diff --git a/.agents/skills/agent-core-dev/SKILL.md b/.agents/skills/agent-core-dev/SKILL.md index 5cf11c040..887296a64 100644 --- a/.agents/skills/agent-core-dev/SKILL.md +++ b/.agents/skills/agent-core-dev/SKILL.md @@ -33,7 +33,7 @@ End-to-end procedures that span the stages. Reach for these before reading the s ## Stages -- [Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the four `LifecycleScope` tiers and visibility, and the no-comment convention. Read before touching business code. +- [Stage 1 — Orient](orient.md): the DI black box (identity / dependencies / lifetime), the four `LifecycleScope` tiers and visibility, and the file-header comment convention. Read before touching business code. - [Stage 2 — Design a service](design.md): pick a scope, split a domain across scopes, choose a calling style (direct call vs event vs hook), and direct dependencies. Decide *where things live and who knows whom* before coding. - Topic: [Domain boundaries vs Scope](domain-boundaries.md) — keep `session` / `agent` / `turn` from becoming god objects; data-ownership test and their split conclusions. - Topic: [Persistence layering](persistence.md) — the three-layer `Store → Storage → backend` model, naming Stores by access pattern, and which layer business code should depend on. diff --git a/.agents/skills/agent-core-dev/config.md b/.agents/skills/agent-core-dev/config.md index c84111259..90e1dc102 100644 --- a/.agents/skills/agent-core-dev/config.md +++ b/.agents/skills/agent-core-dev/config.md @@ -101,7 +101,7 @@ pass `ConfigTarget.Memory` for a per-run override that is never written to disk. - `src/kosong/model/thinking.ts` (owner domain, not `config`) — the `resolveThinkingEffort` helper and the authoritative `ThinkingConfig` type (the `thinking` section itself registers from `src/app/kosongConfig/configSection.ts`). - `src/app/config/configPure.ts` — `isPlainObject`, `deepMerge`, `omitUndefined`, `describeUnknownError`. -A domain that owns a section keeps the schema in its own `configSection.ts` (e.g. `src/app/flag/flag.ts` for `experimental`, `src/agent/loop/configSection.ts` for `loopControl`). Exception: kosong-owned sections (`providers`, `models`, `thinking`) — kosong is a pure, persistence-free abstraction layer that defines only the types (`src/kosong/{provider,model}`); the section constants, the zod schemas (re-derived from those types and compile-time pinned via `AssertExact, Type>>`, see `_base/utils/typeEquality.ts`), the registrations, env bindings, and TOML transforms all live in the persistence wrapper `src/app/kosongConfig/configSection.ts`. (`modelCatalog` has no kosong-side type at all — its section is fully self-contained in `app/kosongConfig`, types derived from the schema.) A cross-section env overlay (e.g. the `KIMI_MODEL_*` synthesis in `src/app/kosongConfig/envOverlay.ts`) lives in the wrapper too and is registered via module-level `registerConfigOverlay`. The session subagent domain owns two sections in `src/session/subagent/configSection.ts`: `[subagent]` (`timeout_ms` on disk) and `[secondary_model]` (`default_model` plus the `[secondary_model.models]` pool, with a lone legacy v1 `model` key honored as a fallback default below `default_model`); neither carries a cross-section overlay. Cross-field pool validation (default present / in-pool / every key resolvable) runs at session creation in `subagentModelsValidationService.ts`, not in the schema. The two-way sync between config sections and kosong's in-memory registries is owned by `IKosongConfigService` (`src/app/kosongConfig/kosongConfigService.ts`). +A domain that owns a section keeps the schema in its own `configSection.ts` (e.g. `src/app/flag/flag.ts` for `experimental`, `src/agent/loop/configSection.ts` for `loopControl`). Exception: kosong-owned sections (`providers`, `models`, `thinking`) — kosong is a pure, persistence-free abstraction layer that defines only the types (`src/kosong/{provider,model}`); the section constants, the zod schemas (re-derived from those types and compile-time pinned via `AssertExact, Type>>`, see `_base/utils/typeEquality.ts`), the registrations, env bindings, and TOML transforms all live in the persistence wrapper `src/app/kosongConfig/configSection.ts`. (`modelCatalog` and `secondaryModel` have no kosong-side type at all — their sections are fully self-contained in `app/kosongConfig`, types derived from the schemas.) A cross-section env overlay (e.g. the `KIMI_MODEL_*` synthesis) lives in the wrapper too (`src/app/kosongConfig/envOverlay.ts`; the `[secondary_model]` derived-entry synthesis in `secondaryModelOverlay.ts`) and is registered via module-level `registerConfigOverlay`. The two-way sync between config sections and kosong's in-memory registries is owned by `IKosongConfigService` (`src/app/kosongConfig/kosongConfigService.ts`). ## Scope diff --git a/.agents/skills/agent-core-dev/edge-exposure.md b/.agents/skills/agent-core-dev/edge-exposure.md index 0c8e6652d..5039201ac 100644 --- a/.agents/skills/agent-core-dev/edge-exposure.md +++ b/.agents/skills/agent-core-dev/edge-exposure.md @@ -45,7 +45,7 @@ A Service method is directly exposable iff **all** hold: 3. Errors are `KimiError` (coded). 4. It is a command/query, not a factory, stream, byte-store, or sink. -If any fail → add a wire-safe orchestration method to the owning domain Service (e.g. `IAgentPromptService.submit` settles `{turn_id}` instead of returning the live `PromptHandle`) or compose several domain Services at the edge — kap-server's `routes/prompts.ts` is the reference for edge-side composition. +If any fail → wrap in a **facade** (a Service that takes ids, returns data, throws `KimiError`) and expose the facade. The repo already ships a wire-shaped facade in `rpc/core-api.ts` (`CoreAPI` / `SessionAPI` / `AgentAPI`) behind `IAgentRPCService` / `ISessionRPCService` — prefer building the HTTP edge on top of it rather than re-deriving a new one. ## 3. Per-scope `resource:action` map diff --git a/.agents/skills/agent-core-dev/orient.md b/.agents/skills/agent-core-dev/orient.md index 8fe8dae31..9644fbea9 100644 --- a/.agents/skills/agent-core-dev/orient.md +++ b/.agents/skills/agent-core-dev/orient.md @@ -66,12 +66,45 @@ There is no domain-layer numbering — a domain may import any other domain, gui - v2 never imports v1 (`@moonshot-ai/agent-core` or any subpath). - The kosong subtree (`src/kosong/{contract,protocol,provider,model}`) keeps its strict internal order (`contract ← protocol ← provider/model`), purity bans (no SDKs in `contract`/`protocol`), and the `provider/bases` registration boundary. -## Comment convention +## File-header comment convention -`packages/agent-core-v2/AGENTS.md` bans comments entirely: no file headers, no section banners, no statement-level narration, no JSDoc (not even on exported symbols) — the code is the source of truth. The only exception is a load-bearing lint-suppression directive (`oxlint-disable` / `eslint-disable`) for a deliberate pattern; other tooling directives (`@ts-expect-error`, …) are banned: fix the underlying lint/type problem instead, and put negative type-safety cases in compiler-asserted fixtures. Scope is carried by the filename: `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no prefix = App (see service-authoring.md). +`packages/agent-core-v2/AGENTS.md` mandates a header-only comment style: + +- **Header only.** Comments live solely in the top-of-file `/** */` block — never beside functions, methods, or statements. The code is the source of truth for *how*; the header states *what the module exposes and the responsibility it owns*. +- **Identity line first.** Start with `` `` domain — . `` Keep an existing `(cross-cutting)` label as-is. Write the role as a responsibility ("drives the turn lifecycle"), not a symbol list. +- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no prefix = App (see service-authoring.md). State the same scope in the header so the two never drift. +- **Interface files** (`.ts`) state the public contract + scope: which `IXxx` they define and what it is for. +- **Impl files** (`Service.ts`) add collaborators + scope: list every imported cross-domain collaborator as a role ("persists records through `records`"); read scope from `registerScopedService(LifecycleScope.X, …)`. +- **Contribution files** (`.ts` / `.contrib.ts`) state what they register into the target domain (e.g. "registers the `log` config section into `config`"). +- **Pure-function / `.types` / `.errors` files** state the responsibility only — they own no scoped state, so no scope line. + +Impl file example (`sessionMetadataService.ts`): + +```ts +/** + * `sessionMetadata` domain — `ISessionMetadata` implementation. + * + * Persists the session metadata document (`state.json`) through the `storage` + * access-pattern store (`IAtomicDocumentStore`), rooted at the `metaScope` + * namespace from `sessionContext`. Loads the existing document on + * construction (creating it on first run), and logs through `log`. Bound at + * Session scope. + */ +``` + +Contribution file example (`config.ts` inside `log/`): + +```ts +/** + * `log` domain — registers the `log` config section into `config`. + * + * Owns the `log` section schema and its env overlay; imported for the + * registration side effect. Bound at App scope. + */ +``` ## Red lines (this stage) - Import via the `#/...` alias (mapped to `src/`); never reach into another domain's internals by relative path. - Short-lived may inject long-lived; never the reverse. -- No comments — not file headers, not beside statements, no JSDoc anywhere; `oxlint-disable` / `eslint-disable` are the only exception. +- File-header comments describe role and scope only; never narrate implementation beside statements. diff --git a/.agents/skills/agent-core-dev/server-align.md b/.agents/skills/agent-core-dev/server-align.md index 88bc7892f..6907a710a 100644 --- a/.agents/skills/agent-core-dev/server-align.md +++ b/.agents/skills/agent-core-dev/server-align.md @@ -128,7 +128,7 @@ registerScopedService( Conventions: - **Name** the domain `Legacy` and the interface with the scope prefix, `ILegacyService` (e.g. `prompt` / `IAgentPromptService`), per service-authoring.md. -- **Role is carried by the name** — `Legacy` marks it as an `edge adapter`; the v1 contract it implements and the native v2 Service it leaves untouched stay evident from its delegation targets (see `prompt.ts`). +- **Header comment** must say it is an `edge adapter` and name both the v1 contract it implements and the native v2 Service it leaves untouched (see `prompt.ts`). - **Scope** = the lifetime of the *legacy* state it holds (the `prompt` queue is per-agent → `LifecycleScope.Agent`). Apply [orient.md](orient.md) / [design.md](design.md) normally — a LegacyService is not exempt from scope rules. - **Delegate, do not duplicate** business logic. The LegacyService translates the v1 contract into native-Service calls and translates results back; the real work stays in the native Service. - **Contract types come from the v1 wire schema homes** (the owning v2 domain contract or `kap-server/src/protocol`), so the interface cannot drift from the wire shape. @@ -165,7 +165,7 @@ const route = defineRoute( app.post(route.path, route.options, route.handler); ``` -**For `/api/v2` (native):** add a `resource:action` entry to `actionMap` ([edge-exposure.md](edge-exposure.md) §3). If the method fails the direct-exposure rules (returns a handle / stream / bytes, takes a live object), add a wire-safe orchestration method to the owning domain Service first — as `prompts:submit` maps to `IAgentPromptService.submit`, which settles `{turn_id}` engine-side instead of returning the live `PromptHandle`. +**For `/api/v2` (native):** add a `resource:action` entry to `actionMap` ([edge-exposure.md](edge-exposure.md) §3). If the method fails the direct-exposure rules (returns a handle / stream / bytes, takes a live object), wrap it in a wire-shaped facade first (`IAgentRPCService` / `ISessionRPCService`) and map to the facade — as `prompts:*` does via `IAgentRPCService`. ### 5. Map errors @@ -218,7 +218,7 @@ This is the reference alignment (commits `feat(server-v2): port v1 /sessions/:si **The split.** -- `/api/v2` keeps the native shape — `prompts:submit` / `steer` / `undo` / `clear` / `cancel` map to the domain Services (`IAgentPromptService.submit` / `submitSteer`, `IAgentConversationUndoService.undo`, `IAgentLoopService.cancelFromUser`) in `actionMap`. +- `/api/v2` keeps the native shape — `prompts:submit` / `steer` / `undo` / `clear` / `cancel` map to `IAgentRPCService` (a wire facade over the v2 turn driver) in `actionMap`. The native `IAgentPromptService` is untouched. - `/api/v1` gets an `AgentPromptLegacyService` (`prompt/`, `LifecycleScope.Agent`) that re-implements the v1 scheduler — queue, `prompt_id`, steer/abort, auto-start-next — **on top of** the native `IAgentPromptService`. The `/api/v1` routes consume the LegacyService. **The schema.** Both surfaces import `promptSubmissionSchema` / `promptSubmitResultSchema` / `promptListResponseSchema` / `promptSteerRequestSchema` / `promptSteerResultSchema` / `promptAbortResponseSchema` from the shared v1 wire schemas (see `packages/kap-server/src/protocol`). The `/api/v1` and `/api/v2` routes are therefore compatible with released clients by construction; the LegacyService projects v2 turn results back into those protocol shapes. @@ -236,7 +236,7 @@ Before submitting a server-align change: - [ ] Request and response schemas come from their owning home (the `agent-core-v2` domain contract or `packages/kap-server/src/protocol`); no inline re-declaration in server-v2. - [ ] Existing schema fields are unchanged in name, type, and semantics; only optional fields added (if any). - [ ] Native v2 Service left clean; v1-only behavior isolated in a `Legacy` / `ILegacyService` edge adapter when the semantics diverge. -- [ ] LegacyService registered with the correct `LifecycleScope` and named as the `Legacy` edge adapter preserving the native Service. +- [ ] LegacyService registered with the correct `LifecycleScope` and a header comment naming it an edge adapter + the native Service it preserves. - [ ] Domain error codes registered in `agent-core-v2`; wire codes registered in `packages/kap-server/src/protocol`; route maps them in `sendMappedError`, matching v1's status codes and idempotent envelopes. - [ ] Route resolves the scope from the URL by `accessor.get(IX)`; no cached scope; finishes before disposal. - [ ] Tests assert the wire envelope + protocol shape; wire-shape guards added/updated where the route mirrors v1. diff --git a/.agents/skills/agent-core-dev/service-authoring.md b/.agents/skills/agent-core-dev/service-authoring.md index b562984d9..5484f48ed 100644 --- a/.agents/skills/agent-core-dev/service-authoring.md +++ b/.agents/skills/agent-core-dev/service-authoring.md @@ -17,7 +17,7 @@ One folder per domain, **camelCase**: `session/`, `sessionActivity/`, `contextMe ``` - **Strictly one service per file.** An interface file holds exactly one injectable interface and exactly one `createDecorator(...)`; an impl file holds exactly one service implementation class and exactly one `registerScopedService(...)`. No exceptions for "tightly-coupled" groups: even same-scope collaborators each get their own `.ts` + `Service.ts` pair. -- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no scope prefix = App (see [Naming](#naming)). +- **Scope is in the filename.** `workspace*.ts` = Workspace, `session*.ts` = Session, `agent*.ts` = Agent, no scope prefix = App (see [Naming](#naming)). The header comment restates the same scope. - A domain therefore has as many impl files as it has services (e.g. `logService.ts` for the App `ILogService`, `sessionLogService.ts` for the Session `ISessionLogService`). See [Multi-Service domains](#multi-service-domains). The package entry `src/index.ts` imports and `export *`s every domain's leaf files precisely (one line per leaf), so importing the package still runs every `registerScopedService(...)` side effect — exactly as the old per-domain barrels did. @@ -51,7 +51,7 @@ File names derive from the interface / class names so that scope and role are vi | Shared-types file | `.types.ts` | `log.types.ts` | | Errors file | `.errors.ts` | `appendLogStore.errors.ts` | -Acronym-aware lowerCamelCase lowercases a leading acronym as a group: `ILLMRequester` → `llmRequester.ts`, `IWSGateway` → `wsGateway.ts`, `IOAuthToolkit` → `oauthToolkit.ts`, `IMcpServerService` → `mcpServerService.ts`. +Acronym-aware lowerCamelCase lowercases a leading acronym as a group: `ILLMRequester` → `llmRequester.ts`, `IWSGateway` → `wsGateway.ts`, `IOAuthToolkit` → `oauthToolkit.ts`, `IAgentRPCService` → `agentRpcService.ts`. Because the impl class always ends in `Service` and the interface file never does, the two files of one service never collide — even for `Store` / `Registry` / `Resolver` interfaces (`IAppendLogStore` → `appendLogStore.ts` + `appendLogStoreService.ts`). @@ -293,11 +293,13 @@ Importing the package therefore fires every `register*` side effect, exactly as - Load the impl file too — its top-level `registerScopedService(...)` only runs when the module is imported. - `export *` helper modules only if they are part of the domain's public surface. +- Each leaf's file-header comment still names the domain, scope, and (for impls) the `register*` binding it owns. ## Comments -- **No comments** (orient.md): no file headers, no statement-level narration, no JSDoc — not on exported symbols either; the only exception is a load-bearing `oxlint-disable` / `eslint-disable` directive. -- **Methods and fields carry no comments.** Well-named identifiers and types say *what*; the code is the source of truth for *how*. +- **File-header comment is mandatory** and the only place comments live (orient.md). State the identity line, the role, collaborators (impls), and scope. +- **Methods and fields carry no comments by default.** Well-named identifiers and types say *what*; the code is the source of truth for *how*. +- Write an inline comment only when the *why* is non-obvious (a hidden constraint, a subtle invariant, a workaround). One short line. - For unimplemented stubs, throw `NotImplementedError('feature')` rather than `throw new Error('TODO: …')` (errors.md). ## Complete minimal example @@ -349,4 +351,4 @@ import './greet/greetService'; - Never `new` a `@IService`-carrying Service — except inside an explicit factory method, which is not a DI request. - Events: typed per-Service event → `Event`/`Emitter` from `'#/_base/event'`; cross-domain broadcast → `IEventService` from `'#/event'`. - `src/index.ts` must import/export every leaf file (including the impl) so each `register*` side effect runs. -- No comments by default (orient.md); stubs throw `NotImplementedError`. +- File-header comment only; methods/fields carry no comments by default; stubs throw `NotImplementedError`. diff --git a/.agents/skills/agent-core-dev/verify.md b/.agents/skills/agent-core-dev/verify.md index 8926b052d..8ab7dd095 100644 --- a/.agents/skills/agent-core-dev/verify.md +++ b/.agents/skills/agent-core-dev/verify.md @@ -21,7 +21,7 @@ Walk the stages you touched and confirm: - **Design** — scope follows state identity; no `Map` at `App`; dependency arrows do not make a foundational layer know an upstream one; no cycle was routed around. - **Implement** — no `new` on `@IService`-carrying classes; `@IX` on constructor params only (service params after static params); interface + impl carry `_serviceBrand`; decorator names unique; coded errors only; flags for unreleased behavior. - **Test** — SUT resolved by interface; stubs under `test/`; scope tests re-register after `_clearScopedRegistryForTests()`; teardown through one `DisposableStore`. -- **Files** — no comments at all (no JSDoc either; only load-bearing `oxlint-disable` / `eslint-disable` survive); registration runs from the impl file's top level; the new domain is exported from `src/index.ts`. +- **Files** — header comments describe role + scope only; registration runs from the impl file's top level; the new domain is exported from `src/index.ts`. Then re-read the [global red lines](SKILL.md#global-red-lines) once — they catch most cross-stage mistakes in a single scan. diff --git a/.agents/skills/gen-changesets/SKILL.md b/.agents/skills/gen-changesets/SKILL.md index 3ab4458ba..ad64295f8 100644 --- a/.agents/skills/gen-changesets/SKILL.md +++ b/.agents/skills/gen-changesets/SKILL.md @@ -1,26 +1,100 @@ --- name: gen-changesets -description: Use when generating changesets in the kimi-code repository — deciding whether to write one, which package to list, the bump level, the wording, and the confirmation workflow. +description: Use when generating changesets in the kimi-code repository, including package bump selection, internal package and CLI bundle handling, bump levels, major confirmation, and English changelog wording. --- # Generate Changesets -The only user-facing published package is the CLI: `@moonshot-ai/kimi-code`. All other `@moonshot-ai/*` packages (sdk, agent-core, kosong, kaos, oauth, telemetry, and so on) are internal. +`kimi-code` uses changesets to manage versions and changelogs. The current user-facing published package is: -## 1. Whether to Write +- `@moonshot-ai/kimi-code`: the CLI -Rule of thumb: **if users cannot perceive the change, write no changeset.** A changeset is a user-facing changelog entry, not a shipping gate — internal changes merged to main ship with the next release anyway, so skipping loses nothing. +All other `@moonshot-ai/*` packages are treated as internal packages, including `@moonshot-ai/kimi-code-sdk`, `agent-core`, `kosong`, `kaos`, `kimi-code-oauth`, `kimi-telemetry`, and `migration-legacy`. -Do not write: -- Docs-only or tests-only changes that never enter the shipped artifact. -- Changes internal to core/server packages — architecture, protocols, refactors, config/journal/wire mechanics — unless they fix a bug users care about. -- When you are unsure whether users can perceive a change, ask first. +`@moonshot-ai/pi-tui` is a special internal package: it is a private fork (`private: true`) that is never published, but it keeps its own changelog through changesets. It is an exception to Core Rule 4 — see the dedicated section below. -Do write: user-perceivable new features or behavior changes, and internal-package changes that fix a user-useful bug or change CLI output/behavior (list `@moonshot-ai/kimi-code` for those). +Only the CLI changelog gets a curated, user-facing presentation (the docs-site changelog sync). The SDK and other internal package changelogs are raw changesets output kept for version history — nobody curates them, so write those entries honestly and technically; their wording does not need to suit end users. -## 2. What to Write +## Core Rules -Create a short kebab-case file under `.changeset/`: +1. **Inspect the actual changes first.** Use `git status` / `git diff --name-only` to identify which packages were actually changed. +2. **List packages that changesets can release.** If a changed package is ignored in `.changeset/config.json`, do not put that ignored package in frontmatter together with a non-ignored package; changesets rejects mixed ignored/non-ignored frontmatter. +3. **Map ignored internal changes to the affected released package.** If an ignored internal package changes CLI output or behavior, list `@moonshot-ai/kimi-code` and describe the actual user-visible or release-artifact change in the changelog text. +4. **Internal package source changes that enter the CLI bundle must manually list the CLI — when they get a changeset at all.** `@moonshot-ai/kimi-code` inline-bundles `@moonshot-ai/*` source, but those internal packages are devDependencies from the CLI's perspective, so changesets will not automatically propagate bumps. If a change enters the CLI output and is user-perceivable, list `@moonshot-ai/kimi-code`. See rule 6 for when to skip the changeset entirely. +5. **Docs-only and tests-only changes usually do not need a changeset.** README, internal docs, and `test/` changes that do not enter package output do not trigger a CLI bump. +6. **Skip changes users cannot perceive — write no changeset at all.** The CLI changelog is user-facing; a changeset is a changelog entry, not a shipping gate. Internal changes merged to `main` still ship in the next release triggered by any user-facing changeset, so skipping the changeset loses nothing. Do not write changesets for: + - `agent-core-v2` internal architecture: new services, refactors, config-persistence or journal/wire mechanisms. + - `kap-server` WebSocket / REST protocol changes consumed only by the bundled web UI, kimi-inspect, or other dev tooling (new endpoints, subscribe protocols, stream baselines). + - Behavior that only takes effect on the experimental engine (e.g. experimental `kimi -p`), unless it exposes documented user configuration such as a `config.toml` section or env vars that also work on a shipped surface (TUI or `kimi web`). + - When unsure whether users can perceive a change, ask before writing. +7. `@moonshot-ai/vis` / `vis-server` / `vis-web` are ignored by changesets and should not be handled. `@moonshot-ai/kimi-inspect` (a private dev app that never ships) is likewise ignored and must never appear in a changeset frontmatter. + +## Workflow + +1. List the changed packages and check whether each one is ignored by `.changeset/config.json`. +2. Decide whether the change is user-perceivable (Core Rule 6); if not, stop — no changeset. +3. Choose a bump level for each package. +4. If an ignored internal package change enters the CLI bundle, put `@moonshot-ai/kimi-code` in frontmatter instead of mixing the ignored package into the same changeset. +5. Create a short kebab-case file under `.changeset/`. +6. Split unrelated changes into separate changesets; keep one logical change in one file. + +Before a release, review the accumulated `.changeset/` entries against Core Rule 6 and prune non-user-facing ones; the release PR regenerates from `.changeset/` on `main`, so deleting a changeset removes its changelog entry without affecting the shipped code. + +Format: + +```markdown +--- +"": patch +"": minor +--- + + +``` + +## Bump Levels + +| Level | When to use | +|---|---| +| `patch` | Bug fixes; build/package fixes; internal refactors that do not change behavior; wording tweaks; small dependency upgrades; small improvements to existing features with limited user-facing impact (e.g. a new keyboard shortcut, a flag alias, a minor UX tweak) | +| `minor` | A substantial new user-facing feature, such as a new slash command, a new built-in tool, or a new mode | +| `major` | Breaking changes: incompatible config changes, renamed or removed commands/arguments, behavior semantics changes, and similar | + +When in doubt between `patch` and `minor`: if the change improves an existing feature and the user-facing impact is small, choose `patch` even when the change is technically "new". Reserve `minor` for a substantial new capability that introduces something users could not do before. + +New configuration surface is not automatically `minor`. Additions to an existing feature's configuration — env var overlays, config-file fallbacks, global defaults under per-item settings — are `patch`. Examples: a global default MCP timeout when per-server timeouts already exist; env-based credentials for a service already configurable in `config.toml`. + +### Major Rule + +Never write `major` on your own. + +If you believe a change qualifies as major, stop first, explain why, and ask the user for confirmation. Only write `major` after the user explicitly agrees. If the user does not reply, replies ambiguously, or disagrees, fall back to `minor`; if `minor` is also unclear, fall back to `patch`. + +## Wording Rules + +- Changelog entries **must be written in English**. +- **Keep the whole entry concise.** Aim for one short sentence that states what was done; at most a short sentence plus a one-line usage hint. Do not write a paragraph, do not pile on technical detail, and do not enumerate every sub-change. +- **For new user-facing features, append a brief usage hint** so users know how to try it. Keep it to a single short line — a command name, a subcommand, a flag, or a one-line "how to use". Do not explain design rationale or list edge cases. Skip the hint for bug fixes, internal changes, and refactors. + - Slash command: `Add the /foo slash command to list active sessions. Run /foo to see them.` + - CLI subcommand: `Add the kimi web subcommand to open the web UI. Run kimi web to launch it.` + - Flag: `Add a --bar flag to skip confirmation prompts. Pass --bar to skip.` + - Too long: `Add the /foo command to list active sessions. It accepts an optional --all flag to include background sessions, supports filtering by name with /foo , and writes the result to the transcript...` +- User-facing CLI wording should only be used when CLI users can perceive the change. +- Internal changes that do not affect CLI users can still share a changeset with the CLI, but the wording must describe the real change honestly and must not present it as a user-facing feature. +- Do not mention file names, class names, function names, PR numbers, or commit hashes. +- Do not include real internal endpoints, key names, account names, or service names. If an example is needed, use neutral placeholders such as `example.com`, `example.test`, or `YOUR_API_KEY`. +- Avoid vague words such as `refactor`, `optimize`, and `improve`. Describe the actual change, or use more specific wording. + +## When You Are Unsure About a Change + +Generate the changeset from what the diff clearly shows. If part of a change is unclear and you cannot confidently describe what it does for users, do not guess or pad the entry with vague wording. + +1. Finish the changeset for the parts that are clear. +2. Then ask the user once, in a short list: name the specific change(s) you do not understand, and ask whether you may dig into the repository (read related source, tests, or call sites) to describe it more accurately. +3. Only read more code after the user agrees. If the user says no or does not reply, keep the concise wording you already have and do not invent detail. + +## Common Examples + +An internal package fixes a bug visible to CLI users: ```markdown --- @@ -30,34 +104,103 @@ Create a short kebab-case file under `.changeset/`: Fix occasional loss of tool call results in long conversations. ``` -Wording: -- One short, user-facing English sentence that states only what changed. Drop trailing clauses that explain the cause, the benefit, or the mechanism. -- New features: say plainly what it is plus one line on how to use it, e.g. `Add the /foo slash command to list active sessions. Run /foo to see them.` -- Experimental features: also state how to enable them (the flag, config key, or env var). -- No file, class, or function names, and no PR numbers. No vague words like refactor, optimize, or improve. No real internal identifiers — use neutral placeholders such as `example.com` or `YOUR_API_KEY`. -- Internal packages' own changelogs (such as the sdk) are not curated for end users — write those entries honestly and technically. -- One logical change per changeset; split unrelated changes into separate files. +A new user-facing slash command (note the short usage hint): -## 3. Bump Level +```markdown +--- +"@moonshot-ai/kimi-code": minor +--- -- `patch`: bug fixes, small improvements, configuration additions to existing features — when in doubt, use this. -- `minor`: a real new capability users could not do before (a new slash command, a new subcommand, a new mode). -- `major`: **never write it.** If you think a change qualifies, stop and ask the user; without explicit approval fall back to `minor`, or to `patch` if `minor` is also unclear. +Add the /foo slash command to list active sessions. Run /foo to see them. +``` -## 4. Which Package +A new CLI subcommand: -- An internal change enters the CLI bundle and is user-perceivable → list `@moonshot-ai/kimi-code`. -- An internal change does not enter the CLI or is not user-perceivable → write nothing; if it is written, list only that internal package. -- Never mix packages ignored in `.changeset/config.json` with non-ignored packages in one frontmatter. -- pi-tui exception: pi-tui-only changes list `@moonshot-ai/pi-tui`; if the same change is also visible to CLI users, write a separate CLI changeset (two files, never mixed). -- kimi-inspect and the vis packages never appear in a changeset. +```markdown +--- +"@moonshot-ai/kimi-code": minor +--- -## 5. Workflow +Add the kimi web subcommand to open the web UI. Run kimi web to launch it. +``` -1. Run `git status` / `git diff --name-only` to see which packages actually changed. -2. Apply section 1; if no changeset is needed, stop. -3. Pick the package and the bump, and write the one sentence. -4. **Show the changeset text to whoever requested the work and get their confirmation before committing.** -5. Do not guess at changes you do not understand: finish the parts that are clear, then list what is unclear and ask whether you may dig into the code. +A new flag on an existing command: -Before a release, review the accumulated `.changeset/` entries and delete the non-user-facing ones — the release PR regenerates from `.changeset/` on main, so deleting a file removes its changelog entry without touching shipped code. +```markdown +--- +"@moonshot-ai/kimi-code": patch +--- + +Add a --bar flag to skip confirmation prompts. Pass --bar to skip. +``` + +An internal package has an internal-only change, but it enters the CLI bundle: + +```markdown +--- +"@moonshot-ai/kimi-code": patch +--- + +Unify tool execution metadata handling. +``` + +Only SDK source changed, and the CLI does not use it: + +```markdown +--- +"@moonshot-ai/kimi-code-sdk": patch +--- + +Clarify session status typing for internal SDK callers. +``` + +## `@moonshot-ai/pi-tui` changes + +`@moonshot-ai/pi-tui` is a vendored fork that lives in `packages/pi-tui`. It is `private: true` and is never published, but it is **not** ignored by changesets: changesets versions it and writes `packages/pi-tui/CHANGELOG.md` so the fork keeps its own history. Because it is bundled into the CLI like other internal packages, it is an exception to Core Rule 4 — do **not** list `@moonshot-ai/kimi-code` for a change that only touches pi-tui. + +- Changes that only affect pi-tui (build, package, strict-mode cleanup, renderer fixes): list `@moonshot-ai/pi-tui` only. No CLI changeset. +- If the same change is also user-visible in the CLI (for example a terminal rendering fix that CLI users can see), add a **separate** changeset that lists `@moonshot-ai/kimi-code` with CLI-focused wording, in addition to the pi-tui changeset. Do not mix both packages in one frontmatter — the two changelogs need different wording. + +pi-tui-only change: + +```markdown +--- +"@moonshot-ai/pi-tui": patch +--- + +Export the package manifest so the bundled binary can locate its native assets. +``` + +pi-tui change that is also visible in the CLI (two separate changesets): + +```markdown +--- +"@moonshot-ai/pi-tui": patch +--- + +Clamp the differential render to the visible viewport so scrolling up during streaming no longer jumps to the top. +``` + +```markdown +--- +"@moonshot-ai/kimi-code": patch +--- + +Fix the transcript jumping to the top when scrolling up through history during streaming output. +``` + +## Red Flags + +- You are about to write `major` without asking the user. +- You are writing a changeset for something users cannot perceive — `agent-core-v2` internals, `kap-server` WS/REST protocol plumbing, experimental-engine-only behavior. Skip the changeset instead (Core Rule 6). +- A new env var overlay or config fallback for an existing feature is bumped `minor` — configuration additions to existing features are `patch`. +- A new user-facing feature entry has no usage hint, or the hint runs to multiple lines and explains design rationale. +- You guessed wording for a change you do not understand instead of asking the user whether you may dig into the repo. +- Internal package source enters the CLI bundle, but `@moonshot-ai/kimi-code` is missing. +- A changeset frontmatter mixes ignored internal packages with non-ignored packages. +- `packages/node-sdk` was not changed, but `@moonshot-ai/kimi-code-sdk` was listed for "internal package sync". +- The changelog entry is in Chinese. +- The wording claims more than the diff actually did. +- The CLI wording mentions internal package names, class names, or PR numbers. +- The entry includes real internal identifiers instead of neutral placeholders. +- A change that only touches `@moonshot-ai/pi-tui` lists `@moonshot-ai/kimi-code` instead of `@moonshot-ai/pi-tui`, or mixes both packages in one frontmatter. diff --git a/.changeset/abort-signal-listener-ceiling.md b/.changeset/abort-signal-listener-ceiling.md deleted file mode 100644 index cc0a62ca2..000000000 --- a/.changeset/abort-signal-listener-ceiling.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Silence the MaxListenersExceededWarning that could appear during long agent turns with many parallel tool calls. diff --git a/.changeset/add-remote-control.md b/.changeset/add-remote-control.md deleted file mode 100644 index 321ecc0ce..000000000 --- a/.changeset/add-remote-control.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": minor ---- - -Add Remote Control as an experimental feature for accessing a local web session remotely. Enable it with `KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL=1`, then run `kimi rc`, `kimi web --remote-control`, or `/remote-control` to start it. diff --git a/.changeset/agent-detail-thinking-collapse.md b/.changeset/agent-detail-thinking-collapse.md deleted file mode 100644 index 9a680fd28..000000000 --- a/.changeset/agent-detail-thinking-collapse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: fix thinking blocks in the subagent detail panel being stuck expanded and not collapsible. diff --git a/.changeset/archive-missing-workspace.md b/.changeset/archive-missing-workspace.md deleted file mode 100644 index 0beac2e42..000000000 --- a/.changeset/archive-missing-workspace.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix sessions failing to archive when their workspace folder no longer exists. diff --git a/.changeset/broadcast-user-prompts.md b/.changeset/broadcast-user-prompts.md deleted file mode 100644 index af1f4bcbf..000000000 --- a/.changeset/broadcast-user-prompts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix messages sent from one web client not appearing on other clients connected to the same session. diff --git a/.changeset/btw-sidechat-esc-ime.md b/.changeset/btw-sidechat-esc-ime.md deleted file mode 100644 index 1244654c4..000000000 --- a/.changeset/btw-sidechat-esc-ime.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix pressing Esc to cancel an IME candidate also closing the BTW side chat. diff --git a/.changeset/btw-sidechat-focus-on-open.md b/.changeset/btw-sidechat-focus-on-open.md deleted file mode 100644 index a331c5e36..000000000 --- a/.changeset/btw-sidechat-focus-on-open.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix the composer not receiving focus after opening the BTW side chat via the shortcut or /btw. diff --git a/.changeset/calm-session-logout.md b/.changeset/calm-session-logout.md deleted file mode 100644 index 12f9d5e82..000000000 --- a/.changeset/calm-session-logout.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Preserve the active session and its selected model when logging out of a provider. diff --git a/.changeset/cloudbase-marketplace.md b/.changeset/cloudbase-marketplace.md deleted file mode 100644 index 942b71781..000000000 --- a/.changeset/cloudbase-marketplace.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Add the Tencent CloudBase plugin to the curated marketplace. diff --git a/.changeset/composer-toolbar-crush-fix.md b/.changeset/composer-toolbar-crush-fix.md deleted file mode 100644 index 7625e4f6d..000000000 --- a/.changeset/composer-toolbar-crush-fix.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix composer toolbar buttons squeezing and overlapping each other in very narrow windows. diff --git a/.changeset/cron-fold-swallows-answer.md b/.changeset/cron-fold-swallows-answer.md deleted file mode 100644 index 408a68aa7..000000000 --- a/.changeset/cron-fold-swallows-answer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix the latest reply disappearing from the transcript after a scheduled cron reminder fires. diff --git a/.changeset/drop-allow-remote-terminals.md b/.changeset/drop-allow-remote-terminals.md deleted file mode 100644 index a4a35a6ad..000000000 --- a/.changeset/drop-allow-remote-terminals.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Remove the `--allow-remote-terminals` flag from `kimi web`; PTY terminal routes now stay available on loopback binds only. diff --git a/.changeset/fix-acp-execution-regressions.md b/.changeset/fix-acp-execution-regressions.md deleted file mode 100644 index 713501caa..000000000 --- a/.changeset/fix-acp-execution-regressions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix ACP session regressions: Bash, Grep, and Glob failing when the editor does not support terminal command execution, session creation failing with stdio MCP servers, and reopening a closed session failing with an internal error. diff --git a/.changeset/fix-desktop-memory-leaks.md b/.changeset/fix-desktop-memory-leaks.md deleted file mode 100644 index 277ef85b0..000000000 --- a/.changeset/fix-desktop-memory-leaks.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix memory usage growing steadily after repeatedly switching sessions and toggling the side chat and subagent panels. diff --git a/.changeset/fix-draft-attachments.md b/.changeset/fix-draft-attachments.md deleted file mode 100644 index ddbe71637..000000000 --- a/.changeset/fix-draft-attachments.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix unsent composer attachments such as images being lost after switching sessions on the new-session page. diff --git a/.changeset/fix-question-card-title-clamp.md b/.changeset/fix-question-card-title-clamp.md deleted file mode 100644 index fb3ef3ec6..000000000 --- a/.changeset/fix-question-card-title-clamp.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix long question text in question cards being truncated with an ellipsis instead of wrapping. diff --git a/.changeset/fix-restore-crash-loop.md b/.changeset/fix-restore-crash-loop.md deleted file mode 100644 index 8707e68e0..000000000 --- a/.changeset/fix-restore-crash-loop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix repeated server crashes when resuming a session that was interrupted in the middle of a turn. diff --git a/.changeset/guard-background-questions.md b/.changeset/guard-background-questions.md deleted file mode 100644 index de33a761e..000000000 --- a/.changeset/guard-background-questions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Prevent AskUserQuestion from starting background tasks when task controls are unavailable. diff --git a/.changeset/login-region-card-titles.md b/.changeset/login-region-card-titles.md deleted file mode 100644 index 64a47af6c..000000000 --- a/.changeset/login-region-card-titles.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Remove the redundant parenthesized domain from the login entry card titles. diff --git a/.changeset/mobile-composer-button-glyphs.md b/.changeset/mobile-composer-button-glyphs.md deleted file mode 100644 index f1fd884c2..000000000 --- a/.changeset/mobile-composer-button-glyphs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix the send and stop button icons rendering too small in the mobile composer. diff --git a/.changeset/mobile-composer-menu-sheets.md b/.changeset/mobile-composer-menu-sheets.md deleted file mode 100644 index 1e319bbe2..000000000 --- a/.changeset/mobile-composer-menu-sheets.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": minor ---- - -web: Fix the slash-command and @-mention panels failing to open on mobile — both panels and the + menu are now grab-handle bottom sheets on small screens. diff --git a/.changeset/mobile-model-picker-sheet.md b/.changeset/mobile-model-picker-sheet.md deleted file mode 100644 index b4c2f44cb..000000000 --- a/.changeset/mobile-model-picker-sheet.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Present the mobile model picker as a bottom sheet consistent with the other mobile drawers. diff --git a/.changeset/mobile-onboarding-theme-cards.md b/.changeset/mobile-onboarding-theme-cards.md deleted file mode 100644 index 9d2d6332c..000000000 --- a/.changeset/mobile-onboarding-theme-cards.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix the oversized appearance theme cards in the mobile first-run wizard. diff --git a/.changeset/mobile-park-custom-provider.md b/.changeset/mobile-park-custom-provider.md deleted file mode 100644 index 0ae42efe2..000000000 --- a/.changeset/mobile-park-custom-provider.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Temporarily remove the custom-provider entry from the mobile first-run wizard. diff --git a/.changeset/mobile-shell-ui.md b/.changeset/mobile-shell-ui.md deleted file mode 100644 index 5f69178b8..000000000 --- a/.changeset/mobile-shell-ui.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Improve mobile UI styling. diff --git a/.changeset/mobile-switcher-flat-grouped-tabs.md b/.changeset/mobile-switcher-flat-grouped-tabs.md deleted file mode 100644 index 1f3e22b12..000000000 --- a/.changeset/mobile-switcher-flat-grouped-tabs.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": minor ---- - -web: Add a flat/by-workspace tab to the mobile session list. diff --git a/.changeset/mobile-tool-row-touch-height.md b/.changeset/mobile-tool-row-touch-height.md deleted file mode 100644 index 74350940a..000000000 --- a/.changeset/mobile-tool-row-touch-height.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix tool-call rows alternating heights on mobile by unifying them to the compact row height. diff --git a/.changeset/model-pill-icon-collapse.md b/.changeset/model-pill-icon-collapse.md deleted file mode 100644 index 9e158d431..000000000 --- a/.changeset/model-pill-icon-collapse.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Collapse the composer model picker to an icon when space is tight; hovering still shows the model and reasoning effort. diff --git a/.changeset/perm-label-flex-shrink.md b/.changeset/perm-label-flex-shrink.md deleted file mode 100644 index 315a40557..000000000 --- a/.changeset/perm-label-flex-shrink.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix the composer permission mode label being hidden even when there is enough space. diff --git a/.changeset/plugins-marketplace-async-versions.md b/.changeset/plugins-marketplace-async-versions.md deleted file mode 100644 index 2a3298973..000000000 --- a/.changeset/plugins-marketplace-async-versions.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Show the /plugins marketplace catalog as soon as it loads, with latest-version lookups running in the background. diff --git a/.changeset/respect-mcp-management-readiness.md b/.changeset/respect-mcp-management-readiness.md deleted file mode 100644 index 98032fb55..000000000 --- a/.changeset/respect-mcp-management-readiness.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Respect workspace trust and configuration readiness when managing MCP servers. diff --git a/.changeset/sdk-mcp-management-cwd.md b/.changeset/sdk-mcp-management-cwd.md deleted file mode 100644 index be4c3c37e..000000000 --- a/.changeset/sdk-mcp-management-cwd.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code-sdk": patch ---- - -Add an optional `cwd` parameter to the global MCP management methods; `verify: false` on the global MCP authorization-status listing now returns a fully offline classification instead of behaving like an omitted `verify`. diff --git a/.changeset/secondary-model-thinking-effort.md b/.changeset/secondary-model-thinking-effort.md deleted file mode 100644 index c032e9f41..000000000 --- a/.changeset/secondary-model-thinking-effort.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix subagents bound to a configured secondary model ignoring its default thinking effort. diff --git a/.changeset/sidebar-overlay-scrollbar.md b/.changeset/sidebar-overlay-scrollbar.md deleted file mode 100644 index bc4eb50e5..000000000 --- a/.changeset/sidebar-overlay-scrollbar.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix mismatched left and right margins in the sidebar session list, and show the scrollbar only while hovering or scrolling. diff --git a/.changeset/subagent-fork-context.md b/.changeset/subagent-fork-context.md deleted file mode 100644 index 3df6db680..000000000 --- a/.changeset/subagent-fork-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": minor ---- - -Add an optional `fork` parameter to subagent and swarm tools that starts the subagent with a snapshot of the calling agent's conversation history; set `KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK=1` or `subagent_fork = true` under `[experimental]` in config.toml to enable it. diff --git a/.changeset/swarm-timeout-config.md b/.changeset/swarm-timeout-config.md deleted file mode 100644 index 6334a100c..000000000 --- a/.changeset/swarm-timeout-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Add a dedicated `[swarm] timeout_ms` config option (or the `KIMI_CODE_SWARM_TIMEOUT_MS` env var) for AgentSwarm subagent timeouts, which no longer follow `[subagent] timeout_ms`. diff --git a/.changeset/task-notification-cron-style.md b/.changeset/task-notification-cron-style.md deleted file mode 100644 index c190c1ed0..000000000 --- a/.changeset/task-notification-cron-style.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Restyle background task notifications as a lighter notice that shows the task summary, output files, and output preview directly. diff --git a/.changeset/tasks-run-in-background.md b/.changeset/tasks-run-in-background.md deleted file mode 100644 index aa525051e..000000000 --- a/.changeset/tasks-run-in-background.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix foreground subagents being reported as background tasks on the task list. diff --git a/.changeset/tower-mode-command.md b/.changeset/tower-mode-command.md deleted file mode 100644 index 9dbcdb9b1..000000000 --- a/.changeset/tower-mode-command.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": minor ---- - -Add experimental tower mode for multi-agent orchestration; set `KIMI_CODE_EXPERIMENTAL_TOWER=1`, then run `/tower on` and `/tower ` to start. diff --git a/.changeset/transcript-notification-fold.md b/.changeset/transcript-notification-fold.md deleted file mode 100644 index 22b28162c..000000000 --- a/.changeset/transcript-notification-fold.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix the cold transcript rebuild splitting a turn at background-task completion notices; they now fold into the current turn like the live stream does. diff --git a/.changeset/usage-flyout-viewport-cap.md b/.changeset/usage-flyout-viewport-cap.md deleted file mode 100644 index 957897087..000000000 --- a/.changeset/usage-flyout-viewport-cap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -web: Fix the reset-time hint in the sidebar usage panel being ellipsized even when there is enough room. diff --git a/.changeset/windows-git-bash-path-bridge.md b/.changeset/windows-git-bash-path-bridge.md deleted file mode 100644 index 093ba6528..000000000 --- a/.changeset/windows-git-bash-path-bridge.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@moonshot-ai/kimi-code": patch ---- - -Fix file tools and shell working directories failing to resolve Git Bash paths such as /c/Users or /tmp on Windows. diff --git a/.github/ISSUE_TEMPLATE/1-bug-report.yml b/.github/ISSUE_TEMPLATE/1-bug-report.yml index c370cc642..45b15e1b4 100644 --- a/.github/ISSUE_TEMPLATE/1-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/1-bug-report.yml @@ -13,7 +13,7 @@ body: Please try to include as much information as possible. - If you plan to submit a fix: check the Contribution box below and wait for a maintainer's `/approve` comment in this issue before opening a PR. + If you plan to submit a fix: link this issue in your PR. Small, reproducible bugs can go straight to a PR; for broader or uncertain fixes, wait for maintainer feedback first. - type: input id: version @@ -65,10 +65,3 @@ body: attributes: label: Additional information description: Is there anything else you think we should know? - - - type: checkboxes - id: willing-to-pr - attributes: - label: Contribution - options: - - label: I am willing to submit a PR for this bug fix myself (please wait for maintainer approval in this issue first) diff --git a/.github/ISSUE_TEMPLATE/2-feature-request.yml b/.github/ISSUE_TEMPLATE/2-feature-request.yml index 1f2b10713..bd1a04e44 100644 --- a/.github/ISSUE_TEMPLATE/2-feature-request.yml +++ b/.github/ISSUE_TEMPLATE/2-feature-request.yml @@ -11,7 +11,7 @@ body: Before you submit a feature: 1. Search existing issues for similar features. If you find one, 👍 it rather than opening a new one. 2. The Kimi Code team will try to balance the varying needs of the community when prioritizing or rejecting new features. Please understand that not all features will be accepted. - 3. Do not open a feature PR. External feature PRs are not accepted — features are discussed and decided in this issue; if accepted, the team will implement it or explicitly invite you to contribute. + 3. Do not open a feature PR until maintainers have had a chance to respond here. PRs without prior discussion may be closed without review. - type: textarea id: feature diff --git a/.github/ISSUE_TEMPLATE/3-bug-report-zh-cn.yml b/.github/ISSUE_TEMPLATE/3-bug-report-zh-cn.yml deleted file mode 100644 index 3dd6f4d7f..000000000 --- a/.github/ISSUE_TEMPLATE/3-bug-report-zh-cn.yml +++ /dev/null @@ -1,73 +0,0 @@ -name: Bug 报告 -description: 报告需要修复的问题 -labels: - - bug - - needs triage -body: - - type: markdown - attributes: - value: | - 感谢你提交 bug 报告!这能帮助 Kimi Code 变得更好。 - - 请确认你正在运行最新版本的 Kimi Code CLI——你遇到的问题可能已经被修复。 - - 请尽量提供完整的信息。 - - 如果你打算提交修复:勾选下方 Contribution 选项,并等待维护者在本 issue 中以 `/approve` 评论批准后再提 PR。 - - - type: input - id: version - attributes: - label: 你运行的 Kimi Code 版本是? - description: 复制 `kimi --version` 或 `/version` 的输出 - validations: - required: true - - type: input - id: plan - attributes: - label: 你使用的是哪个开放平台/订阅? - description: 运行 `/login` 时选择的那个 - validations: - required: true - - type: input - id: model - attributes: - label: 你使用的是哪个模型? - description: 底部状态栏可见,如 `kimi-k2.6`、`kimi-for-coding` 等 - - type: input - id: platform - attributes: - label: 你的电脑平台是? - description: | - macOS 和 Linux:复制 `uname -mprs` 的输出 - Windows:在 PowerShell 中运行 `"$([Environment]::OSVersion | ForEach-Object VersionString) $(if ([Environment]::Is64BitOperatingSystem) { "x64" } else { "x86" })"` 并复制输出 - - type: textarea - id: actual - attributes: - label: 你遇到了什么问题? - description: 请包含完整的错误信息和提示词(隐去隐私信息)。如可能,请提供文本而非截图。 - validations: - required: true - - type: textarea - id: steps - attributes: - label: 复现步骤? - description: 说明 bug 并给出可复现的代码片段。如适用,请提供 session id 和上下文用量。 - validations: - required: true - - type: textarea - id: expected - attributes: - label: 期望的行为是什么? - description: 如可能,请提供文本而非截图。 - - type: textarea - id: notes - attributes: - label: 补充信息 - description: 还有什么想让我们知道的? - - type: checkboxes - id: willing-to-pr - attributes: - label: Contribution - options: - - label: 我愿意自己提交修复此 bug 的 PR(请先等待维护者在本 issue 中批准) diff --git a/.github/ISSUE_TEMPLATE/4-feature-request-zh-cn.yml b/.github/ISSUE_TEMPLATE/4-feature-request-zh-cn.yml deleted file mode 100644 index b7892ff60..000000000 --- a/.github/ISSUE_TEMPLATE/4-feature-request-zh-cn.yml +++ /dev/null @@ -1,26 +0,0 @@ -name: 功能建议 -description: 为 Kimi Code 提议新功能 -labels: - - enhancement -body: - - type: markdown - attributes: - value: | - Kimi Code 缺少你想要的某个功能?欢迎在这里提议。 - - 提交功能建议前: - 1. 先搜索已有 issue,如有类似功能,点 👍 而不是新开 issue。 - 2. Kimi Code 团队会在排序或拒绝新功能时尽量平衡社区的不同需求,请理解并非所有功能都会被接受。 - 3. 不要提交 feature PR。不接受外部功能 PR——功能在本 issue 中讨论和决定;如被接受,由团队实现或明确邀请你来贡献。 - - - type: textarea - id: feature - attributes: - label: 你希望看到什么功能? - validations: - required: true - - type: textarea - id: notes - attributes: - label: 补充信息 - description: 还有什么想让我们知道的? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index eaa61a910..940000f70 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,14 +1,13 @@ ## Related Issue - + Resolve #(issue_number) @@ -23,7 +22,7 @@ Resolve #(issue_number) ## Checklist - [ ] I have read the [CONTRIBUTING](https://github.com/MoonshotAI/kimi-code/blob/main/CONTRIBUTING.md) document. -- [ ] I have linked a related issue (external PRs: the issue must have a maintainer's `/approve`). +- [ ] I have linked a related issue, or explained the problem above. - [ ] I have added tests that prove my feature works. - [ ] Ran `gen-changesets` skill, or this PR needs no changeset. - [ ] Ran `gen-docs` skill, or this PR needs no doc update. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 636568d71..f470a476a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -66,27 +66,6 @@ jobs: - run: pnpm install --frozen-lockfile - run: pnpm --filter @moonshot-ai/pi-tui test - # The VS Code extension suite runs on the default (v2) engine as part of the - # sharded root run above; this job reruns it on the legacy v1 engine, which - # the extension selects through the rollback env var. - test-vscode-legacy: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - uses: pnpm/action-setup@v6 - - - uses: actions/setup-node@v6 - with: - node-version-file: .nvmrc - cache: pnpm - - - run: pnpm install --frozen-lockfile - - run: pnpm --filter kimi-code test - env: - KIMI_CODE_LEGACY_FLAG: "1" - test-windows: runs-on: windows-latest # Temporarily disabled while Windows tests are being stabilized. diff --git a/AGENTS.md b/AGENTS.md index fd94bcdfa..b18f4db8b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -48,7 +48,6 @@ This is a TypeScript monorepo built for agent-assisted development. Keep the roo ## General Coding Rules -- `packages/agent-core-v2`, `packages/kap-server`, and `packages/transcript` are comment-free zones: no comments of any kind — no line/block comments, no JSDoc (not even on exported symbols); the only exception is load-bearing lint-suppression directives (`oxlint-disable` / `eslint-disable`), while other tooling directives (`@ts-expect-error`, …) stay banned. Enforced by `scripts/check-no-comments.mjs` over `.ts`/`.tsx`/`.mts`/`.mjs` under `src/`/`test/`/`scripts/`, which runs as part of `pnpm lint`. - For optional object properties, pass `undefined` directly instead of using conditional spread. - YES: `{ user }` - NO: `{ ...(user ? { user } : undefined) }` @@ -83,7 +82,6 @@ This is a TypeScript monorepo built for agent-assisted development. Keep the roo - When an AI agent opens or updates a PR, fill in `.github/pull_request_template.md` — link the related issue or explain the problem, then describe what changed. Do not leave placeholder text or submit a generic summary of the diff. - Do not submit vague AI-generated PR text. The human author must understand the change well enough to explain the code, edge cases, and why the approach fits this repository. - After finishing a task and before submitting a PR, you must run the `gen-changesets` skill (see `.agents/skills/gen-changesets/SKILL.md`) and generate a changeset under `.changeset/` according to its rules. -- Changesets must strictly follow the rules in `.agents/skills/gen-changesets/SKILL.md`: write one short user-facing sentence that states only what changed, and skip any change users cannot perceive. - When generating a changeset, **never** decide on a `major` bump on your own — stop, explain, and get explicit user confirmation first; default to `minor`, fall back to `patch`. See `.agents/skills/gen-changesets/SKILL.md`. - Prefer importing via `import ... from '#/...'`, which serves the same purpose as `import ... from '@/...'`. - Do not commit throwaway scratch or exploratory files. Never stage: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ff90b934b..87173d926 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,5 @@ # Contributing to kimi-code -[中文版](CONTRIBUTING.zh-CN.md) - Thanks for taking the time to contribute! This project moves quickly, and thoughtful contributions from the community are what keep it sharp. The guide below walks you through how we work so your PR has the best chance of landing smoothly. ## Before You Start @@ -12,25 +10,27 @@ We hold AI-assisted contributions to the same standard as hand-written ones. **Y We only merge PRs aligned with the roadmap. Drive-by refactors without context are unlikely to land. -**External PRs are accepted for approved bug fixes only.** Open an issue first and wait for a maintainer to approve it with an `/approve` comment, then link that issue in your PR. PRs without an approved linked issue may be closed without review; once the issue is approved, ask a maintainer to reopen your PR. +**Discuss first** — open an issue before coding. PRs without prior discussion may be closed without review: -**Discuss first** — open an issue before coding: - -- Bug fixes, including small or typo-level ones: open a bug issue and wait for a maintainer's `/approve` before opening the PR -- New features or user-visible behavior changes (regardless of size): external feature PRs are not accepted — features are discussed and decided in issues, and accepted features are implemented by the team or by explicit maintainer invitation +- New features or user-visible behavior changes (regardless of size) - Refactors or other changes larger than ~100 lines - Public API or compatibility changes +- Bug fixes where the cause or fix approach is still unclear + +**Can open a PR directly** — link an existing issue when there is one: + +- Clear, reproducible bug fixes with a focused diff +- Typos, documentation-only changes, and small CI/build fixes +- Small changes that clearly match an existing issue or maintainer request ## Project Layout This is a pnpm monorepo. The most relevant entry points are: - `apps/kimi-code` — CLI / TUI -- `apps/vscode` — VS Code extension -- `apps/vis` — session debug visualizer +- `apps/vis` — session replay & debugging visualizer - `packages/node-sdk` — public TypeScript SDK (`@moonshot-ai/kimi-code-sdk`) -- `packages/agent-core-v2` — the agent engine (v2, DI Scope architecture); `packages/agent-core` is v1 and being phased out -- `packages/klient`, `kap-server`, `protocol`, `transcript`, `kosong`, `kaos`, `oauth`, `telemetry` — internal engine packages +- `packages/agent-core`, `kosong`, `kaos`, `oauth`, `telemetry` — internal engine packages - `docs/` — VitePress bilingual docs site For the full project map, see [AGENTS.md](AGENTS.md). @@ -84,7 +84,9 @@ This repo uses [changesets](https://github.com/changesets/changesets) to manage ## Pull Requests -Every PR opens with the [PR template](.github/pull_request_template.md). PR titles must follow [Conventional Commits](#commit-convention); CI runs `pnpm lint`, `pnpm typecheck`, and `pnpm test` on every PR. Update user-facing docs in `docs/` when behavior changes — use the `gen-docs` skill when working with coding agents. +Use the [PR template](.github/pull_request_template.md) when opening a feature pull request. + +PR titles must follow [Conventional Commits](#commit-convention); CI runs `pnpm lint`, `pnpm typecheck`, and `pnpm test` on every PR. Update user-facing docs in `docs/` when behavior changes — use the `gen-docs` skill when working with coding agents. ## Code Style diff --git a/CONTRIBUTING.zh-CN.md b/CONTRIBUTING.zh-CN.md deleted file mode 100644 index 160e6d76c..000000000 --- a/CONTRIBUTING.zh-CN.md +++ /dev/null @@ -1,102 +0,0 @@ -# 为 kimi-code 贡献代码 - -[English version](CONTRIBUTING.md) - -感谢你花时间参与贡献!这个项目迭代很快,离不开社区认真的贡献。下面的指南介绍我们的工作方式,帮助你的 PR 顺利合入。 - -## 开始之前 - -Kimi Code 对 CLI/TUI 行为、agent 工作流和公开 API 已有自己的主张。如果你的改动会改变这些方向,请先开 issue 对齐,再投入时间写 PR。 - -我们对 AI 辅助贡献与手写代码一视同仁。**你应该理解自己提交的内容**——改了什么、边界情况下表现如何、为什么适合这个代码库。如果你解释不清楚,这个 PR 就还没准备好接受评审。 - -我们只合入与路线图一致的 PR。缺乏上下文背景的顺手重构很难被接受。 - -**外部 PR 仅接受获批准的 bug 修复。** 先开 issue,等待维护者以 `/approve` 评论明确批准,然后在 PR 中链接该 issue。没有已批准关联 issue 的 PR 可能会不经评审直接关闭;issue 获批后,可联系维护者重开你的 PR。 - -**先讨论**——写代码前先开 issue: - -- bug 修复(包括小的、错别字级别的):先开 bug issue,等待维护者 `/approve` 后再提 PR -- 新功能或用户可见的行为变更(无论大小):不接受外部 feature PR——功能在 issue 中讨论和决定,被接受的功能由团队实现,或由维护者明确邀请你贡献 -- 重构或其他超过约 100 行的改动 -- 公开 API 或兼容性变更 - -## 项目结构 - -本仓库是 pnpm monorepo,最常用的入口: - -- `apps/kimi-code` — CLI / TUI -- `apps/vscode` — VS Code 插件 -- `apps/vis` — 会话调试可视化工具 -- `packages/node-sdk` — 公开 TypeScript SDK(`@moonshot-ai/kimi-code-sdk`) -- `packages/agent-core-v2` — 当前的 agent 引擎(v2,DI Scope 架构);`packages/agent-core` 为 v1,正在逐步废弃 -- `packages/klient`、`kap-server`、`protocol`、`transcript`、`kosong`、`kaos`、`oauth`、`telemetry` — 内部引擎包 -- `docs/` — VitePress 双语文档站 - -完整项目地图见 [AGENTS.md](AGENTS.md)。 - -## 开发环境 - -前置要求:Node.js >= 24.15.0、pnpm 10.33.0、Git。 - -```sh -git clone https://github.com/MoonshotAI/kimi-code.git -cd kimi-code -pnpm install -``` - -常用脚本: - -- `pnpm dev:cli` — 开发模式运行 CLI -- `pnpm test` — 运行测试(vitest) -- `pnpm typecheck` — TypeScript 检查(注意:会先构建各包) -- `pnpm lint` — oxlint -- `pnpm lint:fix` — oxlint 自动修复 -- `pnpm build` — 构建全部包 - -## 提交规范 - -所有 commit 和 PR 标题必须遵循 [Conventional Commits](https://www.conventionalcommits.org/)。 - -| 类型 | 用途 | 示例 | -|----------|------------------------------------------|----------------------------------------| -| feat | 新功能 | feat(agent-core): add tool dedup | -| fix | bug 修复 | fix(tui): correct status bar alignment | -| docs | 仅文档 | docs: clarify install instructions | -| chore | 工具 / 杂务 | chore: bump dependencies | -| refactor | 无行为变更的内部重构 | refactor(kosong): extract retry helper | -| test | 新增或改进测试 | test(agent-core): cover skill resolver | -| ci | CI / 构建流水线变更 | ci: cache pnpm store | -| build | 构建系统 / 产物变更 | build(native): add win32-arm64 target | -| perf | 性能优化 | perf(session): batch event flushes | -| style | 仅格式化(无逻辑变更) | style: apply oxlint --fix | - -PR 标题由 `pr-title-checker` 工作流强制校验——不合规的标题会阻止合并。 - -## Changesets - -本仓库使用 [changesets](https://github.com/changesets/changesets) 管理版本与发布。 - -- 每个影响发布产物(代码、行为、公开 API)的 PR **必须**包含 changeset。 -- 仅文档、仅测试或仅 CI 的 PR 可以不加。 -- 用 `pnpm changeset` 生成并按提示操作(涉及哪些包、什么 bump 级别)。 -- 包选择与 bump 级别的仓库约定见 `.changeset/README.md`。在本仓库使用编程 agent 时,使用 `gen-changesets` 技能。 - -## Pull Requests - -PR 会自动套用 [PR 模板](.github/pull_request_template.md)。PR 标题必须遵循 [Conventional Commits](#提交规范);每个 PR 的 CI 会运行 `pnpm lint`、`pnpm typecheck` 和 `pnpm test`。行为变更时请同步更新 `docs/` 下的用户文档——使用编程 agent 时使用 `gen-docs` 技能。 - -## 代码风格 - -- 全仓库 TypeScript。 -- 使用 `oxlint`(配置见 `.oxlintrc.json`)。 -- 用 `pnpm lint:fix` 自动格式化。 -- lint 规则未覆盖的风格选择,跟随周边现有写法。 - -## 报告安全问题 - -发现安全问题?请查看 [SECURITY.md](SECURITY.md),不要开公开 issue。 - -## 许可证 - -向本仓库贡献即表示你同意你的贡献按 [MIT 许可证](LICENSE) 授权。 diff --git a/GOAL.md b/GOAL.md index 2ab271225..c0fdc2a36 100644 --- a/GOAL.md +++ b/GOAL.md @@ -229,4 +229,3 @@ goal ID 不应暴露给模型,因为它只是 runtime/UI 内部标识,没有 goal 创建、暂停、恢复、阻塞、完成、清除都应发出 goal updated 事件。lifecycle 变化和 completion 变化应区分。completion 是一次终局事件,然后 snapshot 变 null。blocked/paused 保留 snapshot,UI 可以继续展示可恢复 goal。 session 恢复时,active goal 会变 paused,避免重启后自动继续。fork session 时不继承 goal,并提醒模型不要继续源 session 的目标。 - diff --git a/apps/kimi-code/CHANGELOG.md b/apps/kimi-code/CHANGELOG.md index 818ecfc8c..7d77d825a 100644 --- a/apps/kimi-code/CHANGELOG.md +++ b/apps/kimi-code/CHANGELOG.md @@ -1,277 +1,5 @@ # @moonshot-ai/kimi-code -## 0.38.0 - -### Minor Changes - -- [#2862](https://github.com/MoonshotAI/kimi-code/pull/2862) [`3d77620`](https://github.com/MoonshotAI/kimi-code/commit/3d7762003a4a35cbeb8571d471c6898a006152e6) Thanks [@liruifengv](https://github.com/liruifengv)! - Support two OAuth login methods — kimi.ai and kimi.com. - -- [#3060](https://github.com/MoonshotAI/kimi-code/pull/3060) [`8440801`](https://github.com/MoonshotAI/kimi-code/commit/8440801de47ddae29224430048e1228b80cde370) Thanks [@chengluyu](https://github.com/chengluyu)! - Add the WaitFor tool: the agent can now wait for a background task to finish within the current turn instead of ending the turn and being re-invoked. - -### Patch Changes - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Label inline subagent cards in the message stream with their foreground or background mode. - -- [#3121](https://github.com/MoonshotAI/kimi-code/pull/3121) [`3899079`](https://github.com/MoonshotAI/kimi-code/commit/3899079a2c851bd0b3f1cbf1d3d2fd9026fc6abb) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix config.toml entries being lost when the file had a syntax error or was edited outside the app. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Add copy buttons next to the server version and server address in settings. - -- [#3119](https://github.com/MoonshotAI/kimi-code/pull/3119) [`a34d02a`](https://github.com/MoonshotAI/kimi-code/commit/a34d02a64f9b1526ec84e161d8c377654b413624) Thanks [@wbxl2000](https://github.com/wbxl2000)! - Add 13 data sources to the official Kimi Datasource plugin — Chinese government data (NDA/NBS) and standards (GB/HB/DB/TT), eight international organization datasets (WHO, FAO, UNSD, ECB, Eurostat, UNICEF, OECD, FRED), Xinhua Finance, and Caixin. Update the plugin from the Official tab in /plugins. - -- [#3096](https://github.com/MoonshotAI/kimi-code/pull/3096) [`67fbcdf`](https://github.com/MoonshotAI/kimi-code/commit/67fbcdf1ba7dceeebb58875b3b7c81b4b30cf0de) Thanks [@sailist](https://github.com/sailist)! - Edit and Write now require reading an existing file before modifying it, and reject the write when the file changed on disk since it was last read. - -- [#3101](https://github.com/MoonshotAI/kimi-code/pull/3101) [`d96b4a0`](https://github.com/MoonshotAI/kimi-code/commit/d96b4a0149f3ddf3d4910cc6eb87366dbb130ede) Thanks [@kimi-agent-bot](https://github.com/kimi-agent-bot)! - Stop retrying requests blocked by the provider content filter; the filter notice now shows immediately. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Keep empty workspace groups visible in the legacy sidebar after their last session is archived. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Hide button hover tooltips outside a menu while the menu is open. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Keep the model picker menu on the workspace home within the viewport. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Fix the workspace group title showing untranslated text in the search dialog. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Fix the settings dialog dropdown list being clipped by the scroll area, and lock the content behind it while the list is open. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Keep the slash command and @ mention panels on the workspace home within the viewport. - -- [#3052](https://github.com/MoonshotAI/kimi-code/pull/3052) [`6595a69`](https://github.com/MoonshotAI/kimi-code/commit/6595a6989a68163e10a85c8edf1726b30d6d2c2b) Thanks [@RealKai42](https://github.com/RealKai42)! - Fix 422 errors from some OpenAI-compatible providers when a conversation includes tool calls. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Prevent text selection in the sidebar user menu and its plan usage submenu. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Fix slow session list loading when there are many workspaces. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Auto-open the browser authorization page after choosing a login region, redesign the authorization waiting page, and refresh the login state as soon as the window regains focus instead of waiting for the poll. - -- [#3083](https://github.com/MoonshotAI/kimi-code/pull/3083) [`571bcc2`](https://github.com/MoonshotAI/kimi-code/commit/571bcc2f751f02a37b0475b074a1e859c7fc4368) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix the missing OAuth authenticate tool for remote MCP servers that require login. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Upgrade the @ mention menu: file and skill candidates are merged and ranked by match quality, file search is faster, with path-fragment matching and hit highlighting. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Round menu items concentric with their menu frames. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Add a Pin action to the chat header more-menu to pin the current session to the sidebar pinned section. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Allow dragging the divider between the pinned section and the session list to resize both areas, with fade hints at the edges when the pinned section scrolls. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Improve the prompt queue interaction, with per-row steer and send. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Add kimi.com and kimi.ai OAuth login entries, and switch update and help links to the site matching the current login. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Remove sessions archived from another client from the session list immediately, without a manual refresh. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Label the timestamp at the bottom of the session menu as last active and tighten that row's padding. - -- [#3054](https://github.com/MoonshotAI/kimi-code/pull/3054) [`cfc3350`](https://github.com/MoonshotAI/kimi-code/commit/cfc335048378d3708666e11959c8d34507a1d659) Thanks [@Grapedge](https://github.com/Grapedge)! - Collapse long `!` shell command output instead of flooding the transcript. Press ctrl+o to expand or collapse it together with tool output. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Fix misaligned action buttons between the sidebar section headers and the session rows. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Remove the skill-activated card from skill activation messages. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Make skill-activation turns undoable so they can be withdrawn and resent. - -- [#3012](https://github.com/MoonshotAI/kimi-code/pull/3012) [`ca87c58`](https://github.com/MoonshotAI/kimi-code/commit/ca87c58e6205ddf0638e5d737a5f8e939e2132b9) Thanks [@sailist](https://github.com/sailist)! - Sub-agents no longer spawn their own sub-agents by default; custom agent profiles can still allow it explicitly. - -- [#3005](https://github.com/MoonshotAI/kimi-code/pull/3005) [`be8e017`](https://github.com/MoonshotAI/kimi-code/commit/be8e017597b83142282d7e6640076368bf244eae) Thanks [@wbxl2000](https://github.com/wbxl2000)! - Fix background agent rows that could not be stopped right after they appeared, and stray rows left behind when an agent failed to start. - -- [#3046](https://github.com/MoonshotAI/kimi-code/pull/3046) [`f13f379`](https://github.com/MoonshotAI/kimi-code/commit/f13f3790448f64448c76a415500041443ae754e6) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix the model being directed to unavailable tools when it encounters an image or binary file. - -- [#3108](https://github.com/MoonshotAI/kimi-code/pull/3108) [`05f2ad5`](https://github.com/MoonshotAI/kimi-code/commit/05f2ad5ddad1addf10ead6f5274554ca10cde1f4) Thanks [@kimi-agent-bot](https://github.com/kimi-agent-bot)! - web: clearing a goal now removes it from the transcript view instead of leaving the stale goal displayed. - -- [#3108](https://github.com/MoonshotAI/kimi-code/pull/3108) [`05f2ad5`](https://github.com/MoonshotAI/kimi-code/commit/05f2ad5ddad1addf10ead6f5274554ca10cde1f4) Thanks [@kimi-agent-bot](https://github.com/kimi-agent-bot)! - web: attachments sent with a prompt now appear in the live transcript immediately instead of only after a reload. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Tighten the row height and spacing of the account menu and its submenus to match the standard menu density. - -- [#3135](https://github.com/MoonshotAI/kimi-code/pull/3135) [`2c5415f`](https://github.com/MoonshotAI/kimi-code/commit/2c5415f930db3edef3e79a4e88c4ee74af123600) Thanks [@liruifengv](https://github.com/liruifengv)! - web: Give WaitFor tool calls a dedicated quiet-line display showing completed tasks, wait timeouts, and how many tasks are still running. - -## 0.37.2 - -### Patch Changes - -- [#3061](https://github.com/MoonshotAI/kimi-code/pull/3061) [`5c661f4`](https://github.com/MoonshotAI/kimi-code/commit/5c661f4610f36481dbf2f9598aa63f49004e4980) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: the subagent detail panel now keeps the working process fully expanded and drops the end-of-turn timestamp footer. - -- [#3061](https://github.com/MoonshotAI/kimi-code/pull/3061) [`5c661f4`](https://github.com/MoonshotAI/kimi-code/commit/5c661f4610f36481dbf2f9598aa63f49004e4980) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Settings gains a Lab tab with a multi-tab sidebar toggle (off by default); when enabled, the sidebar shows the Open / Done / Workspaces tabs. - -## 0.37.1 - -### Patch Changes - -- [#3053](https://github.com/MoonshotAI/kimi-code/pull/3053) [`95cede8`](https://github.com/MoonshotAI/kimi-code/commit/95cede82b4d3b6cb1845c66e87896ab2e5fd9ba5) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix pasted images failing to reach the model on first send. - -- [#3047](https://github.com/MoonshotAI/kimi-code/pull/3047) [`c9c34ae`](https://github.com/MoonshotAI/kimi-code/commit/c9c34ae5a8626f133bd1b9c34cac0f3270e35b8d) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix pasted videos failing to submit instead of reaching the model. - -## 0.37.0 - -### Minor Changes - -- [#2935](https://github.com/MoonshotAI/kimi-code/pull/2935) [`44a6c70`](https://github.com/MoonshotAI/kimi-code/commit/44a6c70e66762ea9e122f8dceae16dc759086a7c) Thanks [@chengluyu](https://github.com/chengluyu)! - Activate multiple skills in a single prompt. Type `/` after whitespace to insert a skill token. - -- [#2994](https://github.com/MoonshotAI/kimi-code/pull/2994) [`8c865f4`](https://github.com/MoonshotAI/kimi-code/commit/8c865f48173011439cfc2e140e45586e59b6bfcf) Thanks [@liruifengv](https://github.com/liruifengv)! - The Windows native (single-binary) CLI now supports automatic updates. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: the sidebar gains Open / Done / Workspaces tabs, and sessions can be marked as done (and reopened) to keep the open list focused. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: added a session management page (from the sidebar's list-management menu) for cross-workspace triage — filter by workspace, status, and updated time, and batch mark sessions as done or reopen them. - -### Patch Changes - -- [#2593](https://github.com/MoonshotAI/kimi-code/pull/2593) [`d833a1a`](https://github.com/MoonshotAI/kimi-code/commit/d833a1a893c4d69d96af542f40557442992085e0) Thanks [@7Sageer](https://github.com/7Sageer)! - Keep pasted image and video attachments available in session history. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: @-mentioned files, folders, and skills in chat messages now render as icon pills. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: renamed the Subagent panel to "Background Agent". - -- [#2914](https://github.com/MoonshotAI/kimi-code/pull/2914) [`1cf617d`](https://github.com/MoonshotAI/kimi-code/commit/1cf617d769a887f5d8306ebc16a1e078b5e47049) Thanks [@SeleneXX](https://github.com/SeleneXX)! - Fix Gemini tool-calling sessions failing on follow-up requests. - -- [#2972](https://github.com/MoonshotAI/kimi-code/pull/2972) [`04d23e2`](https://github.com/MoonshotAI/kimi-code/commit/04d23e2dab776c480d24cfa033c9500543c75a3b) Thanks [@sailist](https://github.com/sailist)! - Fix text files containing Chinese or emoji being misdetected as binary in the web UI. - -- [#2940](https://github.com/MoonshotAI/kimi-code/pull/2940) [`6b72345`](https://github.com/MoonshotAI/kimi-code/commit/6b72345f8bb03487e3bcc05b541e65484818428c) Thanks [@bj456736](https://github.com/bj456736)! - Print and copy the full `kimi --resume` command after `/fork`. - -- [#2928](https://github.com/MoonshotAI/kimi-code/pull/2928) [`d96cd03`](https://github.com/MoonshotAI/kimi-code/commit/d96cd037702637305422222e985139e51ff83c8c) Thanks [@chengluyu](https://github.com/chengluyu)! - Warn when a typed `/goal` objective exceeds the 4000-character limit, and keep the input if it is rejected. - -- [#2633](https://github.com/MoonshotAI/kimi-code/pull/2633) [`f492cd7`](https://github.com/MoonshotAI/kimi-code/commit/f492cd7c9e03666ecfd10dc47ca9b48c35de2318) Thanks [@tpoisonooo](https://github.com/tpoisonooo)! - Fix slow startup by loading the global search index on demand. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed YAML frontmatter in messages rendering as a giant heading — it now shows as a small meta block. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed plain text like "(c)", "(tm)", and "--" in messages being rewritten as ©, ™, and dashes — message text now renders verbatim. - -- [#2985](https://github.com/MoonshotAI/kimi-code/pull/2985) [`a7dc1ea`](https://github.com/MoonshotAI/kimi-code/commit/a7dc1ea28445555d5944066936fdf6e1b21d27ea) Thanks [@bj456736](https://github.com/bj456736)! - Fix a startup error when a restored session references a model that is no longer configured. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: hovering a mention pill now shows a detail bubble (full path for files and folders, description plus an open button for skills), skill and file mentions in messages are clickable, long file names middle-ellipsize, and deleted files are struck through. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed long task panel titles pushing the status badge, copy, and close buttons out of view — titles now ellipsize and show the full text on hover. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed pasting a copied folder into the composer failing the upload with a connection error — folders are now skipped instead. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: reduced animation power draw — the mascot and home doodle pause while hidden or scrolled offscreen, and looping animations play once and stop when the system's "reduce motion" setting is on. - -- [#2969](https://github.com/MoonshotAI/kimi-code/pull/2969) [`ee564e5`](https://github.com/MoonshotAI/kimi-code/commit/ee564e5ec90afd068123b8052928c53f1fd5a27d) Thanks [@sailist](https://github.com/sailist)! - Fix the displayed context size dropping to a smaller estimate after archiving and resuming a session. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: the plan review feedback box now auto-grows with its content, so longer rejection reasons are easier to write. - -- [#2633](https://github.com/MoonshotAI/kimi-code/pull/2633) [`f492cd7`](https://github.com/MoonshotAI/kimi-code/commit/f492cd7c9e03666ecfd10dc47ca9b48c35de2318) Thanks [@tpoisonooo](https://github.com/tpoisonooo)! - Queue slash skill commands entered while the agent is busy instead of rejecting them. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: the search dialog now finds workspaces too, and picking a workspace or session result expands the sidebar and scrolls the item into view. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed sent image and video attachments rendering broken in session history after a refresh or reopen. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed empty replies left by manually stopped answers still showing a completion time after reloading the page. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed background agent tasks not being cancellable during their first moments after starting. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed foreground subagents leaking into the Background Agent panel, which broke the count and left finished rows stuck as running and unstoppable. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: merged the task panel's two copy icons into a single button with a dropdown menu (copy command / copy output / copy all), with keyboard and touch-friendly targets. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed cancelled or abnormally ended background tasks showing as completed. - -- [#3016](https://github.com/MoonshotAI/kimi-code/pull/3016) [`98ebda8`](https://github.com/MoonshotAI/kimi-code/commit/98ebda840a1e420f57a05ec680cbeca41a2419d7) Thanks [@sailist](https://github.com/sailist)! - Fix /undo not restoring the todo list to its state before the undone turn. - -- [#2858](https://github.com/MoonshotAI/kimi-code/pull/2858) [`59dde73`](https://github.com/MoonshotAI/kimi-code/commit/59dde734f37596db5c77794060f81bfb3c1dbeb6) Thanks [@7Sageer](https://github.com/7Sageer)! - On the legacy engine, plugin MCP server changes and OAuth sign-in now take effect in open sessions immediately. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: the browser tab title now shows the current workspace directory name (override with the new `--web-title` flag), making instances on multiple machines easier to tell apart. - -- [#3043](https://github.com/MoonshotAI/kimi-code/pull/3043) [`e31b3a3`](https://github.com/MoonshotAI/kimi-code/commit/e31b3a335ed49139c1aa3abb6b45a244fa17356a) Thanks [@liruifengv](https://github.com/liruifengv)! - web: fixed Ctrl+K in the composer opening session search on macOS instead of deleting to end of line — session search now only answers to Cmd+K. - -- [#2989](https://github.com/MoonshotAI/kimi-code/pull/2989) [`09976b0`](https://github.com/MoonshotAI/kimi-code/commit/09976b09140c412f81a38cc00191f88bee4a9437) Thanks [@bj456736](https://github.com/bj456736)! - Add `kimi web --web-title ` to set a custom browser tab title for the web UI. - -## 0.36.1 - -### Patch Changes - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: The timestamp under assistant replies now shows the message time instead of the work duration. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Restyle the slash command and @ file mention menus: matched fragments are bold-highlighted in the slash menu, and long lists in both menus get a scroll fade and a draggable floating scrollbar. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: The background Bash panel now supports filtering by status, and clicking a task shows its command and output on the right. - -- [#2865](https://github.com/MoonshotAI/kimi-code/pull/2865) [`53909d9`](https://github.com/MoonshotAI/kimi-code/commit/53909d91e3ca570d4b565ba1abd00f027ca78d6b) Thanks [@weivwang](https://github.com/weivwang)! - Cache content-hashed Kimi Web assets across reloads while keeping the app entry point revalidated. - -- [#2916](https://github.com/MoonshotAI/kimi-code/pull/2916) [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797) Thanks [@Grapedge](https://github.com/Grapedge)! - Cancel an in-flight /init run together with the turn instead of letting it run to completion. - -- [#2911](https://github.com/MoonshotAI/kimi-code/pull/2911) [`249d8fa`](https://github.com/MoonshotAI/kimi-code/commit/249d8faa3447427665185a900926d048213d2ac7) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix sessions hanging on the second approval prompt and tool call results being dropped or mixed up in history when using a self-hosted OpenAI-compatible endpoint that renumbers tool call ids on every response. - -- [#2917](https://github.com/MoonshotAI/kimi-code/pull/2917) [`6cf315b`](https://github.com/MoonshotAI/kimi-code/commit/6cf315b7bdea8a04cfaeba1bb8931c1730853aec) Thanks [@wbxl2000](https://github.com/wbxl2000)! - Fix bare URLs in chat output absorbing the CJK characters that follow them, which made the link unclickable or open a broken address. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix the slash command panel staying open after switching sessions or when the composer loses focus. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Replace the composer mode menu with mutually exclusive plan/goal pills on the left of the input area (arm via /plan or /goal, exit with ×); Swarm becomes a separate toolbar toggle. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Restyle the work status pills above the composer with a borderless rounded look. - -- [#2910](https://github.com/MoonshotAI/kimi-code/pull/2910) [`eb72aeb`](https://github.com/MoonshotAI/kimi-code/commit/eb72aebeeb972b2fcc238d5650dd991a5580f96b) Thanks [@sailist](https://github.com/sailist)! - Remove the 64 MiB limit on web session exports, so large sessions no longer fail with a file-too-large error when downloaded from the web UI. - -- [#2884](https://github.com/MoonshotAI/kimi-code/pull/2884) [`1811bd4`](https://github.com/MoonshotAI/kimi-code/commit/1811bd4baf5b75ba076e2a24825f9c4f82c13341) Thanks [@liruifengv](https://github.com/liruifengv)! - Fix startup banner text wrapping on narrow terminals. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix `$` content inside inline code spans being misrendered as inline math. - -- [#2899](https://github.com/MoonshotAI/kimi-code/pull/2899) [`102984a`](https://github.com/MoonshotAI/kimi-code/commit/102984aa660d752ba8dd7d1aba155575f32affe2) Thanks [@oocz](https://github.com/oocz)! - Fix MCP OAuth cancellation leaving an in-flight authorization waiting for its callback timeout. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix the thinking-effort flyout being unreachable when selecting the last model in the subagent model list. - -- [#2876](https://github.com/MoonshotAI/kimi-code/pull/2876) [`5912d4c`](https://github.com/MoonshotAI/kimi-code/commit/5912d4c7d19d68975e85b007976b1bef59edae5c) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix repeated file-watcher errors on Windows when the workspace is a drive root (such as `E:\`) or a UNC network share. - -- [#2916](https://github.com/MoonshotAI/kimi-code/pull/2916) [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797) Thanks [@Grapedge](https://github.com/Grapedge)! - Show a clear error when forking a session while its turn is running, instead of copying a partially written turn. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix forking sessions with very long histories always failing with a timeout. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Selecting /goal from the slash menu now immediately arms a removable goal pill in the composer; typing and sending creates the goal without requiring the goal text after the command. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Restyle the goal panel: the goal text and elapsed time move to the header, and actions become icon buttons. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix CJK text immediately after a bare URL being swallowed into the link, which made the link unopenable. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Adjust when plan mode takes effect: enabling it now arms a removable plan pill in the composer and only activates when the message is sent, matching goal mode behavior. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Add a plan viewer panel: click a plan entry in the work bar to see the full plan, review results, and feedback. - -- [#2863](https://github.com/MoonshotAI/kimi-code/pull/2863) [`245e3d5`](https://github.com/MoonshotAI/kimi-code/commit/245e3d56a6de45e74d55449ef26cd65304a3250a) Thanks [@LouisDM](https://github.com/LouisDM)! - Prevent background task output from disrupting terminal pane borders. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Show a clear top-center confirmation toast after exporting a session, and a clearer error message when the export fails because the session is too large. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix the session list PR badge not refreshing after a PR is created from within a session. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Restyle the session list PR badge as a small tag with a background. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Unify session status display in the sidebar and stabilize session list ordering. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Slash commands now support fuzzy search: find commands by description text, pinyin, or pinyin initials. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Rework the subagent panel into a card grid layout with status filtering, showing in-progress and recently finished tasks by default. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Fix server request timeouts being misreported as "cannot connect to the Kimi server". - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Restyle the todo panel as frosted cards and add a current-progress completion count. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Increase the font size and row height of the user menu and the plan usage flyout. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Rename the user menu's "Upgrade" entry to "Upgrade membership" and label the plan usage percentage as used. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Add experimental automatic session title generation, with on-demand regeneration from the session list. - -- [#2922](https://github.com/MoonshotAI/kimi-code/pull/2922) [`cd48995`](https://github.com/MoonshotAI/kimi-code/commit/cd489955bb42c4a8055de9545d0b699b93bba98a) Thanks [@wbxl2000](https://github.com/wbxl2000)! - web: Add a "sort by recent activity" option to the workspace-grouped sidebar view (switched in the view options menu); newly added workspaces now sort to the top. - -## 0.36.0 - -### Minor Changes - -- [#2830](https://github.com/MoonshotAI/kimi-code/pull/2830) [`ec84a6f`](https://github.com/MoonshotAI/kimi-code/commit/ec84a6f9a3eb35e1118f8a327f7a11b3978a899c) Thanks [@liruifengv](https://github.com/liruifengv)! - Add an experimental fullscreen TUI mode. Set the `KIMI_CODE_TUI_FULL_SCREEN=1` environment variable to enable it. - -- [#2700](https://github.com/MoonshotAI/kimi-code/pull/2700) [`c9bfe8b`](https://github.com/MoonshotAI/kimi-code/commit/c9bfe8b2c8314ba4ef8806fb3b92ac654c1d1860) Thanks [@7Sageer](https://github.com/7Sageer)! - Add a configurable model pool for spawned subagents behind the `secondary-model` experiment (`KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`, or the master flag): with the experiment on, the `/secondary-model` command or the `[secondary_model]` section in config.toml sets a default model or a small named pool that the main agent picks from per spawn. A lone legacy `model` key in the same section keeps working as the fallback default. - -### Patch Changes - -- [#2830](https://github.com/MoonshotAI/kimi-code/pull/2830) [`ec84a6f`](https://github.com/MoonshotAI/kimi-code/commit/ec84a6f9a3eb35e1118f8a327f7a11b3978a899c) Thanks [@liruifengv](https://github.com/liruifengv)! - Render LaTeX math formulas (`$…$` / `$$…$$`) in messages as Unicode formulas. - -- [#2855](https://github.com/MoonshotAI/kimi-code/pull/2855) [`30f56a2`](https://github.com/MoonshotAI/kimi-code/commit/30f56a2d2da332cbf0c36a13cbe01aac5d319c7b) Thanks [@liruifengv](https://github.com/liruifengv)! - Fix Ctrl+C being ignored during automatic retries of failed API requests. - -- [#2819](https://github.com/MoonshotAI/kimi-code/pull/2819) [`fe3cdae`](https://github.com/MoonshotAI/kimi-code/commit/fe3cdae5f8ab40be71b65eff32319eb94a53c17d) Thanks [@7Sageer](https://github.com/7Sageer)! - Fix sessions failing with a provider 400 error on every follow-up request after a turn is interrupted while the model is still thinking, on strict OpenAI-compatible providers. - -- [#2847](https://github.com/MoonshotAI/kimi-code/pull/2847) [`3b0936d`](https://github.com/MoonshotAI/kimi-code/commit/3b0936d8e025c5a944759c40593d5f21bfb3e621) Thanks [@sailist](https://github.com/sailist)! - Fix plain Markdown files (such as CHANGELOG.md) in an installed plugin's root directory being misidentified as skills when the plugin relies on the root SKILL.md fallback. - -- [#2843](https://github.com/MoonshotAI/kimi-code/pull/2843) [`c212ae9`](https://github.com/MoonshotAI/kimi-code/commit/c212ae9715371c0d7939c15e664acbe0d7cf7fc3) Thanks [@sailist](https://github.com/sailist)! - Show project MCP launch targets in the workspace trust prompt, default to declining trust, and resolve fd and stty binaries to absolute paths so untrusted workspaces cannot plant bare-name executables before confirmation. - - `@moonshot-ai/kimi-code-sdk` contract change: `WorkspaceTrustInfo.gatedMcpServers` now carries structured `WorkspaceTrustMcpServerInfo` records (`name`, `transport`, and `command`/`args`/`cwd` or `url`) instead of plain strings, so SDK consumers rendering a trust prompt can show the full launch target. - -- [#2856](https://github.com/MoonshotAI/kimi-code/pull/2856) [`504e629`](https://github.com/MoonshotAI/kimi-code/commit/504e6292ede448367d1341751f9f98b24cc2994f) Thanks [@pvzheroes125](https://github.com/pvzheroes125)! - Refresh active MCP connections after OAuth credentials are added or reset. - ## 0.35.0 ### Minor Changes @@ -322,10 +50,6 @@ - [#2813](https://github.com/MoonshotAI/kimi-code/pull/2813) [`619564d`](https://github.com/MoonshotAI/kimi-code/commit/619564dcf9ee10a3cfbf7ecbc764c6b9b63fc91b) Thanks [@wbxl2000](https://github.com/wbxl2000)! - Fix the web UI repeatedly losing its realtime connection every ~30 seconds when the server runs behind a reverse proxy or gateway with an idle connection timeout; the server now sends a WebSocket heartbeat and only closes connections that stop responding entirely. -- [#2842](https://github.com/MoonshotAI/kimi-code/pull/2842) [`e476c5a`](https://github.com/MoonshotAI/kimi-code/commit/e476c5a8bbe68fb0b6eb0096aa1efcb893b1a8fc) Thanks [@wbxl2000](https://github.com/wbxl2000)! - Add the Modern Web Guidance plugin to the bundled plugin marketplace. Run /plugins and select Modern Web Guidance to install it. - -- Thanks [@Leakless](https://github.com/Leakless) and [@winmin](https://github.com/winmin) for reporting the Windows binary-planting issues fixed in this release. - ## 0.34.0 ### Minor Changes diff --git a/apps/kimi-code/dist-web/assets/CodeBlockNode-BAtAs_qm.js b/apps/kimi-code/dist-web/assets/CodeBlockNode-BAtAs_qm.js new file mode 100644 index 000000000..accf625fd --- /dev/null +++ b/apps/kimi-code/dist-web/assets/CodeBlockNode-BAtAs_qm.js @@ -0,0 +1,29 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DzfhniX8.js","assets/index-D-7nOosq.js","assets/index-DGHD7Bg9.css"])))=>i.map(i=>d[i]); +import{bR as xi,cb as Si,bQ as zo,M as vl,bl as Ci,af as dl,bY as Mi,cc as Bi,b$ as ml,aU as O,c0 as Ei,c1 as Fi,c2 as Pi,a0 as Co,aD as Ho,bE as ae,az as Li,cd as hn,c8 as vt,aI as No,aL as G,s as bn,aw as It,au as mt,bk as V,ce as Mo,u as oe,I as To,A as Oi,bJ as Ut,aY as pt,bL as cl,v as b,t as ye,bB as fl,bb as Me,q as k,b7 as $i,cf as zi,cg as gn,ch as Hi,ci as Ni,cj as Ti,ck as Ri,as as j,cl as Bo,cm as Di,cn as Ai,co as jt,cp as Eo,bO as Ro,T as ji,G as qi,F as Fo,g as Wi,c7 as _i,b_ as Ii}from"./index-D-7nOosq.js";import{i as fe,t as yn}from"./safeRaf-DGuzXxDK.js";var wn=(x,M,w)=>new Promise((te,ne)=>{var we=E=>{try{r(w.next(E))}catch(z){ne(z)}},be=E=>{try{r(w.throw(E))}catch(z){ne(z)}},r=E=>E.done?te(E.value):Promise.resolve(E.value).then(we,be);r((w=w.apply(x,M)).next())});let Po=!1,qt=null,Wt=null,_t=null;function Ui(){return wn(this,null,function*(){if(_t)return _t;_t=wn(null,null,function*(){if(!Wt)try{if(Wt=(function(x){const M=x;if(typeof M?.useMonaco=="function")return M;const w=x?.default;return typeof w?.useMonaco=="function"?w:null})(yield xi(()=>import("./index-DzfhniX8.js"),__vite__mapDeps([0,1,2]))),!Wt)return null}catch{return null}try{return yield(function(x){return wn(this,null,function*(){return Po?void 0:qt||(qt=wn(null,null,function*(){const w=globalThis?.MonacoEnvironment;w&&(typeof w.getWorker=="function"||typeof w.getWorkerUrl=="function")||typeof x?.preloadMonacoWorkers!="function"||(yield x.preloadMonacoWorkers()),Po=!0}).finally(()=>{qt=null}),qt)})})(Wt),Si(),Wt}catch{return null}});try{return yield _t}finally{_t=null}})}var Vi=Object.defineProperty,Gi=Object.defineProperties,Ji=Object.getOwnPropertyDescriptors,Lo=Object.getOwnPropertySymbols,Yi=Object.prototype.hasOwnProperty,Qi=Object.prototype.propertyIsEnumerable,Oo=(x,M,w)=>M in x?Vi(x,M,{enumerable:!0,configurable:!0,writable:!0,value:w}):x[M]=w,I=(x,M)=>{for(var w in M||(M={}))Yi.call(M,w)&&Oo(x,w,M[w]);if(Lo)for(var w of Lo(M))Qi.call(M,w)&&Oo(x,w,M[w]);return x},Ce=(x,M)=>Gi(x,Ji(M)),q=(x,M,w)=>new Promise((te,ne)=>{var we=E=>{try{r(w.next(E))}catch(z){ne(z)}},be=E=>{try{r(w.throw(E))}catch(z){ne(z)}},r=E=>E.done?te(E.value):Promise.resolve(E.value).then(we,be);r((w=w.apply(x,M)).next())});const Xi={key:0,class:"code-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)] border-[var(--code-border)] bg-[var(--code-header-bg)] text-[var(--code-fg)]"},Ki={class:"flex items-center gap-0.5"},Zi=["aria-label"],er={class:"code-diff-stat removed"},tr={class:"code-diff-stat added"},nr=["aria-label"],lr={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},or={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},ir=["aria-pressed"],rr={key:3,class:"relative"},ar=["aria-expanded"],ur=["disabled"],sr=["disabled"],dr=["disabled"],cr={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},fr={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},vr={class:"code-loading-placeholder"},mr={class:"sr-only","aria-live":"polite",role:"status"},pr=vl({__name:"CodeBlockShell",props:{showHeader:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},enableFontSizeControl:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0},showPreviewButton:{type:Boolean,default:!0},showTooltips:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},stream:{type:Boolean,default:!1},isCollapsed:{type:Boolean,default:!1},isExpanded:{type:Boolean,default:!1},copyText:{type:Boolean,default:!1},isPreviewable:{type:Boolean,default:!1},codeFontSize:{},codeFontMin:{},codeFontMax:{},defaultCodeFontSize:{},fontBaselineReady:{type:Boolean,default:!1},diffStats:{},diffStatsAriaLabel:{}},emits:["toggleCollapse","decreaseFont","resetFont","increaseFont","copy","toggleExpand","preview"],setup(x,{emit:M}){const w=x,te=M,ne=O(!1),we=O(null),be=O(null);function r(){vt(!0),ne.value=!ne.value,ne.value&&document.addEventListener("click",z,{once:!0,capture:!0})}function E(){vt(!0),ne.value=!1}function z(Y){var f,$;const yt=Y.target;(f=we.value)!=null&&f.contains(yt)||($=be.value)!=null&&$.contains(yt)?document.addEventListener("click",z,{once:!0,capture:!0}):E()}const ie=k(()=>w.showFontSizeButtons&&w.enableFontSizeControl||w.showExpandButton||w.isPreviewable&&w.showPreviewButton),{t:N}=ml(),ht=k(()=>w.showTooltips!==!1);function Ge(Y,f){ht.value&&_i(Y.currentTarget,f,"top",!1,void 0,w.isDark)}function Be(){ht.value&&vt()}function gt(Y){Ge(Y,w.copyText?N("common.copied")||"Copied":N("common.copy")||"Copy")}const pl=k(()=>{var Y,f;return!!Number.isFinite(w.codeFontSize)&&((Y=w.codeFontSize)!=null?Y:0)<=((f=w.codeFontMin)!=null?f:0)}),Vt=k(()=>!w.fontBaselineReady||w.codeFontSize===w.defaultCodeFontSize),Gt=k(()=>{var Y,f;return!!Number.isFinite(w.codeFontSize)&&((Y=w.codeFontSize)!=null?Y:0)>=((f=w.codeFontMax)!=null?f:100)});return(Y,f)=>(G(),oe(Fo,null,[w.showHeader?(G(),oe("div",Xi,[pt(Y.$slots,"header-left"),pt(Y.$slots,"header-right",{},()=>[b("div",Ki,[x.diffStats?(G(),oe("div",{key:0,class:"code-diff-stats","aria-label":x.diffStatsAriaLabel},[b("span",er,"-"+Me(x.diffStats.removed),1),b("span",tr,"+"+Me(x.diffStats.added),1)],8,Zi)):ye("",!0),w.showCopyButton?(G(),oe("button",{key:1,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] disabled:opacity-40 disabled:cursor-not-allowed transition-colors","aria-label":x.copyText?V(N)("common.copied")||"Copied":V(N)("common.copy")||"Copy",onClick:f[0]||(f[0]=$=>te("copy")),onMouseenter:f[1]||(f[1]=$=>gt($)),onFocus:f[2]||(f[2]=$=>gt($)),onMouseleave:Be,onBlur:Be},[x.copyText?(G(),oe("svg",or,[...f[14]||(f[14]=[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(G(),oe("svg",lr,[...f[13]||(f[13]=[b("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[b("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),b("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],40,nr)):ye("",!0),w.showCollapseButton?(G(),oe("button",{key:2,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] disabled:opacity-40 disabled:cursor-not-allowed transition-colors","aria-pressed":x.isCollapsed,onClick:f[3]||(f[3]=$=>te("toggleCollapse")),onMouseenter:f[4]||(f[4]=$=>Ge($,x.isCollapsed?V(N)("common.expand")||"Expand":V(N)("common.collapse")||"Collapse")),onFocus:f[5]||(f[5]=$=>Ge($,x.isCollapsed?V(N)("common.expand")||"Expand":V(N)("common.collapse")||"Collapse")),onMouseleave:Be,onBlur:Be},[(G(),oe("svg",{style:It({rotate:x.isCollapsed?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...f[15]||(f[15]=[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,ir)):ye("",!0),ie.value?(G(),oe("div",rr,[b("button",{ref_key:"moreBtnRef",ref:be,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] transition-colors","aria-expanded":ne.value,"aria-haspopup":"true",onClick:Ro(r,["stop"]),onMouseenter:f[6]||(f[6]=$=>Ge($,V(N)("common.more")||"More")),onFocus:f[7]||(f[7]=$=>Ge($,V(N)("common.more")||"More")),onMouseleave:Be,onBlur:Be},[...f[16]||(f[16]=[qi('<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="1em" height="1em" viewBox="0 0 24 24" class="action-icon"><g fill="currentColor"><circle cx="12" cy="5" r="1.5"></circle><circle cx="12" cy="12" r="1.5"></circle><circle cx="12" cy="19" r="1.5"></circle></g></svg>',1)])],40,ar),To(Wi,{name:"code-menu"},{default:Ut(()=>[ne.value?(G(),oe("div",{key:0,ref_key:"moreMenuRef",ref:we,class:"code-more-menu min-w-[10rem] p-1 bg-[hsl(var(--ms-popover))] text-[hsl(var(--ms-popover-foreground))] border border-[var(--code-border)] shadow-[var(--ms-shadow-popover)]",role:"menu"},[w.showFontSizeButtons&&w.enableFontSizeControl?(G(),oe(Fo,{key:0},[b("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:pl.value,onClick:f[8]||(f[8]=$=>{V(vt)(!0),te("decreaseFont")})},[f[17]||(f[17]=b("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 12h14"})],-1)),b("span",null,Me(V(N)("common.fontSmaller")||"Font size −"),1)],8,ur),b("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:Vt.value,onClick:f[9]||(f[9]=$=>{V(vt)(!0),te("resetFont")})},[f[18]||(f[18]=b("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[b("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[b("path",{d:"M3 12a9 9 0 1 0 9-9a9.75 9.75 0 0 0-6.74 2.74L3 8"}),b("path",{d:"M3 3v5h5"})])],-1)),b("span",null,Me(V(N)("common.fontReset")||"Font size reset"),1)],8,sr),b("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:Gt.value,onClick:f[10]||(f[10]=$=>{V(vt)(!0),te("increaseFont")})},[f[19]||(f[19]=b("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 12h14m-7-7v14"})],-1)),b("span",null,Me(V(N)("common.fontLarger")||"Font size +"),1)],8,dr)],64)):ye("",!0),w.showExpandButton?(G(),oe("button",{key:1,type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] transition-colors",onClick:f[11]||(f[11]=$=>{E(),te("toggleExpand")})},[x.isExpanded?(G(),oe("svg",cr,[...f[20]||(f[20]=[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6"},null,-1)])])):(G(),oe("svg",fr,[...f[21]||(f[21]=[b("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6"},null,-1)])])),b("span",null,Me(x.isExpanded?V(N)("common.collapse")||"Collapse":V(N)("common.expand")||"Expand"),1)])):ye("",!0),x.isPreviewable&&w.showPreviewButton?(G(),oe("button",{key:2,type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] transition-colors",onClick:f[12]||(f[12]=$=>{E(),te("preview")})},[f[22]||(f[22]=b("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[b("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[b("path",{d:"M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"}),b("circle",{cx:"12",cy:"12",r:"3"})])],-1)),b("span",null,Me(V(N)("common.preview")||"Preview"),1)])):ye("",!0)],512)):ye("",!0)]),_:1})])):ye("",!0)])])])):ye("",!0),cl(b("div",{class:mt(["code-block-shell-content",{"code-block-shell-content--collapsed":x.isCollapsed}])},[pt(Y.$slots,"default")],2),[[fl,!!x.stream||!x.loading]]),cl(b("div",vr,[pt(Y.$slots,"loading",{},()=>[f[23]||(f[23]=b("div",{class:"loading-skeleton"},[b("div",{class:"skeleton-line"}),b("div",{class:"skeleton-line"}),b("div",{class:"skeleton-line short"})],-1))])],512),[[fl,!x.stream&&x.loading]]),b("span",mr,Me(x.copyText?V(N)("common.copied")||"Copied":""),1)],64))}}),hr={class:"html-preview-frame__header"},gr={class:"html-preview-frame__title"},yr={class:"html-preview-frame__label"},wr=["sandbox","srcdoc"],br=zo(vl({__name:"HtmlPreviewFrame",props:{code:{},isDark:{type:Boolean},htmlPreviewAllowScripts:{type:Boolean},htmlPreviewSandbox:{},onClose:{type:Function},title:{}},setup(x){const M=x,w=import.meta!==void 0&&!1;let te=null;const{t:ne}=ml(),we=k(()=>{const E=M.code||"",z=E.trim().toLowerCase();return z.startsWith("<!doctype")||z.startsWith("<html")||z.startsWith("<body")?E:`<!doctype html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <style> + html, body { + margin: 0; + padding: 0; + height: 100%; + background-color: ${M.isDark?"#020617":"#ffffff"}; + color: ${M.isDark?"#e5e7eb":"#020617"}; + } + body { + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', ui-sans-serif, sans-serif; + } + </style> + </head> + <body> + ${E} + </body> +</html>`}),be=k(()=>{return E=M.htmlPreviewSandbox,z=M.htmlPreviewAllowScripts,typeof E=="string"?((function(ie){if(!w||typeof console>"u"||te===ie)return;const N=(function(ht){return new Set(ht.trim().toLowerCase().split(/\s+/).filter(Boolean))})(ie);N.has("allow-scripts")&&N.has("allow-same-origin")&&(te=ie,console.warn("[markstream-vue] htmlPreviewSandbox contains both allow-scripts and allow-same-origin. Use this only for fully trusted content served from an isolated origin."))})(E),E):E!==void 0?"":z===!0?"allow-scripts":"";var E,z});function r(E){var z;E.key!=="Escape"&&E.key!=="Esc"||(z=M.onClose)==null||z.call(M)}return Ho(()=>{typeof window<"u"&&window.addEventListener("keydown",r)}),No(()=>{typeof window<"u"&&window.removeEventListener("keydown",r)}),(E,z)=>(G(),bn(ji,{to:"body"},[b("div",{class:mt(["markstream-vue",{dark:M.isDark}])},[b("div",{class:"html-preview-frame__backdrop",onClick:z[2]||(z[2]=ie=>{var N;return(N=M.onClose)==null?void 0:N.call(M)})},[b("div",{class:"html-preview-frame",onClick:z[1]||(z[1]=Ro(()=>{},["stop"]))},[b("div",hr,[b("div",gr,[z[3]||(z[3]=b("span",{class:"html-preview-frame__dot"},null,-1)),b("span",yr,Me(M.title||V(ne)("common.preview")||"Preview"),1)]),b("button",{type:"button",class:"html-preview-frame__close",onClick:z[0]||(z[0]=ie=>{var N;return(N=M.onClose)==null?void 0:N.call(M)})}," × ")]),b("iframe",{class:"html-preview-frame__iframe",sandbox:be.value,referrerpolicy:"no-referrer",srcdoc:we.value},null,8,wr)])])],2)]))}}),[["__scopeId","data-v-24e66176"]]),kr=["data-markstream-enhanced","data-markstream-enhancement-state","data-markstream-code-block-state","data-markstream-pending","data-markstream-viewport-pending"],xr={class:"code-header-main"},Sr=["innerHTML"],Cr={class:"code-header-copy"},Mr={class:"code-header-title"},Br={key:0,class:"code-header-caption"},Er=["data-markstream-host-hidden"],$o="__markstreamMonacoPassiveTouchState__",Lr=zo(vl({__name:"CodeBlockNode",props:{node:{},isDark:{type:Boolean,default:!1},loading:{type:Boolean,default:!0},stream:{type:Boolean,default:!0},theme:{},darkTheme:{default:"vitesse-dark"},lightTheme:{default:"vitesse-light"},isShowPreview:{type:Boolean,default:!0},monacoOptions:{},enableFontSizeControl:{type:Boolean,default:!0},minWidth:{default:void 0},maxWidth:{default:void 0},themes:{},showPreviewButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},showTooltips:{type:Boolean},htmlPreviewAllowScripts:{type:Boolean},htmlPreviewSandbox:{},customId:{},showHeader:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0},estimatedHeightPx:{},estimatedContentHeightPx:{},estimatedDiffInline:{type:Boolean}},emits:["previewCode","copy"],setup(x,{emit:M}){var w,te,ne,we,be;const r=x,E=M,z=Ci(),ie=dl(Mi,null),N=dl("markstreamHostScrollManaged",null),ht=dl(Bi,void 0),Ge=k(()=>Ii(r,z)),Be=new Set;function gt(e){return q(this,null,function*(){var t;if(typeof window>"u")return yield e();const n=(t=window.Element)==null?void 0:t.prototype,l=n?.addEventListener;if(!n||!l)return yield e();const o=(function(){const d=window,u=d[$o];if(u)return u;const a={depth:0,original:null};return d[$o]=a,a})();let i=null;try{o.depth===0&&(o.original=l,n.addEventListener=function(u,a,c){var s;const v=(s=o.original)!=null?s:l;return u==="touchstart"&&(function(p,y){if(!p)return!1;const h=p;return!(typeof h.closest!="function"||!h.closest(".monaco-editor, .monaco-diff-editor")||y&&typeof y=="object"&&"passive"in y)})(this,c)?v.call(this,u,a,(function(p){return p==null?{passive:!0}:typeof p=="boolean"?{capture:p,passive:!0}:typeof p=="object"?"passive"in p?p:Ce(I({},p),{passive:!0}):{passive:!0}})(c)):v.call(this,u,a,c)}),o.depth++;let d=!1;i=()=>{d||(d=!0,Be.delete(i),o.depth=Math.max(0,o.depth-1),o.depth===0&&o.original&&n.addEventListener!==o.original&&(n.addEventListener=o.original,o.original=null))},Be.add(i)}catch{return yield e()}try{return yield e()}finally{i?.()}})}function pl(e,t){}const Vt=Co(),Gt=k(()=>{const e=Vt?.vnode.props;return!(!e||!e.onPreviewCode&&!e["onPreview-code"])}),{t:Y}=ml(),f=O(null),$=O(null),yt=O(!1),ke=O(oo(r.node.language,r.node.code,Ue())),kn=k(()=>Bo(ke.value)),Ee=k(()=>kn.value==="plaintext"?"text":kn.value),xn=k(()=>kn.value==="plaintext"),Fe=O(!1),xe=O(!1),Q=O(!1),Se=O(!1),W=O(!1),wt=O(!1);let B=!1,bt=null,Bt=null,Je=null,Ye=0,Qe=!1,qe="";const We=O(null),ve=O(null);let Sn=null,Cn=0,Mn=!1;const Do=Ei(),Jt=Fi(),Bn=Pi(),_e=$i(null),Z=O(typeof window>"u"||!Bn.value),Ao=(ne=(te=(w=Co())==null?void 0:w.vnode.el)==null?void 0:te.textContent)!=null?ne:"",jo=typeof window<"u"&&String((we=r.node.code)!=null?we:"").length>0&&Ao.includes(String(r.node.code)),hl=O(!jo);Ho(()=>{hl.value=!0}),typeof window<"u"&&ae([()=>$.value,Bn],([e,t],n,l)=>{var o,i,d;if((o=_e.value)==null||o.destroy(),_e.value=null,!t||Z.value)return void(Z.value=!0);if(!e)return void(Z.value=!1);let u=!0;const a=(d=(i=Jt?.value.heavyBlockMargin)!=null?i:Jt?.value.rootMargin)!=null?d:"0px",c=Do(e,{rootMargin:a,allowIdle:!1});_e.value=c,Z.value=Z.value||c.isVisible.value,c.whenVisible.then(()=>{u&&_e.value===c&&(Z.value=!0)}).catch(()=>{}),l(()=>{u=!1,c.destroy(),_e.value===c&&(_e.value=null)})},{immediate:!0}),Li(()=>{var e;B=!0;for(const t of Array.from(Be))t();(function(){const t=qe;ie&&t&&(qe="",ie.markSettled(t))})(),(e=_e.value)==null||e.destroy(),_e.value=null});let ue=null,Yt=null,En=()=>{},Qt=()=>{},kt=()=>null,se=()=>({getModel:()=>({getLineCount:()=>1}),getOption:()=>14,updateOptions:()=>{}}),U=()=>({getModel:()=>({getLineCount:()=>1}),getOption:()=>14,updateOptions:()=>{}}),Fn=()=>{},Xe=()=>{},Pn=()=>{},Ke=null,$e=null,Et=null,Ft=null,gl=()=>{var e;return String((e=r.node.language)!=null?e:"plaintext")},Ln=()=>q(null,null,function*(){}),On=!1,Xt=null;const ze=[],$n=[];let He=null;const m=k(()=>zi(r.node)),Ze=O({removed:0,added:0}),qo=k(()=>`-${Ze.value.removed} +${Ze.value.added}`),yl=Object.freeze(Ce(I({},jt),{enabled:!1,revealLineCount:0}));function wl(e){var t,n,l;const o=((n=(t=$.value)==null?void 0:t.getBoundingClientRect)==null?void 0:n.call(t).width)||((l=$.value)==null?void 0:l.clientWidth)||(typeof window>"u"?0:window.innerWidth);return Di(e,o)}function Pt(e,t){return{original:Kt(e),updated:Kt(t)}}function Kt(e){return String(e??"").replace(/\r\n$|\n$|\r$/,"")}function Lt(e){var t;return String((t=e?.message)!=null?t:e).includes("no diff result available")}function xt(){if(!Oe())try{const e=Pn();e&&typeof e.catch=="function"&&e.catch(t=>{Lt(t)})}catch(e){Lt(e)}}const re=k(()=>{var e,t,n,l;const o=r.monacoOptions?I({},r.monacoOptions):{};if(!m.value)return I({lineDecorationsWidth:0,lineNumbersMinChars:2,glyphMargin:!1},o);const i=o.diffHideUnchangedRegions===void 0?I({},jt):gn(o.diffHideUnchangedRegions),d=o.hideUnchangedRegions===void 0?void 0:gn(o.hideUnchangedRegions),u=r.stream!==!1&&r.loading!==!1,a=u?I({},yl):i,c=u?I({},yl):d,s=(function(g){return g.diffWordWrap!==void 0?g.diffWordWrap:"off"})(o),v=I({},(e=o.experimental)!=null?e:{}),p=(t=o.diffUnchangedRegionStyle)!=null?t:"line-info",y=(function(g){const X=g.scrollbar&&typeof g.scrollbar=="object"?g.scrollbar:{};return I(Ce(I({},X),{verticalScrollbarSize:0,horizontalScrollbarSize:0}),wl(g)?{horizontal:"hidden"}:{})})(o),h={maxComputationTime:0,diffAlgorithm:"legacy",ignoreTrimWhitespace:!1,renderIndicators:!0,diffUpdateThrottleMs:120,renderLineHighlight:"none",renderLineHighlightOnlyWhenFocus:!0,selectionHighlight:!1,occurrencesHighlight:"off",matchBrackets:"never",lineDecorationsWidth:4,lineNumbersMinChars:2,glyphMargin:!1,padding:{top:0,bottom:0},minimap:{enabled:!1},renderOverviewRuler:!1,overviewRulerBorder:!1,hideCursorInOverviewRuler:!0,scrollBeyondLastLine:!1,diffWordWrap:s,renderSideBySide:(n=o.renderSideBySide)==null||n,diffHideUnchangedRegions:a,useInlineViewWhenSpaceIsLimited:(l=o.useInlineViewWhenSpaceIsLimited)!=null&&l,diffLineStyle:"background",diffAppearance:"auto",diffUnchangedRegionStyle:p,diffHunkActionsOnHover:!1,experimental:v};return Ce(I(Ce(I(I({},h),o),{experimental:v}),c===void 0?{}:{hideUnchangedRegions:c}),{diffHideUnchangedRegions:a,diffWordWrap:s,scrollbar:y})}),zn=k(()=>(r.theme!==void 0?!fo(r.theme):vo(r.darkTheme,r.lightTheme))?(function(e){var t,n;if(e&&typeof e=="object"&&((t=e.colors)!=null&&t["editor.background"])){const o=Kn(e.colors["editor.background"]);if(o!=null)return o<128}const l=((n=rt(e))!=null?n:"").toLowerCase();return l?["dark","night","moon","black","dracula","mocha","frappe","macchiato","palenight","ocean","poimandres","monokai","laserwave","tokyo","slack-dark","rose-pine","github-dark","material-theme","one-dark","catppuccin-mocha","catppuccin-frappe","catppuccin-macchiato"].some(o=>l.includes(o))&&!["light","latte","dawn","lotus"].some(o=>l.includes(o)):!!r.isDark})(Tt()):!!r.isDark),Hn=k(()=>{var e;if(!m.value)return zn.value?"dark":"light";const t=(e=re.value)==null?void 0:e.diffAppearance;return t==="light"||t==="dark"?t:zn.value?"dark":"light"}),bl=k(()=>m.value?Hn.value==="dark":zn.value),Ot=k(()=>m.value?"diff":"single"),kl=O(Ot.value),ge=O(!1),D=O(!1),$t=O(!1),me=O(!1),et=O(null),Nn=O(0),xl=O(0),Zt=O(!1);let zt=null,tt=!1,Tn=null,Rn=!1;const Dn=k(()=>{var e,t,n;if(m.value){const o=(e=re.value)==null?void 0:e.diffWordWrap;if(o==="inherit"){const i=(t=r.monacoOptions)==null?void 0:t.wordWrap;return i==null||String(i)!=="off"}return o==="on"}const l=(n=r.monacoOptions)==null?void 0:n.wordWrap;return l==null||String(l)!=="off"}),Ie=k(()=>{var e;return!!m.value&&wl((e=re.value)!=null?e:{})}),An=k(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.diffHideUnchangedRegions;return t===void 0?I({},jt):gn(t)});function Sl(e){return N?.value===!0||!!e&&(!!e.closest('[data-markstream-virtual-timeline="1"], .markstream-virtual-timeline')||!!e.closest(".vue-recycle-scroller, [data-virtualizer], [data-virtual-scroll-root]"))}const Wo=k(()=>Sl($.value)),Ne=k(()=>!(ge.value||!me.value&&D.value)),Cl=k(()=>Ne.value),_o=k(()=>Ne.value&&!$t.value),Io=k(()=>!ge.value&&!me.value&&Ne.value),Uo=k(()=>D.value&&!ge.value?"ready":me.value?"fallback":"pending"),en=O(!1),Te=k(()=>Kt(r.node.code)),Ml=k(()=>m.value?r.node.diff===!0?r.node:Ce(I({},r.node),{diff:!0}):Te.value===r.node.code?r.node:Ce(I({},r.node),{code:Te.value})),pe=O(typeof((be=r.monacoOptions)==null?void 0:be.fontSize)=="number"?r.monacoOptions.fontSize:Number.NaN),_=O(pe.value),jn=O(null),tn=O(null),nn=O(null),Vo=k(()=>{const e=pe.value,t=_.value;return typeof e=="number"&&Number.isFinite(e)&&e>0&&typeof t=="number"&&Number.isFinite(t)&&t>0}),ln=k(()=>{var e;const t=jn.value;if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;const n=(e=r.monacoOptions)==null?void 0:e.fontSize;if(typeof n=="number"&&Number.isFinite(n)&&n>0)return n;const l=_.value;return typeof l=="number"&&Number.isFinite(l)&&l>0?l:12}),Go=k(()=>{var e;const t=tn.value;if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;const n=(e=r.monacoOptions)==null?void 0:e.lineHeight;return typeof n=="number"&&Number.isFinite(n)&&n>0?n:ln.value===12?18:Math.max(12,Math.round(1.5*ln.value))}),on=k(()=>Go.value),Jo=k(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.tabSize;return typeof t=="number"&&Number.isFinite(t)&&t>0?t:4}),qn=k(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.padding,n=m.value?0:8;return{top:typeof t?.top=="number"&&Number.isFinite(t.top)&&t.top>=0?t.top:n,bottom:typeof t?.bottom=="number"&&Number.isFinite(t.bottom)&&t.bottom>=0?t.bottom:n}}),rn=k(()=>{const e=r.estimatedContentHeightPx;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:null});function an(e){if(e==null)return null;const t=Math.ceil(e);return!Number.isFinite(t)||t<=0?null:Math.min(t,Math.ceil(Ct()))}function Wn(){return!m.value&&r.stream!==!1&&r.loading!==!1}const Bl=k(()=>m.value?null:rn.value==null||Wn()?Math.ceil((e=>{const t=String(e??"");return t?Math.max(1,t.split(/\r\n|\n|\r/).length):1})(Te.value)*on.value+1):null),El=k(()=>{if(m.value)return null;const e=rn.value;return e==null||Wn()?an(Bl.value):an(e)}),Yo=k(()=>{const e=r.estimatedHeightPx;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:null}),_n=O(null);function nt(){const e=_n.value;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.round(e):null}const In=k(()=>{const e=nt();return e??(!m.value&&Zt.value?null:Ne.value||!D.value?El.value:null)});function Fl(e){const t=e?"hsl(152 42% 60%)":"var(--diff-added-fg)",n=e?"hsl(0 58% 58%)":"var(--diff-removed-fg)",l=e?"hsl(152 42% 60% / 0.18)":"var(--diff-added-bg)",o=e?"hsl(0 58% 58% / 0.18)":"var(--diff-removed-bg)",i=e?"hsl(152 42% 60% / 0.28)":"var(--diff-added-inline-bg)",d=e?"hsl(0 58% 58% / 0.28)":"var(--diff-removed-inline-bg)",u=`linear-gradient(90deg, ${t} 0 4px, transparent 4px 100%)`,a=`linear-gradient(90deg, ${n} 0 4px, transparent 4px 100%)`,c=e?"hsl(0 0% 7% / 0.98)":"hsl(var(--ms-muted) / 0.45)",s="var(--markstream-code-layout-character-width, 1ch)",v=`calc(${s} + ${s})`,p=`calc(${s} + ${s} + ${s} + ${s} + ${s} + 2px)`,y=`calc(${p} + ${s})`;return{"--markstream-diff-line-number-bg":c,"--markstream-diff-added-fg":t,"--markstream-diff-removed-fg":n,"--markstream-diff-added-line":l,"--markstream-diff-removed-line":o,"--markstream-diff-added-line-fill":l,"--markstream-diff-removed-line-fill":o,"--markstream-diff-added-gutter":u,"--markstream-diff-removed-gutter":a,"--markstream-diff-added-inline":i,"--markstream-diff-removed-inline":d,"--stream-monaco-added-fg":t,"--stream-monaco-removed-fg":n,"--stream-monaco-added-line":l,"--stream-monaco-removed-line":o,"--stream-monaco-added-line-fill":l,"--stream-monaco-removed-line-fill":o,"--stream-monaco-added-gutter":u,"--stream-monaco-removed-gutter":a,"--stream-monaco-added-inline":i,"--stream-monaco-removed-inline":d,"--stream-monaco-gutter-marker-width":"4px","--stream-monaco-gutter-gap":"1ch","--stream-monaco-line-number-left":"0px","--stream-monaco-line-number-width":v,"--stream-monaco-line-number-padding-left":v,"--stream-monaco-line-number-padding-right":s,"--stream-monaco-line-number-separator-width":"2px","--stream-monaco-layout-character-width":s,"--stream-monaco-line-number-box-width":p,"--stream-monaco-line-number-gap-to-code":s,"--stream-monaco-line-number-bg":c,"--stream-monaco-diff-code-gap":s,"--stream-monaco-diff-code-padding":"0px","--stream-monaco-original-margin-width":y,"--stream-monaco-original-scrollable-left":y,"--stream-monaco-original-scrollable-width":`calc(100% - ${y})`,"--stream-monaco-modified-margin-width":y,"--stream-monaco-modified-scrollable-left":y,"--stream-monaco-modified-scrollable-width":`calc(100% - ${y})`}}const Pl=k(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.fontFamily,n=an(rn.value),l=an(Bl.value),o=Wn(),i=I(I({fontSize:`${ln.value}px`,lineHeight:`${on.value}px`,tabSize:Jo.value,boxSizing:"border-box",maxHeight:`${Ct()}px`,overflow:"auto",paddingTop:`${qn.value.top}px`,paddingBottom:`${qn.value.bottom}px`},m.value||n==null||o?m.value||l==null?{}:{minHeight:`${l}px`}:{height:`${n}px`,minHeight:`${n}px`}),typeof t=="string"&&t.trim()?{"--markstream-code-font-family":t.trim()}:{});return i["--markstream-pre-line-number-top"]=`${qn.value.top}px`,i["--markstream-code-padding-left"]="calc(2ch + 2ch + 1ch + 2px + 1ch)",i["--markstream-pre-line-number-left"]="0px",i["--markstream-pre-line-number-width"]="2ch",i["--markstream-pre-line-number-padding-left"]="2ch",i["--markstream-pre-line-number-padding-right"]="1ch",i["--markstream-pre-line-number-separator-width"]="2px",m.value&&(i["--markstream-pre-diff-line-height"]=`${on.value}px`,i["--markstream-pre-diff-pane-bottom-padding"]=(Ie.value,"0px"),Object.assign(i,Fl(bl.value))),i}),Ll=k(()=>In.value!=null&&(!D.value||nt()!=null)),Qo=k(()=>{const e=In.value;if(e==null)return null;if(m.value)return Math.ceil(e);const t=Yo.value,n=rn.value;if(t==null||n==null)return Math.ceil(e);const l=Math.max(0,Math.ceil(t)-Math.ceil(n));return Math.ceil(e+l)}),Xo=k(()=>{if(m.value&&Ne.value)return{};const e=In.value;return Ll.value&&e!=null?{minHeight:`${e}px`}:{}});function Ol(){var e,t,n,l,o,i,d,u;const a=(e=$.value)==null?void 0:e.querySelector("pre.code-pre-fallback"),c=U(),s=(t=a?.scrollTop)!=null?t:0;(o=(l=(n=c?.getOriginalEditor)==null?void 0:n.call(c))==null?void 0:l.setScrollTop)==null||o.call(l,s),(u=(d=(i=c?.getModifiedEditor)==null?void 0:i.call(c))==null?void 0:d.setScrollTop)==null||u.call(d,s)}function $l(){return q(this,null,function*(){return m.value?(Zn()!=null||un(),ee(!0),Ol(),he(),$t.value=!0,yield j(),ee(!0),yield Pe(),ee(!0),!(Ke&&!(yield Ke())||(Nt(),un(),ee(!0),D.value=!0,yield j(),un(),ee(!0),Nt(),he(),de(),0))):!(Ke&&!(yield Ke())||(D.value=!0,yield j(),le(!1),ee(),0))})}function un(){const e=f.value;return e&&cn(e)?(he(),le({preferModelDiffHeight:!0}),it(),Number.parseFloat(e.style.height||"")||null):Zn()}function zl(){if(!m.value||!W.value||!D.value||Ne.value)return!1;const e=f.value;return!!e&&Ht(e)}function Hl(e,t=!1,n={}){const l=Math.ceil(e),o=nt();if(o==null)return l;const i=n.allowBelowEstimatedFloor===!0||zl();return l>=o||i?((t||i)&&W.value&&(_n.value=null),l):o}function Pe(){return new Promise(e=>{let t=!1,n=null,l=null;const o=()=>{t||(t=!0,l!=null&&globalThis.clearTimeout(l),n!=null&&yn(n),e())};l=globalThis.setTimeout(o,50),n=fe(o)})}function Nl(){try{const e=f.value;if(!e)return null;const t=e.querySelector(".view-lines .view-line");if(t){const n=Math.ceil(t.getBoundingClientRect().height);if(n>0)return n}}catch{}return null}function Un(){var e,t,n,l,o;try{const i=m.value?(n=(t=(e=U())==null?void 0:e.getModifiedEditor)==null?void 0:t.call(e))!=null?n:U():se(),d=kt(),u=(l=d?.EditorOption)==null?void 0:l.fontInfo;if(i&&u!=null){const a=(o=i.getOption)==null?void 0:o.call(i,u),c=a?.fontSize;if(typeof c=="number"&&Number.isFinite(c)&&c>0)return c}}catch{}try{const i=f.value;if(i){const d=i.querySelector(".view-lines .view-line");if(d)try{if(typeof window<"u"&&typeof window.getComputedStyle=="function"){const u=window.getComputedStyle(d).fontSize,a=u&&u.match(/^(\d+(?:\.\d+)?)/);if(a)return Number.parseFloat(a[1])}}catch{}}}catch{}return null}function St(e){var t,n;try{const i=kt(),d=(t=i?.EditorOption)==null?void 0:t.lineHeight;if(d!=null){const u=(n=e?.getOption)==null?void 0:n.call(e,d);if(typeof u=="number"&&u>0)return u}}catch{}const l=Nl();if(l&&l>0)return l;const o=Number.isFinite(_.value)&&_.value>0?_.value:14;return Math.max(12,Math.round(1.35*o))}function sn(e){var t,n,l;try{const i=kt(),d=(t=i?.EditorOption)==null?void 0:t.padding;if(d!=null){const u=(n=e?.getOption)==null?void 0:n.call(e,d);if(typeof u?.top=="number"||typeof u?.bottom=="number")return(typeof u?.top=="number"&&Number.isFinite(u.top)?Math.max(0,u.top):0)+(typeof u?.bottom=="number"&&Number.isFinite(u.bottom)?Math.max(0,u.bottom):0)}}catch{}const o=(l=re.value)==null?void 0:l.padding;return typeof o?.top=="number"||typeof o?.bottom=="number"?(typeof o?.top=="number"&&Number.isFinite(o.top)?Math.max(0,o.top):0)+(typeof o?.bottom=="number"&&Number.isFinite(o.bottom)?Math.max(0,o.bottom):0):m.value?24:0}function Tl(e,t){return typeof e!="number"||typeof t!="number"||e<1||t<e?0:t-e+1}function Rl(e){if(!e)return[];const t=e.split(/\r?\n/);return t.length===1&&t[0]===""?[]:t}function dn(e,t){const n=Rl(e),l=Rl(t);let o=0,i=n.length-1,d=l.length-1;for(;o<=i&&o<=d&&n[o]===l[o];)o++;for(;i>=o&&d>=o&&n[i]===l[d];)i--,d--;const u=Math.max(0,i-o+1),a=Math.max(0,d-o+1);if(u===0||a===0)return{removed:u,added:a};if((u+1)*(a+1)<=15e5){const c=a+1;let s=new Uint32Array(c),v=new Uint32Array(c);for(let y=u-1;y>=0;y--){v[a]=0;for(let g=a-1;g>=0;g--)v[g]=n[o+y]===l[o+g]?s[g+1]+1:Math.max(s[g],v[g+1]);const h=s;s=v,v=h}const p=s[0];return{removed:u-p,added:a-p}}return{removed:u,added:a}}function Dl(e){var t;if(!(function(){var d,u,a;return!(!m.value||!Ie.value)&&(r.node.originalCode!=null||r.node.updatedCode!=null?dn(String((d=r.node.originalCode)!=null?d:""),String((u=r.node.updatedCode)!=null?u:"")).removed>0:String((a=r.node.code)!=null?a:"").split(/\r\n|\n|\r/).some(c=>(function(s){return s.startsWith("-")&&!s.startsWith("---")})(c)))})())return!0;const n=e?.querySelector(".stream-monaco-fallback-inline-delete-line");if((t=n?.textContent)!=null&&t.trim()&&(n.hasAttribute("data-stream-monaco-colorize-signature")||n.querySelector('[class*="mtk"]')))return!0;const l=e?.querySelector([".editor.modified .view-zones .view-lines.line-delete",".editor.modified .view-lines .view-line.line-delete",".editor.original .view-zones .view-lines.line-delete",".editor.original .view-lines .view-line.line-delete"].join(","));if(!l||!l.matches(".view-line")&&!l.querySelector(".view-line"))return!1;const o=l.getBoundingClientRect(),i=e?.getBoundingClientRect();return i?.width===0&&i.height===0||o.width>0&&o.height>0}function Al(e,t){if(!e)return!1;const n=t.added<=0||!!e.querySelector([".line-insert",".gutter-insert",".stream-monaco-fallback-line-insert",".stream-monaco-fallback-gutter-insert",".stream-monaco-fallback-line-number-insert"].join(",")),l=t.removed<=0||!!e.querySelector([".line-delete",".gutter-delete",".inline-deleted-margin-view-zone",".stream-monaco-fallback-line-delete",".stream-monaco-fallback-gutter-delete",".stream-monaco-fallback-line-number-delete",".stream-monaco-fallback-inline-delete-line",".stream-monaco-fallback-inline-delete-margin"].join(","));return n&&l}function Vn(e,t){const n=e?.querySelector(t);return n instanceof HTMLElement?typeof window>"u"||typeof window.getComputedStyle!="function"?n:window.getComputedStyle(n).display==="none"?null:n:null}function jl(e,t){return Vn(e,t)!==null}function ql(e,t){if(!e)return!1;const n=t.added<=0||[".gutter-insert",".stream-monaco-fallback-gutter-insert"].some(o=>jl(e,o)),l=t.removed<=0||[".gutter-delete",".inline-deleted-margin-view-zone",".stream-monaco-fallback-gutter-delete",".stream-monaco-fallback-inline-delete-margin"].some(o=>jl(e,o));return n&&l}function Wl(e){var t;const n=Array.from((t=e?.querySelectorAll(".monaco-diff-editor .margin-view-overlays .line-numbers"))!=null?t:[]);return!!n.length&&n.some(l=>{var o;if(!((o=l.textContent)!=null&&o.trim()))return!1;if(typeof window>"u"||typeof window.getComputedStyle!="function")return!0;const i=window.getComputedStyle(l);if(i.display==="none")return!1;const d=l.getBoundingClientRect();if(d.width<=0&&d.height<=0)return!0;const u=Number.parseFloat(i.width||""),a=Number.parseFloat(i.paddingLeft||""),c=Number.parseFloat(i.paddingRight||""),s=Math.max(d.width,Number.isFinite(u)?u:0)>=8,v=Number.isFinite(a)&&a>=1&&Number.isFinite(c)&&c>=1;return s&&v})}function _l(e){const t=Vn(e,".monaco-diff-editor .view-lines .view-line");if(!t)return!1;if(!Jn())return!0;const n=Vn(e,".monaco-diff-editor .margin-view-overlays .line-numbers");if(!n)return!1;if(typeof window>"u"||typeof window.getComputedStyle!="function")return!0;const l=t.getBoundingClientRect(),o=n.getBoundingClientRect();if(l.width<=0&&l.height<=0||o.width<=0&&o.height<=0)return!0;const i=l.left-o.right;return i>=0&&i<=32}function Ko(e,t){return!Ie.value||!(t||e?.querySelector([".line-insert",".line-delete",".gutter-insert",".gutter-delete",".stream-monaco-line-number-insert",".stream-monaco-line-number-delete",".stream-monaco-line-insert-fill",".stream-monaco-line-delete-fill",".stream-monaco-fallback-line-insert",".stream-monaco-fallback-line-delete",".stream-monaco-fallback-inline-delete-line"].join(",")))||!!(e?.classList.contains("stream-monaco-diff-inline-native-ready")&&!e.classList.contains("stream-monaco-diff-native-stale"))}function Il(e,t,n,l){const o=e?.querySelector(`.monaco-diff-editor .editor.${t}`);if(!o)return!1;const i=Array.from(o.querySelectorAll(`.margin-view-overlays .line-numbers.${n}`));if(!i.length)return!0;const d=Array.from(o.querySelectorAll(".lines-content > .view-lines:not(.line-delete) > .view-line"));return!!d.length&&i.every(u=>{const a=u.getBoundingClientRect();let c=null;for(const s of d){const v=s.getBoundingClientRect(),p=Math.abs(v.top-a.top);(!c||p<c.distance)&&(c={node:s,distance:p})}return!c||c.distance>1.25||c.node.classList.contains(l)})}function Zo(e,t){if(!e)return!1;const n=t.added<=0||Il(e,"modified","stream-monaco-line-number-insert","stream-monaco-line-insert-fill"),l=t.removed<=0||(Ie.value?!!e.classList.contains("stream-monaco-diff-inline-native-ready"):Il(e,"original","stream-monaco-line-number-delete","stream-monaco-line-delete-fill"));return n&&l}function Gn(e){if(xn.value)return!0;if(!e)return!1;const t=Array.from(e.querySelectorAll(".monaco-diff-editor .view-lines .view-line, .monaco-editor .view-lines .view-line")).filter(l=>{var o;if(!((o=l.textContent)!=null&&o.trim()))return!1;const i=l.getBoundingClientRect();return i.width>0||i.height>0});if(!t.length)return!1;const n=t.filter(l=>{var o,i;return i=(o=l.textContent)!=null?o:"",/['"`{}()[\]:;=<>.,]|\/\/|\/\*|\b(?:async|await|class|const|enum|export|for|function|if|import|interface|let|return|switch|type|var|while)\b/.test(i.replace(/\u00A0/g," ").trim())});return!n.length||n.filter(l=>Array.from(l.querySelectorAll("span")).filter(o=>{var i;return(i=o.textContent)==null?void 0:i.trim()}).some(o=>String(o.className||"").split(/\s+/).some(i=>/^mtk\d+$/.test(i)&&i!=="mtk1"))).length>0}function Jn(){const e=re.value;return e?.lineNumbers!=="off"}function Yn(){var e,t;m.value?Ze.value=dn(String((e=r.node.originalCode)!=null?e:""),String((t=r.node.updatedCode)!=null?t:"")):Ze.value={removed:0,added:0}}function lt(){var e;if(m.value)try{const t=U(),n=(e=t?.getLineChanges)==null?void 0:e.call(t);if(!Array.isArray(n))return void Yn();let l=0,o=0;for(const i of n)l+=Tl(i.originalStartLineNumber,i.originalEndLineNumber),o+=Tl(i.modifiedStartLineNumber,i.modifiedEndLineNumber);Ze.value={removed:l,added:o}}catch{Yn()}else Ze.value={removed:0,added:0}}function Qn(){var e;if(Number.isFinite(_.value)&&_.value>0&&Number.isFinite(pe.value))return _.value;const t=Un();return typeof((e=r.monacoOptions)==null?void 0:e.fontSize)=="number"?(pe.value=r.monacoOptions.fontSize,_.value=r.monacoOptions.fontSize,_.value):t&&t>0?(pe.value=t,_.value=t,t):(pe.value=12,_.value=12,12)}function ei(){const e=Qn(),t=Math.min(36,e+1);_.value=t}function ti(){const e=Qn(),t=Math.max(10,e-1);_.value=t}function ni(){Qn(),Number.isFinite(pe.value)&&(_.value=pe.value)}function Ul(){var e,t,n,l,o,i,d,u,a,c,s,v,p,y;try{const h=m.value?U():null,g=m.value?h:se();if(!g)return null;if(h?.getOriginalEditor&&h?.getModifiedEditor){const C=(e=h.getOriginalEditor)==null?void 0:e.call(h),S=(t=h.getModifiedEditor)==null?void 0:t.call(h);(n=C?.layout)==null||n.call(C),(l=S?.layout)==null||l.call(S);const F=((o=C?.getContentHeight)==null?void 0:o.call(C))||0,P=((i=S?.getContentHeight)==null?void 0:i.call(S))||0,T=Math.max(F,P);if(T>0)return Math.ceil(T);const R=((a=(u=(d=C?.getModel)==null?void 0:d.call(C))==null?void 0:u.getLineCount)==null?void 0:a.call(u))||1,A=((v=(s=(c=S?.getModel)==null?void 0:c.call(S))==null?void 0:s.getLineCount)==null?void 0:v.call(s))||1,H=Math.max(R,A),J=Math.max(St(C),St(S)),K=Math.max(sn(C),sn(S));return Math.ceil(H*J+K+0)}if(g?.getContentHeight){(p=g?.layout)==null||p.call(g);const C=g.getContentHeight();if(C>0)return m.value||(Zt.value=!0),Math.ceil(C)}const X=(y=g?.getModel)==null?void 0:y.call(g);let ce=1;X&&typeof X.getLineCount=="function"&&(ce=X.getLineCount());const L=St(g);return Math.ceil(ce*(L+1.5)+0)}catch{return null}}function Vl(){var e,t;if(m.value)return!1;try{const n=(t=(e=se())==null?void 0:e.getContentHeight)==null?void 0:t.call(e),l=typeof n=="number"&&Number.isFinite(n)&&n>0;return l&&(Zt.value=!0),l}catch{return!1}}function Xn(e){var t,n,l;if(typeof window>"u")return null;try{const o=e.getBoundingClientRect(),i=window.getComputedStyle(e);if(i.display==="none"||i.visibility==="hidden")return null;const d=e.querySelector("diffs-container");if(d instanceof HTMLElement){const c=d.getBoundingClientRect();if(c.height>0&&c.bottom>o.top)return Math.ceil(c.bottom-o.top)}const u=[".editor.original .view-lines .view-line",".editor.modified .view-lines .view-line",".editor.original .view-zones > div",".editor.modified .view-zones > div",".editor.original .margin-view-zones > div",".editor.modified .margin-view-zones > div",".editor.original .diff-hidden-lines",".editor.modified .diff-hidden-lines",".stream-monaco-diff-unchanged-bridge"];let a=0;for(const c of Array.from(e.querySelectorAll(u.join(",")))){if(!(c instanceof HTMLElement)||((t=c.parentElement)!=null&&t.classList.contains("view-zones")||(n=c.parentElement)!=null&&n.classList.contains("margin-view-zones"))&&!((l=c.textContent)!=null&&l.trim()||c.matches(".line-delete, .line-insert, .cdr")||c.querySelector(".diff-hidden-lines, .stream-monaco-diff-unchanged-bridge, .line-delete, .line-insert, .cdr")))continue;const s=window.getComputedStyle(c);if(s.display==="none"||s.visibility==="hidden"||Number.parseFloat(s.opacity||"1")<=.01)continue;const v=c.getBoundingClientRect();v.height<=0||v.bottom<=o.top||(a=Math.max(a,v.bottom-o.top))}return a>0?Math.ceil(a):null}catch{return null}}function Ht(e){if(typeof window>"u")return!1;const t=e.getBoundingClientRect();if(t.width<=0||t.height<=0)return!1;const n=e.querySelectorAll(".editor.modified .diff-hidden-lines, .editor.original .diff-hidden-lines, .stream-monaco-diff-unchanged-bridge");for(const l of Array.from(n)){if(!(l instanceof HTMLElement))continue;const o=window.getComputedStyle(l);if(o.display==="none"||o.visibility==="hidden"||Number.parseFloat(o.opacity||"1")<=.01)continue;const i=l.getBoundingClientRect();if(!(i.width<=0||i.height<=0||i.bottom<=t.top||i.top>=t.bottom))return!0}return!1}function Kn(e){var t;const n=String(e??"").trim(),l=(t=n.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i))==null?void 0:t[1];if(l){const a=l.length===3?l.split("").map(c=>`${c}${c}`).join(""):l;return .2126*Number.parseInt(a.slice(0,2),16)+.7152*Number.parseInt(a.slice(2,4),16)+.0722*Number.parseInt(a.slice(4,6),16)}const o=n.match(/\d+(?:\.\d+)?/g);if(!o||o.length<3)return null;const[i,d,u]=o.slice(0,3).map(Number);return .2126*i+.7152*d+.0722*u}function Nt(){var e,t,n;if(Gl())return;const l=Un();l&&l>0&&(jn.value=l,_.value=l,pe.value=l);try{const o=St(m.value?(n=(t=(e=U())==null?void 0:e.getModifiedEditor)==null?void 0:t.call(e))!=null?n:U():se());o&&o>0&&(tn.value=o)}catch{}try{const o=Nl();o&&o>0&&(tn.value=o)}catch{}}function Gl(){return m.value&&Cl.value}function Zn(){var e;if(!m.value||!Ne.value)return null;const t=f.value,n=(e=$.value)==null?void 0:e.querySelector("pre.code-pre-fallback");if(!t||!n)return null;const l=Math.ceil(n.getBoundingClientRect().height);return!Number.isFinite(l)||l<=0?null:(t.style.height=`${l}px`,t.style.minHeight=`${l}px`,t.style.maxHeight=`${Math.ceil(Ct())}px`,t.style.overflow="hidden",l)}function el(){var e,t,n,l,o,i,d,u;const a=f.value,c=$.value;if(!a||!c)return;const s=a,v=a.querySelector(".monaco-editor")||a,p=v.querySelector(".monaco-editor-background")||v,y=v.querySelector(".view-lines")||v;let h=null,g=null,X=null;try{typeof window<"u"&&typeof window.getComputedStyle=="function"&&(h=window.getComputedStyle(v),g=p===v?h:window.getComputedStyle(p),X=y===v?h:window.getComputedStyle(y))}catch{h=null,g=null,X=null}const ce=String((e=h?.getPropertyValue("--vscode-editor-foreground"))!=null?e:"").trim(),L=String((t=h?.getPropertyValue("--vscode-editor-background"))!=null?t:"").trim(),C=String((l=(n=h?.getPropertyValue("--vscode-editor-selectionBackground"))!=null?n:h?.getPropertyValue("--vscode-editor-hoverHighlightBackground"))!=null?l:"").trim(),S=ce||String((i=(o=X?.color)!=null?o:h?.color)!=null?i:"").trim(),F=L||String((u=(d=g?.backgroundColor)!=null?d:h?.backgroundColor)!=null?u:"").trim(),P=(function(){var T,R,A,H,J;try{const K=m.value?(A=(R=(T=U())==null?void 0:T.getModifiedEditor)==null?void 0:R.call(T))!=null?A:U():se(),st=kt(),Dt=(H=st?.EditorOption)==null?void 0:H.fontInfo;if(K&&Dt!=null){const At=(J=K.getOption)==null?void 0:J.call(K,Dt),Ve=At?.typicalHalfwidthCharacterWidth;if(typeof Ve=="number"&&Number.isFinite(Ve)&&Ve>0)return Ve}}catch{}return null})();if(P!=null&&(nn.value=P),m.value){const T=(R,A)=>{A?(c.style.setProperty(R,A),s.style.setProperty(R,A)):(c.style.removeProperty(R),s.style.removeProperty(R))};for(const[R,A]of Object.entries(Fl(c.classList.contains("is-dark"))))T(R,A);return S?(c.style.setProperty("--markstream-diff-editor-fg",S),s.style.setProperty("--vscode-editor-foreground",S),s.style.setProperty("--stream-monaco-editor-fg",S)):(c.style.removeProperty("--markstream-diff-editor-fg"),s.style.removeProperty("--vscode-editor-foreground"),s.style.removeProperty("--stream-monaco-editor-fg")),F?(c.style.setProperty("--markstream-diff-editor-bg",F),c.style.setProperty("--markstream-diff-panel-bg",F),c.style.setProperty("--markstream-diff-panel-bg-soft",F),c.style.setProperty("--markstream-diff-panel-bg-strong",F),s.style.setProperty("--vscode-editor-background",F),s.style.setProperty("--stream-monaco-editor-bg",F),s.style.setProperty("--stream-monaco-fixed-editor-bg",F),s.style.setProperty("--stream-monaco-panel-bg",F),s.style.setProperty("--stream-monaco-panel-bg-soft",F),s.style.setProperty("--stream-monaco-panel-bg-strong",F),s.style.backgroundColor=F):(c.style.removeProperty("--markstream-diff-editor-bg"),c.style.removeProperty("--markstream-diff-panel-bg"),c.style.removeProperty("--markstream-diff-panel-bg-soft"),c.style.removeProperty("--markstream-diff-panel-bg-strong"),s.style.removeProperty("--vscode-editor-background"),s.style.removeProperty("--stream-monaco-editor-bg"),s.style.removeProperty("--stream-monaco-fixed-editor-bg"),s.style.removeProperty("--stream-monaco-panel-bg"),s.style.removeProperty("--stream-monaco-panel-bg-soft"),s.style.removeProperty("--stream-monaco-panel-bg-strong"),s.style.backgroundColor=""),void(C?s.style.setProperty("--vscode-editor-selectionBackground",C):s.style.removeProperty("--vscode-editor-selectionBackground"))}if((function(T,R,A){if(!xn.value)return!1;const H=Kn(T),J=Kn(R);return A?H!=null&&H>170||J!=null&&J<110:H!=null&&H<85||J!=null&&J>190})(F,S,c.classList.contains("is-dark")))return s.style.removeProperty("--vscode-editor-foreground"),s.style.removeProperty("--vscode-editor-background"),void s.style.removeProperty("--vscode-editor-selectionBackground");S&&s.style.setProperty("--vscode-editor-foreground",S),F&&s.style.setProperty("--vscode-editor-background",F),C&&s.style.setProperty("--vscode-editor-selectionBackground",C)}let tl=0,nl=0;const Jl=/auto|scroll|overlay/i;function Le(e,t,n){var l;if(typeof window>"u"||m.value||(function(s){return Wo.value||Sl(s)})(e))return;const o=Math.ceil(t),i=Math.ceil(n)-o;if(Math.abs(i)<=1)return;const d=(function(s){var v,p;if(typeof window>"u")return null;const y=(v=s?.ownerDocument)!=null?v:document,h=y.scrollingElement||y.documentElement||y.body;let g=(p=s?.parentElement)!=null?p:null;for(;g&&g!==y.body&&g!==h;){const X=window.getComputedStyle(g),ce=(X.overflowY||"").toLowerCase(),L=(X.overflow||"").toLowerCase();if(Jl.test(ce)||Jl.test(L))return g;g=g.parentElement}return h})(e);if(!d)return;const u=(l=e.ownerDocument)!=null?l:document,a=d===u.body||d===u.documentElement||d===u.scrollingElement,c=a?0:d.getBoundingClientRect().top;e.getBoundingClientRect().top-c>=0||(a&&typeof window.scrollBy=="function"?window.scrollBy(0,i):d.scrollTop+=i)}function ll(){try{const e=f.value;if(!e)return;const t=e.getBoundingClientRect().height,n=Ul();if(n!=null&&n>0){const o=Hl(n,!0,{allowBelowEstimatedFloor:!m.value&&W.value&&Vl()}),i=nt();return e.style.minHeight=i!=null?`${i}px`:"0px",e.style.height=`${o}px`,e.style.maxHeight="none",e.style.overflow="visible",void Le(e,t,o)}const l=nt();l!=null&&(e.style.minHeight=`${l}px`,e.style.height=`${l}px`,e.style.maxHeight="none",e.style.overflow="visible",Le(e,t,l))}catch{}}function ot(){for(var e,t;ze.length>0;)try{(t=(e=ze.pop())==null?void 0:e.dispose)==null||t.call(e)}catch{}bt!=null&&(yn(bt),bt=null),Bt!=null&&(yn(Bt),Bt=null),Je!=null&&(yn(Je),Je=null),Ye=0,Qe=!1}function Re(){for(var e;$n.length>0;)try{(e=$n.pop())==null||e()}catch{}}function le(e=!1){xe.value||(Fe.value?ll():(function(t={}){var n,l,o;try{const i=f.value;if(!i)return;const d=i.getBoundingClientRect().height,u=Ct(),a=Math.ceil(((n=i.getBoundingClientRect)==null?void 0:n.call(i).height)||0),c=Number.parseFloat(i.style.height||""),s=a>0?a:Number.isFinite(c)&&c>0?Math.ceil(c):0,v=m.value?(function(){var H,J,K,st,Dt,At,Ve,wo,bo,ko,xo,So;if(Oe())return null;try{const dt=U(),ct=(H=dt?.getOriginalEditor)==null?void 0:H.call(dt),ft=(J=dt?.getModifiedEditor)==null?void 0:J.call(dt);if(!ct||!ft)return null;const hi=((Dt=(st=(K=ct.getModel)==null?void 0:K.call(ct))==null?void 0:st.getLineCount)==null?void 0:Dt.call(st))||1,gi=((wo=(Ve=(At=ft.getModel)==null?void 0:At.call(ft))==null?void 0:Ve.getLineCount)==null?void 0:wo.call(Ve))||1,yi=Math.max(hi,gi),wi=Math.max(St(ct),St(ft)),bi=Math.max(sn(ct),sn(ft)),ki=Math.max((ko=(bo=ct.getContentHeight)==null?void 0:bo.call(ct))!=null?ko:0,(So=(xo=ft.getContentHeight)==null?void 0:xo.call(ft))!=null?So:0);return Math.ceil(Math.max(ki,yi*wi+bi+0))}catch{return null}})():null,p=m.value&&Ht(i),y=m.value&&cn(i),h=m.value&&i.classList.contains("stream-monaco-diff-native-stale"),g=p&&W.value&&D.value&&!Ne.value;if(p||(ve.value=null),Cn>0&&(Cn--,We.value!=null))return void Le(i,d,De(i,We.value,u,{allowBelowEstimatedFloor:g,preserveScrollableOverflow:ol(i)}));if(m.value&&!y&&!p&&Ne.value){const H=Zn();if(H!=null){const J=De(i,H,u,{allowBelowEstimatedFloor:!0});return ee(!0),void Le(i,d,J)}}const X=m.value&&t.preferModelDiffHeight===!0,ce=m.value?Xn(i):null,L=ce,C=!m.value&&W.value&&Vl(),S=m.value&&r.loading!==!1&&(L!=null||v!=null&&a>0&&v<a-1),F=v!=null&&!g;let P;if(m.value)if(X){const H=v!=null&&r.loading===!1&&s>0&&v<s-1;P=r.loading===!1&&L!=null?p||v==null?L:Math.max(L,v):H?v:L!=null&&v!=null?Math.max(L,v,r.loading!==!1?s:0):Math.max(L??0,v??0,r.loading!==!1?s:0)||null}else P=p?ce:Ie.value&&L!=null||L!=null?F?Math.max(L,v):L:m.value&&r.loading!==!1?v!=null&&s>0&&v<s-1?v:s>0?s:null:v;else P=Ul();if(m.value&&r.loading===!1&&h&&!g&&P!=null&&v!=null&&(P=Math.min(P,v)),m.value&&P!=null&&s>0&&(r.loading!==!1||r.loading===!1&&h&&!g||t.holdCurrentDiffHeight===!0&&!g)&&(P=Math.max(P,s)),P!=null&&P>0){const H=p&&ve.value!=null,J=p&&a>0&&a<u-1&&P>=u-1,K=De(i,H?Math.max(ve.value,P):J?a:P,u,{clearEstimatedFloor:!0,allowBelowEstimatedFloor:g||C||S,preserveScrollableOverflow:ol(i)});return p&&K<u-1&&(ve.value=Math.max((l=ve.value)!=null?l:0,K)),il(i),void Le(i,d,K)}if(We.value!=null)return void Le(i,d,De(i,We.value,u,{allowBelowEstimatedFloor:g,preserveScrollableOverflow:ol(i)}));const T=m.value&&r.loading!==!1||p?a:Math.max(a,v!=null&&v>0?v:0);if(T>0){const H=p&&ve.value!=null,J=p&&a>0&&a<u-1&&T>=u-1,K=De(i,H?Math.max(ve.value,T):J?a:T,u,{allowBelowEstimatedFloor:g});return p&&K<u-1&&(ve.value=Math.max((o=ve.value)!=null?o:0,K)),il(i),void Le(i,d,K)}const R=nt();if(!(R==null||m.value&&r.loading!==!1&&y))return void Le(i,d,De(i,R,u,{allowBelowEstimatedFloor:g}));const A=Number.parseFloat(i.style.height);!Number.isNaN(A)&&A>0?Le(i,d,De(i,A,u,{allowBelowEstimatedFloor:g})):m.value||Le(i,d,De(i,u,u))}catch{}})(typeof e=="object"?e:{}))}function Yl(){tl=0,nl=0}function ee(e=!1){var t,n,l;if(xe.value)return;const o=f.value;if(!o)return;const i=m.value?U():se();if(i&&typeof i.layout=="function")try{const d=(t=o.getBoundingClientRect)==null?void 0:t.call(o),u=Math.ceil(((n=d?.width)!=null?n:0)||o.clientWidth||0),a=Math.ceil(((l=d?.height)!=null?l:0)||o.clientHeight||Number.parseFloat(o.style.height||"")||0);if(u>0&&a>0){if(!e&&u===tl&&a===nl)return;tl=u,nl=a,i.layout({width:u,height:a})}else Yl(),i.layout()}catch{}}function he(){if(!m.value)return void Re();const e=f.value;if(!e)return void Re();const t=e.querySelector(".monaco-diff-editor");if(!t||t.classList.contains("side-by-side"))return void Re();const n=Array.from(t.querySelectorAll(".editor.original .diff-hidden-lines")),l=Array.from(t.querySelectorAll(".editor.modified .diff-hidden-lines")),o=Math.min(n.length,l.length);for(let i=0;i<o;i++){const d=l[i],u=d.querySelector("a"),a=d.querySelector(".center > div:first-child"),c=d.querySelector(".center");if(!u||!a||!c||c.querySelector(".markstream-inline-fold-proxy"))continue;const s=document.createElement("button");s.type="button",s.className="markstream-inline-fold-proxy",s.dataset.markstreamInlineFoldProxy="true";const v=u.getAttribute("title")||"Show Unchanged Region";s.title=v,s.setAttribute("aria-label",v);const p=g=>{g.preventDefault(),g.stopPropagation()},y=g=>{g.preventDefault(),g.stopPropagation(),u.click(),fe(()=>de())},h=g=>{g.key!=="Enter"&&g.key!==" "||(g.preventDefault(),g.stopPropagation(),u.click(),fe(()=>de()))};s.addEventListener("mousedown",p),s.addEventListener("click",y),s.addEventListener("keydown",h),c.appendChild(s),$n.push(()=>{s.removeEventListener("mousedown",p),s.removeEventListener("click",y),s.removeEventListener("keydown",h),s.parentElement===c&&c.removeChild(s)})}}function de(e=!1){if(B||bt!=null)return;const t=()=>{B||(he(),le(e),ee())};bt=fe(()=>{bt=null,t(),Bt=fe(()=>{Bt=null,t()})}),it()}function it(e=!1){if(!m.value||B||!e&&r.loading===!1||(Qe=Qe||e,Ye=Math.max(Ye,e?18:6),Je!=null))return;const t=()=>{if(Je=null,!m.value||B||Ye<=0||!Qe&&r.loading===!1)return Ye=0,void(Qe=!1);Ye--,he(),le({preferModelDiffHeight:!0,holdCurrentDiffHeight:Qe}),ee(),Ye>0?Je=fe(t):Qe=!1};Je=fe(t)}function De(e,t,n,l={}){const o=m.value&&r.loading!==!1?Xn(e):null,i=o!=null&&o>t+1?o:t,d=Math.min(i,n),u=l.allowBelowEstimatedFloor===!0||zl(),a=Hl(d,l.clearEstimatedFloor===!0,{allowBelowEstimatedFloor:u}),c=nt();if(e.style.minHeight=c==null||u?"0px":`${Math.min(c,Math.ceil(n))}px`,e.style.height=`${a}px`,e.style.maxHeight=`${Math.ceil(n)}px`,m.value)e.style.overflow="hidden";else{const s=l.preserveScrollableOverflow===!0||t>n+1;e.style.overflow=s?"auto":"hidden"}return a}function Ql(e,t=0){var n;const l=Math.ceil(((n=e.getBoundingClientRect)==null?void 0:n.call(e).height)||0),o=Math.max(t,e.clientHeight||0,l);return o>0&&e.scrollHeight>o+1}function ol(e){var t;return!m.value&&(Mn||Ql(e,(t=We.value)!=null?t:0))}function il(e){var t,n,l,o,i,d,u,a;if(!m.value)return;const c=Fe.value||!Ht(e)||e.getBoundingClientRect().height>=Ct()-1;if(Sn===c)return;Sn=c;const s=Ce(I({},(n=(t=r.monacoOptions)==null?void 0:t.scrollbar)!=null?n:{}),{handleMouseWheel:c}),v=U();try{(i=(o=(l=v?.getOriginalEditor)==null?void 0:l.call(v))==null?void 0:o.updateOptions)==null||i.call(o,{scrollbar:s}),(a=(u=(d=v?.getModifiedEditor)==null?void 0:d.call(v))==null?void 0:u.updateOptions)==null||a.call(u,{scrollbar:s})}catch{}}function cn(e=f.value){return!!Oe(e)||!!e?.querySelector(".monaco-diff-editor .view-lines .view-line")}function Xl(e=f.value){return!!Oe(e)||!!e?.querySelector(".monaco-editor .view-lines .view-line")}function Kl(){var e,t;if(Oe())return!0;const n=(t=(e=se())==null?void 0:e.getModel)==null?void 0:t.call(e);return typeof n?.getValue=="function"&&n.getValue()===Te.value}function Zl(e=f.value){return!!Oe(e)||!!e?.classList.contains("stream-monaco-diff-root")&&!(Ie.value&&!e.classList.contains("stream-monaco-diff-inline"))}function Oe(e=f.value){return!!e?.querySelector("diffs-container")}function eo(e){return r.loading!==!1||D.value||e.classList.contains("stream-monaco-diff-native-stale")||Ht(e)}function li(){const e=U();return typeof e?.getOriginalEditor=="function"||typeof e?.getModifiedEditor=="function"||typeof e?.getLineChanges=="function"}function to(){return q(this,arguments,function*(e={}){var t,n,l;if(!m.value)return!0;if(Oe())return yield j(),yield Pe(),Oe();const o=e.requireHighlight!==!1;let i=0,d=Pt(String((t=r.node.originalCode)!=null?t:""),String((n=r.node.updatedCode)!=null?n:"")),u=dn(d.original,d.updated),a=u.added>0||u.removed>0;const c=()=>{var s,v;const p=Pt(String((s=r.node.originalCode)!=null?s:""),String((v=r.node.updatedCode)!=null?v:""));p.original===d.original&&p.updated===d.updated||(d=p,u=dn(d.original,d.updated),a=u.added>0||u.removed>0)};for(let s=0;s<30;s++){if(B)return!1;c();const v=f.value,p=U(),y=Jn();let h=!1;try{const S=(l=p?.getLineChanges)==null?void 0:l.call(p);h=Array.isArray(S)&&(!a||S.length>0)}catch{h=!1}const g=!!v?.querySelector(".monaco-diff-editor"),X=cn(v),ce=!a||Al(v,u),L=!a||ql(v,u),C=!y||Wl(v);if(g&&X&&h&&ce&&L&&C&&Dl(v)){try{xt(),he(),lt(),de()}catch{}if(yield j(),yield Pe(),B)return!1;const S=f.value,F=!Jn()||Wl(S),P=!a||Al(S,u),T=!a||ql(S,u),R=Ko(S,a),A=Zo(S,u),H=!o||Gn(S),J=Zl(S)&&F&&_l(S)&&P&&T&&R&&A&&H,K=Zl(S)&&F&&_l(S)&&P&&T&&Dl(S)&&H;if(J||K){if(i++,i>=2)return!0}else i=0}yield j(),yield Pe()}return B||(xt(),he(),lt(),de(),c()),!1})}function no(e,t,n){return q(this,null,function*(){try{return void(yield Qt(e,t,n))}catch(l){if(!Lt(l))throw l}if(yield j(),yield Pe(),!B&&m.value)try{yield Qt(e,t,n)}catch(l){if(!Lt(l))throw l}})}function Ct(){var e,t;const n=(t=(e=r.monacoOptions)==null?void 0:e.MAX_HEIGHT)!=null?t:500;if(typeof n=="number")return n;const l=String(n).match(/^(\d+(?:\.\d+)?)/);return l?Number.parseFloat(l[1]):500}const rl=k(()=>r.isShowPreview&&(ke.value==="html"||ke.value==="svg"));function Ue(){return typeof r.node.loading=="boolean"?r.node.loading:r.loading===!0}function lo(){var e,t,n;if(!Ue())return!0;const l=String((e=r.node.raw)!=null?e:""),o=(n=(t=l.split(/\r\n|\n|\r/,1)[0])==null?void 0:t.trimStart())!=null?n:"";return!/^(?:`{3,}|~{3,})/.test(o)||/\r\n|\n|\r/.test(l)}function oo(e,t,n){return!n||lo()&&String(t??"")?hn(String(e??"")):"plain"}function fn(){return Ue()}let Mt=null,al=!1,vn=0;function io(){Mt=null,vn++}function ro(){return q(this,arguments,function*(e=vn){if(!al){al=!0;try{for(;Mt&&!B&&!m.value&&e===vn;){const t=Mt;Mt=null;try{yield Promise.resolve(En(t.code,t.language)),yield j(),B||m.value||(le(!1),ee())}catch{}}}finally{al=!1,!Mt||B||m.value||ro()}}})}function ao(e,t){Mt={code:e,language:t},ro(vn)}ae(()=>[r.node.language,r.node.code,r.node.raw,r.node.loading,r.loading],([e,t,n,l,o])=>{ke.value=oo(e,t,typeof l=="boolean"?l:o===!0)}),ae(()=>[r.node.originalCode,r.node.updatedCode,m.value],()=>{ve.value=null,Yn(),fe(()=>lt())},{immediate:!0});let mn=0;ae(()=>[r.node.originalCode,r.node.updatedCode,Ee.value,m.value,r.stream],e=>q(null,[e],function*([,,,t,n]){var l,o;const i=++mn;if(!t||Ue()||n===!1&&!Q.value)return;if(n!==!1&&ue&&!Q.value&&f.value)try{yield Ae(f.value)}catch{}const d=Et;if(d&&!Se.value){try{yield d}catch{}if(B||!m.value||i!==mn)return}if(i!==mn)return;const u=Pt(String((l=r.node.originalCode)!=null?l:""),String((o=r.node.updatedCode)!=null?o:"")),a=r.loading===!1;a&&at();try{if(yield no(u.original,u.updated,Ee.value),B||!m.value||i!==mn)return;yield j(),ee(!0),he(),le(r.loading===!1||{preferModelDiffHeight:!0}),ee(!0),de(!0)}catch{return}if(a){if(B||!m.value)return;xt(),he(),lt(),de(),it(!0)}Fe.value&&fe(()=>ll())})),ae(()=>r.node.code,e=>q(null,null,function*(){if(Ue()||r.stream===!1||(ke.value||(ke.value=hn(gl(e))),m.value))return;const t=Et;if(t&&!Se.value){try{yield t}catch{}if(B||m.value)return}if(ue&&!Q.value&&f.value)try{yield Ae(f.value)}catch{}ao(Kt(r.node.code),Ee.value),Fe.value&&fe(()=>ll())}));const oi=k(()=>{const e=ke.value;return e?Eo[e]||e.charAt(0).toUpperCase()+e.slice(1):Eo[""]}),uo=k(()=>{var e;return Ai(String((e=r.node.raw)!=null?e:""),oi.value,m.value)}),ii=k(()=>uo.value.title),so=k(()=>uo.value.caption),ri=k(()=>(Hi.value,(function(e,t){if(t===void 0)return Ni(e);if(t){const l=t(e);if(l!=null&&l!=="")return l}const n=hn(e);return Ti(n)||Ri()})(ke.value||"",ht))),ai=k(()=>{const e={};e["--markstream-code-layout-character-width"]=nn.value==null?"1ch":`${nn.value}px`;const t=o=>{if(o!=null)return typeof o=="number"?`${o}px`:String(o)},n=t(r.minWidth),l=t(r.maxWidth);if(n&&(e.minWidth=n),l&&(e.maxWidth=l),Ll.value&&!m.value&&!xe.value){const o=Qo.value;o!=null&&(e.minHeight=`${o}px`)}return m.value||(e.color="var(--vscode-editor-foreground, var(--markstream-code-fallback-fg))",e.backgroundColor="var(--vscode-editor-background, var(--markstream-code-fallback-bg))",e.borderColor="var(--markstream-code-border-color)"),e}),ui=k(()=>r.showTooltips!==!1);function si(){return q(this,null,function*(){try{typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(r.node.code)),yt.value=!0,E("copy",r.node.code),setTimeout(()=>{yt.value=!1},1e3)}catch(e){console.error("复制失败:",e)}})}function di(){Fe.value=!Fe.value;const e=m.value?U():se(),t=f.value;e&&t&&(Fe.value?(pn(!0),t.style.maxHeight="none",t.style.overflow="visible",le(!0)):(pn(!1),t.style.overflow=m.value?"hidden":"auto",le(!0)),il(t))}function ci(){var e,t;if(xe.value=!xe.value,xe.value){if(Mn=!1,f.value){const n=Math.ceil(((t=(e=f.value).getBoundingClientRect)==null?void 0:t.call(e).height)||0);Mn=!m.value&&(Ql(f.value,n)||f.value.style.overflow==="auto"||f.value.style.overflowY==="auto"),n>0&&(We.value=n)}pn(!1)}else Fe.value&&pn(!0),f.value&&We.value!=null&&(f.value.style.height=`${We.value}px`),Cn=2,j(()=>{xe.value||B||(le(!0),ee(!0))})}function fi(){if(!rl.value)return;const e=ke.value;if(Gt.value){const t=e==="html"?"text/html":"image/svg+xml",n=e==="html"?Y("artifacts.htmlPreviewTitle")||"HTML Preview":Y("artifacts.svgPreviewTitle")||"SVG Preview";return void E("previewCode",{node:r.node,artifactType:t,artifactTitle:n,id:`temp-${e}-${Date.now()}`})}e==="html"&&(en.value=!en.value)}function pn(e){var t,n;try{if(m.value){const l=U();(t=l?.updateOptions)==null||t.call(l,{automaticLayout:e})}else{const l=se();(n=l?.updateOptions)==null||n.call(l,{automaticLayout:e})}}catch{}}function vi(e){return q(this,null,function*(){var t;if(!ue||B)return;const n=Ot.value;if(Rn=!1,me.value=!1,et.value=null,Se.value=!1,D.value=!1,$t.value=!1,Sn=null,jn.value=null,tn.value=null,nn.value=null,(function(){const a=(function(){var c;const s=(c=f.value)==null?void 0:c.parentElement;return s instanceof HTMLElement?s:null})();a&&(a.style.removeProperty("--stream-monaco-line-number-left"),a.style.removeProperty("--stream-monaco-line-number-width"),a.style.removeProperty("--stream-monaco-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-original-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-modified-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-original-scrollable-left"),a.style.removeProperty("--stream-monaco-modified-scrollable-left"))})(),Yl(),(function(){Zt.value=!1;const a=El.value;_n.value=W.value||a==null?null:a})(),ot(),Re(),(function(a){a.replaceChildren()})(e),at(),B)return;const l=q(null,null,function*(){var a,c;if(n==="diff"){(function(){if(On||typeof window>"u")return;On=!0;const v=p=>{var y;Lt("reason"in p?p.reason:(y=p.error)!=null?y:p.message)&&(p.preventDefault(),p.stopImmediatePropagation())};window.addEventListener("error",v,!0),window.addEventListener("unhandledrejection",v,!0),Xt=()=>{window.removeEventListener("error",v,!0),window.removeEventListener("unhandledrejection",v,!0),On=!1,Xt=null}})(),Xe();const s=Pt(String((a=r.node.originalCode)!=null?a:""),String((c=r.node.updatedCode)!=null?c:""));Yt?yield gt(()=>Yt(e,s.original,s.updated,Ee.value)):yield gt(()=>ue(e,r.node.code,Ee.value))}else yield gt(()=>ue(e,Te.value,Ee.value));Se.value=!0}),o=l.finally(()=>{Et===o&&(Et=null)});if(Et=o,yield(function(a){return q(this,null,function*(){if(!m.value)return void(yield a);let c,s=!1;for(a.then(()=>{s=!0},v=>{s=!0,c=v});;){if(B)return;if(s){if(c)throw c;return}if(cn()&&li())return;yield j(),yield Pe()}})})(o),B||Ot.value!==n)return;Se.value=!0;const i=n==="diff"?U():se();if(typeof((t=r.monacoOptions)==null?void 0:t.fontSize)=="number")i?.updateOptions({fontSize:r.monacoOptions.fontSize,automaticLayout:!1}),pe.value=r.monacoOptions.fontSize,_.value=r.monacoOptions.fontSize;else if(!Gl()){const a=Un();a&&a>0?(pe.value=a,_.value=a):(pe.value=12,_.value=12)}Nt(),yield mo(),Fe.value||xe.value||le(!1),W.value=!0,kl.value=n,(function(){var a,c,s,v,p;if(ot(),m.value){const h=U(),g=(a=h?.getOriginalEditor)==null?void 0:a.call(h),X=(c=h?.getModifiedEditor)==null?void 0:c.call(h),ce=(C,S)=>{try{const F=C?.[S];if(typeof F!="function")return;const P=F.call(C,()=>de());P&&ze.push(P)}catch{}};try{const C=(s=h?.onDidUpdateDiff)==null?void 0:s.call(h,()=>{de(),fe(()=>lt())});C&&ze.push(C)}catch{}ce(g,"onDidContentSizeChange"),ce(X,"onDidContentSizeChange");const L=f.value;if(L&&typeof MutationObserver<"u"){const C=[".view-line",".view-lines",".view-zones",".margin-view-zones",".diff-hidden-lines",".stream-monaco-diff-unchanged-bridge",".stream-monaco-fallback-inline-delete-zone",".stream-monaco-fallback-inline-delete-margin"].join(","),S=T=>{var R;const A=T instanceof HTMLElement?T:T.parentElement;return!!((R=A?.closest)!=null&&R.call(A,C))},F=T=>{var R,A;const H=T instanceof HTMLElement?T:T.parentElement;return!!((R=H?.closest)!=null&&R.call(H,C)||(A=H?.querySelector)!=null&&A.call(H,C))},P=new MutationObserver(T=>{m.value&&eo(L)&&T.some(R=>S(R.target)||Array.from(R.addedNodes).some(F)||Array.from(R.removedNodes).some(S))&&(he(),le({preferModelDiffHeight:!0}),ee(),it())});P.observe(L,{attributeFilter:["class"],attributes:!0,childList:!0,characterData:!0,subtree:!0}),ze.push({dispose:()=>P.disconnect()})}if(L){const C=S=>{const F=S.target instanceof Element?S.target:null;if(!F?.closest([".stream-monaco-unchanged-summary",".stream-monaco-unchanged-reveal",".stream-monaco-unchanged-expand",".markstream-inline-fold-proxy",".diff-hidden-lines .center"].join(",")))return;const P=Math.ceil(L.getBoundingClientRect().height||0);P>0&&(ve.value=P)};L.addEventListener("click",C,!0),ze.push({dispose:()=>L.removeEventListener("click",C,!0)})}if(L&&typeof ResizeObserver<"u"){const C=new ResizeObserver(()=>{if(!m.value||(ee(),!eo(L)))return;const S=Xn(L);if(S==null)return;const F=Math.ceil(L.getBoundingClientRect().height||0),P=ve.value;if(Ht(L)&&P!=null){if(F>P+1)ve.value=F;else if(F<P-1)return De(L,P,Ct()),void ee()}F<=S+1||(he(),le({preferModelDiffHeight:!0}),ee())});C.observe(L),ze.push({dispose:()=>C.disconnect()})}return}const y=se();try{const h=(v=y?.onDidContentSizeChange)==null?void 0:v.call(y,()=>de());h&&ze.push(h)}catch{}try{const h=(p=y?.onDidLayoutChange)==null?void 0:p.call(y,()=>de());h&&ze.push(h)}catch{}})(),el(),Nt(),he(),lt(),de(),yield j();let d=null;Ke&&(d=yield Ke(),d&&(yield j(),yield Pe()));const u=d??(n==="diff"?yield to({requireHighlight:!0}):yield(function(){return q(this,null,function*(){if(Oe())return yield j(),yield Pe(),Oe();for(let a=0;a<30;a++){if(B||m.value)return!1;const c=f.value,s=Kl(),v=Xl(c),p=!Te.value.trim()||Gn(c);if(s&&v&&p&&(yield j(),yield Pe(),!B&&!m.value&&Kl()&&Xl(f.value)&&(!Te.value.trim()||Gn(f.value))))return!0;yield j(),yield Pe()}return!1})})());B||(u?(Nt(),un(),(yield $l())||je()):je())})}function Ae(e,t={}){if(!ue||B||r.stream===!1&&r.loading!==!1||(sl(),yo())||ge.value||f.value!==e||fn())return null;if($e)return $e;if(Q.value&&W.value)return Promise.resolve();const n=ul(),l=Nn.value;let o=!1;Q.value=!0,(function(){const d=Ge.value;ie&&d&&qe!==d&&(qe&&ie.markSettled(qe),qe=d,ie.markPending(d))})();const i=q(null,null,function*(){try{yield vi(e),zt=null}catch(d){const u=ul(),a=l!==Nn.value,c=t.allowStaleContentRetry!==!1&&a&&zt!==u;if(n!==u||c)return c&&(zt=u),o=!0,Q.value=!1,W.value=!1,Se.value=!1,void(D.value=!1);throw je(n),d}}).finally(()=>{$e===i&&($e=null),(function(){const d=qe;ie&&d&&(qe="",j(()=>{var u,a;if(!B){const c=(a=(u=$.value)==null?void 0:u.offsetHeight)!=null?a:0;c>0&&ie.reportHeight(d,c)}ie.markSettled(d)}))})(),o&&!B&&queueMicrotask(()=>{var d;const u=f.value;u&&!B&&((d=Ae(u))==null||d.catch(a=>{W.value=!1,D.value=!1,je()}))})});return $e=i,i}ae(ui,e=>{e||vt()}),ae(()=>_.value,(e,t)=>{const n=m.value?U():se();n&&typeof e=="number"&&Number.isFinite(e)&&e>0&&(n.updateOptions({fontSize:e}),xe.value||le(!0))},{flush:"post",immediate:!1});let co=0;const mi=ae(()=>[f.value,m.value,r.stream,r.loading,wt.value,Z.value,r.node.language,r.node.raw,r.node.code,r.node.loading],e=>q(null,[e],function*([t,n,l,o,i,d]){const u=++co;if(!t||!d||Ue()||tt||l===!1&&o!==!1||!ue&&(yield(function(){return q(this,null,function*(){if(typeof window>"u"||B||wt.value||ge.value)return;if(Ft)return Ft;const c=q(null,null,function*(){try{const s=yield Ui();if(B)return;if(!s)return void(ge.value=!0);const v=s.useMonaco,p=s.detectLanguage;if(typeof p=="function"&&(gl=p),typeof v!="function")return;He=po();const y=v(He);ue=y.createEditor||ue,Yt=y.createDiffEditor||Yt,En=y.updateCode||En,Qt=y.updateDiff||Qt,kt=y.getEditor||kt,se=y.getEditorView||se,U=y.getDiffEditorView||U,Fn=y.cleanupEditor||Fn,Xe=y.safeClean||y.cleanupEditor||Xe,Pn=y.refreshDiffPresentation||Pn,Ln=y.setTheme||Ln,Ke=y.whenVisualReady||null,wt.value=!0}catch{if(B)return;ge.value=!0}}).finally(()=>{Ft===c&&(Ft=null)});return Ft=c,c})})(),u!==co||r.stream===!1&&r.loading!==!1||fn()||!Z.value||!ue||ge.value||Q.value||yo()||B||f.value!==t)||fn())return;const a=Ae(t);if(a){try{yield a}catch{W.value=!1,D.value=!1,je()}W.value&&D.value&&mi()}}));function fo(e){return!!e&&typeof e=="object"&&"light"in e&&"dark"in e}function rt(e){return typeof e=="string"?e:e&&typeof e=="object"&&"name"in e?String(e.name):null}function vo(e,t){if(e===t)return!0;const n=rt(e),l=rt(t);return!!n&&n===l}function Tt(){var e;const t=(function(){if(r.theme!==void 0){const a=r.theme;return fo(a)?r.isDark?a.dark:a.light:a}return r.isDark?r.darkTheme:r.lightTheme})(),n=(e=re.value)==null?void 0:e.theme,l=t??n;if(l!=null&&typeof l=="object")return l;const o=Array.isArray(r.themes)?r.themes:[];if(!o.length||l==null)return l;const i=rt(l),d=o.map(a=>rt(a)).filter(a=>!!a);if(!i||d.includes(i))return l;const u=rt(n);return n!=null&&u&&d.includes(u)?n:o[0]}function mo(){return q(this,arguments,function*(e={}){at();const t=()=>{m.value&&xt(),fe(()=>{el(),de()})};if(e.appearanceOnly)return void t();const n=Tt();if(n)try{yield Ln(n),t()}catch{}else t()})}function Rt(e,t){if(typeof t!="string")return;const n=hn(t),l=Bo(n),o=["plain","objectivec","objectivecpp"].includes(n)?l:n;for(const i of[o,l])i&&!e.includes(i)&&e.push(i)}ae(Ot,(e,t)=>q(null,null,function*(){if(e===t||me.value||tt||(io(),!ue||!f.value)||!Q.value||r.stream===!1&&r.loading!==!1||!Z.value)return;const n=$e;if(n){try{yield n}catch{}if(B||!f.value)return}if(kl.value!==e||!Q.value||!W.value)try{W.value=!1,D.value=!1,Q.value=!1,Se.value=!1,ot(),Re(),Xe(),yield j(),yield Ae(f.value)}catch{W.value=!1,D.value=!1,je()}}));const pi=k(()=>{var e;const t=[],n=(e=re.value)==null?void 0:e.languages;if(Array.isArray(n))for(const l of n)Rt(t,l);return lo()&&Rt(t,r.node.language),Rt(t,ke.value),Rt(t,Ee.value),Rt(t,"plaintext"),t});function po(){const e=Ce(I(Ce(I({wordWrap:"on",wrappingIndent:"same",themes:r.themes},re.value||{}),{languages:pi.value,stream:!1,fontSize:ln.value,lineHeight:on.value,theme:Tt(),disableFileHeader:!0}),m.value?{diffAppearance:Hn.value}:{}),{onThemeChange(){el()}}),t=(function(){var n;const l=(n=re.value)==null?void 0:n.fontFamily;return typeof l=="string"&&l.trim()?l.trim():m.value?(function(){var o;if(typeof window>"u")return;const i=(o=$.value)==null?void 0:o.querySelector("pre.code-pre-fallback");if(i)return window.getComputedStyle(i).fontFamily.trim()||void 0})():void 0})();if(t&&(e.fontFamily!=null||(e.fontFamily=t)),m.value){e.wordWrap=Dn.value?"on":"off";const n=typeof e.unsafeCSS=="string"?`${e.unsafeCSS} +`:"",l=(function(){var o,i;const d=An.value;if(d===!1||typeof d=="object"&&d.enabled===!1)return null;const u=typeof d=="object"?d:jt,a=Math.max(0,Math.floor((o=u.contextLineCount)!=null?o:2));return{contextLineCount:a,collapsedContextThreshold:a+Math.max(1,Math.floor((i=u.minimumLineCount)!=null?i:4))-1}})();e.unsafeCSS=`${n} +pre { column-gap: 0; } +pre > code { column-gap: 0; padding-block: 0; } +[data-separator="line-info"] { margin-top: 0; } +`,l?(e.parseDiffOptions=Ce(I({},e.parseDiffOptions),{context:l.contextLineCount}),e.collapsedContextThreshold=l.collapsedContextThreshold,e.expandUnchanged=!1,e.hunkSeparators="line-info",e.unsafeCSS+=`[data-separator="line-info"][data-separator-last] { height: 28px; } +`):(e.expandUnchanged=!0,e.hunkSeparators="simple")}return e}function at(){const e=po();if(!He)return He=e,He;for(const t of Object.keys(He))t in e||delete He[t];return Object.assign(He,e),He}const ho=k(()=>{var e,t,n,l,o,i,d,u,a,c,s,v,p,y,h;return JSON.stringify({diffLineStyle:(t=(e=re.value)==null?void 0:e.diffLineStyle)!=null?t:"background",diffUnchangedRegionStyle:(l=(n=re.value)==null?void 0:n.diffUnchangedRegionStyle)!=null?l:"line-info",diffHideUnchangedRegions:((o=r.monacoOptions)==null?void 0:o.diffHideUnchangedRegions)===void 0?I({},jt):gn(r.monacoOptions.diffHideUnchangedRegions),renderSideBySide:(d=(i=re.value)==null?void 0:i.renderSideBySide)==null||d,useInlineViewWhenSpaceIsLimited:(a=(u=re.value)==null?void 0:u.useInlineViewWhenSpaceIsLimited)!=null&&a,enableSplitViewResizing:(s=(c=re.value)==null?void 0:c.enableSplitViewResizing)==null||s,ignoreTrimWhitespace:(p=(v=re.value)==null?void 0:v.ignoreTrimWhitespace)==null||p,originalEditable:(h=(y=re.value)==null?void 0:y.originalEditable)!=null&&h})}),go=O(0);function ul(){var e;const t=Tt();return JSON.stringify({kind:Ot.value,language:Ee.value,structural:ho.value,optionsRevision:go.value,settledContentGeneration:xl.value,theme:(e=rt(t))!=null?e:t==null?null:"custom",isDark:r.isDark})}ae(()=>[r.monacoOptions,r.theme,r.themes,r.lightTheme,r.darkTheme],()=>{go.value+=1},{deep:!0}),ae(()=>[Te.value,r.node.originalCode,r.node.updatedCode],()=>{Nn.value+=1,Ue()||(xl.value+=1)});const ut=k(()=>ul());function sl(){me.value&&et.value!==ut.value&&(me.value=!1,et.value=null,zt=null,Tn=null,Q.value=!1,W.value=!1,Se.value=!1,D.value=!1,$t.value=!1)}function yo(){return sl(),me.value&&et.value===ut.value}function je(e=ut.value){et.value=e,me.value=!0,$t.value=!1}return ae(ut,()=>q(null,null,function*(){if(tt||!me.value||et.value===ut.value||!ue||!f.value||ge.value||B||!Z.value||r.stream===!1&&r.loading!==!1||fn())return;const e=ut.value;tt=!0;try{if(sl(),me.value)return;yield Ae(f.value)}catch{W.value=!1,D.value=!1,je()}finally{Tn=e,yield j(),tt=!1}})),ae(()=>[r.monacoOptions,Z.value],()=>{var e,t;if(at(),!ue||!Z.value)return;const n=m.value?U():se(),l=typeof((e=r.monacoOptions)==null?void 0:e.fontSize)=="number"?r.monacoOptions.fontSize:Number.isFinite(_.value)?_.value:void 0;typeof l=="number"&&Number.isFinite(l)&&l>0&&((t=n?.updateOptions)==null||t.call(n,{fontSize:l})),le(!1)},{deep:!0}),ae(()=>[Tt(),Hn.value,wt.value,Q.value,Z.value],([e],t)=>{wt.value&&W.value&&Z.value&&mo({appearanceOnly:t!=null&&vo(e,t[0])})},{flush:"post"}),ae(()=>[ho.value,wt.value,Z.value],(e,t)=>q(null,[e,t],function*([n,l,o],[i]){if(at(),!l||!o||!ue||!f.value||!Q.value||n===i||r.stream===!1&&r.loading!==!1)return;const d=$e;if(d){try{yield d}catch{}if(B||!f.value)return}try{W.value=!1,D.value=!1,Q.value=!1,Se.value=!1,ot(),Re(),Xe(),yield j(),yield Ae(f.value,{allowStaleContentRetry:!1})}catch{W.value=!1,D.value=!1,je()}}),{flush:"post"}),ae(()=>[r.loading,Z.value],(e,t)=>q(null,[e,t],function*([n,l],o){if(!l)return;const i=o?.[0];if(i===!1&&n!==!1&&m.value&&Q.value&&(yield j(),fe(()=>{q(null,null,function*(){const u=$e;if(u)try{yield u}catch{}!B&&m.value&&r.loading!==!1&&(at(),xt(),de())})})),n)return;const d=i!==void 0&&i!==!1;yield j(),fe(()=>{q(null,null,function*(){var u,a;try{if(d&&(yield(function(){return q(this,null,function*(){if(!me.value||!ue||!f.value||ge.value||B||!Z.value)return!1;if(Tn===ut.value)return!0;tt=!0;try{me.value=!1,et.value=null,zt=null,Q.value=!1,W.value=!1,Se.value=!1,D.value=!1,ot(),Re(),Xe(),yield j();try{yield Ae(f.value)}catch{W.value=!1,D.value=!1,je()}}finally{yield j(),tt=!1}return!0})})()))return void le(!1);if(d&&m.value&&Q.value&&Rn&&f.value)return Rn=!1,W.value=!1,D.value=!1,Q.value=!1,Se.value=!1,ot(),Re(),Xe(),yield j(),yield Ae(f.value,{allowStaleContentRetry:!1}),void it(!0);if(d&&Q.value)if(m.value&&f.value){const c=$e;if(c)try{yield c}catch{}at();const s=Pt(String((u=r.node.originalCode)!=null?u:""),String((a=r.node.updatedCode)!=null?a:""));if(yield no(s.original,s.updated,Ee.value),B||!m.value)return;xt(),ee(!0),Ol(),he(),lt();const v=yield to({requireHighlight:!0});B||!v||D.value||(yield $l()),de(),it(!0)}else io(),ao(Te.value,Ee.value);d&&m.value?(le({preferModelDiffHeight:!0,holdCurrentDiffHeight:!0}),it(!0)):le(!1)}catch{}})})}),{immediate:!0,flush:"post"}),No(()=>{ot(),Re(),Fn(),Xt?.()}),(e,t)=>ge.value?(G(),bn(V(Mo),{key:0,class:mt(["code-pre-fallback",{"is-wrap":Dn.value}]),style:It(Pl.value),node:Ml.value,loading:r.loading,"show-line-numbers":!0,"diff-inline":Ie.value,"diff-hide-unchanged-regions":An.value},null,8,["class","style","node","loading","diff-inline","diff-hide-unchanged-regions"])):(G(),oe("div",{key:1,ref_key:"container",ref:$,style:It(ai.value),class:mt(["code-block-container rounded-lg border",[{dark:r.isDark,"is-rendering":r.loading,"is-dark":bl.value,"is-diff":m.value,"is-plain-text":xn.value}]]),"data-markstream-code-block":"1","data-markstream-enhanced":D.value&&!ge.value?"true":"false","data-markstream-enhancement-state":Uo.value,"data-markstream-code-block-state":Ue()?"streaming":"settled","data-markstream-pending":Io.value?"true":void 0,"data-markstream-viewport-pending":hl.value&&V(Bn)&&!Z.value?"true":void 0},[To(pr,{"show-header":r.showHeader,"show-collapse-button":r.showCollapseButton,"show-font-size-buttons":r.showFontSizeButtons,"enable-font-size-control":r.enableFontSizeControl,"show-copy-button":r.showCopyButton,"show-expand-button":r.showExpandButton,"show-preview-button":r.showPreviewButton,"show-tooltips":r.showTooltips,"is-dark":r.isDark,loading:r.loading,stream:x.stream,"is-collapsed":xe.value,"is-expanded":Fe.value,"copy-text":yt.value,"is-previewable":rl.value,"code-font-size":_.value,"code-font-min":10,"code-font-max":36,"default-code-font-size":pe.value,"font-baseline-ready":Vo.value,"diff-stats":m.value?Ze.value:null,"diff-stats-aria-label":qo.value,onToggleCollapse:ci,onDecreaseFont:ti,onResetFont:ni,onIncreaseFont:ei,onCopy:si,onToggleExpand:di,onPreview:fi},Oi({"header-left":Ut(()=>[pt(e.$slots,"header-left",{},()=>[b("div",xr,[b("span",{class:"icon-slot h-4 w-4 flex-shrink-0",innerHTML:ri.value},null,8,Sr),b("div",Cr,[b("div",Mr,Me(ii.value),1),so.value?(G(),oe("div",Br,Me(so.value),1)):ye("",!0)])])],!0)]),loading:Ut(()=>[pt(e.$slots,"loading",{loading:x.loading,stream:x.stream},()=>[t[0]||(t[0]=b("div",{class:"loading-skeleton"},[b("div",{class:"skeleton-line"}),b("div",{class:"skeleton-line"}),b("div",{class:"skeleton-line short"})],-1))],!0)]),default:Ut(()=>[cl(b("div",{class:mt(["code-editor-layer",{"code-editor-layer--collapsed":xe.value}])},[b("div",{ref_key:"codeEditor",ref:f,class:mt(["code-editor-container",x.stream?"":"code-height-placeholder"]),"data-markstream-host-hidden":_o.value?"true":void 0,style:It(Xo.value)},null,14,Er),Cl.value?(G(),bn(V(Mo),{key:0,class:mt(["code-pre-fallback",{"is-wrap":Dn.value}]),style:It(Pl.value),node:Ml.value,"show-line-numbers":!0,"diff-inline":Ie.value,"diff-hide-unchanged-regions":An.value},null,8,["class","style","node","diff-inline","diff-hide-unchanged-regions"])):ye("",!0)],2),[[fl,!!x.stream||!x.loading]]),en.value&&!Gt.value&&rl.value&&ke.value==="html"?(G(),bn(br,{key:0,code:r.node.code,"html-preview-allow-scripts":r.htmlPreviewAllowScripts,"html-preview-sandbox":r.htmlPreviewSandbox,"is-dark":r.isDark,"on-close":()=>en.value=!1},null,8,["code","html-preview-allow-scripts","html-preview-sandbox","is-dark","on-close"])):ye("",!0)]),_:2},[e.$slots["header-right"]?{name:"header-right",fn:Ut(()=>[pt(e.$slots,"header-right",{},void 0,!0)]),key:"0"}:void 0]),1032,["show-header","show-collapse-button","show-font-size-buttons","enable-font-size-control","show-copy-button","show-expand-button","show-preview-button","show-tooltips","is-dark","loading","stream","is-collapsed","is-expanded","copy-text","is-previewable","code-font-size","default-code-font-size","font-baseline-ready","diff-stats","diff-stats-aria-label"])],14,kr))}}),[["__scopeId","data-v-72200115"]]);export{Lr as default}; diff --git a/apps/kimi-code/dist-web/assets/CodeBlockNode-CJGhujJE.js b/apps/kimi-code/dist-web/assets/CodeBlockNode-CJGhujJE.js deleted file mode 100644 index a1e0867ac..000000000 --- a/apps/kimi-code/dist-web/assets/CodeBlockNode-CJGhujJE.js +++ /dev/null @@ -1,29 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-foxHOIBX.js","assets/index-D1h84VfZ.js","assets/index-BTY1et1y.css"])))=>i.map(i=>d[i]); -import{bR as xi,cb as Si,bQ as Ho,M as pl,bl as Ci,af as fl,bY as Mi,cc as Bi,b$ as hl,aU as $,c0 as Ei,c1 as Fi,c2 as Pi,a0 as Mo,aD as No,bE as ue,az as Li,cd as wn,c8 as mt,aI as To,aL as Y,s as Sn,aw as Vt,au as pt,bk as J,ce as Bo,u as ie,I as Ro,A as Oi,bJ as Gt,aY as ht,bL as vl,v as w,t as we,bB as ml,bb as Be,q as b,b7 as $i,cf as zi,cg as bn,ch as Hi,ci as Ni,cj as Ti,ck as Ri,as as A,cl as Eo,cm as Di,cn as Ai,co as Wt,cp as Fo,bO as Do,T as ji,G as qi,F as Po,g as Wi,c7 as _i,b_ as Ii}from"./index-D1h84VfZ.js";import{i as fe,t as kn}from"./safeRaf-DGuzXxDK.js";var xn=(k,M,y)=>new Promise((te,ne)=>{var be=P=>{try{r(y.next(P))}catch(H){ne(H)}},ke=P=>{try{r(y.throw(P))}catch(H){ne(H)}},r=P=>P.done?te(P.value):Promise.resolve(P.value).then(be,ke);r((y=y.apply(k,M)).next())});let Lo=!1,_t=null,It=null,Ut=null;function Ui(){return xn(this,null,function*(){if(Ut)return Ut;Ut=xn(null,null,function*(){if(!It)try{if(It=(function(k){const M=k;if(typeof M?.useMonaco=="function")return M;const y=k?.default;return typeof y?.useMonaco=="function"?y:null})(yield xi(()=>import("./index-foxHOIBX.js"),__vite__mapDeps([0,1,2]))),!It)return null}catch{return null}try{return yield(function(k){return xn(this,null,function*(){return Lo?void 0:_t||(_t=xn(null,null,function*(){const y=globalThis?.MonacoEnvironment;y&&(typeof y.getWorker=="function"||typeof y.getWorkerUrl=="function")||typeof k?.preloadMonacoWorkers!="function"||(yield k.preloadMonacoWorkers()),Lo=!0}).finally(()=>{_t=null}),_t)})})(It),Si(),It}catch{return null}});try{return yield Ut}finally{Ut=null}})}var Vi=Object.defineProperty,Gi=Object.defineProperties,Ji=Object.getOwnPropertyDescriptors,Oo=Object.getOwnPropertySymbols,Yi=Object.prototype.hasOwnProperty,Qi=Object.prototype.propertyIsEnumerable,$o=(k,M,y)=>M in k?Vi(k,M,{enumerable:!0,configurable:!0,writable:!0,value:y}):k[M]=y,U=(k,M)=>{for(var y in M||(M={}))Yi.call(M,y)&&$o(k,y,M[y]);if(Oo)for(var y of Oo(M))Qi.call(M,y)&&$o(k,y,M[y]);return k},Me=(k,M)=>Gi(k,Ji(M)),j=(k,M,y)=>new Promise((te,ne)=>{var be=P=>{try{r(y.next(P))}catch(H){ne(H)}},ke=P=>{try{r(y.throw(P))}catch(H){ne(H)}},r=P=>P.done?te(P.value):Promise.resolve(P.value).then(be,ke);r((y=y.apply(k,M)).next())});const Xi={key:0,class:"code-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)] border-[var(--code-border)] bg-[var(--code-header-bg)] text-[var(--code-fg)]"},Ki={class:"flex items-center gap-0.5"},Zi=["aria-label"],er={class:"code-diff-stat removed"},tr={class:"code-diff-stat added"},nr=["aria-label"],lr={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},or={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},ir=["aria-pressed"],rr={key:3,class:"relative"},ar=["aria-expanded"],ur=["disabled"],sr=["disabled"],dr=["disabled"],cr={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},fr={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},vr={class:"code-loading-placeholder"},mr={class:"sr-only","aria-live":"polite",role:"status"},pr=pl({__name:"CodeBlockShell",props:{showHeader:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},enableFontSizeControl:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0},showPreviewButton:{type:Boolean,default:!0},showTooltips:{type:Boolean,default:!0},isDark:{type:Boolean,default:!1},loading:{type:Boolean,default:!1},stream:{type:Boolean,default:!1},isCollapsed:{type:Boolean,default:!1},isExpanded:{type:Boolean,default:!1},copyText:{type:Boolean,default:!1},isPreviewable:{type:Boolean,default:!1},codeFontSize:{},codeFontMin:{},codeFontMax:{},defaultCodeFontSize:{},fontBaselineReady:{type:Boolean,default:!1},diffStats:{},diffStatsAriaLabel:{}},emits:["toggleCollapse","decreaseFont","resetFont","increaseFont","copy","toggleExpand","preview"],setup(k,{emit:M}){const y=k,te=M,ne=$(!1),be=$(null),ke=$(null);function r(){mt(!0),ne.value=!ne.value,ne.value&&document.addEventListener("click",H,{once:!0,capture:!0})}function P(){mt(!0),ne.value=!1}function H(Q){var v,z;const wt=Q.target;(v=be.value)!=null&&v.contains(wt)||(z=ke.value)!=null&&z.contains(wt)?document.addEventListener("click",H,{once:!0,capture:!0}):P()}const re=b(()=>y.showFontSizeButtons&&y.enableFontSizeControl||y.showExpandButton||y.isPreviewable&&y.showPreviewButton),{t:T}=hl(),gt=b(()=>y.showTooltips!==!1);function Ge(Q,v){gt.value&&_i(Q.currentTarget,v,"top",!1,void 0,y.isDark)}function Ee(){gt.value&&mt()}function yt(Q){Ge(Q,y.copyText?T("common.copied")||"Copied":T("common.copy")||"Copy")}const gl=b(()=>{var Q,v;return!!Number.isFinite(y.codeFontSize)&&((Q=y.codeFontSize)!=null?Q:0)<=((v=y.codeFontMin)!=null?v:0)}),Jt=b(()=>!y.fontBaselineReady||y.codeFontSize===y.defaultCodeFontSize),Yt=b(()=>{var Q,v;return!!Number.isFinite(y.codeFontSize)&&((Q=y.codeFontSize)!=null?Q:0)>=((v=y.codeFontMax)!=null?v:100)});return(Q,v)=>(Y(),ie(Po,null,[y.showHeader?(Y(),ie("div",Xi,[ht(Q.$slots,"header-left"),ht(Q.$slots,"header-right",{},()=>[w("div",Ki,[k.diffStats?(Y(),ie("div",{key:0,class:"code-diff-stats","aria-label":k.diffStatsAriaLabel},[w("span",er,"-"+Be(k.diffStats.removed),1),w("span",tr,"+"+Be(k.diffStats.added),1)],8,Zi)):we("",!0),y.showCopyButton?(Y(),ie("button",{key:1,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] disabled:opacity-40 disabled:cursor-not-allowed transition-colors","aria-label":k.copyText?J(T)("common.copied")||"Copied":J(T)("common.copy")||"Copy",onClick:v[0]||(v[0]=z=>te("copy")),onMouseenter:v[1]||(v[1]=z=>yt(z)),onFocus:v[2]||(v[2]=z=>yt(z)),onMouseleave:Ee,onBlur:Ee},[k.copyText?(Y(),ie("svg",or,[...v[14]||(v[14]=[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(Y(),ie("svg",lr,[...v[13]||(v[13]=[w("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[w("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),w("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],40,nr)):we("",!0),y.showCollapseButton?(Y(),ie("button",{key:2,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] disabled:opacity-40 disabled:cursor-not-allowed transition-colors","aria-pressed":k.isCollapsed,onClick:v[3]||(v[3]=z=>te("toggleCollapse")),onMouseenter:v[4]||(v[4]=z=>Ge(z,k.isCollapsed?J(T)("common.expand")||"Expand":J(T)("common.collapse")||"Collapse")),onFocus:v[5]||(v[5]=z=>Ge(z,k.isCollapsed?J(T)("common.expand")||"Expand":J(T)("common.collapse")||"Collapse")),onMouseleave:Ee,onBlur:Ee},[(Y(),ie("svg",{style:Vt({rotate:k.isCollapsed?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...v[15]||(v[15]=[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,ir)):we("",!0),re.value?(Y(),ie("div",rr,[w("button",{ref_key:"moreBtnRef",ref:ke,type:"button",class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0 cursor-pointer text-[var(--code-action-fg)] hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] active:scale-[0.96] transition-colors","aria-expanded":ne.value,"aria-haspopup":"true",onClick:Do(r,["stop"]),onMouseenter:v[6]||(v[6]=z=>Ge(z,J(T)("common.more")||"More")),onFocus:v[7]||(v[7]=z=>Ge(z,J(T)("common.more")||"More")),onMouseleave:Ee,onBlur:Ee},[...v[16]||(v[16]=[qi('<svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" width="1em" height="1em" viewBox="0 0 24 24" class="action-icon"><g fill="currentColor"><circle cx="12" cy="5" r="1.5"></circle><circle cx="12" cy="12" r="1.5"></circle><circle cx="12" cy="19" r="1.5"></circle></g></svg>',1)])],40,ar),Ro(Wi,{name:"code-menu"},{default:Gt(()=>[ne.value?(Y(),ie("div",{key:0,ref_key:"moreMenuRef",ref:be,class:"code-more-menu min-w-[10rem] p-1 bg-[hsl(var(--ms-popover))] text-[hsl(var(--ms-popover-foreground))] border border-[var(--code-border)] shadow-[var(--ms-shadow-popover)]",role:"menu"},[y.showFontSizeButtons&&y.enableFontSizeControl?(Y(),ie(Po,{key:0},[w("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:gl.value,onClick:v[8]||(v[8]=z=>{J(mt)(!0),te("decreaseFont")})},[v[17]||(v[17]=w("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 12h14"})],-1)),w("span",null,Be(J(T)("common.fontSmaller")||"Font size −"),1)],8,ur),w("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:Jt.value,onClick:v[9]||(v[9]=z=>{J(mt)(!0),te("resetFont")})},[v[18]||(v[18]=w("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[w("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[w("path",{d:"M3 12a9 9 0 1 0 9-9a9.75 9.75 0 0 0-6.74 2.74L3 8"}),w("path",{d:"M3 3v5h5"})])],-1)),w("span",null,Be(J(T)("common.fontReset")||"Font size reset"),1)],8,sr),w("button",{type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] disabled:opacity-40 disabled:cursor-not-allowed transition-colors",disabled:Yt.value,onClick:v[10]||(v[10]=z=>{J(mt)(!0),te("increaseFont")})},[v[19]||(v[19]=w("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M5 12h14m-7-7v14"})],-1)),w("span",null,Be(J(T)("common.fontLarger")||"Font size +"),1)],8,dr)],64)):we("",!0),y.showExpandButton?(Y(),ie("button",{key:1,type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] transition-colors",onClick:v[11]||(v[11]=z=>{P(),te("toggleExpand")})},[k.isExpanded?(Y(),ie("svg",cr,[...v[20]||(v[20]=[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6"},null,-1)])])):(Y(),ie("svg",fr,[...v[21]||(v[21]=[w("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6"},null,-1)])])),w("span",null,Be(k.isExpanded?J(T)("common.collapse")||"Collapse":J(T)("common.expand")||"Expand"),1)])):we("",!0),k.isPreviewable&&y.showPreviewButton?(Y(),ie("button",{key:2,type:"button",role:"menuitem",class:"flex items-center gap-2 w-full py-1.5 px-2 rounded text-xs text-[var(--code-action-fg)] cursor-pointer whitespace-nowrap hover:bg-[var(--code-action-hover-bg)] hover:text-[var(--code-action-hover-fg)] transition-colors",onClick:v[12]||(v[12]=z=>{P(),te("preview")})},[v[22]||(v[22]=w("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[w("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[w("path",{d:"M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"}),w("circle",{cx:"12",cy:"12",r:"3"})])],-1)),w("span",null,Be(J(T)("common.preview")||"Preview"),1)])):we("",!0)],512)):we("",!0)]),_:1})])):we("",!0)])])])):we("",!0),vl(w("div",{class:pt(["code-block-shell-content",{"code-block-shell-content--collapsed":k.isCollapsed}])},[ht(Q.$slots,"default")],2),[[ml,!!k.stream||!k.loading]]),vl(w("div",vr,[ht(Q.$slots,"loading",{},()=>[v[23]||(v[23]=w("div",{class:"loading-skeleton"},[w("div",{class:"skeleton-line"}),w("div",{class:"skeleton-line"}),w("div",{class:"skeleton-line short"})],-1))])],512),[[ml,!k.stream&&k.loading]]),w("span",mr,Be(k.copyText?J(T)("common.copied")||"Copied":""),1)],64))}}),hr={class:"html-preview-frame__header"},gr={class:"html-preview-frame__title"},yr={class:"html-preview-frame__label"},wr=["sandbox","srcdoc"],br=Ho(pl({__name:"HtmlPreviewFrame",props:{code:{},isDark:{type:Boolean},htmlPreviewAllowScripts:{type:Boolean},htmlPreviewSandbox:{},onClose:{type:Function},title:{}},setup(k){const M=k,y=import.meta!==void 0&&!1;let te=null;const{t:ne}=hl(),be=b(()=>{const P=M.code||"",H=P.trim().toLowerCase();return H.startsWith("<!doctype")||H.startsWith("<html")||H.startsWith("<body")?P:`<!doctype html> -<html lang="en"> - <head> - <meta charset="utf-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1" /> - <style> - html, body { - margin: 0; - padding: 0; - height: 100%; - background-color: ${M.isDark?"#020617":"#ffffff"}; - color: ${M.isDark?"#e5e7eb":"#020617"}; - } - body { - font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', ui-sans-serif, sans-serif; - } - </style> - </head> - <body> - ${P} - </body> -</html>`}),ke=b(()=>{return P=M.htmlPreviewSandbox,H=M.htmlPreviewAllowScripts,typeof P=="string"?((function(re){if(!y||typeof console>"u"||te===re)return;const T=(function(gt){return new Set(gt.trim().toLowerCase().split(/\s+/).filter(Boolean))})(re);T.has("allow-scripts")&&T.has("allow-same-origin")&&(te=re,console.warn("[markstream-vue] htmlPreviewSandbox contains both allow-scripts and allow-same-origin. Use this only for fully trusted content served from an isolated origin."))})(P),P):P!==void 0?"":H===!0?"allow-scripts":"";var P,H});function r(P){var H;P.key!=="Escape"&&P.key!=="Esc"||(H=M.onClose)==null||H.call(M)}return No(()=>{typeof window<"u"&&window.addEventListener("keydown",r)}),To(()=>{typeof window<"u"&&window.removeEventListener("keydown",r)}),(P,H)=>(Y(),Sn(ji,{to:"body"},[w("div",{class:pt(["markstream-vue",{dark:M.isDark}])},[w("div",{class:"html-preview-frame__backdrop",onClick:H[2]||(H[2]=re=>{var T;return(T=M.onClose)==null?void 0:T.call(M)})},[w("div",{class:"html-preview-frame",onClick:H[1]||(H[1]=Do(()=>{},["stop"]))},[w("div",hr,[w("div",gr,[H[3]||(H[3]=w("span",{class:"html-preview-frame__dot"},null,-1)),w("span",yr,Be(M.title||J(ne)("common.preview")||"Preview"),1)]),w("button",{type:"button",class:"html-preview-frame__close",onClick:H[0]||(H[0]=re=>{var T;return(T=M.onClose)==null?void 0:T.call(M)})}," × ")]),w("iframe",{class:"html-preview-frame__iframe",sandbox:ke.value,referrerpolicy:"no-referrer",srcdoc:be.value},null,8,wr)])])],2)]))}}),[["__scopeId","data-v-24e66176"]]),kr=["data-markstream-enhanced","data-markstream-enhancement-state","data-markstream-code-block-state","data-markstream-pending","data-markstream-viewport-pending"],xr={class:"code-header-main"},Sr=["innerHTML"],Cr={class:"code-header-copy"},Mr={class:"code-header-title"},Br={key:0,class:"code-header-caption"},Er=["data-markstream-host-hidden"],zo="__markstreamMonacoPassiveTouchState__",Lr=Ho(pl({__name:"CodeBlockNode",props:{node:{},isDark:{type:Boolean,default:!1},loading:{type:Boolean,default:!0},stream:{type:Boolean,default:!0},theme:{},darkTheme:{default:"vitesse-dark"},lightTheme:{default:"vitesse-light"},isShowPreview:{type:Boolean,default:!0},monacoOptions:{},enableFontSizeControl:{type:Boolean,default:!0},minWidth:{default:void 0},maxWidth:{default:void 0},themes:{},showPreviewButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},showTooltips:{type:Boolean},htmlPreviewAllowScripts:{type:Boolean},htmlPreviewSandbox:{},customId:{},showHeader:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0},estimatedHeightPx:{},estimatedContentHeightPx:{},estimatedDiffInline:{type:Boolean}},emits:["previewCode","copy"],setup(k,{emit:M}){var y,te,ne,be,ke;const r=k,P=M,H=Ci(),re=fl(Mi,null),T=fl("markstreamHostScrollManaged",null),gt=fl(Bi,void 0),Ge=b(()=>Ii(r,H)),Ee=new Set;function yt(e){return j(this,null,function*(){var t;if(typeof window>"u")return yield e();const n=(t=window.Element)==null?void 0:t.prototype,l=n?.addEventListener;if(!n||!l)return yield e();const o=(function(){const s=window,u=s[zo];if(u)return u;const a={depth:0,original:null};return s[zo]=a,a})();let i=null;try{o.depth===0&&(o.original=l,n.addEventListener=function(u,a,c){var d;const f=(d=o.original)!=null?d:l;return u==="touchstart"&&(function(p,h){if(!p)return!1;const x=p;return!(typeof x.closest!="function"||!x.closest(".monaco-editor, .monaco-diff-editor")||h&&typeof h=="object"&&"passive"in h)})(this,c)?f.call(this,u,a,(function(p){return p==null?{passive:!0}:typeof p=="boolean"?{capture:p,passive:!0}:typeof p=="object"?"passive"in p?p:Me(U({},p),{passive:!0}):{passive:!0}})(c)):f.call(this,u,a,c)}),o.depth++;let s=!1;i=()=>{s||(s=!0,Ee.delete(i),o.depth=Math.max(0,o.depth-1),o.depth===0&&o.original&&n.addEventListener!==o.original&&(n.addEventListener=o.original,o.original=null))},Ee.add(i)}catch{return yield e()}try{return yield e()}finally{i?.()}})}function gl(e,t){}const Jt=Mo(),Yt=b(()=>{const e=Jt?.vnode.props;return!(!e||!e.onPreviewCode&&!e["onPreview-code"])}),{t:Q}=hl(),v=$(null),z=$(null),wt=$(!1),xe=$(ao(r.node.language,r.node.code,Ve())),Cn=b(()=>Eo(xe.value)),Fe=b(()=>Cn.value==="plaintext"?"text":Cn.value),Mn=b(()=>Cn.value==="plaintext"),Pe=$(!1),Se=$(!1),X=$(!1),Ce=$(!1),q=$(!1),bt=$(!1);let B=!1,kt=null,Ft=null,Je=null,Ye=0,Qe=!1,We="";const _e=$(null),ve=$(null);let Bn=null,En=0,Fn=!1;const Ao=Ei(),Qt=Fi(),Pn=Pi(),Ie=$i(null),Z=$(typeof window>"u"||!Pn.value),jo=(ne=(te=(y=Mo())==null?void 0:y.vnode.el)==null?void 0:te.textContent)!=null?ne:"",qo=typeof window<"u"&&String((be=r.node.code)!=null?be:"").length>0&&jo.includes(String(r.node.code)),yl=$(!qo);No(()=>{yl.value=!0}),typeof window<"u"&&ue([()=>z.value,Pn],([e,t],n,l)=>{var o,i,s;if((o=Ie.value)==null||o.destroy(),Ie.value=null,!t||Z.value)return void(Z.value=!0);if(!e)return void(Z.value=!1);let u=!0;const a=(s=(i=Qt?.value.heavyBlockMargin)!=null?i:Qt?.value.rootMargin)!=null?s:"0px",c=Ao(e,{rootMargin:a,allowIdle:!1});Ie.value=c,Z.value=Z.value||c.isVisible.value,c.whenVisible.then(()=>{u&&Ie.value===c&&(Z.value=!0)}).catch(()=>{}),l(()=>{u=!1,c.destroy(),Ie.value===c&&(Ie.value=null)})},{immediate:!0}),Li(()=>{var e;B=!0;for(const t of Array.from(Ee))t();(function(){const t=We;re&&t&&(We="",re.markSettled(t))})(),(e=Ie.value)==null||e.destroy(),Ie.value=null});let se=null,Xt=null,Ln=()=>{},Kt=()=>{},xt=()=>null,de=()=>({getModel:()=>({getLineCount:()=>1}),getOption:()=>14,updateOptions:()=>{}}),V=()=>({getModel:()=>({getLineCount:()=>1}),getOption:()=>14,updateOptions:()=>{}}),On=()=>{},Xe=()=>{},$n=()=>{},Ke=null,ze=null,Pt=null,Lt=null,wl=()=>{var e;return String((e=r.node.language)!=null?e:"plaintext")},zn=()=>j(null,null,function*(){}),Hn=!1,Zt=null;const He=[],Nn=[];let Ne=null;const m=b(()=>zi(r.node)),Ze=$({removed:0,added:0}),Wo=b(()=>`-${Ze.value.removed} +${Ze.value.added}`),bl=Object.freeze(Me(U({},Wt),{enabled:!1,revealLineCount:0}));function kl(e){var t,n,l;const o=((n=(t=z.value)==null?void 0:t.getBoundingClientRect)==null?void 0:n.call(t).width)||((l=z.value)==null?void 0:l.clientWidth)||(typeof window>"u"?0:window.innerWidth);return Di(e,o)}function Ot(e,t){return{original:en(e),updated:en(t)}}function en(e){return String(e??"").replace(/\r\n$|\n$|\r$/,"")}function $t(e){var t;return String((t=e?.message)!=null?t:e).includes("no diff result available")}function St(){if(!$e())try{const e=$n();e&&typeof e.catch=="function"&&e.catch(t=>{$t(t)})}catch(e){$t(e)}}const ae=b(()=>{var e,t,n,l;const o=r.monacoOptions?U({},r.monacoOptions):{};if(!m.value)return U({lineDecorationsWidth:0,lineNumbersMinChars:2,glyphMargin:!1},o);const i=o.diffHideUnchangedRegions===void 0?U({},Wt):bn(o.diffHideUnchangedRegions),s=o.hideUnchangedRegions===void 0?void 0:bn(o.hideUnchangedRegions),u=r.stream!==!1&&r.loading!==!1,a=u?U({},bl):i,c=u?U({},bl):s,d=(function(g){return g.diffWordWrap!==void 0?g.diffWordWrap:"off"})(o),f=U({},(e=o.experimental)!=null?e:{}),p=(t=o.diffUnchangedRegionStyle)!=null?t:"line-info",h=(function(g){const N=g.scrollbar&&typeof g.scrollbar=="object"?g.scrollbar:{};return U(Me(U({},N),{verticalScrollbarSize:0,horizontalScrollbarSize:0}),kl(g)?{horizontal:"hidden"}:{})})(o),x={maxComputationTime:0,diffAlgorithm:"legacy",ignoreTrimWhitespace:!1,renderIndicators:!0,diffUpdateThrottleMs:120,renderLineHighlight:"none",renderLineHighlightOnlyWhenFocus:!0,selectionHighlight:!1,occurrencesHighlight:"off",matchBrackets:"never",lineDecorationsWidth:4,lineNumbersMinChars:2,glyphMargin:!1,padding:{top:0,bottom:0},minimap:{enabled:!1},renderOverviewRuler:!1,overviewRulerBorder:!1,hideCursorInOverviewRuler:!0,scrollBeyondLastLine:!1,diffWordWrap:d,renderSideBySide:(n=o.renderSideBySide)==null||n,diffHideUnchangedRegions:a,useInlineViewWhenSpaceIsLimited:(l=o.useInlineViewWhenSpaceIsLimited)!=null&&l,diffLineStyle:"background",diffAppearance:"auto",diffUnchangedRegionStyle:p,diffHunkActionsOnHover:!1,experimental:f};return Me(U(Me(U(U({},x),o),{experimental:f}),c===void 0?{}:{hideUnchangedRegions:c}),{diffHideUnchangedRegions:a,diffWordWrap:d,scrollbar:h})}),Tn=b(()=>(r.theme!==void 0?!po(r.theme):ho(r.darkTheme,r.lightTheme))?(function(e){var t,n;if(e&&typeof e=="object"&&((t=e.colors)!=null&&t["editor.background"])){const o=el(e.colors["editor.background"]);if(o!=null)return o<128}const l=((n=rt(e))!=null?n:"").toLowerCase();return l?["dark","night","moon","black","dracula","mocha","frappe","macchiato","palenight","ocean","poimandres","monokai","laserwave","tokyo","slack-dark","rose-pine","github-dark","material-theme","one-dark","catppuccin-mocha","catppuccin-frappe","catppuccin-macchiato"].some(o=>l.includes(o))&&!["light","latte","dawn","lotus"].some(o=>l.includes(o)):!!r.isDark})(Dt()):!!r.isDark),Rn=b(()=>{var e;if(!m.value)return Tn.value?"dark":"light";const t=(e=ae.value)==null?void 0:e.diffAppearance;return t==="light"||t==="dark"?t:Tn.value?"dark":"light"}),xl=b(()=>m.value?Rn.value==="dark":Tn.value),zt=b(()=>m.value?"diff":"single"),Sl=$(zt.value),ge=$(!1),R=$(!1),Ht=$(!1),me=$(!1),et=$(null),Dn=$(0),Cl=$(0),tn=$(!1);let Nt=null,tt=!1,An=null,jn=!1;const qn=b(()=>{var e,t,n;if(m.value){const o=(e=ae.value)==null?void 0:e.diffWordWrap;if(o==="inherit"){const i=(t=r.monacoOptions)==null?void 0:t.wordWrap;return i==null||String(i)!=="off"}return o==="on"}const l=(n=r.monacoOptions)==null?void 0:n.wordWrap;return l==null||String(l)!=="off"}),Ue=b(()=>{var e;return!!m.value&&kl((e=ae.value)!=null?e:{})}),Wn=b(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.diffHideUnchangedRegions;return t===void 0?U({},Wt):bn(t)});function Ml(e){return T?.value===!0||!!e&&(!!e.closest('[data-markstream-virtual-timeline="1"], .markstream-virtual-timeline')||!!e.closest(".vue-recycle-scroller, [data-virtualizer], [data-virtual-scroll-root]"))}const _o=b(()=>Ml(z.value)),Te=b(()=>!(ge.value||!me.value&&R.value)),Bl=b(()=>Te.value),Io=b(()=>Te.value&&!Ht.value),Uo=b(()=>!ge.value&&!me.value&&Te.value),Vo=b(()=>R.value&&!ge.value?"ready":me.value?"fallback":"pending"),nn=$(!1),Re=b(()=>en(r.node.code)),El=b(()=>m.value?r.node.diff===!0?r.node:Me(U({},r.node),{diff:!0}):Re.value===r.node.code?r.node:Me(U({},r.node),{code:Re.value})),pe=$(typeof((ke=r.monacoOptions)==null?void 0:ke.fontSize)=="number"?r.monacoOptions.fontSize:Number.NaN),W=$(pe.value),_n=$(null),ln=$(null),on=$(null),Go=b(()=>{const e=pe.value,t=W.value;return typeof e=="number"&&Number.isFinite(e)&&e>0&&typeof t=="number"&&Number.isFinite(t)&&t>0}),rn=b(()=>{var e;const t=_n.value;if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;const n=(e=r.monacoOptions)==null?void 0:e.fontSize;if(typeof n=="number"&&Number.isFinite(n)&&n>0)return n;const l=W.value;return typeof l=="number"&&Number.isFinite(l)&&l>0?l:12}),Jo=b(()=>{var e;const t=ln.value;if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;const n=(e=r.monacoOptions)==null?void 0:e.lineHeight;return typeof n=="number"&&Number.isFinite(n)&&n>0?n:rn.value===12?18:Math.max(12,Math.round(1.5*rn.value))}),an=b(()=>Jo.value),Fl=b(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.tabSize;return typeof t=="number"&&Number.isFinite(t)&&t>0?t:4}),un=b(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.padding,n=m.value?0:8;return{top:typeof t?.top=="number"&&Number.isFinite(t.top)&&t.top>=0?t.top:n,bottom:typeof t?.bottom=="number"&&Number.isFinite(t.bottom)&&t.bottom>=0?t.bottom:n}}),sn=b(()=>{const e=r.estimatedContentHeightPx;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:null});function dn(e){if(e==null)return null;const t=Math.ceil(e);return!Number.isFinite(t)||t<=0?null:Math.min(t,Math.ceil(Mt()))}function In(){return!m.value&&r.stream!==!1&&r.loading!==!1}const Pl=b(()=>m.value?null:sn.value==null||In()?Math.ceil((e=>{const t=String(e??"");return t?Math.max(1,t.split(/\r\n|\n|\r/).length):1})(Re.value)*an.value+1):null),Ll=b(()=>{if(m.value)return null;const e=sn.value;return e==null||In()?dn(Pl.value):dn(e)}),Yo=b(()=>{const e=r.estimatedHeightPx;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:null}),Un=$(null);function nt(){const e=Un.value;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.round(e):null}const Vn=b(()=>{const e=nt();return e??(!m.value&&tn.value?null:Te.value||!R.value?Ll.value:null)});function Ol(e){const t=e?"hsl(152 42% 60%)":"var(--diff-added-fg)",n=e?"hsl(0 58% 58%)":"var(--diff-removed-fg)",l=e?"hsl(152 42% 60% / 0.18)":"var(--diff-added-bg)",o=e?"hsl(0 58% 58% / 0.18)":"var(--diff-removed-bg)",i=e?"hsl(152 42% 60% / 0.28)":"var(--diff-added-inline-bg)",s=e?"hsl(0 58% 58% / 0.28)":"var(--diff-removed-inline-bg)",u=`linear-gradient(90deg, ${t} 0 4px, transparent 4px 100%)`,a=`linear-gradient(90deg, ${n} 0 4px, transparent 4px 100%)`,c=e?"hsl(0 0% 7% / 0.98)":"hsl(var(--ms-muted) / 0.45)",d="var(--markstream-code-layout-character-width, 1ch)",f=`calc(${d} + ${d})`,p=`calc(${d} + ${d} + ${d} + ${d} + ${d} + 2px)`,h=`calc(${p} + ${d})`;return{"--markstream-diff-line-number-bg":c,"--markstream-diff-added-fg":t,"--markstream-diff-removed-fg":n,"--markstream-diff-added-line":l,"--markstream-diff-removed-line":o,"--markstream-diff-added-line-fill":l,"--markstream-diff-removed-line-fill":o,"--markstream-diff-added-gutter":u,"--markstream-diff-removed-gutter":a,"--markstream-diff-added-inline":i,"--markstream-diff-removed-inline":s,"--stream-monaco-added-fg":t,"--stream-monaco-removed-fg":n,"--stream-monaco-added-line":l,"--stream-monaco-removed-line":o,"--stream-monaco-added-line-fill":l,"--stream-monaco-removed-line-fill":o,"--stream-monaco-added-gutter":u,"--stream-monaco-removed-gutter":a,"--stream-monaco-added-inline":i,"--stream-monaco-removed-inline":s,"--stream-monaco-gutter-marker-width":"4px","--stream-monaco-gutter-gap":"1ch","--stream-monaco-line-number-left":"0px","--stream-monaco-line-number-width":f,"--stream-monaco-line-number-padding-left":f,"--stream-monaco-line-number-padding-right":d,"--stream-monaco-line-number-separator-width":"2px","--stream-monaco-layout-character-width":d,"--stream-monaco-line-number-box-width":p,"--stream-monaco-line-number-gap-to-code":d,"--stream-monaco-line-number-bg":c,"--stream-monaco-diff-code-gap":d,"--stream-monaco-diff-code-padding":"0px","--stream-monaco-original-margin-width":h,"--stream-monaco-original-scrollable-left":h,"--stream-monaco-original-scrollable-width":`calc(100% - ${h})`,"--stream-monaco-modified-margin-width":h,"--stream-monaco-modified-scrollable-left":h,"--stream-monaco-modified-scrollable-width":`calc(100% - ${h})`}}const $l=b(()=>{var e;const t=(e=r.monacoOptions)==null?void 0:e.fontFamily,n=dn(sn.value),l=dn(Pl.value),o=In(),i=U(U({fontSize:`${rn.value}px`,lineHeight:`${an.value}px`,tabSize:Fl.value,boxSizing:"border-box",maxHeight:`${Mt()}px`,overflow:"auto",paddingTop:`${un.value.top}px`,paddingBottom:`${un.value.bottom}px`},m.value||n==null||o?m.value||l==null?{}:{minHeight:`${l}px`}:{height:`${n}px`,minHeight:`${n}px`}),typeof t=="string"&&t.trim()?{"--markstream-code-font-family":t.trim()}:{});return i["--markstream-pre-line-number-top"]=`${un.value.top}px`,i["--markstream-pre-line-number-left"]="0px",i["--markstream-pre-line-number-padding-left"]="2ch",i["--markstream-pre-line-number-padding-right"]="1ch",i["--markstream-pre-line-number-separator-width"]="2px",m.value&&(i["--markstream-pre-diff-line-height"]=`${an.value}px`,i["--markstream-pre-diff-pane-bottom-padding"]=(Ue.value,"0px"),Object.assign(i,Ol(xl.value))),i}),zl=b(()=>Vn.value!=null&&(!R.value||nt()!=null)),Qo=b(()=>{const e=Vn.value;if(e==null)return null;if(m.value)return Math.ceil(e);const t=Yo.value,n=sn.value;if(t==null||n==null)return Math.ceil(e);const l=Math.max(0,Math.ceil(t)-Math.ceil(n));return Math.ceil(e+l)}),Xo=b(()=>{if(m.value&&Te.value)return{};const e=Vn.value;return zl.value&&e!=null?{minHeight:`${e}px`}:{}});function Hl(){var e,t,n,l,o,i,s,u;const a=(e=z.value)==null?void 0:e.querySelector("pre.code-pre-fallback"),c=V(),d=(t=a?.scrollTop)!=null?t:0;(o=(l=(n=c?.getOriginalEditor)==null?void 0:n.call(c))==null?void 0:l.setScrollTop)==null||o.call(l,d),(u=(s=(i=c?.getModifiedEditor)==null?void 0:i.call(c))==null?void 0:s.setScrollTop)==null||u.call(s,d)}function Nl(){return j(this,null,function*(){return m.value?(tl()!=null||cn(),ee(!0),Hl(),he(),Ht.value=!0,yield A(),ee(!0),yield Le(),ee(!0),!(Ke&&!(yield Ke())||(Rt(),cn(),ee(!0),R.value=!0,yield A(),cn(),ee(!0),Rt(),he(),ce(),0))):!(Ke&&!(yield Ke())||(R.value=!0,yield A(),le(!1),ee(),0))})}function cn(){const e=v.value;return e&&mn(e)?(he(),le({preferModelDiffHeight:!0}),it(),Number.parseFloat(e.style.height||"")||null):tl()}function Tl(){if(!m.value||!q.value||!R.value||Te.value)return!1;const e=v.value;return!!e&&Tt(e)}function Rl(e,t=!1,n={}){const l=Math.ceil(e),o=nt();if(o==null)return l;const i=n.allowBelowEstimatedFloor===!0||Tl();return l>=o||i?((t||i)&&q.value&&(Un.value=null),l):o}function Le(){return new Promise(e=>{let t=!1,n=null,l=null;const o=()=>{t||(t=!0,l!=null&&globalThis.clearTimeout(l),n!=null&&kn(n),e())};l=globalThis.setTimeout(o,50),n=fe(o)})}function Dl(){try{const e=v.value;if(!e)return null;const t=e.querySelector(".view-lines .view-line");if(t){const n=Math.ceil(t.getBoundingClientRect().height);if(n>0)return n}}catch{}return null}function Gn(){var e,t,n,l,o;try{const i=m.value?(n=(t=(e=V())==null?void 0:e.getModifiedEditor)==null?void 0:t.call(e))!=null?n:V():de(),s=xt(),u=(l=s?.EditorOption)==null?void 0:l.fontInfo;if(i&&u!=null){const a=(o=i.getOption)==null?void 0:o.call(i,u),c=a?.fontSize;if(typeof c=="number"&&Number.isFinite(c)&&c>0)return c}}catch{}try{const i=v.value;if(i){const s=i.querySelector(".view-lines .view-line");if(s)try{if(typeof window<"u"&&typeof window.getComputedStyle=="function"){const u=window.getComputedStyle(s).fontSize,a=u&&u.match(/^(\d+(?:\.\d+)?)/);if(a)return Number.parseFloat(a[1])}}catch{}}}catch{}return null}function Ct(e){var t,n;try{const i=xt(),s=(t=i?.EditorOption)==null?void 0:t.lineHeight;if(s!=null){const u=(n=e?.getOption)==null?void 0:n.call(e,s);if(typeof u=="number"&&u>0)return u}}catch{}const l=Dl();if(l&&l>0)return l;const o=Number.isFinite(W.value)&&W.value>0?W.value:14;return Math.max(12,Math.round(1.35*o))}function fn(e){var t,n,l;try{const i=xt(),s=(t=i?.EditorOption)==null?void 0:t.padding;if(s!=null){const u=(n=e?.getOption)==null?void 0:n.call(e,s);if(typeof u?.top=="number"||typeof u?.bottom=="number")return(typeof u?.top=="number"&&Number.isFinite(u.top)?Math.max(0,u.top):0)+(typeof u?.bottom=="number"&&Number.isFinite(u.bottom)?Math.max(0,u.bottom):0)}}catch{}const o=(l=ae.value)==null?void 0:l.padding;return typeof o?.top=="number"||typeof o?.bottom=="number"?(typeof o?.top=="number"&&Number.isFinite(o.top)?Math.max(0,o.top):0)+(typeof o?.bottom=="number"&&Number.isFinite(o.bottom)?Math.max(0,o.bottom):0):m.value?24:0}function Al(e,t){return typeof e!="number"||typeof t!="number"||e<1||t<e?0:t-e+1}function jl(e){if(!e)return[];const t=e.split(/\r?\n/);return t.length===1&&t[0]===""?[]:t}function vn(e,t){const n=jl(e),l=jl(t);let o=0,i=n.length-1,s=l.length-1;for(;o<=i&&o<=s&&n[o]===l[o];)o++;for(;i>=o&&s>=o&&n[i]===l[s];)i--,s--;const u=Math.max(0,i-o+1),a=Math.max(0,s-o+1);if(u===0||a===0)return{removed:u,added:a};if((u+1)*(a+1)<=15e5){const c=a+1;let d=new Uint32Array(c),f=new Uint32Array(c);for(let h=u-1;h>=0;h--){f[a]=0;for(let g=a-1;g>=0;g--)f[g]=n[o+h]===l[o+g]?d[g+1]+1:Math.max(d[g],f[g+1]);const x=d;d=f,f=x}const p=d[0];return{removed:u-p,added:a-p}}return{removed:u,added:a}}function ql(e){var t;if(!(function(){var s,u,a;return!(!m.value||!Ue.value)&&(r.node.originalCode!=null||r.node.updatedCode!=null?vn(String((s=r.node.originalCode)!=null?s:""),String((u=r.node.updatedCode)!=null?u:"")).removed>0:String((a=r.node.code)!=null?a:"").split(/\r\n|\n|\r/).some(c=>(function(d){return d.startsWith("-")&&!d.startsWith("---")})(c)))})())return!0;const n=e?.querySelector(".stream-monaco-fallback-inline-delete-line");if((t=n?.textContent)!=null&&t.trim()&&(n.hasAttribute("data-stream-monaco-colorize-signature")||n.querySelector('[class*="mtk"]')))return!0;const l=e?.querySelector([".editor.modified .view-zones .view-lines.line-delete",".editor.modified .view-lines .view-line.line-delete",".editor.original .view-zones .view-lines.line-delete",".editor.original .view-lines .view-line.line-delete"].join(","));if(!l||!l.matches(".view-line")&&!l.querySelector(".view-line"))return!1;const o=l.getBoundingClientRect(),i=e?.getBoundingClientRect();return i?.width===0&&i.height===0||o.width>0&&o.height>0}function Wl(e,t){if(!e)return!1;const n=t.added<=0||!!e.querySelector([".line-insert",".gutter-insert",".stream-monaco-fallback-line-insert",".stream-monaco-fallback-gutter-insert",".stream-monaco-fallback-line-number-insert"].join(",")),l=t.removed<=0||!!e.querySelector([".line-delete",".gutter-delete",".inline-deleted-margin-view-zone",".stream-monaco-fallback-line-delete",".stream-monaco-fallback-gutter-delete",".stream-monaco-fallback-line-number-delete",".stream-monaco-fallback-inline-delete-line",".stream-monaco-fallback-inline-delete-margin"].join(","));return n&&l}function Jn(e,t){const n=e?.querySelector(t);return n instanceof HTMLElement?typeof window>"u"||typeof window.getComputedStyle!="function"?n:window.getComputedStyle(n).display==="none"?null:n:null}function _l(e,t){return Jn(e,t)!==null}function Il(e,t){if(!e)return!1;const n=t.added<=0||[".gutter-insert",".stream-monaco-fallback-gutter-insert"].some(o=>_l(e,o)),l=t.removed<=0||[".gutter-delete",".inline-deleted-margin-view-zone",".stream-monaco-fallback-gutter-delete",".stream-monaco-fallback-inline-delete-margin"].some(o=>_l(e,o));return n&&l}function Ul(e){var t;const n=Array.from((t=e?.querySelectorAll(".monaco-diff-editor .margin-view-overlays .line-numbers"))!=null?t:[]);return!!n.length&&n.some(l=>{var o;if(!((o=l.textContent)!=null&&o.trim()))return!1;if(typeof window>"u"||typeof window.getComputedStyle!="function")return!0;const i=window.getComputedStyle(l);if(i.display==="none")return!1;const s=l.getBoundingClientRect();if(s.width<=0&&s.height<=0)return!0;const u=Number.parseFloat(i.width||""),a=Number.parseFloat(i.paddingLeft||""),c=Number.parseFloat(i.paddingRight||""),d=Math.max(s.width,Number.isFinite(u)?u:0)>=8,f=Number.isFinite(a)&&a>=1&&Number.isFinite(c)&&c>=1;return d&&f})}function Vl(e){const t=Jn(e,".monaco-diff-editor .view-lines .view-line");if(!t)return!1;if(!Qn())return!0;const n=Jn(e,".monaco-diff-editor .margin-view-overlays .line-numbers");if(!n)return!1;if(typeof window>"u"||typeof window.getComputedStyle!="function")return!0;const l=t.getBoundingClientRect(),o=n.getBoundingClientRect();if(l.width<=0&&l.height<=0||o.width<=0&&o.height<=0)return!0;const i=l.left-o.right;return i>=0&&i<=32}function Ko(e,t){return!Ue.value||!(t||e?.querySelector([".line-insert",".line-delete",".gutter-insert",".gutter-delete",".stream-monaco-line-number-insert",".stream-monaco-line-number-delete",".stream-monaco-line-insert-fill",".stream-monaco-line-delete-fill",".stream-monaco-fallback-line-insert",".stream-monaco-fallback-line-delete",".stream-monaco-fallback-inline-delete-line"].join(",")))||!!(e?.classList.contains("stream-monaco-diff-inline-native-ready")&&!e.classList.contains("stream-monaco-diff-native-stale"))}function Gl(e,t,n,l){const o=e?.querySelector(`.monaco-diff-editor .editor.${t}`);if(!o)return!1;const i=Array.from(o.querySelectorAll(`.margin-view-overlays .line-numbers.${n}`));if(!i.length)return!0;const s=Array.from(o.querySelectorAll(".lines-content > .view-lines:not(.line-delete) > .view-line"));return!!s.length&&i.every(u=>{const a=u.getBoundingClientRect();let c=null;for(const d of s){const f=d.getBoundingClientRect(),p=Math.abs(f.top-a.top);(!c||p<c.distance)&&(c={node:d,distance:p})}return!c||c.distance>1.25||c.node.classList.contains(l)})}function Zo(e,t){if(!e)return!1;const n=t.added<=0||Gl(e,"modified","stream-monaco-line-number-insert","stream-monaco-line-insert-fill"),l=t.removed<=0||(Ue.value?!!e.classList.contains("stream-monaco-diff-inline-native-ready"):Gl(e,"original","stream-monaco-line-number-delete","stream-monaco-line-delete-fill"));return n&&l}function Yn(e){if(Mn.value)return!0;if(!e)return!1;const t=Array.from(e.querySelectorAll(".monaco-diff-editor .view-lines .view-line, .monaco-editor .view-lines .view-line")).filter(l=>{var o;if(!((o=l.textContent)!=null&&o.trim()))return!1;const i=l.getBoundingClientRect();return i.width>0||i.height>0});if(!t.length)return!1;const n=t.filter(l=>{var o,i;return i=(o=l.textContent)!=null?o:"",/['"`{}()[\]:;=<>.,]|\/\/|\/\*|\b(?:async|await|class|const|enum|export|for|function|if|import|interface|let|return|switch|type|var|while)\b/.test(i.replace(/\u00A0/g," ").trim())});return!n.length||n.filter(l=>Array.from(l.querySelectorAll("span")).filter(o=>{var i;return(i=o.textContent)==null?void 0:i.trim()}).some(o=>String(o.className||"").split(/\s+/).some(i=>/^mtk\d+$/.test(i)&&i!=="mtk1"))).length>0}function Qn(){const e=ae.value;return e?.lineNumbers!=="off"}function Xn(){var e,t;m.value?Ze.value=vn(String((e=r.node.originalCode)!=null?e:""),String((t=r.node.updatedCode)!=null?t:"")):Ze.value={removed:0,added:0}}function lt(){var e;if(m.value)try{const t=V(),n=(e=t?.getLineChanges)==null?void 0:e.call(t);if(!Array.isArray(n))return void Xn();let l=0,o=0;for(const i of n)l+=Al(i.originalStartLineNumber,i.originalEndLineNumber),o+=Al(i.modifiedStartLineNumber,i.modifiedEndLineNumber);Ze.value={removed:l,added:o}}catch{Xn()}else Ze.value={removed:0,added:0}}function Kn(){var e;if(Number.isFinite(W.value)&&W.value>0&&Number.isFinite(pe.value))return W.value;const t=Gn();return typeof((e=r.monacoOptions)==null?void 0:e.fontSize)=="number"?(pe.value=r.monacoOptions.fontSize,W.value=r.monacoOptions.fontSize,W.value):t&&t>0?(pe.value=t,W.value=t,t):(pe.value=12,W.value=12,12)}function ei(){const e=Kn(),t=Math.min(36,e+1);W.value=t}function ti(){const e=Kn(),t=Math.max(10,e-1);W.value=t}function ni(){Kn(),Number.isFinite(pe.value)&&(W.value=pe.value)}function Jl(){var e,t,n,l,o,i,s,u,a,c,d,f,p,h;try{const x=m.value?V():null,g=m.value?x:de();if(!g)return null;if(x?.getOriginalEditor&&x?.getModifiedEditor){const F=(e=x.getOriginalEditor)==null?void 0:e.call(x),S=(t=x.getModifiedEditor)==null?void 0:t.call(x);(n=F?.layout)==null||n.call(F),(l=S?.layout)==null||l.call(S);const D=((o=F?.getContentHeight)==null?void 0:o.call(F))||0,C=((i=S?.getContentHeight)==null?void 0:i.call(S))||0,L=Math.max(D,C);if(L>0)return Math.ceil(L);const K=((a=(u=(s=F?.getModel)==null?void 0:s.call(F))==null?void 0:u.getLineCount)==null?void 0:a.call(u))||1,_=((f=(d=(c=S?.getModel)==null?void 0:c.call(S))==null?void 0:d.getLineCount)==null?void 0:f.call(d))||1,O=Math.max(K,_),I=Math.max(Ct(F),Ct(S)),G=Math.max(fn(F),fn(S));return Math.ceil(O*I+G+0)}if(g?.getContentHeight){(p=g?.layout)==null||p.call(g);const F=g.getContentHeight();if(F>0)return m.value||(tn.value=!0),Math.ceil(F)}const N=(h=g?.getModel)==null?void 0:h.call(g);let oe=1;N&&typeof N.getLineCount=="function"&&(oe=N.getLineCount());const E=Ct(g);return Math.ceil(oe*(E+1.5)+0)}catch{return null}}function Yl(){var e,t;if(m.value)return!1;try{const n=(t=(e=de())==null?void 0:e.getContentHeight)==null?void 0:t.call(e),l=typeof n=="number"&&Number.isFinite(n)&&n>0;return l&&(tn.value=!0),l}catch{return!1}}function Zn(e){var t,n,l;if(typeof window>"u")return null;try{const o=e.getBoundingClientRect(),i=window.getComputedStyle(e);if(i.display==="none"||i.visibility==="hidden")return null;const s=e.querySelector("diffs-container");if(s instanceof HTMLElement){const c=s.getBoundingClientRect();if(c.height>0&&c.bottom>o.top)return Math.ceil(c.bottom-o.top)}const u=[".editor.original .view-lines .view-line",".editor.modified .view-lines .view-line",".editor.original .view-zones > div",".editor.modified .view-zones > div",".editor.original .margin-view-zones > div",".editor.modified .margin-view-zones > div",".editor.original .diff-hidden-lines",".editor.modified .diff-hidden-lines",".stream-monaco-diff-unchanged-bridge"];let a=0;for(const c of Array.from(e.querySelectorAll(u.join(",")))){if(!(c instanceof HTMLElement)||((t=c.parentElement)!=null&&t.classList.contains("view-zones")||(n=c.parentElement)!=null&&n.classList.contains("margin-view-zones"))&&!((l=c.textContent)!=null&&l.trim()||c.matches(".line-delete, .line-insert, .cdr")||c.querySelector(".diff-hidden-lines, .stream-monaco-diff-unchanged-bridge, .line-delete, .line-insert, .cdr")))continue;const d=window.getComputedStyle(c);if(d.display==="none"||d.visibility==="hidden"||Number.parseFloat(d.opacity||"1")<=.01)continue;const f=c.getBoundingClientRect();f.height<=0||f.bottom<=o.top||(a=Math.max(a,f.bottom-o.top))}return a>0?Math.ceil(a):null}catch{return null}}function Tt(e){if(typeof window>"u")return!1;const t=e.getBoundingClientRect();if(t.width<=0||t.height<=0)return!1;const n=e.querySelectorAll(".editor.modified .diff-hidden-lines, .editor.original .diff-hidden-lines, .stream-monaco-diff-unchanged-bridge");for(const l of Array.from(n)){if(!(l instanceof HTMLElement))continue;const o=window.getComputedStyle(l);if(o.display==="none"||o.visibility==="hidden"||Number.parseFloat(o.opacity||"1")<=.01)continue;const i=l.getBoundingClientRect();if(!(i.width<=0||i.height<=0||i.bottom<=t.top||i.top>=t.bottom))return!0}return!1}function el(e){var t;const n=String(e??"").trim(),l=(t=n.match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i))==null?void 0:t[1];if(l){const a=l.length===3?l.split("").map(c=>`${c}${c}`).join(""):l;return .2126*Number.parseInt(a.slice(0,2),16)+.7152*Number.parseInt(a.slice(2,4),16)+.0722*Number.parseInt(a.slice(4,6),16)}const o=n.match(/\d+(?:\.\d+)?/g);if(!o||o.length<3)return null;const[i,s,u]=o.slice(0,3).map(Number);return .2126*i+.7152*s+.0722*u}function Rt(){var e,t,n;if(Ql())return;const l=Gn();l&&l>0&&(_n.value=l,W.value=l,pe.value=l);try{const o=Ct(m.value?(n=(t=(e=V())==null?void 0:e.getModifiedEditor)==null?void 0:t.call(e))!=null?n:V():de());o&&o>0&&(ln.value=o)}catch{}try{const o=Dl();o&&o>0&&(ln.value=o)}catch{}}function Ql(){return m.value&&Bl.value}function tl(){var e;if(!m.value||!Te.value)return null;const t=v.value,n=(e=z.value)==null?void 0:e.querySelector("pre.code-pre-fallback");if(!t||!n)return null;const l=Math.ceil(n.getBoundingClientRect().height);return!Number.isFinite(l)||l<=0?null:(t.style.height=`${l}px`,t.style.minHeight=`${l}px`,t.style.maxHeight=`${Math.ceil(Mt())}px`,t.style.overflow="hidden",l)}function nl(){var e,t,n,l,o,i,s,u,a;const c=v.value,d=z.value;if(!c||!d)return;const f=c;f.style.setProperty("--diffs-tab-size",String(Fl.value));const p=(e=r.monacoOptions)==null?void 0:e.padding;p&&typeof p=="object"?f.style.setProperty("--diffs-gap-block",`${un.value.top}px`):f.style.removeProperty("--diffs-gap-block");const h=c.querySelector(".monaco-editor")||c,x=h.querySelector(".monaco-editor-background")||h,g=h.querySelector(".view-lines")||h;let N=null,oe=null,E=null;try{typeof window<"u"&&typeof window.getComputedStyle=="function"&&(N=window.getComputedStyle(h),oe=x===h?N:window.getComputedStyle(x),E=g===h?N:window.getComputedStyle(g))}catch{N=null,oe=null,E=null}const F=String((t=N?.getPropertyValue("--vscode-editor-foreground"))!=null?t:"").trim(),S=String((n=N?.getPropertyValue("--vscode-editor-background"))!=null?n:"").trim(),D=String((o=(l=N?.getPropertyValue("--vscode-editor-selectionBackground"))!=null?l:N?.getPropertyValue("--vscode-editor-hoverHighlightBackground"))!=null?o:"").trim(),C=F||String((s=(i=E?.color)!=null?i:N?.color)!=null?s:"").trim(),L=S||String((a=(u=oe?.backgroundColor)!=null?u:N?.backgroundColor)!=null?a:"").trim(),K=(function(){var _,O,I,G,ye;try{const st=m.value?(I=(O=(_=V())==null?void 0:_.getModifiedEditor)==null?void 0:O.call(_))!=null?I:V():de(),jt=xt(),Et=(G=jt?.EditorOption)==null?void 0:G.fontInfo;if(st&&Et!=null){const qt=(ye=st.getOption)==null?void 0:ye.call(st,Et),dt=qt?.typicalHalfwidthCharacterWidth;if(typeof dt=="number"&&Number.isFinite(dt)&&dt>0)return dt}}catch{}return null})();if(K!=null&&(on.value=K),m.value){const _=(O,I)=>{I?(d.style.setProperty(O,I),f.style.setProperty(O,I)):(d.style.removeProperty(O),f.style.removeProperty(O))};for(const[O,I]of Object.entries(Ol(d.classList.contains("is-dark"))))_(O,I);return C?(d.style.setProperty("--markstream-diff-editor-fg",C),f.style.setProperty("--vscode-editor-foreground",C),f.style.setProperty("--stream-monaco-editor-fg",C)):(d.style.removeProperty("--markstream-diff-editor-fg"),f.style.removeProperty("--vscode-editor-foreground"),f.style.removeProperty("--stream-monaco-editor-fg")),L?(d.style.setProperty("--markstream-diff-editor-bg",L),d.style.setProperty("--markstream-diff-panel-bg",L),d.style.setProperty("--markstream-diff-panel-bg-soft",L),d.style.setProperty("--markstream-diff-panel-bg-strong",L),f.style.setProperty("--vscode-editor-background",L),f.style.setProperty("--stream-monaco-editor-bg",L),f.style.setProperty("--stream-monaco-fixed-editor-bg",L),f.style.setProperty("--stream-monaco-panel-bg",L),f.style.setProperty("--stream-monaco-panel-bg-soft",L),f.style.setProperty("--stream-monaco-panel-bg-strong",L),f.style.backgroundColor=L):(d.style.removeProperty("--markstream-diff-editor-bg"),d.style.removeProperty("--markstream-diff-panel-bg"),d.style.removeProperty("--markstream-diff-panel-bg-soft"),d.style.removeProperty("--markstream-diff-panel-bg-strong"),f.style.removeProperty("--vscode-editor-background"),f.style.removeProperty("--stream-monaco-editor-bg"),f.style.removeProperty("--stream-monaco-fixed-editor-bg"),f.style.removeProperty("--stream-monaco-panel-bg"),f.style.removeProperty("--stream-monaco-panel-bg-soft"),f.style.removeProperty("--stream-monaco-panel-bg-strong"),f.style.backgroundColor=""),void(D?f.style.setProperty("--vscode-editor-selectionBackground",D):f.style.removeProperty("--vscode-editor-selectionBackground"))}if((function(_,O,I){if(!Mn.value)return!1;const G=el(_),ye=el(O);return I?G!=null&&G>170||ye!=null&&ye<110:G!=null&&G<85||ye!=null&&ye>190})(L,C,d.classList.contains("is-dark")))return f.style.removeProperty("--vscode-editor-foreground"),f.style.removeProperty("--vscode-editor-background"),void f.style.removeProperty("--vscode-editor-selectionBackground");C&&f.style.setProperty("--vscode-editor-foreground",C),L&&f.style.setProperty("--vscode-editor-background",L),D&&f.style.setProperty("--vscode-editor-selectionBackground",D)}let ll=0,ol=0;const Xl=/auto|scroll|overlay/i;function Oe(e,t,n){var l;if(typeof window>"u"||m.value||(function(d){return _o.value||Ml(d)})(e))return;const o=Math.ceil(t),i=Math.ceil(n)-o;if(Math.abs(i)<=1)return;const s=(function(d){var f,p;if(typeof window>"u")return null;const h=(f=d?.ownerDocument)!=null?f:document,x=h.scrollingElement||h.documentElement||h.body;let g=(p=d?.parentElement)!=null?p:null;for(;g&&g!==h.body&&g!==x;){const N=window.getComputedStyle(g),oe=(N.overflowY||"").toLowerCase(),E=(N.overflow||"").toLowerCase();if(Xl.test(oe)||Xl.test(E))return g;g=g.parentElement}return x})(e);if(!s)return;const u=(l=e.ownerDocument)!=null?l:document,a=s===u.body||s===u.documentElement||s===u.scrollingElement,c=a?0:s.getBoundingClientRect().top;e.getBoundingClientRect().top-c>=0||(a&&typeof window.scrollBy=="function"?window.scrollBy(0,i):s.scrollTop+=i)}function il(){try{const e=v.value;if(!e)return;const t=e.getBoundingClientRect().height,n=Jl();if(n!=null&&n>0){const o=Rl(n,!0,{allowBelowEstimatedFloor:!m.value&&q.value&&Yl()}),i=nt();return e.style.minHeight=i!=null?`${i}px`:"0px",e.style.height=`${o}px`,e.style.maxHeight="none",e.style.overflow="visible",void Oe(e,t,o)}const l=nt();l!=null&&(e.style.minHeight=`${l}px`,e.style.height=`${l}px`,e.style.maxHeight="none",e.style.overflow="visible",Oe(e,t,l))}catch{}}function ot(){for(var e,t;He.length>0;)try{(t=(e=He.pop())==null?void 0:e.dispose)==null||t.call(e)}catch{}kt!=null&&(kn(kt),kt=null),Ft!=null&&(kn(Ft),Ft=null),Je!=null&&(kn(Je),Je=null),Ye=0,Qe=!1}function De(){for(var e;Nn.length>0;)try{(e=Nn.pop())==null||e()}catch{}}function le(e=!1){Se.value||(Pe.value?il():(function(t={}){var n,l,o;try{const i=v.value;if(!i)return;const s=i.getBoundingClientRect().height,u=Mt(),a=Math.ceil(((n=i.getBoundingClientRect)==null?void 0:n.call(i).height)||0),c=Number.parseFloat(i.style.height||""),d=a>0?a:Number.isFinite(c)&&c>0?Math.ceil(c):0,f=m.value?(function(){var O,I,G,ye,st,jt,Et,qt,dt,xo,So,Co;if($e())return null;try{const ct=V(),ft=(O=ct?.getOriginalEditor)==null?void 0:O.call(ct),vt=(I=ct?.getModifiedEditor)==null?void 0:I.call(ct);if(!ft||!vt)return null;const hi=((st=(ye=(G=ft.getModel)==null?void 0:G.call(ft))==null?void 0:ye.getLineCount)==null?void 0:st.call(ye))||1,gi=((qt=(Et=(jt=vt.getModel)==null?void 0:jt.call(vt))==null?void 0:Et.getLineCount)==null?void 0:qt.call(Et))||1,yi=Math.max(hi,gi),wi=Math.max(Ct(ft),Ct(vt)),bi=Math.max(fn(ft),fn(vt)),ki=Math.max((xo=(dt=ft.getContentHeight)==null?void 0:dt.call(ft))!=null?xo:0,(Co=(So=vt.getContentHeight)==null?void 0:So.call(vt))!=null?Co:0);return Math.ceil(Math.max(ki,yi*wi+bi+0))}catch{return null}})():null,p=m.value&&Tt(i),h=m.value&&mn(i),x=m.value&&i.classList.contains("stream-monaco-diff-native-stale"),g=p&&q.value&&R.value&&!Te.value;if(p||(ve.value=null),En>0&&(En--,_e.value!=null))return void Oe(i,s,Ae(i,_e.value,u,{allowBelowEstimatedFloor:g,preserveScrollableOverflow:rl(i)}));if(m.value&&!h&&!p&&Te.value){const O=tl();if(O!=null){const I=Ae(i,O,u,{allowBelowEstimatedFloor:!0});return ee(!0),void Oe(i,s,I)}}const N=m.value&&t.preferModelDiffHeight===!0,oe=m.value?Zn(i):null,E=oe,F=!m.value&&q.value&&Yl(),S=m.value&&r.loading!==!1&&(E!=null||f!=null&&a>0&&f<a-1),D=f!=null&&!g;let C;if(m.value)if(N){const O=f!=null&&r.loading===!1&&d>0&&f<d-1;C=r.loading===!1&&E!=null?p||f==null?E:Math.max(E,f):O?f:E!=null&&f!=null?Math.max(E,f,r.loading!==!1?d:0):Math.max(E??0,f??0,r.loading!==!1?d:0)||null}else C=p?oe:Ue.value&&E!=null||E!=null?D?Math.max(E,f):E:m.value&&r.loading!==!1?f!=null&&d>0&&f<d-1?f:d>0?d:null:f;else C=Jl();if(m.value&&r.loading===!1&&x&&!g&&C!=null&&f!=null&&(C=Math.min(C,f)),m.value&&C!=null&&d>0&&(r.loading!==!1||r.loading===!1&&x&&!g||t.holdCurrentDiffHeight===!0&&!g)&&(C=Math.max(C,d)),C!=null&&C>0){const O=p&&ve.value!=null,I=p&&a>0&&a<u-1&&C>=u-1,G=Ae(i,O?Math.max(ve.value,C):I?a:C,u,{clearEstimatedFloor:!0,allowBelowEstimatedFloor:g||F||S,preserveScrollableOverflow:rl(i)});return p&&G<u-1&&(ve.value=Math.max((l=ve.value)!=null?l:0,G)),al(i),void Oe(i,s,G)}if(_e.value!=null)return void Oe(i,s,Ae(i,_e.value,u,{allowBelowEstimatedFloor:g,preserveScrollableOverflow:rl(i)}));const L=m.value&&r.loading!==!1||p?a:Math.max(a,f!=null&&f>0?f:0);if(L>0){const O=p&&ve.value!=null,I=p&&a>0&&a<u-1&&L>=u-1,G=Ae(i,O?Math.max(ve.value,L):I?a:L,u,{allowBelowEstimatedFloor:g});return p&&G<u-1&&(ve.value=Math.max((o=ve.value)!=null?o:0,G)),al(i),void Oe(i,s,G)}const K=nt();if(!(K==null||m.value&&r.loading!==!1&&h))return void Oe(i,s,Ae(i,K,u,{allowBelowEstimatedFloor:g}));const _=Number.parseFloat(i.style.height);!Number.isNaN(_)&&_>0?Oe(i,s,Ae(i,_,u,{allowBelowEstimatedFloor:g})):m.value||Oe(i,s,Ae(i,u,u))}catch{}})(typeof e=="object"?e:{}))}function Kl(){ll=0,ol=0}function ee(e=!1){var t,n,l;if(Se.value)return;const o=v.value;if(!o)return;const i=m.value?V():de();if(i&&typeof i.layout=="function")try{const s=(t=o.getBoundingClientRect)==null?void 0:t.call(o),u=Math.ceil(((n=s?.width)!=null?n:0)||o.clientWidth||0),a=Math.ceil(((l=s?.height)!=null?l:0)||o.clientHeight||Number.parseFloat(o.style.height||"")||0);if(u>0&&a>0){if(!e&&u===ll&&a===ol)return;ll=u,ol=a,i.layout({width:u,height:a})}else Kl(),i.layout()}catch{}}function he(){if(!m.value)return void De();const e=v.value;if(!e)return void De();const t=e.querySelector(".monaco-diff-editor");if(!t||t.classList.contains("side-by-side"))return void De();const n=Array.from(t.querySelectorAll(".editor.original .diff-hidden-lines")),l=Array.from(t.querySelectorAll(".editor.modified .diff-hidden-lines")),o=Math.min(n.length,l.length);for(let i=0;i<o;i++){const s=l[i],u=s.querySelector("a"),a=s.querySelector(".center > div:first-child"),c=s.querySelector(".center");if(!u||!a||!c||c.querySelector(".markstream-inline-fold-proxy"))continue;const d=document.createElement("button");d.type="button",d.className="markstream-inline-fold-proxy",d.dataset.markstreamInlineFoldProxy="true";const f=u.getAttribute("title")||"Show Unchanged Region";d.title=f,d.setAttribute("aria-label",f);const p=g=>{g.preventDefault(),g.stopPropagation()},h=g=>{g.preventDefault(),g.stopPropagation(),u.click(),fe(()=>ce())},x=g=>{g.key!=="Enter"&&g.key!==" "||(g.preventDefault(),g.stopPropagation(),u.click(),fe(()=>ce()))};d.addEventListener("mousedown",p),d.addEventListener("click",h),d.addEventListener("keydown",x),c.appendChild(d),Nn.push(()=>{d.removeEventListener("mousedown",p),d.removeEventListener("click",h),d.removeEventListener("keydown",x),d.parentElement===c&&c.removeChild(d)})}}function ce(e=!1){if(B||kt!=null)return;const t=()=>{B||(he(),le(e),ee())};kt=fe(()=>{kt=null,t(),Ft=fe(()=>{Ft=null,t()})}),it()}function it(e=!1){if(!m.value||B||!e&&r.loading===!1||(Qe=Qe||e,Ye=Math.max(Ye,e?18:6),Je!=null))return;const t=()=>{if(Je=null,!m.value||B||Ye<=0||!Qe&&r.loading===!1)return Ye=0,void(Qe=!1);Ye--,he(),le({preferModelDiffHeight:!0,holdCurrentDiffHeight:Qe}),ee(),Ye>0?Je=fe(t):Qe=!1};Je=fe(t)}function Ae(e,t,n,l={}){const o=m.value&&r.loading!==!1?Zn(e):null,i=o!=null&&o>t+1?o:t,s=Math.min(i,n),u=l.allowBelowEstimatedFloor===!0||Tl(),a=Rl(s,l.clearEstimatedFloor===!0,{allowBelowEstimatedFloor:u}),c=nt();if(e.style.minHeight=c==null||u?"0px":`${Math.min(c,Math.ceil(n))}px`,e.style.height=`${a}px`,e.style.maxHeight=`${Math.ceil(n)}px`,m.value)e.style.overflow="hidden";else{const d=l.preserveScrollableOverflow===!0||t>n+1;e.style.overflow=d?"auto":"hidden"}return a}function Zl(e,t=0){var n;const l=Math.ceil(((n=e.getBoundingClientRect)==null?void 0:n.call(e).height)||0),o=Math.max(t,e.clientHeight||0,l);return o>0&&e.scrollHeight>o+1}function rl(e){var t;return!m.value&&(Fn||Zl(e,(t=_e.value)!=null?t:0))}function al(e){var t,n,l,o,i,s,u,a;if(!m.value)return;const c=Pe.value||!Tt(e)||e.getBoundingClientRect().height>=Mt()-1;if(Bn===c)return;Bn=c;const d=Me(U({},(n=(t=r.monacoOptions)==null?void 0:t.scrollbar)!=null?n:{}),{handleMouseWheel:c}),f=V();try{(i=(o=(l=f?.getOriginalEditor)==null?void 0:l.call(f))==null?void 0:o.updateOptions)==null||i.call(o,{scrollbar:d}),(a=(u=(s=f?.getModifiedEditor)==null?void 0:s.call(f))==null?void 0:u.updateOptions)==null||a.call(u,{scrollbar:d})}catch{}}function mn(e=v.value){return!!$e(e)||!!e?.querySelector(".monaco-diff-editor .view-lines .view-line")}function eo(e=v.value){return!!$e(e)||!!e?.querySelector(".monaco-editor .view-lines .view-line")}function to(){var e,t;if($e())return!0;const n=(t=(e=de())==null?void 0:e.getModel)==null?void 0:t.call(e);return typeof n?.getValue=="function"&&n.getValue()===Re.value}function no(e=v.value){return!!$e(e)||!!e?.classList.contains("stream-monaco-diff-root")&&!(Ue.value&&!e.classList.contains("stream-monaco-diff-inline"))}function $e(e=v.value){return!!e?.querySelector("diffs-container")}function lo(e){return r.loading!==!1||R.value||e.classList.contains("stream-monaco-diff-native-stale")||Tt(e)}function li(){const e=V();return typeof e?.getOriginalEditor=="function"||typeof e?.getModifiedEditor=="function"||typeof e?.getLineChanges=="function"}function oo(){return j(this,arguments,function*(e={}){var t,n,l;if(!m.value)return!0;if($e())return yield A(),yield Le(),$e();const o=e.requireHighlight!==!1;let i=0,s=Ot(String((t=r.node.originalCode)!=null?t:""),String((n=r.node.updatedCode)!=null?n:"")),u=vn(s.original,s.updated),a=u.added>0||u.removed>0;const c=()=>{var d,f;const p=Ot(String((d=r.node.originalCode)!=null?d:""),String((f=r.node.updatedCode)!=null?f:""));p.original===s.original&&p.updated===s.updated||(s=p,u=vn(s.original,s.updated),a=u.added>0||u.removed>0)};for(let d=0;d<30;d++){if(B)return!1;c();const f=v.value,p=V(),h=Qn();let x=!1;try{const S=(l=p?.getLineChanges)==null?void 0:l.call(p);x=Array.isArray(S)&&(!a||S.length>0)}catch{x=!1}const g=!!f?.querySelector(".monaco-diff-editor"),N=mn(f),oe=!a||Wl(f,u),E=!a||Il(f,u),F=!h||Ul(f);if(g&&N&&x&&oe&&E&&F&&ql(f)){try{St(),he(),lt(),ce()}catch{}if(yield A(),yield Le(),B)return!1;const S=v.value,D=!Qn()||Ul(S),C=!a||Wl(S,u),L=!a||Il(S,u),K=Ko(S,a),_=Zo(S,u),O=!o||Yn(S),I=no(S)&&D&&Vl(S)&&C&&L&&K&&_&&O,G=no(S)&&D&&Vl(S)&&C&&L&&ql(S)&&O;if(I||G){if(i++,i>=2)return!0}else i=0}yield A(),yield Le()}return B||(St(),he(),lt(),ce(),c()),!1})}function io(e,t,n){return j(this,null,function*(){try{return void(yield Kt(e,t,n))}catch(l){if(!$t(l))throw l}if(yield A(),yield Le(),!B&&m.value)try{yield Kt(e,t,n)}catch(l){if(!$t(l))throw l}})}function Mt(){var e,t;const n=(t=(e=r.monacoOptions)==null?void 0:e.MAX_HEIGHT)!=null?t:500;if(typeof n=="number")return n;const l=String(n).match(/^(\d+(?:\.\d+)?)/);return l?Number.parseFloat(l[1]):500}const ul=b(()=>r.isShowPreview&&(xe.value==="html"||xe.value==="svg"));function Ve(){return typeof r.node.loading=="boolean"?r.node.loading:r.loading===!0}function ro(){var e,t,n;if(!Ve())return!0;const l=String((e=r.node.raw)!=null?e:""),o=(n=(t=l.split(/\r\n|\n|\r/,1)[0])==null?void 0:t.trimStart())!=null?n:"";return!/^(?:`{3,}|~{3,})/.test(o)||/\r\n|\n|\r/.test(l)}function ao(e,t,n){return!n||ro()&&String(t??"")?wn(String(e??"")):"plain"}function pn(){return Ve()}let Bt=null,sl=!1,hn=0;function uo(){Bt=null,hn++}function so(){return j(this,arguments,function*(e=hn){if(!sl){sl=!0;try{for(;Bt&&!B&&!m.value&&e===hn;){const t=Bt;Bt=null;try{yield Promise.resolve(Ln(t.code,t.language)),yield A(),B||m.value||(le(!1),ee())}catch{}}}finally{sl=!1,!Bt||B||m.value||so()}}})}function co(e,t){Bt={code:e,language:t},so(hn)}ue(()=>[r.node.language,r.node.code,r.node.raw,r.node.loading,r.loading],([e,t,n,l,o])=>{xe.value=ao(e,t,typeof l=="boolean"?l:o===!0)}),ue(()=>[r.node.originalCode,r.node.updatedCode,m.value],()=>{ve.value=null,Xn(),fe(()=>lt())},{immediate:!0});let gn=0;ue(()=>[r.node.originalCode,r.node.updatedCode,Fe.value,m.value,r.stream],e=>j(null,[e],function*([,,,t,n]){var l,o;const i=++gn;if(!t||Ve()||n===!1&&!X.value)return;if(n!==!1&&se&&!X.value&&v.value)try{yield je(v.value)}catch{}const s=Pt;if(s&&!Ce.value){try{yield s}catch{}if(B||!m.value||i!==gn)return}if(i!==gn)return;const u=Ot(String((l=r.node.originalCode)!=null?l:""),String((o=r.node.updatedCode)!=null?o:"")),a=r.loading===!1;a&&at();try{if(yield io(u.original,u.updated,Fe.value),B||!m.value||i!==gn)return;yield A(),ee(!0),he(),le(r.loading===!1||{preferModelDiffHeight:!0}),ee(!0),ce(!0)}catch{return}if(a){if(B||!m.value)return;St(),he(),lt(),ce(),it(!0)}Pe.value&&fe(()=>il())})),ue(()=>r.node.code,e=>j(null,null,function*(){if(Ve()||r.stream===!1||(xe.value||(xe.value=wn(wl(e))),m.value))return;const t=Pt;if(t&&!Ce.value){try{yield t}catch{}if(B||m.value)return}if(se&&!X.value&&v.value)try{yield je(v.value)}catch{}co(en(r.node.code),Fe.value),Pe.value&&fe(()=>il())}));const oi=b(()=>{const e=xe.value;return e?Fo[e]||e.charAt(0).toUpperCase()+e.slice(1):Fo[""]}),fo=b(()=>{var e;return Ai(String((e=r.node.raw)!=null?e:""),oi.value,m.value)}),ii=b(()=>fo.value.title),vo=b(()=>fo.value.caption),ri=b(()=>(Hi.value,(function(e,t){if(t===void 0)return Ni(e);if(t){const l=t(e);if(l!=null&&l!=="")return l}const n=wn(e);return Ti(n)||Ri()})(xe.value||"",gt))),ai=b(()=>{const e={};e["--markstream-code-layout-character-width"]=on.value==null?"1ch":`${on.value}px`;const t=o=>{if(o!=null)return typeof o=="number"?`${o}px`:String(o)},n=t(r.minWidth),l=t(r.maxWidth);if(n&&(e.minWidth=n),l&&(e.maxWidth=l),zl.value&&!m.value&&!Se.value){const o=Qo.value;o!=null&&(e.minHeight=`${o}px`)}return m.value||(e.color="var(--markstream-code-fallback-fg, var(--code-fg))",e.backgroundColor="var(--markstream-code-fallback-bg, var(--code-bg))",e.borderColor="var(--markstream-code-border-color, var(--code-border))"),e}),ui=b(()=>r.showTooltips!==!1);function si(){return j(this,null,function*(){try{typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(r.node.code)),wt.value=!0,P("copy",r.node.code),setTimeout(()=>{wt.value=!1},1e3)}catch(e){console.error("复制失败:",e)}})}function di(){Pe.value=!Pe.value;const e=m.value?V():de(),t=v.value;e&&t&&(Pe.value?(yn(!0),t.style.maxHeight="none",t.style.overflow="visible",le(!0)):(yn(!1),t.style.overflow=m.value?"hidden":"auto",le(!0)),al(t))}function ci(){var e,t;if(Se.value=!Se.value,Se.value){if(Fn=!1,v.value){const n=Math.ceil(((t=(e=v.value).getBoundingClientRect)==null?void 0:t.call(e).height)||0);Fn=!m.value&&(Zl(v.value,n)||v.value.style.overflow==="auto"||v.value.style.overflowY==="auto"),n>0&&(_e.value=n)}yn(!1)}else Pe.value&&yn(!0),v.value&&_e.value!=null&&(v.value.style.height=`${_e.value}px`),En=2,A(()=>{Se.value||B||(le(!0),ee(!0))})}function fi(){if(!ul.value)return;const e=xe.value;if(Yt.value){const t=e==="html"?"text/html":"image/svg+xml",n=e==="html"?Q("artifacts.htmlPreviewTitle")||"HTML Preview":Q("artifacts.svgPreviewTitle")||"SVG Preview";return void P("previewCode",{node:r.node,artifactType:t,artifactTitle:n,id:`temp-${e}-${Date.now()}`})}e==="html"&&(nn.value=!nn.value)}function yn(e){var t,n;try{if(m.value){const l=V();(t=l?.updateOptions)==null||t.call(l,{automaticLayout:e})}else{const l=de();(n=l?.updateOptions)==null||n.call(l,{automaticLayout:e})}}catch{}}function vi(e){return j(this,null,function*(){var t;if(!se||B)return;const n=zt.value;if(jn=!1,me.value=!1,et.value=null,Ce.value=!1,R.value=!1,Ht.value=!1,Bn=null,_n.value=null,ln.value=null,on.value=null,(function(){const a=(function(){var c;const d=(c=v.value)==null?void 0:c.parentElement;return d instanceof HTMLElement?d:null})();a&&(a.style.removeProperty("--stream-monaco-line-number-left"),a.style.removeProperty("--stream-monaco-line-number-width"),a.style.removeProperty("--stream-monaco-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-original-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-modified-line-number-gap-to-code"),a.style.removeProperty("--stream-monaco-original-scrollable-left"),a.style.removeProperty("--stream-monaco-modified-scrollable-left"))})(),Kl(),(function(){tn.value=!1;const a=Ll.value;Un.value=q.value||a==null?null:a})(),ot(),De(),(function(a){a.replaceChildren()})(e),at(),B)return;const l=j(null,null,function*(){var a,c;if(n==="diff"){(function(){if(Hn||typeof window>"u")return;Hn=!0;const f=p=>{var h;$t("reason"in p?p.reason:(h=p.error)!=null?h:p.message)&&(p.preventDefault(),p.stopImmediatePropagation())};window.addEventListener("error",f,!0),window.addEventListener("unhandledrejection",f,!0),Zt=()=>{window.removeEventListener("error",f,!0),window.removeEventListener("unhandledrejection",f,!0),Hn=!1,Zt=null}})(),Xe();const d=Ot(String((a=r.node.originalCode)!=null?a:""),String((c=r.node.updatedCode)!=null?c:""));Xt?yield yt(()=>Xt(e,d.original,d.updated,Fe.value)):yield yt(()=>se(e,r.node.code,Fe.value))}else yield yt(()=>se(e,Re.value,Fe.value));Ce.value=!0}),o=l.finally(()=>{Pt===o&&(Pt=null)});if(Pt=o,yield(function(a){return j(this,null,function*(){if(!m.value)return void(yield a);let c,d=!1;for(a.then(()=>{d=!0},f=>{d=!0,c=f});;){if(B)return;if(d){if(c)throw c;return}if(mn()&&li())return;yield A(),yield Le()}})})(o),B||zt.value!==n)return;Ce.value=!0;const i=n==="diff"?V():de();if(typeof((t=r.monacoOptions)==null?void 0:t.fontSize)=="number")i?.updateOptions({fontSize:r.monacoOptions.fontSize,automaticLayout:!1}),pe.value=r.monacoOptions.fontSize,W.value=r.monacoOptions.fontSize;else if(!Ql()){const a=Gn();a&&a>0?(pe.value=a,W.value=a):(pe.value=12,W.value=12)}Rt(),yield go(),Pe.value||Se.value||le(!1),q.value=!0,Sl.value=n,(function(){var a,c,d,f,p;if(ot(),m.value){const x=V(),g=(a=x?.getOriginalEditor)==null?void 0:a.call(x),N=(c=x?.getModifiedEditor)==null?void 0:c.call(x),oe=(F,S)=>{try{const D=F?.[S];if(typeof D!="function")return;const C=D.call(F,()=>ce());C&&He.push(C)}catch{}};try{const F=(d=x?.onDidUpdateDiff)==null?void 0:d.call(x,()=>{ce(),fe(()=>lt())});F&&He.push(F)}catch{}oe(g,"onDidContentSizeChange"),oe(N,"onDidContentSizeChange");const E=v.value;if(E&&typeof MutationObserver<"u"){const F=[".view-line",".view-lines",".view-zones",".margin-view-zones",".diff-hidden-lines",".stream-monaco-diff-unchanged-bridge",".stream-monaco-fallback-inline-delete-zone",".stream-monaco-fallback-inline-delete-margin"].join(","),S=L=>{var K;const _=L instanceof HTMLElement?L:L.parentElement;return!!((K=_?.closest)!=null&&K.call(_,F))},D=L=>{var K,_;const O=L instanceof HTMLElement?L:L.parentElement;return!!((K=O?.closest)!=null&&K.call(O,F)||(_=O?.querySelector)!=null&&_.call(O,F))},C=new MutationObserver(L=>{m.value&&lo(E)&&L.some(K=>S(K.target)||Array.from(K.addedNodes).some(D)||Array.from(K.removedNodes).some(S))&&(he(),le({preferModelDiffHeight:!0}),ee(),it())});C.observe(E,{attributeFilter:["class"],attributes:!0,childList:!0,characterData:!0,subtree:!0}),He.push({dispose:()=>C.disconnect()})}if(E){const F=S=>{const D=S.target instanceof Element?S.target:null;if(!D?.closest([".stream-monaco-unchanged-summary",".stream-monaco-unchanged-reveal",".stream-monaco-unchanged-expand",".markstream-inline-fold-proxy",".diff-hidden-lines .center"].join(",")))return;const C=Math.ceil(E.getBoundingClientRect().height||0);C>0&&(ve.value=C)};E.addEventListener("click",F,!0),He.push({dispose:()=>E.removeEventListener("click",F,!0)})}if(E&&typeof ResizeObserver<"u"){const F=new ResizeObserver(()=>{if(!m.value||(ee(),!lo(E)))return;const S=Zn(E);if(S==null)return;const D=Math.ceil(E.getBoundingClientRect().height||0),C=ve.value;if(Tt(E)&&C!=null){if(D>C+1)ve.value=D;else if(D<C-1)return Ae(E,C,Mt()),void ee()}D<=S+1||(he(),le({preferModelDiffHeight:!0}),ee())});F.observe(E),He.push({dispose:()=>F.disconnect()})}return}const h=de();try{const x=(f=h?.onDidContentSizeChange)==null?void 0:f.call(h,()=>ce());x&&He.push(x)}catch{}try{const x=(p=h?.onDidLayoutChange)==null?void 0:p.call(h,()=>ce());x&&He.push(x)}catch{}})(),nl(),Rt(),he(),lt(),ce(),yield A();let s=null;Ke&&(s=yield Ke(),s&&(yield A(),yield Le()));const u=s??(n==="diff"?yield oo({requireHighlight:!0}):yield(function(){return j(this,null,function*(){if($e())return yield A(),yield Le(),$e();for(let a=0;a<30;a++){if(B||m.value)return!1;const c=v.value,d=to(),f=eo(c),p=!Re.value.trim()||Yn(c);if(d&&f&&p&&(yield A(),yield Le(),!B&&!m.value&&to()&&eo(v.value)&&(!Re.value.trim()||Yn(v.value))))return!0;yield A(),yield Le()}return!1})})());B||(u?(Rt(),cn(),(yield Nl())||qe()):qe())})}function je(e,t={}){if(!se||B||r.stream===!1&&r.loading!==!1||(cl(),ko())||ge.value||v.value!==e||pn())return null;if(ze)return ze;if(X.value&&q.value)return Promise.resolve();const n=dl(),l=Dn.value;let o=!1;X.value=!0,(function(){const s=Ge.value;re&&s&&We!==s&&(We&&re.markSettled(We),We=s,re.markPending(s))})();const i=j(null,null,function*(){try{yield vi(e),Nt=null}catch(s){const u=dl(),a=l!==Dn.value,c=t.allowStaleContentRetry!==!1&&a&&Nt!==u;if(n!==u||c)return c&&(Nt=u),o=!0,X.value=!1,q.value=!1,Ce.value=!1,void(R.value=!1);throw qe(n),s}}).finally(()=>{ze===i&&(ze=null),(function(){const s=We;re&&s&&(We="",A(()=>{var u,a;if(!B){const c=(a=(u=z.value)==null?void 0:u.offsetHeight)!=null?a:0;c>0&&re.reportHeight(s,c)}re.markSettled(s)}))})(),o&&!B&&queueMicrotask(()=>{var s;const u=v.value;u&&!B&&((s=je(u))==null||s.catch(a=>{q.value=!1,R.value=!1,qe()}))})});return ze=i,i}ue(ui,e=>{e||mt()}),ue(()=>W.value,(e,t)=>{const n=m.value?V():de();n&&typeof e=="number"&&Number.isFinite(e)&&e>0&&(n.updateOptions({fontSize:e}),Se.value||le(!0))},{flush:"post",immediate:!1});let mo=0;const mi=ue(()=>[v.value,m.value,r.stream,r.loading,bt.value,Z.value,r.node.language,r.node.raw,r.node.code,r.node.loading],e=>j(null,[e],function*([t,n,l,o,i,s]){const u=++mo;if(!t||!s||Ve()||tt||l===!1&&o!==!1||!se&&(yield(function(){return j(this,null,function*(){if(typeof window>"u"||B||bt.value||ge.value)return;if(Lt)return Lt;const c=j(null,null,function*(){try{const d=yield Ui();if(B)return;if(!d)return void(ge.value=!0);const f=d.useMonaco,p=d.detectLanguage;if(typeof p=="function"&&(wl=p),typeof f!="function")return;Ne=yo();const h=f(Ne);se=h.createEditor||se,Xt=h.createDiffEditor||Xt,Ln=h.updateCode||Ln,Kt=h.updateDiff||Kt,xt=h.getEditor||xt,de=h.getEditorView||de,V=h.getDiffEditorView||V,On=h.cleanupEditor||On,Xe=h.safeClean||h.cleanupEditor||Xe,$n=h.refreshDiffPresentation||$n,zn=h.setTheme||zn,Ke=h.whenVisualReady||null,bt.value=!0}catch{if(B)return;ge.value=!0}}).finally(()=>{Lt===c&&(Lt=null)});return Lt=c,c})})(),u!==mo||r.stream===!1&&r.loading!==!1||pn()||!Z.value||!se||ge.value||X.value||ko()||B||v.value!==t)||pn())return;const a=je(t);if(a){try{yield a}catch{q.value=!1,R.value=!1,qe()}q.value&&R.value&&mi()}}));function po(e){return!!e&&typeof e=="object"&&"light"in e&&"dark"in e}function rt(e){return typeof e=="string"?e:e&&typeof e=="object"&&"name"in e?String(e.name):null}function ho(e,t){if(e===t)return!0;const n=rt(e),l=rt(t);return!!n&&n===l}function Dt(){var e;const t=(function(){if(r.theme!==void 0){const a=r.theme;return po(a)?r.isDark?a.dark:a.light:a}return r.isDark?r.darkTheme:r.lightTheme})(),n=(e=ae.value)==null?void 0:e.theme,l=t??n;if(l!=null&&typeof l=="object")return l;const o=Array.isArray(r.themes)?r.themes:[];if(!o.length||l==null)return l;const i=rt(l),s=o.map(a=>rt(a)).filter(a=>!!a);if(!i||s.includes(i))return l;const u=rt(n);return n!=null&&u&&s.includes(u)?n:o[0]}function go(){return j(this,arguments,function*(e={}){at();const t=()=>{m.value&&St(),fe(()=>{nl(),ce()})};if(e.appearanceOnly)return void t();const n=Dt();if(n)try{yield zn(n),t()}catch{}else t()})}function At(e,t){if(typeof t!="string")return;const n=wn(t),l=Eo(n),o=["plain","objectivec","objectivecpp"].includes(n)?l:n;for(const i of[o,l])i&&!e.includes(i)&&e.push(i)}ue(zt,(e,t)=>j(null,null,function*(){if(e===t||me.value||tt||(uo(),!se||!v.value)||!X.value||r.stream===!1&&r.loading!==!1||!Z.value)return;const n=ze;if(n){try{yield n}catch{}if(B||!v.value)return}if(Sl.value!==e||!X.value||!q.value)try{q.value=!1,R.value=!1,X.value=!1,Ce.value=!1,ot(),De(),Xe(),yield A(),yield je(v.value)}catch{q.value=!1,R.value=!1,qe()}}));const pi=b(()=>{var e;const t=[],n=(e=ae.value)==null?void 0:e.languages;if(Array.isArray(n))for(const l of n)At(t,l);return ro()&&At(t,r.node.language),At(t,xe.value),At(t,Fe.value),At(t,"plaintext"),t});function yo(){const e=Me(U(Me(U({wordWrap:"on",wrappingIndent:"same",themes:r.themes},ae.value||{}),{languages:pi.value,stream:!1,fontSize:rn.value,lineHeight:an.value,theme:Dt(),disableFileHeader:!0}),m.value?{diffAppearance:Rn.value}:{}),{onThemeChange(){nl()}}),t=(function(){var l;const o=(l=ae.value)==null?void 0:l.fontFamily;return typeof o=="string"&&o.trim()?o.trim():m.value?(function(){var i;if(typeof window>"u")return;const s=(i=z.value)==null?void 0:i.querySelector("pre.code-pre-fallback");if(s)return window.getComputedStyle(s).fontFamily.trim()||void 0})():void 0})();t&&(e.fontFamily!=null||(e.fontFamily=t));const n=typeof e.unsafeCSS=="string"?e.unsafeCSS:"";if(e.unsafeCSS=`[data-file], [data-diff] { --diffs-min-number-column-width-default: 2ch !important; } -${n}`.trim(),m.value){e.wordWrap=qn.value?"on":"off";const l=(function(){var o,i;const s=Wn.value;if(s===!1||typeof s=="object"&&s.enabled===!1)return null;const u=typeof s=="object"?s:Wt,a=Math.max(0,Math.floor((o=u.contextLineCount)!=null?o:2));return{contextLineCount:a,collapsedContextThreshold:a+Math.max(1,Math.floor((i=u.minimumLineCount)!=null?i:4))-1}})();e.unsafeCSS+=` -pre { column-gap: 0; } -pre > code { column-gap: 0; padding-block: 0; } -[data-separator="line-info"] { margin-top: 0; } -`,l?(e.parseDiffOptions=Me(U({},e.parseDiffOptions),{context:l.contextLineCount}),e.collapsedContextThreshold=l.collapsedContextThreshold,e.expandUnchanged=!1,e.hunkSeparators="line-info",e.unsafeCSS+=`[data-separator="line-info"][data-separator-last] { height: 28px; } -`):(e.expandUnchanged=!0,e.hunkSeparators="simple")}return e}function at(){const e=yo();if(!Ne)return Ne=e,Ne;for(const t of Object.keys(Ne))t in e||delete Ne[t];return Object.assign(Ne,e),Ne}const wo=b(()=>{var e,t,n,l,o,i,s,u,a,c,d,f,p,h,x;return JSON.stringify({diffLineStyle:(t=(e=ae.value)==null?void 0:e.diffLineStyle)!=null?t:"background",diffUnchangedRegionStyle:(l=(n=ae.value)==null?void 0:n.diffUnchangedRegionStyle)!=null?l:"line-info",diffHideUnchangedRegions:((o=r.monacoOptions)==null?void 0:o.diffHideUnchangedRegions)===void 0?U({},Wt):bn(r.monacoOptions.diffHideUnchangedRegions),renderSideBySide:(s=(i=ae.value)==null?void 0:i.renderSideBySide)==null||s,useInlineViewWhenSpaceIsLimited:(a=(u=ae.value)==null?void 0:u.useInlineViewWhenSpaceIsLimited)!=null&&a,enableSplitViewResizing:(d=(c=ae.value)==null?void 0:c.enableSplitViewResizing)==null||d,ignoreTrimWhitespace:(p=(f=ae.value)==null?void 0:f.ignoreTrimWhitespace)==null||p,originalEditable:(x=(h=ae.value)==null?void 0:h.originalEditable)!=null&&x})}),bo=$(0);function dl(){var e;const t=Dt();return JSON.stringify({kind:zt.value,language:Fe.value,structural:wo.value,optionsRevision:bo.value,settledContentGeneration:Cl.value,theme:(e=rt(t))!=null?e:t==null?null:"custom",isDark:r.isDark})}ue(()=>[r.monacoOptions,r.theme,r.themes,r.lightTheme,r.darkTheme],()=>{bo.value+=1},{deep:!0}),ue(()=>[Re.value,r.node.originalCode,r.node.updatedCode],()=>{Dn.value+=1,Ve()||(Cl.value+=1)});const ut=b(()=>dl());function cl(){me.value&&et.value!==ut.value&&(me.value=!1,et.value=null,Nt=null,An=null,X.value=!1,q.value=!1,Ce.value=!1,R.value=!1,Ht.value=!1)}function ko(){return cl(),me.value&&et.value===ut.value}function qe(e=ut.value){et.value=e,me.value=!0,Ht.value=!1}return ue(ut,()=>j(null,null,function*(){if(tt||!me.value||et.value===ut.value||!se||!v.value||ge.value||B||!Z.value||r.stream===!1&&r.loading!==!1||pn())return;const e=ut.value;tt=!0;try{if(cl(),me.value)return;yield je(v.value)}catch{q.value=!1,R.value=!1,qe()}finally{An=e,yield A(),tt=!1}})),ue(()=>[r.monacoOptions,Z.value],()=>{var e,t;if(at(),!se||!Z.value)return;const n=m.value?V():de(),l=typeof((e=r.monacoOptions)==null?void 0:e.fontSize)=="number"?r.monacoOptions.fontSize:Number.isFinite(W.value)?W.value:void 0;typeof l=="number"&&Number.isFinite(l)&&l>0&&((t=n?.updateOptions)==null||t.call(n,{fontSize:l})),le(!1)},{deep:!0}),ue(()=>[Dt(),Rn.value,bt.value,X.value,Z.value],([e],t)=>{bt.value&&q.value&&Z.value&&go({appearanceOnly:t!=null&&ho(e,t[0])})},{flush:"post"}),ue(()=>[wo.value,bt.value,Z.value],(e,t)=>j(null,[e,t],function*([n,l,o],[i]){if(at(),!l||!o||!se||!v.value||!X.value||n===i||r.stream===!1&&r.loading!==!1)return;const s=ze;if(s){try{yield s}catch{}if(B||!v.value)return}try{q.value=!1,R.value=!1,X.value=!1,Ce.value=!1,ot(),De(),Xe(),yield A(),yield je(v.value,{allowStaleContentRetry:!1})}catch{q.value=!1,R.value=!1,qe()}}),{flush:"post"}),ue(()=>[r.loading,Z.value],(e,t)=>j(null,[e,t],function*([n,l],o){if(!l)return;const i=o?.[0];if(i===!1&&n!==!1&&m.value&&X.value&&(yield A(),fe(()=>{j(null,null,function*(){const u=ze;if(u)try{yield u}catch{}!B&&m.value&&r.loading!==!1&&(at(),St(),ce())})})),n)return;const s=i!==void 0&&i!==!1;yield A(),fe(()=>{j(null,null,function*(){var u,a;try{if(s&&(yield(function(){return j(this,null,function*(){if(!me.value||!se||!v.value||ge.value||B||!Z.value)return!1;if(An===ut.value)return!0;tt=!0;try{me.value=!1,et.value=null,Nt=null,X.value=!1,q.value=!1,Ce.value=!1,R.value=!1,ot(),De(),Xe(),yield A();try{yield je(v.value)}catch{q.value=!1,R.value=!1,qe()}}finally{yield A(),tt=!1}return!0})})()))return void le(!1);if(s&&m.value&&X.value&&jn&&v.value)return jn=!1,q.value=!1,R.value=!1,X.value=!1,Ce.value=!1,ot(),De(),Xe(),yield A(),yield je(v.value,{allowStaleContentRetry:!1}),void it(!0);if(s&&X.value)if(m.value&&v.value){const c=ze;if(c)try{yield c}catch{}at();const d=Ot(String((u=r.node.originalCode)!=null?u:""),String((a=r.node.updatedCode)!=null?a:""));if(yield io(d.original,d.updated,Fe.value),B||!m.value)return;St(),ee(!0),Hl(),he(),lt();const f=yield oo({requireHighlight:!0});B||!f||R.value||(yield Nl()),ce(),it(!0)}else uo(),co(Re.value,Fe.value);s&&m.value?(le({preferModelDiffHeight:!0,holdCurrentDiffHeight:!0}),it(!0)):le(!1)}catch{}})})}),{immediate:!0,flush:"post"}),To(()=>{ot(),De(),On(),Zt?.()}),(e,t)=>ge.value?(Y(),Sn(J(Bo),{key:0,class:pt(["code-pre-fallback",{"is-wrap":qn.value}]),style:Vt($l.value),node:El.value,loading:r.loading,"show-line-numbers":!0,"diff-inline":Ue.value,"diff-hide-unchanged-regions":Wn.value},null,8,["class","style","node","loading","diff-inline","diff-hide-unchanged-regions"])):(Y(),ie("div",{key:1,ref_key:"container",ref:z,style:Vt(ai.value),class:pt(["code-block-container rounded-lg border",[{dark:r.isDark,"is-rendering":r.loading,"is-dark":xl.value,"is-diff":m.value,"is-plain-text":Mn.value}]]),"data-markstream-code-block":"1","data-markstream-enhanced":R.value&&!ge.value?"true":"false","data-markstream-enhancement-state":Vo.value,"data-markstream-code-block-state":Ve()?"streaming":"settled","data-markstream-pending":Uo.value?"true":void 0,"data-markstream-viewport-pending":yl.value&&J(Pn)&&!Z.value?"true":void 0},[Ro(pr,{"show-header":r.showHeader,"show-collapse-button":r.showCollapseButton,"show-font-size-buttons":r.showFontSizeButtons,"enable-font-size-control":r.enableFontSizeControl,"show-copy-button":r.showCopyButton,"show-expand-button":r.showExpandButton,"show-preview-button":r.showPreviewButton,"show-tooltips":r.showTooltips,"is-dark":r.isDark,loading:r.loading,stream:k.stream,"is-collapsed":Se.value,"is-expanded":Pe.value,"copy-text":wt.value,"is-previewable":ul.value,"code-font-size":W.value,"code-font-min":10,"code-font-max":36,"default-code-font-size":pe.value,"font-baseline-ready":Go.value,"diff-stats":m.value?Ze.value:null,"diff-stats-aria-label":Wo.value,onToggleCollapse:ci,onDecreaseFont:ti,onResetFont:ni,onIncreaseFont:ei,onCopy:si,onToggleExpand:di,onPreview:fi},Oi({"header-left":Gt(()=>[ht(e.$slots,"header-left",{},()=>[w("div",xr,[w("span",{class:"icon-slot h-4 w-4 flex-shrink-0",innerHTML:ri.value},null,8,Sr),w("div",Cr,[w("div",Mr,Be(ii.value),1),vo.value?(Y(),ie("div",Br,Be(vo.value),1)):we("",!0)])])],!0)]),loading:Gt(()=>[ht(e.$slots,"loading",{loading:k.loading,stream:k.stream},()=>[t[0]||(t[0]=w("div",{class:"loading-skeleton"},[w("div",{class:"skeleton-line"}),w("div",{class:"skeleton-line"}),w("div",{class:"skeleton-line short"})],-1))],!0)]),default:Gt(()=>[vl(w("div",{class:pt(["code-editor-layer",{"code-editor-layer--collapsed":Se.value}])},[w("div",{ref_key:"codeEditor",ref:v,class:pt(["code-editor-container",k.stream?"":"code-height-placeholder"]),"data-markstream-host-hidden":Io.value?"true":void 0,style:Vt(Xo.value)},null,14,Er),Bl.value?(Y(),Sn(J(Bo),{key:0,class:pt(["code-pre-fallback",{"is-wrap":qn.value}]),style:Vt($l.value),node:El.value,"show-line-numbers":!0,"diff-inline":Ue.value,"diff-hide-unchanged-regions":Wn.value},null,8,["class","style","node","diff-inline","diff-hide-unchanged-regions"])):we("",!0)],2),[[ml,!!k.stream||!k.loading]]),nn.value&&!Yt.value&&ul.value&&xe.value==="html"?(Y(),Sn(br,{key:0,code:r.node.code,"html-preview-allow-scripts":r.htmlPreviewAllowScripts,"html-preview-sandbox":r.htmlPreviewSandbox,"is-dark":r.isDark,"on-close":()=>nn.value=!1},null,8,["code","html-preview-allow-scripts","html-preview-sandbox","is-dark","on-close"])):we("",!0)]),_:2},[e.$slots["header-right"]?{name:"header-right",fn:Gt(()=>[ht(e.$slots,"header-right",{},void 0,!0)]),key:"0"}:void 0]),1032,["show-header","show-collapse-button","show-font-size-buttons","enable-font-size-control","show-copy-button","show-expand-button","show-preview-button","show-tooltips","is-dark","loading","stream","is-collapsed","is-expanded","copy-text","is-previewable","code-font-size","default-code-font-size","font-baseline-ready","diff-stats","diff-stats-aria-label"])],14,kr))}}),[["__scopeId","data-v-ef6e4bb8"]]);export{Lr as default}; diff --git a/apps/kimi-code/dist-web/assets/DesignSystemView-CTUhpkDe.js b/apps/kimi-code/dist-web/assets/DesignSystemView-CTUhpkDe.js new file mode 100644 index 000000000..2b2355945 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/DesignSystemView-CTUhpkDe.js @@ -0,0 +1,13 @@ +import{M as T,aD as z,aI as q,aL as o,u as i,v as a,G as t,H as d,F as p,aX as w,bb as y,I as c,bk as f,cx as h,cy as B,cz as k,cA as A,cB as M}from"./index-D-7nOosq.js";const I={class:"ds-page"},V={class:"layout"},H={class:"content"},L={class:"content-inner"},E={id:"tokens"},D={class:"icon-sizes"},O={class:"sz"},W={class:"p-ic",style:{width:"14px",height:"14px"},viewBox:"0 0 24 24",fill:"currentColor"},R={class:"sz"},N={class:"p-ic",style:{width:"16px",height:"16px"},viewBox:"0 0 24 24",fill:"currentColor"},U={class:"sz"},P={class:"p-ic",style:{width:"20px",height:"20px"},viewBox:"0 0 24 24",fill:"currentColor"},F={class:"icon-grid"},j={class:"icon-group-label"},K={class:"ic-name"},G={id:"primitives"},_={class:"stage-wrap"},J={class:"stage p"},Q={class:"p-pill",style:{color:"var(--p-warning)"}},Y={class:"stage-wrap"},Z={class:"stage p col"},X={class:"demo-row"},$={class:"p-btn primary disabled"},ee={class:"p-spinner sm",viewBox:"0 0 24 24",style:{"--p-accent":"#fff","--p-line":"rgba(255,255,255,.35)"}},ae={class:"stage-wrap"},te={class:"stage p col"},de={class:"demo-row"},se={class:"stage-wrap"},oe={class:"stage p col",style:{gap:"0",background:"var(--p-surface)",padding:"0","max-width":"300px","align-items":"stretch"}},ie={style:{display:"flex","align-items":"center",gap:"8px",padding:"7px 10px",margin:"1px 6px","border-radius":"8px",color:"var(--p-text)","font-size":"13px"}},ne={style:{color:"var(--d-fg-faint)",flex:"none"},width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor"},le={style:{display:"flex","align-items":"center",gap:"8px",padding:"7px 10px",margin:"1px 6px","border-radius":"8px",color:"var(--p-text)","font-size":"13px"}},re={style:{color:"var(--d-fg-faint)",flex:"none"},width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor"},ce={id:"chat"},ve={class:"stage-wrap"},fe={class:"stage p col"},pe={style:{"max-width":"560px",width:"100%"}},he={class:"stage-wrap"},ue={class:"stage p col",style:{"align-items":"center",background:"#fff"}},ge={class:"p-composer",style:{width:"100%","max-width":"620px"}},be={class:"p-composer-bar"},me={class:"p-composer-left"},we={class:"p-pill",style:{color:"var(--p-warning)"}},ye="/repo",ke=T({__name:"DesignSystemView",emits:["close"],setup(xe,{emit:x}){const C=[{path:"/repo/apps/web/src/components/chat/TurnFilesSummary.vue",added:19,removed:4,hasWrite:!1,statsIncomplete:!1,diff:null},{path:"/repo/apps/web/src/composables/useFilePreview.ts",added:8,removed:1,hasWrite:!1,statsIncomplete:!1,diff:null},{path:"/repo/apps/web/src/components/chatTurnRendering.ts",added:0,removed:0,hasWrite:!0,statsIncomplete:!0,diff:null},{path:"/repo/apps/web/src/lib/toolDiff.ts",added:3,removed:2,hasWrite:!1,statsIncomplete:!1,diff:null}];function u(){}const S=x;function g(){S("close")}let v=null;function b(r){r.key==="Escape"&&g()}return z(()=>{document.addEventListener("keydown",b);const r=Array.prototype.slice.call(document.querySelectorAll('#nav a[href^="#"]')),e=new Map;r.forEach(l=>{const s=l.getAttribute("href");if(!s)return;const m=document.getElementById(s.slice(1));m&&e.set(m,l)});let n=null;v=new IntersectionObserver(l=>{l.forEach(s=>{s.isIntersecting&&(n&&n.classList.remove("active"),n=e.get(s.target)??null,n&&n.classList.add("active"))})},{rootMargin:"-20% 0px -70% 0px",threshold:0}),e.forEach((l,s)=>v.observe(s)),r.length&&r[0].classList.add("active")}),q(()=>{document.removeEventListener("keydown",b),v&&(v.disconnect(),v=null)}),(r,e)=>(o(),i("div",I,[a("div",{class:"ds-topbar"},[a("button",{class:"ds-back",type:"button",onClick:g},"← Back"),e[0]||(e[0]=a("span",{class:"ds-topbar-title"},"Design system",-1))]),a("div",V,[e[44]||(e[44]=t('<aside class="sidebar" data-v-5fe218d3><div class="brand" data-v-5fe218d3><div class="brand-mark" data-v-5fe218d3>K</div><div class="brand-name" data-v-5fe218d3>Kimi Web</div></div><div class="brand-sub" data-v-5fe218d3>Design System · v1.0</div><div class="nav-group" data-v-5fe218d3>Navigate</div><nav class="nav" id="nav" data-v-5fe218d3><a href="#overview" data-v-5fe218d3><span class="num" data-v-5fe218d3>00</span>Overview</a><a href="#principles" data-v-5fe218d3><span class="num" data-v-5fe218d3>01</span>Design Principles</a><a href="#tokens" data-v-5fe218d3><span class="num" data-v-5fe218d3>02</span>Design Tokens</a><a href="#primitives" data-v-5fe218d3><span class="num" data-v-5fe218d3>03</span>Primitives</a><a href="#chat" data-v-5fe218d3><span class="num" data-v-5fe218d3>04</span>Chat Interface</a><a href="#themes" data-v-5fe218d3><span class="num" data-v-5fe218d3>05</span>Theming</a><a href="#rules" data-v-5fe218d3><span class="num" data-v-5fe218d3>06</span>Style Rules</a><a href="#shell" data-v-5fe218d3><span class="num" data-v-5fe218d3>07</span>App Shell & Sidebar</a><a href="#a11y" data-v-5fe218d3><span class="num" data-v-5fe218d3>08</span>Accessibility</a><a href="#dialogs" data-v-5fe218d3><span class="num" data-v-5fe218d3>09</span>Dialogs</a></nav><div class="nav-group" data-v-5fe218d3>Companion output</div><nav class="nav" data-v-5fe218d3><a href="#tokens" data-v-5fe218d3><span class="num" data-v-5fe218d3>↗</span>Token list</a><a href="#primitives" data-v-5fe218d3><span class="num" data-v-5fe218d3>↗</span>Component API</a><a href="#rules" data-v-5fe218d3><span class="num" data-v-5fe218d3>↗</span>Style rules</a></nav></aside>',1)),a("main",H,[a("div",L,[e[42]||(e[42]=t('<section id="overview" data-v-5fe218d3><div class="hero" data-v-5fe218d3><span class="eyebrow" data-v-5fe218d3>● Design System · v1.0</span><h1 data-v-5fe218d3>Kimi Web <span class="grad" data-v-5fe218d3>Design System</span></h1><p class="lead" data-v-5fe218d3> This document defines the visual language and component specification for Kimi Web — design tokens, component primitives, the chat interface, theming, and style rules. All UI work is grounded in it: unified, restrained, token-driven, and themeable. </p><div class="hero-meta" data-v-5fe218d3><span class="meta-chip" data-v-5fe218d3><span class="dot" data-v-5fe218d3></span> Scope <b data-v-5fe218d3>apps/kimi-web</b></span><span class="meta-chip" data-v-5fe218d3>Component primitives</span><span class="meta-chip" data-v-5fe218d3>Theme <b data-v-5fe218d3>1 set · 4 customizable colors</b></span><span class="meta-chip" data-v-5fe218d3>Light / dark mode</span></div></div><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>This spec is the single reference when changing the web UI.</b> Before adding or modifying a component, style, layout, or theme, read this document first; color, font, radius, spacing, shadow, z-index, and motion always use the §02 tokens, components reuse the §03 primitives, and the §06 style rules are followed. </div></div></section><section id="principles" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>01</span><h2 class="sec-title" data-v-5fe218d3>Design Principles</h2></div><p class="sec-desc" data-v-5fe218d3> Every UI decision traces back to the following principles. Kimi Web is a local Agent tool for developers: quick scanning, long stretches of staring, often in the dark — the design serves the task, and is restrained, clinical, and density-first. </p><ul class="clean check" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>Consistency</b> —— The same semantics use the same component. The primary button, dialog, input, and badge should each have exactly "one" correct way to be written across the entire site.</li><li data-v-5fe218d3><b data-v-5fe218d3>Hierarchy</b> —— Build a clear hierarchy through size, weight, color, and whitespace; emphasize through "restraint" rather than "bolder and bigger".</li><li data-v-5fe218d3><b data-v-5fe218d3>Proximity</b> —— Group related elements, leave whitespace between unrelated ones. A card's padding, line spacing, and group spacing all come from the same spacing scale.</li><li data-v-5fe218d3><b data-v-5fe218d3>Feedback</b> —— hover / active / focus / loading / success / error all have visible states, and the state language is unified.</li><li data-v-5fe218d3><b data-v-5fe218d3>Breathing room</b> —— Control density with the spacing scale rather than arbitrary pixels; prefer restrained whitespace over cramming controls together.</li><li data-v-5fe218d3><b data-v-5fe218d3>Accessibility (A11y)</b> —— Text contrast ≥ 4.5:1, visible focus rings, touch targets ≥ 32px, and states that don't rely on color alone.</li><li data-v-5fe218d3><b data-v-5fe218d3>Reduction</b> —— The number of colors, radii, shadow levels, and type sizes all converge to a finite set of tokens; delete stray values.</li></ul><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3><b data-v-5fe218d3>Brand tone (the do-not list)</b>: calm, clinical, never exaggerated. <span class="pill red" style="margin:0 4px;" data-v-5fe218d3>Reject</span> purple gradients, glassmorphism, glowing shadows, AI purple / blue glows, endlessly looping fussy micro-animations, "Boost your productivity"-style marketing copy, and using emoji as icons. These are all common tells of AI-generated interfaces (an "AI tell"), deliberately avoided. </div></div><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>Declare design intent first (Design Read)</b>: before adding a component / page, write one sentence describing its scenario, audience, and tone (for example, "a lightweight tool card embedded in a conversation, for developers, calm and restrained"), then build. If the intent isn't clear, ask one question first rather than defaulting to the nearest existing style. </div></div></section>',2)),a("section",E,[e[7]||(e[7]=t(`<div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>02</span><h2 class="sec-title" data-v-5fe218d3>Design Tokens</h2></div><p class="sec-desc" data-v-5fe218d3> Collapse every visual decision into tokens. <b data-v-5fe218d3>Color tokens keep the existing short names and fill out the semantics</b> (lowering migration cost), while <b data-v-5fe218d3>spacing, z-index, motion, and font-weight</b> fill in the scales that are currently missing. Every token has: name, light value, dark value, and usage. </p><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>Naming convention</b>: <code data-v-5fe218d3>--<category>-<role>-<state></code>. For example <code data-v-5fe218d3>--color-text-muted</code>, <code data-v-5fe218d3>--radius-md</code>, <code data-v-5fe218d3>--space-4</code>. To reduce churn, the existing short names (<code data-v-5fe218d3>--bg</code> / <code data-v-5fe218d3>--ink</code> / <code data-v-5fe218d3>--line</code> / <code data-v-5fe218d3>--blue</code> …) are kept as <b data-v-5fe218d3>compatibility aliases</b> for one release cycle. </div></div><h3 class="sub" data-v-5fe218d3>Color</h3><p data-v-5fe218d3>Semantic-first, in three layers: <b data-v-5fe218d3>background / text / border</b> + <b data-v-5fe218d3>accent</b> + <b data-v-5fe218d3>status colors</b>. All colors are defined in light / dark pairs, with contrast ≥ 4.5:1.</p><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3>The table below shows the <b data-v-5fe218d3>semantic tokens</b>. Each ships a light value in <code data-v-5fe218d3>:root</code> and a dark override in the <code data-v-5fe218d3>data-color-scheme</code> blocks — for example <code data-v-5fe218d3>--color-bg</code> is <code data-v-5fe218d3>#ffffff</code> in light and <code data-v-5fe218d3>#121212</code> in dark; <code data-v-5fe218d3>--color-accent</code> is the brand blue (<code data-v-5fe218d3>#1783ff</code> light / <code data-v-5fe218d3>#1a88ff</code> dark). The <b data-v-5fe218d3>semantic status colors</b> (success / warning / danger / info) are independent palettes, one set each for light / dark.</div></div><div class="palette" data-v-5fe218d3><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#ffffff;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>bg</div><div class="cv" data-v-5fe218d3>#ffffff / #121212</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#f5f5f5;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>surface</div><div class="cv" data-v-5fe218d3>#f5f5f5 / #1f1f1f</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#f5f5f5;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>surface-sunken</div><div class="cv" data-v-5fe218d3>#f5f5f5 / #121212</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#f5f5f5;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>well</div><div class="cv" data-v-5fe218d3>#f5f5f5 / #1f1f1f</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#f5f5f5;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>surface-deep</div><div class="cv" data-v-5fe218d3>#f5f5f5 / #0d0d0d</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#fff;border:0.5px solid rgba(0,0,0,.13);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>surface-overlay</div><div class="cv" data-v-5fe218d3>#ffffff / rgba(255,255,255,.1)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:rgba(0,0,0,.05);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>selected</div><div class="cv" data-v-5fe218d3>rgba(0,0,0,.05) / rgba(255,255,255,.1)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:rgba(0,0,0,.9);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>fg</div><div class="cv" data-v-5fe218d3>rgba(0,0,0,.9) / rgba(255,255,255,.84)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:rgba(0,0,0,.6);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>fg-muted</div><div class="cv" data-v-5fe218d3>rgba(0,0,0,.6) / rgba(255,255,255,.56)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:rgba(0,0,0,.13);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>line</div><div class="cv" data-v-5fe218d3>rgba(0,0,0,.13) / rgba(255,255,255,.12)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:rgba(0,0,0,.05);" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>subtle</div><div class="cv" data-v-5fe218d3>rgba(0,0,0,.05) / rgba(255,255,255,.05)</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#1783ff;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>accent (KMBlue)</div><div class="cv" data-v-5fe218d3>#1783ff / #1a88ff</div></div></div><div class="color-card" data-v-5fe218d3><div class="color-chip" style="background:#e8f3ff;" data-v-5fe218d3></div><div class="color-meta" data-v-5fe218d3><div class="cn" data-v-5fe218d3>accent-soft</div><div class="cv" data-v-5fe218d3>#e8f3ff / rgba(26,136,255,.1)</div></div></div></div><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Light</th><th data-v-5fe218d3>Dark</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-bg</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#121212;" data-v-5fe218d3></span>#121212</td><td data-v-5fe218d3>Page background</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-surface</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f5f5f5;" data-v-5fe218d3></span>#f5f5f5</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#1f1f1f;" data-v-5fe218d3></span>#1f1f1f</td><td data-v-5fe218d3>Panel / sidebar / card head</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-surface-raised</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#292929;" data-v-5fe218d3></span>#292929</td><td data-v-5fe218d3>Raised card / dialog / input</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-menu-bg</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.95);" data-v-5fe218d3></span>rgba(255,255,255,.95)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(41,41,41,.95);" data-v-5fe218d3></span>rgba(41,41,41,.95)</td><td data-v-5fe218d3>Floating menu panel — frosted glass over <code data-v-5fe218d3>--p-menu-backdrop</code> blur</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-surface-overlay</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-5fe218d3></span>rgba(255,255,255,.1)</td><td data-v-5fe218d3>Field-control fill on raised cards (selects, steppers) — top rung; light tops out at white (the level is carried by the border), dark steps one rung above raised. Floating layers stay at raised</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-well</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f5f5f5;" data-v-5fe218d3></span>#f5f5f5</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#1f1f1f;" data-v-5fe218d3></span>#1f1f1f</td><td data-v-5fe218d3>Content well on the page (code blocks, tool-output panels, match/file lists, media thumbnails) — light reuses the sunken recess; dark lifts one rung ABOVE the page, because a true recess (<code data-v-5fe218d3>#121212</code>) vanishes into the page there</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-surface-deep</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f5f5f5;" data-v-5fe218d3></span>#f5f5f5</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0d0d0d;" data-v-5fe218d3></span>#0d0d0d</td><td data-v-5fe218d3>Deep chrome plane one step BELOW the page (panel headers, diff gutters) — dark drops under <code data-v-5fe218d3>--color-bg</code> so chrome framing stays darker than the content it frames</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-text</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.9);" data-v-5fe218d3></span>rgba(0,0,0,.9)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.84);" data-v-5fe218d3></span>rgba(255,255,255,.84)</td><td data-v-5fe218d3>Body text / headings</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-text-strong</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#000;" data-v-5fe218d3></span>#000000</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;box-shadow:inset 0 0 0 1px #ddd;" data-v-5fe218d3></span>#ffffff</td><td data-v-5fe218d3>Max foreground emphasis — menu-row label & icon on hover</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-text-muted</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-5fe218d3></span>rgba(0,0,0,.6)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.56);" data-v-5fe218d3></span>rgba(255,255,255,.56)</td><td data-v-5fe218d3>Secondary text / placeholder</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-line</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.13);" data-v-5fe218d3></span>rgba(0,0,0,.13)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.12);" data-v-5fe218d3></span>rgba(255,255,255,.12)</td><td data-v-5fe218d3>Divider / card border</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-subtle</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.05);" data-v-5fe218d3></span>rgba(0,0,0,.05)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.05);" data-v-5fe218d3></span>rgba(255,255,255,.05)</td><td data-v-5fe218d3>Subtle hairline — tertiary separators below <code data-v-5fe218d3>--color-line</code> (diff-gutter column rules, quiet dividers inside wells)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-selected</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.05);" data-v-5fe218d3></span>rgba(0,0,0,.05)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-5fe218d3></span>rgba(255,255,255,.1)</td><td data-v-5fe218d3>Neutral selected fill (sidebar rows, list pickers) — translucent, never accent-tinted</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-hover</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.03);" data-v-5fe218d3></span>rgba(0,0,0,.03)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.05);" data-v-5fe218d3></span>rgba(255,255,255,.05)</td><td data-v-5fe218d3>Row hover wash — lighter than the selected fill (hover < selected); translucent, sits on any surface. The global hover rule: transparent-base controls overlay this f1 wash (hover never darkens — never sunken); filled controls use their own hover token (accent-hover, send-bg-hover)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-inline-code-bg</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.03);" data-v-5fe218d3></span>rgba(0,0,0,.03)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-5fe218d3></span>rgba(255,255,255,.1)</td><td data-v-5fe218d3>Inline-code chip fill — fills.f1 / fills.f2; dark lifts off any dark surface (sunken == bg there)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-media-alpha-bg-1</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#858585;" data-v-5fe218d3></span>≈#858585</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#76797e;" data-v-5fe218d3></span>≈#76797e</td><td data-v-5fe218d3>Checkerboard square A of the <code data-v-5fe218d3><img></code> alpha canvas — color-mix of <code data-v-5fe218d3>--color-bg</code>/<code data-v-5fe218d3>--color-text</code> (52/48); applied via <code data-v-5fe218d3>--media-alpha-canvas</code> (16px period)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-media-alpha-bg-2</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#6b6b6b;" data-v-5fe218d3></span>≈#6b6b6b</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#8c8f93;" data-v-5fe218d3></span>≈#8c8f93</td><td data-v-5fe218d3>Checkerboard square B (42/58) — both squares stay ≥3:1 against white and black; opaque images cover the canvas</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-sidebar-bg</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f9fbfc;" data-v-5fe218d3></span>#f9fbfc</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0d0d0d;" data-v-5fe218d3></span>#0d0d0d</td><td data-v-5fe218d3>Sidebar surface — one step off <code data-v-5fe218d3>--color-bg</code> (just under white in light, one step BELOW the page in dark) so the session column reads as its own plane and never brighter than the reading surface</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-scrim</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.4);" data-v-5fe218d3></span>rgba(0,0,0,.4)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-5fe218d3></span>rgba(0,0,0,.6)</td><td data-v-5fe218d3>Modal scrim — the dark veil behind dialogs/lightboxes (mask.base; legacy hardcoded overlays can migrate here)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-scrim-strong</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-5fe218d3></span>rgba(0,0,0,.6)</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:rgba(0,0,0,.75);" data-v-5fe218d3></span>rgba(0,0,0,.75)</td><td data-v-5fe218d3>Stronger scrim for full-screen media previews (mask.strong — the PhotoSwipe image preview backdrop)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-text-on-scrim</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>same</td><td data-v-5fe218d3>Text drawn on the scrim (captions over the media lightbox)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-accent</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#1783ff;" data-v-5fe218d3></span>#1783ff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#1a88ff;" data-v-5fe218d3></span>#1a88ff</td><td data-v-5fe218d3>Primary action / link / focus</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-success</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0e7a38;" data-v-5fe218d3></span>#0e7a38</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#3fb950;" data-v-5fe218d3></span>#3fb950</td><td data-v-5fe218d3>Success / pass</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-warning</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#a9610a;" data-v-5fe218d3></span>#a9610a</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#d29922;" data-v-5fe218d3></span>#d29922</td><td data-v-5fe218d3>Warning / pending</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--color-danger</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#c0392b;" data-v-5fe218d3></span>#c0392b</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f85149;" data-v-5fe218d3></span>#f85149</td><td data-v-5fe218d3>Danger / error / abort</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Palette</h4><p data-v-5fe218d3>The palette <b data-v-5fe218d3>is</b> the production kimi.com palette (design tokens <code data-v-5fe218d3>tokens.json</code>): neutral-gray surfaces, an alpha-based label / fill / separator ramp (<code data-v-5fe218d3>labels.*</code> / <code data-v-5fe218d3>fills.*</code> / <code data-v-5fe218d3>separator.s1</code>), the KMBlue accent, and a true neutral dark ladder (<code data-v-5fe218d3>#121212 → #1f1f1f → #292929</code>; the deep chrome plane and sidebar derive one step below at <code data-v-5fe218d3>#0d0d0d</code> — the palette has nothing darker than primary).</p><p data-v-5fe218d3>The ONE deliberate exception is the <b data-v-5fe218d3>status hues</b>: success / warning / danger / done keep the app's own WCAG-tuned ramp (≥4.5:1 on the neutral surfaces) — the production status colours (positiveGreen <code data-v-5fe218d3>#16c456</code>, orange <code data-v-5fe218d3>#ff9500</code>, danger red <code data-v-5fe218d3>#ff3849</code>) are too bright against it. Diff add/del bands happen to coincide (both use the production 25% fills in light, 14% in dark).</p><h4 class="mini" data-v-5fe218d3>Surface usage</h4><p data-v-5fe218d3>The surface layers each have a role — choose by "field overlay / raised layer / content well / default flat layer / sunken layer / page background / deep chrome", and avoid treating <code data-v-5fe218d3>--p-surface-raised</code> as a universal background. In dark, elevation = lighter: floating layers sit above the content, content wells sit above the page, and chrome planes (sidebar, panel headers) sit below it — never the reverse. One consequence: on the page itself, never use <code data-v-5fe218d3>--color-surface-sunken</code> for a content carrier — it equals <code data-v-5fe218d3>--color-bg</code> in dark and the fill vanishes; use <code data-v-5fe218d3>--color-well</code>. Sunken stays correct INSIDE surface / raised cards, where it is a genuine recess. Field controls (selects, steppers) on a raised card use <code data-v-5fe218d3>--color-surface-overlay</code>, the top fill rung; floating layers keep <code data-v-5fe218d3>--color-surface-raised</code> — their elevation is shadow + hairline, not a lighter fill.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Light</th><th data-v-5fe218d3>Dark</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-surface-overlay</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#22272e;" data-v-5fe218d3></span>#22272e</td><td data-v-5fe218d3>Field controls on raised cards — select, stepper (top fill rung; light = white)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-surface-raised</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#1c2128;" data-v-5fe218d3></span>#1c2128</td><td data-v-5fe218d3>Raised card / dialog / input (raised layer)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-well</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f3f5f8;" data-v-5fe218d3></span>#f3f5f8</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#13181e;" data-v-5fe218d3></span>#13181e</td><td data-v-5fe218d3>Code block / tool output / list carrier directly on the page (content well — light: recessed, dark: one rung above the page)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-surface</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fafbfc;" data-v-5fe218d3></span>#fafbfc</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#13181e;" data-v-5fe218d3></span>#13181e</td><td data-v-5fe218d3>Panel / sidebar / card head (default flat layer)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-surface-sunken</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#f3f5f8;" data-v-5fe218d3></span>#f3f5f8</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0d1117;" data-v-5fe218d3></span>#0d1117</td><td data-v-5fe218d3>Recessed area INSIDE a surface / raised card — never a content carrier on the page (sunken layer)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-bg</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fff;" data-v-5fe218d3></span>#ffffff</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0d1117;" data-v-5fe218d3></span>#0d1117</td><td data-v-5fe218d3>Page background</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-surface-deep</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#fafbfc;" data-v-5fe218d3></span>#fafbfc</td><td class="val" data-v-5fe218d3><span class="swatch" style="background:#0a0d12;" data-v-5fe218d3></span>#0a0d12</td><td data-v-5fe218d3>Panel header / diff gutter (deep chrome layer — below the page in dark)</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Borders & hairlines</h4><p data-v-5fe218d3>Three line tokens, three jobs: <code data-v-5fe218d3>--color-line</code> is the default structural separator, <code data-v-5fe218d3>--color-subtle</code> the tertiary separator that must stay quieter (diff-gutter column rules, quiet dividers inside wells), and <code data-v-5fe218d3>--color-line-strong</code> the edge of interactive controls (inputs, selects, secondary buttons). Width is one: <b data-v-5fe218d3>0.5px</b> — every stroke is the same hairline, on static structural edges (card rims, plane seams, header dividers), interactive control rims and floating layers alike. Separation comes from luminance first — planes one rung apart already read as distinct in dark, so their shared edge stays a 0.5px hairline rather than a heavier border; same-rung neighbours (list rows, card head / body) are exactly where a hairline is required. In dark, drop shadows fade on near-black surfaces, so a floating layer's edge IS its hairline — never ship a shadow-only floating surface. (Legacy <code data-v-5fe218d3>--line</code> / <code data-v-5fe218d3>--line2</code> alias <code data-v-5fe218d3>--color-line</code> / <code data-v-5fe218d3>--color-subtle</code> for one cycle; new work references the v2 names.)</p><h4 class="mini" data-v-5fe218d3>Focus ring</h4><p data-v-5fe218d3>All focusable controls (button, input, link, menu item, switch, checkbox) use the focus-ring token uniformly; do not hand-write a <code data-v-5fe218d3>box-shadow</code> focus ring.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-focus-ring</td><td class="val" data-v-5fe218d3>0 0 0 3px var(--p-accent-soft)</td><td data-v-5fe218d3>Default focus ring (link, menu item, switch, checkbox)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-focus-ring-strong</td><td class="val" data-v-5fe218d3>0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)</td><td data-v-5fe218d3>Strong focus ring (button, primary action)</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Text selection</h4><p data-v-5fe218d3>The text-selection color uses <code data-v-5fe218d3>--p-selection</code> uniformly (light <code data-v-5fe218d3>rgba(23,131,255,.18)</code> / dark <code data-v-5fe218d3>rgba(88,166,255,.32)</code>), applied by the global <code data-v-5fe218d3>::selection</code> rule; do not set a separate highlight background.</p><h4 class="mini" data-v-5fe218d3>Disabled state</h4><p data-v-5fe218d3>All disabled controls use <code data-v-5fe218d3>opacity:.5</code> + <code data-v-5fe218d3>cursor:not-allowed</code> uniformly; do not separately grey out or recolor.</p><h3 class="sub" data-v-5fe218d3>Font families</h3><p data-v-5fe218d3>Kimi Web uses two font tokens: <b data-v-5fe218d3>--font-ui</b> (UI and body, with Schibsted Grotesk for Latin and Noto Sans SC for Simplified Chinese) and <b data-v-5fe218d3>--font-mono</b> (code and monospace). Components always reference the variables; do not hard-code font names.</p><h4 class="mini" data-v-5fe218d3>--font-ui · UI & body (Schibsted Grotesk + Noto Sans SC)</h4><p data-v-5fe218d3>Body and UI use self-hosted Schibsted Grotesk for Latin text and self-hosted Noto Sans SC Variable for Simplified Chinese. Platform fonts remain as fallbacks:</p><div class="code" data-v-5fe218d3><div class="code-bar" data-v-5fe218d3><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="fn" data-v-5fe218d3>--font-ui</span></div><pre data-v-5fe218d3>--font-ui: "Schibsted Grotesk Variable", "Helvetica Neue", Arial, + "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", + "Microsoft YaHei", + -apple-system, BlinkMacSystemFont, "Segoe UI", + Roboto, Ubuntu, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";</pre></div><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>Schibsted Grotesk first: self-hosted Latin UI and body text, with normal and italic variable faces.</li><li data-v-5fe218d3>Western fallbacks next: Helvetica Neue / Arial for environments where Schibsted Grotesk cannot load.</li><li data-v-5fe218d3>Noto Sans SC Variable next: bundled Simplified Chinese glyphs with a weight range of 100–900.</li><li data-v-5fe218d3>System UI fallbacks last: PingFang SC / Microsoft YaHei, platform UI fonts, and emoji fonts.</li></ul><h4 class="mini" data-v-5fe218d3>--font-mono · Code & monospace</h4><p data-v-5fe218d3>Code, line numbers, diffs, and Bash commands use JetBrains Mono (a self-hosted variable font), falling back to the system monospace. Other tool labels and summaries use the UI font:</p><div class="code" data-v-5fe218d3><div class="code-bar" data-v-5fe218d3><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="fn" data-v-5fe218d3>--font-mono</span></div><pre data-v-5fe218d3>--font-mono: "JetBrains Mono Variable", "JetBrains Mono", + ui-monospace, "SF Mono", Menlo, Consolas, monospace;</pre></div><h4 class="mini" data-v-5fe218d3>Loading strategy</h4><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Font</th><th data-v-5fe218d3>Source</th><th data-v-5fe218d3>Bundled</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>JetBrains Mono</td><td class="val" data-v-5fe218d3>@fontsource-variable/jetbrains-mono</td><td class="val" data-v-5fe218d3>✓ self-hosted</td><td data-v-5fe218d3>monospace / code (--font-mono)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Schibsted Grotesk</td><td class="val" data-v-5fe218d3>prepare-fonts → app-ui/assets/fonts</td><td class="val" data-v-5fe218d3>✓ generated + bundled</td><td data-v-5fe218d3>UI / body / display (--font-ui, --font-display), wght 400-900, normal + italic</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Noto Sans SC</td><td class="val" data-v-5fe218d3>prepare-fonts → app-ui/assets/fonts</td><td class="val" data-v-5fe218d3>✓ generated + bundled</td><td data-v-5fe218d3>Simplified Chinese UI / body, wght 100–900</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>System UI / CJK fonts</td><td class="val" data-v-5fe218d3>operating system</td><td class="val" data-v-5fe218d3>—</td><td data-v-5fe218d3>late fallback for UI / body</td></tr></tbody></table><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3> Schibsted Grotesk, Noto Sans SC, and JetBrains Mono are self-hosted. They make no external network requests and work offline; platform fonts remain as fallbacks. </div></div><h4 class="mini" data-v-5fe218d3>Usage rules</h4><ul class="clean check" data-v-5fe218d3><li data-v-5fe218d3>Components always use <code data-v-5fe218d3>var(--font-ui)</code> / <code data-v-5fe218d3>var(--font-mono)</code>; do not hard-code font names like <code data-v-5fe218d3>'Schibsted Grotesk'</code> / <code data-v-5fe218d3>'JetBrains Mono'</code>.</li><li data-v-5fe218d3>Body / UI use <code data-v-5fe218d3>--font-ui</code> (Schibsted Grotesk for Latin, Noto Sans SC for Simplified Chinese); code / monospace use <code data-v-5fe218d3>--font-mono</code> (JetBrains Mono).</li><li data-v-5fe218d3>Schibsted Grotesk is loaded from complete variable faces, including normal and italic styles; <code data-v-5fe218d3>font-optical-sizing: auto</code> is enabled globally.</li><li data-v-5fe218d3>Noto Sans SC is loaded from one complete weight-variable WOFF2 asset. Platform CJK fonts stay late in the fallback chain.</li></ul><h3 class="sub" data-v-5fe218d3>Type scale & weight</h3><p data-v-5fe218d3>The user font-size preference is one of four named steps (<code data-v-5fe218d3>small / medium / large / xlarge</code>, Medium default) written to <code data-v-5fe218d3>data-font-scale</code> on <code data-v-5fe218d3><html></code>; the step name is persisted, never a px value. The step only moves <code data-v-5fe218d3>--base-font</code>; every size token derives additively (<code data-v-5fe218d3>default + shift</code>), and line heights are locked to integer px via <code data-v-5fe218d3>round(size × ratio, 1px)</code> — never a unitless ratio.</p><p data-v-5fe218d3>Two token groups share the shift but keep their own ratios: <b data-v-5fe218d3>--ui-*</b> for chrome (tight, 1.40–1.50) and <b data-v-5fe218d3>--md-*</b> for Markdown content + the composer (loose, 1.56–1.63; body is anchored to the UI body size — the spec's +2px offset was dropped as a product decision — while keeping its own looser line-height ratios). T0/T1 cap at 24/22px on the top steps (built into the tokens via <code data-v-5fe218d3>min()</code> — do not remove). Use the <code data-v-5fe218d3>.text-ui-*</code> / <code data-v-5fe218d3>.text-md-*</code> utility classes; legacy aliases <code data-v-5fe218d3>--ui-font-size</code> (→ <code data-v-5fe218d3>--ui-b2</code>), <code data-v-5fe218d3>--content-font-size</code> (→ <code data-v-5fe218d3>--md-b1</code>) and the whole 6-level <code data-v-5fe218d3>--text-*</code> ramp (xs→c1, sm→b2−1px, base→b2, lg→t2, xl→t1, 2xl→t0) keep older components on the ramp. Panel titles sit at the base step (<code data-v-5fe218d3>--ui-b2</code>); dropdown menu items sit one rung below (<code data-v-5fe218d3>--text-sm</code> = b2 − 1px) — both still follow the user's font scale.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-5fe218d3><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-t1);font-weight:500;" data-v-5fe218d3>Section Title</div><div class="type-meta" data-v-5fe218d3>--ui-t1 · title (cap 22)</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-t2);font-weight:500;" data-v-5fe218d3>Card title</div><div class="type-meta" data-v-5fe218d3>--ui-t2 · subtitle</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-b1);font-weight:500;" data-v-5fe218d3>UI emphasis</div><div class="type-meta" data-v-5fe218d3>--ui-b1 · body strong</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-b2);" data-v-5fe218d3>UI control / button / form</div><div class="type-meta" data-v-5fe218d3>--ui-b2 · body</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-c1);" data-v-5fe218d3>Helper text / table</div><div class="type-meta" data-v-5fe218d3>--ui-c1 · caption</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--ui-c2);" data-v-5fe218d3>Badge / timestamp</div><div class="type-meta" data-v-5fe218d3>--ui-c2 · non-critical only</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--md-h1);font-weight:600;" data-v-5fe218d3>Markdown H1</div><div class="type-meta" data-v-5fe218d3>--md-h1</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--md-b1);" data-v-5fe218d3>Chat body / message bubbles / composer</div><div class="type-meta" data-v-5fe218d3>--md-b1 · prose body</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--md-b2);" data-v-5fe218d3>Quote / table</div><div class="type-meta" data-v-5fe218d3>--md-b2 · secondary</div></div><div class="type-row" data-v-5fe218d3><div class="type-sample" style="font-size:var(--md-b3);font-family:var(--font-mono);" data-v-5fe218d3>Code block / inline code</div><div class="type-meta" data-v-5fe218d3>--md-b3 · weak / code</div></div></div><p data-v-5fe218d3>The fixed product type tokens still define scale-independent defaults: transcript prose enables <code data-v-5fe218d3>text-autospace: normal</code> for mixed CJK and Latin text. Drop stray <code data-v-5fe218d3>font-weight: 650 / 750</code>; converge on 400 / 500 (regular / emphasis), with a dedicated 600 weight for sidebar section labels.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--font-ui</td><td class="val" data-v-5fe218d3>"Schibsted Grotesk Variable", …, "Noto Sans SC Variable", …</td><td data-v-5fe218d3>UI & body (Schibsted Grotesk + Noto Sans SC)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--font-kbd</td><td class="val" data-v-5fe218d3>"Schibsted Grotesk Variable", system-ui, sans-serif</td><td data-v-5fe218d3>keyboard shortcut keycaps</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--font-mono</td><td class="val" data-v-5fe218d3>JetBrains Mono…</td><td data-v-5fe218d3>code, Bash commands, line numbers, diffs</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>data-font-scale</td><td class="val" data-v-5fe218d3>small / medium / large / xlarge</td><td data-v-5fe218d3>user preference on <html>; sets --base-font (12–18px), Medium = 14px default</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--ui-t0…--ui-c2</td><td class="val" data-v-5fe218d3>default + --ui-shift, t0/t1 capped via min()</td><td data-v-5fe218d3>chrome type ramp (title / subtitle / body / caption); .text-ui-* classes</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--md-h1…--md-b3</td><td class="val" data-v-5fe218d3>default + --md-shift</td><td data-v-5fe218d3>Markdown ramp (headings / body / secondary / code); .text-md-* classes</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--ui-font-size / --content-font-size</td><td class="val" data-v-5fe218d3>var(--ui-b2) / var(--md-b1)</td><td data-v-5fe218d3>legacy aliases kept on the ramp</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--code-font-size</td><td class="val" data-v-5fe218d3>calc(var(--content-font-size) - 2px)</td><td data-v-5fe218d3>standalone code surfaces (diff view, file preview, tool cards) — one step below body, 12px @ Medium; prose-embedded code stays on the --md-* ramp</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--text-xs / sm / base / lg / xl / 2xl</td><td class="val" data-v-5fe218d3>c1 / b2−1 / b2 / t2 / t1 / t0</td><td data-v-5fe218d3>legacy ramp, aliased into the scale</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--leading-tight/normal/prose/relaxed</td><td class="val" data-v-5fe218d3>1.25 / 1.5 / 1.6 / 1.7</td><td data-v-5fe218d3>headings / UI / chat prose / long text</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--weight-regular/option-label/medium/ui-strong</td><td class="val" data-v-5fe218d3>400 / 475 / 500 / 525</td><td data-v-5fe218d3>body / settings labels / emphasis / compact UI emphasis</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--weight-section-label</td><td class="val" data-v-5fe218d3>600</td><td data-v-5fe218d3>sidebar section labels</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Icon size</h4><p data-v-5fe218d3>Icons use three size tokens uniformly. The global <code data-v-5fe218d3>.p-ic</code> default is 16px (<code data-v-5fe218d3>--p-ic-md</code>); components pick as needed, and random pixel sizes are forbidden.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-ic-sm</td><td class="val" data-v-5fe218d3>14px</td><td data-v-5fe218d3>small button, badge, menu item, inline link icon</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-ic-md</td><td class="val" data-v-5fe218d3>16px</td><td data-v-5fe218d3>default (button, icon button, toolbar)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-ic-lg</td><td class="val" data-v-5fe218d3>20px</td><td data-v-5fe218d3>Toast status icon, empty-state illustration</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Icon</h4><p data-v-5fe218d3>Icons always come from the centralized registry <code data-v-5fe218d3>lib/icons.ts</code>: in templates use the <code data-v-5fe218d3><Icon name size /></code> component (<code data-v-5fe218d3>components/ui/Icon.vue</code>); for <code data-v-5fe218d3>v-html</code> contexts (such as a tool glyph) use <code data-v-5fe218d3>iconSvg(name, size)</code>. <b data-v-5fe218d3>Do not hand-write <code data-v-5fe218d3><svg></code></b> — the <code data-v-5fe218d3>scripts/check-style.mjs</code> <code data-v-5fe218d3>icon-from-registry</code> rule flags stray SVGs. Every glyph shares the 24×24 source grid and <code data-v-5fe218d3>currentColor</code> (colour follows text); size uses the three tokens below, and only icons imported in <code data-v-5fe218d3>lib/icons.ts</code> are bundled by <a href="https://github.com/unplugin/unplugin-icons" data-v-5fe218d3>unplugin-icons</a> at build time. Three collections feed the registry, in this order of preference: <b data-v-5fe218d3><code data-v-5fe218d3>~icons/kimi/*</code></b> — Kimi Design System icons (24×24 outlined, 1.8px stroke), local SVGs under <code data-v-5fe218d3>src/icons/kimi/</code> registered as a custom collection in the Vite config, used whenever a Kimi glyph exists for the intent; <b data-v-5fe218d3><code data-v-5fe218d3>~icons/tabler/*</code></b> — Tabler Icons (MIT), for the few gaps it uniquely covers (today: the right-panel toggle); and <b data-v-5fe218d3><code data-v-5fe218d3>~icons/ri/*</code></b> — <a href="https://remixicon.com/" data-v-5fe218d3>Remix Icon</a> (Apache-2.0), for the remaining intents the Kimi set does not cover yet. A few glyphs are filed under their intent rather than the upstream asset name (see the <code data-v-5fe218d3>lib/icons.ts</code> header). When an icon is missing, prefer a glyph from the Kimi icon set: copy the SVG into <code data-v-5fe218d3>src/icons/kimi/</code> (kebab-case name, monochrome <code data-v-5fe218d3>currentColor</code>) and register it — two static imports (component + <code data-v-5fe218d3>?raw</code> string) plus one entry in <code data-v-5fe218d3>ICONS</code>; reach for Remix only when no Kimi glyph fits, and never draw paths in a component.</p><h4 class="mini" data-v-5fe218d3>Size scale</h4>`,49)),a("div",D,[a("div",O,[(o(),i("svg",W,[...e[1]||(e[1]=[a("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),e[2]||(e[2]=d("sm · 14",-1))]),a("div",R,[(o(),i("svg",N,[...e[3]||(e[3]=[a("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),e[4]||(e[4]=d("md · 16",-1))]),a("div",U,[(o(),i("svg",P,[...e[5]||(e[5]=[a("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),e[6]||(e[6]=d("lg · 20",-1))])]),e[8]||(e[8]=a("h4",{class:"mini"},"Icon library",-1)),e[9]||(e[9]=a("p",null,[d("Currently registered icons, grouped by purpose. The display order and grouping are defined by "),a("code",null,"ICON_GROUPS"),d(" in "),a("code",null,"lib/icons.ts"),d(" (a hand-maintained array covering the same icon names), and this catalog is rendered directly from that array so the registry and the document never drift.")],-1)),a("div",F,[(o(!0),i(p,null,w(f(B),([n,l])=>(o(),i(p,{key:n},[a("div",j,y(n),1),(o(!0),i(p,null,w(l,s=>(o(),i("div",{key:s,class:"icon-cell"},[c(f(h),{name:s},null,8,["name"]),a("span",K,y(s),1)]))),128))],64))),128))]),e[10]||(e[10]=t('<p data-v-5fe218d3>Do not use emoji as functional icons. The Kimi brand mark (the robot mascot logo) is a brand asset and is not part of this icon system.</p><p data-v-5fe218d3>A few <b data-v-5fe218d3>special graphics</b> are not in the registry; each has a dedicated component maintained in one place, and must not be copied by hand: <code data-v-5fe218d3><ContextRing :pct /></code> (the Composer context progress ring, data-driven), <code data-v-5fe218d3><AuthStateIcon kind /></code> (the success / expired / error colored illustrations in the login flow), <code data-v-5fe218d3><Spinner /></code> (loading state). Status dots (such as in the Provider list) always use CSS dots (<code data-v-5fe218d3>border-radius:50%</code>), not SVG. The <code data-v-5fe218d3>scripts/check-style.mjs</code> <code data-v-5fe218d3>icon-from-registry</code> rule exempts the above and the brand mark; all other hand-written <code data-v-5fe218d3><svg></code> is flagged.</p><h3 class="sub" data-v-5fe218d3>Spacing</h3><p data-v-5fe218d3>A 4px base grid. All spacing, gaps, and padding inside and outside components come from this scale — no arbitrary pixels.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-5fe218d3><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:4px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-1 · 4</div><div class="space-use" data-v-5fe218d3>icon gap, badge padding</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:8px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-2 · 8</div><div class="space-use" data-v-5fe218d3>control gap, small padding</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:12px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-3 · 12</div><div class="space-use" data-v-5fe218d3>button padding, form-item gap</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:16px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-4 · 16</div><div class="space-use" data-v-5fe218d3>card padding, grid gap</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:20px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-5 · 20</div><div class="space-use" data-v-5fe218d3>dialog padding</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:24px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-6 · 24</div><div class="space-use" data-v-5fe218d3>section gap</div></div><div class="space-row" data-v-5fe218d3><div class="space-bar" style="width:32px;" data-v-5fe218d3></div><div class="space-meta" data-v-5fe218d3>--space-8 · 32</div><div class="space-use" data-v-5fe218d3>large section gap</div></div></div><h4 class="mini" data-v-5fe218d3>Dense list (sidebar / file tree)</h4><p data-v-5fe218d3>High-density navigation lists like the sidebar share one rhythm, all on the 4px grid: <b data-v-5fe218d3>in-row vertical padding</b> <code data-v-5fe218d3>--space-1</code> (4px), <b data-v-5fe218d3>no margin between rows</b> (the hover pill provides the separation); <b data-v-5fe218d3>section gap</b> (between logo / search / action buttons / group title / list) uniformly <code data-v-5fe218d3>--space-2</code> (8px); <b data-v-5fe218d3>between groups</b> <code data-v-5fe218d3>--space-2</code>; the brand header is slightly looser at the top (<code data-v-5fe218d3>--space-3</code>). When building similar lists, reuse this scale — do not hand-write 1/6/7/10px.</p><h3 class="sub" data-v-5fe218d3>Radius</h3><p data-v-5fe218d3>Merge the existing 14 values <b data-v-5fe218d3>into the nearest</b> of 7 scale steps. Rule: the component type determines the radius, not the author's feel. The Composer shell is the sole product-specific exception: its 32px radius pairs with <code data-v-5fe218d3>superellipse(1.5)</code> so the flatter curve stays visually concentric with its controls.</p><div class="radius-grid" data-v-5fe218d3><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:4px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>xs · 4</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:6px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>sm · 6</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:8px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>md · 8</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:12px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>lg · 12</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:16px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>xl · 16</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:20px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>2xl · 20</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:32px;corner-shape:superellipse(1.5);" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>composer · 32 / 1.5</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border-radius:999px;" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>full · 999</span></div></div><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th><th data-v-5fe218d3>Merged from</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-xs</td><td class="val" data-v-5fe218d3>4px</td><td data-v-5fe218d3>small badge, inline tag</td><td class="val" data-v-5fe218d3>2/3/4px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-sm</td><td class="val" data-v-5fe218d3>6px</td><td data-v-5fe218d3>small button, icon button, menu item</td><td class="val" data-v-5fe218d3>5/6px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-md</td><td class="val" data-v-5fe218d3>8px</td><td data-v-5fe218d3>button, input, badge, card</td><td class="val" data-v-5fe218d3>7/8/9px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-lg</td><td class="val" data-v-5fe218d3>12px</td><td data-v-5fe218d3>menu, toast, bubble, floating card</td><td class="val" data-v-5fe218d3>10/12px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-xl</td><td class="val" data-v-5fe218d3>16px</td><td data-v-5fe218d3>container baseline: dialogs, settings cards, sheets, work panel</td><td class="val" data-v-5fe218d3>13/16px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-2xl</td><td class="val" data-v-5fe218d3>20px</td><td data-v-5fe218d3>workspace attachment card bottom (<code data-v-5fe218d3>0 0 2xl 2xl</code>) tucked under the composer</td><td class="val" data-v-5fe218d3>18/20px →</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-composer</td><td class="val" data-v-5fe218d3>32px</td><td data-v-5fe218d3>Composer shell, with <code data-v-5fe218d3>--corner-shape-composer</code></td><td class="val" data-v-5fe218d3>product-specific</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--radius-full</td><td class="val" data-v-5fe218d3>999px</td><td data-v-5fe218d3>pill badge, avatar, send button</td><td class="val" data-v-5fe218d3>999px / 50%</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Elevation & z-index</h3><p data-v-5fe218d3>Shadows express only "elevation", never decoration (no colored glow). z-index is unified into a scale, eradicating <code data-v-5fe218d3>9999</code>-style one-upping.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-5fe218d3><div class="radius-grid" style="align-items:stretch;" data-v-5fe218d3><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border:none;background:#fff;box-shadow:0 1px 2px rgba(16,24,40,.05),0 1px 3px rgba(16,24,40,.06);" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>sm · dropdown menu / sticky</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border:none;background:#fff;box-shadow:0 4px 12px rgba(16,24,40,.07),0 2px 4px rgba(16,24,40,.05);" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>md · Toast</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border:none;background:#fff;box-shadow:0 12px 32px rgba(16,24,40,.12),0 4px 10px rgba(16,24,40,.08);" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>lg · overlay (reserved)</span></div><div class="radius-item" data-v-5fe218d3><div class="radius-box" style="border:none;background:#fff;box-shadow:0 24px 64px rgba(16,24,40,.18),0 8px 20px rgba(16,24,40,.10);" data-v-5fe218d3></div><span class="rl" data-v-5fe218d3>xl · dialog</span></div></div></div><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Z-index Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-base</td><td class="val" data-v-5fe218d3>0</td><td data-v-5fe218d3>normal flow</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-sticky</td><td class="val" data-v-5fe218d3>100</td><td data-v-5fe218d3>sticky header / sidebar</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-dropdown</td><td class="val" data-v-5fe218d3>200</td><td data-v-5fe218d3>dropdown menu</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-overlay</td><td class="val" data-v-5fe218d3>300</td><td data-v-5fe218d3>overlay / bottom Sheet</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-modal</td><td class="val" data-v-5fe218d3>400</td><td data-v-5fe218d3>dialog — sibling overlays tie-break by DOM order, so the global confirm (ConfirmDialogHost) mounts on demand to always land last / on top</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-modal-dropdown</td><td class="val" data-v-5fe218d3>500</td><td data-v-5fe218d3>menus / popovers that open above a modal dialog (teleported to <body>, e.g. the settings SecondaryModelPicker cascade)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-toast</td><td class="val" data-v-5fe218d3>600</td><td data-v-5fe218d3>toast</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-tooltip</td><td class="val" data-v-5fe218d3>650</td><td data-v-5fe218d3>tooltip bubble — transient and pointer-events none, so it sits above everything (dialogs, toasts) to stay visible anywhere</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--z-max</td><td class="val" data-v-5fe218d3>9999</td><td data-v-5fe218d3>reserved: only this tier for extreme fallback</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Motion</h3><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--ease-out</td><td class="val" data-v-5fe218d3>cubic-bezier(0.16, 1, 0.3, 1)</td><td data-v-5fe218d3>enter, hover, expand</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--ease-in-out</td><td class="val" data-v-5fe218d3>cubic-bezier(0.4, 0, 0.2, 1)</td><td data-v-5fe218d3>panel width, layout changes</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--duration-fast</td><td class="val" data-v-5fe218d3>120ms</td><td data-v-5fe218d3>press, focus</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--duration-base</td><td class="val" data-v-5fe218d3>160ms</td><td data-v-5fe218d3>hover, show/hide</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--duration-slow</td><td class="val" data-v-5fe218d3>260ms</td><td data-v-5fe218d3>dialog, Sheet, layout</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--duration-hover-intent</td><td class="val" data-v-5fe218d3>250ms</td><td data-v-5fe218d3>hover-intent reveal gate (TOC rail)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--anim-rive-spin</td><td class="val" data-v-5fe218d3>416.7ms</td><td data-v-5fe218d3>new-chat / folder-plus icon: plus spin on hover</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--anim-leftbar</td><td class="val" data-v-5fe218d3>533.3ms</td><td data-v-5fe218d3>sidebar toggle icon: arrow fly-in on hover</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--anim-leftbar-shrink</td><td class="val" data-v-5fe218d3>200ms</td><td data-v-5fe218d3>sidebar toggle icon: divider shrink on hover</td></tr></tbody></table><p data-v-5fe218d3>The <code data-v-5fe218d3>--anim-*</code> lengths are track timings ported verbatim from the designer's Rive exports, so they sit outside the <code data-v-5fe218d3>--duration-*</code> ramp on purpose — retiming the ramp must not distort them. Their interpolation stays <code data-v-5fe218d3>linear</code> because the easing is already baked into the dense keyframe stops; a token easing would double-apply. Three hover tracks use them today: the sidebar toggle shrinks its divider to half height while an arrow flies in and settles (the expand variant mirrors the track from the left), and the new-chat / folder-plus pluses do one bouncy spin. Each track is keyed to an id inside its own glyph (<code data-v-5fe218d3>#bar-divider</code>, <code data-v-5fe218d3>#bar-arrow</code> / <code data-v-5fe218d3>#bar-arrow-expand</code>, <code data-v-5fe218d3>#p1</code>, <code data-v-5fe218d3>#af-p1</code>) so every instance of the icon animates, and all revert on mouse-out. They still fall under the global reduced-motion switch below.</p><h4 class="mini" data-v-5fe218d3>Reduced motion</h4><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> Under <code data-v-5fe218d3>@media (prefers-reduced-motion: reduce)</code>, all animation and transition durations drop to about <code data-v-5fe218d3>0.001ms</code> (effectively off), and the chat working indicator's mascot renders its static fallback instead of the Rive loop. Components should not check this individually; it is handled uniformly in the global styles. The switch clears durations, not <code data-v-5fe218d3>transition-delay</code>: a hover-intent gate (the conversation TOC's 250ms reveal) decides <i data-v-5fe218d3>whether</i> hidden content appears, and clearing it would make pointer fly-bys strobe content for reduced-motion users. </div></div><h3 class="sub" data-v-5fe218d3>Layout & breakpoints</h3><p data-v-5fe218d3>Layout sizes and responsive breakpoints are tokenized too: sidebar width, content reading-column width, and two global breakpoints. Components should not hard-code pixels.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-sidebar-w</td><td class="val" data-v-5fe218d3>264px</td><td data-v-5fe218d3>left session sidebar width</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-content-max</td><td class="val" data-v-5fe218d3>760px</td><td data-v-5fe218d3>chat reading-column max width (regular chat prose)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-content-wide</td><td class="val" data-v-5fe218d3>920px</td><td data-v-5fe218d3>wide content (settings / panel)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-table-max</td><td class="val" data-v-5fe218d3>1040px</td><td data-v-5fe218d3>desktop wide-table max width (see §04)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-table-cell-max</td><td class="val" data-v-5fe218d3>700px</td><td data-v-5fe218d3>max width of a single table column; longer cell content wraps (see §04)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-bp-sm</td><td class="val" data-v-5fe218d3>640px</td><td data-v-5fe218d3>mobile / desktop boundary</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-bp-md</td><td class="val" data-v-5fe218d3>980px</td><td data-v-5fe218d3>narrow / wide screen boundary</td></tr></tbody></table><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> At ≤640px: dialogs become bottom Sheets, the sidebar collapses into an expandable drawer, and Composer toolbar controls are allowed to wrap. </div></div>',24))]),a("section",G,[e[27]||(e[27]=t(`<div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>03</span><h2 class="sec-title" data-v-5fe218d3>Primitives</h2></div><p class="sec-desc" data-v-5fe218d3> Component primitives are the "smallest correct units" of the site UI. Each primitive exposes variants along only two dimensions — <code data-v-5fe218d3>variant</code> / <code data-v-5fe218d3>size</code> — with appearance driven by tokens, so it naturally supports light / dark mode and customizable theme colors. </p><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> For every interactive primitive, the <b data-v-5fe218d3>keyboard behavior, focus, and ARIA contract are in §08 Accessibility</b>. New primitives must ship with a keyboard model — mouse-only interaction is not enough. </div></div><h3 class="sub" data-v-5fe218d3>Component selection guide</h3><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Scenario</th><th data-v-5fe218d3>Use</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td data-v-5fe218d3>Primary action (submit / confirm)</td><td data-v-5fe218d3><code data-v-5fe218d3>Button variant=primary</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Secondary action / cancel</td><td data-v-5fe218d3><code data-v-5fe218d3>Button secondary</code> / <code data-v-5fe218d3>ghost</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Destructive action (delete / abort)</td><td data-v-5fe218d3><code data-v-5fe218d3>Button danger</code> / <code data-v-5fe218d3>danger-soft</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Status marker</td><td data-v-5fe218d3><code data-v-5fe218d3>Badge</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Toolbar filter / model switch</td><td data-v-5fe218d3><code data-v-5fe218d3>Pill</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>2–5 mutually exclusive options</td><td data-v-5fe218d3><code data-v-5fe218d3>SegmentedControl</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Top tabs</td><td data-v-5fe218d3><code data-v-5fe218d3>Tabs</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Switch / multi-select</td><td data-v-5fe218d3><code data-v-5fe218d3>Switch</code> / <code data-v-5fe218d3>Checkbox</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Scrollable regions with overlay controls</td><td data-v-5fe218d3><code data-v-5fe218d3>ScrollArea</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Floating content card / list action menu</td><td data-v-5fe218d3><code data-v-5fe218d3>Card</code> / <code data-v-5fe218d3>Menu</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Inline notice / global toast</td><td data-v-5fe218d3><code data-v-5fe218d3>Banner</code> / <code data-v-5fe218d3>Toast</code></td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Dialog / confirmation · bottom panel (mobile)</td><td data-v-5fe218d3><code data-v-5fe218d3>Dialog</code> / <code data-v-5fe218d3>Sheet</code></td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Button</h3><p data-v-5fe218d3>4 semantic variants × 3 sizes. The primary action <code data-v-5fe218d3>primary</code> takes its color from the current theme color (§05 can switch between the blue and black families). Radius uses <code data-v-5fe218d3>--radius-md</code> uniformly (small size <code data-v-5fe218d3>--radius-sm</code>), weight 600, with a visible focus ring.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Variant matrix <span class="tag spec" data-v-5fe218d3>light</span></span><span class="sactions" data-v-5fe218d3><span class="tab on" data-v-5fe218d3>preview</span></span></div><div class="stage p col" data-v-5fe218d3><span class="stage-label" data-v-5fe218d3>medium · default</span><div class="demo-row" data-v-5fe218d3><button class="p-btn primary" data-v-5fe218d3>Primary action</button><button class="p-btn secondary" data-v-5fe218d3>Secondary action</button><button class="p-btn ghost" data-v-5fe218d3>Ghost button</button><button class="p-btn danger-soft" data-v-5fe218d3>Destructive (soft)</button><button class="p-btn danger" data-v-5fe218d3>Destructive action</button></div><span class="stage-label" data-v-5fe218d3>small</span><div class="demo-row" data-v-5fe218d3><button class="p-btn primary sm" data-v-5fe218d3>Confirm</button><button class="p-btn secondary sm" data-v-5fe218d3>Cancel</button><button class="p-btn ghost sm" data-v-5fe218d3>More</button></div><span class="stage-label" data-v-5fe218d3>With icon / state</span><div class="demo-row" data-v-5fe218d3><button class="p-btn primary" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-5fe218d3></path></svg>New chat</button><button class="p-btn secondary" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg>Copied</button><button class="p-btn primary disabled" data-v-5fe218d3>Loading…</button></div></div></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Dark skin <span class="tag spec" data-v-5fe218d3>dark</span></span></div><div class="stage dark p col" data-p="dark" data-v-5fe218d3><div class="demo-row" data-v-5fe218d3><button class="p-btn primary" data-v-5fe218d3>Primary action</button><button class="p-btn secondary" data-v-5fe218d3>Secondary action</button><button class="p-btn ghost" data-v-5fe218d3>Ghost button</button><button class="p-btn danger" data-v-5fe218d3>Destructive action</button></div></div></div><h4 class="mini" data-v-5fe218d3>API</h4><div class="code" data-v-5fe218d3><div class="code-bar" data-v-5fe218d3><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="fn" data-v-5fe218d3>Button.vue · usage</span></div><pre data-v-5fe218d3><span class="k" data-v-5fe218d3><Button</span> <span class="p" data-v-5fe218d3>variant</span>=<span class="s" data-v-5fe218d3>"primary"</span> <span class="p" data-v-5fe218d3>size</span>=<span class="s" data-v-5fe218d3>"md"</span> <span class="p" data-v-5fe218d3>:loading</span>=<span class="s" data-v-5fe218d3>"submitting"</span><span class="k" data-v-5fe218d3>></span>Save<span class="k" data-v-5fe218d3></Button></span> + <span class="c" data-v-5fe218d3>// variant: primary | secondary | ghost | danger | danger-soft</span> + <span class="c" data-v-5fe218d3>// size: sm | md | lg</span></pre></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>States</span></div><div class="stage p" data-v-5fe218d3><div class="demo-row" data-v-5fe218d3><button class="p-btn primary" disabled style="opacity:.5;cursor:not-allowed;" data-v-5fe218d3>Disabled primary</button><button class="p-btn primary" data-v-5fe218d3><svg class="p-spinner sm" viewBox="0 0 24 24" data-v-5fe218d3><circle class="track" cx="12" cy="12" r="9" data-v-5fe218d3></circle><circle class="arc" cx="12" cy="12" r="9" data-v-5fe218d3></circle></svg>Submitting</button><button class="p-btn danger" disabled style="opacity:.5;cursor:not-allowed;" data-v-5fe218d3>Disabled danger</button></div></div></div><h3 class="sub" data-v-5fe218d3>IconButton</h3><p data-v-5fe218d3>Unified into three sizes — 26 / 32 / 44px — with the neutral <code data-v-5fe218d3>--color-hover</code> wash on hover and a visible focus ring. Replaces the ad-hoc icon + click areas scattered across components today.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>IconButton</span></div><div class="stage p" data-v-5fe218d3><button class="p-icon-btn" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-5fe218d3></path></svg></button><button class="p-icon-btn" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-5fe218d3></path></svg></button><button class="p-icon-btn" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-5fe218d3></path></svg></button><button class="p-icon-btn sm" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z" data-v-5fe218d3></path></svg></button><button class="p-icon-btn sm" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg></button></div></div><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> The desktop IconButton comes in <code data-v-5fe218d3>sm</code> 26 / <code data-v-5fe218d3>md</code> 32; on touch devices the tap target should be ≥ 44px, so use <code data-v-5fe218d3>lg</code> 44px, satisfying the §01 accessibility principle (the mobile three-piece set uses <code data-v-5fe218d3>lg</code>). Icon-only buttons must also name themselves on hover: pass <code data-v-5fe218d3>tooltip</code> (usually the same text as <code data-v-5fe218d3>label</code> — <code data-v-5fe218d3>label</code> alone only sets the aria-label); bare icon <code data-v-5fe218d3><button></code>/<code data-v-5fe218d3><a></code> triggers wrap the <code data-v-5fe218d3>Tooltip</code> component directly. </div></div><h3 class="sub" data-v-5fe218d3>Badge · Chip · Pill</h3><p data-v-5fe218d3>Collapsed into two kinds: <b data-v-5fe218d3>Badge</b> (status badge, with an optional status dot) and <b data-v-5fe218d3>Pill</b> (the clickable pill in the composer toolbar). Radius, font size, and padding are all unified.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Badge · status badge</span></div><div class="stage p col" data-v-5fe218d3><span class="stage-label" data-v-5fe218d3>Semantic variants</span><div class="demo-row" data-v-5fe218d3><span class="p-badge neutral" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>pending</span><span class="p-badge info" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>running</span><span class="p-badge success" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>completed</span><span class="p-badge warning" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>needs confirmation</span><span class="p-badge danger" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>failed</span><span class="p-badge solid" data-v-5fe218d3>KIMI</span></div><span class="stage-label" data-v-5fe218d3>With icon / small size</span><div class="demo-row" data-v-5fe218d3><span class="p-badge info" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1m1 2v14h14V5z" data-v-5fe218d3></path></svg>plan</span><span class="p-badge success sm" data-v-5fe218d3><span class="bd" data-v-5fe218d3></span>passed</span><span class="p-badge neutral sm" data-v-5fe218d3>read-only</span></div></div></div>`,19)),a("div",_,[e[14]||(e[14]=a("div",{class:"stage-bar"},[a("span",{class:"st"},"Pill · toolbar pill (composer)")],-1)),a("div",J,[e[12]||(e[12]=t('<span class="p-pill" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z" data-v-5fe218d3></path></svg><span class="pp-strong" data-v-5fe218d3>kimi-k2</span><span class="pp-sub" data-v-5fe218d3>· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-5fe218d3></path></svg></span>',1)),a("span",Q,[c(f(h),{name:"shield-question",size:"sm"}),e[11]||(e[11]=d("yolo",-1))]),e[13]||(e[13]=a("span",{class:"p-pill"},[a("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[a("path",{fill:"currentColor",d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m1-8h4v2h-6V7h2z"})]),d("12k / 200k")],-1))])]),e[28]||(e[28]=t(`<h3 class="sub" data-v-5fe218d3>Kbd · keyboard shortcut</h3><p data-v-5fe218d3><b data-v-5fe218d3>Kbd</b> renders a shortcut as keycaps — one block per key, never inline text like <code data-v-5fe218d3>(⌘K)</code>. Caps are 18px tall (Badge sm rhythm): transparent ground with a 0.5px hairline edge, 11px <code data-v-5fe218d3>--font-kbd</code> (Inter + system-ui), text colour inherited from the row that carries it — the cap has no fill or colour of its own, so it follows its context (bright inside the accent-ringed recording box, quiet in a hint row). Typical placement: pushed to the row's trailing edge, opposite the label (e.g. the sidebar search row), and inside dialog navigation hints.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Kbd · keycaps</span></div><div class="stage p" data-v-5fe218d3><span class="p-kbd" data-v-5fe218d3><kbd data-v-5fe218d3>⌘</kbd><kbd data-v-5fe218d3>K</kbd></span><span class="p-kbd" data-v-5fe218d3><kbd data-v-5fe218d3>Ctrl</kbd><kbd data-v-5fe218d3>K</kbd></span><span class="p-kbd" data-v-5fe218d3><kbd data-v-5fe218d3>⌘</kbd><kbd data-v-5fe218d3>⇧</kbd><kbd data-v-5fe218d3>P</kbd></span></div></div><h3 class="sub" data-v-5fe218d3>Card / Surface</h3><p data-v-5fe218d3>All cards across the site share <b data-v-5fe218d3>one structure</b> — <code data-v-5fe218d3>head / body / foot</code> — and come in two tiers by visual weight:</p><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>Operation card</b> —— composite "process" content such as the Swarm overview. (Individual tool calls are NOT cards anymore: they render as quiet borderless lines, see §04.) Flat shell: <code data-v-5fe218d3>0.5px</code> hairline, <code data-v-5fe218d3>--radius-md</code>, no shadow. The head is compact mono with no fill, low weight by default, not competing with the conversation.</li><li data-v-5fe218d3><b data-v-5fe218d3>Attention card</b> —— content that needs a user decision, such as Question / Approval. A floating neutral card: white raised surface, <code data-v-5fe218d3>--radius-lg</code>, a faint popover shadow (<code data-v-5fe218d3>--shadow-menu</code>), a plain dark title head, and a hairline footer whose actions read in number-key order (chips on the buttons) leading to one solid primary action. No semantic color band.</li></ul><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Operation card · compact mono head (no fill)</span></div><div class="stage p col" data-v-5fe218d3><div class="p-card" style="max-width:460px;" data-v-5fe218d3><div class="p-card-head" data-v-5fe218d3><span class="p-card-title" data-v-5fe218d3>read_file</span><span class="p-badge info sm" style="margin-left:auto;" data-v-5fe218d3>session.ts</span></div><div class="p-card-body" data-v-5fe218d3>The head uses mono + a neutral background to emphasize its "code / process" nature; the body uses sans for readability. Flat, radius-md, same shape as the Swarm composite card.</div></div></div></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Attention card · floating neutral surface (no color band)</span></div><div class="stage p col" data-v-5fe218d3><div class="p-action" style="max-width:460px;" data-v-5fe218d3><div class="p-action-head" data-v-5fe218d3><span class="p-action-title" data-v-5fe218d3>A decision needs your confirmation</span></div><div class="p-action-body" data-v-5fe218d3>A floating neutral card — no color band. The raised surface, large radius and soft shadow lift it above the transcript; the head is a plain dark title, and the hairline footer lines up quiet text buttons leading to one solid primary action.</div><div class="p-action-foot" data-v-5fe218d3><button class="p-btn ghost sm" data-v-5fe218d3>Dismiss</button><button class="p-btn primary sm" data-v-5fe218d3>Confirm</button></div></div></div></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Activity run · a summary row expands into the folded lines</span></div><div class="stage p col" data-v-5fe218d3><div class="p-tool-group open" style="max-width:460px;" data-v-5fe218d3><div class="p-tool-group-head" data-v-5fe218d3><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tg-title" data-v-5fe218d3>Read 2 files</span></div><div class="p-tool-row" data-v-5fe218d3><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>session.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><span class="tr-chip" data-v-5fe218d3>34 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div><div class="p-tool-row" data-v-5fe218d3><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>middleware.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><span class="tr-chip" data-v-5fe218d3>58 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div></div></div></div><ul class="clean check" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>One structure, two shells</b>: every card is <code data-v-5fe218d3>head / body / foot</code>; operation cards are flat + 0.5px hairline + radius-md with no shadow, while the attention card is the single exception — raised surface, radius-lg and a soft shadow, because it floats above the transcript in place of the composer.</li><li data-v-5fe218d3><b data-v-5fe218d3>Differences are intentional</b>: operation cards keep a compact mono head; attention cards get a plain dark title head and footer actions.</li><li data-v-5fe218d3><b data-v-5fe218d3>Grouping</b>: consecutive activity (thinking + tool calls of any kind, cards included) folds into ONE activity-run row — a smart summary sentence that expands into the items in order; only text and successful media tools (inline media is the turn's output) stay out and break the run (see §04).</li><li data-v-5fe218d3><b data-v-5fe218d3>Turn fold</b>: once an assistant turn settles, everything before its final text block (thinking, activity runs, interim text, standalone cards) folds into ONE bare "Worked Ns" row — no glyph, a faint one-line label + rotating chevron sharing the activity-run head's padding and hover language; while the turn streams the row stays hidden and the body forced open, and on settle the row appears and folds itself back. The span is the turn's elapsed time (daemon duration once settled, server message stamps for history; approval/question waits included by design), reading the generic "Work details" without any stamp. The final text — and anything after it, so trailing media / cards stay on screen — never folds; a text-only turn renders no row at all (see §04).</li><li data-v-5fe218d3><b data-v-5fe218d3>Status dots</b>: running (pulsing blue) / done (green) / failed (red), sharing one color vocabulary (see §04 tool calls).</li></ul><h3 class="sub" data-v-5fe218d3>Input / Select / Textarea</h3><p data-v-5fe218d3>Unified 38px height (32px small), <code data-v-5fe218d3>--radius-md</code> radius, <code data-v-5fe218d3>--color-surface-overlay</code> background, and a unified blue focus ring (<code data-v-5fe218d3>0 0 0 3px accent-soft</code>). Select is a custom combobox and listbox, not a native <code data-v-5fe218d3><select></code>; opening it centres the selected option in the scrollable menu. Open Select roots enter the dropdown layer; containing settings groups temporarily release clipping and join that layer so later sections cannot cover the menu.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Form primitives</span></div><div class="stage p col" data-v-5fe218d3><div class="demo-row" style="align-items:flex-start;" data-v-5fe218d3><div class="p-field demo-grow" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>Workspace name</label><input class="p-input" placeholder="e.g. frontend" data-v-5fe218d3><span class="p-hint" data-v-5fe218d3>Only letters, numbers, and hyphens are allowed.</span></div><div class="p-field demo-grow" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>Model provider</label><button class="p-select" type="button" data-v-5fe218d3>Anthropic</button></div></div><div class="p-field" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>System prompt</label><textarea class="p-textarea" placeholder="Describe this Agent's role and boundaries…" data-v-5fe218d3></textarea></div></div></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>States</span></div><div class="stage p col" data-v-5fe218d3><div class="demo-row" style="align-items:flex-start;" data-v-5fe218d3><div class="p-field demo-grow" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>Workspace name</label><input class="p-input" value="my workspace!" style="border-color:var(--p-danger);" data-v-5fe218d3><span class="p-field-error" data-v-5fe218d3>Please enter a valid workspace name</span></div><div class="p-field demo-grow" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>Display name</label><input class="p-input" value="frontend" data-v-5fe218d3><span class="p-hint" data-v-5fe218d3>Normal state · validation passed</span></div></div></div></div><h3 class="sub" data-v-5fe218d3>Code / Diff</h3><p data-v-5fe218d3><b data-v-5fe218d3>Diff controls</b>: The non-selectable branch summary starts with a 14px branch icon, aligns to the panel header's 12px inset, uses 12px labels, and ends with a 0.5px hairline. List and tree choices use the 14px <code data-v-5fe218d3>list</code> and <code data-v-5fe218d3>tree-view</code> registry icons. Flat-list and tree-view paths use the UI font at 12px. Tree roots share the flat list's 14px content inset, then each depth advances by 12px and adds a grey indentation rule.</p><p data-v-5fe218d3><b data-v-5fe218d3>Diff empty state</b>: Centre the clean-workspace message in the available panel height and lead with a quiet 32px status icon.</p><p data-v-5fe218d3><b data-v-5fe218d3>Diff detail body</b>: the right-side diff detail reuses <code data-v-5fe218d3>HighlightedCode</code> unframed (the panel owns the edge and scroll) — shiki highlighting with the language inferred from the file path, an old/new line-number gutter, hunk headers as a muted band, at the shared code size <code data-v-5fe218d3>--code-font-size</code> (12px at Medium, one step below body text). The file preview's code body (text / JSON / HTML and Markdown source) renders through the same component with a per-row number gutter plus search-hit / jump-target row states.</p><p data-v-5fe218d3>Inline code, code blocks, and diff contents use the monospace font (<code data-v-5fe218d3>--p-font-mono</code>); diff change counts and branch summaries use the UI font. Code blocks have a filename title bar and a copy button; the action edge uses a compact 6px inset. Diffs use <code data-v-5fe218d3>+</code> / <code data-v-5fe218d3>-</code> row colors to express additions and deletions — additions use a success light background, deletions use a danger light background, with no gradients.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Code / Diff</span></div><div class="stage p col" data-v-5fe218d3><span class="stage-label" data-v-5fe218d3>inline code</span><div data-v-5fe218d3>The server uses <code class="p-code-inline" data-v-5fe218d3>jwt.verify(token)</code> to verify the signature, returning 401 on failure.</div><span class="stage-label" data-v-5fe218d3>code block</span><div class="p-code-block" data-v-5fe218d3><div class="p-code-block-head" data-v-5fe218d3><span data-v-5fe218d3>session.ts</span><button class="p-icon-btn sm" aria-label="Copy" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z" data-v-5fe218d3></path></svg></button></div><pre data-v-5fe218d3>import { verify } from './jwt'; + + export function auth(token: string) { + return verify(token, process.env.JWT_SECRET!); + }</pre></div><span class="stage-label" data-v-5fe218d3>diff</span><div class="p-diff" data-v-5fe218d3><div class="p-diff-head" data-v-5fe218d3>session.ts · +3 -1</div><div class="p-diff-row" data-v-5fe218d3><span class="pm" data-v-5fe218d3></span><span class="p-diff-code" data-v-5fe218d3>import { verify } from './jwt';</span></div><div class="p-diff-row del" data-v-5fe218d3><span class="pm" data-v-5fe218d3>-</span><span class="p-diff-code" data-v-5fe218d3>const secret = 'dev-secret';</span></div><div class="p-diff-row add" data-v-5fe218d3><span class="pm" data-v-5fe218d3>+</span><span class="p-diff-code" data-v-5fe218d3>const secret = process.env.JWT_SECRET!;</span></div><div class="p-diff-row" data-v-5fe218d3><span class="pm" data-v-5fe218d3></span><span class="p-diff-code" data-v-5fe218d3>return verify(token, secret);</span></div></div></div></div><h3 class="sub" data-v-5fe218d3>Dialog</h3><p data-v-5fe218d3>One dialog primitive replaces 6 hand-written implementations: unified <code data-v-5fe218d3>--radius-xl</code> radius, <code data-v-5fe218d3>--shadow-xl</code> shadow, 20px head padding, right-aligned footer actions, and an IconButton close button.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Dialog primitive</span></div><div class="stage p col" style="align-items:center;" data-v-5fe218d3><div class="p-dialog" data-v-5fe218d3><div class="p-dialog-head" data-v-5fe218d3><div data-v-5fe218d3><div class="p-dialog-title" data-v-5fe218d3>New chat</div><div class="p-dialog-desc" data-v-5fe218d3>Create an independent Agent chat in the current workspace.</div></div><button class="p-icon-btn sm" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-5fe218d3></path></svg></button></div><div class="p-dialog-body" data-v-5fe218d3><div class="p-field" data-v-5fe218d3><label class="p-label" data-v-5fe218d3>Chat title (optional)</label><input class="p-input" placeholder="Generated automatically" data-v-5fe218d3></div></div><div class="p-dialog-foot" data-v-5fe218d3><button class="p-btn secondary" data-v-5fe218d3>Cancel</button><button class="p-btn primary" data-v-5fe218d3>Create</button></div></div></div></div><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>Size & height</b>: Dialog offers three widths — <code data-v-5fe218d3>md</code> 440 / <code data-v-5fe218d3>lg</code> 640 / <code data-v-5fe218d3>xl</code> 760 (<code data-v-5fe218d3>--p-content-max</code>) — chosen by content weight. Height comes in two kinds: <code data-v-5fe218d3>auto</code> (default, grows with content up to <code data-v-5fe218d3>max-height</code>) and <code data-v-5fe218d3>fixed</code> (constant height <code data-v-5fe218d3>min(680px, 100vh - 64px)</code>, with overflow scrolled inside the body). <b data-v-5fe218d3>Content / multi-tab dialogs</b> (settings, model picker, provider manager, folder browser) always use <code data-v-5fe218d3>fixed</code> so the frame size stays constant and doesn't jump when switching tabs or content length; short confirmation dialogs keep <code data-v-5fe218d3>auto</code>. Selectable controls inside Settings use 0.5px hairlines. Its navigation stays transparent on the grouped canvas — separated from the content region by the 0.5px hairline (horizontal in the stacked mobile layout) — and uses 12px labels at weight 525 with 16px registry icons; the selected tab paints the same neutral <code data-v-5fe218d3>--color-hover</code> wash as hover, with the label simply brightening to <code data-v-5fe218d3>--color-text</code> — the Kimi app settings nav's recipe (<code data-v-5fe218d3>.ss-nav-item--active</code> → <code data-v-5fe218d3>Fills-F1</code>, no accent tint, no weight change); section captions use 16px UI text in <code data-v-5fe218d3>--color-text</code>. Every setting row has a plain-language description; option labels use <code data-v-5fe218d3>--color-text</code> at weight 475 with a 1px gap before that description. Chinese descriptions use “思考” and “计划模式” rather than the English terms; “skills” stays lowercase when it appears within a sentence. Every settings section puts its rows inside one rounded group with 0.5px dividers; the content region paints the flat <code data-v-5fe218d3>--color-surface</code> so each group (<code data-v-5fe218d3>--color-surface-raised</code>) reads one rung above it — never a sunken pit, which would sink the dialog's content below its chrome in dark. The font-size stepper is a compact 32px UI-font control with 12px values and custom minus and plus buttons. Its 52px desktop row centres the control with equal space above and below. Archived workspace headings reuse the sidebar’s <code data-v-5fe218d3>folder-closed</code> registry icon, and Restore actions lead with the <code data-v-5fe218d3>undo</code> icon. Archive counts use weight 500; timestamps and workspace paths use the UI font. </div></div><p data-v-5fe218d3><b data-v-5fe218d3>Dialog backdrop</b>: Use a restrained 28% neutral overlay so the workspace remains legible without competing with the modal.</p><p data-v-5fe218d3><b data-v-5fe218d3>Settings regions</b>: The settings title and close action belong to the right content region. The navigation is a separate full-height region that starts at the dialog's top edge, not content beneath a dialog-wide header.</p><p data-v-5fe218d3><b data-v-5fe218d3>Archived sessions</b>: Start with the localized page title. Do not add a repeated English kicker above it.</p><p data-v-5fe218d3><b data-v-5fe218d3>Settings interaction</b>: Notification labels and descriptions are not selectable; their switches remain fully interactive.</p><p data-v-5fe218d3><b data-v-5fe218d3>Conversation chrome</b>: Header labels are not selectable; the rename input remains selectable and editable. Branch names start with a 14px branch icon. The overflow trigger is a compact 24px control with a 14px icon. Below a 720px header container, hide the workspace prefix and give the conversation title the available width. On macOS desktop the header doubles as the window-drag region and interactive controls opt out with no-drag; while one of its menus or a dock work panel is open every window-drag strip (chat header, sidebar header, panel header) drops the drag region so an outside press anywhere reaches the page and dismisses the overlay (window dragging is simply paused).</p><p data-v-5fe218d3><b data-v-5fe218d3>Session search</b>: follows the §09 flush picker anatomy — a boxed Input under the head, and a result list that fills the body's available height and owns vertical scrolling.</p><p data-v-5fe218d3><b data-v-5fe218d3>Model picker</b>: follows the §09 flush picker anatomy; the provider filter remains horizontally scrollable without showing a persistent scrollbar. Only the model list scrolls; the shortcut bar remains pinned at the bottom.</p><h3 class="sub" data-v-5fe218d3>Toast</h3><p data-v-5fe218d3>Unified information architecture: status icon + title + description. The status color appears only on the icon, avoiding large colored areas that create visual noise. For an <b data-v-5fe218d3>undoable action</b> there is a second, lighter form — the <b data-v-5fe218d3>Action toast</b> (<code data-v-5fe218d3>ActionToast.vue</code>): a pill floating top-center just below the 48px header, carrying a one-line sentence whose actions are plain inline <code data-v-5fe218d3><button></code>s (styled accent by the component), plus close. Self-timed (default 8s, hover pauses); the parent re-keys to reset and wraps it in a <code data-v-5fe218d3><Transition></code>. First used by session archive (Undo / Settings); warnings keep the bottom-right <code data-v-5fe218d3>Toast</code> stack.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Toast</span></div><div class="stage p col" data-v-5fe218d3><div class="p-toast success" data-v-5fe218d3><span class="ti" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg></span><div data-v-5fe218d3><div class="tt" data-v-5fe218d3>Connected to server</div><div class="td" data-v-5fe218d3>The local server is responding normally; you can start a new chat.</div></div></div><div class="p-toast warning" data-v-5fe218d3><span class="ti" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z" data-v-5fe218d3></path></svg></span><div data-v-5fe218d3><div class="tt" data-v-5fe218d3>Context usage 82%</div><div class="td" data-v-5fe218d3>Consider running /compact to free up space.</div></div></div></div></div><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Action toast</span></div><div class="stage p col" data-v-5fe218d3><div class="p-action-toast" data-v-5fe218d3><button class="lk" data-v-5fe218d3>Undo</button><span data-v-5fe218d3>or view archived chats in</span><button class="lk" data-v-5fe218d3>Settings</button><svg class="p-ic x" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path d="M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z" data-v-5fe218d3></path></svg></div></div></div><h3 class="sub" data-v-5fe218d3>Spinner</h3><p data-v-5fe218d3>Loaders fall into two categories by scenario — <b data-v-5fe218d3>do not mix them</b>:</p><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>Spinner (plain · SVG ring)</b> —— the default loader. Used for button loading, app startup (GlobalLoading), and general inline waits — "everything else".</li><li data-v-5fe218d3><b data-v-5fe218d3>WorkingIndicator (小蓝 mascot · brand signature)</b> —— used <b data-v-5fe218d3>only</b> for the chat working state after a prompt is sent (the sending placeholder in ChatPane, the send → first-token loading in SideChatPanel). The label follows the phase: "Requesting…" until the assistant's reply starts, then "Working…".</li></ul><h4 class="mini" data-v-5fe218d3>Spinner · plain loader (default)</h4>`,39)),a("div",Y,[e[18]||(e[18]=a("div",{class:"stage-bar"},[a("span",{class:"st"},"Spinner · common scenarios")],-1)),a("div",Z,[a("div",X,[e[17]||(e[17]=t('<svg class="p-spinner" viewBox="0 0 24 24" data-v-5fe218d3><circle class="track" cx="12" cy="12" r="9" data-v-5fe218d3></circle><circle class="arc" cx="12" cy="12" r="9" data-v-5fe218d3></circle></svg><span class="p-thinking" data-v-5fe218d3><svg class="p-spinner sm" viewBox="0 0 24 24" data-v-5fe218d3><circle class="track" cx="12" cy="12" r="9" data-v-5fe218d3></circle><circle class="arc" cx="12" cy="12" r="9" data-v-5fe218d3></circle></svg>Loading…</span>',2)),a("button",$,[(o(),i("svg",ee,[...e[15]||(e[15]=[a("circle",{class:"track",cx:"12",cy:"12",r:"9"},null,-1),a("circle",{class:"arc",cx:"12",cy:"12",r:"9"},null,-1)])])),e[16]||(e[16]=d("Submitting",-1))])])])]),e[29]||(e[29]=a("h4",{class:"mini"},"WorkingIndicator · 小蓝 mascot (only the chat working state)",-1)),a("div",ae,[e[20]||(e[20]=a("div",{class:"stage-bar"},[a("span",{class:"st"},[d("WorkingIndicator · chat working state only "),a("span",{class:"tag spec"},"signature")])],-1)),a("div",te,[e[19]||(e[19]=a("span",{class:"stage-label"},"Usage · only while the chat has an unfinished prompt",-1)),a("div",de,[c(k,{label:"Requesting…"}),c(k,{label:"Working…"})])])]),e[30]||(e[30]=t('<div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3>The chat working state is rendered uniformly by <code data-v-5fe218d3>WorkingIndicator</code> — the 小蓝 mascot (<code data-v-5fe218d3>KimiMascot</code>, the kimi.com avatar Rive asset, with a static SVG fallback under reduced motion or when the runtime fails) plus a phase label. All other loading states use the plain Spinner.</div></div><h3 class="sub" data-v-5fe218d3>Link</h3><p data-v-5fe218d3>Inline text link: the default is the accent color with no underline; on hover it shows an underline and darkens. File links inside inline code use a 1.5px underline offset so the line stays clear of the chip background. The <code data-v-5fe218d3>.muted</code> variant uses the secondary text color. Used for in-text jumps, external links, "view all", and other lightweight actions.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Link · inline link</span></div><div class="stage p col" data-v-5fe218d3><div class="demo-row" style="font-size:var(--p-font-size-base);color:var(--p-text);" data-v-5fe218d3><span data-v-5fe218d3>Read the full <a class="p-link" href="#" data-v-5fe218d3>design token docs</a> before building.</span><a class="p-link" href="#" data-v-5fe218d3>View on GitHub<svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z" data-v-5fe218d3></path></svg></a><a class="p-link muted" href="#" data-v-5fe218d3>View history</a></div></div></div><h3 class="sub" data-v-5fe218d3>Menu / Dropdown</h3><p data-v-5fe218d3>Desktop menus use a 3.5px panel inset. Standard items use 5px × 9px padding and a 7px icon gap. Their three-layer neutral shadow stays below 4% opacity.</p><p data-v-5fe218d3>Dropdown menu panel: frosted glass — the translucent <code data-v-5fe218d3>--color-menu-bg</code> fill over a blurred, saturated page backdrop (<code data-v-5fe218d3>--p-menu-backdrop</code>) — plus hairline + light shadow (<code data-v-5fe218d3>--shadow-menu</code>, a three-layer neutral ramp). This is the one place glassmorphism is the design language rather than an exception (§06); every floating menu surface (Menu.vue, the Select listbox, composer dropdowns, slash/mention popups) uses the token pair, never ad-hoc blur values. Menu items support icons, the current (active) state, the danger state, and the disabled state, with separators grouping items. All menu actions use 13px labels at weight 475 with 16px leading icons; both share a 16px line box for vertical alignment. Menu timestamps use the UI font. On touch / mobile, use <code data-v-5fe218d3>lg</code> (≥44px row height) while keeping the same type size. A dropdown menu pops in from its trigger corner — fade plus a slight 0.97 scale over <code data-v-5fe218d3>--duration-base</code> (exit <code data-v-5fe218d3>--duration-fast</code>), the composer model dropdown's motion language; the transform origin and the nudge direction follow the anchoring, including the upward flip near the viewport edge.</p><p data-v-5fe218d3>Row states: hover uses the mode-aware <code data-v-5fe218d3>--color-hover</code> wash (it lightens under dark, never darkens); a leading icon sits one rung below the label (<code data-v-5fe218d3>--muted</code>), and on hover both label and icon step up to <code data-v-5fe218d3>--color-text-strong</code>, the max foreground tier. Selection keeps the accent pair (<code data-v-5fe218d3>--color-accent-soft</code> / <code data-v-5fe218d3>--color-accent-hover</code>); danger keeps its own colour.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Menu · dropdown menu</span></div><div class="stage p col" style="align-items:flex-start;" data-v-5fe218d3><div class="p-menu" data-v-5fe218d3><div class="p-menu-item" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg>Open file</div><div class="p-menu-item active" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg>Selected item</div><div class="p-menu-item disabled" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M8.523 7.109l8.368 8.368a6 6 0 0 1-1.414 1.414L7.109 8.523A6 6 0 0 1 8.523 7.11" data-v-5fe218d3></path></svg>Disabled item</div><div class="p-menu-sep" data-v-5fe218d3></div><div class="p-menu-item danger" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-5fe218d3></path></svg>Delete chat</div></div></div></div><h3 class="sub" data-v-5fe218d3>SegmentedControl</h3><p data-v-5fe218d3>Mutually exclusive short option groups, commonly used for 2–5 option switches such as "light / dark / follow system" or the four font-scale steps. Options may include a 14px registry icon or a colour swatch. A single raised indicator with a soft shadow (no border — the edge stays clean) slides and resizes between options using the standard motion tokens. Three sizes: <code data-v-5fe218d3>md</code> (default, settings pages), <code data-v-5fe218d3>sm</code> (compact rows), and <code data-v-5fe218d3>xs</code> (dense menus such as the composer model dropdown — 20px items, 12px labels).</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>SegmentedControl</span></div><div class="stage p col" data-v-5fe218d3><div class="p-seg" data-v-5fe218d3><span class="p-seg-item on" data-v-5fe218d3>Light</span><span class="p-seg-item" data-v-5fe218d3>Dark</span><span class="p-seg-item" data-v-5fe218d3>Follow system</span></div></div></div><h3 class="sub" data-v-5fe218d3>SecondaryModelPicker</h3><p data-v-5fe218d3>Linked model + thinking-effort picker (settings → Agent → Subagents, experimental; <code data-v-5fe218d3>components/settings/SecondaryModelPicker.vue</code>, shared by both ends). Use it whenever two choices are only valid as a pair — here an effort is meaningless without its model, and every model declares a different supported set. It is a cascading variant of the §03 Select: the trigger is the Select trigger verbatim (value renders <code data-v-5fe218d3>model · effort</code>, the unset state uses the placeholder tint), and the dropdown opens as a SINGLE-LEVEL model list (grouped by provider) on the floating menu surface (<code data-v-5fe218d3>--color-menu-bg</code> / <code data-v-5fe218d3>--p-menu-backdrop</code> / <code data-v-5fe218d3>--shadow-lg</code>). The menu <b data-v-5fe218d3>teleports to <code data-v-5fe218d3><body></code> with <code data-v-5fe218d3>position: fixed</code></b> — it opens on top of the settings modal (on the <code data-v-5fe218d3>--z-modal-dropdown</code> rung), and only a body-level surface escapes the dialog's scrolling-body clip; it re-anchors to the trigger on any outside scroll and closes on window resize (the UserMenu teleport's full recipe). Hovering or clicking a model row flies its effort submenu out to the RIGHT of the row — same menu surface, anchored to the row's live position, flipping to the left only near the viewport edge per the §03 anchoring rules — with a 250ms hover-intent grace (the UserMenu flyout's recipe) so the diagonal path into the submenu doesn't collapse it. Every model row carries a trailing <code data-v-5fe218d3>chevron-right</code> affordance; clicking an effort confirms the pair and closes — one atomic write, never two staggered patches. Flyout options follow the composer's thinking-level model (<code data-v-5fe218d3>segmentsFor</code>): effort models get <code data-v-5fe218d3>off</code> + their declared levels (always-thinking ones get no off), boolean-thinking models get <code data-v-5fe218d3>on</code>/<code data-v-5fe218d3>off</code>, unsupported models get <code data-v-5fe218d3>off</code> alone; while no effort is set at all, a "Model default" entry leads (it writes the model alone — POST /config merges and cannot clear a stored effort, so the entry disappears once one is set). A configured effort the model no longer declares is appended as an extra flyout option so the current pair stays visible and re-selectable. Keyboard mirrors the Select contract (focus stays on the trigger, Esc <code data-v-5fe218d3>preventDefault</code>s so the hosting dialog does not close): ↑/↓ move within the active level (the flyout follows model moves), → opens the flyout, ← collapses it, Enter confirms, Home/End jump. ARIA: combobox trigger → <code data-v-5fe218d3>dialog</code> menu holding a model <code data-v-5fe218d3>listbox</code> plus the effort <code data-v-5fe218d3>listbox</code> flyout with <code data-v-5fe218d3>option</code> rows. The menu itself flips upward when the trigger sits near the viewport bottom.</p><h3 class="sub" data-v-5fe218d3>Tabs</h3><p data-v-5fe218d3>Tabs with a bottom hairline, used for grouping and switching sibling content. The current tab is marked with accent text + an accent underline.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Tabs</span></div><div class="stage p col" data-v-5fe218d3><div class="p-tabs" data-v-5fe218d3><span class="p-tab on" data-v-5fe218d3>General</span><span class="p-tab" data-v-5fe218d3>Agent</span><span class="p-tab" data-v-5fe218d3>Advanced</span></div></div></div><h3 class="sub" data-v-5fe218d3>Switch</h3><p data-v-5fe218d3>A two-state switch for settings that take effect immediately. The 36×20 track has a 0.5px hairline and full radius; its 16px knob uses 1.5px internal offsets so the visible inset remains 2px and symmetric after accounting for the border. On hover, the knob eases to an 18px rounded rectangle towards the track centre. When on, the track turns accent and the knob slides right.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Switch</span></div><div class="stage p" data-v-5fe218d3><span class="p-switch on" data-v-5fe218d3></span><span class="p-switch" data-v-5fe218d3></span></div></div><h3 class="sub" data-v-5fe218d3>Checkbox</h3><p data-v-5fe218d3>A 17×17 checkbox. When checked it fills with the accent color and shows a white tick (inline SVG). Often paired with a text label.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Checkbox</span></div><div class="stage p" data-v-5fe218d3><span class="p-check on" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg></span><span class="p-check" data-v-5fe218d3></span><label style="display:inline-flex;align-items:center;gap:8px;color:var(--p-text);font-size:var(--p-font-size-base);cursor:pointer;" data-v-5fe218d3><span class="p-check on" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg></span>Enable auto-save</label></div></div><h3 class="sub" data-v-5fe218d3>Avatar</h3><p data-v-5fe218d3>A 32px default avatar with md radius; <code data-v-5fe218d3>.sm</code> is 24px. Can hold an initial or an icon; falls back to this placeholder when there is no image.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Avatar</span></div><div class="stage p" data-v-5fe218d3><span class="p-avatar" data-v-5fe218d3>K</span><span class="p-avatar" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 0 0-12 0zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6s6 2.685 6 6s-2.685 6-6 6m0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4s-4 1.79-4 4s1.79 4 4 4" data-v-5fe218d3></path></svg></span><span class="p-avatar sm" data-v-5fe218d3>K</span></div></div><h3 class="sub" data-v-5fe218d3>EmptyState</h3><p data-v-5fe218d3>A centered placeholder for empty lists / panels: a 48px faint icon + title + hint, avoiding blank pages.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>EmptyState</span></div><div class="stage p col" data-v-5fe218d3><div class="p-empty" style="width:100%;border:0.5px dashed var(--p-line);border-radius:var(--p-r-lg);" data-v-5fe218d3><svg class="em-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1zm-.692-2H20V5H4v13.385zM8 10h8v2H8z" data-v-5fe218d3></path></svg><div class="em-title" data-v-5fe218d3>No chats yet</div><div class="em-hint" data-v-5fe218d3>Click "New chat" to start a conversation with Kimi</div></div></div></div><h3 class="sub" data-v-5fe218d3>Divider</h3><p data-v-5fe218d3>A 0.5px hairline divider (<code data-v-5fe218d3>--p-line</code>); <code data-v-5fe218d3>.p-divider-v</code> is the vertical divider, used between inline elements.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Divider</span></div><div class="stage p col" data-v-5fe218d3><div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-5fe218d3>Content above</div><hr class="p-divider" data-v-5fe218d3><div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-5fe218d3>Content below</div><div style="display:flex;align-items:center;gap:10px;height:24px;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-5fe218d3><span data-v-5fe218d3>kimi-k2</span><span class="p-divider-v" data-v-5fe218d3></span><span data-v-5fe218d3>thinking</span></div></div></div><h3 class="sub" data-v-5fe218d3>Tooltip</h3><p data-v-5fe218d3>A CSS-only hover hint, wrapped in <code data-v-5fe218d3>.p-tip</code>. Inverted background (<code data-v-5fe218d3>--p-text</code> / <code data-v-5fe218d3>--p-bg</code>), single line, no wrapping — carries only short notes.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Tooltip (hover the button)</span></div><div class="stage p" data-v-5fe218d3><span class="p-tip" data-v-5fe218d3><button class="p-icon-btn" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-5fe218d3></path></svg></button><span class="p-tooltip" data-v-5fe218d3>New chat</span></span></div></div><h3 class="sub" data-v-5fe218d3>Banner</h3><p data-v-5fe218d3>An inline notice bar placed at the top of a content area. Three states — <code data-v-5fe218d3>.info</code> / <code data-v-5fe218d3>.warning</code> / <code data-v-5fe218d3>.danger</code> — each with a matching 18px icon.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Banner</span></div><div class="stage p col" data-v-5fe218d3><div class="p-banner info" data-v-5fe218d3><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M11 7h2v2h-2zm0 4h2v6h-2z" data-v-5fe218d3></path></svg>Connected to server</div><div class="p-banner warning" data-v-5fe218d3><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z" data-v-5fe218d3></path></svg>Currently in yolo mode; tool calls will run automatically</div></div></div><h3 class="sub" data-v-5fe218d3>Sheet / BottomSheet</h3><p data-v-5fe218d3>A mobile bottom slide-up panel: xl top radius + drag handle, xl shadow. At ≤640px, dialogs become bottom-anchored Sheets.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>BottomSheet</span></div><div class="stage p col" style="align-items:center;" data-v-5fe218d3><div class="p-sheet" style="width:100%;max-width:360px;" data-v-5fe218d3><div class="p-sheet-handle" data-v-5fe218d3></div><div style="font-size:var(--p-font-size-base);font-weight:700;color:var(--p-text);margin-bottom:8px;" data-v-5fe218d3>Choose a model</div><div class="p-menu-item" style="padding:8px 10px;" data-v-5fe218d3>kimi-k2 · thinking</div><div class="p-menu-item" style="padding:8px 10px;" data-v-5fe218d3>kimi-k2 · instant</div></div></div></div><h3 class="sub" data-v-5fe218d3>Skeleton</h3><p data-v-5fe218d3>A placeholder for loading content, using a breathing opacity animation (no gradients), following the <code data-v-5fe218d3>no-gradient-text</code> rule. Composed into titles / text lines / avatars.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Skeleton</span></div><div class="stage p col" data-v-5fe218d3><div style="display:flex;flex-direction:column;gap:10px;width:100%;max-width:360px;" data-v-5fe218d3><div class="p-skeleton" style="height:16px;width:55%;" data-v-5fe218d3></div><div class="p-skeleton" style="height:12px;width:100%;" data-v-5fe218d3></div><div class="p-skeleton" style="height:12px;width:82%;" data-v-5fe218d3></div><div class="p-skeleton" style="height:32px;width:32px;border-radius:var(--p-r-full);" data-v-5fe218d3></div></div></div></div><h3 class="sub" data-v-5fe218d3>Command Bar</h3><p data-v-5fe218d3>An inline combination of "primary action + command text + copy", sitting between a button and a code block — used for install / onboarding / one-click execution. The primary action reuses <code data-v-5fe218d3>Button primary</code>; the command area uses a mono light-grey background.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Command Bar</span></div><div class="stage p col" data-v-5fe218d3><div class="p-cmdbar" style="max-width:620px;" data-v-5fe218d3><button class="p-btn primary" data-v-5fe218d3>Install Kimi Web ▾</button><span class="p-cmd" data-v-5fe218d3><span class="cmd-text" data-v-5fe218d3>curl -fsSL https://code.kimi.com/install.sh | bash</span><button class="cmd-copy" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z" data-v-5fe218d3></path></svg></button></span></div></div></div><h3 class="sub" data-v-5fe218d3>TopBar</h3><p data-v-5fe218d3>The application top bar. Solid by default; the <code data-v-5fe218d3>.frost</code> variant is translucent + background blur, used <b data-v-5fe218d3>only for sticky navigation bars</b>. Together with the floating menu surfaces (Menu / Dropdown), it is one of the two exceptions to the <code data-v-5fe218d3>no-glassmorphism</code> rule (see §06).</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>TopBar · solid / frosted glass</span></div><div class="stage p col" style="gap:14px;background:radial-gradient(circle at 18% 30%,rgba(23,131,255,.16),transparent 42%),radial-gradient(circle at 82% 75%,rgba(20,23,28,.10),transparent 46%),var(--p-surface-sunken);" data-v-5fe218d3><div class="p-topbar" style="width:100%;max-width:580px;" data-v-5fe218d3><span class="tb-title" data-v-5fe218d3>Solid TopBar</span><span class="tb-actions" data-v-5fe218d3><button class="p-icon-btn sm" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-5fe218d3></path></svg></button></span></div><div class="p-topbar frost" style="width:100%;max-width:580px;" data-v-5fe218d3><span class="tb-title" data-v-5fe218d3>Frosted-glass TopBar · .frost</span><span class="tb-actions" data-v-5fe218d3><button class="p-icon-btn sm" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-5fe218d3></path></svg></button></span></div></div></div><h3 class="sub" data-v-5fe218d3>Find Bar · transcript search</h3><p data-v-5fe218d3>The in-transcript find bar (Cmd/Ctrl+F), implemented by <code data-v-5fe218d3>components/chat/TranscriptSearch.vue</code>. A floating card pinned to the transcript's top-right (<code data-v-5fe218d3>top: --panel-head-h + --space-3</code>, <code data-v-5fe218d3>right: --space-3</code> — equal inset on both axes), <code data-v-5fe218d3>--z-sticky</code>, raised surface + 0.5px hairline + <code data-v-5fe218d3>--shadow-menu</code>. <b data-v-5fe218d3>One radius for both states</b>: <code data-v-5fe218d3>--radius-2xl</code> is a full capsule at the collapsed height and a card once the footer expands — never animate between two radii.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Part</th><th data-v-5fe218d3>Rule</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Input row</td><td data-v-5fe218d3>Search icon (muted) + <b data-v-5fe218d3>bare input</b> — the list-style bare-input exception family (sidebar search row, inline rename), NOT the boxed Input primitive; the 38px bordered control would break the pill. Circular close <code data-v-5fe218d3>IconButton sm</code> (concentric with the capsule end); a 0.5px hairline separator before it. Height comes from the grid: 32px control (<code data-v-5fe218d3>--space-8</code>) + 2× <code data-v-5fe218d3>--space-1</code> padding = 40px — at which <code data-v-5fe218d3>--radius-2xl</code> is exactly the half-height capsule.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Footer (results)</td><td data-v-5fe218d3>Expands via the 0fr→1fr grid fold (<code data-v-5fe218d3>--duration-slow</code>), hairline top separator, prev/next <code data-v-5fe218d3>IconButton sm</code> left, right-aligned muted count (<code data-v-5fe218d3>N/M results</code> · <code data-v-5fe218d3>--ui-font-size-sm</code>). Only exists once a query has settled — while typing or empty, the bar stays a bare pill.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>States</td><td data-v-5fe218d3>collapsed (empty query) / searching (<code data-v-5fe218d3>Spinner sm</code> in the input row during the ~800ms debounce) / results / no-results (count reads "No results", nav disabled). Disabled is uniformly <code data-v-5fe218d3>opacity:.5</code>.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Focus</td><td data-v-5fe218d3>Composer-style: a neutral hairline overlay (<code data-v-5fe218d3>::after</code> + <code data-v-5fe218d3>--color-composer-focus-line</code>) fading in on <code data-v-5fe218d3>:focus-within</code>. No accent ring.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Match ink</td><td data-v-5fe218d3>CSS Custom Highlight API — the bar mutates no transcript DOM. All matches: <code data-v-5fe218d3>--color-search-match</code> (yellow); current: <code data-v-5fe218d3>--color-search-match-current</code> + a 2px <code data-v-5fe218d3>--color-warning</code> outline ring (a positioned overlay — highlight pseudos can't paint box outlines). Tokens live in <code data-v-5fe218d3>app-ui/style.css</code> with light/dark pairs.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Keyboard</td><td data-v-5fe218d3>Cmd/Ctrl+F opens + focuses (repeat = re-focus + select-all; hardcoded, reserved in the desktop keymap), Enter / Shift+Enter steps matches (wrapping), Esc closes from ANY control inside (container-level, so it never reaches the conversation's Esc-abort).</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Matching semantics</td><td data-v-5fe218d3>Rendered transcript DOM only (unloaded older pages are out of scope), capped at 1000 matches (count reads <code data-v-5fe218d3>N/1000+</code>). Matches span inline nodes within one block, never cross block breaks; <code data-v-5fe218d3>inert</code> and <code data-v-5fe218d3>display:none</code> content is excluded. Stepping scrolls the match's own rect into view, not its parent element.</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>SectionLabel</h3><p data-v-5fe218d3>A small group title for sidebar lists, used to section the content below (such as <code data-v-5fe218d3>Workspaces</code> in the sidebar). Spec: 13px / 700 / uppercase / letter-spacing <code data-v-5fe218d3>.08em</code>, color <code data-v-5fe218d3>--color-fg-faint</code>; left-aligned to the row's starting padding (<code data-v-5fe218d3>--sb-pad-x</code>), keeping the same indent as the group rows below. For scripts without case (such as Chinese), <code data-v-5fe218d3>text-transform:uppercase</code> simply has no effect — no special handling needed.</p>',55)),a("div",se,[e[26]||(e[26]=a("div",{class:"stage-bar"},[a("span",{class:"st"},"Sidebar · group title")],-1)),a("div",oe,[e[25]||(e[25]=a("div",{class:"p-section-label",style:{padding:"12px 16px 4px"}},"Workspaces",-1)),a("div",ie,[(o(),i("svg",ne,[...e[21]||(e[21]=[a("path",{fill:"currentColor",d:"M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])),e[22]||(e[22]=d(" kimi-code-web ",-1))]),a("div",le,[(o(),i("svg",re,[...e[23]||(e[23]=[a("path",{fill:"currentColor",d:"M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])),e[24]||(e[24]=d(" playground ",-1))])])])]),a("section",ce,[e[39]||(e[39]=t('<div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>04</span><h2 class="sec-title" data-v-5fe218d3>Chat Interface Overhaul</h2></div><p class="sec-desc" data-v-5fe218d3> The message stream is the core of Kimi Web. Tool calls render as <b data-v-5fe218d3>quiet activity lines</b> — one borderless line per call, bespoke per tool kind, auto-grouped, expanding on demand — while Question / Approval elevate to a <b data-v-5fe218d3>floating neutral surface</b> because they need a decision, and the Swarm composite keeps a card; the Composer collapses into a single rounded container. </p><h3 class="sub" data-v-5fe218d3>Unified message stream</h3><p data-v-5fe218d3>User-message bubbles follow the kimiwork production recipe (<code data-v-5fe218d3>MessageItem .user-bubble</code>): a neutral <code data-v-5fe218d3>--color-user-bubble-bg</code> fill (BubbleGray — <code data-v-5fe218d3>#f5f5f5</code> light / <code data-v-5fe218d3>#292929</code> dark), uniform <code data-v-5fe218d3>--radius-lg</code> corners, no border, no shadow.</p><p data-v-5fe218d3>Message timestamps use 12px UI text at weight 500, matching the compact metadata scale without switching to a monospace face.</p><p data-v-5fe218d3>The user-message metadata row sits one 8px spacing step below the bubble, so its actions and timestamp read as supporting information rather than part of the bubble edge.</p><p data-v-5fe218d3>Overlong user messages clamp at 10 measured lines, the tail dissolving through an alpha mask rather than a tint overlay (the translucent accent fill would double-composite); a floating pill toggle centred on the fade expands in place and collapses back, and the collapse pins the toggle itself so the reading position survives. Skill / plugin command args clamp through the same wrapper, beside the card head. Like the transcript's other disclosure controls (thinking row, turn fold, tool lines), the toggle is a bare native button carrying <code data-v-5fe218d3>aria-expanded</code> — chat-surface disclosure controls do not use the §03 Button primitive.</p><p data-v-5fe218d3>The floating jump-to-latest control uses 12px UI text at weight 525, led by the full down-arrow icon rather than a disclosure caret.</p><p data-v-5fe218d3>Thinking is an inline, borderless disclosure row in the message stream — never a side panel. The k15 bulb (the <code data-v-5fe218d3>thinking</code> registry icon) leads the row in every state; while streaming the "Thinking…" label breathes (opacity only, never a gradient shimmer) and whole elapsed seconds tick beside it, afterwards the label settles to "Thinking process" with the final span as <code data-v-5fe218d3>· Ns</code> (renderer-measured, live sessions only — history shows no seconds). Collapsed by default, it expands in place with the standard grid-rows animation and a 90° chevron rotation, and it folds itself back once the stream moves past it, even if the user expanded mid-stream. The header only animates its text colour on hover (standard duration and easing tokens), no card shell.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Conversation · 760px reading column</span></div><div class="stage p col" style="align-items:center;background:#fff;" data-v-5fe218d3><div class="demo-chat" data-v-5fe218d3><div class="p-bubble-user" data-v-5fe218d3>Please change the login endpoint to JWT and add the corresponding unit tests.</div><span class="p-thinking" data-v-5fe218d3><span style="font-size:15px;line-height:1;" data-v-5fe218d3>🌔</span>Analyzing the auth module…</span><div class="p-tool-group open" data-v-5fe218d3><div class="p-tool-group-head" data-v-5fe218d3><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tg-title" data-v-5fe218d3>Read 2 files</span><svg class="tg-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg></div><div class="p-tool-row expanded" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>session.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth · :12-45</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>34 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div><div class="p-tool-detail" data-v-5fe218d3><div class="p-code" data-v-5fe218d3>12 export function verify(token: string) {<br data-v-5fe218d3>13 return jwt.verify(token, getSecret());<br data-v-5fe218d3>14 }</div></div><div class="p-tool-row" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>middleware.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>58 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div></div><div class="p-tool-row" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414 1.414l1.414-1.414l-1.414-1.414l-1.414 1.414zM4 21h16v-2H4v2z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Edit</span><span class="tr-file" data-v-5fe218d3>middleware.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-add" data-v-5fe218d3>+12</span><span class="tr-del" data-v-5fe218d3>−4</span><span class="tr-bar" aria-hidden="true" data-v-5fe218d3><span style="flex:12;background:var(--p-success);" data-v-5fe218d3></span><span style="flex:4;background:var(--p-danger);" data-v-5fe218d3></span></span><span class="tr-ok" data-v-5fe218d3>✓</span></div><div class="p-tool-row" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Search</span><span class="tr-mono" data-v-5fe218d3>"jwt.verify"</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>4 results</span><span class="tr-ok" data-v-5fe218d3>✓</span></div><div class="p-msg" data-v-5fe218d3><p data-v-5fe218d3>I looked at the structure of <code data-v-5fe218d3>src/auth</code>; it is currently based on a session cookie. The scope of the change is below — once you confirm, I'll start.</p></div><div class="p-action" data-v-5fe218d3><div class="p-action-head" data-v-5fe218d3><span class="p-action-title" data-v-5fe218d3>A decision needs your confirmation</span></div><div class="p-action-body" data-v-5fe218d3>How long should the JWT expiry be? Default 7 days, refresh token 30 days.</div><div class="p-action-foot" data-v-5fe218d3><button class="p-btn ghost sm" data-v-5fe218d3>Customize</button><button class="p-btn primary sm" data-v-5fe218d3>Use default</button></div></div><div class="p-action" data-v-5fe218d3><div class="p-action-head" data-v-5fe218d3><span class="p-action-title" data-v-5fe218d3>Write permission required</span></div><div class="p-action-body" data-v-5fe218d3>About to modify <code data-v-5fe218d3>src/auth/middleware.ts</code>, 42 lines changed. Allow?</div><div class="p-action-foot" data-v-5fe218d3><button class="p-btn primary sm" data-v-5fe218d3>Allow this time</button><button class="p-btn ghost sm" data-v-5fe218d3>Always allow</button><button class="p-btn ghost sm" data-v-5fe218d3>Deny</button></div></div><div class="p-todo" data-v-5fe218d3><div class="p-todo-row done" data-v-5fe218d3><span class="p-todo-check" data-v-5fe218d3><svg viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-5fe218d3></path></svg></span>Replace session with JWT signing</div><div class="p-todo-row active" data-v-5fe218d3><span class="p-todo-check" data-v-5fe218d3><svg viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><circle cx="12" cy="12" r="3.5" data-v-5fe218d3></circle></svg></span>Refactor the auth middleware</div><div class="p-todo-row" data-v-5fe218d3><span class="p-todo-check" data-v-5fe218d3><svg viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><circle cx="12" cy="12" r="3.5" data-v-5fe218d3></circle></svg></span>Add unit tests</div></div></div></div></div><p data-v-5fe218d3><b data-v-5fe218d3>Wide markdown tables (desktop):</b> regular chat prose stays within the 760px reading column (<code data-v-5fe218d3>--p-content-max</code>), and tables stay there too by default — an overflowing table scrolls horizontally inside its own wrapper, so the page and the chat area never scroll sideways. A clipped table shows a gradient fade at its truncated right edge, and hovering the table reveals a small widen button at its top-right corner; clicking it lets the table grow naturally with its content up to 1040px (<code data-v-5fe218d3>--p-table-max</code>), centred within the conversation pane, and clicking again restores the default width. At the default width a single column is capped at 36% of the pane; once widened the cap relaxes to 700px (<code data-v-5fe218d3>--p-table-cell-max</code>), so long cell content wraps inside the cell instead of stretching the table. The conversation outline (TOC) keeps its usual position just outside the reading column; when a widened table grows past it and scrolls under the rail, the TOC is hidden temporarily and returns as soon as the table leaves, without touching the user's TOC setting. On mobile a table never breaks out of the reading column.</p><h3 class="sub" data-v-5fe218d3>Tool calls: quiet activity lines, bespoke per tool</h3><p data-v-5fe218d3>High-frequency calls like <code data-v-5fe218d3>read</code> / <code data-v-5fe218d3>bash</code> / <code data-v-5fe218d3>grep</code> are "operational noise" — boxed, collapsible cards quickly drown out the conversation. Tool calls therefore render as <b data-v-5fe218d3>one quiet borderless line</b> in the message stream — never a card — and each tool kind composes that line for its own content, so the stream reads like an activity log rather than a pile of widgets. The three visual-weight tiers:</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Three visual-weight tiers</span></div><div class="stage p col" data-v-5fe218d3><span class="stage-label" data-v-5fe218d3>① Tool line · lightest (default) — bespoke content per tool, no card chrome</span><div class="p-tool-row" style="align-self:stretch;" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm3 3h5v2H7V8zm0 4h8v2H7v-2z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Run</span><span class="tr-mono" data-v-5fe218d3>pnpm run build && pnpm lint</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>0.8s</span><span class="tr-ok" data-v-5fe218d3>✓</span></div><span class="stage-label" data-v-5fe218d3>② Activity run · medium (consecutive quiet activity — thinking + tool lines — folds to one smart-summary row)</span><div class="p-tool-group" data-v-5fe218d3><div class="p-tool-group-head" data-v-5fe218d3><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tg-title" data-v-5fe218d3>Read 3 files</span><svg class="tg-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg></div></div><span class="stage-label" data-v-5fe218d3>③ Sub Agent identity card · one per delegation — task title + agent type; the whole card opens the side panel (no in-stream expansion, never grouped)</span><div class="p-agent-card" data-v-5fe218d3><span class="pa-ic" data-v-5fe218d3><svg viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M13.5 2c0 .444-.193.843-.5 1.118V5h5a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3h5V3.118A1.5 1.5 0 1 1 13.5 2M6 7a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1zm-4 3H0v6h2zm20 0h2v6h-2zM9 14.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m6 0a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3" data-v-5fe218d3></path></svg></span><span class="pa-main" data-v-5fe218d3><span class="pa-task" data-v-5fe218d3>分析双引擎架构</span><span class="pa-type" data-v-5fe218d3>Explore</span></span><span class="pa-ok" data-v-5fe218d3>✓</span><span class="pa-go" data-v-5fe218d3>→</span></div><span class="stage-label" data-v-5fe218d3>④ Decision card · heavy (only question / approval, needs user input)</span><div class="p-action" data-v-5fe218d3><div class="p-action-head" data-v-5fe218d3><span class="p-action-title" data-v-5fe218d3>Write permission required</span></div><div class="p-action-body" data-v-5fe218d3>About to modify <code data-v-5fe218d3>src/auth/middleware.ts</code>, 42 lines changed.</div></div></div></div><ul class="clean check" data-v-5fe218d3><li data-v-5fe218d3>A tool call renders as <b data-v-5fe218d3>one quiet borderless line</b> (~24px, the thinking row's rhythm): leading glyph, tool-specific content, trailing meta + status. There is no card chrome and no hover wash — the chevron hugging the line's text (thinking-row style, never pushed to the far edge) is the only disclosure affordance, a real <code data-v-5fe218d3><button></code> carrying <code data-v-5fe218d3>aria-expanded</code> (keyboard path); the head itself is a plain click target (mouse path), so trailing slots may hold genuine buttons of their own (e.g. Agent's "open detail").</li><li data-v-5fe218d3><b data-v-5fe218d3>One type scale for the whole stream</b>: thinking rows, fold summary rows and tool lines all set 13px UI text; in-line mono and trailing meta run one step down at 12px (a monospace x-height reads larger, so 12px sits level next to 13px). Hierarchy comes from colour, never from size jumps or bold — everything on the line is regular weight: the only dark object is the file-name button (<code data-v-5fe218d3>--color-text</code> — the one interactive place to go); the action label (Run / Read / Edit…), the mono command / pattern and secondary context all sit at <code data-v-5fe218d3>--color-text-muted</code>; auxiliary elements (glyphs, chevrons, trailing meta) stay <code data-v-5fe218d3>--color-text-faint</code>. The stream thus reads in three quiet tiers: prose in text, tool lines in muted, thinking / captions in faint. Line content is centre-aligned so mono-only rows (Bash) sit level with the icon and chevron. Truncating line content (the CSS-ellipsis spans) sets <code data-v-5fe218d3>--leading-tight</code> rather than the row's <code data-v-5fe218d3>line-height: 1</code> — a 1em line box is shorter than the font's ascent + descent, so <code data-v-5fe218d3>overflow: hidden</code> would clip descenders (j / p / g / y); mono runs take the font's own <code data-v-5fe218d3>normal</code> leading instead, since JetBrains Mono's ≈1.32em metrics exceed <code data-v-5fe218d3>--leading-tight</code>. The 16px chevron still drives the ~24px row height.</li><li data-v-5fe218d3><b data-v-5fe218d3>Every tool kind composes its own line, leading with the tool's localized action label</b> (Run / Read / Edit / Write / Search / Find / Fetch…): Bash pairs its label with the full command in mono (CSS-truncated) plus a duration chip; Read / Edit / Write follow the label with the file name as a real button (opens the file preview) followed by the directory, a <code data-v-5fe218d3>:line-range</code> or a <code data-v-5fe218d3>+N −M</code> stat with a mini segmented bar; Grep shows the pattern in mono plus a match count; Glob / Ls list paths; Todo carries the active task with a done/total progress bar; goal tools show a coloured status pill; ExitPlanMode expands into a read-only plan receipt with its persisted review outcome. Unrecognized tools fall back to glyph + localized label + argument summary.</li><li data-v-5fe218d3><b data-v-5fe218d3>The settled question is the one exception to the quiet line</b>: once AskUserQuestion settles with a recognized answer, it becomes a small <b data-v-5fe218d3>receipt card</b> — the question card's echo (raised surface, hairline edge, lg radius, <code data-v-5fe218d3>--shadow-xs</code>, flush with the stream's left edge, ≤560px). The card echoes only the picks, checked with the live QuestionCard's CSS glyph language one step down (14px); passed-over options are not echoed. Dismissed (or zero-answer) collapses to a slim italic one-line card; while running, and for unrecognized output (background launch / error), it stays the plain quiet disclosure line with the raw output.</li><li data-v-5fe218d3>Clicking a line <b data-v-5fe218d3>expands it in place</b>; the detail hangs below at the line's own left edge (no inset), so it reads as part of the stream rather than as a separate card. Details are one of: the mono output panel (content-well surface, hairline edge, 12-line scroll cap), the inline diff, or clickable match / file lists (<code data-v-5fe218d3>path:line</code> opens the preview at that line). Code-bearing details — the Read content, the Edit diff, the Write content — are <b data-v-5fe218d3>syntax-highlighted by file type</b> (github-light / github-dark, following the colour scheme), with the Read output's real line numbers as the gutter; highlighting mounts lazily on first expand and degrades to plain text for unknown languages or oversized content.</li><li data-v-5fe218d3>Rows sit <b data-v-5fe218d3>flush with the message stream's left edge</b> (same alignment as prose and the thinking row): no inset, no hover wash, and the glyph rides the thinking row's 4px icon-to-text rhythm with no padded slot. Expanded rows inside a group stack directly on the shared rhythm — no dividers.</li><li data-v-5fe218d3>Consecutive activity — thinking segments and tool calls of ANY kind, quiet lines and richer cards alike — <b data-v-5fe218d3>folds into ONE activity-run row</b>: a smart summary sentence that aggregates the run per tool kind in first-appearance order (<code data-v-5fe218d3>Read 2 files · Ran 5 commands (1 failed) · 26s</code>), the failure clause hanging on its kind in danger red, the total span faint at the tail — one line, ellipsis-truncated, the full sentence in the title tooltip. Thinking items fold into the run but are not narrated in the sentence. The row shares the thinking row's language (borderless faint text row, text-colour hover only, one whole-row button with a rotating chevron) but rides a roomier 8px vertical padding — 30px against the quiet lines' 22px, so the turn-level summary keeps its presence between prose paragraphs; while the turn streams through the run the row stays expanded and the summary turns live (current action + cumulative per-kind stats + ticking whole seconds), and once every item settles it folds itself back — even if the user expanded it mid-run (the thinking block's vocabulary); a settled → running transition (the stream appending to the same run) reopens it. The glyph carries the state: the current step's own icon breathing while running, green ✓ / red ✕ once settled. A run needs <b data-v-5fe218d3>≥ 2 steps</b> — a lone step renders standalone as the block it always was. <b data-v-5fe218d3>Text never folds</b> (it breaks the run), and neither do successful media tools (no card — inline media is the turn's output); everything else folds, cards included: Todo / Goal progress narration, the sub-agent identity card, Question / Swarm cards and unrecognized kinds (skills, MCP tools) all join the run — the stay-expanded-while-live rule keeps a card visible exactly while it is active. The expanded run is the items flat in order (thinking rows + tool rows), each with its own in-row details intact — the lines keep their own 4px row rhythm but breathe 8px apart, with a small inset below the head.</li><li data-v-5fe218d3><b data-v-5fe218d3>Above the activity run sits the turn fold</b> (<code data-v-5fe218d3>TurnFold.vue</code>): when an assistant turn settles, every block before the LAST text block — thinking segments, activity runs, interim text paragraphs, Todo / Goal / sub-agent cards — folds into a single bare row reading <code data-v-5fe218d3>Worked 4m57s</code> (whole seconds, no glyph, no summary sentence), expanding into the folded blocks in order, each with its own rendering intact. The span is the turn's ELAPSED time (<code data-v-5fe218d3>turnWorkMs</code>): it ticks from the stamped start while the turn is open — approval/question waits included by design, so no park bookkeeping exists — then reads the daemon's own <code data-v-5fe218d3>durationMs</code> once settled (the server message stamps for history turns); the wall clock only feeds the live tick, so throttled tabs, session switches and remounts cannot corrupt the settled value. Without any stamp the row falls back to the generic <code data-v-5fe218d3>Work details</code>. Streaming turns show no row and a forced-open body — the live transcript is untouched, the fold lands only when the stream moves past the turn (or the turn parks). The split never hides the turn's output: the final text block and any trailing blocks (inline media, standalone cards) stay visible, and a text-only turn folds nothing. Fold state is a plain component ref — nothing persists, switching sessions resets to folded. Inside the right-side sub-agent transcript, disclosure bodies open instantly while their chevrons retain the standard rotation: animating the height of a full historical stream would relayout the entire panel on every animation frame.</li><li data-v-5fe218d3><b data-v-5fe218d3>A sub-agent delegation is an identity card</b> — never a quiet line: the card carries the TASK as its title and the agent type as a quiet meta line, while the orchestrator's full prompt stays out of the stream on purpose. The whole card is one action (the quiet shell vocabulary: raised surface, hairline edge, large radius, no shadow): click to open the subagent's live progress in the side panel — there is no in-stream expansion.</li><li data-v-5fe218d3>Status keeps the shared vocabulary: running (pulsing accent dot) / done (green ✓) / failed (red ✗), at the line's right edge. <b data-v-5fe218d3>Only two types keep a full card</b>: <code data-v-5fe218d3>Question</code> and <code data-v-5fe218d3>Approval</code> — they genuinely need the user's attention. The Swarm composite keeps one quiet card (raised surface, 0.5px hairline, large radius) for its phase overview + member accordion.</li><li data-v-5fe218d3><b data-v-5fe218d3>A task notification is a status card, not a quiet line</b> (<code data-v-5fe218d3>NotificationCard.vue</code>): the hidden <code data-v-5fe218d3><notification></code> injections (background-task / sub-agent settlement) render where they landed in the turn — a 28px status chip + title/sub head tinted with the toast status token pairs (completed → success, failed / timed_out / lost → danger, killed → warning, else neutral surface), expanding in place to the fields, the body, an output-file row (copy path) and the raw payload. ≥2 CONSECUTIVE notifications merge into one neutral group card (count + per-item status dots + compact rows, each expanding on its own). Notifications break the activity run but are never turn boundaries, and they <b data-v-5fe218d3>never fold</b> — a notification is an event worth noticing, not process noise, so it punches out of the turn fold and renders right after the fold row, in order.</li><li data-v-5fe218d3><b data-v-5fe218d3>A turn that dies on a model-request failure leaves a persistent terminal card</b> at the transcript tail (ChatPane's <code data-v-5fe218d3>.turn-failed</code>): the notification card's danger shell (danger-soft surface, danger hairline, 24px status chip with the warning glyph) carrying a title keyed by the wire error kind (model failure vs step-limit stop), the provider message as a muted sub, a mono diagnostics meta (code · HTTP status · request id), and exactly ONE secondary sm action — Continue, which submits a short continue prompt through the normal path. It renders only while the session sits idle on <code data-v-5fe218d3>lastTurnReason === 'failed'</code> (a turn with zero assistant output included, so it pins to the tail rather than any assistant row), it is not dismissible, and it vanishes the moment a new turn starts. While the turn is still fighting, the working indicator instead narrates the retry backoff ("retrying n/max" from the live <code data-v-5fe218d3>agent.status.updated</code> phase) — a retrying turn never shows the card. The transient error toast now fires only for background sessions; the viewed session's failure is fully covered by the card.</li><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Turn failed card · persistent terminal marker + one resume action</span></div><div class="stage p col" data-v-5fe218d3><div class="p-turn-failed" data-v-5fe218d3><span class="tf-chip" data-v-5fe218d3><svg viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path d="M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z" data-v-5fe218d3></path><path d="M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z" data-v-5fe218d3></path><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z" data-v-5fe218d3></path></svg></span><div class="tf-main" data-v-5fe218d3><span class="tf-title" data-v-5fe218d3>模型请求失败,本轮对话已中断</span><span class="tf-sub" data-v-5fe218d3>429 The engine is currently overloaded, please try again later</span><span class="tf-meta" data-v-5fe218d3>provider.rate_limit · HTTP 429 · req_01KZ8Y…</span></div><button class="p-btn secondary sm" data-v-5fe218d3>继续</button></div></div></div><li data-v-5fe218d3><b data-v-5fe218d3>A goal-continuation turn carries a provenance row</b>: the hidden <code data-v-5fe218d3>goal_continuation</code> trigger (goal mode's self-driven next turn — a turn boundary, unlike task notifications) never renders its machine prompt; instead the assistant turn it opens shows one faint 12px line flush with the stream's left edge — the <code data-v-5fe218d3>target</code> glyph shared with the Goal tool (this turn belongs to the goal) + a localized label — ABOVE the turn's content and OUTSIDE the turn fold, so the row survives as the turn's provenance after settling. The marker lands with the trigger (before the first assistant block), and while the newest exchange is a goal-continuation turn the undo affordances (edit-and-resend, Esc undo) are suppressed — rewinding would drop the hidden trigger while refilling the older user text.</li><li data-v-5fe218d3><b data-v-5fe218d3>A settled turn's file changes are one summary card</b> (<code data-v-5fe218d3>TurnFilesSummary.vue</code>): between the turn's final text and its footer, a §03 <code data-v-5fe218d3>Card</code> (hairline border, no shadow — NOT the quiet tool line, the artifacts are worth a discrete object) lists every file the turn's Edit / Write calls touched. The head reads "N files changed" with the aggregate <code data-v-5fe218d3>+A −D</code> and the mini diffbar; the aggregate hides whenever any row's stats are incomplete (a Write or an underivable edit makes the total a lower bound, never presented as exact). Each row is one clickable workspace-relative path (short and self-locating; a file outside the cwd stays absolute) with its per-file <code data-v-5fe218d3>+A −D</code> at the right edge. The row's action keys on the tool kind, and the stats tell it apart: a <b data-v-5fe218d3>Write</b> has no per-file count (its diff is underivable) and opens the whole file in the preview; an <b data-v-5fe218d3>Edit / MultiEdit</b> carries its <code data-v-5fe218d3>+A −D</code> and opens that file's <b data-v-5fe218d3>turn diff</b> in the right-side detail layer (<code data-v-5fe218d3>TurnDiffPanel.vue</code> — the turn's own X→Y change, not the git diff), whose header keeps an open-file action. The first three files show inline; the rest collapse behind a "N more files" ghost-button row in the card's foot. Where nothing handles the row action (the BTW side chat), the card renders its file rows as plain text instead of links.</li></ul>',15)),a("div",ve,[e[31]||(e[31]=a("div",{class:"stage-bar"},[a("span",{class:"st"},"Turn files summary · a real TurnFilesSummary (fixed sample)")],-1)),a("div",fe,[a("div",pe,[c(A,{changes:C,cwd:ye,onOpenDiff:u,onOpenFile:u})])])]),e[40]||(e[40]=t('<div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Tool Call · quiet lines (expand on demand)</span></div><div class="stage p" data-v-5fe218d3><div class="p-tool-group open" data-v-5fe218d3><div class="p-tool-group-head" data-v-5fe218d3><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tg-title" data-v-5fe218d3>Read 2 files</span></div><div class="p-tool-row expanded" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>session.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth · :12-45</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>34 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div><div class="p-tool-detail" data-v-5fe218d3><div class="p-code" style="font-size:11px;padding:7px 9px;" data-v-5fe218d3>12 export function verify(…</div></div><div class="p-tool-row" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Read</span><span class="tr-file" data-v-5fe218d3>middleware.ts</span><span class="tr-faint" data-v-5fe218d3>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-chip" data-v-5fe218d3>58 lines</span><span class="tr-ok" data-v-5fe218d3>✓</span></div></div><div class="p-tool-row" data-v-5fe218d3><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414 1.414l1.414-1.414l-1.414-1.414l-1.414 1.414zM4 21h16v-2H4v2z" data-v-5fe218d3></path></svg><span class="tr-name" data-v-5fe218d3>Edit</span><span class="tr-file" data-v-5fe218d3>middleware.ts</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-5fe218d3></path></svg><span class="tr-add" data-v-5fe218d3>+12</span><span class="tr-del" data-v-5fe218d3>−4</span><span class="tr-bar" aria-hidden="true" data-v-5fe218d3><span style="flex:12;background:var(--p-success);" data-v-5fe218d3></span><span style="flex:4;background:var(--p-danger);" data-v-5fe218d3></span></span><span class="tr-ok" data-v-5fe218d3>✓</span></div></div></div><h3 class="sub" data-v-5fe218d3>Decision cards · Question / Approval</h3><p data-v-5fe218d3>The two attention cards replace the composer in the dock and share one contract: a floating neutral shell (<code data-v-5fe218d3>--color-surface-raised</code> + hairline + <code data-v-5fe218d3>--radius-lg</code> + <code data-v-5fe218d3>--shadow-menu</code>), a plain dark 16px title head, and a hairline footer whose actions read in number-key order with exactly one accent primary. There is no semantic colour band — the floating card itself is the "needs a decision" signal.</p><div class="stage-wrap" data-v-5fe218d3><div class="stage-bar" data-v-5fe218d3><span class="st" data-v-5fe218d3>Plan review · pinned option rows, second-line descriptions</span></div><div class="stage p col" data-v-5fe218d3><div class="p-action" style="max-width:520px;" data-v-5fe218d3><div class="p-action-head" data-v-5fe218d3><span class="p-action-title" data-v-5fe218d3>按这份 plan 开始实现?</span></div><div class="p-action-body" data-v-5fe218d3>The plan markdown scrolls in a capped area; the approaches are pinned below it — label on the first line, full description always on the second. The number chip doubles as the keyboard hint.</div><div class="p-opts" data-v-5fe218d3><div class="p-opt" data-v-5fe218d3><span class="n" data-v-5fe218d3>1</span><span class="p-opt-text" data-v-5fe218d3><span class="l" data-v-5fe218d3>方案 A:静态徽章</span><span class="d" data-v-5fe218d3>零依赖、渲染稳定,升级时需手动同步版本号。</span></span></div><div class="p-opt" data-v-5fe218d3><span class="n" data-v-5fe218d3>2</span><span class="p-opt-text" data-v-5fe218d3><span class="l" data-v-5fe218d3>方案 B:动态徽章</span><span class="d" data-v-5fe218d3>版本自动同步免维护,但要求仓库公开可访问。</span></span></div></div><div class="p-action-foot" data-v-5fe218d3><button class="p-btn ghost sm" data-v-5fe218d3>修改</button><button class="p-btn ghost sm" data-v-5fe218d3>拒绝并退出</button></div></div></div></div><ul class="clean check" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>Footer contract</b>: actions are left-aligned in number-key order (1·2·3·4), each carrying a number chip — sized by <code data-v-5fe218d3>--p-chip-num</code> over <code data-v-5fe218d3>--color-inline-code-bg</code>, the same chip vocabulary as option rows and the multi-step chip; exactly one <code data-v-5fe218d3>primary</code> action, the rest are <code data-v-5fe218d3>ghost</code>. Feedback mode swaps the whole footer for submit / cancel.</li><li data-v-5fe218d3><b data-v-5fe218d3>Body by kind</b>: Write approvals preview the incoming content with <code data-v-5fe218d3>HighlightedCode</code> (syntax-highlighted, 24-row cap with scroll); Edit approvals render the before/after hunk as a highlighted line diff. Plan / diff / file kinds get a head expand toggle that lifts the cap so the block fills the card; the card itself never exceeds the pane (only the scroll area shrinks) — with the dock work pills visible, the dock takes over the same height budget as a flex column, so an expanded card yields the pills' height instead of pushing them past the pane's top edge. Once the plan scrolls, a soft shadow fades in at the scroll area's top edge — the sidebar's scroll-linked seam language, so clipped content reads as passing under the card chrome.</li><li data-v-5fe218d3><b data-v-5fe218d3>Danger hint</b>: destructive shell commands (rm -rf, sudo, force-push…) show a <code data-v-5fe218d3>danger-soft</code> filled hint row under the command — detection is a display-layer heuristic on the client.</li><li data-v-5fe218d3><b data-v-5fe218d3>Minimized</b>: the card collapses to a thin bar with a mono peek of the subject; the whole bar is the expand click target.</li><li data-v-5fe218d3><b data-v-5fe218d3>Question card</b>: the title is the question itself (2-line clamp), with a step chip for multi-question flows and a × dismiss button. Options use CSS radio/checkbox glyphs (accent when selected); the number chip and glyph top-align with the option text, optically centred on the label's first line. The footer follows the same left-aligned action contract (primary first, ghosts after), with the keyboard hint pinned to the right edge; keyboard: ↑↓ moves (Space toggles in multi), digits pick, Enter advances/submits, Esc dismisses.</li></ul><h3 class="sub" data-v-5fe218d3>Composer</h3><p data-v-5fe218d3>Unified into a single raised container: <code data-v-5fe218d3>--radius-composer</code> (32px) with <code data-v-5fe218d3>--corner-shape-composer: superellipse(1.5)</code> and a stable 0.5px edge. Focus crossfades a low-chroma line-and-accent edge over <code data-v-5fe218d3>--duration-slow</code> with <code data-v-5fe218d3>--ease-in-out</code>, while the neutral shadow stays unchanged — there is no added halo and no layout shift. The textarea uses <code data-v-5fe218d3>text-autospace: normal</code> for mixed CJK and Latin input. Toolbar controls use a quiet 32px full-round geometry with 8px edge inset; the send button remains a standard 32px circle, with its glyph at 28px (<code data-v-5fe218d3>--composer-send-icon-size</code>, the production kimi.com size; it sits outside the <code data-v-5fe218d3>--p-ic-*</code> scale on purpose).</p><p data-v-5fe218d3><b data-v-5fe218d3>Fill and edge tokens</b>: the card's fill and rest border are their own tokens — <code data-v-5fe218d3>--color-composer-bg</code> and <code data-v-5fe218d3>--color-composer-line</code> — running the kimiwork / kimi.com production input recipe (<code data-v-5fe218d3>.chat-input__shell</code>): fill = <code data-v-5fe218d3>groupedBackground.secondary</code> (#ffffff light / #1f1f1f dark), rest border = <code data-v-5fe218d3>separator.s1</code> (13% black / 12% white), focus line = <code data-v-5fe218d3>fills.f4</code> (25% in both schemes), and <code data-v-5fe218d3>--shadow-input</code> = <code data-v-5fe218d3>effect.shadow.inputDefault</code> (<code data-v-5fe218d3>0 5px 16px -4px rgba(0,0,0,0.07)</code>, kept identical in dark — the hairline carries the edge there). Only colours sit in the tokens; the 32px superellipse shape and the focus-only edge overlay are unchanged.</p><p data-v-5fe218d3><b data-v-5fe218d3>Send button tokens</b>: the send circle runs on <code data-v-5fe218d3>--color-send-bg</code> / <code data-v-5fe218d3>--color-send-bg-hover</code> / <code data-v-5fe218d3>--color-send-icon</code> (+ <code data-v-5fe218d3>*-disabled</code>, <code data-v-5fe218d3>--opacity-send-disabled</code>, <code data-v-5fe218d3>--shadow-send[-hover]</code>), following the production recipe (<code data-v-5fe218d3>.chat-input__send</code>): a neutral <code data-v-5fe218d3>labels.primary</code> fill (90% black light / 84% white dark, hover #252525 / 84.8%) with the production lift shadow (<code data-v-5fe218d3>0 7px 16px -13px 38% + 0 1px 2px 7%</code>, one step larger on hover), a <code data-v-5fe218d3>groupedBackground.secondary</code> glyph, and a disabled state of the same vocabulary — <code data-v-5fe218d3>fills.f2</code> fill with a <code data-v-5fe218d3>labels.quaternary</code> glyph at full opacity. The button is disabled exactly when submit would no-op — an empty draft with no ready attachment (image-only sends stay enabled), an upload in flight, or the starting spinner — so disabled is a first-class persistent state, never a fade.</p><p data-v-5fe218d3><b data-v-5fe218d3>Layering, anchors, and motion</b>: the dock normally stays at <code data-v-5fe218d3>--z-sticky</code> so the Latest Messages pill can remain visible above its veil. While any Composer popup is open, the dock temporarily joins <code data-v-5fe218d3>--z-dropdown</code>, ensuring permission, work-mode, and model menus always paint above that pill. The permission menu's left edge and the model menu's right edge each follow their own trigger pill. All three menus use <code data-v-5fe218d3>--shadow-menu</code> and the same trigger-corner pop motion as Session Row menus: 0.97 scale with a 2px shift toward the trigger, <code data-v-5fe218d3>--duration-base</code> on entry, and <code data-v-5fe218d3>--duration-fast</code> on exit.</p><p data-v-5fe218d3><b data-v-5fe218d3>Attachment strip</b>: attachments hang inside the composer card above the textarea as two grouped rows — images/videos as shared <code data-v-5fe218d3>MediaThumb</code> rounded thumbnails, files as the shared <code data-v-5fe218d3>AttachmentChip</code> pill — the same pair the sent bubble renders, so a draft looks exactly like the sent message. File-store videos render a static play tile instead of fetching a first frame. The strip caps at two thumbnail rows and scrolls beyond that instead of pushing the input down; while overflowing, a quiet count badge pins to the bottom-left and new attachments auto-scroll into view (to the end of whichever group grew). With two or more attachments, a one-click clear-all pins to the strip's top-right corner as a quiet 22px badge (trash glyph, danger on hover). The composer's pending preview and the bubble's media clicks open the same <code data-v-5fe218d3>MediaLightbox</code> preview, which owns Escape via the shared dialog stack: images go through PhotoSwipe (<code data-v-5fe218d3>@moonshot-ai/app-client</code>'s <code data-v-5fe218d3>lib/mediaPreview</code>) and zoom out of the clicked thumbnail (scrim = <code data-v-5fe218d3>--color-scrim-strong</code>, caption = <code data-v-5fe218d3>--color-text-on-scrim</code>; the slide area is inset — 24px sides matching the video modal, 56px top/bottom clearing the close button and caption — so a viewport-filling image never kisses the edges), videos keep the custom modal. Both share the <code data-v-5fe218d3>--color-scrim-strong</code> backdrop and the same close button — the raised 36px circle (<code data-v-5fe218d3>.media-lightbox-close</code>) fixed at the viewport's top-right, rendered by <code data-v-5fe218d3>MediaLightbox</code> for both (PhotoSwipe's own top bar is disabled; zoom stays on wheel / pinch / image click). ReadMedia tool cards open it too (an App-level instance fed by the <code data-v-5fe218d3>openMedia</code> chain): the image zooms out of the card's thumbnail, and videos show as a static play tile that opens the modal player — no more right-side-panel detour or inline <code data-v-5fe218d3><video></code>.</p>',11)),a("div",he,[e[38]||(e[38]=a("div",{class:"stage-bar"},[a("span",{class:"st"},"Composer")],-1)),a("div",ue,[a("div",ge,[e[36]||(e[36]=a("div",{class:"p-composer-ta ph"},"Message Kimi, / to run a command, @ to reference a file…",-1)),a("div",be,[a("div",me,[e[33]||(e[33]=a("button",{class:"p-icon-btn"},[a("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[a("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"})])],-1)),a("span",we,[c(f(h),{name:"shield-question",size:"sm"}),e[32]||(e[32]=d("yolo",-1))]),e[34]||(e[34]=a("span",{class:"p-pill"},[a("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[a("path",{fill:"currentColor",d:"M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"})]),d("plan")],-1))]),e[35]||(e[35]=t('<div class="p-composer-right" data-v-5fe218d3><span class="p-pill" data-v-5fe218d3><span class="pp-strong" data-v-5fe218d3>kimi-k2</span><span class="pp-sub" data-v-5fe218d3>· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-5fe218d3></path></svg></span><button class="p-send" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M13 7.828V20h-2V7.828l-5.364 5.364l-1.414-1.414L12 4l7.778 7.778l-1.414 1.414z" data-v-5fe218d3></path></svg></button></div>',1))])]),e[37]||(e[37]=t('<div class="p-composer-strip" data-v-5fe218d3><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="M4 5a1 1 0 0 1 1-1h5l2 2h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5z" data-v-5fe218d3></path></svg>kimi-code-web<svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-5fe218d3><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-5fe218d3></path></svg></div>',1))])]),e[41]||(e[41]=t('<div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>Site-wide consistency</b>: the composer uses one 32px superellipse shell and one 32px desktop control height. Attachment, permission, modes, compact, and model controls are all full-round and transparent at rest; hover reveals a neutral wash, open/active may use accent-soft, and Send remains the sole persistent filled control — an inverted <code data-v-5fe218d3>--color-text</code> fill with a <code data-v-5fe218d3>--color-bg</code> glyph (never the accent), disabled while the input is empty or an upload is in flight. The transparent dock floats over the transcript, while the scrolling content receives bottom padding equal to the live dock height so its final item can still clear the composer. Composer chrome is not selectable; only the message input permits text selection. Each permission mode has its own registry icon — manual <code data-v-5fe218d3>hand</code>, yolo <code data-v-5fe218d3>shield-question</code>, auto <code data-v-5fe218d3>full-access</code> — paired with the label in the pill (collapsing to the accessible icon below a 620px composer container) and leading its dropdown row in the mode's colour, with the current row's check trailing the row's end. The right toolbar is the flexible region: the model pill shrink-wraps its content, then shrinks and truncates internally only when the toolbar runs out of room. The dock's workbar above the composer carries one pill vocabulary — 32px high with <code data-v-5fe218d3>--space-4</code> inline padding and stadium-shaped (<code data-v-5fe218d3>--radius-full</code>) corners, a <code data-v-5fe218d3>--color-surface</code> fill (one rung above the page in both schemes — sunken is degenerate in dark — the same material as the popover it opens), and the system hairline edge (0.5px at <code data-v-5fe218d3>--color-line-strong</code>, one rung up for presence; no shadow), icon + label + a count or status — for background bash tasks, background sub-agents, todos, and the goal alike; a pill toggles the shared work panel (itself at <code data-v-5fe218d3>--radius-xl</code> with the same 0.5px <code data-v-5fe218d3>--color-line-strong</code> edge outside — inner separators stay <code data-v-5fe218d3>--color-line</code> — and the menu panel's <code data-v-5fe218d3>--shadow-menu</code>), and the goal's detail (full objective, completion criterion) fills the panel body while its pause / resume / cancel controls ride the panel head (the decision cards' action vocabulary — exactly one accent primary, resume while paused; secondary pause while active; danger-soft cancel) and the meta counts (turns / tokens / time / budget) sit in a hairline footer — never a separate full-width strip. </div></div><p data-v-5fe218d3><b data-v-5fe218d3>Workspace attachment card</b>: on the empty session, the workspace picker is a <b data-v-5fe218d3>separate attachment card</b> tucked under the composer — and the composer card itself stays complete (its own 0.5px border, <code data-v-5fe218d3>--radius-composer</code> corners with <code data-v-5fe218d3>--corner-shape-composer</code>, and shadow are never altered). The attachment lives inside the composer's padding box as the card's sibling, so its width always matches; its top <code data-v-5fe218d3>--space-4</code> slides behind the card (the card is raised to <code data-v-5fe218d3>--z-sticky</code>), its square top edge stays hidden, and only the rounded bottom (<code data-v-5fe218d3>0 0 --radius-xl --radius-xl</code>) shows. Background <code data-v-5fe218d3>--color-hover</code> at 60% via <code data-v-5fe218d3>color-mix</code> (≈0.03 black in light, self-adapting in dark), no border, no shadow. Inside sits one quiet capsule trigger: transparent, <code data-v-5fe218d3>--radius-full</code>, 16px leading icon and 12px label at weight 475 in <code data-v-5fe218d3>--color-text-muted</code>; hover deepens to <code data-v-5fe218d3>--color-selected</code> and the label turns <code data-v-5fe218d3>--color-text</code>. The dropdown follows the §03 menu spec and is viewport-aware (flips above when more room, clamps max-height to the scrollport); at <code data-v-5fe218d3>--z-dropdown</code> it outranks both the card and the fixed click-outside backdrop (<code data-v-5fe218d3>--z-sticky</code>), which renders outside the composer because the card's <code data-v-5fe218d3>container-type</code> captures <code data-v-5fe218d3>position: fixed</code> descendants.</p><h3 class="sub" data-v-5fe218d3>Responsive</h3><p data-v-5fe218d3>See §02 <code data-v-5fe218d3>--p-bp-sm</code> for the breakpoint. This section only gives mobile-adaptation pointers for the chat interface; a full mobile mockup is out of scope for this spec.</p><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> At ≤640px: dialogs anchor to the bottom as Sheets (xl top radius, top drag handle), the sidebar collapses into an expandable drawer, the Composer toolbar is allowed to wrap, and the chat reading column drops its max-width to fill the screen. </div></div>',5))]),e[43]||(e[43]=t('<section id="themes" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>05</span><h2 class="sec-title" data-v-5fe218d3>Theming</h2></div><p class="sec-desc" data-v-5fe218d3> Kimi Web uses <b data-v-5fe218d3>one unified theme</b>: the same components, fonts, radii, shadows, and surfaces — theming only swaps color values. Every semantic color token ships a light value in <code data-v-5fe218d3>:root</code> and a dark override in the <code data-v-5fe218d3>data-color-scheme</code> blocks; the semantic status colors (success / warning / danger) are independent palettes, one set each for light / dark. </p><h3 class="sub" data-v-5fe218d3>Accent</h3><p data-v-5fe218d3>The app has <b data-v-5fe218d3>one accent</b>: the brand blue (<code data-v-5fe218d3>--color-accent</code>, <code data-v-5fe218d3>#1783ff</code> light / <code data-v-5fe218d3>#58a6ff</code> dark). Use it sparingly — the accent is reserved for the primary action, focus rings, links, and active marks (current tab, toggles); large fills always come from the neutral surface tokens. Selection that means "where I am" (sidebar rows, list pickers) is deliberately NOT accent-tinted — it uses <code data-v-5fe218d3>--color-selected</code> so it reads as location, not as an action.</p><h3 class="sub" data-v-5fe218d3>Light / dark mode</h3><p data-v-5fe218d3>Each semantic token ships a light value in <code data-v-5fe218d3>:root</code> and a dark override in the two <code data-v-5fe218d3>data-color-scheme</code> blocks (explicit choice, or following the OS preference via <code data-v-5fe218d3>prefers-color-scheme</code>). Switching light / dark simply swaps between these two sets of derived tokens, with zero structural change.</p><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3><b data-v-5fe218d3>Benefits of one theme</b>: components, fonts, radii, and surfaces are consistent site-wide; a single accent keeps the brand identity unambiguous; light / dark mode works out of the box; semantic status colors are independently tunable. </div></div></section><section id="rules" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>06</span><h2 class="sec-title" data-v-5fe218d3>Style Rules</h2></div><p class="sec-desc" data-v-5fe218d3> Anti-pattern rules that all UI code must follow. These rules are also the basis of the check-style detection script, one-to-one with a warning. </p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Rule ID</th><th data-v-5fe218d3>What it detects</th><th data-v-5fe218d3>Action</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-gradient-text</td><td data-v-5fe218d3>gradient text / gradient background</td><td data-v-5fe218d3><span class="pill red" data-v-5fe218d3>Forbidden</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-glassmorphism</td><td data-v-5fe218d3><code data-v-5fe218d3>backdrop-filter: blur</code> (<b data-v-5fe218d3>TopBar sticky nav bar</b> and <b data-v-5fe218d3>menu surfaces via <code data-v-5fe218d3>--p-menu-backdrop</code></b> are the exceptions)</td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>TopBar + menus exempt</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-color-glow</td><td data-v-5fe218d3>colored / large-radius box-shadow glow</td><td data-v-5fe218d3><span class="pill red" data-v-5fe218d3>Forbidden</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-emoji-icon</td><td data-v-5fe218d3>using emoji as a functional icon (no exceptions). Emoji inside <b data-v-5fe218d3>user content</b> — session titles, messages — is not chrome and is out of scope (see §07 Session row's emoji icon)</td><td data-v-5fe218d3><span class="pill red" data-v-5fe218d3>Forbidden</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-hardcoded-hex</td><td data-v-5fe218d3>unregistered hex color inside a component <code data-v-5fe218d3><style></code></td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>Warning</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>no-hardcoded-font</td><td data-v-5fe218d3>hard-coded <code data-v-5fe218d3>font-family</code> in a component (e.g. <code data-v-5fe218d3>'Inter'</code>) instead of <code data-v-5fe218d3>var(--font-ui)</code></td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>Warning</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>radius-from-scale</td><td data-v-5fe218d3>radius value not in <code data-v-5fe218d3>{4,6,8,12,16,20,999}</code></td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>Warning</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>z-from-scale</td><td data-v-5fe218d3>z-index using an unregistered large number</td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>Warning</span></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>weight-from-scale</td><td data-v-5fe218d3>font-weight not in <code data-v-5fe218d3>{400,500}</code></td><td data-v-5fe218d3><span class="pill amber" data-v-5fe218d3>Warning</span></td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>State matrix</h3><p data-v-5fe218d3>Every interactive primitive should define the following states where applicable; missing ones are flagged by the style rules. <code data-v-5fe218d3>focus-visible</code> always uses <code data-v-5fe218d3>--p-focus-ring</code> (appears only on keyboard focus, see §08); <code data-v-5fe218d3>disabled</code> is uniformly <code data-v-5fe218d3>opacity:.5</code>.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>State</th><th data-v-5fe218d3>Button</th><th data-v-5fe218d3>Input</th><th data-v-5fe218d3>Card</th><th data-v-5fe218d3>Menu item</th><th data-v-5fe218d3>Switch</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>default</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>hover</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>active / pressed</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>focus-visible</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>✓</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>disabled</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>loading</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>selected / active</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>✓</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>error</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>readonly</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>✓</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td><td data-v-5fe218d3>—</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Chat working indicator</h3><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3> The chat working state ("prompt sent, turn unfinished") is a brand signature of Kimi Web, rendered uniformly by the <code data-v-5fe218d3>WorkingIndicator</code> component: the 小蓝 mascot plus a phase label — "Requesting…" until the assistant's reply starts, "Working…" once it is streaming. All other loading states (including <code data-v-5fe218d3>ActivityNotice</code>) use the plain <code data-v-5fe218d3>Spinner</code>. </div></div><h3 class="sub" data-v-5fe218d3>Glassmorphism exemption</h3><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3><code data-v-5fe218d3>backdrop-filter: blur</code> is banned site-wide, with <b data-v-5fe218d3>two exceptions</b>: the <code data-v-5fe218d3>.frost</code> variant of <code data-v-5fe218d3>TopBar</code> — only in the one place of the "sticky navigation bar", used to stay readable over scrolling content — and the floating menu surfaces (Menu.vue, the Select listbox, composer dropdowns, slash/mention popups), which go through the <code data-v-5fe218d3>--color-menu-bg</code> / <code data-v-5fe218d3>--p-menu-backdrop</code> token pair so the recipe stays single-sourced. No other component (card, dialog, Toast, panel) may use glassmorphism; violations are flagged under <code data-v-5fe218d3>no-glassmorphism</code>, and menu blur with ad-hoc values (anything but the token) is flagged too. Persistent panels that stay open over scrolling content (the dock work panel) deliberately stay opaque — a live backdrop blur re-samples the scrolling page every frame and janks in Chromium. </div></div><div class="footer" data-v-5fe218d3><span data-v-5fe218d3>Kimi Web Design System · v1.0</span><span data-v-5fe218d3>The reference when changing the web UI</span></div></section><section id="shell" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>07</span><h2 class="sec-title" data-v-5fe218d3>App Shell & Sidebar</h2></div><p class="sec-desc" data-v-5fe218d3> The structural spec for the app shell (three-column grid + right preview panel) and the left session sidebar. These are business-agnostic "skeletons" — components, fonts, radii, and surfaces are reused from §02 / §03, but layout and alignment have their own conventions. </p><h3 class="sub" data-v-5fe218d3>Layout grid</h3><p data-v-5fe218d3>On web it is a single-row 5-track grid: the sidebar and the right panel each occupy a permanent <code data-v-5fe218d3>auto</code> track, with the conversation column in the middle; two 0-width tracks are for the ResizeHandles. (The desktop app adds a second row for its terminal panel — desktop-only, see below.)</p><div class="code" data-v-5fe218d3><div class="code-bar" data-v-5fe218d3><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="d" data-v-5fe218d3></span><span class="fn" data-v-5fe218d3>App.vue · .app</span></div><pre data-v-5fe218d3>grid-template-columns: auto 0 minmax(0, 1fr) 0 auto;\n /* sidebar ↑ ↑handle ↑conversation ↑handle ↑right panel (auto) */</pre></div><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>sidebar width</td><td class="val" data-v-5fe218d3>270px default (adjustable)</td><td data-v-5fe218d3>expanded sidebar width, changed by dragging the ResizeHandle; should approach §02's <code data-v-5fe218d3>--p-sidebar-w</code> (264px)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--preview-w</td><td class="val" data-v-5fe218d3>460px</td><td data-v-5fe218d3>width of the right preview panel when open</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--panel-head-h</td><td class="val" data-v-5fe218d3>48px</td><td data-v-5fe218d3>unified height for all right panel heads + the conversation column head; both use a 0.5px bottom hairline</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--p-bp-sm</td><td class="val" data-v-5fe218d3>640px</td><td data-v-5fe218d3>≤640 switches to a mobile single column (top bar + conversation), no sidebar / handle / right panel</td></tr></tbody></table><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>The right panel track exists permanently, with its width toggling between <code data-v-5fe218d3>0 ↔ var(--preview-w)</code> and no transition — animating a grid track would relayout the whole app grid every frame (when open it squeezes the conversation column, rather than switching templates).</li><li data-v-5fe218d3>The sidebar collapses SYMMETRICALLY to the right panel: its container width animates to 0 while the content keeps its fixed width anchored to the right edge (clipped, sliding out left — no reflow, hairline stays on the clipped content). No rail remains. The collapse control differs by platform: on <b data-v-5fe218d3>macOS desktop</b> the toggle is a single resident floating IconButton pinned beside the traffic lights (rendered in both states, only the glyph swaps — the sidebar slides underneath it, never moves or flashes); on <b data-v-5fe218d3>Windows / web</b> the collapse button lives inside the sidebar header (right-aligned), and a floating expand button appears at the top-left only while collapsed. The conversation header uses a 0.5px bottom hairline and pads left in step with the transition while collapsed.</li><li data-v-5fe218d3>All grid children must have <code data-v-5fe218d3>min-height:0; min-width:0</code>, so only the inner scroll containers scroll and the page itself does not scroll.</li></ul><h3 class="sub" data-v-5fe218d3>Sidebar alignment system (<code data-v-5fe218d3>--sb-*</code>)</h3><p data-v-5fe218d3>All sidebar rows (group head, session row, New chat, search, and Settings buttons) share 4 custom properties. Their 16px icon slots and <code data-v-5fe218d3>--sb-gap</code> place every label on the same x-axis as the workspace name.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Token</th><th data-v-5fe218d3>Value</th><th data-v-5fe218d3>Usage</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--sb-inset</td><td class="val" data-v-5fe218d3>12px</td><td data-v-5fe218d3>row box (hover/selected pill) inset from the sidebar edges — matches the brand header's 12px padding</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--sb-pad-x</td><td class="val" data-v-5fe218d3>20px</td><td data-v-5fe218d3>content start x (= --sb-inset + 8px row padding)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--sb-gutter</td><td class="val" data-v-5fe218d3>16px</td><td data-v-5fe218d3>leading icon slot width — matches the workspace folder icon so the session title aligns under the workspace name</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>--sb-gap</td><td class="val" data-v-5fe218d3>8px</td><td data-v-5fe218d3>gap between the icon slot and the text</td></tr></tbody></table><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3> The session title's starting x = <code data-v-5fe218d3>--sb-pad-x + --sb-gutter + --sb-gap</code>. The group head has a folder icon and the session row has a status slot; both icons are the same width and position, so the titles align naturally. </div></div><h3 class="sub" data-v-5fe218d3>Sidebar structure</h3><p data-v-5fe218d3>The sidebar from top to bottom: brand header → action group → pinned head (pinned section + "Workspaces" label) → scrolling grouped list (workspace head + session rows) → user-menu footer. New chat and Search are direct sibling controls in the same grid container; the optional new-workspace action shares the first row, while Search spans the next row. A 4px gap keeps Search clear of the scroll boundary. The pinned head sits OUTSIDE the scroll container (the action-group / footer pattern — never <code data-v-5fe218d3>position: sticky</code>, which would need an opaque plate over the frosted tint), so the pinned sessions and the "Workspaces" label stay put while the workspace groups scroll beneath; the pinned section is collapsible (a chevron on its label, revealed on hover/focus and kept visible while folded; state persisted) so a long pinned set can't eat the sidebar, and it re-expands when a new session is pinned. Both pinned edges use three light near, middle and far fades across 18px, entering over 260ms only while more session content exists beyond that edge — the top seam lives at the pinned head's bottom border. The footer seam is a 0.5px hairline. Controls reuse the §03 primitives as much as possible. The sidebar sits on <code data-v-5fe218d3>--color-sidebar-bg</code> (one step off <code data-v-5fe218d3>--color-bg</code>: warm off-white just under white in light, one step BELOW the page in dark — the session column reads as its own plane, and with dark elevation = lighter the chrome never sits brighter than the conversation pane; the hairline still separates it from the pane). Vertical rhythm: the brand header keeps 12px padding (on macOS desktop the left padding grows to 80px to clear the traffic lights); rows inside the action group stack flush (0 gap, same rhythm as the list rows); adjacent groups are separated by 12px. The search glyph has a -0.5px optical correction to align its visual centre with the label. Row hover uses <code data-v-5fe218d3>--sb-hover</code> (= the global <code data-v-5fe218d3>--color-hover</code> wash); the selected row uses the lighter <code data-v-5fe218d3>--sb-selected</code> wash derived from <code data-v-5fe218d3>--color-selected</code> — On macOS desktop the sidebar is instead <b data-v-5fe218d3>frosted</b>: the window carries a native <code data-v-5fe218d3>NSVisualEffectView</code> ('menu' vibrancy, following the in-app scheme via the nativeTheme mirror, its state pinned to <code data-v-5fe218d3>inactive</code> so the material keeps its flat pressed-down colour — ≈ #282829 dark / #E7E7E7 light — with no active/inactive drift) and the sidebar column drops <code data-v-5fe218d3>--color-sidebar-bg</code> for a single translucent <code data-v-5fe218d3>--color-sidebar-tint</code> wash that presses the pinned material one step — ≈ #282829 → ≈ #1e1e1f in dark (<code data-v-5fe218d3>rgba(0,0,0,0.25)</code>), ≈ #E7E7E7 → ≈ #f1f1f1 in light (<code data-v-5fe218d3>rgba(255,255,255,0.4)</code>) — with header and footer staying transparent so the tint reads as one uniform pane; the root chain (<code data-v-5fe218d3>html/body/#app/.app</code>) stays unpainted only under the <code data-v-5fe218d3>macos-desktop</code> + <code data-v-5fe218d3>vibrancy</code> flags — the latter is the Settings → Appearance accessibility switch (default on; persisted main-side so the window is created with the right material, and live-applied on toggle): off repaints the root chain and the sidebar falls back to opaque <code data-v-5fe218d3>--color-sidebar-bg</code>, while the traffic-light layout keeps keying off <code data-v-5fe218d3>macos-desktop</code> alone — while the conversation pane, chat header and right preview keep their own opaque surfaces. The list's hover-icon clusters (session-row kebab, group-head actions) paint NOTHING there — no plate, no wash, no blur (real backdrop blur does not even render over this window: Chromium's backdrop sampler returns a flat wash above the transparent BrowserWindow + vibrancy view). Instead the row's title/name dissolves before it ever reaches the buttons: a two-stage <code data-v-5fe218d3>mask-image</code> fade — a subtle 16px dissolve at rest, extending over the cluster zone only while the actions are revealed (row hover / keyboard focus / menu open): 34px on session rows (the pin+kebab cluster overhangs the title by ≈25px), 68px on group heads (the floating cluster is ≈60px wide). The fade is zone-based, so short rows render untouched, and <code data-v-5fe218d3>text-overflow</code> becomes <code data-v-5fe218d3>clip</code> so a long tail dissolves instead of dotting.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Block</th><th data-v-5fe218d3>Use</th><th data-v-5fe218d3>Note</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td data-v-5fe218d3>Brand header</td><td data-v-5fe218d3>logo + name + collapse IconButton (right-aligned)</td><td data-v-5fe218d3>on Windows / web the brand is left and the collapse IconButton sm is right-aligned inside the header; the dev-only backend version/address pill uses the UI font, not monospace; the logo is animated (a blinking eye). On macOS desktop the header is a bare drag strip (brand hidden, traffic lights + resident floating toggle over it)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>New chat</td><td data-v-5fe218d3>full-width left-aligned button (custom)</td><td data-v-5fe218d3>500-weight label; same rhythm as the session rows in the list (left-aligned, hover = <code data-v-5fe218d3>--sb-hover</code>). <b data-v-5fe218d3>Do not</b> use Button (centered, breaks the rhythm)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Search</td><td data-v-5fe218d3>bare search row (custom)</td><td data-v-5fe218d3>500-weight label; no border, hover/focus shows the faint <code data-v-5fe218d3>--color-hover</code> wash; icon + label, with the <code data-v-5fe218d3>Kbd</code> keycaps (⌘K / Ctrl K) pushed to the trailing edge — label and shortcut are justified apart. <b data-v-5fe218d3>Do not</b> use Input (the 38px bordered version is too heavy). It is a direct sibling of New chat in the action group</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Section label</td><td data-v-5fe218d3><code data-v-5fe218d3>.p-section-label</code></td><td data-v-5fe218d3>uppercase muted small titles like "Workspaces", using <code data-v-5fe218d3>--weight-section-label</code> (600)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Pinned head</td><td data-v-5fe218d3>fixed block above the scroll container (<code data-v-5fe218d3>.sessions-head</code>): the pinned section (<code data-v-5fe218d3>PinnedSessionList.vue</code>) + the "Workspaces" section label</td><td data-v-5fe218d3>stays put while the workspace groups scroll; owns the top scroll-linked seam (hairline + fade, only while scrolled). The pinned section folds via its label chevron (persisted, <code data-v-5fe218d3>kimi-web.pinned-collapsed</code>) and re-expands only on an explicit pin (never on load backfill); the expanded rows are capped at 40vh with their own scroll so a long pinned set can't push the list or footer out of view</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Workspace head / session row</td><td data-v-5fe218d3>see next two sections</td><td data-v-5fe218d3>share <code data-v-5fe218d3>--sb-*</code> alignment</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>User-menu footer</td><td data-v-5fe218d3>account area (<code data-v-5fe218d3>components/UserMenu.vue</code>) opening an upward §03 menu</td><td data-v-5fe218d3>pinned row under the session list, separated by a 0.5px <code data-v-5fe218d3>--line</code> hairline; trigger keeps the same list-style family as New chat (24px round avatar + nickname when signed in, user icon + sign-in hint otherwise). The menu box follows the trigger's left edge and width (ResizeObserver-tracked, so it survives a sidebar resize) and is teleported to body because the column's container-type would capture position:fixed. Rows: plan usage / theme / language are macOS-style hover flyout submenus — the parent row carries the module icon, a faint current value and a fixed chevron-right, and hovering (or moving focus to the parent row, or pressing Enter / Space / → on it) opens a teleported panel anchored to the parent menu's right edge (content-adaptive width floored by the menu's own min-width and capped at the parent menu's width; flips left near the viewport edge) with a 250ms hover-intent close grace; the usage panel shows weekly + 5h rows (percent values with severity colours), while the theme (three schemes) and language (two locales) panels move the check to the picked option without closing the menu — then the upgrade entry below the top plan level, settings (with an always-visible Kbd keycap shortcut hint on desktop) and a confirming sign-out; all menu icons come from the Kimi set</td></tr></tbody></table><div class="callout warn" data-v-5fe218d3><span class="ico" data-v-5fe218d3>!</span><div data-v-5fe218d3><b data-v-5fe218d3>Why New chat / search / inline rename don't use Button / Input:</b> they are "list-style" controls (full-width, left-aligned, compact, borderless), while Button is centered and Input is a 38px bordered control — forcing them in would break the sidebar's visual density and alignment. This is an intentional custom exception, not an oversight. </div></div><h3 class="sub" data-v-5fe218d3>Session row</h3><p data-v-5fe218d3>A session row is an inset rounded pill, structured as: <code data-v-5fe218d3>status slot → title → time → attention Badge → hover actions (pin / archive)</code>.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Part</th><th data-v-5fe218d3>Rule</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td data-v-5fe218d3>Container</td><td data-v-5fe218d3><code data-v-5fe218d3>padding: 8px 8px</code> inside the list's <code data-v-5fe218d3>--sb-inset</code> gutter, <code data-v-5fe218d3>radius-sm</code>; <b data-v-5fe218d3>no fixed/min height</b> — row height is font-driven (title <code data-v-5fe218d3>line-height: --leading-tight</code>, ≈16px) → ≈32px total, the sidebar-wide row rhythm. The hover actions are absolutely positioned so they never force the row taller (no hover jitter). hover = <code data-v-5fe218d3>--sb-hover</code> (the global <code data-v-5fe218d3>--color-hover</code> wash); active = <code data-v-5fe218d3>--sb-selected</code> (75% of the global selected wash) — neutral, no accent tint, no border, no weight change</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Status slot (lead)</td><td data-v-5fe218d3>fixed <code data-v-5fe218d3>--sb-gutter</code> width; running = <code data-v-5fe218d3>Spinner</code> sm, otherwise unread = 7px accent dot</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Title</td><td data-v-5fe218d3>flex:1 with truncation and <code data-v-5fe218d3>user-select:none</code>; double-click enters inline rename (compact input, not Input), whose text remains selectable</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Emoji icon</td><td data-v-5fe218d3>the session icon is the title's LEADING emoji cluster (app-core <code data-v-5fe218d3>splitSessionEmoji</code> — no icon field; every client renders the title as-is). The emoji is an ordinary title character — no decoration at rest or on hover (it stays a <code data-v-5fe218d3><button></code> for a11y), and clicking it opens <code data-v-5fe218d3>SessionEmojiPicker</code> — a Menu-shelled panel (bare list-style search row → scrollable sections: Recently used persisted in localStorage (cap 8) + the grouped emoji dataset, with remove/random as MenuItems in the footer; a query swaps the sections for keyword-search results), teleported + fixed + <code data-v-5fe218d3>--z-dropdown</code>, popping from the trigger corner like the right-click menu. The menu's "Set Emoji…" opens the same picker and is the discoverable path. Inline rename edits the whole title — the emoji is an ordinary character in the input</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Time</td><td data-v-5fe218d3>mono xs, <code data-v-5fe218d3>fg-faint</code>; yields to the hover actions on hover</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Attention Badge</td><td data-v-5fe218d3><code data-v-5fe218d3>Badge</code> sm: info (needs answer) / warning (needs approval) / danger (aborted)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Hover actions</td><td data-v-5fe218d3><code data-v-5fe218d3>IconButton</code> sm × 2 — pin + archive — cross-faded over the time on row hover (no kebab button). Right-clicking the row opens the full menu (copy ID / rename / emoji / fork / export / pin / archive + timestamp) anchored to the cursor, except over the inline rename input, where the native text-editing menu stays</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Flat-style variant (flat list + pinned section)</td><td data-v-5fe218d3>the sidebar's flat list rows AND — always, regardless of view mode — the pinned section's rows differ from the grouped row in three ways (all keyed off the facade projecting <code data-v-5fe218d3>cwdLabel</code>): ① no leading status slot — the title is left-aligned at the row's content edge; ② a second line under the title: <code data-v-5fe218d3>folder-closed</code> icon sm + the cwd's final directory name (<code data-v-5fe218d3>-</code> when the session has no cwd), xs faint like the time — except the icon, which takes <code data-v-5fe218d3>--color-text-muted</code> (one rung stronger, the same optical compensation as the group head's folder; the open-folder glyph's thin back-flap washed out at 14px) — rest-width tail mask fade; when the session has an associated PR (v2 git domain), a quiet chip (<code data-v-5fe218d3>git-pull-request</code> icon + #number) sits at the line's right edge, state-colored the GitHub way (open = <code data-v-5fe218d3>--color-success</code>, merged = <code data-v-5fe218d3>--color-done</code> purple, closed = faint) and opens the PR on click; ③ the first line's right side shows status — attention Badges anchored to the row's right edge, running Spinner, unread dot — INSTEAD of the time, which only renders when there is nothing to report (the Spinner yields to the attention pills: a session waiting for approval/answer never shows both); on hover the actions cross-fade IN as the whole status cluster fades OUT — pills and pin/archive never co-exist (grouped rows keep pills visible on hover). Height stays font-driven — the pill just grows the line. Grouped rows never set <code data-v-5fe218d3>cwdLabel</code> and keep the classic structure. The flat ↔ grouped switch lives in a dropdown on the SESSIONS section label (fixed <code data-v-5fe218d3>list-settings</code> icon + hover tooltip; the menu opens with a muted group label, per-view icons, and the current view checked at the row's right edge; mode persisted per device)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Archive</td><td data-v-5fe218d3>no confirm — the hover archive button / menu item archives immediately, then App.vue shows the §03 <code data-v-5fe218d3>ActionToast</code> (top-center) with Undo (restores the session) and Settings (opens the archived list)</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Workspace group</h3><p data-v-5fe218d3>The group head and session rows share <code data-v-5fe218d3>--sb-*</code>: folder icon (open/closed) → name, with the kebab and "+" revealed on hover.</p><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>The folder icon leads the row (switching icons between open and closed states) with the plain <code data-v-5fe218d3>--sb-gap</code> before the name — it does not pad out the <code data-v-5fe218d3>--sb-gutter</code> slot.</li><li data-v-5fe218d3>The name uses 500 weight with muted color (<code data-v-5fe218d3>--color-text-muted</code>, one step lighter than session titles), so group heads remain clear without competing with list content. No path subtitle; hovering the name shows the full root path in a <code data-v-5fe218d3>Tooltip</code>.</li><li data-v-5fe218d3>The kebab (menu) and "+" (new chat in this workspace) both use <code data-v-5fe218d3>IconButton</code> sm inside a floating actions layer anchored to the row's right edge — no reserved layout space, so the name uses the full row width when idle. Shown on hover, keyboard focus, or while the menu is open; the layer backs itself with the sidebar surface (container background) plus the row hover wash (an <code data-v-5fe218d3>::after</code> shown only while the row is hovered), so its color exactly equals the row's current background and the overlapped name tail doesn't bleed through (hidden via <code data-v-5fe218d3>opacity:0</code>, staying in the tab order). On macOS desktop the layer paints nothing at all — the name's <code data-v-5fe218d3>mask-image</code> fade (see the sidebar section above) dissolves the tail before it reaches the buttons</li><li data-v-5fe218d3>The group is collapsible; when collapsed its session list is hidden.</li><li data-v-5fe218d3>While the active workspace has no session selected (the draft state — e.g. right after adding the workspace, or after New chat), the group head carries the same neutral <code data-v-5fe218d3>--sb-selected</code> fill as a selected session row (selection reads as "where I am"; the fill wins over hover). Once a session is selected or created, the fill moves to that session row.</li></ul><h3 class="sub" data-v-5fe218d3>Show more & collapse</h3><p data-v-5fe218d3>The "expand / collapse" controls at the bottom of each workspace group are compact list controls (same family as search, New chat, inline rename — not Buttons) sharing one row: expand (chevron-down) first, collapse (chevron-up) after a faint middot when both are present. Expanding reveals the next batch of sessions, fetching the next page from the server only when the locally loaded rows can't cover it — the control never exposes whether a reveal came from memory or the network.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Part</th><th data-v-5fe218d3>Rule</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Row</td><td data-v-5fe218d3>a single flex row holding the controls, all content-width — hover washes just the button as a snug pill, never the full row. Font-driven height (≈32px like a session row), <code data-v-5fe218d3>radius-sm</code>; hover = <code data-v-5fe218d3>--sb-hover</code> (no text recolor); <code data-v-5fe218d3>:focus-visible</code> uses <code data-v-5fe218d3>--p-focus-ring</code></td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Chevron</td><td data-v-5fe218d3>sm (down = expand, up = collapse); the row indents by <code data-v-5fe218d3>--sb-gutter + --sb-gap</code> so the first button's chevron starts exactly at the session-title x, lining the control's leading edge up with the titles above</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Label</td><td data-v-5fe218d3><code data-v-5fe218d3>font-ui</code>, <code data-v-5fe218d3>text-xs</code>, <code data-v-5fe218d3>--color-text-muted</code>; truncated</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Separator</td><td data-v-5fe218d3>faint middot (<code data-v-5fe218d3>--color-text-faint</code>) with <code data-v-5fe218d3>--space-1</code> side margins, rendered only when both controls are present</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Behavior</td><td data-v-5fe218d3>each group keeps a display cap starting at the first page; "Show more" steps it up by one batch (5) and fetches the next page only when the loaded rows fall short (busy = "Loading…", disabled); "Show less" resets the cap to the first page (view-layer trim — data is kept, no refetch). "Show more" exists while undisplayed loaded rows remain or the server has more; "Show less" appears once past the first page</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>ResizeHandle</h3><p data-v-5fe218d3>A 4px grab strip layered over the 1px column border (<code data-v-5fe218d3>margin: 0 -2px</code> makes the whole 4px grabbable) with a centred 2px indicator bar. The bar stays transparent at rest and shows the neutral fills one step up the ramp — f2 on hover, f3 while the drag is live (the sidebar column is translucent on macOS, so f1 read too faint) — never the accent.</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Rule</th><th data-v-5fe218d3>Value</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td data-v-5fe218d3>Width / cursor</td><td data-v-5fe218d3>4px strip, 2px bar / <code data-v-5fe218d3>col-resize</code> mid-range; <code data-v-5fe218d3>w-resize</code> / <code data-v-5fe218d3>e-resize</code> at the drag limits (hints the direction that still resizes)</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Normal / hover / drag</td><td data-v-5fe218d3>transparent / <code data-v-5fe218d3>--color-selected</code> (f2) / <code data-v-5fe218d3>--color-line-strong</code> (f3) — the neutral ramp one step up, never accent</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Layer</td><td data-v-5fe218d3><code data-v-5fe218d3>--z-dropdown</code>, above pane-level sticky chrome (chat dock at <code data-v-5fe218d3>--z-sticky</code>) so the overhang stays visible and grabbable</td></tr><tr data-v-5fe218d3><td data-v-5fe218d3>Behavior</td><td data-v-5fe218d3>panel width follows the pointer 1:1 while dragging (the parent disables transitions to avoid lag); on release it is persisted to localStorage</td></tr></tbody></table><h3 class="sub" data-v-5fe218d3>Right panel</h3><p data-v-5fe218d3>The right panels (file preview / Diff / compaction summary / sub-agent / side chat) share one track and one head primitive.</p><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>The panel head uses the <code data-v-5fe218d3>PanelHeader</code> primitive (48px = <code data-v-5fe218d3>--panel-head-h</code>), the same height as the conversation column head, so the hairline runs as one line.</li><li data-v-5fe218d3>Panel head: bold mono title + optional muted subtitle + middle slot (Badge / control / path) + close IconButton on the right.</li><li data-v-5fe218d3>When opened, the panel width snaps from <code data-v-5fe218d3>0 → var(--preview-w)</code> with no animation, squeezing the conversation column in a single layout.</li><li data-v-5fe218d3>At ≤640px the panel becomes a full-screen overlay (<code data-v-5fe218d3>position:fixed; inset:0</code>).</li></ul><h3 class="sub" data-v-5fe218d3>Bottom terminal panel (desktop-only)</h3><p data-v-5fe218d3>The native terminal (<code data-v-5fe218d3>components/terminal/</code>) sits in the conversation column's own bottom grid slot — the sidebar and the right panel span BOTH rows and keep full height (the VS Code layout: the panel belongs to the editor area, not to the whole window). Its height transitions <code data-v-5fe218d3>0 ↔ var(--terminal-h)</code> (260px default, 120 min, 60% viewport max; persisted), squeezing the conversation column above instead of overlaying it. The panel mounts lazily on first open and then stays mounted so xterm scrollback survives a collapse.</p><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>Resize: a horizontal twin of the ResizeHandle (4px strip over the 0.5px top hairline, <code data-v-5fe218d3>row-resize</code> mid-range, <code data-v-5fe218d3>n/s-resize</code> at the limits, same neutral f2/f3 ramp, never accent). The shared <code data-v-5fe218d3>useResizable</code> hook owns it via <code data-v-5fe218d3>axis: 'y'</code>; the height var is written imperatively during a drag (same no-Vue-rerender rule as <code data-v-5fe218d3>--preview-w</code>).</li><li data-v-5fe218d3>Toolbar (32px, 0.5px bottom hairline): tab strip on the left — each tab is a compact <code data-v-5fe218d3>radius-sm</code> pill (leading terminal glyph, muted while exited + shell label + hover close affordance), the active tab uses <code data-v-5fe218d3>--color-selected</code>, hover <code data-v-5fe218d3>--color-hover</code>; a "+" action appends a tab. Tabs follow the §08 tablist keyboard model (roving tabindex, ←/→/Home/End), the close affordance is its own button (no nested interactives), and the height separator is keyboard-operable (↑/↓ in steps, value exposed). Trailing actions: restart (only while the active tab exited) and a collapse chevron. Collapsing sets <code data-v-5fe218d3>inert</code> on the region — the xterm instances and their scrollback stay mounted but leave the tab order.</li><li data-v-5fe218d3>The xterm canvas cannot resolve CSS variables either, so its palette is resolved from the live <code data-v-5fe218d3>--color-*</code> tokens at runtime (re-read on scheme flips; the ANSI hues the status ramp doesn't cover use dedicated <code data-v-5fe218d3>--color-term-magenta/cyan</code> tokens); the font is the app JetBrains Mono stack sized off the content token scale. While focused, the panel owns every key except the registered app shortcuts (chat-level Esc / find / select-all chords stay inert inside it).</li><li data-v-5fe218d3>Entries: the chat header's terminal IconButton (right of Open in, lit while the panel is open) — on the empty-composer state, where no chat header renders, the same button floats at the conversation's top-right instead — plus <code data-v-5fe218d3>ctrl+`</code> (⌃` on macOS — VS Code's binding; ⌘` stays free for the OS window switcher — customizable in the shortcut registry), and the View menu's Toggle Terminal item. New tabs spawn in the visible workspace root. Terminal state is per session: switching sessions swaps the visible bucket while the others keep their PTYs and xterm views alive (scrollback survives a round trip; the ten most recent sessions are kept, LRU). The panel never renders on mobile / web.</li></ul><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>One-sentence principle:</b> the sidebar / shell is a "list + grid" skeleton that reuses the §02 tokens and §03 primitives (Button / IconButton / Badge / Kbd / Menu / Spinner / PanelHeader); compact list controls that don't fit a primitive (search, New chat, inline rename, show-more) keep their custom form, governed by this section. </div></div></section><section id="a11y" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>08</span><h2 class="sec-title" data-v-5fe218d3>Accessibility (pragmatic edition)</h2></div><p class="sec-desc" data-v-5fe218d3> Kimi Web is a local developer tool; it <b data-v-5fe218d3>does not target a specific WCAG conformance level</b>, nor maintain a full screen-reader QA matrix. This section collects only the rules that are "low-cost, don't hurt the look, and directly benefit keyboard-heavy users", as the baseline contract for each primitive; the more expensive, lower-ROI parts (such as real-time announcement orchestration for streaming output) are not mandatory for now. </p><div class="callout info" data-v-5fe218d3><span class="ico" data-v-5fe218d3>i</span><div data-v-5fe218d3><b data-v-5fe218d3>On the "ugly" focus ring:</b> the focus visibility required below always uses <code data-v-5fe218d3>:focus-visible</code> (not <code data-v-5fe218d3>:focus</code>). It appears <b data-v-5fe218d3>only on keyboard focus</b>; mouse clicks don't trigger it, so it doesn't pollute the mouse-driven visual; the ring's strength is tuned uniformly with <code data-v-5fe218d3>--p-focus-ring</code>, not overridden per place. </div></div><h4 class="mini" data-v-5fe218d3>1. Contrast & color</h4><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>Body text vs. background contrast <b data-v-5fe218d3>≥ 4.5:1</b>; control borders, icons, and key graphics <b data-v-5fe218d3>≥ 3:1</b>. When changing theme colors / dark mode, verify against §05 together.</li><li data-v-5fe218d3><b data-v-5fe218d3>Button text vs. button background</b>, and <b data-v-5fe218d3>form controls</b> (input, placeholder, helper / error text) <b data-v-5fe218d3>vs. their section background</b> must all have contrast ≥ 4.5:1 (large text ≥ 3:1). White-on-white text, a transparent borderless button floating over the page background, and a light placeholder on a near-white background are all flagged by the style rules.</li><li data-v-5fe218d3><b data-v-5fe218d3>State is not conveyed by color alone.</b> Error, selected, and disabled states also carry text, an icon, or a shape change (for example an error state is not just red, but also carries text or an icon).</li></ul><h4 class="mini" data-v-5fe218d3>2. Keyboard operable</h4><p data-v-5fe218d3>Anything doable with a mouse must also be doable with a keyboard; Tab order follows the DOM, with no invented skipping. Composite controls define their keyboard model per the table below; a missing model is treated as incomplete:</p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Control</th><th data-v-5fe218d3>Keyboard behavior</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Dialog</td><td data-v-5fe218d3><code data-v-5fe218d3>Tab</code> cycles within the dialog (focus trap); <code data-v-5fe218d3>Esc</code> closes; focus returns to the trigger element after closing.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Menu</td><td data-v-5fe218d3><code data-v-5fe218d3>↑</code> / <code data-v-5fe218d3>↓</code> move the highlight, <code data-v-5fe218d3>Enter</code> selects, <code data-v-5fe218d3>Esc</code> closes.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Tabs</td><td data-v-5fe218d3><code data-v-5fe218d3>←</code> / <code data-v-5fe218d3>→</code> switch tabs (roving tabindex); only the current tab is in the Tab sequence.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Switch / Segmented</td><td data-v-5fe218d3><code data-v-5fe218d3>←</code> / <code data-v-5fe218d3>→</code> or <code data-v-5fe218d3>Space</code> / <code data-v-5fe218d3>Enter</code> to toggle.</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>3. Focus visibility</h4><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3>Every interactive element must have a visible focus indicator on keyboard focus, uniformly via <code data-v-5fe218d3>:focus-visible</code> + <code data-v-5fe218d3>--p-focus-ring</code> (primary actions may use <code data-v-5fe218d3>--p-focus-ring-strong</code>).</li><li data-v-5fe218d3>Bare <code data-v-5fe218d3>outline: none</code> is forbidden. To remove the default outline, you must provide an equivalent replacement style.</li></ul><h4 class="mini" data-v-5fe218d3>4. Labels & semantics</h4><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3><b data-v-5fe218d3>Semantic HTML first</b> (button / a / input / dialog…); ARIA is added only when native semantics fall short.</li><li data-v-5fe218d3>Icon-only buttons must have an <code data-v-5fe218d3>aria-label</code> — <code data-v-5fe218d3>IconButton</code> already enforces this with a required <code data-v-5fe218d3>label</code> prop.</li><li data-v-5fe218d3>Dialog: <code data-v-5fe218d3>role="dialog"</code> + <code data-v-5fe218d3>aria-modal="true"</code>, with the title as the dialog's accessible name.</li><li data-v-5fe218d3>Purely decorative SVG / icons get <code data-v-5fe218d3>aria-hidden="true"</code> to avoid being read out by screen readers.</li></ul><h4 class="mini" data-v-5fe218d3>5. Target size</h4><p data-v-5fe218d3>Desktop click targets <b data-v-5fe218d3>≥ 32px</b>; touch devices <b data-v-5fe218d3>≥ 44px</b> (consistent with the §01 principle and the IconButton <code data-v-5fe218d3>lg</code> tier).</p><h4 class="mini" data-v-5fe218d3>6. Reduced motion</h4><p data-v-5fe218d3>Handled uniformly in the global styles per §02's <code data-v-5fe218d3>@media (prefers-reduced-motion: reduce)</code>; components do not check this individually. The chat working indicator's mascot renders its static fallback.</p><h4 class="mini" data-v-5fe218d3>7. Live announcements (non-mandatory)</h4><p data-v-5fe218d3>Screen-reader announcements are <b data-v-5fe218d3>not a mandatory contract</b> in this product. Short hints like Toast can use <code data-v-5fe218d3>role="status"</code> / <code data-v-5fe218d3>aria-live</code>; chat streaming output is currently not announced word-by-word, which is an acceptable trade-off, to be added later if a real need arises.</p><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3><b data-v-5fe218d3>Explicitly not mandatory for now:</b> a WCAG conformance-level claim, a complete ARIA pattern table, a per-screen-reader QA matrix, and real-time announcement orchestration for streaming output — these are not written into the primitive contract, to avoid becoming slogans no one maintains. </div></div></section><section id="dialogs" data-v-5fe218d3><div class="sec-head" data-v-5fe218d3><span class="sec-num" data-v-5fe218d3>09</span><h2 class="sec-title" data-v-5fe218d3>Dialogs</h2></div><p class="sec-desc" data-v-5fe218d3> Every overlay in the app — pickers, browsers, managers, confirmations — is built on the single §03 Dialog primitive. This chapter fixes the two layout anatomies allowed inside that frame, plus the row and footer contracts that make all dialogs read as one family. Do not hand-roll a third anatomy. </p><h3 class="sub" data-v-5fe218d3>The frame (recap)</h3><p data-v-5fe218d3> All dialogs share the §03 primitive: <code data-v-5fe218d3>--radius-xl</code> radius, <code data-v-5fe218d3>--shadow-xl</code> shadow, a restrained 28% neutral backdrop, a head (title + IconButton close), a body, and a right-aligned foot. Widths <code data-v-5fe218d3>md</code> 440 / <code data-v-5fe218d3>lg</code> 640 / <code data-v-5fe218d3>xl</code> 760 and <code data-v-5fe218d3>auto</code> / <code data-v-5fe218d3>fixed</code> height are chosen per §03. One interruptive overlay at a time; <code data-v-5fe218d3>Esc</code> closes; focus is trapped and restored. A blocking flow that must be resolved rather than dismissed (server token) uses <code data-v-5fe218d3>hideClose</code> with <code data-v-5fe218d3>closeOnOverlay</code>/<code data-v-5fe218d3>closeOnEsc</code> off — never a hand-written overlay. </p><h3 class="sub" data-v-5fe218d3>Anatomy A — padded (forms & confirmations)</h3><p data-v-5fe218d3> The default: the body carries its own padding and the caller drops content straight in. Confirmations put their Buttons in the <code data-v-5fe218d3>#foot</code> slot (right-aligned, cancel → confirm). Used by: confirm, login, status panel, server token. </p><h3 class="sub" data-v-5fe218d3>Anatomy B — flush (pickers & browsers)</h3><p data-v-5fe218d3><code data-v-5fe218d3>:padded="false"</code> with <code data-v-5fe218d3>height="fixed"</code>; the consumer owns the zone layout inside a full-height column. The zones below are the whole vocabulary — a picker dialog composes them and adds nothing else. Used by: model picker, session search, folder browser, provider manager. </p><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Zone</th><th data-v-5fe218d3>Contract</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Search</td><td data-v-5fe218d3>The boxed §03 Input, inset 22px so its edge aligns with the head title. Autofocus on open. No leading icon, no borderless variant.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Filter chips</td><td data-v-5fe218d3>Optional. 28px pill: transparent + muted text by default, <code data-v-5fe218d3>--color-hover</code> on hover, <code data-v-5fe218d3>--color-selected</code> + medium <code data-v-5fe218d3>--color-text</code> when active. Horizontally scrollable with the scrollbar hidden. Never a row of Buttons.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>List</td><td data-v-5fe218d3><code data-v-5fe218d3>flex:1</code>, owns the vertical scrolling, padded 4px 8px so rows bleed near the dialog edge. <code data-v-5fe218d3>role="listbox"</code>; rows carry <code data-v-5fe218d3>role="option"</code> + <code data-v-5fe218d3>aria-selected</code>.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Row</td><td data-v-5fe218d3>8px 12px padding, <code data-v-5fe218d3>--radius-md</code>. Two quiet lines: name 14/20 (medium when current) and a meta line 12/18 in <code data-v-5fe218d3>--color-text-faint</code> — provider · context · capability labels, dot-separated. No badge rows, no raw-id line (search still matches them). Trailing slot: check icon (current row only), then the star IconButton.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Row states</td><td data-v-5fe218d3>Hover / keyboard-selected → <code data-v-5fe218d3>--color-hover</code>; current → <code data-v-5fe218d3>--color-selected</code> — a neutral "where I am" fill, never an accent tint, never an inset stroke. The star stays hidden until row hover, keyboard selection, or starred; it is always visible on touch devices and colored <code data-v-5fe218d3>--star</code> when starred.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>State rows</td><td data-v-5fe218d3>Loading / unavailable / empty: centered on both axes, muted 14px; warning color only for the unavailable case.</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Shortcut bar</td><td data-v-5fe218d3>The footer: full-bleed, padding 8px 16px, <code data-v-5fe218d3>border-top --color-line</code>, left-aligned. Keyboard hints are Kbd keycaps + 12px <code data-v-5fe218d3>--color-text-faint</code> labels, groups separated by "·", the whole bar <code data-v-5fe218d3>aria-hidden</code>. An instructional sentence (folder browser) reuses the same bar without keycaps.</td></tr></tbody></table><h4 class="mini" data-v-5fe218d3>Keyboard & behavior contract</h4><ul class="clean" data-v-5fe218d3><li data-v-5fe218d3><code data-v-5fe218d3>↑</code>/<code data-v-5fe218d3>↓</code> move a keyboard selection (rendered identical to hover) and always <code data-v-5fe218d3>scrollIntoView({ block: 'nearest' })</code>; <code data-v-5fe218d3>Enter</code> selects and closes; <code data-v-5fe218d3>Esc</code> closes.</li><li data-v-5fe218d3>Pointer hover drives the same selection index, so keyboard and mouse never disagree about which row is active.</li><li data-v-5fe218d3>Rows transition <code data-v-5fe218d3>background</code> only (<code data-v-5fe218d3>--duration-fast</code> ease-out); the open/close animation lives in the primitive, not in the consumer.</li><li data-v-5fe218d3>Selection is a fill, not a border (surface over stroke). Accent blue is reserved for actions — primary buttons and focus rings — never for "which row am I on".</li></ul><h4 class="mini" data-v-5fe218d3>Dialog map</h4><table class="dt" data-v-5fe218d3><thead data-v-5fe218d3><tr data-v-5fe218d3><th data-v-5fe218d3>Dialog</th><th data-v-5fe218d3>Anatomy</th><th data-v-5fe218d3>Composition</th></tr></thead><tbody data-v-5fe218d3><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Model picker</td><td data-v-5fe218d3>flush · lg · fixed</td><td data-v-5fe218d3>search + provider chips + model rows + shortcut bar</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Session search</td><td data-v-5fe218d3>flush · lg · fixed</td><td data-v-5fe218d3>search + result rows + shortcut bar</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Folder browser</td><td data-v-5fe218d3>flush · lg · fixed</td><td data-v-5fe218d3>breadcrumb bar + filter bar + folder rows + actions + hint bar</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Provider manager</td><td data-v-5fe218d3>flush · xl · fixed</td><td data-v-5fe218d3>management rows with inset dividers (rows are not selectable) + add section + shortcut bar</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Confirm / Login / Status</td><td data-v-5fe218d3>padded · md · auto</td><td data-v-5fe218d3>title + message or form + right-aligned foot</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>App update (desktop)</td><td data-v-5fe218d3>padded · lg · auto</td><td data-v-5fe218d3>version title + quiet meta line (release date · current version) + height-capped scrolling what's-new list / progress bar + right-aligned action row (skip → download, later → restart) with the auto-download checkbox right-aligned on its own foot row below (a pure preference for future checks)</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Server token</td><td data-v-5fe218d3>padded · md · auto</td><td data-v-5fe218d3><code data-v-5fe218d3>hideClose</code>, no Esc/overlay close — resolved only by a valid token</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Settings</td><td data-v-5fe218d3>flush · xl · fixed</td><td data-v-5fe218d3>page-like exception: side-nav region, per §03</td></tr><tr data-v-5fe218d3><td class="tk" data-v-5fe218d3>Onboarding wizard</td><td data-v-5fe218d3>not a Dialog</td><td data-v-5fe218d3>full-page takeover (not built on §03): one centered column (brand lockup → step content → ghost actions + centered primary CTA); selectable options share the option-card pattern — 0.5px <code data-v-5fe218d3>--color-line</code> hairline, <code data-v-5fe218d3>--color-accent</code> border + <code data-v-5fe218d3>--color-accent-soft</code> fill when selected</td></tr></tbody></table><div class="callout good" data-v-5fe218d3><span class="ico" data-v-5fe218d3>✓</span><div data-v-5fe218d3><b data-v-5fe218d3>Design intent:</b> a picker dialog should feel like a quiet command palette — one boxed search, calm rows, a neutral "you are here" fill, and a predictable shortcut bar. Anything noisier — badge clouds, accent-selected rows, per-dialog footer inventions — is a regression to weed out. </div></div></section>',5))])])])]))}}),Se=M(ke,[["__scopeId","data-v-5fe218d3"]]);export{Se as default}; diff --git a/apps/kimi-code/dist-web/assets/DesignSystemView-DId9_nyG.css b/apps/kimi-code/dist-web/assets/DesignSystemView-DId9_nyG.css deleted file mode 100644 index cf76643a6..000000000 --- a/apps/kimi-code/dist-web/assets/DesignSystemView-DId9_nyG.css +++ /dev/null @@ -1 +0,0 @@ -.ds-page[data-v-247f7c56]{--d-bg: var(--color-bg);--d-surface: var(--color-surface);--d-surface-2: var(--color-surface-sunken);--d-surface-3: var(--color-line);--d-fg: var(--color-text);--d-fg-soft: var(--color-text-muted);--d-fg-muted: var(--color-text-muted);--d-fg-faint: var(--color-text-faint);--d-line: var(--color-line);--d-line-2: var(--color-line);--d-accent: var(--color-accent);--d-accent-2: var(--color-accent-hover);--d-accent-soft: var(--color-accent-soft);--d-accent-bd: var(--color-accent-bd);--d-green: var(--color-success);--d-green-soft: var(--color-success-soft);--d-amber: var(--color-warning);--d-amber-soft: var(--color-warning-soft);--d-red: var(--color-danger);--d-red-soft: var(--color-danger-soft);--d-violet: var(--color-done);--d-code-bg: var(--color-surface-sunken);--d-sidebar: var(--color-surface);--d-shadow-sm: var(--shadow-sm);--d-shadow-md: var(--shadow-md);--d-shadow-lg: var(--shadow-lg);--sidebar-w: var(--p-sidebar-w);--content-max: var(--p-content-wide)}.ds-page[data-v-247f7c56] *,.ds-page[data-v-247f7c56] *:before,.ds-page[data-v-247f7c56] *:after{box-sizing:border-box}.ds-page[data-v-247f7c56]{scroll-behavior:smooth}.ds-page[data-v-247f7c56]{margin:0;background:var(--d-bg);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);line-height:1.65;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1[data-v-247f7c56],h2[data-v-247f7c56],h3[data-v-247f7c56],h4[data-v-247f7c56]{color:var(--d-fg);letter-spacing:-.01em;line-height:1.25;margin:0}p[data-v-247f7c56]{margin:0 0 14px;color:var(--d-fg-soft)}a[data-v-247f7c56]{color:var(--d-accent-2);text-decoration:none}a[data-v-247f7c56]:hover{text-decoration:underline}code[data-v-247f7c56],pre[data-v-247f7c56],.mono[data-v-247f7c56]{font-family:JetBrains Mono,ui-monospace,SF Mono,Menlo,Consolas,monospace}code[data-v-247f7c56]{background:var(--d-code-bg);border:.5px solid var(--d-line-2);border-radius:5px;padding:1px 6px;font-size:.88em;color:#1f2937;white-space:nowrap}.layout[data-v-247f7c56]{display:grid;grid-template-columns:var(--sidebar-w) minmax(0,1fr);min-height:100vh}.sidebar[data-v-247f7c56]{position:sticky;top:0;align-self:start;height:100vh;background:var(--d-sidebar);border-right:.5px solid var(--d-line);padding:26px 22px;overflow-y:auto}.brand[data-v-247f7c56]{display:flex;align-items:center;gap:10px;margin-bottom:6px}.brand-mark[data-v-247f7c56]{width:26px;height:26px;border-radius:7px;flex:none;background:var(--d-fg);color:#fff;display:grid;place-items:center;font-weight:800;font-size:14px;letter-spacing:-.04em}.brand-name[data-v-247f7c56]{font-weight:700;font-size:15px;letter-spacing:-.01em}.brand-sub[data-v-247f7c56]{font-size:12px;color:var(--d-fg-faint);margin-bottom:26px;padding-left:36px}.nav-group[data-v-247f7c56]{margin:22px 0 8px;font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--d-fg-faint)}.p-section-label[data-v-247f7c56]{font-size:12px;font-weight:600;text-transform:uppercase;color:var(--d-fg-faint)}.nav a[data-v-247f7c56]{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:7px;font-size:13.5px;font-weight:500;color:var(--d-fg-soft);margin:1px 0;transition:background .15s,color .15s}.nav a .num[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--d-fg-faint);width:18px}.nav a[data-v-247f7c56]:hover{background:var(--color-hover);color:var(--d-fg);text-decoration:none}.nav a.active[data-v-247f7c56]{background:var(--color-hover);color:var(--d-fg)}.nav a.active .num[data-v-247f7c56]{color:var(--d-fg-soft)}.content[data-v-247f7c56]{min-width:0}.content-inner[data-v-247f7c56]{max-width:var(--content-max);margin:0 auto;padding:64px 56px 120px}section[data-v-247f7c56]{scroll-margin-top:32px;padding-top:8px}section+section[data-v-247f7c56]{margin-top:72px}.hero[data-v-247f7c56]{padding:8px 0 40px;border-bottom:.5px solid var(--d-line);margin-bottom:56px}.eyebrow[data-v-247f7c56]{display:inline-flex;align-items:center;gap:8px;font-family:JetBrains Mono,monospace;font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--d-fg);background:#1783ff1a;border:none;padding:6px 12px;border-radius:8px;margin-bottom:22px}.hero h1[data-v-247f7c56]{font-size:48px;font-weight:600;line-height:1.08;letter-spacing:-.025em;margin-bottom:18px}.hero h1 .grad[data-v-247f7c56]{color:var(--d-accent)}.hero p.lead[data-v-247f7c56]{font-size:18px;line-height:1.6;color:var(--d-fg-soft);max-width:680px}.hero-meta[data-v-247f7c56]{display:flex;flex-wrap:wrap;gap:10px;margin-top:28px}.meta-chip[data-v-247f7c56]{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;color:var(--d-fg-muted);background:var(--d-surface);border:.5px solid var(--d-line);border-radius:8px;padding:7px 12px}.meta-chip b[data-v-247f7c56]{color:var(--d-fg);font-weight:600}.meta-chip .dot[data-v-247f7c56]{width:7px;height:7px;border-radius:50%;background:var(--d-green)}.sec-head[data-v-247f7c56]{display:flex;align-items:baseline;gap:14px;margin-bottom:8px}.sec-num[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:13px;font-weight:600;color:var(--d-accent-2)}.sec-title[data-v-247f7c56]{font-size:26px;letter-spacing:-.02em}.sec-desc[data-v-247f7c56]{font-size:15.5px;color:var(--d-fg-muted);max-width:720px;margin-bottom:28px}h3.sub[data-v-247f7c56]{font-size:17px;margin:40px 0 14px;display:flex;align-items:center;gap:10px}h3.sub[data-v-247f7c56]:before{content:"";width:4px;height:16px;border-radius:2px;background:var(--d-accent)}h4.mini[data-v-247f7c56]{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--d-fg-muted);margin:24px 0 12px}.stat-grid[data-v-247f7c56]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:24px 0}.stat[data-v-247f7c56]{background:var(--d-surface);border:.5px solid var(--d-line);border-radius:14px;padding:18px 18px 16px}.stat .v[data-v-247f7c56]{font-size:34px;font-weight:800;letter-spacing:-.03em;line-height:1;color:var(--d-fg)}.stat .v small[data-v-247f7c56]{font-size:16px;color:var(--d-fg-muted);font-weight:600}.stat .l[data-v-247f7c56]{font-size:12.5px;color:var(--d-fg-muted);margin-top:8px;line-height:1.4}.stat.warn[data-v-247f7c56]{background:var(--d-amber-soft);border-color:#f0d9b8}.stat.warn .v[data-v-247f7c56]{color:var(--d-amber)}.stat.bad[data-v-247f7c56]{background:var(--d-red-soft);border-color:#f0cccc}.stat.bad .v[data-v-247f7c56]{color:var(--d-red)}.stat.good[data-v-247f7c56]{background:var(--d-green-soft);border-color:#bfe3cc}.stat.good .v[data-v-247f7c56]{color:var(--d-green)}.panel[data-v-247f7c56]{background:var(--d-bg);border:.5px solid var(--d-line);border-radius:16px;box-shadow:var(--d-shadow-sm)}.panel-pad[data-v-247f7c56]{padding:22px}.panel-soft[data-v-247f7c56]{background:var(--d-surface);border:.5px solid var(--d-line);border-radius:14px}.callout[data-v-247f7c56]{display:flex;gap:12px;padding:14px 16px;border-radius:12px;font-size:14px;line-height:1.55;background:var(--d-surface);border:.5px solid var(--d-line);color:var(--d-fg-soft);margin:18px 0}.callout .ico[data-v-247f7c56]{flex:none;width:20px;height:20px;border-radius:6px;display:grid;place-items:center;font-size:12px;font-weight:800}.callout.info[data-v-247f7c56]{background:var(--d-accent-soft);border-color:var(--d-accent-bd)}.callout.info .ico[data-v-247f7c56]{background:var(--d-accent);color:#fff}.callout.warn[data-v-247f7c56]{background:var(--d-amber-soft);border-color:#f0d9b8}.callout.warn .ico[data-v-247f7c56]{background:var(--d-amber);color:#fff}.callout.good[data-v-247f7c56]{background:var(--d-green-soft);border-color:#bfe3cc}.callout.good .ico[data-v-247f7c56]{background:var(--d-green);color:#fff}table.dt[data-v-247f7c56]{width:100%;border-collapse:collapse;font-size:13.5px;margin:16px 0}table.dt th[data-v-247f7c56]{text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--d-fg-faint);font-weight:700;padding:10px 12px;border-bottom:.5px solid var(--d-line)}table.dt td[data-v-247f7c56]{padding:11px 12px;border-bottom:.5px solid var(--d-line-2);color:var(--d-fg-soft);vertical-align:middle}table.dt tr:last-child td[data-v-247f7c56]{border-bottom:none}table.dt td.tk[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:12.5px;color:var(--d-fg);white-space:nowrap}table.dt td.val[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.swatch[data-v-247f7c56]{display:inline-block;width:16px;height:16px;border-radius:4px;border:.5px solid rgba(0,0,0,.08);vertical-align:-3px;margin-right:8px}.palette[data-v-247f7c56]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:16px 0}.color-card[data-v-247f7c56]{border:.5px solid var(--d-line);border-radius:12px;overflow:hidden;background:var(--d-bg)}.color-chip[data-v-247f7c56]{height:56px;border-bottom:.5px solid var(--d-line)}.color-meta[data-v-247f7c56]{padding:10px 12px 12px}.color-meta .cn[data-v-247f7c56]{font-size:13px;font-weight:600;color:var(--d-fg)}.color-meta .cv[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:11.5px;color:var(--d-fg-muted);margin-top:2px}.type-row[data-v-247f7c56]{display:flex;align-items:baseline;gap:18px;padding:13px 0;border-bottom:.5px solid var(--d-line-2)}.type-row[data-v-247f7c56]:last-child{border-bottom:none}.type-sample[data-v-247f7c56]{flex:1;color:var(--d-fg);line-height:1.2}.type-meta[data-v-247f7c56]{width:190px;flex:none;text-align:right;font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.space-row[data-v-247f7c56]{display:flex;align-items:center;gap:16px;padding:10px 0;border-bottom:.5px solid var(--d-line-2)}.space-row[data-v-247f7c56]:last-child{border-bottom:none}.space-bar[data-v-247f7c56]{height:18px;border-radius:4px;background:linear-gradient(90deg,var(--d-accent),var(--d-accent-2));flex:none}.space-meta[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:12.5px;color:var(--d-fg-soft);width:150px}.space-use[data-v-247f7c56]{font-size:12.5px;color:var(--d-fg-muted)}.radius-grid[data-v-247f7c56]{display:flex;flex-wrap:wrap;gap:22px;align-items:flex-end;margin:16px 0}.radius-item[data-v-247f7c56]{display:flex;flex-direction:column;align-items:center;gap:10px}.radius-box[data-v-247f7c56]{width:64px;height:64px;border:.5px solid var(--d-accent);background:var(--d-accent-soft)}.radius-item .rl[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-soft)}.stage-wrap[data-v-247f7c56]{border:.5px solid var(--d-line);border-radius:16px;overflow:hidden;margin:18px 0;background:var(--d-bg);box-shadow:var(--d-shadow-sm)}.stage-bar[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:.5px solid var(--d-line);background:var(--d-surface)}.stage-bar .st[data-v-247f7c56]{font-size:13px;font-weight:600;color:var(--d-fg);display:flex;align-items:center;gap:8px}.stage-bar .st .tag[data-v-247f7c56]{font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:999px}.tag.after[data-v-247f7c56]{background:var(--d-green-soft);color:var(--d-green)}.tag.before[data-v-247f7c56]{background:var(--d-red-soft);color:var(--d-red)}.tag.spec[data-v-247f7c56]{background:var(--d-accent-soft);color:var(--d-accent-2)}.stage-bar .sactions[data-v-247f7c56]{display:flex;gap:6px}.tab[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:11.5px;padding:4px 10px;border-radius:6px;color:var(--d-fg-muted);cursor:default}.tab.on[data-v-247f7c56]{background:var(--d-bg);color:var(--d-fg);border:.5px solid var(--d-line)}.stage[data-v-247f7c56]{padding:32px;display:flex;flex-wrap:wrap;align-items:center;gap:16px;background:radial-gradient(circle at 1px 1px,rgba(0,0,0,.045) 1px,transparent 0) 0 0 / 18px 18px,var(--d-surface)}.stage.col[data-v-247f7c56]{flex-direction:column;align-items:stretch}.stage.dark[data-v-247f7c56]{background:radial-gradient(circle at 1px 1px,rgba(255,255,255,.06) 1px,transparent 0) 0 0 / 18px 18px,#0d1117}.stage-label[data-v-247f7c56]{width:100%;font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--d-fg-faint);margin-bottom:-6px}.stage.dark .stage-label[data-v-247f7c56]{color:#6b7280}.ba[data-v-247f7c56]{display:grid;grid-template-columns:1fr 1fr;gap:0;border:.5px solid var(--d-line);border-radius:16px;overflow:hidden;margin:18px 0;box-shadow:var(--d-shadow-sm)}.ba-col[data-v-247f7c56]{min-width:0}.ba-col+.ba-col[data-v-247f7c56]{border-left:.5px solid var(--d-line)}.ba-head[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;padding:11px 16px;border-bottom:.5px solid var(--d-line)}.ba-head.before[data-v-247f7c56]{background:var(--d-red-soft)}.ba-head.after[data-v-247f7c56]{background:var(--d-green-soft)}.ba-head .bh[data-v-247f7c56]{font-size:13px;font-weight:700}.ba-head.before .bh[data-v-247f7c56]{color:var(--d-red)}.ba-head.after .bh[data-v-247f7c56]{color:var(--d-green)}.ba-head .bh small[data-v-247f7c56]{font-weight:500;opacity:.7;margin-left:6px}.ba-body[data-v-247f7c56]{padding:24px;background:var(--d-surface);min-height:120px}.ba-col.after .ba-body[data-v-247f7c56]{background:#fff}.code[data-v-247f7c56]{background:#0d1117;border-radius:12px;overflow:hidden;margin:16px 0;border:.5px solid #1c2128}.code-bar[data-v-247f7c56]{display:flex;align-items:center;gap:8px;padding:9px 14px;background:#13181e;border-bottom:.5px solid #1c2128}.code-bar .d[data-v-247f7c56]{width:10px;height:10px;border-radius:50%;background:#30363d}.code-bar .fn[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:11.5px;color:#8b949e;margin-left:4px}.code pre[data-v-247f7c56]{margin:0;padding:18px;overflow-x:auto;font-size:12.5px;line-height:1.7;color:#c9d1d9}.code .c[data-v-247f7c56]{color:#8b949e}.code .k[data-v-247f7c56]{color:#ff7b72}.code .s[data-v-247f7c56]{color:#a5d6ff}.code .p[data-v-247f7c56]{color:#79c0ff}.code .n[data-v-247f7c56]{color:#d2a8ff}.code .v[data-v-247f7c56]{color:#ffa657}.pill[data-v-247f7c56]{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;border:.5px solid var(--d-line);background:var(--d-surface);color:var(--d-fg-soft)}.pill.blue[data-v-247f7c56]{background:var(--d-accent-soft);border-color:var(--d-accent-bd);color:var(--d-accent-2)}.pill.green[data-v-247f7c56]{background:var(--d-green-soft);border-color:#bfe3cc;color:var(--d-green)}.pill.amber[data-v-247f7c56]{background:var(--d-amber-soft);border-color:#f0d9b8;color:var(--d-amber)}.pill.red[data-v-247f7c56]{background:var(--d-red-soft);border-color:#f0cccc;color:var(--d-red)}.pill.mono[data-v-247f7c56]{font-family:JetBrains Mono,monospace}ul.clean[data-v-247f7c56]{list-style:none;padding:0;margin:14px 0}ul.clean li[data-v-247f7c56]{position:relative;padding:8px 0 8px 26px;color:var(--d-fg-soft);border-bottom:.5px solid var(--d-line-2)}ul.clean li[data-v-247f7c56]:last-child{border-bottom:none}ul.clean li[data-v-247f7c56]:before{content:"";position:absolute;left:4px;top:17px;width:7px;height:7px;border-radius:50%;background:var(--d-accent)}ul.clean.check li[data-v-247f7c56]:before{content:"✓";background:none;color:var(--d-green);font-weight:800;top:7px;left:0;font-size:14px}ul.clean.cross li[data-v-247f7c56]:before{content:"✕";background:none;color:var(--d-red);font-weight:800;top:7px;left:0;font-size:13px}ul.clean li b[data-v-247f7c56]{color:var(--d-fg)}ul.clean li .path[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.roadmap[data-v-247f7c56]{position:relative;margin:24px 0}.phase[data-v-247f7c56]{position:relative;display:grid;grid-template-columns:120px 1fr;gap:24px;padding:0 0 32px}.phase[data-v-247f7c56]:not(:last-child):after{content:"";position:absolute;left:59px;top:36px;bottom:0;width:2px;background:var(--d-line)}.phase-tag[data-v-247f7c56]{text-align:right;padding-top:4px}.phase-tag .pt[data-v-247f7c56]{display:inline-block;font-family:JetBrains Mono,monospace;font-size:12px;font-weight:700;color:var(--d-accent-2);background:var(--d-accent-soft);border:.5px solid var(--d-accent-bd);padding:5px 10px;border-radius:8px}.phase-tag .pe[data-v-247f7c56]{font-size:11.5px;color:var(--d-fg-faint);margin-top:8px}.phase-body[data-v-247f7c56]{background:var(--d-bg);border:.5px solid var(--d-line);border-radius:14px;padding:18px 20px;box-shadow:var(--d-shadow-sm)}.phase-body h4[data-v-247f7c56]{font-size:16px;margin-bottom:8px}.phase-body p[data-v-247f7c56]{font-size:14px;margin-bottom:12px}.phase-body ul[data-v-247f7c56]{margin:0}.matrix[data-v-247f7c56]{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:16px 0}.anti[data-v-247f7c56]{border:.5px solid var(--d-line);border-radius:12px;padding:16px;background:var(--d-bg)}.anti .ah[data-v-247f7c56]{display:flex;align-items:center;gap:9px;font-size:14px;font-weight:700;margin-bottom:8px}.anti .ah .verdict[data-v-247f7c56]{margin-left:auto;font-size:11px;font-weight:800;padding:2px 8px;border-radius:999px}.verdict.pass[data-v-247f7c56]{background:var(--d-green-soft);color:var(--d-green)}.verdict.fail[data-v-247f7c56]{background:var(--d-red-soft);color:var(--d-red)}.verdict.warn[data-v-247f7c56]{background:var(--d-amber-soft);color:var(--d-amber)}.anti p[data-v-247f7c56]{font-size:13px;margin:0;color:var(--d-fg-muted)}.footer[data-v-247f7c56]{margin-top:80px;padding-top:28px;border-top:.5px solid var(--d-line);font-size:13px;color:var(--d-fg-faint);display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px}.kbd[data-v-247f7c56]{font-family:JetBrains Mono,monospace;font-size:11px;background:var(--d-surface-2);border:.5px solid var(--d-line);border-radius:5px;padding:1px 6px}@media(max-width:980px){.layout[data-v-247f7c56]{grid-template-columns:1fr}.sidebar[data-v-247f7c56]{position:static;height:auto}.nav[data-v-247f7c56]{display:flex;flex-wrap:wrap;gap:4px}.content-inner[data-v-247f7c56]{padding:40px 22px 80px}.stat-grid[data-v-247f7c56]{grid-template-columns:repeat(2,1fr)}.ba[data-v-247f7c56]{grid-template-columns:1fr}.ba-col+.ba-col[data-v-247f7c56]{border-left:none;border-top:.5px solid var(--d-line)}.palette[data-v-247f7c56]{grid-template-columns:repeat(2,1fr)}.matrix[data-v-247f7c56]{grid-template-columns:1fr}}.ds-page .p[data-v-247f7c56],.ds-page .stage.p-skin[data-v-247f7c56],.ds-page [data-p][data-v-247f7c56]{--p-font-sans: var(--font-ui);--p-font-kbd: var(--font-kbd);--p-font-mono: var(--font-mono);--p-bg: var(--color-bg);--p-surface: var(--color-surface);--p-surface-raised: var(--color-surface-raised);--p-surface-overlay: var(--color-surface-overlay);--p-surface-sunken: var(--color-surface-sunken);--p-well: var(--color-well);--p-surface-deep: var(--color-surface-deep);--p-hover: var(--color-hover);--p-text: var(--color-text);--p-text-strong: var(--color-text-strong);--p-muted: var(--muted);--p-text-muted: var(--color-text-muted);--p-text-faint: var(--color-text-faint);--p-text-on-accent: var(--color-text-on-accent);--p-line: var(--color-line);--p-line-strong: var(--color-line-strong);--p-accent: var(--color-accent);--p-accent-hover: var(--color-accent-hover);--p-accent-soft: var(--color-accent-soft);--p-user-bubble-bg: var(--color-user-bubble-bg);--p-accent-bd: var(--color-accent-bd);--p-success: var(--color-success);--p-success-soft: var(--color-success-soft);--p-success-bd: var(--color-success-bd);--p-warning: var(--color-warning);--p-warning-soft: var(--color-warning-soft);--p-warning-bd: var(--color-warning-bd);--p-danger: var(--color-danger);--p-danger-soft: var(--color-danger-soft);--p-danger-bd: var(--color-danger-bd);--p-info: var(--color-info);--p-sp-1: var(--space-1);--p-sp-2: var(--space-2);--p-sp-3: var(--space-3);--p-sp-4: var(--space-4);--p-sp-5: var(--space-5);--p-sp-6: var(--space-6);--p-sp-8: var(--space-8);--p-r-xs: var(--radius-xs);--p-r-sm: var(--radius-sm);--p-r-md: var(--radius-md);--p-r-lg: var(--radius-lg);--p-r-xl: var(--radius-xl);--p-r-composer: var(--radius-composer);--p-r-full: var(--radius-full);--p-corner-composer: var(--corner-shape-composer);--p-sh-xs: var(--shadow-xs);--p-sh-sm: var(--shadow-sm);--p-sh-menu: var(--shadow-menu);--p-sh-md: var(--shadow-md);--p-sh-input: var(--shadow-input);--p-sh-lg: var(--shadow-lg);--p-sh-xl: var(--shadow-xl);--p-font-size-xs: var(--text-xs);--p-font-size-sm: var(--text-sm);--p-font-size-base: var(--text-base);--p-font-size-md: var(--text-base);--p-font-size-lg: var(--text-lg);--p-font-size-xl: var(--text-xl);--p-font-size-2xl: var(--text-2xl);--p-leading-tight: var(--leading-tight);--p-leading-normal: var(--leading-normal);--p-leading-relaxed: var(--leading-relaxed);--p-ease: var(--ease-out);--p-ease-inout: var(--ease-in-out);--p-dur-fast: var(--duration-fast);--p-dur: var(--duration-base);--p-dur-slow: var(--duration-slow);--p-composer-focus-line: var(--color-composer-focus-line);font-family:var(--font-ui);color:var(--color-text);font-size:var(--text-base)}[data-p=dark][data-v-247f7c56]{--p-bg: #0d1117;--p-surface: #13181e;--p-surface-raised: #1c2128;--p-surface-sunken: #0d1117;--p-well: #13181e;--p-surface-deep: #0a0d12;--p-surface-overlay: #22272e;--p-hover: #ffffff0d;--p-text: #e8eaed;--p-text-strong: #ffffff;--p-muted: #727983;--p-text-muted: #9aa0a8;--p-text-faint: #6b7280;--p-line: #2d333b;--p-line-strong: #3d444d;--p-accent: #58a6ff;--p-accent-hover: #79b8ff;--p-accent-soft: rgba(88,166,255,.14);--p-accent-bd: rgba(88,166,255,.28);--p-success: #3fb950;--p-success-soft: rgba(63,185,80,.14);--p-success-bd: rgba(63,185,80,.28);--p-warning: #d29922;--p-warning-soft: rgba(210,153,34,.14);--p-warning-bd: rgba(210,153,34,.28);--p-danger: #f85149;--p-danger-soft: rgba(248,81,73,.14);--p-danger-bd: rgba(248,81,73,.28);--p-sh-sm: 0 1px 2px rgba(0,0,0,.4);--p-sh-md: 0 4px 12px rgba(0,0,0,.45);--p-sh-lg: 0 12px 32px rgba(0,0,0,.55);--p-sh-input: var(--shadow-input);--p-selection: rgba(88,166,255,.32)}.p-ic[data-v-247f7c56]{width:16px;height:16px;flex:none;display:inline-block;vertical-align:middle}.p-btn[data-v-247f7c56]{--_h: 36px;--_px: 16px;--_fs: var(--p-font-size-base);--_r: var(--p-r-md);display:inline-flex;align-items:center;justify-content:center;gap:8px;height:var(--_h);padding:0 var(--_px);border-radius:var(--_r);font-family:var(--p-font-sans);font-size:var(--_fs);font-weight:600;line-height:1;border:.5px solid transparent;cursor:pointer;white-space:nowrap;transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease),transform var(--p-dur-fast) var(--p-ease)}.p-btn[data-v-247f7c56]:active{transform:scale(.98)}.p-btn[data-v-247f7c56]:focus-visible{outline:none;box-shadow:0 0 0 3px var(--p-accent-soft),0 0 0 1px var(--p-accent)}.p-btn .p-ic[data-v-247f7c56]{width:16px;height:16px}.p-btn.sm[data-v-247f7c56]{--_h: 30px;--_px: 12px;--_fs: var(--p-font-size-sm);--_r: var(--p-r-sm)}.p-btn.sm .p-ic[data-v-247f7c56]{width:14px;height:14px}.p-btn.lg[data-v-247f7c56]{--_h: 42px;--_px: 20px;--_fs: var(--p-font-size-md);--_r: var(--p-r-lg)}.p-btn.primary[data-v-247f7c56]{background:var(--p-accent);color:var(--p-text-on-accent);border-color:var(--p-accent);box-shadow:var(--p-sh-xs)}.p-btn.primary[data-v-247f7c56]:hover{background:var(--p-accent-hover);border-color:var(--p-accent-hover)}.p-btn.secondary[data-v-247f7c56]{background:var(--p-surface-raised);color:var(--p-text);border-color:var(--p-line-strong);box-shadow:var(--p-sh-xs)}.p-btn.secondary[data-v-247f7c56]:hover{background:var(--p-hover);border-color:var(--p-line-strong)}.p-btn.ghost[data-v-247f7c56]{background:transparent;color:var(--p-text);border-color:transparent}.p-btn.ghost[data-v-247f7c56]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-btn.danger[data-v-247f7c56]{background:var(--p-danger);color:#fff;border-color:var(--p-danger);box-shadow:var(--p-sh-xs)}.p-btn.danger[data-v-247f7c56]:hover{filter:brightness(.96)}.p-btn.danger-soft[data-v-247f7c56]{background:var(--p-danger-soft);color:var(--p-danger);border-color:var(--p-danger-bd)}.p-btn.danger-soft[data-v-247f7c56]:hover{background:var(--p-danger);color:#fff;border-color:var(--p-danger)}.p-btn.text[data-v-247f7c56]{height:auto;padding:0;background:transparent;border-color:transparent;border-radius:var(--p-r-xs);color:var(--p-text-muted);font-size:inherit;font-weight:inherit;text-decoration:underline;text-underline-offset:2px}.p-btn.text[data-v-247f7c56]:hover{color:var(--p-text)}.p-btn.text[data-v-247f7c56]:active{transform:none}.demo-inline-text[data-v-247f7c56]{font-size:12px;color:var(--p-text-faint, var(--p-text-muted))}.p-btn[disabled][data-v-247f7c56],.p-btn.disabled[data-v-247f7c56]{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.p-icon-btn[data-v-247f7c56]{--_s: 32px;display:inline-grid;place-items:center;width:var(--_s);height:var(--_s);flex:none;border-radius:var(--p-r-md);border:.5px solid transparent;background:transparent;color:var(--p-text-muted);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-icon-btn[data-v-247f7c56]:hover{background:var(--p-hover);color:var(--p-text)}.p-icon-btn[data-v-247f7c56]:focus-visible{outline:none;box-shadow:0 0 0 3px var(--p-accent-soft)}.p-icon-btn.sm[data-v-247f7c56]{--_s: 26px;border-radius:var(--p-r-sm)}.p-icon-btn.lg[data-v-247f7c56]{--_s: 44px}.p-icon-btn .p-ic[data-v-247f7c56]{width:16px;height:16px}.p-icon-btn.lg .p-ic[data-v-247f7c56]{width:20px;height:20px}.p-badge[data-v-247f7c56]{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:var(--p-r-full);font-family:var(--p-font-sans);font-size:var(--p-font-size-xs);font-weight:600;line-height:1;border:.5px solid var(--p-line);background:var(--p-surface);color:var(--p-text);white-space:nowrap}.p-badge.sm[data-v-247f7c56]{height:18px;padding:0 7px;font-size:11px}.p-badge .bd[data-v-247f7c56]{width:7px;height:7px;border-radius:50%;background:currentColor}.p-badge.neutral[data-v-247f7c56]{background:var(--p-surface-sunken);border-color:var(--p-line);color:var(--p-text-muted)}.p-badge.info[data-v-247f7c56]{background:var(--p-accent-soft);border-color:var(--p-accent-bd);color:var(--p-accent-hover)}.p-badge.success[data-v-247f7c56]{background:var(--p-success-soft);border-color:var(--p-success-bd);color:var(--p-success)}.p-badge.warning[data-v-247f7c56]{background:var(--p-warning-soft);border-color:var(--p-warning-bd);color:var(--p-warning)}.p-badge.danger[data-v-247f7c56]{background:var(--p-danger-soft);border-color:var(--p-danger-bd);color:var(--p-danger)}.p-badge.solid[data-v-247f7c56]{background:var(--p-text);color:var(--p-bg);border-color:var(--p-text)}.p-badge .p-ic[data-v-247f7c56]{width:12px;height:12px}.p-kbd[data-v-247f7c56]{display:inline-flex;align-items:center;gap:3px}.p-kbd kbd[data-v-247f7c56]{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border:.5px solid var(--p-line);border-radius:var(--p-r-xs);background:transparent;color:inherit;font-family:var(--p-font-kbd);font-size:11px;line-height:1}.p-pill[data-v-247f7c56]{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 12px;border-radius:var(--p-r-full);border:.5px solid transparent;background:transparent;font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-pill[data-v-247f7c56]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-pill .pp-strong[data-v-247f7c56]{font-weight:700;color:var(--p-text)}.p-pill .pp-sub[data-v-247f7c56]{color:var(--p-accent);font-weight:600}.p-pill .p-ic[data-v-247f7c56]{width:14px;height:14px;color:var(--p-text-faint)}.p-card[data-v-247f7c56]{background:var(--p-surface);border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;color:var(--p-text)}.p-card.interactive[data-v-247f7c56]{transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease);cursor:pointer}.p-card.interactive[data-v-247f7c56]:hover{background:var(--p-surface);border-color:var(--p-line-strong)}.p-card-head[data-v-247f7c56]{display:flex;align-items:center;gap:9px;padding:10px 14px;border-bottom:.5px solid var(--p-line);background:var(--p-surface)}.p-card-title[data-v-247f7c56]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text);font-family:var(--p-font-mono)}.p-card-body[data-v-247f7c56]{padding:14px;font-size:var(--p-font-size-base);color:var(--p-text);line-height:var(--p-leading-normal)}.p-card-foot[data-v-247f7c56]{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:10px 14px;border-top:.5px solid var(--p-line);background:var(--p-surface)}.p-field[data-v-247f7c56]{display:flex;flex-direction:column;gap:6px}.p-label[data-v-247f7c56]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text)}.p-input[data-v-247f7c56],.p-select[data-v-247f7c56],.p-textarea[data-v-247f7c56]{width:100%;height:38px;padding:0 12px;border-radius:var(--p-r-md);border:.5px solid var(--p-line-strong);background:var(--p-surface-raised);font-family:var(--p-font-sans);font-size:var(--p-font-size-base);color:var(--p-text);box-shadow:var(--p-sh-xs);transition:border-color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease)}.p-textarea[data-v-247f7c56]{height:auto;min-height:84px;padding:10px 12px;resize:vertical;line-height:var(--p-leading-normal)}.p-select[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;text-align:left}.p-select[data-v-247f7c56]:after{content:"⌄";color:var(--p-text-muted)}.p-input[data-v-247f7c56]:hover,.p-select[data-v-247f7c56]:hover,.p-textarea[data-v-247f7c56]:hover{border-color:var(--p-line-strong)}.p-input[data-v-247f7c56]:focus,.p-select[data-v-247f7c56]:focus,.p-textarea[data-v-247f7c56]:focus{outline:none;border-color:var(--p-accent);box-shadow:0 0 0 3px var(--p-accent-soft)}.p-input[data-v-247f7c56]::placeholder,.p-textarea[data-v-247f7c56]::placeholder{color:var(--p-text-faint)}.p-input.sm[data-v-247f7c56]{height:32px;font-size:var(--p-font-size-sm);border-radius:var(--p-r-sm)}.p-hint[data-v-247f7c56]{font-size:var(--p-font-size-xs);color:var(--p-text-faint)}.p-dialog[data-v-247f7c56]{width:480px;max-width:calc(100vw - 48px);background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-xl);box-shadow:var(--p-sh-xl);overflow:hidden;color:var(--p-text)}.p-dialog-head[data-v-247f7c56]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:20px 22px 14px}.p-dialog-title[data-v-247f7c56]{font-size:var(--p-font-size-lg);font-weight:700;letter-spacing:-.01em}.p-dialog-desc[data-v-247f7c56]{font-size:var(--p-font-size-base);color:var(--p-text-muted);margin-top:4px;line-height:var(--p-leading-normal)}.p-dialog-body[data-v-247f7c56]{padding:4px 22px 18px}.p-dialog-foot[data-v-247f7c56]{display:flex;justify-content:flex-end;gap:10px;padding:14px 22px 20px}.p-toast[data-v-247f7c56]{display:flex;align-items:flex-start;gap:11px;width:360px;padding:13px 14px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-md)}.p-toast .ti[data-v-247f7c56]{width:20px;height:20px;border-radius:50%;display:grid;place-items:center;flex:none;margin-top:1px}.p-toast.success .ti[data-v-247f7c56]{background:var(--p-success-soft);color:var(--p-success)}.p-toast.warning .ti[data-v-247f7c56]{background:var(--p-warning-soft);color:var(--p-warning)}.p-toast .tt[data-v-247f7c56]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-toast .td[data-v-247f7c56]{font-size:var(--p-font-size-sm);color:var(--p-text-muted);margin-top:2px;line-height:1.45}.p-action-toast[data-v-247f7c56]{display:inline-flex;align-items:center;gap:8px;align-self:center;padding:4px 6px 4px 14px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-sm);font-size:var(--p-font-size-base);color:var(--p-text);white-space:nowrap}.p-action-toast .lk[data-v-247f7c56]{border:0;padding:0;background:none;color:var(--p-accent);cursor:pointer;font:inherit}.p-action-toast .x[data-v-247f7c56]{color:var(--p-text-muted);width:14px;height:14px}.p-spinner[data-v-247f7c56]{width:18px;height:18px;animation:p-spin-247f7c56 .85s linear infinite}.p-spinner.sm[data-v-247f7c56]{width:14px;height:14px}.p-spinner circle[data-v-247f7c56]{fill:none;stroke-width:2.2;stroke-linecap:round}.p-spinner .track[data-v-247f7c56]{stroke:var(--p-line)}.p-spinner .arc[data-v-247f7c56]{stroke:var(--p-accent);stroke-dasharray:56 56;stroke-dashoffset:38}@keyframes p-spin-247f7c56{to{transform:rotate(360deg)}}.p-thinking[data-v-247f7c56]{display:inline-flex;align-items:center;gap:9px;font-size:var(--p-font-size-sm);color:var(--p-text-muted);font-family:var(--p-font-sans)}.p-bubble-user[data-v-247f7c56]{align-self:flex-end;max-width:var(--p-bubble-max);background:var(--p-user-bubble-bg);border:none;color:var(--p-text);border-radius:var(--p-r-lg);padding:10px 12px;font-size:var(--p-font-size-md);line-height:var(--p-leading-normal)}.p-msg[data-v-247f7c56]{max-width:760px;font-size:var(--p-font-size-md);line-height:var(--p-leading-relaxed);color:var(--p-text)}.p-msg p[data-v-247f7c56]{margin:0 0 10px;color:var(--p-text)}.p-msg code[data-v-247f7c56]{font-family:var(--p-font-mono);background:var(--p-surface-sunken);border:0;color:var(--p-accent-hover);padding:1px 6px;border-radius:5px;font-size:.9em}.p-code[data-v-247f7c56]{font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);line-height:1.65;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);padding:11px 13px;color:var(--p-text);overflow-x:auto}.p-action[data-v-247f7c56]{border-radius:var(--p-r-lg);overflow:hidden;border:.5px solid var(--p-line);background:var(--p-surface-raised);box-shadow:var(--p-sh-menu)}.p-action-head[data-v-247f7c56]{display:flex;align-items:center;gap:9px;padding:14px 16px 0}.p-action-title[data-v-247f7c56]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-action-body[data-v-247f7c56]{padding:12px 16px 0;font-size:var(--p-font-size-base);color:var(--p-text);line-height:var(--p-leading-normal)}.p-action-foot[data-v-247f7c56]{display:flex;gap:8px;margin-top:12px;padding:10px 16px;border-top:.5px solid var(--p-line)}.p-opts[data-v-247f7c56]{display:flex;flex-direction:column;gap:2px;margin-top:12px;padding:12px 16px;border-top:.5px solid var(--p-line)}.p-opt[data-v-247f7c56]{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;border-radius:var(--p-r-md);color:var(--p-text);font-size:var(--p-font-size-base)}.p-opt .n[data-v-247f7c56]{width:var(--p-chip-num);height:var(--p-chip-num);margin-top:calc((var(--p-font-size-base) * var(--p-leading-normal) - var(--p-chip-num)) / 2);border-radius:var(--p-r-sm);background:var(--p-surface-sunken);color:var(--p-text);font-size:var(--p-font-size-xs);font-weight:500;display:inline-flex;align-items:center;justify-content:center;flex:none}.p-opt-text[data-v-247f7c56]{display:flex;flex-direction:column;gap:2px;min-width:0}.p-opt-text .l[data-v-247f7c56]{font-weight:500}.p-opt-text .d[data-v-247f7c56]{font-size:var(--p-font-size-xs);color:var(--p-text-muted);line-height:var(--p-leading-normal)}.p-todo[data-v-247f7c56]{background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-md);padding:6px}.p-todo-row[data-v-247f7c56]{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--p-r-md);font-size:var(--p-font-size-base);color:var(--p-text)}.p-todo-row.done[data-v-247f7c56]{color:var(--p-text-faint);text-decoration:line-through}.p-todo-row.active[data-v-247f7c56]{background:var(--p-accent-soft);color:var(--p-text)}.p-todo-check[data-v-247f7c56]{width:16px;flex:none;display:inline-flex;align-items:center;justify-content:center;user-select:none;color:var(--p-text-faint)}.p-todo-check svg[data-v-247f7c56]{width:14px;height:14px}.p-todo-row.active .p-todo-check[data-v-247f7c56]{color:var(--p-accent)}.p-todo-row.done .p-todo-check[data-v-247f7c56]{color:var(--p-success)}.p-todo-row.active .p-todo-check[data-v-247f7c56]{color:var(--p-accent);font-weight:500}.p-dot[data-v-247f7c56]{width:7px;height:7px;border-radius:50%;flex:none;background:var(--p-text-faint)}.p-dot.done[data-v-247f7c56]{background:var(--p-success)}.p-dot.error[data-v-247f7c56]{background:var(--p-danger)}.p-dot.running[data-v-247f7c56]{background:var(--p-accent);box-shadow:0 0 0 0 var(--p-accent-soft);animation:p-pulse-247f7c56 1.4s ease-out infinite}@keyframes p-pulse-247f7c56{0%{box-shadow:0 0 #1783ff66}to{box-shadow:0 0 0 6px #1783ff00}}.p-tool-group[data-v-247f7c56]{overflow:hidden}.p-tool-group-head[data-v-247f7c56]{display:flex;align-items:center;gap:4px;padding:4px 0;cursor:pointer;border-radius:6px;font-size:var(--p-font-size-sm);line-height:1;color:var(--p-text-faint);user-select:none;transition:color var(--p-dur) var(--p-ease)}.p-tool-group-head .tg-ic[data-v-247f7c56]{width:14px;height:14px;color:var(--p-text-faint);flex:none}.p-tool-group-head[data-v-247f7c56]:hover{color:var(--p-text)}.p-tool-group-head .tg-title[data-v-247f7c56]{font-weight:500}.p-tool-group-head .tg-meta[data-v-247f7c56]{color:var(--p-text-faint);font-weight:400}.p-tool-group-head .tg-car[data-v-247f7c56]{width:14px;height:14px;color:var(--p-text-faint);transition:transform var(--p-dur) var(--p-ease)}.p-tool-group.open .p-tool-group-head .tg-car[data-v-247f7c56]{transform:rotate(90deg)}.p-tool-row[data-v-247f7c56]{position:relative;display:flex;align-items:center;gap:4px;padding:4px 0;border-radius:6px;cursor:pointer;font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);line-height:1;color:var(--p-text)}.p-tool-row .tr-ic[data-v-247f7c56]{width:14px;height:14px;color:var(--p-text-faint);flex:none}.p-tool-row .tr-name[data-v-247f7c56]{font-weight:400;color:var(--p-text-muted);flex:none}.p-tool-row .tr-file[data-v-247f7c56]{font-weight:400;color:var(--p-text);flex:none}.p-tool-row .tr-file[data-v-247f7c56]:hover{color:var(--p-accent);text-decoration:underline;text-underline-offset:3px}.p-tool-row .tr-mono[data-v-247f7c56]{font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);line-height:normal;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--p-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.p-tool-row .tr-faint[data-v-247f7c56]{color:var(--p-text-faint);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.p-tool-row .tr-chip[data-v-247f7c56]{margin-left:auto;color:var(--p-text-faint);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-add[data-v-247f7c56]{margin-left:auto;color:var(--p-success);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-add~.tr-chip[data-v-247f7c56],.p-tool-row .tr-add~.tr-add[data-v-247f7c56]{margin-left:0}.p-tool-row .tr-del[data-v-247f7c56]{color:var(--p-danger);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-bar[data-v-247f7c56]{display:inline-flex;width:36px;height:3px;border-radius:999px;overflow:hidden;gap:1px;flex:none}.p-tool-row .tr-ok[data-v-247f7c56]{color:var(--p-success);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-car[data-v-247f7c56]{width:13px;height:13px;color:var(--p-text-faint);flex:none;transition:transform var(--p-dur) var(--p-ease)}.p-agent-card[data-v-247f7c56]{display:flex;align-items:center;gap:8px;align-self:stretch;padding:8px 12px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);cursor:pointer}.p-agent-card .pa-ic[data-v-247f7c56]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;background:var(--p-surface-sunken);color:var(--p-text-muted);flex:none}.p-agent-card .pa-ic svg[data-v-247f7c56]{width:14px;height:14px}.p-agent-card .pa-main[data-v-247f7c56]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.p-agent-card .pa-task[data-v-247f7c56]{font-size:var(--p-font-size-sm);line-height:1.4;color:var(--p-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-agent-card .pa-type[data-v-247f7c56]{font-size:var(--p-font-size-xs);line-height:1.4;color:var(--p-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-agent-card .pa-ok[data-v-247f7c56]{color:var(--p-success);font-size:var(--p-font-size-xs);flex:none}.p-agent-card .pa-go[data-v-247f7c56]{color:var(--p-text-faint);flex:none}.p-tool-row.expanded .tr-car[data-v-247f7c56]{transform:rotate(90deg)}.p-tool-detail[data-v-247f7c56]{padding:2px 8px 4px 0}.p-tool-detail .p-code[data-v-247f7c56]{margin-top:4px}.p-composer[data-v-247f7c56]{background:var(--p-surface-raised);border:.5px solid var(--p-line-strong);border-radius:var(--p-r-composer);corner-shape:var(--p-corner-composer);box-shadow:var(--p-sh-input);overflow:hidden;position:relative;z-index:1}.p-composer[data-v-247f7c56]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--p-composer-focus-line);border-radius:var(--p-r-composer);corner-shape:var(--p-corner-composer);opacity:0;pointer-events:none;transition:opacity var(--p-dur-slow) var(--p-ease-inout)}.p-composer[data-v-247f7c56]:focus-within:after{opacity:1}.p-composer-ta[data-v-247f7c56]{padding:14px 16px 8px;font-family:var(--p-font-sans);font-size:var(--p-font-size-md);color:var(--p-text);line-height:var(--p-leading-normal);text-autospace:normal}.p-composer-ta.ph[data-v-247f7c56]{color:var(--p-text-faint)}.p-composer-bar[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 8px 8px}.p-composer-strip[data-v-247f7c56]{width:100%;max-width:620px;margin-top:calc(-1 * var(--space-4));display:flex;align-items:center;gap:var(--space-2);padding:calc(var(--space-4) + var(--space-2)) var(--space-2) var(--space-2);background:color-mix(in srgb,var(--color-hover) 60%,transparent);border-radius:0 0 var(--radius-2xl) var(--radius-2xl);font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);color:var(--p-text-faint);cursor:pointer}.p-composer-strip .p-ic[data-v-247f7c56]{width:16px;height:16px;color:var(--p-text-faint)}.p-composer-left[data-v-247f7c56],.p-composer-right[data-v-247f7c56]{display:flex;align-items:center;gap:4px}.p-composer .p-icon-btn[data-v-247f7c56]{border-radius:var(--p-r-full)}.p-send[data-v-247f7c56]{position:relative;width:32px;height:32px;border-radius:var(--p-r-full);display:grid;place-items:center;background:var(--p-text);color:var(--p-bg);border:none;cursor:pointer;box-shadow:var(--p-sh-xs);transition:transform var(--p-dur-fast) var(--p-ease)}.p-send[data-v-247f7c56]:after{content:"";position:absolute;inset:0;border-radius:var(--p-r-full);background:var(--p-bg);opacity:0;transition:opacity var(--p-dur-slow) var(--p-ease);pointer-events:none}.p-send[data-v-247f7c56]:hover:after{opacity:.28}.p-send[data-v-247f7c56]:active{transform:scale(.92)}.p-send .p-ic[data-v-247f7c56]{width:16px;height:16px}.dw-bar[data-v-247f7c56]{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-1) var(--space-1-5)}.am-mock[data-v-247f7c56]{display:flex;flex-direction:column;gap:var(--menu-rows-seam);width:100%;max-width:420px;padding:var(--space-1-5) var(--space-3);background:var(--color-menu-bg-frost);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--p-line);border-radius:var(--radius-composer);corner-shape:var(--corner-shape-composer);box-shadow:var(--p-sh-menu);font-family:var(--font-ui)}.am-mock-row[data-v-247f7c56]{display:flex;align-items:center;gap:var(--menu-row-gap-icon);padding:var(--menu-row-padding-block) var(--menu-row-padding-inline);border-radius:var(--radius-menu-row);color:var(--p-text);font-size:var(--p-font-size-base)}.am-mock-row.focus[data-v-247f7c56]{background:var(--color-selected)}.am-mock-row .n[data-v-247f7c56]{font-weight:var(--weight-medium)}.am-mock-row .d[data-v-247f7c56]{margin-left:var(--space-1);color:var(--p-text-muted);font-size:var(--text-sm)}.dw-pill[data-v-247f7c56]{position:relative;display:inline-flex;align-items:center;gap:var(--space-1-5);padding:var(--space-2) calc(var(--space-3) + var(--space-05)) var(--space-2) var(--space-3);border-radius:var(--radius-lg);background:var(--color-selected);color:var(--p-text);font-size:var(--p-font-size-base);font-weight:var(--weight-medium);line-height:var(--leading-normal)}.dw-pill[data-v-247f7c56] svg{width:1.5em;height:1.5em}.dw-pill.on[data-v-247f7c56]:after{content:"";position:absolute;inset:0;border-radius:var(--radius-lg);background:var(--color-hover);pointer-events:none}.dw-pill .dw-count[data-v-247f7c56]{color:var(--p-text-muted)}.dw-pill .dw-running[data-v-247f7c56]{display:inline-flex;align-items:center;gap:var(--space-1);color:var(--p-text-muted)}.dw-pill .dw-live[data-v-247f7c56]{color:var(--p-success);font-weight:var(--weight-medium)}.dw-panel[data-v-247f7c56]{width:100%;border:.5px solid var(--p-line);border-radius:var(--radius-2xl);background:color-mix(in srgb,var(--p-bg) 70%,transparent);box-shadow:var(--p-sh-menu);overflow:hidden}.dw-head[data-v-247f7c56]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-4) var(--space-4) 0}.dw-tab[data-v-247f7c56]{display:inline-flex;align-items:center;gap:var(--space-2);color:var(--p-text);font-size:var(--p-font-size-base);font-weight:var(--weight-medium);line-height:var(--leading-solid);white-space:nowrap}.dw-tab[data-v-247f7c56] svg{width:1.5em;height:1.5em}.dw-tab .dw-meta[data-v-247f7c56]{color:var(--p-text-muted)}.dw-chips[data-v-247f7c56]{margin-left:auto;display:inline-flex;gap:var(--space-05);padding:var(--space-05);background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md)}.dw-chip[data-v-247f7c56]{display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--p-sp-3);border-radius:var(--p-r-sm);color:var(--p-text-muted);font-size:var(--p-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-solid);white-space:nowrap}.dw-chip.on[data-v-247f7c56]{color:var(--p-text);background:var(--p-surface-raised);box-shadow:var(--p-sh-sm)}.dw-body[data-v-247f7c56]{margin-top:var(--space-3);padding:0 var(--space-4) var(--space-4)}.dw-body.col[data-v-247f7c56]{display:flex;flex-direction:column}.dw-row[data-v-247f7c56]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) 0;color:var(--p-text);font-size:var(--p-font-size-base)}.dw-row .nm[data-v-247f7c56]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dw-row .tm[data-v-247f7c56]{flex:none;color:var(--p-text-muted);font-variant-numeric:tabular-nums}.dw-row .ok[data-v-247f7c56]{color:var(--p-success);transform:scale(.91)}.dw-row.fail .nm[data-v-247f7c56],.dw-row.fail[data-v-247f7c56] svg{color:var(--p-danger)}.dw-row.cancelled[data-v-247f7c56] svg{color:var(--p-text-muted)}.dw-body.grid[data-v-247f7c56]{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--p-subagent-card-min),1fr));gap:var(--space-2)}.dw-card[data-v-247f7c56]{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);border-radius:var(--radius-lg);background:var(--color-selected)}.dw-card .ct[data-v-247f7c56]{display:flex;align-items:center;gap:var(--space-2)}.dw-card .nm[data-v-247f7c56]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-medium)}.dw-card .nu[data-v-247f7c56]{flex:none;color:var(--p-text-muted);font-size:var(--p-font-size-sm);font-variant-numeric:tabular-nums}.dw-card .ds[data-v-247f7c56]{color:var(--p-text-muted);font-size:var(--p-font-size-sm);line-height:var(--leading-caption);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.dw-card .cs[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;color:var(--p-text-muted);font-size:var(--p-font-size-xs)}.dw-card .cf[data-v-247f7c56]{display:flex;flex-direction:column;gap:var(--space-1)}.dw-card .cm[data-v-247f7c56]{display:flex;align-items:center;gap:var(--space-1);color:var(--p-text-muted);font-size:var(--p-font-size-xs)}.dw-card .cm span[data-v-247f7c56]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dw-card .cs .sl[data-v-247f7c56]{display:inline-flex;align-items:center;gap:var(--space-1)}.dw-card .cs .sl .ok[data-v-247f7c56]{color:var(--p-success);transform:scale(.91)}.dw-card .cs .tm[data-v-247f7c56]{margin-left:auto;display:inline-flex;align-items:center;gap:var(--space-1);font-variant-numeric:tabular-nums}.dw-card.fail .cs .sl[data-v-247f7c56]{color:var(--p-danger)}.dw-ring[data-v-247f7c56]{display:inline-block;width:var(--p-ic-md);height:var(--p-ic-md);border:1.5px solid var(--p-line-strong);border-radius:var(--radius-full);vertical-align:middle}.dw-spin[data-v-247f7c56]{display:inline-flex;color:var(--p-text);vertical-align:middle}.dt td .kw-dot[data-v-247f7c56],.dt td[data-v-247f7c56] svg{vertical-align:middle}.p[data-v-247f7c56] ::selection,[data-p][data-v-247f7c56] ::selection{background:var(--p-selection)}.p-link[data-v-247f7c56]{color:var(--p-accent);text-decoration:none;font-family:var(--p-font-sans);transition:color var(--p-dur) var(--p-ease)}.p-link[data-v-247f7c56]:hover{color:var(--p-accent-hover);text-decoration:underline}.p-link[data-v-247f7c56]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:var(--p-r-xs)}.p-link.muted[data-v-247f7c56]{color:var(--p-text-muted)}.p-link.muted[data-v-247f7c56]:hover{color:var(--p-text)}.p-link .p-ic[data-v-247f7c56]{width:var(--p-ic-sm);height:var(--p-ic-sm);vertical-align:-2px}.p-menu[data-v-247f7c56]{background:var(--color-menu-bg);border:.5px solid var(--p-line);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-sm);padding:var(--menu-pad);min-width:180px;font-family:var(--p-font-sans);color:var(--p-text)}.p-menu-item[data-v-247f7c56]{display:flex;align-items:center;gap:7px;padding:var(--menu-item-padding-block) var(--menu-item-padding-inline);border-radius:var(--radius-menu-item);font-size:var(--p-font-size-sm);color:var(--p-text);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-menu-item[data-v-247f7c56]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-menu-item.active[data-v-247f7c56],.p-menu-item.active[data-v-247f7c56]:hover{background:var(--p-hover);color:var(--p-text)}.p-menu-item.danger[data-v-247f7c56]{color:var(--p-danger)}.p-menu-item.danger[data-v-247f7c56]:hover{background:var(--p-danger-soft);color:var(--p-danger)}.p-menu-item.disabled[data-v-247f7c56]{opacity:.5;cursor:not-allowed}.p-menu-item.disabled[data-v-247f7c56]:hover{background:transparent;color:var(--p-text)}.p-menu-item .p-ic[data-v-247f7c56]{width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--p-muted)}.p-menu-item:hover .p-ic[data-v-247f7c56]{color:var(--p-text-strong)}.p-menu-item.active .p-ic[data-v-247f7c56]{color:var(--p-accent-hover)}.p-menu-item.danger .p-ic[data-v-247f7c56]{color:var(--p-danger)}.p-menu-item.lg[data-v-247f7c56]{min-height:44px;padding:12px 14px;font-size:var(--p-font-size-sm)}.p-menu-sep[data-v-247f7c56]{height:1px;background:var(--p-line);margin:4px 0}.p-seg[data-v-247f7c56]{display:inline-flex;gap:2px;padding:2px;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);font-family:var(--p-font-sans)}.p-seg-item[data-v-247f7c56]{display:inline-flex;align-items:center;gap:4px;padding:5px 12px;border-radius:var(--p-r-sm);font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text);cursor:pointer;white-space:nowrap;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease)}.p-seg-item[data-v-247f7c56]:hover{color:var(--p-text)}.p-seg-item.on[data-v-247f7c56]{background:var(--p-surface-raised);color:var(--p-text);box-shadow:var(--p-sh-sm)}.p-tabs[data-v-247f7c56]{display:flex;align-items:center;gap:0;border-bottom:.5px solid var(--p-line);font-family:var(--p-font-sans)}.p-tab[data-v-247f7c56]{padding:8px 14px;font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text-muted);cursor:pointer;white-space:nowrap;border-bottom:.5px solid transparent;margin-bottom:-.5px;transition:color var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease)}.p-tab[data-v-247f7c56]:hover{color:var(--p-text)}.p-tab.on[data-v-247f7c56]{color:var(--p-accent);border-bottom-color:var(--p-accent)}.p-switch[data-v-247f7c56]{position:relative;display:inline-block;width:36px;height:20px;flex:none;border-radius:var(--p-r-full);background:var(--p-line-strong);cursor:pointer;transition:background var(--p-dur) var(--p-ease)}.p-switch[data-v-247f7c56]:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:var(--p-r-full);background:var(--p-surface-raised);box-shadow:var(--p-sh-xs);transform-origin:left center;transition:transform var(--p-dur) var(--p-ease)}.p-switch[data-v-247f7c56]:hover:after{transform:scaleX(1.125)}.p-switch.on[data-v-247f7c56]{background:var(--p-accent)}.p-switch.on[data-v-247f7c56]:after{transform:translate(16px);transform-origin:right center}.p-switch.on[data-v-247f7c56]:hover:after{transform:translate(16px) scaleX(1.125)}.p-switch[data-v-247f7c56]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.p-check[data-v-247f7c56]{width:17px;height:17px;flex:none;display:inline-grid;place-items:center;border:.5px solid var(--p-line-strong);border-radius:var(--p-r-sm);background:var(--p-surface-raised);color:var(--p-text-on-accent);cursor:pointer;transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease)}.p-check.on[data-v-247f7c56]{background:var(--p-accent);border-color:var(--p-accent)}.p-check[data-v-247f7c56]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.p-check .p-ic[data-v-247f7c56]{width:12px;height:12px}.p-avatar[data-v-247f7c56]{width:32px;height:32px;flex:none;display:grid;place-items:center;border-radius:var(--p-r-md);background:var(--p-surface-sunken);border:.5px solid var(--p-line);color:var(--p-text-muted);font-size:var(--p-font-size-sm);font-weight:600}.p-avatar.sm[data-v-247f7c56]{width:24px;height:24px;border-radius:var(--p-r-sm);font-size:var(--p-font-size-xs)}.p-avatar .p-ic[data-v-247f7c56]{width:16px;height:16px}.p-avatar.sm .p-ic[data-v-247f7c56]{width:13px;height:13px}.p-empty[data-v-247f7c56]{display:flex;flex-direction:column;align-items:center;gap:8px;padding:32px 16px;color:var(--p-text-muted);text-align:center}.p-empty .em-ic[data-v-247f7c56]{width:48px;height:48px;color:var(--p-text-faint)}.p-empty .em-title[data-v-247f7c56]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-empty .em-hint[data-v-247f7c56]{font-size:var(--p-font-size-sm);color:var(--p-text-muted)}.p-divider[data-v-247f7c56]{width:100%;height:1px;background:var(--p-line);border:none}.p-divider-v[data-v-247f7c56]{width:1px;align-self:stretch;background:var(--p-line);border:none}.p-turn-failed[data-v-247f7c56]{display:flex;align-items:center;gap:var(--space-2);width:100%;max-width:560px;padding:var(--space-2) var(--space-3);border:var(--p-hairline) solid var(--color-danger-bd);border-radius:var(--radius-lg);background:var(--color-danger-soft);box-shadow:var(--shadow-xs)}.p-turn-failed .tf-chip[data-v-247f7c56]{display:inline-flex;align-items:center;justify-content:center;width:var(--space-6);height:var(--space-6);flex:none;border-radius:var(--radius-md);background:var(--color-surface-raised);box-shadow:var(--shadow-xs);color:var(--color-danger)}.p-turn-failed .tf-chip svg[data-v-247f7c56]{width:var(--p-ic-sm);height:var(--p-ic-sm)}.p-turn-failed .tf-main[data-v-247f7c56]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.p-turn-failed .tf-title[data-v-247f7c56]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-normal)}.p-turn-failed .tf-sub[data-v-247f7c56],.p-turn-failed .tf-meta[data-v-247f7c56]{font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-turn-failed .tf-meta[data-v-247f7c56]{font-family:var(--font-mono);color:var(--color-text-faint)}.p-tip[data-v-247f7c56]{position:relative;display:inline-flex}.p-tip .p-tooltip[data-v-247f7c56]{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:var(--p-text);color:var(--p-bg);font-size:var(--p-font-size-xs);padding:4px 8px;border-radius:var(--p-r-sm);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity var(--p-dur-fast) var(--p-ease)}.p-tip:hover .p-tooltip[data-v-247f7c56]{opacity:1}.p-banner[data-v-247f7c56]{display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:var(--p-r-md);border:.5px solid var(--p-line);background:var(--p-surface);font-size:var(--p-font-size-sm);color:var(--p-text)}.p-banner .bn-ic[data-v-247f7c56]{width:18px;height:18px;flex:none}.p-banner.info[data-v-247f7c56]{background:var(--p-accent-soft);border-color:var(--p-accent-bd)}.p-banner.info .bn-ic[data-v-247f7c56]{color:var(--p-accent)}.p-banner.warning[data-v-247f7c56]{background:var(--p-warning-soft);border-color:var(--p-warning-bd)}.p-banner.warning .bn-ic[data-v-247f7c56]{color:var(--p-warning)}.p-banner.danger[data-v-247f7c56]{background:var(--p-danger-soft);border-color:var(--p-danger-bd)}.p-banner.danger .bn-ic[data-v-247f7c56]{color:var(--p-danger)}.p-sheet[data-v-247f7c56]{background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-xl) var(--p-r-xl) 0 0;box-shadow:var(--p-sh-xl);padding:8px 16px 20px}.p-sheet-handle[data-v-247f7c56]{width:36px;height:4px;border-radius:var(--p-r-full);background:var(--p-line-strong);margin:0 auto 8px}.p-skeleton[data-v-247f7c56]{background:var(--p-surface-sunken);border-radius:var(--p-r-sm);animation:p-skel-247f7c56 1.2s var(--p-ease-inout) infinite alternate}@keyframes p-skel-247f7c56{0%{opacity:.5}to{opacity:1}}.p-cmdbar[data-v-247f7c56]{display:flex;align-items:center;gap:8px;width:100%}.p-cmd[data-v-247f7c56]{flex:1;min-width:0;height:38px;display:flex;align-items:center;gap:10px;padding:0 10px 0 14px;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);color:var(--p-text-muted)}.p-cmd .cmd-text[data-v-247f7c56]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-cmd .cmd-copy[data-v-247f7c56]{margin-left:auto;flex:none;display:grid;place-items:center;width:26px;height:26px;border:none;background:transparent;border-radius:var(--p-r-sm);color:var(--p-text-faint);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-cmd .cmd-copy[data-v-247f7c56]:hover{background:var(--p-surface-raised);color:var(--p-text)}.p-cmd .cmd-copy .p-ic[data-v-247f7c56]{width:15px;height:15px}.p-topbar[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;gap:12px;height:48px;padding:0 16px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg)}.p-topbar .tb-title[data-v-247f7c56]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text)}.p-topbar .tb-actions[data-v-247f7c56]{display:flex;align-items:center;gap:4px}.p-topbar.frost[data-v-247f7c56]{background:#ffffffb8;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-color:#fff9}[data-p=dark] .p-topbar.frost[data-v-247f7c56]{background:#161b22b8;border-color:#ffffff14}.demo-row[data-v-247f7c56]{display:flex;flex-wrap:wrap;align-items:center;gap:10px}.demo-stack[data-v-247f7c56]{display:flex;flex-direction:column;gap:12px;width:100%}.demo-col[data-v-247f7c56]{display:flex;flex-direction:column;gap:10px}.demo-grow[data-v-247f7c56]{flex:1;min-width:0}.demo-chat[data-v-247f7c56]{display:flex;flex-direction:column;gap:14px;width:100%;max-width:560px}.icon-grid[data-v-247f7c56]{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:8px;margin:14px 0}.icon-group-label[data-v-247f7c56]{grid-column:1 / -1;margin-top:10px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--d-fg-muted)}.icon-cell[data-v-247f7c56]{display:flex;align-items:center;gap:10px;padding:8px 10px;border:.5px solid var(--d-line);border-radius:8px;background:var(--d-surface)}.icon-cell .kw-icon[data-v-247f7c56]{width:20px;height:20px;color:var(--d-fg-soft)}.icon-cell .ic-name[data-v-247f7c56]{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;color:var(--d-fg)}.icon-sizes[data-v-247f7c56]{display:flex;align-items:end;gap:22px;flex-wrap:wrap}.icon-sizes .sz[data-v-247f7c56]{display:flex;flex-direction:column;align-items:center;gap:8px;font-size:11px;color:var(--d-fg-muted);font-family:JetBrains Mono,ui-monospace,monospace}.p-code-inline[data-v-247f7c56]{font-family:var(--p-font-mono);background:var(--p-surface-sunken);color:var(--p-text);padding:0 5px;border-radius:var(--p-r-sm);font-size:.9em}.p-code-block[data-v-247f7c56]{border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;background:var(--p-surface-sunken)}.p-code-block-head[data-v-247f7c56]{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--p-surface);border-bottom:.5px solid var(--p-line);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);color:var(--p-text-muted)}.p-code-block pre[data-v-247f7c56]{margin:0;padding:12px 14px;font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);line-height:1.65;color:var(--p-text);overflow-x:auto}.p-diff[data-v-247f7c56]{border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;font-family:var(--p-font-mono);font-size:var(--p-font-size-sm)}.p-diff-head[data-v-247f7c56]{padding:8px 12px;background:var(--p-surface);border-bottom:.5px solid var(--p-line);font-size:var(--p-font-size-xs);color:var(--p-text-muted)}.p-diff-row[data-v-247f7c56]{display:flex;gap:10px;padding:2px 12px;line-height:1.6}.p-diff-row .pm[data-v-247f7c56]{width:14px;flex:none;color:var(--p-text-faint)}.p-diff-row.add[data-v-247f7c56]{background:var(--p-success-soft)}.p-diff-row.add .pm[data-v-247f7c56]{color:var(--p-success)}.p-diff-row.del[data-v-247f7c56]{background:var(--p-danger-soft)}.p-diff-row.del .pm[data-v-247f7c56]{color:var(--p-danger)}.p-diff-row .p-diff-code[data-v-247f7c56]{color:var(--p-text)}.p-field-error[data-v-247f7c56]{color:var(--p-danger);font-size:var(--p-font-size-xs)}.p-btn .p-spinner[data-v-247f7c56]{vertical-align:middle}.p-btn .p-spinner .track[data-v-247f7c56]{stroke:currentColor;opacity:.35}.p-btn .p-spinner .arc[data-v-247f7c56]{stroke:currentColor}.ds-page[data-v-247f7c56]{position:fixed;inset:0;z-index:var(--z-max);overflow-y:auto}.ds-topbar[data-v-247f7c56]{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-4);background:var(--color-surface);border-bottom:.5px solid var(--color-line)}.ds-back[data-v-247f7c56]{display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-3);border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface-raised);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);cursor:pointer}.ds-back[data-v-247f7c56]:hover{background:var(--color-hover)}.ds-topbar-title[data-v-247f7c56]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)} diff --git a/apps/kimi-code/dist-web/assets/DesignSystemView-DVONbdv-.css b/apps/kimi-code/dist-web/assets/DesignSystemView-DVONbdv-.css new file mode 100644 index 000000000..9942d27b2 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/DesignSystemView-DVONbdv-.css @@ -0,0 +1 @@ +.ds-page[data-v-5fe218d3]{--d-bg: var(--color-bg);--d-surface: var(--color-surface);--d-surface-2: var(--color-surface-sunken);--d-surface-3: var(--color-line);--d-fg: var(--color-text);--d-fg-soft: var(--color-text-muted);--d-fg-muted: var(--color-text-muted);--d-fg-faint: var(--color-text-faint);--d-line: var(--color-line);--d-line-2: var(--color-line);--d-accent: var(--color-accent);--d-accent-2: var(--color-accent-hover);--d-accent-soft: var(--color-accent-soft);--d-accent-bd: var(--color-accent-bd);--d-green: var(--color-success);--d-green-soft: var(--color-success-soft);--d-amber: var(--color-warning);--d-amber-soft: var(--color-warning-soft);--d-red: var(--color-danger);--d-red-soft: var(--color-danger-soft);--d-violet: var(--color-done);--d-code-bg: var(--color-surface-sunken);--d-sidebar: var(--color-surface);--d-shadow-sm: var(--shadow-sm);--d-shadow-md: var(--shadow-md);--d-shadow-lg: var(--shadow-lg);--sidebar-w: var(--p-sidebar-w);--content-max: var(--p-content-wide)}.ds-page[data-v-5fe218d3] *,.ds-page[data-v-5fe218d3] *:before,.ds-page[data-v-5fe218d3] *:after{box-sizing:border-box}.ds-page[data-v-5fe218d3]{scroll-behavior:smooth}.ds-page[data-v-5fe218d3]{margin:0;background:var(--d-bg);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);line-height:1.65;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility}h1[data-v-5fe218d3],h2[data-v-5fe218d3],h3[data-v-5fe218d3],h4[data-v-5fe218d3]{color:var(--d-fg);letter-spacing:-.01em;line-height:1.25;margin:0}p[data-v-5fe218d3]{margin:0 0 14px;color:var(--d-fg-soft)}a[data-v-5fe218d3]{color:var(--d-accent-2);text-decoration:none}a[data-v-5fe218d3]:hover{text-decoration:underline}code[data-v-5fe218d3],pre[data-v-5fe218d3],.mono[data-v-5fe218d3]{font-family:JetBrains Mono,ui-monospace,SF Mono,Menlo,Consolas,monospace}code[data-v-5fe218d3]{background:var(--d-code-bg);border:.5px solid var(--d-line-2);border-radius:5px;padding:1px 6px;font-size:.88em;color:#1f2937;white-space:nowrap}.layout[data-v-5fe218d3]{display:grid;grid-template-columns:var(--sidebar-w) minmax(0,1fr);min-height:100vh}.sidebar[data-v-5fe218d3]{position:sticky;top:0;align-self:start;height:100vh;background:var(--d-sidebar);border-right:.5px solid var(--d-line);padding:26px 22px;overflow-y:auto}.brand[data-v-5fe218d3]{display:flex;align-items:center;gap:10px;margin-bottom:6px}.brand-mark[data-v-5fe218d3]{width:26px;height:26px;border-radius:7px;flex:none;background:var(--d-fg);color:#fff;display:grid;place-items:center;font-weight:800;font-size:14px;letter-spacing:-.04em}.brand-name[data-v-5fe218d3]{font-weight:700;font-size:15px;letter-spacing:-.01em}.brand-sub[data-v-5fe218d3]{font-size:12px;color:var(--d-fg-faint);margin-bottom:26px;padding-left:36px}.nav-group[data-v-5fe218d3]{margin:22px 0 8px;font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--d-fg-faint)}.p-section-label[data-v-5fe218d3]{font-size:12px;font-weight:600;text-transform:uppercase;color:var(--d-fg-faint)}.nav a[data-v-5fe218d3]{display:flex;align-items:center;gap:9px;padding:7px 10px;border-radius:7px;font-size:13.5px;font-weight:500;color:var(--d-fg-soft);margin:1px 0;transition:background .15s,color .15s}.nav a .num[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:11px;color:var(--d-fg-faint);width:18px}.nav a[data-v-5fe218d3]:hover{background:var(--color-hover);color:var(--d-fg);text-decoration:none}.nav a.active[data-v-5fe218d3]{background:var(--color-hover);color:var(--d-fg)}.nav a.active .num[data-v-5fe218d3]{color:var(--d-fg-soft)}.content[data-v-5fe218d3]{min-width:0}.content-inner[data-v-5fe218d3]{max-width:var(--content-max);margin:0 auto;padding:64px 56px 120px}section[data-v-5fe218d3]{scroll-margin-top:32px;padding-top:8px}section+section[data-v-5fe218d3]{margin-top:72px}.hero[data-v-5fe218d3]{padding:8px 0 40px;border-bottom:.5px solid var(--d-line);margin-bottom:56px}.eyebrow[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:8px;font-family:JetBrains Mono,monospace;font-size:12px;font-weight:600;letter-spacing:.04em;color:var(--d-fg);background:#1783ff1a;border:none;padding:6px 12px;border-radius:8px;margin-bottom:22px}.hero h1[data-v-5fe218d3]{font-size:48px;font-weight:600;line-height:1.08;letter-spacing:-.025em;margin-bottom:18px}.hero h1 .grad[data-v-5fe218d3]{color:var(--d-accent)}.hero p.lead[data-v-5fe218d3]{font-size:18px;line-height:1.6;color:var(--d-fg-soft);max-width:680px}.hero-meta[data-v-5fe218d3]{display:flex;flex-wrap:wrap;gap:10px;margin-top:28px}.meta-chip[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:8px;font-size:12.5px;color:var(--d-fg-muted);background:var(--d-surface);border:.5px solid var(--d-line);border-radius:8px;padding:7px 12px}.meta-chip b[data-v-5fe218d3]{color:var(--d-fg);font-weight:600}.meta-chip .dot[data-v-5fe218d3]{width:7px;height:7px;border-radius:50%;background:var(--d-green)}.sec-head[data-v-5fe218d3]{display:flex;align-items:baseline;gap:14px;margin-bottom:8px}.sec-num[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:13px;font-weight:600;color:var(--d-accent-2)}.sec-title[data-v-5fe218d3]{font-size:26px;letter-spacing:-.02em}.sec-desc[data-v-5fe218d3]{font-size:15.5px;color:var(--d-fg-muted);max-width:720px;margin-bottom:28px}h3.sub[data-v-5fe218d3]{font-size:17px;margin:40px 0 14px;display:flex;align-items:center;gap:10px}h3.sub[data-v-5fe218d3]:before{content:"";width:4px;height:16px;border-radius:2px;background:var(--d-accent)}h4.mini[data-v-5fe218d3]{font-size:13px;text-transform:uppercase;letter-spacing:.06em;color:var(--d-fg-muted);margin:24px 0 12px}.stat-grid[data-v-5fe218d3]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:24px 0}.stat[data-v-5fe218d3]{background:var(--d-surface);border:.5px solid var(--d-line);border-radius:14px;padding:18px 18px 16px}.stat .v[data-v-5fe218d3]{font-size:34px;font-weight:800;letter-spacing:-.03em;line-height:1;color:var(--d-fg)}.stat .v small[data-v-5fe218d3]{font-size:16px;color:var(--d-fg-muted);font-weight:600}.stat .l[data-v-5fe218d3]{font-size:12.5px;color:var(--d-fg-muted);margin-top:8px;line-height:1.4}.stat.warn[data-v-5fe218d3]{background:var(--d-amber-soft);border-color:#f0d9b8}.stat.warn .v[data-v-5fe218d3]{color:var(--d-amber)}.stat.bad[data-v-5fe218d3]{background:var(--d-red-soft);border-color:#f0cccc}.stat.bad .v[data-v-5fe218d3]{color:var(--d-red)}.stat.good[data-v-5fe218d3]{background:var(--d-green-soft);border-color:#bfe3cc}.stat.good .v[data-v-5fe218d3]{color:var(--d-green)}.panel[data-v-5fe218d3]{background:var(--d-bg);border:.5px solid var(--d-line);border-radius:16px;box-shadow:var(--d-shadow-sm)}.panel-pad[data-v-5fe218d3]{padding:22px}.panel-soft[data-v-5fe218d3]{background:var(--d-surface);border:.5px solid var(--d-line);border-radius:14px}.callout[data-v-5fe218d3]{display:flex;gap:12px;padding:14px 16px;border-radius:12px;font-size:14px;line-height:1.55;background:var(--d-surface);border:.5px solid var(--d-line);color:var(--d-fg-soft);margin:18px 0}.callout .ico[data-v-5fe218d3]{flex:none;width:20px;height:20px;border-radius:6px;display:grid;place-items:center;font-size:12px;font-weight:800}.callout.info[data-v-5fe218d3]{background:var(--d-accent-soft);border-color:var(--d-accent-bd)}.callout.info .ico[data-v-5fe218d3]{background:var(--d-accent);color:#fff}.callout.warn[data-v-5fe218d3]{background:var(--d-amber-soft);border-color:#f0d9b8}.callout.warn .ico[data-v-5fe218d3]{background:var(--d-amber);color:#fff}.callout.good[data-v-5fe218d3]{background:var(--d-green-soft);border-color:#bfe3cc}.callout.good .ico[data-v-5fe218d3]{background:var(--d-green);color:#fff}table.dt[data-v-5fe218d3]{width:100%;border-collapse:collapse;font-size:13.5px;margin:16px 0}table.dt th[data-v-5fe218d3]{text-align:left;font-size:11.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--d-fg-faint);font-weight:700;padding:10px 12px;border-bottom:.5px solid var(--d-line)}table.dt td[data-v-5fe218d3]{padding:11px 12px;border-bottom:.5px solid var(--d-line-2);color:var(--d-fg-soft);vertical-align:middle}table.dt tr:last-child td[data-v-5fe218d3]{border-bottom:none}table.dt td.tk[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:12.5px;color:var(--d-fg);white-space:nowrap}table.dt td.val[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.swatch[data-v-5fe218d3]{display:inline-block;width:16px;height:16px;border-radius:4px;border:.5px solid rgba(0,0,0,.08);vertical-align:-3px;margin-right:8px}.palette[data-v-5fe218d3]{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin:16px 0}.color-card[data-v-5fe218d3]{border:.5px solid var(--d-line);border-radius:12px;overflow:hidden;background:var(--d-bg)}.color-chip[data-v-5fe218d3]{height:56px;border-bottom:.5px solid var(--d-line)}.color-meta[data-v-5fe218d3]{padding:10px 12px 12px}.color-meta .cn[data-v-5fe218d3]{font-size:13px;font-weight:600;color:var(--d-fg)}.color-meta .cv[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:11.5px;color:var(--d-fg-muted);margin-top:2px}.type-row[data-v-5fe218d3]{display:flex;align-items:baseline;gap:18px;padding:13px 0;border-bottom:.5px solid var(--d-line-2)}.type-row[data-v-5fe218d3]:last-child{border-bottom:none}.type-sample[data-v-5fe218d3]{flex:1;color:var(--d-fg);line-height:1.2}.type-meta[data-v-5fe218d3]{width:190px;flex:none;text-align:right;font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.space-row[data-v-5fe218d3]{display:flex;align-items:center;gap:16px;padding:10px 0;border-bottom:.5px solid var(--d-line-2)}.space-row[data-v-5fe218d3]:last-child{border-bottom:none}.space-bar[data-v-5fe218d3]{height:18px;border-radius:4px;background:linear-gradient(90deg,var(--d-accent),var(--d-accent-2));flex:none}.space-meta[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:12.5px;color:var(--d-fg-soft);width:150px}.space-use[data-v-5fe218d3]{font-size:12.5px;color:var(--d-fg-muted)}.radius-grid[data-v-5fe218d3]{display:flex;flex-wrap:wrap;gap:22px;align-items:flex-end;margin:16px 0}.radius-item[data-v-5fe218d3]{display:flex;flex-direction:column;align-items:center;gap:10px}.radius-box[data-v-5fe218d3]{width:64px;height:64px;border:.5px solid var(--d-accent);background:var(--d-accent-soft)}.radius-item .rl[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-soft)}.stage-wrap[data-v-5fe218d3]{border:.5px solid var(--d-line);border-radius:16px;overflow:hidden;margin:18px 0;background:var(--d-bg);box-shadow:var(--d-shadow-sm)}.stage-bar[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:.5px solid var(--d-line);background:var(--d-surface)}.stage-bar .st[data-v-5fe218d3]{font-size:13px;font-weight:600;color:var(--d-fg);display:flex;align-items:center;gap:8px}.stage-bar .st .tag[data-v-5fe218d3]{font-size:10.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:999px}.tag.after[data-v-5fe218d3]{background:var(--d-green-soft);color:var(--d-green)}.tag.before[data-v-5fe218d3]{background:var(--d-red-soft);color:var(--d-red)}.tag.spec[data-v-5fe218d3]{background:var(--d-accent-soft);color:var(--d-accent-2)}.stage-bar .sactions[data-v-5fe218d3]{display:flex;gap:6px}.tab[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:11.5px;padding:4px 10px;border-radius:6px;color:var(--d-fg-muted);cursor:default}.tab.on[data-v-5fe218d3]{background:var(--d-bg);color:var(--d-fg);border:.5px solid var(--d-line)}.stage[data-v-5fe218d3]{padding:32px;display:flex;flex-wrap:wrap;align-items:center;gap:16px;background:radial-gradient(circle at 1px 1px,rgba(0,0,0,.045) 1px,transparent 0) 0 0 / 18px 18px,var(--d-surface)}.stage.col[data-v-5fe218d3]{flex-direction:column;align-items:stretch}.stage.dark[data-v-5fe218d3]{background:radial-gradient(circle at 1px 1px,rgba(255,255,255,.06) 1px,transparent 0) 0 0 / 18px 18px,#0d1117}.stage-label[data-v-5fe218d3]{width:100%;font-size:11.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--d-fg-faint);margin-bottom:-6px}.stage.dark .stage-label[data-v-5fe218d3]{color:#6b7280}.ba[data-v-5fe218d3]{display:grid;grid-template-columns:1fr 1fr;gap:0;border:.5px solid var(--d-line);border-radius:16px;overflow:hidden;margin:18px 0;box-shadow:var(--d-shadow-sm)}.ba-col[data-v-5fe218d3]{min-width:0}.ba-col+.ba-col[data-v-5fe218d3]{border-left:.5px solid var(--d-line)}.ba-head[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;padding:11px 16px;border-bottom:.5px solid var(--d-line)}.ba-head.before[data-v-5fe218d3]{background:var(--d-red-soft)}.ba-head.after[data-v-5fe218d3]{background:var(--d-green-soft)}.ba-head .bh[data-v-5fe218d3]{font-size:13px;font-weight:700}.ba-head.before .bh[data-v-5fe218d3]{color:var(--d-red)}.ba-head.after .bh[data-v-5fe218d3]{color:var(--d-green)}.ba-head .bh small[data-v-5fe218d3]{font-weight:500;opacity:.7;margin-left:6px}.ba-body[data-v-5fe218d3]{padding:24px;background:var(--d-surface);min-height:120px}.ba-col.after .ba-body[data-v-5fe218d3]{background:#fff}.code[data-v-5fe218d3]{background:#0d1117;border-radius:12px;overflow:hidden;margin:16px 0;border:.5px solid #1c2128}.code-bar[data-v-5fe218d3]{display:flex;align-items:center;gap:8px;padding:9px 14px;background:#13181e;border-bottom:.5px solid #1c2128}.code-bar .d[data-v-5fe218d3]{width:10px;height:10px;border-radius:50%;background:#30363d}.code-bar .fn[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:11.5px;color:#8b949e;margin-left:4px}.code pre[data-v-5fe218d3]{margin:0;padding:18px;overflow-x:auto;font-size:12.5px;line-height:1.7;color:#c9d1d9}.code .c[data-v-5fe218d3]{color:#8b949e}.code .k[data-v-5fe218d3]{color:#ff7b72}.code .s[data-v-5fe218d3]{color:#a5d6ff}.code .p[data-v-5fe218d3]{color:#79c0ff}.code .n[data-v-5fe218d3]{color:#d2a8ff}.code .v[data-v-5fe218d3]{color:#ffa657}.pill[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:600;padding:3px 9px;border-radius:999px;border:.5px solid var(--d-line);background:var(--d-surface);color:var(--d-fg-soft)}.pill.blue[data-v-5fe218d3]{background:var(--d-accent-soft);border-color:var(--d-accent-bd);color:var(--d-accent-2)}.pill.green[data-v-5fe218d3]{background:var(--d-green-soft);border-color:#bfe3cc;color:var(--d-green)}.pill.amber[data-v-5fe218d3]{background:var(--d-amber-soft);border-color:#f0d9b8;color:var(--d-amber)}.pill.red[data-v-5fe218d3]{background:var(--d-red-soft);border-color:#f0cccc;color:var(--d-red)}.pill.mono[data-v-5fe218d3]{font-family:JetBrains Mono,monospace}ul.clean[data-v-5fe218d3]{list-style:none;padding:0;margin:14px 0}ul.clean li[data-v-5fe218d3]{position:relative;padding:8px 0 8px 26px;color:var(--d-fg-soft);border-bottom:.5px solid var(--d-line-2)}ul.clean li[data-v-5fe218d3]:last-child{border-bottom:none}ul.clean li[data-v-5fe218d3]:before{content:"";position:absolute;left:4px;top:17px;width:7px;height:7px;border-radius:50%;background:var(--d-accent)}ul.clean.check li[data-v-5fe218d3]:before{content:"✓";background:none;color:var(--d-green);font-weight:800;top:7px;left:0;font-size:14px}ul.clean.cross li[data-v-5fe218d3]:before{content:"✕";background:none;color:var(--d-red);font-weight:800;top:7px;left:0;font-size:13px}ul.clean li b[data-v-5fe218d3]{color:var(--d-fg)}ul.clean li .path[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:12px;color:var(--d-fg-muted)}.roadmap[data-v-5fe218d3]{position:relative;margin:24px 0}.phase[data-v-5fe218d3]{position:relative;display:grid;grid-template-columns:120px 1fr;gap:24px;padding:0 0 32px}.phase[data-v-5fe218d3]:not(:last-child):after{content:"";position:absolute;left:59px;top:36px;bottom:0;width:2px;background:var(--d-line)}.phase-tag[data-v-5fe218d3]{text-align:right;padding-top:4px}.phase-tag .pt[data-v-5fe218d3]{display:inline-block;font-family:JetBrains Mono,monospace;font-size:12px;font-weight:700;color:var(--d-accent-2);background:var(--d-accent-soft);border:.5px solid var(--d-accent-bd);padding:5px 10px;border-radius:8px}.phase-tag .pe[data-v-5fe218d3]{font-size:11.5px;color:var(--d-fg-faint);margin-top:8px}.phase-body[data-v-5fe218d3]{background:var(--d-bg);border:.5px solid var(--d-line);border-radius:14px;padding:18px 20px;box-shadow:var(--d-shadow-sm)}.phase-body h4[data-v-5fe218d3]{font-size:16px;margin-bottom:8px}.phase-body p[data-v-5fe218d3]{font-size:14px;margin-bottom:12px}.phase-body ul[data-v-5fe218d3]{margin:0}.matrix[data-v-5fe218d3]{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:16px 0}.anti[data-v-5fe218d3]{border:.5px solid var(--d-line);border-radius:12px;padding:16px;background:var(--d-bg)}.anti .ah[data-v-5fe218d3]{display:flex;align-items:center;gap:9px;font-size:14px;font-weight:700;margin-bottom:8px}.anti .ah .verdict[data-v-5fe218d3]{margin-left:auto;font-size:11px;font-weight:800;padding:2px 8px;border-radius:999px}.verdict.pass[data-v-5fe218d3]{background:var(--d-green-soft);color:var(--d-green)}.verdict.fail[data-v-5fe218d3]{background:var(--d-red-soft);color:var(--d-red)}.verdict.warn[data-v-5fe218d3]{background:var(--d-amber-soft);color:var(--d-amber)}.anti p[data-v-5fe218d3]{font-size:13px;margin:0;color:var(--d-fg-muted)}.footer[data-v-5fe218d3]{margin-top:80px;padding-top:28px;border-top:.5px solid var(--d-line);font-size:13px;color:var(--d-fg-faint);display:flex;justify-content:space-between;flex-wrap:wrap;gap:12px}.kbd[data-v-5fe218d3]{font-family:JetBrains Mono,monospace;font-size:11px;background:var(--d-surface-2);border:.5px solid var(--d-line);border-radius:5px;padding:1px 6px}@media(max-width:980px){.layout[data-v-5fe218d3]{grid-template-columns:1fr}.sidebar[data-v-5fe218d3]{position:static;height:auto}.nav[data-v-5fe218d3]{display:flex;flex-wrap:wrap;gap:4px}.content-inner[data-v-5fe218d3]{padding:40px 22px 80px}.stat-grid[data-v-5fe218d3]{grid-template-columns:repeat(2,1fr)}.ba[data-v-5fe218d3]{grid-template-columns:1fr}.ba-col+.ba-col[data-v-5fe218d3]{border-left:none;border-top:.5px solid var(--d-line)}.palette[data-v-5fe218d3]{grid-template-columns:repeat(2,1fr)}.matrix[data-v-5fe218d3]{grid-template-columns:1fr}}.ds-page .p[data-v-5fe218d3],.ds-page .stage.p-skin[data-v-5fe218d3],.ds-page [data-p][data-v-5fe218d3]{--p-font-sans: var(--font-ui);--p-font-kbd: var(--font-kbd);--p-font-mono: var(--font-mono);--p-bg: var(--color-bg);--p-surface: var(--color-surface);--p-surface-raised: var(--color-surface-raised);--p-surface-overlay: var(--color-surface-overlay);--p-surface-sunken: var(--color-surface-sunken);--p-well: var(--color-well);--p-surface-deep: var(--color-surface-deep);--p-hover: var(--color-hover);--p-text: var(--color-text);--p-text-strong: var(--color-text-strong);--p-muted: var(--muted);--p-text-muted: var(--color-text-muted);--p-text-faint: var(--color-text-faint);--p-text-on-accent: var(--color-text-on-accent);--p-line: var(--color-line);--p-line-strong: var(--color-line-strong);--p-accent: var(--color-accent);--p-accent-hover: var(--color-accent-hover);--p-accent-soft: var(--color-accent-soft);--p-user-bubble-bg: var(--color-user-bubble-bg);--p-accent-bd: var(--color-accent-bd);--p-success: var(--color-success);--p-success-soft: var(--color-success-soft);--p-success-bd: var(--color-success-bd);--p-warning: var(--color-warning);--p-warning-soft: var(--color-warning-soft);--p-warning-bd: var(--color-warning-bd);--p-danger: var(--color-danger);--p-danger-soft: var(--color-danger-soft);--p-danger-bd: var(--color-danger-bd);--p-info: var(--color-info);--p-sp-1: var(--space-1);--p-sp-2: var(--space-2);--p-sp-3: var(--space-3);--p-sp-4: var(--space-4);--p-sp-5: var(--space-5);--p-sp-6: var(--space-6);--p-sp-8: var(--space-8);--p-r-xs: var(--radius-xs);--p-r-sm: var(--radius-sm);--p-r-md: var(--radius-md);--p-r-lg: var(--radius-lg);--p-r-xl: var(--radius-xl);--p-r-composer: var(--radius-composer);--p-r-full: var(--radius-full);--p-corner-composer: var(--corner-shape-composer);--p-sh-xs: var(--shadow-xs);--p-sh-sm: var(--shadow-sm);--p-sh-menu: var(--shadow-menu);--p-sh-md: var(--shadow-md);--p-sh-input: var(--shadow-input);--p-sh-lg: var(--shadow-lg);--p-sh-xl: var(--shadow-xl);--p-font-size-xs: var(--text-xs);--p-font-size-sm: var(--text-sm);--p-font-size-base: var(--text-base);--p-font-size-md: var(--text-base);--p-font-size-lg: var(--text-lg);--p-font-size-xl: var(--text-xl);--p-font-size-2xl: var(--text-2xl);--p-leading-tight: var(--leading-tight);--p-leading-normal: var(--leading-normal);--p-leading-relaxed: var(--leading-relaxed);--p-ease: var(--ease-out);--p-ease-inout: var(--ease-in-out);--p-dur-fast: var(--duration-fast);--p-dur: var(--duration-base);--p-dur-slow: var(--duration-slow);--p-composer-focus-line: var(--color-composer-focus-line);font-family:var(--font-ui);color:var(--color-text);font-size:var(--text-base)}[data-p=dark][data-v-5fe218d3]{--p-bg: #0d1117;--p-surface: #13181e;--p-surface-raised: #1c2128;--p-surface-sunken: #0d1117;--p-well: #13181e;--p-surface-deep: #0a0d12;--p-surface-overlay: #22272e;--p-hover: #ffffff0d;--p-text: #e8eaed;--p-text-strong: #ffffff;--p-muted: #727983;--p-text-muted: #9aa0a8;--p-text-faint: #6b7280;--p-line: #2d333b;--p-line-strong: #3d444d;--p-accent: #58a6ff;--p-accent-hover: #79b8ff;--p-accent-soft: rgba(88,166,255,.14);--p-accent-bd: rgba(88,166,255,.28);--p-success: #3fb950;--p-success-soft: rgba(63,185,80,.14);--p-success-bd: rgba(63,185,80,.28);--p-warning: #d29922;--p-warning-soft: rgba(210,153,34,.14);--p-warning-bd: rgba(210,153,34,.28);--p-danger: #f85149;--p-danger-soft: rgba(248,81,73,.14);--p-danger-bd: rgba(248,81,73,.28);--p-sh-sm: 0 1px 2px rgba(0,0,0,.4);--p-sh-md: 0 4px 12px rgba(0,0,0,.45);--p-sh-lg: 0 12px 32px rgba(0,0,0,.55);--p-sh-input: var(--shadow-input);--p-selection: rgba(88,166,255,.32)}.p-ic[data-v-5fe218d3]{width:16px;height:16px;flex:none;display:inline-block;vertical-align:middle}.p-btn[data-v-5fe218d3]{--_h: 36px;--_px: 16px;--_fs: var(--p-font-size-base);--_r: var(--p-r-md);display:inline-flex;align-items:center;justify-content:center;gap:8px;height:var(--_h);padding:0 var(--_px);border-radius:var(--_r);font-family:var(--p-font-sans);font-size:var(--_fs);font-weight:600;line-height:1;border:.5px solid transparent;cursor:pointer;white-space:nowrap;transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease),transform var(--p-dur-fast) var(--p-ease)}.p-btn[data-v-5fe218d3]:active{transform:scale(.98)}.p-btn[data-v-5fe218d3]:focus-visible{outline:none;box-shadow:0 0 0 3px var(--p-accent-soft),0 0 0 1px var(--p-accent)}.p-btn .p-ic[data-v-5fe218d3]{width:16px;height:16px}.p-btn.sm[data-v-5fe218d3]{--_h: 30px;--_px: 12px;--_fs: var(--p-font-size-sm);--_r: var(--p-r-sm)}.p-btn.sm .p-ic[data-v-5fe218d3]{width:14px;height:14px}.p-btn.lg[data-v-5fe218d3]{--_h: 42px;--_px: 20px;--_fs: var(--p-font-size-md);--_r: var(--p-r-lg)}.p-btn.primary[data-v-5fe218d3]{background:var(--p-accent);color:var(--p-text-on-accent);border-color:var(--p-accent);box-shadow:var(--p-sh-xs)}.p-btn.primary[data-v-5fe218d3]:hover{background:var(--p-accent-hover);border-color:var(--p-accent-hover)}.p-btn.secondary[data-v-5fe218d3]{background:var(--p-surface-raised);color:var(--p-text);border-color:var(--p-line-strong);box-shadow:var(--p-sh-xs)}.p-btn.secondary[data-v-5fe218d3]:hover{background:var(--p-hover);border-color:var(--p-line-strong)}.p-btn.ghost[data-v-5fe218d3]{background:transparent;color:var(--p-text);border-color:transparent}.p-btn.ghost[data-v-5fe218d3]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-btn.danger[data-v-5fe218d3]{background:var(--p-danger);color:#fff;border-color:var(--p-danger);box-shadow:var(--p-sh-xs)}.p-btn.danger[data-v-5fe218d3]:hover{filter:brightness(.96)}.p-btn.danger-soft[data-v-5fe218d3]{background:var(--p-danger-soft);color:var(--p-danger);border-color:var(--p-danger-bd)}.p-btn.danger-soft[data-v-5fe218d3]:hover{background:var(--p-danger);color:#fff;border-color:var(--p-danger)}.p-btn[disabled][data-v-5fe218d3],.p-btn.disabled[data-v-5fe218d3]{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.p-icon-btn[data-v-5fe218d3]{--_s: 32px;display:inline-grid;place-items:center;width:var(--_s);height:var(--_s);flex:none;border-radius:var(--p-r-md);border:.5px solid transparent;background:transparent;color:var(--p-text-muted);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-icon-btn[data-v-5fe218d3]:hover{background:var(--p-hover);color:var(--p-text)}.p-icon-btn[data-v-5fe218d3]:focus-visible{outline:none;box-shadow:0 0 0 3px var(--p-accent-soft)}.p-icon-btn.sm[data-v-5fe218d3]{--_s: 26px;border-radius:var(--p-r-sm)}.p-icon-btn.lg[data-v-5fe218d3]{--_s: 44px}.p-icon-btn .p-ic[data-v-5fe218d3]{width:16px;height:16px}.p-icon-btn.lg .p-ic[data-v-5fe218d3]{width:20px;height:20px}.p-badge[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:6px;height:22px;padding:0 9px;border-radius:var(--p-r-full);font-family:var(--p-font-sans);font-size:var(--p-font-size-xs);font-weight:600;line-height:1;border:.5px solid var(--p-line);background:var(--p-surface);color:var(--p-text);white-space:nowrap}.p-badge.sm[data-v-5fe218d3]{height:18px;padding:0 7px;font-size:11px}.p-badge .bd[data-v-5fe218d3]{width:7px;height:7px;border-radius:50%;background:currentColor}.p-badge.neutral[data-v-5fe218d3]{background:var(--p-surface-sunken);border-color:var(--p-line);color:var(--p-text-muted)}.p-badge.info[data-v-5fe218d3]{background:var(--p-accent-soft);border-color:var(--p-accent-bd);color:var(--p-accent-hover)}.p-badge.success[data-v-5fe218d3]{background:var(--p-success-soft);border-color:var(--p-success-bd);color:var(--p-success)}.p-badge.warning[data-v-5fe218d3]{background:var(--p-warning-soft);border-color:var(--p-warning-bd);color:var(--p-warning)}.p-badge.danger[data-v-5fe218d3]{background:var(--p-danger-soft);border-color:var(--p-danger-bd);color:var(--p-danger)}.p-badge.solid[data-v-5fe218d3]{background:var(--p-text);color:var(--p-bg);border-color:var(--p-text)}.p-badge .p-ic[data-v-5fe218d3]{width:12px;height:12px}.p-kbd[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:3px}.p-kbd kbd[data-v-5fe218d3]{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border:.5px solid var(--p-line);border-radius:var(--p-r-xs);background:transparent;color:inherit;font-family:var(--p-font-kbd);font-size:11px;line-height:1}.p-pill[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:4px;height:32px;padding:0 12px;border-radius:var(--p-r-full);border:.5px solid transparent;background:transparent;font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-pill[data-v-5fe218d3]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-pill .pp-strong[data-v-5fe218d3]{font-weight:700;color:var(--p-text)}.p-pill .pp-sub[data-v-5fe218d3]{color:var(--p-accent);font-weight:600}.p-pill .p-ic[data-v-5fe218d3]{width:14px;height:14px;color:var(--p-text-faint)}.p-card[data-v-5fe218d3]{background:var(--p-surface);border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;color:var(--p-text)}.p-card.interactive[data-v-5fe218d3]{transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease);cursor:pointer}.p-card.interactive[data-v-5fe218d3]:hover{background:var(--p-surface);border-color:var(--p-line-strong)}.p-card-head[data-v-5fe218d3]{display:flex;align-items:center;gap:9px;padding:10px 14px;border-bottom:.5px solid var(--p-line);background:var(--p-surface)}.p-card-title[data-v-5fe218d3]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text);font-family:var(--p-font-mono)}.p-card-body[data-v-5fe218d3]{padding:14px;font-size:var(--p-font-size-base);color:var(--p-text);line-height:var(--p-leading-normal)}.p-card-foot[data-v-5fe218d3]{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:10px 14px;border-top:.5px solid var(--p-line);background:var(--p-surface)}.p-field[data-v-5fe218d3]{display:flex;flex-direction:column;gap:6px}.p-label[data-v-5fe218d3]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text)}.p-input[data-v-5fe218d3],.p-select[data-v-5fe218d3],.p-textarea[data-v-5fe218d3]{width:100%;height:38px;padding:0 12px;border-radius:var(--p-r-md);border:.5px solid var(--p-line-strong);background:var(--p-surface-raised);font-family:var(--p-font-sans);font-size:var(--p-font-size-base);color:var(--p-text);box-shadow:var(--p-sh-xs);transition:border-color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease)}.p-textarea[data-v-5fe218d3]{height:auto;min-height:84px;padding:10px 12px;resize:vertical;line-height:var(--p-leading-normal)}.p-select[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;text-align:left}.p-select[data-v-5fe218d3]:after{content:"⌄";color:var(--p-text-muted)}.p-input[data-v-5fe218d3]:hover,.p-select[data-v-5fe218d3]:hover,.p-textarea[data-v-5fe218d3]:hover{border-color:var(--p-line-strong)}.p-input[data-v-5fe218d3]:focus,.p-select[data-v-5fe218d3]:focus,.p-textarea[data-v-5fe218d3]:focus{outline:none;border-color:var(--p-accent);box-shadow:0 0 0 3px var(--p-accent-soft)}.p-input[data-v-5fe218d3]::placeholder,.p-textarea[data-v-5fe218d3]::placeholder{color:var(--p-text-faint)}.p-input.sm[data-v-5fe218d3]{height:32px;font-size:var(--p-font-size-sm);border-radius:var(--p-r-sm)}.p-hint[data-v-5fe218d3]{font-size:var(--p-font-size-xs);color:var(--p-text-faint)}.p-dialog[data-v-5fe218d3]{width:480px;max-width:calc(100vw - 48px);background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-xl);box-shadow:var(--p-sh-xl);overflow:hidden;color:var(--p-text)}.p-dialog-head[data-v-5fe218d3]{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:20px 22px 14px}.p-dialog-title[data-v-5fe218d3]{font-size:var(--p-font-size-lg);font-weight:700;letter-spacing:-.01em}.p-dialog-desc[data-v-5fe218d3]{font-size:var(--p-font-size-base);color:var(--p-text-muted);margin-top:4px;line-height:var(--p-leading-normal)}.p-dialog-body[data-v-5fe218d3]{padding:4px 22px 18px}.p-dialog-foot[data-v-5fe218d3]{display:flex;justify-content:flex-end;gap:10px;padding:14px 22px 20px}.p-toast[data-v-5fe218d3]{display:flex;align-items:flex-start;gap:11px;width:360px;padding:13px 14px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-md)}.p-toast .ti[data-v-5fe218d3]{width:20px;height:20px;border-radius:50%;display:grid;place-items:center;flex:none;margin-top:1px}.p-toast.success .ti[data-v-5fe218d3]{background:var(--p-success-soft);color:var(--p-success)}.p-toast.warning .ti[data-v-5fe218d3]{background:var(--p-warning-soft);color:var(--p-warning)}.p-toast .tt[data-v-5fe218d3]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-toast .td[data-v-5fe218d3]{font-size:var(--p-font-size-sm);color:var(--p-text-muted);margin-top:2px;line-height:1.45}.p-action-toast[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:8px;align-self:center;padding:4px 6px 4px 14px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-sm);font-size:var(--p-font-size-base);color:var(--p-text);white-space:nowrap}.p-action-toast .lk[data-v-5fe218d3]{border:0;padding:0;background:none;color:var(--p-accent);cursor:pointer;font:inherit}.p-action-toast .x[data-v-5fe218d3]{color:var(--p-text-muted);width:14px;height:14px}.p-spinner[data-v-5fe218d3]{width:18px;height:18px;animation:p-spin-5fe218d3 .85s linear infinite}.p-spinner.sm[data-v-5fe218d3]{width:14px;height:14px}.p-spinner circle[data-v-5fe218d3]{fill:none;stroke-width:2.2;stroke-linecap:round}.p-spinner .track[data-v-5fe218d3]{stroke:var(--p-line)}.p-spinner .arc[data-v-5fe218d3]{stroke:var(--p-accent);stroke-dasharray:56 56;stroke-dashoffset:38}@keyframes p-spin-5fe218d3{to{transform:rotate(360deg)}}.p-thinking[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:9px;font-size:var(--p-font-size-sm);color:var(--p-text-muted);font-family:var(--p-font-sans)}.p-bubble-user[data-v-5fe218d3]{align-self:flex-end;max-width:78%;background:var(--p-user-bubble-bg);border:none;color:var(--p-text);border-radius:var(--p-r-lg);padding:10px 12px;font-size:var(--p-font-size-md);line-height:var(--p-leading-normal)}.p-msg[data-v-5fe218d3]{max-width:760px;font-size:var(--p-font-size-md);line-height:var(--p-leading-relaxed);color:var(--p-text)}.p-msg p[data-v-5fe218d3]{margin:0 0 10px;color:var(--p-text)}.p-msg code[data-v-5fe218d3]{font-family:var(--p-font-mono);background:var(--p-surface-sunken);border:0;color:var(--p-accent-hover);padding:1px 6px;border-radius:5px;font-size:.9em}.p-code[data-v-5fe218d3]{font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);line-height:1.65;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);padding:11px 13px;color:var(--p-text);overflow-x:auto}.p-action[data-v-5fe218d3]{border-radius:var(--p-r-lg);overflow:hidden;border:.5px solid var(--p-line);background:var(--p-surface-raised);box-shadow:var(--p-sh-menu)}.p-action-head[data-v-5fe218d3]{display:flex;align-items:center;gap:9px;padding:14px 16px 0}.p-action-title[data-v-5fe218d3]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-action-body[data-v-5fe218d3]{padding:12px 16px 0;font-size:var(--p-font-size-base);color:var(--p-text);line-height:var(--p-leading-normal)}.p-action-foot[data-v-5fe218d3]{display:flex;gap:8px;margin-top:12px;padding:10px 16px;border-top:.5px solid var(--p-line)}.p-opts[data-v-5fe218d3]{display:flex;flex-direction:column;gap:2px;margin-top:12px;padding:12px 16px;border-top:.5px solid var(--p-line)}.p-opt[data-v-5fe218d3]{display:flex;align-items:flex-start;gap:10px;padding:8px 12px;border-radius:var(--p-r-md);color:var(--p-text);font-size:var(--p-font-size-base)}.p-opt .n[data-v-5fe218d3]{width:var(--p-chip-num);height:var(--p-chip-num);margin-top:calc((var(--p-font-size-base) * var(--p-leading-normal) - var(--p-chip-num)) / 2);border-radius:var(--p-r-sm);background:var(--p-surface-sunken);color:var(--p-text);font-size:var(--p-font-size-xs);font-weight:500;display:inline-flex;align-items:center;justify-content:center;flex:none}.p-opt-text[data-v-5fe218d3]{display:flex;flex-direction:column;gap:2px;min-width:0}.p-opt-text .l[data-v-5fe218d3]{font-weight:500}.p-opt-text .d[data-v-5fe218d3]{font-size:var(--p-font-size-xs);color:var(--p-text-muted);line-height:var(--p-leading-normal)}.p-todo[data-v-5fe218d3]{background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-md);padding:6px}.p-todo-row[data-v-5fe218d3]{display:flex;align-items:center;gap:10px;padding:8px 10px;border-radius:var(--p-r-md);font-size:var(--p-font-size-base);color:var(--p-text)}.p-todo-row.done[data-v-5fe218d3]{color:var(--p-text-faint);text-decoration:line-through}.p-todo-row.active[data-v-5fe218d3]{background:var(--p-accent-soft);color:var(--p-text)}.p-todo-check[data-v-5fe218d3]{width:16px;flex:none;display:inline-flex;align-items:center;justify-content:center;user-select:none;color:var(--p-text-faint)}.p-todo-check svg[data-v-5fe218d3]{width:14px;height:14px}.p-todo-row.active .p-todo-check[data-v-5fe218d3]{color:var(--p-accent)}.p-todo-row.done .p-todo-check[data-v-5fe218d3]{color:var(--p-success)}.p-todo-row.active .p-todo-check[data-v-5fe218d3]{color:var(--p-accent);font-weight:500}.p-dot[data-v-5fe218d3]{width:7px;height:7px;border-radius:50%;flex:none;background:var(--p-text-faint)}.p-dot.done[data-v-5fe218d3]{background:var(--p-success)}.p-dot.error[data-v-5fe218d3]{background:var(--p-danger)}.p-dot.running[data-v-5fe218d3]{background:var(--p-accent);box-shadow:0 0 0 0 var(--p-accent-soft);animation:p-pulse-5fe218d3 1.4s ease-out infinite}@keyframes p-pulse-5fe218d3{0%{box-shadow:0 0 #1783ff66}to{box-shadow:0 0 0 6px #1783ff00}}.p-tool-group[data-v-5fe218d3]{overflow:hidden}.p-tool-group-head[data-v-5fe218d3]{display:flex;align-items:center;gap:4px;padding:4px 0;cursor:pointer;border-radius:6px;font-size:var(--p-font-size-sm);line-height:1;color:var(--p-text-faint);user-select:none;transition:color var(--p-dur) var(--p-ease)}.p-tool-group-head .tg-ic[data-v-5fe218d3]{width:14px;height:14px;color:var(--p-text-faint);flex:none}.p-tool-group-head[data-v-5fe218d3]:hover{color:var(--p-text)}.p-tool-group-head .tg-title[data-v-5fe218d3]{font-weight:500}.p-tool-group-head .tg-meta[data-v-5fe218d3]{color:var(--p-text-faint);font-weight:400}.p-tool-group-head .tg-car[data-v-5fe218d3]{width:14px;height:14px;color:var(--p-text-faint);transition:transform var(--p-dur) var(--p-ease)}.p-tool-group.open .p-tool-group-head .tg-car[data-v-5fe218d3]{transform:rotate(90deg)}.p-tool-row[data-v-5fe218d3]{position:relative;display:flex;align-items:center;gap:4px;padding:4px 0;border-radius:6px;cursor:pointer;font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);line-height:1;color:var(--p-text)}.p-tool-row .tr-ic[data-v-5fe218d3]{width:14px;height:14px;color:var(--p-text-faint);flex:none}.p-tool-row .tr-name[data-v-5fe218d3]{font-weight:400;color:var(--p-text-muted);flex:none}.p-tool-row .tr-file[data-v-5fe218d3]{font-weight:400;color:var(--p-text);flex:none}.p-tool-row .tr-file[data-v-5fe218d3]:hover{color:var(--p-accent);text-decoration:underline;text-underline-offset:3px}.p-tool-row .tr-mono[data-v-5fe218d3]{font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);line-height:normal;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--p-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.p-tool-row .tr-faint[data-v-5fe218d3]{color:var(--p-text-faint);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.p-tool-row .tr-chip[data-v-5fe218d3]{margin-left:auto;color:var(--p-text-faint);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-add[data-v-5fe218d3]{margin-left:auto;color:var(--p-success);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-add~.tr-chip[data-v-5fe218d3],.p-tool-row .tr-add~.tr-add[data-v-5fe218d3]{margin-left:0}.p-tool-row .tr-del[data-v-5fe218d3]{color:var(--p-danger);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-bar[data-v-5fe218d3]{display:inline-flex;width:36px;height:3px;border-radius:999px;overflow:hidden;gap:1px;flex:none}.p-tool-row .tr-ok[data-v-5fe218d3]{color:var(--p-success);font-size:var(--p-font-size-xs);flex:none}.p-tool-row .tr-car[data-v-5fe218d3]{width:13px;height:13px;color:var(--p-text-faint);flex:none;transition:transform var(--p-dur) var(--p-ease)}.p-agent-card[data-v-5fe218d3]{display:flex;align-items:center;gap:8px;align-self:stretch;padding:8px 12px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg);cursor:pointer}.p-agent-card .pa-ic[data-v-5fe218d3]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:8px;background:var(--p-surface-sunken);color:var(--p-text-muted);flex:none}.p-agent-card .pa-ic svg[data-v-5fe218d3]{width:14px;height:14px}.p-agent-card .pa-main[data-v-5fe218d3]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.p-agent-card .pa-task[data-v-5fe218d3]{font-size:var(--p-font-size-sm);line-height:1.4;color:var(--p-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-agent-card .pa-type[data-v-5fe218d3]{font-size:var(--p-font-size-xs);line-height:1.4;color:var(--p-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-agent-card .pa-ok[data-v-5fe218d3]{color:var(--p-success);font-size:var(--p-font-size-xs);flex:none}.p-agent-card .pa-go[data-v-5fe218d3]{color:var(--p-text-faint);flex:none}.p-tool-row.expanded .tr-car[data-v-5fe218d3]{transform:rotate(90deg)}.p-tool-detail[data-v-5fe218d3]{padding:2px 8px 4px 0}.p-tool-detail .p-code[data-v-5fe218d3]{margin-top:4px}.p-composer[data-v-5fe218d3]{background:var(--p-surface-raised);border:.5px solid var(--p-line-strong);border-radius:var(--p-r-composer);corner-shape:var(--p-corner-composer);box-shadow:var(--p-sh-input);overflow:hidden;position:relative;z-index:1}.p-composer[data-v-5fe218d3]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--p-composer-focus-line);border-radius:var(--p-r-composer);corner-shape:var(--p-corner-composer);opacity:0;pointer-events:none;transition:opacity var(--p-dur-slow) var(--p-ease-inout)}.p-composer[data-v-5fe218d3]:focus-within:after{opacity:1}.p-composer-ta[data-v-5fe218d3]{padding:14px 16px 8px;font-family:var(--p-font-sans);font-size:var(--p-font-size-md);color:var(--p-text);line-height:var(--p-leading-normal);text-autospace:normal}.p-composer-ta.ph[data-v-5fe218d3]{color:var(--p-text-faint)}.p-composer-bar[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 8px 8px}.p-composer-strip[data-v-5fe218d3]{width:100%;max-width:620px;margin-top:calc(-1 * var(--space-4));display:flex;align-items:center;gap:var(--space-2);padding:calc(var(--space-4) + var(--space-2)) var(--space-2) var(--space-2);background:color-mix(in srgb,var(--color-hover) 60%,transparent);border-radius:0 0 var(--radius-2xl) var(--radius-2xl);font-family:var(--p-font-sans);font-size:var(--p-font-size-sm);color:var(--p-text-faint);cursor:pointer}.p-composer-strip .p-ic[data-v-5fe218d3]{width:16px;height:16px;color:var(--p-text-faint)}.p-composer-left[data-v-5fe218d3],.p-composer-right[data-v-5fe218d3]{display:flex;align-items:center;gap:4px}.p-composer .p-icon-btn[data-v-5fe218d3]{border-radius:var(--p-r-full)}.p-send[data-v-5fe218d3]{position:relative;width:32px;height:32px;border-radius:var(--p-r-full);display:grid;place-items:center;background:var(--p-text);color:var(--p-bg);border:none;cursor:pointer;box-shadow:var(--p-sh-xs);transition:transform var(--p-dur-fast) var(--p-ease)}.p-send[data-v-5fe218d3]:after{content:"";position:absolute;inset:0;border-radius:var(--p-r-full);background:var(--p-bg);opacity:0;transition:opacity var(--p-dur-slow) var(--p-ease);pointer-events:none}.p-send[data-v-5fe218d3]:hover:after{opacity:.28}.p-send[data-v-5fe218d3]:active{transform:scale(.92)}.p-send .p-ic[data-v-5fe218d3]{width:16px;height:16px}.p[data-v-5fe218d3] ::selection,[data-p][data-v-5fe218d3] ::selection{background:var(--p-selection)}.p-link[data-v-5fe218d3]{color:var(--p-accent);text-decoration:none;font-family:var(--p-font-sans);transition:color var(--p-dur) var(--p-ease)}.p-link[data-v-5fe218d3]:hover{color:var(--p-accent-hover);text-decoration:underline}.p-link[data-v-5fe218d3]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:var(--p-r-xs)}.p-link.muted[data-v-5fe218d3]{color:var(--p-text-muted)}.p-link.muted[data-v-5fe218d3]:hover{color:var(--p-text)}.p-link .p-ic[data-v-5fe218d3]{width:var(--p-ic-sm);height:var(--p-ic-sm);vertical-align:-2px}.p-menu[data-v-5fe218d3]{background:var(--color-menu-bg);border:.5px solid var(--p-line);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border-radius:var(--p-r-lg);box-shadow:var(--p-sh-sm);padding:3.5px;min-width:180px;font-family:var(--p-font-sans);color:var(--p-text)}.p-menu-item[data-v-5fe218d3]{display:flex;align-items:center;gap:7px;padding:5px 9px;border-radius:var(--p-r-sm);font-size:var(--p-font-size-sm);color:var(--p-text);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-menu-item[data-v-5fe218d3]:hover{background:var(--p-hover);color:var(--p-text-strong)}.p-menu-item.active[data-v-5fe218d3],.p-menu-item.active[data-v-5fe218d3]:hover{background:var(--p-hover);color:var(--p-text)}.p-menu-item.danger[data-v-5fe218d3]{color:var(--p-danger)}.p-menu-item.danger[data-v-5fe218d3]:hover{background:var(--p-danger-soft);color:var(--p-danger)}.p-menu-item.disabled[data-v-5fe218d3]{opacity:.5;cursor:not-allowed}.p-menu-item.disabled[data-v-5fe218d3]:hover{background:transparent;color:var(--p-text)}.p-menu-item .p-ic[data-v-5fe218d3]{width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--p-muted)}.p-menu-item:hover .p-ic[data-v-5fe218d3]{color:var(--p-text-strong)}.p-menu-item.active .p-ic[data-v-5fe218d3]{color:var(--p-accent-hover)}.p-menu-item.danger .p-ic[data-v-5fe218d3]{color:var(--p-danger)}.p-menu-item.lg[data-v-5fe218d3]{min-height:44px;padding:12px 14px;font-size:var(--p-font-size-sm)}.p-menu-sep[data-v-5fe218d3]{height:1px;background:var(--p-line);margin:4px 0}.p-seg[data-v-5fe218d3]{display:inline-flex;gap:2px;padding:2px;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);font-family:var(--p-font-sans)}.p-seg-item[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:4px;padding:5px 12px;border-radius:var(--p-r-sm);font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text);cursor:pointer;white-space:nowrap;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease),box-shadow var(--p-dur) var(--p-ease)}.p-seg-item[data-v-5fe218d3]:hover{color:var(--p-text)}.p-seg-item.on[data-v-5fe218d3]{background:var(--p-surface-raised);color:var(--p-text);box-shadow:var(--p-sh-sm)}.p-tabs[data-v-5fe218d3]{display:flex;align-items:center;gap:0;border-bottom:.5px solid var(--p-line);font-family:var(--p-font-sans)}.p-tab[data-v-5fe218d3]{padding:8px 14px;font-size:var(--p-font-size-sm);font-weight:500;color:var(--p-text-muted);cursor:pointer;white-space:nowrap;border-bottom:.5px solid transparent;margin-bottom:-.5px;transition:color var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease)}.p-tab[data-v-5fe218d3]:hover{color:var(--p-text)}.p-tab.on[data-v-5fe218d3]{color:var(--p-accent);border-bottom-color:var(--p-accent)}.p-switch[data-v-5fe218d3]{position:relative;display:inline-block;width:36px;height:20px;flex:none;border-radius:var(--p-r-full);background:var(--p-line-strong);cursor:pointer;transition:background var(--p-dur) var(--p-ease)}.p-switch[data-v-5fe218d3]:after{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:var(--p-r-full);background:var(--p-surface-raised);box-shadow:var(--p-sh-xs);transform-origin:left center;transition:transform var(--p-dur) var(--p-ease)}.p-switch[data-v-5fe218d3]:hover:after{transform:scaleX(1.125)}.p-switch.on[data-v-5fe218d3]{background:var(--p-accent)}.p-switch.on[data-v-5fe218d3]:after{transform:translate(16px);transform-origin:right center}.p-switch.on[data-v-5fe218d3]:hover:after{transform:translate(16px) scaleX(1.125)}.p-switch[data-v-5fe218d3]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.p-check[data-v-5fe218d3]{width:17px;height:17px;flex:none;display:inline-grid;place-items:center;border:.5px solid var(--p-line-strong);border-radius:var(--p-r-sm);background:var(--p-surface-raised);color:var(--p-text-on-accent);cursor:pointer;transition:background var(--p-dur) var(--p-ease),border-color var(--p-dur) var(--p-ease)}.p-check.on[data-v-5fe218d3]{background:var(--p-accent);border-color:var(--p-accent)}.p-check[data-v-5fe218d3]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.p-check .p-ic[data-v-5fe218d3]{width:12px;height:12px}.p-avatar[data-v-5fe218d3]{width:32px;height:32px;flex:none;display:grid;place-items:center;border-radius:var(--p-r-md);background:var(--p-surface-sunken);border:.5px solid var(--p-line);color:var(--p-text-muted);font-size:var(--p-font-size-sm);font-weight:600}.p-avatar.sm[data-v-5fe218d3]{width:24px;height:24px;border-radius:var(--p-r-sm);font-size:var(--p-font-size-xs)}.p-avatar .p-ic[data-v-5fe218d3]{width:16px;height:16px}.p-avatar.sm .p-ic[data-v-5fe218d3]{width:13px;height:13px}.p-empty[data-v-5fe218d3]{display:flex;flex-direction:column;align-items:center;gap:8px;padding:32px 16px;color:var(--p-text-muted);text-align:center}.p-empty .em-ic[data-v-5fe218d3]{width:48px;height:48px;color:var(--p-text-faint)}.p-empty .em-title[data-v-5fe218d3]{font-size:var(--p-font-size-base);font-weight:600;color:var(--p-text)}.p-empty .em-hint[data-v-5fe218d3]{font-size:var(--p-font-size-sm);color:var(--p-text-muted)}.p-divider[data-v-5fe218d3]{width:100%;height:1px;background:var(--p-line);border:none}.p-divider-v[data-v-5fe218d3]{width:1px;align-self:stretch;background:var(--p-line);border:none}.p-turn-failed[data-v-5fe218d3]{display:flex;align-items:center;gap:var(--space-2);width:100%;max-width:560px;padding:var(--space-2) var(--space-3);border:var(--p-hairline) solid var(--color-danger-bd);border-radius:var(--radius-lg);background:var(--color-danger-soft);box-shadow:var(--shadow-xs)}.p-turn-failed .tf-chip[data-v-5fe218d3]{display:inline-flex;align-items:center;justify-content:center;width:var(--space-6);height:var(--space-6);flex:none;border-radius:var(--radius-md);background:var(--color-surface-raised);box-shadow:var(--shadow-xs);color:var(--color-danger)}.p-turn-failed .tf-chip svg[data-v-5fe218d3]{width:var(--p-ic-sm);height:var(--p-ic-sm)}.p-turn-failed .tf-main[data-v-5fe218d3]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.p-turn-failed .tf-title[data-v-5fe218d3]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-normal)}.p-turn-failed .tf-sub[data-v-5fe218d3],.p-turn-failed .tf-meta[data-v-5fe218d3]{font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-turn-failed .tf-meta[data-v-5fe218d3]{font-family:var(--font-mono);color:var(--color-text-faint)}.p-tip[data-v-5fe218d3]{position:relative;display:inline-flex}.p-tip .p-tooltip[data-v-5fe218d3]{position:absolute;bottom:calc(100% + 6px);left:50%;transform:translate(-50%);background:var(--p-text);color:var(--p-bg);font-size:var(--p-font-size-xs);padding:4px 8px;border-radius:var(--p-r-sm);white-space:nowrap;opacity:0;pointer-events:none;transition:opacity var(--p-dur-fast) var(--p-ease)}.p-tip:hover .p-tooltip[data-v-5fe218d3]{opacity:1}.p-banner[data-v-5fe218d3]{display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:var(--p-r-md);border:.5px solid var(--p-line);background:var(--p-surface);font-size:var(--p-font-size-sm);color:var(--p-text)}.p-banner .bn-ic[data-v-5fe218d3]{width:18px;height:18px;flex:none}.p-banner.info[data-v-5fe218d3]{background:var(--p-accent-soft);border-color:var(--p-accent-bd)}.p-banner.info .bn-ic[data-v-5fe218d3]{color:var(--p-accent)}.p-banner.warning[data-v-5fe218d3]{background:var(--p-warning-soft);border-color:var(--p-warning-bd)}.p-banner.warning .bn-ic[data-v-5fe218d3]{color:var(--p-warning)}.p-banner.danger[data-v-5fe218d3]{background:var(--p-danger-soft);border-color:var(--p-danger-bd)}.p-banner.danger .bn-ic[data-v-5fe218d3]{color:var(--p-danger)}.p-sheet[data-v-5fe218d3]{background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-xl) var(--p-r-xl) 0 0;box-shadow:var(--p-sh-xl);padding:8px 16px 20px}.p-sheet-handle[data-v-5fe218d3]{width:36px;height:4px;border-radius:var(--p-r-full);background:var(--p-line-strong);margin:0 auto 8px}.p-skeleton[data-v-5fe218d3]{background:var(--p-surface-sunken);border-radius:var(--p-r-sm);animation:p-skel-5fe218d3 1.2s var(--p-ease-inout) infinite alternate}@keyframes p-skel-5fe218d3{0%{opacity:.5}to{opacity:1}}.p-cmdbar[data-v-5fe218d3]{display:flex;align-items:center;gap:8px;width:100%}.p-cmd[data-v-5fe218d3]{flex:1;min-width:0;height:38px;display:flex;align-items:center;gap:10px;padding:0 10px 0 14px;background:var(--p-surface-sunken);border:.5px solid var(--p-line);border-radius:var(--p-r-md);font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);color:var(--p-text-muted)}.p-cmd .cmd-text[data-v-5fe218d3]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.p-cmd .cmd-copy[data-v-5fe218d3]{margin-left:auto;flex:none;display:grid;place-items:center;width:26px;height:26px;border:none;background:transparent;border-radius:var(--p-r-sm);color:var(--p-text-faint);cursor:pointer;transition:background var(--p-dur) var(--p-ease),color var(--p-dur) var(--p-ease)}.p-cmd .cmd-copy[data-v-5fe218d3]:hover{background:var(--p-surface-raised);color:var(--p-text)}.p-cmd .cmd-copy .p-ic[data-v-5fe218d3]{width:15px;height:15px}.p-topbar[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;gap:12px;height:48px;padding:0 16px;background:var(--p-surface-raised);border:.5px solid var(--p-line);border-radius:var(--p-r-lg)}.p-topbar .tb-title[data-v-5fe218d3]{font-size:var(--p-font-size-sm);font-weight:600;color:var(--p-text)}.p-topbar .tb-actions[data-v-5fe218d3]{display:flex;align-items:center;gap:4px}.p-topbar.frost[data-v-5fe218d3]{background:#ffffffb8;backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);border-color:#fff9}[data-p=dark] .p-topbar.frost[data-v-5fe218d3]{background:#161b22b8;border-color:#ffffff14}.demo-row[data-v-5fe218d3]{display:flex;flex-wrap:wrap;align-items:center;gap:10px}.demo-stack[data-v-5fe218d3]{display:flex;flex-direction:column;gap:12px;width:100%}.demo-col[data-v-5fe218d3]{display:flex;flex-direction:column;gap:10px}.demo-grow[data-v-5fe218d3]{flex:1;min-width:0}.demo-chat[data-v-5fe218d3]{display:flex;flex-direction:column;gap:14px;width:100%;max-width:560px}.icon-grid[data-v-5fe218d3]{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:8px;margin:14px 0}.icon-group-label[data-v-5fe218d3]{grid-column:1 / -1;margin-top:10px;font-size:11px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--d-fg-muted)}.icon-cell[data-v-5fe218d3]{display:flex;align-items:center;gap:10px;padding:8px 10px;border:.5px solid var(--d-line);border-radius:8px;background:var(--d-surface)}.icon-cell .kw-icon[data-v-5fe218d3]{width:20px;height:20px;color:var(--d-fg-soft)}.icon-cell .ic-name[data-v-5fe218d3]{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px;color:var(--d-fg)}.icon-sizes[data-v-5fe218d3]{display:flex;align-items:end;gap:22px;flex-wrap:wrap}.icon-sizes .sz[data-v-5fe218d3]{display:flex;flex-direction:column;align-items:center;gap:8px;font-size:11px;color:var(--d-fg-muted);font-family:JetBrains Mono,ui-monospace,monospace}.p-code-inline[data-v-5fe218d3]{font-family:var(--p-font-mono);background:var(--p-surface-sunken);color:var(--p-text);padding:0 5px;border-radius:var(--p-r-sm);font-size:.9em}.p-code-block[data-v-5fe218d3]{border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;background:var(--p-surface-sunken)}.p-code-block-head[data-v-5fe218d3]{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--p-surface);border-bottom:.5px solid var(--p-line);font-family:var(--p-font-mono);font-size:var(--p-font-size-xs);color:var(--p-text-muted)}.p-code-block pre[data-v-5fe218d3]{margin:0;padding:12px 14px;font-family:var(--p-font-mono);font-size:var(--p-font-size-sm);line-height:1.65;color:var(--p-text);overflow-x:auto}.p-diff[data-v-5fe218d3]{border:.5px solid var(--p-line);border-radius:var(--p-r-md);overflow:hidden;font-family:var(--p-font-mono);font-size:var(--p-font-size-sm)}.p-diff-head[data-v-5fe218d3]{padding:8px 12px;background:var(--p-surface);border-bottom:.5px solid var(--p-line);font-size:var(--p-font-size-xs);color:var(--p-text-muted)}.p-diff-row[data-v-5fe218d3]{display:flex;gap:10px;padding:2px 12px;line-height:1.6}.p-diff-row .pm[data-v-5fe218d3]{width:14px;flex:none;color:var(--p-text-faint)}.p-diff-row.add[data-v-5fe218d3]{background:var(--p-success-soft)}.p-diff-row.add .pm[data-v-5fe218d3]{color:var(--p-success)}.p-diff-row.del[data-v-5fe218d3]{background:var(--p-danger-soft)}.p-diff-row.del .pm[data-v-5fe218d3]{color:var(--p-danger)}.p-diff-row .p-diff-code[data-v-5fe218d3]{color:var(--p-text)}.p-field-error[data-v-5fe218d3]{color:var(--p-danger);font-size:var(--p-font-size-xs)}.p-btn .p-spinner[data-v-5fe218d3]{vertical-align:middle}.p-btn .p-spinner .track[data-v-5fe218d3]{stroke:currentColor;opacity:.35}.p-btn .p-spinner .arc[data-v-5fe218d3]{stroke:currentColor}.ds-page[data-v-5fe218d3]{position:fixed;inset:0;z-index:var(--z-max);overflow-y:auto}.ds-topbar[data-v-5fe218d3]{position:sticky;top:0;z-index:10;display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-4);background:var(--color-surface);border-bottom:.5px solid var(--color-line)}.ds-back[data-v-5fe218d3]{display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-3);border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface-raised);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);cursor:pointer}.ds-back[data-v-5fe218d3]:hover{background:var(--color-hover)}.ds-topbar-title[data-v-5fe218d3]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)} diff --git a/apps/kimi-code/dist-web/assets/DesignSystemView-TDJEKkA2.js b/apps/kimi-code/dist-web/assets/DesignSystemView-TDJEKkA2.js deleted file mode 100644 index 70ba82599..000000000 --- a/apps/kimi-code/dist-web/assets/DesignSystemView-TDJEKkA2.js +++ /dev/null @@ -1,13 +0,0 @@ -import{M as A,aD as B,aI as M,aL as n,u as l,v as t,G as c,H as e,F as g,aX as k,bb as x,I as s,bk as d,cx as o,cy as I,bJ as h,cz as T,cA as S,cB as E,cC as u,cD as D,cE as O}from"./index-D1h84VfZ.js";const H={class:"ds-page"},R={class:"layout"},V={class:"content"},L={class:"content-inner"},N={id:"tokens"},W={class:"icon-sizes"},P={class:"sz"},U={class:"p-ic",style:{width:"14px",height:"14px"},viewBox:"0 0 24 24",fill:"currentColor"},F={class:"sz"},j={class:"p-ic",style:{width:"16px",height:"16px"},viewBox:"0 0 24 24",fill:"currentColor"},G={class:"sz"},K={class:"p-ic",style:{width:"20px",height:"20px"},viewBox:"0 0 24 24",fill:"currentColor"},J={class:"icon-grid"},Y={class:"icon-group-label"},Q={class:"ic-name"},X={id:"primitives"},Z={class:"stage-wrap"},$={class:"stage p"},_={class:"p-pill",style:{color:"var(--p-warning)"}},aa={class:"stage-wrap"},ta={class:"stage p col"},ea={class:"stage-wrap"},sa={class:"stage p col"},da={class:"demo-row"},oa={class:"p-btn primary disabled"},ca={class:"p-spinner sm",viewBox:"0 0 24 24",style:{"--p-accent":"#fff","--p-line":"rgba(255,255,255,.35)"}},ia={class:"stage-wrap"},na={class:"stage p col"},la={class:"demo-row"},ra={class:"stage-wrap"},va={class:"stage p col",style:{gap:"0",background:"var(--p-surface)",padding:"0","max-width":"300px","align-items":"stretch"}},fa={style:{display:"flex","align-items":"center",gap:"8px",padding:"7px 10px",margin:"1px 6px","border-radius":"8px",color:"var(--p-text)","font-size":"13px"}},ha={style:{color:"var(--d-fg-faint)",flex:"none"},width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor"},pa={style:{display:"flex","align-items":"center",gap:"8px",padding:"7px 10px",margin:"1px 6px","border-radius":"8px",color:"var(--p-text)","font-size":"13px"}},ua={style:{color:"var(--d-fg-faint)",flex:"none"},width:"14",height:"14",viewBox:"0 0 24 24",fill:"currentColor"},ga={id:"chat"},ma={class:"stage-wrap"},ba={class:"stage p col"},wa={style:{"max-width":"560px",width:"100%"}},ya={class:"stage-wrap"},ka={class:"stage p col",style:{"align-items":"center",background:"#fff"}},xa={class:"p-composer",style:{width:"100%","max-width":"620px"}},Ta={class:"p-composer-bar"},Sa={class:"p-composer-left"},Ca={class:"p-pill",style:{color:"var(--p-warning)"}},za={class:"stage-wrap"},qa={class:"stage p",style:{background:"var(--p-bg)"}},Aa={class:"am-mock"},Ba={class:"am-mock-row focus"},Ma={class:"am-mock-row"},Ia={class:"am-mock-row"},Ea={class:"am-mock-row"},Da={class:"dt"},Oa={class:"dw-spin"},Ha={class:"stage-wrap"},Ra={class:"stage p",style:{background:"var(--p-bg)"}},Va={class:"dw-bar"},La={class:"dw-pill"},Na={class:"dw-pill"},Wa={class:"dw-pill on"},Pa={class:"dw-running"},Ua={class:"dw-pill"},Fa={class:"stage-wrap"},ja={class:"stage p col",style:{background:"var(--p-bg)",gap:"var(--space-4)"}},Ga={class:"dw-panel"},Ka={class:"dw-head"},Ja={class:"dw-tab"},Ya={class:"dw-chips"},Qa={class:"dw-chip on"},Xa={class:"dw-chip"},Za={class:"dw-chip"},$a={class:"dw-chip"},_a={class:"dw-body col"},at={class:"dw-row"},tt={class:"dw-row"},et={class:"dw-row fail"},st={class:"dw-row cancelled"},dt={class:"dw-panel"},ot={class:"dw-head"},ct={class:"dw-tab"},it={class:"dw-chips"},nt={class:"dw-chip on"},lt={class:"dw-chip"},rt={class:"dw-chip"},vt={class:"dw-chip"},ft={class:"dw-body grid"},ht={class:"dw-card"},pt={class:"cf"},ut={class:"cm"},gt={class:"cs"},mt={class:"sl"},bt={class:"tm"},wt={class:"dw-card"},yt={class:"cf"},kt={class:"cm"},xt={class:"cs"},Tt={class:"sl"},St={class:"tm"},Ct={class:"dw-card fail"},zt={class:"cf"},qt={class:"cm"},At={class:"cs"},Bt={class:"sl"},Mt={class:"tm"},It={class:"dw-card"},Et={class:"cf"},Dt={class:"cm"},Ot={class:"cs"},Ht={class:"sl"},Rt={class:"tm"},Vt="/repo",Lt=A({__name:"DesignSystemView",emits:["close"],setup(Nt,{emit:C}){const z=[{path:"/repo/apps/web/src/components/chat/TurnFilesSummary.vue",added:19,removed:4,hasWrite:!1,statsIncomplete:!1,diff:null},{path:"/repo/apps/web/src/composables/useFilePreview.ts",added:8,removed:1,hasWrite:!1,statsIncomplete:!1,diff:null},{path:"/repo/apps/web/src/components/chatTurnRendering.ts",added:0,removed:0,hasWrite:!0,statsIncomplete:!0,diff:null},{path:"/repo/apps/web/src/lib/toolDiff.ts",added:3,removed:2,hasWrite:!1,statsIncomplete:!1,diff:null}];function m(){}const q=C;function b(){q("close")}let p=null;function w(f){f.key==="Escape"&&b()}return B(()=>{document.addEventListener("keydown",w);const f=Array.prototype.slice.call(document.querySelectorAll('#nav a[href^="#"]')),a=new Map;f.forEach(v=>{const i=v.getAttribute("href");if(!i)return;const y=document.getElementById(i.slice(1));y&&a.set(y,v)});let r=null;p=new IntersectionObserver(v=>{v.forEach(i=>{i.isIntersecting&&(r&&r.classList.remove("active"),r=a.get(i.target)??null,r&&r.classList.add("active"))})},{rootMargin:"-20% 0px -70% 0px",threshold:0}),a.forEach((v,i)=>p.observe(i)),f.length&&f[0].classList.add("active")}),M(()=>{document.removeEventListener("keydown",w),p&&(p.disconnect(),p=null)}),(f,a)=>(n(),l("div",H,[t("div",{class:"ds-topbar"},[t("button",{class:"ds-back",type:"button",onClick:b},"← Back"),a[0]||(a[0]=t("span",{class:"ds-topbar-title"},"Design system",-1))]),t("div",R,[a[152]||(a[152]=c('<aside class="sidebar" data-v-247f7c56><div class="brand" data-v-247f7c56><div class="brand-mark" data-v-247f7c56>K</div><div class="brand-name" data-v-247f7c56>Kimi Web</div></div><div class="brand-sub" data-v-247f7c56>Design System · v1.0</div><div class="nav-group" data-v-247f7c56>Navigate</div><nav class="nav" id="nav" data-v-247f7c56><a href="#overview" data-v-247f7c56><span class="num" data-v-247f7c56>00</span>Overview</a><a href="#principles" data-v-247f7c56><span class="num" data-v-247f7c56>01</span>Design Principles</a><a href="#tokens" data-v-247f7c56><span class="num" data-v-247f7c56>02</span>Design Tokens</a><a href="#primitives" data-v-247f7c56><span class="num" data-v-247f7c56>03</span>Primitives</a><a href="#chat" data-v-247f7c56><span class="num" data-v-247f7c56>04</span>Chat Interface</a><a href="#richtext" data-v-247f7c56><span class="num" data-v-247f7c56>05</span>Rich Text Messages</a><a href="#themes" data-v-247f7c56><span class="num" data-v-247f7c56>06</span>Theming</a><a href="#rules" data-v-247f7c56><span class="num" data-v-247f7c56>07</span>Style Rules</a><a href="#shell" data-v-247f7c56><span class="num" data-v-247f7c56>08</span>App Shell & Sidebar</a><a href="#a11y" data-v-247f7c56><span class="num" data-v-247f7c56>09</span>Accessibility</a><a href="#dialogs" data-v-247f7c56><span class="num" data-v-247f7c56>10</span>Dialogs</a><a href="#session-admin" data-v-247f7c56><span class="num" data-v-247f7c56>11</span>Session Admin</a></nav><div class="nav-group" data-v-247f7c56>Companion output</div><nav class="nav" data-v-247f7c56><a href="#tokens" data-v-247f7c56><span class="num" data-v-247f7c56>↗</span>Token list</a><a href="#primitives" data-v-247f7c56><span class="num" data-v-247f7c56>↗</span>Component API</a><a href="#rules" data-v-247f7c56><span class="num" data-v-247f7c56>↗</span>Style rules</a></nav></aside>',1)),t("main",V,[t("div",L,[a[150]||(a[150]=c('<section id="overview" data-v-247f7c56><div class="hero" data-v-247f7c56><span class="eyebrow" data-v-247f7c56>● Design System · v1.0</span><h1 data-v-247f7c56>Kimi Web <span class="grad" data-v-247f7c56>Design System</span></h1><p class="lead" data-v-247f7c56> This document defines the visual language and component specification for Kimi Web — design tokens, component primitives, the chat interface, theming, and style rules. All UI work is grounded in it: unified, restrained, token-driven, and themeable. </p><div class="hero-meta" data-v-247f7c56><span class="meta-chip" data-v-247f7c56><span class="dot" data-v-247f7c56></span> Scope <b data-v-247f7c56>apps/kimi-web</b></span><span class="meta-chip" data-v-247f7c56>Component primitives</span><span class="meta-chip" data-v-247f7c56>Theme <b data-v-247f7c56>1 set · 4 customizable colors</b></span><span class="meta-chip" data-v-247f7c56>Light / dark mode</span></div></div><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>This spec is the single reference when changing the web UI.</b> Before adding or modifying a component, style, layout, or theme, read this document first; color, font, radius, spacing, shadow, z-index, and motion always use the §02 tokens, components reuse the §03 primitives, and the §06 style rules are followed. </div></div></section><section id="principles" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>01</span><h2 class="sec-title" data-v-247f7c56>Design Principles</h2></div><p class="sec-desc" data-v-247f7c56> Every UI decision traces back to the following principles. Kimi Web is a local Agent tool for developers: quick scanning, long stretches of staring, often in the dark — the design serves the task, and is restrained, clinical, and density-first. </p><ul class="clean check" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>Consistency</b> —— The same semantics use the same component. The primary button, dialog, input, and badge should each have exactly "one" correct way to be written across the entire site.</li><li data-v-247f7c56><b data-v-247f7c56>Hierarchy</b> —— Build a clear hierarchy through size, weight, color, and whitespace; emphasize through "restraint" rather than "bolder and bigger".</li><li data-v-247f7c56><b data-v-247f7c56>Proximity</b> —— Group related elements, leave whitespace between unrelated ones. A card's padding, line spacing, and group spacing all come from the same spacing scale.</li><li data-v-247f7c56><b data-v-247f7c56>Feedback</b> —— hover / active / focus / loading / success / error all have visible states, and the state language is unified.</li><li data-v-247f7c56><b data-v-247f7c56>Breathing room</b> —— Control density with the spacing scale rather than arbitrary pixels; prefer restrained whitespace over cramming controls together.</li><li data-v-247f7c56><b data-v-247f7c56>Accessibility (A11y)</b> —— Text contrast ≥ 4.5:1, visible focus rings, touch targets ≥ 32px, and states that don't rely on color alone.</li><li data-v-247f7c56><b data-v-247f7c56>Reduction</b> —— The number of colors, radii, shadow levels, and type sizes all converge to a finite set of tokens; delete stray values.</li></ul><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56><b data-v-247f7c56>Brand tone (the do-not list)</b>: calm, clinical, never exaggerated. <span class="pill red" style="margin:0 4px;" data-v-247f7c56>Reject</span> purple gradients, glassmorphism, glowing shadows, AI purple / blue glows, endlessly looping fussy micro-animations, "Boost your productivity"-style marketing copy, and using emoji as icons. These are all common tells of AI-generated interfaces (an "AI tell"), deliberately avoided. </div></div><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>Declare design intent first (Design Read)</b>: before adding a component / page, write one sentence describing its scenario, audience, and tone (for example, "a lightweight tool card embedded in a conversation, for developers, calm and restrained"), then build. If the intent isn't clear, ask one question first rather than defaulting to the nearest existing style. </div></div></section>',2)),t("section",N,[a[7]||(a[7]=c(`<div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>02</span><h2 class="sec-title" data-v-247f7c56>Design Tokens</h2></div><p class="sec-desc" data-v-247f7c56> Collapse every visual decision into tokens. <b data-v-247f7c56>Color tokens keep the existing short names and fill out the semantics</b> (lowering migration cost), while <b data-v-247f7c56>spacing, z-index, motion, and font-weight</b> fill in the scales that are currently missing. Every token has: name, light value, dark value, and usage. </p><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>Naming convention</b>: <code data-v-247f7c56>--<category>-<role>-<state></code>. For example <code data-v-247f7c56>--color-text-muted</code>, <code data-v-247f7c56>--radius-md</code>, <code data-v-247f7c56>--space-4</code>. To reduce churn, the existing short names (<code data-v-247f7c56>--bg</code> / <code data-v-247f7c56>--ink</code> / <code data-v-247f7c56>--line</code> / <code data-v-247f7c56>--blue</code> …) are kept as <b data-v-247f7c56>compatibility aliases</b> for one release cycle. </div></div><h3 class="sub" data-v-247f7c56>Color</h3><p data-v-247f7c56>Semantic-first, in three layers: <b data-v-247f7c56>background / text / border</b> + <b data-v-247f7c56>accent</b> + <b data-v-247f7c56>status colors</b>. All colors are defined in light / dark pairs, with contrast ≥ 4.5:1.</p><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56>The table below shows the <b data-v-247f7c56>semantic tokens</b>. Each ships a light value in <code data-v-247f7c56>:root</code> and a dark override in the <code data-v-247f7c56>data-color-scheme</code> blocks — for example <code data-v-247f7c56>--color-bg</code> is <code data-v-247f7c56>#ffffff</code> in light and <code data-v-247f7c56>#121212</code> in dark; <code data-v-247f7c56>--color-accent</code> is the brand blue (<code data-v-247f7c56>#1783ff</code> light / <code data-v-247f7c56>#1a88ff</code> dark). The <b data-v-247f7c56>semantic status colors</b> (success / warning / danger / info) are independent palettes, one set each for light / dark.</div></div><div class="palette" data-v-247f7c56><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#ffffff;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>bg</div><div class="cv" data-v-247f7c56>#ffffff / #121212</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#f5f5f5;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>surface</div><div class="cv" data-v-247f7c56>#f5f5f5 / #1f1f1f</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#f5f5f5;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>surface-sunken</div><div class="cv" data-v-247f7c56>#f5f5f5 / #121212</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#f5f5f5;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>well</div><div class="cv" data-v-247f7c56>#f5f5f5 / #1f1f1f</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#f5f5f5;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>surface-deep</div><div class="cv" data-v-247f7c56>#f5f5f5 / #0d0d0d</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#fff;border:0.5px solid rgba(0,0,0,.13);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>surface-overlay</div><div class="cv" data-v-247f7c56>#ffffff / rgba(255,255,255,.1)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:rgba(0,0,0,.05);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>selected</div><div class="cv" data-v-247f7c56>rgba(0,0,0,.05) / rgba(255,255,255,.1)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:rgba(0,0,0,.9);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>fg</div><div class="cv" data-v-247f7c56>rgba(0,0,0,.9) / rgba(255,255,255,.84)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:rgba(0,0,0,.6);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>fg-muted</div><div class="cv" data-v-247f7c56>rgba(0,0,0,.6) / rgba(255,255,255,.56)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:rgba(0,0,0,.13);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>line</div><div class="cv" data-v-247f7c56>rgba(0,0,0,.13) / rgba(255,255,255,.12)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:rgba(0,0,0,.05);" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>subtle</div><div class="cv" data-v-247f7c56>rgba(0,0,0,.05) / rgba(255,255,255,.05)</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#1783ff;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>accent (KMBlue)</div><div class="cv" data-v-247f7c56>#1783ff / #1a88ff</div></div></div><div class="color-card" data-v-247f7c56><div class="color-chip" style="background:#e8f3ff;" data-v-247f7c56></div><div class="color-meta" data-v-247f7c56><div class="cn" data-v-247f7c56>accent-soft</div><div class="cv" data-v-247f7c56>#e8f3ff / rgba(26,136,255,.1)</div></div></div></div><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Light</th><th data-v-247f7c56>Dark</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-bg</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#121212;" data-v-247f7c56></span>#121212</td><td data-v-247f7c56>Page background</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-surface</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f5f5f5;" data-v-247f7c56></span>#f5f5f5</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#1f1f1f;" data-v-247f7c56></span>#1f1f1f</td><td data-v-247f7c56>Panel / sidebar / card head</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-surface-raised</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#292929;" data-v-247f7c56></span>#292929</td><td data-v-247f7c56>Raised card / dialog / input</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-menu-bg</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.95);" data-v-247f7c56></span>rgba(255,255,255,.95)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(41,41,41,.95);" data-v-247f7c56></span>rgba(41,41,41,.95)</td><td data-v-247f7c56>Floating menu panel — frosted glass over <code data-v-247f7c56>--p-menu-backdrop</code> blur</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-surface-overlay</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-247f7c56></span>rgba(255,255,255,.1)</td><td data-v-247f7c56>Field-control fill on raised cards (selects, steppers) — top rung; light tops out at white (the level is carried by the border), dark steps one rung above raised. Floating layers stay at raised</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-well</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f5f5f5;" data-v-247f7c56></span>#f5f5f5</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#1f1f1f;" data-v-247f7c56></span>#1f1f1f</td><td data-v-247f7c56>Content well on the page (code blocks, tool-output panels, match/file lists, media thumbnails) — light reuses the sunken recess; dark lifts one rung ABOVE the page, because a true recess (<code data-v-247f7c56>#121212</code>) vanishes into the page there</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-surface-deep</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f5f5f5;" data-v-247f7c56></span>#f5f5f5</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0d0d0d;" data-v-247f7c56></span>#0d0d0d</td><td data-v-247f7c56>Deep chrome plane one step BELOW the page (panel headers, diff gutters) — dark drops under <code data-v-247f7c56>--color-bg</code> so chrome framing stays darker than the content it frames</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-text</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.9);" data-v-247f7c56></span>rgba(0,0,0,.9)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.84);" data-v-247f7c56></span>rgba(255,255,255,.84)</td><td data-v-247f7c56>Body text / headings</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-text-strong</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#000;" data-v-247f7c56></span>#000000</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;box-shadow:inset 0 0 0 1px #ddd;" data-v-247f7c56></span>#ffffff</td><td data-v-247f7c56>Max foreground emphasis — menu-row label & icon on hover</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-text-muted</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-247f7c56></span>rgba(0,0,0,.6)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.56);" data-v-247f7c56></span>rgba(255,255,255,.56)</td><td data-v-247f7c56>Secondary text / placeholder</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-line</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.13);" data-v-247f7c56></span>rgba(0,0,0,.13)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.12);" data-v-247f7c56></span>rgba(255,255,255,.12)</td><td data-v-247f7c56>Divider / card border</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-subtle</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.05);" data-v-247f7c56></span>rgba(0,0,0,.05)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.05);" data-v-247f7c56></span>rgba(255,255,255,.05)</td><td data-v-247f7c56>Subtle hairline — tertiary separators below <code data-v-247f7c56>--color-line</code> (diff-gutter column rules, quiet dividers inside wells)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-selected</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.05);" data-v-247f7c56></span>rgba(0,0,0,.05)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-247f7c56></span>rgba(255,255,255,.1)</td><td data-v-247f7c56>Neutral selected fill (sidebar rows, list pickers) — translucent, never accent-tinted</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-hover</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.03);" data-v-247f7c56></span>rgba(0,0,0,.03)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.05);" data-v-247f7c56></span>rgba(255,255,255,.05)</td><td data-v-247f7c56>Row hover wash — lighter than the selected fill (hover < selected); translucent, sits on any surface. The global hover rule: transparent-base controls overlay this f1 wash (hover never darkens — never sunken); filled controls use their own hover token (accent-hover, send-bg-hover)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-selected-hover</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.08);" data-v-247f7c56></span>rgba(0,0,0,.08)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.14);" data-v-247f7c56></span>rgba(255,255,255,.14)</td><td data-v-247f7c56>Hover of a control RESTING at the selected fill (work cards) — one rung above f2, below f3: hover deepens/brightens a step, never drops below the rest state</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-inline-code-bg</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.03);" data-v-247f7c56></span>rgba(0,0,0,.03)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(255,255,255,.1);" data-v-247f7c56></span>rgba(255,255,255,.1)</td><td data-v-247f7c56>Inline-code chip fill — fills.f1 / fills.f2; dark lifts off any dark surface (sunken == bg there)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-media-alpha-bg-1</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#858585;" data-v-247f7c56></span>≈#858585</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#76797e;" data-v-247f7c56></span>≈#76797e</td><td data-v-247f7c56>Checkerboard square A of the <code data-v-247f7c56><img></code> alpha canvas — color-mix of <code data-v-247f7c56>--color-bg</code>/<code data-v-247f7c56>--color-text</code> (52/48); applied via <code data-v-247f7c56>--media-alpha-canvas</code> (16px period)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-media-alpha-bg-2</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#6b6b6b;" data-v-247f7c56></span>≈#6b6b6b</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#8c8f93;" data-v-247f7c56></span>≈#8c8f93</td><td data-v-247f7c56>Checkerboard square B (42/58) — both squares stay ≥3:1 against white and black; opaque images cover the canvas</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-sidebar-bg</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f9fbfc;" data-v-247f7c56></span>#f9fbfc</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0d0d0d;" data-v-247f7c56></span>#0d0d0d</td><td data-v-247f7c56>Sidebar surface — one step off <code data-v-247f7c56>--color-bg</code> (just under white in light, one step BELOW the page in dark) so the session column reads as its own plane and never brighter than the reading surface</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-scrim</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.4);" data-v-247f7c56></span>rgba(0,0,0,.4)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-247f7c56></span>rgba(0,0,0,.6)</td><td data-v-247f7c56>Modal scrim — the dark veil behind dialogs/lightboxes (mask.base; legacy hardcoded overlays can migrate here)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-scrim-strong</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.6);" data-v-247f7c56></span>rgba(0,0,0,.6)</td><td class="val" data-v-247f7c56><span class="swatch" style="background:rgba(0,0,0,.75);" data-v-247f7c56></span>rgba(0,0,0,.75)</td><td data-v-247f7c56>Stronger scrim for full-screen media previews (mask.strong — the PhotoSwipe image preview backdrop)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-text-on-scrim</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>same</td><td data-v-247f7c56>Text drawn on the scrim (captions over the media lightbox)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-accent</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#1783ff;" data-v-247f7c56></span>#1783ff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#1a88ff;" data-v-247f7c56></span>#1a88ff</td><td data-v-247f7c56>Primary action / link / focus</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-success</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0e7a38;" data-v-247f7c56></span>#0e7a38</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#3fb950;" data-v-247f7c56></span>#3fb950</td><td data-v-247f7c56>Success / pass</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-warning</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#a9610a;" data-v-247f7c56></span>#a9610a</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#d29922;" data-v-247f7c56></span>#d29922</td><td data-v-247f7c56>Warning / pending</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--color-danger</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#c0392b;" data-v-247f7c56></span>#c0392b</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f85149;" data-v-247f7c56></span>#f85149</td><td data-v-247f7c56>Danger / error / abort</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Palette</h4><p data-v-247f7c56>The palette <b data-v-247f7c56>is</b> the production kimi.com palette (design tokens <code data-v-247f7c56>tokens.json</code>): neutral-gray surfaces, an alpha-based label / fill / separator ramp (<code data-v-247f7c56>labels.*</code> / <code data-v-247f7c56>fills.*</code> / <code data-v-247f7c56>separator.s1</code>), the KMBlue accent, and a true neutral dark ladder (<code data-v-247f7c56>#121212 → #1f1f1f → #292929</code>; the deep chrome plane and sidebar derive one step below at <code data-v-247f7c56>#0d0d0d</code> — the palette has nothing darker than primary).</p><p data-v-247f7c56>The ONE deliberate exception is the <b data-v-247f7c56>status hues</b>: success / warning / danger / done keep the app's own WCAG-tuned ramp (≥4.5:1 on the neutral surfaces) — the production status colours (positiveGreen <code data-v-247f7c56>#16c456</code>, orange <code data-v-247f7c56>#ff9500</code>, danger red <code data-v-247f7c56>#ff3849</code>) are too bright against it. Diff add/del bands happen to coincide (both use the production 25% fills in light, 14% in dark).</p><h4 class="mini" data-v-247f7c56>Surface usage</h4><p data-v-247f7c56>The surface layers each have a role — choose by "field overlay / raised layer / content well / default flat layer / sunken layer / page background / deep chrome", and avoid treating <code data-v-247f7c56>--p-surface-raised</code> as a universal background. In dark, elevation = lighter: floating layers sit above the content, content wells sit above the page, and chrome planes (sidebar, panel headers) sit below it — never the reverse. One consequence: on the page itself, never use <code data-v-247f7c56>--color-surface-sunken</code> for a content carrier — it equals <code data-v-247f7c56>--color-bg</code> in dark and the fill vanishes; use <code data-v-247f7c56>--color-well</code>. Sunken stays correct INSIDE surface / raised cards, where it is a genuine recess. Field controls (selects, steppers) on a raised card use <code data-v-247f7c56>--color-surface-overlay</code>, the top fill rung; floating layers keep <code data-v-247f7c56>--color-surface-raised</code> — their elevation is shadow + hairline, not a lighter fill.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Light</th><th data-v-247f7c56>Dark</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-surface-overlay</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#22272e;" data-v-247f7c56></span>#22272e</td><td data-v-247f7c56>Field controls on raised cards — select, stepper (top fill rung; light = white)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-surface-raised</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#1c2128;" data-v-247f7c56></span>#1c2128</td><td data-v-247f7c56>Raised card / dialog / input (raised layer)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-well</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f3f5f8;" data-v-247f7c56></span>#f3f5f8</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#13181e;" data-v-247f7c56></span>#13181e</td><td data-v-247f7c56>Code block / tool output / list carrier directly on the page (content well — light: recessed, dark: one rung above the page)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-surface</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fafbfc;" data-v-247f7c56></span>#fafbfc</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#13181e;" data-v-247f7c56></span>#13181e</td><td data-v-247f7c56>Panel / sidebar / card head (default flat layer)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-surface-sunken</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#f3f5f8;" data-v-247f7c56></span>#f3f5f8</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0d1117;" data-v-247f7c56></span>#0d1117</td><td data-v-247f7c56>Recessed area INSIDE a surface / raised card — never a content carrier on the page (sunken layer)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-bg</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fff;" data-v-247f7c56></span>#ffffff</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0d1117;" data-v-247f7c56></span>#0d1117</td><td data-v-247f7c56>Page background</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-surface-deep</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#fafbfc;" data-v-247f7c56></span>#fafbfc</td><td class="val" data-v-247f7c56><span class="swatch" style="background:#0a0d12;" data-v-247f7c56></span>#0a0d12</td><td data-v-247f7c56>Panel header / diff gutter (deep chrome layer — below the page in dark)</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Borders & hairlines</h4><p data-v-247f7c56>Three line tokens, three jobs: <code data-v-247f7c56>--color-line</code> is the default structural separator, <code data-v-247f7c56>--color-subtle</code> the tertiary separator that must stay quieter (diff-gutter column rules, quiet dividers inside wells), and <code data-v-247f7c56>--color-line-strong</code> the edge of interactive controls (inputs, selects, secondary buttons). Width is one: <b data-v-247f7c56>0.5px</b> — every stroke is the same hairline, on static structural edges (card rims, plane seams, header dividers), interactive control rims and floating layers alike. Separation comes from luminance first — planes one rung apart already read as distinct in dark, so their shared edge stays a 0.5px hairline rather than a heavier border; same-rung neighbours (list rows, card head / body) are exactly where a hairline is required. In dark, drop shadows fade on near-black surfaces, so a floating layer's edge IS its hairline — never ship a shadow-only floating surface. (Legacy <code data-v-247f7c56>--line</code> / <code data-v-247f7c56>--line2</code> alias <code data-v-247f7c56>--color-line</code> / <code data-v-247f7c56>--color-subtle</code> for one cycle; new work references the v2 names.)</p><h4 class="mini" data-v-247f7c56>Focus ring</h4><p data-v-247f7c56>All focusable controls (button, input, link, menu item, switch, checkbox) use the focus-ring token uniformly; do not hand-write a <code data-v-247f7c56>box-shadow</code> focus ring.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-focus-ring-w</td><td class="val" data-v-247f7c56>3px</td><td data-v-247f7c56>The focus ring's spread width — the rings below derive from it, and so does anything that must reserve room for the ring (clip protection)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-focus-ring</td><td class="val" data-v-247f7c56>0 0 0 3px var(--p-accent-soft)</td><td data-v-247f7c56>Default focus ring (link, menu item, switch, checkbox)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-focus-ring-strong</td><td class="val" data-v-247f7c56>0 0 0 3px var(--p-accent-soft), 0 0 0 1px var(--p-accent)</td><td data-v-247f7c56>Strong focus ring (button, primary action)</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Text selection</h4><p data-v-247f7c56>The text-selection color uses <code data-v-247f7c56>--p-selection</code> uniformly (light <code data-v-247f7c56>rgba(23,131,255,.18)</code> / dark <code data-v-247f7c56>rgba(88,166,255,.32)</code>), applied by the global <code data-v-247f7c56>::selection</code> rule; do not set a separate highlight background.</p><h4 class="mini" data-v-247f7c56>Disabled state</h4><p data-v-247f7c56>All disabled controls use <code data-v-247f7c56>opacity:.5</code> + <code data-v-247f7c56>cursor:not-allowed</code> uniformly; do not separately grey out or recolor.</p><h3 class="sub" data-v-247f7c56>Font families</h3><p data-v-247f7c56>Kimi Web uses two font tokens: <b data-v-247f7c56>--font-ui</b> (UI and body, with Schibsted Grotesk for Latin and Noto Sans SC for Simplified Chinese) and <b data-v-247f7c56>--font-mono</b> (code and monospace). Components always reference the variables; do not hard-code font names.</p><h4 class="mini" data-v-247f7c56>--font-ui · UI & body (Schibsted Grotesk + Noto Sans SC)</h4><p data-v-247f7c56>Body and UI use self-hosted Schibsted Grotesk for Latin text and self-hosted Noto Sans SC Variable for Simplified Chinese. Platform fonts remain as fallbacks:</p><div class="code" data-v-247f7c56><div class="code-bar" data-v-247f7c56><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="fn" data-v-247f7c56>--font-ui</span></div><pre data-v-247f7c56>--font-ui: "Schibsted Grotesk Variable", "Helvetica Neue", Arial, - "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", - "Microsoft YaHei", - -apple-system, BlinkMacSystemFont, "Segoe UI", - Roboto, Ubuntu, sans-serif, - "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji";</pre></div><ul class="clean" data-v-247f7c56><li data-v-247f7c56>Schibsted Grotesk first: self-hosted Latin UI and body text, with normal and italic variable faces.</li><li data-v-247f7c56>Western fallbacks next: Helvetica Neue / Arial for environments where Schibsted Grotesk cannot load.</li><li data-v-247f7c56>Noto Sans SC Variable next: bundled Simplified Chinese glyphs with a weight range of 100–900.</li><li data-v-247f7c56>System UI fallbacks last: PingFang SC / Microsoft YaHei, platform UI fonts, and emoji fonts.</li></ul><h4 class="mini" data-v-247f7c56>--font-mono · Code & monospace</h4><p data-v-247f7c56>Code, line numbers, diffs, and Bash commands use JetBrains Mono (a self-hosted variable font), falling back to the system monospace. Other tool labels and summaries use the UI font:</p><div class="code" data-v-247f7c56><div class="code-bar" data-v-247f7c56><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="fn" data-v-247f7c56>--font-mono</span></div><pre data-v-247f7c56>--font-mono: "JetBrains Mono Variable", "JetBrains Mono", - ui-monospace, "SF Mono", Menlo, Consolas, monospace;</pre></div><h4 class="mini" data-v-247f7c56>Loading strategy</h4><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Font</th><th data-v-247f7c56>Source</th><th data-v-247f7c56>Bundled</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>JetBrains Mono</td><td class="val" data-v-247f7c56>@fontsource-variable/jetbrains-mono</td><td class="val" data-v-247f7c56>✓ self-hosted</td><td data-v-247f7c56>monospace / code (--font-mono)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Schibsted Grotesk</td><td class="val" data-v-247f7c56>prepare-fonts → app-ui/assets/fonts</td><td class="val" data-v-247f7c56>✓ generated + bundled</td><td data-v-247f7c56>UI / body / display (--font-ui, --font-display), wght 400-900, normal + italic</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Noto Sans SC</td><td class="val" data-v-247f7c56>prepare-fonts → app-ui/assets/fonts</td><td class="val" data-v-247f7c56>✓ generated + bundled</td><td data-v-247f7c56>Simplified Chinese UI / body, wght 100–900</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>System UI / CJK fonts</td><td class="val" data-v-247f7c56>operating system</td><td class="val" data-v-247f7c56>—</td><td data-v-247f7c56>late fallback for UI / body</td></tr></tbody></table><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56> Schibsted Grotesk, Noto Sans SC, and JetBrains Mono are self-hosted. They make no external network requests and work offline; platform fonts remain as fallbacks. </div></div><h4 class="mini" data-v-247f7c56>Usage rules</h4><ul class="clean check" data-v-247f7c56><li data-v-247f7c56>Components always use <code data-v-247f7c56>var(--font-ui)</code> / <code data-v-247f7c56>var(--font-mono)</code>; do not hard-code font names like <code data-v-247f7c56>'Schibsted Grotesk'</code> / <code data-v-247f7c56>'JetBrains Mono'</code>.</li><li data-v-247f7c56>Body / UI use <code data-v-247f7c56>--font-ui</code> (Schibsted Grotesk for Latin, Noto Sans SC for Simplified Chinese); code / monospace use <code data-v-247f7c56>--font-mono</code> (JetBrains Mono).</li><li data-v-247f7c56>Schibsted Grotesk is loaded from complete variable faces, including normal and italic styles; <code data-v-247f7c56>font-optical-sizing: auto</code> is enabled globally.</li><li data-v-247f7c56>Noto Sans SC is loaded from one complete weight-variable WOFF2 asset. Platform CJK fonts stay late in the fallback chain.</li></ul><h3 class="sub" data-v-247f7c56>Type scale & weight</h3><p data-v-247f7c56>The user font-size preference is one of four named steps (<code data-v-247f7c56>small / medium / large / xlarge</code>, Medium default) written to <code data-v-247f7c56>data-font-scale</code> on <code data-v-247f7c56><html></code>; the step name is persisted, never a px value. The step only moves <code data-v-247f7c56>--base-font</code>; every size token derives additively (<code data-v-247f7c56>default + shift</code>), and line heights are locked to integer px via <code data-v-247f7c56>round(size × ratio, 1px)</code> — never a unitless ratio.</p><p data-v-247f7c56>Two token groups share the shift but keep their own ratios: <b data-v-247f7c56>--ui-*</b> for chrome (tight, 1.40–1.50) and <b data-v-247f7c56>--md-*</b> for Markdown content + the composer (loose, 1.56–1.63; body is anchored to the UI body size — the spec's +2px offset was dropped as a product decision — while keeping its own looser line-height ratios). T0/T1 cap at 24/22px on the top steps (built into the tokens via <code data-v-247f7c56>min()</code> — do not remove). Use the <code data-v-247f7c56>.text-ui-*</code> / <code data-v-247f7c56>.text-md-*</code> utility classes; legacy aliases <code data-v-247f7c56>--ui-font-size</code> (→ <code data-v-247f7c56>--ui-b2</code>), <code data-v-247f7c56>--content-font-size</code> (→ <code data-v-247f7c56>--md-b1</code>) and the whole 6-level <code data-v-247f7c56>--text-*</code> ramp (xs→c1, sm→b2−1px, base→b2, lg→t2, xl→t1, 2xl→t0) keep older components on the ramp. Panel titles sit at the base step (<code data-v-247f7c56>--ui-b2</code>); dropdown menu items sit one rung below (<code data-v-247f7c56>--text-sm</code> = b2 − 1px) — both still follow the user's font scale.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-247f7c56><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-t1);font-weight:500;" data-v-247f7c56>Section Title</div><div class="type-meta" data-v-247f7c56>--ui-t1 · title (cap 22)</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-t2);font-weight:500;" data-v-247f7c56>Card title</div><div class="type-meta" data-v-247f7c56>--ui-t2 · subtitle</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-b1);font-weight:500;" data-v-247f7c56>UI emphasis</div><div class="type-meta" data-v-247f7c56>--ui-b1 · body strong</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-b2);" data-v-247f7c56>UI control / button / form</div><div class="type-meta" data-v-247f7c56>--ui-b2 · body</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-c1);" data-v-247f7c56>Helper text / table</div><div class="type-meta" data-v-247f7c56>--ui-c1 · caption</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--ui-c2);" data-v-247f7c56>Badge / timestamp</div><div class="type-meta" data-v-247f7c56>--ui-c2 · non-critical only</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--md-h1);font-weight:600;" data-v-247f7c56>Markdown H1</div><div class="type-meta" data-v-247f7c56>--md-h1</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--md-b1);" data-v-247f7c56>Chat body / message bubbles / composer</div><div class="type-meta" data-v-247f7c56>--md-b1 · prose body</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--md-b2);" data-v-247f7c56>Quote / table</div><div class="type-meta" data-v-247f7c56>--md-b2 · secondary</div></div><div class="type-row" data-v-247f7c56><div class="type-sample" style="font-size:var(--md-b3);font-family:var(--font-mono);" data-v-247f7c56>Code block / inline code</div><div class="type-meta" data-v-247f7c56>--md-b3 · weak / code</div></div></div><p data-v-247f7c56>The fixed product type tokens still define scale-independent defaults: transcript prose enables <code data-v-247f7c56>text-autospace: normal</code> for mixed CJK and Latin text. Drop stray <code data-v-247f7c56>font-weight: 650 / 750</code>; converge on 400 / 500 (regular / emphasis), with a dedicated 600 weight for sidebar section labels.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--font-ui</td><td class="val" data-v-247f7c56>"Schibsted Grotesk Variable", …, "Noto Sans SC Variable", …</td><td data-v-247f7c56>UI & body (Schibsted Grotesk + Noto Sans SC)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--font-kbd</td><td class="val" data-v-247f7c56>"Schibsted Grotesk Variable", system-ui, sans-serif</td><td data-v-247f7c56>keyboard shortcut keycaps</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--font-mono</td><td class="val" data-v-247f7c56>JetBrains Mono…</td><td data-v-247f7c56>code, Bash commands, line numbers, diffs</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>data-font-scale</td><td class="val" data-v-247f7c56>small / medium / large / xlarge</td><td data-v-247f7c56>user preference on <html>; sets --base-font (12–18px), Medium = 14px default</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--ui-t0…--ui-c2</td><td class="val" data-v-247f7c56>default + --ui-shift, t0/t1 capped via min()</td><td data-v-247f7c56>chrome type ramp (title / subtitle / body / caption); .text-ui-* classes</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--md-h1…--md-b3</td><td class="val" data-v-247f7c56>default + --md-shift</td><td data-v-247f7c56>Markdown ramp (headings / body / secondary / code); .text-md-* classes</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--ui-font-size / --content-font-size</td><td class="val" data-v-247f7c56>var(--ui-b2) / var(--md-b1)</td><td data-v-247f7c56>legacy aliases kept on the ramp</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--code-font-size</td><td class="val" data-v-247f7c56>calc(var(--content-font-size) - 2px)</td><td data-v-247f7c56>standalone code surfaces (diff view, file preview, tool cards) — one step below body, 12px @ Medium; prose-embedded code stays on the --md-* ramp</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--text-xs / sm / base / lg / xl / 2xl</td><td class="val" data-v-247f7c56>c1 / b2−1 / b2 / t2 / t1 / t0</td><td data-v-247f7c56>legacy ramp, aliased into the scale</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--leading-tight/normal/prose/relaxed</td><td class="val" data-v-247f7c56>1.25 / 1.5 / 1.6 / 1.7</td><td data-v-247f7c56>headings / UI / chat prose / long text</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--weight-regular/option-label/medium/ui-strong</td><td class="val" data-v-247f7c56>400 / 475 / 500 / 525</td><td data-v-247f7c56>body / settings labels / emphasis / compact UI emphasis</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--weight-section-label</td><td class="val" data-v-247f7c56>600</td><td data-v-247f7c56>sidebar section labels</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Icon size</h4><p data-v-247f7c56>Icons use three size tokens uniformly. The global <code data-v-247f7c56>.p-ic</code> default is 16px (<code data-v-247f7c56>--p-ic-md</code>); components pick as needed, and random pixel sizes are forbidden.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-ic-sm</td><td class="val" data-v-247f7c56>14px</td><td data-v-247f7c56>small button, badge, menu item, inline link icon</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-ic-md</td><td class="val" data-v-247f7c56>16px</td><td data-v-247f7c56>default (button, icon button, toolbar)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-ic-lg</td><td class="val" data-v-247f7c56>20px</td><td data-v-247f7c56>Toast status icon, empty-state illustration</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Icon</h4><p data-v-247f7c56>Icons always come from the centralized registry <code data-v-247f7c56>lib/icons.ts</code>: in templates use the <code data-v-247f7c56><Icon name size /></code> component (<code data-v-247f7c56>components/ui/Icon.vue</code>); for <code data-v-247f7c56>v-html</code> contexts (such as a tool glyph) use <code data-v-247f7c56>iconSvg(name, size)</code>. <b data-v-247f7c56>Do not hand-write <code data-v-247f7c56><svg></code></b> — the <code data-v-247f7c56>scripts/check-style.mjs</code> <code data-v-247f7c56>icon-from-registry</code> rule flags stray SVGs. Every glyph shares the 24×24 source grid and <code data-v-247f7c56>currentColor</code> (colour follows text); size uses the three tokens below, and only icons imported in <code data-v-247f7c56>lib/icons.ts</code> are bundled by <a href="https://github.com/unplugin/unplugin-icons" data-v-247f7c56>unplugin-icons</a> at build time. Three collections feed the registry, in this order of preference: <b data-v-247f7c56><code data-v-247f7c56>~icons/kimi/*</code></b> — Kimi Design System icons (24×24 outlined, 1.8px stroke), local SVGs under <code data-v-247f7c56>src/icons/kimi/</code> registered as a custom collection in the Vite config, used whenever a Kimi glyph exists for the intent; <b data-v-247f7c56><code data-v-247f7c56>~icons/tabler/*</code></b> — Tabler Icons (MIT), for the few gaps it uniquely covers (today: the right-panel toggle); and <b data-v-247f7c56><code data-v-247f7c56>~icons/ri/*</code></b> — <a href="https://remixicon.com/" data-v-247f7c56>Remix Icon</a> (Apache-2.0), for the remaining intents the Kimi set does not cover yet. A few glyphs are filed under their intent rather than the upstream asset name (see the <code data-v-247f7c56>lib/icons.ts</code> header). When an icon is missing, prefer a glyph from the Kimi icon set: copy the SVG into <code data-v-247f7c56>src/icons/kimi/</code> (kebab-case name, monochrome <code data-v-247f7c56>currentColor</code>) and register it — two static imports (component + <code data-v-247f7c56>?raw</code> string) plus one entry in <code data-v-247f7c56>ICONS</code>; reach for Remix only when no Kimi glyph fits, and never draw paths in a component.</p><h4 class="mini" data-v-247f7c56>Size scale</h4>`,49)),t("div",W,[t("div",P,[(n(),l("svg",U,[...a[1]||(a[1]=[t("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),a[2]||(a[2]=e("sm · 14",-1))]),t("div",F,[(n(),l("svg",j,[...a[3]||(a[3]=[t("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),a[4]||(a[4]=e("md · 16",-1))]),t("div",G,[(n(),l("svg",K,[...a[5]||(a[5]=[t("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"},null,-1)])])),a[6]||(a[6]=e("lg · 20",-1))])]),a[8]||(a[8]=t("h4",{class:"mini"},"Icon library",-1)),a[9]||(a[9]=t("p",null,[e("Currently registered icons, grouped by purpose. The display order and grouping are defined by "),t("code",null,"ICON_GROUPS"),e(" in "),t("code",null,"lib/icons.ts"),e(" (a hand-maintained array covering the same icon names), and this catalog is rendered directly from that array so the registry and the document never drift.")],-1)),t("div",J,[(n(!0),l(g,null,k(d(I),([r,v])=>(n(),l(g,{key:r},[t("div",Y,x(r),1),(n(!0),l(g,null,k(v,i=>(n(),l("div",{key:i,class:"icon-cell"},[s(d(o),{name:i},null,8,["name"]),t("span",Q,x(i),1)]))),128))],64))),128))]),a[10]||(a[10]=c('<p data-v-247f7c56>Do not use emoji as functional icons. The Kimi brand mark (the robot mascot logo) is a brand asset and is not part of this icon system.</p><p data-v-247f7c56>A few <b data-v-247f7c56>special graphics</b> are not in the registry; each has a dedicated component maintained in one place, and must not be copied by hand: <code data-v-247f7c56><ContextRing :pct /></code> (the Composer context progress ring, data-driven), <code data-v-247f7c56><AuthStateIcon kind /></code> (the success / expired / error colored illustrations in the login flow), <code data-v-247f7c56><Spinner /></code> (loading state). Status dots (such as in the Provider list) always use CSS dots (<code data-v-247f7c56>border-radius:50%</code>), not SVG. The <code data-v-247f7c56>scripts/check-style.mjs</code> <code data-v-247f7c56>icon-from-registry</code> rule exempts the above and the brand mark; all other hand-written <code data-v-247f7c56><svg></code> is flagged.</p><h3 class="sub" data-v-247f7c56>Spacing</h3><p data-v-247f7c56>A 4px base grid. All spacing, gaps, and padding inside and outside components come from this scale — no arbitrary pixels.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-247f7c56><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:4px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-1 · 4</div><div class="space-use" data-v-247f7c56>icon gap, badge padding</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:6px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-1-5 · 6</div><div class="space-use" data-v-247f7c56>workbar pill icon ↔ label</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:8px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-2 · 8</div><div class="space-use" data-v-247f7c56>control gap, small padding</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:12px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-3 · 12</div><div class="space-use" data-v-247f7c56>button padding, form-item gap</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:16px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-4 · 16</div><div class="space-use" data-v-247f7c56>card padding, grid gap</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:20px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-5 · 20</div><div class="space-use" data-v-247f7c56>dialog padding</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:24px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-6 · 24</div><div class="space-use" data-v-247f7c56>section gap</div></div><div class="space-row" data-v-247f7c56><div class="space-bar" style="width:32px;" data-v-247f7c56></div><div class="space-meta" data-v-247f7c56>--space-8 · 32</div><div class="space-use" data-v-247f7c56>large section gap</div></div></div><h4 class="mini" data-v-247f7c56>Dense list (sidebar / file tree)</h4><p data-v-247f7c56>High-density navigation lists like the sidebar share one rhythm, all on the 4px grid: <b data-v-247f7c56>in-row vertical padding</b> <code data-v-247f7c56>--space-1</code> (4px), <b data-v-247f7c56>no margin between rows</b> (the hover pill provides the separation); <b data-v-247f7c56>section gap</b> (between logo / search / action buttons / group title / list) uniformly <code data-v-247f7c56>--space-2</code> (8px); <b data-v-247f7c56>between groups</b> <code data-v-247f7c56>--space-2</code>; the brand header is slightly looser at the top (<code data-v-247f7c56>--space-3</code>). When building similar lists, reuse this scale — do not hand-write 1/6/7/10px.</p><h3 class="sub" data-v-247f7c56>Radius</h3><p data-v-247f7c56>Merge the existing 14 values <b data-v-247f7c56>into the nearest</b> of 7 scale steps. Rule: the component type determines the radius, not the author's feel. The Composer shell is the sole product-specific exception: its 32px radius pairs with <code data-v-247f7c56>superellipse(1.5)</code> so the flatter curve stays visually concentric with its controls.</p><div class="radius-grid" data-v-247f7c56><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:4px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>xs · 4</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:6px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>sm · 6</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:8px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>md · 8</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:12px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>lg · 12</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:16px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>xl · 16</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:20px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>2xl · 20</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:32px;corner-shape:superellipse(1.5);" data-v-247f7c56></div><span class="rl" data-v-247f7c56>composer · 32 / 1.5</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border-radius:999px;" data-v-247f7c56></div><span class="rl" data-v-247f7c56>full · 999</span></div></div><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th><th data-v-247f7c56>Merged from</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-xs</td><td class="val" data-v-247f7c56>4px</td><td data-v-247f7c56>small badge, inline tag</td><td class="val" data-v-247f7c56>2/3/4px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-sm</td><td class="val" data-v-247f7c56>6px</td><td data-v-247f7c56>small button, icon button, menu item</td><td class="val" data-v-247f7c56>5/6px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-md</td><td class="val" data-v-247f7c56>8px</td><td data-v-247f7c56>button, input, badge, card</td><td class="val" data-v-247f7c56>7/8/9px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-lg</td><td class="val" data-v-247f7c56>12px</td><td data-v-247f7c56>menu, toast, bubble, floating card</td><td class="val" data-v-247f7c56>10/12px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-xl</td><td class="val" data-v-247f7c56>16px</td><td data-v-247f7c56>container baseline: dialogs, settings cards, sheets, work panel</td><td class="val" data-v-247f7c56>13/16px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-2xl</td><td class="val" data-v-247f7c56>20px</td><td data-v-247f7c56>workspace attachment card bottom (<code data-v-247f7c56>0 0 2xl 2xl</code>) tucked under the composer</td><td class="val" data-v-247f7c56>18/20px →</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-composer</td><td class="val" data-v-247f7c56>32px</td><td data-v-247f7c56>Composer shell, with <code data-v-247f7c56>--corner-shape-composer</code></td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-menu-row</td><td class="val" data-v-247f7c56>var(--radius-sm)</td><td data-v-247f7c56>Menu rows inset 6px inside the plain <code data-v-247f7c56>--radius-lg</code> menu frame (concentric: 12px − 6px hug)</td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-menu-item</td><td class="val" data-v-247f7c56>calc(--radius-lg − --menu-pad − --p-hairline)</td><td data-v-247f7c56>Items of the §03 dropdown Menu — concentric with the frame: 12px − the 3.5px panel inset − the 0.5px hairline = 8px</td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-select-option</td><td class="val" data-v-247f7c56>calc(--radius-md − --space-1 − --p-hairline)</td><td data-v-247f7c56>Options of the §03 Select listbox family (Select, SecondaryModelPicker) — concentric: 8px frame − 4px pad − hairline = 3.5px</td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-dropdown-row</td><td class="val" data-v-247f7c56>calc(--radius-lg − --space-1 − --p-hairline)</td><td data-v-247f7c56>Rows of the composer dropdowns (model / permission) and the workspace picker — concentric: 12px frame − 4px pad − hairline = 7.5px</td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-window</td><td class="val" data-v-247f7c56>14px</td><td data-v-247f7c56>macOS hidden-titlebar window corner (measured on macOS 26 Tahoe) — referenced only through calc(), never directly</td><td class="val" data-v-247f7c56>platform constant</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-window-chip</td><td class="val" data-v-247f7c56>calc(--radius-window − --space-2)</td><td data-v-247f7c56>Sidebar footer chip's bottom-left corner on macOS desktop — concentric with the window corner (14px − the footer's 8px inset = 6px, exactly <code data-v-247f7c56>--radius-sm</code>)</td><td class="val" data-v-247f7c56>product-specific</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--radius-full</td><td class="val" data-v-247f7c56>999px</td><td data-v-247f7c56>pill badge, avatar, send button</td><td class="val" data-v-247f7c56>999px / 50%</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Elevation & z-index</h3><p data-v-247f7c56>Shadows express only "elevation", never decoration (no colored glow). z-index is unified into a scale, eradicating <code data-v-247f7c56>9999</code>-style one-upping.</p><div class="panel panel-pad" style="margin:16px 0;" data-v-247f7c56><div class="radius-grid" style="align-items:stretch;" data-v-247f7c56><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border:none;background:#fff;box-shadow:0 1px 2px rgba(16,24,40,.05),0 1px 3px rgba(16,24,40,.06);" data-v-247f7c56></div><span class="rl" data-v-247f7c56>sm · dropdown menu / sticky</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border:none;background:#fff;box-shadow:0 4px 12px rgba(16,24,40,.07),0 2px 4px rgba(16,24,40,.05);" data-v-247f7c56></div><span class="rl" data-v-247f7c56>md · Toast</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border:none;background:#fff;box-shadow:0 12px 32px rgba(16,24,40,.12),0 4px 10px rgba(16,24,40,.08);" data-v-247f7c56></div><span class="rl" data-v-247f7c56>lg · overlay (reserved)</span></div><div class="radius-item" data-v-247f7c56><div class="radius-box" style="border:none;background:#fff;box-shadow:0 24px 64px rgba(16,24,40,.18),0 8px 20px rgba(16,24,40,.10);" data-v-247f7c56></div><span class="rl" data-v-247f7c56>xl · dialog</span></div></div></div><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Z-index Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-base</td><td class="val" data-v-247f7c56>0</td><td data-v-247f7c56>normal flow</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-raised</td><td class="val" data-v-247f7c56>1</td><td data-v-247f7c56>in-component local stacking (menu scroll thumbs, strip badges, floating pills) — never a global layer</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-sticky</td><td class="val" data-v-247f7c56>100</td><td data-v-247f7c56>sticky header / sidebar</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-dropdown</td><td class="val" data-v-247f7c56>200</td><td data-v-247f7c56>dropdown menu</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-overlay</td><td class="val" data-v-247f7c56>300</td><td data-v-247f7c56>overlay / bottom Sheet</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-modal</td><td class="val" data-v-247f7c56>400</td><td data-v-247f7c56>dialog — sibling overlays tie-break by DOM order, so the global confirm (ConfirmDialogHost) mounts on demand to always land last / on top</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-modal-dropdown</td><td class="val" data-v-247f7c56>500</td><td data-v-247f7c56>menus / popovers that open above a modal dialog (teleported to <body>, e.g. the settings SecondaryModelPicker cascade)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-toast</td><td class="val" data-v-247f7c56>600</td><td data-v-247f7c56>toast</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-tooltip</td><td class="val" data-v-247f7c56>650</td><td data-v-247f7c56>tooltip bubble — transient and pointer-events none, so it sits above everything (dialogs, toasts) to stay visible anywhere</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--z-max</td><td class="val" data-v-247f7c56>9999</td><td data-v-247f7c56>reserved: only this tier for extreme fallback</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Motion</h3><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--ease-out</td><td class="val" data-v-247f7c56>cubic-bezier(0.16, 1, 0.3, 1)</td><td data-v-247f7c56>enter, hover, expand</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--ease-in-out</td><td class="val" data-v-247f7c56>cubic-bezier(0.4, 0, 0.2, 1)</td><td data-v-247f7c56>panel width, layout changes</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-fast</td><td class="val" data-v-247f7c56>120ms</td><td data-v-247f7c56>press, focus</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-base</td><td class="val" data-v-247f7c56>160ms</td><td data-v-247f7c56>hover, show/hide</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-slow</td><td class="val" data-v-247f7c56>260ms</td><td data-v-247f7c56>dialog, Sheet, layout</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-hover-intent</td><td class="val" data-v-247f7c56>250ms</td><td data-v-247f7c56>hover-intent reveal gate (TOC rail)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-spin</td><td class="val" data-v-247f7c56>700ms</td><td data-v-247f7c56>spinner rotation period (mention-tip probe spinner)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--duration-flash</td><td class="val" data-v-247f7c56>1200ms</td><td data-v-247f7c56>one-shot attention flashes (search locate, provider-row added) — a highlight timeout, past the show/hide ramp on purpose</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--anim-rive-spin</td><td class="val" data-v-247f7c56>416.7ms</td><td data-v-247f7c56>new-chat / folder-plus icon: plus spin on hover</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--anim-leftbar</td><td class="val" data-v-247f7c56>533.3ms</td><td data-v-247f7c56>sidebar toggle icon: arrow fly-in on hover</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--anim-leftbar-shrink</td><td class="val" data-v-247f7c56>200ms</td><td data-v-247f7c56>sidebar toggle icon: divider shrink on hover</td></tr></tbody></table><p data-v-247f7c56>The <code data-v-247f7c56>--anim-*</code> lengths are track timings ported verbatim from the designer's Rive exports, so they sit outside the <code data-v-247f7c56>--duration-*</code> ramp on purpose — retiming the ramp must not distort them. Their interpolation stays <code data-v-247f7c56>linear</code> because the easing is already baked into the dense keyframe stops; a token easing would double-apply. Three hover tracks use them today: the sidebar toggle shrinks its divider to half height while an arrow flies in and settles (the expand variant mirrors the track from the left), and the new-chat / folder-plus pluses do one bouncy spin. Each track is keyed to an id inside its own glyph (<code data-v-247f7c56>#bar-divider</code>, <code data-v-247f7c56>#bar-arrow</code> / <code data-v-247f7c56>#bar-arrow-expand</code>, <code data-v-247f7c56>#p1</code>, <code data-v-247f7c56>#af-p1</code>) so every instance of the icon animates, and all revert on mouse-out. They still fall under the global reduced-motion switch below.</p><h4 class="mini" data-v-247f7c56>Reduced motion</h4><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56> Under <code data-v-247f7c56>@media (prefers-reduced-motion: reduce)</code>, all animation and transition durations drop to about <code data-v-247f7c56>0.001ms</code> (effectively off), and the chat working indicator's mascot renders its static fallback instead of the Rive loop. Components should not check this individually; it is handled uniformly in the global styles. The switch clears durations, not <code data-v-247f7c56>transition-delay</code>: a hover-intent gate (the conversation TOC's 250ms reveal) decides <i data-v-247f7c56>whether</i> hidden content appears, and clearing it would make pointer fly-bys strobe content for reduced-motion users. </div></div><h3 class="sub" data-v-247f7c56>Layout & breakpoints</h3><p data-v-247f7c56>Layout sizes and responsive breakpoints are tokenized too: sidebar width, content reading-column width, and two global breakpoints. Components should not hard-code pixels.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-sidebar-w</td><td class="val" data-v-247f7c56>264px</td><td data-v-247f7c56>left session sidebar width</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-content-max</td><td class="val" data-v-247f7c56>760px</td><td data-v-247f7c56>chat reading-column max width (regular chat prose)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-content-wide</td><td class="val" data-v-247f7c56>920px</td><td data-v-247f7c56>wide content (settings / panel)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-table-max</td><td class="val" data-v-247f7c56>1040px</td><td data-v-247f7c56>desktop wide-table max width (see §04)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-table-cell-max</td><td class="val" data-v-247f7c56>700px</td><td data-v-247f7c56>max width of a single table column; longer cell content wraps (see §04)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-bubble-max</td><td class="val" data-v-247f7c56>78%</td><td data-v-247f7c56>right-aligned chat column cap — user bubble, cron notice, task-notification notice (see §04)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-bp-sm</td><td class="val" data-v-247f7c56>640px</td><td data-v-247f7c56>mobile / desktop boundary</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-bp-md</td><td class="val" data-v-247f7c56>980px</td><td data-v-247f7c56>narrow / wide screen boundary</td></tr></tbody></table><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56> At ≤640px: dialogs become bottom Sheets, the sidebar collapses into an expandable drawer, and Composer toolbar controls are allowed to wrap. </div></div>',24))]),t("section",X,[a[32]||(a[32]=c(`<div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>03</span><h2 class="sec-title" data-v-247f7c56>Primitives</h2></div><p class="sec-desc" data-v-247f7c56> Component primitives are the "smallest correct units" of the site UI. Each primitive exposes variants along only two dimensions — <code data-v-247f7c56>variant</code> / <code data-v-247f7c56>size</code> — with appearance driven by tokens, so it naturally supports light / dark mode and customizable theme colors. </p><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56> For every interactive primitive, the <b data-v-247f7c56>keyboard behavior, focus, and ARIA contract are in §08 Accessibility</b>. New primitives must ship with a keyboard model — mouse-only interaction is not enough. </div></div><h3 class="sub" data-v-247f7c56>Component selection guide</h3><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Scenario</th><th data-v-247f7c56>Use</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td data-v-247f7c56>Primary action (submit / confirm)</td><td data-v-247f7c56><code data-v-247f7c56>Button variant=primary</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Secondary action / cancel</td><td data-v-247f7c56><code data-v-247f7c56>Button secondary</code> / <code data-v-247f7c56>ghost</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Destructive action (delete / abort)</td><td data-v-247f7c56><code data-v-247f7c56>Button danger</code> / <code data-v-247f7c56>danger-soft</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Status marker</td><td data-v-247f7c56><code data-v-247f7c56>Badge</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Toolbar filter / model switch</td><td data-v-247f7c56><code data-v-247f7c56>Pill</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>2–5 mutually exclusive options</td><td data-v-247f7c56><code data-v-247f7c56>SegmentedControl</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Top tabs</td><td data-v-247f7c56><code data-v-247f7c56>Tabs</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Switch / multi-select</td><td data-v-247f7c56><code data-v-247f7c56>Switch</code> / <code data-v-247f7c56>Checkbox</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Scrollable regions with overlay controls</td><td data-v-247f7c56><code data-v-247f7c56>ScrollArea</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Floating content card / list action menu</td><td data-v-247f7c56><code data-v-247f7c56>Card</code> / <code data-v-247f7c56>Menu</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Inline notice / global toast</td><td data-v-247f7c56><code data-v-247f7c56>Banner</code> / <code data-v-247f7c56>Toast</code></td></tr><tr data-v-247f7c56><td data-v-247f7c56>Dialog / confirmation · bottom panel (mobile)</td><td data-v-247f7c56><code data-v-247f7c56>Dialog</code> / <code data-v-247f7c56>Sheet</code></td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Button</h3><p data-v-247f7c56>6 semantic variants × 3 sizes. The primary action <code data-v-247f7c56>primary</code> takes its color from the current theme color (§05 can switch between the blue and black families). Radius uses <code data-v-247f7c56>--radius-md</code> uniformly (small size <code data-v-247f7c56>--radius-sm</code>), weight 600, with a visible focus ring. The <code data-v-247f7c56>text</code> variant is the exception to the box: a chromeless inline action — underlined muted text, sized and weighted by its context — for quiet fallbacks such as a copy-link next to a muted label. Use it wherever a native link-styled button would tempt you; never hand-roll one.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Variant matrix <span class="tag spec" data-v-247f7c56>light</span></span><span class="sactions" data-v-247f7c56><span class="tab on" data-v-247f7c56>preview</span></span></div><div class="stage p col" data-v-247f7c56><span class="stage-label" data-v-247f7c56>medium · default</span><div class="demo-row" data-v-247f7c56><button class="p-btn primary" data-v-247f7c56>Primary action</button><button class="p-btn secondary" data-v-247f7c56>Secondary action</button><button class="p-btn ghost" data-v-247f7c56>Ghost button</button><button class="p-btn danger-soft" data-v-247f7c56>Destructive (soft)</button><button class="p-btn danger" data-v-247f7c56>Destructive action</button><span class="demo-inline-text" data-v-247f7c56>Didn't open? <button class="p-btn text" data-v-247f7c56>Copy link</button></span></div><span class="stage-label" data-v-247f7c56>small</span><div class="demo-row" data-v-247f7c56><button class="p-btn primary sm" data-v-247f7c56>Confirm</button><button class="p-btn secondary sm" data-v-247f7c56>Cancel</button><button class="p-btn ghost sm" data-v-247f7c56>More</button></div><span class="stage-label" data-v-247f7c56>With icon / state</span><div class="demo-row" data-v-247f7c56><button class="p-btn primary" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-247f7c56></path></svg>New chat</button><button class="p-btn secondary" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg>Copied</button><button class="p-btn primary disabled" data-v-247f7c56>Loading…</button></div></div></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Dark skin <span class="tag spec" data-v-247f7c56>dark</span></span></div><div class="stage dark p col" data-p="dark" data-v-247f7c56><div class="demo-row" data-v-247f7c56><button class="p-btn primary" data-v-247f7c56>Primary action</button><button class="p-btn secondary" data-v-247f7c56>Secondary action</button><button class="p-btn ghost" data-v-247f7c56>Ghost button</button><button class="p-btn danger" data-v-247f7c56>Destructive action</button></div></div></div><h4 class="mini" data-v-247f7c56>API</h4><div class="code" data-v-247f7c56><div class="code-bar" data-v-247f7c56><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="fn" data-v-247f7c56>Button.vue · usage</span></div><pre data-v-247f7c56><span class="k" data-v-247f7c56><Button</span> <span class="p" data-v-247f7c56>variant</span>=<span class="s" data-v-247f7c56>"primary"</span> <span class="p" data-v-247f7c56>size</span>=<span class="s" data-v-247f7c56>"md"</span> <span class="p" data-v-247f7c56>:loading</span>=<span class="s" data-v-247f7c56>"submitting"</span><span class="k" data-v-247f7c56>></span>Save<span class="k" data-v-247f7c56></Button></span> - <span class="c" data-v-247f7c56>// variant: primary | secondary | ghost | danger | danger-soft | text</span> - <span class="c" data-v-247f7c56>// size: sm | md | lg</span></pre></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>States</span></div><div class="stage p" data-v-247f7c56><div class="demo-row" data-v-247f7c56><button class="p-btn primary" disabled style="opacity:.5;cursor:not-allowed;" data-v-247f7c56>Disabled primary</button><button class="p-btn primary" data-v-247f7c56><svg class="p-spinner sm" viewBox="0 0 24 24" data-v-247f7c56><circle class="track" cx="12" cy="12" r="9" data-v-247f7c56></circle><circle class="arc" cx="12" cy="12" r="9" data-v-247f7c56></circle></svg>Submitting</button><button class="p-btn danger" disabled style="opacity:.5;cursor:not-allowed;" data-v-247f7c56>Disabled danger</button></div></div></div><h3 class="sub" data-v-247f7c56>IconButton</h3><p data-v-247f7c56>Unified into three sizes — 26 / 32 / 44px — with the neutral <code data-v-247f7c56>--color-hover</code> wash on hover and a visible focus ring. Replaces the ad-hoc icon + click areas scattered across components today.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>IconButton</span></div><div class="stage p" data-v-247f7c56><button class="p-icon-btn" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-247f7c56></path></svg></button><button class="p-icon-btn" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-247f7c56></path></svg></button><button class="p-icon-btn" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-247f7c56></path></svg></button><button class="p-icon-btn sm" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z" data-v-247f7c56></path></svg></button><button class="p-icon-btn sm" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg></button></div></div><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56> The desktop IconButton comes in <code data-v-247f7c56>sm</code> 26 / <code data-v-247f7c56>md</code> 32; on touch devices the tap target should be ≥ 44px, so use <code data-v-247f7c56>lg</code> 44px, satisfying the §01 accessibility principle (the mobile three-piece set uses <code data-v-247f7c56>lg</code>). Icon-only buttons must also name themselves on hover: pass <code data-v-247f7c56>tooltip</code> (usually the same text as <code data-v-247f7c56>label</code> — <code data-v-247f7c56>label</code> alone only sets the aria-label); bare icon <code data-v-247f7c56><button></code>/<code data-v-247f7c56><a></code> triggers wrap the <code data-v-247f7c56>Tooltip</code> component directly. </div></div><h3 class="sub" data-v-247f7c56>Badge · Chip · Pill</h3><p data-v-247f7c56>Collapsed into two kinds: <b data-v-247f7c56>Badge</b> (status badge, with an optional status dot) and <b data-v-247f7c56>Pill</b> (the clickable pill in the composer toolbar). Radius, font size, and padding are all unified.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Badge · status badge</span></div><div class="stage p col" data-v-247f7c56><span class="stage-label" data-v-247f7c56>Semantic variants</span><div class="demo-row" data-v-247f7c56><span class="p-badge neutral" data-v-247f7c56><span class="bd" data-v-247f7c56></span>pending</span><span class="p-badge info" data-v-247f7c56><span class="bd" data-v-247f7c56></span>running</span><span class="p-badge success" data-v-247f7c56><span class="bd" data-v-247f7c56></span>completed</span><span class="p-badge warning" data-v-247f7c56><span class="bd" data-v-247f7c56></span>needs confirmation</span><span class="p-badge danger" data-v-247f7c56><span class="bd" data-v-247f7c56></span>failed</span><span class="p-badge solid" data-v-247f7c56>KIMI</span></div><span class="stage-label" data-v-247f7c56>With icon / small size</span><div class="demo-row" data-v-247f7c56><span class="p-badge info" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M4 3h16a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1m1 2v14h14V5z" data-v-247f7c56></path></svg>plan</span><span class="p-badge success sm" data-v-247f7c56><span class="bd" data-v-247f7c56></span>passed</span><span class="p-badge neutral sm" data-v-247f7c56>read-only</span></div></div></div>`,19)),t("div",Z,[a[14]||(a[14]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Pill · toolbar pill (composer)")],-1)),t("div",$,[a[12]||(a[12]=c('<span class="p-pill" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z" data-v-247f7c56></path></svg><span class="pp-strong" data-v-247f7c56>kimi-k2</span><span class="pp-sub" data-v-247f7c56>· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-247f7c56></path></svg></span>',1)),t("span",_,[s(d(o),{name:"shield-question",size:"sm"}),a[11]||(a[11]=e("yolo",-1))]),a[13]||(a[13]=t("span",{class:"p-pill"},[t("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[t("path",{fill:"currentColor",d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m1-8h4v2h-6V7h2z"})]),e("12k / 200k")],-1))])]),a[33]||(a[33]=c('<h3 class="sub" data-v-247f7c56>Kbd · keyboard shortcut</h3><p data-v-247f7c56><b data-v-247f7c56>Kbd</b> renders a shortcut as keycaps — one block per key, never inline text like <code data-v-247f7c56>(⌘K)</code>. Caps are 18px tall (Badge sm rhythm): transparent ground with a 0.5px hairline edge, 11px <code data-v-247f7c56>--font-kbd</code> (Inter + system-ui), text colour inherited from the row that carries it — the cap has no fill or colour of its own, so it follows its context (bright inside the accent-ringed recording box, quiet in a hint row). Typical placement: pushed to the row's trailing edge, opposite the label (e.g. the sidebar search row), and inside dialog navigation hints.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Kbd · keycaps</span></div><div class="stage p" data-v-247f7c56><span class="p-kbd" data-v-247f7c56><kbd data-v-247f7c56>⌘</kbd><kbd data-v-247f7c56>K</kbd></span><span class="p-kbd" data-v-247f7c56><kbd data-v-247f7c56>Ctrl</kbd><kbd data-v-247f7c56>K</kbd></span><span class="p-kbd" data-v-247f7c56><kbd data-v-247f7c56>⌘</kbd><kbd data-v-247f7c56>⇧</kbd><kbd data-v-247f7c56>P</kbd></span></div></div><h3 class="sub" data-v-247f7c56>Card / Surface</h3><p data-v-247f7c56>All cards across the site share <b data-v-247f7c56>one structure</b> — <code data-v-247f7c56>head / body / foot</code> — and come in two tiers by visual weight:</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>Operation card</b> —— composite "process" content such as the Swarm overview. (Individual tool calls are NOT cards anymore: they render as quiet borderless lines, see §04.) Flat shell: <code data-v-247f7c56>0.5px</code> hairline, <code data-v-247f7c56>--radius-md</code>, no shadow. The head is compact mono with no fill, low weight by default, not competing with the conversation.</li><li data-v-247f7c56><b data-v-247f7c56>Attention card</b> —— content that needs a user decision, such as Question / Approval. A floating neutral card: white raised surface, <code data-v-247f7c56>--radius-lg</code>, a faint popover shadow (<code data-v-247f7c56>--shadow-menu</code>), a plain dark title head, and a hairline footer whose actions read in number-key order (chips on the buttons) leading to one solid primary action. No semantic color band.</li><li data-v-247f7c56><b data-v-247f7c56>Action card</b> —— the only interactive card pattern (<code data-v-247f7c56>ActionCard.vue</code> in app-ui): one clickable row for pick-one choices (the OAuth login entries, the custom-provider entry). Leading visual slot, title with an optional trailing status <code data-v-247f7c56>Badge</code>, second-line hint, fixed chevron; hover and the focus ring share the site language, and <code data-v-247f7c56>disabled</code> dims + disarms it (the login entries use it while the daemon-support probe is in flight). Consumers never hand-roll a card-shaped <code data-v-247f7c56><button></code>.</li></ul><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Operation card · compact mono head (no fill)</span></div><div class="stage p col" data-v-247f7c56><div class="p-card" style="max-width:460px;" data-v-247f7c56><div class="p-card-head" data-v-247f7c56><span class="p-card-title" data-v-247f7c56>read_file</span><span class="p-badge info sm" style="margin-left:auto;" data-v-247f7c56>session.ts</span></div><div class="p-card-body" data-v-247f7c56>The head uses mono + a neutral background to emphasize its "code / process" nature; the body uses sans for readability. Flat, radius-md, same shape as the Swarm composite card.</div></div></div></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Attention card · floating neutral surface (no color band)</span></div><div class="stage p col" data-v-247f7c56><div class="p-action" style="max-width:460px;" data-v-247f7c56><div class="p-action-head" data-v-247f7c56><span class="p-action-title" data-v-247f7c56>A decision needs your confirmation</span></div><div class="p-action-body" data-v-247f7c56>A floating neutral card — no color band. The raised surface, large radius and soft shadow lift it above the transcript; the head is a plain dark title, and the hairline footer lines up quiet text buttons leading to one solid primary action.</div><div class="p-action-foot" data-v-247f7c56><button class="p-btn ghost sm" data-v-247f7c56>Dismiss</button><button class="p-btn primary sm" data-v-247f7c56>Confirm</button></div></div></div></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Activity run · a summary row expands into the folded lines</span></div><div class="stage p col" data-v-247f7c56><div class="p-tool-group open" style="max-width:460px;" data-v-247f7c56><div class="p-tool-group-head" data-v-247f7c56><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tg-title" data-v-247f7c56>Read 2 files</span></div><div class="p-tool-row" data-v-247f7c56><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>session.ts</span><span class="tr-faint" data-v-247f7c56>src/auth</span><span class="tr-chip" data-v-247f7c56>34 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div><div class="p-tool-row" data-v-247f7c56><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>middleware.ts</span><span class="tr-faint" data-v-247f7c56>src/auth</span><span class="tr-chip" data-v-247f7c56>58 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div></div></div></div>',9)),t("div",aa,[a[19]||(a[19]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"ActionCard · clickable choice row (normal / disabled)")],-1)),t("div",ta,[s(d(T),{style:{"max-width":"460px"}},{leading:h(()=>[s(d(o),{name:"globe",size:"lg"})]),hint:h(()=>[...a[15]||(a[15]=[e("Sign in with your kimi.com account",-1)])]),default:h(()=>[a[16]||(a[16]=e(" Kimi Code ",-1))]),_:1}),s(d(T),{style:{"max-width":"460px"},disabled:""},{leading:h(()=>[s(d(o),{name:"bolt",size:"lg"})]),hint:h(()=>[...a[17]||(a[17]=[e("Bring your own API key for OpenAI-compatible and other services",-1)])]),default:h(()=>[a[18]||(a[18]=e(" Add a custom provider ",-1))]),_:1})])]),a[34]||(a[34]=c(`<ul class="clean check" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>One structure, two shells</b>: every card is <code data-v-247f7c56>head / body / foot</code>; operation cards are flat + 0.5px hairline + radius-md with no shadow, while the attention card is the single exception — raised surface, radius-lg and a soft shadow, because it floats above the transcript in place of the composer.</li><li data-v-247f7c56><b data-v-247f7c56>Differences are intentional</b>: operation cards keep a compact mono head; attention cards get a plain dark title head and footer actions.</li><li data-v-247f7c56><b data-v-247f7c56>Grouping</b>: consecutive activity (thinking + tool calls of any kind, cards included) folds into ONE activity-run row — a smart summary sentence that expands into the items in order; only text and successful media tools (inline media is the turn's output) stay out and break the run. Task notifications stay out too but NEVER break it — a mid-run notice defers and renders right after the run block (see §04).</li><li data-v-247f7c56><b data-v-247f7c56>Turn fold</b>: once an assistant turn settles, everything before its final text block (thinking, activity runs, interim text, standalone cards) folds into ONE bare "Worked Ns" row — no glyph, a faint one-line label + rotating chevron sharing the activity-run head's padding and hover language; while the turn streams the row stays hidden and the body forced open, and on settle the row appears and folds itself back. The span is the turn's elapsed time (daemon duration once settled, server message stamps for history; approval/question waits included by design), reading the generic "Work details" without any stamp. The final text — and anything after it, so trailing media / cards stay on screen — never folds; a text-only turn renders no row at all (see §04).</li><li data-v-247f7c56><b data-v-247f7c56>Status dots</b>: running (pulsing blue) / done (green) / failed (red), sharing one color vocabulary (see §04 tool calls).</li></ul><h3 class="sub" data-v-247f7c56>Input / Select / Textarea</h3><p data-v-247f7c56>Unified 38px height (32px small), <code data-v-247f7c56>--radius-md</code> radius, <code data-v-247f7c56>--color-surface-overlay</code> background, and a unified blue focus ring (<code data-v-247f7c56>0 0 0 3px accent-soft</code>). Select is a custom combobox and listbox, not a native <code data-v-247f7c56><select></code>; opening it centres the selected option in the scrollable menu. The listbox teleports to <code data-v-247f7c56><body></code> with <code data-v-247f7c56>position: fixed</code> — anchored to the trigger (opening toward the roomier side: flipping upward near the viewport bottom and shrinking its max-height to fit when neither side has room; re-anchoring on scroll/resize; closing when focus tabs away) on the <code data-v-247f7c56>--z-modal-dropdown</code> rung, so it floats above modal dialogs and no scrolling container can clip it; while it is open, scroll gestures outside the menu are swallowed so the surface behind it cannot scroll. Listbox options round at <code data-v-247f7c56>--radius-select-option</code>, concentric with the menu frame (<code data-v-247f7c56>--radius-md</code> − <code data-v-247f7c56>--space-1</code> pad − the 0.5px hairline = 3.5px).</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Form primitives</span></div><div class="stage p col" data-v-247f7c56><div class="demo-row" style="align-items:flex-start;" data-v-247f7c56><div class="p-field demo-grow" data-v-247f7c56><label class="p-label" data-v-247f7c56>Workspace name</label><input class="p-input" placeholder="e.g. frontend" data-v-247f7c56><span class="p-hint" data-v-247f7c56>Only letters, numbers, and hyphens are allowed.</span></div><div class="p-field demo-grow" data-v-247f7c56><label class="p-label" data-v-247f7c56>Model provider</label><button class="p-select" type="button" data-v-247f7c56>Anthropic</button></div></div><div class="p-field" data-v-247f7c56><label class="p-label" data-v-247f7c56>System prompt</label><textarea class="p-textarea" placeholder="Describe this Agent's role and boundaries…" data-v-247f7c56></textarea></div></div></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>States</span></div><div class="stage p col" data-v-247f7c56><div class="demo-row" style="align-items:flex-start;" data-v-247f7c56><div class="p-field demo-grow" data-v-247f7c56><label class="p-label" data-v-247f7c56>Workspace name</label><input class="p-input" value="my workspace!" style="border-color:var(--p-danger);" data-v-247f7c56><span class="p-field-error" data-v-247f7c56>Please enter a valid workspace name</span></div><div class="p-field demo-grow" data-v-247f7c56><label class="p-label" data-v-247f7c56>Display name</label><input class="p-input" value="frontend" data-v-247f7c56><span class="p-hint" data-v-247f7c56>Normal state · validation passed</span></div></div></div></div><h3 class="sub" data-v-247f7c56>Code / Diff</h3><p data-v-247f7c56><b data-v-247f7c56>Diff controls</b>: The non-selectable branch summary starts with a 14px branch icon, aligns to the panel header's 12px inset, uses 12px labels, and ends with a 0.5px hairline. List and tree choices use the 14px <code data-v-247f7c56>list</code> and <code data-v-247f7c56>tree-view</code> registry icons. Flat-list and tree-view paths use the UI font at 12px. Tree roots share the flat list's 14px content inset, then each depth advances by 12px and adds a grey indentation rule.</p><p data-v-247f7c56><b data-v-247f7c56>Diff empty state</b>: Centre the clean-workspace message in the available panel height and lead with a quiet 32px status icon.</p><p data-v-247f7c56><b data-v-247f7c56>Diff detail body</b>: the right-side diff detail reuses <code data-v-247f7c56>HighlightedCode</code> unframed (the panel owns the edge and scroll) — shiki highlighting with the language inferred from the file path, an old/new line-number gutter, hunk headers as a muted band, at the shared code size <code data-v-247f7c56>--code-font-size</code> (12px at Medium, one step below body text). The file preview's code body (text / JSON / HTML and Markdown source) renders through the same component with a per-row number gutter plus search-hit / jump-target row states.</p><p data-v-247f7c56>Inline code, code blocks, and diff contents use the monospace font (<code data-v-247f7c56>--p-font-mono</code>); diff change counts and branch summaries use the UI font. Code blocks have a filename title bar and a copy button; the action edge uses a compact 6px inset. Diffs use <code data-v-247f7c56>+</code> / <code data-v-247f7c56>-</code> row colors to express additions and deletions — additions use a success light background, deletions use a danger light background, with no gradients.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Code / Diff</span></div><div class="stage p col" data-v-247f7c56><span class="stage-label" data-v-247f7c56>inline code</span><div data-v-247f7c56>The server uses <code class="p-code-inline" data-v-247f7c56>jwt.verify(token)</code> to verify the signature, returning 401 on failure.</div><span class="stage-label" data-v-247f7c56>code block</span><div class="p-code-block" data-v-247f7c56><div class="p-code-block-head" data-v-247f7c56><span data-v-247f7c56>session.ts</span><button class="p-icon-btn sm" aria-label="Copy" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z" data-v-247f7c56></path></svg></button></div><pre data-v-247f7c56>import { verify } from './jwt'; - - export function auth(token: string) { - return verify(token, process.env.JWT_SECRET!); - }</pre></div><span class="stage-label" data-v-247f7c56>diff</span><div class="p-diff" data-v-247f7c56><div class="p-diff-head" data-v-247f7c56>session.ts · +3 -1</div><div class="p-diff-row" data-v-247f7c56><span class="pm" data-v-247f7c56></span><span class="p-diff-code" data-v-247f7c56>import { verify } from './jwt';</span></div><div class="p-diff-row del" data-v-247f7c56><span class="pm" data-v-247f7c56>-</span><span class="p-diff-code" data-v-247f7c56>const secret = 'dev-secret';</span></div><div class="p-diff-row add" data-v-247f7c56><span class="pm" data-v-247f7c56>+</span><span class="p-diff-code" data-v-247f7c56>const secret = process.env.JWT_SECRET!;</span></div><div class="p-diff-row" data-v-247f7c56><span class="pm" data-v-247f7c56></span><span class="p-diff-code" data-v-247f7c56>return verify(token, secret);</span></div></div></div></div><h3 class="sub" data-v-247f7c56>Dialog</h3><p data-v-247f7c56>One dialog primitive replaces 6 hand-written implementations: unified <code data-v-247f7c56>--radius-xl</code> radius, <code data-v-247f7c56>--shadow-xl</code> shadow, 20px head padding, right-aligned footer actions, and an IconButton close button.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Dialog primitive</span></div><div class="stage p col" style="align-items:center;" data-v-247f7c56><div class="p-dialog" data-v-247f7c56><div class="p-dialog-head" data-v-247f7c56><div data-v-247f7c56><div class="p-dialog-title" data-v-247f7c56>New chat</div><div class="p-dialog-desc" data-v-247f7c56>Create an independent Agent chat in the current workspace.</div></div><button class="p-icon-btn sm" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-247f7c56></path></svg></button></div><div class="p-dialog-body" data-v-247f7c56><div class="p-field" data-v-247f7c56><label class="p-label" data-v-247f7c56>Chat title (optional)</label><input class="p-input" placeholder="Generated automatically" data-v-247f7c56></div></div><div class="p-dialog-foot" data-v-247f7c56><button class="p-btn secondary" data-v-247f7c56>Cancel</button><button class="p-btn primary" data-v-247f7c56>Create</button></div></div></div></div><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>Size & height</b>: Dialog offers four widths — <code data-v-247f7c56>sm</code> 360 / <code data-v-247f7c56>md</code> 440 / <code data-v-247f7c56>lg</code> 640 / <code data-v-247f7c56>xl</code> 760 (<code data-v-247f7c56>--p-content-max</code>) — chosen by content weight; <code data-v-247f7c56>sm</code> is for quiet single-purpose dialogs (login, confirm). Height comes in two kinds: <code data-v-247f7c56>auto</code> (default, grows with content up to <code data-v-247f7c56>max-height</code>) and <code data-v-247f7c56>fixed</code> (constant height <code data-v-247f7c56>min(680px, 100vh - 64px)</code>, with overflow scrolled inside the body). At ≤640px every modal becomes a bottom-anchored full-width sheet (rounded top, slide-up, max height 86% of the shell's <code data-v-247f7c56>--app-height</code> so it shrinks with the software keyboard). <b data-v-247f7c56>Content / multi-tab dialogs</b> (settings, model picker, provider manager, folder browser) <b data-v-247f7c56>Content / multi-tab dialogs</b> (settings, model picker, provider manager, folder browser) always use <code data-v-247f7c56>fixed</code> so the frame size stays constant and doesn't jump when switching tabs or content length; short confirmation dialogs keep <code data-v-247f7c56>auto</code>. Selectable controls inside Settings use 0.5px hairlines. Its navigation stays transparent on the grouped canvas — separated from the content region by the 0.5px hairline (horizontal in the stacked mobile layout) — and uses 12px labels at weight 525 with 16px registry icons; the selected tab paints the same neutral <code data-v-247f7c56>--color-hover</code> wash as hover, with the label simply brightening to <code data-v-247f7c56>--color-text</code> — the Kimi app settings nav's recipe (<code data-v-247f7c56>.ss-nav-item--active</code> → <code data-v-247f7c56>Fills-F1</code>, no accent tint, no weight change); section captions use 16px UI text in <code data-v-247f7c56>--color-text</code>. Every setting row has a plain-language description; option labels use <code data-v-247f7c56>--color-text</code> at weight 475 with a 1px gap before that description. Chinese descriptions use “思考” and “计划模式” rather than the English terms; “skills” stays lowercase when it appears within a sentence. Every settings section puts its rows inside one rounded group with 0.5px dividers; the content region paints the flat <code data-v-247f7c56>--color-surface</code> so each group (<code data-v-247f7c56>--color-surface-raised</code>) reads one rung above it — never a sunken pit, which would sink the dialog's content below its chrome in dark. The font-size stepper is a compact 32px UI-font control with 12px values and custom minus and plus buttons. Its 52px desktop row centres the control with equal space above and below. Archived workspace headings reuse the sidebar’s <code data-v-247f7c56>folder-closed</code> registry icon, and Restore actions lead with the <code data-v-247f7c56>undo</code> icon. Archive counts use weight 500; timestamps and workspace paths use the UI font. </div></div><p data-v-247f7c56><b data-v-247f7c56>Dialog backdrop</b>: Use a restrained 28% neutral overlay so the workspace remains legible without competing with the modal.</p><p data-v-247f7c56><b data-v-247f7c56>Settings regions</b>: The settings title and close action belong to the right content region. The navigation is a separate full-height region that starts at the dialog's top edge, not content beneath a dialog-wide header.</p><p data-v-247f7c56><b data-v-247f7c56>Archived sessions</b>: Start with the localized page title. Do not add a repeated English kicker above it.</p><p data-v-247f7c56><b data-v-247f7c56>Settings interaction</b>: Notification labels and descriptions are not selectable; their switches remain fully interactive.</p><p data-v-247f7c56><b data-v-247f7c56>Conversation chrome</b>: Header labels are not selectable; the rename input remains selectable and editable. Branch names start with a 14px branch icon. The overflow trigger is a compact 24px control with a 14px icon. Below a 720px header container, hide the workspace prefix and give the conversation title the available width. On macOS desktop the header doubles as the window-drag region and interactive controls opt out with no-drag; while one of its menus or a dock work panel is open every window-drag strip (chat header, sidebar header, panel header) drops the drag region so an outside press anywhere reaches the page and dismisses the overlay (window dragging is simply paused).</p><p data-v-247f7c56><b data-v-247f7c56>Session search</b>: follows the §09 flush picker anatomy — a boxed Input under the head, and a result list that fills the body's available height and owns vertical scrolling.</p><p data-v-247f7c56><b data-v-247f7c56>Model picker</b>: follows the §09 flush picker anatomy; the provider filter remains horizontally scrollable without showing a persistent scrollbar. Only the model list scrolls; the shortcut bar remains pinned at the bottom.</p><h3 class="sub" data-v-247f7c56>Toast</h3><p data-v-247f7c56>Unified information architecture: status icon + title + description. The status color appears only on the icon, avoiding large colored areas that create visual noise. For an <b data-v-247f7c56>undoable action</b> there is a second, lighter form — the <b data-v-247f7c56>Action toast</b> (<code data-v-247f7c56>ActionToast.vue</code>): a pill floating top-center just below the 48px header, carrying a one-line sentence whose actions are plain inline <code data-v-247f7c56><button></code>s (styled accent by the component), plus close. Self-timed (default 8s, hover pauses); the parent re-keys to reset and wraps it in a <code data-v-247f7c56><Transition></code>. First used by session archive (Undo / Settings); warnings keep the bottom-right <code data-v-247f7c56>Toast</code> stack.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Toast</span></div><div class="stage p col" data-v-247f7c56><div class="p-toast success" data-v-247f7c56><span class="ti" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg></span><div data-v-247f7c56><div class="tt" data-v-247f7c56>Connected to server</div><div class="td" data-v-247f7c56>The local server is responding normally; you can start a new chat.</div></div></div><div class="p-toast warning" data-v-247f7c56><span class="ti" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z" data-v-247f7c56></path></svg></span><div data-v-247f7c56><div class="tt" data-v-247f7c56>Context usage 82%</div><div class="td" data-v-247f7c56>Consider running /compact to free up space.</div></div></div></div></div><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Action toast</span></div><div class="stage p col" data-v-247f7c56><div class="p-action-toast" data-v-247f7c56><button class="lk" data-v-247f7c56>Undo</button><span data-v-247f7c56>or view archived chats in</span><button class="lk" data-v-247f7c56>Settings</button><svg class="p-ic x" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path d="M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z" data-v-247f7c56></path></svg></div></div></div><h3 class="sub" data-v-247f7c56>Spinner</h3><p data-v-247f7c56>Loaders fall into two categories by scenario — <b data-v-247f7c56>do not mix them</b>:</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>Spinner (plain · SVG ring)</b> —— the default loader. Used for button loading, app startup (GlobalLoading), and general inline waits — "everything else".</li><li data-v-247f7c56><b data-v-247f7c56>WorkingIndicator (小蓝 mascot · brand signature)</b> —— used <b data-v-247f7c56>only</b> for the chat working state after a prompt is sent (the sending placeholder in ChatPane, the send → first-token loading in SideChatPanel). The label follows the phase: "Requesting…" until the assistant's reply starts, then "Working…".</li></ul><h4 class="mini" data-v-247f7c56>Spinner · plain loader (default)</h4>`,30)),t("div",ea,[a[23]||(a[23]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Spinner · common scenarios")],-1)),t("div",sa,[t("div",da,[a[22]||(a[22]=c('<svg class="p-spinner" viewBox="0 0 24 24" data-v-247f7c56><circle class="track" cx="12" cy="12" r="9" data-v-247f7c56></circle><circle class="arc" cx="12" cy="12" r="9" data-v-247f7c56></circle></svg><span class="p-thinking" data-v-247f7c56><svg class="p-spinner sm" viewBox="0 0 24 24" data-v-247f7c56><circle class="track" cx="12" cy="12" r="9" data-v-247f7c56></circle><circle class="arc" cx="12" cy="12" r="9" data-v-247f7c56></circle></svg>Loading…</span>',2)),t("button",oa,[(n(),l("svg",ca,[...a[20]||(a[20]=[t("circle",{class:"track",cx:"12",cy:"12",r:"9"},null,-1),t("circle",{class:"arc",cx:"12",cy:"12",r:"9"},null,-1)])])),a[21]||(a[21]=e("Submitting",-1))])])])]),a[35]||(a[35]=t("h4",{class:"mini"},"WorkingIndicator · 小蓝 mascot (only the chat working state)",-1)),t("div",ia,[a[25]||(a[25]=t("div",{class:"stage-bar"},[t("span",{class:"st"},[e("WorkingIndicator · chat working state only "),t("span",{class:"tag spec"},"signature")])],-1)),t("div",na,[a[24]||(a[24]=t("span",{class:"stage-label"},"Usage · only while the chat has an unfinished prompt",-1)),t("div",la,[s(S,{label:"Requesting…"}),s(S,{label:"Working…"})])])]),a[36]||(a[36]=c('<div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56>The chat working state is rendered uniformly by <code data-v-247f7c56>WorkingIndicator</code> — the 小蓝 mascot (<code data-v-247f7c56>KimiMascot</code>, the kimi.com avatar Rive asset, with a static SVG fallback under reduced motion or when the runtime fails) plus a phase label. All other loading states use the plain Spinner.</div></div><h3 class="sub" data-v-247f7c56>Link</h3><p data-v-247f7c56>Inline text link: the default is the accent color with no underline; on hover it shows an underline and darkens. File links inside inline code use a 1.5px underline offset so the line stays clear of the chip background. The <code data-v-247f7c56>.muted</code> variant uses the secondary text color. Used for in-text jumps, external links, "view all", and other lightweight actions.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Link · inline link</span></div><div class="stage p col" data-v-247f7c56><div class="demo-row" style="font-size:var(--p-font-size-base);color:var(--p-text);" data-v-247f7c56><span data-v-247f7c56>Read the full <a class="p-link" href="#" data-v-247f7c56>design token docs</a> before building.</span><a class="p-link" href="#" data-v-247f7c56>View on GitHub<svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z" data-v-247f7c56></path></svg></a><a class="p-link muted" href="#" data-v-247f7c56>View history</a></div></div></div><h3 class="sub" data-v-247f7c56>Menu / Dropdown</h3><p data-v-247f7c56>Desktop menus inset their items by <code data-v-247f7c56>--menu-pad</code> (3.5px, so the hairline plus inset lands exactly on the 4px grid), and item corners stay concentric with the frame at <code data-v-247f7c56>--radius-menu-item</code> (<code data-v-247f7c56>--radius-lg</code> − <code data-v-247f7c56>--menu-pad</code> − the 0.5px hairline = 8px — the item arc shares the panel's corner center instead of cutting across it). Standard items pad from the shared <code data-v-247f7c56>--menu-item-padding-block</code> × <code data-v-247f7c56>--menu-item-padding-inline</code> tokens (5px × 9px) with a 7px icon gap. Their three-layer neutral shadow stays below 4% opacity.</p><p data-v-247f7c56>Dropdown menu panel: frosted glass — the translucent <code data-v-247f7c56>--color-menu-bg</code> fill over a blurred, saturated page backdrop (<code data-v-247f7c56>--p-menu-backdrop</code>) — plus hairline + light shadow (<code data-v-247f7c56>--shadow-menu</code>, a three-layer neutral ramp). This is the one place glassmorphism is the design language rather than an exception (§06); every floating menu surface (Menu.vue, the Select listbox, composer dropdowns, slash/mention popups) uses the token pair, never ad-hoc blur values. Menu items support icons, the current (active) state, the danger state, and the disabled state, with separators grouping items. All menu actions use 13px labels at weight 475 with 16px leading icons; both share a 16px line box for vertical alignment. Menu timestamps use the UI font. On touch / mobile, use <code data-v-247f7c56>lg</code> (≥44px row height) while keeping the same type size. A dropdown menu pops in from its trigger corner — fade plus a slight 0.97 scale over <code data-v-247f7c56>--duration-base</code> (exit <code data-v-247f7c56>--duration-fast</code>), the composer model dropdown's motion language; the transform origin and the nudge direction follow the anchoring, including the upward flip near the viewport edge.</p><p data-v-247f7c56>Row states: hover uses the mode-aware <code data-v-247f7c56>--color-hover</code> wash (it lightens under dark, never darkens); a leading icon sits one rung below the label (<code data-v-247f7c56>--muted</code>), and on hover both label and icon step up to <code data-v-247f7c56>--color-text-strong</code>, the max foreground tier. Selection keeps the accent pair (<code data-v-247f7c56>--color-accent-soft</code> / <code data-v-247f7c56>--color-accent-hover</code>); danger keeps its own colour.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Menu · dropdown menu</span></div><div class="stage p col" style="align-items:flex-start;" data-v-247f7c56><div class="p-menu" data-v-247f7c56><div class="p-menu-item" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg>Open file</div><div class="p-menu-item active" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg>Selected item</div><div class="p-menu-item disabled" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M8.523 7.109l8.368 8.368a6 6 0 0 1-1.414 1.414L7.109 8.523A6 6 0 0 1 8.523 7.11" data-v-247f7c56></path></svg>Disabled item</div><div class="p-menu-sep" data-v-247f7c56></div><div class="p-menu-item danger" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 10.587l4.95-4.95l1.414 1.414l-4.95 4.95l4.95 4.95l-1.415 1.414l-4.95-4.95l-4.949 4.95l-1.414-1.415l4.95-4.95l-4.95-4.95L7.05 5.638z" data-v-247f7c56></path></svg>Delete chat</div></div></div></div><h3 class="sub" data-v-247f7c56>SegmentedControl</h3><p data-v-247f7c56>Mutually exclusive short option groups, commonly used for 2–5 option switches such as "light / dark / follow system" or the four font-scale steps. Options may include a 14px registry icon or a colour swatch. A single raised indicator with a soft shadow (no border — the edge stays clean) slides and resizes between options using the standard motion tokens. Three sizes: <code data-v-247f7c56>md</code> (default, settings pages), <code data-v-247f7c56>sm</code> (compact rows), and <code data-v-247f7c56>xs</code> (dense menus such as the composer model dropdown — 20px items, 12px labels).</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>SegmentedControl</span></div><div class="stage p col" data-v-247f7c56><div class="p-seg" data-v-247f7c56><span class="p-seg-item on" data-v-247f7c56>Light</span><span class="p-seg-item" data-v-247f7c56>Dark</span><span class="p-seg-item" data-v-247f7c56>Follow system</span></div></div></div><h3 class="sub" data-v-247f7c56>SecondaryModelPicker</h3><p data-v-247f7c56>Linked model + thinking-effort picker (settings → Agent → Subagents, experimental; <code data-v-247f7c56>components/settings/SecondaryModelPicker.vue</code>, shared by both ends). Use it whenever two choices are only valid as a pair — here an effort is meaningless without its model, and every model declares a different supported set. It is a cascading variant of the §03 Select: the trigger is the Select trigger verbatim (value renders <code data-v-247f7c56>model · effort</code>, the unset state uses the placeholder tint), and the dropdown opens as a SINGLE-LEVEL model list (grouped by provider) on the floating menu surface (<code data-v-247f7c56>--color-menu-bg</code> / <code data-v-247f7c56>--p-menu-backdrop</code> / <code data-v-247f7c56>--shadow-lg</code>). The menu <b data-v-247f7c56>teleports to <code data-v-247f7c56><body></code> with <code data-v-247f7c56>position: fixed</code></b> — it opens on top of the settings modal (on the <code data-v-247f7c56>--z-modal-dropdown</code> rung), and only a body-level surface escapes the dialog's scrolling-body clip; it re-anchors to the trigger on any outside scroll and closes on window resize (the UserMenu teleport's full recipe). Hovering or clicking a model row flies its effort submenu out to the RIGHT of the row — same menu surface, anchored to the row's live position, flipping to the left only near the viewport edge per the §03 anchoring rules — with a 250ms hover-intent grace (the UserMenu flyout's recipe) so the diagonal path into the submenu doesn't collapse it. Every model row carries a trailing <code data-v-247f7c56>chevron-right</code> affordance; clicking an effort confirms the pair and closes — one atomic write, never two staggered patches. Flyout options follow the composer's thinking-level model (<code data-v-247f7c56>segmentsFor</code>): effort models get <code data-v-247f7c56>off</code> + their declared levels (always-thinking ones get no off), boolean-thinking models get <code data-v-247f7c56>on</code>/<code data-v-247f7c56>off</code>, unsupported models get <code data-v-247f7c56>off</code> alone; while no effort is set at all, a "Model default" entry leads (it writes the model alone — POST /config merges and cannot clear a stored effort, so the entry disappears once one is set). A configured effort the model no longer declares is appended as an extra flyout option so the current pair stays visible and re-selectable. Keyboard mirrors the Select contract (focus stays on the trigger, Esc <code data-v-247f7c56>preventDefault</code>s so the hosting dialog does not close): ↑/↓ move within the active level (the flyout follows model moves), → opens the flyout, ← collapses it, Enter confirms, Home/End jump. ARIA: combobox trigger → <code data-v-247f7c56>dialog</code> menu holding a model <code data-v-247f7c56>listbox</code> plus the effort <code data-v-247f7c56>listbox</code> flyout with <code data-v-247f7c56>option</code> rows. The menu itself flips upward when the trigger sits near the viewport bottom.</p><h3 class="sub" data-v-247f7c56>Tabs</h3><p data-v-247f7c56>Tabs with a bottom hairline, used for grouping and switching sibling content. The current tab is marked with accent text + an accent underline.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Tabs</span></div><div class="stage p col" data-v-247f7c56><div class="p-tabs" data-v-247f7c56><span class="p-tab on" data-v-247f7c56>General</span><span class="p-tab" data-v-247f7c56>Agent</span><span class="p-tab" data-v-247f7c56>Advanced</span></div></div></div><h3 class="sub" data-v-247f7c56>Switch</h3><p data-v-247f7c56>A two-state switch for settings that take effect immediately. The 36×20 track has a 0.5px hairline and full radius; its 16px knob uses 1.5px internal offsets so the visible inset remains 2px and symmetric after accounting for the border. On hover, the knob eases to an 18px rounded rectangle towards the track centre. When on, the track turns accent and the knob slides right.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Switch</span></div><div class="stage p" data-v-247f7c56><span class="p-switch on" data-v-247f7c56></span><span class="p-switch" data-v-247f7c56></span></div></div><h3 class="sub" data-v-247f7c56>Checkbox</h3><p data-v-247f7c56>A 17×17 checkbox. When checked it fills with the accent color and shows a white tick (inline SVG). Often paired with a text label.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Checkbox</span></div><div class="stage p" data-v-247f7c56><span class="p-check on" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg></span><span class="p-check" data-v-247f7c56></span><label style="display:inline-flex;align-items:center;gap:8px;color:var(--p-text);font-size:var(--p-font-size-base);cursor:pointer;" data-v-247f7c56><span class="p-check on" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg></span>Enable auto-save</label></div></div><h3 class="sub" data-v-247f7c56>Avatar</h3><p data-v-247f7c56>A 32px default avatar with md radius; <code data-v-247f7c56>.sm</code> is 24px. Can hold an initial or an icon; falls back to this placeholder when there is no image.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Avatar</span></div><div class="stage p" data-v-247f7c56><span class="p-avatar" data-v-247f7c56>K</span><span class="p-avatar" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M4 22a8 8 0 1 1 16 0h-2a6 6 0 0 0-12 0zm8-9c-3.315 0-6-2.685-6-6s2.685-6 6-6s6 2.685 6 6s-2.685 6-6 6m0-2c2.21 0 4-1.79 4-4s-1.79-4-4-4s-4 1.79-4 4s1.79 4 4 4" data-v-247f7c56></path></svg></span><span class="p-avatar sm" data-v-247f7c56>K</span></div></div><h3 class="sub" data-v-247f7c56>EmptyState</h3><p data-v-247f7c56>A centered placeholder for empty lists / panels: a 48px faint icon + title + hint, avoiding blank pages.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>EmptyState</span></div><div class="stage p col" data-v-247f7c56><div class="p-empty" style="width:100%;border:0.5px dashed var(--p-line);border-radius:var(--p-r-lg);" data-v-247f7c56><svg class="em-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1zm-.692-2H20V5H4v13.385zM8 10h8v2H8z" data-v-247f7c56></path></svg><div class="em-title" data-v-247f7c56>No chats yet</div><div class="em-hint" data-v-247f7c56>Click "New chat" to start a conversation with Kimi</div></div></div></div><h3 class="sub" data-v-247f7c56>Divider</h3><p data-v-247f7c56>A 0.5px hairline divider (<code data-v-247f7c56>--p-line</code>); <code data-v-247f7c56>.p-divider-v</code> is the vertical divider, used between inline elements.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Divider</span></div><div class="stage p col" data-v-247f7c56><div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-247f7c56>Content above</div><hr class="p-divider" data-v-247f7c56><div style="width:100%;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-247f7c56>Content below</div><div style="display:flex;align-items:center;gap:10px;height:24px;font-size:var(--p-font-size-sm);color:var(--p-text);" data-v-247f7c56><span data-v-247f7c56>kimi-k2</span><span class="p-divider-v" data-v-247f7c56></span><span data-v-247f7c56>thinking</span></div></div></div><h3 class="sub" data-v-247f7c56>Tooltip</h3><p data-v-247f7c56>A CSS-only hover hint, wrapped in <code data-v-247f7c56>.p-tip</code>. Inverted background (<code data-v-247f7c56>--p-text</code> / <code data-v-247f7c56>--p-bg</code>), single line, no wrapping — carries only short notes.</p><p data-v-247f7c56>Component behavior contract (the <code data-v-247f7c56>Tooltip</code> primitive and IconButton's <code data-v-247f7c56>tooltip</code> prop, both backed by TooltipBubble): while any menu surface is open, every tooltip OUTSIDE it hides immediately and no new one may appear — a menu owns the screen, so a trigger's hint must never hang above its own dropdown (native menu behavior). Hints anchored INSIDE an open menu stay live, and ordinary hover behavior resumes once the last menu closes. <code data-v-247f7c56>Menu.vue</code> and the <code data-v-247f7c56>Select</code> listbox register as menu surfaces automatically; a bespoke menu surface (composer dropdowns, the slash/mention autocomplete popups, pickers) wires its open ref + panel element through <code data-v-247f7c56>trackMenuSurface</code> from <code data-v-247f7c56>@moonshot-ai/app-ui</code>.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Tooltip (hover the button)</span></div><div class="stage p" data-v-247f7c56><span class="p-tip" data-v-247f7c56><button class="p-icon-btn" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z" data-v-247f7c56></path></svg></button><span class="p-tooltip" data-v-247f7c56>New chat</span></span></div></div><h3 class="sub" data-v-247f7c56>Banner</h3><p data-v-247f7c56>An inline notice bar placed at the top of a content area. Three states — <code data-v-247f7c56>.info</code> / <code data-v-247f7c56>.warning</code> / <code data-v-247f7c56>.danger</code> — each with a matching 18px icon.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Banner</span></div><div class="stage p col" data-v-247f7c56><div class="p-banner info" data-v-247f7c56><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16M11 7h2v2h-2zm0 4h2v6h-2z" data-v-247f7c56></path></svg>Connected to server</div><div class="p-banner warning" data-v-247f7c56><svg class="bn-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12.866 3l9.526 16.5a1 1 0 0 1-.866 1.5H2.474a1 1 0 0 1-.866-1.5L11.134 3a1 1 0 0 1 1.732 0m-8.66 16h15.588L12 5.5zM11 16h2v2h-2zm0-7h2v5h-2z" data-v-247f7c56></path></svg>Currently in yolo mode; tool calls will run automatically</div></div></div><h3 class="sub" data-v-247f7c56>Sheet / BottomSheet</h3><p data-v-247f7c56>A mobile bottom slide-up panel: xl top radius + drag handle, xl shadow. At ≤640px, dialogs become bottom-anchored Sheets.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>BottomSheet</span></div><div class="stage p col" style="align-items:center;" data-v-247f7c56><div class="p-sheet" style="width:100%;max-width:360px;" data-v-247f7c56><div class="p-sheet-handle" data-v-247f7c56></div><div style="font-size:var(--p-font-size-base);font-weight:700;color:var(--p-text);margin-bottom:8px;" data-v-247f7c56>Choose a model</div><div class="p-menu-item" style="padding:8px 10px;" data-v-247f7c56>kimi-k2 · thinking</div><div class="p-menu-item" style="padding:8px 10px;" data-v-247f7c56>kimi-k2 · instant</div></div></div></div><h3 class="sub" data-v-247f7c56>Skeleton</h3><p data-v-247f7c56>A placeholder for loading content, using a breathing opacity animation (no gradients), following the <code data-v-247f7c56>no-gradient-text</code> rule. Composed into titles / text lines / avatars.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Skeleton</span></div><div class="stage p col" data-v-247f7c56><div style="display:flex;flex-direction:column;gap:10px;width:100%;max-width:360px;" data-v-247f7c56><div class="p-skeleton" style="height:16px;width:55%;" data-v-247f7c56></div><div class="p-skeleton" style="height:12px;width:100%;" data-v-247f7c56></div><div class="p-skeleton" style="height:12px;width:82%;" data-v-247f7c56></div><div class="p-skeleton" style="height:32px;width:32px;border-radius:var(--p-r-full);" data-v-247f7c56></div></div></div></div><h3 class="sub" data-v-247f7c56>Command Bar</h3><p data-v-247f7c56>An inline combination of "primary action + command text + copy", sitting between a button and a code block — used for install / onboarding / one-click execution. The primary action reuses <code data-v-247f7c56>Button primary</code>; the command area uses a mono light-grey background.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Command Bar</span></div><div class="stage p col" data-v-247f7c56><div class="p-cmdbar" style="max-width:620px;" data-v-247f7c56><button class="p-btn primary" data-v-247f7c56>Install Kimi Web ▾</button><span class="p-cmd" data-v-247f7c56><span class="cmd-text" data-v-247f7c56>curl -fsSL https://code.kimi.com/install.sh | bash</span><button class="cmd-copy" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M7 6V3a1 1 0 0 1 1-1h12a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1h-3v3c0 .552-.45 1-1.007 1H4.007A1 1 0 0 1 3 21l.003-14c0-.552.45-1 1.006-1zM5.002 8L5 20h10V8zM9 6h8v10h2V4H9z" data-v-247f7c56></path></svg></button></span></div></div></div><h3 class="sub" data-v-247f7c56>TopBar</h3><p data-v-247f7c56>The application top bar. Solid by default; the <code data-v-247f7c56>.frost</code> variant is translucent + background blur, used <b data-v-247f7c56>only for sticky navigation bars</b>. Together with the floating menu surfaces (Menu / Dropdown), it is one of the two exceptions to the <code data-v-247f7c56>no-glassmorphism</code> rule (see §06).</p><p data-v-247f7c56>The mobile shell's top bar (<code data-v-247f7c56>components/mobile/MobileTopBar.vue</code>, ≤640px) is the canonical consumer of this <code data-v-247f7c56>.frost</code> recipe — 78% surface + backdrop blur over the scrolling transcript, 0.5px hairline at the bottom. Its content is one full-height tap target that opens the switcher sheet: an optional leading status — the active session's ONE <code data-v-247f7c56>SessionDisplayStatus</code> (approval/question <code data-v-247f7c56>Badge sm</code>, running <code data-v-247f7c56>Spinner sm</code>, 7px unread accent dot; same precedence as the sidebar rows) — ahead of a single vertically-centred line at <code data-v-247f7c56>max(16px, --ui-font-size-xl)</code>: quiet workspace name, strong <code data-v-247f7c56>--weight-semibold</code> session title, faint <code data-v-247f7c56>chevron-down</code>. The trailing <code data-v-247f7c56>IconButton lg</code> (44px) opens settings.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>TopBar · solid / frosted glass</span></div><div class="stage p col" style="gap:14px;background:radial-gradient(circle at 18% 30%,rgba(23,131,255,.16),transparent 42%),radial-gradient(circle at 82% 75%,rgba(20,23,28,.10),transparent 46%),var(--p-surface-sunken);" data-v-247f7c56><div class="p-topbar" style="width:100%;max-width:580px;" data-v-247f7c56><span class="tb-title" data-v-247f7c56>Solid TopBar</span><span class="tb-actions" data-v-247f7c56><button class="p-icon-btn sm" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-247f7c56></path></svg></button></span></div><div class="p-topbar frost" style="width:100%;max-width:580px;" data-v-247f7c56><span class="tb-title" data-v-247f7c56>Frosted-glass TopBar · .frost</span><span class="tb-actions" data-v-247f7c56><button class="p-icon-btn sm" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M3 4h18v2H3zm0 7h18v2H3zm0 7h18v2H3z" data-v-247f7c56></path></svg></button></span></div></div></div><h3 class="sub" data-v-247f7c56>Find Bar · transcript search</h3><p data-v-247f7c56>The in-transcript find bar (Cmd/Ctrl+F), implemented by <code data-v-247f7c56>components/chat/TranscriptSearch.vue</code>. A floating card pinned to the transcript's top-right (<code data-v-247f7c56>top: --panel-head-h + --space-3</code>, <code data-v-247f7c56>right: --space-3</code> — equal inset on both axes), <code data-v-247f7c56>--z-sticky</code>, raised surface + 0.5px hairline + <code data-v-247f7c56>--shadow-menu</code>. <b data-v-247f7c56>One radius for both states</b>: <code data-v-247f7c56>--radius-2xl</code> is a full capsule at the collapsed height and a card once the footer expands — never animate between two radii.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Part</th><th data-v-247f7c56>Rule</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Input row</td><td data-v-247f7c56>Search icon (muted) + <b data-v-247f7c56>bare input</b> — the list-style bare-input exception family (sidebar search row, inline rename), NOT the boxed Input primitive; the 38px bordered control would break the pill. Circular close <code data-v-247f7c56>IconButton sm</code> (concentric with the capsule end); a 0.5px hairline separator before it. Height comes from the grid: 32px control (<code data-v-247f7c56>--space-8</code>) + 2× <code data-v-247f7c56>--space-1</code> padding = 40px — at which <code data-v-247f7c56>--radius-2xl</code> is exactly the half-height capsule.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Footer (results)</td><td data-v-247f7c56>Expands via the 0fr→1fr grid fold (<code data-v-247f7c56>--duration-slow</code>), hairline top separator, prev/next <code data-v-247f7c56>IconButton sm</code> left, right-aligned muted count (<code data-v-247f7c56>N/M results</code> · <code data-v-247f7c56>--ui-font-size-sm</code>). Only exists once a query has settled — while typing or empty, the bar stays a bare pill.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>States</td><td data-v-247f7c56>collapsed (empty query) / searching (<code data-v-247f7c56>Spinner sm</code> in the input row during the ~800ms debounce) / results / no-results (count reads "No results", nav disabled). Disabled is uniformly <code data-v-247f7c56>opacity:.5</code>.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Focus</td><td data-v-247f7c56>Composer-style: a neutral hairline overlay (<code data-v-247f7c56>::after</code> + <code data-v-247f7c56>--color-composer-focus-line</code>) fading in on <code data-v-247f7c56>:focus-within</code>. No accent ring.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Match ink</td><td data-v-247f7c56>CSS Custom Highlight API — the bar mutates no transcript DOM. All matches: <code data-v-247f7c56>--color-search-match</code> (yellow); current: <code data-v-247f7c56>--color-search-match-current</code> + a 2px <code data-v-247f7c56>--color-warning</code> outline ring (a positioned overlay — highlight pseudos can't paint box outlines). Tokens live in <code data-v-247f7c56>app-ui/style.css</code> with light/dark pairs.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Keyboard</td><td data-v-247f7c56>Cmd/Ctrl+F opens + focuses (repeat = re-focus + select-all; hardcoded, reserved in the desktop keymap), Enter / Shift+Enter steps matches (wrapping), Esc closes from ANY control inside (container-level, so it never reaches the conversation's Esc-abort).</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Matching semantics</td><td data-v-247f7c56>Rendered transcript DOM only (unloaded older pages are out of scope), capped at 1000 matches (count reads <code data-v-247f7c56>N/1000+</code>). Matches span inline nodes within one block, never cross block breaks; <code data-v-247f7c56>inert</code> and <code data-v-247f7c56>display:none</code> content is excluded. Stepping scrolls the match's own rect into view, not its parent element.</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>SectionLabel</h3><p data-v-247f7c56>A small group title for sidebar lists, used to section the content below (such as <code data-v-247f7c56>Workspaces</code> in the sidebar). Spec: 13px / 700 / uppercase / letter-spacing <code data-v-247f7c56>.08em</code>, color <code data-v-247f7c56>--color-fg-faint</code>; left-aligned to the row's starting padding (<code data-v-247f7c56>--sb-pad-x</code>), keeping the same indent as the group rows below. For scripts without case (such as Chinese), <code data-v-247f7c56>text-transform:uppercase</code> simply has no effect — no special handling needed.</p>',57)),t("div",ra,[a[31]||(a[31]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Sidebar · group title")],-1)),t("div",va,[a[30]||(a[30]=t("div",{class:"p-section-label",style:{padding:"12px 16px 4px"}},"Workspaces",-1)),t("div",fa,[(n(),l("svg",ha,[...a[26]||(a[26]=[t("path",{fill:"currentColor",d:"M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])),a[27]||(a[27]=e(" kimi-code-web ",-1))]),t("div",pa,[(n(),l("svg",ua,[...a[28]||(a[28]=[t("path",{fill:"currentColor",d:"M4 5v14h16V7h-8.414l-2-2zm8.414 0H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])),a[29]||(a[29]=e(" playground ",-1))])])])]),t("section",ga,[a[142]||(a[142]=c('<div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>04</span><h2 class="sec-title" data-v-247f7c56>Chat Interface Overhaul</h2></div><p class="sec-desc" data-v-247f7c56> The message stream is the core of Kimi Web. Tool calls render as <b data-v-247f7c56>quiet activity lines</b> — one borderless line per call, bespoke per tool kind, auto-grouped, expanding on demand — while Question / Approval elevate to a <b data-v-247f7c56>floating neutral surface</b> because they need a decision, and the Swarm composite keeps a card; the Composer collapses into a single rounded container. </p><h3 class="sub" data-v-247f7c56>Unified message stream</h3><p data-v-247f7c56>User-message bubbles follow the kimiwork production recipe (<code data-v-247f7c56>MessageItem .user-bubble</code>): a neutral <code data-v-247f7c56>--color-user-bubble-bg</code> fill (BubbleGray — <code data-v-247f7c56>#f5f5f5</code> light / <code data-v-247f7c56>#292929</code> dark), uniform <code data-v-247f7c56>--radius-lg</code> corners, no border, no shadow.</p><p data-v-247f7c56>Message timestamps use 12px UI text at weight 500, matching the compact metadata scale without switching to a monospace face.</p><p data-v-247f7c56>The user-message metadata row sits one 8px spacing step below the bubble, so its actions and timestamp read as supporting information rather than part of the bubble edge.</p><p data-v-247f7c56>Overlong user messages clamp at 10 measured lines, the tail dissolving through an alpha mask rather than a tint overlay (the translucent accent fill would double-composite); a floating pill toggle centred on the fade expands in place and collapses back, and the collapse pins the toggle itself so the reading position survives. Skill / plugin command args clamp through the same wrapper, beside the card head. Like the transcript's other disclosure controls (thinking row, turn fold, tool lines), the toggle is a bare native button carrying <code data-v-247f7c56>aria-expanded</code> — chat-surface disclosure controls do not use the §03 Button primitive.</p><p data-v-247f7c56>The floating jump-to-latest control uses 12px UI text at weight 525, led by the full down-arrow icon rather than a disclosure caret.</p><p data-v-247f7c56>Thinking is an inline, borderless disclosure row in the message stream — never a side panel. The k15 bulb (the <code data-v-247f7c56>thinking</code> registry icon) leads the row in every state; while streaming the "Thinking…" label breathes (opacity only, never a gradient shimmer) and whole elapsed seconds tick beside it, afterwards the label settles to "Thinking process" with the final span as <code data-v-247f7c56>· Ns</code> (renderer-measured, live sessions only — history shows no seconds). Collapsed by default, it expands in place with the standard grid-rows animation and a 90° chevron rotation, and it folds itself back once the stream moves past it, even if the user expanded mid-stream. The header only animates its text colour on hover (standard duration and easing tokens), no card shell.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Conversation · 760px reading column</span></div><div class="stage p col" style="align-items:center;background:#fff;" data-v-247f7c56><div class="demo-chat" data-v-247f7c56><div class="p-bubble-user" data-v-247f7c56>Please change the login endpoint to JWT and add the corresponding unit tests.</div><span class="p-thinking" data-v-247f7c56><span style="font-size:15px;line-height:1;" data-v-247f7c56>🌔</span>Analyzing the auth module…</span><div class="p-tool-group open" data-v-247f7c56><div class="p-tool-group-head" data-v-247f7c56><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tg-title" data-v-247f7c56>Read 2 files</span><svg class="tg-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg></div><div class="p-tool-row expanded" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>session.ts</span><span class="tr-faint" data-v-247f7c56>src/auth · :12-45</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>34 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div><div class="p-tool-detail" data-v-247f7c56><div class="p-code" data-v-247f7c56>12 export function verify(token: string) {<br data-v-247f7c56>13 return jwt.verify(token, getSecret());<br data-v-247f7c56>14 }</div></div><div class="p-tool-row" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>middleware.ts</span><span class="tr-faint" data-v-247f7c56>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>58 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div></div><div class="p-tool-row" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414 1.414l1.414-1.414l-1.414-1.414l-1.414 1.414zM4 21h16v-2H4v2z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Edit</span><span class="tr-file" data-v-247f7c56>middleware.ts</span><span class="tr-faint" data-v-247f7c56>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-add" data-v-247f7c56>+12</span><span class="tr-del" data-v-247f7c56>−4</span><span class="tr-bar" aria-hidden="true" data-v-247f7c56><span style="flex:12;background:var(--p-success);" data-v-247f7c56></span><span style="flex:4;background:var(--p-danger);" data-v-247f7c56></span></span><span class="tr-ok" data-v-247f7c56>✓</span></div><div class="p-tool-row" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m18.031 16.617l4.283 4.282l-1.415 1.415l-4.282-4.283A8.96 8.96 0 0 1 11 20c-4.968 0-9-4.032-9-9s4.032-9 9-9s9 4.032 9 9a8.96 8.96 0 0 1-1.969 5.617m-2.006-.742A6.98 6.98 0 0 0 18 11c0-3.867-3.133-7-7-7s-7 3.133-7 7s3.133 7 7 7a6.98 6.98 0 0 0 4.875-1.975z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Search</span><span class="tr-mono" data-v-247f7c56>"jwt.verify"</span><span class="tr-faint" data-v-247f7c56>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>4 results</span><span class="tr-ok" data-v-247f7c56>✓</span></div><div class="p-msg" data-v-247f7c56><p data-v-247f7c56>I looked at the structure of <code data-v-247f7c56>src/auth</code>; it is currently based on a session cookie. The scope of the change is below — once you confirm, I'll start.</p></div><div class="p-action" data-v-247f7c56><div class="p-action-head" data-v-247f7c56><span class="p-action-title" data-v-247f7c56>A decision needs your confirmation</span></div><div class="p-action-body" data-v-247f7c56>How long should the JWT expiry be? Default 7 days, refresh token 30 days.</div><div class="p-action-foot" data-v-247f7c56><button class="p-btn ghost sm" data-v-247f7c56>Customize</button><button class="p-btn primary sm" data-v-247f7c56>Use default</button></div></div><div class="p-action" data-v-247f7c56><div class="p-action-head" data-v-247f7c56><span class="p-action-title" data-v-247f7c56>Write permission required</span></div><div class="p-action-body" data-v-247f7c56>About to modify <code data-v-247f7c56>src/auth/middleware.ts</code>, 42 lines changed. Allow?</div><div class="p-action-foot" data-v-247f7c56><button class="p-btn primary sm" data-v-247f7c56>Allow this time</button><button class="p-btn ghost sm" data-v-247f7c56>Always allow</button><button class="p-btn ghost sm" data-v-247f7c56>Deny</button></div></div><div class="p-todo" data-v-247f7c56><div class="p-todo-row done" data-v-247f7c56><span class="p-todo-check" data-v-247f7c56><svg viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path d="m10 15.17l9.192-9.191l1.414 1.414L10 17.999l-6.364-6.364l1.414-1.414z" data-v-247f7c56></path></svg></span>Replace session with JWT signing</div><div class="p-todo-row active" data-v-247f7c56><span class="p-todo-check" data-v-247f7c56><svg viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><circle cx="12" cy="12" r="3.5" data-v-247f7c56></circle></svg></span>Refactor the auth middleware</div><div class="p-todo-row" data-v-247f7c56><span class="p-todo-check" data-v-247f7c56><svg viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><circle cx="12" cy="12" r="3.5" data-v-247f7c56></circle></svg></span>Add unit tests</div></div></div></div></div><p data-v-247f7c56><b data-v-247f7c56>Wide markdown tables (desktop):</b> regular chat prose stays within the 760px reading column (<code data-v-247f7c56>--p-content-max</code>), and tables stay there too by default — an overflowing table scrolls horizontally inside its own wrapper, so the page and the chat area never scroll sideways. A clipped table shows a gradient fade at its truncated right edge, and hovering the table reveals a small widen button at its top-right corner; clicking it lets the table grow naturally with its content up to 1040px (<code data-v-247f7c56>--p-table-max</code>), centred within the conversation pane, and clicking again restores the default width. At the default width a single column is capped at 36% of the pane; once widened the cap relaxes to 700px (<code data-v-247f7c56>--p-table-cell-max</code>), so long cell content wraps inside the cell instead of stretching the table. The conversation outline (TOC) keeps its usual position just outside the reading column; when a widened table grows past it and scrolls under the rail, the TOC is hidden temporarily and returns as soon as the table leaves, without touching the user's TOC setting. On mobile a table never breaks out of the reading column.</p><h3 class="sub" data-v-247f7c56>Tool calls: quiet activity lines, bespoke per tool</h3><p data-v-247f7c56>High-frequency calls like <code data-v-247f7c56>read</code> / <code data-v-247f7c56>bash</code> / <code data-v-247f7c56>grep</code> are "operational noise" — boxed, collapsible cards quickly drown out the conversation. Tool calls therefore render as <b data-v-247f7c56>one quiet borderless line</b> in the message stream — never a card — and each tool kind composes that line for its own content, so the stream reads like an activity log rather than a pile of widgets. The three visual-weight tiers:</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Three visual-weight tiers</span></div><div class="stage p col" data-v-247f7c56><span class="stage-label" data-v-247f7c56>① Tool line · lightest (default) — bespoke content per tool, no card chrome</span><div class="p-tool-row" style="align-self:stretch;" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm1 2v14h16V5H4zm3 3h5v2H7V8zm0 4h8v2H7v-2z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Run</span><span class="tr-mono" data-v-247f7c56>pnpm run build && pnpm lint</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>0.8s</span><span class="tr-ok" data-v-247f7c56>✓</span></div><span class="stage-label" data-v-247f7c56>② Activity run · medium (consecutive quiet activity — thinking + tool lines — folds to one smart-summary row)</span><div class="p-tool-group" data-v-247f7c56><div class="p-tool-group-head" data-v-247f7c56><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tg-title" data-v-247f7c56>Read 3 files</span><svg class="tg-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg></div></div><span class="stage-label" data-v-247f7c56>③ Sub Agent identity card · one per delegation — task title + a meta line leading with the 前台/后台 mode then agent type · model · effort; the whole card opens the side panel (no in-stream expansion, never grouped)</span><div class="p-agent-card" data-v-247f7c56><span class="pa-ic" data-v-247f7c56><svg viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M13.5 2c0 .444-.193.843-.5 1.118V5h5a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3H6a3 3 0 0 1-3-3V8a3 3 0 0 1 3-3h5V3.118A1.5 1.5 0 1 1 13.5 2M6 7a1 1 0 0 0-1 1v10a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8a1 1 0 0 0-1-1zm-4 3H0v6h2zm20 0h2v6h-2zM9 14.5a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3m6 0a1.5 1.5 0 1 0 0-3a1.5 1.5 0 0 0 0 3" data-v-247f7c56></path></svg></span><span class="pa-main" data-v-247f7c56><span class="pa-task" data-v-247f7c56>分析双引擎架构</span><span class="pa-type" data-v-247f7c56>前台 · Explore</span></span><span class="pa-ok" data-v-247f7c56>✓</span><span class="pa-go" data-v-247f7c56>→</span></div><span class="stage-label" data-v-247f7c56>④ Decision card · heavy (only question / approval, needs user input)</span><div class="p-action" data-v-247f7c56><div class="p-action-head" data-v-247f7c56><span class="p-action-title" data-v-247f7c56>Write permission required</span></div><div class="p-action-body" data-v-247f7c56>About to modify <code data-v-247f7c56>src/auth/middleware.ts</code>, 42 lines changed.</div></div></div></div><ul class="clean check" data-v-247f7c56><li data-v-247f7c56>A tool call renders as <b data-v-247f7c56>one quiet borderless line</b> (~24px, the thinking row's rhythm): leading glyph, tool-specific content, trailing meta + status. There is no card chrome and no hover wash — the chevron hugging the line's text (thinking-row style, never pushed to the far edge) is the only disclosure affordance, a real <code data-v-247f7c56><button></code> carrying <code data-v-247f7c56>aria-expanded</code> (keyboard path); the head itself is a plain click target (mouse path), so trailing slots may hold genuine buttons of their own (e.g. Agent's "open detail").</li><li data-v-247f7c56><b data-v-247f7c56>One type scale for the whole stream</b>: thinking rows, fold summary rows and tool lines all set 13px UI text; in-line mono and trailing meta run one step down at 12px (a monospace x-height reads larger, so 12px sits level next to 13px). Hierarchy comes from colour, never from size jumps or bold — everything on the line is regular weight: the only dark object is the file-name button (<code data-v-247f7c56>--color-text</code> — the one interactive place to go); the action label (Run / Read / Edit…), the mono command / pattern and secondary context all sit at <code data-v-247f7c56>--color-text-muted</code>; auxiliary elements (glyphs, chevrons, trailing meta) stay <code data-v-247f7c56>--color-text-faint</code>. The stream thus reads in three quiet tiers: prose in text, tool lines in muted, thinking / captions in faint. Line content is centre-aligned so mono-only rows (Bash) sit level with the icon and chevron. Truncating line content (the CSS-ellipsis spans) sets <code data-v-247f7c56>--leading-tight</code> rather than the row's <code data-v-247f7c56>line-height: 1</code> — a 1em line box is shorter than the font's ascent + descent, so <code data-v-247f7c56>overflow: hidden</code> would clip descenders (j / p / g / y); mono runs take the font's own <code data-v-247f7c56>normal</code> leading instead, since JetBrains Mono's ≈1.32em metrics exceed <code data-v-247f7c56>--leading-tight</code>. The 16px chevron still drives the ~24px row height.</li><li data-v-247f7c56><b data-v-247f7c56>Every tool kind composes its own line, leading with the tool's localized action label</b> (Run / Read / Edit / Write / Search / Find / Fetch…): Bash pairs its label with the full command in mono (CSS-truncated) plus a duration chip; Read / Edit / Write follow the label with the file name as a real button (opens the file preview) followed by the directory, a <code data-v-247f7c56>:line-range</code> or a <code data-v-247f7c56>+N −M</code> stat with a mini segmented bar; Grep shows the pattern in mono plus a match count; Glob / Ls list paths; Todo carries the active task with a done/total progress bar; goal tools show a coloured status pill; WaitFor names the waited / finished task with the task's terminal status as a §03 Badge (a timed-out wait renders as a warning, never an error) and the waited span as a chip; ExitPlanMode expands into a read-only plan receipt with its persisted review outcome. Unrecognized tools fall back to glyph + localized label + argument summary.</li><li data-v-247f7c56><b data-v-247f7c56>The settled question is the one exception to the quiet line</b>: once AskUserQuestion settles with a recognized answer, it becomes a small <b data-v-247f7c56>receipt card</b> — the question card's echo (raised surface, hairline edge, lg radius, <code data-v-247f7c56>--shadow-xs</code>, flush with the stream's left edge, ≤560px). The card echoes only the picks, checked with the live QuestionCard's CSS glyph language one step down (14px); passed-over options are not echoed. Dismissed (or zero-answer) collapses to a slim italic one-line card; while running, and for unrecognized output (background launch / error), it stays the plain quiet disclosure line with the raw output.</li><li data-v-247f7c56>Clicking a line <b data-v-247f7c56>expands it in place</b>; the detail hangs below at the line's own left edge (no inset), so it reads as part of the stream rather than as a separate card. Details are one of: the mono output panel (content-well surface, hairline edge, 12-line scroll cap), the inline diff, or clickable match / file lists (<code data-v-247f7c56>path:line</code> opens the preview at that line). Code-bearing details — the Read content, the Edit diff, the Write content — are <b data-v-247f7c56>syntax-highlighted by file type</b> (github-light / github-dark, following the colour scheme), with the Read output's real line numbers as the gutter; highlighting mounts lazily on first expand and degrades to plain text for unknown languages or oversized content.</li><li data-v-247f7c56>Rows sit <b data-v-247f7c56>flush with the message stream's left edge</b> (same alignment as prose and the thinking row): no inset, no hover wash, and the glyph rides the thinking row's 4px icon-to-text rhythm with no padded slot. Expanded rows inside a group stack directly on the shared rhythm — no dividers.</li><li data-v-247f7c56>Consecutive activity — thinking segments and tool calls of ANY kind, quiet lines and richer cards alike — <b data-v-247f7c56>folds into ONE activity-run row</b>: a smart summary sentence that aggregates the run per tool kind in first-appearance order (<code data-v-247f7c56>Read 2 files · Ran 5 commands (1 failed) · 26s</code>), the failure clause hanging on its kind in danger red, the total span faint at the tail — one line, ellipsis-truncated, the full sentence in the title tooltip. Thinking items fold into the run but are not narrated in the sentence. The row shares the thinking row's language (borderless faint text row, text-colour hover only, one whole-row button with a rotating chevron) but rides a roomier 8px vertical padding — 30px against the quiet lines' 22px, so the turn-level summary keeps its presence between prose paragraphs; while the turn streams through the run the row stays expanded and the summary turns live (current action + cumulative per-kind stats + ticking whole seconds), and once every item settles it folds itself back — even if the user expanded it mid-run (the thinking block's vocabulary); a settled → running transition (the stream appending to the same run) reopens it. The glyph carries the state: the current step's own icon breathing while running, green ✓ / red ✕ once settled. A run needs <b data-v-247f7c56>≥ 2 steps</b> — a lone step renders standalone as the block it always was. <b data-v-247f7c56>Text never folds</b> (it breaks the run), and neither do successful media tools (no card — inline media is the turn's output). <b data-v-247f7c56>Task notifications never join the run either — but unlike text they never break it</b>: a notice landing mid-run queues and renders right after the run block (see the notification entry below); everything else folds, cards included: Todo / Goal progress narration, the sub-agent identity card, Question / Swarm cards and unrecognized kinds (skills, MCP tools) all join the run — the stay-expanded-while-live rule keeps a card visible exactly while it is active. The expanded run is the items flat in order (thinking rows + tool rows), each with its own in-row details intact — the lines keep their own 4px row rhythm but breathe 8px apart, with a small inset below the head.</li><li data-v-247f7c56><b data-v-247f7c56>Above the activity run sits the turn fold</b> (<code data-v-247f7c56>TurnFold.vue</code>): when an assistant turn settles, every block before the LAST text block — thinking segments, activity runs, interim text paragraphs, Todo / Goal / sub-agent cards — folds into a single bare row reading <code data-v-247f7c56>Worked 4m57s</code> (whole seconds, no glyph, no summary sentence), expanding into the folded blocks in order, each with its own rendering intact. The span is the turn's ELAPSED time (<code data-v-247f7c56>turnWorkMs</code>): it ticks from the stamped start while the turn is open — approval/question waits included by design, so no park bookkeeping exists — then reads the daemon's own <code data-v-247f7c56>durationMs</code> once settled (the server message stamps for history turns); the wall clock only feeds the live tick, so throttled tabs, session switches and remounts cannot corrupt the settled value. Without any stamp the row falls back to the generic <code data-v-247f7c56>Work details</code>. Streaming turns show no row and a forced-open body — the live transcript is untouched, the fold lands only when the stream moves past the turn (or the turn parks). The split never hides the turn's output: the final text block and any trailing blocks (inline media, standalone cards) stay visible, and a text-only turn folds nothing. Fold state is a plain component ref — nothing persists, switching sessions resets to folded. Inside the right-side sub-agent transcript (ChatPane's inspector mode), the turn fold and the run-end footer are suppressed entirely; activity runs stay pinned open (their heads demoted to plain captions — an inspection view exists to show the whole trajectory), while thinking blocks keep the main transcript's fold behavior — collapsed by default, toggleable, folding back when the stream moves past them — skipping only the reveal animation (the <code data-v-247f7c56>instantReveal</code> prop). Disclosure bodies open instantly while their chevrons retain the standard rotation: animating the height of a full historical stream would relayout the entire panel on every animation frame.</li><li data-v-247f7c56><b data-v-247f7c56>A sub-agent delegation is an identity card</b> — never a quiet line: the card carries the TASK as its title and the agent type as a quiet meta line, while the orchestrator's full prompt stays out of the stream on purpose. The whole card is one action (the quiet shell vocabulary: raised surface, hairline edge, large radius, no shadow): click to open the subagent's live progress in the side panel — there is no in-stream expansion.</li><li data-v-247f7c56>Status keeps the shared vocabulary: running (pulsing accent dot) / done (green ✓) / failed (red ✗), at the line's right edge. <b data-v-247f7c56>Only two types keep a full card</b>: <code data-v-247f7c56>Question</code> and <code data-v-247f7c56>Approval</code> — they genuinely need the user's attention. The Swarm composite keeps one quiet card (raised surface, 0.5px hairline, large radius) for its phase overview + member accordion.</li><li data-v-247f7c56><b data-v-247f7c56>A task notification renders in the cron notice's language, not as a status card</b> (<code data-v-247f7c56>NotificationCard.vue</code>, sharing CronNotice.vue's visual grammar): the hidden <code data-v-247f7c56><notification></code> injections (background-task / sub-agent settlement) render as a right-aligned column capped at <code data-v-247f7c56>--p-bubble-max</code> — the user bubble / cron notice side of the stream. A small faint provenance line sits ABOVE the content (status icon + title + source id, e.g. "后台任务完成 · bash-lo9yv9ch", mirroring the cron head's "title · schedule"); only the icon carries the status colour (completed → success, failed / timed_out / lost → danger, killed → warning, else neutral; a sub-agent info notice takes the robot glyph). Under it, the notification's own text sits in a neutral grey rounded block (the user-bubble fill, uniform large radius, no border, no shadow): title and body in full (wrapping, never truncated), an output-file row (mono ellipsized path + formatted size + copy-path button), the output-preview block (a faint caption carrying the payload's truncated flag + sizes over the line-clamped monospace tail of the task output), and the raw-payload <code data-v-247f7c56><details></code> disclosure — type / source / severity fields plus the verbatim XML in a height-capped mono scroller — fused INTO the block as its last section; only the event time sits underneath. ≥2 CONSECUTIVE notifications merge into ONE render block, but every notification renders as its own notice, stacked in order — never a collapsed group card. A notification <b data-v-247f7c56>never breaks the activity run</b>: one landing mid-run (a background task settling while the agent keeps working) is held back and rendered right AFTER the run block, so the turn's tools stay in one group; with no run open it renders in place. Notifications are never turn boundaries, and they <b data-v-247f7c56>never fold</b> — a notification is an event worth noticing, not process noise, so it punches out of the turn fold and renders right after the fold row, in order.</li><li data-v-247f7c56><b data-v-247f7c56>A turn that dies on a model-request failure leaves a persistent terminal card</b> at the transcript tail (ChatPane's <code data-v-247f7c56>.turn-failed</code>): the notification card's danger shell (danger-soft surface, danger hairline, 24px status chip with the warning glyph) carrying a title keyed by the wire error kind (model failure vs step-limit stop), the provider message as a muted sub, a mono diagnostics meta (code · HTTP status · request id), and exactly ONE secondary sm action — Continue, which submits a short continue prompt through the normal path. It renders only while the session sits idle on <code data-v-247f7c56>lastTurnReason === 'failed'</code> (a turn with zero assistant output included, so it pins to the tail rather than any assistant row), it is not dismissible, and it vanishes the moment a new turn starts. While the turn is still fighting, the working indicator instead narrates the retry backoff ("retrying n/max" from the live <code data-v-247f7c56>agent.status.updated</code> phase) — a retrying turn never shows the card. The transient error toast now fires only for background sessions; the viewed session's failure is fully covered by the card.</li><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Turn failed card · persistent terminal marker + one resume action</span></div><div class="stage p col" data-v-247f7c56><div class="p-turn-failed" data-v-247f7c56><span class="tf-chip" data-v-247f7c56><svg viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path d="M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z" data-v-247f7c56></path><path d="M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z" data-v-247f7c56></path><path fill-rule="evenodd" clip-rule="evenodd" d="M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z" data-v-247f7c56></path></svg></span><div class="tf-main" data-v-247f7c56><span class="tf-title" data-v-247f7c56>模型请求失败,本轮对话已中断</span><span class="tf-sub" data-v-247f7c56>429 The engine is currently overloaded, please try again later</span><span class="tf-meta" data-v-247f7c56>provider.rate_limit · HTTP 429 · req_01KZ8Y…</span></div><button class="p-btn secondary sm" data-v-247f7c56>继续</button></div></div></div><li data-v-247f7c56><b data-v-247f7c56>A goal-continuation turn carries a provenance row</b>: the hidden <code data-v-247f7c56>goal_continuation</code> trigger (goal mode's self-driven next turn — a turn boundary, unlike task notifications) never renders its machine prompt; instead the assistant turn it opens shows one faint 12px line flush with the stream's left edge — the <code data-v-247f7c56>target</code> glyph shared with the Goal tool (this turn belongs to the goal) + a localized label — ABOVE the turn's content and OUTSIDE the turn fold, so the row survives as the turn's provenance after settling. The marker lands with the trigger (before the first assistant block), and while the newest exchange is a goal-continuation turn the undo affordances (edit-and-resend, Esc undo) are suppressed — rewinding would drop the hidden trigger while refilling the older user text.</li><li data-v-247f7c56><b data-v-247f7c56>A settled turn's file changes are one summary card</b> (<code data-v-247f7c56>TurnFilesSummary.vue</code>): between the turn's final text and its footer, a §03 <code data-v-247f7c56>Card</code> (hairline border, no shadow — NOT the quiet tool line, the artifacts are worth a discrete object) lists every file the turn's Edit / Write calls touched. The head reads "N files changed" with the aggregate <code data-v-247f7c56>+A −D</code> and the mini diffbar; the aggregate hides whenever any row's stats are incomplete (a Write or an underivable edit makes the total a lower bound, never presented as exact). Each row is one clickable workspace-relative path (short and self-locating; a file outside the cwd stays absolute) with its per-file <code data-v-247f7c56>+A −D</code> at the right edge. The row's action keys on the tool kind, and the stats tell it apart: a <b data-v-247f7c56>Write</b> has no per-file count (its diff is underivable) and opens the whole file in the preview; an <b data-v-247f7c56>Edit / MultiEdit</b> carries its <code data-v-247f7c56>+A −D</code> and opens that file's <b data-v-247f7c56>turn diff</b> in the right-side detail layer (<code data-v-247f7c56>TurnDiffPanel.vue</code> — the turn's own X→Y change, not the git diff), whose header keeps an open-file action. The first three files show inline; the rest collapse behind a "N more files" ghost-button row in the card's foot. Where nothing handles the row action (the BTW side chat), the card renders its file rows as plain text instead of links.</li></ul>',15)),t("div",ma,[a[37]||(a[37]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Turn files summary · a real TurnFilesSummary (fixed sample)")],-1)),t("div",ba,[t("div",wa,[s(E,{changes:z,cwd:Vt,onOpenDiff:m,onOpenFile:m})])])]),a[143]||(a[143]=c('<div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Tool Call · quiet lines (expand on demand)</span></div><div class="stage p" data-v-247f7c56><div class="p-tool-group open" data-v-247f7c56><div class="p-tool-group-head" data-v-247f7c56><svg class="tg-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tg-title" data-v-247f7c56>Read 2 files</span></div><div class="p-tool-row expanded" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>session.ts</span><span class="tr-faint" data-v-247f7c56>src/auth · :12-45</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>34 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div><div class="p-tool-detail" data-v-247f7c56><div class="p-code" style="font-size:11px;padding:7px 9px;" data-v-247f7c56>12 export function verify(…</div></div><div class="p-tool-row" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M9 2.003V2h10.998C20.55 2 21 2.455 21 2.992v18.016a.993.993 0 0 1-.993.992H3.993A1 1 0 0 1 3 20.993V8zM5.83 8H9V4.83zM11 4v5a1 1 0 0 1-1 1H5v10h14V4z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Read</span><span class="tr-file" data-v-247f7c56>middleware.ts</span><span class="tr-faint" data-v-247f7c56>src/auth</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-chip" data-v-247f7c56>58 lines</span><span class="tr-ok" data-v-247f7c56>✓</span></div></div><div class="p-tool-row" data-v-247f7c56><svg class="tr-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M15.728 9.686l-1.414-1.414L5 17.586V19h1.414l9.314-9.314zm1.414-1.414l1.414 1.414l1.414-1.414l-1.414-1.414l-1.414 1.414zM4 21h16v-2H4v2z" data-v-247f7c56></path></svg><span class="tr-name" data-v-247f7c56>Edit</span><span class="tr-file" data-v-247f7c56>middleware.ts</span><svg class="tr-car" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m13.172 12l-4.95-4.95l1.414-1.413L16 12l-6.364 6.364l-1.414-1.415z" data-v-247f7c56></path></svg><span class="tr-add" data-v-247f7c56>+12</span><span class="tr-del" data-v-247f7c56>−4</span><span class="tr-bar" aria-hidden="true" data-v-247f7c56><span style="flex:12;background:var(--p-success);" data-v-247f7c56></span><span style="flex:4;background:var(--p-danger);" data-v-247f7c56></span></span><span class="tr-ok" data-v-247f7c56>✓</span></div></div></div><h3 class="sub" data-v-247f7c56>Decision cards · Question / Approval</h3><p data-v-247f7c56>The two attention cards replace the composer in the dock and share one contract: a floating neutral shell (<code data-v-247f7c56>--color-surface-raised</code> + hairline + <code data-v-247f7c56>--radius-lg</code> + <code data-v-247f7c56>--shadow-menu</code>), a plain dark 16px title head, and a hairline footer whose actions read in number-key order with exactly one accent primary. There is no semantic colour band — the floating card itself is the "needs a decision" signal.</p><div class="stage-wrap" data-v-247f7c56><div class="stage-bar" data-v-247f7c56><span class="st" data-v-247f7c56>Plan review · pinned option rows, second-line descriptions</span></div><div class="stage p col" data-v-247f7c56><div class="p-action" style="max-width:520px;" data-v-247f7c56><div class="p-action-head" data-v-247f7c56><span class="p-action-title" data-v-247f7c56>按这份 plan 开始实现?</span></div><div class="p-action-body" data-v-247f7c56>The plan markdown scrolls in a capped area; the approaches are pinned below it — label on the first line, full description always on the second. The number chip doubles as the keyboard hint.</div><div class="p-opts" data-v-247f7c56><div class="p-opt" data-v-247f7c56><span class="n" data-v-247f7c56>1</span><span class="p-opt-text" data-v-247f7c56><span class="l" data-v-247f7c56>方案 A:静态徽章</span><span class="d" data-v-247f7c56>零依赖、渲染稳定,升级时需手动同步版本号。</span></span></div><div class="p-opt" data-v-247f7c56><span class="n" data-v-247f7c56>2</span><span class="p-opt-text" data-v-247f7c56><span class="l" data-v-247f7c56>方案 B:动态徽章</span><span class="d" data-v-247f7c56>版本自动同步免维护,但要求仓库公开可访问。</span></span></div></div><div class="p-action-foot" data-v-247f7c56><button class="p-btn ghost sm" data-v-247f7c56>修改</button><button class="p-btn ghost sm" data-v-247f7c56>拒绝并退出</button></div></div></div></div><ul class="clean check" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>Footer contract</b>: actions are left-aligned in number-key order (1·2·3·4), each carrying a number chip — sized by <code data-v-247f7c56>--p-chip-num</code> over <code data-v-247f7c56>--color-inline-code-bg</code>, the same chip vocabulary as option rows and the multi-step chip; exactly one <code data-v-247f7c56>primary</code> action, the rest are <code data-v-247f7c56>ghost</code>. Feedback mode swaps the whole footer for submit / cancel.</li><li data-v-247f7c56><b data-v-247f7c56>Feedback input</b>: the reject-with-feedback box is the shared §03 <code data-v-247f7c56>Textarea</code> primitive (no bespoke input), three rows at rest, auto-growing with its content UPWARD — the card is bottom-anchored in the dock, so the bottom edge and the submit / cancel footer never move — capped at 40% of the VISUAL viewport, then scrolling internally. Height budgets follow <code data-v-247f7c56>--app-height</code> (the visual viewport, which shrinks with the iOS keyboard where <code data-v-247f7c56>dvh</code> does not): the card caps at <code data-v-247f7c56>calc(var(--app-height, 100dvh) - var(--dock-card-top-clearance))</code> and the dock takes over the same budget. While the feedback box grows, every body kind yields and scrolls internally by default instead of pushing the card past its cap — the plan scroll area, code previews, shell output, todo lists, invocation chips and generic text — with only the one-line plan path pinned at full height. A plan review's option rows belong to the plan region and never shrink, so once fixed chrome (options, grown feedback box) exceeds what the capped card leaves — e.g. the iOS keyboard shrinking the visual viewport — the WHOLE plan region (body and options together) becomes one scroller, keeping an approve option reachable by scrolling instead of clipped out of reach. Below even that budget — the cap under the fixed chrome alone (header plus mobile's stacked ≥46px submit / cancel buttons), as when an iOS landscape keyboard leaves a ~200px visual viewport — the body has already shrunk to zero and the CARD itself becomes the scroller of last resort (overflow-y: auto, with its own scroll seam), so the footer buttons are never clipped away.</li><li data-v-247f7c56><b data-v-247f7c56>Body by kind</b>: Write approvals preview the incoming content with <code data-v-247f7c56>HighlightedCode</code> (syntax-highlighted, 24-row cap with scroll); Edit approvals render the before/after hunk as a highlighted line diff. Plan / diff / file kinds get a head expand toggle that lifts the cap so the block fills the card; the card itself never exceeds the pane (only the scroll area shrinks) — with the dock work pills visible, the dock takes over the same height budget as a flex column, so an expanded card yields the pills' height instead of pushing them past the pane's top edge. Once the plan scrolls, a soft shadow fades in at the scroll area's top edge — the sidebar's scroll-linked seam language, so clipped content reads as passing under the card chrome.</li><li data-v-247f7c56><b data-v-247f7c56>Danger hint</b>: destructive shell commands (rm -rf, sudo, force-push…) show a <code data-v-247f7c56>danger-soft</code> filled hint row under the command — detection is a display-layer heuristic on the client.</li><li data-v-247f7c56><b data-v-247f7c56>Minimized</b>: the card collapses to a thin bar with a mono peek of the subject; the whole bar is the expand click target.</li><li data-v-247f7c56><b data-v-247f7c56>Question card</b>: the title is the question itself, wrapping in full (only the minimized bar truncates to a single-line ellipsis), with a step chip for multi-question flows and a × dismiss button. Like the approval card, the expanded card is capped just below the chat header (the shared <code data-v-247f7c56>--dock-card-top-clearance</code> budget) — the body is the internal scroll region, and when the fixed chrome (a very long title plus the footer) exhausts the budget on its own the body keeps an operable floor (<code data-v-247f7c56>--question-card-body-min-h</code>) while the CARD itself becomes the scroller of last resort (overflow-y: auto), so the options and footer actions are never clipped out of reach; with dock work pills visible the dock takes over the same budget as a flex column so the card yields the pills' height — and with no room left above a full-height card, an open work panel closes and stays closed until the question resolves; ↑/↓ keeps the highlighted/selected row inside the body's scrollport, and paging between questions resets the scroll position. Options use CSS radio/checkbox glyphs (accent when selected); the number chip and glyph top-align with the option text, optically centred on the label's first line. The footer follows the same left-aligned action contract (primary first, ghosts after), with the keyboard hint pinned to the right edge; keyboard: ↑↓ moves (Space toggles in multi), digits pick, Enter advances/submits, Esc dismisses.</li></ul><h3 class="sub" data-v-247f7c56>Composer</h3><p data-v-247f7c56>Unified into a single raised container: <code data-v-247f7c56>--radius-composer</code> (32px) with <code data-v-247f7c56>--corner-shape-composer: superellipse(1.5)</code> and a stable 0.5px edge. Focus crossfades a low-chroma line-and-accent edge over <code data-v-247f7c56>--duration-slow</code> with <code data-v-247f7c56>--ease-in-out</code>, while the neutral shadow stays unchanged — there is no added halo and no layout shift. The composer input (a ProseMirror contenteditable on desktop, a textarea on the web during the migration) uses <code data-v-247f7c56>text-autospace: normal</code> for mixed CJK and Latin input. Toolbar controls use a quiet 32px full-round geometry with 8px edge inset; the send button remains a standard 32px circle, with its glyph at 28px (<code data-v-247f7c56>--composer-send-icon-size</code>, the production kimi.com size; it sits outside the <code data-v-247f7c56>--p-ic-*</code> scale on purpose).</p><p data-v-247f7c56><b data-v-247f7c56>Fill and edge tokens</b>: the card's fill and rest border are their own tokens — <code data-v-247f7c56>--color-composer-bg</code> and <code data-v-247f7c56>--color-composer-line</code> — running the kimiwork / kimi.com production input recipe (<code data-v-247f7c56>.chat-input__shell</code>): fill = <code data-v-247f7c56>groupedBackground.secondary</code> (#ffffff light / #1f1f1f dark), rest border = <code data-v-247f7c56>separator.s1</code> (13% black / 12% white), focus line = <code data-v-247f7c56>fills.f4</code> (25% in both schemes), and <code data-v-247f7c56>--shadow-input</code> = <code data-v-247f7c56>effect.shadow.inputDefault</code> (<code data-v-247f7c56>0 5px 16px -4px rgba(0,0,0,0.07)</code>, kept identical in dark — the hairline carries the edge there). Only colours sit in the tokens; the 32px superellipse shape and the focus-only edge overlay are unchanged.</p><p data-v-247f7c56><b data-v-247f7c56>Send button tokens</b>: the send circle runs on <code data-v-247f7c56>--color-send-bg</code> / <code data-v-247f7c56>--color-send-bg-hover</code> / <code data-v-247f7c56>--color-send-icon</code> (+ <code data-v-247f7c56>*-disabled</code>, <code data-v-247f7c56>--opacity-send-disabled</code>, <code data-v-247f7c56>--shadow-send[-hover]</code>), following the production recipe (<code data-v-247f7c56>.chat-input__send</code>): a neutral <code data-v-247f7c56>labels.primary</code> fill (90% black light / 84% white dark, hover #252525 / 84.8%) with the production lift shadow (<code data-v-247f7c56>0 7px 16px -13px 38% + 0 1px 2px 7%</code>, one step larger on hover), a <code data-v-247f7c56>groupedBackground.secondary</code> glyph, and a disabled state of the same vocabulary — <code data-v-247f7c56>fills.f2</code> fill with a <code data-v-247f7c56>labels.quaternary</code> glyph at full opacity. The button is disabled exactly when submit would no-op — an empty draft with no ready attachment (image-only sends stay enabled), an upload in flight, or the starting spinner — so disabled is a first-class persistent state, never a fade.</p><p data-v-247f7c56><b data-v-247f7c56>Layering, anchors, and motion</b>: the dock normally stays at <code data-v-247f7c56>--z-sticky</code> so the Latest Messages pill can remain visible above its veil. While any Composer popup or work panel is open, the dock temporarily joins <code data-v-247f7c56>--z-dropdown</code>, ensuring permission, work-mode, and model menus — and the work panel — always paint above that pill. The permission menu's left edge and the model menu's right edge each follow their own trigger pill. All three menus use <code data-v-247f7c56>--shadow-menu</code> and the same trigger-corner pop motion as Session Row menus: 0.97 scale with a 2px shift toward the trigger, <code data-v-247f7c56>--duration-base</code> on entry, and <code data-v-247f7c56>--duration-fast</code> on exit.</p><p data-v-247f7c56><b data-v-247f7c56>Attachment strip</b>: attachments hang inside the composer card above the input as two grouped rows — images/videos as shared <code data-v-247f7c56>MediaThumb</code> rounded thumbnails, files as the shared <code data-v-247f7c56>AttachmentChip</code> pill — the same pair the sent bubble renders, so a draft looks exactly like the sent message. File-store videos render a static play tile instead of fetching a first frame. The strip caps at two thumbnail rows and scrolls beyond that instead of pushing the input down; while overflowing, a quiet count badge pins to the bottom-left and new attachments auto-scroll into view (to the end of whichever group grew). With two or more attachments, a one-click clear-all pins to the strip's top-right corner as a quiet 22px badge (trash glyph, danger on hover). The composer's pending preview and the bubble's media clicks open the same <code data-v-247f7c56>MediaLightbox</code> preview, which owns Escape via the shared dialog stack: images go through PhotoSwipe (<code data-v-247f7c56>@moonshot-ai/app-client</code>'s <code data-v-247f7c56>lib/mediaPreview</code>) and zoom out of the clicked thumbnail (scrim = <code data-v-247f7c56>--color-scrim-strong</code>, caption = <code data-v-247f7c56>--color-text-on-scrim</code>; the slide area is inset — 24px sides matching the video modal, 56px top/bottom clearing the close button and caption — so a viewport-filling image never kisses the edges), videos keep the custom modal. Both share the <code data-v-247f7c56>--color-scrim-strong</code> backdrop and the same close button — the raised 36px circle (<code data-v-247f7c56>.media-lightbox-close</code>) fixed at the viewport's top-right, rendered by <code data-v-247f7c56>MediaLightbox</code> for both (PhotoSwipe's own top bar is disabled; zoom stays on wheel / pinch / image click). ReadMedia tool cards open it too (an App-level instance fed by the <code data-v-247f7c56>openMedia</code> chain): the image zooms out of the card's thumbnail, and videos show as a static play tile that opens the modal player — no more right-side-panel detour or inline <code data-v-247f7c56><video></code>.</p><p data-v-247f7c56><b data-v-247f7c56>Mention pills</b>: @-mentions render as inline pills in the editor — one element of the cross-surface rich-text vocabulary specified in §05 <b data-v-247f7c56>Rich Text Messages</b> (visual recipe, wire forms, and behavior contract live there).</p>',12)),t("div",ya,[a[44]||(a[44]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Composer")],-1)),t("div",ka,[t("div",xa,[a[42]||(a[42]=t("div",{class:"p-composer-ta ph"},"Message Kimi, / to run a command, @ to reference a file…",-1)),t("div",Ta,[t("div",Sa,[a[39]||(a[39]=t("button",{class:"p-icon-btn"},[t("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[t("path",{fill:"currentColor",d:"M11 11V5h2v6h6v2h-6v6h-2v-6H5v-2z"})])],-1)),t("span",Ca,[s(d(o),{name:"shield-question",size:"sm"}),a[38]||(a[38]=e("yolo",-1))]),a[40]||(a[40]=t("span",{class:"p-pill"},[t("svg",{class:"p-ic",viewBox:"0 0 24 24",fill:"currentColor"},[t("path",{fill:"currentColor",d:"M8 4h13v2H8zM4.5 6.5a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 7a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m0 6.9a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3M8 11h13v2H8zm0 7h13v2H8z"})]),e("plan")],-1))]),a[41]||(a[41]=c('<div class="p-composer-right" data-v-247f7c56><span class="p-pill" data-v-247f7c56><span class="pp-strong" data-v-247f7c56>kimi-k2</span><span class="pp-sub" data-v-247f7c56>· thinking</span><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-247f7c56></path></svg></span><button class="p-send" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M13 7.828V20h-2V7.828l-5.364 5.364l-1.414-1.414L12 4l7.778 7.778l-1.414 1.414z" data-v-247f7c56></path></svg></button></div>',1))])]),a[43]||(a[43]=c('<div class="p-composer-strip" data-v-247f7c56><svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="M4 5a1 1 0 0 1 1-1h5l2 2h7a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V5z" data-v-247f7c56></path></svg>kimi-code-web<svg class="p-ic" viewBox="0 0 24 24" fill="currentColor" data-v-247f7c56><path fill="currentColor" d="m12 13.171l4.95-4.95l1.414 1.415L12 16L5.636 9.636L7.05 8.222z" data-v-247f7c56></path></svg></div>',1))])]),a[144]||(a[144]=c('<div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>Site-wide consistency</b>: the composer uses one 32px superellipse shell and one 32px desktop control height. The add (+), permission, compact, and model controls are all full-round and transparent at rest; hover reveals a neutral wash, open/active may use accent-soft, and Send remains the sole persistent filled control — an inverted <code data-v-247f7c56>--color-text</code> fill with a <code data-v-247f7c56>--color-bg</code> glyph (never the accent), disabled while the input is empty or an upload is in flight. The transparent dock floats over the transcript, while the scrolling content receives bottom padding equal to the live dock height so its final item can still clear the composer. Composer chrome is not selectable; only the message input permits text selection. Each permission mode has its own registry icon — manual <code data-v-247f7c56>hand</code>, yolo <code data-v-247f7c56>shield-question</code>, auto <code data-v-247f7c56>full-access</code> — paired with the label in the pill (the left cluster is rigid — its labels never ellipsize; once the row's only valve, the model name, is measured crushed below the readability floor, the stage machine flips the permission/swarm pills straight from full text to the accessible icon circle — computed from the live layout, never a fixed width — and flips them back with hysteresis) and leading its dropdown row in the mode's colour, with the current row's check trailing the row's end. The right toolbar holds the row's only valve: the model name ellipsizes as the toolbar tightens (the thinking suffix is never ellipsized — short effort words show in full or not at all — and the chevron never shrinks); each time it is measured crushed below the readability floor the stage advances one step — permission/swarm pills flip to icon circles, then, if it still doesn't fit, the model pill sheds its text and chevron for the bare <code data-v-247f7c56>model</code> icon (the tooltip carries the model + effort identity and the dropdown stays one tap away) — every transition computed from the live layout with em-based thresholds that track the font scale, unfolding with hysteresis as the pressure eases. The dock's work pills and panels — pill vocabulary, panel shell and motion, the two-tone head, per-kind bodies, filtering, and the open/cancel model — are specified in <b data-v-247f7c56>Dock · work pills & panels</b> below. </div></div><p data-v-247f7c56><b data-v-247f7c56>Workspace attachment card</b>: on the empty session, the workspace picker is a <b data-v-247f7c56>separate attachment card</b> tucked under the composer — and the composer card itself stays complete (its own 0.5px border, <code data-v-247f7c56>--radius-composer</code> corners with <code data-v-247f7c56>--corner-shape-composer</code>, and shadow are never altered). The attachment lives inside the composer's padding box as the card's sibling, so its width always matches; its top <code data-v-247f7c56>--space-4</code> slides behind the card (the card is raised to <code data-v-247f7c56>--z-sticky</code>), its square top edge stays hidden, and only the rounded bottom (<code data-v-247f7c56>0 0 --radius-xl --radius-xl</code>) shows. Background <code data-v-247f7c56>--color-hover</code> at 60% via <code data-v-247f7c56>color-mix</code> (≈0.03 black in light, self-adapting in dark), no border, no shadow. Inside sits one quiet capsule trigger: transparent, <code data-v-247f7c56>--radius-full</code>, 16px leading icon and 12px label at weight 475 in <code data-v-247f7c56>--color-text-muted</code>; hover deepens to <code data-v-247f7c56>--color-selected</code> and the label turns <code data-v-247f7c56>--color-text</code>. The dropdown follows the §03 menu spec and is viewport-aware (flips above when more room, clamps max-height to the scrollport); at <code data-v-247f7c56>--z-dropdown</code> it outranks both the card and the fixed click-outside backdrop (<code data-v-247f7c56>--z-sticky</code>), which renders outside the composer because the card's <code data-v-247f7c56>container-type</code> captures <code data-v-247f7c56>position: fixed</code> descendants.</p><h3 class="sub" data-v-247f7c56>Autocomplete menus</h3><p data-v-247f7c56>The slash, mention, and add popups share one geometry, all on dedicated tokens: the <code data-v-247f7c56>--color-menu-bg-frost</code> surface (the frostier recipe), frame padding <code data-v-247f7c56>--menu-row-hug</code>, rows at <code data-v-247f7c56>--menu-row-padding-block</code> × <code data-v-247f7c56>--menu-row-padding-inline</code> with <code data-v-247f7c56>--radius-menu-row</code> caps (plain corners — the frame is <code data-v-247f7c56>--radius-lg</code> with NO corner-shape, and the row radius stays concentric: 12px frame − 6px hug = 6px), an icon-to-label gap of <code data-v-247f7c56>--menu-row-gap-icon</code>, and a <code data-v-247f7c56>--menu-rows-seam</code> between stacked rows. Touch rows pad to <code data-v-247f7c56>--menu-row-touch-padding-block</code> with a hard floor of <code data-v-247f7c56>--touch-target-min</code>. Scroll height caps at <code data-v-247f7c56>--p-slash-menu-h</code> / <code data-v-247f7c56>--p-mention-menu-h</code> / <code data-v-247f7c56>--p-add-menu-h</code>; the scroll-edge fade is <code data-v-247f7c56>--menu-scroll-fade</code>, and the overlay thumb rides <code data-v-247f7c56>--menu-scrollbar-width</code> / <code data-v-247f7c56>--menu-scrollbar-edge</code> / <code data-v-247f7c56>--menu-scrollbar-track-inset</code> / <code data-v-247f7c56>--menu-scrollbar-thumb-min</code> in <code data-v-247f7c56>--color-menu-scrollbar</code> (hover <code data-v-247f7c56>--color-menu-scrollbar-hover</code>) — 3px visually, with a wider invisible drag strip.</p><h3 class="sub" data-v-247f7c56>Add menu</h3><p data-v-247f7c56>The composer's <b data-v-247f7c56>+ button</b> opens the add menu — the autocomplete family's action-list member: one column of icon + label (+ muted description) rows (Files, Goal, Plan, Swarm) on the same frost surface and row geometry as the slash/mention popups, capped at <code data-v-247f7c56>--p-add-menu-h</code>. Semantically it is an action menu, not an autocomplete listbox: rows are <code data-v-247f7c56>menuitem</code> commands, DOM focus moves into the menu (arrows navigate, Enter activates, Escape closes), and the + button carries <code data-v-247f7c56>aria-haspopup="menu"</code> — the textarea's combobox ARIA never points at it.</p><p data-v-247f7c56><b data-v-247f7c56>Design decision: deliberately NOT the §03 Menu/MenuItem primitives.</b> Those are the trigger-dropdown family (sidebar, user menu, session rows) — <code data-v-247f7c56>--color-menu-bg</code>, <code data-v-247f7c56>--radius-lg</code>, a min-width box. The add menu instead shares the composer menus' material (the frostier surface, the composer corner curve, rows hugging the frame at the composer's text column, muted description sub-lines). Bending MenuItem into that material would require exactly the per-screen appearance overrides the primitive contract forbids, so the add menu keeps bespoke rows built directly on the shared <code data-v-247f7c56>--menu-row-*</code> tokens. This paragraph is the canonical record of that choice — reviews should not re-litigate it.</p>',7)),t("div",za,[a[52]||(a[52]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Add menu — family surface, icon + label + desc rows, keyboard focus wash")],-1)),t("div",qa,[t("div",Aa,[t("span",Ba,[s(d(o),{name:"attachment",size:"sm"}),a[45]||(a[45]=t("span",{class:"n"},"Files",-1))]),t("span",Ma,[s(d(o),{name:"target",size:"sm"}),a[46]||(a[46]=t("span",{class:"n"},"Goal",-1)),a[47]||(a[47]=t("span",{class:"d"},"Set a goal to keep pursuing",-1))]),t("span",Ia,[s(d(o),{name:"file-edit",size:"sm"}),a[48]||(a[48]=t("span",{class:"n"},"Plan",-1)),a[49]||(a[49]=t("span",{class:"d"},"Turn plan mode on",-1))]),t("span",Ea,[s(d(o),{name:"sparkles",size:"sm"}),a[50]||(a[50]=t("span",{class:"n"},"Swarm",-1)),a[51]||(a[51]=t("span",{class:"d"},"Turn swarm mode on",-1))])])])]),a[145]||(a[145]=c('<h3 class="sub" data-v-247f7c56>Work modes</h3><p data-v-247f7c56><b data-v-247f7c56>Plan and Goal are the primary work modes — mutually exclusive, at most one armed at a time.</b> Arming happens only through the slash commands (<code data-v-247f7c56>/plan</code>, <code data-v-247f7c56>/goal</code>) or the add menu; an armed mode renders as the input row's leading pill — a neutral <code data-v-247f7c56>--color-surface</code> chip with the mode's 14px icon, its label, and a × that disarms. The × is an IconButton sized <code data-v-247f7c56>--wm-x-size</code> (below the sm default, so its hover wash never outgrows the pill's rounded end) with a <code data-v-247f7c56>--wm-x-ring</code> hit reserve that stays inside the textarea's indent; on touch it meets <code data-v-247f7c56>--touch-target-min</code>. The input's first-line text indent reserves exactly the pill's width (the desktop ProseMirror editor applies it to the first paragraph), so the caret and placeholder slide right rather than colliding; arming Goal also swaps the placeholder to its objective prompt. Sending with Goal armed creates the goal and the pill hands off to the dock's goal pill; a live goal does NOT lock the primary modes — <code data-v-247f7c56>/goal</code> then just focuses the goal's panel, and <code data-v-247f7c56>/plan</code> still arms (the only hard rule: one message cannot both create a goal and enter plan — the goal write carries the plan disarm atomically — and a failed mode write is treated as a send failure: the optimistic message rolls back, the error toasts). Swarm is deliberately NOT a mode: an orthogonal toolbar chip with its own enable confirmation, disarmed from the chip's ×.</p><h3 class="sub" data-v-247f7c56>Dock · work pills & panels</h3><p data-v-247f7c56><b data-v-247f7c56>Work pills</b> (<code data-v-247f7c56>WorkPill.vue</code>): the dock's workbar above the composer carries one pill vocabulary — font-driven by flex computation: the 1.5em leading icon and the label's own line box (<code data-v-247f7c56>--text-base</code> at <code data-v-247f7c56>--leading-normal</code>) both come to 21px at the 14px UI text, and 8px block padding wraps them to 37px, nothing pinning pixels, so the pills rescale with the font; borderless, with <code data-v-247f7c56>--radius-lg</code> rounded-square corners, filled at the fills ladder's <code data-v-247f7c56>--color-selected</code> rung over the shared <code data-v-247f7c56>--p-menu-backdrop</code> blur — the panel's frosted recipe scaled down to a chip, so transcript text never reads through the light fill (the neutral hover wash layers on top — one layer, never two), the icon at full text colour, <code data-v-247f7c56>--space-2</code> / <code data-v-247f7c56>--space-3</code> block / inline padding — the trailing side adds a <code data-v-247f7c56>--space-05</code> optical compensation against the leading glyph — and a <code data-v-247f7c56>--space-1-5</code> content gap. Every pill stays expanded — the Code client does not collapse status chips — carrying icon + label and a trailing meta that answers one question — what is live on this surface right now — for background bash tasks, background sub-agents, todos, and the goal alike; the row insets to the composer's text column — dock inline inset + the card's 0.5px border + the input wrap's 16px inline padding — not the card edge. The active pill keeps the wash on permanently — one fills-ladder step deeper, neutral. The meta is always muted ink and surface-specific: the goal carries its status word, colour-coded by state (active <code data-v-247f7c56>--color-success</code>, paused <code data-v-247f7c56>--color-warning</code>, blocked <code data-v-247f7c56>--color-danger</code>); the bash and sub-agent pills carry a pulsing dot and the running count, only while something runs (a quiet absence otherwise); the todos carry the done/total fraction. The plan pill joins the row only once plan mode is live server-side or a persisted plan exists — a merely armed directive stays in the composer's inline work-mode pill (its × cancels) and never reaches this bar, so every pill here reads as live server truth rather than local intent. Narrow panes wrap the row instead of clipping (the dock height observes); below the <code data-v-247f7c56>--p-bp-sm</code> breakpoint the pills collapse to their icons — label and meta hide (the threshold is read from the token, never a hardcoded width).</p><p data-v-247f7c56><b data-v-247f7c56>Panel shell & motion</b>: a pill toggles the shared work panel — the menu family material: 70% page background via <code data-v-247f7c56>color-mix</code> over the shared <code data-v-247f7c56>--p-menu-backdrop</code> blur (the frostier recipe, see §06 Glassmorphism exemption), a 0.5px <code data-v-247f7c56>--color-line</code> edge, <code data-v-247f7c56>--radius-2xl</code>, and the menu panel's <code data-v-247f7c56>--shadow-menu</code>. The panel pops from the clicked pill along the trigger-corner motion tokens (<code data-v-247f7c56>--motion-panel-scale</code> / <code data-v-247f7c56>--motion-panel-shift</code>), and switching pills replays the pop from the newly clicked pill (the shell is keyed by panel kind); while it is open the dock raises to <code data-v-247f7c56>--z-dropdown</code> so it clears the transcript's new-message pill, and every window-drag strip pauses so an outside press reaches the page and dismisses. The panel owns Escape while open (a document-capture handler guarded by the shared IME latch, so a candidate-cancelling Escape is never swallowed), and a scrolled body dissolves toward the head through the <code data-v-247f7c56>--menu-scroll-fade</code> alpha mask instead of hard-clipping. Height is content-sized up to <code data-v-247f7c56>min(360px, 50vh)</code>; the filtered panels pin instead — see Filtering & sizing. The panel is chrome: nothing inside it is text-selectable, the head's filter chips included.</p><p data-v-247f7c56><b data-v-247f7c56>Panel head</b> (<code data-v-247f7c56>WorkPanelHead.vue</code>): every work panel head is one tab row — a leading icon at the pill's 1.5em glyph size, the panel title at full text colour, and a muted trailing meta (<code data-v-247f7c56>--color-text-muted</code>) carrying that panel's one live number, joined by the row's <code data-v-247f7c56>--space-2</code> gap with no separator glyph: the goal's wall-clock time, the bash / sub-agent running count, the todos' done/total. Actions right-align in the head: the goal's pause / resume / cancel / close as quiet neutral IconButtons (cancel deliberately shares that neutral vocabulary), the plan's open-in-side-panel, dismiss-directive (shown only while the directive is live), and close, and the bash / sub-agent filter chips as a SegmentedControl. The plan head's meta carries the latest plan's review outcome. On touch these meet the 44px minimum (<code data-v-247f7c56>--touch-target-min</code>) via the <code data-v-247f7c56>hover: none</code> capability query — a width-only gate would miss tablets — and below 480px the head wraps so the actions take a full row.</p><p data-v-247f7c56><b data-v-247f7c56>Panel bodies</b>: todos read as a quiet list — a green <code data-v-247f7c56>circle-check</code> for done, a hollow ring for pending, an xs Spinner for in-progress. The goal's detail (full objective, completion criterion, rendered with the chat Markdown renderer) fills the body — no footer strip. Bash tasks are long rows (<code data-v-247f7c56>TasksPane.vue</code>): a StatusDot while running, <code data-v-247f7c56>circle-check</code> when done, a close glyph for failed and for cancelled (a user stop is neutral, never reported as a failure), the command as the meta line, and a bare duration that renders only when computable — never the raw protocol status word. Sub-agents form a card grid (<code data-v-247f7c56>SubagentGrid.vue</code>) — an auto-fill grid (minmax <code data-v-247f7c56>--p-subagent-card-min</code>) of cards at the <code data-v-247f7c56>--color-selected</code> rung with <code data-v-247f7c56>--radius-lg</code> corners; each card carries the task name, a stable session-wide number (creation order across the session's background sub-agents — unique even across swarms; once shown it sticks, so late-arriving history takes the next tail number), an optional prompt meta line one size down (<code data-v-247f7c56>--text-sm</code>), an icon-led model · effort line and the status row a further size down (<code data-v-247f7c56>--text-xs</code>) — the status row pairs the task-row state glyph with the localized label, plus a clock-led bare duration that renders only when computable; the full-bleed <code data-v-247f7c56>circle-check</code> (drawn for the todo rows' ring family) is scaled onto the shared icon grid wherever it sits beside other glyphs (task rows, cards, filter chips). A failed row tints its name <code data-v-247f7c56>--color-danger</code>; a cancelled one stays neutral. Rows hover with a rounded strip that grows by padding and a matching negative margin — the row metrics never shift. The row stop is danger-coloured; the card cancel reveals on hover and is always visible on touch as a <code data-v-247f7c56>--touch-target-min</code> corner target. Every pane's empty state is centered and muted. State and time labels — the head meta included — set <code data-v-247f7c56>text-autospace: normal</code>, the transcript's mixed CJK/numeric spacing rule, so durations like 9小时2分 breathe.</p><p data-v-247f7c56><b data-v-247f7c56>State vocabulary</b>: two glyph families meet here by design — the activity dot (shared with the transcript's tool rows and swarm members) backs the task rows, the todo rows speak the default loader ring, and the sub-agent cards skip glyphs in favour of a localized text label:</p>',8)),t("table",Da,[a[89]||(a[89]=t("thead",null,[t("tr",null,[t("th",null,"Surface"),t("th",null,"State"),t("th",null,"Meaning"),t("th",null,"Glyph"),t("th",null,"Ink")])],-1)),t("tbody",null,[t("tr",null,[a[54]||(a[54]=t("td",null,"Bash rows",-1)),a[55]||(a[55]=t("td",{class:"tk"},"running",-1)),a[56]||(a[56]=t("td",null,"Task in flight",-1)),t("td",null,[s(d(u),{status:"running"}),a[53]||(a[53]=e(" pulsing dot",-1))]),a[57]||(a[57]=t("td",null,[t("code",null,"--color-accent")],-1))]),t("tr",null,[a[60]||(a[60]=t("td",null,null,-1)),a[61]||(a[61]=t("td",{class:"tk"},"done",-1)),a[62]||(a[62]=t("td",null,"Finished cleanly",-1)),t("td",null,[s(d(o),{name:"circle-check",size:"sm"}),a[58]||(a[58]=e()),a[59]||(a[59]=t("code",null,"circle-check",-1))]),a[63]||(a[63]=t("td",null,[t("code",null,"--color-success")],-1))]),t("tr",null,[a[66]||(a[66]=t("td",null,null,-1)),a[67]||(a[67]=t("td",{class:"tk"},"failed",-1)),a[68]||(a[68]=t("td",null,"Errored — the row's name tints to match",-1)),t("td",null,[s(d(o),{name:"close",size:"sm"}),a[64]||(a[64]=e()),a[65]||(a[65]=t("code",null,"close",-1))]),a[69]||(a[69]=t("td",null,[t("code",null,"--color-danger")],-1))]),t("tr",null,[a[72]||(a[72]=t("td",null,null,-1)),a[73]||(a[73]=t("td",{class:"tk"},"cancelled",-1)),a[74]||(a[74]=t("td",null,"User stop — neutral, never a failure",-1)),t("td",null,[s(d(o),{name:"close",size:"sm"}),a[70]||(a[70]=e()),a[71]||(a[71]=t("code",null,"close",-1))]),a[75]||(a[75]=t("td",null,[t("code",null,"--color-text-muted")],-1))]),t("tr",null,[a[77]||(a[77]=t("td",null,"Todo rows",-1)),a[78]||(a[78]=t("td",{class:"tk"},"in_progress",-1)),a[79]||(a[79]=t("td",null,"Being worked on",-1)),t("td",null,[t("span",Oa,[s(d(D),{size:"xs"})]),a[76]||(a[76]=e(" xs Spinner ring",-1))]),a[80]||(a[80]=t("td",null,[e("the row's own ink ("),t("code",null,"--color-text"),e(")")],-1))]),a[87]||(a[87]=t("tr",null,[t("td"),t("td",{class:"tk"},"pending"),t("td",null,"Not started"),t("td",null,[t("span",{class:"dw-ring"}),e(" hollow ring")]),t("td",null,[t("code",null,"--color-line-strong"),e(" stroke")])],-1)),t("tr",null,[a[83]||(a[83]=t("td",null,null,-1)),a[84]||(a[84]=t("td",{class:"tk"},"done",-1)),a[85]||(a[85]=t("td",null,"Completed",-1)),t("td",null,[s(d(o),{name:"circle-check",size:"md"}),a[81]||(a[81]=e()),a[82]||(a[82]=t("code",null,"circle-check",-1))]),a[86]||(a[86]=t("td",null,[t("code",null,"--color-success")],-1))]),a[88]||(a[88]=t("tr",null,[t("td",null,"Sub-agent cards"),t("td",{class:"tk"},"all"),t("td",null,"The task-row glyph plus a localized label — failed alone tints danger — with a clock-led bare duration trailing"),t("td",null,"glyph + label"),t("td",null,"muted / danger")],-1))])]),a[146]||(a[146]=c("<p data-v-247f7c56><b data-v-247f7c56>Filtering & sizing</b>: the bash and sub-agent heads carry the same four icon-led filter chips — recent (<code data-v-247f7c56>clock</code>; running + the five most recently finished), running (<code data-v-247f7c56>play</code>), done (<code data-v-247f7c56>circle-check</code>; every terminal state), all (<code data-v-247f7c56>list</code>) — and both filtered panels pin to <code data-v-247f7c56>--p-dock-panel-h</code> so filtering never resizes the panel; the body scrolls inside. When the head runs out of room the chips collapse into a dropdown menu (<code data-v-247f7c56>FilterControl.vue</code> measures the head itself, so the switch follows the panel's own width, not the viewport; the menu teleports to <code data-v-247f7c56><body></code> and anchors to the trigger, so the panel's clip and backdrop-filter never squeeze it); the head title never wraps and is never clipped — once the filter is a dropdown the head always fits. An empty pane names its filter (no completed tasks is not no tasks).</p><p data-v-247f7c56><b data-v-247f7c56>Opening & cancelling</b>: clicking a row or card opens the task's detail in the right-side panel. Opening is gated: the overlay navigation button renders only when a stable <code data-v-247f7c56>agentId</code> (on-demand transcript) or locally held output exists, so a REST-only cold-loaded row stays inert instead of opening an empty panel — and says so with the not-allowed cursor. Open and cancel are sibling controls (a full-cover overlay button, the stop IconButton floating above it): no nested interactives, and the stop action exists only while the task runs.</p>",2)),t("div",Ha,[a[100]||(a[100]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Work pills — one vocabulary, a live count or status where one exists")],-1)),t("div",Ra,[t("div",Va,[t("span",La,[s(d(o),{name:"target",size:"md"}),a[90]||(a[90]=t("span",null,"Goal",-1)),a[91]||(a[91]=e()),a[92]||(a[92]=t("span",{class:"dw-live"},"Active",-1))]),t("span",Na,[s(d(o),{name:"terminal",size:"md"}),a[93]||(a[93]=t("span",null,"Bash",-1))]),t("span",Wa,[s(d(o),{name:"sparkles",size:"md"}),a[95]||(a[95]=t("span",null,"Background Agent",-1)),a[96]||(a[96]=e()),t("span",Pa,[s(d(u),{status:"running"}),a[94]||(a[94]=e("3",-1))])]),t("span",Ua,[s(d(o),{name:"list",size:"md"}),a[97]||(a[97]=t("span",null,"Progress",-1)),a[98]||(a[98]=e()),a[99]||(a[99]=t("span",{class:"dw-count"},"3/7",-1))])])])]),t("div",Fa,[a[141]||(a[141]=t("div",{class:"stage-bar"},[t("span",{class:"st"},"Work panels — two-tone head, filter chips, rows & card grid")],-1)),t("div",ja,[t("div",Ga,[t("div",Ka,[t("span",Ja,[s(d(o),{name:"terminal",size:"md"}),a[101]||(a[101]=e("Bash ",-1)),a[102]||(a[102]=t("span",{class:"dw-meta"},"1 running",-1))]),t("span",Ya,[t("span",Qa,[s(d(o),{name:"clock",size:"sm"}),a[103]||(a[103]=e("Recent",-1))]),t("span",Xa,[s(d(o),{name:"play",size:"sm"}),a[104]||(a[104]=e("Running",-1))]),t("span",Za,[s(d(o),{name:"circle-check",size:"sm"}),a[105]||(a[105]=e("Done",-1))]),t("span",$a,[s(d(o),{name:"list",size:"sm"}),a[106]||(a[106]=e("All",-1))])])]),t("div",_a,[t("div",at,[s(d(u),{status:"running"}),a[107]||(a[107]=t("span",{class:"nm"},"pnpm test -- --watch",-1)),a[108]||(a[108]=t("span",{class:"tm"},"0:42",-1))]),t("div",tt,[s(d(o),{name:"circle-check",size:"sm",class:"ok"}),a[109]||(a[109]=t("span",{class:"nm"},"pnpm run build",-1)),a[110]||(a[110]=t("span",{class:"tm"},"3m12s",-1))]),t("div",et,[s(d(o),{name:"close",size:"sm"}),a[111]||(a[111]=t("span",{class:"nm"},"pnpm lint",-1)),a[112]||(a[112]=t("span",{class:"tm"},"1m05s",-1))]),t("div",st,[s(d(o),{name:"close",size:"sm"}),a[113]||(a[113]=t("span",{class:"nm"},"node scripts/migrate.mjs",-1)),a[114]||(a[114]=t("span",{class:"tm"},"0:18",-1))])])]),t("div",dt,[t("div",ot,[t("span",ct,[s(d(o),{name:"sparkles",size:"md"}),a[115]||(a[115]=e("Background Agent ",-1)),a[116]||(a[116]=t("span",{class:"dw-meta"},"1 running",-1))]),t("span",it,[t("span",nt,[s(d(o),{name:"clock",size:"sm"}),a[117]||(a[117]=e("Recent",-1))]),t("span",lt,[s(d(o),{name:"play",size:"sm"}),a[118]||(a[118]=e("Running",-1))]),t("span",rt,[s(d(o),{name:"circle-check",size:"sm"}),a[119]||(a[119]=e("Done",-1))]),t("span",vt,[s(d(o),{name:"list",size:"sm"}),a[120]||(a[120]=e("All",-1))])])]),t("div",ft,[t("div",ht,[a[124]||(a[124]=t("div",{class:"ct"},[t("span",{class:"nu"},"01"),t("span",{class:"nm"},"Explore the auth module")],-1)),a[125]||(a[125]=t("div",{class:"ds"},"Map every callsite of the legacy token refresh and report findings",-1)),t("div",pt,[t("div",ut,[s(d(o),{name:"robot",size:"sm"}),a[121]||(a[121]=t("span",null,"kimi-k2 · thinking",-1))]),t("div",gt,[t("span",mt,[s(d(u),{status:"running"}),a[122]||(a[122]=e("Running",-1))]),t("span",bt,[s(d(o),{name:"clock",size:"sm"}),a[123]||(a[123]=e("0:42",-1))])])])]),t("div",wt,[a[129]||(a[129]=t("div",{class:"ct"},[t("span",{class:"nu"},"02"),t("span",{class:"nm"},"Draft the release notes")],-1)),a[130]||(a[130]=t("div",{class:"ds"},"Summarize the merged PRs since the last tag into user-facing notes",-1)),t("div",yt,[t("div",kt,[s(d(o),{name:"robot",size:"sm"}),a[126]||(a[126]=t("span",null,"kimi-k2 · thinking",-1))]),t("div",xt,[t("span",Tt,[s(d(o),{name:"circle-check",size:"sm",class:"ok"}),a[127]||(a[127]=e("Done",-1))]),t("span",St,[s(d(o),{name:"clock",size:"sm"}),a[128]||(a[128]=e("3m12s",-1))])])])]),t("div",Ct,[a[134]||(a[134]=t("div",{class:"ct"},[t("span",{class:"nu"},"03"),t("span",{class:"nm"},"Run the integration tests")],-1)),a[135]||(a[135]=t("div",{class:"ds"},"pnpm test against the staging daemon",-1)),t("div",zt,[t("div",qt,[s(d(o),{name:"robot",size:"sm"}),a[131]||(a[131]=t("span",null,"kimi-k2 · thinking",-1))]),t("div",At,[t("span",Bt,[s(d(o),{name:"close",size:"sm"}),a[132]||(a[132]=e("Failed",-1))]),t("span",Mt,[s(d(o),{name:"clock",size:"sm"}),a[133]||(a[133]=e("1m05s",-1))])])])]),t("div",It,[a[139]||(a[139]=t("div",{class:"ct"},[t("span",{class:"nu"},"04"),t("span",{class:"nm"},"Migrate the config files")],-1)),a[140]||(a[140]=t("div",{class:"ds"},"Rewrite the workspace configs to the new schema",-1)),t("div",Et,[t("div",Dt,[s(d(o),{name:"robot",size:"sm"}),a[136]||(a[136]=t("span",null,"kimi-k2 · thinking",-1))]),t("div",Ot,[t("span",Ht,[s(d(o),{name:"close",size:"sm"}),a[137]||(a[137]=e("Cancelled",-1))]),t("span",Rt,[s(d(o),{name:"clock",size:"sm"}),a[138]||(a[138]=e("0:18",-1))])])])])])])])]),a[147]||(a[147]=t("h3",{class:"sub"},"Responsive",-1)),a[148]||(a[148]=t("p",null,[e("See §02 "),t("code",null,"--p-bp-sm"),e(" for the breakpoint. This section only gives mobile-adaptation pointers for the chat interface; a full mobile mockup is out of scope for this spec.")],-1)),a[149]||(a[149]=t("div",{class:"callout info"},[t("span",{class:"ico"},"i"),t("div",null," At ≤640px: dialogs anchor to the bottom as Sheets (xl top radius, top drag handle), the sidebar collapses into an expandable drawer, the Composer toolbar is allowed to wrap, and the chat reading column drops its max-width to fill the screen. ")],-1))]),a[151]||(a[151]=c('<section id="richtext" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>05</span><h2 class="sec-title" data-v-247f7c56>Rich Text Messages</h2></div><p class="sec-desc" data-v-247f7c56> Structured references travel as <b data-v-247f7c56>plain text on the wire</b> and render as <b data-v-247f7c56>pills at both ends</b>: the composer's editing surface and the rendered message stream share one pill vocabulary, so what you type is what the message shows. This section is the category spec — every future rich-text element (marks, embeds, interactive chips) joins it here. </p><h3 class="sub" data-v-247f7c56>Mention pill</h3><p data-v-247f7c56>The mention is the first rich-text element. It exists in two synchronized forms: an <b data-v-247f7c56>atom</b> inside the desktop composer's ProseMirror document, and a <b data-v-247f7c56>pill in the message stream</b> — assistant Markdown decorates local links with the same classes, and user/queue bubbles (verbatim wire text, never Markdown) render through the declarative <code data-v-247f7c56>ComposerText</code> component. Both are the same mark: <b data-v-247f7c56>not a filled chip</b> — no background, no vertical padding — just body text in a heavier weight (<code data-v-247f7c56>--weight-ui-strong</code>) on a lighter ink (<code data-v-247f7c56>--color-text-muted</code>), so the baseline stays flush with the surrounding text; a 2px horizontal inset (<code data-v-247f7c56>padding-inline: var(--space-05)</code>) supplies the CJK/Latin autospacing that can't cross element boundaries and sets the mention apart from plain text; a 13px muted <b data-v-247f7c56>kind glyph</b> leads, and the label is the <b data-v-247f7c56>basename</b> — never the full path, which lives on the tooltip. Hover deepens the ink (glyph included) toward <code data-v-247f7c56>--color-text</code> on every surface; in the message stream the clickable kinds (file, skill) also take the pointer cursor and the link underline, while the composer keeps pure editing semantics — I-beam, no underline, a click just places the caret. The shared classes live in app-ui's global sheet; the kind → glyph mapping is single-sourced in app-composer (<code data-v-247f7c56>mentionIcons</code>) and also drives the mention menu rows, so a file looks identical in the menu, the editor, and the sent bubble. Copying from a bubble re-serializes the selection back to the wire text — pills carry their full attrs in <code data-v-247f7c56>data-mention-*</code>, so a copy/paste round trip restores the link instead of a truncated basename.</p><p data-v-247f7c56><b data-v-247f7c56>Kinds and wire forms</b> (serialization is a Markdown link, so the daemon payload stays plain text and the TUI needs nothing new):</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Kind</th><th data-v-247f7c56>Glyph</th><th data-v-247f7c56>Wire form</th><th data-v-247f7c56>Click (in messages)</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td data-v-247f7c56>File</td><td data-v-247f7c56>single folded-corner file glyph for every file (no per-extension variants)</td><td data-v-247f7c56><code data-v-247f7c56>[name](path)</code> — the dest is canonically encoded per path segment (every non-unreserved ASCII character → <code data-v-247f7c56>%XX</code>; non-ASCII stays literal, so a CJK path reads as itself — one <code data-v-247f7c56>decodeURIComponent</code> restores it on every surface)</td><td data-v-247f7c56>opens the file preview</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Folder</td><td data-v-247f7c56>folder glyph</td><td data-v-247f7c56><code data-v-247f7c56>[name](path/)</code> — trailing slash marks the kind (dest <code data-v-247f7c56>%</code> → <code data-v-247f7c56>%25</code> as above)</td><td data-v-247f7c56>inert (no target yet)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Skill</td><td data-v-247f7c56>sparkling glyph</td><td data-v-247f7c56><code data-v-247f7c56>[name](kimi-code://skill/<name>)</code> — the app's deep-link protocol</td><td data-v-247f7c56>opens the skill's SKILL.md in the preview panel</td></tr></tbody></table><p data-v-247f7c56><b data-v-247f7c56>Hover tooltip</b>: one document-level singleton (<code data-v-247f7c56>mentionTooltip</code>) serves every pill — composer NodeViews, ComposerText-rendered bubbles, and Markdown anchors are all raw DOM a Vue wrapper can't reach, so it delegates on document mouseover into a single shared bubble. The bubble keeps the design-system tooltip's dark skin but is <b data-v-247f7c56>interactive</b>. File and folder pills show the <b data-v-247f7c56>full path</b>, wrapping anywhere within a fixed max width: every <code data-v-247f7c56>/</code> separator muted, the basename bold (<code data-v-247f7c56>--weight-semibold</code>). Skill pills show a card — the name with an <b data-v-247f7c56>open button</b> at the right (opens the skill's SKILL.md in the preview panel; the path rides the wire skill descriptor through <code data-v-247f7c56>AppSkill.path</code>), the description below, clamped to four lines; an unresolvable skill degrades to the name alone. Timing mirrors TooltipBubble (150ms show delay, top placement with flip, viewport clamping) and the bubble stays open while hovered so the button is reachable; native <code data-v-247f7c56>title</code> tooltips are removed wherever a pill appears. The bubble is a <b data-v-247f7c56>documented structural exception</b> to the component-primitive rule (like the dock overlay): its anchors are ProseMirror NodeViews and pillified spans a Vue wrapper can't reach, so the open/copy buttons re-implement the Button primitive's contract (size, hover, <code data-v-247f7c56>:focus-visible</code> ring) by hand instead of importing it.</p><p data-v-247f7c56><b data-v-247f7c56>Edge cases</b>: labels cap at 32 chars — a longer name takes a <b data-v-247f7c56>middle ellipsis</b> that keeps the head of the base name and the whole extension (the full name stays in the data attributes, the full path on the tooltip). A pill whose target was deleted after the fact: hovering fires a one-byte <b data-v-247f7c56>existence probe</b> (an inline spinner sits at the tail of the tooltip's path text while in flight), and a definitive not-found fades the pill and strikes it through — in messages and in the composer alike. Clicks are never gated on the verdict (the preview's own not-found state is the final answer); only confirmed-existing verdicts are cached, scoped to the session, so a recreated file recovers on the next hover and a flaky daemon can never strike a pill by mistake.</p><p data-v-247f7c56><b data-v-247f7c56>Behavior contract</b>: a bare <code data-v-247f7c56>@</code> opens the menu instantly with the workspace root listing (Esc dismisses); with a query, the menu is ONE merged list — no sections — ranked by match strength: exact skill > prefix skill > strong file hits (substring-or-better on the basename; a query containing <code data-v-247f7c56>/</code> matches path segments and is always strong) > substring skill > subsequence skill (tokens of 3+ chars, separator-bridging — <code data-v-247f7c56>larkim</code> matches <code data-v-247f7c56>lark-im</code>) > weak file hits (a bare subsequence), with the search firing per keystroke (rg-backed <code data-v-247f7c56>fs:suggest</code>, no debounce; older daemons fall back to <code data-v-247f7c56>fs:search</code>). An in-flight search never hides the current rows (a corner spinner marks it; superseded rows dim as stale and stay unselectable until fresh results land). File and skill rows highlight the matched characters with ink emphasis only — semibold strong ink in the name, body ink in the muted directory, never a background, so the row rhythm never shifts. The default highlight is simply the top row of the ranking — skill rows included — and follows its row by identity across async landings. Full-width <code data-v-247f7c56>@</code> from IMEs triggers identically. Insertion replaces the @token and adds a separating trailing space; the pill is one atom — Backspace removes it whole, and a zero-width caret anchor keeps the caret on the pill's line when it ends a paragraph. Drafts, history recall, and queue reloads revive pills from their link form on load, and pasting mention-link text (e.g. a copied pill) revives them too — the serializer round-trips both ways. <b data-v-247f7c56>Skill activation</b>: sending a message with exactly one skill pill activates that skill via the existing channel (the pill form of <code data-v-247f7c56>/skill:<name></code>, the full text — the pill traveling as its mention link — becomes the args, attachments ride along), and the sent bubble shows the original message verbatim with the pill revived in place (a slash-typed activation, whose bare args carry no pill, keeps the identity card instead); two or more skill pills degrade to plain references, because each activation is its own turn.</p><p data-v-247f7c56><b data-v-247f7c56>Implementation map</b>: schema/serialization/offset mapping in app-composer's <code data-v-247f7c56>composerTextDoc</code> (pure, node-tested); the editor surface in <code data-v-247f7c56>composerEditor</code>; user/queue bubbles render via app-composer's <code data-v-247f7c56>ComposerText</code> (one segment pass, declarative tree — no post-processing); assistant-side classification (<code data-v-247f7c56>classifyMentionHref</code>) and decoration in app-markdown's <code data-v-247f7c56>Markdown.vue</code> link pass; hover + skill-click routing in app-composer's <code data-v-247f7c56>mentionTooltip</code> singleton, wired per app shell. When editing these, keep the two surfaces in lockstep — a pill that serializes one way in the composer must read the same way in a message.</p></section><section id="themes" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>06</span><h2 class="sec-title" data-v-247f7c56>Theming</h2></div><p class="sec-desc" data-v-247f7c56> Kimi Web uses <b data-v-247f7c56>one unified theme</b>: the same components, fonts, radii, shadows, and surfaces — theming only swaps color values. Every semantic color token ships a light value in <code data-v-247f7c56>:root</code> and a dark override in the <code data-v-247f7c56>data-color-scheme</code> blocks; the semantic status colors (success / warning / danger) are independent palettes, one set each for light / dark. </p><h3 class="sub" data-v-247f7c56>Accent</h3><p data-v-247f7c56>The app has <b data-v-247f7c56>one accent</b>: the brand blue (<code data-v-247f7c56>--color-accent</code>, <code data-v-247f7c56>#1783ff</code> light / <code data-v-247f7c56>#58a6ff</code> dark). Use it sparingly — the accent is reserved for the primary action, focus rings, links, and active marks (current tab, toggles); large fills always come from the neutral surface tokens. Selection that means "where I am" (sidebar rows, list pickers) is deliberately NOT accent-tinted — it uses <code data-v-247f7c56>--color-selected</code> so it reads as location, not as an action.</p><h3 class="sub" data-v-247f7c56>Light / dark mode</h3><p data-v-247f7c56>Each semantic token ships a light value in <code data-v-247f7c56>:root</code> and a dark override in the two <code data-v-247f7c56>data-color-scheme</code> blocks (explicit choice, or following the OS preference via <code data-v-247f7c56>prefers-color-scheme</code>). Switching light / dark simply swaps between these two sets of derived tokens, with zero structural change.</p><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56><b data-v-247f7c56>Benefits of one theme</b>: components, fonts, radii, and surfaces are consistent site-wide; a single accent keeps the brand identity unambiguous; light / dark mode works out of the box; semantic status colors are independently tunable. </div></div></section><section id="rules" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>07</span><h2 class="sec-title" data-v-247f7c56>Style Rules</h2></div><p class="sec-desc" data-v-247f7c56> Anti-pattern rules that all UI code must follow. These rules are also the basis of the check-style detection script, one-to-one with a warning. </p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Rule ID</th><th data-v-247f7c56>What it detects</th><th data-v-247f7c56>Action</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-gradient-text</td><td data-v-247f7c56>gradient text / gradient background</td><td data-v-247f7c56><span class="pill red" data-v-247f7c56>Forbidden</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-glassmorphism</td><td data-v-247f7c56><code data-v-247f7c56>backdrop-filter: blur</code> (<b data-v-247f7c56>TopBar sticky nav bar</b> and <b data-v-247f7c56>menu surfaces via <code data-v-247f7c56>--p-menu-backdrop</code></b> are the exceptions)</td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>TopBar + menus exempt</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-color-glow</td><td data-v-247f7c56>colored / large-radius box-shadow glow</td><td data-v-247f7c56><span class="pill red" data-v-247f7c56>Forbidden</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-emoji-icon</td><td data-v-247f7c56>using emoji as a functional icon (no exceptions). Emoji inside <b data-v-247f7c56>user content</b> — session titles, messages — is not chrome and is out of scope (see §07 Session row's emoji icon)</td><td data-v-247f7c56><span class="pill red" data-v-247f7c56>Forbidden</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-hardcoded-hex</td><td data-v-247f7c56>unregistered hex color inside a component <code data-v-247f7c56><style></code></td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>Warning</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>no-hardcoded-font</td><td data-v-247f7c56>hard-coded <code data-v-247f7c56>font-family</code> in a component (e.g. <code data-v-247f7c56>'Inter'</code>) instead of <code data-v-247f7c56>var(--font-ui)</code></td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>Warning</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>radius-from-scale</td><td data-v-247f7c56>radius value not in <code data-v-247f7c56>{4,6,8,12,16,20,999}</code></td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>Warning</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>z-from-scale</td><td data-v-247f7c56>z-index using an unregistered large number</td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>Warning</span></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>weight-from-scale</td><td data-v-247f7c56>font-weight not in <code data-v-247f7c56>{400,500}</code></td><td data-v-247f7c56><span class="pill amber" data-v-247f7c56>Warning</span></td></tr></tbody></table><h3 class="sub" data-v-247f7c56>State matrix</h3><p data-v-247f7c56>Every interactive primitive should define the following states where applicable; missing ones are flagged by the style rules. <code data-v-247f7c56>focus-visible</code> always uses <code data-v-247f7c56>--p-focus-ring</code> (appears only on keyboard focus, see §08); <code data-v-247f7c56>disabled</code> is uniformly <code data-v-247f7c56>opacity:.5</code>.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>State</th><th data-v-247f7c56>Button</th><th data-v-247f7c56>Input</th><th data-v-247f7c56>Card</th><th data-v-247f7c56>Menu item</th><th data-v-247f7c56>Switch</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>default</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>hover</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>active / pressed</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>focus-visible</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>✓</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>disabled</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>loading</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>selected / active</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>✓</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>error</td><td data-v-247f7c56>—</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>readonly</td><td data-v-247f7c56>—</td><td data-v-247f7c56>✓</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td><td data-v-247f7c56>—</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Chat working indicator</h3><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56> The chat working state ("prompt sent, turn unfinished") is a brand signature of Kimi Web, rendered uniformly by the <code data-v-247f7c56>WorkingIndicator</code> component: the 小蓝 mascot plus a phase label — "Requesting…" until the assistant's reply starts, "Working…" once it is streaming. All other loading states (including <code data-v-247f7c56>ActivityNotice</code>) use the plain <code data-v-247f7c56>Spinner</code>. </div></div><h3 class="sub" data-v-247f7c56>Glassmorphism exemption</h3><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56><code data-v-247f7c56>backdrop-filter: blur</code> is banned site-wide, with <b data-v-247f7c56>two exceptions</b>: the <code data-v-247f7c56>.frost</code> variant of <code data-v-247f7c56>TopBar</code> — only in the one place of the "sticky navigation bar", used to stay readable over scrolling content — and the floating menu surfaces: Menu.vue, the Select listbox and the composer dropdowns use the <code data-v-247f7c56>--color-menu-bg</code> token (a 95% surface), while the autocomplete family — slash/mention popups and the dock work panel — deliberately runs a frostier recipe of its own: 70% page background (single-sourced as <code data-v-247f7c56>--color-menu-bg-frost</code>) over the shared <code data-v-247f7c56>--p-menu-backdrop</code> blur, which stays the single-sourced blur token across all of them. The dock's work surfaces — the work panel and its pills, persistent over the scrolling transcript — ride that same frostier recipe (specified per-surface in §04 (Dock · work pills & panels)) rather than a bespoke one. No other component (card, dialog, Toast, panel) may use glassmorphism; violations are flagged under <code data-v-247f7c56>no-glassmorphism</code>, and menu blur with ad-hoc values (anything but the token) is flagged too. </div></div><div class="footer" data-v-247f7c56><span data-v-247f7c56>Kimi Web Design System · v1.0</span><span data-v-247f7c56>The reference when changing the web UI</span></div></section><section id="shell" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>08</span><h2 class="sec-title" data-v-247f7c56>App Shell & Sidebar</h2></div><p class="sec-desc" data-v-247f7c56> The structural spec for the app shell (three-column grid + right preview panel) and the left session sidebar. These are business-agnostic "skeletons" — components, fonts, radii, and surfaces are reused from §02 / §03, but layout and alignment have their own conventions. </p><h3 class="sub" data-v-247f7c56>Layout grid</h3><p data-v-247f7c56>On web it is a single-row 5-track grid: the sidebar and the right panel each occupy a permanent <code data-v-247f7c56>auto</code> track, with the conversation column in the middle; two 0-width tracks are for the ResizeHandles. (The desktop app adds a second row for its terminal panel — desktop-only, see below.)</p><div class="code" data-v-247f7c56><div class="code-bar" data-v-247f7c56><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="d" data-v-247f7c56></span><span class="fn" data-v-247f7c56>App.vue · .app</span></div><pre data-v-247f7c56>grid-template-columns: auto 0 minmax(0, 1fr) 0 auto;\n /* sidebar ↑ ↑handle ↑conversation ↑handle ↑right panel (auto) */</pre></div><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>sidebar width</td><td class="val" data-v-247f7c56>270px default (adjustable)</td><td data-v-247f7c56>expanded sidebar width, changed by dragging the ResizeHandle; should approach §02's <code data-v-247f7c56>--p-sidebar-w</code> (264px)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--preview-w</td><td class="val" data-v-247f7c56>460px</td><td data-v-247f7c56>width of the right preview panel when open</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--panel-head-h</td><td class="val" data-v-247f7c56>48px</td><td data-v-247f7c56>unified height for all right panel heads + the conversation column head; both use a 0.5px bottom hairline</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--p-bp-sm</td><td class="val" data-v-247f7c56>640px</td><td data-v-247f7c56>≤640 switches to a mobile single column (top bar + conversation), no sidebar / handle / right panel</td></tr></tbody></table><ul class="clean" data-v-247f7c56><li data-v-247f7c56>The right panel track exists permanently, with its width toggling between <code data-v-247f7c56>0 ↔ var(--preview-w)</code> and no transition — animating a grid track would relayout the whole app grid every frame (when open it squeezes the conversation column, rather than switching templates).</li><li data-v-247f7c56>The sidebar collapses SYMMETRICALLY to the right panel: its container width animates to 0 while the content keeps its fixed width anchored to the right edge (clipped, sliding out left — no reflow, hairline stays on the clipped content). No rail remains. The collapse control differs by platform: on <b data-v-247f7c56>macOS desktop</b> the toggle is a single resident floating IconButton pinned beside the traffic lights (rendered in both states, only the glyph swaps — the sidebar slides underneath it, never moves or flashes); on <b data-v-247f7c56>Windows / web</b> the collapse button lives inside the sidebar header (right-aligned), and a floating expand button appears at the top-left only while collapsed. The conversation header uses a 0.5px bottom hairline and pads left in step with the transition while collapsed.</li><li data-v-247f7c56>All grid children must have <code data-v-247f7c56>min-height:0; min-width:0</code>, so only the inner scroll containers scroll and the page itself does not scroll.</li></ul><h3 class="sub" data-v-247f7c56>Sidebar alignment system (<code data-v-247f7c56>--sb-*</code>)</h3><p data-v-247f7c56>All sidebar rows (group head, session row, New chat, search, and Settings buttons) share 5 custom properties. Their 16px icon slots and <code data-v-247f7c56>--sb-gap</code> place every label on the same x-axis as the workspace name.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Token</th><th data-v-247f7c56>Value</th><th data-v-247f7c56>Usage</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--sb-inset</td><td class="val" data-v-247f7c56>12px</td><td data-v-247f7c56>row box (hover/selected pill) inset from the sidebar edges — matches the brand header's 12px padding</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--sb-pad-x</td><td class="val" data-v-247f7c56>20px</td><td data-v-247f7c56>content start x (= --sb-inset + 8px row padding)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--sb-gutter</td><td class="val" data-v-247f7c56>16px</td><td data-v-247f7c56>leading icon slot width — matches the workspace folder icon so the session title aligns under the workspace name</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--sb-gap</td><td class="val" data-v-247f7c56>8px</td><td data-v-247f7c56>gap between the icon slot and the text</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>--sb-action-inset</td><td class="val" data-v-247f7c56>calc((max(--ui-font-size-sm × --leading-tight, --p-ic-md) + 2 × --space-2 − --icon-button-sm) / 2) ≈ 3px</td><td data-v-247f7c56>trailing action buttons sit this far inside the row box's right edge — exactly the buttons' vertical inset: half the font-driven row height's slack over the fixed IconButton sm box. The row height is the title line box floored at the group-head / directory rows' 16px folder icon, plus the vertical row padding, so the inset tracks the user's font scale without dropping below the icon-floored rows' slack; the session row's hover cluster, the group head's ⋯/+, and the section labels' buttons all share this one right edge</td></tr></tbody></table><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56> The session title's starting x = <code data-v-247f7c56>--sb-pad-x + --sb-gutter + --sb-gap</code>. The group head has a folder icon and the session row has a status slot; both icons are the same width and position, so the titles align naturally. On the trailing side, the list's scrollbar is an <b data-v-247f7c56>overlay</b> thumb that reserves no layout space: the native bar is hidden outright (<code data-v-247f7c56>.sessions</code> and the pinned rows' scroller set <code data-v-247f7c56>scrollbar-width: none</code> + <code data-v-247f7c56>::-webkit-scrollbar display:none</code>) and a floating thumb element follows the scroll position — hidden at rest, revealed while the list is hovered or scrolling, fading back out once idle, and draggable since the thumb is the only scroll affordance (<code data-v-247f7c56>useOverlayScrollbar</code> in <code data-v-247f7c56>@moonshot-ai/app-client</code>, the same contract as the composer menus' overlay thumbs; the thumb floats over the right padding strip, 4px in the text-derived 12% fill / 25% on hover, with an invisible wider drag strip). A layout scrollbar — even the thin 4px one these lists used to carry — reserves width on the right whenever it shows, so the rows' right edge sat one track width further in than the left edge. With the overlay the rows' left/right insets stay symmetric whether or not the list scrolls, and the section labels' right padding is simply <code data-v-247f7c56>--sb-action-inset</code>: every trailing button — section-label buttons included — stays on the same right line, with nothing measured or hard-coded. </div></div><h3 class="sub" data-v-247f7c56>Sidebar structure</h3><p data-v-247f7c56>The sidebar from top to bottom: brand header → action group → pinned head (pinned section + "Workspaces" label) → scrolling grouped list (workspace head + session rows) → user-menu footer. New chat and Search are direct sibling controls in the same grid container; the optional new-workspace action shares the first row, while Search spans the next row. A 4px gap keeps Search clear of the scroll boundary. The pinned head sits OUTSIDE the scroll container (the action-group / footer pattern — never <code data-v-247f7c56>position: sticky</code>, which would need an opaque plate over the frosted tint), so the pinned sessions and the "Workspaces" label stay put while the workspace groups scroll beneath; the pinned section is collapsible (a chevron on its label, revealed on hover/focus and kept visible while folded; state persisted) so a long pinned set can't eat the sidebar, and it re-expands when a new session is pinned. Both pinned edges use three light near, middle and far fades across <code data-v-247f7c56>--p-sidebar-seam-h</code> (13px), entering over 260ms only while more session content exists beyond that edge — the top seam lives at the pinned head's bottom border. The footer seam is a 0.5px hairline. Controls reuse the §03 primitives as much as possible. The sidebar sits on <code data-v-247f7c56>--color-sidebar-bg</code> (one step off <code data-v-247f7c56>--color-bg</code>: warm off-white just under white in light, one step BELOW the page in dark — the session column reads as its own plane, and with dark elevation = lighter the chrome never sits brighter than the conversation pane; the hairline still separates it from the pane). Vertical rhythm: the brand header keeps 12px padding (on macOS desktop the left padding grows to 80px to clear the traffic lights); rows inside the action group stack flush (0 gap, same rhythm as the list rows); adjacent groups are separated by 12px. The search glyph has a -0.5px optical correction to align its visual centre with the label. Row hover uses <code data-v-247f7c56>--sb-hover</code> (= the global <code data-v-247f7c56>--color-hover</code> wash); the selected row uses the lighter <code data-v-247f7c56>--sb-selected</code> wash derived from <code data-v-247f7c56>--color-selected</code> — On macOS desktop the sidebar is instead <b data-v-247f7c56>frosted</b>: the window carries a native <code data-v-247f7c56>NSVisualEffectView</code> ('menu' vibrancy, following the in-app scheme via the nativeTheme mirror, its state pinned to <code data-v-247f7c56>active</code> — the focused, translucent rendering that lets the desktop read through, with no active/inactive drift) and the sidebar column drops <code data-v-247f7c56>--color-sidebar-bg</code> for a single translucent <code data-v-247f7c56>--color-sidebar-tint</code> wash that presses the see-through material just a whisper — a shade darker in dark (<code data-v-247f7c56>rgba(0,0,0,0.12)</code>), a shade brighter in light (<code data-v-247f7c56>rgba(255,255,255,0.2)</code>) — so the sidebar ink stays legible while the tone follows the wallpaper, with header and footer staying transparent so the tint reads as one uniform pane; the root chain (<code data-v-247f7c56>html/body/#app/.app</code>) stays unpainted only under the <code data-v-247f7c56>macos-desktop</code> + <code data-v-247f7c56>vibrancy</code> flags — the latter is the Settings → Appearance accessibility switch (default on; persisted main-side so the window is created with the right material, and live-applied on toggle): off repaints the root chain and the sidebar falls back to opaque <code data-v-247f7c56>--color-sidebar-bg</code>, while the traffic-light layout keeps keying off <code data-v-247f7c56>macos-desktop</code> alone — while the conversation pane, chat header and right preview keep their own opaque surfaces. The list's hover-icon clusters (session-row kebab, group-head actions) paint NOTHING there — no plate, no wash, no blur (real backdrop blur does not even render over this window: Chromium's backdrop sampler returns a flat wash above the transparent BrowserWindow + vibrancy view). Instead the row's title/name dissolves before it ever reaches the buttons: a two-stage <code data-v-247f7c56>mask-image</code> fade — a subtle 16px dissolve at rest, extending over the cluster zone only while the actions are revealed (row hover / keyboard focus / menu open): 34px on session rows (the pin+kebab cluster overhangs the title by ≈25px), 68px on group heads (the floating cluster is ≈60px wide). The fade is zone-based, so short rows render untouched, and <code data-v-247f7c56>text-overflow</code> becomes <code data-v-247f7c56>clip</code> so a long tail dissolves instead of dotting.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Block</th><th data-v-247f7c56>Use</th><th data-v-247f7c56>Note</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td data-v-247f7c56>Brand header</td><td data-v-247f7c56>logo + name + collapse IconButton (right-aligned)</td><td data-v-247f7c56>on Windows / web the brand is left and the collapse IconButton sm is right-aligned inside the header; the dev-only backend version/address pill uses the UI font, not monospace; the logo is animated (a blinking eye). On macOS desktop the header is a bare drag strip (brand hidden, traffic lights + resident floating toggle over it)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>New chat</td><td data-v-247f7c56>full-width left-aligned button (custom)</td><td data-v-247f7c56>500-weight label; same rhythm as the session rows in the list (left-aligned, hover = <code data-v-247f7c56>--sb-hover</code>). <b data-v-247f7c56>Do not</b> use Button (centered, breaks the rhythm)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Search</td><td data-v-247f7c56>bare search row (custom)</td><td data-v-247f7c56>500-weight label; no border, hover/focus shows the faint <code data-v-247f7c56>--color-hover</code> wash; icon + label, with the <code data-v-247f7c56>Kbd</code> keycaps (⌘K / Ctrl K) pushed to the trailing edge — label and shortcut are justified apart. <b data-v-247f7c56>Do not</b> use Input (the 38px bordered version is too heavy). It is a direct sibling of New chat in the action group</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Section label</td><td data-v-247f7c56><code data-v-247f7c56>.p-section-label</code></td><td data-v-247f7c56>uppercase muted small titles like "Workspaces", using <code data-v-247f7c56>--weight-section-label</code> (600)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Pinned head</td><td data-v-247f7c56>fixed block above the scroll container (<code data-v-247f7c56>.sessions-head</code>): the pinned section (<code data-v-247f7c56>PinnedSessionList.vue</code>) + the "Workspaces" section label</td><td data-v-247f7c56>stays put while the workspace groups scroll; owns the top scroll-linked seam (hairline + fade, only while scrolled). Pinned rows render in pure recency order (updatedAt desc — no manual ordering, no attention tiering): drag a session row in to pin it (the drop spot carries no position meaning), drag a pinned row out to unpin. The pinned section folds via its label chevron (persisted, <code data-v-247f7c56>kimi-web.pinned-collapsed</code>) and re-expands only on an explicit pin (never on load backfill); the expanded rows are capped (40vh at rest) with their own scroll so a long pinned set can't push the list or footer out of view. Once the pinned content exceeds a few rows, a horizontal ResizeHandle twin renders between the rows and the section label (a shorter set keeps its natural height and no handle): dragging it re-caps the rows (two rows min; the max is 60% of the viewport, narrowed further on short windows so the list below always keeps ~3 rows — both bounds measured off the rendered rows, so they track the font-scale setting — and a gesture never targets positions past the content's natural height so the separator always tracks what renders; 40vh default; persisted per device, <code data-v-247f7c56>kimi-web.sidebar-pinned-height</code>) and the list below takes what remains — same 4px strip / centred 2px bar, neutral f2/f3 ramp, <code data-v-247f7c56>row-resize</code> with directional hints at the limits, <code data-v-247f7c56>useResizable axis: 'y'</code> with imperative height writes, and the §08 separator keyboard model (↑/↓). While the rows scroll internally, their edges carry the session list's scroll-linked seam language: a <code data-v-247f7c56>--p-sidebar-seam-h</code> three-layer text-tint veil plus a 0.5px <code data-v-247f7c56>--line</code> hairline at the content edge, at the top once scrolled and at the bottom while more rows remain — absolutely positioned (no layout shift), <code data-v-247f7c56>--duration-slow</code> opacity fade, below the resize handle so its hover/drag bar always wins. The rows scroller owns the same inset as <code data-v-247f7c56>.sessions</code> (the wrapper stretches to the full column width), so the rows' right edge and the scrollbar track land exactly where the session list's do</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Workspace head / session row</td><td data-v-247f7c56>see next two sections</td><td data-v-247f7c56>share <code data-v-247f7c56>--sb-*</code> alignment</td></tr><tr data-v-247f7c56><td data-v-247f7c56>User-menu footer</td><td data-v-247f7c56>account area (<code data-v-247f7c56>components/UserMenu.vue</code>) opening an upward §03 menu</td><td data-v-247f7c56>pinned row under the session list, separated by a 0.5px <code data-v-247f7c56>--line</code> hairline; trigger keeps the same list-style family as New chat (24px round avatar + nickname when signed in, user icon + sign-in hint otherwise). The menu box follows the trigger's left edge and width (ResizeObserver-tracked, so it survives a sidebar resize) and is teleported to body because the column's container-type would capture position:fixed. Rows: plan usage / theme / language are macOS-style hover flyout submenus — the parent row carries the module icon, a faint current value and a fixed chevron-right, and hovering (or moving focus to the parent row, or pressing Enter / Space / → on it) opens a teleported panel anchored to the parent menu's right edge (content-adaptive width floored by the menu's own min-width and capped by the viewport margin on the side it opens (usage reset hints ellipsize only when the window is genuinely too narrow); flips left near the viewport edge) with a 250ms hover-intent close grace; the usage panel shows weekly + 5h rows (used-percent values via <code data-v-247f7c56>settings.planUsage.usedPct</code>, with severity colours), while the theme (three schemes) and language (two locales) panels move the check to the picked option without closing the menu — then the upgrade entry below the top plan level, settings (with an always-visible Kbd keycap shortcut hint on desktop) and a confirming sign-out; all menu icons come from the Kimi set, and the whole menu (flyouts included) runs at the §03 default density — same row inset, label size and separator rhythm as every other menu; the usage flyout's custom rows read the same <code data-v-247f7c56>--menu-item-padding-*</code> inset tokens as the primitive — each a two-column grid (label + end-justified used-percent on line one, the reset hint one rung down at <code data-v-247f7c56>--text-xs</code> spanning both columns on line two so it is never squeezed by the top line's split), stacked at the adjacent-menu-item rhythm (2 × <code data-v-247f7c56>--menu-item-padding-block</code>). On macOS desktop the trigger's bottom-left corner rounds at <code data-v-247f7c56>--radius-window-chip</code> — concentric with the window's corner (the window rounds at the measured 14px <code data-v-247f7c56>--radius-window</code>, and the footer's <code data-v-247f7c56>--sb-inset</code> row inset and <code data-v-247f7c56>--space-2</code> block padding both resolve to 8px, so the chip hugs 8px from the window's left and bottom edges and 14px − 8px lands exactly on <code data-v-247f7c56>--radius-sm</code>); web and other platforms have no rounded container corner there and keep the uniform <code data-v-247f7c56>--radius-sm</code></td></tr></tbody></table><div class="callout warn" data-v-247f7c56><span class="ico" data-v-247f7c56>!</span><div data-v-247f7c56><b data-v-247f7c56>Why New chat / search / inline rename don't use Button / Input:</b> they are "list-style" controls (full-width, left-aligned, compact, borderless), while Button is centered and Input is a 38px bordered control — forcing them in would break the sidebar's visual density and alignment. This is an intentional custom exception, not an oversight. </div></div><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>实验室 multi-tab sidebar toggle</b> (Settings → 实验室, <code data-v-247f7c56>kimi-web.sidebar-multi-tab</code>, default OFF) forks the sidebar into two forms. <b data-v-247f7c56>OFF = the legacy single session list</b>: no 进行中/已完成/工作空间 tabs (<code data-v-247f7c56>statusTab</code> pinned to <code data-v-247f7c56>open</code>, tab shortcuts inert), no session-admin entries (the 列表管理 menu item hides and the workspace home itself falls back to the classic 新建会话 doodle hero — no workspace head, no recent-sessions list), the row hover action + context menu and the chat-header ⋯ menu read <b data-v-247f7c56>归档</b> with the <code data-v-247f7c56>archive</code> glyph (no success-hover variant, the header's Done pill + reopen button hide), and the archive ActionToast is the legacy «撤销 · 或到 · 设置 · 查看已归档的会话» linking to Settings → Archived. <b data-v-247f7c56>ON = the status-tabs form</b> documented in this section (tabs, session admin page, the complete/reopen relabel, «已完成 · 撤销» toast). The preference is an app-core singleton (<code data-v-247f7c56>useSidebarTabs</code>) consumed directly by Sidebar / SessionRow / ConversationPane / App.vue — no prop threading. </div></div><h3 class="sub" data-v-247f7c56>Session row</h3><p data-v-247f7c56>A session row is an inset rounded pill, structured as: <code data-v-247f7c56>status slot → title → time → attention Badge → hover actions (pin / archive)</code>.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Part</th><th data-v-247f7c56>Rule</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td data-v-247f7c56>Container</td><td data-v-247f7c56><code data-v-247f7c56>padding: 8px 8px</code> inside the list's <code data-v-247f7c56>--sb-inset</code> gutter, <code data-v-247f7c56>radius-sm</code>; <b data-v-247f7c56>no fixed/min height</b> — row height is font-driven (title <code data-v-247f7c56>line-height: --leading-tight</code>, ≈16px) → ≈32px total, the sidebar-wide row rhythm. The hover actions are absolutely positioned so they never force the row taller (no hover jitter). hover = <code data-v-247f7c56>--sb-hover</code> (the global <code data-v-247f7c56>--color-hover</code> wash); active = <code data-v-247f7c56>--sb-selected</code> (75% of the global selected wash) — neutral, no accent tint, no border, no weight change</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Status slot (lead)</td><td data-v-247f7c56>fixed <code data-v-247f7c56>--sb-gutter</code> width; running = <code data-v-247f7c56>Spinner</code> sm, otherwise unread = 7px accent dot; empty while an attention Badge owns the row — one status at a time, decided by the shared <code data-v-247f7c56>SessionDisplayStatus</code> enum (app-core <code data-v-247f7c56>sessionDisplayStatus.ts</code>: approval › question › running › aborted › unread)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Title</td><td data-v-247f7c56>flex:1 with truncation and <code data-v-247f7c56>user-select:none</code>; double-click enters inline rename (compact input, not Input), whose text remains selectable</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Emoji icon</td><td data-v-247f7c56>the session icon is the title's LEADING emoji cluster (app-core <code data-v-247f7c56>splitSessionEmoji</code> — no icon field; every client renders the title as-is). The emoji is an ordinary title character — no decoration at rest or on hover (it stays a <code data-v-247f7c56><button></code> for a11y), and clicking it opens <code data-v-247f7c56>SessionEmojiPicker</code> — a Menu-shelled panel (bare list-style search row → scrollable sections: Recently used persisted in localStorage (cap 8) + the grouped emoji dataset, with remove/random as MenuItems in the footer; a query swaps the sections for keyword-search results), teleported + fixed + <code data-v-247f7c56>--z-dropdown</code>, popping from the trigger corner like the right-click menu. The menu's "Set Emoji…" opens the same picker and is the discoverable path. Inline rename edits the whole title — the emoji is an ordinary character in the input</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Time</td><td data-v-247f7c56>mono xs, <code data-v-247f7c56>fg-faint</code>; yields to the hover actions on hover</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Attention Badge</td><td data-v-247f7c56><code data-v-247f7c56>Badge</code> sm: info (needs answer) / warning (needs approval) / danger (aborted)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Hover actions</td><td data-v-247f7c56><code data-v-247f7c56>IconButton</code> sm × 2 — pin + archive — cross-faded over the time on row hover (no kebab button). Right-clicking the row opens the full menu (copy ID / rename / emoji / fork / export / pin / archive + timestamp) anchored to the cursor, except over the inline rename input, where the native text-editing menu stays</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Flat-style variant (flat list + pinned section)</td><td data-v-247f7c56>the sidebar's flat list rows AND — always, regardless of view mode — the pinned section's rows differ from the grouped row in three ways (all keyed off the facade projecting <code data-v-247f7c56>cwdLabel</code>): ① no leading status slot — the title is left-aligned at the row's content edge; ② a second line under the title: <code data-v-247f7c56>folder-closed</code> icon sm + the cwd's final directory name (<code data-v-247f7c56>-</code> when the session has no cwd), xs faint like the time — except the icon, which takes <code data-v-247f7c56>--color-text-muted</code> (one rung stronger, the same optical compensation as the group head's folder; the open-folder glyph's thin back-flap washed out at 14px) — rest-width tail mask fade; when the session has an associated PR (v2 git domain), a small tag (<code data-v-247f7c56>git-pull-request</code> icon + #number, 2xs medium on a soft ground with a hairline edge and radius-sm corners — a mini §03 Badge) sits at the line's right edge, state-colored the GitHub way (open = <code data-v-247f7c56>--color-success-soft</code> ground + <code data-v-247f7c56>--color-success</code> text, merged = <code data-v-247f7c56>--color-done-soft</code> + <code data-v-247f7c56>--color-done</code> purple, closed = neutral sunken) and opens the PR on click; ③ the first line's right side shows status — attention Badges anchored to the row's right edge, running Spinner, unread dot — INSTEAD of the time, which only renders when there is nothing to report (the Spinner yields to the attention pills: a session waiting for approval/answer never shows both); on hover the actions cross-fade IN as the whole status cluster fades OUT — pills and pin/archive never co-exist (grouped rows keep pills visible on hover). Height stays font-driven — the pill just grows the line. Grouped rows never set <code data-v-247f7c56>cwdLabel</code> and keep the classic structure. The flat ↔ grouped switch lives in a dropdown on the SESSIONS section label (fixed <code data-v-247f7c56>list-settings</code> icon + hover tooltip; the menu opens with a muted group label, per-view icons, and the current view checked at the row's right edge; mode persisted per device)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Archive</td><td data-v-247f7c56>no confirm — the hover archive button / menu item archives immediately, then App.vue shows the §03 <code data-v-247f7c56>ActionToast</code> (top-center) with Undo (restores the session) and Settings (opens the archived list)</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Workspace group</h3><p data-v-247f7c56>The group head and session rows share <code data-v-247f7c56>--sb-*</code>: folder icon (open/closed) → name, with the kebab and "+" revealed on hover.</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56>The folder icon leads the row (switching icons between open and closed states) with the plain <code data-v-247f7c56>--sb-gap</code> before the name — it does not pad out the <code data-v-247f7c56>--sb-gutter</code> slot.</li><li data-v-247f7c56>The name uses 500 weight with muted color (<code data-v-247f7c56>--color-text-muted</code>, one step lighter than session titles), so group heads remain clear without competing with list content. No path subtitle; hovering the name shows the full root path in a <code data-v-247f7c56>Tooltip</code>.</li><li data-v-247f7c56>The kebab (menu) and "+" (new chat in this workspace) both use <code data-v-247f7c56>IconButton</code> sm inside a floating actions layer anchored to the row's right edge — no reserved layout space, so the name uses the full row width when idle. Shown on hover, keyboard focus, or while the menu is open; the layer backs itself with the sidebar surface (container background) plus the row hover wash (an <code data-v-247f7c56>::after</code> shown only while the row is hovered), so its color exactly equals the row's current background and the overlapped name tail doesn't bleed through (hidden via <code data-v-247f7c56>opacity:0</code>, staying in the tab order). On macOS desktop the layer paints nothing at all — the name's <code data-v-247f7c56>mask-image</code> fade (see the sidebar section above) dissolves the tail before it reaches the buttons</li><li data-v-247f7c56>The group is collapsible; when collapsed its session list is hidden.</li><li data-v-247f7c56>A group with no sessions is NOT rendered in the 进行中 tab of the status-tabs form (a cleanup leaves no pile of empty folders; the 工作空间 tab is the directory for creating sessions) — EXCEPT the active workspace's group, which stays so the draft state below keeps its head fill. The legacy single-list form (multi-tab toggle OFF) has no 工作空间 tab to fall back on, so it keeps EVERY group, empty ones included — archiving a workspace's last session must not make the workspace unreachable there. The Done tab's groups filter the same way. When nothing is open at all (and no pinned sessions), the tab shows the "还没有进行中的会话" empty line.</li><li data-v-247f7c56>While the active workspace has no session selected (the draft state — e.g. right after adding the workspace, or after New chat), the group head carries the same neutral <code data-v-247f7c56>--sb-selected</code> fill as a selected session row (selection reads as "where I am"; the fill wins over hover). Once a session is selected or created, the fill moves to that session row.</li></ul><h3 class="sub" data-v-247f7c56>Show more & collapse</h3><p data-v-247f7c56>The "expand / collapse" controls at the bottom of each workspace group are compact list controls (same family as search, New chat, inline rename — not Buttons) sharing one row: expand (chevron-down) first, collapse (chevron-up) after a faint middot when both are present. Expanding reveals the next batch of sessions, fetching the next page from the server only when the locally loaded rows can't cover it — the control never exposes whether a reveal came from memory or the network.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Part</th><th data-v-247f7c56>Rule</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Row</td><td data-v-247f7c56>a single flex row holding the controls, all content-width — hover washes just the button as a snug pill, never the full row. Font-driven height (≈32px like a session row), <code data-v-247f7c56>radius-sm</code>; hover = <code data-v-247f7c56>--sb-hover</code> (no text recolor); <code data-v-247f7c56>:focus-visible</code> uses <code data-v-247f7c56>--p-focus-ring</code></td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Chevron</td><td data-v-247f7c56>sm (down = expand, up = collapse); the row indents by <code data-v-247f7c56>--sb-gutter + --sb-gap</code> so the first button's chevron starts exactly at the session-title x, lining the control's leading edge up with the titles above</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Label</td><td data-v-247f7c56><code data-v-247f7c56>font-ui</code>, <code data-v-247f7c56>text-xs</code>, <code data-v-247f7c56>--color-text-muted</code>; truncated</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Separator</td><td data-v-247f7c56>faint middot (<code data-v-247f7c56>--color-text-faint</code>) with <code data-v-247f7c56>--space-1</code> side margins, rendered only when both controls are present</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Behavior</td><td data-v-247f7c56>each group keeps a display cap starting at the first page; "Show more" steps it up by one batch (5) and fetches the next page only when the loaded rows fall short (busy = "Loading…", disabled); "Show less" resets the cap to the first page (view-layer trim — data is kept, no refetch). "Show more" exists while undisplayed loaded rows remain or the server has more; "Show less" appears once past the first page</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>ResizeHandle</h3><p data-v-247f7c56>A 4px grab strip layered over the 1px column border (<code data-v-247f7c56>margin: 0 -2px</code> makes the whole 4px grabbable) with a centred 2px indicator bar. The bar stays transparent at rest and shows the neutral fills one step up the ramp — f2 on hover, f3 while the drag is live (the sidebar column is translucent on macOS, so f1 read too faint) — never the accent.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Rule</th><th data-v-247f7c56>Value</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td data-v-247f7c56>Width / cursor</td><td data-v-247f7c56>4px strip, 2px bar / <code data-v-247f7c56>col-resize</code> mid-range; <code data-v-247f7c56>w-resize</code> / <code data-v-247f7c56>e-resize</code> at the drag limits (hints the direction that still resizes)</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Normal / hover / drag</td><td data-v-247f7c56>transparent / <code data-v-247f7c56>--color-selected</code> (f2) / <code data-v-247f7c56>--color-line-strong</code> (f3) — the neutral ramp one step up, never accent</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Layer</td><td data-v-247f7c56><code data-v-247f7c56>--z-dropdown</code>, above pane-level sticky chrome (chat dock at <code data-v-247f7c56>--z-sticky</code>) so the overhang stays visible and grabbable</td></tr><tr data-v-247f7c56><td data-v-247f7c56>Behavior</td><td data-v-247f7c56>panel width follows the pointer 1:1 while dragging (the parent disables transitions to avoid lag); on release it is persisted to localStorage</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Right panel</h3><p data-v-247f7c56>The right panels (file preview / Diff / compaction summary / sub-agent / side chat) share one track and one head primitive.</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56>The panel head uses the <code data-v-247f7c56>PanelHeader</code> primitive (48px = <code data-v-247f7c56>--panel-head-h</code>), the same height as the conversation column head, so the hairline runs as one line.</li><li data-v-247f7c56>Panel head: bold mono title + optional muted subtitle + middle slot (Badge / control / path) + close IconButton on the right.</li><li data-v-247f7c56>When opened, the panel width snaps from <code data-v-247f7c56>0 → var(--preview-w)</code> with no animation, squeezing the conversation column in a single layout.</li><li data-v-247f7c56>At ≤640px the panel becomes a full-screen overlay (<code data-v-247f7c56>position:fixed; inset:0</code>).</li></ul><h3 class="sub" data-v-247f7c56>Bottom terminal panel (desktop-only)</h3><p data-v-247f7c56>The native terminal (<code data-v-247f7c56>components/terminal/</code>) sits in the conversation column's own bottom grid slot — the sidebar and the right panel span BOTH rows and keep full height (the VS Code layout: the panel belongs to the editor area, not to the whole window). Its height transitions <code data-v-247f7c56>0 ↔ var(--terminal-h)</code> (260px default, 120 min, 60% viewport max; persisted), squeezing the conversation column above instead of overlaying it. The panel mounts lazily on first open and then stays mounted so xterm scrollback survives a collapse.</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56>Resize: a horizontal twin of the ResizeHandle (4px strip over the 0.5px top hairline, <code data-v-247f7c56>row-resize</code> mid-range, <code data-v-247f7c56>n/s-resize</code> at the limits, same neutral f2/f3 ramp, never accent). The shared <code data-v-247f7c56>useResizable</code> hook owns it via <code data-v-247f7c56>axis: 'y'</code>; the height var is written imperatively during a drag (same no-Vue-rerender rule as <code data-v-247f7c56>--preview-w</code>).</li><li data-v-247f7c56>Toolbar (32px, 0.5px bottom hairline): tab strip on the left — each tab is a compact <code data-v-247f7c56>radius-sm</code> pill (leading terminal glyph, muted while exited + shell label + hover close affordance), the active tab uses <code data-v-247f7c56>--color-selected</code>, hover <code data-v-247f7c56>--color-hover</code>; a "+" action appends a tab. Tabs follow the §08 tablist keyboard model (roving tabindex, ←/→/Home/End), the close affordance is its own button (no nested interactives), and the height separator is keyboard-operable (↑/↓ in steps, value exposed). Trailing actions: restart (only while the active tab exited) and a collapse chevron. Collapsing sets <code data-v-247f7c56>inert</code> on the region — the xterm instances and their scrollback stay mounted but leave the tab order.</li><li data-v-247f7c56>The xterm canvas cannot resolve CSS variables either, so its palette is resolved from the live <code data-v-247f7c56>--color-*</code> tokens at runtime (re-read on scheme flips; the ANSI hues the status ramp doesn't cover use dedicated <code data-v-247f7c56>--color-term-magenta/cyan</code> tokens); the font is the app JetBrains Mono stack sized off the content token scale. While focused, the panel owns every key except the registered app shortcuts (chat-level Esc / find / select-all chords stay inert inside it).</li><li data-v-247f7c56>Entries: the chat header's terminal IconButton (right of Open in, lit while the panel is open) — on the empty-composer state, where no chat header renders, the same button floats at the conversation's top-right instead — plus <code data-v-247f7c56>ctrl+`</code> (⌃` on macOS — VS Code's binding; ⌘` stays free for the OS window switcher — customizable in the shortcut registry), and the View menu's Toggle Terminal item. New tabs spawn in the visible workspace root. Terminal state is per session: switching sessions swaps the visible bucket while the others keep their PTYs and xterm views alive (scrollback survives a round trip; the ten most recent sessions are kept, LRU). The panel never renders on mobile / web.</li></ul><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>One-sentence principle:</b> the sidebar / shell is a "list + grid" skeleton that reuses the §02 tokens and §03 primitives (Button / IconButton / Badge / Kbd / Menu / Spinner / PanelHeader); compact list controls that don't fit a primitive (search, New chat, inline rename, show-more) keep their custom form, governed by this section. </div></div></section><section id="a11y" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>09</span><h2 class="sec-title" data-v-247f7c56>Accessibility (pragmatic edition)</h2></div><p class="sec-desc" data-v-247f7c56> Kimi Web is a local developer tool; it <b data-v-247f7c56>does not target a specific WCAG conformance level</b>, nor maintain a full screen-reader QA matrix. This section collects only the rules that are "low-cost, don't hurt the look, and directly benefit keyboard-heavy users", as the baseline contract for each primitive; the more expensive, lower-ROI parts (such as real-time announcement orchestration for streaming output) are not mandatory for now. </p><div class="callout info" data-v-247f7c56><span class="ico" data-v-247f7c56>i</span><div data-v-247f7c56><b data-v-247f7c56>On the "ugly" focus ring:</b> the focus visibility required below always uses <code data-v-247f7c56>:focus-visible</code> (not <code data-v-247f7c56>:focus</code>). It appears <b data-v-247f7c56>only on keyboard focus</b>; mouse clicks don't trigger it, so it doesn't pollute the mouse-driven visual; the ring's strength is tuned uniformly with <code data-v-247f7c56>--p-focus-ring</code>, not overridden per place. </div></div><h4 class="mini" data-v-247f7c56>1. Contrast & color</h4><ul class="clean" data-v-247f7c56><li data-v-247f7c56>Body text vs. background contrast <b data-v-247f7c56>≥ 4.5:1</b>; control borders, icons, and key graphics <b data-v-247f7c56>≥ 3:1</b>. When changing theme colors / dark mode, verify against §05 together.</li><li data-v-247f7c56><b data-v-247f7c56>Button text vs. button background</b>, and <b data-v-247f7c56>form controls</b> (input, placeholder, helper / error text) <b data-v-247f7c56>vs. their section background</b> must all have contrast ≥ 4.5:1 (large text ≥ 3:1). White-on-white text, a transparent borderless button floating over the page background, and a light placeholder on a near-white background are all flagged by the style rules.</li><li data-v-247f7c56><b data-v-247f7c56>State is not conveyed by color alone.</b> Error, selected, and disabled states also carry text, an icon, or a shape change (for example an error state is not just red, but also carries text or an icon).</li></ul><h4 class="mini" data-v-247f7c56>2. Keyboard operable</h4><p data-v-247f7c56>Anything doable with a mouse must also be doable with a keyboard; Tab order follows the DOM, with no invented skipping. Composite controls define their keyboard model per the table below; a missing model is treated as incomplete:</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Control</th><th data-v-247f7c56>Keyboard behavior</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Dialog</td><td data-v-247f7c56><code data-v-247f7c56>Tab</code> cycles within the dialog (focus trap); <code data-v-247f7c56>Esc</code> closes; focus returns to the trigger element after closing.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Menu</td><td data-v-247f7c56><code data-v-247f7c56>↑</code> / <code data-v-247f7c56>↓</code> move the highlight, <code data-v-247f7c56>Enter</code> selects, <code data-v-247f7c56>Esc</code> closes.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Tabs</td><td data-v-247f7c56><code data-v-247f7c56>←</code> / <code data-v-247f7c56>→</code> switch tabs (roving tabindex); only the current tab is in the Tab sequence.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Switch / Segmented</td><td data-v-247f7c56><code data-v-247f7c56>←</code> / <code data-v-247f7c56>→</code> or <code data-v-247f7c56>Space</code> / <code data-v-247f7c56>Enter</code> to toggle.</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>3. Focus visibility</h4><ul class="clean" data-v-247f7c56><li data-v-247f7c56>Every interactive element must have a visible focus indicator on keyboard focus, uniformly via <code data-v-247f7c56>:focus-visible</code> + <code data-v-247f7c56>--p-focus-ring</code> (primary actions may use <code data-v-247f7c56>--p-focus-ring-strong</code>).</li><li data-v-247f7c56>Bare <code data-v-247f7c56>outline: none</code> is forbidden. To remove the default outline, you must provide an equivalent replacement style.</li></ul><h4 class="mini" data-v-247f7c56>4. Labels & semantics</h4><ul class="clean" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>Semantic HTML first</b> (button / a / input / dialog…); ARIA is added only when native semantics fall short.</li><li data-v-247f7c56>Icon-only buttons must have an <code data-v-247f7c56>aria-label</code> — <code data-v-247f7c56>IconButton</code> already enforces this with a required <code data-v-247f7c56>label</code> prop.</li><li data-v-247f7c56>Dialog: <code data-v-247f7c56>role="dialog"</code> + <code data-v-247f7c56>aria-modal="true"</code>, with the title as the dialog's accessible name.</li><li data-v-247f7c56>Purely decorative SVG / icons get <code data-v-247f7c56>aria-hidden="true"</code> to avoid being read out by screen readers.</li></ul><h4 class="mini" data-v-247f7c56>5. Target size</h4><p data-v-247f7c56>Desktop click targets <b data-v-247f7c56>≥ 32px</b>; touch devices <b data-v-247f7c56>≥ 44px</b> (consistent with the §01 principle and the IconButton <code data-v-247f7c56>lg</code> tier).</p><h4 class="mini" data-v-247f7c56>6. Reduced motion</h4><p data-v-247f7c56>Handled uniformly in the global styles per §02's <code data-v-247f7c56>@media (prefers-reduced-motion: reduce)</code>; components do not check this individually. The chat working indicator's mascot renders its static fallback.</p><h4 class="mini" data-v-247f7c56>7. Live announcements (non-mandatory)</h4><p data-v-247f7c56>Screen-reader announcements are <b data-v-247f7c56>not a mandatory contract</b> in this product. Short hints like Toast can use <code data-v-247f7c56>role="status"</code> / <code data-v-247f7c56>aria-live</code>; chat streaming output is currently not announced word-by-word, which is an acceptable trade-off, to be added later if a real need arises.</p><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56><b data-v-247f7c56>Explicitly not mandatory for now:</b> a WCAG conformance-level claim, a complete ARIA pattern table, a per-screen-reader QA matrix, and real-time announcement orchestration for streaming output — these are not written into the primitive contract, to avoid becoming slogans no one maintains. </div></div></section><section id="dialogs" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>10</span><h2 class="sec-title" data-v-247f7c56>Dialogs</h2></div><p class="sec-desc" data-v-247f7c56> Every overlay in the app — pickers, browsers, managers, confirmations — is built on the single §03 Dialog primitive. This chapter fixes the two layout anatomies allowed inside that frame, plus the row and footer contracts that make all dialogs read as one family. Do not hand-roll a third anatomy. </p><h3 class="sub" data-v-247f7c56>The frame (recap)</h3><p data-v-247f7c56> All dialogs share the §03 primitive: <code data-v-247f7c56>--radius-xl</code> radius, <code data-v-247f7c56>--shadow-xl</code> shadow, a restrained 28% neutral backdrop, a head (title + IconButton close), a body, and a right-aligned foot. Widths <code data-v-247f7c56>sm</code> 360 / <code data-v-247f7c56>md</code> 440 / <code data-v-247f7c56>lg</code> 640 / <code data-v-247f7c56>xl</code> 760 and <code data-v-247f7c56>auto</code> / <code data-v-247f7c56>fixed</code> height are chosen per §03. One interruptive overlay at a time; <code data-v-247f7c56>Esc</code> closes; focus is trapped and restored. A blocking flow that must be resolved rather than dismissed (server token) uses <code data-v-247f7c56>hideClose</code> with <code data-v-247f7c56>closeOnOverlay</code>/<code data-v-247f7c56>closeOnEsc</code> off — never a hand-written overlay. </p><h3 class="sub" data-v-247f7c56>Anatomy A — padded (forms & confirmations)</h3><p data-v-247f7c56> The default: the body carries its own padding and the caller drops content straight in. Confirmations put their Buttons in the <code data-v-247f7c56>#foot</code> slot (right-aligned, cancel → confirm). Used by: confirm, login, status panel, server token. </p><h3 class="sub" data-v-247f7c56>Anatomy B — flush (pickers & browsers)</h3><p data-v-247f7c56><code data-v-247f7c56>:padded="false"</code> with <code data-v-247f7c56>height="fixed"</code>; the consumer owns the zone layout inside a full-height column. The zones below are the whole vocabulary — a picker dialog composes them and adds nothing else. Used by: model picker, session search, folder browser, provider manager. </p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Zone</th><th data-v-247f7c56>Contract</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Search</td><td data-v-247f7c56>The boxed §03 Input, inset 22px so its edge aligns with the head title. Autofocus on open. No leading icon, no borderless variant.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Filter chips</td><td data-v-247f7c56>Optional. 28px pill: transparent + muted text by default, <code data-v-247f7c56>--color-hover</code> on hover, <code data-v-247f7c56>--color-selected</code> + medium <code data-v-247f7c56>--color-text</code> when active. Horizontally scrollable with the scrollbar hidden. Never a row of Buttons.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>List</td><td data-v-247f7c56><code data-v-247f7c56>flex:1</code>, owns the vertical scrolling, padded 4px 8px so rows bleed near the dialog edge. <code data-v-247f7c56>role="listbox"</code>; rows carry <code data-v-247f7c56>role="option"</code> + <code data-v-247f7c56>aria-selected</code>.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Row</td><td data-v-247f7c56>8px 12px padding, <code data-v-247f7c56>--radius-md</code>. Two quiet lines: name 14/20 (medium when current) and a meta line 12/18 in <code data-v-247f7c56>--color-text-faint</code> — provider · context · capability labels, dot-separated. No badge rows, no raw-id line (search still matches them). Trailing slot: check icon (current row only), then the star IconButton.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Row states</td><td data-v-247f7c56>Hover / keyboard-selected → <code data-v-247f7c56>--color-hover</code>; current → <code data-v-247f7c56>--color-selected</code> — a neutral "where I am" fill, never an accent tint, never an inset stroke. The star stays hidden until row hover, keyboard selection, or starred; it is always visible on touch devices and colored <code data-v-247f7c56>--star</code> when starred.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>State rows</td><td data-v-247f7c56>Loading / unavailable / empty: centered on both axes, muted 14px; warning color only for the unavailable case.</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Shortcut bar</td><td data-v-247f7c56>The footer: full-bleed, padding 8px 16px, <code data-v-247f7c56>border-top --color-line</code>, left-aligned. Keyboard hints are Kbd keycaps + 12px <code data-v-247f7c56>--color-text-faint</code> labels, groups separated by "·", the whole bar <code data-v-247f7c56>aria-hidden</code>. An instructional sentence (folder browser) reuses the same bar without keycaps.</td></tr></tbody></table><h4 class="mini" data-v-247f7c56>Keyboard & behavior contract</h4><ul class="clean" data-v-247f7c56><li data-v-247f7c56><code data-v-247f7c56>↑</code>/<code data-v-247f7c56>↓</code> move a keyboard selection (rendered identical to hover) and always <code data-v-247f7c56>scrollIntoView({ block: 'nearest' })</code>; <code data-v-247f7c56>Enter</code> selects and closes; <code data-v-247f7c56>Esc</code> closes.</li><li data-v-247f7c56>Pointer hover drives the same selection index, so keyboard and mouse never disagree about which row is active.</li><li data-v-247f7c56>Rows transition <code data-v-247f7c56>background</code> only (<code data-v-247f7c56>--duration-fast</code> ease-out); the open/close animation lives in the primitive, not in the consumer.</li><li data-v-247f7c56>Selection is a fill, not a border (surface over stroke). Accent blue is reserved for actions — primary buttons and focus rings — never for "which row am I on".</li></ul><h4 class="mini" data-v-247f7c56>Dialog map</h4><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Dialog</th><th data-v-247f7c56>Anatomy</th><th data-v-247f7c56>Composition</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Model picker</td><td data-v-247f7c56>flush · lg · fixed</td><td data-v-247f7c56>search + provider chips + model rows + shortcut bar</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Session search</td><td data-v-247f7c56>flush · lg · fixed</td><td data-v-247f7c56>search + result rows (sidebar-style alignment: one icon gutter, shared left text edge, shared right meta edge; workspace rows single-line name + right-aligned path, session rows title + time over a workspace · snippet meta line; quiet uppercase section heads with counts; empty query shows a few top workspaces + recent sessions) + shortcut bar</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Folder browser</td><td data-v-247f7c56>flush · lg · fixed</td><td data-v-247f7c56>breadcrumb bar + filter bar + folder rows + actions + hint bar</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Provider manager</td><td data-v-247f7c56>flush · xl · fixed</td><td data-v-247f7c56>management rows with inset dividers (rows are not selectable) + add section + shortcut bar</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Confirm / Login / Status</td><td data-v-247f7c56>padded · md · auto</td><td data-v-247f7c56>title + message or form + right-aligned foot</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>App update (desktop)</td><td data-v-247f7c56>padded · lg · auto</td><td data-v-247f7c56>version title (stays "发现新版本 vX" even while downloading) + quiet meta line (release date · current version) + height-capped scrolling what's-new list + right-aligned action row (skip → download; downloading → background + disabled live-percent button; later → restart) with the auto-download checkbox right-aligned on its own foot row below (a pure preference for future checks)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Server token</td><td data-v-247f7c56>padded · md · auto</td><td data-v-247f7c56><code data-v-247f7c56>hideClose</code>, no Esc/overlay close — resolved only by a valid token</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Settings</td><td data-v-247f7c56>flush · xl · fixed</td><td data-v-247f7c56>page-like exception: side-nav region, per §03</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>Onboarding wizard</td><td data-v-247f7c56>not a Dialog</td><td data-v-247f7c56>full-page takeover (not built on §03): one centered column (brand lockup → step content → ghost actions + centered primary CTA); selectable options share the option-card pattern — 0.5px <code data-v-247f7c56>--color-line</code> hairline, <code data-v-247f7c56>--color-accent</code> border + <code data-v-247f7c56>--color-accent-soft</code> fill when selected</td></tr></tbody></table><div class="callout good" data-v-247f7c56><span class="ico" data-v-247f7c56>✓</span><div data-v-247f7c56><b data-v-247f7c56>Design intent:</b> a picker dialog should feel like a quiet command palette — one boxed search, calm rows, a neutral "you are here" fill, and a predictable shortcut bar. Anything noisier — badge clouds, accent-selected rows, per-dialog footer inventions — is a regression to weed out. </div></div></section><section id="session-admin" data-v-247f7c56><div class="sec-head" data-v-247f7c56><span class="sec-num" data-v-247f7c56>11</span><h2 class="sec-title" data-v-247f7c56>Session Admin Page</h2></div><p class="sec-desc" data-v-247f7c56> The session admin page (<code data-v-247f7c56>/admin/sessions</code>, opened from the sidebar's list-management menu) is a full-pane management view for cross-workspace session triage: filters, a server-side paged table, and batch lifecycle actions. It is a main-view peer of the conversation pane (<code data-v-247f7c56>mainView</code> in the facade, switched with v-show so the chat stays alive) and page-private by decision — everything lives under <code data-v-247f7c56>components/admin/</code> (<code data-v-247f7c56>SessionAdminView/Table/Pagination</code>, <code data-v-247f7c56>FilterSelect</code>, <code data-v-247f7c56>MultiSelectMenu</code>, <code data-v-247f7c56>SessionAdminMenu</code>, <code data-v-247f7c56>useAnchoredMenu</code>); nothing here promotes to §03 until a second consumer exists. Data is one <code data-v-247f7c56>GET /api/v2/sessions</code> page-mode call per filter/page change (all conditions pushed down, no client-side aggregation); batch archive/restore go through the v2 batch endpoints with per-item outcomes. </p><h3 class="sub" data-v-247f7c56>Page skeleton — a full-pane admin surface</h3><p data-v-247f7c56>A 48px title bar (a back IconButton — chevron-left, tooltip 返回, closing the page back to the chat underneath via <code data-v-247f7c56>closeSessionAdmin</code> — then the page title, semibold base; hairline bottom edge; on macOS desktop it doubles as the window-drag region and takes the chat header's collapsed-sidebar clearance — 146px / 78px / Windows fallback — so ONLY the bar insets, the body never does) → muted subtitle → query-form filter bar → table card → pager. The title bar and the scroll container are siblings (bar fixed, body scrolls). The page wrapper spans the whole conversation column — <b data-v-247f7c56>do not</b> apply the chat content measure (<code data-v-247f7c56>--p-content-max</code>) here: under <code data-v-247f7c56>table-layout: fixed</code> a narrow wrapper crushes the table's flexible columns to zero width (the title/prompt columns collapsed in practice). An admin table surface owns the pane width. The status filter defaults to 全部 (all) — the page is the whole inventory, 重置 restores that same default.</p><div class="callout warn" data-v-247f7c56><span class="ico" data-v-247f7c56>!</span><div data-v-247f7c56><b data-v-247f7c56>Lesson (content measure):</b> <code data-v-247f7c56>--p-content-max</code> is a READING measure for prose-like content (chat, dialogs). Full-bleed work surfaces — tables, grids, dashboards — span the pane instead. Pick one deliberately; inheriting the chat measure by default is the bug. </div></div><h3 class="sub" data-v-247f7c56>Table</h3><p data-v-247f7c56>The card is the flat shell: 0.5px <code data-v-247f7c56>--color-line</code> hairline, <code data-v-247f7c56>--radius-lg</code>, no shadow. Inside, <code data-v-247f7c56>table-layout: fixed</code> with a <code data-v-247f7c56>colgroup</code>: fixed-width utility columns (checkbox, workspace, status, the two time columns, actions) and two flexible content columns (title at <code data-v-247f7c56>max(200px, 20%)</code> — a floor, not a bare percentage — last prompt taking the rest). The head row is a pinned-height 32px box (it hosts the batch transform below); body rows are 40px. Rows are separated by 0.5px <code data-v-247f7c56>--color-subtle</code> hairlines (none after the last row), with a <code data-v-247f7c56>--color-hover</code> wash on hover. Every cell truncates single-line with ellipsis and carries a <code data-v-247f7c56>title</code> tooltip. Time columns are absolute (<code data-v-247f7c56>YYYY-MM-DD HH:mm</code>) in <code data-v-247f7c56>--font-mono</code> xs with <code data-v-247f7c56>tabular-nums</code> — the admin page is an audit view, so no relative times; empty values render a faint <code data-v-247f7c56>—</code>. The status column sits right after the workspace column and reuses the sidebar row's lifecycle glyphs: <code data-v-247f7c56>state-open</code> (dashed ring, <code data-v-247f7c56>--color-success</code>) for 进行中 and <code data-v-247f7c56>state-done</code> (checked ring, <code data-v-247f7c56>--color-done</code>) for 已完成, icon + label. First load swaps the body for a centered §03 Spinner; refetches keep the stale rows and dim the card (opacity + <code data-v-247f7c56>pointer-events: none</code>) rather than flashing it away; filters with no matches render the centered faint empty line.</p><p data-v-247f7c56><b data-v-247f7c56>Responsive steps</b> (the card is the query container; web's narrow panes matter too): the time columns give ground FIRST — at ≤1020px their values swap to the compact <code data-v-247f7c56>MM-DD HH:mm</code> at 108px (each time cell carries both spans, CSS toggles them — no JS measuring); at ≤760px the time columns hide outright (the <code data-v-247f7c56>col</code> and the cells share <code data-v-247f7c56>sa-c-time</code>/<code data-v-247f7c56>sa-col-time</code> classes) and the workspace column drops its folder icon. The table itself floors at 640px and the card takes <code data-v-247f7c56>overflow-x: auto</code> — past the floor the card scrolls horizontally instead of crushing title/prompt to zero, and auto still clips the rounded corners like hidden did.</p><table class="dt" data-v-247f7c56><thead data-v-247f7c56><tr data-v-247f7c56><th data-v-247f7c56>Column</th><th data-v-247f7c56>Width</th><th data-v-247f7c56>Content</th></tr></thead><tbody data-v-247f7c56><tr data-v-247f7c56><td class="tk" data-v-247f7c56>checkbox</td><td class="val" data-v-247f7c56>36px</td><td data-v-247f7c56>header select-this-page (indeterminate) + row checkboxes</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>会话名</td><td class="val" data-v-247f7c56>20%</td><td data-v-247f7c56>title (emoji verbatim), weight 475, ellipsis; hosts inline rename</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>工作空间</td><td class="val" data-v-247f7c56>116px</td><td data-v-247f7c56>folder-closed icon + workspace name (cwd basename fallback)</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>状态</td><td class="val" data-v-247f7c56>88px</td><td data-v-247f7c56>state-open/state-done glyph + label</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>最后一条 prompt</td><td class="val" data-v-247f7c56>flex</td><td data-v-247f7c56>muted, ellipsis, faint <code data-v-247f7c56>—</code> when null</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>最后更新 / 完成时间</td><td class="val" data-v-247f7c56>140px ×2</td><td data-v-247f7c56>mono tabular-nums absolute time; completed shows <code data-v-247f7c56>—</code> while open</td></tr><tr data-v-247f7c56><td class="tk" data-v-247f7c56>操作</td><td class="val" data-v-247f7c56>84px</td><td data-v-247f7c56>lifecycle IconButton (state-done completes an open row, undo reopens a done one; tooltips carry 标记完成/恢复进行中) + ⋯ IconButton dropdown (Rename… / Fork / Export)</td></tr></tbody></table><h3 class="sub" data-v-247f7c56>Batch header — the zero-offset transform</h3><p data-v-247f7c56>GitHub issues/PR semantics: while a selection exists, the head row transforms IN PLACE — the checkbox column stays put, and the remaining column headers swap for a single <code data-v-247f7c56><th colspan></code> batch bar ("已选 n 项" + Mark-as-done / Reopen, each disabled when the selection holds no row of that lifecycle) inside the SAME pinned 32px box, so the table body does not move a pixel. Mark-as-done is the bar's one accent-primary button (fill + on-accent icon/label); Reopen stays a quiet hairline button. The selection itself is facade-owned (a reactive id set plus a per-id lifecycle map, reconciled against fresh rows on every landing) and survives page and filter changes — the batch count deliberately includes rows no longer visible. Successful batch items leave the selection and the current page is silently re-pulled; failures stay selected. There is deliberately no "clear selection" button for ordinary selections: unchecking rows or the header checkbox is the way out. Toasts ride App.vue's shared ActionToast channel (succeeded count, failed count when partial, Undo through the inverse batch endpoint); an all-failed batch has nothing to undo and surfaces as a WarningToast instead.</p><h3 class="sub" data-v-247f7c56>Select-all-matching — the Gmail move</h3><p data-v-247f7c56>Page-size caps (≤100) make "mark everything done" hopeless against thousands of rows, so the batch bar borrows Gmail's escalation: once the header checkbox has the whole page selected and <code data-v-247f7c56>total</code> says more rows exist, a link-style button appears IN the bar (zero-offset — no banner pushing the table down): "选中当前条件下的全部 N 项" (busy-label 正在选中… while fetching). Activating it materializes every matching id into the selection via the ids projection (<code data-v-247f7c56>GET /api/v2/sessions?fields=id,archived</code> — the one cheap shape whose page_size ceiling relaxes to 10000; cursor-walked for larger sets), merging atomically: a filter change mid-flight discards the fetch entirely. While active the count reads "已选中全部 n 项" and the link becomes 清除选择. Exclusions are free — unchecking a row just drops it from the set; emptying the selection drops the mode, as does a right-click single-row collapse. The mode ties itself to the filter fingerprint it was built from: a real condition change (query-form apply with different values, or any granular setter) clears the whole selection — re-applying the SAME conditions keeps it. Batch executions chunk at the wire's 5000-unique-ids ceiling (sequential, merged per-item outcomes; a thrown chunk aborts the rest and counts everything unexecuted as failed — the succeeded ids still reconcile).</p><h3 class="sub" data-v-247f7c56>The quiet-button border reset</h3><p data-v-247f7c56>All quiet icon/text buttons on the page (the batch bar's Reopen, the pager buttons) set <code data-v-247f7c56>border: none; background: transparent</code> explicitly — or, for the bordered shapes (the filter triggers), an explicit 0.5px hairline. Row actions are pure §03 IconButtons (the sidebar row's language): the lifecycle glyph (<code data-v-247f7c56>state-done</code> completes an open row, <code data-v-247f7c56>undo</code> reopens a done one — tooltips carry the labels) plus the ⋯ dropdown; a text button per row read as visual noise once every row carried one.</p><div class="callout warn" data-v-247f7c56><span class="ico" data-v-247f7c56>!</span><div data-v-247f7c56><b data-v-247f7c56>Lesson (UA borders):</b> the global reset clears button backgrounds only — a bare <code data-v-247f7c56><button></code> still inherits the UA stylesheet's outset border, which reads as a stray box around every quiet control. Any quiet button outside the §03 primitives must reset both properties. </div></div><h3 class="sub" data-v-247f7c56>Quiet filter controls (query form)</h3><p data-v-247f7c56>The filter bar is a <b data-v-247f7c56>query form</b> (antd Pro semantics): the controls edit a local DRAFT only — nothing is requested until an explicit apply. 查询 (a §03 <code data-v-247f7c56>Button variant=primary size=sm</code>) applies the whole draft through the facade in one shot (<code data-v-247f7c56>applySessionAdminFilters</code> — atomic write + page reset + exactly one request, never the per-setter debounce dribble), 重置 (a <code data-v-247f7c56>ghost</code> sibling) restores defaults the same way, and Enter inside the bar queries too — except while any overlay (a select dropdown) is open, where Enter belongs to the overlay. Pagination is exempt: page/page-size changes still fetch immediately. Entry paths can pre-seed the conditions: the workspace home's 查看更多 opens the page with its workspace already selected in the filter (<code data-v-247f7c56>openSessionAdmin(workspaceId)</code> applies the filter atomically with the navigation), and because the page is v-show-kept, the draft re-seeds from the applied filters on EVERY entry so the controls always show the true conditions. The controls themselves are muted sm labels plus a family of quiet 30px hairline controls (0.5px <code data-v-247f7c56>--color-line</code>, <code data-v-247f7c56>--radius-md</code>, transparent ground, <code data-v-247f7c56>--color-hover</code> on hover/open) — deliberately NOT the §03 Select (a 32px+ form control with an accent focus ring, too heavy for a filter strip):</p><ul class="clean" data-v-247f7c56><li data-v-247f7c56><b data-v-247f7c56>FilterSelect</b> — quiet single-select (status, updated time, page size): the trigger carries the current label + a faint chevron; the dropdown is the §03 Menu surface with a leading fixed-width check slot and an optional lifecycle dot (<code data-v-247f7c56>--color-success</code> open / <code data-v-247f7c56>--color-done</code> done).</li><li data-v-247f7c56><b data-v-247f7c56>MultiSelectMenu</b> — workspace multi-select: the trigger shows the selection as removable tags (at most two, then "+N"; empty = the 全部工作空间 placeholder). The anchored panel leads with a search row (case-insensitive name filter, autofocused, reset on close), then a Select-all row, then the option rows — no checkboxes, selected rows take the active highlight. The options area is capped at 320px with its own scroll (in-menu scrolls never close the panel); the panel STAYS OPEN on toggles so several workspaces can be picked in one go (Esc / outside click / outside scroll closes). Empty selection = no filter.</li><li data-v-247f7c56><b data-v-247f7c56>Updated-time presets</b> — a FilterSelect of relative windows (全部时间 / 3 天以前 / 7 天以前 / 30 天以前): a pick maps onto the facade's <code data-v-247f7c56>updatedTo</code> bound as the local calendar day N days back (computed at apply time, so a saved draft never goes stale), and the facade's day-end mapping turns it into <code data-v-247f7c56>updatedBefore</code>. Deliberately not a calendar range picker — triage asks "older than X", not "between two dates".</li></ul><h3 class="sub" data-v-247f7c56>Point-anchored context menus</h3><p data-v-247f7c56><code data-v-247f7c56>useAnchoredMenu</code> is the page's one menu mechanic: fixed-position §03 Menu surface, pop-from-anchor motion (fade + 0.97 scale on the menu tokens, origin and nudge following the upward flip at the viewport edge), closed by outside mousedown / Esc / scroll / resize. Three anchor modes — left-aligned under a trigger (filter selects), right-edge under a trigger (the row ⋯), and <code data-v-247f7c56>openAt(x, y)</code> at a raw viewport point for the row contextmenu. The contextmenu has two shapes: on a row outside the multi-selection the selection first collapses to just that row and the menu is the single shape (Open session / Rename… / Fork / Export / — / the lifecycle action); on a row inside it, the multi shape (a muted count head + Mark-as-done (n) / Reopen (n), disabled per availability). Open session is the facade's <code data-v-247f7c56>selectSession</code> — a user navigation that also leaves the admin page back to chat.</p><h3 class="sub" data-v-247f7c56>Inline rename</h3><p data-v-247f7c56>The title cell swaps for an accent-ringed input (<code data-v-247f7c56>--color-accent</code> border + <code data-v-247f7c56>--color-accent-bd</code> ring, <code data-v-247f7c56>--radius-sm</code>) — Enter commits, Esc cancels, blur commits, settled once. The table is server-fed, so a commit is followed by a silent re-pull of the current page (the facade's pool update never reaches it).</p></section>',7))])])])]))}}),Pt=O(Lt,[["__scopeId","data-v-247f7c56"]]);export{Pt as default}; diff --git a/apps/kimi-code/dist-web/assets/Tooltip-06BtTYE8.js b/apps/kimi-code/dist-web/assets/Tooltip-DbYQWF1U.js similarity index 98% rename from apps/kimi-code/dist-web/assets/Tooltip-06BtTYE8.js rename to apps/kimi-code/dist-web/assets/Tooltip-DbYQWF1U.js index 7c64e499a..2977411a4 100644 --- a/apps/kimi-code/dist-web/assets/Tooltip-06BtTYE8.js +++ b/apps/kimi-code/dist-web/assets/Tooltip-DbYQWF1U.js @@ -1 +1 @@ -import{bQ as A,M as H,aU as b,bE as V,az as J,aL as O,s as Q,v as R,I as F,bJ as G,bL as K,aw as L,H as W,bb as Z,bB as ee,g as te,au as le,T as ae,as as B,bR as ne}from"./index-D1h84VfZ.js";var k=(h,E,e)=>new Promise((o,p)=>{var i=a=>{try{d(e.next(a))}catch(c){p(c)}},y=a=>{try{d(e.throw(a))}catch(c){p(c)}},d=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,y);d((e=e.apply(h,E)).next())});const oe=["id"],ie=["data-placement"],ue=A(H({__name:"Tooltip",props:{visible:{type:Boolean},anchorEl:{},content:{},placement:{},offset:{},originX:{},originY:{},id:{},isDark:{type:[Boolean,null]}},setup(h){var E;const e=h,o=b(null),p=b(null),i=b({transform:"translate3d(0px, 0px, 0px)",left:"0px",top:"0px"}),y=b({}),d=b((E=e.placement)!=null?E:"top"),a=b(!1);let c=null,$=null,T=null,C=null,w=null,s=0;function X(){return C?Promise.resolve(C):(w||(w=ne(()=>import("./floating-ui.dom-xGUaHE3m.js"),[]).then(l=>(C=l,l)).catch(l=>{throw w=null,l})),w)}function D(){c&&(c(),c=null),$=null,T=null}function P(l){return k(this,null,function*(){const t=e.anchorEl,n=o.value;if(!e.visible||!t||!n||$===t&&T===n)return;const{autoUpdate:r}=yield X();l()&&e.visible&&e.anchorEl===t&&o.value===n&&(D(),$=t,T=n,c=r(t,n,()=>{N().catch(()=>{_()})}))})}function N(){return k(this,null,function*(){var l,t;const n=e.anchorEl,r=o.value;if(!e.visible||!n||!r)return!1;const{arrow:u,computePosition:m,flip:v,offset:f,shift:x}=yield X();if(!e.visible||e.anchorEl!==n||o.value!==r)return!1;const g=[f((l=e.offset)!=null?l:6),v(),x({padding:6}),...p.value?[u({element:p.value,padding:4})]:[]],{x:S,y:j,placement:Y,middlewareData:z}=yield m(n,r,{placement:(t=e.placement)!=null?t:"top",middleware:g,strategy:"fixed"});if(!e.visible||e.anchorEl!==n||o.value!==r)return!1;if(i.value.transform=`translate3d(${Math.round(S)}px, ${Math.round(j)}px, 0)`,i.value.left="0px",i.value.top="0px",d.value=Y,z.arrow&&p.value){const{x:I,y:U}=z.arrow,q={top:"bottom",bottom:"top",left:"right",right:"left"}[Y.split("-")[0]];y.value={left:I!=null?`${I}px`:"",top:U!=null?`${U}px`:"",[q]:"-3px"}}return!0})}function _(){var l,t;const n=e.anchorEl,r=o.value;if(!n||!r)return!1;const u=n.getBoundingClientRect(),m=r.getBoundingClientRect(),v=(l=e.offset)!=null?l:6,f=(t=e.placement)!=null?t:"top";let x=u.left,g=u.top;return f==="bottom"?g=u.bottom+v:f==="left"?x=u.left-m.width-v:f==="right"?x=u.right+v:g=u.top-m.height-v,i.value.transform=`translate3d(${Math.round(Math.max(0,x))}px, ${Math.round(Math.max(0,g))}px, 0)`,i.value.left="0px",i.value.top="0px",d.value=f,y.value={},!0}V(()=>e.visible,l=>k(null,null,function*(){const t=++s;if(l){if(a.value=!1,yield B(),t!==s||!e.visible)return;if(e.anchorEl&&o.value)try{const n=e.anchorEl,r=o.value,u=n.getBoundingClientRect();if(!(yield N())||t!==s||!e.visible||e.anchorEl!==n||o.value!==r)return;const m=i.value.transform;if(e.originX!=null&&e.originY!=null){const v=Math.abs(Number(e.originX)-u.left),f=Math.abs(Number(e.originY)-u.top);if(Math.hypot(v,f)>120){if(i.value.transform=`translate3d(${Math.round(e.originX)}px, ${Math.round(e.originY)}px, 0)`,yield B(),t!==s||!e.visible||(a.value=!0,yield B(),t!==s||!e.visible))return;i.value.transform=m}else a.value=!0}else a.value=!0;yield P(()=>t===s)}catch{if(t!==s||!e.visible)return;if(a.value=_(),e.anchorEl&&o.value)try{yield P(()=>t===s)}catch{}}else a.value=!0}else a.value=!1,D()}));let M=0;return V([()=>e.anchorEl,()=>e.placement,()=>e.content],()=>k(null,null,function*(){const l=++M;if(e.visible&&e.anchorEl&&o.value){if(yield B(),l!==M||!e.visible||!e.anchorEl||!o.value)return;try{const t=yield N();if(l!==M||!e.visible||!e.anchorEl||!o.value)return;t||_()}catch{_()}yield P(()=>l===M)}})),J(()=>{s+=1,D()}),(l,t)=>(O(),Q(ae,{to:"body"},[R("div",{class:le(["markstream-vue",{dark:h.isDark}])},[F(te,{name:"tooltip",appear:""},{default:G(()=>[K(R("div",{id:e.id,ref_key:"tooltip",ref:o,style:L({position:"fixed",left:i.value.left,top:i.value.top,transform:i.value.transform,visibility:a.value?"visible":"hidden",pointerEvents:a.value?void 0:"none"}),class:"tooltip-element",role:"tooltip"},[W(Z(h.content)+" ",1),R("div",{ref_key:"arrowEl",ref:p,class:"tooltip-arrow","data-placement":d.value,style:L(y.value)},null,12,ie)],12,oe),[[ee,h.visible]])]),_:1})],2)]))}}),[["__scopeId","data-v-c606ee4c"]]);export{ue as default}; +import{bQ as A,M as H,aU as b,bE as V,az as J,aL as O,s as Q,v as R,I as F,bJ as G,bL as K,aw as L,H as W,bb as Z,bB as ee,g as te,au as le,T as ae,as as B,bR as ne}from"./index-D-7nOosq.js";var k=(h,E,e)=>new Promise((o,p)=>{var i=a=>{try{d(e.next(a))}catch(c){p(c)}},y=a=>{try{d(e.throw(a))}catch(c){p(c)}},d=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,y);d((e=e.apply(h,E)).next())});const oe=["id"],ie=["data-placement"],ue=A(H({__name:"Tooltip",props:{visible:{type:Boolean},anchorEl:{},content:{},placement:{},offset:{},originX:{},originY:{},id:{},isDark:{type:[Boolean,null]}},setup(h){var E;const e=h,o=b(null),p=b(null),i=b({transform:"translate3d(0px, 0px, 0px)",left:"0px",top:"0px"}),y=b({}),d=b((E=e.placement)!=null?E:"top"),a=b(!1);let c=null,$=null,T=null,C=null,w=null,s=0;function X(){return C?Promise.resolve(C):(w||(w=ne(()=>import("./floating-ui.dom-xGUaHE3m.js"),[]).then(l=>(C=l,l)).catch(l=>{throw w=null,l})),w)}function D(){c&&(c(),c=null),$=null,T=null}function P(l){return k(this,null,function*(){const t=e.anchorEl,n=o.value;if(!e.visible||!t||!n||$===t&&T===n)return;const{autoUpdate:r}=yield X();l()&&e.visible&&e.anchorEl===t&&o.value===n&&(D(),$=t,T=n,c=r(t,n,()=>{N().catch(()=>{_()})}))})}function N(){return k(this,null,function*(){var l,t;const n=e.anchorEl,r=o.value;if(!e.visible||!n||!r)return!1;const{arrow:u,computePosition:m,flip:v,offset:f,shift:x}=yield X();if(!e.visible||e.anchorEl!==n||o.value!==r)return!1;const g=[f((l=e.offset)!=null?l:6),v(),x({padding:6}),...p.value?[u({element:p.value,padding:4})]:[]],{x:S,y:j,placement:Y,middlewareData:z}=yield m(n,r,{placement:(t=e.placement)!=null?t:"top",middleware:g,strategy:"fixed"});if(!e.visible||e.anchorEl!==n||o.value!==r)return!1;if(i.value.transform=`translate3d(${Math.round(S)}px, ${Math.round(j)}px, 0)`,i.value.left="0px",i.value.top="0px",d.value=Y,z.arrow&&p.value){const{x:I,y:U}=z.arrow,q={top:"bottom",bottom:"top",left:"right",right:"left"}[Y.split("-")[0]];y.value={left:I!=null?`${I}px`:"",top:U!=null?`${U}px`:"",[q]:"-3px"}}return!0})}function _(){var l,t;const n=e.anchorEl,r=o.value;if(!n||!r)return!1;const u=n.getBoundingClientRect(),m=r.getBoundingClientRect(),v=(l=e.offset)!=null?l:6,f=(t=e.placement)!=null?t:"top";let x=u.left,g=u.top;return f==="bottom"?g=u.bottom+v:f==="left"?x=u.left-m.width-v:f==="right"?x=u.right+v:g=u.top-m.height-v,i.value.transform=`translate3d(${Math.round(Math.max(0,x))}px, ${Math.round(Math.max(0,g))}px, 0)`,i.value.left="0px",i.value.top="0px",d.value=f,y.value={},!0}V(()=>e.visible,l=>k(null,null,function*(){const t=++s;if(l){if(a.value=!1,yield B(),t!==s||!e.visible)return;if(e.anchorEl&&o.value)try{const n=e.anchorEl,r=o.value,u=n.getBoundingClientRect();if(!(yield N())||t!==s||!e.visible||e.anchorEl!==n||o.value!==r)return;const m=i.value.transform;if(e.originX!=null&&e.originY!=null){const v=Math.abs(Number(e.originX)-u.left),f=Math.abs(Number(e.originY)-u.top);if(Math.hypot(v,f)>120){if(i.value.transform=`translate3d(${Math.round(e.originX)}px, ${Math.round(e.originY)}px, 0)`,yield B(),t!==s||!e.visible||(a.value=!0,yield B(),t!==s||!e.visible))return;i.value.transform=m}else a.value=!0}else a.value=!0;yield P(()=>t===s)}catch{if(t!==s||!e.visible)return;if(a.value=_(),e.anchorEl&&o.value)try{yield P(()=>t===s)}catch{}}else a.value=!0}else a.value=!1,D()}));let M=0;return V([()=>e.anchorEl,()=>e.placement,()=>e.content],()=>k(null,null,function*(){const l=++M;if(e.visible&&e.anchorEl&&o.value){if(yield B(),l!==M||!e.visible||!e.anchorEl||!o.value)return;try{const t=yield N();if(l!==M||!e.visible||!e.anchorEl||!o.value)return;t||_()}catch{_()}yield P(()=>l===M)}})),J(()=>{s+=1,D()}),(l,t)=>(O(),Q(ae,{to:"body"},[R("div",{class:le(["markstream-vue",{dark:h.isDark}])},[F(te,{name:"tooltip",appear:""},{default:G(()=>[K(R("div",{id:e.id,ref_key:"tooltip",ref:o,style:L({position:"fixed",left:i.value.left,top:i.value.top,transform:i.value.transform,visibility:a.value?"visible":"hidden",pointerEvents:a.value?void 0:"none"}),class:"tooltip-element",role:"tooltip"},[W(Z(h.content)+" ",1),R("div",{ref_key:"arrowEl",ref:p,class:"tooltip-arrow","data-placement":d.value,style:L(y.value)},null,12,ie)],12,oe),[[ee,h.visible]])]),_:1})],2)]))}}),[["__scopeId","data-v-c606ee4c"]]);export{ue as default}; diff --git a/apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-BXPcW32X.js b/apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-C0Afmuc1.js similarity index 86% rename from apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-BXPcW32X.js rename to apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-C0Afmuc1.js index ed41ade56..e0a31a7b0 100644 --- a/apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-BXPcW32X.js +++ b/apps/kimi-code/dist-web/assets/abnfDiagram-VRR7QNED-C0Afmuc1.js @@ -1 +1 @@ -import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-Ce2Y728v.js";import{p as f}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as n,l as o}from"./mermaid.core-DaDTfY6S.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},F={parser:R,db:a,renderer:u,styles:p};export{F as diagram}; +import{g as p,r as u,d as a}from"./chunk-MOJQB5TN-JQ2kJR9W.js";import{p as f}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as n,l as o}from"./mermaid.core-CJB1tAev.js";import{M as c,b as d}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var v=d().RailroadAbnf.parser.LangiumParser,i=n(e=>{const r=e.alternatives.map(g);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformAlternation"),g=n(e=>{const r=e.elements.map(y);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformConcatenation"),b=n(e=>{if(e.includes("*")){const[t,s]=e.split("*"),l=t?parseInt(t,10):0,m=s?parseInt(s,10):1/0;return{min:l,max:m}}const r=parseInt(e,10);return{min:r,max:r}},"parseRepeat"),y=n(e=>{const r=A(e.primary);if(!e.repeat)return r;const{min:t,max:s}=b(e.repeat);return t===0&&s===1?{type:"optional",element:r}:{type:"repetition",element:r,min:t,max:s}},"transformElement"),A=n(e=>{switch(e.$type){case"AbnfStringLiteral":return{type:"terminal",value:e.value};case"AbnfNumVal":return{type:"terminal",value:e.value};case"AbnfRuleName":return{type:"nonterminal",name:e.name};case"AbnfGroup":return i(e.element);case"AbnfOptionalGroup":return{type:"optional",element:i(e.element)};default:throw new Error(`Unsupported ABNF primary node: ${e.$type}`)}},"transformPrimary"),P=n(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=n(e=>{f(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(P(r)))},"populateDb"),R={parse:n(e=>{a.clear(),o.debug("[ABNF Parser] Starting Langium parse");const r=v.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new c(r);const t=r.value;o.debug("[ABNF Parser] Parsed rules:",t.rules.length),h(t),o.debug("[ABNF Parser] Parse complete")},"parse"),parser:{yy:a}},F={parser:R,db:a,renderer:u,styles:p};export{F as diagram}; diff --git a/apps/kimi-code/dist-web/assets/arc-CC9q5kjc.js b/apps/kimi-code/dist-web/assets/arc-IkhU3FHH.js similarity index 98% rename from apps/kimi-code/dist-web/assets/arc-CC9q5kjc.js rename to apps/kimi-code/dist-web/assets/arc-IkhU3FHH.js index 6f0402dba..2c68be080 100644 --- a/apps/kimi-code/dist-web/assets/arc-CC9q5kjc.js +++ b/apps/kimi-code/dist-web/assets/arc-IkhU3FHH.js @@ -1 +1 @@ -import{G as ln,H as un,I as N,J as I,K as J,L as an,M as y,N as tn,O as j,P as _,Q as rn,R as o,S as on,T as sn,V as fn}from"./mermaid.core-DaDTfY6S.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,q,O,v,R,K,u){var D=q-l,i=O-h,n=K-v,d=u-R,a=d*D-n*i;if(!(a*a<y))return a=(n*(h-R)-d*(l-v))/a,[l+a*D,h+a*i]}function W(l,h,q,O,v,R,K){var u=l-q,D=h-O,i=(K?R:-R)/j(u*u+D*D),n=i*D,d=-i*u,a=l+n,s=h+d,f=q+n,c=O+d,L=(a+f)/2,t=(s+c)/2,m=f-a,g=c-s,A=m*m+g*g,T=v-R,P=a*c-f*s,E=(g<0?-1:1)*j(on(0,T*T*A-P*P)),G=(P*g-m*E)/A,H=(-P*m-g*E)/A,w=(P*g+m*E)/A,p=(-P*m+g*E)/A,x=G-L,e=H-t,r=w-L,M=p-t;return x*x+e*e>r*r+M*M&&(G=w,H=p),{cx:G,cy:H,x01:-n,y01:-d,x11:G*(v/T-1),y11:H*(v/T-1)}}function hn(){var l=cn,h=yn,q=J(0),O=null,v=gn,R=dn,K=mn,u=null,D=ln(i);function i(){var n,d,a=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=R.apply(this,arguments)-an,L=rn(c-f),t=c>f;if(u||(u=n=D()),s<a&&(d=s,s=a,a=d),!(s>y))u.moveTo(0,0);else if(L>tn-y)u.moveTo(s*N(f),s*I(f)),u.arc(0,0,s,f,c,!t),a>y&&(u.moveTo(a*N(c),a*I(c)),u.arc(0,0,a,c,f,t));else{var m=f,g=c,A=f,T=c,P=L,E=L,G=K.apply(this,arguments)/2,H=G>y&&(O?+O.apply(this,arguments):j(a*a+s*s)),w=_(rn(s-a)/2,+q.apply(this,arguments)),p=w,x=w,e,r;if(H>y){var M=sn(H/a*I(G)),z=sn(H/s*I(G));(P-=M*2)>y?(M*=t?1:-1,A+=M,T-=M):(P=0,A=T=(f+c)/2),(E-=z*2)>y?(z*=t?1:-1,m+=z,g-=z):(E=0,m=g=(f+c)/2)}var Q=s*N(m),V=s*I(m),B=a*N(T),C=a*I(T);if(w>y){var F=s*N(g),U=s*I(g),X=a*N(A),Y=a*I(A),S;if(L<un)if(S=pn(Q,V,X,Y,F,U,B,C)){var Z=Q-S[0],$=V-S[1],k=F-S[0],b=U-S[1],nn=1/I(fn((Z*k+$*b)/(j(Z*Z+$*$)*j(k*k+b*b)))/2),en=j(S[0]*S[0]+S[1]*S[1]);p=_(w,(a-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}E>y?x>y?(e=W(X,Y,Q,V,s,x,t),r=W(F,U,B,C,s,x,t),u.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?u.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(u.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),u.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),u.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(u.moveTo(Q,V),u.arc(0,0,s,m,g,!t)):u.moveTo(Q,V),!(a>y)||!(P>y)?u.lineTo(B,C):p>y?(e=W(B,C,F,U,a,-p,t),r=W(Q,V,X,Y,a,-p,t),u.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?u.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(u.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),u.arc(0,0,a,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),u.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):u.arc(0,0,a,T,A,t)}if(u.closePath(),n)return u=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +R.apply(this,arguments))/2-un/2;return[N(d)*n,I(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:J(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:J(+n),i):h},i.cornerRadius=function(n){return arguments.length?(q=typeof n=="function"?n:J(+n),i):q},i.padRadius=function(n){return arguments.length?(O=n==null?null:typeof n=="function"?n:J(+n),i):O},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:J(+n),i):v},i.endAngle=function(n){return arguments.length?(R=typeof n=="function"?n:J(+n),i):R},i.padAngle=function(n){return arguments.length?(K=typeof n=="function"?n:J(+n),i):K},i.context=function(n){return arguments.length?(u=n??null,i):u},i}export{hn as d}; +import{G as ln,H as un,I as N,J as I,K as J,L as an,M as y,N as tn,O as j,P as _,Q as rn,R as o,S as on,T as sn,V as fn}from"./mermaid.core-CJB1tAev.js";function cn(l){return l.innerRadius}function yn(l){return l.outerRadius}function gn(l){return l.startAngle}function dn(l){return l.endAngle}function mn(l){return l&&l.padAngle}function pn(l,h,q,O,v,R,K,u){var D=q-l,i=O-h,n=K-v,d=u-R,a=d*D-n*i;if(!(a*a<y))return a=(n*(h-R)-d*(l-v))/a,[l+a*D,h+a*i]}function W(l,h,q,O,v,R,K){var u=l-q,D=h-O,i=(K?R:-R)/j(u*u+D*D),n=i*D,d=-i*u,a=l+n,s=h+d,f=q+n,c=O+d,L=(a+f)/2,t=(s+c)/2,m=f-a,g=c-s,A=m*m+g*g,T=v-R,P=a*c-f*s,E=(g<0?-1:1)*j(on(0,T*T*A-P*P)),G=(P*g-m*E)/A,H=(-P*m-g*E)/A,w=(P*g+m*E)/A,p=(-P*m+g*E)/A,x=G-L,e=H-t,r=w-L,M=p-t;return x*x+e*e>r*r+M*M&&(G=w,H=p),{cx:G,cy:H,x01:-n,y01:-d,x11:G*(v/T-1),y11:H*(v/T-1)}}function hn(){var l=cn,h=yn,q=J(0),O=null,v=gn,R=dn,K=mn,u=null,D=ln(i);function i(){var n,d,a=+l.apply(this,arguments),s=+h.apply(this,arguments),f=v.apply(this,arguments)-an,c=R.apply(this,arguments)-an,L=rn(c-f),t=c>f;if(u||(u=n=D()),s<a&&(d=s,s=a,a=d),!(s>y))u.moveTo(0,0);else if(L>tn-y)u.moveTo(s*N(f),s*I(f)),u.arc(0,0,s,f,c,!t),a>y&&(u.moveTo(a*N(c),a*I(c)),u.arc(0,0,a,c,f,t));else{var m=f,g=c,A=f,T=c,P=L,E=L,G=K.apply(this,arguments)/2,H=G>y&&(O?+O.apply(this,arguments):j(a*a+s*s)),w=_(rn(s-a)/2,+q.apply(this,arguments)),p=w,x=w,e,r;if(H>y){var M=sn(H/a*I(G)),z=sn(H/s*I(G));(P-=M*2)>y?(M*=t?1:-1,A+=M,T-=M):(P=0,A=T=(f+c)/2),(E-=z*2)>y?(z*=t?1:-1,m+=z,g-=z):(E=0,m=g=(f+c)/2)}var Q=s*N(m),V=s*I(m),B=a*N(T),C=a*I(T);if(w>y){var F=s*N(g),U=s*I(g),X=a*N(A),Y=a*I(A),S;if(L<un)if(S=pn(Q,V,X,Y,F,U,B,C)){var Z=Q-S[0],$=V-S[1],k=F-S[0],b=U-S[1],nn=1/I(fn((Z*k+$*b)/(j(Z*Z+$*$)*j(k*k+b*b)))/2),en=j(S[0]*S[0]+S[1]*S[1]);p=_(w,(a-en)/(nn-1)),x=_(w,(s-en)/(nn+1))}else p=x=0}E>y?x>y?(e=W(X,Y,Q,V,s,x,t),r=W(F,U,B,C,s,x,t),u.moveTo(e.cx+e.x01,e.cy+e.y01),x<w?u.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(r.y01,r.x01),!t):(u.arc(e.cx,e.cy,x,o(e.y01,e.x01),o(e.y11,e.x11),!t),u.arc(0,0,s,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),!t),u.arc(r.cx,r.cy,x,o(r.y11,r.x11),o(r.y01,r.x01),!t))):(u.moveTo(Q,V),u.arc(0,0,s,m,g,!t)):u.moveTo(Q,V),!(a>y)||!(P>y)?u.lineTo(B,C):p>y?(e=W(B,C,F,U,a,-p,t),r=W(Q,V,X,Y,a,-p,t),u.lineTo(e.cx+e.x01,e.cy+e.y01),p<w?u.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(r.y01,r.x01),!t):(u.arc(e.cx,e.cy,p,o(e.y01,e.x01),o(e.y11,e.x11),!t),u.arc(0,0,a,o(e.cy+e.y11,e.cx+e.x11),o(r.cy+r.y11,r.cx+r.x11),t),u.arc(r.cx,r.cy,p,o(r.y11,r.x11),o(r.y01,r.x01),!t))):u.arc(0,0,a,T,A,t)}if(u.closePath(),n)return u=null,n+""||null}return i.centroid=function(){var n=(+l.apply(this,arguments)+ +h.apply(this,arguments))/2,d=(+v.apply(this,arguments)+ +R.apply(this,arguments))/2-un/2;return[N(d)*n,I(d)*n]},i.innerRadius=function(n){return arguments.length?(l=typeof n=="function"?n:J(+n),i):l},i.outerRadius=function(n){return arguments.length?(h=typeof n=="function"?n:J(+n),i):h},i.cornerRadius=function(n){return arguments.length?(q=typeof n=="function"?n:J(+n),i):q},i.padRadius=function(n){return arguments.length?(O=n==null?null:typeof n=="function"?n:J(+n),i):O},i.startAngle=function(n){return arguments.length?(v=typeof n=="function"?n:J(+n),i):v},i.endAngle=function(n){return arguments.length?(R=typeof n=="function"?n:J(+n),i):R},i.padAngle=function(n){return arguments.length?(K=typeof n=="function"?n:J(+n),i):K},i.context=function(n){return arguments.length?(u=n??null,i):u},i}export{hn as d}; diff --git a/apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-BkXVAeQG.js b/apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-CBluWNBt.js similarity index 99% rename from apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-BkXVAeQG.js rename to apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-CBluWNBt.js index 4c76304d5..f45d0cb17 100644 --- a/apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-BkXVAeQG.js +++ b/apps/kimi-code/dist-web/assets/architectureDiagram-ZJ3FMSHR-CBluWNBt.js @@ -1,4 +1,4 @@ -import{p as ke}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as gt,F as Ze,ad as qe,l as Se,b as Qe,a as Je,o as Ke,p as je,g as _e,s as tr,q as er,B as rr,z as ir,D as ar,c as me,a$ as Ee,ai as ve,i as nr,d as or,r as sr,aj as hr,b7 as lr}from"./mermaid.core-DaDTfY6S.js";import{p as fr}from"./cynefin-VYW2F7L2-0NmB13eq.js";import{c as Fe}from"./cytoscape.esm-OyMbaexL.js";import{g as cr}from"./_commonjsHelpers-CqkleIqs.js";import"./index-D1h84VfZ.js";var se={exports:{}},he={exports:{}},le={exports:{}},gr=le.exports,Me;function ur(){return Me||(Me=1,(function(L,b){(function(G,N){L.exports=N()})(gr,function(){return(function(A){var G={};function N(v){if(G[v])return G[v].exports;var h=G[v]={i:v,l:!1,exports:{}};return A[v].call(h.exports,h,h.exports,N),h.l=!0,h.exports}return N.m=A,N.c=G,N.i=function(v){return v},N.d=function(v,h,i){N.o(v,h)||Object.defineProperty(v,h,{configurable:!1,enumerable:!0,get:i})},N.n=function(v){var h=v&&v.__esModule?function(){return v.default}:function(){return v};return N.d(h,"a",h),h},N.o=function(v,h){return Object.prototype.hasOwnProperty.call(v,h)},N.p="",N(N.s=28)})([(function(A,G,N){function v(){}v.QUALITY=1,v.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,v.DEFAULT_INCREMENTAL=!1,v.DEFAULT_ANIMATION_ON_LAYOUT=!0,v.DEFAULT_ANIMATION_DURING_LAYOUT=!1,v.DEFAULT_ANIMATION_PERIOD=50,v.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,v.DEFAULT_GRAPH_MARGIN=15,v.NODE_DIMENSIONS_INCLUDE_LABELS=!1,v.SIMPLE_NODE_SIZE=40,v.SIMPLE_NODE_HALF_SIZE=v.SIMPLE_NODE_SIZE/2,v.EMPTY_COMPOUND_NODE_SIZE=40,v.MIN_EDGE_LENGTH=1,v.WORLD_BOUNDARY=1e6,v.INITIAL_WORLD_BOUNDARY=v.WORLD_BOUNDARY/1e3,v.WORLD_CENTER_X=1200,v.WORLD_CENTER_Y=900,A.exports=v}),(function(A,G,N){var v=N(2),h=N(8),i=N(9);function r(f,e,u){v.call(this,u),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=u,this.bendpoints=[],this.source=f,this.target=e}r.prototype=Object.create(v.prototype);for(var a in v)r[a]=v[a];r.prototype.getSource=function(){return this.source},r.prototype.getTarget=function(){return this.target},r.prototype.isInterGraph=function(){return this.isInterGraph},r.prototype.getLength=function(){return this.length},r.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},r.prototype.getBendpoints=function(){return this.bendpoints},r.prototype.getLca=function(){return this.lca},r.prototype.getSourceInLca=function(){return this.sourceInLca},r.prototype.getTargetInLca=function(){return this.targetInLca},r.prototype.getOtherEnd=function(f){if(this.source===f)return this.target;if(this.target===f)return this.source;throw"Node is not incident with this edge"},r.prototype.getOtherEndInGraph=function(f,e){for(var u=this.getOtherEnd(f),t=e.getGraphManager().getRoot();;){if(u.getOwner()==e)return u;if(u.getOwner()==t)break;u=u.getOwner().getParent()}return null},r.prototype.updateLength=function(){var f=new Array(4);this.isOverlapingSourceAndTarget=h.getIntersection(this.target.getRect(),this.source.getRect(),f),this.isOverlapingSourceAndTarget||(this.lengthX=f[0]-f[2],this.lengthY=f[1]-f[3],Math.abs(this.lengthX)<1&&(this.lengthX=i.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=i.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},r.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=i.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=i.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},A.exports=r}),(function(A,G,N){function v(h){this.vGraphObject=h}A.exports=v}),(function(A,G,N){var v=N(2),h=N(10),i=N(13),r=N(0),a=N(16),f=N(5);function e(t,s,o,c){o==null&&c==null&&(c=s),v.call(this,c),t.graphManager!=null&&(t=t.graphManager),this.estimatedSize=h.MIN_VALUE,this.inclusionTreeDepth=h.MAX_VALUE,this.vGraphObject=c,this.edges=[],this.graphManager=t,o!=null&&s!=null?this.rect=new i(s.x,s.y,o.width,o.height):this.rect=new i}e.prototype=Object.create(v.prototype);for(var u in v)e[u]=v[u];e.prototype.getEdges=function(){return this.edges},e.prototype.getChild=function(){return this.child},e.prototype.getOwner=function(){return this.owner},e.prototype.getWidth=function(){return this.rect.width},e.prototype.setWidth=function(t){this.rect.width=t},e.prototype.getHeight=function(){return this.rect.height},e.prototype.setHeight=function(t){this.rect.height=t},e.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},e.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},e.prototype.getCenter=function(){return new f(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},e.prototype.getLocation=function(){return new f(this.rect.x,this.rect.y)},e.prototype.getRect=function(){return this.rect},e.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},e.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},e.prototype.setRect=function(t,s){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=s.width,this.rect.height=s.height},e.prototype.setCenter=function(t,s){this.rect.x=t-this.rect.width/2,this.rect.y=s-this.rect.height/2},e.prototype.setLocation=function(t,s){this.rect.x=t,this.rect.y=s},e.prototype.moveBy=function(t,s){this.rect.x+=t,this.rect.y+=s},e.prototype.getEdgeListToNode=function(t){var s=[],o=this;return o.edges.forEach(function(c){if(c.target==t){if(c.source!=o)throw"Incorrect edge source!";s.push(c)}}),s},e.prototype.getEdgesBetween=function(t){var s=[],o=this;return o.edges.forEach(function(c){if(!(c.source==o||c.target==o))throw"Incorrect edge source and/or target";(c.target==t||c.source==t)&&s.push(c)}),s},e.prototype.getNeighborsList=function(){var t=new Set,s=this;return s.edges.forEach(function(o){if(o.source==s)t.add(o.target);else{if(o.target!=s)throw"Incorrect incidency!";t.add(o.source)}}),t},e.prototype.withChildren=function(){var t=new Set,s,o;if(t.add(this),this.child!=null)for(var c=this.child.getNodes(),l=0;l<c.length;l++)s=c[l],o=s.withChildren(),o.forEach(function(T){t.add(T)});return t},e.prototype.getNoOfChildren=function(){var t=0,s;if(this.child==null)t=1;else for(var o=this.child.getNodes(),c=0;c<o.length;c++)s=o[c],t+=s.getNoOfChildren();return t==0&&(t=1),t},e.prototype.getEstimatedSize=function(){if(this.estimatedSize==h.MIN_VALUE)throw"assert failed";return this.estimatedSize},e.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},e.prototype.scatter=function(){var t,s,o=-r.INITIAL_WORLD_BOUNDARY,c=r.INITIAL_WORLD_BOUNDARY;t=r.WORLD_CENTER_X+a.nextDouble()*(c-o)+o;var l=-r.INITIAL_WORLD_BOUNDARY,T=r.INITIAL_WORLD_BOUNDARY;s=r.WORLD_CENTER_Y+a.nextDouble()*(T-l)+l,this.rect.x=t,this.rect.y=s},e.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var t=this.getChild();if(t.updateBounds(!0),this.rect.x=t.getLeft(),this.rect.y=t.getTop(),this.setWidth(t.getRight()-t.getLeft()),this.setHeight(t.getBottom()-t.getTop()),r.NODE_DIMENSIONS_INCLUDE_LABELS){var s=t.getRight()-t.getLeft(),o=t.getBottom()-t.getTop();this.labelWidth&&(this.labelPosHorizontal=="left"?(this.rect.x-=this.labelWidth,this.setWidth(s+this.labelWidth)):this.labelPosHorizontal=="center"&&this.labelWidth>s?(this.rect.x-=(this.labelWidth-s)/2,this.setWidth(this.labelWidth)):this.labelPosHorizontal=="right"&&this.setWidth(s+this.labelWidth)),this.labelHeight&&(this.labelPosVertical=="top"?(this.rect.y-=this.labelHeight,this.setHeight(o+this.labelHeight)):this.labelPosVertical=="center"&&this.labelHeight>o?(this.rect.y-=(this.labelHeight-o)/2,this.setHeight(this.labelHeight)):this.labelPosVertical=="bottom"&&this.setHeight(o+this.labelHeight))}}},e.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==h.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},e.prototype.transform=function(t){var s=this.rect.x;s>r.WORLD_BOUNDARY?s=r.WORLD_BOUNDARY:s<-r.WORLD_BOUNDARY&&(s=-r.WORLD_BOUNDARY);var o=this.rect.y;o>r.WORLD_BOUNDARY?o=r.WORLD_BOUNDARY:o<-r.WORLD_BOUNDARY&&(o=-r.WORLD_BOUNDARY);var c=new f(s,o),l=t.inverseTransformPoint(c);this.setLocation(l.x,l.y)},e.prototype.getLeft=function(){return this.rect.x},e.prototype.getRight=function(){return this.rect.x+this.rect.width},e.prototype.getTop=function(){return this.rect.y},e.prototype.getBottom=function(){return this.rect.y+this.rect.height},e.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},A.exports=e}),(function(A,G,N){var v=N(0);function h(){}for(var i in v)h[i]=v[i];h.MAX_ITERATIONS=2500,h.DEFAULT_EDGE_LENGTH=50,h.DEFAULT_SPRING_STRENGTH=.45,h.DEFAULT_REPULSION_STRENGTH=4500,h.DEFAULT_GRAVITY_STRENGTH=.4,h.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,h.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,h.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,h.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,h.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,h.COOLING_ADAPTATION_FACTOR=.33,h.ADAPTATION_LOWER_NODE_LIMIT=1e3,h.ADAPTATION_UPPER_NODE_LIMIT=5e3,h.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,h.MAX_NODE_DISPLACEMENT=h.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,h.MIN_REPULSION_DIST=h.DEFAULT_EDGE_LENGTH/10,h.CONVERGENCE_CHECK_PERIOD=100,h.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,h.MIN_EDGE_LENGTH=1,h.GRID_CALCULATION_CHECK_PERIOD=10,A.exports=h}),(function(A,G,N){function v(h,i){h==null&&i==null?(this.x=0,this.y=0):(this.x=h,this.y=i)}v.prototype.getX=function(){return this.x},v.prototype.getY=function(){return this.y},v.prototype.setX=function(h){this.x=h},v.prototype.setY=function(h){this.y=h},v.prototype.getDifference=function(h){return new DimensionD(this.x-h.x,this.y-h.y)},v.prototype.getCopy=function(){return new v(this.x,this.y)},v.prototype.translate=function(h){return this.x+=h.width,this.y+=h.height,this},A.exports=v}),(function(A,G,N){var v=N(2),h=N(10),i=N(0),r=N(7),a=N(3),f=N(1),e=N(13),u=N(12),t=N(11);function s(c,l,T){v.call(this,T),this.estimatedSize=h.MIN_VALUE,this.margin=i.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=c,l!=null&&l instanceof r?this.graphManager=l:l!=null&&l instanceof Layout&&(this.graphManager=l.graphManager)}s.prototype=Object.create(v.prototype);for(var o in v)s[o]=v[o];s.prototype.getNodes=function(){return this.nodes},s.prototype.getEdges=function(){return this.edges},s.prototype.getGraphManager=function(){return this.graphManager},s.prototype.getParent=function(){return this.parent},s.prototype.getLeft=function(){return this.left},s.prototype.getRight=function(){return this.right},s.prototype.getTop=function(){return this.top},s.prototype.getBottom=function(){return this.bottom},s.prototype.isConnected=function(){return this.isConnected},s.prototype.add=function(c,l,T){if(l==null&&T==null){var g=c;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(g)>-1)throw"Node already in graph!";return g.owner=this,this.getNodes().push(g),g}else{var d=c;if(!(this.getNodes().indexOf(l)>-1&&this.getNodes().indexOf(T)>-1))throw"Source or target not in graph!";if(!(l.owner==T.owner&&l.owner==this))throw"Both owners must be this graph!";return l.owner!=T.owner?null:(d.source=l,d.target=T,d.isInterGraph=!1,this.getEdges().push(d),l.edges.push(d),T!=l&&T.edges.push(d),d)}},s.prototype.remove=function(c){var l=c;if(c instanceof a){if(l==null)throw"Node is null!";if(!(l.owner!=null&&l.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var T=l.edges.slice(),g,d=T.length,C=0;C<d;C++)g=T[C],g.isInterGraph?this.graphManager.remove(g):g.source.owner.remove(g);var S=this.nodes.indexOf(l);if(S==-1)throw"Node not in owner node list!";this.nodes.splice(S,1)}else if(c instanceof f){var g=c;if(g==null)throw"Edge is null!";if(!(g.source!=null&&g.target!=null))throw"Source and/or target is null!";if(!(g.source.owner!=null&&g.target.owner!=null&&g.source.owner==this&&g.target.owner==this))throw"Source and/or target owner is invalid!";var w=g.source.edges.indexOf(g),P=g.target.edges.indexOf(g);if(!(w>-1&&P>-1))throw"Source and/or target doesn't know this edge!";g.source.edges.splice(w,1),g.target!=g.source&&g.target.edges.splice(P,1);var S=g.source.owner.getEdges().indexOf(g);if(S==-1)throw"Not in owner's edge list!";g.source.owner.getEdges().splice(S,1)}},s.prototype.updateLeftTop=function(){for(var c=h.MAX_VALUE,l=h.MAX_VALUE,T,g,d,C=this.getNodes(),S=C.length,w=0;w<S;w++){var P=C[w];T=P.getTop(),g=P.getLeft(),c>T&&(c=T),l>g&&(l=g)}return c==h.MAX_VALUE?null:(C[0].getParent().paddingLeft!=null?d=C[0].getParent().paddingLeft:d=this.margin,this.left=l-d,this.top=c-d,new u(this.left,this.top))},s.prototype.updateBounds=function(c){for(var l=h.MAX_VALUE,T=-h.MAX_VALUE,g=h.MAX_VALUE,d=-h.MAX_VALUE,C,S,w,P,B,U=this.nodes,V=U.length,M=0;M<V;M++){var _=U[M];c&&_.child!=null&&_.updateBounds(),C=_.getLeft(),S=_.getRight(),w=_.getTop(),P=_.getBottom(),l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var n=new e(l,g,T-l,d-g);l==h.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),U[0].getParent().paddingLeft!=null?B=U[0].getParent().paddingLeft:B=this.margin,this.left=n.x-B,this.right=n.x+n.width+B,this.top=n.y-B,this.bottom=n.y+n.height+B},s.calculateBounds=function(c){for(var l=h.MAX_VALUE,T=-h.MAX_VALUE,g=h.MAX_VALUE,d=-h.MAX_VALUE,C,S,w,P,B=c.length,U=0;U<B;U++){var V=c[U];C=V.getLeft(),S=V.getRight(),w=V.getTop(),P=V.getBottom(),l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var M=new e(l,g,T-l,d-g);return M},s.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},s.prototype.getEstimatedSize=function(){if(this.estimatedSize==h.MIN_VALUE)throw"assert failed";return this.estimatedSize},s.prototype.calcEstimatedSize=function(){for(var c=0,l=this.nodes,T=l.length,g=0;g<T;g++){var d=l[g];c+=d.calcEstimatedSize()}return c==0?this.estimatedSize=i.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=c/Math.sqrt(this.nodes.length),this.estimatedSize},s.prototype.updateConnected=function(){var c=this;if(this.nodes.length==0){this.isConnected=!0;return}var l=new t,T=new Set,g=this.nodes[0],d,C,S=g.withChildren();for(S.forEach(function(M){l.push(M),T.add(M)});l.length!==0;){g=l.shift(),d=g.getEdges();for(var w=d.length,P=0;P<w;P++){var B=d[P];if(C=B.getOtherEndInGraph(g,this),C!=null&&!T.has(C)){var U=C.withChildren();U.forEach(function(M){l.push(M),T.add(M)})}}}if(this.isConnected=!1,T.size>=this.nodes.length){var V=0;T.forEach(function(M){M.owner==c&&V++}),V==this.nodes.length&&(this.isConnected=!0)}},A.exports=s}),(function(A,G,N){var v,h=N(1);function i(r){v=N(6),this.layout=r,this.graphs=[],this.edges=[]}i.prototype.addRoot=function(){var r=this.layout.newGraph(),a=this.layout.newNode(null),f=this.add(r,a);return this.setRootGraph(f),this.rootGraph},i.prototype.add=function(r,a,f,e,u){if(f==null&&e==null&&u==null){if(r==null)throw"Graph is null!";if(a==null)throw"Parent node is null!";if(this.graphs.indexOf(r)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(r),r.parent!=null)throw"Already has a parent!";if(a.child!=null)throw"Already has a child!";return r.parent=a,a.child=r,r}else{u=f,e=a,f=r;var t=e.getOwner(),s=u.getOwner();if(!(t!=null&&t.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(s!=null&&s.getGraphManager()==this))throw"Target not in this graph mgr!";if(t==s)return f.isInterGraph=!1,t.add(f,e,u);if(f.isInterGraph=!0,f.source=e,f.target=u,this.edges.indexOf(f)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(f),!(f.source!=null&&f.target!=null))throw"Edge source and/or target is null!";if(!(f.source.edges.indexOf(f)==-1&&f.target.edges.indexOf(f)==-1))throw"Edge already in source and/or target incidency list!";return f.source.edges.push(f),f.target.edges.push(f),f}},i.prototype.remove=function(r){if(r instanceof v){var a=r;if(a.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(a==this.rootGraph||a.parent!=null&&a.parent.graphManager==this))throw"Invalid parent node!";var f=[];f=f.concat(a.getEdges());for(var e,u=f.length,t=0;t<u;t++)e=f[t],a.remove(e);var s=[];s=s.concat(a.getNodes());var o;u=s.length;for(var t=0;t<u;t++)o=s[t],a.remove(o);a==this.rootGraph&&this.setRootGraph(null);var c=this.graphs.indexOf(a);this.graphs.splice(c,1),a.parent=null}else if(r instanceof h){if(e=r,e==null)throw"Edge is null!";if(!e.isInterGraph)throw"Not an inter-graph edge!";if(!(e.source!=null&&e.target!=null))throw"Source and/or target is null!";if(!(e.source.edges.indexOf(e)!=-1&&e.target.edges.indexOf(e)!=-1))throw"Source and/or target doesn't know this edge!";var c=e.source.edges.indexOf(e);if(e.source.edges.splice(c,1),c=e.target.edges.indexOf(e),e.target.edges.splice(c,1),!(e.source.owner!=null&&e.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(e.source.owner.getGraphManager().edges.indexOf(e)==-1)throw"Not in owner graph manager's edge list!";var c=e.source.owner.getGraphManager().edges.indexOf(e);e.source.owner.getGraphManager().edges.splice(c,1)}},i.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},i.prototype.getGraphs=function(){return this.graphs},i.prototype.getAllNodes=function(){if(this.allNodes==null){for(var r=[],a=this.getGraphs(),f=a.length,e=0;e<f;e++)r=r.concat(a[e].getNodes());this.allNodes=r}return this.allNodes},i.prototype.resetAllNodes=function(){this.allNodes=null},i.prototype.resetAllEdges=function(){this.allEdges=null},i.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},i.prototype.getAllEdges=function(){if(this.allEdges==null){var r=[],a=this.getGraphs();a.length;for(var f=0;f<a.length;f++)r=r.concat(a[f].getEdges());r=r.concat(this.edges),this.allEdges=r}return this.allEdges},i.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},i.prototype.setAllNodesToApplyGravitation=function(r){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=r},i.prototype.getRoot=function(){return this.rootGraph},i.prototype.setRootGraph=function(r){if(r.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=r,r.parent==null&&(r.parent=this.layout.newNode("Root node"))},i.prototype.getLayout=function(){return this.layout},i.prototype.isOneAncestorOfOther=function(r,a){if(!(r!=null&&a!=null))throw"assert failed";if(r==a)return!0;var f=r.getOwner(),e;do{if(e=f.getParent(),e==null)break;if(e==a)return!0;if(f=e.getOwner(),f==null)break}while(!0);f=a.getOwner();do{if(e=f.getParent(),e==null)break;if(e==r)return!0;if(f=e.getOwner(),f==null)break}while(!0);return!1},i.prototype.calcLowestCommonAncestors=function(){for(var r,a,f,e,u,t=this.getAllEdges(),s=t.length,o=0;o<s;o++){if(r=t[o],a=r.source,f=r.target,r.lca=null,r.sourceInLca=a,r.targetInLca=f,a==f){r.lca=a.getOwner();continue}for(e=a.getOwner();r.lca==null;){for(r.targetInLca=f,u=f.getOwner();r.lca==null;){if(u==e){r.lca=u;break}if(u==this.rootGraph)break;if(r.lca!=null)throw"assert failed";r.targetInLca=u.getParent(),u=r.targetInLca.getOwner()}if(e==this.rootGraph)break;r.lca==null&&(r.sourceInLca=e.getParent(),e=r.sourceInLca.getOwner())}if(r.lca==null)throw"assert failed"}},i.prototype.calcLowestCommonAncestor=function(r,a){if(r==a)return r.getOwner();var f=r.getOwner();do{if(f==null)break;var e=a.getOwner();do{if(e==null)break;if(e==f)return e;e=e.getParent().getOwner()}while(!0);f=f.getParent().getOwner()}while(!0);return f},i.prototype.calcInclusionTreeDepths=function(r,a){r==null&&a==null&&(r=this.rootGraph,a=1);for(var f,e=r.getNodes(),u=e.length,t=0;t<u;t++)f=e[t],f.inclusionTreeDepth=a,f.child!=null&&this.calcInclusionTreeDepths(f.child,a+1)},i.prototype.includesInvalidEdge=function(){for(var r,a=[],f=this.edges.length,e=0;e<f;e++)r=this.edges[e],this.isOneAncestorOfOther(r.source,r.target)&&a.push(r);for(var e=0;e<a.length;e++)this.remove(a[e]);return!1},A.exports=i}),(function(A,G,N){var v=N(12);function h(){}h.calcSeparationAmount=function(i,r,a,f){if(!i.intersects(r))throw"assert failed";var e=new Array(2);this.decideDirectionsForOverlappingNodes(i,r,e),a[0]=Math.min(i.getRight(),r.getRight())-Math.max(i.x,r.x),a[1]=Math.min(i.getBottom(),r.getBottom())-Math.max(i.y,r.y),i.getX()<=r.getX()&&i.getRight()>=r.getRight()?a[0]+=Math.min(r.getX()-i.getX(),i.getRight()-r.getRight()):r.getX()<=i.getX()&&r.getRight()>=i.getRight()&&(a[0]+=Math.min(i.getX()-r.getX(),r.getRight()-i.getRight())),i.getY()<=r.getY()&&i.getBottom()>=r.getBottom()?a[1]+=Math.min(r.getY()-i.getY(),i.getBottom()-r.getBottom()):r.getY()<=i.getY()&&r.getBottom()>=i.getBottom()&&(a[1]+=Math.min(i.getY()-r.getY(),r.getBottom()-i.getBottom()));var u=Math.abs((r.getCenterY()-i.getCenterY())/(r.getCenterX()-i.getCenterX()));r.getCenterY()===i.getCenterY()&&r.getCenterX()===i.getCenterX()&&(u=1);var t=u*a[0],s=a[1]/u;a[0]<s?s=a[0]:t=a[1],a[0]=-1*e[0]*(s/2+f),a[1]=-1*e[1]*(t/2+f)},h.decideDirectionsForOverlappingNodes=function(i,r,a){i.getCenterX()<r.getCenterX()?a[0]=-1:a[0]=1,i.getCenterY()<r.getCenterY()?a[1]=-1:a[1]=1},h.getIntersection2=function(i,r,a){var f=i.getCenterX(),e=i.getCenterY(),u=r.getCenterX(),t=r.getCenterY();if(i.intersects(r))return a[0]=f,a[1]=e,a[2]=u,a[3]=t,!0;var s=i.getX(),o=i.getY(),c=i.getRight(),l=i.getX(),T=i.getBottom(),g=i.getRight(),d=i.getWidthHalf(),C=i.getHeightHalf(),S=r.getX(),w=r.getY(),P=r.getRight(),B=r.getX(),U=r.getBottom(),V=r.getRight(),M=r.getWidthHalf(),_=r.getHeightHalf(),n=!1,E=!1;if(f===u){if(e>t)return a[0]=f,a[1]=o,a[2]=u,a[3]=U,!1;if(e<t)return a[0]=f,a[1]=T,a[2]=u,a[3]=w,!1}else if(e===t){if(f>u)return a[0]=s,a[1]=e,a[2]=P,a[3]=t,!1;if(f<u)return a[0]=c,a[1]=e,a[2]=S,a[3]=t,!1}else{var p=i.height/i.width,m=r.height/r.width,y=(t-e)/(u-f),I=void 0,O=void 0,R=void 0,W=void 0,x=void 0,Q=void 0;if(-p===y?f>u?(a[0]=l,a[1]=T,n=!0):(a[0]=c,a[1]=o,n=!0):p===y&&(f>u?(a[0]=s,a[1]=o,n=!0):(a[0]=g,a[1]=T,n=!0)),-m===y?u>f?(a[2]=B,a[3]=U,E=!0):(a[2]=P,a[3]=w,E=!0):m===y&&(u>f?(a[2]=S,a[3]=w,E=!0):(a[2]=V,a[3]=U,E=!0)),n&&E)return!1;if(f>u?e>t?(I=this.getCardinalDirection(p,y,4),O=this.getCardinalDirection(m,y,2)):(I=this.getCardinalDirection(-p,y,3),O=this.getCardinalDirection(-m,y,1)):e>t?(I=this.getCardinalDirection(-p,y,1),O=this.getCardinalDirection(-m,y,3)):(I=this.getCardinalDirection(p,y,2),O=this.getCardinalDirection(m,y,4)),!n)switch(I){case 1:W=o,R=f+-C/y,a[0]=R,a[1]=W;break;case 2:R=g,W=e+d*y,a[0]=R,a[1]=W;break;case 3:W=T,R=f+C/y,a[0]=R,a[1]=W;break;case 4:R=l,W=e+-d*y,a[0]=R,a[1]=W;break}if(!E)switch(O){case 1:Q=w,x=u+-_/y,a[2]=x,a[3]=Q;break;case 2:x=V,Q=t+M*y,a[2]=x,a[3]=Q;break;case 3:Q=U,x=u+_/y,a[2]=x,a[3]=Q;break;case 4:x=B,Q=t+-M*y,a[2]=x,a[3]=Q;break}}return!1},h.getCardinalDirection=function(i,r,a){return i>r?a:1+a%4},h.getIntersection=function(i,r,a,f){if(f==null)return this.getIntersection2(i,r,a);var e=i.x,u=i.y,t=r.x,s=r.y,o=a.x,c=a.y,l=f.x,T=f.y,g=void 0,d=void 0,C=void 0,S=void 0,w=void 0,P=void 0,B=void 0,U=void 0,V=void 0;return C=s-u,w=e-t,B=t*u-e*s,S=T-c,P=o-l,U=l*c-o*T,V=C*P-S*w,V===0?null:(g=(w*U-P*B)/V,d=(S*B-C*U)/V,new v(g,d))},h.angleOfVector=function(i,r,a,f){var e=void 0;return i!==a?(e=Math.atan((f-r)/(a-i)),a<i?e+=Math.PI:f<r&&(e+=this.TWO_PI)):f<r?e=this.ONE_AND_HALF_PI:e=this.HALF_PI,e},h.doIntersect=function(i,r,a,f){var e=i.x,u=i.y,t=r.x,s=r.y,o=a.x,c=a.y,l=f.x,T=f.y,g=(t-e)*(T-c)-(l-o)*(s-u);if(g===0)return!1;var d=((T-c)*(l-e)+(o-l)*(T-u))/g,C=((u-s)*(l-e)+(t-e)*(T-u))/g;return 0<d&&d<1&&0<C&&C<1},h.findCircleLineIntersections=function(i,r,a,f,e,u,t){var s=(a-i)*(a-i)+(f-r)*(f-r),o=2*((i-e)*(a-i)+(r-u)*(f-r)),c=(i-e)*(i-e)+(r-u)*(r-u)-t*t,l=o*o-4*s*c;if(l>=0){var T=(-o+Math.sqrt(o*o-4*s*c))/(2*s),g=(-o-Math.sqrt(o*o-4*s*c))/(2*s),d=null;return T>=0&&T<=1?[T]:g>=0&&g<=1?[g]:d}else return null},h.HALF_PI=.5*Math.PI,h.ONE_AND_HALF_PI=1.5*Math.PI,h.TWO_PI=2*Math.PI,h.THREE_PI=3*Math.PI,A.exports=h}),(function(A,G,N){function v(){}v.sign=function(h){return h>0?1:h<0?-1:0},v.floor=function(h){return h<0?Math.ceil(h):Math.floor(h)},v.ceil=function(h){return h<0?Math.floor(h):Math.ceil(h)},A.exports=v}),(function(A,G,N){function v(){}v.MAX_VALUE=2147483647,v.MIN_VALUE=-2147483648,A.exports=v}),(function(A,G,N){var v=(function(){function e(u,t){for(var s=0;s<t.length;s++){var o=t[s];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(u,o.key,o)}}return function(u,t,s){return t&&e(u.prototype,t),s&&e(u,s),u}})();function h(e,u){if(!(e instanceof u))throw new TypeError("Cannot call a class as a function")}var i=function(u){return{value:u,next:null,prev:null}},r=function(u,t,s,o){return u!==null?u.next=t:o.head=t,s!==null?s.prev=t:o.tail=t,t.prev=u,t.next=s,o.length++,t},a=function(u,t){var s=u.prev,o=u.next;return s!==null?s.next=o:t.head=o,o!==null?o.prev=s:t.tail=s,u.prev=u.next=null,t.length--,u},f=(function(){function e(u){var t=this;h(this,e),this.length=0,this.head=null,this.tail=null,u?.forEach(function(s){return t.push(s)})}return v(e,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(t,s){return r(s.prev,i(t),s,this)}},{key:"insertAfter",value:function(t,s){return r(s,i(t),s.next,this)}},{key:"insertNodeBefore",value:function(t,s){return r(s.prev,t,s,this)}},{key:"insertNodeAfter",value:function(t,s){return r(s,t,s.next,this)}},{key:"push",value:function(t){return r(this.tail,i(t),null,this)}},{key:"unshift",value:function(t){return r(null,i(t),this.head,this)}},{key:"remove",value:function(t){return a(t,this)}},{key:"pop",value:function(){return a(this.tail,this).value}},{key:"popNode",value:function(){return a(this.tail,this)}},{key:"shift",value:function(){return a(this.head,this).value}},{key:"shiftNode",value:function(){return a(this.head,this)}},{key:"get_object_at",value:function(t){if(t<=this.length()){for(var s=1,o=this.head;s<t;)o=o.next,s++;return o.value}}},{key:"set_object_at",value:function(t,s){if(t<=this.length()){for(var o=1,c=this.head;o<t;)c=c.next,o++;c.value=s}}}]),e})();A.exports=f}),(function(A,G,N){function v(h,i,r){this.x=null,this.y=null,h==null&&i==null&&r==null?(this.x=0,this.y=0):typeof h=="number"&&typeof i=="number"&&r==null?(this.x=h,this.y=i):h.constructor.name=="Point"&&i==null&&r==null&&(r=h,this.x=r.x,this.y=r.y)}v.prototype.getX=function(){return this.x},v.prototype.getY=function(){return this.y},v.prototype.getLocation=function(){return new v(this.x,this.y)},v.prototype.setLocation=function(h,i,r){h.constructor.name=="Point"&&i==null&&r==null?(r=h,this.setLocation(r.x,r.y)):typeof h=="number"&&typeof i=="number"&&r==null&&(parseInt(h)==h&&parseInt(i)==i?this.move(h,i):(this.x=Math.floor(h+.5),this.y=Math.floor(i+.5)))},v.prototype.move=function(h,i){this.x=h,this.y=i},v.prototype.translate=function(h,i){this.x+=h,this.y+=i},v.prototype.equals=function(h){if(h.constructor.name=="Point"){var i=h;return this.x==i.x&&this.y==i.y}return this==h},v.prototype.toString=function(){return new v().constructor.name+"[x="+this.x+",y="+this.y+"]"},A.exports=v}),(function(A,G,N){function v(h,i,r,a){this.x=0,this.y=0,this.width=0,this.height=0,h!=null&&i!=null&&r!=null&&a!=null&&(this.x=h,this.y=i,this.width=r,this.height=a)}v.prototype.getX=function(){return this.x},v.prototype.setX=function(h){this.x=h},v.prototype.getY=function(){return this.y},v.prototype.setY=function(h){this.y=h},v.prototype.getWidth=function(){return this.width},v.prototype.setWidth=function(h){this.width=h},v.prototype.getHeight=function(){return this.height},v.prototype.setHeight=function(h){this.height=h},v.prototype.getRight=function(){return this.x+this.width},v.prototype.getBottom=function(){return this.y+this.height},v.prototype.intersects=function(h){return!(this.getRight()<h.x||this.getBottom()<h.y||h.getRight()<this.x||h.getBottom()<this.y)},v.prototype.getCenterX=function(){return this.x+this.width/2},v.prototype.getMinX=function(){return this.getX()},v.prototype.getMaxX=function(){return this.getX()+this.width},v.prototype.getCenterY=function(){return this.y+this.height/2},v.prototype.getMinY=function(){return this.getY()},v.prototype.getMaxY=function(){return this.getY()+this.height},v.prototype.getWidthHalf=function(){return this.width/2},v.prototype.getHeightHalf=function(){return this.height/2},A.exports=v}),(function(A,G,N){var v=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i};function h(){}h.lastID=0,h.createID=function(i){return h.isPrimitive(i)?i:(i.uniqueID!=null||(i.uniqueID=h.getString(),h.lastID++),i.uniqueID)},h.getString=function(i){return i==null&&(i=h.lastID),"Object#"+i},h.isPrimitive=function(i){var r=typeof i>"u"?"undefined":v(i);return i==null||r!="object"&&r!="function"},A.exports=h}),(function(A,G,N){function v(o){if(Array.isArray(o)){for(var c=0,l=Array(o.length);c<o.length;c++)l[c]=o[c];return l}else return Array.from(o)}var h=N(0),i=N(7),r=N(3),a=N(1),f=N(6),e=N(5),u=N(17),t=N(29);function s(o){t.call(this),this.layoutQuality=h.QUALITY,this.createBendsAsNeeded=h.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=h.DEFAULT_INCREMENTAL,this.animationOnLayout=h.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=h.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=h.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=h.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new i(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,o!=null&&(this.isRemoteUse=o)}s.RANDOM_SEED=1,s.prototype=Object.create(t.prototype),s.prototype.getGraphManager=function(){return this.graphManager},s.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},s.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},s.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},s.prototype.newGraphManager=function(){var o=new i(this);return this.graphManager=o,o},s.prototype.newGraph=function(o){return new f(null,this.graphManager,o)},s.prototype.newNode=function(o){return new r(this.graphManager,o)},s.prototype.newEdge=function(o){return new a(null,null,o)},s.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},s.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var o;return this.checkLayoutSuccess()?o=!1:o=this.layout(),h.ANIMATE==="during"?!1:(o&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,o)},s.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},s.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var o=this.graphManager.getAllEdges(),c=0;c<o.length;c++)o[c];for(var l=this.graphManager.getRoot().getNodes(),c=0;c<l.length;c++)l[c];this.update(this.graphManager.getRoot())}},s.prototype.update=function(o){if(o==null)this.update2();else if(o instanceof r){var c=o;if(c.getChild()!=null)for(var l=c.getChild().getNodes(),T=0;T<l.length;T++)update(l[T]);if(c.vGraphObject!=null){var g=c.vGraphObject;g.update(c)}}else if(o instanceof a){var d=o;if(d.vGraphObject!=null){var C=d.vGraphObject;C.update(d)}}else if(o instanceof f){var S=o;if(S.vGraphObject!=null){var w=S.vGraphObject;w.update(S)}}},s.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=h.QUALITY,this.animationDuringLayout=h.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=h.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=h.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=h.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=h.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=h.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},s.prototype.transform=function(o){if(o==null)this.transform(new e(0,0));else{var c=new u,l=this.graphManager.getRoot().updateLeftTop();if(l!=null){c.setWorldOrgX(o.x),c.setWorldOrgY(o.y),c.setDeviceOrgX(l.x),c.setDeviceOrgY(l.y);for(var T=this.getAllNodes(),g,d=0;d<T.length;d++)g=T[d],g.transform(c)}}},s.prototype.positionNodesRandomly=function(o){if(o==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var c,l,T=o.getNodes(),g=0;g<T.length;g++)c=T[g],l=c.getChild(),l==null||l.getNodes().length==0?c.scatter():(this.positionNodesRandomly(l),c.updateBounds())},s.prototype.getFlatForest=function(){for(var o=[],c=!0,l=this.graphManager.getRoot().getNodes(),T=!0,g=0;g<l.length;g++)l[g].getChild()!=null&&(T=!1);if(!T)return o;var d=new Set,C=[],S=new Map,w=[];for(w=w.concat(l);w.length>0&&c;){for(C.push(w[0]);C.length>0&&c;){var P=C[0];C.splice(0,1),d.add(P);for(var B=P.getEdges(),g=0;g<B.length;g++){var U=B[g].getOtherEnd(P);if(S.get(P)!=U)if(!d.has(U))C.push(U),S.set(U,P);else{c=!1;break}}}if(!c)o=[];else{var V=[].concat(v(d));o.push(V);for(var g=0;g<V.length;g++){var M=V[g],_=w.indexOf(M);_>-1&&w.splice(_,1)}d=new Set,S=new Map}}return o},s.prototype.createDummyNodesForBendpoints=function(o){for(var c=[],l=o.source,T=this.graphManager.calcLowestCommonAncestor(o.source,o.target),g=0;g<o.bendpoints.length;g++){var d=this.newNode(null);d.setRect(new Point(0,0),new Dimension(1,1)),T.add(d);var C=this.newEdge(null);this.graphManager.add(C,l,d),c.add(d),l=d}var C=this.newEdge(null);return this.graphManager.add(C,l,o.target),this.edgeToDummyNodes.set(o,c),o.isInterGraph()?this.graphManager.remove(o):T.remove(o),c},s.prototype.createBendpointsFromDummyNodes=function(){var o=[];o=o.concat(this.graphManager.getAllEdges()),o=[].concat(v(this.edgeToDummyNodes.keys())).concat(o);for(var c=0;c<o.length;c++){var l=o[c];if(l.bendpoints.length>0){for(var T=this.edgeToDummyNodes.get(l),g=0;g<T.length;g++){var d=T[g],C=new e(d.getCenterX(),d.getCenterY()),S=l.bendpoints.get(g);S.x=C.x,S.y=C.y,d.getOwner().remove(d)}this.graphManager.add(l,l.source,l.target)}}},s.transform=function(o,c,l,T){if(l!=null&&T!=null){var g=c;if(o<=50){var d=c/l;g-=(c-d)/50*(50-o)}else{var C=c*T;g+=(C-c)/50*(o-50)}return g}else{var S,w;return o<=50?(S=9*c/500,w=c/10):(S=9*c/50,w=-8*c),S*o+w}},s.findCenterOfTree=function(o){var c=[];c=c.concat(o);var l=[],T=new Map,g=!1,d=null;(c.length==1||c.length==2)&&(g=!0,d=c[0]);for(var C=0;C<c.length;C++){var S=c[C],w=S.getNeighborsList().size;T.set(S,S.getNeighborsList().size),w==1&&l.push(S)}var P=[];for(P=P.concat(l);!g;){var B=[];B=B.concat(P),P=[];for(var C=0;C<c.length;C++){var S=c[C],U=c.indexOf(S);U>=0&&c.splice(U,1);var V=S.getNeighborsList();V.forEach(function(n){if(l.indexOf(n)<0){var E=T.get(n),p=E-1;p==1&&P.push(n),T.set(n,p)}})}l=l.concat(P),(c.length==1||c.length==2)&&(g=!0,d=c[0])}return d},s.prototype.setGraphManager=function(o){this.graphManager=o},A.exports=s}),(function(A,G,N){function v(){}v.seed=1,v.x=0,v.nextDouble=function(){return v.x=Math.sin(v.seed++)*1e4,v.x-Math.floor(v.x)},A.exports=v}),(function(A,G,N){var v=N(5);function h(i,r){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}h.prototype.getWorldOrgX=function(){return this.lworldOrgX},h.prototype.setWorldOrgX=function(i){this.lworldOrgX=i},h.prototype.getWorldOrgY=function(){return this.lworldOrgY},h.prototype.setWorldOrgY=function(i){this.lworldOrgY=i},h.prototype.getWorldExtX=function(){return this.lworldExtX},h.prototype.setWorldExtX=function(i){this.lworldExtX=i},h.prototype.getWorldExtY=function(){return this.lworldExtY},h.prototype.setWorldExtY=function(i){this.lworldExtY=i},h.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},h.prototype.setDeviceOrgX=function(i){this.ldeviceOrgX=i},h.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},h.prototype.setDeviceOrgY=function(i){this.ldeviceOrgY=i},h.prototype.getDeviceExtX=function(){return this.ldeviceExtX},h.prototype.setDeviceExtX=function(i){this.ldeviceExtX=i},h.prototype.getDeviceExtY=function(){return this.ldeviceExtY},h.prototype.setDeviceExtY=function(i){this.ldeviceExtY=i},h.prototype.transformX=function(i){var r=0,a=this.lworldExtX;return a!=0&&(r=this.ldeviceOrgX+(i-this.lworldOrgX)*this.ldeviceExtX/a),r},h.prototype.transformY=function(i){var r=0,a=this.lworldExtY;return a!=0&&(r=this.ldeviceOrgY+(i-this.lworldOrgY)*this.ldeviceExtY/a),r},h.prototype.inverseTransformX=function(i){var r=0,a=this.ldeviceExtX;return a!=0&&(r=this.lworldOrgX+(i-this.ldeviceOrgX)*this.lworldExtX/a),r},h.prototype.inverseTransformY=function(i){var r=0,a=this.ldeviceExtY;return a!=0&&(r=this.lworldOrgY+(i-this.ldeviceOrgY)*this.lworldExtY/a),r},h.prototype.inverseTransformPoint=function(i){var r=new v(this.inverseTransformX(i.x),this.inverseTransformY(i.y));return r},A.exports=h}),(function(A,G,N){function v(t){if(Array.isArray(t)){for(var s=0,o=Array(t.length);s<t.length;s++)o[s]=t[s];return o}else return Array.from(t)}var h=N(15),i=N(4),r=N(0),a=N(8),f=N(9);function e(){h.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}e.prototype=Object.create(h.prototype);for(var u in h)e[u]=h[u];e.prototype.initParameters=function(){h.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},e.prototype.calcIdealEdgeLengths=function(){for(var t,s,o,c,l,T,g,d=this.getGraphManager().getAllEdges(),C=0;C<d.length;C++)t=d[C],s=t.idealLength,t.isInterGraph&&(c=t.getSource(),l=t.getTarget(),T=t.getSourceInLca().getEstimatedSize(),g=t.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(t.idealLength+=T+g-2*r.SIMPLE_NODE_SIZE),o=t.getLca().getInclusionTreeDepth(),t.idealLength+=s*i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(c.getInclusionTreeDepth()+l.getInclusionTreeDepth()-2*o))},e.prototype.initSpringEmbedder=function(){var t=this.getAllNodes().length;this.incremental?(t>i.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(t-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},e.prototype.calcSpringForces=function(){for(var t=this.getAllEdges(),s,o=0;o<t.length;o++)s=t[o],this.calcSpringForce(s,s.idealLength)},e.prototype.calcRepulsionForces=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,o,c,l,T,g=this.getAllNodes(),d;if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&t&&this.updateGrid(),d=new Set,o=0;o<g.length;o++)l=g[o],this.calculateRepulsionForceOfANode(l,d,t,s),d.add(l);else for(o=0;o<g.length;o++)for(l=g[o],c=o+1;c<g.length;c++)T=g[c],l.getOwner()==T.getOwner()&&this.calcRepulsionForce(l,T)},e.prototype.calcGravitationalForces=function(){for(var t,s=this.getAllNodesToApplyGravitation(),o=0;o<s.length;o++)t=s[o],this.calcGravitationalForce(t)},e.prototype.moveNodes=function(){for(var t=this.getAllNodes(),s,o=0;o<t.length;o++)s=t[o],s.move()},e.prototype.calcSpringForce=function(t,s){var o=t.getSource(),c=t.getTarget(),l,T,g,d;if(this.uniformLeafNodeSizes&&o.getChild()==null&&c.getChild()==null)t.updateLengthSimple();else if(t.updateLength(),t.isOverlapingSourceAndTarget)return;l=t.getLength(),l!=0&&(T=t.edgeElasticity*(l-s),g=T*(t.lengthX/l),d=T*(t.lengthY/l),o.springForceX+=g,o.springForceY+=d,c.springForceX-=g,c.springForceY-=d)},e.prototype.calcRepulsionForce=function(t,s){var o=t.getRect(),c=s.getRect(),l=new Array(2),T=new Array(4),g,d,C,S,w,P,B;if(o.intersects(c)){a.calcSeparationAmount(o,c,l,i.DEFAULT_EDGE_LENGTH/2),P=2*l[0],B=2*l[1];var U=t.noOfChildren*s.noOfChildren/(t.noOfChildren+s.noOfChildren);t.repulsionForceX-=U*P,t.repulsionForceY-=U*B,s.repulsionForceX+=U*P,s.repulsionForceY+=U*B}else this.uniformLeafNodeSizes&&t.getChild()==null&&s.getChild()==null?(g=c.getCenterX()-o.getCenterX(),d=c.getCenterY()-o.getCenterY()):(a.getIntersection(o,c,T),g=T[2]-T[0],d=T[3]-T[1]),Math.abs(g)<i.MIN_REPULSION_DIST&&(g=f.sign(g)*i.MIN_REPULSION_DIST),Math.abs(d)<i.MIN_REPULSION_DIST&&(d=f.sign(d)*i.MIN_REPULSION_DIST),C=g*g+d*d,S=Math.sqrt(C),w=(t.nodeRepulsion/2+s.nodeRepulsion/2)*t.noOfChildren*s.noOfChildren/C,P=w*g/S,B=w*d/S,t.repulsionForceX-=P,t.repulsionForceY-=B,s.repulsionForceX+=P,s.repulsionForceY+=B},e.prototype.calcGravitationalForce=function(t){var s,o,c,l,T,g,d,C;s=t.getOwner(),o=(s.getRight()+s.getLeft())/2,c=(s.getTop()+s.getBottom())/2,l=t.getCenterX()-o,T=t.getCenterY()-c,g=Math.abs(l)+t.getWidth()/2,d=Math.abs(T)+t.getHeight()/2,t.getOwner()==this.graphManager.getRoot()?(C=s.getEstimatedSize()*this.gravityRangeFactor,(g>C||d>C)&&(t.gravitationForceX=-this.gravityConstant*l,t.gravitationForceY=-this.gravityConstant*T)):(C=s.getEstimatedSize()*this.compoundGravityRangeFactor,(g>C||d>C)&&(t.gravitationForceX=-this.gravityConstant*l*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*T*this.compoundGravityConstant))},e.prototype.isConverged=function(){var t,s=!1;return this.totalIterations>this.maxIterations/3&&(s=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,t||s},e.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},e.prototype.calcNoOfChildrenForAllNodes=function(){for(var t,s=this.graphManager.getAllNodes(),o=0;o<s.length;o++)t=s[o],t.noOfChildren=t.getNoOfChildren()},e.prototype.calcGrid=function(t){var s=0,o=0;s=parseInt(Math.ceil((t.getRight()-t.getLeft())/this.repulsionRange)),o=parseInt(Math.ceil((t.getBottom()-t.getTop())/this.repulsionRange));for(var c=new Array(s),l=0;l<s;l++)c[l]=new Array(o);for(var l=0;l<s;l++)for(var T=0;T<o;T++)c[l][T]=new Array;return c},e.prototype.addNodeToGrid=function(t,s,o){var c=0,l=0,T=0,g=0;c=parseInt(Math.floor((t.getRect().x-s)/this.repulsionRange)),l=parseInt(Math.floor((t.getRect().width+t.getRect().x-s)/this.repulsionRange)),T=parseInt(Math.floor((t.getRect().y-o)/this.repulsionRange)),g=parseInt(Math.floor((t.getRect().height+t.getRect().y-o)/this.repulsionRange));for(var d=c;d<=l;d++)for(var C=T;C<=g;C++)this.grid[d][C].push(t),t.setGridCoordinates(c,l,T,g)},e.prototype.updateGrid=function(){var t,s,o=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),t=0;t<o.length;t++)s=o[t],this.addNodeToGrid(s,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},e.prototype.calculateRepulsionForceOfANode=function(t,s,o,c){if(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o||c){var l=new Set;t.surrounding=new Array;for(var T,g=this.grid,d=t.startX-1;d<t.finishX+2;d++)for(var C=t.startY-1;C<t.finishY+2;C++)if(!(d<0||C<0||d>=g.length||C>=g[0].length)){for(var S=0;S<g[d][C].length;S++)if(T=g[d][C][S],!(t.getOwner()!=T.getOwner()||t==T)&&!s.has(T)&&!l.has(T)){var w=Math.abs(t.getCenterX()-T.getCenterX())-(t.getWidth()/2+T.getWidth()/2),P=Math.abs(t.getCenterY()-T.getCenterY())-(t.getHeight()/2+T.getHeight()/2);w<=this.repulsionRange&&P<=this.repulsionRange&&l.add(T)}}t.surrounding=[].concat(v(l))}for(d=0;d<t.surrounding.length;d++)this.calcRepulsionForce(t,t.surrounding[d])},e.prototype.calcRepulsionRange=function(){return 0},A.exports=e}),(function(A,G,N){var v=N(1),h=N(4);function i(a,f,e){v.call(this,a,f,e),this.idealLength=h.DEFAULT_EDGE_LENGTH,this.edgeElasticity=h.DEFAULT_SPRING_STRENGTH}i.prototype=Object.create(v.prototype);for(var r in v)i[r]=v[r];A.exports=i}),(function(A,G,N){var v=N(3),h=N(4);function i(a,f,e,u){v.call(this,a,f,e,u),this.nodeRepulsion=h.DEFAULT_REPULSION_STRENGTH,this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}i.prototype=Object.create(v.prototype);for(var r in v)i[r]=v[r];i.prototype.setGridCoordinates=function(a,f,e,u){this.startX=a,this.finishX=f,this.startY=e,this.finishY=u},A.exports=i}),(function(A,G,N){function v(h,i){this.width=0,this.height=0,h!==null&&i!==null&&(this.height=i,this.width=h)}v.prototype.getWidth=function(){return this.width},v.prototype.setWidth=function(h){this.width=h},v.prototype.getHeight=function(){return this.height},v.prototype.setHeight=function(h){this.height=h},A.exports=v}),(function(A,G,N){var v=N(14);function h(){this.map={},this.keys=[]}h.prototype.put=function(i,r){var a=v.createID(i);this.contains(a)||(this.map[a]=r,this.keys.push(i))},h.prototype.contains=function(i){return v.createID(i),this.map[i]!=null},h.prototype.get=function(i){var r=v.createID(i);return this.map[r]},h.prototype.keySet=function(){return this.keys},A.exports=h}),(function(A,G,N){var v=N(14);function h(){this.set={}}h.prototype.add=function(i){var r=v.createID(i);this.contains(r)||(this.set[r]=i)},h.prototype.remove=function(i){delete this.set[v.createID(i)]},h.prototype.clear=function(){this.set={}},h.prototype.contains=function(i){return this.set[v.createID(i)]==i},h.prototype.isEmpty=function(){return this.size()===0},h.prototype.size=function(){return Object.keys(this.set).length},h.prototype.addAllTo=function(i){for(var r=Object.keys(this.set),a=r.length,f=0;f<a;f++)i.push(this.set[r[f]])},h.prototype.size=function(){return Object.keys(this.set).length},h.prototype.addAll=function(i){for(var r=i.length,a=0;a<r;a++){var f=i[a];this.add(f)}},A.exports=h}),(function(A,G,N){function v(){}v.multMat=function(h,i){for(var r=[],a=0;a<h.length;a++){r[a]=[];for(var f=0;f<i[0].length;f++){r[a][f]=0;for(var e=0;e<h[0].length;e++)r[a][f]+=h[a][e]*i[e][f]}}return r},v.transpose=function(h){for(var i=[],r=0;r<h[0].length;r++){i[r]=[];for(var a=0;a<h.length;a++)i[r][a]=h[a][r]}return i},v.multCons=function(h,i){for(var r=[],a=0;a<h.length;a++)r[a]=h[a]*i;return r},v.minusOp=function(h,i){for(var r=[],a=0;a<h.length;a++)r[a]=h[a]-i[a];return r},v.dotProduct=function(h,i){for(var r=0,a=0;a<h.length;a++)r+=h[a]*i[a];return r},v.mag=function(h){return Math.sqrt(this.dotProduct(h,h))},v.normalize=function(h){for(var i=[],r=this.mag(h),a=0;a<h.length;a++)i[a]=h[a]/r;return i},v.multGamma=function(h){for(var i=[],r=0,a=0;a<h.length;a++)r+=h[a];r*=-1/h.length;for(var f=0;f<h.length;f++)i[f]=r+h[f];return i},v.multL=function(h,i,r){for(var a=[],f=[],e=[],u=0;u<i[0].length;u++){for(var t=0,s=0;s<i.length;s++)t+=-.5*i[s][u]*h[s];f[u]=t}for(var o=0;o<r.length;o++){for(var c=0,l=0;l<r.length;l++)c+=r[o][l]*f[l];e[o]=c}for(var T=0;T<i.length;T++){for(var g=0,d=0;d<i[0].length;d++)g+=i[T][d]*e[d];a[T]=g}return a},A.exports=v}),(function(A,G,N){var v=(function(){function a(f,e){for(var u=0;u<e.length;u++){var t=e[u];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(f,t.key,t)}}return function(f,e,u){return e&&a(f.prototype,e),u&&a(f,u),f}})();function h(a,f){if(!(a instanceof f))throw new TypeError("Cannot call a class as a function")}var i=N(11),r=(function(){function a(f,e){h(this,a),(e!==null||e!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var u=void 0;f instanceof i?u=f.size():u=f.length,this._quicksort(f,0,u-1)}return v(a,[{key:"_quicksort",value:function(e,u,t){if(u<t){var s=this._partition(e,u,t);this._quicksort(e,u,s),this._quicksort(e,s+1,t)}}},{key:"_partition",value:function(e,u,t){for(var s=this._get(e,u),o=u,c=t;;){for(;this.compareFunction(s,this._get(e,c));)c--;for(;this.compareFunction(this._get(e,o),s);)o++;if(o<c)this._swap(e,o,c),o++,c--;else return c}}},{key:"_get",value:function(e,u){return e instanceof i?e.get_object_at(u):e[u]}},{key:"_set",value:function(e,u,t){e instanceof i?e.set_object_at(u,t):e[u]=t}},{key:"_swap",value:function(e,u,t){var s=this._get(e,u);this._set(e,u,this._get(e,t)),this._set(e,t,s)}},{key:"_defaultCompareFunction",value:function(e,u){return u>e}}]),a})();A.exports=r}),(function(A,G,N){function v(){}v.svd=function(h){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=h.length,this.n=h[0].length;var i=Math.min(this.m,this.n);this.s=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(Math.min(this.m+1,this.n)),this.U=(function(Tt){var Ct=function Bt(bt){if(bt.length==0)return 0;for(var zt=[],St=0;St<bt[0];St++)zt.push(Bt(bt.slice(1)));return zt};return Ct(Tt)})([this.m,i]),this.V=(function(Tt){var Ct=function Bt(bt){if(bt.length==0)return 0;for(var zt=[],St=0;St<bt[0];St++)zt.push(Bt(bt.slice(1)));return zt};return Ct(Tt)})([this.n,this.n]);for(var r=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(this.n),a=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(this.m),f=!0,e=Math.min(this.m-1,this.n),u=Math.max(0,Math.min(this.n-2,this.m)),t=0;t<Math.max(e,u);t++){if(t<e){this.s[t]=0;for(var s=t;s<this.m;s++)this.s[t]=v.hypot(this.s[t],h[s][t]);if(this.s[t]!==0){h[t][t]<0&&(this.s[t]=-this.s[t]);for(var o=t;o<this.m;o++)h[o][t]/=this.s[t];h[t][t]+=1}this.s[t]=-this.s[t]}for(var c=t+1;c<this.n;c++){if((function(Tt,Ct){return Tt&&Ct})(t<e,this.s[t]!==0)){for(var l=0,T=t;T<this.m;T++)l+=h[T][t]*h[T][c];l=-l/h[t][t];for(var g=t;g<this.m;g++)h[g][c]+=l*h[g][t]}r[c]=h[t][c]}if((function(Tt,Ct){return Ct})(f,t<e))for(var d=t;d<this.m;d++)this.U[d][t]=h[d][t];if(t<u){r[t]=0;for(var C=t+1;C<this.n;C++)r[t]=v.hypot(r[t],r[C]);if(r[t]!==0){r[t+1]<0&&(r[t]=-r[t]);for(var S=t+1;S<this.n;S++)r[S]/=r[t];r[t+1]+=1}if(r[t]=-r[t],(function(Tt,Ct){return Tt&&Ct})(t+1<this.m,r[t]!==0)){for(var w=t+1;w<this.m;w++)a[w]=0;for(var P=t+1;P<this.n;P++)for(var B=t+1;B<this.m;B++)a[B]+=r[P]*h[B][P];for(var U=t+1;U<this.n;U++)for(var V=-r[U]/r[t+1],M=t+1;M<this.m;M++)h[M][U]+=V*a[M]}for(var _=t+1;_<this.n;_++)this.V[_][t]=r[_]}}var n=Math.min(this.n,this.m+1);e<this.n&&(this.s[e]=h[e][e]),this.m<n&&(this.s[n-1]=0),u+1<n&&(r[u]=h[u][n-1]),r[n-1]=0;{for(var E=e;E<i;E++){for(var p=0;p<this.m;p++)this.U[p][E]=0;this.U[E][E]=1}for(var m=e-1;m>=0;m--)if(this.s[m]!==0){for(var y=m+1;y<i;y++){for(var I=0,O=m;O<this.m;O++)I+=this.U[O][m]*this.U[O][y];I=-I/this.U[m][m];for(var R=m;R<this.m;R++)this.U[R][y]+=I*this.U[R][m]}for(var W=m;W<this.m;W++)this.U[W][m]=-this.U[W][m];this.U[m][m]=1+this.U[m][m];for(var x=0;x<m-1;x++)this.U[x][m]=0}else{for(var Q=0;Q<this.m;Q++)this.U[Q][m]=0;this.U[m][m]=1}}for(var z=this.n-1;z>=0;z--){if((function(Tt,Ct){return Tt&&Ct})(z<u,r[z]!==0))for(var X=z+1;X<i;X++){for(var rt=0,$=z+1;$<this.n;$++)rt+=this.V[$][z]*this.V[$][X];rt=-rt/this.V[z+1][z];for(var D=z+1;D<this.n;D++)this.V[D][X]+=rt*this.V[D][z]}for(var H=0;H<this.n;H++)this.V[H][z]=0;this.V[z][z]=1}for(var k=n-1,tt=Math.pow(2,-52),ht=Math.pow(2,-966);n>0;){var J=void 0,It=void 0;for(J=n-2;J>=-1&&J!==-1;J--)if(Math.abs(r[J])<=ht+tt*(Math.abs(this.s[J])+Math.abs(this.s[J+1]))){r[J]=0;break}if(J===n-2)It=4;else{var Nt=void 0;for(Nt=n-1;Nt>=J&&Nt!==J;Nt--){var vt=(Nt!==n?Math.abs(r[Nt]):0)+(Nt!==J+1?Math.abs(r[Nt-1]):0);if(Math.abs(this.s[Nt])<=ht+tt*vt){this.s[Nt]=0;break}}Nt===J?It=3:Nt===n-1?It=1:(It=2,J=Nt)}switch(J++,It){case 1:{var it=r[n-2];r[n-2]=0;for(var ut=n-2;ut>=J;ut--){var Et=v.hypot(this.s[ut],it),wt=this.s[ut]/Et,Ot=it/Et;this.s[ut]=Et,ut!==J&&(it=-Ot*r[ut-1],r[ut-1]=wt*r[ut-1]);for(var mt=0;mt<this.n;mt++)Et=wt*this.V[mt][ut]+Ot*this.V[mt][n-1],this.V[mt][n-1]=-Ot*this.V[mt][ut]+wt*this.V[mt][n-1],this.V[mt][ut]=Et}}break;case 2:{var Dt=r[J-1];r[J-1]=0;for(var Rt=J;Rt<n;Rt++){var Ht=v.hypot(this.s[Rt],Dt),Ut=this.s[Rt]/Ht,Pt=Dt/Ht;this.s[Rt]=Ht,Dt=-Pt*r[Rt],r[Rt]=Ut*r[Rt];for(var Ft=0;Ft<this.m;Ft++)Ht=Ut*this.U[Ft][Rt]+Pt*this.U[Ft][J-1],this.U[Ft][J-1]=-Pt*this.U[Ft][Rt]+Ut*this.U[Ft][J-1],this.U[Ft][Rt]=Ht}}break;case 3:{var Yt=Math.max(Math.max(Math.max(Math.max(Math.abs(this.s[n-1]),Math.abs(this.s[n-2])),Math.abs(r[n-2])),Math.abs(this.s[J])),Math.abs(r[J])),Vt=this.s[n-1]/Yt,F=this.s[n-2]/Yt,Y=r[n-2]/Yt,Z=this.s[J]/Yt,K=r[J]/Yt,q=((F+Vt)*(F-Vt)+Y*Y)/2,at=Vt*Y*(Vt*Y),ct=0;(function(Tt,Ct){return Tt||Ct})(q!==0,at!==0)&&(ct=Math.sqrt(q*q+at),q<0&&(ct=-ct),ct=at/(q+ct));for(var nt=(Z+Vt)*(Z-Vt)+ct,et=Z*K,j=J;j<n-1;j++){var dt=v.hypot(nt,et),At=nt/dt,pt=et/dt;j!==J&&(r[j-1]=dt),nt=At*this.s[j]+pt*r[j],r[j]=At*r[j]-pt*this.s[j],et=pt*this.s[j+1],this.s[j+1]=At*this.s[j+1];for(var xt=0;xt<this.n;xt++)dt=At*this.V[xt][j]+pt*this.V[xt][j+1],this.V[xt][j+1]=-pt*this.V[xt][j]+At*this.V[xt][j+1],this.V[xt][j]=dt;if(dt=v.hypot(nt,et),At=nt/dt,pt=et/dt,this.s[j]=dt,nt=At*r[j]+pt*this.s[j+1],this.s[j+1]=-pt*r[j]+At*this.s[j+1],et=pt*r[j+1],r[j+1]=At*r[j+1],j<this.m-1)for(var lt=0;lt<this.m;lt++)dt=At*this.U[lt][j]+pt*this.U[lt][j+1],this.U[lt][j+1]=-pt*this.U[lt][j]+At*this.U[lt][j+1],this.U[lt][j]=dt}r[n-2]=nt}break;case 4:{if(this.s[J]<=0){this.s[J]=this.s[J]<0?-this.s[J]:0;for(var ot=0;ot<=k;ot++)this.V[ot][J]=-this.V[ot][J]}for(;J<k&&!(this.s[J]>=this.s[J+1]);){var Lt=this.s[J];if(this.s[J]=this.s[J+1],this.s[J+1]=Lt,J<this.n-1)for(var ft=0;ft<this.n;ft++)Lt=this.V[ft][J+1],this.V[ft][J+1]=this.V[ft][J],this.V[ft][J]=Lt;if(J<this.m-1)for(var st=0;st<this.m;st++)Lt=this.U[st][J+1],this.U[st][J+1]=this.U[st][J],this.U[st][J]=Lt;J++}n--}break}}var Xt={U:this.U,V:this.V,S:this.s};return Xt},v.hypot=function(h,i){var r=void 0;return Math.abs(h)>Math.abs(i)?(r=i/h,r=Math.abs(h)*Math.sqrt(1+r*r)):i!=0?(r=h/i,r=Math.abs(i)*Math.sqrt(1+r*r)):r=0,r},A.exports=v}),(function(A,G,N){var v=(function(){function r(a,f){for(var e=0;e<f.length;e++){var u=f[e];u.enumerable=u.enumerable||!1,u.configurable=!0,"value"in u&&(u.writable=!0),Object.defineProperty(a,u.key,u)}}return function(a,f,e){return f&&r(a.prototype,f),e&&r(a,e),a}})();function h(r,a){if(!(r instanceof a))throw new TypeError("Cannot call a class as a function")}var i=(function(){function r(a,f){var e=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,u=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,t=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;h(this,r),this.sequence1=a,this.sequence2=f,this.match_score=e,this.mismatch_penalty=u,this.gap_penalty=t,this.iMax=a.length+1,this.jMax=f.length+1,this.grid=new Array(this.iMax);for(var s=0;s<this.iMax;s++){this.grid[s]=new Array(this.jMax);for(var o=0;o<this.jMax;o++)this.grid[s][o]=0}this.tracebackGrid=new Array(this.iMax);for(var c=0;c<this.iMax;c++){this.tracebackGrid[c]=new Array(this.jMax);for(var l=0;l<this.jMax;l++)this.tracebackGrid[c][l]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return v(r,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var f=1;f<this.jMax;f++)this.grid[0][f]=this.grid[0][f-1]+this.gap_penalty,this.tracebackGrid[0][f]=[!1,!1,!0];for(var e=1;e<this.iMax;e++)this.grid[e][0]=this.grid[e-1][0]+this.gap_penalty,this.tracebackGrid[e][0]=[!1,!0,!1];for(var u=1;u<this.iMax;u++)for(var t=1;t<this.jMax;t++){var s=void 0;this.sequence1[u-1]===this.sequence2[t-1]?s=this.grid[u-1][t-1]+this.match_score:s=this.grid[u-1][t-1]+this.mismatch_penalty;var o=this.grid[u-1][t]+this.gap_penalty,c=this.grid[u][t-1]+this.gap_penalty,l=[s,o,c],T=this.arrayAllMaxIndexes(l);this.grid[u][t]=l[T[0]],this.tracebackGrid[u][t]=[T.includes(0),T.includes(1),T.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var f=[];for(f.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});f[0];){var e=f[0],u=this.tracebackGrid[e.pos[0]][e.pos[1]];u[0]&&f.push({pos:[e.pos[0]-1,e.pos[1]-1],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),u[1]&&f.push({pos:[e.pos[0]-1,e.pos[1]],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:"-"+e.seq2}),u[2]&&f.push({pos:[e.pos[0],e.pos[1]-1],seq1:"-"+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),e.pos[0]===0&&e.pos[1]===0&&this.alignments.push({sequence1:e.seq1,sequence2:e.seq2}),f.shift()}return this.alignments}},{key:"getAllIndexes",value:function(f,e){for(var u=[],t=-1;(t=f.indexOf(e,t+1))!==-1;)u.push(t);return u}},{key:"arrayAllMaxIndexes",value:function(f){return this.getAllIndexes(f,Math.max.apply(null,f))}}]),r})();A.exports=i}),(function(A,G,N){var v=function(){};v.FDLayout=N(18),v.FDLayoutConstants=N(4),v.FDLayoutEdge=N(19),v.FDLayoutNode=N(20),v.DimensionD=N(21),v.HashMap=N(22),v.HashSet=N(23),v.IGeometry=N(8),v.IMath=N(9),v.Integer=N(10),v.Point=N(12),v.PointD=N(5),v.RandomSeed=N(16),v.RectangleD=N(13),v.Transform=N(17),v.UniqueIDGeneretor=N(14),v.Quicksort=N(25),v.LinkedList=N(11),v.LGraphObject=N(2),v.LGraph=N(6),v.LEdge=N(1),v.LGraphManager=N(7),v.LNode=N(3),v.Layout=N(15),v.LayoutConstants=N(0),v.NeedlemanWunsch=N(27),v.Matrix=N(24),v.SVD=N(26),A.exports=v}),(function(A,G,N){function v(){this.listeners=[]}var h=v.prototype;h.addListener=function(i,r){this.listeners.push({event:i,callback:r})},h.removeListener=function(i,r){for(var a=this.listeners.length;a>=0;a--){var f=this.listeners[a];f.event===i&&f.callback===r&&this.listeners.splice(a,1)}},h.emit=function(i,r){for(var a=0;a<this.listeners.length;a++){var f=this.listeners[a];i===f.event&&f.callback(r)}},A.exports=v})])})})(le)),le.exports}var dr=he.exports,Oe;function vr(){return Oe||(Oe=1,(function(L,b){(function(G,N){L.exports=N(ur())})(dr,function(A){return(()=>{var G={45:((i,r,a)=>{var f={};f.layoutBase=a(551),f.CoSEConstants=a(806),f.CoSEEdge=a(767),f.CoSEGraph=a(880),f.CoSEGraphManager=a(578),f.CoSELayout=a(765),f.CoSENode=a(991),f.ConstraintHandler=a(902),i.exports=f}),806:((i,r,a)=>{var f=a(551).FDLayoutConstants;function e(){}for(var u in f)e[u]=f[u];e.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,e.DEFAULT_RADIAL_SEPARATION=f.DEFAULT_EDGE_LENGTH,e.DEFAULT_COMPONENT_SEPERATION=60,e.TILE=!0,e.TILING_PADDING_VERTICAL=10,e.TILING_PADDING_HORIZONTAL=10,e.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,e.ENFORCE_CONSTRAINTS=!0,e.APPLY_LAYOUT=!0,e.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,e.TREE_REDUCTION_ON_INCREMENTAL=!0,e.PURE_INCREMENTAL=e.DEFAULT_INCREMENTAL,i.exports=e}),767:((i,r,a)=>{var f=a(551).FDLayoutEdge;function e(t,s,o){f.call(this,t,s,o)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),880:((i,r,a)=>{var f=a(551).LGraph;function e(t,s,o){f.call(this,t,s,o)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),578:((i,r,a)=>{var f=a(551).LGraphManager;function e(t){f.call(this,t)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),765:((i,r,a)=>{var f=a(551).FDLayout,e=a(578),u=a(880),t=a(991),s=a(767),o=a(806),c=a(902),l=a(551).FDLayoutConstants,T=a(551).LayoutConstants,g=a(551).Point,d=a(551).PointD,C=a(551).DimensionD,S=a(551).Layout,w=a(551).Integer,P=a(551).IGeometry,B=a(551).LGraph,U=a(551).Transform,V=a(551).LinkedList;function M(){f.call(this),this.toBeTiled={},this.constraints={}}M.prototype=Object.create(f.prototype);for(var _ in f)M[_]=f[_];M.prototype.newGraphManager=function(){var n=new e(this);return this.graphManager=n,n},M.prototype.newGraph=function(n){return new u(null,this.graphManager,n)},M.prototype.newNode=function(n){return new t(this.graphManager,n)},M.prototype.newEdge=function(n){return new s(null,null,n)},M.prototype.initParameters=function(){f.prototype.initParameters.call(this,arguments),this.isSubLayout||(o.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=o.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=o.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=l.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=l.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=l.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},M.prototype.initSpringEmbedder=function(){f.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/l.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},M.prototype.layout=function(){var n=T.DEFAULT_CREATE_BENDS_AS_NEEDED;return n&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},M.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(o.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),p=this.nodesWithGravity.filter(function(I){return E.has(I)});this.graphManager.setAllNodesToApplyGravitation(p)}}else{var n=this.getFlatForest();if(n.length>0)this.positionNodesRadially(n);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),p=this.nodesWithGravity.filter(function(m){return E.has(m)});this.graphManager.setAllNodesToApplyGravitation(p),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(c.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),o.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},M.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%l.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var n=new Set(this.getAllNodes()),E=this.nodesWithGravity.filter(function(y){return n.has(y)});this.graphManager.setAllNodesToApplyGravitation(E),this.graphManager.updateBounds(),this.updateGrid(),o.PURE_INCREMENTAL?this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),o.PURE_INCREMENTAL?this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var p=!this.isTreeGrowing&&!this.isGrowthFinished,m=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(p,m),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},M.prototype.getPositionsData=function(){for(var n=this.graphManager.getAllNodes(),E={},p=0;p<n.length;p++){var m=n[p].rect,y=n[p].id;E[y]={id:y,x:m.getCenterX(),y:m.getCenterY(),w:m.width,h:m.height}}return E},M.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var n=!1;if(l.ANIMATE==="during")this.emit("layoutstarted");else{for(;!n;)n=this.tick();this.graphManager.updateBounds()}},M.prototype.moveNodes=function(){for(var n=this.getAllNodes(),E,p=0;p<n.length;p++)E=n[p],E.calculateDisplacement();Object.keys(this.constraints).length>0&&this.updateDisplacements();for(var p=0;p<n.length;p++)E=n[p],E.move()},M.prototype.initConstraintVariables=function(){var n=this;this.idToNodeMap=new Map,this.fixedNodeSet=new Set;for(var E=this.graphManager.getAllNodes(),p=0;p<E.length;p++){var m=E[p];this.idToNodeMap.set(m.id,m)}var y=function D(H){for(var k=H.getChild().getNodes(),tt,ht=0,J=0;J<k.length;J++)tt=k[J],tt.getChild()==null?n.fixedNodeSet.has(tt.id)&&(ht+=100):ht+=D(tt);return ht};if(this.constraints.fixedNodeConstraint){this.constraints.fixedNodeConstraint.forEach(function(k){n.fixedNodeSet.add(k.nodeId)});for(var E=this.graphManager.getAllNodes(),m,p=0;p<E.length;p++)if(m=E[p],m.getChild()!=null){var I=y(m);I>0&&(m.fixedNodeWeight=I)}}if(this.constraints.relativePlacementConstraint){var O=new Map,R=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(D){n.fixedNodesOnHorizontal.add(D),n.fixedNodesOnVertical.add(D)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var W=this.constraints.alignmentConstraint.vertical,p=0;p<W.length;p++)this.dummyToNodeForVerticalAlignment.set("dummy"+p,[]),W[p].forEach(function(H){O.set(H,"dummy"+p),n.dummyToNodeForVerticalAlignment.get("dummy"+p).push(H),n.fixedNodeSet.has(H)&&n.fixedNodesOnHorizontal.add("dummy"+p)});if(this.constraints.alignmentConstraint.horizontal)for(var x=this.constraints.alignmentConstraint.horizontal,p=0;p<x.length;p++)this.dummyToNodeForHorizontalAlignment.set("dummy"+p,[]),x[p].forEach(function(H){R.set(H,"dummy"+p),n.dummyToNodeForHorizontalAlignment.get("dummy"+p).push(H),n.fixedNodeSet.has(H)&&n.fixedNodesOnVertical.add("dummy"+p)})}if(o.RELAX_MOVEMENT_ON_CONSTRAINTS)this.shuffle=function(D){var H,k,tt;for(tt=D.length-1;tt>=2*D.length/3;tt--)H=Math.floor(Math.random()*(tt+1)),k=D[tt],D[tt]=D[H],D[H]=k;return D},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(D){if(D.left){var H=O.has(D.left)?O.get(D.left):D.left,k=O.has(D.right)?O.get(D.right):D.right;n.nodesInRelativeHorizontal.includes(H)||(n.nodesInRelativeHorizontal.push(H),n.nodeToRelativeConstraintMapHorizontal.set(H,[]),n.dummyToNodeForVerticalAlignment.has(H)?n.nodeToTempPositionMapHorizontal.set(H,n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get(H)[0]).getCenterX()):n.nodeToTempPositionMapHorizontal.set(H,n.idToNodeMap.get(H).getCenterX())),n.nodesInRelativeHorizontal.includes(k)||(n.nodesInRelativeHorizontal.push(k),n.nodeToRelativeConstraintMapHorizontal.set(k,[]),n.dummyToNodeForVerticalAlignment.has(k)?n.nodeToTempPositionMapHorizontal.set(k,n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get(k)[0]).getCenterX()):n.nodeToTempPositionMapHorizontal.set(k,n.idToNodeMap.get(k).getCenterX())),n.nodeToRelativeConstraintMapHorizontal.get(H).push({right:k,gap:D.gap}),n.nodeToRelativeConstraintMapHorizontal.get(k).push({left:H,gap:D.gap})}else{var tt=R.has(D.top)?R.get(D.top):D.top,ht=R.has(D.bottom)?R.get(D.bottom):D.bottom;n.nodesInRelativeVertical.includes(tt)||(n.nodesInRelativeVertical.push(tt),n.nodeToRelativeConstraintMapVertical.set(tt,[]),n.dummyToNodeForHorizontalAlignment.has(tt)?n.nodeToTempPositionMapVertical.set(tt,n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get(tt)[0]).getCenterY()):n.nodeToTempPositionMapVertical.set(tt,n.idToNodeMap.get(tt).getCenterY())),n.nodesInRelativeVertical.includes(ht)||(n.nodesInRelativeVertical.push(ht),n.nodeToRelativeConstraintMapVertical.set(ht,[]),n.dummyToNodeForHorizontalAlignment.has(ht)?n.nodeToTempPositionMapVertical.set(ht,n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get(ht)[0]).getCenterY()):n.nodeToTempPositionMapVertical.set(ht,n.idToNodeMap.get(ht).getCenterY())),n.nodeToRelativeConstraintMapVertical.get(tt).push({bottom:ht,gap:D.gap}),n.nodeToRelativeConstraintMapVertical.get(ht).push({top:tt,gap:D.gap})}});else{var Q=new Map,z=new Map;this.constraints.relativePlacementConstraint.forEach(function(D){if(D.left){var H=O.has(D.left)?O.get(D.left):D.left,k=O.has(D.right)?O.get(D.right):D.right;Q.has(H)?Q.get(H).push(k):Q.set(H,[k]),Q.has(k)?Q.get(k).push(H):Q.set(k,[H])}else{var tt=R.has(D.top)?R.get(D.top):D.top,ht=R.has(D.bottom)?R.get(D.bottom):D.bottom;z.has(tt)?z.get(tt).push(ht):z.set(tt,[ht]),z.has(ht)?z.get(ht).push(tt):z.set(ht,[tt])}});var X=function(H,k){var tt=[],ht=[],J=new V,It=new Set,Nt=0;return H.forEach(function(vt,it){if(!It.has(it)){tt[Nt]=[],ht[Nt]=!1;var ut=it;for(J.push(ut),It.add(ut),tt[Nt].push(ut);J.length!=0;){ut=J.shift(),k.has(ut)&&(ht[Nt]=!0);var Et=H.get(ut);Et.forEach(function(wt){It.has(wt)||(J.push(wt),It.add(wt),tt[Nt].push(wt))})}Nt++}}),{components:tt,isFixed:ht}},rt=X(Q,n.fixedNodesOnHorizontal);this.componentsOnHorizontal=rt.components,this.fixedComponentsOnHorizontal=rt.isFixed;var $=X(z,n.fixedNodesOnVertical);this.componentsOnVertical=$.components,this.fixedComponentsOnVertical=$.isFixed}}},M.prototype.updateDisplacements=function(){var n=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function($){var D=n.idToNodeMap.get($.nodeId);D.displacementX=0,D.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var E=this.constraints.alignmentConstraint.vertical,p=0;p<E.length;p++){for(var m=0,y=0;y<E[p].length;y++){if(this.fixedNodeSet.has(E[p][y])){m=0;break}m+=this.idToNodeMap.get(E[p][y]).displacementX}for(var I=m/E[p].length,y=0;y<E[p].length;y++)this.idToNodeMap.get(E[p][y]).displacementX=I}if(this.constraints.alignmentConstraint.horizontal)for(var O=this.constraints.alignmentConstraint.horizontal,p=0;p<O.length;p++){for(var R=0,y=0;y<O[p].length;y++){if(this.fixedNodeSet.has(O[p][y])){R=0;break}R+=this.idToNodeMap.get(O[p][y]).displacementY}for(var W=R/O[p].length,y=0;y<O[p].length;y++)this.idToNodeMap.get(O[p][y]).displacementY=W}}if(this.constraints.relativePlacementConstraint)if(o.RELAX_MOVEMENT_ON_CONSTRAINTS)this.totalIterations%10==0&&(this.shuffle(this.nodesInRelativeHorizontal),this.shuffle(this.nodesInRelativeVertical)),this.nodesInRelativeHorizontal.forEach(function($){if(!n.fixedNodesOnHorizontal.has($)){var D=0;n.dummyToNodeForVerticalAlignment.has($)?D=n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get($)[0]).displacementX:D=n.idToNodeMap.get($).displacementX,n.nodeToRelativeConstraintMapHorizontal.get($).forEach(function(H){if(H.right){var k=n.nodeToTempPositionMapHorizontal.get(H.right)-n.nodeToTempPositionMapHorizontal.get($)-D;k<H.gap&&(D-=H.gap-k)}else{var k=n.nodeToTempPositionMapHorizontal.get($)-n.nodeToTempPositionMapHorizontal.get(H.left)+D;k<H.gap&&(D+=H.gap-k)}}),n.nodeToTempPositionMapHorizontal.set($,n.nodeToTempPositionMapHorizontal.get($)+D),n.dummyToNodeForVerticalAlignment.has($)?n.dummyToNodeForVerticalAlignment.get($).forEach(function(H){n.idToNodeMap.get(H).displacementX=D}):n.idToNodeMap.get($).displacementX=D}}),this.nodesInRelativeVertical.forEach(function($){if(!n.fixedNodesOnHorizontal.has($)){var D=0;n.dummyToNodeForHorizontalAlignment.has($)?D=n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get($)[0]).displacementY:D=n.idToNodeMap.get($).displacementY,n.nodeToRelativeConstraintMapVertical.get($).forEach(function(H){if(H.bottom){var k=n.nodeToTempPositionMapVertical.get(H.bottom)-n.nodeToTempPositionMapVertical.get($)-D;k<H.gap&&(D-=H.gap-k)}else{var k=n.nodeToTempPositionMapVertical.get($)-n.nodeToTempPositionMapVertical.get(H.top)+D;k<H.gap&&(D+=H.gap-k)}}),n.nodeToTempPositionMapVertical.set($,n.nodeToTempPositionMapVertical.get($)+D),n.dummyToNodeForHorizontalAlignment.has($)?n.dummyToNodeForHorizontalAlignment.get($).forEach(function(H){n.idToNodeMap.get(H).displacementY=D}):n.idToNodeMap.get($).displacementY=D}});else{for(var p=0;p<this.componentsOnHorizontal.length;p++){var x=this.componentsOnHorizontal[p];if(this.fixedComponentsOnHorizontal[p])for(var y=0;y<x.length;y++)this.dummyToNodeForVerticalAlignment.has(x[y])?this.dummyToNodeForVerticalAlignment.get(x[y]).forEach(function(H){n.idToNodeMap.get(H).displacementX=0}):this.idToNodeMap.get(x[y]).displacementX=0;else{for(var Q=0,z=0,y=0;y<x.length;y++)if(this.dummyToNodeForVerticalAlignment.has(x[y])){var X=this.dummyToNodeForVerticalAlignment.get(x[y]);Q+=X.length*this.idToNodeMap.get(X[0]).displacementX,z+=X.length}else Q+=this.idToNodeMap.get(x[y]).displacementX,z++;for(var rt=Q/z,y=0;y<x.length;y++)this.dummyToNodeForVerticalAlignment.has(x[y])?this.dummyToNodeForVerticalAlignment.get(x[y]).forEach(function(H){n.idToNodeMap.get(H).displacementX=rt}):this.idToNodeMap.get(x[y]).displacementX=rt}}for(var p=0;p<this.componentsOnVertical.length;p++){var x=this.componentsOnVertical[p];if(this.fixedComponentsOnVertical[p])for(var y=0;y<x.length;y++)this.dummyToNodeForHorizontalAlignment.has(x[y])?this.dummyToNodeForHorizontalAlignment.get(x[y]).forEach(function(k){n.idToNodeMap.get(k).displacementY=0}):this.idToNodeMap.get(x[y]).displacementY=0;else{for(var Q=0,z=0,y=0;y<x.length;y++)if(this.dummyToNodeForHorizontalAlignment.has(x[y])){var X=this.dummyToNodeForHorizontalAlignment.get(x[y]);Q+=X.length*this.idToNodeMap.get(X[0]).displacementY,z+=X.length}else Q+=this.idToNodeMap.get(x[y]).displacementY,z++;for(var rt=Q/z,y=0;y<x.length;y++)this.dummyToNodeForHorizontalAlignment.has(x[y])?this.dummyToNodeForHorizontalAlignment.get(x[y]).forEach(function(J){n.idToNodeMap.get(J).displacementY=rt}):this.idToNodeMap.get(x[y]).displacementY=rt}}}},M.prototype.calculateNodesToApplyGravitationTo=function(){var n=[],E,p=this.graphManager.getGraphs(),m=p.length,y;for(y=0;y<m;y++)E=p[y],E.updateConnected(),E.isConnected||(n=n.concat(E.getNodes()));return n},M.prototype.createBendpoints=function(){var n=[];n=n.concat(this.graphManager.getAllEdges());var E=new Set,p;for(p=0;p<n.length;p++){var m=n[p];if(!E.has(m)){var y=m.getSource(),I=m.getTarget();if(y==I)m.getBendpoints().push(new d),m.getBendpoints().push(new d),this.createDummyNodesForBendpoints(m),E.add(m);else{var O=[];if(O=O.concat(y.getEdgeListToNode(I)),O=O.concat(I.getEdgeListToNode(y)),!E.has(O[0])){if(O.length>1){var R;for(R=0;R<O.length;R++){var W=O[R];W.getBendpoints().push(new d),this.createDummyNodesForBendpoints(W)}}O.forEach(function(x){E.add(x)})}}}if(E.size==n.length)break}},M.prototype.positionNodesRadially=function(n){for(var E=new g(0,0),p=Math.ceil(Math.sqrt(n.length)),m=0,y=0,I=0,O=new d(0,0),R=0;R<n.length;R++){R%p==0&&(I=0,y=m,R!=0&&(y+=o.DEFAULT_COMPONENT_SEPERATION),m=0);var W=n[R],x=S.findCenterOfTree(W);E.x=I,E.y=y,O=M.radialLayout(W,x,E),O.y>m&&(m=Math.floor(O.y)),I=Math.floor(O.x+o.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(T.WORLD_CENTER_X-O.x/2,T.WORLD_CENTER_Y-O.y/2))},M.radialLayout=function(n,E,p){var m=Math.max(this.maxDiagonalInTree(n),o.DEFAULT_RADIAL_SEPARATION);M.branchRadialLayout(E,null,0,359,0,m);var y=B.calculateBounds(n),I=new U;I.setDeviceOrgX(y.getMinX()),I.setDeviceOrgY(y.getMinY()),I.setWorldOrgX(p.x),I.setWorldOrgY(p.y);for(var O=0;O<n.length;O++){var R=n[O];R.transform(I)}var W=new d(y.getMaxX(),y.getMaxY());return I.inverseTransformPoint(W)},M.branchRadialLayout=function(n,E,p,m,y,I){var O=(m-p+1)/2;O<0&&(O+=180);var R=(O+p)%360,W=R*P.TWO_PI/360,x=y*Math.cos(W),Q=y*Math.sin(W);n.setCenter(x,Q);var z=[];z=z.concat(n.getEdges());var X=z.length;E!=null&&X--;for(var rt=0,$=z.length,D,H=n.getEdgesBetween(E);H.length>1;){var k=H[0];H.splice(0,1);var tt=z.indexOf(k);tt>=0&&z.splice(tt,1),$--,X--}E!=null?D=(z.indexOf(H[0])+1)%$:D=0;for(var ht=Math.abs(m-p)/X,J=D;rt!=X;J=++J%$){var It=z[J].getOtherEnd(n);if(It!=E){var Nt=(p+rt*ht)%360,vt=(Nt+ht)%360;M.branchRadialLayout(It,n,Nt,vt,y+I,I),rt++}}},M.maxDiagonalInTree=function(n){for(var E=w.MIN_VALUE,p=0;p<n.length;p++){var m=n[p],y=m.getDiagonal();y>E&&(E=y)}return E},M.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},M.prototype.groupZeroDegreeMembers=function(){var n=this,E={};this.memberGroups={},this.idToDummyNode={};for(var p=[],m=this.graphManager.getAllNodes(),y=0;y<m.length;y++){var I=m[y],O=I.getParent();this.getNodeDegreeWithChildren(I)===0&&(O.id==null||!this.getToBeTiled(O))&&p.push(I)}for(var y=0;y<p.length;y++){var I=p[y],R=I.getParent().id;typeof E[R]>"u"&&(E[R]=[]),E[R]=E[R].concat(I)}Object.keys(E).forEach(function(W){if(E[W].length>1){var x="DummyCompound_"+W;n.memberGroups[x]=E[W];var Q=E[W][0].getParent(),z=new t(n.graphManager);z.id=x,z.paddingLeft=Q.paddingLeft||0,z.paddingRight=Q.paddingRight||0,z.paddingBottom=Q.paddingBottom||0,z.paddingTop=Q.paddingTop||0,n.idToDummyNode[x]=z;var X=n.getGraphManager().add(n.newGraph(),z),rt=Q.getChild();rt.add(z);for(var $=0;$<E[W].length;$++){var D=E[W][$];rt.remove(D),X.add(D)}}})},M.prototype.clearCompounds=function(){var n={},E={};this.performDFSOnCompounds();for(var p=0;p<this.compoundOrder.length;p++)E[this.compoundOrder[p].id]=this.compoundOrder[p],n[this.compoundOrder[p].id]=[].concat(this.compoundOrder[p].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[p].getChild()),this.compoundOrder[p].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(n,E)},M.prototype.clearZeroDegreeMembers=function(){var n=this,E=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(p){var m=n.idToDummyNode[p];if(E[p]=n.tileNodes(n.memberGroups[p],m.paddingLeft+m.paddingRight),m.rect.width=E[p].width,m.rect.height=E[p].height,m.setCenter(E[p].centerX,E[p].centerY),m.labelMarginLeft=0,m.labelMarginTop=0,o.NODE_DIMENSIONS_INCLUDE_LABELS){var y=m.rect.width,I=m.rect.height;m.labelWidth&&(m.labelPosHorizontal=="left"?(m.rect.x-=m.labelWidth,m.setWidth(y+m.labelWidth),m.labelMarginLeft=m.labelWidth):m.labelPosHorizontal=="center"&&m.labelWidth>y?(m.rect.x-=(m.labelWidth-y)/2,m.setWidth(m.labelWidth),m.labelMarginLeft=(m.labelWidth-y)/2):m.labelPosHorizontal=="right"&&m.setWidth(y+m.labelWidth)),m.labelHeight&&(m.labelPosVertical=="top"?(m.rect.y-=m.labelHeight,m.setHeight(I+m.labelHeight),m.labelMarginTop=m.labelHeight):m.labelPosVertical=="center"&&m.labelHeight>I?(m.rect.y-=(m.labelHeight-I)/2,m.setHeight(m.labelHeight),m.labelMarginTop=(m.labelHeight-I)/2):m.labelPosVertical=="bottom"&&m.setHeight(I+m.labelHeight))}})},M.prototype.repopulateCompounds=function(){for(var n=this.compoundOrder.length-1;n>=0;n--){var E=this.compoundOrder[n],p=E.id,m=E.paddingLeft,y=E.paddingTop,I=E.labelMarginLeft,O=E.labelMarginTop;this.adjustLocations(this.tiledMemberPack[p],E.rect.x,E.rect.y,m,y,I,O)}},M.prototype.repopulateZeroDegreeMembers=function(){var n=this,E=this.tiledZeroDegreePack;Object.keys(E).forEach(function(p){var m=n.idToDummyNode[p],y=m.paddingLeft,I=m.paddingTop,O=m.labelMarginLeft,R=m.labelMarginTop;n.adjustLocations(E[p],m.rect.x,m.rect.y,y,I,O,R)})},M.prototype.getToBeTiled=function(n){var E=n.id;if(this.toBeTiled[E]!=null)return this.toBeTiled[E];var p=n.getChild();if(p==null)return this.toBeTiled[E]=!1,!1;for(var m=p.getNodes(),y=0;y<m.length;y++){var I=m[y];if(this.getNodeDegree(I)>0)return this.toBeTiled[E]=!1,!1;if(I.getChild()==null){this.toBeTiled[I.id]=!1;continue}if(!this.getToBeTiled(I))return this.toBeTiled[E]=!1,!1}return this.toBeTiled[E]=!0,!0},M.prototype.getNodeDegree=function(n){n.id;for(var E=n.getEdges(),p=0,m=0;m<E.length;m++){var y=E[m];y.getSource().id!==y.getTarget().id&&(p=p+1)}return p},M.prototype.getNodeDegreeWithChildren=function(n){var E=this.getNodeDegree(n);if(n.getChild()==null)return E;for(var p=n.getChild().getNodes(),m=0;m<p.length;m++){var y=p[m];E+=this.getNodeDegreeWithChildren(y)}return E},M.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},M.prototype.fillCompexOrderByDFS=function(n){for(var E=0;E<n.length;E++){var p=n[E];p.getChild()!=null&&this.fillCompexOrderByDFS(p.getChild().getNodes()),this.getToBeTiled(p)&&this.compoundOrder.push(p)}},M.prototype.adjustLocations=function(n,E,p,m,y,I,O){E+=m+I,p+=y+O;for(var R=E,W=0;W<n.rows.length;W++){var x=n.rows[W];E=R;for(var Q=0,z=0;z<x.length;z++){var X=x[z];X.rect.x=E,X.rect.y=p,E+=X.rect.width+n.horizontalPadding,X.rect.height>Q&&(Q=X.rect.height)}p+=Q+n.verticalPadding}},M.prototype.tileCompoundMembers=function(n,E){var p=this;this.tiledMemberPack=[],Object.keys(n).forEach(function(m){var y=E[m];if(p.tiledMemberPack[m]=p.tileNodes(n[m],y.paddingLeft+y.paddingRight),y.rect.width=p.tiledMemberPack[m].width,y.rect.height=p.tiledMemberPack[m].height,y.setCenter(p.tiledMemberPack[m].centerX,p.tiledMemberPack[m].centerY),y.labelMarginLeft=0,y.labelMarginTop=0,o.NODE_DIMENSIONS_INCLUDE_LABELS){var I=y.rect.width,O=y.rect.height;y.labelWidth&&(y.labelPosHorizontal=="left"?(y.rect.x-=y.labelWidth,y.setWidth(I+y.labelWidth),y.labelMarginLeft=y.labelWidth):y.labelPosHorizontal=="center"&&y.labelWidth>I?(y.rect.x-=(y.labelWidth-I)/2,y.setWidth(y.labelWidth),y.labelMarginLeft=(y.labelWidth-I)/2):y.labelPosHorizontal=="right"&&y.setWidth(I+y.labelWidth)),y.labelHeight&&(y.labelPosVertical=="top"?(y.rect.y-=y.labelHeight,y.setHeight(O+y.labelHeight),y.labelMarginTop=y.labelHeight):y.labelPosVertical=="center"&&y.labelHeight>O?(y.rect.y-=(y.labelHeight-O)/2,y.setHeight(y.labelHeight),y.labelMarginTop=(y.labelHeight-O)/2):y.labelPosVertical=="bottom"&&y.setHeight(O+y.labelHeight))}})},M.prototype.tileNodes=function(n,E){var p=this.tileNodesByFavoringDim(n,E,!0),m=this.tileNodesByFavoringDim(n,E,!1),y=this.getOrgRatio(p),I=this.getOrgRatio(m),O;return I<y?O=m:O=p,O},M.prototype.getOrgRatio=function(n){var E=n.width,p=n.height,m=E/p;return m<1&&(m=1/m),m},M.prototype.calcIdealRowWidth=function(n,E){var p=o.TILING_PADDING_VERTICAL,m=o.TILING_PADDING_HORIZONTAL,y=n.length,I=0,O=0,R=0;n.forEach(function($){I+=$.getWidth(),O+=$.getHeight(),$.getWidth()>R&&(R=$.getWidth())});var W=I/y,x=O/y,Q=Math.pow(p-m,2)+4*(W+m)*(x+p)*y,z=(m-p+Math.sqrt(Q))/(2*(W+m)),X;E?(X=Math.ceil(z),X==z&&X++):X=Math.floor(z);var rt=X*(W+m)-m;return R>rt&&(rt=R),rt+=m*2,rt},M.prototype.tileNodesByFavoringDim=function(n,E,p){var m=o.TILING_PADDING_VERTICAL,y=o.TILING_PADDING_HORIZONTAL,I=o.TILING_COMPARE_BY,O={rows:[],rowWidth:[],rowHeight:[],width:0,height:E,verticalPadding:m,horizontalPadding:y,centerX:0,centerY:0};I&&(O.idealRowWidth=this.calcIdealRowWidth(n,p));var R=function(D){return D.rect.width*D.rect.height},W=function(D,H){return R(H)-R(D)};n.sort(function($,D){var H=W;return O.idealRowWidth?(H=I,H($.id,D.id)):H($,D)});for(var x=0,Q=0,z=0;z<n.length;z++){var X=n[z];x+=X.getCenterX(),Q+=X.getCenterY()}O.centerX=x/n.length,O.centerY=Q/n.length;for(var z=0;z<n.length;z++){var X=n[z];if(O.rows.length==0)this.insertNodeToRow(O,X,0,E);else if(this.canAddHorizontal(O,X.rect.width,X.rect.height)){var rt=O.rows.length-1;O.idealRowWidth||(rt=this.getShortestRowIndex(O)),this.insertNodeToRow(O,X,rt,E)}else this.insertNodeToRow(O,X,O.rows.length,E);this.shiftToLastRow(O)}return O},M.prototype.insertNodeToRow=function(n,E,p,m){var y=m;if(p==n.rows.length){var I=[];n.rows.push(I),n.rowWidth.push(y),n.rowHeight.push(0)}var O=n.rowWidth[p]+E.rect.width;n.rows[p].length>0&&(O+=n.horizontalPadding),n.rowWidth[p]=O,n.width<O&&(n.width=O);var R=E.rect.height;p>0&&(R+=n.verticalPadding);var W=0;R>n.rowHeight[p]&&(W=n.rowHeight[p],n.rowHeight[p]=R,W=n.rowHeight[p]-W),n.height+=W,n.rows[p].push(E)},M.prototype.getShortestRowIndex=function(n){for(var E=-1,p=Number.MAX_VALUE,m=0;m<n.rows.length;m++)n.rowWidth[m]<p&&(E=m,p=n.rowWidth[m]);return E},M.prototype.getLongestRowIndex=function(n){for(var E=-1,p=Number.MIN_VALUE,m=0;m<n.rows.length;m++)n.rowWidth[m]>p&&(E=m,p=n.rowWidth[m]);return E},M.prototype.canAddHorizontal=function(n,E,p){if(n.idealRowWidth){var m=n.rows.length-1,y=n.rowWidth[m];return y+E+n.horizontalPadding<=n.idealRowWidth}var I=this.getShortestRowIndex(n);if(I<0)return!0;var O=n.rowWidth[I];if(O+n.horizontalPadding+E<=n.width)return!0;var R=0;n.rowHeight[I]<p&&I>0&&(R=p+n.verticalPadding-n.rowHeight[I]);var W;n.width-O>=E+n.horizontalPadding?W=(n.height+R)/(O+E+n.horizontalPadding):W=(n.height+R)/n.width,R=p+n.verticalPadding;var x;return n.width<E?x=(n.height+R)/E:x=(n.height+R)/n.width,x<1&&(x=1/x),W<1&&(W=1/W),W<x},M.prototype.shiftToLastRow=function(n){var E=this.getLongestRowIndex(n),p=n.rowWidth.length-1,m=n.rows[E],y=m[m.length-1],I=y.width+n.horizontalPadding;if(n.width-n.rowWidth[p]>I&&E!=p){m.splice(-1,1),n.rows[p].push(y),n.rowWidth[E]=n.rowWidth[E]-I,n.rowWidth[p]=n.rowWidth[p]+I,n.width=n.rowWidth[instance.getLongestRowIndex(n)];for(var O=Number.MIN_VALUE,R=0;R<m.length;R++)m[R].height>O&&(O=m[R].height);E>0&&(O+=n.verticalPadding);var W=n.rowHeight[E]+n.rowHeight[p];n.rowHeight[E]=O,n.rowHeight[p]<y.height+n.verticalPadding&&(n.rowHeight[p]=y.height+n.verticalPadding);var x=n.rowHeight[E]+n.rowHeight[p];n.height+=x-W,this.shiftToLastRow(n)}},M.prototype.tilingPreLayout=function(){o.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},M.prototype.tilingPostLayout=function(){o.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},M.prototype.reduceTrees=function(){for(var n=[],E=!0,p;E;){var m=this.graphManager.getAllNodes(),y=[];E=!1;for(var I=0;I<m.length;I++)if(p=m[I],p.getEdges().length==1&&!p.getEdges()[0].isInterGraph&&p.getChild()==null){if(o.PURE_INCREMENTAL){var O=p.getEdges()[0].getOtherEnd(p),R=new C(p.getCenterX()-O.getCenterX(),p.getCenterY()-O.getCenterY());y.push([p,p.getEdges()[0],p.getOwner(),R])}else y.push([p,p.getEdges()[0],p.getOwner()]);E=!0}if(E==!0){for(var W=[],x=0;x<y.length;x++)y[x][0].getEdges().length==1&&(W.push(y[x]),y[x][0].getOwner().remove(y[x][0]));n.push(W),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=n},M.prototype.growTree=function(n){for(var E=n.length,p=n[E-1],m,y=0;y<p.length;y++)m=p[y],this.findPlaceforPrunedNode(m),m[2].add(m[0]),m[2].add(m[1],m[1].source,m[1].target);n.splice(n.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},M.prototype.findPlaceforPrunedNode=function(n){var E,p,m=n[0];if(m==n[1].source?p=n[1].target:p=n[1].source,o.PURE_INCREMENTAL)m.setCenter(p.getCenterX()+n[3].getWidth(),p.getCenterY()+n[3].getHeight());else{var y=p.startX,I=p.finishX,O=p.startY,R=p.finishY,W=0,x=0,Q=0,z=0,X=[W,Q,x,z];if(O>0)for(var rt=y;rt<=I;rt++)X[0]+=this.grid[rt][O-1].length+this.grid[rt][O].length-1;if(I<this.grid.length-1)for(var rt=O;rt<=R;rt++)X[1]+=this.grid[I+1][rt].length+this.grid[I][rt].length-1;if(R<this.grid[0].length-1)for(var rt=y;rt<=I;rt++)X[2]+=this.grid[rt][R+1].length+this.grid[rt][R].length-1;if(y>0)for(var rt=O;rt<=R;rt++)X[3]+=this.grid[y-1][rt].length+this.grid[y][rt].length-1;for(var $=w.MAX_VALUE,D,H,k=0;k<X.length;k++)X[k]<$?($=X[k],D=1,H=k):X[k]==$&&D++;if(D==3&&$==0)X[0]==0&&X[1]==0&&X[2]==0?E=1:X[0]==0&&X[1]==0&&X[3]==0?E=0:X[0]==0&&X[2]==0&&X[3]==0?E=3:X[1]==0&&X[2]==0&&X[3]==0&&(E=2);else if(D==2&&$==0){var tt=Math.floor(Math.random()*2);X[0]==0&&X[1]==0?tt==0?E=0:E=1:X[0]==0&&X[2]==0?tt==0?E=0:E=2:X[0]==0&&X[3]==0?tt==0?E=0:E=3:X[1]==0&&X[2]==0?tt==0?E=1:E=2:X[1]==0&&X[3]==0?tt==0?E=1:E=3:tt==0?E=2:E=3}else if(D==4&&$==0){var tt=Math.floor(Math.random()*4);E=tt}else E=H;E==0?m.setCenter(p.getCenterX(),p.getCenterY()-p.getHeight()/2-l.DEFAULT_EDGE_LENGTH-m.getHeight()/2):E==1?m.setCenter(p.getCenterX()+p.getWidth()/2+l.DEFAULT_EDGE_LENGTH+m.getWidth()/2,p.getCenterY()):E==2?m.setCenter(p.getCenterX(),p.getCenterY()+p.getHeight()/2+l.DEFAULT_EDGE_LENGTH+m.getHeight()/2):m.setCenter(p.getCenterX()-p.getWidth()/2-l.DEFAULT_EDGE_LENGTH-m.getWidth()/2,p.getCenterY())}},i.exports=M}),991:((i,r,a)=>{var f=a(551).FDLayoutNode,e=a(551).IMath;function u(s,o,c,l){f.call(this,s,o,c,l)}u.prototype=Object.create(f.prototype);for(var t in f)u[t]=f[t];u.prototype.calculateDisplacement=function(){var s=this.graphManager.getLayout();this.getChild()!=null&&this.fixedNodeWeight?(this.displacementX+=s.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=s.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=s.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=s.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>s.coolingFactor*s.maxNodeDisplacement&&(this.displacementX=s.coolingFactor*s.maxNodeDisplacement*e.sign(this.displacementX)),Math.abs(this.displacementY)>s.coolingFactor*s.maxNodeDisplacement&&(this.displacementY=s.coolingFactor*s.maxNodeDisplacement*e.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},u.prototype.propogateDisplacementToChildren=function(s,o){for(var c=this.getChild().getNodes(),l,T=0;T<c.length;T++)l=c[T],l.getChild()==null?(l.displacementX+=s,l.displacementY+=o):l.propogateDisplacementToChildren(s,o)},u.prototype.move=function(){var s=this.graphManager.getLayout();(this.child==null||this.child.getNodes().length==0)&&(this.moveBy(this.displacementX,this.displacementY),s.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY)),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},u.prototype.setPred1=function(s){this.pred1=s},u.prototype.getPred1=function(){return pred1},u.prototype.getPred2=function(){return pred2},u.prototype.setNext=function(s){this.next=s},u.prototype.getNext=function(){return next},u.prototype.setProcessed=function(s){this.processed=s},u.prototype.isProcessed=function(){return processed},i.exports=u}),902:((i,r,a)=>{function f(c){if(Array.isArray(c)){for(var l=0,T=Array(c.length);l<c.length;l++)T[l]=c[l];return T}else return Array.from(c)}var e=a(806),u=a(551).LinkedList,t=a(551).Matrix,s=a(551).SVD;function o(){}o.handleConstraints=function(c){var l={};l.fixedNodeConstraint=c.constraints.fixedNodeConstraint,l.alignmentConstraint=c.constraints.alignmentConstraint,l.relativePlacementConstraint=c.constraints.relativePlacementConstraint;for(var T=new Map,g=new Map,d=[],C=[],S=c.getAllNodes(),w=0,P=0;P<S.length;P++){var B=S[P];B.getChild()==null&&(g.set(B.id,w++),d.push(B.getCenterX()),C.push(B.getCenterY()),T.set(B.id,B))}l.relativePlacementConstraint&&l.relativePlacementConstraint.forEach(function(F){!F.gap&&F.gap!=0&&(F.left?F.gap=e.DEFAULT_EDGE_LENGTH+T.get(F.left).getWidth()/2+T.get(F.right).getWidth()/2:F.gap=e.DEFAULT_EDGE_LENGTH+T.get(F.top).getHeight()/2+T.get(F.bottom).getHeight()/2)});var U=function(Y,Z){return{x:Y.x-Z.x,y:Y.y-Z.y}},V=function(Y){var Z=0,K=0;return Y.forEach(function(q){Z+=d[g.get(q)],K+=C[g.get(q)]}),{x:Z/Y.size,y:K/Y.size}},M=function(Y,Z,K,q,at){function ct(lt,ot){var Lt=new Set(lt),ft=!0,st=!1,Xt=void 0;try{for(var Tt=ot[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;Lt.add(Bt)}}catch(bt){st=!0,Xt=bt}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}return Lt}var nt=new Map;Y.forEach(function(lt,ot){nt.set(ot,0)}),Y.forEach(function(lt,ot){lt.forEach(function(Lt){nt.set(Lt.id,nt.get(Lt.id)+1)})});var et=new Map,j=new Map,dt=new u;nt.forEach(function(lt,ot){lt==0?(dt.push(ot),K||(Z=="horizontal"?et.set(ot,g.has(ot)?d[g.get(ot)]:q.get(ot)):et.set(ot,g.has(ot)?C[g.get(ot)]:q.get(ot)))):et.set(ot,Number.NEGATIVE_INFINITY),K&&j.set(ot,new Set([ot]))}),K&&at.forEach(function(lt){var ot=[];if(lt.forEach(function(st){K.has(st)&&ot.push(st)}),ot.length>0){var Lt=0;ot.forEach(function(st){Z=="horizontal"?(et.set(st,g.has(st)?d[g.get(st)]:q.get(st)),Lt+=et.get(st)):(et.set(st,g.has(st)?C[g.get(st)]:q.get(st)),Lt+=et.get(st))}),Lt=Lt/ot.length,lt.forEach(function(st){K.has(st)||et.set(st,Lt)})}else{var ft=0;lt.forEach(function(st){Z=="horizontal"?ft+=g.has(st)?d[g.get(st)]:q.get(st):ft+=g.has(st)?C[g.get(st)]:q.get(st)}),ft=ft/lt.length,lt.forEach(function(st){et.set(st,ft)})}});for(var At=function(){var ot=dt.shift(),Lt=Y.get(ot);Lt.forEach(function(ft){if(et.get(ft.id)<et.get(ot)+ft.gap)if(K&&K.has(ft.id)){var st=void 0;if(Z=="horizontal"?st=g.has(ft.id)?d[g.get(ft.id)]:q.get(ft.id):st=g.has(ft.id)?C[g.get(ft.id)]:q.get(ft.id),et.set(ft.id,st),st<et.get(ot)+ft.gap){var Xt=et.get(ot)+ft.gap-st;j.get(ot).forEach(function(Tt){et.set(Tt,et.get(Tt)-Xt)})}}else et.set(ft.id,et.get(ot)+ft.gap);nt.set(ft.id,nt.get(ft.id)-1),nt.get(ft.id)==0&&dt.push(ft.id),K&&j.set(ft.id,ct(j.get(ot),j.get(ft.id)))})};dt.length!=0;)At();if(K){var pt=new Set;Y.forEach(function(lt,ot){lt.length==0&&pt.add(ot)});var xt=[];j.forEach(function(lt,ot){if(pt.has(ot)){var Lt=!1,ft=!0,st=!1,Xt=void 0;try{for(var Tt=lt[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;K.has(Bt)&&(Lt=!0)}}catch(St){st=!0,Xt=St}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}if(!Lt){var bt=!1,zt=void 0;xt.forEach(function(St,kt){St.has([].concat(f(lt))[0])&&(bt=!0,zt=kt)}),bt?lt.forEach(function(St){xt[zt].add(St)}):xt.push(new Set(lt))}}}),xt.forEach(function(lt,ot){var Lt=Number.POSITIVE_INFINITY,ft=Number.POSITIVE_INFINITY,st=Number.NEGATIVE_INFINITY,Xt=Number.NEGATIVE_INFINITY,Tt=!0,Ct=!1,Bt=void 0;try{for(var bt=lt[Symbol.iterator](),zt;!(Tt=(zt=bt.next()).done);Tt=!0){var St=zt.value,kt=void 0;Z=="horizontal"?kt=g.has(St)?d[g.get(St)]:q.get(St):kt=g.has(St)?C[g.get(St)]:q.get(St);var Kt=et.get(St);kt<Lt&&(Lt=kt),kt>st&&(st=kt),Kt<ft&&(ft=Kt),Kt>Xt&&(Xt=Kt)}}catch(ee){Ct=!0,Bt=ee}finally{try{!Tt&&bt.return&&bt.return()}finally{if(Ct)throw Bt}}var fe=(Lt+st)/2-(ft+Xt)/2,Qt=!0,jt=!1,_t=void 0;try{for(var Jt=lt[Symbol.iterator](),ne;!(Qt=(ne=Jt.next()).done);Qt=!0){var te=ne.value;et.set(te,et.get(te)+fe)}}catch(ee){jt=!0,_t=ee}finally{try{!Qt&&Jt.return&&Jt.return()}finally{if(jt)throw _t}}})}return et},_=function(Y){var Z=0,K=0,q=0,at=0;if(Y.forEach(function(j){j.left?d[g.get(j.left)]-d[g.get(j.right)]>=0?Z++:K++:C[g.get(j.top)]-C[g.get(j.bottom)]>=0?q++:at++}),Z>K&&q>at)for(var ct=0;ct<g.size;ct++)d[ct]=-1*d[ct],C[ct]=-1*C[ct];else if(Z>K)for(var nt=0;nt<g.size;nt++)d[nt]=-1*d[nt];else if(q>at)for(var et=0;et<g.size;et++)C[et]=-1*C[et]},n=function(Y){var Z=[],K=new u,q=new Set,at=0;return Y.forEach(function(ct,nt){if(!q.has(nt)){Z[at]=[];var et=nt;for(K.push(et),q.add(et),Z[at].push(et);K.length!=0;){et=K.shift();var j=Y.get(et);j.forEach(function(dt){q.has(dt.id)||(K.push(dt.id),q.add(dt.id),Z[at].push(dt.id))})}at++}}),Z},E=function(Y){var Z=new Map;return Y.forEach(function(K,q){Z.set(q,[])}),Y.forEach(function(K,q){K.forEach(function(at){Z.get(q).push(at),Z.get(at.id).push({id:q,gap:at.gap,direction:at.direction})})}),Z},p=function(Y){var Z=new Map;return Y.forEach(function(K,q){Z.set(q,[])}),Y.forEach(function(K,q){K.forEach(function(at){Z.get(at.id).push({id:q,gap:at.gap,direction:at.direction})})}),Z},m=[],y=[],I=!1,O=!1,R=new Set,W=new Map,x=new Map,Q=[];if(l.fixedNodeConstraint&&l.fixedNodeConstraint.forEach(function(F){R.add(F.nodeId)}),l.relativePlacementConstraint&&(l.relativePlacementConstraint.forEach(function(F){F.left?(W.has(F.left)?W.get(F.left).push({id:F.right,gap:F.gap,direction:"horizontal"}):W.set(F.left,[{id:F.right,gap:F.gap,direction:"horizontal"}]),W.has(F.right)||W.set(F.right,[])):(W.has(F.top)?W.get(F.top).push({id:F.bottom,gap:F.gap,direction:"vertical"}):W.set(F.top,[{id:F.bottom,gap:F.gap,direction:"vertical"}]),W.has(F.bottom)||W.set(F.bottom,[]))}),x=E(W),Q=n(x)),e.TRANSFORM_ON_CONSTRAINT_HANDLING){if(l.fixedNodeConstraint&&l.fixedNodeConstraint.length>1)l.fixedNodeConstraint.forEach(function(F,Y){m[Y]=[F.position.x,F.position.y],y[Y]=[d[g.get(F.nodeId)],C[g.get(F.nodeId)]]}),I=!0;else if(l.alignmentConstraint)(function(){var F=0;if(l.alignmentConstraint.vertical){for(var Y=l.alignmentConstraint.vertical,Z=function(et){var j=new Set;Y[et].forEach(function(pt){j.add(pt)});var dt=new Set([].concat(f(j)).filter(function(pt){return R.has(pt)})),At=void 0;dt.size>0?At=d[g.get(dt.values().next().value)]:At=V(j).x,Y[et].forEach(function(pt){m[F]=[At,C[g.get(pt)]],y[F]=[d[g.get(pt)],C[g.get(pt)]],F++})},K=0;K<Y.length;K++)Z(K);I=!0}if(l.alignmentConstraint.horizontal){for(var q=l.alignmentConstraint.horizontal,at=function(et){var j=new Set;q[et].forEach(function(pt){j.add(pt)});var dt=new Set([].concat(f(j)).filter(function(pt){return R.has(pt)})),At=void 0;dt.size>0?At=d[g.get(dt.values().next().value)]:At=V(j).y,q[et].forEach(function(pt){m[F]=[d[g.get(pt)],At],y[F]=[d[g.get(pt)],C[g.get(pt)]],F++})},ct=0;ct<q.length;ct++)at(ct);I=!0}l.relativePlacementConstraint&&(O=!0)})();else if(l.relativePlacementConstraint){for(var z=0,X=0,rt=0;rt<Q.length;rt++)Q[rt].length>z&&(z=Q[rt].length,X=rt);if(z<x.size/2)_(l.relativePlacementConstraint),I=!1,O=!1;else{var $=new Map,D=new Map,H=[];Q[X].forEach(function(F){W.get(F).forEach(function(Y){Y.direction=="horizontal"?($.has(F)?$.get(F).push(Y):$.set(F,[Y]),$.has(Y.id)||$.set(Y.id,[]),H.push({left:F,right:Y.id})):(D.has(F)?D.get(F).push(Y):D.set(F,[Y]),D.has(Y.id)||D.set(Y.id,[]),H.push({top:F,bottom:Y.id}))})}),_(H),O=!1;var k=M($,"horizontal"),tt=M(D,"vertical");Q[X].forEach(function(F,Y){y[Y]=[d[g.get(F)],C[g.get(F)]],m[Y]=[],k.has(F)?m[Y][0]=k.get(F):m[Y][0]=d[g.get(F)],tt.has(F)?m[Y][1]=tt.get(F):m[Y][1]=C[g.get(F)]}),I=!0}}if(I){for(var ht=void 0,J=t.transpose(m),It=t.transpose(y),Nt=0;Nt<J.length;Nt++)J[Nt]=t.multGamma(J[Nt]),It[Nt]=t.multGamma(It[Nt]);var vt=t.multMat(J,t.transpose(It)),it=s.svd(vt);ht=t.multMat(it.V,t.transpose(it.U));for(var ut=0;ut<g.size;ut++){var Et=[d[ut],C[ut]],wt=[ht[0][0],ht[1][0]],Ot=[ht[0][1],ht[1][1]];d[ut]=t.dotProduct(Et,wt),C[ut]=t.dotProduct(Et,Ot)}O&&_(l.relativePlacementConstraint)}}if(e.ENFORCE_CONSTRAINTS){if(l.fixedNodeConstraint&&l.fixedNodeConstraint.length>0){var mt={x:0,y:0};l.fixedNodeConstraint.forEach(function(F,Y){var Z={x:d[g.get(F.nodeId)],y:C[g.get(F.nodeId)]},K=F.position,q=U(K,Z);mt.x+=q.x,mt.y+=q.y}),mt.x/=l.fixedNodeConstraint.length,mt.y/=l.fixedNodeConstraint.length,d.forEach(function(F,Y){d[Y]+=mt.x}),C.forEach(function(F,Y){C[Y]+=mt.y}),l.fixedNodeConstraint.forEach(function(F){d[g.get(F.nodeId)]=F.position.x,C[g.get(F.nodeId)]=F.position.y})}if(l.alignmentConstraint){if(l.alignmentConstraint.vertical)for(var Dt=l.alignmentConstraint.vertical,Rt=function(Y){var Z=new Set;Dt[Y].forEach(function(at){Z.add(at)});var K=new Set([].concat(f(Z)).filter(function(at){return R.has(at)})),q=void 0;K.size>0?q=d[g.get(K.values().next().value)]:q=V(Z).x,Z.forEach(function(at){R.has(at)||(d[g.get(at)]=q)})},Ht=0;Ht<Dt.length;Ht++)Rt(Ht);if(l.alignmentConstraint.horizontal)for(var Ut=l.alignmentConstraint.horizontal,Pt=function(Y){var Z=new Set;Ut[Y].forEach(function(at){Z.add(at)});var K=new Set([].concat(f(Z)).filter(function(at){return R.has(at)})),q=void 0;K.size>0?q=C[g.get(K.values().next().value)]:q=V(Z).y,Z.forEach(function(at){R.has(at)||(C[g.get(at)]=q)})},Ft=0;Ft<Ut.length;Ft++)Pt(Ft)}l.relativePlacementConstraint&&(function(){var F=new Map,Y=new Map,Z=new Map,K=new Map,q=new Map,at=new Map,ct=new Set,nt=new Set;if(R.forEach(function(Gt){ct.add(Gt),nt.add(Gt)}),l.alignmentConstraint){if(l.alignmentConstraint.vertical)for(var et=l.alignmentConstraint.vertical,j=function(yt){Z.set("dummy"+yt,[]),et[yt].forEach(function(Mt){F.set(Mt,"dummy"+yt),Z.get("dummy"+yt).push(Mt),R.has(Mt)&&ct.add("dummy"+yt)}),q.set("dummy"+yt,d[g.get(et[yt][0])])},dt=0;dt<et.length;dt++)j(dt);if(l.alignmentConstraint.horizontal)for(var At=l.alignmentConstraint.horizontal,pt=function(yt){K.set("dummy"+yt,[]),At[yt].forEach(function(Mt){Y.set(Mt,"dummy"+yt),K.get("dummy"+yt).push(Mt),R.has(Mt)&&nt.add("dummy"+yt)}),at.set("dummy"+yt,C[g.get(At[yt][0])])},xt=0;xt<At.length;xt++)pt(xt)}var lt=new Map,ot=new Map,Lt=function(yt){W.get(yt).forEach(function(Mt){var Zt=void 0,$t=void 0;Mt.direction=="horizontal"?(Zt=F.get(yt)?F.get(yt):yt,F.get(Mt.id)?$t={id:F.get(Mt.id),gap:Mt.gap,direction:Mt.direction}:$t=Mt,lt.has(Zt)?lt.get(Zt).push($t):lt.set(Zt,[$t]),lt.has($t.id)||lt.set($t.id,[])):(Zt=Y.get(yt)?Y.get(yt):yt,Y.get(Mt.id)?$t={id:Y.get(Mt.id),gap:Mt.gap,direction:Mt.direction}:$t=Mt,ot.has(Zt)?ot.get(Zt).push($t):ot.set(Zt,[$t]),ot.has($t.id)||ot.set($t.id,[]))})},ft=!0,st=!1,Xt=void 0;try{for(var Tt=W.keys()[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;Lt(Bt)}}catch(Gt){st=!0,Xt=Gt}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}var bt=E(lt),zt=E(ot),St=n(bt),kt=n(zt),Kt=p(lt),fe=p(ot),Qt=[],jt=[];St.forEach(function(Gt,yt){Qt[yt]=[],Gt.forEach(function(Mt){Kt.get(Mt).length==0&&Qt[yt].push(Mt)})}),kt.forEach(function(Gt,yt){jt[yt]=[],Gt.forEach(function(Mt){fe.get(Mt).length==0&&jt[yt].push(Mt)})});var _t=M(lt,"horizontal",ct,q,Qt),Jt=M(ot,"vertical",nt,at,jt),ne=function(yt){Z.get(yt)?Z.get(yt).forEach(function(Mt){d[g.get(Mt)]=_t.get(yt)}):d[g.get(yt)]=_t.get(yt)},te=!0,ee=!1,Ne=void 0;try{for(var ce=_t.keys()[Symbol.iterator](),Le;!(te=(Le=ce.next()).done);te=!0){var ge=Le.value;ne(ge)}}catch(Gt){ee=!0,Ne=Gt}finally{try{!te&&ce.return&&ce.return()}finally{if(ee)throw Ne}}var $e=function(yt){K.get(yt)?K.get(yt).forEach(function(Mt){C[g.get(Mt)]=Jt.get(yt)}):C[g.get(yt)]=Jt.get(yt)},ue=!0,Ce=!1,we=void 0;try{for(var de=Jt.keys()[Symbol.iterator](),Ae;!(ue=(Ae=de.next()).done);ue=!0){var ge=Ae.value;$e(ge)}}catch(Gt){Ce=!0,we=Gt}finally{try{!ue&&de.return&&de.return()}finally{if(Ce)throw we}}})()}for(var Yt=0;Yt<S.length;Yt++){var Vt=S[Yt];Vt.getChild()==null&&Vt.setCenter(d[g.get(Vt.id)],C[g.get(Vt.id)])}},i.exports=o}),551:(i=>{i.exports=A})},N={};function v(i){var r=N[i];if(r!==void 0)return r.exports;var a=N[i]={exports:{}};return G[i](a,a.exports,v),a.exports}var h=v(45);return h})()})})(he)),he.exports}var pr=se.exports,De;function yr(){return De||(De=1,(function(L,b){(function(G,N){L.exports=N(vr())})(pr,function(A){return(()=>{var G={658:(i=>{i.exports=Object.assign!=null?Object.assign.bind(Object):function(r){for(var a=arguments.length,f=Array(a>1?a-1:0),e=1;e<a;e++)f[e-1]=arguments[e];return f.forEach(function(u){Object.keys(u).forEach(function(t){return r[t]=u[t]})}),r}}),548:((i,r,a)=>{var f=(function(){function t(s,o){var c=[],l=!0,T=!1,g=void 0;try{for(var d=s[Symbol.iterator](),C;!(l=(C=d.next()).done)&&(c.push(C.value),!(o&&c.length===o));l=!0);}catch(S){T=!0,g=S}finally{try{!l&&d.return&&d.return()}finally{if(T)throw g}}return c}return function(s,o){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return t(s,o);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})(),e=a(140).layoutBase.LinkedList,u={};u.getTopMostNodes=function(t){for(var s={},o=0;o<t.length;o++)s[t[o].id()]=!0;var c=t.filter(function(l,T){typeof l=="number"&&(l=T);for(var g=l.parent()[0];g!=null;){if(s[g.id()])return!1;g=g.parent()[0]}return!0});return c},u.connectComponents=function(t,s,o,c){var l=new e,T=new Set,g=[],d=void 0,C=void 0,S=void 0,w=!1,P=1,B=[],U=[],V=function(){var _=t.collection();U.push(_);var n=o[0],E=t.collection();E.merge(n).merge(n.descendants().intersection(s)),g.push(n),E.forEach(function(y){l.push(y),T.add(y),_.merge(y)});for(var p=function(){n=l.shift();var I=t.collection();n.neighborhood().nodes().forEach(function(x){s.intersection(n.edgesWith(x)).length>0&&I.merge(x)});for(var O=0;O<I.length;O++){var R=I[O];if(d=o.intersection(R.union(R.ancestors())),d!=null&&!T.has(d[0])){var W=d.union(d.descendants());W.forEach(function(x){l.push(x),T.add(x),_.merge(x),o.has(x)&&g.push(x)})}}};l.length!=0;)p();if(_.forEach(function(y){s.intersection(y.connectedEdges()).forEach(function(I){_.has(I.source())&&_.has(I.target())&&_.merge(I)})}),g.length==o.length&&(w=!0),!w||w&&P>1){C=g[0],S=C.connectedEdges().length,g.forEach(function(y){y.connectedEdges().length<S&&(S=y.connectedEdges().length,C=y)}),B.push(C.id());var m=t.collection();m.merge(g[0]),g.forEach(function(y){m.merge(y)}),g=[],o=o.difference(m),P++}};do V();while(!w);return c&&B.length>0&&c.set("dummy"+(c.size+1),B),U},u.relocateComponent=function(t,s,o){if(!o.fixedNodeConstraint){var c=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,T=Number.POSITIVE_INFINITY,g=Number.NEGATIVE_INFINITY;if(o.quality=="draft"){var d=!0,C=!1,S=void 0;try{for(var w=s.nodeIndexes[Symbol.iterator](),P;!(d=(P=w.next()).done);d=!0){var B=P.value,U=f(B,2),V=U[0],M=U[1],_=o.cy.getElementById(V);if(_){var n=_.boundingBox(),E=s.xCoords[M]-n.w/2,p=s.xCoords[M]+n.w/2,m=s.yCoords[M]-n.h/2,y=s.yCoords[M]+n.h/2;E<c&&(c=E),p>l&&(l=p),m<T&&(T=m),y>g&&(g=y)}}}catch(x){C=!0,S=x}finally{try{!d&&w.return&&w.return()}finally{if(C)throw S}}var I=t.x-(l+c)/2,O=t.y-(g+T)/2;s.xCoords=s.xCoords.map(function(x){return x+I}),s.yCoords=s.yCoords.map(function(x){return x+O})}else{Object.keys(s).forEach(function(x){var Q=s[x],z=Q.getRect().x,X=Q.getRect().x+Q.getRect().width,rt=Q.getRect().y,$=Q.getRect().y+Q.getRect().height;z<c&&(c=z),X>l&&(l=X),rt<T&&(T=rt),$>g&&(g=$)});var R=t.x-(l+c)/2,W=t.y-(g+T)/2;Object.keys(s).forEach(function(x){var Q=s[x];Q.setCenter(Q.getCenterX()+R,Q.getCenterY()+W)})}}},u.calcBoundingBox=function(t,s,o,c){for(var l=Number.MAX_SAFE_INTEGER,T=Number.MIN_SAFE_INTEGER,g=Number.MAX_SAFE_INTEGER,d=Number.MIN_SAFE_INTEGER,C=void 0,S=void 0,w=void 0,P=void 0,B=t.descendants().not(":parent"),U=B.length,V=0;V<U;V++){var M=B[V];C=s[c.get(M.id())]-M.width()/2,S=s[c.get(M.id())]+M.width()/2,w=o[c.get(M.id())]-M.height()/2,P=o[c.get(M.id())]+M.height()/2,l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var _={};return _.topLeftX=l,_.topLeftY=g,_.width=T-l,_.height=d-g,_},u.calcParentsWithoutChildren=function(t,s){var o=t.collection();return s.nodes(":parent").forEach(function(c){var l=!1;c.children().forEach(function(T){T.css("display")!="none"&&(l=!0)}),l||o.merge(c)}),o},i.exports=u}),816:((i,r,a)=>{var f=a(548),e=a(140).CoSELayout,u=a(140).CoSENode,t=a(140).layoutBase.PointD,s=a(140).layoutBase.DimensionD,o=a(140).layoutBase.LayoutConstants,c=a(140).layoutBase.FDLayoutConstants,l=a(140).CoSEConstants,T=function(d,C){var S=d.cy,w=d.eles,P=w.nodes(),B=w.edges(),U=void 0,V=void 0,M=void 0,_={};d.randomize&&(U=C.nodeIndexes,V=C.xCoords,M=C.yCoords);var n=function(x){return typeof x=="function"},E=function(x,Q){return n(x)?x(Q):x},p=f.calcParentsWithoutChildren(S,w),m=function W(x,Q,z,X){for(var rt=Q.length,$=0;$<rt;$++){var D=Q[$],H=null;D.intersection(p).length==0&&(H=D.children());var k=void 0,tt=D.layoutDimensions({nodeDimensionsIncludeLabels:X.nodeDimensionsIncludeLabels});if(D.outerWidth()!=null&&D.outerHeight()!=null)if(X.randomize)if(!D.isParent())k=x.add(new u(z.graphManager,new t(V[U.get(D.id())]-tt.w/2,M[U.get(D.id())]-tt.h/2),new s(parseFloat(tt.w),parseFloat(tt.h))));else{var ht=f.calcBoundingBox(D,V,M,U);D.intersection(p).length==0?k=x.add(new u(z.graphManager,new t(ht.topLeftX,ht.topLeftY),new s(ht.width,ht.height))):k=x.add(new u(z.graphManager,new t(ht.topLeftX,ht.topLeftY),new s(parseFloat(tt.w),parseFloat(tt.h))))}else k=x.add(new u(z.graphManager,new t(D.position("x")-tt.w/2,D.position("y")-tt.h/2),new s(parseFloat(tt.w),parseFloat(tt.h))));else k=x.add(new u(this.graphManager));if(k.id=D.data("id"),k.nodeRepulsion=E(X.nodeRepulsion,D),k.paddingLeft=parseInt(D.css("padding")),k.paddingTop=parseInt(D.css("padding")),k.paddingRight=parseInt(D.css("padding")),k.paddingBottom=parseInt(D.css("padding")),X.nodeDimensionsIncludeLabels&&(k.labelWidth=D.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).w,k.labelHeight=D.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).h,k.labelPosVertical=D.css("text-valign"),k.labelPosHorizontal=D.css("text-halign")),_[D.data("id")]=k,isNaN(k.rect.x)&&(k.rect.x=0),isNaN(k.rect.y)&&(k.rect.y=0),H!=null&&H.length>0){var J=void 0;J=z.getGraphManager().add(z.newGraph(),k),W(J,H,z,X)}}},y=function(x,Q,z){for(var X=0,rt=0,$=0;$<z.length;$++){var D=z[$],H=_[D.data("source")],k=_[D.data("target")];if(H&&k&&H!==k&&H.getEdgesBetween(k).length==0){var tt=Q.add(x.newEdge(),H,k);tt.id=D.id(),tt.idealLength=E(d.idealEdgeLength,D),tt.edgeElasticity=E(d.edgeElasticity,D),X+=tt.idealLength,rt++}}d.idealEdgeLength!=null&&(rt>0?l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=X/rt:n(d.idealEdgeLength)?l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=50:l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=d.idealEdgeLength,l.MIN_REPULSION_DIST=c.MIN_REPULSION_DIST=c.DEFAULT_EDGE_LENGTH/10,l.DEFAULT_RADIAL_SEPARATION=c.DEFAULT_EDGE_LENGTH)},I=function(x,Q){Q.fixedNodeConstraint&&(x.constraints.fixedNodeConstraint=Q.fixedNodeConstraint),Q.alignmentConstraint&&(x.constraints.alignmentConstraint=Q.alignmentConstraint),Q.relativePlacementConstraint&&(x.constraints.relativePlacementConstraint=Q.relativePlacementConstraint)};d.nestingFactor!=null&&(l.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=c.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=d.nestingFactor),d.gravity!=null&&(l.DEFAULT_GRAVITY_STRENGTH=c.DEFAULT_GRAVITY_STRENGTH=d.gravity),d.numIter!=null&&(l.MAX_ITERATIONS=c.MAX_ITERATIONS=d.numIter),d.gravityRange!=null&&(l.DEFAULT_GRAVITY_RANGE_FACTOR=c.DEFAULT_GRAVITY_RANGE_FACTOR=d.gravityRange),d.gravityCompound!=null&&(l.DEFAULT_COMPOUND_GRAVITY_STRENGTH=c.DEFAULT_COMPOUND_GRAVITY_STRENGTH=d.gravityCompound),d.gravityRangeCompound!=null&&(l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=c.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=d.gravityRangeCompound),d.initialEnergyOnIncremental!=null&&(l.DEFAULT_COOLING_FACTOR_INCREMENTAL=c.DEFAULT_COOLING_FACTOR_INCREMENTAL=d.initialEnergyOnIncremental),d.tilingCompareBy!=null&&(l.TILING_COMPARE_BY=d.tilingCompareBy),d.quality=="proof"?o.QUALITY=2:o.QUALITY=0,l.NODE_DIMENSIONS_INCLUDE_LABELS=c.NODE_DIMENSIONS_INCLUDE_LABELS=o.NODE_DIMENSIONS_INCLUDE_LABELS=d.nodeDimensionsIncludeLabels,l.DEFAULT_INCREMENTAL=c.DEFAULT_INCREMENTAL=o.DEFAULT_INCREMENTAL=!d.randomize,l.ANIMATE=c.ANIMATE=o.ANIMATE=d.animate,l.TILE=d.tile,l.TILING_PADDING_VERTICAL=typeof d.tilingPaddingVertical=="function"?d.tilingPaddingVertical.call():d.tilingPaddingVertical,l.TILING_PADDING_HORIZONTAL=typeof d.tilingPaddingHorizontal=="function"?d.tilingPaddingHorizontal.call():d.tilingPaddingHorizontal,l.DEFAULT_INCREMENTAL=c.DEFAULT_INCREMENTAL=o.DEFAULT_INCREMENTAL=!0,l.PURE_INCREMENTAL=!d.randomize,o.DEFAULT_UNIFORM_LEAF_NODE_SIZES=d.uniformNodeDimensions,d.step=="transformed"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,l.ENFORCE_CONSTRAINTS=!1,l.APPLY_LAYOUT=!1),d.step=="enforced"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!0,l.APPLY_LAYOUT=!1),d.step=="cose"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!1,l.APPLY_LAYOUT=!0),d.step=="all"&&(d.randomize?l.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!0,l.APPLY_LAYOUT=!0),d.fixedNodeConstraint||d.alignmentConstraint||d.relativePlacementConstraint?l.TREE_REDUCTION_ON_INCREMENTAL=!1:l.TREE_REDUCTION_ON_INCREMENTAL=!0;var O=new e,R=O.newGraphManager();return m(R.addRoot(),f.getTopMostNodes(P),O,d),y(O,R,B),I(O,d),O.runLayout(),_};i.exports={coseLayout:T}}),212:((i,r,a)=>{var f=(function(){function d(C,S){for(var w=0;w<S.length;w++){var P=S[w];P.enumerable=P.enumerable||!1,P.configurable=!0,"value"in P&&(P.writable=!0),Object.defineProperty(C,P.key,P)}}return function(C,S,w){return S&&d(C.prototype,S),w&&d(C,w),C}})();function e(d,C){if(!(d instanceof C))throw new TypeError("Cannot call a class as a function")}var u=a(658),t=a(548),s=a(657),o=s.spectralLayout,c=a(816),l=c.coseLayout,T=Object.freeze({quality:"default",randomize:!0,animate:!0,animationDuration:1e3,animationEasing:void 0,fit:!0,padding:30,nodeDimensionsIncludeLabels:!1,uniformNodeDimensions:!1,packComponents:!0,step:"all",samplingType:!0,sampleSize:25,nodeSeparation:75,piTol:1e-7,nodeRepulsion:function(C){return 4500},idealEdgeLength:function(C){return 50},edgeElasticity:function(C){return .45},nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,tilingCompareBy:void 0,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.3,fixedNodeConstraint:void 0,alignmentConstraint:void 0,relativePlacementConstraint:void 0,ready:function(){},stop:function(){}}),g=(function(){function d(C){e(this,d),this.options=u({},T,C)}return f(d,[{key:"run",value:function(){var S=this,w=this.options,P=w.cy,B=w.eles,U=[],V=[],M=void 0,_=[];w.fixedNodeConstraint&&(!Array.isArray(w.fixedNodeConstraint)||w.fixedNodeConstraint.length==0)&&(w.fixedNodeConstraint=void 0),w.alignmentConstraint&&(w.alignmentConstraint.vertical&&(!Array.isArray(w.alignmentConstraint.vertical)||w.alignmentConstraint.vertical.length==0)&&(w.alignmentConstraint.vertical=void 0),w.alignmentConstraint.horizontal&&(!Array.isArray(w.alignmentConstraint.horizontal)||w.alignmentConstraint.horizontal.length==0)&&(w.alignmentConstraint.horizontal=void 0)),w.relativePlacementConstraint&&(!Array.isArray(w.relativePlacementConstraint)||w.relativePlacementConstraint.length==0)&&(w.relativePlacementConstraint=void 0);var n=w.fixedNodeConstraint||w.alignmentConstraint||w.relativePlacementConstraint;n&&(w.tile=!1,w.packComponents=!1);var E=void 0,p=!1;if(P.layoutUtilities&&w.packComponents&&(E=P.layoutUtilities("get"),E||(E=P.layoutUtilities()),p=!0),B.nodes().length>0)if(p){var I=t.getTopMostNodes(w.eles.nodes());if(M=t.connectComponents(P,w.eles,I),M.forEach(function(vt){var it=vt.boundingBox();_.push({x:it.x1+it.w/2,y:it.y1+it.h/2})}),w.randomize&&M.forEach(function(vt){w.eles=vt,U.push(o(w))}),w.quality=="default"||w.quality=="proof"){var O=P.collection();if(w.tile){var R=new Map,W=[],x=[],Q=0,z={nodeIndexes:R,xCoords:W,yCoords:x},X=[];if(M.forEach(function(vt,it){vt.edges().length==0&&(vt.nodes().forEach(function(ut,Et){O.merge(vt.nodes()[Et]),ut.isParent()||(z.nodeIndexes.set(vt.nodes()[Et].id(),Q++),z.xCoords.push(vt.nodes()[0].position().x),z.yCoords.push(vt.nodes()[0].position().y))}),X.push(it))}),O.length>1){var rt=O.boundingBox();_.push({x:rt.x1+rt.w/2,y:rt.y1+rt.h/2}),M.push(O),U.push(z);for(var $=X.length-1;$>=0;$--)M.splice(X[$],1),U.splice(X[$],1),_.splice(X[$],1)}}M.forEach(function(vt,it){w.eles=vt,V.push(l(w,U[it])),t.relocateComponent(_[it],V[it],w)})}else M.forEach(function(vt,it){t.relocateComponent(_[it],U[it],w)});var D=new Set;if(M.length>1){var H=[],k=B.filter(function(vt){return vt.css("display")=="none"});M.forEach(function(vt,it){var ut=void 0;if(w.quality=="draft"&&(ut=U[it].nodeIndexes),vt.nodes().not(k).length>0){var Et={};Et.edges=[],Et.nodes=[];var wt=void 0;vt.nodes().not(k).forEach(function(Ot){if(w.quality=="draft")if(!Ot.isParent())wt=ut.get(Ot.id()),Et.nodes.push({x:U[it].xCoords[wt]-Ot.boundingbox().w/2,y:U[it].yCoords[wt]-Ot.boundingbox().h/2,width:Ot.boundingbox().w,height:Ot.boundingbox().h});else{var mt=t.calcBoundingBox(Ot,U[it].xCoords,U[it].yCoords,ut);Et.nodes.push({x:mt.topLeftX,y:mt.topLeftY,width:mt.width,height:mt.height})}else V[it][Ot.id()]&&Et.nodes.push({x:V[it][Ot.id()].getLeft(),y:V[it][Ot.id()].getTop(),width:V[it][Ot.id()].getWidth(),height:V[it][Ot.id()].getHeight()})}),vt.edges().forEach(function(Ot){var mt=Ot.source(),Dt=Ot.target();if(mt.css("display")!="none"&&Dt.css("display")!="none")if(w.quality=="draft"){var Rt=ut.get(mt.id()),Ht=ut.get(Dt.id()),Ut=[],Pt=[];if(mt.isParent()){var Ft=t.calcBoundingBox(mt,U[it].xCoords,U[it].yCoords,ut);Ut.push(Ft.topLeftX+Ft.width/2),Ut.push(Ft.topLeftY+Ft.height/2)}else Ut.push(U[it].xCoords[Rt]),Ut.push(U[it].yCoords[Rt]);if(Dt.isParent()){var Yt=t.calcBoundingBox(Dt,U[it].xCoords,U[it].yCoords,ut);Pt.push(Yt.topLeftX+Yt.width/2),Pt.push(Yt.topLeftY+Yt.height/2)}else Pt.push(U[it].xCoords[Ht]),Pt.push(U[it].yCoords[Ht]);Et.edges.push({startX:Ut[0],startY:Ut[1],endX:Pt[0],endY:Pt[1]})}else V[it][mt.id()]&&V[it][Dt.id()]&&Et.edges.push({startX:V[it][mt.id()].getCenterX(),startY:V[it][mt.id()].getCenterY(),endX:V[it][Dt.id()].getCenterX(),endY:V[it][Dt.id()].getCenterY()})}),Et.nodes.length>0&&(H.push(Et),D.add(it))}});var tt=E.packComponents(H,w.randomize).shifts;if(w.quality=="draft")U.forEach(function(vt,it){var ut=vt.xCoords.map(function(wt){return wt+tt[it].dx}),Et=vt.yCoords.map(function(wt){return wt+tt[it].dy});vt.xCoords=ut,vt.yCoords=Et});else{var ht=0;D.forEach(function(vt){Object.keys(V[vt]).forEach(function(it){var ut=V[vt][it];ut.setCenter(ut.getCenterX()+tt[ht].dx,ut.getCenterY()+tt[ht].dy)}),ht++})}}}else{var m=w.eles.boundingBox();if(_.push({x:m.x1+m.w/2,y:m.y1+m.h/2}),w.randomize){var y=o(w);U.push(y)}w.quality=="default"||w.quality=="proof"?(V.push(l(w,U[0])),t.relocateComponent(_[0],V[0],w)):t.relocateComponent(_[0],U[0],w)}var J=function(it,ut){if(w.quality=="default"||w.quality=="proof"){typeof it=="number"&&(it=ut);var Et=void 0,wt=void 0,Ot=it.data("id");return V.forEach(function(Dt){Ot in Dt&&(Et={x:Dt[Ot].getRect().getCenterX(),y:Dt[Ot].getRect().getCenterY()},wt=Dt[Ot])}),w.nodeDimensionsIncludeLabels&&(wt.labelWidth&&(wt.labelPosHorizontal=="left"?Et.x+=wt.labelWidth/2:wt.labelPosHorizontal=="right"&&(Et.x-=wt.labelWidth/2)),wt.labelHeight&&(wt.labelPosVertical=="top"?Et.y+=wt.labelHeight/2:wt.labelPosVertical=="bottom"&&(Et.y-=wt.labelHeight/2))),Et==null&&(Et={x:it.position("x"),y:it.position("y")}),{x:Et.x,y:Et.y}}else{var mt=void 0;return U.forEach(function(Dt){var Rt=Dt.nodeIndexes.get(it.id());Rt!=null&&(mt={x:Dt.xCoords[Rt],y:Dt.yCoords[Rt]})}),mt==null&&(mt={x:it.position("x"),y:it.position("y")}),{x:mt.x,y:mt.y}}};if(w.quality=="default"||w.quality=="proof"||w.randomize){var It=t.calcParentsWithoutChildren(P,B),Nt=B.filter(function(vt){return vt.css("display")=="none"});w.eles=B.not(Nt),B.nodes().not(":parent").not(Nt).layoutPositions(S,w,J),It.length>0&&It.forEach(function(vt){vt.position(J(vt))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")}}]),d})();i.exports=g}),657:((i,r,a)=>{var f=a(548),e=a(140).layoutBase.Matrix,u=a(140).layoutBase.SVD,t=function(o){var c=o.cy,l=o.eles,T=l.nodes(),g=l.nodes(":parent"),d=new Map,C=new Map,S=new Map,w=[],P=[],B=[],U=[],V=[],M=[],_=[],n=[],E=void 0,p=1e8,m=1e-9,y=o.piTol,I=o.samplingType,O=o.nodeSeparation,R=void 0,W=function(){for(var Y=0,Z=0,K=!1;Z<R;){Y=Math.floor(Math.random()*E),K=!1;for(var q=0;q<Z;q++)if(U[q]==Y){K=!0;break}if(!K)U[Z]=Y,Z++;else continue}},x=function(Y,Z,K){for(var q=[],at=0,ct=0,nt=0,et=void 0,j=[],dt=0,At=1,pt=0;pt<E;pt++)j[pt]=p;for(q[ct]=Y,j[Y]=0;ct>=at;){nt=q[at++];for(var xt=w[nt],lt=0;lt<xt.length;lt++)et=C.get(xt[lt]),j[et]==p&&(j[et]=j[nt]+1,q[++ct]=et);M[nt][Z]=j[nt]*O}if(K){for(var ot=0;ot<E;ot++)M[ot][Z]<V[ot]&&(V[ot]=M[ot][Z]);for(var Lt=0;Lt<E;Lt++)V[Lt]>dt&&(dt=V[Lt],At=Lt)}return At},Q=function(Y){var Z=void 0;if(Y){Z=Math.floor(Math.random()*E);for(var q=0;q<E;q++)V[q]=p;for(var at=0;at<R;at++)U[at]=Z,Z=x(Z,at,Y)}else{W();for(var K=0;K<R;K++)x(U[K],K,Y)}for(var ct=0;ct<E;ct++)for(var nt=0;nt<R;nt++)M[ct][nt]*=M[ct][nt];for(var et=0;et<R;et++)_[et]=[];for(var j=0;j<R;j++)for(var dt=0;dt<R;dt++)_[j][dt]=M[U[dt]][j]},z=function(){for(var Y=u.svd(_),Z=Y.S,K=Y.U,q=Y.V,at=Z[0]*Z[0]*Z[0],ct=[],nt=0;nt<R;nt++){ct[nt]=[];for(var et=0;et<R;et++)ct[nt][et]=0,nt==et&&(ct[nt][et]=Z[nt]/(Z[nt]*Z[nt]+at/(Z[nt]*Z[nt])))}n=e.multMat(e.multMat(q,ct),e.transpose(K))},X=function(){for(var Y=void 0,Z=void 0,K=[],q=[],at=[],ct=[],nt=0;nt<E;nt++)K[nt]=Math.random(),q[nt]=Math.random();K=e.normalize(K),q=e.normalize(q);for(var et=m,j=m,dt=void 0;;){for(var At=0;At<E;At++)at[At]=K[At];if(K=e.multGamma(e.multL(e.multGamma(at),M,n)),Y=e.dotProduct(at,K),K=e.normalize(K),et=e.dotProduct(at,K),dt=Math.abs(et/j),dt<=1+y&&dt>=1)break;j=et}for(var pt=0;pt<E;pt++)at[pt]=K[pt];for(j=m;;){for(var xt=0;xt<E;xt++)ct[xt]=q[xt];if(ct=e.minusOp(ct,e.multCons(at,e.dotProduct(at,ct))),q=e.multGamma(e.multL(e.multGamma(ct),M,n)),Z=e.dotProduct(ct,q),q=e.normalize(q),et=e.dotProduct(ct,q),dt=Math.abs(et/j),dt<=1+y&&dt>=1)break;j=et}for(var lt=0;lt<E;lt++)ct[lt]=q[lt];P=e.multCons(at,Math.sqrt(Math.abs(Y))),B=e.multCons(ct,Math.sqrt(Math.abs(Z)))};f.connectComponents(c,l,f.getTopMostNodes(T),d),g.forEach(function(F){f.connectComponents(c,l,f.getTopMostNodes(F.descendants().intersection(l)),d)});for(var rt=0,$=0;$<T.length;$++)T[$].isParent()||C.set(T[$].id(),rt++);var D=!0,H=!1,k=void 0;try{for(var tt=d.keys()[Symbol.iterator](),ht;!(D=(ht=tt.next()).done);D=!0){var J=ht.value;C.set(J,rt++)}}catch(F){H=!0,k=F}finally{try{!D&&tt.return&&tt.return()}finally{if(H)throw k}}for(var It=0;It<C.size;It++)w[It]=[];g.forEach(function(F){for(var Y=F.children().intersection(l);Y.nodes(":childless").length==0;)Y=Y.nodes()[0].children().intersection(l);var Z=0,K=Y.nodes(":childless")[0].connectedEdges().length;Y.nodes(":childless").forEach(function(q,at){q.connectedEdges().length<K&&(K=q.connectedEdges().length,Z=at)}),S.set(F.id(),Y.nodes(":childless")[Z].id())}),T.forEach(function(F){var Y=void 0;F.isParent()?Y=C.get(S.get(F.id())):Y=C.get(F.id()),F.neighborhood().nodes().forEach(function(Z){l.intersection(F.edgesWith(Z)).length>0&&(Z.isParent()?w[Y].push(S.get(Z.id())):w[Y].push(Z.id()))})});var Nt=function(Y){var Z=C.get(Y),K=void 0;d.get(Y).forEach(function(q){c.getElementById(q).isParent()?K=S.get(q):K=q,w[Z].push(K),w[C.get(K)].push(Y)})},vt=!0,it=!1,ut=void 0;try{for(var Et=d.keys()[Symbol.iterator](),wt;!(vt=(wt=Et.next()).done);vt=!0){var Ot=wt.value;Nt(Ot)}}catch(F){it=!0,ut=F}finally{try{!vt&&Et.return&&Et.return()}finally{if(it)throw ut}}E=C.size;var mt=void 0;if(E>2){R=E<o.sampleSize?E:o.sampleSize;for(var Dt=0;Dt<E;Dt++)M[Dt]=[];for(var Rt=0;Rt<R;Rt++)n[Rt]=[];return o.quality=="draft"||o.step=="all"?(Q(I),z(),X(),mt={nodeIndexes:C,xCoords:P,yCoords:B}):(C.forEach(function(F,Y){P.push(c.getElementById(Y).position("x")),B.push(c.getElementById(Y).position("y"))}),mt={nodeIndexes:C,xCoords:P,yCoords:B}),mt}else{var Ht=C.keys(),Ut=c.getElementById(Ht.next().value),Pt=Ut.position(),Ft=Ut.outerWidth();if(P.push(Pt.x),B.push(Pt.y),E==2){var Yt=c.getElementById(Ht.next().value),Vt=Yt.outerWidth();P.push(Pt.x+Ft/2+Vt/2+o.idealEdgeLength),B.push(Pt.y)}return mt={nodeIndexes:C,xCoords:P,yCoords:B},mt}};i.exports={spectralLayout:t}}),579:((i,r,a)=>{var f=a(212),e=function(t){t&&t("layout","fcose",f)};typeof cytoscape<"u"&&e(cytoscape),i.exports=e}),140:(i=>{i.exports=A})},N={};function v(i){var r=N[i];if(r!==void 0)return r.exports;var a=N[i]={exports:{}};return G[i](a,a.exports,v),a.exports}var h=v(579);return h})()})})(se)),se.exports}var mr=yr();const Er=cr(mr);var xe={L:"left",R:"right",T:"top",B:"bottom"},Ie={L:gt(L=>`${L},${L/2} 0,${L} 0,0`,"L"),R:gt(L=>`0,${L/2} ${L},0 ${L},${L}`,"R"),T:gt(L=>`0,0 ${L},0 ${L/2},${L}`,"T"),B:gt(L=>`${L/2},0 ${L},${L} 0,${L}`,"B")},oe={L:gt((L,b)=>L-b+2,"L"),R:gt((L,b)=>L-2,"R"),T:gt((L,b)=>L-b+2,"T"),B:gt((L,b)=>L-2,"B")},Tr=gt(function(L){return Wt(L)?L==="L"?"R":"L":L==="T"?"B":"T"},"getOppositeArchitectureDirection"),Re=gt(function(L){const b=L;return b==="L"||b==="R"||b==="T"||b==="B"},"isArchitectureDirection"),Wt=gt(function(L){const b=L;return b==="L"||b==="R"},"isArchitectureDirectionX"),qt=gt(function(L){const b=L;return b==="T"||b==="B"},"isArchitectureDirectionY"),Te=gt(function(L,b){const A=Wt(L)&&qt(b),G=qt(L)&&Wt(b);return A||G},"isArchitectureDirectionXY"),Nr=gt(function(L){const b=L[0],A=L[1],G=Wt(b)&&qt(A),N=qt(b)&&Wt(A);return G||N},"isArchitecturePairXY"),Lr=gt(function(L){return L!=="LL"&&L!=="RR"&&L!=="TT"&&L!=="BB"},"isValidArchitectureDirectionPair"),pe=gt(function(L,b){const A=`${L}${b}`;return Lr(A)?A:void 0},"getArchitectureDirectionPair"),Cr=gt(function([L,b],A){const G=A[0],N=A[1];return Wt(G)?qt(N)?[L+(G==="L"?-1:1),b+(N==="T"?1:-1)]:[L+(G==="L"?-1:1),b]:Wt(N)?[L+(N==="L"?1:-1),b+(G==="T"?1:-1)]:[L,b+(G==="T"?1:-1)]},"shiftPositionByArchitectureDirectionPair"),wr=gt(function(L){return L==="LT"||L==="TL"?[1,1]:L==="BL"||L==="LB"?[1,-1]:L==="BR"||L==="RB"?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),Ar=gt(function(L,b){return Te(L,b)?"bend":Wt(L)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),Mr=gt(function(L){return L.type==="service"},"isArchitectureService"),Or=gt(function(L){return L.type==="junction"},"isArchitectureJunction"),be=gt(L=>L.data(),"edgeData"),ie=gt(L=>L.data(),"nodeData"),Dr=ar.architecture,Pe=class{constructor(){this.nodes={},this.groups={},this.edges=[],this.layoutHints=[],this.registeredIds={},this.elements={},this.diagramId="",this.setAccTitle=Qe,this.getAccTitle=Je,this.setDiagramTitle=Ke,this.getDiagramTitle=je,this.getAccDescription=_e,this.setAccDescription=tr,this.clear()}static{gt(this,"ArchitectureDB")}setDiagramId(L){this.diagramId=L}getDiagramId(){return this.diagramId}clear(){this.nodes={},this.groups={},this.edges=[],this.layoutHints=[],this.registeredIds={},this.dataStructures=void 0,this.elements={},this.diagramId="",er()}addService({id:L,icon:b,in:A,title:G,iconText:N}){if(this.registeredIds[L]!==void 0)throw new Error(`The service id [${L}] is already in use by another ${this.registeredIds[L]}`);if(A!==void 0){if(L===A)throw new Error(`The service [${L}] cannot be placed within itself`);if(this.registeredIds[A]===void 0)throw new Error(`The service [${L}]'s parent does not exist. Please make sure the parent is created before this service`);if(this.registeredIds[A]==="node")throw new Error(`The service [${L}]'s parent is not a group`)}this.registeredIds[L]="node",this.nodes[L]={id:L,type:"service",icon:b,iconText:N,title:G,edges:[],in:A}}getServices(){return Object.values(this.nodes).filter(Mr)}addJunction({id:L,in:b}){if(this.registeredIds[L]!==void 0)throw new Error(`The junction id [${L}] is already in use by another ${this.registeredIds[L]}`);if(b!==void 0){if(L===b)throw new Error(`The junction [${L}] cannot be placed within itself`);if(this.registeredIds[b]===void 0)throw new Error(`The junction [${L}]'s parent does not exist. Please make sure the parent is created before this junction`);if(this.registeredIds[b]==="node")throw new Error(`The junction [${L}]'s parent is not a group`)}this.registeredIds[L]="node",this.nodes[L]={id:L,type:"junction",edges:[],in:b}}getJunctions(){return Object.values(this.nodes).filter(Or)}getNodes(){return Object.values(this.nodes)}getNode(L){return this.nodes[L]??null}addGroup({id:L,icon:b,in:A,title:G}){if(this.registeredIds?.[L]!==void 0)throw new Error(`The group id [${L}] is already in use by another ${this.registeredIds[L]}`);if(A!==void 0){if(L===A)throw new Error(`The group [${L}] cannot be placed within itself`);if(this.registeredIds?.[A]===void 0)throw new Error(`The group [${L}]'s parent does not exist. Please make sure the parent is created before this group`);if(this.registeredIds?.[A]==="node")throw new Error(`The group [${L}]'s parent is not a group`)}this.registeredIds[L]="group",this.groups[L]={id:L,icon:b,title:G,in:A}}getGroups(){return Object.values(this.groups)}addEdge({lhsId:L,rhsId:b,lhsDir:A,rhsDir:G,lhsInto:N,rhsInto:v,lhsGroup:h,rhsGroup:i,title:r}){if(!Re(A))throw new Error(`Invalid direction given for left hand side of edge ${L}--${b}. Expected (L,R,T,B) got ${String(A)}`);if(!Re(G))throw new Error(`Invalid direction given for right hand side of edge ${L}--${b}. Expected (L,R,T,B) got ${String(G)}`);if(this.nodes[L]===void 0&&this.groups[L]===void 0)throw new Error(`The left-hand id [${L}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(this.nodes[b]===void 0&&this.groups[b]===void 0)throw new Error(`The right-hand id [${b}] does not yet exist. Please create the service/group before declaring an edge to it.`);const a=this.nodes[L].in,f=this.nodes[b].in;if(h&&a&&f&&a==f)throw new Error(`The left-hand id [${L}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(i&&a&&f&&a==f)throw new Error(`The right-hand id [${b}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);const e={lhsId:L,lhsDir:A,lhsInto:N,lhsGroup:h,rhsId:b,rhsDir:G,rhsInto:v,rhsGroup:i,title:r};this.edges.push(e),this.nodes[L]&&this.nodes[b]&&(this.nodes[L].edges.push(this.edges[this.edges.length-1]),this.nodes[b].edges.push(this.edges[this.edges.length-1]))}getEdges(){return this.edges}addLayoutHint(L){if(L.members.length<2)throw new Error(`An align directive requires at least two members; got ${L.members.length}`);const b=new Set;L.members.forEach(A=>{if(this.registeredIds[A]!=="node")throw new Error(`align ${L.direction} references [${A}], which is not a service or junction`);if(b.has(A))throw new Error(`align ${L.direction} lists [${A}] more than once`);b.add(A)}),this.layoutHints.push(L)}getLayoutHints(){return this.layoutHints}getDataStructures(){if(this.dataStructures===void 0){const L={},b=Object.entries(this.nodes).reduce((i,[r,a])=>(i[r]=a.edges.reduce((f,e)=>{const u=this.getNode(e.lhsId)?.in,t=this.getNode(e.rhsId)?.in;if(u&&t&&u!==t){const s=Ar(e.lhsDir,e.rhsDir);s!=="bend"&&(L[u]??={},L[u][t]=s,L[t]??={},L[t][u]=s)}if(e.lhsId===r){const s=pe(e.lhsDir,e.rhsDir);s&&(f[s]=e.rhsId)}else{const s=pe(e.rhsDir,e.lhsDir);s&&(f[s]=e.lhsId)}return f},{}),i),{}),A=Object.keys(b)[0],G={[A]:1},N=Object.keys(b).reduce((i,r)=>r===A?i:{...i,[r]:1},{}),v=gt(i=>{const r={[i]:[0,0]},a=[i];for(;a.length>0;){const f=a.shift();if(f){G[f]=1,delete N[f];const e=b[f],[u,t]=r[f];Object.entries(e).forEach(([s,o])=>{G[o]||(r[o]=Cr([u,t],s),a.push(o))})}}return r},"BFS"),h=[v(A)];for(;Object.keys(N).length>0;)h.push(v(Object.keys(N)[0]));this.dataStructures={adjList:b,spatialMaps:h,groupAlignments:L}}return this.dataStructures}setElementForId(L,b){this.elements[L]=b}getElementById(L){return this.elements[L]}getConfig(){return rr({...Dr,...ir().architecture})}getConfigField(L){return this.getConfig()[L]}},xr=gt((L,b)=>{ke(L,b),L.groups.map(A=>b.addGroup(A)),L.services.map(A=>b.addService({...A,type:"service"})),L.junctions.map(A=>b.addJunction({...A,type:"junction"})),L.edges.map(A=>b.addEdge(A)),L.alignments?.map(A=>b.addLayoutHint({direction:A.direction,members:[...A.members]}))},"populateDb"),Ge={parser:{yy:void 0},parse:gt(async L=>{const b=await fr("architecture",L);Se.debug(b);const A=Ge.parser?.yy;if(!(A instanceof Pe))throw new Error("parser.parser?.yy was not a ArchitectureDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");xr(b,A)},"parse")},Ir=gt(L=>` +import{p as ke}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as gt,F as Ze,ad as qe,l as Se,b as Qe,a as Je,o as Ke,p as je,g as _e,s as tr,q as er,B as rr,z as ir,D as ar,c as me,a$ as Ee,ai as ve,i as nr,d as or,r as sr,aj as hr,b7 as lr}from"./mermaid.core-CJB1tAev.js";import{p as fr}from"./cynefin-VYW2F7L2-BIlq342y.js";import{c as Fe}from"./cytoscape.esm-OyMbaexL.js";import{g as cr}from"./_commonjsHelpers-CqkleIqs.js";import"./index-D-7nOosq.js";var se={exports:{}},he={exports:{}},le={exports:{}},gr=le.exports,Me;function ur(){return Me||(Me=1,(function(L,b){(function(G,N){L.exports=N()})(gr,function(){return(function(A){var G={};function N(v){if(G[v])return G[v].exports;var h=G[v]={i:v,l:!1,exports:{}};return A[v].call(h.exports,h,h.exports,N),h.l=!0,h.exports}return N.m=A,N.c=G,N.i=function(v){return v},N.d=function(v,h,i){N.o(v,h)||Object.defineProperty(v,h,{configurable:!1,enumerable:!0,get:i})},N.n=function(v){var h=v&&v.__esModule?function(){return v.default}:function(){return v};return N.d(h,"a",h),h},N.o=function(v,h){return Object.prototype.hasOwnProperty.call(v,h)},N.p="",N(N.s=28)})([(function(A,G,N){function v(){}v.QUALITY=1,v.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,v.DEFAULT_INCREMENTAL=!1,v.DEFAULT_ANIMATION_ON_LAYOUT=!0,v.DEFAULT_ANIMATION_DURING_LAYOUT=!1,v.DEFAULT_ANIMATION_PERIOD=50,v.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,v.DEFAULT_GRAPH_MARGIN=15,v.NODE_DIMENSIONS_INCLUDE_LABELS=!1,v.SIMPLE_NODE_SIZE=40,v.SIMPLE_NODE_HALF_SIZE=v.SIMPLE_NODE_SIZE/2,v.EMPTY_COMPOUND_NODE_SIZE=40,v.MIN_EDGE_LENGTH=1,v.WORLD_BOUNDARY=1e6,v.INITIAL_WORLD_BOUNDARY=v.WORLD_BOUNDARY/1e3,v.WORLD_CENTER_X=1200,v.WORLD_CENTER_Y=900,A.exports=v}),(function(A,G,N){var v=N(2),h=N(8),i=N(9);function r(f,e,u){v.call(this,u),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=u,this.bendpoints=[],this.source=f,this.target=e}r.prototype=Object.create(v.prototype);for(var a in v)r[a]=v[a];r.prototype.getSource=function(){return this.source},r.prototype.getTarget=function(){return this.target},r.prototype.isInterGraph=function(){return this.isInterGraph},r.prototype.getLength=function(){return this.length},r.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},r.prototype.getBendpoints=function(){return this.bendpoints},r.prototype.getLca=function(){return this.lca},r.prototype.getSourceInLca=function(){return this.sourceInLca},r.prototype.getTargetInLca=function(){return this.targetInLca},r.prototype.getOtherEnd=function(f){if(this.source===f)return this.target;if(this.target===f)return this.source;throw"Node is not incident with this edge"},r.prototype.getOtherEndInGraph=function(f,e){for(var u=this.getOtherEnd(f),t=e.getGraphManager().getRoot();;){if(u.getOwner()==e)return u;if(u.getOwner()==t)break;u=u.getOwner().getParent()}return null},r.prototype.updateLength=function(){var f=new Array(4);this.isOverlapingSourceAndTarget=h.getIntersection(this.target.getRect(),this.source.getRect(),f),this.isOverlapingSourceAndTarget||(this.lengthX=f[0]-f[2],this.lengthY=f[1]-f[3],Math.abs(this.lengthX)<1&&(this.lengthX=i.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=i.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},r.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=i.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=i.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},A.exports=r}),(function(A,G,N){function v(h){this.vGraphObject=h}A.exports=v}),(function(A,G,N){var v=N(2),h=N(10),i=N(13),r=N(0),a=N(16),f=N(5);function e(t,s,o,c){o==null&&c==null&&(c=s),v.call(this,c),t.graphManager!=null&&(t=t.graphManager),this.estimatedSize=h.MIN_VALUE,this.inclusionTreeDepth=h.MAX_VALUE,this.vGraphObject=c,this.edges=[],this.graphManager=t,o!=null&&s!=null?this.rect=new i(s.x,s.y,o.width,o.height):this.rect=new i}e.prototype=Object.create(v.prototype);for(var u in v)e[u]=v[u];e.prototype.getEdges=function(){return this.edges},e.prototype.getChild=function(){return this.child},e.prototype.getOwner=function(){return this.owner},e.prototype.getWidth=function(){return this.rect.width},e.prototype.setWidth=function(t){this.rect.width=t},e.prototype.getHeight=function(){return this.rect.height},e.prototype.setHeight=function(t){this.rect.height=t},e.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},e.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},e.prototype.getCenter=function(){return new f(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},e.prototype.getLocation=function(){return new f(this.rect.x,this.rect.y)},e.prototype.getRect=function(){return this.rect},e.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},e.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},e.prototype.setRect=function(t,s){this.rect.x=t.x,this.rect.y=t.y,this.rect.width=s.width,this.rect.height=s.height},e.prototype.setCenter=function(t,s){this.rect.x=t-this.rect.width/2,this.rect.y=s-this.rect.height/2},e.prototype.setLocation=function(t,s){this.rect.x=t,this.rect.y=s},e.prototype.moveBy=function(t,s){this.rect.x+=t,this.rect.y+=s},e.prototype.getEdgeListToNode=function(t){var s=[],o=this;return o.edges.forEach(function(c){if(c.target==t){if(c.source!=o)throw"Incorrect edge source!";s.push(c)}}),s},e.prototype.getEdgesBetween=function(t){var s=[],o=this;return o.edges.forEach(function(c){if(!(c.source==o||c.target==o))throw"Incorrect edge source and/or target";(c.target==t||c.source==t)&&s.push(c)}),s},e.prototype.getNeighborsList=function(){var t=new Set,s=this;return s.edges.forEach(function(o){if(o.source==s)t.add(o.target);else{if(o.target!=s)throw"Incorrect incidency!";t.add(o.source)}}),t},e.prototype.withChildren=function(){var t=new Set,s,o;if(t.add(this),this.child!=null)for(var c=this.child.getNodes(),l=0;l<c.length;l++)s=c[l],o=s.withChildren(),o.forEach(function(T){t.add(T)});return t},e.prototype.getNoOfChildren=function(){var t=0,s;if(this.child==null)t=1;else for(var o=this.child.getNodes(),c=0;c<o.length;c++)s=o[c],t+=s.getNoOfChildren();return t==0&&(t=1),t},e.prototype.getEstimatedSize=function(){if(this.estimatedSize==h.MIN_VALUE)throw"assert failed";return this.estimatedSize},e.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},e.prototype.scatter=function(){var t,s,o=-r.INITIAL_WORLD_BOUNDARY,c=r.INITIAL_WORLD_BOUNDARY;t=r.WORLD_CENTER_X+a.nextDouble()*(c-o)+o;var l=-r.INITIAL_WORLD_BOUNDARY,T=r.INITIAL_WORLD_BOUNDARY;s=r.WORLD_CENTER_Y+a.nextDouble()*(T-l)+l,this.rect.x=t,this.rect.y=s},e.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var t=this.getChild();if(t.updateBounds(!0),this.rect.x=t.getLeft(),this.rect.y=t.getTop(),this.setWidth(t.getRight()-t.getLeft()),this.setHeight(t.getBottom()-t.getTop()),r.NODE_DIMENSIONS_INCLUDE_LABELS){var s=t.getRight()-t.getLeft(),o=t.getBottom()-t.getTop();this.labelWidth&&(this.labelPosHorizontal=="left"?(this.rect.x-=this.labelWidth,this.setWidth(s+this.labelWidth)):this.labelPosHorizontal=="center"&&this.labelWidth>s?(this.rect.x-=(this.labelWidth-s)/2,this.setWidth(this.labelWidth)):this.labelPosHorizontal=="right"&&this.setWidth(s+this.labelWidth)),this.labelHeight&&(this.labelPosVertical=="top"?(this.rect.y-=this.labelHeight,this.setHeight(o+this.labelHeight)):this.labelPosVertical=="center"&&this.labelHeight>o?(this.rect.y-=(this.labelHeight-o)/2,this.setHeight(this.labelHeight)):this.labelPosVertical=="bottom"&&this.setHeight(o+this.labelHeight))}}},e.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==h.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},e.prototype.transform=function(t){var s=this.rect.x;s>r.WORLD_BOUNDARY?s=r.WORLD_BOUNDARY:s<-r.WORLD_BOUNDARY&&(s=-r.WORLD_BOUNDARY);var o=this.rect.y;o>r.WORLD_BOUNDARY?o=r.WORLD_BOUNDARY:o<-r.WORLD_BOUNDARY&&(o=-r.WORLD_BOUNDARY);var c=new f(s,o),l=t.inverseTransformPoint(c);this.setLocation(l.x,l.y)},e.prototype.getLeft=function(){return this.rect.x},e.prototype.getRight=function(){return this.rect.x+this.rect.width},e.prototype.getTop=function(){return this.rect.y},e.prototype.getBottom=function(){return this.rect.y+this.rect.height},e.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},A.exports=e}),(function(A,G,N){var v=N(0);function h(){}for(var i in v)h[i]=v[i];h.MAX_ITERATIONS=2500,h.DEFAULT_EDGE_LENGTH=50,h.DEFAULT_SPRING_STRENGTH=.45,h.DEFAULT_REPULSION_STRENGTH=4500,h.DEFAULT_GRAVITY_STRENGTH=.4,h.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,h.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,h.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,h.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,h.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,h.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,h.COOLING_ADAPTATION_FACTOR=.33,h.ADAPTATION_LOWER_NODE_LIMIT=1e3,h.ADAPTATION_UPPER_NODE_LIMIT=5e3,h.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,h.MAX_NODE_DISPLACEMENT=h.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,h.MIN_REPULSION_DIST=h.DEFAULT_EDGE_LENGTH/10,h.CONVERGENCE_CHECK_PERIOD=100,h.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,h.MIN_EDGE_LENGTH=1,h.GRID_CALCULATION_CHECK_PERIOD=10,A.exports=h}),(function(A,G,N){function v(h,i){h==null&&i==null?(this.x=0,this.y=0):(this.x=h,this.y=i)}v.prototype.getX=function(){return this.x},v.prototype.getY=function(){return this.y},v.prototype.setX=function(h){this.x=h},v.prototype.setY=function(h){this.y=h},v.prototype.getDifference=function(h){return new DimensionD(this.x-h.x,this.y-h.y)},v.prototype.getCopy=function(){return new v(this.x,this.y)},v.prototype.translate=function(h){return this.x+=h.width,this.y+=h.height,this},A.exports=v}),(function(A,G,N){var v=N(2),h=N(10),i=N(0),r=N(7),a=N(3),f=N(1),e=N(13),u=N(12),t=N(11);function s(c,l,T){v.call(this,T),this.estimatedSize=h.MIN_VALUE,this.margin=i.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=c,l!=null&&l instanceof r?this.graphManager=l:l!=null&&l instanceof Layout&&(this.graphManager=l.graphManager)}s.prototype=Object.create(v.prototype);for(var o in v)s[o]=v[o];s.prototype.getNodes=function(){return this.nodes},s.prototype.getEdges=function(){return this.edges},s.prototype.getGraphManager=function(){return this.graphManager},s.prototype.getParent=function(){return this.parent},s.prototype.getLeft=function(){return this.left},s.prototype.getRight=function(){return this.right},s.prototype.getTop=function(){return this.top},s.prototype.getBottom=function(){return this.bottom},s.prototype.isConnected=function(){return this.isConnected},s.prototype.add=function(c,l,T){if(l==null&&T==null){var g=c;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(g)>-1)throw"Node already in graph!";return g.owner=this,this.getNodes().push(g),g}else{var d=c;if(!(this.getNodes().indexOf(l)>-1&&this.getNodes().indexOf(T)>-1))throw"Source or target not in graph!";if(!(l.owner==T.owner&&l.owner==this))throw"Both owners must be this graph!";return l.owner!=T.owner?null:(d.source=l,d.target=T,d.isInterGraph=!1,this.getEdges().push(d),l.edges.push(d),T!=l&&T.edges.push(d),d)}},s.prototype.remove=function(c){var l=c;if(c instanceof a){if(l==null)throw"Node is null!";if(!(l.owner!=null&&l.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var T=l.edges.slice(),g,d=T.length,C=0;C<d;C++)g=T[C],g.isInterGraph?this.graphManager.remove(g):g.source.owner.remove(g);var S=this.nodes.indexOf(l);if(S==-1)throw"Node not in owner node list!";this.nodes.splice(S,1)}else if(c instanceof f){var g=c;if(g==null)throw"Edge is null!";if(!(g.source!=null&&g.target!=null))throw"Source and/or target is null!";if(!(g.source.owner!=null&&g.target.owner!=null&&g.source.owner==this&&g.target.owner==this))throw"Source and/or target owner is invalid!";var w=g.source.edges.indexOf(g),P=g.target.edges.indexOf(g);if(!(w>-1&&P>-1))throw"Source and/or target doesn't know this edge!";g.source.edges.splice(w,1),g.target!=g.source&&g.target.edges.splice(P,1);var S=g.source.owner.getEdges().indexOf(g);if(S==-1)throw"Not in owner's edge list!";g.source.owner.getEdges().splice(S,1)}},s.prototype.updateLeftTop=function(){for(var c=h.MAX_VALUE,l=h.MAX_VALUE,T,g,d,C=this.getNodes(),S=C.length,w=0;w<S;w++){var P=C[w];T=P.getTop(),g=P.getLeft(),c>T&&(c=T),l>g&&(l=g)}return c==h.MAX_VALUE?null:(C[0].getParent().paddingLeft!=null?d=C[0].getParent().paddingLeft:d=this.margin,this.left=l-d,this.top=c-d,new u(this.left,this.top))},s.prototype.updateBounds=function(c){for(var l=h.MAX_VALUE,T=-h.MAX_VALUE,g=h.MAX_VALUE,d=-h.MAX_VALUE,C,S,w,P,B,U=this.nodes,V=U.length,M=0;M<V;M++){var _=U[M];c&&_.child!=null&&_.updateBounds(),C=_.getLeft(),S=_.getRight(),w=_.getTop(),P=_.getBottom(),l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var n=new e(l,g,T-l,d-g);l==h.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),U[0].getParent().paddingLeft!=null?B=U[0].getParent().paddingLeft:B=this.margin,this.left=n.x-B,this.right=n.x+n.width+B,this.top=n.y-B,this.bottom=n.y+n.height+B},s.calculateBounds=function(c){for(var l=h.MAX_VALUE,T=-h.MAX_VALUE,g=h.MAX_VALUE,d=-h.MAX_VALUE,C,S,w,P,B=c.length,U=0;U<B;U++){var V=c[U];C=V.getLeft(),S=V.getRight(),w=V.getTop(),P=V.getBottom(),l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var M=new e(l,g,T-l,d-g);return M},s.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},s.prototype.getEstimatedSize=function(){if(this.estimatedSize==h.MIN_VALUE)throw"assert failed";return this.estimatedSize},s.prototype.calcEstimatedSize=function(){for(var c=0,l=this.nodes,T=l.length,g=0;g<T;g++){var d=l[g];c+=d.calcEstimatedSize()}return c==0?this.estimatedSize=i.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=c/Math.sqrt(this.nodes.length),this.estimatedSize},s.prototype.updateConnected=function(){var c=this;if(this.nodes.length==0){this.isConnected=!0;return}var l=new t,T=new Set,g=this.nodes[0],d,C,S=g.withChildren();for(S.forEach(function(M){l.push(M),T.add(M)});l.length!==0;){g=l.shift(),d=g.getEdges();for(var w=d.length,P=0;P<w;P++){var B=d[P];if(C=B.getOtherEndInGraph(g,this),C!=null&&!T.has(C)){var U=C.withChildren();U.forEach(function(M){l.push(M),T.add(M)})}}}if(this.isConnected=!1,T.size>=this.nodes.length){var V=0;T.forEach(function(M){M.owner==c&&V++}),V==this.nodes.length&&(this.isConnected=!0)}},A.exports=s}),(function(A,G,N){var v,h=N(1);function i(r){v=N(6),this.layout=r,this.graphs=[],this.edges=[]}i.prototype.addRoot=function(){var r=this.layout.newGraph(),a=this.layout.newNode(null),f=this.add(r,a);return this.setRootGraph(f),this.rootGraph},i.prototype.add=function(r,a,f,e,u){if(f==null&&e==null&&u==null){if(r==null)throw"Graph is null!";if(a==null)throw"Parent node is null!";if(this.graphs.indexOf(r)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(r),r.parent!=null)throw"Already has a parent!";if(a.child!=null)throw"Already has a child!";return r.parent=a,a.child=r,r}else{u=f,e=a,f=r;var t=e.getOwner(),s=u.getOwner();if(!(t!=null&&t.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(s!=null&&s.getGraphManager()==this))throw"Target not in this graph mgr!";if(t==s)return f.isInterGraph=!1,t.add(f,e,u);if(f.isInterGraph=!0,f.source=e,f.target=u,this.edges.indexOf(f)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(f),!(f.source!=null&&f.target!=null))throw"Edge source and/or target is null!";if(!(f.source.edges.indexOf(f)==-1&&f.target.edges.indexOf(f)==-1))throw"Edge already in source and/or target incidency list!";return f.source.edges.push(f),f.target.edges.push(f),f}},i.prototype.remove=function(r){if(r instanceof v){var a=r;if(a.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(a==this.rootGraph||a.parent!=null&&a.parent.graphManager==this))throw"Invalid parent node!";var f=[];f=f.concat(a.getEdges());for(var e,u=f.length,t=0;t<u;t++)e=f[t],a.remove(e);var s=[];s=s.concat(a.getNodes());var o;u=s.length;for(var t=0;t<u;t++)o=s[t],a.remove(o);a==this.rootGraph&&this.setRootGraph(null);var c=this.graphs.indexOf(a);this.graphs.splice(c,1),a.parent=null}else if(r instanceof h){if(e=r,e==null)throw"Edge is null!";if(!e.isInterGraph)throw"Not an inter-graph edge!";if(!(e.source!=null&&e.target!=null))throw"Source and/or target is null!";if(!(e.source.edges.indexOf(e)!=-1&&e.target.edges.indexOf(e)!=-1))throw"Source and/or target doesn't know this edge!";var c=e.source.edges.indexOf(e);if(e.source.edges.splice(c,1),c=e.target.edges.indexOf(e),e.target.edges.splice(c,1),!(e.source.owner!=null&&e.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(e.source.owner.getGraphManager().edges.indexOf(e)==-1)throw"Not in owner graph manager's edge list!";var c=e.source.owner.getGraphManager().edges.indexOf(e);e.source.owner.getGraphManager().edges.splice(c,1)}},i.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},i.prototype.getGraphs=function(){return this.graphs},i.prototype.getAllNodes=function(){if(this.allNodes==null){for(var r=[],a=this.getGraphs(),f=a.length,e=0;e<f;e++)r=r.concat(a[e].getNodes());this.allNodes=r}return this.allNodes},i.prototype.resetAllNodes=function(){this.allNodes=null},i.prototype.resetAllEdges=function(){this.allEdges=null},i.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},i.prototype.getAllEdges=function(){if(this.allEdges==null){var r=[],a=this.getGraphs();a.length;for(var f=0;f<a.length;f++)r=r.concat(a[f].getEdges());r=r.concat(this.edges),this.allEdges=r}return this.allEdges},i.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},i.prototype.setAllNodesToApplyGravitation=function(r){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=r},i.prototype.getRoot=function(){return this.rootGraph},i.prototype.setRootGraph=function(r){if(r.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=r,r.parent==null&&(r.parent=this.layout.newNode("Root node"))},i.prototype.getLayout=function(){return this.layout},i.prototype.isOneAncestorOfOther=function(r,a){if(!(r!=null&&a!=null))throw"assert failed";if(r==a)return!0;var f=r.getOwner(),e;do{if(e=f.getParent(),e==null)break;if(e==a)return!0;if(f=e.getOwner(),f==null)break}while(!0);f=a.getOwner();do{if(e=f.getParent(),e==null)break;if(e==r)return!0;if(f=e.getOwner(),f==null)break}while(!0);return!1},i.prototype.calcLowestCommonAncestors=function(){for(var r,a,f,e,u,t=this.getAllEdges(),s=t.length,o=0;o<s;o++){if(r=t[o],a=r.source,f=r.target,r.lca=null,r.sourceInLca=a,r.targetInLca=f,a==f){r.lca=a.getOwner();continue}for(e=a.getOwner();r.lca==null;){for(r.targetInLca=f,u=f.getOwner();r.lca==null;){if(u==e){r.lca=u;break}if(u==this.rootGraph)break;if(r.lca!=null)throw"assert failed";r.targetInLca=u.getParent(),u=r.targetInLca.getOwner()}if(e==this.rootGraph)break;r.lca==null&&(r.sourceInLca=e.getParent(),e=r.sourceInLca.getOwner())}if(r.lca==null)throw"assert failed"}},i.prototype.calcLowestCommonAncestor=function(r,a){if(r==a)return r.getOwner();var f=r.getOwner();do{if(f==null)break;var e=a.getOwner();do{if(e==null)break;if(e==f)return e;e=e.getParent().getOwner()}while(!0);f=f.getParent().getOwner()}while(!0);return f},i.prototype.calcInclusionTreeDepths=function(r,a){r==null&&a==null&&(r=this.rootGraph,a=1);for(var f,e=r.getNodes(),u=e.length,t=0;t<u;t++)f=e[t],f.inclusionTreeDepth=a,f.child!=null&&this.calcInclusionTreeDepths(f.child,a+1)},i.prototype.includesInvalidEdge=function(){for(var r,a=[],f=this.edges.length,e=0;e<f;e++)r=this.edges[e],this.isOneAncestorOfOther(r.source,r.target)&&a.push(r);for(var e=0;e<a.length;e++)this.remove(a[e]);return!1},A.exports=i}),(function(A,G,N){var v=N(12);function h(){}h.calcSeparationAmount=function(i,r,a,f){if(!i.intersects(r))throw"assert failed";var e=new Array(2);this.decideDirectionsForOverlappingNodes(i,r,e),a[0]=Math.min(i.getRight(),r.getRight())-Math.max(i.x,r.x),a[1]=Math.min(i.getBottom(),r.getBottom())-Math.max(i.y,r.y),i.getX()<=r.getX()&&i.getRight()>=r.getRight()?a[0]+=Math.min(r.getX()-i.getX(),i.getRight()-r.getRight()):r.getX()<=i.getX()&&r.getRight()>=i.getRight()&&(a[0]+=Math.min(i.getX()-r.getX(),r.getRight()-i.getRight())),i.getY()<=r.getY()&&i.getBottom()>=r.getBottom()?a[1]+=Math.min(r.getY()-i.getY(),i.getBottom()-r.getBottom()):r.getY()<=i.getY()&&r.getBottom()>=i.getBottom()&&(a[1]+=Math.min(i.getY()-r.getY(),r.getBottom()-i.getBottom()));var u=Math.abs((r.getCenterY()-i.getCenterY())/(r.getCenterX()-i.getCenterX()));r.getCenterY()===i.getCenterY()&&r.getCenterX()===i.getCenterX()&&(u=1);var t=u*a[0],s=a[1]/u;a[0]<s?s=a[0]:t=a[1],a[0]=-1*e[0]*(s/2+f),a[1]=-1*e[1]*(t/2+f)},h.decideDirectionsForOverlappingNodes=function(i,r,a){i.getCenterX()<r.getCenterX()?a[0]=-1:a[0]=1,i.getCenterY()<r.getCenterY()?a[1]=-1:a[1]=1},h.getIntersection2=function(i,r,a){var f=i.getCenterX(),e=i.getCenterY(),u=r.getCenterX(),t=r.getCenterY();if(i.intersects(r))return a[0]=f,a[1]=e,a[2]=u,a[3]=t,!0;var s=i.getX(),o=i.getY(),c=i.getRight(),l=i.getX(),T=i.getBottom(),g=i.getRight(),d=i.getWidthHalf(),C=i.getHeightHalf(),S=r.getX(),w=r.getY(),P=r.getRight(),B=r.getX(),U=r.getBottom(),V=r.getRight(),M=r.getWidthHalf(),_=r.getHeightHalf(),n=!1,E=!1;if(f===u){if(e>t)return a[0]=f,a[1]=o,a[2]=u,a[3]=U,!1;if(e<t)return a[0]=f,a[1]=T,a[2]=u,a[3]=w,!1}else if(e===t){if(f>u)return a[0]=s,a[1]=e,a[2]=P,a[3]=t,!1;if(f<u)return a[0]=c,a[1]=e,a[2]=S,a[3]=t,!1}else{var p=i.height/i.width,m=r.height/r.width,y=(t-e)/(u-f),I=void 0,O=void 0,R=void 0,W=void 0,x=void 0,Q=void 0;if(-p===y?f>u?(a[0]=l,a[1]=T,n=!0):(a[0]=c,a[1]=o,n=!0):p===y&&(f>u?(a[0]=s,a[1]=o,n=!0):(a[0]=g,a[1]=T,n=!0)),-m===y?u>f?(a[2]=B,a[3]=U,E=!0):(a[2]=P,a[3]=w,E=!0):m===y&&(u>f?(a[2]=S,a[3]=w,E=!0):(a[2]=V,a[3]=U,E=!0)),n&&E)return!1;if(f>u?e>t?(I=this.getCardinalDirection(p,y,4),O=this.getCardinalDirection(m,y,2)):(I=this.getCardinalDirection(-p,y,3),O=this.getCardinalDirection(-m,y,1)):e>t?(I=this.getCardinalDirection(-p,y,1),O=this.getCardinalDirection(-m,y,3)):(I=this.getCardinalDirection(p,y,2),O=this.getCardinalDirection(m,y,4)),!n)switch(I){case 1:W=o,R=f+-C/y,a[0]=R,a[1]=W;break;case 2:R=g,W=e+d*y,a[0]=R,a[1]=W;break;case 3:W=T,R=f+C/y,a[0]=R,a[1]=W;break;case 4:R=l,W=e+-d*y,a[0]=R,a[1]=W;break}if(!E)switch(O){case 1:Q=w,x=u+-_/y,a[2]=x,a[3]=Q;break;case 2:x=V,Q=t+M*y,a[2]=x,a[3]=Q;break;case 3:Q=U,x=u+_/y,a[2]=x,a[3]=Q;break;case 4:x=B,Q=t+-M*y,a[2]=x,a[3]=Q;break}}return!1},h.getCardinalDirection=function(i,r,a){return i>r?a:1+a%4},h.getIntersection=function(i,r,a,f){if(f==null)return this.getIntersection2(i,r,a);var e=i.x,u=i.y,t=r.x,s=r.y,o=a.x,c=a.y,l=f.x,T=f.y,g=void 0,d=void 0,C=void 0,S=void 0,w=void 0,P=void 0,B=void 0,U=void 0,V=void 0;return C=s-u,w=e-t,B=t*u-e*s,S=T-c,P=o-l,U=l*c-o*T,V=C*P-S*w,V===0?null:(g=(w*U-P*B)/V,d=(S*B-C*U)/V,new v(g,d))},h.angleOfVector=function(i,r,a,f){var e=void 0;return i!==a?(e=Math.atan((f-r)/(a-i)),a<i?e+=Math.PI:f<r&&(e+=this.TWO_PI)):f<r?e=this.ONE_AND_HALF_PI:e=this.HALF_PI,e},h.doIntersect=function(i,r,a,f){var e=i.x,u=i.y,t=r.x,s=r.y,o=a.x,c=a.y,l=f.x,T=f.y,g=(t-e)*(T-c)-(l-o)*(s-u);if(g===0)return!1;var d=((T-c)*(l-e)+(o-l)*(T-u))/g,C=((u-s)*(l-e)+(t-e)*(T-u))/g;return 0<d&&d<1&&0<C&&C<1},h.findCircleLineIntersections=function(i,r,a,f,e,u,t){var s=(a-i)*(a-i)+(f-r)*(f-r),o=2*((i-e)*(a-i)+(r-u)*(f-r)),c=(i-e)*(i-e)+(r-u)*(r-u)-t*t,l=o*o-4*s*c;if(l>=0){var T=(-o+Math.sqrt(o*o-4*s*c))/(2*s),g=(-o-Math.sqrt(o*o-4*s*c))/(2*s),d=null;return T>=0&&T<=1?[T]:g>=0&&g<=1?[g]:d}else return null},h.HALF_PI=.5*Math.PI,h.ONE_AND_HALF_PI=1.5*Math.PI,h.TWO_PI=2*Math.PI,h.THREE_PI=3*Math.PI,A.exports=h}),(function(A,G,N){function v(){}v.sign=function(h){return h>0?1:h<0?-1:0},v.floor=function(h){return h<0?Math.ceil(h):Math.floor(h)},v.ceil=function(h){return h<0?Math.floor(h):Math.ceil(h)},A.exports=v}),(function(A,G,N){function v(){}v.MAX_VALUE=2147483647,v.MIN_VALUE=-2147483648,A.exports=v}),(function(A,G,N){var v=(function(){function e(u,t){for(var s=0;s<t.length;s++){var o=t[s];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(u,o.key,o)}}return function(u,t,s){return t&&e(u.prototype,t),s&&e(u,s),u}})();function h(e,u){if(!(e instanceof u))throw new TypeError("Cannot call a class as a function")}var i=function(u){return{value:u,next:null,prev:null}},r=function(u,t,s,o){return u!==null?u.next=t:o.head=t,s!==null?s.prev=t:o.tail=t,t.prev=u,t.next=s,o.length++,t},a=function(u,t){var s=u.prev,o=u.next;return s!==null?s.next=o:t.head=o,o!==null?o.prev=s:t.tail=s,u.prev=u.next=null,t.length--,u},f=(function(){function e(u){var t=this;h(this,e),this.length=0,this.head=null,this.tail=null,u?.forEach(function(s){return t.push(s)})}return v(e,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(t,s){return r(s.prev,i(t),s,this)}},{key:"insertAfter",value:function(t,s){return r(s,i(t),s.next,this)}},{key:"insertNodeBefore",value:function(t,s){return r(s.prev,t,s,this)}},{key:"insertNodeAfter",value:function(t,s){return r(s,t,s.next,this)}},{key:"push",value:function(t){return r(this.tail,i(t),null,this)}},{key:"unshift",value:function(t){return r(null,i(t),this.head,this)}},{key:"remove",value:function(t){return a(t,this)}},{key:"pop",value:function(){return a(this.tail,this).value}},{key:"popNode",value:function(){return a(this.tail,this)}},{key:"shift",value:function(){return a(this.head,this).value}},{key:"shiftNode",value:function(){return a(this.head,this)}},{key:"get_object_at",value:function(t){if(t<=this.length()){for(var s=1,o=this.head;s<t;)o=o.next,s++;return o.value}}},{key:"set_object_at",value:function(t,s){if(t<=this.length()){for(var o=1,c=this.head;o<t;)c=c.next,o++;c.value=s}}}]),e})();A.exports=f}),(function(A,G,N){function v(h,i,r){this.x=null,this.y=null,h==null&&i==null&&r==null?(this.x=0,this.y=0):typeof h=="number"&&typeof i=="number"&&r==null?(this.x=h,this.y=i):h.constructor.name=="Point"&&i==null&&r==null&&(r=h,this.x=r.x,this.y=r.y)}v.prototype.getX=function(){return this.x},v.prototype.getY=function(){return this.y},v.prototype.getLocation=function(){return new v(this.x,this.y)},v.prototype.setLocation=function(h,i,r){h.constructor.name=="Point"&&i==null&&r==null?(r=h,this.setLocation(r.x,r.y)):typeof h=="number"&&typeof i=="number"&&r==null&&(parseInt(h)==h&&parseInt(i)==i?this.move(h,i):(this.x=Math.floor(h+.5),this.y=Math.floor(i+.5)))},v.prototype.move=function(h,i){this.x=h,this.y=i},v.prototype.translate=function(h,i){this.x+=h,this.y+=i},v.prototype.equals=function(h){if(h.constructor.name=="Point"){var i=h;return this.x==i.x&&this.y==i.y}return this==h},v.prototype.toString=function(){return new v().constructor.name+"[x="+this.x+",y="+this.y+"]"},A.exports=v}),(function(A,G,N){function v(h,i,r,a){this.x=0,this.y=0,this.width=0,this.height=0,h!=null&&i!=null&&r!=null&&a!=null&&(this.x=h,this.y=i,this.width=r,this.height=a)}v.prototype.getX=function(){return this.x},v.prototype.setX=function(h){this.x=h},v.prototype.getY=function(){return this.y},v.prototype.setY=function(h){this.y=h},v.prototype.getWidth=function(){return this.width},v.prototype.setWidth=function(h){this.width=h},v.prototype.getHeight=function(){return this.height},v.prototype.setHeight=function(h){this.height=h},v.prototype.getRight=function(){return this.x+this.width},v.prototype.getBottom=function(){return this.y+this.height},v.prototype.intersects=function(h){return!(this.getRight()<h.x||this.getBottom()<h.y||h.getRight()<this.x||h.getBottom()<this.y)},v.prototype.getCenterX=function(){return this.x+this.width/2},v.prototype.getMinX=function(){return this.getX()},v.prototype.getMaxX=function(){return this.getX()+this.width},v.prototype.getCenterY=function(){return this.y+this.height/2},v.prototype.getMinY=function(){return this.getY()},v.prototype.getMaxY=function(){return this.getY()+this.height},v.prototype.getWidthHalf=function(){return this.width/2},v.prototype.getHeightHalf=function(){return this.height/2},A.exports=v}),(function(A,G,N){var v=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i};function h(){}h.lastID=0,h.createID=function(i){return h.isPrimitive(i)?i:(i.uniqueID!=null||(i.uniqueID=h.getString(),h.lastID++),i.uniqueID)},h.getString=function(i){return i==null&&(i=h.lastID),"Object#"+i},h.isPrimitive=function(i){var r=typeof i>"u"?"undefined":v(i);return i==null||r!="object"&&r!="function"},A.exports=h}),(function(A,G,N){function v(o){if(Array.isArray(o)){for(var c=0,l=Array(o.length);c<o.length;c++)l[c]=o[c];return l}else return Array.from(o)}var h=N(0),i=N(7),r=N(3),a=N(1),f=N(6),e=N(5),u=N(17),t=N(29);function s(o){t.call(this),this.layoutQuality=h.QUALITY,this.createBendsAsNeeded=h.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=h.DEFAULT_INCREMENTAL,this.animationOnLayout=h.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=h.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=h.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=h.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new i(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,o!=null&&(this.isRemoteUse=o)}s.RANDOM_SEED=1,s.prototype=Object.create(t.prototype),s.prototype.getGraphManager=function(){return this.graphManager},s.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},s.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},s.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},s.prototype.newGraphManager=function(){var o=new i(this);return this.graphManager=o,o},s.prototype.newGraph=function(o){return new f(null,this.graphManager,o)},s.prototype.newNode=function(o){return new r(this.graphManager,o)},s.prototype.newEdge=function(o){return new a(null,null,o)},s.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},s.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var o;return this.checkLayoutSuccess()?o=!1:o=this.layout(),h.ANIMATE==="during"?!1:(o&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,o)},s.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},s.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var o=this.graphManager.getAllEdges(),c=0;c<o.length;c++)o[c];for(var l=this.graphManager.getRoot().getNodes(),c=0;c<l.length;c++)l[c];this.update(this.graphManager.getRoot())}},s.prototype.update=function(o){if(o==null)this.update2();else if(o instanceof r){var c=o;if(c.getChild()!=null)for(var l=c.getChild().getNodes(),T=0;T<l.length;T++)update(l[T]);if(c.vGraphObject!=null){var g=c.vGraphObject;g.update(c)}}else if(o instanceof a){var d=o;if(d.vGraphObject!=null){var C=d.vGraphObject;C.update(d)}}else if(o instanceof f){var S=o;if(S.vGraphObject!=null){var w=S.vGraphObject;w.update(S)}}},s.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=h.QUALITY,this.animationDuringLayout=h.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=h.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=h.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=h.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=h.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=h.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},s.prototype.transform=function(o){if(o==null)this.transform(new e(0,0));else{var c=new u,l=this.graphManager.getRoot().updateLeftTop();if(l!=null){c.setWorldOrgX(o.x),c.setWorldOrgY(o.y),c.setDeviceOrgX(l.x),c.setDeviceOrgY(l.y);for(var T=this.getAllNodes(),g,d=0;d<T.length;d++)g=T[d],g.transform(c)}}},s.prototype.positionNodesRandomly=function(o){if(o==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var c,l,T=o.getNodes(),g=0;g<T.length;g++)c=T[g],l=c.getChild(),l==null||l.getNodes().length==0?c.scatter():(this.positionNodesRandomly(l),c.updateBounds())},s.prototype.getFlatForest=function(){for(var o=[],c=!0,l=this.graphManager.getRoot().getNodes(),T=!0,g=0;g<l.length;g++)l[g].getChild()!=null&&(T=!1);if(!T)return o;var d=new Set,C=[],S=new Map,w=[];for(w=w.concat(l);w.length>0&&c;){for(C.push(w[0]);C.length>0&&c;){var P=C[0];C.splice(0,1),d.add(P);for(var B=P.getEdges(),g=0;g<B.length;g++){var U=B[g].getOtherEnd(P);if(S.get(P)!=U)if(!d.has(U))C.push(U),S.set(U,P);else{c=!1;break}}}if(!c)o=[];else{var V=[].concat(v(d));o.push(V);for(var g=0;g<V.length;g++){var M=V[g],_=w.indexOf(M);_>-1&&w.splice(_,1)}d=new Set,S=new Map}}return o},s.prototype.createDummyNodesForBendpoints=function(o){for(var c=[],l=o.source,T=this.graphManager.calcLowestCommonAncestor(o.source,o.target),g=0;g<o.bendpoints.length;g++){var d=this.newNode(null);d.setRect(new Point(0,0),new Dimension(1,1)),T.add(d);var C=this.newEdge(null);this.graphManager.add(C,l,d),c.add(d),l=d}var C=this.newEdge(null);return this.graphManager.add(C,l,o.target),this.edgeToDummyNodes.set(o,c),o.isInterGraph()?this.graphManager.remove(o):T.remove(o),c},s.prototype.createBendpointsFromDummyNodes=function(){var o=[];o=o.concat(this.graphManager.getAllEdges()),o=[].concat(v(this.edgeToDummyNodes.keys())).concat(o);for(var c=0;c<o.length;c++){var l=o[c];if(l.bendpoints.length>0){for(var T=this.edgeToDummyNodes.get(l),g=0;g<T.length;g++){var d=T[g],C=new e(d.getCenterX(),d.getCenterY()),S=l.bendpoints.get(g);S.x=C.x,S.y=C.y,d.getOwner().remove(d)}this.graphManager.add(l,l.source,l.target)}}},s.transform=function(o,c,l,T){if(l!=null&&T!=null){var g=c;if(o<=50){var d=c/l;g-=(c-d)/50*(50-o)}else{var C=c*T;g+=(C-c)/50*(o-50)}return g}else{var S,w;return o<=50?(S=9*c/500,w=c/10):(S=9*c/50,w=-8*c),S*o+w}},s.findCenterOfTree=function(o){var c=[];c=c.concat(o);var l=[],T=new Map,g=!1,d=null;(c.length==1||c.length==2)&&(g=!0,d=c[0]);for(var C=0;C<c.length;C++){var S=c[C],w=S.getNeighborsList().size;T.set(S,S.getNeighborsList().size),w==1&&l.push(S)}var P=[];for(P=P.concat(l);!g;){var B=[];B=B.concat(P),P=[];for(var C=0;C<c.length;C++){var S=c[C],U=c.indexOf(S);U>=0&&c.splice(U,1);var V=S.getNeighborsList();V.forEach(function(n){if(l.indexOf(n)<0){var E=T.get(n),p=E-1;p==1&&P.push(n),T.set(n,p)}})}l=l.concat(P),(c.length==1||c.length==2)&&(g=!0,d=c[0])}return d},s.prototype.setGraphManager=function(o){this.graphManager=o},A.exports=s}),(function(A,G,N){function v(){}v.seed=1,v.x=0,v.nextDouble=function(){return v.x=Math.sin(v.seed++)*1e4,v.x-Math.floor(v.x)},A.exports=v}),(function(A,G,N){var v=N(5);function h(i,r){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}h.prototype.getWorldOrgX=function(){return this.lworldOrgX},h.prototype.setWorldOrgX=function(i){this.lworldOrgX=i},h.prototype.getWorldOrgY=function(){return this.lworldOrgY},h.prototype.setWorldOrgY=function(i){this.lworldOrgY=i},h.prototype.getWorldExtX=function(){return this.lworldExtX},h.prototype.setWorldExtX=function(i){this.lworldExtX=i},h.prototype.getWorldExtY=function(){return this.lworldExtY},h.prototype.setWorldExtY=function(i){this.lworldExtY=i},h.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},h.prototype.setDeviceOrgX=function(i){this.ldeviceOrgX=i},h.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},h.prototype.setDeviceOrgY=function(i){this.ldeviceOrgY=i},h.prototype.getDeviceExtX=function(){return this.ldeviceExtX},h.prototype.setDeviceExtX=function(i){this.ldeviceExtX=i},h.prototype.getDeviceExtY=function(){return this.ldeviceExtY},h.prototype.setDeviceExtY=function(i){this.ldeviceExtY=i},h.prototype.transformX=function(i){var r=0,a=this.lworldExtX;return a!=0&&(r=this.ldeviceOrgX+(i-this.lworldOrgX)*this.ldeviceExtX/a),r},h.prototype.transformY=function(i){var r=0,a=this.lworldExtY;return a!=0&&(r=this.ldeviceOrgY+(i-this.lworldOrgY)*this.ldeviceExtY/a),r},h.prototype.inverseTransformX=function(i){var r=0,a=this.ldeviceExtX;return a!=0&&(r=this.lworldOrgX+(i-this.ldeviceOrgX)*this.lworldExtX/a),r},h.prototype.inverseTransformY=function(i){var r=0,a=this.ldeviceExtY;return a!=0&&(r=this.lworldOrgY+(i-this.ldeviceOrgY)*this.lworldExtY/a),r},h.prototype.inverseTransformPoint=function(i){var r=new v(this.inverseTransformX(i.x),this.inverseTransformY(i.y));return r},A.exports=h}),(function(A,G,N){function v(t){if(Array.isArray(t)){for(var s=0,o=Array(t.length);s<t.length;s++)o[s]=t[s];return o}else return Array.from(t)}var h=N(15),i=N(4),r=N(0),a=N(8),f=N(9);function e(){h.call(this),this.useSmartIdealEdgeLengthCalculation=i.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=i.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=i.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=i.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=i.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=i.MAX_ITERATIONS}e.prototype=Object.create(h.prototype);for(var u in h)e[u]=h[u];e.prototype.initParameters=function(){h.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=i.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},e.prototype.calcIdealEdgeLengths=function(){for(var t,s,o,c,l,T,g,d=this.getGraphManager().getAllEdges(),C=0;C<d.length;C++)t=d[C],s=t.idealLength,t.isInterGraph&&(c=t.getSource(),l=t.getTarget(),T=t.getSourceInLca().getEstimatedSize(),g=t.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(t.idealLength+=T+g-2*r.SIMPLE_NODE_SIZE),o=t.getLca().getInclusionTreeDepth(),t.idealLength+=s*i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(c.getInclusionTreeDepth()+l.getInclusionTreeDepth()-2*o))},e.prototype.initSpringEmbedder=function(){var t=this.getAllNodes().length;this.incremental?(t>i.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*i.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(t-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-i.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT_INCREMENTAL):(t>i.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(i.COOLING_ADAPTATION_FACTOR,1-(t-i.ADAPTATION_LOWER_NODE_LIMIT)/(i.ADAPTATION_UPPER_NODE_LIMIT-i.ADAPTATION_LOWER_NODE_LIMIT)*(1-i.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=i.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.displacementThresholdPerNode=3*i.DEFAULT_EDGE_LENGTH/100,this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},e.prototype.calcSpringForces=function(){for(var t=this.getAllEdges(),s,o=0;o<t.length;o++)s=t[o],this.calcSpringForce(s,s.idealLength)},e.prototype.calcRepulsionForces=function(){var t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,s=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,o,c,l,T,g=this.getAllNodes(),d;if(this.useFRGridVariant)for(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&t&&this.updateGrid(),d=new Set,o=0;o<g.length;o++)l=g[o],this.calculateRepulsionForceOfANode(l,d,t,s),d.add(l);else for(o=0;o<g.length;o++)for(l=g[o],c=o+1;c<g.length;c++)T=g[c],l.getOwner()==T.getOwner()&&this.calcRepulsionForce(l,T)},e.prototype.calcGravitationalForces=function(){for(var t,s=this.getAllNodesToApplyGravitation(),o=0;o<s.length;o++)t=s[o],this.calcGravitationalForce(t)},e.prototype.moveNodes=function(){for(var t=this.getAllNodes(),s,o=0;o<t.length;o++)s=t[o],s.move()},e.prototype.calcSpringForce=function(t,s){var o=t.getSource(),c=t.getTarget(),l,T,g,d;if(this.uniformLeafNodeSizes&&o.getChild()==null&&c.getChild()==null)t.updateLengthSimple();else if(t.updateLength(),t.isOverlapingSourceAndTarget)return;l=t.getLength(),l!=0&&(T=t.edgeElasticity*(l-s),g=T*(t.lengthX/l),d=T*(t.lengthY/l),o.springForceX+=g,o.springForceY+=d,c.springForceX-=g,c.springForceY-=d)},e.prototype.calcRepulsionForce=function(t,s){var o=t.getRect(),c=s.getRect(),l=new Array(2),T=new Array(4),g,d,C,S,w,P,B;if(o.intersects(c)){a.calcSeparationAmount(o,c,l,i.DEFAULT_EDGE_LENGTH/2),P=2*l[0],B=2*l[1];var U=t.noOfChildren*s.noOfChildren/(t.noOfChildren+s.noOfChildren);t.repulsionForceX-=U*P,t.repulsionForceY-=U*B,s.repulsionForceX+=U*P,s.repulsionForceY+=U*B}else this.uniformLeafNodeSizes&&t.getChild()==null&&s.getChild()==null?(g=c.getCenterX()-o.getCenterX(),d=c.getCenterY()-o.getCenterY()):(a.getIntersection(o,c,T),g=T[2]-T[0],d=T[3]-T[1]),Math.abs(g)<i.MIN_REPULSION_DIST&&(g=f.sign(g)*i.MIN_REPULSION_DIST),Math.abs(d)<i.MIN_REPULSION_DIST&&(d=f.sign(d)*i.MIN_REPULSION_DIST),C=g*g+d*d,S=Math.sqrt(C),w=(t.nodeRepulsion/2+s.nodeRepulsion/2)*t.noOfChildren*s.noOfChildren/C,P=w*g/S,B=w*d/S,t.repulsionForceX-=P,t.repulsionForceY-=B,s.repulsionForceX+=P,s.repulsionForceY+=B},e.prototype.calcGravitationalForce=function(t){var s,o,c,l,T,g,d,C;s=t.getOwner(),o=(s.getRight()+s.getLeft())/2,c=(s.getTop()+s.getBottom())/2,l=t.getCenterX()-o,T=t.getCenterY()-c,g=Math.abs(l)+t.getWidth()/2,d=Math.abs(T)+t.getHeight()/2,t.getOwner()==this.graphManager.getRoot()?(C=s.getEstimatedSize()*this.gravityRangeFactor,(g>C||d>C)&&(t.gravitationForceX=-this.gravityConstant*l,t.gravitationForceY=-this.gravityConstant*T)):(C=s.getEstimatedSize()*this.compoundGravityRangeFactor,(g>C||d>C)&&(t.gravitationForceX=-this.gravityConstant*l*this.compoundGravityConstant,t.gravitationForceY=-this.gravityConstant*T*this.compoundGravityConstant))},e.prototype.isConverged=function(){var t,s=!1;return this.totalIterations>this.maxIterations/3&&(s=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),t=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,t||s},e.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},e.prototype.calcNoOfChildrenForAllNodes=function(){for(var t,s=this.graphManager.getAllNodes(),o=0;o<s.length;o++)t=s[o],t.noOfChildren=t.getNoOfChildren()},e.prototype.calcGrid=function(t){var s=0,o=0;s=parseInt(Math.ceil((t.getRight()-t.getLeft())/this.repulsionRange)),o=parseInt(Math.ceil((t.getBottom()-t.getTop())/this.repulsionRange));for(var c=new Array(s),l=0;l<s;l++)c[l]=new Array(o);for(var l=0;l<s;l++)for(var T=0;T<o;T++)c[l][T]=new Array;return c},e.prototype.addNodeToGrid=function(t,s,o){var c=0,l=0,T=0,g=0;c=parseInt(Math.floor((t.getRect().x-s)/this.repulsionRange)),l=parseInt(Math.floor((t.getRect().width+t.getRect().x-s)/this.repulsionRange)),T=parseInt(Math.floor((t.getRect().y-o)/this.repulsionRange)),g=parseInt(Math.floor((t.getRect().height+t.getRect().y-o)/this.repulsionRange));for(var d=c;d<=l;d++)for(var C=T;C<=g;C++)this.grid[d][C].push(t),t.setGridCoordinates(c,l,T,g)},e.prototype.updateGrid=function(){var t,s,o=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),t=0;t<o.length;t++)s=o[t],this.addNodeToGrid(s,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},e.prototype.calculateRepulsionForceOfANode=function(t,s,o,c){if(this.totalIterations%i.GRID_CALCULATION_CHECK_PERIOD==1&&o||c){var l=new Set;t.surrounding=new Array;for(var T,g=this.grid,d=t.startX-1;d<t.finishX+2;d++)for(var C=t.startY-1;C<t.finishY+2;C++)if(!(d<0||C<0||d>=g.length||C>=g[0].length)){for(var S=0;S<g[d][C].length;S++)if(T=g[d][C][S],!(t.getOwner()!=T.getOwner()||t==T)&&!s.has(T)&&!l.has(T)){var w=Math.abs(t.getCenterX()-T.getCenterX())-(t.getWidth()/2+T.getWidth()/2),P=Math.abs(t.getCenterY()-T.getCenterY())-(t.getHeight()/2+T.getHeight()/2);w<=this.repulsionRange&&P<=this.repulsionRange&&l.add(T)}}t.surrounding=[].concat(v(l))}for(d=0;d<t.surrounding.length;d++)this.calcRepulsionForce(t,t.surrounding[d])},e.prototype.calcRepulsionRange=function(){return 0},A.exports=e}),(function(A,G,N){var v=N(1),h=N(4);function i(a,f,e){v.call(this,a,f,e),this.idealLength=h.DEFAULT_EDGE_LENGTH,this.edgeElasticity=h.DEFAULT_SPRING_STRENGTH}i.prototype=Object.create(v.prototype);for(var r in v)i[r]=v[r];A.exports=i}),(function(A,G,N){var v=N(3),h=N(4);function i(a,f,e,u){v.call(this,a,f,e,u),this.nodeRepulsion=h.DEFAULT_REPULSION_STRENGTH,this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}i.prototype=Object.create(v.prototype);for(var r in v)i[r]=v[r];i.prototype.setGridCoordinates=function(a,f,e,u){this.startX=a,this.finishX=f,this.startY=e,this.finishY=u},A.exports=i}),(function(A,G,N){function v(h,i){this.width=0,this.height=0,h!==null&&i!==null&&(this.height=i,this.width=h)}v.prototype.getWidth=function(){return this.width},v.prototype.setWidth=function(h){this.width=h},v.prototype.getHeight=function(){return this.height},v.prototype.setHeight=function(h){this.height=h},A.exports=v}),(function(A,G,N){var v=N(14);function h(){this.map={},this.keys=[]}h.prototype.put=function(i,r){var a=v.createID(i);this.contains(a)||(this.map[a]=r,this.keys.push(i))},h.prototype.contains=function(i){return v.createID(i),this.map[i]!=null},h.prototype.get=function(i){var r=v.createID(i);return this.map[r]},h.prototype.keySet=function(){return this.keys},A.exports=h}),(function(A,G,N){var v=N(14);function h(){this.set={}}h.prototype.add=function(i){var r=v.createID(i);this.contains(r)||(this.set[r]=i)},h.prototype.remove=function(i){delete this.set[v.createID(i)]},h.prototype.clear=function(){this.set={}},h.prototype.contains=function(i){return this.set[v.createID(i)]==i},h.prototype.isEmpty=function(){return this.size()===0},h.prototype.size=function(){return Object.keys(this.set).length},h.prototype.addAllTo=function(i){for(var r=Object.keys(this.set),a=r.length,f=0;f<a;f++)i.push(this.set[r[f]])},h.prototype.size=function(){return Object.keys(this.set).length},h.prototype.addAll=function(i){for(var r=i.length,a=0;a<r;a++){var f=i[a];this.add(f)}},A.exports=h}),(function(A,G,N){function v(){}v.multMat=function(h,i){for(var r=[],a=0;a<h.length;a++){r[a]=[];for(var f=0;f<i[0].length;f++){r[a][f]=0;for(var e=0;e<h[0].length;e++)r[a][f]+=h[a][e]*i[e][f]}}return r},v.transpose=function(h){for(var i=[],r=0;r<h[0].length;r++){i[r]=[];for(var a=0;a<h.length;a++)i[r][a]=h[a][r]}return i},v.multCons=function(h,i){for(var r=[],a=0;a<h.length;a++)r[a]=h[a]*i;return r},v.minusOp=function(h,i){for(var r=[],a=0;a<h.length;a++)r[a]=h[a]-i[a];return r},v.dotProduct=function(h,i){for(var r=0,a=0;a<h.length;a++)r+=h[a]*i[a];return r},v.mag=function(h){return Math.sqrt(this.dotProduct(h,h))},v.normalize=function(h){for(var i=[],r=this.mag(h),a=0;a<h.length;a++)i[a]=h[a]/r;return i},v.multGamma=function(h){for(var i=[],r=0,a=0;a<h.length;a++)r+=h[a];r*=-1/h.length;for(var f=0;f<h.length;f++)i[f]=r+h[f];return i},v.multL=function(h,i,r){for(var a=[],f=[],e=[],u=0;u<i[0].length;u++){for(var t=0,s=0;s<i.length;s++)t+=-.5*i[s][u]*h[s];f[u]=t}for(var o=0;o<r.length;o++){for(var c=0,l=0;l<r.length;l++)c+=r[o][l]*f[l];e[o]=c}for(var T=0;T<i.length;T++){for(var g=0,d=0;d<i[0].length;d++)g+=i[T][d]*e[d];a[T]=g}return a},A.exports=v}),(function(A,G,N){var v=(function(){function a(f,e){for(var u=0;u<e.length;u++){var t=e[u];t.enumerable=t.enumerable||!1,t.configurable=!0,"value"in t&&(t.writable=!0),Object.defineProperty(f,t.key,t)}}return function(f,e,u){return e&&a(f.prototype,e),u&&a(f,u),f}})();function h(a,f){if(!(a instanceof f))throw new TypeError("Cannot call a class as a function")}var i=N(11),r=(function(){function a(f,e){h(this,a),(e!==null||e!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var u=void 0;f instanceof i?u=f.size():u=f.length,this._quicksort(f,0,u-1)}return v(a,[{key:"_quicksort",value:function(e,u,t){if(u<t){var s=this._partition(e,u,t);this._quicksort(e,u,s),this._quicksort(e,s+1,t)}}},{key:"_partition",value:function(e,u,t){for(var s=this._get(e,u),o=u,c=t;;){for(;this.compareFunction(s,this._get(e,c));)c--;for(;this.compareFunction(this._get(e,o),s);)o++;if(o<c)this._swap(e,o,c),o++,c--;else return c}}},{key:"_get",value:function(e,u){return e instanceof i?e.get_object_at(u):e[u]}},{key:"_set",value:function(e,u,t){e instanceof i?e.set_object_at(u,t):e[u]=t}},{key:"_swap",value:function(e,u,t){var s=this._get(e,u);this._set(e,u,this._get(e,t)),this._set(e,t,s)}},{key:"_defaultCompareFunction",value:function(e,u){return u>e}}]),a})();A.exports=r}),(function(A,G,N){function v(){}v.svd=function(h){this.U=null,this.V=null,this.s=null,this.m=0,this.n=0,this.m=h.length,this.n=h[0].length;var i=Math.min(this.m,this.n);this.s=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(Math.min(this.m+1,this.n)),this.U=(function(Tt){var Ct=function Bt(bt){if(bt.length==0)return 0;for(var zt=[],St=0;St<bt[0];St++)zt.push(Bt(bt.slice(1)));return zt};return Ct(Tt)})([this.m,i]),this.V=(function(Tt){var Ct=function Bt(bt){if(bt.length==0)return 0;for(var zt=[],St=0;St<bt[0];St++)zt.push(Bt(bt.slice(1)));return zt};return Ct(Tt)})([this.n,this.n]);for(var r=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(this.n),a=(function(Tt){for(var Ct=[];Tt-- >0;)Ct.push(0);return Ct})(this.m),f=!0,e=Math.min(this.m-1,this.n),u=Math.max(0,Math.min(this.n-2,this.m)),t=0;t<Math.max(e,u);t++){if(t<e){this.s[t]=0;for(var s=t;s<this.m;s++)this.s[t]=v.hypot(this.s[t],h[s][t]);if(this.s[t]!==0){h[t][t]<0&&(this.s[t]=-this.s[t]);for(var o=t;o<this.m;o++)h[o][t]/=this.s[t];h[t][t]+=1}this.s[t]=-this.s[t]}for(var c=t+1;c<this.n;c++){if((function(Tt,Ct){return Tt&&Ct})(t<e,this.s[t]!==0)){for(var l=0,T=t;T<this.m;T++)l+=h[T][t]*h[T][c];l=-l/h[t][t];for(var g=t;g<this.m;g++)h[g][c]+=l*h[g][t]}r[c]=h[t][c]}if((function(Tt,Ct){return Ct})(f,t<e))for(var d=t;d<this.m;d++)this.U[d][t]=h[d][t];if(t<u){r[t]=0;for(var C=t+1;C<this.n;C++)r[t]=v.hypot(r[t],r[C]);if(r[t]!==0){r[t+1]<0&&(r[t]=-r[t]);for(var S=t+1;S<this.n;S++)r[S]/=r[t];r[t+1]+=1}if(r[t]=-r[t],(function(Tt,Ct){return Tt&&Ct})(t+1<this.m,r[t]!==0)){for(var w=t+1;w<this.m;w++)a[w]=0;for(var P=t+1;P<this.n;P++)for(var B=t+1;B<this.m;B++)a[B]+=r[P]*h[B][P];for(var U=t+1;U<this.n;U++)for(var V=-r[U]/r[t+1],M=t+1;M<this.m;M++)h[M][U]+=V*a[M]}for(var _=t+1;_<this.n;_++)this.V[_][t]=r[_]}}var n=Math.min(this.n,this.m+1);e<this.n&&(this.s[e]=h[e][e]),this.m<n&&(this.s[n-1]=0),u+1<n&&(r[u]=h[u][n-1]),r[n-1]=0;{for(var E=e;E<i;E++){for(var p=0;p<this.m;p++)this.U[p][E]=0;this.U[E][E]=1}for(var m=e-1;m>=0;m--)if(this.s[m]!==0){for(var y=m+1;y<i;y++){for(var I=0,O=m;O<this.m;O++)I+=this.U[O][m]*this.U[O][y];I=-I/this.U[m][m];for(var R=m;R<this.m;R++)this.U[R][y]+=I*this.U[R][m]}for(var W=m;W<this.m;W++)this.U[W][m]=-this.U[W][m];this.U[m][m]=1+this.U[m][m];for(var x=0;x<m-1;x++)this.U[x][m]=0}else{for(var Q=0;Q<this.m;Q++)this.U[Q][m]=0;this.U[m][m]=1}}for(var z=this.n-1;z>=0;z--){if((function(Tt,Ct){return Tt&&Ct})(z<u,r[z]!==0))for(var X=z+1;X<i;X++){for(var rt=0,$=z+1;$<this.n;$++)rt+=this.V[$][z]*this.V[$][X];rt=-rt/this.V[z+1][z];for(var D=z+1;D<this.n;D++)this.V[D][X]+=rt*this.V[D][z]}for(var H=0;H<this.n;H++)this.V[H][z]=0;this.V[z][z]=1}for(var k=n-1,tt=Math.pow(2,-52),ht=Math.pow(2,-966);n>0;){var J=void 0,It=void 0;for(J=n-2;J>=-1&&J!==-1;J--)if(Math.abs(r[J])<=ht+tt*(Math.abs(this.s[J])+Math.abs(this.s[J+1]))){r[J]=0;break}if(J===n-2)It=4;else{var Nt=void 0;for(Nt=n-1;Nt>=J&&Nt!==J;Nt--){var vt=(Nt!==n?Math.abs(r[Nt]):0)+(Nt!==J+1?Math.abs(r[Nt-1]):0);if(Math.abs(this.s[Nt])<=ht+tt*vt){this.s[Nt]=0;break}}Nt===J?It=3:Nt===n-1?It=1:(It=2,J=Nt)}switch(J++,It){case 1:{var it=r[n-2];r[n-2]=0;for(var ut=n-2;ut>=J;ut--){var Et=v.hypot(this.s[ut],it),wt=this.s[ut]/Et,Ot=it/Et;this.s[ut]=Et,ut!==J&&(it=-Ot*r[ut-1],r[ut-1]=wt*r[ut-1]);for(var mt=0;mt<this.n;mt++)Et=wt*this.V[mt][ut]+Ot*this.V[mt][n-1],this.V[mt][n-1]=-Ot*this.V[mt][ut]+wt*this.V[mt][n-1],this.V[mt][ut]=Et}}break;case 2:{var Dt=r[J-1];r[J-1]=0;for(var Rt=J;Rt<n;Rt++){var Ht=v.hypot(this.s[Rt],Dt),Ut=this.s[Rt]/Ht,Pt=Dt/Ht;this.s[Rt]=Ht,Dt=-Pt*r[Rt],r[Rt]=Ut*r[Rt];for(var Ft=0;Ft<this.m;Ft++)Ht=Ut*this.U[Ft][Rt]+Pt*this.U[Ft][J-1],this.U[Ft][J-1]=-Pt*this.U[Ft][Rt]+Ut*this.U[Ft][J-1],this.U[Ft][Rt]=Ht}}break;case 3:{var Yt=Math.max(Math.max(Math.max(Math.max(Math.abs(this.s[n-1]),Math.abs(this.s[n-2])),Math.abs(r[n-2])),Math.abs(this.s[J])),Math.abs(r[J])),Vt=this.s[n-1]/Yt,F=this.s[n-2]/Yt,Y=r[n-2]/Yt,Z=this.s[J]/Yt,K=r[J]/Yt,q=((F+Vt)*(F-Vt)+Y*Y)/2,at=Vt*Y*(Vt*Y),ct=0;(function(Tt,Ct){return Tt||Ct})(q!==0,at!==0)&&(ct=Math.sqrt(q*q+at),q<0&&(ct=-ct),ct=at/(q+ct));for(var nt=(Z+Vt)*(Z-Vt)+ct,et=Z*K,j=J;j<n-1;j++){var dt=v.hypot(nt,et),At=nt/dt,pt=et/dt;j!==J&&(r[j-1]=dt),nt=At*this.s[j]+pt*r[j],r[j]=At*r[j]-pt*this.s[j],et=pt*this.s[j+1],this.s[j+1]=At*this.s[j+1];for(var xt=0;xt<this.n;xt++)dt=At*this.V[xt][j]+pt*this.V[xt][j+1],this.V[xt][j+1]=-pt*this.V[xt][j]+At*this.V[xt][j+1],this.V[xt][j]=dt;if(dt=v.hypot(nt,et),At=nt/dt,pt=et/dt,this.s[j]=dt,nt=At*r[j]+pt*this.s[j+1],this.s[j+1]=-pt*r[j]+At*this.s[j+1],et=pt*r[j+1],r[j+1]=At*r[j+1],j<this.m-1)for(var lt=0;lt<this.m;lt++)dt=At*this.U[lt][j]+pt*this.U[lt][j+1],this.U[lt][j+1]=-pt*this.U[lt][j]+At*this.U[lt][j+1],this.U[lt][j]=dt}r[n-2]=nt}break;case 4:{if(this.s[J]<=0){this.s[J]=this.s[J]<0?-this.s[J]:0;for(var ot=0;ot<=k;ot++)this.V[ot][J]=-this.V[ot][J]}for(;J<k&&!(this.s[J]>=this.s[J+1]);){var Lt=this.s[J];if(this.s[J]=this.s[J+1],this.s[J+1]=Lt,J<this.n-1)for(var ft=0;ft<this.n;ft++)Lt=this.V[ft][J+1],this.V[ft][J+1]=this.V[ft][J],this.V[ft][J]=Lt;if(J<this.m-1)for(var st=0;st<this.m;st++)Lt=this.U[st][J+1],this.U[st][J+1]=this.U[st][J],this.U[st][J]=Lt;J++}n--}break}}var Xt={U:this.U,V:this.V,S:this.s};return Xt},v.hypot=function(h,i){var r=void 0;return Math.abs(h)>Math.abs(i)?(r=i/h,r=Math.abs(h)*Math.sqrt(1+r*r)):i!=0?(r=h/i,r=Math.abs(i)*Math.sqrt(1+r*r)):r=0,r},A.exports=v}),(function(A,G,N){var v=(function(){function r(a,f){for(var e=0;e<f.length;e++){var u=f[e];u.enumerable=u.enumerable||!1,u.configurable=!0,"value"in u&&(u.writable=!0),Object.defineProperty(a,u.key,u)}}return function(a,f,e){return f&&r(a.prototype,f),e&&r(a,e),a}})();function h(r,a){if(!(r instanceof a))throw new TypeError("Cannot call a class as a function")}var i=(function(){function r(a,f){var e=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,u=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,t=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;h(this,r),this.sequence1=a,this.sequence2=f,this.match_score=e,this.mismatch_penalty=u,this.gap_penalty=t,this.iMax=a.length+1,this.jMax=f.length+1,this.grid=new Array(this.iMax);for(var s=0;s<this.iMax;s++){this.grid[s]=new Array(this.jMax);for(var o=0;o<this.jMax;o++)this.grid[s][o]=0}this.tracebackGrid=new Array(this.iMax);for(var c=0;c<this.iMax;c++){this.tracebackGrid[c]=new Array(this.jMax);for(var l=0;l<this.jMax;l++)this.tracebackGrid[c][l]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return v(r,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var f=1;f<this.jMax;f++)this.grid[0][f]=this.grid[0][f-1]+this.gap_penalty,this.tracebackGrid[0][f]=[!1,!1,!0];for(var e=1;e<this.iMax;e++)this.grid[e][0]=this.grid[e-1][0]+this.gap_penalty,this.tracebackGrid[e][0]=[!1,!0,!1];for(var u=1;u<this.iMax;u++)for(var t=1;t<this.jMax;t++){var s=void 0;this.sequence1[u-1]===this.sequence2[t-1]?s=this.grid[u-1][t-1]+this.match_score:s=this.grid[u-1][t-1]+this.mismatch_penalty;var o=this.grid[u-1][t]+this.gap_penalty,c=this.grid[u][t-1]+this.gap_penalty,l=[s,o,c],T=this.arrayAllMaxIndexes(l);this.grid[u][t]=l[T[0]],this.tracebackGrid[u][t]=[T.includes(0),T.includes(1),T.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var f=[];for(f.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});f[0];){var e=f[0],u=this.tracebackGrid[e.pos[0]][e.pos[1]];u[0]&&f.push({pos:[e.pos[0]-1,e.pos[1]-1],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),u[1]&&f.push({pos:[e.pos[0]-1,e.pos[1]],seq1:this.sequence1[e.pos[0]-1]+e.seq1,seq2:"-"+e.seq2}),u[2]&&f.push({pos:[e.pos[0],e.pos[1]-1],seq1:"-"+e.seq1,seq2:this.sequence2[e.pos[1]-1]+e.seq2}),e.pos[0]===0&&e.pos[1]===0&&this.alignments.push({sequence1:e.seq1,sequence2:e.seq2}),f.shift()}return this.alignments}},{key:"getAllIndexes",value:function(f,e){for(var u=[],t=-1;(t=f.indexOf(e,t+1))!==-1;)u.push(t);return u}},{key:"arrayAllMaxIndexes",value:function(f){return this.getAllIndexes(f,Math.max.apply(null,f))}}]),r})();A.exports=i}),(function(A,G,N){var v=function(){};v.FDLayout=N(18),v.FDLayoutConstants=N(4),v.FDLayoutEdge=N(19),v.FDLayoutNode=N(20),v.DimensionD=N(21),v.HashMap=N(22),v.HashSet=N(23),v.IGeometry=N(8),v.IMath=N(9),v.Integer=N(10),v.Point=N(12),v.PointD=N(5),v.RandomSeed=N(16),v.RectangleD=N(13),v.Transform=N(17),v.UniqueIDGeneretor=N(14),v.Quicksort=N(25),v.LinkedList=N(11),v.LGraphObject=N(2),v.LGraph=N(6),v.LEdge=N(1),v.LGraphManager=N(7),v.LNode=N(3),v.Layout=N(15),v.LayoutConstants=N(0),v.NeedlemanWunsch=N(27),v.Matrix=N(24),v.SVD=N(26),A.exports=v}),(function(A,G,N){function v(){this.listeners=[]}var h=v.prototype;h.addListener=function(i,r){this.listeners.push({event:i,callback:r})},h.removeListener=function(i,r){for(var a=this.listeners.length;a>=0;a--){var f=this.listeners[a];f.event===i&&f.callback===r&&this.listeners.splice(a,1)}},h.emit=function(i,r){for(var a=0;a<this.listeners.length;a++){var f=this.listeners[a];i===f.event&&f.callback(r)}},A.exports=v})])})})(le)),le.exports}var dr=he.exports,Oe;function vr(){return Oe||(Oe=1,(function(L,b){(function(G,N){L.exports=N(ur())})(dr,function(A){return(()=>{var G={45:((i,r,a)=>{var f={};f.layoutBase=a(551),f.CoSEConstants=a(806),f.CoSEEdge=a(767),f.CoSEGraph=a(880),f.CoSEGraphManager=a(578),f.CoSELayout=a(765),f.CoSENode=a(991),f.ConstraintHandler=a(902),i.exports=f}),806:((i,r,a)=>{var f=a(551).FDLayoutConstants;function e(){}for(var u in f)e[u]=f[u];e.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,e.DEFAULT_RADIAL_SEPARATION=f.DEFAULT_EDGE_LENGTH,e.DEFAULT_COMPONENT_SEPERATION=60,e.TILE=!0,e.TILING_PADDING_VERTICAL=10,e.TILING_PADDING_HORIZONTAL=10,e.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,e.ENFORCE_CONSTRAINTS=!0,e.APPLY_LAYOUT=!0,e.RELAX_MOVEMENT_ON_CONSTRAINTS=!0,e.TREE_REDUCTION_ON_INCREMENTAL=!0,e.PURE_INCREMENTAL=e.DEFAULT_INCREMENTAL,i.exports=e}),767:((i,r,a)=>{var f=a(551).FDLayoutEdge;function e(t,s,o){f.call(this,t,s,o)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),880:((i,r,a)=>{var f=a(551).LGraph;function e(t,s,o){f.call(this,t,s,o)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),578:((i,r,a)=>{var f=a(551).LGraphManager;function e(t){f.call(this,t)}e.prototype=Object.create(f.prototype);for(var u in f)e[u]=f[u];i.exports=e}),765:((i,r,a)=>{var f=a(551).FDLayout,e=a(578),u=a(880),t=a(991),s=a(767),o=a(806),c=a(902),l=a(551).FDLayoutConstants,T=a(551).LayoutConstants,g=a(551).Point,d=a(551).PointD,C=a(551).DimensionD,S=a(551).Layout,w=a(551).Integer,P=a(551).IGeometry,B=a(551).LGraph,U=a(551).Transform,V=a(551).LinkedList;function M(){f.call(this),this.toBeTiled={},this.constraints={}}M.prototype=Object.create(f.prototype);for(var _ in f)M[_]=f[_];M.prototype.newGraphManager=function(){var n=new e(this);return this.graphManager=n,n},M.prototype.newGraph=function(n){return new u(null,this.graphManager,n)},M.prototype.newNode=function(n){return new t(this.graphManager,n)},M.prototype.newEdge=function(n){return new s(null,null,n)},M.prototype.initParameters=function(){f.prototype.initParameters.call(this,arguments),this.isSubLayout||(o.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=o.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=o.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.gravityConstant=l.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=l.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=l.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1)},M.prototype.initSpringEmbedder=function(){f.prototype.initSpringEmbedder.call(this),this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/l.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=.04,this.coolingAdjuster=1},M.prototype.layout=function(){var n=T.DEFAULT_CREATE_BENDS_AS_NEEDED;return n&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},M.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(o.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),p=this.nodesWithGravity.filter(function(I){return E.has(I)});this.graphManager.setAllNodesToApplyGravitation(p)}}else{var n=this.getFlatForest();if(n.length>0)this.positionNodesRadially(n);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var E=new Set(this.getAllNodes()),p=this.nodesWithGravity.filter(function(m){return E.has(m)});this.graphManager.setAllNodesToApplyGravitation(p),this.positionNodesRandomly()}}return Object.keys(this.constraints).length>0&&(c.handleConstraints(this),this.initConstraintVariables()),this.initSpringEmbedder(),o.APPLY_LAYOUT&&this.runSpringEmbedder(),!0},M.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%l.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var n=new Set(this.getAllNodes()),E=this.nodesWithGravity.filter(function(y){return n.has(y)});this.graphManager.setAllNodesToApplyGravitation(E),this.graphManager.updateBounds(),this.updateGrid(),o.PURE_INCREMENTAL?this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL/2:this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),o.PURE_INCREMENTAL?this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL/2*((100-this.afterGrowthIterations)/100):this.coolingFactor=l.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var p=!this.isTreeGrowing&&!this.isGrowthFinished,m=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(p,m),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},M.prototype.getPositionsData=function(){for(var n=this.graphManager.getAllNodes(),E={},p=0;p<n.length;p++){var m=n[p].rect,y=n[p].id;E[y]={id:y,x:m.getCenterX(),y:m.getCenterY(),w:m.width,h:m.height}}return E},M.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var n=!1;if(l.ANIMATE==="during")this.emit("layoutstarted");else{for(;!n;)n=this.tick();this.graphManager.updateBounds()}},M.prototype.moveNodes=function(){for(var n=this.getAllNodes(),E,p=0;p<n.length;p++)E=n[p],E.calculateDisplacement();Object.keys(this.constraints).length>0&&this.updateDisplacements();for(var p=0;p<n.length;p++)E=n[p],E.move()},M.prototype.initConstraintVariables=function(){var n=this;this.idToNodeMap=new Map,this.fixedNodeSet=new Set;for(var E=this.graphManager.getAllNodes(),p=0;p<E.length;p++){var m=E[p];this.idToNodeMap.set(m.id,m)}var y=function D(H){for(var k=H.getChild().getNodes(),tt,ht=0,J=0;J<k.length;J++)tt=k[J],tt.getChild()==null?n.fixedNodeSet.has(tt.id)&&(ht+=100):ht+=D(tt);return ht};if(this.constraints.fixedNodeConstraint){this.constraints.fixedNodeConstraint.forEach(function(k){n.fixedNodeSet.add(k.nodeId)});for(var E=this.graphManager.getAllNodes(),m,p=0;p<E.length;p++)if(m=E[p],m.getChild()!=null){var I=y(m);I>0&&(m.fixedNodeWeight=I)}}if(this.constraints.relativePlacementConstraint){var O=new Map,R=new Map;if(this.dummyToNodeForVerticalAlignment=new Map,this.dummyToNodeForHorizontalAlignment=new Map,this.fixedNodesOnHorizontal=new Set,this.fixedNodesOnVertical=new Set,this.fixedNodeSet.forEach(function(D){n.fixedNodesOnHorizontal.add(D),n.fixedNodesOnVertical.add(D)}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var W=this.constraints.alignmentConstraint.vertical,p=0;p<W.length;p++)this.dummyToNodeForVerticalAlignment.set("dummy"+p,[]),W[p].forEach(function(H){O.set(H,"dummy"+p),n.dummyToNodeForVerticalAlignment.get("dummy"+p).push(H),n.fixedNodeSet.has(H)&&n.fixedNodesOnHorizontal.add("dummy"+p)});if(this.constraints.alignmentConstraint.horizontal)for(var x=this.constraints.alignmentConstraint.horizontal,p=0;p<x.length;p++)this.dummyToNodeForHorizontalAlignment.set("dummy"+p,[]),x[p].forEach(function(H){R.set(H,"dummy"+p),n.dummyToNodeForHorizontalAlignment.get("dummy"+p).push(H),n.fixedNodeSet.has(H)&&n.fixedNodesOnVertical.add("dummy"+p)})}if(o.RELAX_MOVEMENT_ON_CONSTRAINTS)this.shuffle=function(D){var H,k,tt;for(tt=D.length-1;tt>=2*D.length/3;tt--)H=Math.floor(Math.random()*(tt+1)),k=D[tt],D[tt]=D[H],D[H]=k;return D},this.nodesInRelativeHorizontal=[],this.nodesInRelativeVertical=[],this.nodeToRelativeConstraintMapHorizontal=new Map,this.nodeToRelativeConstraintMapVertical=new Map,this.nodeToTempPositionMapHorizontal=new Map,this.nodeToTempPositionMapVertical=new Map,this.constraints.relativePlacementConstraint.forEach(function(D){if(D.left){var H=O.has(D.left)?O.get(D.left):D.left,k=O.has(D.right)?O.get(D.right):D.right;n.nodesInRelativeHorizontal.includes(H)||(n.nodesInRelativeHorizontal.push(H),n.nodeToRelativeConstraintMapHorizontal.set(H,[]),n.dummyToNodeForVerticalAlignment.has(H)?n.nodeToTempPositionMapHorizontal.set(H,n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get(H)[0]).getCenterX()):n.nodeToTempPositionMapHorizontal.set(H,n.idToNodeMap.get(H).getCenterX())),n.nodesInRelativeHorizontal.includes(k)||(n.nodesInRelativeHorizontal.push(k),n.nodeToRelativeConstraintMapHorizontal.set(k,[]),n.dummyToNodeForVerticalAlignment.has(k)?n.nodeToTempPositionMapHorizontal.set(k,n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get(k)[0]).getCenterX()):n.nodeToTempPositionMapHorizontal.set(k,n.idToNodeMap.get(k).getCenterX())),n.nodeToRelativeConstraintMapHorizontal.get(H).push({right:k,gap:D.gap}),n.nodeToRelativeConstraintMapHorizontal.get(k).push({left:H,gap:D.gap})}else{var tt=R.has(D.top)?R.get(D.top):D.top,ht=R.has(D.bottom)?R.get(D.bottom):D.bottom;n.nodesInRelativeVertical.includes(tt)||(n.nodesInRelativeVertical.push(tt),n.nodeToRelativeConstraintMapVertical.set(tt,[]),n.dummyToNodeForHorizontalAlignment.has(tt)?n.nodeToTempPositionMapVertical.set(tt,n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get(tt)[0]).getCenterY()):n.nodeToTempPositionMapVertical.set(tt,n.idToNodeMap.get(tt).getCenterY())),n.nodesInRelativeVertical.includes(ht)||(n.nodesInRelativeVertical.push(ht),n.nodeToRelativeConstraintMapVertical.set(ht,[]),n.dummyToNodeForHorizontalAlignment.has(ht)?n.nodeToTempPositionMapVertical.set(ht,n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get(ht)[0]).getCenterY()):n.nodeToTempPositionMapVertical.set(ht,n.idToNodeMap.get(ht).getCenterY())),n.nodeToRelativeConstraintMapVertical.get(tt).push({bottom:ht,gap:D.gap}),n.nodeToRelativeConstraintMapVertical.get(ht).push({top:tt,gap:D.gap})}});else{var Q=new Map,z=new Map;this.constraints.relativePlacementConstraint.forEach(function(D){if(D.left){var H=O.has(D.left)?O.get(D.left):D.left,k=O.has(D.right)?O.get(D.right):D.right;Q.has(H)?Q.get(H).push(k):Q.set(H,[k]),Q.has(k)?Q.get(k).push(H):Q.set(k,[H])}else{var tt=R.has(D.top)?R.get(D.top):D.top,ht=R.has(D.bottom)?R.get(D.bottom):D.bottom;z.has(tt)?z.get(tt).push(ht):z.set(tt,[ht]),z.has(ht)?z.get(ht).push(tt):z.set(ht,[tt])}});var X=function(H,k){var tt=[],ht=[],J=new V,It=new Set,Nt=0;return H.forEach(function(vt,it){if(!It.has(it)){tt[Nt]=[],ht[Nt]=!1;var ut=it;for(J.push(ut),It.add(ut),tt[Nt].push(ut);J.length!=0;){ut=J.shift(),k.has(ut)&&(ht[Nt]=!0);var Et=H.get(ut);Et.forEach(function(wt){It.has(wt)||(J.push(wt),It.add(wt),tt[Nt].push(wt))})}Nt++}}),{components:tt,isFixed:ht}},rt=X(Q,n.fixedNodesOnHorizontal);this.componentsOnHorizontal=rt.components,this.fixedComponentsOnHorizontal=rt.isFixed;var $=X(z,n.fixedNodesOnVertical);this.componentsOnVertical=$.components,this.fixedComponentsOnVertical=$.isFixed}}},M.prototype.updateDisplacements=function(){var n=this;if(this.constraints.fixedNodeConstraint&&this.constraints.fixedNodeConstraint.forEach(function($){var D=n.idToNodeMap.get($.nodeId);D.displacementX=0,D.displacementY=0}),this.constraints.alignmentConstraint){if(this.constraints.alignmentConstraint.vertical)for(var E=this.constraints.alignmentConstraint.vertical,p=0;p<E.length;p++){for(var m=0,y=0;y<E[p].length;y++){if(this.fixedNodeSet.has(E[p][y])){m=0;break}m+=this.idToNodeMap.get(E[p][y]).displacementX}for(var I=m/E[p].length,y=0;y<E[p].length;y++)this.idToNodeMap.get(E[p][y]).displacementX=I}if(this.constraints.alignmentConstraint.horizontal)for(var O=this.constraints.alignmentConstraint.horizontal,p=0;p<O.length;p++){for(var R=0,y=0;y<O[p].length;y++){if(this.fixedNodeSet.has(O[p][y])){R=0;break}R+=this.idToNodeMap.get(O[p][y]).displacementY}for(var W=R/O[p].length,y=0;y<O[p].length;y++)this.idToNodeMap.get(O[p][y]).displacementY=W}}if(this.constraints.relativePlacementConstraint)if(o.RELAX_MOVEMENT_ON_CONSTRAINTS)this.totalIterations%10==0&&(this.shuffle(this.nodesInRelativeHorizontal),this.shuffle(this.nodesInRelativeVertical)),this.nodesInRelativeHorizontal.forEach(function($){if(!n.fixedNodesOnHorizontal.has($)){var D=0;n.dummyToNodeForVerticalAlignment.has($)?D=n.idToNodeMap.get(n.dummyToNodeForVerticalAlignment.get($)[0]).displacementX:D=n.idToNodeMap.get($).displacementX,n.nodeToRelativeConstraintMapHorizontal.get($).forEach(function(H){if(H.right){var k=n.nodeToTempPositionMapHorizontal.get(H.right)-n.nodeToTempPositionMapHorizontal.get($)-D;k<H.gap&&(D-=H.gap-k)}else{var k=n.nodeToTempPositionMapHorizontal.get($)-n.nodeToTempPositionMapHorizontal.get(H.left)+D;k<H.gap&&(D+=H.gap-k)}}),n.nodeToTempPositionMapHorizontal.set($,n.nodeToTempPositionMapHorizontal.get($)+D),n.dummyToNodeForVerticalAlignment.has($)?n.dummyToNodeForVerticalAlignment.get($).forEach(function(H){n.idToNodeMap.get(H).displacementX=D}):n.idToNodeMap.get($).displacementX=D}}),this.nodesInRelativeVertical.forEach(function($){if(!n.fixedNodesOnHorizontal.has($)){var D=0;n.dummyToNodeForHorizontalAlignment.has($)?D=n.idToNodeMap.get(n.dummyToNodeForHorizontalAlignment.get($)[0]).displacementY:D=n.idToNodeMap.get($).displacementY,n.nodeToRelativeConstraintMapVertical.get($).forEach(function(H){if(H.bottom){var k=n.nodeToTempPositionMapVertical.get(H.bottom)-n.nodeToTempPositionMapVertical.get($)-D;k<H.gap&&(D-=H.gap-k)}else{var k=n.nodeToTempPositionMapVertical.get($)-n.nodeToTempPositionMapVertical.get(H.top)+D;k<H.gap&&(D+=H.gap-k)}}),n.nodeToTempPositionMapVertical.set($,n.nodeToTempPositionMapVertical.get($)+D),n.dummyToNodeForHorizontalAlignment.has($)?n.dummyToNodeForHorizontalAlignment.get($).forEach(function(H){n.idToNodeMap.get(H).displacementY=D}):n.idToNodeMap.get($).displacementY=D}});else{for(var p=0;p<this.componentsOnHorizontal.length;p++){var x=this.componentsOnHorizontal[p];if(this.fixedComponentsOnHorizontal[p])for(var y=0;y<x.length;y++)this.dummyToNodeForVerticalAlignment.has(x[y])?this.dummyToNodeForVerticalAlignment.get(x[y]).forEach(function(H){n.idToNodeMap.get(H).displacementX=0}):this.idToNodeMap.get(x[y]).displacementX=0;else{for(var Q=0,z=0,y=0;y<x.length;y++)if(this.dummyToNodeForVerticalAlignment.has(x[y])){var X=this.dummyToNodeForVerticalAlignment.get(x[y]);Q+=X.length*this.idToNodeMap.get(X[0]).displacementX,z+=X.length}else Q+=this.idToNodeMap.get(x[y]).displacementX,z++;for(var rt=Q/z,y=0;y<x.length;y++)this.dummyToNodeForVerticalAlignment.has(x[y])?this.dummyToNodeForVerticalAlignment.get(x[y]).forEach(function(H){n.idToNodeMap.get(H).displacementX=rt}):this.idToNodeMap.get(x[y]).displacementX=rt}}for(var p=0;p<this.componentsOnVertical.length;p++){var x=this.componentsOnVertical[p];if(this.fixedComponentsOnVertical[p])for(var y=0;y<x.length;y++)this.dummyToNodeForHorizontalAlignment.has(x[y])?this.dummyToNodeForHorizontalAlignment.get(x[y]).forEach(function(k){n.idToNodeMap.get(k).displacementY=0}):this.idToNodeMap.get(x[y]).displacementY=0;else{for(var Q=0,z=0,y=0;y<x.length;y++)if(this.dummyToNodeForHorizontalAlignment.has(x[y])){var X=this.dummyToNodeForHorizontalAlignment.get(x[y]);Q+=X.length*this.idToNodeMap.get(X[0]).displacementY,z+=X.length}else Q+=this.idToNodeMap.get(x[y]).displacementY,z++;for(var rt=Q/z,y=0;y<x.length;y++)this.dummyToNodeForHorizontalAlignment.has(x[y])?this.dummyToNodeForHorizontalAlignment.get(x[y]).forEach(function(J){n.idToNodeMap.get(J).displacementY=rt}):this.idToNodeMap.get(x[y]).displacementY=rt}}}},M.prototype.calculateNodesToApplyGravitationTo=function(){var n=[],E,p=this.graphManager.getGraphs(),m=p.length,y;for(y=0;y<m;y++)E=p[y],E.updateConnected(),E.isConnected||(n=n.concat(E.getNodes()));return n},M.prototype.createBendpoints=function(){var n=[];n=n.concat(this.graphManager.getAllEdges());var E=new Set,p;for(p=0;p<n.length;p++){var m=n[p];if(!E.has(m)){var y=m.getSource(),I=m.getTarget();if(y==I)m.getBendpoints().push(new d),m.getBendpoints().push(new d),this.createDummyNodesForBendpoints(m),E.add(m);else{var O=[];if(O=O.concat(y.getEdgeListToNode(I)),O=O.concat(I.getEdgeListToNode(y)),!E.has(O[0])){if(O.length>1){var R;for(R=0;R<O.length;R++){var W=O[R];W.getBendpoints().push(new d),this.createDummyNodesForBendpoints(W)}}O.forEach(function(x){E.add(x)})}}}if(E.size==n.length)break}},M.prototype.positionNodesRadially=function(n){for(var E=new g(0,0),p=Math.ceil(Math.sqrt(n.length)),m=0,y=0,I=0,O=new d(0,0),R=0;R<n.length;R++){R%p==0&&(I=0,y=m,R!=0&&(y+=o.DEFAULT_COMPONENT_SEPERATION),m=0);var W=n[R],x=S.findCenterOfTree(W);E.x=I,E.y=y,O=M.radialLayout(W,x,E),O.y>m&&(m=Math.floor(O.y)),I=Math.floor(O.x+o.DEFAULT_COMPONENT_SEPERATION)}this.transform(new d(T.WORLD_CENTER_X-O.x/2,T.WORLD_CENTER_Y-O.y/2))},M.radialLayout=function(n,E,p){var m=Math.max(this.maxDiagonalInTree(n),o.DEFAULT_RADIAL_SEPARATION);M.branchRadialLayout(E,null,0,359,0,m);var y=B.calculateBounds(n),I=new U;I.setDeviceOrgX(y.getMinX()),I.setDeviceOrgY(y.getMinY()),I.setWorldOrgX(p.x),I.setWorldOrgY(p.y);for(var O=0;O<n.length;O++){var R=n[O];R.transform(I)}var W=new d(y.getMaxX(),y.getMaxY());return I.inverseTransformPoint(W)},M.branchRadialLayout=function(n,E,p,m,y,I){var O=(m-p+1)/2;O<0&&(O+=180);var R=(O+p)%360,W=R*P.TWO_PI/360,x=y*Math.cos(W),Q=y*Math.sin(W);n.setCenter(x,Q);var z=[];z=z.concat(n.getEdges());var X=z.length;E!=null&&X--;for(var rt=0,$=z.length,D,H=n.getEdgesBetween(E);H.length>1;){var k=H[0];H.splice(0,1);var tt=z.indexOf(k);tt>=0&&z.splice(tt,1),$--,X--}E!=null?D=(z.indexOf(H[0])+1)%$:D=0;for(var ht=Math.abs(m-p)/X,J=D;rt!=X;J=++J%$){var It=z[J].getOtherEnd(n);if(It!=E){var Nt=(p+rt*ht)%360,vt=(Nt+ht)%360;M.branchRadialLayout(It,n,Nt,vt,y+I,I),rt++}}},M.maxDiagonalInTree=function(n){for(var E=w.MIN_VALUE,p=0;p<n.length;p++){var m=n[p],y=m.getDiagonal();y>E&&(E=y)}return E},M.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},M.prototype.groupZeroDegreeMembers=function(){var n=this,E={};this.memberGroups={},this.idToDummyNode={};for(var p=[],m=this.graphManager.getAllNodes(),y=0;y<m.length;y++){var I=m[y],O=I.getParent();this.getNodeDegreeWithChildren(I)===0&&(O.id==null||!this.getToBeTiled(O))&&p.push(I)}for(var y=0;y<p.length;y++){var I=p[y],R=I.getParent().id;typeof E[R]>"u"&&(E[R]=[]),E[R]=E[R].concat(I)}Object.keys(E).forEach(function(W){if(E[W].length>1){var x="DummyCompound_"+W;n.memberGroups[x]=E[W];var Q=E[W][0].getParent(),z=new t(n.graphManager);z.id=x,z.paddingLeft=Q.paddingLeft||0,z.paddingRight=Q.paddingRight||0,z.paddingBottom=Q.paddingBottom||0,z.paddingTop=Q.paddingTop||0,n.idToDummyNode[x]=z;var X=n.getGraphManager().add(n.newGraph(),z),rt=Q.getChild();rt.add(z);for(var $=0;$<E[W].length;$++){var D=E[W][$];rt.remove(D),X.add(D)}}})},M.prototype.clearCompounds=function(){var n={},E={};this.performDFSOnCompounds();for(var p=0;p<this.compoundOrder.length;p++)E[this.compoundOrder[p].id]=this.compoundOrder[p],n[this.compoundOrder[p].id]=[].concat(this.compoundOrder[p].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[p].getChild()),this.compoundOrder[p].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(n,E)},M.prototype.clearZeroDegreeMembers=function(){var n=this,E=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(p){var m=n.idToDummyNode[p];if(E[p]=n.tileNodes(n.memberGroups[p],m.paddingLeft+m.paddingRight),m.rect.width=E[p].width,m.rect.height=E[p].height,m.setCenter(E[p].centerX,E[p].centerY),m.labelMarginLeft=0,m.labelMarginTop=0,o.NODE_DIMENSIONS_INCLUDE_LABELS){var y=m.rect.width,I=m.rect.height;m.labelWidth&&(m.labelPosHorizontal=="left"?(m.rect.x-=m.labelWidth,m.setWidth(y+m.labelWidth),m.labelMarginLeft=m.labelWidth):m.labelPosHorizontal=="center"&&m.labelWidth>y?(m.rect.x-=(m.labelWidth-y)/2,m.setWidth(m.labelWidth),m.labelMarginLeft=(m.labelWidth-y)/2):m.labelPosHorizontal=="right"&&m.setWidth(y+m.labelWidth)),m.labelHeight&&(m.labelPosVertical=="top"?(m.rect.y-=m.labelHeight,m.setHeight(I+m.labelHeight),m.labelMarginTop=m.labelHeight):m.labelPosVertical=="center"&&m.labelHeight>I?(m.rect.y-=(m.labelHeight-I)/2,m.setHeight(m.labelHeight),m.labelMarginTop=(m.labelHeight-I)/2):m.labelPosVertical=="bottom"&&m.setHeight(I+m.labelHeight))}})},M.prototype.repopulateCompounds=function(){for(var n=this.compoundOrder.length-1;n>=0;n--){var E=this.compoundOrder[n],p=E.id,m=E.paddingLeft,y=E.paddingTop,I=E.labelMarginLeft,O=E.labelMarginTop;this.adjustLocations(this.tiledMemberPack[p],E.rect.x,E.rect.y,m,y,I,O)}},M.prototype.repopulateZeroDegreeMembers=function(){var n=this,E=this.tiledZeroDegreePack;Object.keys(E).forEach(function(p){var m=n.idToDummyNode[p],y=m.paddingLeft,I=m.paddingTop,O=m.labelMarginLeft,R=m.labelMarginTop;n.adjustLocations(E[p],m.rect.x,m.rect.y,y,I,O,R)})},M.prototype.getToBeTiled=function(n){var E=n.id;if(this.toBeTiled[E]!=null)return this.toBeTiled[E];var p=n.getChild();if(p==null)return this.toBeTiled[E]=!1,!1;for(var m=p.getNodes(),y=0;y<m.length;y++){var I=m[y];if(this.getNodeDegree(I)>0)return this.toBeTiled[E]=!1,!1;if(I.getChild()==null){this.toBeTiled[I.id]=!1;continue}if(!this.getToBeTiled(I))return this.toBeTiled[E]=!1,!1}return this.toBeTiled[E]=!0,!0},M.prototype.getNodeDegree=function(n){n.id;for(var E=n.getEdges(),p=0,m=0;m<E.length;m++){var y=E[m];y.getSource().id!==y.getTarget().id&&(p=p+1)}return p},M.prototype.getNodeDegreeWithChildren=function(n){var E=this.getNodeDegree(n);if(n.getChild()==null)return E;for(var p=n.getChild().getNodes(),m=0;m<p.length;m++){var y=p[m];E+=this.getNodeDegreeWithChildren(y)}return E},M.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},M.prototype.fillCompexOrderByDFS=function(n){for(var E=0;E<n.length;E++){var p=n[E];p.getChild()!=null&&this.fillCompexOrderByDFS(p.getChild().getNodes()),this.getToBeTiled(p)&&this.compoundOrder.push(p)}},M.prototype.adjustLocations=function(n,E,p,m,y,I,O){E+=m+I,p+=y+O;for(var R=E,W=0;W<n.rows.length;W++){var x=n.rows[W];E=R;for(var Q=0,z=0;z<x.length;z++){var X=x[z];X.rect.x=E,X.rect.y=p,E+=X.rect.width+n.horizontalPadding,X.rect.height>Q&&(Q=X.rect.height)}p+=Q+n.verticalPadding}},M.prototype.tileCompoundMembers=function(n,E){var p=this;this.tiledMemberPack=[],Object.keys(n).forEach(function(m){var y=E[m];if(p.tiledMemberPack[m]=p.tileNodes(n[m],y.paddingLeft+y.paddingRight),y.rect.width=p.tiledMemberPack[m].width,y.rect.height=p.tiledMemberPack[m].height,y.setCenter(p.tiledMemberPack[m].centerX,p.tiledMemberPack[m].centerY),y.labelMarginLeft=0,y.labelMarginTop=0,o.NODE_DIMENSIONS_INCLUDE_LABELS){var I=y.rect.width,O=y.rect.height;y.labelWidth&&(y.labelPosHorizontal=="left"?(y.rect.x-=y.labelWidth,y.setWidth(I+y.labelWidth),y.labelMarginLeft=y.labelWidth):y.labelPosHorizontal=="center"&&y.labelWidth>I?(y.rect.x-=(y.labelWidth-I)/2,y.setWidth(y.labelWidth),y.labelMarginLeft=(y.labelWidth-I)/2):y.labelPosHorizontal=="right"&&y.setWidth(I+y.labelWidth)),y.labelHeight&&(y.labelPosVertical=="top"?(y.rect.y-=y.labelHeight,y.setHeight(O+y.labelHeight),y.labelMarginTop=y.labelHeight):y.labelPosVertical=="center"&&y.labelHeight>O?(y.rect.y-=(y.labelHeight-O)/2,y.setHeight(y.labelHeight),y.labelMarginTop=(y.labelHeight-O)/2):y.labelPosVertical=="bottom"&&y.setHeight(O+y.labelHeight))}})},M.prototype.tileNodes=function(n,E){var p=this.tileNodesByFavoringDim(n,E,!0),m=this.tileNodesByFavoringDim(n,E,!1),y=this.getOrgRatio(p),I=this.getOrgRatio(m),O;return I<y?O=m:O=p,O},M.prototype.getOrgRatio=function(n){var E=n.width,p=n.height,m=E/p;return m<1&&(m=1/m),m},M.prototype.calcIdealRowWidth=function(n,E){var p=o.TILING_PADDING_VERTICAL,m=o.TILING_PADDING_HORIZONTAL,y=n.length,I=0,O=0,R=0;n.forEach(function($){I+=$.getWidth(),O+=$.getHeight(),$.getWidth()>R&&(R=$.getWidth())});var W=I/y,x=O/y,Q=Math.pow(p-m,2)+4*(W+m)*(x+p)*y,z=(m-p+Math.sqrt(Q))/(2*(W+m)),X;E?(X=Math.ceil(z),X==z&&X++):X=Math.floor(z);var rt=X*(W+m)-m;return R>rt&&(rt=R),rt+=m*2,rt},M.prototype.tileNodesByFavoringDim=function(n,E,p){var m=o.TILING_PADDING_VERTICAL,y=o.TILING_PADDING_HORIZONTAL,I=o.TILING_COMPARE_BY,O={rows:[],rowWidth:[],rowHeight:[],width:0,height:E,verticalPadding:m,horizontalPadding:y,centerX:0,centerY:0};I&&(O.idealRowWidth=this.calcIdealRowWidth(n,p));var R=function(D){return D.rect.width*D.rect.height},W=function(D,H){return R(H)-R(D)};n.sort(function($,D){var H=W;return O.idealRowWidth?(H=I,H($.id,D.id)):H($,D)});for(var x=0,Q=0,z=0;z<n.length;z++){var X=n[z];x+=X.getCenterX(),Q+=X.getCenterY()}O.centerX=x/n.length,O.centerY=Q/n.length;for(var z=0;z<n.length;z++){var X=n[z];if(O.rows.length==0)this.insertNodeToRow(O,X,0,E);else if(this.canAddHorizontal(O,X.rect.width,X.rect.height)){var rt=O.rows.length-1;O.idealRowWidth||(rt=this.getShortestRowIndex(O)),this.insertNodeToRow(O,X,rt,E)}else this.insertNodeToRow(O,X,O.rows.length,E);this.shiftToLastRow(O)}return O},M.prototype.insertNodeToRow=function(n,E,p,m){var y=m;if(p==n.rows.length){var I=[];n.rows.push(I),n.rowWidth.push(y),n.rowHeight.push(0)}var O=n.rowWidth[p]+E.rect.width;n.rows[p].length>0&&(O+=n.horizontalPadding),n.rowWidth[p]=O,n.width<O&&(n.width=O);var R=E.rect.height;p>0&&(R+=n.verticalPadding);var W=0;R>n.rowHeight[p]&&(W=n.rowHeight[p],n.rowHeight[p]=R,W=n.rowHeight[p]-W),n.height+=W,n.rows[p].push(E)},M.prototype.getShortestRowIndex=function(n){for(var E=-1,p=Number.MAX_VALUE,m=0;m<n.rows.length;m++)n.rowWidth[m]<p&&(E=m,p=n.rowWidth[m]);return E},M.prototype.getLongestRowIndex=function(n){for(var E=-1,p=Number.MIN_VALUE,m=0;m<n.rows.length;m++)n.rowWidth[m]>p&&(E=m,p=n.rowWidth[m]);return E},M.prototype.canAddHorizontal=function(n,E,p){if(n.idealRowWidth){var m=n.rows.length-1,y=n.rowWidth[m];return y+E+n.horizontalPadding<=n.idealRowWidth}var I=this.getShortestRowIndex(n);if(I<0)return!0;var O=n.rowWidth[I];if(O+n.horizontalPadding+E<=n.width)return!0;var R=0;n.rowHeight[I]<p&&I>0&&(R=p+n.verticalPadding-n.rowHeight[I]);var W;n.width-O>=E+n.horizontalPadding?W=(n.height+R)/(O+E+n.horizontalPadding):W=(n.height+R)/n.width,R=p+n.verticalPadding;var x;return n.width<E?x=(n.height+R)/E:x=(n.height+R)/n.width,x<1&&(x=1/x),W<1&&(W=1/W),W<x},M.prototype.shiftToLastRow=function(n){var E=this.getLongestRowIndex(n),p=n.rowWidth.length-1,m=n.rows[E],y=m[m.length-1],I=y.width+n.horizontalPadding;if(n.width-n.rowWidth[p]>I&&E!=p){m.splice(-1,1),n.rows[p].push(y),n.rowWidth[E]=n.rowWidth[E]-I,n.rowWidth[p]=n.rowWidth[p]+I,n.width=n.rowWidth[instance.getLongestRowIndex(n)];for(var O=Number.MIN_VALUE,R=0;R<m.length;R++)m[R].height>O&&(O=m[R].height);E>0&&(O+=n.verticalPadding);var W=n.rowHeight[E]+n.rowHeight[p];n.rowHeight[E]=O,n.rowHeight[p]<y.height+n.verticalPadding&&(n.rowHeight[p]=y.height+n.verticalPadding);var x=n.rowHeight[E]+n.rowHeight[p];n.height+=x-W,this.shiftToLastRow(n)}},M.prototype.tilingPreLayout=function(){o.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},M.prototype.tilingPostLayout=function(){o.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},M.prototype.reduceTrees=function(){for(var n=[],E=!0,p;E;){var m=this.graphManager.getAllNodes(),y=[];E=!1;for(var I=0;I<m.length;I++)if(p=m[I],p.getEdges().length==1&&!p.getEdges()[0].isInterGraph&&p.getChild()==null){if(o.PURE_INCREMENTAL){var O=p.getEdges()[0].getOtherEnd(p),R=new C(p.getCenterX()-O.getCenterX(),p.getCenterY()-O.getCenterY());y.push([p,p.getEdges()[0],p.getOwner(),R])}else y.push([p,p.getEdges()[0],p.getOwner()]);E=!0}if(E==!0){for(var W=[],x=0;x<y.length;x++)y[x][0].getEdges().length==1&&(W.push(y[x]),y[x][0].getOwner().remove(y[x][0]));n.push(W),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=n},M.prototype.growTree=function(n){for(var E=n.length,p=n[E-1],m,y=0;y<p.length;y++)m=p[y],this.findPlaceforPrunedNode(m),m[2].add(m[0]),m[2].add(m[1],m[1].source,m[1].target);n.splice(n.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},M.prototype.findPlaceforPrunedNode=function(n){var E,p,m=n[0];if(m==n[1].source?p=n[1].target:p=n[1].source,o.PURE_INCREMENTAL)m.setCenter(p.getCenterX()+n[3].getWidth(),p.getCenterY()+n[3].getHeight());else{var y=p.startX,I=p.finishX,O=p.startY,R=p.finishY,W=0,x=0,Q=0,z=0,X=[W,Q,x,z];if(O>0)for(var rt=y;rt<=I;rt++)X[0]+=this.grid[rt][O-1].length+this.grid[rt][O].length-1;if(I<this.grid.length-1)for(var rt=O;rt<=R;rt++)X[1]+=this.grid[I+1][rt].length+this.grid[I][rt].length-1;if(R<this.grid[0].length-1)for(var rt=y;rt<=I;rt++)X[2]+=this.grid[rt][R+1].length+this.grid[rt][R].length-1;if(y>0)for(var rt=O;rt<=R;rt++)X[3]+=this.grid[y-1][rt].length+this.grid[y][rt].length-1;for(var $=w.MAX_VALUE,D,H,k=0;k<X.length;k++)X[k]<$?($=X[k],D=1,H=k):X[k]==$&&D++;if(D==3&&$==0)X[0]==0&&X[1]==0&&X[2]==0?E=1:X[0]==0&&X[1]==0&&X[3]==0?E=0:X[0]==0&&X[2]==0&&X[3]==0?E=3:X[1]==0&&X[2]==0&&X[3]==0&&(E=2);else if(D==2&&$==0){var tt=Math.floor(Math.random()*2);X[0]==0&&X[1]==0?tt==0?E=0:E=1:X[0]==0&&X[2]==0?tt==0?E=0:E=2:X[0]==0&&X[3]==0?tt==0?E=0:E=3:X[1]==0&&X[2]==0?tt==0?E=1:E=2:X[1]==0&&X[3]==0?tt==0?E=1:E=3:tt==0?E=2:E=3}else if(D==4&&$==0){var tt=Math.floor(Math.random()*4);E=tt}else E=H;E==0?m.setCenter(p.getCenterX(),p.getCenterY()-p.getHeight()/2-l.DEFAULT_EDGE_LENGTH-m.getHeight()/2):E==1?m.setCenter(p.getCenterX()+p.getWidth()/2+l.DEFAULT_EDGE_LENGTH+m.getWidth()/2,p.getCenterY()):E==2?m.setCenter(p.getCenterX(),p.getCenterY()+p.getHeight()/2+l.DEFAULT_EDGE_LENGTH+m.getHeight()/2):m.setCenter(p.getCenterX()-p.getWidth()/2-l.DEFAULT_EDGE_LENGTH-m.getWidth()/2,p.getCenterY())}},i.exports=M}),991:((i,r,a)=>{var f=a(551).FDLayoutNode,e=a(551).IMath;function u(s,o,c,l){f.call(this,s,o,c,l)}u.prototype=Object.create(f.prototype);for(var t in f)u[t]=f[t];u.prototype.calculateDisplacement=function(){var s=this.graphManager.getLayout();this.getChild()!=null&&this.fixedNodeWeight?(this.displacementX+=s.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.fixedNodeWeight,this.displacementY+=s.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.fixedNodeWeight):(this.displacementX+=s.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY+=s.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren),Math.abs(this.displacementX)>s.coolingFactor*s.maxNodeDisplacement&&(this.displacementX=s.coolingFactor*s.maxNodeDisplacement*e.sign(this.displacementX)),Math.abs(this.displacementY)>s.coolingFactor*s.maxNodeDisplacement&&(this.displacementY=s.coolingFactor*s.maxNodeDisplacement*e.sign(this.displacementY)),this.child&&this.child.getNodes().length>0&&this.propogateDisplacementToChildren(this.displacementX,this.displacementY)},u.prototype.propogateDisplacementToChildren=function(s,o){for(var c=this.getChild().getNodes(),l,T=0;T<c.length;T++)l=c[T],l.getChild()==null?(l.displacementX+=s,l.displacementY+=o):l.propogateDisplacementToChildren(s,o)},u.prototype.move=function(){var s=this.graphManager.getLayout();(this.child==null||this.child.getNodes().length==0)&&(this.moveBy(this.displacementX,this.displacementY),s.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY)),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},u.prototype.setPred1=function(s){this.pred1=s},u.prototype.getPred1=function(){return pred1},u.prototype.getPred2=function(){return pred2},u.prototype.setNext=function(s){this.next=s},u.prototype.getNext=function(){return next},u.prototype.setProcessed=function(s){this.processed=s},u.prototype.isProcessed=function(){return processed},i.exports=u}),902:((i,r,a)=>{function f(c){if(Array.isArray(c)){for(var l=0,T=Array(c.length);l<c.length;l++)T[l]=c[l];return T}else return Array.from(c)}var e=a(806),u=a(551).LinkedList,t=a(551).Matrix,s=a(551).SVD;function o(){}o.handleConstraints=function(c){var l={};l.fixedNodeConstraint=c.constraints.fixedNodeConstraint,l.alignmentConstraint=c.constraints.alignmentConstraint,l.relativePlacementConstraint=c.constraints.relativePlacementConstraint;for(var T=new Map,g=new Map,d=[],C=[],S=c.getAllNodes(),w=0,P=0;P<S.length;P++){var B=S[P];B.getChild()==null&&(g.set(B.id,w++),d.push(B.getCenterX()),C.push(B.getCenterY()),T.set(B.id,B))}l.relativePlacementConstraint&&l.relativePlacementConstraint.forEach(function(F){!F.gap&&F.gap!=0&&(F.left?F.gap=e.DEFAULT_EDGE_LENGTH+T.get(F.left).getWidth()/2+T.get(F.right).getWidth()/2:F.gap=e.DEFAULT_EDGE_LENGTH+T.get(F.top).getHeight()/2+T.get(F.bottom).getHeight()/2)});var U=function(Y,Z){return{x:Y.x-Z.x,y:Y.y-Z.y}},V=function(Y){var Z=0,K=0;return Y.forEach(function(q){Z+=d[g.get(q)],K+=C[g.get(q)]}),{x:Z/Y.size,y:K/Y.size}},M=function(Y,Z,K,q,at){function ct(lt,ot){var Lt=new Set(lt),ft=!0,st=!1,Xt=void 0;try{for(var Tt=ot[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;Lt.add(Bt)}}catch(bt){st=!0,Xt=bt}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}return Lt}var nt=new Map;Y.forEach(function(lt,ot){nt.set(ot,0)}),Y.forEach(function(lt,ot){lt.forEach(function(Lt){nt.set(Lt.id,nt.get(Lt.id)+1)})});var et=new Map,j=new Map,dt=new u;nt.forEach(function(lt,ot){lt==0?(dt.push(ot),K||(Z=="horizontal"?et.set(ot,g.has(ot)?d[g.get(ot)]:q.get(ot)):et.set(ot,g.has(ot)?C[g.get(ot)]:q.get(ot)))):et.set(ot,Number.NEGATIVE_INFINITY),K&&j.set(ot,new Set([ot]))}),K&&at.forEach(function(lt){var ot=[];if(lt.forEach(function(st){K.has(st)&&ot.push(st)}),ot.length>0){var Lt=0;ot.forEach(function(st){Z=="horizontal"?(et.set(st,g.has(st)?d[g.get(st)]:q.get(st)),Lt+=et.get(st)):(et.set(st,g.has(st)?C[g.get(st)]:q.get(st)),Lt+=et.get(st))}),Lt=Lt/ot.length,lt.forEach(function(st){K.has(st)||et.set(st,Lt)})}else{var ft=0;lt.forEach(function(st){Z=="horizontal"?ft+=g.has(st)?d[g.get(st)]:q.get(st):ft+=g.has(st)?C[g.get(st)]:q.get(st)}),ft=ft/lt.length,lt.forEach(function(st){et.set(st,ft)})}});for(var At=function(){var ot=dt.shift(),Lt=Y.get(ot);Lt.forEach(function(ft){if(et.get(ft.id)<et.get(ot)+ft.gap)if(K&&K.has(ft.id)){var st=void 0;if(Z=="horizontal"?st=g.has(ft.id)?d[g.get(ft.id)]:q.get(ft.id):st=g.has(ft.id)?C[g.get(ft.id)]:q.get(ft.id),et.set(ft.id,st),st<et.get(ot)+ft.gap){var Xt=et.get(ot)+ft.gap-st;j.get(ot).forEach(function(Tt){et.set(Tt,et.get(Tt)-Xt)})}}else et.set(ft.id,et.get(ot)+ft.gap);nt.set(ft.id,nt.get(ft.id)-1),nt.get(ft.id)==0&&dt.push(ft.id),K&&j.set(ft.id,ct(j.get(ot),j.get(ft.id)))})};dt.length!=0;)At();if(K){var pt=new Set;Y.forEach(function(lt,ot){lt.length==0&&pt.add(ot)});var xt=[];j.forEach(function(lt,ot){if(pt.has(ot)){var Lt=!1,ft=!0,st=!1,Xt=void 0;try{for(var Tt=lt[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;K.has(Bt)&&(Lt=!0)}}catch(St){st=!0,Xt=St}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}if(!Lt){var bt=!1,zt=void 0;xt.forEach(function(St,kt){St.has([].concat(f(lt))[0])&&(bt=!0,zt=kt)}),bt?lt.forEach(function(St){xt[zt].add(St)}):xt.push(new Set(lt))}}}),xt.forEach(function(lt,ot){var Lt=Number.POSITIVE_INFINITY,ft=Number.POSITIVE_INFINITY,st=Number.NEGATIVE_INFINITY,Xt=Number.NEGATIVE_INFINITY,Tt=!0,Ct=!1,Bt=void 0;try{for(var bt=lt[Symbol.iterator](),zt;!(Tt=(zt=bt.next()).done);Tt=!0){var St=zt.value,kt=void 0;Z=="horizontal"?kt=g.has(St)?d[g.get(St)]:q.get(St):kt=g.has(St)?C[g.get(St)]:q.get(St);var Kt=et.get(St);kt<Lt&&(Lt=kt),kt>st&&(st=kt),Kt<ft&&(ft=Kt),Kt>Xt&&(Xt=Kt)}}catch(ee){Ct=!0,Bt=ee}finally{try{!Tt&&bt.return&&bt.return()}finally{if(Ct)throw Bt}}var fe=(Lt+st)/2-(ft+Xt)/2,Qt=!0,jt=!1,_t=void 0;try{for(var Jt=lt[Symbol.iterator](),ne;!(Qt=(ne=Jt.next()).done);Qt=!0){var te=ne.value;et.set(te,et.get(te)+fe)}}catch(ee){jt=!0,_t=ee}finally{try{!Qt&&Jt.return&&Jt.return()}finally{if(jt)throw _t}}})}return et},_=function(Y){var Z=0,K=0,q=0,at=0;if(Y.forEach(function(j){j.left?d[g.get(j.left)]-d[g.get(j.right)]>=0?Z++:K++:C[g.get(j.top)]-C[g.get(j.bottom)]>=0?q++:at++}),Z>K&&q>at)for(var ct=0;ct<g.size;ct++)d[ct]=-1*d[ct],C[ct]=-1*C[ct];else if(Z>K)for(var nt=0;nt<g.size;nt++)d[nt]=-1*d[nt];else if(q>at)for(var et=0;et<g.size;et++)C[et]=-1*C[et]},n=function(Y){var Z=[],K=new u,q=new Set,at=0;return Y.forEach(function(ct,nt){if(!q.has(nt)){Z[at]=[];var et=nt;for(K.push(et),q.add(et),Z[at].push(et);K.length!=0;){et=K.shift();var j=Y.get(et);j.forEach(function(dt){q.has(dt.id)||(K.push(dt.id),q.add(dt.id),Z[at].push(dt.id))})}at++}}),Z},E=function(Y){var Z=new Map;return Y.forEach(function(K,q){Z.set(q,[])}),Y.forEach(function(K,q){K.forEach(function(at){Z.get(q).push(at),Z.get(at.id).push({id:q,gap:at.gap,direction:at.direction})})}),Z},p=function(Y){var Z=new Map;return Y.forEach(function(K,q){Z.set(q,[])}),Y.forEach(function(K,q){K.forEach(function(at){Z.get(at.id).push({id:q,gap:at.gap,direction:at.direction})})}),Z},m=[],y=[],I=!1,O=!1,R=new Set,W=new Map,x=new Map,Q=[];if(l.fixedNodeConstraint&&l.fixedNodeConstraint.forEach(function(F){R.add(F.nodeId)}),l.relativePlacementConstraint&&(l.relativePlacementConstraint.forEach(function(F){F.left?(W.has(F.left)?W.get(F.left).push({id:F.right,gap:F.gap,direction:"horizontal"}):W.set(F.left,[{id:F.right,gap:F.gap,direction:"horizontal"}]),W.has(F.right)||W.set(F.right,[])):(W.has(F.top)?W.get(F.top).push({id:F.bottom,gap:F.gap,direction:"vertical"}):W.set(F.top,[{id:F.bottom,gap:F.gap,direction:"vertical"}]),W.has(F.bottom)||W.set(F.bottom,[]))}),x=E(W),Q=n(x)),e.TRANSFORM_ON_CONSTRAINT_HANDLING){if(l.fixedNodeConstraint&&l.fixedNodeConstraint.length>1)l.fixedNodeConstraint.forEach(function(F,Y){m[Y]=[F.position.x,F.position.y],y[Y]=[d[g.get(F.nodeId)],C[g.get(F.nodeId)]]}),I=!0;else if(l.alignmentConstraint)(function(){var F=0;if(l.alignmentConstraint.vertical){for(var Y=l.alignmentConstraint.vertical,Z=function(et){var j=new Set;Y[et].forEach(function(pt){j.add(pt)});var dt=new Set([].concat(f(j)).filter(function(pt){return R.has(pt)})),At=void 0;dt.size>0?At=d[g.get(dt.values().next().value)]:At=V(j).x,Y[et].forEach(function(pt){m[F]=[At,C[g.get(pt)]],y[F]=[d[g.get(pt)],C[g.get(pt)]],F++})},K=0;K<Y.length;K++)Z(K);I=!0}if(l.alignmentConstraint.horizontal){for(var q=l.alignmentConstraint.horizontal,at=function(et){var j=new Set;q[et].forEach(function(pt){j.add(pt)});var dt=new Set([].concat(f(j)).filter(function(pt){return R.has(pt)})),At=void 0;dt.size>0?At=d[g.get(dt.values().next().value)]:At=V(j).y,q[et].forEach(function(pt){m[F]=[d[g.get(pt)],At],y[F]=[d[g.get(pt)],C[g.get(pt)]],F++})},ct=0;ct<q.length;ct++)at(ct);I=!0}l.relativePlacementConstraint&&(O=!0)})();else if(l.relativePlacementConstraint){for(var z=0,X=0,rt=0;rt<Q.length;rt++)Q[rt].length>z&&(z=Q[rt].length,X=rt);if(z<x.size/2)_(l.relativePlacementConstraint),I=!1,O=!1;else{var $=new Map,D=new Map,H=[];Q[X].forEach(function(F){W.get(F).forEach(function(Y){Y.direction=="horizontal"?($.has(F)?$.get(F).push(Y):$.set(F,[Y]),$.has(Y.id)||$.set(Y.id,[]),H.push({left:F,right:Y.id})):(D.has(F)?D.get(F).push(Y):D.set(F,[Y]),D.has(Y.id)||D.set(Y.id,[]),H.push({top:F,bottom:Y.id}))})}),_(H),O=!1;var k=M($,"horizontal"),tt=M(D,"vertical");Q[X].forEach(function(F,Y){y[Y]=[d[g.get(F)],C[g.get(F)]],m[Y]=[],k.has(F)?m[Y][0]=k.get(F):m[Y][0]=d[g.get(F)],tt.has(F)?m[Y][1]=tt.get(F):m[Y][1]=C[g.get(F)]}),I=!0}}if(I){for(var ht=void 0,J=t.transpose(m),It=t.transpose(y),Nt=0;Nt<J.length;Nt++)J[Nt]=t.multGamma(J[Nt]),It[Nt]=t.multGamma(It[Nt]);var vt=t.multMat(J,t.transpose(It)),it=s.svd(vt);ht=t.multMat(it.V,t.transpose(it.U));for(var ut=0;ut<g.size;ut++){var Et=[d[ut],C[ut]],wt=[ht[0][0],ht[1][0]],Ot=[ht[0][1],ht[1][1]];d[ut]=t.dotProduct(Et,wt),C[ut]=t.dotProduct(Et,Ot)}O&&_(l.relativePlacementConstraint)}}if(e.ENFORCE_CONSTRAINTS){if(l.fixedNodeConstraint&&l.fixedNodeConstraint.length>0){var mt={x:0,y:0};l.fixedNodeConstraint.forEach(function(F,Y){var Z={x:d[g.get(F.nodeId)],y:C[g.get(F.nodeId)]},K=F.position,q=U(K,Z);mt.x+=q.x,mt.y+=q.y}),mt.x/=l.fixedNodeConstraint.length,mt.y/=l.fixedNodeConstraint.length,d.forEach(function(F,Y){d[Y]+=mt.x}),C.forEach(function(F,Y){C[Y]+=mt.y}),l.fixedNodeConstraint.forEach(function(F){d[g.get(F.nodeId)]=F.position.x,C[g.get(F.nodeId)]=F.position.y})}if(l.alignmentConstraint){if(l.alignmentConstraint.vertical)for(var Dt=l.alignmentConstraint.vertical,Rt=function(Y){var Z=new Set;Dt[Y].forEach(function(at){Z.add(at)});var K=new Set([].concat(f(Z)).filter(function(at){return R.has(at)})),q=void 0;K.size>0?q=d[g.get(K.values().next().value)]:q=V(Z).x,Z.forEach(function(at){R.has(at)||(d[g.get(at)]=q)})},Ht=0;Ht<Dt.length;Ht++)Rt(Ht);if(l.alignmentConstraint.horizontal)for(var Ut=l.alignmentConstraint.horizontal,Pt=function(Y){var Z=new Set;Ut[Y].forEach(function(at){Z.add(at)});var K=new Set([].concat(f(Z)).filter(function(at){return R.has(at)})),q=void 0;K.size>0?q=C[g.get(K.values().next().value)]:q=V(Z).y,Z.forEach(function(at){R.has(at)||(C[g.get(at)]=q)})},Ft=0;Ft<Ut.length;Ft++)Pt(Ft)}l.relativePlacementConstraint&&(function(){var F=new Map,Y=new Map,Z=new Map,K=new Map,q=new Map,at=new Map,ct=new Set,nt=new Set;if(R.forEach(function(Gt){ct.add(Gt),nt.add(Gt)}),l.alignmentConstraint){if(l.alignmentConstraint.vertical)for(var et=l.alignmentConstraint.vertical,j=function(yt){Z.set("dummy"+yt,[]),et[yt].forEach(function(Mt){F.set(Mt,"dummy"+yt),Z.get("dummy"+yt).push(Mt),R.has(Mt)&&ct.add("dummy"+yt)}),q.set("dummy"+yt,d[g.get(et[yt][0])])},dt=0;dt<et.length;dt++)j(dt);if(l.alignmentConstraint.horizontal)for(var At=l.alignmentConstraint.horizontal,pt=function(yt){K.set("dummy"+yt,[]),At[yt].forEach(function(Mt){Y.set(Mt,"dummy"+yt),K.get("dummy"+yt).push(Mt),R.has(Mt)&&nt.add("dummy"+yt)}),at.set("dummy"+yt,C[g.get(At[yt][0])])},xt=0;xt<At.length;xt++)pt(xt)}var lt=new Map,ot=new Map,Lt=function(yt){W.get(yt).forEach(function(Mt){var Zt=void 0,$t=void 0;Mt.direction=="horizontal"?(Zt=F.get(yt)?F.get(yt):yt,F.get(Mt.id)?$t={id:F.get(Mt.id),gap:Mt.gap,direction:Mt.direction}:$t=Mt,lt.has(Zt)?lt.get(Zt).push($t):lt.set(Zt,[$t]),lt.has($t.id)||lt.set($t.id,[])):(Zt=Y.get(yt)?Y.get(yt):yt,Y.get(Mt.id)?$t={id:Y.get(Mt.id),gap:Mt.gap,direction:Mt.direction}:$t=Mt,ot.has(Zt)?ot.get(Zt).push($t):ot.set(Zt,[$t]),ot.has($t.id)||ot.set($t.id,[]))})},ft=!0,st=!1,Xt=void 0;try{for(var Tt=W.keys()[Symbol.iterator](),Ct;!(ft=(Ct=Tt.next()).done);ft=!0){var Bt=Ct.value;Lt(Bt)}}catch(Gt){st=!0,Xt=Gt}finally{try{!ft&&Tt.return&&Tt.return()}finally{if(st)throw Xt}}var bt=E(lt),zt=E(ot),St=n(bt),kt=n(zt),Kt=p(lt),fe=p(ot),Qt=[],jt=[];St.forEach(function(Gt,yt){Qt[yt]=[],Gt.forEach(function(Mt){Kt.get(Mt).length==0&&Qt[yt].push(Mt)})}),kt.forEach(function(Gt,yt){jt[yt]=[],Gt.forEach(function(Mt){fe.get(Mt).length==0&&jt[yt].push(Mt)})});var _t=M(lt,"horizontal",ct,q,Qt),Jt=M(ot,"vertical",nt,at,jt),ne=function(yt){Z.get(yt)?Z.get(yt).forEach(function(Mt){d[g.get(Mt)]=_t.get(yt)}):d[g.get(yt)]=_t.get(yt)},te=!0,ee=!1,Ne=void 0;try{for(var ce=_t.keys()[Symbol.iterator](),Le;!(te=(Le=ce.next()).done);te=!0){var ge=Le.value;ne(ge)}}catch(Gt){ee=!0,Ne=Gt}finally{try{!te&&ce.return&&ce.return()}finally{if(ee)throw Ne}}var $e=function(yt){K.get(yt)?K.get(yt).forEach(function(Mt){C[g.get(Mt)]=Jt.get(yt)}):C[g.get(yt)]=Jt.get(yt)},ue=!0,Ce=!1,we=void 0;try{for(var de=Jt.keys()[Symbol.iterator](),Ae;!(ue=(Ae=de.next()).done);ue=!0){var ge=Ae.value;$e(ge)}}catch(Gt){Ce=!0,we=Gt}finally{try{!ue&&de.return&&de.return()}finally{if(Ce)throw we}}})()}for(var Yt=0;Yt<S.length;Yt++){var Vt=S[Yt];Vt.getChild()==null&&Vt.setCenter(d[g.get(Vt.id)],C[g.get(Vt.id)])}},i.exports=o}),551:(i=>{i.exports=A})},N={};function v(i){var r=N[i];if(r!==void 0)return r.exports;var a=N[i]={exports:{}};return G[i](a,a.exports,v),a.exports}var h=v(45);return h})()})})(he)),he.exports}var pr=se.exports,De;function yr(){return De||(De=1,(function(L,b){(function(G,N){L.exports=N(vr())})(pr,function(A){return(()=>{var G={658:(i=>{i.exports=Object.assign!=null?Object.assign.bind(Object):function(r){for(var a=arguments.length,f=Array(a>1?a-1:0),e=1;e<a;e++)f[e-1]=arguments[e];return f.forEach(function(u){Object.keys(u).forEach(function(t){return r[t]=u[t]})}),r}}),548:((i,r,a)=>{var f=(function(){function t(s,o){var c=[],l=!0,T=!1,g=void 0;try{for(var d=s[Symbol.iterator](),C;!(l=(C=d.next()).done)&&(c.push(C.value),!(o&&c.length===o));l=!0);}catch(S){T=!0,g=S}finally{try{!l&&d.return&&d.return()}finally{if(T)throw g}}return c}return function(s,o){if(Array.isArray(s))return s;if(Symbol.iterator in Object(s))return t(s,o);throw new TypeError("Invalid attempt to destructure non-iterable instance")}})(),e=a(140).layoutBase.LinkedList,u={};u.getTopMostNodes=function(t){for(var s={},o=0;o<t.length;o++)s[t[o].id()]=!0;var c=t.filter(function(l,T){typeof l=="number"&&(l=T);for(var g=l.parent()[0];g!=null;){if(s[g.id()])return!1;g=g.parent()[0]}return!0});return c},u.connectComponents=function(t,s,o,c){var l=new e,T=new Set,g=[],d=void 0,C=void 0,S=void 0,w=!1,P=1,B=[],U=[],V=function(){var _=t.collection();U.push(_);var n=o[0],E=t.collection();E.merge(n).merge(n.descendants().intersection(s)),g.push(n),E.forEach(function(y){l.push(y),T.add(y),_.merge(y)});for(var p=function(){n=l.shift();var I=t.collection();n.neighborhood().nodes().forEach(function(x){s.intersection(n.edgesWith(x)).length>0&&I.merge(x)});for(var O=0;O<I.length;O++){var R=I[O];if(d=o.intersection(R.union(R.ancestors())),d!=null&&!T.has(d[0])){var W=d.union(d.descendants());W.forEach(function(x){l.push(x),T.add(x),_.merge(x),o.has(x)&&g.push(x)})}}};l.length!=0;)p();if(_.forEach(function(y){s.intersection(y.connectedEdges()).forEach(function(I){_.has(I.source())&&_.has(I.target())&&_.merge(I)})}),g.length==o.length&&(w=!0),!w||w&&P>1){C=g[0],S=C.connectedEdges().length,g.forEach(function(y){y.connectedEdges().length<S&&(S=y.connectedEdges().length,C=y)}),B.push(C.id());var m=t.collection();m.merge(g[0]),g.forEach(function(y){m.merge(y)}),g=[],o=o.difference(m),P++}};do V();while(!w);return c&&B.length>0&&c.set("dummy"+(c.size+1),B),U},u.relocateComponent=function(t,s,o){if(!o.fixedNodeConstraint){var c=Number.POSITIVE_INFINITY,l=Number.NEGATIVE_INFINITY,T=Number.POSITIVE_INFINITY,g=Number.NEGATIVE_INFINITY;if(o.quality=="draft"){var d=!0,C=!1,S=void 0;try{for(var w=s.nodeIndexes[Symbol.iterator](),P;!(d=(P=w.next()).done);d=!0){var B=P.value,U=f(B,2),V=U[0],M=U[1],_=o.cy.getElementById(V);if(_){var n=_.boundingBox(),E=s.xCoords[M]-n.w/2,p=s.xCoords[M]+n.w/2,m=s.yCoords[M]-n.h/2,y=s.yCoords[M]+n.h/2;E<c&&(c=E),p>l&&(l=p),m<T&&(T=m),y>g&&(g=y)}}}catch(x){C=!0,S=x}finally{try{!d&&w.return&&w.return()}finally{if(C)throw S}}var I=t.x-(l+c)/2,O=t.y-(g+T)/2;s.xCoords=s.xCoords.map(function(x){return x+I}),s.yCoords=s.yCoords.map(function(x){return x+O})}else{Object.keys(s).forEach(function(x){var Q=s[x],z=Q.getRect().x,X=Q.getRect().x+Q.getRect().width,rt=Q.getRect().y,$=Q.getRect().y+Q.getRect().height;z<c&&(c=z),X>l&&(l=X),rt<T&&(T=rt),$>g&&(g=$)});var R=t.x-(l+c)/2,W=t.y-(g+T)/2;Object.keys(s).forEach(function(x){var Q=s[x];Q.setCenter(Q.getCenterX()+R,Q.getCenterY()+W)})}}},u.calcBoundingBox=function(t,s,o,c){for(var l=Number.MAX_SAFE_INTEGER,T=Number.MIN_SAFE_INTEGER,g=Number.MAX_SAFE_INTEGER,d=Number.MIN_SAFE_INTEGER,C=void 0,S=void 0,w=void 0,P=void 0,B=t.descendants().not(":parent"),U=B.length,V=0;V<U;V++){var M=B[V];C=s[c.get(M.id())]-M.width()/2,S=s[c.get(M.id())]+M.width()/2,w=o[c.get(M.id())]-M.height()/2,P=o[c.get(M.id())]+M.height()/2,l>C&&(l=C),T<S&&(T=S),g>w&&(g=w),d<P&&(d=P)}var _={};return _.topLeftX=l,_.topLeftY=g,_.width=T-l,_.height=d-g,_},u.calcParentsWithoutChildren=function(t,s){var o=t.collection();return s.nodes(":parent").forEach(function(c){var l=!1;c.children().forEach(function(T){T.css("display")!="none"&&(l=!0)}),l||o.merge(c)}),o},i.exports=u}),816:((i,r,a)=>{var f=a(548),e=a(140).CoSELayout,u=a(140).CoSENode,t=a(140).layoutBase.PointD,s=a(140).layoutBase.DimensionD,o=a(140).layoutBase.LayoutConstants,c=a(140).layoutBase.FDLayoutConstants,l=a(140).CoSEConstants,T=function(d,C){var S=d.cy,w=d.eles,P=w.nodes(),B=w.edges(),U=void 0,V=void 0,M=void 0,_={};d.randomize&&(U=C.nodeIndexes,V=C.xCoords,M=C.yCoords);var n=function(x){return typeof x=="function"},E=function(x,Q){return n(x)?x(Q):x},p=f.calcParentsWithoutChildren(S,w),m=function W(x,Q,z,X){for(var rt=Q.length,$=0;$<rt;$++){var D=Q[$],H=null;D.intersection(p).length==0&&(H=D.children());var k=void 0,tt=D.layoutDimensions({nodeDimensionsIncludeLabels:X.nodeDimensionsIncludeLabels});if(D.outerWidth()!=null&&D.outerHeight()!=null)if(X.randomize)if(!D.isParent())k=x.add(new u(z.graphManager,new t(V[U.get(D.id())]-tt.w/2,M[U.get(D.id())]-tt.h/2),new s(parseFloat(tt.w),parseFloat(tt.h))));else{var ht=f.calcBoundingBox(D,V,M,U);D.intersection(p).length==0?k=x.add(new u(z.graphManager,new t(ht.topLeftX,ht.topLeftY),new s(ht.width,ht.height))):k=x.add(new u(z.graphManager,new t(ht.topLeftX,ht.topLeftY),new s(parseFloat(tt.w),parseFloat(tt.h))))}else k=x.add(new u(z.graphManager,new t(D.position("x")-tt.w/2,D.position("y")-tt.h/2),new s(parseFloat(tt.w),parseFloat(tt.h))));else k=x.add(new u(this.graphManager));if(k.id=D.data("id"),k.nodeRepulsion=E(X.nodeRepulsion,D),k.paddingLeft=parseInt(D.css("padding")),k.paddingTop=parseInt(D.css("padding")),k.paddingRight=parseInt(D.css("padding")),k.paddingBottom=parseInt(D.css("padding")),X.nodeDimensionsIncludeLabels&&(k.labelWidth=D.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).w,k.labelHeight=D.boundingBox({includeLabels:!0,includeNodes:!1,includeOverlays:!1}).h,k.labelPosVertical=D.css("text-valign"),k.labelPosHorizontal=D.css("text-halign")),_[D.data("id")]=k,isNaN(k.rect.x)&&(k.rect.x=0),isNaN(k.rect.y)&&(k.rect.y=0),H!=null&&H.length>0){var J=void 0;J=z.getGraphManager().add(z.newGraph(),k),W(J,H,z,X)}}},y=function(x,Q,z){for(var X=0,rt=0,$=0;$<z.length;$++){var D=z[$],H=_[D.data("source")],k=_[D.data("target")];if(H&&k&&H!==k&&H.getEdgesBetween(k).length==0){var tt=Q.add(x.newEdge(),H,k);tt.id=D.id(),tt.idealLength=E(d.idealEdgeLength,D),tt.edgeElasticity=E(d.edgeElasticity,D),X+=tt.idealLength,rt++}}d.idealEdgeLength!=null&&(rt>0?l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=X/rt:n(d.idealEdgeLength)?l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=50:l.DEFAULT_EDGE_LENGTH=c.DEFAULT_EDGE_LENGTH=d.idealEdgeLength,l.MIN_REPULSION_DIST=c.MIN_REPULSION_DIST=c.DEFAULT_EDGE_LENGTH/10,l.DEFAULT_RADIAL_SEPARATION=c.DEFAULT_EDGE_LENGTH)},I=function(x,Q){Q.fixedNodeConstraint&&(x.constraints.fixedNodeConstraint=Q.fixedNodeConstraint),Q.alignmentConstraint&&(x.constraints.alignmentConstraint=Q.alignmentConstraint),Q.relativePlacementConstraint&&(x.constraints.relativePlacementConstraint=Q.relativePlacementConstraint)};d.nestingFactor!=null&&(l.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=c.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=d.nestingFactor),d.gravity!=null&&(l.DEFAULT_GRAVITY_STRENGTH=c.DEFAULT_GRAVITY_STRENGTH=d.gravity),d.numIter!=null&&(l.MAX_ITERATIONS=c.MAX_ITERATIONS=d.numIter),d.gravityRange!=null&&(l.DEFAULT_GRAVITY_RANGE_FACTOR=c.DEFAULT_GRAVITY_RANGE_FACTOR=d.gravityRange),d.gravityCompound!=null&&(l.DEFAULT_COMPOUND_GRAVITY_STRENGTH=c.DEFAULT_COMPOUND_GRAVITY_STRENGTH=d.gravityCompound),d.gravityRangeCompound!=null&&(l.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=c.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=d.gravityRangeCompound),d.initialEnergyOnIncremental!=null&&(l.DEFAULT_COOLING_FACTOR_INCREMENTAL=c.DEFAULT_COOLING_FACTOR_INCREMENTAL=d.initialEnergyOnIncremental),d.tilingCompareBy!=null&&(l.TILING_COMPARE_BY=d.tilingCompareBy),d.quality=="proof"?o.QUALITY=2:o.QUALITY=0,l.NODE_DIMENSIONS_INCLUDE_LABELS=c.NODE_DIMENSIONS_INCLUDE_LABELS=o.NODE_DIMENSIONS_INCLUDE_LABELS=d.nodeDimensionsIncludeLabels,l.DEFAULT_INCREMENTAL=c.DEFAULT_INCREMENTAL=o.DEFAULT_INCREMENTAL=!d.randomize,l.ANIMATE=c.ANIMATE=o.ANIMATE=d.animate,l.TILE=d.tile,l.TILING_PADDING_VERTICAL=typeof d.tilingPaddingVertical=="function"?d.tilingPaddingVertical.call():d.tilingPaddingVertical,l.TILING_PADDING_HORIZONTAL=typeof d.tilingPaddingHorizontal=="function"?d.tilingPaddingHorizontal.call():d.tilingPaddingHorizontal,l.DEFAULT_INCREMENTAL=c.DEFAULT_INCREMENTAL=o.DEFAULT_INCREMENTAL=!0,l.PURE_INCREMENTAL=!d.randomize,o.DEFAULT_UNIFORM_LEAF_NODE_SIZES=d.uniformNodeDimensions,d.step=="transformed"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!0,l.ENFORCE_CONSTRAINTS=!1,l.APPLY_LAYOUT=!1),d.step=="enforced"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!0,l.APPLY_LAYOUT=!1),d.step=="cose"&&(l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!1,l.APPLY_LAYOUT=!0),d.step=="all"&&(d.randomize?l.TRANSFORM_ON_CONSTRAINT_HANDLING=!0:l.TRANSFORM_ON_CONSTRAINT_HANDLING=!1,l.ENFORCE_CONSTRAINTS=!0,l.APPLY_LAYOUT=!0),d.fixedNodeConstraint||d.alignmentConstraint||d.relativePlacementConstraint?l.TREE_REDUCTION_ON_INCREMENTAL=!1:l.TREE_REDUCTION_ON_INCREMENTAL=!0;var O=new e,R=O.newGraphManager();return m(R.addRoot(),f.getTopMostNodes(P),O,d),y(O,R,B),I(O,d),O.runLayout(),_};i.exports={coseLayout:T}}),212:((i,r,a)=>{var f=(function(){function d(C,S){for(var w=0;w<S.length;w++){var P=S[w];P.enumerable=P.enumerable||!1,P.configurable=!0,"value"in P&&(P.writable=!0),Object.defineProperty(C,P.key,P)}}return function(C,S,w){return S&&d(C.prototype,S),w&&d(C,w),C}})();function e(d,C){if(!(d instanceof C))throw new TypeError("Cannot call a class as a function")}var u=a(658),t=a(548),s=a(657),o=s.spectralLayout,c=a(816),l=c.coseLayout,T=Object.freeze({quality:"default",randomize:!0,animate:!0,animationDuration:1e3,animationEasing:void 0,fit:!0,padding:30,nodeDimensionsIncludeLabels:!1,uniformNodeDimensions:!1,packComponents:!0,step:"all",samplingType:!0,sampleSize:25,nodeSeparation:75,piTol:1e-7,nodeRepulsion:function(C){return 4500},idealEdgeLength:function(C){return 50},edgeElasticity:function(C){return .45},nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,tilingCompareBy:void 0,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.3,fixedNodeConstraint:void 0,alignmentConstraint:void 0,relativePlacementConstraint:void 0,ready:function(){},stop:function(){}}),g=(function(){function d(C){e(this,d),this.options=u({},T,C)}return f(d,[{key:"run",value:function(){var S=this,w=this.options,P=w.cy,B=w.eles,U=[],V=[],M=void 0,_=[];w.fixedNodeConstraint&&(!Array.isArray(w.fixedNodeConstraint)||w.fixedNodeConstraint.length==0)&&(w.fixedNodeConstraint=void 0),w.alignmentConstraint&&(w.alignmentConstraint.vertical&&(!Array.isArray(w.alignmentConstraint.vertical)||w.alignmentConstraint.vertical.length==0)&&(w.alignmentConstraint.vertical=void 0),w.alignmentConstraint.horizontal&&(!Array.isArray(w.alignmentConstraint.horizontal)||w.alignmentConstraint.horizontal.length==0)&&(w.alignmentConstraint.horizontal=void 0)),w.relativePlacementConstraint&&(!Array.isArray(w.relativePlacementConstraint)||w.relativePlacementConstraint.length==0)&&(w.relativePlacementConstraint=void 0);var n=w.fixedNodeConstraint||w.alignmentConstraint||w.relativePlacementConstraint;n&&(w.tile=!1,w.packComponents=!1);var E=void 0,p=!1;if(P.layoutUtilities&&w.packComponents&&(E=P.layoutUtilities("get"),E||(E=P.layoutUtilities()),p=!0),B.nodes().length>0)if(p){var I=t.getTopMostNodes(w.eles.nodes());if(M=t.connectComponents(P,w.eles,I),M.forEach(function(vt){var it=vt.boundingBox();_.push({x:it.x1+it.w/2,y:it.y1+it.h/2})}),w.randomize&&M.forEach(function(vt){w.eles=vt,U.push(o(w))}),w.quality=="default"||w.quality=="proof"){var O=P.collection();if(w.tile){var R=new Map,W=[],x=[],Q=0,z={nodeIndexes:R,xCoords:W,yCoords:x},X=[];if(M.forEach(function(vt,it){vt.edges().length==0&&(vt.nodes().forEach(function(ut,Et){O.merge(vt.nodes()[Et]),ut.isParent()||(z.nodeIndexes.set(vt.nodes()[Et].id(),Q++),z.xCoords.push(vt.nodes()[0].position().x),z.yCoords.push(vt.nodes()[0].position().y))}),X.push(it))}),O.length>1){var rt=O.boundingBox();_.push({x:rt.x1+rt.w/2,y:rt.y1+rt.h/2}),M.push(O),U.push(z);for(var $=X.length-1;$>=0;$--)M.splice(X[$],1),U.splice(X[$],1),_.splice(X[$],1)}}M.forEach(function(vt,it){w.eles=vt,V.push(l(w,U[it])),t.relocateComponent(_[it],V[it],w)})}else M.forEach(function(vt,it){t.relocateComponent(_[it],U[it],w)});var D=new Set;if(M.length>1){var H=[],k=B.filter(function(vt){return vt.css("display")=="none"});M.forEach(function(vt,it){var ut=void 0;if(w.quality=="draft"&&(ut=U[it].nodeIndexes),vt.nodes().not(k).length>0){var Et={};Et.edges=[],Et.nodes=[];var wt=void 0;vt.nodes().not(k).forEach(function(Ot){if(w.quality=="draft")if(!Ot.isParent())wt=ut.get(Ot.id()),Et.nodes.push({x:U[it].xCoords[wt]-Ot.boundingbox().w/2,y:U[it].yCoords[wt]-Ot.boundingbox().h/2,width:Ot.boundingbox().w,height:Ot.boundingbox().h});else{var mt=t.calcBoundingBox(Ot,U[it].xCoords,U[it].yCoords,ut);Et.nodes.push({x:mt.topLeftX,y:mt.topLeftY,width:mt.width,height:mt.height})}else V[it][Ot.id()]&&Et.nodes.push({x:V[it][Ot.id()].getLeft(),y:V[it][Ot.id()].getTop(),width:V[it][Ot.id()].getWidth(),height:V[it][Ot.id()].getHeight()})}),vt.edges().forEach(function(Ot){var mt=Ot.source(),Dt=Ot.target();if(mt.css("display")!="none"&&Dt.css("display")!="none")if(w.quality=="draft"){var Rt=ut.get(mt.id()),Ht=ut.get(Dt.id()),Ut=[],Pt=[];if(mt.isParent()){var Ft=t.calcBoundingBox(mt,U[it].xCoords,U[it].yCoords,ut);Ut.push(Ft.topLeftX+Ft.width/2),Ut.push(Ft.topLeftY+Ft.height/2)}else Ut.push(U[it].xCoords[Rt]),Ut.push(U[it].yCoords[Rt]);if(Dt.isParent()){var Yt=t.calcBoundingBox(Dt,U[it].xCoords,U[it].yCoords,ut);Pt.push(Yt.topLeftX+Yt.width/2),Pt.push(Yt.topLeftY+Yt.height/2)}else Pt.push(U[it].xCoords[Ht]),Pt.push(U[it].yCoords[Ht]);Et.edges.push({startX:Ut[0],startY:Ut[1],endX:Pt[0],endY:Pt[1]})}else V[it][mt.id()]&&V[it][Dt.id()]&&Et.edges.push({startX:V[it][mt.id()].getCenterX(),startY:V[it][mt.id()].getCenterY(),endX:V[it][Dt.id()].getCenterX(),endY:V[it][Dt.id()].getCenterY()})}),Et.nodes.length>0&&(H.push(Et),D.add(it))}});var tt=E.packComponents(H,w.randomize).shifts;if(w.quality=="draft")U.forEach(function(vt,it){var ut=vt.xCoords.map(function(wt){return wt+tt[it].dx}),Et=vt.yCoords.map(function(wt){return wt+tt[it].dy});vt.xCoords=ut,vt.yCoords=Et});else{var ht=0;D.forEach(function(vt){Object.keys(V[vt]).forEach(function(it){var ut=V[vt][it];ut.setCenter(ut.getCenterX()+tt[ht].dx,ut.getCenterY()+tt[ht].dy)}),ht++})}}}else{var m=w.eles.boundingBox();if(_.push({x:m.x1+m.w/2,y:m.y1+m.h/2}),w.randomize){var y=o(w);U.push(y)}w.quality=="default"||w.quality=="proof"?(V.push(l(w,U[0])),t.relocateComponent(_[0],V[0],w)):t.relocateComponent(_[0],U[0],w)}var J=function(it,ut){if(w.quality=="default"||w.quality=="proof"){typeof it=="number"&&(it=ut);var Et=void 0,wt=void 0,Ot=it.data("id");return V.forEach(function(Dt){Ot in Dt&&(Et={x:Dt[Ot].getRect().getCenterX(),y:Dt[Ot].getRect().getCenterY()},wt=Dt[Ot])}),w.nodeDimensionsIncludeLabels&&(wt.labelWidth&&(wt.labelPosHorizontal=="left"?Et.x+=wt.labelWidth/2:wt.labelPosHorizontal=="right"&&(Et.x-=wt.labelWidth/2)),wt.labelHeight&&(wt.labelPosVertical=="top"?Et.y+=wt.labelHeight/2:wt.labelPosVertical=="bottom"&&(Et.y-=wt.labelHeight/2))),Et==null&&(Et={x:it.position("x"),y:it.position("y")}),{x:Et.x,y:Et.y}}else{var mt=void 0;return U.forEach(function(Dt){var Rt=Dt.nodeIndexes.get(it.id());Rt!=null&&(mt={x:Dt.xCoords[Rt],y:Dt.yCoords[Rt]})}),mt==null&&(mt={x:it.position("x"),y:it.position("y")}),{x:mt.x,y:mt.y}}};if(w.quality=="default"||w.quality=="proof"||w.randomize){var It=t.calcParentsWithoutChildren(P,B),Nt=B.filter(function(vt){return vt.css("display")=="none"});w.eles=B.not(Nt),B.nodes().not(":parent").not(Nt).layoutPositions(S,w,J),It.length>0&&It.forEach(function(vt){vt.position(J(vt))})}else console.log("If randomize option is set to false, then quality option must be 'default' or 'proof'.")}}]),d})();i.exports=g}),657:((i,r,a)=>{var f=a(548),e=a(140).layoutBase.Matrix,u=a(140).layoutBase.SVD,t=function(o){var c=o.cy,l=o.eles,T=l.nodes(),g=l.nodes(":parent"),d=new Map,C=new Map,S=new Map,w=[],P=[],B=[],U=[],V=[],M=[],_=[],n=[],E=void 0,p=1e8,m=1e-9,y=o.piTol,I=o.samplingType,O=o.nodeSeparation,R=void 0,W=function(){for(var Y=0,Z=0,K=!1;Z<R;){Y=Math.floor(Math.random()*E),K=!1;for(var q=0;q<Z;q++)if(U[q]==Y){K=!0;break}if(!K)U[Z]=Y,Z++;else continue}},x=function(Y,Z,K){for(var q=[],at=0,ct=0,nt=0,et=void 0,j=[],dt=0,At=1,pt=0;pt<E;pt++)j[pt]=p;for(q[ct]=Y,j[Y]=0;ct>=at;){nt=q[at++];for(var xt=w[nt],lt=0;lt<xt.length;lt++)et=C.get(xt[lt]),j[et]==p&&(j[et]=j[nt]+1,q[++ct]=et);M[nt][Z]=j[nt]*O}if(K){for(var ot=0;ot<E;ot++)M[ot][Z]<V[ot]&&(V[ot]=M[ot][Z]);for(var Lt=0;Lt<E;Lt++)V[Lt]>dt&&(dt=V[Lt],At=Lt)}return At},Q=function(Y){var Z=void 0;if(Y){Z=Math.floor(Math.random()*E);for(var q=0;q<E;q++)V[q]=p;for(var at=0;at<R;at++)U[at]=Z,Z=x(Z,at,Y)}else{W();for(var K=0;K<R;K++)x(U[K],K,Y)}for(var ct=0;ct<E;ct++)for(var nt=0;nt<R;nt++)M[ct][nt]*=M[ct][nt];for(var et=0;et<R;et++)_[et]=[];for(var j=0;j<R;j++)for(var dt=0;dt<R;dt++)_[j][dt]=M[U[dt]][j]},z=function(){for(var Y=u.svd(_),Z=Y.S,K=Y.U,q=Y.V,at=Z[0]*Z[0]*Z[0],ct=[],nt=0;nt<R;nt++){ct[nt]=[];for(var et=0;et<R;et++)ct[nt][et]=0,nt==et&&(ct[nt][et]=Z[nt]/(Z[nt]*Z[nt]+at/(Z[nt]*Z[nt])))}n=e.multMat(e.multMat(q,ct),e.transpose(K))},X=function(){for(var Y=void 0,Z=void 0,K=[],q=[],at=[],ct=[],nt=0;nt<E;nt++)K[nt]=Math.random(),q[nt]=Math.random();K=e.normalize(K),q=e.normalize(q);for(var et=m,j=m,dt=void 0;;){for(var At=0;At<E;At++)at[At]=K[At];if(K=e.multGamma(e.multL(e.multGamma(at),M,n)),Y=e.dotProduct(at,K),K=e.normalize(K),et=e.dotProduct(at,K),dt=Math.abs(et/j),dt<=1+y&&dt>=1)break;j=et}for(var pt=0;pt<E;pt++)at[pt]=K[pt];for(j=m;;){for(var xt=0;xt<E;xt++)ct[xt]=q[xt];if(ct=e.minusOp(ct,e.multCons(at,e.dotProduct(at,ct))),q=e.multGamma(e.multL(e.multGamma(ct),M,n)),Z=e.dotProduct(ct,q),q=e.normalize(q),et=e.dotProduct(ct,q),dt=Math.abs(et/j),dt<=1+y&&dt>=1)break;j=et}for(var lt=0;lt<E;lt++)ct[lt]=q[lt];P=e.multCons(at,Math.sqrt(Math.abs(Y))),B=e.multCons(ct,Math.sqrt(Math.abs(Z)))};f.connectComponents(c,l,f.getTopMostNodes(T),d),g.forEach(function(F){f.connectComponents(c,l,f.getTopMostNodes(F.descendants().intersection(l)),d)});for(var rt=0,$=0;$<T.length;$++)T[$].isParent()||C.set(T[$].id(),rt++);var D=!0,H=!1,k=void 0;try{for(var tt=d.keys()[Symbol.iterator](),ht;!(D=(ht=tt.next()).done);D=!0){var J=ht.value;C.set(J,rt++)}}catch(F){H=!0,k=F}finally{try{!D&&tt.return&&tt.return()}finally{if(H)throw k}}for(var It=0;It<C.size;It++)w[It]=[];g.forEach(function(F){for(var Y=F.children().intersection(l);Y.nodes(":childless").length==0;)Y=Y.nodes()[0].children().intersection(l);var Z=0,K=Y.nodes(":childless")[0].connectedEdges().length;Y.nodes(":childless").forEach(function(q,at){q.connectedEdges().length<K&&(K=q.connectedEdges().length,Z=at)}),S.set(F.id(),Y.nodes(":childless")[Z].id())}),T.forEach(function(F){var Y=void 0;F.isParent()?Y=C.get(S.get(F.id())):Y=C.get(F.id()),F.neighborhood().nodes().forEach(function(Z){l.intersection(F.edgesWith(Z)).length>0&&(Z.isParent()?w[Y].push(S.get(Z.id())):w[Y].push(Z.id()))})});var Nt=function(Y){var Z=C.get(Y),K=void 0;d.get(Y).forEach(function(q){c.getElementById(q).isParent()?K=S.get(q):K=q,w[Z].push(K),w[C.get(K)].push(Y)})},vt=!0,it=!1,ut=void 0;try{for(var Et=d.keys()[Symbol.iterator](),wt;!(vt=(wt=Et.next()).done);vt=!0){var Ot=wt.value;Nt(Ot)}}catch(F){it=!0,ut=F}finally{try{!vt&&Et.return&&Et.return()}finally{if(it)throw ut}}E=C.size;var mt=void 0;if(E>2){R=E<o.sampleSize?E:o.sampleSize;for(var Dt=0;Dt<E;Dt++)M[Dt]=[];for(var Rt=0;Rt<R;Rt++)n[Rt]=[];return o.quality=="draft"||o.step=="all"?(Q(I),z(),X(),mt={nodeIndexes:C,xCoords:P,yCoords:B}):(C.forEach(function(F,Y){P.push(c.getElementById(Y).position("x")),B.push(c.getElementById(Y).position("y"))}),mt={nodeIndexes:C,xCoords:P,yCoords:B}),mt}else{var Ht=C.keys(),Ut=c.getElementById(Ht.next().value),Pt=Ut.position(),Ft=Ut.outerWidth();if(P.push(Pt.x),B.push(Pt.y),E==2){var Yt=c.getElementById(Ht.next().value),Vt=Yt.outerWidth();P.push(Pt.x+Ft/2+Vt/2+o.idealEdgeLength),B.push(Pt.y)}return mt={nodeIndexes:C,xCoords:P,yCoords:B},mt}};i.exports={spectralLayout:t}}),579:((i,r,a)=>{var f=a(212),e=function(t){t&&t("layout","fcose",f)};typeof cytoscape<"u"&&e(cytoscape),i.exports=e}),140:(i=>{i.exports=A})},N={};function v(i){var r=N[i];if(r!==void 0)return r.exports;var a=N[i]={exports:{}};return G[i](a,a.exports,v),a.exports}var h=v(579);return h})()})})(se)),se.exports}var mr=yr();const Er=cr(mr);var xe={L:"left",R:"right",T:"top",B:"bottom"},Ie={L:gt(L=>`${L},${L/2} 0,${L} 0,0`,"L"),R:gt(L=>`0,${L/2} ${L},0 ${L},${L}`,"R"),T:gt(L=>`0,0 ${L},0 ${L/2},${L}`,"T"),B:gt(L=>`${L/2},0 ${L},${L} 0,${L}`,"B")},oe={L:gt((L,b)=>L-b+2,"L"),R:gt((L,b)=>L-2,"R"),T:gt((L,b)=>L-b+2,"T"),B:gt((L,b)=>L-2,"B")},Tr=gt(function(L){return Wt(L)?L==="L"?"R":"L":L==="T"?"B":"T"},"getOppositeArchitectureDirection"),Re=gt(function(L){const b=L;return b==="L"||b==="R"||b==="T"||b==="B"},"isArchitectureDirection"),Wt=gt(function(L){const b=L;return b==="L"||b==="R"},"isArchitectureDirectionX"),qt=gt(function(L){const b=L;return b==="T"||b==="B"},"isArchitectureDirectionY"),Te=gt(function(L,b){const A=Wt(L)&&qt(b),G=qt(L)&&Wt(b);return A||G},"isArchitectureDirectionXY"),Nr=gt(function(L){const b=L[0],A=L[1],G=Wt(b)&&qt(A),N=qt(b)&&Wt(A);return G||N},"isArchitecturePairXY"),Lr=gt(function(L){return L!=="LL"&&L!=="RR"&&L!=="TT"&&L!=="BB"},"isValidArchitectureDirectionPair"),pe=gt(function(L,b){const A=`${L}${b}`;return Lr(A)?A:void 0},"getArchitectureDirectionPair"),Cr=gt(function([L,b],A){const G=A[0],N=A[1];return Wt(G)?qt(N)?[L+(G==="L"?-1:1),b+(N==="T"?1:-1)]:[L+(G==="L"?-1:1),b]:Wt(N)?[L+(N==="L"?1:-1),b+(G==="T"?1:-1)]:[L,b+(G==="T"?1:-1)]},"shiftPositionByArchitectureDirectionPair"),wr=gt(function(L){return L==="LT"||L==="TL"?[1,1]:L==="BL"||L==="LB"?[1,-1]:L==="BR"||L==="RB"?[-1,-1]:[-1,1]},"getArchitectureDirectionXYFactors"),Ar=gt(function(L,b){return Te(L,b)?"bend":Wt(L)?"horizontal":"vertical"},"getArchitectureDirectionAlignment"),Mr=gt(function(L){return L.type==="service"},"isArchitectureService"),Or=gt(function(L){return L.type==="junction"},"isArchitectureJunction"),be=gt(L=>L.data(),"edgeData"),ie=gt(L=>L.data(),"nodeData"),Dr=ar.architecture,Pe=class{constructor(){this.nodes={},this.groups={},this.edges=[],this.layoutHints=[],this.registeredIds={},this.elements={},this.diagramId="",this.setAccTitle=Qe,this.getAccTitle=Je,this.setDiagramTitle=Ke,this.getDiagramTitle=je,this.getAccDescription=_e,this.setAccDescription=tr,this.clear()}static{gt(this,"ArchitectureDB")}setDiagramId(L){this.diagramId=L}getDiagramId(){return this.diagramId}clear(){this.nodes={},this.groups={},this.edges=[],this.layoutHints=[],this.registeredIds={},this.dataStructures=void 0,this.elements={},this.diagramId="",er()}addService({id:L,icon:b,in:A,title:G,iconText:N}){if(this.registeredIds[L]!==void 0)throw new Error(`The service id [${L}] is already in use by another ${this.registeredIds[L]}`);if(A!==void 0){if(L===A)throw new Error(`The service [${L}] cannot be placed within itself`);if(this.registeredIds[A]===void 0)throw new Error(`The service [${L}]'s parent does not exist. Please make sure the parent is created before this service`);if(this.registeredIds[A]==="node")throw new Error(`The service [${L}]'s parent is not a group`)}this.registeredIds[L]="node",this.nodes[L]={id:L,type:"service",icon:b,iconText:N,title:G,edges:[],in:A}}getServices(){return Object.values(this.nodes).filter(Mr)}addJunction({id:L,in:b}){if(this.registeredIds[L]!==void 0)throw new Error(`The junction id [${L}] is already in use by another ${this.registeredIds[L]}`);if(b!==void 0){if(L===b)throw new Error(`The junction [${L}] cannot be placed within itself`);if(this.registeredIds[b]===void 0)throw new Error(`The junction [${L}]'s parent does not exist. Please make sure the parent is created before this junction`);if(this.registeredIds[b]==="node")throw new Error(`The junction [${L}]'s parent is not a group`)}this.registeredIds[L]="node",this.nodes[L]={id:L,type:"junction",edges:[],in:b}}getJunctions(){return Object.values(this.nodes).filter(Or)}getNodes(){return Object.values(this.nodes)}getNode(L){return this.nodes[L]??null}addGroup({id:L,icon:b,in:A,title:G}){if(this.registeredIds?.[L]!==void 0)throw new Error(`The group id [${L}] is already in use by another ${this.registeredIds[L]}`);if(A!==void 0){if(L===A)throw new Error(`The group [${L}] cannot be placed within itself`);if(this.registeredIds?.[A]===void 0)throw new Error(`The group [${L}]'s parent does not exist. Please make sure the parent is created before this group`);if(this.registeredIds?.[A]==="node")throw new Error(`The group [${L}]'s parent is not a group`)}this.registeredIds[L]="group",this.groups[L]={id:L,icon:b,title:G,in:A}}getGroups(){return Object.values(this.groups)}addEdge({lhsId:L,rhsId:b,lhsDir:A,rhsDir:G,lhsInto:N,rhsInto:v,lhsGroup:h,rhsGroup:i,title:r}){if(!Re(A))throw new Error(`Invalid direction given for left hand side of edge ${L}--${b}. Expected (L,R,T,B) got ${String(A)}`);if(!Re(G))throw new Error(`Invalid direction given for right hand side of edge ${L}--${b}. Expected (L,R,T,B) got ${String(G)}`);if(this.nodes[L]===void 0&&this.groups[L]===void 0)throw new Error(`The left-hand id [${L}] does not yet exist. Please create the service/group before declaring an edge to it.`);if(this.nodes[b]===void 0&&this.groups[b]===void 0)throw new Error(`The right-hand id [${b}] does not yet exist. Please create the service/group before declaring an edge to it.`);const a=this.nodes[L].in,f=this.nodes[b].in;if(h&&a&&f&&a==f)throw new Error(`The left-hand id [${L}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);if(i&&a&&f&&a==f)throw new Error(`The right-hand id [${b}] is modified to traverse the group boundary, but the edge does not pass through two groups.`);const e={lhsId:L,lhsDir:A,lhsInto:N,lhsGroup:h,rhsId:b,rhsDir:G,rhsInto:v,rhsGroup:i,title:r};this.edges.push(e),this.nodes[L]&&this.nodes[b]&&(this.nodes[L].edges.push(this.edges[this.edges.length-1]),this.nodes[b].edges.push(this.edges[this.edges.length-1]))}getEdges(){return this.edges}addLayoutHint(L){if(L.members.length<2)throw new Error(`An align directive requires at least two members; got ${L.members.length}`);const b=new Set;L.members.forEach(A=>{if(this.registeredIds[A]!=="node")throw new Error(`align ${L.direction} references [${A}], which is not a service or junction`);if(b.has(A))throw new Error(`align ${L.direction} lists [${A}] more than once`);b.add(A)}),this.layoutHints.push(L)}getLayoutHints(){return this.layoutHints}getDataStructures(){if(this.dataStructures===void 0){const L={},b=Object.entries(this.nodes).reduce((i,[r,a])=>(i[r]=a.edges.reduce((f,e)=>{const u=this.getNode(e.lhsId)?.in,t=this.getNode(e.rhsId)?.in;if(u&&t&&u!==t){const s=Ar(e.lhsDir,e.rhsDir);s!=="bend"&&(L[u]??={},L[u][t]=s,L[t]??={},L[t][u]=s)}if(e.lhsId===r){const s=pe(e.lhsDir,e.rhsDir);s&&(f[s]=e.rhsId)}else{const s=pe(e.rhsDir,e.lhsDir);s&&(f[s]=e.lhsId)}return f},{}),i),{}),A=Object.keys(b)[0],G={[A]:1},N=Object.keys(b).reduce((i,r)=>r===A?i:{...i,[r]:1},{}),v=gt(i=>{const r={[i]:[0,0]},a=[i];for(;a.length>0;){const f=a.shift();if(f){G[f]=1,delete N[f];const e=b[f],[u,t]=r[f];Object.entries(e).forEach(([s,o])=>{G[o]||(r[o]=Cr([u,t],s),a.push(o))})}}return r},"BFS"),h=[v(A)];for(;Object.keys(N).length>0;)h.push(v(Object.keys(N)[0]));this.dataStructures={adjList:b,spatialMaps:h,groupAlignments:L}}return this.dataStructures}setElementForId(L,b){this.elements[L]=b}getElementById(L){return this.elements[L]}getConfig(){return rr({...Dr,...ir().architecture})}getConfigField(L){return this.getConfig()[L]}},xr=gt((L,b)=>{ke(L,b),L.groups.map(A=>b.addGroup(A)),L.services.map(A=>b.addService({...A,type:"service"})),L.junctions.map(A=>b.addJunction({...A,type:"junction"})),L.edges.map(A=>b.addEdge(A)),L.alignments?.map(A=>b.addLayoutHint({direction:A.direction,members:[...A.members]}))},"populateDb"),Ge={parser:{yy:void 0},parse:gt(async L=>{const b=await fr("architecture",L);Se.debug(b);const A=Ge.parser?.yy;if(!(A instanceof Pe))throw new Error("parser.parser?.yy was not a ArchitectureDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");xr(b,A)},"parse")},Ir=gt(L=>` .edge { stroke-width: ${L.archEdgeWidth}; stroke: ${L.archEdgeColor}; diff --git a/apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-DMGXLKk2.js b/apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-BNXb88Fr.js similarity index 99% rename from apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-DMGXLKk2.js rename to apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-BNXb88Fr.js index 4fea8867e..6e3062b78 100644 --- a/apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-DMGXLKk2.js +++ b/apps/kimi-code/dist-web/assets/blockDiagram-677ZJIJ3-BNXb88Fr.js @@ -1,4 +1,4 @@ -import{g as de}from"./chunk-5VM5RSS4-B87d3yQb.js";import{aA as pe,aB as Kt,aC as fe,aD as xe,aE as ye,aF as be,aG as we,aH as me,aI as Se,aJ as Le,aK as ke,aL as ve,aM as Ee,aN as _e,aO as Te,aP as De,aQ as Be,aR as Ne,aS as Ie,aT as Ce,aU as Oe,aV as Re,aW as Ae,aX as ze,aY as Me,_ as g,z as rt,d as D,e as Pe,l as k,q as Fe,t as We,c as R,aZ as Ye,a7 as He,a8 as Ke,a3 as Ue,a_ as M,a$ as kt,b0 as Q,as as Xe,y as $,k as Ve,b1 as je,i as Ct,b2 as Ot,b3 as Ge}from"./mermaid.core-DaDTfY6S.js";import{G as Ze}from"./graph-DOmOIIwC.js";import{c as qe}from"./channel-d4fEaqwQ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";function Je(e){return Array.isArray(e)}function Qe(e){if(pe(e))return e;const t=Kt(e);if(!$e(e))return{};if(Je(e)){const s=Array.from(e);return e.length>0&&typeof e[0]=="string"&&Object.hasOwn(e,"index")&&(s.index=e.index,s.input=e.input),s}if(fe(e)){const s=e,i=s.constructor;return new i(s.buffer,s.byteOffset,s.length)}if(t==="[object ArrayBuffer]")return new ArrayBuffer(e.byteLength);if(t==="[object DataView]"){const s=e,i=s.buffer,c=s.byteOffset,r=s.byteLength,n=new ArrayBuffer(r),l=new Uint8Array(i,c,r);return new Uint8Array(n).set(l),new DataView(n)}if(t==="[object Boolean]"||t==="[object Number]"||t==="[object String]"){const s=e.constructor,i=new s(e.valueOf());return t==="[object String]"?er(i,e):xt(i,e),i}if(t==="[object Date]")return new Date(Number(e));if(t==="[object RegExp]"){const s=e,i=new RegExp(s.source,s.flags);return i.lastIndex=s.lastIndex,i}if(t==="[object Symbol]")return Object(Symbol.prototype.valueOf.call(e));if(t==="[object Map]"){const s=e,i=new Map;return s.forEach((c,r)=>{i.set(r,c)}),i}if(t==="[object Set]"){const s=e,i=new Set;return s.forEach(c=>{i.add(c)}),i}if(t==="[object Arguments]"){const s=e,i={};return xt(i,s),i.length=s.length,i[Symbol.iterator]=s[Symbol.iterator],i}const a={};return rr(a,e),xt(a,e),tr(a,e),a}function $e(e){switch(Kt(e)){case Me:case ze:case Ae:case Re:case Oe:case Ce:case Ie:case Ne:case Be:case De:case Te:case _e:case Ee:case ve:case ke:case Le:case Se:case me:case we:case be:case ye:case xe:return!0;default:return!1}}function xt(e,t){for(const a in t)Object.hasOwn(t,a)&&(e[a]=t[a])}function tr(e,t){const a=Object.getOwnPropertySymbols(t);for(let s=0;s<a.length;s++){const i=a[s];Object.prototype.propertyIsEnumerable.call(t,i)&&(e[i]=t[i])}}function er(e,t){const a=t.valueOf().length;for(const s in t)Object.hasOwn(t,s)&&(Number.isNaN(Number(s))||Number(s)>=a)&&(e[s]=t[s])}function rr(e,t){const a=Object.getPrototypeOf(t);a!==null&&typeof t.constructor=="function"&&Object.setPrototypeOf(e,a)}var bt=(function(){var e=g(function(T,m,p,x){for(p=p||{},x=T.length;x--;p[T[x]]=m);return p},"o"),t=[1,15],a=[1,7],s=[1,13],i=[1,14],c=[1,19],r=[1,16],n=[1,17],l=[1,18],u=[8,30],h=[8,10,21,28,29,30,31,39,43,46],d=[1,23],b=[1,24],w=[8,10,15,16,21,28,29,30,31,39,43,46],y=[8,10,15,16,21,27,28,29,30,31,39,43,46],v=[1,49],S={trace:g(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,NODE_ID:31,nodeShapeNLabel:32,dirList:33,DIR:34,NODE_DSTART:35,NODE_DEND:36,BLOCK_ARROW_START:37,BLOCK_ARROW_END:38,classDef:39,CLASSDEF_ID:40,CLASSDEF_STYLEOPTS:41,DEFAULT:42,class:43,CLASSENTITY_IDS:44,STYLECLASS:45,style:46,STYLE_ENTITY_IDS:47,STYLE_DEFINITION_DATA:48,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"NODE_ID",34:"DIR",35:"NODE_DSTART",36:"NODE_DEND",37:"BLOCK_ARROW_START",38:"BLOCK_ARROW_END",39:"classDef",40:"CLASSDEF_ID",41:"CLASSDEF_STYLEOPTS",42:"DEFAULT",43:"class",44:"CLASSENTITY_IDS",45:"STYLECLASS",46:"style",47:"STYLE_ENTITY_IDS",48:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[33,1],[33,2],[32,3],[32,4],[23,3],[23,3],[24,3],[25,3]],performAction:g(function(m,p,x,L,E,o,F){var f=o.length-1;switch(E){case 4:L.getLogger().debug("Rule: separator (NL) ");break;case 5:L.getLogger().debug("Rule: separator (Space) ");break;case 6:L.getLogger().debug("Rule: separator (EOF) ");break;case 7:L.getLogger().debug("Rule: hierarchy: ",o[f-1]),L.setHierarchy(o[f-1]);break;case 8:L.getLogger().debug("Stop NL ");break;case 9:L.getLogger().debug("Stop EOF ");break;case 10:L.getLogger().debug("Stop NL2 ");break;case 11:L.getLogger().debug("Stop EOF2 ");break;case 12:L.getLogger().debug("Rule: statement: ",o[f]),typeof o[f].length=="number"?this.$=o[f]:this.$=[o[f]];break;case 13:L.getLogger().debug("Rule: statement #2: ",o[f-1]),this.$=[o[f-1]].concat(o[f]);break;case 14:L.getLogger().debug("Rule: link: ",o[f],m),this.$={edgeTypeStr:o[f],label:""};break;case 15:L.getLogger().debug("Rule: LABEL link: ",o[f-3],o[f-1],o[f]),this.$={edgeTypeStr:o[f],label:o[f-1]};break;case 18:const C=parseInt(o[f]),Z=L.generateId();this.$={id:Z,type:"space",label:"",width:C,children:[]};break;case 23:L.getLogger().debug("Rule: (nodeStatement link node) ",o[f-2],o[f-1],o[f]," typestr: ",o[f-1].edgeTypeStr);const V=L.edgeStrToEdgeData(o[f-1].edgeTypeStr),at=L.edgeStrToEdgeStartData(o[f-1].edgeTypeStr),gt=L.edgeStrToThickness(o[f-1].edgeTypeStr),O=L.edgeStrToPattern(o[f-1].edgeTypeStr);this.$=[{id:o[f-2].id,label:o[f-2].label,type:o[f-2].type,directions:o[f-2].directions},{id:o[f-2].id+"-"+o[f].id,start:o[f-2].id,end:o[f].id,label:o[f-1].label,type:"edge",thickness:gt,pattern:O,directions:o[f].directions,arrowTypeEnd:V,arrowTypeStart:at},{id:o[f].id,label:o[f].label,type:L.typeStr2Type(o[f].typeStr),directions:o[f].directions}];break;case 24:L.getLogger().debug("Rule: nodeStatement (abc88 node size) ",o[f-1],o[f]),this.$={id:o[f-1].id,label:o[f-1].label,type:L.typeStr2Type(o[f-1].typeStr),directions:o[f-1].directions,widthInColumns:parseInt(o[f],10)};break;case 25:L.getLogger().debug("Rule: nodeStatement (node) ",o[f]),this.$={id:o[f].id,label:o[f].label,type:L.typeStr2Type(o[f].typeStr),directions:o[f].directions,widthInColumns:1};break;case 26:L.getLogger().debug("APA123",this?this:"na"),L.getLogger().debug("COLUMNS: ",o[f]),this.$={type:"column-setting",columns:o[f]==="auto"?-1:parseInt(o[f])};break;case 27:L.getLogger().debug("Rule: id-block statement : ",o[f-2],o[f-1]),L.generateId(),this.$={...o[f-2],type:"composite",children:o[f-1]};break;case 28:L.getLogger().debug("Rule: blockStatement : ",o[f-2],o[f-1],o[f]);const j=L.generateId();this.$={id:j,type:"composite",label:"",children:o[f-1]};break;case 29:L.getLogger().debug("Rule: node (NODE_ID separator): ",o[f]),this.$={id:o[f]};break;case 30:L.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",o[f-1],o[f]),this.$={id:o[f-1],label:o[f].label,typeStr:o[f].typeStr,directions:o[f].directions};break;case 31:L.getLogger().debug("Rule: dirList: ",o[f]),this.$=[o[f]];break;case 32:L.getLogger().debug("Rule: dirList: ",o[f-1],o[f]),this.$=[o[f-1]].concat(o[f]);break;case 33:L.getLogger().debug("Rule: nodeShapeNLabel: ",o[f-2],o[f-1],o[f]),this.$={typeStr:o[f-2]+o[f],label:o[f-1]};break;case 34:L.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",o[f-3],o[f-2]," #3:",o[f-1],o[f]),this.$={typeStr:o[f-3]+o[f],label:o[f-2],directions:o[f-1]};break;case 35:case 36:this.$={type:"classDef",id:o[f-1].trim(),css:o[f].trim()};break;case 37:this.$={type:"applyClass",id:o[f-1].trim(),styleClass:o[f].trim()};break;case 38:this.$={type:"applyStyles",id:o[f-1].trim(),stylesStr:o[f].trim()};break}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{10:t,11:3,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{8:[1,20]},e(u,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,10:t,21:a,28:s,29:i,31:c,39:r,43:n,46:l}),e(h,[2,16],{14:22,15:d,16:b}),e(h,[2,17]),e(h,[2,18]),e(h,[2,19]),e(h,[2,20]),e(h,[2,21]),e(h,[2,22]),e(w,[2,25],{27:[1,25]}),e(h,[2,26]),{19:26,26:12,31:c},{10:t,11:27,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{40:[1,28],42:[1,29]},{44:[1,30]},{47:[1,31]},e(y,[2,29],{32:32,35:[1,33],37:[1,34]}),{1:[2,7]},e(u,[2,13]),{26:35,31:c},{31:[2,14]},{17:[1,36]},e(w,[2,24]),{10:t,11:37,13:4,14:22,15:d,16:b,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{30:[1,38]},{41:[1,39]},{41:[1,40]},{45:[1,41]},{48:[1,42]},e(y,[2,30]),{18:[1,43]},{18:[1,44]},e(w,[2,23]),{18:[1,45]},{30:[1,46]},e(h,[2,28]),e(h,[2,35]),e(h,[2,36]),e(h,[2,37]),e(h,[2,38]),{36:[1,47]},{33:48,34:v},{15:[1,50]},e(h,[2,27]),e(y,[2,33]),{38:[1,51]},{33:52,34:v,38:[2,31]},{31:[2,15]},e(y,[2,34]),{38:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:g(function(m,p){if(p.recoverable)this.trace(m);else{var x=new Error(m);throw x.hash=p,x}},"parseError"),parse:g(function(m){var p=this,x=[0],L=[],E=[null],o=[],F=this.table,f="",C=0,Z=0,V=2,at=1,gt=o.slice.call(arguments,1),O=Object.create(this.lexer),j={yy:{}};for(var ut in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ut)&&(j.yy[ut]=this.yy[ut]);O.setInput(m,j.yy),j.yy.lexer=O,j.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var dt=O.yylloc;o.push(dt);var ge=O.options&&O.options.ranges;typeof j.yy.parseError=="function"?this.parseError=j.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ue(W){x.length=x.length-2*W,E.length=E.length-W,o.length=o.length-W}g(ue,"popStack");function Nt(){var W;return W=L.pop()||O.lex()||at,typeof W!="number"&&(W instanceof Array&&(L=W,W=L.pop()),W=p.symbols_[W]||W),W}g(Nt,"lex");for(var P,q,H,pt,J={},st,G,It,it;;){if(q=x[x.length-1],this.defaultActions[q]?H=this.defaultActions[q]:((P===null||typeof P>"u")&&(P=Nt()),H=F[q]&&F[q][P]),typeof H>"u"||!H.length||!H[0]){var ft="";it=[];for(st in F[q])this.terminals_[st]&&st>V&&it.push("'"+this.terminals_[st]+"'");O.showPosition?ft="Parse error on line "+(C+1)+`: +import{g as de}from"./chunk-5VM5RSS4-yyj9cAyF.js";import{aA as pe,aB as Kt,aC as fe,aD as xe,aE as ye,aF as be,aG as we,aH as me,aI as Se,aJ as Le,aK as ke,aL as ve,aM as Ee,aN as _e,aO as Te,aP as De,aQ as Be,aR as Ne,aS as Ie,aT as Ce,aU as Oe,aV as Re,aW as Ae,aX as ze,aY as Me,_ as g,z as rt,d as D,e as Pe,l as k,q as Fe,t as We,c as R,aZ as Ye,a7 as He,a8 as Ke,a3 as Ue,a_ as M,a$ as kt,b0 as Q,as as Xe,y as $,k as Ve,b1 as je,i as Ct,b2 as Ot,b3 as Ge}from"./mermaid.core-CJB1tAev.js";import{G as Ze}from"./graph-DOmOIIwC.js";import{c as qe}from"./channel-xkK6nTGq.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";function Je(e){return Array.isArray(e)}function Qe(e){if(pe(e))return e;const t=Kt(e);if(!$e(e))return{};if(Je(e)){const s=Array.from(e);return e.length>0&&typeof e[0]=="string"&&Object.hasOwn(e,"index")&&(s.index=e.index,s.input=e.input),s}if(fe(e)){const s=e,i=s.constructor;return new i(s.buffer,s.byteOffset,s.length)}if(t==="[object ArrayBuffer]")return new ArrayBuffer(e.byteLength);if(t==="[object DataView]"){const s=e,i=s.buffer,c=s.byteOffset,r=s.byteLength,n=new ArrayBuffer(r),l=new Uint8Array(i,c,r);return new Uint8Array(n).set(l),new DataView(n)}if(t==="[object Boolean]"||t==="[object Number]"||t==="[object String]"){const s=e.constructor,i=new s(e.valueOf());return t==="[object String]"?er(i,e):xt(i,e),i}if(t==="[object Date]")return new Date(Number(e));if(t==="[object RegExp]"){const s=e,i=new RegExp(s.source,s.flags);return i.lastIndex=s.lastIndex,i}if(t==="[object Symbol]")return Object(Symbol.prototype.valueOf.call(e));if(t==="[object Map]"){const s=e,i=new Map;return s.forEach((c,r)=>{i.set(r,c)}),i}if(t==="[object Set]"){const s=e,i=new Set;return s.forEach(c=>{i.add(c)}),i}if(t==="[object Arguments]"){const s=e,i={};return xt(i,s),i.length=s.length,i[Symbol.iterator]=s[Symbol.iterator],i}const a={};return rr(a,e),xt(a,e),tr(a,e),a}function $e(e){switch(Kt(e)){case Me:case ze:case Ae:case Re:case Oe:case Ce:case Ie:case Ne:case Be:case De:case Te:case _e:case Ee:case ve:case ke:case Le:case Se:case me:case we:case be:case ye:case xe:return!0;default:return!1}}function xt(e,t){for(const a in t)Object.hasOwn(t,a)&&(e[a]=t[a])}function tr(e,t){const a=Object.getOwnPropertySymbols(t);for(let s=0;s<a.length;s++){const i=a[s];Object.prototype.propertyIsEnumerable.call(t,i)&&(e[i]=t[i])}}function er(e,t){const a=t.valueOf().length;for(const s in t)Object.hasOwn(t,s)&&(Number.isNaN(Number(s))||Number(s)>=a)&&(e[s]=t[s])}function rr(e,t){const a=Object.getPrototypeOf(t);a!==null&&typeof t.constructor=="function"&&Object.setPrototypeOf(e,a)}var bt=(function(){var e=g(function(T,m,p,x){for(p=p||{},x=T.length;x--;p[T[x]]=m);return p},"o"),t=[1,15],a=[1,7],s=[1,13],i=[1,14],c=[1,19],r=[1,16],n=[1,17],l=[1,18],u=[8,30],h=[8,10,21,28,29,30,31,39,43,46],d=[1,23],b=[1,24],w=[8,10,15,16,21,28,29,30,31,39,43,46],y=[8,10,15,16,21,27,28,29,30,31,39,43,46],v=[1,49],S={trace:g(function(){},"trace"),yy:{},symbols_:{error:2,spaceLines:3,SPACELINE:4,NL:5,separator:6,SPACE:7,EOF:8,start:9,BLOCK_DIAGRAM_KEY:10,document:11,stop:12,statement:13,link:14,LINK:15,START_LINK:16,LINK_LABEL:17,STR:18,nodeStatement:19,columnsStatement:20,SPACE_BLOCK:21,blockStatement:22,classDefStatement:23,cssClassStatement:24,styleStatement:25,node:26,SIZE:27,COLUMNS:28,"id-block":29,end:30,NODE_ID:31,nodeShapeNLabel:32,dirList:33,DIR:34,NODE_DSTART:35,NODE_DEND:36,BLOCK_ARROW_START:37,BLOCK_ARROW_END:38,classDef:39,CLASSDEF_ID:40,CLASSDEF_STYLEOPTS:41,DEFAULT:42,class:43,CLASSENTITY_IDS:44,STYLECLASS:45,style:46,STYLE_ENTITY_IDS:47,STYLE_DEFINITION_DATA:48,$accept:0,$end:1},terminals_:{2:"error",4:"SPACELINE",5:"NL",7:"SPACE",8:"EOF",10:"BLOCK_DIAGRAM_KEY",15:"LINK",16:"START_LINK",17:"LINK_LABEL",18:"STR",21:"SPACE_BLOCK",27:"SIZE",28:"COLUMNS",29:"id-block",30:"end",31:"NODE_ID",34:"DIR",35:"NODE_DSTART",36:"NODE_DEND",37:"BLOCK_ARROW_START",38:"BLOCK_ARROW_END",39:"classDef",40:"CLASSDEF_ID",41:"CLASSDEF_STYLEOPTS",42:"DEFAULT",43:"class",44:"CLASSENTITY_IDS",45:"STYLECLASS",46:"style",47:"STYLE_ENTITY_IDS",48:"STYLE_DEFINITION_DATA"},productions_:[0,[3,1],[3,2],[3,2],[6,1],[6,1],[6,1],[9,3],[12,1],[12,1],[12,2],[12,2],[11,1],[11,2],[14,1],[14,4],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[13,1],[19,3],[19,2],[19,1],[20,1],[22,4],[22,3],[26,1],[26,2],[33,1],[33,2],[32,3],[32,4],[23,3],[23,3],[24,3],[25,3]],performAction:g(function(m,p,x,L,E,o,F){var f=o.length-1;switch(E){case 4:L.getLogger().debug("Rule: separator (NL) ");break;case 5:L.getLogger().debug("Rule: separator (Space) ");break;case 6:L.getLogger().debug("Rule: separator (EOF) ");break;case 7:L.getLogger().debug("Rule: hierarchy: ",o[f-1]),L.setHierarchy(o[f-1]);break;case 8:L.getLogger().debug("Stop NL ");break;case 9:L.getLogger().debug("Stop EOF ");break;case 10:L.getLogger().debug("Stop NL2 ");break;case 11:L.getLogger().debug("Stop EOF2 ");break;case 12:L.getLogger().debug("Rule: statement: ",o[f]),typeof o[f].length=="number"?this.$=o[f]:this.$=[o[f]];break;case 13:L.getLogger().debug("Rule: statement #2: ",o[f-1]),this.$=[o[f-1]].concat(o[f]);break;case 14:L.getLogger().debug("Rule: link: ",o[f],m),this.$={edgeTypeStr:o[f],label:""};break;case 15:L.getLogger().debug("Rule: LABEL link: ",o[f-3],o[f-1],o[f]),this.$={edgeTypeStr:o[f],label:o[f-1]};break;case 18:const C=parseInt(o[f]),Z=L.generateId();this.$={id:Z,type:"space",label:"",width:C,children:[]};break;case 23:L.getLogger().debug("Rule: (nodeStatement link node) ",o[f-2],o[f-1],o[f]," typestr: ",o[f-1].edgeTypeStr);const V=L.edgeStrToEdgeData(o[f-1].edgeTypeStr),at=L.edgeStrToEdgeStartData(o[f-1].edgeTypeStr),gt=L.edgeStrToThickness(o[f-1].edgeTypeStr),O=L.edgeStrToPattern(o[f-1].edgeTypeStr);this.$=[{id:o[f-2].id,label:o[f-2].label,type:o[f-2].type,directions:o[f-2].directions},{id:o[f-2].id+"-"+o[f].id,start:o[f-2].id,end:o[f].id,label:o[f-1].label,type:"edge",thickness:gt,pattern:O,directions:o[f].directions,arrowTypeEnd:V,arrowTypeStart:at},{id:o[f].id,label:o[f].label,type:L.typeStr2Type(o[f].typeStr),directions:o[f].directions}];break;case 24:L.getLogger().debug("Rule: nodeStatement (abc88 node size) ",o[f-1],o[f]),this.$={id:o[f-1].id,label:o[f-1].label,type:L.typeStr2Type(o[f-1].typeStr),directions:o[f-1].directions,widthInColumns:parseInt(o[f],10)};break;case 25:L.getLogger().debug("Rule: nodeStatement (node) ",o[f]),this.$={id:o[f].id,label:o[f].label,type:L.typeStr2Type(o[f].typeStr),directions:o[f].directions,widthInColumns:1};break;case 26:L.getLogger().debug("APA123",this?this:"na"),L.getLogger().debug("COLUMNS: ",o[f]),this.$={type:"column-setting",columns:o[f]==="auto"?-1:parseInt(o[f])};break;case 27:L.getLogger().debug("Rule: id-block statement : ",o[f-2],o[f-1]),L.generateId(),this.$={...o[f-2],type:"composite",children:o[f-1]};break;case 28:L.getLogger().debug("Rule: blockStatement : ",o[f-2],o[f-1],o[f]);const j=L.generateId();this.$={id:j,type:"composite",label:"",children:o[f-1]};break;case 29:L.getLogger().debug("Rule: node (NODE_ID separator): ",o[f]),this.$={id:o[f]};break;case 30:L.getLogger().debug("Rule: node (NODE_ID nodeShapeNLabel separator): ",o[f-1],o[f]),this.$={id:o[f-1],label:o[f].label,typeStr:o[f].typeStr,directions:o[f].directions};break;case 31:L.getLogger().debug("Rule: dirList: ",o[f]),this.$=[o[f]];break;case 32:L.getLogger().debug("Rule: dirList: ",o[f-1],o[f]),this.$=[o[f-1]].concat(o[f]);break;case 33:L.getLogger().debug("Rule: nodeShapeNLabel: ",o[f-2],o[f-1],o[f]),this.$={typeStr:o[f-2]+o[f],label:o[f-1]};break;case 34:L.getLogger().debug("Rule: BLOCK_ARROW nodeShapeNLabel: ",o[f-3],o[f-2]," #3:",o[f-1],o[f]),this.$={typeStr:o[f-3]+o[f],label:o[f-2],directions:o[f-1]};break;case 35:case 36:this.$={type:"classDef",id:o[f-1].trim(),css:o[f].trim()};break;case 37:this.$={type:"applyClass",id:o[f-1].trim(),styleClass:o[f].trim()};break;case 38:this.$={type:"applyStyles",id:o[f-1].trim(),stylesStr:o[f].trim()};break}},"anonymous"),table:[{9:1,10:[1,2]},{1:[3]},{10:t,11:3,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{8:[1,20]},e(u,[2,12],{13:4,19:5,20:6,22:8,23:9,24:10,25:11,26:12,11:21,10:t,21:a,28:s,29:i,31:c,39:r,43:n,46:l}),e(h,[2,16],{14:22,15:d,16:b}),e(h,[2,17]),e(h,[2,18]),e(h,[2,19]),e(h,[2,20]),e(h,[2,21]),e(h,[2,22]),e(w,[2,25],{27:[1,25]}),e(h,[2,26]),{19:26,26:12,31:c},{10:t,11:27,13:4,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{40:[1,28],42:[1,29]},{44:[1,30]},{47:[1,31]},e(y,[2,29],{32:32,35:[1,33],37:[1,34]}),{1:[2,7]},e(u,[2,13]),{26:35,31:c},{31:[2,14]},{17:[1,36]},e(w,[2,24]),{10:t,11:37,13:4,14:22,15:d,16:b,19:5,20:6,21:a,22:8,23:9,24:10,25:11,26:12,28:s,29:i,31:c,39:r,43:n,46:l},{30:[1,38]},{41:[1,39]},{41:[1,40]},{45:[1,41]},{48:[1,42]},e(y,[2,30]),{18:[1,43]},{18:[1,44]},e(w,[2,23]),{18:[1,45]},{30:[1,46]},e(h,[2,28]),e(h,[2,35]),e(h,[2,36]),e(h,[2,37]),e(h,[2,38]),{36:[1,47]},{33:48,34:v},{15:[1,50]},e(h,[2,27]),e(y,[2,33]),{38:[1,51]},{33:52,34:v,38:[2,31]},{31:[2,15]},e(y,[2,34]),{38:[2,32]}],defaultActions:{20:[2,7],23:[2,14],50:[2,15],52:[2,32]},parseError:g(function(m,p){if(p.recoverable)this.trace(m);else{var x=new Error(m);throw x.hash=p,x}},"parseError"),parse:g(function(m){var p=this,x=[0],L=[],E=[null],o=[],F=this.table,f="",C=0,Z=0,V=2,at=1,gt=o.slice.call(arguments,1),O=Object.create(this.lexer),j={yy:{}};for(var ut in this.yy)Object.prototype.hasOwnProperty.call(this.yy,ut)&&(j.yy[ut]=this.yy[ut]);O.setInput(m,j.yy),j.yy.lexer=O,j.yy.parser=this,typeof O.yylloc>"u"&&(O.yylloc={});var dt=O.yylloc;o.push(dt);var ge=O.options&&O.options.ranges;typeof j.yy.parseError=="function"?this.parseError=j.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ue(W){x.length=x.length-2*W,E.length=E.length-W,o.length=o.length-W}g(ue,"popStack");function Nt(){var W;return W=L.pop()||O.lex()||at,typeof W!="number"&&(W instanceof Array&&(L=W,W=L.pop()),W=p.symbols_[W]||W),W}g(Nt,"lex");for(var P,q,H,pt,J={},st,G,It,it;;){if(q=x[x.length-1],this.defaultActions[q]?H=this.defaultActions[q]:((P===null||typeof P>"u")&&(P=Nt()),H=F[q]&&F[q][P]),typeof H>"u"||!H.length||!H[0]){var ft="";it=[];for(st in F[q])this.terminals_[st]&&st>V&&it.push("'"+this.terminals_[st]+"'");O.showPosition?ft="Parse error on line "+(C+1)+`: `+O.showPosition()+` Expecting `+it.join(", ")+", got '"+(this.terminals_[P]||P)+"'":ft="Parse error on line "+(C+1)+": Unexpected "+(P==at?"end of input":"'"+(this.terminals_[P]||P)+"'"),this.parseError(ft,{text:O.match,token:this.terminals_[P]||P,line:O.yylineno,loc:dt,expected:it})}if(H[0]instanceof Array&&H.length>1)throw new Error("Parse Error: multiple actions possible at state: "+q+", token: "+P);switch(H[0]){case 1:x.push(P),E.push(O.yytext),o.push(O.yylloc),x.push(H[1]),P=null,Z=O.yyleng,f=O.yytext,C=O.yylineno,dt=O.yylloc;break;case 2:if(G=this.productions_[H[1]][1],J.$=E[E.length-G],J._$={first_line:o[o.length-(G||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(G||1)].first_column,last_column:o[o.length-1].last_column},ge&&(J._$.range=[o[o.length-(G||1)].range[0],o[o.length-1].range[1]]),pt=this.performAction.apply(J,[f,Z,C,j.yy,H[1],E,o].concat(gt)),typeof pt<"u")return pt;G&&(x=x.slice(0,-1*G*2),E=E.slice(0,-1*G),o=o.slice(0,-1*G)),x.push(this.productions_[H[1]][0]),E.push(J.$),o.push(J._$),It=F[x[x.length-2]][x[x.length-1]],x.push(It);break;case 3:return!0}}return!0},"parse")},N=(function(){var T={EOF:1,parseError:g(function(p,x){if(this.yy.parser)this.yy.parser.parseError(p,x);else throw new Error(p)},"parseError"),setInput:g(function(m,p){return this.yy=p||this.yy||{},this._input=m,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:g(function(){var m=this._input[0];this.yytext+=m,this.yyleng++,this.offset++,this.match+=m,this.matched+=m;var p=m.match(/(?:\r\n?|\n).*/g);return p?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),m},"input"),unput:g(function(m){var p=m.length,x=m.split(/(?:\r\n?|\n)/g);this._input=m+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-p),this.offset-=p;var L=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),x.length-1&&(this.yylineno-=x.length-1);var E=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:x?(x.length===L.length?this.yylloc.first_column:0)+L[L.length-x.length].length-x[0].length:this.yylloc.first_column-p},this.options.ranges&&(this.yylloc.range=[E[0],E[0]+this.yyleng-p]),this.yyleng=this.yytext.length,this},"unput"),more:g(function(){return this._more=!0,this},"more"),reject:g(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:g(function(m){this.unput(this.match.slice(m))},"less"),pastInput:g(function(){var m=this.matched.substr(0,this.matched.length-this.match.length);return(m.length>20?"...":"")+m.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:g(function(){var m=this.match;return m.length<20&&(m+=this._input.substr(0,20-m.length)),(m.substr(0,20)+(m.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:g(function(){var m=this.pastInput(),p=new Array(m.length+1).join("-");return m+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CuD9sHro.js b/apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CUyKVoVi.js similarity index 99% rename from apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CuD9sHro.js rename to apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CUyKVoVi.js index 583361a7a..c44d1d792 100644 --- a/apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CuD9sHro.js +++ b/apps/kimi-code/dist-web/assets/c4Diagram-LMCZKHZV-CUyKVoVi.js @@ -1,4 +1,4 @@ -import{g as Oe,d as Re}from"./chunk-32BRIVSS-_Sd4SrsJ.js";import{s as Se,g as De,a as Pe,b as Be,_ as y,c as Dt,d as Nt,l as he,e as Ie,f as Me,h as Tt,i as pe,j as Le,w as Ne,k as Jt,m as ue}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var jt=(function(){var e=y(function(_t,x,v,E){for(v=v||{},E=_t.length;E--;v[_t[E]]=x);return v},"o"),t=[1,24],s=[1,25],o=[1,26],l=[1,27],r=[1,28],a=[1,63],n=[1,64],i=[1,65],u=[1,66],d=[1,67],p=[1,68],g=[1,69],m=[1,29],O=[1,30],S=[1,31],P=[1,32],M=[1,33],U=[1,34],H=[1,35],q=[1,36],G=[1,37],K=[1,38],J=[1,39],Z=[1,40],$=[1,41],tt=[1,42],et=[1,43],at=[1,44],it=[1,45],nt=[1,46],st=[1,47],rt=[1,48],lt=[1,50],ot=[1,51],ct=[1,52],ht=[1,53],ut=[1,54],dt=[1,55],ft=[1,56],pt=[1,57],yt=[1,58],gt=[1,59],bt=[1,60],Ct=[14,42],Xt=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Ot=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],A=[1,82],k=[1,83],C=[1,84],w=[1,85],T=[12,14,42],se=[12,14,33,42],Bt=[12,14,33,42,76,77,79,80],vt=[12,33],Wt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Qt={trace:y(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:y(function(x,v,E,b,R,h,Rt){var f=h.length-1;switch(R){case 3:b.setDirection("TB");break;case 4:b.setDirection("BT");break;case 5:b.setDirection("RL");break;case 6:b.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:b.setC4Type(h[f-3]);break;case 19:b.setTitle(h[f].substring(6)),this.$=h[f].substring(6);break;case 20:b.setAccDescription(h[f].substring(15)),this.$=h[f].substring(15);break;case 21:this.$=h[f].trim(),b.setTitle(this.$);break;case 22:case 23:this.$=h[f].trim(),b.setAccDescription(this.$);break;case 28:h[f].splice(2,0,"ENTERPRISE"),b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 29:h[f].splice(2,0,"SYSTEM"),b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 30:b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 31:h[f].splice(2,0,"CONTAINER"),b.addContainerBoundary(...h[f]),this.$=h[f];break;case 32:b.addDeploymentNode("node",...h[f]),this.$=h[f];break;case 33:b.addDeploymentNode("nodeL",...h[f]),this.$=h[f];break;case 34:b.addDeploymentNode("nodeR",...h[f]),this.$=h[f];break;case 35:b.popBoundaryParseStack();break;case 39:b.addPersonOrSystem("person",...h[f]),this.$=h[f];break;case 40:b.addPersonOrSystem("external_person",...h[f]),this.$=h[f];break;case 41:b.addPersonOrSystem("system",...h[f]),this.$=h[f];break;case 42:b.addPersonOrSystem("system_db",...h[f]),this.$=h[f];break;case 43:b.addPersonOrSystem("system_queue",...h[f]),this.$=h[f];break;case 44:b.addPersonOrSystem("external_system",...h[f]),this.$=h[f];break;case 45:b.addPersonOrSystem("external_system_db",...h[f]),this.$=h[f];break;case 46:b.addPersonOrSystem("external_system_queue",...h[f]),this.$=h[f];break;case 47:b.addContainer("container",...h[f]),this.$=h[f];break;case 48:b.addContainer("container_db",...h[f]),this.$=h[f];break;case 49:b.addContainer("container_queue",...h[f]),this.$=h[f];break;case 50:b.addContainer("external_container",...h[f]),this.$=h[f];break;case 51:b.addContainer("external_container_db",...h[f]),this.$=h[f];break;case 52:b.addContainer("external_container_queue",...h[f]),this.$=h[f];break;case 53:b.addComponent("component",...h[f]),this.$=h[f];break;case 54:b.addComponent("component_db",...h[f]),this.$=h[f];break;case 55:b.addComponent("component_queue",...h[f]),this.$=h[f];break;case 56:b.addComponent("external_component",...h[f]),this.$=h[f];break;case 57:b.addComponent("external_component_db",...h[f]),this.$=h[f];break;case 58:b.addComponent("external_component_queue",...h[f]),this.$=h[f];break;case 60:b.addRel("rel",...h[f]),this.$=h[f];break;case 61:b.addRel("birel",...h[f]),this.$=h[f];break;case 62:b.addRel("rel_u",...h[f]),this.$=h[f];break;case 63:b.addRel("rel_d",...h[f]),this.$=h[f];break;case 64:b.addRel("rel_l",...h[f]),this.$=h[f];break;case 65:b.addRel("rel_r",...h[f]),this.$=h[f];break;case 66:b.addRel("rel_b",...h[f]),this.$=h[f];break;case 67:h[f].splice(0,1),b.addRel("rel",...h[f]),this.$=h[f];break;case 68:b.updateElStyle("update_el_style",...h[f]),this.$=h[f];break;case 69:b.updateRelStyle("update_rel_style",...h[f]),this.$=h[f];break;case 70:b.updateLayoutConfig("update_layout_config",...h[f]),this.$=h[f];break;case 71:this.$=[h[f]];break;case 72:h[f].unshift(h[f-1]),this.$=h[f];break;case 73:case 75:this.$=h[f].trim();break;case 74:let Et={};Et[h[f-1].trim()]=h[f].trim(),this.$=Et;break;case 76:this.$="";break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:70,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:71,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:72,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:73,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{14:[1,74]},e(Ct,[2,13],{43:23,29:49,30:61,32:62,20:75,34:a,36:n,37:i,38:u,39:d,40:p,41:g,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt}),e(Ct,[2,14]),e(Xt,[2,16],{12:[1,76]}),e(Ct,[2,36],{12:[1,77]}),e(Ot,[2,19]),e(Ot,[2,20]),{25:[1,78]},{27:[1,79]},e(Ot,[2,23]),{35:80,75:81,76:A,77:k,79:C,80:w},{35:86,75:81,76:A,77:k,79:C,80:w},{35:87,75:81,76:A,77:k,79:C,80:w},{35:88,75:81,76:A,77:k,79:C,80:w},{35:89,75:81,76:A,77:k,79:C,80:w},{35:90,75:81,76:A,77:k,79:C,80:w},{35:91,75:81,76:A,77:k,79:C,80:w},{35:92,75:81,76:A,77:k,79:C,80:w},{35:93,75:81,76:A,77:k,79:C,80:w},{35:94,75:81,76:A,77:k,79:C,80:w},{35:95,75:81,76:A,77:k,79:C,80:w},{35:96,75:81,76:A,77:k,79:C,80:w},{35:97,75:81,76:A,77:k,79:C,80:w},{35:98,75:81,76:A,77:k,79:C,80:w},{35:99,75:81,76:A,77:k,79:C,80:w},{35:100,75:81,76:A,77:k,79:C,80:w},{35:101,75:81,76:A,77:k,79:C,80:w},{35:102,75:81,76:A,77:k,79:C,80:w},{35:103,75:81,76:A,77:k,79:C,80:w},{35:104,75:81,76:A,77:k,79:C,80:w},e(T,[2,59]),{35:105,75:81,76:A,77:k,79:C,80:w},{35:106,75:81,76:A,77:k,79:C,80:w},{35:107,75:81,76:A,77:k,79:C,80:w},{35:108,75:81,76:A,77:k,79:C,80:w},{35:109,75:81,76:A,77:k,79:C,80:w},{35:110,75:81,76:A,77:k,79:C,80:w},{35:111,75:81,76:A,77:k,79:C,80:w},{35:112,75:81,76:A,77:k,79:C,80:w},{35:113,75:81,76:A,77:k,79:C,80:w},{35:114,75:81,76:A,77:k,79:C,80:w},{35:115,75:81,76:A,77:k,79:C,80:w},{20:116,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{12:[1,118],33:[1,117]},{35:119,75:81,76:A,77:k,79:C,80:w},{35:120,75:81,76:A,77:k,79:C,80:w},{35:121,75:81,76:A,77:k,79:C,80:w},{35:122,75:81,76:A,77:k,79:C,80:w},{35:123,75:81,76:A,77:k,79:C,80:w},{35:124,75:81,76:A,77:k,79:C,80:w},{35:125,75:81,76:A,77:k,79:C,80:w},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},e(Ct,[2,15]),e(Xt,[2,17],{21:22,19:130,22:t,23:s,24:o,26:l,28:r}),e(Ct,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:t,23:s,24:o,26:l,28:r,34:a,36:n,37:i,38:u,39:d,40:p,41:g,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt}),e(Ot,[2,21]),e(Ot,[2,22]),e(T,[2,39]),e(se,[2,71],{75:81,35:132,76:A,77:k,79:C,80:w}),e(Bt,[2,73]),{78:[1,133]},e(Bt,[2,75]),e(Bt,[2,76]),e(T,[2,40]),e(T,[2,41]),e(T,[2,42]),e(T,[2,43]),e(T,[2,44]),e(T,[2,45]),e(T,[2,46]),e(T,[2,47]),e(T,[2,48]),e(T,[2,49]),e(T,[2,50]),e(T,[2,51]),e(T,[2,52]),e(T,[2,53]),e(T,[2,54]),e(T,[2,55]),e(T,[2,56]),e(T,[2,57]),e(T,[2,58]),e(T,[2,60]),e(T,[2,61]),e(T,[2,62]),e(T,[2,63]),e(T,[2,64]),e(T,[2,65]),e(T,[2,66]),e(T,[2,67]),e(T,[2,68]),e(T,[2,69]),e(T,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},e(vt,[2,28]),e(vt,[2,29]),e(vt,[2,30]),e(vt,[2,31]),e(vt,[2,32]),e(vt,[2,33]),e(vt,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},e(Xt,[2,18]),e(Ct,[2,38]),e(se,[2,72]),e(Bt,[2,74]),e(T,[2,24]),e(T,[2,35]),e(Wt,[2,25]),e(Wt,[2,26],{12:[1,138]}),e(Wt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:y(function(x,v){if(v.recoverable)this.trace(x);else{var E=new Error(x);throw E.hash=v,E}},"parseError"),parse:y(function(x){var v=this,E=[0],b=[],R=[null],h=[],Rt=this.table,f="",Et=0,re=0,ke=2,le=1,Ce=h.slice.call(arguments,1),D=Object.create(this.lexer),At={yy:{}};for(var Ht in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ht)&&(At.yy[Ht]=this.yy[Ht]);D.setInput(x,At.yy),At.yy.lexer=D,At.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var qt=D.yylloc;h.push(qt);var we=D.options&&D.options.ranges;typeof At.yy.parseError=="function"?this.parseError=At.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Te(L){E.length=E.length-2*L,R.length=R.length-L,h.length=h.length-L}y(Te,"popStack");function oe(){var L;return L=b.pop()||D.lex()||le,typeof L!="number"&&(L instanceof Array&&(b=L,L=b.pop()),L=v.symbols_[L]||L),L}y(oe,"lex");for(var I,kt,N,Gt,wt={},Mt,W,ce,Lt;;){if(kt=E[E.length-1],this.defaultActions[kt]?N=this.defaultActions[kt]:((I===null||typeof I>"u")&&(I=oe()),N=Rt[kt]&&Rt[kt][I]),typeof N>"u"||!N.length||!N[0]){var Kt="";Lt=[];for(Mt in Rt[kt])this.terminals_[Mt]&&Mt>ke&&Lt.push("'"+this.terminals_[Mt]+"'");D.showPosition?Kt="Parse error on line "+(Et+1)+`: +import{g as Oe,d as Re}from"./chunk-32BRIVSS-DUDRPqmY.js";import{s as Se,g as De,a as Pe,b as Be,_ as y,c as Dt,d as Nt,l as he,e as Ie,f as Me,h as Tt,i as pe,j as Le,w as Ne,k as Jt,m as ue}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var jt=(function(){var e=y(function(_t,x,v,E){for(v=v||{},E=_t.length;E--;v[_t[E]]=x);return v},"o"),t=[1,24],s=[1,25],o=[1,26],l=[1,27],r=[1,28],a=[1,63],n=[1,64],i=[1,65],u=[1,66],d=[1,67],p=[1,68],g=[1,69],m=[1,29],O=[1,30],S=[1,31],P=[1,32],M=[1,33],U=[1,34],H=[1,35],q=[1,36],G=[1,37],K=[1,38],J=[1,39],Z=[1,40],$=[1,41],tt=[1,42],et=[1,43],at=[1,44],it=[1,45],nt=[1,46],st=[1,47],rt=[1,48],lt=[1,50],ot=[1,51],ct=[1,52],ht=[1,53],ut=[1,54],dt=[1,55],ft=[1,56],pt=[1,57],yt=[1,58],gt=[1,59],bt=[1,60],Ct=[14,42],Xt=[14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Ot=[12,14,34,36,37,38,39,40,41,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],A=[1,82],k=[1,83],C=[1,84],w=[1,85],T=[12,14,42],se=[12,14,33,42],Bt=[12,14,33,42,76,77,79,80],vt=[12,33],Wt=[34,36,37,38,39,40,41,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74],Qt={trace:y(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,direction:5,direction_tb:6,direction_bt:7,direction_rl:8,direction_lr:9,graphConfig:10,C4_CONTEXT:11,NEWLINE:12,statements:13,EOF:14,C4_CONTAINER:15,C4_COMPONENT:16,C4_DYNAMIC:17,C4_DEPLOYMENT:18,otherStatements:19,diagramStatements:20,otherStatement:21,title:22,accDescription:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,boundaryStatement:29,boundaryStartStatement:30,boundaryStopStatement:31,boundaryStart:32,LBRACE:33,ENTERPRISE_BOUNDARY:34,attributes:35,SYSTEM_BOUNDARY:36,BOUNDARY:37,CONTAINER_BOUNDARY:38,NODE:39,NODE_L:40,NODE_R:41,RBRACE:42,diagramStatement:43,PERSON:44,PERSON_EXT:45,SYSTEM:46,SYSTEM_DB:47,SYSTEM_QUEUE:48,SYSTEM_EXT:49,SYSTEM_EXT_DB:50,SYSTEM_EXT_QUEUE:51,CONTAINER:52,CONTAINER_DB:53,CONTAINER_QUEUE:54,CONTAINER_EXT:55,CONTAINER_EXT_DB:56,CONTAINER_EXT_QUEUE:57,COMPONENT:58,COMPONENT_DB:59,COMPONENT_QUEUE:60,COMPONENT_EXT:61,COMPONENT_EXT_DB:62,COMPONENT_EXT_QUEUE:63,REL:64,BIREL:65,REL_U:66,REL_D:67,REL_L:68,REL_R:69,REL_B:70,REL_INDEX:71,UPDATE_EL_STYLE:72,UPDATE_REL_STYLE:73,UPDATE_LAYOUT_CONFIG:74,attribute:75,STR:76,STR_KEY:77,STR_VALUE:78,ATTRIBUTE:79,ATTRIBUTE_EMPTY:80,$accept:0,$end:1},terminals_:{2:"error",6:"direction_tb",7:"direction_bt",8:"direction_rl",9:"direction_lr",11:"C4_CONTEXT",12:"NEWLINE",14:"EOF",15:"C4_CONTAINER",16:"C4_COMPONENT",17:"C4_DYNAMIC",18:"C4_DEPLOYMENT",22:"title",23:"accDescription",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"LBRACE",34:"ENTERPRISE_BOUNDARY",36:"SYSTEM_BOUNDARY",37:"BOUNDARY",38:"CONTAINER_BOUNDARY",39:"NODE",40:"NODE_L",41:"NODE_R",42:"RBRACE",44:"PERSON",45:"PERSON_EXT",46:"SYSTEM",47:"SYSTEM_DB",48:"SYSTEM_QUEUE",49:"SYSTEM_EXT",50:"SYSTEM_EXT_DB",51:"SYSTEM_EXT_QUEUE",52:"CONTAINER",53:"CONTAINER_DB",54:"CONTAINER_QUEUE",55:"CONTAINER_EXT",56:"CONTAINER_EXT_DB",57:"CONTAINER_EXT_QUEUE",58:"COMPONENT",59:"COMPONENT_DB",60:"COMPONENT_QUEUE",61:"COMPONENT_EXT",62:"COMPONENT_EXT_DB",63:"COMPONENT_EXT_QUEUE",64:"REL",65:"BIREL",66:"REL_U",67:"REL_D",68:"REL_L",69:"REL_R",70:"REL_B",71:"REL_INDEX",72:"UPDATE_EL_STYLE",73:"UPDATE_REL_STYLE",74:"UPDATE_LAYOUT_CONFIG",76:"STR",77:"STR_KEY",78:"STR_VALUE",79:"ATTRIBUTE",80:"ATTRIBUTE_EMPTY"},productions_:[0,[3,1],[3,1],[5,1],[5,1],[5,1],[5,1],[4,1],[10,4],[10,4],[10,4],[10,4],[10,4],[13,1],[13,1],[13,2],[19,1],[19,2],[19,3],[21,1],[21,1],[21,2],[21,2],[21,1],[29,3],[30,3],[30,3],[30,4],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[32,2],[31,1],[20,1],[20,2],[20,3],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,1],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[43,2],[35,1],[35,2],[75,1],[75,2],[75,1],[75,1]],performAction:y(function(x,v,E,b,R,h,Rt){var f=h.length-1;switch(R){case 3:b.setDirection("TB");break;case 4:b.setDirection("BT");break;case 5:b.setDirection("RL");break;case 6:b.setDirection("LR");break;case 8:case 9:case 10:case 11:case 12:b.setC4Type(h[f-3]);break;case 19:b.setTitle(h[f].substring(6)),this.$=h[f].substring(6);break;case 20:b.setAccDescription(h[f].substring(15)),this.$=h[f].substring(15);break;case 21:this.$=h[f].trim(),b.setTitle(this.$);break;case 22:case 23:this.$=h[f].trim(),b.setAccDescription(this.$);break;case 28:h[f].splice(2,0,"ENTERPRISE"),b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 29:h[f].splice(2,0,"SYSTEM"),b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 30:b.addPersonOrSystemBoundary(...h[f]),this.$=h[f];break;case 31:h[f].splice(2,0,"CONTAINER"),b.addContainerBoundary(...h[f]),this.$=h[f];break;case 32:b.addDeploymentNode("node",...h[f]),this.$=h[f];break;case 33:b.addDeploymentNode("nodeL",...h[f]),this.$=h[f];break;case 34:b.addDeploymentNode("nodeR",...h[f]),this.$=h[f];break;case 35:b.popBoundaryParseStack();break;case 39:b.addPersonOrSystem("person",...h[f]),this.$=h[f];break;case 40:b.addPersonOrSystem("external_person",...h[f]),this.$=h[f];break;case 41:b.addPersonOrSystem("system",...h[f]),this.$=h[f];break;case 42:b.addPersonOrSystem("system_db",...h[f]),this.$=h[f];break;case 43:b.addPersonOrSystem("system_queue",...h[f]),this.$=h[f];break;case 44:b.addPersonOrSystem("external_system",...h[f]),this.$=h[f];break;case 45:b.addPersonOrSystem("external_system_db",...h[f]),this.$=h[f];break;case 46:b.addPersonOrSystem("external_system_queue",...h[f]),this.$=h[f];break;case 47:b.addContainer("container",...h[f]),this.$=h[f];break;case 48:b.addContainer("container_db",...h[f]),this.$=h[f];break;case 49:b.addContainer("container_queue",...h[f]),this.$=h[f];break;case 50:b.addContainer("external_container",...h[f]),this.$=h[f];break;case 51:b.addContainer("external_container_db",...h[f]),this.$=h[f];break;case 52:b.addContainer("external_container_queue",...h[f]),this.$=h[f];break;case 53:b.addComponent("component",...h[f]),this.$=h[f];break;case 54:b.addComponent("component_db",...h[f]),this.$=h[f];break;case 55:b.addComponent("component_queue",...h[f]),this.$=h[f];break;case 56:b.addComponent("external_component",...h[f]),this.$=h[f];break;case 57:b.addComponent("external_component_db",...h[f]),this.$=h[f];break;case 58:b.addComponent("external_component_queue",...h[f]),this.$=h[f];break;case 60:b.addRel("rel",...h[f]),this.$=h[f];break;case 61:b.addRel("birel",...h[f]),this.$=h[f];break;case 62:b.addRel("rel_u",...h[f]),this.$=h[f];break;case 63:b.addRel("rel_d",...h[f]),this.$=h[f];break;case 64:b.addRel("rel_l",...h[f]),this.$=h[f];break;case 65:b.addRel("rel_r",...h[f]),this.$=h[f];break;case 66:b.addRel("rel_b",...h[f]),this.$=h[f];break;case 67:h[f].splice(0,1),b.addRel("rel",...h[f]),this.$=h[f];break;case 68:b.updateElStyle("update_el_style",...h[f]),this.$=h[f];break;case 69:b.updateRelStyle("update_rel_style",...h[f]),this.$=h[f];break;case 70:b.updateLayoutConfig("update_layout_config",...h[f]),this.$=h[f];break;case 71:this.$=[h[f]];break;case 72:h[f].unshift(h[f-1]),this.$=h[f];break;case 73:case 75:this.$=h[f].trim();break;case 74:let Et={};Et[h[f-1].trim()]=h[f].trim(),this.$=Et;break;case 76:this.$="";break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],7:[1,6],8:[1,7],9:[1,8],10:4,11:[1,9],15:[1,10],16:[1,11],17:[1,12],18:[1,13]},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,7]},{1:[2,3]},{1:[2,4]},{1:[2,5]},{1:[2,6]},{12:[1,14]},{12:[1,15]},{12:[1,16]},{12:[1,17]},{12:[1,18]},{13:19,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:70,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:71,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:72,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{13:73,19:20,20:21,21:22,22:t,23:s,24:o,26:l,28:r,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{14:[1,74]},e(Ct,[2,13],{43:23,29:49,30:61,32:62,20:75,34:a,36:n,37:i,38:u,39:d,40:p,41:g,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt}),e(Ct,[2,14]),e(Xt,[2,16],{12:[1,76]}),e(Ct,[2,36],{12:[1,77]}),e(Ot,[2,19]),e(Ot,[2,20]),{25:[1,78]},{27:[1,79]},e(Ot,[2,23]),{35:80,75:81,76:A,77:k,79:C,80:w},{35:86,75:81,76:A,77:k,79:C,80:w},{35:87,75:81,76:A,77:k,79:C,80:w},{35:88,75:81,76:A,77:k,79:C,80:w},{35:89,75:81,76:A,77:k,79:C,80:w},{35:90,75:81,76:A,77:k,79:C,80:w},{35:91,75:81,76:A,77:k,79:C,80:w},{35:92,75:81,76:A,77:k,79:C,80:w},{35:93,75:81,76:A,77:k,79:C,80:w},{35:94,75:81,76:A,77:k,79:C,80:w},{35:95,75:81,76:A,77:k,79:C,80:w},{35:96,75:81,76:A,77:k,79:C,80:w},{35:97,75:81,76:A,77:k,79:C,80:w},{35:98,75:81,76:A,77:k,79:C,80:w},{35:99,75:81,76:A,77:k,79:C,80:w},{35:100,75:81,76:A,77:k,79:C,80:w},{35:101,75:81,76:A,77:k,79:C,80:w},{35:102,75:81,76:A,77:k,79:C,80:w},{35:103,75:81,76:A,77:k,79:C,80:w},{35:104,75:81,76:A,77:k,79:C,80:w},e(T,[2,59]),{35:105,75:81,76:A,77:k,79:C,80:w},{35:106,75:81,76:A,77:k,79:C,80:w},{35:107,75:81,76:A,77:k,79:C,80:w},{35:108,75:81,76:A,77:k,79:C,80:w},{35:109,75:81,76:A,77:k,79:C,80:w},{35:110,75:81,76:A,77:k,79:C,80:w},{35:111,75:81,76:A,77:k,79:C,80:w},{35:112,75:81,76:A,77:k,79:C,80:w},{35:113,75:81,76:A,77:k,79:C,80:w},{35:114,75:81,76:A,77:k,79:C,80:w},{35:115,75:81,76:A,77:k,79:C,80:w},{20:116,29:49,30:61,32:62,34:a,36:n,37:i,38:u,39:d,40:p,41:g,43:23,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt},{12:[1,118],33:[1,117]},{35:119,75:81,76:A,77:k,79:C,80:w},{35:120,75:81,76:A,77:k,79:C,80:w},{35:121,75:81,76:A,77:k,79:C,80:w},{35:122,75:81,76:A,77:k,79:C,80:w},{35:123,75:81,76:A,77:k,79:C,80:w},{35:124,75:81,76:A,77:k,79:C,80:w},{35:125,75:81,76:A,77:k,79:C,80:w},{14:[1,126]},{14:[1,127]},{14:[1,128]},{14:[1,129]},{1:[2,8]},e(Ct,[2,15]),e(Xt,[2,17],{21:22,19:130,22:t,23:s,24:o,26:l,28:r}),e(Ct,[2,37],{19:20,20:21,21:22,43:23,29:49,30:61,32:62,13:131,22:t,23:s,24:o,26:l,28:r,34:a,36:n,37:i,38:u,39:d,40:p,41:g,44:m,45:O,46:S,47:P,48:M,49:U,50:H,51:q,52:G,53:K,54:J,55:Z,56:$,57:tt,58:et,59:at,60:it,61:nt,62:st,63:rt,64:lt,65:ot,66:ct,67:ht,68:ut,69:dt,70:ft,71:pt,72:yt,73:gt,74:bt}),e(Ot,[2,21]),e(Ot,[2,22]),e(T,[2,39]),e(se,[2,71],{75:81,35:132,76:A,77:k,79:C,80:w}),e(Bt,[2,73]),{78:[1,133]},e(Bt,[2,75]),e(Bt,[2,76]),e(T,[2,40]),e(T,[2,41]),e(T,[2,42]),e(T,[2,43]),e(T,[2,44]),e(T,[2,45]),e(T,[2,46]),e(T,[2,47]),e(T,[2,48]),e(T,[2,49]),e(T,[2,50]),e(T,[2,51]),e(T,[2,52]),e(T,[2,53]),e(T,[2,54]),e(T,[2,55]),e(T,[2,56]),e(T,[2,57]),e(T,[2,58]),e(T,[2,60]),e(T,[2,61]),e(T,[2,62]),e(T,[2,63]),e(T,[2,64]),e(T,[2,65]),e(T,[2,66]),e(T,[2,67]),e(T,[2,68]),e(T,[2,69]),e(T,[2,70]),{31:134,42:[1,135]},{12:[1,136]},{33:[1,137]},e(vt,[2,28]),e(vt,[2,29]),e(vt,[2,30]),e(vt,[2,31]),e(vt,[2,32]),e(vt,[2,33]),e(vt,[2,34]),{1:[2,9]},{1:[2,10]},{1:[2,11]},{1:[2,12]},e(Xt,[2,18]),e(Ct,[2,38]),e(se,[2,72]),e(Bt,[2,74]),e(T,[2,24]),e(T,[2,35]),e(Wt,[2,25]),e(Wt,[2,26],{12:[1,138]}),e(Wt,[2,27])],defaultActions:{2:[2,1],3:[2,2],4:[2,7],5:[2,3],6:[2,4],7:[2,5],8:[2,6],74:[2,8],126:[2,9],127:[2,10],128:[2,11],129:[2,12]},parseError:y(function(x,v){if(v.recoverable)this.trace(x);else{var E=new Error(x);throw E.hash=v,E}},"parseError"),parse:y(function(x){var v=this,E=[0],b=[],R=[null],h=[],Rt=this.table,f="",Et=0,re=0,ke=2,le=1,Ce=h.slice.call(arguments,1),D=Object.create(this.lexer),At={yy:{}};for(var Ht in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ht)&&(At.yy[Ht]=this.yy[Ht]);D.setInput(x,At.yy),At.yy.lexer=D,At.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var qt=D.yylloc;h.push(qt);var we=D.options&&D.options.ranges;typeof At.yy.parseError=="function"?this.parseError=At.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Te(L){E.length=E.length-2*L,R.length=R.length-L,h.length=h.length-L}y(Te,"popStack");function oe(){var L;return L=b.pop()||D.lex()||le,typeof L!="number"&&(L instanceof Array&&(b=L,L=b.pop()),L=v.symbols_[L]||L),L}y(oe,"lex");for(var I,kt,N,Gt,wt={},Mt,W,ce,Lt;;){if(kt=E[E.length-1],this.defaultActions[kt]?N=this.defaultActions[kt]:((I===null||typeof I>"u")&&(I=oe()),N=Rt[kt]&&Rt[kt][I]),typeof N>"u"||!N.length||!N[0]){var Kt="";Lt=[];for(Mt in Rt[kt])this.terminals_[Mt]&&Mt>ke&&Lt.push("'"+this.terminals_[Mt]+"'");D.showPosition?Kt="Parse error on line "+(Et+1)+`: `+D.showPosition()+` Expecting `+Lt.join(", ")+", got '"+(this.terminals_[I]||I)+"'":Kt="Parse error on line "+(Et+1)+": Unexpected "+(I==le?"end of input":"'"+(this.terminals_[I]||I)+"'"),this.parseError(Kt,{text:D.match,token:this.terminals_[I]||I,line:D.yylineno,loc:qt,expected:Lt})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+kt+", token: "+I);switch(N[0]){case 1:E.push(I),R.push(D.yytext),h.push(D.yylloc),E.push(N[1]),I=null,re=D.yyleng,f=D.yytext,Et=D.yylineno,qt=D.yylloc;break;case 2:if(W=this.productions_[N[1]][1],wt.$=R[R.length-W],wt._$={first_line:h[h.length-(W||1)].first_line,last_line:h[h.length-1].last_line,first_column:h[h.length-(W||1)].first_column,last_column:h[h.length-1].last_column},we&&(wt._$.range=[h[h.length-(W||1)].range[0],h[h.length-1].range[1]]),Gt=this.performAction.apply(wt,[f,re,Et,At.yy,N[1],R,h].concat(Ce)),typeof Gt<"u")return Gt;W&&(E=E.slice(0,-1*W*2),R=R.slice(0,-1*W),h=h.slice(0,-1*W)),E.push(this.productions_[N[1]][0]),R.push(wt.$),h.push(wt._$),ce=Rt[E[E.length-2]][E[E.length-1]],E.push(ce);break;case 3:return!0}}return!0},"parse")},Ae=(function(){var _t={EOF:1,parseError:y(function(v,E){if(this.yy.parser)this.yy.parser.parseError(v,E);else throw new Error(v)},"parseError"),setInput:y(function(x,v){return this.yy=v||this.yy||{},this._input=x,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:y(function(){var x=this._input[0];this.yytext+=x,this.yyleng++,this.offset++,this.match+=x,this.matched+=x;var v=x.match(/(?:\r\n?|\n).*/g);return v?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),x},"input"),unput:y(function(x){var v=x.length,E=x.split(/(?:\r\n?|\n)/g);this._input=x+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-v),this.offset-=v;var b=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),E.length-1&&(this.yylineno-=E.length-1);var R=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:E?(E.length===b.length?this.yylloc.first_column:0)+b[b.length-E.length].length-E[0].length:this.yylloc.first_column-v},this.options.ranges&&(this.yylloc.range=[R[0],R[0]+this.yyleng-v]),this.yyleng=this.yytext.length,this},"unput"),more:y(function(){return this._more=!0,this},"more"),reject:y(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:y(function(x){this.unput(this.match.slice(x))},"less"),pastInput:y(function(){var x=this.matched.substr(0,this.matched.length-this.match.length);return(x.length>20?"...":"")+x.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:y(function(){var x=this.match;return x.length<20&&(x+=this._input.substr(0,20-x.length)),(x.substr(0,20)+(x.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:y(function(){var x=this.pastInput(),v=new Array(x.length+1).join("-");return x+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/channel-d4fEaqwQ.js b/apps/kimi-code/dist-web/assets/channel-d4fEaqwQ.js deleted file mode 100644 index 73cb5a3b9..000000000 --- a/apps/kimi-code/dist-web/assets/channel-d4fEaqwQ.js +++ /dev/null @@ -1 +0,0 @@ -import{U as a,C as n}from"./mermaid.core-DaDTfY6S.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c}; diff --git a/apps/kimi-code/dist-web/assets/channel-xkK6nTGq.js b/apps/kimi-code/dist-web/assets/channel-xkK6nTGq.js new file mode 100644 index 000000000..3838ae216 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/channel-xkK6nTGq.js @@ -0,0 +1 @@ +import{U as a,C as n}from"./mermaid.core-CJB1tAev.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c}; diff --git a/apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DqVWYlyS.js b/apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DsAC7dRk.js similarity index 67% rename from apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DqVWYlyS.js rename to apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DsAC7dRk.js index a2f47c6f6..09a3ced2a 100644 --- a/apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DqVWYlyS.js +++ b/apps/kimi-code/dist-web/assets/chunk-2Q5K7J3B-DsAC7dRk.js @@ -1 +1 @@ -import{_ as i}from"./mermaid.core-DaDTfY6S.js";var r=class{constructor(t){this.init=t,this.records=this.init()}static{i(this,"ImperativeState")}reset(){this.records=this.init()}};export{r as I}; +import{_ as i}from"./mermaid.core-CJB1tAev.js";var r=class{constructor(t){this.init=t,this.records=this.init()}static{i(this,"ImperativeState")}reset(){this.records=this.init()}};export{r as I}; diff --git a/apps/kimi-code/dist-web/assets/chunk-32BRIVSS-_Sd4SrsJ.js b/apps/kimi-code/dist-web/assets/chunk-32BRIVSS-DUDRPqmY.js similarity index 96% rename from apps/kimi-code/dist-web/assets/chunk-32BRIVSS-_Sd4SrsJ.js rename to apps/kimi-code/dist-web/assets/chunk-32BRIVSS-DUDRPqmY.js index 308520d84..24d8ca128 100644 --- a/apps/kimi-code/dist-web/assets/chunk-32BRIVSS-_Sd4SrsJ.js +++ b/apps/kimi-code/dist-web/assets/chunk-32BRIVSS-DUDRPqmY.js @@ -1 +1 @@ -import{_ as i,d as l,n as d,j as o}from"./mermaid.core-DaDTfY6S.js";var x=i((r,t)=>{const e=r.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const s in t.attrs)e.attr(s,t.attrs[s]);return t.class&&e.attr("class",t.class),e},"drawRect"),p=i((r,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};x(r,e).lower()},"drawBackgroundRect"),y=i((r,t)=>{const e=t.text.replace(d," "),s=r.append("text");s.attr("x",t.x),s.attr("y",t.y),s.attr("class","legend"),s.style("text-anchor",t.anchor),t.class&&s.attr("class",t.class);const a=s.append("tspan");return a.attr("x",t.x+t.textMargin*2),a.text(e),s},"drawText"),m=i((r,t,e,s)=>{const a=r.append("image");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",n)},"drawImage"),g=i((r,t,e,s)=>{const a=r.append("use");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",`#${n}`)},"drawEmbeddedImage"),h=i(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),f=i(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj"),w=i(()=>{let r=l(".mermaidTooltip");return r.empty()&&(r=l("body").append("div").attr("class","mermaidTooltip").style("opacity",0).style("position","absolute").style("text-align","center").style("max-width","200px").style("padding","2px").style("font-size","12px").style("background","#ffffde").style("border","1px solid #333").style("border-radius","2px").style("pointer-events","none").style("z-index","100")),r},"createTooltip");export{p as a,f as b,g as c,x as d,m as e,w as f,h as g,y as h}; +import{_ as i,d as l,n as d,j as o}from"./mermaid.core-CJB1tAev.js";var x=i((r,t)=>{const e=r.append("rect");if(e.attr("x",t.x),e.attr("y",t.y),e.attr("fill",t.fill),e.attr("stroke",t.stroke),e.attr("width",t.width),e.attr("height",t.height),t.name&&e.attr("name",t.name),t.rx&&e.attr("rx",t.rx),t.ry&&e.attr("ry",t.ry),t.attrs!==void 0)for(const s in t.attrs)e.attr(s,t.attrs[s]);return t.class&&e.attr("class",t.class),e},"drawRect"),p=i((r,t)=>{const e={x:t.startx,y:t.starty,width:t.stopx-t.startx,height:t.stopy-t.starty,fill:t.fill,stroke:t.stroke,class:"rect"};x(r,e).lower()},"drawBackgroundRect"),y=i((r,t)=>{const e=t.text.replace(d," "),s=r.append("text");s.attr("x",t.x),s.attr("y",t.y),s.attr("class","legend"),s.style("text-anchor",t.anchor),t.class&&s.attr("class",t.class);const a=s.append("tspan");return a.attr("x",t.x+t.textMargin*2),a.text(e),s},"drawText"),m=i((r,t,e,s)=>{const a=r.append("image");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",n)},"drawImage"),g=i((r,t,e,s)=>{const a=r.append("use");a.attr("x",t),a.attr("y",e);const n=o.sanitizeUrl(s);a.attr("xlink:href",`#${n}`)},"drawEmbeddedImage"),h=i(()=>({x:0,y:0,width:100,height:100,fill:"#EDF2AE",stroke:"#666",anchor:"start",rx:0,ry:0}),"getNoteRect"),f=i(()=>({x:0,y:0,width:100,height:100,"text-anchor":"start",style:"#666",textMargin:0,rx:0,ry:0,tspan:!0}),"getTextObj"),w=i(()=>{let r=l(".mermaidTooltip");return r.empty()&&(r=l("body").append("div").attr("class","mermaidTooltip").style("opacity",0).style("position","absolute").style("text-align","center").style("max-width","200px").style("padding","2px").style("font-size","12px").style("background","#ffffde").style("border","1px solid #333").style("border-radius","2px").style("pointer-events","none").style("z-index","100")),r},"createTooltip");export{p as a,f as b,g as c,x as d,m as e,w as f,h as g,y as h}; diff --git a/apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-B87d3yQb.js b/apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-yyj9cAyF.js similarity index 83% rename from apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-B87d3yQb.js rename to apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-yyj9cAyF.js index a9aa966ae..5798bdcab 100644 --- a/apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-B87d3yQb.js +++ b/apps/kimi-code/dist-web/assets/chunk-5VM5RSS4-yyj9cAyF.js @@ -1,4 +1,4 @@ -import{_ as e}from"./mermaid.core-DaDTfY6S.js";var l=e(()=>` +import{_ as e}from"./mermaid.core-CJB1tAev.js";var l=e(()=>` /* Font Awesome icon styling - consolidated */ .label-icon { display: inline-block; diff --git a/apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-CyUsdK3n.js b/apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-BCWDroXJ.js similarity index 99% rename from apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-CyUsdK3n.js rename to apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-BCWDroXJ.js index d4962ee7f..e9fc77468 100644 --- a/apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-CyUsdK3n.js +++ b/apps/kimi-code/dist-web/assets/chunk-EX3LRPZG-BCWDroXJ.js @@ -1,4 +1,4 @@ -import{g as te}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as ee}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as f,l as _,c as $,x as se,y as ie,a as re,b as ae,g as ne,s as oe,o as le,p as ce,a9 as he,k as j,q as ue,d as bt,a5 as de}from"./mermaid.core-DaDTfY6S.js";import{f as fe}from"./chunk-32BRIVSS-_Sd4SrsJ.js";var vt=(function(){var t=f(function(V,a,d,r){for(d=d||{},r=V.length;r--;d[V[r]]=a);return d},"o"),e=[1,2],o=[1,3],s=[1,4],c=[2,4],h=[1,9],p=[1,11],y=[1,16],n=[1,17],T=[1,18],m=[1,19],O=[1,33],x=[1,20],k=[1,21],u=[1,22],L=[1,23],I=[1,24],v=[1,26],F=[1,27],C=[1,28],P=[1,29],w=[1,30],H=[1,31],it=[1,32],rt=[1,35],at=[1,36],nt=[1,37],ot=[1,38],z=[1,34],S=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],lt=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,39,40,41,45,48,51,52,53,54,57],xt=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],yt={trace:f(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"-->":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,CLICK:38,STRING:39,HREF:40,classDef:41,CLASSDEF_ID:42,CLASSDEF_STYLEOPTS:43,DEFAULT:44,style:45,STYLE_IDS:46,STYLEDEF_STYLEOPTS:47,class:48,CLASSENTITY_IDS:49,STYLECLASS:50,direction_tb:51,direction_bt:52,direction_rl:53,direction_lr:54,eol:55,";":56,EDGE_STATE:57,STYLE_SEPARATOR:58,left_of:59,right_of:60,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"-->",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"CLICK",39:"STRING",40:"HREF",41:"classDef",42:"CLASSDEF_ID",43:"CLASSDEF_STYLEOPTS",44:"DEFAULT",45:"style",46:"STYLE_IDS",47:"STYLEDEF_STYLEOPTS",48:"class",49:"CLASSENTITY_IDS",50:"STYLECLASS",51:"direction_tb",52:"direction_bt",53:"direction_rl",54:"direction_lr",56:";",57:"EDGE_STATE",58:"STYLE_SEPARATOR",59:"left_of",60:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[9,5],[9,5],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[55,1],[55,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:f(function(a,d,r,g,E,i,B){var l=i.length-1;switch(E){case 3:return g.setRootDoc(i[l]),i[l];case 4:this.$=[];break;case 5:i[l]!="nl"&&(i[l-1].push(i[l]),this.$=i[l-1]);break;case 6:case 7:this.$=i[l];break;case 8:this.$="nl";break;case 12:this.$=i[l];break;case 13:const Q=i[l-1];Q.description=g.trimColon(i[l]),this.$=Q;break;case 14:this.$={stmt:"relation",state1:i[l-2],state2:i[l]};break;case 15:const gt=g.trimColon(i[l]);this.$={stmt:"relation",state1:i[l-3],state2:i[l-1],description:gt};break;case 19:this.$={stmt:"state",id:i[l-3],type:"default",description:"",doc:i[l-1]};break;case 20:var Y=i[l],K=i[l-2].trim();if(i[l].match(":")){var ht=i[l].split(":");Y=ht[0],K=[K,ht[1]]}this.$={stmt:"state",id:Y,type:"default",description:K};break;case 21:this.$={stmt:"state",id:i[l-3],type:"default",description:i[l-5],doc:i[l-1]};break;case 22:this.$={stmt:"state",id:i[l],type:"fork"};break;case 23:this.$={stmt:"state",id:i[l],type:"join"};break;case 24:this.$={stmt:"state",id:i[l],type:"choice"};break;case 25:this.$={stmt:"state",id:g.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:i[l-1].trim(),note:{position:i[l-2].trim(),text:i[l].trim()}};break;case 29:this.$=i[l].trim(),g.setAccTitle(this.$);break;case 30:case 31:this.$=i[l].trim(),g.setAccDescription(this.$);break;case 32:this.$={stmt:"click",id:i[l-3],url:i[l-2],tooltip:i[l-1]};break;case 33:this.$={stmt:"click",id:i[l-3],url:i[l-1],tooltip:""};break;case 34:case 35:this.$={stmt:"classDef",id:i[l-1].trim(),classes:i[l].trim()};break;case 36:this.$={stmt:"style",id:i[l-1].trim(),styleClass:i[l].trim()};break;case 37:this.$={stmt:"applyClass",id:i[l-1].trim(),styleClass:i[l].trim()};break;case 38:g.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:g.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:g.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:g.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:i[l].trim(),type:"default",description:""};break;case 46:this.$={stmt:"state",id:i[l-2].trim(),classes:[i[l].trim()],type:"default",description:""};break;case 47:this.$={stmt:"state",id:i[l-2].trim(),classes:[i[l].trim()],type:"default",description:""};break}},"anonymous"),table:[{3:1,4:e,5:o,6:s},{1:[3]},{3:5,4:e,5:o,6:s},{3:6,4:e,5:o,6:s},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],c,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,5]),{9:39,10:12,11:13,12:14,13:15,16:y,17:n,19:T,22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,7]),t(S,[2,8]),t(S,[2,9]),t(S,[2,10]),t(S,[2,11]),t(S,[2,12],{14:[1,40],15:[1,41]}),t(S,[2,16]),{18:[1,42]},t(S,[2,18],{20:[1,43]}),{23:[1,44]},t(S,[2,22]),t(S,[2,23]),t(S,[2,24]),t(S,[2,25]),{30:45,31:[1,46],59:[1,47],60:[1,48]},t(S,[2,28]),{34:[1,49]},{36:[1,50]},t(S,[2,31]),{13:51,24:O,57:z},{42:[1,52],44:[1,53]},{46:[1,54]},{49:[1,55]},t(lt,[2,44],{58:[1,56]}),t(lt,[2,45],{58:[1,57]}),t(S,[2,38]),t(S,[2,39]),t(S,[2,40]),t(S,[2,41]),t(S,[2,6]),t(S,[2,13]),{13:58,24:O,57:z},t(S,[2,17]),t(xt,c,{7:59}),{24:[1,60]},{24:[1,61]},{23:[1,62]},{24:[2,48]},{24:[2,49]},t(S,[2,29]),t(S,[2,30]),{39:[1,63],40:[1,64]},{43:[1,65]},{43:[1,66]},{47:[1,67]},{50:[1,68]},{24:[1,69]},{24:[1,70]},t(S,[2,14],{14:[1,71]}),{4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,21:[1,72],22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,20],{20:[1,73]}),{31:[1,74]},{24:[1,75]},{39:[1,76]},{39:[1,77]},t(S,[2,34]),t(S,[2,35]),t(S,[2,36]),t(S,[2,37]),t(lt,[2,46]),t(lt,[2,47]),t(S,[2,15]),t(S,[2,19]),t(xt,c,{7:78}),t(S,[2,26]),t(S,[2,27]),{5:[1,79]},{5:[1,80]},{4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,21:[1,81],22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,32]),t(S,[2,33]),t(S,[2,21])],defaultActions:{5:[2,1],6:[2,2],47:[2,48],48:[2,49]},parseError:f(function(a,d){if(d.recoverable)this.trace(a);else{var r=new Error(a);throw r.hash=d,r}},"parseError"),parse:f(function(a){var d=this,r=[0],g=[],E=[null],i=[],B=this.table,l="",Y=0,K=0,ht=2,Q=1,gt=i.slice.call(arguments,1),b=Object.create(this.lexer),U={yy:{}};for(var Tt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Tt)&&(U.yy[Tt]=this.yy[Tt]);b.setInput(a,U.yy),U.yy.lexer=b,U.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var Et=b.yylloc;i.push(Et);var Qt=b.options&&b.options.ranges;typeof U.yy.parseError=="function"?this.parseError=U.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Zt(N){r.length=r.length-2*N,E.length=E.length-N,i.length=i.length-N}f(Zt,"popStack");function Lt(){var N;return N=g.pop()||b.lex()||Q,typeof N!="number"&&(N instanceof Array&&(g=N,N=g.pop()),N=d.symbols_[N]||N),N}f(Lt,"lex");for(var A,W,R,_t,X={},ut,G,It,dt;;){if(W=r[r.length-1],this.defaultActions[W]?R=this.defaultActions[W]:((A===null||typeof A>"u")&&(A=Lt()),R=B[W]&&B[W][A]),typeof R>"u"||!R.length||!R[0]){var mt="";dt=[];for(ut in B[W])this.terminals_[ut]&&ut>ht&&dt.push("'"+this.terminals_[ut]+"'");b.showPosition?mt="Parse error on line "+(Y+1)+`: +import{g as te}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as ee}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as f,l as _,c as $,x as se,y as ie,a as re,b as ae,g as ne,s as oe,o as le,p as ce,a9 as he,k as j,q as ue,d as bt,a5 as de}from"./mermaid.core-CJB1tAev.js";import{f as fe}from"./chunk-32BRIVSS-DUDRPqmY.js";var vt=(function(){var t=f(function(V,a,d,r){for(d=d||{},r=V.length;r--;d[V[r]]=a);return d},"o"),e=[1,2],o=[1,3],s=[1,4],c=[2,4],h=[1,9],p=[1,11],y=[1,16],n=[1,17],T=[1,18],m=[1,19],O=[1,33],x=[1,20],k=[1,21],u=[1,22],L=[1,23],I=[1,24],v=[1,26],F=[1,27],C=[1,28],P=[1,29],w=[1,30],H=[1,31],it=[1,32],rt=[1,35],at=[1,36],nt=[1,37],ot=[1,38],z=[1,34],S=[1,4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],lt=[1,4,5,14,15,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,39,40,41,45,48,51,52,53,54,57],xt=[4,5,16,17,19,21,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],yt={trace:f(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NL:5,SD:6,document:7,line:8,statement:9,classDefStatement:10,styleStatement:11,cssClassStatement:12,idStatement:13,DESCR:14,"-->":15,HIDE_EMPTY:16,scale:17,WIDTH:18,COMPOSIT_STATE:19,STRUCT_START:20,STRUCT_STOP:21,STATE_DESCR:22,AS:23,ID:24,FORK:25,JOIN:26,CHOICE:27,CONCURRENT:28,note:29,notePosition:30,NOTE_TEXT:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,CLICK:38,STRING:39,HREF:40,classDef:41,CLASSDEF_ID:42,CLASSDEF_STYLEOPTS:43,DEFAULT:44,style:45,STYLE_IDS:46,STYLEDEF_STYLEOPTS:47,class:48,CLASSENTITY_IDS:49,STYLECLASS:50,direction_tb:51,direction_bt:52,direction_rl:53,direction_lr:54,eol:55,";":56,EDGE_STATE:57,STYLE_SEPARATOR:58,left_of:59,right_of:60,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NL",6:"SD",14:"DESCR",15:"-->",16:"HIDE_EMPTY",17:"scale",18:"WIDTH",19:"COMPOSIT_STATE",20:"STRUCT_START",21:"STRUCT_STOP",22:"STATE_DESCR",23:"AS",24:"ID",25:"FORK",26:"JOIN",27:"CHOICE",28:"CONCURRENT",29:"note",31:"NOTE_TEXT",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",38:"CLICK",39:"STRING",40:"HREF",41:"classDef",42:"CLASSDEF_ID",43:"CLASSDEF_STYLEOPTS",44:"DEFAULT",45:"style",46:"STYLE_IDS",47:"STYLEDEF_STYLEOPTS",48:"class",49:"CLASSENTITY_IDS",50:"STYLECLASS",51:"direction_tb",52:"direction_bt",53:"direction_rl",54:"direction_lr",56:";",57:"EDGE_STATE",58:"STYLE_SEPARATOR",59:"left_of",60:"right_of"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,3],[9,4],[9,1],[9,2],[9,1],[9,4],[9,3],[9,6],[9,1],[9,1],[9,1],[9,1],[9,4],[9,4],[9,1],[9,2],[9,2],[9,1],[9,5],[9,5],[10,3],[10,3],[11,3],[12,3],[32,1],[32,1],[32,1],[32,1],[55,1],[55,1],[13,1],[13,1],[13,3],[13,3],[30,1],[30,1]],performAction:f(function(a,d,r,g,E,i,B){var l=i.length-1;switch(E){case 3:return g.setRootDoc(i[l]),i[l];case 4:this.$=[];break;case 5:i[l]!="nl"&&(i[l-1].push(i[l]),this.$=i[l-1]);break;case 6:case 7:this.$=i[l];break;case 8:this.$="nl";break;case 12:this.$=i[l];break;case 13:const Q=i[l-1];Q.description=g.trimColon(i[l]),this.$=Q;break;case 14:this.$={stmt:"relation",state1:i[l-2],state2:i[l]};break;case 15:const gt=g.trimColon(i[l]);this.$={stmt:"relation",state1:i[l-3],state2:i[l-1],description:gt};break;case 19:this.$={stmt:"state",id:i[l-3],type:"default",description:"",doc:i[l-1]};break;case 20:var Y=i[l],K=i[l-2].trim();if(i[l].match(":")){var ht=i[l].split(":");Y=ht[0],K=[K,ht[1]]}this.$={stmt:"state",id:Y,type:"default",description:K};break;case 21:this.$={stmt:"state",id:i[l-3],type:"default",description:i[l-5],doc:i[l-1]};break;case 22:this.$={stmt:"state",id:i[l],type:"fork"};break;case 23:this.$={stmt:"state",id:i[l],type:"join"};break;case 24:this.$={stmt:"state",id:i[l],type:"choice"};break;case 25:this.$={stmt:"state",id:g.getDividerId(),type:"divider"};break;case 26:this.$={stmt:"state",id:i[l-1].trim(),note:{position:i[l-2].trim(),text:i[l].trim()}};break;case 29:this.$=i[l].trim(),g.setAccTitle(this.$);break;case 30:case 31:this.$=i[l].trim(),g.setAccDescription(this.$);break;case 32:this.$={stmt:"click",id:i[l-3],url:i[l-2],tooltip:i[l-1]};break;case 33:this.$={stmt:"click",id:i[l-3],url:i[l-1],tooltip:""};break;case 34:case 35:this.$={stmt:"classDef",id:i[l-1].trim(),classes:i[l].trim()};break;case 36:this.$={stmt:"style",id:i[l-1].trim(),styleClass:i[l].trim()};break;case 37:this.$={stmt:"applyClass",id:i[l-1].trim(),styleClass:i[l].trim()};break;case 38:g.setDirection("TB"),this.$={stmt:"dir",value:"TB"};break;case 39:g.setDirection("BT"),this.$={stmt:"dir",value:"BT"};break;case 40:g.setDirection("RL"),this.$={stmt:"dir",value:"RL"};break;case 41:g.setDirection("LR"),this.$={stmt:"dir",value:"LR"};break;case 44:case 45:this.$={stmt:"state",id:i[l].trim(),type:"default",description:""};break;case 46:this.$={stmt:"state",id:i[l-2].trim(),classes:[i[l].trim()],type:"default",description:""};break;case 47:this.$={stmt:"state",id:i[l-2].trim(),classes:[i[l].trim()],type:"default",description:""};break}},"anonymous"),table:[{3:1,4:e,5:o,6:s},{1:[3]},{3:5,4:e,5:o,6:s},{3:6,4:e,5:o,6:s},t([1,4,5,16,17,19,22,24,25,26,27,28,29,33,35,37,38,41,45,48,51,52,53,54,57],c,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,5]),{9:39,10:12,11:13,12:14,13:15,16:y,17:n,19:T,22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,7]),t(S,[2,8]),t(S,[2,9]),t(S,[2,10]),t(S,[2,11]),t(S,[2,12],{14:[1,40],15:[1,41]}),t(S,[2,16]),{18:[1,42]},t(S,[2,18],{20:[1,43]}),{23:[1,44]},t(S,[2,22]),t(S,[2,23]),t(S,[2,24]),t(S,[2,25]),{30:45,31:[1,46],59:[1,47],60:[1,48]},t(S,[2,28]),{34:[1,49]},{36:[1,50]},t(S,[2,31]),{13:51,24:O,57:z},{42:[1,52],44:[1,53]},{46:[1,54]},{49:[1,55]},t(lt,[2,44],{58:[1,56]}),t(lt,[2,45],{58:[1,57]}),t(S,[2,38]),t(S,[2,39]),t(S,[2,40]),t(S,[2,41]),t(S,[2,6]),t(S,[2,13]),{13:58,24:O,57:z},t(S,[2,17]),t(xt,c,{7:59}),{24:[1,60]},{24:[1,61]},{23:[1,62]},{24:[2,48]},{24:[2,49]},t(S,[2,29]),t(S,[2,30]),{39:[1,63],40:[1,64]},{43:[1,65]},{43:[1,66]},{47:[1,67]},{50:[1,68]},{24:[1,69]},{24:[1,70]},t(S,[2,14],{14:[1,71]}),{4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,21:[1,72],22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,20],{20:[1,73]}),{31:[1,74]},{24:[1,75]},{39:[1,76]},{39:[1,77]},t(S,[2,34]),t(S,[2,35]),t(S,[2,36]),t(S,[2,37]),t(lt,[2,46]),t(lt,[2,47]),t(S,[2,15]),t(S,[2,19]),t(xt,c,{7:78}),t(S,[2,26]),t(S,[2,27]),{5:[1,79]},{5:[1,80]},{4:h,5:p,8:8,9:10,10:12,11:13,12:14,13:15,16:y,17:n,19:T,21:[1,81],22:m,24:O,25:x,26:k,27:u,28:L,29:I,32:25,33:v,35:F,37:C,38:P,41:w,45:H,48:it,51:rt,52:at,53:nt,54:ot,57:z},t(S,[2,32]),t(S,[2,33]),t(S,[2,21])],defaultActions:{5:[2,1],6:[2,2],47:[2,48],48:[2,49]},parseError:f(function(a,d){if(d.recoverable)this.trace(a);else{var r=new Error(a);throw r.hash=d,r}},"parseError"),parse:f(function(a){var d=this,r=[0],g=[],E=[null],i=[],B=this.table,l="",Y=0,K=0,ht=2,Q=1,gt=i.slice.call(arguments,1),b=Object.create(this.lexer),U={yy:{}};for(var Tt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Tt)&&(U.yy[Tt]=this.yy[Tt]);b.setInput(a,U.yy),U.yy.lexer=b,U.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var Et=b.yylloc;i.push(Et);var Qt=b.options&&b.options.ranges;typeof U.yy.parseError=="function"?this.parseError=U.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Zt(N){r.length=r.length-2*N,E.length=E.length-N,i.length=i.length-N}f(Zt,"popStack");function Lt(){var N;return N=g.pop()||b.lex()||Q,typeof N!="number"&&(N instanceof Array&&(g=N,N=g.pop()),N=d.symbols_[N]||N),N}f(Lt,"lex");for(var A,W,R,_t,X={},ut,G,It,dt;;){if(W=r[r.length-1],this.defaultActions[W]?R=this.defaultActions[W]:((A===null||typeof A>"u")&&(A=Lt()),R=B[W]&&B[W][A]),typeof R>"u"||!R.length||!R[0]){var mt="";dt=[];for(ut in B[W])this.terminals_[ut]&&ut>ht&&dt.push("'"+this.terminals_[ut]+"'");b.showPosition?mt="Parse error on line "+(Y+1)+`: `+b.showPosition()+` Expecting `+dt.join(", ")+", got '"+(this.terminals_[A]||A)+"'":mt="Parse error on line "+(Y+1)+": Unexpected "+(A==Q?"end of input":"'"+(this.terminals_[A]||A)+"'"),this.parseError(mt,{text:b.match,token:this.terminals_[A]||A,line:b.yylineno,loc:Et,expected:dt})}if(R[0]instanceof Array&&R.length>1)throw new Error("Parse Error: multiple actions possible at state: "+W+", token: "+A);switch(R[0]){case 1:r.push(A),E.push(b.yytext),i.push(b.yylloc),r.push(R[1]),A=null,K=b.yyleng,l=b.yytext,Y=b.yylineno,Et=b.yylloc;break;case 2:if(G=this.productions_[R[1]][1],X.$=E[E.length-G],X._$={first_line:i[i.length-(G||1)].first_line,last_line:i[i.length-1].last_line,first_column:i[i.length-(G||1)].first_column,last_column:i[i.length-1].last_column},Qt&&(X._$.range=[i[i.length-(G||1)].range[0],i[i.length-1].range[1]]),_t=this.performAction.apply(X,[l,K,Y,U.yy,R[1],E,i].concat(gt)),typeof _t<"u")return _t;G&&(r=r.slice(0,-1*G*2),E=E.slice(0,-1*G),i=i.slice(0,-1*G)),r.push(this.productions_[R[1]][0]),E.push(X.$),i.push(X._$),It=B[r[r.length-2]][r[r.length-1]],r.push(It);break;case 3:return!0}}return!0},"parse")},qt=(function(){var V={EOF:1,parseError:f(function(d,r){if(this.yy.parser)this.yy.parser.parseError(d,r);else throw new Error(d)},"parseError"),setInput:f(function(a,d){return this.yy=d||this.yy||{},this._input=a,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:f(function(){var a=this._input[0];this.yytext+=a,this.yyleng++,this.offset++,this.match+=a,this.matched+=a;var d=a.match(/(?:\r\n?|\n).*/g);return d?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),a},"input"),unput:f(function(a){var d=a.length,r=a.split(/(?:\r\n?|\n)/g);this._input=a+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-d),this.offset-=d;var g=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var E=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===g.length?this.yylloc.first_column:0)+g[g.length-r.length].length-r[0].length:this.yylloc.first_column-d},this.options.ranges&&(this.yylloc.range=[E[0],E[0]+this.yyleng-d]),this.yyleng=this.yytext.length,this},"unput"),more:f(function(){return this._more=!0,this},"more"),reject:f(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:f(function(a){this.unput(this.match.slice(a))},"less"),pastInput:f(function(){var a=this.matched.substr(0,this.matched.length-this.match.length);return(a.length>20?"...":"")+a.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:f(function(){var a=this.match;return a.length<20&&(a+=this._input.substr(0,20-a.length)),(a.substr(0,20)+(a.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:f(function(){var a=this.pastInput(),d=new Array(a.length+1).join("-");return a+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-XhS5NGpP.js b/apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-Dsg3gA8l.js similarity index 71% rename from apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-XhS5NGpP.js rename to apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-Dsg3gA8l.js index 889894642..ef3bb13e5 100644 --- a/apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-XhS5NGpP.js +++ b/apps/kimi-code/dist-web/assets/chunk-JWPE2WC7-Dsg3gA8l.js @@ -1 +1 @@ -import{_ as i}from"./mermaid.core-DaDTfY6S.js";function t(c,e){c.accDescr&&e.setAccDescription?.(c.accDescr),c.accTitle&&e.setAccTitle?.(c.accTitle),c.title&&e.setDiagramTitle?.(c.title)}i(t,"populateCommonDb");export{t as p}; +import{_ as i}from"./mermaid.core-CJB1tAev.js";function t(c,e){c.accDescr&&e.setAccDescription?.(c.accDescr),c.accTitle&&e.setAccTitle?.(c.accTitle),c.title&&e.setDiagramTitle?.(c.title)}i(t,"populateCommonDb");export{t as p}; diff --git a/apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-Ce2Y728v.js b/apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-JQ2kJR9W.js similarity index 99% rename from apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-Ce2Y728v.js rename to apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-JQ2kJR9W.js index d236c6b49..ca6d13d0a 100644 --- a/apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-Ce2Y728v.js +++ b/apps/kimi-code/dist-web/assets/chunk-MOJQB5TN-JQ2kJR9W.js @@ -1,4 +1,4 @@ -import{_ as p,l as w,F as L,z as E,q as I,W as X,e as q,i as H,c as G}from"./mermaid.core-DaDTfY6S.js";var z="",b="",N="",A=[],R=new Map,k=p(e=>H(e,G()),"sanitizeText"),F=p(e=>{switch(e.type){case"terminal":return{...e,value:k(e.value)};case"nonterminal":return{...e,name:k(e.name)};case"sequence":return{...e,elements:e.elements.map(F)};case"choice":return{...e,alternatives:e.alternatives.map(F)};case"optional":return{...e,element:F(e.element)};case"repetition":return{...e,element:F(e.element),separator:e.separator?F(e.separator):void 0};case"special":return{...e,text:k(e.text)}}},"sanitizeAstNode"),U=p(()=>{z="",b="",N="",A.length=0,R.clear(),I(),w.debug("[Railroad] Database cleared")},"clear"),W=p(e=>{z=k(e),w.debug("[Railroad] Title set:",e)},"setTitle"),_=p(()=>z,"getTitle"),j=p(e=>{const i={...e,name:k(e.name),definition:F(e.definition),comment:e.comment?k(e.comment):void 0};w.debug("[Railroad] Adding rule:",i.name),R.has(i.name)&&w.warn(`[Railroad] Rule '${i.name}' is already defined. Overwriting.`),A.push(i),R.set(i.name,i)},"addRule"),K=p(()=>A,"getRules"),J=p(e=>R.get(e),"getRule"),Q=p(e=>{b=k(e).replace(/^\s+/g,""),w.debug("[Railroad] Accessibility title set:",e)},"setAccTitle"),Z=p(()=>b,"getAccTitle"),V=p(e=>{N=k(e).replace(/\n\s+/g,` +import{_ as p,l as w,F as L,z as E,q as I,W as X,e as q,i as H,c as G}from"./mermaid.core-CJB1tAev.js";var z="",b="",N="",A=[],R=new Map,k=p(e=>H(e,G()),"sanitizeText"),F=p(e=>{switch(e.type){case"terminal":return{...e,value:k(e.value)};case"nonterminal":return{...e,name:k(e.name)};case"sequence":return{...e,elements:e.elements.map(F)};case"choice":return{...e,alternatives:e.alternatives.map(F)};case"optional":return{...e,element:F(e.element)};case"repetition":return{...e,element:F(e.element),separator:e.separator?F(e.separator):void 0};case"special":return{...e,text:k(e.text)}}},"sanitizeAstNode"),U=p(()=>{z="",b="",N="",A.length=0,R.clear(),I(),w.debug("[Railroad] Database cleared")},"clear"),W=p(e=>{z=k(e),w.debug("[Railroad] Title set:",e)},"setTitle"),_=p(()=>z,"getTitle"),j=p(e=>{const i={...e,name:k(e.name),definition:F(e.definition),comment:e.comment?k(e.comment):void 0};w.debug("[Railroad] Adding rule:",i.name),R.has(i.name)&&w.warn(`[Railroad] Rule '${i.name}' is already defined. Overwriting.`),A.push(i),R.set(i.name,i)},"addRule"),K=p(()=>A,"getRules"),J=p(e=>R.get(e),"getRule"),Q=p(e=>{b=k(e).replace(/^\s+/g,""),w.debug("[Railroad] Accessibility title set:",e)},"setAccTitle"),Z=p(()=>b,"getAccTitle"),V=p(e=>{N=k(e).replace(/\n\s+/g,` `),w.debug("[Railroad] Accessibility description set:",e)},"setAccDescription"),ee=p(()=>N,"getAccDescription"),te=W,re=_,ie={clear:U,setTitle:W,getTitle:_,addRule:j,getRules:K,getRule:J,setAccTitle:Q,getAccTitle:Z,setAccDescription:V,getAccDescription:ee,setDiagramTitle:te,getDiagramTitle:re},g={compactMode:!1,padding:10,verticalSeparation:8,horizontalSeparation:10,arcRadius:10,fontSize:14,fontFamily:"monospace",terminalFill:"#FFFFC0",terminalStroke:"#000000",terminalTextColor:"#000000",nonTerminalFill:"#FFFFFF",nonTerminalStroke:"#000000",nonTerminalTextColor:"#000000",lineColor:"#000000",strokeWidth:2,markerFill:"#000000",commentFill:"#E8E8E8",commentStroke:"#888888",commentTextColor:"#666666",specialFill:"#F0E0FF",specialStroke:"#8800CC",ruleNameColor:"#000066",showMarkers:!0,markerRadius:5},ne=/^#(?:[\da-f]{3,4}|[\da-f]{6}|[\da-f]{8})$|^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch)\([\d\s%+,./-]+\)$|^[a-z]+$/i,ae=/^[\w "',.-]+$/,oe=new Set(["compactMode","padding","verticalSeparation","horizontalSeparation","arcRadius","fontSize","fontFamily","terminalFill","terminalStroke","terminalTextColor","nonTerminalFill","nonTerminalStroke","nonTerminalTextColor","lineColor","strokeWidth","markerFill","commentFill","commentStroke","commentTextColor","specialFill","specialStroke","ruleNameColor","showMarkers","markerRadius"]),B=p(e=>e?Object.keys(e).every(i=>i==="railroad"||oe.has(i)):!1,"isRailroadStyleOptions"),le=p(e=>e?"railroad"in e&&e.railroad?e.railroad:B(e)?e:{}:{},"extractRailroadOverrides"),se=p(e=>{if(!e||B(e))return{};const{railroad:i,svgId:a,theme:r,look:t,...n}=e;return n},"extractThemeOverrides"),m=p((e,i)=>{if(typeof e!="string")return i;const a=e.trim();return ne.test(a)?a:i},"sanitizeColorValue"),Y=p((e,i)=>{if(typeof e!="string")return i;const a=e.trim();return ae.test(a)?a:i},"sanitizeFontFamilyValue"),S=p((e,i)=>{const a=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):Number.NaN;return Number.isFinite(a)&&a>=0?a:i},"sanitizeNumberValue"),de=p(e=>{const i=typeof e=="number"?e:typeof e=="string"?Number.parseFloat(e):Number.NaN;return Number.isFinite(i)&&i>0?i:void 0},"parseThemeFontSize"),ce=p(e=>{const i=Y(e.fontFamily,g.fontFamily),a=de(e.fontSize)??g.fontSize;return{...g,fontFamily:i,fontSize:a,terminalFill:m(e.secondBkg??e.secondaryColor,g.terminalFill),terminalStroke:m(e.secondaryBorderColor??e.lineColor,g.terminalStroke),terminalTextColor:m(e.secondaryTextColor??e.textColor,g.terminalTextColor),nonTerminalFill:m(e.mainBkg??e.background,g.nonTerminalFill),nonTerminalStroke:m(e.primaryBorderColor??e.lineColor,g.nonTerminalStroke),nonTerminalTextColor:m(e.primaryTextColor??e.textColor,g.nonTerminalTextColor),lineColor:m(e.lineColor,g.lineColor),markerFill:m(e.lineColor,g.markerFill),commentFill:m(e.labelBackground??e.tertiaryColor,g.commentFill),commentStroke:m(e.tertiaryBorderColor??e.lineColor,g.commentStroke),commentTextColor:m(e.tertiaryTextColor??e.textColor,g.commentTextColor),specialFill:m(e.tertiaryColor??e.secondaryColor,g.specialFill),specialStroke:m(e.tertiaryBorderColor??e.secondaryBorderColor,g.specialStroke),ruleNameColor:m(e.titleColor??e.textColor,g.ruleNameColor)}},"buildThemeDefaults"),M=p(e=>{const i=E(),a={...X(),...i.themeVariables??{},...se(e)},r=ce(a),t={...i.railroad??{},...le(e)};return{compactMode:t.compactMode??r.compactMode,padding:S(t.padding,r.padding),verticalSeparation:S(t.verticalSeparation,r.verticalSeparation),horizontalSeparation:S(t.horizontalSeparation,r.horizontalSeparation),arcRadius:S(t.arcRadius,r.arcRadius),fontSize:S(t.fontSize,r.fontSize),fontFamily:Y(t.fontFamily,r.fontFamily),terminalFill:m(t.terminalFill,r.terminalFill),terminalStroke:m(t.terminalStroke,r.terminalStroke),terminalTextColor:m(t.terminalTextColor,r.terminalTextColor),nonTerminalFill:m(t.nonTerminalFill,r.nonTerminalFill),nonTerminalStroke:m(t.nonTerminalStroke,r.nonTerminalStroke),nonTerminalTextColor:m(t.nonTerminalTextColor,r.nonTerminalTextColor),lineColor:m(t.lineColor,r.lineColor),strokeWidth:S(t.strokeWidth,r.strokeWidth),markerFill:m(t.markerFill,r.markerFill),commentFill:m(t.commentFill,r.commentFill),commentStroke:m(t.commentStroke,r.commentStroke),commentTextColor:m(t.commentTextColor,r.commentTextColor),specialFill:m(t.specialFill,r.specialFill),specialStroke:m(t.specialStroke,r.specialStroke),ruleNameColor:m(t.ruleNameColor,r.ruleNameColor),showMarkers:t.showMarkers??r.showMarkers,markerRadius:S(t.markerRadius,r.markerRadius)}},"buildRailroadStyleOptions"),ue=p(e=>{const{fontFamily:i,fontSize:a,terminalFill:r,terminalStroke:t,terminalTextColor:n,nonTerminalFill:h,nonTerminalStroke:s,nonTerminalTextColor:o,lineColor:u,strokeWidth:c,markerFill:d,commentFill:x,commentStroke:l,commentTextColor:f,specialFill:y,specialStroke:v,ruleNameColor:C}=M(e);return` .railroad-diagram { font-family: ${i}; diff --git a/apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-D1Yl7opn.js b/apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-Df2V79id.js similarity index 99% rename from apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-D1Yl7opn.js rename to apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-Df2V79id.js index 17ac894a2..b0c5afb3c 100644 --- a/apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-D1Yl7opn.js +++ b/apps/kimi-code/dist-web/assets/chunk-RYQCIY6F-Df2V79id.js @@ -1 +1 @@ -import{_ as u,l as i}from"./mermaid.core-DaDTfY6S.js";import{i as m,G as y}from"./graph-DOmOIIwC.js";import{b as _,m as X}from"./map-DxJ2ADlA.js";var j=4;function p(e){return _(e,j)}function C(e){var r={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:F(e),edges:M(e)};return m(e.graph())||(r.value=p(e.graph())),r}function F(e){return X(e.nodes(),function(r){var n=e.node(r),s=e.parent(r),t={v:r};return m(n)||(t.value=n),m(s)||(t.parent=s),t})}function M(e){return X(e.edges(),function(r){var n=e.edge(r),s={v:r.v,w:r.w};return m(r.name)||(s.name=r.name),m(n)||(s.value=n),s})}var c=new Map,w=new Map,A=new Map,J=u(()=>{w.clear(),A.clear(),c.clear()},"clear"),v=u((e,r)=>{const n=w.get(r)||[];return i.trace("In isDescendant",r," ",e," = ",n.includes(e)),n.includes(e)},"isDescendant"),R=u((e,r)=>{const n=w.get(r)||[];return i.info("Descendants of ",r," is ",n),i.info("Edge is ",e),e.v===r||e.w===r?!1:n?n.includes(e.v)||v(e.v,r)||v(e.w,r)||n.includes(e.w):(i.debug("Tilt, ",r,",not in descendants"),!1)},"edgeInCluster"),b=u((e,r,n,s)=>{i.warn("Copying children of ",e,"root",s,"data",r.node(e),s);const t=r.children(e)||[];e!==s&&t.push(e),i.warn("Copying (nodes) clusterId",e,"nodes",t),t.forEach(o=>{if(r.children(o).length>0)b(o,r,n,s);else{const l=r.node(o);i.info("cp ",o," to ",s," with parent ",e),n.setNode(o,l),s!==r.parent(o)&&(i.warn("Setting parent",o,r.parent(o)),n.setParent(o,r.parent(o))),e!==s&&o!==e?(i.debug("Setting parent",o,e),n.setParent(o,e)):(i.info("In copy ",e,"root",s,"data",r.node(e),s),i.debug("Not Setting parent for node=",o,"cluster!==rootId",e!==s,"node!==clusterId",o!==e));const f=r.edges(o);i.debug("Copying Edges",f),f.forEach(a=>{i.info("Edge",a);const d=r.edge(a.v,a.w,a.name);i.info("Edge data",d,s);try{if(R(a,s)){const g=w.get(s)||[],E=g.includes(a.v)||v(a.v,s)||a.v===s,x=g.includes(a.w)||v(a.w,s)||a.w===s;if(E&&x)i.info("Copying as ",a.v,a.w,d,a.name),n.setEdge(a.v,a.w,d,a.name),i.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]));else{const N=E?s:a.v,h=x?s:a.w;i.info("Rebinding cross-boundary edge as ",N,h,d,a.name),r.setEdge(N,h,d,a.name)}}else i.info("Skipping copy of edge ",a.v,"-->",a.w," rootId: ",s," clusterId:",e)}catch(g){i.error(g)}})}i.debug("Removing node",o),r.removeNode(o)})},"copy"),O=u((e,r)=>{const n=r.children(e);let s=[...n];for(const t of n)A.set(t,e),s=[...s,...O(t,r)];return s},"extractDescendants"),P=u((e,r,n)=>{const s=e.edges().filter(a=>a.v===r||a.w===r),t=e.edges().filter(a=>a.v===n||a.w===n),o=s.map(a=>({v:a.v===r?n:a.v,w:a.w===r?r:a.w})),l=t.map(a=>({v:a.v,w:a.w}));return o.filter(a=>l.some(d=>a.v===d.v&&a.w===d.w))},"findCommonEdges"),D=u((e,r,n)=>{const s=r.children(e);if(i.trace("Searching children of id ",e,s),s.length<1)return e;let t;for(const o of s){const l=D(o,r,n),f=P(r,n,l);if(l)if(f.length>0)t=l;else return l}return t},"findNonClusterChild"),S=u(e=>!c.has(e)||!c.get(e).externalConnections?e:c.has(e)?c.get(e).id:e,"getAnchorId"),U=u((e,r)=>{if(!e||r>10){i.debug("Opting out, no graph ");return}else i.debug("Opting in, graph ");e.nodes().forEach(function(n){e.children(n).length>0&&(i.warn("Cluster identified",n," Replacement id in edges: ",D(n,e,n)),w.set(n,O(n,e)),c.set(n,{id:D(n,e,n),clusterData:e.node(n)}))}),e.nodes().forEach(function(n){const s=e.children(n),t=e.edges();s.length>0?(i.debug("Cluster identified",n,w),t.forEach(o=>{const l=v(o.v,n),f=v(o.w,n);l^f&&(i.warn("Edge: ",o," leaves cluster ",n),i.warn("Descendants of XXX ",n,": ",w.get(n)),c.get(n).externalConnections=!0)})):i.debug("Not a cluster ",n,w)});for(let n of c.keys()){const s=c.get(n).id,t=e.parent(s);t!==n&&c.has(t)&&!c.get(t).externalConnections&&(c.get(n).id=t);const o=e.edges().some(l=>l.v===n);if(s&&c.get(n)?.externalConnections&&o&&L(e,s,n)){const l=T(e,n,e.parent(s));l&&(c.get(n).id=l)}}e.edges().forEach(function(n){const s=e.edge(n);i.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),i.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let t=n.v,o=n.w;if(i.warn("Fix XXX",c,"ids:",n.v,n.w,"Translating: ",c.get(n.v)," --- ",c.get(n.w)),c.get(n.v)||c.get(n.w)){if(i.warn("Fixing and trying - removing XXX",n.v,n.w,n.name),t=S(n.v),o=S(n.w),e.removeEdge(n.v,n.w,n.name),t!==n.v){const l=e.parent(t);c.get(l).externalConnections=!0,s.fromCluster=n.v}if(o!==n.w){const l=e.parent(o);c.get(l).externalConnections=!0,s.toCluster=n.w}i.warn("Fix Replacing with XXX",t,o,n.name),e.setEdge(t,o,s,n.name)}}),i.warn("Adjusted Graph",C(e)),k(e,0),i.trace(c)},"adjustClustersAndEdges"),k=u((e,r)=>{if(i.warn("extractor - ",r,C(e),e.children("D")),r>10){i.error("Bailing out");return}let n=e.nodes(),s=!1;for(const t of n){const o=e.children(t);s=s||o.length>0}if(!s){i.debug("Done, no node has children",e.nodes());return}i.debug("Nodes = ",n,r);for(const t of n)if(i.debug("Extracting node",t,c,c.has(t)&&!c.get(t).externalConnections,!e.parent(t),e.node(t),e.children("D")," Depth ",r),!c.has(t))i.debug("Not a cluster",t,r);else if(c.get(t)?.clusterData?.explicitDir&&e.children(t)&&e.children(t).length>0){i.warn("Cluster with explicit dir, creating subgraph for children",t,r);const o=c.get(t).clusterData.dir,l=new y({multigraph:!0,compound:!0}).setGraph({rankdir:o,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});b(t,e,l,t);const f=e.node(t)||{};e.setNode(t,{...f,clusterNode:!0,id:t,clusterData:c.get(t).clusterData,label:c.get(t).label,graph:l}),i.warn("Subgraph for cluster with explicit dir created:",t,C(l))}else if(!c.get(t).externalConnections&&e.children(t)&&e.children(t).length>0){i.warn("Cluster without external connections, without a parent and with children",t,r);let l=e.graph().rankdir==="TB"?"LR":"TB";c.get(t)?.clusterData?.dir&&(l=c.get(t).clusterData.dir,i.warn("Fixing dir",c.get(t).clusterData.dir,l));const f=new y({multigraph:!0,compound:!0}).setGraph({rankdir:l,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});b(t,e,f,t);const a=e.node(t)||{};e.setNode(t,{...a,clusterNode:!0,id:t,clusterData:c.get(t).clusterData,label:c.get(t).label,graph:f}),i.debug("Old graph after copy",C(e))}else i.warn("Cluster ** ",t," **not meeting the criteria !externalConnections:",!c.get(t).externalConnections," no parent: ",!e.parent(t)," children ",e.children(t)&&e.children(t).length>0,e.children("D"),r),i.debug(c);n=e.nodes(),i.warn("New list of nodes",n);for(const t of n){const o=e.node(t);i.warn(" Now next level",t,o),o?.clusterNode&&k(o.graph,r+1)}},"extractor"),B=u((e,r)=>{if(r.length===0)return[];let n=Object.assign([],r);return r.forEach(s=>{const t=e.children(s),o=B(e,t);n=[...n,...o]}),n},"sorter"),W=u(e=>B(e,e.children()),"sortNodesByHierarchy"),L=u((e,r,n)=>{let s=e.parent(r);for(;s&&s!==n;){const t=c.get(s);if(t&&!t.externalConnections)return!0;s=e.parent(s)}return!1},"isNodeInExtractableCluster"),T=u((e,r,n)=>{const s=e.children(r)??[];for(const t of s){if(t===n||v(t,n))continue;const o=D(t,e,r);if(o&&!L(e,o,r))return o}return null},"findSafeAnchorNode");export{U as a,c as b,J as c,D as f,W as s,C as w}; +import{_ as u,l as i}from"./mermaid.core-CJB1tAev.js";import{i as m,G as y}from"./graph-DOmOIIwC.js";import{b as _,m as X}from"./map-DxJ2ADlA.js";var j=4;function p(e){return _(e,j)}function C(e){var r={options:{directed:e.isDirected(),multigraph:e.isMultigraph(),compound:e.isCompound()},nodes:F(e),edges:M(e)};return m(e.graph())||(r.value=p(e.graph())),r}function F(e){return X(e.nodes(),function(r){var n=e.node(r),s=e.parent(r),t={v:r};return m(n)||(t.value=n),m(s)||(t.parent=s),t})}function M(e){return X(e.edges(),function(r){var n=e.edge(r),s={v:r.v,w:r.w};return m(r.name)||(s.name=r.name),m(n)||(s.value=n),s})}var c=new Map,w=new Map,A=new Map,J=u(()=>{w.clear(),A.clear(),c.clear()},"clear"),v=u((e,r)=>{const n=w.get(r)||[];return i.trace("In isDescendant",r," ",e," = ",n.includes(e)),n.includes(e)},"isDescendant"),R=u((e,r)=>{const n=w.get(r)||[];return i.info("Descendants of ",r," is ",n),i.info("Edge is ",e),e.v===r||e.w===r?!1:n?n.includes(e.v)||v(e.v,r)||v(e.w,r)||n.includes(e.w):(i.debug("Tilt, ",r,",not in descendants"),!1)},"edgeInCluster"),b=u((e,r,n,s)=>{i.warn("Copying children of ",e,"root",s,"data",r.node(e),s);const t=r.children(e)||[];e!==s&&t.push(e),i.warn("Copying (nodes) clusterId",e,"nodes",t),t.forEach(o=>{if(r.children(o).length>0)b(o,r,n,s);else{const l=r.node(o);i.info("cp ",o," to ",s," with parent ",e),n.setNode(o,l),s!==r.parent(o)&&(i.warn("Setting parent",o,r.parent(o)),n.setParent(o,r.parent(o))),e!==s&&o!==e?(i.debug("Setting parent",o,e),n.setParent(o,e)):(i.info("In copy ",e,"root",s,"data",r.node(e),s),i.debug("Not Setting parent for node=",o,"cluster!==rootId",e!==s,"node!==clusterId",o!==e));const f=r.edges(o);i.debug("Copying Edges",f),f.forEach(a=>{i.info("Edge",a);const d=r.edge(a.v,a.w,a.name);i.info("Edge data",d,s);try{if(R(a,s)){const g=w.get(s)||[],E=g.includes(a.v)||v(a.v,s)||a.v===s,x=g.includes(a.w)||v(a.w,s)||a.w===s;if(E&&x)i.info("Copying as ",a.v,a.w,d,a.name),n.setEdge(a.v,a.w,d,a.name),i.info("newGraph edges ",n.edges(),n.edge(n.edges()[0]));else{const N=E?s:a.v,h=x?s:a.w;i.info("Rebinding cross-boundary edge as ",N,h,d,a.name),r.setEdge(N,h,d,a.name)}}else i.info("Skipping copy of edge ",a.v,"-->",a.w," rootId: ",s," clusterId:",e)}catch(g){i.error(g)}})}i.debug("Removing node",o),r.removeNode(o)})},"copy"),O=u((e,r)=>{const n=r.children(e);let s=[...n];for(const t of n)A.set(t,e),s=[...s,...O(t,r)];return s},"extractDescendants"),P=u((e,r,n)=>{const s=e.edges().filter(a=>a.v===r||a.w===r),t=e.edges().filter(a=>a.v===n||a.w===n),o=s.map(a=>({v:a.v===r?n:a.v,w:a.w===r?r:a.w})),l=t.map(a=>({v:a.v,w:a.w}));return o.filter(a=>l.some(d=>a.v===d.v&&a.w===d.w))},"findCommonEdges"),D=u((e,r,n)=>{const s=r.children(e);if(i.trace("Searching children of id ",e,s),s.length<1)return e;let t;for(const o of s){const l=D(o,r,n),f=P(r,n,l);if(l)if(f.length>0)t=l;else return l}return t},"findNonClusterChild"),S=u(e=>!c.has(e)||!c.get(e).externalConnections?e:c.has(e)?c.get(e).id:e,"getAnchorId"),U=u((e,r)=>{if(!e||r>10){i.debug("Opting out, no graph ");return}else i.debug("Opting in, graph ");e.nodes().forEach(function(n){e.children(n).length>0&&(i.warn("Cluster identified",n," Replacement id in edges: ",D(n,e,n)),w.set(n,O(n,e)),c.set(n,{id:D(n,e,n),clusterData:e.node(n)}))}),e.nodes().forEach(function(n){const s=e.children(n),t=e.edges();s.length>0?(i.debug("Cluster identified",n,w),t.forEach(o=>{const l=v(o.v,n),f=v(o.w,n);l^f&&(i.warn("Edge: ",o," leaves cluster ",n),i.warn("Descendants of XXX ",n,": ",w.get(n)),c.get(n).externalConnections=!0)})):i.debug("Not a cluster ",n,w)});for(let n of c.keys()){const s=c.get(n).id,t=e.parent(s);t!==n&&c.has(t)&&!c.get(t).externalConnections&&(c.get(n).id=t);const o=e.edges().some(l=>l.v===n);if(s&&c.get(n)?.externalConnections&&o&&L(e,s,n)){const l=T(e,n,e.parent(s));l&&(c.get(n).id=l)}}e.edges().forEach(function(n){const s=e.edge(n);i.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(n)),i.warn("Edge "+n.v+" -> "+n.w+": "+JSON.stringify(e.edge(n)));let t=n.v,o=n.w;if(i.warn("Fix XXX",c,"ids:",n.v,n.w,"Translating: ",c.get(n.v)," --- ",c.get(n.w)),c.get(n.v)||c.get(n.w)){if(i.warn("Fixing and trying - removing XXX",n.v,n.w,n.name),t=S(n.v),o=S(n.w),e.removeEdge(n.v,n.w,n.name),t!==n.v){const l=e.parent(t);c.get(l).externalConnections=!0,s.fromCluster=n.v}if(o!==n.w){const l=e.parent(o);c.get(l).externalConnections=!0,s.toCluster=n.w}i.warn("Fix Replacing with XXX",t,o,n.name),e.setEdge(t,o,s,n.name)}}),i.warn("Adjusted Graph",C(e)),k(e,0),i.trace(c)},"adjustClustersAndEdges"),k=u((e,r)=>{if(i.warn("extractor - ",r,C(e),e.children("D")),r>10){i.error("Bailing out");return}let n=e.nodes(),s=!1;for(const t of n){const o=e.children(t);s=s||o.length>0}if(!s){i.debug("Done, no node has children",e.nodes());return}i.debug("Nodes = ",n,r);for(const t of n)if(i.debug("Extracting node",t,c,c.has(t)&&!c.get(t).externalConnections,!e.parent(t),e.node(t),e.children("D")," Depth ",r),!c.has(t))i.debug("Not a cluster",t,r);else if(c.get(t)?.clusterData?.explicitDir&&e.children(t)&&e.children(t).length>0){i.warn("Cluster with explicit dir, creating subgraph for children",t,r);const o=c.get(t).clusterData.dir,l=new y({multigraph:!0,compound:!0}).setGraph({rankdir:o,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});b(t,e,l,t);const f=e.node(t)||{};e.setNode(t,{...f,clusterNode:!0,id:t,clusterData:c.get(t).clusterData,label:c.get(t).label,graph:l}),i.warn("Subgraph for cluster with explicit dir created:",t,C(l))}else if(!c.get(t).externalConnections&&e.children(t)&&e.children(t).length>0){i.warn("Cluster without external connections, without a parent and with children",t,r);let l=e.graph().rankdir==="TB"?"LR":"TB";c.get(t)?.clusterData?.dir&&(l=c.get(t).clusterData.dir,i.warn("Fixing dir",c.get(t).clusterData.dir,l));const f=new y({multigraph:!0,compound:!0}).setGraph({rankdir:l,nodesep:50,ranksep:50,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}});b(t,e,f,t);const a=e.node(t)||{};e.setNode(t,{...a,clusterNode:!0,id:t,clusterData:c.get(t).clusterData,label:c.get(t).label,graph:f}),i.debug("Old graph after copy",C(e))}else i.warn("Cluster ** ",t," **not meeting the criteria !externalConnections:",!c.get(t).externalConnections," no parent: ",!e.parent(t)," children ",e.children(t)&&e.children(t).length>0,e.children("D"),r),i.debug(c);n=e.nodes(),i.warn("New list of nodes",n);for(const t of n){const o=e.node(t);i.warn(" Now next level",t,o),o?.clusterNode&&k(o.graph,r+1)}},"extractor"),B=u((e,r)=>{if(r.length===0)return[];let n=Object.assign([],r);return r.forEach(s=>{const t=e.children(s),o=B(e,t);n=[...n,...o]}),n},"sorter"),W=u(e=>B(e,e.children()),"sortNodesByHierarchy"),L=u((e,r,n)=>{let s=e.parent(r);for(;s&&s!==n;){const t=c.get(s);if(t&&!t.externalConnections)return!0;s=e.parent(s)}return!1},"isNodeInExtractableCluster"),T=u((e,r,n)=>{const s=e.children(r)??[];for(const t of s){if(t===n||v(t,n))continue;const o=D(t,e,r);if(o&&!L(e,o,r))return o}return null},"findSafeAnchorNode");export{U as a,c as b,J as c,D as f,W as s,C as w}; diff --git a/apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-czNi1QQl.js b/apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-B4q9plWN.js similarity index 99% rename from apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-czNi1QQl.js rename to apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-B4q9plWN.js index 4ea50361d..2943bac3e 100644 --- a/apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-czNi1QQl.js +++ b/apps/kimi-code/dist-web/assets/chunk-V7JOEXUC-B4q9plWN.js @@ -1,4 +1,4 @@ -import{g as tt}from"./chunk-5VM5RSS4-B87d3yQb.js";import{g as st}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as it}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as f,l as Ie,c as F,v as at,x as nt,y as Oe,d as de,a5 as rt,b as ut,a as lt,s as ct,g as ot,o as ht,p as dt,k as I,q as pt,r as At,i as ft,a6 as G}from"./mermaid.core-DaDTfY6S.js";import{f as gt}from"./chunk-32BRIVSS-_Sd4SrsJ.js";var we=(function(){var t=f(function(O,o,h,p){for(h=h||{},p=O.length;p--;h[O[p]]=o);return h},"o"),i=[1,18],a=[1,19],n=[1,20],r=[1,41],c=[1,26],u=[1,42],d=[1,24],m=[1,25],g=[1,32],N=[1,33],Ae=[1,34],b=[1,45],fe=[1,35],ge=[1,36],me=[1,37],Ce=[1,38],be=[1,27],ke=[1,28],Ee=[1,29],Te=[1,30],ye=[1,31],k=[1,44],E=[1,46],T=[1,43],y=[1,47],De=[1,9],A=[1,8,9],Z=[1,58],$=[1,59],ee=[1,60],te=[1,61],se=[1,62],Fe=[1,63],Be=[1,64],_=[1,8,9,41],Pe=[1,77],M=[1,8,9,12,13,22,39,41,44,46,68,69,70,71,72,73,74,79,81],ie=[1,8,9,12,13,18,20,22,39,41,44,46,47,60,68,69,70,71,72,73,74,79,81,86,100,102,103],ae=[13,60,86,100,102,103],U=[13,60,73,74,86,100,102,103],Me=[13,60,68,69,70,71,72,86,100,102,103],ne=[1,103],z=[1,121],Y=[1,117],K=[1,113],W=[1,119],Q=[1,114],j=[1,115],X=[1,116],q=[1,118],H=[1,120],Re=[22,50,60,61,82,86,87,88,89,90],Ge=[1,128],re=[12,39],_e=[1,8,9,39,41,44,46],ue=[1,8,9,22],Ue=[1,153],ze=[1,8,9,61],x=[1,8,9,22,50,60,61,82,86,87,88,89,90],Se={trace:f(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,classLiteralName:17,DOT:18,className:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,ANNOTATION_START:46,ANNOTATION_END:47,CLASS:48,emptyBody:49,SPACE:50,MEMBER:51,SEPARATOR:52,relation:53,NOTE_FOR:54,noteText:55,NOTE:56,CLASSDEF:57,classList:58,stylesOpt:59,ALPHA:60,COMMA:61,direction_tb:62,direction_bt:63,direction_rl:64,direction_lr:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,STYLE:82,CSSCLASS:83,style:84,styleComponent:85,NUM:86,COLON:87,UNIT:88,BRKT:89,PCT:90,commentToken:91,textToken:92,graphCodeTokens:93,textNoTagsToken:94,TAGSTART:95,TAGEND:96,"==":97,"--":98,DEFAULT:99,MINUS:100,keywords:101,UNICODE_TEXT:102,BQUOTE_STR:103,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",18:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"ANNOTATION_START",47:"ANNOTATION_END",48:"CLASS",50:"SPACE",51:"MEMBER",52:"SEPARATOR",54:"NOTE_FOR",56:"NOTE",57:"CLASSDEF",60:"ALPHA",61:"COMMA",62:"direction_tb",63:"direction_bt",64:"direction_rl",65:"direction_lr",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"STYLE",83:"CSSCLASS",86:"NUM",87:"COLON",88:"UNIT",89:"BRKT",90:"PCT",93:"graphCodeTokens",95:"TAGSTART",96:"TAGEND",97:"==",98:"--",99:"DEFAULT",100:"MINUS",101:"keywords",102:"UNICODE_TEXT",103:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,1],[15,3],[15,2],[19,1],[19,3],[19,1],[19,2],[19,2],[19,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[38,3],[40,1],[40,2],[40,3],[40,1],[40,2],[40,3],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,3],[24,6],[24,4],[24,7],[24,6],[43,2],[43,3],[49,0],[49,2],[49,2],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[58,1],[58,3],[32,1],[32,1],[32,1],[32,1],[53,3],[53,2],[53,2],[53,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[59,1],[59,3],[84,1],[84,2],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[91,1],[91,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[94,1],[94,1],[94,1],[94,1],[16,1],[16,1],[16,1],[16,1],[17,1],[55,1]],performAction:f(function(o,h,p,l,C,e,J){var s=e.length-1;switch(C){case 8:this.$=e[s-1];break;case 9:case 10:case 13:case 15:this.$=e[s];break;case 11:case 14:this.$=e[s-2]+"."+e[s];break;case 12:case 16:this.$=e[s-1]+e[s];break;case 17:case 18:this.$=e[s-1]+"~"+e[s]+"~";break;case 19:l.addRelation(e[s]);break;case 20:e[s-1].title=l.cleanupLabel(e[s]),l.addRelation(e[s-1]);break;case 31:this.$=e[s].trim(),l.setAccTitle(this.$);break;case 32:case 33:this.$=e[s].trim(),l.setAccDescription(this.$);break;case 34:l.addClassesToNamespace(e[s-3],e[s-1][0],e[s-1][1]),l.popNamespace();break;case 35:l.addClassesToNamespace(e[s-4],e[s-1][0],e[s-1][1]),l.popNamespace();break;case 36:this.$=l.addNamespace(e[s]);break;case 37:this.$=l.addNamespace(e[s-1],e[s]);break;case 38:this.$=[[e[s]],[]];break;case 39:this.$=[[e[s-1]],[]];break;case 40:e[s][0].unshift(e[s-2]),this.$=e[s];break;case 41:this.$=[[],[e[s]]];break;case 42:this.$=[[],[e[s-1]]];break;case 43:e[s][1].unshift(e[s-2]),this.$=e[s];break;case 44:case 45:this.$=[[],[]];break;case 46:this.$=e[s];break;case 48:l.setCssClass(e[s-2],e[s]);break;case 49:l.addMembers(e[s-3],e[s-1]);break;case 51:l.setCssClass(e[s-5],e[s-3]),l.addMembers(e[s-5],e[s-1]);break;case 52:l.addAnnotation(e[s-3],e[s-1]);break;case 53:l.addAnnotation(e[s-6],e[s-4]),l.addMembers(e[s-6],e[s-1]);break;case 54:l.addAnnotation(e[s-5],e[s-3]);break;case 55:this.$=e[s],l.addClass(e[s]);break;case 56:this.$=e[s-1],l.addClass(e[s-1]),l.setClassLabel(e[s-1],e[s]);break;case 60:l.addAnnotation(e[s],e[s-2]);break;case 61:case 74:this.$=[e[s]];break;case 62:e[s].push(e[s-1]),this.$=e[s];break;case 63:break;case 64:l.addMember(e[s-1],l.cleanupLabel(e[s]));break;case 65:break;case 66:break;case 67:this.$={id1:e[s-2],id2:e[s],relation:e[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 68:this.$={id1:e[s-3],id2:e[s],relation:e[s-1],relationTitle1:e[s-2],relationTitle2:"none"};break;case 69:this.$={id1:e[s-3],id2:e[s],relation:e[s-2],relationTitle1:"none",relationTitle2:e[s-1]};break;case 70:this.$={id1:e[s-4],id2:e[s],relation:e[s-2],relationTitle1:e[s-3],relationTitle2:e[s-1]};break;case 71:this.$=l.addNote(e[s],e[s-1]);break;case 72:this.$=l.addNote(e[s]);break;case 73:this.$=e[s-2],l.defineClass(e[s-1],e[s]);break;case 75:this.$=e[s-2].concat([e[s]]);break;case 76:l.setDirection("TB");break;case 77:l.setDirection("BT");break;case 78:l.setDirection("RL");break;case 79:l.setDirection("LR");break;case 80:this.$={type1:e[s-2],type2:e[s],lineType:e[s-1]};break;case 81:this.$={type1:"none",type2:e[s],lineType:e[s-1]};break;case 82:this.$={type1:e[s-1],type2:"none",lineType:e[s]};break;case 83:this.$={type1:"none",type2:"none",lineType:e[s]};break;case 84:this.$=l.relationType.AGGREGATION;break;case 85:this.$=l.relationType.EXTENSION;break;case 86:this.$=l.relationType.COMPOSITION;break;case 87:this.$=l.relationType.DEPENDENCY;break;case 88:this.$=l.relationType.LOLLIPOP;break;case 89:this.$=l.lineType.LINE;break;case 90:this.$=l.lineType.DOTTED_LINE;break;case 91:case 97:this.$=e[s-2],l.setClickEvent(e[s-1],e[s]);break;case 92:case 98:this.$=e[s-3],l.setClickEvent(e[s-2],e[s-1]),l.setTooltip(e[s-2],e[s]);break;case 93:this.$=e[s-2],l.setLink(e[s-1],e[s]);break;case 94:this.$=e[s-3],l.setLink(e[s-2],e[s-1],e[s]);break;case 95:this.$=e[s-3],l.setLink(e[s-2],e[s-1]),l.setTooltip(e[s-2],e[s]);break;case 96:this.$=e[s-4],l.setLink(e[s-3],e[s-2],e[s]),l.setTooltip(e[s-3],e[s-1]);break;case 99:this.$=e[s-3],l.setClickEvent(e[s-2],e[s-1],e[s]);break;case 100:this.$=e[s-4],l.setClickEvent(e[s-3],e[s-2],e[s-1]),l.setTooltip(e[s-3],e[s]);break;case 101:this.$=e[s-3],l.setLink(e[s-2],e[s]);break;case 102:this.$=e[s-4],l.setLink(e[s-3],e[s-1],e[s]);break;case 103:this.$=e[s-4],l.setLink(e[s-3],e[s-1]),l.setTooltip(e[s-3],e[s]);break;case 104:this.$=e[s-5],l.setLink(e[s-4],e[s-2],e[s]),l.setTooltip(e[s-4],e[s-1]);break;case 105:this.$=e[s-2],l.setCssStyle(e[s-1],e[s]);break;case 106:l.setCssClass(e[s-1],e[s]);break;case 107:this.$=[e[s]];break;case 108:e[s-2].push(e[s]),this.$=e[s-2];break;case 110:this.$=e[s-1]+e[s];break}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:i,35:a,37:n,38:22,42:r,43:23,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(De,[2,5],{8:[1,48]}),{8:[1,49]},t(A,[2,19],{22:[1,50]}),t(A,[2,21]),t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),t(A,[2,26]),t(A,[2,27]),t(A,[2,28]),t(A,[2,29]),t(A,[2,30]),{34:[1,51]},{36:[1,52]},t(A,[2,33]),t(A,[2,63],{53:53,66:56,67:57,13:[1,54],22:[1,55],68:Z,69:$,70:ee,71:te,72:se,73:Fe,74:Be}),{39:[1,65]},t(_,[2,47],{39:[1,67],44:[1,66],46:[1,68]}),t(A,[2,65]),t(A,[2,66]),{16:69,60:b,86:k,100:E,102:T},{16:39,17:40,19:70,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:71,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:72,60:b,86:k,100:E,102:T,103:y},{60:[1,73]},{13:[1,74]},{16:39,17:40,19:75,60:b,86:k,100:E,102:T,103:y},{13:Pe,55:76},{58:78,60:[1,79]},t(A,[2,76]),t(A,[2,77]),t(A,[2,78]),t(A,[2,79]),t(M,[2,13],{16:39,17:40,19:81,18:[1,80],20:[1,82],60:b,86:k,100:E,102:T,103:y}),t(M,[2,15],{20:[1,83]}),{15:84,16:85,17:86,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:87,60:b,86:k,100:E,102:T,103:y},t(ie,[2,133]),t(ie,[2,134]),t(ie,[2,135]),t(ie,[2,136]),t([1,8,9,12,13,20,22,39,41,44,46,68,69,70,71,72,73,74,79,81],[2,137]),t(De,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,19:21,38:22,43:23,16:39,17:40,5:88,33:i,35:a,37:n,42:r,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y}),{5:89,10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:i,35:a,37:n,38:22,42:r,43:23,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y},t(A,[2,20]),t(A,[2,31]),t(A,[2,32]),{13:[1,91],16:39,17:40,19:90,60:b,86:k,100:E,102:T,103:y},{53:92,66:56,67:57,68:Z,69:$,70:ee,71:te,72:se,73:Fe,74:Be},t(A,[2,64]),{67:93,73:Fe,74:Be},t(ae,[2,83],{66:94,68:Z,69:$,70:ee,71:te,72:se}),t(U,[2,84]),t(U,[2,85]),t(U,[2,86]),t(U,[2,87]),t(U,[2,88]),t(Me,[2,89]),t(Me,[2,90]),{8:[1,96],23:99,24:97,30:98,38:22,40:95,42:r,43:23,48:u,54:g,56:N},{16:100,60:b,86:k,100:E,102:T},{41:[1,102],45:101,51:ne},{16:104,60:b,86:k,100:E,102:T},{47:[1,105]},{13:[1,106]},{13:[1,107]},{79:[1,108],81:[1,109]},{22:z,50:Y,59:110,60:K,82:W,84:111,85:112,86:Q,87:j,88:X,89:q,90:H},{60:[1,122]},{13:Pe,55:123},t(_,[2,72]),t(_,[2,138]),{22:z,50:Y,59:124,60:K,61:[1,125],82:W,84:111,85:112,86:Q,87:j,88:X,89:q,90:H},t(Re,[2,74]),{16:39,17:40,19:126,60:b,86:k,100:E,102:T,103:y},t(M,[2,16]),t(M,[2,17]),t(M,[2,18]),{11:127,12:Ge,39:[2,36]},t(re,[2,9],{16:85,17:86,15:130,18:[1,129],60:b,86:k,100:E,102:T,103:y}),t(re,[2,10]),t(_e,[2,55],{11:131,12:Ge}),t(De,[2,7]),{9:[1,132]},t(ue,[2,67]),{16:39,17:40,19:133,60:b,86:k,100:E,102:T,103:y},{13:[1,135],16:39,17:40,19:134,60:b,86:k,100:E,102:T,103:y},t(ae,[2,82],{66:136,68:Z,69:$,70:ee,71:te,72:se}),t(ae,[2,81]),{41:[1,137]},{23:99,24:97,30:98,38:22,40:138,42:r,43:23,48:u,54:g,56:N},{8:[1,139],41:[2,38]},{8:[1,140],41:[2,41]},{8:[1,141],41:[2,44]},t(_,[2,48],{39:[1,142]}),{41:[1,143]},t(_,[2,50]),{41:[2,61],45:144,51:ne},{47:[1,145]},{16:39,17:40,19:146,60:b,86:k,100:E,102:T,103:y},t(A,[2,91],{13:[1,147]}),t(A,[2,93],{13:[1,149],77:[1,148]}),t(A,[2,97],{13:[1,150],80:[1,151]}),{13:[1,152]},t(A,[2,105],{61:Ue}),t(ze,[2,107],{85:154,22:z,50:Y,60:K,82:W,86:Q,87:j,88:X,89:q,90:H}),t(x,[2,109]),t(x,[2,111]),t(x,[2,112]),t(x,[2,113]),t(x,[2,114]),t(x,[2,115]),t(x,[2,116]),t(x,[2,117]),t(x,[2,118]),t(x,[2,119]),t(A,[2,106]),t(_,[2,71]),t(A,[2,73],{61:Ue}),{60:[1,155]},t(M,[2,14]),{39:[2,37]},{13:[1,156]},{15:157,16:85,17:86,60:b,86:k,100:E,102:T,103:y},t(re,[2,12]),t(_e,[2,56]),{1:[2,4]},t(ue,[2,69]),t(ue,[2,68]),{16:39,17:40,19:158,60:b,86:k,100:E,102:T,103:y},t(ae,[2,80]),t(_,[2,34]),{41:[1,159]},{23:99,24:97,30:98,38:22,40:160,41:[2,39],42:r,43:23,48:u,54:g,56:N},{23:99,24:97,30:98,38:22,40:161,41:[2,42],42:r,43:23,48:u,54:g,56:N},{23:99,24:97,30:98,38:22,40:162,41:[2,45],42:r,43:23,48:u,54:g,56:N},{45:163,51:ne},t(_,[2,49]),{41:[2,62]},t(_,[2,52],{39:[1,164]}),t(A,[2,60]),t(A,[2,92]),t(A,[2,94]),t(A,[2,95],{77:[1,165]}),t(A,[2,98]),t(A,[2,99],{13:[1,166]}),t(A,[2,101],{13:[1,168],77:[1,167]}),{22:z,50:Y,60:K,82:W,84:169,85:112,86:Q,87:j,88:X,89:q,90:H},t(x,[2,110]),t(Re,[2,75]),{14:[1,170]},t(re,[2,11]),t(ue,[2,70]),t(_,[2,35]),{41:[2,40]},{41:[2,43]},{41:[2,46]},{41:[1,171]},{41:[1,173],45:172,51:ne},t(A,[2,96]),t(A,[2,100]),t(A,[2,102]),t(A,[2,103],{77:[1,174]}),t(ze,[2,108],{85:154,22:z,50:Y,60:K,82:W,86:Q,87:j,88:X,89:q,90:H}),t(_e,[2,8]),t(_,[2,51]),{41:[1,175]},t(_,[2,54]),t(A,[2,104]),t(_,[2,53])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],127:[2,37],132:[2,4],144:[2,62],160:[2,40],161:[2,43],162:[2,46]},parseError:f(function(o,h){if(h.recoverable)this.trace(o);else{var p=new Error(o);throw p.hash=h,p}},"parseError"),parse:f(function(o){var h=this,p=[0],l=[],C=[null],e=[],J=this.table,s="",ce=0,Ye=0,Je=2,Ke=1,Ze=e.slice.call(arguments,1),D=Object.create(this.lexer),w={yy:{}};for(var Ne in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ne)&&(w.yy[Ne]=this.yy[Ne]);D.setInput(o,w.yy),w.yy.lexer=D,w.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var Le=D.yylloc;e.push(Le);var $e=D.options&&D.options.ranges;typeof w.yy.parseError=="function"?this.parseError=w.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function et(S){p.length=p.length-2*S,C.length=C.length-S,e.length=e.length-S}f(et,"popStack");function We(){var S;return S=l.pop()||D.lex()||Ke,typeof S!="number"&&(S instanceof Array&&(l=S,S=l.pop()),S=h.symbols_[S]||S),S}f(We,"lex");for(var B,V,L,xe,R={},oe,v,Qe,he;;){if(V=p[p.length-1],this.defaultActions[V]?L=this.defaultActions[V]:((B===null||typeof B>"u")&&(B=We()),L=J[V]&&J[V][B]),typeof L>"u"||!L.length||!L[0]){var ve="";he=[];for(oe in J[V])this.terminals_[oe]&&oe>Je&&he.push("'"+this.terminals_[oe]+"'");D.showPosition?ve="Parse error on line "+(ce+1)+`: +import{g as tt}from"./chunk-5VM5RSS4-yyj9cAyF.js";import{g as st}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as it}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as f,l as Ie,c as F,v as at,x as nt,y as Oe,d as de,a5 as rt,b as ut,a as lt,s as ct,g as ot,o as ht,p as dt,k as I,q as pt,r as At,i as ft,a6 as G}from"./mermaid.core-CJB1tAev.js";import{f as gt}from"./chunk-32BRIVSS-DUDRPqmY.js";var we=(function(){var t=f(function(O,o,h,p){for(h=h||{},p=O.length;p--;h[O[p]]=o);return h},"o"),i=[1,18],a=[1,19],n=[1,20],r=[1,41],c=[1,26],u=[1,42],d=[1,24],m=[1,25],g=[1,32],N=[1,33],Ae=[1,34],b=[1,45],fe=[1,35],ge=[1,36],me=[1,37],Ce=[1,38],be=[1,27],ke=[1,28],Ee=[1,29],Te=[1,30],ye=[1,31],k=[1,44],E=[1,46],T=[1,43],y=[1,47],De=[1,9],A=[1,8,9],Z=[1,58],$=[1,59],ee=[1,60],te=[1,61],se=[1,62],Fe=[1,63],Be=[1,64],_=[1,8,9,41],Pe=[1,77],M=[1,8,9,12,13,22,39,41,44,46,68,69,70,71,72,73,74,79,81],ie=[1,8,9,12,13,18,20,22,39,41,44,46,47,60,68,69,70,71,72,73,74,79,81,86,100,102,103],ae=[13,60,86,100,102,103],U=[13,60,73,74,86,100,102,103],Me=[13,60,68,69,70,71,72,86,100,102,103],ne=[1,103],z=[1,121],Y=[1,117],K=[1,113],W=[1,119],Q=[1,114],j=[1,115],X=[1,116],q=[1,118],H=[1,120],Re=[22,50,60,61,82,86,87,88,89,90],Ge=[1,128],re=[12,39],_e=[1,8,9,39,41,44,46],ue=[1,8,9,22],Ue=[1,153],ze=[1,8,9,61],x=[1,8,9,22,50,60,61,82,86,87,88,89,90],Se={trace:f(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mermaidDoc:4,statements:5,graphConfig:6,CLASS_DIAGRAM:7,NEWLINE:8,EOF:9,statement:10,classLabel:11,SQS:12,STR:13,SQE:14,namespaceName:15,alphaNumToken:16,classLiteralName:17,DOT:18,className:19,GENERICTYPE:20,relationStatement:21,LABEL:22,namespaceStatement:23,classStatement:24,memberStatement:25,annotationStatement:26,clickStatement:27,styleStatement:28,cssClassStatement:29,noteStatement:30,classDefStatement:31,direction:32,acc_title:33,acc_title_value:34,acc_descr:35,acc_descr_value:36,acc_descr_multiline_value:37,namespaceIdentifier:38,STRUCT_START:39,classStatements:40,STRUCT_STOP:41,NAMESPACE:42,classIdentifier:43,STYLE_SEPARATOR:44,members:45,ANNOTATION_START:46,ANNOTATION_END:47,CLASS:48,emptyBody:49,SPACE:50,MEMBER:51,SEPARATOR:52,relation:53,NOTE_FOR:54,noteText:55,NOTE:56,CLASSDEF:57,classList:58,stylesOpt:59,ALPHA:60,COMMA:61,direction_tb:62,direction_bt:63,direction_rl:64,direction_lr:65,relationType:66,lineType:67,AGGREGATION:68,EXTENSION:69,COMPOSITION:70,DEPENDENCY:71,LOLLIPOP:72,LINE:73,DOTTED_LINE:74,CALLBACK:75,LINK:76,LINK_TARGET:77,CLICK:78,CALLBACK_NAME:79,CALLBACK_ARGS:80,HREF:81,STYLE:82,CSSCLASS:83,style:84,styleComponent:85,NUM:86,COLON:87,UNIT:88,BRKT:89,PCT:90,commentToken:91,textToken:92,graphCodeTokens:93,textNoTagsToken:94,TAGSTART:95,TAGEND:96,"==":97,"--":98,DEFAULT:99,MINUS:100,keywords:101,UNICODE_TEXT:102,BQUOTE_STR:103,$accept:0,$end:1},terminals_:{2:"error",7:"CLASS_DIAGRAM",8:"NEWLINE",9:"EOF",12:"SQS",13:"STR",14:"SQE",18:"DOT",20:"GENERICTYPE",22:"LABEL",33:"acc_title",34:"acc_title_value",35:"acc_descr",36:"acc_descr_value",37:"acc_descr_multiline_value",39:"STRUCT_START",41:"STRUCT_STOP",42:"NAMESPACE",44:"STYLE_SEPARATOR",46:"ANNOTATION_START",47:"ANNOTATION_END",48:"CLASS",50:"SPACE",51:"MEMBER",52:"SEPARATOR",54:"NOTE_FOR",56:"NOTE",57:"CLASSDEF",60:"ALPHA",61:"COMMA",62:"direction_tb",63:"direction_bt",64:"direction_rl",65:"direction_lr",68:"AGGREGATION",69:"EXTENSION",70:"COMPOSITION",71:"DEPENDENCY",72:"LOLLIPOP",73:"LINE",74:"DOTTED_LINE",75:"CALLBACK",76:"LINK",77:"LINK_TARGET",78:"CLICK",79:"CALLBACK_NAME",80:"CALLBACK_ARGS",81:"HREF",82:"STYLE",83:"CSSCLASS",86:"NUM",87:"COLON",88:"UNIT",89:"BRKT",90:"PCT",93:"graphCodeTokens",95:"TAGSTART",96:"TAGEND",97:"==",98:"--",99:"DEFAULT",100:"MINUS",101:"keywords",102:"UNICODE_TEXT",103:"BQUOTE_STR"},productions_:[0,[3,1],[3,1],[4,1],[6,4],[5,1],[5,2],[5,3],[11,3],[15,1],[15,1],[15,3],[15,2],[19,1],[19,3],[19,1],[19,2],[19,2],[19,2],[10,1],[10,2],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,1],[10,2],[10,2],[10,1],[23,4],[23,5],[38,2],[38,3],[40,1],[40,2],[40,3],[40,1],[40,2],[40,3],[40,1],[40,2],[40,3],[24,1],[24,3],[24,4],[24,3],[24,6],[24,4],[24,7],[24,6],[43,2],[43,3],[49,0],[49,2],[49,2],[26,4],[45,1],[45,2],[25,1],[25,2],[25,1],[25,1],[21,3],[21,4],[21,4],[21,5],[30,3],[30,2],[31,3],[58,1],[58,3],[32,1],[32,1],[32,1],[32,1],[53,3],[53,2],[53,2],[53,1],[66,1],[66,1],[66,1],[66,1],[66,1],[67,1],[67,1],[27,3],[27,4],[27,3],[27,4],[27,4],[27,5],[27,3],[27,4],[27,4],[27,5],[27,4],[27,5],[27,5],[27,6],[28,3],[29,3],[59,1],[59,3],[84,1],[84,2],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[85,1],[91,1],[91,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[92,1],[94,1],[94,1],[94,1],[94,1],[16,1],[16,1],[16,1],[16,1],[17,1],[55,1]],performAction:f(function(o,h,p,l,C,e,J){var s=e.length-1;switch(C){case 8:this.$=e[s-1];break;case 9:case 10:case 13:case 15:this.$=e[s];break;case 11:case 14:this.$=e[s-2]+"."+e[s];break;case 12:case 16:this.$=e[s-1]+e[s];break;case 17:case 18:this.$=e[s-1]+"~"+e[s]+"~";break;case 19:l.addRelation(e[s]);break;case 20:e[s-1].title=l.cleanupLabel(e[s]),l.addRelation(e[s-1]);break;case 31:this.$=e[s].trim(),l.setAccTitle(this.$);break;case 32:case 33:this.$=e[s].trim(),l.setAccDescription(this.$);break;case 34:l.addClassesToNamespace(e[s-3],e[s-1][0],e[s-1][1]),l.popNamespace();break;case 35:l.addClassesToNamespace(e[s-4],e[s-1][0],e[s-1][1]),l.popNamespace();break;case 36:this.$=l.addNamespace(e[s]);break;case 37:this.$=l.addNamespace(e[s-1],e[s]);break;case 38:this.$=[[e[s]],[]];break;case 39:this.$=[[e[s-1]],[]];break;case 40:e[s][0].unshift(e[s-2]),this.$=e[s];break;case 41:this.$=[[],[e[s]]];break;case 42:this.$=[[],[e[s-1]]];break;case 43:e[s][1].unshift(e[s-2]),this.$=e[s];break;case 44:case 45:this.$=[[],[]];break;case 46:this.$=e[s];break;case 48:l.setCssClass(e[s-2],e[s]);break;case 49:l.addMembers(e[s-3],e[s-1]);break;case 51:l.setCssClass(e[s-5],e[s-3]),l.addMembers(e[s-5],e[s-1]);break;case 52:l.addAnnotation(e[s-3],e[s-1]);break;case 53:l.addAnnotation(e[s-6],e[s-4]),l.addMembers(e[s-6],e[s-1]);break;case 54:l.addAnnotation(e[s-5],e[s-3]);break;case 55:this.$=e[s],l.addClass(e[s]);break;case 56:this.$=e[s-1],l.addClass(e[s-1]),l.setClassLabel(e[s-1],e[s]);break;case 60:l.addAnnotation(e[s],e[s-2]);break;case 61:case 74:this.$=[e[s]];break;case 62:e[s].push(e[s-1]),this.$=e[s];break;case 63:break;case 64:l.addMember(e[s-1],l.cleanupLabel(e[s]));break;case 65:break;case 66:break;case 67:this.$={id1:e[s-2],id2:e[s],relation:e[s-1],relationTitle1:"none",relationTitle2:"none"};break;case 68:this.$={id1:e[s-3],id2:e[s],relation:e[s-1],relationTitle1:e[s-2],relationTitle2:"none"};break;case 69:this.$={id1:e[s-3],id2:e[s],relation:e[s-2],relationTitle1:"none",relationTitle2:e[s-1]};break;case 70:this.$={id1:e[s-4],id2:e[s],relation:e[s-2],relationTitle1:e[s-3],relationTitle2:e[s-1]};break;case 71:this.$=l.addNote(e[s],e[s-1]);break;case 72:this.$=l.addNote(e[s]);break;case 73:this.$=e[s-2],l.defineClass(e[s-1],e[s]);break;case 75:this.$=e[s-2].concat([e[s]]);break;case 76:l.setDirection("TB");break;case 77:l.setDirection("BT");break;case 78:l.setDirection("RL");break;case 79:l.setDirection("LR");break;case 80:this.$={type1:e[s-2],type2:e[s],lineType:e[s-1]};break;case 81:this.$={type1:"none",type2:e[s],lineType:e[s-1]};break;case 82:this.$={type1:e[s-1],type2:"none",lineType:e[s]};break;case 83:this.$={type1:"none",type2:"none",lineType:e[s]};break;case 84:this.$=l.relationType.AGGREGATION;break;case 85:this.$=l.relationType.EXTENSION;break;case 86:this.$=l.relationType.COMPOSITION;break;case 87:this.$=l.relationType.DEPENDENCY;break;case 88:this.$=l.relationType.LOLLIPOP;break;case 89:this.$=l.lineType.LINE;break;case 90:this.$=l.lineType.DOTTED_LINE;break;case 91:case 97:this.$=e[s-2],l.setClickEvent(e[s-1],e[s]);break;case 92:case 98:this.$=e[s-3],l.setClickEvent(e[s-2],e[s-1]),l.setTooltip(e[s-2],e[s]);break;case 93:this.$=e[s-2],l.setLink(e[s-1],e[s]);break;case 94:this.$=e[s-3],l.setLink(e[s-2],e[s-1],e[s]);break;case 95:this.$=e[s-3],l.setLink(e[s-2],e[s-1]),l.setTooltip(e[s-2],e[s]);break;case 96:this.$=e[s-4],l.setLink(e[s-3],e[s-2],e[s]),l.setTooltip(e[s-3],e[s-1]);break;case 99:this.$=e[s-3],l.setClickEvent(e[s-2],e[s-1],e[s]);break;case 100:this.$=e[s-4],l.setClickEvent(e[s-3],e[s-2],e[s-1]),l.setTooltip(e[s-3],e[s]);break;case 101:this.$=e[s-3],l.setLink(e[s-2],e[s]);break;case 102:this.$=e[s-4],l.setLink(e[s-3],e[s-1],e[s]);break;case 103:this.$=e[s-4],l.setLink(e[s-3],e[s-1]),l.setTooltip(e[s-3],e[s]);break;case 104:this.$=e[s-5],l.setLink(e[s-4],e[s-2],e[s]),l.setTooltip(e[s-4],e[s-1]);break;case 105:this.$=e[s-2],l.setCssStyle(e[s-1],e[s]);break;case 106:l.setCssClass(e[s-1],e[s]);break;case 107:this.$=[e[s]];break;case 108:e[s-2].push(e[s]),this.$=e[s-2];break;case 110:this.$=e[s-1]+e[s];break}},"anonymous"),table:[{3:1,4:2,5:3,6:4,7:[1,6],10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:i,35:a,37:n,38:22,42:r,43:23,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y},{1:[3]},{1:[2,1]},{1:[2,2]},{1:[2,3]},t(De,[2,5],{8:[1,48]}),{8:[1,49]},t(A,[2,19],{22:[1,50]}),t(A,[2,21]),t(A,[2,22]),t(A,[2,23]),t(A,[2,24]),t(A,[2,25]),t(A,[2,26]),t(A,[2,27]),t(A,[2,28]),t(A,[2,29]),t(A,[2,30]),{34:[1,51]},{36:[1,52]},t(A,[2,33]),t(A,[2,63],{53:53,66:56,67:57,13:[1,54],22:[1,55],68:Z,69:$,70:ee,71:te,72:se,73:Fe,74:Be}),{39:[1,65]},t(_,[2,47],{39:[1,67],44:[1,66],46:[1,68]}),t(A,[2,65]),t(A,[2,66]),{16:69,60:b,86:k,100:E,102:T},{16:39,17:40,19:70,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:71,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:72,60:b,86:k,100:E,102:T,103:y},{60:[1,73]},{13:[1,74]},{16:39,17:40,19:75,60:b,86:k,100:E,102:T,103:y},{13:Pe,55:76},{58:78,60:[1,79]},t(A,[2,76]),t(A,[2,77]),t(A,[2,78]),t(A,[2,79]),t(M,[2,13],{16:39,17:40,19:81,18:[1,80],20:[1,82],60:b,86:k,100:E,102:T,103:y}),t(M,[2,15],{20:[1,83]}),{15:84,16:85,17:86,60:b,86:k,100:E,102:T,103:y},{16:39,17:40,19:87,60:b,86:k,100:E,102:T,103:y},t(ie,[2,133]),t(ie,[2,134]),t(ie,[2,135]),t(ie,[2,136]),t([1,8,9,12,13,20,22,39,41,44,46,68,69,70,71,72,73,74,79,81],[2,137]),t(De,[2,6],{10:5,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,19:21,38:22,43:23,16:39,17:40,5:88,33:i,35:a,37:n,42:r,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y}),{5:89,10:5,16:39,17:40,19:21,21:7,23:8,24:9,25:10,26:11,27:12,28:13,29:14,30:15,31:16,32:17,33:i,35:a,37:n,38:22,42:r,43:23,46:c,48:u,51:d,52:m,54:g,56:N,57:Ae,60:b,62:fe,63:ge,64:me,65:Ce,75:be,76:ke,78:Ee,82:Te,83:ye,86:k,100:E,102:T,103:y},t(A,[2,20]),t(A,[2,31]),t(A,[2,32]),{13:[1,91],16:39,17:40,19:90,60:b,86:k,100:E,102:T,103:y},{53:92,66:56,67:57,68:Z,69:$,70:ee,71:te,72:se,73:Fe,74:Be},t(A,[2,64]),{67:93,73:Fe,74:Be},t(ae,[2,83],{66:94,68:Z,69:$,70:ee,71:te,72:se}),t(U,[2,84]),t(U,[2,85]),t(U,[2,86]),t(U,[2,87]),t(U,[2,88]),t(Me,[2,89]),t(Me,[2,90]),{8:[1,96],23:99,24:97,30:98,38:22,40:95,42:r,43:23,48:u,54:g,56:N},{16:100,60:b,86:k,100:E,102:T},{41:[1,102],45:101,51:ne},{16:104,60:b,86:k,100:E,102:T},{47:[1,105]},{13:[1,106]},{13:[1,107]},{79:[1,108],81:[1,109]},{22:z,50:Y,59:110,60:K,82:W,84:111,85:112,86:Q,87:j,88:X,89:q,90:H},{60:[1,122]},{13:Pe,55:123},t(_,[2,72]),t(_,[2,138]),{22:z,50:Y,59:124,60:K,61:[1,125],82:W,84:111,85:112,86:Q,87:j,88:X,89:q,90:H},t(Re,[2,74]),{16:39,17:40,19:126,60:b,86:k,100:E,102:T,103:y},t(M,[2,16]),t(M,[2,17]),t(M,[2,18]),{11:127,12:Ge,39:[2,36]},t(re,[2,9],{16:85,17:86,15:130,18:[1,129],60:b,86:k,100:E,102:T,103:y}),t(re,[2,10]),t(_e,[2,55],{11:131,12:Ge}),t(De,[2,7]),{9:[1,132]},t(ue,[2,67]),{16:39,17:40,19:133,60:b,86:k,100:E,102:T,103:y},{13:[1,135],16:39,17:40,19:134,60:b,86:k,100:E,102:T,103:y},t(ae,[2,82],{66:136,68:Z,69:$,70:ee,71:te,72:se}),t(ae,[2,81]),{41:[1,137]},{23:99,24:97,30:98,38:22,40:138,42:r,43:23,48:u,54:g,56:N},{8:[1,139],41:[2,38]},{8:[1,140],41:[2,41]},{8:[1,141],41:[2,44]},t(_,[2,48],{39:[1,142]}),{41:[1,143]},t(_,[2,50]),{41:[2,61],45:144,51:ne},{47:[1,145]},{16:39,17:40,19:146,60:b,86:k,100:E,102:T,103:y},t(A,[2,91],{13:[1,147]}),t(A,[2,93],{13:[1,149],77:[1,148]}),t(A,[2,97],{13:[1,150],80:[1,151]}),{13:[1,152]},t(A,[2,105],{61:Ue}),t(ze,[2,107],{85:154,22:z,50:Y,60:K,82:W,86:Q,87:j,88:X,89:q,90:H}),t(x,[2,109]),t(x,[2,111]),t(x,[2,112]),t(x,[2,113]),t(x,[2,114]),t(x,[2,115]),t(x,[2,116]),t(x,[2,117]),t(x,[2,118]),t(x,[2,119]),t(A,[2,106]),t(_,[2,71]),t(A,[2,73],{61:Ue}),{60:[1,155]},t(M,[2,14]),{39:[2,37]},{13:[1,156]},{15:157,16:85,17:86,60:b,86:k,100:E,102:T,103:y},t(re,[2,12]),t(_e,[2,56]),{1:[2,4]},t(ue,[2,69]),t(ue,[2,68]),{16:39,17:40,19:158,60:b,86:k,100:E,102:T,103:y},t(ae,[2,80]),t(_,[2,34]),{41:[1,159]},{23:99,24:97,30:98,38:22,40:160,41:[2,39],42:r,43:23,48:u,54:g,56:N},{23:99,24:97,30:98,38:22,40:161,41:[2,42],42:r,43:23,48:u,54:g,56:N},{23:99,24:97,30:98,38:22,40:162,41:[2,45],42:r,43:23,48:u,54:g,56:N},{45:163,51:ne},t(_,[2,49]),{41:[2,62]},t(_,[2,52],{39:[1,164]}),t(A,[2,60]),t(A,[2,92]),t(A,[2,94]),t(A,[2,95],{77:[1,165]}),t(A,[2,98]),t(A,[2,99],{13:[1,166]}),t(A,[2,101],{13:[1,168],77:[1,167]}),{22:z,50:Y,60:K,82:W,84:169,85:112,86:Q,87:j,88:X,89:q,90:H},t(x,[2,110]),t(Re,[2,75]),{14:[1,170]},t(re,[2,11]),t(ue,[2,70]),t(_,[2,35]),{41:[2,40]},{41:[2,43]},{41:[2,46]},{41:[1,171]},{41:[1,173],45:172,51:ne},t(A,[2,96]),t(A,[2,100]),t(A,[2,102]),t(A,[2,103],{77:[1,174]}),t(ze,[2,108],{85:154,22:z,50:Y,60:K,82:W,86:Q,87:j,88:X,89:q,90:H}),t(_e,[2,8]),t(_,[2,51]),{41:[1,175]},t(_,[2,54]),t(A,[2,104]),t(_,[2,53])],defaultActions:{2:[2,1],3:[2,2],4:[2,3],127:[2,37],132:[2,4],144:[2,62],160:[2,40],161:[2,43],162:[2,46]},parseError:f(function(o,h){if(h.recoverable)this.trace(o);else{var p=new Error(o);throw p.hash=h,p}},"parseError"),parse:f(function(o){var h=this,p=[0],l=[],C=[null],e=[],J=this.table,s="",ce=0,Ye=0,Je=2,Ke=1,Ze=e.slice.call(arguments,1),D=Object.create(this.lexer),w={yy:{}};for(var Ne in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Ne)&&(w.yy[Ne]=this.yy[Ne]);D.setInput(o,w.yy),w.yy.lexer=D,w.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var Le=D.yylloc;e.push(Le);var $e=D.options&&D.options.ranges;typeof w.yy.parseError=="function"?this.parseError=w.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function et(S){p.length=p.length-2*S,C.length=C.length-S,e.length=e.length-S}f(et,"popStack");function We(){var S;return S=l.pop()||D.lex()||Ke,typeof S!="number"&&(S instanceof Array&&(l=S,S=l.pop()),S=h.symbols_[S]||S),S}f(We,"lex");for(var B,V,L,xe,R={},oe,v,Qe,he;;){if(V=p[p.length-1],this.defaultActions[V]?L=this.defaultActions[V]:((B===null||typeof B>"u")&&(B=We()),L=J[V]&&J[V][B]),typeof L>"u"||!L.length||!L[0]){var ve="";he=[];for(oe in J[V])this.terminals_[oe]&&oe>Je&&he.push("'"+this.terminals_[oe]+"'");D.showPosition?ve="Parse error on line "+(ce+1)+`: `+D.showPosition()+` Expecting `+he.join(", ")+", got '"+(this.terminals_[B]||B)+"'":ve="Parse error on line "+(ce+1)+": Unexpected "+(B==Ke?"end of input":"'"+(this.terminals_[B]||B)+"'"),this.parseError(ve,{text:D.match,token:this.terminals_[B]||B,line:D.yylineno,loc:Le,expected:he})}if(L[0]instanceof Array&&L.length>1)throw new Error("Parse Error: multiple actions possible at state: "+V+", token: "+B);switch(L[0]){case 1:p.push(B),C.push(D.yytext),e.push(D.yylloc),p.push(L[1]),B=null,Ye=D.yyleng,s=D.yytext,ce=D.yylineno,Le=D.yylloc;break;case 2:if(v=this.productions_[L[1]][1],R.$=C[C.length-v],R._$={first_line:e[e.length-(v||1)].first_line,last_line:e[e.length-1].last_line,first_column:e[e.length-(v||1)].first_column,last_column:e[e.length-1].last_column},$e&&(R._$.range=[e[e.length-(v||1)].range[0],e[e.length-1].range[1]]),xe=this.performAction.apply(R,[s,Ye,ce,w.yy,L[1],C,e].concat(Ze)),typeof xe<"u")return xe;v&&(p=p.slice(0,-1*v*2),C=C.slice(0,-1*v),e=e.slice(0,-1*v)),p.push(this.productions_[L[1]][0]),C.push(R.$),e.push(R._$),Qe=J[p[p.length-2]][p[p.length-1]],p.push(Qe);break;case 3:return!0}}return!0},"parse")},He=(function(){var O={EOF:1,parseError:f(function(h,p){if(this.yy.parser)this.yy.parser.parseError(h,p);else throw new Error(h)},"parseError"),setInput:f(function(o,h){return this.yy=h||this.yy||{},this._input=o,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:f(function(){var o=this._input[0];this.yytext+=o,this.yyleng++,this.offset++,this.match+=o,this.matched+=o;var h=o.match(/(?:\r\n?|\n).*/g);return h?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),o},"input"),unput:f(function(o){var h=o.length,p=o.split(/(?:\r\n?|\n)/g);this._input=o+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-h),this.offset-=h;var l=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),p.length-1&&(this.yylineno-=p.length-1);var C=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:p?(p.length===l.length?this.yylloc.first_column:0)+l[l.length-p.length].length-p[0].length:this.yylloc.first_column-h},this.options.ranges&&(this.yylloc.range=[C[0],C[0]+this.yyleng-h]),this.yyleng=this.yytext.length,this},"unput"),more:f(function(){return this._more=!0,this},"more"),reject:f(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:f(function(o){this.unput(this.match.slice(o))},"less"),pastInput:f(function(){var o=this.matched.substr(0,this.matched.length-this.match.length);return(o.length>20?"...":"")+o.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:f(function(){var o=this.match;return o.length<20&&(o+=this._input.substr(0,20-o.length)),(o.substr(0,20)+(o.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:f(function(){var o=this.pastInput(),h=new Array(o.length+1).join("-");return o+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-Dzr2NgNj.js b/apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-CEH7JYJn.js similarity index 87% rename from apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-Dzr2NgNj.js rename to apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-CEH7JYJn.js index b5ea7b6fe..2d8f67ed1 100644 --- a/apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-Dzr2NgNj.js +++ b/apps/kimi-code/dist-web/assets/chunk-VR4S4FIN-CEH7JYJn.js @@ -1 +1 @@ -import{_ as a,e as w,l as x}from"./mermaid.core-DaDTfY6S.js";var d=a((e,t,i,r)=>{e.attr("class",i);const{width:o,height:h,x:n,y:c}=u(e,t);w(e,h,o,r);const s=l(n,c,o,h,t);e.attr("viewBox",s),x.debug(`viewBox configured: ${s} with padding: ${t}`)},"setupViewPortForSVG"),u=a((e,t)=>{const i=e.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:i.width+t*2,height:i.height+t*2,x:i.x,y:i.y}},"calculateDimensionsWithPadding"),l=a((e,t,i,r,o)=>`${e-o} ${t-o} ${i} ${r}`,"createViewBox");export{d as s}; +import{_ as a,e as w,l as x}from"./mermaid.core-CJB1tAev.js";var d=a((e,t,i,r)=>{e.attr("class",i);const{width:o,height:h,x:n,y:c}=u(e,t);w(e,h,o,r);const s=l(n,c,o,h,t);e.attr("viewBox",s),x.debug(`viewBox configured: ${s} with padding: ${t}`)},"setupViewPortForSVG"),u=a((e,t)=>{const i=e.node()?.getBBox()||{width:0,height:0,x:0,y:0};return{width:i.width+t*2,height:i.height+t*2,x:i.x,y:i.y}},"calculateDimensionsWithPadding"),l=a((e,t,i,r,o)=>`${e-o} ${t-o} ${i} ${r}`,"createViewBox");export{d as s}; diff --git a/apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-BEgNawAD.js b/apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-5rh7CWvm.js similarity index 72% rename from apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-BEgNawAD.js rename to apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-5rh7CWvm.js index 98cb65403..146d77322 100644 --- a/apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-BEgNawAD.js +++ b/apps/kimi-code/dist-web/assets/chunk-XXDRQBXY-5rh7CWvm.js @@ -1 +1 @@ -import{_ as a,d as o}from"./mermaid.core-DaDTfY6S.js";var d=a((t,e)=>{let n;return e==="sandbox"&&(n=o("#i"+t)),(e==="sandbox"?o(n.nodes()[0].contentDocument.body):o("body")).select(`[id="${t}"]`)},"getDiagramElement");export{d as g}; +import{_ as a,d as o}from"./mermaid.core-CJB1tAev.js";var d=a((t,e)=>{let n;return e==="sandbox"&&(n=o("#i"+t)),(e==="sandbox"?o(n.nodes()[0].contentDocument.body):o("body")).select(`[id="${t}"]`)},"getDiagramElement");export{d as g}; diff --git a/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-ClMG95L0.js b/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-ClMG95L0.js new file mode 100644 index 000000000..75377c626 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-ClMG95L0.js @@ -0,0 +1 @@ +import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-B4q9plWN.js";import{_ as i}from"./mermaid.core-CJB1tAev.js";import"./chunk-5VM5RSS4-yyj9cAyF.js";import"./chunk-XXDRQBXY-5rh7CWvm.js";import"./chunk-VR4S4FIN-CEH7JYJn.js";import"./chunk-32BRIVSS-DUDRPqmY.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; diff --git a/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-DPiTyikT.js b/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-DPiTyikT.js deleted file mode 100644 index 4c8869771..000000000 --- a/apps/kimi-code/dist-web/assets/classDiagram-OUVF2IWQ-DPiTyikT.js +++ /dev/null @@ -1 +0,0 @@ -import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-czNi1QQl.js";import{_ as i}from"./mermaid.core-DaDTfY6S.js";import"./chunk-5VM5RSS4-B87d3yQb.js";import"./chunk-XXDRQBXY-BEgNawAD.js";import"./chunk-VR4S4FIN-Dzr2NgNj.js";import"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; diff --git a/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-ClMG95L0.js b/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-ClMG95L0.js new file mode 100644 index 000000000..75377c626 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-ClMG95L0.js @@ -0,0 +1 @@ +import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-B4q9plWN.js";import{_ as i}from"./mermaid.core-CJB1tAev.js";import"./chunk-5VM5RSS4-yyj9cAyF.js";import"./chunk-XXDRQBXY-5rh7CWvm.js";import"./chunk-VR4S4FIN-CEH7JYJn.js";import"./chunk-32BRIVSS-DUDRPqmY.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; diff --git a/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-DPiTyikT.js b/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-DPiTyikT.js deleted file mode 100644 index 4c8869771..000000000 --- a/apps/kimi-code/dist-web/assets/classDiagram-v2-EOCWNBFH-DPiTyikT.js +++ /dev/null @@ -1 +0,0 @@ -import{s as a,c as s,a as e,C as t}from"./chunk-V7JOEXUC-czNi1QQl.js";import{_ as i}from"./mermaid.core-DaDTfY6S.js";import"./chunk-5VM5RSS4-B87d3yQb.js";import"./chunk-XXDRQBXY-BEgNawAD.js";import"./chunk-VR4S4FIN-Dzr2NgNj.js";import"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var f={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{f as diagram}; diff --git a/apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-CDDliH5o.js b/apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-TWQPJk-P.js similarity index 99% rename from apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-CDDliH5o.js rename to apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-TWQPJk-P.js index 7ac210200..7c650885b 100644 --- a/apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-CDDliH5o.js +++ b/apps/kimi-code/dist-web/assets/cose-bilkent-JH36ORCC-TWQPJk-P.js @@ -1 +1 @@ -import{_ as V,l as k,d as lt}from"./mermaid.core-DaDTfY6S.js";import{c as tt}from"./cytoscape.esm-OyMbaexL.js";import{g as gt}from"./_commonjsHelpers-CqkleIqs.js";import"./index-D1h84VfZ.js";var Z={exports:{}},$={exports:{}},Q={exports:{}},ut=Q.exports,j;function ft(){return j||(j=1,(function(G,b){(function(I,L){G.exports=L()})(ut,function(){return(function(N){var I={};function L(o){if(I[o])return I[o].exports;var e=I[o]={i:o,l:!1,exports:{}};return N[o].call(e.exports,e,e.exports,L),e.l=!0,e.exports}return L.m=N,L.c=I,L.i=function(o){return o},L.d=function(o,e,t){L.o(o,e)||Object.defineProperty(o,e,{configurable:!1,enumerable:!0,get:t})},L.n=function(o){var e=o&&o.__esModule?function(){return o.default}:function(){return o};return L.d(e,"a",e),e},L.o=function(o,e){return Object.prototype.hasOwnProperty.call(o,e)},L.p="",L(L.s=26)})([(function(N,I,L){function o(){}o.QUALITY=1,o.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,o.DEFAULT_INCREMENTAL=!1,o.DEFAULT_ANIMATION_ON_LAYOUT=!0,o.DEFAULT_ANIMATION_DURING_LAYOUT=!1,o.DEFAULT_ANIMATION_PERIOD=50,o.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,o.DEFAULT_GRAPH_MARGIN=15,o.NODE_DIMENSIONS_INCLUDE_LABELS=!1,o.SIMPLE_NODE_SIZE=40,o.SIMPLE_NODE_HALF_SIZE=o.SIMPLE_NODE_SIZE/2,o.EMPTY_COMPOUND_NODE_SIZE=40,o.MIN_EDGE_LENGTH=1,o.WORLD_BOUNDARY=1e6,o.INITIAL_WORLD_BOUNDARY=o.WORLD_BOUNDARY/1e3,o.WORLD_CENTER_X=1200,o.WORLD_CENTER_Y=900,N.exports=o}),(function(N,I,L){var o=L(2),e=L(8),t=L(9);function i(g,n,d){o.call(this,d),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=d,this.bendpoints=[],this.source=g,this.target=n}i.prototype=Object.create(o.prototype);for(var l in o)i[l]=o[l];i.prototype.getSource=function(){return this.source},i.prototype.getTarget=function(){return this.target},i.prototype.isInterGraph=function(){return this.isInterGraph},i.prototype.getLength=function(){return this.length},i.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},i.prototype.getBendpoints=function(){return this.bendpoints},i.prototype.getLca=function(){return this.lca},i.prototype.getSourceInLca=function(){return this.sourceInLca},i.prototype.getTargetInLca=function(){return this.targetInLca},i.prototype.getOtherEnd=function(g){if(this.source===g)return this.target;if(this.target===g)return this.source;throw"Node is not incident with this edge"},i.prototype.getOtherEndInGraph=function(g,n){for(var d=this.getOtherEnd(g),r=n.getGraphManager().getRoot();;){if(d.getOwner()==n)return d;if(d.getOwner()==r)break;d=d.getOwner().getParent()}return null},i.prototype.updateLength=function(){var g=new Array(4);this.isOverlapingSourceAndTarget=e.getIntersection(this.target.getRect(),this.source.getRect(),g),this.isOverlapingSourceAndTarget||(this.lengthX=g[0]-g[2],this.lengthY=g[1]-g[3],Math.abs(this.lengthX)<1&&(this.lengthX=t.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=t.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},i.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=t.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=t.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},N.exports=i}),(function(N,I,L){function o(e){this.vGraphObject=e}N.exports=o}),(function(N,I,L){var o=L(2),e=L(10),t=L(13),i=L(0),l=L(16),g=L(4);function n(r,h,a,p){a==null&&p==null&&(p=h),o.call(this,p),r.graphManager!=null&&(r=r.graphManager),this.estimatedSize=e.MIN_VALUE,this.inclusionTreeDepth=e.MAX_VALUE,this.vGraphObject=p,this.edges=[],this.graphManager=r,a!=null&&h!=null?this.rect=new t(h.x,h.y,a.width,a.height):this.rect=new t}n.prototype=Object.create(o.prototype);for(var d in o)n[d]=o[d];n.prototype.getEdges=function(){return this.edges},n.prototype.getChild=function(){return this.child},n.prototype.getOwner=function(){return this.owner},n.prototype.getWidth=function(){return this.rect.width},n.prototype.setWidth=function(r){this.rect.width=r},n.prototype.getHeight=function(){return this.rect.height},n.prototype.setHeight=function(r){this.rect.height=r},n.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},n.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},n.prototype.getCenter=function(){return new g(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},n.prototype.getLocation=function(){return new g(this.rect.x,this.rect.y)},n.prototype.getRect=function(){return this.rect},n.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},n.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},n.prototype.setRect=function(r,h){this.rect.x=r.x,this.rect.y=r.y,this.rect.width=h.width,this.rect.height=h.height},n.prototype.setCenter=function(r,h){this.rect.x=r-this.rect.width/2,this.rect.y=h-this.rect.height/2},n.prototype.setLocation=function(r,h){this.rect.x=r,this.rect.y=h},n.prototype.moveBy=function(r,h){this.rect.x+=r,this.rect.y+=h},n.prototype.getEdgeListToNode=function(r){var h=[],a=this;return a.edges.forEach(function(p){if(p.target==r){if(p.source!=a)throw"Incorrect edge source!";h.push(p)}}),h},n.prototype.getEdgesBetween=function(r){var h=[],a=this;return a.edges.forEach(function(p){if(!(p.source==a||p.target==a))throw"Incorrect edge source and/or target";(p.target==r||p.source==r)&&h.push(p)}),h},n.prototype.getNeighborsList=function(){var r=new Set,h=this;return h.edges.forEach(function(a){if(a.source==h)r.add(a.target);else{if(a.target!=h)throw"Incorrect incidency!";r.add(a.source)}}),r},n.prototype.withChildren=function(){var r=new Set,h,a;if(r.add(this),this.child!=null)for(var p=this.child.getNodes(),v=0;v<p.length;v++)h=p[v],a=h.withChildren(),a.forEach(function(D){r.add(D)});return r},n.prototype.getNoOfChildren=function(){var r=0,h;if(this.child==null)r=1;else for(var a=this.child.getNodes(),p=0;p<a.length;p++)h=a[p],r+=h.getNoOfChildren();return r==0&&(r=1),r},n.prototype.getEstimatedSize=function(){if(this.estimatedSize==e.MIN_VALUE)throw"assert failed";return this.estimatedSize},n.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},n.prototype.scatter=function(){var r,h,a=-i.INITIAL_WORLD_BOUNDARY,p=i.INITIAL_WORLD_BOUNDARY;r=i.WORLD_CENTER_X+l.nextDouble()*(p-a)+a;var v=-i.INITIAL_WORLD_BOUNDARY,D=i.INITIAL_WORLD_BOUNDARY;h=i.WORLD_CENTER_Y+l.nextDouble()*(D-v)+v,this.rect.x=r,this.rect.y=h},n.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var r=this.getChild();if(r.updateBounds(!0),this.rect.x=r.getLeft(),this.rect.y=r.getTop(),this.setWidth(r.getRight()-r.getLeft()),this.setHeight(r.getBottom()-r.getTop()),i.NODE_DIMENSIONS_INCLUDE_LABELS){var h=r.getRight()-r.getLeft(),a=r.getBottom()-r.getTop();this.labelWidth>h&&(this.rect.x-=(this.labelWidth-h)/2,this.setWidth(this.labelWidth)),this.labelHeight>a&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-a)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-a),this.setHeight(this.labelHeight))}}},n.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==e.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},n.prototype.transform=function(r){var h=this.rect.x;h>i.WORLD_BOUNDARY?h=i.WORLD_BOUNDARY:h<-i.WORLD_BOUNDARY&&(h=-i.WORLD_BOUNDARY);var a=this.rect.y;a>i.WORLD_BOUNDARY?a=i.WORLD_BOUNDARY:a<-i.WORLD_BOUNDARY&&(a=-i.WORLD_BOUNDARY);var p=new g(h,a),v=r.inverseTransformPoint(p);this.setLocation(v.x,v.y)},n.prototype.getLeft=function(){return this.rect.x},n.prototype.getRight=function(){return this.rect.x+this.rect.width},n.prototype.getTop=function(){return this.rect.y},n.prototype.getBottom=function(){return this.rect.y+this.rect.height},n.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},N.exports=n}),(function(N,I,L){function o(e,t){e==null&&t==null?(this.x=0,this.y=0):(this.x=e,this.y=t)}o.prototype.getX=function(){return this.x},o.prototype.getY=function(){return this.y},o.prototype.setX=function(e){this.x=e},o.prototype.setY=function(e){this.y=e},o.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},o.prototype.getCopy=function(){return new o(this.x,this.y)},o.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},N.exports=o}),(function(N,I,L){var o=L(2),e=L(10),t=L(0),i=L(6),l=L(3),g=L(1),n=L(13),d=L(12),r=L(11);function h(p,v,D){o.call(this,D),this.estimatedSize=e.MIN_VALUE,this.margin=t.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=p,v!=null&&v instanceof i?this.graphManager=v:v!=null&&v instanceof Layout&&(this.graphManager=v.graphManager)}h.prototype=Object.create(o.prototype);for(var a in o)h[a]=o[a];h.prototype.getNodes=function(){return this.nodes},h.prototype.getEdges=function(){return this.edges},h.prototype.getGraphManager=function(){return this.graphManager},h.prototype.getParent=function(){return this.parent},h.prototype.getLeft=function(){return this.left},h.prototype.getRight=function(){return this.right},h.prototype.getTop=function(){return this.top},h.prototype.getBottom=function(){return this.bottom},h.prototype.isConnected=function(){return this.isConnected},h.prototype.add=function(p,v,D){if(v==null&&D==null){var u=p;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(u)>-1)throw"Node already in graph!";return u.owner=this,this.getNodes().push(u),u}else{var T=p;if(!(this.getNodes().indexOf(v)>-1&&this.getNodes().indexOf(D)>-1))throw"Source or target not in graph!";if(!(v.owner==D.owner&&v.owner==this))throw"Both owners must be this graph!";return v.owner!=D.owner?null:(T.source=v,T.target=D,T.isInterGraph=!1,this.getEdges().push(T),v.edges.push(T),D!=v&&D.edges.push(T),T)}},h.prototype.remove=function(p){var v=p;if(p instanceof l){if(v==null)throw"Node is null!";if(!(v.owner!=null&&v.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var D=v.edges.slice(),u,T=D.length,y=0;y<T;y++)u=D[y],u.isInterGraph?this.graphManager.remove(u):u.source.owner.remove(u);var O=this.nodes.indexOf(v);if(O==-1)throw"Node not in owner node list!";this.nodes.splice(O,1)}else if(p instanceof g){var u=p;if(u==null)throw"Edge is null!";if(!(u.source!=null&&u.target!=null))throw"Source and/or target is null!";if(!(u.source.owner!=null&&u.target.owner!=null&&u.source.owner==this&&u.target.owner==this))throw"Source and/or target owner is invalid!";var s=u.source.edges.indexOf(u),f=u.target.edges.indexOf(u);if(!(s>-1&&f>-1))throw"Source and/or target doesn't know this edge!";u.source.edges.splice(s,1),u.target!=u.source&&u.target.edges.splice(f,1);var O=u.source.owner.getEdges().indexOf(u);if(O==-1)throw"Not in owner's edge list!";u.source.owner.getEdges().splice(O,1)}},h.prototype.updateLeftTop=function(){for(var p=e.MAX_VALUE,v=e.MAX_VALUE,D,u,T,y=this.getNodes(),O=y.length,s=0;s<O;s++){var f=y[s];D=f.getTop(),u=f.getLeft(),p>D&&(p=D),v>u&&(v=u)}return p==e.MAX_VALUE?null:(y[0].getParent().paddingLeft!=null?T=y[0].getParent().paddingLeft:T=this.margin,this.left=v-T,this.top=p-T,new d(this.left,this.top))},h.prototype.updateBounds=function(p){for(var v=e.MAX_VALUE,D=-e.MAX_VALUE,u=e.MAX_VALUE,T=-e.MAX_VALUE,y,O,s,f,c,E=this.nodes,A=E.length,m=0;m<A;m++){var C=E[m];p&&C.child!=null&&C.updateBounds(),y=C.getLeft(),O=C.getRight(),s=C.getTop(),f=C.getBottom(),v>y&&(v=y),D<O&&(D=O),u>s&&(u=s),T<f&&(T=f)}var R=new n(v,u,D-v,T-u);v==e.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),E[0].getParent().paddingLeft!=null?c=E[0].getParent().paddingLeft:c=this.margin,this.left=R.x-c,this.right=R.x+R.width+c,this.top=R.y-c,this.bottom=R.y+R.height+c},h.calculateBounds=function(p){for(var v=e.MAX_VALUE,D=-e.MAX_VALUE,u=e.MAX_VALUE,T=-e.MAX_VALUE,y,O,s,f,c=p.length,E=0;E<c;E++){var A=p[E];y=A.getLeft(),O=A.getRight(),s=A.getTop(),f=A.getBottom(),v>y&&(v=y),D<O&&(D=O),u>s&&(u=s),T<f&&(T=f)}var m=new n(v,u,D-v,T-u);return m},h.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},h.prototype.getEstimatedSize=function(){if(this.estimatedSize==e.MIN_VALUE)throw"assert failed";return this.estimatedSize},h.prototype.calcEstimatedSize=function(){for(var p=0,v=this.nodes,D=v.length,u=0;u<D;u++){var T=v[u];p+=T.calcEstimatedSize()}return p==0?this.estimatedSize=t.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=p/Math.sqrt(this.nodes.length),this.estimatedSize},h.prototype.updateConnected=function(){var p=this;if(this.nodes.length==0){this.isConnected=!0;return}var v=new r,D=new Set,u=this.nodes[0],T,y,O=u.withChildren();for(O.forEach(function(m){v.push(m),D.add(m)});v.length!==0;){u=v.shift(),T=u.getEdges();for(var s=T.length,f=0;f<s;f++){var c=T[f];if(y=c.getOtherEndInGraph(u,this),y!=null&&!D.has(y)){var E=y.withChildren();E.forEach(function(m){v.push(m),D.add(m)})}}}if(this.isConnected=!1,D.size>=this.nodes.length){var A=0;D.forEach(function(m){m.owner==p&&A++}),A==this.nodes.length&&(this.isConnected=!0)}},N.exports=h}),(function(N,I,L){var o,e=L(1);function t(i){o=L(5),this.layout=i,this.graphs=[],this.edges=[]}t.prototype.addRoot=function(){var i=this.layout.newGraph(),l=this.layout.newNode(null),g=this.add(i,l);return this.setRootGraph(g),this.rootGraph},t.prototype.add=function(i,l,g,n,d){if(g==null&&n==null&&d==null){if(i==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(i)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(i),i.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return i.parent=l,l.child=i,i}else{d=g,n=l,g=i;var r=n.getOwner(),h=d.getOwner();if(!(r!=null&&r.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(h!=null&&h.getGraphManager()==this))throw"Target not in this graph mgr!";if(r==h)return g.isInterGraph=!1,r.add(g,n,d);if(g.isInterGraph=!0,g.source=n,g.target=d,this.edges.indexOf(g)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(g),!(g.source!=null&&g.target!=null))throw"Edge source and/or target is null!";if(!(g.source.edges.indexOf(g)==-1&&g.target.edges.indexOf(g)==-1))throw"Edge already in source and/or target incidency list!";return g.source.edges.push(g),g.target.edges.push(g),g}},t.prototype.remove=function(i){if(i instanceof o){var l=i;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var g=[];g=g.concat(l.getEdges());for(var n,d=g.length,r=0;r<d;r++)n=g[r],l.remove(n);var h=[];h=h.concat(l.getNodes());var a;d=h.length;for(var r=0;r<d;r++)a=h[r],l.remove(a);l==this.rootGraph&&this.setRootGraph(null);var p=this.graphs.indexOf(l);this.graphs.splice(p,1),l.parent=null}else if(i instanceof e){if(n=i,n==null)throw"Edge is null!";if(!n.isInterGraph)throw"Not an inter-graph edge!";if(!(n.source!=null&&n.target!=null))throw"Source and/or target is null!";if(!(n.source.edges.indexOf(n)!=-1&&n.target.edges.indexOf(n)!=-1))throw"Source and/or target doesn't know this edge!";var p=n.source.edges.indexOf(n);if(n.source.edges.splice(p,1),p=n.target.edges.indexOf(n),n.target.edges.splice(p,1),!(n.source.owner!=null&&n.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(n.source.owner.getGraphManager().edges.indexOf(n)==-1)throw"Not in owner graph manager's edge list!";var p=n.source.owner.getGraphManager().edges.indexOf(n);n.source.owner.getGraphManager().edges.splice(p,1)}},t.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},t.prototype.getGraphs=function(){return this.graphs},t.prototype.getAllNodes=function(){if(this.allNodes==null){for(var i=[],l=this.getGraphs(),g=l.length,n=0;n<g;n++)i=i.concat(l[n].getNodes());this.allNodes=i}return this.allNodes},t.prototype.resetAllNodes=function(){this.allNodes=null},t.prototype.resetAllEdges=function(){this.allEdges=null},t.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},t.prototype.getAllEdges=function(){if(this.allEdges==null){var i=[],l=this.getGraphs();l.length;for(var g=0;g<l.length;g++)i=i.concat(l[g].getEdges());i=i.concat(this.edges),this.allEdges=i}return this.allEdges},t.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},t.prototype.setAllNodesToApplyGravitation=function(i){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=i},t.prototype.getRoot=function(){return this.rootGraph},t.prototype.setRootGraph=function(i){if(i.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=i,i.parent==null&&(i.parent=this.layout.newNode("Root node"))},t.prototype.getLayout=function(){return this.layout},t.prototype.isOneAncestorOfOther=function(i,l){if(!(i!=null&&l!=null))throw"assert failed";if(i==l)return!0;var g=i.getOwner(),n;do{if(n=g.getParent(),n==null)break;if(n==l)return!0;if(g=n.getOwner(),g==null)break}while(!0);g=l.getOwner();do{if(n=g.getParent(),n==null)break;if(n==i)return!0;if(g=n.getOwner(),g==null)break}while(!0);return!1},t.prototype.calcLowestCommonAncestors=function(){for(var i,l,g,n,d,r=this.getAllEdges(),h=r.length,a=0;a<h;a++){if(i=r[a],l=i.source,g=i.target,i.lca=null,i.sourceInLca=l,i.targetInLca=g,l==g){i.lca=l.getOwner();continue}for(n=l.getOwner();i.lca==null;){for(i.targetInLca=g,d=g.getOwner();i.lca==null;){if(d==n){i.lca=d;break}if(d==this.rootGraph)break;if(i.lca!=null)throw"assert failed";i.targetInLca=d.getParent(),d=i.targetInLca.getOwner()}if(n==this.rootGraph)break;i.lca==null&&(i.sourceInLca=n.getParent(),n=i.sourceInLca.getOwner())}if(i.lca==null)throw"assert failed"}},t.prototype.calcLowestCommonAncestor=function(i,l){if(i==l)return i.getOwner();var g=i.getOwner();do{if(g==null)break;var n=l.getOwner();do{if(n==null)break;if(n==g)return n;n=n.getParent().getOwner()}while(!0);g=g.getParent().getOwner()}while(!0);return g},t.prototype.calcInclusionTreeDepths=function(i,l){i==null&&l==null&&(i=this.rootGraph,l=1);for(var g,n=i.getNodes(),d=n.length,r=0;r<d;r++)g=n[r],g.inclusionTreeDepth=l,g.child!=null&&this.calcInclusionTreeDepths(g.child,l+1)},t.prototype.includesInvalidEdge=function(){for(var i,l=this.edges.length,g=0;g<l;g++)if(i=this.edges[g],this.isOneAncestorOfOther(i.source,i.target))return!0;return!1},N.exports=t}),(function(N,I,L){var o=L(0);function e(){}for(var t in o)e[t]=o[t];e.MAX_ITERATIONS=2500,e.DEFAULT_EDGE_LENGTH=50,e.DEFAULT_SPRING_STRENGTH=.45,e.DEFAULT_REPULSION_STRENGTH=4500,e.DEFAULT_GRAVITY_STRENGTH=.4,e.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,e.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,e.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,e.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,e.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,e.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,e.COOLING_ADAPTATION_FACTOR=.33,e.ADAPTATION_LOWER_NODE_LIMIT=1e3,e.ADAPTATION_UPPER_NODE_LIMIT=5e3,e.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,e.MAX_NODE_DISPLACEMENT=e.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,e.MIN_REPULSION_DIST=e.DEFAULT_EDGE_LENGTH/10,e.CONVERGENCE_CHECK_PERIOD=100,e.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,e.MIN_EDGE_LENGTH=1,e.GRID_CALCULATION_CHECK_PERIOD=10,N.exports=e}),(function(N,I,L){var o=L(12);function e(){}e.calcSeparationAmount=function(t,i,l,g){if(!t.intersects(i))throw"assert failed";var n=new Array(2);this.decideDirectionsForOverlappingNodes(t,i,n),l[0]=Math.min(t.getRight(),i.getRight())-Math.max(t.x,i.x),l[1]=Math.min(t.getBottom(),i.getBottom())-Math.max(t.y,i.y),t.getX()<=i.getX()&&t.getRight()>=i.getRight()?l[0]+=Math.min(i.getX()-t.getX(),t.getRight()-i.getRight()):i.getX()<=t.getX()&&i.getRight()>=t.getRight()&&(l[0]+=Math.min(t.getX()-i.getX(),i.getRight()-t.getRight())),t.getY()<=i.getY()&&t.getBottom()>=i.getBottom()?l[1]+=Math.min(i.getY()-t.getY(),t.getBottom()-i.getBottom()):i.getY()<=t.getY()&&i.getBottom()>=t.getBottom()&&(l[1]+=Math.min(t.getY()-i.getY(),i.getBottom()-t.getBottom()));var d=Math.abs((i.getCenterY()-t.getCenterY())/(i.getCenterX()-t.getCenterX()));i.getCenterY()===t.getCenterY()&&i.getCenterX()===t.getCenterX()&&(d=1);var r=d*l[0],h=l[1]/d;l[0]<h?h=l[0]:r=l[1],l[0]=-1*n[0]*(h/2+g),l[1]=-1*n[1]*(r/2+g)},e.decideDirectionsForOverlappingNodes=function(t,i,l){t.getCenterX()<i.getCenterX()?l[0]=-1:l[0]=1,t.getCenterY()<i.getCenterY()?l[1]=-1:l[1]=1},e.getIntersection2=function(t,i,l){var g=t.getCenterX(),n=t.getCenterY(),d=i.getCenterX(),r=i.getCenterY();if(t.intersects(i))return l[0]=g,l[1]=n,l[2]=d,l[3]=r,!0;var h=t.getX(),a=t.getY(),p=t.getRight(),v=t.getX(),D=t.getBottom(),u=t.getRight(),T=t.getWidthHalf(),y=t.getHeightHalf(),O=i.getX(),s=i.getY(),f=i.getRight(),c=i.getX(),E=i.getBottom(),A=i.getRight(),m=i.getWidthHalf(),C=i.getHeightHalf(),R=!1,M=!1;if(g===d){if(n>r)return l[0]=g,l[1]=a,l[2]=d,l[3]=E,!1;if(n<r)return l[0]=g,l[1]=D,l[2]=d,l[3]=s,!1}else if(n===r){if(g>d)return l[0]=h,l[1]=n,l[2]=f,l[3]=r,!1;if(g<d)return l[0]=p,l[1]=n,l[2]=O,l[3]=r,!1}else{var S=t.height/t.width,Y=i.height/i.width,w=(r-n)/(d-g),x=void 0,F=void 0,U=void 0,P=void 0,_=void 0,X=void 0;if(-S===w?g>d?(l[0]=v,l[1]=D,R=!0):(l[0]=p,l[1]=a,R=!0):S===w&&(g>d?(l[0]=h,l[1]=a,R=!0):(l[0]=u,l[1]=D,R=!0)),-Y===w?d>g?(l[2]=c,l[3]=E,M=!0):(l[2]=f,l[3]=s,M=!0):Y===w&&(d>g?(l[2]=O,l[3]=s,M=!0):(l[2]=A,l[3]=E,M=!0)),R&&M)return!1;if(g>d?n>r?(x=this.getCardinalDirection(S,w,4),F=this.getCardinalDirection(Y,w,2)):(x=this.getCardinalDirection(-S,w,3),F=this.getCardinalDirection(-Y,w,1)):n>r?(x=this.getCardinalDirection(-S,w,1),F=this.getCardinalDirection(-Y,w,3)):(x=this.getCardinalDirection(S,w,2),F=this.getCardinalDirection(Y,w,4)),!R)switch(x){case 1:P=a,U=g+-y/w,l[0]=U,l[1]=P;break;case 2:U=u,P=n+T*w,l[0]=U,l[1]=P;break;case 3:P=D,U=g+y/w,l[0]=U,l[1]=P;break;case 4:U=v,P=n+-T*w,l[0]=U,l[1]=P;break}if(!M)switch(F){case 1:X=s,_=d+-C/w,l[2]=_,l[3]=X;break;case 2:_=A,X=r+m*w,l[2]=_,l[3]=X;break;case 3:X=E,_=d+C/w,l[2]=_,l[3]=X;break;case 4:_=c,X=r+-m*w,l[2]=_,l[3]=X;break}}return!1},e.getCardinalDirection=function(t,i,l){return t>i?l:1+l%4},e.getIntersection=function(t,i,l,g){if(g==null)return this.getIntersection2(t,i,l);var n=t.x,d=t.y,r=i.x,h=i.y,a=l.x,p=l.y,v=g.x,D=g.y,u=void 0,T=void 0,y=void 0,O=void 0,s=void 0,f=void 0,c=void 0,E=void 0,A=void 0;return y=h-d,s=n-r,c=r*d-n*h,O=D-p,f=a-v,E=v*p-a*D,A=y*f-O*s,A===0?null:(u=(s*E-f*c)/A,T=(O*c-y*E)/A,new o(u,T))},e.angleOfVector=function(t,i,l,g){var n=void 0;return t!==l?(n=Math.atan((g-i)/(l-t)),l<t?n+=Math.PI:g<i&&(n+=this.TWO_PI)):g<i?n=this.ONE_AND_HALF_PI:n=this.HALF_PI,n},e.doIntersect=function(t,i,l,g){var n=t.x,d=t.y,r=i.x,h=i.y,a=l.x,p=l.y,v=g.x,D=g.y,u=(r-n)*(D-p)-(v-a)*(h-d);if(u===0)return!1;var T=((D-p)*(v-n)+(a-v)*(D-d))/u,y=((d-h)*(v-n)+(r-n)*(D-d))/u;return 0<T&&T<1&&0<y&&y<1},e.HALF_PI=.5*Math.PI,e.ONE_AND_HALF_PI=1.5*Math.PI,e.TWO_PI=2*Math.PI,e.THREE_PI=3*Math.PI,N.exports=e}),(function(N,I,L){function o(){}o.sign=function(e){return e>0?1:e<0?-1:0},o.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},o.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},N.exports=o}),(function(N,I,L){function o(){}o.MAX_VALUE=2147483647,o.MIN_VALUE=-2147483648,N.exports=o}),(function(N,I,L){var o=(function(){function n(d,r){for(var h=0;h<r.length;h++){var a=r[h];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(d,a.key,a)}}return function(d,r,h){return r&&n(d.prototype,r),h&&n(d,h),d}})();function e(n,d){if(!(n instanceof d))throw new TypeError("Cannot call a class as a function")}var t=function(d){return{value:d,next:null,prev:null}},i=function(d,r,h,a){return d!==null?d.next=r:a.head=r,h!==null?h.prev=r:a.tail=r,r.prev=d,r.next=h,a.length++,r},l=function(d,r){var h=d.prev,a=d.next;return h!==null?h.next=a:r.head=a,a!==null?a.prev=h:r.tail=h,d.prev=d.next=null,r.length--,d},g=(function(){function n(d){var r=this;e(this,n),this.length=0,this.head=null,this.tail=null,d?.forEach(function(h){return r.push(h)})}return o(n,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(r,h){return i(h.prev,t(r),h,this)}},{key:"insertAfter",value:function(r,h){return i(h,t(r),h.next,this)}},{key:"insertNodeBefore",value:function(r,h){return i(h.prev,r,h,this)}},{key:"insertNodeAfter",value:function(r,h){return i(h,r,h.next,this)}},{key:"push",value:function(r){return i(this.tail,t(r),null,this)}},{key:"unshift",value:function(r){return i(null,t(r),this.head,this)}},{key:"remove",value:function(r){return l(r,this)}},{key:"pop",value:function(){return l(this.tail,this).value}},{key:"popNode",value:function(){return l(this.tail,this)}},{key:"shift",value:function(){return l(this.head,this).value}},{key:"shiftNode",value:function(){return l(this.head,this)}},{key:"get_object_at",value:function(r){if(r<=this.length()){for(var h=1,a=this.head;h<r;)a=a.next,h++;return a.value}}},{key:"set_object_at",value:function(r,h){if(r<=this.length()){for(var a=1,p=this.head;a<r;)p=p.next,a++;p.value=h}}}]),n})();N.exports=g}),(function(N,I,L){function o(e,t,i){this.x=null,this.y=null,e==null&&t==null&&i==null?(this.x=0,this.y=0):typeof e=="number"&&typeof t=="number"&&i==null?(this.x=e,this.y=t):e.constructor.name=="Point"&&t==null&&i==null&&(i=e,this.x=i.x,this.y=i.y)}o.prototype.getX=function(){return this.x},o.prototype.getY=function(){return this.y},o.prototype.getLocation=function(){return new o(this.x,this.y)},o.prototype.setLocation=function(e,t,i){e.constructor.name=="Point"&&t==null&&i==null?(i=e,this.setLocation(i.x,i.y)):typeof e=="number"&&typeof t=="number"&&i==null&&(parseInt(e)==e&&parseInt(t)==t?this.move(e,t):(this.x=Math.floor(e+.5),this.y=Math.floor(t+.5)))},o.prototype.move=function(e,t){this.x=e,this.y=t},o.prototype.translate=function(e,t){this.x+=e,this.y+=t},o.prototype.equals=function(e){if(e.constructor.name=="Point"){var t=e;return this.x==t.x&&this.y==t.y}return this==e},o.prototype.toString=function(){return new o().constructor.name+"[x="+this.x+",y="+this.y+"]"},N.exports=o}),(function(N,I,L){function o(e,t,i,l){this.x=0,this.y=0,this.width=0,this.height=0,e!=null&&t!=null&&i!=null&&l!=null&&(this.x=e,this.y=t,this.width=i,this.height=l)}o.prototype.getX=function(){return this.x},o.prototype.setX=function(e){this.x=e},o.prototype.getY=function(){return this.y},o.prototype.setY=function(e){this.y=e},o.prototype.getWidth=function(){return this.width},o.prototype.setWidth=function(e){this.width=e},o.prototype.getHeight=function(){return this.height},o.prototype.setHeight=function(e){this.height=e},o.prototype.getRight=function(){return this.x+this.width},o.prototype.getBottom=function(){return this.y+this.height},o.prototype.intersects=function(e){return!(this.getRight()<e.x||this.getBottom()<e.y||e.getRight()<this.x||e.getBottom()<this.y)},o.prototype.getCenterX=function(){return this.x+this.width/2},o.prototype.getMinX=function(){return this.getX()},o.prototype.getMaxX=function(){return this.getX()+this.width},o.prototype.getCenterY=function(){return this.y+this.height/2},o.prototype.getMinY=function(){return this.getY()},o.prototype.getMaxY=function(){return this.getY()+this.height},o.prototype.getWidthHalf=function(){return this.width/2},o.prototype.getHeightHalf=function(){return this.height/2},N.exports=o}),(function(N,I,L){var o=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function e(){}e.lastID=0,e.createID=function(t){return e.isPrimitive(t)?t:(t.uniqueID!=null||(t.uniqueID=e.getString(),e.lastID++),t.uniqueID)},e.getString=function(t){return t==null&&(t=e.lastID),"Object#"+t},e.isPrimitive=function(t){var i=typeof t>"u"?"undefined":o(t);return t==null||i!="object"&&i!="function"},N.exports=e}),(function(N,I,L){function o(a){if(Array.isArray(a)){for(var p=0,v=Array(a.length);p<a.length;p++)v[p]=a[p];return v}else return Array.from(a)}var e=L(0),t=L(6),i=L(3),l=L(1),g=L(5),n=L(4),d=L(17),r=L(27);function h(a){r.call(this),this.layoutQuality=e.QUALITY,this.createBendsAsNeeded=e.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=e.DEFAULT_INCREMENTAL,this.animationOnLayout=e.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=e.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=e.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=e.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new t(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,a!=null&&(this.isRemoteUse=a)}h.RANDOM_SEED=1,h.prototype=Object.create(r.prototype),h.prototype.getGraphManager=function(){return this.graphManager},h.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},h.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},h.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},h.prototype.newGraphManager=function(){var a=new t(this);return this.graphManager=a,a},h.prototype.newGraph=function(a){return new g(null,this.graphManager,a)},h.prototype.newNode=function(a){return new i(this.graphManager,a)},h.prototype.newEdge=function(a){return new l(null,null,a)},h.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},h.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var a;return this.checkLayoutSuccess()?a=!1:a=this.layout(),e.ANIMATE==="during"?!1:(a&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,a)},h.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},h.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var a=this.graphManager.getAllEdges(),p=0;p<a.length;p++)a[p];for(var v=this.graphManager.getRoot().getNodes(),p=0;p<v.length;p++)v[p];this.update(this.graphManager.getRoot())}},h.prototype.update=function(a){if(a==null)this.update2();else if(a instanceof i){var p=a;if(p.getChild()!=null)for(var v=p.getChild().getNodes(),D=0;D<v.length;D++)update(v[D]);if(p.vGraphObject!=null){var u=p.vGraphObject;u.update(p)}}else if(a instanceof l){var T=a;if(T.vGraphObject!=null){var y=T.vGraphObject;y.update(T)}}else if(a instanceof g){var O=a;if(O.vGraphObject!=null){var s=O.vGraphObject;s.update(O)}}},h.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=e.QUALITY,this.animationDuringLayout=e.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=e.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=e.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=e.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=e.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=e.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},h.prototype.transform=function(a){if(a==null)this.transform(new n(0,0));else{var p=new d,v=this.graphManager.getRoot().updateLeftTop();if(v!=null){p.setWorldOrgX(a.x),p.setWorldOrgY(a.y),p.setDeviceOrgX(v.x),p.setDeviceOrgY(v.y);for(var D=this.getAllNodes(),u,T=0;T<D.length;T++)u=D[T],u.transform(p)}}},h.prototype.positionNodesRandomly=function(a){if(a==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var p,v,D=a.getNodes(),u=0;u<D.length;u++)p=D[u],v=p.getChild(),v==null||v.getNodes().length==0?p.scatter():(this.positionNodesRandomly(v),p.updateBounds())},h.prototype.getFlatForest=function(){for(var a=[],p=!0,v=this.graphManager.getRoot().getNodes(),D=!0,u=0;u<v.length;u++)v[u].getChild()!=null&&(D=!1);if(!D)return a;var T=new Set,y=[],O=new Map,s=[];for(s=s.concat(v);s.length>0&&p;){for(y.push(s[0]);y.length>0&&p;){var f=y[0];y.splice(0,1),T.add(f);for(var c=f.getEdges(),u=0;u<c.length;u++){var E=c[u].getOtherEnd(f);if(O.get(f)!=E)if(!T.has(E))y.push(E),O.set(E,f);else{p=!1;break}}}if(!p)a=[];else{var A=[].concat(o(T));a.push(A);for(var u=0;u<A.length;u++){var m=A[u],C=s.indexOf(m);C>-1&&s.splice(C,1)}T=new Set,O=new Map}}return a},h.prototype.createDummyNodesForBendpoints=function(a){for(var p=[],v=a.source,D=this.graphManager.calcLowestCommonAncestor(a.source,a.target),u=0;u<a.bendpoints.length;u++){var T=this.newNode(null);T.setRect(new Point(0,0),new Dimension(1,1)),D.add(T);var y=this.newEdge(null);this.graphManager.add(y,v,T),p.add(T),v=T}var y=this.newEdge(null);return this.graphManager.add(y,v,a.target),this.edgeToDummyNodes.set(a,p),a.isInterGraph()?this.graphManager.remove(a):D.remove(a),p},h.prototype.createBendpointsFromDummyNodes=function(){var a=[];a=a.concat(this.graphManager.getAllEdges()),a=[].concat(o(this.edgeToDummyNodes.keys())).concat(a);for(var p=0;p<a.length;p++){var v=a[p];if(v.bendpoints.length>0){for(var D=this.edgeToDummyNodes.get(v),u=0;u<D.length;u++){var T=D[u],y=new n(T.getCenterX(),T.getCenterY()),O=v.bendpoints.get(u);O.x=y.x,O.y=y.y,T.getOwner().remove(T)}this.graphManager.add(v,v.source,v.target)}}},h.transform=function(a,p,v,D){if(v!=null&&D!=null){var u=p;if(a<=50){var T=p/v;u-=(p-T)/50*(50-a)}else{var y=p*D;u+=(y-p)/50*(a-50)}return u}else{var O,s;return a<=50?(O=9*p/500,s=p/10):(O=9*p/50,s=-8*p),O*a+s}},h.findCenterOfTree=function(a){var p=[];p=p.concat(a);var v=[],D=new Map,u=!1,T=null;(p.length==1||p.length==2)&&(u=!0,T=p[0]);for(var y=0;y<p.length;y++){var O=p[y],s=O.getNeighborsList().size;D.set(O,O.getNeighborsList().size),s==1&&v.push(O)}var f=[];for(f=f.concat(v);!u;){var c=[];c=c.concat(f),f=[];for(var y=0;y<p.length;y++){var O=p[y],E=p.indexOf(O);E>=0&&p.splice(E,1);var A=O.getNeighborsList();A.forEach(function(R){if(v.indexOf(R)<0){var M=D.get(R),S=M-1;S==1&&f.push(R),D.set(R,S)}})}v=v.concat(f),(p.length==1||p.length==2)&&(u=!0,T=p[0])}return T},h.prototype.setGraphManager=function(a){this.graphManager=a},N.exports=h}),(function(N,I,L){function o(){}o.seed=1,o.x=0,o.nextDouble=function(){return o.x=Math.sin(o.seed++)*1e4,o.x-Math.floor(o.x)},N.exports=o}),(function(N,I,L){var o=L(4);function e(t,i){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}e.prototype.getWorldOrgX=function(){return this.lworldOrgX},e.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},e.prototype.getWorldOrgY=function(){return this.lworldOrgY},e.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},e.prototype.getWorldExtX=function(){return this.lworldExtX},e.prototype.setWorldExtX=function(t){this.lworldExtX=t},e.prototype.getWorldExtY=function(){return this.lworldExtY},e.prototype.setWorldExtY=function(t){this.lworldExtY=t},e.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},e.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},e.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},e.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},e.prototype.getDeviceExtX=function(){return this.ldeviceExtX},e.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},e.prototype.getDeviceExtY=function(){return this.ldeviceExtY},e.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},e.prototype.transformX=function(t){var i=0,l=this.lworldExtX;return l!=0&&(i=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/l),i},e.prototype.transformY=function(t){var i=0,l=this.lworldExtY;return l!=0&&(i=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/l),i},e.prototype.inverseTransformX=function(t){var i=0,l=this.ldeviceExtX;return l!=0&&(i=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/l),i},e.prototype.inverseTransformY=function(t){var i=0,l=this.ldeviceExtY;return l!=0&&(i=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/l),i},e.prototype.inverseTransformPoint=function(t){var i=new o(this.inverseTransformX(t.x),this.inverseTransformY(t.y));return i},N.exports=e}),(function(N,I,L){function o(r){if(Array.isArray(r)){for(var h=0,a=Array(r.length);h<r.length;h++)a[h]=r[h];return a}else return Array.from(r)}var e=L(15),t=L(7),i=L(0),l=L(8),g=L(9);function n(){e.call(this),this.useSmartIdealEdgeLengthCalculation=t.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=t.DEFAULT_EDGE_LENGTH,this.springConstant=t.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=t.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=t.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=t.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=t.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=t.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*t.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=t.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=t.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=t.MAX_ITERATIONS}n.prototype=Object.create(e.prototype);for(var d in e)n[d]=e[d];n.prototype.initParameters=function(){e.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=t.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},n.prototype.calcIdealEdgeLengths=function(){for(var r,h,a,p,v,D,u=this.getGraphManager().getAllEdges(),T=0;T<u.length;T++)r=u[T],r.idealLength=this.idealEdgeLength,r.isInterGraph&&(a=r.getSource(),p=r.getTarget(),v=r.getSourceInLca().getEstimatedSize(),D=r.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(r.idealLength+=v+D-2*i.SIMPLE_NODE_SIZE),h=r.getLca().getInclusionTreeDepth(),r.idealLength+=t.DEFAULT_EDGE_LENGTH*t.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(a.getInclusionTreeDepth()+p.getInclusionTreeDepth()-2*h))},n.prototype.initSpringEmbedder=function(){var r=this.getAllNodes().length;this.incremental?(r>t.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*t.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(r-t.ADAPTATION_LOWER_NODE_LIMIT)/(t.ADAPTATION_UPPER_NODE_LIMIT-t.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-t.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=t.MAX_NODE_DISPLACEMENT_INCREMENTAL):(r>t.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(t.COOLING_ADAPTATION_FACTOR,1-(r-t.ADAPTATION_LOWER_NODE_LIMIT)/(t.ADAPTATION_UPPER_NODE_LIMIT-t.ADAPTATION_LOWER_NODE_LIMIT)*(1-t.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=t.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},n.prototype.calcSpringForces=function(){for(var r=this.getAllEdges(),h,a=0;a<r.length;a++)h=r[a],this.calcSpringForce(h,h.idealLength)},n.prototype.calcRepulsionForces=function(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,h=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,a,p,v,D,u=this.getAllNodes(),T;if(this.useFRGridVariant)for(this.totalIterations%t.GRID_CALCULATION_CHECK_PERIOD==1&&r&&this.updateGrid(),T=new Set,a=0;a<u.length;a++)v=u[a],this.calculateRepulsionForceOfANode(v,T,r,h),T.add(v);else for(a=0;a<u.length;a++)for(v=u[a],p=a+1;p<u.length;p++)D=u[p],v.getOwner()==D.getOwner()&&this.calcRepulsionForce(v,D)},n.prototype.calcGravitationalForces=function(){for(var r,h=this.getAllNodesToApplyGravitation(),a=0;a<h.length;a++)r=h[a],this.calcGravitationalForce(r)},n.prototype.moveNodes=function(){for(var r=this.getAllNodes(),h,a=0;a<r.length;a++)h=r[a],h.move()},n.prototype.calcSpringForce=function(r,h){var a=r.getSource(),p=r.getTarget(),v,D,u,T;if(this.uniformLeafNodeSizes&&a.getChild()==null&&p.getChild()==null)r.updateLengthSimple();else if(r.updateLength(),r.isOverlapingSourceAndTarget)return;v=r.getLength(),v!=0&&(D=this.springConstant*(v-h),u=D*(r.lengthX/v),T=D*(r.lengthY/v),a.springForceX+=u,a.springForceY+=T,p.springForceX-=u,p.springForceY-=T)},n.prototype.calcRepulsionForce=function(r,h){var a=r.getRect(),p=h.getRect(),v=new Array(2),D=new Array(4),u,T,y,O,s,f,c;if(a.intersects(p)){l.calcSeparationAmount(a,p,v,t.DEFAULT_EDGE_LENGTH/2),f=2*v[0],c=2*v[1];var E=r.noOfChildren*h.noOfChildren/(r.noOfChildren+h.noOfChildren);r.repulsionForceX-=E*f,r.repulsionForceY-=E*c,h.repulsionForceX+=E*f,h.repulsionForceY+=E*c}else this.uniformLeafNodeSizes&&r.getChild()==null&&h.getChild()==null?(u=p.getCenterX()-a.getCenterX(),T=p.getCenterY()-a.getCenterY()):(l.getIntersection(a,p,D),u=D[2]-D[0],T=D[3]-D[1]),Math.abs(u)<t.MIN_REPULSION_DIST&&(u=g.sign(u)*t.MIN_REPULSION_DIST),Math.abs(T)<t.MIN_REPULSION_DIST&&(T=g.sign(T)*t.MIN_REPULSION_DIST),y=u*u+T*T,O=Math.sqrt(y),s=this.repulsionConstant*r.noOfChildren*h.noOfChildren/y,f=s*u/O,c=s*T/O,r.repulsionForceX-=f,r.repulsionForceY-=c,h.repulsionForceX+=f,h.repulsionForceY+=c},n.prototype.calcGravitationalForce=function(r){var h,a,p,v,D,u,T,y;h=r.getOwner(),a=(h.getRight()+h.getLeft())/2,p=(h.getTop()+h.getBottom())/2,v=r.getCenterX()-a,D=r.getCenterY()-p,u=Math.abs(v)+r.getWidth()/2,T=Math.abs(D)+r.getHeight()/2,r.getOwner()==this.graphManager.getRoot()?(y=h.getEstimatedSize()*this.gravityRangeFactor,(u>y||T>y)&&(r.gravitationForceX=-this.gravityConstant*v,r.gravitationForceY=-this.gravityConstant*D)):(y=h.getEstimatedSize()*this.compoundGravityRangeFactor,(u>y||T>y)&&(r.gravitationForceX=-this.gravityConstant*v*this.compoundGravityConstant,r.gravitationForceY=-this.gravityConstant*D*this.compoundGravityConstant))},n.prototype.isConverged=function(){var r,h=!1;return this.totalIterations>this.maxIterations/3&&(h=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),r=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,r||h},n.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},n.prototype.calcNoOfChildrenForAllNodes=function(){for(var r,h=this.graphManager.getAllNodes(),a=0;a<h.length;a++)r=h[a],r.noOfChildren=r.getNoOfChildren()},n.prototype.calcGrid=function(r){var h=0,a=0;h=parseInt(Math.ceil((r.getRight()-r.getLeft())/this.repulsionRange)),a=parseInt(Math.ceil((r.getBottom()-r.getTop())/this.repulsionRange));for(var p=new Array(h),v=0;v<h;v++)p[v]=new Array(a);for(var v=0;v<h;v++)for(var D=0;D<a;D++)p[v][D]=new Array;return p},n.prototype.addNodeToGrid=function(r,h,a){var p=0,v=0,D=0,u=0;p=parseInt(Math.floor((r.getRect().x-h)/this.repulsionRange)),v=parseInt(Math.floor((r.getRect().width+r.getRect().x-h)/this.repulsionRange)),D=parseInt(Math.floor((r.getRect().y-a)/this.repulsionRange)),u=parseInt(Math.floor((r.getRect().height+r.getRect().y-a)/this.repulsionRange));for(var T=p;T<=v;T++)for(var y=D;y<=u;y++)this.grid[T][y].push(r),r.setGridCoordinates(p,v,D,u)},n.prototype.updateGrid=function(){var r,h,a=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),r=0;r<a.length;r++)h=a[r],this.addNodeToGrid(h,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},n.prototype.calculateRepulsionForceOfANode=function(r,h,a,p){if(this.totalIterations%t.GRID_CALCULATION_CHECK_PERIOD==1&&a||p){var v=new Set;r.surrounding=new Array;for(var D,u=this.grid,T=r.startX-1;T<r.finishX+2;T++)for(var y=r.startY-1;y<r.finishY+2;y++)if(!(T<0||y<0||T>=u.length||y>=u[0].length)){for(var O=0;O<u[T][y].length;O++)if(D=u[T][y][O],!(r.getOwner()!=D.getOwner()||r==D)&&!h.has(D)&&!v.has(D)){var s=Math.abs(r.getCenterX()-D.getCenterX())-(r.getWidth()/2+D.getWidth()/2),f=Math.abs(r.getCenterY()-D.getCenterY())-(r.getHeight()/2+D.getHeight()/2);s<=this.repulsionRange&&f<=this.repulsionRange&&v.add(D)}}r.surrounding=[].concat(o(v))}for(T=0;T<r.surrounding.length;T++)this.calcRepulsionForce(r,r.surrounding[T])},n.prototype.calcRepulsionRange=function(){return 0},N.exports=n}),(function(N,I,L){var o=L(1),e=L(7);function t(l,g,n){o.call(this,l,g,n),this.idealLength=e.DEFAULT_EDGE_LENGTH}t.prototype=Object.create(o.prototype);for(var i in o)t[i]=o[i];N.exports=t}),(function(N,I,L){var o=L(3);function e(i,l,g,n){o.call(this,i,l,g,n),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}e.prototype=Object.create(o.prototype);for(var t in o)e[t]=o[t];e.prototype.setGridCoordinates=function(i,l,g,n){this.startX=i,this.finishX=l,this.startY=g,this.finishY=n},N.exports=e}),(function(N,I,L){function o(e,t){this.width=0,this.height=0,e!==null&&t!==null&&(this.height=t,this.width=e)}o.prototype.getWidth=function(){return this.width},o.prototype.setWidth=function(e){this.width=e},o.prototype.getHeight=function(){return this.height},o.prototype.setHeight=function(e){this.height=e},N.exports=o}),(function(N,I,L){var o=L(14);function e(){this.map={},this.keys=[]}e.prototype.put=function(t,i){var l=o.createID(t);this.contains(l)||(this.map[l]=i,this.keys.push(t))},e.prototype.contains=function(t){return o.createID(t),this.map[t]!=null},e.prototype.get=function(t){var i=o.createID(t);return this.map[i]},e.prototype.keySet=function(){return this.keys},N.exports=e}),(function(N,I,L){var o=L(14);function e(){this.set={}}e.prototype.add=function(t){var i=o.createID(t);this.contains(i)||(this.set[i]=t)},e.prototype.remove=function(t){delete this.set[o.createID(t)]},e.prototype.clear=function(){this.set={}},e.prototype.contains=function(t){return this.set[o.createID(t)]==t},e.prototype.isEmpty=function(){return this.size()===0},e.prototype.size=function(){return Object.keys(this.set).length},e.prototype.addAllTo=function(t){for(var i=Object.keys(this.set),l=i.length,g=0;g<l;g++)t.push(this.set[i[g]])},e.prototype.size=function(){return Object.keys(this.set).length},e.prototype.addAll=function(t){for(var i=t.length,l=0;l<i;l++){var g=t[l];this.add(g)}},N.exports=e}),(function(N,I,L){var o=(function(){function l(g,n){for(var d=0;d<n.length;d++){var r=n[d];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(g,r.key,r)}}return function(g,n,d){return n&&l(g.prototype,n),d&&l(g,d),g}})();function e(l,g){if(!(l instanceof g))throw new TypeError("Cannot call a class as a function")}var t=L(11),i=(function(){function l(g,n){e(this,l),(n!==null||n!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var d=void 0;g instanceof t?d=g.size():d=g.length,this._quicksort(g,0,d-1)}return o(l,[{key:"_quicksort",value:function(n,d,r){if(d<r){var h=this._partition(n,d,r);this._quicksort(n,d,h),this._quicksort(n,h+1,r)}}},{key:"_partition",value:function(n,d,r){for(var h=this._get(n,d),a=d,p=r;;){for(;this.compareFunction(h,this._get(n,p));)p--;for(;this.compareFunction(this._get(n,a),h);)a++;if(a<p)this._swap(n,a,p),a++,p--;else return p}}},{key:"_get",value:function(n,d){return n instanceof t?n.get_object_at(d):n[d]}},{key:"_set",value:function(n,d,r){n instanceof t?n.set_object_at(d,r):n[d]=r}},{key:"_swap",value:function(n,d,r){var h=this._get(n,d);this._set(n,d,this._get(n,r)),this._set(n,r,h)}},{key:"_defaultCompareFunction",value:function(n,d){return d>n}}]),l})();N.exports=i}),(function(N,I,L){var o=(function(){function i(l,g){for(var n=0;n<g.length;n++){var d=g[n];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(l,d.key,d)}}return function(l,g,n){return g&&i(l.prototype,g),n&&i(l,n),l}})();function e(i,l){if(!(i instanceof l))throw new TypeError("Cannot call a class as a function")}var t=(function(){function i(l,g){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,d=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,r=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;e(this,i),this.sequence1=l,this.sequence2=g,this.match_score=n,this.mismatch_penalty=d,this.gap_penalty=r,this.iMax=l.length+1,this.jMax=g.length+1,this.grid=new Array(this.iMax);for(var h=0;h<this.iMax;h++){this.grid[h]=new Array(this.jMax);for(var a=0;a<this.jMax;a++)this.grid[h][a]=0}this.tracebackGrid=new Array(this.iMax);for(var p=0;p<this.iMax;p++){this.tracebackGrid[p]=new Array(this.jMax);for(var v=0;v<this.jMax;v++)this.tracebackGrid[p][v]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return o(i,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var g=1;g<this.jMax;g++)this.grid[0][g]=this.grid[0][g-1]+this.gap_penalty,this.tracebackGrid[0][g]=[!1,!1,!0];for(var n=1;n<this.iMax;n++)this.grid[n][0]=this.grid[n-1][0]+this.gap_penalty,this.tracebackGrid[n][0]=[!1,!0,!1];for(var d=1;d<this.iMax;d++)for(var r=1;r<this.jMax;r++){var h=void 0;this.sequence1[d-1]===this.sequence2[r-1]?h=this.grid[d-1][r-1]+this.match_score:h=this.grid[d-1][r-1]+this.mismatch_penalty;var a=this.grid[d-1][r]+this.gap_penalty,p=this.grid[d][r-1]+this.gap_penalty,v=[h,a,p],D=this.arrayAllMaxIndexes(v);this.grid[d][r]=v[D[0]],this.tracebackGrid[d][r]=[D.includes(0),D.includes(1),D.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var g=[];for(g.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});g[0];){var n=g[0],d=this.tracebackGrid[n.pos[0]][n.pos[1]];d[0]&&g.push({pos:[n.pos[0]-1,n.pos[1]-1],seq1:this.sequence1[n.pos[0]-1]+n.seq1,seq2:this.sequence2[n.pos[1]-1]+n.seq2}),d[1]&&g.push({pos:[n.pos[0]-1,n.pos[1]],seq1:this.sequence1[n.pos[0]-1]+n.seq1,seq2:"-"+n.seq2}),d[2]&&g.push({pos:[n.pos[0],n.pos[1]-1],seq1:"-"+n.seq1,seq2:this.sequence2[n.pos[1]-1]+n.seq2}),n.pos[0]===0&&n.pos[1]===0&&this.alignments.push({sequence1:n.seq1,sequence2:n.seq2}),g.shift()}return this.alignments}},{key:"getAllIndexes",value:function(g,n){for(var d=[],r=-1;(r=g.indexOf(n,r+1))!==-1;)d.push(r);return d}},{key:"arrayAllMaxIndexes",value:function(g){return this.getAllIndexes(g,Math.max.apply(null,g))}}]),i})();N.exports=t}),(function(N,I,L){var o=function(){};o.FDLayout=L(18),o.FDLayoutConstants=L(7),o.FDLayoutEdge=L(19),o.FDLayoutNode=L(20),o.DimensionD=L(21),o.HashMap=L(22),o.HashSet=L(23),o.IGeometry=L(8),o.IMath=L(9),o.Integer=L(10),o.Point=L(12),o.PointD=L(4),o.RandomSeed=L(16),o.RectangleD=L(13),o.Transform=L(17),o.UniqueIDGeneretor=L(14),o.Quicksort=L(24),o.LinkedList=L(11),o.LGraphObject=L(2),o.LGraph=L(5),o.LEdge=L(1),o.LGraphManager=L(6),o.LNode=L(3),o.Layout=L(15),o.LayoutConstants=L(0),o.NeedlemanWunsch=L(25),N.exports=o}),(function(N,I,L){function o(){this.listeners=[]}var e=o.prototype;e.addListener=function(t,i){this.listeners.push({event:t,callback:i})},e.removeListener=function(t,i){for(var l=this.listeners.length;l>=0;l--){var g=this.listeners[l];g.event===t&&g.callback===i&&this.listeners.splice(l,1)}},e.emit=function(t,i){for(var l=0;l<this.listeners.length;l++){var g=this.listeners[l];t===g.event&&g.callback(i)}},N.exports=o})])})})(Q)),Q.exports}var ct=$.exports,z;function pt(){return z||(z=1,(function(G,b){(function(I,L){G.exports=L(ft())})(ct,function(N){return(function(I){var L={};function o(e){if(L[e])return L[e].exports;var t=L[e]={i:e,l:!1,exports:{}};return I[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=I,o.c=L,o.i=function(e){return e},o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=7)})([(function(I,L){I.exports=N}),(function(I,L,o){var e=o(0).FDLayoutConstants;function t(){}for(var i in e)t[i]=e[i];t.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,t.DEFAULT_RADIAL_SEPARATION=e.DEFAULT_EDGE_LENGTH,t.DEFAULT_COMPONENT_SEPERATION=60,t.TILE=!0,t.TILING_PADDING_VERTICAL=10,t.TILING_PADDING_HORIZONTAL=10,t.TREE_REDUCTION_ON_INCREMENTAL=!1,I.exports=t}),(function(I,L,o){var e=o(0).FDLayoutEdge;function t(l,g,n){e.call(this,l,g,n)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).LGraph;function t(l,g,n){e.call(this,l,g,n)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).LGraphManager;function t(l){e.call(this,l)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).FDLayoutNode,t=o(0).IMath;function i(g,n,d,r){e.call(this,g,n,d,r)}i.prototype=Object.create(e.prototype);for(var l in e)i[l]=e[l];i.prototype.move=function(){var g=this.graphManager.getLayout();this.displacementX=g.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=g.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>g.coolingFactor*g.maxNodeDisplacement&&(this.displacementX=g.coolingFactor*g.maxNodeDisplacement*t.sign(this.displacementX)),Math.abs(this.displacementY)>g.coolingFactor*g.maxNodeDisplacement&&(this.displacementY=g.coolingFactor*g.maxNodeDisplacement*t.sign(this.displacementY)),this.child==null?this.moveBy(this.displacementX,this.displacementY):this.child.getNodes().length==0?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),g.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},i.prototype.propogateDisplacementToChildren=function(g,n){for(var d=this.getChild().getNodes(),r,h=0;h<d.length;h++)r=d[h],r.getChild()==null?(r.moveBy(g,n),r.displacementX+=g,r.displacementY+=n):r.propogateDisplacementToChildren(g,n)},i.prototype.setPred1=function(g){this.pred1=g},i.prototype.getPred1=function(){return pred1},i.prototype.getPred2=function(){return pred2},i.prototype.setNext=function(g){this.next=g},i.prototype.getNext=function(){return next},i.prototype.setProcessed=function(g){this.processed=g},i.prototype.isProcessed=function(){return processed},I.exports=i}),(function(I,L,o){var e=o(0).FDLayout,t=o(4),i=o(3),l=o(5),g=o(2),n=o(1),d=o(0).FDLayoutConstants,r=o(0).LayoutConstants,h=o(0).Point,a=o(0).PointD,p=o(0).Layout,v=o(0).Integer,D=o(0).IGeometry,u=o(0).LGraph,T=o(0).Transform;function y(){e.call(this),this.toBeTiled={}}y.prototype=Object.create(e.prototype);for(var O in e)y[O]=e[O];y.prototype.newGraphManager=function(){var s=new t(this);return this.graphManager=s,s},y.prototype.newGraph=function(s){return new i(null,this.graphManager,s)},y.prototype.newNode=function(s){return new l(this.graphManager,s)},y.prototype.newEdge=function(s){return new g(null,null,s)},y.prototype.initParameters=function(){e.prototype.initParameters.call(this,arguments),this.isSubLayout||(n.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=n.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=d.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=d.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=d.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=d.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=d.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=d.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/d.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=d.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},y.prototype.layout=function(){var s=r.DEFAULT_CREATE_BENDS_AS_NEEDED;return s&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},y.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(n.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var f=new Set(this.getAllNodes()),c=this.nodesWithGravity.filter(function(m){return f.has(m)});this.graphManager.setAllNodesToApplyGravitation(c)}}else{var s=this.getFlatForest();if(s.length>0)this.positionNodesRadially(s);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var f=new Set(this.getAllNodes()),c=this.nodesWithGravity.filter(function(E){return f.has(E)});this.graphManager.setAllNodesToApplyGravitation(c),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},y.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%d.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var s=new Set(this.getAllNodes()),f=this.nodesWithGravity.filter(function(A){return s.has(A)});this.graphManager.setAllNodesToApplyGravitation(f),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var c=!this.isTreeGrowing&&!this.isGrowthFinished,E=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(c,E),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},y.prototype.getPositionsData=function(){for(var s=this.graphManager.getAllNodes(),f={},c=0;c<s.length;c++){var E=s[c].rect,A=s[c].id;f[A]={id:A,x:E.getCenterX(),y:E.getCenterY(),w:E.width,h:E.height}}return f},y.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var s=!1;if(d.ANIMATE==="during")this.emit("layoutstarted");else{for(;!s;)s=this.tick();this.graphManager.updateBounds()}},y.prototype.calculateNodesToApplyGravitationTo=function(){var s=[],f,c=this.graphManager.getGraphs(),E=c.length,A;for(A=0;A<E;A++)f=c[A],f.updateConnected(),f.isConnected||(s=s.concat(f.getNodes()));return s},y.prototype.createBendpoints=function(){var s=[];s=s.concat(this.graphManager.getAllEdges());var f=new Set,c;for(c=0;c<s.length;c++){var E=s[c];if(!f.has(E)){var A=E.getSource(),m=E.getTarget();if(A==m)E.getBendpoints().push(new a),E.getBendpoints().push(new a),this.createDummyNodesForBendpoints(E),f.add(E);else{var C=[];if(C=C.concat(A.getEdgeListToNode(m)),C=C.concat(m.getEdgeListToNode(A)),!f.has(C[0])){if(C.length>1){var R;for(R=0;R<C.length;R++){var M=C[R];M.getBendpoints().push(new a),this.createDummyNodesForBendpoints(M)}}C.forEach(function(S){f.add(S)})}}}if(f.size==s.length)break}},y.prototype.positionNodesRadially=function(s){for(var f=new h(0,0),c=Math.ceil(Math.sqrt(s.length)),E=0,A=0,m=0,C=new a(0,0),R=0;R<s.length;R++){R%c==0&&(m=0,A=E,R!=0&&(A+=n.DEFAULT_COMPONENT_SEPERATION),E=0);var M=s[R],S=p.findCenterOfTree(M);f.x=m,f.y=A,C=y.radialLayout(M,S,f),C.y>E&&(E=Math.floor(C.y)),m=Math.floor(C.x+n.DEFAULT_COMPONENT_SEPERATION)}this.transform(new a(r.WORLD_CENTER_X-C.x/2,r.WORLD_CENTER_Y-C.y/2))},y.radialLayout=function(s,f,c){var E=Math.max(this.maxDiagonalInTree(s),n.DEFAULT_RADIAL_SEPARATION);y.branchRadialLayout(f,null,0,359,0,E);var A=u.calculateBounds(s),m=new T;m.setDeviceOrgX(A.getMinX()),m.setDeviceOrgY(A.getMinY()),m.setWorldOrgX(c.x),m.setWorldOrgY(c.y);for(var C=0;C<s.length;C++){var R=s[C];R.transform(m)}var M=new a(A.getMaxX(),A.getMaxY());return m.inverseTransformPoint(M)},y.branchRadialLayout=function(s,f,c,E,A,m){var C=(E-c+1)/2;C<0&&(C+=180);var R=(C+c)%360,M=R*D.TWO_PI/360,S=A*Math.cos(M),Y=A*Math.sin(M);s.setCenter(S,Y);var w=[];w=w.concat(s.getEdges());var x=w.length;f!=null&&x--;for(var F=0,U=w.length,P,_=s.getEdgesBetween(f);_.length>1;){var X=_[0];_.splice(0,1);var H=w.indexOf(X);H>=0&&w.splice(H,1),U--,x--}f!=null?P=(w.indexOf(_[0])+1)%U:P=0;for(var W=Math.abs(E-c)/x,B=P;F!=x;B=++B%U){var K=w[B].getOtherEnd(s);if(K!=f){var q=(c+F*W)%360,ht=(q+W)%360;y.branchRadialLayout(K,s,q,ht,A+m,m),F++}}},y.maxDiagonalInTree=function(s){for(var f=v.MIN_VALUE,c=0;c<s.length;c++){var E=s[c],A=E.getDiagonal();A>f&&(f=A)}return f},y.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},y.prototype.groupZeroDegreeMembers=function(){var s=this,f={};this.memberGroups={},this.idToDummyNode={};for(var c=[],E=this.graphManager.getAllNodes(),A=0;A<E.length;A++){var m=E[A],C=m.getParent();this.getNodeDegreeWithChildren(m)===0&&(C.id==null||!this.getToBeTiled(C))&&c.push(m)}for(var A=0;A<c.length;A++){var m=c[A],R=m.getParent().id;typeof f[R]>"u"&&(f[R]=[]),f[R]=f[R].concat(m)}Object.keys(f).forEach(function(M){if(f[M].length>1){var S="DummyCompound_"+M;s.memberGroups[S]=f[M];var Y=f[M][0].getParent(),w=new l(s.graphManager);w.id=S,w.paddingLeft=Y.paddingLeft||0,w.paddingRight=Y.paddingRight||0,w.paddingBottom=Y.paddingBottom||0,w.paddingTop=Y.paddingTop||0,s.idToDummyNode[S]=w;var x=s.getGraphManager().add(s.newGraph(),w),F=Y.getChild();F.add(w);for(var U=0;U<f[M].length;U++){var P=f[M][U];F.remove(P),x.add(P)}}})},y.prototype.clearCompounds=function(){var s={},f={};this.performDFSOnCompounds();for(var c=0;c<this.compoundOrder.length;c++)f[this.compoundOrder[c].id]=this.compoundOrder[c],s[this.compoundOrder[c].id]=[].concat(this.compoundOrder[c].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[c].getChild()),this.compoundOrder[c].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(s,f)},y.prototype.clearZeroDegreeMembers=function(){var s=this,f=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(c){var E=s.idToDummyNode[c];f[c]=s.tileNodes(s.memberGroups[c],E.paddingLeft+E.paddingRight),E.rect.width=f[c].width,E.rect.height=f[c].height})},y.prototype.repopulateCompounds=function(){for(var s=this.compoundOrder.length-1;s>=0;s--){var f=this.compoundOrder[s],c=f.id,E=f.paddingLeft,A=f.paddingTop;this.adjustLocations(this.tiledMemberPack[c],f.rect.x,f.rect.y,E,A)}},y.prototype.repopulateZeroDegreeMembers=function(){var s=this,f=this.tiledZeroDegreePack;Object.keys(f).forEach(function(c){var E=s.idToDummyNode[c],A=E.paddingLeft,m=E.paddingTop;s.adjustLocations(f[c],E.rect.x,E.rect.y,A,m)})},y.prototype.getToBeTiled=function(s){var f=s.id;if(this.toBeTiled[f]!=null)return this.toBeTiled[f];var c=s.getChild();if(c==null)return this.toBeTiled[f]=!1,!1;for(var E=c.getNodes(),A=0;A<E.length;A++){var m=E[A];if(this.getNodeDegree(m)>0)return this.toBeTiled[f]=!1,!1;if(m.getChild()==null){this.toBeTiled[m.id]=!1;continue}if(!this.getToBeTiled(m))return this.toBeTiled[f]=!1,!1}return this.toBeTiled[f]=!0,!0},y.prototype.getNodeDegree=function(s){s.id;for(var f=s.getEdges(),c=0,E=0;E<f.length;E++){var A=f[E];A.getSource().id!==A.getTarget().id&&(c=c+1)}return c},y.prototype.getNodeDegreeWithChildren=function(s){var f=this.getNodeDegree(s);if(s.getChild()==null)return f;for(var c=s.getChild().getNodes(),E=0;E<c.length;E++){var A=c[E];f+=this.getNodeDegreeWithChildren(A)}return f},y.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},y.prototype.fillCompexOrderByDFS=function(s){for(var f=0;f<s.length;f++){var c=s[f];c.getChild()!=null&&this.fillCompexOrderByDFS(c.getChild().getNodes()),this.getToBeTiled(c)&&this.compoundOrder.push(c)}},y.prototype.adjustLocations=function(s,f,c,E,A){f+=E,c+=A;for(var m=f,C=0;C<s.rows.length;C++){var R=s.rows[C];f=m;for(var M=0,S=0;S<R.length;S++){var Y=R[S];Y.rect.x=f,Y.rect.y=c,f+=Y.rect.width+s.horizontalPadding,Y.rect.height>M&&(M=Y.rect.height)}c+=M+s.verticalPadding}},y.prototype.tileCompoundMembers=function(s,f){var c=this;this.tiledMemberPack=[],Object.keys(s).forEach(function(E){var A=f[E];c.tiledMemberPack[E]=c.tileNodes(s[E],A.paddingLeft+A.paddingRight),A.rect.width=c.tiledMemberPack[E].width,A.rect.height=c.tiledMemberPack[E].height})},y.prototype.tileNodes=function(s,f){var c=n.TILING_PADDING_VERTICAL,E=n.TILING_PADDING_HORIZONTAL,A={rows:[],rowWidth:[],rowHeight:[],width:0,height:f,verticalPadding:c,horizontalPadding:E};s.sort(function(R,M){return R.rect.width*R.rect.height>M.rect.width*M.rect.height?-1:R.rect.width*R.rect.height<M.rect.width*M.rect.height?1:0});for(var m=0;m<s.length;m++){var C=s[m];A.rows.length==0?this.insertNodeToRow(A,C,0,f):this.canAddHorizontal(A,C.rect.width,C.rect.height)?this.insertNodeToRow(A,C,this.getShortestRowIndex(A),f):this.insertNodeToRow(A,C,A.rows.length,f),this.shiftToLastRow(A)}return A},y.prototype.insertNodeToRow=function(s,f,c,E){var A=E;if(c==s.rows.length){var m=[];s.rows.push(m),s.rowWidth.push(A),s.rowHeight.push(0)}var C=s.rowWidth[c]+f.rect.width;s.rows[c].length>0&&(C+=s.horizontalPadding),s.rowWidth[c]=C,s.width<C&&(s.width=C);var R=f.rect.height;c>0&&(R+=s.verticalPadding);var M=0;R>s.rowHeight[c]&&(M=s.rowHeight[c],s.rowHeight[c]=R,M=s.rowHeight[c]-M),s.height+=M,s.rows[c].push(f)},y.prototype.getShortestRowIndex=function(s){for(var f=-1,c=Number.MAX_VALUE,E=0;E<s.rows.length;E++)s.rowWidth[E]<c&&(f=E,c=s.rowWidth[E]);return f},y.prototype.getLongestRowIndex=function(s){for(var f=-1,c=Number.MIN_VALUE,E=0;E<s.rows.length;E++)s.rowWidth[E]>c&&(f=E,c=s.rowWidth[E]);return f},y.prototype.canAddHorizontal=function(s,f,c){var E=this.getShortestRowIndex(s);if(E<0)return!0;var A=s.rowWidth[E];if(A+s.horizontalPadding+f<=s.width)return!0;var m=0;s.rowHeight[E]<c&&E>0&&(m=c+s.verticalPadding-s.rowHeight[E]);var C;s.width-A>=f+s.horizontalPadding?C=(s.height+m)/(A+f+s.horizontalPadding):C=(s.height+m)/s.width,m=c+s.verticalPadding;var R;return s.width<f?R=(s.height+m)/f:R=(s.height+m)/s.width,R<1&&(R=1/R),C<1&&(C=1/C),C<R},y.prototype.shiftToLastRow=function(s){var f=this.getLongestRowIndex(s),c=s.rowWidth.length-1,E=s.rows[f],A=E[E.length-1],m=A.width+s.horizontalPadding;if(s.width-s.rowWidth[c]>m&&f!=c){E.splice(-1,1),s.rows[c].push(A),s.rowWidth[f]=s.rowWidth[f]-m,s.rowWidth[c]=s.rowWidth[c]+m,s.width=s.rowWidth[instance.getLongestRowIndex(s)];for(var C=Number.MIN_VALUE,R=0;R<E.length;R++)E[R].height>C&&(C=E[R].height);f>0&&(C+=s.verticalPadding);var M=s.rowHeight[f]+s.rowHeight[c];s.rowHeight[f]=C,s.rowHeight[c]<A.height+s.verticalPadding&&(s.rowHeight[c]=A.height+s.verticalPadding);var S=s.rowHeight[f]+s.rowHeight[c];s.height+=S-M,this.shiftToLastRow(s)}},y.prototype.tilingPreLayout=function(){n.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},y.prototype.tilingPostLayout=function(){n.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},y.prototype.reduceTrees=function(){for(var s=[],f=!0,c;f;){var E=this.graphManager.getAllNodes(),A=[];f=!1;for(var m=0;m<E.length;m++)c=E[m],c.getEdges().length==1&&!c.getEdges()[0].isInterGraph&&c.getChild()==null&&(A.push([c,c.getEdges()[0],c.getOwner()]),f=!0);if(f==!0){for(var C=[],R=0;R<A.length;R++)A[R][0].getEdges().length==1&&(C.push(A[R]),A[R][0].getOwner().remove(A[R][0]));s.push(C),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=s},y.prototype.growTree=function(s){for(var f=s.length,c=s[f-1],E,A=0;A<c.length;A++)E=c[A],this.findPlaceforPrunedNode(E),E[2].add(E[0]),E[2].add(E[1],E[1].source,E[1].target);s.splice(s.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},y.prototype.findPlaceforPrunedNode=function(s){var f,c,E=s[0];E==s[1].source?c=s[1].target:c=s[1].source;var A=c.startX,m=c.finishX,C=c.startY,R=c.finishY,M=0,S=0,Y=0,w=0,x=[M,Y,S,w];if(C>0)for(var F=A;F<=m;F++)x[0]+=this.grid[F][C-1].length+this.grid[F][C].length-1;if(m<this.grid.length-1)for(var F=C;F<=R;F++)x[1]+=this.grid[m+1][F].length+this.grid[m][F].length-1;if(R<this.grid[0].length-1)for(var F=A;F<=m;F++)x[2]+=this.grid[F][R+1].length+this.grid[F][R].length-1;if(A>0)for(var F=C;F<=R;F++)x[3]+=this.grid[A-1][F].length+this.grid[A][F].length-1;for(var U=v.MAX_VALUE,P,_,X=0;X<x.length;X++)x[X]<U?(U=x[X],P=1,_=X):x[X]==U&&P++;if(P==3&&U==0)x[0]==0&&x[1]==0&&x[2]==0?f=1:x[0]==0&&x[1]==0&&x[3]==0?f=0:x[0]==0&&x[2]==0&&x[3]==0?f=3:x[1]==0&&x[2]==0&&x[3]==0&&(f=2);else if(P==2&&U==0){var H=Math.floor(Math.random()*2);x[0]==0&&x[1]==0?H==0?f=0:f=1:x[0]==0&&x[2]==0?H==0?f=0:f=2:x[0]==0&&x[3]==0?H==0?f=0:f=3:x[1]==0&&x[2]==0?H==0?f=1:f=2:x[1]==0&&x[3]==0?H==0?f=1:f=3:H==0?f=2:f=3}else if(P==4&&U==0){var H=Math.floor(Math.random()*4);f=H}else f=_;f==0?E.setCenter(c.getCenterX(),c.getCenterY()-c.getHeight()/2-d.DEFAULT_EDGE_LENGTH-E.getHeight()/2):f==1?E.setCenter(c.getCenterX()+c.getWidth()/2+d.DEFAULT_EDGE_LENGTH+E.getWidth()/2,c.getCenterY()):f==2?E.setCenter(c.getCenterX(),c.getCenterY()+c.getHeight()/2+d.DEFAULT_EDGE_LENGTH+E.getHeight()/2):E.setCenter(c.getCenterX()-c.getWidth()/2-d.DEFAULT_EDGE_LENGTH-E.getWidth()/2,c.getCenterY())},I.exports=y}),(function(I,L,o){var e={};e.layoutBase=o(0),e.CoSEConstants=o(1),e.CoSEEdge=o(2),e.CoSEGraph=o(3),e.CoSEGraphManager=o(4),e.CoSELayout=o(6),e.CoSENode=o(5),I.exports=e})])})})($)),$.exports}var dt=Z.exports,J;function vt(){return J||(J=1,(function(G,b){(function(I,L){G.exports=L(pt())})(dt,function(N){return(function(I){var L={};function o(e){if(L[e])return L[e].exports;var t=L[e]={i:e,l:!1,exports:{}};return I[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=I,o.c=L,o.i=function(e){return e},o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=1)})([(function(I,L){I.exports=N}),(function(I,L,o){var e=o(0).layoutBase.LayoutConstants,t=o(0).layoutBase.FDLayoutConstants,i=o(0).CoSEConstants,l=o(0).CoSELayout,g=o(0).CoSENode,n=o(0).layoutBase.PointD,d=o(0).layoutBase.DimensionD,r={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function h(D,u){var T={};for(var y in D)T[y]=D[y];for(var y in u)T[y]=u[y];return T}function a(D){this.options=h(r,D),p(this.options)}var p=function(u){u.nodeRepulsion!=null&&(i.DEFAULT_REPULSION_STRENGTH=t.DEFAULT_REPULSION_STRENGTH=u.nodeRepulsion),u.idealEdgeLength!=null&&(i.DEFAULT_EDGE_LENGTH=t.DEFAULT_EDGE_LENGTH=u.idealEdgeLength),u.edgeElasticity!=null&&(i.DEFAULT_SPRING_STRENGTH=t.DEFAULT_SPRING_STRENGTH=u.edgeElasticity),u.nestingFactor!=null&&(i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=t.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=u.nestingFactor),u.gravity!=null&&(i.DEFAULT_GRAVITY_STRENGTH=t.DEFAULT_GRAVITY_STRENGTH=u.gravity),u.numIter!=null&&(i.MAX_ITERATIONS=t.MAX_ITERATIONS=u.numIter),u.gravityRange!=null&&(i.DEFAULT_GRAVITY_RANGE_FACTOR=t.DEFAULT_GRAVITY_RANGE_FACTOR=u.gravityRange),u.gravityCompound!=null&&(i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=t.DEFAULT_COMPOUND_GRAVITY_STRENGTH=u.gravityCompound),u.gravityRangeCompound!=null&&(i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=t.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=u.gravityRangeCompound),u.initialEnergyOnIncremental!=null&&(i.DEFAULT_COOLING_FACTOR_INCREMENTAL=t.DEFAULT_COOLING_FACTOR_INCREMENTAL=u.initialEnergyOnIncremental),u.quality=="draft"?e.QUALITY=0:u.quality=="proof"?e.QUALITY=2:e.QUALITY=1,i.NODE_DIMENSIONS_INCLUDE_LABELS=t.NODE_DIMENSIONS_INCLUDE_LABELS=e.NODE_DIMENSIONS_INCLUDE_LABELS=u.nodeDimensionsIncludeLabels,i.DEFAULT_INCREMENTAL=t.DEFAULT_INCREMENTAL=e.DEFAULT_INCREMENTAL=!u.randomize,i.ANIMATE=t.ANIMATE=e.ANIMATE=u.animate,i.TILE=u.tile,i.TILING_PADDING_VERTICAL=typeof u.tilingPaddingVertical=="function"?u.tilingPaddingVertical.call():u.tilingPaddingVertical,i.TILING_PADDING_HORIZONTAL=typeof u.tilingPaddingHorizontal=="function"?u.tilingPaddingHorizontal.call():u.tilingPaddingHorizontal};a.prototype.run=function(){var D,u,T=this.options;this.idToLNode={};var y=this.layout=new l,O=this;O.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var s=y.newGraphManager();this.gm=s;var f=this.options.eles.nodes(),c=this.options.eles.edges();this.root=s.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(f),y);for(var E=0;E<c.length;E++){var A=c[E],m=this.idToLNode[A.data("source")],C=this.idToLNode[A.data("target")];if(m!==C&&m.getEdgesBetween(C).length==0){var R=s.add(y.newEdge(),m,C);R.id=A.id()}}var M=function(w,x){typeof w=="number"&&(w=x);var F=w.data("id"),U=O.idToLNode[F];return{x:U.getRect().getCenterX(),y:U.getRect().getCenterY()}},S=function Y(){for(var w=function(){T.fit&&T.cy.fit(T.eles,T.padding),D||(D=!0,O.cy.one("layoutready",T.ready),O.cy.trigger({type:"layoutready",layout:O}))},x=O.options.refresh,F,U=0;U<x&&!F;U++)F=O.stopped||O.layout.tick();if(F){y.checkLayoutSuccess()&&!y.isSubLayout&&y.doPostLayout(),y.tilingPostLayout&&y.tilingPostLayout(),y.isLayoutFinished=!0,O.options.eles.nodes().positions(M),w(),O.cy.one("layoutstop",O.options.stop),O.cy.trigger({type:"layoutstop",layout:O}),u&&cancelAnimationFrame(u),D=!1;return}var P=O.layout.getPositionsData();T.eles.nodes().positions(function(_,X){if(typeof _=="number"&&(_=X),!_.isParent()){for(var H=_.id(),W=P[H],B=_;W==null&&(W=P[B.data("parent")]||P["DummyCompound_"+B.data("parent")],P[H]=W,B=B.parent()[0],B!=null););return W!=null?{x:W.x,y:W.y}:{x:_.position("x"),y:_.position("y")}}}),w(),u=requestAnimationFrame(Y)};return y.addListener("layoutstarted",function(){O.options.animate==="during"&&(u=requestAnimationFrame(S))}),y.runLayout(),this.options.animate!=="during"&&(O.options.eles.nodes().not(":parent").layoutPositions(O,O.options,M),D=!1),this},a.prototype.getTopMostNodes=function(D){for(var u={},T=0;T<D.length;T++)u[D[T].id()]=!0;var y=D.filter(function(O,s){typeof O=="number"&&(O=s);for(var f=O.parent()[0];f!=null;){if(u[f.id()])return!1;f=f.parent()[0]}return!0});return y},a.prototype.processChildrenList=function(D,u,T){for(var y=u.length,O=0;O<y;O++){var s=u[O],f=s.children(),c,E=s.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if(s.outerWidth()!=null&&s.outerHeight()!=null?c=D.add(new g(T.graphManager,new n(s.position("x")-E.w/2,s.position("y")-E.h/2),new d(parseFloat(E.w),parseFloat(E.h)))):c=D.add(new g(this.graphManager)),c.id=s.data("id"),c.paddingLeft=parseInt(s.css("padding")),c.paddingTop=parseInt(s.css("padding")),c.paddingRight=parseInt(s.css("padding")),c.paddingBottom=parseInt(s.css("padding")),this.options.nodeDimensionsIncludeLabels&&s.isParent()){var A=s.boundingBox({includeLabels:!0,includeNodes:!1}).w,m=s.boundingBox({includeLabels:!0,includeNodes:!1}).h,C=s.css("text-halign");c.labelWidth=A,c.labelHeight=m,c.labelPos=C}if(this.idToLNode[s.data("id")]=c,isNaN(c.rect.x)&&(c.rect.x=0),isNaN(c.rect.y)&&(c.rect.y=0),f!=null&&f.length>0){var R;R=T.getGraphManager().add(T.newGraph(),c),this.processChildrenList(R,f,T)}}},a.prototype.stop=function(){return this.stopped=!0,this};var v=function(u){u("layout","cose-bilkent",a)};typeof cytoscape<"u"&&v(cytoscape),I.exports=v})])})})(Z)),Z.exports}var yt=vt();const Et=gt(yt);tt.use(Et);function et(G,b){G.forEach(N=>{const I={id:N.id,labelText:N.label,height:N.height,width:N.width,padding:N.padding??0};Object.keys(N).forEach(L=>{["id","label","height","width","padding","x","y"].includes(L)||(I[L]=N[L])}),b.add({group:"nodes",data:I,position:{x:N.x??0,y:N.y??0}})})}V(et,"addNodes");function rt(G,b){G.forEach(N=>{const I={id:N.id,source:N.start,target:N.end};Object.keys(N).forEach(L=>{["id","start","end"].includes(L)||(I[L]=N[L])}),b.add({group:"edges",data:I})})}V(rt,"addEdges");function it(G){return new Promise(b=>{const N=lt("body").append("div").attr("id","cy").attr("style","display:none"),I=tt({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});N.remove(),et(G.nodes,I),rt(G.edges,I),I.nodes().forEach(function(o){o.layoutDimensions=()=>{const e=o.data();return{w:e.width,h:e.height}}});const L={name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1};I.layout(L).run(),I.ready(o=>{k.info("Cytoscape ready",o),b(I)})})}V(it,"createCytoscapeInstance");function nt(G){return G.nodes().map(b=>{const N=b.data(),I=b.position(),L={id:N.id,x:I.x,y:I.y};return Object.keys(N).forEach(o=>{o!=="id"&&(L[o]=N[o])}),L})}V(nt,"extractPositionedNodes");function ot(G){return G.edges().map(b=>{const N=b.data(),I=b._private.rscratch,L={id:N.id,source:N.source,target:N.target,startX:I.startX,startY:I.startY,midX:I.midX,midY:I.midY,endX:I.endX,endY:I.endY};return Object.keys(N).forEach(o=>{["id","source","target"].includes(o)||(L[o]=N[o])}),L})}V(ot,"extractPositionedEdges");async function st(G,b){k.debug("Starting cose-bilkent layout algorithm");try{at(G);const N=await it(G),I=nt(N),L=ot(N);return k.debug(`Layout completed: ${I.length} nodes, ${L.length} edges`),{nodes:I,edges:L}}catch(N){throw k.error("Error in cose-bilkent layout algorithm:",N),N}}V(st,"executeCoseBilkentLayout");function at(G){if(!G)throw new Error("Layout data is required");if(!G.config)throw new Error("Configuration is required in layout data");if(!G.rootNode)throw new Error("Root node is required");if(!G.nodes||!Array.isArray(G.nodes))throw new Error("No nodes found in layout data");if(!Array.isArray(G.edges))throw new Error("Edges array is required in layout data");return!0}V(at,"validateLayoutData");var Lt=V(async(G,b,{insertCluster:N,insertEdge:I,insertEdgeLabel:L,insertMarkers:o,insertNode:e,log:t,positionEdgeLabel:i},{algorithm:l})=>{const g={},n={},d=b.select("g");o(d,G.markers,G.type,G.diagramId);const r=d.insert("g").attr("class","subgraphs"),h=d.insert("g").attr("class","edgePaths"),a=d.insert("g").attr("class","edgeLabels"),p=d.insert("g").attr("class","nodes");t.debug("Inserting nodes into DOM for dimension calculation"),await Promise.all(G.nodes.map(async u=>{if(u.isGroup){const T={...u};n[u.id]=T,g[u.id]=T,await N(r,u)}else{const T={...u};g[u.id]=T;const y=await e(p,u,{config:G.config,dir:G.direction||"TB"}),O=y.node().getBBox();T.width=O.width,T.height=O.height,T.domId=y,t.debug(`Node ${u.id} dimensions: ${O.width}x${O.height}`)}})),t.debug("Running cose-bilkent layout algorithm");const v={...G,nodes:G.nodes.map(u=>{const T=g[u.id];return{...u,width:T.width,height:T.height}})},D=await st(v,G.config);t.debug("Positioning nodes based on layout results"),D.nodes.forEach(u=>{const T=g[u.id];T?.domId&&(T.domId.attr("transform",`translate(${u.x}, ${u.y})`),T.x=u.x,T.y=u.y,t.debug(`Positioned node ${T.id} at center (${u.x}, ${u.y})`))}),D.edges.forEach(u=>{const T=G.edges.find(y=>y.id===u.id);T&&(T.points=[{x:u.startX,y:u.startY},{x:u.midX,y:u.midY},{x:u.endX,y:u.endY}])}),t.debug("Inserting and positioning edges"),await Promise.all(G.edges.map(async u=>{await L(a,u);const T=g[u.start??""],y=g[u.end??""];if(T&&y){const O=D.edges.find(s=>s.id===u.id);if(O){t.debug("APA01 positionedEdge",O);const s={...u},f=I(h,s,n,G.type,T,y,G.diagramId);i(s,f)}else{const s={...u,points:[{x:T.x||0,y:T.y||0},{x:y.x||0,y:y.y||0}]},f=I(h,s,n,G.type,T,y,G.diagramId);i(s,f)}}})),t.debug("Cose-bilkent rendering completed")},"render"),Ot=Lt;export{Ot as render}; +import{_ as V,l as k,d as lt}from"./mermaid.core-CJB1tAev.js";import{c as tt}from"./cytoscape.esm-OyMbaexL.js";import{g as gt}from"./_commonjsHelpers-CqkleIqs.js";import"./index-D-7nOosq.js";var Z={exports:{}},$={exports:{}},Q={exports:{}},ut=Q.exports,j;function ft(){return j||(j=1,(function(G,b){(function(I,L){G.exports=L()})(ut,function(){return(function(N){var I={};function L(o){if(I[o])return I[o].exports;var e=I[o]={i:o,l:!1,exports:{}};return N[o].call(e.exports,e,e.exports,L),e.l=!0,e.exports}return L.m=N,L.c=I,L.i=function(o){return o},L.d=function(o,e,t){L.o(o,e)||Object.defineProperty(o,e,{configurable:!1,enumerable:!0,get:t})},L.n=function(o){var e=o&&o.__esModule?function(){return o.default}:function(){return o};return L.d(e,"a",e),e},L.o=function(o,e){return Object.prototype.hasOwnProperty.call(o,e)},L.p="",L(L.s=26)})([(function(N,I,L){function o(){}o.QUALITY=1,o.DEFAULT_CREATE_BENDS_AS_NEEDED=!1,o.DEFAULT_INCREMENTAL=!1,o.DEFAULT_ANIMATION_ON_LAYOUT=!0,o.DEFAULT_ANIMATION_DURING_LAYOUT=!1,o.DEFAULT_ANIMATION_PERIOD=50,o.DEFAULT_UNIFORM_LEAF_NODE_SIZES=!1,o.DEFAULT_GRAPH_MARGIN=15,o.NODE_DIMENSIONS_INCLUDE_LABELS=!1,o.SIMPLE_NODE_SIZE=40,o.SIMPLE_NODE_HALF_SIZE=o.SIMPLE_NODE_SIZE/2,o.EMPTY_COMPOUND_NODE_SIZE=40,o.MIN_EDGE_LENGTH=1,o.WORLD_BOUNDARY=1e6,o.INITIAL_WORLD_BOUNDARY=o.WORLD_BOUNDARY/1e3,o.WORLD_CENTER_X=1200,o.WORLD_CENTER_Y=900,N.exports=o}),(function(N,I,L){var o=L(2),e=L(8),t=L(9);function i(g,n,d){o.call(this,d),this.isOverlapingSourceAndTarget=!1,this.vGraphObject=d,this.bendpoints=[],this.source=g,this.target=n}i.prototype=Object.create(o.prototype);for(var l in o)i[l]=o[l];i.prototype.getSource=function(){return this.source},i.prototype.getTarget=function(){return this.target},i.prototype.isInterGraph=function(){return this.isInterGraph},i.prototype.getLength=function(){return this.length},i.prototype.isOverlapingSourceAndTarget=function(){return this.isOverlapingSourceAndTarget},i.prototype.getBendpoints=function(){return this.bendpoints},i.prototype.getLca=function(){return this.lca},i.prototype.getSourceInLca=function(){return this.sourceInLca},i.prototype.getTargetInLca=function(){return this.targetInLca},i.prototype.getOtherEnd=function(g){if(this.source===g)return this.target;if(this.target===g)return this.source;throw"Node is not incident with this edge"},i.prototype.getOtherEndInGraph=function(g,n){for(var d=this.getOtherEnd(g),r=n.getGraphManager().getRoot();;){if(d.getOwner()==n)return d;if(d.getOwner()==r)break;d=d.getOwner().getParent()}return null},i.prototype.updateLength=function(){var g=new Array(4);this.isOverlapingSourceAndTarget=e.getIntersection(this.target.getRect(),this.source.getRect(),g),this.isOverlapingSourceAndTarget||(this.lengthX=g[0]-g[2],this.lengthY=g[1]-g[3],Math.abs(this.lengthX)<1&&(this.lengthX=t.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=t.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY))},i.prototype.updateLengthSimple=function(){this.lengthX=this.target.getCenterX()-this.source.getCenterX(),this.lengthY=this.target.getCenterY()-this.source.getCenterY(),Math.abs(this.lengthX)<1&&(this.lengthX=t.sign(this.lengthX)),Math.abs(this.lengthY)<1&&(this.lengthY=t.sign(this.lengthY)),this.length=Math.sqrt(this.lengthX*this.lengthX+this.lengthY*this.lengthY)},N.exports=i}),(function(N,I,L){function o(e){this.vGraphObject=e}N.exports=o}),(function(N,I,L){var o=L(2),e=L(10),t=L(13),i=L(0),l=L(16),g=L(4);function n(r,h,a,p){a==null&&p==null&&(p=h),o.call(this,p),r.graphManager!=null&&(r=r.graphManager),this.estimatedSize=e.MIN_VALUE,this.inclusionTreeDepth=e.MAX_VALUE,this.vGraphObject=p,this.edges=[],this.graphManager=r,a!=null&&h!=null?this.rect=new t(h.x,h.y,a.width,a.height):this.rect=new t}n.prototype=Object.create(o.prototype);for(var d in o)n[d]=o[d];n.prototype.getEdges=function(){return this.edges},n.prototype.getChild=function(){return this.child},n.prototype.getOwner=function(){return this.owner},n.prototype.getWidth=function(){return this.rect.width},n.prototype.setWidth=function(r){this.rect.width=r},n.prototype.getHeight=function(){return this.rect.height},n.prototype.setHeight=function(r){this.rect.height=r},n.prototype.getCenterX=function(){return this.rect.x+this.rect.width/2},n.prototype.getCenterY=function(){return this.rect.y+this.rect.height/2},n.prototype.getCenter=function(){return new g(this.rect.x+this.rect.width/2,this.rect.y+this.rect.height/2)},n.prototype.getLocation=function(){return new g(this.rect.x,this.rect.y)},n.prototype.getRect=function(){return this.rect},n.prototype.getDiagonal=function(){return Math.sqrt(this.rect.width*this.rect.width+this.rect.height*this.rect.height)},n.prototype.getHalfTheDiagonal=function(){return Math.sqrt(this.rect.height*this.rect.height+this.rect.width*this.rect.width)/2},n.prototype.setRect=function(r,h){this.rect.x=r.x,this.rect.y=r.y,this.rect.width=h.width,this.rect.height=h.height},n.prototype.setCenter=function(r,h){this.rect.x=r-this.rect.width/2,this.rect.y=h-this.rect.height/2},n.prototype.setLocation=function(r,h){this.rect.x=r,this.rect.y=h},n.prototype.moveBy=function(r,h){this.rect.x+=r,this.rect.y+=h},n.prototype.getEdgeListToNode=function(r){var h=[],a=this;return a.edges.forEach(function(p){if(p.target==r){if(p.source!=a)throw"Incorrect edge source!";h.push(p)}}),h},n.prototype.getEdgesBetween=function(r){var h=[],a=this;return a.edges.forEach(function(p){if(!(p.source==a||p.target==a))throw"Incorrect edge source and/or target";(p.target==r||p.source==r)&&h.push(p)}),h},n.prototype.getNeighborsList=function(){var r=new Set,h=this;return h.edges.forEach(function(a){if(a.source==h)r.add(a.target);else{if(a.target!=h)throw"Incorrect incidency!";r.add(a.source)}}),r},n.prototype.withChildren=function(){var r=new Set,h,a;if(r.add(this),this.child!=null)for(var p=this.child.getNodes(),v=0;v<p.length;v++)h=p[v],a=h.withChildren(),a.forEach(function(D){r.add(D)});return r},n.prototype.getNoOfChildren=function(){var r=0,h;if(this.child==null)r=1;else for(var a=this.child.getNodes(),p=0;p<a.length;p++)h=a[p],r+=h.getNoOfChildren();return r==0&&(r=1),r},n.prototype.getEstimatedSize=function(){if(this.estimatedSize==e.MIN_VALUE)throw"assert failed";return this.estimatedSize},n.prototype.calcEstimatedSize=function(){return this.child==null?this.estimatedSize=(this.rect.width+this.rect.height)/2:(this.estimatedSize=this.child.calcEstimatedSize(),this.rect.width=this.estimatedSize,this.rect.height=this.estimatedSize,this.estimatedSize)},n.prototype.scatter=function(){var r,h,a=-i.INITIAL_WORLD_BOUNDARY,p=i.INITIAL_WORLD_BOUNDARY;r=i.WORLD_CENTER_X+l.nextDouble()*(p-a)+a;var v=-i.INITIAL_WORLD_BOUNDARY,D=i.INITIAL_WORLD_BOUNDARY;h=i.WORLD_CENTER_Y+l.nextDouble()*(D-v)+v,this.rect.x=r,this.rect.y=h},n.prototype.updateBounds=function(){if(this.getChild()==null)throw"assert failed";if(this.getChild().getNodes().length!=0){var r=this.getChild();if(r.updateBounds(!0),this.rect.x=r.getLeft(),this.rect.y=r.getTop(),this.setWidth(r.getRight()-r.getLeft()),this.setHeight(r.getBottom()-r.getTop()),i.NODE_DIMENSIONS_INCLUDE_LABELS){var h=r.getRight()-r.getLeft(),a=r.getBottom()-r.getTop();this.labelWidth>h&&(this.rect.x-=(this.labelWidth-h)/2,this.setWidth(this.labelWidth)),this.labelHeight>a&&(this.labelPos=="center"?this.rect.y-=(this.labelHeight-a)/2:this.labelPos=="top"&&(this.rect.y-=this.labelHeight-a),this.setHeight(this.labelHeight))}}},n.prototype.getInclusionTreeDepth=function(){if(this.inclusionTreeDepth==e.MAX_VALUE)throw"assert failed";return this.inclusionTreeDepth},n.prototype.transform=function(r){var h=this.rect.x;h>i.WORLD_BOUNDARY?h=i.WORLD_BOUNDARY:h<-i.WORLD_BOUNDARY&&(h=-i.WORLD_BOUNDARY);var a=this.rect.y;a>i.WORLD_BOUNDARY?a=i.WORLD_BOUNDARY:a<-i.WORLD_BOUNDARY&&(a=-i.WORLD_BOUNDARY);var p=new g(h,a),v=r.inverseTransformPoint(p);this.setLocation(v.x,v.y)},n.prototype.getLeft=function(){return this.rect.x},n.prototype.getRight=function(){return this.rect.x+this.rect.width},n.prototype.getTop=function(){return this.rect.y},n.prototype.getBottom=function(){return this.rect.y+this.rect.height},n.prototype.getParent=function(){return this.owner==null?null:this.owner.getParent()},N.exports=n}),(function(N,I,L){function o(e,t){e==null&&t==null?(this.x=0,this.y=0):(this.x=e,this.y=t)}o.prototype.getX=function(){return this.x},o.prototype.getY=function(){return this.y},o.prototype.setX=function(e){this.x=e},o.prototype.setY=function(e){this.y=e},o.prototype.getDifference=function(e){return new DimensionD(this.x-e.x,this.y-e.y)},o.prototype.getCopy=function(){return new o(this.x,this.y)},o.prototype.translate=function(e){return this.x+=e.width,this.y+=e.height,this},N.exports=o}),(function(N,I,L){var o=L(2),e=L(10),t=L(0),i=L(6),l=L(3),g=L(1),n=L(13),d=L(12),r=L(11);function h(p,v,D){o.call(this,D),this.estimatedSize=e.MIN_VALUE,this.margin=t.DEFAULT_GRAPH_MARGIN,this.edges=[],this.nodes=[],this.isConnected=!1,this.parent=p,v!=null&&v instanceof i?this.graphManager=v:v!=null&&v instanceof Layout&&(this.graphManager=v.graphManager)}h.prototype=Object.create(o.prototype);for(var a in o)h[a]=o[a];h.prototype.getNodes=function(){return this.nodes},h.prototype.getEdges=function(){return this.edges},h.prototype.getGraphManager=function(){return this.graphManager},h.prototype.getParent=function(){return this.parent},h.prototype.getLeft=function(){return this.left},h.prototype.getRight=function(){return this.right},h.prototype.getTop=function(){return this.top},h.prototype.getBottom=function(){return this.bottom},h.prototype.isConnected=function(){return this.isConnected},h.prototype.add=function(p,v,D){if(v==null&&D==null){var u=p;if(this.graphManager==null)throw"Graph has no graph mgr!";if(this.getNodes().indexOf(u)>-1)throw"Node already in graph!";return u.owner=this,this.getNodes().push(u),u}else{var T=p;if(!(this.getNodes().indexOf(v)>-1&&this.getNodes().indexOf(D)>-1))throw"Source or target not in graph!";if(!(v.owner==D.owner&&v.owner==this))throw"Both owners must be this graph!";return v.owner!=D.owner?null:(T.source=v,T.target=D,T.isInterGraph=!1,this.getEdges().push(T),v.edges.push(T),D!=v&&D.edges.push(T),T)}},h.prototype.remove=function(p){var v=p;if(p instanceof l){if(v==null)throw"Node is null!";if(!(v.owner!=null&&v.owner==this))throw"Owner graph is invalid!";if(this.graphManager==null)throw"Owner graph manager is invalid!";for(var D=v.edges.slice(),u,T=D.length,y=0;y<T;y++)u=D[y],u.isInterGraph?this.graphManager.remove(u):u.source.owner.remove(u);var O=this.nodes.indexOf(v);if(O==-1)throw"Node not in owner node list!";this.nodes.splice(O,1)}else if(p instanceof g){var u=p;if(u==null)throw"Edge is null!";if(!(u.source!=null&&u.target!=null))throw"Source and/or target is null!";if(!(u.source.owner!=null&&u.target.owner!=null&&u.source.owner==this&&u.target.owner==this))throw"Source and/or target owner is invalid!";var s=u.source.edges.indexOf(u),f=u.target.edges.indexOf(u);if(!(s>-1&&f>-1))throw"Source and/or target doesn't know this edge!";u.source.edges.splice(s,1),u.target!=u.source&&u.target.edges.splice(f,1);var O=u.source.owner.getEdges().indexOf(u);if(O==-1)throw"Not in owner's edge list!";u.source.owner.getEdges().splice(O,1)}},h.prototype.updateLeftTop=function(){for(var p=e.MAX_VALUE,v=e.MAX_VALUE,D,u,T,y=this.getNodes(),O=y.length,s=0;s<O;s++){var f=y[s];D=f.getTop(),u=f.getLeft(),p>D&&(p=D),v>u&&(v=u)}return p==e.MAX_VALUE?null:(y[0].getParent().paddingLeft!=null?T=y[0].getParent().paddingLeft:T=this.margin,this.left=v-T,this.top=p-T,new d(this.left,this.top))},h.prototype.updateBounds=function(p){for(var v=e.MAX_VALUE,D=-e.MAX_VALUE,u=e.MAX_VALUE,T=-e.MAX_VALUE,y,O,s,f,c,E=this.nodes,A=E.length,m=0;m<A;m++){var C=E[m];p&&C.child!=null&&C.updateBounds(),y=C.getLeft(),O=C.getRight(),s=C.getTop(),f=C.getBottom(),v>y&&(v=y),D<O&&(D=O),u>s&&(u=s),T<f&&(T=f)}var R=new n(v,u,D-v,T-u);v==e.MAX_VALUE&&(this.left=this.parent.getLeft(),this.right=this.parent.getRight(),this.top=this.parent.getTop(),this.bottom=this.parent.getBottom()),E[0].getParent().paddingLeft!=null?c=E[0].getParent().paddingLeft:c=this.margin,this.left=R.x-c,this.right=R.x+R.width+c,this.top=R.y-c,this.bottom=R.y+R.height+c},h.calculateBounds=function(p){for(var v=e.MAX_VALUE,D=-e.MAX_VALUE,u=e.MAX_VALUE,T=-e.MAX_VALUE,y,O,s,f,c=p.length,E=0;E<c;E++){var A=p[E];y=A.getLeft(),O=A.getRight(),s=A.getTop(),f=A.getBottom(),v>y&&(v=y),D<O&&(D=O),u>s&&(u=s),T<f&&(T=f)}var m=new n(v,u,D-v,T-u);return m},h.prototype.getInclusionTreeDepth=function(){return this==this.graphManager.getRoot()?1:this.parent.getInclusionTreeDepth()},h.prototype.getEstimatedSize=function(){if(this.estimatedSize==e.MIN_VALUE)throw"assert failed";return this.estimatedSize},h.prototype.calcEstimatedSize=function(){for(var p=0,v=this.nodes,D=v.length,u=0;u<D;u++){var T=v[u];p+=T.calcEstimatedSize()}return p==0?this.estimatedSize=t.EMPTY_COMPOUND_NODE_SIZE:this.estimatedSize=p/Math.sqrt(this.nodes.length),this.estimatedSize},h.prototype.updateConnected=function(){var p=this;if(this.nodes.length==0){this.isConnected=!0;return}var v=new r,D=new Set,u=this.nodes[0],T,y,O=u.withChildren();for(O.forEach(function(m){v.push(m),D.add(m)});v.length!==0;){u=v.shift(),T=u.getEdges();for(var s=T.length,f=0;f<s;f++){var c=T[f];if(y=c.getOtherEndInGraph(u,this),y!=null&&!D.has(y)){var E=y.withChildren();E.forEach(function(m){v.push(m),D.add(m)})}}}if(this.isConnected=!1,D.size>=this.nodes.length){var A=0;D.forEach(function(m){m.owner==p&&A++}),A==this.nodes.length&&(this.isConnected=!0)}},N.exports=h}),(function(N,I,L){var o,e=L(1);function t(i){o=L(5),this.layout=i,this.graphs=[],this.edges=[]}t.prototype.addRoot=function(){var i=this.layout.newGraph(),l=this.layout.newNode(null),g=this.add(i,l);return this.setRootGraph(g),this.rootGraph},t.prototype.add=function(i,l,g,n,d){if(g==null&&n==null&&d==null){if(i==null)throw"Graph is null!";if(l==null)throw"Parent node is null!";if(this.graphs.indexOf(i)>-1)throw"Graph already in this graph mgr!";if(this.graphs.push(i),i.parent!=null)throw"Already has a parent!";if(l.child!=null)throw"Already has a child!";return i.parent=l,l.child=i,i}else{d=g,n=l,g=i;var r=n.getOwner(),h=d.getOwner();if(!(r!=null&&r.getGraphManager()==this))throw"Source not in this graph mgr!";if(!(h!=null&&h.getGraphManager()==this))throw"Target not in this graph mgr!";if(r==h)return g.isInterGraph=!1,r.add(g,n,d);if(g.isInterGraph=!0,g.source=n,g.target=d,this.edges.indexOf(g)>-1)throw"Edge already in inter-graph edge list!";if(this.edges.push(g),!(g.source!=null&&g.target!=null))throw"Edge source and/or target is null!";if(!(g.source.edges.indexOf(g)==-1&&g.target.edges.indexOf(g)==-1))throw"Edge already in source and/or target incidency list!";return g.source.edges.push(g),g.target.edges.push(g),g}},t.prototype.remove=function(i){if(i instanceof o){var l=i;if(l.getGraphManager()!=this)throw"Graph not in this graph mgr";if(!(l==this.rootGraph||l.parent!=null&&l.parent.graphManager==this))throw"Invalid parent node!";var g=[];g=g.concat(l.getEdges());for(var n,d=g.length,r=0;r<d;r++)n=g[r],l.remove(n);var h=[];h=h.concat(l.getNodes());var a;d=h.length;for(var r=0;r<d;r++)a=h[r],l.remove(a);l==this.rootGraph&&this.setRootGraph(null);var p=this.graphs.indexOf(l);this.graphs.splice(p,1),l.parent=null}else if(i instanceof e){if(n=i,n==null)throw"Edge is null!";if(!n.isInterGraph)throw"Not an inter-graph edge!";if(!(n.source!=null&&n.target!=null))throw"Source and/or target is null!";if(!(n.source.edges.indexOf(n)!=-1&&n.target.edges.indexOf(n)!=-1))throw"Source and/or target doesn't know this edge!";var p=n.source.edges.indexOf(n);if(n.source.edges.splice(p,1),p=n.target.edges.indexOf(n),n.target.edges.splice(p,1),!(n.source.owner!=null&&n.source.owner.getGraphManager()!=null))throw"Edge owner graph or owner graph manager is null!";if(n.source.owner.getGraphManager().edges.indexOf(n)==-1)throw"Not in owner graph manager's edge list!";var p=n.source.owner.getGraphManager().edges.indexOf(n);n.source.owner.getGraphManager().edges.splice(p,1)}},t.prototype.updateBounds=function(){this.rootGraph.updateBounds(!0)},t.prototype.getGraphs=function(){return this.graphs},t.prototype.getAllNodes=function(){if(this.allNodes==null){for(var i=[],l=this.getGraphs(),g=l.length,n=0;n<g;n++)i=i.concat(l[n].getNodes());this.allNodes=i}return this.allNodes},t.prototype.resetAllNodes=function(){this.allNodes=null},t.prototype.resetAllEdges=function(){this.allEdges=null},t.prototype.resetAllNodesToApplyGravitation=function(){this.allNodesToApplyGravitation=null},t.prototype.getAllEdges=function(){if(this.allEdges==null){var i=[],l=this.getGraphs();l.length;for(var g=0;g<l.length;g++)i=i.concat(l[g].getEdges());i=i.concat(this.edges),this.allEdges=i}return this.allEdges},t.prototype.getAllNodesToApplyGravitation=function(){return this.allNodesToApplyGravitation},t.prototype.setAllNodesToApplyGravitation=function(i){if(this.allNodesToApplyGravitation!=null)throw"assert failed";this.allNodesToApplyGravitation=i},t.prototype.getRoot=function(){return this.rootGraph},t.prototype.setRootGraph=function(i){if(i.getGraphManager()!=this)throw"Root not in this graph mgr!";this.rootGraph=i,i.parent==null&&(i.parent=this.layout.newNode("Root node"))},t.prototype.getLayout=function(){return this.layout},t.prototype.isOneAncestorOfOther=function(i,l){if(!(i!=null&&l!=null))throw"assert failed";if(i==l)return!0;var g=i.getOwner(),n;do{if(n=g.getParent(),n==null)break;if(n==l)return!0;if(g=n.getOwner(),g==null)break}while(!0);g=l.getOwner();do{if(n=g.getParent(),n==null)break;if(n==i)return!0;if(g=n.getOwner(),g==null)break}while(!0);return!1},t.prototype.calcLowestCommonAncestors=function(){for(var i,l,g,n,d,r=this.getAllEdges(),h=r.length,a=0;a<h;a++){if(i=r[a],l=i.source,g=i.target,i.lca=null,i.sourceInLca=l,i.targetInLca=g,l==g){i.lca=l.getOwner();continue}for(n=l.getOwner();i.lca==null;){for(i.targetInLca=g,d=g.getOwner();i.lca==null;){if(d==n){i.lca=d;break}if(d==this.rootGraph)break;if(i.lca!=null)throw"assert failed";i.targetInLca=d.getParent(),d=i.targetInLca.getOwner()}if(n==this.rootGraph)break;i.lca==null&&(i.sourceInLca=n.getParent(),n=i.sourceInLca.getOwner())}if(i.lca==null)throw"assert failed"}},t.prototype.calcLowestCommonAncestor=function(i,l){if(i==l)return i.getOwner();var g=i.getOwner();do{if(g==null)break;var n=l.getOwner();do{if(n==null)break;if(n==g)return n;n=n.getParent().getOwner()}while(!0);g=g.getParent().getOwner()}while(!0);return g},t.prototype.calcInclusionTreeDepths=function(i,l){i==null&&l==null&&(i=this.rootGraph,l=1);for(var g,n=i.getNodes(),d=n.length,r=0;r<d;r++)g=n[r],g.inclusionTreeDepth=l,g.child!=null&&this.calcInclusionTreeDepths(g.child,l+1)},t.prototype.includesInvalidEdge=function(){for(var i,l=this.edges.length,g=0;g<l;g++)if(i=this.edges[g],this.isOneAncestorOfOther(i.source,i.target))return!0;return!1},N.exports=t}),(function(N,I,L){var o=L(0);function e(){}for(var t in o)e[t]=o[t];e.MAX_ITERATIONS=2500,e.DEFAULT_EDGE_LENGTH=50,e.DEFAULT_SPRING_STRENGTH=.45,e.DEFAULT_REPULSION_STRENGTH=4500,e.DEFAULT_GRAVITY_STRENGTH=.4,e.DEFAULT_COMPOUND_GRAVITY_STRENGTH=1,e.DEFAULT_GRAVITY_RANGE_FACTOR=3.8,e.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=1.5,e.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION=!0,e.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION=!0,e.DEFAULT_COOLING_FACTOR_INCREMENTAL=.3,e.COOLING_ADAPTATION_FACTOR=.33,e.ADAPTATION_LOWER_NODE_LIMIT=1e3,e.ADAPTATION_UPPER_NODE_LIMIT=5e3,e.MAX_NODE_DISPLACEMENT_INCREMENTAL=100,e.MAX_NODE_DISPLACEMENT=e.MAX_NODE_DISPLACEMENT_INCREMENTAL*3,e.MIN_REPULSION_DIST=e.DEFAULT_EDGE_LENGTH/10,e.CONVERGENCE_CHECK_PERIOD=100,e.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=.1,e.MIN_EDGE_LENGTH=1,e.GRID_CALCULATION_CHECK_PERIOD=10,N.exports=e}),(function(N,I,L){var o=L(12);function e(){}e.calcSeparationAmount=function(t,i,l,g){if(!t.intersects(i))throw"assert failed";var n=new Array(2);this.decideDirectionsForOverlappingNodes(t,i,n),l[0]=Math.min(t.getRight(),i.getRight())-Math.max(t.x,i.x),l[1]=Math.min(t.getBottom(),i.getBottom())-Math.max(t.y,i.y),t.getX()<=i.getX()&&t.getRight()>=i.getRight()?l[0]+=Math.min(i.getX()-t.getX(),t.getRight()-i.getRight()):i.getX()<=t.getX()&&i.getRight()>=t.getRight()&&(l[0]+=Math.min(t.getX()-i.getX(),i.getRight()-t.getRight())),t.getY()<=i.getY()&&t.getBottom()>=i.getBottom()?l[1]+=Math.min(i.getY()-t.getY(),t.getBottom()-i.getBottom()):i.getY()<=t.getY()&&i.getBottom()>=t.getBottom()&&(l[1]+=Math.min(t.getY()-i.getY(),i.getBottom()-t.getBottom()));var d=Math.abs((i.getCenterY()-t.getCenterY())/(i.getCenterX()-t.getCenterX()));i.getCenterY()===t.getCenterY()&&i.getCenterX()===t.getCenterX()&&(d=1);var r=d*l[0],h=l[1]/d;l[0]<h?h=l[0]:r=l[1],l[0]=-1*n[0]*(h/2+g),l[1]=-1*n[1]*(r/2+g)},e.decideDirectionsForOverlappingNodes=function(t,i,l){t.getCenterX()<i.getCenterX()?l[0]=-1:l[0]=1,t.getCenterY()<i.getCenterY()?l[1]=-1:l[1]=1},e.getIntersection2=function(t,i,l){var g=t.getCenterX(),n=t.getCenterY(),d=i.getCenterX(),r=i.getCenterY();if(t.intersects(i))return l[0]=g,l[1]=n,l[2]=d,l[3]=r,!0;var h=t.getX(),a=t.getY(),p=t.getRight(),v=t.getX(),D=t.getBottom(),u=t.getRight(),T=t.getWidthHalf(),y=t.getHeightHalf(),O=i.getX(),s=i.getY(),f=i.getRight(),c=i.getX(),E=i.getBottom(),A=i.getRight(),m=i.getWidthHalf(),C=i.getHeightHalf(),R=!1,M=!1;if(g===d){if(n>r)return l[0]=g,l[1]=a,l[2]=d,l[3]=E,!1;if(n<r)return l[0]=g,l[1]=D,l[2]=d,l[3]=s,!1}else if(n===r){if(g>d)return l[0]=h,l[1]=n,l[2]=f,l[3]=r,!1;if(g<d)return l[0]=p,l[1]=n,l[2]=O,l[3]=r,!1}else{var S=t.height/t.width,Y=i.height/i.width,w=(r-n)/(d-g),x=void 0,F=void 0,U=void 0,P=void 0,_=void 0,X=void 0;if(-S===w?g>d?(l[0]=v,l[1]=D,R=!0):(l[0]=p,l[1]=a,R=!0):S===w&&(g>d?(l[0]=h,l[1]=a,R=!0):(l[0]=u,l[1]=D,R=!0)),-Y===w?d>g?(l[2]=c,l[3]=E,M=!0):(l[2]=f,l[3]=s,M=!0):Y===w&&(d>g?(l[2]=O,l[3]=s,M=!0):(l[2]=A,l[3]=E,M=!0)),R&&M)return!1;if(g>d?n>r?(x=this.getCardinalDirection(S,w,4),F=this.getCardinalDirection(Y,w,2)):(x=this.getCardinalDirection(-S,w,3),F=this.getCardinalDirection(-Y,w,1)):n>r?(x=this.getCardinalDirection(-S,w,1),F=this.getCardinalDirection(-Y,w,3)):(x=this.getCardinalDirection(S,w,2),F=this.getCardinalDirection(Y,w,4)),!R)switch(x){case 1:P=a,U=g+-y/w,l[0]=U,l[1]=P;break;case 2:U=u,P=n+T*w,l[0]=U,l[1]=P;break;case 3:P=D,U=g+y/w,l[0]=U,l[1]=P;break;case 4:U=v,P=n+-T*w,l[0]=U,l[1]=P;break}if(!M)switch(F){case 1:X=s,_=d+-C/w,l[2]=_,l[3]=X;break;case 2:_=A,X=r+m*w,l[2]=_,l[3]=X;break;case 3:X=E,_=d+C/w,l[2]=_,l[3]=X;break;case 4:_=c,X=r+-m*w,l[2]=_,l[3]=X;break}}return!1},e.getCardinalDirection=function(t,i,l){return t>i?l:1+l%4},e.getIntersection=function(t,i,l,g){if(g==null)return this.getIntersection2(t,i,l);var n=t.x,d=t.y,r=i.x,h=i.y,a=l.x,p=l.y,v=g.x,D=g.y,u=void 0,T=void 0,y=void 0,O=void 0,s=void 0,f=void 0,c=void 0,E=void 0,A=void 0;return y=h-d,s=n-r,c=r*d-n*h,O=D-p,f=a-v,E=v*p-a*D,A=y*f-O*s,A===0?null:(u=(s*E-f*c)/A,T=(O*c-y*E)/A,new o(u,T))},e.angleOfVector=function(t,i,l,g){var n=void 0;return t!==l?(n=Math.atan((g-i)/(l-t)),l<t?n+=Math.PI:g<i&&(n+=this.TWO_PI)):g<i?n=this.ONE_AND_HALF_PI:n=this.HALF_PI,n},e.doIntersect=function(t,i,l,g){var n=t.x,d=t.y,r=i.x,h=i.y,a=l.x,p=l.y,v=g.x,D=g.y,u=(r-n)*(D-p)-(v-a)*(h-d);if(u===0)return!1;var T=((D-p)*(v-n)+(a-v)*(D-d))/u,y=((d-h)*(v-n)+(r-n)*(D-d))/u;return 0<T&&T<1&&0<y&&y<1},e.HALF_PI=.5*Math.PI,e.ONE_AND_HALF_PI=1.5*Math.PI,e.TWO_PI=2*Math.PI,e.THREE_PI=3*Math.PI,N.exports=e}),(function(N,I,L){function o(){}o.sign=function(e){return e>0?1:e<0?-1:0},o.floor=function(e){return e<0?Math.ceil(e):Math.floor(e)},o.ceil=function(e){return e<0?Math.floor(e):Math.ceil(e)},N.exports=o}),(function(N,I,L){function o(){}o.MAX_VALUE=2147483647,o.MIN_VALUE=-2147483648,N.exports=o}),(function(N,I,L){var o=(function(){function n(d,r){for(var h=0;h<r.length;h++){var a=r[h];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(d,a.key,a)}}return function(d,r,h){return r&&n(d.prototype,r),h&&n(d,h),d}})();function e(n,d){if(!(n instanceof d))throw new TypeError("Cannot call a class as a function")}var t=function(d){return{value:d,next:null,prev:null}},i=function(d,r,h,a){return d!==null?d.next=r:a.head=r,h!==null?h.prev=r:a.tail=r,r.prev=d,r.next=h,a.length++,r},l=function(d,r){var h=d.prev,a=d.next;return h!==null?h.next=a:r.head=a,a!==null?a.prev=h:r.tail=h,d.prev=d.next=null,r.length--,d},g=(function(){function n(d){var r=this;e(this,n),this.length=0,this.head=null,this.tail=null,d?.forEach(function(h){return r.push(h)})}return o(n,[{key:"size",value:function(){return this.length}},{key:"insertBefore",value:function(r,h){return i(h.prev,t(r),h,this)}},{key:"insertAfter",value:function(r,h){return i(h,t(r),h.next,this)}},{key:"insertNodeBefore",value:function(r,h){return i(h.prev,r,h,this)}},{key:"insertNodeAfter",value:function(r,h){return i(h,r,h.next,this)}},{key:"push",value:function(r){return i(this.tail,t(r),null,this)}},{key:"unshift",value:function(r){return i(null,t(r),this.head,this)}},{key:"remove",value:function(r){return l(r,this)}},{key:"pop",value:function(){return l(this.tail,this).value}},{key:"popNode",value:function(){return l(this.tail,this)}},{key:"shift",value:function(){return l(this.head,this).value}},{key:"shiftNode",value:function(){return l(this.head,this)}},{key:"get_object_at",value:function(r){if(r<=this.length()){for(var h=1,a=this.head;h<r;)a=a.next,h++;return a.value}}},{key:"set_object_at",value:function(r,h){if(r<=this.length()){for(var a=1,p=this.head;a<r;)p=p.next,a++;p.value=h}}}]),n})();N.exports=g}),(function(N,I,L){function o(e,t,i){this.x=null,this.y=null,e==null&&t==null&&i==null?(this.x=0,this.y=0):typeof e=="number"&&typeof t=="number"&&i==null?(this.x=e,this.y=t):e.constructor.name=="Point"&&t==null&&i==null&&(i=e,this.x=i.x,this.y=i.y)}o.prototype.getX=function(){return this.x},o.prototype.getY=function(){return this.y},o.prototype.getLocation=function(){return new o(this.x,this.y)},o.prototype.setLocation=function(e,t,i){e.constructor.name=="Point"&&t==null&&i==null?(i=e,this.setLocation(i.x,i.y)):typeof e=="number"&&typeof t=="number"&&i==null&&(parseInt(e)==e&&parseInt(t)==t?this.move(e,t):(this.x=Math.floor(e+.5),this.y=Math.floor(t+.5)))},o.prototype.move=function(e,t){this.x=e,this.y=t},o.prototype.translate=function(e,t){this.x+=e,this.y+=t},o.prototype.equals=function(e){if(e.constructor.name=="Point"){var t=e;return this.x==t.x&&this.y==t.y}return this==e},o.prototype.toString=function(){return new o().constructor.name+"[x="+this.x+",y="+this.y+"]"},N.exports=o}),(function(N,I,L){function o(e,t,i,l){this.x=0,this.y=0,this.width=0,this.height=0,e!=null&&t!=null&&i!=null&&l!=null&&(this.x=e,this.y=t,this.width=i,this.height=l)}o.prototype.getX=function(){return this.x},o.prototype.setX=function(e){this.x=e},o.prototype.getY=function(){return this.y},o.prototype.setY=function(e){this.y=e},o.prototype.getWidth=function(){return this.width},o.prototype.setWidth=function(e){this.width=e},o.prototype.getHeight=function(){return this.height},o.prototype.setHeight=function(e){this.height=e},o.prototype.getRight=function(){return this.x+this.width},o.prototype.getBottom=function(){return this.y+this.height},o.prototype.intersects=function(e){return!(this.getRight()<e.x||this.getBottom()<e.y||e.getRight()<this.x||e.getBottom()<this.y)},o.prototype.getCenterX=function(){return this.x+this.width/2},o.prototype.getMinX=function(){return this.getX()},o.prototype.getMaxX=function(){return this.getX()+this.width},o.prototype.getCenterY=function(){return this.y+this.height/2},o.prototype.getMinY=function(){return this.getY()},o.prototype.getMaxY=function(){return this.getY()+this.height},o.prototype.getWidthHalf=function(){return this.width/2},o.prototype.getHeightHalf=function(){return this.height/2},N.exports=o}),(function(N,I,L){var o=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(t){return typeof t}:function(t){return t&&typeof Symbol=="function"&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};function e(){}e.lastID=0,e.createID=function(t){return e.isPrimitive(t)?t:(t.uniqueID!=null||(t.uniqueID=e.getString(),e.lastID++),t.uniqueID)},e.getString=function(t){return t==null&&(t=e.lastID),"Object#"+t},e.isPrimitive=function(t){var i=typeof t>"u"?"undefined":o(t);return t==null||i!="object"&&i!="function"},N.exports=e}),(function(N,I,L){function o(a){if(Array.isArray(a)){for(var p=0,v=Array(a.length);p<a.length;p++)v[p]=a[p];return v}else return Array.from(a)}var e=L(0),t=L(6),i=L(3),l=L(1),g=L(5),n=L(4),d=L(17),r=L(27);function h(a){r.call(this),this.layoutQuality=e.QUALITY,this.createBendsAsNeeded=e.DEFAULT_CREATE_BENDS_AS_NEEDED,this.incremental=e.DEFAULT_INCREMENTAL,this.animationOnLayout=e.DEFAULT_ANIMATION_ON_LAYOUT,this.animationDuringLayout=e.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=e.DEFAULT_ANIMATION_PERIOD,this.uniformLeafNodeSizes=e.DEFAULT_UNIFORM_LEAF_NODE_SIZES,this.edgeToDummyNodes=new Map,this.graphManager=new t(this),this.isLayoutFinished=!1,this.isSubLayout=!1,this.isRemoteUse=!1,a!=null&&(this.isRemoteUse=a)}h.RANDOM_SEED=1,h.prototype=Object.create(r.prototype),h.prototype.getGraphManager=function(){return this.graphManager},h.prototype.getAllNodes=function(){return this.graphManager.getAllNodes()},h.prototype.getAllEdges=function(){return this.graphManager.getAllEdges()},h.prototype.getAllNodesToApplyGravitation=function(){return this.graphManager.getAllNodesToApplyGravitation()},h.prototype.newGraphManager=function(){var a=new t(this);return this.graphManager=a,a},h.prototype.newGraph=function(a){return new g(null,this.graphManager,a)},h.prototype.newNode=function(a){return new i(this.graphManager,a)},h.prototype.newEdge=function(a){return new l(null,null,a)},h.prototype.checkLayoutSuccess=function(){return this.graphManager.getRoot()==null||this.graphManager.getRoot().getNodes().length==0||this.graphManager.includesInvalidEdge()},h.prototype.runLayout=function(){this.isLayoutFinished=!1,this.tilingPreLayout&&this.tilingPreLayout(),this.initParameters();var a;return this.checkLayoutSuccess()?a=!1:a=this.layout(),e.ANIMATE==="during"?!1:(a&&(this.isSubLayout||this.doPostLayout()),this.tilingPostLayout&&this.tilingPostLayout(),this.isLayoutFinished=!0,a)},h.prototype.doPostLayout=function(){this.incremental||this.transform(),this.update()},h.prototype.update2=function(){if(this.createBendsAsNeeded&&(this.createBendpointsFromDummyNodes(),this.graphManager.resetAllEdges()),!this.isRemoteUse){for(var a=this.graphManager.getAllEdges(),p=0;p<a.length;p++)a[p];for(var v=this.graphManager.getRoot().getNodes(),p=0;p<v.length;p++)v[p];this.update(this.graphManager.getRoot())}},h.prototype.update=function(a){if(a==null)this.update2();else if(a instanceof i){var p=a;if(p.getChild()!=null)for(var v=p.getChild().getNodes(),D=0;D<v.length;D++)update(v[D]);if(p.vGraphObject!=null){var u=p.vGraphObject;u.update(p)}}else if(a instanceof l){var T=a;if(T.vGraphObject!=null){var y=T.vGraphObject;y.update(T)}}else if(a instanceof g){var O=a;if(O.vGraphObject!=null){var s=O.vGraphObject;s.update(O)}}},h.prototype.initParameters=function(){this.isSubLayout||(this.layoutQuality=e.QUALITY,this.animationDuringLayout=e.DEFAULT_ANIMATION_DURING_LAYOUT,this.animationPeriod=e.DEFAULT_ANIMATION_PERIOD,this.animationOnLayout=e.DEFAULT_ANIMATION_ON_LAYOUT,this.incremental=e.DEFAULT_INCREMENTAL,this.createBendsAsNeeded=e.DEFAULT_CREATE_BENDS_AS_NEEDED,this.uniformLeafNodeSizes=e.DEFAULT_UNIFORM_LEAF_NODE_SIZES),this.animationDuringLayout&&(this.animationOnLayout=!1)},h.prototype.transform=function(a){if(a==null)this.transform(new n(0,0));else{var p=new d,v=this.graphManager.getRoot().updateLeftTop();if(v!=null){p.setWorldOrgX(a.x),p.setWorldOrgY(a.y),p.setDeviceOrgX(v.x),p.setDeviceOrgY(v.y);for(var D=this.getAllNodes(),u,T=0;T<D.length;T++)u=D[T],u.transform(p)}}},h.prototype.positionNodesRandomly=function(a){if(a==null)this.positionNodesRandomly(this.getGraphManager().getRoot()),this.getGraphManager().getRoot().updateBounds(!0);else for(var p,v,D=a.getNodes(),u=0;u<D.length;u++)p=D[u],v=p.getChild(),v==null||v.getNodes().length==0?p.scatter():(this.positionNodesRandomly(v),p.updateBounds())},h.prototype.getFlatForest=function(){for(var a=[],p=!0,v=this.graphManager.getRoot().getNodes(),D=!0,u=0;u<v.length;u++)v[u].getChild()!=null&&(D=!1);if(!D)return a;var T=new Set,y=[],O=new Map,s=[];for(s=s.concat(v);s.length>0&&p;){for(y.push(s[0]);y.length>0&&p;){var f=y[0];y.splice(0,1),T.add(f);for(var c=f.getEdges(),u=0;u<c.length;u++){var E=c[u].getOtherEnd(f);if(O.get(f)!=E)if(!T.has(E))y.push(E),O.set(E,f);else{p=!1;break}}}if(!p)a=[];else{var A=[].concat(o(T));a.push(A);for(var u=0;u<A.length;u++){var m=A[u],C=s.indexOf(m);C>-1&&s.splice(C,1)}T=new Set,O=new Map}}return a},h.prototype.createDummyNodesForBendpoints=function(a){for(var p=[],v=a.source,D=this.graphManager.calcLowestCommonAncestor(a.source,a.target),u=0;u<a.bendpoints.length;u++){var T=this.newNode(null);T.setRect(new Point(0,0),new Dimension(1,1)),D.add(T);var y=this.newEdge(null);this.graphManager.add(y,v,T),p.add(T),v=T}var y=this.newEdge(null);return this.graphManager.add(y,v,a.target),this.edgeToDummyNodes.set(a,p),a.isInterGraph()?this.graphManager.remove(a):D.remove(a),p},h.prototype.createBendpointsFromDummyNodes=function(){var a=[];a=a.concat(this.graphManager.getAllEdges()),a=[].concat(o(this.edgeToDummyNodes.keys())).concat(a);for(var p=0;p<a.length;p++){var v=a[p];if(v.bendpoints.length>0){for(var D=this.edgeToDummyNodes.get(v),u=0;u<D.length;u++){var T=D[u],y=new n(T.getCenterX(),T.getCenterY()),O=v.bendpoints.get(u);O.x=y.x,O.y=y.y,T.getOwner().remove(T)}this.graphManager.add(v,v.source,v.target)}}},h.transform=function(a,p,v,D){if(v!=null&&D!=null){var u=p;if(a<=50){var T=p/v;u-=(p-T)/50*(50-a)}else{var y=p*D;u+=(y-p)/50*(a-50)}return u}else{var O,s;return a<=50?(O=9*p/500,s=p/10):(O=9*p/50,s=-8*p),O*a+s}},h.findCenterOfTree=function(a){var p=[];p=p.concat(a);var v=[],D=new Map,u=!1,T=null;(p.length==1||p.length==2)&&(u=!0,T=p[0]);for(var y=0;y<p.length;y++){var O=p[y],s=O.getNeighborsList().size;D.set(O,O.getNeighborsList().size),s==1&&v.push(O)}var f=[];for(f=f.concat(v);!u;){var c=[];c=c.concat(f),f=[];for(var y=0;y<p.length;y++){var O=p[y],E=p.indexOf(O);E>=0&&p.splice(E,1);var A=O.getNeighborsList();A.forEach(function(R){if(v.indexOf(R)<0){var M=D.get(R),S=M-1;S==1&&f.push(R),D.set(R,S)}})}v=v.concat(f),(p.length==1||p.length==2)&&(u=!0,T=p[0])}return T},h.prototype.setGraphManager=function(a){this.graphManager=a},N.exports=h}),(function(N,I,L){function o(){}o.seed=1,o.x=0,o.nextDouble=function(){return o.x=Math.sin(o.seed++)*1e4,o.x-Math.floor(o.x)},N.exports=o}),(function(N,I,L){var o=L(4);function e(t,i){this.lworldOrgX=0,this.lworldOrgY=0,this.ldeviceOrgX=0,this.ldeviceOrgY=0,this.lworldExtX=1,this.lworldExtY=1,this.ldeviceExtX=1,this.ldeviceExtY=1}e.prototype.getWorldOrgX=function(){return this.lworldOrgX},e.prototype.setWorldOrgX=function(t){this.lworldOrgX=t},e.prototype.getWorldOrgY=function(){return this.lworldOrgY},e.prototype.setWorldOrgY=function(t){this.lworldOrgY=t},e.prototype.getWorldExtX=function(){return this.lworldExtX},e.prototype.setWorldExtX=function(t){this.lworldExtX=t},e.prototype.getWorldExtY=function(){return this.lworldExtY},e.prototype.setWorldExtY=function(t){this.lworldExtY=t},e.prototype.getDeviceOrgX=function(){return this.ldeviceOrgX},e.prototype.setDeviceOrgX=function(t){this.ldeviceOrgX=t},e.prototype.getDeviceOrgY=function(){return this.ldeviceOrgY},e.prototype.setDeviceOrgY=function(t){this.ldeviceOrgY=t},e.prototype.getDeviceExtX=function(){return this.ldeviceExtX},e.prototype.setDeviceExtX=function(t){this.ldeviceExtX=t},e.prototype.getDeviceExtY=function(){return this.ldeviceExtY},e.prototype.setDeviceExtY=function(t){this.ldeviceExtY=t},e.prototype.transformX=function(t){var i=0,l=this.lworldExtX;return l!=0&&(i=this.ldeviceOrgX+(t-this.lworldOrgX)*this.ldeviceExtX/l),i},e.prototype.transformY=function(t){var i=0,l=this.lworldExtY;return l!=0&&(i=this.ldeviceOrgY+(t-this.lworldOrgY)*this.ldeviceExtY/l),i},e.prototype.inverseTransformX=function(t){var i=0,l=this.ldeviceExtX;return l!=0&&(i=this.lworldOrgX+(t-this.ldeviceOrgX)*this.lworldExtX/l),i},e.prototype.inverseTransformY=function(t){var i=0,l=this.ldeviceExtY;return l!=0&&(i=this.lworldOrgY+(t-this.ldeviceOrgY)*this.lworldExtY/l),i},e.prototype.inverseTransformPoint=function(t){var i=new o(this.inverseTransformX(t.x),this.inverseTransformY(t.y));return i},N.exports=e}),(function(N,I,L){function o(r){if(Array.isArray(r)){for(var h=0,a=Array(r.length);h<r.length;h++)a[h]=r[h];return a}else return Array.from(r)}var e=L(15),t=L(7),i=L(0),l=L(8),g=L(9);function n(){e.call(this),this.useSmartIdealEdgeLengthCalculation=t.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.idealEdgeLength=t.DEFAULT_EDGE_LENGTH,this.springConstant=t.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=t.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=t.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=t.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=t.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=t.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.displacementThresholdPerNode=3*t.DEFAULT_EDGE_LENGTH/100,this.coolingFactor=t.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.initialCoolingFactor=t.DEFAULT_COOLING_FACTOR_INCREMENTAL,this.totalDisplacement=0,this.oldTotalDisplacement=0,this.maxIterations=t.MAX_ITERATIONS}n.prototype=Object.create(e.prototype);for(var d in e)n[d]=e[d];n.prototype.initParameters=function(){e.prototype.initParameters.call(this,arguments),this.totalIterations=0,this.notAnimatedIterations=0,this.useFRGridVariant=t.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION,this.grid=[]},n.prototype.calcIdealEdgeLengths=function(){for(var r,h,a,p,v,D,u=this.getGraphManager().getAllEdges(),T=0;T<u.length;T++)r=u[T],r.idealLength=this.idealEdgeLength,r.isInterGraph&&(a=r.getSource(),p=r.getTarget(),v=r.getSourceInLca().getEstimatedSize(),D=r.getTargetInLca().getEstimatedSize(),this.useSmartIdealEdgeLengthCalculation&&(r.idealLength+=v+D-2*i.SIMPLE_NODE_SIZE),h=r.getLca().getInclusionTreeDepth(),r.idealLength+=t.DEFAULT_EDGE_LENGTH*t.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR*(a.getInclusionTreeDepth()+p.getInclusionTreeDepth()-2*h))},n.prototype.initSpringEmbedder=function(){var r=this.getAllNodes().length;this.incremental?(r>t.ADAPTATION_LOWER_NODE_LIMIT&&(this.coolingFactor=Math.max(this.coolingFactor*t.COOLING_ADAPTATION_FACTOR,this.coolingFactor-(r-t.ADAPTATION_LOWER_NODE_LIMIT)/(t.ADAPTATION_UPPER_NODE_LIMIT-t.ADAPTATION_LOWER_NODE_LIMIT)*this.coolingFactor*(1-t.COOLING_ADAPTATION_FACTOR))),this.maxNodeDisplacement=t.MAX_NODE_DISPLACEMENT_INCREMENTAL):(r>t.ADAPTATION_LOWER_NODE_LIMIT?this.coolingFactor=Math.max(t.COOLING_ADAPTATION_FACTOR,1-(r-t.ADAPTATION_LOWER_NODE_LIMIT)/(t.ADAPTATION_UPPER_NODE_LIMIT-t.ADAPTATION_LOWER_NODE_LIMIT)*(1-t.COOLING_ADAPTATION_FACTOR)):this.coolingFactor=1,this.initialCoolingFactor=this.coolingFactor,this.maxNodeDisplacement=t.MAX_NODE_DISPLACEMENT),this.maxIterations=Math.max(this.getAllNodes().length*5,this.maxIterations),this.totalDisplacementThreshold=this.displacementThresholdPerNode*this.getAllNodes().length,this.repulsionRange=this.calcRepulsionRange()},n.prototype.calcSpringForces=function(){for(var r=this.getAllEdges(),h,a=0;a<r.length;a++)h=r[a],this.calcSpringForce(h,h.idealLength)},n.prototype.calcRepulsionForces=function(){var r=arguments.length>0&&arguments[0]!==void 0?arguments[0]:!0,h=arguments.length>1&&arguments[1]!==void 0?arguments[1]:!1,a,p,v,D,u=this.getAllNodes(),T;if(this.useFRGridVariant)for(this.totalIterations%t.GRID_CALCULATION_CHECK_PERIOD==1&&r&&this.updateGrid(),T=new Set,a=0;a<u.length;a++)v=u[a],this.calculateRepulsionForceOfANode(v,T,r,h),T.add(v);else for(a=0;a<u.length;a++)for(v=u[a],p=a+1;p<u.length;p++)D=u[p],v.getOwner()==D.getOwner()&&this.calcRepulsionForce(v,D)},n.prototype.calcGravitationalForces=function(){for(var r,h=this.getAllNodesToApplyGravitation(),a=0;a<h.length;a++)r=h[a],this.calcGravitationalForce(r)},n.prototype.moveNodes=function(){for(var r=this.getAllNodes(),h,a=0;a<r.length;a++)h=r[a],h.move()},n.prototype.calcSpringForce=function(r,h){var a=r.getSource(),p=r.getTarget(),v,D,u,T;if(this.uniformLeafNodeSizes&&a.getChild()==null&&p.getChild()==null)r.updateLengthSimple();else if(r.updateLength(),r.isOverlapingSourceAndTarget)return;v=r.getLength(),v!=0&&(D=this.springConstant*(v-h),u=D*(r.lengthX/v),T=D*(r.lengthY/v),a.springForceX+=u,a.springForceY+=T,p.springForceX-=u,p.springForceY-=T)},n.prototype.calcRepulsionForce=function(r,h){var a=r.getRect(),p=h.getRect(),v=new Array(2),D=new Array(4),u,T,y,O,s,f,c;if(a.intersects(p)){l.calcSeparationAmount(a,p,v,t.DEFAULT_EDGE_LENGTH/2),f=2*v[0],c=2*v[1];var E=r.noOfChildren*h.noOfChildren/(r.noOfChildren+h.noOfChildren);r.repulsionForceX-=E*f,r.repulsionForceY-=E*c,h.repulsionForceX+=E*f,h.repulsionForceY+=E*c}else this.uniformLeafNodeSizes&&r.getChild()==null&&h.getChild()==null?(u=p.getCenterX()-a.getCenterX(),T=p.getCenterY()-a.getCenterY()):(l.getIntersection(a,p,D),u=D[2]-D[0],T=D[3]-D[1]),Math.abs(u)<t.MIN_REPULSION_DIST&&(u=g.sign(u)*t.MIN_REPULSION_DIST),Math.abs(T)<t.MIN_REPULSION_DIST&&(T=g.sign(T)*t.MIN_REPULSION_DIST),y=u*u+T*T,O=Math.sqrt(y),s=this.repulsionConstant*r.noOfChildren*h.noOfChildren/y,f=s*u/O,c=s*T/O,r.repulsionForceX-=f,r.repulsionForceY-=c,h.repulsionForceX+=f,h.repulsionForceY+=c},n.prototype.calcGravitationalForce=function(r){var h,a,p,v,D,u,T,y;h=r.getOwner(),a=(h.getRight()+h.getLeft())/2,p=(h.getTop()+h.getBottom())/2,v=r.getCenterX()-a,D=r.getCenterY()-p,u=Math.abs(v)+r.getWidth()/2,T=Math.abs(D)+r.getHeight()/2,r.getOwner()==this.graphManager.getRoot()?(y=h.getEstimatedSize()*this.gravityRangeFactor,(u>y||T>y)&&(r.gravitationForceX=-this.gravityConstant*v,r.gravitationForceY=-this.gravityConstant*D)):(y=h.getEstimatedSize()*this.compoundGravityRangeFactor,(u>y||T>y)&&(r.gravitationForceX=-this.gravityConstant*v*this.compoundGravityConstant,r.gravitationForceY=-this.gravityConstant*D*this.compoundGravityConstant))},n.prototype.isConverged=function(){var r,h=!1;return this.totalIterations>this.maxIterations/3&&(h=Math.abs(this.totalDisplacement-this.oldTotalDisplacement)<2),r=this.totalDisplacement<this.totalDisplacementThreshold,this.oldTotalDisplacement=this.totalDisplacement,r||h},n.prototype.animate=function(){this.animationDuringLayout&&!this.isSubLayout&&(this.notAnimatedIterations==this.animationPeriod?(this.update(),this.notAnimatedIterations=0):this.notAnimatedIterations++)},n.prototype.calcNoOfChildrenForAllNodes=function(){for(var r,h=this.graphManager.getAllNodes(),a=0;a<h.length;a++)r=h[a],r.noOfChildren=r.getNoOfChildren()},n.prototype.calcGrid=function(r){var h=0,a=0;h=parseInt(Math.ceil((r.getRight()-r.getLeft())/this.repulsionRange)),a=parseInt(Math.ceil((r.getBottom()-r.getTop())/this.repulsionRange));for(var p=new Array(h),v=0;v<h;v++)p[v]=new Array(a);for(var v=0;v<h;v++)for(var D=0;D<a;D++)p[v][D]=new Array;return p},n.prototype.addNodeToGrid=function(r,h,a){var p=0,v=0,D=0,u=0;p=parseInt(Math.floor((r.getRect().x-h)/this.repulsionRange)),v=parseInt(Math.floor((r.getRect().width+r.getRect().x-h)/this.repulsionRange)),D=parseInt(Math.floor((r.getRect().y-a)/this.repulsionRange)),u=parseInt(Math.floor((r.getRect().height+r.getRect().y-a)/this.repulsionRange));for(var T=p;T<=v;T++)for(var y=D;y<=u;y++)this.grid[T][y].push(r),r.setGridCoordinates(p,v,D,u)},n.prototype.updateGrid=function(){var r,h,a=this.getAllNodes();for(this.grid=this.calcGrid(this.graphManager.getRoot()),r=0;r<a.length;r++)h=a[r],this.addNodeToGrid(h,this.graphManager.getRoot().getLeft(),this.graphManager.getRoot().getTop())},n.prototype.calculateRepulsionForceOfANode=function(r,h,a,p){if(this.totalIterations%t.GRID_CALCULATION_CHECK_PERIOD==1&&a||p){var v=new Set;r.surrounding=new Array;for(var D,u=this.grid,T=r.startX-1;T<r.finishX+2;T++)for(var y=r.startY-1;y<r.finishY+2;y++)if(!(T<0||y<0||T>=u.length||y>=u[0].length)){for(var O=0;O<u[T][y].length;O++)if(D=u[T][y][O],!(r.getOwner()!=D.getOwner()||r==D)&&!h.has(D)&&!v.has(D)){var s=Math.abs(r.getCenterX()-D.getCenterX())-(r.getWidth()/2+D.getWidth()/2),f=Math.abs(r.getCenterY()-D.getCenterY())-(r.getHeight()/2+D.getHeight()/2);s<=this.repulsionRange&&f<=this.repulsionRange&&v.add(D)}}r.surrounding=[].concat(o(v))}for(T=0;T<r.surrounding.length;T++)this.calcRepulsionForce(r,r.surrounding[T])},n.prototype.calcRepulsionRange=function(){return 0},N.exports=n}),(function(N,I,L){var o=L(1),e=L(7);function t(l,g,n){o.call(this,l,g,n),this.idealLength=e.DEFAULT_EDGE_LENGTH}t.prototype=Object.create(o.prototype);for(var i in o)t[i]=o[i];N.exports=t}),(function(N,I,L){var o=L(3);function e(i,l,g,n){o.call(this,i,l,g,n),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0,this.startX=0,this.finishX=0,this.startY=0,this.finishY=0,this.surrounding=[]}e.prototype=Object.create(o.prototype);for(var t in o)e[t]=o[t];e.prototype.setGridCoordinates=function(i,l,g,n){this.startX=i,this.finishX=l,this.startY=g,this.finishY=n},N.exports=e}),(function(N,I,L){function o(e,t){this.width=0,this.height=0,e!==null&&t!==null&&(this.height=t,this.width=e)}o.prototype.getWidth=function(){return this.width},o.prototype.setWidth=function(e){this.width=e},o.prototype.getHeight=function(){return this.height},o.prototype.setHeight=function(e){this.height=e},N.exports=o}),(function(N,I,L){var o=L(14);function e(){this.map={},this.keys=[]}e.prototype.put=function(t,i){var l=o.createID(t);this.contains(l)||(this.map[l]=i,this.keys.push(t))},e.prototype.contains=function(t){return o.createID(t),this.map[t]!=null},e.prototype.get=function(t){var i=o.createID(t);return this.map[i]},e.prototype.keySet=function(){return this.keys},N.exports=e}),(function(N,I,L){var o=L(14);function e(){this.set={}}e.prototype.add=function(t){var i=o.createID(t);this.contains(i)||(this.set[i]=t)},e.prototype.remove=function(t){delete this.set[o.createID(t)]},e.prototype.clear=function(){this.set={}},e.prototype.contains=function(t){return this.set[o.createID(t)]==t},e.prototype.isEmpty=function(){return this.size()===0},e.prototype.size=function(){return Object.keys(this.set).length},e.prototype.addAllTo=function(t){for(var i=Object.keys(this.set),l=i.length,g=0;g<l;g++)t.push(this.set[i[g]])},e.prototype.size=function(){return Object.keys(this.set).length},e.prototype.addAll=function(t){for(var i=t.length,l=0;l<i;l++){var g=t[l];this.add(g)}},N.exports=e}),(function(N,I,L){var o=(function(){function l(g,n){for(var d=0;d<n.length;d++){var r=n[d];r.enumerable=r.enumerable||!1,r.configurable=!0,"value"in r&&(r.writable=!0),Object.defineProperty(g,r.key,r)}}return function(g,n,d){return n&&l(g.prototype,n),d&&l(g,d),g}})();function e(l,g){if(!(l instanceof g))throw new TypeError("Cannot call a class as a function")}var t=L(11),i=(function(){function l(g,n){e(this,l),(n!==null||n!==void 0)&&(this.compareFunction=this._defaultCompareFunction);var d=void 0;g instanceof t?d=g.size():d=g.length,this._quicksort(g,0,d-1)}return o(l,[{key:"_quicksort",value:function(n,d,r){if(d<r){var h=this._partition(n,d,r);this._quicksort(n,d,h),this._quicksort(n,h+1,r)}}},{key:"_partition",value:function(n,d,r){for(var h=this._get(n,d),a=d,p=r;;){for(;this.compareFunction(h,this._get(n,p));)p--;for(;this.compareFunction(this._get(n,a),h);)a++;if(a<p)this._swap(n,a,p),a++,p--;else return p}}},{key:"_get",value:function(n,d){return n instanceof t?n.get_object_at(d):n[d]}},{key:"_set",value:function(n,d,r){n instanceof t?n.set_object_at(d,r):n[d]=r}},{key:"_swap",value:function(n,d,r){var h=this._get(n,d);this._set(n,d,this._get(n,r)),this._set(n,r,h)}},{key:"_defaultCompareFunction",value:function(n,d){return d>n}}]),l})();N.exports=i}),(function(N,I,L){var o=(function(){function i(l,g){for(var n=0;n<g.length;n++){var d=g[n];d.enumerable=d.enumerable||!1,d.configurable=!0,"value"in d&&(d.writable=!0),Object.defineProperty(l,d.key,d)}}return function(l,g,n){return g&&i(l.prototype,g),n&&i(l,n),l}})();function e(i,l){if(!(i instanceof l))throw new TypeError("Cannot call a class as a function")}var t=(function(){function i(l,g){var n=arguments.length>2&&arguments[2]!==void 0?arguments[2]:1,d=arguments.length>3&&arguments[3]!==void 0?arguments[3]:-1,r=arguments.length>4&&arguments[4]!==void 0?arguments[4]:-1;e(this,i),this.sequence1=l,this.sequence2=g,this.match_score=n,this.mismatch_penalty=d,this.gap_penalty=r,this.iMax=l.length+1,this.jMax=g.length+1,this.grid=new Array(this.iMax);for(var h=0;h<this.iMax;h++){this.grid[h]=new Array(this.jMax);for(var a=0;a<this.jMax;a++)this.grid[h][a]=0}this.tracebackGrid=new Array(this.iMax);for(var p=0;p<this.iMax;p++){this.tracebackGrid[p]=new Array(this.jMax);for(var v=0;v<this.jMax;v++)this.tracebackGrid[p][v]=[null,null,null]}this.alignments=[],this.score=-1,this.computeGrids()}return o(i,[{key:"getScore",value:function(){return this.score}},{key:"getAlignments",value:function(){return this.alignments}},{key:"computeGrids",value:function(){for(var g=1;g<this.jMax;g++)this.grid[0][g]=this.grid[0][g-1]+this.gap_penalty,this.tracebackGrid[0][g]=[!1,!1,!0];for(var n=1;n<this.iMax;n++)this.grid[n][0]=this.grid[n-1][0]+this.gap_penalty,this.tracebackGrid[n][0]=[!1,!0,!1];for(var d=1;d<this.iMax;d++)for(var r=1;r<this.jMax;r++){var h=void 0;this.sequence1[d-1]===this.sequence2[r-1]?h=this.grid[d-1][r-1]+this.match_score:h=this.grid[d-1][r-1]+this.mismatch_penalty;var a=this.grid[d-1][r]+this.gap_penalty,p=this.grid[d][r-1]+this.gap_penalty,v=[h,a,p],D=this.arrayAllMaxIndexes(v);this.grid[d][r]=v[D[0]],this.tracebackGrid[d][r]=[D.includes(0),D.includes(1),D.includes(2)]}this.score=this.grid[this.iMax-1][this.jMax-1]}},{key:"alignmentTraceback",value:function(){var g=[];for(g.push({pos:[this.sequence1.length,this.sequence2.length],seq1:"",seq2:""});g[0];){var n=g[0],d=this.tracebackGrid[n.pos[0]][n.pos[1]];d[0]&&g.push({pos:[n.pos[0]-1,n.pos[1]-1],seq1:this.sequence1[n.pos[0]-1]+n.seq1,seq2:this.sequence2[n.pos[1]-1]+n.seq2}),d[1]&&g.push({pos:[n.pos[0]-1,n.pos[1]],seq1:this.sequence1[n.pos[0]-1]+n.seq1,seq2:"-"+n.seq2}),d[2]&&g.push({pos:[n.pos[0],n.pos[1]-1],seq1:"-"+n.seq1,seq2:this.sequence2[n.pos[1]-1]+n.seq2}),n.pos[0]===0&&n.pos[1]===0&&this.alignments.push({sequence1:n.seq1,sequence2:n.seq2}),g.shift()}return this.alignments}},{key:"getAllIndexes",value:function(g,n){for(var d=[],r=-1;(r=g.indexOf(n,r+1))!==-1;)d.push(r);return d}},{key:"arrayAllMaxIndexes",value:function(g){return this.getAllIndexes(g,Math.max.apply(null,g))}}]),i})();N.exports=t}),(function(N,I,L){var o=function(){};o.FDLayout=L(18),o.FDLayoutConstants=L(7),o.FDLayoutEdge=L(19),o.FDLayoutNode=L(20),o.DimensionD=L(21),o.HashMap=L(22),o.HashSet=L(23),o.IGeometry=L(8),o.IMath=L(9),o.Integer=L(10),o.Point=L(12),o.PointD=L(4),o.RandomSeed=L(16),o.RectangleD=L(13),o.Transform=L(17),o.UniqueIDGeneretor=L(14),o.Quicksort=L(24),o.LinkedList=L(11),o.LGraphObject=L(2),o.LGraph=L(5),o.LEdge=L(1),o.LGraphManager=L(6),o.LNode=L(3),o.Layout=L(15),o.LayoutConstants=L(0),o.NeedlemanWunsch=L(25),N.exports=o}),(function(N,I,L){function o(){this.listeners=[]}var e=o.prototype;e.addListener=function(t,i){this.listeners.push({event:t,callback:i})},e.removeListener=function(t,i){for(var l=this.listeners.length;l>=0;l--){var g=this.listeners[l];g.event===t&&g.callback===i&&this.listeners.splice(l,1)}},e.emit=function(t,i){for(var l=0;l<this.listeners.length;l++){var g=this.listeners[l];t===g.event&&g.callback(i)}},N.exports=o})])})})(Q)),Q.exports}var ct=$.exports,z;function pt(){return z||(z=1,(function(G,b){(function(I,L){G.exports=L(ft())})(ct,function(N){return(function(I){var L={};function o(e){if(L[e])return L[e].exports;var t=L[e]={i:e,l:!1,exports:{}};return I[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=I,o.c=L,o.i=function(e){return e},o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=7)})([(function(I,L){I.exports=N}),(function(I,L,o){var e=o(0).FDLayoutConstants;function t(){}for(var i in e)t[i]=e[i];t.DEFAULT_USE_MULTI_LEVEL_SCALING=!1,t.DEFAULT_RADIAL_SEPARATION=e.DEFAULT_EDGE_LENGTH,t.DEFAULT_COMPONENT_SEPERATION=60,t.TILE=!0,t.TILING_PADDING_VERTICAL=10,t.TILING_PADDING_HORIZONTAL=10,t.TREE_REDUCTION_ON_INCREMENTAL=!1,I.exports=t}),(function(I,L,o){var e=o(0).FDLayoutEdge;function t(l,g,n){e.call(this,l,g,n)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).LGraph;function t(l,g,n){e.call(this,l,g,n)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).LGraphManager;function t(l){e.call(this,l)}t.prototype=Object.create(e.prototype);for(var i in e)t[i]=e[i];I.exports=t}),(function(I,L,o){var e=o(0).FDLayoutNode,t=o(0).IMath;function i(g,n,d,r){e.call(this,g,n,d,r)}i.prototype=Object.create(e.prototype);for(var l in e)i[l]=e[l];i.prototype.move=function(){var g=this.graphManager.getLayout();this.displacementX=g.coolingFactor*(this.springForceX+this.repulsionForceX+this.gravitationForceX)/this.noOfChildren,this.displacementY=g.coolingFactor*(this.springForceY+this.repulsionForceY+this.gravitationForceY)/this.noOfChildren,Math.abs(this.displacementX)>g.coolingFactor*g.maxNodeDisplacement&&(this.displacementX=g.coolingFactor*g.maxNodeDisplacement*t.sign(this.displacementX)),Math.abs(this.displacementY)>g.coolingFactor*g.maxNodeDisplacement&&(this.displacementY=g.coolingFactor*g.maxNodeDisplacement*t.sign(this.displacementY)),this.child==null?this.moveBy(this.displacementX,this.displacementY):this.child.getNodes().length==0?this.moveBy(this.displacementX,this.displacementY):this.propogateDisplacementToChildren(this.displacementX,this.displacementY),g.totalDisplacement+=Math.abs(this.displacementX)+Math.abs(this.displacementY),this.springForceX=0,this.springForceY=0,this.repulsionForceX=0,this.repulsionForceY=0,this.gravitationForceX=0,this.gravitationForceY=0,this.displacementX=0,this.displacementY=0},i.prototype.propogateDisplacementToChildren=function(g,n){for(var d=this.getChild().getNodes(),r,h=0;h<d.length;h++)r=d[h],r.getChild()==null?(r.moveBy(g,n),r.displacementX+=g,r.displacementY+=n):r.propogateDisplacementToChildren(g,n)},i.prototype.setPred1=function(g){this.pred1=g},i.prototype.getPred1=function(){return pred1},i.prototype.getPred2=function(){return pred2},i.prototype.setNext=function(g){this.next=g},i.prototype.getNext=function(){return next},i.prototype.setProcessed=function(g){this.processed=g},i.prototype.isProcessed=function(){return processed},I.exports=i}),(function(I,L,o){var e=o(0).FDLayout,t=o(4),i=o(3),l=o(5),g=o(2),n=o(1),d=o(0).FDLayoutConstants,r=o(0).LayoutConstants,h=o(0).Point,a=o(0).PointD,p=o(0).Layout,v=o(0).Integer,D=o(0).IGeometry,u=o(0).LGraph,T=o(0).Transform;function y(){e.call(this),this.toBeTiled={}}y.prototype=Object.create(e.prototype);for(var O in e)y[O]=e[O];y.prototype.newGraphManager=function(){var s=new t(this);return this.graphManager=s,s},y.prototype.newGraph=function(s){return new i(null,this.graphManager,s)},y.prototype.newNode=function(s){return new l(this.graphManager,s)},y.prototype.newEdge=function(s){return new g(null,null,s)},y.prototype.initParameters=function(){e.prototype.initParameters.call(this,arguments),this.isSubLayout||(n.DEFAULT_EDGE_LENGTH<10?this.idealEdgeLength=10:this.idealEdgeLength=n.DEFAULT_EDGE_LENGTH,this.useSmartIdealEdgeLengthCalculation=n.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION,this.springConstant=d.DEFAULT_SPRING_STRENGTH,this.repulsionConstant=d.DEFAULT_REPULSION_STRENGTH,this.gravityConstant=d.DEFAULT_GRAVITY_STRENGTH,this.compoundGravityConstant=d.DEFAULT_COMPOUND_GRAVITY_STRENGTH,this.gravityRangeFactor=d.DEFAULT_GRAVITY_RANGE_FACTOR,this.compoundGravityRangeFactor=d.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR,this.prunedNodesAll=[],this.growTreeIterations=0,this.afterGrowthIterations=0,this.isTreeGrowing=!1,this.isGrowthFinished=!1,this.coolingCycle=0,this.maxCoolingCycle=this.maxIterations/d.CONVERGENCE_CHECK_PERIOD,this.finalTemperature=d.CONVERGENCE_CHECK_PERIOD/this.maxIterations,this.coolingAdjuster=1)},y.prototype.layout=function(){var s=r.DEFAULT_CREATE_BENDS_AS_NEEDED;return s&&(this.createBendpoints(),this.graphManager.resetAllEdges()),this.level=0,this.classicLayout()},y.prototype.classicLayout=function(){if(this.nodesWithGravity=this.calculateNodesToApplyGravitationTo(),this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity),this.calcNoOfChildrenForAllNodes(),this.graphManager.calcLowestCommonAncestors(),this.graphManager.calcInclusionTreeDepths(),this.graphManager.getRoot().calcEstimatedSize(),this.calcIdealEdgeLengths(),this.incremental){if(n.TREE_REDUCTION_ON_INCREMENTAL){this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var f=new Set(this.getAllNodes()),c=this.nodesWithGravity.filter(function(m){return f.has(m)});this.graphManager.setAllNodesToApplyGravitation(c)}}else{var s=this.getFlatForest();if(s.length>0)this.positionNodesRadially(s);else{this.reduceTrees(),this.graphManager.resetAllNodesToApplyGravitation();var f=new Set(this.getAllNodes()),c=this.nodesWithGravity.filter(function(E){return f.has(E)});this.graphManager.setAllNodesToApplyGravitation(c),this.positionNodesRandomly()}}return this.initSpringEmbedder(),this.runSpringEmbedder(),!0},y.prototype.tick=function(){if(this.totalIterations++,this.totalIterations===this.maxIterations&&!this.isTreeGrowing&&!this.isGrowthFinished)if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;if(this.totalIterations%d.CONVERGENCE_CHECK_PERIOD==0&&!this.isTreeGrowing&&!this.isGrowthFinished){if(this.isConverged())if(this.prunedNodesAll.length>0)this.isTreeGrowing=!0;else return!0;this.coolingCycle++,this.layoutQuality==0?this.coolingAdjuster=this.coolingCycle:this.layoutQuality==1&&(this.coolingAdjuster=this.coolingCycle/3),this.coolingFactor=Math.max(this.initialCoolingFactor-Math.pow(this.coolingCycle,Math.log(100*(this.initialCoolingFactor-this.finalTemperature))/Math.log(this.maxCoolingCycle))/100*this.coolingAdjuster,this.finalTemperature),this.animationPeriod=Math.ceil(this.initialAnimationPeriod*Math.sqrt(this.coolingFactor))}if(this.isTreeGrowing){if(this.growTreeIterations%10==0)if(this.prunedNodesAll.length>0){this.graphManager.updateBounds(),this.updateGrid(),this.growTree(this.prunedNodesAll),this.graphManager.resetAllNodesToApplyGravitation();var s=new Set(this.getAllNodes()),f=this.nodesWithGravity.filter(function(A){return s.has(A)});this.graphManager.setAllNodesToApplyGravitation(f),this.graphManager.updateBounds(),this.updateGrid(),this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL}else this.isTreeGrowing=!1,this.isGrowthFinished=!0;this.growTreeIterations++}if(this.isGrowthFinished){if(this.isConverged())return!0;this.afterGrowthIterations%10==0&&(this.graphManager.updateBounds(),this.updateGrid()),this.coolingFactor=d.DEFAULT_COOLING_FACTOR_INCREMENTAL*((100-this.afterGrowthIterations)/100),this.afterGrowthIterations++}var c=!this.isTreeGrowing&&!this.isGrowthFinished,E=this.growTreeIterations%10==1&&this.isTreeGrowing||this.afterGrowthIterations%10==1&&this.isGrowthFinished;return this.totalDisplacement=0,this.graphManager.updateBounds(),this.calcSpringForces(),this.calcRepulsionForces(c,E),this.calcGravitationalForces(),this.moveNodes(),this.animate(),!1},y.prototype.getPositionsData=function(){for(var s=this.graphManager.getAllNodes(),f={},c=0;c<s.length;c++){var E=s[c].rect,A=s[c].id;f[A]={id:A,x:E.getCenterX(),y:E.getCenterY(),w:E.width,h:E.height}}return f},y.prototype.runSpringEmbedder=function(){this.initialAnimationPeriod=25,this.animationPeriod=this.initialAnimationPeriod;var s=!1;if(d.ANIMATE==="during")this.emit("layoutstarted");else{for(;!s;)s=this.tick();this.graphManager.updateBounds()}},y.prototype.calculateNodesToApplyGravitationTo=function(){var s=[],f,c=this.graphManager.getGraphs(),E=c.length,A;for(A=0;A<E;A++)f=c[A],f.updateConnected(),f.isConnected||(s=s.concat(f.getNodes()));return s},y.prototype.createBendpoints=function(){var s=[];s=s.concat(this.graphManager.getAllEdges());var f=new Set,c;for(c=0;c<s.length;c++){var E=s[c];if(!f.has(E)){var A=E.getSource(),m=E.getTarget();if(A==m)E.getBendpoints().push(new a),E.getBendpoints().push(new a),this.createDummyNodesForBendpoints(E),f.add(E);else{var C=[];if(C=C.concat(A.getEdgeListToNode(m)),C=C.concat(m.getEdgeListToNode(A)),!f.has(C[0])){if(C.length>1){var R;for(R=0;R<C.length;R++){var M=C[R];M.getBendpoints().push(new a),this.createDummyNodesForBendpoints(M)}}C.forEach(function(S){f.add(S)})}}}if(f.size==s.length)break}},y.prototype.positionNodesRadially=function(s){for(var f=new h(0,0),c=Math.ceil(Math.sqrt(s.length)),E=0,A=0,m=0,C=new a(0,0),R=0;R<s.length;R++){R%c==0&&(m=0,A=E,R!=0&&(A+=n.DEFAULT_COMPONENT_SEPERATION),E=0);var M=s[R],S=p.findCenterOfTree(M);f.x=m,f.y=A,C=y.radialLayout(M,S,f),C.y>E&&(E=Math.floor(C.y)),m=Math.floor(C.x+n.DEFAULT_COMPONENT_SEPERATION)}this.transform(new a(r.WORLD_CENTER_X-C.x/2,r.WORLD_CENTER_Y-C.y/2))},y.radialLayout=function(s,f,c){var E=Math.max(this.maxDiagonalInTree(s),n.DEFAULT_RADIAL_SEPARATION);y.branchRadialLayout(f,null,0,359,0,E);var A=u.calculateBounds(s),m=new T;m.setDeviceOrgX(A.getMinX()),m.setDeviceOrgY(A.getMinY()),m.setWorldOrgX(c.x),m.setWorldOrgY(c.y);for(var C=0;C<s.length;C++){var R=s[C];R.transform(m)}var M=new a(A.getMaxX(),A.getMaxY());return m.inverseTransformPoint(M)},y.branchRadialLayout=function(s,f,c,E,A,m){var C=(E-c+1)/2;C<0&&(C+=180);var R=(C+c)%360,M=R*D.TWO_PI/360,S=A*Math.cos(M),Y=A*Math.sin(M);s.setCenter(S,Y);var w=[];w=w.concat(s.getEdges());var x=w.length;f!=null&&x--;for(var F=0,U=w.length,P,_=s.getEdgesBetween(f);_.length>1;){var X=_[0];_.splice(0,1);var H=w.indexOf(X);H>=0&&w.splice(H,1),U--,x--}f!=null?P=(w.indexOf(_[0])+1)%U:P=0;for(var W=Math.abs(E-c)/x,B=P;F!=x;B=++B%U){var K=w[B].getOtherEnd(s);if(K!=f){var q=(c+F*W)%360,ht=(q+W)%360;y.branchRadialLayout(K,s,q,ht,A+m,m),F++}}},y.maxDiagonalInTree=function(s){for(var f=v.MIN_VALUE,c=0;c<s.length;c++){var E=s[c],A=E.getDiagonal();A>f&&(f=A)}return f},y.prototype.calcRepulsionRange=function(){return 2*(this.level+1)*this.idealEdgeLength},y.prototype.groupZeroDegreeMembers=function(){var s=this,f={};this.memberGroups={},this.idToDummyNode={};for(var c=[],E=this.graphManager.getAllNodes(),A=0;A<E.length;A++){var m=E[A],C=m.getParent();this.getNodeDegreeWithChildren(m)===0&&(C.id==null||!this.getToBeTiled(C))&&c.push(m)}for(var A=0;A<c.length;A++){var m=c[A],R=m.getParent().id;typeof f[R]>"u"&&(f[R]=[]),f[R]=f[R].concat(m)}Object.keys(f).forEach(function(M){if(f[M].length>1){var S="DummyCompound_"+M;s.memberGroups[S]=f[M];var Y=f[M][0].getParent(),w=new l(s.graphManager);w.id=S,w.paddingLeft=Y.paddingLeft||0,w.paddingRight=Y.paddingRight||0,w.paddingBottom=Y.paddingBottom||0,w.paddingTop=Y.paddingTop||0,s.idToDummyNode[S]=w;var x=s.getGraphManager().add(s.newGraph(),w),F=Y.getChild();F.add(w);for(var U=0;U<f[M].length;U++){var P=f[M][U];F.remove(P),x.add(P)}}})},y.prototype.clearCompounds=function(){var s={},f={};this.performDFSOnCompounds();for(var c=0;c<this.compoundOrder.length;c++)f[this.compoundOrder[c].id]=this.compoundOrder[c],s[this.compoundOrder[c].id]=[].concat(this.compoundOrder[c].getChild().getNodes()),this.graphManager.remove(this.compoundOrder[c].getChild()),this.compoundOrder[c].child=null;this.graphManager.resetAllNodes(),this.tileCompoundMembers(s,f)},y.prototype.clearZeroDegreeMembers=function(){var s=this,f=this.tiledZeroDegreePack=[];Object.keys(this.memberGroups).forEach(function(c){var E=s.idToDummyNode[c];f[c]=s.tileNodes(s.memberGroups[c],E.paddingLeft+E.paddingRight),E.rect.width=f[c].width,E.rect.height=f[c].height})},y.prototype.repopulateCompounds=function(){for(var s=this.compoundOrder.length-1;s>=0;s--){var f=this.compoundOrder[s],c=f.id,E=f.paddingLeft,A=f.paddingTop;this.adjustLocations(this.tiledMemberPack[c],f.rect.x,f.rect.y,E,A)}},y.prototype.repopulateZeroDegreeMembers=function(){var s=this,f=this.tiledZeroDegreePack;Object.keys(f).forEach(function(c){var E=s.idToDummyNode[c],A=E.paddingLeft,m=E.paddingTop;s.adjustLocations(f[c],E.rect.x,E.rect.y,A,m)})},y.prototype.getToBeTiled=function(s){var f=s.id;if(this.toBeTiled[f]!=null)return this.toBeTiled[f];var c=s.getChild();if(c==null)return this.toBeTiled[f]=!1,!1;for(var E=c.getNodes(),A=0;A<E.length;A++){var m=E[A];if(this.getNodeDegree(m)>0)return this.toBeTiled[f]=!1,!1;if(m.getChild()==null){this.toBeTiled[m.id]=!1;continue}if(!this.getToBeTiled(m))return this.toBeTiled[f]=!1,!1}return this.toBeTiled[f]=!0,!0},y.prototype.getNodeDegree=function(s){s.id;for(var f=s.getEdges(),c=0,E=0;E<f.length;E++){var A=f[E];A.getSource().id!==A.getTarget().id&&(c=c+1)}return c},y.prototype.getNodeDegreeWithChildren=function(s){var f=this.getNodeDegree(s);if(s.getChild()==null)return f;for(var c=s.getChild().getNodes(),E=0;E<c.length;E++){var A=c[E];f+=this.getNodeDegreeWithChildren(A)}return f},y.prototype.performDFSOnCompounds=function(){this.compoundOrder=[],this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes())},y.prototype.fillCompexOrderByDFS=function(s){for(var f=0;f<s.length;f++){var c=s[f];c.getChild()!=null&&this.fillCompexOrderByDFS(c.getChild().getNodes()),this.getToBeTiled(c)&&this.compoundOrder.push(c)}},y.prototype.adjustLocations=function(s,f,c,E,A){f+=E,c+=A;for(var m=f,C=0;C<s.rows.length;C++){var R=s.rows[C];f=m;for(var M=0,S=0;S<R.length;S++){var Y=R[S];Y.rect.x=f,Y.rect.y=c,f+=Y.rect.width+s.horizontalPadding,Y.rect.height>M&&(M=Y.rect.height)}c+=M+s.verticalPadding}},y.prototype.tileCompoundMembers=function(s,f){var c=this;this.tiledMemberPack=[],Object.keys(s).forEach(function(E){var A=f[E];c.tiledMemberPack[E]=c.tileNodes(s[E],A.paddingLeft+A.paddingRight),A.rect.width=c.tiledMemberPack[E].width,A.rect.height=c.tiledMemberPack[E].height})},y.prototype.tileNodes=function(s,f){var c=n.TILING_PADDING_VERTICAL,E=n.TILING_PADDING_HORIZONTAL,A={rows:[],rowWidth:[],rowHeight:[],width:0,height:f,verticalPadding:c,horizontalPadding:E};s.sort(function(R,M){return R.rect.width*R.rect.height>M.rect.width*M.rect.height?-1:R.rect.width*R.rect.height<M.rect.width*M.rect.height?1:0});for(var m=0;m<s.length;m++){var C=s[m];A.rows.length==0?this.insertNodeToRow(A,C,0,f):this.canAddHorizontal(A,C.rect.width,C.rect.height)?this.insertNodeToRow(A,C,this.getShortestRowIndex(A),f):this.insertNodeToRow(A,C,A.rows.length,f),this.shiftToLastRow(A)}return A},y.prototype.insertNodeToRow=function(s,f,c,E){var A=E;if(c==s.rows.length){var m=[];s.rows.push(m),s.rowWidth.push(A),s.rowHeight.push(0)}var C=s.rowWidth[c]+f.rect.width;s.rows[c].length>0&&(C+=s.horizontalPadding),s.rowWidth[c]=C,s.width<C&&(s.width=C);var R=f.rect.height;c>0&&(R+=s.verticalPadding);var M=0;R>s.rowHeight[c]&&(M=s.rowHeight[c],s.rowHeight[c]=R,M=s.rowHeight[c]-M),s.height+=M,s.rows[c].push(f)},y.prototype.getShortestRowIndex=function(s){for(var f=-1,c=Number.MAX_VALUE,E=0;E<s.rows.length;E++)s.rowWidth[E]<c&&(f=E,c=s.rowWidth[E]);return f},y.prototype.getLongestRowIndex=function(s){for(var f=-1,c=Number.MIN_VALUE,E=0;E<s.rows.length;E++)s.rowWidth[E]>c&&(f=E,c=s.rowWidth[E]);return f},y.prototype.canAddHorizontal=function(s,f,c){var E=this.getShortestRowIndex(s);if(E<0)return!0;var A=s.rowWidth[E];if(A+s.horizontalPadding+f<=s.width)return!0;var m=0;s.rowHeight[E]<c&&E>0&&(m=c+s.verticalPadding-s.rowHeight[E]);var C;s.width-A>=f+s.horizontalPadding?C=(s.height+m)/(A+f+s.horizontalPadding):C=(s.height+m)/s.width,m=c+s.verticalPadding;var R;return s.width<f?R=(s.height+m)/f:R=(s.height+m)/s.width,R<1&&(R=1/R),C<1&&(C=1/C),C<R},y.prototype.shiftToLastRow=function(s){var f=this.getLongestRowIndex(s),c=s.rowWidth.length-1,E=s.rows[f],A=E[E.length-1],m=A.width+s.horizontalPadding;if(s.width-s.rowWidth[c]>m&&f!=c){E.splice(-1,1),s.rows[c].push(A),s.rowWidth[f]=s.rowWidth[f]-m,s.rowWidth[c]=s.rowWidth[c]+m,s.width=s.rowWidth[instance.getLongestRowIndex(s)];for(var C=Number.MIN_VALUE,R=0;R<E.length;R++)E[R].height>C&&(C=E[R].height);f>0&&(C+=s.verticalPadding);var M=s.rowHeight[f]+s.rowHeight[c];s.rowHeight[f]=C,s.rowHeight[c]<A.height+s.verticalPadding&&(s.rowHeight[c]=A.height+s.verticalPadding);var S=s.rowHeight[f]+s.rowHeight[c];s.height+=S-M,this.shiftToLastRow(s)}},y.prototype.tilingPreLayout=function(){n.TILE&&(this.groupZeroDegreeMembers(),this.clearCompounds(),this.clearZeroDegreeMembers())},y.prototype.tilingPostLayout=function(){n.TILE&&(this.repopulateZeroDegreeMembers(),this.repopulateCompounds())},y.prototype.reduceTrees=function(){for(var s=[],f=!0,c;f;){var E=this.graphManager.getAllNodes(),A=[];f=!1;for(var m=0;m<E.length;m++)c=E[m],c.getEdges().length==1&&!c.getEdges()[0].isInterGraph&&c.getChild()==null&&(A.push([c,c.getEdges()[0],c.getOwner()]),f=!0);if(f==!0){for(var C=[],R=0;R<A.length;R++)A[R][0].getEdges().length==1&&(C.push(A[R]),A[R][0].getOwner().remove(A[R][0]));s.push(C),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()}}this.prunedNodesAll=s},y.prototype.growTree=function(s){for(var f=s.length,c=s[f-1],E,A=0;A<c.length;A++)E=c[A],this.findPlaceforPrunedNode(E),E[2].add(E[0]),E[2].add(E[1],E[1].source,E[1].target);s.splice(s.length-1,1),this.graphManager.resetAllNodes(),this.graphManager.resetAllEdges()},y.prototype.findPlaceforPrunedNode=function(s){var f,c,E=s[0];E==s[1].source?c=s[1].target:c=s[1].source;var A=c.startX,m=c.finishX,C=c.startY,R=c.finishY,M=0,S=0,Y=0,w=0,x=[M,Y,S,w];if(C>0)for(var F=A;F<=m;F++)x[0]+=this.grid[F][C-1].length+this.grid[F][C].length-1;if(m<this.grid.length-1)for(var F=C;F<=R;F++)x[1]+=this.grid[m+1][F].length+this.grid[m][F].length-1;if(R<this.grid[0].length-1)for(var F=A;F<=m;F++)x[2]+=this.grid[F][R+1].length+this.grid[F][R].length-1;if(A>0)for(var F=C;F<=R;F++)x[3]+=this.grid[A-1][F].length+this.grid[A][F].length-1;for(var U=v.MAX_VALUE,P,_,X=0;X<x.length;X++)x[X]<U?(U=x[X],P=1,_=X):x[X]==U&&P++;if(P==3&&U==0)x[0]==0&&x[1]==0&&x[2]==0?f=1:x[0]==0&&x[1]==0&&x[3]==0?f=0:x[0]==0&&x[2]==0&&x[3]==0?f=3:x[1]==0&&x[2]==0&&x[3]==0&&(f=2);else if(P==2&&U==0){var H=Math.floor(Math.random()*2);x[0]==0&&x[1]==0?H==0?f=0:f=1:x[0]==0&&x[2]==0?H==0?f=0:f=2:x[0]==0&&x[3]==0?H==0?f=0:f=3:x[1]==0&&x[2]==0?H==0?f=1:f=2:x[1]==0&&x[3]==0?H==0?f=1:f=3:H==0?f=2:f=3}else if(P==4&&U==0){var H=Math.floor(Math.random()*4);f=H}else f=_;f==0?E.setCenter(c.getCenterX(),c.getCenterY()-c.getHeight()/2-d.DEFAULT_EDGE_LENGTH-E.getHeight()/2):f==1?E.setCenter(c.getCenterX()+c.getWidth()/2+d.DEFAULT_EDGE_LENGTH+E.getWidth()/2,c.getCenterY()):f==2?E.setCenter(c.getCenterX(),c.getCenterY()+c.getHeight()/2+d.DEFAULT_EDGE_LENGTH+E.getHeight()/2):E.setCenter(c.getCenterX()-c.getWidth()/2-d.DEFAULT_EDGE_LENGTH-E.getWidth()/2,c.getCenterY())},I.exports=y}),(function(I,L,o){var e={};e.layoutBase=o(0),e.CoSEConstants=o(1),e.CoSEEdge=o(2),e.CoSEGraph=o(3),e.CoSEGraphManager=o(4),e.CoSELayout=o(6),e.CoSENode=o(5),I.exports=e})])})})($)),$.exports}var dt=Z.exports,J;function vt(){return J||(J=1,(function(G,b){(function(I,L){G.exports=L(pt())})(dt,function(N){return(function(I){var L={};function o(e){if(L[e])return L[e].exports;var t=L[e]={i:e,l:!1,exports:{}};return I[e].call(t.exports,t,t.exports,o),t.l=!0,t.exports}return o.m=I,o.c=L,o.i=function(e){return e},o.d=function(e,t,i){o.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:i})},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="",o(o.s=1)})([(function(I,L){I.exports=N}),(function(I,L,o){var e=o(0).layoutBase.LayoutConstants,t=o(0).layoutBase.FDLayoutConstants,i=o(0).CoSEConstants,l=o(0).CoSELayout,g=o(0).CoSENode,n=o(0).layoutBase.PointD,d=o(0).layoutBase.DimensionD,r={ready:function(){},stop:function(){},quality:"default",nodeDimensionsIncludeLabels:!1,refresh:30,fit:!0,padding:10,randomize:!0,nodeRepulsion:4500,idealEdgeLength:50,edgeElasticity:.45,nestingFactor:.1,gravity:.25,numIter:2500,tile:!0,animate:"end",animationDuration:500,tilingPaddingVertical:10,tilingPaddingHorizontal:10,gravityRangeCompound:1.5,gravityCompound:1,gravityRange:3.8,initialEnergyOnIncremental:.5};function h(D,u){var T={};for(var y in D)T[y]=D[y];for(var y in u)T[y]=u[y];return T}function a(D){this.options=h(r,D),p(this.options)}var p=function(u){u.nodeRepulsion!=null&&(i.DEFAULT_REPULSION_STRENGTH=t.DEFAULT_REPULSION_STRENGTH=u.nodeRepulsion),u.idealEdgeLength!=null&&(i.DEFAULT_EDGE_LENGTH=t.DEFAULT_EDGE_LENGTH=u.idealEdgeLength),u.edgeElasticity!=null&&(i.DEFAULT_SPRING_STRENGTH=t.DEFAULT_SPRING_STRENGTH=u.edgeElasticity),u.nestingFactor!=null&&(i.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=t.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR=u.nestingFactor),u.gravity!=null&&(i.DEFAULT_GRAVITY_STRENGTH=t.DEFAULT_GRAVITY_STRENGTH=u.gravity),u.numIter!=null&&(i.MAX_ITERATIONS=t.MAX_ITERATIONS=u.numIter),u.gravityRange!=null&&(i.DEFAULT_GRAVITY_RANGE_FACTOR=t.DEFAULT_GRAVITY_RANGE_FACTOR=u.gravityRange),u.gravityCompound!=null&&(i.DEFAULT_COMPOUND_GRAVITY_STRENGTH=t.DEFAULT_COMPOUND_GRAVITY_STRENGTH=u.gravityCompound),u.gravityRangeCompound!=null&&(i.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=t.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR=u.gravityRangeCompound),u.initialEnergyOnIncremental!=null&&(i.DEFAULT_COOLING_FACTOR_INCREMENTAL=t.DEFAULT_COOLING_FACTOR_INCREMENTAL=u.initialEnergyOnIncremental),u.quality=="draft"?e.QUALITY=0:u.quality=="proof"?e.QUALITY=2:e.QUALITY=1,i.NODE_DIMENSIONS_INCLUDE_LABELS=t.NODE_DIMENSIONS_INCLUDE_LABELS=e.NODE_DIMENSIONS_INCLUDE_LABELS=u.nodeDimensionsIncludeLabels,i.DEFAULT_INCREMENTAL=t.DEFAULT_INCREMENTAL=e.DEFAULT_INCREMENTAL=!u.randomize,i.ANIMATE=t.ANIMATE=e.ANIMATE=u.animate,i.TILE=u.tile,i.TILING_PADDING_VERTICAL=typeof u.tilingPaddingVertical=="function"?u.tilingPaddingVertical.call():u.tilingPaddingVertical,i.TILING_PADDING_HORIZONTAL=typeof u.tilingPaddingHorizontal=="function"?u.tilingPaddingHorizontal.call():u.tilingPaddingHorizontal};a.prototype.run=function(){var D,u,T=this.options;this.idToLNode={};var y=this.layout=new l,O=this;O.stopped=!1,this.cy=this.options.cy,this.cy.trigger({type:"layoutstart",layout:this});var s=y.newGraphManager();this.gm=s;var f=this.options.eles.nodes(),c=this.options.eles.edges();this.root=s.addRoot(),this.processChildrenList(this.root,this.getTopMostNodes(f),y);for(var E=0;E<c.length;E++){var A=c[E],m=this.idToLNode[A.data("source")],C=this.idToLNode[A.data("target")];if(m!==C&&m.getEdgesBetween(C).length==0){var R=s.add(y.newEdge(),m,C);R.id=A.id()}}var M=function(w,x){typeof w=="number"&&(w=x);var F=w.data("id"),U=O.idToLNode[F];return{x:U.getRect().getCenterX(),y:U.getRect().getCenterY()}},S=function Y(){for(var w=function(){T.fit&&T.cy.fit(T.eles,T.padding),D||(D=!0,O.cy.one("layoutready",T.ready),O.cy.trigger({type:"layoutready",layout:O}))},x=O.options.refresh,F,U=0;U<x&&!F;U++)F=O.stopped||O.layout.tick();if(F){y.checkLayoutSuccess()&&!y.isSubLayout&&y.doPostLayout(),y.tilingPostLayout&&y.tilingPostLayout(),y.isLayoutFinished=!0,O.options.eles.nodes().positions(M),w(),O.cy.one("layoutstop",O.options.stop),O.cy.trigger({type:"layoutstop",layout:O}),u&&cancelAnimationFrame(u),D=!1;return}var P=O.layout.getPositionsData();T.eles.nodes().positions(function(_,X){if(typeof _=="number"&&(_=X),!_.isParent()){for(var H=_.id(),W=P[H],B=_;W==null&&(W=P[B.data("parent")]||P["DummyCompound_"+B.data("parent")],P[H]=W,B=B.parent()[0],B!=null););return W!=null?{x:W.x,y:W.y}:{x:_.position("x"),y:_.position("y")}}}),w(),u=requestAnimationFrame(Y)};return y.addListener("layoutstarted",function(){O.options.animate==="during"&&(u=requestAnimationFrame(S))}),y.runLayout(),this.options.animate!=="during"&&(O.options.eles.nodes().not(":parent").layoutPositions(O,O.options,M),D=!1),this},a.prototype.getTopMostNodes=function(D){for(var u={},T=0;T<D.length;T++)u[D[T].id()]=!0;var y=D.filter(function(O,s){typeof O=="number"&&(O=s);for(var f=O.parent()[0];f!=null;){if(u[f.id()])return!1;f=f.parent()[0]}return!0});return y},a.prototype.processChildrenList=function(D,u,T){for(var y=u.length,O=0;O<y;O++){var s=u[O],f=s.children(),c,E=s.layoutDimensions({nodeDimensionsIncludeLabels:this.options.nodeDimensionsIncludeLabels});if(s.outerWidth()!=null&&s.outerHeight()!=null?c=D.add(new g(T.graphManager,new n(s.position("x")-E.w/2,s.position("y")-E.h/2),new d(parseFloat(E.w),parseFloat(E.h)))):c=D.add(new g(this.graphManager)),c.id=s.data("id"),c.paddingLeft=parseInt(s.css("padding")),c.paddingTop=parseInt(s.css("padding")),c.paddingRight=parseInt(s.css("padding")),c.paddingBottom=parseInt(s.css("padding")),this.options.nodeDimensionsIncludeLabels&&s.isParent()){var A=s.boundingBox({includeLabels:!0,includeNodes:!1}).w,m=s.boundingBox({includeLabels:!0,includeNodes:!1}).h,C=s.css("text-halign");c.labelWidth=A,c.labelHeight=m,c.labelPos=C}if(this.idToLNode[s.data("id")]=c,isNaN(c.rect.x)&&(c.rect.x=0),isNaN(c.rect.y)&&(c.rect.y=0),f!=null&&f.length>0){var R;R=T.getGraphManager().add(T.newGraph(),c),this.processChildrenList(R,f,T)}}},a.prototype.stop=function(){return this.stopped=!0,this};var v=function(u){u("layout","cose-bilkent",a)};typeof cytoscape<"u"&&v(cytoscape),I.exports=v})])})})(Z)),Z.exports}var yt=vt();const Et=gt(yt);tt.use(Et);function et(G,b){G.forEach(N=>{const I={id:N.id,labelText:N.label,height:N.height,width:N.width,padding:N.padding??0};Object.keys(N).forEach(L=>{["id","label","height","width","padding","x","y"].includes(L)||(I[L]=N[L])}),b.add({group:"nodes",data:I,position:{x:N.x??0,y:N.y??0}})})}V(et,"addNodes");function rt(G,b){G.forEach(N=>{const I={id:N.id,source:N.start,target:N.end};Object.keys(N).forEach(L=>{["id","start","end"].includes(L)||(I[L]=N[L])}),b.add({group:"edges",data:I})})}V(rt,"addEdges");function it(G){return new Promise(b=>{const N=lt("body").append("div").attr("id","cy").attr("style","display:none"),I=tt({container:document.getElementById("cy"),style:[{selector:"edge",style:{"curve-style":"bezier"}}]});N.remove(),et(G.nodes,I),rt(G.edges,I),I.nodes().forEach(function(o){o.layoutDimensions=()=>{const e=o.data();return{w:e.width,h:e.height}}});const L={name:"cose-bilkent",quality:"proof",styleEnabled:!1,animate:!1};I.layout(L).run(),I.ready(o=>{k.info("Cytoscape ready",o),b(I)})})}V(it,"createCytoscapeInstance");function nt(G){return G.nodes().map(b=>{const N=b.data(),I=b.position(),L={id:N.id,x:I.x,y:I.y};return Object.keys(N).forEach(o=>{o!=="id"&&(L[o]=N[o])}),L})}V(nt,"extractPositionedNodes");function ot(G){return G.edges().map(b=>{const N=b.data(),I=b._private.rscratch,L={id:N.id,source:N.source,target:N.target,startX:I.startX,startY:I.startY,midX:I.midX,midY:I.midY,endX:I.endX,endY:I.endY};return Object.keys(N).forEach(o=>{["id","source","target"].includes(o)||(L[o]=N[o])}),L})}V(ot,"extractPositionedEdges");async function st(G,b){k.debug("Starting cose-bilkent layout algorithm");try{at(G);const N=await it(G),I=nt(N),L=ot(N);return k.debug(`Layout completed: ${I.length} nodes, ${L.length} edges`),{nodes:I,edges:L}}catch(N){throw k.error("Error in cose-bilkent layout algorithm:",N),N}}V(st,"executeCoseBilkentLayout");function at(G){if(!G)throw new Error("Layout data is required");if(!G.config)throw new Error("Configuration is required in layout data");if(!G.rootNode)throw new Error("Root node is required");if(!G.nodes||!Array.isArray(G.nodes))throw new Error("No nodes found in layout data");if(!Array.isArray(G.edges))throw new Error("Edges array is required in layout data");return!0}V(at,"validateLayoutData");var Lt=V(async(G,b,{insertCluster:N,insertEdge:I,insertEdgeLabel:L,insertMarkers:o,insertNode:e,log:t,positionEdgeLabel:i},{algorithm:l})=>{const g={},n={},d=b.select("g");o(d,G.markers,G.type,G.diagramId);const r=d.insert("g").attr("class","subgraphs"),h=d.insert("g").attr("class","edgePaths"),a=d.insert("g").attr("class","edgeLabels"),p=d.insert("g").attr("class","nodes");t.debug("Inserting nodes into DOM for dimension calculation"),await Promise.all(G.nodes.map(async u=>{if(u.isGroup){const T={...u};n[u.id]=T,g[u.id]=T,await N(r,u)}else{const T={...u};g[u.id]=T;const y=await e(p,u,{config:G.config,dir:G.direction||"TB"}),O=y.node().getBBox();T.width=O.width,T.height=O.height,T.domId=y,t.debug(`Node ${u.id} dimensions: ${O.width}x${O.height}`)}})),t.debug("Running cose-bilkent layout algorithm");const v={...G,nodes:G.nodes.map(u=>{const T=g[u.id];return{...u,width:T.width,height:T.height}})},D=await st(v,G.config);t.debug("Positioning nodes based on layout results"),D.nodes.forEach(u=>{const T=g[u.id];T?.domId&&(T.domId.attr("transform",`translate(${u.x}, ${u.y})`),T.x=u.x,T.y=u.y,t.debug(`Positioned node ${T.id} at center (${u.x}, ${u.y})`))}),D.edges.forEach(u=>{const T=G.edges.find(y=>y.id===u.id);T&&(T.points=[{x:u.startX,y:u.startY},{x:u.midX,y:u.midY},{x:u.endX,y:u.endY}])}),t.debug("Inserting and positioning edges"),await Promise.all(G.edges.map(async u=>{await L(a,u);const T=g[u.start??""],y=g[u.end??""];if(T&&y){const O=D.edges.find(s=>s.id===u.id);if(O){t.debug("APA01 positionedEdge",O);const s={...u},f=I(h,s,n,G.type,T,y,G.diagramId);i(s,f)}else{const s={...u,points:[{x:T.x||0,y:T.y||0},{x:y.x||0,y:y.y||0}]},f=I(h,s,n,G.type,T,y,G.diagramId);i(s,f)}}})),t.debug("Cose-bilkent rendering completed")},"render"),Ot=Lt;export{Ot as render}; diff --git a/apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-0NmB13eq.js b/apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-BIlq342y.js similarity index 99% rename from apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-0NmB13eq.js rename to apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-BIlq342y.js index b2fdfebef..465b4ad85 100644 --- a/apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-0NmB13eq.js +++ b/apps/kimi-code/dist-web/assets/cynefin-VYW2F7L2-BIlq342y.js @@ -1,4 +1,4 @@ -import{bR as et}from"./index-D1h84VfZ.js";var RI=Object.create,Ds=Object.defineProperty,AI=Object.getOwnPropertyDescriptor,Ad=Object.getOwnPropertyNames,EI=Object.getPrototypeOf,CI=Object.prototype.hasOwnProperty,i=(e,t)=>Ds(e,"name",{value:t,configurable:!0}),bI=(e,t)=>function(){return e&&(t=(0,e[Ad(e)[0]])(e=0)),t},H=(e,t)=>function(){return t||(0,e[Ad(e)[0]])((t={exports:{}}).exports,t),t.exports},Vr=(e,t)=>{for(var r in t)Ds(e,r,{get:t[r],enumerable:!0})},Ed=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ad(t))!CI.call(e,a)&&a!==r&&Ds(e,a,{get:()=>t[a],enumerable:!(n=AI(t,a))||n.enumerable});return e},Ll=(e,t,r)=>(Ed(e,t,"default"),r),Cd=(e,t,r)=>(r=e!=null?RI(EI(e)):{},Ed(Ds(r,"default",{value:e,enumerable:!0}),e)),bd=e=>Ed(Ds({},"__esModule",{value:!0}),e),Dl={};Vr(Dl,{AnnotatedTextEdit:()=>mr,ChangeAnnotation:()=>an,ChangeAnnotationIdentifier:()=>Ke,CodeAction:()=>ef,CodeActionContext:()=>Qc,CodeActionKind:()=>Zc,CodeActionTriggerKind:()=>Xi,CodeDescription:()=>Nc,CodeLens:()=>tf,Color:()=>Co,ColorInformation:()=>Cc,ColorPresentation:()=>bc,Command:()=>nn,CompletionItem:()=>zc,CompletionItemKind:()=>Lc,CompletionItemLabelDetails:()=>Fc,CompletionItemTag:()=>xc,CompletionList:()=>jc,CreateFile:()=>ya,DeleteFile:()=>va,Diagnostic:()=>Vi,DiagnosticRelatedInformation:()=>bo,DiagnosticSeverity:()=>wc,DiagnosticTag:()=>Ic,DocumentHighlight:()=>Vc,DocumentHighlightKind:()=>Wc,DocumentLink:()=>nf,DocumentSymbol:()=>Jc,DocumentUri:()=>Rc,EOL:()=>zg,FoldingRange:()=>Sc,FoldingRangeKind:()=>_c,FormattingOptions:()=>rf,Hover:()=>Bc,InlayHint:()=>pf,InlayHintKind:()=>wo,InlayHintLabelPart:()=>Io,InlineCompletionContext:()=>Tf,InlineCompletionItem:()=>hf,InlineCompletionList:()=>yf,InlineCompletionTriggerKind:()=>gf,InlineValueContext:()=>df,InlineValueEvaluatableExpression:()=>ff,InlineValueText:()=>uf,InlineValueVariableLookup:()=>cf,InsertReplaceEdit:()=>Mc,InsertTextFormat:()=>Dc,InsertTextMode:()=>Gc,Location:()=>Wi,LocationLink:()=>Ec,MarkedString:()=>Yi,MarkupContent:()=>Ta,MarkupKind:()=>So,OptionalVersionedTextDocumentIdentifier:()=>Hi,ParameterInformation:()=>Uc,Position:()=>ie,Range:()=>Q,RenameFile:()=>ga,SelectedCompletionInfo:()=>vf,SelectionRange:()=>af,SemanticTokenModifiers:()=>of,SemanticTokenTypes:()=>sf,SemanticTokens:()=>lf,SignatureInformation:()=>Kc,StringValue:()=>mf,SymbolInformation:()=>Yc,SymbolKind:()=>qc,SymbolTag:()=>Hc,TextDocument:()=>Rf,TextDocumentEdit:()=>qi,TextDocumentIdentifier:()=>Pc,TextDocumentItem:()=>Oc,TextEdit:()=>Yt,URI:()=>Eo,VersionedTextDocumentIdentifier:()=>kc,WorkspaceChange:()=>Fg,WorkspaceEdit:()=>_o,WorkspaceFolder:()=>$f,WorkspaceSymbol:()=>Xc,integer:()=>Ac,uinteger:()=>Ki});var Rc,Eo,Ac,Ki,ie,Q,Wi,Ec,Co,Cc,bc,_c,Sc,bo,wc,Ic,Nc,Vi,nn,Yt,an,Ke,mr,qi,ya,ga,va,_o,ki,Ku,Fg,Pc,kc,Hi,Oc,So,Ta,Lc,Dc,xc,Mc,Gc,Fc,zc,jc,Yi,Bc,Uc,Kc,Wc,Vc,qc,Hc,Yc,Xc,Jc,Zc,Xi,Qc,ef,tf,rf,nf,af,sf,of,lf,uf,cf,ff,df,wo,Io,pf,mf,hf,yf,gf,vf,Tf,$f,zg,Rf,lh,A,xs=bI({"../../node_modules/.pnpm/vscode-languageserver-types@3.17.5/node_modules/vscode-languageserver-types/lib/esm/main.js"(){(function(e){function t(r){return typeof r=="string"}i(t,"is"),e.is=t})(Rc||(Rc={})),(function(e){function t(r){return typeof r=="string"}i(t,"is"),e.is=t})(Eo||(Eo={})),(function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647;function t(r){return typeof r=="number"&&e.MIN_VALUE<=r&&r<=e.MAX_VALUE}i(t,"is"),e.is=t})(Ac||(Ac={})),(function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647;function t(r){return typeof r=="number"&&e.MIN_VALUE<=r&&r<=e.MAX_VALUE}i(t,"is"),e.is=t})(Ki||(Ki={})),(function(e){function t(n,a){return n===Number.MAX_VALUE&&(n=Ki.MAX_VALUE),a===Number.MAX_VALUE&&(a=Ki.MAX_VALUE),{line:n,character:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&A.uinteger(a.line)&&A.uinteger(a.character)}i(r,"is"),e.is=r})(ie||(ie={})),(function(e){function t(n,a,s,o){if(A.uinteger(n)&&A.uinteger(a)&&A.uinteger(s)&&A.uinteger(o))return{start:ie.create(n,a),end:ie.create(s,o)};if(ie.is(n)&&ie.is(a))return{start:n,end:a};throw new Error(`Range#create called with invalid arguments[${n}, ${a}, ${s}, ${o}]`)}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&ie.is(a.start)&&ie.is(a.end)}i(r,"is"),e.is=r})(Q||(Q={})),(function(e){function t(n,a){return{uri:n,range:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.range)&&(A.string(a.uri)||A.undefined(a.uri))}i(r,"is"),e.is=r})(Wi||(Wi={})),(function(e){function t(n,a,s,o){return{targetUri:n,targetRange:a,targetSelectionRange:s,originSelectionRange:o}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.targetRange)&&A.string(a.targetUri)&&Q.is(a.targetSelectionRange)&&(Q.is(a.originSelectionRange)||A.undefined(a.originSelectionRange))}i(r,"is"),e.is=r})(Ec||(Ec={})),(function(e){function t(n,a,s,o){return{red:n,green:a,blue:s,alpha:o}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.numberRange(a.red,0,1)&&A.numberRange(a.green,0,1)&&A.numberRange(a.blue,0,1)&&A.numberRange(a.alpha,0,1)}i(r,"is"),e.is=r})(Co||(Co={})),(function(e){function t(n,a){return{range:n,color:a}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&Q.is(a.range)&&Co.is(a.color)}i(r,"is"),e.is=r})(Cc||(Cc={})),(function(e){function t(n,a,s){return{label:n,textEdit:a,additionalTextEdits:s}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.string(a.label)&&(A.undefined(a.textEdit)||Yt.is(a))&&(A.undefined(a.additionalTextEdits)||A.typedArray(a.additionalTextEdits,Yt.is))}i(r,"is"),e.is=r})(bc||(bc={})),(function(e){e.Comment="comment",e.Imports="imports",e.Region="region"})(_c||(_c={})),(function(e){function t(n,a,s,o,l,u){const c={startLine:n,endLine:a};return A.defined(s)&&(c.startCharacter=s),A.defined(o)&&(c.endCharacter=o),A.defined(l)&&(c.kind=l),A.defined(u)&&(c.collapsedText=u),c}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.uinteger(a.startLine)&&A.uinteger(a.startLine)&&(A.undefined(a.startCharacter)||A.uinteger(a.startCharacter))&&(A.undefined(a.endCharacter)||A.uinteger(a.endCharacter))&&(A.undefined(a.kind)||A.string(a.kind))}i(r,"is"),e.is=r})(Sc||(Sc={})),(function(e){function t(n,a){return{location:n,message:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Wi.is(a.location)&&A.string(a.message)}i(r,"is"),e.is=r})(bo||(bo={})),(function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4})(wc||(wc={})),(function(e){e.Unnecessary=1,e.Deprecated=2})(Ic||(Ic={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&A.string(n.href)}i(t,"is"),e.is=t})(Nc||(Nc={})),(function(e){function t(n,a,s,o,l,u){let c={range:n,message:a};return A.defined(s)&&(c.severity=s),A.defined(o)&&(c.code=o),A.defined(l)&&(c.source=l),A.defined(u)&&(c.relatedInformation=u),c}i(t,"create"),e.create=t;function r(n){var a;let s=n;return A.defined(s)&&Q.is(s.range)&&A.string(s.message)&&(A.number(s.severity)||A.undefined(s.severity))&&(A.integer(s.code)||A.string(s.code)||A.undefined(s.code))&&(A.undefined(s.codeDescription)||A.string((a=s.codeDescription)===null||a===void 0?void 0:a.href))&&(A.string(s.source)||A.undefined(s.source))&&(A.undefined(s.relatedInformation)||A.typedArray(s.relatedInformation,bo.is))}i(r,"is"),e.is=r})(Vi||(Vi={})),(function(e){function t(n,a,...s){let o={title:n,command:a};return A.defined(s)&&s.length>0&&(o.arguments=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.title)&&A.string(a.command)}i(r,"is"),e.is=r})(nn||(nn={})),(function(e){function t(s,o){return{range:s,newText:o}}i(t,"replace"),e.replace=t;function r(s,o){return{range:{start:s,end:s},newText:o}}i(r,"insert"),e.insert=r;function n(s){return{range:s,newText:""}}i(n,"del"),e.del=n;function a(s){const o=s;return A.objectLiteral(o)&&A.string(o.newText)&&Q.is(o.range)}i(a,"is"),e.is=a})(Yt||(Yt={})),(function(e){function t(n,a,s){const o={label:n};return a!==void 0&&(o.needsConfirmation=a),s!==void 0&&(o.description=s),o}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.string(a.label)&&(A.boolean(a.needsConfirmation)||a.needsConfirmation===void 0)&&(A.string(a.description)||a.description===void 0)}i(r,"is"),e.is=r})(an||(an={})),(function(e){function t(r){const n=r;return A.string(n)}i(t,"is"),e.is=t})(Ke||(Ke={})),(function(e){function t(s,o,l){return{range:s,newText:o,annotationId:l}}i(t,"replace"),e.replace=t;function r(s,o,l){return{range:{start:s,end:s},newText:o,annotationId:l}}i(r,"insert"),e.insert=r;function n(s,o){return{range:s,newText:"",annotationId:o}}i(n,"del"),e.del=n;function a(s){const o=s;return Yt.is(o)&&(an.is(o.annotationId)||Ke.is(o.annotationId))}i(a,"is"),e.is=a})(mr||(mr={})),(function(e){function t(n,a){return{textDocument:n,edits:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Hi.is(a.textDocument)&&Array.isArray(a.edits)}i(r,"is"),e.is=r})(qi||(qi={})),(function(e){function t(n,a,s){let o={kind:"create",uri:n};return a!==void 0&&(a.overwrite!==void 0||a.ignoreIfExists!==void 0)&&(o.options=a),s!==void 0&&(o.annotationId=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="create"&&A.string(a.uri)&&(a.options===void 0||(a.options.overwrite===void 0||A.boolean(a.options.overwrite))&&(a.options.ignoreIfExists===void 0||A.boolean(a.options.ignoreIfExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(ya||(ya={})),(function(e){function t(n,a,s,o){let l={kind:"rename",oldUri:n,newUri:a};return s!==void 0&&(s.overwrite!==void 0||s.ignoreIfExists!==void 0)&&(l.options=s),o!==void 0&&(l.annotationId=o),l}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="rename"&&A.string(a.oldUri)&&A.string(a.newUri)&&(a.options===void 0||(a.options.overwrite===void 0||A.boolean(a.options.overwrite))&&(a.options.ignoreIfExists===void 0||A.boolean(a.options.ignoreIfExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(ga||(ga={})),(function(e){function t(n,a,s){let o={kind:"delete",uri:n};return a!==void 0&&(a.recursive!==void 0||a.ignoreIfNotExists!==void 0)&&(o.options=a),s!==void 0&&(o.annotationId=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="delete"&&A.string(a.uri)&&(a.options===void 0||(a.options.recursive===void 0||A.boolean(a.options.recursive))&&(a.options.ignoreIfNotExists===void 0||A.boolean(a.options.ignoreIfNotExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(va||(va={})),(function(e){function t(r){let n=r;return n&&(n.changes!==void 0||n.documentChanges!==void 0)&&(n.documentChanges===void 0||n.documentChanges.every(a=>A.string(a.kind)?ya.is(a)||ga.is(a)||va.is(a):qi.is(a)))}i(t,"is"),e.is=t})(_o||(_o={})),ki=class{static{i(this,"TextEditChangeImpl")}constructor(e,t){this.edits=e,this.changeAnnotations=t}insert(e,t,r){let n,a;if(r===void 0?n=Yt.insert(e,t):Ke.is(r)?(a=r,n=mr.insert(e,t,r)):(this.assertChangeAnnotations(this.changeAnnotations),a=this.changeAnnotations.manage(r),n=mr.insert(e,t,a)),this.edits.push(n),a!==void 0)return a}replace(e,t,r){let n,a;if(r===void 0?n=Yt.replace(e,t):Ke.is(r)?(a=r,n=mr.replace(e,t,r)):(this.assertChangeAnnotations(this.changeAnnotations),a=this.changeAnnotations.manage(r),n=mr.replace(e,t,a)),this.edits.push(n),a!==void 0)return a}delete(e,t){let r,n;if(t===void 0?r=Yt.del(e):Ke.is(t)?(n=t,r=mr.del(e,t)):(this.assertChangeAnnotations(this.changeAnnotations),n=this.changeAnnotations.manage(t),r=mr.del(e,n)),this.edits.push(r),n!==void 0)return n}add(e){this.edits.push(e)}all(){return this.edits}clear(){this.edits.splice(0,this.edits.length)}assertChangeAnnotations(e){if(e===void 0)throw new Error("Text edit change is not configured to manage change annotations.")}},Ku=class{static{i(this,"ChangeAnnotations")}constructor(e){this._annotations=e===void 0?Object.create(null):e,this._counter=0,this._size=0}all(){return this._annotations}get size(){return this._size}manage(e,t){let r;if(Ke.is(e)?r=e:(r=this.nextId(),t=e),this._annotations[r]!==void 0)throw new Error(`Id ${r} is already in use.`);if(t===void 0)throw new Error(`No annotation provided for id ${r}`);return this._annotations[r]=t,this._size++,r}nextId(){return this._counter++,this._counter.toString()}},Fg=class{static{i(this,"WorkspaceChange")}constructor(e){this._textEditChanges=Object.create(null),e!==void 0?(this._workspaceEdit=e,e.documentChanges?(this._changeAnnotations=new Ku(e.changeAnnotations),e.changeAnnotations=this._changeAnnotations.all(),e.documentChanges.forEach(t=>{if(qi.is(t)){const r=new ki(t.edits,this._changeAnnotations);this._textEditChanges[t.textDocument.uri]=r}})):e.changes&&Object.keys(e.changes).forEach(t=>{const r=new ki(e.changes[t]);this._textEditChanges[t]=r})):this._workspaceEdit={}}get edit(){return this.initDocumentChanges(),this._changeAnnotations!==void 0&&(this._changeAnnotations.size===0?this._workspaceEdit.changeAnnotations=void 0:this._workspaceEdit.changeAnnotations=this._changeAnnotations.all()),this._workspaceEdit}getTextEditChange(e){if(Hi.is(e)){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");const t={uri:e.uri,version:e.version};let r=this._textEditChanges[t.uri];if(!r){const n=[],a={textDocument:t,edits:n};this._workspaceEdit.documentChanges.push(a),r=new ki(n,this._changeAnnotations),this._textEditChanges[t.uri]=r}return r}else{if(this.initChanges(),this._workspaceEdit.changes===void 0)throw new Error("Workspace edit is not configured for normal text edit changes.");let t=this._textEditChanges[e];if(!t){let r=[];this._workspaceEdit.changes[e]=r,t=new ki(r),this._textEditChanges[e]=t}return t}}initDocumentChanges(){this._workspaceEdit.documentChanges===void 0&&this._workspaceEdit.changes===void 0&&(this._changeAnnotations=new Ku,this._workspaceEdit.documentChanges=[],this._workspaceEdit.changeAnnotations=this._changeAnnotations.all())}initChanges(){this._workspaceEdit.documentChanges===void 0&&this._workspaceEdit.changes===void 0&&(this._workspaceEdit.changes=Object.create(null))}createFile(e,t,r){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let n;an.is(t)||Ke.is(t)?n=t:r=t;let a,s;if(n===void 0?a=ya.create(e,r):(s=Ke.is(n)?n:this._changeAnnotations.manage(n),a=ya.create(e,r,s)),this._workspaceEdit.documentChanges.push(a),s!==void 0)return s}renameFile(e,t,r,n){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let a;an.is(r)||Ke.is(r)?a=r:n=r;let s,o;if(a===void 0?s=ga.create(e,t,n):(o=Ke.is(a)?a:this._changeAnnotations.manage(a),s=ga.create(e,t,n,o)),this._workspaceEdit.documentChanges.push(s),o!==void 0)return o}deleteFile(e,t,r){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let n;an.is(t)||Ke.is(t)?n=t:r=t;let a,s;if(n===void 0?a=va.create(e,r):(s=Ke.is(n)?n:this._changeAnnotations.manage(n),a=va.create(e,r,s)),this._workspaceEdit.documentChanges.push(a),s!==void 0)return s}},(function(e){function t(n){return{uri:n}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)}i(r,"is"),e.is=r})(Pc||(Pc={})),(function(e){function t(n,a){return{uri:n,version:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&A.integer(a.version)}i(r,"is"),e.is=r})(kc||(kc={})),(function(e){function t(n,a){return{uri:n,version:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&(a.version===null||A.integer(a.version))}i(r,"is"),e.is=r})(Hi||(Hi={})),(function(e){function t(n,a,s,o){return{uri:n,languageId:a,version:s,text:o}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&A.string(a.languageId)&&A.integer(a.version)&&A.string(a.text)}i(r,"is"),e.is=r})(Oc||(Oc={})),(function(e){e.PlainText="plaintext",e.Markdown="markdown";function t(r){const n=r;return n===e.PlainText||n===e.Markdown}i(t,"is"),e.is=t})(So||(So={})),(function(e){function t(r){const n=r;return A.objectLiteral(r)&&So.is(n.kind)&&A.string(n.value)}i(t,"is"),e.is=t})(Ta||(Ta={})),(function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25})(Lc||(Lc={})),(function(e){e.PlainText=1,e.Snippet=2})(Dc||(Dc={})),(function(e){e.Deprecated=1})(xc||(xc={})),(function(e){function t(n,a,s){return{newText:n,insert:a,replace:s}}i(t,"create"),e.create=t;function r(n){const a=n;return a&&A.string(a.newText)&&Q.is(a.insert)&&Q.is(a.replace)}i(r,"is"),e.is=r})(Mc||(Mc={})),(function(e){e.asIs=1,e.adjustIndentation=2})(Gc||(Gc={})),(function(e){function t(r){const n=r;return n&&(A.string(n.detail)||n.detail===void 0)&&(A.string(n.description)||n.description===void 0)}i(t,"is"),e.is=t})(Fc||(Fc={})),(function(e){function t(r){return{label:r}}i(t,"create"),e.create=t})(zc||(zc={})),(function(e){function t(r,n){return{items:r||[],isIncomplete:!!n}}i(t,"create"),e.create=t})(jc||(jc={})),(function(e){function t(n){return n.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}i(t,"fromPlainText"),e.fromPlainText=t;function r(n){const a=n;return A.string(a)||A.objectLiteral(a)&&A.string(a.language)&&A.string(a.value)}i(r,"is"),e.is=r})(Yi||(Yi={})),(function(e){function t(r){let n=r;return!!n&&A.objectLiteral(n)&&(Ta.is(n.contents)||Yi.is(n.contents)||A.typedArray(n.contents,Yi.is))&&(r.range===void 0||Q.is(r.range))}i(t,"is"),e.is=t})(Bc||(Bc={})),(function(e){function t(r,n){return n?{label:r,documentation:n}:{label:r}}i(t,"create"),e.create=t})(Uc||(Uc={})),(function(e){function t(r,n,...a){let s={label:r};return A.defined(n)&&(s.documentation=n),A.defined(a)?s.parameters=a:s.parameters=[],s}i(t,"create"),e.create=t})(Kc||(Kc={})),(function(e){e.Text=1,e.Read=2,e.Write=3})(Wc||(Wc={})),(function(e){function t(r,n){let a={range:r};return A.number(n)&&(a.kind=n),a}i(t,"create"),e.create=t})(Vc||(Vc={})),(function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26})(qc||(qc={})),(function(e){e.Deprecated=1})(Hc||(Hc={})),(function(e){function t(r,n,a,s,o){let l={name:r,kind:n,location:{uri:s,range:a}};return o&&(l.containerName=o),l}i(t,"create"),e.create=t})(Yc||(Yc={})),(function(e){function t(r,n,a,s){return s!==void 0?{name:r,kind:n,location:{uri:a,range:s}}:{name:r,kind:n,location:{uri:a}}}i(t,"create"),e.create=t})(Xc||(Xc={})),(function(e){function t(n,a,s,o,l,u){let c={name:n,detail:a,kind:s,range:o,selectionRange:l};return u!==void 0&&(c.children=u),c}i(t,"create"),e.create=t;function r(n){let a=n;return a&&A.string(a.name)&&A.number(a.kind)&&Q.is(a.range)&&Q.is(a.selectionRange)&&(a.detail===void 0||A.string(a.detail))&&(a.deprecated===void 0||A.boolean(a.deprecated))&&(a.children===void 0||Array.isArray(a.children))&&(a.tags===void 0||Array.isArray(a.tags))}i(r,"is"),e.is=r})(Jc||(Jc={})),(function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"})(Zc||(Zc={})),(function(e){e.Invoked=1,e.Automatic=2})(Xi||(Xi={})),(function(e){function t(n,a,s){let o={diagnostics:n};return a!=null&&(o.only=a),s!=null&&(o.triggerKind=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.typedArray(a.diagnostics,Vi.is)&&(a.only===void 0||A.typedArray(a.only,A.string))&&(a.triggerKind===void 0||a.triggerKind===Xi.Invoked||a.triggerKind===Xi.Automatic)}i(r,"is"),e.is=r})(Qc||(Qc={})),(function(e){function t(n,a,s){let o={title:n},l=!0;return typeof a=="string"?(l=!1,o.kind=a):nn.is(a)?o.command=a:o.edit=a,l&&s!==void 0&&(o.kind=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&A.string(a.title)&&(a.diagnostics===void 0||A.typedArray(a.diagnostics,Vi.is))&&(a.kind===void 0||A.string(a.kind))&&(a.edit!==void 0||a.command!==void 0)&&(a.command===void 0||nn.is(a.command))&&(a.isPreferred===void 0||A.boolean(a.isPreferred))&&(a.edit===void 0||_o.is(a.edit))}i(r,"is"),e.is=r})(ef||(ef={})),(function(e){function t(n,a){let s={range:n};return A.defined(a)&&(s.data=a),s}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Q.is(a.range)&&(A.undefined(a.command)||nn.is(a.command))}i(r,"is"),e.is=r})(tf||(tf={})),(function(e){function t(n,a){return{tabSize:n,insertSpaces:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.uinteger(a.tabSize)&&A.boolean(a.insertSpaces)}i(r,"is"),e.is=r})(rf||(rf={})),(function(e){function t(n,a,s){return{range:n,target:a,data:s}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Q.is(a.range)&&(A.undefined(a.target)||A.string(a.target))}i(r,"is"),e.is=r})(nf||(nf={})),(function(e){function t(n,a){return{range:n,parent:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.range)&&(a.parent===void 0||e.is(a.parent))}i(r,"is"),e.is=r})(af||(af={})),(function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"})(sf||(sf={})),(function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"})(of||(of={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&(n.resultId===void 0||typeof n.resultId=="string")&&Array.isArray(n.data)&&(n.data.length===0||typeof n.data[0]=="number")}i(t,"is"),e.is=t})(lf||(lf={})),(function(e){function t(n,a){return{range:n,text:a}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&A.string(a.text)}i(r,"is"),e.is=r})(uf||(uf={})),(function(e){function t(n,a,s){return{range:n,variableName:a,caseSensitiveLookup:s}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&A.boolean(a.caseSensitiveLookup)&&(A.string(a.variableName)||a.variableName===void 0)}i(r,"is"),e.is=r})(cf||(cf={})),(function(e){function t(n,a){return{range:n,expression:a}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&(A.string(a.expression)||a.expression===void 0)}i(r,"is"),e.is=r})(ff||(ff={})),(function(e){function t(n,a){return{frameId:n,stoppedLocation:a}}i(t,"create"),e.create=t;function r(n){const a=n;return A.defined(a)&&Q.is(n.stoppedLocation)}i(r,"is"),e.is=r})(df||(df={})),(function(e){e.Type=1,e.Parameter=2;function t(r){return r===1||r===2}i(t,"is"),e.is=t})(wo||(wo={})),(function(e){function t(n){return{value:n}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&(a.tooltip===void 0||A.string(a.tooltip)||Ta.is(a.tooltip))&&(a.location===void 0||Wi.is(a.location))&&(a.command===void 0||nn.is(a.command))}i(r,"is"),e.is=r})(Io||(Io={})),(function(e){function t(n,a,s){const o={position:n,label:a};return s!==void 0&&(o.kind=s),o}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&ie.is(a.position)&&(A.string(a.label)||A.typedArray(a.label,Io.is))&&(a.kind===void 0||wo.is(a.kind))&&a.textEdits===void 0||A.typedArray(a.textEdits,Yt.is)&&(a.tooltip===void 0||A.string(a.tooltip)||Ta.is(a.tooltip))&&(a.paddingLeft===void 0||A.boolean(a.paddingLeft))&&(a.paddingRight===void 0||A.boolean(a.paddingRight))}i(r,"is"),e.is=r})(pf||(pf={})),(function(e){function t(r){return{kind:"snippet",value:r}}i(t,"createSnippet"),e.createSnippet=t})(mf||(mf={})),(function(e){function t(r,n,a,s){return{insertText:r,filterText:n,range:a,command:s}}i(t,"create"),e.create=t})(hf||(hf={})),(function(e){function t(r){return{items:r}}i(t,"create"),e.create=t})(yf||(yf={})),(function(e){e.Invoked=0,e.Automatic=1})(gf||(gf={})),(function(e){function t(r,n){return{range:r,text:n}}i(t,"create"),e.create=t})(vf||(vf={})),(function(e){function t(r,n){return{triggerKind:r,selectedCompletionInfo:n}}i(t,"create"),e.create=t})(Tf||(Tf={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&Eo.is(n.uri)&&A.string(n.name)}i(t,"is"),e.is=t})($f||($f={})),zg=[` +import{bR as et}from"./index-D-7nOosq.js";var RI=Object.create,Ds=Object.defineProperty,AI=Object.getOwnPropertyDescriptor,Ad=Object.getOwnPropertyNames,EI=Object.getPrototypeOf,CI=Object.prototype.hasOwnProperty,i=(e,t)=>Ds(e,"name",{value:t,configurable:!0}),bI=(e,t)=>function(){return e&&(t=(0,e[Ad(e)[0]])(e=0)),t},H=(e,t)=>function(){return t||(0,e[Ad(e)[0]])((t={exports:{}}).exports,t),t.exports},Vr=(e,t)=>{for(var r in t)Ds(e,r,{get:t[r],enumerable:!0})},Ed=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of Ad(t))!CI.call(e,a)&&a!==r&&Ds(e,a,{get:()=>t[a],enumerable:!(n=AI(t,a))||n.enumerable});return e},Ll=(e,t,r)=>(Ed(e,t,"default"),r),Cd=(e,t,r)=>(r=e!=null?RI(EI(e)):{},Ed(Ds(r,"default",{value:e,enumerable:!0}),e)),bd=e=>Ed(Ds({},"__esModule",{value:!0}),e),Dl={};Vr(Dl,{AnnotatedTextEdit:()=>mr,ChangeAnnotation:()=>an,ChangeAnnotationIdentifier:()=>Ke,CodeAction:()=>ef,CodeActionContext:()=>Qc,CodeActionKind:()=>Zc,CodeActionTriggerKind:()=>Xi,CodeDescription:()=>Nc,CodeLens:()=>tf,Color:()=>Co,ColorInformation:()=>Cc,ColorPresentation:()=>bc,Command:()=>nn,CompletionItem:()=>zc,CompletionItemKind:()=>Lc,CompletionItemLabelDetails:()=>Fc,CompletionItemTag:()=>xc,CompletionList:()=>jc,CreateFile:()=>ya,DeleteFile:()=>va,Diagnostic:()=>Vi,DiagnosticRelatedInformation:()=>bo,DiagnosticSeverity:()=>wc,DiagnosticTag:()=>Ic,DocumentHighlight:()=>Vc,DocumentHighlightKind:()=>Wc,DocumentLink:()=>nf,DocumentSymbol:()=>Jc,DocumentUri:()=>Rc,EOL:()=>zg,FoldingRange:()=>Sc,FoldingRangeKind:()=>_c,FormattingOptions:()=>rf,Hover:()=>Bc,InlayHint:()=>pf,InlayHintKind:()=>wo,InlayHintLabelPart:()=>Io,InlineCompletionContext:()=>Tf,InlineCompletionItem:()=>hf,InlineCompletionList:()=>yf,InlineCompletionTriggerKind:()=>gf,InlineValueContext:()=>df,InlineValueEvaluatableExpression:()=>ff,InlineValueText:()=>uf,InlineValueVariableLookup:()=>cf,InsertReplaceEdit:()=>Mc,InsertTextFormat:()=>Dc,InsertTextMode:()=>Gc,Location:()=>Wi,LocationLink:()=>Ec,MarkedString:()=>Yi,MarkupContent:()=>Ta,MarkupKind:()=>So,OptionalVersionedTextDocumentIdentifier:()=>Hi,ParameterInformation:()=>Uc,Position:()=>ie,Range:()=>Q,RenameFile:()=>ga,SelectedCompletionInfo:()=>vf,SelectionRange:()=>af,SemanticTokenModifiers:()=>of,SemanticTokenTypes:()=>sf,SemanticTokens:()=>lf,SignatureInformation:()=>Kc,StringValue:()=>mf,SymbolInformation:()=>Yc,SymbolKind:()=>qc,SymbolTag:()=>Hc,TextDocument:()=>Rf,TextDocumentEdit:()=>qi,TextDocumentIdentifier:()=>Pc,TextDocumentItem:()=>Oc,TextEdit:()=>Yt,URI:()=>Eo,VersionedTextDocumentIdentifier:()=>kc,WorkspaceChange:()=>Fg,WorkspaceEdit:()=>_o,WorkspaceFolder:()=>$f,WorkspaceSymbol:()=>Xc,integer:()=>Ac,uinteger:()=>Ki});var Rc,Eo,Ac,Ki,ie,Q,Wi,Ec,Co,Cc,bc,_c,Sc,bo,wc,Ic,Nc,Vi,nn,Yt,an,Ke,mr,qi,ya,ga,va,_o,ki,Ku,Fg,Pc,kc,Hi,Oc,So,Ta,Lc,Dc,xc,Mc,Gc,Fc,zc,jc,Yi,Bc,Uc,Kc,Wc,Vc,qc,Hc,Yc,Xc,Jc,Zc,Xi,Qc,ef,tf,rf,nf,af,sf,of,lf,uf,cf,ff,df,wo,Io,pf,mf,hf,yf,gf,vf,Tf,$f,zg,Rf,lh,A,xs=bI({"../../node_modules/.pnpm/vscode-languageserver-types@3.17.5/node_modules/vscode-languageserver-types/lib/esm/main.js"(){(function(e){function t(r){return typeof r=="string"}i(t,"is"),e.is=t})(Rc||(Rc={})),(function(e){function t(r){return typeof r=="string"}i(t,"is"),e.is=t})(Eo||(Eo={})),(function(e){e.MIN_VALUE=-2147483648,e.MAX_VALUE=2147483647;function t(r){return typeof r=="number"&&e.MIN_VALUE<=r&&r<=e.MAX_VALUE}i(t,"is"),e.is=t})(Ac||(Ac={})),(function(e){e.MIN_VALUE=0,e.MAX_VALUE=2147483647;function t(r){return typeof r=="number"&&e.MIN_VALUE<=r&&r<=e.MAX_VALUE}i(t,"is"),e.is=t})(Ki||(Ki={})),(function(e){function t(n,a){return n===Number.MAX_VALUE&&(n=Ki.MAX_VALUE),a===Number.MAX_VALUE&&(a=Ki.MAX_VALUE),{line:n,character:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&A.uinteger(a.line)&&A.uinteger(a.character)}i(r,"is"),e.is=r})(ie||(ie={})),(function(e){function t(n,a,s,o){if(A.uinteger(n)&&A.uinteger(a)&&A.uinteger(s)&&A.uinteger(o))return{start:ie.create(n,a),end:ie.create(s,o)};if(ie.is(n)&&ie.is(a))return{start:n,end:a};throw new Error(`Range#create called with invalid arguments[${n}, ${a}, ${s}, ${o}]`)}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&ie.is(a.start)&&ie.is(a.end)}i(r,"is"),e.is=r})(Q||(Q={})),(function(e){function t(n,a){return{uri:n,range:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.range)&&(A.string(a.uri)||A.undefined(a.uri))}i(r,"is"),e.is=r})(Wi||(Wi={})),(function(e){function t(n,a,s,o){return{targetUri:n,targetRange:a,targetSelectionRange:s,originSelectionRange:o}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.targetRange)&&A.string(a.targetUri)&&Q.is(a.targetSelectionRange)&&(Q.is(a.originSelectionRange)||A.undefined(a.originSelectionRange))}i(r,"is"),e.is=r})(Ec||(Ec={})),(function(e){function t(n,a,s,o){return{red:n,green:a,blue:s,alpha:o}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.numberRange(a.red,0,1)&&A.numberRange(a.green,0,1)&&A.numberRange(a.blue,0,1)&&A.numberRange(a.alpha,0,1)}i(r,"is"),e.is=r})(Co||(Co={})),(function(e){function t(n,a){return{range:n,color:a}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&Q.is(a.range)&&Co.is(a.color)}i(r,"is"),e.is=r})(Cc||(Cc={})),(function(e){function t(n,a,s){return{label:n,textEdit:a,additionalTextEdits:s}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.string(a.label)&&(A.undefined(a.textEdit)||Yt.is(a))&&(A.undefined(a.additionalTextEdits)||A.typedArray(a.additionalTextEdits,Yt.is))}i(r,"is"),e.is=r})(bc||(bc={})),(function(e){e.Comment="comment",e.Imports="imports",e.Region="region"})(_c||(_c={})),(function(e){function t(n,a,s,o,l,u){const c={startLine:n,endLine:a};return A.defined(s)&&(c.startCharacter=s),A.defined(o)&&(c.endCharacter=o),A.defined(l)&&(c.kind=l),A.defined(u)&&(c.collapsedText=u),c}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.uinteger(a.startLine)&&A.uinteger(a.startLine)&&(A.undefined(a.startCharacter)||A.uinteger(a.startCharacter))&&(A.undefined(a.endCharacter)||A.uinteger(a.endCharacter))&&(A.undefined(a.kind)||A.string(a.kind))}i(r,"is"),e.is=r})(Sc||(Sc={})),(function(e){function t(n,a){return{location:n,message:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Wi.is(a.location)&&A.string(a.message)}i(r,"is"),e.is=r})(bo||(bo={})),(function(e){e.Error=1,e.Warning=2,e.Information=3,e.Hint=4})(wc||(wc={})),(function(e){e.Unnecessary=1,e.Deprecated=2})(Ic||(Ic={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&A.string(n.href)}i(t,"is"),e.is=t})(Nc||(Nc={})),(function(e){function t(n,a,s,o,l,u){let c={range:n,message:a};return A.defined(s)&&(c.severity=s),A.defined(o)&&(c.code=o),A.defined(l)&&(c.source=l),A.defined(u)&&(c.relatedInformation=u),c}i(t,"create"),e.create=t;function r(n){var a;let s=n;return A.defined(s)&&Q.is(s.range)&&A.string(s.message)&&(A.number(s.severity)||A.undefined(s.severity))&&(A.integer(s.code)||A.string(s.code)||A.undefined(s.code))&&(A.undefined(s.codeDescription)||A.string((a=s.codeDescription)===null||a===void 0?void 0:a.href))&&(A.string(s.source)||A.undefined(s.source))&&(A.undefined(s.relatedInformation)||A.typedArray(s.relatedInformation,bo.is))}i(r,"is"),e.is=r})(Vi||(Vi={})),(function(e){function t(n,a,...s){let o={title:n,command:a};return A.defined(s)&&s.length>0&&(o.arguments=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.title)&&A.string(a.command)}i(r,"is"),e.is=r})(nn||(nn={})),(function(e){function t(s,o){return{range:s,newText:o}}i(t,"replace"),e.replace=t;function r(s,o){return{range:{start:s,end:s},newText:o}}i(r,"insert"),e.insert=r;function n(s){return{range:s,newText:""}}i(n,"del"),e.del=n;function a(s){const o=s;return A.objectLiteral(o)&&A.string(o.newText)&&Q.is(o.range)}i(a,"is"),e.is=a})(Yt||(Yt={})),(function(e){function t(n,a,s){const o={label:n};return a!==void 0&&(o.needsConfirmation=a),s!==void 0&&(o.description=s),o}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&A.string(a.label)&&(A.boolean(a.needsConfirmation)||a.needsConfirmation===void 0)&&(A.string(a.description)||a.description===void 0)}i(r,"is"),e.is=r})(an||(an={})),(function(e){function t(r){const n=r;return A.string(n)}i(t,"is"),e.is=t})(Ke||(Ke={})),(function(e){function t(s,o,l){return{range:s,newText:o,annotationId:l}}i(t,"replace"),e.replace=t;function r(s,o,l){return{range:{start:s,end:s},newText:o,annotationId:l}}i(r,"insert"),e.insert=r;function n(s,o){return{range:s,newText:"",annotationId:o}}i(n,"del"),e.del=n;function a(s){const o=s;return Yt.is(o)&&(an.is(o.annotationId)||Ke.is(o.annotationId))}i(a,"is"),e.is=a})(mr||(mr={})),(function(e){function t(n,a){return{textDocument:n,edits:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Hi.is(a.textDocument)&&Array.isArray(a.edits)}i(r,"is"),e.is=r})(qi||(qi={})),(function(e){function t(n,a,s){let o={kind:"create",uri:n};return a!==void 0&&(a.overwrite!==void 0||a.ignoreIfExists!==void 0)&&(o.options=a),s!==void 0&&(o.annotationId=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="create"&&A.string(a.uri)&&(a.options===void 0||(a.options.overwrite===void 0||A.boolean(a.options.overwrite))&&(a.options.ignoreIfExists===void 0||A.boolean(a.options.ignoreIfExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(ya||(ya={})),(function(e){function t(n,a,s,o){let l={kind:"rename",oldUri:n,newUri:a};return s!==void 0&&(s.overwrite!==void 0||s.ignoreIfExists!==void 0)&&(l.options=s),o!==void 0&&(l.annotationId=o),l}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="rename"&&A.string(a.oldUri)&&A.string(a.newUri)&&(a.options===void 0||(a.options.overwrite===void 0||A.boolean(a.options.overwrite))&&(a.options.ignoreIfExists===void 0||A.boolean(a.options.ignoreIfExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(ga||(ga={})),(function(e){function t(n,a,s){let o={kind:"delete",uri:n};return a!==void 0&&(a.recursive!==void 0||a.ignoreIfNotExists!==void 0)&&(o.options=a),s!==void 0&&(o.annotationId=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&a.kind==="delete"&&A.string(a.uri)&&(a.options===void 0||(a.options.recursive===void 0||A.boolean(a.options.recursive))&&(a.options.ignoreIfNotExists===void 0||A.boolean(a.options.ignoreIfNotExists)))&&(a.annotationId===void 0||Ke.is(a.annotationId))}i(r,"is"),e.is=r})(va||(va={})),(function(e){function t(r){let n=r;return n&&(n.changes!==void 0||n.documentChanges!==void 0)&&(n.documentChanges===void 0||n.documentChanges.every(a=>A.string(a.kind)?ya.is(a)||ga.is(a)||va.is(a):qi.is(a)))}i(t,"is"),e.is=t})(_o||(_o={})),ki=class{static{i(this,"TextEditChangeImpl")}constructor(e,t){this.edits=e,this.changeAnnotations=t}insert(e,t,r){let n,a;if(r===void 0?n=Yt.insert(e,t):Ke.is(r)?(a=r,n=mr.insert(e,t,r)):(this.assertChangeAnnotations(this.changeAnnotations),a=this.changeAnnotations.manage(r),n=mr.insert(e,t,a)),this.edits.push(n),a!==void 0)return a}replace(e,t,r){let n,a;if(r===void 0?n=Yt.replace(e,t):Ke.is(r)?(a=r,n=mr.replace(e,t,r)):(this.assertChangeAnnotations(this.changeAnnotations),a=this.changeAnnotations.manage(r),n=mr.replace(e,t,a)),this.edits.push(n),a!==void 0)return a}delete(e,t){let r,n;if(t===void 0?r=Yt.del(e):Ke.is(t)?(n=t,r=mr.del(e,t)):(this.assertChangeAnnotations(this.changeAnnotations),n=this.changeAnnotations.manage(t),r=mr.del(e,n)),this.edits.push(r),n!==void 0)return n}add(e){this.edits.push(e)}all(){return this.edits}clear(){this.edits.splice(0,this.edits.length)}assertChangeAnnotations(e){if(e===void 0)throw new Error("Text edit change is not configured to manage change annotations.")}},Ku=class{static{i(this,"ChangeAnnotations")}constructor(e){this._annotations=e===void 0?Object.create(null):e,this._counter=0,this._size=0}all(){return this._annotations}get size(){return this._size}manage(e,t){let r;if(Ke.is(e)?r=e:(r=this.nextId(),t=e),this._annotations[r]!==void 0)throw new Error(`Id ${r} is already in use.`);if(t===void 0)throw new Error(`No annotation provided for id ${r}`);return this._annotations[r]=t,this._size++,r}nextId(){return this._counter++,this._counter.toString()}},Fg=class{static{i(this,"WorkspaceChange")}constructor(e){this._textEditChanges=Object.create(null),e!==void 0?(this._workspaceEdit=e,e.documentChanges?(this._changeAnnotations=new Ku(e.changeAnnotations),e.changeAnnotations=this._changeAnnotations.all(),e.documentChanges.forEach(t=>{if(qi.is(t)){const r=new ki(t.edits,this._changeAnnotations);this._textEditChanges[t.textDocument.uri]=r}})):e.changes&&Object.keys(e.changes).forEach(t=>{const r=new ki(e.changes[t]);this._textEditChanges[t]=r})):this._workspaceEdit={}}get edit(){return this.initDocumentChanges(),this._changeAnnotations!==void 0&&(this._changeAnnotations.size===0?this._workspaceEdit.changeAnnotations=void 0:this._workspaceEdit.changeAnnotations=this._changeAnnotations.all()),this._workspaceEdit}getTextEditChange(e){if(Hi.is(e)){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");const t={uri:e.uri,version:e.version};let r=this._textEditChanges[t.uri];if(!r){const n=[],a={textDocument:t,edits:n};this._workspaceEdit.documentChanges.push(a),r=new ki(n,this._changeAnnotations),this._textEditChanges[t.uri]=r}return r}else{if(this.initChanges(),this._workspaceEdit.changes===void 0)throw new Error("Workspace edit is not configured for normal text edit changes.");let t=this._textEditChanges[e];if(!t){let r=[];this._workspaceEdit.changes[e]=r,t=new ki(r),this._textEditChanges[e]=t}return t}}initDocumentChanges(){this._workspaceEdit.documentChanges===void 0&&this._workspaceEdit.changes===void 0&&(this._changeAnnotations=new Ku,this._workspaceEdit.documentChanges=[],this._workspaceEdit.changeAnnotations=this._changeAnnotations.all())}initChanges(){this._workspaceEdit.documentChanges===void 0&&this._workspaceEdit.changes===void 0&&(this._workspaceEdit.changes=Object.create(null))}createFile(e,t,r){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let n;an.is(t)||Ke.is(t)?n=t:r=t;let a,s;if(n===void 0?a=ya.create(e,r):(s=Ke.is(n)?n:this._changeAnnotations.manage(n),a=ya.create(e,r,s)),this._workspaceEdit.documentChanges.push(a),s!==void 0)return s}renameFile(e,t,r,n){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let a;an.is(r)||Ke.is(r)?a=r:n=r;let s,o;if(a===void 0?s=ga.create(e,t,n):(o=Ke.is(a)?a:this._changeAnnotations.manage(a),s=ga.create(e,t,n,o)),this._workspaceEdit.documentChanges.push(s),o!==void 0)return o}deleteFile(e,t,r){if(this.initDocumentChanges(),this._workspaceEdit.documentChanges===void 0)throw new Error("Workspace edit is not configured for document changes.");let n;an.is(t)||Ke.is(t)?n=t:r=t;let a,s;if(n===void 0?a=va.create(e,r):(s=Ke.is(n)?n:this._changeAnnotations.manage(n),a=va.create(e,r,s)),this._workspaceEdit.documentChanges.push(a),s!==void 0)return s}},(function(e){function t(n){return{uri:n}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)}i(r,"is"),e.is=r})(Pc||(Pc={})),(function(e){function t(n,a){return{uri:n,version:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&A.integer(a.version)}i(r,"is"),e.is=r})(kc||(kc={})),(function(e){function t(n,a){return{uri:n,version:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&(a.version===null||A.integer(a.version))}i(r,"is"),e.is=r})(Hi||(Hi={})),(function(e){function t(n,a,s,o){return{uri:n,languageId:a,version:s,text:o}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.string(a.uri)&&A.string(a.languageId)&&A.integer(a.version)&&A.string(a.text)}i(r,"is"),e.is=r})(Oc||(Oc={})),(function(e){e.PlainText="plaintext",e.Markdown="markdown";function t(r){const n=r;return n===e.PlainText||n===e.Markdown}i(t,"is"),e.is=t})(So||(So={})),(function(e){function t(r){const n=r;return A.objectLiteral(r)&&So.is(n.kind)&&A.string(n.value)}i(t,"is"),e.is=t})(Ta||(Ta={})),(function(e){e.Text=1,e.Method=2,e.Function=3,e.Constructor=4,e.Field=5,e.Variable=6,e.Class=7,e.Interface=8,e.Module=9,e.Property=10,e.Unit=11,e.Value=12,e.Enum=13,e.Keyword=14,e.Snippet=15,e.Color=16,e.File=17,e.Reference=18,e.Folder=19,e.EnumMember=20,e.Constant=21,e.Struct=22,e.Event=23,e.Operator=24,e.TypeParameter=25})(Lc||(Lc={})),(function(e){e.PlainText=1,e.Snippet=2})(Dc||(Dc={})),(function(e){e.Deprecated=1})(xc||(xc={})),(function(e){function t(n,a,s){return{newText:n,insert:a,replace:s}}i(t,"create"),e.create=t;function r(n){const a=n;return a&&A.string(a.newText)&&Q.is(a.insert)&&Q.is(a.replace)}i(r,"is"),e.is=r})(Mc||(Mc={})),(function(e){e.asIs=1,e.adjustIndentation=2})(Gc||(Gc={})),(function(e){function t(r){const n=r;return n&&(A.string(n.detail)||n.detail===void 0)&&(A.string(n.description)||n.description===void 0)}i(t,"is"),e.is=t})(Fc||(Fc={})),(function(e){function t(r){return{label:r}}i(t,"create"),e.create=t})(zc||(zc={})),(function(e){function t(r,n){return{items:r||[],isIncomplete:!!n}}i(t,"create"),e.create=t})(jc||(jc={})),(function(e){function t(n){return n.replace(/[\\`*_{}[\]()#+\-.!]/g,"\\$&")}i(t,"fromPlainText"),e.fromPlainText=t;function r(n){const a=n;return A.string(a)||A.objectLiteral(a)&&A.string(a.language)&&A.string(a.value)}i(r,"is"),e.is=r})(Yi||(Yi={})),(function(e){function t(r){let n=r;return!!n&&A.objectLiteral(n)&&(Ta.is(n.contents)||Yi.is(n.contents)||A.typedArray(n.contents,Yi.is))&&(r.range===void 0||Q.is(r.range))}i(t,"is"),e.is=t})(Bc||(Bc={})),(function(e){function t(r,n){return n?{label:r,documentation:n}:{label:r}}i(t,"create"),e.create=t})(Uc||(Uc={})),(function(e){function t(r,n,...a){let s={label:r};return A.defined(n)&&(s.documentation=n),A.defined(a)?s.parameters=a:s.parameters=[],s}i(t,"create"),e.create=t})(Kc||(Kc={})),(function(e){e.Text=1,e.Read=2,e.Write=3})(Wc||(Wc={})),(function(e){function t(r,n){let a={range:r};return A.number(n)&&(a.kind=n),a}i(t,"create"),e.create=t})(Vc||(Vc={})),(function(e){e.File=1,e.Module=2,e.Namespace=3,e.Package=4,e.Class=5,e.Method=6,e.Property=7,e.Field=8,e.Constructor=9,e.Enum=10,e.Interface=11,e.Function=12,e.Variable=13,e.Constant=14,e.String=15,e.Number=16,e.Boolean=17,e.Array=18,e.Object=19,e.Key=20,e.Null=21,e.EnumMember=22,e.Struct=23,e.Event=24,e.Operator=25,e.TypeParameter=26})(qc||(qc={})),(function(e){e.Deprecated=1})(Hc||(Hc={})),(function(e){function t(r,n,a,s,o){let l={name:r,kind:n,location:{uri:s,range:a}};return o&&(l.containerName=o),l}i(t,"create"),e.create=t})(Yc||(Yc={})),(function(e){function t(r,n,a,s){return s!==void 0?{name:r,kind:n,location:{uri:a,range:s}}:{name:r,kind:n,location:{uri:a}}}i(t,"create"),e.create=t})(Xc||(Xc={})),(function(e){function t(n,a,s,o,l,u){let c={name:n,detail:a,kind:s,range:o,selectionRange:l};return u!==void 0&&(c.children=u),c}i(t,"create"),e.create=t;function r(n){let a=n;return a&&A.string(a.name)&&A.number(a.kind)&&Q.is(a.range)&&Q.is(a.selectionRange)&&(a.detail===void 0||A.string(a.detail))&&(a.deprecated===void 0||A.boolean(a.deprecated))&&(a.children===void 0||Array.isArray(a.children))&&(a.tags===void 0||Array.isArray(a.tags))}i(r,"is"),e.is=r})(Jc||(Jc={})),(function(e){e.Empty="",e.QuickFix="quickfix",e.Refactor="refactor",e.RefactorExtract="refactor.extract",e.RefactorInline="refactor.inline",e.RefactorRewrite="refactor.rewrite",e.Source="source",e.SourceOrganizeImports="source.organizeImports",e.SourceFixAll="source.fixAll"})(Zc||(Zc={})),(function(e){e.Invoked=1,e.Automatic=2})(Xi||(Xi={})),(function(e){function t(n,a,s){let o={diagnostics:n};return a!=null&&(o.only=a),s!=null&&(o.triggerKind=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.typedArray(a.diagnostics,Vi.is)&&(a.only===void 0||A.typedArray(a.only,A.string))&&(a.triggerKind===void 0||a.triggerKind===Xi.Invoked||a.triggerKind===Xi.Automatic)}i(r,"is"),e.is=r})(Qc||(Qc={})),(function(e){function t(n,a,s){let o={title:n},l=!0;return typeof a=="string"?(l=!1,o.kind=a):nn.is(a)?o.command=a:o.edit=a,l&&s!==void 0&&(o.kind=s),o}i(t,"create"),e.create=t;function r(n){let a=n;return a&&A.string(a.title)&&(a.diagnostics===void 0||A.typedArray(a.diagnostics,Vi.is))&&(a.kind===void 0||A.string(a.kind))&&(a.edit!==void 0||a.command!==void 0)&&(a.command===void 0||nn.is(a.command))&&(a.isPreferred===void 0||A.boolean(a.isPreferred))&&(a.edit===void 0||_o.is(a.edit))}i(r,"is"),e.is=r})(ef||(ef={})),(function(e){function t(n,a){let s={range:n};return A.defined(a)&&(s.data=a),s}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Q.is(a.range)&&(A.undefined(a.command)||nn.is(a.command))}i(r,"is"),e.is=r})(tf||(tf={})),(function(e){function t(n,a){return{tabSize:n,insertSpaces:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&A.uinteger(a.tabSize)&&A.boolean(a.insertSpaces)}i(r,"is"),e.is=r})(rf||(rf={})),(function(e){function t(n,a,s){return{range:n,target:a,data:s}}i(t,"create"),e.create=t;function r(n){let a=n;return A.defined(a)&&Q.is(a.range)&&(A.undefined(a.target)||A.string(a.target))}i(r,"is"),e.is=r})(nf||(nf={})),(function(e){function t(n,a){return{range:n,parent:a}}i(t,"create"),e.create=t;function r(n){let a=n;return A.objectLiteral(a)&&Q.is(a.range)&&(a.parent===void 0||e.is(a.parent))}i(r,"is"),e.is=r})(af||(af={})),(function(e){e.namespace="namespace",e.type="type",e.class="class",e.enum="enum",e.interface="interface",e.struct="struct",e.typeParameter="typeParameter",e.parameter="parameter",e.variable="variable",e.property="property",e.enumMember="enumMember",e.event="event",e.function="function",e.method="method",e.macro="macro",e.keyword="keyword",e.modifier="modifier",e.comment="comment",e.string="string",e.number="number",e.regexp="regexp",e.operator="operator",e.decorator="decorator"})(sf||(sf={})),(function(e){e.declaration="declaration",e.definition="definition",e.readonly="readonly",e.static="static",e.deprecated="deprecated",e.abstract="abstract",e.async="async",e.modification="modification",e.documentation="documentation",e.defaultLibrary="defaultLibrary"})(of||(of={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&(n.resultId===void 0||typeof n.resultId=="string")&&Array.isArray(n.data)&&(n.data.length===0||typeof n.data[0]=="number")}i(t,"is"),e.is=t})(lf||(lf={})),(function(e){function t(n,a){return{range:n,text:a}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&A.string(a.text)}i(r,"is"),e.is=r})(uf||(uf={})),(function(e){function t(n,a,s){return{range:n,variableName:a,caseSensitiveLookup:s}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&A.boolean(a.caseSensitiveLookup)&&(A.string(a.variableName)||a.variableName===void 0)}i(r,"is"),e.is=r})(cf||(cf={})),(function(e){function t(n,a){return{range:n,expression:a}}i(t,"create"),e.create=t;function r(n){const a=n;return a!=null&&Q.is(a.range)&&(A.string(a.expression)||a.expression===void 0)}i(r,"is"),e.is=r})(ff||(ff={})),(function(e){function t(n,a){return{frameId:n,stoppedLocation:a}}i(t,"create"),e.create=t;function r(n){const a=n;return A.defined(a)&&Q.is(n.stoppedLocation)}i(r,"is"),e.is=r})(df||(df={})),(function(e){e.Type=1,e.Parameter=2;function t(r){return r===1||r===2}i(t,"is"),e.is=t})(wo||(wo={})),(function(e){function t(n){return{value:n}}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&(a.tooltip===void 0||A.string(a.tooltip)||Ta.is(a.tooltip))&&(a.location===void 0||Wi.is(a.location))&&(a.command===void 0||nn.is(a.command))}i(r,"is"),e.is=r})(Io||(Io={})),(function(e){function t(n,a,s){const o={position:n,label:a};return s!==void 0&&(o.kind=s),o}i(t,"create"),e.create=t;function r(n){const a=n;return A.objectLiteral(a)&&ie.is(a.position)&&(A.string(a.label)||A.typedArray(a.label,Io.is))&&(a.kind===void 0||wo.is(a.kind))&&a.textEdits===void 0||A.typedArray(a.textEdits,Yt.is)&&(a.tooltip===void 0||A.string(a.tooltip)||Ta.is(a.tooltip))&&(a.paddingLeft===void 0||A.boolean(a.paddingLeft))&&(a.paddingRight===void 0||A.boolean(a.paddingRight))}i(r,"is"),e.is=r})(pf||(pf={})),(function(e){function t(r){return{kind:"snippet",value:r}}i(t,"createSnippet"),e.createSnippet=t})(mf||(mf={})),(function(e){function t(r,n,a,s){return{insertText:r,filterText:n,range:a,command:s}}i(t,"create"),e.create=t})(hf||(hf={})),(function(e){function t(r){return{items:r}}i(t,"create"),e.create=t})(yf||(yf={})),(function(e){e.Invoked=0,e.Automatic=1})(gf||(gf={})),(function(e){function t(r,n){return{range:r,text:n}}i(t,"create"),e.create=t})(vf||(vf={})),(function(e){function t(r,n){return{triggerKind:r,selectedCompletionInfo:n}}i(t,"create"),e.create=t})(Tf||(Tf={})),(function(e){function t(r){const n=r;return A.objectLiteral(n)&&Eo.is(n.uri)&&A.string(n.name)}i(t,"is"),e.is=t})($f||($f={})),zg=[` `,`\r `,"\r"],(function(e){function t(s,o,l,u){return new lh(s,o,l,u)}i(t,"create"),e.create=t;function r(s){let o=s;return!!(A.defined(o)&&A.string(o.uri)&&(A.undefined(o.languageId)||A.string(o.languageId))&&A.uinteger(o.lineCount)&&A.func(o.getText)&&A.func(o.positionAt)&&A.func(o.offsetAt))}i(r,"is"),e.is=r;function n(s,o){let l=s.getText(),u=a(o,(f,d)=>{let m=f.range.start.line-d.range.start.line;return m===0?f.range.start.character-d.range.start.character:m}),c=l.length;for(let f=u.length-1;f>=0;f--){let d=u[f],m=s.offsetAt(d.range.start),g=s.offsetAt(d.range.end);if(g<=c)l=l.substring(0,m)+d.newText+l.substring(g,l.length);else throw new Error("Overlapping edit");c=m}return l}i(n,"applyEdits"),e.applyEdits=n;function a(s,o){if(s.length<=1)return s;const l=s.length/2|0,u=s.slice(0,l),c=s.slice(l);a(u,o),a(c,o);let f=0,d=0,m=0;for(;f<u.length&&d<c.length;)o(u[f],c[d])<=0?s[m++]=u[f++]:s[m++]=c[d++];for(;f<u.length;)s[m++]=u[f++];for(;d<c.length;)s[m++]=c[d++];return s}i(a,"mergeSort")})(Rf||(Rf={})),lh=class{static{i(this,"FullTextDocument")}constructor(e,t,r,n){this._uri=e,this._languageId=t,this._version=r,this._content=n,this._lineOffsets=void 0}get uri(){return this._uri}get languageId(){return this._languageId}get version(){return this._version}getText(e){if(e){let t=this.offsetAt(e.start),r=this.offsetAt(e.end);return this._content.substring(t,r)}return this._content}update(e,t){this._content=e.text,this._version=t,this._lineOffsets=void 0}getLineOffsets(){if(this._lineOffsets===void 0){let e=[],t=this._content,r=!0;for(let n=0;n<t.length;n++){r&&(e.push(n),r=!1);let a=t.charAt(n);r=a==="\r"||a===` `,a==="\r"&&n+1<t.length&&t.charAt(n+1)===` diff --git a/apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-CSvOhRTt.js b/apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-zQaCQNIP.js similarity index 98% rename from apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-CSvOhRTt.js rename to apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-zQaCQNIP.js index 8ead8342d..460d5fdba 100644 --- a/apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-CSvOhRTt.js +++ b/apps/kimi-code/dist-web/assets/cynefinDiagram-TSTJHNR4-zQaCQNIP.js @@ -1,4 +1,4 @@ -import{p as xt}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{s as gt,g as $t,p as bt,o as wt,a as Ct,b as vt,_ as s,l as O,F as Dt,e as kt,q as Tt,B as U,z as Q,D as At,W as ot}from"./mermaid.core-DaDTfY6S.js";import{p as Bt}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var rt=s(()=>({domains:new Map,transitions:[]}),"createDefaultData"),H=rt(),St=s(()=>H.domains,"getDomains"),Mt=s(()=>H.transitions,"getTransitions"),zt=s(t=>{if(t)for(const e of t){const n=e.domain,a=(e.items??[]).map(c=>({label:c.label}));H.domains.set(n,{name:n,items:a})}},"setDomains"),Lt=s(t=>{t&&(H.transitions=t.filter(e=>e.from===e.to?(O.warn(`Cynefin: self-loop transition on domain "${e.from}" is not meaningful and will be skipped.`),!1):!0).map(e=>({from:e.from,to:e.to,label:e.label||void 0})))},"setTransitions"),Nt=s(()=>U({...At.cynefin,...Q().cynefin}),"getConfig"),Pt=s(()=>{Tt(),H=rt()},"clear"),Y={getDomains:St,getTransitions:Mt,setDomains:zt,setTransitions:Lt,getConfig:Nt,clear:Pt,setAccTitle:vt,getAccTitle:Ct,setDiagramTitle:wt,getDiagramTitle:bt,getAccDescription:$t,setAccDescription:gt},Wt=s(t=>{xt(t,Y),Y.setDomains(t.domains),Y.setTransitions(t.transitions)},"populate"),It={parse:s(async t=>{const e=await Bt("cynefin",t);O.debug(e),Wt(e)},"parse")};function E(t){let e=t+1831565813|0;return e=Math.imul(e^e>>>15,e|1),e^=e+Math.imul(e^e>>>7,e|61),((e^e>>>14)>>>0)/4294967296}s(E,"seededRandom");function st(t){let e=0;for(let n=0;n<t.length;n++){const a=t.charCodeAt(n);e=(e<<5)-e+a,e|=0}return e}s(st,"hashString");function it(t,e){return typeof t=="number"&&Number.isFinite(t)&&t!==0?t:st(e)}s(it,"resolveSeed");function ct(t,e,n,a){const c=t/2,m=a??t*.015,v=7,I=e/v,d=[];for(let o=0;o<=v;o++){const p=E(n+o*17)*m*2-m;d.push({x:c+p,y:o*I})}let D=`M${d[0].x},${d[0].y}`;for(let o=0;o<d.length-1;o++){const p=d[o],i=d[o+1],f=(p.y+i.y)/2,b=o%2===0?1:-1,h=m*1.5*b*E(n+o*31+7),F=p.x+h,R=f,_=i.x-h;D+=` C${F},${R} ${_},${f} ${i.x},${i.y}`}return D}s(ct,"generateFoldPath");function lt(t,e,n,a){const c=e/2,m=a??e*.015,v=7,I=t/v,d=[];for(let o=0;o<=v;o++){const p=E(n+o*23)*m*2-m;d.push({x:o*I,y:c+p})}let D=`M${d[0].x},${d[0].y}`;for(let o=0;o<d.length-1;o++){const p=d[o],i=d[o+1],f=(p.x+i.x)/2,b=o%2===0?1:-1,h=m*1.5*b*E(n+o*37+11),F=f,R=p.y+h,_=f,z=i.y-h;D+=` C${F},${R} ${_},${z} ${i.x},${i.y}`}return D}s(lt,"generateHorizontalBoundary");function dt(t,e){const n=t/2,a=e*.5,c=e,m=t*.03;return[`M${n},${a}`,`C${n+m},${a+(c-a)*.2}`,`${n-m*1.5},${a+(c-a)*.55}`,`${n+m*.5},${a+(c-a)*.75}`,`C${n-m},${a+(c-a)*.85}`,`${n+m*.3},${a+(c-a)*.95}`,`${n},${c}`].join(" ")}s(dt,"generateCliffPath");function ft(t,e,n,a){return[`M${t-n},${e}`,`A${n},${a} 0 1,1 ${t+n},${e}`,`A${n},${a} 0 1,1 ${t-n},${e}`,"Z"].join(" ")}s(ft,"generateConfusionPath");var at={complex:{model:"Probe → Sense → Respond",practice:"Emergent Practices"},complicated:{model:"Sense → Analyse → Respond",practice:"Good Practices"},clear:{model:"Sense → Categorise → Respond",practice:"Best Practices"},chaotic:{model:"Act → Sense → Respond",practice:"Novel Practices"},confusion:{model:"",practice:"Disorder"}},Ft=s((t,e)=>{const n=t/2,a=e/2;return{complex:{cx:n/2,cy:a/2,x:0,y:0,w:n,h:a},complicated:{cx:n+n/2,cy:a/2,x:n,y:0,w:n,h:a},chaotic:{cx:n/2,cy:a+a/2,x:0,y:a,w:n,h:a},clear:{cx:n+n/2,cy:a+a/2,x:n,y:a,w:n,h:a},confusion:{cx:n,cy:a,x:n*.7,y:a*.7,w:n*.6,h:a*.6}}},"getDomainLayouts"),Rt=s(()=>{const t=ot(),e=Q();return U(t,e.themeVariables).cynefin},"getCynefinDomainColors"),q=3,_t=s((t,e,n,a)=>{const c=a.db,m=c.getDomains(),v=c.getTransitions(),I=c.getDiagramTitle(),d=c.getAccTitle(),D=c.getAccDescription(),o=c.getConfig(),p=Rt();O.debug("Rendering Cynefin diagram");const i=o.width,f=o.height,b=o.padding,h=o.showDomainDescriptions,F=o.boundaryAmplitude,R=i+b*2,_=f+b*2,z={complex:p.complexBg,complicated:p.complicatedBg,clear:p.clearBg,chaotic:p.chaoticBg,confusion:p.confusionBg},k=Dt(e);kt(k,_,R,o.useMaxWidth??!0),k.attr("viewBox",`0 0 ${R} ${_}`),d&&k.append("title").text(d),D&&k.append("desc").text(D);const T=k.append("g").attr("transform",`translate(${b}, ${b})`),V=Ft(i,f),Z=it(o.seed,e),mt=T.append("g").attr("class","cynefin-backgrounds"),X=["complex","complicated","chaotic","clear"];for(const l of X){const r=V[l];mt.append("rect").attr("class","cynefinDomain").attr("x",r.x).attr("y",r.y).attr("width",r.w).attr("height",r.h).attr("fill",z[l]).attr("fill-opacity",.4).attr("stroke","none")}const j=T.append("g").attr("class","cynefin-boundaries");j.append("path").attr("class","cynefinBoundary").attr("d",ct(i,f,Z,F)).attr("fill","none"),j.append("path").attr("class","cynefinBoundary").attr("d",lt(i,f,Z+100,F)).attr("fill","none"),j.append("path").attr("class","cynefinCliff").attr("d",dt(i,f)).attr("fill","none");const pt=i*.15,yt=f*.15;T.append("path").attr("class","cynefinConfusion").attr("d",ft(i/2,f/2,pt,yt)).attr("fill",z.confusion).attr("fill-opacity",.5);const J=T.append("g").attr("class","cynefin-labels");for(const l of X){const r=V[l];J.append("text").attr("class","cynefinDomainLabel").attr("x",r.cx).attr("y",h?r.cy-30:r.cy).attr("text-anchor","middle").attr("dominant-baseline","middle").text(l.charAt(0).toUpperCase()+l.slice(1))}if(J.append("text").attr("class","cynefinDomainLabel").attr("x",i/2).attr("y",h?f/2-10:f/2).attr("text-anchor","middle").attr("dominant-baseline","middle").text("Confusion"),h){const l=T.append("g").attr("class","cynefin-subtitles");for(const r of X){const u=V[r],y=at[r];l.append("text").attr("class","cynefinSubtitle").attr("x",u.cx).attr("y",u.cy-10).attr("text-anchor","middle").attr("dominant-baseline","middle").text(y.model),l.append("text").attr("class","cynefinSubtitle").attr("x",u.cx).attr("y",u.cy+5).attr("text-anchor","middle").attr("dominant-baseline","middle").text(y.practice)}l.append("text").attr("class","cynefinSubtitle").attr("x",i/2).attr("y",f/2+8).attr("text-anchor","middle").attr("dominant-baseline","middle").text(at.confusion.practice)}const K=T.append("g").attr("class","cynefin-items"),A=26,tt=10,ut=["complex","complicated","chaotic","clear","confusion"];for(const l of ut){const r=m.get(l);if(!r||r.items.length===0)continue;const u=V[l],y=l==="confusion";let L=r.items,N=0;y&&r.items.length>q&&(N=r.items.length-q,L=r.items.slice(0,q));let B;if(y){const g=h?22:14;B=u.cy+g}else B=u.cy+(h?25:15);if([...L].forEach((g,S)=>{const w=B+S*(A+4),M=K.append("g"),P=M.append("text").attr("class","cynefinItemText").attr("x",0).attr("y",A/2).attr("text-anchor","middle").attr("dominant-baseline","central").text(g.label);let $=g.label.length*7;const x=P.node();if(x&&typeof x.getBBox=="function"){const G=x.getBBox();G.width>0&&($=G.width)}const C=$+tt*2,W=u.cx-C/2;M.attr("transform",`translate(${W}, ${w})`),M.insert("rect","text").attr("class","cynefinItem").attr("x",0).attr("y",0).attr("width",C).attr("height",A).attr("rx",4).attr("ry",4).attr("fill",z[l]).attr("fill-opacity",.95),P.attr("x",C/2).attr("y",A/2)}),N>0){const g=B+L.length*(A+4),S=`+${N} more`,w=K.append("g"),M=w.append("text").attr("class","cynefinItemText").attr("x",0).attr("y",A/2).attr("text-anchor","middle").attr("dominant-baseline","central").text(S);let P=S.length*7;const $=M.node();if($&&typeof $.getBBox=="function"){const W=$.getBBox();W.width>0&&(P=W.width)}const x=P+tt*2,C=u.cx-x/2;w.attr("transform",`translate(${C}, ${g})`),w.insert("rect","text").attr("class","cynefinItemOverflow").attr("x",0).attr("y",0).attr("width",x).attr("height",A).attr("rx",4).attr("ry",4).attr("fill",z[l]).attr("fill-opacity",.6),M.attr("x",x/2).attr("y",A/2)}}if(v.length>0){const l=k.select("defs").empty()?k.append("defs"):k.select("defs"),r=`cynefin-arrow-${e}`;l.append("marker").attr("id",r).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",6).attr("markerHeight",6).attr("orient","auto-start-reverse").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","cynefinArrowHead");const u=T.append("g").attr("class","cynefin-arrows");v.forEach(y=>{const L=V[y.from],N=V[y.to];if(!L||!N)return;if(y.from===y.to){O.warn(`Cynefin renderer: skipping self-loop on domain "${y.from}"`);return}const B=L.cx,g=L.cy,S=N.cx,w=N.cy,M=(B+S)/2,P=(g+w)/2,$=S-B,x=w-g,C=Math.sqrt($*$+x*x),W=C*.15,G=-x/C,ht=$/C,et=M+G*W,nt=P+ht*W;u.append("path").attr("class","cynefinArrowLine").attr("d",`M${B},${g} Q${et},${nt} ${S},${w}`).attr("fill","none").attr("marker-end",`url(#${r})`),y.label&&u.append("text").attr("class","cynefinArrowLabel").attr("x",et).attr("y",nt-6).attr("text-anchor","middle").attr("dominant-baseline","auto").text(y.label)})}I&&T.append("text").attr("class","cynefinTitle").attr("x",i/2).attr("y",-b/2).attr("text-anchor","middle").attr("dominant-baseline","middle").text(I)},"draw"),Vt={draw:_t},Et=s(()=>{const t=ot(),e=Q();return U(t,e.themeVariables).cynefin},"getCynefinTheme"),Ht=s(()=>{const t=Et();return` +import{p as xt}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{s as gt,g as $t,p as bt,o as wt,a as Ct,b as vt,_ as s,l as O,F as Dt,e as kt,q as Tt,B as U,z as Q,D as At,W as ot}from"./mermaid.core-CJB1tAev.js";import{p as Bt}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var rt=s(()=>({domains:new Map,transitions:[]}),"createDefaultData"),H=rt(),St=s(()=>H.domains,"getDomains"),Mt=s(()=>H.transitions,"getTransitions"),zt=s(t=>{if(t)for(const e of t){const n=e.domain,a=(e.items??[]).map(c=>({label:c.label}));H.domains.set(n,{name:n,items:a})}},"setDomains"),Lt=s(t=>{t&&(H.transitions=t.filter(e=>e.from===e.to?(O.warn(`Cynefin: self-loop transition on domain "${e.from}" is not meaningful and will be skipped.`),!1):!0).map(e=>({from:e.from,to:e.to,label:e.label||void 0})))},"setTransitions"),Nt=s(()=>U({...At.cynefin,...Q().cynefin}),"getConfig"),Pt=s(()=>{Tt(),H=rt()},"clear"),Y={getDomains:St,getTransitions:Mt,setDomains:zt,setTransitions:Lt,getConfig:Nt,clear:Pt,setAccTitle:vt,getAccTitle:Ct,setDiagramTitle:wt,getDiagramTitle:bt,getAccDescription:$t,setAccDescription:gt},Wt=s(t=>{xt(t,Y),Y.setDomains(t.domains),Y.setTransitions(t.transitions)},"populate"),It={parse:s(async t=>{const e=await Bt("cynefin",t);O.debug(e),Wt(e)},"parse")};function E(t){let e=t+1831565813|0;return e=Math.imul(e^e>>>15,e|1),e^=e+Math.imul(e^e>>>7,e|61),((e^e>>>14)>>>0)/4294967296}s(E,"seededRandom");function st(t){let e=0;for(let n=0;n<t.length;n++){const a=t.charCodeAt(n);e=(e<<5)-e+a,e|=0}return e}s(st,"hashString");function it(t,e){return typeof t=="number"&&Number.isFinite(t)&&t!==0?t:st(e)}s(it,"resolveSeed");function ct(t,e,n,a){const c=t/2,m=a??t*.015,v=7,I=e/v,d=[];for(let o=0;o<=v;o++){const p=E(n+o*17)*m*2-m;d.push({x:c+p,y:o*I})}let D=`M${d[0].x},${d[0].y}`;for(let o=0;o<d.length-1;o++){const p=d[o],i=d[o+1],f=(p.y+i.y)/2,b=o%2===0?1:-1,h=m*1.5*b*E(n+o*31+7),F=p.x+h,R=f,_=i.x-h;D+=` C${F},${R} ${_},${f} ${i.x},${i.y}`}return D}s(ct,"generateFoldPath");function lt(t,e,n,a){const c=e/2,m=a??e*.015,v=7,I=t/v,d=[];for(let o=0;o<=v;o++){const p=E(n+o*23)*m*2-m;d.push({x:o*I,y:c+p})}let D=`M${d[0].x},${d[0].y}`;for(let o=0;o<d.length-1;o++){const p=d[o],i=d[o+1],f=(p.x+i.x)/2,b=o%2===0?1:-1,h=m*1.5*b*E(n+o*37+11),F=f,R=p.y+h,_=f,z=i.y-h;D+=` C${F},${R} ${_},${z} ${i.x},${i.y}`}return D}s(lt,"generateHorizontalBoundary");function dt(t,e){const n=t/2,a=e*.5,c=e,m=t*.03;return[`M${n},${a}`,`C${n+m},${a+(c-a)*.2}`,`${n-m*1.5},${a+(c-a)*.55}`,`${n+m*.5},${a+(c-a)*.75}`,`C${n-m},${a+(c-a)*.85}`,`${n+m*.3},${a+(c-a)*.95}`,`${n},${c}`].join(" ")}s(dt,"generateCliffPath");function ft(t,e,n,a){return[`M${t-n},${e}`,`A${n},${a} 0 1,1 ${t+n},${e}`,`A${n},${a} 0 1,1 ${t-n},${e}`,"Z"].join(" ")}s(ft,"generateConfusionPath");var at={complex:{model:"Probe → Sense → Respond",practice:"Emergent Practices"},complicated:{model:"Sense → Analyse → Respond",practice:"Good Practices"},clear:{model:"Sense → Categorise → Respond",practice:"Best Practices"},chaotic:{model:"Act → Sense → Respond",practice:"Novel Practices"},confusion:{model:"",practice:"Disorder"}},Ft=s((t,e)=>{const n=t/2,a=e/2;return{complex:{cx:n/2,cy:a/2,x:0,y:0,w:n,h:a},complicated:{cx:n+n/2,cy:a/2,x:n,y:0,w:n,h:a},chaotic:{cx:n/2,cy:a+a/2,x:0,y:a,w:n,h:a},clear:{cx:n+n/2,cy:a+a/2,x:n,y:a,w:n,h:a},confusion:{cx:n,cy:a,x:n*.7,y:a*.7,w:n*.6,h:a*.6}}},"getDomainLayouts"),Rt=s(()=>{const t=ot(),e=Q();return U(t,e.themeVariables).cynefin},"getCynefinDomainColors"),q=3,_t=s((t,e,n,a)=>{const c=a.db,m=c.getDomains(),v=c.getTransitions(),I=c.getDiagramTitle(),d=c.getAccTitle(),D=c.getAccDescription(),o=c.getConfig(),p=Rt();O.debug("Rendering Cynefin diagram");const i=o.width,f=o.height,b=o.padding,h=o.showDomainDescriptions,F=o.boundaryAmplitude,R=i+b*2,_=f+b*2,z={complex:p.complexBg,complicated:p.complicatedBg,clear:p.clearBg,chaotic:p.chaoticBg,confusion:p.confusionBg},k=Dt(e);kt(k,_,R,o.useMaxWidth??!0),k.attr("viewBox",`0 0 ${R} ${_}`),d&&k.append("title").text(d),D&&k.append("desc").text(D);const T=k.append("g").attr("transform",`translate(${b}, ${b})`),V=Ft(i,f),Z=it(o.seed,e),mt=T.append("g").attr("class","cynefin-backgrounds"),X=["complex","complicated","chaotic","clear"];for(const l of X){const r=V[l];mt.append("rect").attr("class","cynefinDomain").attr("x",r.x).attr("y",r.y).attr("width",r.w).attr("height",r.h).attr("fill",z[l]).attr("fill-opacity",.4).attr("stroke","none")}const j=T.append("g").attr("class","cynefin-boundaries");j.append("path").attr("class","cynefinBoundary").attr("d",ct(i,f,Z,F)).attr("fill","none"),j.append("path").attr("class","cynefinBoundary").attr("d",lt(i,f,Z+100,F)).attr("fill","none"),j.append("path").attr("class","cynefinCliff").attr("d",dt(i,f)).attr("fill","none");const pt=i*.15,yt=f*.15;T.append("path").attr("class","cynefinConfusion").attr("d",ft(i/2,f/2,pt,yt)).attr("fill",z.confusion).attr("fill-opacity",.5);const J=T.append("g").attr("class","cynefin-labels");for(const l of X){const r=V[l];J.append("text").attr("class","cynefinDomainLabel").attr("x",r.cx).attr("y",h?r.cy-30:r.cy).attr("text-anchor","middle").attr("dominant-baseline","middle").text(l.charAt(0).toUpperCase()+l.slice(1))}if(J.append("text").attr("class","cynefinDomainLabel").attr("x",i/2).attr("y",h?f/2-10:f/2).attr("text-anchor","middle").attr("dominant-baseline","middle").text("Confusion"),h){const l=T.append("g").attr("class","cynefin-subtitles");for(const r of X){const u=V[r],y=at[r];l.append("text").attr("class","cynefinSubtitle").attr("x",u.cx).attr("y",u.cy-10).attr("text-anchor","middle").attr("dominant-baseline","middle").text(y.model),l.append("text").attr("class","cynefinSubtitle").attr("x",u.cx).attr("y",u.cy+5).attr("text-anchor","middle").attr("dominant-baseline","middle").text(y.practice)}l.append("text").attr("class","cynefinSubtitle").attr("x",i/2).attr("y",f/2+8).attr("text-anchor","middle").attr("dominant-baseline","middle").text(at.confusion.practice)}const K=T.append("g").attr("class","cynefin-items"),A=26,tt=10,ut=["complex","complicated","chaotic","clear","confusion"];for(const l of ut){const r=m.get(l);if(!r||r.items.length===0)continue;const u=V[l],y=l==="confusion";let L=r.items,N=0;y&&r.items.length>q&&(N=r.items.length-q,L=r.items.slice(0,q));let B;if(y){const g=h?22:14;B=u.cy+g}else B=u.cy+(h?25:15);if([...L].forEach((g,S)=>{const w=B+S*(A+4),M=K.append("g"),P=M.append("text").attr("class","cynefinItemText").attr("x",0).attr("y",A/2).attr("text-anchor","middle").attr("dominant-baseline","central").text(g.label);let $=g.label.length*7;const x=P.node();if(x&&typeof x.getBBox=="function"){const G=x.getBBox();G.width>0&&($=G.width)}const C=$+tt*2,W=u.cx-C/2;M.attr("transform",`translate(${W}, ${w})`),M.insert("rect","text").attr("class","cynefinItem").attr("x",0).attr("y",0).attr("width",C).attr("height",A).attr("rx",4).attr("ry",4).attr("fill",z[l]).attr("fill-opacity",.95),P.attr("x",C/2).attr("y",A/2)}),N>0){const g=B+L.length*(A+4),S=`+${N} more`,w=K.append("g"),M=w.append("text").attr("class","cynefinItemText").attr("x",0).attr("y",A/2).attr("text-anchor","middle").attr("dominant-baseline","central").text(S);let P=S.length*7;const $=M.node();if($&&typeof $.getBBox=="function"){const W=$.getBBox();W.width>0&&(P=W.width)}const x=P+tt*2,C=u.cx-x/2;w.attr("transform",`translate(${C}, ${g})`),w.insert("rect","text").attr("class","cynefinItemOverflow").attr("x",0).attr("y",0).attr("width",x).attr("height",A).attr("rx",4).attr("ry",4).attr("fill",z[l]).attr("fill-opacity",.6),M.attr("x",x/2).attr("y",A/2)}}if(v.length>0){const l=k.select("defs").empty()?k.append("defs"):k.select("defs"),r=`cynefin-arrow-${e}`;l.append("marker").attr("id",r).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",6).attr("markerHeight",6).attr("orient","auto-start-reverse").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("class","cynefinArrowHead");const u=T.append("g").attr("class","cynefin-arrows");v.forEach(y=>{const L=V[y.from],N=V[y.to];if(!L||!N)return;if(y.from===y.to){O.warn(`Cynefin renderer: skipping self-loop on domain "${y.from}"`);return}const B=L.cx,g=L.cy,S=N.cx,w=N.cy,M=(B+S)/2,P=(g+w)/2,$=S-B,x=w-g,C=Math.sqrt($*$+x*x),W=C*.15,G=-x/C,ht=$/C,et=M+G*W,nt=P+ht*W;u.append("path").attr("class","cynefinArrowLine").attr("d",`M${B},${g} Q${et},${nt} ${S},${w}`).attr("fill","none").attr("marker-end",`url(#${r})`),y.label&&u.append("text").attr("class","cynefinArrowLabel").attr("x",et).attr("y",nt-6).attr("text-anchor","middle").attr("dominant-baseline","auto").text(y.label)})}I&&T.append("text").attr("class","cynefinTitle").attr("x",i/2).attr("y",-b/2).attr("text-anchor","middle").attr("dominant-baseline","middle").text(I)},"draw"),Vt={draw:_t},Et=s(()=>{const t=ot(),e=Q();return U(t,e.themeVariables).cynefin},"getCynefinTheme"),Ht=s(()=>{const t=Et();return` .cynefinDomain { stroke: none; } diff --git a/apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-BV_7O_eU.js b/apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-D8gdq5tS.js similarity index 97% rename from apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-BV_7O_eU.js rename to apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-D8gdq5tS.js index 97893ee8a..b6eae6b18 100644 --- a/apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-BV_7O_eU.js +++ b/apps/kimi-code/dist-web/assets/dagre-VKFMJZFB-D8gdq5tS.js @@ -1,4 +1,4 @@ -import{c as O,w as I,a as J,f as P,b as E,s as A}from"./chunk-RYQCIY6F-D1Yl7opn.js";import{_ as w,am as v,an as D,ao as H,ap as Y,l,c as _,aq as W,ar as $,ag as j,as as q,ah as R,af as F,at as z,au as K,av as G}from"./mermaid.core-DaDTfY6S.js";import{G as Q}from"./graph-DOmOIIwC.js";import{l as U}from"./layout-D-LzfAck.js";import"./map-DxJ2ADlA.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var C=w((s,t,g)=>Math.max(t,Math.min(g,s)),"clamp"),B=w((s="TB")=>{switch(s){case"BT":return"bottom";case"LR":return"right";case"RL":return"left";case"TB":default:return"top"}},"getDefaultSelfLoopSide"),V=w(s=>s==="flowchart"||s==="flowchart-v2"||s==="stateDiagram","shouldMergeSelfLoopSegments"),Z=w((s,t,g,m,c)=>{const o=[],r=new Set;if(g.forEach(({start:i,end:n})=>{i!==m&&r.add(i),n!==m&&r.add(n)}),r.forEach(i=>{const n=s.node(i);typeof n?.x=="number"&&typeof n?.y=="number"&&o.push(n)}),o.length===0&&g.forEach(({edge:i})=>{(i.points??[]).forEach(n=>{typeof n?.x=="number"&&typeof n?.y=="number"&&o.push(n)})}),o.length===0)return B(c);const f=o.reduce((i,n)=>({x:i.x+n.x/o.length,y:i.y+n.y/o.length}),{x:0,y:0}),h=f.x-t.x,a=f.y-t.y;return Math.abs(h)>Math.abs(a)?h>0?"right":"left":Math.abs(a)>0?a>0?"bottom":"top":B(c)},"getSelfLoopSide"),ee=w((s,t="top",g=0,m=0)=>{const c=s.x,o=s.y-g,r=s.width/2,f=s.height/2,h=Math.max(36,Math.min(100,s.width*.8)),a=C(Math.max(m,s.width*.35),36,h),i=C(Math.min(s.width,s.height)*.45,24,48);switch(t){case"bottom":{const n=o+f;return[{x:c-a/2,y:n},{x:c-a/2,y:n+i},{x:c+a/2,y:n+i},{x:c+a/2,y:n}]}case"right":{const n=c+r;return[{x:n,y:o-a/2},{x:n+i,y:o-a/2},{x:n+i,y:o+a/2},{x:n,y:o+a/2}]}case"left":{const n=c-r;return[{x:n,y:o-a/2},{x:n-i,y:o-a/2},{x:n-i,y:o+a/2},{x:n,y:o+a/2}]}case"top":default:{const n=o-f;return[{x:c-a/2,y:n},{x:c-a/2,y:n-i},{x:c+a/2,y:n-i},{x:c+a/2,y:n}]}}},"getSelfLoopPoints"),te=w((s,t,g="top",m=0,c={})=>{const r=s.x,f=s.y-m,h=c.width??0,a=c.height??0;switch(g){case"bottom":return{x:r,y:Math.max(...t.map(i=>i.y))+a/2+4};case"right":return{x:Math.max(...t.map(i=>i.x))+h/2+4,y:f};case"left":return{x:Math.min(...t.map(i=>i.x))-h/2-4,y:f};case"top":default:return{x:r,y:Math.min(...t.map(i=>i.y))-a/2-4}}},"getSelfLoopLabelPosition"),ne=w((s,t=0,{mergeSelfLoops:g=!0}={})=>{const m=new Map,c=[],o=s.graph()?.rankdir;return s.edges().forEach(r=>{const f=s.edge(r);if(g&&f.selfLoop){const h=f.selfLoop.id;m.has(h)||m.set(h,[]),m.get(h).push({edge:f,start:r.v,end:r.w})}else c.push({edge:f,start:r.v,end:r.w})}),m.forEach(r=>{if(r.length!==3){r.forEach(L=>c.push(L));return}r.sort((L,d)=>L.edge.selfLoop.order-d.edge.selfLoop.order);const[f,h,a]=r,i=f.edge.originalEdge??h.edge.originalEdge??a.edge.originalEdge??h.edge,n=s.node(i.start);if(!n){r.forEach(L=>c.push(L));return}const p={width:h.edge.width,height:h.edge.height},y=Z(s,n,r,i.start,o),X=ee(n,y,t,p.width??0),S=te(n,X,y,t,p),b={...h.edge,...i,id:i.id,points:X,start:i.start,end:i.end,x:S.x,y:S.y,width:p.width,height:p.height,labelStyle:h.edge.labelStyle,fromCluster:f.edge.fromCluster??h.edge.fromCluster??a.edge.fromCluster,toCluster:f.edge.toCluster??h.edge.toCluster??a.edge.toCluster};delete b.selfLoop,delete b.originalEdge,c.push({edge:b,start:b.start,end:b.end})}),c},"getEdgesToRender"),T=w(async(s,t,g,m,c,o)=>{l.warn("Graph in recursive render:XAX",I(t),c);const r=t.graph().rankdir;l.trace("Dir in recursive render - dir:",r);const f=s.insert("g").attr("class","root");t.nodes()?l.info("Recursive render XXX",t.nodes()):l.info("No nodes found for",t),t.edges().length>0&&l.info("Recursive edges",t.edge(t.edges()[0]));const h=f.insert("g").attr("class","clusters"),a=f.insert("g").attr("class","edgePaths"),i=f.insert("g").attr("class","edgeLabels"),n=f.insert("g").attr("class","nodes"),p=V(g);await Promise.all(t.nodes().map(async function(d){const e=t.node(d);if(c!==void 0){const u=JSON.parse(JSON.stringify(c.clusterData));l.trace(`Setting data for parent cluster XXX +import{c as O,w as I,a as J,f as P,b as E,s as A}from"./chunk-RYQCIY6F-Df2V79id.js";import{_ as w,am as v,an as D,ao as H,ap as Y,l,c as _,aq as W,ar as $,ag as j,as as q,ah as R,af as F,at as z,au as K,av as G}from"./mermaid.core-CJB1tAev.js";import{G as Q}from"./graph-DOmOIIwC.js";import{l as U}from"./layout-D-LzfAck.js";import"./map-DxJ2ADlA.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var C=w((s,t,g)=>Math.max(t,Math.min(g,s)),"clamp"),B=w((s="TB")=>{switch(s){case"BT":return"bottom";case"LR":return"right";case"RL":return"left";case"TB":default:return"top"}},"getDefaultSelfLoopSide"),V=w(s=>s==="flowchart"||s==="flowchart-v2"||s==="stateDiagram","shouldMergeSelfLoopSegments"),Z=w((s,t,g,m,c)=>{const o=[],r=new Set;if(g.forEach(({start:i,end:n})=>{i!==m&&r.add(i),n!==m&&r.add(n)}),r.forEach(i=>{const n=s.node(i);typeof n?.x=="number"&&typeof n?.y=="number"&&o.push(n)}),o.length===0&&g.forEach(({edge:i})=>{(i.points??[]).forEach(n=>{typeof n?.x=="number"&&typeof n?.y=="number"&&o.push(n)})}),o.length===0)return B(c);const f=o.reduce((i,n)=>({x:i.x+n.x/o.length,y:i.y+n.y/o.length}),{x:0,y:0}),h=f.x-t.x,a=f.y-t.y;return Math.abs(h)>Math.abs(a)?h>0?"right":"left":Math.abs(a)>0?a>0?"bottom":"top":B(c)},"getSelfLoopSide"),ee=w((s,t="top",g=0,m=0)=>{const c=s.x,o=s.y-g,r=s.width/2,f=s.height/2,h=Math.max(36,Math.min(100,s.width*.8)),a=C(Math.max(m,s.width*.35),36,h),i=C(Math.min(s.width,s.height)*.45,24,48);switch(t){case"bottom":{const n=o+f;return[{x:c-a/2,y:n},{x:c-a/2,y:n+i},{x:c+a/2,y:n+i},{x:c+a/2,y:n}]}case"right":{const n=c+r;return[{x:n,y:o-a/2},{x:n+i,y:o-a/2},{x:n+i,y:o+a/2},{x:n,y:o+a/2}]}case"left":{const n=c-r;return[{x:n,y:o-a/2},{x:n-i,y:o-a/2},{x:n-i,y:o+a/2},{x:n,y:o+a/2}]}case"top":default:{const n=o-f;return[{x:c-a/2,y:n},{x:c-a/2,y:n-i},{x:c+a/2,y:n-i},{x:c+a/2,y:n}]}}},"getSelfLoopPoints"),te=w((s,t,g="top",m=0,c={})=>{const r=s.x,f=s.y-m,h=c.width??0,a=c.height??0;switch(g){case"bottom":return{x:r,y:Math.max(...t.map(i=>i.y))+a/2+4};case"right":return{x:Math.max(...t.map(i=>i.x))+h/2+4,y:f};case"left":return{x:Math.min(...t.map(i=>i.x))-h/2-4,y:f};case"top":default:return{x:r,y:Math.min(...t.map(i=>i.y))-a/2-4}}},"getSelfLoopLabelPosition"),ne=w((s,t=0,{mergeSelfLoops:g=!0}={})=>{const m=new Map,c=[],o=s.graph()?.rankdir;return s.edges().forEach(r=>{const f=s.edge(r);if(g&&f.selfLoop){const h=f.selfLoop.id;m.has(h)||m.set(h,[]),m.get(h).push({edge:f,start:r.v,end:r.w})}else c.push({edge:f,start:r.v,end:r.w})}),m.forEach(r=>{if(r.length!==3){r.forEach(L=>c.push(L));return}r.sort((L,d)=>L.edge.selfLoop.order-d.edge.selfLoop.order);const[f,h,a]=r,i=f.edge.originalEdge??h.edge.originalEdge??a.edge.originalEdge??h.edge,n=s.node(i.start);if(!n){r.forEach(L=>c.push(L));return}const p={width:h.edge.width,height:h.edge.height},y=Z(s,n,r,i.start,o),X=ee(n,y,t,p.width??0),S=te(n,X,y,t,p),b={...h.edge,...i,id:i.id,points:X,start:i.start,end:i.end,x:S.x,y:S.y,width:p.width,height:p.height,labelStyle:h.edge.labelStyle,fromCluster:f.edge.fromCluster??h.edge.fromCluster??a.edge.fromCluster,toCluster:f.edge.toCluster??h.edge.toCluster??a.edge.toCluster};delete b.selfLoop,delete b.originalEdge,c.push({edge:b,start:b.start,end:b.end})}),c},"getEdgesToRender"),T=w(async(s,t,g,m,c,o)=>{l.warn("Graph in recursive render:XAX",I(t),c);const r=t.graph().rankdir;l.trace("Dir in recursive render - dir:",r);const f=s.insert("g").attr("class","root");t.nodes()?l.info("Recursive render XXX",t.nodes()):l.info("No nodes found for",t),t.edges().length>0&&l.info("Recursive edges",t.edge(t.edges()[0]));const h=f.insert("g").attr("class","clusters"),a=f.insert("g").attr("class","edgePaths"),i=f.insert("g").attr("class","edgeLabels"),n=f.insert("g").attr("class","nodes"),p=V(g);await Promise.all(t.nodes().map(async function(d){const e=t.node(d);if(c!==void 0){const u=JSON.parse(JSON.stringify(c.clusterData));l.trace(`Setting data for parent cluster XXX Node.id = `,d,` data=`,u.height,` Parent cluster`,c.height),t.setNode(c.id,u),t.parent(d)||(l.trace("Setting parent",d,c.id),t.setParent(d,c.id,u))}if(l.info("(Insert) Node XXX"+d+": "+JSON.stringify(t.node(d))),e?.clusterNode){l.info("Cluster identified XBX",d,e.width,t.node(d));const{ranksep:u,nodesep:x}=t.graph();e.graph.setGraph({...e.graph.graph(),ranksep:u+25,nodesep:x});const N=await T(n,e.graph,g,m,t.node(d),o),M=N.elem;W(e,M),e.diff=N.diff||0,l.info("New compound node after recursive render XAX",d,"width",e.width,"height",e.height),$(M,e)}else t.children(d).length>0?(l.trace("Cluster - the non recursive path XBX",d,e.id,e,e.width,"Graph:",t),l.trace(P(e.id,t)),E.set(e.id,{id:P(e.id,t),node:e})):(l.trace("Node - the non recursive path XAX",d,n,t.node(d),r),await j(n,t.node(d),{config:o,dir:r}))})),await w(async()=>{const d=t.edges().map(async function(e){const u=t.edge(e.v,e.w,e.name);if(l.info("Edge "+e.v+" -> "+e.w+": "+JSON.stringify(e)),l.info("Edge "+e.v+" -> "+e.w+": ",e," ",JSON.stringify(t.edge(e))),l.info("Fix",E,"ids:",e.v,e.w,"Translating: ",E.get(e.v),E.get(e.w)),p&&u.selfLoop){if(u.selfLoop.order!==1)return;const x=u.id;u.id=u.selfLoop.id,await G(i,u),u.id=x;return}await G(i,u)});await Promise.all(d)},"processEdges")(),l.info("Graph before layout:",JSON.stringify(I(t))),l.info("############################################# XXX"),l.info("### Layout ### XXX"),l.info("############################################# XXX"),U(t),l.info("Graph after layout:",JSON.stringify(I(t)));let X=0,{subGraphTitleTotalMargin:S}=q(o);await Promise.all(A(t).map(async function(d){const e=t.node(d);if(l.info("Position XBX => "+d+": ("+e.x,","+e.y,") width: ",e.width," height: ",e.height),e?.clusterNode)e.y+=S,l.info("A tainted cluster node XBX1",d,e.id,e.width,e.height,e.x,e.y,t.parent(d)),E.get(e.id).node=e,R(e);else if(t.children(d).length>0){l.info("A pure cluster node XBX1",d,e.id,e.x,e.y,e.width,e.height,t.parent(d)),e.height+=S,t.node(e.parentId);const u=e?.padding/2||0,x=e?.labelBBox?.height||0,N=x-u||0;l.debug("OffsetY",N,"labelHeight",x,"halfPadding",u),await F(h,e),E.get(e.id).node=e}else{const u=t.node(e.parentId);e.y+=S/2,l.info("A regular node XBX1 - using the padding",e.id,"parent",e.parentId,e.width,e.height,e.x,e.y,"offsetY",e.offsetY,"parent",u,u?.offsetY,e),R(e)}}));const b=S/2;return ne(t,b,{mergeSelfLoops:p}).forEach(function({edge:d,start:e,end:u}){l.info("Edge "+e+" -> "+u+": "+JSON.stringify(d),d),d.points.forEach(k=>k.y+=b);const x=t.node(e),N=t.node(u),M=z(a,d,E,g,x,N,m);K(d,M)}),t.nodes().forEach(function(d){const e=t.node(d);l.info(d,e.type,e.diff),e.isGroup&&(X=e.diff)}),l.warn("Returning from recursive render XAX",f,X),{elem:f,diff:X}},"recursiveRender"),le=w(async(s,t)=>{const g=new Q({multigraph:!0,compound:!0}).setGraph({rankdir:s.direction,nodesep:s.config?.nodeSpacing||s.config?.flowchart?.nodeSpacing||s.nodeSpacing,ranksep:s.config?.rankSpacing||s.config?.flowchart?.rankSpacing||s.rankSpacing,marginx:8,marginy:8}).setDefaultEdgeLabel(function(){return{}}),m=t.select("g");v(m,s.markers,s.type,s.diagramId),D(),H(),Y(),O(),s.nodes.forEach(o=>{g.setNode(o.id,{...o}),o.parentId&&g.setParent(o.id,o.parentId)}),l.debug("Edges:",s.edges),s.edges.forEach(o=>{if(o.start===o.end){const r=o.start,f=r+"---"+r+"---1",h=r+"---"+r+"---2",a=g.node(r);g.setNode(f,{domId:f,id:f,parentId:a.parentId,labelStyle:"",label:"",padding:0,shape:"labelRect",style:"",width:10,height:10}),g.setParent(f,a.parentId),g.setNode(h,{domId:h,id:h,parentId:a.parentId,labelStyle:"",padding:0,shape:"labelRect",label:"",style:"",width:10,height:10}),g.setParent(h,a.parentId);const i=structuredClone(o),n=structuredClone(o),p=structuredClone(o),y=structuredClone(o);n.originalEdge=i,n.selfLoop={id:i.id,order:0},p.originalEdge=i,p.selfLoop={id:i.id,order:1},y.originalEdge=i,y.selfLoop={id:i.id,order:2},n.label="",n.arrowTypeEnd="none",n.endLabelLeft="",n.endLabelRight="",n.startLabelLeft="",n.id=r+"-cyclic-special-1",p.startLabelRight="",p.startLabelLeft="",p.endLabelLeft="",p.endLabelRight="",p.arrowTypeStart="none",p.arrowTypeEnd="none",p.id=r+"-cyclic-special-mid",y.label="",y.startLabelRight="",y.startLabelLeft="",y.arrowTypeStart="none",a.isGroup&&(n.fromCluster=r,y.toCluster=r),y.id=r+"-cyclic-special-2",y.arrowTypeStart="none",g.setEdge(r,f,n,r+"-cyclic-special-0"),g.setEdge(f,h,p,r+"-cyclic-special-1"),g.setEdge(h,r,y,r+"-cyclic-special-2")}else g.setEdge(o.start,o.end,{...o},o.id)}),l.warn("Graph at first:",JSON.stringify(I(g))),J(g),l.warn("Graph after XAX:",JSON.stringify(I(g)));const c=_();await T(m,g,s.type,s.diagramId,void 0,c)},"render");export{ne as getEdgesToRender,le as render}; diff --git a/apps/kimi-code/dist-web/assets/diagram-FQU43EPY-C_ItQEVf.js b/apps/kimi-code/dist-web/assets/diagram-FQU43EPY-D2bRXH1a.js similarity index 98% rename from apps/kimi-code/dist-web/assets/diagram-FQU43EPY-C_ItQEVf.js rename to apps/kimi-code/dist-web/assets/diagram-FQU43EPY-D2bRXH1a.js index 74f8f444b..f0cf49a25 100644 --- a/apps/kimi-code/dist-web/assets/diagram-FQU43EPY-C_ItQEVf.js +++ b/apps/kimi-code/dist-web/assets/diagram-FQU43EPY-D2bRXH1a.js @@ -1,3 +1,3 @@ -import{p as re}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{p as oe,o as se,s as de,g as le,a as ce,b as me,_ as o,l as g,c as D,d as ue,A as xe,q as fe,B as ge,z as M,D as he,i as y,w as P,ak as pe}from"./mermaid.core-DaDTfY6S.js";import{p as be,i as ve}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var T="position frame",$="frame positioned",S="position relation",N="relation positioned",we=o(function(e){g.debug("options str",e)},"setOptions"),ye=o(function(){return{}},"getOptions"),Pe=o(function(){C(),fe()},"clear");function C(){B={}}o(C,"reset");var Se=he.eventmodeling,ke=o(()=>ge({...Se,...M().eventmodeling}),"getConfig"),B={};function O(){let e=Fe;const{ast:n}=B,t=E();if(!n)throw new Error("No data for EventModel");return n.frames.forEach((i,a)=>{const r=G(i,n.dataEntities,t);e=v(e,{$kind:T,index:a,frame:i,textProps:r});let d;K(i)?(g.debug("source frame",i.sourceFrames),d=n.frames.filter(l=>i.sourceFrames.some(c=>c.$refText===l.name)),d.forEach(l=>{e=v(e,{$kind:S,index:a,frame:i,sourceFrame:l})})):e=v(e,{$kind:S,index:a,frame:i})}),e={...e,sortedSwimlanesArray:A(e.swimlanes)},e}o(O,"getState");function I(e){B.ast=e}o(I,"setAst");var s={swimlaneMinHeight:70,swimlanePadding:15,swimlaneGap:10,boxPadding:10,boxOverlap:90,boxDefaultY:0,boxMinWidth:80,boxMaxWidth:450,boxMinHeight:80,boxMaxHeight:750,contentStartX:250,textMaxWidth:430,boxTextFontWeight:"bold",boxTextPadding:10,swimlaneTextFontWeight:"bold",labelUiAutomation:"UI/Automation",labelUiAutomationPrefix:"UI/A: ",labelCommandReadModel:"Command/Read Model",labelCommandReadModelPrefix:"C/RM: ",labelEvents:"Events",labelEventsPrefix:"Stream: "};function E(){return s}o(E,"getDiagramProps");var Fe={boxes:[],swimlanes:{},relations:[],maxR:0,sortedSwimlanesArray:[]};function W(e){const n=e.split(".");if(n.length===2)return n[0]}o(W,"extractNamespace");function H(e){const n=e.split(".");return n.length===2?n[1]:e}o(H,"extractName");function U(e,n){if(!(!n||n.length===0))return Object.values(e).find(t=>t.namespace===n)}o(U,"findSwimlaneByNamespace");function b(e,n,t){return Math.max(n,...Object.keys(e).filter(i=>{const a=Number.parseInt(i);return a>n&&a<t}).map(i=>Number.parseInt(i)))+1}o(b,"findNextAvailableIndex");function _(e,n){const t=W(e.entityIdentifier),i=U(n,t);switch(e.modelEntityType){case"ui":case"pcr":case"processor":return i?{index:i.index,label:i.namespace||s.labelUiAutomation}:t?{index:b(n,0,100),label:s.labelUiAutomationPrefix+t}:{index:0,label:s.labelUiAutomation};case"rmo":case"readmodel":case"cmd":case"command":return i?{index:i.index,label:i.namespace||s.labelCommandReadModel}:t?{index:b(n,100,200),label:s.labelCommandReadModelPrefix+t}:{index:100,label:s.labelCommandReadModel};case"evt":case"event":default:return i?{index:i.index,label:i.namespace||s.labelEvents}:t?{index:b(n,200,300),label:s.labelEventsPrefix+t}:{index:200,label:s.labelEvents}}}o(_,"calculateSwimlaneProps");function L(e){const{themeVariables:n}=M();switch(e.modelEntityType){case"ui":return{fill:n.emUiFill??"white",stroke:n.emUiStroke??"#dbdada"};case"pcr":case"processor":return{fill:n.emProcessorFill??"#edb3f6",stroke:n.emProcessorStroke??"#b88cbf"};case"rmo":case"readmodel":return{fill:n.emReadModelFill??"#d3f1a2",stroke:n.emReadModelStroke??"#a3b732"};case"cmd":case"command":return{fill:n.emCommandFill??"#bcd6fe",stroke:n.emCommandStroke??"#679ac3"};case"evt":case"event":return{fill:n.emEventFill??"#ffb778",stroke:n.emEventStroke??"#c19a0f"};default:return{fill:"red",stroke:"black"}}}o(L,"calculateEntityVisualProps");function G(e,n,t){const i=M(),a=y(H(e.entityIdentifier)??"",i);let r;const d={fontSize:16,fontWeight:700,fontFamily:'"trebuchet ms", verdana, arial, sans-serif',joinWith:"<br/>"};let c=`<b>${P(a,t.textMaxWidth,d)}</b>`;if(e.dataInlineValue&&(r=e.dataInlineValue,r=r.substring(r.indexOf("{")+1),r=r.substring(0,r.lastIndexOf("}")-1),r=y(r,i),r=P(r,t.textMaxWidth,d),r=r.replaceAll(" "," ")),e.dataReference){const p=n.find(w=>w.name===e.dataReference?.$refText);p&&(r=p.dataBlockValue,r=r.substring(r.indexOf(`{ +import{p as re}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{p as oe,o as se,s as de,g as le,a as ce,b as me,_ as o,l as g,c as D,d as ue,A as xe,q as fe,B as ge,z as M,D as he,i as y,w as P,ak as pe}from"./mermaid.core-CJB1tAev.js";import{p as be,i as ve}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var T="position frame",$="frame positioned",S="position relation",N="relation positioned",we=o(function(e){g.debug("options str",e)},"setOptions"),ye=o(function(){return{}},"getOptions"),Pe=o(function(){C(),fe()},"clear");function C(){B={}}o(C,"reset");var Se=he.eventmodeling,ke=o(()=>ge({...Se,...M().eventmodeling}),"getConfig"),B={};function O(){let e=Fe;const{ast:n}=B,t=E();if(!n)throw new Error("No data for EventModel");return n.frames.forEach((i,a)=>{const r=G(i,n.dataEntities,t);e=v(e,{$kind:T,index:a,frame:i,textProps:r});let d;K(i)?(g.debug("source frame",i.sourceFrames),d=n.frames.filter(l=>i.sourceFrames.some(c=>c.$refText===l.name)),d.forEach(l=>{e=v(e,{$kind:S,index:a,frame:i,sourceFrame:l})})):e=v(e,{$kind:S,index:a,frame:i})}),e={...e,sortedSwimlanesArray:A(e.swimlanes)},e}o(O,"getState");function I(e){B.ast=e}o(I,"setAst");var s={swimlaneMinHeight:70,swimlanePadding:15,swimlaneGap:10,boxPadding:10,boxOverlap:90,boxDefaultY:0,boxMinWidth:80,boxMaxWidth:450,boxMinHeight:80,boxMaxHeight:750,contentStartX:250,textMaxWidth:430,boxTextFontWeight:"bold",boxTextPadding:10,swimlaneTextFontWeight:"bold",labelUiAutomation:"UI/Automation",labelUiAutomationPrefix:"UI/A: ",labelCommandReadModel:"Command/Read Model",labelCommandReadModelPrefix:"C/RM: ",labelEvents:"Events",labelEventsPrefix:"Stream: "};function E(){return s}o(E,"getDiagramProps");var Fe={boxes:[],swimlanes:{},relations:[],maxR:0,sortedSwimlanesArray:[]};function W(e){const n=e.split(".");if(n.length===2)return n[0]}o(W,"extractNamespace");function H(e){const n=e.split(".");return n.length===2?n[1]:e}o(H,"extractName");function U(e,n){if(!(!n||n.length===0))return Object.values(e).find(t=>t.namespace===n)}o(U,"findSwimlaneByNamespace");function b(e,n,t){return Math.max(n,...Object.keys(e).filter(i=>{const a=Number.parseInt(i);return a>n&&a<t}).map(i=>Number.parseInt(i)))+1}o(b,"findNextAvailableIndex");function _(e,n){const t=W(e.entityIdentifier),i=U(n,t);switch(e.modelEntityType){case"ui":case"pcr":case"processor":return i?{index:i.index,label:i.namespace||s.labelUiAutomation}:t?{index:b(n,0,100),label:s.labelUiAutomationPrefix+t}:{index:0,label:s.labelUiAutomation};case"rmo":case"readmodel":case"cmd":case"command":return i?{index:i.index,label:i.namespace||s.labelCommandReadModel}:t?{index:b(n,100,200),label:s.labelCommandReadModelPrefix+t}:{index:100,label:s.labelCommandReadModel};case"evt":case"event":default:return i?{index:i.index,label:i.namespace||s.labelEvents}:t?{index:b(n,200,300),label:s.labelEventsPrefix+t}:{index:200,label:s.labelEvents}}}o(_,"calculateSwimlaneProps");function L(e){const{themeVariables:n}=M();switch(e.modelEntityType){case"ui":return{fill:n.emUiFill??"white",stroke:n.emUiStroke??"#dbdada"};case"pcr":case"processor":return{fill:n.emProcessorFill??"#edb3f6",stroke:n.emProcessorStroke??"#b88cbf"};case"rmo":case"readmodel":return{fill:n.emReadModelFill??"#d3f1a2",stroke:n.emReadModelStroke??"#a3b732"};case"cmd":case"command":return{fill:n.emCommandFill??"#bcd6fe",stroke:n.emCommandStroke??"#679ac3"};case"evt":case"event":return{fill:n.emEventFill??"#ffb778",stroke:n.emEventStroke??"#c19a0f"};default:return{fill:"red",stroke:"black"}}}o(L,"calculateEntityVisualProps");function G(e,n,t){const i=M(),a=y(H(e.entityIdentifier)??"",i);let r;const d={fontSize:16,fontWeight:700,fontFamily:'"trebuchet ms", verdana, arial, sans-serif',joinWith:"<br/>"};let c=`<b>${P(a,t.textMaxWidth,d)}</b>`;if(e.dataInlineValue&&(r=e.dataInlineValue,r=r.substring(r.indexOf("{")+1),r=r.substring(0,r.lastIndexOf("}")-1),r=y(r,i),r=P(r,t.textMaxWidth,d),r=r.replaceAll(" "," ")),e.dataReference){const p=n.find(w=>w.name===e.dataReference?.$refText);p&&(r=p.dataBlockValue,r=r.substring(r.indexOf(`{ `)+2),r=r.substring(0,r.lastIndexOf("}")-1),r=y(r,i),r=P(r,t.textMaxWidth,d),r=r.replaceAll(" "," "),r+="<br/>")}const m=r!==void 0;m&&(c+=`<br/><br/><code style="text-align: left; display: block;max-width:${t.textMaxWidth}px">${r}</code>`);const x={fontSize:d.fontSize,fontWeight:d.fontWeight,fontFamily:d.fontFamily},u=pe(c,x),h=m?u.width/3:u.width,f={content:c,width:h,height:u.height};return g.debug(`[${e.name}] ${e.entityIdentifier} text`,f),f}o(G,"calculateTextProps");function V(e,n){const t=n,i=L(t.frame),a={width:t.textProps.width+2*s.boxTextPadding,height:t.textProps.height+2*s.boxTextPadding};return[{$kind:$,frame:t.frame,index:t.index,visual:i,dimension:a,textProps:t.textProps}]}o(V,"decidePositionFrame");function X(e,n,t){return n===void 0?s.contentStartX:n.index===e.index&&e.r?e.r+s.boxPadding:t===void 0?s.contentStartX:t.r-s.boxOverlap+s.boxPadding}o(X,"calculateX");function j(e,n){const t=[...e.map(i=>i.r),n];return Math.max(...t)}o(j,"calculateMaxRight");function A(e){return Object.values(e).sort((n,t)=>n.index-t.index)}o(A,"sortedSwimlanesArray");function Y(e,n){const t=n,i=_(t.frame,e.swimlanes);let a;i.index in e.swimlanes?a=e.swimlanes[i.index]:a={index:i.index,label:i.label,r:0,y:i.index*s.swimlaneMinHeight+s.swimlaneGap,height:s.swimlaneMinHeight,maxHeight:s.swimlaneMinHeight};const r=e.boxes.length>0?e.boxes[e.boxes.length-1]:void 0,d=e.previousSwimlaneNumber!==void 0?e.swimlanes[e.previousSwimlaneNumber]:void 0,l={width:Math.max(s.boxMinWidth,Math.min(s.boxMaxWidth,t.dimension.width))+2*s.boxPadding,height:Math.max(s.boxMinHeight,Math.min(s.boxMaxHeight,t.dimension.height))+2*s.boxPadding},c=X(a,d,r),m=c+l.width+s.boxPadding,x=j(Object.values(e.swimlanes),m);a.r=c+l.width,a.maxHeight=Math.max(a.maxHeight,l.height),a.height=Math.max(s.swimlaneMinHeight,a.maxHeight)+2*s.swimlanePadding;const u={x:c,y:s.swimlanePadding+a.y,r:m,dimension:l,leftSibling:!1,swimlane:a,visual:t.visual,text:t.textProps.content,frame:t.frame,index:t.index},h={...e,boxes:[...e.boxes,u],swimlanes:{...e.swimlanes,[`${a.index}`]:a},previousSwimlaneNumber:i.index,previousFrame:t.frame,maxR:x},f=A(h.swimlanes);f.length>0&&(f[0].y=0);for(let p=1;p<f.length;p++){const w=f[p],R=f[p-1];w.y=R.y+R.height+s.swimlaneGap}return h}o(Y,"evolveFramePositioned");function z(e,n){return e===0&&n.sourceFrames.length===0}o(z,"isFirstFrame");function K(e){return e.sourceFrames!==void 0&&e.sourceFrames!==null&&e.sourceFrames.length>0}o(K,"hasSourceFrame");function k(e,n){if(n!=null)return e.find(t=>t.frame.name===n.name)}o(k,"findBoxByFrame");function q(e,n,t){if(!(t<0))for(let i=t;i>=0;i--){const a=e[i];if(a.swimlane.index!==n)return a}}o(q,"findBoxByLineIndex");function J(e,n){const t=n;if(ve(t.frame)||z(t.index,t.frame))return[];const i=k(e.boxes,t.frame);if(i===void 0)throw new Error(`Target box not found for frame ${t.frame.name}`);let a;return t.sourceFrame?a=k(e.boxes,t.sourceFrame):a=q(e.boxes,i.swimlane.index,t.index-1),a===void 0?[]:[{$kind:N,frame:t.frame,index:t.index,sourceBox:a,targetBox:i}]}o(J,"decidePositionRelation");function Q(e,n){const t=n,i={visual:{fill:"none",stroke:"#000"},source:{x:t.sourceBox.x,y:t.sourceBox.y},target:{x:t.targetBox.x,y:t.targetBox.y},sourceBox:t.sourceBox,targetBox:t.targetBox};return{...e,relations:[...e.relations,i]}}o(Q,"evolveRelationPositioned");var Me={[T]:V,[S]:J},Be={[$]:Y,[N]:Q};function Z(e,n){const t=Me[n.$kind];if(t==null)return[];const i=t(e,n);return g.debug("decided events",i),i}o(Z,"decide");function ee(e,n){const t=n.reduce((i,a)=>{const r=Be[a.$kind];return r==null?i:r(i,a)},e);return g.debug("evolve events",{state:e,newState:t,events:n}),t}o(ee,"evolve");function v(e,n){const t=Z(e,n);return ee(e,t)}o(v,"dispatch");var F={getConfig:ke,setOptions:we,getOptions:ye,clear:Pe,setAccTitle:me,getAccTitle:ce,getAccDescription:le,setAccDescription:de,setDiagramTitle:se,getDiagramTitle:oe,setAst:I,getDiagramProps:E,getState:O},Ee={parse:o(async e=>{const n=await be("eventmodeling",e);g.debug(n),F.setAst(n),re(n,F)},"parse")},Ae=D(),Re=Ae?.eventmodeling;function te(e,n){return t=>{const i=t.swimlane.y+n.swimlanePadding,a=e.append("g").attr("class","em-box");a.append("rect").attr("x",t.x).attr("y",i).attr("rx","3").attr("width",t.dimension.width).attr("height",t.dimension.height).attr("stroke",t.visual.stroke).attr("fill",t.visual.fill),a.append("foreignObject").attr("x",t.x+n.boxPadding).attr("y",i+10).attr("width",t.dimension.width-2*n.boxPadding).attr("height",t.dimension.height-2*n.boxPadding).append("xhtml:div").style("display","table").style("height","100%").style("width","100%").append("span").style("display","table-cell").style("text-align","center").style("vertical-align","middle").html(t.text)}}o(te,"renderD3Box");function ne(e,n){return e>n}o(ne,"dirUpwards");function ie(e,n,t,i){return a=>{const r=a.sourceBox.swimlane.y+n.swimlanePadding,d=a.targetBox.swimlane.y+n.swimlanePadding,l=ne(r,d),c=a.sourceBox.x+a.sourceBox.dimension.width*2/3,m=a.targetBox.x+a.targetBox.dimension.width/3;let x,u;g.debug(`rendering relation up=${l} for `,{sourceBox:a.sourceBox,targetBox:a.targetBox}),l?(x=r,u=d+a.targetBox.dimension.height):(x=r+a.sourceBox.dimension.height,u=d);const h=i.emRelationStroke??a.visual.stroke;e.append("path").attr("class","em-relation").attr("fill",a.visual.fill).attr("stroke",h).attr("stroke-width","1").attr("marker-end",`url(#${t})`).attr("d",`M${c} ${x} L${m} ${u}`)}}o(ie,"renderD3Relation");function ae(e,n,t,i){return a=>{const r=e.append("g").attr("class","em-swimlane"),d=i.emSwimlaneBackgroundOdd??"rgb(250,250,250)",l=i.emSwimlaneBackgroundStroke??"rgb(240,240,240)";r.append("rect").attr("x",0).attr("y",a.y).attr("rx","3").attr("width",n+t.swimlanePadding).attr("height",a.height).attr("fill",d).attr("stroke",l),r.append("text").attr("font-weight",t.swimlaneTextFontWeight).attr("x",30).attr("y",a.y+30).text(a.label)}}o(ae,"renderD3Swimlane");var De=o(function(e,n,t,i){if(g.debug("in eventmodeling renderer",e+` `,"id:",n,t),!Re)throw new Error("EventModeling config not found");const a=i.db,{themeVariables:r,eventmodeling:d}=D(),l=ue(`[id="${n}"]`),c=a.getDiagramProps(),m=a.getState(),x=`em-arrowhead-${n}`,u=r.emArrowhead??"#000000";m.sortedSwimlanesArray.forEach(ae(l,m.maxR,c,r)),m.boxes.forEach(te(l,c)),m.relations.forEach(ie(l,c,x,r)),l.append("defs").append("marker").attr("id",x).attr("markerWidth","10").attr("markerHeight","7").attr("refX","10").attr("refY","3.5").attr("orient","auto").append("polygon").attr("points","0 0, 10 3.5, 0 7").attr("fill",u),xe(void 0,l,d?.padding??30,d?.useMaxWidth)},"draw"),Te={draw:De},$e=o(e=>"","getStyles"),Ne=$e,Ue={parser:Ee,db:F,renderer:Te,styles:Ne};export{Ue as diagram}; diff --git a/apps/kimi-code/dist-web/assets/diagram-G47NLZAW-Cm4DutfF.js b/apps/kimi-code/dist-web/assets/diagram-G47NLZAW-BF9x_uf7.js similarity index 97% rename from apps/kimi-code/dist-web/assets/diagram-G47NLZAW-Cm4DutfF.js rename to apps/kimi-code/dist-web/assets/diagram-G47NLZAW-BF9x_uf7.js index d4551abd9..646a85161 100644 --- a/apps/kimi-code/dist-web/assets/diagram-G47NLZAW-Cm4DutfF.js +++ b/apps/kimi-code/dist-web/assets/diagram-G47NLZAW-BF9x_uf7.js @@ -1,4 +1,4 @@ -import{p as me}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as w,W as ge,z as te,B as Q,F as ye,e as Se,l as ee,be as B,d as j,b as ve,a as xe,o as be,p as we,g as Ce,s as Te,D as Le,bf as $e,q as Ae}from"./mermaid.core-DaDTfY6S.js";import{s as Fe}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{p as Ne}from"./cynefin-VYW2F7L2-0NmB13eq.js";import{b as I}from"./defaultLocale-DX6XiGOO.js";import{o as K}from"./ordinal-Cboi1Yqb.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function Me(e){var a=0,n=e.children,l=n&&n.length;if(!l)a=1;else for(;--l>=0;)a+=n[l].value;e.value=a}function _e(){return this.eachAfter(Me)}function ke(e,a){let n=-1;for(const l of this)e.call(a,l,++n,this);return this}function ze(e,a){for(var n=this,l=[n],r,o,h=-1;n=l.pop();)if(e.call(a,n,++h,this),r=n.children)for(o=r.length-1;o>=0;--o)l.push(r[o]);return this}function Ve(e,a){for(var n=this,l=[n],r=[],o,h,d,g=-1;n=l.pop();)if(r.push(n),o=n.children)for(h=0,d=o.length;h<d;++h)l.push(o[h]);for(;n=r.pop();)e.call(a,n,++g,this);return this}function De(e,a){let n=-1;for(const l of this)if(e.call(a,l,++n,this))return l}function Pe(e){return this.eachAfter(function(a){for(var n=+e(a.data)||0,l=a.children,r=l&&l.length;--r>=0;)n+=l[r].value;a.value=n})}function Be(e){return this.eachBefore(function(a){a.children&&a.children.sort(e)})}function We(e){for(var a=this,n=Ee(a,e),l=[a];a!==n;)a=a.parent,l.push(a);for(var r=l.length;e!==n;)l.splice(r,0,e),e=e.parent;return l}function Ee(e,a){if(e===a)return e;var n=e.ancestors(),l=a.ancestors(),r=null;for(e=n.pop(),a=l.pop();e===a;)r=e,e=n.pop(),a=l.pop();return r}function Re(){for(var e=this,a=[e];e=e.parent;)a.push(e);return a}function He(){return Array.from(this)}function Ie(){var e=[];return this.eachBefore(function(a){a.children||e.push(a)}),e}function Oe(){var e=this,a=[];return e.each(function(n){n!==e&&a.push({source:n.parent,target:n})}),a}function*qe(){var e=this,a,n=[e],l,r,o;do for(a=n.reverse(),n=[];e=a.pop();)if(yield e,l=e.children)for(r=0,o=l.length;r<o;++r)n.push(l[r]);while(n.length)}function ae(e,a){e instanceof Map?(e=[void 0,e],a===void 0&&(a=Ye)):a===void 0&&(a=Xe);for(var n=new U(e),l,r=[n],o,h,d,g;l=r.pop();)if((h=a(l.data))&&(g=(h=Array.from(h)).length))for(l.children=h,d=g-1;d>=0;--d)r.push(o=h[d]=new U(h[d])),o.parent=l,o.depth=l.depth+1;return n.eachBefore(Ue)}function Ge(){return ae(this).eachBefore(je)}function Xe(e){return e.children}function Ye(e){return Array.isArray(e)?e[1]:null}function je(e){e.data.value!==void 0&&(e.value=e.data.value),e.data=e.data.data}function Ue(e){var a=0;do e.height=a;while((e=e.parent)&&e.height<++a)}function U(e){this.data=e,this.depth=this.height=0,this.parent=null}U.prototype=ae.prototype={constructor:U,count:_e,each:ke,eachAfter:Ve,eachBefore:ze,find:De,sum:Pe,sort:Be,path:We,ancestors:Re,descendants:He,leaves:Ie,links:Oe,copy:Ge,[Symbol.iterator]:qe};function Ze(e){if(typeof e!="function")throw new Error;return e}function O(){return 0}function q(e){return function(){return e}}function Je(e){e.x0=Math.round(e.x0),e.y0=Math.round(e.y0),e.x1=Math.round(e.x1),e.y1=Math.round(e.y1)}function Ke(e,a,n,l,r){for(var o=e.children,h,d=-1,g=o.length,c=e.value&&(l-a)/e.value;++d<g;)h=o[d],h.y0=n,h.y1=r,h.x0=a,h.x1=a+=h.value*c}function Qe(e,a,n,l,r){for(var o=e.children,h,d=-1,g=o.length,c=e.value&&(r-n)/e.value;++d<g;)h=o[d],h.x0=a,h.x1=l,h.y0=n,h.y1=n+=h.value*c}var et=(1+Math.sqrt(5))/2;function tt(e,a,n,l,r,o){for(var h=[],d=a.children,g,c,p=0,b=0,s=d.length,x,S,v=a.value,u,y,N,$,V,E,M;p<s;){x=r-n,S=o-l;do u=d[b++].value;while(!u&&b<s);for(y=N=u,E=Math.max(S/x,x/S)/(v*e),M=u*u*E,V=Math.max(N/M,M/y);b<s;++b){if(u+=c=d[b].value,c<y&&(y=c),c>N&&(N=c),M=u*u*E,$=Math.max(N/M,M/y),$>V){u-=c;break}V=$}h.push(g={value:u,dice:x<S,children:d.slice(p,b)}),g.dice?Ke(g,n,l,r,v?l+=S*u/v:o):Qe(g,n,l,v?n+=x*u/v:r,o),v-=u,p=b}return h}const at=(function e(a){function n(l,r,o,h,d){tt(a,l,r,o,h,d)}return n.ratio=function(l){return e((l=+l)>1?l:1)},n})(et);function nt(){var e=at,a=!1,n=1,l=1,r=[0],o=O,h=O,d=O,g=O,c=O;function p(s){return s.x0=s.y0=0,s.x1=n,s.y1=l,s.eachBefore(b),r=[0],a&&s.eachBefore(Je),s}function b(s){var x=r[s.depth],S=s.x0+x,v=s.y0+x,u=s.x1-x,y=s.y1-x;u<S&&(S=u=(S+u)/2),y<v&&(v=y=(v+y)/2),s.x0=S,s.y0=v,s.x1=u,s.y1=y,s.children&&(x=r[s.depth+1]=o(s)/2,S+=c(s)-x,v+=h(s)-x,u-=d(s)-x,y-=g(s)-x,u<S&&(S=u=(S+u)/2),y<v&&(v=y=(v+y)/2),e(s,S,v,u,y))}return p.round=function(s){return arguments.length?(a=!!s,p):a},p.size=function(s){return arguments.length?(n=+s[0],l=+s[1],p):[n,l]},p.tile=function(s){return arguments.length?(e=Ze(s),p):e},p.padding=function(s){return arguments.length?p.paddingInner(s).paddingOuter(s):p.paddingInner()},p.paddingInner=function(s){return arguments.length?(o=typeof s=="function"?s:q(+s),p):o},p.paddingOuter=function(s){return arguments.length?p.paddingTop(s).paddingRight(s).paddingBottom(s).paddingLeft(s):p.paddingTop()},p.paddingTop=function(s){return arguments.length?(h=typeof s=="function"?s:q(+s),p):h},p.paddingRight=function(s){return arguments.length?(d=typeof s=="function"?s:q(+s),p):d},p.paddingBottom=function(s){return arguments.length?(g=typeof s=="function"?s:q(+s),p):g},p.paddingLeft=function(s){return arguments.length?(c=typeof s=="function"?s:q(+s),p):c},p}var ie=class{constructor(){this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.setAccTitle=ve,this.getAccTitle=xe,this.setDiagramTitle=be,this.getDiagramTitle=we,this.getAccDescription=Ce,this.setAccDescription=Te}static{w(this,"TreeMapDB")}getNodes(){return this.nodes}getConfig(){const e=Le,a=te();return Q({...e.treemap,...a.treemap??{}})}addNode(e,a){this.nodes.push(e),this.levels.set(e,a),a===0&&(this.outerNodes.push(e),this.root??=e)}getRoot(){return{name:"",children:this.outerNodes}}addClass(e,a){const n=this.classes.get(e)??{id:e,styles:[],textStyles:[]},l=a.replace(/\\,/g,"§§§").replace(/,/g,";").replace(/§§§/g,",").split(";");l&&l.forEach(r=>{$e(r)&&(n?.textStyles?n.textStyles.push(r):n.textStyles=[r]),n?.styles?n.styles.push(r):n.styles=[r]}),this.classes.set(e,n)}getClasses(){return this.classes}getStylesForClass(e){return this.classes.get(e)?.styles??[]}clear(){Ae(),this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.root=void 0}};function oe(e){if(!e.length)return[];const a=[],n=[];return e.forEach(l=>{const r={name:l.name,children:l.type==="Leaf"?void 0:[]};for(r.classSelector=l?.classSelector,l?.cssCompiledStyles&&(r.cssCompiledStyles=l.cssCompiledStyles),l.type==="Leaf"&&l.value!==void 0&&(r.value=l.value);n.length>0&&n[n.length-1].level>=l.level;)n.pop();if(n.length===0)a.push(r);else{const o=n[n.length-1].node;o.children?o.children.push(r):o.children=[r]}l.type!=="Leaf"&&n.push({node:r,level:l.level})}),a}w(oe,"buildHierarchy");var lt=w((e,a)=>{me(e,a);const n=[];for(const o of e.TreemapRows??[])o.$type==="ClassDefStatement"&&a.addClass(o.className??"",o.styleText??"");for(const o of e.TreemapRows??[]){const h=o.item;if(!h)continue;const d=o.indent?parseInt(o.indent):0,g=rt(h),c=h.classSelector?a.getStylesForClass(h.classSelector):[],p=c.length>0?c:void 0,b={level:d,name:g,type:h.$type,value:h.value,classSelector:h.classSelector,cssCompiledStyles:p};n.push(b)}const l=oe(n),r=w((o,h)=>{for(const d of o)a.addNode(d,h),d.children&&d.children.length>0&&r(d.children,h+1)},"addNodesRecursively");r(l,0)},"populate"),rt=w(e=>e.name?String(e.name):"","getItemName"),ce={parser:{yy:void 0},parse:w(async e=>{try{const n=await Ne("treemap",e);ee.debug("Treemap AST:",n);const l=ce.parser?.yy;if(!(l instanceof ie))throw new Error("parser.parser?.yy was not a TreemapDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");lt(n,l)}catch(a){throw ee.error("Error parsing treemap:",a),a}},"parse")},st=10,W=10,G=25,it=w((e,a,n,l)=>{const r=l.db,o=r.getConfig(),h=o.padding??st,d=r.getDiagramTitle(),g=r.getRoot(),{themeVariables:c}=te();if(!g)return;const p=d?30:0,b=ye(a),s=o.nodeWidth?o.nodeWidth*W:960,x=o.nodeHeight?o.nodeHeight*W:500,S=s,v=x+p;b.attr("viewBox",`0 0 ${S} ${v}`),Se(b,v,S,o.useMaxWidth);let u;try{const t=o.valueFormat||",";if(t==="$0,0")u=w(i=>"$"+I(",")(i),"valueFormat");else if(t.startsWith("$")&&t.includes(",")){const i=/\.\d+/.exec(t),f=i?i[0]:"";u=w(C=>"$"+I(","+f)(C),"valueFormat")}else if(t.startsWith("$")){const i=t.substring(1);u=w(f=>"$"+I(i||"")(f),"valueFormat")}else u=I(t)}catch(t){ee.error("Error creating format function:",t),u=I(",")}const y=K().range(["transparent",c.cScale0,c.cScale1,c.cScale2,c.cScale3,c.cScale4,c.cScale5,c.cScale6,c.cScale7,c.cScale8,c.cScale9,c.cScale10,c.cScale11]),N=K().range(["transparent",c.cScalePeer0,c.cScalePeer1,c.cScalePeer2,c.cScalePeer3,c.cScalePeer4,c.cScalePeer5,c.cScalePeer6,c.cScalePeer7,c.cScalePeer8,c.cScalePeer9,c.cScalePeer10,c.cScalePeer11]),$=K().range([c.cScaleLabel0,c.cScaleLabel1,c.cScaleLabel2,c.cScaleLabel3,c.cScaleLabel4,c.cScaleLabel5,c.cScaleLabel6,c.cScaleLabel7,c.cScaleLabel8,c.cScaleLabel9,c.cScaleLabel10,c.cScaleLabel11]);d&&b.append("text").attr("x",S/2).attr("y",p/2).attr("class","treemapTitle").attr("text-anchor","middle").attr("dominant-baseline","middle").text(d);const V=b.append("g").attr("transform",`translate(0, ${p})`).attr("class","treemapContainer"),E=ae(g).sum(t=>t.value??0).sort((t,i)=>(i.value??0)-(t.value??0)),ne=nt().size([s,x]).paddingTop(t=>t.children&&t.children.length>0?G+W:0).paddingInner(h).paddingLeft(t=>t.children&&t.children.length>0?W:0).paddingRight(t=>t.children&&t.children.length>0?W:0).paddingBottom(t=>t.children&&t.children.length>0?W:0).round(!0)(E),he=ne.descendants().filter(t=>t.children&&t.children.length>0),R=V.selectAll(".treemapSection").data(he).enter().append("g").attr("class","treemapSection").attr("transform",t=>`translate(${t.x0},${t.y0})`);R.append("rect").attr("width",t=>t.x1-t.x0).attr("height",G).attr("class","treemapSectionHeader").attr("fill","none").attr("fill-opacity",.6).attr("stroke-width",.6).attr("style",t=>t.depth===0?"display: none;":""),R.append("clipPath").attr("id",(t,i)=>`clip-section-${a}-${i}`).append("rect").attr("width",t=>Math.max(0,t.x1-t.x0-12)).attr("height",G),R.append("rect").attr("width",t=>t.x1-t.x0).attr("height",t=>t.y1-t.y0).attr("class",(t,i)=>`treemapSection section${i}`).attr("fill",t=>y(t.data.name)).attr("fill-opacity",.6).attr("stroke",t=>N(t.data.name)).attr("stroke-width",2).attr("stroke-opacity",.4).attr("style",t=>{if(t.depth===0)return"display: none;";const i=B({cssCompiledStyles:t.data.cssCompiledStyles});return i.nodeStyles+";"+i.borderStyles.join(";")}),R.append("text").attr("class","treemapSectionLabel").attr("x",6).attr("y",G/2).attr("dominant-baseline","middle").text(t=>t.depth===0?"":t.data.name).attr("font-weight","bold").attr("clip-path",(t,i)=>`url(#clip-section-${a}-${i})`).attr("style",t=>{if(t.depth===0)return"display: none;";const i="dominant-baseline: middle; font-size: 12px; fill:"+$(t.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")}).each(function(t){if(t.depth===0)return;const i=j(this),f=t.data.name;i.text(f);const C=t.x1-t.x0,L=6;let T;o.showValues!==!1&&t.value?T=C-10-30-10-L:T=C-L-6;const m=Math.max(15,T),_=i.node();if(_.getComputedTextLength()>m){let z=f;for(;z.length>0;){if(z=f.substring(0,z.length-1),z.length===0){i.text("..."),_.getComputedTextLength()>m&&i.text("");break}if(i.text(z+"..."),_.getComputedTextLength()<=m)break}}}),o.showValues!==!1&&R.append("text").attr("class","treemapSectionValue").attr("x",t=>t.x1-t.x0-10).attr("y",G/2).attr("text-anchor","end").attr("dominant-baseline","middle").text(t=>t.value?u(t.value):"").attr("font-style","italic").attr("style",t=>{if(t.depth===0)return"display: none;";const i="text-anchor: end; dominant-baseline: middle; font-size: 10px; fill:"+$(t.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")});const le=ne.leaves(),A=le.length>20,de=A?16:38,X=A?14:28,D=A?4:8,H=A?4:6,Z=A?2:4,re=A?8:10,J=A?1:2,Y=V.selectAll(".treemapLeafGroup").data(le).enter().append("g").attr("class",(t,i)=>`treemapNode treemapLeafGroup leaf${i}${t.data.classSelector?` ${t.data.classSelector}`:""}x`).attr("transform",t=>`translate(${t.x0},${t.y0})`);Y.append("rect").attr("width",t=>t.x1-t.x0).attr("height",t=>t.y1-t.y0).attr("class","treemapLeaf").attr("fill",t=>t.parent?y(t.parent.data.name):y(t.data.name)).attr("style",t=>B({cssCompiledStyles:t.data.cssCompiledStyles}).nodeStyles).attr("fill-opacity",.3).attr("stroke",t=>t.parent?y(t.parent.data.name):y(t.data.name)).attr("stroke-width",3),Y.append("clipPath").attr("id",(t,i)=>`clip-${a}-${i}`).append("rect").attr("width",t=>Math.max(0,t.x1-t.x0-4)).attr("height",t=>Math.max(0,t.y1-t.y0-4)),Y.append("text").attr("class","treemapLabel").attr("x",t=>(t.x1-t.x0)/2).attr("y",t=>(t.y1-t.y0)/2).attr("style",t=>{const i=`text-anchor: middle; dominant-baseline: middle; font-size: ${de}px;fill:`+$(t.data.name)+";",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")}).attr("clip-path",(t,i)=>`url(#clip-${a}-${i})`).text(t=>t.data.name).each(function(t){const i=j(this),f=t.x1-t.x0,C=t.y1-t.y0,L=i.node(),T=f-2*Z,P=C-2*Z;if(T<re||P<re){i.style("display","none");return}let m=parseInt(i.style("font-size"),10);const _=.6;for(;L.getComputedTextLength()>T&&m>D;)m--,i.style("font-size",`${m}px`);let F=Math.max(H,Math.min(X,Math.round(m*_))),k=m+J+F;for(;k>P&&m>D&&(m--,F=Math.max(H,Math.min(X,Math.round(m*_))),!(F<H&&m===D));)i.style("font-size",`${m}px`),k=m+J+F;i.style("font-size",`${m}px`),A?(m<D||P<D)&&i.style("display","none"):(L.getComputedTextLength()>T||m<D||P<m)&&i.style("display","none")}),o.showValues!==!1&&Y.append("text").attr("class","treemapValue").attr("x",i=>(i.x1-i.x0)/2).attr("y",function(i){return(i.y1-i.y0)/2}).attr("style",i=>{const f=`text-anchor: middle; dominant-baseline: hanging; font-size: ${X}px;fill:`+$(i.data.name)+";",C=B({cssCompiledStyles:i.data.cssCompiledStyles});return f+C.labelStyles.replace("color:","fill:")}).attr("clip-path",(i,f)=>`url(#clip-${a}-${f})`).text(i=>i.value?u(i.value):"").each(function(i){const f=j(this),C=this.parentNode;if(!C){f.style("display","none");return}const L=j(C).select(".treemapLabel");if(L.empty()||L.style("display")==="none"){f.style("display","none");return}const T=parseFloat(L.style("font-size")),m=Math.max(H,Math.min(X,Math.round(T*.6)));f.style("font-size",`${m}px`);const F=(i.y1-i.y0)/2+T/2+J;f.attr("y",F);const k=i.x1-i.x0,se=i.y1-i.y0-4,fe=k-2*Z;f.node().getComputedTextLength()>fe||F+m>se||m<H?f.style("display","none"):f.style("display",null)});const pe=o.diagramPadding??8;Fe(b,pe,"flowchart",o?.useMaxWidth||!1)},"draw"),ot=w(function(e,a){return a.db.getClasses()},"getClasses"),ct={draw:it,getClasses:ot},ht={sectionStrokeColor:"black",sectionStrokeWidth:"1",sectionFillColor:"#efefef",leafStrokeColor:"black",leafStrokeWidth:"1",leafFillColor:"#efefef",labelFontSize:"12px",valueFontSize:"10px",titleFontSize:"14px"},dt=w(({treemap:e}={})=>{const a=ge(),n=te(),l=Q(a,n.themeVariables),r=Q(ht,e),o=r.titleColor??l.titleColor,h=r.labelColor??l.textColor,d=r.valueColor??l.textColor;return` +import{p as me}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as w,W as ge,z as te,B as Q,F as ye,e as Se,l as ee,be as B,d as j,b as ve,a as xe,o as be,p as we,g as Ce,s as Te,D as Le,bf as $e,q as Ae}from"./mermaid.core-CJB1tAev.js";import{s as Fe}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{p as Ne}from"./cynefin-VYW2F7L2-BIlq342y.js";import{b as I}from"./defaultLocale-DX6XiGOO.js";import{o as K}from"./ordinal-Cboi1Yqb.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function Me(e){var a=0,n=e.children,l=n&&n.length;if(!l)a=1;else for(;--l>=0;)a+=n[l].value;e.value=a}function _e(){return this.eachAfter(Me)}function ke(e,a){let n=-1;for(const l of this)e.call(a,l,++n,this);return this}function ze(e,a){for(var n=this,l=[n],r,o,h=-1;n=l.pop();)if(e.call(a,n,++h,this),r=n.children)for(o=r.length-1;o>=0;--o)l.push(r[o]);return this}function Ve(e,a){for(var n=this,l=[n],r=[],o,h,d,g=-1;n=l.pop();)if(r.push(n),o=n.children)for(h=0,d=o.length;h<d;++h)l.push(o[h]);for(;n=r.pop();)e.call(a,n,++g,this);return this}function De(e,a){let n=-1;for(const l of this)if(e.call(a,l,++n,this))return l}function Pe(e){return this.eachAfter(function(a){for(var n=+e(a.data)||0,l=a.children,r=l&&l.length;--r>=0;)n+=l[r].value;a.value=n})}function Be(e){return this.eachBefore(function(a){a.children&&a.children.sort(e)})}function We(e){for(var a=this,n=Ee(a,e),l=[a];a!==n;)a=a.parent,l.push(a);for(var r=l.length;e!==n;)l.splice(r,0,e),e=e.parent;return l}function Ee(e,a){if(e===a)return e;var n=e.ancestors(),l=a.ancestors(),r=null;for(e=n.pop(),a=l.pop();e===a;)r=e,e=n.pop(),a=l.pop();return r}function Re(){for(var e=this,a=[e];e=e.parent;)a.push(e);return a}function He(){return Array.from(this)}function Ie(){var e=[];return this.eachBefore(function(a){a.children||e.push(a)}),e}function Oe(){var e=this,a=[];return e.each(function(n){n!==e&&a.push({source:n.parent,target:n})}),a}function*qe(){var e=this,a,n=[e],l,r,o;do for(a=n.reverse(),n=[];e=a.pop();)if(yield e,l=e.children)for(r=0,o=l.length;r<o;++r)n.push(l[r]);while(n.length)}function ae(e,a){e instanceof Map?(e=[void 0,e],a===void 0&&(a=Ye)):a===void 0&&(a=Xe);for(var n=new U(e),l,r=[n],o,h,d,g;l=r.pop();)if((h=a(l.data))&&(g=(h=Array.from(h)).length))for(l.children=h,d=g-1;d>=0;--d)r.push(o=h[d]=new U(h[d])),o.parent=l,o.depth=l.depth+1;return n.eachBefore(Ue)}function Ge(){return ae(this).eachBefore(je)}function Xe(e){return e.children}function Ye(e){return Array.isArray(e)?e[1]:null}function je(e){e.data.value!==void 0&&(e.value=e.data.value),e.data=e.data.data}function Ue(e){var a=0;do e.height=a;while((e=e.parent)&&e.height<++a)}function U(e){this.data=e,this.depth=this.height=0,this.parent=null}U.prototype=ae.prototype={constructor:U,count:_e,each:ke,eachAfter:Ve,eachBefore:ze,find:De,sum:Pe,sort:Be,path:We,ancestors:Re,descendants:He,leaves:Ie,links:Oe,copy:Ge,[Symbol.iterator]:qe};function Ze(e){if(typeof e!="function")throw new Error;return e}function O(){return 0}function q(e){return function(){return e}}function Je(e){e.x0=Math.round(e.x0),e.y0=Math.round(e.y0),e.x1=Math.round(e.x1),e.y1=Math.round(e.y1)}function Ke(e,a,n,l,r){for(var o=e.children,h,d=-1,g=o.length,c=e.value&&(l-a)/e.value;++d<g;)h=o[d],h.y0=n,h.y1=r,h.x0=a,h.x1=a+=h.value*c}function Qe(e,a,n,l,r){for(var o=e.children,h,d=-1,g=o.length,c=e.value&&(r-n)/e.value;++d<g;)h=o[d],h.x0=a,h.x1=l,h.y0=n,h.y1=n+=h.value*c}var et=(1+Math.sqrt(5))/2;function tt(e,a,n,l,r,o){for(var h=[],d=a.children,g,c,p=0,b=0,s=d.length,x,S,v=a.value,u,y,N,$,V,E,M;p<s;){x=r-n,S=o-l;do u=d[b++].value;while(!u&&b<s);for(y=N=u,E=Math.max(S/x,x/S)/(v*e),M=u*u*E,V=Math.max(N/M,M/y);b<s;++b){if(u+=c=d[b].value,c<y&&(y=c),c>N&&(N=c),M=u*u*E,$=Math.max(N/M,M/y),$>V){u-=c;break}V=$}h.push(g={value:u,dice:x<S,children:d.slice(p,b)}),g.dice?Ke(g,n,l,r,v?l+=S*u/v:o):Qe(g,n,l,v?n+=x*u/v:r,o),v-=u,p=b}return h}const at=(function e(a){function n(l,r,o,h,d){tt(a,l,r,o,h,d)}return n.ratio=function(l){return e((l=+l)>1?l:1)},n})(et);function nt(){var e=at,a=!1,n=1,l=1,r=[0],o=O,h=O,d=O,g=O,c=O;function p(s){return s.x0=s.y0=0,s.x1=n,s.y1=l,s.eachBefore(b),r=[0],a&&s.eachBefore(Je),s}function b(s){var x=r[s.depth],S=s.x0+x,v=s.y0+x,u=s.x1-x,y=s.y1-x;u<S&&(S=u=(S+u)/2),y<v&&(v=y=(v+y)/2),s.x0=S,s.y0=v,s.x1=u,s.y1=y,s.children&&(x=r[s.depth+1]=o(s)/2,S+=c(s)-x,v+=h(s)-x,u-=d(s)-x,y-=g(s)-x,u<S&&(S=u=(S+u)/2),y<v&&(v=y=(v+y)/2),e(s,S,v,u,y))}return p.round=function(s){return arguments.length?(a=!!s,p):a},p.size=function(s){return arguments.length?(n=+s[0],l=+s[1],p):[n,l]},p.tile=function(s){return arguments.length?(e=Ze(s),p):e},p.padding=function(s){return arguments.length?p.paddingInner(s).paddingOuter(s):p.paddingInner()},p.paddingInner=function(s){return arguments.length?(o=typeof s=="function"?s:q(+s),p):o},p.paddingOuter=function(s){return arguments.length?p.paddingTop(s).paddingRight(s).paddingBottom(s).paddingLeft(s):p.paddingTop()},p.paddingTop=function(s){return arguments.length?(h=typeof s=="function"?s:q(+s),p):h},p.paddingRight=function(s){return arguments.length?(d=typeof s=="function"?s:q(+s),p):d},p.paddingBottom=function(s){return arguments.length?(g=typeof s=="function"?s:q(+s),p):g},p.paddingLeft=function(s){return arguments.length?(c=typeof s=="function"?s:q(+s),p):c},p}var ie=class{constructor(){this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.setAccTitle=ve,this.getAccTitle=xe,this.setDiagramTitle=be,this.getDiagramTitle=we,this.getAccDescription=Ce,this.setAccDescription=Te}static{w(this,"TreeMapDB")}getNodes(){return this.nodes}getConfig(){const e=Le,a=te();return Q({...e.treemap,...a.treemap??{}})}addNode(e,a){this.nodes.push(e),this.levels.set(e,a),a===0&&(this.outerNodes.push(e),this.root??=e)}getRoot(){return{name:"",children:this.outerNodes}}addClass(e,a){const n=this.classes.get(e)??{id:e,styles:[],textStyles:[]},l=a.replace(/\\,/g,"§§§").replace(/,/g,";").replace(/§§§/g,",").split(";");l&&l.forEach(r=>{$e(r)&&(n?.textStyles?n.textStyles.push(r):n.textStyles=[r]),n?.styles?n.styles.push(r):n.styles=[r]}),this.classes.set(e,n)}getClasses(){return this.classes}getStylesForClass(e){return this.classes.get(e)?.styles??[]}clear(){Ae(),this.nodes=[],this.levels=new Map,this.outerNodes=[],this.classes=new Map,this.root=void 0}};function oe(e){if(!e.length)return[];const a=[],n=[];return e.forEach(l=>{const r={name:l.name,children:l.type==="Leaf"?void 0:[]};for(r.classSelector=l?.classSelector,l?.cssCompiledStyles&&(r.cssCompiledStyles=l.cssCompiledStyles),l.type==="Leaf"&&l.value!==void 0&&(r.value=l.value);n.length>0&&n[n.length-1].level>=l.level;)n.pop();if(n.length===0)a.push(r);else{const o=n[n.length-1].node;o.children?o.children.push(r):o.children=[r]}l.type!=="Leaf"&&n.push({node:r,level:l.level})}),a}w(oe,"buildHierarchy");var lt=w((e,a)=>{me(e,a);const n=[];for(const o of e.TreemapRows??[])o.$type==="ClassDefStatement"&&a.addClass(o.className??"",o.styleText??"");for(const o of e.TreemapRows??[]){const h=o.item;if(!h)continue;const d=o.indent?parseInt(o.indent):0,g=rt(h),c=h.classSelector?a.getStylesForClass(h.classSelector):[],p=c.length>0?c:void 0,b={level:d,name:g,type:h.$type,value:h.value,classSelector:h.classSelector,cssCompiledStyles:p};n.push(b)}const l=oe(n),r=w((o,h)=>{for(const d of o)a.addNode(d,h),d.children&&d.children.length>0&&r(d.children,h+1)},"addNodesRecursively");r(l,0)},"populate"),rt=w(e=>e.name?String(e.name):"","getItemName"),ce={parser:{yy:void 0},parse:w(async e=>{try{const n=await Ne("treemap",e);ee.debug("Treemap AST:",n);const l=ce.parser?.yy;if(!(l instanceof ie))throw new Error("parser.parser?.yy was not a TreemapDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");lt(n,l)}catch(a){throw ee.error("Error parsing treemap:",a),a}},"parse")},st=10,W=10,G=25,it=w((e,a,n,l)=>{const r=l.db,o=r.getConfig(),h=o.padding??st,d=r.getDiagramTitle(),g=r.getRoot(),{themeVariables:c}=te();if(!g)return;const p=d?30:0,b=ye(a),s=o.nodeWidth?o.nodeWidth*W:960,x=o.nodeHeight?o.nodeHeight*W:500,S=s,v=x+p;b.attr("viewBox",`0 0 ${S} ${v}`),Se(b,v,S,o.useMaxWidth);let u;try{const t=o.valueFormat||",";if(t==="$0,0")u=w(i=>"$"+I(",")(i),"valueFormat");else if(t.startsWith("$")&&t.includes(",")){const i=/\.\d+/.exec(t),f=i?i[0]:"";u=w(C=>"$"+I(","+f)(C),"valueFormat")}else if(t.startsWith("$")){const i=t.substring(1);u=w(f=>"$"+I(i||"")(f),"valueFormat")}else u=I(t)}catch(t){ee.error("Error creating format function:",t),u=I(",")}const y=K().range(["transparent",c.cScale0,c.cScale1,c.cScale2,c.cScale3,c.cScale4,c.cScale5,c.cScale6,c.cScale7,c.cScale8,c.cScale9,c.cScale10,c.cScale11]),N=K().range(["transparent",c.cScalePeer0,c.cScalePeer1,c.cScalePeer2,c.cScalePeer3,c.cScalePeer4,c.cScalePeer5,c.cScalePeer6,c.cScalePeer7,c.cScalePeer8,c.cScalePeer9,c.cScalePeer10,c.cScalePeer11]),$=K().range([c.cScaleLabel0,c.cScaleLabel1,c.cScaleLabel2,c.cScaleLabel3,c.cScaleLabel4,c.cScaleLabel5,c.cScaleLabel6,c.cScaleLabel7,c.cScaleLabel8,c.cScaleLabel9,c.cScaleLabel10,c.cScaleLabel11]);d&&b.append("text").attr("x",S/2).attr("y",p/2).attr("class","treemapTitle").attr("text-anchor","middle").attr("dominant-baseline","middle").text(d);const V=b.append("g").attr("transform",`translate(0, ${p})`).attr("class","treemapContainer"),E=ae(g).sum(t=>t.value??0).sort((t,i)=>(i.value??0)-(t.value??0)),ne=nt().size([s,x]).paddingTop(t=>t.children&&t.children.length>0?G+W:0).paddingInner(h).paddingLeft(t=>t.children&&t.children.length>0?W:0).paddingRight(t=>t.children&&t.children.length>0?W:0).paddingBottom(t=>t.children&&t.children.length>0?W:0).round(!0)(E),he=ne.descendants().filter(t=>t.children&&t.children.length>0),R=V.selectAll(".treemapSection").data(he).enter().append("g").attr("class","treemapSection").attr("transform",t=>`translate(${t.x0},${t.y0})`);R.append("rect").attr("width",t=>t.x1-t.x0).attr("height",G).attr("class","treemapSectionHeader").attr("fill","none").attr("fill-opacity",.6).attr("stroke-width",.6).attr("style",t=>t.depth===0?"display: none;":""),R.append("clipPath").attr("id",(t,i)=>`clip-section-${a}-${i}`).append("rect").attr("width",t=>Math.max(0,t.x1-t.x0-12)).attr("height",G),R.append("rect").attr("width",t=>t.x1-t.x0).attr("height",t=>t.y1-t.y0).attr("class",(t,i)=>`treemapSection section${i}`).attr("fill",t=>y(t.data.name)).attr("fill-opacity",.6).attr("stroke",t=>N(t.data.name)).attr("stroke-width",2).attr("stroke-opacity",.4).attr("style",t=>{if(t.depth===0)return"display: none;";const i=B({cssCompiledStyles:t.data.cssCompiledStyles});return i.nodeStyles+";"+i.borderStyles.join(";")}),R.append("text").attr("class","treemapSectionLabel").attr("x",6).attr("y",G/2).attr("dominant-baseline","middle").text(t=>t.depth===0?"":t.data.name).attr("font-weight","bold").attr("clip-path",(t,i)=>`url(#clip-section-${a}-${i})`).attr("style",t=>{if(t.depth===0)return"display: none;";const i="dominant-baseline: middle; font-size: 12px; fill:"+$(t.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")}).each(function(t){if(t.depth===0)return;const i=j(this),f=t.data.name;i.text(f);const C=t.x1-t.x0,L=6;let T;o.showValues!==!1&&t.value?T=C-10-30-10-L:T=C-L-6;const m=Math.max(15,T),_=i.node();if(_.getComputedTextLength()>m){let z=f;for(;z.length>0;){if(z=f.substring(0,z.length-1),z.length===0){i.text("..."),_.getComputedTextLength()>m&&i.text("");break}if(i.text(z+"..."),_.getComputedTextLength()<=m)break}}}),o.showValues!==!1&&R.append("text").attr("class","treemapSectionValue").attr("x",t=>t.x1-t.x0-10).attr("y",G/2).attr("text-anchor","end").attr("dominant-baseline","middle").text(t=>t.value?u(t.value):"").attr("font-style","italic").attr("style",t=>{if(t.depth===0)return"display: none;";const i="text-anchor: end; dominant-baseline: middle; font-size: 10px; fill:"+$(t.data.name)+"; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")});const le=ne.leaves(),A=le.length>20,de=A?16:38,X=A?14:28,D=A?4:8,H=A?4:6,Z=A?2:4,re=A?8:10,J=A?1:2,Y=V.selectAll(".treemapLeafGroup").data(le).enter().append("g").attr("class",(t,i)=>`treemapNode treemapLeafGroup leaf${i}${t.data.classSelector?` ${t.data.classSelector}`:""}x`).attr("transform",t=>`translate(${t.x0},${t.y0})`);Y.append("rect").attr("width",t=>t.x1-t.x0).attr("height",t=>t.y1-t.y0).attr("class","treemapLeaf").attr("fill",t=>t.parent?y(t.parent.data.name):y(t.data.name)).attr("style",t=>B({cssCompiledStyles:t.data.cssCompiledStyles}).nodeStyles).attr("fill-opacity",.3).attr("stroke",t=>t.parent?y(t.parent.data.name):y(t.data.name)).attr("stroke-width",3),Y.append("clipPath").attr("id",(t,i)=>`clip-${a}-${i}`).append("rect").attr("width",t=>Math.max(0,t.x1-t.x0-4)).attr("height",t=>Math.max(0,t.y1-t.y0-4)),Y.append("text").attr("class","treemapLabel").attr("x",t=>(t.x1-t.x0)/2).attr("y",t=>(t.y1-t.y0)/2).attr("style",t=>{const i=`text-anchor: middle; dominant-baseline: middle; font-size: ${de}px;fill:`+$(t.data.name)+";",f=B({cssCompiledStyles:t.data.cssCompiledStyles});return i+f.labelStyles.replace("color:","fill:")}).attr("clip-path",(t,i)=>`url(#clip-${a}-${i})`).text(t=>t.data.name).each(function(t){const i=j(this),f=t.x1-t.x0,C=t.y1-t.y0,L=i.node(),T=f-2*Z,P=C-2*Z;if(T<re||P<re){i.style("display","none");return}let m=parseInt(i.style("font-size"),10);const _=.6;for(;L.getComputedTextLength()>T&&m>D;)m--,i.style("font-size",`${m}px`);let F=Math.max(H,Math.min(X,Math.round(m*_))),k=m+J+F;for(;k>P&&m>D&&(m--,F=Math.max(H,Math.min(X,Math.round(m*_))),!(F<H&&m===D));)i.style("font-size",`${m}px`),k=m+J+F;i.style("font-size",`${m}px`),A?(m<D||P<D)&&i.style("display","none"):(L.getComputedTextLength()>T||m<D||P<m)&&i.style("display","none")}),o.showValues!==!1&&Y.append("text").attr("class","treemapValue").attr("x",i=>(i.x1-i.x0)/2).attr("y",function(i){return(i.y1-i.y0)/2}).attr("style",i=>{const f=`text-anchor: middle; dominant-baseline: hanging; font-size: ${X}px;fill:`+$(i.data.name)+";",C=B({cssCompiledStyles:i.data.cssCompiledStyles});return f+C.labelStyles.replace("color:","fill:")}).attr("clip-path",(i,f)=>`url(#clip-${a}-${f})`).text(i=>i.value?u(i.value):"").each(function(i){const f=j(this),C=this.parentNode;if(!C){f.style("display","none");return}const L=j(C).select(".treemapLabel");if(L.empty()||L.style("display")==="none"){f.style("display","none");return}const T=parseFloat(L.style("font-size")),m=Math.max(H,Math.min(X,Math.round(T*.6)));f.style("font-size",`${m}px`);const F=(i.y1-i.y0)/2+T/2+J;f.attr("y",F);const k=i.x1-i.x0,se=i.y1-i.y0-4,fe=k-2*Z;f.node().getComputedTextLength()>fe||F+m>se||m<H?f.style("display","none"):f.style("display",null)});const pe=o.diagramPadding??8;Fe(b,pe,"flowchart",o?.useMaxWidth||!1)},"draw"),ot=w(function(e,a){return a.db.getClasses()},"getClasses"),ct={draw:it,getClasses:ot},ht={sectionStrokeColor:"black",sectionStrokeWidth:"1",sectionFillColor:"#efefef",leafStrokeColor:"black",leafStrokeWidth:"1",leafFillColor:"#efefef",labelFontSize:"12px",valueFontSize:"10px",titleFontSize:"14px"},dt=w(({treemap:e}={})=>{const a=ge(),n=te(),l=Q(a,n.themeVariables),r=Q(ht,e),o=r.titleColor??l.titleColor,h=r.labelColor??l.textColor,d=r.valueColor??l.textColor;return` .treemapNode.section { stroke: ${r.sectionStrokeColor}; stroke-width: ${r.sectionStrokeWidth}; diff --git a/apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-C09rk2Ua.js b/apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-DUn2m-AO.js similarity index 93% rename from apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-C09rk2Ua.js rename to apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-DUn2m-AO.js index b03d3cc85..bc899383c 100644 --- a/apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-C09rk2Ua.js +++ b/apps/kimi-code/dist-web/assets/diagram-NH7WQ7WH-DUn2m-AO.js @@ -1,4 +1,4 @@ -import{p as B}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as b,B as u,F as $,e as C,l as m,b as S,a as D,o as T,p as z,g as F,s as P,z as E,D as A,q as W}from"./mermaid.core-DaDTfY6S.js";import{p as _}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var N=A.packet,w=class{constructor(){this.packet=[],this.setAccTitle=S,this.getAccTitle=D,this.setDiagramTitle=T,this.getDiagramTitle=z,this.getAccDescription=F,this.setAccDescription=P}static{b(this,"PacketDB")}getConfig(){const t=u({...N,...E().packet});return t.showBits&&(t.paddingY+=10),t}getPacket(){return this.packet}pushWord(t){t.length>0&&this.packet.push(t)}clear(){W(),this.packet=[]}},L=1e4,M=b((t,e)=>{B(t,e);let r=-1,o=[],n=1;const{bitsPerRow:l}=e.getConfig();for(let{start:a,end:i,bits:d,label:c}of t.blocks){if(a!==void 0&&i!==void 0&&i<a)throw new Error(`Packet block ${a} - ${i} is invalid. End must be greater than start.`);if(a??=r+1,a!==r+1)throw new Error(`Packet block ${a} - ${i??a} is not contiguous. It should start from ${r+1}.`);if(d===0)throw new Error(`Packet block ${a} is invalid. Cannot have a zero bit field.`);for(i??=a+(d??1)-1,d??=i-a+1,r=i,m.debug(`Packet block ${a} - ${r} with label ${c}`);o.length<=l+1&&e.getPacket().length<L;){const[p,s]=Y({start:a,end:i,bits:d,label:c},n,l);if(o.push(p),p.end+1===n*l&&(e.pushWord(o),o=[],n++),!s)break;({start:a,end:i,bits:d,label:c}=s)}}e.pushWord(o)},"populate"),Y=b((t,e,r)=>{if(t.start===void 0)throw new Error("start should have been set during first phase");if(t.end===void 0)throw new Error("end should have been set during first phase");if(t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);if(t.end+1<=e*r)return[t,void 0];const o=e*r-1,n=e*r;return[{start:t.start,end:o,label:t.label,bits:o-t.start},{start:n,end:t.end,label:t.label,bits:t.end-n}]},"getNextFittingBlock"),v={parser:{yy:void 0},parse:b(async t=>{const e=await _("packet",t),r=v.parser?.yy;if(!(r instanceof w))throw new Error("parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");m.debug(e),M(e,r)},"parse")},I=b((t,e,r,o)=>{const n=o.db,l=n.getConfig(),{rowHeight:a,paddingY:i,bitWidth:d,bitsPerRow:c}=l,p=n.getPacket(),s=n.getDiagramTitle(),h=a+i,g=h*(p.length+1)-(s?0:a),k=d*c+2,f=$(e);f.attr("viewBox",`0 0 ${k} ${g}`),C(f,g,k,l.useMaxWidth);for(const[x,y]of p.entries())O(f,y,x,l);f.append("text").text(s).attr("x",k/2).attr("y",g-h/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),O=b((t,e,r,{rowHeight:o,paddingX:n,paddingY:l,bitWidth:a,bitsPerRow:i,showBits:d})=>{const c=t.append("g"),p=r*(o+l)+l;for(const s of e){const h=s.start%i*a+1,g=(s.end-s.start+1)*a-n;if(c.append("rect").attr("x",h).attr("y",p).attr("width",g).attr("height",o).attr("class","packetBlock"),c.append("text").attr("x",h+g/2).attr("y",p+o/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(s.label),!d)continue;const k=s.end===s.start,f=p-2;c.append("text").attr("x",h+(k?g/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(s.start),k||c.append("text").attr("x",h+g).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(s.end)}},"drawWord"),j={draw:I},q={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},G=b(({packet:t}={})=>{const e=u(q,t);return` +import{p as B}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as b,B as u,F as $,e as C,l as m,b as S,a as D,o as T,p as z,g as F,s as P,z as E,D as A,q as W}from"./mermaid.core-CJB1tAev.js";import{p as _}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var N=A.packet,w=class{constructor(){this.packet=[],this.setAccTitle=S,this.getAccTitle=D,this.setDiagramTitle=T,this.getDiagramTitle=z,this.getAccDescription=F,this.setAccDescription=P}static{b(this,"PacketDB")}getConfig(){const t=u({...N,...E().packet});return t.showBits&&(t.paddingY+=10),t}getPacket(){return this.packet}pushWord(t){t.length>0&&this.packet.push(t)}clear(){W(),this.packet=[]}},L=1e4,M=b((t,e)=>{B(t,e);let r=-1,o=[],n=1;const{bitsPerRow:l}=e.getConfig();for(let{start:a,end:i,bits:d,label:c}of t.blocks){if(a!==void 0&&i!==void 0&&i<a)throw new Error(`Packet block ${a} - ${i} is invalid. End must be greater than start.`);if(a??=r+1,a!==r+1)throw new Error(`Packet block ${a} - ${i??a} is not contiguous. It should start from ${r+1}.`);if(d===0)throw new Error(`Packet block ${a} is invalid. Cannot have a zero bit field.`);for(i??=a+(d??1)-1,d??=i-a+1,r=i,m.debug(`Packet block ${a} - ${r} with label ${c}`);o.length<=l+1&&e.getPacket().length<L;){const[p,s]=Y({start:a,end:i,bits:d,label:c},n,l);if(o.push(p),p.end+1===n*l&&(e.pushWord(o),o=[],n++),!s)break;({start:a,end:i,bits:d,label:c}=s)}}e.pushWord(o)},"populate"),Y=b((t,e,r)=>{if(t.start===void 0)throw new Error("start should have been set during first phase");if(t.end===void 0)throw new Error("end should have been set during first phase");if(t.start>t.end)throw new Error(`Block start ${t.start} is greater than block end ${t.end}.`);if(t.end+1<=e*r)return[t,void 0];const o=e*r-1,n=e*r;return[{start:t.start,end:o,label:t.label,bits:o-t.start},{start:n,end:t.end,label:t.label,bits:t.end-n}]},"getNextFittingBlock"),v={parser:{yy:void 0},parse:b(async t=>{const e=await _("packet",t),r=v.parser?.yy;if(!(r instanceof w))throw new Error("parser.parser?.yy was not a PacketDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");m.debug(e),M(e,r)},"parse")},I=b((t,e,r,o)=>{const n=o.db,l=n.getConfig(),{rowHeight:a,paddingY:i,bitWidth:d,bitsPerRow:c}=l,p=n.getPacket(),s=n.getDiagramTitle(),h=a+i,g=h*(p.length+1)-(s?0:a),k=d*c+2,f=$(e);f.attr("viewBox",`0 0 ${k} ${g}`),C(f,g,k,l.useMaxWidth);for(const[x,y]of p.entries())O(f,y,x,l);f.append("text").text(s).attr("x",k/2).attr("y",g-h/2).attr("dominant-baseline","middle").attr("text-anchor","middle").attr("class","packetTitle")},"draw"),O=b((t,e,r,{rowHeight:o,paddingX:n,paddingY:l,bitWidth:a,bitsPerRow:i,showBits:d})=>{const c=t.append("g"),p=r*(o+l)+l;for(const s of e){const h=s.start%i*a+1,g=(s.end-s.start+1)*a-n;if(c.append("rect").attr("x",h).attr("y",p).attr("width",g).attr("height",o).attr("class","packetBlock"),c.append("text").attr("x",h+g/2).attr("y",p+o/2).attr("class","packetLabel").attr("dominant-baseline","middle").attr("text-anchor","middle").text(s.label),!d)continue;const k=s.end===s.start,f=p-2;c.append("text").attr("x",h+(k?g/2:0)).attr("y",f).attr("class","packetByte start").attr("dominant-baseline","auto").attr("text-anchor",k?"middle":"start").text(s.start),k||c.append("text").attr("x",h+g).attr("y",f).attr("class","packetByte end").attr("dominant-baseline","auto").attr("text-anchor","end").text(s.end)}},"drawWord"),j={draw:I},q={byteFontSize:"10px",startByteColor:"black",endByteColor:"black",labelColor:"black",labelFontSize:"12px",titleColor:"black",titleFontSize:"14px",blockStrokeColor:"black",blockStrokeWidth:"1",blockFillColor:"#efefef"},G=b(({packet:t}={})=>{const e=u(q,t);return` .packetByte { font-size: ${e.byteFontSize}; } diff --git a/apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-DnPyyrOM.js b/apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-BOIp7TNe.js similarity index 96% rename from apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-DnPyyrOM.js rename to apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-BOIp7TNe.js index cf50cd80c..dd7fa5554 100644 --- a/apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-DnPyyrOM.js +++ b/apps/kimi-code/dist-web/assets/diagram-OA4YK3LP-BOIp7TNe.js @@ -1,4 +1,4 @@ -import{I as X}from"./chunk-2Q5K7J3B-DqVWYlyS.js";import{p as O}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{o as G,b as Y,s as F,p as P,g as j,a as q,_ as f,B as A,l as D,F as Z,e as U,z as N,q as J,i as K,ai as Q,D as ee,aj as te}from"./mermaid.core-DaDTfY6S.js";import{p as ne}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var E=/[─━│┃└┗├┣]/,S=/[└┗├┣]/,re=/[─━]/,V=/^[\s│┃]+$/,$=/^\s*(title[\t ]|accTitle[\t ]*:|accDescr[\t ]*[:{])/,k=/^\s*%%/,ie=" ";function L(n){return n.some(e=>E.test(e))}f(L,"isBoxDrawingFormat");function _(n){for(const e of n){const t=S.exec(e);if(t?.index&&t.index>0)return t.index}return 4}f(_,"inferSegmentWidth");function M(n,e){return n.replace(/\bline\s+(\d+)\b/gi,(t,r)=>{const i=parseInt(r,10),a=e.get(i);return a?`line ${a}`:t})}f(M,"remapErrorLines");function R(n){const e=n.split(` +import{I as X}from"./chunk-2Q5K7J3B-DsAC7dRk.js";import{p as O}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{o as G,b as Y,s as F,p as P,g as j,a as q,_ as f,B as A,l as D,F as Z,e as U,z as N,q as J,i as K,ai as Q,D as ee,aj as te}from"./mermaid.core-CJB1tAev.js";import{p as ne}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var E=/[─━│┃└┗├┣]/,S=/[└┗├┣]/,re=/[─━]/,V=/^[\s│┃]+$/,$=/^\s*(title[\t ]|accTitle[\t ]*:|accDescr[\t ]*[:{])/,k=/^\s*%%/,ie=" ";function L(n){return n.some(e=>E.test(e))}f(L,"isBoxDrawingFormat");function _(n){for(const e of n){const t=S.exec(e);if(t?.index&&t.index>0)return t.index}return 4}f(_,"inferSegmentWidth");function M(n,e){return n.replace(/\bline\s+(\d+)\b/gi,(t,r)=>{const i=parseInt(r,10),a=e.get(i);return a?`line ${a}`:t})}f(M,"remapErrorLines");function R(n){const e=n.split(` `),t=new Map;let r=-1;for(const[s,o]of e.entries())if(o.trim()==="treeView-beta"){r=s;break}if(r===-1)return{text:n,lineMap:t};const i=[];for(let s=r+1;s<e.length;s++){const o=e[s];o.trim()===""||k.test(o)||$.test(o)||V.test(o)||i.push(o.replace(/\t/g," "))}if(!L(i))return{text:n,lineMap:t};const a=_(i),c=[];let l=0;for(let s=0;s<=r;s++)c.push(e[s]),l++,t.set(l,s+1);for(let s=r+1;s<e.length;s++){const o=e[s],h=o.trim(),p=s+1;if(h===""){c.push(o),l++,t.set(l,p);continue}if(k.test(o)){c.push(o),l++,t.set(l,p);continue}if($.test(o)){c.push(o),l++,t.set(l,p);continue}if(V.test(o))continue;const d=o.replace(/\t/g," "),w=S.exec(d);if(w?.index!==void 0){const g=w.index,m=Math.round(g/a)+1;let u=g+1;for(;u<d.length&&re.test(d[u]);)u++;for(;u<d.length&&d[u]===" ";)u++;const v=d.slice(u).trimEnd();if(!v)throw new Error(`Line ${p}: Empty node — expected a filename or directory name after the box-drawing prefix`);const W=ie.repeat(m);c.push(W+v),l++,t.set(l,p)}else{if(/^[\s─━│┃└┗├┣]+$/.test(d))continue;if(E.test(d))c.push(o),l++,t.set(l,p);else{if(/^\s+/.test(d))throw new Error(`Line ${p}: Unexpected indentation without box-drawing characters. In box-drawing format, use ├── or └── prefixes for indented nodes.`);c.push(o),l++,t.set(l,p)}}}return{text:c.join(` `),lineMap:t}}f(R,"preprocessBoxDrawing");var x=new X(()=>({cnt:1,stack:[{id:0,level:-1,name:"/",nodeType:"directory",children:[]}]})),oe=f(()=>{x.reset(),J()},"clear"),se=f(()=>x.records.stack[0],"getRoot"),ae=f(()=>x.records.cnt,"getCount"),ce=ee.treeView,le=f(()=>A(ce,N().treeView),"getConfig"),de=f((n,e,t,r,i,a)=>{for(;n<=x.records.stack[x.records.stack.length-1].level;)x.records.stack.pop();const c={id:x.records.cnt++,level:n,name:e,nodeType:t,icon:i,cssClass:r,description:a,children:[]};x.records.stack[x.records.stack.length-1].children.push(c),x.records.stack.push(c)},"addNode"),he={clear:oe,addNode:de,getRoot:se,getCount:ae,getConfig:le,getAccTitle:q,getAccDescription:j,getDiagramTitle:P,setAccDescription:F,setAccTitle:Y,setDiagramTitle:G},I=he,pe=f(n=>{O(n,I);for(const e of n.nodes){const t=typeof e.indent=="number"?e.indent:0;let r=e.name;const i=r.endsWith("/");i&&(r=r.slice(0,-1));const a=i?"directory":"file",c=e.classAnnotation||void 0,l=e.iconAnnotation,s=l!==void 0?l||"none":void 0,o=e.descAnnotation||void 0,h=o?K(o,N()):void 0;I.addNode(t,r,a,c,s,h)}},"populate"),fe={parse:f(async n=>{const{text:e,lineMap:t}=R(n);try{const r=await ne("treeView",e);D.debug(r),pe(r)}catch(r){throw t.size>0&&r instanceof Error&&(r.message=M(r.message,t)),r}},"parse")},b={prefix:"mermaid-treeview",height:24,width:24,icons:{folder:{body:'<path fill="currentColor" d="M10.59 4.59A2 2 0 0 0 9.17 4H4a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.17z"/>'},file:{body:'<path fill="currentColor" fill-rule="evenodd" d="M6 2a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8.83a2 2 0 0 0-.59-1.42l-4.82-4.82A2 2 0 0 0 13.17 2H6Zm7.5 1.9l4.6 4.6h-3.6a1 1 0 0 1-1-1V3.9Z" clip-rule="evenodd"/>'}}};function z(n,e){const t=e?.filenameIcons?.[n];if(t)return t;const r=n.lastIndexOf(".");if(r>0){const i=n.substring(r).toLowerCase(),a=e?.extensionIcons;return a?.[i]??a?.[i.slice(1)]}}f(z,"detectIcon");function C(n,e){return n.includes(":")?n:n in b.icons||!e?`${b.prefix}:${n}`:`${e}:${n}`}f(C,"qualifyIcon");function B(n,e){if(n.icon!=="none"){if(n.icon)return C(n.icon,e.defaultIconPack);if(e.showIcons){if(n.nodeType==="file"){const t=z(n.name,e);if(t==="none")return;if(t)return C(t,e.defaultIconPack)}return`${b.prefix}:${n.nodeType==="directory"?"folder":"file"}`}}}f(B,"getNodeIcon");te([{name:b.prefix,icons:b}]);var y=14,ge=4,ue=16,H=f((n,e)=>`tv-icon-${n}-${e.replace(/[^\w-]/g,"-")}`,"iconSymbolId"),we=f(async(n,e,t,r)=>{const i=new Set,a=f(s=>{const o=B(s,t);o&&i.add(o),s.children.forEach(a)},"collect");if(a(e),i.size===0)return;const c=await Promise.all([...i].map(async s=>({icon:s,svg:await Q(s,{height:y,width:y})}))),l=n.append("defs");for(const{icon:s,svg:o}of c)l.append("g").attr("id",H(r,s)).html(o)},"injectIconDefs"),me=f((n,e,t,r,i,a)=>{const c=r.append("g");let l="treeView-node-label";t.nodeType==="directory"&&(l+=" treeView-node-dir"),t.cssClass&&(l+=` ${t.cssClass}`);const s=y+ge,o=B(t,i),h=o!==void 0;o&&c.append("use").attr("xlink:href",`#${H(a,o)}`).attr("x",n+i.paddingX).attr("y",e+i.paddingY).attr("class","treeView-node-icon");const p=c.append("text").text(t.name).attr("dominant-baseline","middle").attr("class",l),{height:d,width:w}=p.node().getBBox(),g=d+i.paddingY*2,m=n+i.paddingX+(h?s:0);p.attr("x",m),p.attr("y",e+g/2);const u=m+w,v=w+i.paddingX*2+(h?s:0);return t.BBox={x:n,y:e,width:v,height:g},t.cssClass?.split(/\s+/).includes("highlight")&&c.insert("rect",":first-child").attr("x",n).attr("y",e+1).attr("width",0).attr("height",g-2).attr("rx",3).attr("class","treeView-highlight-bg"),{node:t,nodeGroup:c,labelRightEdge:u,centerY:e+g/2}},"positionLabel"),T=f((n,e,t,r,i,a)=>n.append("line").attr("x1",e).attr("y1",t).attr("x2",r).attr("y2",i).attr("stroke-width",a).attr("class","treeView-node-line"),"positionLine"),xe=f((n,e,t,r)=>{let i=0,a=0;const c=[],l=f((h,p,d,w)=>{const g=w*(d.rowIndent+d.paddingX),m=me(g,i,p,h,d,r);c.push(m);const{height:u,width:v}=p.BBox;T(h,g-d.rowIndent,i+u/2,g,i+u/2,d.lineThickness),a=Math.max(a,g+v),i+=u},"drawNode"),s=f((h,p=0)=>{l(n,h,t,p),h.children.forEach(m=>{s(m,p+1)});const{x:d,y:w,height:g}=h.BBox;if(h.children.length){const{y:m,height:u}=h.children[h.children.length-1].BBox;T(n,d+t.paddingX,w+g,d+t.paddingX,m+u/2+t.lineThickness/2,t.lineThickness)}},"processNode");s(e);const o=c.filter(h=>h.node.description);if(o.length>0){const p=Math.max(...c.map(d=>d.labelRightEdge))+ue;for(const d of o){const g=d.nodeGroup.append("text").text(d.node.description).attr("dominant-baseline","middle").attr("class","treeView-node-description").attr("x",p).attr("y",d.centerY).node().getBBox();a=Math.max(a,p+g.width+t.paddingX)}}for(const h of c)if(h.node.cssClass?.split(/\s+/).includes("highlight")){const p=h.nodeGroup.select(".treeView-highlight-bg");if(!p.empty()){const d=a-h.node.BBox.x+8;p.attr("width",d),a=Math.max(a,h.node.BBox.x+d+2)}}return{totalHeight:i,totalWidth:a}},"drawTree"),ve=f(async(n,e,t,r)=>{D.debug(`Rendering treeView diagram `+n);const i=r.db,a=i.getRoot(),c=i.getConfig(),l=Z(e);await we(l,a,c,e);const s=l.append("g");s.attr("class","tree-view");const{totalHeight:o,totalWidth:h}=xe(s,a,c,e);l.attr("viewBox",`-${c.lineThickness/2} 0 ${h} ${o}`),U(l,o,h,c.useMaxWidth)},"draw"),be={draw:ve},Ie=be,Ce={labelFontSize:"16px",labelColor:"black",lineColor:"black",iconColor:"#546e7a",descriptionColor:"#6a9955",highlightBg:"rgba(255, 193, 7, 0.15)",highlightStroke:"#ffc107"},ye=f(({treeView:n})=>{const{labelFontSize:e,labelColor:t,lineColor:r,iconColor:i,descriptionColor:a,highlightBg:c,highlightStroke:l}=A(Ce,n);return` diff --git a/apps/kimi-code/dist-web/assets/diagram-WEI45ONY-DRhsbaVI.js b/apps/kimi-code/dist-web/assets/diagram-WEI45ONY-CFwFRAWa.js similarity index 95% rename from apps/kimi-code/dist-web/assets/diagram-WEI45ONY-DRhsbaVI.js rename to apps/kimi-code/dist-web/assets/diagram-WEI45ONY-CFwFRAWa.js index 9261ef844..b2a80168d 100644 --- a/apps/kimi-code/dist-web/assets/diagram-WEI45ONY-DRhsbaVI.js +++ b/apps/kimi-code/dist-web/assets/diagram-WEI45ONY-CFwFRAWa.js @@ -1,4 +1,4 @@ -import{p as k}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{s as R,g as F,p as I,o as _,a as D,b as E,_ as c,F as z,q as P,B as y,z as C,D as G,l as B,W,e as V}from"./mermaid.core-DaDTfY6S.js";import{p as H}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var m={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},w={axes:[],curves:[],options:m},x=structuredClone(w),j=G.radar,q=c(()=>y({...j,...C().radar}),"getConfig"),b=c(()=>x.axes,"getAxes"),N=c(()=>x.curves,"getCurves"),U=c(()=>x.options,"getOptions"),X=c(a=>{x.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Y=c(a=>{x.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:Z(t.entries)}))},"setCurves"),Z=c(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=b();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>s.axis?.$refText===e.name);if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),J=c(a=>{const t=a.reduce((e,r)=>(e[r.name]=r,e),{});x.options={showLegend:t.showLegend?.value??m.showLegend,ticks:t.ticks?.value??m.ticks,max:t.max?.value??m.max,min:t.min?.value??m.min,graticule:t.graticule?.value??m.graticule}},"setOptions"),K=c(()=>{P(),x=structuredClone(w)},"clear"),$={getAxes:b,getCurves:N,getOptions:U,setAxes:X,setCurves:Y,setOptions:J,getConfig:q,clear:K,setAccTitle:E,getAccTitle:D,setDiagramTitle:_,getDiagramTitle:I,getAccDescription:F,setAccDescription:R},Q=c(a=>{k(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),tt={parse:c(async a=>{const t=await H("radar",a);B.debug(t),Q(t)},"parse")},et=c((a,t,e,r)=>{const s=r.db,i=s.getAxes(),l=s.getCurves(),n=s.getOptions(),o=s.getConfig(),d=s.getDiagramTitle(),p=z(t),u=at(p,o),g=n.max??Math.max(...l.map(f=>Math.max(...f.entries))),h=n.min,v=Math.min(o.width,o.height)/2;rt(u,i,v,n.ticks,n.graticule),st(u,i,v,o),A(u,i,l,h,g,n.graticule,o),T(u,l,n.showLegend,o),u.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-o.height/2-o.marginTop)},"draw"),at=c((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return V(a,r,e,t.useMaxWidth??!0),a.attr("viewBox",`0 0 ${e} ${r}`).attr("overflow","visible"),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),rt=c((a,t,e,r,s)=>{if(s==="circle")for(let i=0;i<r;i++){const l=e*(i+1)/r;a.append("circle").attr("r",l).attr("class","radarGraticule")}else if(s==="polygon"){const i=t.length;for(let l=0;l<r;l++){const n=e*(l+1)/r,o=t.map((d,p)=>{const u=2*p*Math.PI/i-Math.PI/2,g=n*Math.cos(u),h=n*Math.sin(u);return`${g},${h}`}).join(" ");a.append("polygon").attr("points",o).attr("class","radarGraticule")}}},"drawGraticule"),st=c((a,t,e,r)=>{const s=t.length;for(let i=0;i<s;i++){const l=t[i].label,n=2*i*Math.PI/s-Math.PI/2,o=Math.cos(n),d=Math.sin(n);a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*o).attr("y2",e*r.axisScaleFactor*d).attr("class","radarAxisLine");const p=o>.01?"start":o<-.01?"end":"middle",u=d>.01?"hanging":d<-.01?"auto":"central",g=4;a.append("text").text(l).attr("x",e*r.axisLabelFactor*o+g*o).attr("y",e*r.axisLabelFactor*d+g*d).attr("text-anchor",p).attr("dominant-baseline",u).attr("class","radarAxisLabel")}},"drawAxes");function A(a,t,e,r,s,i,l){const n=t.length,o=Math.min(l.width,l.height)/2;e.forEach((d,p)=>{if(d.entries.length!==n)return;const u=d.entries.map((g,h)=>{const v=2*Math.PI*h/n-Math.PI/2,f=M(g,r,s,o),S=f*Math.cos(v),O=f*Math.sin(v);return{x:S,y:O}});i==="circle"?a.append("path").attr("d",L(u,l.curveTension)).attr("class",`radarCurve-${p}`):i==="polygon"&&a.append("polygon").attr("points",u.map(g=>`${g.x},${g.y}`).join(" ")).attr("class",`radarCurve-${p}`)})}c(A,"drawCurves");function M(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}c(M,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const i=a[(s-1+e)%e],l=a[s],n=a[(s+1)%e],o=a[(s+2)%e],d={x:l.x+(n.x-i.x)*t,y:l.y+(n.y-i.y)*t},p={x:n.x-(o.x-l.x)*t,y:n.y-(o.y-l.y)*t};r+=` C${d.x},${d.y} ${p.x},${p.y} ${n.x},${n.y}`}return`${r} Z`}c(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,i=-(r.height/2+r.marginTop)*3/4,l=20;t.forEach((n,o)=>{const d=a.append("g").attr("transform",`translate(${s}, ${i+o*l})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${o}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}c(T,"drawLegend");var nt={draw:et},ot=c((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=` +import{p as k}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{s as R,g as F,p as I,o as _,a as D,b as E,_ as c,F as z,q as P,B as y,z as C,D as G,l as B,W,e as V}from"./mermaid.core-CJB1tAev.js";import{p as H}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var m={showLegend:!0,ticks:5,max:null,min:0,graticule:"circle"},w={axes:[],curves:[],options:m},x=structuredClone(w),j=G.radar,q=c(()=>y({...j,...C().radar}),"getConfig"),b=c(()=>x.axes,"getAxes"),N=c(()=>x.curves,"getCurves"),U=c(()=>x.options,"getOptions"),X=c(a=>{x.axes=a.map(t=>({name:t.name,label:t.label??t.name}))},"setAxes"),Y=c(a=>{x.curves=a.map(t=>({name:t.name,label:t.label??t.name,entries:Z(t.entries)}))},"setCurves"),Z=c(a=>{if(a[0].axis==null)return a.map(e=>e.value);const t=b();if(t.length===0)throw new Error("Axes must be populated before curves for reference entries");return t.map(e=>{const r=a.find(s=>s.axis?.$refText===e.name);if(r===void 0)throw new Error("Missing entry for axis "+e.label);return r.value})},"computeCurveEntries"),J=c(a=>{const t=a.reduce((e,r)=>(e[r.name]=r,e),{});x.options={showLegend:t.showLegend?.value??m.showLegend,ticks:t.ticks?.value??m.ticks,max:t.max?.value??m.max,min:t.min?.value??m.min,graticule:t.graticule?.value??m.graticule}},"setOptions"),K=c(()=>{P(),x=structuredClone(w)},"clear"),$={getAxes:b,getCurves:N,getOptions:U,setAxes:X,setCurves:Y,setOptions:J,getConfig:q,clear:K,setAccTitle:E,getAccTitle:D,setDiagramTitle:_,getDiagramTitle:I,getAccDescription:F,setAccDescription:R},Q=c(a=>{k(a,$);const{axes:t,curves:e,options:r}=a;$.setAxes(t),$.setCurves(e),$.setOptions(r)},"populate"),tt={parse:c(async a=>{const t=await H("radar",a);B.debug(t),Q(t)},"parse")},et=c((a,t,e,r)=>{const s=r.db,i=s.getAxes(),l=s.getCurves(),n=s.getOptions(),o=s.getConfig(),d=s.getDiagramTitle(),p=z(t),u=at(p,o),g=n.max??Math.max(...l.map(f=>Math.max(...f.entries))),h=n.min,v=Math.min(o.width,o.height)/2;rt(u,i,v,n.ticks,n.graticule),st(u,i,v,o),A(u,i,l,h,g,n.graticule,o),T(u,l,n.showLegend,o),u.append("text").attr("class","radarTitle").text(d).attr("x",0).attr("y",-o.height/2-o.marginTop)},"draw"),at=c((a,t)=>{const e=t.width+t.marginLeft+t.marginRight,r=t.height+t.marginTop+t.marginBottom,s={x:t.marginLeft+t.width/2,y:t.marginTop+t.height/2};return V(a,r,e,t.useMaxWidth??!0),a.attr("viewBox",`0 0 ${e} ${r}`).attr("overflow","visible"),a.append("g").attr("transform",`translate(${s.x}, ${s.y})`)},"drawFrame"),rt=c((a,t,e,r,s)=>{if(s==="circle")for(let i=0;i<r;i++){const l=e*(i+1)/r;a.append("circle").attr("r",l).attr("class","radarGraticule")}else if(s==="polygon"){const i=t.length;for(let l=0;l<r;l++){const n=e*(l+1)/r,o=t.map((d,p)=>{const u=2*p*Math.PI/i-Math.PI/2,g=n*Math.cos(u),h=n*Math.sin(u);return`${g},${h}`}).join(" ");a.append("polygon").attr("points",o).attr("class","radarGraticule")}}},"drawGraticule"),st=c((a,t,e,r)=>{const s=t.length;for(let i=0;i<s;i++){const l=t[i].label,n=2*i*Math.PI/s-Math.PI/2,o=Math.cos(n),d=Math.sin(n);a.append("line").attr("x1",0).attr("y1",0).attr("x2",e*r.axisScaleFactor*o).attr("y2",e*r.axisScaleFactor*d).attr("class","radarAxisLine");const p=o>.01?"start":o<-.01?"end":"middle",u=d>.01?"hanging":d<-.01?"auto":"central",g=4;a.append("text").text(l).attr("x",e*r.axisLabelFactor*o+g*o).attr("y",e*r.axisLabelFactor*d+g*d).attr("text-anchor",p).attr("dominant-baseline",u).attr("class","radarAxisLabel")}},"drawAxes");function A(a,t,e,r,s,i,l){const n=t.length,o=Math.min(l.width,l.height)/2;e.forEach((d,p)=>{if(d.entries.length!==n)return;const u=d.entries.map((g,h)=>{const v=2*Math.PI*h/n-Math.PI/2,f=M(g,r,s,o),S=f*Math.cos(v),O=f*Math.sin(v);return{x:S,y:O}});i==="circle"?a.append("path").attr("d",L(u,l.curveTension)).attr("class",`radarCurve-${p}`):i==="polygon"&&a.append("polygon").attr("points",u.map(g=>`${g.x},${g.y}`).join(" ")).attr("class",`radarCurve-${p}`)})}c(A,"drawCurves");function M(a,t,e,r){const s=Math.min(Math.max(a,t),e);return r*(s-t)/(e-t)}c(M,"relativeRadius");function L(a,t){const e=a.length;let r=`M${a[0].x},${a[0].y}`;for(let s=0;s<e;s++){const i=a[(s-1+e)%e],l=a[s],n=a[(s+1)%e],o=a[(s+2)%e],d={x:l.x+(n.x-i.x)*t,y:l.y+(n.y-i.y)*t},p={x:n.x-(o.x-l.x)*t,y:n.y-(o.y-l.y)*t};r+=` C${d.x},${d.y} ${p.x},${p.y} ${n.x},${n.y}`}return`${r} Z`}c(L,"closedRoundCurve");function T(a,t,e,r){if(!e)return;const s=(r.width/2+r.marginRight)*3/4,i=-(r.height/2+r.marginTop)*3/4,l=20;t.forEach((n,o)=>{const d=a.append("g").attr("transform",`translate(${s}, ${i+o*l})`);d.append("rect").attr("width",12).attr("height",12).attr("class",`radarLegendBox-${o}`),d.append("text").attr("x",16).attr("y",0).attr("class","radarLegendText").text(n.label)})}c(T,"drawLegend");var nt={draw:et},ot=c((a,t)=>{let e="";for(let r=0;r<a.THEME_COLOR_LIMIT;r++){const s=a[`cScale${r}`];e+=` .radarCurve-${r} { color: ${s}; fill: ${s}; diff --git a/apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-C6JPA7C_.js b/apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-B4NTctc_.js similarity index 87% rename from apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-C6JPA7C_.js rename to apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-B4NTctc_.js index e9b3835a7..b3fad21e0 100644 --- a/apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-C6JPA7C_.js +++ b/apps/kimi-code/dist-web/assets/ebnfDiagram-CCIWWBDH-B4NTctc_.js @@ -1 +1 @@ -import{g as l,r as m,d as n}from"./chunk-MOJQB5TN-Ce2Y728v.js";import{p}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as t,l as o}from"./mermaid.core-DaDTfY6S.js";import{M as u,a as f}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var c=f().RailroadEbnf.parser.LangiumParser,s=t(e=>{const r=e.alternatives.map(E);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformChoice"),E=t(e=>{const r=e.elements.map(d);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformSequence"),i=t(e=>{switch(e.$type){case"EbnfTerminal":return{type:"terminal",value:e.value};case"EbnfNonTerminal":return{type:"nonterminal",name:e.name};case"EbnfSpecial":return{type:"special",text:e.text};case"EbnfGroup":return s(e.element);case"EbnfOptional":return{type:"optional",element:s(e.element)};case"EbnfRepetition":return{type:"repetition",element:s(e.element),min:0,max:1/0};default:throw new Error(`Unsupported EBNF primary node: ${e.$type}`)}},"transformPrimary"),b=t((e,r)=>{switch(r.$type){case"EbnfOptionalPostfix":return{type:"optional",element:e};case"EbnfZeroOrMorePostfix":return{type:"repetition",element:e,min:0,max:1/0};case"EbnfOneOrMorePostfix":return{type:"repetition",element:e,min:1,max:1/0};case"EbnfExceptionPostfix":return{type:"sequence",elements:[e,{type:"terminal",value:"-"},i(r.except)]};default:throw new Error(`Unsupported EBNF postfix node: ${r.$type}`)}},"transformPostfix"),d=t(e=>e.postfixes.reduce((r,a)=>b(r,a),i(e.base)),"transformTerm"),y=t(e=>({name:e.name,definition:s(e.definition)}),"transformRule"),v=t(e=>{p(e,n),e.title&&n.setTitle(e.title),e.rules.map(r=>n.addRule(y(r)))},"populateDb"),g={parse:t(e=>{n.clear(),o.debug("[EBNF Parser] Starting Langium parse");const r=c.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new u(r);const a=r.value;o.debug("[EBNF Parser] Parsed rules:",a.rules.length),v(a),o.debug("[EBNF Parser] Parse complete")},"parse"),parser:{yy:n}},S={parser:g,db:n,renderer:m,styles:l};export{S as diagram}; +import{g as l,r as m,d as n}from"./chunk-MOJQB5TN-JQ2kJR9W.js";import{p}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as t,l as o}from"./mermaid.core-CJB1tAev.js";import{M as u,a as f}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var c=f().RailroadEbnf.parser.LangiumParser,s=t(e=>{const r=e.alternatives.map(E);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformChoice"),E=t(e=>{const r=e.elements.map(d);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformSequence"),i=t(e=>{switch(e.$type){case"EbnfTerminal":return{type:"terminal",value:e.value};case"EbnfNonTerminal":return{type:"nonterminal",name:e.name};case"EbnfSpecial":return{type:"special",text:e.text};case"EbnfGroup":return s(e.element);case"EbnfOptional":return{type:"optional",element:s(e.element)};case"EbnfRepetition":return{type:"repetition",element:s(e.element),min:0,max:1/0};default:throw new Error(`Unsupported EBNF primary node: ${e.$type}`)}},"transformPrimary"),b=t((e,r)=>{switch(r.$type){case"EbnfOptionalPostfix":return{type:"optional",element:e};case"EbnfZeroOrMorePostfix":return{type:"repetition",element:e,min:0,max:1/0};case"EbnfOneOrMorePostfix":return{type:"repetition",element:e,min:1,max:1/0};case"EbnfExceptionPostfix":return{type:"sequence",elements:[e,{type:"terminal",value:"-"},i(r.except)]};default:throw new Error(`Unsupported EBNF postfix node: ${r.$type}`)}},"transformPostfix"),d=t(e=>e.postfixes.reduce((r,a)=>b(r,a),i(e.base)),"transformTerm"),y=t(e=>({name:e.name,definition:s(e.definition)}),"transformRule"),v=t(e=>{p(e,n),e.title&&n.setTitle(e.title),e.rules.map(r=>n.addRule(y(r)))},"populateDb"),g={parse:t(e=>{n.clear(),o.debug("[EBNF Parser] Starting Langium parse");const r=c.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new u(r);const a=r.value;o.debug("[EBNF Parser] Parsed rules:",a.rules.length),v(a),o.debug("[EBNF Parser] Parse complete")},"parse"),parser:{yy:n}},S={parser:g,db:n,renderer:m,styles:l};export{S as diagram}; diff --git a/apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-xK3dRTZk.js b/apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-DVzumNgk.js similarity index 99% rename from apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-xK3dRTZk.js rename to apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-DVzumNgk.js index c4af92731..317317275 100644 --- a/apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-xK3dRTZk.js +++ b/apps/kimi-code/dist-web/assets/erDiagram-Q63AITRT-DVzumNgk.js @@ -1,4 +1,4 @@ -import{g as Mt}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as Bt}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as l,b as Ft,a as Yt,s as Pt,g as zt,o as Gt,p as Kt,c as it,l as V,q as Ut,r as Zt,t as jt,u as Wt,v as qt,x as Qt,d as Xt,y as Ht}from"./mermaid.core-DaDTfY6S.js";import{c as Jt}from"./channel-d4fEaqwQ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var _t=(function(){var e=l(function(I,n,c,o){for(c=c||{},o=I.length;o--;c[I[o]]=n);return c},"o"),i=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52],h=[1,10],a=[1,11],u=[1,12],d=[1,13],y=[1,23],f=[1,24],m=[1,25],j=[1,26],W=[1,27],S=[1,19],q=[1,28],M=[1,29],D=[1,20],R=[1,18],T=[1,21],C=[1,22],nt=[1,36],at=[1,37],ct=[1,38],ot=[1,39],lt=[1,40],B=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52,66,67,68,69,70],O=[1,45],N=[1,46],F=[1,55],Y=[40,48,50,51,52,71,72],P=[1,66],z=[1,64],A=[1,61],G=[1,65],K=[1,67],Q=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,51,52,66,67,68,69,70],gt=[66,67,68,69,70],bt=[1,85],kt=[1,84],mt=[1,82],Et=[1,83],St=[6,10,42,47],L=[6,10,13,41,42,47,48,49],X=[1,93],H=[1,92],J=[1,91],U=[19,58],Tt=[1,102],Ot=[1,101],ht=[19,58,61,63],ut={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,DECIMAL_NUM:51,ENTITY_ONE:52,attribute:53,attributeType:54,attributeName:55,attributeKeyTypeList:56,attributeComment:57,ATTRIBUTE_WORD:58,"?":59,attributeKeyType:60,",":61,ATTRIBUTE_KEY:62,COMMENT:63,cardinality:64,relType:65,ZERO_OR_ONE:66,ZERO_OR_MORE:67,ONE_OR_MORE:68,ONLY_ONE:69,MD_PARENT:70,NON_IDENTIFYING:71,IDENTIFYING:72,WORD:73,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",51:"DECIMAL_NUM",52:"ENTITY_ONE",58:"ATTRIBUTE_WORD",59:"?",61:",",62:"ATTRIBUTE_KEY",63:"COMMENT",66:"ZERO_OR_ONE",67:"ZERO_OR_MORE",68:"ONE_OR_MORE",69:"ONLY_ONE",70:"MD_PARENT",71:"NON_IDENTIFYING",72:"IDENTIFYING",73:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[11,1],[11,1],[11,1],[18,1],[18,2],[53,2],[53,3],[53,3],[53,4],[54,1],[54,2],[55,1],[56,1],[56,3],[60,1],[57,1],[12,3],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[14,1],[14,1],[14,1]],performAction:l(function(n,c,o,r,p,t,Z){var s=t.length-1;switch(p){case 1:break;case 2:this.$=[];break;case 3:t[s-1].push(t[s]),this.$=t[s-1];break;case 4:case 5:this.$=t[s];break;case 6:case 7:this.$=[];break;case 8:r.addEntity(t[s-4]),r.addEntity(t[s-2]),r.addRelationship(t[s-4],t[s],t[s-2],t[s-3]);break;case 9:r.addEntity(t[s-8]),r.addEntity(t[s-4]),r.addRelationship(t[s-8],t[s],t[s-4],t[s-5]),r.setClass([t[s-8]],t[s-6]),r.setClass([t[s-4]],t[s-2]);break;case 10:r.addEntity(t[s-6]),r.addEntity(t[s-2]),r.addRelationship(t[s-6],t[s],t[s-2],t[s-3]),r.setClass([t[s-6]],t[s-4]);break;case 11:r.addEntity(t[s-6]),r.addEntity(t[s-4]),r.addRelationship(t[s-6],t[s],t[s-4],t[s-5]),r.setClass([t[s-4]],t[s-2]);break;case 12:r.addEntity(t[s-3]),r.addAttributes(t[s-3],t[s-1]);break;case 13:r.addEntity(t[s-5]),r.addAttributes(t[s-5],t[s-1]),r.setClass([t[s-5]],t[s-3]);break;case 14:r.addEntity(t[s-2]);break;case 15:r.addEntity(t[s-4]),r.setClass([t[s-4]],t[s-2]);break;case 16:r.addEntity(t[s]);break;case 17:r.addEntity(t[s-2]),r.setClass([t[s-2]],t[s]);break;case 18:r.addEntity(t[s-6],t[s-4]),r.addAttributes(t[s-6],t[s-1]);break;case 19:r.addEntity(t[s-8],t[s-6]),r.addAttributes(t[s-8],t[s-1]),r.setClass([t[s-8]],t[s-3]);break;case 20:r.addEntity(t[s-5],t[s-3]);break;case 21:r.addEntity(t[s-7],t[s-5]),r.setClass([t[s-7]],t[s-2]);break;case 22:r.addEntity(t[s-3],t[s-1]);break;case 23:r.addEntity(t[s-5],t[s-3]),r.setClass([t[s-5]],t[s]);break;case 24:case 25:this.$=t[s].trim(),r.setAccTitle(this.$);break;case 26:case 27:this.$=t[s].trim(),r.setAccDescription(this.$);break;case 32:r.setDirection("TB");break;case 33:r.setDirection("BT");break;case 34:r.setDirection("RL");break;case 35:r.setDirection("LR");break;case 36:this.$=t[s-3],r.addClass(t[s-2],t[s-1]);break;case 37:case 38:case 59:case 68:this.$=[t[s]];break;case 39:case 40:this.$=t[s-2].concat([t[s]]);break;case 41:this.$=t[s-2],r.setClass(t[s-1],t[s]);break;case 42:this.$=t[s-3],r.addCssStyles(t[s-2],t[s-1]);break;case 43:this.$=[t[s]];break;case 44:t[s-2].push(t[s]),this.$=t[s-2];break;case 46:this.$=t[s-1]+t[s];break;case 54:case 80:case 81:this.$=t[s].replace(/"/g,"");break;case 55:case 56:case 57:case 58:case 82:this.$=t[s];break;case 60:t[s].push(t[s-1]),this.$=t[s];break;case 61:this.$={type:t[s-1],name:t[s]};break;case 62:this.$={type:t[s-2],name:t[s-1],keys:t[s]};break;case 63:this.$={type:t[s-2],name:t[s-1],comment:t[s]};break;case 64:this.$={type:t[s-3],name:t[s-2],keys:t[s-1],comment:t[s]};break;case 65:case 67:case 70:this.$=t[s];break;case 66:this.$=t[s-1]+t[s];break;case 69:t[s-2].push(t[s]),this.$=t[s-2];break;case 71:this.$=t[s].replace(/"/g,"");break;case 72:this.$={cardA:t[s],relType:t[s-1],cardB:t[s-2]};break;case 73:this.$=r.Cardinality.ZERO_OR_ONE;break;case 74:this.$=r.Cardinality.ZERO_OR_MORE;break;case 75:this.$=r.Cardinality.ONE_OR_MORE;break;case 76:this.$=r.Cardinality.ONLY_ONE;break;case 77:this.$=r.Cardinality.MD_PARENT;break;case 78:this.$=r.Identification.NON_IDENTIFYING;break;case 79:this.$=r.Identification.IDENTIFYING;break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},e(i,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:h,24:a,26:u,28:d,29:14,30:15,31:16,32:17,33:y,34:f,35:m,36:j,37:W,40:S,43:q,44:M,48:D,50:R,51:T,52:C},e(i,[2,7],{1:[2,1]}),e(i,[2,3]),{9:30,11:9,22:h,24:a,26:u,28:d,29:14,30:15,31:16,32:17,33:y,34:f,35:m,36:j,37:W,40:S,43:q,44:M,48:D,50:R,51:T,52:C},e(i,[2,5]),e(i,[2,6]),e(i,[2,16],{12:31,64:35,15:[1,32],17:[1,33],20:[1,34],66:nt,67:at,68:ct,69:ot,70:lt}),{23:[1,41]},{25:[1,42]},{27:[1,43]},e(i,[2,27]),e(i,[2,28]),e(i,[2,29]),e(i,[2,30]),e(i,[2,31]),e(B,[2,54]),e(B,[2,55]),e(B,[2,56]),e(B,[2,57]),e(B,[2,58]),e(i,[2,32]),e(i,[2,33]),e(i,[2,34]),e(i,[2,35]),{16:44,40:O,41:N},{16:47,40:O,41:N},{16:48,40:O,41:N},e(i,[2,4]),{11:49,40:S,48:D,50:R,51:T,52:C},{16:50,40:O,41:N},{18:51,19:[1,52],53:53,54:54,58:F},{11:56,40:S,48:D,50:R,51:T,52:C},{65:57,71:[1,58],72:[1,59]},e(Y,[2,73]),e(Y,[2,74]),e(Y,[2,75]),e(Y,[2,76]),e(Y,[2,77]),e(i,[2,24]),e(i,[2,25]),e(i,[2,26]),{13:P,38:60,41:z,42:A,45:62,46:63,48:G,49:K},e(Q,[2,37]),e(Q,[2,38]),{16:68,40:O,41:N,42:A},{13:P,38:69,41:z,42:A,45:62,46:63,48:G,49:K},{13:[1,70],15:[1,71]},e(i,[2,17],{64:35,12:72,17:[1,73],42:A,66:nt,67:at,68:ct,69:ot,70:lt}),{19:[1,74]},e(i,[2,14]),{18:75,19:[2,59],53:53,54:54,58:F},{55:76,58:[1,77]},{58:[2,65],59:[1,78]},{21:[1,79]},{64:80,66:nt,67:at,68:ct,69:ot,70:lt},e(gt,[2,78]),e(gt,[2,79]),{6:bt,10:kt,39:81,42:mt,47:Et},{40:[1,86],41:[1,87]},e(St,[2,43],{46:88,13:P,41:z,48:G,49:K}),e(L,[2,45]),e(L,[2,50]),e(L,[2,51]),e(L,[2,52]),e(L,[2,53]),e(i,[2,41],{42:A}),{6:bt,10:kt,39:89,42:mt,47:Et},{14:90,40:X,50:H,73:J},{16:94,40:O,41:N},{11:95,40:S,48:D,50:R,51:T,52:C},{18:96,19:[1,97],53:53,54:54,58:F},e(i,[2,12]),{19:[2,60]},e(U,[2,61],{56:98,57:99,60:100,62:Tt,63:Ot}),e([19,58,62,63],[2,67]),{58:[2,66]},e(i,[2,22],{15:[1,104],17:[1,103]}),e([40,48,50,51,52],[2,72]),e(i,[2,36]),{13:P,41:z,45:105,46:63,48:G,49:K},e(i,[2,47]),e(i,[2,48]),e(i,[2,49]),e(Q,[2,39]),e(Q,[2,40]),e(L,[2,46]),e(i,[2,42]),e(i,[2,8]),e(i,[2,80]),e(i,[2,81]),e(i,[2,82]),{13:[1,106],42:A},{13:[1,108],15:[1,107]},{19:[1,109]},e(i,[2,15]),e(U,[2,62],{57:110,61:[1,111],63:Ot}),e(U,[2,63]),e(ht,[2,68]),e(U,[2,71]),e(ht,[2,70]),{18:112,19:[1,113],53:53,54:54,58:F},{16:114,40:O,41:N},e(St,[2,44],{46:88,13:P,41:z,48:G,49:K}),{14:115,40:X,50:H,73:J},{16:116,40:O,41:N},{14:117,40:X,50:H,73:J},e(i,[2,13]),e(U,[2,64]),{60:118,62:Tt},{19:[1,119]},e(i,[2,20]),e(i,[2,23],{17:[1,120],42:A}),e(i,[2,11]),{13:[1,121],42:A},e(i,[2,10]),e(ht,[2,69]),e(i,[2,18]),{18:122,19:[1,123],53:53,54:54,58:F},{14:124,40:X,50:H,73:J},{19:[1,125]},e(i,[2,21]),e(i,[2,9]),e(i,[2,19])],defaultActions:{75:[2,60],78:[2,66]},parseError:l(function(n,c){if(c.recoverable)this.trace(n);else{var o=new Error(n);throw o.hash=c,o}},"parseError"),parse:l(function(n){var c=this,o=[0],r=[],p=[null],t=[],Z=this.table,s="",tt=0,Nt=0,Dt=2,At=1,Lt=t.slice.call(arguments,1),_=Object.create(this.lexer),x={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(x.yy[dt]=this.yy[dt]);_.setInput(n,x.yy),x.yy.lexer=_,x.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var pt=_.yylloc;t.push(pt);var wt=_.options&&_.options.ranges;typeof x.yy.parseError=="function"?this.parseError=x.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Vt(b){o.length=o.length-2*b,p.length=p.length-b,t.length=t.length-b}l(Vt,"popStack");function It(){var b;return b=r.pop()||_.lex()||At,typeof b!="number"&&(b instanceof Array&&(r=b,b=r.pop()),b=c.symbols_[b]||b),b}l(It,"lex");for(var g,v,k,ft,w={},et,E,Rt,st;;){if(v=o[o.length-1],this.defaultActions[v]?k=this.defaultActions[v]:((g===null||typeof g>"u")&&(g=It()),k=Z[v]&&Z[v][g]),typeof k>"u"||!k.length||!k[0]){var yt="";st=[];for(et in Z[v])this.terminals_[et]&&et>Dt&&st.push("'"+this.terminals_[et]+"'");_.showPosition?yt="Parse error on line "+(tt+1)+`: +import{g as Mt}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as Bt}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as l,b as Ft,a as Yt,s as Pt,g as zt,o as Gt,p as Kt,c as it,l as V,q as Ut,r as Zt,t as jt,u as Wt,v as qt,x as Qt,d as Xt,y as Ht}from"./mermaid.core-CJB1tAev.js";import{c as Jt}from"./channel-xkK6nTGq.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var _t=(function(){var e=l(function(I,n,c,o){for(c=c||{},o=I.length;o--;c[I[o]]=n);return c},"o"),i=[6,8,10,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52],h=[1,10],a=[1,11],u=[1,12],d=[1,13],y=[1,23],f=[1,24],m=[1,25],j=[1,26],W=[1,27],S=[1,19],q=[1,28],M=[1,29],D=[1,20],R=[1,18],T=[1,21],C=[1,22],nt=[1,36],at=[1,37],ct=[1,38],ot=[1,39],lt=[1,40],B=[6,8,10,13,15,17,20,21,22,24,26,28,33,34,35,36,37,40,43,44,48,50,51,52,66,67,68,69,70],O=[1,45],N=[1,46],F=[1,55],Y=[40,48,50,51,52,71,72],P=[1,66],z=[1,64],A=[1,61],G=[1,65],K=[1,67],Q=[6,8,10,13,17,22,24,26,28,33,34,35,36,37,40,41,42,43,44,48,49,50,51,52,66,67,68,69,70],gt=[66,67,68,69,70],bt=[1,85],kt=[1,84],mt=[1,82],Et=[1,83],St=[6,10,42,47],L=[6,10,13,41,42,47,48,49],X=[1,93],H=[1,92],J=[1,91],U=[19,58],Tt=[1,102],Ot=[1,101],ht=[19,58,61,63],ut={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ER_DIAGRAM:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,entityName:11,relSpec:12,COLON:13,role:14,STYLE_SEPARATOR:15,idList:16,BLOCK_START:17,attributes:18,BLOCK_STOP:19,SQS:20,SQE:21,title:22,title_value:23,acc_title:24,acc_title_value:25,acc_descr:26,acc_descr_value:27,acc_descr_multiline_value:28,direction:29,classDefStatement:30,classStatement:31,styleStatement:32,direction_tb:33,direction_bt:34,direction_rl:35,direction_lr:36,CLASSDEF:37,stylesOpt:38,separator:39,UNICODE_TEXT:40,STYLE_TEXT:41,COMMA:42,CLASS:43,STYLE:44,style:45,styleComponent:46,SEMI:47,NUM:48,BRKT:49,ENTITY_NAME:50,DECIMAL_NUM:51,ENTITY_ONE:52,attribute:53,attributeType:54,attributeName:55,attributeKeyTypeList:56,attributeComment:57,ATTRIBUTE_WORD:58,"?":59,attributeKeyType:60,",":61,ATTRIBUTE_KEY:62,COMMENT:63,cardinality:64,relType:65,ZERO_OR_ONE:66,ZERO_OR_MORE:67,ONE_OR_MORE:68,ONLY_ONE:69,MD_PARENT:70,NON_IDENTIFYING:71,IDENTIFYING:72,WORD:73,$accept:0,$end:1},terminals_:{2:"error",4:"ER_DIAGRAM",6:"EOF",8:"SPACE",10:"NEWLINE",13:"COLON",15:"STYLE_SEPARATOR",17:"BLOCK_START",19:"BLOCK_STOP",20:"SQS",21:"SQE",22:"title",23:"title_value",24:"acc_title",25:"acc_title_value",26:"acc_descr",27:"acc_descr_value",28:"acc_descr_multiline_value",33:"direction_tb",34:"direction_bt",35:"direction_rl",36:"direction_lr",37:"CLASSDEF",40:"UNICODE_TEXT",41:"STYLE_TEXT",42:"COMMA",43:"CLASS",44:"STYLE",47:"SEMI",48:"NUM",49:"BRKT",50:"ENTITY_NAME",51:"DECIMAL_NUM",52:"ENTITY_ONE",58:"ATTRIBUTE_WORD",59:"?",61:",",62:"ATTRIBUTE_KEY",63:"COMMENT",66:"ZERO_OR_ONE",67:"ZERO_OR_MORE",68:"ONE_OR_MORE",69:"ONLY_ONE",70:"MD_PARENT",71:"NON_IDENTIFYING",72:"IDENTIFYING",73:"WORD"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,5],[9,9],[9,7],[9,7],[9,4],[9,6],[9,3],[9,5],[9,1],[9,3],[9,7],[9,9],[9,6],[9,8],[9,4],[9,6],[9,2],[9,2],[9,2],[9,1],[9,1],[9,1],[9,1],[9,1],[29,1],[29,1],[29,1],[29,1],[30,4],[16,1],[16,1],[16,3],[16,3],[31,3],[32,4],[38,1],[38,3],[45,1],[45,2],[39,1],[39,1],[39,1],[46,1],[46,1],[46,1],[46,1],[11,1],[11,1],[11,1],[11,1],[11,1],[18,1],[18,2],[53,2],[53,3],[53,3],[53,4],[54,1],[54,2],[55,1],[56,1],[56,3],[60,1],[57,1],[12,3],[64,1],[64,1],[64,1],[64,1],[64,1],[65,1],[65,1],[14,1],[14,1],[14,1]],performAction:l(function(n,c,o,r,p,t,Z){var s=t.length-1;switch(p){case 1:break;case 2:this.$=[];break;case 3:t[s-1].push(t[s]),this.$=t[s-1];break;case 4:case 5:this.$=t[s];break;case 6:case 7:this.$=[];break;case 8:r.addEntity(t[s-4]),r.addEntity(t[s-2]),r.addRelationship(t[s-4],t[s],t[s-2],t[s-3]);break;case 9:r.addEntity(t[s-8]),r.addEntity(t[s-4]),r.addRelationship(t[s-8],t[s],t[s-4],t[s-5]),r.setClass([t[s-8]],t[s-6]),r.setClass([t[s-4]],t[s-2]);break;case 10:r.addEntity(t[s-6]),r.addEntity(t[s-2]),r.addRelationship(t[s-6],t[s],t[s-2],t[s-3]),r.setClass([t[s-6]],t[s-4]);break;case 11:r.addEntity(t[s-6]),r.addEntity(t[s-4]),r.addRelationship(t[s-6],t[s],t[s-4],t[s-5]),r.setClass([t[s-4]],t[s-2]);break;case 12:r.addEntity(t[s-3]),r.addAttributes(t[s-3],t[s-1]);break;case 13:r.addEntity(t[s-5]),r.addAttributes(t[s-5],t[s-1]),r.setClass([t[s-5]],t[s-3]);break;case 14:r.addEntity(t[s-2]);break;case 15:r.addEntity(t[s-4]),r.setClass([t[s-4]],t[s-2]);break;case 16:r.addEntity(t[s]);break;case 17:r.addEntity(t[s-2]),r.setClass([t[s-2]],t[s]);break;case 18:r.addEntity(t[s-6],t[s-4]),r.addAttributes(t[s-6],t[s-1]);break;case 19:r.addEntity(t[s-8],t[s-6]),r.addAttributes(t[s-8],t[s-1]),r.setClass([t[s-8]],t[s-3]);break;case 20:r.addEntity(t[s-5],t[s-3]);break;case 21:r.addEntity(t[s-7],t[s-5]),r.setClass([t[s-7]],t[s-2]);break;case 22:r.addEntity(t[s-3],t[s-1]);break;case 23:r.addEntity(t[s-5],t[s-3]),r.setClass([t[s-5]],t[s]);break;case 24:case 25:this.$=t[s].trim(),r.setAccTitle(this.$);break;case 26:case 27:this.$=t[s].trim(),r.setAccDescription(this.$);break;case 32:r.setDirection("TB");break;case 33:r.setDirection("BT");break;case 34:r.setDirection("RL");break;case 35:r.setDirection("LR");break;case 36:this.$=t[s-3],r.addClass(t[s-2],t[s-1]);break;case 37:case 38:case 59:case 68:this.$=[t[s]];break;case 39:case 40:this.$=t[s-2].concat([t[s]]);break;case 41:this.$=t[s-2],r.setClass(t[s-1],t[s]);break;case 42:this.$=t[s-3],r.addCssStyles(t[s-2],t[s-1]);break;case 43:this.$=[t[s]];break;case 44:t[s-2].push(t[s]),this.$=t[s-2];break;case 46:this.$=t[s-1]+t[s];break;case 54:case 80:case 81:this.$=t[s].replace(/"/g,"");break;case 55:case 56:case 57:case 58:case 82:this.$=t[s];break;case 60:t[s].push(t[s-1]),this.$=t[s];break;case 61:this.$={type:t[s-1],name:t[s]};break;case 62:this.$={type:t[s-2],name:t[s-1],keys:t[s]};break;case 63:this.$={type:t[s-2],name:t[s-1],comment:t[s]};break;case 64:this.$={type:t[s-3],name:t[s-2],keys:t[s-1],comment:t[s]};break;case 65:case 67:case 70:this.$=t[s];break;case 66:this.$=t[s-1]+t[s];break;case 69:t[s-2].push(t[s]),this.$=t[s-2];break;case 71:this.$=t[s].replace(/"/g,"");break;case 72:this.$={cardA:t[s],relType:t[s-1],cardB:t[s-2]};break;case 73:this.$=r.Cardinality.ZERO_OR_ONE;break;case 74:this.$=r.Cardinality.ZERO_OR_MORE;break;case 75:this.$=r.Cardinality.ONE_OR_MORE;break;case 76:this.$=r.Cardinality.ONLY_ONE;break;case 77:this.$=r.Cardinality.MD_PARENT;break;case 78:this.$=r.Identification.NON_IDENTIFYING;break;case 79:this.$=r.Identification.IDENTIFYING;break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},e(i,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:9,22:h,24:a,26:u,28:d,29:14,30:15,31:16,32:17,33:y,34:f,35:m,36:j,37:W,40:S,43:q,44:M,48:D,50:R,51:T,52:C},e(i,[2,7],{1:[2,1]}),e(i,[2,3]),{9:30,11:9,22:h,24:a,26:u,28:d,29:14,30:15,31:16,32:17,33:y,34:f,35:m,36:j,37:W,40:S,43:q,44:M,48:D,50:R,51:T,52:C},e(i,[2,5]),e(i,[2,6]),e(i,[2,16],{12:31,64:35,15:[1,32],17:[1,33],20:[1,34],66:nt,67:at,68:ct,69:ot,70:lt}),{23:[1,41]},{25:[1,42]},{27:[1,43]},e(i,[2,27]),e(i,[2,28]),e(i,[2,29]),e(i,[2,30]),e(i,[2,31]),e(B,[2,54]),e(B,[2,55]),e(B,[2,56]),e(B,[2,57]),e(B,[2,58]),e(i,[2,32]),e(i,[2,33]),e(i,[2,34]),e(i,[2,35]),{16:44,40:O,41:N},{16:47,40:O,41:N},{16:48,40:O,41:N},e(i,[2,4]),{11:49,40:S,48:D,50:R,51:T,52:C},{16:50,40:O,41:N},{18:51,19:[1,52],53:53,54:54,58:F},{11:56,40:S,48:D,50:R,51:T,52:C},{65:57,71:[1,58],72:[1,59]},e(Y,[2,73]),e(Y,[2,74]),e(Y,[2,75]),e(Y,[2,76]),e(Y,[2,77]),e(i,[2,24]),e(i,[2,25]),e(i,[2,26]),{13:P,38:60,41:z,42:A,45:62,46:63,48:G,49:K},e(Q,[2,37]),e(Q,[2,38]),{16:68,40:O,41:N,42:A},{13:P,38:69,41:z,42:A,45:62,46:63,48:G,49:K},{13:[1,70],15:[1,71]},e(i,[2,17],{64:35,12:72,17:[1,73],42:A,66:nt,67:at,68:ct,69:ot,70:lt}),{19:[1,74]},e(i,[2,14]),{18:75,19:[2,59],53:53,54:54,58:F},{55:76,58:[1,77]},{58:[2,65],59:[1,78]},{21:[1,79]},{64:80,66:nt,67:at,68:ct,69:ot,70:lt},e(gt,[2,78]),e(gt,[2,79]),{6:bt,10:kt,39:81,42:mt,47:Et},{40:[1,86],41:[1,87]},e(St,[2,43],{46:88,13:P,41:z,48:G,49:K}),e(L,[2,45]),e(L,[2,50]),e(L,[2,51]),e(L,[2,52]),e(L,[2,53]),e(i,[2,41],{42:A}),{6:bt,10:kt,39:89,42:mt,47:Et},{14:90,40:X,50:H,73:J},{16:94,40:O,41:N},{11:95,40:S,48:D,50:R,51:T,52:C},{18:96,19:[1,97],53:53,54:54,58:F},e(i,[2,12]),{19:[2,60]},e(U,[2,61],{56:98,57:99,60:100,62:Tt,63:Ot}),e([19,58,62,63],[2,67]),{58:[2,66]},e(i,[2,22],{15:[1,104],17:[1,103]}),e([40,48,50,51,52],[2,72]),e(i,[2,36]),{13:P,41:z,45:105,46:63,48:G,49:K},e(i,[2,47]),e(i,[2,48]),e(i,[2,49]),e(Q,[2,39]),e(Q,[2,40]),e(L,[2,46]),e(i,[2,42]),e(i,[2,8]),e(i,[2,80]),e(i,[2,81]),e(i,[2,82]),{13:[1,106],42:A},{13:[1,108],15:[1,107]},{19:[1,109]},e(i,[2,15]),e(U,[2,62],{57:110,61:[1,111],63:Ot}),e(U,[2,63]),e(ht,[2,68]),e(U,[2,71]),e(ht,[2,70]),{18:112,19:[1,113],53:53,54:54,58:F},{16:114,40:O,41:N},e(St,[2,44],{46:88,13:P,41:z,48:G,49:K}),{14:115,40:X,50:H,73:J},{16:116,40:O,41:N},{14:117,40:X,50:H,73:J},e(i,[2,13]),e(U,[2,64]),{60:118,62:Tt},{19:[1,119]},e(i,[2,20]),e(i,[2,23],{17:[1,120],42:A}),e(i,[2,11]),{13:[1,121],42:A},e(i,[2,10]),e(ht,[2,69]),e(i,[2,18]),{18:122,19:[1,123],53:53,54:54,58:F},{14:124,40:X,50:H,73:J},{19:[1,125]},e(i,[2,21]),e(i,[2,9]),e(i,[2,19])],defaultActions:{75:[2,60],78:[2,66]},parseError:l(function(n,c){if(c.recoverable)this.trace(n);else{var o=new Error(n);throw o.hash=c,o}},"parseError"),parse:l(function(n){var c=this,o=[0],r=[],p=[null],t=[],Z=this.table,s="",tt=0,Nt=0,Dt=2,At=1,Lt=t.slice.call(arguments,1),_=Object.create(this.lexer),x={yy:{}};for(var dt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,dt)&&(x.yy[dt]=this.yy[dt]);_.setInput(n,x.yy),x.yy.lexer=_,x.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var pt=_.yylloc;t.push(pt);var wt=_.options&&_.options.ranges;typeof x.yy.parseError=="function"?this.parseError=x.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function Vt(b){o.length=o.length-2*b,p.length=p.length-b,t.length=t.length-b}l(Vt,"popStack");function It(){var b;return b=r.pop()||_.lex()||At,typeof b!="number"&&(b instanceof Array&&(r=b,b=r.pop()),b=c.symbols_[b]||b),b}l(It,"lex");for(var g,v,k,ft,w={},et,E,Rt,st;;){if(v=o[o.length-1],this.defaultActions[v]?k=this.defaultActions[v]:((g===null||typeof g>"u")&&(g=It()),k=Z[v]&&Z[v][g]),typeof k>"u"||!k.length||!k[0]){var yt="";st=[];for(et in Z[v])this.terminals_[et]&&et>Dt&&st.push("'"+this.terminals_[et]+"'");_.showPosition?yt="Parse error on line "+(tt+1)+`: `+_.showPosition()+` Expecting `+st.join(", ")+", got '"+(this.terminals_[g]||g)+"'":yt="Parse error on line "+(tt+1)+": Unexpected "+(g==At?"end of input":"'"+(this.terminals_[g]||g)+"'"),this.parseError(yt,{text:_.match,token:this.terminals_[g]||g,line:_.yylineno,loc:pt,expected:st})}if(k[0]instanceof Array&&k.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+g);switch(k[0]){case 1:o.push(g),p.push(_.yytext),t.push(_.yylloc),o.push(k[1]),g=null,Nt=_.yyleng,s=_.yytext,tt=_.yylineno,pt=_.yylloc;break;case 2:if(E=this.productions_[k[1]][1],w.$=p[p.length-E],w._$={first_line:t[t.length-(E||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(E||1)].first_column,last_column:t[t.length-1].last_column},wt&&(w._$.range=[t[t.length-(E||1)].range[0],t[t.length-1].range[1]]),ft=this.performAction.apply(w,[s,Nt,tt,x.yy,k[1],p,t].concat(Lt)),typeof ft<"u")return ft;E&&(o=o.slice(0,-1*E*2),p=p.slice(0,-1*E),t=t.slice(0,-1*E)),o.push(this.productions_[k[1]][0]),p.push(w.$),t.push(w._$),Rt=Z[o[o.length-2]][o[o.length-1]],o.push(Rt);break;case 3:return!0}}return!0},"parse")},vt=(function(){var I={EOF:1,parseError:l(function(c,o){if(this.yy.parser)this.yy.parser.parseError(c,o);else throw new Error(c)},"parseError"),setInput:l(function(n,c){return this.yy=c||this.yy||{},this._input=n,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:l(function(){var n=this._input[0];this.yytext+=n,this.yyleng++,this.offset++,this.match+=n,this.matched+=n;var c=n.match(/(?:\r\n?|\n).*/g);return c?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),n},"input"),unput:l(function(n){var c=n.length,o=n.split(/(?:\r\n?|\n)/g);this._input=n+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-c),this.offset-=c;var r=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),o.length-1&&(this.yylineno-=o.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:o?(o.length===r.length?this.yylloc.first_column:0)+r[r.length-o.length].length-o[0].length:this.yylloc.first_column-c},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-c]),this.yyleng=this.yytext.length,this},"unput"),more:l(function(){return this._more=!0,this},"more"),reject:l(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:l(function(n){this.unput(this.match.slice(n))},"less"),pastInput:l(function(){var n=this.matched.substr(0,this.matched.length-this.match.length);return(n.length>20?"...":"")+n.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:l(function(){var n=this.match;return n.length<20&&(n+=this._input.substr(0,20-n.length)),(n.substr(0,20)+(n.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:l(function(){var n=this.pastInput(),c=new Array(n.length+1).join("-");return n+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-D0EBISGr.js b/apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-CzI-GKO4.js similarity index 99% rename from apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-D0EBISGr.js rename to apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-CzI-GKO4.js index d2e5502bc..c717156e9 100644 --- a/apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-D0EBISGr.js +++ b/apps/kimi-code/dist-web/assets/flowDiagram-23GEKE2U-CzI-GKO4.js @@ -1,4 +1,4 @@ -import{g as He}from"./chunk-5VM5RSS4-B87d3yQb.js";import{g as Xe}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as Qe}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as b,b6 as Ze,X as Oe,l as Z,c as g1,v as Je,x as $e,y as ie,b as et,s as tt,o as st,a as it,g as rt,p as at,k as nt,Y as ut,Z as ot,bo as lt,r as te,d as se,a5 as ct,q as ht,b8 as dt,t as pt}from"./mermaid.core-DaDTfY6S.js";import{f as ft}from"./chunk-32BRIVSS-_Sd4SrsJ.js";import{c as gt}from"./channel-d4fEaqwQ.js";var bt="flowchart-",At=class{constructor(){this.vertexCounter=0,this.config=g1(),this.diagramId="",this.vertices=new Map,this.edges=[],this.classes=new Map,this.subGraphs=[],this.subGraphLookup=new Map,this.tooltips=new Map,this.subCount=0,this.firstGraphFlag=!0,this.secCount=-1,this.posCrossRef=[],this.funs=[],this.setAccTitle=et,this.setAccDescription=tt,this.setDiagramTitle=st,this.getAccTitle=it,this.getAccDescription=rt,this.getDiagramTitle=at,this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{b(this,"FlowDB")}sanitizeText(e){return nt.sanitizeText(e,this.config)}sanitizeNodeLabelType(e){switch(e){case"markdown":case"string":case"text":return e;default:return"markdown"}}setDiagramId(e){this.diagramId=e}lookUpDomId(e){for(const i of this.vertices.values())if(i.id===e)return this.diagramId?`${this.diagramId}-${i.domId}`:i.domId;return this.diagramId?`${this.diagramId}-${e}`:e}addVertex(e,i,r,a,o,d,l={},A){if(!e||e.trim().length===0)return;let n;if(A!==void 0){let k;A.includes(` +import{g as He}from"./chunk-5VM5RSS4-yyj9cAyF.js";import{g as Xe}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as Qe}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as b,b6 as Ze,X as Oe,l as Z,c as g1,v as Je,x as $e,y as ie,b as et,s as tt,o as st,a as it,g as rt,p as at,k as nt,Y as ut,Z as ot,bo as lt,r as te,d as se,a5 as ct,q as ht,b8 as dt,t as pt}from"./mermaid.core-CJB1tAev.js";import{f as ft}from"./chunk-32BRIVSS-DUDRPqmY.js";import{c as gt}from"./channel-xkK6nTGq.js";var bt="flowchart-",At=class{constructor(){this.vertexCounter=0,this.config=g1(),this.diagramId="",this.vertices=new Map,this.edges=[],this.classes=new Map,this.subGraphs=[],this.subGraphLookup=new Map,this.tooltips=new Map,this.subCount=0,this.firstGraphFlag=!0,this.secCount=-1,this.posCrossRef=[],this.funs=[],this.setAccTitle=et,this.setAccDescription=tt,this.setDiagramTitle=st,this.getAccTitle=it,this.getAccDescription=rt,this.getDiagramTitle=at,this.funs.push(this.setupToolTips.bind(this)),this.addVertex=this.addVertex.bind(this),this.firstGraph=this.firstGraph.bind(this),this.setDirection=this.setDirection.bind(this),this.addSubGraph=this.addSubGraph.bind(this),this.addLink=this.addLink.bind(this),this.setLink=this.setLink.bind(this),this.updateLink=this.updateLink.bind(this),this.addClass=this.addClass.bind(this),this.setClass=this.setClass.bind(this),this.destructLink=this.destructLink.bind(this),this.setClickEvent=this.setClickEvent.bind(this),this.setTooltip=this.setTooltip.bind(this),this.updateLinkInterpolate=this.updateLinkInterpolate.bind(this),this.setClickFun=this.setClickFun.bind(this),this.bindFunctions=this.bindFunctions.bind(this),this.lex={firstGraph:this.firstGraph.bind(this)},this.clear(),this.setGen("gen-2")}static{b(this,"FlowDB")}sanitizeText(e){return nt.sanitizeText(e,this.config)}sanitizeNodeLabelType(e){switch(e){case"markdown":case"string":case"text":return e;default:return"markdown"}}setDiagramId(e){this.diagramId=e}lookUpDomId(e){for(const i of this.vertices.values())if(i.id===e)return this.diagramId?`${this.diagramId}-${i.domId}`:i.domId;return this.diagramId?`${this.diagramId}-${e}`:e}addVertex(e,i,r,a,o,d,l={},A){if(!e||e.trim().length===0)return;let n;if(A!==void 0){let k;A.includes(` `)?k=A+` `:k=`{ `+A+` diff --git a/apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-IslzQD84.js b/apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-B2lfrNfh.js similarity index 99% rename from apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-IslzQD84.js rename to apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-B2lfrNfh.js index bfcf7d359..7552e3c8e 100644 --- a/apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-IslzQD84.js +++ b/apps/kimi-code/dist-web/assets/ganttDiagram-NO4QXBWP-B2lfrNfh.js @@ -1,4 +1,4 @@ -import{bg as on,bh as On,bi as cn,bj as un,bk as ln,bl as ue,bm as Hn,g as Nn,s as Pn,p as Vn,o as Rn,a as zn,b as qn,_ as d,c as Yt,d as Zt,e as Bn,bn as it,l as Tt,k as Zn,j as Xn,q as Gn,y as jn}from"./mermaid.core-DaDTfY6S.js";import{g as oe}from"./_commonjsHelpers-CqkleIqs.js";import{b as Qn,t as Ne,c as Jn,a as Kn,l as tr}from"./linear-BmFm-Eu7.js";import{i as er}from"./init-Gi6I4Gst.js";import"./index-D1h84VfZ.js";import"./defaultLocale-DX6XiGOO.js";function nr(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n<r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n<i||n===void 0&&i>=i)&&(n=i)}return n}function rr(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function ir(t){return t}var Gt=1,le=2,xe=3,Xt=4,Pe=1e-6;function sr(t){return"translate("+t+",0)"}function ar(t){return"translate(0,"+t+")"}function or(t){return e=>+t(e)}function cr(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function ur(){return!this.__axis}function fn(t,e){var n=[],r=null,i=null,s=6,a=6,y=3,F=typeof window<"u"&&window.devicePixelRatio>1?0:.5,S=t===Gt||t===Xt?-1:1,w=t===Xt||t===le?"x":"y",P=t===Gt||t===xe?sr:ar;function _(Y){var X=r??(e.ticks?e.ticks.apply(e,n):e.domain()),B=i??(e.tickFormat?e.tickFormat.apply(e,n):ir),v=Math.max(s,0)+y,U=e.range(),R=+U[0]+F,E=+U[U.length-1]+F,z=(e.bandwidth?cr:or)(e.copy(),F),G=Y.selection?Y.selection():Y,T=G.selectAll(".domain").data([null]),k=G.selectAll(".tick").data(X,e).order(),p=k.exit(),L=k.enter().append("g").attr("class","tick"),x=k.select("line"),C=k.select("text");T=T.merge(T.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),k=k.merge(L),x=x.merge(L.append("line").attr("stroke","currentColor").attr(w+"2",S*s)),C=C.merge(L.append("text").attr("fill","currentColor").attr(w,S*v).attr("dy",t===Gt?"0em":t===xe?"0.71em":"0.32em")),Y!==G&&(T=T.transition(Y),k=k.transition(Y),x=x.transition(Y),C=C.transition(Y),p=p.transition(Y).attr("opacity",Pe).attr("transform",function(M){return isFinite(M=z(M))?P(M+F):this.getAttribute("transform")}),L.attr("opacity",Pe).attr("transform",function(M){var D=this.parentNode.__axis;return P((D&&isFinite(D=D(M))?D:z(M))+F)})),p.remove(),T.attr("d",t===Xt||t===le?a?"M"+S*a+","+R+"H"+F+"V"+E+"H"+S*a:"M"+F+","+R+"V"+E:a?"M"+R+","+S*a+"V"+F+"H"+E+"V"+S*a:"M"+R+","+F+"H"+E),k.attr("opacity",1).attr("transform",function(M){return P(z(M)+F)}),x.attr(w+"2",S*s),C.attr(w,S*v).text(B),G.filter(ur).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===le?"start":t===Xt?"end":"middle"),G.each(function(){this.__axis=z})}return _.scale=function(Y){return arguments.length?(e=Y,_):e},_.ticks=function(){return n=Array.from(arguments),_},_.tickArguments=function(Y){return arguments.length?(n=Y==null?[]:Array.from(Y),_):n.slice()},_.tickValues=function(Y){return arguments.length?(r=Y==null?null:Array.from(Y),_):r&&r.slice()},_.tickFormat=function(Y){return arguments.length?(i=Y,_):i},_.tickSize=function(Y){return arguments.length?(s=a=+Y,_):s},_.tickSizeInner=function(Y){return arguments.length?(s=+Y,_):s},_.tickSizeOuter=function(Y){return arguments.length?(a=+Y,_):a},_.tickPadding=function(Y){return arguments.length?(y=+Y,_):y},_.offset=function(Y){return arguments.length?(F=+Y,_):F},_}function lr(t){return fn(Gt,t)}function fr(t){return fn(xe,t)}const dr=Math.PI/180,hr=180/Math.PI,ne=18,dn=.96422,hn=1,mn=.82521,gn=4/29,Ft=6/29,yn=3*Ft*Ft,mr=Ft*Ft*Ft;function kn(t){if(t instanceof ft)return new ft(t.l,t.a,t.b,t.opacity);if(t instanceof ht)return pn(t);t instanceof on||(t=On(t));var e=me(t.r),n=me(t.g),r=me(t.b),i=fe((.2225045*e+.7168786*n+.0606169*r)/hn),s,a;return e===n&&n===r?s=a=i:(s=fe((.4360747*e+.3850649*n+.1430804*r)/dn),a=fe((.0139322*e+.0971045*n+.7141733*r)/mn)),new ft(116*i-16,500*(s-i),200*(i-a),t.opacity)}function gr(t,e,n,r){return arguments.length===1?kn(t):new ft(t,e,n,r??1)}function ft(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}cn(ft,gr,un(ln,{brighter(t){return new ft(this.l+ne*(t??1),this.a,this.b,this.opacity)},darker(t){return new ft(this.l-ne*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=dn*de(e),t=hn*de(t),n=mn*de(n),new on(he(3.1338561*e-1.6168667*t-.4906146*n),he(-.9787684*e+1.9161415*t+.033454*n),he(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function fe(t){return t>mr?Math.pow(t,1/3):t/yn+gn}function de(t){return t>Ft?t*t*t:yn*(t-gn)}function he(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function me(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function yr(t){if(t instanceof ht)return new ht(t.h,t.c,t.l,t.opacity);if(t instanceof ft||(t=kn(t)),t.a===0&&t.b===0)return new ht(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*hr;return new ht(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function be(t,e,n,r){return arguments.length===1?yr(t):new ht(t,e,n,r??1)}function ht(t,e,n,r){this.h=+t,this.c=+e,this.l=+n,this.opacity=+r}function pn(t){if(isNaN(t.h))return new ft(t.l,0,0,t.opacity);var e=t.h*dr;return new ft(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}cn(ht,be,un(ln,{brighter(t){return new ht(this.h,this.c,this.l+ne*(t??1),this.opacity)},darker(t){return new ht(this.h,this.c,this.l-ne*(t??1),this.opacity)},rgb(){return pn(this).rgb()}}));function kr(t){return function(e,n){var r=t((e=be(e)).h,(n=be(n)).h),i=ue(e.c,n.c),s=ue(e.l,n.l),a=ue(e.opacity,n.opacity);return function(y){return e.h=r(y),e.c=i(y),e.l=s(y),e.opacity=a(y),e+""}}}const pr=kr(Hn);function vr(t,e){t=t.slice();var n=0,r=t.length-1,i=t[n],s=t[r],a;return s<i&&(a=n,n=r,r=a,a=i,i=s,s=a),t[n]=e.floor(i),t[r]=e.ceil(s),t}const ge=new Date,ye=new Date;function nt(t,e,n,r){function i(s){return t(s=arguments.length===0?new Date:new Date(+s)),s}return i.floor=s=>(t(s=new Date(+s)),s),i.ceil=s=>(t(s=new Date(s-1)),e(s,1),t(s),s),i.round=s=>{const a=i(s),y=i.ceil(s);return s-a<y-s?a:y},i.offset=(s,a)=>(e(s=new Date(+s),a==null?1:Math.floor(a)),s),i.range=(s,a,y)=>{const F=[];if(s=i.ceil(s),y=y==null?1:Math.floor(y),!(s<a)||!(y>0))return F;let S;do F.push(S=new Date(+s)),e(s,y),t(s);while(S<s&&s<a);return F},i.filter=s=>nt(a=>{if(a>=a)for(;t(a),!s(a);)a.setTime(a-1)},(a,y)=>{if(a>=a)if(y<0)for(;++y<=0;)for(;e(a,-1),!s(a););else for(;--y>=0;)for(;e(a,1),!s(a););}),n&&(i.count=(s,a)=>(ge.setTime(+s),ye.setTime(+a),t(ge),t(ye),Math.floor(n(ge,ye))),i.every=s=>(s=Math.floor(s),!isFinite(s)||!(s>0)?null:s>1?i.filter(r?a=>r(a)%s===0:a=>i.count(0,a)%s===0):i)),i}const Et=nt(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);Et.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?nt(e=>{e.setTime(Math.floor(e/t)*t)},(e,n)=>{e.setTime(+e+n*t)},(e,n)=>(n-e)/t):Et);Et.range;const mt=1e3,ct=mt*60,gt=ct*60,yt=gt*24,Se=yt*7,Ve=yt*30,ke=yt*365,vt=nt(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*mt)},(t,e)=>(e-t)/mt,t=>t.getUTCSeconds());vt.range;const Nt=nt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*mt)},(t,e)=>{t.setTime(+t+e*ct)},(t,e)=>(e-t)/ct,t=>t.getMinutes());Nt.range;const Tr=nt(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*ct)},(t,e)=>(e-t)/ct,t=>t.getUTCMinutes());Tr.range;const Pt=nt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*mt-t.getMinutes()*ct)},(t,e)=>{t.setTime(+t+e*gt)},(t,e)=>(e-t)/gt,t=>t.getHours());Pt.range;const xr=nt(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*gt)},(t,e)=>(e-t)/gt,t=>t.getUTCHours());xr.range;const xt=nt(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*ct)/yt,t=>t.getDate()-1);xt.range;const _e=nt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/yt,t=>t.getUTCDate()-1);_e.range;const br=nt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/yt,t=>Math.floor(t/yt));br.range;function Dt(t){return nt(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,n)=>{e.setDate(e.getDate()+n*7)},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*ct)/Se)}const zt=Dt(0),Vt=Dt(1),vn=Dt(2),Tn=Dt(3),bt=Dt(4),xn=Dt(5),bn=Dt(6);zt.range;Vt.range;vn.range;Tn.range;bt.range;xn.range;bn.range;function Mt(t){return nt(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7)},(e,n)=>(n-e)/Se)}const wn=Mt(0),re=Mt(1),wr=Mt(2),Dr=Mt(3),It=Mt(4),Mr=Mt(5),Cr=Mt(6);wn.range;re.range;wr.range;Dr.range;It.range;Mr.range;Cr.range;const Rt=nt(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());Rt.range;const Sr=nt(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());Sr.range;const kt=nt(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());kt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:nt(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,n)=>{e.setFullYear(e.getFullYear()+n*t)});kt.range;const wt=nt(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());wt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:nt(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)});wt.range;function _r(t,e,n,r,i,s){const a=[[vt,1,mt],[vt,5,5*mt],[vt,15,15*mt],[vt,30,30*mt],[s,1,ct],[s,5,5*ct],[s,15,15*ct],[s,30,30*ct],[i,1,gt],[i,3,3*gt],[i,6,6*gt],[i,12,12*gt],[r,1,yt],[r,2,2*yt],[n,1,Se],[e,1,Ve],[e,3,3*Ve],[t,1,ke]];function y(S,w,P){const _=w<S;_&&([S,w]=[w,S]);const Y=P&&typeof P.range=="function"?P:F(S,w,P),X=Y?Y.range(S,+w+1):[];return _?X.reverse():X}function F(S,w,P){const _=Math.abs(w-S)/P,Y=Qn(([,,v])=>v).right(a,_);if(Y===a.length)return t.every(Ne(S/ke,w/ke,P));if(Y===0)return Et.every(Math.max(Ne(S,w,P),1));const[X,B]=a[_/a[Y-1][2]<a[Y][2]/_?Y-1:Y];return X.every(B)}return[y,F]}const[Yr,Fr]=_r(kt,Rt,zt,xt,Pt,Nt);function pe(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function ve(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function $t(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}function Ur(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,s=t.days,a=t.shortDays,y=t.months,F=t.shortMonths,S=Ot(i),w=Ht(i),P=Ot(s),_=Ht(s),Y=Ot(a),X=Ht(a),B=Ot(y),v=Ht(y),U=Ot(F),R=Ht(F),E={a:m,A:I,b:o,B:W,c:null,d:Xe,e:Xe,f:ti,g:li,G:di,H:Qr,I:Jr,j:Kr,L:Dn,m:ei,M:ni,p:u,q:K,Q:Qe,s:Je,S:ri,u:ii,U:si,V:ai,w:oi,W:ci,x:null,X:null,y:ui,Y:fi,Z:hi,"%":je},z={a:l,A:$,b:O,B:j,c:null,d:Ge,e:Ge,f:ki,g:Si,G:Yi,H:mi,I:gi,j:yi,L:Cn,m:pi,M:vi,p:H,q:J,Q:Qe,s:Je,S:Ti,u:xi,U:bi,V:wi,w:Di,W:Mi,x:null,X:null,y:Ci,Y:_i,Z:Fi,"%":je},G={a:x,A:C,b:M,B:D,c,d:Be,e:Be,f:Zr,g:qe,G:ze,H:Ze,I:Ze,j:Rr,L:Br,m:Vr,M:zr,p:L,q:Pr,Q:Gr,s:jr,S:qr,u:Wr,U:$r,V:Or,w:Ar,W:Hr,x:g,X:b,y:qe,Y:ze,Z:Nr,"%":Xr};E.x=T(n,E),E.X=T(r,E),E.c=T(e,E),z.x=T(n,z),z.X=T(r,z),z.c=T(e,z);function T(h,N){return function(V){var f=[],tt=-1,A=0,Q=h.length,Z,st,at;for(V instanceof Date||(V=new Date(+V));++tt<Q;)h.charCodeAt(tt)===37&&(f.push(h.slice(A,tt)),(st=Re[Z=h.charAt(++tt)])!=null?Z=h.charAt(++tt):st=Z==="e"?" ":"0",(at=N[Z])&&(Z=at(V,st)),f.push(Z),A=tt+1);return f.push(h.slice(A,tt)),f.join("")}}function k(h,N){return function(V){var f=$t(1900,void 0,1),tt=p(f,h,V+="",0),A,Q;if(tt!=V.length)return null;if("Q"in f)return new Date(f.Q);if("s"in f)return new Date(f.s*1e3+("L"in f?f.L:0));if(N&&!("Z"in f)&&(f.Z=0),"p"in f&&(f.H=f.H%12+f.p*12),f.m===void 0&&(f.m="q"in f?f.q:0),"V"in f){if(f.V<1||f.V>53)return null;"w"in f||(f.w=1),"Z"in f?(A=ve($t(f.y,0,1)),Q=A.getUTCDay(),A=Q>4||Q===0?re.ceil(A):re(A),A=_e.offset(A,(f.V-1)*7),f.y=A.getUTCFullYear(),f.m=A.getUTCMonth(),f.d=A.getUTCDate()+(f.w+6)%7):(A=pe($t(f.y,0,1)),Q=A.getDay(),A=Q>4||Q===0?Vt.ceil(A):Vt(A),A=xt.offset(A,(f.V-1)*7),f.y=A.getFullYear(),f.m=A.getMonth(),f.d=A.getDate()+(f.w+6)%7)}else("W"in f||"U"in f)&&("w"in f||(f.w="u"in f?f.u%7:"W"in f?1:0),Q="Z"in f?ve($t(f.y,0,1)).getUTCDay():pe($t(f.y,0,1)).getDay(),f.m=0,f.d="W"in f?(f.w+6)%7+f.W*7-(Q+5)%7:f.w+f.U*7-(Q+6)%7);return"Z"in f?(f.H+=f.Z/100|0,f.M+=f.Z%100,ve(f)):pe(f)}}function p(h,N,V,f){for(var tt=0,A=N.length,Q=V.length,Z,st;tt<A;){if(f>=Q)return-1;if(Z=N.charCodeAt(tt++),Z===37){if(Z=N.charAt(tt++),st=G[Z in Re?N.charAt(tt++):Z],!st||(f=st(h,V,f))<0)return-1}else if(Z!=V.charCodeAt(f++))return-1}return f}function L(h,N,V){var f=S.exec(N.slice(V));return f?(h.p=w.get(f[0].toLowerCase()),V+f[0].length):-1}function x(h,N,V){var f=Y.exec(N.slice(V));return f?(h.w=X.get(f[0].toLowerCase()),V+f[0].length):-1}function C(h,N,V){var f=P.exec(N.slice(V));return f?(h.w=_.get(f[0].toLowerCase()),V+f[0].length):-1}function M(h,N,V){var f=U.exec(N.slice(V));return f?(h.m=R.get(f[0].toLowerCase()),V+f[0].length):-1}function D(h,N,V){var f=B.exec(N.slice(V));return f?(h.m=v.get(f[0].toLowerCase()),V+f[0].length):-1}function c(h,N,V){return p(h,e,N,V)}function g(h,N,V){return p(h,n,N,V)}function b(h,N,V){return p(h,r,N,V)}function m(h){return a[h.getDay()]}function I(h){return s[h.getDay()]}function o(h){return F[h.getMonth()]}function W(h){return y[h.getMonth()]}function u(h){return i[+(h.getHours()>=12)]}function K(h){return 1+~~(h.getMonth()/3)}function l(h){return a[h.getUTCDay()]}function $(h){return s[h.getUTCDay()]}function O(h){return F[h.getUTCMonth()]}function j(h){return y[h.getUTCMonth()]}function H(h){return i[+(h.getUTCHours()>=12)]}function J(h){return 1+~~(h.getUTCMonth()/3)}return{format:function(h){var N=T(h+="",E);return N.toString=function(){return h},N},parse:function(h){var N=k(h+="",!1);return N.toString=function(){return h},N},utcFormat:function(h){var N=T(h+="",z);return N.toString=function(){return h},N},utcParse:function(h){var N=k(h+="",!0);return N.toString=function(){return h},N}}}var Re={"-":"",_:" ",0:"0"},rt=/^\s*\d+/,Er=/^%/,Ir=/[\\^$*+?|[\]().{}]/g;function q(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",s=i.length;return r+(s<n?new Array(n-s+1).join(e)+i:i)}function Lr(t){return t.replace(Ir,"\\$&")}function Ot(t){return new RegExp("^(?:"+t.map(Lr).join("|")+")","i")}function Ht(t){return new Map(t.map((e,n)=>[e.toLowerCase(),n]))}function Ar(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Wr(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function $r(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Or(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Hr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function ze(t,e,n){var r=rt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function qe(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Nr(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function Pr(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function Vr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Be(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Rr(t,e,n){var r=rt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Ze(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function zr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function qr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Br(t,e,n){var r=rt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Zr(t,e,n){var r=rt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Xr(t,e,n){var r=Er.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Gr(t,e,n){var r=rt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function jr(t,e,n){var r=rt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Xe(t,e){return q(t.getDate(),e,2)}function Qr(t,e){return q(t.getHours(),e,2)}function Jr(t,e){return q(t.getHours()%12||12,e,2)}function Kr(t,e){return q(1+xt.count(kt(t),t),e,3)}function Dn(t,e){return q(t.getMilliseconds(),e,3)}function ti(t,e){return Dn(t,e)+"000"}function ei(t,e){return q(t.getMonth()+1,e,2)}function ni(t,e){return q(t.getMinutes(),e,2)}function ri(t,e){return q(t.getSeconds(),e,2)}function ii(t){var e=t.getDay();return e===0?7:e}function si(t,e){return q(zt.count(kt(t)-1,t),e,2)}function Mn(t){var e=t.getDay();return e>=4||e===0?bt(t):bt.ceil(t)}function ai(t,e){return t=Mn(t),q(bt.count(kt(t),t)+(kt(t).getDay()===4),e,2)}function oi(t){return t.getDay()}function ci(t,e){return q(Vt.count(kt(t)-1,t),e,2)}function ui(t,e){return q(t.getFullYear()%100,e,2)}function li(t,e){return t=Mn(t),q(t.getFullYear()%100,e,2)}function fi(t,e){return q(t.getFullYear()%1e4,e,4)}function di(t,e){var n=t.getDay();return t=n>=4||n===0?bt(t):bt.ceil(t),q(t.getFullYear()%1e4,e,4)}function hi(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+q(e/60|0,"0",2)+q(e%60,"0",2)}function Ge(t,e){return q(t.getUTCDate(),e,2)}function mi(t,e){return q(t.getUTCHours(),e,2)}function gi(t,e){return q(t.getUTCHours()%12||12,e,2)}function yi(t,e){return q(1+_e.count(wt(t),t),e,3)}function Cn(t,e){return q(t.getUTCMilliseconds(),e,3)}function ki(t,e){return Cn(t,e)+"000"}function pi(t,e){return q(t.getUTCMonth()+1,e,2)}function vi(t,e){return q(t.getUTCMinutes(),e,2)}function Ti(t,e){return q(t.getUTCSeconds(),e,2)}function xi(t){var e=t.getUTCDay();return e===0?7:e}function bi(t,e){return q(wn.count(wt(t)-1,t),e,2)}function Sn(t){var e=t.getUTCDay();return e>=4||e===0?It(t):It.ceil(t)}function wi(t,e){return t=Sn(t),q(It.count(wt(t),t)+(wt(t).getUTCDay()===4),e,2)}function Di(t){return t.getUTCDay()}function Mi(t,e){return q(re.count(wt(t)-1,t),e,2)}function Ci(t,e){return q(t.getUTCFullYear()%100,e,2)}function Si(t,e){return t=Sn(t),q(t.getUTCFullYear()%100,e,2)}function _i(t,e){return q(t.getUTCFullYear()%1e4,e,4)}function Yi(t,e){var n=t.getUTCDay();return t=n>=4||n===0?It(t):It.ceil(t),q(t.getUTCFullYear()%1e4,e,4)}function Fi(){return"+0000"}function je(){return"%"}function Qe(t){return+t}function Je(t){return Math.floor(+t/1e3)}var St,ie;Ui({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function Ui(t){return St=Ur(t),ie=St.format,St.parse,St.utcFormat,St.utcParse,St}function Ei(t){return new Date(t)}function Ii(t){return t instanceof Date?+t:+new Date(+t)}function _n(t,e,n,r,i,s,a,y,F,S){var w=Jn(),P=w.invert,_=w.domain,Y=S(".%L"),X=S(":%S"),B=S("%I:%M"),v=S("%I %p"),U=S("%a %d"),R=S("%b %d"),E=S("%B"),z=S("%Y");function G(T){return(F(T)<T?Y:y(T)<T?X:a(T)<T?B:s(T)<T?v:r(T)<T?i(T)<T?U:R:n(T)<T?E:z)(T)}return w.invert=function(T){return new Date(P(T))},w.domain=function(T){return arguments.length?_(Array.from(T,Ii)):_().map(Ei)},w.ticks=function(T){var k=_();return t(k[0],k[k.length-1],T??10)},w.tickFormat=function(T,k){return k==null?G:S(k)},w.nice=function(T){var k=_();return(!T||typeof T.range!="function")&&(T=e(k[0],k[k.length-1],T??10)),T?_(vr(k,T)):w},w.copy=function(){return Kn(w,_n(t,e,n,r,i,s,a,y,F,S))},w}function Li(){return er.apply(_n(Yr,Fr,kt,Rt,zt,xt,Pt,Nt,vt,ie).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}var jt={exports:{}},Ai=jt.exports,Ke;function Wi(){return Ke||(Ke=1,(function(t,e){(function(n,r){t.exports=r()})(Ai,(function(){var n="day";return function(r,i,s){var a=function(S){return S.add(4-S.isoWeekday(),n)},y=i.prototype;y.isoWeekYear=function(){return a(this).year()},y.isoWeek=function(S){if(!this.$utils().u(S))return this.add(7*(S-this.isoWeek()),n);var w,P,_,Y,X=a(this),B=(w=this.isoWeekYear(),P=this.$u,_=(P?s.utc:s)().year(w).startOf("year"),Y=4-_.isoWeekday(),_.isoWeekday()>4&&(Y+=7),_.add(Y,n));return X.diff(B,"week")+1},y.isoWeekday=function(S){return this.$utils().u(S)?this.day()||7:this.day(this.day()%7?S:S-7)};var F=y.startOf;y.startOf=function(S,w){var P=this.$utils(),_=!!P.u(w)||w;return P.p(S)==="isoweek"?_?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):F.bind(this)(S,w)}}}))})(jt)),jt.exports}var $i=Wi();const Oi=oe($i);var Qt={exports:{}},Hi=Qt.exports,tn;function Ni(){return tn||(tn=1,(function(t,e){(function(n,r){t.exports=r()})(Hi,(function(){var n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},r=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,i=/\d/,s=/\d\d/,a=/\d\d?/,y=/\d*[^-_:/,()\s\d]+/,F={},S=function(v){return(v=+v)+(v>68?1900:2e3)},w=function(v){return function(U){this[v]=+U}},P=[/[+-]\d\d:?(\d\d)?|Z/,function(v){(this.zone||(this.zone={})).offset=(function(U){if(!U||U==="Z")return 0;var R=U.match(/([+-]|\d\d)/g),E=60*R[1]+(+R[2]||0);return E===0?0:R[0]==="+"?-E:E})(v)}],_=function(v){var U=F[v];return U&&(U.indexOf?U:U.s.concat(U.f))},Y=function(v,U){var R,E=F.meridiem;if(E){for(var z=1;z<=24;z+=1)if(v.indexOf(E(z,0,U))>-1){R=z>12;break}}else R=v===(U?"pm":"PM");return R},X={A:[y,function(v){this.afternoon=Y(v,!1)}],a:[y,function(v){this.afternoon=Y(v,!0)}],Q:[i,function(v){this.month=3*(v-1)+1}],S:[i,function(v){this.milliseconds=100*+v}],SS:[s,function(v){this.milliseconds=10*+v}],SSS:[/\d{3}/,function(v){this.milliseconds=+v}],s:[a,w("seconds")],ss:[a,w("seconds")],m:[a,w("minutes")],mm:[a,w("minutes")],H:[a,w("hours")],h:[a,w("hours")],HH:[a,w("hours")],hh:[a,w("hours")],D:[a,w("day")],DD:[s,w("day")],Do:[y,function(v){var U=F.ordinal,R=v.match(/\d+/);if(this.day=R[0],U)for(var E=1;E<=31;E+=1)U(E).replace(/\[|\]/g,"")===v&&(this.day=E)}],w:[a,w("week")],ww:[s,w("week")],M:[a,w("month")],MM:[s,w("month")],MMM:[y,function(v){var U=_("months"),R=(_("monthsShort")||U.map((function(E){return E.slice(0,3)}))).indexOf(v)+1;if(R<1)throw new Error;this.month=R%12||R}],MMMM:[y,function(v){var U=_("months").indexOf(v)+1;if(U<1)throw new Error;this.month=U%12||U}],Y:[/[+-]?\d+/,w("year")],YY:[s,function(v){this.year=S(v)}],YYYY:[/\d{4}/,w("year")],Z:P,ZZ:P};function B(v){var U,R;U=v,R=F&&F.formats;for(var E=(v=U.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(x,C,M){var D=M&&M.toUpperCase();return C||R[M]||n[M]||R[D].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(c,g,b){return g||b.slice(1)}))}))).match(r),z=E.length,G=0;G<z;G+=1){var T=E[G],k=X[T],p=k&&k[0],L=k&&k[1];E[G]=L?{regex:p,parser:L}:T.replace(/^\[|\]$/g,"")}return function(x){for(var C={},M=0,D=0;M<z;M+=1){var c=E[M];if(typeof c=="string")D+=c.length;else{var g=c.regex,b=c.parser,m=x.slice(D),I=g.exec(m)[0];b.call(C,I),x=x.replace(I,"")}}return(function(o){var W=o.afternoon;if(W!==void 0){var u=o.hours;W?u<12&&(o.hours+=12):u===12&&(o.hours=0),delete o.afternoon}})(C),C}}return function(v,U,R){R.p.customParseFormat=!0,v&&v.parseTwoDigitYear&&(S=v.parseTwoDigitYear);var E=U.prototype,z=E.parse;E.parse=function(G){var T=G.date,k=G.utc,p=G.args;this.$u=k;var L=p[1];if(typeof L=="string"){var x=p[2]===!0,C=p[3]===!0,M=x||C,D=p[2];C&&(D=p[2]),F=this.$locale(),!x&&D&&(F=R.Ls[D]),this.$d=(function(m,I,o,W){try{if(["x","X"].indexOf(I)>-1)return new Date((I==="X"?1e3:1)*m);var u=B(I)(m),K=u.year,l=u.month,$=u.day,O=u.hours,j=u.minutes,H=u.seconds,J=u.milliseconds,h=u.zone,N=u.week,V=new Date,f=$||(K||l?1:V.getDate()),tt=K||V.getFullYear(),A=0;K&&!l||(A=l>0?l-1:V.getMonth());var Q,Z=O||0,st=j||0,at=H||0,pt=J||0;return h?new Date(Date.UTC(tt,A,f,Z,st,at,pt+60*h.offset*1e3)):o?new Date(Date.UTC(tt,A,f,Z,st,at,pt)):(Q=new Date(tt,A,f,Z,st,at,pt),N&&(Q=W(Q).week(N).toDate()),Q)}catch{return new Date("")}})(T,L,k,R),this.init(),D&&D!==!0&&(this.$L=this.locale(D).$L),M&&T!=this.format(L)&&(this.$d=new Date("")),F={}}else if(L instanceof Array)for(var c=L.length,g=1;g<=c;g+=1){p[1]=L[g-1];var b=R.apply(this,p);if(b.isValid()){this.$d=b.$d,this.$L=b.$L,this.init();break}g===c&&(this.$d=new Date(""))}else z.call(this,G)}}}))})(Qt)),Qt.exports}var Pi=Ni();const Vi=oe(Pi);var Jt={exports:{}},Ri=Jt.exports,en;function zi(){return en||(en=1,(function(t,e){(function(n,r){t.exports=r()})(Ri,(function(){return function(n,r){var i=r.prototype,s=i.format;i.format=function(a){var y=this,F=this.$locale();if(!this.isValid())return s.bind(this)(a);var S=this.$utils(),w=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(P){switch(P){case"Q":return Math.ceil((y.$M+1)/3);case"Do":return F.ordinal(y.$D);case"gggg":return y.weekYear();case"GGGG":return y.isoWeekYear();case"wo":return F.ordinal(y.week(),"W");case"w":case"ww":return S.s(y.week(),P==="w"?1:2,"0");case"W":case"WW":return S.s(y.isoWeek(),P==="W"?1:2,"0");case"k":case"kk":return S.s(String(y.$H===0?24:y.$H),P==="k"?1:2,"0");case"X":return Math.floor(y.$d.getTime()/1e3);case"x":return y.$d.getTime();case"z":return"["+y.offsetName()+"]";case"zzz":return"["+y.offsetName("long")+"]";default:return P}}));return s.bind(this)(w)}}}))})(Jt)),Jt.exports}var qi=zi();const Bi=oe(qi);var Kt={exports:{}},Zi=Kt.exports,nn;function Xi(){return nn||(nn=1,(function(t,e){(function(n,r){t.exports=r()})(Zi,(function(){var n,r,i=1e3,s=6e4,a=36e5,y=864e5,F=31536e6,S=2628e6,w=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,P=/\[([^\]]+)]|YYYY|YY|Y|M{1,2}|D{1,2}|H{1,2}|m{1,2}|s{1,2}|SSS/g,_={years:F,months:S,days:y,hours:a,minutes:s,seconds:i,milliseconds:1,weeks:6048e5},Y=function(T){return T instanceof z},X=function(T,k,p){return new z(T,p,k.$l)},B=function(T){return r.p(T)+"s"},v=function(T){return T<0},U=function(T){return v(T)?Math.ceil(T):Math.floor(T)},R=function(T){return Math.abs(T)},E=function(T,k){return T?v(T)?{negative:!0,format:""+R(T)+k}:{negative:!1,format:""+T+k}:{negative:!1,format:""}},z=(function(){function T(p,L,x){var C=this;if(this.$d={},this.$l=x,p===void 0&&(this.$ms=0,this.parseFromMilliseconds()),L)return X(p*_[B(L)],this);if(typeof p=="number")return this.$ms=p,this.parseFromMilliseconds(),this;if(typeof p=="object")return Object.keys(p).forEach((function(c){C.$d[B(c)]=p[c]})),this.calMilliseconds(),this;if(typeof p=="string"){var M=p.match(w);if(M){var D=M.slice(2).map((function(c){return c!=null?Number(c):0}));return this.$d.years=D[0],this.$d.months=D[1],this.$d.weeks=D[2],this.$d.days=D[3],this.$d.hours=D[4],this.$d.minutes=D[5],this.$d.seconds=D[6],this.calMilliseconds(),this}}return this}var k=T.prototype;return k.calMilliseconds=function(){var p=this;this.$ms=Object.keys(this.$d).reduce((function(L,x){return L+(p.$d[x]||0)*_[x]}),0)},k.parseFromMilliseconds=function(){var p=this.$ms;this.$d.years=U(p/F),p%=F,this.$d.months=U(p/S),p%=S,this.$d.days=U(p/y),p%=y,this.$d.hours=U(p/a),p%=a,this.$d.minutes=U(p/s),p%=s,this.$d.seconds=U(p/i),p%=i,this.$d.milliseconds=p},k.toISOString=function(){var p=E(this.$d.years,"Y"),L=E(this.$d.months,"M"),x=+this.$d.days||0;this.$d.weeks&&(x+=7*this.$d.weeks);var C=E(x,"D"),M=E(this.$d.hours,"H"),D=E(this.$d.minutes,"M"),c=this.$d.seconds||0;this.$d.milliseconds&&(c+=this.$d.milliseconds/1e3,c=Math.round(1e3*c)/1e3);var g=E(c,"S"),b=p.negative||L.negative||C.negative||M.negative||D.negative||g.negative,m=M.format||D.format||g.format?"T":"",I=(b?"-":"")+"P"+p.format+L.format+C.format+m+M.format+D.format+g.format;return I==="P"||I==="-P"?"P0D":I},k.toJSON=function(){return this.toISOString()},k.format=function(p){var L=p||"YYYY-MM-DDTHH:mm:ss",x={Y:this.$d.years,YY:r.s(this.$d.years,2,"0"),YYYY:r.s(this.$d.years,4,"0"),M:this.$d.months,MM:r.s(this.$d.months,2,"0"),D:this.$d.days,DD:r.s(this.$d.days,2,"0"),H:this.$d.hours,HH:r.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:r.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:r.s(this.$d.seconds,2,"0"),SSS:r.s(this.$d.milliseconds,3,"0")};return L.replace(P,(function(C,M){return M||String(x[C])}))},k.as=function(p){return this.$ms/_[B(p)]},k.get=function(p){var L=this.$ms,x=B(p);return x==="milliseconds"?L%=1e3:L=x==="weeks"?U(L/_[x]):this.$d[x],L||0},k.add=function(p,L,x){var C;return C=L?p*_[B(L)]:Y(p)?p.$ms:X(p,this).$ms,X(this.$ms+C*(x?-1:1),this)},k.subtract=function(p,L){return this.add(p,L,!0)},k.locale=function(p){var L=this.clone();return L.$l=p,L},k.clone=function(){return X(this.$ms,this)},k.humanize=function(p){return n().add(this.$ms,"ms").locale(this.$l).fromNow(!p)},k.valueOf=function(){return this.asMilliseconds()},k.milliseconds=function(){return this.get("milliseconds")},k.asMilliseconds=function(){return this.as("milliseconds")},k.seconds=function(){return this.get("seconds")},k.asSeconds=function(){return this.as("seconds")},k.minutes=function(){return this.get("minutes")},k.asMinutes=function(){return this.as("minutes")},k.hours=function(){return this.get("hours")},k.asHours=function(){return this.as("hours")},k.days=function(){return this.get("days")},k.asDays=function(){return this.as("days")},k.weeks=function(){return this.get("weeks")},k.asWeeks=function(){return this.as("weeks")},k.months=function(){return this.get("months")},k.asMonths=function(){return this.as("months")},k.years=function(){return this.get("years")},k.asYears=function(){return this.as("years")},T})(),G=function(T,k,p){return T.add(k.years()*p,"y").add(k.months()*p,"M").add(k.days()*p,"d").add(k.hours()*p,"h").add(k.minutes()*p,"m").add(k.seconds()*p,"s").add(k.milliseconds()*p,"ms")};return function(T,k,p){n=p,r=p().$utils(),p.duration=function(C,M){var D=p.locale();return X(C,{$l:D},M)},p.isDuration=Y;var L=k.prototype.add,x=k.prototype.subtract;k.prototype.add=function(C,M){return Y(C)?G(this,C,1):L.bind(this)(C,M)},k.prototype.subtract=function(C,M){return Y(C)?G(this,C,-1):x.bind(this)(C,M)}}}))})(Kt)),Kt.exports}var Gi=Xi();const ji=oe(Gi);var we=(function(){var t=d(function(D,c,g,b){for(g=g||{},b=D.length;b--;g[D[b]]=c);return g},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],n=[1,26],r=[1,27],i=[1,28],s=[1,29],a=[1,30],y=[1,31],F=[1,32],S=[1,33],w=[1,34],P=[1,9],_=[1,10],Y=[1,11],X=[1,12],B=[1,13],v=[1,14],U=[1,15],R=[1,16],E=[1,19],z=[1,20],G=[1,21],T=[1,22],k=[1,23],p=[1,25],L=[1,35],x={trace:d(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:d(function(c,g,b,m,I,o,W){var u=o.length-1;switch(I){case 1:return o[u-1];case 2:this.$=[];break;case 3:o[u-1].push(o[u]),this.$=o[u-1];break;case 4:case 5:this.$=o[u];break;case 6:case 7:this.$=[];break;case 8:m.setWeekday("monday");break;case 9:m.setWeekday("tuesday");break;case 10:m.setWeekday("wednesday");break;case 11:m.setWeekday("thursday");break;case 12:m.setWeekday("friday");break;case 13:m.setWeekday("saturday");break;case 14:m.setWeekday("sunday");break;case 15:m.setWeekend("friday");break;case 16:m.setWeekend("saturday");break;case 17:m.setDateFormat(o[u].substr(11)),this.$=o[u].substr(11);break;case 18:m.enableInclusiveEndDates(),this.$=o[u].substr(18);break;case 19:m.TopAxis(),this.$=o[u].substr(8);break;case 20:m.setAxisFormat(o[u].substr(11)),this.$=o[u].substr(11);break;case 21:m.setTickInterval(o[u].substr(13)),this.$=o[u].substr(13);break;case 22:m.setExcludes(o[u].substr(9)),this.$=o[u].substr(9);break;case 23:m.setIncludes(o[u].substr(9)),this.$=o[u].substr(9);break;case 24:m.setTodayMarker(o[u].substr(12)),this.$=o[u].substr(12);break;case 27:m.setDiagramTitle(o[u].substr(6)),this.$=o[u].substr(6);break;case 28:this.$=o[u].trim(),m.setAccTitle(this.$);break;case 29:case 30:this.$=o[u].trim(),m.setAccDescription(this.$);break;case 31:m.addSection(o[u].substr(8)),this.$=o[u].substr(8);break;case 33:m.addTask(o[u-1],o[u]),this.$="task";break;case 34:this.$=o[u-1],m.setClickEvent(o[u-1],o[u],null);break;case 35:this.$=o[u-2],m.setClickEvent(o[u-2],o[u-1],o[u]);break;case 36:this.$=o[u-2],m.setClickEvent(o[u-2],o[u-1],null),m.setLink(o[u-2],o[u]);break;case 37:this.$=o[u-3],m.setClickEvent(o[u-3],o[u-2],o[u-1]),m.setLink(o[u-3],o[u]);break;case 38:this.$=o[u-2],m.setClickEvent(o[u-2],o[u],null),m.setLink(o[u-2],o[u-1]);break;case 39:this.$=o[u-3],m.setClickEvent(o[u-3],o[u-1],o[u]),m.setLink(o[u-3],o[u-2]);break;case 40:this.$=o[u-1],m.setLink(o[u-1],o[u]);break;case 41:case 47:this.$=o[u-1]+" "+o[u];break;case 42:case 43:case 45:this.$=o[u-2]+" "+o[u-1]+" "+o[u];break;case 44:case 46:this.$=o[u-3]+" "+o[u-2]+" "+o[u-1]+" "+o[u];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:r,14:i,15:s,16:a,17:y,18:F,19:18,20:S,21:w,22:P,23:_,24:Y,25:X,26:B,27:v,28:U,29:R,30:E,31:z,33:G,35:T,36:k,37:24,38:p,40:L},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:n,13:r,14:i,15:s,16:a,17:y,18:F,19:18,20:S,21:w,22:P,23:_,24:Y,25:X,26:B,27:v,28:U,29:R,30:E,31:z,33:G,35:T,36:k,37:24,38:p,40:L},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:d(function(c,g){if(g.recoverable)this.trace(c);else{var b=new Error(c);throw b.hash=g,b}},"parseError"),parse:d(function(c){var g=this,b=[0],m=[],I=[null],o=[],W=this.table,u="",K=0,l=0,$=2,O=1,j=o.slice.call(arguments,1),H=Object.create(this.lexer),J={yy:{}};for(var h in this.yy)Object.prototype.hasOwnProperty.call(this.yy,h)&&(J.yy[h]=this.yy[h]);H.setInput(c,J.yy),J.yy.lexer=H,J.yy.parser=this,typeof H.yylloc>"u"&&(H.yylloc={});var N=H.yylloc;o.push(N);var V=H.options&&H.options.ranges;typeof J.yy.parseError=="function"?this.parseError=J.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function f(ot){b.length=b.length-2*ot,I.length=I.length-ot,o.length=o.length-ot}d(f,"popStack");function tt(){var ot;return ot=m.pop()||H.lex()||O,typeof ot!="number"&&(ot instanceof Array&&(m=ot,ot=m.pop()),ot=g.symbols_[ot]||ot),ot}d(tt,"lex");for(var A,Q,Z,st,at={},pt,ut,He,Bt;;){if(Q=b[b.length-1],this.defaultActions[Q]?Z=this.defaultActions[Q]:((A===null||typeof A>"u")&&(A=tt()),Z=W[Q]&&W[Q][A]),typeof Z>"u"||!Z.length||!Z[0]){var ce="";Bt=[];for(pt in W[Q])this.terminals_[pt]&&pt>$&&Bt.push("'"+this.terminals_[pt]+"'");H.showPosition?ce="Parse error on line "+(K+1)+`: +import{bg as on,bh as On,bi as cn,bj as un,bk as ln,bl as ue,bm as Hn,g as Nn,s as Pn,p as Vn,o as Rn,a as zn,b as qn,_ as d,c as Yt,d as Zt,e as Bn,bn as it,l as Tt,k as Zn,j as Xn,q as Gn,y as jn}from"./mermaid.core-CJB1tAev.js";import{g as oe}from"./_commonjsHelpers-CqkleIqs.js";import{b as Qn,t as Ne,c as Jn,a as Kn,l as tr}from"./linear-DH49UJnN.js";import{i as er}from"./init-Gi6I4Gst.js";import"./index-D-7nOosq.js";import"./defaultLocale-DX6XiGOO.js";function nr(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n<r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n<i||n===void 0&&i>=i)&&(n=i)}return n}function rr(t,e){let n;if(e===void 0)for(const r of t)r!=null&&(n>r||n===void 0&&r>=r)&&(n=r);else{let r=-1;for(let i of t)(i=e(i,++r,t))!=null&&(n>i||n===void 0&&i>=i)&&(n=i)}return n}function ir(t){return t}var Gt=1,le=2,xe=3,Xt=4,Pe=1e-6;function sr(t){return"translate("+t+",0)"}function ar(t){return"translate(0,"+t+")"}function or(t){return e=>+t(e)}function cr(t,e){return e=Math.max(0,t.bandwidth()-e*2)/2,t.round()&&(e=Math.round(e)),n=>+t(n)+e}function ur(){return!this.__axis}function fn(t,e){var n=[],r=null,i=null,s=6,a=6,y=3,F=typeof window<"u"&&window.devicePixelRatio>1?0:.5,S=t===Gt||t===Xt?-1:1,w=t===Xt||t===le?"x":"y",P=t===Gt||t===xe?sr:ar;function _(Y){var X=r??(e.ticks?e.ticks.apply(e,n):e.domain()),B=i??(e.tickFormat?e.tickFormat.apply(e,n):ir),v=Math.max(s,0)+y,U=e.range(),R=+U[0]+F,E=+U[U.length-1]+F,z=(e.bandwidth?cr:or)(e.copy(),F),G=Y.selection?Y.selection():Y,T=G.selectAll(".domain").data([null]),k=G.selectAll(".tick").data(X,e).order(),p=k.exit(),L=k.enter().append("g").attr("class","tick"),x=k.select("line"),C=k.select("text");T=T.merge(T.enter().insert("path",".tick").attr("class","domain").attr("stroke","currentColor")),k=k.merge(L),x=x.merge(L.append("line").attr("stroke","currentColor").attr(w+"2",S*s)),C=C.merge(L.append("text").attr("fill","currentColor").attr(w,S*v).attr("dy",t===Gt?"0em":t===xe?"0.71em":"0.32em")),Y!==G&&(T=T.transition(Y),k=k.transition(Y),x=x.transition(Y),C=C.transition(Y),p=p.transition(Y).attr("opacity",Pe).attr("transform",function(M){return isFinite(M=z(M))?P(M+F):this.getAttribute("transform")}),L.attr("opacity",Pe).attr("transform",function(M){var D=this.parentNode.__axis;return P((D&&isFinite(D=D(M))?D:z(M))+F)})),p.remove(),T.attr("d",t===Xt||t===le?a?"M"+S*a+","+R+"H"+F+"V"+E+"H"+S*a:"M"+F+","+R+"V"+E:a?"M"+R+","+S*a+"V"+F+"H"+E+"V"+S*a:"M"+R+","+F+"H"+E),k.attr("opacity",1).attr("transform",function(M){return P(z(M)+F)}),x.attr(w+"2",S*s),C.attr(w,S*v).text(B),G.filter(ur).attr("fill","none").attr("font-size",10).attr("font-family","sans-serif").attr("text-anchor",t===le?"start":t===Xt?"end":"middle"),G.each(function(){this.__axis=z})}return _.scale=function(Y){return arguments.length?(e=Y,_):e},_.ticks=function(){return n=Array.from(arguments),_},_.tickArguments=function(Y){return arguments.length?(n=Y==null?[]:Array.from(Y),_):n.slice()},_.tickValues=function(Y){return arguments.length?(r=Y==null?null:Array.from(Y),_):r&&r.slice()},_.tickFormat=function(Y){return arguments.length?(i=Y,_):i},_.tickSize=function(Y){return arguments.length?(s=a=+Y,_):s},_.tickSizeInner=function(Y){return arguments.length?(s=+Y,_):s},_.tickSizeOuter=function(Y){return arguments.length?(a=+Y,_):a},_.tickPadding=function(Y){return arguments.length?(y=+Y,_):y},_.offset=function(Y){return arguments.length?(F=+Y,_):F},_}function lr(t){return fn(Gt,t)}function fr(t){return fn(xe,t)}const dr=Math.PI/180,hr=180/Math.PI,ne=18,dn=.96422,hn=1,mn=.82521,gn=4/29,Ft=6/29,yn=3*Ft*Ft,mr=Ft*Ft*Ft;function kn(t){if(t instanceof ft)return new ft(t.l,t.a,t.b,t.opacity);if(t instanceof ht)return pn(t);t instanceof on||(t=On(t));var e=me(t.r),n=me(t.g),r=me(t.b),i=fe((.2225045*e+.7168786*n+.0606169*r)/hn),s,a;return e===n&&n===r?s=a=i:(s=fe((.4360747*e+.3850649*n+.1430804*r)/dn),a=fe((.0139322*e+.0971045*n+.7141733*r)/mn)),new ft(116*i-16,500*(s-i),200*(i-a),t.opacity)}function gr(t,e,n,r){return arguments.length===1?kn(t):new ft(t,e,n,r??1)}function ft(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}cn(ft,gr,un(ln,{brighter(t){return new ft(this.l+ne*(t??1),this.a,this.b,this.opacity)},darker(t){return new ft(this.l-ne*(t??1),this.a,this.b,this.opacity)},rgb(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return e=dn*de(e),t=hn*de(t),n=mn*de(n),new on(he(3.1338561*e-1.6168667*t-.4906146*n),he(-.9787684*e+1.9161415*t+.033454*n),he(.0719453*e-.2289914*t+1.4052427*n),this.opacity)}}));function fe(t){return t>mr?Math.pow(t,1/3):t/yn+gn}function de(t){return t>Ft?t*t*t:yn*(t-gn)}function he(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function me(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function yr(t){if(t instanceof ht)return new ht(t.h,t.c,t.l,t.opacity);if(t instanceof ft||(t=kn(t)),t.a===0&&t.b===0)return new ht(NaN,0<t.l&&t.l<100?0:NaN,t.l,t.opacity);var e=Math.atan2(t.b,t.a)*hr;return new ht(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}function be(t,e,n,r){return arguments.length===1?yr(t):new ht(t,e,n,r??1)}function ht(t,e,n,r){this.h=+t,this.c=+e,this.l=+n,this.opacity=+r}function pn(t){if(isNaN(t.h))return new ft(t.l,0,0,t.opacity);var e=t.h*dr;return new ft(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}cn(ht,be,un(ln,{brighter(t){return new ht(this.h,this.c,this.l+ne*(t??1),this.opacity)},darker(t){return new ht(this.h,this.c,this.l-ne*(t??1),this.opacity)},rgb(){return pn(this).rgb()}}));function kr(t){return function(e,n){var r=t((e=be(e)).h,(n=be(n)).h),i=ue(e.c,n.c),s=ue(e.l,n.l),a=ue(e.opacity,n.opacity);return function(y){return e.h=r(y),e.c=i(y),e.l=s(y),e.opacity=a(y),e+""}}}const pr=kr(Hn);function vr(t,e){t=t.slice();var n=0,r=t.length-1,i=t[n],s=t[r],a;return s<i&&(a=n,n=r,r=a,a=i,i=s,s=a),t[n]=e.floor(i),t[r]=e.ceil(s),t}const ge=new Date,ye=new Date;function nt(t,e,n,r){function i(s){return t(s=arguments.length===0?new Date:new Date(+s)),s}return i.floor=s=>(t(s=new Date(+s)),s),i.ceil=s=>(t(s=new Date(s-1)),e(s,1),t(s),s),i.round=s=>{const a=i(s),y=i.ceil(s);return s-a<y-s?a:y},i.offset=(s,a)=>(e(s=new Date(+s),a==null?1:Math.floor(a)),s),i.range=(s,a,y)=>{const F=[];if(s=i.ceil(s),y=y==null?1:Math.floor(y),!(s<a)||!(y>0))return F;let S;do F.push(S=new Date(+s)),e(s,y),t(s);while(S<s&&s<a);return F},i.filter=s=>nt(a=>{if(a>=a)for(;t(a),!s(a);)a.setTime(a-1)},(a,y)=>{if(a>=a)if(y<0)for(;++y<=0;)for(;e(a,-1),!s(a););else for(;--y>=0;)for(;e(a,1),!s(a););}),n&&(i.count=(s,a)=>(ge.setTime(+s),ye.setTime(+a),t(ge),t(ye),Math.floor(n(ge,ye))),i.every=s=>(s=Math.floor(s),!isFinite(s)||!(s>0)?null:s>1?i.filter(r?a=>r(a)%s===0:a=>i.count(0,a)%s===0):i)),i}const Et=nt(()=>{},(t,e)=>{t.setTime(+t+e)},(t,e)=>e-t);Et.every=t=>(t=Math.floor(t),!isFinite(t)||!(t>0)?null:t>1?nt(e=>{e.setTime(Math.floor(e/t)*t)},(e,n)=>{e.setTime(+e+n*t)},(e,n)=>(n-e)/t):Et);Et.range;const mt=1e3,ct=mt*60,gt=ct*60,yt=gt*24,Se=yt*7,Ve=yt*30,ke=yt*365,vt=nt(t=>{t.setTime(t-t.getMilliseconds())},(t,e)=>{t.setTime(+t+e*mt)},(t,e)=>(e-t)/mt,t=>t.getUTCSeconds());vt.range;const Nt=nt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*mt)},(t,e)=>{t.setTime(+t+e*ct)},(t,e)=>(e-t)/ct,t=>t.getMinutes());Nt.range;const Tr=nt(t=>{t.setUTCSeconds(0,0)},(t,e)=>{t.setTime(+t+e*ct)},(t,e)=>(e-t)/ct,t=>t.getUTCMinutes());Tr.range;const Pt=nt(t=>{t.setTime(t-t.getMilliseconds()-t.getSeconds()*mt-t.getMinutes()*ct)},(t,e)=>{t.setTime(+t+e*gt)},(t,e)=>(e-t)/gt,t=>t.getHours());Pt.range;const xr=nt(t=>{t.setUTCMinutes(0,0,0)},(t,e)=>{t.setTime(+t+e*gt)},(t,e)=>(e-t)/gt,t=>t.getUTCHours());xr.range;const xt=nt(t=>t.setHours(0,0,0,0),(t,e)=>t.setDate(t.getDate()+e),(t,e)=>(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*ct)/yt,t=>t.getDate()-1);xt.range;const _e=nt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/yt,t=>t.getUTCDate()-1);_e.range;const br=nt(t=>{t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCDate(t.getUTCDate()+e)},(t,e)=>(e-t)/yt,t=>Math.floor(t/yt));br.range;function Dt(t){return nt(e=>{e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},(e,n)=>{e.setDate(e.getDate()+n*7)},(e,n)=>(n-e-(n.getTimezoneOffset()-e.getTimezoneOffset())*ct)/Se)}const zt=Dt(0),Vt=Dt(1),vn=Dt(2),Tn=Dt(3),bt=Dt(4),xn=Dt(5),bn=Dt(6);zt.range;Vt.range;vn.range;Tn.range;bt.range;xn.range;bn.range;function Mt(t){return nt(e=>{e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCDate(e.getUTCDate()+n*7)},(e,n)=>(n-e)/Se)}const wn=Mt(0),re=Mt(1),wr=Mt(2),Dr=Mt(3),It=Mt(4),Mr=Mt(5),Cr=Mt(6);wn.range;re.range;wr.range;Dr.range;It.range;Mr.range;Cr.range;const Rt=nt(t=>{t.setDate(1),t.setHours(0,0,0,0)},(t,e)=>{t.setMonth(t.getMonth()+e)},(t,e)=>e.getMonth()-t.getMonth()+(e.getFullYear()-t.getFullYear())*12,t=>t.getMonth());Rt.range;const Sr=nt(t=>{t.setUTCDate(1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCMonth(t.getUTCMonth()+e)},(t,e)=>e.getUTCMonth()-t.getUTCMonth()+(e.getUTCFullYear()-t.getUTCFullYear())*12,t=>t.getUTCMonth());Sr.range;const kt=nt(t=>{t.setMonth(0,1),t.setHours(0,0,0,0)},(t,e)=>{t.setFullYear(t.getFullYear()+e)},(t,e)=>e.getFullYear()-t.getFullYear(),t=>t.getFullYear());kt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:nt(e=>{e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},(e,n)=>{e.setFullYear(e.getFullYear()+n*t)});kt.range;const wt=nt(t=>{t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},(t,e)=>{t.setUTCFullYear(t.getUTCFullYear()+e)},(t,e)=>e.getUTCFullYear()-t.getUTCFullYear(),t=>t.getUTCFullYear());wt.every=t=>!isFinite(t=Math.floor(t))||!(t>0)?null:nt(e=>{e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},(e,n)=>{e.setUTCFullYear(e.getUTCFullYear()+n*t)});wt.range;function _r(t,e,n,r,i,s){const a=[[vt,1,mt],[vt,5,5*mt],[vt,15,15*mt],[vt,30,30*mt],[s,1,ct],[s,5,5*ct],[s,15,15*ct],[s,30,30*ct],[i,1,gt],[i,3,3*gt],[i,6,6*gt],[i,12,12*gt],[r,1,yt],[r,2,2*yt],[n,1,Se],[e,1,Ve],[e,3,3*Ve],[t,1,ke]];function y(S,w,P){const _=w<S;_&&([S,w]=[w,S]);const Y=P&&typeof P.range=="function"?P:F(S,w,P),X=Y?Y.range(S,+w+1):[];return _?X.reverse():X}function F(S,w,P){const _=Math.abs(w-S)/P,Y=Qn(([,,v])=>v).right(a,_);if(Y===a.length)return t.every(Ne(S/ke,w/ke,P));if(Y===0)return Et.every(Math.max(Ne(S,w,P),1));const[X,B]=a[_/a[Y-1][2]<a[Y][2]/_?Y-1:Y];return X.every(B)}return[y,F]}const[Yr,Fr]=_r(kt,Rt,zt,xt,Pt,Nt);function pe(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function ve(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function $t(t,e,n){return{y:t,m:e,d:n,H:0,M:0,S:0,L:0}}function Ur(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,s=t.days,a=t.shortDays,y=t.months,F=t.shortMonths,S=Ot(i),w=Ht(i),P=Ot(s),_=Ht(s),Y=Ot(a),X=Ht(a),B=Ot(y),v=Ht(y),U=Ot(F),R=Ht(F),E={a:m,A:I,b:o,B:W,c:null,d:Xe,e:Xe,f:ti,g:li,G:di,H:Qr,I:Jr,j:Kr,L:Dn,m:ei,M:ni,p:u,q:K,Q:Qe,s:Je,S:ri,u:ii,U:si,V:ai,w:oi,W:ci,x:null,X:null,y:ui,Y:fi,Z:hi,"%":je},z={a:l,A:$,b:O,B:j,c:null,d:Ge,e:Ge,f:ki,g:Si,G:Yi,H:mi,I:gi,j:yi,L:Cn,m:pi,M:vi,p:H,q:J,Q:Qe,s:Je,S:Ti,u:xi,U:bi,V:wi,w:Di,W:Mi,x:null,X:null,y:Ci,Y:_i,Z:Fi,"%":je},G={a:x,A:C,b:M,B:D,c,d:Be,e:Be,f:Zr,g:qe,G:ze,H:Ze,I:Ze,j:Rr,L:Br,m:Vr,M:zr,p:L,q:Pr,Q:Gr,s:jr,S:qr,u:Wr,U:$r,V:Or,w:Ar,W:Hr,x:g,X:b,y:qe,Y:ze,Z:Nr,"%":Xr};E.x=T(n,E),E.X=T(r,E),E.c=T(e,E),z.x=T(n,z),z.X=T(r,z),z.c=T(e,z);function T(h,N){return function(V){var f=[],tt=-1,A=0,Q=h.length,Z,st,at;for(V instanceof Date||(V=new Date(+V));++tt<Q;)h.charCodeAt(tt)===37&&(f.push(h.slice(A,tt)),(st=Re[Z=h.charAt(++tt)])!=null?Z=h.charAt(++tt):st=Z==="e"?" ":"0",(at=N[Z])&&(Z=at(V,st)),f.push(Z),A=tt+1);return f.push(h.slice(A,tt)),f.join("")}}function k(h,N){return function(V){var f=$t(1900,void 0,1),tt=p(f,h,V+="",0),A,Q;if(tt!=V.length)return null;if("Q"in f)return new Date(f.Q);if("s"in f)return new Date(f.s*1e3+("L"in f?f.L:0));if(N&&!("Z"in f)&&(f.Z=0),"p"in f&&(f.H=f.H%12+f.p*12),f.m===void 0&&(f.m="q"in f?f.q:0),"V"in f){if(f.V<1||f.V>53)return null;"w"in f||(f.w=1),"Z"in f?(A=ve($t(f.y,0,1)),Q=A.getUTCDay(),A=Q>4||Q===0?re.ceil(A):re(A),A=_e.offset(A,(f.V-1)*7),f.y=A.getUTCFullYear(),f.m=A.getUTCMonth(),f.d=A.getUTCDate()+(f.w+6)%7):(A=pe($t(f.y,0,1)),Q=A.getDay(),A=Q>4||Q===0?Vt.ceil(A):Vt(A),A=xt.offset(A,(f.V-1)*7),f.y=A.getFullYear(),f.m=A.getMonth(),f.d=A.getDate()+(f.w+6)%7)}else("W"in f||"U"in f)&&("w"in f||(f.w="u"in f?f.u%7:"W"in f?1:0),Q="Z"in f?ve($t(f.y,0,1)).getUTCDay():pe($t(f.y,0,1)).getDay(),f.m=0,f.d="W"in f?(f.w+6)%7+f.W*7-(Q+5)%7:f.w+f.U*7-(Q+6)%7);return"Z"in f?(f.H+=f.Z/100|0,f.M+=f.Z%100,ve(f)):pe(f)}}function p(h,N,V,f){for(var tt=0,A=N.length,Q=V.length,Z,st;tt<A;){if(f>=Q)return-1;if(Z=N.charCodeAt(tt++),Z===37){if(Z=N.charAt(tt++),st=G[Z in Re?N.charAt(tt++):Z],!st||(f=st(h,V,f))<0)return-1}else if(Z!=V.charCodeAt(f++))return-1}return f}function L(h,N,V){var f=S.exec(N.slice(V));return f?(h.p=w.get(f[0].toLowerCase()),V+f[0].length):-1}function x(h,N,V){var f=Y.exec(N.slice(V));return f?(h.w=X.get(f[0].toLowerCase()),V+f[0].length):-1}function C(h,N,V){var f=P.exec(N.slice(V));return f?(h.w=_.get(f[0].toLowerCase()),V+f[0].length):-1}function M(h,N,V){var f=U.exec(N.slice(V));return f?(h.m=R.get(f[0].toLowerCase()),V+f[0].length):-1}function D(h,N,V){var f=B.exec(N.slice(V));return f?(h.m=v.get(f[0].toLowerCase()),V+f[0].length):-1}function c(h,N,V){return p(h,e,N,V)}function g(h,N,V){return p(h,n,N,V)}function b(h,N,V){return p(h,r,N,V)}function m(h){return a[h.getDay()]}function I(h){return s[h.getDay()]}function o(h){return F[h.getMonth()]}function W(h){return y[h.getMonth()]}function u(h){return i[+(h.getHours()>=12)]}function K(h){return 1+~~(h.getMonth()/3)}function l(h){return a[h.getUTCDay()]}function $(h){return s[h.getUTCDay()]}function O(h){return F[h.getUTCMonth()]}function j(h){return y[h.getUTCMonth()]}function H(h){return i[+(h.getUTCHours()>=12)]}function J(h){return 1+~~(h.getUTCMonth()/3)}return{format:function(h){var N=T(h+="",E);return N.toString=function(){return h},N},parse:function(h){var N=k(h+="",!1);return N.toString=function(){return h},N},utcFormat:function(h){var N=T(h+="",z);return N.toString=function(){return h},N},utcParse:function(h){var N=k(h+="",!0);return N.toString=function(){return h},N}}}var Re={"-":"",_:" ",0:"0"},rt=/^\s*\d+/,Er=/^%/,Ir=/[\\^$*+?|[\]().{}]/g;function q(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",s=i.length;return r+(s<n?new Array(n-s+1).join(e)+i:i)}function Lr(t){return t.replace(Ir,"\\$&")}function Ot(t){return new RegExp("^(?:"+t.map(Lr).join("|")+")","i")}function Ht(t){return new Map(t.map((e,n)=>[e.toLowerCase(),n]))}function Ar(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function Wr(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.u=+r[0],n+r[0].length):-1}function $r(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.U=+r[0],n+r[0].length):-1}function Or(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.V=+r[0],n+r[0].length):-1}function Hr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.W=+r[0],n+r[0].length):-1}function ze(t,e,n){var r=rt.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function qe(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function Nr(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function Pr(t,e,n){var r=rt.exec(e.slice(n,n+1));return r?(t.q=r[0]*3-3,n+r[0].length):-1}function Vr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Be(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Rr(t,e,n){var r=rt.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function Ze(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function zr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function qr(t,e,n){var r=rt.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Br(t,e,n){var r=rt.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Zr(t,e,n){var r=rt.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Xr(t,e,n){var r=Er.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Gr(t,e,n){var r=rt.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function jr(t,e,n){var r=rt.exec(e.slice(n));return r?(t.s=+r[0],n+r[0].length):-1}function Xe(t,e){return q(t.getDate(),e,2)}function Qr(t,e){return q(t.getHours(),e,2)}function Jr(t,e){return q(t.getHours()%12||12,e,2)}function Kr(t,e){return q(1+xt.count(kt(t),t),e,3)}function Dn(t,e){return q(t.getMilliseconds(),e,3)}function ti(t,e){return Dn(t,e)+"000"}function ei(t,e){return q(t.getMonth()+1,e,2)}function ni(t,e){return q(t.getMinutes(),e,2)}function ri(t,e){return q(t.getSeconds(),e,2)}function ii(t){var e=t.getDay();return e===0?7:e}function si(t,e){return q(zt.count(kt(t)-1,t),e,2)}function Mn(t){var e=t.getDay();return e>=4||e===0?bt(t):bt.ceil(t)}function ai(t,e){return t=Mn(t),q(bt.count(kt(t),t)+(kt(t).getDay()===4),e,2)}function oi(t){return t.getDay()}function ci(t,e){return q(Vt.count(kt(t)-1,t),e,2)}function ui(t,e){return q(t.getFullYear()%100,e,2)}function li(t,e){return t=Mn(t),q(t.getFullYear()%100,e,2)}function fi(t,e){return q(t.getFullYear()%1e4,e,4)}function di(t,e){var n=t.getDay();return t=n>=4||n===0?bt(t):bt.ceil(t),q(t.getFullYear()%1e4,e,4)}function hi(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+q(e/60|0,"0",2)+q(e%60,"0",2)}function Ge(t,e){return q(t.getUTCDate(),e,2)}function mi(t,e){return q(t.getUTCHours(),e,2)}function gi(t,e){return q(t.getUTCHours()%12||12,e,2)}function yi(t,e){return q(1+_e.count(wt(t),t),e,3)}function Cn(t,e){return q(t.getUTCMilliseconds(),e,3)}function ki(t,e){return Cn(t,e)+"000"}function pi(t,e){return q(t.getUTCMonth()+1,e,2)}function vi(t,e){return q(t.getUTCMinutes(),e,2)}function Ti(t,e){return q(t.getUTCSeconds(),e,2)}function xi(t){var e=t.getUTCDay();return e===0?7:e}function bi(t,e){return q(wn.count(wt(t)-1,t),e,2)}function Sn(t){var e=t.getUTCDay();return e>=4||e===0?It(t):It.ceil(t)}function wi(t,e){return t=Sn(t),q(It.count(wt(t),t)+(wt(t).getUTCDay()===4),e,2)}function Di(t){return t.getUTCDay()}function Mi(t,e){return q(re.count(wt(t)-1,t),e,2)}function Ci(t,e){return q(t.getUTCFullYear()%100,e,2)}function Si(t,e){return t=Sn(t),q(t.getUTCFullYear()%100,e,2)}function _i(t,e){return q(t.getUTCFullYear()%1e4,e,4)}function Yi(t,e){var n=t.getUTCDay();return t=n>=4||n===0?It(t):It.ceil(t),q(t.getUTCFullYear()%1e4,e,4)}function Fi(){return"+0000"}function je(){return"%"}function Qe(t){return+t}function Je(t){return Math.floor(+t/1e3)}var St,ie;Ui({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});function Ui(t){return St=Ur(t),ie=St.format,St.parse,St.utcFormat,St.utcParse,St}function Ei(t){return new Date(t)}function Ii(t){return t instanceof Date?+t:+new Date(+t)}function _n(t,e,n,r,i,s,a,y,F,S){var w=Jn(),P=w.invert,_=w.domain,Y=S(".%L"),X=S(":%S"),B=S("%I:%M"),v=S("%I %p"),U=S("%a %d"),R=S("%b %d"),E=S("%B"),z=S("%Y");function G(T){return(F(T)<T?Y:y(T)<T?X:a(T)<T?B:s(T)<T?v:r(T)<T?i(T)<T?U:R:n(T)<T?E:z)(T)}return w.invert=function(T){return new Date(P(T))},w.domain=function(T){return arguments.length?_(Array.from(T,Ii)):_().map(Ei)},w.ticks=function(T){var k=_();return t(k[0],k[k.length-1],T??10)},w.tickFormat=function(T,k){return k==null?G:S(k)},w.nice=function(T){var k=_();return(!T||typeof T.range!="function")&&(T=e(k[0],k[k.length-1],T??10)),T?_(vr(k,T)):w},w.copy=function(){return Kn(w,_n(t,e,n,r,i,s,a,y,F,S))},w}function Li(){return er.apply(_n(Yr,Fr,kt,Rt,zt,xt,Pt,Nt,vt,ie).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)}var jt={exports:{}},Ai=jt.exports,Ke;function Wi(){return Ke||(Ke=1,(function(t,e){(function(n,r){t.exports=r()})(Ai,(function(){var n="day";return function(r,i,s){var a=function(S){return S.add(4-S.isoWeekday(),n)},y=i.prototype;y.isoWeekYear=function(){return a(this).year()},y.isoWeek=function(S){if(!this.$utils().u(S))return this.add(7*(S-this.isoWeek()),n);var w,P,_,Y,X=a(this),B=(w=this.isoWeekYear(),P=this.$u,_=(P?s.utc:s)().year(w).startOf("year"),Y=4-_.isoWeekday(),_.isoWeekday()>4&&(Y+=7),_.add(Y,n));return X.diff(B,"week")+1},y.isoWeekday=function(S){return this.$utils().u(S)?this.day()||7:this.day(this.day()%7?S:S-7)};var F=y.startOf;y.startOf=function(S,w){var P=this.$utils(),_=!!P.u(w)||w;return P.p(S)==="isoweek"?_?this.date(this.date()-(this.isoWeekday()-1)).startOf("day"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf("day"):F.bind(this)(S,w)}}}))})(jt)),jt.exports}var $i=Wi();const Oi=oe($i);var Qt={exports:{}},Hi=Qt.exports,tn;function Ni(){return tn||(tn=1,(function(t,e){(function(n,r){t.exports=r()})(Hi,(function(){var n={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},r=/(\[[^[]*\])|([-_:/.,()\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,i=/\d/,s=/\d\d/,a=/\d\d?/,y=/\d*[^-_:/,()\s\d]+/,F={},S=function(v){return(v=+v)+(v>68?1900:2e3)},w=function(v){return function(U){this[v]=+U}},P=[/[+-]\d\d:?(\d\d)?|Z/,function(v){(this.zone||(this.zone={})).offset=(function(U){if(!U||U==="Z")return 0;var R=U.match(/([+-]|\d\d)/g),E=60*R[1]+(+R[2]||0);return E===0?0:R[0]==="+"?-E:E})(v)}],_=function(v){var U=F[v];return U&&(U.indexOf?U:U.s.concat(U.f))},Y=function(v,U){var R,E=F.meridiem;if(E){for(var z=1;z<=24;z+=1)if(v.indexOf(E(z,0,U))>-1){R=z>12;break}}else R=v===(U?"pm":"PM");return R},X={A:[y,function(v){this.afternoon=Y(v,!1)}],a:[y,function(v){this.afternoon=Y(v,!0)}],Q:[i,function(v){this.month=3*(v-1)+1}],S:[i,function(v){this.milliseconds=100*+v}],SS:[s,function(v){this.milliseconds=10*+v}],SSS:[/\d{3}/,function(v){this.milliseconds=+v}],s:[a,w("seconds")],ss:[a,w("seconds")],m:[a,w("minutes")],mm:[a,w("minutes")],H:[a,w("hours")],h:[a,w("hours")],HH:[a,w("hours")],hh:[a,w("hours")],D:[a,w("day")],DD:[s,w("day")],Do:[y,function(v){var U=F.ordinal,R=v.match(/\d+/);if(this.day=R[0],U)for(var E=1;E<=31;E+=1)U(E).replace(/\[|\]/g,"")===v&&(this.day=E)}],w:[a,w("week")],ww:[s,w("week")],M:[a,w("month")],MM:[s,w("month")],MMM:[y,function(v){var U=_("months"),R=(_("monthsShort")||U.map((function(E){return E.slice(0,3)}))).indexOf(v)+1;if(R<1)throw new Error;this.month=R%12||R}],MMMM:[y,function(v){var U=_("months").indexOf(v)+1;if(U<1)throw new Error;this.month=U%12||U}],Y:[/[+-]?\d+/,w("year")],YY:[s,function(v){this.year=S(v)}],YYYY:[/\d{4}/,w("year")],Z:P,ZZ:P};function B(v){var U,R;U=v,R=F&&F.formats;for(var E=(v=U.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(x,C,M){var D=M&&M.toUpperCase();return C||R[M]||n[M]||R[D].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(c,g,b){return g||b.slice(1)}))}))).match(r),z=E.length,G=0;G<z;G+=1){var T=E[G],k=X[T],p=k&&k[0],L=k&&k[1];E[G]=L?{regex:p,parser:L}:T.replace(/^\[|\]$/g,"")}return function(x){for(var C={},M=0,D=0;M<z;M+=1){var c=E[M];if(typeof c=="string")D+=c.length;else{var g=c.regex,b=c.parser,m=x.slice(D),I=g.exec(m)[0];b.call(C,I),x=x.replace(I,"")}}return(function(o){var W=o.afternoon;if(W!==void 0){var u=o.hours;W?u<12&&(o.hours+=12):u===12&&(o.hours=0),delete o.afternoon}})(C),C}}return function(v,U,R){R.p.customParseFormat=!0,v&&v.parseTwoDigitYear&&(S=v.parseTwoDigitYear);var E=U.prototype,z=E.parse;E.parse=function(G){var T=G.date,k=G.utc,p=G.args;this.$u=k;var L=p[1];if(typeof L=="string"){var x=p[2]===!0,C=p[3]===!0,M=x||C,D=p[2];C&&(D=p[2]),F=this.$locale(),!x&&D&&(F=R.Ls[D]),this.$d=(function(m,I,o,W){try{if(["x","X"].indexOf(I)>-1)return new Date((I==="X"?1e3:1)*m);var u=B(I)(m),K=u.year,l=u.month,$=u.day,O=u.hours,j=u.minutes,H=u.seconds,J=u.milliseconds,h=u.zone,N=u.week,V=new Date,f=$||(K||l?1:V.getDate()),tt=K||V.getFullYear(),A=0;K&&!l||(A=l>0?l-1:V.getMonth());var Q,Z=O||0,st=j||0,at=H||0,pt=J||0;return h?new Date(Date.UTC(tt,A,f,Z,st,at,pt+60*h.offset*1e3)):o?new Date(Date.UTC(tt,A,f,Z,st,at,pt)):(Q=new Date(tt,A,f,Z,st,at,pt),N&&(Q=W(Q).week(N).toDate()),Q)}catch{return new Date("")}})(T,L,k,R),this.init(),D&&D!==!0&&(this.$L=this.locale(D).$L),M&&T!=this.format(L)&&(this.$d=new Date("")),F={}}else if(L instanceof Array)for(var c=L.length,g=1;g<=c;g+=1){p[1]=L[g-1];var b=R.apply(this,p);if(b.isValid()){this.$d=b.$d,this.$L=b.$L,this.init();break}g===c&&(this.$d=new Date(""))}else z.call(this,G)}}}))})(Qt)),Qt.exports}var Pi=Ni();const Vi=oe(Pi);var Jt={exports:{}},Ri=Jt.exports,en;function zi(){return en||(en=1,(function(t,e){(function(n,r){t.exports=r()})(Ri,(function(){return function(n,r){var i=r.prototype,s=i.format;i.format=function(a){var y=this,F=this.$locale();if(!this.isValid())return s.bind(this)(a);var S=this.$utils(),w=(a||"YYYY-MM-DDTHH:mm:ssZ").replace(/\[([^\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(P){switch(P){case"Q":return Math.ceil((y.$M+1)/3);case"Do":return F.ordinal(y.$D);case"gggg":return y.weekYear();case"GGGG":return y.isoWeekYear();case"wo":return F.ordinal(y.week(),"W");case"w":case"ww":return S.s(y.week(),P==="w"?1:2,"0");case"W":case"WW":return S.s(y.isoWeek(),P==="W"?1:2,"0");case"k":case"kk":return S.s(String(y.$H===0?24:y.$H),P==="k"?1:2,"0");case"X":return Math.floor(y.$d.getTime()/1e3);case"x":return y.$d.getTime();case"z":return"["+y.offsetName()+"]";case"zzz":return"["+y.offsetName("long")+"]";default:return P}}));return s.bind(this)(w)}}}))})(Jt)),Jt.exports}var qi=zi();const Bi=oe(qi);var Kt={exports:{}},Zi=Kt.exports,nn;function Xi(){return nn||(nn=1,(function(t,e){(function(n,r){t.exports=r()})(Zi,(function(){var n,r,i=1e3,s=6e4,a=36e5,y=864e5,F=31536e6,S=2628e6,w=/^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/,P=/\[([^\]]+)]|YYYY|YY|Y|M{1,2}|D{1,2}|H{1,2}|m{1,2}|s{1,2}|SSS/g,_={years:F,months:S,days:y,hours:a,minutes:s,seconds:i,milliseconds:1,weeks:6048e5},Y=function(T){return T instanceof z},X=function(T,k,p){return new z(T,p,k.$l)},B=function(T){return r.p(T)+"s"},v=function(T){return T<0},U=function(T){return v(T)?Math.ceil(T):Math.floor(T)},R=function(T){return Math.abs(T)},E=function(T,k){return T?v(T)?{negative:!0,format:""+R(T)+k}:{negative:!1,format:""+T+k}:{negative:!1,format:""}},z=(function(){function T(p,L,x){var C=this;if(this.$d={},this.$l=x,p===void 0&&(this.$ms=0,this.parseFromMilliseconds()),L)return X(p*_[B(L)],this);if(typeof p=="number")return this.$ms=p,this.parseFromMilliseconds(),this;if(typeof p=="object")return Object.keys(p).forEach((function(c){C.$d[B(c)]=p[c]})),this.calMilliseconds(),this;if(typeof p=="string"){var M=p.match(w);if(M){var D=M.slice(2).map((function(c){return c!=null?Number(c):0}));return this.$d.years=D[0],this.$d.months=D[1],this.$d.weeks=D[2],this.$d.days=D[3],this.$d.hours=D[4],this.$d.minutes=D[5],this.$d.seconds=D[6],this.calMilliseconds(),this}}return this}var k=T.prototype;return k.calMilliseconds=function(){var p=this;this.$ms=Object.keys(this.$d).reduce((function(L,x){return L+(p.$d[x]||0)*_[x]}),0)},k.parseFromMilliseconds=function(){var p=this.$ms;this.$d.years=U(p/F),p%=F,this.$d.months=U(p/S),p%=S,this.$d.days=U(p/y),p%=y,this.$d.hours=U(p/a),p%=a,this.$d.minutes=U(p/s),p%=s,this.$d.seconds=U(p/i),p%=i,this.$d.milliseconds=p},k.toISOString=function(){var p=E(this.$d.years,"Y"),L=E(this.$d.months,"M"),x=+this.$d.days||0;this.$d.weeks&&(x+=7*this.$d.weeks);var C=E(x,"D"),M=E(this.$d.hours,"H"),D=E(this.$d.minutes,"M"),c=this.$d.seconds||0;this.$d.milliseconds&&(c+=this.$d.milliseconds/1e3,c=Math.round(1e3*c)/1e3);var g=E(c,"S"),b=p.negative||L.negative||C.negative||M.negative||D.negative||g.negative,m=M.format||D.format||g.format?"T":"",I=(b?"-":"")+"P"+p.format+L.format+C.format+m+M.format+D.format+g.format;return I==="P"||I==="-P"?"P0D":I},k.toJSON=function(){return this.toISOString()},k.format=function(p){var L=p||"YYYY-MM-DDTHH:mm:ss",x={Y:this.$d.years,YY:r.s(this.$d.years,2,"0"),YYYY:r.s(this.$d.years,4,"0"),M:this.$d.months,MM:r.s(this.$d.months,2,"0"),D:this.$d.days,DD:r.s(this.$d.days,2,"0"),H:this.$d.hours,HH:r.s(this.$d.hours,2,"0"),m:this.$d.minutes,mm:r.s(this.$d.minutes,2,"0"),s:this.$d.seconds,ss:r.s(this.$d.seconds,2,"0"),SSS:r.s(this.$d.milliseconds,3,"0")};return L.replace(P,(function(C,M){return M||String(x[C])}))},k.as=function(p){return this.$ms/_[B(p)]},k.get=function(p){var L=this.$ms,x=B(p);return x==="milliseconds"?L%=1e3:L=x==="weeks"?U(L/_[x]):this.$d[x],L||0},k.add=function(p,L,x){var C;return C=L?p*_[B(L)]:Y(p)?p.$ms:X(p,this).$ms,X(this.$ms+C*(x?-1:1),this)},k.subtract=function(p,L){return this.add(p,L,!0)},k.locale=function(p){var L=this.clone();return L.$l=p,L},k.clone=function(){return X(this.$ms,this)},k.humanize=function(p){return n().add(this.$ms,"ms").locale(this.$l).fromNow(!p)},k.valueOf=function(){return this.asMilliseconds()},k.milliseconds=function(){return this.get("milliseconds")},k.asMilliseconds=function(){return this.as("milliseconds")},k.seconds=function(){return this.get("seconds")},k.asSeconds=function(){return this.as("seconds")},k.minutes=function(){return this.get("minutes")},k.asMinutes=function(){return this.as("minutes")},k.hours=function(){return this.get("hours")},k.asHours=function(){return this.as("hours")},k.days=function(){return this.get("days")},k.asDays=function(){return this.as("days")},k.weeks=function(){return this.get("weeks")},k.asWeeks=function(){return this.as("weeks")},k.months=function(){return this.get("months")},k.asMonths=function(){return this.as("months")},k.years=function(){return this.get("years")},k.asYears=function(){return this.as("years")},T})(),G=function(T,k,p){return T.add(k.years()*p,"y").add(k.months()*p,"M").add(k.days()*p,"d").add(k.hours()*p,"h").add(k.minutes()*p,"m").add(k.seconds()*p,"s").add(k.milliseconds()*p,"ms")};return function(T,k,p){n=p,r=p().$utils(),p.duration=function(C,M){var D=p.locale();return X(C,{$l:D},M)},p.isDuration=Y;var L=k.prototype.add,x=k.prototype.subtract;k.prototype.add=function(C,M){return Y(C)?G(this,C,1):L.bind(this)(C,M)},k.prototype.subtract=function(C,M){return Y(C)?G(this,C,-1):x.bind(this)(C,M)}}}))})(Kt)),Kt.exports}var Gi=Xi();const ji=oe(Gi);var we=(function(){var t=d(function(D,c,g,b){for(g=g||{},b=D.length;b--;g[D[b]]=c);return g},"o"),e=[6,8,10,12,13,14,15,16,17,18,20,21,22,23,24,25,26,27,28,29,30,31,33,35,36,38,40],n=[1,26],r=[1,27],i=[1,28],s=[1,29],a=[1,30],y=[1,31],F=[1,32],S=[1,33],w=[1,34],P=[1,9],_=[1,10],Y=[1,11],X=[1,12],B=[1,13],v=[1,14],U=[1,15],R=[1,16],E=[1,19],z=[1,20],G=[1,21],T=[1,22],k=[1,23],p=[1,25],L=[1,35],x={trace:d(function(){},"trace"),yy:{},symbols_:{error:2,start:3,gantt:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NL:10,weekday:11,weekday_monday:12,weekday_tuesday:13,weekday_wednesday:14,weekday_thursday:15,weekday_friday:16,weekday_saturday:17,weekday_sunday:18,weekend:19,weekend_friday:20,weekend_saturday:21,dateFormat:22,inclusiveEndDates:23,topAxis:24,axisFormat:25,tickInterval:26,excludes:27,includes:28,todayMarker:29,title:30,acc_title:31,acc_title_value:32,acc_descr:33,acc_descr_value:34,acc_descr_multiline_value:35,section:36,clickStatement:37,taskTxt:38,taskData:39,click:40,callbackname:41,callbackargs:42,href:43,clickStatementDebug:44,$accept:0,$end:1},terminals_:{2:"error",4:"gantt",6:"EOF",8:"SPACE",10:"NL",12:"weekday_monday",13:"weekday_tuesday",14:"weekday_wednesday",15:"weekday_thursday",16:"weekday_friday",17:"weekday_saturday",18:"weekday_sunday",20:"weekend_friday",21:"weekend_saturday",22:"dateFormat",23:"inclusiveEndDates",24:"topAxis",25:"axisFormat",26:"tickInterval",27:"excludes",28:"includes",29:"todayMarker",30:"title",31:"acc_title",32:"acc_title_value",33:"acc_descr",34:"acc_descr_value",35:"acc_descr_multiline_value",36:"section",38:"taskTxt",39:"taskData",40:"click",41:"callbackname",42:"callbackargs",43:"href"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[19,1],[19,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,1],[9,2],[37,2],[37,3],[37,3],[37,4],[37,3],[37,4],[37,2],[44,2],[44,3],[44,3],[44,4],[44,3],[44,4],[44,2]],performAction:d(function(c,g,b,m,I,o,W){var u=o.length-1;switch(I){case 1:return o[u-1];case 2:this.$=[];break;case 3:o[u-1].push(o[u]),this.$=o[u-1];break;case 4:case 5:this.$=o[u];break;case 6:case 7:this.$=[];break;case 8:m.setWeekday("monday");break;case 9:m.setWeekday("tuesday");break;case 10:m.setWeekday("wednesday");break;case 11:m.setWeekday("thursday");break;case 12:m.setWeekday("friday");break;case 13:m.setWeekday("saturday");break;case 14:m.setWeekday("sunday");break;case 15:m.setWeekend("friday");break;case 16:m.setWeekend("saturday");break;case 17:m.setDateFormat(o[u].substr(11)),this.$=o[u].substr(11);break;case 18:m.enableInclusiveEndDates(),this.$=o[u].substr(18);break;case 19:m.TopAxis(),this.$=o[u].substr(8);break;case 20:m.setAxisFormat(o[u].substr(11)),this.$=o[u].substr(11);break;case 21:m.setTickInterval(o[u].substr(13)),this.$=o[u].substr(13);break;case 22:m.setExcludes(o[u].substr(9)),this.$=o[u].substr(9);break;case 23:m.setIncludes(o[u].substr(9)),this.$=o[u].substr(9);break;case 24:m.setTodayMarker(o[u].substr(12)),this.$=o[u].substr(12);break;case 27:m.setDiagramTitle(o[u].substr(6)),this.$=o[u].substr(6);break;case 28:this.$=o[u].trim(),m.setAccTitle(this.$);break;case 29:case 30:this.$=o[u].trim(),m.setAccDescription(this.$);break;case 31:m.addSection(o[u].substr(8)),this.$=o[u].substr(8);break;case 33:m.addTask(o[u-1],o[u]),this.$="task";break;case 34:this.$=o[u-1],m.setClickEvent(o[u-1],o[u],null);break;case 35:this.$=o[u-2],m.setClickEvent(o[u-2],o[u-1],o[u]);break;case 36:this.$=o[u-2],m.setClickEvent(o[u-2],o[u-1],null),m.setLink(o[u-2],o[u]);break;case 37:this.$=o[u-3],m.setClickEvent(o[u-3],o[u-2],o[u-1]),m.setLink(o[u-3],o[u]);break;case 38:this.$=o[u-2],m.setClickEvent(o[u-2],o[u],null),m.setLink(o[u-2],o[u-1]);break;case 39:this.$=o[u-3],m.setClickEvent(o[u-3],o[u-1],o[u]),m.setLink(o[u-3],o[u-2]);break;case 40:this.$=o[u-1],m.setLink(o[u-1],o[u]);break;case 41:case 47:this.$=o[u-1]+" "+o[u];break;case 42:case 43:case 45:this.$=o[u-2]+" "+o[u-1]+" "+o[u];break;case 44:case 46:this.$=o[u-3]+" "+o[u-2]+" "+o[u-1]+" "+o[u];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:17,12:n,13:r,14:i,15:s,16:a,17:y,18:F,19:18,20:S,21:w,22:P,23:_,24:Y,25:X,26:B,27:v,28:U,29:R,30:E,31:z,33:G,35:T,36:k,37:24,38:p,40:L},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:36,11:17,12:n,13:r,14:i,15:s,16:a,17:y,18:F,19:18,20:S,21:w,22:P,23:_,24:Y,25:X,26:B,27:v,28:U,29:R,30:E,31:z,33:G,35:T,36:k,37:24,38:p,40:L},t(e,[2,5]),t(e,[2,6]),t(e,[2,17]),t(e,[2,18]),t(e,[2,19]),t(e,[2,20]),t(e,[2,21]),t(e,[2,22]),t(e,[2,23]),t(e,[2,24]),t(e,[2,25]),t(e,[2,26]),t(e,[2,27]),{32:[1,37]},{34:[1,38]},t(e,[2,30]),t(e,[2,31]),t(e,[2,32]),{39:[1,39]},t(e,[2,8]),t(e,[2,9]),t(e,[2,10]),t(e,[2,11]),t(e,[2,12]),t(e,[2,13]),t(e,[2,14]),t(e,[2,15]),t(e,[2,16]),{41:[1,40],43:[1,41]},t(e,[2,4]),t(e,[2,28]),t(e,[2,29]),t(e,[2,33]),t(e,[2,34],{42:[1,42],43:[1,43]}),t(e,[2,40],{41:[1,44]}),t(e,[2,35],{43:[1,45]}),t(e,[2,36]),t(e,[2,38],{42:[1,46]}),t(e,[2,37]),t(e,[2,39])],defaultActions:{},parseError:d(function(c,g){if(g.recoverable)this.trace(c);else{var b=new Error(c);throw b.hash=g,b}},"parseError"),parse:d(function(c){var g=this,b=[0],m=[],I=[null],o=[],W=this.table,u="",K=0,l=0,$=2,O=1,j=o.slice.call(arguments,1),H=Object.create(this.lexer),J={yy:{}};for(var h in this.yy)Object.prototype.hasOwnProperty.call(this.yy,h)&&(J.yy[h]=this.yy[h]);H.setInput(c,J.yy),J.yy.lexer=H,J.yy.parser=this,typeof H.yylloc>"u"&&(H.yylloc={});var N=H.yylloc;o.push(N);var V=H.options&&H.options.ranges;typeof J.yy.parseError=="function"?this.parseError=J.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function f(ot){b.length=b.length-2*ot,I.length=I.length-ot,o.length=o.length-ot}d(f,"popStack");function tt(){var ot;return ot=m.pop()||H.lex()||O,typeof ot!="number"&&(ot instanceof Array&&(m=ot,ot=m.pop()),ot=g.symbols_[ot]||ot),ot}d(tt,"lex");for(var A,Q,Z,st,at={},pt,ut,He,Bt;;){if(Q=b[b.length-1],this.defaultActions[Q]?Z=this.defaultActions[Q]:((A===null||typeof A>"u")&&(A=tt()),Z=W[Q]&&W[Q][A]),typeof Z>"u"||!Z.length||!Z[0]){var ce="";Bt=[];for(pt in W[Q])this.terminals_[pt]&&pt>$&&Bt.push("'"+this.terminals_[pt]+"'");H.showPosition?ce="Parse error on line "+(K+1)+`: `+H.showPosition()+` Expecting `+Bt.join(", ")+", got '"+(this.terminals_[A]||A)+"'":ce="Parse error on line "+(K+1)+": Unexpected "+(A==O?"end of input":"'"+(this.terminals_[A]||A)+"'"),this.parseError(ce,{text:H.match,token:this.terminals_[A]||A,line:H.yylineno,loc:N,expected:Bt})}if(Z[0]instanceof Array&&Z.length>1)throw new Error("Parse Error: multiple actions possible at state: "+Q+", token: "+A);switch(Z[0]){case 1:b.push(A),I.push(H.yytext),o.push(H.yylloc),b.push(Z[1]),A=null,l=H.yyleng,u=H.yytext,K=H.yylineno,N=H.yylloc;break;case 2:if(ut=this.productions_[Z[1]][1],at.$=I[I.length-ut],at._$={first_line:o[o.length-(ut||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(ut||1)].first_column,last_column:o[o.length-1].last_column},V&&(at._$.range=[o[o.length-(ut||1)].range[0],o[o.length-1].range[1]]),st=this.performAction.apply(at,[u,l,K,J.yy,Z[1],I,o].concat(j)),typeof st<"u")return st;ut&&(b=b.slice(0,-1*ut*2),I=I.slice(0,-1*ut),o=o.slice(0,-1*ut)),b.push(this.productions_[Z[1]][0]),I.push(at.$),o.push(at._$),He=W[b[b.length-2]][b[b.length-1]],b.push(He);break;case 3:return!0}}return!0},"parse")},C=(function(){var D={EOF:1,parseError:d(function(g,b){if(this.yy.parser)this.yy.parser.parseError(g,b);else throw new Error(g)},"parseError"),setInput:d(function(c,g){return this.yy=g||this.yy||{},this._input=c,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:d(function(){var c=this._input[0];this.yytext+=c,this.yyleng++,this.offset++,this.match+=c,this.matched+=c;var g=c.match(/(?:\r\n?|\n).*/g);return g?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),c},"input"),unput:d(function(c){var g=c.length,b=c.split(/(?:\r\n?|\n)/g);this._input=c+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-g),this.offset-=g;var m=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),b.length-1&&(this.yylineno-=b.length-1);var I=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:b?(b.length===m.length?this.yylloc.first_column:0)+m[m.length-b.length].length-b[0].length:this.yylloc.first_column-g},this.options.ranges&&(this.yylloc.range=[I[0],I[0]+this.yyleng-g]),this.yyleng=this.yytext.length,this},"unput"),more:d(function(){return this._more=!0,this},"more"),reject:d(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:d(function(c){this.unput(this.match.slice(c))},"less"),pastInput:d(function(){var c=this.matched.substr(0,this.matched.length-this.match.length);return(c.length>20?"...":"")+c.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:d(function(){var c=this.match;return c.length<20&&(c+=this._input.substr(0,20-c.length)),(c.substr(0,20)+(c.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:d(function(){var c=this.pastInput(),g=new Array(c.length+1).join("-");return c+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-DaTSF-Bh.js b/apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-D7UBC8np.js similarity index 99% rename from apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-DaTSF-Bh.js rename to apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-D7UBC8np.js index 6c06acc6c..131bb5638 100644 --- a/apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-DaTSF-Bh.js +++ b/apps/kimi-code/dist-web/assets/gitGraphDiagram-IHSO6WYX-D7UBC8np.js @@ -1,4 +1,4 @@ -import{I as le}from"./chunk-2Q5K7J3B-DqVWYlyS.js";import{p as he}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{p as $e,o as fe,s as ge,g as ue,a as ye,b as xe,_ as h,z as J,l as w,d as me,c as W,y as pe,A as be,q as we,k as B,B as ke,D as ve,E as Ce}from"./mermaid.core-DaDTfY6S.js";import{p as Ee}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var m={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},Be=ve.gitGraph,S=h(()=>ke({...Be,...J().gitGraph}),"getConfig"),d=new le(()=>{const e=S(),r=e.mainBranchName,t=e.mainBranchOrder;return{mainBranchName:r,commits:new Map,head:null,branchConfig:new Map([[r,{name:r,order:t}]]),branches:new Map([[r,null]]),currBranch:r,direction:"LR",seq:0,options:{}}});function Y(){return Ce({length:7})}h(Y,"getID");function te(e,r){const t=Object.create(null);return e.reduce((s,o)=>{const i=r(o);return t[i]||(t[i]=!0,s.push(o)),s},[])}h(te,"uniqBy");var Te=h(function(e){d.records.direction=e},"setDirection"),Le=h(function(e){w.debug("options str",e),e=e?.trim(),e=e||"{}";try{d.records.options=JSON.parse(e)}catch(r){w.error("error while parsing gitGraph options",r.message)}},"setOptions"),Me=h(function(){return d.records.options},"getOptions"),Re=h(function(e){let r=e.msg,t=e.id;const s=e.type;let o=e.tags;w.info("commit",r,t,s,o),w.debug("Entering commit:",r,t,s,o);const i=S();t=B.sanitizeText(t,i),r=B.sanitizeText(r,i),o=o?.map(a=>B.sanitizeText(a,i));const n={id:t||d.records.seq+"-"+Y(),message:r,seq:d.records.seq++,type:s??m.NORMAL,tags:o??[],parents:d.records.head==null?[]:[d.records.head.id],branch:d.records.currBranch};d.records.head=n,w.info("main branch",i.mainBranchName),d.records.commits.has(n.id)&&w.warn(`Commit ID ${n.id} already exists`),d.records.commits.set(n.id,n),d.records.branches.set(d.records.currBranch,n.id),w.debug("in pushCommit "+n.id)},"commit"),Ie=h(function(e){let r=e.name;const t=e.order;if(r=B.sanitizeText(r,S()),d.records.branches.has(r))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${r}")`);d.records.branches.set(r,d.records.head!=null?d.records.head.id:null),d.records.branchConfig.set(r,{name:r,order:t}),ae(r),w.debug("in createBranch")},"branch"),Oe=h(e=>{let r=e.branch,t=e.id;const s=e.type,o=e.tags,i=S();r=B.sanitizeText(r,i),t&&(t=B.sanitizeText(t,i));const n=d.records.branches.get(d.records.currBranch),a=d.records.branches.get(r),l=n?d.records.commits.get(n):void 0,f=a?d.records.commits.get(a):void 0;if(l&&f&&l.branch===r)throw new Error(`Cannot merge branch '${r}' into itself.`);if(d.records.currBranch===r){const c=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},c}if(l===void 0||!l){const c=new Error(`Incorrect usage of "merge". Current branch (${d.records.currBranch})has no commits`);throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["commit"]},c}if(!d.records.branches.has(r)){const c=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") does not exist");throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:[`branch ${r}`]},c}if(f===void 0||!f){const c=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") has no commits");throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:['"commit"']},c}if(l===f){const c=new Error('Incorrect usage of "merge". Both branches have same head');throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},c}if(t&&d.records.commits.has(t)){const c=new Error('Incorrect usage of "merge". Commit with id:'+t+" already exists, use different custom id");throw c.hash={text:`merge ${r} ${t} ${s} ${o?.join(" ")}`,token:`merge ${r} ${t} ${s} ${o?.join(" ")}`,expected:[`merge ${r} ${t}_UNIQUE ${s} ${o?.join(" ")}`]},c}const g=a||"",$={id:t||`${d.records.seq}-${Y()}`,message:`merged branch ${r} into ${d.records.currBranch}`,seq:d.records.seq++,parents:d.records.head==null?[]:[d.records.head.id,g],branch:d.records.currBranch,type:m.MERGE,customType:s,customId:!!t,tags:o??[]};d.records.head=$,d.records.commits.set($.id,$),d.records.branches.set(d.records.currBranch,$.id),w.debug(d.records.branches),w.debug("in mergeBranch")},"merge"),_e=h(function(e){let r=e.id,t=e.targetId,s=e.tags,o=e.parent;w.debug("Entering cherryPick:",r,t,s);const i=S();if(r=B.sanitizeText(r,i),t=B.sanitizeText(t,i),s=s?.map(l=>B.sanitizeText(l,i)),o=B.sanitizeText(o,i),!r||!d.records.commits.has(r)){const l=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw l.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},l}const n=d.records.commits.get(r);if(n===void 0||!n)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(o&&!(Array.isArray(n.parents)&&n.parents.includes(o)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");const a=n.branch;if(n.type===m.MERGE&&!o)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!t||!d.records.commits.has(t)){if(a===d.records.currBranch){const $=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const l=d.records.branches.get(d.records.currBranch);if(l===void 0||!l){const $=new Error(`Incorrect usage of "cherry-pick". Current branch (${d.records.currBranch})has no commits`);throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const f=d.records.commits.get(l);if(f===void 0||!f){const $=new Error(`Incorrect usage of "cherry-pick". Current branch (${d.records.currBranch})has no commits`);throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const g={id:d.records.seq+"-"+Y(),message:`cherry-picked ${n?.message} into ${d.records.currBranch}`,seq:d.records.seq++,parents:d.records.head==null?[]:[d.records.head.id,n.id],branch:d.records.currBranch,type:m.CHERRY_PICK,tags:s?s.filter(Boolean):[`cherry-pick:${n.id}${n.type===m.MERGE?`|parent:${o}`:""}`]};d.records.head=g,d.records.commits.set(g.id,g),d.records.branches.set(d.records.currBranch,g.id),w.debug(d.records.branches),w.debug("in cherryPick")}},"cherryPick"),ae=h(function(e){if(e=B.sanitizeText(e,S()),d.records.branches.has(e)){d.records.currBranch=e;const r=d.records.branches.get(d.records.currBranch);r===void 0||!r?d.records.head=null:d.records.head=d.records.commits.get(r)??null}else{const r=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${e}")`);throw r.hash={text:`checkout ${e}`,token:`checkout ${e}`,expected:[`branch ${e}`]},r}},"checkout");function V(e,r,t){const s=e.indexOf(r);s===-1?e.push(t):e.splice(s,1,t)}h(V,"upsert");function Q(e){const r=e.reduce((o,i)=>o.seq>i.seq?o:i,e[0]);let t="";e.forEach(function(o){o===r?t+=" *":t+=" |"});const s=[t,r.id,r.seq];for(const o in d.records.branches)d.records.branches.get(o)===r.id&&s.push(o);if(w.debug(s.join(" ")),r.parents&&r.parents.length==2&&r.parents[0]&&r.parents[1]){const o=d.records.commits.get(r.parents[0]);V(e,r,o),r.parents[1]&&e.push(d.records.commits.get(r.parents[1]))}else{if(r.parents.length==0)return;if(r.parents[0]){const o=d.records.commits.get(r.parents[0]);V(e,r,o)}}e=te(e,o=>o.id),Q(e)}h(Q,"prettyPrintCommitHistory");var Ge=h(function(){w.debug(d.records.commits);const e=ne()[0];Q([e])},"prettyPrint"),He=h(function(){d.reset(),we()},"clear"),Se=h(function(){return[...d.records.branchConfig.values()].map((r,t)=>r.order!==null&&r.order!==void 0?r:{...r,order:parseFloat(`0.${t}`)}).sort((r,t)=>(r.order??0)-(t.order??0)).map(({name:r})=>({name:r}))},"getBranchesAsObjArray"),Ae=h(function(){return d.records.branches},"getBranches"),De=h(function(){return d.records.commits},"getCommits"),ne=h(function(){const e=[...d.records.commits.values()];return e.forEach(function(r){w.debug(r.id)}),e.sort((r,t)=>r.seq-t.seq),e},"getCommitsArray"),qe=h(function(){return d.records.currBranch},"getCurrentBranch"),Pe=h(function(){return d.records.direction},"getDirection"),We=h(function(){return d.records.head},"getHead"),se={commitType:m,getConfig:S,setDirection:Te,setOptions:Le,getOptions:Me,commit:Re,branch:Ie,merge:Oe,cherryPick:_e,checkout:ae,prettyPrint:Ge,clear:He,getBranchesAsObjArray:Se,getBranches:Ae,getCommits:De,getCommitsArray:ne,getCurrentBranch:qe,getDirection:Pe,getHead:We,setAccTitle:xe,getAccTitle:ye,getAccDescription:ue,setAccDescription:ge,setDiagramTitle:fe,getDiagramTitle:$e},Ne=h((e,r)=>{he(e,r),e.dir&&r.setDirection(e.dir);for(const t of e.statements)Fe(t,r)},"populate"),Fe=h((e,r)=>{const s={Commit:h(o=>r.commit(ze(o)),"Commit"),Branch:h(o=>r.branch(Ye(o)),"Branch"),Merge:h(o=>r.merge(je(o)),"Merge"),Checkout:h(o=>r.checkout(Ue(o)),"Checkout"),CherryPicking:h(o=>r.cherryPick(Ke(o)),"CherryPicking")}[e.$type];s?s(e):w.error(`Unknown statement type: ${e.$type}`)},"parseStatement"),ze=h(e=>({id:e.id,msg:e.message??"",type:e.type!==void 0?m[e.type]:m.NORMAL,tags:e.tags??void 0}),"parseCommit"),Ye=h(e=>({name:e.name,order:e.order??0}),"parseBranch"),je=h(e=>({branch:e.branch,id:e.id??"",type:e.type!==void 0?m[e.type]:void 0,tags:e.tags??void 0}),"parseMerge"),Ue=h(e=>e.branch,"parseCheckout"),Ke=h(e=>({id:e.id,targetId:"",tags:e.tags?.length===0?void 0:e.tags,parent:e.parent}),"parseCherryPicking"),Ve={parse:h(async e=>{const r=await Ee("gitGraph",e);w.debug(r),Ne(r,se)},"parse")},O=10,_=40,L=4,R=2,G=8,j=new Set(["redux","redux-dark","redux-color","redux-dark-color"]),X=12,Z=new Set(["redux-color","redux-dark-color"]),Xe=new Set(["dark","redux-dark","redux-dark-color","neo-dark"]),H=h((e,r,t=!1)=>t&&e>0?(e-1)%(r-1)+1:e%r,"calcColorIndex"),C=new Map,E=new Map,F=30,q=new Map,z=[],I=0,y="LR",Je=h(()=>{C.clear(),E.clear(),q.clear(),I=0,z=[],y="LR"},"clear"),oe=h(e=>{const r=document.createElementNS("http://www.w3.org/2000/svg","text");return(typeof e=="string"?e.split(/\\n|\n|<br\s*\/?>/gi):e).forEach(s=>{const o=document.createElementNS("http://www.w3.org/2000/svg","tspan");o.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),o.setAttribute("dy","1em"),o.setAttribute("x","0"),o.setAttribute("class","row"),o.textContent=s.trim(),r.appendChild(o)}),r},"drawText"),ce=h(e=>{let r,t,s;return y==="BT"?(t=h((o,i)=>o<=i,"comparisonFunc"),s=1/0):(t=h((o,i)=>o>=i,"comparisonFunc"),s=0),e.forEach(o=>{const i=y==="TB"||y=="BT"?E.get(o)?.y:E.get(o)?.x;i!==void 0&&t(i,s)&&(r=o,s=i)}),r},"findClosestParent"),Qe=h(e=>{let r="",t=1/0;return e.forEach(s=>{const o=E.get(s).y;o<=t&&(r=s,t=o)}),r||void 0},"findClosestParentBT"),Ze=h((e,r,t)=>{let s=t,o=t;const i=[];e.forEach(n=>{const a=r.get(n);if(!a)throw new Error(`Commit not found for key ${n}`);a.parents.length?(s=rr(a),o=Math.max(s,o)):i.push(a),tr(a,s)}),s=o,i.forEach(n=>{ar(n,s,t)}),e.forEach(n=>{const a=r.get(n);if(a?.parents.length){const l=Qe(a.parents);s=E.get(l).y-_,s<=o&&(o=s);const f=C.get(a.branch).pos,g=s-O;E.set(a.id,{x:f,y:g})}})},"setParallelBTPos"),er=h(e=>{const r=ce(e.parents.filter(s=>s!==null));if(!r)throw new Error(`Closest parent not found for commit ${e.id}`);const t=E.get(r)?.y;if(t===void 0)throw new Error(`Closest parent position not found for commit ${e.id}`);return t},"findClosestParentPos"),rr=h(e=>er(e)+_,"calculateCommitPosition"),tr=h((e,r)=>{const t=C.get(e.branch);if(!t)throw new Error(`Branch not found for commit ${e.id}`);const s=t.pos,o=r+O;return E.set(e.id,{x:s,y:o}),{x:s,y:o}},"setCommitPosition"),ar=h((e,r,t)=>{const s=C.get(e.branch);if(!s)throw new Error(`Branch not found for commit ${e.id}`);const o=r+t,i=s.pos;E.set(e.id,{x:i,y:o})},"setRootPosition"),nr=h((e,r,t,s,o,i)=>{const{theme:n}=W(),a=j.has(n??""),l=Z.has(n??""),f=Xe.has(n??"");if(i===m.HIGHLIGHT)e.append("rect").attr("x",t.x-10+(a?3:0)).attr("y",t.y-10+(a?3:0)).attr("width",a?14:20).attr("height",a?14:20).attr("class",`commit ${r.id} commit-highlight${H(o,G,l)} ${s}-outer`),e.append("rect").attr("x",t.x-6+(a?2:0)).attr("y",t.y-6+(a?2:0)).attr("width",a?8:12).attr("height",a?8:12).attr("class",`commit ${r.id} commit${H(o,G,l)} ${s}-inner`);else if(i===m.CHERRY_PICK)e.append("circle").attr("cx",t.x).attr("cy",t.y).attr("r",a?7:10).attr("class",`commit ${r.id} ${s}`),e.append("circle").attr("cx",t.x-3).attr("cy",t.y+2).attr("r",a?2.5:2.75).attr("fill",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("circle").attr("cx",t.x+3).attr("cy",t.y+2).attr("r",a?2.5:2.75).attr("fill",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("line").attr("x1",t.x+3).attr("y1",t.y+1).attr("x2",t.x).attr("y2",t.y-5).attr("stroke",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("line").attr("x1",t.x-3).attr("y1",t.y+1).attr("x2",t.x).attr("y2",t.y-5).attr("stroke",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`);else{const g=e.append("circle");if(g.attr("cx",t.x),g.attr("cy",t.y),g.attr("r",a?7:10),g.attr("class",`commit ${r.id} commit${H(o,G,l)}`),i===m.MERGE){const $=e.append("circle");$.attr("cx",t.x),$.attr("cy",t.y),$.attr("r",a?5:6),$.attr("class",`commit ${s} ${r.id} commit${H(o,G,l)}`)}if(i===m.REVERSE){const $=e.append("path"),c=a?4:5;$.attr("d",`M ${t.x-c},${t.y-c}L${t.x+c},${t.y+c}M${t.x-c},${t.y+c}L${t.x+c},${t.y-c}`).attr("class",`commit ${s} ${r.id} commit${H(o,G,l)}`)}}},"drawCommitBullet"),sr=h((e,r,t,s,o)=>{if(r.type!==m.CHERRY_PICK&&(r.customId&&r.type===m.MERGE||r.type!==m.MERGE)&&o.showCommitLabel){const i=e.append("g"),n=i.insert("rect").attr("class","commit-label-bkg"),a=i.append("text").attr("x",s).attr("y",t.y+25).attr("class","commit-label").text(r.id),l=a.node()?.getBBox();if(l&&(n.attr("x",t.posWithOffset-l.width/2-R).attr("y",t.y+13.5).attr("width",l.width+2*R).attr("height",l.height+2*R),y==="TB"||y==="BT"?(n.attr("x",t.x-(l.width+4*L+5)).attr("y",t.y-12),a.attr("x",t.x-(l.width+4*L)).attr("y",t.y+l.height-12)):a.attr("x",t.posWithOffset-l.width/2),o.rotateCommitLabel))if(y==="TB"||y==="BT")a.attr("transform","rotate(-45, "+t.x+", "+t.y+")"),n.attr("transform","rotate(-45, "+t.x+", "+t.y+")");else{const f=-7.5-(l.width+10)/25*9.5,g=10+l.width/25*8.5;i.attr("transform","translate("+f+", "+g+") rotate(-45, "+s+", "+t.y+")")}}},"drawCommitLabel"),or=h((e,r,t,s)=>{if(r.tags.length>0){let o=0,i=0,n=0;const a=[];for(const l of r.tags.reverse()){const f=e.insert("polygon"),g=e.append("circle"),$=e.append("text").attr("y",t.y-16-o).attr("class","tag-label").text(l),c=$.node()?.getBBox();if(!c)throw new Error("Tag bbox not found");i=Math.max(i,c.width),n=Math.max(n,c.height),$.attr("x",t.posWithOffset-c.width/2),a.push({tag:$,hole:g,rect:f,yOffset:o}),o+=20}for(const{tag:l,hole:f,rect:g,yOffset:$}of a){const c=n/2,x=t.y-19.2-$;if(g.attr("class","tag-label-bkg").attr("points",` +import{I as le}from"./chunk-2Q5K7J3B-DsAC7dRk.js";import{p as he}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{p as $e,o as fe,s as ge,g as ue,a as ye,b as xe,_ as h,z as J,l as w,d as me,c as W,y as pe,A as be,q as we,k as B,B as ke,D as ve,E as Ce}from"./mermaid.core-CJB1tAev.js";import{p as Ee}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var m={NORMAL:0,REVERSE:1,HIGHLIGHT:2,MERGE:3,CHERRY_PICK:4},Be=ve.gitGraph,S=h(()=>ke({...Be,...J().gitGraph}),"getConfig"),d=new le(()=>{const e=S(),r=e.mainBranchName,t=e.mainBranchOrder;return{mainBranchName:r,commits:new Map,head:null,branchConfig:new Map([[r,{name:r,order:t}]]),branches:new Map([[r,null]]),currBranch:r,direction:"LR",seq:0,options:{}}});function Y(){return Ce({length:7})}h(Y,"getID");function te(e,r){const t=Object.create(null);return e.reduce((s,o)=>{const i=r(o);return t[i]||(t[i]=!0,s.push(o)),s},[])}h(te,"uniqBy");var Te=h(function(e){d.records.direction=e},"setDirection"),Le=h(function(e){w.debug("options str",e),e=e?.trim(),e=e||"{}";try{d.records.options=JSON.parse(e)}catch(r){w.error("error while parsing gitGraph options",r.message)}},"setOptions"),Me=h(function(){return d.records.options},"getOptions"),Re=h(function(e){let r=e.msg,t=e.id;const s=e.type;let o=e.tags;w.info("commit",r,t,s,o),w.debug("Entering commit:",r,t,s,o);const i=S();t=B.sanitizeText(t,i),r=B.sanitizeText(r,i),o=o?.map(a=>B.sanitizeText(a,i));const n={id:t||d.records.seq+"-"+Y(),message:r,seq:d.records.seq++,type:s??m.NORMAL,tags:o??[],parents:d.records.head==null?[]:[d.records.head.id],branch:d.records.currBranch};d.records.head=n,w.info("main branch",i.mainBranchName),d.records.commits.has(n.id)&&w.warn(`Commit ID ${n.id} already exists`),d.records.commits.set(n.id,n),d.records.branches.set(d.records.currBranch,n.id),w.debug("in pushCommit "+n.id)},"commit"),Ie=h(function(e){let r=e.name;const t=e.order;if(r=B.sanitizeText(r,S()),d.records.branches.has(r))throw new Error(`Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using "checkout ${r}")`);d.records.branches.set(r,d.records.head!=null?d.records.head.id:null),d.records.branchConfig.set(r,{name:r,order:t}),ae(r),w.debug("in createBranch")},"branch"),Oe=h(e=>{let r=e.branch,t=e.id;const s=e.type,o=e.tags,i=S();r=B.sanitizeText(r,i),t&&(t=B.sanitizeText(t,i));const n=d.records.branches.get(d.records.currBranch),a=d.records.branches.get(r),l=n?d.records.commits.get(n):void 0,f=a?d.records.commits.get(a):void 0;if(l&&f&&l.branch===r)throw new Error(`Cannot merge branch '${r}' into itself.`);if(d.records.currBranch===r){const c=new Error('Incorrect usage of "merge". Cannot merge a branch to itself');throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},c}if(l===void 0||!l){const c=new Error(`Incorrect usage of "merge". Current branch (${d.records.currBranch})has no commits`);throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["commit"]},c}if(!d.records.branches.has(r)){const c=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") does not exist");throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:[`branch ${r}`]},c}if(f===void 0||!f){const c=new Error('Incorrect usage of "merge". Branch to be merged ('+r+") has no commits");throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:['"commit"']},c}if(l===f){const c=new Error('Incorrect usage of "merge". Both branches have same head');throw c.hash={text:`merge ${r}`,token:`merge ${r}`,expected:["branch abc"]},c}if(t&&d.records.commits.has(t)){const c=new Error('Incorrect usage of "merge". Commit with id:'+t+" already exists, use different custom id");throw c.hash={text:`merge ${r} ${t} ${s} ${o?.join(" ")}`,token:`merge ${r} ${t} ${s} ${o?.join(" ")}`,expected:[`merge ${r} ${t}_UNIQUE ${s} ${o?.join(" ")}`]},c}const g=a||"",$={id:t||`${d.records.seq}-${Y()}`,message:`merged branch ${r} into ${d.records.currBranch}`,seq:d.records.seq++,parents:d.records.head==null?[]:[d.records.head.id,g],branch:d.records.currBranch,type:m.MERGE,customType:s,customId:!!t,tags:o??[]};d.records.head=$,d.records.commits.set($.id,$),d.records.branches.set(d.records.currBranch,$.id),w.debug(d.records.branches),w.debug("in mergeBranch")},"merge"),_e=h(function(e){let r=e.id,t=e.targetId,s=e.tags,o=e.parent;w.debug("Entering cherryPick:",r,t,s);const i=S();if(r=B.sanitizeText(r,i),t=B.sanitizeText(t,i),s=s?.map(l=>B.sanitizeText(l,i)),o=B.sanitizeText(o,i),!r||!d.records.commits.has(r)){const l=new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');throw l.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},l}const n=d.records.commits.get(r);if(n===void 0||!n)throw new Error('Incorrect usage of "cherryPick". Source commit id should exist and provided');if(o&&!(Array.isArray(n.parents)&&n.parents.includes(o)))throw new Error("Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.");const a=n.branch;if(n.type===m.MERGE&&!o)throw new Error("Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.");if(!t||!d.records.commits.has(t)){if(a===d.records.currBranch){const $=new Error('Incorrect usage of "cherryPick". Source commit is already on current branch');throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const l=d.records.branches.get(d.records.currBranch);if(l===void 0||!l){const $=new Error(`Incorrect usage of "cherry-pick". Current branch (${d.records.currBranch})has no commits`);throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const f=d.records.commits.get(l);if(f===void 0||!f){const $=new Error(`Incorrect usage of "cherry-pick". Current branch (${d.records.currBranch})has no commits`);throw $.hash={text:`cherryPick ${r} ${t}`,token:`cherryPick ${r} ${t}`,expected:["cherry-pick abc"]},$}const g={id:d.records.seq+"-"+Y(),message:`cherry-picked ${n?.message} into ${d.records.currBranch}`,seq:d.records.seq++,parents:d.records.head==null?[]:[d.records.head.id,n.id],branch:d.records.currBranch,type:m.CHERRY_PICK,tags:s?s.filter(Boolean):[`cherry-pick:${n.id}${n.type===m.MERGE?`|parent:${o}`:""}`]};d.records.head=g,d.records.commits.set(g.id,g),d.records.branches.set(d.records.currBranch,g.id),w.debug(d.records.branches),w.debug("in cherryPick")}},"cherryPick"),ae=h(function(e){if(e=B.sanitizeText(e,S()),d.records.branches.has(e)){d.records.currBranch=e;const r=d.records.branches.get(d.records.currBranch);r===void 0||!r?d.records.head=null:d.records.head=d.records.commits.get(r)??null}else{const r=new Error(`Trying to checkout branch which is not yet created. (Help try using "branch ${e}")`);throw r.hash={text:`checkout ${e}`,token:`checkout ${e}`,expected:[`branch ${e}`]},r}},"checkout");function V(e,r,t){const s=e.indexOf(r);s===-1?e.push(t):e.splice(s,1,t)}h(V,"upsert");function Q(e){const r=e.reduce((o,i)=>o.seq>i.seq?o:i,e[0]);let t="";e.forEach(function(o){o===r?t+=" *":t+=" |"});const s=[t,r.id,r.seq];for(const o in d.records.branches)d.records.branches.get(o)===r.id&&s.push(o);if(w.debug(s.join(" ")),r.parents&&r.parents.length==2&&r.parents[0]&&r.parents[1]){const o=d.records.commits.get(r.parents[0]);V(e,r,o),r.parents[1]&&e.push(d.records.commits.get(r.parents[1]))}else{if(r.parents.length==0)return;if(r.parents[0]){const o=d.records.commits.get(r.parents[0]);V(e,r,o)}}e=te(e,o=>o.id),Q(e)}h(Q,"prettyPrintCommitHistory");var Ge=h(function(){w.debug(d.records.commits);const e=ne()[0];Q([e])},"prettyPrint"),He=h(function(){d.reset(),we()},"clear"),Se=h(function(){return[...d.records.branchConfig.values()].map((r,t)=>r.order!==null&&r.order!==void 0?r:{...r,order:parseFloat(`0.${t}`)}).sort((r,t)=>(r.order??0)-(t.order??0)).map(({name:r})=>({name:r}))},"getBranchesAsObjArray"),Ae=h(function(){return d.records.branches},"getBranches"),De=h(function(){return d.records.commits},"getCommits"),ne=h(function(){const e=[...d.records.commits.values()];return e.forEach(function(r){w.debug(r.id)}),e.sort((r,t)=>r.seq-t.seq),e},"getCommitsArray"),qe=h(function(){return d.records.currBranch},"getCurrentBranch"),Pe=h(function(){return d.records.direction},"getDirection"),We=h(function(){return d.records.head},"getHead"),se={commitType:m,getConfig:S,setDirection:Te,setOptions:Le,getOptions:Me,commit:Re,branch:Ie,merge:Oe,cherryPick:_e,checkout:ae,prettyPrint:Ge,clear:He,getBranchesAsObjArray:Se,getBranches:Ae,getCommits:De,getCommitsArray:ne,getCurrentBranch:qe,getDirection:Pe,getHead:We,setAccTitle:xe,getAccTitle:ye,getAccDescription:ue,setAccDescription:ge,setDiagramTitle:fe,getDiagramTitle:$e},Ne=h((e,r)=>{he(e,r),e.dir&&r.setDirection(e.dir);for(const t of e.statements)Fe(t,r)},"populate"),Fe=h((e,r)=>{const s={Commit:h(o=>r.commit(ze(o)),"Commit"),Branch:h(o=>r.branch(Ye(o)),"Branch"),Merge:h(o=>r.merge(je(o)),"Merge"),Checkout:h(o=>r.checkout(Ue(o)),"Checkout"),CherryPicking:h(o=>r.cherryPick(Ke(o)),"CherryPicking")}[e.$type];s?s(e):w.error(`Unknown statement type: ${e.$type}`)},"parseStatement"),ze=h(e=>({id:e.id,msg:e.message??"",type:e.type!==void 0?m[e.type]:m.NORMAL,tags:e.tags??void 0}),"parseCommit"),Ye=h(e=>({name:e.name,order:e.order??0}),"parseBranch"),je=h(e=>({branch:e.branch,id:e.id??"",type:e.type!==void 0?m[e.type]:void 0,tags:e.tags??void 0}),"parseMerge"),Ue=h(e=>e.branch,"parseCheckout"),Ke=h(e=>({id:e.id,targetId:"",tags:e.tags?.length===0?void 0:e.tags,parent:e.parent}),"parseCherryPicking"),Ve={parse:h(async e=>{const r=await Ee("gitGraph",e);w.debug(r),Ne(r,se)},"parse")},O=10,_=40,L=4,R=2,G=8,j=new Set(["redux","redux-dark","redux-color","redux-dark-color"]),X=12,Z=new Set(["redux-color","redux-dark-color"]),Xe=new Set(["dark","redux-dark","redux-dark-color","neo-dark"]),H=h((e,r,t=!1)=>t&&e>0?(e-1)%(r-1)+1:e%r,"calcColorIndex"),C=new Map,E=new Map,F=30,q=new Map,z=[],I=0,y="LR",Je=h(()=>{C.clear(),E.clear(),q.clear(),I=0,z=[],y="LR"},"clear"),oe=h(e=>{const r=document.createElementNS("http://www.w3.org/2000/svg","text");return(typeof e=="string"?e.split(/\\n|\n|<br\s*\/?>/gi):e).forEach(s=>{const o=document.createElementNS("http://www.w3.org/2000/svg","tspan");o.setAttributeNS("http://www.w3.org/XML/1998/namespace","xml:space","preserve"),o.setAttribute("dy","1em"),o.setAttribute("x","0"),o.setAttribute("class","row"),o.textContent=s.trim(),r.appendChild(o)}),r},"drawText"),ce=h(e=>{let r,t,s;return y==="BT"?(t=h((o,i)=>o<=i,"comparisonFunc"),s=1/0):(t=h((o,i)=>o>=i,"comparisonFunc"),s=0),e.forEach(o=>{const i=y==="TB"||y=="BT"?E.get(o)?.y:E.get(o)?.x;i!==void 0&&t(i,s)&&(r=o,s=i)}),r},"findClosestParent"),Qe=h(e=>{let r="",t=1/0;return e.forEach(s=>{const o=E.get(s).y;o<=t&&(r=s,t=o)}),r||void 0},"findClosestParentBT"),Ze=h((e,r,t)=>{let s=t,o=t;const i=[];e.forEach(n=>{const a=r.get(n);if(!a)throw new Error(`Commit not found for key ${n}`);a.parents.length?(s=rr(a),o=Math.max(s,o)):i.push(a),tr(a,s)}),s=o,i.forEach(n=>{ar(n,s,t)}),e.forEach(n=>{const a=r.get(n);if(a?.parents.length){const l=Qe(a.parents);s=E.get(l).y-_,s<=o&&(o=s);const f=C.get(a.branch).pos,g=s-O;E.set(a.id,{x:f,y:g})}})},"setParallelBTPos"),er=h(e=>{const r=ce(e.parents.filter(s=>s!==null));if(!r)throw new Error(`Closest parent not found for commit ${e.id}`);const t=E.get(r)?.y;if(t===void 0)throw new Error(`Closest parent position not found for commit ${e.id}`);return t},"findClosestParentPos"),rr=h(e=>er(e)+_,"calculateCommitPosition"),tr=h((e,r)=>{const t=C.get(e.branch);if(!t)throw new Error(`Branch not found for commit ${e.id}`);const s=t.pos,o=r+O;return E.set(e.id,{x:s,y:o}),{x:s,y:o}},"setCommitPosition"),ar=h((e,r,t)=>{const s=C.get(e.branch);if(!s)throw new Error(`Branch not found for commit ${e.id}`);const o=r+t,i=s.pos;E.set(e.id,{x:i,y:o})},"setRootPosition"),nr=h((e,r,t,s,o,i)=>{const{theme:n}=W(),a=j.has(n??""),l=Z.has(n??""),f=Xe.has(n??"");if(i===m.HIGHLIGHT)e.append("rect").attr("x",t.x-10+(a?3:0)).attr("y",t.y-10+(a?3:0)).attr("width",a?14:20).attr("height",a?14:20).attr("class",`commit ${r.id} commit-highlight${H(o,G,l)} ${s}-outer`),e.append("rect").attr("x",t.x-6+(a?2:0)).attr("y",t.y-6+(a?2:0)).attr("width",a?8:12).attr("height",a?8:12).attr("class",`commit ${r.id} commit${H(o,G,l)} ${s}-inner`);else if(i===m.CHERRY_PICK)e.append("circle").attr("cx",t.x).attr("cy",t.y).attr("r",a?7:10).attr("class",`commit ${r.id} ${s}`),e.append("circle").attr("cx",t.x-3).attr("cy",t.y+2).attr("r",a?2.5:2.75).attr("fill",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("circle").attr("cx",t.x+3).attr("cy",t.y+2).attr("r",a?2.5:2.75).attr("fill",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("line").attr("x1",t.x+3).attr("y1",t.y+1).attr("x2",t.x).attr("y2",t.y-5).attr("stroke",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`),e.append("line").attr("x1",t.x-3).attr("y1",t.y+1).attr("x2",t.x).attr("y2",t.y-5).attr("stroke",f?"#000000":"#fff").attr("class",`commit ${r.id} ${s}`);else{const g=e.append("circle");if(g.attr("cx",t.x),g.attr("cy",t.y),g.attr("r",a?7:10),g.attr("class",`commit ${r.id} commit${H(o,G,l)}`),i===m.MERGE){const $=e.append("circle");$.attr("cx",t.x),$.attr("cy",t.y),$.attr("r",a?5:6),$.attr("class",`commit ${s} ${r.id} commit${H(o,G,l)}`)}if(i===m.REVERSE){const $=e.append("path"),c=a?4:5;$.attr("d",`M ${t.x-c},${t.y-c}L${t.x+c},${t.y+c}M${t.x-c},${t.y+c}L${t.x+c},${t.y-c}`).attr("class",`commit ${s} ${r.id} commit${H(o,G,l)}`)}}},"drawCommitBullet"),sr=h((e,r,t,s,o)=>{if(r.type!==m.CHERRY_PICK&&(r.customId&&r.type===m.MERGE||r.type!==m.MERGE)&&o.showCommitLabel){const i=e.append("g"),n=i.insert("rect").attr("class","commit-label-bkg"),a=i.append("text").attr("x",s).attr("y",t.y+25).attr("class","commit-label").text(r.id),l=a.node()?.getBBox();if(l&&(n.attr("x",t.posWithOffset-l.width/2-R).attr("y",t.y+13.5).attr("width",l.width+2*R).attr("height",l.height+2*R),y==="TB"||y==="BT"?(n.attr("x",t.x-(l.width+4*L+5)).attr("y",t.y-12),a.attr("x",t.x-(l.width+4*L)).attr("y",t.y+l.height-12)):a.attr("x",t.posWithOffset-l.width/2),o.rotateCommitLabel))if(y==="TB"||y==="BT")a.attr("transform","rotate(-45, "+t.x+", "+t.y+")"),n.attr("transform","rotate(-45, "+t.x+", "+t.y+")");else{const f=-7.5-(l.width+10)/25*9.5,g=10+l.width/25*8.5;i.attr("transform","translate("+f+", "+g+") rotate(-45, "+s+", "+t.y+")")}}},"drawCommitLabel"),or=h((e,r,t,s)=>{if(r.tags.length>0){let o=0,i=0,n=0;const a=[];for(const l of r.tags.reverse()){const f=e.insert("polygon"),g=e.append("circle"),$=e.append("text").attr("y",t.y-16-o).attr("class","tag-label").text(l),c=$.node()?.getBBox();if(!c)throw new Error("Tag bbox not found");i=Math.max(i,c.width),n=Math.max(n,c.height),$.attr("x",t.posWithOffset-c.width/2),a.push({tag:$,hole:g,rect:f,yOffset:o}),o+=20}for(const{tag:l,hole:f,rect:g,yOffset:$}of a){const c=n/2,x=t.y-19.2-$;if(g.attr("class","tag-label-bkg").attr("points",` ${s-i/2-L/2},${x+R} ${s-i/2-L/2},${x-R} ${t.posWithOffset-i/2-L},${x-c-R} diff --git a/apps/kimi-code/dist-web/assets/index-BTY1et1y.css b/apps/kimi-code/dist-web/assets/index-BTY1et1y.css deleted file mode 100644 index 355a43408..000000000 --- a/apps/kimi-code/dist-web/assets/index-BTY1et1y.css +++ /dev/null @@ -1 +0,0 @@ -.ui-action-card[data-v-aa7ca9d9]{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-4);background:var(--color-surface-raised);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-lg);font-family:var(--font-ui);text-align:left;cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.ui-action-card[data-v-aa7ca9d9]:hover:not(:disabled){border-color:var(--color-line-strong);background:var(--color-surface)}.ui-action-card[data-v-aa7ca9d9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.ui-action-card[data-v-aa7ca9d9]:disabled{opacity:.5;cursor:not-allowed}.ui-action-card__leading[data-v-aa7ca9d9]{align-self:flex-start;display:inline-flex;flex:none}.ui-action-card__text[data-v-aa7ca9d9]{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1)}.ui-action-card__title[data-v-aa7ca9d9]{display:block;font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.ui-action-card__title[data-v-aa7ca9d9] .ui-badge{margin-left:var(--space-2);vertical-align:middle}.ui-action-card__hint[data-v-aa7ca9d9]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.ui-action-card__chevron[data-v-aa7ca9d9]{color:var(--color-text-faint);flex:none}.ui-tip__bubble[data-v-890c262c]{position:fixed;z-index:var(--z-tooltip);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--tip-lines);max-width:280px;padding:4px 8px;border-radius:var(--radius-sm);background:var(--color-text);color:var(--color-bg);font-family:var(--font-ui);font-size:var(--text-xs);line-height:1.35;overflow:hidden;overflow-wrap:anywhere;pointer-events:none;opacity:0;transition:opacity var(--duration-fast) var(--ease-out)}.ui-tip__bubble.positioned[data-v-890c262c]{opacity:1}.ui-icon-button[data-v-2cbeca98]{display:inline-flex;align-items:center;justify-content:center;flex:none;padding:0;border:.5px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);cursor:pointer;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.ui-icon-button[data-v-2cbeca98]:hover:not(:disabled){background:var(--color-hover);color:var(--color-text)}.ui-icon-button[data-v-2cbeca98]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-icon-button[data-v-2cbeca98]:disabled{opacity:.5;cursor:not-allowed}.ui-icon-button--sm[data-v-2cbeca98]{width:var(--icon-button-sm);height:var(--icon-button-sm);border-radius:var(--radius-sm)}.ui-icon-button--md[data-v-2cbeca98]{width:32px;height:32px}.ui-icon-button--lg[data-v-2cbeca98]{width:44px;height:44px}.ui-icon-button[data-v-2cbeca98] svg{width:var(--p-ic-md);height:var(--p-ic-md)}.ui-icon-button--sm[data-v-2cbeca98] svg{width:var(--p-ic-md);height:var(--p-ic-md)}.ui-icon-button--lg[data-v-2cbeca98] svg{width:var(--p-ic-lg);height:var(--p-ic-lg)}.ui-action-toast-host[data-v-e67fcfa0]{position:fixed;top:calc(48px + var(--space-2));left:50%;translate:-50% 0;z-index:var(--z-toast);max-width:calc(100vw - 32px)}.ui-action-toast[data-v-e67fcfa0]{display:flex;align-items:center;gap:var(--space-2);padding:4px 6px 4px 14px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);font-family:var(--font-ui);font-size:var(--text-base);line-height:1.45;color:var(--color-text);white-space:nowrap}.ui-action-toast__body[data-v-e67fcfa0]{min-width:0}.ui-action-toast__body button[data-v-e67fcfa0-s]{border:0;padding:0;margin-inline:var(--space-1);background:none;color:var(--color-accent);cursor:pointer;font:inherit}.ui-action-toast__body button[data-v-e67fcfa0-s]:hover{color:var(--color-accent-hover);text-decoration:underline}.ui-action-toast__body button[data-v-e67fcfa0-s]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:var(--radius-xs)}.ui-action-toast__close[data-v-e67fcfa0]{flex:none}.ui-badge[data-v-d879fe18]{display:inline-flex;align-items:center;gap:6px;border-radius:var(--radius-full);font-family:var(--font-ui);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;border:.5px solid transparent}.ui-badge--md[data-v-d879fe18]{height:22px;padding:0 9px;font-size:var(--text-xs)}.ui-badge--sm[data-v-d879fe18]{height:18px;padding:0 7px;font-size:11px}.ui-badge__dot[data-v-d879fe18]{width:6px;height:6px;border-radius:var(--radius-full);background:currentColor;flex:none}.ui-badge--neutral[data-v-d879fe18]{background:var(--color-surface-sunken);color:var(--color-text-muted);border-color:var(--color-line)}.ui-badge--info[data-v-d879fe18]{background:var(--color-accent-soft);color:var(--color-accent-hover);border-color:var(--color-accent-bd)}.ui-badge--success[data-v-d879fe18]{background:var(--color-success-soft);color:var(--color-success);border-color:var(--color-success-bd)}.ui-badge--warning[data-v-d879fe18]{background:var(--color-warning-soft);color:var(--color-warning);border-color:var(--color-warning-bd)}.ui-badge--danger[data-v-d879fe18]{background:var(--color-danger-soft);color:var(--color-danger);border-color:var(--color-danger-bd)}.ui-badge--solid[data-v-d879fe18]{background:var(--color-text);color:var(--color-bg)}.ui-banner[data-v-6d739c6d]{display:flex;align-items:center;gap:10px;padding:10px 14px;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);line-height:var(--leading-normal)}.ui-banner__icon[data-v-6d739c6d]{display:inline-flex;flex:none}.ui-banner__icon svg[data-v-6d739c6d]{width:18px;height:18px}.ui-banner--info[data-v-6d739c6d]{background:var(--color-accent-soft);border-color:var(--color-accent-bd)}.ui-banner--warning[data-v-6d739c6d]{background:var(--color-warning-soft);border-color:var(--color-warning-bd)}.ui-banner--danger[data-v-6d739c6d]{background:var(--color-danger-soft);border-color:var(--color-danger-bd)}.ui-banner--info .ui-banner__icon[data-v-6d739c6d]{color:var(--color-accent)}.ui-banner--warning .ui-banner__icon[data-v-6d739c6d]{color:var(--color-warning)}.ui-banner--danger .ui-banner__icon[data-v-6d739c6d]{color:var(--color-danger)}.ui-spinner[data-v-476ed1b4]{display:inline-flex;flex:none;color:var(--color-accent)}.ui-spinner--xs[data-v-476ed1b4]{width:var(--p-ic-md);height:var(--p-ic-md)}.ui-spinner--xs .ui-spinner__track[data-v-476ed1b4],.ui-spinner--xs .ui-spinner__arc[data-v-476ed1b4]{r:10.875px;stroke-width:calc(var(--p-ring-stroke) * 1.5)}.ui-spinner--xs .ui-spinner__arc[data-v-476ed1b4]{stroke-dasharray:67.7 67.7;stroke-dashoffset:45.9}.ui-spinner--sm[data-v-476ed1b4]{width:14px;height:14px}.ui-spinner--md[data-v-476ed1b4]{width:18px;height:18px}.ui-spinner--lg[data-v-476ed1b4]{width:28px;height:28px}.ui-spinner__svg[data-v-476ed1b4]{width:100%;height:100%}.ui-spinner__track[data-v-476ed1b4]{fill:none;stroke:var(--color-line);stroke-width:2.2}.ui-spinner__arc[data-v-476ed1b4]{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-dasharray:56 56;stroke-dashoffset:38}.ui-button[data-v-8e78b113]{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);border:.5px solid transparent;border-radius:var(--radius-md);font-family:var(--font-ui);font-weight:var(--weight-medium);line-height:1;cursor:pointer;white-space:nowrap;transition:background var(--duration-base) var(--ease-out),border-color var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.ui-button[data-v-8e78b113]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.ui-button[data-v-8e78b113]:not(:disabled):active{transform:scale(.98)}.ui-button[data-v-8e78b113]:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.ui-button--sm[data-v-8e78b113]{height:30px;padding:0 var(--space-3);font-size:var(--text-sm);border-radius:var(--radius-sm)}.ui-button--md[data-v-8e78b113]{height:36px;padding:0 var(--space-4);font-size:var(--text-base)}.ui-button--lg[data-v-8e78b113]{height:42px;padding:0 var(--space-5);font-size:15px;border-radius:var(--radius-lg)}.ui-button__content[data-v-8e78b113]{display:inline-flex;align-items:center;gap:var(--space-2)}.ui-button__content[data-v-8e78b113] svg{flex:none}.ui-button__content[data-v-8e78b113] svg:not([width]){width:1em;height:1em}.ui-button--primary[data-v-8e78b113]{background:var(--color-accent);color:var(--color-text-on-accent);border-color:var(--color-accent);box-shadow:var(--shadow-xs)}.ui-button--primary[data-v-8e78b113]:not(:disabled):hover{background:var(--color-accent-hover);border-color:var(--color-accent-hover)}.ui-button--secondary[data-v-8e78b113]{background:var(--color-surface-raised);color:var(--color-text);border-color:var(--color-line-strong);box-shadow:var(--shadow-xs)}.ui-button--secondary[data-v-8e78b113]:not(:disabled):hover{border-color:var(--color-line-strong);background:var(--color-hover)}.ui-button--ghost[data-v-8e78b113]{background:transparent;color:var(--color-text-muted);border-color:transparent}.ui-button--ghost[data-v-8e78b113]:not(:disabled):hover{background:var(--color-hover);color:var(--color-text-strong)}.ui-button--danger[data-v-8e78b113]{background:var(--color-danger);color:var(--color-text-on-accent);border-color:var(--color-danger);box-shadow:var(--shadow-xs)}.ui-button--danger[data-v-8e78b113]:not(:disabled):hover{filter:brightness(.96)}.ui-button--danger-soft[data-v-8e78b113]{background:var(--color-danger-soft);color:var(--color-danger);border-color:var(--color-danger-bd)}.ui-button--danger-soft[data-v-8e78b113]:not(:disabled):hover{background:var(--color-danger);color:var(--color-text-on-accent);border-color:var(--color-danger)}.ui-button--text[data-v-8e78b113]{height:auto;padding:0;background:transparent;border-color:transparent;border-radius:var(--radius-xs);color:var(--color-text-muted);font-size:inherit;font-weight:inherit;text-decoration:underline;text-underline-offset:2px}.ui-button--text[data-v-8e78b113]:not(:disabled):hover{color:var(--color-text)}.ui-button--text[data-v-8e78b113]:not(:disabled):active{transform:none}.ui-button.is-loading .ui-button__content[data-v-8e78b113]{opacity:.7}.ui-button .ui-button__spinner[data-v-8e78b113]{flex:none;color:inherit}.ui-button__spinner[data-v-8e78b113] .ui-spinner__track{opacity:.35}.ui-card[data-v-fbd05138]{background:var(--color-surface);border:.5px solid var(--color-line);border-radius:var(--radius-md);overflow:hidden}.ui-card.is-elevated[data-v-fbd05138]{box-shadow:var(--shadow-md);border-color:transparent}.ui-card__head[data-v-fbd05138]{display:flex;align-items:center;gap:var(--space-2);padding:10px 14px;border-bottom:.5px solid var(--color-line);background:var(--color-surface);font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text)}.ui-card__body[data-v-fbd05138]{padding:14px;color:var(--color-text-muted)}.ui-card__foot[data-v-fbd05138]{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding:10px 14px;border-top:.5px solid var(--color-line);background:var(--color-surface)}.ctx-ring[data-v-de787cf2]{width:16px;height:16px;flex:none;transform:rotate(-90deg)}.ctx-ring-track[data-v-de787cf2]{stroke:var(--line)}.ctx-ring-fill[data-v-de787cf2]{stroke:var(--color-accent);transition:stroke-dashoffset .3s ease,stroke .3s ease}.ui-dialog__overlay[data-v-41ce75e5]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-6);background:#0d111747;animation:kimi-dialog-overlay-in-41ce75e5 var(--duration-base) var(--ease-out)}@keyframes kimi-dialog-overlay-in-41ce75e5{0%{opacity:0}to{opacity:1}}.ui-dialog[data-v-41ce75e5]{max-height:calc(100vh - var(--space-8) * 2);display:flex;flex-direction:column;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-xl);box-shadow:var(--shadow-xl);outline:none;overflow:hidden;animation:kimi-card-in var(--duration-slow) var(--ease-out)}.ui-dialog--sm[data-v-41ce75e5]{width:min(360px,100%)}.ui-dialog--md[data-v-41ce75e5]{width:min(440px,100%)}.ui-dialog--lg[data-v-41ce75e5]{width:min(640px,100%)}.ui-dialog--xl[data-v-41ce75e5]{width:min(var(--p-content-max),100%)}.ui-dialog--fixed-height[data-v-41ce75e5]{height:min(680px,calc(100vh - var(--space-8) * 2))}.ui-dialog--grouped[data-v-41ce75e5]{background:var(--color-bg)}.ui-dialog--flush .ui-dialog__body[data-v-41ce75e5]{padding:0}.ui-dialog__head[data-v-41ce75e5]{display:flex;align-items:flex-start;gap:var(--space-3);padding:20px 22px 14px}.ui-dialog__titles[data-v-41ce75e5]{flex:1;min-width:0}.ui-dialog__title[data-v-41ce75e5]{font-size:var(--text-lg);font-weight:500;color:var(--color-text);line-height:var(--leading-tight)}.ui-dialog__desc[data-v-41ce75e5]{margin-top:4px;font-size:var(--text-base);color:var(--color-text-muted)}.ui-dialog__close[data-v-41ce75e5]{flex:none;margin-top:-2px}.ui-dialog__body[data-v-41ce75e5]{flex:1;min-height:0;padding:4px 22px 18px;color:var(--color-text);overflow:auto}.ui-dialog__foot[data-v-41ce75e5]{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:14px 22px 20px}@media(max-width:640px){.ui-dialog__overlay[data-v-41ce75e5]{align-items:flex-end;padding:0}.ui-dialog[data-v-41ce75e5]{width:100%;max-width:100%;max-height:calc(var(--app-height, 100dvh) * .86);border-right:none;border-bottom:none;border-left:none;border-radius:var(--radius-xl) var(--radius-xl) 0 0;padding-bottom:var(--safe-bottom, 0px);animation:ui-dialog-sheet-up-41ce75e5 var(--duration-slow) var(--ease-out)}.ui-dialog--fixed-height[data-v-41ce75e5]{height:calc(var(--app-height, 100dvh) * .86)}}@keyframes ui-dialog-sheet-up-41ce75e5{0%{transform:translateY(101%)}to{transform:translateY(0)}}.ui-empty[data-v-6da80932]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-8) var(--space-4);text-align:center;color:var(--color-text-muted)}.ui-empty__icon[data-v-6da80932]{color:var(--color-text-faint)}.ui-empty__icon[data-v-6da80932] svg{width:48px;height:48px}.ui-empty__title[data-v-6da80932]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text-muted)}.ui-empty__hint[data-v-6da80932]{font-size:var(--text-sm);color:var(--color-text-muted)}.ui-field[data-v-a8de5f7f]{display:flex;flex-direction:column;gap:6px}.ui-field__label[data-v-a8de5f7f]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.ui-field__hint[data-v-a8de5f7f]{font-size:var(--text-xs);color:var(--color-text-faint)}.ui-field__error[data-v-a8de5f7f]{font-size:var(--text-xs);color:var(--color-danger)}.ui-input[data-v-f1cdf732]{width:100%;border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-surface-overlay);box-shadow:var(--shadow-xs);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);line-height:var(--leading-normal);padding:0 var(--space-3);transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.ui-input--md[data-v-f1cdf732]{height:38px}.ui-input--sm[data-v-f1cdf732]{height:32px;font-size:var(--text-sm);border-radius:var(--radius-sm)}.ui-input[data-v-f1cdf732]::placeholder{color:var(--color-text-faint)}.ui-input[data-v-f1cdf732]:hover:not(:disabled):not(:focus){border-color:var(--color-line-strong)}.ui-input[data-v-f1cdf732]:focus{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.ui-input[data-v-f1cdf732]:disabled{opacity:.5;cursor:not-allowed}.ui-input[readonly][data-v-f1cdf732]{background:var(--color-surface-sunken)}.ui-input.has-error[data-v-f1cdf732]{border-color:var(--color-danger)}.ui-input.has-error[data-v-f1cdf732]:focus{box-shadow:0 0 0 3px var(--color-danger-soft)}.ui-kbd[data-v-04b30ce2]{display:inline-flex;align-items:center;gap:3px;flex:none}.ui-kbd__key[data-v-04b30ce2]{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border:.5px solid var(--color-line);border-radius:var(--radius-xs);background:transparent;color:inherit;font-family:var(--font-kbd);font-size:11px;line-height:1}.ui-menu[data-v-18d99605]{min-width:180px;padding:var(--menu-pad);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);display:flex;flex-direction:column}.ui-menu-item[data-v-607794d8]{display:flex;align-items:center;gap:7px;width:100%;padding:var(--menu-item-padding-block) var(--menu-item-padding-inline);border:none;border-radius:var(--radius-menu-item);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-option-label);line-height:var(--leading-tight);text-align:left;cursor:pointer;transition:background var(--duration-base),color var(--duration-base)}.ui-menu-item[data-v-607794d8]:hover:not(:disabled):not(.is-active):not(.is-danger){background:var(--color-hover);color:var(--color-text-strong)}.ui-menu-item[data-v-607794d8]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-menu-item[data-v-607794d8]:disabled{opacity:.5;cursor:not-allowed}.ui-menu-item.is-active[data-v-607794d8]{background:var(--color-hover);color:var(--color-text)}.ui-menu-item.is-danger[data-v-607794d8]{color:var(--color-danger)}.ui-menu-item.is-danger[data-v-607794d8]:hover:not(:disabled){background:var(--color-danger-soft)}.ui-menu-item[data-v-607794d8] svg{display:block;width:16px;height:16px;flex:none;color:var(--muted);transition:color var(--duration-base)}.ui-menu-item[data-v-607794d8]:hover:not(:disabled):not(.is-active):not(.is-danger) svg{color:var(--color-text-strong)}.ui-menu-item.is-active[data-v-607794d8] svg{color:var(--color-text)}.ui-menu-item.is-danger[data-v-607794d8] svg{color:var(--color-danger)}.ui-menu-item--lg[data-v-607794d8]{min-height:44px;padding:12px 14px;font-size:var(--text-sm)}.ui-menu-sep[data-v-607794d8]{height:1px;margin:4px 0;background:var(--color-line)}.ui-tip[data-v-414bd903]{display:contents}.ui-panel-header[data-v-2650aff3]{flex:none;display:flex;align-items:center;gap:var(--space-2);height:var(--panel-head-h, 48px);padding:0 var(--panel-head-inset, 11px) 0 var(--space-3);box-sizing:border-box;min-width:0;border-bottom:.5px solid var(--color-line);background:var(--color-surface-deep)}.ui-panel-header__title[data-v-2650aff3]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--weight-semibold) var(--ui-b2) var(--font-ui);color:var(--color-text)}.ui-panel-header__sub[data-v-2650aff3]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--ui-c1) var(--font-mono);color:var(--color-text-muted)}.ui-panel-header__close[data-v-2650aff3]{flex:none;margin-left:auto}.ui-panel-header.wrap[data-v-2650aff3]{flex-wrap:wrap;height:auto;min-height:var(--panel-head-h, 48px);padding-top:3px;padding-bottom:3px;gap:4px 6px}.ui-panel-header.wrap .ui-panel-header__close[data-v-2650aff3]{margin-left:0}.ui-pill[data-v-fe6a2873]{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;border:.5px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;cursor:default;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}button.ui-pill[data-v-fe6a2873]{cursor:pointer}button.ui-pill[data-v-fe6a2873]:hover:not(:disabled){background:var(--color-hover);color:var(--color-text-strong)}button.ui-pill[data-v-fe6a2873]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}button.ui-pill[data-v-fe6a2873]:disabled{opacity:.5;cursor:not-allowed}.ui-pill.is-active[data-v-fe6a2873]{background:var(--color-accent-soft);color:var(--color-accent)}.ui-pill[data-v-fe6a2873] svg{width:var(--p-ic-sm);height:var(--p-ic-sm);flex:none;color:var(--color-text-faint)}.ui-scroll-area[data-v-9c504ebc]{position:relative;min-width:0;min-height:0;overflow:hidden}.ui-scroll-area__viewport[data-v-9c504ebc]{width:100%;height:100%;overscroll-behavior:contain;scrollbar-width:none}.ui-scroll-area__viewport[data-v-9c504ebc]::-webkit-scrollbar{display:none}.ui-scroll-area__viewport[data-v-9c504ebc]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.ui-scroll-area__bar[data-v-9c504ebc]{position:absolute;z-index:3;opacity:0;pointer-events:none;touch-action:none;transition:opacity var(--duration-base) var(--ease-out)}.ui-scroll-area__bar.is-visible[data-v-9c504ebc]{opacity:1;pointer-events:auto}.ui-scroll-area__bar--vertical[data-v-9c504ebc]{inset:2px 2px 2px auto;width:10px}.ui-scroll-area__bar--horizontal[data-v-9c504ebc]{inset:auto 2px 2px;height:10px}.ui-scroll-area__thumb[data-v-9c504ebc]{position:absolute;display:block;border-radius:999px;background:color-mix(in srgb,var(--color-text-muted) 62%,transparent);transition:background var(--duration-fast) var(--ease-out),width var(--duration-fast) var(--ease-out),height var(--duration-fast) var(--ease-out)}.ui-scroll-area__bar--vertical .ui-scroll-area__thumb[data-v-9c504ebc]{right:1px;width:4px}.ui-scroll-area__bar--horizontal .ui-scroll-area__thumb[data-v-9c504ebc]{bottom:1px;height:4px}.ui-scroll-area__bar:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__thumb[data-v-9c504ebc]:active{background:color-mix(in srgb,var(--color-text-muted) 82%,transparent)}.ui-scroll-area__bar--vertical:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__bar--vertical .ui-scroll-area__thumb[data-v-9c504ebc]:active{width:6px}.ui-scroll-area__bar--horizontal:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__bar--horizontal .ui-scroll-area__thumb[data-v-9c504ebc]:active{height:6px}.ui-seg[data-v-b09ef1d1]{position:relative;display:inline-flex;gap:2px;padding:2px;background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md)}.ui-seg__indicator[data-v-b09ef1d1]{position:absolute;top:0;left:0;z-index:0;border-radius:var(--radius-sm);background:var(--color-surface-raised);box-shadow:var(--shadow-sm);opacity:0;pointer-events:none;transition:transform var(--duration-base) var(--ease-out),width var(--duration-base) var(--ease-out),height var(--duration-base) var(--ease-out),opacity var(--duration-fast) var(--ease-out)}.ui-seg__indicator.is-ready[data-v-b09ef1d1]{opacity:1}.ui-seg__item[data-v-b09ef1d1]{position:relative;z-index:1;display:inline-flex;align-items:center;gap:var(--space-1);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-weight:var(--weight-medium);cursor:pointer;line-height:1;white-space:nowrap;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.ui-seg__swatch[data-v-b09ef1d1]{width:7px;height:7px;border:.5px solid color-mix(in srgb,currentColor 22%,transparent);border-radius:50%;flex:none}.ui-seg__icon[data-v-b09ef1d1]{flex:none}.ui-seg--md .ui-seg__item[data-v-b09ef1d1]{padding:5px var(--space-3);font-size:var(--text-sm)}.ui-seg--sm .ui-seg__item[data-v-b09ef1d1]{height:24px;padding:0 var(--space-2);font-size:var(--text-sm)}.ui-seg--xs .ui-seg__item[data-v-b09ef1d1]{height:20px;padding:0 var(--space-2);font-size:var(--text-xs)}.ui-seg__item[data-v-b09ef1d1]:hover:not(.is-on){color:var(--color-text)}.ui-seg__item.is-on[data-v-b09ef1d1]{color:var(--color-text)}.ui-seg__item[data-v-b09ef1d1]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-select[data-v-285335af]{position:relative;width:100%;font-family:var(--font-ui)}.ui-select__trigger[data-v-285335af]{display:flex;align-items:center;gap:var(--space-2);width:100%;height:100%;padding:0 var(--space-3);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:transparent;box-shadow:none;color:var(--color-text);font:inherit;font-size:var(--text-base);line-height:var(--leading-normal);text-align:left;cursor:pointer;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out)}.ui-select--md[data-v-285335af]{height:38px}.ui-select--sm[data-v-285335af]{height:32px}.ui-select--sm .ui-select__trigger[data-v-285335af]{font-size:var(--text-sm)}.ui-select__trigger[data-v-285335af]:hover:not(:disabled){border-color:var(--color-line-strong)}.ui-select__trigger[data-v-285335af]:focus-visible,.ui-select.is-open .ui-select__trigger[data-v-285335af]{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.ui-select.has-error .ui-select__trigger[data-v-285335af]{border-color:var(--color-danger)}.ui-select.has-error .ui-select__trigger[data-v-285335af]:focus-visible{box-shadow:0 0 0 3px var(--color-danger-soft)}.ui-select__value[data-v-285335af]{min-width:0;flex:1;display:flex;align-items:center;gap:var(--space-2);overflow:hidden;white-space:nowrap}.ui-select__value-text[data-v-285335af]{min-width:0;overflow:hidden;text-overflow:ellipsis}.ui-select__value.is-placeholder[data-v-285335af]{color:var(--color-text-faint)}.ui-select__icon[data-v-285335af]{flex:none;width:14px;height:14px;border-radius:3px}.ui-select__icon--option[data-v-285335af]{width:16px;height:16px;border-radius:4px}.ui-select__chevron[data-v-285335af]{flex:none;color:var(--color-text-muted);transition:transform var(--duration-base) var(--ease-out)}.ui-select.is-open .ui-select__chevron[data-v-285335af]{transform:rotate(180deg)}.ui-select.is-disabled[data-v-285335af]{opacity:.5}.ui-select.is-disabled .ui-select__trigger[data-v-285335af]{cursor:not-allowed}.ui-select__menu[data-v-285335af]{position:fixed;z-index:var(--z-modal-dropdown);max-height:260px;overflow-y:auto;overscroll-behavior:contain;padding:var(--space-1);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.ui-select__group[data-v-285335af]{padding:var(--space-2) var(--space-2) var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium)}.ui-select__option[data-v-285335af]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:32px;padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-select-option);background:transparent;color:var(--color-text);font:inherit;font-size:var(--text-sm);text-align:left;cursor:pointer}.ui-select__option.is-active[data-v-285335af]{background:var(--color-hover);color:var(--color-text-strong)}.ui-select__option[data-v-285335af]:disabled{opacity:.45;cursor:not-allowed}.ui-select__check[data-v-285335af]{flex:none;color:transparent}.ui-select__option.is-selected .ui-select__check[data-v-285335af]{color:var(--color-accent)}.kw-dot[data-v-390a778a]{width:7px;height:7px;border-radius:var(--radius-full);background:var(--color-text-faint);flex:none}.kw-dot--ok[data-v-390a778a]{background:var(--color-success)}.kw-dot--error[data-v-390a778a]{background:var(--color-danger)}.kw-dot--suspended[data-v-390a778a]{background:var(--color-warning)}.kw-dot--running[data-v-390a778a]{background:var(--color-accent);position:relative}.kw-dot--running[data-v-390a778a]:after{content:"";position:absolute;inset:0;border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-accent) 40%,transparent);animation:kw-dot-pulse-390a778a 1.4s var(--ease-out) infinite}@keyframes kw-dot-pulse-390a778a{0%{transform:scale(1);opacity:1}to{transform:scale(2.7);opacity:0}}.ui-switch[data-v-2fc56545]{position:relative;width:36px;height:20px;flex:none;padding:0;border:.5px solid var(--color-line-strong);border-radius:var(--radius-full);background:var(--color-line-strong);cursor:pointer;transition:background var(--duration-base) var(--ease-out)}.ui-switch.is-on[data-v-2fc56545]{background:var(--color-accent)}.ui-switch[data-v-2fc56545]:disabled{opacity:.5;cursor:not-allowed}.ui-switch[data-v-2fc56545]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-switch__thumb[data-v-2fc56545]{position:absolute;top:1.5px;left:1.5px;width:16px;height:16px;border-radius:var(--radius-full);background:var(--color-text-on-accent);box-shadow:var(--shadow-xs);transform-origin:left center;transition:transform var(--duration-base) var(--ease-out)}.ui-switch:not(:disabled):hover .ui-switch__thumb[data-v-2fc56545]{transform:scaleX(1.125)}.ui-switch.is-on .ui-switch__thumb[data-v-2fc56545]{transform:translate(16px);transform-origin:right center}.ui-switch.is-on:not(:disabled):hover .ui-switch__thumb[data-v-2fc56545]{transform:translate(16px) scaleX(1.125)}.ui-textarea[data-v-07cc9fb9]{width:100%;min-height:84px;resize:vertical;border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-surface-overlay);box-shadow:var(--shadow-xs);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);line-height:var(--leading-normal);padding:10px 12px;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.ui-textarea[data-v-07cc9fb9]::placeholder{color:var(--color-text-faint)}.ui-textarea.no-resize[data-v-07cc9fb9]{resize:none}.ui-textarea[data-v-07cc9fb9]:hover:not(:disabled):not(:focus){border-color:var(--color-line-strong)}.ui-textarea[data-v-07cc9fb9]:focus{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.ui-textarea[data-v-07cc9fb9]:disabled{opacity:.5;cursor:not-allowed}.ui-textarea[readonly][data-v-07cc9fb9]{background:var(--color-surface-sunken)}.ui-textarea.has-error[data-v-07cc9fb9]{border-color:var(--color-danger)}.ui-textarea.has-error[data-v-07cc9fb9]:focus{box-shadow:0 0 0 3px var(--color-danger-soft)}.ui-toast[data-v-62bc76d1]{display:flex;align-items:flex-start;gap:11px;width:360px;max-width:100%;padding:13px 14px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);font-family:var(--font-ui);line-height:1.45}.ui-toast__icon[data-v-62bc76d1]{flex:none;width:20px;height:20px;margin-top:1px;border-radius:var(--radius-full);display:grid;place-items:center;background:var(--color-accent-soft);color:var(--color-accent)}.ui-toast__icon svg[data-v-62bc76d1]{width:12px;height:12px}.ui-toast--success .ui-toast__icon[data-v-62bc76d1]{background:var(--color-success-soft);color:var(--color-success)}.ui-toast--warning .ui-toast__icon[data-v-62bc76d1]{background:var(--color-warning-soft);color:var(--color-warning)}.ui-toast--danger .ui-toast__icon[data-v-62bc76d1]{background:var(--color-danger-soft);color:var(--color-danger)}.ui-toast--danger[data-v-62bc76d1]{border-color:color-mix(in srgb,var(--color-danger) 35%,transparent)}.ui-toast__body[data-v-62bc76d1]{flex:1;min-width:0}.ui-toast__title[data-v-62bc76d1]{font-size:var(--text-base);font-weight:500;color:var(--color-text);overflow-wrap:anywhere}.ui-toast__msg[data-v-62bc76d1]{margin-top:2px;font-size:var(--text-sm);color:var(--color-text-muted);overflow-wrap:anywhere}.ui-toast--danger .ui-toast__msg[data-v-62bc76d1]{color:var(--color-danger)}.ui-toast__close[data-v-62bc76d1]{flex:none;margin:-3px -4px 0 0}.sd-search[data-v-5bf43f78]{position:relative;margin:0 22px;padding-bottom:var(--space-1)}.sd-search[data-v-5bf43f78] .ui-input{padding-right:30px}.search-clear[data-v-5bf43f78]{position:absolute;top:0;bottom:var(--space-1);right:var(--space-2);margin-block:auto;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:var(--radius-full);background:var(--color-hover);color:var(--color-text-faint);cursor:pointer;visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast),background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.search-clear.is-on[data-v-5bf43f78]{visibility:visible;opacity:1}.search-clear[data-v-5bf43f78]:hover{background:var(--color-selected);color:var(--color-text-muted)}.search-clear[data-v-5bf43f78]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}@media(prefers-reduced-motion:reduce){.search-clear[data-v-5bf43f78]{transition:none}}.sd-body[data-v-5bf43f78]{height:100%;min-height:0;display:flex;flex-direction:column;gap:var(--space-2);padding-top:4px}.sd-list[data-v-5bf43f78]{flex:1;min-height:0;overflow-y:auto;padding:var(--space-1) var(--space-2);--sd-gutter: var(--p-ic-md);--sd-gap: var(--space-2)}.sd-section[data-v-5bf43f78]{display:flex;align-items:baseline;gap:var(--space-1);padding:var(--space-2) var(--space-3) var(--space-1);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--color-text-faint);user-select:none}.sd-section-count[data-v-5bf43f78]{font-weight:var(--weight-regular)}.sd-section[data-v-5bf43f78]:first-child{padding-top:var(--space-1)}.sd-section[data-v-5bf43f78]:not(:first-child){margin-top:var(--space-1);border-top:var(--p-hairline) solid var(--color-line)}.sd-row[data-v-5bf43f78]{display:flex;flex-direction:column;gap:2px;width:100%;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-md);background:none;cursor:pointer;text-align:left;font-family:var(--font-ui);color:var(--color-text)}.sd-row[data-v-5bf43f78]:hover{background:var(--color-hover)}.sd-row.on[data-v-5bf43f78]{background:var(--color-selected)}.sd-row.active .sd-title[data-v-5bf43f78]{color:var(--color-accent-hover)}.sd-row-ws[data-v-5bf43f78]{flex-direction:row;align-items:center;gap:var(--sd-gap)}.sd-folder[data-v-5bf43f78]{flex:none;width:var(--sd-gutter);color:var(--color-text-muted)}.sd-ws-name[data-v-5bf43f78]{flex:none;max-width:45%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);color:var(--color-text)}.sd-ws-path[data-v-5bf43f78]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:right;font-size:var(--text-xs);color:var(--color-text-faint)}.sd-line1[data-v-5bf43f78],.sd-line2[data-v-5bf43f78]{padding-left:calc(var(--sd-gutter) + var(--sd-gap))}.sd-line1[data-v-5bf43f78]{display:flex;align-items:baseline;gap:var(--space-2);min-width:0}.sd-title[data-v-5bf43f78]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);color:var(--color-text)}.sd-time[data-v-5bf43f78]{flex:none;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint)}.sd-line2[data-v-5bf43f78]{display:flex;align-items:center;gap:var(--space-1);min-width:0;font-size:var(--text-xs);color:var(--color-text-muted)}.sd-meta-ws[data-v-5bf43f78]{flex:none;max-width:40%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-meta-sep[data-v-5bf43f78]{color:var(--color-text-faint)}.sd-meta-snippet[data-v-5bf43f78]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-title[data-v-5bf43f78] mark,.sd-ws-name[data-v-5bf43f78] mark{background:var(--color-accent-soft);color:inherit;font-weight:var(--weight-semibold);border-radius:var(--radius-xs);padding:0 1px}.sd-line2[data-v-5bf43f78] mark,.sd-ws-path[data-v-5bf43f78] mark{background:var(--color-accent-soft);color:var(--color-text);font-weight:var(--weight-medium);border-radius:var(--radius-xs);padding:0 1px}.sd-empty[data-v-5bf43f78]{height:100%;display:flex;align-items:center;justify-content:center}.sd-foot[data-v-5bf43f78]{flex:none;display:flex;align-items:center;gap:var(--space-1);padding:var(--space-2) var(--space-4);border-top:.5px solid var(--color-line);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.sd-hint[data-v-5bf43f78]{display:inline-flex;align-items:center;gap:var(--space-1)}.sd-dot[data-v-5bf43f78]{margin:0 var(--space-1)}.rc-dev[data-v-4dd165fb]{--sb-inset: var(--space-2);--sb-pad-x: var(--space-4);--sb-gap: var(--space-2);--sb-hover: var(--color-hover);position:relative;padding:0 var(--sb-inset) var(--space-1)}.rc-dev--mobile[data-v-4dd165fb]{padding:var(--space-1) var(--sb-inset) var(--space-2)}.rc-dev--mobile .rc-dev-trigger[data-v-4dd165fb]{min-height:44px}.rc-dev-trigger[data-v-4dd165fb]{display:flex;align-items:center;gap:var(--sb-gap);width:100%;min-width:0;padding:6px calc(var(--sb-pad-x) - var(--sb-inset));border:.5px solid var(--color-line);border-radius:var(--radius-md);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);cursor:pointer;text-align:left}.rc-dev-trigger[data-v-4dd165fb]:hover,.rc-dev-trigger[aria-expanded=true][data-v-4dd165fb]{background:var(--sb-hover)}.rc-dev-trigger[data-v-4dd165fb]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.rc-dev-trigger svg[data-v-4dd165fb]{flex:none}.rc-dev-name[data-v-4dd165fb]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rc-dev-chevron[data-v-4dd165fb]{margin-left:auto;color:var(--color-text-faint)}.rc-dev-menu[data-v-4dd165fb]{position:fixed;top:0;left:0;z-index:var(--z-dropdown);max-height:calc(100vh - 16px);overflow-y:auto;overflow-x:hidden;user-select:none}.rc-dev-menu--mobile[data-v-4dd165fb]{position:absolute;top:100%;left:var(--sb-inset);right:var(--sb-inset);bottom:auto;max-height:min(50vh,320px);transform-origin:top center}.rc-dev-menu--mobile .rc-dev-offline[data-v-4dd165fb]{min-height:44px;padding:12px 14px}.menu-pop-enter-active[data-v-4dd165fb]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-4dd165fb]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-4dd165fb],.menu-pop-leave-to[data-v-4dd165fb]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, 2px))}.rc-dev-state[data-v-4dd165fb]{display:flex;align-items:center;justify-content:center;padding:var(--space-3)}.rc-dev-failed[data-v-4dd165fb]{color:var(--color-text-muted);font-size:var(--text-sm)}.rc-dev-caption[data-v-4dd165fb]{padding:var(--space-2) var(--menu-item-padding-inline) 2px;color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:var(--leading-tight)}.rc-dev-item-name[data-v-4dd165fb]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rc-dev-item-status[data-v-4dd165fb]{display:flex;align-items:center;gap:6px;flex:none;color:var(--color-text-muted)}.rc-dev-item-check[data-v-4dd165fb]{display:flex;align-items:center;justify-content:center;width:var(--p-ic-md);height:var(--p-ic-md);flex:none}.rc-dev-offline[data-v-4dd165fb]{padding:var(--menu-item-padding-block) var(--menu-item-padding-inline);border-radius:var(--radius-menu-item);color:var(--color-text-muted);font-size:var(--text-sm);font-weight:var(--weight-option-label);line-height:var(--leading-tight)}.rc-dev-offline.is-current[data-v-4dd165fb]{background:var(--color-hover);color:var(--color-text)}.rc-dev-offline-row[data-v-4dd165fb]{display:flex;align-items:center;gap:7px}.rc-dev-offline-row svg[data-v-4dd165fb]{display:block;width:var(--p-ic-md);height:var(--p-ic-md);flex:none}.user-menu-trigger[data-v-7472da32]{display:flex;align-items:center;gap:var(--sb-gap);width:100%;min-width:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);cursor:pointer;text-align:left}.user-menu-trigger[data-v-7472da32]:hover,.user-menu-trigger[aria-expanded=true][data-v-7472da32]{background:var(--sb-hover)}.user-menu-trigger[data-v-7472da32]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}html.macos-desktop .user-menu-trigger[data-v-7472da32]{border-bottom-left-radius:var(--radius-window-chip)}.user-menu-trigger svg[data-v-7472da32]{flex:none}.user-menu-avatar[data-v-7472da32]{display:flex;align-items:center;justify-content:center;width:24px;height:24px;flex:none;border-radius:var(--radius-full);background:var(--color-surface-sunken);color:var(--color-text-muted);overflow:hidden}.user-menu-avatar img[data-v-7472da32]{width:100%;height:100%;object-fit:cover}.user-menu-name[data-v-7472da32]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-menu[data-v-7472da32]{position:fixed;top:0;left:0;z-index:var(--z-dropdown);max-height:calc(100vh - 16px);overflow-y:auto;overflow-x:hidden;user-select:none}.user-submenu[data-v-7472da32]{position:fixed;top:0;left:0;z-index:var(--z-dropdown);width:max-content;max-height:calc(100vh - 16px);overflow-y:auto;overflow-x:hidden;user-select:none}.menu-pop-enter-active[data-v-7472da32]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-7472da32]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-7472da32],.menu-pop-leave-to[data-v-7472da32]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, 2px))}.user-menu-usage[data-v-7472da32]{display:flex;flex-direction:column;gap:calc(var(--menu-item-padding-block) * 2);padding:var(--menu-item-padding-block) var(--menu-item-padding-inline)}.user-menu-usage-state[data-v-7472da32]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-1) 0;color:var(--color-text-muted);font-size:var(--text-sm)}.user-menu-usage-error[data-v-7472da32]{flex:1;min-width:0}.user-menu-usage-empty[data-v-7472da32]{color:var(--color-text-faint)}.user-menu-usage-row[data-v-7472da32]{display:grid;grid-template-columns:auto 1fr;column-gap:var(--space-3);row-gap:var(--space-05)}.user-menu-usage-label[data-v-7472da32]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);line-height:var(--leading-tight);color:var(--color-text)}.user-menu-usage-hint[data-v-7472da32]{grid-column:1 / -1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-text-faint)}.user-menu-usage-value[data-v-7472da32]{justify-self:end;font-size:var(--text-sm);line-height:var(--leading-tight);font-weight:var(--weight-medium);color:var(--color-text);font-variant-numeric:tabular-nums;white-space:nowrap}.user-menu-usage-value.sev-warn[data-v-7472da32]{color:var(--color-warning)}.user-menu-usage-value.sev-danger[data-v-7472da32]{color:var(--color-danger)}.user-menu-item-label[data-v-7472da32]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-menu-login-label[data-v-7472da32]{color:var(--color-accent)}.user-menu-row-value[data-v-7472da32]{flex:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);color:var(--color-text-faint)}.emoji-picker[data-v-b0dbbae4]{--ep-cell: 26px}.ep-search[data-v-b0dbbae4]{display:flex;align-items:center;gap:var(--space-2);margin:var(--space-1);padding:0 var(--space-2);border-radius:var(--radius-sm);color:var(--color-text-faint)}.ep-search[data-v-b0dbbae4]:hover,.ep-search[data-v-b0dbbae4]:focus-within{background:var(--color-surface-sunken)}.ep-input[data-v-b0dbbae4]{flex:1;min-width:0;height:calc(var(--ep-cell) + 2px);font-size:var(--text-sm);color:var(--color-text);background:transparent;border:none;outline:none}.ep-input[data-v-b0dbbae4]::placeholder{color:var(--color-text-faint)}.ep-scroll[data-v-b0dbbae4]{max-height:calc(var(--ep-cell) * 10 + var(--space-1));overflow-y:auto;padding:0 var(--space-1)}.ep-label[data-v-b0dbbae4]{padding:var(--space-1) var(--space-2);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--color-text-faint);user-select:none}.ep-grid[data-v-b0dbbae4]{display:grid;grid-template-columns:repeat(8,var(--ep-cell));gap:var(--space-1);padding-bottom:var(--space-1)}.ep-e[data-v-b0dbbae4]{height:var(--ep-cell);display:grid;place-items:center;padding:0;font-size:var(--text-lg);background:transparent;border:none;border-radius:var(--radius-xs);cursor:pointer}.ep-e[data-v-b0dbbae4]:hover{background:var(--color-hover)}.ep-e[data-v-b0dbbae4]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ep-e.sel[data-v-b0dbbae4]{background:var(--color-accent-soft)}.ep-empty[data-v-b0dbbae4]{padding:var(--space-3) var(--space-2);font-size:var(--text-xs);color:var(--color-text-faint);text-align:center;user-select:none}.se[data-v-9068e4e1]{--se-pad-x: var(--space-2);display:block;margin:0;padding:8px var(--se-pad-x);border-radius:var(--radius-sm);font-family:var(--font-ui);color:var(--color-text);cursor:pointer;position:relative}.se[data-v-9068e4e1]:hover{background:var(--sb-hover, var(--color-hover));color:var(--color-text)}.se.on[data-v-9068e4e1]{background:var(--sb-selected, var(--color-selected));color:var(--color-text)}.row[data-v-9068e4e1]{display:flex;align-items:center;gap:var(--sb-gap, 6px);min-width:0}.left[data-v-9068e4e1]{display:flex;align-items:center;flex:1;min-width:0}.lead[data-v-9068e4e1]{width:var(--sb-gutter, 16px);flex:none;display:inline-flex;align-items:center;justify-content:center}.unread-dot[data-v-9068e4e1]{width:7px;height:7px;border-radius:var(--radius-full);background:var(--color-accent)}.ha .complete-btn[data-v-9068e4e1]:hover{color:var(--color-success)}.t[data-v-9068e4e1]{--sb-fade: 0px;--sb-fade-len: 16px;color:inherit;font-size:var(--ui-font-size-sm);font-weight:450;line-height:var(--leading-tight);user-select:none;flex:1;min-width:0;overflow:hidden;text-overflow:clip;white-space:nowrap;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)));mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)))}.se:hover .t[data-v-9068e4e1]{--sb-fade: 34px;--sb-fade-len: 26px}.se:has(.ui-badge):hover .t[data-v-9068e4e1]{--sb-fade: 0px;--sb-fade-len: 16px}.t .emoji[data-v-9068e4e1]{padding:0;background:transparent;border:none;cursor:pointer}.t .emoji[data-v-9068e4e1]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.sub[data-v-9068e4e1]{display:flex;align-items:center;gap:var(--space-1);margin:var(--space-1) 0 0;color:var(--color-text-faint);font-size:var(--text-xs);line-height:var(--leading-tight);user-select:none}.sub-icon[data-v-9068e4e1]{flex:none;color:var(--color-text-muted)}.pr[data-v-9068e4e1]{display:inline-flex;align-items:center;gap:var(--space-05);flex:none;padding:1px var(--space-1);border:.5px solid var(--color-line);border-radius:var(--radius-sm);background:var(--color-surface-sunken);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-2xs);font-weight:var(--weight-medium);line-height:1;cursor:pointer}.pr[data-v-9068e4e1]:hover{border-color:var(--color-line-strong)}.pr[data-v-9068e4e1]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.pr--open[data-v-9068e4e1],.pr--open[data-v-9068e4e1]:hover{background:var(--color-success-soft);border-color:var(--color-success-bd);color:var(--color-success)}.pr--merged[data-v-9068e4e1],.pr--merged[data-v-9068e4e1]:hover{background:var(--color-done-soft);border-color:var(--color-done-bd);color:var(--color-done)}.sub-text[data-v-9068e4e1]{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent);mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent)}.ts[data-v-9068e4e1]{color:var(--color-text-faint);font-size:var(--text-xs);font-family:var(--font-ui);font-weight:475;line-height:var(--leading-tight);font-variant-numeric:tabular-nums;text-align:right}.act[data-v-9068e4e1]{position:relative;flex:none;align-self:stretch;display:inline-flex;align-items:center;justify-content:flex-end;gap:var(--sb-gap, 6px);min-width:var(--icon-button-sm)}.act .ha[data-v-9068e4e1]{position:absolute;top:0;bottom:0;right:calc(var(--sb-action-inset, 3px) - var(--se-pad-x));display:inline-flex;align-items:center;gap:2px;opacity:0;visibility:hidden;border-radius:var(--radius-sm);transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.se:hover .ha[data-v-9068e4e1]{opacity:1;visibility:visible;transition:opacity var(--duration-fast) var(--ease-out)}.act .ts[data-v-9068e4e1]{transition:opacity var(--duration-fast) var(--ease-out)}.se:hover .act .ts[data-v-9068e4e1]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.act .st[data-v-9068e4e1]{display:inline-flex;align-items:center;transition:opacity var(--duration-fast) var(--ease-out)}.se:hover .act .st[data-v-9068e4e1]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.act .ui-badge[data-v-9068e4e1]{transition:opacity var(--duration-fast) var(--ease-out)}.se:hover .act .ui-badge[data-v-9068e4e1]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.menu[data-v-9068e4e1],.picker[data-v-9068e4e1]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.menu-pop-enter-active[data-v-9068e4e1]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-9068e4e1]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-9068e4e1],.menu-pop-leave-to[data-v-9068e4e1]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}.menu-time[data-v-9068e4e1]{padding:var(--space-1) var(--space-2);color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-medium);cursor:default;user-select:text}.rename-wrap[data-v-9068e4e1]{position:relative;display:flex;align-items:center;flex:1;min-width:0;background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs)}.rename-input[data-v-9068e4e1]{flex:1;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text);background:transparent;border:none;padding:1px 4px;outline:none;min-width:0}.rename-wrap.generating .rename-input[data-v-9068e4e1]{visibility:hidden}.gen-dots[data-v-9068e4e1]{position:absolute;left:6px;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;gap:3px;pointer-events:none}.gen-dots i[data-v-9068e4e1]{width:3px;height:3px;border-radius:var(--radius-full, 50%);background:var(--color-accent);animation:gen-title-dot-9068e4e1 .9s var(--ease-out) infinite}.gen-dots i[data-v-9068e4e1]:nth-child(2){animation-delay:.15s}.gen-dots i[data-v-9068e4e1]:nth-child(3){animation-delay:.3s}@keyframes gen-title-dot-9068e4e1{0%,60%,to{opacity:.3;transform:translate(0)}30%{opacity:1;transform:translate(2px)}}.gen-title-btn[data-v-9068e4e1]{flex:none;margin-right:1px;color:var(--color-accent)}.gen-title-btn[data-v-9068e4e1]:hover:not(:disabled){color:var(--color-accent-hover);background:transparent}.sessions .se[data-v-9068e4e1]{margin:0;border-radius:var(--radius-sm);--se-pad-x: calc(var(--sb-pad-x, 20px) - var(--sb-inset, 12px));padding:8px var(--se-pad-x)}.sessions .se.flat+.se.flat[data-v-9068e4e1]{margin-top:var(--space-05)}.sessions .se .rename-input[data-v-9068e4e1]{border-radius:var(--radius-sm);font-family:var(--sans)}.group.dragging[data-v-8a2d5457]{opacity:.45}.group.pinned-drag-active[data-v-8a2d5457],.group.pinned-drop-hover[data-v-8a2d5457]{border-radius:var(--radius-sm)}.group.pinned-drag-active[data-v-8a2d5457]{box-shadow:inset 0 0 0 1px var(--color-accent)}.group.pinned-drop-hover[data-v-8a2d5457]{box-shadow:inset 0 0 0 2px var(--color-accent)}.group.pinned-drop-blocked[data-v-8a2d5457],.group.pinned-drop-blocked[data-v-8a2d5457] *{cursor:no-drop}.se-locate-flash[data-v-8a2d5457]{isolation:isolate}.se-locate-flash[data-v-8a2d5457]:before{content:"";position:absolute;inset:0;z-index:-1;border-radius:var(--radius-sm);background:var(--color-accent-soft);pointer-events:none;animation:se-locate-fade-8a2d5457 var(--duration-flash) var(--ease-out) forwards}@keyframes se-locate-fade-8a2d5457{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.se-locate-flash[data-v-8a2d5457]:before{animation:none}}.group-sessions[data-v-8a2d5457]{height:auto;overflow:hidden;transition:height var(--duration-base) var(--ease-out)}.group-sessions.collapsed[data-v-8a2d5457]{height:0}.gh[data-v-8a2d5457]{display:flex;flex-direction:column;margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border-radius:var(--radius-sm);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text);user-select:none;position:relative;cursor:grab}.gh[data-v-8a2d5457]:active{cursor:grabbing}.gh[data-v-8a2d5457]:hover{background:var(--sb-hover, var(--color-hover))}.gh.on[data-v-8a2d5457]{background:var(--sb-selected, var(--color-selected))}.gh-top[data-v-8a2d5457]{position:relative;display:flex;align-items:center;gap:var(--sb-gap)}.gh-folder[data-v-8a2d5457]{flex:none;color:var(--color-text-muted)}.gh-name[data-v-8a2d5457]{font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);color:var(--color-text-muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.gh-actions[data-v-8a2d5457]{position:absolute;right:calc(var(--sb-action-inset) - (var(--sb-pad-x) - var(--sb-inset)));top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--space-1);padding-left:var(--space-1);border-radius:var(--radius-sm);isolation:isolate;opacity:0;pointer-events:none}.gh-name[data-v-8a2d5457]{--sb-fade: 0px;--sb-fade-len: 16px;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)));mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)))}.gh:hover .gh-name[data-v-8a2d5457],.gh:focus-within .gh-name[data-v-8a2d5457],.gh:has(.gh-actions.open) .gh-name[data-v-8a2d5457]{--sb-fade: 64px;--sb-fade-len: 26px}.gh-actions[data-v-8a2d5457]>*{position:relative;z-index:1}.gh:hover .gh-actions[data-v-8a2d5457],.gh:focus-within .gh-actions[data-v-8a2d5457],.gh-actions.open[data-v-8a2d5457]{opacity:1;pointer-events:auto}.gh-more.open[data-v-8a2d5457]{color:var(--color-text);background:var(--color-line)}.group-empty[data-v-8a2d5457]{padding:var(--space-1) var(--space-2) var(--space-1) calc(var(--sb-pad-x) - var(--sb-inset) + var(--sb-gutter) + var(--sb-gap));font-size:var(--text-xs);color:var(--color-text-faint);font-family:var(--font-ui);user-select:none}.show-more-row[data-v-8a2d5457]{display:flex;align-items:center;padding-left:calc(var(--sb-gutter) + var(--sb-gap))}.show-more[data-v-8a2d5457]{display:flex;align-items:center;gap:var(--sb-gap);margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));min-width:0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);text-align:left;cursor:pointer}.show-more[data-v-8a2d5457]:hover{background:var(--sb-hover, var(--color-hover))}.show-more[data-v-8a2d5457]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.show-more-sep[data-v-8a2d5457]{margin:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);user-select:none}.show-more-label[data-v-8a2d5457]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gh-rename[data-v-8a2d5457]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-regular);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs);padding:2px 5px;outline:none}.gh-rename[data-v-8a2d5457]{border-radius:var(--radius-sm);font-family:var(--sans)}.gh-add[data-v-8a2d5457]{color:var(--faint)}.gh-add[data-v-8a2d5457]:hover{color:var(--dim)}.pinned-label[data-v-0c30d45b]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 var(--sb-action-inset) var(--space-1) var(--space-2);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--faint);user-select:none}.pinned-title[data-v-0c30d45b]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pinned-toggle[data-v-0c30d45b]{color:var(--faint);opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.pinned-label:hover .pinned-toggle[data-v-0c30d45b],.pinned-label:focus-within .pinned-toggle[data-v-0c30d45b],.pinned-toggle--on[data-v-0c30d45b]{opacity:1}.pinned-toggle[data-v-0c30d45b]:hover{color:var(--dim)}.pinned-toggle svg[data-v-0c30d45b]{width:13px;height:13px}.se-locate-flash[data-v-0c30d45b]{isolation:isolate}.se-locate-flash[data-v-0c30d45b]:before{content:"";position:absolute;inset:0;z-index:-1;border-radius:var(--radius-sm);background:var(--color-accent-soft);pointer-events:none;animation:se-locate-fade-0c30d45b var(--duration-flash) var(--ease-out) forwards}@keyframes se-locate-fade-0c30d45b{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.se-locate-flash[data-v-0c30d45b]:before{animation:none}}.pinned-rows[data-v-0c30d45b]{max-height:40vh;overflow-y:auto;padding:0 var(--sb-inset);--overlay-scrollbar-thumb-min: var(--space-6);scrollbar-width:none}.pinned-rows[data-v-0c30d45b]::-webkit-scrollbar{display:none}.pinned-thumb[data-v-0c30d45b]{position:absolute;right:0;width:var(--space-1);border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-text) 12%,transparent);opacity:0;pointer-events:none;transition:opacity var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out);z-index:var(--z-raised);touch-action:none}.pinned-thumb.visible[data-v-0c30d45b]{opacity:1;pointer-events:auto}.pinned-thumb.visible[data-v-0c30d45b]:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.pinned-thumb[data-v-0c30d45b]:before{content:"";position:absolute;top:0;bottom:0;left:calc(-1 * var(--space-2));right:0}.pinned-rows-wrap[data-v-0c30d45b]{position:relative;margin:0 calc(var(--sb-inset) * -1);--pinned-seam-down: linear-gradient(to bottom, color-mix(in srgb, var(--color-text) 1.5%, transparent), transparent 35%), linear-gradient(to bottom, color-mix(in srgb, var(--color-text) 1%, transparent), transparent 65%), linear-gradient(to bottom, color-mix(in srgb, var(--color-text) .75%, transparent), transparent);--pinned-seam-up: linear-gradient(to top, color-mix(in srgb, var(--color-text) 1.5%, transparent), transparent 35%), linear-gradient(to top, color-mix(in srgb, var(--color-text) 1%, transparent), transparent 65%), linear-gradient(to top, color-mix(in srgb, var(--color-text) .75%, transparent), transparent)}.pinned-seam[data-v-0c30d45b]{position:absolute;left:0;right:0;height:var(--p-sidebar-seam-h);pointer-events:none;opacity:0;z-index:var(--z-raised);transition:opacity var(--duration-slow) var(--ease-out)}.pinned-seam--top[data-v-0c30d45b]{top:0;border-top:var(--p-hairline) solid var(--line);background:var(--pinned-seam-down)}.pinned-seam--bottom[data-v-0c30d45b]{bottom:0;border-bottom:var(--p-hairline) solid var(--line);background:var(--pinned-seam-up)}.pinned-rows-wrap.scrolled .pinned-seam--top[data-v-0c30d45b],.pinned-rows-wrap.more-below .pinned-seam--bottom[data-v-0c30d45b]{opacity:1}.pinned-resize[data-v-0c30d45b]{height:var(--space-1);position:relative;background:transparent;touch-action:none;margin:calc(var(--space-05) * -1) calc(var(--sb-inset) * -1);z-index:var(--z-dropdown)}.pinned-resize-bar[data-v-0c30d45b]{position:absolute;top:50%;left:0;right:0;height:var(--space-05);translate:0 -50%;background:transparent;transition:background var(--duration-fast) var(--ease-out)}.pinned-resize:hover .pinned-resize-bar[data-v-0c30d45b]{background:var(--color-selected)}.pinned-resize.dragging .pinned-resize-bar[data-v-0c30d45b]{background:var(--color-line-strong)}.pinned-resize[data-v-0c30d45b]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.pin-row.dragging[data-v-0c30d45b]{opacity:.45}.pinned.drop-active[data-v-0c30d45b]{border-radius:var(--radius-sm);box-shadow:inset 0 0 0 1px var(--color-accent)}.side[data-v-e9b3eef9]{background:var(--color-sidebar-bg);display:flex;flex-direction:row;justify-content:flex-end;overflow:hidden;min-width:0;height:100%;transition:width .28s cubic-bezier(.4,0,.2,1),visibility .28s;--sb-inset: var(--space-2);--sb-pad-x: var(--space-4);--sb-gutter: 16px;--sb-gap: var(--space-2);--sb-action-inset: calc((max(var(--ui-font-size-sm) * var(--leading-tight), var(--p-ic-md)) + 2 * var(--space-2) - var(--icon-button-sm)) / 2);--sb-hover: var(--color-hover);--sb-selected: color-mix(in srgb, var(--color-selected) 75%, transparent)}.side.no-anim[data-v-e9b3eef9]{transition:none}.side.collapsed[data-v-e9b3eef9]{visibility:hidden}.col[data-v-e9b3eef9]{flex:none;min-width:0;display:flex;flex-direction:column;min-height:0;width:100%;box-sizing:border-box;border-right:.5px solid var(--line);container-type:inline-size;container-name:sidebar-col;position:relative}.ch[data-v-e9b3eef9]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:var(--space-3);min-height:calc(26px + 2 * var(--space-3));width:100%;box-sizing:border-box}.side.macos-desktop .ch[data-v-e9b3eef9]{padding-left:80px;-webkit-app-region:drag}.side.macos-desktop .ch-brand[data-v-e9b3eef9]{display:none}.ch-logo[data-v-e9b3eef9]{height:22px;width:32px;flex:none;display:block;cursor:pointer;user-select:none;touch-action:none;transition:transform .18s ease}.ch-logo[data-v-e9b3eef9]:hover{transform:scale(1.08)}.ch-brand[data-v-e9b3eef9]{display:flex;align-items:center;gap:8px;min-width:0;flex:1;user-select:none;touch-action:none}.ch-tail[data-v-e9b3eef9]{display:flex;align-items:center;gap:var(--space-2);flex:none;min-width:0;margin-left:auto}.ch-name[data-v-e9b3eef9]{font-size:var(--ui-font-size);font-weight:500;line-height:22px;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@container sidebar-col (max-width: 250px){.ch-name[data-v-e9b3eef9]{display:none}}.sidebar-actions[data-v-e9b3eef9]{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:0 var(--space-2);padding:0 var(--sb-inset) var(--space-1);position:relative;z-index:1;background:var(--color-sidebar-bg)}.sessions-head[data-v-e9b3eef9]{position:relative;z-index:1;padding:var(--space-3) var(--sb-inset) 0;border-bottom:.5px solid transparent;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.sessions-head[data-v-e9b3eef9]:after,.side-footer[data-v-e9b3eef9]:before{content:"";position:absolute;left:0;right:0;height:var(--p-sidebar-seam-h);pointer-events:none;opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.sessions-head[data-v-e9b3eef9]:after{top:100%;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) .75%,transparent),transparent);transition-duration:var(--duration-slow)}.sessions-head--scrolled[data-v-e9b3eef9]{border-bottom-color:var(--line)}.sessions-head--scrolled[data-v-e9b3eef9]:after{opacity:1}.btn-new-chat[data-v-e9b3eef9]{grid-column:1 / -1;display:flex;align-items:center;gap:var(--sb-gap);width:100%;min-width:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);cursor:pointer;text-align:left}.sidebar-actions--has-workspace-action .btn-new-chat[data-v-e9b3eef9]{grid-column:1}.btn-new-chat[data-v-e9b3eef9]:hover{background:var(--sb-hover)}.btn-new-chat[data-v-e9b3eef9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.btn-new-chat svg[data-v-e9b3eef9]{flex:none}.btn-new-chat span[data-v-e9b3eef9]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-new-chat[data-v-e9b3eef9] .ui-kbd{margin-left:auto}.btn-new-chat[data-v-e9b3eef9] .ui-kbd,.search[data-v-e9b3eef9] .ui-kbd{opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.btn-new-chat[data-v-e9b3eef9]:hover .ui-kbd,.btn-new-chat[data-v-e9b3eef9]:focus-visible .ui-kbd,.search[data-v-e9b3eef9]:hover .ui-kbd,.search[data-v-e9b3eef9]:focus-visible .ui-kbd{opacity:1}.search[data-v-e9b3eef9]{grid-column:1 / -1;display:flex;align-items:center;gap:var(--sb-gap);width:100%;margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font:inherit;text-align:left;cursor:pointer}.search[data-v-e9b3eef9]:hover{background:var(--sb-hover)}.search[data-v-e9b3eef9]:focus-visible{background:var(--sb-hover);color:var(--color-text);outline:2px solid var(--color-accent-bd);outline-offset:-2px}.search-icon[data-v-e9b3eef9]{flex:none;transform:translateY(-.5px)}.search-input[data-v-e9b3eef9]{flex:1;min-width:0;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.status-tabs[data-v-e9b3eef9]{padding:var(--space-2) var(--sb-inset) 0}.status-seg[data-v-e9b3eef9]{width:100%;display:flex}.status-seg[data-v-e9b3eef9] .ui-seg__item{flex:1;min-width:0;justify-content:center;padding:0 var(--space-1);overflow:hidden}.ws-dir[data-v-e9b3eef9]{display:block;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border-radius:var(--radius-sm);cursor:pointer;position:relative;user-select:none}.ws-dir[data-v-e9b3eef9]:hover{background:var(--sb-hover, var(--color-hover))}.ws-dir.on[data-v-e9b3eef9]{background:var(--sb-selected, var(--color-selected))}.ws-dir+.ws-dir[data-v-e9b3eef9]{margin-top:var(--space-05)}.ws-dir-row[data-v-e9b3eef9]{display:flex;align-items:center;gap:var(--sb-gap);min-width:0}.ws-dir-icon[data-v-e9b3eef9]{flex:none;color:var(--color-text-muted)}.ws-dir-name[data-v-e9b3eef9]{flex:1;min-width:0;font-size:var(--ui-font-size-sm);font-weight:var(--weight-caption);line-height:var(--leading-tight);color:var(--color-text);overflow:hidden;white-space:nowrap;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent);mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent)}.ws-dir-act[data-v-e9b3eef9]{position:absolute;top:0;bottom:0;right:var(--sb-action-inset);display:inline-flex;align-items:center;opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.ws-dir-rename[data-v-e9b3eef9]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-caption);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-sm);padding:2px 5px;outline:none}.ws-dir:hover .ws-dir-act[data-v-e9b3eef9],.ws-dir:focus-within .ws-dir-act[data-v-e9b3eef9]{opacity:1;visibility:visible;transition:opacity var(--duration-fast) var(--ease-out)}.ws-dir-sub[data-v-e9b3eef9]{margin:var(--space-1) 0 0;color:var(--color-text-faint);font-size:var(--text-xs);line-height:var(--leading-tight);overflow:hidden;white-space:nowrap;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent);mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent)}.ws-dir:hover .ws-dir-name[data-v-e9b3eef9],.ws-dir:focus-within .ws-dir-name[data-v-e9b3eef9],.ws-dir:hover .ws-dir-sub[data-v-e9b3eef9],.ws-dir:focus-within .ws-dir-sub[data-v-e9b3eef9]{margin-right:calc(var(--icon-button-sm) + var(--space-2))}.done-gh[data-v-e9b3eef9]{display:flex;align-items:center;gap:var(--sb-gap);padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border-radius:var(--radius-sm);font-family:var(--font-ui);color:var(--color-text);user-select:none;position:relative;cursor:pointer}.done-gh[data-v-e9b3eef9]:hover{background:var(--sb-hover, var(--color-hover))}.done-gh-folder[data-v-e9b3eef9]{flex:none;color:var(--color-text-muted)}.done-gh-name[data-v-e9b3eef9]{flex:1;min-width:0;font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);color:var(--color-text-muted);overflow:hidden;white-space:nowrap;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent);mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent)}.done-gh-count[data-v-e9b3eef9]{flex:none;color:var(--color-text-faint);font-size:var(--text-xs);font-variant-numeric:tabular-nums}.done-gh-act[data-v-e9b3eef9]{position:absolute;top:0;bottom:0;right:var(--sb-action-inset);display:inline-flex;align-items:center;opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.done-gh:hover .done-gh-act[data-v-e9b3eef9],.done-gh:focus-within .done-gh-act[data-v-e9b3eef9]{opacity:1;visibility:visible;transition:opacity var(--duration-fast) var(--ease-out)}.done-gh:hover .done-gh-count[data-v-e9b3eef9],.done-gh:focus-within .done-gh-count[data-v-e9b3eef9]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.sessions[data-v-e9b3eef9]{flex:1;overflow-y:auto;padding:0 var(--sb-inset) var(--space-3);min-height:0;--overlay-scrollbar-thumb-min: var(--space-6);scrollbar-width:none}.sessions[data-v-e9b3eef9]::-webkit-scrollbar{display:none}.sessions-thumb[data-v-e9b3eef9]{position:absolute;right:0;width:var(--space-1);border-radius:var(--radius-full);background:color-mix(in srgb,var(--color-text) 12%,transparent);opacity:0;pointer-events:none;transition:opacity var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out);z-index:var(--z-raised);touch-action:none}.sessions-thumb.visible[data-v-e9b3eef9]{opacity:1;pointer-events:auto}.sessions-thumb.visible[data-v-e9b3eef9]:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.sessions-thumb[data-v-e9b3eef9]:before{content:"";position:absolute;top:0;bottom:0;left:calc(-1 * var(--space-2));right:0}.side-footer[data-v-e9b3eef9]{flex:none;position:relative;z-index:1;padding:var(--space-2) var(--sb-inset);border-top:.5px solid var(--line);background:var(--color-sidebar-bg)}.side-footer[data-v-e9b3eef9]:before{bottom:100%;background:linear-gradient(to top,color-mix(in srgb,var(--color-text) 1.5%,transparent),transparent 35%),linear-gradient(to top,color-mix(in srgb,var(--color-text) 1%,transparent),transparent 65%),linear-gradient(to top,color-mix(in srgb,var(--color-text) .75%,transparent),transparent);transition-duration:var(--duration-slow)}.side-footer--shadowed[data-v-e9b3eef9]:before{opacity:1}.side-section-label[data-v-e9b3eef9]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 var(--sb-action-inset) var(--space-1) var(--space-2);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--faint);user-select:none}.side-section-title[data-v-e9b3eef9]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sessions-head .pinned+.side-section-label[data-v-e9b3eef9]{margin-top:var(--space-1)}.side-section-toggle[data-v-e9b3eef9]{color:var(--faint)}.side-section-toggle[data-v-e9b3eef9]:hover{color:var(--dim)}.side-section-toggle svg[data-v-e9b3eef9]{width:13px;height:13px}.side-section-actions[data-v-e9b3eef9]{display:flex;align-items:center;gap:2px}.ws-drop-target.drop-before[data-v-e9b3eef9]{box-shadow:inset 0 2px 0 var(--color-accent)}.ws-drop-target.drop-after[data-v-e9b3eef9]{box-shadow:inset 0 -2px 0 var(--color-accent)}.ws-drop-target.ws-locate-flash[data-v-e9b3eef9] .gh{isolation:isolate}.ws-drop-target.ws-locate-flash[data-v-e9b3eef9] .gh:before{content:"";position:absolute;inset:0;z-index:-1;border-radius:var(--radius-sm);background:var(--color-accent-soft);pointer-events:none;animation:ws-locate-fade-e9b3eef9 var(--duration-flash) var(--ease-out) forwards}@keyframes ws-locate-fade-e9b3eef9{0%{opacity:1}to{opacity:0}}@media(prefers-reduced-motion:reduce){.ws-drop-target.ws-locate-flash[data-v-e9b3eef9] .gh:before{animation:none}}.sessions.pinned-drag-active[data-v-e9b3eef9]{box-shadow:inset 0 0 0 1px var(--color-accent)}.sessions.flat-pinned-drop-hover[data-v-e9b3eef9]{box-shadow:inset 0 0 0 2px var(--color-accent)}.show-more-row[data-v-e9b3eef9]{display:flex;align-items:center;justify-content:center}.show-more[data-v-e9b3eef9]{display:flex;align-items:center;justify-content:center;gap:var(--space-1);margin:0;padding:6px var(--space-3);min-width:0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);cursor:pointer}.show-more[data-v-e9b3eef9]:hover{background:var(--sb-hover, var(--color-hover))}.show-more[data-v-e9b3eef9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.show-more-label[data-v-e9b3eef9]{flex:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folder-drop-overlay[data-v-e9b3eef9]{position:absolute;inset:0;z-index:1;display:flex;align-items:center;justify-content:center;padding:var(--space-3);box-sizing:border-box;background:color-mix(in srgb,var(--color-sidebar-bg) 72%,transparent);pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--duration-base) ease,visibility var(--duration-base)}.folder-drop-overlay.show[data-v-e9b3eef9]{opacity:1;visibility:visible}.folder-drop-card[data-v-e9b3eef9]{display:flex;align-items:center;gap:var(--space-3);max-width:100%;box-sizing:border-box;padding:var(--space-4);border-radius:var(--radius-lg);border:.5px dashed var(--color-accent);background:var(--color-bg);color:var(--color-accent);font-size:var(--ui-font-size-lg);font-weight:var(--weight-medium);box-shadow:var(--shadow-md)}.folder-drop-card svg[data-v-e9b3eef9]{flex:none}.folder-drop-card span[data-v-e9b3eef9]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.empty[data-v-e9b3eef9]{padding:var(--space-6) var(--space-3);text-align:center;color:var(--faint);font-size:calc(var(--ui-font-size) - 3px);line-height:1.6}.ws-menu[data-v-e9b3eef9],.gh-menu[data-v-e9b3eef9],.view-menu[data-v-e9b3eef9]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.view-menu-label[data-v-e9b3eef9]{padding:var(--space-1) var(--space-2) var(--space-05);font-size:var(--text-xs);color:var(--faint);user-select:none}.view-menu-check[data-v-e9b3eef9]{margin-left:auto;display:inline-flex}.menu-pop-enter-active[data-v-e9b3eef9]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-e9b3eef9]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-e9b3eef9],.menu-pop-leave-to[data-v-e9b3eef9]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}[data-v-e9b3eef9] .workspace-rename-item{font-size:var(--text-xs);font-weight:var(--weight-option-label)}.section-menu-check[data-v-e9b3eef9]{display:inline-flex;flex:none;width:14px}.rh[data-v-1c6dfdc5]{width:4px;flex:none;position:relative;align-self:stretch;background:transparent;touch-action:none;margin:0 -2px;z-index:var(--z-dropdown)}.rh-bar[data-v-1c6dfdc5]{position:absolute;inset:0 1px;background:transparent;transition:background .12s}.rh:hover .rh-bar[data-v-1c6dfdc5]{background:var(--color-selected)}.rh.dragging .rh-bar[data-v-1c6dfdc5]{background:var(--color-line-strong)}.op[data-v-ab413c67]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);background:var(--color-well);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);white-space:pre-wrap;word-break:break-word;max-height:12lh;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable}.op-empty[data-v-ab413c67]{color:var(--color-text-faint);font-style:italic}.agent-card[data-v-ab8f0011]{margin:var(--space-1) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);overflow:hidden;transition:border-color var(--duration-base) var(--ease-out)}.agent-card[data-v-ab8f0011]:hover{border-color:var(--color-line-strong)}.agent-card.err[data-v-ab8f0011]{border-color:color-mix(in srgb,var(--color-danger) 45%,var(--bg))}.head[data-v-ab8f0011]{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border:none;background:transparent;color:var(--color-text);font-family:var(--font-ui);text-align:left;cursor:pointer}.head[data-v-ab8f0011]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.head[data-v-ab8f0011]:disabled{cursor:default}.lead[data-v-ab8f0011]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-md);background:var(--color-surface-sunken);color:var(--color-text-muted);flex:none}.main[data-v-ab8f0011]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.task[data-v-ab8f0011]{font-size:var(--ui-font-size);line-height:var(--leading-caption);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.type[data-v-ab8f0011]{font-size:var(--text-xs);line-height:var(--leading-caption);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tail[data-v-ab8f0011]{display:flex;align-items:center;gap:var(--space-2);flex:none}.st[data-v-ab8f0011]{display:inline-flex;align-items:center}.st.ok[data-v-ab8f0011]{color:var(--color-success)}.st.error[data-v-ab8f0011]{color:var(--color-danger)}.go[data-v-ab8f0011]{color:var(--color-text-faint);transition:color var(--duration-base) var(--ease-out)}.agent-card:hover .head:not(:disabled) .go[data-v-ab8f0011]{color:var(--color-text)}.go.car[data-v-ab8f0011]{transition:color var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.go.car.open[data-v-ab8f0011]{transform:rotate(90deg)}.saved-result[data-v-ab8f0011]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) var(--space-3);border:none;border-top:.5px solid var(--color-line);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);text-align:left;cursor:pointer}.saved-result[data-v-ab8f0011]:hover{color:var(--color-text-muted)}.saved-result[data-v-ab8f0011]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.saved-result__chevron[data-v-ab8f0011]{transition:transform var(--duration-base) var(--ease-out)}.saved-result__chevron.open[data-v-ab8f0011]{transform:rotate(90deg)}.result[data-v-ab8f0011]{padding:var(--space-2) var(--space-3)}.result--legacy[data-v-ab8f0011]{border-top:.5px solid var(--color-line)}.tl-head[data-v-6e9ab5f9]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) 0;border-radius:var(--radius-sm);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left}.tl-head.clickable[data-v-6e9ab5f9]{cursor:pointer;user-select:none}.tl-ic[data-v-6e9ab5f9]{display:inline-flex;align-items:center;justify-content:flex-start;flex:none;color:var(--color-text-faint)}.tl-main[data-v-6e9ab5f9]{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-1)}.tl-tail[data-v-6e9ab5f9]{margin-left:auto;display:flex;align-items:center;gap:var(--space-1);flex:none}.tl-status[data-v-6e9ab5f9]{display:inline-flex;align-items:center;flex:none}.tl-status.ok[data-v-6e9ab5f9]{color:var(--color-success)}.tl-status.error[data-v-6e9ab5f9]{color:var(--color-danger)}.tl-car[data-v-6e9ab5f9]{display:inline-flex;align-items:center;justify-content:center;align-self:center;width:16px;height:16px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);cursor:pointer;flex:none}.tl-car[data-v-6e9ab5f9]:hover{color:var(--color-text)}.tl-car[data-v-6e9ab5f9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-car-ic[data-v-6e9ab5f9]{transition:transform var(--duration-base) var(--ease-out)}.tool-line.open .tl-car-ic[data-v-6e9ab5f9]{transform:rotate(90deg)}.tl-body[data-v-6e9ab5f9]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.tl-body.open[data-v-6e9ab5f9]{grid-template-rows:minmax(0,1fr)}.tl-body-inner[data-v-6e9ab5f9]{min-height:0;overflow:hidden;padding:2px var(--space-2) var(--space-1) 0}.tl-main .tl-name[data-v-6e9ab5f9-s]{font-weight:var(--weight-regular);color:var(--color-text-muted);flex:none}.tl-main .tl-dim[data-v-6e9ab5f9-s]{color:var(--color-text-muted);line-height:var(--leading-tight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-faint[data-v-6e9ab5f9-s]{color:var(--color-text-faint);line-height:var(--leading-tight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-mono[data-v-6e9ab5f9-s]{font-family:var(--font-mono);font-size:var(--text-xs);font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);line-height:normal;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-file[data-v-6e9ab5f9-s]{font-weight:var(--weight-regular);color:var(--color-text);line-height:var(--leading-tight);flex:none;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:none;border-radius:var(--radius-xs);background:transparent;padding:0 1px;font-family:inherit;font-size:inherit;cursor:pointer}.tl-main .tl-file[data-v-6e9ab5f9-s]:hover{color:var(--color-accent);text-decoration:underline;text-underline-offset:3px}.tl-main .tl-file[data-v-6e9ab5f9-s]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-tail .tl-pill[data-v-6e9ab5f9-s]{font-size:var(--text-xs);line-height:1.5;padding:0 var(--space-2);border-radius:var(--radius-full);flex:none;white-space:nowrap}.tl-tail .tl-chip[data-v-6e9ab5f9-s]{color:var(--color-text-faint);font-size:var(--text-xs);flex:none;white-space:nowrap}.tl-tail .tl-add[data-v-6e9ab5f9-s]{color:var(--color-success);font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.tl-tail .tl-del[data-v-6e9ab5f9-s]{color:var(--color-danger);font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.ask-receipt[data-v-f29eda04]{max-width:560px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-xs);padding:var(--space-2) var(--space-3) 10px;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text)}.ask-receipt.flat[data-v-f29eda04]{color:var(--color-text-faint);font-style:italic;padding-top:6px;padding-bottom:6px}.rc-head[data-v-f29eda04]{display:flex;align-items:center;gap:var(--space-2);color:var(--color-text-faint);font-size:var(--text-xs);margin-bottom:6px}.rc-st[data-v-f29eda04]{margin-left:auto;color:var(--color-success);display:inline-flex}.rc-q+.rc-q[data-v-f29eda04]{margin-top:6px}.rc-qtext[data-v-f29eda04]{display:flex;align-items:baseline;gap:var(--space-2);margin-bottom:3px;font-weight:var(--weight-medium);color:var(--color-text)}.rc-opt[data-v-f29eda04]{display:flex;align-items:center;gap:var(--space-2);padding:1.5px 0;color:var(--color-text)}.rc-qskip[data-v-f29eda04]{padding:1.5px 0;color:var(--color-text-faint);font-style:italic}.rc-lb[data-v-f29eda04]{min-width:0}.rc-ds[data-v-f29eda04]{color:var(--color-text-faint);font-size:var(--text-xs)}.rc-g[data-v-f29eda04]{width:14px;height:14px;flex:none;border:.5px solid var(--color-line-strong);position:relative}.rc-g.chk[data-v-f29eda04]{border-radius:var(--radius-xs)}.rc-g.rad[data-v-f29eda04]{border-radius:50%}.rc-g.on[data-v-f29eda04]{border-color:var(--color-accent)}.rc-g.chk.on[data-v-f29eda04]{background:var(--color-accent)}.rc-g.chk.on[data-v-f29eda04]:after{content:"";position:absolute;left:3.5px;top:.5px;width:4px;height:8px;border-right:1.5px solid var(--color-text-on-accent);border-bottom:1.5px solid var(--color-text-on-accent);transform:rotate(45deg)}.rc-g.rad.on[data-v-f29eda04]:after{content:"";position:absolute;inset:2.5px;border-radius:50%;background:var(--color-accent)}.cmd-echo[data-v-8869dd42]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.hl-code[data-v-6735e4da]{border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);overflow:auto;max-height:calc(24 * 1.5 * var(--ui-font-size));overscroll-behavior:contain;font-family:var(--font-mono);font-size:var(--code-font-size);line-height:var(--leading-normal);font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none}.hl-code[data-v-6735e4da]:not(.framed){border:none;border-radius:0;background:transparent;max-height:none;overflow:visible}.hl-body[data-v-6735e4da]{width:max-content;min-width:100%;padding:var(--space-1) 0 var(--space-2)}.hl-code.plain-pad .hl-body[data-v-6735e4da]{padding-left:var(--space-3)}.hl-row[data-v-6735e4da]{display:flex;align-items:flex-start;min-height:calc(1em * var(--leading-normal));white-space:pre;width:100%}.hl-gutter[data-v-6735e4da]{flex:none;box-sizing:content-box;min-width:var(--gutter-ch, 4ch);padding:0 var(--space-2);text-align:right;color:var(--color-text-faint);user-select:none;border-right:.5px solid var(--color-line);font-variant-numeric:tabular-nums}.hl-sign[data-v-6735e4da]{flex:none;width:16px;text-align:center;color:var(--color-text-muted);user-select:none}.hl-text[data-v-6735e4da]{flex:none;padding-right:14px;white-space:pre;color:var(--color-text)}.hl-gutter+.hl-text[data-v-6735e4da]{padding-left:var(--space-2)}.row-add[data-v-6735e4da]{background:var(--color-diff-add-bg)}.row-add .hl-sign[data-v-6735e4da]{color:var(--color-success)}.row-del[data-v-6735e4da]{background:var(--color-diff-del-bg)}.row-del .hl-sign[data-v-6735e4da]{color:var(--color-danger)}.row-hunk[data-v-6735e4da]{background:var(--color-surface-sunken)}.row-hunk .hl-text[data-v-6735e4da]{color:var(--color-text-muted)}.hl-code.gutter .row-add[data-v-6735e4da]{box-shadow:inset 2px 0 color-mix(in srgb,var(--color-success) 55%,transparent)}.hl-code.gutter .row-del[data-v-6735e4da]{box-shadow:inset 2px 0 color-mix(in srgb,var(--color-danger) 55%,transparent)}.diffbar[data-v-bbf61950]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);overflow:hidden;gap:1px;flex:none}.seg-add[data-v-bbf61950]{background:var(--color-success)}.seg-del[data-v-bbf61950]{background:var(--color-danger)}.gl[data-v-b12a8498]{display:inline-flex;align-items:center}.arg-full[data-v-b12a8498]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.file-list[data-v-3936099e]{display:flex;flex-direction:column;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-1);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.file-row[data-v-3936099e]{width:100%;border:none;border-radius:var(--radius-sm);background:transparent;padding:2px var(--space-2);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.file-row[data-v-3936099e]:hover{background:var(--color-hover);color:var(--color-accent)}.file-row[data-v-3936099e]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-pill.pill-active[data-v-862274de]{color:var(--color-accent);background:var(--color-accent-soft)}.tl-pill.pill-done[data-v-862274de]{color:var(--color-success);background:var(--color-success-soft)}.tl-pill.pill-blocked[data-v-862274de]{color:var(--color-warning);background:var(--color-warning-soft)}.goal-block[data-v-862274de]{margin-bottom:var(--space-1)}.goal-text[data-v-862274de]{color:var(--color-text);font-size:calc(var(--content-font-size) - 1px);line-height:1.6;white-space:pre-wrap;word-break:break-word}.goal-criterion[data-v-862274de]{color:var(--color-text-muted);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;margin-top:2px;white-space:pre-wrap;word-break:break-word}.match-list[data-v-899c1a48]{display:flex;flex-direction:column;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-1);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.match-row[data-v-899c1a48]{display:flex;align-items:baseline;gap:var(--space-2);width:100%;border:none;border-radius:var(--radius-sm);background:transparent;padding:2px var(--space-2);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);text-align:left;cursor:default}.match-row.link[data-v-899c1a48]{cursor:pointer}.match-row.link[data-v-899c1a48]:hover{background:var(--color-hover)}.match-row[data-v-899c1a48]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.mref[data-v-899c1a48]{flex:none;max-width:45%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-faint)}.match-row.link:hover .mref[data-v-899c1a48]{color:var(--color-accent)}.mtext[data-v-899c1a48]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.is-resolving[data-v-23acd4fa]{visibility:hidden}.media-tool[data-v-3bc3ee1a]{display:inline-flex;flex-direction:column;gap:6px;max-width:320px}.media-title[data-v-3bc3ee1a]{font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-image-button[data-v-3bc3ee1a]{padding:0;border:none;background:transparent;cursor:pointer;border-radius:var(--radius-md);overflow:hidden}.media-image[data-v-3bc3ee1a]{display:block;max-width:100%;border-radius:var(--radius-md);background:var(--media-alpha-canvas)}.media-video[data-v-3bc3ee1a],.media-audio[data-v-3bc3ee1a]{max-width:100%;border-radius:var(--radius-md)}.media-video[data-v-3bc3ee1a]{display:block}.media-video-button[data-v-3bc3ee1a]{position:relative}.media-video-tile[data-v-3bc3ee1a]{display:block;width:320px;max-width:100%;aspect-ratio:16 / 9;background:var(--color-well)}.media-play-badge[data-v-3bc3ee1a]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:var(--radius-full);background:var(--color-surface-raised);border:.5px solid var(--color-line);color:var(--color-text);box-shadow:var(--shadow-sm);pointer-events:none}:where(.markstream-vue) button{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:transparent;border:0;font:inherit;color:inherit}.markstream-vue li:has(.checkbox-node){list-style-type:none;margin-left:calc(-1 * var(--ms-flow-list-indent))}.markstream-vue .text-node{white-space:pre-wrap;overflow-wrap:break-word}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.markstream-vue .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.markstream-vue .pointer-events-none{pointer-events:none}.markstream-vue .\!visible{visibility:visible!important}.markstream-vue .visible{visibility:visible}.markstream-vue .collapse{visibility:collapse}.markstream-vue .static{position:static}.markstream-vue .fixed{position:fixed}.markstream-vue .absolute{position:absolute}.markstream-vue .relative{position:relative}.markstream-vue .inset-0{inset:0}.markstream-vue .right-2{right:8px}.markstream-vue .right-6{right:24px}.markstream-vue .top-2{top:8px}.markstream-vue .top-6{top:24px}.markstream-vue .z-10{z-index:10}.markstream-vue .z-50{z-index:50}.markstream-vue .m-0{margin:0}.markstream-vue .mx-0\.5{margin-left:2px;margin-right:2px}.markstream-vue .mr-2{margin-right:8px}.markstream-vue .mt-2{margin-top:8px}.markstream-vue .block{display:block}.markstream-vue .inline{display:inline}.markstream-vue .flex{display:flex}.markstream-vue .inline-flex{display:inline-flex}.markstream-vue .table{display:table}.markstream-vue .flow-root{display:flow-root}.markstream-vue .grid{display:grid}.markstream-vue .contents{display:contents}.markstream-vue .list-item{display:list-item}.markstream-vue .hidden{display:none}.markstream-vue .h-4{height:16px}.markstream-vue .h-full{height:100%}.markstream-vue .max-h-full{max-height:100%}.markstream-vue .min-h-full{min-height:100%}.markstream-vue .w-2\/3{width:66.666667%}.markstream-vue .w-4{width:16px}.markstream-vue .w-4\/5{width:80%}.markstream-vue .w-full{width:100%}.markstream-vue .min-w-\[160px\]{min-width:160px}.markstream-vue .max-w-full{max-width:100%}.markstream-vue .flex-1{flex:1 1 0%}.markstream-vue .flex-shrink{flex-shrink:1}.markstream-vue .flex-shrink-0{flex-shrink:0}.markstream-vue .shrink{flex-shrink:1}.markstream-vue .shrink-0{flex-shrink:0}.markstream-vue .border-collapse{border-collapse:collapse}.markstream-vue .transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.markstream-vue .animate-spin{animation:spin 1s linear infinite}.markstream-vue .cursor-grab{cursor:grab}.markstream-vue .cursor-grabbing{cursor:grabbing}.markstream-vue .cursor-not-allowed{cursor:not-allowed}.markstream-vue .cursor-pointer{cursor:pointer}.markstream-vue .resize{resize:both}.markstream-vue .list-decimal{list-style-type:decimal}.markstream-vue .list-disc{list-style-type:disc}.markstream-vue .flex-wrap{flex-wrap:wrap}.markstream-vue .items-center{align-items:center}.markstream-vue .items-baseline{align-items:baseline}.markstream-vue .justify-center{justify-content:center}.markstream-vue .justify-between{justify-content:space-between}.markstream-vue .gap-0\.5{gap:2px}.markstream-vue .gap-1\.5{gap:6px}.markstream-vue .gap-2{gap:8px}.markstream-vue .gap-\[var\(--ms-gap-header-actions\)\]{gap:var(--ms-gap-header-actions)}.markstream-vue .gap-x-1{-moz-column-gap:4px;column-gap:4px}.markstream-vue .gap-x-2{-moz-column-gap:8px;column-gap:8px}.markstream-vue .overflow-hidden{overflow:hidden}.markstream-vue .overflow-x-auto{overflow-x:auto}.markstream-vue .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.markstream-vue .whitespace-nowrap{white-space:nowrap}.markstream-vue .whitespace-pre-wrap{white-space:pre-wrap}.markstream-vue .rounded{border-radius:calc(var(--ms-radius) * .5)}.markstream-vue .rounded-lg{border-radius:var(--ms-radius)}.markstream-vue .rounded-md{border-radius:calc(var(--ms-radius) * .75)}.markstream-vue .border{border-width:1px}.markstream-vue .border-b{border-bottom-width:1px}.markstream-vue .border-t{border-top-width:1px}.markstream-vue .border-\[var\(--code-border\)\]{border-color:var(--code-border)}.markstream-vue .border-\[var\(--footnote-border\)\]{border-color:var(--footnote-border)}.markstream-vue .border-\[var\(--hr-border\)\]{border-color:var(--hr-border)}.markstream-vue .bg-\[hsl\(var\(--ms-popover\)\)\]{background-color:hsl(var(--ms-popover))}.markstream-vue .bg-\[var\(--code-header-bg\)\]{background-color:var(--code-header-bg)}.markstream-vue .p-0{padding:0}.markstream-vue .p-1{padding:4px}.markstream-vue .p-4{padding:16px}.markstream-vue .p-\[var\(--ms-action-btn-padding\)\]{padding:var(--ms-action-btn-padding)}.markstream-vue .px-1\.5{padding-left:6px;padding-right:6px}.markstream-vue .px-2{padding-left:8px;padding-right:8px}.markstream-vue .px-4{padding-left:16px;padding-right:16px}.markstream-vue .px-\[var\(--ms-inset-panel-x\)\]{padding-left:var(--ms-inset-panel-x);padding-right:var(--ms-inset-panel-x)}.markstream-vue .py-0\.5{padding-top:2px;padding-bottom:2px}.markstream-vue .py-1\.5{padding-top:6px;padding-bottom:6px}.markstream-vue .py-\[var\(--ms-inset-panel-y\)\]{padding-top:var(--ms-inset-panel-y);padding-bottom:var(--ms-inset-panel-y)}.markstream-vue .pb-3{padding-bottom:12px}.markstream-vue .pt-2{padding-top:8px}.markstream-vue .text-left{text-align:left}.markstream-vue .text-center{text-align:center}.markstream-vue .text-right{text-align:right}.markstream-vue .font-mono{font-family:var(--ms-font-mono)}.markstream-vue .text-\[length\:var\(--ms-text-label\)\]{font-size:var(--ms-text-label)}.markstream-vue .text-sm{font-size:14px;line-height:20px}.markstream-vue .text-xs{font-size:12px;line-height:16px}.markstream-vue .font-medium{font-weight:500}.markstream-vue .font-semibold{font-weight:600}.markstream-vue .uppercase{text-transform:uppercase}.markstream-vue .lowercase{text-transform:lowercase}.markstream-vue .italic{font-style:italic}.markstream-vue .leading-\[normal\]{line-height:normal}.markstream-vue .leading-none{line-height:1}.markstream-vue .leading-relaxed{line-height:1.625}.markstream-vue .text-\[\#0366d6\]{--tw-text-opacity: 1;color:rgb(3 102 214 / var(--tw-text-opacity, 1))}.markstream-vue .text-\[hsl\(var\(--ms-popover-foreground\)\)\]{color:hsl(var(--ms-popover-foreground))}.markstream-vue .text-\[var\(--code-action-fg\)\]{color:var(--code-action-fg)}.markstream-vue .text-\[var\(--code-fg\)\]{color:var(--code-fg)}.markstream-vue .underline{text-decoration-line:underline}.markstream-vue .antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.markstream-vue .opacity-0{opacity:0}.markstream-vue .opacity-50{opacity:.5}.markstream-vue .shadow{--tw-shadow: 0 1px 3px 0 rgb(0 0 0 / .1), 0 1px 2px -1px rgb(0 0 0 / .1);--tw-shadow-colored: 0 1px 3px 0 var(--tw-shadow-color), 0 1px 2px -1px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.markstream-vue .shadow-\[var\(--ms-shadow-popover\)\]{--tw-shadow-color: var(--ms-shadow-popover);--tw-shadow: var(--tw-shadow-colored)}.markstream-vue .outline{outline-style:solid}.markstream-vue .blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.markstream-vue .filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.markstream-vue .backdrop-blur{--tw-backdrop-blur: blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.markstream-vue .backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.markstream-vue .transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-\[height\]{transition-property:height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.markstream-vue .ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.markstream-vue{--ms-background: 0 0% 100%;--ms-foreground: 0 0% 10%;--ms-muted: 0 0% 96.5%;--ms-muted-foreground: 0 0% 43%;--ms-secondary: 0 0% 93.5%;--ms-secondary-foreground: 0 0% 10%;--ms-accent: 0 0% 91%;--ms-accent-foreground: 0 0% 10%;--ms-primary: 0 0% 10%;--ms-primary-foreground: 0 0% 100%;--ms-destructive: 0 62% 52%;--ms-destructive-foreground: 0 0% 100%;--ms-border: 0 0% 87%;--ms-ring: 0 0% 10%;--ms-popover: 0 0% 100%;--ms-popover-foreground: 0 0% 10%;--ms-radius: 8px;--ms-info: 215 60% 50%;--ms-info-foreground: 0 0% 100%;--ms-success: 152 56% 39%;--ms-success-foreground: 0 0% 100%;--ms-warning: 38 64% 46%;--ms-warning-foreground: 0 0% 9%;--ms-diff-added: 152 50% 36%;--ms-diff-removed: 0 58% 48%;--ms-highlight: 50 60% 72%;--ms-highlight-foreground: 0 0% 0%;--ms-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";--ms-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace}.dark .markstream-vue,.markstream-vue.dark{--ms-background: 0 0% 7%;--ms-foreground: 0 0% 93%;--ms-muted: 0 0% 12%;--ms-muted-foreground: 0 0% 60%;--ms-secondary: 0 0% 16%;--ms-secondary-foreground: 0 0% 93%;--ms-accent: 0 0% 24%;--ms-accent-foreground: 0 0% 93%;--ms-primary: 0 0% 93%;--ms-primary-foreground: 0 0% 10%;--ms-destructive: 0 60% 50%;--ms-destructive-foreground: 0 0% 93%;--ms-border: 0 0% 20%;--ms-ring: 0 0% 80%;--ms-popover: 0 0% 9%;--ms-popover-foreground: 0 0% 93%;--ms-info: 215 55% 62%;--ms-info-foreground: 0 0% 100%;--ms-success: 152 48% 55%;--ms-success-foreground: 0 0% 100%;--ms-warning: 32 65% 58%;--ms-warning-foreground: 0 0% 9%;--ms-diff-added: 152 42% 60%;--ms-diff-removed: 0 58% 58%;--ms-highlight: 48 65% 50%;--ms-highlight-foreground: 0 0% 0%;--ms-shadow-subtle: 0 1px 3px 0 hsl(0 0% 0% / .25);--ms-shadow-popover: 0 4px 6px -1px hsl(0 0% 0% / .2), 0 2px 4px -2px hsl(0 0% 0% / .15);--ms-shadow-modal: 0 10px 15px -3px hsl(0 0% 0% / .5), 0 4px 6px -4px hsl(0 0% 0% / .4);--ms-shadow-preview: 0 10px 40px hsl(0 0% 0% / .6);--tooltip-bg: hsl(0 0% 12%);--tooltip-fg: hsl(0 0% 72%);--code-bg: #111827;--code-header-bg: hsl(var(--ms-muted));--admonition-note-header-bg: color-mix(in srgb, hsl(var(--ms-info)) 12%, transparent);--admonition-tip-header-bg: color-mix(in srgb, hsl(var(--ms-success)) 12%, transparent);--admonition-warn-header-bg: color-mix(in srgb, hsl(var(--ms-warning)) 12%, transparent);--admonition-danger-header-bg: color-mix(in srgb, hsl(var(--ms-destructive)) 12%, transparent)}.markstream-vue{font-family:var(--ms-font-sans);font-size:var(--ms-text-body);line-height:var(--ms-leading-body);--inline-code-bg: hsl(var(--ms-secondary));--inline-code-fg: hsl(var(--ms-foreground) / .75);--inline-code-border: hsl(var(--ms-border) / .9);--code-bg: #fff;--code-fg: hsl(var(--ms-foreground));--code-border: hsl(var(--ms-border));--code-header-bg: hsl(var(--ms-secondary));--code-selection-bg: hsl(var(--ms-accent) / .3);--code-line-number: hsl(var(--ms-muted-foreground));--markstream-code-line-number-align: right;--code-action-fg: hsl(var(--ms-muted-foreground));--code-action-hover-bg: hsl(var(--ms-accent));--code-action-hover-fg: hsl(var(--ms-accent-foreground));--code-action-active-bg: hsl(var(--ms-primary));--code-action-active-fg: hsl(var(--ms-primary-foreground));--diff-added-fg: hsl(var(--ms-diff-added));--diff-removed-fg: hsl(var(--ms-diff-removed));--diff-added-bg: hsl(var(--ms-diff-added) / .1);--diff-added-inline-bg: hsl(var(--ms-diff-added) / .2);--diff-removed-bg: hsl(var(--ms-diff-removed) / .1);--diff-removed-inline-bg: hsl(var(--ms-diff-removed) / .2);--blockquote-border: hsl(var(--ms-muted-foreground) / .2);--admonition-bg: hsl(var(--ms-muted));--admonition-border: hsl(var(--ms-border));--admonition-fg: hsl(var(--ms-foreground));--admonition-muted: hsl(var(--ms-muted-foreground));--admonition-header-bg: hsl(var(--ms-muted) / .5);--admonition-note: hsl(var(--ms-info));--admonition-tip: hsl(var(--ms-success));--admonition-warning: hsl(var(--ms-warning));--admonition-danger: hsl(var(--ms-destructive));--admonition-note-header-bg: color-mix(in srgb, hsl(var(--ms-info)) 6%, transparent);--admonition-tip-header-bg: color-mix(in srgb, hsl(var(--ms-success)) 6%, transparent);--admonition-warn-header-bg: color-mix(in srgb, hsl(var(--ms-warning)) 6%, transparent);--admonition-danger-header-bg: color-mix(in srgb, hsl(var(--ms-destructive)) 6%, transparent);--table-border: hsl(var(--ms-border));--table-header-bg: hsl(var(--ms-muted));--link-color: hsl(var(--ms-info));--list-marker: hsl(var(--ms-muted-foreground) / .5);--list-counter-marker: hsl(var(--ms-muted-foreground));--hr-border: hsl(var(--ms-border));--highlight-bg: hsl(var(--ms-highlight));--footnote-border: hsl(var(--ms-border));--tooltip-bg: hsl(0 0% 18%);--tooltip-fg: hsl(0 0% 88%);--tooltip-border: hsl(var(--ms-border));--modal-overlay: hsl(0 0% 0% / .7);--modal-bg: hsl(var(--ms-popover));--modal-fg: hsl(var(--ms-popover-foreground));--diagram-bg: hsl(var(--ms-muted));--diagram-border: hsl(var(--ms-border));--diagram-header-bg: hsl(var(--ms-muted));--loading-spinner: hsl(var(--ms-muted-foreground));--loading-shimmer: hsl(var(--ms-muted) / .5);--image-placeholder-bg: hsl(var(--ms-muted));--focus-ring: hsl(var(--ms-ring));--ms-space-1: 4px;--ms-space-1_5: 6px;--ms-space-2: 8px;--ms-space-2_5: 10px;--ms-space-3: 12px;--ms-space-4: 16px;--ms-space-5: 20px;--ms-space-6: 24px;--ms-space-8: 32px;--ms-space-12: 48px;--ms-flow-paragraph-y: 1.5em;--ms-flow-list-y: 1em;--ms-flow-list-item-y: .25em;--ms-flow-list-indent: 1.625em ;--ms-flow-list-indent-mobile: calc(14 / 9 * 1em);--ms-flow-table-y: 2em;--ms-flow-table-cell: .5em .75em;--ms-flow-blockquote-y: 1.25em;--ms-flow-blockquote-indent: 1.25em;--ms-flow-admonition-y: 1.25em;--ms-flow-footnote-y: .5em;--ms-flow-hr-y: 2.5em;--ms-flow-diagram-y: 1.5em;--ms-flow-codeblock-y: 1.5em;--ms-flow-definition-term-mt: .75em;--ms-flow-definition-desc-ml: 1.25em;--ms-flow-definition-desc-mb: .5em;--ms-flow-heading-1-mt: 0;--ms-flow-heading-1-mb: 1em;--ms-flow-heading-2-mt: 2em;--ms-flow-heading-2-mb: .75em;--ms-flow-heading-3-mt: 1.5em;--ms-flow-heading-3-mb: .6em;--ms-flow-heading-4-mt: 1.25em;--ms-flow-heading-4-mb: .4em;--ms-flow-heading-5-mt: 1em;--ms-flow-heading-5-mb: .25em;--ms-flow-heading-6-mt: 1em;--ms-flow-heading-6-mb: .25em;--ms-text-body: 16px;--ms-leading-body: 1.75;--ms-text-h1: 36px;--ms-text-h2: 24px;--ms-text-h3: 20px;--ms-text-h4: 16px;--ms-text-h5: 16px;--ms-text-h6: 16px;--ms-leading-h1: 1.2;--ms-leading-h2: 1.35;--ms-leading-h3: 1.5;--ms-weight-h1: 700;--ms-weight-h2: 600;--ms-weight-h3: 600;--ms-weight-h4: 600;--ms-text-label: 12px;--ms-action-btn-padding: 6px;--ms-action-btn-icon: 14px;--ms-inset-panel-x: 10px;--ms-inset-panel-y: 6px;--ms-inset-panel-body-sm: 8px;--ms-inset-panel-body: 16px;--ms-inset-admonition-body-top: 8px;--ms-inset-admonition-body-bottom: 12px;--ms-gap-header: var(--ms-space-4);--ms-gap-header-main: var(--ms-space-2_5);--ms-gap-header-actions: var(--ms-space-2);--ms-shadow-subtle: 0 1px 3px 0 hsl(var(--ms-foreground) / .06);--ms-shadow-popover: 0 4px 6px -1px hsl(var(--ms-foreground) / .1), 0 2px 4px -2px hsl(var(--ms-foreground) / .1);--ms-shadow-modal: 0 10px 15px -3px hsl(var(--ms-foreground) / .1), 0 4px 6px -4px hsl(var(--ms-foreground) / .1);--ms-shadow-preview: 0 10px 40px hsl(var(--ms-foreground) / .25);--ms-duration-fast: .12s;--ms-duration-standard: .18s;--ms-duration-overlay: .2s;--ms-duration-emphasis: .22s;--ms-duration-slow: .3s;--ms-duration-stream: .28s;--ms-ease-linear: linear;--ms-ease-standard: ease;--ms-ease-out: ease-out;--ms-ease-in-out: ease-in-out;--ms-ease-spring: cubic-bezier(.16, 1, .3, 1);--ms-border-width: 1px;--ms-border-width-strong: 4px;--ms-focus-ring-width: 2px;--ms-focus-ring-offset: 2px;--ms-size-diagram-min-height: 360px;--ms-size-code-max-height: 500px;--ms-size-image-max-width: 384px;--ms-size-image-min-width: 128px;--ms-size-image-min-height: 1.5em;--ms-size-math-min-height: 40px;--ms-size-skeleton-min-height: 120px}body>div[id^=dmermaid-]{position:fixed;top:-10000px;left:0;width:100%;visibility:hidden;pointer-events:none}.markstream-vue .hover\:bg-\[var\(--code-action-hover-bg\)\]:hover{background-color:var(--code-action-hover-bg)}.markstream-vue .hover\:text-\[var\(--code-action-hover-fg\)\]:hover{color:var(--code-action-hover-fg)}.markstream-vue .hover\:underline:hover{text-decoration-line:underline}.markstream-vue .active\:scale-\[0\.96\]:active{--tw-scale-x: .96;--tw-scale-y: .96;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.markstream-vue .disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.markstream-vue .disabled\:opacity-40:disabled{opacity:.4}.checkbox-node[data-v-be21ab83]{display:inline-flex;align-items:center;margin-right:.5em;vertical-align:-.15em}.checkbox-icon[data-v-be21ab83]{flex-shrink:0}.checkbox-unchecked[data-v-be21ab83]{color:hsl(var(--ms-muted-foreground) / .5)}.checkbox-checked[data-v-be21ab83]{color:hsl(var(--ms-info))}.emoji-node[data-v-de55dc97]{display:inline-block}.footnote-reference[data-v-c1463a29]{font-size:.75em;line-height:0}.footnote-link[data-v-c1463a29]{color:var(--link-color);text-decoration:none}.footnote-link[data-v-c1463a29]:hover{text-decoration:underline}.html-inline-node[data-v-d17f12b0]{display:inline}.html-inline-node--loading[data-v-d17f12b0]{opacity:.85}.inline-code[data-v-4e331c97]{display:inline;font-family:var(--ms-font-mono);font-size:.8125em;line-height:inherit;color:var(--inline-code-fg);background-color:var(--inline-code-bg);padding:.15em .35em;border-radius:.25em;white-space:normal;word-break:break-word;max-width:100%;-webkit-box-decoration-break:clone;box-decoration-break:clone}.inline-code-stream-delta[data-v-4e331c97]{animation-duration:var(--stream-update-fade-duration, var(--fade-duration, .28s));animation-timing-function:var(--stream-update-fade-ease, var(--fade-ease, cubic-bezier(.33, 0, .67, 1)));animation-fill-mode:both}.inline-code-stream-delta--a[data-v-4e331c97]{animation-name:inline-code-stream-update-fade-a-4e331c97}.inline-code-stream-delta--b[data-v-4e331c97]{animation-name:inline-code-stream-update-fade-b-4e331c97}@keyframes inline-code-stream-update-fade-a-4e331c97{0%{opacity:0}to{opacity:1}}@keyframes inline-code-stream-update-fade-b-4e331c97{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.inline-code-stream-delta[data-v-4e331c97]{animation:none!important}}.image-node-container[data-v-046e82ac]{display:inline-block;position:relative;vertical-align:middle;max-width:var(--ms-size-image-max-width)}.image-node__img[data-v-046e82ac]{display:inline-block;max-width:100%;min-width:var(--ms-size-image-min-width);min-height:var(--ms-size-image-min-height);height:auto;vertical-align:middle;transition:opacity var(--ms-duration-emphasis) var(--ms-ease-standard)}.image-node__img.is-loading[data-v-046e82ac]{opacity:0}.image-node__img.is-loaded[data-v-046e82ac]{opacity:1}.image-node__img.has-natural-size[data-v-046e82ac]{min-width:0;min-height:0}.image-placeholder[data-v-046e82ac]{display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:var(--ms-size-image-min-width);min-height:128px;max-width:var(--ms-size-image-max-width);background:hsl(var(--ms-muted));overflow:hidden;vertical-align:middle}.image-shimmer-overlay[data-v-046e82ac]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:hsl(var(--ms-muted));overflow:hidden}.image-shimmer-overlay .image-shimmer[data-v-046e82ac]{width:100%;height:100%}.image-shimmer[data-v-046e82ac]{display:block;width:100%;height:100%;min-height:128px;background:linear-gradient(90deg,hsl(var(--ms-muted)),hsl(var(--ms-muted-foreground) / .06),hsl(var(--ms-muted)));background-size:200% 100%;animation:image-shimmer-046e82ac 1.5s ease-in-out infinite}.image-node-container[data-markstream-viewport-pending=true] .image-shimmer[data-v-046e82ac]{animation:none}@keyframes image-shimmer-046e82ac{0%{background-position:100% 0}to{background-position:-100% 0}}.image-error[data-v-046e82ac]{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:16px 24px;min-height:64px;max-width:var(--ms-size-image-max-width);background:hsl(var(--ms-muted));color:hsl(var(--ms-muted-foreground));font-size:var(--ms-text-label);vertical-align:middle}.image-node__raw-text[data-v-046e82ac]{font-size:var(--ms-text-label);color:hsl(var(--ms-muted-foreground))}@media(prefers-reduced-motion:reduce){.image-shimmer[data-v-046e82ac]{animation:none!important}}.markstream-vue pre[class^=language-],.markstream-vue pre[class*=" language-"]{white-space:pre;overflow:auto;-moz-tab-size:2;-o-tab-size:2;tab-size:2;font-variant-ligatures:none;contain:content;backface-visibility:hidden;transform:translateZ(0);-webkit-font-smoothing:antialiased}.markstream-vue pre[class^=language-]>code,.markstream-vue pre[class*=" language-"]>code{display:block}.markstream-vue pre[data-markstream-pre="1"]:not(.markstream-pre--diff-preview){background:var(--code-bg);color:var(--code-fg)}.markstream-vue pre.markstream-pre--line-numbers{position:relative}.markstream-vue pre.code-pre-fallback[data-markstream-code-loading="1"]{--markstream-pre-line-number-top: var(--markstream-code-padding-y, 8px);--markstream-pre-line-number-left: 0px;--markstream-pre-line-number-width: 2ch;--markstream-pre-line-number-padding-left: 2ch;--markstream-pre-line-number-padding-right: 1ch;--markstream-pre-line-number-separator-width: 2px;--markstream-code-padding-left: calc(6ch + 2px) ;box-sizing:border-box;width:100%;margin:0;padding:var(--markstream-code-padding-y, 8px) var(--markstream-code-padding-x, 12px);padding-left:var(--markstream-code-padding-left);overflow:auto;border:0;border-radius:0;background:var(--code-bg);color:var(--code-fg);font-family:var( --markstream-code-font-family, Menlo, Monaco, Courier New, monospace );font-size:var(--vscode-editor-font-size, 12px);line-height:var(--vscode-editor-line-height, 18px)}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers{position:absolute;top:var(--markstream-pre-line-number-top, 0);left:var(--markstream-pre-line-number-left, 0);box-sizing:content-box;display:flex;flex-direction:column;align-items:flex-end;width:var(--markstream-pre-line-number-width, 2ch);min-width:var(--markstream-pre-line-number-width, 2ch);padding-left:var(--markstream-pre-line-number-padding-left, 2ch);padding-right:var(--markstream-pre-line-number-padding-right, 1ch);border-right:var(--markstream-pre-line-number-separator-width, 2px) solid transparent;color:var(--code-line-number);font:inherit;font-variant-numeric:tabular-nums;line-height:inherit;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.markstream-vue pre.markstream-pre--line-numbers:not(.markstream-pre--diff-preview):not(.code-pre-fallback)>.markstream-pre__code{box-sizing:border-box;min-width:100%;padding-left:var(--markstream-code-padding-left, 52px);padding-right:var(--markstream-code-padding-x, 12px)}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers>.markstream-pre__line-number{display:block;min-height:1lh}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers>.markstream-pre__line-numbers-text{display:block;min-height:1lh;text-align:right;white-space:pre}.markstream-vue pre.markstream-pre--diff-preview{box-sizing:border-box;padding-left:0;padding-right:0;width:100%;--markstream-pre-diff-gutter-marker-width: var(--stream-monaco-gutter-marker-width, 4px);--markstream-pre-diff-gutter-gap: var(--stream-monaco-gutter-gap, 1ch);--markstream-pre-diff-code-gap: var(--stream-monaco-diff-code-gap, 1ch);--markstream-pre-diff-code-padding: var(--stream-monaco-diff-code-padding, 0px);--markstream-diff-added-fg: var(--diff-added-fg, #2f8f68);--markstream-diff-removed-fg: var(--diff-removed-fg, #c24141);--markstream-diff-added-line-fill: var(--diff-added-bg, rgb(47 143 104 / 12%));--markstream-diff-removed-line-fill: var(--diff-removed-bg, rgb(194 65 65 / 12%));--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--markstream-pre-diff-gutter-marker-width), transparent var(--markstream-pre-diff-gutter-marker-width) 100% );--markstream-diff-removed-gutter: linear-gradient( 90deg, var(--markstream-diff-removed-fg) 0 var(--markstream-pre-diff-gutter-marker-width), transparent var(--markstream-pre-diff-gutter-marker-width) 100% );--markstream-pre-diff-line-number-width: var( --stream-monaco-line-number-width, 2ch );--markstream-pre-diff-line-number-padding-left: var(--stream-monaco-line-number-padding-left, 2ch);--markstream-pre-diff-line-number-padding-right: var(--stream-monaco-line-number-padding-right, 1ch);--markstream-pre-diff-line-number-separator-width: var(--stream-monaco-line-number-separator-width, 2px);--markstream-pre-diff-line-number-box-width: calc( var(--markstream-pre-diff-line-number-padding-left) + var(--markstream-pre-diff-line-number-width) + var(--markstream-pre-diff-line-number-padding-right) + var(--markstream-pre-diff-line-number-separator-width) );--markstream-pre-diff-line-number-bg: var( --stream-monaco-line-number-bg, var(--markstream-diff-line-number-bg, transparent) );--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-original-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px );--markstream-pre-diff-line-number-align: var(--markstream-diff-line-number-align, right);--markstream-pre-diff-code-fill-left: calc( var(--markstream-pre-diff-line-number-left) + var(--markstream-pre-diff-line-number-box-width) );--markstream-pre-diff-code-left: calc( var(--markstream-pre-diff-code-fill-left) + var(--markstream-pre-diff-line-number-gap-to-code) + var(--markstream-pre-diff-code-padding) )}.markstream-vue pre.markstream-pre--diff-preview::-webkit-scrollbar{width:12px;height:12px}.markstream-vue pre.markstream-pre--diff-preview.is-wrap{white-space:pre-wrap;overflow-wrap:anywhere}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline{--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-modified-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px )}.markstream-vue pre.markstream-pre--diff-preview>.markstream-pre__diff-code{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);font:inherit;line-height:inherit;min-width:100%;width:100%}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline>.markstream-pre__diff-code{grid-template-columns:minmax(0,1fr)}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline:not(.is-wrap)>.markstream-pre__diff-code{grid-template-columns:minmax(100%,max-content);width:100%;min-width:-moz-max-content;min-width:max-content}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane{min-width:0;overflow:hidden}.markstream-vue pre.markstream-pre--diff-preview:not(.is-wrap):not(.markstream-pre--diff-inline) .markstream-pre__diff-pane{overflow-x:auto;overflow-y:hidden}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane-content{display:block;min-width:100%}.markstream-vue pre.markstream-pre--diff-preview:not(.is-wrap):not(.markstream-pre--diff-inline) .markstream-pre__diff-pane-content{width:-moz-max-content;width:max-content}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline:not(.is-wrap) .markstream-pre__diff-pane{min-width:-moz-max-content;min-width:max-content;width:100%;overflow:visible}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane--modified{--markstream-pre-diff-pane-divider-width: 1px;--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-modified-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px );box-shadow:inset 1px 0 var(--markstream-diff-pane-divider, hsl(var(--ms-border)))}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified{--markstream-pre-diff-line-number-left: calc( var(--stream-monaco-line-number-left, 0px) + var(--markstream-pre-diff-pane-divider-width) )}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-rail{left:var(--markstream-pre-diff-pane-divider-width)}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-line{padding-left:calc(var(--markstream-pre-diff-code-left) + var(--markstream-pre-diff-pane-divider-width))}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-line:before{left:calc(var(--markstream-pre-diff-code-fill-left) + var(--markstream-pre-diff-pane-divider-width))}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline .markstream-pre__diff-pane--modified{box-shadow:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line{position:relative;display:block;box-sizing:border-box;width:100%;min-width:100%;min-height:var( --markstream-pre-diff-synced-row-height, var(--markstream-pre-diff-line-height, 18px) );padding-left:var(--markstream-pre-diff-code-left);line-height:var(--markstream-pre-diff-line-height, 18px)}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line:before{content:"";position:absolute;left:var(--markstream-pre-diff-code-fill-left);right:0;top:0;height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );z-index:0;pointer-events:none;border-radius:0;background:transparent}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line:after{content:"";position:absolute;left:var(--markstream-pre-diff-line-number-left);top:0;width:var(--markstream-pre-diff-line-number-box-width);height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );z-index:0;pointer-events:none;background:var(--markstream-pre-diff-line-number-bg);box-shadow:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-rail{position:absolute;z-index:2;top:0;left:0;height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );width:var(--markstream-pre-diff-gutter-marker-width, 4px);min-width:var(--markstream-pre-diff-gutter-marker-width, 4px)}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-number{position:absolute;z-index:1;top:0;left:var(--markstream-pre-diff-line-number-left);width:var(--markstream-pre-diff-line-number-width);min-width:var(--markstream-pre-diff-line-number-width);height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );box-sizing:content-box;background:var(--markstream-pre-diff-line-number-bg);box-shadow:none;padding-left:var(--markstream-pre-diff-line-number-padding-left, 2ch);padding-right:var(--markstream-pre-diff-line-number-padding-right, 1ch);border-right:var(--markstream-pre-diff-line-number-separator-width, 2px) solid var(--stream-monaco-editor-bg, var(--code-bg));color:var(--code-line-number);font-variant-numeric:tabular-nums;line-height:var(--markstream-pre-diff-line-height, 18px);text-align:var(--markstream-pre-diff-line-number-align, right);-webkit-user-select:none;-moz-user-select:none;user-select:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-number{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent));color:var(--stream-monaco-added-fg, var(--markstream-diff-added-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-number{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent));color:var(--stream-monaco-removed-fg, var(--markstream-diff-removed-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-content{position:relative;z-index:1;display:block;width:-moz-max-content;width:max-content;min-width:100%;line-height:var(--markstream-pre-diff-line-height, 18px);white-space:inherit;overflow-wrap:normal;word-break:normal;line-break:auto}.markstream-vue pre.markstream-pre--diff-preview.is-wrap .markstream-pre__diff-content{width:auto;min-width:0;overflow-wrap:inherit}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-content-inner{white-space:inherit;overflow-wrap:inherit;word-break:inherit;line-break:inherit;-webkit-box-decoration-break:clone;box-decoration-break:clone}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--hunk{color:var(--stream-monaco-unchanged-fg, var(--markstream-diff-unchanged-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--hunk:before{background:var(--stream-monaco-unchanged-bg, var(--markstream-diff-unchanged-bg, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer:before{background-image:linear-gradient(-45deg,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 12.5%,transparent 12.5%,transparent 50%,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 50%,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 62.5%,transparent 62.5%,transparent 100%);background-size:10px 10px;opacity:.38}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer:after,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-rail,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-number,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-content{display:none}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-collapsed:not(.code-pre-fallback){height:auto!important;min-height:0!important}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed{min-height:28px;padding-left:0;color:var(--stream-monaco-unchanged-fg, var(--markstream-diff-unchanged-fg, var(--code-line-number)));line-height:28px}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed:before{left:0;height:28px;background:var(--stream-monaco-unchanged-bg, var(--markstream-diff-unchanged-bg, rgb(0 0 0 / 4%)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed:after,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-rail,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-number{display:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-content{width:100%;min-width:0;padding-left:calc(var(--markstream-pre-diff-code-left) + 12px);line-height:28px}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added:before{background:linear-gradient(var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent)),var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))),var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed:before{background:linear-gradient(var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent)),var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))),var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added:after{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed:after{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-rail{background:var(--stream-monaco-added-gutter, var(--markstream-diff-added-gutter, currentColor))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-rail{background:var(--stream-monaco-removed-gutter, var(--markstream-diff-removed-gutter, currentColor))}.markstream-vue pre[class^=language-]:focus,.markstream-vue pre[class*=" language-"]:focus{outline:var(--ms-focus-ring-width) solid var(--focus-ring);outline-offset:var(--ms-focus-ring-offset)}.text-node[data-v-fd79037c]{display:inline;font-weight:inherit;vertical-align:baseline}.text-node-center[data-v-fd79037c]{display:inline-flex;justify-content:center;width:100%}.text-node-stream-delta[data-v-fd79037c]{animation-duration:var(--stream-update-fade-duration, var(--fade-duration, .28s));animation-timing-function:var(--stream-update-fade-ease, var(--fade-ease, cubic-bezier(.33, 0, .67, 1)));animation-fill-mode:both;will-change:opacity}.text-node-stream-delta--a[data-v-fd79037c]{animation-name:text-node-stream-update-fade-a-fd79037c}.text-node-stream-delta--b[data-v-fd79037c]{animation-name:text-node-stream-update-fade-b-fd79037c}@keyframes text-node-stream-update-fade-a-fd79037c{0%{opacity:0}to{opacity:1}}@keyframes text-node-stream-update-fade-b-fd79037c{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.text-node-stream-delta[data-v-fd79037c]{animation:none!important}}.reference-node[data-v-775c65e4]{background-color:hsl(var(--ms-muted));color:hsl(var(--ms-muted-foreground))}.reference-node[data-v-775c65e4]:hover{background-color:hsl(var(--ms-secondary))}.superscript-node[data-v-24160b22]{font-size:.8em;vertical-align:super}.subscript-node[data-v-197fa13b]{font-size:.8em;vertical-align:sub}.strong-node[data-v-a8647104]{font-weight:700}.strikethrough-node[data-v-b7a531fa]{text-decoration:line-through}.link-node[data-v-367e6ca4]{color:var(--link-color);text-decoration:none}.link-node[data-v-367e6ca4]:hover{text-decoration:underline;text-underline-offset:3.2px}.link-loading .link-text-wrapper[data-v-367e6ca4]{position:relative}.link-loading[data-v-367e6ca4]{color:var(--link-color)}.link-loading .link-text[data-v-367e6ca4]{position:relative;z-index:2}.link-loading-indicator[data-v-367e6ca4]{position:absolute;left:0;right:0;height:var(--underline-height, 2px);bottom:var(--underline-bottom, -3px);background:currentColor;border-radius:999px;will-change:opacity;opacity:var(--underline-rest-opacity, .18);animation:underlinePulse-367e6ca4 var(--underline-duration, 1.6s) var(--underline-timing, ease-in-out) var(--underline-iteration, infinite)}@keyframes underlinePulse-367e6ca4{0%,to{opacity:var(--underline-rest-opacity, .18)}50%{opacity:var(--underline-opacity, .35)}}@media(prefers-reduced-motion:reduce){.link-loading-indicator[data-v-367e6ca4]{animation:none;opacity:var(--underline-rest-opacity, .18)}}.insert-node[data-v-1e2c29d4]{text-decoration:underline}.highlight-node[data-v-7a62982a]{background-color:var(--highlight-bg);padding:0 3.2px;border-radius:.2em}.emphasis-node[data-v-2a5aafbf]{font-style:italic}.hard-break[data-v-50c58f70]{display:block}.blockquote[data-v-abfecebc]{font-weight:400;font-style:normal;color:var(--blockquote-fg, hsl(var(--ms-muted-foreground)));border-left:3px solid var(--blockquote-border);margin-top:var(--ms-flow-blockquote-y);margin-bottom:var(--ms-flow-blockquote-y);padding-left:var(--ms-flow-blockquote-indent)}.blockquote>.paragraph-node[data-v-abfecebc]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:var(--ms-flow-paragraph-y) 0}.blockquote>.paragraph-node[data-v-abfecebc]:first-child{margin-top:0}.blockquote>.paragraph-node[data-v-abfecebc]:last-child{margin-bottom:0}.blockquote[data-v-abfecebc] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.definition-list[data-v-4e103b30]{margin:0 0 16px}.definition-term[data-v-4e103b30]{font-weight:600;margin-top:var(--ms-flow-definition-term-mt)}.definition-desc[data-v-4e103b30]{margin-left:var(--ms-flow-definition-desc-ml);margin-bottom:var(--ms-flow-definition-desc-mb)}.definition-list[data-v-4e103b30] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.footnote-anchor[data-v-e1eb37b6]{margin-left:8px;color:var(--link-color)}.footnote-node{margin-top:var(--ms-flow-footnote-y);margin-bottom:var(--ms-flow-footnote-y)}.markstream-vue [class*=footnote-] .markdown-renderer,.markstream-vue .flex-1 .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.heading-node[data-v-7122dbe1]{font-weight:500;line-height:1.25}hr+.heading-node[data-v-7122dbe1]{margin-top:0}.heading-1[data-v-7122dbe1]{font-size:var(--ms-text-h1);line-height:var(--ms-leading-h1);font-weight:var(--ms-weight-h1);margin-top:var(--ms-flow-heading-1-mt);margin-bottom:var(--ms-flow-heading-1-mb)}.heading-2[data-v-7122dbe1]{font-size:var(--ms-text-h2);line-height:var(--ms-leading-h2);font-weight:var(--ms-weight-h2);margin-top:var(--ms-flow-heading-2-mt);margin-bottom:var(--ms-flow-heading-2-mb)}.heading-3[data-v-7122dbe1]{font-size:var(--ms-text-h3);line-height:var(--ms-leading-h3);font-weight:var(--ms-weight-h3);margin-top:var(--ms-flow-heading-3-mt);margin-bottom:var(--ms-flow-heading-3-mb)}.heading-4[data-v-7122dbe1]{font-size:var(--ms-text-h4);font-weight:var(--ms-weight-h4);margin-top:var(--ms-flow-heading-4-mt);margin-bottom:var(--ms-flow-heading-4-mb)}.heading-5[data-v-7122dbe1]{font-size:var(--ms-text-h5);margin-top:var(--ms-flow-heading-5-mt);margin-bottom:var(--ms-flow-heading-5-mb)}.heading-6[data-v-7122dbe1]{font-size:var(--ms-text-h6);margin-top:var(--ms-flow-heading-6-mt);margin-bottom:var(--ms-flow-heading-6-mb)}.list-item[data-v-617214f9]{margin:var(--ms-flow-list-item-y) 0;padding-left:var(--ms-space-1_5)}ol>.list-item[data-v-617214f9]::marker{color:var(--list-counter-marker);line-height:1.6}ul>.list-item[data-v-617214f9]::marker{color:var(--list-marker)}.list-item>.paragraph-node[data-v-617214f9]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:0}.list-item[data-v-617214f9] .markdown-renderer{content-visibility:visible;contain-intrinsic-size:0px 0px;contain:content}.list-node[data-v-99cb95e0]{margin-top:var(--ms-flow-list-y);margin-bottom:var(--ms-flow-list-y);padding-left:var(--ms-flow-list-indent)}.list-decimal[data-v-99cb95e0]{list-style-type:decimal}.list-disc[data-v-99cb95e0]{list-style-type:disc}@media(max-width:1023px){.list-disc[data-v-99cb95e0]{margin-top:calc(4/3*1em);margin-bottom:calc(4/3*1em);padding-left:var(--ms-flow-list-indent-mobile)}}.html-block-node__raw[data-v-e140a874]{white-space:pre-wrap;overflow-wrap:anywhere;opacity:.85}.html-block-node__placeholder[data-v-e140a874]{display:flex;flex-direction:column;gap:5.6px;padding:8px 0}.html-block-node__placeholder-bar[data-v-e140a874]{display:block;height:12.8px;border-radius:9999px;background-image:linear-gradient(90deg,var(--loading-shimmer),transparent,var(--loading-shimmer));background-size:200% 100%}.paragraph-node[data-v-c59ff506]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:var(--ms-flow-paragraph-y) 0}li .paragraph-node[data-v-c59ff506]{margin:0}.table-node-wrapper[data-v-39f87b5d]{position:relative;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;overscroll-behavior-y:auto;scrollbar-gutter:stable}.table-node[data-v-39f87b5d]{width:100%;table-layout:fixed;border-collapse:separate;border-spacing:0;margin:var(--ms-flow-table-y) 0;font-size:inherit;border:1px solid var(--table-border);border-radius:var(--ms-radius);overflow:hidden;box-shadow:var(--ms-shadow-subtle)}.table-node[data-v-39f87b5d] th,.table-node[data-v-39f87b5d] td{border-bottom:1px solid var(--table-border);border-right:1px solid var(--table-border);padding:var(--ms-flow-table-cell);white-space:normal;overflow-wrap:break-word;word-break:normal}.table-node[data-v-39f87b5d] th:last-child,.table-node[data-v-39f87b5d] td:last-child{border-right:none}.table-node[data-v-39f87b5d] tbody tr:last-child td{border-bottom:none}.table-node[data-v-39f87b5d] thead th{position:relative;font-weight:600;background-color:var(--table-header-bg);border-bottom-width:2px}.table-node__resize-handle[data-v-39f87b5d]{position:absolute;top:0;right:-4px;bottom:0;z-index:1;width:8px;padding:0;border:0;background:transparent;cursor:col-resize;touch-action:none}.table-node__resize-handle[data-v-39f87b5d]:after{content:"";position:absolute;top:.35em;bottom:.35em;left:50%;width:2px;border-radius:9999px;background:color-mix(in srgb,var(--table-border) 45%,hsl(var(--ms-foreground)));opacity:0;transform:translate(-50%);transition:opacity var(--ms-duration-fast) var(--ms-ease-standard)}.table-node__resize-handle[data-v-39f87b5d]:hover:after,.table-node__resize-handle[data-v-39f87b5d]:focus-visible:after{opacity:1}.table-node[data-v-39f87b5d] tbody tr:nth-child(2n){background-color:hsl(var(--ms-muted) / .35)}.table-node[data-v-39f87b5d] tbody tr:hover{background-color:var(--code-action-hover-bg)}.table-node--loading tbody td[data-v-39f87b5d]{position:relative;overflow:hidden}.table-node--loading tbody td[data-v-39f87b5d]>*{visibility:hidden}.table-node--loading tbody td[data-v-39f87b5d]:after{content:"";position:absolute;inset:0;border-radius:calc(var(--ms-radius) * .5);background:linear-gradient(90deg,var(--loading-shimmer) 25%,var(--loading-shimmer) 50%,var(--loading-shimmer) 75%);background-size:200% 100%;animation:table-node-shimmer-39f87b5d 1.2s linear infinite;will-change:background-position}.table-node__loading[data-v-39f87b5d]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}.table-node__spinner[data-v-39f87b5d]{width:40px;height:40px;border-radius:9999px;border:2px solid color-mix(in srgb,var(--loading-spinner) 25%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);will-change:transform}.table-node-fade-enter-active[data-v-39f87b5d],.table-node-fade-leave-active[data-v-39f87b5d]{transition:opacity var(--ms-duration-standard) var(--ms-ease-standard)}.table-node-fade-enter-from[data-v-39f87b5d],.table-node-fade-leave-to[data-v-39f87b5d]{opacity:0}[data-v-39f87b5d] .table-node .markdown-renderer{display:contents;content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}[data-v-39f87b5d] .table-node .markdown-renderer .node-slot,[data-v-39f87b5d] .table-node .markdown-renderer .node-content,[data-v-39f87b5d] .table-node .markdown-renderer .node-space{display:contents}[data-v-39f87b5d] .table-node .text-node,[data-v-39f87b5d] .table-node code{white-space:inherit;overflow-wrap:inherit;word-break:inherit;max-width:none}@keyframes table-node-shimmer-39f87b5d{0%{background-position:0% 0%}50%{background-position:100% 0%}to{background-position:200% 0%}}.hr+.table-node-wrapper[data-v-39f87b5d]{margin-top:0}.hr+.table-node-wrapper .table-node[data-v-39f87b5d]{margin-top:0}.sr-only[data-v-39f87b5d]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hr-node[data-v-39b2349c]{border-top-width:1px;border-color:var(--hr-border);margin:var(--ms-flow-hr-y) 0}.vmr-container[data-v-911e41c4]{margin-top:16px;margin-bottom:16px;border-radius:var(--ms-radius);border-width:1px;padding:16px;border-left-width:var(--ms-border-width-strong)}.height-estimation-probes[data-v-3e0766e2]{position:absolute;left:-100000px;top:0;visibility:hidden;pointer-events:none;overflow:hidden;z-index:-1}.node-content[data-v-3e0766e2]{width:100%}.node-content-flow-root[data-v-3e0766e2]{display:flow-root}.markdown-renderer[data-v-a9489508]{position:relative;contain:layout;content-visibility:auto;contain-intrinsic-size:800px 600px}.markdown-renderer.virtualized[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated[data-v-a9489508]{content-visibility:visible;contain-intrinsic-size:auto}.markdown-renderer.stable-layout[data-v-a9489508]{content-visibility:visible;contain-intrinsic-size:none}.node-slot[data-v-a9489508],.node-content[data-v-a9489508]{width:100%}.markdown-renderer.virtualized .node-slot[data-v-a9489508],.markdown-renderer.virtualized .node-content[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated .node-slot[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated .node-content[data-v-a9489508]{display:flow-root}.node-placeholder[data-v-a9489508]{width:100%;min-height:16px;margin:4px 0}.node-placeholder[data-v-a9489508]:first-child{margin-top:0}.node-spacer[data-v-a9489508]{width:100%}.unknown-node[data-v-a9489508]{color:hsl(var(--ms-muted-foreground));font-style:italic;margin:var(--ms-flow-paragraph-y) 0}.typewriter-cursor[data-v-a9489508]{position:absolute;left:0;top:0;display:inline-block;width:.55em;height:1em;margin-left:.08em;vertical-align:-.12em;border-right:2px solid currentColor;pointer-events:none;visibility:hidden;animation:typewriter-cursor-blink-a9489508 1s steps(1,end) infinite}@keyframes typewriter-cursor-blink-a9489508{0%,49%{opacity:1}50%,to{opacity:0}}.markstream-vue.typewriter-simple-cursor .typewriter-simple-cursor-target:after{content:"";display:inline-block;width:.55em;height:1em;margin-left:.08em;vertical-align:-.12em;border-right:2px solid currentColor;pointer-events:none;animation:typewriter-cursor-blink 1s steps(1,end) infinite}@media(prefers-reduced-motion:reduce){.markstream-vue.typewriter-simple-cursor .typewriter-simple-cursor-target:after{animation:none}}.markstream-vue .fade-enter-from{opacity:0}.markstream-vue .fade-enter-active{transition:opacity var(--fade-duration, .28s) var(--fade-ease, cubic-bezier(.33, 0, .67, 1));will-change:opacity}.markstream-vue .fade-enter-to{opacity:1}.admonition[data-v-a83480e1]{position:relative;margin:var(--ms-flow-admonition-y) 0;padding:.25em .75em .375em;border:1px solid var(--admonition-border);border-radius:var(--ms-radius);color:var(--admonition-fg)}.admonition-legend[data-v-a83480e1]{position:absolute;top:0;left:.75em;transform:translateY(-50%);display:inline-flex;align-items:center;gap:.35em;padding:0 .5em;background-color:hsl(var(--ms-background));font-size:13px;font-weight:600;line-height:1}.admonition-icon[data-v-a83480e1]{flex-shrink:0}.admonition-title[data-v-a83480e1]{white-space:nowrap}.admonition-content[data-v-a83480e1]{padding-top:.25em;color:var(--admonition-fg)}.admonition-note[data-v-a83480e1],.admonition-info[data-v-a83480e1]{border-color:hsl(var(--ms-info) / .3);background-color:hsl(var(--ms-info) / .04)}.admonition-note .admonition-legend[data-v-a83480e1],.admonition-info .admonition-legend[data-v-a83480e1]{color:var(--admonition-note)}.admonition-tip[data-v-a83480e1]{border-color:hsl(var(--ms-success) / .3);background-color:hsl(var(--ms-success) / .04)}.admonition-tip .admonition-legend[data-v-a83480e1]{color:var(--admonition-tip)}.admonition-warning[data-v-a83480e1],.admonition-caution[data-v-a83480e1]{border-color:hsl(var(--ms-warning) / .3);background-color:hsl(var(--ms-warning) / .04)}.admonition-warning .admonition-legend[data-v-a83480e1],.admonition-caution .admonition-legend[data-v-a83480e1]{color:var(--admonition-warning)}.admonition-danger[data-v-a83480e1],.admonition-error[data-v-a83480e1]{border-color:hsl(var(--ms-destructive) / .3);background-color:hsl(var(--ms-destructive) / .04)}.admonition-danger .admonition-legend[data-v-a83480e1],.admonition-error .admonition-legend[data-v-a83480e1]{color:var(--admonition-danger)}.admonition-toggle[data-v-a83480e1]{margin-left:.25em;background:transparent;border:none;color:inherit;cursor:pointer;padding:2px;border-radius:calc(var(--ms-radius) * .5);display:inline-flex;align-items:center;transition:background-color var(--ms-duration-fast) var(--ms-ease-standard)}.admonition-toggle[data-v-a83480e1]:hover{background-color:hsl(var(--ms-accent))}.admonition-toggle[data-v-a83480e1]:focus-visible{outline:var(--ms-focus-ring-width) solid var(--focus-ring);outline-offset:var(--ms-focus-ring-offset)}.admonition-content[data-v-a83480e1] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.tooltip-element[data-v-c606ee4c]{z-index:9999;display:inline-block;max-width:320px;padding:4px 8px;border-radius:calc(var(--ms-radius) * .75);font-size:12px;line-height:1.4;white-space:normal;word-break:break-word;pointer-events:none;background-color:var(--tooltip-bg);color:var(--tooltip-fg);box-shadow:inset 0 1px #ffffff26,0 0 0 1px #0000001f,var(--ms-shadow-popover);transition:transform var(--ms-duration-emphasis) var(--ms-ease-spring),box-shadow var(--ms-duration-emphasis) var(--ms-ease-spring)}.tooltip-arrow[data-v-c606ee4c]{position:absolute;width:6px;height:6px;background:inherit;transform:rotate(45deg)}.tooltip-arrow[data-placement^=top][data-v-c606ee4c]{bottom:-3px}.tooltip-arrow[data-placement^=bottom][data-v-c606ee4c]{top:-3px}.tooltip-arrow[data-placement^=left][data-v-c606ee4c]{right:-3px}.tooltip-arrow[data-placement^=right][data-v-c606ee4c]{left:-3px}.tooltip-enter-active[data-v-c606ee4c]{transition:opacity .18s cubic-bezier(.16,1,.3,1),transform .18s cubic-bezier(.16,1,.3,1)}.tooltip-leave-active[data-v-c606ee4c]{transition:opacity .12s ease-in,transform .12s ease-in}.tooltip-enter-from[data-v-c606ee4c]{opacity:0;transform:scale(.96)}.tooltip-enter-to[data-v-c606ee4c],.tooltip-leave-from[data-v-c606ee4c]{opacity:1;transform:scale(1)}.tooltip-leave-to[data-v-c606ee4c]{opacity:0;transform:scale(.97)}.action-icon{width:var(--ms-action-btn-icon, 14px);height:var(--ms-action-btn-icon, 14px);max-width:20px;max-height:20px}.code-block-container{margin:var(--ms-flow-codeblock-y) 0;contain:layout style;container-type:inline-size;background:var(--code-bg);border-color:var(--code-border);color:var(--code-fg);box-shadow:var(--ms-shadow-subtle)}.code-block-header{position:relative;z-index:1;gap:var(--ms-gap-header);border-radius:var(--ms-radius) var(--ms-radius) 0 0;overflow:visible}.code-block-header .code-header-main{min-width:0;flex:1 1 auto;display:flex;align-items:center;gap:var(--ms-gap-header-main);overflow:hidden}.code-block-header .code-header-copy{min-width:0;display:grid;gap:2px}.code-block-header .code-header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ms-text-label);font-weight:500;color:var(--code-action-fg)}.code-block-header .code-header-caption{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--code-line-number)}.code-block-header .code-header-actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--ms-gap-header-actions);flex-wrap:wrap}.code-block-header .icon-slot{display:inline-flex;align-items:center;justify-content:center}.code-block-header .icon-slot svg,.code-block-header .icon-slot img{display:block;width:100%;height:100%}.code-diff-stats{display:inline-flex;align-items:center;gap:var(--ms-space-1_5);margin-right:var(--ms-space-1);font-size:var(--ms-text-label);font-weight:600;line-height:1;font-variant-numeric:tabular-nums}.code-diff-stat{display:inline-flex;align-items:center;padding:2px 6px;border-radius:var(--ms-radius);line-height:1}.code-diff-stat.removed{color:var(--diff-removed-fg);background:hsl(var(--ms-diff-removed) / .1)}.code-diff-stat.added{color:var(--diff-added-fg);background:hsl(var(--ms-diff-added) / .1)}.code-more-menu{position:absolute;top:100%;right:0;margin-top:4px;z-index:50;border-radius:var(--ms-radius)}.code-block-shell-content,.code-loading-placeholder{overflow:hidden;border-radius:0 0 var(--ms-radius) var(--ms-radius);contain:content}.code-block-shell-content--collapsed{height:0;min-height:0;visibility:hidden;pointer-events:none}.code-menu-enter-active,.code-menu-leave-active{transform-origin:top right}.code-menu-enter-active{transition:opacity .22s cubic-bezier(.16,1,.3,1),transform .22s cubic-bezier(.16,1,.3,1)}.code-menu-leave-active{transition:opacity .14s ease-in,transform .14s ease-in}.code-menu-enter-from{opacity:0;transform:scale(.9) translateY(-4px)}.code-menu-leave-to{opacity:0;transform:scale(.95) translateY(-2px)}.html-preview-frame__backdrop[data-v-24e66176]{position:fixed;inset:0;background-color:var(--modal-overlay);display:flex;align-items:center;justify-content:center;z-index:50}.html-preview-frame[data-v-24e66176]{width:80vw;max-width:960px;height:70vh;background-color:var(--modal-bg);color:var(--modal-fg);border-radius:calc(var(--ms-radius) * 2);overflow:hidden;box-shadow:var(--ms-shadow-preview);display:flex;flex-direction:column}.html-preview-frame__header[data-v-24e66176]{display:flex;justify-content:space-between;align-items:center;padding:6.4px 12px;border-bottom:1px solid var(--code-border)}.html-preview-frame__title[data-v-24e66176]{display:inline-flex;align-items:center;gap:6.4px;font-size:12px;font-weight:500;letter-spacing:.02em;text-transform:uppercase;opacity:.85}.html-preview-frame__dot[data-v-24e66176]{width:8px;height:8px;border-radius:999px;background-color:hsl(var(--ms-success))}.html-preview-frame__label[data-v-24e66176]{white-space:nowrap}.html-preview-frame__close[data-v-24e66176]{border:none;background:transparent;font-size:20px;line-height:1;cursor:pointer;color:var(--modal-fg)}.html-preview-frame__iframe[data-v-24e66176]{width:100%;height:100%;border:none;display:block}@media(max-width:640px){.html-preview-frame[data-v-24e66176]{width:100vw;height:80vh;border-radius:0}}.code-block-container[data-v-ef6e4bb8]{--markstream-code-fallback-bg: var(--code-bg);--markstream-code-fallback-fg: var(--code-fg);--markstream-code-border-color: var(--code-border);--vscode-editor-selectionBackground: var(--markstream-code-fallback-selection-bg);--markstream-code-fallback-selection-bg: var(--code-selection-bg);--markstream-diff-frame-border: var(--code-border);--markstream-diff-frame-shadow: 0 16px 40px -32px hsl(var(--ms-foreground) / .18);--markstream-diff-shell-fg: hsl(var(--ms-foreground));--markstream-diff-shell-muted: hsl(var(--ms-muted-foreground));--markstream-diff-shell-border: var(--code-border);--markstream-diff-shell-shadow: var(--ms-shadow-subtle);--markstream-diff-shell-bg: var(--code-bg);--markstream-diff-header-border: hsl(var(--ms-border) / .92);--markstream-diff-editor-bg: hsl(var(--ms-background));--markstream-diff-editor-fg: hsl(var(--ms-foreground));--markstream-diff-unchanged-fg: hsl(var(--ms-foreground));--markstream-diff-unchanged-bg: hsl(var(--ms-muted));--markstream-diff-unchanged-divider: hsl(var(--ms-background) / .94);--markstream-diff-focus: var(--focus-ring);--markstream-diff-widget-shadow: hsl(var(--ms-foreground) / .26);--markstream-diff-action-hover: var(--code-action-hover-bg);--markstream-diff-panel-bg: linear-gradient(180deg, var(--code-bg) 0%, hsl(var(--ms-muted)) 100%);--markstream-diff-panel-bg-soft: var(--code-bg);--markstream-diff-panel-bg-strong: var(--code-bg);--markstream-diff-panel-border: hsl(var(--ms-border) / .3);--markstream-diff-pane-divider: hsl(var(--ms-border) / .42);--markstream-diff-gutter-bg: transparent;--markstream-diff-gutter-guide: hsl(var(--ms-border) / .72);--markstream-diff-gutter-gap: 8px;--markstream-diff-line-number-bg: hsl(var(--ms-muted) / .45);--markstream-diff-line-number: var(--code-line-number);--markstream-diff-line-number-active: var(--code-line-number);--markstream-diff-added-fg: var(--diff-added-fg);--markstream-diff-removed-fg: var(--diff-removed-fg);--markstream-diff-added-line: var(--diff-added-bg);--markstream-diff-removed-line: var(--diff-removed-bg);--markstream-diff-added-inline: var(--diff-added-inline-bg);--markstream-diff-removed-inline: var(--diff-removed-inline-bg);--markstream-diff-added-inline-border: transparent;--markstream-diff-removed-inline-border: transparent;--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--stream-monaco-gutter-marker-width, 4px), transparent var(--stream-monaco-gutter-marker-width, 4px) 100% );--markstream-diff-removed-gutter: repeating-linear-gradient( 180deg, var(--markstream-diff-removed-fg) 0 2px, transparent 2px 4px ) left / var(--stream-monaco-gutter-marker-width, 4px) 100% no-repeat;--markstream-diff-added-line-fill: var(--diff-added-bg);--markstream-diff-removed-line-fill: var(--diff-removed-bg)}.code-block-container.is-dark[data-v-ef6e4bb8]{--markstream-code-fallback-bg: var(--code-bg);--markstream-code-fallback-fg: var(--code-fg);--markstream-code-border-color: var(--code-border);--markstream-code-fallback-selection-bg: var(--code-selection-bg);--markstream-diff-frame-border: var(--code-border);--markstream-diff-frame-shadow: 0 18px 40px -30px hsl(var(--ms-foreground) / .84);--markstream-diff-shell-fg: hsl(var(--ms-foreground));--markstream-diff-shell-muted: hsl(var(--ms-muted-foreground));--markstream-diff-shell-border: var(--code-border);--markstream-diff-shell-shadow: var(--ms-shadow-subtle);--markstream-diff-shell-bg: var(--code-bg);--markstream-diff-header-border: hsl(var(--ms-border) / .82);--markstream-diff-editor-bg: #121212;--markstream-diff-editor-fg: #e5e5e5;--markstream-diff-unchanged-fg: #d4d4d4;--markstream-diff-unchanged-bg: #262626;--markstream-diff-unchanged-divider: hsl(0 0% 100% / .08);--markstream-diff-focus: var(--focus-ring);--markstream-diff-widget-shadow: hsl(var(--ms-foreground) / .72);--markstream-diff-action-hover: var(--code-action-hover-bg);--markstream-diff-panel-bg: #121212;--markstream-diff-panel-bg-soft: #121212;--markstream-diff-panel-bg-strong: #121212;--markstream-diff-panel-border: hsl(var(--ms-border) / .3);--markstream-diff-pane-divider: hsl(var(--ms-border) / .34);--markstream-diff-gutter-bg: linear-gradient( 180deg, hsl(0 0% 7% / .94) 0%, hsl(0 0% 7% / .98) 100% );--markstream-diff-gutter-guide: hsl(var(--ms-muted-foreground) / .08);--markstream-diff-gutter-gap: 8px;--markstream-diff-line-number-bg: hsl(0 0% 7% / .98);--markstream-diff-line-number: var(--code-line-number);--markstream-diff-line-number-active: var(--code-line-number);--markstream-diff-added-fg: hsl(152 42% 60%);--markstream-diff-removed-fg: hsl(0 58% 58%);--markstream-diff-added-line: hsl(152 42% 60% / .18);--markstream-diff-removed-line: hsl(0 58% 58% / .18);--markstream-diff-added-inline: hsl(152 42% 60% / .28);--markstream-diff-removed-inline: hsl(0 58% 58% / .28);--markstream-diff-added-inline-border: transparent;--markstream-diff-removed-inline-border: transparent;--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--stream-monaco-gutter-marker-width, 4px), transparent var(--stream-monaco-gutter-marker-width, 4px) 100% );--markstream-diff-removed-gutter: repeating-linear-gradient( 180deg, var(--markstream-diff-removed-fg) 0 2px, transparent 2px 4px ) left / var(--stream-monaco-gutter-marker-width, 4px) 100% no-repeat;--markstream-diff-added-line-fill: hsl(152 42% 60% / .18);--markstream-diff-removed-line-fill: hsl(0 58% 58% / .18)}.code-editor-container[data-v-ef6e4bb8]{transition:none;box-sizing:border-box;min-width:0;width:100%}.code-block-container.is-diff .code-editor-container[data-v-ef6e4bb8]{transition:none}.code-editor-layer[data-v-ef6e4bb8]{display:grid;min-width:0;position:relative}.code-editor-layer--collapsed[data-v-ef6e4bb8]{height:0;min-height:0;overflow:hidden;visibility:hidden;pointer-events:none}.code-editor-layer>.code-editor-container[data-v-ef6e4bb8]{grid-area:1 / 1;z-index:1}.code-editor-layer>pre.code-pre-fallback[data-v-ef6e4bb8]{grid-area:1 / 1;position:relative;z-index:2}.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .monaco-editor-background,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .margin,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .lines-content{background:var(--vscode-editor-background, var(--markstream-code-fallback-bg))!important}.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .margin,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .view-lines,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .view-line,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .view-line span,.code-block-container.is-plain-text[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .line-numbers{color:var(--vscode-editor-foreground, var(--markstream-code-fallback-fg))!important}.code-block-container.is-diff[data-v-ef6e4bb8]{color:var(--markstream-diff-shell-fg);border-color:var(--markstream-diff-shell-border);background:var(--markstream-diff-shell-bg);box-shadow:var(--markstream-diff-shell-shadow);--vscode-editor-selectionBackground: var(--markstream-diff-action-hover);--code-fg: var(--markstream-diff-shell-fg);--code-header-bg: transparent;--code-border: var(--markstream-diff-header-border);--code-line-number: var(--markstream-diff-shell-muted);--code-action-fg: var(--markstream-diff-shell-muted)}.code-block-container.is-diff .code-editor-layer[data-v-ef6e4bb8]{background:transparent;--vscode-editor-background: var(--markstream-diff-editor-bg);--vscode-editor-foreground: var(--markstream-diff-editor-fg);--vscode-diffEditor-unchangedRegionForeground: var(--markstream-diff-unchanged-fg);--vscode-diffEditor-unchangedRegionBackground: var(--markstream-diff-unchanged-bg);--vscode-focusBorder: var(--markstream-diff-focus);--vscode-widget-shadow: var(--markstream-diff-widget-shadow);--vscode-editor-selectionBackground: color-mix( in srgb, var(--markstream-diff-editor-bg) 90%, var(--markstream-diff-editor-fg) 10% );--stream-monaco-editor-bg: var(--markstream-diff-editor-bg);--stream-monaco-editor-fg: var(--markstream-diff-editor-fg);--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg);--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg);--stream-monaco-frame-radius: 0;--stream-monaco-fixed-editor-bg: var(--markstream-diff-editor-bg);--stream-monaco-frame-border: transparent;--stream-monaco-frame-shadow: none;--stream-monaco-panel-bg: var(--markstream-diff-editor-bg);--stream-monaco-panel-bg-soft: var(--markstream-diff-editor-bg);--stream-monaco-panel-bg-strong: var(--markstream-diff-editor-bg);--stream-monaco-panel-border: transparent;--stream-monaco-pane-divider: var(--markstream-diff-pane-divider);--stream-monaco-gutter-bg: var(--markstream-diff-gutter-bg);--stream-monaco-gutter-guide: var(--markstream-diff-gutter-guide);--stream-monaco-gutter-marker-width: 4px;--stream-monaco-gutter-gap: 1ch;--stream-monaco-line-number-bg: var(--markstream-diff-line-number-bg);--stream-monaco-line-number: var(--markstream-diff-line-number);--stream-monaco-line-number-active: var(--markstream-diff-line-number-active);--stream-monaco-line-number-left: 0px;--stream-monaco-line-number-width: 2ch;--stream-monaco-line-number-padding-left: 2ch;--stream-monaco-line-number-padding-right: 1ch;--stream-monaco-line-number-separator-width: 2px;--stream-monaco-layout-character-width: var(--markstream-code-layout-character-width, 1ch);--stream-monaco-line-number-box-width: calc( var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-line-number-separator-width) );--stream-monaco-diff-code-gap: 1ch;--stream-monaco-diff-code-padding: 0px;--stream-monaco-line-number-gap-to-code: var(--stream-monaco-diff-code-gap);--stream-monaco-line-number-align: var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) );--stream-monaco-original-margin-width: calc( var(--stream-monaco-line-number-left) + var(--stream-monaco-line-number-box-width) + var(--stream-monaco-line-number-gap-to-code) );--stream-monaco-original-scrollable-left: var(--stream-monaco-original-margin-width);--stream-monaco-original-scrollable-width: calc( 100% - var(--stream-monaco-original-margin-width) );--stream-monaco-modified-margin-width: calc( var(--stream-monaco-line-number-left) + var(--stream-monaco-line-number-box-width) + var(--stream-monaco-line-number-gap-to-code) );--stream-monaco-modified-scrollable-left: var(--stream-monaco-modified-margin-width);--stream-monaco-modified-scrollable-width: calc( 100% - var(--stream-monaco-modified-margin-width) );--stream-monaco-added-fg: var(--markstream-diff-added-fg);--stream-monaco-removed-fg: var(--markstream-diff-removed-fg);--stream-monaco-added-line: var(--markstream-diff-added-line);--stream-monaco-removed-line: var(--markstream-diff-removed-line);--stream-monaco-added-inline: var(--markstream-diff-added-inline);--stream-monaco-removed-inline: var(--markstream-diff-removed-inline);--stream-monaco-added-outline: transparent;--stream-monaco-removed-outline: transparent;--stream-monaco-added-inline-border: var(--markstream-diff-added-inline-border);--stream-monaco-removed-inline-border: var(--markstream-diff-removed-inline-border);--stream-monaco-added-line-shadow: none;--stream-monaco-removed-line-shadow: none;--stream-monaco-added-gutter: var(--markstream-diff-added-gutter);--stream-monaco-removed-gutter: var(--markstream-diff-removed-gutter);--stream-monaco-added-line-fill: var(--markstream-diff-added-line-fill);--stream-monaco-removed-line-fill: var(--markstream-diff-removed-line-fill);--stream-monaco-added-border: hsl(var(--ms-diff-added) / .25);--stream-monaco-removed-border: hsl(var(--ms-diff-removed) / .25);--stream-monaco-widget-shadow: var(--markstream-diff-widget-shadow)}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers{left:var(--stream-monaco-line-number-left)!important;width:var(--stream-monaco-line-number-width)!important;min-width:var(--stream-monaco-line-number-width)!important;box-sizing:content-box!important;background:var(--stream-monaco-line-number-bg, var(--markstream-diff-line-number-bg))!important;padding-left:var(--stream-monaco-line-number-padding-left, 2ch)!important;padding-right:var(--stream-monaco-line-number-padding-right, 1ch)!important;border-right:var(--stream-monaco-line-number-separator-width, 2px) solid var(--stream-monaco-editor-bg)!important;text-align:var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) )!important;font-variant-numeric:tabular-nums;box-shadow:none}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin-view-overlays .line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin-view-overlays .line-numbers *{text-align:var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) )!important;font-variant-numeric:tabular-nums}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.original .margin-view-overlays .line-delete.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.modified .margin-view-overlays .line-delete.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .line-delete.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers.stream-monaco-line-number-delete,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers.stream-monaco-line-number-delete,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-editor .stream-monaco-fallback-line-number-delete,.code-block-container.is-diff[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-native-stale .monaco-diff-editor .line-delete.line-numbers{background:var(--stream-monaco-removed-line-fill)!important;color:var(--stream-monaco-removed-fg)!important;box-shadow:none!important}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.original .margin-view-overlays .line-insert.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.modified .margin-view-overlays .line-insert.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .line-insert.line-numbers,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers.stream-monaco-line-number-insert,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers.stream-monaco-line-number-insert,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-editor .stream-monaco-fallback-line-number-insert,.code-block-container.is-diff[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-native-stale .monaco-diff-editor .line-insert.line-numbers{background:var(--stream-monaco-added-line-fill)!important;color:var(--stream-monaco-added-fg)!important;box-shadow:none!important}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .monaco-editor,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin,.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin-view-overlays{--stream-monaco-line-number-align: var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) ) !important}.code-block-container[data-v-ef6e4bb8]:not(.is-diff){--markstream-code-line-number-box-width: calc( var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + 2px );--markstream-code-content-left: calc( var(--markstream-code-line-number-box-width) + var(--markstream-code-layout-character-width, 1ch) )}.code-block-container[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .margin,.code-block-container[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .margin-view-overlays{width:var(--markstream-code-content-left)!important}.code-block-container[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .line-numbers{left:0!important;width:2ch!important;min-width:2ch!important;box-sizing:content-box!important;padding-left:2ch!important;padding-right:1ch!important;border-right:2px solid var(--vscode-editor-background)!important;text-align:var(--markstream-code-line-number-align, right)!important;font-variant-numeric:tabular-nums}.code-block-container[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .monaco-scrollable-element.editor-scrollable{left:var(--markstream-code-content-left)!important;width:calc(100% - var(--markstream-code-content-left))!important}.code-block-container[data-v-ef6e4bb8]:not(.is-diff) .monaco-editor .lines-content{left:0!important}.code-editor-container[data-markstream-host-hidden=true][data-v-ef6e4bb8]{position:absolute;inset:0;width:100%;height:100%!important;min-height:0!important;max-height:none!important;overflow:hidden;visibility:hidden;pointer-events:none}pre.code-pre-fallback[data-v-ef6e4bb8]{margin:0;box-sizing:border-box;width:100%;padding:var(--markstream-code-padding-y, 8px) var(--markstream-code-padding-x, 12px);padding-left:var(--markstream-code-padding-left, 52px);background:var(--markstream-code-fallback-bg, var(--code-bg, #fff));color:var(--markstream-code-fallback-fg, var(--code-fg));backface-visibility:visible;transform:none;-webkit-font-smoothing:auto;font-size:var(--vscode-editor-font-size, 12px);line-height:var(--vscode-editor-line-height, 18px);font-weight:400;font-family:var( --markstream-code-font-family, Menlo, Monaco, Courier New, monospace )}pre.code-pre-fallback[data-v-ef6e4bb8] code{font-size:inherit;font-weight:inherit;line-height:inherit;font-family:inherit}pre.code-pre-fallback.is-wrap[data-v-ef6e4bb8]{white-space:pre-wrap;overflow-wrap:anywhere}pre.code-pre-fallback.markstream-pre--diff-preview[data-v-ef6e4bb8]{padding-left:0;padding-right:0}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview{background:var(--markstream-diff-editor-bg);transition:none}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-pane{box-sizing:border-box;padding-bottom:var(--markstream-pre-diff-pane-bottom-padding, 0px)}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane{padding-bottom:var(--markstream-pre-diff-pane-bottom-padding, 0px)}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added:after,.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-number{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))!important}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed:after,.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-number{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))!important}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-rail{background:var(--stream-monaco-added-gutter, var(--markstream-diff-added-gutter, currentColor))!important}.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-rail{background:var(--stream-monaco-removed-gutter, var(--markstream-diff-removed-gutter, currentColor))!important}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin-view-overlays>.gutter-insert>.cmdr.gutter-insert{background:linear-gradient(90deg,transparent 0 var(--stream-monaco-line-number-box-width),var(--stream-monaco-added-line-fill) var(--stream-monaco-line-number-box-width) 100%)!important}.code-block-container.is-diff[data-v-ef6e4bb8] .monaco-diff-editor .margin-view-overlays>.gutter-delete>.cmdr.gutter-delete{background:linear-gradient(90deg,transparent 0 var(--stream-monaco-line-number-box-width),var(--stream-monaco-removed-line-fill) var(--stream-monaco-line-number-box-width) 100%)!important}@media(prefers-reduced-motion:reduce){.code-block-container.is-diff[data-v-ef6e4bb8] pre.code-pre-fallback.markstream-pre--diff-preview{transition:none}}.code-block-container.is-rendering .code-height-placeholder[data-v-ef6e4bb8]{background-size:400% 100%;animation:code-skeleton-shimmer-ef6e4bb8 1.2s ease-in-out infinite;min-height:var(--ms-size-skeleton-min-height);background:linear-gradient(90deg,var(--loading-shimmer) 25%,hsl(var(--ms-muted) / .7) 37%,var(--loading-shimmer) 63%)}.code-loading-placeholder[data-v-ef6e4bb8]{padding:16px;min-height:var(--ms-size-skeleton-min-height)}.loading-skeleton[data-v-ef6e4bb8]{display:flex;flex-direction:column;gap:12px}.skeleton-line[data-v-ef6e4bb8]{height:16px;background:linear-gradient(90deg,var(--loading-shimmer) 25%,hsl(var(--ms-muted) / .7) 37%,var(--loading-shimmer) 63%);background-size:400% 100%;animation:code-skeleton-shimmer-ef6e4bb8 1.2s ease-in-out infinite;border-radius:calc(var(--ms-radius) * .5)}.skeleton-line.short[data-v-ef6e4bb8]{width:60%}.code-block-container[data-markstream-viewport-pending=true] .code-height-placeholder[data-v-ef6e4bb8],.code-block-container[data-markstream-viewport-pending=true] .skeleton-line[data-v-ef6e4bb8]{animation:none}@keyframes code-skeleton-shimmer-ef6e4bb8{0%{background-position:100% 0}to{background-position:0 0}}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center{border-radius:var(--ms-radius)!important;background:transparent!important;border:1px solid transparent!important;box-shadow:none!important;min-height:28px!important;transition:background-color .14s ease,border-color .14s ease!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:hover,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center.stream-monaco-focus-within{background:color-mix(in srgb,var(--stream-monaco-editor-fg) 4%,transparent)!important;border-color:color-mix(in srgb,var(--stream-monaco-editor-fg) 10%,transparent)!important;box-shadow:none!important}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center{background:transparent!important;border-color:transparent!important;box-shadow:none!important}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center:hover,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center.stream-monaco-focus-within{background:color-mix(in srgb,var(--stream-monaco-editor-fg) 6%,transparent)!important;border-color:color-mix(in srgb,var(--stream-monaco-editor-fg) 12%,transparent)!important;box-shadow:none!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center .stream-monaco-unchanged-count:before{content:"";display:inline-block;width:14px;height:14px;margin-right:4px;flex-shrink:0;background:currentColor;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5'/%3E%3Cpath d='m7 9 5-5 5 5'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5'/%3E%3Cpath d='m7 9 5-5 5 5'/%3E%3C/svg%3E");mask-size:contain;-webkit-mask-size:contain;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat}[data-v-ef6e4bb8] .monaco-diff-editor .diffOverview{background-color:var(--vscode-editor-background)}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor .diffOverview,[data-v-ef6e4bb8] .stream-monaco-diff-root .decorationsOverviewRuler{display:none!important;width:0!important;min-width:0!important;max-width:0!important;border:0!important;background:transparent!important;opacity:0!important;pointer-events:none!important;overflow:hidden!important}[data-v-ef6e4bb8] .code-block-container .stream-monaco-diff-root .monaco-diff-editor{border:0!important;border-radius:0!important;box-shadow:none!important}[data-v-ef6e4bb8] .code-block-container .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:not(.stream-monaco-clickable)>*:not(a){visibility:hidden!important}[data-v-ef6e4bb8] .code-block-container .stream-monaco-diff-root .monaco-editor .diff-hidden-lines-compact .text{opacity:0!important}[data-v-ef6e4bb8] .stream-monaco-diff-root{--stream-monaco-gutter-guide: var(--markstream-diff-gutter-guide) !important;--stream-monaco-gutter-gap: var(--markstream-diff-gutter-gap) !important;--stream-monaco-line-number: var(--markstream-diff-line-number) !important;--stream-monaco-line-number-active: var(--markstream-diff-line-number-active) !important;--stream-monaco-added-fg: var(--markstream-diff-added-fg) !important;--stream-monaco-removed-fg: var(--markstream-diff-removed-fg) !important;--stream-monaco-added-line: var(--markstream-diff-added-line) !important;--stream-monaco-removed-line: var(--markstream-diff-removed-line) !important;--stream-monaco-added-inline: var(--markstream-diff-added-inline) !important;--stream-monaco-removed-inline: var(--markstream-diff-removed-inline) !important;--stream-monaco-added-inline-border: var(--markstream-diff-added-inline-border) !important;--stream-monaco-removed-inline-border: var(--markstream-diff-removed-inline-border) !important;--stream-monaco-added-line-fill: var(--markstream-diff-added-line-fill) !important;--stream-monaco-removed-line-fill: var(--markstream-diff-removed-line-fill) !important;--stream-monaco-added-gutter: var(--markstream-diff-added-gutter) !important;--stream-monaco-removed-gutter: var(--markstream-diff-removed-gutter) !important;--stream-monaco-added-line-shadow: none !important;--stream-monaco-removed-line-shadow: none !important;--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg) !important;--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg) !important;box-sizing:border-box;min-width:0;width:100%}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .monaco-editor,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .overflow-guard,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side),[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .monaco-editor,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .overflow-guard{min-width:0!important;width:100%!important}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .monaco-scrollable-element.editor-scrollable,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .monaco-scrollable-element.editor-scrollable{left:var(--stream-monaco-modified-scrollable-left, var(--stream-monaco-modified-margin-width))!important;width:calc(100% - var(--stream-monaco-modified-scrollable-left, var(--stream-monaco-modified-margin-width)))!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor .editor.modified .view-lines .view-line.stream-monaco-line-insert-fill,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor .editor.original .view-lines .view-line.stream-monaco-line-delete-fill{width:1000000px!important}.code-block-container.is-diff[data-v-ef6e4bb8] .stream-monaco-fallback-inline-delete-line{box-sizing:border-box;padding-left:var(--stream-monaco-diff-code-padding, 0px)}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .scrollbar.horizontal,[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .scrollbar.horizontal{display:none!important;height:0!important}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .view-lines.line-delete{margin-left:0!important;width:100%!important;background:var(--stream-monaco-removed-line-fill)!important;box-shadow:var(--stream-monaco-removed-line-shadow)!important;display:block!important;height:-moz-max-content!important;height:max-content!important;min-height:18px!important;overflow:visible!important}[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .gutter-delete,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .inline-deleted-margin-view-zone,[data-v-ef6e4bb8] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .stream-monaco-fallback-inline-delete-margin{background:var(--stream-monaco-removed-gutter),var(--stream-monaco-removed-line-fill)!important;display:block!important;height:100%!important;min-height:18px!important;overflow:visible!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:not(.stream-monaco-unchanged-bridge-source),[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge{--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg) !important;--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg) !important;background:var(--stream-monaco-unchanged-bg)!important;color:var(--stream-monaco-unchanged-fg)!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge{right:calc(var(--stream-monaco-gutter-marker-width) - var(--stream-monaco-unchanged-rail-width) / 2 + (var(--stream-monaco-gutter-gap) * 2))!important;width:auto!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary:hover,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary:focus-visible,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary.stream-monaco-focus-visible{background:var(--stream-monaco-unchanged-bg)!important;color:var(--markstream-diff-unchanged-fg)!important;padding-left:calc(var(--stream-monaco-gutter-marker-width) + (var(--stream-monaco-gutter-gap) * 2))!important;padding-right:calc(var(--stream-monaco-gutter-marker-width) + (var(--stream-monaco-gutter-gap) * 2))!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge.stream-monaco-diff-unchanged-bridge-line-info .stream-monaco-unchanged-rail,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:hover,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:focus-visible,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal.stream-monaco-focus-visible{background:var(--stream-monaco-unchanged-bg)!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail{border-right-color:var(--markstream-diff-unchanged-divider)!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal{border-bottom-color:transparent!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-both .stream-monaco-unchanged-reveal:first-child{border-bottom-color:var(--markstream-diff-unchanged-divider)!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-top-only .stream-monaco-unchanged-reveal,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-bottom-only .stream-monaco-unchanged-reveal{border-bottom:0!important}[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-meta,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-count,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-metadata-label,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:hover,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:focus-visible,[data-v-ef6e4bb8] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal.stream-monaco-focus-visible{color:var(--markstream-diff-unchanged-fg)!important}[data-v-ef6e4bb8] .monaco-diff-editor:not(.side-by-side) .editor.original .diff-hidden-lines .center{align-items:center;justify-content:center}[data-v-ef6e4bb8] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center{align-items:center;justify-content:center!important;position:relative}[data-v-ef6e4bb8] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center:not(.stream-monaco-clickable){opacity:0!important;pointer-events:none!important}[data-v-ef6e4bb8] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center .stream-monaco-unchanged-meta{justify-content:center!important;padding:0 28px!important}[data-v-ef6e4bb8] .monaco-diff-editor:not(.side-by-side) .editor.original .diff-hidden-lines .center>div:first-child{align-items:center;display:flex;justify-content:center!important;min-width:100%;width:100%!important}[data-v-ef6e4bb8] .markstream-inline-fold-proxy{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;border-radius:calc(var(--ms-radius) * .5);box-shadow:none;cursor:pointer;inset:0;padding:0;pointer-events:auto;position:absolute;z-index:2}[data-v-ef6e4bb8] .markstream-inline-fold-proxy:hover,[data-v-ef6e4bb8] .markstream-inline-fold-proxy:focus-visible{background:transparent}[data-v-ef6e4bb8] .markstream-inline-fold-proxy:focus-visible{outline:1px solid var(--vscode-focusBorder, currentColor);outline-offset:-1px}.math-inline-wrapper[data-v-6c556261]{position:relative;display:inline-block}.math-inline[data-v-6c556261]{display:inline-block;vertical-align:middle}.math-inline--fallback[data-v-6c556261]{white-space:pre-wrap}.math-inline__loading[data-v-6c556261]{display:inline-flex;align-items:center;justify-content:center;pointer-events:none}.math-inline__spinner[data-v-6c556261]{width:16px;height:16px;border-radius:9999px;border:2px solid color-mix(in srgb,var(--loading-spinner) 25%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);will-change:transform}.table-node-fade-enter-active[data-v-6c556261],.table-node-fade-leave-active[data-v-6c556261]{transition:opacity var(--ms-duration-standard) var(--ms-ease-standard)}.table-node-fade-enter-from[data-v-6c556261],.table-node-fade-leave-to[data-v-6c556261]{opacity:0}.sr-only[data-v-6c556261]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.math-block[data-v-939191ad]{min-height:var(--ms-size-math-min-height);transition:min-height var(--ms-duration-overlay) var(--ms-ease-standard)}.math-loading-overlay[data-v-939191ad]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(2px);min-height:var(--ms-size-math-min-height)}.math-loading-spinner[data-v-939191ad]{width:20px;height:20px;border:2px solid color-mix(in srgb,var(--loading-spinner) 15%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);border-radius:50%;animation:math-spin-939191ad .8s linear infinite}@keyframes math-spin-939191ad{to{transform:rotate(360deg)}}.math-rendering[data-v-939191ad]{opacity:.3;transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.math-block__fallback[data-v-939191ad]{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.math-fade-enter-active[data-v-939191ad],.math-fade-leave-active[data-v-939191ad]{transition:all var(--ms-duration-slow) var(--ms-ease-standard)}.math-fade-enter-from[data-v-939191ad],.math-fade-leave-to[data-v-939191ad]{opacity:0}.action-icon{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.icon-slot{display:inline-flex;align-items:center;justify-content:center}.icon-slot svg{display:block;width:100%;height:100%}.mermaid-block-container[data-v-73c385f8]{margin:var(--ms-flow-diagram-y) 0;border-color:var(--diagram-border)}.mermaid-block-header[data-v-73c385f8]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border)}.mermaid-label-text[data-v-73c385f8]{color:var(--code-action-fg)}.mermaid-mode-toggle-group[data-v-73c385f8]{background:transparent}.mermaid-mode-btn[data-v-73c385f8]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6}.mermaid-mode-btn[data-v-73c385f8]:hover{opacity:.9}.mermaid-mode-btn.is-active[data-v-73c385f8]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.mermaid-header-actions[data-v-73c385f8]{gap:var(--ms-gap-header-actions)}.mermaid-action-btn[data-v-73c385f8]{font-family:inherit;font-size:var(--ms-text-label);color:var(--code-action-fg)}.mermaid-action-btn[data-v-73c385f8]:hover{background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.mermaid-action-btn[data-v-73c385f8]:active{transform:scale(.98)}.mermaid-source-panel[data-v-73c385f8]{padding:var(--ms-inset-panel-body);background:var(--diagram-bg)}.mermaid-source-code[data-v-73c385f8]{color:hsl(var(--ms-foreground))}.mermaid-preview-area[data-v-73c385f8]{background:var(--diagram-bg);min-height:var(--ms-size-diagram-min-height);transition-duration:var(--ms-duration-standard)}.mermaid-modal-overlay[data-v-73c385f8]{background:var(--modal-overlay)}.mermaid-modal-panel[data-v-73c385f8]{background:var(--modal-bg);color:var(--modal-fg);box-shadow:var(--ms-shadow-modal)}._mermaid[data-v-73c385f8]{position:relative;font-family:inherit;content-visibility:auto;contain:content;contain-intrinsic-size:var(--ms-size-diagram-min-height) 240px}._mermaid[data-v-73c385f8] [data-mermaid-svg-layer]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;width:100%;min-height:100%}._mermaid[data-v-73c385f8] svg{width:100%;height:auto;max-height:100%;display:block}.fullscreen ._mermaid[data-v-73c385f8] svg{max-height:none}.fullscreen[data-v-73c385f8]{width:100%;max-height:100%!important;height:100%!important}.mermaid-dialog-enter-from[data-v-73c385f8],.mermaid-dialog-leave-to[data-v-73c385f8]{opacity:0}.mermaid-dialog-enter-active[data-v-73c385f8],.mermaid-dialog-leave-active[data-v-73c385f8]{transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.mermaid-dialog-enter-from .dialog-panel[data-v-73c385f8],.mermaid-dialog-leave-to .dialog-panel[data-v-73c385f8]{transform:translateY(8px) scale(.98);opacity:.98}.mermaid-dialog-enter-to .dialog-panel[data-v-73c385f8],.mermaid-dialog-leave-from .dialog-panel[data-v-73c385f8]{transform:translateY(0) scale(1);opacity:1}.mermaid-dialog-enter-active .dialog-panel[data-v-73c385f8],.mermaid-dialog-leave-active .dialog-panel[data-v-73c385f8]{transition:transform var(--ms-duration-overlay) var(--ms-ease-standard),opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.infographic-block-container[data-v-de34ec4b]{margin:var(--ms-flow-diagram-y) 0;background:var(--diagram-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground));box-shadow:var(--ms-shadow-subtle)}.infographic-block-header[data-v-de34ec4b]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground))}.infographic-label[data-v-de34ec4b]{font-size:var(--ms-text-label);color:hsl(var(--ms-muted-foreground))}.action-icon[data-v-de34ec4b]{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.icon-slot[data-v-de34ec4b]{display:inline-flex;align-items:center;justify-content:center}.icon-slot[data-v-de34ec4b] svg{display:block;width:100%;height:100%}.infographic-mode-toggle[data-v-de34ec4b]{background:transparent}.infographic-mode-btn[data-v-de34ec4b]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6;transition:color .15s,background-color .15s,opacity .15s}.infographic-mode-btn[data-v-de34ec4b]:hover{opacity:.9}.infographic-mode-btn.is-active[data-v-de34ec4b]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.infographic-header-actions[data-v-de34ec4b]{gap:var(--ms-gap-header-actions)}.infographic-action-btn[data-v-de34ec4b]{font-family:inherit;color:var(--code-action-fg);transition:background-color .15s,color .15s}.infographic-action-btn[data-v-de34ec4b]:hover{background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.infographic-action-btn[data-v-de34ec4b]:active{transform:scale(.98)}.infographic-source[data-v-de34ec4b]{padding:var(--ms-inset-panel-body);background:var(--diagram-bg)}.infographic-source-code[data-v-de34ec4b]{color:hsl(var(--ms-foreground))}.infographic-preview[data-v-de34ec4b]{background:var(--diagram-bg);min-height:var(--ms-size-diagram-min-height);transition-duration:var(--ms-duration-fast)}.infographic-pending-source[data-v-de34ec4b]{position:absolute;inset:0;z-index:1;margin:0;padding:var(--ms-inset-panel-body);overflow:auto;color:hsl(var(--ms-foreground));text-align:left;background:var(--diagram-bg)}.infographic-modal-overlay[data-v-de34ec4b]{background:var(--modal-overlay)}.infographic-modal-panel[data-v-de34ec4b]{background:var(--modal-bg);color:var(--modal-fg);box-shadow:var(--ms-shadow-modal)}.fullscreen[data-v-de34ec4b]{width:100%;max-height:100%!important;height:100%!important}.infographic-dialog-enter-from[data-v-de34ec4b],.infographic-dialog-leave-to[data-v-de34ec4b]{opacity:0}.infographic-dialog-enter-active[data-v-de34ec4b],.infographic-dialog-leave-active[data-v-de34ec4b]{transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.infographic-dialog-enter-from .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-to .dialog-panel[data-v-de34ec4b]{transform:translateY(8px) scale(.98);opacity:.98}.infographic-dialog-enter-to .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-from .dialog-panel[data-v-de34ec4b]{transform:translateY(0) scale(1);opacity:1}.infographic-dialog-enter-active .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-active .dialog-panel[data-v-de34ec4b]{transition:transform var(--ms-duration-overlay) var(--ms-ease-standard),opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.d2-block-container[data-v-3b434cf5]{margin:var(--ms-flow-diagram-y) 0;background:var(--diagram-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground));box-shadow:var(--ms-shadow-subtle)}.d2-block-header[data-v-3b434cf5]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground))}.d2-mode-toggle[data-v-3b434cf5]{background:transparent}.mode-btn[data-v-3b434cf5]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6;transition:opacity .2s,color .2s,background-color .2s}.mode-btn[data-v-3b434cf5]:hover{opacity:.9}.mode-btn.is-active[data-v-3b434cf5]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.d2-header-actions[data-v-3b434cf5]{gap:var(--ms-gap-header-actions)}.d2-action-btn[data-v-3b434cf5]{color:var(--code-action-fg);opacity:.7;transition:opacity .2s,background-color .15s,color .15s}.d2-action-btn[data-v-3b434cf5]:hover{opacity:1;background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.d2-action-btn[data-v-3b434cf5]:disabled{opacity:.3;cursor:not-allowed}.d2-block-body[data-v-3b434cf5]{position:relative}.d2-source[data-v-3b434cf5]{padding:var(--ms-inset-panel-body) var(--ms-inset-panel-x);font-family:var(--vscode-editor-font-family, "Fira Code", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace)}.d2-code[data-v-3b434cf5]{white-space:pre;font-size:14px;line-height:1.5}.d2-render[data-v-3b434cf5]{max-height:var(--ms-size-code-max-height);overflow:auto}.d2-svg[data-v-3b434cf5] svg.markstream-d2-root-svg{width:100%;max-width:100%;height:auto;display:block}.d2-label[data-v-3b434cf5]{font-size:var(--ms-text-label)}.action-icon[data-v-3b434cf5]{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.d2-error[data-v-3b434cf5]{color:hsl(var(--ms-destructive))}.markstream-virtual-timeline[data-v-1303f06e]{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;overflow:auto;overflow-anchor:none}.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__spacer[data-v-1303f06e],.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__item[data-v-1303f06e]{opacity:0;visibility:hidden;pointer-events:none}.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__item[data-v-1303f06e],.markstream-virtual-timeline__item.is-restored-height-floor[data-v-1303f06e]{height:var(--markstream-virtual-item-size);overflow:hidden}.markstream-virtual-timeline__restore-loading[data-v-1303f06e]{position:absolute;top:0;left:0;right:0;z-index:10;display:grid;place-items:center;pointer-events:none;overflow:hidden;background:Canvas;contain:strict}.markstream-virtual-timeline__restore-loading-card[data-v-1303f06e]{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border:1px solid rgb(148 163 184 / 32%);border-radius:999px;background:#ffffffeb;color:#334155;font-size:13px;box-shadow:0 8px 24px #0f172a14}.markstream-virtual-timeline__restore-spinner[data-v-1303f06e]{width:14px;height:14px;border:2px solid rgb(148 163 184 / 35%);border-top-color:#334155;border-radius:999px;animation:markstream-timeline-restore-spin-1303f06e .8s linear infinite}@keyframes markstream-timeline-restore-spin-1303f06e{to{transform:rotate(360deg)}}.markstream-virtual-timeline__spacer[data-v-1303f06e]{flex:0 0 auto;overflow-anchor:none}.markstream-virtual-timeline__item[data-v-1303f06e]{display:flow-root;flex:0 0 auto;overflow-anchor:none}.markstream-virtual-timeline__default-item[data-v-1303f06e]{margin:8px 0;padding:10px 12px;border:1px solid rgb(148 163 184 / 32%);border-radius:8px;background:#f8fafc;color:#0f172a;line-height:1.5;white-space:pre-wrap}.markstream-virtual-timeline__default-item--system-divider[data-v-1303f06e]{border:0;background:transparent;color:#64748b;font-size:12px;text-align:center}.markstream-virtual-timeline__default-item--error[data-v-1303f06e]{border-color:#f8717173;background:#fef2f2;color:#991b1b}.markstream-virtual-timeline__status[data-v-1303f06e]{display:inline-flex;margin-right:8px;color:#475569;font-size:12px;text-transform:uppercase}@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2) format("woff2"),url(/assets/KaTeX_AMS-Regular-DMm9YOAa.woff) format("woff"),url(/assets/KaTeX_AMS-Regular-DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff) format("woff"),url(/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff) format("woff"),url(/assets/KaTeX_Fraktur-Regular-CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Main-Bold-Cx986IdX.woff2) format("woff2"),url(/assets/KaTeX_Main-Bold-Jm3AIy58.woff) format("woff"),url(/assets/KaTeX_Main-Bold-waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2) format("woff2"),url(/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff) format("woff"),url(/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2) format("woff2"),url(/assets/KaTeX_Main-Italic-BMLOBm91.woff) format("woff"),url(/assets/KaTeX_Main-Italic-3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Main-Regular-B22Nviop.woff2) format("woff2"),url(/assets/KaTeX_Main-Regular-Dr94JaBh.woff) format("woff"),url(/assets/KaTeX_Main-Regular-ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2) format("woff2"),url(/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff) format("woff"),url(/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Math-Italic-t53AETM-.woff2) format("woff2"),url(/assets/KaTeX_Math-Italic-DA0__PXp.woff) format("woff"),url(/assets/KaTeX_Math-Italic-flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url(/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff) format("woff"),url(/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url(/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff) format("woff"),url(/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url(/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff) format("woff"),url(/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Script-Regular-D3wIWfF6.woff2) format("woff2"),url(/assets/KaTeX_Script-Regular-D5yQViql.woff) format("woff"),url(/assets/KaTeX_Script-Regular-C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2) format("woff2"),url(/assets/KaTeX_Size1-Regular-C195tn64.woff) format("woff"),url(/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2) format("woff2"),url(/assets/KaTeX_Size2-Regular-oD1tc_U0.woff) format("woff"),url(/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/assets/KaTeX_Size3-Regular-CTq5MqoE.woff) format("woff"),url(/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2) format("woff2"),url(/assets/KaTeX_Size4-Regular-BF-4gkZK.woff) format("woff"),url(/assets/KaTeX_Size4-Regular-DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2) format("woff2"),url(/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff) format("woff"),url(/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf) format("truetype")}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.17.0"}.katex .katex-mathml{border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}.md[data-v-4a3beed4]{font:400 var(--content-font-size)/1.6 var(--font-ui);line-height:round(calc(var(--content-font-size) * 1.625),1px);color:var(--color-text);word-break:break-word}.md[data-v-4a3beed4] .markdown-renderer{font:400 var(--content-font-size)/1.6 var(--font-ui);line-height:round(calc(var(--content-font-size) * 1.625),1px);color:var(--color-text)}.md[data-v-4a3beed4] .markstream-vue,.md[data-v-4a3beed4] .markdown-renderer{--code-bg: var(--color-surface-sunken);--code-fg: var(--color-text);--code-border: var(--color-line);--code-header-bg: var(--color-surface);--code-action-fg: var(--color-text-muted);--code-action-hover-fg: var(--color-accent);--markstream-code-fallback-bg: var(--color-surface-sunken);--markstream-code-fallback-fg: var(--color-text);--markstream-code-border-color: var(--color-line);--inline-code-bg: var(--color-inline-code-bg);--inline-code-fg: var(--color-text);--inline-code-border: transparent}.md[data-v-4a3beed4] .md-file-link{appearance:none;display:inline;border:0;padding:0;background:transparent;color:var(--color-accent-hover);font:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;cursor:pointer}.md[data-v-4a3beed4] .md-file-link:hover{color:var(--color-accent)}.md[data-v-4a3beed4] .inline-code .md-file-link{text-underline-offset:1.5px}.md[data-v-4a3beed4] .markdown-renderer p,.md[data-v-4a3beed4] .markdown-renderer li{font-size:var(--content-font-size);line-height:round(calc(var(--content-font-size) * 1.625),1px)}.md[data-v-4a3beed4] .markdown-renderer blockquote,.md[data-v-4a3beed4] .markdown-renderer td,.md[data-v-4a3beed4] .markdown-renderer th{font-size:var(--md-b2)}.md[data-v-4a3beed4] .markdown-renderer img{background:var(--media-alpha-canvas)}.md[data-v-4a3beed4] strong{color:color-mix(in srgb,var(--color-text) 86%,var(--color-text-muted));font-weight:var(--weight-semibold)}.md[data-v-4a3beed4] h1,.md[data-v-4a3beed4] h2,.md[data-v-4a3beed4] h3,.md[data-v-4a3beed4] h4{color:var(--color-text);font-optical-sizing:auto;font-weight:600;margin:.85em 0 .35em}.md[data-v-4a3beed4] h1{font-size:var(--md-h1);line-height:round(calc(var(--md-h1) * 1.63),1px);border-bottom:1px solid var(--color-line);padding-bottom:4px}.md[data-v-4a3beed4] h2{font-size:var(--md-h2);line-height:round(calc(var(--md-h2) * 1.6),1px)}.md[data-v-4a3beed4] h3{font-size:var(--md-h3);line-height:round(calc(var(--md-h3) * 1.56),1px)}.md[data-v-4a3beed4] h4{font-size:var(--md-b2);line-height:round(calc(var(--md-b2) * 1.6),1px);color:var(--color-text-muted)}.md[data-v-4a3beed4] p{margin:0}.md[data-v-4a3beed4] .node-slot+.node-slot{margin-top:var(--content-font-size)}.md[data-v-4a3beed4] .node-slot+.node-slot:has(h1),.md[data-v-4a3beed4] .node-slot+.node-slot:has(h2){margin-top:calc(var(--content-font-size) * 2)}.md[data-v-4a3beed4] .node-slot+.node-slot:has(h3),.md[data-v-4a3beed4] .node-slot+.node-slot:has(h4){margin-top:calc(var(--content-font-size) * 1.5)}.md[data-v-4a3beed4] ul,.md[data-v-4a3beed4] ol{--md-dot: round(calc(var(--content-font-size) * .375), 1px);list-style:none;margin:0;padding-left:calc(var(--content-font-size) * 2)}.md[data-v-4a3beed4] li{position:relative;margin:0;padding:0}.md[data-v-4a3beed4] li+li{margin-top:round(calc(var(--content-font-size) * .75),1px)}.md[data-v-4a3beed4] li>ul,.md[data-v-4a3beed4] li>ol{margin-top:round(calc(var(--content-font-size) * .75),1px);padding-left:calc(var(--content-font-size) * 1.5)}.md[data-v-4a3beed4] ul>li:before{content:"";position:absolute;left:calc((var(--md-dot) + var(--content-font-size) * 2) / -2);top:calc((round(calc(var(--content-font-size) * 1.625),1px) - var(--md-dot)) / 2);width:var(--md-dot);height:var(--md-dot);border-radius:50%;background:color-mix(in srgb,var(--color-text) 90%,transparent)}.md[data-v-4a3beed4] ul>li:has(>input[type=checkbox]):before,.md[data-v-4a3beed4] ul>li:has(>p>input[type=checkbox]):before{content:none}.md[data-v-4a3beed4] ul ul>li:before{background:transparent;border:1px solid color-mix(in srgb,var(--color-text) 90%,transparent);box-sizing:border-box}.md[data-v-4a3beed4] ol{counter-reset:md-ol}.md[data-v-4a3beed4] ol[start],.md[data-v-4a3beed4] ol:has(>li[value]){counter-reset:none;list-style:decimal}.md[data-v-4a3beed4] ol[start]>li,.md[data-v-4a3beed4] ol:has(>li[value])>li{counter-increment:none}.md[data-v-4a3beed4] ol[start]>li:before,.md[data-v-4a3beed4] ol:has(>li[value])>li:before{content:none}.md[data-v-4a3beed4] ol>li{counter-increment:md-ol}.md[data-v-4a3beed4] ol>li:before{content:counter(md-ol) ".";position:absolute;top:0;left:calc(var(--content-font-size) * -2);width:calc(var(--content-font-size) * 2);line-height:round(calc(var(--content-font-size) * 1.625),1px);text-align:center;color:var(--color-text)}.md[data-v-4a3beed4] :not(pre)>code,.md[data-v-4a3beed4] .inline-code{font:.9em var(--font-mono);background:var(--color-inline-code-bg);color:var(--color-text);border:0;padding:0 4px;border-radius:var(--radius-sm)}.md[data-v-4a3beed4] strong code,.md[data-v-4a3beed4] strong .inline-code,.md[data-v-4a3beed4] b code,.md[data-v-4a3beed4] b .inline-code{font-weight:var(--weight-semibold)}.md[data-v-4a3beed4] .code-block-container{margin:.6em 0;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);box-shadow:var(--shadow-xs);overflow:hidden;--vscode-editor-font-size: var(--text-sm);--vscode-editor-line-height: calc(var(--text-sm) * 1.65)}.md[data-v-4a3beed4] .code-block-header{background:var(--color-surface);border-bottom:.5px solid var(--color-line);padding:4px 6px 4px 12px;color:var(--color-text-muted);font:var(--text-xs) var(--font-ui)}.md[data-v-4a3beed4] .code-block-header *{color:var(--color-text-muted);font:var(--text-xs) var(--font-ui)}.md[data-v-4a3beed4] .code-block-header .code-header-main{font-family:var(--font-ui)}.md[data-v-4a3beed4] .code-block-header .code-action-btn{color:var(--color-text-muted);background:transparent;border:none;border-radius:var(--radius-sm);cursor:pointer;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.md[data-v-4a3beed4] .code-block-header .code-action-btn:hover{background:var(--color-surface-sunken);color:var(--color-text)}.md[data-v-4a3beed4] .code-block-header .code-action-btn:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md[data-v-4a3beed4] .code-block-header .code-action-btn *{pointer-events:none}.md[data-v-4a3beed4] .code-block-shell-content,.md[data-v-4a3beed4] .markstream-pre{background:var(--color-well)}.md[data-v-4a3beed4] .code-editor-container{line-height:1.65;--diffs-gap-block: var(--space-3)}.md[data-v-4a3beed4] .code-editor-container diffs-container{--diffs-line-height: 1.65em}.md[data-v-4a3beed4] .code-pre-fallback>.markstream-pre__line-numbers{display:none}.md[data-v-4a3beed4] .code-block-container .code-pre-fallback{padding-left:1ch;line-height:1.65!important}.md[data-v-4a3beed4] .code-block-container pre:not(.code-pre-fallback):not(.markstream-pre--line-numbers),.md[data-v-4a3beed4] .markstream-pre:not(.code-pre-fallback):not(.markstream-pre--line-numbers){margin:0;padding:12px 14px;overflow-x:auto;font:var(--text-sm)/1.65 var(--font-mono)}.md[data-v-4a3beed4] .code-block-container pre code{font:inherit;color:var(--color-text);background:none;border:none;padding:0;border-radius:0}.md[data-v-4a3beed4] .markstream-pre,.md[data-v-4a3beed4] .code-pre-fallback,.md[data-v-4a3beed4] .code-block-shell-content pre:not(.shiki),.md[data-v-4a3beed4] .code-block-shell-content pre:not(.shiki) code{color:var(--color-text)}.md[data-v-4a3beed4] a{color:var(--color-accent);text-decoration:none}.md[data-v-4a3beed4] a:hover{text-decoration:underline}.md[data-v-4a3beed4] a.mention-pill{color:var(--color-text-muted);text-decoration:none}.md[data-v-4a3beed4] a.mention-folder:hover{text-decoration:none}.md[data-v-4a3beed4] .katex-display{overflow-x:auto;overflow-y:hidden;padding:2px 0 6px;margin:.6em 0}.md[data-v-4a3beed4] .math-inline{vertical-align:baseline}.md[data-v-4a3beed4] blockquote{position:relative;margin:0;padding:0 0 0 round(calc(var(--content-font-size) * 1.5),1px);border-left:none;color:var(--color-text)}.md[data-v-4a3beed4] blockquote:before{content:"";position:absolute;left:calc(round(calc(var(--content-font-size) * 1.5),1px)/2 - 1px);top:2px;bottom:2px;width:2px;border-radius:2px;background:var(--color-line)}.md[data-v-4a3beed4] .blockquote>.paragraph-node{margin:0}.md[data-v-4a3beed4] .blockquote>.paragraph-node+.paragraph-node{margin-top:var(--content-font-size)}.md[data-v-4a3beed4] hr{border:none;border-top:1px solid var(--color-line);margin:0}.md[data-v-4a3beed4] table:not(.table-node){border-collapse:collapse;font-size:var(--text-lg);margin:.5em 0}.md[data-v-4a3beed4] table:not(.table-node) th,.md[data-v-4a3beed4] table:not(.table-node) td{border:1px solid var(--color-line);padding:4px 10px;text-align:left}.md[data-v-4a3beed4] table:not(.table-node) th{background:var(--color-surface);color:var(--color-text);font-weight:var(--weight-medium)}.md[data-v-4a3beed4] .table-node-wrapper{width:100%;max-width:100%!important;min-width:0;overflow-x:auto!important;scrollbar-gutter:auto!important;position:relative;--table-cell-cap: var(--p-table-cell-max)}.md[data-v-4a3beed4] .table-node{--table-border: var(--color-line);--table-header-bg: var(--color-surface);font-size:var(--text-lg);margin:.5em 0;width:max-content!important;min-width:100%;max-width:none!important;table-layout:auto!important}.md[data-v-4a3beed4] .table-node th,.md[data-v-4a3beed4] .table-node td{text-align:left;vertical-align:top;max-width:var(--table-cell-cap)}.md[data-v-4a3beed4] .table-node .text-node{display:inline-block;max-width:var(--table-cell-cap);vertical-align:top}.md[data-v-4a3beed4] .md-table-fade{display:none;position:absolute;top:0;bottom:0;right:0;width:36px;z-index:1;background:linear-gradient(to right,transparent,color-mix(in srgb,var(--color-bg) 65%,transparent) 55%,var(--color-bg));pointer-events:none;transition:opacity var(--duration-base) var(--ease-out)}.md[data-v-4a3beed4] .md-table-at-end .md-table-fade{opacity:0}.md[data-v-4a3beed4] .md-table-toggle{display:none;position:absolute;top:6px;right:6px;z-index:2;align-items:center;justify-content:center;width:26px;height:26px;color:var(--color-text-muted);background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--radius-sm);box-shadow:var(--shadow-sm);cursor:pointer;opacity:0;transition:opacity var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}@container (min-width: 760px){.md[data-v-4a3beed4] .md-table-fade.md-table-toggle--show,.md[data-v-4a3beed4] .md-table-toggle.md-table-toggle--show{display:block}.md[data-v-4a3beed4] .md-table-toggle.md-table-toggle--show{display:inline-flex}}.md[data-v-4a3beed4] .table-node-wrapper:hover .md-table-toggle.md-table-toggle--show,.md[data-v-4a3beed4] .table-node-wrapper:focus-within .md-table-toggle.md-table-toggle--show,.md[data-v-4a3beed4] .table-node-wrapper.md-table-wide .md-table-toggle.md-table-toggle--show{opacity:1}.md[data-v-4a3beed4] .md-table-toggle:hover{background:var(--color-surface-sunken);color:var(--color-text)}.md[data-v-4a3beed4] .md-table-toggle:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md[data-v-4a3beed4] .md-table-toggle svg{display:block}.md[data-v-4a3beed4] .table-node tbody tr:hover{background-color:transparent!important}.md-frontmatter[data-v-4a3beed4]{margin:0 0 var(--space-2);padding:var(--space-3) var(--space-4);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);box-shadow:var(--shadow-xs);overflow-x:auto;color:var(--color-text-muted);font:var(--text-sm)/1.65 var(--font-mono)}.diff-wrap[data-v-4a3beed4]{margin:.6em 0;border:1px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface-sunken);box-shadow:var(--shadow-xs);overflow:hidden}.diff-bar[data-v-4a3beed4]{display:flex;align-items:center;gap:6px;padding:4px 12px;background:var(--color-surface);border-bottom:1px solid var(--color-line);color:var(--color-text-muted);font:var(--text-xs) var(--font-mono)}.diff-lang[data-v-4a3beed4]{margin-right:auto}.diff-copy[data-v-4a3beed4]{display:inline-flex;align-items:center;justify-content:center;color:var(--color-text-muted);background:transparent;border:none;border-radius:var(--radius-sm);cursor:pointer;padding:2px 6px;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.diff-copy[data-v-4a3beed4]:hover{background:var(--color-surface-sunken);color:var(--color-text)}.diff-copy[data-v-4a3beed4]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.diff-pre[data-v-4a3beed4]{margin:0;padding:12px 0;overflow-x:auto;background:var(--color-surface-sunken)}.diff-pre code[data-v-4a3beed4]{display:block;width:max-content;min-width:100%;font:var(--text-sm)/1.65 var(--font-mono);color:var(--color-text)}.diff-line[data-v-4a3beed4]{display:block;width:100%;padding:0 14px}.diff-sign[data-v-4a3beed4]{display:inline-block;width:14px;text-align:center;color:var(--color-text-muted);user-select:none}.diff-text[data-v-4a3beed4]{color:var(--color-text)}.diff-add[data-v-4a3beed4]{background:var(--color-success-soft);box-shadow:inset 2px 0 color-mix(in srgb,var(--color-success) 55%,transparent)}.diff-add .diff-sign[data-v-4a3beed4]{color:var(--color-success)}.diff-del[data-v-4a3beed4]{background:var(--color-danger-soft);box-shadow:inset 2px 0 color-mix(in srgb,var(--color-danger) 55%,transparent)}.diff-del .diff-sign[data-v-4a3beed4]{color:var(--color-danger)}.diff-hunk[data-v-4a3beed4]{background:var(--color-surface)}.diff-hunk .diff-text[data-v-4a3beed4]{color:var(--color-text-muted)}.md[data-v-4a3beed4],.md .markdown-renderer[data-v-4a3beed4]{font-family:var(--sans)}.md .code-block-container[data-v-4a3beed4],.md .diff-wrap[data-v-4a3beed4]{border-radius:var(--radius-md)}.md :not(pre)>code[data-v-4a3beed4],.md .inline-code[data-v-4a3beed4]{border-radius:var(--radius-sm)}.plan-glyph[data-v-8dff80a1]{display:inline-flex;align-items:center}.plan-path[data-v-8dff80a1]{display:block;max-width:100%;margin:0 0 var(--space-2);padding:0;overflow:hidden;border:none;background:transparent;color:var(--color-accent);font-family:var(--font-mono);font-size:var(--text-xs);text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.plan-path[data-v-8dff80a1]:hover{text-decoration:underline}.plan-path[data-v-8dff80a1]:focus-visible{outline:none;border-radius:var(--radius-xs);box-shadow:var(--p-focus-ring)}.plan-content[data-v-8dff80a1]{padding:var(--space-3);border:1px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);color:var(--color-text)}.plan-review[data-v-8dff80a1]{display:flex;flex-direction:column;gap:var(--space-1);margin-top:var(--space-2);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);line-height:var(--leading-normal)}.plan-review>div[data-v-8dff80a1]{display:flex;align-items:baseline;gap:var(--space-2)}.review-label[data-v-8dff80a1]{flex:none;color:var(--color-text-faint)}.review-feedback[data-v-8dff80a1]{white-space:pre-wrap}.path-link[data-v-0edbdd82]{display:block;width:100%;border:none;border-radius:var(--radius-xs);background:transparent;padding:0 0 var(--space-1);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);color:var(--color-text-muted);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.path-link[data-v-0edbdd82]:hover{color:var(--color-accent);text-decoration:underline;text-underline-offset:3px}.path-link[data-v-0edbdd82]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.swarm-card[data-v-f7b643ea]{margin:0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);overflow:hidden;transition:border-color var(--duration-base) var(--ease-out)}.swarm-card.err[data-v-f7b643ea]{border-color:color-mix(in srgb,var(--color-danger) 45%,var(--bg))}.head[data-v-f7b643ea]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:34px;padding:0 var(--space-2) 0 var(--space-3);border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--ui-font-size);text-align:left;cursor:pointer;user-select:none}.head[data-v-f7b643ea]:hover{background:var(--color-hover);color:var(--color-text)}.head[data-v-f7b643ea]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.ic[data-v-f7b643ea]{color:var(--color-text-faint);flex:none}.title[data-v-f7b643ea]{font-weight:var(--weight-medium);color:var(--color-text);flex:none}.meta[data-v-f7b643ea]{color:var(--color-text-faint);flex:none}.sum-txt[data-v-f7b643ea]{color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.rt[data-v-f7b643ea]{margin-left:auto;display:flex;align-items:center;gap:var(--space-2);flex:none;color:var(--color-text-muted);font-size:var(--text-xs)}.status[data-v-f7b643ea]{display:inline-flex;align-items:center;flex:none}.status[data-v-f7b643ea]:has(>svg){color:var(--color-success)}.err .status[data-v-f7b643ea]:has(>svg){color:var(--color-danger)}.chip[data-v-f7b643ea]{color:var(--color-text-muted);font-family:var(--font-mono)}.tm[data-v-f7b643ea]{color:var(--color-text-faint);font-family:var(--font-mono)}.car[data-v-f7b643ea]{margin-left:2px;color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.swarm-card.open .car[data-v-f7b643ea]{transform:rotate(90deg)}.body[data-v-f7b643ea]{border-top:.5px solid var(--color-line)}.overview[data-v-f7b643ea]{padding:10px var(--space-3) var(--space-2);border-bottom:.5px solid var(--color-line)}.overview-line[data-v-f7b643ea]{display:flex;align-items:baseline;gap:var(--space-2)}.big[data-v-f7b643ea]{font-family:var(--font-mono);font-weight:var(--weight-medium);color:var(--color-text);font-size:15px}.lbl[data-v-f7b643ea]{color:var(--color-text-muted);font-size:var(--text-xs)}.seg[data-v-f7b643ea]{display:flex;height:5px;border-radius:var(--radius-full);overflow:hidden;margin:var(--space-2) 0 var(--space-1);gap:2px}.seg>span[data-v-f7b643ea]{height:100%;border-radius:var(--radius-full);min-width:3px}.s-ok[data-v-f7b643ea]{background:var(--color-success)}.s-run[data-v-f7b643ea]{background:var(--color-accent)}.s-warn[data-v-f7b643ea]{background:var(--color-warning)}.s-fail[data-v-f7b643ea]{background:var(--color-danger)}.s-queue[data-v-f7b643ea]{background:var(--color-line)}.legend[data-v-f7b643ea]{display:flex;flex-wrap:wrap;gap:10px}.legend span[data-v-f7b643ea]{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted)}.lg-dot[data-v-f7b643ea]{width:6px;height:6px;border-radius:var(--radius-full)}.member[data-v-f7b643ea]{border-bottom:.5px solid var(--color-line)}.member[data-v-f7b643ea]:last-child{border-bottom:none}.member-head[data-v-f7b643ea]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:30px;padding:0 var(--space-2) 0 var(--space-3);border:none;background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size);text-align:left;cursor:pointer;user-select:none}.member-head[data-v-f7b643ea]:not(:disabled):hover{background:var(--color-hover)}.member-head[data-v-f7b643ea]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.member-head[data-v-f7b643ea]:disabled{cursor:default}.row-dot[data-v-f7b643ea]{flex:none}.mname[data-v-f7b643ea]{flex:none;min-width:0;max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-medium);color:var(--color-text)}.mact[data-v-f7b643ea]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted);font-size:var(--text-xs)}.mphase[data-v-f7b643ea]{flex:none;margin-left:auto;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint)}.phase-completed .mphase[data-v-f7b643ea]{color:var(--color-success)}.phase-failed .mphase[data-v-f7b643ea]{color:var(--color-danger)}.phase-working .mphase[data-v-f7b643ea]{color:var(--color-accent)}.phase-suspended .mphase[data-v-f7b643ea]{color:var(--color-warning)}.mcar[data-v-f7b643ea]{margin-left:var(--space-1);color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.member.open .mcar[data-v-f7b643ea]{transform:rotate(90deg)}.member-saved[data-v-f7b643ea]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) var(--space-3);border:none;border-top:.5px solid var(--color-line);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);text-align:left;cursor:pointer}.member-saved[data-v-f7b643ea]:hover{color:var(--color-text-muted)}.member-saved[data-v-f7b643ea]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.member-saved-car[data-v-f7b643ea]{transition:transform var(--duration-base) var(--ease-out)}.member-saved-car.open[data-v-f7b643ea]{transform:rotate(90deg)}.member-body[data-v-f7b643ea]{padding:var(--space-1) var(--space-3) 10px 31px;color:var(--color-text-muted);font-size:calc(var(--content-font-size) - 2px);line-height:1.65;white-space:pre-wrap;word-break:break-word}.waiting[data-v-f7b643ea]{padding:6px var(--space-3) 10px;color:var(--color-text-muted);font-size:var(--text-xs)}.fallback-output[data-v-f7b643ea]{padding:10px var(--space-3);color:var(--color-text);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;white-space:pre-wrap;word-break:break-word}.status-glyph[data-v-f1aedfd0]{flex:none;width:16px;display:inline-flex;align-items:center;justify-content:center;user-select:none}.status-glyph.s-run[data-v-f1aedfd0]{color:var(--color-accent)}.status-glyph.s-done[data-v-f1aedfd0]{color:var(--color-success)}.status-glyph.s-fail[data-v-f1aedfd0]{color:var(--color-danger)}.status-glyph.s-pending[data-v-f1aedfd0]{color:var(--color-text-faint)}.todo-bar[data-v-1b7f51f3]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden;flex:none}.todo-fill[data-v-1b7f51f3]{background:var(--color-success);border-radius:var(--radius-full);transition:width var(--duration-slow) var(--ease-out)}.todo-list[data-v-1b7f51f3]{display:flex;flex-direction:column;gap:1px;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-2) var(--space-3);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.todo-row[data-v-1b7f51f3]{display:flex;align-items:center;gap:7px;padding:2px 0;font-size:calc(var(--content-font-size) - 1px);color:var(--color-text)}.todo-title[data-v-1b7f51f3]{flex:1;min-width:0;overflow-wrap:anywhere;line-height:1.4}.todo-row.s-in_progress .todo-title[data-v-1b7f51f3]{font-weight:var(--weight-medium)}.todo-row.s-done .todo-title[data-v-1b7f51f3]{color:var(--color-text-faint);text-decoration:line-through}.wf-glance[data-v-256015f8]{margin-bottom:var(--space-1)}.wf-main[data-v-256015f8]{color:var(--color-text);font-size:var(--text-sm);line-height:var(--leading-prose);white-space:pre-wrap;word-break:break-word}.wf-sub[data-v-256015f8]{color:var(--color-text-muted);font-size:var(--text-xs);line-height:var(--leading-prose);white-space:pre-wrap;word-break:break-word}.fetch-url[data-v-8c248fcc]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;color:var(--color-text-faint);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.think[data-v-980ffe0e]{margin:0}.think-head[data-v-980ffe0e]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.think-head[data-v-980ffe0e]:hover{color:var(--color-text)}.think-head[data-v-980ffe0e]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.think-bulb[data-v-980ffe0e]{flex:none}.think-title[data-v-980ffe0e]{font-weight:var(--weight-medium)}.think-time[data-v-980ffe0e]{color:var(--color-text-faint);font-weight:400;flex:none}.think.streaming .think-title[data-v-980ffe0e]{animation:think-breathe-980ffe0e 1.6s var(--ease-in-out) infinite}@keyframes think-breathe-980ffe0e{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.think.streaming .think-title[data-v-980ffe0e]{animation:none}}.think-car[data-v-980ffe0e]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.think.open .think-car[data-v-980ffe0e]{transform:rotate(90deg)}.think-body[data-v-980ffe0e]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.think-body.instant[data-v-980ffe0e]{transition:none}.think-body.open[data-v-980ffe0e]{grid-template-rows:minmax(0,1fr)}.think-body-inner[data-v-980ffe0e]{min-height:0;overflow:hidden}.think-text[data-v-980ffe0e]{font:var(--text-base)/var(--leading-relaxed) var(--font-ui);font-weight:400;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-word;margin:0;padding:var(--space-1) 0 var(--space-2)}.mob .think-text[data-v-980ffe0e]{color:var(--color-text-faint);line-height:var(--leading-normal)}.activity-run[data-v-45842de9]{display:flex;flex-direction:column;animation:kimi-card-in var(--duration-base) var(--ease-out)}.ar-head[data-v-45842de9]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.ar-head[data-v-45842de9]:hover{color:var(--color-text)}.ar-head.is-static[data-v-45842de9],.ar-head.is-static[data-v-45842de9]:hover{cursor:default;color:var(--color-text-faint)}.ar-head[data-v-45842de9]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.ar-glyph[data-v-45842de9]{display:inline-flex;align-items:center;flex:none;color:var(--color-text-faint)}.ar-glyph.ok[data-v-45842de9]{color:var(--color-success)}.ar-glyph.err[data-v-45842de9]{color:var(--color-danger)}.ar-glyph.run[data-v-45842de9]{color:var(--color-text-muted);animation:ar-breathe-45842de9 1.6s var(--ease-in-out) infinite}@keyframes ar-breathe-45842de9{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.ar-glyph.run[data-v-45842de9]{animation:none}}.ar-sum[data-v-45842de9]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-regular)}.ar-danger[data-v-45842de9]{color:var(--color-danger)}.ar-faint[data-v-45842de9],.ar-sep[data-v-45842de9]{color:var(--color-text-faint)}.ar-car[data-v-45842de9]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.activity-run.open .ar-car[data-v-45842de9]{transform:rotate(90deg)}.ar-body[data-v-45842de9]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.ar-body.open[data-v-45842de9]{grid-template-rows:minmax(0,1fr)}.ar-body-inner[data-v-45842de9]{min-height:0;overflow:hidden;display:flex;flex-direction:column;gap:var(--space-2);padding-top:var(--space-1)}.msg-time[data-v-9153170e]{display:inline-flex;align-items:center;min-height:22px;box-sizing:border-box;padding:2px 5px;border-radius:var(--radius-sm);color:var(--muted);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:1;opacity:.7;white-space:nowrap}.ntf-list[data-v-010c7307]{display:flex;flex-direction:column;align-items:flex-end;gap:var(--space-3);margin:var(--space-2) 0}.ntn[data-v-010c7307]{margin-left:auto;max-width:var(--p-bubble-max);display:flex;flex-direction:column;align-items:flex-end}.ntn-head[data-v-010c7307]{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal);overflow-wrap:anywhere}.ntn-ico[data-v-010c7307]{flex:none}.ntn.ok .ntn-ico[data-v-010c7307]{color:var(--color-success)}.ntn.err .ntn-ico[data-v-010c7307]{color:var(--color-danger)}.ntn.warn .ntn-ico[data-v-010c7307]{color:var(--color-warning)}.ntn-bubble[data-v-010c7307]{box-sizing:border-box;max-width:100%;padding:var(--space-2) var(--space-3);background:var(--color-user-bubble-bg);border-radius:var(--radius-lg);color:var(--color-text);font-size:var(--content-font-size);line-height:var(--leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.ntn-line+.ntn-line[data-v-010c7307]{margin-top:var(--space-1)}.ntn-out[data-v-010c7307]{display:flex;align-items:center;gap:var(--space-2);background:var(--color-surface-raised);border-radius:var(--radius-md);padding:var(--space-1) var(--space-2);box-shadow:var(--shadow-xs);white-space:normal}.ntn-out-ic[data-v-010c7307]{color:var(--color-text-faint);flex:none}.ntn-out-path[data-v-010c7307]{flex:1;min-width:0;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.ntn-out-size[data-v-010c7307]{flex:none;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint)}.ntn-out-copy[data-v-010c7307]{display:inline-flex;align-items:center;height:var(--space-6);padding:0 var(--space-2);border-radius:var(--radius-full);font-size:var(--text-xs);color:var(--color-text-muted);border:.5px solid var(--color-line-strong);background:var(--color-surface-raised);flex:none;transition:color var(--duration-fast) var(--ease-out)}.ntn-out-copy[data-v-010c7307]:hover{color:var(--color-text)}.ntn-preview-cap[data-v-010c7307]{font-size:var(--text-xs);color:var(--color-text-faint);margin-bottom:var(--space-05)}.ntn-preview-text[data-v-010c7307]{margin:0;font-family:var(--font-mono);font-size:var(--text-xs);line-height:var(--leading-normal);color:var(--color-text-muted);white-space:pre-wrap;overflow-wrap:anywhere;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:8;overflow:hidden}.ntn-meta[data-v-010c7307]{margin-top:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal)}.ntn-raw[data-v-010c7307]{max-width:100%}.ntn-raw summary[data-v-010c7307]{list-style:none;display:flex;align-items:center;gap:var(--space-1);cursor:pointer;font-size:var(--text-xs);color:var(--color-text-faint);user-select:none}.ntn-raw summary[data-v-010c7307]::-webkit-details-marker{display:none}.ntn-raw summary[data-v-010c7307]:hover{color:var(--color-text)}.ntn-raw-car[data-v-010c7307]{transition:transform var(--duration-base) var(--ease-out)}.ntn-raw[open] .ntn-raw-car[data-v-010c7307]{transform:rotate(90deg)}.ntn-raw-in[data-v-010c7307]{margin-top:var(--space-1);display:flex;flex-direction:column;gap:var(--space-2)}.ntn-raw-fields[data-v-010c7307]{display:grid;grid-template-columns:auto 1fr;gap:var(--space-1) var(--space-3)}.ntn-raw-fields .k[data-v-010c7307]{color:var(--color-text-faint);font-size:var(--text-xs)}.ntn-raw-fields .v[data-v-010c7307]{color:var(--color-text-muted);font-size:var(--text-xs);font-family:var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ntn-raw-pre[data-v-010c7307]{margin:0;padding:var(--space-2) var(--space-3);background:var(--color-surface-raised);border-radius:var(--radius-sm);box-shadow:var(--shadow-xs);font-family:var(--font-mono);font-size:var(--text-xs);line-height:var(--leading-normal);color:var(--color-text-muted);white-space:pre;overflow:auto;max-width:100%;max-height:13lh}.turn-fold[data-v-ce1eb651]{display:flex;flex-direction:column}.tf-head[data-v-ce1eb651]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.tf-head[data-v-ce1eb651]:hover{color:var(--color-text)}.tf-head[data-v-ce1eb651]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.tf-sum[data-v-ce1eb651]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-regular)}.tf-car[data-v-ce1eb651]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.turn-fold.open .tf-car[data-v-ce1eb651]{transform:rotate(90deg)}.tf-body[data-v-ce1eb651]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.tf-body.open[data-v-ce1eb651]{grid-template-rows:minmax(0,1fr)}.tf-body-inner[data-v-ce1eb651]{min-height:0;overflow:hidden;display:flex;flex-direction:column}.tf-body-inner>.msg[data-v-ce1eb651],.tf-body-inner[data-v-ce1eb651]>.think,.tf-body-inner[data-v-ce1eb651]>.tool-group,.tf-body-inner[data-v-ce1eb651]>.activity-run,.tf-body-inner[data-v-ce1eb651]>.agent-card,.tf-body-inner[data-v-ce1eb651]>.agent-group,.tf-body-inner[data-v-ce1eb651]>.tool-line,.tf-body-inner[data-v-ce1eb651]>.swarm-card,.tf-body-inner[data-v-ce1eb651]>.media-tool,.tf-body-inner[data-v-ce1eb651]>.ask-receipt{margin-top:var(--chat-block-gap)}.turn-fold.streaming .tf-body-inner>.msg[data-v-ce1eb651]:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.think:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.tool-group:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.activity-run:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.agent-card:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.agent-group:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.tool-line:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.swarm-card:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.media-tool:first-child,.turn-fold.streaming .tf-body-inner[data-v-ce1eb651]>.ask-receipt:first-child{margin-top:0}.tf-body-inner .msg[data-v-ce1eb651]{font-size:var(--ui-font-size);line-height:var(--leading-prose);color:var(--color-text);font-weight:var(--weight-medium)}.tf-body-inner .msg[data-v-ce1eb651] p{margin:0}.tf-body-inner .msg[data-v-ce1eb651] p+p{margin-top:var(--space-2)}@container (min-width: 760px){.tf-body-inner .msg[data-v-ce1eb651] .markstream-vue.markdown-renderer:has(.table-node-wrapper.md-table-wide){content-visibility:visible}.tf-body-inner .msg[data-v-ce1eb651] .table-node-wrapper.md-table-wide{position:relative;left:50%;width:max-content;min-width:100%;max-width:min(var(--p-table-max),calc(100cqi - var(--space-5) - var(--space-5)))!important;transform:translate(-50%)}.tf-body-inner .msg[data-v-ce1eb651] .table-node-wrapper:not(.md-table-wide){--table-cell-cap: min(var(--p-table-cell-max), 36cqi)}}.turn-files[data-v-f37da416]{margin-top:var(--chat-block-gap)}.turn-files[data-v-f37da416] .ui-card__head{font-family:var(--font-ui);font-weight:var(--weight-regular);padding:var(--space-2) var(--space-3)}.turn-files[data-v-f37da416] .ui-card__body{padding:var(--space-1) var(--space-3)}.turn-files[data-v-f37da416] .ui-card__foot{padding:0;justify-content:stretch}.tf-ic[data-v-f37da416]{display:inline-flex;align-items:center;color:var(--color-text-faint);flex:none}.tf-title[data-v-f37da416]{font-size:var(--text-sm);color:var(--color-text);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tf-stats[data-v-f37da416]{margin-left:auto;display:inline-flex;align-items:center;gap:var(--space-1);flex:none}.tf-add[data-v-f37da416],.tf-del[data-v-f37da416]{font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.tf-add[data-v-f37da416]{color:var(--color-success)}.tf-del[data-v-f37da416]{color:var(--color-danger)}.tf-list[data-v-f37da416]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.tf-row[data-v-f37da416]{display:flex;align-items:center;gap:var(--space-1);min-width:0;padding:var(--space-1) 0;font-size:var(--text-sm);line-height:var(--leading-tight)}.tf-file[data-v-f37da416]{display:flex;align-items:baseline;border:none;border-radius:var(--radius-xs);background:transparent;padding:0;font-family:inherit;font-size:inherit;color:var(--color-text);flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-align:left}button.tf-file[data-v-f37da416]{cursor:pointer}button.tf-file[data-v-f37da416]:hover{text-decoration:underline;text-decoration-color:var(--color-text-faint);text-underline-offset:3px}.tf-file[data-v-f37da416]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tf-dir[data-v-f37da416]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--color-text-faint)}.tf-base[data-v-f37da416]{flex:none;font-weight:var(--weight-medium);color:var(--color-text)}.tf-more[data-v-f37da416]{width:100%;justify-content:flex-start;border-radius:0}.turn-files .tf-more[data-v-f37da416]:not(:disabled):active{transform:none}.tf-more-car[data-v-f37da416]{color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.tf-more-car.open[data-v-f37da416]{transform:rotate(180deg)}.diffbar[data-v-f37da416]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);overflow:hidden;flex:none}.seg-add[data-v-f37da416]{background:var(--color-success)}.seg-del[data-v-f37da416]{background:var(--color-danger)}.activity-notice[data-v-cc29061f]{display:inline-flex;align-items:center;gap:9px;align-self:flex-start;margin:0;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text-muted)}.cn[data-v-9f79345d]{margin:0;align-self:flex-end;max-width:78%;display:flex;flex-direction:column;align-items:flex-end}.cn-head[data-v-9f79345d]{align-self:flex-end;display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal);overflow-wrap:anywhere}.cn-head-ico[data-v-9f79345d]{flex:none}.cn-head.error .cn-head-ico[data-v-9f79345d]{color:var(--color-danger)}.cn-bubble[data-v-9f79345d]{box-sizing:border-box;max-width:100%;padding:10px 12px;background:var(--color-user-bubble-bg);border-radius:var(--radius-lg);color:var(--color-text);font-size:var(--content-font-size);line-height:var(--leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.cn-meta[data-v-9f79345d]{margin-top:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal)}/*! PhotoSwipe main CSS by Dmytro Semenov | photoswipe.com */.pswp{--pswp-bg: #000;--pswp-placeholder-bg: #222;--pswp-root-z-index: 100000;--pswp-preloader-color: rgba(79, 79, 79, .4);--pswp-preloader-color-secondary: rgba(255, 255, 255, .9);--pswp-icon-color: #fff;--pswp-icon-color-secondary: #4f4f4f;--pswp-icon-stroke-color: #4f4f4f;--pswp-icon-stroke-width: 2px;--pswp-error-text-color: var(--pswp-icon-color)}.pswp{position:fixed;top:0;left:0;width:100%;height:100%;z-index:var(--pswp-root-z-index);display:none;touch-action:none;outline:0;opacity:.003;contain:layout style size;-webkit-tap-highlight-color:rgba(0,0,0,0)}.pswp:focus{outline:0}.pswp *{box-sizing:border-box}.pswp img{max-width:none}.pswp--open{display:block}.pswp,.pswp__bg{transform:translateZ(0);will-change:opacity}.pswp__bg{opacity:.005;background:var(--pswp-bg)}.pswp,.pswp__scroll-wrap{overflow:hidden}.pswp__scroll-wrap,.pswp__bg,.pswp__container,.pswp__item,.pswp__content,.pswp__img,.pswp__zoom-wrap{position:absolute;top:0;left:0;width:100%;height:100%}.pswp__img,.pswp__zoom-wrap{width:auto;height:auto}.pswp--click-to-zoom.pswp--zoom-allowed .pswp__img{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img:active{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img,.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img:active,.pswp__img{cursor:-webkit-zoom-out;cursor:-moz-zoom-out;cursor:zoom-out}.pswp__container,.pswp__img,.pswp__button,.pswp__counter{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pswp__item{z-index:1;overflow:hidden}.pswp__hidden{display:none!important}.pswp__content{pointer-events:none}.pswp__content>*{pointer-events:auto}.pswp__error-msg-container{display:grid}.pswp__error-msg{margin:auto;font-size:1em;line-height:1;color:var(--pswp-error-text-color)}.pswp .pswp__hide-on-close{opacity:.005;will-change:opacity;transition:opacity var(--pswp-transition-duration) cubic-bezier(.4,0,.22,1);z-index:10;pointer-events:none}.pswp--ui-visible .pswp__hide-on-close{opacity:1;pointer-events:auto}.pswp__button{position:relative;display:block;width:50px;height:60px;padding:0;margin:0;overflow:hidden;cursor:pointer;background:none;border:0;box-shadow:none;opacity:.85;-webkit-appearance:none;-webkit-touch-callout:none}.pswp__button:hover,.pswp__button:active,.pswp__button:focus{transition:none;padding:0;background:none;border:0;box-shadow:none;opacity:1}.pswp__button:disabled{opacity:.3;cursor:auto}.pswp__icn{fill:var(--pswp-icon-color);color:var(--pswp-icon-color-secondary)}.pswp__icn{position:absolute;top:14px;left:9px;width:32px;height:32px;overflow:hidden;pointer-events:none}.pswp__icn-shadow{stroke:var(--pswp-icon-stroke-color);stroke-width:var(--pswp-icon-stroke-width);fill:none}.pswp__icn:focus{outline:0}div.pswp__img--placeholder,.pswp__img--with-bg{background:var(--pswp-placeholder-bg)}.pswp__top-bar{position:absolute;left:0;top:0;width:100%;height:60px;display:flex;flex-direction:row;justify-content:flex-end;z-index:10;pointer-events:none!important}.pswp__top-bar>*{pointer-events:auto;will-change:opacity}.pswp__button--close{margin-right:6px}.pswp__button--arrow{position:absolute;width:75px;height:100px;top:50%;margin-top:-50px}.pswp__button--arrow:disabled{display:none;cursor:default}.pswp__button--arrow .pswp__icn{top:50%;margin-top:-30px;width:60px;height:60px;background:none;border-radius:0}.pswp--one-slide .pswp__button--arrow{display:none}.pswp--touch .pswp__button--arrow{visibility:hidden}.pswp--has_mouse .pswp__button--arrow{visibility:visible}.pswp__button--arrow--prev{right:auto;left:0}.pswp__button--arrow--next{right:0}.pswp__button--arrow--next .pswp__icn{left:auto;right:14px;transform:scaleX(-1)}.pswp__button--zoom{display:none}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__zoom-icn-bar-v{display:none}.pswp__preloader{position:relative;overflow:hidden;width:50px;height:60px;margin-right:auto}.pswp__preloader .pswp__icn{opacity:0;transition:opacity .2s linear;animation:pswp-clockwise .6s linear infinite}.pswp__preloader--active .pswp__icn{opacity:.85}@keyframes pswp-clockwise{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pswp__counter{height:30px;margin-top:15px;margin-inline-start:20px;font-size:14px;line-height:30px;color:var(--pswp-icon-color);text-shadow:1px 1px 3px var(--pswp-icon-color-secondary);opacity:.85}.pswp--one-slide .pswp__counter{display:none}.pswp{--pswp-root-z-index: var(--z-modal);--pswp-bg: var(--color-scrim-strong)}.media-preview-caption{position:absolute;left:0;right:0;bottom:var(--space-4);padding:0 var(--space-6);color:var(--color-text-on-scrim);font-size:var(--ui-font-size-xs);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.media-lightbox[data-v-c59e1983]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-6);background:var(--color-scrim-strong)}.media-lightbox-card[data-v-c59e1983]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);max-width:min(960px,calc(100vw - var(--space-6) * 2));max-height:calc(var(--app-height, 100vh) - var(--space-6) * 2)}.media-lightbox-frame[data-v-c59e1983]{max-width:100%;border-radius:var(--radius-md);overflow:hidden;background:var(--color-bg);box-shadow:var(--shadow-xl)}.media-lightbox-media[data-v-c59e1983]{display:block;max-width:100%;max-height:calc(var(--app-height, 100vh) - var(--space-6) * 4);object-fit:contain}.media-lightbox-name[data-v-c59e1983]{max-width:100%;color:var(--color-text-on-scrim);font-size:var(--ui-font-size-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-lightbox-close[data-v-c59e1983]{position:fixed;top:var(--space-4);right:var(--space-6);display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-surface-raised);color:var(--color-text);box-shadow:var(--shadow-sm);cursor:pointer;z-index:var(--z-modal-dropdown)}.media-lightbox-close[data-v-c59e1983]:before{content:"";position:absolute;inset:-6px}.media-lightbox-close[data-v-c59e1983]:hover{border-color:var(--color-line-strong);background:var(--color-surface-sunken)}.media-thumb[data-v-16b8c78d]{position:relative;flex:none;display:inline-flex}.media-thumb-btn[data-v-16b8c78d]{display:block;padding:0;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);overflow:hidden;cursor:pointer;transition:border-color var(--duration-fast) ease}.media-thumb-btn[data-v-16b8c78d]:hover{border-color:var(--color-line-strong)}.media-thumb-btn[data-v-16b8c78d]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.media-thumb-media[data-v-16b8c78d]{display:block;width:64px;height:64px;object-fit:cover}.media-thumb-tile[data-v-16b8c78d]{object-fit:none}.media-thumb-badge[data-v-16b8c78d]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:var(--radius-full);background:var(--color-surface-raised);border:.5px solid var(--color-line);color:var(--color-text);box-shadow:var(--shadow-sm);pointer-events:none}.media-thumb-badge.is-error[data-v-16b8c78d]{color:var(--color-danger);border-color:var(--color-danger-bd)}.media-thumb.is-error .media-thumb-btn[data-v-16b8c78d]{border-color:var(--color-danger-bd)}.media-thumb-rm[data-v-16b8c78d]{position:absolute;top:var(--space-1);right:var(--space-1);z-index:1;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:var(--color-scrim);color:var(--color-text-on-scrim);cursor:pointer}.media-thumb-rm[data-v-16b8c78d]:hover{background:var(--color-text);color:var(--color-bg)}.media-thumb-rm[data-v-16b8c78d]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.att-chip[data-v-37de1632]{display:inline-flex;align-items:center;gap:6px;max-width:220px;padding:4px 9px 4px var(--att-chip-pad-left, 5px);background:var(--color-well);border:.5px solid var(--color-line);border-radius:999px;font-size:var(--ui-font-size-sm);transition:border-color var(--duration-fast) ease}.att-chip[data-v-37de1632]:hover{border-color:var(--color-line-strong)}.att-activate[data-v-37de1632]{display:inline-flex;align-items:center;gap:6px;min-width:0;padding:0;border:none;background:transparent;color:inherit;font:inherit;cursor:pointer}.att-activate[data-v-37de1632]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:999px}.att-tile[data-v-37de1632]{width:20px;height:20px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--color-text-muted);background:var(--color-surface-sunken)}.att-tile[data-v-37de1632] .att-thumb{width:100%;height:100%;object-fit:cover;display:block}.att-name[data-v-37de1632]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text);font-weight:var(--weight-medium)}.att-chip.is-error[data-v-37de1632]{border-color:var(--color-danger-bd)}.att-chip.is-error .att-err[data-v-37de1632]{flex:none;display:flex;align-items:center;color:var(--color-danger)}.att-rm[data-v-37de1632]{flex:none;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:transparent;color:var(--color-text-faint);cursor:pointer}.att-rm[data-v-37de1632]:hover{background:var(--color-hover);color:var(--color-text)}.att-rm[data-v-37de1632]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.mascot-host[data-v-27600ac7]{position:relative;width:100%;aspect-ratio:72 / 100}.mascot-fallback[data-v-27600ac7]{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;width:86.5%;height:auto}.mascot-canvas[data-v-27600ac7]{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .25s ease}.mascot-canvas.ready[data-v-27600ac7]{opacity:1}@media(prefers-reduced-motion:reduce){.mascot-canvas[data-v-27600ac7]{transition:none}}.working-indicator[data-v-8abb44ef]{display:inline-flex;align-items:center;gap:var(--space-2);align-self:flex-start;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text-muted)}.wi-mascot[data-v-8abb44ef]{flex:none;width:40px}.wi-label[data-v-8abb44ef]{animation:wi-breathe-8abb44ef 1.6s var(--ease-in-out) infinite}@keyframes wi-breathe-8abb44ef{0%,to{opacity:1}50%{opacity:.45}}.chat-empty[data-v-765caf09]{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:24px 16px;color:var(--faint);text-align:center}.chat-empty-text[data-v-765caf09]{font-size:var(--ui-font-size-sm)}.chat-loading[data-v-765caf09]{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;padding:24px 16px;color:var(--muted)}.chat-loading-text[data-v-765caf09]{font-size:var(--ui-font-size-sm)}.chat[data-v-765caf09]{--chat-turn-gap: 16px;--chat-block-gap: 10px;--chat-section-gap: 18px;display:flex;flex-direction:column;gap:0;padding:16px 14px 20px;flex:1;min-height:0;position:relative}.chat .chat-empty[data-v-765caf09]{align-self:stretch}.open-unsupported[data-v-765caf09]{position:absolute;bottom:16px;left:50%;transform:translate(-50%);max-width:min(90%,480px);padding:6px 12px;border-radius:var(--radius-md);border:.5px solid var(--color-line);background:var(--color-surface-raised);color:var(--color-text-muted);font-size:var(--ui-font-size-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;z-index:var(--z-sticky)}.chat>.u-turn[data-v-765caf09],.chat>.a-msg[data-v-765caf09],.chat>.compact-divider[data-v-765caf09],.chat>.cron-notice[data-v-765caf09],.chat>.sending-placeholder[data-v-765caf09],.chat[data-v-765caf09]>.activity-notice{margin-top:var(--chat-turn-gap)}.chat>.a-msg[data-v-765caf09]{margin-top:10px}.chat>.u-turn[data-v-765caf09]:first-child,.chat>.a-msg[data-v-765caf09]:first-child,.chat>.compact-divider[data-v-765caf09]:first-child,.chat>.cron-notice[data-v-765caf09]:first-child,.chat>.sending-placeholder[data-v-765caf09]:first-child,.chat[data-v-765caf09]>.activity-notice:first-child{margin-top:0}.u-turn[data-v-765caf09]{display:flex;flex-direction:column;align-items:flex-end;align-self:flex-start;width:100%}.u-bub[data-v-765caf09]{align-self:flex-end;max-width:78%;background:var(--color-user-bubble-bg);color:var(--color-text);border-radius:var(--radius-lg);padding:10px 12px;font-size:var(--content-font-size);line-height:var(--leading-normal)}.u-meta[data-v-765caf09]{align-self:flex-end;display:flex;justify-content:flex-end;align-items:center;max-width:78%;margin-top:var(--space-2);margin-right:4px}.u-meta .u-edit[data-v-765caf09]{min-height:22px;box-sizing:border-box}.u-text[data-v-765caf09]{white-space:pre-wrap;overflow-wrap:anywhere}.u-text-wrap[data-v-765caf09]{position:relative;display:flex;flex-direction:column}.u-text-wrap-args[data-v-765caf09]{margin-top:var(--space-1)}.u-text-wrap.is-clamped[data-v-765caf09]{min-width:120px}.u-text-wrap.is-clamped>.u-text[data-v-765caf09],.u-text-wrap.is-clamped>.skill-act-args[data-v-765caf09]{max-height:10lh;overflow:hidden;mask-image:linear-gradient(to bottom,black calc(100% - 5lh),transparent calc(100% - 1lh));-webkit-mask-image:linear-gradient(to bottom,black calc(100% - 5lh),transparent calc(100% - 1lh))}.u-text-wrap.is-clamped>.q-body[data-v-765caf09]{max-height:3lh;overflow:hidden;mask-image:linear-gradient(to bottom,black calc(100% - 1.2lh),transparent calc(100% - .2lh));-webkit-mask-image:linear-gradient(to bottom,black calc(100% - 1.2lh),transparent calc(100% - .2lh))}.u-text-toggle[data-v-765caf09]{display:inline-flex;align-items:center;gap:var(--space-1);align-self:center;margin-top:var(--space-2);padding:var(--space-2) var(--space-4);border:none;border-radius:var(--radius-full);background:var(--color-surface-raised);box-shadow:var(--shadow-sm);color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);line-height:1;cursor:pointer;user-select:none;transition:box-shadow var(--duration-base) var(--ease-out)}.u-text-toggle[data-v-765caf09]:hover{box-shadow:var(--shadow-md)}.u-text-toggle[data-v-765caf09]:focus-visible{outline:2px solid var(--color-accent);outline-offset:1px}.u-text-wrap.is-clamped .u-text-toggle[data-v-765caf09]{position:absolute;bottom:0;left:50%;transform:translate(-50%);margin-top:0}.u-text-toggle-car[data-v-765caf09]{transition:transform var(--duration-base) var(--ease-out)}.u-text-toggle[aria-expanded=true] .u-text-toggle-car[data-v-765caf09]{transform:rotate(180deg)}.u-edit[data-v-765caf09]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s}.u-edit svg[data-v-765caf09]{display:block;flex:none}.u-edit[data-v-765caf09]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.u-edit-armed[data-v-765caf09]{--undo-hint-duration: 5s;gap:var(--space-1);opacity:1;color:var(--color-text);animation:u-edit-armed-blink-765caf09 var(--undo-hint-duration) linear forwards}.u-edit-armed[data-v-765caf09]:hover{color:var(--color-accent);background:var(--hover)}.u-edit-hint[data-v-765caf09]{display:inline-flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);font-weight:var(--weight-medium);white-space:nowrap}@keyframes u-edit-armed-blink-765caf09{0%,55%{opacity:1}62%{opacity:.45}69%{opacity:1}75%{opacity:.4}81%{opacity:.95}86%{opacity:.35}91%{opacity:.85}95%{opacity:.3}to{opacity:0}}@media(prefers-reduced-motion:reduce){.u-edit-armed[data-v-765caf09]{animation:none}}.u-copy[data-v-765caf09]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s;min-height:22px;box-sizing:border-box}.u-copy svg[data-v-765caf09]{display:block;flex:none}.u-copy[data-v-765caf09]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.u-edit-wrap[data-v-765caf09]{display:flex;justify-content:flex-end}.chat>.u-edit-wrap[data-v-765caf09]{margin-top:4px}.chat>.u-edit-wrap+.a-msg[data-v-765caf09]{margin-top:8px}.compact-divider[data-v-765caf09]{display:flex;align-items:center;gap:10px;align-self:stretch;width:100%;margin:var(--chat-section-gap) 0 0}.chat>.compact-divider[data-v-765caf09]:first-child{margin-top:0}.cd-line[data-v-765caf09]{flex:1;height:1px;background:var(--line)}.cd-label[data-v-765caf09]{flex:none;display:inline-flex;align-items:center;gap:8px;max-width:80%;font-size:var(--text-base);color:var(--muted);white-space:nowrap}.cd-btn[data-v-765caf09]{background:none;border:none;padding:0;cursor:pointer;font:inherit;font-size:var(--text-base);color:var(--muted)}.cd-view[data-v-765caf09]{color:var(--color-accent)}.cd-btn:hover .cd-view[data-v-765caf09]{text-decoration:underline}.chat>.turn-failed[data-v-765caf09]{margin-top:var(--chat-turn-gap)}.chat>.turn-failed[data-v-765caf09]:first-child{margin-top:0}.turn-failed[data-v-765caf09]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border:var(--p-hairline) solid var(--color-danger-bd);border-radius:var(--radius-lg);background:var(--color-danger-soft);box-shadow:var(--shadow-xs);animation:kimi-card-in var(--duration-slow) var(--ease-out)}.tf-chip[data-v-765caf09]{display:inline-flex;align-items:center;justify-content:center;width:var(--space-6);height:var(--space-6);border-radius:var(--radius-md);background:var(--color-surface-raised);box-shadow:var(--shadow-xs);flex:none;color:var(--color-danger)}.tf-main[data-v-765caf09]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.tf-title[data-v-765caf09]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-normal)}.tf-sub[data-v-765caf09]{font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tf-meta[data-v-765caf09]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.goal-prov[data-v-765caf09]{display:flex;align-items:center;gap:var(--space-1);margin-bottom:var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);line-height:var(--leading-normal);user-select:none}.a-msg[data-v-765caf09]{align-self:flex-start;max-width:94%;width:94%}.a-msg-ft[data-v-765caf09]{display:flex;justify-content:flex-start;align-items:center;gap:8px;height:auto;margin-top:var(--chat-block-gap);overflow:visible}.a-time[data-v-765caf09]{display:inline-flex;align-items:center;font-size:var(--text-base);color:var(--muted);line-height:1}.a-cpbtn[data-v-765caf09]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s;min-height:22px;box-sizing:border-box}.a-cpbtn[data-v-765caf09]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.a-cpbtn svg[data-v-765caf09]{display:block;flex:none}@media(hover:none){.a-msg-ft[data-v-765caf09]{height:auto;margin-top:var(--chat-block-gap);opacity:1;pointer-events:auto}.a-cpbtn[data-v-765caf09]{font-size:var(--ui-font-size-sm);padding:8px 10px;margin:-4px -6px}}.a-msg .msg[data-v-765caf09]{font-size:var(--ui-font-size);line-height:var(--leading-prose);color:var(--color-text);font-weight:500}.a-msg .msg[data-v-765caf09] p{margin:0}.a-msg .msg[data-v-765caf09] p+p{margin-top:8px}.a-msg>.msg[data-v-765caf09],.a-msg[data-v-765caf09]>.think,.a-msg[data-v-765caf09]>.tool-group,.a-msg[data-v-765caf09]>.activity-run,.a-msg[data-v-765caf09]>.agent-card,.a-msg[data-v-765caf09]>.agent-group,.a-msg[data-v-765caf09]>.tool-line,.a-msg[data-v-765caf09]>.swarm-card,.a-msg[data-v-765caf09]>.media-tool,.a-msg[data-v-765caf09]>.ask-receipt{margin-top:var(--chat-block-gap)}.a-msg>.msg[data-v-765caf09]:first-child,.a-msg[data-v-765caf09]>.think:first-child,.a-msg[data-v-765caf09]>.tool-group:first-child,.a-msg[data-v-765caf09]>.activity-run:first-child,.a-msg[data-v-765caf09]>.agent-card:first-child,.a-msg[data-v-765caf09]>.agent-group:first-child,.a-msg[data-v-765caf09]>.tool-line:first-child,.a-msg[data-v-765caf09]>.swarm-card:first-child,.a-msg[data-v-765caf09]>.media-tool:first-child,.a-msg[data-v-765caf09]>.ask-receipt:first-child{margin-top:0}.a-msg>.goal-prov:first-child+.msg[data-v-765caf09],.a-msg>.goal-prov[data-v-765caf09]:first-child+.think,.a-msg>.goal-prov[data-v-765caf09]:first-child+.tool-group,.a-msg>.goal-prov[data-v-765caf09]:first-child+.activity-run,.a-msg>.goal-prov[data-v-765caf09]:first-child+.agent-card,.a-msg>.goal-prov[data-v-765caf09]:first-child+.agent-group,.a-msg>.goal-prov[data-v-765caf09]:first-child+.tool-line,.a-msg>.goal-prov[data-v-765caf09]:first-child+.swarm-card,.a-msg>.goal-prov[data-v-765caf09]:first-child+.media-tool,.a-msg>.goal-prov[data-v-765caf09]:first-child+.ask-receipt,.a-msg>.goal-prov[data-v-765caf09]:first-child+.turn-fold{margin-top:0}.a-msg[data-v-765caf09] :not(pre)>code{font:.9em var(--font-mono);background:var(--color-inline-code-bg);border:.5px solid var(--color-line);border-radius:var(--radius-sm);padding:1px 6px;color:var(--color-accent-hover)}@container (min-width: 760px){.a-msg .msg[data-v-765caf09] .markstream-vue.markdown-renderer:has(.table-node-wrapper.md-table-wide){content-visibility:visible}.a-msg .msg[data-v-765caf09] .table-node-wrapper.md-table-wide{position:relative;left:50%;width:max-content;min-width:100%;max-width:min(var(--p-table-max),calc(100cqi - var(--space-5) - var(--space-5)))!important;transform:translate(-50%)}.a-msg .msg[data-v-765caf09] .table-node-wrapper:not(.md-table-wide){--table-cell-cap: min(var(--p-table-cell-max), 36cqi)}}.u-media[data-v-765caf09]{display:flex;flex-wrap:wrap;gap:var(--space-2)}.u-media[data-v-765caf09]:not(:last-child){margin-bottom:var(--space-2)}.u-atts[data-v-765caf09]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.sending-placeholder[data-v-765caf09]{align-self:flex-start;padding:10px 0}.skill-act[data-v-765caf09]{display:flex;flex-direction:column;gap:2px}.skill-act-head[data-v-765caf09]{font-size:var(--ui-font-size-sm);font-weight:500;color:var(--color-accent-hover);display:flex;align-items:center;gap:6px}.skill-act-arrow[data-v-765caf09]{color:var(--color-accent);font-size:var(--text-base)}.skill-act-args[data-v-765caf09]{font-size:var(--text-base);color:var(--muted);padding-left:17px;white-space:pre-wrap;overflow-wrap:anywhere}@media(max-width:640px){.chat[data-v-765caf09]{box-sizing:border-box;width:100%;padding:14px max(12px,var(--safe-right)) 18px max(12px,var(--safe-left))}.u-bub[data-v-765caf09]{max-width:min(88%,calc(100vw - 52px))}.a-msg[data-v-765caf09]{width:100%;max-width:100%}.a-msg[data-v-765caf09] .md,.a-msg[data-v-765caf09] .markdown-renderer,.a-msg[data-v-765caf09] .code-block-container,.a-msg[data-v-765caf09] .diff-wrap,.a-msg[data-v-765caf09] pre{max-width:100%}.a-msg[data-v-765caf09] .code-block-container pre,.a-msg[data-v-765caf09] .diff-pre{overflow-x:auto;-webkit-overflow-scrolling:touch}.a-msg[data-v-765caf09] .media-tool.mob{width:min(44vw,160px)}.cd-label[data-v-765caf09]{min-width:0;max-width:calc(100% - 48px);overflow:hidden;text-overflow:ellipsis}.u-edit-confirm[data-v-765caf09]{flex-wrap:wrap;justify-content:flex-end;max-width:calc(100vw - 28px)}.ts[data-v-765caf09]{font-size:var(--ui-font-size-sm)}.chat-empty-text[data-v-765caf09],.chat-loading-text[data-v-765caf09]{font-size:var(--ui-font-size-lg)}.cd-label[data-v-765caf09],.cd-btn[data-v-765caf09]{font-size:var(--ui-font-size)}}.top-sentinel[data-v-765caf09]{display:flex;align-items:center;justify-content:center;padding:12px 0;min-height:28px;user-select:none}.top-sentinel-loading[data-v-765caf09]{opacity:.8}.top-sentinel-btn[data-v-765caf09]{appearance:none;border:.5px solid var(--border);background:transparent;color:var(--muted);font-size:var(--ui-font-size-sm);padding:4px 12px;border-radius:999px;cursor:pointer;transition:color .15s ease,border-color .15s ease}.top-sentinel-btn[data-v-765caf09]:hover{color:var(--fg);border-color:var(--fg)}.top-sentinel-text[data-v-765caf09]{display:inline-flex;align-items:center;gap:8px;color:var(--muted);font-size:var(--ui-font-size-sm)}.chat[data-v-765caf09]{background:transparent}.chat[data-v-765caf09]{gap:0;padding:22px 20px 26px}.u-bub[data-v-765caf09]{background:var(--color-user-bubble-bg);border-radius:var(--radius-lg);padding:10px 12px}.a-msg[data-v-765caf09]{max-width:100%;width:100%}.chat>.q-stack[data-v-765caf09]{margin-top:var(--chat-turn-gap)}.chat>.q-stack[data-v-765caf09]:first-child{margin-top:0}.q-stack[data-v-765caf09]{align-self:flex-end;width:100%;display:flex;flex-direction:column;gap:8px}.q-head[data-v-765caf09]{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 6px;color:var(--color-text-faint);font-size:var(--ui-font-size-xs)}.q-title[data-v-765caf09]{display:inline-flex;align-items:center;gap:6px}.q-title b[data-v-765caf09]{color:var(--color-accent-hover);font-weight:var(--weight-medium)}.q-turn[data-v-765caf09]{position:relative;flex-direction:row;align-items:center;justify-content:flex-end;gap:var(--space-2)}.q-send[data-v-765caf09]{flex:none;width:var(--space-6);height:var(--space-6);display:inline-flex;align-items:center;justify-content:center;padding:0;border:none;border-radius:var(--radius-full);background:var(--color-accent);color:var(--color-text-on-accent);box-shadow:var(--shadow-xs);cursor:pointer;transition:background var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.q-send[data-v-765caf09]:hover{background:var(--color-accent-hover)}.q-send[data-v-765caf09]:active{transform:scale(.92)}.q-send[data-v-765caf09]:focus-visible{outline:2px solid var(--color-accent);outline-offset:1px}.q-send svg[data-v-765caf09]{display:block;flex:none}.q-bub[data-v-765caf09]{display:flex;align-items:center;gap:8px;width:fit-content;background:var(--color-user-bubble-bg);padding:8px 8px 8px 6px;transition:background var(--duration-fast) var(--ease-out)}.q-bub[data-v-765caf09]:hover{background:var(--hover)}.q-grip[data-v-765caf09]{flex:none;display:inline-flex;align-items:center;padding:2px;color:var(--color-text-faint);cursor:grab;opacity:.7}.q-grip[data-v-765caf09]:hover{opacity:1}.q-grip[data-v-765caf09]:active{cursor:grabbing}.q-clamp[data-v-765caf09]{flex:1;min-width:0}.q-body[data-v-765caf09]{flex:1;min-width:0;background:none;border:none;padding:0;margin:0;font:inherit;color:var(--color-text);text-align:left;cursor:pointer;opacity:.82}.q-bub:hover .q-body[data-v-765caf09]{opacity:1}.q-body[data-v-765caf09]:disabled{cursor:default}.q-text[data-v-765caf09]{white-space:pre-wrap;overflow-wrap:anywhere}.q-text-placeholder[data-v-765caf09]{display:inline-flex;align-items:center;gap:4px;color:var(--color-text-muted)}.q-imgs[data-v-765caf09]{display:flex;gap:4px;flex:none}.q-img[data-v-765caf09]{width:28px;height:28px;object-fit:cover;border-radius:var(--radius-sm);border:.5px solid var(--color-line)}.q-file[data-v-765caf09]{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 6px;border-radius:var(--radius-sm);border:.5px solid var(--color-line);color:var(--color-text-muted);font-size:calc(var(--ui-font-size) - 3px);max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.q-rm[data-v-765caf09]{flex:none;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--radius-sm);color:var(--color-text-faint);cursor:pointer;opacity:0;transition:opacity .12s ease,background .12s ease,color .12s ease}.q-bub:hover .q-rm[data-v-765caf09],.q-bub:focus-within .q-rm[data-v-765caf09],.q-rm[data-v-765caf09]:focus-visible{opacity:1}.q-rm[data-v-765caf09]:hover{background:var(--color-danger-soft);color:var(--color-danger)}.q-edit[data-v-765caf09]{display:none;flex:none;width:22px;height:22px;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--radius-sm);color:var(--color-text-faint);cursor:pointer}.q-edit[data-v-765caf09]:hover{background:var(--color-hover);color:var(--color-text)}@media(hover:none){.q-grip[data-v-765caf09]{display:none}.q-edit[data-v-765caf09]{display:inline-flex}.q-rm[data-v-765caf09],.q-edit[data-v-765caf09]{opacity:1;position:relative}.q-rm[data-v-765caf09]:before,.q-edit[data-v-765caf09]:before{content:"";position:absolute;inset:-11px}}.q-turn.q-dragging .q-bub[data-v-765caf09]{opacity:.45}.q-turn.drop-before[data-v-765caf09]:before,.q-turn.drop-after[data-v-765caf09]:after{content:"";position:absolute;left:0;right:0;height:2px;background:var(--color-accent);border-radius:var(--radius-full);z-index:1}.q-turn.drop-before[data-v-765caf09]:before{top:-5px}.q-turn.drop-after[data-v-765caf09]:after{bottom:-5px}.chat-header[data-v-2fde3f1e]{flex:none;display:flex;align-items:center;gap:14px;height:var(--panel-head-h, 48px);padding:0 16px;border-bottom:.5px solid var(--color-line);background:var(--color-bg);font-family:var(--font-ui);min-width:0;user-select:none;container-type:inline-size}.chat-header.macos-desktop[data-v-2fde3f1e]{-webkit-app-region:drag}.chat-header.macos-desktop button[data-v-2fde3f1e],.chat-header.macos-desktop input[data-v-2fde3f1e]{-webkit-app-region:no-drag}.ch-id[data-v-2fde3f1e]{display:flex;align-items:center;gap:6px;min-width:0;flex:none;max-width:46%}.ch-ws[data-v-2fde3f1e]{color:var(--color-text-muted);font-size:var(--text-base);font-weight:var(--weight-medium);flex:none}.ch-sep[data-v-2fde3f1e]{color:var(--color-text-faint);flex:none}.ch-ses[data-v-2fde3f1e]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ch-rename[data-v-2fde3f1e]{flex:1;min-width:0;font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs);padding:2px 5px;outline:none;user-select:text}.ch-git[data-v-2fde3f1e]{display:flex;align-items:center;gap:4px;border:none;background:transparent;padding:0;color:var(--muted);font-family:var(--font-ui);font-size:calc(var(--ui-font-size) - 2px);flex:0 1 auto;max-width:none;min-width:0;cursor:pointer}.ch-git:hover .ch-branch[data-v-2fde3f1e]{color:var(--color-text)}.ch-branch-icon[data-v-2fde3f1e]{flex:none;color:var(--color-text-muted)}.ch-branch[data-v-2fde3f1e]{color:var(--dim);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-right:4px}.ch-detached[data-v-2fde3f1e]{color:var(--muted);font-style:italic}.ch-pill[data-v-2fde3f1e]{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border-radius:999px;background:var(--panel);border:.5px solid var(--line);font-size:calc(var(--ui-font-size) - 3px)}.ch-sync-pill[data-v-2fde3f1e]{border-color:var(--line)}.ch-diff-pill[data-v-2fde3f1e]{border-color:color-mix(in srgb,var(--color-success) 20%,var(--line));font-variant-numeric:tabular-nums}.ch-ahead[data-v-2fde3f1e]{color:var(--color-warning);flex:none}.ch-behind[data-v-2fde3f1e]{color:var(--color-accent-hover);flex:none}.ch-add[data-v-2fde3f1e]{color:var(--color-success);flex:none}.ch-del[data-v-2fde3f1e]{color:var(--color-danger);flex:none}.ch-spacer[data-v-2fde3f1e]{flex:1;min-width:0}@container (max-width: 720px){.ch-ws[data-v-2fde3f1e],.ch-sep[data-v-2fde3f1e]{display:none}.ch-id[data-v-2fde3f1e]{flex:1;max-width:none}.ch-spacer[data-v-2fde3f1e]{flex:0}}.chat-header .ch-act-more[data-v-2fde3f1e]{width:24px;height:24px;border-radius:var(--radius-sm)}.chat-header .ch-act-more[data-v-2fde3f1e] svg{width:14px;height:14px}.ch-act-more.open[data-v-2fde3f1e]{background:var(--color-well);color:var(--color-text)}.ch-dev[data-v-2fde3f1e]{display:inline-flex;align-items:center;height:22px;padding:0 9px;flex:none;border:.5px solid var(--color-warning-bd);border-radius:var(--radius-full);background:var(--color-warning-soft);color:var(--color-warning);font-size:var(--text-xs);font-weight:500}.ch-pr[data-v-2fde3f1e]{display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 9px;flex:none;border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-well);color:var(--color-text-muted);font-size:var(--text-xs);font-weight:500;cursor:pointer}.ch-pr svg[data-v-2fde3f1e]{flex:none}.ch-pr.pr-open[data-v-2fde3f1e]{color:var(--color-success);border-color:var(--color-success-bd);background:var(--color-success-soft)}.ch-pr.pr-merged[data-v-2fde3f1e]{color:var(--color-done);border-color:var(--color-done-bd);background:var(--color-done-soft)}.ch-pr.pr-closed[data-v-2fde3f1e]{color:var(--color-danger);border-color:var(--color-danger-bd);background:var(--color-danger-soft)}.ch-pr.pr-draft[data-v-2fde3f1e],.ch-pr.pr-unknown[data-v-2fde3f1e]{color:var(--color-text-muted);border-color:var(--color-line-strong);background:var(--color-well)}.ch-pr[data-v-2fde3f1e]:hover{border-color:var(--color-line-strong)}.ch-done-pill[data-v-2fde3f1e]{cursor:default}.ch-done-pill[data-v-2fde3f1e]:hover{border-color:var(--color-done-bd)}.ch-menu[data-v-2fde3f1e]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.menu-pop-enter-active[data-v-2fde3f1e]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-2fde3f1e]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-2fde3f1e],.menu-pop-leave-to[data-v-2fde3f1e]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}@media(max-width:980px){.ch-act-label[data-v-2fde3f1e]{display:none}}@media(max-width:640px){.chat-header[data-v-2fde3f1e]{display:none}}.slash-menu[data-menu-frame][data-v-ac34fe29]{position:absolute;bottom:calc(100% + var(--space-2));left:0;right:0;padding:var(--space-1-5) var(--space-3);background:var(--color-menu-bg-frost);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);z-index:var(--z-dropdown)}.slash-menu.is-sheet[data-menu-frame][data-v-ac34fe29]{position:static;padding:0;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;border:none;border-radius:0;box-shadow:none;z-index:auto}.slash-menu.is-sheet .slash-scroll[data-v-ac34fe29]{margin:0;padding:var(--space-1) var(--space-2)}.slash-menu.is-sheet .slash-item[data-v-ac34fe29]{margin:0;padding-left:var(--space-2);padding-right:var(--space-2)}.slash-scroll[data-v-ac34fe29]{max-height:var(--p-slash-menu-h);margin:0 calc(-1 * var(--menu-row-hug));padding:0 var(--menu-row-hug);overflow-y:auto;scrollbar-width:none}.slash-scroll[data-v-ac34fe29]::-webkit-scrollbar{display:none}.scroll-thumb[data-v-ac34fe29]{position:absolute;right:var(--menu-scrollbar-edge);width:var(--menu-scrollbar-width);border-radius:var(--radius-full);background:var(--color-menu-scrollbar);transition:background var(--duration-base) var(--ease-out);cursor:default;touch-action:none;z-index:var(--z-raised)}.slash-menu:hover .scroll-thumb[data-v-ac34fe29]{background:var(--color-menu-scrollbar-hover)}.scroll-thumb[data-v-ac34fe29]:before{content:"";position:absolute;top:0;bottom:0;left:calc(-1 * var(--space-2));right:0}.slash-item[data-v-ac34fe29]{display:flex;align-items:baseline;gap:var(--space-2);margin:0 calc(-1 * var(--menu-row-hug));padding:var(--menu-row-padding-block) var(--menu-row-padding-inline);cursor:pointer;font-family:var(--font-ui);font-size:var(--ui-b2);border-radius:var(--radius-menu-row)}.slash-item[data-v-ac34fe29]:hover{background:var(--color-hover)}.slash-item.active[data-v-ac34fe29]{background:var(--color-selected)}.slash-item+.slash-item[data-v-ac34fe29]{margin-top:var(--menu-rows-seam)}.slash-name[data-v-ac34fe29]{flex:none;max-width:60%;color:var(--color-text);font-weight:500;min-width:0;line-height:var(--leading-normal);overflow-wrap:anywhere}.slash-match[data-v-ac34fe29]{font-weight:var(--weight-semibold)}.slash-empty[data-v-ac34fe29]{padding:var(--space-1-5) var(--space-1);color:var(--color-text-muted)}@media(hover:none){.slash-item[data-v-ac34fe29]{min-height:var(--touch-target-min);padding-top:var(--menu-row-touch-padding-block);padding-bottom:var(--menu-row-touch-padding-block)}}.slash-desc[data-v-ac34fe29]{flex:1;min-width:0;color:var(--color-text-muted);font-size:var(--ui-b2);font-weight:var(--weight-regular);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.slash-desc-match[data-v-ac34fe29]{font-weight:var(--weight-semibold)}@media(max-width:520px){.slash-item[data-v-ac34fe29]{flex-direction:column;align-items:stretch;gap:var(--space-05)}.slash-name[data-v-ac34fe29]{max-width:none}}.mention-menu[data-menu-frame][data-v-8b392586]{position:absolute;bottom:calc(100% + var(--space-2));left:0;right:0;padding:var(--space-1-5) var(--space-3);background:var(--color-menu-bg-frost);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);z-index:var(--z-dropdown)}.mention-menu.is-sheet[data-menu-frame][data-v-8b392586]{position:static;padding:0;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;border:none;border-radius:0;box-shadow:none;z-index:auto}.mention-menu.is-sheet .mention-scroll[data-v-8b392586]{margin:0;padding:var(--space-1) var(--space-2)}.mention-menu.is-sheet .mention-item[data-v-8b392586]{margin:0;padding-left:var(--space-2);padding-right:var(--space-2)}.mention-menu.is-sheet .mention-state[data-v-8b392586]{padding-left:var(--space-4)}.mention-scroll[data-v-8b392586]{max-height:var(--p-mention-menu-h);margin:0 calc(-1 * var(--menu-row-hug));padding:0 var(--menu-row-hug);overflow-y:auto;scrollbar-width:none}.mention-scroll[data-v-8b392586]::-webkit-scrollbar{display:none}.scroll-thumb[data-v-8b392586]{position:absolute;right:var(--menu-scrollbar-edge);width:var(--menu-scrollbar-width);border-radius:var(--radius-full);background:var(--color-menu-scrollbar);transition:background var(--duration-base) var(--ease-out);cursor:default;touch-action:none;z-index:var(--z-raised)}.mention-menu:hover .scroll-thumb[data-v-8b392586]{background:var(--color-menu-scrollbar-hover)}.scroll-thumb[data-v-8b392586]:before{content:"";position:absolute;top:0;bottom:0;left:calc(-1 * var(--space-2));right:0}.mention-state[data-v-8b392586]{padding:var(--space-2) var(--space-1);font-family:var(--font-ui);font-size:var(--ui-b2)}.mention-spin[data-v-8b392586]{position:absolute;top:var(--space-2);right:var(--space-3);color:var(--color-text-muted);z-index:var(--z-raised)}.dim[data-v-8b392586]{color:var(--color-text-muted)}.mention-item[data-v-8b392586]{display:flex;align-items:center;gap:var(--menu-row-gap-icon);margin:0 calc(-1 * var(--menu-row-hug));padding:var(--menu-row-padding-block) var(--space-2);cursor:pointer;font-family:var(--font-ui);font-size:var(--text-sm);border-radius:var(--radius-menu-row)}.mention-icon[data-v-8b392586]{display:inline-flex;align-items:center;justify-content:center;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--muted);flex-shrink:0}.mention-icon[data-v-8b392586] svg{width:var(--p-ic-sm);height:var(--p-ic-sm);display:block}.mention-item:hover .mention-icon[data-v-8b392586],.mention-item.active .mention-icon[data-v-8b392586]{color:var(--color-text-strong)}.mention-item[data-v-8b392586]:hover{background:var(--color-hover)}.mention-item:hover .mention-name[data-v-8b392586],.mention-item.active .mention-name[data-v-8b392586]{color:var(--color-text-strong)}.mention-item.active[data-v-8b392586]{background:var(--color-selected)}.mention-item+.mention-item[data-v-8b392586]{margin-top:var(--menu-rows-seam)}.mention-item[data-v-8b392586]{transition:opacity var(--duration-slow) var(--ease-out)}.mention-item.stale[data-v-8b392586]{opacity:var(--opacity-stale)}@media(hover:none){.mention-item[data-v-8b392586]{min-height:var(--touch-target-min);padding-top:var(--menu-row-touch-padding-block);padding-bottom:var(--menu-row-touch-padding-block)}}.mention-name[data-v-8b392586]{color:var(--color-text);font-weight:500;flex-shrink:0}.mention-name .mention-hit[data-v-8b392586]{color:var(--color-text-strong);font-weight:var(--weight-semibold)}.mention-meta .mention-hit[data-v-8b392586]{color:var(--color-text)}.mention-meta[data-v-8b392586]{color:var(--color-text-muted);font-size:inherit;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sheet-root[data-v-d719a5d1]{position:fixed;inset:0;z-index:var(--z-overlay);display:flex;flex-direction:column;justify-content:flex-end}.sheet-scrim[data-v-d719a5d1]{position:absolute;inset:0;background:#0d111773}.sheet-panel[data-v-d719a5d1]{position:relative;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-bottom:none;border-radius:var(--radius-xl) var(--radius-xl) 0 0;box-shadow:var(--shadow-xl);max-height:calc(var(--app-height, 100dvh) * .86);display:flex;flex-direction:column;min-height:0;font-family:var(--font-ui);color:var(--color-text)}.sheet-grab[data-v-d719a5d1]{flex:none;align-self:center;width:56px;height:18px;padding:0;border:none;background:none;cursor:pointer;position:relative;margin-top:4px}.sheet-grab[data-v-d719a5d1]:after{content:"";position:absolute;left:50%;top:7px;transform:translate(-50%);width:38px;height:5px;border-radius:var(--radius-full);background:var(--color-line)}.sheet-head[data-v-d719a5d1]{flex:none;display:flex;align-items:center;justify-content:space-between;padding:6px 16px 10px}.sheet-title[data-v-d719a5d1]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.sheet-body[data-v-d719a5d1]{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:max(16px,var(--safe-bottom))}.sheet-enter-active[data-v-d719a5d1],.sheet-leave-active[data-v-d719a5d1]{transition:opacity var(--duration-slow) var(--ease-out)}.sheet-enter-active .sheet-panel[data-v-d719a5d1],.sheet-leave-active .sheet-panel[data-v-d719a5d1]{transition:transform var(--duration-slow) var(--ease-out)}.sheet-enter-from[data-v-d719a5d1],.sheet-leave-to[data-v-d719a5d1]{opacity:0}.sheet-enter-from .sheet-panel[data-v-d719a5d1],.sheet-leave-to .sheet-panel[data-v-d719a5d1]{transform:translateY(102%)}.composer[data-v-5a96480c]{padding:7px var(--dock-inline-right, 16px) 12px var(--dock-inline-left, 16px);background:transparent;transition:background .12s}.composer.drag-over[data-v-5a96480c]{background:var(--color-accent-soft)}.drop-overlay[data-v-5a96480c]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--color-bg) 72%,transparent);pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--duration-base) ease,visibility var(--duration-base)}.drop-overlay.show[data-v-5a96480c]{opacity:1;visibility:visible}.drop-card[data-v-5a96480c]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-6);border-radius:var(--radius-lg);border:.5px dashed var(--color-accent);background:var(--color-bg);color:var(--color-accent);font-size:var(--ui-font-size-lg);font-weight:var(--weight-medium);box-shadow:var(--shadow-md)}.composer-card[data-v-5a96480c]{--composer-control-size: var(--space-8);--composer-send-size: var(--composer-control-size);--composer-control-inset: var(--space-2);--composer-valve-floor: 4em;--composer-valve-expand-margin: 3.4em;position:relative;border:.5px solid var(--color-composer-line);border-radius:var(--radius-composer);corner-shape:var(--corner-shape-composer);background:var(--color-composer-bg);box-shadow:var(--shadow-input);user-select:none;container-type:inline-size}.composer-card[data-v-5a96480c]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--color-composer-focus-line);border-radius:var(--radius-composer);corner-shape:var(--corner-shape-composer);opacity:0;pointer-events:none;transition:opacity var(--duration-slow) var(--ease-in-out)}.composer-card[data-v-5a96480c]:focus-within:after{opacity:1}.att-strip[data-v-5a96480c]{position:relative;padding:calc(var(--space-4) + var(--space-05)) var(--space-4) 0 calc(var(--space-4) + var(--space-05))}.att-scroll[data-v-5a96480c]{max-height:calc(128px + var(--space-2));overflow-y:auto;margin-right:calc(var(--icon-button-sm) + var(--space-1))}.att-scroll-content[data-v-5a96480c]{display:flex;flex-direction:column;gap:var(--space-2);padding-right:var(--space-1)}.att-scroll.is-overflowing[data-v-5a96480c]{padding-bottom:var(--space-6)}.att-more[data-v-5a96480c]{position:absolute;left:var(--space-4);bottom:var(--space-1);z-index:var(--z-raised);display:inline-flex;align-items:center;height:18px;padding:0 var(--space-2);border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-surface-raised);color:var(--color-text-muted);font-size:var(--text-xs);box-shadow:var(--shadow-sm);pointer-events:none}.att-row[data-v-5a96480c]{display:flex;flex-wrap:wrap;gap:6px}.att-row-media[data-v-5a96480c]{gap:var(--space-2)}.att-scroll-content[data-v-5a96480c] .att-chip{corner-shape:superellipse(1.5)}.att-scroll-content[data-v-5a96480c] .att-tile{margin-left:calc(-1 * (var(--att-chip-pad-left, 5px) + var(--space-05)))}.att-clear[data-v-5a96480c]{position:absolute;top:calc(var(--space-4) + var(--space-05));right:var(--space-4);z-index:var(--z-raised)}.file-input-hidden[data-v-5a96480c]{display:none}.cin-wrap[data-v-5a96480c]{position:relative;padding:14px 16px 8px}.input-row[data-v-5a96480c]{position:relative;display:flex;align-items:flex-start;gap:var(--space-2)}.expand-btn[data-v-5a96480c]{width:22px;height:22px;display:flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:var(--dim);cursor:pointer;padding:0;transition:background .12s,color .12s}.expand-btn[data-v-5a96480c]:hover{background:var(--panel2);color:var(--color-text)}.expand-btn[data-v-5a96480c]:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}.ph[data-v-5a96480c]{color:var(--faint);caret-color:var(--color-text);flex:1;border:none;outline:none;resize:none;font-family:var(--font-ui);font-size:var(--content-font-size);text-autospace:normal;background:transparent;min-height:36px;max-height:calc(var(--app-height, 100dvh) / 4);overflow-y:auto;scrollbar-width:none;line-height:1.5;margin-bottom:6px;user-select:text}.ph[data-v-5a96480c]::-webkit-scrollbar{display:none}.ph[data-v-5a96480c]::placeholder{color:var(--muted)}.ph[data-v-5a96480c]:not(:placeholder-shown){color:var(--color-text)}.composer.expanded .ph[data-v-5a96480c]{min-height:calc(var(--app-height, 100dvh) * .7);max-height:calc(var(--app-height, 100dvh) * .7)}.compact-chip[data-v-5a96480c]{height:var(--composer-control-size);padding:0 var(--space-2);border:.5px solid transparent;border-radius:var(--radius-full);background:transparent;color:var(--color-warning);font-family:var(--mono);font-size:var(--ui-font-size);cursor:pointer;line-height:1;flex:none;transition:background var(--duration-base) var(--ease-out)}.compact-chip[data-v-5a96480c]:hover{background:var(--color-hover)}.composer-attach[data-v-5a96480c]{width:var(--composer-control-size);height:var(--composer-control-size);border-radius:var(--radius-full);flex:none}.add-menu[data-v-5a96480c]{position:absolute;bottom:calc(100% + var(--space-2));left:0;right:0;z-index:var(--z-dropdown);background:var(--color-menu-bg-frost);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:var(--space-1-5) var(--space-3);display:flex;flex-direction:column;gap:var(--menu-rows-seam);font-family:var(--font-ui);transform-origin:bottom left}.am-scroll[data-v-5a96480c]{max-height:var(--p-add-menu-h);margin:0 calc(-1 * var(--menu-row-hug));padding:0 var(--menu-row-hug);overflow-y:auto;scrollbar-width:none;display:flex;flex-direction:column;gap:var(--menu-rows-seam)}.am-scroll[data-v-5a96480c]::-webkit-scrollbar{display:none}.scroll-thumb[data-v-5a96480c]{position:absolute;right:var(--menu-scrollbar-edge);width:var(--menu-scrollbar-width);border-radius:var(--radius-full);background:var(--color-menu-scrollbar);transition:background var(--duration-base) var(--ease-out);pointer-events:none;z-index:var(--z-raised)}.add-menu:hover .scroll-thumb[data-v-5a96480c]{background:var(--color-menu-scrollbar-hover)}.msheet-search[data-v-5a96480c]{padding:0 var(--space-4) var(--space-2)}.msheet-add[data-v-5a96480c]{display:flex;flex-direction:column;gap:var(--menu-rows-seam);padding:0 var(--menu-row-hug);font-family:var(--font-ui)}.am-row[data-v-5a96480c]{display:flex;align-items:center;gap:var(--menu-row-gap-icon);margin:0 calc(-1 * var(--menu-row-hug));padding:var(--menu-row-padding-block) var(--menu-row-padding-inline);border:none;border-radius:var(--radius-menu-row);background:none;cursor:pointer;font-size:var(--ui-font-size);color:var(--color-text);text-align:left;transition:background var(--duration-base) var(--ease-out)}.am-row[data-v-5a96480c]:hover{background:var(--color-hover)}.am-row[data-v-5a96480c]:focus-visible{background:var(--color-selected);outline:none}@media(hover:none){.am-row[data-v-5a96480c]{padding-top:var(--menu-row-touch-padding-block);padding-bottom:var(--menu-row-touch-padding-block)}}.am-row:hover .am-icon[data-v-5a96480c],.am-row:focus-visible .am-icon[data-v-5a96480c]{color:var(--color-text)}.am-icon[data-v-5a96480c]{flex:none;width:var(--p-ic-sm);display:flex;justify-content:center;color:var(--color-text-muted);transition:color var(--duration-base) var(--ease-out)}.am-name[data-v-5a96480c]{flex:none;font-weight:var(--weight-medium)}.am-desc[data-v-5a96480c]{margin-left:var(--space-1);color:var(--color-text-muted);font-size:var(--ui-font-size-sm)}.send[data-v-5a96480c]{width:var(--composer-send-size);height:var(--composer-send-size);border-radius:var(--radius-full);background:var(--color-send-bg);color:var(--color-send-icon);border:none;box-shadow:var(--shadow-send);padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background var(--duration-slow) var(--ease-out),transform var(--duration-fast) var(--ease-out),box-shadow var(--duration-slow) var(--ease-out);position:relative}.send[data-v-5a96480c]:hover:not(:disabled){background:var(--color-send-bg-hover);box-shadow:var(--shadow-send-hover)}.send[data-v-5a96480c]:active{transform:scale(.92)}.send[data-v-5a96480c]:disabled{cursor:not-allowed;background:var(--color-send-bg-disabled);color:var(--color-send-icon-disabled);opacity:var(--opacity-send-disabled)}.send[data-v-5a96480c]:disabled:active{transform:none}.send.is-starting[data-v-5a96480c]:disabled{background:var(--color-send-bg);color:var(--color-send-icon)}.send.is-starting[data-v-5a96480c] .ui-spinner{color:var(--color-send-icon)}.send.is-starting[data-v-5a96480c] .ui-spinner__track{stroke:color-mix(in srgb,var(--color-send-icon) 32%,transparent)}.send svg[data-v-5a96480c]{flex:none;width:var(--composer-send-icon-size);height:var(--composer-send-icon-size)}.stop[data-v-5a96480c]{width:var(--composer-send-size);height:var(--composer-send-size);border-radius:var(--radius-full);background:var(--color-subtle);color:var(--color-stop-glyph);border:none;box-shadow:var(--shadow-xs);padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .16s ease,color .16s ease,transform .12s ease}.stop[data-v-5a96480c]:hover{background:var(--color-danger);color:var(--color-text-on-accent)}.stop[data-v-5a96480c]:active{transform:scale(.92)}.stop svg[data-v-5a96480c]{flex:none;width:var(--composer-send-icon-size);height:var(--composer-send-icon-size)}.toolbar[data-v-5a96480c]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);padding:var(--space-1) var(--composer-control-inset) var(--composer-control-inset);position:relative}.menu-measure[data-v-5a96480c]{position:absolute;width:max-content;height:0;overflow:hidden;visibility:hidden;pointer-events:none}.toolbar-left[data-v-5a96480c],.toolbar-right[data-v-5a96480c]{display:flex;align-items:center;gap:var(--space-1);min-width:0}.toolbar-left[data-v-5a96480c]{flex:none;overflow:hidden}.toolbar-right[data-v-5a96480c]{flex:1 1 auto;justify-content:flex-end}.perm-pill[data-v-5a96480c],.swarm-chip[data-v-5a96480c],.model-pill[data-v-5a96480c]{position:relative;display:inline-flex;align-items:center;gap:var(--space-1);height:var(--composer-control-size);padding:0 var(--space-3);border:.5px solid transparent;border-radius:var(--radius-full);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;cursor:pointer;user-select:none;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.perm-pill[data-v-5a96480c]{font-size:var(--ui-font-size-sm)}.perm-pill[data-v-5a96480c]:after,.swarm-chip[data-v-5a96480c]:after,.model-pill[data-v-5a96480c]:after{content:"";position:absolute;inset:0;border-radius:var(--radius-full);background:var(--color-hover);opacity:0;transition:opacity var(--duration-base) var(--ease-out);pointer-events:none}.perm-pill[data-v-5a96480c]:hover:after,.swarm-chip[data-v-5a96480c]:hover:after,.model-pill[data-v-5a96480c]:hover:after{opacity:1}.perm-pill.open[data-v-5a96480c],.model-pill.open[data-v-5a96480c]{background:var(--color-accent-soft)}.swarm-chip[data-v-5a96480c]{cursor:default}.swarm-x[data-v-5a96480c]{margin-right:calc(var(--composer-control-size) / 2 - var(--space-3) - var(--icon-button-sm) / 2);color:inherit;opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.swarm-chip .swarm-x[data-v-5a96480c]{border-radius:var(--radius-full)}.swarm-chip:hover .swarm-x[data-v-5a96480c],.swarm-x[data-v-5a96480c]:focus-visible{opacity:1}@media(hover:none){.toolbar-left[data-v-5a96480c]{padding-right:var(--space-2)}.swarm-chip[data-v-5a96480c]{margin-right:calc((var(--touch-target-min) - var(--icon-button-sm)) / 2 - var(--space-1))}.swarm-x[data-v-5a96480c]{opacity:1;position:relative}.swarm-x[data-v-5a96480c]:before{content:"";position:absolute;inset:calc(-1 * (var(--touch-target-min) - var(--icon-button-sm)) / 2)}}.perm-pill.perm-manual[data-v-5a96480c]{color:var(--dim)}.perm-pill.perm-yolo[data-v-5a96480c]{color:var(--color-warning)}.perm-pill.perm-auto[data-v-5a96480c]{color:var(--color-danger)}.perm-pill-icon[data-v-5a96480c]{flex:none}.perm-pill[data-v-5a96480c],.swarm-chip[data-v-5a96480c]{flex:none;padding-left:var(--space-2)}.swarm-ic[data-v-5a96480c],.swarm-x[data-v-5a96480c]{flex:none}.labels-collapsed .perm-pill[data-v-5a96480c]{width:var(--composer-control-size);height:var(--composer-control-size);padding:0;justify-content:center;flex:none}.labels-collapsed .perm-pill-label[data-v-5a96480c]{display:none}.labels-collapsed .swarm-chip[data-v-5a96480c]{position:relative;width:var(--composer-control-size);height:var(--composer-control-size);padding:0;justify-content:center;flex:none}.labels-collapsed .swarm-label[data-v-5a96480c]{display:none}.labels-collapsed .swarm-ic[data-v-5a96480c]{transition:opacity var(--duration-base) var(--ease-out)}.labels-collapsed .swarm-chip:hover .swarm-ic[data-v-5a96480c]{opacity:0}.labels-collapsed .swarm-x[data-v-5a96480c]{position:absolute;inset:0;width:auto;height:auto;margin-right:0}@media(hover:none){.labels-collapsed .swarm-chip[data-v-5a96480c]{width:var(--touch-target-min);height:var(--touch-target-min)}.labels-collapsed .swarm-chip:hover .swarm-ic[data-v-5a96480c]{opacity:1}.labels-collapsed .swarm-x[data-v-5a96480c]{inset:0;width:auto;height:auto;opacity:1;background:transparent}.labels-collapsed .swarm-x[data-v-5a96480c]:before{inset:0 0 auto auto;width:var(--p-ic-md);height:var(--p-ic-md);border-radius:var(--radius-full);background:var(--color-selected)}.labels-collapsed .swarm-x[data-v-5a96480c] svg{position:absolute;top:calc(var(--space-1-5) / 2);right:calc(var(--space-1-5) / 2);width:calc(var(--p-ic-md) - var(--space-1-5));height:calc(var(--p-ic-md) - var(--space-1-5))}}.ctx-group[data-v-5a96480c]{display:flex;align-items:center;gap:4px;flex-shrink:0;padding:2px 0;border-radius:var(--radius-xs)}.ctx-group[data-v-5a96480c]:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}.model-pill[data-v-5a96480c]{gap:var(--space-1);line-height:var(--leading-normal);overflow:hidden;flex:0 1 auto;min-width:0;max-width:320px;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.model-pill[data-v-5a96480c]:active{transform:scale(.97)}.model-pill[data-v-5a96480c]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.model-pill .mp-name[data-v-5a96480c]{flex:0 8 auto;font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.model-pill .think-suffix[data-v-5a96480c]{color:var(--color-accent);font-weight:var(--weight-medium);flex:none}.model-pill .cv[data-v-5a96480c]{color:var(--faint);flex:none;transition:transform var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.model-pill:hover .cv[data-v-5a96480c],.model-pill.open .cv[data-v-5a96480c]{color:var(--dim)}.model-pill.open .cv[data-v-5a96480c]{transform:rotate(180deg)}.model-pill.icon-only[data-v-5a96480c]{width:var(--composer-control-size);height:var(--composer-control-size);padding:0;justify-content:center;flex:none}.model-pill.login-pill[data-v-5a96480c]{flex:none;color:var(--color-accent)}.model-pill.login-pill .mp-name[data-v-5a96480c]{color:var(--color-accent)}.model-dropdown[data-v-5a96480c]{position:absolute;bottom:calc(100% + var(--space-1));right:calc(var(--composer-control-inset) + var(--composer-send-size) + var(--space-1));z-index:var(--z-dropdown);min-width:200px;background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:var(--space-1);display:flex;flex-direction:column;gap:1px;font-family:var(--font-ui);transform-origin:bottom right;overflow-y:auto;overscroll-behavior:contain}.model-dropdown.flip-down[data-v-5a96480c]{top:calc(100% + var(--space-1));bottom:auto;transform-origin:top right}.composer-menu-pop-enter-active[data-v-5a96480c]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.composer-menu-pop-leave-active[data-v-5a96480c]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.composer-menu-pop-enter-from[data-v-5a96480c],.composer-menu-pop-leave-to[data-v-5a96480c]{opacity:0;transform:scale(.97) translateY(2px)}.model-dropdown.flip-down.composer-menu-pop-enter-from[data-v-5a96480c],.model-dropdown.flip-down.composer-menu-pop-leave-to[data-v-5a96480c]{transform:scale(.97) translateY(-2px)}.md-list[data-v-5a96480c]{display:flex;flex-direction:column;gap:1px;max-height:min(320px,40vh);overflow-y:auto;overscroll-behavior:contain}.md-section[data-v-5a96480c]{padding:4px 9px 2px;font-size:var(--text-xs);color:var(--muted);text-transform:uppercase;letter-spacing:.04em;font-weight:var(--weight-semibold)}.md-row[data-v-5a96480c]{display:flex;align-items:center;gap:7px;width:100%;background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text);padding:5px 9px;border-radius:var(--radius-dropdown-row);text-align:left;transition:background var(--duration-base) var(--ease-out)}.md-row[data-v-5a96480c]:hover{background:var(--color-hover)}.md-row:hover .md-name[data-v-5a96480c]{color:var(--color-text-strong)}.md-row[data-v-5a96480c]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md-row[data-v-5a96480c]:disabled{cursor:default;opacity:.58}.md-row[data-v-5a96480c]:disabled:hover{background:none}.md-row.is-current[data-v-5a96480c]{background:var(--color-selected)}.md-note[data-v-5a96480c]{margin-left:auto;color:var(--muted);font-size:var(--ui-font-size-xs)}.md-row-more .md-more-icon[data-v-5a96480c]{color:var(--dim)}.md-row-more .md-more-arrow[data-v-5a96480c]{color:var(--faint);flex:none;transition:color var(--duration-base) var(--ease-out)}.md-row-more:hover .md-more-arrow[data-v-5a96480c]{color:var(--dim)}.md-check[data-v-5a96480c]{width:14px;flex:none;color:var(--color-accent);font-weight:500;display:flex;justify-content:center}.md-name[data-v-5a96480c]{flex:1;transition:color var(--duration-base) var(--ease-out)}.md-provider[data-v-5a96480c]{color:var(--muted);font-size:var(--ui-font-size-xs);flex:none}.md-star[data-v-5a96480c]{color:var(--star);flex:none;margin-left:auto}.md-divider[data-v-5a96480c]{height:1px;background:var(--line);margin:3px 0}.md-thinking[data-v-5a96480c]{display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:var(--radius-dropdown-row)}.md-thinking .md-name[data-v-5a96480c]{font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text);flex:none}.md-thinking .md-note[data-v-5a96480c],.md-thinking .ui-seg[data-v-5a96480c]{margin-left:auto}.md-cache-note[data-v-5a96480c]{width:0;min-width:100%;padding:2px 7px 4px;color:var(--muted);font-size:var(--ui-font-size-xs);line-height:1.4}.perm-dropdown[data-v-5a96480c]{position:absolute;bottom:calc(100% + 4px);left:var(--composer-control-inset);z-index:var(--z-dropdown);min-width:220px;width:max-content;max-width:calc(100vw - var(--space-8));background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:var(--space-1);display:flex;flex-direction:column;gap:1px;transform-origin:bottom left}.pd-row[data-v-5a96480c]{display:grid;grid-template-columns:var(--p-ic-md) var(--composer-menu-desc-width, max-content) var(--p-ic-sm);column-gap:7px;row-gap:2px;align-items:start;width:100%;background:none;border:none;cursor:pointer;padding:6px 7px;border-radius:var(--radius-dropdown-row);text-align:left}.pd-row[data-v-5a96480c]:hover,.pd-row.is-current[data-v-5a96480c]{background:var(--color-hover)}.pd-icon[data-v-5a96480c]{grid-column:1;grid-row:1;width:var(--p-ic-md);min-height:1lh;display:flex;align-items:center;justify-content:center;line-height:var(--leading-tight)}.pd-check[data-v-5a96480c]{grid-column:3;grid-row:1;width:var(--p-ic-sm);min-height:1lh;color:var(--color-accent);font-size:var(--ui-font-size);font-weight:var(--weight-medium);display:flex;align-items:center;justify-content:center;line-height:var(--leading-tight)}.pd-info[data-v-5a96480c]{display:contents}.pd-name[data-v-5a96480c]{grid-column:2;grid-row:1;font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight)}.pd-desc[data-v-5a96480c]{grid-column:2;grid-row:2;width:var(--composer-menu-desc-width, auto);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-caption);color:var(--muted);line-height:var(--leading-tight)}.wm-pill[data-v-5a96480c]{position:absolute;top:0;left:0;margin-left:calc(-1 * var(--space-05));z-index:var(--z-raised);display:inline-flex;align-items:center;gap:var(--space-1);height:calc(var(--content-font-size) * 1.5);padding:0 calc((var(--content-font-size) * 1.5 - var(--wm-x-size)) / 2) 0 var(--space-2);border:none;border-radius:var(--radius-full);background:var(--color-surface);color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:calc(var(--content-font-size) * 1.5);white-space:nowrap;user-select:none}.wm-x[data-v-5a96480c]{position:relative;width:var(--wm-x-size);height:var(--wm-x-size);border-radius:var(--radius-full)}.wm-x[data-v-5a96480c]:before{content:"";position:absolute;inset:calc(-1 * var(--wm-x-ring))}@media(hover:none){.wm-x[data-v-5a96480c]:before{inset:calc((var(--wm-x-size) - var(--touch-target-min)) / 2)}}@media(max-width:640px){.composer[data-v-5a96480c]{padding:9px var(--dock-inline-right, max(12px, var(--safe-right))) max(24px,var(--safe-bottom)) var(--dock-inline-left, max(12px, var(--safe-left)))}.composer-card[data-v-5a96480c]{--composer-control-size: 36px;max-width:100%}.input-row[data-v-5a96480c]{gap:6px;min-width:0}.send[data-v-5a96480c],.stop[data-v-5a96480c]{width:var(--composer-send-size);height:var(--composer-send-size);min-width:var(--composer-send-size);padding:0;border-radius:var(--radius-full);font-size:0;align-self:flex-end;position:relative}.perm-pill[data-v-5a96480c],.wm-pill[data-v-5a96480c]{display:none}.model-dropdown[data-v-5a96480c]{right:calc(var(--composer-control-inset) + var(--composer-send-size) + var(--space-1));left:auto;min-width:180px;max-width:calc(100vw - 24px)}.ph[data-v-5a96480c]{font-size:16px}.model-pill[data-v-5a96480c],.attach-btn[data-v-5a96480c]{font-size:var(--ui-font-size)}.toolbar[data-v-5a96480c]{gap:6px;min-width:0}.toolbar-left[data-v-5a96480c],.toolbar-right[data-v-5a96480c]{min-width:0}.model-pill[data-v-5a96480c]{max-width:min(52vw,220px)}.model-pill .mp-name[data-v-5a96480c]{max-width:min(40vw,170px)}.md-row[data-v-5a96480c],.md-section[data-v-5a96480c]{font-size:var(--ui-font-size)}.md-thinking[data-v-5a96480c]{flex-wrap:wrap;row-gap:6px}.md-thinking .ui-seg[data-v-5a96480c]{margin-left:0}.pd-name[data-v-5a96480c]{font-size:var(--ui-font-size)}.pd-desc[data-v-5a96480c]{font-size:var(--text-xs)}}@media(max-width:640px)and (hover:none){.send[data-v-5a96480c],.stop[data-v-5a96480c],.attach-btn[data-v-5a96480c],.expand-btn[data-v-5a96480c],.model-pill[data-v-5a96480c]{position:relative}.send[data-v-5a96480c]:before,.stop[data-v-5a96480c]:before,.attach-btn[data-v-5a96480c]:before,.expand-btn[data-v-5a96480c]:before,.model-pill[data-v-5a96480c]:before{content:"";position:absolute;inset:-6px}.expand-btn[data-v-5a96480c]:before{inset:-11px}}.goal-panel[data-v-cdb3e8b0]{display:flex;flex-direction:column;gap:var(--space-2);overflow-wrap:anywhere}.goal-criterion[data-v-cdb3e8b0]{padding-top:var(--space-2);border-top:.5px solid var(--color-line)}.goal-criterion-label[data-v-cdb3e8b0]{display:flex;align-items:center;gap:var(--space-1);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-section-label);line-height:var(--leading-normal);margin-bottom:var(--space-1)}.plan-panel[data-v-dea23306]{display:flex;flex-direction:column;gap:var(--space-2)}.plan-review-row[data-v-dea23306]{display:flex;gap:var(--space-2);font-size:var(--text-sm)}.plan-review-label[data-v-dea23306]{flex:none;color:var(--color-text-muted)}.plan-review-feedback[data-v-dea23306]{color:var(--color-text-muted)}.plan-path-only[data-v-dea23306]{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-1)}.plan-path-hint[data-v-dea23306]{color:var(--color-text-muted);font-size:var(--text-sm)}.plan-path[data-v-dea23306]{max-width:100%;font-family:var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.plan-empty[data-v-dea23306]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-6) var(--space-4);color:var(--color-text-faint);font-size:var(--text-sm)}.plan-empty-ico[data-v-dea23306]{width:var(--p-empty-ico);height:var(--p-empty-ico);color:var(--color-line-strong)}.qcard[data-v-8e7280dd]{display:flex;flex-direction:column;max-height:calc(var(--app-height, 100dvh) - var(--dock-card-top-clearance));margin:var(--space-2) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);overflow:hidden auto;animation:kimi-card-in var(--duration-base) var(--ease-out)}.qcard>.qh[data-v-8e7280dd],.qcard>.qfoot[data-v-8e7280dd]{flex:none}.qcard.minimized[data-v-8e7280dd]{transition:background var(--duration-fast) var(--ease-out)}.qcard.minimized[data-v-8e7280dd]:hover{background:var(--color-hover)}.qh[data-v-8e7280dd]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-3) var(--space-4) 0}.qcard.minimized .qh[data-v-8e7280dd]{padding-bottom:var(--space-3);align-items:center}.qcard.minimized .qh.clickable[data-v-8e7280dd]{cursor:pointer}.qh-chip[data-v-8e7280dd]{width:var(--p-chip-num);height:var(--p-chip-num);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.qtitle[data-v-8e7280dd]{flex:1;min-width:0;color:var(--color-text);font-size:var(--text-lg);font-weight:var(--weight-semibold);line-height:var(--leading-tight);overflow-wrap:anywhere}.qcard.minimized .qtitle[data-v-8e7280dd]{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.qmin[data-v-8e7280dd],.qclose[data-v-8e7280dd]{flex:none;margin-top:calc((var(--text-lg) * var(--leading-tight) - var(--icon-button-sm)) / 2)}.qmin[data-v-8e7280dd]{margin-left:auto}.qcard.minimized .qmin[data-v-8e7280dd],.qcard.minimized .qclose[data-v-8e7280dd]{margin-top:0}.qbody[data-v-8e7280dd]{min-height:min(var(--question-card-body-min-h),calc(var(--app-height, 100dvh) * .25));overflow-y:auto;padding:var(--space-3) var(--space-4) 0;color:var(--color-text);font:var(--text-base)/var(--leading-normal) var(--font-ui)}.qmdbody[data-v-8e7280dd]{margin-bottom:var(--space-2)}.qopts[data-v-8e7280dd]{display:flex;flex-direction:column;gap:2px;margin-top:var(--space-2)}.qopt[data-v-8e7280dd]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);cursor:pointer;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text);transition:background var(--duration-fast) var(--ease-out);user-select:none}.qopt[data-v-8e7280dd]:hover,.qopt.highlighted[data-v-8e7280dd]{background:var(--color-hover)}.qopt-key[data-v-8e7280dd]{width:var(--p-chip-num);height:var(--p-chip-num);margin-top:calc((var(--text-base) * var(--leading-normal) - var(--p-chip-num)) / 2);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.qopt-key[data-v-8e7280dd]:empty{background:transparent}.qopt-glyph[data-v-8e7280dd]{width:16px;height:16px;margin-top:calc((var(--text-base) * var(--leading-normal) - 16px) / 2);flex:none;border:.5px solid var(--color-line-strong);position:relative;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.qopt-glyph.rad[data-v-8e7280dd]{border-radius:50%}.qopt-glyph.chk[data-v-8e7280dd]{border-radius:var(--radius-xs)}.qopt.selected .qopt-glyph[data-v-8e7280dd]{border-color:var(--color-accent)}.qopt.selected .qopt-glyph.rad[data-v-8e7280dd]:after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--color-accent)}.qopt.selected .qopt-glyph.chk[data-v-8e7280dd]{background:var(--color-accent)}.qopt.selected .qopt-glyph.chk[data-v-8e7280dd]:after{content:"";position:absolute;left:4.5px;top:1.5px;width:4px;height:8px;border-right:1.5px solid var(--color-text-on-accent);border-bottom:1.5px solid var(--color-text-on-accent);transform:rotate(45deg)}.qopt-text[data-v-8e7280dd]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.qopt-label[data-v-8e7280dd]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.qopt-desc[data-v-8e7280dd]{color:var(--color-text-muted);font:var(--text-xs)/var(--leading-normal) var(--font-ui)}.other-input[data-v-8e7280dd]{flex:1;font:var(--text-base) var(--font-ui);border:none;border-bottom:.5px solid var(--color-line);outline:none;padding:2px var(--space-1);color:var(--color-text);background:transparent;min-width:0}.other-input[data-v-8e7280dd]:focus-visible{border-bottom-color:var(--color-accent);box-shadow:0 1px 0 0 var(--color-accent)}.qfoot[data-v-8e7280dd]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.qbtns[data-v-8e7280dd]{display:flex;align-items:center;gap:var(--space-1)}.qhint[data-v-8e7280dd]{margin-left:auto;color:var(--color-text-faint);font:var(--text-xs) var(--font-ui);user-select:none}@media(max-width:640px){.qopt[data-v-8e7280dd]{min-height:44px;padding:var(--space-3)}.other-input[data-v-8e7280dd]{flex-basis:100%;min-height:28px}.qfoot[data-v-8e7280dd]{flex-direction:column;align-items:stretch}.qhint[data-v-8e7280dd]{display:none}.qbtns[data-v-8e7280dd]{flex-direction:column;gap:var(--space-2)}.qbtns[data-v-8e7280dd] .ui-button{width:100%;min-height:46px}}.appr[data-v-690f6ed6]{display:flex;flex-direction:column;max-height:calc(var(--app-height, 100dvh) - var(--dock-card-top-clearance));margin:var(--space-2) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);overflow:hidden auto;animation:kimi-card-in var(--duration-base) var(--ease-out)}.appr[data-v-690f6ed6]:before{content:"";position:sticky;top:0;flex:none;height:var(--p-scroll-seam-h);margin-bottom:calc(-1 * var(--p-scroll-seam-h));z-index:var(--z-raised);pointer-events:none;opacity:0;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 2.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.75%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.25%,transparent),transparent);transition:opacity var(--duration-slow) var(--ease-out)}.appr.scrolled[data-v-690f6ed6]:before{opacity:1}.appr>.ah[data-v-690f6ed6],.appr>.af[data-v-690f6ed6]{flex:none}.appr.minimized[data-v-690f6ed6]{transition:background var(--duration-fast) var(--ease-out)}.appr.minimized[data-v-690f6ed6]:hover{background:var(--color-hover)}.ah[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4) 0;flex-wrap:nowrap}.appr.minimized .ah[data-v-690f6ed6]{padding-bottom:var(--space-3)}.appr.minimized .ah.clickable[data-v-690f6ed6]{cursor:pointer}.akind[data-v-690f6ed6]{color:var(--color-text);font-size:var(--text-lg);font-weight:var(--weight-semibold);white-space:nowrap;flex:none}.apeek[data-v-690f6ed6]{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted);font:var(--text-xs) var(--font-mono)}.amin[data-v-690f6ed6],.aexpand[data-v-690f6ed6]{margin-left:auto;flex:none}.aexpand+.amin[data-v-690f6ed6]{margin-left:0}.ab[data-v-690f6ed6]{display:flex;flex-direction:column;flex:1;min-height:0;padding:var(--space-3) var(--space-4) 0}.ab[data-v-690f6ed6]>*{flex:0 1 auto;min-height:0}.ab>.plan-path[data-v-690f6ed6]{flex:none}.ab>.body-plan-wrap[data-v-690f6ed6]{flex:1}.plan-path[data-v-690f6ed6]{display:block;width:100%;margin-bottom:var(--space-2);padding:0;border:none;background:transparent;color:var(--color-accent);font:var(--text-xs) var(--font-mono);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.plan-path[data-v-690f6ed6]:hover{text-decoration:underline}.plan-path[data-v-690f6ed6]:focus-visible{outline:none;text-decoration:underline;border-radius:var(--radius-xs);box-shadow:var(--p-focus-ring)}.body-code[data-v-690f6ed6]{display:flex;flex-direction:column}.body-code.expanded[data-v-690f6ed6]{flex:1}.body-code.expanded[data-v-690f6ed6] .hl-code{max-height:none;flex:1}.code-path[data-v-690f6ed6]{flex:none;color:var(--color-text-muted);font:var(--text-xs) var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.body-shell[data-v-690f6ed6]{overflow-y:auto}.shell-cmd[data-v-690f6ed6]{font:var(--text-sm) var(--font-mono);background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);white-space:pre-wrap;word-break:break-all;max-height:160px;overflow-y:auto;color:var(--color-text)}.shell-dollar[data-v-690f6ed6]{color:var(--color-accent-hover);font-weight:var(--weight-medium);margin-right:var(--space-2)}.shell-cwd[data-v-690f6ed6]{font:var(--text-xs) var(--font-mono);color:var(--color-text-muted);margin-top:var(--space-1)}.shell-danger[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);color:var(--color-danger);font:var(--text-sm)/var(--leading-normal) var(--font-ui);background:var(--color-danger-soft)}.shell-danger-ic[data-v-690f6ed6]{flex:none}.body-chip[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text);overflow-y:auto}.chip-label[data-v-690f6ed6]{background:var(--color-inline-code-bg);border-radius:var(--radius-sm);padding:2px var(--space-2);font:var(--weight-semibold) var(--text-xs) var(--font-mono);color:var(--color-text-muted);white-space:nowrap}.chip-value[data-v-690f6ed6]{font:var(--text-sm) var(--font-mono);color:var(--color-text);word-break:break-all}.chip-detail[data-v-690f6ed6]{font:var(--text-xs) var(--font-ui);color:var(--color-text-muted)}.body-todo[data-v-690f6ed6]{overflow-y:auto}.todo-item[data-v-690f6ed6]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-1) 0;font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text)}.todo-glyph[data-v-690f6ed6]{color:var(--color-accent);font-size:var(--text-sm);flex:none;width:14px}.todo-title[data-v-690f6ed6]{color:var(--color-text)}.todo-done[data-v-690f6ed6]{color:var(--color-text-muted);text-decoration:line-through}.body-generic[data-v-690f6ed6]{font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text);word-break:break-word;overflow-y:auto}.body-plan-wrap[data-v-690f6ed6]{display:flex;flex-direction:column;overflow-y:auto}.body-plan-wrap[data-v-690f6ed6]:before{content:"";position:sticky;top:0;flex:none;height:var(--p-scroll-seam-h);margin-bottom:calc(-1 * var(--p-scroll-seam-h));z-index:var(--z-raised);pointer-events:none;opacity:0;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 2.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.75%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.25%,transparent),transparent);transition:opacity var(--duration-slow) var(--ease-out)}.body-plan-wrap.scrolled[data-v-690f6ed6]:before{opacity:1}.body-plan-wrap>.plan-opts[data-v-690f6ed6]{flex:none}.body-plan[data-v-690f6ed6]{max-height:50vh;overflow-y:auto;min-height:0}.body-plan.expanded[data-v-690f6ed6]{max-height:none;flex:1}.plan-opts[data-v-690f6ed6]{display:flex;flex-direction:column;gap:2px;margin-top:var(--space-3);padding-top:var(--space-3);border-top:.5px solid var(--color-line)}.popt[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-md);background:transparent;color:var(--color-text);font:var(--text-sm)/var(--leading-normal) var(--font-ui);text-align:left;cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.popt[data-v-690f6ed6]:hover:not(:disabled){background:var(--color-hover)}.popt[data-v-690f6ed6]:focus-visible{outline:none;background:var(--color-hover);box-shadow:var(--p-focus-ring)}.popt[data-v-690f6ed6]:disabled{cursor:default;opacity:.6}.popt-key[data-v-690f6ed6]{width:var(--p-chip-num);height:var(--p-chip-num);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.popt-text[data-v-690f6ed6]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.popt-label[data-v-690f6ed6]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.popt-desc[data-v-690f6ed6]{color:var(--color-text-muted);font:var(--text-xs)/var(--leading-normal) var(--font-ui)}.popt-spin[data-v-690f6ed6]{flex:none;color:var(--color-text-muted)}.feedback-wrap[data-v-690f6ed6]{margin-top:var(--space-3);overflow-y:auto}.feedback-hint[data-v-690f6ed6]{font:var(--text-xs) var(--font-ui);color:var(--color-text-muted);margin-top:var(--space-1)}.af[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.abtns[data-v-690f6ed6]{display:flex;align-items:center;gap:var(--space-1)}.knum[data-v-690f6ed6]{min-width:16px;height:16px;padding:0 3px;border-radius:var(--radius-xs);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/16px var(--font-ui);text-align:center}.abtns .ui-button--primary .knum[data-v-690f6ed6]{background:color-mix(in srgb,var(--color-text-on-accent) 28%,transparent);color:var(--color-text-on-accent)}@media(max-width:640px){.popt[data-v-690f6ed6]{min-height:44px;padding:var(--space-3)}.af[data-v-690f6ed6]{flex-direction:column;align-items:stretch}.abtns[data-v-690f6ed6]{flex-direction:column;margin-left:0;gap:var(--space-2)}.abtns[data-v-690f6ed6] .ui-button{width:100%;min-height:46px}.abtns .amain[data-v-690f6ed6]{order:-1}}.taskspane[data-v-22fc9dfb]{flex:1;min-height:0;display:flex;flex-direction:column}.tp-list[data-v-22fc9dfb]{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:var(--space-05)}.tp-row[data-v-22fc9dfb]{padding:var(--space-1) 0}.tp-row.fail .tp-name[data-v-22fc9dfb]{color:var(--color-danger)}.tp-main[data-v-22fc9dfb]{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-base)}.tp-row.expandable>.tp-main[data-v-22fc9dfb]{position:relative;border-radius:var(--radius-lg);padding:var(--space-1) var(--space-2);margin:calc(-1 * var(--space-1)) 0}.tp-row.expandable>.tp-main[data-v-22fc9dfb]:hover{background:var(--color-hover)}.tp-row[data-v-22fc9dfb]:not(.expandable){cursor:not-allowed}.tp-open[data-v-22fc9dfb]{position:absolute;inset:0;padding:0;border:none;border-radius:var(--radius-lg);background:transparent;cursor:pointer}.tp-open[data-v-22fc9dfb]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tp-chevron[data-v-22fc9dfb]{flex:none;color:var(--muted)}.tp-name[data-v-22fc9dfb]{color:var(--color-text);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-meta[data-v-22fc9dfb]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted)}.tp-glyph[data-v-22fc9dfb]{flex:none;width:var(--p-ic-md);height:var(--p-ic-md);display:inline-flex;align-items:center;justify-content:center}.tp-done[data-v-22fc9dfb]{color:var(--color-success);transform:scale(.91)}.tp-cancelled[data-v-22fc9dfb]{color:var(--color-text-muted)}.tp-fail[data-v-22fc9dfb]{color:var(--color-danger)}.tp-time[data-v-22fc9dfb]{flex:none;font-size:var(--text-base);color:var(--muted);font-variant-numeric:tabular-nums;text-autospace:normal}.tp-model[data-v-22fc9dfb]{flex:0 1 auto;min-width:0;font-size:var(--text-base);color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-stop[data-v-22fc9dfb]{position:relative;flex:none;color:var(--color-danger)}.tp-stop[data-v-22fc9dfb]:hover{color:var(--color-danger)}@media(hover:none){.tp-stop[data-v-22fc9dfb]{width:var(--touch-target-min);height:var(--touch-target-min)}.tp-row.expandable>.tp-main[data-v-22fc9dfb]{min-height:var(--touch-target-min)}}.tp-empty[data-v-22fc9dfb]{flex:1;display:flex;align-items:center;justify-content:center;color:var(--faint);font-size:var(--ui-font-size-sm);user-select:none}@media(max-width:640px){.tp-main[data-v-22fc9dfb]{flex-wrap:wrap;row-gap:var(--space-1)}.tp-name[data-v-22fc9dfb]{font-size:var(--ui-font-size-sm)}.tp-meta[data-v-22fc9dfb]{order:10;flex:1 1 100%;padding-left:calc(var(--p-ic-md) + var(--space-2));font-size:var(--ui-font-size-xs)}}.sg-empty[data-v-f7e4b600]{height:100%;display:flex;align-items:center;justify-content:center;color:var(--color-text-faint);font-size:var(--text-sm);user-select:none}.sg-grid[data-v-f7e4b600]{display:grid;grid-template-columns:repeat(auto-fill,minmax(var(--p-subagent-card-min),1fr));gap:var(--space-2)}.sg-card[data-v-f7e4b600]{position:relative;display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3);border-radius:var(--radius-lg);background:var(--color-selected)}.sg-card.openable[data-v-f7e4b600]{cursor:pointer}.sg-card.openable[data-v-f7e4b600]:hover{background:var(--color-selected-hover)}.sg-card[data-v-f7e4b600]:not(.openable){cursor:not-allowed}.sg-open[data-v-f7e4b600]{position:absolute;inset:0;padding:0;border:none;border-radius:var(--radius-lg);background:transparent;cursor:pointer}.sg-open[data-v-f7e4b600]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.sg-top[data-v-f7e4b600]{display:flex;align-items:center;gap:var(--space-2)}.sg-name[data-v-f7e4b600]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text);font-weight:var(--weight-medium)}.sg-num[data-v-f7e4b600]{flex:none;color:var(--color-text-muted);font-size:var(--text-sm);font-variant-numeric:tabular-nums}.sg-card:has(.sg-cancel) .sg-top[data-v-f7e4b600]{padding-right:calc(var(--icon-button-sm) + var(--space-1))}@media(hover:none){.sg-card:has(.sg-cancel) .sg-top[data-v-f7e4b600]{padding-right:calc(var(--touch-target-min) + var(--space-1))}}.sg-desc[data-v-f7e4b600]{color:var(--color-text-muted);font-size:var(--text-sm);line-height:var(--leading-caption);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.sg-foot[data-v-f7e4b600]{display:flex;flex-direction:column;gap:var(--space-1)}.sg-model[data-v-f7e4b600]{display:flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted);font-size:var(--text-xs)}.sg-model span[data-v-f7e4b600]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sg-status[data-v-f7e4b600]{display:flex;align-items:center}.sg-state[data-v-f7e4b600]{display:inline-flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted);font-size:var(--text-xs);text-autospace:normal}.sg-ic-done[data-v-f7e4b600]{color:var(--color-success);transform:scale(.91)}.s-fail .sg-state[data-v-f7e4b600]{color:var(--color-danger)}.sg-time[data-v-f7e4b600]{margin-left:auto;display:inline-flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted);font-size:var(--text-xs);font-variant-numeric:tabular-nums;text-autospace:normal}.sg-cancel[data-v-f7e4b600]{position:absolute;top:var(--space-2);right:var(--space-2);color:var(--color-text-muted);opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.sg-card:hover .sg-cancel[data-v-f7e4b600],.sg-cancel[data-v-f7e4b600]:focus-visible{opacity:1}.sg-cancel[data-v-f7e4b600]:hover{color:var(--color-danger)}@media(hover:none){.sg-cancel[data-v-f7e4b600]{top:0;right:0;width:var(--touch-target-min);height:var(--touch-target-min);opacity:1}}.todo-card[data-v-f090f678]{display:flex;flex-direction:column;gap:var(--space-3);font-size:var(--text-base)}.tc-row[data-v-f090f678]{display:flex;align-items:center;gap:var(--space-2);color:var(--color-text)}.tc-name[data-v-f090f678]{flex:1;min-width:0;overflow-wrap:anywhere;line-height:var(--leading-caption)}.tc-row.s-in_progress .tc-name[data-v-f090f678]{font-weight:var(--weight-medium)}.tc-row.s-pending .tc-name[data-v-f090f678]{color:var(--color-text-muted)}.tc-glyph[data-v-f090f678]{flex:none;width:var(--p-ic-md);height:var(--p-ic-md);display:inline-flex;align-items:center;justify-content:center;border-radius:var(--radius-full)}.tc-glyph.g-done[data-v-f090f678]{color:var(--color-success)}.tc-glyph.g-pending[data-v-f090f678]{border:var(--p-ring-stroke) solid var(--color-line-strong)}.tc-glyph .tc-spin[data-v-f090f678]{color:var(--color-text)}.tc-empty[data-v-f090f678]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-6) var(--space-4);color:var(--color-text-faint);font-size:var(--text-sm)}.tc-empty-ico[data-v-f090f678]{width:var(--p-empty-ico);height:var(--p-empty-ico);color:var(--color-line-strong)}@media(max-width:640px){.todo-card[data-v-f090f678]{font-size:var(--text-lg)}.tc-row[data-v-f090f678]{padding:var(--space-2) var(--space-3)}}.wp-head-tab[data-v-82048a74]{display:inline-flex;align-items:center;gap:var(--space-2);padding:0;border:.5px solid transparent;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium);line-height:var(--leading-solid);white-space:nowrap;flex:none}.wp-head-tab[data-v-82048a74] svg{width:1.5em;height:1.5em}.wp-head-meta[data-v-82048a74]{color:var(--color-text-muted);text-autospace:normal}.wp-head-actions[data-v-82048a74]{margin-left:auto;display:flex;align-items:center;gap:var(--space-1);flex:none}@media(max-width:480px){.wp-head-actions[data-v-82048a74]{flex-basis:100%;margin-left:0}}@media(hover:none){.wp-head-actions[data-v-82048a74] .ui-seg__item{min-height:var(--touch-target-min)}}@media(max-width:640px),(hover:none){.wp-head-actions[data-v-82048a74] .ui-seg__item{height:var(--touch-target-min)}.wp-head-actions[data-v-82048a74] .ui-icon-button{width:var(--touch-target-min);height:var(--touch-target-min)}.wp-head-actions[data-v-82048a74] .fc-trigger{min-height:var(--touch-target-min)}}.filter-control[data-v-153e0d9c]{display:inline-flex;min-width:0}.fc-chevron[data-v-153e0d9c]{color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.fc-trigger[aria-expanded=true] .fc-chevron[data-v-153e0d9c]{transform:rotate(180deg)}.fc-menu[data-v-153e0d9c]{position:fixed;z-index:var(--z-dropdown)}.fc-menu[data-v-153e0d9c] .ui-menu{min-width:0}.fc-label[data-v-153e0d9c]{flex:1;white-space:nowrap}.filter-control[data-v-153e0d9c] .ui-seg__item[data-icon=circle-check] .ui-seg__icon,.fc-menu .kw-icon[data-icon=circle-check][data-v-153e0d9c]{transform:scale(.91)}.fc-check[data-v-153e0d9c]{color:var(--color-accent)}.chat-dock[data-v-8cd7cb40]{--dock-inline-left: 16px;--dock-inline-right: 16px;box-sizing:border-box;width:100%;max-width:calc(var(--read-max) + var(--panes-scrollbar-width, 0px));padding-right:var(--panes-scrollbar-width, 0px);flex:none;position:absolute;inset:auto 0 0;background:transparent;z-index:var(--z-sticky)}.chat-dock.has-popup[data-v-8cd7cb40]{z-index:var(--z-dropdown)}.chat-dock.align-center[data-v-8cd7cb40]{margin-left:auto;margin-right:auto}.chat-dock.align-left[data-v-8cd7cb40]{margin-left:0;margin-right:auto}.chat-dock.align-mobile[data-v-8cd7cb40]{max-width:none}.chat-dock[data-v-8cd7cb40]:before{--fade: 48px;--veil: 72px;content:"";position:absolute;top:calc(-1 * var(--fade));right:0;bottom:0;left:0;z-index:0;pointer-events:none;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-bg) 0%,transparent),color-mix(in srgb,var(--color-bg) 30%,transparent) 21px,color-mix(in srgb,var(--color-bg) 70%,transparent) 45px,var(--color-bg) var(--veil))}.chat-dock[data-v-8cd7cb40]>*{position:relative;z-index:1}.dock-work-panel[data-v-8cd7cb40]{position:absolute;left:16px;right:calc(16px + var(--panes-scrollbar-width, 0px));bottom:100%;background:var(--color-menu-bg-frost);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-2xl);box-shadow:var(--shadow-menu);margin-bottom:var(--space-2);max-height:min(360px,50vh);display:flex;flex-direction:column;overflow:hidden;user-select:none}.dock-work-panel.panel-todos .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-goal .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-subagent .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-bash .dock-work-head[data-v-8cd7cb40]{padding:var(--space-4) var(--space-4) 0;border-bottom:none}.dock-work-panel.panel-todos .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-goal .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-subagent .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-bash .dock-work-body[data-v-8cd7cb40]{margin-top:var(--space-3);padding:0 var(--space-4) var(--space-4)}.dock-work-panel.panel-todos .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-goal .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-plan .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-subagent .dock-work-head[data-v-8cd7cb40],.dock-work-panel.panel-bash .dock-work-head[data-v-8cd7cb40]{padding:var(--space-4) var(--space-4) 0;border-bottom:none}.dock-work-panel.panel-todos .dock-work-tab[data-v-8cd7cb40],.dock-work-panel.panel-goal .dock-work-tab[data-v-8cd7cb40],.dock-work-panel.panel-plan .dock-work-tab[data-v-8cd7cb40],.dock-work-panel.panel-subagent .dock-work-tab[data-v-8cd7cb40],.dock-work-panel.panel-bash .dock-work-tab[data-v-8cd7cb40]{padding:0;line-height:var(--leading-solid)}.dock-work-panel.panel-goal .gh-time[data-v-8cd7cb40]{color:var(--color-text-muted)}.dock-work-panel.panel-todos .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-goal .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-plan .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-subagent .dock-work-body[data-v-8cd7cb40],.dock-work-panel.panel-bash .dock-work-body[data-v-8cd7cb40]{margin-top:var(--space-3);padding:0 var(--space-4) var(--space-4)}.dock-work-panel.panel-subagent[data-v-8cd7cb40],.dock-work-panel.panel-bash[data-v-8cd7cb40]{height:min(var(--p-dock-panel-h),50vh)}.dock-work-tab.tab-progress[data-v-8cd7cb40]{display:inline-flex;align-items:center;gap:var(--space-2)}@media(max-width:640px){.dock-work-panel.panel-subagent[data-v-8cd7cb40],.dock-work-panel.panel-bash[data-v-8cd7cb40]{height:auto}}.dock-work-head[data-v-8cd7cb40]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-bottom:.5px solid var(--color-line);position:relative;z-index:1}.dock-work-body[data-v-8cd7cb40]{padding:var(--space-2) var(--space-3);overflow-y:auto;min-height:0;display:flex;flex-direction:column}@media(max-width:480px){.dock-work-head[data-v-8cd7cb40]{flex-wrap:wrap}}.dock-work-panel.body-scrolled-up .dock-work-body[data-v-8cd7cb40]{mask-image:linear-gradient(to bottom,transparent,black var(--menu-scroll-fade))}.dock-work-body[data-v-8cd7cb40] .taskspane{border:none;background:transparent;padding:0}.dock-work-body[data-v-8cd7cb40] .taskspane .tp-head{display:none}.dock-workbar[data-v-8cd7cb40]{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-1) var(--space-1-5);padding:var(--space-1) calc(var(--dock-inline-right) + var(--space-4) + var(--p-hairline)) var(--space-05) calc(var(--dock-inline-left) + var(--space-4) + var(--p-hairline))}.dock-workbar[data-v-8cd7cb40] .ui-pill{position:relative;gap:var(--space-1-5);height:auto;padding:var(--space-2) calc(var(--space-3) + var(--space-05)) var(--space-2) var(--space-3);border:none;border-radius:var(--radius-lg);background:var(--color-selected);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);color:var(--color-text);font-size:var(--text-base);line-height:var(--leading-normal)}.dock-workbar[data-v-8cd7cb40] .ui-pill svg{width:1.5em;height:1.5em;color:inherit}.dock-workbar[data-v-8cd7cb40] .ui-pill:after{content:"";position:absolute;inset:0;border-radius:var(--radius-lg);background:var(--color-hover);opacity:0;transition:opacity var(--duration-base) var(--ease-out);pointer-events:none}.dock-workbar[data-v-8cd7cb40] .ui-pill:hover:not(:disabled):after,.dock-workbar[data-v-8cd7cb40] .ui-pill.is-active:after{opacity:1}.chat-dock.pills-compact .dock-workbar[data-v-8cd7cb40] .ui-pill{padding:var(--space-2)}.chat-dock.pills-compact .dock-workbar[data-v-8cd7cb40] .ui-pill>span{display:none}.dock-workbar .dw-count[data-v-8cd7cb40]{color:var(--color-text-muted)}.dock-workbar .dw-running[data-v-8cd7cb40]{display:inline-flex;align-items:center;gap:var(--space-1);color:var(--color-text-muted)}.dock-workbar .dw-goal-status[data-v-8cd7cb40]{font-weight:var(--weight-medium)}.dock-workbar .dw-goal-status--active[data-v-8cd7cb40]{color:var(--color-success)}.dock-workbar .dw-goal-status--paused[data-v-8cd7cb40]{color:var(--color-warning)}.dock-workbar .dw-goal-status--blocked[data-v-8cd7cb40]{color:var(--color-danger)}.dock-approval[data-v-8cd7cb40]{margin-top:8px}.chat-dock.has-approval[data-v-8cd7cb40],.chat-dock.has-question[data-v-8cd7cb40]{display:flex;flex-direction:column;max-height:calc(var(--app-height, 100dvh) - var(--dock-card-top-clearance))}.chat-dock.has-approval>.dock-workbar[data-v-8cd7cb40],.chat-dock.has-question>.dock-workbar[data-v-8cd7cb40]{flex:none}.chat-dock.has-approval>.dock-approval[data-v-8cd7cb40],.chat-dock.has-question>.dock-question[data-v-8cd7cb40]{min-height:0}@media(max-width:640px){.chat-dock[data-v-8cd7cb40]{--dock-inline-left: max(12px, var(--safe-left));--dock-inline-right: max(12px, var(--safe-right))}.dock-work-panel[data-v-8cd7cb40]{left:10px;right:calc(10px + var(--panes-scrollbar-width, 0px))}.dock-work-head-actions[data-v-8cd7cb40] .ui-seg__item{height:var(--touch-target-min)}.dock-work-head-actions[data-v-8cd7cb40] .ui-icon-button{width:var(--touch-target-min);height:var(--touch-target-min)}}.chat-dock[data-v-8cd7cb40]:not(.align-mobile) .composer{padding-bottom:14px}.dock-panel-enter-active[data-v-8cd7cb40]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.dock-panel-leave-active[data-v-8cd7cb40]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.dock-panel-enter-from[data-v-8cd7cb40],.dock-panel-leave-to[data-v-8cd7cb40]{opacity:0;transform:translateY(var(--motion-panel-shift)) scale(var(--motion-panel-scale))}.ws-home[data-v-cf7957ea]{flex:none;display:flex;flex-direction:column;align-items:center;gap:var(--space-1);padding:0 var(--space-4) var(--space-4);user-select:none}.ws-home-title[data-v-cf7957ea]{display:flex;align-items:center;gap:10px;color:var(--color-text);font-size:var(--ui-t1);font-weight:var(--weight-section-label)}.ws-home-folder[data-v-cf7957ea]{color:var(--color-text-muted)}.ws-home-path[data-v-cf7957ea]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wrs[data-v-f463cc7b]{flex:none;display:flex;flex-direction:column;margin:var(--space-4) var(--dock-inline-right, 16px) 0 var(--dock-inline-left, 16px)}.wrs-caption[data-v-f463cc7b]{padding:0 var(--space-2) var(--space-1);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--faint);user-select:none}.wrs-row[data-v-f463cc7b]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-width:0;padding:6px var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);text-align:left;cursor:pointer}.wrs-row[data-v-f463cc7b]:hover{background:var(--color-hover)}.wrs-row[data-v-f463cc7b]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.wrs-ico[data-v-f463cc7b]{display:inline-flex;flex:none}.wrs-ico--open[data-v-f463cc7b]{color:var(--color-success)}.wrs-ico--done[data-v-f463cc7b]{color:var(--color-done)}.wrs-title[data-v-f463cc7b]{flex:1;min-width:0;font-size:var(--ui-font-size-sm);font-weight:var(--weight-caption);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.wrs-time[data-v-f463cc7b]{flex:none;color:var(--color-text-faint);font-size:var(--text-xs);font-variant-numeric:tabular-nums}.wrs-foot[data-v-f463cc7b]{display:flex;justify-content:center;margin-top:var(--space-2)}.wrs-more[data-v-f463cc7b]{display:inline-flex;align-items:center;gap:var(--space-1);height:26px;padding:0 var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.wrs-more[data-v-f463cc7b]:hover{background:var(--color-hover);color:var(--color-text)}.wrs-more svg[data-v-f463cc7b]{color:var(--color-text-faint)}.conversation-toc[data-v-b8ba267a]{position:absolute;z-index:var(--z-sticky);top:50%;transform:translateY(-50%);--toc-content-max: min( var(--p-content-max), calc(100cqi - var(--space-5) - var(--space-5)) );left:calc(50% + (var(--toc-content-max) / 2) + 14px);max-height:calc(100% - 160px);display:flex;flex-direction:column;justify-content:center;opacity:.5;transition:opacity var(--duration-base) var(--ease-out)}.conversation-toc[data-v-b8ba267a]:before{content:"";position:absolute;inset:0 -48px 0 -14px;z-index:0}.conversation-toc[data-v-b8ba267a]:hover,.conversation-toc[data-v-b8ba267a]:focus-within{opacity:1}.conversation-toc[data-v-b8ba267a]:hover:not(:focus-within){transition-delay:var(--duration-hover-intent)}.toc-scroll[data-v-b8ba267a]{position:relative;z-index:1;display:flex;flex-direction:column;gap:7px;padding:8px 0;min-height:0;overflow-y:auto;scrollbar-width:none}.toc-scroll[data-v-b8ba267a]::-webkit-scrollbar{display:none}.toc-row[data-v-b8ba267a]{display:flex;align-items:center;gap:10px;height:18px;padding:0;border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);text-align:left;cursor:pointer;white-space:nowrap}.toc-row[data-v-b8ba267a]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.toc-bar[data-v-b8ba267a]{flex:none;width:3px;height:14px;border-radius:var(--radius-full);background:var(--color-accent);opacity:.3;transition:opacity var(--duration-fast) var(--ease-out),height var(--duration-fast) var(--ease-out)}.toc-label[data-v-b8ba267a]{display:block;max-width:0;overflow:hidden;opacity:0;text-overflow:ellipsis;transition:max-width .22s var(--ease-out),opacity var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.conversation-toc:hover .toc-bar[data-v-b8ba267a],.conversation-toc:focus-within .toc-bar[data-v-b8ba267a]{height:18px;opacity:.5}.conversation-toc:hover .toc-label[data-v-b8ba267a],.conversation-toc:focus-within .toc-label[data-v-b8ba267a]{max-width:220px;opacity:1}.conversation-toc:hover:not(:focus-within) .toc-bar[data-v-b8ba267a]{transition-delay:0ms,var(--duration-hover-intent)}.conversation-toc:hover:not(:focus-within) .toc-label[data-v-b8ba267a]{transition-delay:var(--duration-hover-intent),var(--duration-hover-intent),0ms}.toc-row.active .toc-bar[data-v-b8ba267a]{opacity:1;height:18px}.toc-row.active .toc-label[data-v-b8ba267a]{color:var(--color-accent);font-weight:var(--weight-medium)}.toc-row:hover .toc-bar[data-v-b8ba267a]{opacity:1}.toc-row:hover .toc-label[data-v-b8ba267a]{color:var(--color-text)}.conversation-toc.toc-clipped[data-v-b8ba267a]{visibility:hidden;pointer-events:none}.tsearch[data-v-26f3fed5]{position:absolute;top:calc(var(--panel-head-h, 48px) + var(--space-3));right:var(--space-3);z-index:var(--z-sticky);width:min(var(--p-findbar-w),calc(100% - var(--space-3) * 2));background:var(--color-surface-raised);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-2xl);box-shadow:var(--shadow-menu);animation:kimi-card-in var(--duration-slow) var(--ease-out)}.tsearch.mobile[data-v-26f3fed5]{top:var(--space-3)}.tsearch[data-v-26f3fed5]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--color-composer-focus-line);border-radius:var(--radius-2xl);opacity:0;pointer-events:none;transition:opacity var(--duration-slow) var(--ease-in-out)}.tsearch[data-v-26f3fed5]:focus-within:after{opacity:1}.tsearch-main[data-v-26f3fed5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);min-height:calc(var(--space-8) + 2 * var(--space-1))}.tsearch-icon[data-v-26f3fed5]{flex:none;margin-left:var(--space-1);color:var(--color-text-muted)}.tsearch-input[data-v-26f3fed5]{flex:1;min-width:0;height:var(--space-8);padding:0;border:none;background:transparent;font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text)}.tsearch-input[data-v-26f3fed5]:focus-visible{outline:none}.tsearch-input[data-v-26f3fed5]::placeholder{color:var(--color-text-muted)}.tsearch-spin[data-v-26f3fed5]{display:inline-flex;flex:none}.tsearch-sep[data-v-26f3fed5]{flex:none;width:var(--p-hairline);height:var(--space-4);background:var(--color-line)}.tsearch .tsearch-close[data-v-26f3fed5]{border-radius:var(--radius-full)}.tsearch-foot-wrap[data-v-26f3fed5]{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--duration-slow) var(--ease-out)}.tsearch-foot-wrap.open[data-v-26f3fed5]{grid-template-rows:1fr}.tsearch-foot[data-v-26f3fed5]{overflow:hidden;min-height:0;display:flex;align-items:center;gap:var(--space-1);padding:0 var(--space-2)}.tsearch-foot-wrap.open .tsearch-foot[data-v-26f3fed5]{padding:var(--space-1) var(--space-2);border-top:var(--p-hairline) solid var(--color-line)}.tsearch-count[data-v-26f3fed5]{margin-left:auto;padding-right:var(--space-1);font-size:var(--ui-font-size-sm);color:var(--color-text-muted);white-space:nowrap;user-select:none}.tsearch-rings[data-v-26f3fed5]{position:absolute;inset:0;pointer-events:none}.tsearch-ring[data-v-26f3fed5]{position:absolute;box-sizing:content-box;border:var(--p-findring-w) solid var(--color-warning);margin:calc(-1 * var(--p-findring-w));border-radius:var(--radius-xs);pointer-events:none}.doodle-host[data-v-694a2ad0]{position:relative;width:100%;aspect-ratio:338 / 152;display:flex;align-items:center;justify-content:center}.doodle-canvas[data-v-694a2ad0]{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .25s ease}.doodle-canvas.ready[data-v-694a2ad0]{opacity:1}@media(prefers-reduced-motion:reduce){.doodle-canvas[data-v-694a2ad0]{transition:none}}.con[data-v-031838d6]{--read-max: 760px;display:flex;flex-direction:column;min-width:0;height:100%;position:relative;container-type:inline-size}.empty-drag[data-v-031838d6]{position:absolute;top:0;left:0;right:0;height:var(--panel-head-h, 48px)}.empty-drag.macos-desktop[data-v-031838d6]{-webkit-app-region:drag}.panes[data-v-031838d6]{flex:1;min-height:0;overflow-y:auto;overflow-anchor:auto;scrollbar-gutter:stable}.panes[data-v-031838d6]::-webkit-scrollbar{width:4px}.panes[data-v-031838d6]::-webkit-scrollbar-thumb{background:transparent;transition:background var(--duration-base) var(--ease-out)}.panes.scrolling[data-v-031838d6]::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.panes.scrolling[data-v-031838d6]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.panes.session-settling .chat[data-v-031838d6]>*:not(.chat-loading){visibility:hidden}.panes.is-following[data-v-031838d6],.panes.history-prepending[data-v-031838d6],.panes.is-pinned[data-v-031838d6]{overflow-anchor:none}.chat-layout[data-v-031838d6]{display:flex;flex-direction:column;height:100%;min-height:0;position:relative}.chat-scroll[data-v-031838d6]{flex:1;min-height:0;position:relative}.content-wrap[data-v-031838d6]{width:100%;max-width:var(--read-max);min-height:100%;box-sizing:border-box;padding-bottom:var(--chat-dock-height, 0px);display:flex;flex-direction:column;flex-shrink:0}.content-wrap.align-center[data-v-031838d6]{margin-left:auto;margin-right:auto}.content-wrap.align-left[data-v-031838d6]{margin-left:0;margin-right:auto}.content-wrap.align-mobile[data-v-031838d6]{max-width:none}@media(max-width:640px){.con.mobile[data-v-031838d6]{min-width:0;overflow:hidden}.con.mobile .panes[data-v-031838d6]{scrollbar-gutter:auto;-webkit-overflow-scrolling:touch}.content-wrap.align-mobile[data-v-031838d6]{width:100%;min-width:0}}.empty-spacer[data-v-031838d6]{flex:1}.empty-tail[data-v-031838d6]{min-height:0;overflow-y:auto;padding-bottom:var(--space-4);box-sizing:border-box}.empty-hint[data-v-031838d6]{flex:none;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;padding:0 16px 16px;color:var(--color-text);font-family:var(--font-ui);user-select:none}.empty-hint-title[data-v-031838d6]{font-size:calc(var(--ui-font-size) + 16px);font-optical-sizing:auto;font-weight:600}.empty-hint-title.is-starting[data-v-031838d6]{display:inline-flex;align-items:center;gap:9px;color:var(--dim);font-weight:400}.empty-doodle[data-v-031838d6]{width:min(340px,62vw)}.empty-hint-text[data-v-031838d6]{display:inline-block;font-size:var(--text-base);color:var(--dim);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.upgrade-banner[data-v-031838d6]{flex:none;display:flex;align-items:center;gap:var(--space-3);margin:0 var(--dock-inline-right, 16px) var(--space-2) var(--dock-inline-left, 16px);padding:var(--space-2) var(--space-3);border:.5px solid var(--color-accent-bd);border-radius:var(--radius-xl);background:var(--color-accent-soft)}.upgrade-banner-icon[data-v-031838d6]{flex:none;color:var(--color-accent)}.upgrade-banner-text[data-v-031838d6]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text)}.upgrade-banner-cta[data-v-031838d6]{flex:none;display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-accent);cursor:pointer}.upgrade-banner-cta[data-v-031838d6]:hover{color:var(--color-accent-hover)}.empty-composer[data-v-031838d6] .composer-card{position:relative;z-index:var(--z-sticky)}.empty-composer[data-v-031838d6]:not(.expanded) .ph{min-height:3lh}.ws-bar[data-v-031838d6]{margin-top:calc(-1 * var(--space-4));padding:calc(var(--space-4) + var(--space-2)) var(--space-2) var(--space-2);background:color-mix(in srgb,var(--color-hover) 60%,transparent);border-radius:0 0 var(--radius-2xl) var(--radius-2xl);font-family:var(--font-ui)}.ws-anchor[data-v-031838d6]{position:relative}.ws-chip[data-v-031838d6]{display:inline-flex;align-items:center;gap:var(--space-2);max-width:100%;padding:var(--space-2) var(--space-3);background:none;border:none;border-radius:var(--radius-full);color:var(--color-text-muted);font-family:inherit;font-size:var(--ui-font-size-sm);cursor:pointer;transition:background var(--duration-base) var(--ease-out)}.ws-chip[data-v-031838d6]:hover,.ws-chip.open[data-v-031838d6]{background:var(--color-selected);color:var(--color-text)}.ws-chip[data-v-031838d6]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ws-chip>.kw-icon[data-v-031838d6]{flex:none}.ws-chip-name[data-v-031838d6]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-option-label)}.ws-chip-chev[data-v-031838d6]{flex:none;transition:transform var(--duration-base) var(--ease-out)}.ws-chip.open .ws-chip-chev[data-v-031838d6]{transform:rotate(180deg)}.ws-chip.ws-ghost[data-v-031838d6]{color:var(--color-text-muted)}.ws-chip.ws-ghost[data-v-031838d6]:hover{color:var(--color-text)}.ws-backdrop[data-v-031838d6]{position:fixed;inset:0;z-index:var(--z-sticky)}.ws-panel[data-v-031838d6]{position:absolute;box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);left:0;top:calc(100% + var(--space-1));z-index:var(--z-dropdown);width:max-content;min-width:min(calc(var(--space-8) * 8),100%);max-width:100%;max-height:calc(var(--space-8) * 10);overflow:hidden auto;background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);padding:var(--space-1);animation:ws-pop-031838d6 var(--duration-base) var(--ease-out)}.ws-panel.up[data-v-031838d6]{top:auto;bottom:calc(100% + var(--space-1));animation-name:ws-pop-up-031838d6}@keyframes ws-pop-031838d6{0%{opacity:0;transform:translateY(calc(-1 * var(--space-1))) scale(.99)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes ws-pop-up-031838d6{0%{opacity:0;transform:translateY(var(--space-1)) scale(.99)}to{opacity:1;transform:translateY(0) scale(1)}}.ws-caption[data-v-031838d6]{padding:var(--space-1) var(--space-2);font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--color-text-faint);user-select:none}.ws-row[data-v-031838d6]{display:flex;align-items:center;gap:var(--space-2);width:100%;text-align:left;background:none;border:none;border-radius:var(--radius-dropdown-row);padding:var(--space-1) var(--space-2);cursor:pointer;font-family:var(--font-ui)}.ws-row>.kw-icon[data-v-031838d6]{flex:none;color:var(--muted)}.ws-row[data-v-031838d6]:hover{background:var(--color-hover)}.ws-row.on[data-v-031838d6]{background:var(--color-selected)}.ws-row[data-v-031838d6]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ws-info[data-v-031838d6]{flex:1;min-width:0;display:flex;flex-direction:column}.ws-name[data-v-031838d6]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);font-weight:var(--weight-option-label);color:var(--color-text);line-height:var(--leading-normal)}.ws-path[data-v-031838d6]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);font-weight:var(--weight-option-label);color:var(--muted);line-height:var(--leading-normal)}.ws-check[data-v-031838d6]{flex:none;margin-left:var(--space-3);color:var(--color-text)}.ws-divider[data-v-031838d6]{height:1px;margin:var(--space-1) var(--space-2);background:var(--line)}.ws-action[data-v-031838d6]{display:flex;align-items:center;gap:var(--space-2);width:100%;text-align:left;background:none;border:none;border-radius:var(--radius-dropdown-row);padding:var(--space-2);cursor:pointer;font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--dim)}.ws-action>.kw-icon[data-v-031838d6]{flex:none;color:var(--muted)}.ws-action span[data-v-031838d6]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-action[data-v-031838d6]:hover{background:var(--color-hover);color:var(--color-text)}.ws-action:hover>.kw-icon[data-v-031838d6]{color:var(--dim)}.ws-action[data-v-031838d6]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.chat-scroll[data-v-031838d6]{display:flex;flex-direction:column}.mobile .panes[data-v-031838d6]:has(>.chat-layout){overflow:hidden;scrollbar-gutter:auto}.newmsg-pill[data-v-031838d6]{position:absolute;left:50%;bottom:12px;transform:translate(-50%);display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;border:.5px solid var(--line);background:var(--panel);color:var(--color-text);font-size:var(--text-xs);font-weight:var(--weight-ui-strong);cursor:pointer;box-shadow:var(--shadow-sm);z-index:var(--z-sticky)}.pill-chevron[data-v-031838d6]{width:12px;height:12px}.pill-enter-active[data-v-031838d6],.pill-leave-active[data-v-031838d6]{transition:opacity .2s ease,transform .2s ease}.pill-enter-from[data-v-031838d6],.pill-leave-to[data-v-031838d6]{opacity:0;transform:translate(-50%) translateY(8px)}.undo-toast[data-v-031838d6]{position:absolute;left:50%;top:60px;transform:translate(-50%);padding:8px 14px;border-radius:var(--radius-sm);background:var(--color-text);color:var(--bg);font-size:var(--ui-font-size-sm);z-index:var(--z-sticky);box-shadow:var(--shadow-sm)}.undo-toast-text[data-v-031838d6]{display:flex;align-items:center;gap:8px}.undo-toast-enter-active[data-v-031838d6],.undo-toast-leave-active[data-v-031838d6]{transition:opacity .15s ease,transform .15s ease}.undo-toast-enter-from[data-v-031838d6],.undo-toast-leave-to[data-v-031838d6]{opacity:0;transform:translate(-50%) translateY(-6px)}.con[data-v-031838d6]{background:var(--bg)}.newmsg-pill[data-v-031838d6]{font-family:var(--sans)}.sa-select[data-v-559b928b]{display:inline-flex;align-items:center;gap:var(--space-1-5);height:30px;padding:0 var(--space-3);border:.5px solid var(--color-line);border-radius:var(--radius-md);background:transparent;color:var(--color-text);font-size:var(--text-sm);font-weight:var(--weight-option-label);line-height:1;white-space:nowrap;transition:background var(--duration-fast) var(--ease-out)}.sa-select[data-v-559b928b]:hover,.sa-select.is-open[data-v-559b928b]{background:var(--color-hover)}.sa-select-chev[data-v-559b928b]{color:var(--color-text-faint)}.sa-menu[data-v-559b928b]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.sa-check[data-v-559b928b]{display:inline-flex;flex:none;width:14px}.sa-dot[data-v-559b928b]{flex:none;width:8px;height:8px;border-radius:var(--radius-full)}.sa-dot--open[data-v-559b928b]{background:var(--color-success)}.sa-dot--done[data-v-559b928b]{background:var(--color-done)}.menu-pop-enter-active[data-v-559b928b]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-559b928b]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-559b928b],.menu-pop-leave-to[data-v-559b928b]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}.sa-select[data-v-08fc2991]{display:inline-flex;align-items:center;gap:var(--space-1-5);min-height:30px;padding:0 var(--space-2);border:.5px solid var(--color-line);border-radius:var(--radius-md);background:transparent;color:var(--color-text);font-size:var(--text-sm);font-weight:var(--weight-option-label);line-height:1;white-space:nowrap;cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.sa-select[data-v-08fc2991]:hover,.sa-select.is-open[data-v-08fc2991]{background:var(--color-hover)}.sa-select[data-v-08fc2991]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.sa-select-chev[data-v-08fc2991]{color:var(--color-text-faint)}.sa-tag[data-v-08fc2991]{display:inline-flex;align-items:center;gap:1px;height:20px;padding:0 2px 0 var(--space-1-5);border-radius:var(--radius-xs);background:var(--color-selected);font-size:var(--text-xs)}.sa-tag-name[data-v-08fc2991]{max-width:120px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sa-tag-x[data-v-08fc2991]{display:inline-flex;align-items:center;justify-content:center;flex:none;width:16px;height:16px;padding:0;border:none;border-radius:var(--radius-xs);background:transparent;color:var(--color-text-faint);cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.sa-tag-x[data-v-08fc2991]:hover{background:var(--color-hover);color:var(--color-text)}.sa-tag-more[data-v-08fc2991]{color:var(--color-text-muted);font-size:var(--text-xs)}.sa-menu[data-v-08fc2991]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.sa-search[data-v-08fc2991]{display:flex;align-items:center;gap:7px;padding:5px 9px;color:var(--color-text-faint)}.sa-search-input[data-v-08fc2991]{flex:1;min-width:0;border:none;outline:none;background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);line-height:var(--leading-tight)}.sa-search-input[data-v-08fc2991]::placeholder{color:var(--color-text-faint)}.sa-ws-name[data-v-08fc2991]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sa-opts[data-v-08fc2991]{max-height:320px;overflow-y:auto;overscroll-behavior:contain}.sa-menu-empty[data-v-08fc2991]{padding:5px 9px;color:var(--color-text-faint);font-size:var(--text-sm)}.menu-pop-enter-active[data-v-08fc2991]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-08fc2991]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-08fc2991],.menu-pop-leave-to[data-v-08fc2991]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}.sa-menu[data-v-770e2854]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.sa-menu-head[data-v-770e2854]{padding:var(--space-1) var(--space-2) var(--space-05);color:var(--color-text-faint);font-size:var(--text-xs);user-select:none}.menu-pop-enter-active[data-v-770e2854]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-770e2854]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-770e2854],.menu-pop-leave-to[data-v-770e2854]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}.sa-table-card[data-v-9b9dc9c2]{border:.5px solid var(--color-line);border-radius:var(--radius-lg);background:var(--color-bg);overflow-x:auto;container-type:inline-size;transition:opacity var(--duration-fast) var(--ease-out)}.sa-table-card.is-loading[data-v-9b9dc9c2]{opacity:.45;pointer-events:none}table[data-v-9b9dc9c2]{width:100%;min-width:640px;border-collapse:collapse;table-layout:fixed}.sa-col-cb[data-v-9b9dc9c2]{width:36px}.sa-col-title[data-v-9b9dc9c2]{width:max(200px,20%)}.sa-col-ws[data-v-9b9dc9c2]{width:116px}.sa-col-status[data-v-9b9dc9c2]{width:88px}.sa-col-time[data-v-9b9dc9c2]{width:140px}.sa-col-act[data-v-9b9dc9c2]{width:84px}.sa-time--compact[data-v-9b9dc9c2]{display:none}@container (max-width: 1020px){.sa-col-time[data-v-9b9dc9c2]{width:108px}.sa-time--full[data-v-9b9dc9c2]{display:none}.sa-time--compact[data-v-9b9dc9c2]{display:inline}}@container (max-width: 760px){col.sa-col-time[data-v-9b9dc9c2],.sa-c-time[data-v-9b9dc9c2]{display:none}.sa-col-ws[data-v-9b9dc9c2]{width:96px}}thead th[data-v-9b9dc9c2]{height:32px;padding:0 var(--space-3);border-bottom:.5px solid var(--color-line);color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium);text-align:left;white-space:nowrap;user-select:none}th.sa-col-cb[data-v-9b9dc9c2],td.sa-col-cb[data-v-9b9dc9c2]{padding-right:0}tbody td[data-v-9b9dc9c2]{height:40px;padding:0 var(--space-3);border-bottom:.5px solid var(--color-subtle);font-size:var(--text-sm);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle}tbody tr:last-child td[data-v-9b9dc9c2]{border-bottom:none}tbody tr[data-v-9b9dc9c2]{transition:background var(--duration-fast) var(--ease-out)}tbody tr[data-v-9b9dc9c2]:hover{background:var(--color-hover)}.sa-cb[data-v-9b9dc9c2]{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border:.5px solid var(--color-line-strong);border-radius:var(--radius-xs);color:var(--color-text-on-accent);vertical-align:middle;transition:background var(--duration-fast) var(--ease-out),border-color var(--duration-fast) var(--ease-out)}.sa-cb[data-v-9b9dc9c2]:hover{border-color:var(--color-text-faint)}.sa-cb.on[data-v-9b9dc9c2],.sa-cb.ind[data-v-9b9dc9c2]{background:var(--color-accent);border-color:var(--color-accent)}.sa-batch-inner[data-v-9b9dc9c2]{display:flex;align-items:center;gap:var(--space-2)}.sa-batch-count[data-v-9b9dc9c2]{margin-right:var(--space-1);color:var(--color-text-muted);font-size:var(--text-sm);white-space:nowrap;user-select:none}.sa-batch-link[data-v-9b9dc9c2]{display:inline-flex;align-items:center;height:24px;padding:0 var(--space-1);border:none;background:transparent;color:var(--color-accent);font-size:var(--text-sm);font-weight:var(--weight-medium);white-space:nowrap}.sa-batch-link[data-v-9b9dc9c2]:hover{text-decoration:underline}.sa-batch-link[data-v-9b9dc9c2]:disabled{color:var(--color-text-faint);cursor:default;text-decoration:none}.sa-btn-q[data-v-9b9dc9c2]{display:inline-flex;align-items:center;gap:var(--space-1-5);height:24px;padding:0 var(--space-2);border:.5px solid var(--color-line);border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:1;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.sa-btn-q[data-v-9b9dc9c2]:hover{background:var(--color-hover)}.sa-btn-q[data-v-9b9dc9c2]:disabled{opacity:.42;cursor:default}.sa-btn-q[data-v-9b9dc9c2]:disabled:hover{background:transparent}.sa-btn-q[data-v-9b9dc9c2] :first-child{color:var(--color-text-muted)}.sa-btn-q[data-v-9b9dc9c2]:hover :first-child{color:var(--color-text)}.sa-btn-q--primary[data-v-9b9dc9c2],.sa-btn-q--primary[data-v-9b9dc9c2] :first-child{border-color:var(--color-accent);background:var(--color-accent);color:var(--color-text-on-accent)}.sa-btn-q--primary[data-v-9b9dc9c2]:hover,.sa-btn-q--primary[data-v-9b9dc9c2]:hover :first-child{border-color:var(--color-accent-hover);background:var(--color-accent-hover);color:var(--color-text-on-accent)}.sa-btn-q--primary[data-v-9b9dc9c2]:disabled,.sa-btn-q--primary[data-v-9b9dc9c2]:disabled:hover,.sa-btn-q--primary[data-v-9b9dc9c2]:disabled :first-child,.sa-btn-q--primary[data-v-9b9dc9c2]:disabled:hover :first-child{border-color:var(--color-accent);background:var(--color-accent);color:var(--color-text-on-accent)}.sa-st[data-v-9b9dc9c2]{display:inline-flex;align-items:center;gap:var(--space-1-5)}.sa-st--open[data-v-9b9dc9c2]{color:var(--color-success)}.sa-st--done[data-v-9b9dc9c2]{color:var(--color-done)}.sa-title[data-v-9b9dc9c2]{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text);font-weight:var(--weight-option-label)}.sa-rename[data-v-9b9dc9c2]{width:100%;height:26px;padding:0 var(--space-1-5);border:1px solid var(--color-accent);border-radius:var(--radius-sm);outline:none;box-shadow:0 0 0 2px var(--color-accent-bd);background:var(--color-bg);color:var(--color-text);font-family:inherit;font-size:var(--text-sm)}.sa-ws[data-v-9b9dc9c2]{display:inline-flex;align-items:center;max-width:100%;color:var(--color-text-muted)}.sa-ws span[data-v-9b9dc9c2]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sa-prompt[data-v-9b9dc9c2]{color:var(--color-text-muted)}.sa-time[data-v-9b9dc9c2]{color:var(--color-text-muted);font-family:var(--font-mono);font-size:var(--text-xs);font-variant-numeric:tabular-nums;white-space:nowrap}.sa-none[data-v-9b9dc9c2]{color:var(--color-text-faint)}.sa-act[data-v-9b9dc9c2]{display:flex;align-items:center;gap:var(--space-05)}.sa-state[data-v-9b9dc9c2]{display:flex;align-items:center;justify-content:center;padding:calc(var(--space-8) + var(--space-6)) var(--space-4)}.sa-empty[data-v-9b9dc9c2]{color:var(--color-text-faint);font-size:var(--text-sm)}.sa-pager[data-v-a27fa76f]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);flex-wrap:wrap;margin-top:var(--space-3)}.sa-total[data-v-a27fa76f]{color:var(--color-text-muted);font-size:var(--text-sm);font-variant-numeric:tabular-nums;user-select:none}.sa-pager-right[data-v-a27fa76f]{display:flex;align-items:center;gap:var(--space-3)}.sa-pages[data-v-a27fa76f]{display:flex;align-items:center;gap:var(--space-05)}.sa-pg[data-v-a27fa76f]{display:inline-flex;align-items:center;justify-content:center;min-width:26px;height:26px;padding:0 var(--space-1-5);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-size:var(--text-sm);font-variant-numeric:tabular-nums;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.sa-pg[data-v-a27fa76f]:hover{background:var(--color-hover);color:var(--color-text)}.sa-pg.cur[data-v-a27fa76f]{background:var(--color-selected);color:var(--color-text);font-weight:var(--weight-medium)}.sa-pg.cur[data-v-a27fa76f]:hover{background:var(--color-selected)}.sa-pg[data-v-a27fa76f]:disabled{opacity:.38;cursor:default}.sa-pg[data-v-a27fa76f]:disabled:hover{background:transparent;color:var(--color-text-muted)}.sa-ellipsis[data-v-a27fa76f]{padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-sm);user-select:none}.session-admin[data-v-01565f3a]{display:flex;flex-direction:column;min-width:0;height:100%;background:var(--color-bg);font-family:var(--font-ui)}.sa-scroll[data-v-01565f3a]{flex:1;min-height:0;overflow-y:auto}.sa-page[data-v-01565f3a]{padding:var(--space-8) var(--space-6);display:flex;flex-direction:column;box-sizing:border-box}.sa-head[data-v-01565f3a]{flex:none;display:flex;align-items:center;gap:var(--space-2);height:48px;padding:0 var(--space-6);border-bottom:.5px solid var(--color-line);box-sizing:border-box}.sa-title[data-v-01565f3a]{margin:0;font-size:var(--text-base);font-weight:var(--weight-semibold);line-height:var(--leading-tight);color:var(--color-text);user-select:none}.sa-subtitle[data-v-01565f3a]{margin:0 0 var(--space-3);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted)}.session-admin.macos-desktop .sa-head[data-v-01565f3a]{-webkit-app-region:drag}.session-admin.macos-desktop .sa-head button[data-v-01565f3a],.session-admin.macos-desktop .sa-head input[data-v-01565f3a]{-webkit-app-region:no-drag}.sa-filters[data-v-01565f3a]{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;margin-bottom:var(--space-3)}.sa-f-label[data-v-01565f3a]{margin-left:var(--space-2);color:var(--color-text-muted);font-size:var(--text-sm);user-select:none}.sa-f-label[data-v-01565f3a]:first-child{margin-left:0}.sa-f-actions[data-v-01565f3a]{display:inline-flex;align-items:center;gap:var(--space-2);margin-left:var(--space-2)}.file-preview[data-v-9a4f39c9]{display:flex;flex-direction:column;height:100%;background:var(--bg);font-family:var(--mono);min-width:0;container-type:inline-size}.fp-empty[data-v-9a4f39c9],.fp-loading[data-v-9a4f39c9]{flex:1;display:flex;align-items:center;justify-content:center;gap:10px;color:var(--muted);font-size:var(--ui-font-size)}.fp-path[data-v-9a4f39c9]{flex:1 1 60px;min-width:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left;font-size:var(--ui-font-size-xs);color:var(--muted);font-weight:400}.fp-meta[data-v-9a4f39c9]{display:flex;align-items:center;gap:8px;flex:none}@container (max-width: 539px){.fp-meta[data-v-9a4f39c9]{display:none}}.fp-lines[data-v-9a4f39c9],.fp-size[data-v-9a4f39c9]{font-size:max(9px,calc(var(--ui-font-size) - 3.5px));color:var(--muted);white-space:nowrap}.fp-search[data-v-9a4f39c9]{display:flex;align-items:center;gap:4px;flex:1 1 110px;min-width:70px;max-width:200px}.fp-search-input[data-v-9a4f39c9]{flex:1;min-width:0;height:26px;border:.5px solid var(--color-line);border-radius:var(--radius-sm);padding:2px 7px;background:var(--color-surface-raised);color:var(--color-text);font:var(--text-xs) var(--font-mono)}.fp-search-count[data-v-9a4f39c9]{color:var(--muted);font-size:max(9px,calc(var(--ui-font-size) - 3.5px));min-width:18px;text-align:right}.fp-download[data-v-9a4f39c9]{display:inline-grid;place-items:center;width:26px;height:26px;flex:none;border-radius:var(--radius-sm);color:var(--color-text-muted)}.fp-download[data-v-9a4f39c9]:hover{background:var(--color-hover);color:var(--color-text)}.fp-download[data-v-9a4f39c9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.fp-download svg[data-v-9a4f39c9]{width:var(--p-ic-sm);height:var(--p-ic-sm)}.fp-check[data-v-9a4f39c9]{color:var(--color-success)}.fp-body[data-v-9a4f39c9]{--fp-search-hit-bg: color-mix(in srgb, var(--star) 22%, var(--bg));--fp-search-active-bg: color-mix(in srgb, var(--star) 36%, var(--bg));flex:1;min-height:0;overflow:auto}.fp-markdown[data-v-9a4f39c9]{padding:16px 20px}.fp-code[data-v-9a4f39c9]{background:var(--bg)}.fp-code[data-v-9a4f39c9] .hl-row.hit,.fp-table tr.hit td[data-v-9a4f39c9]{background:var(--fp-search-hit-bg)}.fp-code[data-v-9a4f39c9] .hl-row.active,.fp-table tr.active td[data-v-9a4f39c9]{background:var(--fp-search-active-bg)}.fp-code[data-v-9a4f39c9] .hl-row.target,.fp-table tr.target th[data-v-9a4f39c9],.fp-table tr.target td[data-v-9a4f39c9]{background:var(--color-accent-soft)}.fp-html-frame[data-v-9a4f39c9],.fp-pdf-frame[data-v-9a4f39c9]{width:100%;height:100%;border:0;background:var(--color-surface-raised)}.fp-pdf-wrap[data-v-9a4f39c9]{background:var(--panel2)}.fp-table-wrap[data-v-9a4f39c9]{background:var(--bg)}.fp-table[data-v-9a4f39c9]{border-collapse:collapse;min-width:100%;font:var(--code-font-size)/var(--leading-normal) var(--mono)}.fp-table th[data-v-9a4f39c9]{position:sticky;left:0;z-index:1;width:44px;min-width:44px;padding:2px 8px;text-align:right;color:var(--faint);background:var(--panel);border-right:.5px solid var(--line2);user-select:none}.fp-table td[data-v-9a4f39c9]{padding:2px 10px;border-right:.5px solid var(--line2);border-bottom:.5px solid var(--line2);white-space:pre}.fp-image-wrap[data-v-9a4f39c9]{display:flex;align-items:center;justify-content:center;padding:24px;background:var(--panel2)}.fp-image[data-v-9a4f39c9]{max-width:100%;max-height:100%;object-fit:contain;border:.5px solid var(--line);border-radius:4px;background:var(--media-alpha-canvas)}.fp-image.actual[data-v-9a4f39c9]{max-width:none;max-height:none}.fp-binary-wrap[data-v-9a4f39c9]{display:flex;align-items:center;justify-content:center}.fp-binary-card[data-v-9a4f39c9]{display:flex;align-items:center;gap:12px;padding:20px 24px;border:.5px solid var(--line);border-radius:6px;background:var(--panel);color:var(--muted);font-size:var(--ui-font-size);margin:32px auto;max-width:480px}.fp-binary-icon[data-v-9a4f39c9]{color:var(--faint);flex:none}.fp-error[data-v-9a4f39c9]{flex-direction:column;padding:24px;text-align:center}@keyframes spin-9a4f39c9{to{transform:rotate(360deg)}}.spinner[data-v-9a4f39c9]{display:inline-block;width:14px;height:14px;border:.5px solid var(--line);border-top-color:var(--color-accent);border-radius:50%;animation:spin-9a4f39c9 .7s linear infinite}@media(max-width:640px){.fp-lines[data-v-9a4f39c9]{display:none}.fp-markdown[data-v-9a4f39c9]{padding:14px 16px}.fp-body.fp-code[data-v-9a4f39c9]{-webkit-overflow-scrolling:touch}}.fp-empty[data-v-9a4f39c9],.fp-loading[data-v-9a4f39c9]{font-family:var(--sans)}.fp-binary-card[data-v-9a4f39c9]{border:.5px solid var(--color-line);border-radius:var(--radius-md)}.fp-binary-label[data-v-9a4f39c9]{font-family:var(--sans)}.fp-image[data-v-9a4f39c9]{border-radius:var(--radius-md)}.seg-btn[data-v-9a4f39c9]{font-family:var(--sans)}.tp[data-v-afb1f46f]{height:100%;display:flex;flex-direction:column;min-height:0;background:var(--color-bg)}.tp-body[data-v-afb1f46f]{flex:1;min-height:0;overflow-y:auto;margin:0;padding:12px 14px;font:var(--text-base)/var(--leading-relaxed) var(--font-ui);font-weight:400;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-word}.agent-panel[data-v-87af6ca2]{height:100%;min-height:0;display:flex;flex-direction:column;background:var(--color-bg)}.agent-transcript[data-v-87af6ca2]{flex:1;min-height:0;overflow-y:auto}.agent-transcript[data-v-87af6ca2] .think-body,.agent-transcript[data-v-87af6ca2] .ar-body,.agent-transcript[data-v-87af6ca2] .tf-body,.agent-transcript[data-v-87af6ca2] .bb,.agent-transcript[data-v-87af6ca2] .tl-body{transition:none}.agent-error[data-v-87af6ca2]{color:var(--color-danger);font:var(--text-sm)/var(--leading-normal) var(--font-ui)}.copy-menu[data-v-87af6ca2]{position:fixed;z-index:var(--z-dropdown)}.agent-fallback[data-v-87af6ca2]{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4)}.sc[data-v-ce2b775d]{height:100%;display:flex;flex-direction:column;min-height:0;background:var(--bg)}.sc-body[data-v-ce2b775d]{flex:1;min-height:0;overflow-y:auto}.sc-empty[data-v-ce2b775d]{padding:24px 16px;text-align:center;color:var(--muted);font-size:var(--ui-font-size)}.sc-composer[data-v-ce2b775d]{flex:none;display:flex;align-items:flex-end;gap:6px;padding:8px 10px;border-top:.5px solid var(--color-line);background:var(--color-surface-raised)}.sc-input[data-v-ce2b775d]{flex:1;min-width:0;resize:none;border:.5px solid var(--color-line);border-radius:var(--r-sm);padding:7px 9px;background:var(--bg);color:var(--color-text);font:var(--ui-font-size)/1.5 var(--sans);outline:none;max-height:160px}.sc-input[data-v-ce2b775d]:focus{border-color:var(--color-accent-bd)}.sc-send[data-v-ce2b775d]{flex:none;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--r-sm);background:var(--color-accent);color:var(--color-text-on-accent);cursor:pointer}.sc-send[data-v-ce2b775d]:disabled{opacity:.4;cursor:default}.sc-send[data-v-ce2b775d]:not(:disabled):hover{background:var(--color-accent-hover)}.sc-loading[data-v-ce2b775d]{flex:none;padding:8px 12px 12px}.sc-body[data-v-ce2b775d] .sending-placeholder,.sc-body[data-v-ce2b775d] .sending-line{display:none}.changes-pane[data-v-7d5ab9c7]{display:flex;flex-direction:column;height:100%;background:var(--bg);font-family:var(--mono)}.dv-path[data-v-7d5ab9c7],.dv-change-count[data-v-7d5ab9c7]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:var(--ui-font-size-xs);color:var(--muted)}.dv-change-count[data-v-7d5ab9c7]{flex:1;align-self:stretch;display:inline-flex;align-items:center;font-family:var(--font-ui)}.dv-path[data-v-7d5ab9c7]{font-family:var(--font-ui)}.ch-head[data-v-7d5ab9c7]{display:flex;align-items:center;gap:8px;padding:8px var(--space-3);border-bottom:.5px solid var(--line);background:var(--panel);font-size:var(--text-base);color:var(--dim);flex:none;white-space:nowrap;overflow:hidden;font-family:var(--font-ui);user-select:none}.br-heading[data-v-7d5ab9c7]{display:inline-flex;align-items:center;gap:var(--space-1);flex:none}.br-icon[data-v-7d5ab9c7]{flex:none;color:var(--muted)}.br-label[data-v-7d5ab9c7]{color:var(--muted);font-size:var(--text-xs);font-weight:500}.br-name[data-v-7d5ab9c7]{color:var(--color-text);font-weight:500;font-size:var(--text-xs)}.sync-info[data-v-7d5ab9c7]{display:flex;align-items:center;gap:4px}.ahead[data-v-7d5ab9c7]{color:var(--color-accent);font-size:var(--text-xs)}.behind[data-v-7d5ab9c7]{color:var(--color-warning);font-size:var(--text-xs)}.empty-head[data-v-7d5ab9c7]{color:var(--muted);font-size:var(--text-base)}.ch-list[data-v-7d5ab9c7]{flex:1;min-height:0}.ch-list-content[data-v-7d5ab9c7]{min-height:100%;padding:4px 0}.ch-row[data-v-7d5ab9c7]{display:flex;align-items:center;gap:6px;padding:3px 8px;cursor:pointer;font-size:var(--text-xs);line-height:1.6;width:100%;background:none;border:none;text-align:left;font-family:var(--font-ui);color:inherit}.ch-row[data-v-7d5ab9c7]:hover{background:var(--panel2)}.ch-row[data-v-7d5ab9c7]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.ch-tree[data-v-7d5ab9c7]{--tree-base-indent: 14px;--tree-indent-step: 12px;font-family:var(--font-ui)}.tree-list[data-v-7d5ab9c7]{list-style:none;margin:0}.tree-node[data-v-7d5ab9c7]{overflow:hidden;interpolate-size:allow-keywords}.tree-collapse-enter-active[data-v-7d5ab9c7],.tree-collapse-leave-active[data-v-7d5ab9c7]{transition:block-size var(--duration-base) var(--ease-out),opacity var(--duration-fast) var(--ease-out),transform var(--duration-base) var(--ease-out)}.tree-collapse-enter-from[data-v-7d5ab9c7],.tree-collapse-leave-to[data-v-7d5ab9c7]{block-size:0;opacity:0;transform:translateY(-3px)}.tree-collapse-enter-to[data-v-7d5ab9c7],.tree-collapse-leave-from[data-v-7d5ab9c7]{block-size:auto;opacity:1;transform:translateY(0)}.tree-row[data-v-7d5ab9c7]{position:relative;display:flex;align-items:center;gap:6px;width:100%;margin-top:1px;padding:3px 8px;background:none;border:none;text-align:left;font-family:inherit;font-size:var(--text-xs);color:inherit;cursor:pointer}.tree-row[data-v-7d5ab9c7]:before{content:"";position:absolute;top:0;bottom:0;left:calc(var(--tree-base-indent) + 6px);width:calc(var(--tree-depth, 0) * var(--tree-indent-step));background:repeating-linear-gradient(to right,var(--color-line) 0 1px,transparent 1px var(--tree-indent-step));pointer-events:none}.tree-row[data-v-7d5ab9c7]:hover{background:var(--panel2)}.tree-row[data-v-7d5ab9c7]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.tree-folder[data-v-7d5ab9c7]{color:var(--color-text);font-weight:500}.tree-file[data-v-7d5ab9c7]{color:var(--color-text);font-weight:450}.tree-icon[data-v-7d5ab9c7]{flex:none;color:var(--muted)}.tree-name[data-v-7d5ab9c7]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.badge[data-v-7d5ab9c7]{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:var(--radius-xs);font-size:max(9px,calc(var(--ui-font-size) - 4px));font-weight:500;flex:none;user-select:none}.badge.modified[data-v-7d5ab9c7]{background:var(--color-warning-soft);color:var(--color-warning)}.badge.added[data-v-7d5ab9c7]{background:var(--color-success-soft);color:var(--color-success)}.badge.deleted[data-v-7d5ab9c7]{background:var(--color-danger-soft);color:var(--color-danger)}.badge.renamed[data-v-7d5ab9c7]{background:var(--color-done-soft);color:var(--color-done)}.badge.untracked[data-v-7d5ab9c7]{background:var(--color-success-soft);color:var(--color-success)}.badge.conflicted[data-v-7d5ab9c7]{background:color-mix(in srgb,var(--color-danger) 10%,var(--bg));color:var(--color-danger);font-size:max(9px,calc(var(--ui-font-size) - 5px))}.badge.ignored[data-v-7d5ab9c7]{background:var(--color-well);color:var(--faint)}.badge.clean[data-v-7d5ab9c7]{background:transparent;color:var(--faint)}.badge.unknown[data-v-7d5ab9c7]{background:var(--color-well);color:var(--muted)}.fpath[data-v-7d5ab9c7]{color:var(--color-text);font-size:var(--text-xs);font-weight:450;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;text-align:left;min-width:0}.fpath[data-v-7d5ab9c7]:before,.fpath[data-v-7d5ab9c7]:after{content:"‎"}.empty-state[data-v-7d5ab9c7]{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:32px 20px;color:var(--muted);font-size:var(--ui-font-size);text-align:center;user-select:none}.empty-state-icon[data-v-7d5ab9c7]{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:var(--color-well);color:var(--color-text-muted)}.diff-head[data-v-7d5ab9c7]{display:flex;align-items:center;gap:10px;padding:6px 12px;border-bottom:.5px solid var(--line);background:var(--panel);flex:none;white-space:nowrap;overflow:hidden}.dv-lines-wrap[data-v-7d5ab9c7]{flex:1;min-height:0;overflow:auto}.diff-content-enter-active[data-v-7d5ab9c7],.diff-content-leave-active[data-v-7d5ab9c7]{transition:opacity var(--duration-base) var(--ease-out)}.diff-content-enter-from[data-v-7d5ab9c7],.diff-content-leave-to[data-v-7d5ab9c7]{opacity:0}@media(max-width:640px){.ch-head[data-v-7d5ab9c7]{padding:10px 14px}.ch-list[data-v-7d5ab9c7]{padding:2px 0 12px}.ch-row[data-v-7d5ab9c7]{min-height:44px;padding:8px 14px;gap:12px;font-size:var(--text-xs)}.ch-row[data-v-7d5ab9c7]:active{background:var(--panel2)}.badge[data-v-7d5ab9c7]{width:18px;height:18px}.fpath[data-v-7d5ab9c7]{font-size:var(--text-xs)}.tree-row[data-v-7d5ab9c7]{min-height:40px;padding:8px 14px}.diff-head[data-v-7d5ab9c7]{padding:8px 12px;gap:10px}.diff-path[data-v-7d5ab9c7]{font-size:var(--text-base)}}.changes-pane .empty-state[data-v-7d5ab9c7],.br-label[data-v-7d5ab9c7],.empty-head[data-v-7d5ab9c7]{font-family:var(--sans)}.ch-row[data-v-7d5ab9c7],.ct-row[data-v-7d5ab9c7]{margin:1px 6px;width:calc(100% - 12px);border-radius:var(--radius-md)}.changes-pane .badge[data-v-7d5ab9c7],.changed-tree .badge[data-v-7d5ab9c7]{border-radius:var(--radius-sm)}.change-count[data-v-7d5ab9c7]{font-family:var(--sans);border-radius:999px}.td[data-v-fdd0bc05]{display:flex;flex-direction:column;height:100%;min-height:0}.td-path[data-v-fdd0bc05]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--ui-c1) var(--font-mono);color:var(--color-text-muted)}.td-body[data-v-fdd0bc05]{flex:1;min-height:0;overflow:auto}.td-empty[data-v-fdd0bc05]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);height:100%;padding:var(--space-6);color:var(--color-text-muted);font-size:var(--text-sm);text-align:center}.mp[data-v-87452cd9]{display:flex;flex-direction:column;gap:var(--space-2);height:100%;min-height:0;padding-top:4px}.mp--sheet[data-v-87452cd9]{height:auto;padding-top:0}.mp--sheet .search-wrap[data-v-87452cd9],.mp--sheet .chip-strip[data-v-87452cd9]{margin:0 16px}.search-wrap[data-v-87452cd9]{position:relative;margin:0 22px;padding-bottom:var(--space-1)}.search-wrap[data-v-87452cd9] .ui-input{padding-right:30px}.search-clear[data-v-87452cd9]{position:absolute;top:0;bottom:var(--space-1);right:var(--space-2);margin-block:auto;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:var(--radius-full);background:var(--color-hover);color:var(--color-text-faint);cursor:pointer;visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast),background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.search-clear.is-on[data-v-87452cd9]{visibility:visible;opacity:1}.search-clear[data-v-87452cd9]:hover{background:var(--color-selected);color:var(--color-text-muted)}.search-clear[data-v-87452cd9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.chip-strip[data-v-87452cd9]{display:flex;gap:var(--space-1);margin:0 22px;overflow-x:auto;scrollbar-width:none}.chip-strip[data-v-87452cd9]::-webkit-scrollbar{display:none}.chip[data-v-87452cd9]{flex:none;height:28px;padding:0 var(--space-3);border:none;border-radius:var(--radius-full);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base);white-space:nowrap;cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.chip[data-v-87452cd9]:hover{background:var(--color-hover);color:var(--color-text)}.chip.is-active[data-v-87452cd9]{background:var(--color-selected);color:var(--color-text);font-weight:var(--weight-medium)}.chip[data-v-87452cd9]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.model-list[data-v-87452cd9]{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto;padding:var(--space-1) var(--space-2)}.model-row[data-v-87452cd9]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);cursor:pointer;color:var(--color-text);min-width:0;transition:background var(--duration-fast) var(--ease-out)}.model-row[data-v-87452cd9]:hover,.model-row.is-selected[data-v-87452cd9]{background:var(--color-hover)}.model-row.is-current[data-v-87452cd9]{background:var(--color-selected)}.model-main[data-v-87452cd9]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.model-name[data-v-87452cd9]{font-family:var(--font-ui);font-size:var(--text-base);line-height:20px;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.model-row.is-current .model-name[data-v-87452cd9]{font-weight:var(--weight-medium)}.model-meta[data-v-87452cd9]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:18px;color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.model-side[data-v-87452cd9]{display:flex;align-items:center;gap:var(--space-1);flex:none}.model-check[data-v-87452cd9]{color:var(--color-text)}.model-star[data-v-87452cd9]{color:var(--color-text-faint);visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast)}.model-row:hover .model-star[data-v-87452cd9],.model-row.is-selected .model-star[data-v-87452cd9],.model-star.is-starred[data-v-87452cd9],.model-star[data-v-87452cd9]:focus-visible{visibility:visible;opacity:1}.model-star.is-starred[data-v-87452cd9]{color:var(--star)}@media(hover:none){.model-star[data-v-87452cd9]{visibility:visible;opacity:1}}.state-row[data-v-87452cd9]{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:var(--space-2);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.state-row.unavail[data-v-87452cd9]{color:var(--color-warning)}.empty[data-v-87452cd9]{flex:1;display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.footer-hint[data-v-87452cd9]{flex:none;display:flex;align-items:center;gap:var(--space-1);padding:var(--space-2) var(--space-4);border-top:.5px solid var(--color-line);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.hint-dot[data-v-87452cd9]{margin:0 var(--space-1)}@media(hover:none){.footer-hint[data-v-87452cd9]{display:none}}@media(prefers-reduced-motion:reduce){.chip[data-v-87452cd9],.model-row[data-v-87452cd9],.model-star[data-v-87452cd9],.search-clear[data-v-87452cd9]{transition:none}}.brand-logo[data-v-f04205a8]{display:block;flex:none;cursor:pointer;user-select:none;touch-action:manipulation}.nb-cards[data-v-99a1a98a]{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-2) 0 var(--space-4)}.center-body[data-v-99a1a98a]{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);padding:var(--space-8) 0 var(--space-4);text-align:center}.center-text[data-v-99a1a98a]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.success-text[data-v-99a1a98a]{color:var(--color-success)}.err-text[data-v-99a1a98a]{color:var(--color-danger)}.warn-text[data-v-99a1a98a]{color:var(--color-warning);font-size:var(--text-base)}.center-hint[data-v-99a1a98a]{font-size:var(--text-sm);color:var(--color-text-muted)}.nb[data-v-99a1a98a]{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-2) 0 var(--space-4)}.nb-hero[data-v-99a1a98a]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);text-align:center}.nb-hero-icon[data-v-99a1a98a]{display:inline-flex;margin-bottom:var(--space-1)}.nb-hero-title[data-v-99a1a98a]{font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.nb-hero-hint[data-v-99a1a98a]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal);font-variant-numeric:tabular-nums}.nb-manual[data-v-99a1a98a]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2)}.nb-manual-label[data-v-99a1a98a]{font-size:var(--text-xs);color:var(--color-text-faint)}.nb-copy-text[data-v-99a1a98a]{margin-left:var(--space-2)}.nb-copy-text.is-copied[data-v-99a1a98a]{color:var(--color-success);text-decoration:none}.nb-or[data-v-99a1a98a]{display:flex;align-items:center;gap:var(--space-3);color:var(--color-text-muted);font-size:var(--text-xs);letter-spacing:.06em}.nb-or[data-v-99a1a98a]:before,.nb-or[data-v-99a1a98a]:after{content:"";flex:1;height:1px;background:var(--color-line)}.nb-fallback[data-v-99a1a98a]{display:flex;flex-direction:column;gap:var(--space-2)}.nb-fb-text[data-v-99a1a98a]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.nb-fb-link[data-v-99a1a98a]{color:var(--color-accent);text-decoration:none;border-bottom:var(--p-hairline) solid var(--color-accent-bd)}.nb-fb-link[data-v-99a1a98a]:hover{border-bottom-color:var(--color-accent)}.nb-code-row[data-v-99a1a98a]{display:flex;align-items:center;gap:var(--space-3);background:var(--color-surface-sunken);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3)}.nb-code[data-v-99a1a98a]{flex:1;font-family:var(--font-mono);font-size:var(--text-xl);font-weight:var(--weight-medium);color:var(--color-text);letter-spacing:.14em}.nb-copy.is-copied[data-v-99a1a98a]{color:var(--color-success);border-color:var(--color-success-bd)}.actions[data-v-99a1a98a]{display:flex;justify-content:flex-end;gap:var(--space-3);padding-top:var(--space-4)}@media(max-width:640px){.center-body[data-v-99a1a98a],.nb[data-v-99a1a98a]{overflow-y:auto;-webkit-overflow-scrolling:touch}.nb-code-row[data-v-99a1a98a],.actions[data-v-99a1a98a]{flex-wrap:wrap}.nb-code[data-v-99a1a98a]{min-width:0;overflow-wrap:anywhere;letter-spacing:.08em}.nb-copy[data-v-99a1a98a]{min-height:34px}}.pf-form[data-v-3164ed08]{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-4) var(--space-4) var(--space-5);border-top:.5px solid var(--color-line)}.pf-guard[data-v-3164ed08] .ui-banner__text{display:flex;align-items:center;gap:var(--space-2);width:100%}.pf-guard .msg[data-v-3164ed08]{flex:1}.pf-field[data-v-3164ed08]{display:flex;flex-direction:column;gap:6px}.pf-key-wrap[data-v-3164ed08]{position:relative}.pf-key-wrap[data-v-3164ed08] .ui-input{padding-right:calc(var(--icon-button-sm) + var(--space-2))}.pf-key-eye[data-v-3164ed08]{position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%)}.pf-field-label[data-v-3164ed08]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.req[data-v-3164ed08]{color:var(--color-danger)}.pf-models[data-v-3164ed08]{display:flex;flex-direction:column;gap:var(--space-2)}.pf-model-grid[data-v-3164ed08]{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,2fr) auto;gap:var(--space-2);align-items:center}.pf-model-head span[data-v-3164ed08]{font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.pf-models-empty[data-v-3164ed08]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.pf-foot[data-v-3164ed08]{display:flex;align-items:center;gap:var(--space-2);padding-top:var(--space-4);border-top:.5px solid var(--color-line)}.pf-foot .spacer[data-v-3164ed08]{flex:1}.pf-confirm-msg[data-v-3164ed08]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-danger)}.pf-managed-note[data-v-3164ed08]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}@media(max-width:640px){.pf-model-grid[data-v-3164ed08]{grid-template-columns:minmax(0,1fr) auto}}.af[data-v-9777a945]{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4) var(--space-4) var(--space-5);border-top:.5px solid var(--color-line)}.af-guard[data-v-9777a945] .ui-banner__text{display:flex;align-items:center;gap:var(--space-2);width:100%}.af-guard .msg[data-v-9777a945]{flex:1}.af-catalog[data-v-9777a945]{display:flex;flex-direction:column;gap:var(--space-3)}.af-center[data-v-9777a945]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4) 0;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.af-error[data-v-9777a945]{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2)}.af-list[data-v-9777a945]{display:flex;flex-direction:column;max-height:320px;overflow-y:auto;border:.5px solid var(--color-line);border-radius:var(--radius-md)}.af-list[data-v-9777a945]>*+*{border-top:.5px solid var(--color-line)}.af-entry[data-v-9777a945]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:34px;padding:var(--space-1) var(--space-3);border:none;background:transparent;text-align:left;font-family:var(--font-ui);color:var(--color-text);cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.af-entry[data-v-9777a945]:hover:not(:disabled){background:var(--color-hover)}.af-entry[data-v-9777a945]:disabled{cursor:not-allowed;opacity:.55}.af-entry-name[data-v-9777a945]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);font-weight:var(--weight-medium)}.af-entry .grow[data-v-9777a945]{flex:1;min-width:0}.af-entry-count[data-v-9777a945],.af-entry-reason[data-v-9777a945]{flex:none;font-size:var(--text-xs);color:var(--color-text-faint);white-space:nowrap}.af-empty[data-v-9777a945]{padding:var(--space-4);text-align:center;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm)}.af-import[data-v-9777a945],.af-registry[data-v-9777a945]{display:flex;flex-direction:column;gap:var(--space-4)}.af-hint[data-v-9777a945]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.af-back[data-v-9777a945]{display:inline-flex;align-items:center;gap:var(--space-1);align-self:flex-start;padding:0;border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);cursor:pointer;transition:color var(--duration-fast) var(--ease-out)}.af-back[data-v-9777a945]:hover{color:var(--color-text)}.af-field[data-v-9777a945]{display:flex;flex-direction:column;gap:6px}.af-label[data-v-9777a945]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.req[data-v-9777a945]{color:var(--color-danger)}.af-key-wrap[data-v-9777a945]{position:relative}.af-key-wrap[data-v-9777a945] .ui-input{padding-right:calc(var(--icon-button-sm) + var(--space-2))}.af-key-eye[data-v-9777a945]{position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%)}.af-note[data-v-9777a945]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.af-foot[data-v-9777a945]{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding-top:var(--space-4);border-top:.5px solid var(--color-line)}.af-manual[data-v-9777a945] .pf-form{padding:0;border-top:none}.pp[data-v-193300c3]{display:flex;flex-direction:column}.pp-head[data-v-193300c3]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}.pp-title[data-v-193300c3]{margin:0;font-family:var(--font-ui);font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.pp-loading[data-v-193300c3]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4) 0;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.pp-group[data-v-193300c3]{overflow:hidden;border:.5px solid var(--color-line);border-radius:var(--radius-xl);background:var(--color-surface-raised)}.pp-group[data-v-193300c3]>*+*{border-top:.5px solid var(--color-line)}.pp-row[data-v-193300c3]{display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:40px;padding:var(--space-2) var(--space-4);border:none;background:transparent;text-align:left;font-family:var(--font-ui);color:var(--color-text);cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.pp-row[data-v-193300c3]:hover{background:var(--color-hover)}.pp-item.open>.pp-row[data-v-193300c3]{background:var(--color-surface-sunken)}.pp-row .grow[data-v-193300c3]{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-2)}.pp-id[data-v-193300c3]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pp-count[data-v-193300c3]{flex:none;font-size:var(--text-xs);color:var(--color-text-faint);white-space:nowrap}.pp-chev[data-v-193300c3]{display:inline-flex;flex:none;color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.pp-item.open .pp-chev[data-v-193300c3]{transform:rotate(90deg)}.pp-add-row[data-v-193300c3]{gap:var(--space-2);color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.pp-acc[data-v-193300c3]{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--duration-slow) var(--ease-out)}.pp-item.open>.pp-acc[data-v-193300c3]{grid-template-rows:1fr}.pp-acc-in[data-v-193300c3]{overflow:hidden;min-height:0}.pp-item.open .pp-acc-in[data-v-193300c3]{overflow:visible}.pp-item.flash>.pp-row[data-v-193300c3]{animation:pp-flash-193300c3 1.2s var(--ease-out)}@keyframes pp-flash-193300c3{0%{background:var(--color-accent-soft)}to{background:transparent}}.pp-empty[data-v-193300c3]{padding:var(--space-5) var(--space-4);color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);text-align:center}.sec[data-v-5711dff8]{margin-bottom:var(--space-5)}.sec-title[data-v-5711dff8]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);margin:0 0 var(--space-3)}.pu-group[data-v-5711dff8]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.pu-row[data-v-5711dff8]{display:flex;align-items:center;gap:var(--space-3);min-height:52px;padding:var(--space-3) var(--space-4)}.pu-main[data-v-5711dff8]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.pu-label[data-v-5711dff8]{font-size:var(--text-sm);color:var(--color-text)}.pu-hint[data-v-5711dff8]{font-size:var(--text-xs);color:var(--color-text-faint)}.sec[data-v-f39cdded]{margin-bottom:var(--space-5)}.sec-title[data-v-f39cdded]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);margin:0 0 var(--space-3)}.pu-group[data-v-f39cdded]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.pu-row[data-v-f39cdded]{display:flex;align-items:center;gap:var(--space-3);min-height:52px;padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.pu-row[data-v-f39cdded]:first-child{border-top:none}.pu-state[data-v-f39cdded]{color:var(--color-text-muted);font-size:var(--text-sm)}.pu-error-text[data-v-f39cdded]{flex:1;min-width:0}.pu-empty[data-v-f39cdded]{color:var(--color-text-faint)}.pu-main[data-v-f39cdded]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.pu-label[data-v-f39cdded]{font-size:var(--text-sm);color:var(--color-text)}.pu-hint[data-v-f39cdded]{font-size:var(--text-xs);color:var(--color-text-faint)}.pu-value[data-v-f39cdded]{flex:none;font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);font-variant-numeric:tabular-nums;white-space:nowrap}.pu-value-sub[data-v-f39cdded]{font-weight:var(--weight-regular);color:var(--color-text-faint)}.pu-meter[data-v-f39cdded]{flex:none;width:120px;height:5px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden}.pu-meter i[data-v-f39cdded]{display:block;height:100%;border-radius:var(--radius-full);background:var(--color-accent);transition:width var(--duration-base) var(--ease-out)}.pu-meter i.sev-warn[data-v-f39cdded]{background:var(--color-warning)}.pu-meter i.sev-danger[data-v-f39cdded]{background:var(--color-danger)}.sm-picker[data-v-0cf7dc4b]{position:relative;width:100%;font-family:var(--font-ui)}.sm-picker__trigger[data-v-0cf7dc4b]{display:flex;align-items:center;gap:var(--space-2);width:100%;height:38px;padding:0 var(--space-3);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:transparent;box-shadow:none;color:var(--color-text);font:inherit;font-size:var(--text-base);line-height:var(--leading-normal);text-align:left;cursor:pointer;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out)}.sm-picker__trigger[data-v-0cf7dc4b]:focus-visible,.sm-picker.is-open .sm-picker__trigger[data-v-0cf7dc4b]{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.sm-picker__value[data-v-0cf7dc4b]{min-width:0;flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap}.sm-picker__value-text[data-v-0cf7dc4b]{min-width:0;overflow:hidden;text-overflow:ellipsis}.sm-picker__value.is-placeholder[data-v-0cf7dc4b]{color:var(--color-text-faint)}.sm-picker__chevron[data-v-0cf7dc4b]{flex:none;color:var(--color-text-muted);transition:transform var(--duration-base) var(--ease-out)}.sm-picker.is-open .sm-picker__chevron[data-v-0cf7dc4b]{transform:rotate(180deg)}.sm-picker__menu[data-v-0cf7dc4b]{position:fixed;z-index:var(--z-modal-dropdown);width:252px;max-width:calc(100vw - 64px);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.sm-picker__models[data-v-0cf7dc4b]{max-height:280px;overflow-y:auto;padding:var(--space-1);border-radius:var(--radius-md)}.sm-picker__flyout[data-v-0cf7dc4b]{position:absolute;width:180px;max-height:280px;overflow-y:auto;padding:var(--space-1);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.sm-picker__flyout--right[data-v-0cf7dc4b]{left:calc(100% + var(--space-1))}.sm-picker__flyout--left[data-v-0cf7dc4b]{right:calc(100% + var(--space-1))}.sm-picker__group[data-v-0cf7dc4b]{padding:var(--space-2) var(--space-2) var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium)}.sm-picker__option[data-v-0cf7dc4b]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:32px;padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-select-option);background:transparent;color:var(--color-text);font:inherit;font-size:var(--text-sm);text-align:left;cursor:pointer}.sm-picker__option.is-active[data-v-0cf7dc4b]{background:var(--color-hover);color:var(--color-text-strong)}.sm-picker__option.is-muted[data-v-0cf7dc4b]{color:var(--color-text-muted)}.sm-picker__option-label[data-v-0cf7dc4b]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-picker__check[data-v-0cf7dc4b]{flex:none;color:transparent}.sm-picker__option.is-selected .sm-picker__check[data-v-0cf7dc4b]{color:var(--color-accent)}.sm-picker__flyout-caret[data-v-0cf7dc4b]{flex:none;margin-left:auto;color:var(--color-text-faint)}.sd[data-v-955ddf4d]{display:grid;grid-template-columns:148px 1fr;grid-template-areas:"tabs region";min-height:0;height:100%;user-select:none}.sd[data-v-955ddf4d] :is(input,textarea,[contenteditable=true]){user-select:text}.settings-region[data-v-955ddf4d]{display:flex;min-width:0;min-height:0;flex-direction:column;grid-area:region}.settings-region-header[data-v-955ddf4d],.settings-tabs-header[data-v-955ddf4d]{display:flex;align-items:center;height:calc(var(--space-4) + var(--icon-button-sm) + var(--space-2));box-sizing:border-box}.settings-region-header[data-v-955ddf4d]{justify-content:flex-end;padding-right:var(--space-5)}.settings-tabs-header[data-v-955ddf4d]{padding-inline:var(--space-3)}.settings-dialog-title[data-v-955ddf4d]{margin:0;font-family:var(--font-ui);font-size:var(--text-lg);font-weight:var(--weight-medium);line-height:var(--leading-tight);color:var(--color-text)}.settings-tabs[data-v-955ddf4d]{display:flex;flex-direction:column;width:148px;padding:0 var(--space-2) var(--space-2);gap:2px;overflow-y:auto;border-right:.5px solid var(--color-line);grid-area:tabs}.settings-tab-list[data-v-955ddf4d]{display:flex;flex-direction:column;gap:2px}.tab[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-2);text-align:left;padding:8px 10px;border:none;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-ui-strong);cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.tab[data-v-955ddf4d]:hover{background:var(--color-hover);color:var(--color-text-strong)}.tab.on[data-v-955ddf4d]{background:var(--color-hover);color:var(--color-text)}.tab[data-v-955ddf4d]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.body[data-v-955ddf4d]{display:flex;flex-direction:column;overflow-y:auto;padding:var(--space-2) 32px var(--space-5);flex:1;min-width:0}.body[data-v-955ddf4d]::-webkit-scrollbar{width:4px}.body[data-v-955ddf4d]::-webkit-scrollbar-track{background:transparent}.body[data-v-955ddf4d]::-webkit-scrollbar-thumb{background:transparent;border-radius:var(--radius-full);transition:background var(--duration-base) var(--ease-out)}.body.scrolling[data-v-955ddf4d]::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.body.scrolling[data-v-955ddf4d]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.panel[data-v-955ddf4d]{display:block}.sec[data-v-955ddf4d]{padding:var(--space-4) 0}.panel>.sec[data-v-955ddf4d]:first-child{padding-top:0}.sec-head[data-v-955ddf4d]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}.sec-title[data-v-955ddf4d]{margin:0 0 var(--space-3);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);letter-spacing:0;color:var(--color-text)}.notification-settings[data-v-955ddf4d]{user-select:none}.sec-head .sec-title[data-v-955ddf4d]{margin-bottom:0}.row[data-v-955ddf4d]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);min-height:38px;padding:var(--space-1) 0}.settings-group[data-v-955ddf4d]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.settings-group>.row[data-v-955ddf4d]{min-height:52px;padding:var(--space-4);border-top:.5px solid var(--color-line)}.settings-group>.row[data-v-955ddf4d]:first-child{border-top:none}.settings-group>.empty-config[data-v-955ddf4d]{padding:var(--space-3)}.account-row[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4)}.account-avatar[data-v-955ddf4d]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border-radius:50%;background:var(--color-surface-sunken);color:var(--color-text-muted)}.account-avatar img[data-v-955ddf4d]{width:100%;height:100%;border-radius:50%;object-fit:cover}.account-name-row[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-2);min-width:0}.account-level[data-v-955ddf4d]{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}.account-meta[data-v-955ddf4d]{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}.account-name[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.account-sub[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rlabel[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text);font-weight:var(--weight-option-label);display:flex;flex-direction:column;gap:0}.rvalue[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-muted);max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rvalue.mono[data-v-955ddf4d]{font-family:var(--font-mono);font-size:var(--text-xs)}.rvalue-wrap[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-1);max-width:60%;min-width:0}.rvalue-wrap .rvalue[data-v-955ddf4d]{max-width:none}.sd-check[data-v-955ddf4d]{color:var(--color-success)}.hint[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-text-faint)}.body[data-v-955ddf4d] .ui-seg,.body[data-v-955ddf4d] .ui-select__trigger,.body[data-v-955ddf4d] .ui-button,.archive-search[data-v-955ddf4d]{border-width:.5px}.select-wrap[data-v-955ddf4d]{min-width:220px;max-width:min(320px,50vw);flex:none}.empty-config[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-muted);padding:var(--space-1) 0}@media(max-width:640px){.sd[data-v-955ddf4d]{grid-template-columns:1fr;grid-template-rows:auto 1fr;grid-template-areas:"tabs" "region"}.settings-tabs[data-v-955ddf4d]{width:auto;padding:0;overflow-x:visible;border-right:none;border-bottom:.5px solid var(--color-line)}.settings-tabs-header[data-v-955ddf4d]{padding:var(--space-3)}.settings-tab-list[data-v-955ddf4d]{flex-direction:row;gap:var(--space-1);overflow-x:auto;padding:0 var(--space-3) var(--space-2)}.settings-region-header[data-v-955ddf4d]{padding:var(--space-3)}.body[data-v-955ddf4d]{padding-inline:var(--space-3)}.tab[data-v-955ddf4d]{white-space:nowrap;flex:none}.row[data-v-955ddf4d]{align-items:flex-start;flex-direction:column}.settings-group[data-v-955ddf4d]{margin-inline:0}.select-wrap[data-v-955ddf4d]{width:100%;max-width:none}}.setting-card[data-v-955ddf4d]{border-radius:var(--radius-xl);overflow:hidden;background:var(--color-surface)}.panel-head[data-v-955ddf4d]{margin-bottom:var(--space-4)}.panel-title[data-v-955ddf4d]{margin:0 0 var(--space-2);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);letter-spacing:0;color:var(--color-text)}.panel-desc[data-v-955ddf4d]{margin:0;font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-normal);color:var(--color-text-muted);max-width:560px}.archive-toolbar[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-4);flex-wrap:wrap}.archive-search[data-v-955ddf4d]{flex:1;min-width:200px;height:36px;display:flex;align-items:center;gap:var(--space-2);padding:0 var(--space-3);border-radius:var(--radius-md);border:.5px solid var(--color-line);color:var(--color-text-faint);font-size:var(--text-xs);background:var(--color-surface-overlay);transition:border-color var(--duration-fast) var(--ease-out),box-shadow var(--duration-fast) var(--ease-out)}.archive-search[data-v-955ddf4d]:focus-within{border-color:var(--color-accent);box-shadow:var(--p-focus-ring);color:var(--color-text-muted)}.archive-search svg[data-v-955ddf4d]{width:15px;height:15px;flex:none}.archive-search input[data-v-955ddf4d]{width:100%;border:none;outline:none;background:transparent;font:inherit;color:var(--color-text)}.archive-list[data-v-955ddf4d]{display:flex;flex-direction:column;gap:var(--space-4)}.archive-card .setting-card[data-v-955ddf4d]{margin-bottom:0}.archive-workspace[data-v-955ddf4d]{display:flex;align-items:center;gap:var(--space-2);margin:0 2px var(--space-2);color:var(--color-text-muted);font-size:var(--text-xs);font-weight:var(--weight-medium)}.archive-workspace svg[data-v-955ddf4d]{width:16px;height:16px;color:var(--color-text-faint);flex:none}.archive-workspace .path[data-v-955ddf4d]{font-family:var(--font-ui);font-size:var(--text-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archive-workspace .count[data-v-955ddf4d]{margin-left:auto;color:var(--color-text-faint);font-weight:var(--weight-medium);font-size:var(--text-xs);flex:none}.archive-row[data-v-955ddf4d]{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-3);align-items:center;padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.archive-row[data-v-955ddf4d]:first-child{border-top:none}.archive-row[data-v-955ddf4d]:hover{background:var(--color-hover)}.archive-meta[data-v-955ddf4d]{min-width:0}.archive-name[data-v-955ddf4d]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archive-time[data-v-955ddf4d]{margin-top:2px;font-size:var(--text-xs);color:var(--color-text-faint);font-family:var(--font-ui)}.archive-draining[data-v-955ddf4d]{margin-bottom:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);background:var(--color-accent-soft);color:var(--color-accent-hover);font-size:var(--text-xs)}.archive-empty[data-v-955ddf4d]{padding:var(--space-6) var(--space-4);border-radius:var(--radius-xl);color:var(--color-text-faint);font-size:var(--text-xs);text-align:center;background:var(--color-surface)}@media(max-width:640px){.archive-toolbar[data-v-955ddf4d]{flex-direction:column;align-items:stretch}.archive-search[data-v-955ddf4d]{min-width:0}}[data-v-955ddf4d] .ui-dialog{width:min(980px,96vw)}[data-v-955ddf4d] .ui-dialog--fixed-height{height:min(780px,calc(var(--app-height, 100vh) - var(--space-8) * 2))}.aw[data-v-fea98be5]{padding-top:4px}.crumbbar[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) 22px;border-bottom:.5px solid var(--color-line)}.crumbs[data-v-fea98be5]{display:flex;align-items:center;flex-wrap:wrap;gap:1px;min-width:0;font-size:var(--text-sm)}.crumb-sep[data-v-fea98be5]{color:var(--color-text-muted)}.crumb[data-v-fea98be5]{background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-muted);padding:1px var(--space-1);border-radius:var(--radius-xs)}.crumb[data-v-fea98be5]:hover{color:var(--color-text);background:var(--color-hover)}.crumb.last[data-v-fea98be5]{color:var(--color-text);font-weight:var(--weight-medium)}.filterbar[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) 22px;border-bottom:.5px solid var(--color-line)}.filter-icon[data-v-fea98be5]{flex:none;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--color-text-muted)}.filter-input[data-v-fea98be5]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-base);padding:var(--space-1) 0;border:none;background:none;color:var(--color-text);outline:none}.filter-input[data-v-fea98be5]::placeholder{color:var(--color-text-muted)}.search-rel[data-v-fea98be5]{color:var(--color-text)}.folder-list[data-v-fea98be5]{height:300px;overflow-y:auto;padding:var(--space-1) var(--space-2)}.fl-loading[data-v-fea98be5],.fl-empty[data-v-fea98be5]{padding:var(--space-6) var(--space-4);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm)}.folder-row[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);width:100%;background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--text-base);color:var(--color-text);text-align:left;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);transition:background var(--duration-fast) var(--ease-out)}.folder-row[data-v-fea98be5]:hover{background:var(--color-hover)}.dir-icon[data-v-fea98be5]{flex:none;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--color-text-muted)}.folder-name[data-v-fea98be5]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text)}.paste-section[data-v-fea98be5]{padding:var(--space-3) 22px;border-top:.5px solid var(--color-line)}.paste-section.paste-only[data-v-fea98be5]{border-top:none}.paste-row[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2)}.paste-input-wrap[data-v-fea98be5]{flex:1;min-width:0}.add-error[data-v-fea98be5]{margin:0 22px var(--space-2);padding:var(--space-2) var(--space-3);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-danger);background:var(--color-danger-soft);border:.5px solid var(--color-danger-bd);border-radius:var(--radius-sm)}.actions[data-v-fea98be5]{display:flex;justify-content:flex-end;gap:var(--space-2);padding:var(--space-3) 22px}.footer-hint[data-v-fea98be5]{padding:var(--space-2) var(--space-4);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint);border-top:.5px solid var(--color-line)}@media(max-width:640px){.folder-row[data-v-fea98be5]{min-height:44px}.crumbbar[data-v-fea98be5]{align-items:flex-start}.actions[data-v-fea98be5]{flex-wrap:wrap}}.confirm-dialog__message[data-v-aa5422da]{margin:0;font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted)}.rows[data-v-340d1b31]{margin:0;padding:0}.row[data-v-340d1b31]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0;font-size:var(--text-base)}.row dt[data-v-340d1b31]{width:96px;flex:none;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.04em;font-size:var(--text-xs)}.row dd[data-v-340d1b31]{margin:0;color:var(--color-text);font-weight:var(--weight-medium);display:flex;align-items:center;gap:var(--space-2);min-width:0}.row dd.plan-on[data-v-340d1b31],.row dd.swarm-on[data-v-340d1b31]{color:var(--color-accent)}.ctx-text[data-v-340d1b31]{flex:none}.bar[data-v-340d1b31]{width:80px;height:5px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden;flex:none}.bar i[data-v-340d1b31]{display:block;height:100%;background:var(--color-accent)}@media(max-width:640px){.rows[data-v-340d1b31]{overflow-y:auto;-webkit-overflow-scrolling:touch}.row[data-v-340d1b31]{align-items:flex-start;flex-direction:column;gap:var(--space-1);min-height:48px}.row dt[data-v-340d1b31]{width:auto}.row dd[data-v-340d1b31]{max-width:100%;flex-wrap:wrap}}.toasts[data-v-c225aa7a]{position:fixed;right:16px;bottom:84px;display:flex;flex-direction:column;gap:var(--space-2);z-index:var(--z-toast);width:min(440px,calc(100vw - 32px));max-height:56vh;overflow-y:auto}.toasts.below-overlay[data-v-c225aa7a]{z-index:var(--z-dropdown)}.toast-enter-active[data-v-c225aa7a],.toast-leave-active[data-v-c225aa7a]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.toast-enter-from[data-v-c225aa7a],.toast-leave-to[data-v-c225aa7a]{opacity:0;transform:translate(16px)}.toast-move[data-v-c225aa7a]{transition:transform var(--duration-base) var(--ease-out)}.actions[data-v-c225aa7a]{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:var(--space-2)}.link[data-v-c225aa7a]{border:0;padding:0;background:none;color:var(--color-accent);cursor:pointer;font:inherit;font-size:var(--ui-font-size-xs)}.link[data-v-c225aa7a]:hover{text-decoration:underline}.details[data-v-c225aa7a]{display:grid;gap:5px;margin:8px 0 0;padding:8px;border:.5px solid var(--color-line);border-radius:var(--radius-sm);background:var(--color-surface-sunken)}.detail-row[data-v-c225aa7a]{display:grid;grid-template-columns:minmax(88px,.34fr) minmax(0,1fr);gap:8px}.detail-row dt[data-v-c225aa7a]{color:var(--color-text-muted)}.detail-row dd[data-v-c225aa7a]{margin:0;color:var(--color-text);overflow-wrap:anywhere;white-space:pre-wrap}@media(max-width:640px){.toasts[data-v-c225aa7a]{left:12px;right:12px;bottom:calc(var(--dock-h, 76px) + 8px);width:auto;max-height:50vh}.detail-row[data-v-c225aa7a]{grid-template-columns:1fr;gap:2px}}.topbar[data-v-58cf4cd3]{display:flex;align-items:center;height:calc(50px + var(--safe-top));flex:none;padding:var(--safe-top) max(12px,var(--safe-right)) 0 max(12px,var(--safe-left));border-bottom:.5px solid var(--color-line);background:var(--color-topbar-bg-frost);-webkit-backdrop-filter:var(--p-topbar-backdrop);backdrop-filter:var(--p-topbar-backdrop);font-family:var(--font-ui);-webkit-user-select:none;user-select:none}.tb-main[data-v-58cf4cd3]{flex:1;min-width:0;height:100%;display:flex;align-items:center;gap:8px;margin-right:4px;padding:0 6px 0 0;background:none;border:none;border-radius:var(--radius-md);font:inherit;color:inherit;text-align:left;cursor:pointer;-webkit-tap-highlight-color:transparent;transition:opacity var(--duration-fast) var(--ease-out)}.tb-main[data-v-58cf4cd3]:active{opacity:.55}.st[data-v-58cf4cd3]{flex:none;display:inline-flex;align-items:center}.tb-line[data-v-58cf4cd3]{flex:1;min-width:0;display:flex;align-items:baseline;gap:4px;font-size:max(16px,var(--ui-font-size-xl));line-height:1.25;white-space:nowrap}.tb-line .dir[data-v-58cf4cd3]{flex:none;max-width:42%;overflow:hidden;text-overflow:ellipsis;color:var(--color-text-faint)}.tb-line .dir.solo[data-v-58cf4cd3]{max-width:none;min-width:0;color:var(--color-text);font-weight:var(--weight-semibold)}.tb-line .sl[data-v-58cf4cd3]{flex:none;color:var(--color-text-faint)}.tb-line .tt[data-v-58cf4cd3]{min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--color-text);font-weight:var(--weight-semibold)}.tb-line .cv[data-v-58cf4cd3]{flex:none;align-self:center;color:var(--color-text-faint)}.unread-dot[data-v-58cf4cd3]{width:7px;height:7px;border-radius:var(--radius-full);background:var(--color-accent)}.actions[data-v-38e26691]{padding:0 var(--space-2) var(--space-2);border-bottom:.5px solid var(--color-line);margin-bottom:var(--space-1)}.newrow[data-v-38e26691]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:44px;padding:var(--space-2);background:none;border:none;border-radius:var(--radius-md);color:var(--color-text-muted);font-family:var(--sans);font-weight:var(--weight-regular);font-size:var(--ui-font-size);cursor:pointer;text-align:left}.newrow[data-v-38e26691]:hover{background:var(--color-hover)}.newrow[data-v-38e26691]:active{background:var(--color-surface-sunken);color:var(--color-text)}.view-tabs[data-v-38e26691]{padding:var(--space-1) var(--space-2) var(--space-2)}.view-tabs[data-v-38e26691] .ui-seg{display:flex;width:100%}.view-tabs[data-v-38e26691] .ui-seg__item{flex:1;justify-content:center}.mlist[data-v-38e26691]{--m-pad: 16px;--m-gutter: 15px;--m-gap: 8px;--m-indent: calc(var(--m-pad) + var(--m-gutter) + var(--m-gap));padding-bottom:var(--space-1)}.mempty[data-v-38e26691]{padding:var(--space-6) var(--space-4);text-align:center;color:var(--color-text-faint);font-size:var(--ui-font-size)}.mempty.small[data-v-38e26691]{padding:10px 16px 12px var(--m-indent);text-align:left;font-size:var(--ui-font-size-xs)}.mgroup[data-v-38e26691]{padding-top:var(--space-2)}.mgh[data-v-38e26691]{display:flex;align-items:center;gap:var(--m-gap);min-height:44px;margin:0 var(--space-2);padding:0 calc(var(--m-pad) - var(--space-2));border-radius:var(--radius-md);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.mgh[data-v-38e26691]:hover{background:var(--color-hover)}.mgh[data-v-38e26691]:active{background:var(--color-surface-sunken)}.mgh-folder[data-v-38e26691]{flex:none;color:var(--color-text-muted)}.mgh-name[data-v-38e26691]{flex:none;max-width:50%;font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mgh-path[data-v-38e26691]{flex:1;min-width:0;font-size:var(--text-xs);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mgh-more[data-v-38e26691]{margin:0 calc(-1 * var(--space-2))}.mgh-add[data-v-38e26691]{margin:0 calc(-1 * var(--space-2)) 0 0}.mgh-add[data-v-38e26691]:active,.mgh-more[data-v-38e26691]:active{color:var(--color-text);background:var(--color-hover)}.srow[data-v-38e26691]{display:flex;align-items:center;gap:var(--space-2);min-height:44px;margin:1px var(--space-2);padding:0 calc(var(--m-pad) - var(--space-2)) 0 calc(var(--m-indent) - var(--space-2));border-radius:var(--radius-md);cursor:pointer;-webkit-user-select:none;user-select:none;position:relative}.srow[data-v-38e26691]:hover{background:var(--color-hover)}.srow[data-v-38e26691]:active{background:var(--color-surface-sunken)}.srow.cur[data-v-38e26691]{background:var(--color-accent-soft);box-shadow:inset 0 0 0 1px var(--color-accent-bd)}.srow .t[data-v-38e26691]{flex:1;min-width:0;font-size:var(--ui-font-size-sm);font-weight:var(--weight-caption);line-height:var(--leading-tight);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.srow.cur .t[data-v-38e26691]{color:var(--color-accent-hover)}.srow .t.run[data-v-38e26691]{position:relative}.srow .t.run[data-v-38e26691]:before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:var(--radius-full);background:var(--color-accent);animation:mRunPulse-38e26691 1.4s ease-in-out infinite}@keyframes mRunPulse-38e26691{0%,to{opacity:1}50%{opacity:.35}}.srow .t.aborted[data-v-38e26691]{position:relative}.srow .t.aborted[data-v-38e26691]:before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:var(--radius-full);background:var(--color-danger)}.srow .time[data-v-38e26691]{flex:none;font-size:var(--text-xs);font-variant-numeric:tabular-nums;color:var(--color-text-faint)}.att[data-v-38e26691]{flex:none;font-family:var(--font-mono);font-size:max(9px,calc(var(--ui-font-size) - 4px));color:var(--color-text-on-accent);background:var(--color-warning);border-radius:var(--radius-full);padding:1px 7px}.srow .kb[data-v-38e26691]{flex:none;margin:0 calc(-1 * var(--space-2)) 0 0}.srow .kb[data-v-38e26691]:active{color:var(--color-text);background:var(--color-hover)}.srow-flat[data-v-38e26691]{min-height:52px}.srow-main[data-v-38e26691]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.srow-main .t[data-v-38e26691]{flex:none}.srow-sub[data-v-38e26691]{font-size:var(--text-xs);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kmenu[data-v-38e26691]{position:absolute;right:12px;top:44px;z-index:var(--z-dropdown);min-width:96px;overflow:hidden}.wsmenu[data-v-38e26691]{top:calc(100% - 4px);right:var(--m-pad);min-width:132px}.mshow-more-row[data-v-38e26691]{display:flex;align-items:center;padding-left:calc(var(--m-indent) - var(--space-3))}.mshow-more[data-v-38e26691]{display:flex;align-items:center;gap:var(--space-2);min-height:44px;padding:var(--space-1) var(--space-3);background:none;border:none;border-radius:var(--radius-md);color:var(--color-text-muted);font-size:var(--ui-font-size);cursor:pointer;text-align:left}.mshow-more[data-v-38e26691]:active{color:var(--color-accent-hover);background:var(--color-hover)}.mshow-more-sep[data-v-38e26691]{margin:0 var(--space-1);color:var(--color-text-faint);user-select:none}.group-title[data-v-65e9ffc0]{padding:var(--space-4) max(var(--space-4),var(--safe-right)) var(--space-2) max(var(--space-4),var(--safe-left));font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.group-title[data-v-65e9ffc0]:first-child{padding-top:0}.card[data-v-65e9ffc0]{margin:0 max(var(--space-4),var(--safe-right)) 0 max(var(--space-4),var(--safe-left));background:var(--color-surface);border-radius:var(--radius-xl);overflow:hidden}.card>.srow[data-v-65e9ffc0]{border-radius:0}.card>.srow+.srow[data-v-65e9ffc0]{border-top:.5px solid var(--color-line)}.srow[data-v-65e9ffc0]:disabled{opacity:.5;cursor:not-allowed}.srow[data-v-65e9ffc0]{display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:52px;padding:var(--space-3) var(--space-4);background:none;border:none;border-radius:var(--radius-md);cursor:pointer;text-align:left;color:var(--color-text)}.srow[data-v-65e9ffc0]:hover:not(.read-only){background:var(--color-hover)}.srow[data-v-65e9ffc0]:active:not(.read-only){background:var(--color-surface-sunken)}.srow.read-only[data-v-65e9ffc0]{cursor:default}.srow-main[data-v-65e9ffc0]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.srow-label[data-v-65e9ffc0]{font-size:var(--text-base);color:var(--color-text)}.srow-sub[data-v-65e9ffc0]{font-size:var(--text-base);color:var(--color-text-faint);overflow-wrap:anywhere}.srow-val[data-v-65e9ffc0]{flex:none;font-family:var(--font-mono);font-size:var(--ui-font-size);font-weight:500;color:var(--color-accent-hover)}.srow-val.dim[data-v-65e9ffc0]{font-weight:400;color:var(--color-text-muted)}.cache-note[data-v-65e9ffc0]{padding:var(--space-1) max(var(--space-4),var(--safe-right)) 0 max(var(--space-4),var(--safe-left));font-size:var(--text-xs);color:var(--color-text-faint);line-height:1.4}.chev[data-v-65e9ffc0]{flex:none;color:var(--color-text-faint);font-size:17px;line-height:1}.toggle[data-v-65e9ffc0]{flex:none;width:44px;height:26px;border-radius:var(--radius-full);background:var(--color-line);position:relative;transition:background .18s}.toggle.on[data-v-65e9ffc0]{background:var(--color-accent)}.toggle[data-v-65e9ffc0]:after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:var(--radius-full);box-sizing:border-box;background:var(--color-bg);border:.5px solid var(--color-line);box-shadow:var(--shadow-xs);transition:left .18s}.toggle.on[data-v-65e9ffc0]:after{left:21px}.srow.pref[data-v-65e9ffc0]{flex-wrap:wrap;cursor:default}.srow.pref .srow-main[data-v-65e9ffc0]{flex:1 0 100%}.srow.acct.in .srow-label[data-v-65e9ffc0]{color:var(--color-accent-hover);font-weight:500}.srow.acct.out .srow-label[data-v-65e9ffc0]{color:var(--color-danger)}.acct-avatar[data-v-65e9ffc0]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border-radius:50%;background:var(--color-surface-sunken);color:var(--color-text-muted)}.acct-avatar img[data-v-65e9ffc0]{width:100%;height:100%;border-radius:50%;object-fit:cover}.acct-name-row[data-v-65e9ffc0]{display:flex;align-items:center;gap:var(--space-2);min-width:0}.acct-name-row .srow-label[data-v-65e9ffc0]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.acct-level[data-v-65e9ffc0]{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}.usage[data-v-65e9ffc0]{margin:var(--space-4) max(var(--space-4),var(--safe-right)) 0 max(var(--space-4),var(--safe-left))}.usage[data-v-65e9ffc0] .sec{margin-bottom:0}.ctx-meter[data-v-65e9ffc0]{flex:none;width:96px;height:5px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden}.ctx-meter i[data-v-65e9ffc0]{display:block;height:100%;border-radius:var(--radius-full);background:var(--color-accent)}.srow[data-v-65e9ffc0],.srow-sub[data-v-65e9ffc0],.srow-val[data-v-65e9ffc0],.cache-note[data-v-65e9ffc0]{font-family:var(--sans)}.ls-cards[data-v-3875193b]{display:flex;flex-direction:column;gap:var(--space-3)}.ls-card-icon[data-v-3875193b]{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;color:var(--color-text-muted)}.ls-card-text[data-v-3875193b]{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1)}.ls-card-title[data-v-3875193b]{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.ls-card-hint[data-v-3875193b]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.ls-done-card[data-v-3875193b]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);background:var(--color-surface-raised);border:var(--p-hairline) solid var(--color-success-bd);border-radius:var(--radius-lg)}.ls-done-badge[data-v-3875193b]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-full);background:var(--color-success-soft);color:var(--color-success);flex:none}.ls-flow[data-v-3875193b]{display:flex;flex-direction:column;gap:var(--space-4)}.ls-center[data-v-3875193b]{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);padding:var(--space-6) 0 var(--space-2);text-align:center}.ls-center-text[data-v-3875193b]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.ls-success-text[data-v-3875193b]{color:var(--color-success)}.ls-err-text[data-v-3875193b]{color:var(--color-danger)}.ls-warn-text[data-v-3875193b]{color:var(--color-warning)}.ls-center-hint[data-v-3875193b]{font-size:var(--text-sm);color:var(--color-text-muted)}.ls-device[data-v-3875193b]{display:flex;flex-direction:column;gap:var(--space-4)}.ls-hero[data-v-3875193b]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);text-align:center}.ls-hero-icon[data-v-3875193b]{display:inline-flex;margin-bottom:var(--space-1)}.ls-hero-title[data-v-3875193b]{font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.ls-hero-hint[data-v-3875193b]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal);font-variant-numeric:tabular-nums}.ls-manual[data-v-3875193b]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2)}.ls-manual-label[data-v-3875193b]{font-size:var(--text-xs);color:var(--color-text-faint)}.ls-copy-text[data-v-3875193b]{margin-left:var(--space-2)}.ls-copy-text.is-copied[data-v-3875193b]{color:var(--color-success);text-decoration:none}.ls-or[data-v-3875193b]{display:flex;align-items:center;gap:var(--space-3);color:var(--color-text-muted);font-size:var(--text-xs);letter-spacing:.06em}.ls-or[data-v-3875193b]:before,.ls-or[data-v-3875193b]:after{content:"";flex:1;height:1px;background:var(--color-line)}.ls-fb-text[data-v-3875193b]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.ls-fb-link[data-v-3875193b]{color:var(--color-accent);text-decoration:none;border-bottom:var(--p-hairline) solid var(--color-accent-bd)}.ls-fb-link[data-v-3875193b]:hover{border-bottom-color:var(--color-accent)}.ls-code-row[data-v-3875193b]{display:flex;align-items:center;gap:var(--space-3);background:var(--color-surface-sunken);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3)}.ls-code[data-v-3875193b]{flex:1;font-family:var(--font-mono);font-size:var(--text-xl);font-weight:var(--weight-medium);color:var(--color-text);letter-spacing:.14em}.ls-copy.is-copied[data-v-3875193b]{color:var(--color-success);border-color:var(--color-success-bd)}.ls-actions[data-v-3875193b]{display:flex;justify-content:flex-end;gap:var(--space-3)}@media(max-width:640px){.ls-code-row[data-v-3875193b],.ls-actions[data-v-3875193b]{flex-wrap:wrap}.ls-code[data-v-3875193b]{min-width:0;overflow-wrap:anywhere;letter-spacing:.08em}}.wizard[data-v-0535eac0]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;flex-direction:column;background:var(--color-bg);color:var(--color-text);overflow-y:auto;font-family:var(--font-ui)}.wiz-body[data-v-0535eac0]{flex:1;display:flex;flex-direction:column;align-items:center;width:min(560px,100%);margin:0 auto;padding:max(var(--space-8),12vh) var(--space-5) var(--space-6)}.wiz-step[data-v-0535eac0]{display:flex;flex-direction:column;align-items:center;width:100%;flex:1;min-height:0}.wiz-step-fill[data-v-0535eac0]{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;width:100%}.wiz-title[data-v-0535eac0]{margin:var(--space-4) 0 0;font-size:var(--text-2xl);font-weight:var(--weight-semibold);line-height:var(--leading-tight);color:var(--color-text);text-align:center}.wiz-sub[data-v-0535eac0]{margin:var(--space-2) 0 var(--space-6);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted);text-align:center;max-width:460px}.pref-group[data-v-0535eac0]{width:100%;margin-bottom:var(--space-5)}.pref-label[data-v-0535eac0]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);margin-bottom:var(--space-2)}.opt-card[data-v-0535eac0]{display:flex;align-items:center;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);font-family:var(--font-ui);cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.opt-card[data-v-0535eac0]:hover{border-color:var(--color-line-strong)}.opt-card[data-v-0535eac0]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.opt-card.selected[data-v-0535eac0]{border-color:var(--color-accent);background:var(--color-accent-soft)}.opt-label[data-v-0535eac0]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.lang-cards[data-v-0535eac0]{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-3);width:100%}.lang-card[data-v-0535eac0]{gap:var(--space-3);padding:var(--space-4)}.opt-radio[data-v-0535eac0]{width:18px;height:18px;border-radius:var(--radius-full);border:.5px solid var(--color-line-strong);background:var(--color-surface-raised);flex:none;display:inline-flex;align-items:center;justify-content:center;transition:border-color var(--duration-fast) var(--ease-out)}.opt-radio[data-v-0535eac0]:after{content:"";width:8px;height:8px;border-radius:var(--radius-full);background:transparent;transition:background var(--duration-fast) var(--ease-out)}.opt-radio.on[data-v-0535eac0]{border-color:var(--color-accent)}.opt-radio.on[data-v-0535eac0]:after{background:var(--color-accent)}.theme-cards[data-v-0535eac0]{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-3);width:100%}.theme-card[data-v-0535eac0]{flex-direction:column;gap:var(--space-3);padding:var(--space-3)}.tp[data-v-0535eac0]{display:flex;width:100%;aspect-ratio:16 / 10;border:.5px solid var(--color-line);border-radius:var(--radius-md);overflow:hidden}.tp-light[data-v-0535eac0]{background:#fff}.tp-dark[data-v-0535eac0]{background:#0d1117}.tp-half[data-v-0535eac0]{flex:1;display:flex;min-width:0}.tp-half-light[data-v-0535eac0]{background:#fff}.tp-half-dark[data-v-0535eac0]{background:#0d1117}.tp-side[data-v-0535eac0]{width:30%;flex:none}.tp-light .tp-side[data-v-0535eac0],.tp-half-light .tp-side[data-v-0535eac0]{background:#0000000d}.tp-dark .tp-side[data-v-0535eac0],.tp-half-dark .tp-side[data-v-0535eac0]{background:#ffffff12}.tp-lines[data-v-0535eac0]{flex:1;display:flex;flex-direction:column;gap:6px;padding:14% 12%}.tp-lines span[data-v-0535eac0]{height:6px;border-radius:var(--radius-full)}.tp-lines span[data-v-0535eac0]:nth-child(1){width:62%}.tp-lines span[data-v-0535eac0]:nth-child(2){width:88%}.tp-lines span[data-v-0535eac0]:nth-child(3){width:44%}.tp-light .tp-lines span[data-v-0535eac0],.tp-half-light .tp-lines span[data-v-0535eac0]{background:#00000024}.tp-dark .tp-lines span[data-v-0535eac0],.tp-half-dark .tp-lines span[data-v-0535eac0]{background:#ffffff38}.wiz-foot[data-v-0535eac0]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);width:100%;margin-top:auto;padding:var(--space-8) 0 max(var(--space-8),8vh)}.wiz-foot-ghost[data-v-0535eac0]{display:flex;gap:var(--space-3);min-height:32px;align-items:center}.wiz-foot-ghost[data-v-0535eac0] .ui-button--ghost:not(:disabled):hover{background:transparent;color:var(--color-text)}.wiz-primary[data-v-0535eac0]{min-width:140px}@media(max-width:640px){.theme-cards[data-v-0535eac0]{gap:var(--space-2)}}.gload[data-v-ab85ede1]{position:fixed;top:0;left:0;width:100vw;height:100vh;height:100dvh;min-width:100vw;min-height:100dvh;z-index:var(--z-toast);display:flex;align-items:center;justify-content:center;background:var(--bg)}.gload-box[data-v-ab85ede1]{display:flex;flex-direction:column;align-items:center;gap:22px;transform:translateY(-6%)}.gload-logo[data-v-ab85ede1]{width:128px;height:auto;color:var(--color-text);animation:gload-pop-ab85ede1 .55s cubic-bezier(.22,1,.36,1) both}.gload-text[data-v-ab85ede1]{font-family:var(--mono);font-size:var(--text-base);color:var(--muted);letter-spacing:.04em}@keyframes gload-pop-ab85ede1{0%{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@media(prefers-reduced-motion:reduce){.gload-logo[data-v-ab85ede1]{animation:none}}.gload-text[data-v-ab85ede1]{font-family:var(--sans)}.kap-root[data-v-2b13888e]{height:100vh;display:flex;flex-direction:column;background:var(--bg);font-family:var(--mono);font-size:calc(var(--ui-font-size) - 2.5px);color:var(--color-text)}.kap-head[data-v-2b13888e]{flex:none;display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:.5px solid var(--line);background:var(--panel)}.kap-count[data-v-2b13888e]{color:var(--muted)}.kap-head-actions[data-v-2b13888e]{margin-left:auto;display:flex;gap:6px}.kap-head-actions button[data-v-2b13888e],.kap-view-toggle button[data-v-2b13888e]{padding:3px 8px;border:.5px solid var(--line);border-radius:6px;background:var(--bg);color:var(--muted);font:inherit;cursor:pointer}.kap-head-actions button[data-v-2b13888e]:hover,.kap-view-toggle button[data-v-2b13888e]:hover{color:var(--color-text)}.kap-head-actions button.on[data-v-2b13888e],.kap-view-toggle button.on[data-v-2b13888e]{color:var(--color-accent-hover);border-color:var(--color-accent-bd);background:var(--color-accent-soft)}.kap-filters[data-v-2b13888e]{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:7px 10px;border-bottom:.5px solid var(--line)}.kap-filters select[data-v-2b13888e],.kap-filters input[type=text][data-v-2b13888e]{padding:3px 6px;border:.5px solid var(--line);border-radius:6px;background:var(--bg);color:var(--color-text);font:inherit;min-width:0}.kap-filters input[type=text][data-v-2b13888e]{flex:1;min-width:120px}.kap-check[data-v-2b13888e]{display:inline-flex;align-items:center;gap:4px;color:var(--muted);white-space:nowrap}.kap-view-toggle[data-v-2b13888e]{display:flex;gap:0}.kap-view-toggle button[data-v-2b13888e]:first-child{border-radius:6px 0 0 6px;border-right:none}.kap-view-toggle button[data-v-2b13888e]:last-child{border-radius:0 6px 6px 0}.kap-list[data-v-2b13888e]{flex:1;min-height:0;overflow-y:auto}.kap-empty[data-v-2b13888e]{padding:18px 12px;color:var(--muted);text-align:center}.kap-row[data-v-2b13888e]{display:flex;align-items:baseline;gap:7px;width:100%;padding:3px 10px;border:none;border-bottom:.5px solid var(--line);background:transparent;color:var(--color-text);font:inherit;text-align:left;cursor:pointer}.kap-row[data-v-2b13888e]:hover{background:var(--panel2)}.kap-row.expanded[data-v-2b13888e]{background:var(--color-accent-soft)}.kap-ts[data-v-2b13888e]{flex:none;color:var(--muted)}.kap-badge[data-v-2b13888e]{flex:none;padding:0 5px;border-radius:var(--radius-sm);font-size:max(9px,calc(var(--ui-font-size) - 4.5px));font-weight:500;line-height:1.7}.b-rest[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-accent-hover)}.b-in[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-success)}.b-out[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-warning)}.b-life[data-v-2b13888e]{background:var(--panel2);color:var(--muted)}.b-err[data-v-2b13888e]{background:var(--color-warning);color:var(--bg)}.kap-label[data-v-2b13888e]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kap-detail[data-v-2b13888e]{border-bottom:.5px solid var(--line);background:var(--bg);padding:6px 10px 10px}.kap-detail-actions[data-v-2b13888e]{display:flex;justify-content:flex-end;margin-bottom:4px}.kap-detail-actions button[data-v-2b13888e]{padding:2px 8px;border:.5px solid var(--line);border-radius:6px;background:var(--panel);color:var(--muted);font:inherit;cursor:pointer}.kap-detail-actions button[data-v-2b13888e]:hover{color:var(--color-text)}.kap-detail pre[data-v-2b13888e]{margin:0;max-height:320px;overflow:auto;white-space:pre-wrap;word-break:break-word;font-size:calc(var(--ui-font-size) - 3px);line-height:1.45}.kap-agg[data-v-2b13888e]{flex:1;min-height:0;overflow-y:auto;padding:8px 10px}.kap-agg h4[data-v-2b13888e]{margin:8px 0 4px;font-size:calc(var(--ui-font-size) - 2.5px);color:var(--muted)}.kap-agg table[data-v-2b13888e]{width:100%;border-collapse:collapse}.kap-agg th[data-v-2b13888e],.kap-agg td[data-v-2b13888e]{padding:3px 6px;border-bottom:.5px solid var(--line);text-align:left;vertical-align:top}.kap-agg th[data-v-2b13888e]{color:var(--muted);font-weight:500}.kap-agg .num[data-v-2b13888e]{text-align:right}.kap-agg .err[data-v-2b13888e]{color:var(--color-warning);font-weight:500}.kap-agg .mono[data-v-2b13888e]{word-break:break-all}.kap-fab[data-v-21de79fc]{position:fixed;right:10px;bottom:10px;z-index:var(--z-overlay);padding:5px 9px;border:.5px solid var(--line);border-radius:8px;background:var(--panel);color:var(--muted);font-family:var(--mono);font-size:calc(var(--ui-font-size) - 3px);font-weight:500;letter-spacing:.04em;cursor:pointer;opacity:.75}.kap-fab[data-v-21de79fc]:hover{opacity:1;color:var(--color-accent)}.server-auth-hint[data-v-331563ff]{margin:0 0 var(--space-3);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted)}.server-auth-hint code[data-v-331563ff]{padding:1px 5px;font-family:var(--font-mono);font-size:var(--text-xs);background:var(--color-surface-sunken);border-radius:var(--radius-xs)}.internal-build-tag[data-v-14c3d0e0]{flex:none;display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:999px;background:#f5a623;color:#3a2a00;font-size:11px;font-weight:700;letter-spacing:.01em;line-height:1.4;white-space:nowrap;user-select:none}.gload-fade-leave-active[data-v-d59cb496]{transition:opacity .28s ease}.gload-fade-leave-to[data-v-d59cb496]{opacity:0}.action-toast-enter-active[data-v-d59cb496],.action-toast-leave-active[data-v-d59cb496]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.action-toast-leave-active[data-v-d59cb496]{transition-duration:var(--duration-fast);pointer-events:none}.action-toast-enter-from[data-v-d59cb496],.action-toast-leave-to[data-v-d59cb496]{opacity:0;transform:translateY(-6px)}.app-shell[data-v-d59cb496]{position:fixed;top:var(--app-top, 0px);left:0;right:0;height:100vh;height:100dvh;height:var(--app-height, 100dvh);display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box}.app[data-v-d59cb496]{flex:1;min-height:0;position:relative;display:grid;grid-template-columns:auto 0 minmax(0,1fr) 0 auto;background:var(--bg);color:var(--color-text);overflow:hidden;box-sizing:border-box}.app[data-v-d59cb496]>*{min-height:0;min-width:0}.app>.side[data-v-d59cb496]{grid-column:1}.side-handle[data-v-d59cb496]{grid-column:2}.app:not(.mobile)>.con[data-v-d59cb496]{grid-column:3}.preview-handle[data-v-d59cb496]{grid-column:4}.sidebar-toggle-btn[data-v-d59cb496]{position:absolute;top:11px;left:16px;z-index:var(--z-sticky);animation:sidebar-toggle-btn-in-d59cb496 .18s var(--ease-out) .12s backwards;-webkit-app-region:no-drag}.app.macos-desktop .sidebar-toggle-btn[data-v-d59cb496]{left:84px;animation:none}.new-chat-btn[data-v-d59cb496]{position:absolute;top:11px;left:42px;z-index:var(--z-sticky);animation:sidebar-toggle-btn-in-d59cb496 .18s var(--ease-out) .12s backwards;-webkit-app-region:no-drag}.app.macos-desktop .new-chat-btn[data-v-d59cb496]{left:110px}@keyframes sidebar-toggle-btn-in-d59cb496{0%{opacity:0}}.internal-build-fab[data-v-d59cb496]{position:absolute;right:var(--space-3);bottom:var(--space-3);z-index:var(--z-sticky);pointer-events:none}.app.mobile[data-v-d59cb496]{grid-template-columns:1fr;grid-template-rows:auto 1fr}.global-preview[data-v-d59cb496]{--preview-w: 460px;grid-column:5;min-width:0;min-height:0;width:0;background:var(--bg);overflow:hidden}.global-preview.open[data-v-d59cb496]{width:var(--preview-w)}.global-preview[data-v-d59cb496]:not(.mobile)>*{width:var(--preview-w);height:100%;box-sizing:border-box;border-left:.5px solid var(--line)}.global-preview.mobile[data-v-d59cb496]{position:fixed;inset:0;z-index:var(--z-sticky);width:auto;transition:none;border-top:.5px solid var(--color-text)}:root{--panel-head-h: 48px;--panel-head-inset: calc((var(--panel-head-h) - var(--icon-button-sm)) / 2)}.app:not(.mobile) .chat-header{transition:padding-left .28s cubic-bezier(.4,0,.2,1)}.app.sidebar-collapsed .chat-header{padding-left:78px}.app.sidebar-collapsed.macos-desktop .chat-header{padding-left:146px}.app.sidebar-collapsed .session-admin .sa-head{padding-left:78px}.app.sidebar-collapsed.windows-desktop .session-admin .sa-head{padding-left:var(--space-6)}.app.sidebar-collapsed.macos-desktop .session-admin .sa-head{padding-left:146px}.app.fullscreen.sidebar-collapsed.macos-desktop .session-admin .sa-head{padding-left:78px}.app.macos-desktop .global-preview .ui-panel-header{-webkit-app-region:drag}.app.macos-desktop .global-preview .ui-panel-header button,.app.macos-desktop .global-preview .ui-panel-header input{-webkit-app-region:no-drag}.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel,.copy-menu-open) .chat-header,.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel,.copy-menu-open) .side .ch,.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel,.copy-menu-open) .global-preview .ui-panel-header{-webkit-app-region:no-drag}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2) format("woff2-variations");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--dim: rgba(0, 0, 0, .6);--muted: rgba(0, 0, 0, .45);--faint: rgba(0, 0, 0, .3);--line: var(--color-line);--line2: var(--color-subtle);--canvas: #f9fbfc;--sh: 0 1px 3px rgba(28, 40, 66, .05), 0 6px 18px rgba(28, 40, 66, .06);--shc: 0 1px 2px rgba(28, 40, 66, .05);--panel: #f5f5f5;--panel2: rgba(0, 0, 0, .05);--bg: #ffffff;--blue: #1783ff;--blue2: #167ff7;--soft: #e8f3ff;--bd: rgba(23, 131, 255, .25);--logo: #1783ff;--bluebg: #e8f3ff;--blueln: rgba(23, 131, 255, .25);--ok: #0e7a38;--warn: #a9610a;--star: #eab308;--err: #c0392b;--hover: var(--color-hover);--r-xs: var(--radius-sm);--r-sm: var(--radius-md);--r-md: var(--radius-lg);--r-lg: var(--radius-xl);--ui-font-size: var(--ui-b2);--ui-font-size-sm: calc(var(--ui-font-size) - 1px);--ui-font-size-xs: calc(var(--ui-font-size) - 2px);--ui-font-size-lg: calc(var(--ui-font-size) + 1px);--ui-font-size-xl: calc(var(--ui-font-size) + 2px);--content-font-size: var(--md-b1);--code-font-size: calc(var(--content-font-size) - 2px);--mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--sans: var(--font-ui);color-scheme:light dark}html[data-color-scheme=light]{color-scheme:light}html[data-color-scheme=system]{color-scheme:light dark}html[data-color-scheme=dark]{color-scheme:dark;--dim: rgba(255, 255, 255, .56);--muted: rgba(255, 255, 255, .42);--faint: rgba(255, 255, 255, .26);--panel: #1f1f1f;--panel2: #121212;--bg: #121212;--blue: #1a88ff;--blue2: #258eff;--soft: rgba(26, 136, 255, .1);--bd: rgba(26, 136, 255, .28);--logo: #1a88ff;--bluebg: #292929;--blueln: rgba(255, 255, 255, .05);--ok: #3fb950;--warn: #d29922;--star: #facc15;--err: #f85149;--hover: var(--color-hover);--canvas: #161717;--sh: 0 1px 3px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .4);--shc: 0 1px 2px rgba(0, 0, 0, .35)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--dim: rgba(255, 255, 255, .56);--muted: rgba(255, 255, 255, .42);--faint: rgba(255, 255, 255, .26);--panel: #1f1f1f;--panel2: #121212;--bg: #121212;--blue: #1a88ff;--blue2: #258eff;--soft: rgba(26, 136, 255, .1);--bd: rgba(26, 136, 255, .28);--logo: #1a88ff;--bluebg: #292929;--blueln: rgba(255, 255, 255, .05);--ok: #3fb950;--warn: #d29922;--star: #facc15;--err: #f85149;--hover: var(--color-hover);--canvas: #161717;--sh: 0 1px 3px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .4);--shc: 0 1px 2px rgba(0, 0, 0, .35)}}:root{--color-bg: #ffffff;--color-surface: #f5f5f5;--color-surface-raised: #ffffff;--color-surface-overlay: #ffffff;--color-surface-sunken: #f5f5f5;--color-inline-code-bg: rgba(0, 0, 0, .03);--color-well: #f5f5f5;--color-surface-deep: #f5f5f5;--color-media-alpha-bg-1: color-mix(in srgb, var(--color-bg) 52%, var(--color-text) 48%);--color-media-alpha-bg-2: color-mix(in srgb, var(--color-bg) 42%, var(--color-text) 58%);--media-alpha-canvas: conic-gradient( var(--color-media-alpha-bg-1) 25%, var(--color-media-alpha-bg-2) 0 50%, var(--color-media-alpha-bg-1) 0 75%, var(--color-media-alpha-bg-2) 0 ) 0 0 / 16px 16px;--color-text: rgba(0, 0, 0, .9);--color-text-strong: #000000;--color-text-muted: rgba(0, 0, 0, .6);--color-text-faint: rgba(0, 0, 0, .45);--color-text-on-accent: #ffffff;--color-line: rgba(0, 0, 0, .13);--color-subtle: rgba(0, 0, 0, .05);--color-line-strong: rgba(0, 0, 0, .15);--color-scrim: rgba(0, 0, 0, .4);--color-scrim-strong: rgba(0, 0, 0, .6);--color-text-on-scrim: #ffffff;--color-selected: rgba(0, 0, 0, .05);--color-selected-hover: rgba(0, 0, 0, .08);--color-hover: rgba(0, 0, 0, .03);--color-sidebar-bg: #f9fbfc;--color-user-bubble-bg: #f5f5f5;--color-accent: #1783ff;--color-accent-hover: #167ff7;--color-accent-soft: #e8f3ff;--color-accent-bd: rgba(23, 131, 255, .25);--color-success: #0e7a38;--color-success-soft: #e7f6ee;--color-success-bd: #bfe3cc;--color-warning: #a9610a;--color-warning-soft: #fbf1e0;--color-warning-bd: #f0d9b8;--color-danger: #c0392b;--color-danger-soft: #fbeaea;--color-danger-bd: #f0cccc;--color-diff-add-bg: rgba(22, 196, 86, .25);--color-diff-del-bg: rgba(255, 56, 73, .25);--color-done: #8250df;--color-done-soft: #f3e8ff;--color-done-bd: #e0ccff;--color-info: #1783ff;--color-term-magenta: #8250df;--color-term-cyan: #1b7c83;--color-term-black: #24292f;--space-05: 2px;--space-1: 4px;--space-1-5: 6px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--radius-xs: 4px;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 12px;--radius-xl: 16px;--radius-2xl: 20px;--radius-composer: 32px;--corner-shape-composer: superellipse(1.5);--radius-menu-row: var(--radius-sm);--corner-shape-menu: var(--corner-shape-composer);--menu-pad: 3.5px;--radius-menu-item: calc(var(--radius-lg) - var(--menu-pad) - var(--p-hairline));--radius-select-option: calc(var(--radius-md) - var(--space-1) - var(--p-hairline));--radius-dropdown-row: calc(var(--radius-lg) - var(--space-1) - var(--p-hairline));--color-menu-bg-frost: color-mix(in srgb, var(--color-bg) 70%, transparent);--color-topbar-bg-frost: color-mix(in srgb, var(--color-surface) 78%, transparent);--p-topbar-backdrop: saturate(150%) blur(12px);--color-menu-scrollbar: color-mix(in srgb, var(--color-text) 16%, transparent);--color-menu-scrollbar-hover: color-mix(in srgb, var(--color-text) 48%, transparent);--radius-full: 999px;--radius-window: 14px;--radius-window-chip: calc(var(--radius-window) - var(--space-2));--menu-scroll-fade: var(--space-5);--menu-item-padding-block: 5px;--menu-item-padding-inline: 9px;--menu-row-hug: var(--space-1-5);--menu-rows-seam: 1px;--menu-row-gap-icon: 7px;--menu-row-padding-block: var(--space-05);--menu-row-padding-inline: calc(var(--space-4) - var(--space-3) + var(--menu-row-hug));--menu-row-touch-padding-block: 11px;--menu-scrollbar-width: 3px;--menu-scrollbar-edge: calc(var(--menu-row-hug) + var(--p-hairline) - var(--menu-scrollbar-width));--menu-scrollbar-track-inset: calc(var(--radius-lg) - var(--space-1-5));--menu-scrollbar-thumb-min: 24px;--att-chip-pad-left: 5px;--wm-x-size: calc(var(--p-ic-sm) + var(--space-1));--wm-x-ring: var(--space-1-5);--z-base: 0;--z-raised: 1;--z-sticky: 100;--z-dropdown: 200;--z-overlay: 300;--z-modal: 400;--z-modal-dropdown: 500;--z-toast: 600;--z-tooltip: 650;--z-max: 9999;--shadow-xs: 0 1px 2px rgba(16, 24, 40, .04);--shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .06);--shadow-menu: 0 6px 18px lch(0% 0 0 / .02), 0 3px 9px lch(0% 0 0 / .04), 0 1px 1px lch(0% 0 0 / .04);--color-menu-bg: rgba(255, 255, 255, .95);--p-menu-backdrop: blur(24px) saturate(1.8);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(16, 24, 40, .07), 0 2px 4px rgba(16, 24, 40, .05);--shadow-lg: 0 12px 32px rgba(16, 24, 40, .12), 0 4px 10px rgba(16, 24, 40, .08);--shadow-xl: 0 24px 64px rgba(16, 24, 40, .18), 0 8px 20px rgba(16, 24, 40, .1);--ease-out: cubic-bezier(.16, 1, .3, 1);--ease-in-out: cubic-bezier(.4, 0, .2, 1);--duration-fast: .12s;--duration-base: .16s;--duration-slow: .26s;--duration-hover-intent: .25s;--duration-tooltip: .15s;--duration-spin: .7s;--duration-flash: 1.2s;--motion-panel-shift: 2px;--motion-panel-scale: .97;--color-composer-bg: #ffffff;--color-composer-line: rgba(0, 0, 0, .13);--color-composer-focus-line: rgba(0, 0, 0, .25);--color-send-bg: rgba(0, 0, 0, .9);--color-send-bg-hover: #252525;--color-send-icon: #ffffff;--color-stop-glyph: var(--color-danger);--color-send-bg-disabled: rgba(0, 0, 0, .05);--color-send-icon-disabled: rgba(0, 0, 0, .27);--opacity-send-disabled: 1;--shadow-send: 0 7px 16px -13px rgba(0, 0, 0, .38), 0 1px 2px rgba(0, 0, 0, .07);--shadow-send-hover: 0 8px 18px -13px rgba(0, 0, 0, .42), 0 1px 3px rgba(0, 0, 0, .09);--composer-send-icon-size: 28px;--font-ui-latin: "Schibsted Grotesk Variable", "Helvetica Neue", Arial;--font-ui: var(--font-ui-latin), "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-display: var(--font-ui);--font-kbd: "Schibsted Grotesk Variable", system-ui, sans-serif;--font-mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--text-2xs: calc(var(--ui-c1) - 1px);--text-xs: var(--ui-c1);--text-sm: calc(var(--ui-b2) - 1px);--text-base: var(--ui-b2);--text-lg: var(--ui-t2);--text-xl: var(--ui-t1);--text-2xl: var(--ui-t0);--leading-solid: 1;--leading-tight: 1.25;--leading-caption: 1.4;--leading-normal: 1.5;--leading-prose: 1.6;--leading-relaxed: 1.7;--weight-regular: 400;--weight-caption: 450;--weight-option-label: 475;--weight-medium: 500;--weight-ui-strong: 525;--weight-section-label: 600;--weight-semibold: 700;--ui-shift: calc(var(--base-font, 14px) - 14px);--md-shift: var(--ui-shift);--ui-t0: min(calc(20px + var(--ui-shift)), 24px);--ui-t1: min(calc(18px + var(--ui-shift)), 22px);--ui-t2: calc(16px + var(--ui-shift));--ui-b1: calc(15px + var(--ui-shift));--ui-b2: calc(14px + var(--ui-shift));--ui-c1: calc(12px + var(--ui-shift));--ui-c2: calc(10px + var(--ui-shift));--md-h1: calc(22px + var(--md-shift));--md-h2: calc(20px + var(--md-shift));--md-h3: calc(18px + var(--md-shift));--md-b1: calc(14px + var(--md-shift));--md-b2: calc(13px + var(--md-shift));--md-b3: calc(13px + var(--md-shift));--p-focus-ring-w: 3px;--p-focus-ring: 0 0 0 var(--p-focus-ring-w) var(--color-accent-soft);--p-focus-ring-strong: 0 0 0 var(--p-focus-ring-w) var(--color-accent-soft), 0 0 0 1px var(--color-accent);--p-selection: rgba(23, 131, 255, .2);--p-ic-sm: 14px;--p-ic-md: 16px;--p-ring-stroke: 1.5px;--p-ic-lg: 20px;--p-empty-ico: 28px;--p-hairline: .5px;--p-findring-w: 2px;--p-scroll-seam-h: 18px;--p-sidebar-seam-h: 13px;--icon-button-sm: 26px;--touch-target-min: 44px;--p-chip-num: 20px;--p-sidebar-w: 264px;--p-content-max: 760px;--p-content-wide: 920px;--p-table-max: 1040px;--p-table-cell-max: 700px;--p-findbar-w: 340px;--p-bubble-max: 78%;--p-dock-panel-h: 320px;--p-subagent-card-min: 180px;--p-slash-menu-h: 228px;--p-mention-menu-h: 296px;--p-mention-tip-w: 320px;--p-mention-tip-vmargin: var(--space-3);--p-mention-tip-spinner-lift: -.1em;--opacity-stale: .55;--p-add-menu-h: var(--p-slash-menu-h);--p-bp-sm: 640px;--p-bp-md: 980px}:root,html[data-font-scale=medium]{--base-font: 14px}html[data-font-scale=small]{--base-font: 12px}html[data-font-scale=large]{--base-font: 16px}html[data-font-scale=xlarge]{--base-font: 18px}.text-ui-t0{font-size:var(--ui-t0);line-height:round(calc(var(--ui-t0) * 1.4),1px)}.text-ui-t1{font-size:var(--ui-t1);line-height:round(calc(var(--ui-t1) * 1.44),1px)}.text-ui-t2{font-size:var(--ui-t2);line-height:round(calc(var(--ui-t2) * 1.5),1px)}.text-ui-b1{font-size:var(--ui-b1);line-height:round(calc(var(--ui-b1) * 1.47),1px)}.text-ui-b2{font-size:var(--ui-b2);line-height:round(calc(var(--ui-b2) * 1.42),1px)}.text-ui-c1{font-size:var(--ui-c1);line-height:round(calc(var(--ui-c1) * 1.5),1px)}.text-ui-c2{font-size:var(--ui-c2);line-height:round(calc(var(--ui-c2) * 1.4),1px)}.text-md-h1{font-size:var(--md-h1);line-height:round(calc(var(--md-h1) * 1.63),1px)}.text-md-h2{font-size:var(--md-h2);line-height:round(calc(var(--md-h2) * 1.6),1px)}.text-md-h3{font-size:var(--md-h3);line-height:round(calc(var(--md-h3) * 1.56),1px)}.text-md-b1{font-size:var(--md-b1);line-height:round(calc(var(--md-b1) * 1.625),1px)}.text-md-b2{font-size:var(--md-b2);line-height:round(calc(var(--md-b2) * 1.6),1px)}.text-md-b3{font-size:var(--md-b3);line-height:round(calc(var(--md-b3) * 1.57),1px)}html[data-color-scheme=dark]{--color-bg: #121212;--color-surface: #1f1f1f;--color-surface-raised: #292929;--color-surface-overlay: rgba(255, 255, 255, .1);--color-surface-sunken: #121212;--color-inline-code-bg: rgba(255, 255, 255, .1);--color-well: #1f1f1f;--color-surface-deep: #0d0d0d;--color-text: rgba(255, 255, 255, .84);--color-text-strong: #ffffff;--color-text-muted: rgba(255, 255, 255, .56);--color-text-faint: rgba(255, 255, 255, .42);--color-line: rgba(255, 255, 255, .12);--color-subtle: rgba(255, 255, 255, .05);--color-line-strong: rgba(255, 255, 255, .18);--color-scrim: rgba(0, 0, 0, .6);--color-scrim-strong: rgba(0, 0, 0, .75);--color-selected: rgba(255, 255, 255, .1);--color-selected-hover: rgba(255, 255, 255, .14);--color-hover: rgba(255, 255, 255, .05);--color-sidebar-bg: #0d0d0d;--color-user-bubble-bg: #292929;--color-accent: #1a88ff;--color-accent-hover: #258eff;--color-accent-soft: rgba(26, 136, 255, .1);--color-accent-bd: rgba(26, 136, 255, .28);--p-selection: rgba(26, 136, 255, .2);--color-success: #3fb950;--color-success-soft: rgba(63, 185, 80, .14);--color-success-bd: rgba(63, 185, 80, .28);--color-warning: #d29922;--color-warning-soft: rgba(210, 153, 34, .14);--color-warning-bd: rgba(210, 153, 34, .28);--color-danger: #f85149;--color-danger-soft: rgba(248, 81, 73, .14);--color-danger-bd: rgba(248, 81, 73, .28);--color-diff-add-bg: rgba(63, 185, 80, .14);--color-diff-del-bg: rgba(248, 81, 73, .14);--color-done: #a371f7;--color-done-soft: rgba(163, 113, 247, .14);--color-done-bd: rgba(163, 113, 247, .28);--color-info: #1a88ff;--color-term-magenta: #d2a8ff;--color-term-cyan: #76e3ea;--color-term-black: #484f58;--color-composer-bg: #1f1f1f;--color-composer-line: rgba(255, 255, 255, .12);--color-composer-focus-line: rgba(255, 255, 255, .25);--color-send-bg: rgba(255, 255, 255, .84);--color-send-bg-hover: rgba(255, 255, 255, .848);--color-send-icon: #1f1f1f;--color-stop-glyph: color-mix(in srgb, var(--color-danger) 72%, transparent);--color-send-bg-disabled: rgba(255, 255, 255, .1);--color-send-icon-disabled: rgba(255, 255, 255, .28);--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .22), 0 1px 3px rgba(0, 0, 0, .18);--shadow-menu: 0 6px 18px rgba(0, 0, 0, .2), 0 3px 9px rgba(0, 0, 0, .24), 0 1px 1px rgba(0, 0, 0, .24);--color-menu-bg: rgba(41, 41, 41, .95);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3), 0 2px 4px rgba(0, 0, 0, .24);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .34), 0 4px 10px rgba(0, 0, 0, .28);--shadow-xl: 0 24px 64px rgba(0, 0, 0, .42), 0 8px 20px rgba(0, 0, 0, .32)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-bg: #121212;--color-surface: #1f1f1f;--color-surface-raised: #292929;--color-surface-overlay: rgba(255, 255, 255, .1);--color-surface-sunken: #121212;--color-inline-code-bg: rgba(255, 255, 255, .1);--color-well: #1f1f1f;--color-surface-deep: #0d0d0d;--color-text: rgba(255, 255, 255, .84);--color-text-strong: #ffffff;--color-text-muted: rgba(255, 255, 255, .56);--color-text-faint: rgba(255, 255, 255, .42);--color-line: rgba(255, 255, 255, .12);--color-subtle: rgba(255, 255, 255, .05);--color-line-strong: rgba(255, 255, 255, .18);--color-scrim: rgba(0, 0, 0, .6);--color-scrim-strong: rgba(0, 0, 0, .75);--color-selected: rgba(255, 255, 255, .1);--color-selected-hover: rgba(255, 255, 255, .14);--color-hover: rgba(255, 255, 255, .05);--color-sidebar-bg: #0d0d0d;--color-user-bubble-bg: #292929;--color-accent: #1a88ff;--color-accent-hover: #258eff;--color-accent-soft: rgba(26, 136, 255, .1);--color-accent-bd: rgba(26, 136, 255, .28);--p-selection: rgba(26, 136, 255, .2);--color-success: #3fb950;--color-success-soft: rgba(63, 185, 80, .14);--color-success-bd: rgba(63, 185, 80, .28);--color-warning: #d29922;--color-warning-soft: rgba(210, 153, 34, .14);--color-warning-bd: rgba(210, 153, 34, .28);--color-danger: #f85149;--color-danger-soft: rgba(248, 81, 73, .14);--color-danger-bd: rgba(248, 81, 73, .28);--color-diff-add-bg: rgba(63, 185, 80, .14);--color-diff-del-bg: rgba(248, 81, 73, .14);--color-done: #a371f7;--color-done-soft: rgba(163, 113, 247, .14);--color-done-bd: rgba(163, 113, 247, .28);--color-term-magenta: #d2a8ff;--color-term-cyan: #76e3ea;--color-term-black: #484f58;--color-info: #1a88ff;--color-composer-bg: #1f1f1f;--color-composer-line: rgba(255, 255, 255, .12);--color-composer-focus-line: rgba(255, 255, 255, .25);--color-send-bg: rgba(255, 255, 255, .84);--color-send-bg-hover: rgba(255, 255, 255, .848);--color-send-icon: #1f1f1f;--color-stop-glyph: color-mix(in srgb, var(--color-danger) 72%, transparent);--color-send-bg-disabled: rgba(255, 255, 255, .1);--color-send-icon-disabled: rgba(255, 255, 255, .28);--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .22), 0 1px 3px rgba(0, 0, 0, .18);--shadow-menu: 0 6px 18px rgba(0, 0, 0, .2), 0 3px 9px rgba(0, 0, 0, .24), 0 1px 1px rgba(0, 0, 0, .24);--color-menu-bg: rgba(41, 41, 41, .95);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3), 0 2px 4px rgba(0, 0, 0, .24);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .34), 0 4px 10px rgba(0, 0, 0, .28);--shadow-xl: 0 24px 64px rgba(0, 0, 0, .42), 0 8px 20px rgba(0, 0, 0, .32)}}:root{--color-sidebar-tint: rgba(255, 255, 255, .2)}html[data-color-scheme=dark]{--color-sidebar-tint: rgba(0, 0, 0, .12)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-sidebar-tint: rgba(0, 0, 0, .12)}}:root{--color-search-match: #ffe066;--color-search-match-current: #ffc531}html[data-color-scheme=dark]{--color-search-match: rgba(255, 197, 49, .3);--color-search-match-current: rgba(255, 197, 49, .55)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-search-match: rgba(255, 197, 49, .3);--color-search-match-current: rgba(255, 197, 49, .55)}}::highlight(kimi-transcript-search){background-color:var(--color-search-match)}::highlight(kimi-transcript-search-current){background-color:var(--color-search-match-current)}.mention-pill{display:inline-flex;align-items:baseline;gap:var(--space-05);color:var(--color-text-muted);font-weight:var(--weight-ui-strong);white-space:nowrap;text-decoration:none;vertical-align:baseline;padding-inline:var(--space-05);transition:color var(--duration-fast) var(--ease-out)}.mention-pill:hover{color:var(--color-text)}.mention-pill:hover .mention-pill-icon{color:inherit}.mention-pill.mention-file,.mention-pill.mention-skill{cursor:pointer}.mention-pill.mention-file:hover,.mention-pill.mention-skill:hover{text-decoration:underline}.mention-pill:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:var(--radius-sm)}.ProseMirror .mention-pill,.ProseMirror .mention-pill:hover{cursor:text;text-decoration:none}a.mention-folder{cursor:default}.mention-pill.mention-skill.mention-inert,.mention-pill.mention-skill.mention-inert:hover{cursor:default;text-decoration:none}.mention-pill-name{max-width:24em;min-width:0;overflow:hidden;text-overflow:ellipsis}.mention-pill-icon{display:inline-flex;align-items:center;justify-content:center;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--muted);align-self:center;flex-shrink:0}.mention-pill-icon svg{width:var(--p-ic-sm);height:var(--p-ic-sm);display:block;stroke:currentColor;stroke-width:var(--p-hairline)}.mention-pill.pill-in-selection{background:var(--p-selection);border-radius:var(--radius-sm)}.mention-tip{position:fixed;z-index:var(--z-tooltip);max-width:min(var(--p-mention-tip-w),calc(100vw - 2 * var(--p-mention-tip-vmargin)));padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);background:var(--color-text);color:var(--color-bg);font-family:var(--font-ui);font-size:var(--text-xs);line-height:round(calc(var(--text-xs) * 1.5),1px);overflow-wrap:anywhere;opacity:0;transition:opacity var(--duration-fast) var(--ease-out)}.mention-tip:not(.positioned){pointer-events:none}.mention-tip.positioned{opacity:1}.mention-tip-path{display:flex;align-items:flex-start;gap:var(--space-2)}.mention-tip-path-text{min-width:0}.mention-tip-sep{color:color-mix(in srgb,currentColor 45%,transparent)}.mention-tip-base{font-weight:var(--weight-semibold)}.mention-tip-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2)}.mention-tip-name{font-weight:var(--weight-semibold);overflow-wrap:anywhere}.mention-tip-open,.mention-tip-copy{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;padding:var(--space-05);border:none;border-radius:var(--radius-xs);background:transparent;color:color-mix(in srgb,currentColor 65%,transparent);cursor:pointer;transition:color var(--duration-fast) var(--ease-out),background-color var(--duration-fast) var(--ease-out)}.mention-tip-open:hover,.mention-tip-copy:hover{color:var(--color-bg);background:color-mix(in srgb,var(--color-bg) 14%,transparent)}.mention-tip-open:focus-visible,.mention-tip-copy:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.mention-tip-open svg,.mention-tip-copy svg{width:var(--p-ic-sm);height:var(--p-ic-sm);display:block}.mention-tip-copy{margin-top:calc(0px - var(--space-05));margin-right:calc(var(--space-05) - var(--space-2))}.mention-tip-desc{margin-top:var(--space-05);color:color-mix(in srgb,currentColor 78%,transparent);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;overflow:hidden}.mention-tip-spinner{display:inline-block;width:calc(var(--space-2) + var(--space-05));height:calc(var(--space-2) + var(--space-05));margin-left:var(--space-1);vertical-align:var(--p-mention-tip-spinner-lift);border-radius:50%;border:var(--p-ring-stroke) solid color-mix(in srgb,currentColor 30%,transparent);border-top-color:currentColor;animation:mention-tip-spin var(--duration-spin) linear infinite}@keyframes mention-tip-spin{to{transform:rotate(360deg)}}.mention-pill.mention-missing,.mention-pill.mention-missing:hover{color:color-mix(in srgb,var(--color-text-muted) 55%,transparent);text-decoration:line-through}.mention-pill.mention-missing .mention-pill-icon{color:inherit}@font-face{font-family:Noto Sans SC Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/NotoSansSC_wght_-BkPpiACN.woff2) format("woff2-variations")}@font-face{font-family:Schibsted Grotesk Variable;font-style:normal;font-display:swap;font-weight:400 900;src:url(/assets/SchibstedGrotesk_wght_-DIzGrWVg.woff2) format("woff2-variations")}@font-face{font-family:Schibsted Grotesk Variable;font-style:italic;font-display:swap;font-weight:400 900;src:url(/assets/SchibstedGrotesk-Italic_wght_-DjkBGo1z.woff2) format("woff2-variations")}*,*:before,*:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit;margin:0}p,blockquote,dl,dd,figure,pre{margin:0}ol,ul,menu{list-style:none;margin:0;padding:0}a{color:inherit;text-decoration:inherit}b,strong{font-weight:var(--weight-medium)}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}button,input,optgroup,select,textarea{margin:0;padding:0;font-family:inherit;font-size:100%;line-height:inherit;color:inherit}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background:transparent;background-image:none}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block}img,video{max-width:100%;height:auto}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1}table{border-collapse:collapse;border-color:inherit;text-indent:0}hr{height:0;color:inherit;border-top-width:1px}fieldset{margin:0;padding:0}legend{padding:0}dialog{padding:0}summary{display:list-item}[hidden]{display:none}@supports (interpolate-size: allow-keywords){:root{interpolate-size:allow-keywords}}:root{--safe-top: env(safe-area-inset-top, 0px);--safe-right: env(safe-area-inset-right, 0px);--safe-bottom: env(safe-area-inset-bottom, 0px);--safe-left: env(safe-area-inset-left, 0px);--dock-card-top-clearance: 72px;--question-card-body-min-h: 120px}.kw-icon{display:inline-block;flex:none;vertical-align:-.15em}code,pre,kbd,samp,tt{font-feature-settings:"liga" 0,"calt" 0,"ss01" 0;font-variant-ligatures:none}html,body,#app{height:100%;margin:0;background:var(--bg)}#app{position:fixed;inset:0}html,body{overflow:hidden}@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-text) 12%,transparent) transparent}}*::-webkit-scrollbar{width:6px;height:6px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent);border-radius:999px}*::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}*::-webkit-scrollbar-corner{background:transparent}body{font-family:var(--sans);color:var(--color-text);background:var(--bg);font-size:var(--ui-font-size);font-weight:400;line-height:1.6;font-optical-sizing:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:auto;font-synthesis:none;text-size-adjust:100%;-webkit-hyphens:none;hyphens:none}@keyframes kimi-card-in{0%{opacity:0;transform:translateY(8px) scale(.995)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes kimi-check-in{0%{opacity:0;transform:scale(.4)}60%{opacity:1;transform:scale(1.15)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;animation-delay:0ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important}}.ch-eyes{animation:kimi-eye-look 16s ease-in-out infinite}.ch-eye{transform-box:fill-box;transform-origin:center;animation:kimi-eye-blink 11s ease-in-out infinite}@keyframes kimi-eye-look{0%,42%{transform:translate(0)}47%,53%{transform:translate(2px)}58%,80%{transform:translate(0)}84%,90%{transform:translate(-2px)}95%,to{transform:translate(0)}}@keyframes kimi-eye-blink{0%,94%,to{transform:scaleY(1)}96.5%,98%{transform:scaleY(.12)}}@media(prefers-reduced-motion:reduce){.ch-eyes,.ch-eye{animation:none}}.blink-now .ch-eye{animation:kimi-eye-blink-once .24s ease-in-out}@keyframes kimi-eye-blink-once{0%,to{transform:scaleY(1)}50%{transform:scaleY(.1)}}.md .markdown-renderer img{min-width:0;min-height:0}.app{font-size:var(--ui-font-size)}.md,.md .markdown-renderer,.md .markdown-renderer p,.md .markdown-renderer li,.u-bub,.u-bub .u-text,.a-msg .msg,.ph{font-size:var(--content-font-size)}.md .markdown-renderer blockquote,.md .markdown-renderer td,.md .markdown-renderer th{font-size:var(--md-b2)}.md,.u-bub .u-text,.a-msg .msg{text-autospace:normal}.md .code-block-container pre,.md .markstream-pre,.md .code-block-container pre code,.md .diff-pre code,.md .markdown-renderer :not(pre)>code,.md .markdown-renderer .inline-code,.a-msg code{font-size:var(--md-b3)}.md .markdown-renderer :is(h1,h2,h3,h4) :not(pre)>code,.md .markdown-renderer :is(h1,h2,h3,h4) .inline-code{font-size:.9em}.queue-item,.queue-text,.ctx-num,.model-pill,.perm-pill,.mode-pill,.compact-chip,.qcard,.qtext,.qopt,.qbtn,.srow,.srow-val{font-size:var(--ui-font-size)}.qopt-desc,.srow-label{font-size:var(--ui-font-size-sm)}.code-block-header,.code-block-header *,.diff-lang,.queue-label,.qopt-key,.qstep,.srow-sub{font-size:var(--ui-font-size-xs)}@media(max-width:640px){:root{--content-font-size: calc(var(--md-b1) + 2px)}.md .markdown-renderer blockquote,.md .markdown-renderer td,.md .markdown-renderer th{font-size:calc(var(--md-b2) + 2px)}}:root{--anim-rive-spin: .4167s;--anim-leftbar: .5333s;--anim-leftbar-shrink: .2s}#bar-divider{transform-box:view-box;transform-origin:9.3px 12px;transition:transform var(--anim-leftbar-shrink) linear}svg:hover #bar-divider,button:hover #bar-divider{transform:translate(-1.5px) scaleY(.5)}#bar-arrow{transform-box:view-box;transform-origin:0 0;transform:translate(63.95833%,50.625%) scale(0)}svg:hover #bar-arrow,button:hover #bar-arrow{animation:leftbar-arrow var(--anim-leftbar) linear 1 forwards}@keyframes leftbar-arrow{0%{transform:translate(62.97083%,50.625%) scale(-.6);opacity:0}3.125%{transform:translate(62.97083%,50.625%) scale(-.6);opacity:1}15.625%{transform:translate(59.0125%,50.625%) scale(-1);opacity:1}37.5%{transform:translate(52.08333%,50.625%) scale(-1);opacity:1}to{transform:translate(52.08333%,50.625%) scale(-1);opacity:1}}#bar-arrow-expand{transform-box:view-box;transform-origin:0 0;transform:translate(52.08333%,50.625%) scale(0)}svg:hover #bar-arrow-expand,button:hover #bar-arrow-expand{animation:leftbar-arrow-expand var(--anim-leftbar) linear 1 forwards}@keyframes leftbar-arrow-expand{0%{transform:translate(37.02917%,50.625%) scale(.6);opacity:0}3.125%{transform:translate(37.02917%,50.625%) scale(.6);opacity:1}15.625%{transform:translate(40.9875%,50.625%) scale(1);opacity:1}37.5%{transform:translate(52.08333%,50.625%) scale(1);opacity:1}to{transform:translate(52.08333%,50.625%) scale(1);opacity:1}}#p1{transform-box:view-box;transform-origin:0 0}svg:hover #p1,button:hover #p1{animation:nc-plus-spin var(--anim-rive-spin) linear 1 forwards}@keyframes nc-plus-spin{0%{transform:translate(11.5px,11.5px)}8%{transform:translate(11.501px,11.48px) rotate(1.1795deg) scale(1.02022)}12%{transform:translate(11.511px,11.46px) rotate(2.8374deg) scale(1.03026)}20%{transform:translate(11.562px,11.401px) rotate(8.8167deg) scale(1.05041)}24%{transform:translate(11.608px,11.361px) rotate(13.4726deg) scale(1.06017)}32%{transform:translate(11.751px,11.278px) rotate(25.9719deg) scale(1.08008)}48%{transform:translate(12.149px,11.222px) rotate(55.8418deg) scale(1.12025)}52%{transform:translate(12.235px,11.236px) rotate(62.0737deg) scale(1.12953)}60%{transform:translate(12.371px,11.276px) rotate(72.1167deg) scale(1.14954)}68%{transform:translate(12.446px,11.346px) rotate(79.3018deg) scale(1.12048)}76%{transform:translate(12.488px,11.403px) rotate(84.2633deg) scale(1.09046)}88%{transform:translate(12.509px,11.464px) rotate(88.52deg) scale(1.04535)}to{transform:translate(12.5px,11.5px) rotate(90deg)}}#af-p1{transform-box:view-box;transform-origin:18.4px 16.3px}svg:hover #af-p1,button:hover #af-p1{animation:folder-plus-spin var(--anim-rive-spin) linear 1 forwards}@keyframes folder-plus-spin{0%{transform:none}8%{transform:rotate(1.1795deg) scale(1.02022)}12%{transform:rotate(2.8374deg) scale(1.03026)}20%{transform:rotate(8.8167deg) scale(1.05041)}24%{transform:rotate(13.4726deg) scale(1.06017)}32%{transform:rotate(25.9719deg) scale(1.08008)}48%{transform:rotate(55.8418deg) scale(1.12025)}52%{transform:rotate(62.0737deg) scale(1.12953)}60%{transform:rotate(72.1167deg) scale(1.14954)}68%{transform:rotate(79.3018deg) scale(1.12048)}76%{transform:rotate(84.2633deg) scale(1.09046)}88%{transform:rotate(88.52deg) scale(1.04535)}to{transform:rotate(90deg)}} diff --git a/apps/kimi-code/dist-web/assets/index-O6aQX5k9.js b/apps/kimi-code/dist-web/assets/index-BZFTzQ6y.js similarity index 99% rename from apps/kimi-code/dist-web/assets/index-O6aQX5k9.js rename to apps/kimi-code/dist-web/assets/index-BZFTzQ6y.js index e65da2367..2fcf7105a 100644 --- a/apps/kimi-code/dist-web/assets/index-O6aQX5k9.js +++ b/apps/kimi-code/dist-web/assets/index-BZFTzQ6y.js @@ -1,5 +1,5 @@ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/angular-html-DA-rfuFy.js","assets/html-pp8916En.js","assets/javascript-wDzz0qaB.js","assets/css-CLj8gQPS.js","assets/angular-ts-BrjP3tb8.js","assets/scss-D5BDwBP9.js","assets/apl-CORt7UWP.js","assets/xml-sdJ4AIDG.js","assets/java-CylS5w8V.js","assets/json-Cp-IABpG.js","assets/astro-HNnZUWAn.js","assets/typescript-BPQ3VLAy.js","assets/postcss-CXtECtnM.js","assets/tsx-COt5Ahok.js","assets/blade-2xfisSek.js","assets/html-derivative-DlHx6ybY.js","assets/sql-CRqJ_cUM.js","assets/bsl-BO_Y6i37.js","assets/sdbl-DVxCFoDh.js","assets/cairo-KRGpt6FW.js","assets/python-B6aJPvgy.js","assets/cobol-nBiQ_Alo.js","assets/coffee-Ch7k5sss.js","assets/cpp-UfJy6YNI.js","assets/regexp-CDVJQ6XC.js","assets/glsl-DplSGwfg.js","assets/c-BIGW1oBm.js","assets/crystal-DGywbUpC.js","assets/shellscript-Yzrsuije.js","assets/edge-FbVlp4U3.js","assets/elixir-CkH2-t6x.js","assets/elm-DbKCFpqz.js","assets/erb-Dm6A9KJ5.js","assets/ruby-DyJCeAvU.js","assets/haml-D5jkg6IW.js","assets/graphql-ChdNCCLP.js","assets/jsx-g9-lgVsj.js","assets/lua-BaeVxFsk.js","assets/yaml-Buea-lGh.js","assets/erlang-DsQrWhSR.js","assets/markdown-Cvjx9yec.js","assets/fortran-fixed-form-CkoXwp7k.js","assets/fortran-free-form-BxgE0vQu.js","assets/fsharp-CXgrBDvD.js","assets/gdresource-BOOCDP_w.js","assets/gdshader-DkwncUOv.js","assets/gdscript-C5YyOfLZ.js","assets/git-commit-F4YmCXRG.js","assets/diff-D97Zzqfu.js","assets/git-rebase-r7XF79zn.js","assets/glimmer-js-ByusRIyA.js","assets/glimmer-ts-BfAWNZQY.js","assets/hack-DbPARsA_.js","assets/handlebars-BpdQsYii.js","assets/http-jrhK8wxY.js","assets/hurl-irOxFIW8.js","assets/csv-fuZLfV_i.js","assets/hxml-Bvhsp5Yf.js","assets/haxe-CzTSHFRz.js","assets/jinja-f2NsQr07.js","assets/jison-wvAkD_A8.js","assets/julia-D7OTSIA_.js","assets/r-Dspwwk_N.js","assets/just-CUsbIsdP.js","assets/perl-B9cMNwum.js","assets/latex-CaSxy8MP.js","assets/tex-idrVyKtj.js","assets/liquid-C0sCDyMI.js","assets/marko-DjSrsDqO.js","assets/less-B1dDrJ26.js","assets/mdc-DTYItulj.js","assets/nextflow-C-mBbutL.js","assets/nextflow-groovy-vE_lwT2v.js","assets/nginx-BpAMiNFr.js","assets/nim-BIad80T-.js","assets/php-Csjmro_R.js","assets/pug-DKIMFp6K.js","assets/qml-3beO22l8.js","assets/razor-BjBPvh-w.js","assets/csharp-DSvCPggb.js","assets/rst-CpCqk9r5.js","assets/cmake-D1j8_8rp.js","assets/sas-DEy46yEz.js","assets/shaderlab-Dg9Lc6iA.js","assets/hlsl-D3lLCCz7.js","assets/shellsession-BADoaaVG.js","assets/soy-8wufbnw4.js","assets/sparql-rVzFXLq3.js","assets/turtle-BsS91CYL.js","assets/stata-DI20mbqo.js","assets/surrealql-Bq5Q-fJD.js","assets/svelte-Cy7k_4gC.js","assets/templ-DhtptRzy.js","assets/go-C27-OAKa.js","assets/ts-tags-D351s5mN.js","assets/twig-CW1WmMYd.js","assets/vue-D2xRrEX4.js","assets/vue-html-AaS7Mt5G.js","assets/vue-vine-BoDAl6tE.js","assets/stylus-BEDo0Tqx.js","assets/xsl-CtQFsRM5.js"])))=>i.map(i=>d[i]); -import{bR as c}from"./index-D1h84VfZ.js";var Ft=Object.defineProperty,eo=Object.getOwnPropertyDescriptor,to=Object.getOwnPropertyNames,no=Object.prototype.hasOwnProperty,an=(e,t)=>{let n={};for(var r in e)Ft(n,r,{get:e[r],enumerable:!0});return Ft(n,Symbol.toStringTag,{value:"Module"}),n},ro=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(var i=to(t),o=0,s=i.length,a;o<s;o++)a=i[o],!no.call(e,a)&&a!==n&&Ft(e,a,{get:(l=>t[l]).bind(null,a),enumerable:!(r=eo(t,a))||r.enumerable});return e},Sr=(e,t,n)=>(ro(e,t,"default"),n);const Ne=[{id:"abap",name:"ABAP",import:(()=>c(()=>import("./abap-BdImnpbu.js"),[]))},{id:"actionscript-3",name:"ActionScript",import:(()=>c(()=>import("./actionscript-3-CoDkCxhg.js"),[]))},{id:"ada",name:"Ada",import:(()=>c(()=>import("./ada-bCR0ucgS.js"),[]))},{id:"angular-html",name:"Angular HTML",import:(()=>c(()=>import("./angular-html-DA-rfuFy.js").then(e=>e.f),__vite__mapDeps([0,1,2,3])))},{id:"angular-ts",name:"Angular TypeScript",import:(()=>c(()=>import("./angular-ts-BrjP3tb8.js"),__vite__mapDeps([4,0,1,2,3,5])))},{id:"apache",name:"Apache Conf",import:(()=>c(()=>import("./apache-Pmp26Uib.js"),[]))},{id:"apex",name:"Apex",import:(()=>c(()=>import("./apex-Dqspr-GT.js"),[]))},{id:"apl",name:"APL",import:(()=>c(()=>import("./apl-CORt7UWP.js"),__vite__mapDeps([6,1,2,3,7,8,9])))},{id:"applescript",name:"AppleScript",import:(()=>c(()=>import("./applescript-Co6uUVPk.js"),[]))},{id:"ara",name:"Ara",import:(()=>c(()=>import("./ara-BRHolxvo.js"),[]))},{id:"asciidoc",name:"AsciiDoc",aliases:["adoc"],import:(()=>c(()=>import("./asciidoc-Ve4PFQV2.js"),[]))},{id:"asm",name:"Assembly",import:(()=>c(()=>import("./asm-D_Q5rh1f.js"),[]))},{id:"astro",name:"Astro",import:(()=>c(()=>import("./astro-HNnZUWAn.js"),__vite__mapDeps([10,9,2,11,3,12,13])))},{id:"awk",name:"AWK",import:(()=>c(()=>import("./awk-DMzUqQB5.js"),[]))},{id:"ballerina",name:"Ballerina",import:(()=>c(()=>import("./ballerina-BFfxhgS-.js"),[]))},{id:"bat",name:"Batch File",aliases:["batch"],import:(()=>c(()=>import("./bat-BkioyH1T.js"),[]))},{id:"beancount",name:"Beancount",import:(()=>c(()=>import("./beancount-k_qm7-4y.js"),[]))},{id:"berry",name:"Berry",aliases:["be"],import:(()=>c(()=>import("./berry-uYugtg8r.js"),[]))},{id:"bibtex",name:"BibTeX",import:(()=>c(()=>import("./bibtex-CHM0blh-.js"),[]))},{id:"bicep",name:"Bicep",import:(()=>c(()=>import("./bicep-Bmn6On1c.js"),[]))},{id:"bird2",name:"BIRD2 Configuration",aliases:["bird"],import:(()=>c(()=>import("./bird2-BIv1doCn.js"),[]))},{id:"blade",name:"Blade",import:(()=>c(()=>import("./blade-2xfisSek.js"),__vite__mapDeps([14,15,1,2,3,7,8,16,9])))},{id:"bsl",name:"1C (Enterprise)",aliases:["1c"],import:(()=>c(()=>import("./bsl-BO_Y6i37.js"),__vite__mapDeps([17,18])))},{id:"c",name:"C",import:(()=>c(()=>import("./c-BIGW1oBm.js"),[]))},{id:"c3",name:"C3",import:(()=>c(()=>import("./c3-MRO5bC_T.js"),[]))},{id:"cadence",name:"Cadence",aliases:["cdc"],import:(()=>c(()=>import("./cadence-Bv_4Rxtq.js"),[]))},{id:"cairo",name:"Cairo",import:(()=>c(()=>import("./cairo-KRGpt6FW.js"),__vite__mapDeps([19,20])))},{id:"clarity",name:"Clarity",import:(()=>c(()=>import("./clarity-D53aC0YG.js"),[]))},{id:"clojure",name:"Clojure",aliases:["clj"],import:(()=>c(()=>import("./clojure-P80f7IUj.js"),[]))},{id:"cmake",name:"CMake",import:(()=>c(()=>import("./cmake-D1j8_8rp.js"),[]))},{id:"cobol",name:"COBOL",import:(()=>c(()=>import("./cobol-nBiQ_Alo.js"),__vite__mapDeps([21,1,2,3,8])))},{id:"codeowners",name:"CODEOWNERS",import:(()=>c(()=>import("./codeowners-Bp6g37R7.js"),[]))},{id:"codeql",name:"CodeQL",aliases:["ql"],import:(()=>c(()=>import("./codeql-DsOJ9woJ.js"),[]))},{id:"coffee",name:"CoffeeScript",aliases:["coffeescript"],import:(()=>c(()=>import("./coffee-Ch7k5sss.js"),__vite__mapDeps([22,2])))},{id:"common-lisp",name:"Common Lisp",aliases:["lisp"],import:(()=>c(()=>import("./common-lisp-Cg-RD9OK.js"),[]))},{id:"coq",name:"Coq",import:(()=>c(()=>import("./coq-DkFqJrB1.js"),[]))},{id:"cpp",name:"C++",aliases:["c++"],import:(()=>c(()=>import("./cpp-UfJy6YNI.js"),__vite__mapDeps([23,24,25,26,16])))},{id:"crystal",name:"Crystal",import:(()=>c(()=>import("./crystal-DGywbUpC.js"),__vite__mapDeps([27,1,2,3,16,26,28])))},{id:"csharp",name:"C#",aliases:["c#","cs"],import:(()=>c(()=>import("./csharp-DSvCPggb.js"),[]))},{id:"css",name:"CSS",import:(()=>c(()=>import("./css-CLj8gQPS.js"),[]))},{id:"csv",name:"CSV",import:(()=>c(()=>import("./csv-fuZLfV_i.js"),[]))},{id:"cue",name:"CUE",import:(()=>c(()=>import("./cue-D82EKSYY.js"),[]))},{id:"cypher",name:"Cypher",aliases:["cql"],import:(()=>c(()=>import("./cypher-COkxafJQ.js"),[]))},{id:"d",name:"D",import:(()=>c(()=>import("./d-85-TOEBH.js"),[]))},{id:"dart",name:"Dart",import:(()=>c(()=>import("./dart-bE4Kk8sk.js"),[]))},{id:"dax",name:"DAX",import:(()=>c(()=>import("./dax-CEL-wOlO.js"),[]))},{id:"desktop",name:"Desktop",import:(()=>c(()=>import("./desktop-BmXAJ9_W.js"),[]))},{id:"diff",name:"Diff",import:(()=>c(()=>import("./diff-D97Zzqfu.js"),[]))},{id:"docker",name:"Dockerfile",aliases:["dockerfile"],import:(()=>c(()=>import("./docker-BcOcwvcX.js"),[]))},{id:"dotenv",name:"dotEnv",import:(()=>c(()=>import("./dotenv-Da5cRb03.js"),[]))},{id:"dream-maker",name:"Dream Maker",import:(()=>c(()=>import("./dream-maker-BtqSS_iP.js"),[]))},{id:"edge",name:"Edge",import:(()=>c(()=>import("./edge-FbVlp4U3.js"),__vite__mapDeps([29,11,1,2,3,15])))},{id:"elixir",name:"Elixir",import:(()=>c(()=>import("./elixir-CkH2-t6x.js"),__vite__mapDeps([30,1,2,3])))},{id:"elm",name:"Elm",import:(()=>c(()=>import("./elm-DbKCFpqz.js"),__vite__mapDeps([31,25,26])))},{id:"emacs-lisp",name:"Emacs Lisp",aliases:["elisp"],import:(()=>c(()=>import("./emacs-lisp-CXvaQtF9.js"),[]))},{id:"erb",name:"ERB",import:(()=>c(()=>import("./erb-Dm6A9KJ5.js"),__vite__mapDeps([32,1,2,3,33,34,7,8,16,35,11,36,13,23,24,25,26,28,37,38])))},{id:"erlang",name:"Erlang",aliases:["erl"],import:(()=>c(()=>import("./erlang-DsQrWhSR.js"),__vite__mapDeps([39,40])))},{id:"fennel",name:"Fennel",import:(()=>c(()=>import("./fennel-BYunw83y.js"),[]))},{id:"fish",name:"Fish",import:(()=>c(()=>import("./fish-BvzEVeQv.js"),[]))},{id:"fluent",name:"Fluent",aliases:["ftl"],import:(()=>c(()=>import("./fluent-C4IJs8-o.js"),[]))},{id:"fortran-fixed-form",name:"Fortran (Fixed Form)",aliases:["f","for","f77"],import:(()=>c(()=>import("./fortran-fixed-form-CkoXwp7k.js"),__vite__mapDeps([41,42])))},{id:"fortran-free-form",name:"Fortran (Free Form)",aliases:["f90","f95","f03","f08","f18"],import:(()=>c(()=>import("./fortran-free-form-BxgE0vQu.js"),[]))},{id:"fsharp",name:"F#",aliases:["f#","fs"],import:(()=>c(()=>import("./fsharp-CXgrBDvD.js"),__vite__mapDeps([43,40])))},{id:"gdresource",name:"GDResource",aliases:["tscn","tres"],import:(()=>c(()=>import("./gdresource-BOOCDP_w.js"),__vite__mapDeps([44,45,46])))},{id:"gdscript",name:"GDScript",aliases:["gd"],import:(()=>c(()=>import("./gdscript-C5YyOfLZ.js"),[]))},{id:"gdshader",name:"GDShader",import:(()=>c(()=>import("./gdshader-DkwncUOv.js"),[]))},{id:"genie",name:"Genie",import:(()=>c(()=>import("./genie-D0YGMca9.js"),[]))},{id:"gherkin",name:"Gherkin",import:(()=>c(()=>import("./gherkin-DyxjwDmM.js"),[]))},{id:"git-commit",name:"Git Commit Message",import:(()=>c(()=>import("./git-commit-F4YmCXRG.js"),__vite__mapDeps([47,48])))},{id:"git-rebase",name:"Git Rebase Message",import:(()=>c(()=>import("./git-rebase-r7XF79zn.js"),__vite__mapDeps([49,28])))},{id:"gleam",name:"Gleam",import:(()=>c(()=>import("./gleam-BspZqrRM.js"),[]))},{id:"glimmer-js",name:"Glimmer JS",aliases:["gjs"],import:(()=>c(()=>import("./glimmer-js-ByusRIyA.js"),__vite__mapDeps([50,2,11,3,1])))},{id:"glimmer-ts",name:"Glimmer TS",aliases:["gts"],import:(()=>c(()=>import("./glimmer-ts-BfAWNZQY.js"),__vite__mapDeps([51,11,3,2,1])))},{id:"glsl",name:"GLSL",import:(()=>c(()=>import("./glsl-DplSGwfg.js"),__vite__mapDeps([25,26])))},{id:"gn",name:"GN",import:(()=>c(()=>import("./gn-n2N0HUVH.js"),[]))},{id:"gnuplot",name:"Gnuplot",import:(()=>c(()=>import("./gnuplot-DdkO51Og.js"),[]))},{id:"go",name:"Go",import:(()=>c(()=>import("./go-C27-OAKa.js"),[]))},{id:"graphql",name:"GraphQL",aliases:["gql"],import:(()=>c(()=>import("./graphql-ChdNCCLP.js"),__vite__mapDeps([35,2,11,36,13])))},{id:"groovy",name:"Groovy",import:(()=>c(()=>import("./groovy-gcz8RCvz.js"),[]))},{id:"hack",name:"Hack",import:(()=>c(()=>import("./hack-DbPARsA_.js"),__vite__mapDeps([52,1,2,3,16])))},{id:"haml",name:"Ruby Haml",import:(()=>c(()=>import("./haml-D5jkg6IW.js"),__vite__mapDeps([34,2,3])))},{id:"handlebars",name:"Handlebars",aliases:["hbs"],import:(()=>c(()=>import("./handlebars-BpdQsYii.js"),__vite__mapDeps([53,1,2,3,38])))},{id:"haskell",name:"Haskell",aliases:["hs"],import:(()=>c(()=>import("./haskell-Df6bDoY_.js"),[]))},{id:"haxe",name:"Haxe",import:(()=>c(()=>import("./haxe-CzTSHFRz.js"),[]))},{id:"hcl",name:"HashiCorp HCL",import:(()=>c(()=>import("./hcl-BWvSN4gD.js"),[]))},{id:"hjson",name:"Hjson",import:(()=>c(()=>import("./hjson-D5-asLiD.js"),[]))},{id:"hlsl",name:"HLSL",import:(()=>c(()=>import("./hlsl-D3lLCCz7.js"),[]))},{id:"html",name:"HTML",import:(()=>c(()=>import("./html-pp8916En.js"),__vite__mapDeps([1,2,3])))},{id:"html-derivative",name:"HTML (Derivative)",import:(()=>c(()=>import("./html-derivative-DlHx6ybY.js"),__vite__mapDeps([15,1,2,3])))},{id:"http",name:"HTTP",import:(()=>c(()=>import("./http-jrhK8wxY.js"),__vite__mapDeps([54,28,9,7,8,35,2,11,36,13])))},{id:"hurl",name:"Hurl",import:(()=>c(()=>import("./hurl-irOxFIW8.js"),__vite__mapDeps([55,35,2,11,36,13,7,8,56])))},{id:"hxml",name:"HXML",import:(()=>c(()=>import("./hxml-Bvhsp5Yf.js"),__vite__mapDeps([57,58])))},{id:"hy",name:"Hy",import:(()=>c(()=>import("./hy-DFXneXwc.js"),[]))},{id:"imba",name:"Imba",import:(()=>c(()=>import("./imba-DGztddWO.js"),[]))},{id:"ini",name:"INI",aliases:["properties"],import:(()=>c(()=>import("./ini-BEwlwnbL.js"),[]))},{id:"java",name:"Java",import:(()=>c(()=>import("./java-CylS5w8V.js"),[]))},{id:"javascript",name:"JavaScript",aliases:["js","cjs","mjs"],import:(()=>c(()=>import("./javascript-wDzz0qaB.js"),[]))},{id:"jinja",name:"Jinja",import:(()=>c(()=>import("./jinja-f2NsQr07.js"),__vite__mapDeps([59,1,2,3])))},{id:"jison",name:"Jison",import:(()=>c(()=>import("./jison-wvAkD_A8.js"),__vite__mapDeps([60,2])))},{id:"json",name:"JSON",import:(()=>c(()=>import("./json-Cp-IABpG.js"),[]))},{id:"json5",name:"JSON5",import:(()=>c(()=>import("./json5-C9tS-k6U.js"),[]))},{id:"jsonc",name:"JSON with Comments",import:(()=>c(()=>import("./jsonc-Des-eS-w.js"),[]))},{id:"jsonl",name:"JSON Lines",import:(()=>c(()=>import("./jsonl-DcaNXYhu.js"),[]))},{id:"jsonnet",name:"Jsonnet",import:(()=>c(()=>import("./jsonnet-DFQXde-d.js"),[]))},{id:"jssm",name:"JSSM",aliases:["fsl"],import:(()=>c(()=>import("./jssm-C2t-YnRu.js"),[]))},{id:"jsx",name:"JSX",import:(()=>c(()=>import("./jsx-g9-lgVsj.js"),[]))},{id:"julia",name:"Julia",aliases:["jl"],import:(()=>c(()=>import("./julia-D7OTSIA_.js"),__vite__mapDeps([61,23,24,25,26,16,20,2,62])))},{id:"just",name:"Just",import:(()=>c(()=>import("./just-CUsbIsdP.js"),__vite__mapDeps([63,28,2,11,64,1,3,7,8,16,20,33,34,35,36,13,23,24,25,26,37,38])))},{id:"kdl",name:"KDL",import:(()=>c(()=>import("./kdl-DV7GczEv.js"),[]))},{id:"kotlin",name:"Kotlin",aliases:["kt","kts"],import:(()=>c(()=>import("./kotlin-BdnUsdx6.js"),[]))},{id:"kusto",name:"Kusto",aliases:["kql"],import:(()=>c(()=>import("./kusto-wEQ09or8.js"),[]))},{id:"latex",name:"LaTeX",import:(()=>c(()=>import("./latex-CaSxy8MP.js"),__vite__mapDeps([65,66,62])))},{id:"lean",name:"Lean 4",aliases:["lean4"],import:(()=>c(()=>import("./lean-BZvkOJ9d.js"),[]))},{id:"less",name:"Less",import:(()=>c(()=>import("./less-B1dDrJ26.js"),[]))},{id:"liquid",name:"Liquid",import:(()=>c(()=>import("./liquid-C0sCDyMI.js"),__vite__mapDeps([67,1,2,3,9])))},{id:"llvm",name:"LLVM IR",import:(()=>c(()=>import("./llvm-DjAJT7YJ.js"),[]))},{id:"log",name:"Log file",import:(()=>c(()=>import("./log-2UxHyX5q.js"),[]))},{id:"logo",name:"Logo",import:(()=>c(()=>import("./logo-BtOb2qkB.js"),[]))},{id:"lua",name:"Lua",import:(()=>c(()=>import("./lua-BaeVxFsk.js"),__vite__mapDeps([37,26])))},{id:"luau",name:"Luau",import:(()=>c(()=>import("./luau-KW6xsasC.js"),[]))},{id:"make",name:"Makefile",aliases:["makefile"],import:(()=>c(()=>import("./make-CHLpvVh8.js"),[]))},{id:"markdown",name:"Markdown",aliases:["md"],import:(()=>c(()=>import("./markdown-Cvjx9yec.js"),[]))},{id:"marko",name:"Marko",import:(()=>c(()=>import("./marko-DjSrsDqO.js"),__vite__mapDeps([68,3,69,5,11])))},{id:"matlab",name:"MATLAB",import:(()=>c(()=>import("./matlab-D7o27uSR.js"),[]))},{id:"mdc",name:"MDC",import:(()=>c(()=>import("./mdc-DTYItulj.js"),__vite__mapDeps([70,40,38,15,1,2,3])))},{id:"mdx",name:"MDX",import:(()=>c(()=>import("./mdx-Cmh6b_Ma.js"),[]))},{id:"mermaid",name:"Mermaid",aliases:["mmd"],import:(()=>c(()=>import("./mermaid-mWjccvbQ.js"),[]))},{id:"mipsasm",name:"MIPS Assembly",aliases:["mips"],import:(()=>c(()=>import("./mipsasm-CKIfxQSi.js"),[]))},{id:"mojo",name:"Mojo",import:(()=>c(()=>import("./mojo-rZm6bMo-.js"),[]))},{id:"moonbit",name:"MoonBit",aliases:["mbt","mbti"],import:(()=>c(()=>import("./moonbit-_H4v1dQx.js"),[]))},{id:"move",name:"Move",import:(()=>c(()=>import("./move-IF9eRakj.js"),[]))},{id:"narrat",name:"Narrat Language",aliases:["nar"],import:(()=>c(()=>import("./narrat-DRg8JJMk.js"),[]))},{id:"nextflow",name:"Nextflow",aliases:["nf"],import:(()=>c(()=>import("./nextflow-C-mBbutL.js"),__vite__mapDeps([71,72])))},{id:"nextflow-groovy",name:"Nextflow Groovy",import:(()=>c(()=>import("./nextflow-groovy-vE_lwT2v.js"),[]))},{id:"nginx",name:"Nginx",import:(()=>c(()=>import("./nginx-BpAMiNFr.js"),__vite__mapDeps([73,37,26])))},{id:"nim",name:"Nim",import:(()=>c(()=>import("./nim-BIad80T-.js"),__vite__mapDeps([74,26,1,2,3,7,8,25,40])))},{id:"nix",name:"Nix",import:(()=>c(()=>import("./nix-CwoSXNpI.js"),[]))},{id:"nushell",name:"nushell",aliases:["nu"],import:(()=>c(()=>import("./nushell-Cz2AlsmD.js"),[]))},{id:"objective-c",name:"Objective-C",aliases:["objc"],import:(()=>c(()=>import("./objective-c-DXmwc3jG.js"),[]))},{id:"objective-cpp",name:"Objective-C++",import:(()=>c(()=>import("./objective-cpp-CLxacb5B.js"),[]))},{id:"ocaml",name:"OCaml",import:(()=>c(()=>import("./ocaml-C0hk2d4L.js"),[]))},{id:"odin",name:"Odin",import:(()=>c(()=>import("./odin-BBf5iR-q.js"),[]))},{id:"openscad",name:"OpenSCAD",aliases:["scad"],import:(()=>c(()=>import("./openscad-C4EeE6gA.js"),[]))},{id:"pascal",name:"Pascal",import:(()=>c(()=>import("./pascal-D93ZcfNL.js"),[]))},{id:"perl",name:"Perl",import:(()=>c(()=>import("./perl-B9cMNwum.js"),__vite__mapDeps([64,1,2,3,7,8,16])))},{id:"php",name:"PHP",import:(()=>c(()=>import("./php-Csjmro_R.js"),__vite__mapDeps([75,1,2,3,7,8,16,9])))},{id:"pkl",name:"Pkl",import:(()=>c(()=>import("./pkl-u5AG7uiY.js"),[]))},{id:"plsql",name:"PL/SQL",import:(()=>c(()=>import("./plsql-ChMvpjG-.js"),[]))},{id:"po",name:"Gettext PO",aliases:["pot","potx"],import:(()=>c(()=>import("./po-BTJTHyun.js"),[]))},{id:"polar",name:"Polar",import:(()=>c(()=>import("./polar-C0HS_06l.js"),[]))},{id:"postcss",name:"PostCSS",import:(()=>c(()=>import("./postcss-CXtECtnM.js"),[]))},{id:"powerquery",name:"PowerQuery",import:(()=>c(()=>import("./powerquery-CEu0bR-o.js"),[]))},{id:"powershell",name:"PowerShell",aliases:["ps","ps1"],import:(()=>c(()=>import("./powershell-Dpen1YoG.js"),[]))},{id:"prisma",name:"Prisma",import:(()=>c(()=>import("./prisma-Dd19v3D-.js"),[]))},{id:"prolog",name:"Prolog",import:(()=>c(()=>import("./prolog-CbFg5uaA.js"),[]))},{id:"proto",name:"Protocol Buffer 3",aliases:["protobuf"],import:(()=>c(()=>import("./proto-C7zT0LnQ.js"),[]))},{id:"pug",name:"Pug",aliases:["jade"],import:(()=>c(()=>import("./pug-DKIMFp6K.js"),__vite__mapDeps([76,2,3,1])))},{id:"puppet",name:"Puppet",import:(()=>c(()=>import("./puppet-BMWR74SV.js"),[]))},{id:"purescript",name:"PureScript",import:(()=>c(()=>import("./purescript-CklMAg4u.js"),[]))},{id:"python",name:"Python",aliases:["py"],import:(()=>c(()=>import("./python-B6aJPvgy.js"),[]))},{id:"qml",name:"QML",import:(()=>c(()=>import("./qml-3beO22l8.js"),__vite__mapDeps([77,2])))},{id:"qmldir",name:"QML Directory",import:(()=>c(()=>import("./qmldir-C8lEn-DE.js"),[]))},{id:"qss",name:"Qt Style Sheets",import:(()=>c(()=>import("./qss-IeuSbFQv.js"),[]))},{id:"r",name:"R",import:(()=>c(()=>import("./r-Dspwwk_N.js"),[]))},{id:"racket",name:"Racket",import:(()=>c(()=>import("./racket-BqYA7rlc.js"),[]))},{id:"raku",name:"Raku",aliases:["perl6"],import:(()=>c(()=>import("./raku-DXvB9xmW.js"),[]))},{id:"razor",name:"ASP.NET Razor",import:(()=>c(()=>import("./razor-BjBPvh-w.js"),__vite__mapDeps([78,1,2,3,79])))},{id:"reg",name:"Windows Registry Script",import:(()=>c(()=>import("./reg-C-SQnVFl.js"),[]))},{id:"regexp",name:"RegExp",aliases:["regex"],import:(()=>c(()=>import("./regexp-CDVJQ6XC.js"),[]))},{id:"rel",name:"Rel",import:(()=>c(()=>import("./rel-C3B-1QV4.js"),[]))},{id:"riscv",name:"RISC-V",import:(()=>c(()=>import("./riscv-BM1_JUlF.js"),[]))},{id:"ron",name:"RON",import:(()=>c(()=>import("./ron-D8l8udqQ.js"),[]))},{id:"rosmsg",name:"ROS Interface",import:(()=>c(()=>import("./rosmsg-BJDFO7_C.js"),[]))},{id:"rst",name:"reStructuredText",import:(()=>c(()=>import("./rst-CpCqk9r5.js"),__vite__mapDeps([80,15,1,2,3,23,24,25,26,16,20,28,38,81,33,34,7,8,35,11,36,13,37])))},{id:"ruby",name:"Ruby",aliases:["rb"],import:(()=>c(()=>import("./ruby-DyJCeAvU.js"),__vite__mapDeps([33,1,2,3,34,7,8,16,35,11,36,13,23,24,25,26,28,37,38])))},{id:"rust",name:"Rust",aliases:["rs"],import:(()=>c(()=>import("./rust-B1yitclQ.js"),[]))},{id:"sas",name:"SAS",import:(()=>c(()=>import("./sas-DEy46yEz.js"),__vite__mapDeps([82,16])))},{id:"sass",name:"Sass",import:(()=>c(()=>import("./sass-Cj5Yp3dK.js"),[]))},{id:"scala",name:"Scala",import:(()=>c(()=>import("./scala-C151Ov-r.js"),[]))},{id:"scheme",name:"Scheme",import:(()=>c(()=>import("./scheme-C98Dy4si.js"),[]))},{id:"scss",name:"SCSS",import:(()=>c(()=>import("./scss-D5BDwBP9.js"),__vite__mapDeps([5,3])))},{id:"sdbl",name:"1C (Query)",aliases:["1c-query"],import:(()=>c(()=>import("./sdbl-DVxCFoDh.js"),[]))},{id:"shaderlab",name:"ShaderLab",aliases:["shader"],import:(()=>c(()=>import("./shaderlab-Dg9Lc6iA.js"),__vite__mapDeps([83,84])))},{id:"shellscript",name:"Shell",aliases:["bash","sh","shell","zsh"],import:(()=>c(()=>import("./shellscript-Yzrsuije.js"),[]))},{id:"shellsession",name:"Shell Session",aliases:["console"],import:(()=>c(()=>import("./shellsession-BADoaaVG.js"),__vite__mapDeps([85,28])))},{id:"smalltalk",name:"Smalltalk",import:(()=>c(()=>import("./smalltalk-BERRCDM3.js"),[]))},{id:"solidity",name:"Solidity",import:(()=>c(()=>import("./solidity-rGO070M0.js"),[]))},{id:"soy",name:"Closure Templates",aliases:["closure-templates"],import:(()=>c(()=>import("./soy-8wufbnw4.js"),__vite__mapDeps([86,1,2,3])))},{id:"sparql",name:"SPARQL",import:(()=>c(()=>import("./sparql-rVzFXLq3.js"),__vite__mapDeps([87,88])))},{id:"splunk",name:"Splunk Query Language",aliases:["spl"],import:(()=>c(()=>import("./splunk-BtCnVYZw.js"),[]))},{id:"sql",name:"SQL",import:(()=>c(()=>import("./sql-CRqJ_cUM.js"),[]))},{id:"ssh-config",name:"SSH Config",import:(()=>c(()=>import("./ssh-config-_ykCGR6B.js"),[]))},{id:"stata",name:"Stata",import:(()=>c(()=>import("./stata-DI20mbqo.js"),__vite__mapDeps([89,16])))},{id:"stylus",name:"Stylus",aliases:["styl"],import:(()=>c(()=>import("./stylus-BEDo0Tqx.js"),[]))},{id:"surrealql",name:"SurrealQL",aliases:["surql"],import:(()=>c(()=>import("./surrealql-Bq5Q-fJD.js"),__vite__mapDeps([90,2])))},{id:"svelte",name:"Svelte",import:(()=>c(()=>import("./svelte-Cy7k_4gC.js"),__vite__mapDeps([91,2,11,3,12])))},{id:"swift",name:"Swift",import:(()=>c(()=>import("./swift-D82vCrfD.js"),[]))},{id:"system-verilog",name:"SystemVerilog",import:(()=>c(()=>import("./system-verilog-CnnmHF94.js"),[]))},{id:"systemd",name:"Systemd Units",import:(()=>c(()=>import("./systemd-4A_iFExJ.js"),[]))},{id:"talonscript",name:"TalonScript",aliases:["talon"],import:(()=>c(()=>import("./talonscript-CkByrt1z.js"),[]))},{id:"tasl",name:"Tasl",import:(()=>c(()=>import("./tasl-QIJgUcNo.js"),[]))},{id:"tcl",name:"Tcl",import:(()=>c(()=>import("./tcl-dwOrl1Do.js"),[]))},{id:"templ",name:"Templ",import:(()=>c(()=>import("./templ-DhtptRzy.js"),__vite__mapDeps([92,93,2,3])))},{id:"terraform",name:"Terraform",aliases:["tf","tfvars"],import:(()=>c(()=>import("./terraform-BETggiCN.js"),[]))},{id:"tex",name:"TeX",import:(()=>c(()=>import("./tex-idrVyKtj.js"),__vite__mapDeps([66,62])))},{id:"toml",name:"TOML",import:(()=>c(()=>import("./toml-vGWfd6FD.js"),[]))},{id:"ts-tags",name:"TypeScript with Tags",aliases:["lit"],import:(()=>c(()=>import("./ts-tags-D351s5mN.js"),__vite__mapDeps([94,11,3,2,25,26,1,16,7,8])))},{id:"tsv",name:"TSV",import:(()=>c(()=>import("./tsv-B_m7g4N7.js"),[]))},{id:"tsx",name:"TSX",import:(()=>c(()=>import("./tsx-COt5Ahok.js"),[]))},{id:"turtle",name:"Turtle",import:(()=>c(()=>import("./turtle-BsS91CYL.js"),[]))},{id:"twig",name:"Twig",import:(()=>c(()=>import("./twig-CW1WmMYd.js"),__vite__mapDeps([95,3,2,5,75,1,7,8,16,9,20,33,34,35,11,36,13,23,24,25,26,28,37,38])))},{id:"typescript",name:"TypeScript",aliases:["ts","cts","mts"],import:(()=>c(()=>import("./typescript-BPQ3VLAy.js"),[]))},{id:"typespec",name:"TypeSpec",aliases:["tsp"],import:(()=>c(()=>import("./typespec-CAFt9gP4.js"),[]))},{id:"typst",name:"Typst",aliases:["typ"],import:(()=>c(()=>import("./typst-DHCkPAjA.js"),[]))},{id:"v",name:"V",import:(()=>c(()=>import("./v-BcVCzyr7.js"),[]))},{id:"vala",name:"Vala",import:(()=>c(()=>import("./vala-CsfeWuGM.js"),[]))},{id:"vb",name:"Visual Basic",aliases:["cmd"],import:(()=>c(()=>import("./vb-D17OF-Vu.js"),[]))},{id:"verilog",name:"Verilog",import:(()=>c(()=>import("./verilog-BQ8w6xss.js"),[]))},{id:"vhdl",name:"VHDL",import:(()=>c(()=>import("./vhdl-CeAyd5Ju.js"),[]))},{id:"viml",name:"Vim Script",aliases:["vim","vimscript"],import:(()=>c(()=>import("./viml-CJc9bBzg.js"),[]))},{id:"vue",name:"Vue",import:(()=>c(()=>import("./vue-D2xRrEX4.js"),__vite__mapDeps([96,3,2,11,9,1,15])))},{id:"vue-html",name:"Vue HTML",import:(()=>c(()=>import("./vue-html-AaS7Mt5G.js"),__vite__mapDeps([97,2])))},{id:"vue-vine",name:"Vue Vine",import:(()=>c(()=>import("./vue-vine-BoDAl6tE.js"),__vite__mapDeps([98,3,5,69,99,12,2])))},{id:"vyper",name:"Vyper",aliases:["vy"],import:(()=>c(()=>import("./vyper-CDx5xZoG.js"),[]))},{id:"wasm",name:"WebAssembly",import:(()=>c(()=>import("./wasm-MzD3tlZU.js"),[]))},{id:"wenyan",name:"Wenyan",aliases:["文言"],import:(()=>c(()=>import("./wenyan-BV7otONQ.js"),[]))},{id:"wgsl",name:"WGSL",import:(()=>c(()=>import("./wgsl-Dx-B1_4e.js"),[]))},{id:"wikitext",name:"Wikitext",aliases:["mediawiki","wiki"],import:(()=>c(()=>import("./wikitext-BhOHFoWU.js"),[]))},{id:"wit",name:"WebAssembly Interface Types",import:(()=>c(()=>import("./wit-5i3qLPDT.js"),[]))},{id:"wolfram",name:"Wolfram",aliases:["wl"],import:(()=>c(()=>import("./wolfram-lXgVvXCa.js"),[]))},{id:"xml",name:"XML",import:(()=>c(()=>import("./xml-sdJ4AIDG.js"),__vite__mapDeps([7,8])))},{id:"xsl",name:"XSL",import:(()=>c(()=>import("./xsl-CtQFsRM5.js"),__vite__mapDeps([100,7,8])))},{id:"yaml",name:"YAML",aliases:["yml"],import:(()=>c(()=>import("./yaml-Buea-lGh.js"),[]))},{id:"zenscript",name:"ZenScript",import:(()=>c(()=>import("./zenscript-DVFEvuxE.js"),[]))},{id:"zig",name:"Zig",import:(()=>c(()=>import("./zig-VOosw3JB.js"),[]))}],at=Object.fromEntries(Ne.map(e=>[e.id,e.import])),lt=Object.fromEntries(Ne.flatMap(e=>e.aliases?.map(t=>[t,e.import])||[])),ut={...at,...lt},ct=[{id:"andromeeda",displayName:"Andromeeda",type:"dark",import:(()=>c(()=>import("./andromeeda-C4gqWexZ.js"),[]))},{id:"aurora-x",displayName:"Aurora X",type:"dark",import:(()=>c(()=>import("./aurora-x-D-2ljcwZ.js"),[]))},{id:"ayu-dark",displayName:"Ayu Dark",type:"dark",import:(()=>c(()=>import("./ayu-dark-DYE7WIF3.js"),[]))},{id:"ayu-light",displayName:"Ayu Light",type:"light",import:(()=>c(()=>import("./ayu-light-BA47KaF1.js"),[]))},{id:"ayu-mirage",displayName:"Ayu Mirage",type:"dark",import:(()=>c(()=>import("./ayu-mirage-32ctXXKs.js"),[]))},{id:"catppuccin-frappe",displayName:"Catppuccin Frappé",type:"dark",import:(()=>c(()=>import("./catppuccin-frappe-DFWUc33u.js"),[]))},{id:"catppuccin-latte",displayName:"Catppuccin Latte",type:"light",import:(()=>c(()=>import("./catppuccin-latte-C9dUb6Cb.js"),[]))},{id:"catppuccin-macchiato",displayName:"Catppuccin Macchiato",type:"dark",import:(()=>c(()=>import("./catppuccin-macchiato-DQyhUUbL.js"),[]))},{id:"catppuccin-mocha",displayName:"Catppuccin Mocha",type:"dark",import:(()=>c(()=>import("./catppuccin-mocha-D87Tk5Gz.js"),[]))},{id:"dark-plus",displayName:"Dark Plus",type:"dark",import:(()=>c(()=>import("./dark-plus-C3mMm8J8.js"),[]))},{id:"dracula",displayName:"Dracula Theme",type:"dark",import:(()=>c(()=>import("./dracula-BzJJZx-M.js"),[]))},{id:"dracula-soft",displayName:"Dracula Theme Soft",type:"dark",import:(()=>c(()=>import("./dracula-soft-BXkSAIEj.js"),[]))},{id:"everforest-dark",displayName:"Everforest Dark",type:"dark",import:(()=>c(()=>import("./everforest-dark-BgDCqdQA.js"),[]))},{id:"everforest-light",displayName:"Everforest Light",type:"light",import:(()=>c(()=>import("./everforest-light-C8M2exoo.js"),[]))},{id:"github-dark",displayName:"GitHub Dark",type:"dark",import:(()=>c(()=>import("./github-dark-DHJKELXO.js"),[]))},{id:"github-dark-default",displayName:"GitHub Dark Default",type:"dark",import:(()=>c(()=>import("./github-dark-default-Cuk6v7N8.js"),[]))},{id:"github-dark-dimmed",displayName:"GitHub Dark Dimmed",type:"dark",import:(()=>c(()=>import("./github-dark-dimmed-DH5Ifo-i.js"),[]))},{id:"github-dark-high-contrast",displayName:"GitHub Dark High Contrast",type:"dark",import:(()=>c(()=>import("./github-dark-high-contrast-E3gJ1_iC.js"),[]))},{id:"github-light",displayName:"GitHub Light",type:"light",import:(()=>c(()=>import("./github-light-DAi9KRSo.js"),[]))},{id:"github-light-default",displayName:"GitHub Light Default",type:"light",import:(()=>c(()=>import("./github-light-default-D7oLnXFd.js"),[]))},{id:"github-light-high-contrast",displayName:"GitHub Light High Contrast",type:"light",import:(()=>c(()=>import("./github-light-high-contrast-BfjtVDDH.js"),[]))},{id:"gruvbox-dark-hard",displayName:"Gruvbox Dark Hard",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-hard-CFHQjOhq.js"),[]))},{id:"gruvbox-dark-medium",displayName:"Gruvbox Dark Medium",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-medium-GsRaNv29.js"),[]))},{id:"gruvbox-dark-soft",displayName:"Gruvbox Dark Soft",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-soft-CVdnzihN.js"),[]))},{id:"gruvbox-light-hard",displayName:"Gruvbox Light Hard",type:"light",import:(()=>c(()=>import("./gruvbox-light-hard-CH1njM8p.js"),[]))},{id:"gruvbox-light-medium",displayName:"Gruvbox Light Medium",type:"light",import:(()=>c(()=>import("./gruvbox-light-medium-DRw_LuNl.js"),[]))},{id:"gruvbox-light-soft",displayName:"Gruvbox Light Soft",type:"light",import:(()=>c(()=>import("./gruvbox-light-soft-hJgmCMqR.js"),[]))},{id:"horizon",displayName:"Horizon",type:"dark",import:(()=>c(()=>import("./horizon-BUw7H-hv.js"),[]))},{id:"horizon-bright",displayName:"Horizon Bright",type:"light",import:(()=>c(()=>import("./horizon-bright-CUuTKBJd.js"),[]))},{id:"houston",displayName:"Houston",type:"dark",import:(()=>c(()=>import("./houston-DnULxvSX.js"),[]))},{id:"kanagawa-dragon",displayName:"Kanagawa Dragon",type:"dark",import:(()=>c(()=>import("./kanagawa-dragon-CkXjmgJE.js"),[]))},{id:"kanagawa-lotus",displayName:"Kanagawa Lotus",type:"light",import:(()=>c(()=>import("./kanagawa-lotus-CfQXZHmo.js"),[]))},{id:"kanagawa-wave",displayName:"Kanagawa Wave",type:"dark",import:(()=>c(()=>import("./kanagawa-wave-DWedfzmr.js"),[]))},{id:"laserwave",displayName:"LaserWave",type:"dark",import:(()=>c(()=>import("./laserwave-DUszq2jm.js"),[]))},{id:"light-plus",displayName:"Light Plus",type:"light",import:(()=>c(()=>import("./light-plus-B7mTdjB0.js"),[]))},{id:"material-theme",displayName:"Material Theme",type:"dark",import:(()=>c(()=>import("./material-theme-D5KoaKCx.js"),[]))},{id:"material-theme-darker",displayName:"Material Theme Darker",type:"dark",import:(()=>c(()=>import("./material-theme-darker-BfHTSMKl.js"),[]))},{id:"material-theme-lighter",displayName:"Material Theme Lighter",type:"light",import:(()=>c(()=>import("./material-theme-lighter-B0m2ddpp.js"),[]))},{id:"material-theme-ocean",displayName:"Material Theme Ocean",type:"dark",import:(()=>c(()=>import("./material-theme-ocean-CyktbL80.js"),[]))},{id:"material-theme-palenight",displayName:"Material Theme Palenight",type:"dark",import:(()=>c(()=>import("./material-theme-palenight-Csfq5Kiy.js"),[]))},{id:"min-dark",displayName:"Min Dark",type:"dark",import:(()=>c(()=>import("./min-dark-CafNBF8u.js"),[]))},{id:"min-light",displayName:"Min Light",type:"light",import:(()=>c(()=>import("./min-light-CTRr51gU.js"),[]))},{id:"monokai",displayName:"Monokai",type:"dark",import:(()=>c(()=>import("./monokai-D4h5O-jR.js"),[]))},{id:"night-owl",displayName:"Night Owl",type:"dark",import:(()=>c(()=>import("./night-owl-C39BiMTA.js"),[]))},{id:"night-owl-light",displayName:"Night Owl Light",type:"light",import:(()=>c(()=>import("./night-owl-light-CMTm3GFP.js"),[]))},{id:"nord",displayName:"Nord",type:"dark",import:(()=>c(()=>import("./nord-Ddv68eIx.js"),[]))},{id:"one-dark-pro",displayName:"One Dark Pro",type:"dark",import:(()=>c(()=>import("./one-dark-pro-DVMEJ2y_.js"),[]))},{id:"one-light",displayName:"One Light",type:"light",import:(()=>c(()=>import("./one-light-C3Wv6jpd.js"),[]))},{id:"plastic",displayName:"Plastic",type:"dark",import:(()=>c(()=>import("./plastic-3e1v2bzS.js"),[]))},{id:"poimandres",displayName:"Poimandres",type:"dark",import:(()=>c(()=>import("./poimandres-CS3Unz2-.js"),[]))},{id:"red",displayName:"Red",type:"dark",import:(()=>c(()=>import("./red-bN70gL4F.js"),[]))},{id:"rose-pine",displayName:"Rosé Pine",type:"dark",import:(()=>c(()=>import("./rose-pine-qdsjHGoJ.js"),[]))},{id:"rose-pine-dawn",displayName:"Rosé Pine Dawn",type:"light",import:(()=>c(()=>import("./rose-pine-dawn-DHQR4-dF.js"),[]))},{id:"rose-pine-moon",displayName:"Rosé Pine Moon",type:"dark",import:(()=>c(()=>import("./rose-pine-moon-D4_iv3hh.js"),[]))},{id:"slack-dark",displayName:"Slack Dark",type:"dark",import:(()=>c(()=>import("./slack-dark-BthQWCQV.js"),[]))},{id:"slack-ochin",displayName:"Slack Ochin",type:"light",import:(()=>c(()=>import("./slack-ochin-DqwNpetd.js"),[]))},{id:"snazzy-light",displayName:"Snazzy Light",type:"light",import:(()=>c(()=>import("./snazzy-light-Bw305WKR.js"),[]))},{id:"solarized-dark",displayName:"Solarized Dark",type:"dark",import:(()=>c(()=>import("./solarized-dark-DXbdFlpD.js"),[]))},{id:"solarized-light",displayName:"Solarized Light",type:"light",import:(()=>c(()=>import("./solarized-light-L9t79GZl.js"),[]))},{id:"synthwave-84",displayName:"Synthwave '84",type:"dark",import:(()=>c(()=>import("./synthwave-84-CbfX1IO0.js"),[]))},{id:"tokyo-night",displayName:"Tokyo Night",type:"dark",import:(()=>c(()=>import("./tokyo-night-hegEt444.js"),[]))},{id:"vesper",displayName:"Vesper",type:"dark",import:(()=>c(()=>import("./vesper-DRje8inN.js"),[]))},{id:"vitesse-black",displayName:"Vitesse Black",type:"dark",import:(()=>c(()=>import("./vitesse-black-Bkuqu6BP.js"),[]))},{id:"vitesse-dark",displayName:"Vitesse Dark",type:"dark",import:(()=>c(()=>import("./vitesse-dark-D0r3Knsf.js"),[]))},{id:"vitesse-light",displayName:"Vitesse Light",type:"light",import:(()=>c(()=>import("./vitesse-light-CVO1_9PV.js"),[]))}],dt=Object.fromEntries(ct.map(e=>[e.id,e.import]));var ln=class extends Error{constructor(t){super(t),this.name="ShikiError"}};function io(){return 2147483648}function oo(){return typeof performance<"u"?performance.now():Date.now()}const so=(e,t)=>e+(t-e%t)%t;async function ao(e){let t,n;const r={};function i(h){n=h,r.HEAPU8=new Uint8Array(h),r.HEAPU32=new Uint32Array(h)}function o(h,m,E){r.HEAPU8.copyWithin(h,m,m+E)}function s(h){try{return t.grow(h-n.byteLength+65535>>>16),i(t.buffer),1}catch{}}function a(h){const m=r.HEAPU8.length;h=h>>>0;const E=io();if(h>E)return!1;for(let b=1;b<=4;b*=2){let g=m*(1+.2/b);g=Math.min(g,h+100663296);const y=Math.min(E,so(Math.max(h,g),65536));if(s(y))return!0}return!1}const l=typeof TextDecoder<"u"?new TextDecoder("utf8"):void 0;function u(h,m,E=1024){const b=m+E;let g=m;for(;h[g]&&!(g>=b);)++g;if(g-m>16&&h.buffer&&l)return l.decode(h.subarray(m,g));let y="";for(;m<g;){let w=h[m++];if(!(w&128)){y+=String.fromCharCode(w);continue}const A=h[m++]&63;if((w&224)===192){y+=String.fromCharCode((w&31)<<6|A);continue}const k=h[m++]&63;if((w&240)===224?w=(w&15)<<12|A<<6|k:w=(w&7)<<18|A<<12|k<<6|h[m++]&63,w<65536)y+=String.fromCharCode(w);else{const I=w-65536;y+=String.fromCharCode(55296|I>>10,56320|I&1023)}}return y}function p(h,m){return h?u(r.HEAPU8,h,m):""}const d={emscripten_get_now:oo,emscripten_memcpy_big:o,emscripten_resize_heap:a,fd_write:()=>0};async function f(){const m=await e({env:d,wasi_snapshot_preview1:d});t=m.memory,i(t.buffer),Object.assign(r,m),r.UTF8ToString=p}return await f(),r}var lo=Object.defineProperty,uo=(e,t,n)=>t in e?lo(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,P=(e,t,n)=>uo(e,typeof t!="symbol"?t+"":t,n);let D=null;function co(e){throw new ln(e.UTF8ToString(e.getLastOnigError()))}class pt{constructor(t){P(this,"utf16Length"),P(this,"utf8Length"),P(this,"utf16Value"),P(this,"utf8Value"),P(this,"utf16OffsetToUtf8"),P(this,"utf8OffsetToUtf16");const n=t.length,r=pt._utf8ByteLength(t),i=r!==n,o=i?new Uint32Array(n+1):null;i&&(o[n]=r);const s=i?new Uint32Array(r+1):null;i&&(s[r]=n);const a=new Uint8Array(r);let l=0;for(let u=0;u<n;u++){const p=t.charCodeAt(u);let d=p,f=!1;if(p>=55296&&p<=56319&&u+1<n){const h=t.charCodeAt(u+1);h>=56320&&h<=57343&&(d=(p-55296<<10)+65536|h-56320,f=!0)}i&&(o[u]=l,f&&(o[u+1]=l),d<=127?s[l+0]=u:d<=2047?(s[l+0]=u,s[l+1]=u):d<=65535?(s[l+0]=u,s[l+1]=u,s[l+2]=u):(s[l+0]=u,s[l+1]=u,s[l+2]=u,s[l+3]=u)),d<=127?a[l++]=d:d<=2047?(a[l++]=192|(d&1984)>>>6,a[l++]=128|(d&63)>>>0):d<=65535?(a[l++]=224|(d&61440)>>>12,a[l++]=128|(d&4032)>>>6,a[l++]=128|(d&63)>>>0):(a[l++]=240|(d&1835008)>>>18,a[l++]=128|(d&258048)>>>12,a[l++]=128|(d&4032)>>>6,a[l++]=128|(d&63)>>>0),f&&u++}this.utf16Length=n,this.utf8Length=r,this.utf16Value=t,this.utf8Value=a,this.utf16OffsetToUtf8=o,this.utf8OffsetToUtf16=s}static _utf8ByteLength(t){let n=0;for(let r=0,i=t.length;r<i;r++){const o=t.charCodeAt(r);let s=o,a=!1;if(o>=55296&&o<=56319&&r+1<i){const l=t.charCodeAt(r+1);l>=56320&&l<=57343&&(s=(o-55296<<10)+65536|l-56320,a=!0)}s<=127?n+=1:s<=2047?n+=2:s<=65535?n+=3:n+=4,a&&r++}return n}createString(t){const n=t.omalloc(this.utf8Length);return t.HEAPU8.set(this.utf8Value,n),n}}const ht=class X{constructor(t){if(P(this,"id",++X.LAST_ID),P(this,"_onigBinding"),P(this,"content"),P(this,"utf16Length"),P(this,"utf8Length"),P(this,"utf16OffsetToUtf8"),P(this,"utf8OffsetToUtf16"),P(this,"ptr"),!D)throw new ln("Must invoke loadWasm first.");this._onigBinding=D,this.content=t;const n=new pt(t);this.utf16Length=n.utf16Length,this.utf8Length=n.utf8Length,this.utf16OffsetToUtf8=n.utf16OffsetToUtf8,this.utf8OffsetToUtf16=n.utf8OffsetToUtf16,this.utf8Length<1e4&&!X._sharedPtrInUse?(X._sharedPtr||(X._sharedPtr=D.omalloc(1e4)),X._sharedPtrInUse=!0,D.HEAPU8.set(n.utf8Value,X._sharedPtr),this.ptr=X._sharedPtr):this.ptr=n.createString(D)}convertUtf8OffsetToUtf16(t){return this.utf8OffsetToUtf16?t<0?0:t>this.utf8Length?this.utf16Length:this.utf8OffsetToUtf16[t]:t}convertUtf16OffsetToUtf8(t){return this.utf16OffsetToUtf8?t<0?0:t>this.utf16Length?this.utf8Length:this.utf16OffsetToUtf8[t]:t}dispose(){this.ptr===X._sharedPtr?X._sharedPtrInUse=!1:this._onigBinding.ofree(this.ptr)}};P(ht,"LAST_ID",0);P(ht,"_sharedPtr",0);P(ht,"_sharedPtrInUse",!1);let Lr=ht;class po{constructor(t){if(P(this,"_onigBinding"),P(this,"_ptr"),!D)throw new ln("Must invoke loadWasm first.");const n=[],r=[];for(let a=0,l=t.length;a<l;a++){const u=new pt(t[a]);n[a]=u.createString(D),r[a]=u.utf8Length}const i=D.omalloc(4*t.length);D.HEAPU32.set(n,i/4);const o=D.omalloc(4*t.length);D.HEAPU32.set(r,o/4);const s=D.createOnigScanner(i,o,t.length);for(let a=0,l=t.length;a<l;a++)D.ofree(n[a]);D.ofree(o),D.ofree(i),s===0&&co(D),this._onigBinding=D,this._ptr=s}dispose(){this._onigBinding.freeOnigScanner(this._ptr)}findNextMatchSync(t,n,r){let i=0;if(typeof r=="number"&&(i=r),typeof t=="string"){t=new Lr(t);const o=this._findNextMatchSync(t,n,!1,i);return t.dispose(),o}return this._findNextMatchSync(t,n,!1,i)}_findNextMatchSync(t,n,r,i){const o=this._onigBinding,s=o.findNextOnigScannerMatch(this._ptr,t.id,t.ptr,t.utf8Length,t.convertUtf16OffsetToUtf8(n),i);if(s===0)return null;const a=o.HEAPU32;let l=s/4;const u=a[l++],p=a[l++],d=[];for(let f=0;f<p;f++){const h=t.convertUtf8OffsetToUtf16(a[l++]),m=t.convertUtf8OffsetToUtf16(a[l++]);d[f]={start:h,end:m,length:m-h}}return{index:u,captureIndices:d}}}function ho(e){return typeof e.instantiator=="function"}function fo(e){return typeof e.default=="function"}function mo(e){return typeof e.data<"u"}function go(e){return typeof Response<"u"&&e instanceof Response}function _o(e){return typeof ArrayBuffer<"u"&&(e instanceof ArrayBuffer||ArrayBuffer.isView(e))||typeof Buffer<"u"&&Buffer.isBuffer?.(e)||typeof SharedArrayBuffer<"u"&&e instanceof SharedArrayBuffer||typeof Uint32Array<"u"&&e instanceof Uint32Array}let Fe;function ft(e){if(Fe)return Fe;async function t(){D=await ao(async n=>{let r=e;return r=await r,typeof r=="function"&&(r=await r(n)),typeof r=="function"&&(r=await r(n)),ho(r)?r=await r.instantiator(n):fo(r)?r=await r.default(n):(mo(r)&&(r=r.data),go(r)?typeof WebAssembly.instantiateStreaming=="function"?r=await yo(r)(n):r=await Eo(r)(n):_o(r)?r=await Lt(r)(n):r instanceof WebAssembly.Module?r=await Lt(r)(n):"default"in r&&r.default instanceof WebAssembly.Module&&(r=await Lt(r.default)(n))),"instance"in r&&(r=r.instance),"exports"in r&&(r=r.exports),r})}return Fe=t(),Fe}function Lt(e){return t=>WebAssembly.instantiate(e,t)}function yo(e){return t=>WebAssembly.instantiateStreaming(e,t)}function Eo(e){return async t=>{const n=await e.arrayBuffer();return WebAssembly.instantiate(n,t)}}let Rr;function bo(e){Rr=e}function wo(){return Rr}async function un(e){return e&&await ft(e),{createScanner(t){return new po(t.map(n=>typeof n=="string"?n:n.source))},createString(t){return new Lr(t)}}}const vo=Object.freeze(Object.defineProperty({__proto__:null,createOnigurumaEngine:un,getDefaultWasmLoader:wo,loadWasm:ft,setDefaultWasmLoader:bo},Symbol.toStringTag,{value:"Module"}));var Ir=an({});Sr(Ir,vo);var L=class extends Error{constructor(e){super(e),this.name="ShikiError"}};function Co(e){return cn(e)}function cn(e){return Array.isArray(e)?Ao(e):e instanceof RegExp?e:typeof e=="object"?ko(e):e}function Ao(e){let t=[];for(let n=0,r=e.length;n<r;n++)t[n]=cn(e[n]);return t}function ko(e){let t={};for(let n in e)t[n]=cn(e[n]);return t}function Tr(e,...t){return t.forEach(n=>{for(let r in n)e[r]=n[r]}),e}function Pr(e){const t=~e.lastIndexOf("/")||~e.lastIndexOf("\\");return t===0?e:~t===e.length-1?Pr(e.substring(0,e.length-1)):e.substr(~t+1)}var Rt=/\$(\d+)|\${(\d+):\/(downcase|upcase)}/g,je=class{static hasCaptures(e){return e===null?!1:(Rt.lastIndex=0,Rt.test(e))}static replaceCaptures(e,t,n){return e.replace(Rt,(r,i,o,s)=>{let a=n[parseInt(i||o,10)];if(a){let l=t.substring(a.start,a.end);for(;l[0]===".";)l=l.substring(1);switch(s){case"downcase":return l.toLowerCase();case"upcase":return l.toUpperCase();default:return l}}else return r})}};function Or(e,t){return e<t?-1:e>t?1:0}function xr(e,t){if(e===null&&t===null)return 0;if(!e)return-1;if(!t)return 1;let n=e.length,r=t.length;if(n===r){for(let i=0;i<n;i++){let o=Or(e[i],t[i]);if(o!==0)return o}return 0}return n-r}function $n(e){return!!(/^#[0-9a-f]{6}$/i.test(e)||/^#[0-9a-f]{8}$/i.test(e)||/^#[0-9a-f]{3}$/i.test(e)||/^#[0-9a-f]{4}$/i.test(e))}function Dr(e){return e.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g,"\\$&")}var Nr=class{constructor(e){this.fn=e}cache=new Map;get(e){if(this.cache.has(e))return this.cache.get(e);const t=this.fn(e);return this.cache.set(e,t),t}},Ye=class{constructor(e,t,n){this._colorMap=e,this._defaults=t,this._root=n}static createFromRawTheme(e,t){return this.createFromParsedTheme(Ro(e),t)}static createFromParsedTheme(e,t){return To(e,t)}_cachedMatchRoot=new Nr(e=>this._root.match(e));getColorMap(){return this._colorMap.getColorMap()}getDefaults(){return this._defaults}match(e){if(e===null)return this._defaults;const t=e.scopeName,r=this._cachedMatchRoot.get(t).find(i=>So(e.parent,i.parentScopes));return r?new Vr(r.fontStyle,r.foreground,r.background):null}},It=class Ke{constructor(t,n){this.parent=t,this.scopeName=n}static push(t,n){for(const r of n)t=new Ke(t,r);return t}static from(...t){let n=null;for(let r=0;r<t.length;r++)n=new Ke(n,t[r]);return n}push(t){return new Ke(this,t)}getSegments(){let t=this;const n=[];for(;t;)n.push(t.scopeName),t=t.parent;return n.reverse(),n}toString(){return this.getSegments().join(" ")}extends(t){return this===t?!0:this.parent===null?!1:this.parent.extends(t)}getExtensionIfDefined(t){const n=[];let r=this;for(;r&&r!==t;)n.push(r.scopeName),r=r.parent;return r===t?n.reverse():void 0}};function So(e,t){if(t.length===0)return!0;for(let n=0;n<t.length;n++){let r=t[n],i=!1;if(r===">"){if(n===t.length-1)return!1;r=t[++n],i=!0}for(;e&&!Lo(e.scopeName,r);){if(i)return!1;e=e.parent}if(!e)return!1;e=e.parent}return!0}function Lo(e,t){return t===e||e.startsWith(t)&&e[t.length]==="."}var Vr=class{constructor(e,t,n){this.fontStyle=e,this.foregroundId=t,this.backgroundId=n}};function Ro(e){if(!e)return[];if(!e.settings||!Array.isArray(e.settings))return[];let t=e.settings,n=[],r=0;for(let i=0,o=t.length;i<o;i++){let s=t[i];if(!s.settings)continue;let a;if(typeof s.scope=="string"){let d=s.scope;d=d.replace(/^[,]+/,""),d=d.replace(/[,]+$/,""),a=d.split(",")}else Array.isArray(s.scope)?a=s.scope:a=[""];let l=-1;if(typeof s.settings.fontStyle=="string"){l=0;let d=s.settings.fontStyle.split(" ");for(let f=0,h=d.length;f<h;f++)switch(d[f]){case"italic":l=l|1;break;case"bold":l=l|2;break;case"underline":l=l|4;break;case"strikethrough":l=l|8;break}}let u=null;typeof s.settings.foreground=="string"&&$n(s.settings.foreground)&&(u=s.settings.foreground);let p=null;typeof s.settings.background=="string"&&$n(s.settings.background)&&(p=s.settings.background);for(let d=0,f=a.length;d<f;d++){let m=a[d].trim().split(" "),E=m[m.length-1],b=null;m.length>1&&(b=m.slice(0,m.length-1),b.reverse()),n[r++]=new Io(E,b,i,l,u,p)}}return n}var Io=class{constructor(e,t,n,r,i,o){this.scope=e,this.parentScopes=t,this.index=n,this.fontStyle=r,this.foreground=i,this.background=o}},$=(e=>(e[e.NotSet=-1]="NotSet",e[e.None=0]="None",e[e.Italic=1]="Italic",e[e.Bold=2]="Bold",e[e.Underline=4]="Underline",e[e.Strikethrough=8]="Strikethrough",e))($||{});function To(e,t){e.sort((l,u)=>{let p=Or(l.scope,u.scope);return p!==0||(p=xr(l.parentScopes,u.parentScopes),p!==0)?p:l.index-u.index});let n=0,r="#000000",i="#ffffff";for(;e.length>=1&&e[0].scope==="";){let l=e.shift();l.fontStyle!==-1&&(n=l.fontStyle),l.foreground!==null&&(r=l.foreground),l.background!==null&&(i=l.background)}let o=new Po(t),s=new Vr(n,o.getId(r),o.getId(i)),a=new xo(new jt(0,null,-1,0,0),[]);for(let l=0,u=e.length;l<u;l++){let p=e[l];a.insert(0,p.scope,p.parentScopes,p.fontStyle,o.getId(p.foreground),o.getId(p.background))}return new Ye(o,s,a)}var Po=class{_isFrozen;_lastColorId;_id2color;_color2id;constructor(e){if(this._lastColorId=0,this._id2color=[],this._color2id=Object.create(null),Array.isArray(e)){this._isFrozen=!0;for(let t=0,n=e.length;t<n;t++)this._color2id[e[t]]=t,this._id2color[t]=e[t]}else this._isFrozen=!1}getId(e){if(e===null)return 0;e=e.toUpperCase();let t=this._color2id[e];if(t)return t;if(this._isFrozen)throw new Error(`Missing color in color map - ${e}`);return t=++this._lastColorId,this._color2id[e]=t,this._id2color[t]=e,t}getColorMap(){return this._id2color.slice(0)}},Oo=Object.freeze([]),jt=class $r{scopeDepth;parentScopes;fontStyle;foreground;background;constructor(t,n,r,i,o){this.scopeDepth=t,this.parentScopes=n||Oo,this.fontStyle=r,this.foreground=i,this.background=o}clone(){return new $r(this.scopeDepth,this.parentScopes,this.fontStyle,this.foreground,this.background)}static cloneArr(t){let n=[];for(let r=0,i=t.length;r<i;r++)n[r]=t[r].clone();return n}acceptOverwrite(t,n,r,i){this.scopeDepth>t?console.log("how did this happen?"):this.scopeDepth=t,n!==-1&&(this.fontStyle=n),r!==0&&(this.foreground=r),i!==0&&(this.background=i)}},xo=class Ht{constructor(t,n=[],r={}){this._mainRule=t,this._children=r,this._rulesWithParentScopes=n}_rulesWithParentScopes;static _cmpBySpecificity(t,n){if(t.scopeDepth!==n.scopeDepth)return n.scopeDepth-t.scopeDepth;let r=0,i=0;for(;t.parentScopes[r]===">"&&r++,n.parentScopes[i]===">"&&i++,!(r>=t.parentScopes.length||i>=n.parentScopes.length);){const o=n.parentScopes[i].length-t.parentScopes[r].length;if(o!==0)return o;r++,i++}return n.parentScopes.length-t.parentScopes.length}match(t){if(t!==""){let r=t.indexOf("."),i,o;if(r===-1?(i=t,o=""):(i=t.substring(0,r),o=t.substring(r+1)),this._children.hasOwnProperty(i))return this._children[i].match(o)}const n=this._rulesWithParentScopes.concat(this._mainRule);return n.sort(Ht._cmpBySpecificity),n}insert(t,n,r,i,o,s){if(n===""){this._doInsertHere(t,r,i,o,s);return}let a=n.indexOf("."),l,u;a===-1?(l=n,u=""):(l=n.substring(0,a),u=n.substring(a+1));let p;this._children.hasOwnProperty(l)?p=this._children[l]:(p=new Ht(this._mainRule.clone(),jt.cloneArr(this._rulesWithParentScopes)),this._children[l]=p),p.insert(t+1,u,r,i,o,s)}_doInsertHere(t,n,r,i,o){if(n===null){this._mainRule.acceptOverwrite(t,r,i,o);return}for(let s=0,a=this._rulesWithParentScopes.length;s<a;s++){let l=this._rulesWithParentScopes[s];if(xr(l.parentScopes,n)===0){l.acceptOverwrite(t,r,i,o);return}}r===-1&&(r=this._mainRule.fontStyle),i===0&&(i=this._mainRule.foreground),o===0&&(o=this._mainRule.background),this._rulesWithParentScopes.push(new jt(t,n,r,i,o))}},le=class U{static toBinaryStr(t){return t.toString(2).padStart(32,"0")}static print(t){const n=U.getLanguageId(t),r=U.getTokenType(t),i=U.getFontStyle(t),o=U.getForeground(t),s=U.getBackground(t);console.log({languageId:n,tokenType:r,fontStyle:i,foreground:o,background:s})}static getLanguageId(t){return(t&255)>>>0}static getTokenType(t){return(t&768)>>>8}static containsBalancedBrackets(t){return(t&1024)!==0}static getFontStyle(t){return(t&30720)>>>11}static getForeground(t){return(t&16744448)>>>15}static getBackground(t){return(t&4278190080)>>>24}static set(t,n,r,i,o,s,a){let l=U.getLanguageId(t),u=U.getTokenType(t),p=U.containsBalancedBrackets(t)?1:0,d=U.getFontStyle(t),f=U.getForeground(t),h=U.getBackground(t);return n!==0&&(l=n),r!==8&&(u=r),i!==null&&(p=i?1:0),o!==-1&&(d=o),s!==0&&(f=s),a!==0&&(h=a),(l<<0|u<<8|p<<10|d<<11|f<<15|h<<24)>>>0}};function Ze(e,t){const n=[],r=Do(e);let i=r.next();for(;i!==null;){let l=0;if(i.length===2&&i.charAt(1)===":"){switch(i.charAt(0)){case"R":l=1;break;case"L":l=-1;break;default:console.log(`Unknown priority ${i} in scope selector`)}i=r.next()}let u=s();if(n.push({matcher:u,priority:l}),i!==",")break;i=r.next()}return n;function o(){if(i==="-"){i=r.next();const l=o();return u=>!!l&&!l(u)}if(i==="("){i=r.next();const l=a();return i===")"&&(i=r.next()),l}if(Mn(i)){const l=[];do l.push(i),i=r.next();while(Mn(i));return u=>t(l,u)}return null}function s(){const l=[];let u=o();for(;u;)l.push(u),u=o();return p=>l.every(d=>d(p))}function a(){const l=[];let u=s();for(;u&&(l.push(u),i==="|"||i===",");){do i=r.next();while(i==="|"||i===",");u=s()}return p=>l.some(d=>d(p))}}function Mn(e){return!!e&&!!e.match(/[\w\.:]+/)}function Do(e){let t=/([LR]:|[\w\.:][\w\.:\-]*|[\,\|\-\(\)])/g,n=t.exec(e);return{next:()=>{if(!n)return null;const r=n[0];return n=t.exec(e),r}}}function Mr(e){typeof e.dispose=="function"&&e.dispose()}var Se=class{constructor(e){this.scopeName=e}toKey(){return this.scopeName}},No=class{constructor(e,t){this.scopeName=e,this.ruleName=t}toKey(){return`${this.scopeName}#${this.ruleName}`}},Vo=class{_references=[];_seenReferenceKeys=new Set;get references(){return this._references}visitedRule=new Set;add(e){const t=e.toKey();this._seenReferenceKeys.has(t)||(this._seenReferenceKeys.add(t),this._references.push(e))}},$o=class{constructor(e,t){this.repo=e,this.initialScopeName=t,this.seenFullScopeRequests.add(this.initialScopeName),this.Q=[new Se(this.initialScopeName)]}seenFullScopeRequests=new Set;seenPartialScopeRequests=new Set;Q;processQueue(){const e=this.Q;this.Q=[];const t=new Vo;for(const n of e)Mo(n,this.initialScopeName,this.repo,t);for(const n of t.references)if(n instanceof Se){if(this.seenFullScopeRequests.has(n.scopeName))continue;this.seenFullScopeRequests.add(n.scopeName),this.Q.push(n)}else{if(this.seenFullScopeRequests.has(n.scopeName)||this.seenPartialScopeRequests.has(n.toKey()))continue;this.seenPartialScopeRequests.add(n.toKey()),this.Q.push(n)}}};function Mo(e,t,n,r){const i=n.lookup(e.scopeName);if(!i){if(e.scopeName===t)throw new Error(`No grammar provided for <${t}>`);return}const o=n.lookup(t);e instanceof Se?Qe({baseGrammar:o,selfGrammar:i},r):Wt(e.ruleName,{baseGrammar:o,selfGrammar:i,repository:i.repository},r);const s=n.injections(e.scopeName);if(s)for(const a of s)r.add(new Se(a))}function Wt(e,t,n){if(t.repository&&t.repository[e]){const r=t.repository[e];et([r],t,n)}}function Qe(e,t){e.selfGrammar.patterns&&Array.isArray(e.selfGrammar.patterns)&&et(e.selfGrammar.patterns,{...e,repository:e.selfGrammar.repository},t),e.selfGrammar.injections&&et(Object.values(e.selfGrammar.injections),{...e,repository:e.selfGrammar.repository},t)}function et(e,t,n){for(const r of e){if(n.visitedRule.has(r))continue;n.visitedRule.add(r);const i=r.repository?Tr({},t.repository,r.repository):t.repository;Array.isArray(r.patterns)&&et(r.patterns,{...t,repository:i},n);const o=r.include;if(!o)continue;const s=Gr(o);switch(s.kind){case 0:Qe({...t,selfGrammar:t.baseGrammar},n);break;case 1:Qe(t,n);break;case 2:Wt(s.ruleName,{...t,repository:i},n);break;case 3:case 4:const a=s.scopeName===t.selfGrammar.scopeName?t.selfGrammar:s.scopeName===t.baseGrammar.scopeName?t.baseGrammar:void 0;if(a){const l={baseGrammar:t.baseGrammar,selfGrammar:a,repository:i};s.kind===4?Wt(s.ruleName,l,n):Qe(l,n)}else s.kind===4?n.add(new No(s.scopeName,s.ruleName)):n.add(new Se(s.scopeName));break}}}var Go=class{kind=0},Bo=class{kind=1},Uo=class{constructor(e){this.ruleName=e}kind=2},Fo=class{constructor(e){this.scopeName=e}kind=3},jo=class{constructor(e,t){this.scopeName=e,this.ruleName=t}kind=4};function Gr(e){if(e==="$base")return new Go;if(e==="$self")return new Bo;const t=e.indexOf("#");if(t===-1)return new Fo(e);if(t===0)return new Uo(e.substring(1));{const n=e.substring(0,t),r=e.substring(t+1);return new jo(n,r)}}var Ho=/\\(\d+)/,Gn=/\\(\d+)/g,Wo=-1,Br=-2;var Ve=class{$location;id;_nameIsCapturing;_name;_contentNameIsCapturing;_contentName;constructor(e,t,n,r){this.$location=e,this.id=t,this._name=n||null,this._nameIsCapturing=je.hasCaptures(this._name),this._contentName=r||null,this._contentNameIsCapturing=je.hasCaptures(this._contentName)}get debugName(){const e=this.$location?`${Pr(this.$location.filename)}:${this.$location.line}`:"unknown";return`${this.constructor.name}#${this.id} @ ${e}`}getName(e,t){return!this._nameIsCapturing||this._name===null||e===null||t===null?this._name:je.replaceCaptures(this._name,e,t)}getContentName(e,t){return!this._contentNameIsCapturing||this._contentName===null?this._contentName:je.replaceCaptures(this._contentName,e,t)}},zo=class extends Ve{retokenizeCapturedWithRuleId;constructor(e,t,n,r,i){super(e,t,n,r),this.retokenizeCapturedWithRuleId=i}dispose(){}collectPatterns(e,t){throw new Error("Not supported!")}compile(e,t){throw new Error("Not supported!")}compileAG(e,t,n,r){throw new Error("Not supported!")}},qo=class extends Ve{_match;captures;_cachedCompiledPatterns;constructor(e,t,n,r,i){super(e,t,n,null),this._match=new Le(r,this.id),this.captures=i,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugMatchRegExp(){return`${this._match.source}`}collectPatterns(e,t){t.push(this._match)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new Re,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},Bn=class extends Ve{hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,r,i){super(e,t,n,r),this.patterns=i.patterns,this.hasMissingPatterns=i.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}collectPatterns(e,t){for(const n of this.patterns)e.getRule(n).collectPatterns(e,t)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new Re,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},zt=class extends Ve{_begin;beginCaptures;_end;endHasBackReferences;endCaptures;applyEndPatternLast;hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,r,i,o,s,a,l,u){super(e,t,n,r),this._begin=new Le(i,this.id),this.beginCaptures=o,this._end=new Le(s||"￿",-1),this.endHasBackReferences=this._end.hasBackReferences,this.endCaptures=a,this.applyEndPatternLast=l||!1,this.patterns=u.patterns,this.hasMissingPatterns=u.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugEndRegExp(){return`${this._end.source}`}getEndWithResolvedBackReferences(e,t){return this._end.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e,t).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e,t).compileAG(e,n,r)}_getCachedCompiledPatterns(e,t){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new Re;for(const n of this.patterns)e.getRule(n).collectPatterns(e,this._cachedCompiledPatterns);this.applyEndPatternLast?this._cachedCompiledPatterns.push(this._end.hasBackReferences?this._end.clone():this._end):this._cachedCompiledPatterns.unshift(this._end.hasBackReferences?this._end.clone():this._end)}return this._end.hasBackReferences&&(this.applyEndPatternLast?this._cachedCompiledPatterns.setSource(this._cachedCompiledPatterns.length()-1,t):this._cachedCompiledPatterns.setSource(0,t)),this._cachedCompiledPatterns}},tt=class extends Ve{_begin;beginCaptures;whileCaptures;_while;whileHasBackReferences;hasMissingPatterns;patterns;_cachedCompiledPatterns;_cachedCompiledWhilePatterns;constructor(e,t,n,r,i,o,s,a,l){super(e,t,n,r),this._begin=new Le(i,this.id),this.beginCaptures=o,this.whileCaptures=a,this._while=new Le(s,Br),this.whileHasBackReferences=this._while.hasBackReferences,this.patterns=l.patterns,this.hasMissingPatterns=l.hasMissingPatterns,this._cachedCompiledPatterns=null,this._cachedCompiledWhilePatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null),this._cachedCompiledWhilePatterns&&(this._cachedCompiledWhilePatterns.dispose(),this._cachedCompiledWhilePatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugWhileRegExp(){return`${this._while.source}`}getWhileWithResolvedBackReferences(e,t){return this._while.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new Re;for(const t of this.patterns)e.getRule(t).collectPatterns(e,this._cachedCompiledPatterns)}return this._cachedCompiledPatterns}compileWhile(e,t){return this._getCachedCompiledWhilePatterns(e,t).compile(e)}compileWhileAG(e,t,n,r){return this._getCachedCompiledWhilePatterns(e,t).compileAG(e,n,r)}_getCachedCompiledWhilePatterns(e,t){return this._cachedCompiledWhilePatterns||(this._cachedCompiledWhilePatterns=new Re,this._cachedCompiledWhilePatterns.push(this._while.hasBackReferences?this._while.clone():this._while)),this._while.hasBackReferences&&this._cachedCompiledWhilePatterns.setSource(0,t||"￿"),this._cachedCompiledWhilePatterns}},Ur=class V{static createCaptureRule(t,n,r,i,o){return t.registerRule(s=>new zo(n,s,r,i,o))}static getCompiledRuleId(t,n,r){return t.id||n.registerRule(i=>{if(t.id=i,t.match)return new qo(t.$vscodeTextmateLocation,t.id,t.name,t.match,V._compileCaptures(t.captures,n,r));if(typeof t.begin>"u"){t.repository&&(r=Tr({},r,t.repository));let o=t.patterns;return typeof o>"u"&&t.include&&(o=[{include:t.include}]),new Bn(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,V._compilePatterns(o,n,r))}return t.while?new tt(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,V._compileCaptures(t.beginCaptures||t.captures,n,r),t.while,V._compileCaptures(t.whileCaptures||t.captures,n,r),V._compilePatterns(t.patterns,n,r)):new zt(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,V._compileCaptures(t.beginCaptures||t.captures,n,r),t.end,V._compileCaptures(t.endCaptures||t.captures,n,r),t.applyEndPatternLast,V._compilePatterns(t.patterns,n,r))}),t.id}static _compileCaptures(t,n,r){let i=[];if(t){let o=0;for(const s in t){if(s==="$vscodeTextmateLocation")continue;const a=parseInt(s,10);a>o&&(o=a)}for(let s=0;s<=o;s++)i[s]=null;for(const s in t){if(s==="$vscodeTextmateLocation")continue;const a=parseInt(s,10);let l=0;t[s].patterns&&(l=V.getCompiledRuleId(t[s],n,r)),i[a]=V.createCaptureRule(n,t[s].$vscodeTextmateLocation,t[s].name,t[s].contentName,l)}}return i}static _compilePatterns(t,n,r){let i=[];if(t)for(let o=0,s=t.length;o<s;o++){const a=t[o];let l=-1;if(a.include){const u=Gr(a.include);switch(u.kind){case 0:case 1:l=V.getCompiledRuleId(r[a.include],n,r);break;case 2:let p=r[u.ruleName];p&&(l=V.getCompiledRuleId(p,n,r));break;case 3:case 4:const d=u.scopeName,f=u.kind===4?u.ruleName:null,h=n.getExternalGrammar(d,r);if(h)if(f){let m=h.repository[f];m&&(l=V.getCompiledRuleId(m,n,h.repository))}else l=V.getCompiledRuleId(h.repository.$self,n,h.repository);break}}else l=V.getCompiledRuleId(a,n,r);if(l!==-1){const u=n.getRule(l);let p=!1;if((u instanceof Bn||u instanceof zt||u instanceof tt)&&u.hasMissingPatterns&&u.patterns.length===0&&(p=!0),p)continue;i.push(l)}}return{patterns:i,hasMissingPatterns:(t?t.length:0)!==i.length}}},Le=class Fr{source;ruleId;hasAnchor;hasBackReferences;_anchorCache;constructor(t,n){if(t&&typeof t=="string"){const r=t.length;let i=0,o=[],s=!1;for(let a=0;a<r;a++)if(t.charAt(a)==="\\"&&a+1<r){const u=t.charAt(a+1);u==="z"?(o.push(t.substring(i,a)),o.push("$(?!\\n)(?<!\\n)"),i=a+2):(u==="A"||u==="G")&&(s=!0),a++}this.hasAnchor=s,i===0?this.source=t:(o.push(t.substring(i,r)),this.source=o.join(""))}else this.hasAnchor=!1,this.source=t;this.hasAnchor?this._anchorCache=this._buildAnchorCache():this._anchorCache=null,this.ruleId=n,typeof this.source=="string"?this.hasBackReferences=Ho.test(this.source):this.hasBackReferences=!1}clone(){return new Fr(this.source,this.ruleId)}setSource(t){this.source!==t&&(this.source=t,this.hasAnchor&&(this._anchorCache=this._buildAnchorCache()))}resolveBackReferences(t,n){if(typeof this.source!="string")throw new Error("This method should only be called if the source is a string");let r=n.map(i=>t.substring(i.start,i.end));return Gn.lastIndex=0,this.source.replace(Gn,(i,o)=>Dr(r[parseInt(o,10)]||""))}_buildAnchorCache(){if(typeof this.source!="string")throw new Error("This method should only be called if the source is a string");let t=[],n=[],r=[],i=[],o,s,a,l;for(o=0,s=this.source.length;o<s;o++)a=this.source.charAt(o),t[o]=a,n[o]=a,r[o]=a,i[o]=a,a==="\\"&&o+1<s&&(l=this.source.charAt(o+1),l==="A"?(t[o+1]="￿",n[o+1]="￿",r[o+1]="A",i[o+1]="A"):l==="G"?(t[o+1]="￿",n[o+1]="G",r[o+1]="￿",i[o+1]="G"):(t[o+1]=l,n[o+1]=l,r[o+1]=l,i[o+1]=l),o++);return{A0_G0:t.join(""),A0_G1:n.join(""),A1_G0:r.join(""),A1_G1:i.join("")}}resolveAnchors(t,n){return!this.hasAnchor||!this._anchorCache||typeof this.source!="string"?this.source:t?n?this._anchorCache.A1_G1:this._anchorCache.A1_G0:n?this._anchorCache.A0_G1:this._anchorCache.A0_G0}},Re=class{_items;_hasAnchors;_cached;_anchorCache;constructor(){this._items=[],this._hasAnchors=!1,this._cached=null,this._anchorCache={A0_G0:null,A0_G1:null,A1_G0:null,A1_G1:null}}dispose(){this._disposeCaches()}_disposeCaches(){this._cached&&(this._cached.dispose(),this._cached=null),this._anchorCache.A0_G0&&(this._anchorCache.A0_G0.dispose(),this._anchorCache.A0_G0=null),this._anchorCache.A0_G1&&(this._anchorCache.A0_G1.dispose(),this._anchorCache.A0_G1=null),this._anchorCache.A1_G0&&(this._anchorCache.A1_G0.dispose(),this._anchorCache.A1_G0=null),this._anchorCache.A1_G1&&(this._anchorCache.A1_G1.dispose(),this._anchorCache.A1_G1=null)}push(e){this._items.push(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}unshift(e){this._items.unshift(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}length(){return this._items.length}setSource(e,t){this._items[e].source!==t&&(this._disposeCaches(),this._items[e].setSource(t))}compile(e){if(!this._cached){let t=this._items.map(n=>n.source);this._cached=new Un(e,t,this._items.map(n=>n.ruleId))}return this._cached}compileAG(e,t,n){return this._hasAnchors?t?n?(this._anchorCache.A1_G1||(this._anchorCache.A1_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G1):(this._anchorCache.A1_G0||(this._anchorCache.A1_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G0):n?(this._anchorCache.A0_G1||(this._anchorCache.A0_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G1):(this._anchorCache.A0_G0||(this._anchorCache.A0_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G0):this.compile(e)}_resolveAnchors(e,t,n){let r=this._items.map(i=>i.resolveAnchors(t,n));return new Un(e,r,this._items.map(i=>i.ruleId))}},Un=class{constructor(e,t,n){this.regExps=t,this.rules=n,this.scanner=e.createOnigScanner(t)}scanner;dispose(){typeof this.scanner.dispose=="function"&&this.scanner.dispose()}toString(){const e=[];for(let t=0,n=this.rules.length;t<n;t++)e.push(" - "+this.rules[t]+": "+this.regExps[t]);return e.join(` +import{bR as c}from"./index-D-7nOosq.js";var Ft=Object.defineProperty,eo=Object.getOwnPropertyDescriptor,to=Object.getOwnPropertyNames,no=Object.prototype.hasOwnProperty,an=(e,t)=>{let n={};for(var r in e)Ft(n,r,{get:e[r],enumerable:!0});return Ft(n,Symbol.toStringTag,{value:"Module"}),n},ro=(e,t,n,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(var i=to(t),o=0,s=i.length,a;o<s;o++)a=i[o],!no.call(e,a)&&a!==n&&Ft(e,a,{get:(l=>t[l]).bind(null,a),enumerable:!(r=eo(t,a))||r.enumerable});return e},Sr=(e,t,n)=>(ro(e,t,"default"),n);const Ne=[{id:"abap",name:"ABAP",import:(()=>c(()=>import("./abap-BdImnpbu.js"),[]))},{id:"actionscript-3",name:"ActionScript",import:(()=>c(()=>import("./actionscript-3-CoDkCxhg.js"),[]))},{id:"ada",name:"Ada",import:(()=>c(()=>import("./ada-bCR0ucgS.js"),[]))},{id:"angular-html",name:"Angular HTML",import:(()=>c(()=>import("./angular-html-DA-rfuFy.js").then(e=>e.f),__vite__mapDeps([0,1,2,3])))},{id:"angular-ts",name:"Angular TypeScript",import:(()=>c(()=>import("./angular-ts-BrjP3tb8.js"),__vite__mapDeps([4,0,1,2,3,5])))},{id:"apache",name:"Apache Conf",import:(()=>c(()=>import("./apache-Pmp26Uib.js"),[]))},{id:"apex",name:"Apex",import:(()=>c(()=>import("./apex-Dqspr-GT.js"),[]))},{id:"apl",name:"APL",import:(()=>c(()=>import("./apl-CORt7UWP.js"),__vite__mapDeps([6,1,2,3,7,8,9])))},{id:"applescript",name:"AppleScript",import:(()=>c(()=>import("./applescript-Co6uUVPk.js"),[]))},{id:"ara",name:"Ara",import:(()=>c(()=>import("./ara-BRHolxvo.js"),[]))},{id:"asciidoc",name:"AsciiDoc",aliases:["adoc"],import:(()=>c(()=>import("./asciidoc-Ve4PFQV2.js"),[]))},{id:"asm",name:"Assembly",import:(()=>c(()=>import("./asm-D_Q5rh1f.js"),[]))},{id:"astro",name:"Astro",import:(()=>c(()=>import("./astro-HNnZUWAn.js"),__vite__mapDeps([10,9,2,11,3,12,13])))},{id:"awk",name:"AWK",import:(()=>c(()=>import("./awk-DMzUqQB5.js"),[]))},{id:"ballerina",name:"Ballerina",import:(()=>c(()=>import("./ballerina-BFfxhgS-.js"),[]))},{id:"bat",name:"Batch File",aliases:["batch"],import:(()=>c(()=>import("./bat-BkioyH1T.js"),[]))},{id:"beancount",name:"Beancount",import:(()=>c(()=>import("./beancount-k_qm7-4y.js"),[]))},{id:"berry",name:"Berry",aliases:["be"],import:(()=>c(()=>import("./berry-uYugtg8r.js"),[]))},{id:"bibtex",name:"BibTeX",import:(()=>c(()=>import("./bibtex-CHM0blh-.js"),[]))},{id:"bicep",name:"Bicep",import:(()=>c(()=>import("./bicep-Bmn6On1c.js"),[]))},{id:"bird2",name:"BIRD2 Configuration",aliases:["bird"],import:(()=>c(()=>import("./bird2-BIv1doCn.js"),[]))},{id:"blade",name:"Blade",import:(()=>c(()=>import("./blade-2xfisSek.js"),__vite__mapDeps([14,15,1,2,3,7,8,16,9])))},{id:"bsl",name:"1C (Enterprise)",aliases:["1c"],import:(()=>c(()=>import("./bsl-BO_Y6i37.js"),__vite__mapDeps([17,18])))},{id:"c",name:"C",import:(()=>c(()=>import("./c-BIGW1oBm.js"),[]))},{id:"c3",name:"C3",import:(()=>c(()=>import("./c3-MRO5bC_T.js"),[]))},{id:"cadence",name:"Cadence",aliases:["cdc"],import:(()=>c(()=>import("./cadence-Bv_4Rxtq.js"),[]))},{id:"cairo",name:"Cairo",import:(()=>c(()=>import("./cairo-KRGpt6FW.js"),__vite__mapDeps([19,20])))},{id:"clarity",name:"Clarity",import:(()=>c(()=>import("./clarity-D53aC0YG.js"),[]))},{id:"clojure",name:"Clojure",aliases:["clj"],import:(()=>c(()=>import("./clojure-P80f7IUj.js"),[]))},{id:"cmake",name:"CMake",import:(()=>c(()=>import("./cmake-D1j8_8rp.js"),[]))},{id:"cobol",name:"COBOL",import:(()=>c(()=>import("./cobol-nBiQ_Alo.js"),__vite__mapDeps([21,1,2,3,8])))},{id:"codeowners",name:"CODEOWNERS",import:(()=>c(()=>import("./codeowners-Bp6g37R7.js"),[]))},{id:"codeql",name:"CodeQL",aliases:["ql"],import:(()=>c(()=>import("./codeql-DsOJ9woJ.js"),[]))},{id:"coffee",name:"CoffeeScript",aliases:["coffeescript"],import:(()=>c(()=>import("./coffee-Ch7k5sss.js"),__vite__mapDeps([22,2])))},{id:"common-lisp",name:"Common Lisp",aliases:["lisp"],import:(()=>c(()=>import("./common-lisp-Cg-RD9OK.js"),[]))},{id:"coq",name:"Coq",import:(()=>c(()=>import("./coq-DkFqJrB1.js"),[]))},{id:"cpp",name:"C++",aliases:["c++"],import:(()=>c(()=>import("./cpp-UfJy6YNI.js"),__vite__mapDeps([23,24,25,26,16])))},{id:"crystal",name:"Crystal",import:(()=>c(()=>import("./crystal-DGywbUpC.js"),__vite__mapDeps([27,1,2,3,16,26,28])))},{id:"csharp",name:"C#",aliases:["c#","cs"],import:(()=>c(()=>import("./csharp-DSvCPggb.js"),[]))},{id:"css",name:"CSS",import:(()=>c(()=>import("./css-CLj8gQPS.js"),[]))},{id:"csv",name:"CSV",import:(()=>c(()=>import("./csv-fuZLfV_i.js"),[]))},{id:"cue",name:"CUE",import:(()=>c(()=>import("./cue-D82EKSYY.js"),[]))},{id:"cypher",name:"Cypher",aliases:["cql"],import:(()=>c(()=>import("./cypher-COkxafJQ.js"),[]))},{id:"d",name:"D",import:(()=>c(()=>import("./d-85-TOEBH.js"),[]))},{id:"dart",name:"Dart",import:(()=>c(()=>import("./dart-bE4Kk8sk.js"),[]))},{id:"dax",name:"DAX",import:(()=>c(()=>import("./dax-CEL-wOlO.js"),[]))},{id:"desktop",name:"Desktop",import:(()=>c(()=>import("./desktop-BmXAJ9_W.js"),[]))},{id:"diff",name:"Diff",import:(()=>c(()=>import("./diff-D97Zzqfu.js"),[]))},{id:"docker",name:"Dockerfile",aliases:["dockerfile"],import:(()=>c(()=>import("./docker-BcOcwvcX.js"),[]))},{id:"dotenv",name:"dotEnv",import:(()=>c(()=>import("./dotenv-Da5cRb03.js"),[]))},{id:"dream-maker",name:"Dream Maker",import:(()=>c(()=>import("./dream-maker-BtqSS_iP.js"),[]))},{id:"edge",name:"Edge",import:(()=>c(()=>import("./edge-FbVlp4U3.js"),__vite__mapDeps([29,11,1,2,3,15])))},{id:"elixir",name:"Elixir",import:(()=>c(()=>import("./elixir-CkH2-t6x.js"),__vite__mapDeps([30,1,2,3])))},{id:"elm",name:"Elm",import:(()=>c(()=>import("./elm-DbKCFpqz.js"),__vite__mapDeps([31,25,26])))},{id:"emacs-lisp",name:"Emacs Lisp",aliases:["elisp"],import:(()=>c(()=>import("./emacs-lisp-CXvaQtF9.js"),[]))},{id:"erb",name:"ERB",import:(()=>c(()=>import("./erb-Dm6A9KJ5.js"),__vite__mapDeps([32,1,2,3,33,34,7,8,16,35,11,36,13,23,24,25,26,28,37,38])))},{id:"erlang",name:"Erlang",aliases:["erl"],import:(()=>c(()=>import("./erlang-DsQrWhSR.js"),__vite__mapDeps([39,40])))},{id:"fennel",name:"Fennel",import:(()=>c(()=>import("./fennel-BYunw83y.js"),[]))},{id:"fish",name:"Fish",import:(()=>c(()=>import("./fish-BvzEVeQv.js"),[]))},{id:"fluent",name:"Fluent",aliases:["ftl"],import:(()=>c(()=>import("./fluent-C4IJs8-o.js"),[]))},{id:"fortran-fixed-form",name:"Fortran (Fixed Form)",aliases:["f","for","f77"],import:(()=>c(()=>import("./fortran-fixed-form-CkoXwp7k.js"),__vite__mapDeps([41,42])))},{id:"fortran-free-form",name:"Fortran (Free Form)",aliases:["f90","f95","f03","f08","f18"],import:(()=>c(()=>import("./fortran-free-form-BxgE0vQu.js"),[]))},{id:"fsharp",name:"F#",aliases:["f#","fs"],import:(()=>c(()=>import("./fsharp-CXgrBDvD.js"),__vite__mapDeps([43,40])))},{id:"gdresource",name:"GDResource",aliases:["tscn","tres"],import:(()=>c(()=>import("./gdresource-BOOCDP_w.js"),__vite__mapDeps([44,45,46])))},{id:"gdscript",name:"GDScript",aliases:["gd"],import:(()=>c(()=>import("./gdscript-C5YyOfLZ.js"),[]))},{id:"gdshader",name:"GDShader",import:(()=>c(()=>import("./gdshader-DkwncUOv.js"),[]))},{id:"genie",name:"Genie",import:(()=>c(()=>import("./genie-D0YGMca9.js"),[]))},{id:"gherkin",name:"Gherkin",import:(()=>c(()=>import("./gherkin-DyxjwDmM.js"),[]))},{id:"git-commit",name:"Git Commit Message",import:(()=>c(()=>import("./git-commit-F4YmCXRG.js"),__vite__mapDeps([47,48])))},{id:"git-rebase",name:"Git Rebase Message",import:(()=>c(()=>import("./git-rebase-r7XF79zn.js"),__vite__mapDeps([49,28])))},{id:"gleam",name:"Gleam",import:(()=>c(()=>import("./gleam-BspZqrRM.js"),[]))},{id:"glimmer-js",name:"Glimmer JS",aliases:["gjs"],import:(()=>c(()=>import("./glimmer-js-ByusRIyA.js"),__vite__mapDeps([50,2,11,3,1])))},{id:"glimmer-ts",name:"Glimmer TS",aliases:["gts"],import:(()=>c(()=>import("./glimmer-ts-BfAWNZQY.js"),__vite__mapDeps([51,11,3,2,1])))},{id:"glsl",name:"GLSL",import:(()=>c(()=>import("./glsl-DplSGwfg.js"),__vite__mapDeps([25,26])))},{id:"gn",name:"GN",import:(()=>c(()=>import("./gn-n2N0HUVH.js"),[]))},{id:"gnuplot",name:"Gnuplot",import:(()=>c(()=>import("./gnuplot-DdkO51Og.js"),[]))},{id:"go",name:"Go",import:(()=>c(()=>import("./go-C27-OAKa.js"),[]))},{id:"graphql",name:"GraphQL",aliases:["gql"],import:(()=>c(()=>import("./graphql-ChdNCCLP.js"),__vite__mapDeps([35,2,11,36,13])))},{id:"groovy",name:"Groovy",import:(()=>c(()=>import("./groovy-gcz8RCvz.js"),[]))},{id:"hack",name:"Hack",import:(()=>c(()=>import("./hack-DbPARsA_.js"),__vite__mapDeps([52,1,2,3,16])))},{id:"haml",name:"Ruby Haml",import:(()=>c(()=>import("./haml-D5jkg6IW.js"),__vite__mapDeps([34,2,3])))},{id:"handlebars",name:"Handlebars",aliases:["hbs"],import:(()=>c(()=>import("./handlebars-BpdQsYii.js"),__vite__mapDeps([53,1,2,3,38])))},{id:"haskell",name:"Haskell",aliases:["hs"],import:(()=>c(()=>import("./haskell-Df6bDoY_.js"),[]))},{id:"haxe",name:"Haxe",import:(()=>c(()=>import("./haxe-CzTSHFRz.js"),[]))},{id:"hcl",name:"HashiCorp HCL",import:(()=>c(()=>import("./hcl-BWvSN4gD.js"),[]))},{id:"hjson",name:"Hjson",import:(()=>c(()=>import("./hjson-D5-asLiD.js"),[]))},{id:"hlsl",name:"HLSL",import:(()=>c(()=>import("./hlsl-D3lLCCz7.js"),[]))},{id:"html",name:"HTML",import:(()=>c(()=>import("./html-pp8916En.js"),__vite__mapDeps([1,2,3])))},{id:"html-derivative",name:"HTML (Derivative)",import:(()=>c(()=>import("./html-derivative-DlHx6ybY.js"),__vite__mapDeps([15,1,2,3])))},{id:"http",name:"HTTP",import:(()=>c(()=>import("./http-jrhK8wxY.js"),__vite__mapDeps([54,28,9,7,8,35,2,11,36,13])))},{id:"hurl",name:"Hurl",import:(()=>c(()=>import("./hurl-irOxFIW8.js"),__vite__mapDeps([55,35,2,11,36,13,7,8,56])))},{id:"hxml",name:"HXML",import:(()=>c(()=>import("./hxml-Bvhsp5Yf.js"),__vite__mapDeps([57,58])))},{id:"hy",name:"Hy",import:(()=>c(()=>import("./hy-DFXneXwc.js"),[]))},{id:"imba",name:"Imba",import:(()=>c(()=>import("./imba-DGztddWO.js"),[]))},{id:"ini",name:"INI",aliases:["properties"],import:(()=>c(()=>import("./ini-BEwlwnbL.js"),[]))},{id:"java",name:"Java",import:(()=>c(()=>import("./java-CylS5w8V.js"),[]))},{id:"javascript",name:"JavaScript",aliases:["js","cjs","mjs"],import:(()=>c(()=>import("./javascript-wDzz0qaB.js"),[]))},{id:"jinja",name:"Jinja",import:(()=>c(()=>import("./jinja-f2NsQr07.js"),__vite__mapDeps([59,1,2,3])))},{id:"jison",name:"Jison",import:(()=>c(()=>import("./jison-wvAkD_A8.js"),__vite__mapDeps([60,2])))},{id:"json",name:"JSON",import:(()=>c(()=>import("./json-Cp-IABpG.js"),[]))},{id:"json5",name:"JSON5",import:(()=>c(()=>import("./json5-C9tS-k6U.js"),[]))},{id:"jsonc",name:"JSON with Comments",import:(()=>c(()=>import("./jsonc-Des-eS-w.js"),[]))},{id:"jsonl",name:"JSON Lines",import:(()=>c(()=>import("./jsonl-DcaNXYhu.js"),[]))},{id:"jsonnet",name:"Jsonnet",import:(()=>c(()=>import("./jsonnet-DFQXde-d.js"),[]))},{id:"jssm",name:"JSSM",aliases:["fsl"],import:(()=>c(()=>import("./jssm-C2t-YnRu.js"),[]))},{id:"jsx",name:"JSX",import:(()=>c(()=>import("./jsx-g9-lgVsj.js"),[]))},{id:"julia",name:"Julia",aliases:["jl"],import:(()=>c(()=>import("./julia-D7OTSIA_.js"),__vite__mapDeps([61,23,24,25,26,16,20,2,62])))},{id:"just",name:"Just",import:(()=>c(()=>import("./just-CUsbIsdP.js"),__vite__mapDeps([63,28,2,11,64,1,3,7,8,16,20,33,34,35,36,13,23,24,25,26,37,38])))},{id:"kdl",name:"KDL",import:(()=>c(()=>import("./kdl-DV7GczEv.js"),[]))},{id:"kotlin",name:"Kotlin",aliases:["kt","kts"],import:(()=>c(()=>import("./kotlin-BdnUsdx6.js"),[]))},{id:"kusto",name:"Kusto",aliases:["kql"],import:(()=>c(()=>import("./kusto-wEQ09or8.js"),[]))},{id:"latex",name:"LaTeX",import:(()=>c(()=>import("./latex-CaSxy8MP.js"),__vite__mapDeps([65,66,62])))},{id:"lean",name:"Lean 4",aliases:["lean4"],import:(()=>c(()=>import("./lean-BZvkOJ9d.js"),[]))},{id:"less",name:"Less",import:(()=>c(()=>import("./less-B1dDrJ26.js"),[]))},{id:"liquid",name:"Liquid",import:(()=>c(()=>import("./liquid-C0sCDyMI.js"),__vite__mapDeps([67,1,2,3,9])))},{id:"llvm",name:"LLVM IR",import:(()=>c(()=>import("./llvm-DjAJT7YJ.js"),[]))},{id:"log",name:"Log file",import:(()=>c(()=>import("./log-2UxHyX5q.js"),[]))},{id:"logo",name:"Logo",import:(()=>c(()=>import("./logo-BtOb2qkB.js"),[]))},{id:"lua",name:"Lua",import:(()=>c(()=>import("./lua-BaeVxFsk.js"),__vite__mapDeps([37,26])))},{id:"luau",name:"Luau",import:(()=>c(()=>import("./luau-KW6xsasC.js"),[]))},{id:"make",name:"Makefile",aliases:["makefile"],import:(()=>c(()=>import("./make-CHLpvVh8.js"),[]))},{id:"markdown",name:"Markdown",aliases:["md"],import:(()=>c(()=>import("./markdown-Cvjx9yec.js"),[]))},{id:"marko",name:"Marko",import:(()=>c(()=>import("./marko-DjSrsDqO.js"),__vite__mapDeps([68,3,69,5,11])))},{id:"matlab",name:"MATLAB",import:(()=>c(()=>import("./matlab-D7o27uSR.js"),[]))},{id:"mdc",name:"MDC",import:(()=>c(()=>import("./mdc-DTYItulj.js"),__vite__mapDeps([70,40,38,15,1,2,3])))},{id:"mdx",name:"MDX",import:(()=>c(()=>import("./mdx-Cmh6b_Ma.js"),[]))},{id:"mermaid",name:"Mermaid",aliases:["mmd"],import:(()=>c(()=>import("./mermaid-mWjccvbQ.js"),[]))},{id:"mipsasm",name:"MIPS Assembly",aliases:["mips"],import:(()=>c(()=>import("./mipsasm-CKIfxQSi.js"),[]))},{id:"mojo",name:"Mojo",import:(()=>c(()=>import("./mojo-rZm6bMo-.js"),[]))},{id:"moonbit",name:"MoonBit",aliases:["mbt","mbti"],import:(()=>c(()=>import("./moonbit-_H4v1dQx.js"),[]))},{id:"move",name:"Move",import:(()=>c(()=>import("./move-IF9eRakj.js"),[]))},{id:"narrat",name:"Narrat Language",aliases:["nar"],import:(()=>c(()=>import("./narrat-DRg8JJMk.js"),[]))},{id:"nextflow",name:"Nextflow",aliases:["nf"],import:(()=>c(()=>import("./nextflow-C-mBbutL.js"),__vite__mapDeps([71,72])))},{id:"nextflow-groovy",name:"Nextflow Groovy",import:(()=>c(()=>import("./nextflow-groovy-vE_lwT2v.js"),[]))},{id:"nginx",name:"Nginx",import:(()=>c(()=>import("./nginx-BpAMiNFr.js"),__vite__mapDeps([73,37,26])))},{id:"nim",name:"Nim",import:(()=>c(()=>import("./nim-BIad80T-.js"),__vite__mapDeps([74,26,1,2,3,7,8,25,40])))},{id:"nix",name:"Nix",import:(()=>c(()=>import("./nix-CwoSXNpI.js"),[]))},{id:"nushell",name:"nushell",aliases:["nu"],import:(()=>c(()=>import("./nushell-Cz2AlsmD.js"),[]))},{id:"objective-c",name:"Objective-C",aliases:["objc"],import:(()=>c(()=>import("./objective-c-DXmwc3jG.js"),[]))},{id:"objective-cpp",name:"Objective-C++",import:(()=>c(()=>import("./objective-cpp-CLxacb5B.js"),[]))},{id:"ocaml",name:"OCaml",import:(()=>c(()=>import("./ocaml-C0hk2d4L.js"),[]))},{id:"odin",name:"Odin",import:(()=>c(()=>import("./odin-BBf5iR-q.js"),[]))},{id:"openscad",name:"OpenSCAD",aliases:["scad"],import:(()=>c(()=>import("./openscad-C4EeE6gA.js"),[]))},{id:"pascal",name:"Pascal",import:(()=>c(()=>import("./pascal-D93ZcfNL.js"),[]))},{id:"perl",name:"Perl",import:(()=>c(()=>import("./perl-B9cMNwum.js"),__vite__mapDeps([64,1,2,3,7,8,16])))},{id:"php",name:"PHP",import:(()=>c(()=>import("./php-Csjmro_R.js"),__vite__mapDeps([75,1,2,3,7,8,16,9])))},{id:"pkl",name:"Pkl",import:(()=>c(()=>import("./pkl-u5AG7uiY.js"),[]))},{id:"plsql",name:"PL/SQL",import:(()=>c(()=>import("./plsql-ChMvpjG-.js"),[]))},{id:"po",name:"Gettext PO",aliases:["pot","potx"],import:(()=>c(()=>import("./po-BTJTHyun.js"),[]))},{id:"polar",name:"Polar",import:(()=>c(()=>import("./polar-C0HS_06l.js"),[]))},{id:"postcss",name:"PostCSS",import:(()=>c(()=>import("./postcss-CXtECtnM.js"),[]))},{id:"powerquery",name:"PowerQuery",import:(()=>c(()=>import("./powerquery-CEu0bR-o.js"),[]))},{id:"powershell",name:"PowerShell",aliases:["ps","ps1"],import:(()=>c(()=>import("./powershell-Dpen1YoG.js"),[]))},{id:"prisma",name:"Prisma",import:(()=>c(()=>import("./prisma-Dd19v3D-.js"),[]))},{id:"prolog",name:"Prolog",import:(()=>c(()=>import("./prolog-CbFg5uaA.js"),[]))},{id:"proto",name:"Protocol Buffer 3",aliases:["protobuf"],import:(()=>c(()=>import("./proto-C7zT0LnQ.js"),[]))},{id:"pug",name:"Pug",aliases:["jade"],import:(()=>c(()=>import("./pug-DKIMFp6K.js"),__vite__mapDeps([76,2,3,1])))},{id:"puppet",name:"Puppet",import:(()=>c(()=>import("./puppet-BMWR74SV.js"),[]))},{id:"purescript",name:"PureScript",import:(()=>c(()=>import("./purescript-CklMAg4u.js"),[]))},{id:"python",name:"Python",aliases:["py"],import:(()=>c(()=>import("./python-B6aJPvgy.js"),[]))},{id:"qml",name:"QML",import:(()=>c(()=>import("./qml-3beO22l8.js"),__vite__mapDeps([77,2])))},{id:"qmldir",name:"QML Directory",import:(()=>c(()=>import("./qmldir-C8lEn-DE.js"),[]))},{id:"qss",name:"Qt Style Sheets",import:(()=>c(()=>import("./qss-IeuSbFQv.js"),[]))},{id:"r",name:"R",import:(()=>c(()=>import("./r-Dspwwk_N.js"),[]))},{id:"racket",name:"Racket",import:(()=>c(()=>import("./racket-BqYA7rlc.js"),[]))},{id:"raku",name:"Raku",aliases:["perl6"],import:(()=>c(()=>import("./raku-DXvB9xmW.js"),[]))},{id:"razor",name:"ASP.NET Razor",import:(()=>c(()=>import("./razor-BjBPvh-w.js"),__vite__mapDeps([78,1,2,3,79])))},{id:"reg",name:"Windows Registry Script",import:(()=>c(()=>import("./reg-C-SQnVFl.js"),[]))},{id:"regexp",name:"RegExp",aliases:["regex"],import:(()=>c(()=>import("./regexp-CDVJQ6XC.js"),[]))},{id:"rel",name:"Rel",import:(()=>c(()=>import("./rel-C3B-1QV4.js"),[]))},{id:"riscv",name:"RISC-V",import:(()=>c(()=>import("./riscv-BM1_JUlF.js"),[]))},{id:"ron",name:"RON",import:(()=>c(()=>import("./ron-D8l8udqQ.js"),[]))},{id:"rosmsg",name:"ROS Interface",import:(()=>c(()=>import("./rosmsg-BJDFO7_C.js"),[]))},{id:"rst",name:"reStructuredText",import:(()=>c(()=>import("./rst-CpCqk9r5.js"),__vite__mapDeps([80,15,1,2,3,23,24,25,26,16,20,28,38,81,33,34,7,8,35,11,36,13,37])))},{id:"ruby",name:"Ruby",aliases:["rb"],import:(()=>c(()=>import("./ruby-DyJCeAvU.js"),__vite__mapDeps([33,1,2,3,34,7,8,16,35,11,36,13,23,24,25,26,28,37,38])))},{id:"rust",name:"Rust",aliases:["rs"],import:(()=>c(()=>import("./rust-B1yitclQ.js"),[]))},{id:"sas",name:"SAS",import:(()=>c(()=>import("./sas-DEy46yEz.js"),__vite__mapDeps([82,16])))},{id:"sass",name:"Sass",import:(()=>c(()=>import("./sass-Cj5Yp3dK.js"),[]))},{id:"scala",name:"Scala",import:(()=>c(()=>import("./scala-C151Ov-r.js"),[]))},{id:"scheme",name:"Scheme",import:(()=>c(()=>import("./scheme-C98Dy4si.js"),[]))},{id:"scss",name:"SCSS",import:(()=>c(()=>import("./scss-D5BDwBP9.js"),__vite__mapDeps([5,3])))},{id:"sdbl",name:"1C (Query)",aliases:["1c-query"],import:(()=>c(()=>import("./sdbl-DVxCFoDh.js"),[]))},{id:"shaderlab",name:"ShaderLab",aliases:["shader"],import:(()=>c(()=>import("./shaderlab-Dg9Lc6iA.js"),__vite__mapDeps([83,84])))},{id:"shellscript",name:"Shell",aliases:["bash","sh","shell","zsh"],import:(()=>c(()=>import("./shellscript-Yzrsuije.js"),[]))},{id:"shellsession",name:"Shell Session",aliases:["console"],import:(()=>c(()=>import("./shellsession-BADoaaVG.js"),__vite__mapDeps([85,28])))},{id:"smalltalk",name:"Smalltalk",import:(()=>c(()=>import("./smalltalk-BERRCDM3.js"),[]))},{id:"solidity",name:"Solidity",import:(()=>c(()=>import("./solidity-rGO070M0.js"),[]))},{id:"soy",name:"Closure Templates",aliases:["closure-templates"],import:(()=>c(()=>import("./soy-8wufbnw4.js"),__vite__mapDeps([86,1,2,3])))},{id:"sparql",name:"SPARQL",import:(()=>c(()=>import("./sparql-rVzFXLq3.js"),__vite__mapDeps([87,88])))},{id:"splunk",name:"Splunk Query Language",aliases:["spl"],import:(()=>c(()=>import("./splunk-BtCnVYZw.js"),[]))},{id:"sql",name:"SQL",import:(()=>c(()=>import("./sql-CRqJ_cUM.js"),[]))},{id:"ssh-config",name:"SSH Config",import:(()=>c(()=>import("./ssh-config-_ykCGR6B.js"),[]))},{id:"stata",name:"Stata",import:(()=>c(()=>import("./stata-DI20mbqo.js"),__vite__mapDeps([89,16])))},{id:"stylus",name:"Stylus",aliases:["styl"],import:(()=>c(()=>import("./stylus-BEDo0Tqx.js"),[]))},{id:"surrealql",name:"SurrealQL",aliases:["surql"],import:(()=>c(()=>import("./surrealql-Bq5Q-fJD.js"),__vite__mapDeps([90,2])))},{id:"svelte",name:"Svelte",import:(()=>c(()=>import("./svelte-Cy7k_4gC.js"),__vite__mapDeps([91,2,11,3,12])))},{id:"swift",name:"Swift",import:(()=>c(()=>import("./swift-D82vCrfD.js"),[]))},{id:"system-verilog",name:"SystemVerilog",import:(()=>c(()=>import("./system-verilog-CnnmHF94.js"),[]))},{id:"systemd",name:"Systemd Units",import:(()=>c(()=>import("./systemd-4A_iFExJ.js"),[]))},{id:"talonscript",name:"TalonScript",aliases:["talon"],import:(()=>c(()=>import("./talonscript-CkByrt1z.js"),[]))},{id:"tasl",name:"Tasl",import:(()=>c(()=>import("./tasl-QIJgUcNo.js"),[]))},{id:"tcl",name:"Tcl",import:(()=>c(()=>import("./tcl-dwOrl1Do.js"),[]))},{id:"templ",name:"Templ",import:(()=>c(()=>import("./templ-DhtptRzy.js"),__vite__mapDeps([92,93,2,3])))},{id:"terraform",name:"Terraform",aliases:["tf","tfvars"],import:(()=>c(()=>import("./terraform-BETggiCN.js"),[]))},{id:"tex",name:"TeX",import:(()=>c(()=>import("./tex-idrVyKtj.js"),__vite__mapDeps([66,62])))},{id:"toml",name:"TOML",import:(()=>c(()=>import("./toml-vGWfd6FD.js"),[]))},{id:"ts-tags",name:"TypeScript with Tags",aliases:["lit"],import:(()=>c(()=>import("./ts-tags-D351s5mN.js"),__vite__mapDeps([94,11,3,2,25,26,1,16,7,8])))},{id:"tsv",name:"TSV",import:(()=>c(()=>import("./tsv-B_m7g4N7.js"),[]))},{id:"tsx",name:"TSX",import:(()=>c(()=>import("./tsx-COt5Ahok.js"),[]))},{id:"turtle",name:"Turtle",import:(()=>c(()=>import("./turtle-BsS91CYL.js"),[]))},{id:"twig",name:"Twig",import:(()=>c(()=>import("./twig-CW1WmMYd.js"),__vite__mapDeps([95,3,2,5,75,1,7,8,16,9,20,33,34,35,11,36,13,23,24,25,26,28,37,38])))},{id:"typescript",name:"TypeScript",aliases:["ts","cts","mts"],import:(()=>c(()=>import("./typescript-BPQ3VLAy.js"),[]))},{id:"typespec",name:"TypeSpec",aliases:["tsp"],import:(()=>c(()=>import("./typespec-CAFt9gP4.js"),[]))},{id:"typst",name:"Typst",aliases:["typ"],import:(()=>c(()=>import("./typst-DHCkPAjA.js"),[]))},{id:"v",name:"V",import:(()=>c(()=>import("./v-BcVCzyr7.js"),[]))},{id:"vala",name:"Vala",import:(()=>c(()=>import("./vala-CsfeWuGM.js"),[]))},{id:"vb",name:"Visual Basic",aliases:["cmd"],import:(()=>c(()=>import("./vb-D17OF-Vu.js"),[]))},{id:"verilog",name:"Verilog",import:(()=>c(()=>import("./verilog-BQ8w6xss.js"),[]))},{id:"vhdl",name:"VHDL",import:(()=>c(()=>import("./vhdl-CeAyd5Ju.js"),[]))},{id:"viml",name:"Vim Script",aliases:["vim","vimscript"],import:(()=>c(()=>import("./viml-CJc9bBzg.js"),[]))},{id:"vue",name:"Vue",import:(()=>c(()=>import("./vue-D2xRrEX4.js"),__vite__mapDeps([96,3,2,11,9,1,15])))},{id:"vue-html",name:"Vue HTML",import:(()=>c(()=>import("./vue-html-AaS7Mt5G.js"),__vite__mapDeps([97,2])))},{id:"vue-vine",name:"Vue Vine",import:(()=>c(()=>import("./vue-vine-BoDAl6tE.js"),__vite__mapDeps([98,3,5,69,99,12,2])))},{id:"vyper",name:"Vyper",aliases:["vy"],import:(()=>c(()=>import("./vyper-CDx5xZoG.js"),[]))},{id:"wasm",name:"WebAssembly",import:(()=>c(()=>import("./wasm-MzD3tlZU.js"),[]))},{id:"wenyan",name:"Wenyan",aliases:["文言"],import:(()=>c(()=>import("./wenyan-BV7otONQ.js"),[]))},{id:"wgsl",name:"WGSL",import:(()=>c(()=>import("./wgsl-Dx-B1_4e.js"),[]))},{id:"wikitext",name:"Wikitext",aliases:["mediawiki","wiki"],import:(()=>c(()=>import("./wikitext-BhOHFoWU.js"),[]))},{id:"wit",name:"WebAssembly Interface Types",import:(()=>c(()=>import("./wit-5i3qLPDT.js"),[]))},{id:"wolfram",name:"Wolfram",aliases:["wl"],import:(()=>c(()=>import("./wolfram-lXgVvXCa.js"),[]))},{id:"xml",name:"XML",import:(()=>c(()=>import("./xml-sdJ4AIDG.js"),__vite__mapDeps([7,8])))},{id:"xsl",name:"XSL",import:(()=>c(()=>import("./xsl-CtQFsRM5.js"),__vite__mapDeps([100,7,8])))},{id:"yaml",name:"YAML",aliases:["yml"],import:(()=>c(()=>import("./yaml-Buea-lGh.js"),[]))},{id:"zenscript",name:"ZenScript",import:(()=>c(()=>import("./zenscript-DVFEvuxE.js"),[]))},{id:"zig",name:"Zig",import:(()=>c(()=>import("./zig-VOosw3JB.js"),[]))}],at=Object.fromEntries(Ne.map(e=>[e.id,e.import])),lt=Object.fromEntries(Ne.flatMap(e=>e.aliases?.map(t=>[t,e.import])||[])),ut={...at,...lt},ct=[{id:"andromeeda",displayName:"Andromeeda",type:"dark",import:(()=>c(()=>import("./andromeeda-C4gqWexZ.js"),[]))},{id:"aurora-x",displayName:"Aurora X",type:"dark",import:(()=>c(()=>import("./aurora-x-D-2ljcwZ.js"),[]))},{id:"ayu-dark",displayName:"Ayu Dark",type:"dark",import:(()=>c(()=>import("./ayu-dark-DYE7WIF3.js"),[]))},{id:"ayu-light",displayName:"Ayu Light",type:"light",import:(()=>c(()=>import("./ayu-light-BA47KaF1.js"),[]))},{id:"ayu-mirage",displayName:"Ayu Mirage",type:"dark",import:(()=>c(()=>import("./ayu-mirage-32ctXXKs.js"),[]))},{id:"catppuccin-frappe",displayName:"Catppuccin Frappé",type:"dark",import:(()=>c(()=>import("./catppuccin-frappe-DFWUc33u.js"),[]))},{id:"catppuccin-latte",displayName:"Catppuccin Latte",type:"light",import:(()=>c(()=>import("./catppuccin-latte-C9dUb6Cb.js"),[]))},{id:"catppuccin-macchiato",displayName:"Catppuccin Macchiato",type:"dark",import:(()=>c(()=>import("./catppuccin-macchiato-DQyhUUbL.js"),[]))},{id:"catppuccin-mocha",displayName:"Catppuccin Mocha",type:"dark",import:(()=>c(()=>import("./catppuccin-mocha-D87Tk5Gz.js"),[]))},{id:"dark-plus",displayName:"Dark Plus",type:"dark",import:(()=>c(()=>import("./dark-plus-C3mMm8J8.js"),[]))},{id:"dracula",displayName:"Dracula Theme",type:"dark",import:(()=>c(()=>import("./dracula-BzJJZx-M.js"),[]))},{id:"dracula-soft",displayName:"Dracula Theme Soft",type:"dark",import:(()=>c(()=>import("./dracula-soft-BXkSAIEj.js"),[]))},{id:"everforest-dark",displayName:"Everforest Dark",type:"dark",import:(()=>c(()=>import("./everforest-dark-BgDCqdQA.js"),[]))},{id:"everforest-light",displayName:"Everforest Light",type:"light",import:(()=>c(()=>import("./everforest-light-C8M2exoo.js"),[]))},{id:"github-dark",displayName:"GitHub Dark",type:"dark",import:(()=>c(()=>import("./github-dark-DHJKELXO.js"),[]))},{id:"github-dark-default",displayName:"GitHub Dark Default",type:"dark",import:(()=>c(()=>import("./github-dark-default-Cuk6v7N8.js"),[]))},{id:"github-dark-dimmed",displayName:"GitHub Dark Dimmed",type:"dark",import:(()=>c(()=>import("./github-dark-dimmed-DH5Ifo-i.js"),[]))},{id:"github-dark-high-contrast",displayName:"GitHub Dark High Contrast",type:"dark",import:(()=>c(()=>import("./github-dark-high-contrast-E3gJ1_iC.js"),[]))},{id:"github-light",displayName:"GitHub Light",type:"light",import:(()=>c(()=>import("./github-light-DAi9KRSo.js"),[]))},{id:"github-light-default",displayName:"GitHub Light Default",type:"light",import:(()=>c(()=>import("./github-light-default-D7oLnXFd.js"),[]))},{id:"github-light-high-contrast",displayName:"GitHub Light High Contrast",type:"light",import:(()=>c(()=>import("./github-light-high-contrast-BfjtVDDH.js"),[]))},{id:"gruvbox-dark-hard",displayName:"Gruvbox Dark Hard",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-hard-CFHQjOhq.js"),[]))},{id:"gruvbox-dark-medium",displayName:"Gruvbox Dark Medium",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-medium-GsRaNv29.js"),[]))},{id:"gruvbox-dark-soft",displayName:"Gruvbox Dark Soft",type:"dark",import:(()=>c(()=>import("./gruvbox-dark-soft-CVdnzihN.js"),[]))},{id:"gruvbox-light-hard",displayName:"Gruvbox Light Hard",type:"light",import:(()=>c(()=>import("./gruvbox-light-hard-CH1njM8p.js"),[]))},{id:"gruvbox-light-medium",displayName:"Gruvbox Light Medium",type:"light",import:(()=>c(()=>import("./gruvbox-light-medium-DRw_LuNl.js"),[]))},{id:"gruvbox-light-soft",displayName:"Gruvbox Light Soft",type:"light",import:(()=>c(()=>import("./gruvbox-light-soft-hJgmCMqR.js"),[]))},{id:"horizon",displayName:"Horizon",type:"dark",import:(()=>c(()=>import("./horizon-BUw7H-hv.js"),[]))},{id:"horizon-bright",displayName:"Horizon Bright",type:"light",import:(()=>c(()=>import("./horizon-bright-CUuTKBJd.js"),[]))},{id:"houston",displayName:"Houston",type:"dark",import:(()=>c(()=>import("./houston-DnULxvSX.js"),[]))},{id:"kanagawa-dragon",displayName:"Kanagawa Dragon",type:"dark",import:(()=>c(()=>import("./kanagawa-dragon-CkXjmgJE.js"),[]))},{id:"kanagawa-lotus",displayName:"Kanagawa Lotus",type:"light",import:(()=>c(()=>import("./kanagawa-lotus-CfQXZHmo.js"),[]))},{id:"kanagawa-wave",displayName:"Kanagawa Wave",type:"dark",import:(()=>c(()=>import("./kanagawa-wave-DWedfzmr.js"),[]))},{id:"laserwave",displayName:"LaserWave",type:"dark",import:(()=>c(()=>import("./laserwave-DUszq2jm.js"),[]))},{id:"light-plus",displayName:"Light Plus",type:"light",import:(()=>c(()=>import("./light-plus-B7mTdjB0.js"),[]))},{id:"material-theme",displayName:"Material Theme",type:"dark",import:(()=>c(()=>import("./material-theme-D5KoaKCx.js"),[]))},{id:"material-theme-darker",displayName:"Material Theme Darker",type:"dark",import:(()=>c(()=>import("./material-theme-darker-BfHTSMKl.js"),[]))},{id:"material-theme-lighter",displayName:"Material Theme Lighter",type:"light",import:(()=>c(()=>import("./material-theme-lighter-B0m2ddpp.js"),[]))},{id:"material-theme-ocean",displayName:"Material Theme Ocean",type:"dark",import:(()=>c(()=>import("./material-theme-ocean-CyktbL80.js"),[]))},{id:"material-theme-palenight",displayName:"Material Theme Palenight",type:"dark",import:(()=>c(()=>import("./material-theme-palenight-Csfq5Kiy.js"),[]))},{id:"min-dark",displayName:"Min Dark",type:"dark",import:(()=>c(()=>import("./min-dark-CafNBF8u.js"),[]))},{id:"min-light",displayName:"Min Light",type:"light",import:(()=>c(()=>import("./min-light-CTRr51gU.js"),[]))},{id:"monokai",displayName:"Monokai",type:"dark",import:(()=>c(()=>import("./monokai-D4h5O-jR.js"),[]))},{id:"night-owl",displayName:"Night Owl",type:"dark",import:(()=>c(()=>import("./night-owl-C39BiMTA.js"),[]))},{id:"night-owl-light",displayName:"Night Owl Light",type:"light",import:(()=>c(()=>import("./night-owl-light-CMTm3GFP.js"),[]))},{id:"nord",displayName:"Nord",type:"dark",import:(()=>c(()=>import("./nord-Ddv68eIx.js"),[]))},{id:"one-dark-pro",displayName:"One Dark Pro",type:"dark",import:(()=>c(()=>import("./one-dark-pro-DVMEJ2y_.js"),[]))},{id:"one-light",displayName:"One Light",type:"light",import:(()=>c(()=>import("./one-light-C3Wv6jpd.js"),[]))},{id:"plastic",displayName:"Plastic",type:"dark",import:(()=>c(()=>import("./plastic-3e1v2bzS.js"),[]))},{id:"poimandres",displayName:"Poimandres",type:"dark",import:(()=>c(()=>import("./poimandres-CS3Unz2-.js"),[]))},{id:"red",displayName:"Red",type:"dark",import:(()=>c(()=>import("./red-bN70gL4F.js"),[]))},{id:"rose-pine",displayName:"Rosé Pine",type:"dark",import:(()=>c(()=>import("./rose-pine-qdsjHGoJ.js"),[]))},{id:"rose-pine-dawn",displayName:"Rosé Pine Dawn",type:"light",import:(()=>c(()=>import("./rose-pine-dawn-DHQR4-dF.js"),[]))},{id:"rose-pine-moon",displayName:"Rosé Pine Moon",type:"dark",import:(()=>c(()=>import("./rose-pine-moon-D4_iv3hh.js"),[]))},{id:"slack-dark",displayName:"Slack Dark",type:"dark",import:(()=>c(()=>import("./slack-dark-BthQWCQV.js"),[]))},{id:"slack-ochin",displayName:"Slack Ochin",type:"light",import:(()=>c(()=>import("./slack-ochin-DqwNpetd.js"),[]))},{id:"snazzy-light",displayName:"Snazzy Light",type:"light",import:(()=>c(()=>import("./snazzy-light-Bw305WKR.js"),[]))},{id:"solarized-dark",displayName:"Solarized Dark",type:"dark",import:(()=>c(()=>import("./solarized-dark-DXbdFlpD.js"),[]))},{id:"solarized-light",displayName:"Solarized Light",type:"light",import:(()=>c(()=>import("./solarized-light-L9t79GZl.js"),[]))},{id:"synthwave-84",displayName:"Synthwave '84",type:"dark",import:(()=>c(()=>import("./synthwave-84-CbfX1IO0.js"),[]))},{id:"tokyo-night",displayName:"Tokyo Night",type:"dark",import:(()=>c(()=>import("./tokyo-night-hegEt444.js"),[]))},{id:"vesper",displayName:"Vesper",type:"dark",import:(()=>c(()=>import("./vesper-DRje8inN.js"),[]))},{id:"vitesse-black",displayName:"Vitesse Black",type:"dark",import:(()=>c(()=>import("./vitesse-black-Bkuqu6BP.js"),[]))},{id:"vitesse-dark",displayName:"Vitesse Dark",type:"dark",import:(()=>c(()=>import("./vitesse-dark-D0r3Knsf.js"),[]))},{id:"vitesse-light",displayName:"Vitesse Light",type:"light",import:(()=>c(()=>import("./vitesse-light-CVO1_9PV.js"),[]))}],dt=Object.fromEntries(ct.map(e=>[e.id,e.import]));var ln=class extends Error{constructor(t){super(t),this.name="ShikiError"}};function io(){return 2147483648}function oo(){return typeof performance<"u"?performance.now():Date.now()}const so=(e,t)=>e+(t-e%t)%t;async function ao(e){let t,n;const r={};function i(h){n=h,r.HEAPU8=new Uint8Array(h),r.HEAPU32=new Uint32Array(h)}function o(h,m,E){r.HEAPU8.copyWithin(h,m,m+E)}function s(h){try{return t.grow(h-n.byteLength+65535>>>16),i(t.buffer),1}catch{}}function a(h){const m=r.HEAPU8.length;h=h>>>0;const E=io();if(h>E)return!1;for(let b=1;b<=4;b*=2){let g=m*(1+.2/b);g=Math.min(g,h+100663296);const y=Math.min(E,so(Math.max(h,g),65536));if(s(y))return!0}return!1}const l=typeof TextDecoder<"u"?new TextDecoder("utf8"):void 0;function u(h,m,E=1024){const b=m+E;let g=m;for(;h[g]&&!(g>=b);)++g;if(g-m>16&&h.buffer&&l)return l.decode(h.subarray(m,g));let y="";for(;m<g;){let w=h[m++];if(!(w&128)){y+=String.fromCharCode(w);continue}const A=h[m++]&63;if((w&224)===192){y+=String.fromCharCode((w&31)<<6|A);continue}const k=h[m++]&63;if((w&240)===224?w=(w&15)<<12|A<<6|k:w=(w&7)<<18|A<<12|k<<6|h[m++]&63,w<65536)y+=String.fromCharCode(w);else{const I=w-65536;y+=String.fromCharCode(55296|I>>10,56320|I&1023)}}return y}function p(h,m){return h?u(r.HEAPU8,h,m):""}const d={emscripten_get_now:oo,emscripten_memcpy_big:o,emscripten_resize_heap:a,fd_write:()=>0};async function f(){const m=await e({env:d,wasi_snapshot_preview1:d});t=m.memory,i(t.buffer),Object.assign(r,m),r.UTF8ToString=p}return await f(),r}var lo=Object.defineProperty,uo=(e,t,n)=>t in e?lo(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,P=(e,t,n)=>uo(e,typeof t!="symbol"?t+"":t,n);let D=null;function co(e){throw new ln(e.UTF8ToString(e.getLastOnigError()))}class pt{constructor(t){P(this,"utf16Length"),P(this,"utf8Length"),P(this,"utf16Value"),P(this,"utf8Value"),P(this,"utf16OffsetToUtf8"),P(this,"utf8OffsetToUtf16");const n=t.length,r=pt._utf8ByteLength(t),i=r!==n,o=i?new Uint32Array(n+1):null;i&&(o[n]=r);const s=i?new Uint32Array(r+1):null;i&&(s[r]=n);const a=new Uint8Array(r);let l=0;for(let u=0;u<n;u++){const p=t.charCodeAt(u);let d=p,f=!1;if(p>=55296&&p<=56319&&u+1<n){const h=t.charCodeAt(u+1);h>=56320&&h<=57343&&(d=(p-55296<<10)+65536|h-56320,f=!0)}i&&(o[u]=l,f&&(o[u+1]=l),d<=127?s[l+0]=u:d<=2047?(s[l+0]=u,s[l+1]=u):d<=65535?(s[l+0]=u,s[l+1]=u,s[l+2]=u):(s[l+0]=u,s[l+1]=u,s[l+2]=u,s[l+3]=u)),d<=127?a[l++]=d:d<=2047?(a[l++]=192|(d&1984)>>>6,a[l++]=128|(d&63)>>>0):d<=65535?(a[l++]=224|(d&61440)>>>12,a[l++]=128|(d&4032)>>>6,a[l++]=128|(d&63)>>>0):(a[l++]=240|(d&1835008)>>>18,a[l++]=128|(d&258048)>>>12,a[l++]=128|(d&4032)>>>6,a[l++]=128|(d&63)>>>0),f&&u++}this.utf16Length=n,this.utf8Length=r,this.utf16Value=t,this.utf8Value=a,this.utf16OffsetToUtf8=o,this.utf8OffsetToUtf16=s}static _utf8ByteLength(t){let n=0;for(let r=0,i=t.length;r<i;r++){const o=t.charCodeAt(r);let s=o,a=!1;if(o>=55296&&o<=56319&&r+1<i){const l=t.charCodeAt(r+1);l>=56320&&l<=57343&&(s=(o-55296<<10)+65536|l-56320,a=!0)}s<=127?n+=1:s<=2047?n+=2:s<=65535?n+=3:n+=4,a&&r++}return n}createString(t){const n=t.omalloc(this.utf8Length);return t.HEAPU8.set(this.utf8Value,n),n}}const ht=class X{constructor(t){if(P(this,"id",++X.LAST_ID),P(this,"_onigBinding"),P(this,"content"),P(this,"utf16Length"),P(this,"utf8Length"),P(this,"utf16OffsetToUtf8"),P(this,"utf8OffsetToUtf16"),P(this,"ptr"),!D)throw new ln("Must invoke loadWasm first.");this._onigBinding=D,this.content=t;const n=new pt(t);this.utf16Length=n.utf16Length,this.utf8Length=n.utf8Length,this.utf16OffsetToUtf8=n.utf16OffsetToUtf8,this.utf8OffsetToUtf16=n.utf8OffsetToUtf16,this.utf8Length<1e4&&!X._sharedPtrInUse?(X._sharedPtr||(X._sharedPtr=D.omalloc(1e4)),X._sharedPtrInUse=!0,D.HEAPU8.set(n.utf8Value,X._sharedPtr),this.ptr=X._sharedPtr):this.ptr=n.createString(D)}convertUtf8OffsetToUtf16(t){return this.utf8OffsetToUtf16?t<0?0:t>this.utf8Length?this.utf16Length:this.utf8OffsetToUtf16[t]:t}convertUtf16OffsetToUtf8(t){return this.utf16OffsetToUtf8?t<0?0:t>this.utf16Length?this.utf8Length:this.utf16OffsetToUtf8[t]:t}dispose(){this.ptr===X._sharedPtr?X._sharedPtrInUse=!1:this._onigBinding.ofree(this.ptr)}};P(ht,"LAST_ID",0);P(ht,"_sharedPtr",0);P(ht,"_sharedPtrInUse",!1);let Lr=ht;class po{constructor(t){if(P(this,"_onigBinding"),P(this,"_ptr"),!D)throw new ln("Must invoke loadWasm first.");const n=[],r=[];for(let a=0,l=t.length;a<l;a++){const u=new pt(t[a]);n[a]=u.createString(D),r[a]=u.utf8Length}const i=D.omalloc(4*t.length);D.HEAPU32.set(n,i/4);const o=D.omalloc(4*t.length);D.HEAPU32.set(r,o/4);const s=D.createOnigScanner(i,o,t.length);for(let a=0,l=t.length;a<l;a++)D.ofree(n[a]);D.ofree(o),D.ofree(i),s===0&&co(D),this._onigBinding=D,this._ptr=s}dispose(){this._onigBinding.freeOnigScanner(this._ptr)}findNextMatchSync(t,n,r){let i=0;if(typeof r=="number"&&(i=r),typeof t=="string"){t=new Lr(t);const o=this._findNextMatchSync(t,n,!1,i);return t.dispose(),o}return this._findNextMatchSync(t,n,!1,i)}_findNextMatchSync(t,n,r,i){const o=this._onigBinding,s=o.findNextOnigScannerMatch(this._ptr,t.id,t.ptr,t.utf8Length,t.convertUtf16OffsetToUtf8(n),i);if(s===0)return null;const a=o.HEAPU32;let l=s/4;const u=a[l++],p=a[l++],d=[];for(let f=0;f<p;f++){const h=t.convertUtf8OffsetToUtf16(a[l++]),m=t.convertUtf8OffsetToUtf16(a[l++]);d[f]={start:h,end:m,length:m-h}}return{index:u,captureIndices:d}}}function ho(e){return typeof e.instantiator=="function"}function fo(e){return typeof e.default=="function"}function mo(e){return typeof e.data<"u"}function go(e){return typeof Response<"u"&&e instanceof Response}function _o(e){return typeof ArrayBuffer<"u"&&(e instanceof ArrayBuffer||ArrayBuffer.isView(e))||typeof Buffer<"u"&&Buffer.isBuffer?.(e)||typeof SharedArrayBuffer<"u"&&e instanceof SharedArrayBuffer||typeof Uint32Array<"u"&&e instanceof Uint32Array}let Fe;function ft(e){if(Fe)return Fe;async function t(){D=await ao(async n=>{let r=e;return r=await r,typeof r=="function"&&(r=await r(n)),typeof r=="function"&&(r=await r(n)),ho(r)?r=await r.instantiator(n):fo(r)?r=await r.default(n):(mo(r)&&(r=r.data),go(r)?typeof WebAssembly.instantiateStreaming=="function"?r=await yo(r)(n):r=await Eo(r)(n):_o(r)?r=await Lt(r)(n):r instanceof WebAssembly.Module?r=await Lt(r)(n):"default"in r&&r.default instanceof WebAssembly.Module&&(r=await Lt(r.default)(n))),"instance"in r&&(r=r.instance),"exports"in r&&(r=r.exports),r})}return Fe=t(),Fe}function Lt(e){return t=>WebAssembly.instantiate(e,t)}function yo(e){return t=>WebAssembly.instantiateStreaming(e,t)}function Eo(e){return async t=>{const n=await e.arrayBuffer();return WebAssembly.instantiate(n,t)}}let Rr;function bo(e){Rr=e}function wo(){return Rr}async function un(e){return e&&await ft(e),{createScanner(t){return new po(t.map(n=>typeof n=="string"?n:n.source))},createString(t){return new Lr(t)}}}const vo=Object.freeze(Object.defineProperty({__proto__:null,createOnigurumaEngine:un,getDefaultWasmLoader:wo,loadWasm:ft,setDefaultWasmLoader:bo},Symbol.toStringTag,{value:"Module"}));var Ir=an({});Sr(Ir,vo);var L=class extends Error{constructor(e){super(e),this.name="ShikiError"}};function Co(e){return cn(e)}function cn(e){return Array.isArray(e)?Ao(e):e instanceof RegExp?e:typeof e=="object"?ko(e):e}function Ao(e){let t=[];for(let n=0,r=e.length;n<r;n++)t[n]=cn(e[n]);return t}function ko(e){let t={};for(let n in e)t[n]=cn(e[n]);return t}function Tr(e,...t){return t.forEach(n=>{for(let r in n)e[r]=n[r]}),e}function Pr(e){const t=~e.lastIndexOf("/")||~e.lastIndexOf("\\");return t===0?e:~t===e.length-1?Pr(e.substring(0,e.length-1)):e.substr(~t+1)}var Rt=/\$(\d+)|\${(\d+):\/(downcase|upcase)}/g,je=class{static hasCaptures(e){return e===null?!1:(Rt.lastIndex=0,Rt.test(e))}static replaceCaptures(e,t,n){return e.replace(Rt,(r,i,o,s)=>{let a=n[parseInt(i||o,10)];if(a){let l=t.substring(a.start,a.end);for(;l[0]===".";)l=l.substring(1);switch(s){case"downcase":return l.toLowerCase();case"upcase":return l.toUpperCase();default:return l}}else return r})}};function Or(e,t){return e<t?-1:e>t?1:0}function xr(e,t){if(e===null&&t===null)return 0;if(!e)return-1;if(!t)return 1;let n=e.length,r=t.length;if(n===r){for(let i=0;i<n;i++){let o=Or(e[i],t[i]);if(o!==0)return o}return 0}return n-r}function $n(e){return!!(/^#[0-9a-f]{6}$/i.test(e)||/^#[0-9a-f]{8}$/i.test(e)||/^#[0-9a-f]{3}$/i.test(e)||/^#[0-9a-f]{4}$/i.test(e))}function Dr(e){return e.replace(/[\-\\\{\}\*\+\?\|\^\$\.\,\[\]\(\)\#\s]/g,"\\$&")}var Nr=class{constructor(e){this.fn=e}cache=new Map;get(e){if(this.cache.has(e))return this.cache.get(e);const t=this.fn(e);return this.cache.set(e,t),t}},Ye=class{constructor(e,t,n){this._colorMap=e,this._defaults=t,this._root=n}static createFromRawTheme(e,t){return this.createFromParsedTheme(Ro(e),t)}static createFromParsedTheme(e,t){return To(e,t)}_cachedMatchRoot=new Nr(e=>this._root.match(e));getColorMap(){return this._colorMap.getColorMap()}getDefaults(){return this._defaults}match(e){if(e===null)return this._defaults;const t=e.scopeName,r=this._cachedMatchRoot.get(t).find(i=>So(e.parent,i.parentScopes));return r?new Vr(r.fontStyle,r.foreground,r.background):null}},It=class Ke{constructor(t,n){this.parent=t,this.scopeName=n}static push(t,n){for(const r of n)t=new Ke(t,r);return t}static from(...t){let n=null;for(let r=0;r<t.length;r++)n=new Ke(n,t[r]);return n}push(t){return new Ke(this,t)}getSegments(){let t=this;const n=[];for(;t;)n.push(t.scopeName),t=t.parent;return n.reverse(),n}toString(){return this.getSegments().join(" ")}extends(t){return this===t?!0:this.parent===null?!1:this.parent.extends(t)}getExtensionIfDefined(t){const n=[];let r=this;for(;r&&r!==t;)n.push(r.scopeName),r=r.parent;return r===t?n.reverse():void 0}};function So(e,t){if(t.length===0)return!0;for(let n=0;n<t.length;n++){let r=t[n],i=!1;if(r===">"){if(n===t.length-1)return!1;r=t[++n],i=!0}for(;e&&!Lo(e.scopeName,r);){if(i)return!1;e=e.parent}if(!e)return!1;e=e.parent}return!0}function Lo(e,t){return t===e||e.startsWith(t)&&e[t.length]==="."}var Vr=class{constructor(e,t,n){this.fontStyle=e,this.foregroundId=t,this.backgroundId=n}};function Ro(e){if(!e)return[];if(!e.settings||!Array.isArray(e.settings))return[];let t=e.settings,n=[],r=0;for(let i=0,o=t.length;i<o;i++){let s=t[i];if(!s.settings)continue;let a;if(typeof s.scope=="string"){let d=s.scope;d=d.replace(/^[,]+/,""),d=d.replace(/[,]+$/,""),a=d.split(",")}else Array.isArray(s.scope)?a=s.scope:a=[""];let l=-1;if(typeof s.settings.fontStyle=="string"){l=0;let d=s.settings.fontStyle.split(" ");for(let f=0,h=d.length;f<h;f++)switch(d[f]){case"italic":l=l|1;break;case"bold":l=l|2;break;case"underline":l=l|4;break;case"strikethrough":l=l|8;break}}let u=null;typeof s.settings.foreground=="string"&&$n(s.settings.foreground)&&(u=s.settings.foreground);let p=null;typeof s.settings.background=="string"&&$n(s.settings.background)&&(p=s.settings.background);for(let d=0,f=a.length;d<f;d++){let m=a[d].trim().split(" "),E=m[m.length-1],b=null;m.length>1&&(b=m.slice(0,m.length-1),b.reverse()),n[r++]=new Io(E,b,i,l,u,p)}}return n}var Io=class{constructor(e,t,n,r,i,o){this.scope=e,this.parentScopes=t,this.index=n,this.fontStyle=r,this.foreground=i,this.background=o}},$=(e=>(e[e.NotSet=-1]="NotSet",e[e.None=0]="None",e[e.Italic=1]="Italic",e[e.Bold=2]="Bold",e[e.Underline=4]="Underline",e[e.Strikethrough=8]="Strikethrough",e))($||{});function To(e,t){e.sort((l,u)=>{let p=Or(l.scope,u.scope);return p!==0||(p=xr(l.parentScopes,u.parentScopes),p!==0)?p:l.index-u.index});let n=0,r="#000000",i="#ffffff";for(;e.length>=1&&e[0].scope==="";){let l=e.shift();l.fontStyle!==-1&&(n=l.fontStyle),l.foreground!==null&&(r=l.foreground),l.background!==null&&(i=l.background)}let o=new Po(t),s=new Vr(n,o.getId(r),o.getId(i)),a=new xo(new jt(0,null,-1,0,0),[]);for(let l=0,u=e.length;l<u;l++){let p=e[l];a.insert(0,p.scope,p.parentScopes,p.fontStyle,o.getId(p.foreground),o.getId(p.background))}return new Ye(o,s,a)}var Po=class{_isFrozen;_lastColorId;_id2color;_color2id;constructor(e){if(this._lastColorId=0,this._id2color=[],this._color2id=Object.create(null),Array.isArray(e)){this._isFrozen=!0;for(let t=0,n=e.length;t<n;t++)this._color2id[e[t]]=t,this._id2color[t]=e[t]}else this._isFrozen=!1}getId(e){if(e===null)return 0;e=e.toUpperCase();let t=this._color2id[e];if(t)return t;if(this._isFrozen)throw new Error(`Missing color in color map - ${e}`);return t=++this._lastColorId,this._color2id[e]=t,this._id2color[t]=e,t}getColorMap(){return this._id2color.slice(0)}},Oo=Object.freeze([]),jt=class $r{scopeDepth;parentScopes;fontStyle;foreground;background;constructor(t,n,r,i,o){this.scopeDepth=t,this.parentScopes=n||Oo,this.fontStyle=r,this.foreground=i,this.background=o}clone(){return new $r(this.scopeDepth,this.parentScopes,this.fontStyle,this.foreground,this.background)}static cloneArr(t){let n=[];for(let r=0,i=t.length;r<i;r++)n[r]=t[r].clone();return n}acceptOverwrite(t,n,r,i){this.scopeDepth>t?console.log("how did this happen?"):this.scopeDepth=t,n!==-1&&(this.fontStyle=n),r!==0&&(this.foreground=r),i!==0&&(this.background=i)}},xo=class Ht{constructor(t,n=[],r={}){this._mainRule=t,this._children=r,this._rulesWithParentScopes=n}_rulesWithParentScopes;static _cmpBySpecificity(t,n){if(t.scopeDepth!==n.scopeDepth)return n.scopeDepth-t.scopeDepth;let r=0,i=0;for(;t.parentScopes[r]===">"&&r++,n.parentScopes[i]===">"&&i++,!(r>=t.parentScopes.length||i>=n.parentScopes.length);){const o=n.parentScopes[i].length-t.parentScopes[r].length;if(o!==0)return o;r++,i++}return n.parentScopes.length-t.parentScopes.length}match(t){if(t!==""){let r=t.indexOf("."),i,o;if(r===-1?(i=t,o=""):(i=t.substring(0,r),o=t.substring(r+1)),this._children.hasOwnProperty(i))return this._children[i].match(o)}const n=this._rulesWithParentScopes.concat(this._mainRule);return n.sort(Ht._cmpBySpecificity),n}insert(t,n,r,i,o,s){if(n===""){this._doInsertHere(t,r,i,o,s);return}let a=n.indexOf("."),l,u;a===-1?(l=n,u=""):(l=n.substring(0,a),u=n.substring(a+1));let p;this._children.hasOwnProperty(l)?p=this._children[l]:(p=new Ht(this._mainRule.clone(),jt.cloneArr(this._rulesWithParentScopes)),this._children[l]=p),p.insert(t+1,u,r,i,o,s)}_doInsertHere(t,n,r,i,o){if(n===null){this._mainRule.acceptOverwrite(t,r,i,o);return}for(let s=0,a=this._rulesWithParentScopes.length;s<a;s++){let l=this._rulesWithParentScopes[s];if(xr(l.parentScopes,n)===0){l.acceptOverwrite(t,r,i,o);return}}r===-1&&(r=this._mainRule.fontStyle),i===0&&(i=this._mainRule.foreground),o===0&&(o=this._mainRule.background),this._rulesWithParentScopes.push(new jt(t,n,r,i,o))}},le=class U{static toBinaryStr(t){return t.toString(2).padStart(32,"0")}static print(t){const n=U.getLanguageId(t),r=U.getTokenType(t),i=U.getFontStyle(t),o=U.getForeground(t),s=U.getBackground(t);console.log({languageId:n,tokenType:r,fontStyle:i,foreground:o,background:s})}static getLanguageId(t){return(t&255)>>>0}static getTokenType(t){return(t&768)>>>8}static containsBalancedBrackets(t){return(t&1024)!==0}static getFontStyle(t){return(t&30720)>>>11}static getForeground(t){return(t&16744448)>>>15}static getBackground(t){return(t&4278190080)>>>24}static set(t,n,r,i,o,s,a){let l=U.getLanguageId(t),u=U.getTokenType(t),p=U.containsBalancedBrackets(t)?1:0,d=U.getFontStyle(t),f=U.getForeground(t),h=U.getBackground(t);return n!==0&&(l=n),r!==8&&(u=r),i!==null&&(p=i?1:0),o!==-1&&(d=o),s!==0&&(f=s),a!==0&&(h=a),(l<<0|u<<8|p<<10|d<<11|f<<15|h<<24)>>>0}};function Ze(e,t){const n=[],r=Do(e);let i=r.next();for(;i!==null;){let l=0;if(i.length===2&&i.charAt(1)===":"){switch(i.charAt(0)){case"R":l=1;break;case"L":l=-1;break;default:console.log(`Unknown priority ${i} in scope selector`)}i=r.next()}let u=s();if(n.push({matcher:u,priority:l}),i!==",")break;i=r.next()}return n;function o(){if(i==="-"){i=r.next();const l=o();return u=>!!l&&!l(u)}if(i==="("){i=r.next();const l=a();return i===")"&&(i=r.next()),l}if(Mn(i)){const l=[];do l.push(i),i=r.next();while(Mn(i));return u=>t(l,u)}return null}function s(){const l=[];let u=o();for(;u;)l.push(u),u=o();return p=>l.every(d=>d(p))}function a(){const l=[];let u=s();for(;u&&(l.push(u),i==="|"||i===",");){do i=r.next();while(i==="|"||i===",");u=s()}return p=>l.some(d=>d(p))}}function Mn(e){return!!e&&!!e.match(/[\w\.:]+/)}function Do(e){let t=/([LR]:|[\w\.:][\w\.:\-]*|[\,\|\-\(\)])/g,n=t.exec(e);return{next:()=>{if(!n)return null;const r=n[0];return n=t.exec(e),r}}}function Mr(e){typeof e.dispose=="function"&&e.dispose()}var Se=class{constructor(e){this.scopeName=e}toKey(){return this.scopeName}},No=class{constructor(e,t){this.scopeName=e,this.ruleName=t}toKey(){return`${this.scopeName}#${this.ruleName}`}},Vo=class{_references=[];_seenReferenceKeys=new Set;get references(){return this._references}visitedRule=new Set;add(e){const t=e.toKey();this._seenReferenceKeys.has(t)||(this._seenReferenceKeys.add(t),this._references.push(e))}},$o=class{constructor(e,t){this.repo=e,this.initialScopeName=t,this.seenFullScopeRequests.add(this.initialScopeName),this.Q=[new Se(this.initialScopeName)]}seenFullScopeRequests=new Set;seenPartialScopeRequests=new Set;Q;processQueue(){const e=this.Q;this.Q=[];const t=new Vo;for(const n of e)Mo(n,this.initialScopeName,this.repo,t);for(const n of t.references)if(n instanceof Se){if(this.seenFullScopeRequests.has(n.scopeName))continue;this.seenFullScopeRequests.add(n.scopeName),this.Q.push(n)}else{if(this.seenFullScopeRequests.has(n.scopeName)||this.seenPartialScopeRequests.has(n.toKey()))continue;this.seenPartialScopeRequests.add(n.toKey()),this.Q.push(n)}}};function Mo(e,t,n,r){const i=n.lookup(e.scopeName);if(!i){if(e.scopeName===t)throw new Error(`No grammar provided for <${t}>`);return}const o=n.lookup(t);e instanceof Se?Qe({baseGrammar:o,selfGrammar:i},r):Wt(e.ruleName,{baseGrammar:o,selfGrammar:i,repository:i.repository},r);const s=n.injections(e.scopeName);if(s)for(const a of s)r.add(new Se(a))}function Wt(e,t,n){if(t.repository&&t.repository[e]){const r=t.repository[e];et([r],t,n)}}function Qe(e,t){e.selfGrammar.patterns&&Array.isArray(e.selfGrammar.patterns)&&et(e.selfGrammar.patterns,{...e,repository:e.selfGrammar.repository},t),e.selfGrammar.injections&&et(Object.values(e.selfGrammar.injections),{...e,repository:e.selfGrammar.repository},t)}function et(e,t,n){for(const r of e){if(n.visitedRule.has(r))continue;n.visitedRule.add(r);const i=r.repository?Tr({},t.repository,r.repository):t.repository;Array.isArray(r.patterns)&&et(r.patterns,{...t,repository:i},n);const o=r.include;if(!o)continue;const s=Gr(o);switch(s.kind){case 0:Qe({...t,selfGrammar:t.baseGrammar},n);break;case 1:Qe(t,n);break;case 2:Wt(s.ruleName,{...t,repository:i},n);break;case 3:case 4:const a=s.scopeName===t.selfGrammar.scopeName?t.selfGrammar:s.scopeName===t.baseGrammar.scopeName?t.baseGrammar:void 0;if(a){const l={baseGrammar:t.baseGrammar,selfGrammar:a,repository:i};s.kind===4?Wt(s.ruleName,l,n):Qe(l,n)}else s.kind===4?n.add(new No(s.scopeName,s.ruleName)):n.add(new Se(s.scopeName));break}}}var Go=class{kind=0},Bo=class{kind=1},Uo=class{constructor(e){this.ruleName=e}kind=2},Fo=class{constructor(e){this.scopeName=e}kind=3},jo=class{constructor(e,t){this.scopeName=e,this.ruleName=t}kind=4};function Gr(e){if(e==="$base")return new Go;if(e==="$self")return new Bo;const t=e.indexOf("#");if(t===-1)return new Fo(e);if(t===0)return new Uo(e.substring(1));{const n=e.substring(0,t),r=e.substring(t+1);return new jo(n,r)}}var Ho=/\\(\d+)/,Gn=/\\(\d+)/g,Wo=-1,Br=-2;var Ve=class{$location;id;_nameIsCapturing;_name;_contentNameIsCapturing;_contentName;constructor(e,t,n,r){this.$location=e,this.id=t,this._name=n||null,this._nameIsCapturing=je.hasCaptures(this._name),this._contentName=r||null,this._contentNameIsCapturing=je.hasCaptures(this._contentName)}get debugName(){const e=this.$location?`${Pr(this.$location.filename)}:${this.$location.line}`:"unknown";return`${this.constructor.name}#${this.id} @ ${e}`}getName(e,t){return!this._nameIsCapturing||this._name===null||e===null||t===null?this._name:je.replaceCaptures(this._name,e,t)}getContentName(e,t){return!this._contentNameIsCapturing||this._contentName===null?this._contentName:je.replaceCaptures(this._contentName,e,t)}},zo=class extends Ve{retokenizeCapturedWithRuleId;constructor(e,t,n,r,i){super(e,t,n,r),this.retokenizeCapturedWithRuleId=i}dispose(){}collectPatterns(e,t){throw new Error("Not supported!")}compile(e,t){throw new Error("Not supported!")}compileAG(e,t,n,r){throw new Error("Not supported!")}},qo=class extends Ve{_match;captures;_cachedCompiledPatterns;constructor(e,t,n,r,i){super(e,t,n,null),this._match=new Le(r,this.id),this.captures=i,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugMatchRegExp(){return`${this._match.source}`}collectPatterns(e,t){t.push(this._match)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new Re,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},Bn=class extends Ve{hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,r,i){super(e,t,n,r),this.patterns=i.patterns,this.hasMissingPatterns=i.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}collectPatterns(e,t){for(const n of this.patterns)e.getRule(n).collectPatterns(e,t)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){return this._cachedCompiledPatterns||(this._cachedCompiledPatterns=new Re,this.collectPatterns(e,this._cachedCompiledPatterns)),this._cachedCompiledPatterns}},zt=class extends Ve{_begin;beginCaptures;_end;endHasBackReferences;endCaptures;applyEndPatternLast;hasMissingPatterns;patterns;_cachedCompiledPatterns;constructor(e,t,n,r,i,o,s,a,l,u){super(e,t,n,r),this._begin=new Le(i,this.id),this.beginCaptures=o,this._end=new Le(s||"￿",-1),this.endHasBackReferences=this._end.hasBackReferences,this.endCaptures=a,this.applyEndPatternLast=l||!1,this.patterns=u.patterns,this.hasMissingPatterns=u.hasMissingPatterns,this._cachedCompiledPatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugEndRegExp(){return`${this._end.source}`}getEndWithResolvedBackReferences(e,t){return this._end.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e,t).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e,t).compileAG(e,n,r)}_getCachedCompiledPatterns(e,t){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new Re;for(const n of this.patterns)e.getRule(n).collectPatterns(e,this._cachedCompiledPatterns);this.applyEndPatternLast?this._cachedCompiledPatterns.push(this._end.hasBackReferences?this._end.clone():this._end):this._cachedCompiledPatterns.unshift(this._end.hasBackReferences?this._end.clone():this._end)}return this._end.hasBackReferences&&(this.applyEndPatternLast?this._cachedCompiledPatterns.setSource(this._cachedCompiledPatterns.length()-1,t):this._cachedCompiledPatterns.setSource(0,t)),this._cachedCompiledPatterns}},tt=class extends Ve{_begin;beginCaptures;whileCaptures;_while;whileHasBackReferences;hasMissingPatterns;patterns;_cachedCompiledPatterns;_cachedCompiledWhilePatterns;constructor(e,t,n,r,i,o,s,a,l){super(e,t,n,r),this._begin=new Le(i,this.id),this.beginCaptures=o,this.whileCaptures=a,this._while=new Le(s,Br),this.whileHasBackReferences=this._while.hasBackReferences,this.patterns=l.patterns,this.hasMissingPatterns=l.hasMissingPatterns,this._cachedCompiledPatterns=null,this._cachedCompiledWhilePatterns=null}dispose(){this._cachedCompiledPatterns&&(this._cachedCompiledPatterns.dispose(),this._cachedCompiledPatterns=null),this._cachedCompiledWhilePatterns&&(this._cachedCompiledWhilePatterns.dispose(),this._cachedCompiledWhilePatterns=null)}get debugBeginRegExp(){return`${this._begin.source}`}get debugWhileRegExp(){return`${this._while.source}`}getWhileWithResolvedBackReferences(e,t){return this._while.resolveBackReferences(e,t)}collectPatterns(e,t){t.push(this._begin)}compile(e,t){return this._getCachedCompiledPatterns(e).compile(e)}compileAG(e,t,n,r){return this._getCachedCompiledPatterns(e).compileAG(e,n,r)}_getCachedCompiledPatterns(e){if(!this._cachedCompiledPatterns){this._cachedCompiledPatterns=new Re;for(const t of this.patterns)e.getRule(t).collectPatterns(e,this._cachedCompiledPatterns)}return this._cachedCompiledPatterns}compileWhile(e,t){return this._getCachedCompiledWhilePatterns(e,t).compile(e)}compileWhileAG(e,t,n,r){return this._getCachedCompiledWhilePatterns(e,t).compileAG(e,n,r)}_getCachedCompiledWhilePatterns(e,t){return this._cachedCompiledWhilePatterns||(this._cachedCompiledWhilePatterns=new Re,this._cachedCompiledWhilePatterns.push(this._while.hasBackReferences?this._while.clone():this._while)),this._while.hasBackReferences&&this._cachedCompiledWhilePatterns.setSource(0,t||"￿"),this._cachedCompiledWhilePatterns}},Ur=class V{static createCaptureRule(t,n,r,i,o){return t.registerRule(s=>new zo(n,s,r,i,o))}static getCompiledRuleId(t,n,r){return t.id||n.registerRule(i=>{if(t.id=i,t.match)return new qo(t.$vscodeTextmateLocation,t.id,t.name,t.match,V._compileCaptures(t.captures,n,r));if(typeof t.begin>"u"){t.repository&&(r=Tr({},r,t.repository));let o=t.patterns;return typeof o>"u"&&t.include&&(o=[{include:t.include}]),new Bn(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,V._compilePatterns(o,n,r))}return t.while?new tt(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,V._compileCaptures(t.beginCaptures||t.captures,n,r),t.while,V._compileCaptures(t.whileCaptures||t.captures,n,r),V._compilePatterns(t.patterns,n,r)):new zt(t.$vscodeTextmateLocation,t.id,t.name,t.contentName,t.begin,V._compileCaptures(t.beginCaptures||t.captures,n,r),t.end,V._compileCaptures(t.endCaptures||t.captures,n,r),t.applyEndPatternLast,V._compilePatterns(t.patterns,n,r))}),t.id}static _compileCaptures(t,n,r){let i=[];if(t){let o=0;for(const s in t){if(s==="$vscodeTextmateLocation")continue;const a=parseInt(s,10);a>o&&(o=a)}for(let s=0;s<=o;s++)i[s]=null;for(const s in t){if(s==="$vscodeTextmateLocation")continue;const a=parseInt(s,10);let l=0;t[s].patterns&&(l=V.getCompiledRuleId(t[s],n,r)),i[a]=V.createCaptureRule(n,t[s].$vscodeTextmateLocation,t[s].name,t[s].contentName,l)}}return i}static _compilePatterns(t,n,r){let i=[];if(t)for(let o=0,s=t.length;o<s;o++){const a=t[o];let l=-1;if(a.include){const u=Gr(a.include);switch(u.kind){case 0:case 1:l=V.getCompiledRuleId(r[a.include],n,r);break;case 2:let p=r[u.ruleName];p&&(l=V.getCompiledRuleId(p,n,r));break;case 3:case 4:const d=u.scopeName,f=u.kind===4?u.ruleName:null,h=n.getExternalGrammar(d,r);if(h)if(f){let m=h.repository[f];m&&(l=V.getCompiledRuleId(m,n,h.repository))}else l=V.getCompiledRuleId(h.repository.$self,n,h.repository);break}}else l=V.getCompiledRuleId(a,n,r);if(l!==-1){const u=n.getRule(l);let p=!1;if((u instanceof Bn||u instanceof zt||u instanceof tt)&&u.hasMissingPatterns&&u.patterns.length===0&&(p=!0),p)continue;i.push(l)}}return{patterns:i,hasMissingPatterns:(t?t.length:0)!==i.length}}},Le=class Fr{source;ruleId;hasAnchor;hasBackReferences;_anchorCache;constructor(t,n){if(t&&typeof t=="string"){const r=t.length;let i=0,o=[],s=!1;for(let a=0;a<r;a++)if(t.charAt(a)==="\\"&&a+1<r){const u=t.charAt(a+1);u==="z"?(o.push(t.substring(i,a)),o.push("$(?!\\n)(?<!\\n)"),i=a+2):(u==="A"||u==="G")&&(s=!0),a++}this.hasAnchor=s,i===0?this.source=t:(o.push(t.substring(i,r)),this.source=o.join(""))}else this.hasAnchor=!1,this.source=t;this.hasAnchor?this._anchorCache=this._buildAnchorCache():this._anchorCache=null,this.ruleId=n,typeof this.source=="string"?this.hasBackReferences=Ho.test(this.source):this.hasBackReferences=!1}clone(){return new Fr(this.source,this.ruleId)}setSource(t){this.source!==t&&(this.source=t,this.hasAnchor&&(this._anchorCache=this._buildAnchorCache()))}resolveBackReferences(t,n){if(typeof this.source!="string")throw new Error("This method should only be called if the source is a string");let r=n.map(i=>t.substring(i.start,i.end));return Gn.lastIndex=0,this.source.replace(Gn,(i,o)=>Dr(r[parseInt(o,10)]||""))}_buildAnchorCache(){if(typeof this.source!="string")throw new Error("This method should only be called if the source is a string");let t=[],n=[],r=[],i=[],o,s,a,l;for(o=0,s=this.source.length;o<s;o++)a=this.source.charAt(o),t[o]=a,n[o]=a,r[o]=a,i[o]=a,a==="\\"&&o+1<s&&(l=this.source.charAt(o+1),l==="A"?(t[o+1]="￿",n[o+1]="￿",r[o+1]="A",i[o+1]="A"):l==="G"?(t[o+1]="￿",n[o+1]="G",r[o+1]="￿",i[o+1]="G"):(t[o+1]=l,n[o+1]=l,r[o+1]=l,i[o+1]=l),o++);return{A0_G0:t.join(""),A0_G1:n.join(""),A1_G0:r.join(""),A1_G1:i.join("")}}resolveAnchors(t,n){return!this.hasAnchor||!this._anchorCache||typeof this.source!="string"?this.source:t?n?this._anchorCache.A1_G1:this._anchorCache.A1_G0:n?this._anchorCache.A0_G1:this._anchorCache.A0_G0}},Re=class{_items;_hasAnchors;_cached;_anchorCache;constructor(){this._items=[],this._hasAnchors=!1,this._cached=null,this._anchorCache={A0_G0:null,A0_G1:null,A1_G0:null,A1_G1:null}}dispose(){this._disposeCaches()}_disposeCaches(){this._cached&&(this._cached.dispose(),this._cached=null),this._anchorCache.A0_G0&&(this._anchorCache.A0_G0.dispose(),this._anchorCache.A0_G0=null),this._anchorCache.A0_G1&&(this._anchorCache.A0_G1.dispose(),this._anchorCache.A0_G1=null),this._anchorCache.A1_G0&&(this._anchorCache.A1_G0.dispose(),this._anchorCache.A1_G0=null),this._anchorCache.A1_G1&&(this._anchorCache.A1_G1.dispose(),this._anchorCache.A1_G1=null)}push(e){this._items.push(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}unshift(e){this._items.unshift(e),this._hasAnchors=this._hasAnchors||e.hasAnchor}length(){return this._items.length}setSource(e,t){this._items[e].source!==t&&(this._disposeCaches(),this._items[e].setSource(t))}compile(e){if(!this._cached){let t=this._items.map(n=>n.source);this._cached=new Un(e,t,this._items.map(n=>n.ruleId))}return this._cached}compileAG(e,t,n){return this._hasAnchors?t?n?(this._anchorCache.A1_G1||(this._anchorCache.A1_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G1):(this._anchorCache.A1_G0||(this._anchorCache.A1_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A1_G0):n?(this._anchorCache.A0_G1||(this._anchorCache.A0_G1=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G1):(this._anchorCache.A0_G0||(this._anchorCache.A0_G0=this._resolveAnchors(e,t,n)),this._anchorCache.A0_G0):this.compile(e)}_resolveAnchors(e,t,n){let r=this._items.map(i=>i.resolveAnchors(t,n));return new Un(e,r,this._items.map(i=>i.ruleId))}},Un=class{constructor(e,t,n){this.regExps=t,this.rules=n,this.scanner=e.createOnigScanner(t)}scanner;dispose(){typeof this.scanner.dispose=="function"&&this.scanner.dispose()}toString(){const e=[];for(let t=0,n=this.rules.length;t<n;t++)e.push(" - "+this.rules[t]+": "+this.regExps[t]);return e.join(` `)}findNextMatchSync(e,t,n){const r=this.scanner.findNextMatchSync(e,t,n);return r?{ruleId:this.rules[r.index],captureIndices:r.captureIndices}:null}},Tt=class{constructor(e,t){this.languageId=e,this.tokenType=t}},Xo=class qt{_defaultAttributes;_embeddedLanguagesMatcher;constructor(t,n){this._defaultAttributes=new Tt(t,8),this._embeddedLanguagesMatcher=new Ko(Object.entries(n||{}))}getDefaultAttributes(){return this._defaultAttributes}getBasicScopeAttributes(t){return t===null?qt._NULL_SCOPE_METADATA:this._getBasicScopeAttributes.get(t)}static _NULL_SCOPE_METADATA=new Tt(0,0);_getBasicScopeAttributes=new Nr(t=>{const n=this._scopeToLanguage(t),r=this._toStandardTokenType(t);return new Tt(n,r)});_scopeToLanguage(t){return this._embeddedLanguagesMatcher.match(t)||0}_toStandardTokenType(t){const n=t.match(qt.STANDARD_TOKEN_TYPE_REGEXP);if(!n)return 8;switch(n[1]){case"comment":return 1;case"string":return 2;case"regex":return 3;case"meta.embedded":return 0}throw new Error("Unexpected match for standard token type!")}static STANDARD_TOKEN_TYPE_REGEXP=/\b(comment|string|regex|meta\.embedded)\b/},Ko=class{values;scopesRegExp;constructor(e){if(e.length===0)this.values=null,this.scopesRegExp=null;else{this.values=new Map(e);const t=e.map(([n,r])=>Dr(n));t.sort(),t.reverse(),this.scopesRegExp=new RegExp(`^((${t.join(")|(")}))($|\\.)`,"")}}match(e){if(!this.scopesRegExp)return;const t=e.match(this.scopesRegExp);if(t)return this.values.get(t[1])}},Fn=class{constructor(e,t){this.stack=e,this.stoppedEarly=t}};function jr(e,t,n,r,i,o,s,a){const l=t.content.length;let u=!1,p=-1;if(s){const h=Qo(e,t,n,r,i,o);i=h.stack,r=h.linePos,n=h.isFirstLine,p=h.anchorPosition}const d=Date.now();for(;!u;){if(a!==0&&Date.now()-d>a)return new Fn(i,!0);f()}return new Fn(i,!1);function f(){const h=Jo(e,t,n,r,i,p);if(!h){o.produce(i,l),u=!0;return}const m=h.captureIndices,E=h.matchedRuleId,b=m&&m.length>0?m[0].end>r:!1;if(E===Wo){const g=i.getRule(e);o.produce(i,m[0].start),i=i.withContentNameScopesList(i.nameScopesList),Ce(e,t,n,i,o,g.endCaptures,m),o.produce(i,m[0].end);const y=i;if(i=i.parent,p=y.getAnchorPos(),!b&&y.getEnterPos()===r){i=y,o.produce(i,l),u=!0;return}}else{const g=e.getRule(E);o.produce(i,m[0].start);const y=i,w=g.getName(t.content,m),A=i.contentNameScopesList.pushAttributed(w,e);if(i=i.push(E,r,p,m[0].end===l,null,A,A),g instanceof zt){const k=g;Ce(e,t,n,i,o,k.beginCaptures,m),o.produce(i,m[0].end),p=m[0].end;const I=k.getContentName(t.content,m),M=A.pushAttributed(I,e);if(i=i.withContentNameScopesList(M),k.endHasBackReferences&&(i=i.withEndRule(k.getEndWithResolvedBackReferences(t.content,m))),!b&&y.hasSameRuleAs(i)){i=i.pop(),o.produce(i,l),u=!0;return}}else if(g instanceof tt){const k=g;Ce(e,t,n,i,o,k.beginCaptures,m),o.produce(i,m[0].end),p=m[0].end;const I=k.getContentName(t.content,m),M=A.pushAttributed(I,e);if(i=i.withContentNameScopesList(M),k.whileHasBackReferences&&(i=i.withEndRule(k.getWhileWithResolvedBackReferences(t.content,m))),!b&&y.hasSameRuleAs(i)){i=i.pop(),o.produce(i,l),u=!0;return}}else if(Ce(e,t,n,i,o,g.captures,m),o.produce(i,m[0].end),i=i.pop(),!b){i=i.safePop(),o.produce(i,l),u=!0;return}}m[0].end>r&&(r=m[0].end,n=!1)}}function Qo(e,t,n,r,i,o){let s=i.beginRuleCapturedEOL?0:-1;const a=[];for(let l=i;l;l=l.pop()){const u=l.getRule(e);u instanceof tt&&a.push({rule:u,stack:l})}for(let l=a.pop();l;l=a.pop()){const{ruleScanner:u,findOptions:p}=es(l.rule,e,l.stack.endRule,n,r===s),d=u.findNextMatchSync(t,r,p);if(d){if(d.ruleId!==Br){i=l.stack.pop();break}d.captureIndices&&d.captureIndices.length&&(o.produce(l.stack,d.captureIndices[0].start),Ce(e,t,n,l.stack,o,l.rule.whileCaptures,d.captureIndices),o.produce(l.stack,d.captureIndices[0].end),s=d.captureIndices[0].end,d.captureIndices[0].end>r&&(r=d.captureIndices[0].end,n=!1))}else{i=l.stack.pop();break}}return{stack:i,linePos:r,anchorPosition:s,isFirstLine:n}}function Jo(e,t,n,r,i,o){const s=Yo(e,t,n,r,i,o),a=e.getInjections();if(a.length===0)return s;const l=Zo(a,e,t,n,r,i,o);if(!l)return s;if(!s)return l;const u=s.captureIndices[0].start,p=l.captureIndices[0].start;return p<u||l.priorityMatch&&p===u?l:s}function Yo(e,t,n,r,i,o){const s=i.getRule(e),{ruleScanner:a,findOptions:l}=Hr(s,e,i.endRule,n,r===o),u=a.findNextMatchSync(t,r,l);return u?{captureIndices:u.captureIndices,matchedRuleId:u.ruleId}:null}function Zo(e,t,n,r,i,o,s){let a=Number.MAX_VALUE,l=null,u,p=0;const d=o.contentNameScopesList.getScopeNames();for(let f=0,h=e.length;f<h;f++){const m=e[f];if(!m.matcher(d))continue;const E=t.getRule(m.ruleId),{ruleScanner:b,findOptions:g}=Hr(E,t,null,r,i===s),y=b.findNextMatchSync(n,i,g);if(!y)continue;const w=y.captureIndices[0].start;if(!(w>=a)&&(a=w,l=y.captureIndices,u=y.ruleId,p=m.priority,a===i))break}return l?{priorityMatch:p===-1,captureIndices:l,matchedRuleId:u}:null}function Hr(e,t,n,r,i){return{ruleScanner:e.compileAG(t,n,r,i),findOptions:0}}function es(e,t,n,r,i){return{ruleScanner:e.compileWhileAG(t,n,r,i),findOptions:0}}function Ce(e,t,n,r,i,o,s){if(o.length===0)return;const a=t.content,l=Math.min(o.length,s.length),u=[],p=s[0].end;for(let d=0;d<l;d++){const f=o[d];if(f===null)continue;const h=s[d];if(h.length===0)continue;if(h.start>p)break;for(;u.length>0&&u[u.length-1].endPos<=h.start;)i.produceFromScopes(u[u.length-1].scopes,u[u.length-1].endPos),u.pop();if(u.length>0?i.produceFromScopes(u[u.length-1].scopes,h.start):i.produce(r,h.start),f.retokenizeCapturedWithRuleId){const E=f.getName(a,s),b=r.contentNameScopesList.pushAttributed(E,e),g=f.getContentName(a,s),y=b.pushAttributed(g,e),w=r.push(f.retokenizeCapturedWithRuleId,h.start,-1,!1,null,b,y),A=e.createOnigString(a.substring(0,h.end));jr(e,A,n&&h.start===0,h.start,w,i,!1,0),Mr(A);continue}const m=f.getName(a,s);if(m!==null){const b=(u.length>0?u[u.length-1].scopes:r.contentNameScopesList).pushAttributed(m,e);u.push(new ts(b,h.end))}}for(;u.length>0;)i.produceFromScopes(u[u.length-1].scopes,u[u.length-1].endPos),u.pop()}var ts=class{scopes;endPos;constructor(e,t){this.scopes=e,this.endPos=t}};function ns(e,t,n,r,i,o,s,a){return new is(e,t,n,r,i,o,s,a)}function jn(e,t,n,r,i){const o=Ze(t,nt),s=Ur.getCompiledRuleId(n,r,i.repository);for(const a of o)e.push({debugSelector:t,matcher:a.matcher,ruleId:s,grammar:i,priority:a.priority})}function nt(e,t){if(t.length<e.length)return!1;let n=0;return e.every(r=>{for(let i=n;i<t.length;i++)if(rs(t[i],r))return n=i+1,!0;return!1})}function rs(e,t){if(!e)return!1;if(e===t)return!0;const n=t.length;return e.length>n&&e.substr(0,n)===t&&e[n]==="."}var is=class{constructor(e,t,n,r,i,o,s,a){if(this._rootScopeName=e,this.balancedBracketSelectors=o,this._onigLib=a,this._basicScopeAttributesProvider=new Xo(n,r),this._rootId=-1,this._lastRuleId=0,this._ruleId2desc=[null],this._includedGrammars={},this._grammarRepository=s,this._grammar=Hn(t,null),this._injections=null,this._tokenTypeMatchers=[],i)for(const l of Object.keys(i)){const u=Ze(l,nt);for(const p of u)this._tokenTypeMatchers.push({matcher:p.matcher,type:i[l]})}}_rootId;_lastRuleId;_ruleId2desc;_includedGrammars;_grammarRepository;_grammar;_injections;_basicScopeAttributesProvider;_tokenTypeMatchers;get themeProvider(){return this._grammarRepository}dispose(){for(const e of this._ruleId2desc)e&&e.dispose()}createOnigScanner(e){return this._onigLib.createOnigScanner(e)}createOnigString(e){return this._onigLib.createOnigString(e)}getMetadataForScope(e){return this._basicScopeAttributesProvider.getBasicScopeAttributes(e)}_collectInjections(){const e={lookup:i=>i===this._rootScopeName?this._grammar:this.getExternalGrammar(i),injections:i=>this._grammarRepository.injections(i)},t=[],n=this._rootScopeName,r=e.lookup(n);if(r){const i=r.injections;if(i)for(let s in i)jn(t,s,i[s],this,r);const o=this._grammarRepository.injections(n);o&&o.forEach(s=>{const a=this.getExternalGrammar(s);if(a){const l=a.injectionSelector;l&&jn(t,l,a,this,a)}})}return t.sort((i,o)=>i.priority-o.priority),t}getInjections(){return this._injections===null&&(this._injections=this._collectInjections()),this._injections}registerRule(e){const t=++this._lastRuleId,n=e(t);return this._ruleId2desc[t]=n,n}getRule(e){return this._ruleId2desc[e]}getExternalGrammar(e,t){if(this._includedGrammars[e])return this._includedGrammars[e];if(this._grammarRepository){const n=this._grammarRepository.lookup(e);if(n)return this._includedGrammars[e]=Hn(n,t&&t.$base),this._includedGrammars[e]}}tokenizeLine(e,t,n=0){const r=this._tokenize(e,t,!1,n);return{tokens:r.lineTokens.getResult(r.ruleStack,r.lineLength),ruleStack:r.ruleStack,stoppedEarly:r.stoppedEarly}}tokenizeLine2(e,t,n=0){const r=this._tokenize(e,t,!0,n);return{tokens:r.lineTokens.getBinaryResult(r.ruleStack,r.lineLength),ruleStack:r.ruleStack,stoppedEarly:r.stoppedEarly}}_tokenize(e,t,n,r){this._rootId===-1&&(this._rootId=Ur.getCompiledRuleId(this._grammar.repository.$self,this,this._grammar.repository),this.getInjections());let i;if(!t||t===Xt.NULL){i=!0;const u=this._basicScopeAttributesProvider.getDefaultAttributes(),p=this.themeProvider.getDefaults(),d=le.set(0,u.languageId,u.tokenType,null,p.fontStyle,p.foregroundId,p.backgroundId),f=this.getRule(this._rootId).getName(null,null);let h;f?h=Ae.createRootAndLookUpScopeName(f,d,this):h=Ae.createRoot("unknown",d),t=new Xt(null,this._rootId,-1,-1,!1,null,h,h)}else i=!1,t.reset();e=e+` `;const o=this.createOnigString(e),s=o.content.length,a=new ss(n,e,this._tokenTypeMatchers,this.balancedBracketSelectors),l=jr(this,o,i,0,t,a,!0,r);return Mr(o),{lineLength:s,lineTokens:a,ruleStack:l.stack,stoppedEarly:l.stoppedEarly}}};function Hn(e,t){return e=Co(e),e.repository=e.repository||{},e.repository.$self={$vscodeTextmateLocation:e.$vscodeTextmateLocation,patterns:e.patterns,name:e.scopeName},e.repository.$base=t||e.repository.$self,e}var Ae=class K{constructor(t,n,r){this.parent=t,this.scopePath=n,this.tokenAttributes=r}static fromExtension(t,n){let r=t,i=t?.scopePath??null;for(const o of n)i=It.push(i,o.scopeNames),r=new K(r,i,o.encodedTokenAttributes);return r}static createRoot(t,n){return new K(null,new It(null,t),n)}static createRootAndLookUpScopeName(t,n,r){const i=r.getMetadataForScope(t),o=new It(null,t),s=r.themeProvider.themeMatch(o),a=K.mergeAttributes(n,i,s);return new K(null,o,a)}get scopeName(){return this.scopePath.scopeName}toString(){return this.getScopeNames().join(" ")}equals(t){return K.equals(this,t)}static equals(t,n){do{if(t===n||!t&&!n)return!0;if(!t||!n||t.scopeName!==n.scopeName||t.tokenAttributes!==n.tokenAttributes)return!1;t=t.parent,n=n.parent}while(!0)}static mergeAttributes(t,n,r){let i=-1,o=0,s=0;return r!==null&&(i=r.fontStyle,o=r.foregroundId,s=r.backgroundId),le.set(t,n.languageId,n.tokenType,null,i,o,s)}pushAttributed(t,n){if(t===null)return this;if(t.indexOf(" ")===-1)return K._pushAttributed(this,t,n);const r=t.split(/ /g);let i=this;for(const o of r)i=K._pushAttributed(i,o,n);return i}static _pushAttributed(t,n,r){const i=r.getMetadataForScope(n),o=t.scopePath.push(n),s=r.themeProvider.themeMatch(o),a=K.mergeAttributes(t.tokenAttributes,i,s);return new K(t,o,a)}getScopeNames(){return this.scopePath.getSegments()}getExtensionIfDefined(t){const n=[];let r=this;for(;r&&r!==t;)n.push({encodedTokenAttributes:r.tokenAttributes,scopeNames:r.scopePath.getExtensionIfDefined(r.parent?.scopePath??null)}),r=r.parent;return r===t?n.reverse():void 0}},Xt=class ie{constructor(t,n,r,i,o,s,a,l){this.parent=t,this.ruleId=n,this.beginRuleCapturedEOL=o,this.endRule=s,this.nameScopesList=a,this.contentNameScopesList=l,this.depth=this.parent?this.parent.depth+1:1,this._enterPos=r,this._anchorPos=i}_stackElementBrand=void 0;static NULL=new ie(null,0,0,0,!1,null,null,null);_enterPos;_anchorPos;depth;equals(t){return t===null?!1:ie._equals(this,t)}static _equals(t,n){return t===n?!0:this._structuralEquals(t,n)?Ae.equals(t.contentNameScopesList,n.contentNameScopesList):!1}static _structuralEquals(t,n){do{if(t===n||!t&&!n)return!0;if(!t||!n||t.depth!==n.depth||t.ruleId!==n.ruleId||t.endRule!==n.endRule)return!1;t=t.parent,n=n.parent}while(!0)}clone(){return this}static _reset(t){for(;t;)t._enterPos=-1,t._anchorPos=-1,t=t.parent}reset(){ie._reset(this)}pop(){return this.parent}safePop(){return this.parent?this.parent:this}push(t,n,r,i,o,s,a){return new ie(this,t,n,r,i,o,s,a)}getEnterPos(){return this._enterPos}getAnchorPos(){return this._anchorPos}getRule(t){return t.getRule(this.ruleId)}toString(){const t=[];return this._writeString(t,0),"["+t.join(",")+"]"}_writeString(t,n){return this.parent&&(n=this.parent._writeString(t,n)),t[n++]=`(${this.ruleId}, ${this.nameScopesList?.toString()}, ${this.contentNameScopesList?.toString()})`,n}withContentNameScopesList(t){return this.contentNameScopesList===t?this:this.parent.push(this.ruleId,this._enterPos,this._anchorPos,this.beginRuleCapturedEOL,this.endRule,this.nameScopesList,t)}withEndRule(t){return this.endRule===t?this:new ie(this.parent,this.ruleId,this._enterPos,this._anchorPos,this.beginRuleCapturedEOL,t,this.nameScopesList,this.contentNameScopesList)}hasSameRuleAs(t){let n=this;for(;n&&n._enterPos===t._enterPos;){if(n.ruleId===t.ruleId)return!0;n=n.parent}return!1}toStateStackFrame(){return{ruleId:this.ruleId,beginRuleCapturedEOL:this.beginRuleCapturedEOL,endRule:this.endRule,nameScopesList:this.nameScopesList?.getExtensionIfDefined(this.parent?.nameScopesList??null)??[],contentNameScopesList:this.contentNameScopesList?.getExtensionIfDefined(this.nameScopesList)??[]}}static pushFrame(t,n){const r=Ae.fromExtension(t?.nameScopesList??null,n.nameScopesList);return new ie(t,n.ruleId,n.enterPos??-1,n.anchorPos??-1,n.beginRuleCapturedEOL,n.endRule,r,Ae.fromExtension(r,n.contentNameScopesList))}},os=class{balancedBracketScopes;unbalancedBracketScopes;allowAny=!1;constructor(e,t){this.balancedBracketScopes=e.flatMap(n=>n==="*"?(this.allowAny=!0,[]):Ze(n,nt).map(r=>r.matcher)),this.unbalancedBracketScopes=t.flatMap(n=>Ze(n,nt).map(r=>r.matcher))}get matchesAlways(){return this.allowAny&&this.unbalancedBracketScopes.length===0}get matchesNever(){return this.balancedBracketScopes.length===0&&!this.allowAny}match(e){for(const t of this.unbalancedBracketScopes)if(t(e))return!1;for(const t of this.balancedBracketScopes)if(t(e))return!0;return this.allowAny}},ss=class{constructor(e,t,n,r){this.balancedBracketSelectors=r,this._emitBinaryTokens=e,this._tokenTypeOverrides=n,this._lineText=null,this._tokens=[],this._binaryTokens=[],this._lastTokenEndIndex=0}_emitBinaryTokens;_lineText;_tokens;_binaryTokens;_lastTokenEndIndex;_tokenTypeOverrides;produce(e,t){this.produceFromScopes(e.contentNameScopesList,t)}produceFromScopes(e,t){if(this._lastTokenEndIndex>=t)return;if(this._emitBinaryTokens){let r=e?.tokenAttributes??0,i=!1;if(this.balancedBracketSelectors?.matchesAlways&&(i=!0),this._tokenTypeOverrides.length>0||this.balancedBracketSelectors&&!this.balancedBracketSelectors.matchesAlways&&!this.balancedBracketSelectors.matchesNever){const o=e?.getScopeNames()??[];for(const s of this._tokenTypeOverrides)s.matcher(o)&&(r=le.set(r,0,s.type,null,-1,0,0));this.balancedBracketSelectors&&(i=this.balancedBracketSelectors.match(o))}if(i&&(r=le.set(r,0,8,i,-1,0,0)),this._binaryTokens.length>0&&this._binaryTokens[this._binaryTokens.length-1]===r){this._lastTokenEndIndex=t;return}this._binaryTokens.push(this._lastTokenEndIndex),this._binaryTokens.push(r),this._lastTokenEndIndex=t;return}const n=e?.getScopeNames()??[];this._tokens.push({startIndex:this._lastTokenEndIndex,endIndex:t,scopes:n}),this._lastTokenEndIndex=t}getResult(e,t){return this._tokens.length>0&&this._tokens[this._tokens.length-1].startIndex===t-1&&this._tokens.pop(),this._tokens.length===0&&(this._lastTokenEndIndex=-1,this.produce(e,t),this._tokens[this._tokens.length-1].startIndex=0),this._tokens}getBinaryResult(e,t){this._binaryTokens.length>0&&this._binaryTokens[this._binaryTokens.length-2]===t-1&&(this._binaryTokens.pop(),this._binaryTokens.pop()),this._binaryTokens.length===0&&(this._lastTokenEndIndex=-1,this.produce(e,t),this._binaryTokens[this._binaryTokens.length-2]=0);const n=new Uint32Array(this._binaryTokens.length);for(let r=0,i=this._binaryTokens.length;r<i;r++)n[r]=this._binaryTokens[r];return n}},as=class{constructor(e,t){this._onigLib=t,this._theme=e}_grammars=new Map;_rawGrammars=new Map;_injectionGrammars=new Map;_theme;dispose(){for(const e of this._grammars.values())e.dispose()}setTheme(e){this._theme=e}getColorMap(){return this._theme.getColorMap()}addGrammar(e,t){this._rawGrammars.set(e.scopeName,e),t&&this._injectionGrammars.set(e.scopeName,t)}lookup(e){return this._rawGrammars.get(e)}injections(e){return this._injectionGrammars.get(e)}getDefaults(){return this._theme.getDefaults()}themeMatch(e){return this._theme.match(e)}grammarForScopeName(e,t,n,r,i){if(!this._grammars.has(e)){let o=this._rawGrammars.get(e);if(!o)return null;this._grammars.set(e,ns(e,o,t,n,r,i,this,this._onigLib))}return this._grammars.get(e)}},ls=class{_options;_syncRegistry;_ensureGrammarCache;constructor(t){this._options=t,this._syncRegistry=new as(Ye.createFromRawTheme(t.theme,t.colorMap),t.onigLib),this._ensureGrammarCache=new Map}dispose(){this._syncRegistry.dispose()}setTheme(t,n){this._syncRegistry.setTheme(Ye.createFromRawTheme(t,n))}getColorMap(){return this._syncRegistry.getColorMap()}loadGrammarWithEmbeddedLanguages(t,n,r){return this.loadGrammarWithConfiguration(t,n,{embeddedLanguages:r})}loadGrammarWithConfiguration(t,n,r){return this._loadGrammar(t,n,r.embeddedLanguages,r.tokenTypes,new os(r.balancedBracketSelectors||[],r.unbalancedBracketSelectors||[]))}loadGrammar(t){return this._loadGrammar(t,0,null,null,null)}_loadGrammar(t,n,r,i,o){const s=new $o(this._syncRegistry,t);for(;s.Q.length>0;)s.Q.map(a=>this._loadSingleGrammar(a.scopeName)),s.processQueue();return this._grammarForScopeName(t,n,r,i,o)}_loadSingleGrammar(t){this._ensureGrammarCache.has(t)||(this._doLoadSingleGrammar(t),this._ensureGrammarCache.set(t,!0))}_doLoadSingleGrammar(t){const n=this._options.loadGrammar(t);if(n){const r=typeof this._options.getInjections=="function"?this._options.getInjections(t):void 0;this._syncRegistry.addGrammar(n,r)}}addGrammar(t,n=[],r=0,i=null){return this._syncRegistry.addGrammar(t,n),this._grammarForScopeName(t.scopeName,r,i)}_grammarForScopeName(t,n=0,r=null,i=null,o=null){return this._syncRegistry.grammarForScopeName(t,n,r,i,o)}},Kt=Xt.NULL;function Ie(e,t){const n=typeof e=="string"?{}:{...e.colorReplacements},r=typeof e=="string"?e:e.name;for(const[i,o]of Object.entries(t?.colorReplacements||{}))typeof o=="string"?n[i]=o:i===r&&Object.assign(n,o);return n}function ee(e,t){return e&&(t?.[e?.toLowerCase()]||e)}function Wr(e){return Array.isArray(e)?e:[e]}async function dn(e){return Promise.resolve(typeof e=="function"?e():e).then(t=>t.default||t)}function $e(e){return!e||["plaintext","txt","text","plain"].includes(e)}function pn(e){return e==="ansi"||$e(e)}function Me(e){return e==="none"}function hn(e){return Me(e)}const us=/(\r?\n)/g;function Ge(e,t=!1){if(e.length===0)return[["",0]];const n=e.split(us);let r=0;const i=[];for(let o=0;o<n.length;o+=2){const s=t?n[o]+(n[o+1]||""):n[o];i.push([s,r]),r+=n[o].length,r+=n[o+1]?.length||0}return i}const Wn={light:"#333333",dark:"#bbbbbb"},zn={light:"#fffffe",dark:"#1e1e1e"},qn="__shiki_resolved";function mt(e){if(e?.[qn])return e;const t={...e};t.tokenColors&&!t.settings&&(t.settings=t.tokenColors,delete t.tokenColors),t.type||="dark",t.colorReplacements={...t.colorReplacements},t.settings||=[];let{bg:n,fg:r}=t;if(!n||!r){const a=t.settings?t.settings.find(l=>!l.name&&!l.scope):void 0;a?.settings?.foreground&&(r=a.settings.foreground),a?.settings?.background&&(n=a.settings.background),!r&&t?.colors?.["editor.foreground"]&&(r=t.colors["editor.foreground"]),!n&&t?.colors?.["editor.background"]&&(n=t.colors["editor.background"]),r||(r=t.type==="light"?Wn.light:Wn.dark),n||(n=t.type==="light"?zn.light:zn.dark),t.fg=r,t.bg=n}t.settings[0]&&t.settings[0].settings&&!t.settings[0].scope||t.settings.unshift({settings:{foreground:t.fg,background:t.bg}});let i=0;const o=new Map;function s(a){if(o.has(a))return o.get(a);i+=1;const l=`#${i.toString(16).padStart(8,"0").toLowerCase()}`;return t.colorReplacements?.[`#${l}`]?s(a):(o.set(a,l),l)}t.settings=t.settings.map(a=>{const l=a.settings?.foreground&&!a.settings.foreground.startsWith("#"),u=a.settings?.background&&!a.settings.background.startsWith("#");if(!l&&!u)return a;const p={...a,settings:{...a.settings}};if(l){const d=s(a.settings.foreground);t.colorReplacements[d]=a.settings.foreground,p.settings.foreground=d}if(u){const d=s(a.settings.background);t.colorReplacements[d]=a.settings.background,p.settings.background=d}return p});for(const a of Object.keys(t.colors||{}))if((a==="editor.foreground"||a==="editor.background"||a.startsWith("terminal.ansi"))&&!t.colors[a]?.startsWith("#")){const l=s(t.colors[a]);t.colorReplacements[l]=t.colors[a],t.colors[a]=l}return Object.defineProperty(t,qn,{enumerable:!1,writable:!1,value:!0}),t}async function zr(e){return[...new Set((await Promise.all(e.filter(t=>!pn(t)).map(async t=>await dn(t).then(n=>Array.isArray(n)?n:[n])))).flat())]}async function qr(e){return(await Promise.all(e.map(async t=>hn(t)?null:mt(await dn(t))))).filter(t=>!!t)}function Xr(e,t){if(!t)return e;if(t[e]){const n=new Set([e]);for(;t[e];){if(e=t[e],n.has(e))throw new L(`Circular alias \`${[...n].join(" -> ")} -> ${e}\``);n.add(e)}}return e}var cs=class extends ls{_resolver;_themes;_langs;_alias;_resolvedThemes=new Map;_resolvedGrammars=new Map;_langMap=new Map;_langGraph=new Map;_textmateThemeCache=new WeakMap;_loadedThemesCache=null;_loadedLanguagesCache=null;constructor(e,t,n,r={}){super(e),this._resolver=e,this._themes=t,this._langs=n,this._alias=r,this._themes.map(i=>this.loadTheme(i)),this.loadLanguages(this._langs)}getTheme(e){return typeof e=="string"?this._resolvedThemes.get(e):this.loadTheme(e)}loadTheme(e){const t=mt(e);return t.name&&(this._resolvedThemes.set(t.name,t),this._loadedThemesCache=null),t}getLoadedThemes(){return this._loadedThemesCache||(this._loadedThemesCache=[...this._resolvedThemes.keys()]),this._loadedThemesCache}setTheme(e){let t=this._textmateThemeCache.get(e);t||(t=Ye.createFromRawTheme(e),this._textmateThemeCache.set(e,t)),this._syncRegistry.setTheme(t)}getGrammar(e){return e=Xr(e,this._alias),this._resolvedGrammars.get(e)}loadLanguage(e){if(this.getGrammar(e.name))return;const t=new Set([...this._langMap.values()].filter(i=>i.embeddedLangsLazy?.includes(e.name)));this._resolver.addLanguage(e);const n={balancedBracketSelectors:e.balancedBracketSelectors||["*"],unbalancedBracketSelectors:e.unbalancedBracketSelectors||[]};this._syncRegistry._rawGrammars.set(e.scopeName,e);const r=this.loadGrammarWithConfiguration(e.scopeName,1,n);if(r.name=e.name,this._resolvedGrammars.set(e.name,r),e.aliases&&e.aliases.forEach(i=>{this._alias[i]=e.name}),this._loadedLanguagesCache=null,t.size)for(const i of t)this._resolvedGrammars.delete(i.name),this._loadedLanguagesCache=null,this._syncRegistry?._injectionGrammars?.delete(i.scopeName),this._syncRegistry?._grammars?.delete(i.scopeName),this.loadLanguage(this._langMap.get(i.name))}dispose(){super.dispose(),this._resolvedThemes.clear(),this._resolvedGrammars.clear(),this._langMap.clear(),this._langGraph.clear(),this._loadedThemesCache=null}loadLanguages(e){for(const r of e)this.resolveEmbeddedLanguages(r);const t=[...this._langGraph.entries()],n=t.filter(([r,i])=>!i);if(n.length){const r=t.filter(([i,o])=>o?(o.embeddedLanguages||o.embeddedLangs)?.some(s=>n.map(([a])=>a).includes(s)):!1).filter(i=>!n.includes(i));throw new L(`Missing languages ${n.map(([i])=>`\`${i}\``).join(", ")}, required by ${r.map(([i])=>`\`${i}\``).join(", ")}`)}for(const[r,i]of t)this._resolver.addLanguage(i);for(const[r,i]of t)this.loadLanguage(i)}getLoadedLanguages(){return this._loadedLanguagesCache||(this._loadedLanguagesCache=[...new Set([...this._resolvedGrammars.keys(),...Object.keys(this._alias)])]),this._loadedLanguagesCache}resolveEmbeddedLanguages(e){this._langMap.set(e.name,e),this._langGraph.set(e.name,e);const t=e.embeddedLanguages??e.embeddedLangs;if(t)for(const n of t)this._langGraph.set(n,this._langMap.get(n))}},ds=class{_langs=new Map;_scopeToLang=new Map;_injections=new Map;_onigLib;constructor(e,t){this._onigLib={createOnigScanner:n=>e.createScanner(n),createOnigString:n=>e.createString(n)},t.forEach(n=>this.addLanguage(n))}get onigLib(){return this._onigLib}getLangRegistration(e){return this._langs.get(e)}loadGrammar(e){return this._scopeToLang.get(e)}addLanguage(e){this._langs.set(e.name,e),e.aliases&&e.aliases.forEach(t=>{this._langs.set(t,e)}),this._scopeToLang.set(e.scopeName,e),e.injectTo&&e.injectTo.forEach(t=>{this._injections.get(t)||this._injections.set(t,[]),this._injections.get(t).push(e.scopeName)})}getInjections(e){const t=e.split(".");let n=[];for(let r=1;r<=t.length;r++){const i=t.slice(0,r).join(".");n=[...n,...this._injections.get(i)||[]]}return n}};let ve=0;function gt(e){ve+=1,e.warnings!==!1&&ve>=10&&ve%10===0&&console.warn(`[Shiki] ${ve} instances have been created. Shiki is supposed to be used as a singleton, consider refactoring your code to cache your highlighter instance; Or call \`highlighter.dispose()\` to release unused instances.`);let t=!1;if(!e.engine)throw new L("`engine` option is required for synchronous mode");const n=(e.langs||[]).flat(1),r=(e.themes||[]).flat(1).map(mt),i=new cs(new ds(e.engine,n),r,n,e.langAlias);let o;function s(y){return Xr(y,e.langAlias)}function a(y){b();const w=i.getGrammar(typeof y=="string"?y:y.name);if(!w)throw new L(`Language \`${y}\` not found, you may need to load it first`);return w}function l(y){if(y==="none")return{bg:"",fg:"",name:"none",settings:[],type:"dark"};b();const w=i.getTheme(y);if(!w)throw new L(`Theme \`${y}\` not found, you may need to load it first`);return w}function u(y){b();const w=l(y);return o!==y&&(i.setTheme(w),o=y),{theme:w,colorMap:i.getColorMap()}}function p(){return b(),i.getLoadedThemes()}function d(){return b(),i.getLoadedLanguages()}function f(...y){b(),i.loadLanguages(y.flat(1))}async function h(...y){return f(await zr(y))}function m(...y){b();for(const w of y.flat(1))i.loadTheme(w)}async function E(...y){return b(),m(await qr(y))}function b(){if(t)throw new L("Shiki instance has been disposed")}function g(){t||(t=!0,i.dispose(),ve-=1)}return{setTheme:u,getTheme:l,getLanguage:a,getLoadedThemes:p,getLoadedLanguages:d,resolveLangAlias:s,loadLanguage:h,loadLanguageSync:f,loadTheme:E,loadThemeSync:m,dispose:g,[Symbol.dispose]:g}}const ps=gt;async function fn(e){e.engine||console.warn("`engine` option is required. Use `createOnigurumaEngine` or `createJavaScriptRegexEngine` to create an engine.");const[t,n,r]=await Promise.all([qr(e.themes||[]),zr(e.langs||[]),e.engine]);return gt({...e,themes:t,langs:n,engine:r})}const hs=fn,Kr=new WeakMap;function _t(e,t){Kr.set(e,t)}function Te(e){return Kr.get(e)}var yt=class Qr{_stacks={};lang;get themes(){return Object.keys(this._stacks)}get theme(){return this.themes[0]}get _stack(){return this._stacks[this.theme]}static initial(t,n){return new Qr(Object.fromEntries(Wr(n).map(r=>[r,Kt])),t)}constructor(...t){if(t.length===2){const[n,r]=t;this.lang=r,this._stacks=n}else{const[n,r,i]=t;this.lang=r,this._stacks={[i]:n}}}getInternalStack(t=this.theme){return this._stacks[t]}getScopes(t=this.theme){return fs(this._stacks[t])}toJSON(){return{lang:this.lang,theme:this.theme,themes:this.themes,scopes:this.getScopes()}}};function fs(e){const t=[],n=new Set;function r(i){if(n.has(i))return;n.add(i);const o=i?.nameScopesList?.scopeName;o&&t.push(o),i.parent&&r(i.parent)}return r(e),t}function ms(e,t){if(!(e instanceof yt))throw new L("Invalid grammar state");return e.getInternalStack(t)}const gs=/,/,_s=/ /;function Jr(e,t,n={}){const{theme:r=e.getLoadedThemes()[0]}=n;if($e(e.resolveLangAlias(n.lang||"text"))||Me(r))return Ge(t).map(a=>[{content:a[0],offset:a[1]}]);const{theme:i,colorMap:o}=e.setTheme(r),s=e.getLanguage(n.lang||"text");if(n.grammarState){if(n.grammarState.lang!==s.name)throw new L(`Grammar state language "${n.grammarState.lang}" does not match highlight language "${s.name}"`);if(!n.grammarState.themes.includes(i.name))throw new L(`Grammar state themes "${n.grammarState.themes}" do not contain highlight theme "${i.name}"`)}return Zr(t,s,i,o,n)}function Yr(...e){if(e.length===2)return Te(e[1]);const[t,n,r={}]=e,{lang:i="text",theme:o=t.getLoadedThemes()[0]}=r;if($e(i)||Me(o))throw new L("Plain language does not have grammar state");if(i==="ansi")throw new L("ANSI language does not have grammar state");const{theme:s,colorMap:a}=t.setTheme(o),l=t.getLanguage(i);return new yt(mn(n,l,s,a,r).stateStack,l.name,s.name)}function Zr(e,t,n,r,i){const o=mn(e,t,n,r,i),s=new yt(o.stateStack,t.name,n.name);return _t(o.tokens,s),o.tokens}function mn(e,t,n,r,i){const o=Ie(n,i),{tokenizeMaxLineLength:s=0,tokenizeTimeLimit:a=500,includeExplanation:l=!1}=i,u=Ge(e);let p=i.grammarState?ms(i.grammarState,n.name)??Kt:i.grammarContextCode!=null?mn(i.grammarContextCode,t,n,r,{...i,grammarState:void 0,grammarContextCode:void 0}).stateStack:Kt,d=[];const f=[];for(let h=0,m=u.length;h<m;h++){const[E,b]=u[h];if(E===""){d=[],f.push([]);continue}if(s>0&&E.length>=s){d=[],f.push([{content:E,offset:b,color:"",fontStyle:0}]);continue}let g,y,w;l&&l!=="tokenType"&&(g=t.tokenizeLine(E,p,a),y=g.tokens,w=0);const A=t.tokenizeLine2(E,p,a),k=A.tokens.length/2;for(let I=0;I<k;I++){const M=A.tokens[2*I],z=I+1<k?A.tokens[2*I+2]:E.length;if(M===z)continue;const pe=A.tokens[2*I+1],At=ee(r[le.getForeground(pe)],o),kt=le.getFontStyle(pe),q={content:E.substring(M,z),offset:b+M,color:At,fontStyle:kt};if(l==="tokenType")q.type=le.getTokenType(pe);else if(l){const Nn=[];if(l!=="scopeName")for(const Q of n.settings){let he;switch(typeof Q.scope){case"string":he=Q.scope.split(gs).map(St=>St.trim());break;case"object":he=Q.scope;break;default:continue}Nn.push({settings:Q,selectors:he.map(St=>St.split(_s))})}q.explanation=[];let Vn=0;for(;M+Vn<z;){const Q=y[w],he=E.substring(Q.startIndex,Q.endIndex);Vn+=he.length,q.explanation.push({content:he,scopes:l==="scopeName"?ys(Q.scopes):Es(Nn,Q.scopes)}),w+=1}}d.push(q)}f.push(d),d=[],p=A.ruleStack}return{tokens:f,stateStack:p}}function ys(e){return e.map(t=>({scopeName:t}))}function Es(e,t){const n=[];for(let r=0,i=t.length;r<i;r++){const o=t[r];n[r]={scopeName:o,themeMatches:ws(e,o,t.slice(0,r))}}return n}function Xn(e,t){return e===t||t.substring(0,e.length)===e&&t[e.length]==="."}function bs(e,t,n){if(!Xn(e.at(-1),t))return!1;let r=e.length-2,i=n.length-1;for(;r>=0&&i>=0;)Xn(e[r],n[i])&&(r-=1),i-=1;return r===-1}function ws(e,t,n){const r=[];for(const{selectors:i,settings:o}of e)for(const s of i)if(bs(s,t,n)){r.push(o);break}return r}function gn(e,t,n,r=Jr){const i=Object.entries(n.themes).filter(u=>u[1]).map(u=>({color:u[0],theme:u[1]})),o=i.map(u=>{const p=r(e,t,{...n,theme:u.theme});return{tokens:p,state:Te(p),theme:typeof u.theme=="string"?u.theme:u.theme.name}}),s=vs(...o.map(u=>u.tokens)),a=s[0].map((u,p)=>u.map((d,f)=>{const h={content:d.content,variants:{},offset:d.offset};return"includeExplanation"in n&&n.includeExplanation&&(h.explanation=d.explanation),s.forEach((m,E)=>{const{content:b,explanation:g,offset:y,...w}=m[p][f];h.variants[i[E].color]=w}),h})),l=o[0].state?new yt(Object.fromEntries(o.map(u=>[u.theme,u.state?.getInternalStack(u.theme)])),o[0].state.lang):void 0;return l&&_t(a,l),a}function vs(...e){const t=e.map(()=>[]),n=e.length;for(let r=0;r<e[0].length;r++){const i=e.map(l=>l[r]),o=t.map(()=>[]);t.forEach((l,u)=>l.push(o[u]));const s=i.map(()=>0),a=i.map(l=>l[0]);for(;a.every(l=>l);){const l=Math.min(...a.map(u=>u.content.length));for(let u=0;u<n;u++){const p=a[u];p.content.length===l?(o[u].push(p),s[u]+=1,a[u]=i[u][s[u]]):(o[u].push({...p,content:p.content.slice(0,l)}),a[u]={...p,content:p.content.slice(l),offset:p.offset+l})}}}return t}const Cs=["area","base","basefont","bgsound","br","col","command","embed","frame","hr","image","img","input","keygen","link","meta","param","source","track","wbr"];class Be{constructor(t,n,r){this.normal=n,this.property=t,r&&(this.space=r)}}Be.prototype.normal={};Be.prototype.property={};Be.prototype.space=void 0;function ei(e,t){const n={},r={};for(const i of e)Object.assign(n,i.property),Object.assign(r,i.normal);return new Be(n,r,t)}function Qt(e){return e.toLowerCase()}class G{constructor(t,n){this.attribute=n,this.property=t}}G.prototype.attribute="";G.prototype.booleanish=!1;G.prototype.boolean=!1;G.prototype.commaOrSpaceSeparated=!1;G.prototype.commaSeparated=!1;G.prototype.defined=!1;G.prototype.mustUseProperty=!1;G.prototype.number=!1;G.prototype.overloadedBoolean=!1;G.prototype.property="";G.prototype.spaceSeparated=!1;G.prototype.space=void 0;let As=0;const v=de(),T=de(),Jt=de(),_=de(),S=de(),ue=de(),B=de();function de(){return 2**++As}const Yt=Object.freeze(Object.defineProperty({__proto__:null,boolean:v,booleanish:T,commaOrSpaceSeparated:B,commaSeparated:ue,number:_,overloadedBoolean:Jt,spaceSeparated:S},Symbol.toStringTag,{value:"Module"})),Pt=Object.keys(Yt);class _n extends G{constructor(t,n,r,i){let o=-1;if(super(t,n),Kn(this,"space",i),typeof r=="number")for(;++o<Pt.length;){const s=Pt[o];Kn(this,Pt[o],(r&Yt[s])===Yt[s])}}}_n.prototype.defined=!0;function Kn(e,t,n){n&&(e[t]=n)}function Ee(e){const t={},n={};for(const[r,i]of Object.entries(e.properties)){const o=new _n(r,e.transform(e.attributes||{},r),i,e.space);e.mustUseProperty&&e.mustUseProperty.includes(r)&&(o.mustUseProperty=!0),t[r]=o,n[Qt(r)]=r,n[Qt(o.attribute)]=r}return new Be(t,n,e.space)}const ti=Ee({properties:{ariaActiveDescendant:null,ariaAtomic:T,ariaAutoComplete:null,ariaBusy:T,ariaChecked:T,ariaColCount:_,ariaColIndex:_,ariaColSpan:_,ariaControls:S,ariaCurrent:null,ariaDescribedBy:S,ariaDetails:null,ariaDisabled:T,ariaDropEffect:S,ariaErrorMessage:null,ariaExpanded:T,ariaFlowTo:S,ariaGrabbed:T,ariaHasPopup:null,ariaHidden:T,ariaInvalid:null,ariaKeyShortcuts:null,ariaLabel:null,ariaLabelledBy:S,ariaLevel:_,ariaLive:null,ariaModal:T,ariaMultiLine:T,ariaMultiSelectable:T,ariaOrientation:null,ariaOwns:S,ariaPlaceholder:null,ariaPosInSet:_,ariaPressed:T,ariaReadOnly:T,ariaRelevant:null,ariaRequired:T,ariaRoleDescription:S,ariaRowCount:_,ariaRowIndex:_,ariaRowSpan:_,ariaSelected:T,ariaSetSize:_,ariaSort:null,ariaValueMax:_,ariaValueMin:_,ariaValueNow:_,ariaValueText:null,role:null},transform(e,t){return t==="role"?t:"aria-"+t.slice(4).toLowerCase()}});function ni(e,t){return t in e?e[t]:t}function ri(e,t){return ni(e,t.toLowerCase())}const ks=Ee({attributes:{acceptcharset:"accept-charset",classname:"class",htmlfor:"for",httpequiv:"http-equiv"},mustUseProperty:["checked","multiple","muted","selected"],properties:{abbr:null,accept:ue,acceptCharset:S,accessKey:S,action:null,allow:null,allowFullScreen:v,allowPaymentRequest:v,allowUserMedia:v,alpha:v,alt:null,as:null,async:v,autoCapitalize:null,autoComplete:S,autoFocus:v,autoPlay:v,blocking:S,capture:null,charSet:null,checked:v,cite:null,className:S,closedBy:null,colorSpace:null,cols:_,colSpan:_,command:null,commandFor:null,content:null,contentEditable:T,controls:v,controlsList:S,coords:_|ue,crossOrigin:null,data:null,dateTime:null,decoding:null,default:v,defer:v,dir:null,dirName:null,disabled:v,download:Jt,draggable:T,encType:null,enterKeyHint:null,fetchPriority:null,form:null,formAction:null,formEncType:null,formMethod:null,formNoValidate:v,formTarget:null,headers:S,height:_,hidden:Jt,high:_,href:null,hrefLang:null,htmlFor:S,httpEquiv:S,id:null,imageSizes:null,imageSrcSet:null,inert:v,inputMode:null,integrity:null,is:null,isMap:v,itemId:null,itemProp:S,itemRef:S,itemScope:v,itemType:S,kind:null,label:null,lang:null,language:null,list:null,loading:null,loop:v,low:_,manifest:null,max:null,maxLength:_,media:null,method:null,min:null,minLength:_,multiple:v,muted:v,name:null,nonce:null,noModule:v,noValidate:v,onAbort:null,onAfterPrint:null,onAuxClick:null,onBeforeMatch:null,onBeforePrint:null,onBeforeToggle:null,onBeforeUnload:null,onBlur:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onContextLost:null,onContextMenu:null,onContextRestored:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnded:null,onError:null,onFocus:null,onFormData:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLanguageChange:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadEnd:null,onLoadStart:null,onMessage:null,onMessageError:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRejectionHandled:null,onReset:null,onResize:null,onScroll:null,onScrollEnd:null,onSecurityPolicyViolation:null,onSeeked:null,onSeeking:null,onSelect:null,onSlotChange:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnhandledRejection:null,onUnload:null,onVolumeChange:null,onWaiting:null,onWheel:null,open:v,optimum:_,pattern:null,ping:S,placeholder:null,playsInline:v,popover:null,popoverTarget:null,popoverTargetAction:null,poster:null,preload:null,readOnly:v,referrerPolicy:null,rel:S,required:v,reversed:v,rows:_,rowSpan:_,sandbox:S,scope:null,scoped:v,seamless:v,selected:v,shadowRootClonable:v,shadowRootCustomElementRegistry:v,shadowRootDelegatesFocus:v,shadowRootMode:null,shadowRootSerializable:v,shape:null,size:_,sizes:null,slot:null,span:_,spellCheck:T,src:null,srcDoc:null,srcLang:null,srcSet:null,start:_,step:null,style:null,tabIndex:_,target:null,title:null,translate:null,type:null,typeMustMatch:v,useMap:null,value:T,width:_,wrap:null,writingSuggestions:null,align:null,aLink:null,archive:S,axis:null,background:null,bgColor:null,border:_,borderColor:null,bottomMargin:_,cellPadding:null,cellSpacing:null,char:null,charOff:null,classId:null,clear:null,code:null,codeBase:null,codeType:null,color:null,compact:v,declare:v,event:null,face:null,frame:null,frameBorder:null,hSpace:_,leftMargin:_,link:null,longDesc:null,lowSrc:null,marginHeight:_,marginWidth:_,noResize:v,noHref:v,noShade:v,noWrap:v,object:null,profile:null,prompt:null,rev:null,rightMargin:_,rules:null,scheme:null,scrolling:T,standby:null,summary:null,text:null,topMargin:_,valueType:null,version:null,vAlign:null,vLink:null,vSpace:_,allowTransparency:null,autoCorrect:null,autoSave:null,credentialless:v,disablePictureInPicture:v,disableRemotePlayback:v,exportParts:ue,part:S,prefix:null,property:null,results:_,security:null,unselectable:null},space:"html",transform:ri}),Ss=Ee({attributes:{accentHeight:"accent-height",alignmentBaseline:"alignment-baseline",arabicForm:"arabic-form",baselineShift:"baseline-shift",capHeight:"cap-height",className:"class",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",colorProfile:"color-profile",colorRendering:"color-rendering",crossOrigin:"crossorigin",dataType:"datatype",dominantBaseline:"dominant-baseline",enableBackground:"enable-background",fillOpacity:"fill-opacity",fillRule:"fill-rule",floodColor:"flood-color",floodOpacity:"flood-opacity",fontFamily:"font-family",fontSize:"font-size",fontSizeAdjust:"font-size-adjust",fontStretch:"font-stretch",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",glyphName:"glyph-name",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",hrefLang:"hreflang",horizAdvX:"horiz-adv-x",horizOriginX:"horiz-origin-x",horizOriginY:"horiz-origin-y",imageRendering:"image-rendering",letterSpacing:"letter-spacing",lightingColor:"lighting-color",markerEnd:"marker-end",markerMid:"marker-mid",markerStart:"marker-start",maskType:"mask-type",navDown:"nav-down",navDownLeft:"nav-down-left",navDownRight:"nav-down-right",navLeft:"nav-left",navNext:"nav-next",navPrev:"nav-prev",navRight:"nav-right",navUp:"nav-up",navUpLeft:"nav-up-left",navUpRight:"nav-up-right",onAbort:"onabort",onActivate:"onactivate",onAfterPrint:"onafterprint",onBeforePrint:"onbeforeprint",onBegin:"onbegin",onCancel:"oncancel",onCanPlay:"oncanplay",onCanPlayThrough:"oncanplaythrough",onChange:"onchange",onClick:"onclick",onClose:"onclose",onCopy:"oncopy",onCueChange:"oncuechange",onCut:"oncut",onDblClick:"ondblclick",onDrag:"ondrag",onDragEnd:"ondragend",onDragEnter:"ondragenter",onDragExit:"ondragexit",onDragLeave:"ondragleave",onDragOver:"ondragover",onDragStart:"ondragstart",onDrop:"ondrop",onDurationChange:"ondurationchange",onEmptied:"onemptied",onEnd:"onend",onEnded:"onended",onError:"onerror",onFocus:"onfocus",onFocusIn:"onfocusin",onFocusOut:"onfocusout",onHashChange:"onhashchange",onInput:"oninput",onInvalid:"oninvalid",onKeyDown:"onkeydown",onKeyPress:"onkeypress",onKeyUp:"onkeyup",onLoad:"onload",onLoadedData:"onloadeddata",onLoadedMetadata:"onloadedmetadata",onLoadStart:"onloadstart",onMessage:"onmessage",onMouseDown:"onmousedown",onMouseEnter:"onmouseenter",onMouseLeave:"onmouseleave",onMouseMove:"onmousemove",onMouseOut:"onmouseout",onMouseOver:"onmouseover",onMouseUp:"onmouseup",onMouseWheel:"onmousewheel",onOffline:"onoffline",onOnline:"ononline",onPageHide:"onpagehide",onPageShow:"onpageshow",onPaste:"onpaste",onPause:"onpause",onPlay:"onplay",onPlaying:"onplaying",onPopState:"onpopstate",onProgress:"onprogress",onRateChange:"onratechange",onRepeat:"onrepeat",onReset:"onreset",onResize:"onresize",onScroll:"onscroll",onSeeked:"onseeked",onSeeking:"onseeking",onSelect:"onselect",onShow:"onshow",onStalled:"onstalled",onStorage:"onstorage",onSubmit:"onsubmit",onSuspend:"onsuspend",onTimeUpdate:"ontimeupdate",onToggle:"ontoggle",onUnload:"onunload",onVolumeChange:"onvolumechange",onWaiting:"onwaiting",onZoom:"onzoom",overlinePosition:"overline-position",overlineThickness:"overline-thickness",paintOrder:"paint-order",panose1:"panose-1",pointerEvents:"pointer-events",referrerPolicy:"referrerpolicy",renderingIntent:"rendering-intent",shapeRendering:"shape-rendering",stopColor:"stop-color",stopOpacity:"stop-opacity",strikethroughPosition:"strikethrough-position",strikethroughThickness:"strikethrough-thickness",strokeDashArray:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeLineCap:"stroke-linecap",strokeLineJoin:"stroke-linejoin",strokeMiterLimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",tabIndex:"tabindex",textAnchor:"text-anchor",textDecoration:"text-decoration",textRendering:"text-rendering",transformOrigin:"transform-origin",typeOf:"typeof",underlinePosition:"underline-position",underlineThickness:"underline-thickness",unicodeBidi:"unicode-bidi",unicodeRange:"unicode-range",unitsPerEm:"units-per-em",vAlphabetic:"v-alphabetic",vHanging:"v-hanging",vIdeographic:"v-ideographic",vMathematical:"v-mathematical",vectorEffect:"vector-effect",vertAdvY:"vert-adv-y",vertOriginX:"vert-origin-x",vertOriginY:"vert-origin-y",wordSpacing:"word-spacing",writingMode:"writing-mode",xHeight:"x-height",playbackOrder:"playbackorder",timelineBegin:"timelinebegin"},properties:{about:B,accentHeight:_,accumulate:null,additive:null,alignmentBaseline:null,alphabetic:_,amplitude:_,arabicForm:null,ascent:_,attributeName:null,attributeType:null,azimuth:_,bandwidth:null,baselineShift:null,baseFrequency:null,baseProfile:null,bbox:null,begin:null,bias:_,by:null,calcMode:null,capHeight:_,className:S,clip:null,clipPath:null,clipPathUnits:null,clipRule:null,color:null,colorInterpolation:null,colorInterpolationFilters:null,colorProfile:null,colorRendering:null,content:null,contentScriptType:null,contentStyleType:null,crossOrigin:null,cursor:null,cx:null,cy:null,d:null,dataType:null,defaultAction:null,descent:_,diffuseConstant:_,direction:null,display:null,dur:null,divisor:_,dominantBaseline:null,download:v,dx:null,dy:null,edgeMode:null,editable:null,elevation:_,enableBackground:null,end:null,event:null,exponent:_,externalResourcesRequired:null,fill:null,fillOpacity:_,fillRule:null,filter:null,filterRes:null,filterUnits:null,floodColor:null,floodOpacity:null,focusable:null,focusHighlight:null,fontFamily:null,fontSize:null,fontSizeAdjust:null,fontStretch:null,fontStyle:null,fontVariant:null,fontWeight:null,format:null,fr:null,from:null,fx:null,fy:null,g1:ue,g2:ue,glyphName:ue,glyphOrientationHorizontal:null,glyphOrientationVertical:null,glyphRef:null,gradientTransform:null,gradientUnits:null,handler:null,hanging:_,hatchContentUnits:null,hatchUnits:null,height:null,href:null,hrefLang:null,horizAdvX:_,horizOriginX:_,horizOriginY:_,id:null,ideographic:_,imageRendering:null,initialVisibility:null,in:null,in2:null,intercept:_,k:_,k1:_,k2:_,k3:_,k4:_,kernelMatrix:B,kernelUnitLength:null,keyPoints:null,keySplines:null,keyTimes:null,kerning:null,lang:null,lengthAdjust:null,letterSpacing:null,lightingColor:null,limitingConeAngle:_,local:null,markerEnd:null,markerMid:null,markerStart:null,markerHeight:null,markerUnits:null,markerWidth:null,mask:null,maskContentUnits:null,maskType:null,maskUnits:null,mathematical:null,max:null,media:null,mediaCharacterEncoding:null,mediaContentEncodings:null,mediaSize:_,mediaTime:null,method:null,min:null,mode:null,name:null,navDown:null,navDownLeft:null,navDownRight:null,navLeft:null,navNext:null,navPrev:null,navRight:null,navUp:null,navUpLeft:null,navUpRight:null,numOctaves:null,observer:null,offset:null,onAbort:null,onActivate:null,onAfterPrint:null,onBeforePrint:null,onBegin:null,onCancel:null,onCanPlay:null,onCanPlayThrough:null,onChange:null,onClick:null,onClose:null,onCopy:null,onCueChange:null,onCut:null,onDblClick:null,onDrag:null,onDragEnd:null,onDragEnter:null,onDragExit:null,onDragLeave:null,onDragOver:null,onDragStart:null,onDrop:null,onDurationChange:null,onEmptied:null,onEnd:null,onEnded:null,onError:null,onFocus:null,onFocusIn:null,onFocusOut:null,onHashChange:null,onInput:null,onInvalid:null,onKeyDown:null,onKeyPress:null,onKeyUp:null,onLoad:null,onLoadedData:null,onLoadedMetadata:null,onLoadStart:null,onMessage:null,onMouseDown:null,onMouseEnter:null,onMouseLeave:null,onMouseMove:null,onMouseOut:null,onMouseOver:null,onMouseUp:null,onMouseWheel:null,onOffline:null,onOnline:null,onPageHide:null,onPageShow:null,onPaste:null,onPause:null,onPlay:null,onPlaying:null,onPopState:null,onProgress:null,onRateChange:null,onRepeat:null,onReset:null,onResize:null,onScroll:null,onSeeked:null,onSeeking:null,onSelect:null,onShow:null,onStalled:null,onStorage:null,onSubmit:null,onSuspend:null,onTimeUpdate:null,onToggle:null,onUnload:null,onVolumeChange:null,onWaiting:null,onZoom:null,opacity:null,operator:null,order:null,orient:null,orientation:null,origin:null,overflow:null,overlay:null,overlinePosition:_,overlineThickness:_,paintOrder:null,panose1:null,path:null,pathLength:_,patternContentUnits:null,patternTransform:null,patternUnits:null,phase:null,ping:S,pitch:null,playbackOrder:null,pointerEvents:null,points:null,pointsAtX:_,pointsAtY:_,pointsAtZ:_,preserveAlpha:null,preserveAspectRatio:null,primitiveUnits:null,propagate:null,property:B,r:null,radius:null,referrerPolicy:null,refX:null,refY:null,rel:B,rev:B,renderingIntent:null,repeatCount:null,repeatDur:null,requiredExtensions:B,requiredFeatures:B,requiredFonts:B,requiredFormats:B,resource:null,restart:null,result:null,rotate:null,rx:null,ry:null,scale:null,seed:null,shapeRendering:null,side:null,slope:null,snapshotTime:null,specularConstant:_,specularExponent:_,spreadMethod:null,spacing:null,startOffset:null,stdDeviation:null,stemh:null,stemv:null,stitchTiles:null,stopColor:null,stopOpacity:null,strikethroughPosition:_,strikethroughThickness:_,string:null,stroke:null,strokeDashArray:B,strokeDashOffset:null,strokeLineCap:null,strokeLineJoin:null,strokeMiterLimit:_,strokeOpacity:_,strokeWidth:null,style:null,surfaceScale:_,syncBehavior:null,syncBehaviorDefault:null,syncMaster:null,syncTolerance:null,syncToleranceDefault:null,systemLanguage:B,tabIndex:_,tableValues:null,target:null,targetX:_,targetY:_,textAnchor:null,textDecoration:null,textRendering:null,textLength:null,timelineBegin:null,title:null,transformBehavior:null,type:null,typeOf:B,to:null,transform:null,transformOrigin:null,u1:null,u2:null,underlinePosition:_,underlineThickness:_,unicode:null,unicodeBidi:null,unicodeRange:null,unitsPerEm:_,values:null,vAlphabetic:_,vMathematical:_,vectorEffect:null,vHanging:_,vIdeographic:_,version:null,vertAdvY:_,vertOriginX:_,vertOriginY:_,viewBox:null,viewTarget:null,visibility:null,width:null,widths:null,wordSpacing:null,writingMode:null,x:null,x1:null,x2:null,xChannelSelector:null,xHeight:_,y:null,y1:null,y2:null,yChannelSelector:null,z:null,zoomAndPan:null},space:"svg",transform:ni}),ii=Ee({properties:{xLinkActuate:null,xLinkArcRole:null,xLinkHref:null,xLinkRole:null,xLinkShow:null,xLinkTitle:null,xLinkType:null},space:"xlink",transform(e,t){return"xlink:"+t.slice(5).toLowerCase()}}),oi=Ee({attributes:{xmlnsxlink:"xmlns:xlink"},properties:{xmlnsXLink:null,xmlns:null},space:"xmlns",transform:ri}),si=Ee({properties:{xmlBase:null,xmlLang:null,xmlSpace:null},space:"xml",transform(e,t){return"xml:"+t.slice(3).toLowerCase()}}),Ls=/[A-Z]/g,Qn=/-[a-z]/g,Rs=/^data[-\w.:]+$/i;function Is(e,t){const n=Qt(t);let r=t,i=G;if(n in e.normal)return e.property[e.normal[n]];if(n.length>4&&n.slice(0,4)==="data"&&Rs.test(t)){if(t.charAt(4)==="-"){const o=t.slice(5).replace(Qn,Ps);r="data"+o.charAt(0).toUpperCase()+o.slice(1)}else{const o=t.slice(4);if(!Qn.test(o)){let s=o.replace(Ls,Ts);s.charAt(0)!=="-"&&(s="-"+s),t="data"+s}}i=_n}return new i(r,t)}function Ts(e){return"-"+e.toLowerCase()}function Ps(e){return e.charAt(1).toUpperCase()}const Os=ei([ti,ks,ii,oi,si],"html"),ai=ei([ti,Ss,ii,oi,si],"svg"),Jn={}.hasOwnProperty;function xs(e,t){const n=t||{};function r(i,...o){let s=r.invalid;const a=r.handlers;if(i&&Jn.call(i,e)){const l=String(i[e]);s=Jn.call(a,l)?a[l]:r.unknown}if(s)return s.call(this,i,...o)}return r.handlers=n.handlers||{},r.invalid=n.invalid,r.unknown=n.unknown,r}const Ds=/["&'<>`]/g,Ns=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,Vs=/[\x01-\t\v\f\x0E-\x1F\x7F\x81\x8D\x8F\x90\x9D\xA0-\uFFFF]/g,$s=/[|\\{}()[\]^$+*?.]/g,Yn=new WeakMap;function Ms(e,t){if(e=e.replace(t.subset?Gs(t.subset):Ds,r),t.subset||t.escapeOnly)return e;return e.replace(Ns,n).replace(Vs,r);function n(i,o,s){return t.format((i.charCodeAt(0)-55296)*1024+i.charCodeAt(1)-56320+65536,s.charCodeAt(o+2),t)}function r(i,o,s){return t.format(i.charCodeAt(0),s.charCodeAt(o+1),t)}}function Gs(e){let t=Yn.get(e);return t||(t=Bs(e),Yn.set(e,t)),t}function Bs(e){const t=[];let n=-1;for(;++n<e.length;)t.push(e[n].replace($s,"\\$&"));return new RegExp("(?:"+t.join("|")+")","g")}const Us=/[\dA-Fa-f]/;function Fs(e,t,n){const r="&#x"+e.toString(16).toUpperCase();return n&&t&&!Us.test(String.fromCharCode(t))?r:r+";"}const js=/\d/;function Hs(e,t,n){const r="&#"+String(e);return n&&t&&!js.test(String.fromCharCode(t))?r:r+";"}const Ws=["AElig","AMP","Aacute","Acirc","Agrave","Aring","Atilde","Auml","COPY","Ccedil","ETH","Eacute","Ecirc","Egrave","Euml","GT","Iacute","Icirc","Igrave","Iuml","LT","Ntilde","Oacute","Ocirc","Ograve","Oslash","Otilde","Ouml","QUOT","REG","THORN","Uacute","Ucirc","Ugrave","Uuml","Yacute","aacute","acirc","acute","aelig","agrave","amp","aring","atilde","auml","brvbar","ccedil","cedil","cent","copy","curren","deg","divide","eacute","ecirc","egrave","eth","euml","frac12","frac14","frac34","gt","iacute","icirc","iexcl","igrave","iquest","iuml","laquo","lt","macr","micro","middot","nbsp","not","ntilde","oacute","ocirc","ograve","ordf","ordm","oslash","otilde","ouml","para","plusmn","pound","quot","raquo","reg","sect","shy","sup1","sup2","sup3","szlig","thorn","times","uacute","ucirc","ugrave","uml","uuml","yacute","yen","yuml"],Ot={nbsp:" ",iexcl:"¡",cent:"¢",pound:"£",curren:"¤",yen:"¥",brvbar:"¦",sect:"§",uml:"¨",copy:"©",ordf:"ª",laquo:"«",not:"¬",shy:"­",reg:"®",macr:"¯",deg:"°",plusmn:"±",sup2:"²",sup3:"³",acute:"´",micro:"µ",para:"¶",middot:"·",cedil:"¸",sup1:"¹",ordm:"º",raquo:"»",frac14:"¼",frac12:"½",frac34:"¾",iquest:"¿",Agrave:"À",Aacute:"Á",Acirc:"Â",Atilde:"Ã",Auml:"Ä",Aring:"Å",AElig:"Æ",Ccedil:"Ç",Egrave:"È",Eacute:"É",Ecirc:"Ê",Euml:"Ë",Igrave:"Ì",Iacute:"Í",Icirc:"Î",Iuml:"Ï",ETH:"Ð",Ntilde:"Ñ",Ograve:"Ò",Oacute:"Ó",Ocirc:"Ô",Otilde:"Õ",Ouml:"Ö",times:"×",Oslash:"Ø",Ugrave:"Ù",Uacute:"Ú",Ucirc:"Û",Uuml:"Ü",Yacute:"Ý",THORN:"Þ",szlig:"ß",agrave:"à",aacute:"á",acirc:"â",atilde:"ã",auml:"ä",aring:"å",aelig:"æ",ccedil:"ç",egrave:"è",eacute:"é",ecirc:"ê",euml:"ë",igrave:"ì",iacute:"í",icirc:"î",iuml:"ï",eth:"ð",ntilde:"ñ",ograve:"ò",oacute:"ó",ocirc:"ô",otilde:"õ",ouml:"ö",divide:"÷",oslash:"ø",ugrave:"ù",uacute:"ú",ucirc:"û",uuml:"ü",yacute:"ý",thorn:"þ",yuml:"ÿ",fnof:"ƒ",Alpha:"Α",Beta:"Β",Gamma:"Γ",Delta:"Δ",Epsilon:"Ε",Zeta:"Ζ",Eta:"Η",Theta:"Θ",Iota:"Ι",Kappa:"Κ",Lambda:"Λ",Mu:"Μ",Nu:"Ν",Xi:"Ξ",Omicron:"Ο",Pi:"Π",Rho:"Ρ",Sigma:"Σ",Tau:"Τ",Upsilon:"Υ",Phi:"Φ",Chi:"Χ",Psi:"Ψ",Omega:"Ω",alpha:"α",beta:"β",gamma:"γ",delta:"δ",epsilon:"ε",zeta:"ζ",eta:"η",theta:"θ",iota:"ι",kappa:"κ",lambda:"λ",mu:"μ",nu:"ν",xi:"ξ",omicron:"ο",pi:"π",rho:"ρ",sigmaf:"ς",sigma:"σ",tau:"τ",upsilon:"υ",phi:"φ",chi:"χ",psi:"ψ",omega:"ω",thetasym:"ϑ",upsih:"ϒ",piv:"ϖ",bull:"•",hellip:"…",prime:"′",Prime:"″",oline:"‾",frasl:"⁄",weierp:"℘",image:"ℑ",real:"ℜ",trade:"™",alefsym:"ℵ",larr:"←",uarr:"↑",rarr:"→",darr:"↓",harr:"↔",crarr:"↵",lArr:"⇐",uArr:"⇑",rArr:"⇒",dArr:"⇓",hArr:"⇔",forall:"∀",part:"∂",exist:"∃",empty:"∅",nabla:"∇",isin:"∈",notin:"∉",ni:"∋",prod:"∏",sum:"∑",minus:"−",lowast:"∗",radic:"√",prop:"∝",infin:"∞",ang:"∠",and:"∧",or:"∨",cap:"∩",cup:"∪",int:"∫",there4:"∴",sim:"∼",cong:"≅",asymp:"≈",ne:"≠",equiv:"≡",le:"≤",ge:"≥",sub:"⊂",sup:"⊃",nsub:"⊄",sube:"⊆",supe:"⊇",oplus:"⊕",otimes:"⊗",perp:"⊥",sdot:"⋅",lceil:"⌈",rceil:"⌉",lfloor:"⌊",rfloor:"⌋",lang:"〈",rang:"〉",loz:"◊",spades:"♠",clubs:"♣",hearts:"♥",diams:"♦",quot:'"',amp:"&",lt:"<",gt:">",OElig:"Œ",oelig:"œ",Scaron:"Š",scaron:"š",Yuml:"Ÿ",circ:"ˆ",tilde:"˜",ensp:" ",emsp:" ",thinsp:" ",zwnj:"‌",zwj:"‍",lrm:"‎",rlm:"‏",ndash:"–",mdash:"—",lsquo:"‘",rsquo:"’",sbquo:"‚",ldquo:"“",rdquo:"”",bdquo:"„",dagger:"†",Dagger:"‡",permil:"‰",lsaquo:"‹",rsaquo:"›",euro:"€"},zs=["cent","copy","divide","gt","lt","not","para","times"],li={}.hasOwnProperty,Zt={};let He;for(He in Ot)li.call(Ot,He)&&(Zt[Ot[He]]=He);const qs=/[^\dA-Za-z]/;function Xs(e,t,n,r){const i=String.fromCharCode(e);if(li.call(Zt,i)){const o=Zt[i],s="&"+o;return n&&Ws.includes(o)&&!zs.includes(o)&&(!r||t&&t!==61&&qs.test(String.fromCharCode(t)))?s:s+";"}return""}function Ks(e,t,n){let r=Fs(e,t,n.omitOptionalSemicolons),i;if((n.useNamedReferences||n.useShortestReferences)&&(i=Xs(e,t,n.omitOptionalSemicolons,n.attribute)),(n.useShortestReferences||!i)&&n.useShortestReferences){const o=Hs(e,t,n.omitOptionalSemicolons);o.length<r.length&&(r=o)}return i&&(!n.useShortestReferences||i.length<r.length)?i:r}function ye(e,t){return Ms(e,Object.assign({format:Ks},t))}const Qs=/^>|^->|<!--|-->|--!>|<!-$/g,Js=[">"],Ys=["<",">"];function Zs(e,t,n,r){return r.settings.bogusComments?"<?"+ye(e.value,Object.assign({},r.settings.characterReferences,{subset:Js}))+">":"<!--"+e.value.replace(Qs,i)+"-->";function i(o){return ye(o,Object.assign({},r.settings.characterReferences,{subset:Ys}))}}function ea(e,t,n,r){return"<!"+(r.settings.upperDoctype?"DOCTYPE":"doctype")+(r.settings.tightDoctype?"":" ")+"html>"}function Zn(e,t){const n=String(e);if(typeof t!="string")throw new TypeError("Expected character");let r=0,i=n.indexOf(t);for(;i!==-1;)r++,i=n.indexOf(t,i+t.length);return r}function ta(e,t){const n=t||{};return(e[e.length-1]===""?[...e,""]:e).join((n.padRight?" ":"")+","+(n.padLeft===!1?"":" ")).trim()}function na(e){return e.join(" ").trim()}const ra=/[ \t\n\f\r]/g;function yn(e){return typeof e=="object"?e.type==="text"?er(e.value):!1:er(e)}function er(e){return e.replace(ra,"")===""}const x=ci(1),ui=ci(-1),ia=[];function ci(e){return t;function t(n,r,i){const o=n?n.children:ia;let s=(r||0)+e,a=o[s];if(!i)for(;a&&yn(a);)s+=e,a=o[s];return a}}const oa={}.hasOwnProperty;function di(e){return t;function t(n,r,i){return oa.call(e,n.tagName)&&e[n.tagName](n,r,i)}}const En=di({body:aa,caption:xt,colgroup:xt,dd:da,dt:ca,head:xt,html:sa,li:ua,optgroup:pa,option:ha,p:la,rp:tr,rt:tr,tbody:ma,td:nr,tfoot:ga,th:nr,thead:fa,tr:_a});function xt(e,t,n){const r=x(n,t,!0);return!r||r.type!=="comment"&&!(r.type==="text"&&yn(r.value.charAt(0)))}function sa(e,t,n){const r=x(n,t);return!r||r.type!=="comment"}function aa(e,t,n){const r=x(n,t);return!r||r.type!=="comment"}function la(e,t,n){const r=x(n,t);return r?r.type==="element"&&(r.tagName==="address"||r.tagName==="article"||r.tagName==="aside"||r.tagName==="blockquote"||r.tagName==="details"||r.tagName==="div"||r.tagName==="dl"||r.tagName==="fieldset"||r.tagName==="figcaption"||r.tagName==="figure"||r.tagName==="footer"||r.tagName==="form"||r.tagName==="h1"||r.tagName==="h2"||r.tagName==="h3"||r.tagName==="h4"||r.tagName==="h5"||r.tagName==="h6"||r.tagName==="header"||r.tagName==="hgroup"||r.tagName==="hr"||r.tagName==="main"||r.tagName==="menu"||r.tagName==="nav"||r.tagName==="ol"||r.tagName==="p"||r.tagName==="pre"||r.tagName==="section"||r.tagName==="table"||r.tagName==="ul"):!n||!(n.type==="element"&&(n.tagName==="a"||n.tagName==="audio"||n.tagName==="del"||n.tagName==="ins"||n.tagName==="map"||n.tagName==="noscript"||n.tagName==="video"))}function ua(e,t,n){const r=x(n,t);return!r||r.type==="element"&&r.tagName==="li"}function ca(e,t,n){const r=x(n,t);return!!(r&&r.type==="element"&&(r.tagName==="dt"||r.tagName==="dd"))}function da(e,t,n){const r=x(n,t);return!r||r.type==="element"&&(r.tagName==="dt"||r.tagName==="dd")}function tr(e,t,n){const r=x(n,t);return!r||r.type==="element"&&(r.tagName==="rp"||r.tagName==="rt")}function pa(e,t,n){const r=x(n,t);return!r||r.type==="element"&&r.tagName==="optgroup"}function ha(e,t,n){const r=x(n,t);return!r||r.type==="element"&&(r.tagName==="option"||r.tagName==="optgroup")}function fa(e,t,n){const r=x(n,t);return!!(r&&r.type==="element"&&(r.tagName==="tbody"||r.tagName==="tfoot"))}function ma(e,t,n){const r=x(n,t);return!r||r.type==="element"&&(r.tagName==="tbody"||r.tagName==="tfoot")}function ga(e,t,n){return!x(n,t)}function _a(e,t,n){const r=x(n,t);return!r||r.type==="element"&&r.tagName==="tr"}function nr(e,t,n){const r=x(n,t);return!r||r.type==="element"&&(r.tagName==="td"||r.tagName==="th")}const ya=di({body:wa,colgroup:va,head:ba,html:Ea,tbody:Ca});function Ea(e){const t=x(e,-1);return!t||t.type!=="comment"}function ba(e){const t=new Set;for(const r of e.children)if(r.type==="element"&&(r.tagName==="base"||r.tagName==="title")){if(t.has(r.tagName))return!1;t.add(r.tagName)}const n=e.children[0];return!n||n.type==="element"}function wa(e){const t=x(e,-1,!0);return!t||t.type!=="comment"&&!(t.type==="text"&&yn(t.value.charAt(0)))&&!(t.type==="element"&&(t.tagName==="meta"||t.tagName==="link"||t.tagName==="script"||t.tagName==="style"||t.tagName==="template"))}function va(e,t,n){const r=ui(n,t),i=x(e,-1,!0);return n&&r&&r.type==="element"&&r.tagName==="colgroup"&&En(r,n.children.indexOf(r),n)?!1:!!(i&&i.type==="element"&&i.tagName==="col")}function Ca(e,t,n){const r=ui(n,t),i=x(e,-1);return n&&r&&r.type==="element"&&(r.tagName==="thead"||r.tagName==="tbody")&&En(r,n.children.indexOf(r),n)?!1:!!(i&&i.type==="element"&&i.tagName==="tr")}const We={name:[[` \f\r &/=>`.split(""),` diff --git a/apps/kimi-code/dist-web/assets/index-D-7nOosq.js b/apps/kimi-code/dist-web/assets/index-D-7nOosq.js new file mode 100644 index 000000000..f2c6fdf4b --- /dev/null +++ b/apps/kimi-code/dist-web/assets/index-D-7nOosq.js @@ -0,0 +1,638 @@ +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mhchem-DtR62fUK.js","assets/katex-DnlPpQZa.js","assets/mermaid.core-CJB1tAev.js","assets/_commonjsHelpers-CqkleIqs.js","assets/CodeBlockNode-BAtAs_qm.js","assets/safeRaf-DGuzXxDK.js","assets/index5-Cn2jfVMX.js","assets/index11-Ci8_PlMN.js","assets/DesignSystemView-CTUhpkDe.js","assets/DesignSystemView-DVONbdv-.css","assets/rive-CeXCFBdn.js"])))=>i.map(i=>d[i]); +(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))o(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const r of i.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&o(r)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function o(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();/** +* @vue/shared v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/function Dg(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const An={},Id=[],wr=()=>{},xS=()=>!1,Fp=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),Bg=e=>e.startsWith("onUpdate:"),to=Object.assign,I8=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},pR=Object.prototype.hasOwnProperty,Kn=(e,t)=>pR.call(e,t),jt=Array.isArray,Ld=e=>c1(e)==="[object Map]",Ac=e=>c1(e)==="[object Set]",k7=e=>c1(e)==="[object Date]",hR=e=>c1(e)==="[object RegExp]",un=e=>typeof e=="function",ro=e=>typeof e=="string",lr=e=>typeof e=="symbol",Zn=e=>e!==null&&typeof e=="object",L8=e=>(Zn(e)||un(e))&&un(e.then)&&un(e.catch),SS=Object.prototype.toString,c1=e=>SS.call(e),mR=e=>c1(e).slice(8,-1),Hg=e=>c1(e)==="[object Object]",zg=e=>ro(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,oc=Dg(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Wg=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},gR=/-\w/g,_s=Wg(e=>e.replace(gR,t=>t.slice(1).toUpperCase())),vR=/\B([A-Z])/g,Bi=Wg(e=>e.replace(vR,"-$1").toLowerCase()),Ug=Wg(e=>e.charAt(0).toUpperCase()+e.slice(1)),Fh=Wg(e=>e?`on${Ug(e)}`:""),Es=(e,t)=>!Object.is(e,t),$d=(e,...t)=>{for(let n=0;n<e.length;n++)e[n](...t)},AS=(e,t,n,o=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:o,value:n})},jg=e=>{const t=parseFloat(e);return isNaN(t)?e:t},cm=e=>{const t=ro(e)?Number(e):NaN;return isNaN(t)?e:t};let b7;const Vg=()=>b7||(b7=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),yR="Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol",kR=Dg(yR);function Zt(e){if(jt(e)){const t={};for(let n=0;n<e.length;n++){const o=e[n],s=ro(o)?_R(o):Zt(o);if(s)for(const i in s)t[i]=s[i]}return t}else if(ro(e)||Zn(e))return e}const bR=/;(?![^(]*\))/g,CR=/:([^]+)/,wR=/\/\*[^]*?\*\//g;function _R(e){const t={};return e.replace(wR,"").split(bR).forEach(n=>{if(n){const o=n.split(CR);o.length>1&&(t[o[0].trim()]=o[1].trim())}}),t}function Re(e){let t="";if(ro(e))t=e;else if(jt(e))for(let n=0;n<e.length;n++){const o=Re(e[n]);o&&(t+=o+" ")}else if(Zn(e))for(const n in e)e[n]&&(t+=n+" ");return t.trim()}function xR(e){if(!e)return null;let{class:t,style:n}=e;return t&&!ro(t)&&(e.class=Re(t)),n&&(e.style=Zt(n)),e}const SR="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",AR=Dg(SR);function MS(e){return!!e||e===""}function MR(e,t){if(e.length!==t.length)return!1;let n=!0;for(let o=0;n&&o<e.length;o++)n=sa(e[o],t[o]);return n}function sa(e,t){if(e===t)return!0;let n=k7(e),o=k7(t);if(n||o)return n&&o?e.getTime()===t.getTime():!1;if(n=lr(e),o=lr(t),n||o)return e===t;if(n=jt(e),o=jt(t),n||o)return n&&o?MR(e,t):!1;if(n=Zn(e),o=Zn(t),n||o){if(!n||!o)return!1;const s=Object.keys(e).length,i=Object.keys(t).length;if(s!==i)return!1;for(const r in e){const l=e.hasOwnProperty(r),a=t.hasOwnProperty(r);if(l&&!a||!l&&a||!sa(e[r],t[r]))return!1}}return String(e)===String(t)}function qg(e,t){return e.findIndex(n=>sa(n,t))}const TS=e=>!!(e&&e.__v_isRef===!0),N=e=>ro(e)?e:e==null?"":jt(e)||Zn(e)&&(e.toString===SS||!un(e.toString))?TS(e)?N(e.value):JSON.stringify(e,ES,2):String(e),ES=(e,t)=>TS(t)?ES(e,t.value):Ld(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[o,s],i)=>(n[Dv(o,i)+" =>"]=s,n),{})}:Ac(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>Dv(n))}:lr(t)?Dv(t):Zn(t)&&!jt(t)&&!Hg(t)?String(t):t,Dv=(e,t="")=>{var n;return lr(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};function TR(e){return e==null?"initial":typeof e=="string"?e===""?" ":e:String(e)}/** +* @vue/reactivity v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let ks;class IS{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ks&&(ks.active?(this.parent=ks,this.index=(ks.scopes||(ks.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].pause();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].resume();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].resume()}}run(t){if(this._active){const n=ks;try{return ks=this,t()}finally{ks=n}}}on(){++this._on===1&&(this.prevScope=ks,ks=this)}off(){if(this._on>0&&--this._on===0){if(ks===this)ks=this.prevScope;else{let t=ks;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,o;for(n=0,o=this.effects.length;n<o;n++)this.effects[n].stop();for(this.effects.length=0,n=0,o=this.cleanups.length;n<o;n++)this.cleanups[n]();if(this.cleanups.length=0,this.scopes){for(n=0,o=this.scopes.length;n<o;n++)this.scopes[n].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const s=this.parent.scopes.pop();s&&s!==this&&(this.parent.scopes[this.index]=s,s.index=this.index)}this.parent=void 0}}}function ER(e){return new IS(e)}function Kg(){return ks}function d1(e,t=!1){ks&&ks.cleanups.push(e)}let ho;const Bv=new WeakSet;class dm{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ks&&(ks.active?ks.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,Bv.has(this)&&(Bv.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||$S(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,C7(this),NS(this);const t=ho,n=jr;ho=this,jr=!0;try{return this.fn()}finally{FS(this),ho=t,jr=n,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)F8(t);this.deps=this.depsTail=void 0,C7(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?Bv.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){A4(this)&&this.run()}get dirty(){return A4(this)}}let LS=0,$f,Nf;function $S(e,t=!1){if(e.flags|=8,t){e.next=Nf,Nf=e;return}e.next=$f,$f=e}function $8(){LS++}function N8(){if(--LS>0)return;if(Nf){let t=Nf;for(Nf=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;$f;){let t=$f;for($f=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(o){e||(e=o)}t=n}}if(e)throw e}function NS(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function FS(e){let t,n=e.depsTail,o=n;for(;o;){const s=o.prevDep;o.version===-1?(o===n&&(n=s),F8(o),IR(o)):t=o,o.dep.activeLink=o.prevActiveLink,o.prevActiveLink=void 0,o=s}e.deps=t,e.depsTail=n}function A4(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(RS(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function RS(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===ip)||(e.globalVersion=ip,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!A4(e))))return;e.flags|=2;const t=e.dep,n=ho,o=jr;ho=e,jr=!0;try{NS(e);const s=e.fn(e._value);(t.version===0||Es(s,e._value))&&(e.flags|=128,e._value=s,t.version++)}catch(s){throw t.version++,s}finally{ho=n,jr=o,FS(e),e.flags&=-3}}function F8(e,t=!1){const{dep:n,prevSub:o,nextSub:s}=e;if(o&&(o.nextSub=s,e.prevSub=void 0),s&&(s.prevSub=o,e.nextSub=void 0),n.subs===e&&(n.subs=o,!o&&n.computed)){n.computed.flags&=-5;for(let i=n.computed.deps;i;i=i.nextDep)F8(i,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function IR(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}function kje(e,t){e.effect instanceof dm&&(e=e.effect.fn);const n=new dm(e);t&&to(n,t);try{n.run()}catch(s){throw n.stop(),s}const o=n.run.bind(n);return o.effect=n,o}function bje(e){e.effect.stop()}let jr=!0;const OS=[];function wl(){OS.push(jr),jr=!1}function _l(){const e=OS.pop();jr=e===void 0?!0:e}function C7(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=ho;ho=void 0;try{t()}finally{ho=n}}}let ip=0;class LR{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Zg{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!ho||!jr||ho===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==ho)n=this.activeLink=new LR(ho,this),ho.deps?(n.prevDep=ho.depsTail,ho.depsTail.nextDep=n,ho.depsTail=n):ho.deps=ho.depsTail=n,PS(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const o=n.nextDep;o.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=o),n.prevDep=ho.depsTail,n.nextDep=void 0,ho.depsTail.nextDep=n,ho.depsTail=n,ho.deps===n&&(ho.deps=o)}return n}trigger(t){this.version++,ip++,this.notify(t)}notify(t){$8();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{N8()}}}function PS(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let o=t.deps;o;o=o.nextDep)PS(o)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const fm=new WeakMap,sc=Symbol(""),M4=Symbol(""),rp=Symbol("");function ii(e,t,n){if(jr&&ho){let o=fm.get(e);o||fm.set(e,o=new Map);let s=o.get(n);s||(o.set(n,s=new Zg),s.map=o,s.key=n),s.track()}}function Zl(e,t,n,o,s,i){const r=fm.get(e);if(!r){ip++;return}const l=a=>{a&&a.trigger()};if($8(),t==="clear")r.forEach(l);else{const a=jt(e),u=a&&zg(n);if(a&&n==="length"){const c=Number(o);r.forEach((d,f)=>{(f==="length"||f===rp||!lr(f)&&f>=c)&&l(d)})}else switch((n!==void 0||r.has(void 0))&&l(r.get(n)),u&&l(r.get(rp)),t){case"add":a?u&&l(r.get("length")):(l(r.get(sc)),Ld(e)&&l(r.get(M4)));break;case"delete":a||(l(r.get(sc)),Ld(e)&&l(r.get(M4)));break;case"set":Ld(e)&&l(r.get(sc));break}}N8()}function $R(e,t){const n=fm.get(e);return n&&n.get(t)}function Jc(e){const t=Pn(e);return t===e?t:(ii(t,"iterate",rp),tr(e)?t:t.map(Kr))}function Gg(e){return ii(e=Pn(e),"iterate",rp),e}function ml(e,t){return ia(e)?Xd(Wa(e)?Kr(t):t):Kr(t)}const NR={__proto__:null,[Symbol.iterator](){return Hv(this,Symbol.iterator,e=>ml(this,e))},concat(...e){return Jc(this).concat(...e.map(t=>jt(t)?Jc(t):t))},entries(){return Hv(this,"entries",e=>(e[1]=ml(this,e[1]),e))},every(e,t){return Hl(this,"every",e,t,void 0,arguments)},filter(e,t){return Hl(this,"filter",e,t,n=>n.map(o=>ml(this,o)),arguments)},find(e,t){return Hl(this,"find",e,t,n=>ml(this,n),arguments)},findIndex(e,t){return Hl(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return Hl(this,"findLast",e,t,n=>ml(this,n),arguments)},findLastIndex(e,t){return Hl(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return Hl(this,"forEach",e,t,void 0,arguments)},includes(...e){return zv(this,"includes",e)},indexOf(...e){return zv(this,"indexOf",e)},join(e){return Jc(this).join(e)},lastIndexOf(...e){return zv(this,"lastIndexOf",e)},map(e,t){return Hl(this,"map",e,t,void 0,arguments)},pop(){return G1(this,"pop")},push(...e){return G1(this,"push",e)},reduce(e,...t){return w7(this,"reduce",e,t)},reduceRight(e,...t){return w7(this,"reduceRight",e,t)},shift(){return G1(this,"shift")},some(e,t){return Hl(this,"some",e,t,void 0,arguments)},splice(...e){return G1(this,"splice",e)},toReversed(){return Jc(this).toReversed()},toSorted(e){return Jc(this).toSorted(e)},toSpliced(...e){return Jc(this).toSpliced(...e)},unshift(...e){return G1(this,"unshift",e)},values(){return Hv(this,"values",e=>ml(this,e))}};function Hv(e,t,n){const o=Gg(e),s=o[t]();return o!==e&&!tr(e)&&(s._next=s.next,s.next=()=>{const i=s._next();return i.done||(i.value=n(i.value)),i}),s}const FR=Array.prototype;function Hl(e,t,n,o,s,i){const r=Gg(e),l=r!==e&&!tr(e),a=r[t];if(a!==FR[t]){const d=a.apply(e,i);return l?Kr(d):d}let u=n;r!==e&&(l?u=function(d,f){return n.call(this,ml(e,d),f,e)}:n.length>2&&(u=function(d,f){return n.call(this,d,f,e)}));const c=a.call(r,u,o);return l&&s?s(c):c}function w7(e,t,n,o){const s=Gg(e),i=s!==e&&!tr(e);let r=n,l=!1;s!==e&&(i?(l=o.length===0,r=function(u,c,d){return l&&(l=!1,u=ml(e,u)),n.call(this,u,ml(e,c),d,e)}):n.length>3&&(r=function(u,c,d){return n.call(this,u,c,d,e)}));const a=s[t](r,...o);return l?ml(e,a):a}function zv(e,t,n){const o=Pn(e);ii(o,"iterate",rp);const s=o[t](...n);return(s===-1||s===!1)&&Jg(n[0])?(n[0]=Pn(n[0]),o[t](...n)):s}function G1(e,t,n=[]){wl(),$8();const o=Pn(e)[t].apply(e,n);return N8(),_l(),o}const RR=Dg("__proto__,__v_isRef,__isVue"),DS=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(lr));function OR(e){lr(e)||(e=String(e));const t=Pn(this);return ii(t,"has",e),t.hasOwnProperty(e)}class BS{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,o){if(n==="__v_skip")return t.__v_skip;const s=this._isReadonly,i=this._isShallow;if(n==="__v_isReactive")return!s;if(n==="__v_isReadonly")return s;if(n==="__v_isShallow")return i;if(n==="__v_raw")return o===(s?i?VS:jS:i?US:WS).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(o)?t:void 0;const r=jt(t);if(!s){let a;if(r&&(a=NR[n]))return a;if(n==="hasOwnProperty")return OR}const l=Reflect.get(t,n,Xo(t)?t:o);if((lr(n)?DS.has(n):RR(n))||(s||ii(t,"get",n),i))return l;if(Xo(l)){const a=r&&zg(n)?l:l.value;return s&&Zn(a)?E4(a):a}return Zn(l)?s?E4(l):Go(l):l}}class HS extends BS{constructor(t=!1){super(!1,t)}set(t,n,o,s){let i=t[n];const r=jt(t)&&zg(n);if(!this._isShallow){const u=ia(i);if(!tr(o)&&!ia(o)&&(i=Pn(i),o=Pn(o)),!r&&Xo(i)&&!Xo(o))return u||(i.value=o),!0}const l=r?Number(n)<t.length:Kn(t,n),a=Reflect.set(t,n,o,Xo(t)?t:s);return t===Pn(s)&&a&&(l?Es(o,i)&&Zl(t,"set",n,o):Zl(t,"add",n,o)),a}deleteProperty(t,n){const o=Kn(t,n);t[n];const s=Reflect.deleteProperty(t,n);return s&&o&&Zl(t,"delete",n,void 0),s}has(t,n){const o=Reflect.has(t,n);return(!lr(n)||!DS.has(n))&&ii(t,"has",n),o}ownKeys(t){return ii(t,"iterate",jt(t)?"length":sc),Reflect.ownKeys(t)}}class zS extends BS{constructor(t=!1){super(!0,t)}set(t,n){return!0}deleteProperty(t,n){return!0}}const PR=new HS,DR=new zS,BR=new HS(!0),HR=new zS(!0),T4=e=>e,P0=e=>Reflect.getPrototypeOf(e);function zR(e,t,n){return function(...o){const s=this.__v_raw,i=Pn(s),r=Ld(i),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,u=s[e](...o),c=n?T4:t?Xd:Kr;return!t&&ii(i,"iterate",a?M4:sc),to(Object.create(u),{next(){const{value:d,done:f}=u.next();return f?{value:d,done:f}:{value:l?[c(d[0]),c(d[1])]:c(d),done:f}}})}}function D0(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function WR(e,t){const n={get(s){const i=this.__v_raw,r=Pn(i),l=Pn(s);e||(Es(s,l)&&ii(r,"get",s),ii(r,"get",l));const{has:a}=P0(r),u=t?T4:e?Xd:Kr;if(a.call(r,s))return u(i.get(s));if(a.call(r,l))return u(i.get(l));i!==r&&i.get(s)},get size(){const s=this.__v_raw;return!e&&ii(Pn(s),"iterate",sc),s.size},has(s){const i=this.__v_raw,r=Pn(i),l=Pn(s);return e||(Es(s,l)&&ii(r,"has",s),ii(r,"has",l)),s===l?i.has(s):i.has(s)||i.has(l)},forEach(s,i){const r=this,l=r.__v_raw,a=Pn(l),u=t?T4:e?Xd:Kr;return!e&&ii(a,"iterate",sc),l.forEach((c,d)=>s.call(i,u(c),u(d),r))}};return to(n,e?{add:D0("add"),set:D0("set"),delete:D0("delete"),clear:D0("clear")}:{add(s){const i=Pn(this),r=P0(i),l=Pn(s),a=!t&&!tr(s)&&!ia(s)?l:s;return r.has.call(i,a)||Es(s,a)&&r.has.call(i,s)||Es(l,a)&&r.has.call(i,l)||(i.add(a),Zl(i,"add",a,a)),this},set(s,i){!t&&!tr(i)&&!ia(i)&&(i=Pn(i));const r=Pn(this),{has:l,get:a}=P0(r);let u=l.call(r,s);u||(s=Pn(s),u=l.call(r,s));const c=a.call(r,s);return r.set(s,i),u?Es(i,c)&&Zl(r,"set",s,i):Zl(r,"add",s,i),this},delete(s){const i=Pn(this),{has:r,get:l}=P0(i);let a=r.call(i,s);a||(s=Pn(s),a=r.call(i,s)),l&&l.call(i,s);const u=i.delete(s);return a&&Zl(i,"delete",s,void 0),u},clear(){const s=Pn(this),i=s.size!==0,r=s.clear();return i&&Zl(s,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(s=>{n[s]=zR(s,e,t)}),n}function Yg(e,t){const n=WR(e,t);return(o,s,i)=>s==="__v_isReactive"?!e:s==="__v_isReadonly"?e:s==="__v_raw"?o:Reflect.get(Kn(n,s)&&s in o?n:o,s,i)}const UR={get:Yg(!1,!1)},jR={get:Yg(!1,!0)},VR={get:Yg(!0,!1)},qR={get:Yg(!0,!0)},WS=new WeakMap,US=new WeakMap,jS=new WeakMap,VS=new WeakMap;function KR(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function Go(e){return ia(e)?e:Xg(e,!1,PR,UR,WS)}function qS(e){return Xg(e,!1,BR,jR,US)}function E4(e){return Xg(e,!0,DR,VR,jS)}function Cje(e){return Xg(e,!0,HR,qR,VS)}function Xg(e,t,n,o,s){if(!Zn(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const i=s.get(e);if(i)return i;const r=KR(mR(e));if(r===0)return e;const l=new Proxy(e,r===2?o:n);return s.set(e,l),l}function Wa(e){return ia(e)?Wa(e.__v_raw):!!(e&&e.__v_isReactive)}function ia(e){return!!(e&&e.__v_isReadonly)}function tr(e){return!!(e&&e.__v_isShallow)}function Jg(e){return e?!!e.__v_raw:!1}function Pn(e){const t=e&&e.__v_raw;return t?Pn(t):e}function kt(e){return!Kn(e,"__v_skip")&&Object.isExtensible(e)&&AS(e,"__v_skip",!0),e}const Kr=e=>Zn(e)?Go(e):e,Xd=e=>Zn(e)?E4(e):e;function Xo(e){return e?e.__v_isRef===!0:!1}function Z(e){return KS(e,!1)}function Xr(e){return KS(e,!0)}function KS(e,t){return Xo(e)?e:new ZR(e,t)}class ZR{constructor(t,n){this.dep=new Zg,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:Pn(t),this._value=n?t:Kr(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,o=this.__v_isShallow||tr(t)||ia(t);t=o?t:Pn(t),Es(t,n)&&(this._rawValue=t,this._value=o?t:Kr(t),this.dep.trigger())}}function GR(e){e.dep&&e.dep.trigger()}function p(e){return Xo(e)?e.value:e}function Rh(e){return un(e)?e():p(e)}const YR={get:(e,t,n)=>t==="__v_raw"?e:p(Reflect.get(e,t,n)),set:(e,t,n,o)=>{const s=e[t];return Xo(s)&&!Xo(n)?(s.value=n,!0):Reflect.set(e,t,n,o)}};function ZS(e){return Wa(e)?e:new Proxy(e,YR)}class XR{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Zg,{get:o,set:s}=t(n.track.bind(n),n.trigger.bind(n));this._get=o,this._set=s}get value(){return this._value=this._get()}set value(t){this._set(t)}}function JR(e){return new XR(e)}function wje(e){const t=jt(e)?new Array(e.length):{};for(const n in e)t[n]=GS(e,n);return t}class QR{constructor(t,n,o){this._object=t,this._defaultValue=o,this.__v_isRef=!0,this._value=void 0,this._key=lr(n)?n:String(n),this._raw=Pn(t);let s=!0,i=t;if(!jt(t)||lr(this._key)||!zg(this._key))do s=!Jg(i)||tr(i);while(s&&(i=i.__v_raw));this._shallow=s}get value(){let t=this._object[this._key];return this._shallow&&(t=p(t)),this._value=t===void 0?this._defaultValue:t}set value(t){if(this._shallow&&Xo(this._raw[this._key])){const n=this._object[this._key];if(Xo(n)){n.value=t;return}}this._object[this._key]=t}get dep(){return $R(this._raw,this._key)}}class eO{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function _je(e,t,n){return Xo(e)?e:un(e)?new eO(e):Zn(e)&&arguments.length>1?GS(e,t,n):Z(e)}function GS(e,t,n){return new QR(e,t,n)}class tO{constructor(t,n,o){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Zg(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=ip-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=o}notify(){if(this.flags|=16,!(this.flags&8)&&ho!==this)return $S(this,!0),!0}get value(){const t=this.dep.track();return RS(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function nO(e,t,n=!1){let o,s;return un(e)?o=e:(o=e.get,s=e.set),new tO(o,s,n)}const xje={GET:"get",HAS:"has",ITERATE:"iterate"},Sje={SET:"set",ADD:"add",DELETE:"delete",CLEAR:"clear"},B0={},pm=new WeakMap;let La;function Aje(){return La}function oO(e,t=!1,n=La){if(n){let o=pm.get(n);o||pm.set(n,o=[]),o.push(e)}}function sO(e,t,n=An){const{immediate:o,deep:s,once:i,scheduler:r,augmentJob:l,call:a}=n,u=g=>s?g:tr(g)||s===!1||s===0?Gl(g,1):Gl(g);let c,d,f,h,m=!1,v=!1;if(Xo(e)?(d=()=>e.value,m=tr(e)):Wa(e)?(d=()=>u(e),m=!0):jt(e)?(v=!0,m=e.some(g=>Wa(g)||tr(g)),d=()=>e.map(g=>{if(Xo(g))return g.value;if(Wa(g))return u(g);if(un(g))return a?a(g,2):g()})):un(e)?t?d=a?()=>a(e,2):e:d=()=>{if(f){wl();try{f()}finally{_l()}}const g=La;La=c;try{return a?a(e,3,[h]):e(h)}finally{La=g}}:d=wr,t&&s){const g=d,x=s===!0?1/0:s;d=()=>Gl(g(),x)}const k=Kg(),w=()=>{c.stop(),k&&k.active&&I8(k.effects,c)};if(i&&t){const g=t;t=(...x)=>{const S=g(...x);return w(),S}}let b=v?new Array(e.length).fill(B0):B0;const _=g=>{if(!(!(c.flags&1)||!c.dirty&&!g))if(t){const x=c.run();if(g||s||m||(v?x.some((S,T)=>Es(S,b[T])):Es(x,b))){f&&f();const S=La;La=c;try{const T=[x,b===B0?void 0:v&&b[0]===B0?[]:b,h];b=x,a?a(t,3,T):t(...T)}finally{La=S}}}else c.run()};return l&&l(_),c=new dm(d),c.scheduler=r?()=>r(_,!1):_,h=g=>oO(g,!1,c),f=c.onStop=()=>{const g=pm.get(c);if(g){if(a)a(g,4);else for(const x of g)x();pm.delete(c)}},t?o?_(!0):b=c.run():r?r(_.bind(null,!0),!0):c.run(),w.pause=c.pause.bind(c),w.resume=c.resume.bind(c),w.stop=w,w}function Gl(e,t=1/0,n){if(t<=0||!Zn(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,Xo(e))Gl(e.value,t,n);else if(jt(e))for(let o=0;o<e.length;o++)Gl(e[o],t,n);else if(Ac(e)||Ld(e))e.forEach(o=>{Gl(o,t,n)});else if(Hg(e)){for(const o in e)Gl(e[o],t,n);for(const o of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,o)&&Gl(e[o],t,n)}return e}/** +* @vue/runtime-core v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/const YS=[];function iO(e){YS.push(e)}function rO(){YS.pop()}function Mje(e,t){}const Tje={SETUP_FUNCTION:0,0:"SETUP_FUNCTION",RENDER_FUNCTION:1,1:"RENDER_FUNCTION",NATIVE_EVENT_HANDLER:5,5:"NATIVE_EVENT_HANDLER",COMPONENT_EVENT_HANDLER:6,6:"COMPONENT_EVENT_HANDLER",VNODE_HOOK:7,7:"VNODE_HOOK",DIRECTIVE_HOOK:8,8:"DIRECTIVE_HOOK",TRANSITION_HOOK:9,9:"TRANSITION_HOOK",APP_ERROR_HANDLER:10,10:"APP_ERROR_HANDLER",APP_WARN_HANDLER:11,11:"APP_WARN_HANDLER",FUNCTION_REF:12,12:"FUNCTION_REF",ASYNC_COMPONENT_LOADER:13,13:"ASYNC_COMPONENT_LOADER",SCHEDULER:14,14:"SCHEDULER",COMPONENT_UPDATE:15,15:"COMPONENT_UPDATE",APP_UNMOUNT_CLEANUP:16,16:"APP_UNMOUNT_CLEANUP"},lO={sp:"serverPrefetch hook",bc:"beforeCreate hook",c:"created hook",bm:"beforeMount hook",m:"mounted hook",bu:"beforeUpdate hook",u:"updated",bum:"beforeUnmount hook",um:"unmounted hook",a:"activated hook",da:"deactivated hook",ec:"errorCaptured hook",rtc:"renderTracked hook",rtg:"renderTriggered hook",0:"setup function",1:"render function",2:"watcher getter",3:"watcher callback",4:"watcher cleanup function",5:"native event handler",6:"component event handler",7:"vnode hook",8:"directive hook",9:"transition hook",10:"app errorHandler",11:"app warnHandler",12:"ref function",13:"async component loader",14:"scheduler flush",15:"component update",16:"app unmount cleanup function"};function Rp(e,t,n,o){try{return o?e(...o):e()}catch(s){f1(s,t,n)}}function xr(e,t,n,o){if(un(e)){const s=Rp(e,t,n,o);return s&&L8(s)&&s.catch(i=>{f1(i,t,n)}),s}if(jt(e)){const s=[];for(let i=0;i<e.length;i++)s.push(xr(e[i],t,n,o));return s}}function f1(e,t,n,o=!0){const s=t?t.vnode:null,{errorHandler:i,throwUnhandledErrorInProduction:r}=t&&t.appContext.config||An;if(t){let l=t.parent;const a=t.proxy,u=`https://vuejs.org/error-reference/#runtime-${n}`;for(;l;){const c=l.ec;if(c){for(let d=0;d<c.length;d++)if(c[d](e,a,u)===!1)return}l=l.parent}if(i){wl(),Rp(i,null,10,[e,a,u]),_l();return}}aO(e,n,s,o,r)}function aO(e,t,n,o=!0,s=!1){if(s)throw e;console.error(e)}const yi=[];let fl=-1;const Nd=[];let $a=null,dd=0;const XS=Promise.resolve();let hm=null;function yt(e){const t=hm||XS;return e?t.then(this?e.bind(this):e):t}function uO(e){let t=fl+1,n=yi.length;for(;t<n;){const o=t+n>>>1,s=yi[o],i=lp(s);i<e||i===e&&s.flags&2?t=o+1:n=o}return t}function R8(e){if(!(e.flags&1)){const t=lp(e),n=yi[yi.length-1];!n||!(e.flags&2)&&t>=lp(n)?yi.push(e):yi.splice(uO(t),0,e),e.flags|=1,JS()}}function JS(){hm||(hm=XS.then(QS))}function mm(e){jt(e)?Nd.push(...e):$a&&e.id===-1?$a.splice(dd+1,0,e):e.flags&1||(Nd.push(e),e.flags|=1),JS()}function _7(e,t,n=fl+1){for(;n<yi.length;n++){const o=yi[n];if(o&&o.flags&2){if(e&&o.id!==e.uid)continue;yi.splice(n,1),n--,o.flags&4&&(o.flags&=-2),o(),o.flags&4||(o.flags&=-2)}}}function gm(e){if(Nd.length){const t=[...new Set(Nd)].sort((n,o)=>lp(n)-lp(o));if(Nd.length=0,$a){$a.push(...t);return}for($a=t,dd=0;dd<$a.length;dd++){const n=$a[dd];n.flags&4&&(n.flags&=-2),n.flags&8||n(),n.flags&=-2}$a=null,dd=0}}const lp=e=>e.id==null?e.flags&2?-1:1/0:e.id;function QS(e){try{for(fl=0;fl<yi.length;fl++){const t=yi[fl];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),Rp(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;fl<yi.length;fl++){const t=yi[fl];t&&(t.flags&=-2)}fl=-1,yi.length=0,gm(),hm=null,(yi.length||Nd.length)&&QS()}}let fd,H0=[];function eA(e,t){var n,o;fd=e,fd?(fd.enabled=!0,H0.forEach(({event:s,args:i})=>fd.emit(s,...i)),H0=[]):typeof window<"u"&&window.HTMLElement&&!((o=(n=window.navigator)==null?void 0:n.userAgent)!=null&&o.includes("jsdom"))?((t.__VUE_DEVTOOLS_HOOK_REPLAY__=t.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push(i=>{eA(i,t)}),setTimeout(()=>{fd||(t.__VUE_DEVTOOLS_HOOK_REPLAY__=null,H0=[])},3e3)):H0=[]}let Ks=null,Qg=null;function ap(e){const t=Ks;return Ks=e,Qg=e&&e.type.__scopeId||null,t}function Eje(e){Qg=e}function Ije(){Qg=null}const Lje=e=>me;function me(e,t=Ks,n){if(!t||e._n)return e;const o=(...s)=>{o._d&&wm(-1);const i=ap(t);let r;try{r=e(...s)}finally{ap(i),o._d&&wm(1)}return r};return o._n=!0,o._c=!0,o._d=!0,o}function Bn(e,t){if(Ks===null)return e;const n=Bp(Ks),o=e.dirs||(e.dirs=[]);for(let s=0;s<t.length;s++){let[i,r,l,a=An]=t[s];i&&(un(i)&&(i={mounted:i,updated:i}),i.deep&&Gl(r),o.push({dir:i,instance:n,value:r,oldValue:void 0,arg:l,modifiers:a}))}return e}function hl(e,t,n,o){const s=e.dirs,i=t&&t.dirs;for(let r=0;r<s.length;r++){const l=s[r];i&&(l.oldValue=i[r].value);let a=l.dir[o];a&&(wl(),xr(a,n,8,[e.el,l,e,t]),_l())}}function Ln(e,t){if(Vs){let n=Vs.provides;const o=Vs.parent&&Vs.parent.provides;o===n&&(n=Vs.provides=Object.create(o)),n[e]=t}}function nn(e,t,n=!1){const o=ds();if(o||ic){let s=ic?ic._context.provides:o?o.parent==null||o.ce?o.vnode.appContext&&o.vnode.appContext.provides:o.parent.provides:void 0;if(s&&e in s)return s[e];if(arguments.length>1)return n&&un(t)?t.call(o&&o.proxy):t}}function $je(){return!!(ds()||ic)}const cO=Symbol.for("v-scx"),dO=()=>nn(cO);function I4(e,t){return Op(e,null,t)}function Nje(e,t){return Op(e,null,{flush:"post"})}function fO(e,t){return Op(e,null,{flush:"sync"})}function Je(e,t,n){return Op(e,t,n)}function Op(e,t,n=An){const{immediate:o,deep:s,flush:i,once:r}=n,l=to({},n),a=t&&o||!t&&i!=="post";let u;if(fc){if(i==="sync"){const h=dO();u=h.__watcherHandles||(h.__watcherHandles=[])}else if(!a){const h=()=>{};return h.stop=wr,h.resume=wr,h.pause=wr,h}}const c=Vs;l.call=(h,m,v)=>xr(h,c,m,v);let d=!1;i==="post"?l.scheduler=h=>{os(h,c&&c.suspense)}:i!=="sync"&&(d=!0,l.scheduler=(h,m)=>{m?h():R8(h)}),l.augmentJob=h=>{t&&(h.flags|=4),d&&(h.flags|=2,c&&(h.id=c.uid,h.i=c))};const f=sO(e,t,l);return fc&&(u?u.push(f):a&&f()),f}function pO(e,t,n){const o=this.proxy,s=ro(e)?e.includes(".")?tA(o,e):()=>o[e]:e.bind(o,o);let i;un(t)?i=t:(i=t.handler,n=t);const r=h1(this),l=Op(s,i.bind(o),n);return r(),l}function tA(e,t){const n=t.split(".");return()=>{let o=e;for(let s=0;s<n.length&&o;s++)o=o[n[s]];return o}}const Aa=new WeakMap,nA=Symbol("_vte"),oA=e=>e.__isTeleport,Vu=e=>e&&(e.disabled||e.disabled===""),hO=e=>e&&(e.defer||e.defer===""),x7=e=>typeof SVGElement<"u"&&e instanceof SVGElement,S7=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,L4=(e,t)=>{const n=e&&e.to;return ro(n)?t?t(n):null:n},mO={name:"Teleport",__isTeleport:!0,process(e,t,n,o,s,i,r,l,a,u){const{mc:c,pc:d,pbc:f,o:{insert:h,querySelector:m,createText:v,createComment:k,parentNode:w}}=u,b=Vu(t.props);let{dynamicChildren:_}=t;const g=(T,A,E)=>{T.shapeFlag&16&&c(T.children,A,E,s,i,r,l,a)},x=(T=t)=>{const A=Vu(T.props),E=T.target=L4(T.props,m),P=$4(E,T,v,h);E&&(r!=="svg"&&x7(E)?r="svg":r!=="mathml"&&S7(E)&&(r="mathml"),s&&s.isCE&&(s.ce._teleportTargets||(s.ce._teleportTargets=new Set)).add(E),A||(g(T,E,P),pf(T,!1)))},S=T=>{const A=()=>{if(Aa.get(T)===A){if(Aa.delete(T),Vu(T.props)){const E=w(T.el)||n;g(T,E,T.anchor),pf(T,!0)}x(T)}};Aa.set(T,A),os(A,i)};if(e==null){const T=t.el=v(""),A=t.anchor=v("");if(h(T,n,o),h(A,n,o),hO(t.props)||i&&i.pendingBranch){S(t);return}b&&(g(t,n,A),pf(t,!0)),x()}else{t.el=e.el;const T=t.anchor=e.anchor,A=Aa.get(e);if(A){A.flags|=8,Aa.delete(e),S(t);return}t.targetStart=e.targetStart;const E=t.target=e.target,P=t.targetAnchor=e.targetAnchor,D=Vu(e.props),I=D?n:E,$=D?T:P;if(r==="svg"||x7(E)?r="svg":(r==="mathml"||S7(E))&&(r="mathml"),_?(f(e.dynamicChildren,_,I,s,i,r,l),V8(e,t,!0)):a||d(e,t,I,$,s,i,r,l,!1),b)D?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):z0(t,n,T,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const B=L4(t.props,m);B&&(t.target=B,z0(t,B,null,u,0))}else D&&z0(t,E,P,u,1);pf(t,b)}},remove(e,t,n,{um:o,o:{remove:s}},i){const{shapeFlag:r,children:l,anchor:a,targetStart:u,targetAnchor:c,target:d,props:f}=e,h=Vu(f),m=i||!h,v=Aa.get(e);if(v&&(v.flags|=8,Aa.delete(e)),d&&(s(u),s(c)),i&&s(a),!v&&(h||d)&&r&16)for(let k=0;k<l.length;k++){const w=l[k];o(w,t,n,m,!!w.dynamicChildren)}},move:z0,hydrate:gO};function z0(e,t,n,{o:{insert:o},m:s},i=2){i===0&&o(e.targetAnchor,t,n);const{el:r,anchor:l,shapeFlag:a,children:u,props:c}=e,d=i===2;if(d&&o(r,t,n),!Aa.has(e)&&(!d||Vu(c))&&a&16)for(let f=0;f<u.length;f++)s(u[f],t,n,2);d&&o(l,t,n)}function gO(e,t,n,o,s,i,{o:{nextSibling:r,parentNode:l,querySelector:a,insert:u,createText:c}},d){function f(k,w){let b=w;for(;b;){if(b&&b.nodeType===8){if(b.data==="teleport start anchor")t.targetStart=b;else if(b.data==="teleport anchor"){t.targetAnchor=b,k._lpa=t.targetAnchor&&r(t.targetAnchor);break}}b=r(b)}}function h(k,w){w.anchor=d(r(k),w,l(k),n,o,s,i)}const m=t.target=L4(t.props,a),v=Vu(t.props);if(m){const k=m._lpa||m.firstChild;t.shapeFlag&16&&(v?(h(e,t),f(m,k),t.targetAnchor||$4(m,t,c,u,l(e)===m?e:null)):(t.anchor=r(e),f(m,k),t.targetAnchor||$4(m,t,c,u),d(k&&r(k),t,m,n,o,s,i))),pf(t,v)}else v&&t.shapeFlag&16&&(h(e,t),t.targetStart=e,t.targetAnchor=r(e));return t.anchor&&r(t.anchor)}const Zr=mO;function pf(e,t){const n=e.ctx;if(n&&n.ut){let o,s;for(t?(o=e.el,s=e.anchor):(o=e.targetStart,s=e.targetAnchor);o&&o!==s;)o.nodeType===1&&o.setAttribute("data-v-owner",n.uid),o=o.nextSibling;n.ut()}}function $4(e,t,n,o,s=null){const i=t.targetStart=n(""),r=t.targetAnchor=n("");return i[nA]=r,e&&(o(i,e,s),o(r,e,s)),r}const yr=Symbol("_leaveCb"),Y1=Symbol("_enterCb");function sA(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return dn(()=>{e.isMounted=!0}),Vn(()=>{e.isUnmounting=!0}),e}const fr=[Function,Array],iA={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:fr,onEnter:fr,onAfterEnter:fr,onEnterCancelled:fr,onBeforeLeave:fr,onLeave:fr,onAfterLeave:fr,onLeaveCancelled:fr,onBeforeAppear:fr,onAppear:fr,onAfterAppear:fr,onAppearCancelled:fr},rA=e=>{const t=e.subTree;return t.component?rA(t.component):t},vO={name:"BaseTransition",props:iA,setup(e,{slots:t}){const n=ds(),o=sA();return()=>{const s=t.default&&O8(t.default(),!0),i=s&&s.length?lA(s):n.subTree?ee():void 0;if(!i)return;const r=Pn(e),{mode:l}=r;if(o.isLeaving)return Wv(i);const a=A7(i);if(!a)return Wv(i);let u=up(a,r,o,n,d=>u=d);a.type!==rs&&Za(a,u);let c=n.subTree&&A7(n.subTree);if(c&&c.type!==rs&&!Br(c,a)&&rA(n).type!==rs){let d=up(c,r,o,n);if(Za(c,d),l==="out-in"&&a.type!==rs)return o.isLeaving=!0,d.afterLeave=()=>{o.isLeaving=!1,n.job.flags&8||n.update(),delete d.afterLeave,c=void 0},Wv(i);l==="in-out"&&a.type!==rs?d.delayLeave=(f,h,m)=>{const v=aA(o,c);v[String(c.key)]=c,f[yr]=()=>{h(),f[yr]=void 0,delete u.delayedLeave,c=void 0},u.delayedLeave=()=>{m(),delete u.delayedLeave,c=void 0}}:c=void 0}else c&&(c=void 0);return i}}};function lA(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==rs){t=n;break}}return t}const yO=vO;function aA(e,t){const{leavingVNodes:n}=e;let o=n.get(t.type);return o||(o=Object.create(null),n.set(t.type,o)),o}function up(e,t,n,o,s){const{appear:i,mode:r,persisted:l=!1,onBeforeEnter:a,onEnter:u,onAfterEnter:c,onEnterCancelled:d,onBeforeLeave:f,onLeave:h,onAfterLeave:m,onLeaveCancelled:v,onBeforeAppear:k,onAppear:w,onAfterAppear:b,onAppearCancelled:_}=t,g=String(e.key),x=aA(n,e),S=(E,P)=>{E&&xr(E,o,9,P)},T=(E,P)=>{const D=P[1];S(E,P),jt(E)?E.every(I=>I.length<=1)&&D():E.length<=1&&D()},A={mode:r,persisted:l,beforeEnter(E){let P=a;if(!n.isMounted)if(i)P=k||a;else return;E[yr]&&E[yr](!0);const D=x[g];D&&Br(e,D)&&D.el[yr]&&D.el[yr](),S(P,[E])},enter(E){if(x[g]===e)return;let P=u,D=c,I=d;if(!n.isMounted)if(i)P=w||u,D=b||c,I=_||d;else return;let $=!1;E[Y1]=H=>{$||($=!0,H?S(I,[E]):S(D,[E]),A.delayedLeave&&A.delayedLeave(),E[Y1]=void 0)};const B=E[Y1].bind(null,!1);P?T(P,[E,B]):B()},leave(E,P){const D=String(e.key);if(E[Y1]&&E[Y1](!0),n.isUnmounting)return P();S(f,[E]);let I=!1;E[yr]=B=>{I||(I=!0,P(),B?S(v,[E]):S(m,[E]),E[yr]=void 0,x[D]===e&&delete x[D])};const $=E[yr].bind(null,!1);x[D]=e,h?T(h,[E,$]):$()},clone(E){const P=up(E,t,n,o,s);return s&&s(P),P}};return A}function Wv(e){if(Pp(e))return e=ra(e),e.children=null,e}function A7(e){if(!Pp(e))return oA(e.type)&&e.children?lA(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&un(n.default))return n.default()}}function Za(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Za(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function O8(e,t=!1,n){let o=[],s=0;for(let i=0;i<e.length;i++){let r=e[i];const l=n==null?r.key:String(n)+String(r.key!=null?r.key:i);r.type===Pe?(r.patchFlag&128&&s++,o=o.concat(O8(r.children,t,l))):(t||r.type!==rs)&&o.push(l!=null?ra(r,{key:l}):r)}if(s>1)for(let i=0;i<o.length;i++)o[i].patchFlag=-2;return o}function et(e,t){return un(e)?to({name:e.name},t,{setup:e}):e}function kO(){const e=ds();return e?(e.appContext.config.idPrefix||"v")+"-"+e.ids[0]+e.ids[1]++:""}function P8(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Fje(e){const t=ds(),n=Xr(null);if(t){const s=t.refs===An?t.refs={}:t.refs;Object.defineProperty(s,e,{enumerable:!0,get:()=>n.value,set:i=>n.value=i})}return n}function M7(e,t){let n;return!!((n=Object.getOwnPropertyDescriptor(e,t))&&!n.configurable)}const vm=new WeakMap;function Fd(e,t,n,o,s=!1){if(jt(e)){e.forEach((v,k)=>Fd(v,t&&(jt(t)?t[k]:t),n,o,s));return}if(na(o)&&!s){o.shapeFlag&512&&o.type.__asyncResolved&&o.component.subTree.component&&Fd(e,t,n,o.component.subTree);return}const i=o.shapeFlag&4?Bp(o.component):o.el,r=s?null:i,{i:l,r:a}=e,u=t&&t.r,c=l.refs===An?l.refs={}:l.refs,d=l.setupState,f=Pn(d),h=d===An?xS:v=>M7(c,v)?!1:Kn(f,v),m=(v,k)=>!(k&&M7(c,k));if(u!=null&&u!==a){if(T7(t),ro(u))c[u]=null,h(u)&&(d[u]=null);else if(Xo(u)){const v=t;m(u,v.k)&&(u.value=null),v.k&&(c[v.k]=null)}}if(un(a)){wl();try{Rp(a,l,12,[r,c])}finally{_l()}}else{const v=ro(a),k=Xo(a);if(v||k){const w=()=>{if(e.f){const b=v?h(a)?d[a]:c[a]:m()||!e.k?a.value:c[e.k];if(s)jt(b)&&I8(b,i);else if(jt(b))b.includes(i)||b.push(i);else if(v)c[a]=[i],h(a)&&(d[a]=c[a]);else{const _=[i];m(a,e.k)&&(a.value=_),e.k&&(c[e.k]=_)}}else v?(c[a]=r,h(a)&&(d[a]=r)):k&&(m(a,e.k)&&(a.value=r),e.k&&(c[e.k]=r))};if(r){const b=()=>{w(),vm.delete(e)};b.id=-1,vm.set(e,b),os(b,n)}else T7(e),w()}}}function T7(e){const t=vm.get(e);t&&(t.flags|=8,vm.delete(e))}let E7=!1;const Qc=()=>{E7||(console.error("Hydration completed but contains mismatches."),E7=!0)},bO=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",CO=e=>e.namespaceURI.includes("MathML"),W0=e=>{if(e.nodeType===1){if(bO(e))return"svg";if(CO(e))return"mathml"}},kd=e=>e.nodeType===8;function wO(e){const{mt:t,p:n,o:{patchProp:o,createText:s,nextSibling:i,parentNode:r,remove:l,insert:a,createComment:u}}=e,c=(_,g)=>{if(!g.hasChildNodes()){n(null,_,g),gm(),g._vnode=_;return}d(g.firstChild,_,null,null,null),gm(),g._vnode=_},d=(_,g,x,S,T,A=!1)=>{A=A||!!g.dynamicChildren;const E=kd(_)&&_.data==="[",P=()=>v(_,g,x,S,T,E),{type:D,ref:I,shapeFlag:$,patchFlag:B}=g;let H=_.nodeType;g.el=_,B===-2&&(A=!1,g.dynamicChildren=null);let O=null;switch(D){case Ua:H!==3?g.children===""?(a(g.el=s(""),r(_),_),O=_):O=P():(_.data!==g.children&&(Qc(),_.data=g.children),O=i(_));break;case rs:b(_)?(O=i(_),w(g.el=_.content.firstChild,_,x)):H!==8||E?O=P():O=i(_);break;case Od:if(E&&(_=i(_),H=_.nodeType),H===1||H===3){O=_;const F=!g.children.length;for(let U=0;U<g.staticCount;U++)F&&(g.children+=O.nodeType===1?O.outerHTML:O.data),U===g.staticCount-1&&(g.anchor=O),O=i(O);return E?i(O):O}else P();break;case Pe:E?O=m(_,g,x,S,T,A):O=P();break;default:if($&1)(H!==1||g.type.toLowerCase()!==_.tagName.toLowerCase())&&!b(_)?O=P():O=f(_,g,x,S,T,A);else if($&6){g.slotScopeIds=T;const F=r(_);if(E?O=k(_):kd(_)&&_.data==="teleport start"?O=k(_,_.data,"teleport end"):O=i(_),t(g,F,null,x,S,W0(F),A),na(g)&&!g.type.__asyncResolved){let U;E?(U=j(Pe),U.anchor=O?O.previousSibling:F.lastChild):U=_.nodeType===3?qe(""):j("div"),U.el=_,g.component.subTree=U}}else $&64?H!==8?O=P():O=g.type.hydrate(_,g,x,S,T,A,e,h):$&128&&(O=g.type.hydrate(_,g,x,S,W0(r(_)),T,A,e,d))}return I!=null&&Fd(I,null,S,g),O},f=(_,g,x,S,T,A)=>{A=A||!!g.dynamicChildren;const{type:E,dynamicProps:P,props:D,patchFlag:I,shapeFlag:$,dirs:B,transition:H}=g,O=E==="input"||E==="option",F=!!P;if(O||F||I!==-1){B&&hl(g,null,x,"created");let U=!1;if(b(_)){U=TA(null,H)&&x&&x.vnode.props&&x.vnode.props.appear;const W=_.content.firstChild;if(U){const K=W.getAttribute("class");K&&(W.$cls=K),H.beforeEnter(W)}w(W,_,x),g.el=_=W}if($&16&&!(D&&(D.innerHTML||D.textContent))){let W=h(_.firstChild,g,_,x,S,T,A);for(W&&!Oh(_,1)&&Qc();W;){const K=W;W=W.nextSibling,l(K)}}else if($&8){let W=g.children;W[0]===` +`&&(_.tagName==="PRE"||_.tagName==="TEXTAREA")&&(W=W.slice(1));const{textContent:K}=_;K!==W&&K!==W.replace(/\r\n|\r/g,` +`)&&(Oh(_,0)||Qc(),_.textContent=g.children)}if(D){if(O||F||!A||I&48){const W=_.tagName.includes("-");for(const K in D)(O&&(K.endsWith("value")||K==="indeterminate")||Fp(K)&&!oc(K)||K[0]==="."||W&&!oc(K)||P&&P.includes(K))&&o(_,K,null,D[K],void 0,x)}else if(D.onClick)o(_,"onClick",null,D.onClick,void 0,x);else if(I&4&&Wa(D.style))for(const W in D.style)D.style[W]}let z;(z=D&&D.onVnodeBeforeMount)&&Fi(z,x,g),B&&hl(g,null,x,"beforeMount"),((z=D&&D.onVnodeMounted)||B||U)&&$A(()=>{z&&Fi(z,x,g),U&&H.enter(_),B&&hl(g,null,x,"mounted")},S)}return _.nextSibling},h=(_,g,x,S,T,A,E)=>{E=E||!!g.dynamicChildren;const P=g.children,D=P.length;let I=!1;for(let $=0;$<D;$++){const B=E?P[$]:P[$]=Di(P[$]),H=B.type===Ua;_?(H&&!E&&$+1<D&&Di(P[$+1]).type===Ua&&(a(s(_.data.slice(B.children.length)),x,i(_)),_.data=B.children),_=d(_,B,S,T,A,E)):H&&!B.children?a(B.el=s(""),x):(I||(I=!0,Oh(x,1)||Qc()),n(null,B,x,null,S,T,W0(x),A))}return _},m=(_,g,x,S,T,A)=>{const{slotScopeIds:E}=g;E&&(T=T?T.concat(E):E);const P=r(_),D=h(i(_),g,P,x,S,T,A);return D&&kd(D)&&D.data==="]"?i(g.anchor=D):(Qc(),a(g.anchor=u("]"),P,D),D)},v=(_,g,x,S,T,A)=>{if(xO(_,g)||Qc(),g.el=null,A){const D=k(_);for(;;){const I=i(_);if(I&&I!==D)l(I);else break}}const E=i(_),P=r(_);return l(_),n(null,g,P,E,x,S,W0(P),T),x&&(x.vnode.el=g.el,n2(x,g.el)),E},k=(_,g="[",x="]")=>{let S=0;for(;_;)if(_=i(_),_&&kd(_)&&(_.data===g&&S++,_.data===x)){if(S===0)return i(_);S--}return _},w=(_,g,x)=>{const S=g.parentNode;S&&S.replaceChild(_,g);let T=x;for(;T;)T.vnode.el===g&&(T.vnode.el=T.subTree.el=_),T=T.parent},b=_=>_.nodeType===1&&_.tagName==="TEMPLATE";return[c,d]}const ym="data-allow-mismatch",_O={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function Oh(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(ym);)e=e.parentElement;return D8(e&&e.getAttribute(ym),t)}function D8(e,t){if(e==null)return!1;if(e==="")return!0;{const n=e.split(",");return t===0&&n.includes("children")?!0:n.includes(_O[t])}}function xO(e,t){return Oh(e.parentElement,1)||SO(e)||AO(t)}function SO(e){return e.nodeType===1&&D8(e.getAttribute(ym),1)}function AO({props:e}){const t=e&&e[ym];return typeof t=="string"&&D8(t,1)}const MO=Vg().requestIdleCallback||(e=>setTimeout(e,1)),TO=Vg().cancelIdleCallback||(e=>clearTimeout(e)),Rje=(e=1e4)=>t=>{const n=MO(t,{timeout:e});return()=>TO(n)};function EO(e){const{top:t,left:n,bottom:o,right:s}=e.getBoundingClientRect(),{innerHeight:i,innerWidth:r}=window;return(t>0&&t<i||o>0&&o<i)&&(n>0&&n<r||s>0&&s<r)}const Oje=e=>(t,n)=>{const o=new IntersectionObserver(s=>{for(const i of s)if(i.isIntersecting){o.disconnect(),t();break}},e);return n(s=>{if(s instanceof Element){if(EO(s))return t(),o.disconnect(),!1;o.observe(s)}}),()=>o.disconnect()},Pje=e=>t=>{if(e){const n=matchMedia(e);if(n.matches)t();else return n.addEventListener("change",t,{once:!0}),()=>n.removeEventListener("change",t)}},Dje=(e=[])=>(t,n)=>{ro(e)&&(e=[e]);let o=!1;const s=r=>{o||(o=!0,i(),t(),r.target.dispatchEvent(new r.constructor(r.type,r)))},i=()=>{n(r=>{for(const l of e)r.removeEventListener(l,s)})};return n(r=>{for(const l of e)r.addEventListener(l,s,{once:!0})}),i};function IO(e,t){if(kd(e)&&e.data==="["){let n=1,o=e.nextSibling;for(;o;){if(o.nodeType===1){if(t(o)===!1)break}else if(kd(o))if(o.data==="]"){if(--n===0)break}else o.data==="["&&n++;o=o.nextSibling}}else t(e)}const na=e=>!!e.type.__asyncLoader;function zr(e){un(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:o,delay:s=200,hydrate:i,timeout:r,suspensible:l=!0,onError:a}=e;let u=null,c,d=0;const f=()=>(d++,u=null,h()),h=()=>{let m;return u||(m=u=t().catch(v=>{if(v=v instanceof Error?v:new Error(String(v)),a)return new Promise((k,w)=>{a(v,()=>k(f()),()=>w(v),d+1)});throw v}).then(v=>m!==u&&u?u:(v&&(v.__esModule||v[Symbol.toStringTag]==="Module")&&(v=v.default),c=v,v)))};return et({name:"AsyncComponentWrapper",__asyncLoader:h,__asyncHydrate(m,v,k){let w=!1;(v.bu||(v.bu=[])).push(()=>w=!0);const b=()=>{w||k()},_=i?()=>{const g=i(b,x=>IO(m,x));g&&(v.bum||(v.bum=[])).push(g)}:b;c?_():h().then(()=>!v.isUnmounted&&_())},get __asyncResolved(){return c},setup(){const m=Vs;if(P8(m),c)return()=>U0(c,m);const v=x=>{u=null,f1(x,m,13,!o)};if(l&&m.suspense||fc)return h().then(x=>()=>U0(x,m)).catch(x=>(v(x),()=>o?j(o,{error:x}):null));const k=Z(!1),w=Z(),b=Z(!!s);let _,g;return bn(()=>{_!=null&&clearTimeout(_),g!=null&&clearTimeout(g)}),s&&(g=setTimeout(()=>{m.isUnmounted||(b.value=!1)},s)),r!=null&&(_=setTimeout(()=>{if(!m.isUnmounted&&!k.value&&!w.value){const x=new Error(`Async component timed out after ${r}ms.`);v(x),w.value=x}},r)),h().then(()=>{m.isUnmounted||(k.value=!0,m.parent&&Pp(m.parent.vnode)&&m.parent.update())}).catch(x=>{if(m.isUnmounted){u=null;return}v(x),w.value=x}),()=>{if(k.value&&c)return U0(c,m);if(w.value&&o)return j(o,{error:w.value});if(n&&!b.value)return U0(n,m)}}})}function U0(e,t){const{ref:n,props:o,children:s,ce:i}=t.vnode,r=j(e,o,s);return r.ref=n,r.ce=i,delete t.vnode.ce,r}const Pp=e=>e.type.__isKeepAlive,LO={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=ds(),o=n.ctx;if(!o.renderer)return()=>{const b=t.default&&t.default();return b&&b.length===1?b[0]:b};const s=new Map,i=new Set;let r=null;const l=n.suspense,{renderer:{p:a,m:u,um:c,o:{createElement:d}}}=o,f=d("div");o.activate=(b,_,g,x,S)=>{const T=b.component;u(b,_,g,0,l),a(T.vnode,b,_,g,T,l,x,b.slotScopeIds,S),os(()=>{T.isDeactivated=!1,T.a&&$d(T.a);const A=b.props&&b.props.onVnodeMounted;A&&Fi(A,T.parent,b)},l)},o.deactivate=b=>{const _=b.component;bm(_.m),bm(_.a),u(b,f,null,1,l),os(()=>{_.da&&$d(_.da);const g=b.props&&b.props.onVnodeUnmounted;g&&Fi(g,_.parent,b),_.isDeactivated=!0},l)};function h(b){Uv(b),c(b,n,l,!0)}function m(b){s.forEach((_,g)=>{const x=z4(na(_)?_.type.__asyncResolved||{}:_.type);x&&!b(x)&&v(g)})}function v(b){const _=s.get(b);_&&(!r||!Br(_,r))?h(_):r&&Uv(r),s.delete(b),i.delete(b)}Je(()=>[e.include,e.exclude],([b,_])=>{b&&m(g=>hf(b,g)),_&&m(g=>!hf(_,g))},{flush:"post",deep:!0});let k=null;const w=()=>{k!=null&&(Cm(n.subTree.type)?os(()=>{s.set(k,j0(n.subTree))},n.subTree.suspense):s.set(k,j0(n.subTree)))};return dn(w),Dp(w),Vn(()=>{s.forEach(b=>{const{subTree:_,suspense:g}=n,x=j0(_);if(b.type===x.type&&b.key===x.key){Uv(x);const S=x.component.da;S&&os(S,g);return}h(b)})}),()=>{if(k=null,!t.default)return r=null;const b=t.default(),_=b[0];if(b.length>1)return r=null,b;if(!Ga(_)||!(_.shapeFlag&4)&&!(_.shapeFlag&128))return r=null,_;let g=j0(_);if(g.type===rs)return r=null,g;const x=g.type,S=z4(na(g)?g.type.__asyncResolved||{}:x),{include:T,exclude:A,max:E}=e;if(T&&(!S||!hf(T,S))||A&&S&&hf(A,S))return g.shapeFlag&=-257,r=g,_;const P=g.key==null?x:g.key,D=s.get(P);return g.el&&(g=ra(g),_.shapeFlag&128&&(_.ssContent=g)),k=P,D?(g.el=D.el,g.component=D.component,g.transition&&Za(g,g.transition),g.shapeFlag|=512,i.delete(P),i.add(P)):(i.add(P),E&&i.size>parseInt(E,10)&&v(i.values().next().value)),g.shapeFlag|=256,r=g,Cm(_.type)?_:g}}},Bje=LO;function hf(e,t){return jt(e)?e.some(n=>hf(n,t)):ro(e)?e.split(",").includes(t):hR(e)?(e.lastIndex=0,e.test(t)):!1}function $O(e,t){uA(e,"a",t)}function NO(e,t){uA(e,"da",t)}function uA(e,t,n=Vs){const o=e.__wdc||(e.__wdc=()=>{let s=n;for(;s;){if(s.isDeactivated)return;s=s.parent}return e()});if(e2(t,o,n),n){let s=n.parent;for(;s&&s.parent;)Pp(s.parent.vnode)&&FO(o,t,n,s),s=s.parent}}function FO(e,t,n,o){const s=e2(t,e,o,!0);bn(()=>{I8(o[t],s)},n)}function Uv(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function j0(e){return e.shapeFlag&128?e.ssContent:e}function e2(e,t,n=Vs,o=!1){if(n){const s=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...r)=>{wl();const l=h1(n),a=xr(t,n,e,r);return l(),_l(),a});return o?s.unshift(i):s.push(i),i}}const aa=e=>(t,n=Vs)=>{(!fc||e==="sp")&&e2(e,(...o)=>t(...o),n)},RO=aa("bm"),dn=aa("m"),cA=aa("bu"),Dp=aa("u"),Vn=aa("bum"),bn=aa("um"),OO=aa("sp"),PO=aa("rtg"),DO=aa("rtc");function BO(e,t=Vs){e2("ec",e,t)}const B8="components",HO="directives";function zO(e,t){return H8(B8,e,!0,t)||e}const dA=Symbol.for("v-ndc");function bs(e){return ro(e)?H8(B8,e,!1)||e:e||dA}function Hje(e){return H8(HO,e)}function H8(e,t,n=!0,o=!1){const s=Ks||Vs;if(s){const i=s.type;if(e===B8){const l=z4(i,!1);if(l&&(l===t||l===_s(t)||l===Ug(_s(t))))return i}const r=I7(s[e]||i[e],t)||I7(s.appContext[e],t);return!r&&o?i:r}}function I7(e,t){return e&&(e[t]||e[_s(t)]||e[Ug(_s(t))])}function pt(e,t,n,o){let s;const i=n&&n[o],r=jt(e);if(r||ro(e)){const l=r&&Wa(e);let a=!1,u=!1;l&&(a=!tr(e),u=ia(e),e=Gg(e)),s=new Array(e.length);for(let c=0,d=e.length;c<d;c++)s[c]=t(a?u?Xd(Kr(e[c])):Kr(e[c]):e[c],c,void 0,i&&i[c])}else if(typeof e=="number"){s=new Array(e);for(let l=0;l<e;l++)s[l]=t(l+1,l,void 0,i&&i[l])}else if(Zn(e))if(e[Symbol.iterator])s=Array.from(e,(l,a)=>t(l,a,void 0,i&&i[a]));else{const l=Object.keys(e);s=new Array(l.length);for(let a=0,u=l.length;a<u;a++){const c=l[a];s[a]=t(e[c],c,a,i&&i[a])}}else s=[];return n&&(n[o]=s),s}function fA(e,t){for(let n=0;n<t.length;n++){const o=t[n];if(jt(o))for(let s=0;s<o.length;s++)e[o[s].name]=o[s].fn;else o&&(e[o.name]=o.key?(...s)=>{const i=o.fn(...s);return i&&(i.key=o.key),i}:o.fn)}return e}function xn(e,t,n={},o,s){if(Ks.ce||Ks.parent&&na(Ks.parent)&&Ks.parent.ce){const u=Object.keys(n).length>0;return t!=="default"&&(n.name=t),y(),he(Pe,null,[j("slot",n,o&&o())],u?-2:64)}let i=e[t];i&&i._c&&(i._d=!1),y();const r=i&&z8(i(n)),l=n.key||r&&r.key,a=he(Pe,{key:(l&&!lr(l)?l:`_${t}`)+(!r&&o?"_fb":"")},r||(o?o():[]),r&&e._===1?64:-2);return!s&&a.scopeId&&(a.slotScopeIds=[a.scopeId+"-s"]),i&&i._c&&(i._d=!0),a}function z8(e){return e.some(t=>Ga(t)?!(t.type===rs||t.type===Pe&&!z8(t.children)):!0)?e:null}function zje(e,t){const n={};for(const o in e)n[t&&/[A-Z]/.test(o)?`on:${o}`:Fh(o)]=e[o];return n}const N4=e=>e?DA(e)?Bp(e):N4(e.parent):null,Ff=to(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>N4(e.parent),$root:e=>N4(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>W8(e),$forceUpdate:e=>e.f||(e.f=()=>{R8(e.update)}),$nextTick:e=>e.n||(e.n=yt.bind(e.proxy)),$watch:e=>pO.bind(e)}),jv=(e,t)=>e!==An&&!e.__isScriptSetup&&Kn(e,t),F4={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:o,data:s,props:i,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const f=r[t];if(f!==void 0)switch(f){case 1:return o[t];case 2:return s[t];case 4:return n[t];case 3:return i[t]}else{if(jv(o,t))return r[t]=1,o[t];if(s!==An&&Kn(s,t))return r[t]=2,s[t];if(Kn(i,t))return r[t]=3,i[t];if(n!==An&&Kn(n,t))return r[t]=4,n[t];R4&&(r[t]=0)}}const u=Ff[t];let c,d;if(u)return t==="$attrs"&&ii(e.attrs,"get",""),u(e);if((c=l.__cssModules)&&(c=c[t]))return c;if(n!==An&&Kn(n,t))return r[t]=4,n[t];if(d=a.config.globalProperties,Kn(d,t))return d[t]},set({_:e},t,n){const{data:o,setupState:s,ctx:i}=e;return jv(s,t)?(s[t]=n,!0):o!==An&&Kn(o,t)?(o[t]=n,!0):Kn(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:o,appContext:s,props:i,type:r}},l){let a;return!!(n[l]||e!==An&&l[0]!=="$"&&Kn(e,l)||jv(t,l)||Kn(i,l)||Kn(o,l)||Kn(Ff,l)||Kn(s.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:Kn(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}},WO=to({},F4,{get(e,t){if(t!==Symbol.unscopables)return F4.get(e,t,e)},has(e,t){return t[0]!=="_"&&!kR(t)}});function Wje(){return null}function Uje(){return null}function jje(e){}function Vje(e){}function qje(){return null}function Kje(){}function Zje(e,t){return null}function Gje(){return pA().slots}function p1(){return pA().attrs}function pA(e){const t=ds();return t.setupContext||(t.setupContext=zA(t))}function cp(e){return jt(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}function Yje(e,t){const n=cp(e);for(const o in t){if(o.startsWith("__skip"))continue;let s=n[o];s?jt(s)||un(s)?s=n[o]={type:s,default:t[o]}:s.default=t[o]:s===null&&(s=n[o]={default:t[o]}),s&&t[`__skip_${o}`]&&(s.skipFactory=!0)}return n}function Xje(e,t){return!e||!t?e||t:jt(e)&&jt(t)?e.concat(t):to({},cp(e),cp(t))}function Jje(e,t){const n={};for(const o in e)t.includes(o)||Object.defineProperty(n,o,{enumerable:!0,get:()=>e[o]});return n}function Qje(e){const t=ds(),n=fc;let o=e();fp(),n&&Pd(!1);const s=()=>{h1(t),n&&Pd(!0)},i=()=>{ds()!==t&&t.scope.off(),fp(),n&&Pd(!1)};return L8(o)&&(o=o.catch(r=>{throw s(),Promise.resolve().then(()=>Promise.resolve().then(i)),r})),[o,()=>{s(),Promise.resolve().then(i)}]}let R4=!0;function UO(e){const t=W8(e),n=e.proxy,o=e.ctx;R4=!1,t.beforeCreate&&L7(t.beforeCreate,e,"bc");const{data:s,computed:i,methods:r,watch:l,provide:a,inject:u,created:c,beforeMount:d,mounted:f,beforeUpdate:h,updated:m,activated:v,deactivated:k,beforeDestroy:w,beforeUnmount:b,destroyed:_,unmounted:g,render:x,renderTracked:S,renderTriggered:T,errorCaptured:A,serverPrefetch:E,expose:P,inheritAttrs:D,components:I,directives:$,filters:B}=t;if(u&&jO(u,o,null),r)for(const F in r){const U=r[F];un(U)&&(o[F]=U.bind(n))}if(s){const F=s.call(n,n);Zn(F)&&(e.data=Go(F))}if(R4=!0,i)for(const F in i){const U=i[F],z=un(U)?U.bind(n,n):un(U.get)?U.get.bind(n,n):wr,W=!un(U)&&un(U.set)?U.set.bind(n):wr,K=R({get:z,set:W});Object.defineProperty(o,F,{enumerable:!0,configurable:!0,get:()=>K.value,set:V=>K.value=V})}if(l)for(const F in l)hA(l[F],o,n,F);if(a){const F=un(a)?a.call(n):a;Reflect.ownKeys(F).forEach(U=>{Ln(U,F[U])})}c&&L7(c,e,"c");function O(F,U){jt(U)?U.forEach(z=>F(z.bind(n))):U&&F(U.bind(n))}if(O(RO,d),O(dn,f),O(cA,h),O(Dp,m),O($O,v),O(NO,k),O(BO,A),O(DO,S),O(PO,T),O(Vn,b),O(bn,g),O(OO,E),jt(P))if(P.length){const F=e.exposed||(e.exposed={});P.forEach(U=>{Object.defineProperty(F,U,{get:()=>n[U],set:z=>n[U]=z,enumerable:!0})})}else e.exposed||(e.exposed={});x&&e.render===wr&&(e.render=x),D!=null&&(e.inheritAttrs=D),I&&(e.components=I),$&&(e.directives=$),E&&P8(e)}function jO(e,t,n=wr){jt(e)&&(e=O4(e));for(const o in e){const s=e[o];let i;Zn(s)?"default"in s?i=nn(s.from||o,s.default,!0):i=nn(s.from||o):i=nn(s),Xo(i)?Object.defineProperty(t,o,{enumerable:!0,configurable:!0,get:()=>i.value,set:r=>i.value=r}):t[o]=i}}function L7(e,t,n){xr(jt(e)?e.map(o=>o.bind(t.proxy)):e.bind(t.proxy),t,n)}function hA(e,t,n,o){let s=o.includes(".")?tA(n,o):()=>n[o];if(ro(e)){const i=t[e];un(i)&&Je(s,i)}else if(un(e))Je(s,e.bind(n));else if(Zn(e))if(jt(e))e.forEach(i=>hA(i,t,n,o));else{const i=un(e.handler)?e.handler.bind(n):t[e.handler];un(i)&&Je(s,i,e)}}function W8(e){const t=e.type,{mixins:n,extends:o}=t,{mixins:s,optionsCache:i,config:{optionMergeStrategies:r}}=e.appContext,l=i.get(t);let a;return l?a=l:!s.length&&!n&&!o?a=t:(a={},s.length&&s.forEach(u=>km(a,u,r,!0)),km(a,t,r)),Zn(t)&&i.set(t,a),a}function km(e,t,n,o=!1){const{mixins:s,extends:i}=t;i&&km(e,i,n,!0),s&&s.forEach(r=>km(e,r,n,!0));for(const r in t)if(!(o&&r==="expose")){const l=VO[r]||n&&n[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const VO={data:$7,props:N7,emits:N7,methods:mf,computed:mf,beforeCreate:mi,created:mi,beforeMount:mi,mounted:mi,beforeUpdate:mi,updated:mi,beforeDestroy:mi,beforeUnmount:mi,destroyed:mi,unmounted:mi,activated:mi,deactivated:mi,errorCaptured:mi,serverPrefetch:mi,components:mf,directives:mf,watch:KO,provide:$7,inject:qO};function $7(e,t){return t?e?function(){return to(un(e)?e.call(this,this):e,un(t)?t.call(this,this):t)}:t:e}function qO(e,t){return mf(O4(e),O4(t))}function O4(e){if(jt(e)){const t={};for(let n=0;n<e.length;n++)t[e[n]]=e[n];return t}return e}function mi(e,t){return e?[...new Set([].concat(e,t))]:t}function mf(e,t){return e?to(Object.create(null),e,t):t}function N7(e,t){return e?jt(e)&&jt(t)?[...new Set([...e,...t])]:to(Object.create(null),cp(e),cp(t??{})):t}function KO(e,t){if(!e)return t;if(!t)return e;const n=to(Object.create(null),e);for(const o in t)n[o]=mi(e[o],t[o]);return n}function mA(){return{app:null,config:{isNativeTag:xS,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let ZO=0;function GO(e,t){return function(o,s=null){un(o)||(o=to({},o)),s!=null&&!Zn(s)&&(s=null);const i=mA(),r=new WeakSet,l=[];let a=!1;const u=i.app={_uid:ZO++,_component:o,_props:s,_container:null,_context:i,_instance:null,version:xP,get config(){return i.config},set config(c){},use(c,...d){return r.has(c)||(c&&un(c.install)?(r.add(c),c.install(u,...d)):un(c)&&(r.add(c),c(u,...d))),u},mixin(c){return i.mixins.includes(c)||i.mixins.push(c),u},component(c,d){return d?(i.components[c]=d,u):i.components[c]},directive(c,d){return d?(i.directives[c]=d,u):i.directives[c]},mount(c,d,f){if(!a){const h=u._ceVNode||j(o,s);return h.appContext=i,f===!0?f="svg":f===!1&&(f=void 0),d&&t?t(h,c):e(h,c,f),a=!0,u._container=c,c.__vue_app__=u,Bp(h.component)}},onUnmount(c){l.push(c)},unmount(){a&&(xr(l,u._instance,16),e(null,u._container),delete u._container.__vue_app__)},provide(c,d){return i.provides[c]=d,u},runWithContext(c){const d=ic;ic=u;try{return c()}finally{ic=d}}};return u}}let ic=null;function eVe(e,t,n=An){const o=ds(),s=_s(t),i=Bi(t),r=gA(e,s),l=JR((a,u)=>{let c,d=An,f;return fO(()=>{const h=e[s];Es(c,h)&&(c=h,u())}),{get(){return a(),n.get?n.get(c):c},set(h){const m=n.set?n.set(h):h;if(!Es(m,c)&&!(d!==An&&Es(h,d)))return;const v=o.vnode.props,k=!!(v&&(t in v||s in v||i in v)&&(`onUpdate:${t}`in v||`onUpdate:${s}`in v||`onUpdate:${i}`in v));k||(c=h,u()),o.emit(`update:${t}`,m),Es(h,d)&&(Es(h,m)&&!Es(m,f)||k&&d!==An&&!Es(m,c))&&u(),d=h,f=m}}});return l[Symbol.iterator]=()=>{let a=0;return{next(){return a<2?{value:a++?r||An:l,done:!1}:{done:!0}}}},l}const gA=(e,t)=>t==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${_s(t)}Modifiers`]||e[`${Bi(t)}Modifiers`];function YO(e,t,...n){if(e.isUnmounted)return;const o=e.vnode.props||An;let s=n;const i=t.startsWith("update:"),r=i&&gA(o,t.slice(7));r&&(r.trim&&(s=n.map(c=>ro(c)?c.trim():c)),r.number&&(s=n.map(jg)));let l,a=o[l=Fh(t)]||o[l=Fh(_s(t))];!a&&i&&(a=o[l=Fh(Bi(t))]),a&&xr(a,e,6,s);const u=o[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,xr(u,e,6,s)}}const XO=new WeakMap;function vA(e,t,n=!1){const o=n?XO:t.emitsCache,s=o.get(e);if(s!==void 0)return s;const i=e.emits;let r={},l=!1;if(!un(e)){const a=u=>{const c=vA(u,t,!0);c&&(l=!0,to(r,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!i&&!l?(Zn(e)&&o.set(e,null),null):(jt(i)?i.forEach(a=>r[a]=null):to(r,i),Zn(e)&&o.set(e,r),r)}function t2(e,t){return!e||!Fp(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),Kn(e,t[0].toLowerCase()+t.slice(1))||Kn(e,Bi(t))||Kn(e,t))}function Ph(e){const{type:t,vnode:n,proxy:o,withProxy:s,propsOptions:[i],slots:r,attrs:l,emit:a,render:u,renderCache:c,props:d,data:f,setupState:h,ctx:m,inheritAttrs:v}=e,k=ap(e);let w,b;try{if(n.shapeFlag&4){const g=s||o,x=g;w=Di(u.call(x,g,c,d,h,f,m)),b=l}else{const g=t;w=Di(g.length>1?g(d,{attrs:l,slots:r,emit:a}):g(d,null)),b=t.props?l:QO(l)}}catch(g){Rf.length=0,f1(g,e,1),w=j(rs)}let _=w;if(b&&v!==!1){const g=Object.keys(b),{shapeFlag:x}=_;g.length&&x&7&&(i&&g.some(Bg)&&(b=eP(b,i)),_=ra(_,b,!1,!0))}return n.dirs&&(_=ra(_,null,!1,!0),_.dirs=_.dirs?_.dirs.concat(n.dirs):n.dirs),n.transition&&Za(_,n.transition),w=_,ap(k),w}function JO(e,t=!0){let n;for(let o=0;o<e.length;o++){const s=e[o];if(Ga(s)){if(s.type!==rs||s.children==="v-if"){if(n)return;n=s}}else return}return n}const QO=e=>{let t;for(const n in e)(n==="class"||n==="style"||Fp(n))&&((t||(t={}))[n]=e[n]);return t},eP=(e,t)=>{const n={};for(const o in e)(!Bg(o)||!(o.slice(9)in t))&&(n[o]=e[o]);return n};function tP(e,t,n){const{props:o,children:s,component:i}=e,{props:r,children:l,patchFlag:a}=t,u=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return o?F7(o,r,u):!!r;if(a&8){const c=t.dynamicProps;for(let d=0;d<c.length;d++){const f=c[d];if(yA(r,o,f)&&!t2(u,f))return!0}}}else return(s||l)&&(!l||!l.$stable)?!0:o===r?!1:o?r?F7(o,r,u):!0:!!r;return!1}function F7(e,t,n){const o=Object.keys(t);if(o.length!==Object.keys(e).length)return!0;for(let s=0;s<o.length;s++){const i=o[s];if(yA(t,e,i)&&!t2(n,i))return!0}return!1}function yA(e,t,n){const o=e[n],s=t[n];return n==="style"&&Zn(o)&&Zn(s)?!sa(o,s):o!==s}function n2({vnode:e,parent:t,suspense:n},o){for(;t;){const s=t.subTree;if(s.suspense&&s.suspense.activeBranch===e&&(s.suspense.vnode.el=s.el=o,e=s),s===e)(e=t.vnode).el=o,t=t.parent;else break}n&&n.activeBranch===e&&(n.vnode.el=o)}const kA={},bA=()=>Object.create(kA),CA=e=>Object.getPrototypeOf(e)===kA;function nP(e,t,n,o=!1){const s={},i=bA();e.propsDefaults=Object.create(null),wA(e,t,s,i);for(const r in e.propsOptions[0])r in s||(s[r]=void 0);n?e.props=o?s:qS(s):e.type.props?e.props=s:e.props=i,e.attrs=i}function oP(e,t,n,o){const{props:s,attrs:i,vnode:{patchFlag:r}}=e,l=Pn(s),[a]=e.propsOptions;let u=!1;if((o||r>0)&&!(r&16)){if(r&8){const c=e.vnode.dynamicProps;for(let d=0;d<c.length;d++){let f=c[d];if(t2(e.emitsOptions,f))continue;const h=t[f];if(a)if(Kn(i,f))h!==i[f]&&(i[f]=h,u=!0);else{const m=_s(f);s[m]=P4(a,l,m,h,e,!1)}else h!==i[f]&&(i[f]=h,u=!0)}}}else{wA(e,t,s,i)&&(u=!0);let c;for(const d in l)(!t||!Kn(t,d)&&((c=Bi(d))===d||!Kn(t,c)))&&(a?n&&(n[d]!==void 0||n[c]!==void 0)&&(s[d]=P4(a,l,d,void 0,e,!0)):delete s[d]);if(i!==l)for(const d in i)(!t||!Kn(t,d))&&(delete i[d],u=!0)}u&&Zl(e.attrs,"set","")}function wA(e,t,n,o){const[s,i]=e.propsOptions;let r=!1,l;if(t)for(let a in t){if(oc(a))continue;const u=t[a];let c;s&&Kn(s,c=_s(a))?!i||!i.includes(c)?n[c]=u:(l||(l={}))[c]=u:t2(e.emitsOptions,a)||(!(a in o)||u!==o[a])&&(o[a]=u,r=!0)}if(i){const a=Pn(n),u=l||An;for(let c=0;c<i.length;c++){const d=i[c];n[d]=P4(s,a,d,u[d],e,!Kn(u,d))}}return r}function P4(e,t,n,o,s,i){const r=e[n];if(r!=null){const l=Kn(r,"default");if(l&&o===void 0){const a=r.default;if(r.type!==Function&&!r.skipFactory&&un(a)){const{propsDefaults:u}=s;if(n in u)o=u[n];else{const c=h1(s);o=u[n]=a.call(null,t),c()}}else o=a;s.ce&&s.ce._setProp(n,o)}r[0]&&(i&&!l?o=!1:r[1]&&(o===""||o===Bi(n))&&(o=!0))}return o}const sP=new WeakMap;function _A(e,t,n=!1){const o=n?sP:t.propsCache,s=o.get(e);if(s)return s;const i=e.props,r={},l=[];let a=!1;if(!un(e)){const c=d=>{a=!0;const[f,h]=_A(d,t,!0);to(r,f),h&&l.push(...h)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!i&&!a)return Zn(e)&&o.set(e,Id),Id;if(jt(i))for(let c=0;c<i.length;c++){const d=_s(i[c]);R7(d)&&(r[d]=An)}else if(i)for(const c in i){const d=_s(c);if(R7(d)){const f=i[c],h=r[d]=jt(f)||un(f)?{type:f}:to({},f),m=h.type;let v=!1,k=!0;if(jt(m))for(let w=0;w<m.length;++w){const b=m[w],_=un(b)&&b.name;if(_==="Boolean"){v=!0;break}else _==="String"&&(k=!1)}else v=un(m)&&m.name==="Boolean";h[0]=v,h[1]=k,(v||Kn(h,"default"))&&l.push(d)}}const u=[r,l];return Zn(e)&&o.set(e,u),u}function R7(e){return e[0]!=="$"&&!oc(e)}const U8=e=>e==="_"||e==="_ctx"||e==="$stable",j8=e=>jt(e)?e.map(Di):[Di(e)],iP=(e,t,n)=>{if(t._n)return t;const o=me((...s)=>j8(t(...s)),n);return o._c=!1,o},xA=(e,t,n)=>{const o=e._ctx;for(const s in e){if(U8(s))continue;const i=e[s];if(un(i))t[s]=iP(s,i,o);else if(i!=null){const r=j8(i);t[s]=()=>r}}},SA=(e,t)=>{const n=j8(t);e.slots.default=()=>n},AA=(e,t,n)=>{for(const o in t)(n||!U8(o))&&(e[o]=t[o])},rP=(e,t,n)=>{const o=e.slots=bA();if(e.vnode.shapeFlag&32){const s=t._;s?(AA(o,t,n),n&&AS(o,"_",s,!0)):xA(t,o)}else t&&SA(e,t)},lP=(e,t,n)=>{const{vnode:o,slots:s}=e;let i=!0,r=An;if(o.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:AA(s,t,n):(i=!t.$stable,xA(t,s)),r=t}else t&&(SA(e,t),r={default:1});if(i)for(const l in s)!U8(l)&&r[l]==null&&delete s[l]},os=$A;function aP(e){return MA(e)}function uP(e){return MA(e,wO)}function MA(e,t){const n=Vg();n.__VUE__=!0;const{insert:o,remove:s,patchProp:i,createElement:r,createText:l,createComment:a,setText:u,setElementText:c,parentNode:d,nextSibling:f,setScopeId:h=wr,insertStaticContent:m}=e,v=(G,Y,fe,we=null,ge=null,Q=null,te=void 0,ce=null,ue=!!Y.dynamicChildren)=>{if(G===Y)return;G&&!Br(G,Y)&&(we=Ie(G),V(G,ge,Q,!0),G=null),Y.patchFlag===-2&&(ue=!1,Y.dynamicChildren=null);const{type:Se,ref:ze,shapeFlag:_e}=Y;switch(Se){case Ua:k(G,Y,fe,we);break;case rs:w(G,Y,fe,we);break;case Od:G==null&&b(Y,fe,we,te);break;case Pe:I(G,Y,fe,we,ge,Q,te,ce,ue);break;default:_e&1?x(G,Y,fe,we,ge,Q,te,ce,ue):_e&6?$(G,Y,fe,we,ge,Q,te,ce,ue):(_e&64||_e&128)&&Se.process(G,Y,fe,we,ge,Q,te,ce,ue,ve)}ze!=null&&ge?Fd(ze,G&&G.ref,Q,Y||G,!Y):ze==null&&G&&G.ref!=null&&Fd(G.ref,null,Q,G,!0)},k=(G,Y,fe,we)=>{if(G==null)o(Y.el=l(Y.children),fe,we);else{const ge=Y.el=G.el;Y.children!==G.children&&u(ge,Y.children)}},w=(G,Y,fe,we)=>{G==null?o(Y.el=a(Y.children||""),fe,we):Y.el=G.el},b=(G,Y,fe,we)=>{[G.el,G.anchor]=m(G.children,Y,fe,we,G.el,G.anchor)},_=({el:G,anchor:Y},fe,we)=>{let ge;for(;G&&G!==Y;)ge=f(G),o(G,fe,we),G=ge;o(Y,fe,we)},g=({el:G,anchor:Y})=>{let fe;for(;G&&G!==Y;)fe=f(G),s(G),G=fe;s(Y)},x=(G,Y,fe,we,ge,Q,te,ce,ue)=>{if(Y.type==="svg"?te="svg":Y.type==="math"&&(te="mathml"),G==null)S(Y,fe,we,ge,Q,te,ce,ue);else{const Se=G.el&&G.el._isVueCE?G.el:null;try{Se&&Se._beginPatch(),E(G,Y,ge,Q,te,ce,ue)}finally{Se&&Se._endPatch()}}},S=(G,Y,fe,we,ge,Q,te,ce)=>{let ue,Se;const{props:ze,shapeFlag:_e,transition:Ee,dirs:it}=G;if(ue=G.el=r(G.type,Q,ze&&ze.is,ze),_e&8?c(ue,G.children):_e&16&&A(G.children,ue,null,we,ge,Vv(G,Q),te,ce),it&&hl(G,null,we,"created"),T(ue,G,G.scopeId,te,we),ze){for(const Oe in ze)Oe!=="value"&&!oc(Oe)&&i(ue,Oe,null,ze[Oe],Q,we);"value"in ze&&i(ue,"value",null,ze.value,Q),(Se=ze.onVnodeBeforeMount)&&Fi(Se,we,G)}it&&hl(G,null,we,"beforeMount");const Fe=TA(ge,Ee);Fe&&Ee.beforeEnter(ue),o(ue,Y,fe),((Se=ze&&ze.onVnodeMounted)||Fe||it)&&os(()=>{try{Se&&Fi(Se,we,G),Fe&&Ee.enter(ue),it&&hl(G,null,we,"mounted")}finally{}},ge)},T=(G,Y,fe,we,ge)=>{if(fe&&h(G,fe),we)for(let Q=0;Q<we.length;Q++)h(G,we[Q]);if(ge){let Q=ge.subTree;if(Y===Q||Cm(Q.type)&&(Q.ssContent===Y||Q.ssFallback===Y)){const te=ge.vnode;T(G,te,te.scopeId,te.slotScopeIds,ge.parent)}}},A=(G,Y,fe,we,ge,Q,te,ce,ue=0)=>{for(let Se=ue;Se<G.length;Se++){const ze=G[Se]=ce?Kl(G[Se]):Di(G[Se]);v(null,ze,Y,fe,we,ge,Q,te,ce)}},E=(G,Y,fe,we,ge,Q,te)=>{const ce=Y.el=G.el;let{patchFlag:ue,dynamicChildren:Se,dirs:ze}=Y;ue|=G.patchFlag&16;const _e=G.props||An,Ee=Y.props||An;let it;if(fe&&Iu(fe,!1),(it=Ee.onVnodeBeforeUpdate)&&Fi(it,fe,Y,G),ze&&hl(Y,G,fe,"beforeUpdate"),fe&&Iu(fe,!0),Se&&(!G.dynamicChildren||G.dynamicChildren.length!==Se.length)&&(ue=0,te=!1,Se=null),(_e.innerHTML&&Ee.innerHTML==null||_e.textContent&&Ee.textContent==null)&&c(ce,""),Se?P(G.dynamicChildren,Se,ce,fe,we,Vv(Y,ge),Q):te||U(G,Y,ce,null,fe,we,Vv(Y,ge),Q,!1),ue>0){if(ue&16)D(ce,_e,Ee,fe,ge);else if(ue&2&&_e.class!==Ee.class&&i(ce,"class",null,Ee.class,ge),ue&4&&i(ce,"style",_e.style,Ee.style,ge),ue&8){const Fe=Y.dynamicProps;for(let Oe=0;Oe<Fe.length;Oe++){const Ge=Fe[Oe],at=_e[Ge],Tt=Ee[Ge];(Tt!==at||Ge==="value")&&i(ce,Ge,at,Tt,ge,fe)}}ue&1&&G.children!==Y.children&&c(ce,Y.children)}else!te&&Se==null&&D(ce,_e,Ee,fe,ge);((it=Ee.onVnodeUpdated)||ze)&&os(()=>{it&&Fi(it,fe,Y,G),ze&&hl(Y,G,fe,"updated")},we)},P=(G,Y,fe,we,ge,Q,te)=>{for(let ce=0;ce<Y.length;ce++){const ue=G[ce],Se=Y[ce],ze=ue.el&&(ue.type===Pe||!Br(ue,Se)||ue.shapeFlag&198)?d(ue.el):fe;v(ue,Se,ze,null,we,ge,Q,te,!0)}},D=(G,Y,fe,we,ge)=>{if(Y!==fe){if(Y!==An)for(const Q in Y)!oc(Q)&&!(Q in fe)&&i(G,Q,Y[Q],null,ge,we);for(const Q in fe){if(oc(Q))continue;const te=fe[Q],ce=Y[Q];te!==ce&&Q!=="value"&&i(G,Q,ce,te,ge,we)}"value"in fe&&i(G,"value",Y.value,fe.value,ge)}},I=(G,Y,fe,we,ge,Q,te,ce,ue)=>{const Se=Y.el=G?G.el:l(""),ze=Y.anchor=G?G.anchor:l("");let{patchFlag:_e,dynamicChildren:Ee,slotScopeIds:it}=Y;it&&(ce=ce?ce.concat(it):it),G==null?(o(Se,fe,we),o(ze,fe,we),A(Y.children||[],fe,ze,ge,Q,te,ce,ue)):_e>0&&_e&64&&Ee&&G.dynamicChildren&&G.dynamicChildren.length===Ee.length?(P(G.dynamicChildren,Ee,fe,ge,Q,te,ce),(Y.key!=null||ge&&Y===ge.subTree)&&V8(G,Y,!0)):U(G,Y,fe,ze,ge,Q,te,ce,ue)},$=(G,Y,fe,we,ge,Q,te,ce,ue)=>{Y.slotScopeIds=ce,G==null?Y.shapeFlag&512?ge.ctx.activate(Y,fe,we,te,ue):B(Y,fe,we,ge,Q,te,ue):H(G,Y,ue)},B=(G,Y,fe,we,ge,Q,te)=>{const ce=G.component=PA(G,we,ge);if(Pp(G)&&(ce.ctx.renderer=ve),BA(ce,!1,te),ce.asyncDep){if(ge&&ge.registerDep(ce,O,te),!G.el){const ue=ce.subTree=j(rs);w(null,ue,Y,fe),G.placeholder=ue.el}}else O(ce,G,Y,fe,ge,Q,te)},H=(G,Y,fe)=>{const we=Y.component=G.component;if(tP(G,Y,fe))if(we.asyncDep&&!we.asyncResolved){F(we,Y,fe);return}else we.next=Y,we.update();else Y.el=G.el,we.vnode=Y},O=(G,Y,fe,we,ge,Q,te)=>{const ce=()=>{if(G.isMounted){let{next:_e,bu:Ee,u:it,parent:Fe,vnode:Oe}=G;{const Yt=EA(G);if(Yt){_e&&(_e.el=Oe.el,F(G,_e,te)),Yt.asyncDep.then(()=>{os(()=>{G.isUnmounted||Se()},ge)});return}}let Ge=_e,at;Iu(G,!1),_e?(_e.el=Oe.el,F(G,_e,te)):_e=Oe,Ee&&$d(Ee),(at=_e.props&&_e.props.onVnodeBeforeUpdate)&&Fi(at,Fe,_e,Oe),Iu(G,!0);const Tt=Ph(G),Bt=G.subTree;G.subTree=Tt,v(Bt,Tt,d(Bt.el),Ie(Bt),G,ge,Q),_e.el=Tt.el,Ge===null&&n2(G,Tt.el),it&&os(it,ge),(at=_e.props&&_e.props.onVnodeUpdated)&&os(()=>Fi(at,Fe,_e,Oe),ge)}else{let _e;const{el:Ee,props:it}=Y,{bm:Fe,m:Oe,parent:Ge,root:at,type:Tt}=G,Bt=na(Y);if(Iu(G,!1),Fe&&$d(Fe),!Bt&&(_e=it&&it.onVnodeBeforeMount)&&Fi(_e,Ge,Y),Iu(G,!0),Ee&&ye){const Yt=()=>{G.subTree=Ph(G),ye(Ee,G.subTree,G,ge,null)};Bt&&Tt.__asyncHydrate?Tt.__asyncHydrate(Ee,G,Yt):Yt()}else{at.ce&&at.ce._hasShadowRoot()&&at.ce._injectChildStyle(Tt,G.parent?G.parent.type:void 0);const Yt=G.subTree=Ph(G);v(null,Yt,fe,we,G,ge,Q),Y.el=Yt.el}if(Oe&&os(Oe,ge),!Bt&&(_e=it&&it.onVnodeMounted)){const Yt=Y;os(()=>Fi(_e,Ge,Yt),ge)}(Y.shapeFlag&256||Ge&&na(Ge.vnode)&&Ge.vnode.shapeFlag&256)&&G.a&&os(G.a,ge),G.isMounted=!0,Y=fe=we=null}};G.scope.on();const ue=G.effect=new dm(ce);G.scope.off();const Se=G.update=ue.run.bind(ue),ze=G.job=ue.runIfDirty.bind(ue);ze.i=G,ze.id=G.uid,ue.scheduler=()=>R8(ze),Iu(G,!0),Se()},F=(G,Y,fe)=>{Y.component=G;const we=G.vnode.props;G.vnode=Y,G.next=null,oP(G,Y.props,we,fe),lP(G,Y.children,fe),wl(),_7(G),_l()},U=(G,Y,fe,we,ge,Q,te,ce,ue=!1)=>{const Se=G&&G.children,ze=G?G.shapeFlag:0,_e=Y.children,{patchFlag:Ee,shapeFlag:it}=Y;if(Ee>0){if(Ee&128){W(Se,_e,fe,we,ge,Q,te,ce,ue);return}else if(Ee&256){z(Se,_e,fe,we,ge,Q,te,ce,ue);return}}it&8?(ze&16&&le(Se,ge,Q),_e!==Se&&c(fe,_e)):ze&16?it&16?W(Se,_e,fe,we,ge,Q,te,ce,ue):le(Se,ge,Q,!0):(ze&8&&c(fe,""),it&16&&A(_e,fe,we,ge,Q,te,ce,ue))},z=(G,Y,fe,we,ge,Q,te,ce,ue)=>{G=G||Id,Y=Y||Id;const Se=G.length,ze=Y.length,_e=Math.min(Se,ze);let Ee;for(Ee=0;Ee<_e;Ee++){const it=Y[Ee]=ue?Kl(Y[Ee]):Di(Y[Ee]);v(G[Ee],it,fe,null,ge,Q,te,ce,ue)}Se>ze?le(G,ge,Q,!0,!1,_e):A(Y,fe,we,ge,Q,te,ce,ue,_e)},W=(G,Y,fe,we,ge,Q,te,ce,ue)=>{let Se=0;const ze=Y.length;let _e=G.length-1,Ee=ze-1;for(;Se<=_e&&Se<=Ee;){const it=G[Se],Fe=Y[Se]=ue?Kl(Y[Se]):Di(Y[Se]);if(Br(it,Fe))v(it,Fe,fe,null,ge,Q,te,ce,ue);else break;Se++}for(;Se<=_e&&Se<=Ee;){const it=G[_e],Fe=Y[Ee]=ue?Kl(Y[Ee]):Di(Y[Ee]);if(Br(it,Fe))v(it,Fe,fe,null,ge,Q,te,ce,ue);else break;_e--,Ee--}if(Se>_e){if(Se<=Ee){const it=Ee+1,Fe=it<ze?Y[it].el:we;for(;Se<=Ee;)v(null,Y[Se]=ue?Kl(Y[Se]):Di(Y[Se]),fe,Fe,ge,Q,te,ce,ue),Se++}}else if(Se>Ee)for(;Se<=_e;)V(G[Se],ge,Q,!0),Se++;else{const it=Se,Fe=Se,Oe=new Map;for(Se=Fe;Se<=Ee;Se++){const en=Y[Se]=ue?Kl(Y[Se]):Di(Y[Se]);en.key!=null&&Oe.set(en.key,Se)}let Ge,at=0;const Tt=Ee-Fe+1;let Bt=!1,Yt=0;const Sn=new Array(Tt);for(Se=0;Se<Tt;Se++)Sn[Se]=0;for(Se=it;Se<=_e;Se++){const en=G[Se];if(at>=Tt){V(en,ge,Q,!0);continue}let Cn;if(en.key!=null)Cn=Oe.get(en.key);else for(Ge=Fe;Ge<=Ee;Ge++)if(Sn[Ge-Fe]===0&&Br(en,Y[Ge])){Cn=Ge;break}Cn===void 0?V(en,ge,Q,!0):(Sn[Cn-Fe]=Se+1,Cn>=Yt?Yt=Cn:Bt=!0,v(en,Y[Cn],fe,null,ge,Q,te,ce,ue),at++)}const on=Bt?cP(Sn):Id;for(Ge=on.length-1,Se=Tt-1;Se>=0;Se--){const en=Fe+Se,Cn=Y[en],Mn=Y[en+1],We=en+1<ze?Mn.el||IA(Mn):we;Sn[Se]===0?v(null,Cn,fe,We,ge,Q,te,ce,ue):Bt&&(Ge<0||Se!==on[Ge]?K(Cn,fe,We,2):Ge--)}}},K=(G,Y,fe,we,ge=null)=>{const{el:Q,type:te,transition:ce,children:ue,shapeFlag:Se}=G;if(Se&6){K(G.component.subTree,Y,fe,we);return}if(Se&128){G.suspense.move(Y,fe,we);return}if(Se&64){te.move(G,Y,fe,ve);return}if(te===Pe){o(Q,Y,fe);for(let _e=0;_e<ue.length;_e++)K(ue[_e],Y,fe,we);o(G.anchor,Y,fe);return}if(te===Od){_(G,Y,fe);return}if(we!==2&&Se&1&&ce)if(we===0)ce.persisted&&!Q[yr]?o(Q,Y,fe):(ce.beforeEnter(Q),o(Q,Y,fe),os(()=>ce.enter(Q),ge));else{const{leave:_e,delayLeave:Ee,afterLeave:it}=ce,Fe=()=>{G.ctx.isUnmounted?s(Q):o(Q,Y,fe)},Oe=()=>{const Ge=Q._isLeaving||!!Q[yr];Q._isLeaving&&Q[yr](!0),ce.persisted&&!Ge?Fe():_e(Q,()=>{Fe(),it&&it()})};Ee?Ee(Q,Fe,Oe):Oe()}else o(Q,Y,fe)},V=(G,Y,fe,we=!1,ge=!1)=>{const{type:Q,props:te,ref:ce,children:ue,dynamicChildren:Se,shapeFlag:ze,patchFlag:_e,dirs:Ee,cacheIndex:it,memo:Fe}=G;if(_e===-2&&(ge=!1),ce!=null&&(wl(),Fd(ce,null,fe,G,!0),_l()),it!=null&&(Y.renderCache[it]=void 0),ze&256){Y.ctx.deactivate(G);return}const Oe=ze&1&&Ee,Ge=!na(G);let at;if(Ge&&(at=te&&te.onVnodeBeforeUnmount)&&Fi(at,Y,G),ze&6)X(G.component,fe,we);else{if(ze&128){G.suspense.unmount(fe,we);return}Oe&&hl(G,null,Y,"beforeUnmount"),ze&64?G.type.remove(G,Y,fe,ve,we):Se&&!Se.hasOnce&&(Q!==Pe||_e>0&&_e&64)?le(Se,Y,fe,!1,!0):(Q===Pe&&_e&384||!ge&&ze&16)&&le(ue,Y,fe),we&&ie(G)}const Tt=Fe!=null&&it==null;(Ge&&(at=te&&te.onVnodeUnmounted)||Oe||Tt)&&os(()=>{at&&Fi(at,Y,G),Oe&&hl(G,null,Y,"unmounted"),Tt&&(G.el=null)},fe)},ie=G=>{const{type:Y,el:fe,anchor:we,transition:ge}=G;if(Y===Pe){ne(fe,we);return}if(Y===Od){g(G);return}const Q=()=>{s(fe),ge&&!ge.persisted&&ge.afterLeave&&ge.afterLeave()};if(G.shapeFlag&1&&ge&&!ge.persisted){const{leave:te,delayLeave:ce}=ge,ue=()=>te(fe,Q);ce?ce(G.el,Q,ue):ue()}else Q()},ne=(G,Y)=>{let fe;for(;G!==Y;)fe=f(G),s(G),G=fe;s(Y)},X=(G,Y,fe)=>{const{bum:we,scope:ge,job:Q,subTree:te,um:ce,m:ue,a:Se}=G;bm(ue),bm(Se),we&&$d(we),ge.stop(),Q&&(Q.flags|=8,V(te,G,Y,fe)),ce&&os(ce,Y),os(()=>{G.isUnmounted=!0},Y)},le=(G,Y,fe,we=!1,ge=!1,Q=0)=>{for(let te=Q;te<G.length;te++)V(G[te],Y,fe,we,ge)},Ie=G=>{if(G.shapeFlag&6)return Ie(G.component.subTree);if(G.shapeFlag&128)return G.suspense.next();const Y=f(G.anchor||G.el),fe=Y&&Y[nA];return fe?f(fe):Y};let de=!1;const pe=(G,Y,fe)=>{let we;G==null?Y._vnode&&(V(Y._vnode,null,null,!0),we=Y._vnode.component):v(Y._vnode||null,G,Y,null,null,null,fe),Y._vnode=G,de||(de=!0,_7(we),gm(),de=!1)},ve={p:v,um:V,m:K,r:ie,mt:B,mc:A,pc:U,pbc:P,n:Ie,o:e};let oe,ye;return t&&([oe,ye]=t(ve)),{render:pe,hydrate:oe,createApp:GO(pe,oe)}}function Vv({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function Iu({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function TA(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function V8(e,t,n=!1){const o=e.children,s=t.children;if(jt(o)&&jt(s))for(let i=0;i<o.length;i++){const r=o[i];let l=s[i];l.shapeFlag&1&&!l.dynamicChildren&&((l.patchFlag<=0||l.patchFlag===32)&&(l=s[i]=Kl(s[i]),l.el=r.el),!n&&l.patchFlag!==-2&&V8(r,l)),l.type===Ua&&(l.patchFlag===-1&&(l=s[i]=Kl(l)),l.el=r.el),l.type===rs&&!l.el&&(l.el=r.el)}}function cP(e){const t=e.slice(),n=[0];let o,s,i,r,l;const a=e.length;for(o=0;o<a;o++){const u=e[o];if(u!==0){if(s=n[n.length-1],e[s]<u){t[o]=s,n.push(o);continue}for(i=0,r=n.length-1;i<r;)l=i+r>>1,e[n[l]]<u?i=l+1:r=l;u<e[n[i]]&&(i>0&&(t[o]=n[i-1]),n[i]=o)}}for(i=n.length,r=n[i-1];i-- >0;)n[i]=r,r=t[r];return n}function EA(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:EA(t)}function bm(e){if(e)for(let t=0;t<e.length;t++)e[t].flags|=8}function IA(e){if(e.placeholder)return e.placeholder;const t=e.component;return t?IA(t.subTree):null}const Cm=e=>e.__isSuspense;let D4=0;const dP={name:"Suspense",__isSuspense:!0,process(e,t,n,o,s,i,r,l,a,u){if(e==null)fP(t,n,o,s,i,r,l,a,u);else{if(i&&i.deps>0&&!e.suspense.isInFallback){t.suspense=e.suspense,t.suspense.vnode=t,t.el=e.el;return}pP(e,t,n,o,s,r,l,a,u)}},hydrate:hP,normalize:mP},tVe=dP;function dp(e,t){const n=e.props&&e.props[t];un(n)&&n()}function fP(e,t,n,o,s,i,r,l,a){const{p:u,o:{createElement:c}}=a,d=c("div"),f=e.suspense=LA(e,s,o,t,d,n,i,r,l,a);u(null,f.pendingBranch=e.ssContent,d,null,o,f,i,r),f.deps>0?(dp(e,"onPending"),dp(e,"onFallback"),u(null,e.ssFallback,t,n,o,null,i,r),Rd(f,e.ssFallback)):f.resolve(!1,!0)}function pP(e,t,n,o,s,i,r,l,{p:a,um:u,o:{createElement:c}}){const d=t.suspense=e.suspense;d.vnode=t,t.el=e.el;const f=t.ssContent,h=t.ssFallback,{activeBranch:m,pendingBranch:v,isInFallback:k,isHydrating:w}=d;if(v)d.pendingBranch=f,Br(v,f)?(a(v,f,d.hiddenContainer,null,s,d,i,r,l),d.deps<=0?d.resolve():k&&(w||(a(m,h,n,o,s,null,i,r,l),Rd(d,h)))):(d.pendingId=D4++,w?(d.isHydrating=!1,d.activeBranch=v):u(v,s,d),d.deps=0,d.effects.length=0,d.hiddenContainer=c("div"),k?(a(null,f,d.hiddenContainer,null,s,d,i,r,l),d.deps<=0?d.resolve():(a(m,h,n,o,s,null,i,r,l),Rd(d,h))):m&&Br(m,f)?(a(m,f,n,o,s,d,i,r,l),d.resolve(!0)):(a(null,f,d.hiddenContainer,null,s,d,i,r,l),d.deps<=0&&d.resolve()));else if(m&&Br(m,f))a(m,f,n,o,s,d,i,r,l),Rd(d,f);else if(dp(t,"onPending"),d.pendingBranch=f,f.shapeFlag&512?d.pendingId=f.component.suspenseId:d.pendingId=D4++,a(null,f,d.hiddenContainer,null,s,d,i,r,l),d.deps<=0)d.resolve();else{const{timeout:b,pendingId:_}=d;b>0?setTimeout(()=>{d.pendingId===_&&d.fallback(h)},b):b===0&&d.fallback(h)}}function LA(e,t,n,o,s,i,r,l,a,u,c=!1){const{p:d,m:f,um:h,n:m,o:{parentNode:v,remove:k}}=u;let w;const b=gP(e);b&&t&&t.pendingBranch&&(w=t.pendingId,t.deps++);const _=e.props?cm(e.props.timeout):void 0,g=i,x={vnode:e,parent:t,parentComponent:n,namespace:r,container:o,hiddenContainer:s,deps:0,pendingId:D4++,timeout:typeof _=="number"?_:-1,activeBranch:null,isFallbackMountPending:!1,pendingBranch:null,isInFallback:!c,isHydrating:c,isUnmounted:!1,effects:[],resolve(S=!1,T=!1){const{vnode:A,activeBranch:E,pendingBranch:P,pendingId:D,effects:I,parentComponent:$,container:B,isInFallback:H}=x;let O=!1;if(x.isHydrating)x.isHydrating=!1;else if(!S){O=E&&P.transition&&P.transition.mode==="out-in";let z=!1;O&&(E.transition.afterLeave=()=>{D===x.pendingId&&(f(P,B,i===g&&!z?m(E):i,0),mm(I),H&&A.ssFallback&&(A.ssFallback.el=null))}),E&&!x.isFallbackMountPending&&(v(E.el)===B&&(i=m(E),z=!0),h(E,$,x,!0),!O&&H&&A.ssFallback&&os(()=>A.ssFallback.el=null,x)),O||f(P,B,i,0)}x.isFallbackMountPending=!1,Rd(x,P),x.pendingBranch=null,x.isInFallback=!1;let F=x.parent,U=!1;for(;F;){if(F.pendingBranch){F.effects.push(...I),U=!0;break}F=F.parent}!U&&!O&&mm(I),x.effects=[],b&&t&&t.pendingBranch&&w===t.pendingId&&(t.deps--,t.deps===0&&!T&&t.resolve()),dp(A,"onResolve")},fallback(S){if(!x.pendingBranch)return;const{vnode:T,activeBranch:A,parentComponent:E,container:P,namespace:D}=x;dp(T,"onFallback");const I=m(A),$=()=>{x.isFallbackMountPending=!1,x.isInFallback&&(d(null,S,P,I,E,null,D,l,a),Rd(x,S))},B=S.transition&&S.transition.mode==="out-in";B&&(x.isFallbackMountPending=!0,A.transition.afterLeave=$),x.isInFallback=!0,h(A,E,null,!0),B||$()},move(S,T,A){x.activeBranch&&f(x.activeBranch,S,T,A),x.container=S},next(){return x.activeBranch&&m(x.activeBranch)},registerDep(S,T,A){const E=!!x.pendingBranch;E&&x.deps++;const P=S.vnode.el;S.asyncDep.catch(D=>{f1(D,S,0)}).then(D=>{if(S.isUnmounted||x.isUnmounted||x.pendingId!==S.suspenseId)return;fp(),S.asyncResolved=!0;const{vnode:I}=S;B4(S,D,!1),P&&(I.el=P);const $=!P&&S.subTree.el;T(S,I,v(P||S.subTree.el),P?null:m(S.subTree),x,r,A),$&&(I.placeholder=null,k($)),n2(S,I.el),E&&--x.deps===0&&x.resolve()})},unmount(S,T){x.isUnmounted=!0,x.activeBranch&&h(x.activeBranch,n,S,T),x.pendingBranch&&h(x.pendingBranch,n,S,T)}};return x}function hP(e,t,n,o,s,i,r,l,a){const u=t.suspense=LA(t,o,n,e.parentNode,document.createElement("div"),null,s,i,r,l,!0),c=a(e,u.pendingBranch=t.ssContent,n,u,i,r);return u.deps===0&&u.resolve(!1,!0),c}function mP(e){const{shapeFlag:t,children:n}=e,o=t&32;e.ssContent=O7(o?n.default:n),e.ssFallback=o?O7(n.fallback):j(rs)}function O7(e){let t;if(un(e)){const n=dc&&e._c;n&&(e._d=!1,y()),e=e(),n&&(e._d=!0,t=ri,NA())}return jt(e)&&(e=JO(e)),e=Di(e),t&&!e.dynamicChildren&&(e.dynamicChildren=t.filter(n=>n!==e)),e}function $A(e,t){t&&t.pendingBranch?jt(e)?t.effects.push(...e):t.effects.push(e):mm(e)}function Rd(e,t){e.activeBranch=t;const{vnode:n,parentComponent:o}=e;let s=t.el;for(;!s&&t.component;)t=t.component.subTree,s=t.el;n.el=s,o&&o.subTree===n&&(o.vnode.el=s,n2(o,s))}function gP(e){const t=e.props&&e.props.suspensible;return t!=null&&t!==!1}const Pe=Symbol.for("v-fgt"),Ua=Symbol.for("v-txt"),rs=Symbol.for("v-cmt"),Od=Symbol.for("v-stc"),Rf=[];let ri=null;function y(e=!1){Rf.push(ri=e?null:[])}function NA(){Rf.pop(),ri=Rf[Rf.length-1]||null}let dc=1;function wm(e,t=!1){dc+=e,e<0&&ri&&t&&(ri.hasOnce=!0)}function FA(e){return e.dynamicChildren=dc>0?ri||Id:null,NA(),dc>0&&ri&&ri.push(e),e}function M(e,t,n,o,s,i){return FA(C(e,t,n,o,s,i,!0))}function he(e,t,n,o,s){return FA(j(e,t,n,o,s,!0))}function Ga(e){return e?e.__v_isVNode===!0:!1}function Br(e,t){return e.type===t.type&&e.key===t.key}function nVe(e){}const RA=({key:e})=>e??null,Dh=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?ro(e)||Xo(e)||un(e)?{i:Ks,r:e,k:t,f:!!n}:e:null);function C(e,t=null,n=null,o=0,s=null,i=e===Pe?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&RA(t),ref:t&&Dh(t),scopeId:Qg,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:o,dynamicProps:s,dynamicChildren:null,appContext:null,ctx:Ks};return l?(_m(a,n),i&128&&e.normalize(a)):n&&(a.shapeFlag|=ro(n)?8:16),dc>0&&!r&&ri&&(a.patchFlag>0||i&6)&&a.patchFlag!==32&&ri.push(a),a}const j=vP;function vP(e,t=null,n=null,o=0,s=null,i=!1){if((!e||e===dA)&&(e=rs),Ga(e)){const l=ra(e,t,!0);return n&&_m(l,n),dc>0&&!i&&ri&&(l.shapeFlag&6?ri[ri.indexOf(e)]=l:ri.push(l)),l.patchFlag=-2,l}if(wP(e)&&(e=e.__vccOpts),t){t=OA(t);let{class:l,style:a}=t;l&&!ro(l)&&(t.class=Re(l)),Zn(a)&&(Jg(a)&&!jt(a)&&(a=to({},a)),t.style=Zt(a))}const r=ro(e)?1:Cm(e)?128:oA(e)?64:Zn(e)?4:un(e)?2:0;return C(e,t,n,o,s,r,i,!0)}function OA(e){return e?Jg(e)||CA(e)?to({},e):e:null}function ra(e,t,n=!1,o=!1){const{props:s,ref:i,patchFlag:r,children:l,transition:a}=e,u=t?zn(s||{},t):s,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&RA(u),ref:t&&t.ref?n&&i?jt(i)?i.concat(Dh(t)):[i,Dh(t)]:Dh(t):i,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Pe?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&ra(e.ssContent),ssFallback:e.ssFallback&&ra(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&o&&Za(c,a.clone(c)),c}function qe(e=" ",t=0){return j(Ua,null,e,t)}function iu(e,t){const n=j(Od,null,e);return n.staticCount=t,n}function ee(e="",t=!1){return t?(y(),he(rs,null,e)):j(rs,null,e)}function Di(e){return e==null||typeof e=="boolean"?j(rs):jt(e)?j(Pe,null,e.slice()):Ga(e)?Kl(e):j(Ua,null,String(e))}function Kl(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:ra(e)}function _m(e,t){let n=0;const{shapeFlag:o}=e;if(t==null)t=null;else if(jt(t))n=16;else if(typeof t=="object")if(o&65){const s=t.default;s&&(s._c&&(s._d=!1),_m(e,s()),s._c&&(s._d=!0));return}else{n=32;const s=t._;!s&&!CA(t)?t._ctx=Ks:s===3&&Ks&&(Ks.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(un(t)){if(o&65){_m(e,{default:t});return}t={default:t,_ctx:Ks},n=32}else t=String(t),o&64?(n=16,t=[qe(t)]):n=8;e.children=t,e.shapeFlag|=n}function zn(...e){const t={};for(let n=0;n<e.length;n++){const o=e[n];for(const s in o)if(s==="class")t.class!==o.class&&(t.class=Re([t.class,o.class]));else if(s==="style")t.style=Zt([t.style,o.style]);else if(Fp(s)){const i=t[s],r=o[s];r&&i!==r&&!(jt(i)&&i.includes(r))?t[s]=i?[].concat(i,r):r:r==null&&i==null&&!Bg(s)&&(t[s]=r)}else s!==""&&(t[s]=o[s])}return t}function Fi(e,t,n,o=null){xr(e,t,7,[n,o])}const yP=mA();let kP=0;function PA(e,t,n){const o=e.type,s=(t?t.appContext:e.appContext)||yP,i={uid:kP++,vnode:e,type:o,parent:t,appContext:s,root:null,next:null,subTree:null,effect:null,update:null,job:null,scope:new IS(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(s.provides),ids:t?t.ids:["",0,0],accessCache:null,renderCache:[],components:null,directives:null,propsOptions:_A(o,s),emitsOptions:vA(o,s),emit:null,emitted:null,propsDefaults:An,inheritAttrs:o.inheritAttrs,ctx:An,data:An,props:An,attrs:An,slots:An,refs:An,setupState:An,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return i.ctx={_:i},i.root=t?t.root:i,i.emit=YO.bind(null,i),e.ce&&e.ce(i),i}let Vs=null;const ds=()=>Vs||Ks;let xm,Pd;{const e=Vg(),t=(n,o)=>{let s;return(s=e[n])||(s=e[n]=[]),s.push(o),i=>{s.length>1?s.forEach(r=>r(i)):s[0](i)}};xm=t("__VUE_INSTANCE_SETTERS__",n=>Vs=n),Pd=t("__VUE_SSR_SETTERS__",n=>fc=n)}const h1=e=>{const t=Vs;return xm(e),e.scope.on(),()=>{e.scope.off(),xm(t)}},fp=()=>{Vs&&Vs.scope.off(),xm(null)};function DA(e){return e.vnode.shapeFlag&4}let fc=!1;function BA(e,t=!1,n=!1){t&&Pd(t);const{props:o,children:s}=e.vnode,i=DA(e);nP(e,o,i,t),rP(e,s,n||t);const r=i?bP(e,t):void 0;return t&&Pd(!1),r}function bP(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,F4);const{setup:o}=n;if(o){wl();const s=e.setupContext=o.length>1?zA(e):null,i=h1(e),r=Rp(o,e,0,[e.props,s]),l=L8(r);if(_l(),i(),(l||e.sp)&&!na(e)&&P8(e),l){if(r.then(fp,fp),t)return r.then(a=>{B4(e,a,t)}).catch(a=>{f1(a,e,0)});e.asyncDep=r}else B4(e,r,t)}else HA(e,t)}function B4(e,t,n){un(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Zn(t)&&(e.setupState=ZS(t)),HA(e,n)}let Sm,H4;function oVe(e){Sm=e,H4=t=>{t.render._rc&&(t.withProxy=new Proxy(t.ctx,WO))}}const sVe=()=>!Sm;function HA(e,t,n){const o=e.type;if(!e.render){if(!t&&Sm&&!o.render){const s=o.template||W8(e).template;if(s){const{isCustomElement:i,compilerOptions:r}=e.appContext.config,{delimiters:l,compilerOptions:a}=o,u=to(to({isCustomElement:i,delimiters:l},r),a);o.render=Sm(s,u)}}e.render=o.render||wr,H4&&H4(e)}{const s=h1(e);wl();try{UO(e)}finally{_l(),s()}}}const CP={get(e,t){return ii(e,"get",""),e[t]}};function zA(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,CP),slots:e.slots,emit:e.emit,expose:t}}function Bp(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(ZS(kt(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Ff)return Ff[n](e)},has(t,n){return n in t||n in Ff}})):e.proxy}function z4(e,t=!0){return un(e)?e.displayName||e.name:e.name||t&&e.__name}function wP(e){return un(e)&&"__vccOpts"in e}const R=(e,t)=>nO(e,t,fc);function tn(e,t,n){try{wm(-1);const o=arguments.length;return o===2?Zn(t)&&!jt(t)?Ga(t)?j(e,null,[t]):j(e,t):j(e,null,t):(o>3?n=Array.prototype.slice.call(arguments,2):o===3&&Ga(n)&&(n=[n]),j(e,t,n))}finally{wm(1)}}function iVe(){}function rVe(e,t,n,o){const s=n[o];if(s&&_P(s,e))return s;const i=t();return i.memo=e.slice(),i.cacheIndex=o,n[o]=i}function _P(e,t){const n=e.memo;if(n.length!=t.length)return!1;for(let o=0;o<n.length;o++)if(Es(n[o],t[o]))return!1;return dc>0&&ri&&ri.push(e),!0}const xP="3.5.39",lVe=wr,aVe=lO,uVe=fd,cVe=eA,SP={createComponentInstance:PA,setupComponent:BA,renderComponentRoot:Ph,setCurrentRenderingInstance:ap,isVNode:Ga,normalizeVNode:Di,getComponentPublicInstance:Bp,ensureValidVNode:z8,pushWarningContext:iO,popWarningContext:rO},dVe=SP,fVe=null,pVe=null,hVe=null;/** +* @vue/runtime-dom v3.5.39 +* (c) 2018-present Yuxi (Evan) You and Vue contributors +* @license MIT +**/let W4;const P7=typeof window<"u"&&window.trustedTypes;if(P7)try{W4=P7.createPolicy("vue",{createHTML:e=>e})}catch{}const WA=W4?e=>W4.createHTML(e):e=>e,AP="http://www.w3.org/2000/svg",MP="http://www.w3.org/1998/Math/MathML",jl=typeof document<"u"?document:null,D7=jl&&jl.createElement("template"),TP={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,o)=>{const s=t==="svg"?jl.createElementNS(AP,e):t==="mathml"?jl.createElementNS(MP,e):n?jl.createElement(e,{is:n}):jl.createElement(e);return e==="select"&&o&&o.multiple!=null&&s.setAttribute("multiple",o.multiple),s},createText:e=>jl.createTextNode(e),createComment:e=>jl.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>jl.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,o,s,i){const r=n?n.previousSibling:t.lastChild;if(s&&(s===i||s.nextSibling))for(;t.insertBefore(s.cloneNode(!0),n),!(s===i||!(s=s.nextSibling)););else{D7.innerHTML=WA(o==="svg"?`<svg>${e}</svg>`:o==="mathml"?`<math>${e}</math>`:e);const l=D7.content;if(o==="svg"||o==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[r?r.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},va="transition",X1="animation",Jd=Symbol("_vtc"),UA={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},jA=to({},iA,UA),EP=e=>(e.displayName="Transition",e.props=jA,e),as=EP((e,{slots:t})=>tn(yO,VA(e),t)),Lu=(e,t=[])=>{jt(e)?e.forEach(n=>n(...t)):e&&e(...t)},B7=e=>e?jt(e)?e.some(t=>t.length>1):e.length>1:!1;function VA(e){const t={};for(const I in e)I in UA||(t[I]=e[I]);if(e.css===!1)return t;const{name:n="v",type:o,duration:s,enterFromClass:i=`${n}-enter-from`,enterActiveClass:r=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=i,appearActiveClass:u=r,appearToClass:c=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:f=`${n}-leave-active`,leaveToClass:h=`${n}-leave-to`}=e,m=IP(s),v=m&&m[0],k=m&&m[1],{onBeforeEnter:w,onEnter:b,onEnterCancelled:_,onLeave:g,onLeaveCancelled:x,onBeforeAppear:S=w,onAppear:T=b,onAppearCancelled:A=_}=t,E=(I,$,B,H)=>{I._enterCancelled=H,Ma(I,$?c:l),Ma(I,$?u:r),B&&B()},P=(I,$)=>{I._isLeaving=!1,Ma(I,d),Ma(I,h),Ma(I,f),$&&$()},D=I=>($,B)=>{const H=I?T:b,O=()=>E($,I,B);Lu(H,[$,O]),H7(()=>{Ma($,I?a:i),dl($,I?c:l),B7(H)||z7($,o,v,O)})};return to(t,{onBeforeEnter(I){Lu(w,[I]),dl(I,i),dl(I,r)},onBeforeAppear(I){Lu(S,[I]),dl(I,a),dl(I,u)},onEnter:D(!1),onAppear:D(!0),onLeave(I,$){I._isLeaving=!0;const B=()=>P(I,$);dl(I,d),I._enterCancelled?(dl(I,f),U4(I)):(U4(I),dl(I,f)),H7(()=>{I._isLeaving&&(Ma(I,d),dl(I,h),B7(g)||z7(I,o,k,B))}),Lu(g,[I,B])},onEnterCancelled(I){E(I,!1,void 0,!0),Lu(_,[I])},onAppearCancelled(I){E(I,!0,void 0,!0),Lu(A,[I])},onLeaveCancelled(I){P(I),Lu(x,[I])}})}function IP(e){if(e==null)return null;if(Zn(e))return[qv(e.enter),qv(e.leave)];{const t=qv(e);return[t,t]}}function qv(e){return cm(e)}function dl(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Jd]||(e[Jd]=new Set)).add(t)}function Ma(e,t){t.split(/\s+/).forEach(o=>o&&e.classList.remove(o));const n=e[Jd];n&&(n.delete(t),n.size||(e[Jd]=void 0))}function H7(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let LP=0;function z7(e,t,n,o){const s=e._endId=++LP,i=()=>{s===e._endId&&o()};if(n!=null)return setTimeout(i,n);const{type:r,timeout:l,propCount:a}=qA(e,t);if(!r)return o();const u=r+"end";let c=0;const d=()=>{e.removeEventListener(u,f),i()},f=h=>{h.target===e&&++c>=a&&d()};setTimeout(()=>{c<a&&d()},l+1),e.addEventListener(u,f)}function qA(e,t){const n=window.getComputedStyle(e),o=m=>(n[m]||"").split(", "),s=o(`${va}Delay`),i=o(`${va}Duration`),r=W7(s,i),l=o(`${X1}Delay`),a=o(`${X1}Duration`),u=W7(l,a);let c=null,d=0,f=0;t===va?r>0&&(c=va,d=r,f=i.length):t===X1?u>0&&(c=X1,d=u,f=a.length):(d=Math.max(r,u),c=d>0?r>u?va:X1:null,f=c?c===va?i.length:a.length:0);const h=c===va&&/\b(?:transform|all)(?:,|$)/.test(o(`${va}Property`).toString());return{type:c,timeout:d,propCount:f,hasTransform:h}}function W7(e,t){for(;e.length<t.length;)e=e.concat(e);return Math.max(...t.map((n,o)=>U7(n)+U7(e[o])))}function U7(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function U4(e){return(e?e.ownerDocument:document).body.offsetHeight}function $P(e,t,n){const o=e[Jd];o&&(t=(t?[t,...o]:[...o]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const Am=Symbol("_vod"),q8=Symbol("_vsh"),qs={name:"show",beforeMount(e,{value:t},{transition:n}){e[Am]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):J1(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:o}){!t!=!n&&(o?t?(o.beforeEnter(e),J1(e,!0),o.enter(e)):o.leave(e,()=>{J1(e,!1)}):J1(e,t))},beforeUnmount(e,{value:t}){J1(e,t)}};function J1(e,t){e.style.display=t?e[Am]:"none",e[q8]=!t}function NP(){qs.getSSRProps=({value:e})=>{if(!e)return{style:{display:"none"}}}}const KA=Symbol("");function mVe(e){const t=ds();if(!t)return;const n=t.ut=(s=e(t.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${t.uid}"]`)).forEach(i=>Mm(i,s))},o=()=>{const s=e(t.proxy);t.ce?Mm(t.ce,s):j4(t.subTree,s),n(s)};cA(()=>{mm(o)}),dn(()=>{Je(o,wr,{flush:"post"});const s=new MutationObserver(o);s.observe(t.subTree.el.parentNode,{childList:!0}),bn(()=>s.disconnect())})}function j4(e,t){if(e.shapeFlag&128){const n=e.suspense;e=n.activeBranch,n.pendingBranch&&!n.isHydrating&&n.effects.push(()=>{j4(n.activeBranch,t)})}for(;e.component;)e=e.component.subTree;if(e.shapeFlag&1&&e.el)Mm(e.el,t);else if(e.type===Pe)e.children.forEach(n=>j4(n,t));else if(e.type===Od){let{el:n,anchor:o}=e;for(;n&&(Mm(n,t),n!==o);)n=n.nextSibling}}function Mm(e,t){if(e.nodeType===1){const n=e.style;let o="";for(const s in t){const i=TR(t[s]);n.setProperty(`--${s}`,i),o+=`--${s}: ${i};`}n[KA]=o}}const FP=/(?:^|;)\s*display\s*:/;function RP(e,t,n){const o=e.style,s=ro(n);let i=!1;if(n&&!s){if(t)if(ro(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();n[l]==null&&gf(o,l,"")}else for(const r in t)n[r]==null&&gf(o,r,"");for(const r in n){r==="display"&&(i=!0);const l=n[r];l!=null?PP(e,r,!ro(t)&&t?t[r]:void 0,l)||gf(o,r,l):gf(o,r,"")}}else if(s){if(t!==n){const r=o[KA];r&&(n+=";"+r),o.cssText=n,i=FP.test(n)}}else t&&e.removeAttribute("style");Am in e&&(e[Am]=i?o.display:"",e[q8]&&(o.display="none"))}const j7=/\s*!important$/;function gf(e,t,n){if(jt(n))n.forEach(o=>gf(e,t,o));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const o=OP(e,t);j7.test(n)?e.setProperty(Bi(o),n.replace(j7,""),"important"):e[o]=n}}const V7=["Webkit","Moz","ms"],Kv={};function OP(e,t){const n=Kv[t];if(n)return n;let o=_s(t);if(o!=="filter"&&o in e)return Kv[t]=o;o=Ug(o);for(let s=0;s<V7.length;s++){const i=V7[s]+o;if(i in e)return Kv[t]=i}return t}function PP(e,t,n,o){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&ro(o)&&n===o}const q7="http://www.w3.org/1999/xlink";function K7(e,t,n,o,s,i=AR(t)){o&&t.startsWith("xlink:")?n==null?e.removeAttributeNS(q7,t.slice(6,t.length)):e.setAttributeNS(q7,t,n):n==null||i&&!MS(n)?e.removeAttribute(t):e.setAttribute(t,i?"":lr(n)?String(n):n)}function Z7(e,t,n,o,s){if(t==="innerHTML"||t==="textContent"){n!=null&&(e[t]=t==="innerHTML"?WA(n):n);return}const i=e.tagName;if(t==="value"&&i!=="PROGRESS"&&!i.includes("-")){const l=i==="OPTION"?e.getAttribute("value")||"":e.value,a=n==null?e.type==="checkbox"?"on":"":String(n);(l!==a||!("_value"in e))&&(e.value=a),n==null&&e.removeAttribute(t),e._value=n;return}let r=!1;if(n===""||n==null){const l=typeof e[t];l==="boolean"?n=MS(n):n==null&&l==="string"?(n="",r=!0):l==="number"&&(n=0,r=!0)}try{e[t]=n}catch{}r&&e.removeAttribute(s||t)}function Yl(e,t,n,o){e.addEventListener(t,n,o)}function DP(e,t,n,o){e.removeEventListener(t,n,o)}const G7=Symbol("_vei");function BP(e,t,n,o,s=null){const i=e[G7]||(e[G7]={}),r=i[t];if(o&&r)r.value=o;else{const[l,a]=WP(t);if(o){const u=i[t]=VP(o,s);Yl(e,l,u,a)}else r&&(DP(e,l,r,a),i[t]=void 0)}}const HP=/(Once|Passive|Capture)$/,zP=/^on:?(?:Once|Passive|Capture)$/;function WP(e){let t,n;for(;(n=e.match(HP))&&!zP.test(e);)t||(t={}),e=e.slice(0,e.length-n[1].length),t[n[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):Bi(e.slice(2)),t]}let Zv=0;const UP=Promise.resolve(),jP=()=>Zv||(UP.then(()=>Zv=0),Zv=Date.now());function VP(e,t){const n=o=>{if(!o._vts)o._vts=Date.now();else if(o._vts<=n.attached)return;const s=n.value;if(jt(s)){const i=o.stopImmediatePropagation;o.stopImmediatePropagation=()=>{i.call(o),o._stopped=!0};const r=s.slice(),l=[o];for(let a=0;a<r.length&&!o._stopped;a++){const u=r[a];u&&xr(u,t,5,l)}}else xr(s,t,5,[o])};return n.value=e,n.attached=jP(),n}const Y7=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,qP=(e,t,n,o,s,i)=>{const r=s==="svg";t==="class"?$P(e,o,r):t==="style"?RP(e,n,o):Fp(t)?Bg(t)||BP(e,t,n,o,i):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):KP(e,t,o,r))?(Z7(e,t,o),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&K7(e,t,o,r,i,t!=="value")):e._isVueCE&&(ZP(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!ro(o)))?Z7(e,_s(t),o,i,t):(t==="true-value"?e._trueValue=o:t==="false-value"&&(e._falseValue=o),K7(e,t,o,r))};function KP(e,t,n,o){if(o)return!!(t==="innerHTML"||t==="textContent"||t in e&&Y7(t)&&un(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const s=e.tagName;if(s==="IMG"||s==="VIDEO"||s==="CANVAS"||s==="SOURCE")return!1}return Y7(t)&&ro(n)?!1:t in e}function ZP(e,t){const n=e._def.props;if(!n)return!1;const o=_s(t);return Array.isArray(n)?n.some(s=>_s(s)===o):Object.keys(n).some(s=>_s(s)===o)}const X7={};function GP(e,t,n){let o=et(e,t);Hg(o)&&(o=to({},o,t));class s extends K8{constructor(r){super(o,r,n)}}return s.def=o,s}const gVe=((e,t)=>GP(e,t,dD)),YP=typeof HTMLElement<"u"?HTMLElement:class{};class K8 extends YP{constructor(t,n={},o=Im){super(),this._def=t,this._props=n,this._createApp=o,this._isVueCE=!0,this._instance=null,this._app=null,this._nonce=this._def.nonce,this._connected=!1,this._resolved=!1,this._patching=!1,this._dirty=!1,this._numberProps=null,this._styleChildren=new WeakSet,this._styleAnchors=new WeakMap,this._ob=null,this.shadowRoot&&o!==Im?this._root=this.shadowRoot:t.shadowRoot!==!1?(this.attachShadow(to({},t.shadowRootOptions,{mode:"open"})),this._root=this.shadowRoot):this._root=this}connectedCallback(){if(!this.isConnected)return;!this.shadowRoot&&!this._resolved&&this._parseSlots(),this._connected=!0;let t=this;for(;t=t&&(t.assignedSlot||t.parentNode||t.host);)if(t instanceof K8){this._parent=t;break}this._instance||(this._resolved?this._mount(this._def):t&&t._pendingResolve?this._pendingResolve=t._pendingResolve.then(()=>{this._pendingResolve=void 0,this._resolveDef()}):this._resolveDef())}_setParent(t=this._parent){t&&(this._instance.parent=t._instance,this._inheritParentContext(t))}_inheritParentContext(t=this._parent){t&&this._app&&Object.setPrototypeOf(this._app._context.provides,t._instance.provides)}disconnectedCallback(){this._connected=!1,yt(()=>{this._connected||(this._ob&&(this._ob.disconnect(),this._ob=null),this._app&&this._app.unmount(),this._instance&&(this._instance.ce=void 0),this._app=this._instance=null,this._teleportTargets&&(this._teleportTargets.clear(),this._teleportTargets=void 0))})}_processMutations(t){for(const n of t)this._setAttr(n.attributeName)}_resolveDef(){if(this._pendingResolve)return;for(let o=0;o<this.attributes.length;o++)this._setAttr(this.attributes[o].name);this._ob=new MutationObserver(this._processMutations.bind(this)),this._ob.observe(this,{attributes:!0});const t=(o,s=!1)=>{this._resolved=!0,this._pendingResolve=void 0;const{props:i,styles:r}=o;let l;if(i&&!jt(i))for(const a in i){const u=i[a];(u===Number||u&&u.type===Number)&&(a in this._props&&(this._props[a]=cm(this._props[a])),(l||(l=Object.create(null)))[_s(a)]=!0)}this._numberProps=l,this._resolveProps(o),this.shadowRoot&&this._applyStyles(r),this._mount(o)},n=this._def.__asyncLoader;n?this._pendingResolve=n().then(o=>{o.configureApp=this._def.configureApp,t(this._def=o,!0)}):t(this._def)}_mount(t){this._app=this._createApp(t),this._inheritParentContext(),t.configureApp&&t.configureApp(this._app),this._app._ceVNode=this._createVNode(),this._app.mount(this._root);const n=this._instance&&this._instance.exposed;if(n)for(const o in n)Kn(this,o)||Object.defineProperty(this,o,{get:()=>p(n[o])})}_resolveProps(t){const{props:n}=t,o=jt(n)?n:Object.keys(n||{});for(const s of Object.keys(this))s[0]!=="_"&&o.includes(s)&&this._setProp(s,this[s]);for(const s of o.map(_s))Object.defineProperty(this,s,{get(){return this._getProp(s)},set(i){this._setProp(s,i,!0,!this._patching)}})}_setAttr(t){if(t.startsWith("data-v-"))return;const n=this.hasAttribute(t);let o=n?this.getAttribute(t):X7;const s=_s(t);n&&this._numberProps&&this._numberProps[s]&&(o=cm(o)),this._setProp(s,o,!1,!0)}_getProp(t){return this._props[t]}_setProp(t,n,o=!0,s=!1){if(n!==this._props[t]&&(this._dirty=!0,n===X7?delete this._props[t]:(this._props[t]=n,t==="key"&&this._app&&(this._app._ceVNode.key=n)),s&&this._instance&&this._update(),o)){const i=this._ob;i&&(this._processMutations(i.takeRecords()),i.disconnect()),n===!0?this.setAttribute(Bi(t),""):typeof n=="string"||typeof n=="number"?this.setAttribute(Bi(t),n+""):n||this.removeAttribute(Bi(t)),i&&i.observe(this,{attributes:!0})}}_update(){const t=this._createVNode();this._app&&(t.appContext=this._app._context),cD(t,this._root)}_createVNode(){const t={};this.shadowRoot||(t.onVnodeMounted=t.onVnodeUpdated=this._renderSlots.bind(this));const n=j(this._def,to(t,this._props));return this._instance||(n.ce=o=>{this._instance=o,o.ce=this,o.isCE=!0;const s=(i,r)=>{this.dispatchEvent(new CustomEvent(i,Hg(r[0])?to({detail:r},r[0]):{detail:r}))};o.emit=(i,...r)=>{s(i,r),Bi(i)!==i&&s(Bi(i),r)},this._setParent()}),n}_applyStyles(t,n,o){if(!t)return;if(n){if(n===this._def||this._styleChildren.has(n))return;this._styleChildren.add(n)}const s=this._nonce,i=this.shadowRoot,r=o?this._getStyleAnchor(o)||this._getStyleAnchor(this._def):this._getRootStyleInsertionAnchor(i);let l=null;for(let a=t.length-1;a>=0;a--){const u=document.createElement("style");s&&u.setAttribute("nonce",s),u.textContent=t[a],i.insertBefore(u,l||r),l=u,a===0&&(o||this._styleAnchors.set(this._def,u),n&&this._styleAnchors.set(n,u))}}_getStyleAnchor(t){if(!t)return null;const n=this._styleAnchors.get(t);return n&&n.parentNode===this.shadowRoot?n:(n&&this._styleAnchors.delete(t),null)}_getRootStyleInsertionAnchor(t){for(let n=0;n<t.childNodes.length;n++){const o=t.childNodes[n];if(!(o instanceof HTMLStyleElement))return o}return null}_parseSlots(){const t=this._slots={};let n;for(;n=this.firstChild;){const o=n.nodeType===1&&n.getAttribute("slot")||"default";(t[o]||(t[o]=[])).push(n),this.removeChild(n)}}_renderSlots(){const t=this._getSlots(),n=this._instance.type.__scopeId;for(let o=0;o<t.length;o++){const s=t[o],i=s.getAttribute("name")||"default",r=this._slots[i],l=s.parentNode;if(r)for(const a of r){if(n&&a.nodeType===1){const u=n+"-s",c=document.createTreeWalker(a,1);a.setAttribute(u,"");let d;for(;d=c.nextNode();)d.setAttribute(u,"")}l.insertBefore(a,s)}else for(;s.firstChild;)l.insertBefore(s.firstChild,s);l.removeChild(s)}}_getSlots(){const t=[this];this._teleportTargets&&t.push(...this._teleportTargets);const n=new Set;for(const o of t){const s=o.querySelectorAll("slot");for(let i=0;i<s.length;i++)n.add(s[i])}return Array.from(n)}_injectChildStyle(t,n){this._applyStyles(t.styles,t,n)}_beginPatch(){this._patching=!0,this._dirty=!1}_endPatch(){this._patching=!1,this._dirty&&this._instance&&this._update()}_hasShadowRoot(){return this._def.shadowRoot!==!1}_removeChildStyle(t){}}function XP(e){const t=ds(),n=t&&t.ce;return n||null}function vVe(){const e=XP();return e&&e.shadowRoot}function yVe(e="$style"){{const t=ds();if(!t)return An;const n=t.type.__cssModules;if(!n)return An;const o=n[e];return o||An}}const ZA=new WeakMap,GA=new WeakMap,Tm=Symbol("_moveCb"),J7=Symbol("_enterCb"),JP=e=>(delete e.props.mode,e),QP=JP({name:"TransitionGroup",props:to({},jA,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=ds(),o=sA();let s,i;return Dp(()=>{if(!s.length)return;const r=e.moveClass||`${e.name||"v"}-move`;if(!oD(s[0].el,n.vnode.el,r)){s=[];return}s.forEach(eD),s.forEach(tD);const l=s.filter(nD);U4(n.vnode.el),l.forEach(a=>{const u=a.el,c=u.style;dl(u,r),c.transform=c.webkitTransform=c.transitionDuration="";const d=u[Tm]=f=>{f&&f.target!==u||(!f||f.propertyName.endsWith("transform"))&&(u.removeEventListener("transitionend",d),u[Tm]=null,Ma(u,r))};u.addEventListener("transitionend",d)}),s=[]}),()=>{const r=Pn(e),l=VA(r);let a=r.tag||Pe;if(s=[],i)for(let u=0;u<i.length;u++){const c=i[u];c.el&&c.el instanceof Element&&!c.el[q8]&&(s.push(c),Za(c,up(c,l,o,n)),ZA.set(c,XA(c.el)))}i=t.default?O8(t.default()):[];for(let u=0;u<i.length;u++){const c=i[u];c.key!=null&&Za(c,up(c,l,o,n))}return j(a,null,i)}}}),YA=QP;function eD(e){const t=e.el;t[Tm]&&t[Tm](),t[J7]&&t[J7]()}function tD(e){GA.set(e,XA(e.el))}function nD(e){const t=ZA.get(e),n=GA.get(e),o=t.left-n.left,s=t.top-n.top;if(o||s){const i=e.el,r=i.style,l=i.getBoundingClientRect();let a=1,u=1;return i.offsetWidth&&(a=l.width/i.offsetWidth),i.offsetHeight&&(u=l.height/i.offsetHeight),(!Number.isFinite(a)||a===0)&&(a=1),(!Number.isFinite(u)||u===0)&&(u=1),Math.abs(a-1)<.01&&(a=1),Math.abs(u-1)<.01&&(u=1),r.transform=r.webkitTransform=`translate(${o/a}px,${s/u}px)`,r.transitionDuration="0s",e}}function XA(e){const t=e.getBoundingClientRect();return{left:t.left,top:t.top}}function oD(e,t,n){const o=e.cloneNode(),s=e[Jd];s&&s.forEach(l=>{l.split(/\s+/).forEach(a=>a&&o.classList.remove(a))}),n.split(/\s+/).forEach(l=>l&&o.classList.add(l)),o.style.display="none";const i=t.nodeType===1?t:t.parentNode;i.appendChild(o);const{hasTransform:r}=qA(o);return i.removeChild(o),r}const Ya=e=>{const t=e.props["onUpdate:modelValue"]||!1;return jt(t)?n=>$d(t,n):t};function sD(e){e.target.composing=!0}function Q7(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const _r=Symbol("_assign");function ek(e,t,n){return t&&(e=e.trim()),n&&(e=jg(e)),e}const ai={created(e,{modifiers:{lazy:t,trim:n,number:o}},s){e[_r]=Ya(s);const i=o||s.props&&s.props.type==="number";Yl(e,t?"change":"input",r=>{r.target.composing||e[_r](ek(e.value,n,i))}),(n||i)&&Yl(e,"change",()=>{e.value=ek(e.value,n,i)}),t||(Yl(e,"compositionstart",sD),Yl(e,"compositionend",Q7),Yl(e,"change",Q7))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:o,trim:s,number:i}},r){if(e[_r]=Ya(r),e.composing)return;const l=(i||e.type==="number")&&!/^0\d/.test(e.value)?jg(e.value):e.value,a=t??"";if(l===a)return;const u=e.getRootNode();(u instanceof Document||u instanceof ShadowRoot)&&u.activeElement===e&&e.type!=="range"&&(o&&t===n||s&&e.value.trim()===a)||(e.value=a)}},Em={deep:!0,created(e,t,n){e[_r]=Ya(n),Yl(e,"change",()=>{const o=e._modelValue,s=Qd(e),i=e.checked,r=e[_r];if(jt(o)){const l=qg(o,s),a=l!==-1;if(i&&!a)r(o.concat(s));else if(!i&&a){const u=[...o];u.splice(l,1),r(u)}}else if(Ac(o)){const l=new Set(o);i?l.add(s):l.delete(s),r(l)}else r(QA(e,i))})},mounted:tk,beforeUpdate(e,t,n){e[_r]=Ya(n),tk(e,t,n)}};function tk(e,{value:t,oldValue:n},o){e._modelValue=t;let s;if(jt(t))s=qg(t,o.props.value)>-1;else if(Ac(t))s=t.has(o.props.value);else{if(t===n)return;s=sa(t,QA(e,!0))}e.checked!==s&&(e.checked=s)}const JA={created(e,{value:t},n){e.checked=sa(t,n.props.value),e[_r]=Ya(n),Yl(e,"change",()=>{e[_r](Qd(e))})},beforeUpdate(e,{value:t,oldValue:n},o){e[_r]=Ya(o),t!==n&&(e.checked=sa(t,o.props.value))}},V4={deep:!0,created(e,{value:t,modifiers:{number:n}},o){const s=Ac(t);Yl(e,"change",()=>{const i=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>n?jg(Qd(r)):Qd(r));e[_r](e.multiple?s?new Set(i):i:i[0]),e._assigning=!0,yt(()=>{e._assigning=!1})}),e[_r]=Ya(o)},mounted(e,{value:t}){nk(e,t)},beforeUpdate(e,t,n){e[_r]=Ya(n)},updated(e,{value:t}){e._assigning||nk(e,t)}};function nk(e,t){const n=e.multiple,o=jt(t);if(!(n&&!o&&!Ac(t))){for(let s=0,i=e.options.length;s<i;s++){const r=e.options[s],l=Qd(r);if(n)if(o){const a=typeof l;a==="string"||a==="number"?r.selected=t.some(u=>String(u)===String(l)):r.selected=qg(t,l)>-1}else r.selected=t.has(l);else if(sa(Qd(r),t)){e.selectedIndex!==s&&(e.selectedIndex=s);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Qd(e){return"_value"in e?e._value:e.value}function QA(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const iD={created(e,t,n){V0(e,t,n,null,"created")},mounted(e,t,n){V0(e,t,n,null,"mounted")},beforeUpdate(e,t,n,o){V0(e,t,n,o,"beforeUpdate")},updated(e,t,n,o){V0(e,t,n,o,"updated")}};function eM(e,t){switch(e){case"SELECT":return V4;case"TEXTAREA":return ai;default:switch(t){case"checkbox":return Em;case"radio":return JA;default:return ai}}}function V0(e,t,n,o,s){const r=eM(e.tagName,n.props&&n.props.type)[s];r&&r(e,t,n,o)}function rD(){ai.getSSRProps=({value:e})=>({value:e}),JA.getSSRProps=({value:e},t)=>{if(t.props&&sa(t.props.value,e))return{checked:!0}},Em.getSSRProps=({value:e},t)=>{if(jt(e)){if(t.props&&qg(e,t.props.value)>-1)return{checked:!0}}else if(Ac(e)){if(t.props&&e.has(t.props.value))return{checked:!0}}else if(e)return{checked:!0}},iD.getSSRProps=(e,t)=>{if(typeof t.type!="string")return;const n=eM(t.type.toUpperCase(),t.props&&t.props.type);if(n.getSSRProps)return n.getSSRProps(e,t)}}const lD=["ctrl","shift","alt","meta"],aD={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>lD.some(n=>e[`${n}Key`]&&!t.includes(n))},It=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),o=t.join(".");return n[o]||(n[o]=((s,...i)=>{for(let r=0;r<t.length;r++){const l=aD[t[r]];if(l&&l(s,t))return}return e(s,...i)}))},uD={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},xl=(e,t)=>{const n=e._withKeys||(e._withKeys={}),o=t.join(".");return n[o]||(n[o]=(s=>{if(!("key"in s))return;const i=Bi(s.key);if(t.some(r=>r===i||uD[r]===i))return e(s)}))},tM=to({patchProp:qP},TP);let Of,ok=!1;function nM(){return Of||(Of=aP(tM))}function oM(){return Of=ok?Of:uP(tM),ok=!0,Of}const cD=((...e)=>{nM().render(...e)}),kVe=((...e)=>{oM().hydrate(...e)}),Im=((...e)=>{const t=nM().createApp(...e),{mount:n}=t;return t.mount=o=>{const s=iM(o);if(!s)return;const i=t._component;!un(i)&&!i.render&&!i.template&&(i.template=s.innerHTML),s.nodeType===1&&(s.textContent="");const r=n(s,!1,sM(s));return s instanceof Element&&(s.removeAttribute("v-cloak"),s.setAttribute("data-v-app","")),r},t}),dD=((...e)=>{const t=oM().createApp(...e),{mount:n}=t;return t.mount=o=>{const s=iM(o);if(s)return n(s,!0,sM(s))},t});function sM(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function iM(e){return ro(e)?document.querySelector(e):e}let sk=!1;const bVe=()=>{sk||(sk=!0,rD(),NP())};/*! + * shared v11.4.6 + * (c) 2026 kazuya kawaguchi + * Released under the MIT License. + */function fD(e,t){typeof console<"u"&&(console.warn("[intlify] "+e),t&&console.warn(t.stack))}const Lm=typeof window<"u",ru=(e,t=!1)=>t?Symbol.for(e):Symbol(e),pD=(e,t,n)=>hD({l:e,k:t,s:n}),hD=e=>JSON.stringify(e).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),ls=e=>typeof e=="number"&&isFinite(e),rM=e=>G8(e)==="[object Date]",e1=e=>G8(e)==="[object RegExp]",o2=e=>$n(e)&&Object.keys(e).length===0,us=Object.assign,mD=Object.create,io=(e=null)=>mD(e);let ik;const Xu=()=>ik||(ik=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:io());function rk(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/").replace(/=/g,"=")}function gD(e){return e.replace(/&(?![a-zA-Z0-9#]{2,6};)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}const vD=/^\s*javascript\s*(?::|�*58;?|�*3a;?|:?)/i,yD=/^(?:href|src|action|formaction)$/i;function Z8(e){return vD.test(e)}function kD(e){const t=/url\s*\(/gi;let n="",o=0,s;for(;(s=t.exec(e))!==null;){const i=s.index,r=t.lastIndex-1;let l=r+1,a=1,u=null;for(;l<e.length;l++){const f=e[l];if(u){f===u&&(u=null);continue}if(f==='"'||f==="'")u=f;else if(f==="(")a++;else if(f===")"&&(a--,a===0))break}if(a!==0)break;const c=e.slice(r+1,l).trim(),d=c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'")?c.slice(1,-1).trim():c;n+=e.slice(o,i),n+=Z8(d)?"url(about:blank)":e.slice(i,l+1),o=l+1}return n+e.slice(o)}function lk(e,t){if(yD.test(e)&&Z8(t))return"about:blank";const n=e.toLowerCase()==="style"?kD(t):t;return gD(n)}function bD(e){return e=e.replace(/([\w:-]+)\s*=\s*"([^"]*)"/g,(n,o,s)=>`${o}="${lk(o,s)}"`),e=e.replace(/([\w:-]+)\s*=\s*'([^']*)'/g,(n,o,s)=>`${o}='${lk(o,s)}'`),/\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi.test(e)&&(e=e.replace(/(\s+)(on)(\w+\s*=)/gi,"$1on$3")),e=e.replace(/(\s+(?:href|src|action|formaction)\s*=\s*)([^\s"'=<>`]+)/gi,(n,o,s)=>Z8(s)?`${o}about:blank`:n),e}const CD=Object.prototype.hasOwnProperty;function br(e,t){return CD.call(e,t)}const Uo=Array.isArray,xo=e=>typeof e=="function",zt=e=>typeof e=="string",Un=e=>typeof e=="boolean",qn=e=>e!==null&&typeof e=="object",wD=e=>qn(e)&&xo(e.then)&&xo(e.catch),lM=Object.prototype.toString,G8=e=>lM.call(e),$n=e=>G8(e)==="[object Object]",_D=e=>e==null?"":Uo(e)||$n(e)&&e.toString===lM?JSON.stringify(e,null,2):String(e);function Y8(e,t=""){return e.reduce((n,o,s)=>s===0?n+o:n+t+o,"")}const q0=e=>!qn(e)||Uo(e);function Bh(e,t){if(q0(e)||q0(t))throw new Error("Invalid value");const n=[{src:e,des:t}];for(;n.length;){const{src:o,des:s}=n.pop();Object.keys(o).forEach(i=>{i!=="__proto__"&&(qn(o[i])&&!qn(s[i])&&(s[i]=Array.isArray(o[i])?[]:io()),q0(s[i])||q0(o[i])?s[i]=o[i]:n.push({src:o[i],des:s[i]}))})}}/*! + * message-compiler v11.4.6 + * (c) 2026 kazuya kawaguchi + * Released under the MIT License. + */function xD(e,t,n){return{line:e,column:t,offset:n}}function q4(e,t,n){return{start:e,end:t}}const Xn={EXPECTED_TOKEN:1,INVALID_TOKEN_IN_PLACEHOLDER:2,UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER:3,UNKNOWN_ESCAPE_SEQUENCE:4,INVALID_UNICODE_ESCAPE_SEQUENCE:5,UNBALANCED_CLOSING_BRACE:6,UNTERMINATED_CLOSING_BRACE:7,EMPTY_PLACEHOLDER:8,NOT_ALLOW_NEST_PLACEHOLDER:9,INVALID_LINKED_FORMAT:10,MUST_HAVE_MESSAGES_IN_PLURAL:11,UNEXPECTED_EMPTY_LINKED_MODIFIER:12,UNEXPECTED_EMPTY_LINKED_KEY:13,UNEXPECTED_LEXICAL_ANALYSIS:14},SD=17;function s2(e,t,n={}){const{domain:o,messages:s,args:i}=n,r=e,l=new SyntaxError(String(r));return l.code=e,t&&(l.location=t),l.domain=o,l}function AD(e){throw e}const rl=" ",MD="\r",ni=` +`,TD="\u2028",ED="\u2029";function ID(e){const t=e;let n=0,o=1,s=1,i=0;const r=T=>t[T]===MD&&t[T+1]===ni,l=T=>t[T]===ni,a=T=>t[T]===ED,u=T=>t[T]===TD,c=T=>r(T)||l(T)||a(T)||u(T),d=()=>n,f=()=>o,h=()=>s,m=()=>i,v=T=>r(T)||a(T)||u(T)?ni:t[T],k=()=>v(n),w=()=>v(n+i);function b(){return i=0,c(n)&&(o++,s=0),r(n)&&n++,n++,s++,t[n]}function _(){return r(n+i)&&i++,i++,t[n+i]}function g(){n=0,o=1,s=1,i=0}function x(T=0){i=T}function S(){const T=n+i;for(;T!==n;)b();i=0}return{index:d,line:f,column:h,peekOffset:m,charAt:v,currentChar:k,currentPeek:w,next:b,peek:_,reset:g,resetPeek:x,skipToPeek:S}}const zl=void 0,LD=".",ak="'",$D="tokenizer";function ND(e,t={}){const n=t.location!==!1,o=ID(e),s=()=>o.index(),i=()=>xD(o.line(),o.column(),o.index()),r=i(),l=s(),a={currentType:13,offset:l,startLoc:r,endLoc:r,lastType:13,lastOffset:l,lastStartLoc:r,lastEndLoc:r,braceNest:0,inLinked:!1,text:""},u=()=>a,{onError:c}=t;function d(Q,te,ce,...ue){const Se=u();if(te.column+=ce,te.offset+=ce,c){const ze=n?q4(Se.startLoc,te):null,_e=s2(Q,ze,{domain:$D,args:ue});c(_e)}}function f(Q,te,ce){Q.endLoc=i(),Q.currentType=te;const ue={type:te};return n&&(ue.loc=q4(Q.startLoc,Q.endLoc)),ce!=null&&(ue.value=ce),ue}const h=Q=>f(Q,13);function m(Q,te){return Q.currentChar()===te?(Q.next(),te):(d(Xn.EXPECTED_TOKEN,i(),0,te),"")}function v(Q){let te="";for(;Q.currentPeek()===rl||Q.currentPeek()===ni;)te+=Q.currentPeek(),Q.peek();return te}function k(Q){const te=v(Q);return Q.skipToPeek(),te}function w(Q){if(Q===zl)return!1;const te=Q.charCodeAt(0);return te>=97&&te<=122||te>=65&&te<=90||te===95}function b(Q){if(Q===zl)return!1;const te=Q.charCodeAt(0);return te>=48&&te<=57}function _(Q,te){const{currentType:ce}=te;if(ce!==2)return!1;v(Q);const ue=w(Q.currentPeek());return Q.resetPeek(),ue}function g(Q,te){const{currentType:ce}=te;if(ce!==2)return!1;v(Q);const ue=Q.currentPeek()==="-"?Q.peek():Q.currentPeek(),Se=b(ue);return Q.resetPeek(),Se}function x(Q,te){const{currentType:ce}=te;if(ce!==2)return!1;v(Q);const ue=Q.currentPeek()===ak;return Q.resetPeek(),ue}function S(Q,te){const{currentType:ce}=te;if(ce!==7)return!1;v(Q);const ue=Q.currentPeek()===".";return Q.resetPeek(),ue}function T(Q,te){const{currentType:ce}=te;if(ce!==8)return!1;v(Q);const ue=w(Q.currentPeek());return Q.resetPeek(),ue}function A(Q,te){const{currentType:ce}=te;if(!(ce===7||ce===11))return!1;v(Q);const ue=Q.currentPeek()===":";return Q.resetPeek(),ue}function E(Q,te){const{currentType:ce}=te;if(ce!==9)return!1;const ue=()=>{const ze=Q.currentPeek();return ze==="{"?w(Q.peek()):ze==="@"||ze==="|"||ze===":"||ze==="."||ze===rl||!ze?!1:ze===ni?(Q.peek(),ue()):D(Q,!1)},Se=ue();return Q.resetPeek(),Se}function P(Q){v(Q);const te=Q.currentPeek()==="|";return Q.resetPeek(),te}function D(Q,te=!0){const ce=(Se=!1,ze="")=>{const _e=Q.currentPeek();return _e==="{"||_e==="@"||!_e?Se:_e==="|"?!(ze===rl||ze===ni):_e===rl?(Q.peek(),ce(!0,rl)):_e===ni?(Q.peek(),ce(!0,ni)):!0},ue=ce();return te&&Q.resetPeek(),ue}function I(Q,te){const ce=Q.currentChar();return ce===zl?zl:te(ce)?(Q.next(),ce):null}function $(Q){const te=Q.charCodeAt(0);return te>=97&&te<=122||te>=65&&te<=90||te>=48&&te<=57||te===95||te===36}function B(Q){return I(Q,$)}function H(Q){const te=Q.charCodeAt(0);return te>=97&&te<=122||te>=65&&te<=90||te>=48&&te<=57||te===95||te===36||te===45}function O(Q){return I(Q,H)}function F(Q){const te=Q.charCodeAt(0);return te>=48&&te<=57}function U(Q){return I(Q,F)}function z(Q){const te=Q.charCodeAt(0);return te>=48&&te<=57||te>=65&&te<=70||te>=97&&te<=102}function W(Q){return I(Q,z)}function K(Q){let te="",ce="";for(;te=U(Q);)ce+=te;return ce}function V(Q){let te="";for(;;){const ce=Q.currentChar();if(ce==="\\"){const ue=Q.peek();ue==="{"||ue==="}"||ue==="@"||ue==="|"||ue==="\\"?(te+=ce+ue,Q.next(),Q.next()):(Q.resetPeek(),te+=ce,Q.next())}else{if(ce==="{"||ce==="}"||ce==="@"||ce==="|"||!ce)break;if(ce===rl||ce===ni)if(D(Q))te+=ce,Q.next();else{if(P(Q))break;te+=ce,Q.next()}else te+=ce,Q.next()}}return te}function ie(Q){k(Q);let te="",ce="";for(;te=O(Q);)ce+=te;const ue=Q.currentChar();if(ue&&ue!=="}"&&ue!==zl&&ue!==rl&&ue!==ni&&ue!==" "){const Se=ve(Q);return d(Xn.INVALID_TOKEN_IN_PLACEHOLDER,i(),0,ce+Se),ce+Se}return Q.currentChar()===zl&&d(Xn.UNTERMINATED_CLOSING_BRACE,i(),0),ce}function ne(Q){k(Q);let te="";return Q.currentChar()==="-"?(Q.next(),te+=`-${K(Q)}`):te+=K(Q),Q.currentChar()===zl&&d(Xn.UNTERMINATED_CLOSING_BRACE,i(),0),te}function X(Q){return Q!==ak&&Q!==ni}function le(Q){k(Q),m(Q,"'");let te="",ce="";for(;te=I(Q,X);)te==="\\"?ce+=Ie(Q):ce+=te;const ue=Q.currentChar();return ue===ni||ue===zl?(d(Xn.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER,i(),0),ue===ni&&(Q.next(),m(Q,"'")),ce):(m(Q,"'"),ce)}function Ie(Q){const te=Q.currentChar();switch(te){case"\\":case"'":return Q.next(),`\\${te}`;case"u":return de(Q,te,4);case"U":return de(Q,te,6);default:return d(Xn.UNKNOWN_ESCAPE_SEQUENCE,i(),0,te),""}}function de(Q,te,ce){m(Q,te);let ue="";for(let Se=0;Se<ce;Se++){const ze=W(Q);if(!ze){d(Xn.INVALID_UNICODE_ESCAPE_SEQUENCE,i(),0,`\\${te}${ue}${Q.currentChar()}`);break}ue+=ze}return`\\${te}${ue}`}function pe(Q){return Q!=="{"&&Q!=="}"&&Q!==rl&&Q!==ni}function ve(Q){k(Q);let te="",ce="";for(;te=I(Q,pe);)ce+=te;return ce}function oe(Q){let te="",ce="";for(;te=B(Q);)ce+=te;return ce}function ye(Q){const te=ce=>{const ue=Q.currentChar();return ue==="{"||ue==="@"||ue==="|"||ue==="("||ue===")"||!ue||ue===rl?ce:(ce+=ue,Q.next(),te(ce))};return te("")}function G(Q){k(Q);const te=m(Q,"|");return k(Q),te}function Y(Q,te){let ce=null;switch(Q.currentChar()){case"{":return te.braceNest>=1&&d(Xn.NOT_ALLOW_NEST_PLACEHOLDER,i(),0),Q.next(),ce=f(te,2,"{"),k(Q),te.braceNest++,ce;case"}":return te.braceNest>0&&te.currentType===2&&d(Xn.EMPTY_PLACEHOLDER,i(),0),Q.next(),ce=f(te,3,"}"),te.braceNest--,te.braceNest>0&&k(Q),te.inLinked&&te.braceNest===0&&(te.inLinked=!1),ce;case"@":return te.braceNest>0&&d(Xn.UNTERMINATED_CLOSING_BRACE,i(),0),ce=fe(Q,te)||h(te),te.braceNest=0,ce;default:{let Se=!0,ze=!0,_e=!0;if(P(Q))return te.braceNest>0&&d(Xn.UNTERMINATED_CLOSING_BRACE,i(),0),ce=f(te,1,G(Q)),te.braceNest=0,te.inLinked=!1,ce;if(te.braceNest>0&&(te.currentType===4||te.currentType===5||te.currentType===6))return d(Xn.UNTERMINATED_CLOSING_BRACE,i(),0),te.braceNest=0,we(Q,te);if(Se=_(Q,te))return ce=f(te,4,ie(Q)),k(Q),ce;if(ze=g(Q,te))return ce=f(te,5,ne(Q)),k(Q),ce;if(_e=x(Q,te))return ce=f(te,6,le(Q)),k(Q),ce;if(!Se&&!ze&&!_e)return ce=f(te,12,ve(Q)),d(Xn.INVALID_TOKEN_IN_PLACEHOLDER,i(),0,ce.value),k(Q),ce;break}}return ce}function fe(Q,te){const{currentType:ce}=te;let ue=null;const Se=Q.currentChar();switch((ce===7||ce===8||ce===11||ce===9)&&(Se===ni||Se===rl)&&d(Xn.INVALID_LINKED_FORMAT,i(),0),Se){case"@":return Q.next(),ue=f(te,7,"@"),te.inLinked=!0,ue;case".":return k(Q),Q.next(),f(te,8,".");case":":return k(Q),Q.next(),f(te,9,":");default:return P(Q)?(ue=f(te,1,G(Q)),te.braceNest=0,te.inLinked=!1,ue):S(Q,te)||A(Q,te)?(k(Q),fe(Q,te)):T(Q,te)?(k(Q),f(te,11,oe(Q))):E(Q,te)?(k(Q),Se==="{"?Y(Q,te)||ue:f(te,10,ye(Q))):(ce===7&&d(Xn.INVALID_LINKED_FORMAT,i(),0),te.braceNest=0,te.inLinked=!1,we(Q,te))}}function we(Q,te){let ce={type:13};if(te.braceNest>0)return Y(Q,te)||h(te);if(te.inLinked)return fe(Q,te)||h(te);switch(Q.currentChar()){case"{":return Y(Q,te)||h(te);case"}":return d(Xn.UNBALANCED_CLOSING_BRACE,i(),0),Q.next(),f(te,3,"}");case"@":return fe(Q,te)||h(te);default:{if(P(Q))return ce=f(te,1,G(Q)),te.braceNest=0,te.inLinked=!1,ce;if(D(Q))return f(te,0,V(Q));break}}return ce}function ge(){const{currentType:Q,offset:te,startLoc:ce,endLoc:ue}=a;return a.lastType=Q,a.lastOffset=te,a.lastStartLoc=ce,a.lastEndLoc=ue,a.offset=s(),a.startLoc=i(),o.currentChar()===zl?f(a,13):we(o,a)}return{nextToken:ge,currentOffset:s,currentPosition:i,context:u}}const FD="parser",RD=/(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g,OD=/\\([\\@{}|])/g;function PD(e,t){return t}function DD(e,t,n){switch(e){case"\\\\":return"\\";case"\\'":return"'";default:{const o=parseInt(t||n,16);return o<=55295||o>=57344?String.fromCodePoint(o):"�"}}}function BD(e={}){const t=e.location!==!1,{onError:n}=e;function o(w,b,_,g,...x){const S=w.currentPosition();if(S.offset+=g,S.column+=g,n){const T=t?q4(_,S):null,A=s2(b,T,{domain:FD,args:x});n(A)}}function s(w,b,_){const g={type:w};return t&&(g.start=b,g.end=b,g.loc={start:_,end:_}),g}function i(w,b,_,g){t&&(w.end=b,w.loc&&(w.loc.end=_))}function r(w,b){const _=w.context(),g=s(3,_.offset,_.startLoc);return g.value=b.replace(OD,PD),i(g,w.currentOffset(),w.currentPosition()),g}function l(w,b){const _=w.context(),{lastOffset:g,lastStartLoc:x}=_,S=s(5,g,x);return S.index=parseInt(b,10),w.nextToken(),i(S,w.currentOffset(),w.currentPosition()),S}function a(w,b){const _=w.context(),{lastOffset:g,lastStartLoc:x}=_,S=s(4,g,x);return S.key=b,w.nextToken(),i(S,w.currentOffset(),w.currentPosition()),S}function u(w,b){const _=w.context(),{lastOffset:g,lastStartLoc:x}=_,S=s(9,g,x);return S.value=b.replace(RD,DD),w.nextToken(),i(S,w.currentOffset(),w.currentPosition()),S}function c(w){const b=w.nextToken(),_=w.context(),{lastOffset:g,lastStartLoc:x}=_,S=s(8,g,x);return b.type!==11?(o(w,Xn.UNEXPECTED_EMPTY_LINKED_MODIFIER,_.lastStartLoc,0),S.value="",i(S,g,x),{nextConsumeToken:b,node:S}):(b.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,_.lastStartLoc,0,ll(b)),S.value=b.value||"",i(S,w.currentOffset(),w.currentPosition()),{node:S})}function d(w,b){const _=w.context(),g=s(7,_.offset,_.startLoc);return g.value=b,i(g,w.currentOffset(),w.currentPosition()),g}function f(w){const b=w.context(),_=s(6,b.offset,b.startLoc);let g=w.nextToken();if(g.type===8){const x=c(w);_.modifier=x.node,g=x.nextConsumeToken||w.nextToken()}switch(g.type!==9&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(g)),g=w.nextToken(),g.type===2&&(g=w.nextToken()),g.type){case 10:g.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(g)),_.key=d(w,g.value||"");break;case 4:g.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(g)),_.key=a(w,g.value||"");break;case 5:g.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(g)),_.key=l(w,g.value||"");break;case 6:g.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(g)),_.key=u(w,g.value||"");break;default:{o(w,Xn.UNEXPECTED_EMPTY_LINKED_KEY,b.lastStartLoc,0);const x=w.context(),S=s(7,x.offset,x.startLoc);return S.value="",i(S,x.offset,x.startLoc),_.key=S,i(_,x.offset,x.startLoc),{nextConsumeToken:g,node:_}}}return i(_,w.currentOffset(),w.currentPosition()),{node:_}}function h(w){const b=w.context(),_=b.currentType===1?w.currentOffset():b.offset,g=b.currentType===1?b.endLoc:b.startLoc,x=s(2,_,g);x.items=[];let S=null;do{const E=S||w.nextToken();switch(S=null,E.type){case 0:E.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(E)),x.items.push(r(w,E.value||""));break;case 5:E.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(E)),x.items.push(l(w,E.value||""));break;case 4:E.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(E)),x.items.push(a(w,E.value||""));break;case 6:E.value==null&&o(w,Xn.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,ll(E)),x.items.push(u(w,E.value||""));break;case 7:{const P=f(w);x.items.push(P.node),S=P.nextConsumeToken||null;break}}}while(b.currentType!==13&&b.currentType!==1);const T=b.currentType===1?b.lastOffset:w.currentOffset(),A=b.currentType===1?b.lastEndLoc:w.currentPosition();return i(x,T,A),x}function m(w,b,_,g){const x=w.context();let S=g.items.length===0;const T=s(1,b,_);T.cases=[],T.cases.push(g);do{const A=h(w);S||(S=A.items.length===0),T.cases.push(A)}while(x.currentType!==13);return S&&o(w,Xn.MUST_HAVE_MESSAGES_IN_PLURAL,_,0),i(T,w.currentOffset(),w.currentPosition()),T}function v(w){const b=w.context(),{offset:_,startLoc:g}=b,x=h(w);return b.currentType===13?x:m(w,_,g,x)}function k(w){const b=ND(w,us({},e)),_=b.context(),g=s(0,_.offset,_.startLoc);return t&&g.loc&&(g.loc.source=w),g.body=v(b),e.onCacheKey&&(g.cacheKey=e.onCacheKey(w)),_.currentType!==13&&o(b,Xn.UNEXPECTED_LEXICAL_ANALYSIS,_.lastStartLoc,0,w[_.offset]||""),i(g,b.currentOffset(),b.currentPosition()),g}return{parse:k}}function ll(e){if(e.type===13)return"EOF";const t=(e.value||"").replace(/\r?\n/gu,"\\n");return t.length>10?t.slice(0,9)+"…":t}function HD(e,t={}){const n={ast:e,helpers:new Set};return{context:()=>n,helper:i=>(n.helpers.add(i),i)}}function uk(e,t){for(let n=0;n<e.length;n++)X8(e[n],t)}function X8(e,t){switch(e.type){case 1:uk(e.cases,t),t.helper("plural");break;case 2:uk(e.items,t);break;case 6:{X8(e.key,t),t.helper("linked"),t.helper("type");break}case 5:t.helper("interpolate"),t.helper("list");break;case 4:t.helper("interpolate"),t.helper("named");break}}function zD(e,t={}){const n=HD(e);n.helper("normalize"),e.body&&X8(e.body,n);const o=n.context();e.helpers=Array.from(o.helpers)}function WD(e){const t=e.body;return t.type===2?ck(t):t.cases.forEach(n=>ck(n)),e}function ck(e){if(e.items.length===1){const t=e.items[0];(t.type===3||t.type===9)&&(e.static=t.value,delete t.value)}else{const t=[];for(let n=0;n<e.items.length;n++){const o=e.items[n];if(!(o.type===3||o.type===9)||o.value==null)break;t.push(o.value)}if(t.length===e.items.length){e.static=Y8(t);for(let n=0;n<e.items.length;n++){const o=e.items[n];(o.type===3||o.type===9)&&delete o.value}}}}function pd(e){switch(e.t=e.type,e.type){case 0:{const t=e;pd(t.body),t.b=t.body,delete t.body;break}case 1:{const t=e,n=t.cases;for(let o=0;o<n.length;o++)pd(n[o]);t.c=n,delete t.cases;break}case 2:{const t=e,n=t.items;for(let o=0;o<n.length;o++)pd(n[o]);t.i=n,delete t.items,t.static&&(t.s=t.static,delete t.static);break}case 3:case 9:case 8:case 7:{const t=e;t.value&&(t.v=t.value,delete t.value);break}case 6:{const t=e;pd(t.key),t.k=t.key,delete t.key,t.modifier&&(pd(t.modifier),t.m=t.modifier,delete t.modifier);break}case 5:{const t=e;t.i=t.index,delete t.index;break}case 4:{const t=e;t.k=t.key,delete t.key;break}}delete e.type}function UD(e,t){const{filename:n,breakLineCode:o,needIndent:s}=t,i=t.location!==!1,r={filename:n,code:"",column:1,line:1,offset:0,map:void 0,breakLineCode:o,needIndent:s,indentLevel:0};i&&e.loc&&(r.source=e.loc.source);const l=()=>r;function a(v,k){r.code+=v}function u(v,k=!0){const w=k?o:"";a(s?w+" ".repeat(v):w)}function c(v=!0){const k=++r.indentLevel;v&&u(k)}function d(v=!0){const k=--r.indentLevel;v&&u(k)}function f(){u(r.indentLevel)}return{context:l,push:a,indent:c,deindent:d,newline:f,helper:v=>`_${v}`,needIndent:()=>r.needIndent}}function jD(e,t){const{helper:n}=e;e.push(`${n("linked")}(`),t1(e,t.key),t.modifier?(e.push(", "),t1(e,t.modifier),e.push(", _type")):e.push(", undefined, _type"),e.push(")")}function VD(e,t){const{helper:n,needIndent:o}=e;e.push(`${n("normalize")}([`),e.indent(o());const s=t.items.length;for(let i=0;i<s&&(t1(e,t.items[i]),i!==s-1);i++)e.push(", ");e.deindent(o()),e.push("])")}function qD(e,t){const{helper:n,needIndent:o}=e;if(t.cases.length>1){e.push(`${n("plural")}([`),e.indent(o());const s=t.cases.length;for(let i=0;i<s&&(t1(e,t.cases[i]),i!==s-1);i++)e.push(", ");e.deindent(o()),e.push("])")}}function KD(e,t){t.body?t1(e,t.body):e.push("null")}function t1(e,t){const{helper:n}=e;switch(t.type){case 0:KD(e,t);break;case 1:qD(e,t);break;case 2:VD(e,t);break;case 6:jD(e,t);break;case 8:e.push(JSON.stringify(t.value),t);break;case 7:e.push(JSON.stringify(t.value),t);break;case 5:e.push(`${n("interpolate")}(${n("list")}(${t.index}))`,t);break;case 4:e.push(`${n("interpolate")}(${n("named")}(${JSON.stringify(t.key)}))`,t);break;case 9:e.push(JSON.stringify(t.value),t);break;case 3:e.push(JSON.stringify(t.value),t);break}}const ZD=(e,t={})=>{const n=zt(t.mode)?t.mode:"normal",o=zt(t.filename)?t.filename:"message.intl";t.sourceMap;const s=t.breakLineCode!=null?t.breakLineCode:n==="arrow"?";":` +`,i=t.needIndent?t.needIndent:n!=="arrow",r=e.helpers||[],l=UD(e,{filename:o,breakLineCode:s,needIndent:i});l.push(n==="normal"?"function __msg__ (ctx) {":"(ctx) => {"),l.indent(i),r.length>0&&(l.push(`const { ${Y8(r.map(c=>`${c}: _${c}`),", ")} } = ctx`),l.newline()),l.push("return "),t1(l,e),l.deindent(i),l.push("}"),delete e.helpers;const{code:a,map:u}=l.context();return{ast:e,code:a,map:u?u.toJSON():void 0}};function GD(e,t={}){const n=us({},t),o=!!n.jit,s=!!n.minify,i=n.optimize==null?!0:n.optimize,l=BD(n).parse(e);return o?(i&&WD(l),s&&pd(l),{ast:l,code:""}):(zD(l,n),ZD(l,n))}/*! + * core-base v11.4.6 + * (c) 2026 kazuya kawaguchi + * Released under the MIT License. + */function YD(){typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Xu().__INTLIFY_PROD_DEVTOOLS__=!1),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Xu().__INTLIFY_DROP_MESSAGE_COMPILER__=!1)}function bl(e){return qn(e)&&J8(e)===0&&(br(e,"b")||br(e,"body"))}const aM=["b","body"];function XD(e){return lu(e,aM)}const uM=["c","cases"];function JD(e){return lu(e,uM,[])}const cM=["s","static"];function QD(e){return lu(e,cM)}const dM=["i","items"];function eB(e){return lu(e,dM,[])}const fM=["t","type"];function J8(e){return lu(e,fM)}const pM=["v","value"];function K0(e,t){const n=lu(e,pM);if(n!=null)return n;throw pp(t)}const hM=["m","modifier"];function tB(e){return lu(e,hM)}const mM=["k","key"];function nB(e){const t=lu(e,mM);if(t)return t;throw pp(6)}function lu(e,t,n){for(let o=0;o<t.length;o++){const s=t[o];if(br(e,s)&&e[s]!=null)return e[s]}return n}const gM=[...aM,...uM,...cM,...dM,...mM,...hM,...pM,...fM];function pp(e){return new Error(`unhandled node type: ${e}`)}function Gv(e){return n=>oB(n,e)}function oB(e,t){const n=XD(t);if(n==null)throw pp(0);if(J8(n)===1){const i=JD(n);return e.plural(i.reduce((r,l)=>[...r,dk(e,l)],[]))}else return dk(e,n)}function dk(e,t){const n=QD(t);if(n!=null)return e.type==="text"?n:e.normalize([n]);{const o=eB(t).reduce((s,i)=>[...s,K4(e,i)],[]);return e.normalize(o)}}function K4(e,t){const n=J8(t);switch(n){case 3:return K0(t,n);case 9:return K0(t,n);case 4:{const o=t;if(br(o,"k")&&o.k)return e.interpolate(e.named(o.k));if(br(o,"key")&&o.key)return e.interpolate(e.named(o.key));throw pp(n)}case 5:{const o=t;if(br(o,"i")&&ls(o.i))return e.interpolate(e.list(o.i));if(br(o,"index")&&ls(o.index))return e.interpolate(e.list(o.index));throw pp(n)}case 6:{const o=t,s=tB(o),i=nB(o);return e.linked(K4(e,i),s?K4(e,s):void 0,e.type)}case 7:return K0(t,n);case 8:return K0(t,n);default:throw new Error(`unhandled node on format message part: ${n}`)}}const sB=e=>e;let Z0=io();function iB(e,t={}){let n=!1;const o=t.onError||AD;return t.onError=s=>{n=!0,o(s)},{...GD(e,t),detectError:n}}function rB(e,t){if(!__INTLIFY_DROP_MESSAGE_COMPILER__&&zt(e)){Un(t.warnHtmlMessage)&&t.warnHtmlMessage;const o=(t.onCacheKey||sB)(e),s=Z0[o];if(s)return s;const{ast:i,detectError:r}=iB(e,{...t,location:!1,jit:!0}),l=Gv(i);return r?l:Z0[o]=l}else{const n=e.cacheKey;if(n){const o=Z0[n];return o||(Z0[n]=Gv(e))}else return Gv(e)}}let hp=null;function lB(e){hp=e}function aB(e,t,n){hp&&hp.emit("i18n:init",{timestamp:Date.now(),i18n:e,version:t,meta:n})}const uB=cB("function:translate");function cB(e){return t=>hp&&hp.emit(e,t)}const Jl={INVALID_ARGUMENT:SD,INVALID_DATE_ARGUMENT:18,INVALID_ISO_DATE_ARGUMENT:19,NOT_SUPPORT_LOCALE_PROMISE_VALUE:21,NOT_SUPPORT_LOCALE_ASYNC_FUNCTION:22,NOT_SUPPORT_LOCALE_TYPE:23},dB=24;function Ql(e){return s2(e,null,void 0)}function Q8(e,t){return t.locale!=null?fk(t.locale):fk(e.locale)}let Yv;function fk(e){if(zt(e))return e;if(xo(e)){if(e.resolvedOnce&&Yv!=null)return Yv;if(e.constructor.name==="Function"){const t=e();if(wD(t))throw Ql(Jl.NOT_SUPPORT_LOCALE_PROMISE_VALUE);return Yv=t}else throw Ql(Jl.NOT_SUPPORT_LOCALE_ASYNC_FUNCTION)}else throw Ql(Jl.NOT_SUPPORT_LOCALE_TYPE)}function fB(e,t,n){return[...new Set([n,...Uo(t)?t:qn(t)?Object.keys(t):zt(t)?[t]:[n]])]}function Z4(e,t,n){const o=zt(n)?n:mp,s=e;s.__localeChainCache||(s.__localeChainCache=new Map);let i=s.__localeChainCache.get(o);if(!i){i=[];let r=[n];for(;Uo(r);)r=pk(i,r,t);const l=Uo(t)||!$n(t)?t:t.default?t.default:null;r=zt(l)?[l]:l,Uo(r)&&pk(i,r,!1),s.__localeChainCache.set(o,i)}return i}function pk(e,t,n){let o=!0;for(let s=0;s<t.length&&Un(o);s++){const i=t[s];zt(i)&&(o=pB(e,t[s],n))}return o}function pB(e,t,n){let o;const s=t.split("-");do{const i=s.join("-");o=hB(e,i,n),s.splice(-1,1)}while(s.length&&o===!0);return o}function hB(e,t,n){let o=!1;if(!e.includes(t)&&(o=!0,t)){o=t[t.length-1]!=="!";const s=t.replace(/!/g,"");e.push(s),(Uo(n)||$n(n))&&n[s]&&(o=n[s])}return o}const au=[];au[0]={w:[0],i:[3,0],"[":[4],o:[7]};au[1]={w:[1],".":[2],"[":[4],o:[7]};au[2]={w:[2],i:[3,0],0:[3,0]};au[3]={i:[3,0],0:[3,0],w:[1,1],".":[2,1],"[":[4,1],o:[7,1]};au[4]={"'":[5,0],'"':[6,0],"[":[4,2],"]":[1,3],o:8,l:[4,0]};au[5]={"'":[4,0],o:8,l:[5,0]};au[6]={'"':[4,0],o:8,l:[6,0]};const mB=/^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;function gB(e){return mB.test(e)}function vB(e){const t=e.charCodeAt(0),n=e.charCodeAt(e.length-1);return t===n&&(t===34||t===39)?e.slice(1,-1):e}function yB(e){if(e==null)return"o";switch(e.charCodeAt(0)){case 91:case 93:case 46:case 34:case 39:return e;case 95:case 36:case 45:return"i";case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"w"}return"i"}function kB(e){const t=e.trim();return e.charAt(0)==="0"&&isNaN(parseInt(e))?!1:gB(t)?vB(t):"*"+t}function bB(e){const t=[];let n=-1,o=0,s=0,i,r,l,a,u,c,d;const f=[];f[0]=()=>{r===void 0?r=l:r+=l},f[1]=()=>{r!==void 0&&(t.push(r),r=void 0)},f[2]=()=>{f[0](),s++},f[3]=()=>{if(s>0)s--,o=4,f[0]();else{if(s=0,r===void 0||(r=kB(r),r===!1))return!1;f[1]()}};function h(){const m=e[n+1];if(o===5&&m==="'"||o===6&&m==='"')return n++,l="\\"+m,f[0](),!0}for(;o!==null;)if(n++,i=e[n],!(i==="\\"&&h())){if(a=yB(i),d=au[o],u=d[a]||d.l||8,u===8||(o=u[0],u[1]!==void 0&&(c=f[u[1]],c&&(l=i,c()===!1))))return;if(o===7)return t}}const hk=new Map;function CB(e,t){return qn(e)?e[t]:null}function wB(e,t){if(!qn(e))return null;let n=hk.get(t);if(n||(n=bB(t),n&&hk.set(t,n)),!n)return null;const o=n.length;let s=e,i=0;for(;i<o;){const r=n[i];if(gM.includes(r)&&bl(s)||!qn(s)||!br(s,r))return null;const l=s[r];if(l===void 0||xo(s))return null;s=l,i++}return s}const _B="11.4.6",i2=-1,mp="en-US",$m="",mk=e=>`${e.charAt(0).toLocaleUpperCase()}${e.substr(1)}`;function xB(){return{upper:(e,t)=>t==="text"&&zt(e)?e.toUpperCase():t==="vnode"&&qn(e)&&"__v_isVNode"in e?e.children.toUpperCase():e,lower:(e,t)=>t==="text"&&zt(e)?e.toLowerCase():t==="vnode"&&qn(e)&&"__v_isVNode"in e?e.children.toLowerCase():e,capitalize:(e,t)=>t==="text"&&zt(e)?mk(e):t==="vnode"&&qn(e)&&"__v_isVNode"in e?mk(e.children):e}}let vM;function SB(e){vM=e}let yM;function AB(e){yM=e}let kM;function MB(e){kM=e}let bM=null;const TB=e=>{bM=e},EB=()=>bM;let CM=null;const gk=e=>{CM=e},IB=()=>CM;let vk=0;function LB(e={}){const t=xo(e.onWarn)?e.onWarn:fD,n=zt(e.version)?e.version:_B,o=zt(e.locale)||xo(e.locale)?e.locale:mp,s=xo(o)?mp:o,i=Uo(e.fallbackLocale)||$n(e.fallbackLocale)||zt(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:s,r=$n(e.messages)?e.messages:Xv(s),l=$n(e.datetimeFormats)?e.datetimeFormats:Xv(s),a=$n(e.numberFormats)?e.numberFormats:Xv(s),u=us(io(),e.modifiers,xB()),c=e.pluralRules||io(),d=xo(e.missing)?e.missing:null,f=Un(e.missingWarn)||e1(e.missingWarn)?e.missingWarn:!0,h=Un(e.fallbackWarn)||e1(e.fallbackWarn)?e.fallbackWarn:!0,m=!!e.fallbackFormat,v=!!e.unresolving,k=xo(e.postTranslation)?e.postTranslation:null,w=$n(e.processor)?e.processor:null,b=Un(e.warnHtmlMessage)?e.warnHtmlMessage:!0,_=!!e.escapeParameter,g=xo(e.messageCompiler)?e.messageCompiler:vM,x=xo(e.messageResolver)?e.messageResolver:yM||CB,S=xo(e.localeFallbacker)?e.localeFallbacker:kM||fB,T=qn(e.fallbackContext)?e.fallbackContext:void 0,A=e,E=qn(A.__datetimeFormatters)?A.__datetimeFormatters:new Map,P=qn(A.__numberFormatters)?A.__numberFormatters:new Map,D=qn(A.__meta)?A.__meta:{};vk++;const I={version:n,cid:vk,locale:o,fallbackLocale:i,messages:r,modifiers:u,pluralRules:c,missing:d,missingWarn:f,fallbackWarn:h,fallbackFormat:m,unresolving:v,postTranslation:k,processor:w,warnHtmlMessage:b,escapeParameter:_,messageCompiler:g,messageResolver:x,localeFallbacker:S,fallbackContext:T,onWarn:t,__meta:D};return I.datetimeFormats=l,I.numberFormats=a,I.__datetimeFormatters=E,I.__numberFormatters=P,__INTLIFY_PROD_DEVTOOLS__&&aB(I,n,D),I}const Xv=e=>({[e]:io()});function ey(e,t,n,o,s){const{missing:i,onWarn:r}=e;if(i!==null){const l=i(e,n,t,s);return zt(l)?l:t}else return t}function Q1(e,t,n){const o=e;o.__localeChainCache=new Map,e.localeFallbacker(e,n,t)}function $B(e,t){return e===t?!1:e.split("-")[0]===t.split("-")[0]}function NB(e,t){const n=t.indexOf(e);if(n===-1)return!1;for(let o=n+1;o<t.length;o++)if($B(e,t[o]))return!0;return!1}function yk(e,...t){const{datetimeFormats:n,unresolving:o,fallbackLocale:s,onWarn:i,localeFallbacker:r}=e,{__datetimeFormatters:l}=e;if(!zt(t[0])&&!rM(t[0])&&!ls(t[0]))return $m;const[a,u,c,d]=G4(...t),f=Un(c.missingWarn)?c.missingWarn:e.missingWarn;Un(c.fallbackWarn)?c.fallbackWarn:e.fallbackWarn;const h=!!c.part,m=Q8(e,c),v=r(e,s,m);if(!zt(a)||a===""){const S=new Intl.DateTimeFormat(m.replace(/!/g,""),d);return h?S.formatToParts(u):S.format(u)}let k={},w,b=null;const _="datetime format";for(let S=0;S<v.length&&(w=v[S],k=n[w]||{},b=k[a],!$n(b));S++)ey(e,a,w,f,_);if(!$n(b)||!zt(w))return o?i2:a;let g=`${w}__${a}`;o2(d)||(g=`${g}__${JSON.stringify(d)}`);let x=l.get(g);return x||(x=new Intl.DateTimeFormat(w,us({},b,d)),l.set(g,x)),h?x.formatToParts(u):x.format(u)}const wM=["localeMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName","formatMatcher","hour12","timeZone","dateStyle","timeStyle","calendar","dayPeriod","numberingSystem","hourCycle","fractionalSecondDigits"];function G4(...e){const[t,n,o,s]=e,i=io();let r=io(),l;if(zt(t)){const a=t.match(/(\d{4}-\d{2}-\d{2})(T|\s)?(.*)/);if(!a)throw Ql(Jl.INVALID_ISO_DATE_ARGUMENT);const u=a[3]?a[3].trim().startsWith("T")?`${a[1].trim()}${a[3].trim()}`:`${a[1].trim()}T${a[3].trim()}`:a[1].trim();l=new Date(u);try{l.toISOString()}catch{throw Ql(Jl.INVALID_ISO_DATE_ARGUMENT)}}else if(rM(t)){if(isNaN(t.getTime()))throw Ql(Jl.INVALID_DATE_ARGUMENT);l=t}else if(ls(t))l=t;else throw Ql(Jl.INVALID_ARGUMENT);return zt(n)?i.key=n:$n(n)&&Object.keys(n).forEach(a=>{wM.includes(a)?r[a]=n[a]:i[a]=n[a]}),zt(o)?i.locale=o:$n(o)&&(r=o),$n(s)&&(r=s),[i.key||"",l,i,r]}function kk(e,t,n){const o=e;for(const s in n){const i=`${t}__${s}`;o.__datetimeFormatters.has(i)&&o.__datetimeFormatters.delete(i)}}function bk(e,...t){const{numberFormats:n,unresolving:o,fallbackLocale:s,onWarn:i,localeFallbacker:r}=e,{__numberFormatters:l}=e;if(!ls(t[0]))return $m;const[a,u,c,d]=Y4(...t),f=Un(c.missingWarn)?c.missingWarn:e.missingWarn;Un(c.fallbackWarn)?c.fallbackWarn:e.fallbackWarn;const h=!!c.part,m=Q8(e,c),v=r(e,s,m);if(!zt(a)||a===""){const S=new Intl.NumberFormat(m.replace(/!/g,""),d);return h?S.formatToParts(u):S.format(u)}let k={},w,b=null;const _="number format";for(let S=0;S<v.length&&(w=v[S],k=n[w]||{},b=k[a],!$n(b));S++)ey(e,a,w,f,_);if(!$n(b)||!zt(w))return o?i2:a;let g=`${w}__${a}`;o2(d)||(g=`${g}__${JSON.stringify(d)}`);let x=l.get(g);return x||(x=new Intl.NumberFormat(w,us({},b,d)),l.set(g,x)),h?x.formatToParts(u):x.format(u)}const _M=["localeMatcher","style","currency","currencyDisplay","currencySign","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits","compactDisplay","notation","signDisplay","unit","unitDisplay","roundingMode","roundingPriority","roundingIncrement","trailingZeroDisplay"];function Y4(...e){const[t,n,o,s]=e,i=io();let r=io();if(!ls(t))throw Ql(Jl.INVALID_ARGUMENT);const l=t;return zt(n)?i.key=n:$n(n)&&Object.keys(n).forEach(a=>{_M.includes(a)?r[a]=n[a]:i[a]=n[a]}),zt(o)?i.locale=o:$n(o)&&(r=o),$n(s)&&(r=s),[i.key||"",l,i,r]}function Ck(e,t,n){const o=e;for(const s in n){const i=`${t}__${s}`;o.__numberFormatters.has(i)&&o.__numberFormatters.delete(i)}}const FB=e=>e,RB=e=>"",OB="text",PB=e=>e.length===0?"":Y8(e),DB=_D;function Jv(e,t){return e=Math.abs(e),t===2?e===1?0:1:Math.min(e,2)}function BB(e){const t=ls(e.pluralIndex)?e.pluralIndex:-1;return ls(e.named?.count)?e.named.count:ls(e.named?.n)?e.named.n:t}function HB(e={}){const t=e.locale,n=BB(e),o=zt(t)&&xo(e.pluralRules?.[t])?e.pluralRules[t]:Jv,s=o===Jv?void 0:Jv,i=w=>w[o(n,w.length,s)],r=e.list||[],l=w=>r[w],a=e.named||io();ls(e.pluralIndex)&&(a.count||=e.pluralIndex,a.n||=e.pluralIndex);const u=w=>a[w];function c(w,b){const _=xo(e.messages)?e.messages(w,!!b):qn(e.messages)?e.messages[w]:!1;return _||(e.parent?e.parent.message(w):RB)}const d=w=>e.modifiers?e.modifiers[w]:FB,f=xo(e.processor?.normalize)?e.processor.normalize:PB,h=xo(e.processor?.interpolate)?e.processor.interpolate:DB,m=zt(e.processor?.type)?e.processor.type:OB,k={list:l,named:u,plural:i,linked:(w,...b)=>{const[_,g]=b;let x="text",S="";b.length===1?qn(_)?(S=_.modifier||S,x=_.type||x):zt(_)&&(S=_||S):b.length===2&&(zt(_)&&(S=_||S),zt(g)&&(x=g||x));const T=c(w,!0)(k),A=T===""||T===void 0?w:T,E=x==="vnode"&&Uo(A)&&S?A[0]:A;return S?d(S)(E,x):E},message:c,type:m,interpolate:h,normalize:f,values:us(io(),r,a)};return k}const wk=()=>"",kr=e=>xo(e);function _k(e,...t){const{fallbackFormat:n,postTranslation:o,unresolving:s,messageCompiler:i,fallbackLocale:r,messages:l}=e,[a,u]=X4(...t),c=Un(u.missingWarn)?u.missingWarn:e.missingWarn,d=Un(u.fallbackWarn)?u.fallbackWarn:e.fallbackWarn,f=Un(u.escapeParameter)?u.escapeParameter:e.escapeParameter,h=!!u.resolvedMessage,m=zt(u.default)||Un(u.default)?Un(u.default)?i?a:()=>a:u.default:n?i?a:()=>a:null,v=n||m!=null&&(zt(m)||xo(m)),k=Q8(e,u);f&&zB(u);let[w,b,_]=h?[a,k,l[k]||io()]:xM(e,a,k,r,d,c),g=w,x=a;if(!h&&!(zt(g)||bl(g)||kr(g))&&v&&(g=m,x=g),!h&&(!(zt(g)||bl(g)||kr(g))||!zt(b)))return s?i2:a;let S=!1;const T=()=>{S=!0},A=kr(g)?g:SM(e,a,b,g,x,T);if(S)return g;const E=jB(e,b,_,u),P=HB(E),D=WB(e,A,P);let I=o?o(D,a):D;if(f&&zt(I)&&(I=bD(I)),__INTLIFY_PROD_DEVTOOLS__){const $={timestamp:Date.now(),key:zt(a)?a:kr(g)?g.key:"",locale:b||(kr(g)?g.locale:""),format:zt(g)?g:kr(g)?g.source:"",message:I};$.meta=us({},e.__meta,EB()||{}),uB($)}return I}function zB(e){Uo(e.list)?e.list=e.list.map(t=>zt(t)?rk(t):t):qn(e.named)&&Object.keys(e.named).forEach(t=>{zt(e.named[t])&&(e.named[t]=rk(e.named[t]))})}function xM(e,t,n,o,s,i){const{messages:r,onWarn:l,messageResolver:a,localeFallbacker:u}=e,c=u(e,o,n);let d=io(),f,h=null;const m="translate";for(let v=0;v<c.length&&(f=c[v],d=r[f]||io(),(h=a(d,t))===null&&(h=d[t]),!(zt(h)||bl(h)||kr(h)));v++)if(!NB(f,c)){const k=ey(e,t,f,i,m);k!==t&&(h=k)}return[h,f,d]}function SM(e,t,n,o,s,i){const{messageCompiler:r,warnHtmlMessage:l}=e;if(kr(o)){const u=o;return u.locale=u.locale||n,u.key=u.key||t,u}if(r==null){const u=(()=>o);return u.locale=n,u.key=t,u}const a=r(o,UB(e,n,s,o,l,i));return a.locale=n,a.key=t,a.source=o,a}function WB(e,t,n){return t(n)}function X4(...e){const[t,n,o]=e,s=io();if(!zt(t)&&!ls(t)&&!kr(t)&&!bl(t))throw Ql(Jl.INVALID_ARGUMENT);const i=ls(t)?String(t):(kr(t),t);return ls(n)?s.plural=n:zt(n)?s.default=n:$n(n)&&!o2(n)?s.named=n:Uo(n)&&(s.list=n),ls(o)?s.plural=o:zt(o)?s.default=o:$n(o)&&us(s,o),[i,s]}function UB(e,t,n,o,s,i){return{locale:t,key:n,warnHtmlMessage:s,onError:r=>{throw i&&i(r),r},onCacheKey:r=>pD(t,n,r)}}function jB(e,t,n,o){const{modifiers:s,pluralRules:i,messageResolver:r,fallbackLocale:l,fallbackWarn:a,missingWarn:u,fallbackContext:c}=e,f={locale:t,modifiers:s,pluralRules:i,messages:(h,m)=>{let v=r(n,h);if(v==null&&(c||m)){const[k,,w]=xM(c||e,h,t,l,a,u);v=k??r(w,h)}if(zt(v)||bl(v)){let k=!1;const b=SM(e,h,t,v,h,()=>{k=!0});return k?wk:b}else return kr(v)?v:wk}};return e.processor&&(f.processor=e.processor),o.list&&(f.list=o.list),o.named&&(f.named=o.named),ls(o.plural)&&(f.pluralIndex=o.plural),f}YD();/*! + * vue-i18n v11.4.6 + * (c) 2026 kazuya kawaguchi + * Released under the MIT License. + */const VB="11.4.6";function qB(){typeof __VUE_I18N_FULL_INSTALL__!="boolean"&&(Xu().__VUE_I18N_FULL_INSTALL__=!0),typeof __VUE_I18N_LEGACY_API__!="boolean"&&(Xu().__VUE_I18N_LEGACY_API__=!0),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Xu().__INTLIFY_DROP_MESSAGE_COMPILER__=!1),typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Xu().__INTLIFY_PROD_DEVTOOLS__=!1)}const _i={UNEXPECTED_RETURN_TYPE:dB,INVALID_ARGUMENT:25,MUST_BE_CALL_SETUP_TOP:26,NOT_INSTALLED:27,REQUIRED_VALUE:28,INVALID_VALUE:29,NOT_INSTALLED_WITH_PROVIDE:31,UNEXPECTED_ERROR:32,NOT_AVAILABLE_COMPOSITION_IN_LEGACY:34};function Hi(e,...t){return s2(e,null,void 0)}const J4=ru("__translateVNode"),Q4=ru("__datetimeParts"),e3=ru("__numberParts"),AM=ru("__setPluralRules"),MM=ru("__injectWithOption"),bd=ru("__dispose");function gp(e){if(!qn(e)||bl(e))return e;for(const t in e)if(br(e,t))if(!t.includes("."))qn(e[t])&&gp(e[t]);else{const n=t.split("."),o=n.length-1;let s=e,i=!1;for(let r=0;r<o;r++){if(n[r]==="__proto__")throw new Error(`unsafe key: ${n[r]}`);if(n[r]in s||(s[n[r]]=io()),!qn(s[n[r]])){i=!0;break}s=s[n[r]]}if(i||(bl(s)?gM.includes(n[o])||delete e[t]:(s[n[o]]=e[t],delete e[t])),!bl(s)){const r=s[n[o]];qn(r)&&gp(r)}}return e}function ty(e,t){const{messages:n,__i18n:o,messageResolver:s,flatJson:i}=t,r=$n(n)?n:Uo(o)?io():{[e]:io()};if(Uo(o)&&o.forEach(l=>{if("locale"in l&&"resource"in l){const{locale:a,resource:u}=l;a?(r[a]=r[a]||io(),Bh(u,r[a])):Bh(u,r)}else zt(l)&&Bh(JSON.parse(l),r)}),s==null&&i)for(const l in r)br(r,l)&&gp(r[l]);return r}function TM(e){return e.type}function EM(e,t,n){let o=qn(t.messages)?t.messages:io();"__i18nGlobal"in n&&(o=ty(e.locale.value,{messages:o,__i18n:n.__i18nGlobal}));const s=Object.keys(o);s.length&&s.forEach(i=>{e.mergeLocaleMessage(i,o[i])});{if(qn(t.datetimeFormats)){const i=Object.keys(t.datetimeFormats);i.length&&i.forEach(r=>{e.mergeDateTimeFormat(r,t.datetimeFormats[r])})}if(qn(t.numberFormats)){const i=Object.keys(t.numberFormats);i.length&&i.forEach(r=>{e.mergeNumberFormat(r,t.numberFormats[r])})}}}function xk(e){return j(Ua,null,e,0)}function vp(){return ds()}const Sk="__INTLIFY_META__",Ak=()=>[],KB=()=>!1;let Mk=0;function Tk(e){return((t,n,o,s)=>e(n,o,vp()||void 0,s))}const ZB=()=>{const e=vp();let t=null;return e&&(t=TM(e)[Sk])?{[Sk]:t}:null};function Nm(e={}){const{__root:t,__injectWithOption:n}=e,o=t===void 0,s=e.flatJson,i=Lm?Z:Xr;let r=Un(e.inheritLocale)?e.inheritLocale:!0;const l=i(t&&r?t.locale.value:zt(e.locale)?e.locale:mp),a=i(t&&r?t.fallbackLocale.value:zt(e.fallbackLocale)||Uo(e.fallbackLocale)||$n(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:l.value),u=i(ty(l.value,e)),c=i($n(e.datetimeFormats)?e.datetimeFormats:{[l.value]:{}}),d=i($n(e.numberFormats)?e.numberFormats:{[l.value]:{}});let f=t?t.missingWarn:Un(e.missingWarn)||e1(e.missingWarn)?e.missingWarn:!0,h=t?t.fallbackWarn:Un(e.fallbackWarn)||e1(e.fallbackWarn)?e.fallbackWarn:!0,m=t?t.fallbackRoot:Un(e.fallbackRoot)?e.fallbackRoot:!0,v=!!e.fallbackFormat,k=xo(e.missing)?e.missing:null,w=xo(e.missing)?Tk(e.missing):null,b=xo(e.postTranslation)?e.postTranslation:null,_=t?t.warnHtmlMessage:Un(e.warnHtmlMessage)?e.warnHtmlMessage:!0,g=!!e.escapeParameter;const x=t?t.modifiers:$n(e.modifiers)?e.modifiers:{};let S=e.pluralRules||t&&t.pluralRules,T;T=(()=>{o&&gk(null);const _e={version:VB,locale:l.value,fallbackLocale:a.value,messages:u.value,modifiers:x,pluralRules:S,missing:w===null?void 0:w,missingWarn:f,fallbackWarn:h,fallbackFormat:v,unresolving:!0,postTranslation:b===null?void 0:b,warnHtmlMessage:_,escapeParameter:g,messageResolver:e.messageResolver,messageCompiler:e.messageCompiler,__meta:{framework:"vue"}};_e.datetimeFormats=c.value,_e.numberFormats=d.value,_e.__datetimeFormatters=$n(T)?T.__datetimeFormatters:void 0,_e.__numberFormatters=$n(T)?T.__numberFormatters:void 0;const Ee=LB(_e);return o&&gk(Ee),Ee})(),Q1(T,l.value,a.value);function E(){return[l.value,a.value,u.value,c.value,d.value]}const P=R({get:()=>l.value,set:_e=>{T.locale=_e,l.value=_e}}),D=R({get:()=>a.value,set:_e=>{T.fallbackLocale=_e,a.value=_e,Q1(T,l.value,_e)}}),I=R(()=>u.value),$=R(()=>c.value),B=R(()=>d.value);function H(){return xo(b)?b:null}function O(_e){b=_e,T.postTranslation=_e}function F(){return k}function U(_e){_e!==null&&(w=Tk(_e)),k=_e,T.missing=w}const z=(_e,Ee,it,Fe,Oe,Ge)=>{E();let at;try{__INTLIFY_PROD_DEVTOOLS__,o||(T.fallbackContext=t?IB():void 0),at=_e(T)}finally{__INTLIFY_PROD_DEVTOOLS__,o||(T.fallbackContext=void 0)}if(it!=="translate exists"&&ls(at)&&at===i2||it==="translate exists"&&!at){const[Tt,Bt]=Ee();return t&&m?Fe(t):Oe(Tt)}else{if(Ge(at))return at;throw Hi(_i.UNEXPECTED_RETURN_TYPE)}};function W(..._e){return z(Ee=>Reflect.apply(_k,null,[Ee,..._e]),()=>X4(..._e),"translate",Ee=>Reflect.apply(Ee.t,Ee,[..._e]),Ee=>Ee,Ee=>zt(Ee))}function K(..._e){const[Ee,it,Fe]=_e;if(Fe&&!qn(Fe))throw Hi(_i.INVALID_ARGUMENT);return W(Ee,it,us({resolvedMessage:!0},Fe||{}))}function V(..._e){return z(Ee=>Reflect.apply(yk,null,[Ee,..._e]),()=>G4(..._e),"datetime format",Ee=>Reflect.apply(Ee.d,Ee,[..._e]),()=>$m,Ee=>zt(Ee)||Uo(Ee))}function ie(..._e){return z(Ee=>Reflect.apply(bk,null,[Ee,..._e]),()=>Y4(..._e),"number format",Ee=>Reflect.apply(Ee.n,Ee,[..._e]),()=>$m,Ee=>zt(Ee)||Uo(Ee))}function ne(_e){return _e.map(Ee=>zt(Ee)||ls(Ee)||Un(Ee)?xk(String(Ee)):Ee)}const le={normalize:ne,interpolate:_e=>_e,type:"vnode"};function Ie(..._e){return z(Ee=>{let it;const Fe=Ee;try{Fe.processor=le,it=Reflect.apply(_k,null,[Fe,..._e])}finally{Fe.processor=null}return it},()=>X4(..._e),"translate",Ee=>Ee[J4](..._e),Ee=>[xk(Ee)],Ee=>Uo(Ee))}function de(..._e){return z(Ee=>Reflect.apply(bk,null,[Ee,..._e]),()=>Y4(..._e),"number format",Ee=>Ee[e3](..._e),Ak,Ee=>zt(Ee)||Uo(Ee))}function pe(..._e){return z(Ee=>Reflect.apply(yk,null,[Ee,..._e]),()=>G4(..._e),"datetime format",Ee=>Ee[Q4](..._e),Ak,Ee=>zt(Ee)||Uo(Ee))}function ve(_e){S=_e,T.pluralRules=S}function oe(_e,Ee){return z(()=>{if(!_e)return!1;const it=zt(Ee)?Ee:l.value,Fe=zt(Ee)?[it]:Z4(T,a.value,it);for(let Oe=0;Oe<Fe.length;Oe++){const Ge=Y(Fe[Oe]);let at=T.messageResolver(Ge,_e);if(at===null&&(at=Ge[_e]),bl(at)||kr(at)||zt(at))return!0}return!1},()=>[_e],"translate exists",it=>Reflect.apply(it.te,it,[_e,Ee]),KB,it=>Un(it))}function ye(_e){let Ee=null;const it=Z4(T,a.value,l.value);for(let Fe=0;Fe<it.length;Fe++){const Oe=u.value[it[Fe]]||{},Ge=T.messageResolver(Oe,_e);if(Ge!=null){Ee=Ge;break}}return Ee}function G(_e){const Ee=ye(_e);return Ee??(t?t.tm(_e)||{}:{})}function Y(_e){return u.value[_e]||{}}function fe(_e,Ee){if(s){const it={[_e]:Ee};for(const Fe in it)br(it,Fe)&&gp(it[Fe]);Ee=it[_e]}u.value[_e]=Ee,T.messages=u.value}function we(_e,Ee){u.value[_e]=u.value[_e]||{};const it={[_e]:Ee};if(s)for(const Fe in it)br(it,Fe)&&gp(it[Fe]);Ee=it[_e],Bh(Ee,u.value[_e]),T.messages=u.value}function ge(_e){return c.value[_e]||{}}function Q(_e,Ee){c.value[_e]=Ee,T.datetimeFormats=c.value,kk(T,_e,Ee)}function te(_e,Ee){c.value[_e]=us(c.value[_e]||{},Ee),T.datetimeFormats=c.value,kk(T,_e,Ee)}function ce(_e){return d.value[_e]||{}}function ue(_e,Ee){d.value[_e]=Ee,T.numberFormats=d.value,Ck(T,_e,Ee)}function Se(_e,Ee){d.value[_e]=us(d.value[_e]||{},Ee),T.numberFormats=d.value,Ck(T,_e,Ee)}Mk++,t&&Lm&&(Je(t.locale,_e=>{r&&(l.value=_e,T.locale=_e,Q1(T,l.value,a.value))}),Je(t.fallbackLocale,_e=>{r&&(a.value=_e,T.fallbackLocale=_e,Q1(T,l.value,a.value))}));const ze={id:Mk,locale:P,fallbackLocale:D,get inheritLocale(){return r},set inheritLocale(_e){r=_e,_e&&t&&(l.value=t.locale.value,a.value=t.fallbackLocale.value,Q1(T,l.value,a.value))},get availableLocales(){return Object.keys(u.value).sort()},messages:I,get modifiers(){return x},get pluralRules(){return S||{}},get isGlobal(){return o},get missingWarn(){return f},set missingWarn(_e){f=_e,T.missingWarn=f},get fallbackWarn(){return h},set fallbackWarn(_e){h=_e,T.fallbackWarn=h},get fallbackRoot(){return m},set fallbackRoot(_e){m=_e},get fallbackFormat(){return v},set fallbackFormat(_e){v=_e,T.fallbackFormat=v},get warnHtmlMessage(){return _},set warnHtmlMessage(_e){_=_e,T.warnHtmlMessage=_e},get escapeParameter(){return g},set escapeParameter(_e){g=_e,T.escapeParameter=_e},t:W,getLocaleMessage:Y,setLocaleMessage:fe,mergeLocaleMessage:we,getPostTranslationHandler:H,setPostTranslationHandler:O,getMissingHandler:F,setMissingHandler:U,[AM]:ve};return ze.datetimeFormats=$,ze.numberFormats=B,ze.rt=K,ze.te=oe,ze.tm=G,ze.d=V,ze.n=ie,ze.getDateTimeFormat=ge,ze.setDateTimeFormat=Q,ze.mergeDateTimeFormat=te,ze.getNumberFormat=ce,ze.setNumberFormat=ue,ze.mergeNumberFormat=Se,ze[MM]=n,ze[J4]=Ie,ze[Q4]=pe,ze[e3]=de,ze}function GB(e){const t=zt(e.locale)?e.locale:mp,n=zt(e.fallbackLocale)||Uo(e.fallbackLocale)||$n(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:t,o=xo(e.missing)?e.missing:void 0,s=Un(e.silentTranslationWarn)||e1(e.silentTranslationWarn)?!e.silentTranslationWarn:!0,i=Un(e.silentFallbackWarn)||e1(e.silentFallbackWarn)?!e.silentFallbackWarn:!0,r=Un(e.fallbackRoot)?e.fallbackRoot:!0,l=!!e.formatFallbackMessages,a=$n(e.modifiers)?e.modifiers:{},u=e.pluralizationRules,c=xo(e.postTranslation)?e.postTranslation:void 0,d=zt(e.warnHtmlInMessage)?e.warnHtmlInMessage!=="off":!0,f=!!e.escapeParameterHtml,h=Un(e.sync)?e.sync:!0;let m=e.messages;if($n(e.sharedMessages)){const x=e.sharedMessages;m=Object.keys(x).reduce((T,A)=>{const E=T[A]||(T[A]={});return us(E,x[A]),T},m||{})}const{__i18n:v,__root:k,__injectWithOption:w}=e,b=e.datetimeFormats,_=e.numberFormats,g=e.flatJson;return{locale:t,fallbackLocale:n,messages:m,flatJson:g,datetimeFormats:b,numberFormats:_,missing:o,missingWarn:s,fallbackWarn:i,fallbackRoot:r,fallbackFormat:l,modifiers:a,pluralRules:u,postTranslation:c,warnHtmlMessage:d,escapeParameter:f,messageResolver:e.messageResolver,inheritLocale:h,__i18n:v,__root:k,__injectWithOption:w}}function t3(e={}){const t=Nm(GB(e)),{__extender:n}=e,o={id:t.id,get locale(){return t.locale.value},set locale(s){t.locale.value=s},get fallbackLocale(){return t.fallbackLocale.value},set fallbackLocale(s){t.fallbackLocale.value=s},get messages(){return t.messages.value},get datetimeFormats(){return t.datetimeFormats.value},get numberFormats(){return t.numberFormats.value},get availableLocales(){return t.availableLocales},get missing(){return t.getMissingHandler()},set missing(s){t.setMissingHandler(s)},get silentTranslationWarn(){return Un(t.missingWarn)?!t.missingWarn:t.missingWarn},set silentTranslationWarn(s){t.missingWarn=Un(s)?!s:s},get silentFallbackWarn(){return Un(t.fallbackWarn)?!t.fallbackWarn:t.fallbackWarn},set silentFallbackWarn(s){t.fallbackWarn=Un(s)?!s:s},get modifiers(){return t.modifiers},get formatFallbackMessages(){return t.fallbackFormat},set formatFallbackMessages(s){t.fallbackFormat=s},get postTranslation(){return t.getPostTranslationHandler()},set postTranslation(s){t.setPostTranslationHandler(s)},get sync(){return t.inheritLocale},set sync(s){t.inheritLocale=s},get warnHtmlInMessage(){return t.warnHtmlMessage?"warn":"off"},set warnHtmlInMessage(s){t.warnHtmlMessage=s!=="off"},get escapeParameterHtml(){return t.escapeParameter},set escapeParameterHtml(s){t.escapeParameter=s},get pluralizationRules(){return t.pluralRules||{}},__composer:t,t(...s){return Reflect.apply(t.t,t,[...s])},rt(...s){return Reflect.apply(t.rt,t,[...s])},te(s,i){return t.te(s,i)},tm(s){return t.tm(s)},getLocaleMessage(s){return t.getLocaleMessage(s)},setLocaleMessage(s,i){t.setLocaleMessage(s,i)},mergeLocaleMessage(s,i){t.mergeLocaleMessage(s,i)},d(...s){return Reflect.apply(t.d,t,[...s])},getDateTimeFormat(s){return t.getDateTimeFormat(s)},setDateTimeFormat(s,i){t.setDateTimeFormat(s,i)},mergeDateTimeFormat(s,i){t.mergeDateTimeFormat(s,i)},n(...s){return Reflect.apply(t.n,t,[...s])},getNumberFormat(s){return t.getNumberFormat(s)},setNumberFormat(s,i){t.setNumberFormat(s,i)},mergeNumberFormat(s,i){t.mergeNumberFormat(s,i)}};return o.__extender=n,o}function YB(e,t,n){return{beforeCreate(){const o=vp();if(!o)throw Hi(_i.UNEXPECTED_ERROR);const s=this.$options;if(s.i18n){const i=s.i18n;if(s.__i18n&&(i.__i18n=s.__i18n),i.__root=t,this===this.$root)this.$i18n=Ek(e,i);else{i.__injectWithOption=!0,i.__extender=n.__vueI18nExtend,this.$i18n=t3(i);const r=this.$i18n;r.__extender&&(r.__disposer=r.__extender(this.$i18n))}}else if(s.__i18n)if(this===this.$root)this.$i18n=Ek(e,s);else{this.$i18n=t3({__i18n:s.__i18n,__injectWithOption:!0,__extender:n.__vueI18nExtend,__root:t});const i=this.$i18n;i.__extender&&(i.__disposer=i.__extender(this.$i18n))}else this.$i18n=e;s.__i18nGlobal&&EM(t,s,s),this.$t=(...i)=>this.$i18n.t(...i),this.$rt=(...i)=>this.$i18n.rt(...i),this.$te=(i,r)=>this.$i18n.te(i,r),this.$d=(...i)=>this.$i18n.d(...i),this.$n=(...i)=>this.$i18n.n(...i),this.$tm=i=>this.$i18n.tm(i),n.__setInstance(o,this.$i18n)},mounted(){},unmounted(){const o=vp();if(!o)throw Hi(_i.UNEXPECTED_ERROR);const s=this.$i18n;s&&(delete this.$t,delete this.$rt,delete this.$te,delete this.$d,delete this.$n,delete this.$tm,s?.__disposer&&(s.__disposer(),delete s.__disposer,delete s.__extender),n.__deleteInstance(o),delete this.$i18n)}}}function Ek(e,t){e.locale=t.locale||e.locale,e.fallbackLocale=t.fallbackLocale||e.fallbackLocale,e.missing=t.missing||e.missing,e.silentTranslationWarn=t.silentTranslationWarn||e.silentFallbackWarn,e.silentFallbackWarn=t.silentFallbackWarn||e.silentFallbackWarn,e.formatFallbackMessages=t.formatFallbackMessages||e.formatFallbackMessages,e.postTranslation=t.postTranslation||e.postTranslation,e.warnHtmlInMessage=t.warnHtmlInMessage||e.warnHtmlInMessage,e.escapeParameterHtml=t.escapeParameterHtml||e.escapeParameterHtml,e.sync=t.sync||e.sync,e.__composer[AM](t.pluralizationRules||e.pluralizationRules);const n=ty(e.locale,{messages:t.messages,__i18n:t.__i18n});return Object.keys(n).forEach(o=>e.mergeLocaleMessage(o,n[o])),t.datetimeFormats&&Object.keys(t.datetimeFormats).forEach(o=>e.mergeDateTimeFormat(o,t.datetimeFormats[o])),t.numberFormats&&Object.keys(t.numberFormats).forEach(o=>e.mergeNumberFormat(o,t.numberFormats[o])),e}const ny={tag:{type:[String,Object]},locale:{type:String},scope:{type:String,validator:e=>e==="parent"||e==="global",default:"parent"},i18n:{type:Object}};function XB({slots:e},t){return t.length===1&&t[0]==="default"?(e.default?e.default():[]).reduce((o,s)=>[...o,...s.type===Pe?s.children:[s]],[]):t.reduce((n,o)=>{const s=e[o];return s&&(n[o]=s()),n},io())}function IM(){return Pe}const JB=et({name:"i18n-t",props:us({keypath:{type:String,required:!0},plural:{type:[Number,String],validator:e=>ls(e)||!isNaN(e)}},ny),setup(e,t){const{slots:n,attrs:o}=t,s=e.i18n||Nt({useScope:e.scope,__useComponent:!0});return()=>{const i=()=>{const a=Object.keys(n).filter(d=>d[0]!=="_"),u=io();e.locale&&(u.locale=e.locale),e.plural!==void 0&&(u.plural=zt(e.plural)?+e.plural:e.plural);const c=XB(t,a);return s[J4](e.keypath,c,u)},r=us(io(),o),l=zt(e.tag)||qn(e.tag)?e.tag:IM();return qn(l)?tn(l,r,{default:i}):tn(l,r,i())}}}),Ik=JB;function QB(e){return Uo(e)&&!zt(e[0])}function LM(e,t,n,o){const{slots:s,attrs:i}=t;return()=>{const r=()=>{const u={part:!0};let c=io();e.locale&&(u.locale=e.locale),zt(e.format)?u.key=e.format:qn(e.format)&&(zt(e.format.key)&&(u.key=e.format.key),c=Object.keys(e.format).reduce((h,m)=>n.includes(m)?us(io(),h,{[m]:e.format[m]}):h,io()));const d=o(e.value,u,c);let f=[u.key];return Uo(d)?f=d.map((h,m)=>{const v=s[h.type],k=v?v({[h.type]:h.value,index:m,parts:d}):[h.value];return QB(k)&&(k[0].key=`${h.type}-${m}`),k}):zt(d)&&(f=[d]),f},l=us(io(),i),a=zt(e.tag)||qn(e.tag)?e.tag:IM();return qn(a)?tn(a,l,{default:r}):tn(a,l,r())}}const eH=et({name:"i18n-n",props:us({value:{type:Number,required:!0},format:{type:[String,Object]}},ny),setup(e,t){const n=e.i18n||Nt({useScope:e.scope,__useComponent:!0});return LM(e,t,_M,(...o)=>n[e3](...o))}}),Lk=eH;function tH(e,t){const n=e;if(e.mode==="composition")return n.__getInstance(t)||e.global;{const o=n.__getInstance(t);return o!=null?o.__composer:e.global.__composer}}function nH(e){const t=r=>{const{instance:l,value:a}=r;if(!l||!l.$)throw Hi(_i.UNEXPECTED_ERROR);const u=tH(e,l.$),c=$k(a);return[Reflect.apply(u.t,u,[...Nk(c)]),u]};return{created:(r,l)=>{const[a,u]=t(l);Lm&&(r.__i18nWatcher=Je(u.locale,()=>{l.instance&&l.instance.$forceUpdate()})),r.__composer=u,r.textContent=a},unmounted:r=>{Lm&&r.__i18nWatcher&&(r.__i18nWatcher(),r.__i18nWatcher=void 0,delete r.__i18nWatcher),r.__composer&&(r.__composer=void 0,delete r.__composer)},beforeUpdate:(r,{value:l})=>{if(r.__composer){const a=r.__composer,u=$k(l);r.textContent=Reflect.apply(a.t,a,[...Nk(u)])}},getSSRProps:r=>{const[l]=t(r);return{textContent:l}}}}function $k(e){if(zt(e))return{path:e};if($n(e)){if(!("path"in e))throw Hi(_i.REQUIRED_VALUE,"path");return e}else throw Hi(_i.INVALID_VALUE)}function Nk(e){const{path:t,locale:n,args:o,choice:s,plural:i}=e,r={},l=o||{};return zt(n)&&(r.locale=n),ls(s)&&(r.plural=s),ls(i)&&(r.plural=i),[t,l,r]}function oH(e,t,...n){const o=$n(n[0])?n[0]:{};(Un(o.globalInstall)?o.globalInstall:!0)&&([Ik.name,"I18nT"].forEach(i=>e.component(i,Ik)),[Lk.name,"I18nN"].forEach(i=>e.component(i,Lk)),[Ok.name,"I18nD"].forEach(i=>e.component(i,Ok))),e.directive("t",nH(t))}const sH=ru("global-vue-i18n");function iH(e={}){const t=__VUE_I18N_LEGACY_API__&&Un(e.legacy)?e.legacy:__VUE_I18N_LEGACY_API__,n=Un(e.globalInjection)?e.globalInjection:!0,o=new Map,[s,i]=rH(e,t),r=ru("");function l(d){return o.get(d)||null}function a(d,f){o.set(d,f)}function u(d){o.delete(d)}const c={get mode(){return __VUE_I18N_LEGACY_API__&&t?"legacy":"composition"},async install(d,...f){if(d.__VUE_I18N_SYMBOL__=r,d.provide(d.__VUE_I18N_SYMBOL__,c),$n(f[0])){const v=f[0];c.__composerExtend=v.__composerExtend,c.__vueI18nExtend=v.__vueI18nExtend}let h=null;!t&&n&&(h=pH(d,c.global)),__VUE_I18N_FULL_INSTALL__&&oH(d,c,...f),__VUE_I18N_LEGACY_API__&&t&&d.mixin(YB(i,i.__composer,c));const m=d.unmount;d.unmount=()=>{h&&h(),c.dispose(),m()}},get global(){return i},dispose(){s.stop()},__instances:o,__getInstance:l,__setInstance:a,__deleteInstance:u};return c}function Nt(e={}){const t=vp();if(t==null)throw Hi(_i.MUST_BE_CALL_SETUP_TOP);if(!t.isCE&&t.appContext.app!=null&&!t.appContext.app.__VUE_I18N_SYMBOL__)throw Hi(_i.NOT_INSTALLED);const n=lH(t),o=uH(n),s=TM(t),i=aH(e,s);if(i==="global")return EM(o,e,s),o;if(i==="parent"){let a=Fk(n,t,e.__useComponent);return a==null&&(a=o),a}if(i==="isolated"){if(n.mode!=="composition")throw Hi(_i.NOT_AVAILABLE_COMPOSITION_IN_LEGACY);const a=n,u=us({},e),c=Fk(n,t);u.__root=c||o;const d=Nm(u);return a.__composerExtend&&(d[bd]=a.__composerExtend(d)),Kg()&&d1(()=>{const h=d[bd];h&&(h(),delete d[bd])}),d}const r=n;let l=r.__getInstance(t);if(l==null){const a=us({},e);"__i18n"in s&&(a.__i18n=s.__i18n),o&&(a.__root=o),l=Nm(a),r.__composerExtend&&(l[bd]=r.__composerExtend(l)),dH(r,t,l),r.__setInstance(t,l)}return l}function rH(e,t){const n=ER(),o=__VUE_I18N_LEGACY_API__&&t?n.run(()=>t3(e)):n.run(()=>Nm(e));if(o==null)throw Hi(_i.UNEXPECTED_ERROR);return[n,o]}function lH(e){const t=nn(e.isCE?sH:e.appContext.app.__VUE_I18N_SYMBOL__);if(!t)throw Hi(e.isCE?_i.NOT_INSTALLED_WITH_PROVIDE:_i.UNEXPECTED_ERROR);return t}function aH(e,t){return o2(e)?"__i18n"in t?"local":"global":e.useScope?e.useScope:"local"}function uH(e){return e.mode==="composition"?e.global:e.global.__composer}function Fk(e,t,n=!1){let o=null;const s=t.root;let i=cH(t,n);for(;i!=null;){const r=e;if(e.mode==="composition")o=r.__getInstance(i);else if(__VUE_I18N_LEGACY_API__){const l=r.__getInstance(i);l!=null&&(o=l.__composer,n&&o&&!o[MM]&&(o=null))}if(o!=null||s===i)break;i=i.parent}return o}function cH(e,t=!1){return e==null?null:t&&e.vnode.ctx||e.parent}function dH(e,t,n){dn(()=>{},t),bn(()=>{const o=n;e.__deleteInstance(t);const s=o[bd];s&&(s(),delete o[bd])},t)}const fH=["locale","fallbackLocale","availableLocales"],Rk=["t","rt","d","n","tm","te"];function pH(e,t){const n=Object.create(null);return fH.forEach(s=>{const i=Object.getOwnPropertyDescriptor(t,s);if(!i)throw Hi(_i.UNEXPECTED_ERROR);const r=Xo(i.value)?{get(){return i.value.value},set(l){i.value.value=l}}:{get(){return i.get&&i.get()}};Object.defineProperty(n,s,r)}),e.config.globalProperties.$i18n=n,Rk.forEach(s=>{const i=Object.getOwnPropertyDescriptor(t,s);if(!i||!i.value)throw Hi(_i.UNEXPECTED_ERROR);Object.defineProperty(e.config.globalProperties,`$${s}`,i)}),()=>{delete e.config.globalProperties.$i18n,Rk.forEach(s=>{delete e.config.globalProperties[`$${s}`]})}}const hH=et({name:"i18n-d",props:us({value:{type:[Number,Date],required:!0},format:{type:[String,Object]}},ny),setup(e,t){const n=e.i18n||Nt({useScope:e.scope,__useComponent:!0});return LM(e,t,wM,(...o)=>n[Q4](...o))}}),Ok=hH;qB();SB(rB);AB(wB);MB(Z4);if(__INTLIFY_PROD_DEVTOOLS__){const e=Xu();e.__INTLIFY__=!0,lB(e.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__)}const mH={preview:"Preview",confirm:"Confirm",cancel:"Cancel",close:"Close",dismiss:"Dismiss",loading:"Loading",copy:"Copy"},gH={authBannerMessage:"Not signed in · Sign in to Kimi Code to start a conversation",authBannerLogin:"Sign in",connecting:"Connecting…",internalBuildBanner:"Internal testing only",menuFile:"File",menuEdit:"Edit",menuView:"View",menuHelp:"Help",applicationMenu:"Application menu"},vH={workspaceMeta:"workspace · {branch}",sessionsHeader:"sessions",workspaces:"Workspaces",viewSwitcher:"View options",viewGroup:"View",viewFlat:"Flat list",viewGrouped:"Group by workspace",collapseAll:"Collapse all workspaces",expandAll:"Expand all workspaces",newSession:"New Session",newChat:"New Session",newWorkspace:"New Workspace",dropToAddWorkspace:"Drop to add workspace",emptyState:"No sessions yet · click New Session to start",options:"Options",rename:"Rename",setEmoji:"Set Emoji…",sessionEmojiTitle:"Pick an emoji",removeEmoji:"Remove emoji",randomEmoji:"Random",searchEmoji:"Search emoji",recentEmojis:"Recently used",noEmojiResults:"No matching emoji",emojiGroupFaces:"Smileys & People",emojiGroupNature:"Animals & Nature",emojiGroupFood:"Food & Drink",emojiGroupActivity:"Activities & Travel",emojiGroupObjects:"Objects & Work",emojiGroupSymbols:"Symbols & Status",copyPath:"Copy path",copySessionId:"Copy session ID",copied:"Copied ✓",copyFailed:"Copy failed",archive:"Archive",archiveToastUndo:"Undo",archiveToastMid:"or view archived chats in",archiveToastSettings:"Settings",archiveToastTail:"",fork:"Fork session",export:"Export session",pin:"Pin",unpin:"Unpin",pinned:"Pinned",collapsePinned:"Collapse pinned",expandPinned:"Expand pinned",delete:"Delete",removeWorkspace:"Remove workspace",brand:"Kimi Code",signedIn:"Signed in",signOut:"Sign out",notSignedIn:"Not signed in",signIn:"Sign in",defaultUserName:"Kimi User",upgrade:"Upgrade",logoutConfirmTitle:"Sign out",logoutConfirmMessage:"Are you sure you want to sign out?",language:"Language",backendTitle:"Backend {backend} · {endpoint} — click to switch",noSessions:"No conversations yet",allPinned:"{count} conversations pinned",showMore:"Show more",loadMore:"Load more",showLess:"Show less",loadingMore:"Loading…",collapseSidebar:"Collapse sidebar",expandSidebar:"Expand sidebar",searchPlaceholder:"Search sessions",search:"Search",searchHint:"↑↓ navigate · ↵ open · Esc close",searchHintSelect:"navigate",searchHintOpen:"open",searchHintClose:"close",searchClear:"Clear search",searchNoResults:"No matching sessions",searchEmpty:"No sessions yet",update:"Upgrade",updateAvailable:"v{version} available",updateDownloading:"Downloading… {percent}%",updateReady:"v{version} ready",updateDone:"Restart",updateFailed:"Download failed",updateRetry:"Retry",updateDownloadNow:"Download & Update",updateSkip:"Skip This Version",updateRestartNow:"Restart Now",updateRestartLater:"Later",updateReleaseDate:"Released {date}",updateCurrentVersion:"Current v{version}",updateWhatsNew:"What’s new",updateBackground:"Download in Background",updateAutoDownload:"Automatically download and install updates"},yH={switcherTitle:"Switch workspace",switchTooltip:"Switch workspace",eyebrow:"Workspace",branchLabel:"branch: {branch}",noBranch:"no branch",sessionCount:"{count} session | {count} sessions",allWorkspaces:"All workspaces",currentWorkspace:"Current workspace only",addWorkspace:"Add workspace…",noWorkspace:"No workspace",deleteHasSessions:"This workspace still has sessions — archive them before deleting it",removeWorkspaceConfirm:'Remove workspace "{name}"?',swarmEnableTitle:"Enable swarm mode?",swarmEnableConfirm:"The agent will run multiple sub-agents in parallel.",goalStartTitle:"Start goal?",goalStartConfirm:'"{objective}" — the agent will run autonomously toward it.',scopeCurrent:"this workspace",scopeAll:"all workspaces",newInGroup:"New session in this workspace",addTitle:"Add workspace",pathLabel:"Path",pathPlaceholder:"/absolute/path/to/project",recentLabel:"Recent folders",add:"Add",cancel:"Cancel",addHint:"Paste an absolute folder path, or pick a recent one.",addFailed:"Couldn't open this folder. Check the path and try again.",requiredTitle:"Choose a workspace first",requiredMessage:"Pick a folder to use as your workspace before sending a message.",openThisFolder:"Open this folder",up:"Up",browsing:"Browsing…",filterPlaceholder:"Filter subfolders…",searchPlaceholder:"Fuzzy-search under this folder…",searching:"Searching…",pasteToggle:"Enter an absolute path",noFilterMatch:"No subfolders match “{q}”",noSubfolders:"No subfolders here",browseHint:'Click a folder to enter it, then "Open this folder" to add it as a workspace.',attentionTitle:"{count} item needs your attention | {count} items need your attention",awaitingAnswer:"Answer",awaitingAnswerTitle:"A question is waiting for your answer",awaitingPermission:"Approve",awaitingPermissionTitle:"An action is waiting for your approval",aborted:"Failed",abortedTitle:"This session's latest turn ended on an error"},kH={jumpToLatestAria:"Jump to latest message",toc:"Conversation outline",newMessages:"Latest messages",loading:"Loading…",starting:"Starting conversation…",requesting:"Requesting…",working:"Working…",workingRetry:"Model request failed — retrying ({n}/{max})…",emptyWorkspaceHint:"Send in {name}",switchWorkspace:"Switch workspace",addWorkspace:"New workspace",moreWorkspaces:"More workspaces ({count})",pickFolder:"Choose folder…",compacting:"Compacting context…",compactedPlain:"Context compacted",compactedAuto:"Context auto-compacted",compactedTokens:" ({before} → {after} tokens)",viewSummary:"View summary",summaryTitle:"Compaction summary",activatedSkill:"Activated skill: {name}",undo:"Undo",undoTooltip:"Undo edit",undoConfirm:"Undo last message?",escUndoHintPre:"Press",escUndoHintPost:"again to undo",undone:"Undone — the message is back in the composer",turnInterrupted:"Manually stopped",turnFailed:"Model request failed — this turn was interrupted",turnFailedMaxSteps:"Step limit reached — this turn was interrupted",turnFailedResume:"Continue",turnFailedResumeText:"Continue",yesterday:"Yesterday",loadOlder:"Load earlier messages",loadingOlder:"Loading earlier messages…",widenTable:"Widen table",restoreTableWidth:"Restore default width",cron:{fired:"Scheduled reminder fired",missed:"Missed scheduled reminders",job:"job {id}",oneShot:"one-shot",coalesced:"{n} fires coalesced",missedCount:"{n} missed",finalDelivery:"final delivery",expand:"Show more",collapse:"Show less"},fold:{worked:"Worked {duration}",workedUnknown:"Work details"},turnFiles:{titleOne:"{number} file changed",titleOther:"{number} files changed",more:"{number} more files",moreOne:"1 more file",showLess:"Show less",diffTitle:"Changes this turn",diffUnavailable:"This file’s changes can’t be shown line by line",openFile:"Open file"},goal:{continuation:"Goal continuation"},notification:{kindTask:"Background task",kindSubagent:"Subagent",title:{completed:"{kind} completed",failed:"{kind} failed",timed_out:"{kind} timed out",killed:"{kind} killed",lost:"{kind} lost",info:"{kind} notification"},status:{completed:"completed",failed:"failed",timed_out:"timed out",killed:"killed",lost:"lost",info:"info"},groupTitle:"{n} notifications",copyPath:"Copy path",copied:"Copied",rawPayload:"Raw payload",fields:{type:"Type",source:"Source",severity:"Severity"}},userMessage:{expand:"Show more",collapse:"Show less"},search:{placeholder:"Search chat…",searching:"Searching…",results:"{current}/{total} results",resultsCapped:"{current}/{total}+ results",noResults:"No results",previous:"Previous match",next:"Next match",close:"Close search"}},bH={connectionConnected:"Connected",connectionConnecting:"Connecting…",connectionDisconnected:"Disconnected",ctxTooltip:"Used {used} / {max} tokens ({pct}%)",modelLabel:"Model",permissionManual:"Manual",permissionAuto:"Auto",permissionYolo:"YOLO",permissionManualDesc:"Ask for approval on every tool action",permissionAutoDesc:"Fully autonomous — agent decides everything without asking",permissionYoloDesc:"Auto-approve tool actions, but agent may still ask questions",planLabel:"Plan",planDesc:"Have the agent make a plan before changing files",planOn:"on",planOff:"off",planTooltip:"Toggle plan mode (research before editing)",modesLabel:"Mode",goalLabel:"Goal",goalDesc:"Track one objective until it is complete",swarmLabel:"Swarm",swarmDesc:"Run parallel agents for broader exploration",modeOff:"Off",goalPlaceholder:"What should the agent achieve?",goalStart:"Start",goalPause:"Pause",goalResume:"Resume",goalCancel:"Cancel",goalCancelConfirm:"Cancel this goal? It cannot be resumed afterwards.",goalCancelConfirmYes:"Yes",goalCancelConfirmNo:"No",goalDoneWhen:"Done when",goalStatusActive:"Active",goalStatusPaused:"Paused",goalStatusBlocked:"Blocked",goalStatusComplete:"Complete",modeNotSupported:"Not supported",thinkingLabel:"Thinking",thinkingTooltip:"Toggle thinking mode",thinkingOn:"On",thinkingOff:"Off",cacheNote:"Note: Switching models or thinking effort invalidates the existing prompt cache. Start a new chat to avoid extra token costs.",starredModels:"Starred",moreModels:"More models…",statusPanelTitle:"Session status",statusPanelClose:"Close",statusModel:"Model",statusThinking:"Thinking",statusPermission:"Permission",statusPlanMode:"Plan mode",statusSwarmMode:"Swarm mode",swarmOn:"on",swarmOff:"off",statusContext:"Context",statusCost:"Cost",statusContextValue:"{used} / {max} ({pct}%)",statusNone:"—",activityRunning:"Running…",activityAwaitingApproval:"Awaiting approval",activityAwaitingQuestion:"Awaiting answer",interrupt:"Interrupt",runningShort:"in progress"},CH={placeholder:"Type a message…",send:"Send ↵",queueLabel:"Queue",placeholderRunning:"Press Enter to queue · Ctrl+S to inject into the running turn",starting:"Sending…",queueAutoDrain:"sends automatically when the current turn ends",queueNext:"Up next",queueDragTitle:"Drag to reorder",editQueued:"Edit (load back into the input)",queuedAttachments:"attachment ×{n}",queuedHasImage:"Contains {n} image(s) — remove only, not editable",attachmentImage:"Image",attachmentVideo:"Video",attachmentFile:"File",attachmentOpenUnsupported:"Can’t open {name} — this file type isn’t supported",dropToAttach:"Drop files to attach",remove:"Remove",removeNamed:"Remove {name}",clearAll:"Clear all attachments",attachmentCount:"{n} attachments",uploading:"Uploading",uploadFailed:"Upload failed",attachFile:"Attach file",previewAttachment:"Preview {name}",interrupt:"Interrupt",interruptTitle:"Interrupt current operation",expandTitle:"Expand input for multi-line editing",collapseTitle:"Collapse input",emptyConversationTitle:"Kimi Code",emptyConversation:"No messages yet — type below to start the conversation",upgradeBanner:"Upgrade your Kimi account to use Kimi Code",quickStartPlaceholder:"Type a message to start a new conversation…",thinkingSuffix:" · thinking",thinkingSuffixEffort:" · {level}"},wH={title:"Sign in to Kimi Code",close:"Close (Esc)",starting:"Starting sign-in flow…",lead:"Click the button below to sign in from a new browser tab.",authorizeInBrowser:"Sign in via browser",orDivider:"or",fallbackPrefix:"On another device? Open ",fallbackSuffix:" and enter the device code:",copy:"Copy",copied:"Copied",copyLink:"Copy link",waitingAuth:"Waiting for sign-in",waitingAutoClose:"Waiting for sign-in, closes automatically…",success:"Signed in",successHint:"Loading, will close automatically…",expiredTitle:"Device code expired",expiredHint:"Please restart the sign-in flow",retry:"Retry",closeBtn:"Close",errorTitle:"The current version does not support login yet",errorHint:"Please upgrade kimi-code and try again",pollErrorTitle:"Lost connection",pollErrorHint:"Sign-in polling failed repeatedly. Check the kimi-code process and try again.",action:"Sign in",requiredTitle:"Sign in required",requiredMessage:"Sign in to your Kimi account and set up a model to start chatting.",goToLogin:"Sign in",upgradeRequiredTitle:"Upgrade required",upgradeRequiredMessage:"Your account is on the free plan. Upgrade to a membership to start chatting with Kimi models."},_H={title:"Provider management",loading:"Loading providers…",unavailable:"Provider management is not available yet",empty:"No providers yet",status:{connected:"Connected",error:"Error",unconfigured:"Not configured"},keySet:"key set",keyNotSet:"key not set",managedBadge:"OAuth",modelCount:"{count} models",confirmDelete:"Confirm delete?",refresh:"Refresh",delete:"Delete",refreshTitle:"Refresh {type}",deleteTitle:"Delete {type}",loginKimi:"Sign in to Kimi",loginAnthropic:"Sign in to Anthropic",addProvider:"Add provider",added:"Provider added",enterApiKey:"Enter API Key",optional:"Optional",apiKeyRequired:"API Key cannot be empty",fieldId:"Name",fieldType:"API Protocol",types:{kimi:"Kimi",openai:"OpenAI",openai_responses:"OpenAI Responses",anthropic:"Anthropic","google-genai":"Google GenAI",vertexai:"Vertex AI"},fieldApiKey:"API Key",apiKeyManaged:"Signed in with OAuth",apiKeySet:"Set — enter a new key to replace",showApiKey:"Show API key",hideApiKey:"Hide API key",fieldBaseUrl:"Base URL",baseUrlPlaceholder:"https://api.example.com/v1",fieldModels:"Models",colModelId:"Model ID",colContext:"Context",colDisplayName:"Display name",modelIdPlaceholder:"kimi-k3",modelContextPlaceholder:"1048576",modelNamePlaceholder:"Optional",noModels:"No models",addModel:"Add model",removeModel:"Remove model",fieldDefaultModel:"Default model",save:"Save",saved:"Provider saved",deleteProvider:"Delete provider",deleteConfirm:"Delete {id} and its {count} models?",deleteConfirmYes:"Delete",managedHint:"Managed providers sign in and out on the Account tab",unsavedGuard:"You have unsaved changes.",guardStay:"Keep editing",guardDiscard:"Discard",add:"Add",catalog:{sourceCatalog:"From directory",sourceManual:"Manual",sourceRegistry:"Registry",registryHint:"Import providers and models from an api.json registry; re-importing the same URL refreshes it",registryUrlLabel:"Registry URL",registryImported:"{count} providers imported",searchPlaceholder:"Search providers",loading:"Loading directory…",loadError:"Failed to load the directory. Check your network and retry.",retry:"Retry",empty:"No matching providers",rejected:"Not importable",rejectReason:{"unknown-explicit-type":"Unsupported protocol","proprietary-sdk":"Proprietary SDK — cannot be imported","empty-base-url":"Blank base URL","placeholder-base-url":"Endpoint contains an env placeholder"},backToList:"Back to directory",willImport:"{count} models will be imported from the directory",overwriteWarning:"A provider with this name already exists; importing overwrites its config and models",importAction:"Import"},error:{idRequired:"Name cannot be empty",idInvalid:'Name must start with a letter or digit and may only contain letters, digits, "-", "_" and spaces',apiKeyRequired:"API Key cannot be empty",baseUrlRequired:"Base URL cannot be empty",registryUrlRequired:"Registry URL cannot be empty",modelRequired:"Model ID cannot be empty",contextSizeRequired:"Max context size cannot be empty",contextSizeInvalid:"Max context size must be a positive integer"},hintClose:"Close"},xH={dialogLabel:"Switch model",title:"Switch model",close:"Close (Esc)",allTab:"All",providerTabs:"Model providers",searchPlaceholder:"Search models or providers…",clearSearch:"Clear search",loading:"Loading models…",unavailable:"Model list is unavailable",contextSuffix:"{size} ctx",capabilityImageInput:"Image input",capabilityVideoInput:"Video input",capabilityToolUse:"Tool use",capabilityThinking:"Thinking",capabilityAlwaysThinking:"Always thinking",emptyNoModels:"No models available",emptyNoMatch:"No matching models",starTitle:"Add to favorites",unstarTitle:"Remove from favorites",hintNavigate:"Navigate",hintSelect:"Select",hintClose:"Close"},SH={justNow:"just now"},AH={title:{shell:"Run command?",diff:"Apply changes?",file:"Write file?",fileop:"File operation?",url:"Fetch URL?",search:"Search?",invocation:"Invoke?",todo:"Update todo?",plan_review:"Ready to build with this plan?",generic:"Approve action?"},subagentBadge:"sub agent · {name}",danger:"Danger: {detail}",searchQueryLabel:"query",searchScope:"scope: {scope}",feedbackPlaceholder:"Explain why you are rejecting… (Enter to submit, Esc to cancel)",feedbackHint:"Enter to submit · Esc to cancel",approve:"Approve",approveSession:"Approve for session",reject:"Reject",feedback:"Feedback",feedbackSubmit:"Reject with feedback",feedbackCancel:"Cancel",approvePlan:"Approve plan",revise:"Revise",rejectAndExit:"Reject and Exit",expandPlan:"Expand",collapsePlan:"Collapse"},MH={back:"‹ Previous question",nextQuestion:"Next question ›",otherDefault:"Other…",submit:"Submit",dismiss:"Dismiss",minimize:"Minimize",expand:"Expand",hint:"↑↓ to choose · Enter to confirm"},TH={tag:"tasks",summary:"{run} running · {done} done",copy:"Copy",calling:"Calling {label}",fieldTask:"Task",fieldOutput:"Output",fieldProgress:"Progress",fieldResult:"Result",moreLines:"… ({count} more)",copied:"Copied",stop:"stop",defaultDescription:"Background task",dockTasks:"Background tasks",dockBash:"Bash",dockSubagent:"Sub Agent",dockTodos:"Todos",running:"running",closePanel:"Close panel",timingRunning:"Running · {time}",timingDone:"Done · {sec}s",emptyTasks:"No background tasks running",emptyBash:"No bash tasks running",emptySubagent:"No sub agent tasks running",emptyTodo:"No todos yet",openTab:"Open the tasks tab",openDetail:"Open",collapse:"Collapse",expand:"Expand",transcriptLoadError:"Failed to load this sub agent’s conversation."},EH={panelTitle:"Thinking",streaming:"Thinking…",close:"Close"},IH={title:"Changes",branch:"branch",aheadTitle:"ahead of remote",behindTitle:"behind remote",fileCountOne:"{number} file",fileCountOther:"{number} files",empty:"No git changes",clean:"Working tree clean, no changes",back:"Back",loading:"Loading diff…",noDiff:"No line changes for this file",emptyFile:"Empty file",list:"List",tree:"Tree",close:"Close"},LH={},$H={empty:"Select a file on the left to preview",loading:"Loading…",lineCount:"{count} lines",copy:"Copy",copied:"Copied",copyPath:"Copy path",openInEditor:"Open",reveal:"Reveal",download:"Download",close:"Close",search:"Search",prevMatch:"Previous match",nextMatch:"Next match",htmlMode:"HTML preview mode",markdownMode:"Markdown preview mode",preview:"Preview",source:"Source",imageFit:"Image sizing",fit:"Fit",actual:"Actual",pdfNoPreview:"This PDF cannot be embedded here. Download it to view.",imageNoPreview:"Image file · {mime} · {size} · preview unavailable",binaryNoPreview:"Binary file · {mime} · {size} bytes · preview unavailable",unknownType:"unknown type",copyCode:"Copy code",enlargeImage:"Enlarge image",errors:{emptyPath:"File path is empty",unsupportedPath:"URLs and remote paths cannot be previewed",outsideWorkspace:"Only files inside the current workspace can be previewed",isDirectory:"Select a file instead of a directory",notFound:"File no longer exists or was moved",tooLarge:"File is too large to preview",loadFailed:"Unable to read this file"}},NH={searching:"Searching…",noMatch:"No matches"},FH={dismiss:"Close",errorLabel:"Error",noteLabel:"Note",agentWarningFallback:"agent warning",unhandledEvent:"Unhandled event: {type}",agentError:{title:"Model request failed",connection:"Cannot connect to the model service",auth:"Model authentication failed",rateLimit:"Model rate limit reached",overloaded:"Model overloaded",filtered:"Response filtered by the provider",api:"Model API error",contextOverflow:"Context size exceeded"},details:{cause:"Cause",code:"Error code",connection:"Connection",contentType:"Content type",details:"Server details",duration:"Duration",endpoint:"Endpoint",errorName:"Error type",message:"Message",operation:"Operation",phase:"Failure phase",request:"Request",requestId:"Request ID",responsePreview:"Response preview",sessionId:"Session ID",stack:"Stack",status:"HTTP status",timeout:"Timeout",timestamp:"Time"},daemonApiTitle:"Kimi server returned an error",daemonNetworkMessage:"Web did not receive a response from the Kimi server. Check that it is still running, or refresh the page.",daemonNetworkTitle:"Cannot connect to Kimi server",diagnostics:"Diagnostics",hideDetails:"Hide details",operationFailedMessage:"The last operation did not finish. Try again later.",operationFailedTitle:"Operation failed",sessionSnapshotMessage:"Web could not load the current conversation. Check that the Kimi server is still running, or refresh the page.",sessionSnapshotTitle:"Cannot load current conversation",showDetails:"Show details",copyDetails:"Copy diagnostics",copied:"Copied",wsTitle:"Realtime connection error",goal:{alreadyExists:"This session already has an active goal. Cancel it before starting a new one.",notFound:"No goal to act on — it may have already finished or been cancelled.",statusInvalid:"The current goal state does not allow this action.",notResumable:"This goal cannot be resumed (it may be cancelled or completed).",objectiveTooLong:"The objective is too long. Please shorten it and try again."}},RH={new:{desc:"Create a new session"},clear:{desc:"Clear and start a new session"},login:{desc:"Sign in to Kimi in the browser"},plan:{desc:"Toggle plan mode on/off"},swarm:{desc:"Toggle swarm mode; /swarm <task> runs a task in swarm"},goal:{desc:"Create/control a goal: /goal <objective>, /goal pause{'|'}resume{'|'}cancel"},btw:{desc:"Side chat: /btw <question> asks a forked side session"},yolo:{desc:"Auto-approve tool actions; the agent may still ask questions"},auto:{desc:"Fully autonomous — the agent never asks questions"},thinking:{desc:"Set the thinking level"},compact:{desc:"Compact the conversation history"},fork:{desc:"Fork this session into a new one"},export:{desc:"Download this session and troubleshooting logs as a ZIP",noSession:"Open a session before exporting it."},status:{desc:"View session status"},undo:{desc:"Undo the last message"}},OH={label:{read:"Read",bash:"Run",edit:"Edit",write:"Write",grep:"Search",glob:"Find",ls:"List",web_fetch:"Fetch",search:"Search",todo:"Todo",task:"Task",swarm:"Swarm",ask_user:"Question",plan:"Plan",goal_create:"Start Goal",goal_get:"Read Goal",goal_budget:"Set Goal Budget",goal_update:"Update Goal"},swarm:{progress:"{done} / {total}",runningSub:"{count} in progress",doneSub:"{completed} completed · {failed} failed",phaseQueued:"Queued",phaseWorking:"Working",phaseSuspended:"Suspended",phaseCompleted:"Completed",phaseFailed:"Failed",waiting:"Waiting for subagents…"},chip:{lines:"{count} lines",results:"{count} results",files:"{count} files",edited:"edited",created:"created",todos:"{count} items"},disclosure:{expand:"Expand details",collapse:"Collapse details"},output:{waiting:"Waiting for output…",empty:"No output",saved:"Saved result"},plan:{review:{pending:"Pending review",approved:"Approved",rejected:"Rejected",cancelled:"Cancelled"},selectedOption:"Selected",feedback:"Feedback"},summary:{inScope:"{value} in {scope}"},goal:{objectiveWithCriterion:"{objective} · {criterion}",status:"Status: {status}",budget:"{value} {unit}",turns:"{value} turns",tokens:"{value} tokens",milliseconds:"{value} ms",seconds:"{value} sec",minutes:"{value} min",hours:"{value} hr"},group:{countOther:"{count} tool call | {count} tool calls",typed:{read:{done:"Read {count} file | Read {count} files"},bash:{done:"Ran {count} command | Ran {count} commands"},grep:{done:"Searched {count} pattern | Searched {count} patterns"},search:{done:"Ran {count} web search | Ran {count} web searches"},glob:{done:"Matched {count} file pattern | Matched {count} file patterns"},ls:{done:"Listed {count} directory | Listed {count} directories"},web_fetch:{done:"Fetched {count} page | Fetched {count} pages"},edit:{done:"Made {count} edit | Made {count} edits"},write:{done:"Wrote {count} file | Wrote {count} files"}}},activity:{failedClause:" ({count} failed)",liveDonePrefix:"",busy:"Working…",doing:{read:"Reading {subject}",bash:"Running {subject}",grep:"Searching {subject}",search:"Searching {subject}",glob:"Matching {subject}",ls:"Listing {subject}",web_fetch:"Fetching {subject}",edit:"Editing {subject}",write:"Writing {subject}"}},ask:{dismissed:"Dismissed",answer:"{count} answer",answers:"{count} answers",answered:"Answered",more:"(+{count} more)",collected:"Collected your answers",question:"{count} question",questions:"{count} questions",freeInput:"(free text)",unanswered:"No answer"}},PH={resizeHandleAria:"Resize sidebar width",resizePreviewAria:"Resize preview panel width",detailPanelAria:"Detail panel"},DH={openSwitcher:"Switch session / workspace",openSettings:"Session settings",settingsTitle:"Session settings",groupSession:"Current session",groupApp:"App preferences",sheetLabel:"Sheet",closeSheet:"Close",tapToCycle:"tap to cycle",running:"running",idle:"idle",sessionCount:"{n} sessions",newSession:"New session",permManualSub:"confirm every tool",permAutoSub:"fully autonomous, never asks",permYoloSub:"auto-approve tools, may still ask",planModeSub:"Plan mode",swarmModeSub:"Swarm mode",archivedSessions:"Archived sessions",archivedSessionsSub:"Browse and restore archived sessions",archivedBack:"Back"},BH={colorSchemeLabel:"Appearance",light:"Moon bright",dark:"Moon dark",system:"System"},HH={continue:"Continue",back:"Back",skip:"Skip",welcome:{title:"Welcome to Kimi Code",subtitle:"The AI coding workbench for professional developers",languageLabel:"Language",themeLabel:"Appearance"},login:{title:"Configure Model",subtitle:"Choose the model service that powers Kimi Code. You can change it later in Settings",kimiTitle:"Sign in with Kimi",kimiHint:"Ready out of the box with Kimi membership benefits",recommended:"Recommended",customProviderTitle:"Add a custom provider",customProviderHint:"Bring your own API key for OpenAI-compatible and other services",loggedInTitle:"Logged in with Kimi",loggedInHint:"Your model service is ready to use",finish:"Finish",skip:"Skip for now"}},zH={title:"Settings",internalTest:"Internal Test",close:"Close (Esc)",tabs:{general:"General",agent:"Agent",account:"Account",providers:"Providers",advanced:"Advanced",archived:"Archived",shortcuts:"Hotkeys"},appearance:"Appearance",notifications:"Notifications",notifyEnabled:"System notifications",notifyEnabledHint:"Send a system notification when a turn completes, needs an answer, or needs approval",notifySound:"Notification sound",notifySoundHint:"Play the system sound with notifications",notifyDenied:"Blocked in browser settings",notifyTitle:"Kimi Code · Turn finished",notifyQuestionTitle:"Kimi Code · Needs answer",notifyApprovalTitle:"Kimi Code · Approval required",notifyFallback:"View result",notifyQuestionFallback:"A question is waiting for your answer",notifyApprovalFallback:"A tool needs your approval",account:"Account",signedIn:"Signed in",signedOutHint:"Sign in to view your account and model access",planUsage:{title:"Plan Usage",retry:"Retry",loadFailed:"Failed to load",empty:"No usage data yet",weekLimit:"Weekly limit",genericLimit:"Limit",hourLimit:"{n}h limit",dayLimit:"{n}d limit",minuteLimit:"{n}m limit",resetsIn:"resets in {duration}",resetDone:"reset",durationDay:"{n}d",durationHour:"{n}h",durationMinute:"{n}m",durationSecond:"{n}s",usedPct:"{pct}% used",boosterTitle:"Booster",boosterBalance:"Balance",monthlyUsed:"Used this month",monthlyLimit:"Monthly limit",unlimited:"Unlimited",freeTitle:"Free account",freeHint:"Upgrade to a membership to use Kimi models and see plan usage"},colorSchemeHint:"Choose the app’s light or dark appearance",appIcon:"Dock icon",appIconHint:"Choose the icon shown in the Dock",appIconDefault:"Default",appIconBlack:"Black",uiFontSize:"Font size",uiFontSizeHint:"Adjust interface and message text size",vibrancy:"Frosted sidebar",vibrancyHint:"Use the native macOS frosted-glass material behind the sidebar — turn it off if the translucency is hard to read",languageHint:"Choose the interface language",defaultOpenInApp:"Default open-in app",defaultOpenInAppHint:"App used when opening files and folders from the header menu",openWith:"Open with",agentDefaults:"Agent defaults",saving:"Saving",defaultModel:"Default model",defaultModelHint:"New sessions prefer this model",noDefaultModel:"No default model",defaultPermission:"Default permission",defaultPermissionHint:"Only affects newly-created sessions",defaultThinking:"Thinking by default",defaultThinkingHint:"Whether new sessions start with thinking enabled",defaultPlanMode:"Plan mode by default",defaultPlanModeHint:"Whether new sessions start in plan mode",secondaryModelSection:"Subagents",secondaryModel:"Subagent model",secondaryModelHint:"Model and thinking effort that subagents use by default",secondaryModelEffort:"Thinking effort",noSecondaryModel:"Not set (inherit primary)",secondaryModelEffortAuto:"Model default",telemetry:"Improve product with usage data",telemetryHint:"When on, we collect anonymous interaction data (such as clicks, interruptions, and feature usage) to improve the product experience. You can turn it off at any time.",telemetryRestartHint:"Takes effect after restarting the service.",credentialReady:"Credential configured",credentialMissing:"Missing credential",configUnavailable:"The server did not return config yet. These settings are unavailable.",versionAndUpdates:"Version & updates",appVersion:"App version",appVersionHint:"The running app’s version and build time",checkUpdate:"Check for updates",checkUpdateHint:"Manually check whether a new version is available",checkUpdateBtn:"Check now",updateChecking:"Checking…",updateCheckLatest:"You’re on the latest version",updateCheckAvailable:"Version {version} is available — download it from the update entry in the sidebar",updateCheckUnsupported:"This build does not support update checks",updateCheckFailed:"Check failed. Please try again later.",updateCheckAvailableAuto:"Version {version} found — downloading in the background",updateCheckDownloaded:"Version {version} is ready — restart from the update entry in the sidebar",autoDownloadUpdate:"Auto-download updates",autoDownloadUpdateHint:"Download new versions in the background and install them on the next restart",privacy:"Data & privacy",diagnostics:"Diagnostics",build:"Build",serverVersion:"Server version",serverAddress:"Server address",serverAddressHint:"The address of the connected server",serverVersionHint:"The version of the connected service",exportLog:"Troubleshooting log",exportLogHint:"Export the troubleshooting log collected by the app",logHint:"Enable with ?debug=1 to capture",exportLogBtn:"Export log",archivedTitle:"Archived sessions",archivedDesc:"Browse archived sessions, see their workspace path, name, and archive time, and restore them to the session list.",archivedSearch:"Search archived sessions",archivedAllWorkspaces:"All workspaces",archivedSortLabel:"Sort by",archivedSortArchived:"Archive time",archivedSortCreated:"Created time",archivedSortName:"Name",archivedRestore:"Restore",archivedEmpty:"No archived sessions yet",archivedNoMatch:"No matching archived sessions",archivedSessionsCount:"{count} sessions",archivedAt:"Archived {time}",archivedLoadMore:"Load more",archivedLoading:"Loading…",archivedLoadingAll:"Loading all archived sessions…"},WH={openInEditor:"Open in editor",openInEditorShort:"Open",openInApp:"Open in {app}",chooseOpenApp:"Choose application",copyAll:"Copy all as Markdown",copyFinalSummary:"Copy final summary",copied:"Copied",lastUsed:"Last used",copyPath:"Copy path",changed:"{n} changed",gitTooltip:"Open Files > Changed",detached:"detached",openPr:"Open pull request",prStatusOpen:"open",prStatusClosed:"closed",prStatusMerged:"merged",prStatusDraft:"draft",prStatusUnknown:"unknown",options:"Options",copySessionId:"Copy session ID",renameSession:"Rename",forkSession:"Fork session",archiveSession:"Archive",exportSession:"Export session",devBadge:"Running in development mode"},UH={title:"Side chat",subtitle:"forked from this session",empty:"Ask a quick question on the side — it shares this session’s context.",placeholder:"Ask the side chat…",send:"Send"},jH={actions:{summonApp:{label:"Show App Window",desc:"Bring the app window to the foreground from anywhere"},newSession:{label:"New Session",desc:"Start a new session in the current workspace"},searchSessions:{label:"Search Chats",desc:"Open the session search dialog"},archiveSession:{label:"Archive Chat",desc:"Archive the current chat right away"},toggleSideChat:{label:"Toggle Side Chat",desc:"Open or close the /btw side chat"},toggleSidebar:{label:"Toggle Sidebar",desc:"Collapse or expand the session sidebar"},openFolder:{label:"Open Folder",desc:"Add a workspace folder with the native picker"},openInDefaultApp:{label:"Open in App",desc:"Open the workspace in your default editor/terminal"},openSettings:{label:"Open Settings",desc:"Show or hide the settings dialog"},toggleTerminal:{label:"Toggle Terminal",desc:"Show or hide the bottom terminal panel"},send:{label:"Send Message",desc:"Send the composer input"},newline:{label:"Newline",desc:"Insert a newline in the composer"}},searchPlaceholder:"Search shortcuts",unassigned:"Unassigned",unassign:"Unassign shortcut",edit:"Edit shortcut",reset:"Reset to default",resetAll:"Reset all to defaults",recording:"Press the new shortcut…",invalid:"This key combination can’t be used as a shortcut",notGlobal:"This key combination can’t be registered as a system-wide shortcut",globalTaken:"This shortcut is already taken by the system or another app",reserved:"Reserved by the system menu",reservedSteer:"Reserved for steer (Ctrl/Cmd+S)",reservedFind:"Reserved for transcript find (Ctrl/Cmd+F)",conflict:"Already used by “{action}”",customBadge:"Custom"},VH={panelAria:"Terminal",toolbarAria:"Terminal tabs",resizeAria:"Resize terminal panel height",toggle:"Toggle terminal",newTab:"New terminal",closeTab:"Close terminal",restartTab:"Restart terminal",collapse:"Collapse terminal panel",empty:"No terminal yet — click to start one",processExited:"[process exited]",processExitedWithCode:"[process exited with code {code}]"},qH={common:mH,app:gH,sidebar:vH,workspace:yH,conversation:kH,status:bH,composer:CH,login:wH,providers:_H,model:xH,sessions:SH,approval:AH,question:MH,tasks:TH,thinking:EH,diff:IH,fileTree:LH,filePreview:$H,mention:NH,warnings:FH,commands:RH,tools:OH,layout:PH,mobile:DH,theme:BH,onboarding:HH,settings:zH,header:WH,sideChat:UH,shortcuts:jH,terminal:VH},KH={preview:"预览",confirm:"确认",cancel:"取消",close:"关闭",dismiss:"关闭",loading:"加载中",copy:"复制"},ZH={authBannerMessage:"未登录 · 需要登录 Kimi Code 才能开始对话",authBannerLogin:"登录",connecting:"连接中…",internalBuildBanner:"仅供内部测试",menuFile:"文件",menuEdit:"编辑",menuView:"视图",menuHelp:"帮助",applicationMenu:"应用菜单"},GH={workspaceMeta:"workspace · {branch}",sessionsHeader:"会话",workspaces:"工作区",viewSwitcher:"视图选项",viewGroup:"视图",viewFlat:"平铺列表",viewGrouped:"按工作区分组",collapseAll:"折叠全部工作区",expandAll:"展开全部工作区",newSession:"新建会话",newChat:"新建会话",newWorkspace:"新建工作区",dropToAddWorkspace:"松开鼠标添加工作区",emptyState:"还没有会话 · 点击 新建会话 开始",options:"选项",rename:"重命名",setEmoji:"设置 Emoji…",sessionEmojiTitle:"选择 Emoji",removeEmoji:"移除 Emoji",randomEmoji:"随机",searchEmoji:"搜索 Emoji",recentEmojis:"最近使用",noEmojiResults:"没有匹配的 Emoji",emojiGroupFaces:"笑脸与人物",emojiGroupNature:"动物与自然",emojiGroupFood:"美食饮品",emojiGroupActivity:"活动与出行",emojiGroupObjects:"物品与工作",emojiGroupSymbols:"符号与状态",copyPath:"复制路径",copySessionId:"复制 Session ID",copied:"已复制 ✓",copyFailed:"复制失败",archive:"归档",archiveToastUndo:"撤销",archiveToastMid:"或到",archiveToastSettings:"设置",archiveToastTail:"查看已归档的会话",fork:"分叉会话",export:"导出会话",pin:"置顶",unpin:"取消置顶",pinned:"置顶",collapsePinned:"折叠置顶区",expandPinned:"展开置顶区",delete:"删除",removeWorkspace:"移除工作区",brand:"Kimi Code",signedIn:"已登录",signOut:"退出登录",notSignedIn:"未登录",signIn:"登录",defaultUserName:"Kimi 用户",upgrade:"升级",logoutConfirmTitle:"退出登录",logoutConfirmMessage:"确定要退出当前账号吗?",language:"语言",backendTitle:"后端 {backend} · {endpoint} — 点击切换",noSessions:"暂无对话",allPinned:"有 {count} 条对话被置顶",showMore:"展开更多",loadMore:"加载更多",showLess:"收起",loadingMore:"加载中…",collapseSidebar:"收起侧边栏",expandSidebar:"展开侧边栏",searchPlaceholder:"搜索会话",search:"搜索",searchHint:"↑↓ 选择 · ↵ 打开 · Esc 关闭",searchHintSelect:"选择",searchHintOpen:"打开",searchHintClose:"关闭",searchClear:"清除搜索",searchNoResults:"没有匹配的会话",searchEmpty:"暂无会话",update:"更新",updateAvailable:"发现新版本 v{version}",updateDownloading:"下载中… {percent}%",updateReady:"v{version} 已就绪",updateDone:"重启并更新",updateFailed:"下载失败",updateRetry:"重试",updateDownloadNow:"下载并更新",updateSkip:"本次跳过",updateRestartNow:"立即重启",updateRestartLater:"下次启动",updateReleaseDate:"发布于 {date}",updateCurrentVersion:"当前版本 v{version}",updateWhatsNew:"更新内容",updateBackground:"后台下载",updateAutoDownload:"以后自动下载并安装更新"},YH={switcherTitle:"切换工作区",switchTooltip:"切换工作区",eyebrow:"工作区",branchLabel:"分支: {branch}",noBranch:"无分支",sessionCount:"{count} 个会话",allWorkspaces:"全部工作区",currentWorkspace:"仅当前工作区",addWorkspace:"添加工作区…",noWorkspace:"暂无工作区",deleteHasSessions:"工作区内还有会话,请先归档这些会话再删除",removeWorkspaceConfirm:"移除工作区「{name}」?",swarmEnableTitle:"启用 swarm 模式?",swarmEnableConfirm:"Agent 将并行运行多个子 agent。",goalStartTitle:"启动 goal?",goalStartConfirm:"「{objective}」——Agent 将自主执行。",scopeCurrent:"当前工作区",scopeAll:"全部工作区",newInGroup:"在此工作区新建会话",addTitle:"添加工作区",pathLabel:"路径",pathPlaceholder:"/项目的绝对路径",recentLabel:"最近的文件夹",add:"添加",cancel:"取消",addHint:"粘贴一个绝对路径,或从最近用过的文件夹中选择。",addFailed:"无法打开此文件夹,请检查路径后重试。",requiredTitle:"请先选择工作空间",requiredMessage:"发送消息前,需要先选择一个文件夹作为工作区。",openThisFolder:"打开此文件夹",up:"上一级",browsing:"加载中…",filterPlaceholder:"过滤子文件夹…",searchPlaceholder:"在此目录下模糊搜索…",searching:"搜索中…",pasteToggle:"直接输入绝对路径",noFilterMatch:"没有匹配「{q}」的子文件夹",noSubfolders:"此处没有子文件夹",browseHint:'点击文件夹进入,再点"打开此文件夹"将其添加为工作区。',attentionTitle:"{count} 项待处理",awaitingAnswer:"待回答",awaitingAnswerTitle:"有提问等待你回答",awaitingPermission:"待授权",awaitingPermissionTitle:"有操作等待你授权",aborted:"失败",abortedTitle:"此会话的上一轮对话因错误中断"},XH={jumpToLatestAria:"跳到最新消息",toc:"对话目录",newMessages:"最新消息",loading:"加载中…",starting:"正在创建对话…",requesting:"请求中…",working:"工作中…",workingRetry:"模型请求失败,正在重试(第 {n}/{max} 次)…",emptyWorkspaceHint:"在 {name} 中发送",switchWorkspace:"切换工作区",addWorkspace:"添加工作区",moreWorkspaces:"更多工作区 ({count})",pickFolder:"选择文件夹…",compacting:"正在压缩上下文…",compactedPlain:"上下文已压缩",compactedAuto:"已自动压缩上下文",compactedTokens:"({before} → {after} tokens)",viewSummary:"查看摘要",summaryTitle:"压缩摘要",activatedSkill:"已激活技能: {name}",undo:"撤销",undoTooltip:"撤回编辑",undoConfirm:"撤销上一条消息?",escUndoHintPre:"再按",escUndoHintPost:"撤销本条",undone:"已撤销,原文已放回输入框",turnInterrupted:"已手动终止",turnFailed:"模型请求失败,本轮对话已中断",turnFailedMaxSteps:"达到本轮步数上限,对话已中断",turnFailedResume:"继续",turnFailedResumeText:"继续",yesterday:"昨天",loadOlder:"加载更早的消息",loadingOlder:"正在加载更早的消息…",widenTable:"加宽表格",restoreTableWidth:"恢复默认宽度",cron:{fired:"定时任务已触发",missed:"错过的定时提醒",job:"任务 {id}",oneShot:"单次",coalesced:"已合并 {n} 次触发",missedCount:"错过 {n} 次",finalDelivery:"最后一次投递",expand:"展开",collapse:"收起"},fold:{worked:"已工作 {duration}",workedUnknown:"工作过程"},turnFiles:{titleOne:"{number} 个文件已修改",titleOther:"{number} 个文件已修改",more:"还有 {number} 个文件",moreOne:"还有 1 个文件",showLess:"收起",diffTitle:"本次改动",diffUnavailable:"此文件的改动无法逐项展示",openFile:"打开文件"},goal:{continuation:"目标续跑"},notification:{kindTask:"后台任务",kindSubagent:"子代理",title:{completed:"{kind}完成",failed:"{kind}失败",timed_out:"{kind}超时",killed:"{kind}被终止",lost:"{kind}丢失",info:"{kind}通知"},status:{completed:"完成",failed:"失败",timed_out:"超时",killed:"已终止",lost:"丢失",info:"信息"},groupTitle:"{n} 条通知",copyPath:"复制路径",copied:"已复制",rawPayload:"原始 payload",fields:{type:"类型",source:"来源",severity:"严重度"}},userMessage:{expand:"展开",collapse:"收起"},search:{placeholder:"搜索对话…",searching:"搜索中…",results:"{current}/{total} 条结果",resultsCapped:"{current}/{total}+ 条结果",noResults:"无结果",previous:"上一个匹配",next:"下一个匹配",close:"关闭搜索"}},JH={connectionConnected:"已连接",connectionConnecting:"连接中…",connectionDisconnected:"未连接",ctxTooltip:"使用 {used} / {max} tokens ({pct}%)",modelLabel:"模型",permissionManual:"逐条确认",permissionAuto:"完全自主",permissionYolo:"自动通过",permissionManualDesc:"每个工具操作都需要你手动确认",permissionAutoDesc:"完全自主运行,智能体自己做决定,不再询问",permissionYoloDesc:"自动批准工具操作,但遇到关键问题仍会询问",planLabel:"计划",planDesc:"先让智能体梳理计划,再修改文件",planOn:"开",planOff:"关",planTooltip:"切换计划模式(先调研再修改)",modesLabel:"模式",goalLabel:"目标",goalDesc:"持续跟踪一个目标,直到任务完成",swarmLabel:"Swarm",swarmDesc:"并行运行多个智能体,适合大范围探索",modeOff:"未启用",goalPlaceholder:"让智能体完成什么目标?",goalStart:"开始",goalPause:"暂停",goalResume:"继续",goalCancel:"取消",goalCancelConfirm:"是否需要取消当前目标?取消后将无法恢复。",goalCancelConfirmYes:"是",goalCancelConfirmNo:"否",goalDoneWhen:"完成条件",goalStatusActive:"进行中",goalStatusPaused:"已暂停",goalStatusBlocked:"已阻塞",goalStatusComplete:"已完成",modeNotSupported:"暂不支持",thinkingLabel:"思考",thinkingTooltip:"切换思考模式",thinkingOn:"开",thinkingOff:"关",cacheNote:"提示:切换模型或思考程度会使已有的提示词缓存失效。建议新建会话,避免额外的 token 消耗。",starredModels:"收藏",moreModels:"更多模型…",statusPanelTitle:"会话状态",statusPanelClose:"关闭",statusModel:"模型",statusThinking:"思考强度",statusPermission:"权限",statusPlanMode:"计划模式",statusSwarmMode:"Swarm 模式",swarmOn:"开",swarmOff:"关",statusContext:"上下文",statusCost:"花费",statusContextValue:"{used} / {max} ({pct}%)",statusNone:"—",activityRunning:"运行中…",activityAwaitingApproval:"等待批准",activityAwaitingQuestion:"等待回答",interrupt:"中断",runningShort:"进行中"},QH={placeholder:"输入消息…",send:"发送 ↵",queueLabel:"队列",placeholderRunning:"输入会加入队列 · Ctrl+S 立即插入运行中的回合",starting:"正在发送…",queueAutoDrain:"当前回合结束后自动逐条发送",queueNext:"下一条",queueDragTitle:"拖拽排序",editQueued:"编辑(载入到输入框)",queuedAttachments:"附件 ×{n}",queuedHasImage:"包含 {n} 张图片 — 只能移除,不能编辑",attachmentImage:"图片",attachmentVideo:"视频",attachmentFile:"文件",attachmentOpenUnsupported:"无法打开 {name}:暂不支持此文件类型",dropToAttach:"松开鼠标添加附件",remove:"移除",removeNamed:"移除 {name}",clearAll:"清空全部附件",attachmentCount:"共 {n} 个附件",uploading:"上传中",uploadFailed:"上传失败",attachFile:"添加附件",previewAttachment:"预览 {name}",interrupt:"中断",interruptTitle:"中断当前操作",expandTitle:"展开输入框进行多行编辑",collapseTitle:"收起输入框",emptyConversationTitle:"Kimi Code",emptyConversation:"还没有消息 —— 在下方输入开始对话",upgradeBanner:"升级你的 Kimi 账户来使用 Kimi Code",quickStartPlaceholder:"输入消息开始新对话…",thinkingSuffix:" · 思考",thinkingSuffixEffort:" · {level}"},ez={title:"登录 Kimi Code",close:"关闭 (Esc)",starting:"正在启动登录流程…",lead:"点击下方按钮,在新标签页中完成登录。",authorizeInBrowser:"在浏览器中登录",orDivider:"或者",fallbackPrefix:"换个设备?在浏览器打开 ",fallbackSuffix:" 输入设备码:",copy:"复制",copied:"已复制",copyLink:"复制链接",waitingAuth:"等待登录",waitingAutoClose:"等待登录,完成后自动关闭…",success:"已登录",successHint:"正在加载,稍后自动关闭…",expiredTitle:"设备码已过期",expiredHint:"请重新开始登录流程",retry:"重试",closeBtn:"关闭",errorTitle:"当前版本暂不支持登录",errorHint:"请升级 kimi-code 后重试",pollErrorTitle:"连接已断开",pollErrorHint:"登录轮询连续失败,请检查 kimi-code 进程后重试",action:"登录",requiredTitle:"请先登录",requiredMessage:"登录 Kimi 账号并配置模型后,才能开始对话。",goToLogin:"去登录",upgradeRequiredTitle:"请升级会员",upgradeRequiredMessage:"当前为免费账户,升级会员后即可使用 Kimi 模型开始对话。"},tz={title:"供应商管理",loading:"加载提供商中…",unavailable:"暂不支持提供商管理",empty:"暂无提供商",status:{connected:"已连接",error:"错误",unconfigured:"未配置"},keySet:"key 已设置",keyNotSet:"未设置 key",managedBadge:"OAuth",modelCount:"{count} 个模型",confirmDelete:"确认删除?",refresh:"刷新",delete:"删除",refreshTitle:"刷新 {type}",deleteTitle:"删除 {type}",loginKimi:"登录 Kimi",loginAnthropic:"登录 Anthropic",addProvider:"添加供应商",added:"已添加",enterApiKey:"填写 API Key",optional:"可选",apiKeyRequired:"API Key 不能为空",fieldId:"名称",fieldType:"API 协议",types:{kimi:"Kimi",openai:"OpenAI",openai_responses:"OpenAI Responses",anthropic:"Anthropic","google-genai":"Google GenAI",vertexai:"Vertex AI"},fieldApiKey:"API Key",apiKeyManaged:"OAuth 托管登录",apiKeySet:"已设置,输入以更换",showApiKey:"显示 API Key",hideApiKey:"隐藏 API Key",fieldBaseUrl:"Base URL",baseUrlPlaceholder:"https://api.example.com/v1",fieldModels:"模型",colModelId:"模型 ID",colContext:"上下文",colDisplayName:"显示名",modelIdPlaceholder:"kimi-k3",modelContextPlaceholder:"1048576",modelNamePlaceholder:"可选",noModels:"暂无模型",addModel:"添加模型",removeModel:"移除模型",fieldDefaultModel:"默认模型",save:"保存",saved:"已保存",deleteProvider:"删除供应商",deleteConfirm:"确认删除 {id} 及其 {count} 个模型?",deleteConfirmYes:"确认删除",managedHint:"托管供应商在账户页登录 / 登出",unsavedGuard:"有未保存的修改。",guardStay:"继续编辑",guardDiscard:"丢弃",add:"添加",catalog:{sourceCatalog:"从目录添加",sourceManual:"手动添加",sourceRegistry:"注册表",registryHint:"从 api.json 注册表导入供应商与模型;同一 URL 重复导入即为刷新",registryUrlLabel:"注册表 URL",registryImported:"已导入 {count} 个供应商",searchPlaceholder:"搜索供应商",loading:"加载目录中…",loadError:"目录加载失败,请检查网络后重试",retry:"重试",empty:"没有匹配的供应商",rejected:"不可导入",rejectReason:{"unknown-explicit-type":"协议不受支持","proprietary-sdk":"私有协议,无法导入","empty-base-url":"Base URL 为空","placeholder-base-url":"端点包含环境变量占位符"},backToList:"返回目录列表",willImport:"将从目录导入 {count} 个模型",overwriteWarning:"已存在同名供应商,导入将覆盖其配置与模型",importAction:"导入"},error:{idRequired:"名称不能为空",idInvalid:'名称需以字母或数字开头,只能包含字母、数字、"-"、"_" 和空格',apiKeyRequired:"API Key 不能为空",baseUrlRequired:"Base URL 不能为空",registryUrlRequired:"注册表 URL 不能为空",modelRequired:"模型 ID 不能为空",contextSizeRequired:"上下文长度不能为空",contextSizeInvalid:"上下文长度需为正整数"},hintClose:"关闭"},nz={dialogLabel:"切换模型",title:"切换模型",close:"关闭 (Esc)",allTab:"全部",providerTabs:"模型提供商",searchPlaceholder:"搜索模型或提供商…",clearSearch:"清除搜索",loading:"加载模型中…",unavailable:"暂无可用模型列表",contextSuffix:"{size} ctx",capabilityImageInput:"图片输入",capabilityVideoInput:"视频输入",capabilityToolUse:"工具调用",capabilityThinking:"思考",capabilityAlwaysThinking:"始终思考",emptyNoModels:"暂无可用模型",emptyNoMatch:"无匹配模型",starTitle:"添加到收藏",unstarTitle:"取消收藏",hintNavigate:"导航",hintSelect:"选择",hintClose:"关闭"},oz={justNow:"刚刚"},sz={title:{shell:"运行命令?",diff:"应用修改?",file:"写入文件?",fileop:"文件操作?",url:"抓取 URL?",search:"搜索?",invocation:"调用?",todo:"更新 todo?",plan_review:"按这份 plan 开始实现?",generic:"批准操作?"},subagentBadge:"子 agent · {name}",danger:"危险: {detail}",searchQueryLabel:"查询",searchScope:"范围:{scope}",feedbackPlaceholder:"说明拒绝原因… (Enter 提交, Esc 取消)",feedbackHint:"Enter 提交 · Esc 取消",approve:"批准",approveSession:"本会话内批准",reject:"拒绝",feedback:"反馈",feedbackSubmit:"提交并拒绝",feedbackCancel:"取消",approvePlan:"批准 plan",revise:"修改",rejectAndExit:"拒绝并退出",expandPlan:"放大",collapsePlan:"还原"},iz={back:"‹ 上一题",nextQuestion:"下一题 ›",otherDefault:"其他…",submit:"提交",dismiss:"放弃",minimize:"最小化",expand:"展开",hint:"↑↓ 选择 · Enter 确认"},rz={tag:"任务",summary:"{run} 运行中 · {done} 完成",copy:"复制",calling:"调用 {label}",fieldTask:"任务",fieldOutput:"输出",fieldProgress:"进度",fieldResult:"结果",moreLines:"…(还有 {count} 行)",copied:"已复制",stop:"stop",defaultDescription:"后台任务",dockTasks:"后台任务",dockBash:"后台 Bash",dockSubagent:"子 Agent",dockTodos:"待办",running:"运行中",closePanel:"关闭面板",timingRunning:"运行中 · {time}",timingDone:"完成 · {sec}s",emptyTasks:"暂无后台任务",emptyBash:"暂无后台 Bash 任务",emptySubagent:"暂无子 Agent 任务",emptyTodo:"暂无待办事项",openTab:"查看全部后台任务",openDetail:"查看",collapse:"折叠",expand:"展开",transcriptLoadError:"无法加载这个子 Agent 的对话。"},lz={panelTitle:"思考过程",streaming:"思考中…",close:"关闭"},az={title:"改动",branch:"分支",aheadTitle:"领先远程",behindTitle:"落后远程",fileCountOne:"{number} 个文件",fileCountOther:"{number} 个文件",empty:"无 git 改动",clean:"工作区干净,无改动",back:"返回",loading:"正在加载 diff…",noDiff:"该文件没有行级改动",emptyFile:"空文件",list:"列表",tree:"树形",close:"关闭"},uz={},cz={empty:"选择左侧文件预览",loading:"加载中…",lineCount:"{count} 行",copy:"复制",copied:"已复制",copyPath:"复制路径",openInEditor:"打开",reveal:"显示",download:"下载",close:"关闭",search:"搜索",prevMatch:"上一个匹配",nextMatch:"下一个匹配",htmlMode:"HTML 预览模式",markdownMode:"Markdown 预览模式",preview:"预览",source:"源码",imageFit:"图片缩放",fit:"适应",actual:"原始",pdfNoPreview:"无法内嵌预览此 PDF,可以下载后查看",imageNoPreview:"图片文件 · {mime} · {size} · 暂不预览",binaryNoPreview:"二进制文件 · {mime} · {size} 字节 · 暂不预览",unknownType:"未知类型",copyCode:"复制代码",enlargeImage:"放大图片",errors:{emptyPath:"文件路径为空",unsupportedPath:"不支持预览 URL 或远程路径",outsideWorkspace:"只能预览当前 workspace 内的文件",isDirectory:"请选择具体文件,而不是目录",notFound:"文件不存在或已被移动",tooLarge:"文件过大,暂不支持预览",loadFailed:"无法读取这个文件"}},dz={searching:"搜索中…",noMatch:"无匹配"},fz={dismiss:"关闭",errorLabel:"错误",noteLabel:"提示",agentWarningFallback:"agent 警告",unhandledEvent:"未处理的事件:{type}",agentError:{title:"模型请求失败",connection:"无法连接模型服务",auth:"模型认证失败",rateLimit:"模型请求被限流",overloaded:"模型服务过载",filtered:"响应被提供方过滤",api:"模型接口返回错误",contextOverflow:"上下文超出模型限制"},details:{cause:"底层原因",code:"错误码",connection:"连接状态",contentType:"响应类型",details:"服务端详情",duration:"耗时",endpoint:"请求地址",errorName:"错误类型",message:"错误信息",operation:"操作",phase:"失败阶段",request:"请求",requestId:"Request ID",responsePreview:"响应预览",sessionId:"Session ID",stack:"堆栈",status:"HTTP 状态",timeout:"超时设置",timestamp:"时间"},daemonApiTitle:"Kimi 服务器返回错误",daemonNetworkMessage:"Web 没有拿到 Kimi 服务器的响应。请确认它仍在运行,或刷新页面重试。",daemonNetworkTitle:"无法连接到 Kimi 服务器",diagnostics:"诊断信息",hideDetails:"收起详情",operationFailedMessage:"刚才的操作没有完成,请稍后重试。",operationFailedTitle:"操作失败",sessionSnapshotMessage:"Web 没能加载当前会话内容。请确认 Kimi 服务器仍在运行,或刷新页面重试。",sessionSnapshotTitle:"无法加载当前会话内容",showDetails:"查看详情",copyDetails:"复制诊断信息",copied:"已复制",wsTitle:"实时连接出错",goal:{alreadyExists:"当前会话已有一个进行中的目标,请先取消它再创建新目标。",notFound:"没有找到可操作的目标,可能它已经结束或被取消。",statusInvalid:"当前目标状态不支持这个操作。",notResumable:"这个目标无法恢复(可能已取消或已完成)。",objectiveTooLong:"目标描述太长了,请精简后重试。"}},pz={new:{desc:"创建新会话"},clear:{desc:"清空并新建会话"},login:{desc:"在浏览器中登录 Kimi"},plan:{desc:"切换计划模式 开/关"},swarm:{desc:"切换 swarm 模式;/swarm <任务> 直接在 swarm 下执行"},goal:{desc:"创建/控制目标:/goal <目标>、/goal pause{'|'}resume{'|'}cancel"},btw:{desc:"侧边聊天:/btw <问题> 向 fork 的侧边会话提问"},yolo:{desc:"自动批准工具操作,Agent 仍可能提问"},auto:{desc:"完全自主,Agent 不再提问"},thinking:{desc:"设置思考强度"},compact:{desc:"压缩会话历史"},fork:{desc:"把当前会话 fork 出一个新会话"},export:{desc:"将当前会话和排障日志下载为 ZIP 压缩包",noSession:"请先打开一个会话再导出。"},status:{desc:"查看会话状态"},undo:{desc:"撤销上一条消息"}},hz={label:{read:"读取",bash:"运行",edit:"编辑",write:"写入",grep:"搜索",glob:"查找",ls:"列目录",web_fetch:"抓取",search:"搜索",todo:"待办",task:"任务",swarm:"Swarm",ask_user:"提问",plan:"计划",goal_create:"启动目标",goal_get:"读取目标",goal_budget:"设置目标预算",goal_update:"更新目标"},swarm:{progress:"{done} / {total}",runningSub:"{count} 个进行中",doneSub:"完成 {completed} · 失败 {failed}",phaseQueued:"排队",phaseWorking:"运行中",phaseSuspended:"暂停",phaseCompleted:"完成",phaseFailed:"失败",waiting:"等待子任务加入…"},chip:{lines:"{count} 行",results:"{count} 结果",files:"{count} 个文件",edited:"已编辑",created:"已创建",todos:"{count} 项"},disclosure:{expand:"展开详情",collapse:"收起详情"},output:{waiting:"等待输出…",empty:"(无输出)",saved:"已保存的结果"},plan:{review:{pending:"待确认",approved:"已通过",rejected:"已拒绝",cancelled:"已取消"},selectedOption:"已选择",feedback:"反馈"},summary:{inScope:"{value} 在 {scope} 中"},goal:{objectiveWithCriterion:"{objective} · {criterion}",status:"状态:{status}",budget:"{value} {unit}",turns:"{value} 轮",tokens:"{value} token",milliseconds:"{value} 毫秒",seconds:"{value} 秒",minutes:"{value} 分钟",hours:"{value} 小时"},group:{countOther:"执行了 {count} 次工具调用",typed:{read:{done:"读取了 {count} 个文件"},bash:{done:"运行了 {count} 条命令"},grep:{done:"搜索了 {count} 个模式"},search:{done:"网络搜索了 {count} 次"},glob:{done:"找了 {count} 次文件"},ls:{done:"列出了 {count} 个目录"},web_fetch:{done:"抓取了 {count} 个页面"},edit:{done:"编辑了 {count} 处"},write:{done:"写入了 {count} 个文件"}}},activity:{failedClause:"({count} 失败)",liveDonePrefix:"已",busy:"正在执行…",doing:{read:"正在读取 {subject}",bash:"正在运行 {subject}",grep:"正在搜索 {subject}",search:"正在搜索 {subject}",glob:"正在匹配 {subject}",ls:"正在列出 {subject}",web_fetch:"正在抓取 {subject}",edit:"正在编辑 {subject}",write:"正在写入 {subject}"}},ask:{dismissed:"已忽略",answer:"{count} 个回答",answers:"{count} 个回答",answered:"已回答",more:"(还有 {count} 个)",collected:"已收集回答",question:"{count} 个问题",questions:"{count} 个问题",freeInput:"(自由输入)",unanswered:"未作答"}},mz={resizeHandleAria:"调整侧栏宽度",resizePreviewAria:"调整预览面板宽度",detailPanelAria:"详情面板"},gz={openSwitcher:"切换会话 / 工作区",openSettings:"会话设置",settingsTitle:"会话设置",groupSession:"当前会话",groupApp:"应用偏好",sheetLabel:"面板",closeSheet:"关闭",tapToCycle:"点击切换",running:"运行中",idle:"空闲",sessionCount:"{n} 个会话",newSession:"新建会话",permManualSub:"每个工具都确认",permAutoSub:"完全自主,不再提问",permYoloSub:"自动批准工具,仍可能提问",planModeSub:"计划模式",swarmModeSub:"Swarm 模式",archivedSessions:"已归档会话",archivedSessionsSub:"查看并恢复已归档会话",archivedBack:"返回"},vz={colorSchemeLabel:"外观",light:"月之亮面",dark:"月之暗面",system:"跟随系统"},yz={continue:"继续",back:"上一步",skip:"跳过",welcome:{title:"欢迎使用 Kimi Code",subtitle:"为专业开发者打造的 AI 编程工作台",languageLabel:"语言",themeLabel:"外观"},login:{title:"选择配置模型",subtitle:"选择驱动 Kimi Code 的模型服务,之后可在「设置」中更改。",kimiTitle:"登录 Kimi 账号",kimiHint:"使用 Kimi 会员权益,开箱即用",recommended:"推荐",customProviderTitle:"添加自定义供应商",customProviderHint:"使用自己的 API Key,接入 OpenAI 兼容等模型服务",loggedInTitle:"已登录 Kimi 账号",loggedInHint:"模型服务已就绪,可以开始使用",finish:"完成",skip:"跳过,稍后再说"}},kz={title:"设置",internalTest:"内部测试",close:"关闭 (Esc)",tabs:{general:"通用",agent:"Agent",account:"账户",providers:"供应商",advanced:"高级",archived:"已归档",shortcuts:"快捷键"},appearance:"外观",notifications:"通知",notifyEnabled:"系统通知",notifyEnabledHint:"回合完成、待回答或待审批时发送系统通知",notifySound:"通知提示音",notifySoundHint:"系统通知随附提示音",notifyDenied:"已在浏览器设置中被阻止",notifyTitle:"Kimi Code · 回合完成",notifyQuestionTitle:"Kimi Code · 待回答",notifyApprovalTitle:"Kimi Code · 等待审批",notifyFallback:"点击查看结果",notifyQuestionFallback:"有提问等待你回答",notifyApprovalFallback:"有工具等待你审批",account:"账户",signedIn:"已登录",signedOutHint:"登录后可查看账户和模型权益",planUsage:{title:"套餐用量",retry:"重试",loadFailed:"加载失败",empty:"暂无用量数据",weekLimit:"每周限额",genericLimit:"限额",hourLimit:"{n} 小时限额",dayLimit:"{n} 天限额",minuteLimit:"{n} 分钟限额",resetsIn:"{duration}后重置",resetDone:"已重置",durationDay:"{n} 天",durationHour:"{n} 小时",durationMinute:"{n} 分钟",durationSecond:"{n} 秒",usedPct:"已用 {pct}%",boosterTitle:"加油包",boosterBalance:"余额",monthlyUsed:"本月已用",monthlyLimit:"每月上限",unlimited:"不限",freeTitle:"免费账户",freeHint:"升级会员后即可使用 Kimi 模型并查看套餐用量"},colorSchemeHint:"选择应用的明暗外观",appIcon:"程序坞图标",appIconHint:"选择程序坞中显示的图标",appIconDefault:"默认",appIconBlack:"黑色",uiFontSize:"字体大小",uiFontSizeHint:"调整界面和消息文字大小",vibrancy:"毛玻璃侧栏",vibrancyHint:"在侧栏使用 macOS 原生毛玻璃材质——如果半透明影响阅读可以关闭",languageHint:"选择界面显示语言",defaultOpenInApp:"默认打开应用",defaultOpenInAppHint:"从顶栏菜单打开文件和文件夹时默认使用的应用",openWith:"打开方式",agentDefaults:"Agent 默认值",saving:"保存中",defaultModel:"默认模型",defaultModelHint:"新会话会优先使用这个模型",noDefaultModel:"未设置默认模型",defaultPermission:"默认权限",defaultPermissionHint:"只影响之后新建的会话",defaultThinking:"默认开启思考",defaultThinkingHint:"新会话默认是否开启思考",defaultPlanMode:"默认计划模式",defaultPlanModeHint:"新会话默认进入计划模式",secondaryModelSection:"子智能体",secondaryModel:"子智能体模型",secondaryModelHint:"子智能体默认使用的模型与思考强度",secondaryModelEffort:"思考强度",noSecondaryModel:"未设置(跟随主模型)",secondaryModelEffortAuto:"模型默认",telemetry:"使用数据改进产品",telemetryHint:"开启后,我们会收集您的匿名交互数据(如点击、打断、功能使用等),用于改进产品体验。您可以随时关闭。",telemetryRestartHint:"更改后需重启服务生效。",credentialReady:"凭据已配置",credentialMissing:"缺少凭据",configUnavailable:"当前服务端没有返回 config,设置项暂不可用。",versionAndUpdates:"版本与更新",appVersion:"应用版本",appVersionHint:"当前应用的版本号和构建时间",checkUpdate:"检查更新",checkUpdateHint:"手动检查是否有新版本",checkUpdateBtn:"立即检查",updateChecking:"检查中…",updateCheckLatest:"已是最新版本",updateCheckAvailable:"发现新版本 {version},可从侧边栏的更新入口下载",updateCheckUnsupported:"当前构建不支持检查更新",updateCheckFailed:"检查失败,请稍后重试",updateCheckAvailableAuto:"发现新版本 {version},正在后台下载",updateCheckDownloaded:"新版本 {version} 已就绪,可从侧边栏的更新入口重启安装",autoDownloadUpdate:"自动下载更新",autoDownloadUpdateHint:"发现新版本时在后台自动下载,重启后完成安装",privacy:"数据与隐私",diagnostics:"诊断",build:"构建",serverVersion:"服务端版本",serverAddress:"服务器地址",serverAddressHint:"当前连接的服务器地址",serverVersionHint:"当前连接服务的版本",exportLog:"故障排查日志",exportLogHint:"导出已采集的故障排查日志",logHint:"加 ?debug=1 开启采集",exportLogBtn:"导出日志",archivedTitle:"已归档会话",archivedDesc:"查看已归档会话,确认其所属工作区路径、会话名称和归档时间,并可恢复到会话列表。",archivedSearch:"搜索已归档会话",archivedAllWorkspaces:"所有工作区",archivedSortLabel:"排序方式",archivedSortArchived:"归档时间",archivedSortCreated:"创建时间",archivedSortName:"按字母顺序",archivedRestore:"恢复",archivedEmpty:"还没有归档的会话",archivedNoMatch:"没有匹配的已归档会话",archivedSessionsCount:"{count} 个会话",archivedAt:"归档于 {time}",archivedLoadMore:"加载更多",archivedLoading:"加载中…",archivedLoadingAll:"正在加载全部归档会话…"},bz={openInEditor:"在编辑器中打开",openInEditorShort:"打开",openInApp:"用 {app} 打开",chooseOpenApp:"选择应用",copyAll:"复制全部对话为 Markdown",copyFinalSummary:"仅复制最终总结",copied:"已复制",lastUsed:"上次使用",copyPath:"复制路径",changed:"{n} 处改动",gitTooltip:"打开「文件 > 改动」",detached:"游离",openPr:"打开 Pull Request",prStatusOpen:"已打开",prStatusClosed:"已关闭",prStatusMerged:"已合并",prStatusDraft:"草稿",prStatusUnknown:"未知",options:"选项",copySessionId:"复制 Session ID",renameSession:"重命名",forkSession:"分叉会话",archiveSession:"归档",exportSession:"导出会话",devBadge:"开发环境运行中"},Cz={title:"侧边聊天",subtitle:"从当前会话 fork",empty:"在侧边随手问一句 —— 它共享当前会话的上下文。",placeholder:"问问侧边聊天…",send:"发送"},wz={actions:{summonApp:{label:"显示应用窗口",desc:"从任意位置将应用窗口唤起到前台"},newSession:{label:"新建会话",desc:"在当前工作区开始一个新会话"},searchSessions:{label:"搜索会话",desc:"打开会话搜索弹窗"},archiveSession:{label:"归档任务",desc:"立即归档当前聊天"},toggleSideChat:{label:"侧边聊天",desc:"打开或关闭 /btw 侧边聊天"},toggleSidebar:{label:"展开/收起侧边栏",desc:"收起或展开会话侧边栏"},openFolder:{label:"打开文件夹",desc:"通过系统原生选择器添加工作目录"},openInDefaultApp:{label:"在默认应用中打开",desc:"在默认编辑器或终端中打开当前工作目录"},openSettings:{label:"打开设置",desc:"显示或隐藏设置窗口"},toggleTerminal:{label:"切换终端",desc:"显示或隐藏底部终端面板"},send:{label:"发送消息",desc:"发送输入框中的内容"},newline:{label:"换行",desc:"在输入框中插入换行"}},searchPlaceholder:"搜索快捷键",unassigned:"未分配",unassign:"取消分配",edit:"编辑快捷键",reset:"恢复默认",resetAll:"全部恢复默认",recording:"按下新的快捷键…",invalid:"该按键组合不能用作快捷键",notGlobal:"该按键组合无法注册为系统级快捷键",globalTaken:"该快捷键已被系统或其他应用占用",reserved:"系统菜单已占用该快捷键",reservedSteer:"steer 固定快捷键(Ctrl/Cmd+S),不可占用",reservedFind:"对话搜索固定快捷键(Ctrl/Cmd+F),不可占用",conflict:"已被「{action}」占用",customBadge:"自定义"},_z={panelAria:"终端",toolbarAria:"终端标签页",resizeAria:"调整终端面板高度",toggle:"切换终端",newTab:"新建终端",closeTab:"关闭终端",restartTab:"重启终端",collapse:"收起终端面板",empty:"还没有终端,点击新建一个",processExited:"[进程已退出]",processExitedWithCode:"[进程已退出,退出码 {code}]"},xz={common:KH,app:ZH,sidebar:GH,workspace:YH,conversation:XH,status:JH,composer:QH,login:ez,providers:tz,model:nz,sessions:oz,approval:sz,question:iz,tasks:rz,thinking:lz,diff:az,fileTree:uz,filePreview:cz,mention:dz,warnings:fz,commands:pz,tools:hz,layout:mz,mobile:gz,theme:vz,onboarding:yz,settings:kz,header:bz,sideChat:Cz,shortcuts:wz,terminal:_z},Sz={en:qH,zh:xz},Az="kimi-locale";function $M(){let e=null;try{e=globalThis.localStorage?.getItem(Az)??null}catch{e=null}return e==="en"||e==="zh"?e:globalThis.navigator?.language?.toLowerCase().startsWith("zh")?"zh":"en"}function Mz(e){const t=e.locale??$M();return iH({legacy:!1,locale:t,fallbackLocale:"en",messages:Sz})}const NM=Symbol("KimiI18n"),Tz={t:e=>e};function m1(){const e=nn(NM,null);if(e)return e;try{const t=Nt();return{t:(n,o)=>t.t(n,o),locale:t.locale.value}}catch{return Tz}}const ya=6,ka=8,Ez=150,Iz=et({__name:"TooltipBubble",props:{target:{default:null},delegate:{default:null},text:{},placement:{default:"top"},maxWidth:{default:280},maxLines:{default:6}},setup(e){const t=e,n=Z(),o=Z(!1),s=Z(!1),i=Z({maxWidth:`${t.maxWidth}px`});let r,l=null,a;function u(){if(t.target)return t.target;const T=t.delegate;return T?T.firstElementChild??T:null}function c(T){const A=n.value;if(!A)return;const E=T.getBoundingClientRect(),P=A.offsetWidth,D=A.offsetHeight,I=window.innerWidth,$=window.innerHeight;let B=t.placement;B==="top"&&E.top-ya-D<ka?B="bottom":B==="bottom"&&E.bottom+ya+D>$-ka?B="top":B==="left"&&E.left-ya-P<ka?B="right":B==="right"&&E.right+ya+P>I-ka&&(B="left");let H=0,O=0;B==="top"?(H=E.top-ya-D,O=E.left+E.width/2-P/2):B==="bottom"?(H=E.bottom+ya,O=E.left+E.width/2-P/2):B==="left"?(H=E.top+E.height/2-D/2,O=E.left-ya-P):(H=E.top+E.height/2-D/2,O=E.right+ya),O=Math.min(Math.max(O,ka),I-ka-P),H=Math.min(Math.max(H,ka),$-ka-D),i.value={maxWidth:`${t.maxWidth}px`,top:`${Math.round(H)}px`,left:`${Math.round(O)}px`}}function d(){if(!t.text)return;const T=u();T&&(window.clearTimeout(r),r=window.setTimeout(()=>{o.value=!0,s.value=!1,yt(()=>{c(T),s.value=!0})},Ez))}function f(){window.clearTimeout(r),o.value=!1,s.value=!1}function h(){d()}function m(){f()}function v(T){return T instanceof Element?T.closest(".ui-tip"):null}function k(T){const A=t.delegate;if(!A)return;if(v(T.target)!==A){f();return}const E=T.relatedTarget;E instanceof Element&&A.contains(E)&&v(E)===A||d()}function w(T){const A=t.delegate;if(!A)return;const E=T.relatedTarget;E instanceof Element&&A.contains(E)||f()}function b(T){v(T.target)===t.delegate&&d()}function _(){f()}function g(){l&&(t.delegate?(l.removeEventListener("mouseover",k),l.removeEventListener("mouseout",w),l.removeEventListener("focusin",b),l.removeEventListener("focusout",_)):(l.removeEventListener("mouseenter",h),l.removeEventListener("mouseleave",m),l.removeEventListener("focusin",h),l.removeEventListener("focusout",m)),l=null)}function x(){g(),a?.disconnect(),a=void 0;const T=t.target??t.delegate;T&&(l=T,t.delegate?(T.addEventListener("mouseover",k),T.addEventListener("mouseout",w),T.addEventListener("focusin",b),T.addEventListener("focusout",_),a=new MutationObserver(()=>{o.value&&f()}),a.observe(T,{childList:!0})):(T.addEventListener("mouseenter",h),T.addEventListener("mouseleave",m),T.addEventListener("focusin",h),T.addEventListener("focusout",m)))}Je(()=>[t.target,t.delegate],()=>{f(),x()});function S(){o.value&&f()}return dn(()=>{x(),window.addEventListener("scroll",S,!0),window.addEventListener("resize",S)}),Vn(()=>{window.clearTimeout(r),a?.disconnect(),g(),window.removeEventListener("scroll",S,!0),window.removeEventListener("resize",S)}),(T,A)=>o.value?(y(),he(Zr,{key:0,to:"body"},[C("div",{ref_key:"bubble",ref:n,class:Re(["ui-tip__bubble",{positioned:s.value}]),style:Zt([i.value,{"--tip-lines":e.maxLines}]),role:"tooltip"},N(e.text),7)])):ee("",!0)}}),ft=(e,t)=>{const n=e.__vccOpts||e;for(const[o,s]of t)n[o]=s;return n},FM=ft(Iz,[["__scopeId","data-v-93bacf6d"]]),Lz=["type","disabled","aria-label"],$z=et({__name:"IconButton",props:{size:{default:"md"},disabled:{type:Boolean},label:{},tooltip:{},type:{default:"button"}},setup(e,{expose:t}){const n=Z();return t({el:n}),(o,s)=>(y(),M("button",{ref_key:"el",ref:n,class:Re(["ui-icon-button",`ui-icon-button--${e.size}`]),type:e.type,disabled:e.disabled,"aria-label":e.label},[xn(o.$slots,"default",{},void 0,!0),e.tooltip?(y(),he(FM,{key:0,target:n.value??null,text:e.tooltip},null,8,["target","text"])):ee("",!0)],10,Lz))}}),gn=ft($z,[["__scopeId","data-v-2cbeca98"]]),RM=Symbol("IconResolver"),Nz={sm:14,md:16,lg:20},Te=et({__name:"Icon",props:{name:{},size:{default:"md"},label:{}},setup(e){const t=e,n=nn(RM,()=>{}),o=R(()=>n(t.name)),s=R(()=>Nz[t.size]);return(i,r)=>o.value?(y(),he(bs(o.value),{key:0,class:"kw-icon",width:s.value,height:s.value,"aria-label":e.label,"aria-hidden":e.label?void 0:!0},null,8,["width","height","aria-label","aria-hidden"])):ee("",!0)}}),Fz={class:"ui-action-toast-host"},Rz={class:"ui-action-toast__body"},Oz=et({__name:"ActionToast",props:{duration:{default:8e3},dismissLabel:{}},emits:["dismiss"],setup(e,{emit:t}){const n=e,o=t,{t:s}=m1();let i=null,r=0,l=0;function a(d){i=setTimeout(()=>o("dismiss"),d),r=Date.now()+d}function u(){i!==null&&(clearTimeout(i),i=null,l=Math.max(0,r-Date.now()))}function c(){i===null&&a(l)}return a(n.duration),bn(()=>{i!==null&&clearTimeout(i)}),(d,f)=>(y(),M("div",Fz,[C("div",{class:"ui-action-toast",role:"status",onPointerenter:u,onPointerleave:c},[C("span",Rz,[xn(d.$slots,"default")]),j(gn,{class:"ui-action-toast__close",size:"sm",label:e.dismissLabel??p(s)("common.dismiss"),tooltip:e.dismissLabel??p(s)("common.dismiss"),onClick:f[0]||(f[0]=h=>o("dismiss"))},{default:me(()=>[j(Te,{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])],32)]))}}),Pz=ft(Oz,[["__scopeId","data-v-e84c8ca2"]]),Dz={key:0,width:"36",height:"36",viewBox:"0 0 36 36",fill:"none",stroke:"var(--color-success)","stroke-width":"2","aria-hidden":"true"},Bz={key:1,width:"28",height:"28",viewBox:"0 0 28 28",fill:"none",stroke:"var(--color-danger)","stroke-width":"1.5","aria-hidden":"true"},Hz={key:2,width:"28",height:"28",viewBox:"0 0 28 28",fill:"none",stroke:"var(--color-warning)","stroke-width":"1.5","aria-hidden":"true"},Dd=et({__name:"AuthStateIcon",props:{kind:{}},setup(e){return(t,n)=>e.kind==="success"?(y(),M("svg",Dz,[...n[0]||(n[0]=[C("circle",{cx:"18",cy:"18",r:"15"},null,-1),C("polyline",{points:"10,18 15,24 26,12"},null,-1)])])):e.kind==="expired"?(y(),M("svg",Bz,[...n[1]||(n[1]=[C("circle",{cx:"14",cy:"14",r:"12"},null,-1),C("line",{x1:"14",y1:"8",x2:"14",y2:"15"},null,-1),C("circle",{cx:"14",cy:"19",r:"1.2",fill:"var(--color-danger)"},null,-1)])])):(y(),M("svg",Hz,[...n[2]||(n[2]=[C("path",{d:"M14 3 L26 24 H2 Z"},null,-1),C("line",{x1:"14",y1:"12",x2:"14",y2:"18"},null,-1),C("circle",{cx:"14",cy:"21.5",r:"1",fill:"var(--color-warning)"},null,-1)])]))}}),zz={key:0,class:"ui-badge__dot","aria-hidden":"true"},Wz=et({__name:"Badge",props:{variant:{default:"neutral"},size:{default:"md"},dot:{type:Boolean}},setup(e){return(t,n)=>(y(),M("span",{class:Re(["ui-badge",[`ui-badge--${e.variant}`,`ui-badge--${e.size}`]])},[e.dot?(y(),M("span",zz)):ee("",!0),xn(t.$slots,"default",{},void 0,!0)],2))}}),Vr=ft(Wz,[["__scopeId","data-v-d879fe18"]]),Uz={class:"ui-banner__icon","aria-hidden":"true"},jz={class:"ui-banner__text"},Vz=et({__name:"Banner",props:{variant:{default:"info"}},setup(e){return(t,n)=>(y(),M("div",{class:Re(["ui-banner",`ui-banner--${e.variant}`]),role:"status"},[C("span",Uz,[xn(t.$slots,"icon",{},()=>[e.variant==="info"?(y(),he(Te,{key:0,name:"info",size:"md"})):(y(),he(Te,{key:1,name:"alert-triangle",size:"md"}))],!0)]),C("span",jz,[xn(t.$slots,"default",{},void 0,!0)])],2))}}),qu=ft(Vz,[["__scopeId","data-v-6d739c6d"]]),qz=["aria-label"],Kz=et({__name:"Spinner",props:{size:{default:"md"},label:{}},setup(e){const{t}=m1(),n=Z(null);let o,s;function i(){const r=n.value;if(r){if(s?.matches){o?.cancel(),o=void 0;return}o||(o=r.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:850,iterations:1/0}),o.startTime=0)}}return dn(()=>{const r=n.value;!r||typeof r.animate!="function"||(s=window.matchMedia("(prefers-reduced-motion: reduce)"),s.addEventListener("change",i),i())}),Vn(()=>{s?.removeEventListener("change",i),s=void 0,o?.cancel(),o=void 0}),(r,l)=>(y(),M("span",{ref_key:"boxRef",ref:n,class:Re(["ui-spinner",`ui-spinner--${e.size}`]),role:"status","aria-label":e.label??p(t)("common.loading")},[...l[0]||(l[0]=[C("svg",{class:"ui-spinner__svg",viewBox:"0 0 24 24","aria-hidden":"true"},[C("circle",{class:"ui-spinner__track",cx:"12",cy:"12",r:"9"}),C("circle",{class:"ui-spinner__arc",cx:"12",cy:"12",r:"9"})],-1)])],10,qz))}}),Ao=ft(Kz,[["__scopeId","data-v-0b81b1b5"]]),Zz=["type","disabled"],Gz={class:"ui-button__content"},Yz=et({__name:"Button",props:{variant:{default:"primary"},size:{default:"md"},disabled:{type:Boolean},loading:{type:Boolean},type:{default:"button"}},setup(e){return(t,n)=>(y(),M("button",{class:Re(["ui-button",[`ui-button--${e.variant}`,`ui-button--${e.size}`,{"is-loading":e.loading}]]),type:e.type,disabled:e.disabled||e.loading},[e.loading?(y(),he(Ao,{key:0,size:"sm",class:"ui-button__spinner"})):ee("",!0),C("span",Gz,[xn(t.$slots,"default",{},void 0,!0)])],10,Zz))}}),Rt=ft(Yz,[["__scopeId","data-v-01b5ec22"]]),Xz={key:0,class:"ui-card__head"},Jz={class:"ui-card__body"},Qz={key:1,class:"ui-card__foot"},eW=et({__name:"Card",props:{elevated:{type:Boolean,default:!1}},setup(e){return(t,n)=>(y(),M("div",{class:Re(["ui-card",{"is-elevated":e.elevated}])},[t.$slots.head?(y(),M("div",Xz,[xn(t.$slots,"head",{},void 0,!0)])):ee("",!0),C("div",Jz,[xn(t.$slots,"default",{},void 0,!0)]),t.$slots.foot?(y(),M("div",Qz,[xn(t.$slots,"foot",{},void 0,!0)])):ee("",!0)],2))}}),tW=ft(eW,[["__scopeId","data-v-fbd05138"]]),nW=["checked","disabled"],oW={class:"ui-check__box","aria-hidden":"true"},sW={key:0,class:"ui-check__label"},iW=et({__name:"Checkbox",props:{modelValue:{type:Boolean},disabled:{type:Boolean}},emits:["update:modelValue"],setup(e,{emit:t}){const n=t;return(o,s)=>(y(),M("label",{class:Re(["ui-check",{"is-on":e.modelValue,"is-disabled":e.disabled}])},[C("input",{class:"ui-check__input",type:"checkbox",checked:e.modelValue,disabled:e.disabled,onChange:s[0]||(s[0]=i=>n("update:modelValue",i.target.checked))},null,40,nW),C("span",oW,[e.modelValue?(y(),he(Te,{key:0,name:"check",size:"md"})):ee("",!0)]),o.$slots.default?(y(),M("span",sW,[xn(o.$slots,"default",{},void 0,!0)])):ee("",!0)],2))}}),rW=ft(iW,[["__scopeId","data-v-d4bf4026"]]),lW={class:"ctx-ring",viewBox:"0 0 20 20","aria-hidden":"true"},aW=["stroke-dasharray","stroke-dashoffset"],Qv=7,uW=et({__name:"ContextRing",props:{pct:{}},setup(e){const t=e,n=2*Math.PI*Qv;return(o,s)=>(y(),M("svg",lW,[C("circle",{class:"ctx-ring-track",cx:"10",cy:"10",r:Qv,fill:"none","stroke-width":"2.5"}),C("circle",{class:"ctx-ring-fill",cx:"10",cy:"10",r:Qv,fill:"none","stroke-width":"2.5","stroke-linecap":"round","stroke-dasharray":`${n}`,"stroke-dashoffset":`${n*(1-t.pct/100)}`},null,8,aW)]))}}),cW=ft(uW,[["__scopeId","data-v-de787cf2"]]),Ci=Z(0),dW=["aria-label"],fW={key:0,class:"ui-dialog__head"},pW={class:"ui-dialog__titles"},hW={key:0,class:"ui-dialog__title"},mW={key:1,class:"ui-dialog__desc"},gW={class:"ui-dialog__body"},vW={key:1,class:"ui-dialog__foot"},yW='a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',kW=et({__name:"Dialog",props:{open:{type:Boolean},title:{},ariaLabel:{},description:{},closeOnOverlay:{type:Boolean,default:!0},closeOnEsc:{type:Boolean,default:!0},size:{default:"md"},height:{default:"auto"},padded:{type:Boolean,default:!0},hideClose:{type:Boolean},level:{default:"raised"},initialFocus:{}},emits:["update:open","close"],setup(e,{emit:t}){const n=e,o=t,{t:s}=m1(),i=Z(null);let r=null;function l(){o("update:open",!1),o("close")}function a(){return i.value?Array.from(i.value.querySelectorAll(yW)):[]}function u(){const{initialFocus:f}=n;return f?typeof f=="function"?f()??null:typeof f=="string"?i.value?.querySelector(f)??null:i.value?.contains(f)?f:null:null}function c(f){if(!n.open)return;if(f.key==="Escape"&&n.closeOnEsc){f.preventDefault(),l();return}if(f.key!=="Tab")return;const h=a(),m=h[0],v=h[h.length-1];if(!m||!v){f.preventDefault(),i.value?.focus();return}const k=document.activeElement;f.shiftKey&&k===m?(f.preventDefault(),v.focus()):!f.shiftKey&&k===v&&(f.preventDefault(),m.focus())}function d(f){n.closeOnOverlay&&f.target===f.currentTarget&&l()}return Je(()=>n.open,async f=>{if(f){Ci.value+=1,r=document.activeElement,await yt();const h=u(),m=a();(h??m[0]??i.value)?.focus()}else Ci.value=Math.max(0,Ci.value-1),r instanceof HTMLElement&&(r.focus(),r=null)},{immediate:!0}),typeof window<"u"&&window.addEventListener("keydown",c),Vn(()=>{typeof window<"u"&&window.removeEventListener("keydown",c),n.open&&(Ci.value=Math.max(0,Ci.value-1),r instanceof HTMLElement&&r.focus())}),(f,h)=>(y(),he(Zr,{to:"body"},[e.open?(y(),M("div",{key:0,class:"ui-dialog__overlay",onMousedown:d},[C("div",{ref_key:"panel",ref:i,class:Re(["ui-dialog",[`ui-dialog--${e.size}`,{"ui-dialog--flush":!e.padded,"ui-dialog--fixed-height":e.height==="fixed","ui-dialog--grouped":e.level==="grouped"}]]),role:"dialog","aria-modal":"true","aria-label":e.ariaLabel??e.title,tabindex:"-1"},[e.title||f.$slots.head?(y(),M("div",fW,[xn(f.$slots,"head",{},()=>[C("div",pW,[e.title?(y(),M("div",hW,N(e.title),1)):ee("",!0),e.description?(y(),M("div",mW,N(e.description),1)):ee("",!0)])],!0),e.hideClose?ee("",!0):(y(),he(gn,{key:0,class:"ui-dialog__close",size:"sm",label:p(s)("common.close"),tooltip:p(s)("common.close"),onClick:l},{default:me(()=>[j(Te,{name:"close",size:"md"})]),_:1},8,["label","tooltip"]))])):ee("",!0),C("div",gW,[xn(f.$slots,"default",{},void 0,!0)]),f.$slots.foot?(y(),M("div",vW,[xn(f.$slots,"foot",{},void 0,!0)])):ee("",!0)],10,dW)],32)):ee("",!0)]))}}),ua=ft(kW,[["__scopeId","data-v-ebbc1a68"]]),bW={class:"ui-empty"},CW={key:0,class:"ui-empty__icon","aria-hidden":"true"},wW={key:1,class:"ui-empty__title"},_W={key:2,class:"ui-empty__hint"},xW=et({__name:"EmptyState",props:{title:{},hint:{}},setup(e){return(t,n)=>(y(),M("div",bW,[t.$slots.icon?(y(),M("span",CW,[xn(t.$slots,"icon",{},void 0,!0)])):ee("",!0),e.title?(y(),M("div",wW,N(e.title),1)):ee("",!0),e.hint?(y(),M("div",_W,N(e.hint),1)):ee("",!0),xn(t.$slots,"default",{},void 0,!0)]))}}),SW=ft(xW,[["__scopeId","data-v-6da80932"]]),AW={key:0,class:"ui-field__label"},MW={key:1,class:"ui-field__error"},TW={key:2,class:"ui-field__hint"},EW=et({__name:"Field",props:{label:{},hint:{},error:{}},setup(e){return(t,n)=>(y(),M("div",{class:Re(["ui-field",{"has-error":!!e.error}])},[e.label?(y(),M("label",AW,N(e.label),1)):ee("",!0),xn(t.$slots,"default",{},void 0,!0),e.error?(y(),M("span",MW,N(e.error),1)):e.hint?(y(),M("span",TW,N(e.hint),1)):ee("",!0)],2))}}),IW=ft(EW,[["__scopeId","data-v-a8de5f7f"]]),LW=["type","value","placeholder","disabled","readonly"],$W=et({__name:"Input",props:{modelValue:{},size:{default:"md"},type:{default:"text"},placeholder:{},disabled:{type:Boolean},readonly:{type:Boolean},error:{type:Boolean}},emits:["update:modelValue","focus","blur"],setup(e,{expose:t,emit:n}){const o=n,s=Z();function i(a){o("update:modelValue",a.target.value)}function r(){s.value?.focus()}function l(){s.value?.select()}return t({focus:r,select:l,el:s}),(a,u)=>(y(),M("input",{ref_key:"el",ref:s,class:Re(["ui-input",[`ui-input--${e.size}`,{"has-error":e.error}]]),type:e.type,value:e.modelValue,placeholder:e.placeholder,disabled:e.disabled,readonly:e.readonly,onInput:i,onFocus:u[0]||(u[0]=c=>a.$emit("focus",c)),onBlur:u[1]||(u[1]=c=>a.$emit("blur",c))},null,42,LW))}}),js=ft($W,[["__scopeId","data-v-f1cdf732"]]),NW={class:"ui-kbd"},FW=et({__name:"Kbd",props:{keys:{}},setup(e){return(t,n)=>(y(),M("span",NW,[(y(!0),M(Pe,null,pt(e.keys,o=>(y(),M("kbd",{key:o,class:"ui-kbd__key"},N(o),1))),128))]))}}),oa=ft(FW,[["__scopeId","data-v-04b30ce2"]]),RW=["role"],OW=et({__name:"Menu",props:{role:{default:"menu"}},setup(e,{expose:t}){const n=Z();return t({el:n}),(o,s)=>(y(),M("div",{ref_key:"el",ref:n,class:"ui-menu",role:e.role},[xn(o.$slots,"default",{},void 0,!0)],8,RW))}}),Cl=ft(OW,[["__scopeId","data-v-9be2c64a"]]),PW={key:0,class:"ui-menu-sep",role:"separator"},DW=["role","disabled"],BW=et({__name:"MenuItem",props:{active:{type:Boolean},danger:{type:Boolean},disabled:{type:Boolean},separator:{type:Boolean},size:{default:"md"},role:{default:"menuitem"}},emits:["click"],setup(e){return(t,n)=>e.separator?(y(),M("div",PW)):(y(),M("button",{key:1,class:Re(["ui-menu-item",[`ui-menu-item--${e.size}`,{"is-active":e.active,"is-danger":e.danger}]]),type:"button",role:e.role,disabled:e.disabled,onClick:n[0]||(n[0]=o=>t.$emit("click",o))},[xn(t.$slots,"default",{},void 0,!0)],10,DW))}}),hn=ft(BW,[["__scopeId","data-v-3866cadb"]]),HW=et({__name:"Tooltip",props:{text:{},placement:{default:"top"},maxWidth:{default:280},maxLines:{default:6}},setup(e){const t=Z();return(n,o)=>(y(),M(Pe,null,[C("span",{ref_key:"trigger",ref:t,class:"ui-tip"},[xn(n.$slots,"default",{},void 0,!0)],512),j(FM,{delegate:t.value??null,text:e.text,placement:e.placement,"max-width":e.maxWidth,"max-lines":e.maxLines},null,8,["delegate","text","placement","max-width","max-lines"])],64))}}),pn=ft(HW,[["__scopeId","data-v-414bd903"]]),zW={class:"ui-panel-header__title"},WW={key:0,class:"ui-panel-header__sub"},UW=et({__name:"PanelHeader",props:{title:{},subtitle:{},closable:{type:Boolean,default:!0},closeLabel:{},closeIcon:{default:"close"},wrap:{type:Boolean}},emits:["close"],setup(e){const{t}=m1();return(n,o)=>(y(),M("div",{class:Re(["ui-panel-header",{wrap:e.wrap}])},[C("span",zW,N(e.title),1),j(pn,{text:e.subtitle},{default:me(()=>[e.subtitle?(y(),M("span",WW,N(e.subtitle),1)):ee("",!0)]),_:1},8,["text"]),xn(n.$slots,"default",{},void 0,!0),e.closable?(y(),he(gn,{key:0,class:"ui-panel-header__close",size:"sm",label:e.closeLabel??p(t)("common.close"),tooltip:e.closeLabel??p(t)("common.close"),onClick:o[0]||(o[0]=s=>n.$emit("close"))},{default:me(()=>[j(Te,{name:e.closeIcon,size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])):ee("",!0)],2))}}),pc=ft(UW,[["__scopeId","data-v-eb14b05d"]]),jW=["disabled","aria-pressed"],VW=et({__name:"Pill",props:{clickable:{type:Boolean,default:!0},active:{type:Boolean},disabled:{type:Boolean},ariaPressed:{type:Boolean}},emits:["click"],setup(e){return(t,n)=>e.clickable?(y(),M("button",{key:0,class:Re(["ui-pill",{"is-active":e.active}]),type:"button",disabled:e.disabled,"aria-pressed":e.ariaPressed,onClick:n[0]||(n[0]=o=>t.$emit("click",o))},[xn(t.$slots,"default",{},void 0,!0)],10,jW)):(y(),M("span",{key:1,class:Re(["ui-pill",{"is-active":e.active}])},[xn(t.$slots,"default",{},void 0,!0)],2))}}),G0=ft(VW,[["__scopeId","data-v-fe6a2873"]]),qW=et({__name:"ScrollArea",props:{orientation:{default:"vertical"},hideDelay:{default:600}},setup(e,{expose:t}){const n=e,o=Z(null),s=Z(null),i=Z(!1),r=Z({overflow:!1,size:0,offset:0}),l=Z({overflow:!1,size:0,offset:0}),a=Z(null);let u=null,c=null,d=null;const f=R(()=>({overflowX:n.orientation==="vertical"?"hidden":"auto",overflowY:n.orientation==="horizontal"?"hidden":"auto"})),h=R(()=>({height:`${r.value.size}px`,transform:`translateY(${r.value.offset}px)`})),m=R(()=>({width:`${l.value.size}px`,transform:`translateX(${l.value.offset}px)`}));function v(E,P,D){if(!(P>E+1)||E<=0)return{overflow:!1,size:0,offset:0};const $=Math.max(0,E-4),B=Math.min($,Math.max(24,$*E/P)),H=Math.max(0,$-B),O=Math.max(1,P-E);return{overflow:!0,size:B,offset:H*D/O}}function k(){const E=s.value;if(!E)return;const P=v(E.clientHeight,E.scrollHeight,E.scrollTop),D=v(E.clientWidth,E.scrollWidth,E.scrollLeft);(P.overflow!==r.value.overflow||P.size!==r.value.size||P.offset!==r.value.offset)&&(r.value=P),(D.overflow!==l.value.overflow||D.size!==l.value.size||D.offset!==l.value.offset)&&(l.value=D)}function w(){u!==null&&clearTimeout(u),u=null}function b(){w(),i.value=!0}function _(){w(),!(a.value||o.value?.matches(":hover, :focus-within"))&&(u=setTimeout(()=>{i.value=!1,u=null},n.hideDelay))}function g(){k(),b(),_()}function x(E,P){const D=s.value;D&&(P.preventDefault(),b(),a.value={axis:E,pointerId:P.pointerId,startPointer:E==="vertical"?P.clientY:P.clientX,startScroll:E==="vertical"?D.scrollTop:D.scrollLeft},P.currentTarget.setPointerCapture(P.pointerId))}function S(E){const P=a.value,D=s.value;if(!P||P.pointerId!==E.pointerId||!D)return;const I=P.axis==="vertical"?E.clientY:E.clientX,$=P.axis==="vertical"?D.clientHeight:D.clientWidth,B=P.axis==="vertical"?D.scrollHeight:D.scrollWidth,H=P.axis==="vertical"?r.value.size:l.value.size,O=Math.max(1,$-4-H),F=(I-P.startPointer)*(B-$)/O;P.axis==="vertical"?D.scrollTop=P.startScroll+F:D.scrollLeft=P.startScroll+F}function T(E){!a.value||a.value.pointerId!==E.pointerId||(a.value=null,_())}function A(){const E=s.value;if(!(!E||!c))for(const P of E.children)c.observe(P)}return dn(async()=>{await yt();const E=s.value;E&&(c=new ResizeObserver(k),c.observe(E),A(),d=new MutationObserver(()=>{A(),k()}),d.observe(E,{childList:!0,subtree:!0,characterData:!0}),k())}),Vn(()=>{w(),c?.disconnect(),d?.disconnect()}),t({viewport:s,updateMetrics:k}),(E,P)=>(y(),M("div",{ref_key:"root",ref:o,class:"ui-scroll-area",onPointerenter:b,onPointerleave:_,onFocusin:b,onFocusout:_},[C("div",{ref_key:"viewport",ref:s,class:"ui-scroll-area__viewport",style:Zt(f.value),tabindex:"0",onScroll:g},[xn(E.$slots,"default",{},void 0,!0)],36),r.value.overflow&&n.orientation!=="horizontal"?(y(),M("div",{key:0,class:Re(["ui-scroll-area__bar ui-scroll-area__bar--vertical",{"is-visible":i.value}]),"aria-hidden":"true"},[C("span",{class:"ui-scroll-area__thumb",style:Zt(h.value),onPointerdown:P[0]||(P[0]=D=>x("vertical",D)),onPointermove:S,onPointerup:T,onPointercancel:T},null,36)],2)):ee("",!0),l.value.overflow&&n.orientation!=="vertical"?(y(),M("div",{key:1,class:Re(["ui-scroll-area__bar ui-scroll-area__bar--horizontal",{"is-visible":i.value}]),"aria-hidden":"true"},[C("span",{class:"ui-scroll-area__thumb",style:Zt(m.value),onPointerdown:P[1]||(P[1]=D=>x("horizontal",D)),onPointermove:S,onPointerup:T,onPointercancel:T},null,36)],2)):ee("",!0)],544))}}),Pk=ft(qW,[["__scopeId","data-v-9c504ebc"]]),KW=["aria-selected","onClick"],ZW=et({__name:"SegmentedControl",props:{modelValue:{},options:{},size:{}},emits:["update:modelValue"],setup(e,{emit:t}){const n=e,o=t,s=Z(null),i=Z([]),r=Z(!1),l=Z({});let a=null;function u(d,f){d instanceof HTMLElement&&(i.value[f]=d)}async function c(){await yt();const d=n.options.findIndex(h=>h.value===n.modelValue),f=i.value[d];f&&(l.value={width:`${f.offsetWidth}px`,height:`${f.offsetHeight}px`,transform:`translate(${f.offsetLeft}px, ${f.offsetTop}px)`},r.value=!0)}return Je(()=>[n.modelValue,n.options.length],c,{immediate:!0}),dn(()=>{a=new ResizeObserver(()=>c()),s.value&&a.observe(s.value);for(const d of i.value)a.observe(d);c()}),Vn(()=>a?.disconnect()),(d,f)=>(y(),M("div",{ref_key:"root",ref:s,class:Re(["ui-seg",`ui-seg--${e.size??"md"}`]),role:"tablist"},[C("span",{class:Re(["ui-seg__indicator",{"is-ready":r.value}]),style:Zt(l.value),"aria-hidden":"true"},null,6),(y(!0),M(Pe,null,pt(e.options,(h,m)=>(y(),M("button",{key:h.value,ref_for:!0,ref:v=>u(v,m),class:Re(["ui-seg__item",{"is-on":h.value===e.modelValue}]),type:"button",role:"tab","aria-selected":h.value===e.modelValue,onClick:v=>o("update:modelValue",h.value)},[h.icon?(y(),he(Te,{key:0,class:"ui-seg__icon",name:h.icon,size:"sm"},null,8,["name"])):ee("",!0),h.swatch?(y(),M("span",{key:1,class:"ui-seg__swatch",style:Zt({backgroundColor:h.swatch})},null,4)):ee("",!0),qe(" "+N(h.label),1)],10,KW))),128))],2))}}),wi=ft(ZW,[["__scopeId","data-v-27f5a180"]]),GW=["aria-expanded","disabled"],YW=["src"],XW={class:"ui-select__value-text"},JW={key:0,class:"ui-select__group"},QW=["aria-selected","disabled","onMouseenter","onClick"],eU=["src"],tU=et({inheritAttrs:!1,__name:"Select",props:{modelValue:{},options:{},placeholder:{default:""},size:{default:"md"},disabled:{type:Boolean},error:{type:Boolean}},emits:["update:modelValue"],setup(e,{emit:t}){const n=e,o=t,s=p1(),i=Z(null),r=Z(null),l=Z(null),a=Z([]),u=Z(!1),c=Z(-1),d=`ui-select-${Math.random().toString(36).slice(2,9)}`,f=R(()=>n.options.findIndex(A=>String(A.value)===String(n.modelValue??""))),h=R(()=>n.options[f.value]),m=R(()=>h.value?.label??n.placeholder);function v(A,E){a.value[E]=A instanceof HTMLElement?A:null}function k(){const A=l.value,E=a.value[c.value];!A||!E||(A.scrollTop=E.offsetTop-(A.clientHeight-E.offsetHeight)/2)}function w(){n.disabled||u.value||(u.value=!0,c.value=f.value>=0?f.value:n.options.findIndex(A=>!A.disabled),yt(k))}function b({restoreFocus:A=!1}={}){u.value&&(u.value=!1,A&&yt(()=>r.value?.focus()))}function _(){u.value?b():w()}function g(A){A.disabled||(String(A.value)!==String(n.modelValue??"")&&o("update:modelValue",A.value),b({restoreFocus:!0}))}function x(A){if(u.value||w(),n.options.length===0)return;let E=c.value;for(let P=0;P<n.options.length;P+=1)if(E=(E+A+n.options.length)%n.options.length,!n.options[E]?.disabled){c.value=E,yt(k);return}}function S(A){if(A.key==="ArrowDown")A.preventDefault(),x(1);else if(A.key==="ArrowUp")A.preventDefault(),x(-1);else if(A.key==="Enter"||A.key===" ")if(A.preventDefault(),!u.value)w();else{const E=n.options[c.value];E&&g(E)}else if(A.key==="Escape")A.preventDefault(),b();else if(A.key==="Home"||A.key==="End"){A.preventDefault();const E=n.options.map((P,D)=>P.disabled?-1:D).filter(P=>P>=0);c.value=A.key==="Home"?E[0]??-1:E.at(-1)??-1,yt(k)}}function T(A){i.value?.contains(A.target)||b()}return dn(()=>document.addEventListener("pointerdown",T)),bn(()=>document.removeEventListener("pointerdown",T)),(A,E)=>(y(),M("div",{ref_key:"rootRef",ref:i,class:Re(["ui-select",[`ui-select--${e.size}`,{"has-error":e.error,"is-open":u.value,"is-disabled":e.disabled}]])},[C("button",zn({ref_key:"triggerRef",ref:r},p(s),{class:"ui-select__trigger",type:"button",role:"combobox","aria-controls":d,"aria-expanded":u.value,"aria-haspopup":"listbox",disabled:e.disabled,onClick:_,onKeydown:S}),[C("span",{class:Re(["ui-select__value",{"is-placeholder":!h.value}])},[h.value?.icon?(y(),M("img",{key:0,class:"ui-select__icon",src:h.value.icon,alt:""},null,8,YW)):ee("",!0),C("span",XW,N(m.value),1)],2),j(Te,{class:"ui-select__chevron",name:"chevron-down",size:"sm"})],16,GW),u.value?(y(),M("div",{key:0,id:d,ref_key:"listRef",ref:l,class:"ui-select__menu",role:"listbox"},[(y(!0),M(Pe,null,pt(e.options,(P,D)=>(y(),M(Pe,{key:`${P.group??""}:${P.value}`},[P.group&&P.group!==e.options[D-1]?.group?(y(),M("div",JW,N(P.group),1)):ee("",!0),C("button",{ref_for:!0,ref:I=>v(I,D),class:Re(["ui-select__option",{"is-selected":D===f.value,"is-active":D===c.value}]),type:"button",role:"option","aria-selected":D===f.value,disabled:P.disabled,onMouseenter:I=>c.value=D,onClick:I=>g(P)},[j(Te,{class:"ui-select__check",name:"check",size:"sm"}),P.icon?(y(),M("img",{key:0,class:"ui-select__icon ui-select__icon--option",src:P.icon,alt:""},null,8,eU)):ee("",!0),C("span",null,N(P.label),1)],42,QW)],64))),128))],512)):ee("",!0)],2))}}),n3=ft(tU,[["__scopeId","data-v-63f5dcbc"]]),nU=et({__name:"StatusDot",props:{status:{}},setup(e){const t=e;function n(s){switch(s){case"ok":case"done":case"completed":case"success":return"ok";case"error":case"failed":case"danger":return"error";case"running":case"working":case"in_progress":case"active":return"running";case"suspended":return"suspended";default:return"idle"}}const o=R(()=>n(t.status));return(s,i)=>(y(),M("span",{class:Re(["kw-dot",`kw-dot--${o.value}`]),"aria-hidden":"true"},null,2))}}),hc=ft(nU,[["__scopeId","data-v-b282847b"]]),oU=["aria-checked","aria-label","disabled"],sU=et({__name:"Switch",props:{modelValue:{type:Boolean},disabled:{type:Boolean},label:{}},emits:["update:modelValue"],setup(e,{emit:t}){const n=t;return(o,s)=>(y(),M("button",{class:Re(["ui-switch",{"is-on":e.modelValue}]),type:"button",role:"switch","aria-checked":e.modelValue,"aria-label":e.label,disabled:e.disabled,onClick:s[0]||(s[0]=i=>n("update:modelValue",!e.modelValue))},[...s[1]||(s[1]=[C("span",{class:"ui-switch__thumb"},null,-1)])],10,oU))}}),ed=ft(sU,[["__scopeId","data-v-2fc56545"]]),iU={class:"ui-toast__icon","aria-hidden":"true"},rU={class:"ui-toast__body"},lU={class:"ui-toast__title"},aU={key:0,class:"ui-toast__msg"},uU=et({__name:"Toast",props:{variant:{default:"info"},title:{},message:{},dismissLabel:{}},emits:["dismiss"],setup(e){const{t}=m1();return(n,o)=>(y(),M("div",{class:Re(["ui-toast",`ui-toast--${e.variant}`])},[C("span",iU,[xn(n.$slots,"icon",{},()=>[e.variant==="success"?(y(),he(Te,{key:0,name:"check"})):e.variant==="danger"?(y(),he(Te,{key:1,name:"close"})):e.variant==="warning"?(y(),he(Te,{key:2,name:"alert-triangle"})):(y(),he(Te,{key:3,name:"info"}))],!0)]),C("div",rU,[C("div",lU,N(e.title),1),e.message?(y(),M("div",aU,N(e.message),1)):ee("",!0),xn(n.$slots,"default",{},void 0,!0)]),j(gn,{class:"ui-toast__close",size:"sm",label:e.dismissLabel??p(t)("common.dismiss"),tooltip:e.dismissLabel??p(t)("common.dismiss"),onClick:o[0]||(o[0]=s=>n.$emit("dismiss"))},{default:me(()=>[j(Te,{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])],2))}}),cU=ft(uU,[["__scopeId","data-v-62bc76d1"]]),dU=100;function Ar(){let e=!1,t=0;function n(){e=!0,t=0}function o(){e=!1,t=Date.now()}function s(){e=!1,t=0}function i(r){return e||r.isComposing||r.keyCode===229||Date.now()-t<dU}return typeof window<"u"&&(window.addEventListener("focusin",s,!0),window.addEventListener("focusout",s,!0)),bn(()=>{typeof window<"u"&&(window.removeEventListener("focusin",s,!0),window.removeEventListener("focusout",s,!0))}),{handleCompositionStart:n,handleCompositionEnd:o,resetComposition:s,isComposingKeyEvent:i}}function Cd(e,t,n="/api/v1"){return`${e}${n}${t.startsWith("/")?t:`/${t}`}`}function fU(e,t){const n=new URL(`${e}/api/v1/ws`);return n.protocol=n.protocol==="https:"?"wss:":"ws:",n.searchParams.set("client_id",t),n.toString()}const oy={};class wd extends Error{code;requestId;details;timestamp;durationMs;constructor(t){super(t.msg),this.name="DaemonApiError",this.code=t.code,this.requestId=t.requestId,this.details=t.details,this.timestamp=t.timestamp,this.durationMs=t.durationMs}}class Wl extends Error{cause;method;path;url;requestId;phase;timeoutMs;status;statusText;contentType;bodyPreview;timestamp;durationMs;constructor(t){super(t.message),this.name="DaemonNetworkError",this.cause=t.cause,this.method=t.method,this.path=t.path,this.url=t.url,this.requestId=t.requestId,this.phase=t.phase,this.timeoutMs=t.timeoutMs,this.status=t.status,this.statusText=t.statusText,this.contentType=t.contentType,this.bodyPreview=t.bodyPreview,this.timestamp=t.timestamp,this.durationMs=t.durationMs}}class sy extends Error{size;limit;constructor(t){super(`file too large to preview: ${t.size} bytes (limit ${t.limit})`),this.name="FileTooLargeError",this.size=t.size,this.limit=t.limit}}function Us(e){return e instanceof wd||typeof e=="object"&&e!==null&&e.name==="DaemonApiError"&&typeof e.code=="number"}function iy(e){return e instanceof Wl||typeof e=="object"&&e!==null&&e.name==="DaemonNetworkError"&&typeof e.method=="string"&&typeof e.path=="string"}function pU(e){return e instanceof sy||typeof e=="object"&&e!==null&&e.name==="FileTooLargeError"&&typeof e.limit=="number"}const hU=40922;function mU(e){return Us(e)&&e.code===hU}const hd=3e4,Y0=5*6e4,OM="0123456789ABCDEFGHJKMNPQRSTVWXYZ",Dk=500,PM=40101;function Bk(e,t){for(const[n,o]of Object.entries(t))if(o!==void 0)if(Array.isArray(o))for(const s of o)s!==void 0&&e.append(n,String(s));else e.set(n,String(o))}function X0(e=hd){try{return AbortSignal.timeout(e)}catch{return}}function gU(e,t){let n="",o=e;for(let s=0;s<t;s++)n=OM[o%32]+n,o=Math.floor(o/32);return n}function vU(e){const t=new Uint8Array(e);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(t);else for(let n=0;n<t.length;n++)t[n]=Math.floor(Math.random()*256);return Array.from(t,n=>OM[n%32]).join("")}function J0(){return`${gU(Date.now(),10)}${vU(16)}`}function yU(e){try{const t=[];return e.forEach((n,o)=>{typeof n=="string"?t.push({field:o,value:n}):t.push({field:o,file:n.name,size:n.size,type:n.type})}),{formData:t}}catch{return"[FormData]"}}async function e9(e){try{const t=await e.text();return t?t.length>Dk?`${t.slice(0,Dk)}...`:t:void 0}catch{return}}class Hk{constructor(t){this.opts=t,this.tracer=t.tracer??oy}tracer;async get(t,n){return this.request("GET",t,void 0,n)}async getBlob(t,n,o){let s=Cd(this.opts.origin,t,this.opts.restBasePath);if(n){const c=new URLSearchParams;Bk(c,n);const d=c.toString();d&&(s=`${s}?${d}`)}const i=J0(),r={"X-Request-Id":i};this.addClientHeaders(r);const l=Date.now();this.tracer.restRequest?.({method:"GET",path:t,url:s,requestId:i});let a;try{a=await fetch(s,{method:"GET",headers:r,signal:X0()})}catch(c){throw this.tracer.restFailure?.({method:"GET",path:t,requestId:i,phase:"fetch",durationMs:Date.now()-l,error:c}),new Wl({message:`Network error calling GET ${t}`,cause:c,method:"GET",path:t,url:s,requestId:i,phase:"fetch",timeoutMs:hd,timestamp:Date.now(),durationMs:Date.now()-l})}if(a.ok){this.tracer.restResponse?.({method:"GET",path:t,requestId:i,status:a.status,durationMs:Date.now()-l,code:0,msg:""});const c=Number(a.headers.get("content-length")??0);if(o?.maxBytes!==void 0&&c>o.maxBytes)throw a.body?.cancel(),new sy({size:c,limit:o.maxBytes});return a.blob()}let u;try{u=await a.clone().json()}catch{}throw this.checkAuthRequired(a,u?.code??0),this.tracer.restResponse?.({method:"GET",path:t,requestId:i,status:a.status,durationMs:Date.now()-l,code:u?.code??a.status,msg:u?.msg??a.statusText,envelopeRequestId:u?.request_id}),new wd({code:u?.code??a.status,msg:u?.msg??a.statusText,requestId:u?.request_id??i,details:u?.details,timestamp:Date.now(),durationMs:Date.now()-l})}async post(t,n,o){return this.request("POST",t,n,void 0,o?.allowCodes)}async postZip(t,n,o){const s="POST",i=Cd(this.opts.origin,t,this.opts.restBasePath),r=J0(),l={"X-Request-Id":r,"Content-Type":"application/json; charset=utf-8"};this.addClientHeaders(l);const a=Date.now();this.tracer.restRequest?.({method:s,path:t,url:i,requestId:r,body:o});let u;try{u=await fetch(i,{method:s,headers:l,body:JSON.stringify(n),signal:X0(Y0)})}catch(h){throw this.tracer.restFailure?.({method:s,path:t,requestId:r,phase:"fetch",durationMs:Date.now()-a,error:h}),new Wl({message:`Network error calling ${s} ${t}`,cause:h,method:s,path:t,url:i,requestId:r,phase:"fetch",timeoutMs:Y0,timestamp:Date.now(),durationMs:Date.now()-a})}const c=u.headers.get("content-type")??void 0,d=c?.split(";",1)[0]?.trim().toLowerCase();if(!u.ok||d!=="application/zip"){let h;try{h=await u.clone().json()}catch{}if(this.checkAuthRequired(u,h?.code??0),!u.ok||h!==void 0&&h.code!==0){const k=h?.code??u.status,w=h?.msg??u.statusText;throw this.tracer.restResponse?.({method:s,path:t,requestId:r,status:u.status,durationMs:Date.now()-a,code:k,msg:w,envelopeRequestId:h?.request_id}),new wd({code:k,msg:w,requestId:h?.request_id??r,details:h?.details,timestamp:Date.now(),durationMs:Date.now()-a})}const m=u.clone(),v=new TypeError(`Expected application/zip, received ${c??"no content type"}`);throw this.tracer.restFailure?.({method:s,path:t,requestId:r,phase:"parse",durationMs:Date.now()-a,status:u.status,error:v}),new Wl({message:`Invalid ZIP response from ${s} ${t}`,cause:v,method:s,path:t,url:i,requestId:r,phase:"parse",timeoutMs:Y0,status:u.status,statusText:u.statusText,contentType:c,bodyPreview:await e9(m),timestamp:Date.now(),durationMs:Date.now()-a})}let f;try{f=await u.blob()}catch(h){throw this.tracer.restFailure?.({method:s,path:t,requestId:r,phase:"parse",durationMs:Date.now()-a,status:u.status,error:h}),new Wl({message:`Failed to read ZIP response from ${s} ${t}`,cause:h,method:s,path:t,url:i,requestId:r,phase:"parse",timeoutMs:Y0,status:u.status,statusText:u.statusText,contentType:c,timestamp:Date.now(),durationMs:Date.now()-a})}return this.tracer.restResponse?.({method:s,path:t,requestId:r,status:u.status,durationMs:Date.now()-a,code:0,msg:""}),{blob:f,contentDisposition:u.headers.get("content-disposition")??void 0}}async postForm(t,n){const o=Cd(this.opts.origin,t,this.opts.restBasePath),s=J0(),i={"X-Request-Id":s};this.addClientHeaders(i);const r=Date.now();this.tracer.restRequest?.({method:"POST",path:t,url:o,requestId:s,body:yU(n)});let l;try{l=await fetch(o,{method:"POST",headers:i,body:n,signal:X0()})}catch(c){throw this.tracer.restFailure?.({method:"POST",path:t,requestId:s,phase:"fetch",durationMs:Date.now()-r,error:c}),new Wl({message:`Network error calling POST ${t}`,cause:c,method:"POST",path:t,url:o,requestId:s,phase:"fetch",timeoutMs:hd,timestamp:Date.now(),durationMs:Date.now()-r})}let a;const u=l.clone();try{a=await l.json()}catch(c){throw this.tracer.restFailure?.({method:"POST",path:t,requestId:s,phase:"parse",durationMs:Date.now()-r,status:l.status,error:c}),new Wl({message:`Failed to parse JSON response from POST ${t}`,cause:c,method:"POST",path:t,url:o,requestId:s,phase:"parse",timeoutMs:hd,status:l.status,statusText:l.statusText,contentType:l.headers.get("content-type")??void 0,bodyPreview:await e9(u),timestamp:Date.now(),durationMs:Date.now()-r})}if(this.tracer.restResponse?.({method:"POST",path:t,requestId:s,status:l.status,durationMs:Date.now()-r,code:a.code,msg:a.msg,envelopeRequestId:a.request_id,data:a.data}),this.checkAuthRequired(l,a.code),a.code!==0)throw new wd({code:a.code,msg:a.msg,requestId:a.request_id,details:a.details,timestamp:Date.now(),durationMs:Date.now()-r});return a.data}async patch(t,n){return this.request("PATCH",t,n)}async put(t,n){return this.request("PUT",t,n)}async delete(t){return this.request("DELETE",t)}async request(t,n,o,s,i=[]){let r=Cd(this.opts.origin,n,this.opts.restBasePath);if(s){const h=new URLSearchParams;Bk(h,s);const m=h.toString();m&&(r=`${r}?${m}`)}const l=J0(),a={"X-Request-Id":l};this.addClientHeaders(a),o!==void 0&&(a["Content-Type"]="application/json; charset=utf-8");const u=Date.now();this.tracer.restRequest?.({method:t,path:n,url:r,requestId:l,body:o});let c;try{c=await fetch(r,{method:t,headers:a,body:o!==void 0?JSON.stringify(o):void 0,signal:X0()})}catch(h){throw this.tracer.restFailure?.({method:t,path:n,requestId:l,phase:"fetch",durationMs:Date.now()-u,error:h}),new Wl({message:`Network error calling ${t} ${n}`,cause:h,method:t,path:n,url:r,requestId:l,phase:"fetch",timeoutMs:hd,timestamp:Date.now(),durationMs:Date.now()-u})}let d;const f=c.clone();try{const h=await c.text();d=c.status===204&&h===""?{code:0,msg:"",data:null,request_id:l}:JSON.parse(h)}catch(h){throw this.tracer.restFailure?.({method:t,path:n,requestId:l,phase:"parse",durationMs:Date.now()-u,status:c.status,error:h}),new Wl({message:`Failed to parse JSON response from ${t} ${n}`,cause:h,method:t,path:n,url:r,requestId:l,phase:"parse",timeoutMs:hd,status:c.status,statusText:c.statusText,contentType:c.headers.get("content-type")??void 0,bodyPreview:await e9(f),timestamp:Date.now(),durationMs:Date.now()-u})}if(this.tracer.restResponse?.({method:t,path:n,requestId:l,status:c.status,durationMs:Date.now()-u,code:d.code,msg:d.msg,envelopeRequestId:d.request_id,data:d.data}),this.checkAuthRequired(c,d.code),d.code!==0&&!i.includes(d.code))throw new wd({code:d.code,msg:typeof d.msg=="string"&&d.msg.length>0?d.msg:`HTTP ${c.status}${c.statusText?` ${c.statusText}`:""}`,requestId:d.request_id??l,details:d.details,timestamp:Date.now(),durationMs:Date.now()-u});return d.data}addClientHeaders(t){const n=this.opts.credentialStore?.getToken();n!==void 0&&(t.Authorization=`Bearer ${n}`);const o=this.opts.identity;o!==void 0&&(t["X-Kimi-Client-Id"]=o.clientId,t["X-Kimi-Client-Name"]=o.clientName,t["X-Kimi-Client-Version"]=o.clientVersion,t["X-Kimi-Client-Ui-Mode"]=o.clientUiMode)}checkAuthRequired(t,n){(t.status===401||n===PM)&&this.opts.credentialStore?.markAuthRequired?.()}}function DM(e){return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_tokens,cacheCreationTokens:e.cache_creation_tokens,totalCostUsd:e.total_cost_usd,contextTokens:e.context_tokens,contextLimit:e.context_limit,turnCount:e.turn_count}}function o3(e){return e.contextTokens===0&&e.contextLimit===0&&e.inputTokens===0&&e.outputTokens===0&&e.turnCount===0}function Fr(e){return{id:e.id,title:e.title,createdAt:e.created_at,updatedAt:e.updated_at,busy:e.busy,mainTurnActive:e.main_turn_active,pendingInteraction:e.pending_interaction,lastTurnReason:e.last_turn_reason,archived:e.archived??!1,currentPromptId:e.current_prompt_id,lastPrompt:e.last_prompt,cwd:e.metadata.cwd,model:e.agent_config.model,usage:DM(e.usage),messageCount:e.message_count,lastSeq:e.last_seq,workspaceId:e.workspace_id,parentSessionId:typeof e.metadata.parent_session_id=="string"?e.metadata.parent_session_id:void 0}}function kU(e){const t=e.activity.status;return{id:e.id,title:e.meta.title??e.meta.last_prompt??e.id.slice(0,12),createdAt:new Date(e.meta.created_at).toISOString(),updatedAt:new Date(e.meta.updated_at).toISOString(),busy:t==="running",pendingInteraction:t==="approval"?"approval":t==="question"?"question":void 0,lastTurnReason:t==="failed"?"failed":void 0,archived:e.meta.archived,lastPrompt:e.meta.last_prompt??void 0,cwd:e.workspace.cwd??"",model:"",pullRequest:e.git===void 0?void 0:e.git.pull_request,usage:{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,totalCostUsd:0,contextTokens:0,contextLimit:0,turnCount:0},messageCount:0,lastSeq:0,workspaceId:e.workspace.id.length>0?e.workspace.id:void 0}}function Pf(e){return{id:e.id,root:e.root,name:e.name,lastOpenedAt:e.last_opened_at,sessionCount:e.session_count}}function zk(e){return e.kind==="base64"?{kind:"base64",mediaType:e.media_type,data:e.data}:e.kind==="file"?{kind:"file",fileId:e.file_id}:{kind:"url",url:e.url}}function ry(e){switch(e.type){case"text":return{type:"text",text:e.text};case"tool_use":return{type:"toolUse",toolCallId:e.tool_call_id,toolName:e.tool_name,input:e.input};case"tool_result":return{type:"toolResult",toolCallId:e.tool_call_id,output:e.output,isError:e.is_error};case"image":return{type:"image",source:zk(e.source)};case"video":return{type:"video",source:zk(e.source)};case"file":return{type:"file",fileId:e.file_id,name:e.name,mediaType:e.media_type,size:e.size};case"thinking":return{type:"thinking",thinking:e.thinking,signature:e.signature};default:return{type:"unknown",raw:e}}}function s3(e){return{id:e.id,sessionId:e.session_id,role:e.role,content:e.content.map(ry),createdAt:e.created_at,promptId:e.prompt_id,parentMessageId:e.parent_message_id,metadata:e.metadata}}function BM(e){switch(e.type){case"text":return{type:"text",text:e.text};case"toolUse":return{type:"tool_use",tool_call_id:e.toolCallId,tool_name:e.toolName,input:e.input};case"toolResult":return{type:"tool_result",tool_call_id:e.toolCallId,output:e.output,is_error:e.isError};case"image":case"video":{const t=e.source;let n;return t.kind==="base64"?n={kind:"base64",media_type:t.mediaType,data:t.data}:t.kind==="file"?n={kind:"file",file_id:t.fileId}:n={kind:"url",url:t.url},{type:e.type,source:n}}case"file":return{type:"file",file_id:e.fileId,name:e.name,media_type:e.mediaType,size:e.size};case"thinking":return{type:"thinking",thinking:e.thinking,signature:e.signature};case"unknown":return e.raw}}function bU(e){return{content:e.content.map(BM),metadata:e.metadata,agent_id:e.agentId,model:e.model,thinking:e.thinking,permission_mode:e.permissionMode,plan_mode:e.planMode,swarm_mode:e.swarmMode,goal_objective:e.goalObjective,goal_control:e.goalControl}}function CU(e){return{decision:e.decision,scope:e.scope,feedback:e.feedback,selected_label:e.selectedLabel}}function HM(e){return{approvalId:e.approval_id,sessionId:e.session_id,turnId:e.turn_id,toolCallId:e.tool_call_id,toolName:e.tool_name,action:e.action,display:e.tool_input_display??e.display,expiresAt:e.expires_at,createdAt:e.created_at}}function wU(e){return{id:e.id,label:e.label,description:e.description,recommended:e.recommended===!0||e.is_recommended===!0}}function _U(e){return{id:e.id,question:e.question,header:e.header,body:e.body,options:e.options.map(wU),multiSelect:e.multi_select,allowOther:e.allow_other,otherLabel:e.other_label,otherDescription:e.other_description}}function zM(e){return{questionId:e.question_id,sessionId:e.session_id,turnId:e.turn_id,toolCallId:e.tool_call_id,questions:e.questions.map(_U),createdAt:e.created_at}}function xU(e){switch(e.kind){case"single":return{kind:"single",option_id:e.optionId};case"multi":return{kind:"multi",option_ids:e.optionIds};case"other":return{kind:"other",text:e.text};case"multiWithOther":return{kind:"multi_with_other",option_ids:e.optionIds,other_text:e.otherText};case"skipped":return{kind:"skipped"}}}function SU(e){const t={};for(const[n,o]of Object.entries(e.answers))t[n]=xU(o);return{answers:t,method:e.method,note:e.note}}function Hh(e,t){return{id:e.id,agentId:e.agent_id??t,sessionId:e.session_id,kind:e.kind,description:e.description,status:e.status,command:e.command,createdAt:e.created_at,startedAt:e.started_at,completedAt:e.completed_at,outputPreview:e.output_preview,outputBytes:e.output_bytes,subagentPhase:e.subagent_phase,subagentType:e.subagent_type,model:e.model,thinkingEffort:e.thinking_effort,parentToolCallId:e.parent_tool_call_id,suspendedReason:e.suspended_reason,swarmIndex:e.swarm_index,runInBackground:e.run_in_background??(e.kind==="subagent"?!0:void 0)}}function Wk(e){return{path:e.path,name:e.name,kind:e.kind,size:e.size,modifiedAt:e.modified_at,etag:e.etag,mime:e.mime,languageId:e.language_id,isBinary:e.is_binary,isSymlinkTo:e.is_symlink_to,gitStatus:e.git_status,childCount:e.child_count}}function ba(e,t){const n=e[t];return typeof n=="string"?n:void 0}function td(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:void 0}function pr(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null}function WM(e){if(!e||typeof e!="object")return null;const t=e,n=ba(t,"status");if(n!=="active"&&n!=="paused"&&n!=="blocked"&&n!=="complete")return null;const o=t.budget,s=o&&typeof o=="object"?o:{};return{goalId:ba(t,"goalId")??ba(t,"goal_id")??"goal",objective:ba(t,"objective")??"",completionCriterion:ba(t,"completionCriterion")??ba(t,"completion_criterion"),status:n,turnsUsed:td(t,"turnsUsed")??td(t,"turns_used")??0,tokensUsed:td(t,"tokensUsed")??td(t,"tokens_used")??0,wallClockMs:td(t,"wallClockMs")??td(t,"wall_clock_ms")??0,terminalReason:ba(t,"terminalReason")??ba(t,"terminal_reason"),budget:{tokenBudget:pr(s,"tokenBudget")??pr(s,"token_budget"),remainingTokens:pr(s,"remainingTokens")??pr(s,"remaining_tokens"),turnBudget:pr(s,"turnBudget")??pr(s,"turn_budget"),remainingTurns:pr(s,"remainingTurns")??pr(s,"remaining_turns"),wallClockBudgetMs:pr(s,"wallClockBudgetMs")??pr(s,"wall_clock_budget_ms"),remainingWallClockMs:pr(s,"remainingWallClockMs")??pr(s,"remaining_wall_clock_ms"),overBudget:s.overBudget===!0||s.over_budget===!0}}}function AU(e){const t=e;switch(e.type){case"event.session.created":return{type:"sessionCreated",session:Fr(t.payload.session)};case"event.session.updated":return{type:"sessionUpdated",session:Fr(t.payload.session),changedFields:t.payload.changed_fields};case"event.session.deleted":return{type:"sessionDeleted",sessionId:t.session_id};case"event.workspace.created":return{type:"workspaceCreated",workspace:Pf(t.payload.workspace)};case"event.workspace.updated":return{type:"workspaceUpdated",workspace:Pf(t.payload.workspace)};case"event.workspace.deleted":return{type:"workspaceDeleted",workspaceId:t.payload.workspace_id,root:t.payload.root};case"event.session.work_changed":return{type:"sessionWorkChanged",sessionId:t.session_id,busy:t.payload.busy,mainTurnActive:t.payload.main_turn_active,pendingInteraction:t.payload.pending_interaction,lastTurnReason:t.payload.last_turn_reason};case"event.session.status_changed":return{type:"sessionWorkChanged",sessionId:t.session_id,busy:t.payload.status!=="idle"&&t.payload.status!=="aborted",mainTurnActive:t.payload.status!=="idle"&&t.payload.status!=="aborted",pendingInteraction:t.payload.status==="awaiting_approval"?"approval":t.payload.status==="awaiting_question"?"question":"none",lastTurnReason:t.payload.status==="aborted"?"cancelled":void 0};case"event.session.usage_updated":return{type:"sessionUsageUpdated",sessionId:t.session_id,usage:DM(t.payload.usage)};case"event.session.history_compacted":return{type:"historyCompacted",sessionId:t.session_id,beforeSeq:t.payload.before_seq,reason:t.payload.reason,summaryMessageId:t.payload.summary_message_id};case"event.goal.updated":{const n=WM(t.payload.snapshot??null);return{type:"goalUpdated",sessionId:t.session_id,goal:n?.status==="complete"?null:n}}case"event.message.created":return{type:"messageCreated",message:s3(t.payload.message)};case"event.message.updated":return{type:"messageUpdated",sessionId:t.session_id,messageId:t.payload.message_id,content:t.payload.content.map(ry),status:t.payload.status};case"event.assistant.delta":return{type:"assistantDelta",sessionId:t.session_id,messageId:t.payload.message_id,contentIndex:t.payload.content_index,delta:t.payload.delta};case"event.assistant.tool_use_started":case"event.assistant.tool_use_delta":case"event.assistant.tool_use_completed":case"event.assistant.completed":case"event.tool.started":return{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.tool.output":return{type:"toolOutput",sessionId:t.session_id,toolCallId:t.payload.tool_call_id,outputChunk:t.payload.chunk,stream:t.payload.stream};case"event.tool.progress":return typeof t.payload.message=="string"&&t.payload.message.length>0?{type:"toolOutput",sessionId:t.session_id,toolCallId:t.payload.tool_call_id,outputChunk:t.payload.message,stream:"stdout"}:{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.tool.completed":return{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.approval.requested":return{type:"approvalRequested",sessionId:t.session_id,approval:HM(t.payload)};case"event.approval.resolved":return{type:"approvalResolved",sessionId:t.session_id,approvalId:t.payload.approval_id,decision:t.payload.decision,resolvedAt:t.payload.resolved_at};case"event.approval.expired":return{type:"approvalExpired",sessionId:t.session_id,approvalId:t.payload.approval_id};case"event.question.requested":return{type:"questionRequested",sessionId:t.session_id,question:zM(t.payload)};case"event.question.answered":return{type:"questionAnswered",sessionId:t.session_id,questionId:t.payload.question_id,resolvedAt:t.payload.resolved_at};case"event.question.dismissed":return{type:"questionDismissed",sessionId:t.session_id,questionId:t.payload.question_id,dismissedAt:t.payload.dismissed_at};case"event.task.created":return{type:"taskCreated",sessionId:t.session_id,task:Hh(t.payload.task)};case"event.task.progress":return{type:"taskProgress",sessionId:t.session_id,taskId:t.payload.task_id,outputChunk:t.payload.output_chunk,stream:t.payload.stream};case"event.task.completed":return{type:"taskCompleted",sessionId:t.session_id,taskId:t.payload.task_id,status:t.payload.status,outputPreview:t.payload.output_preview,outputBytes:t.payload.output_bytes};case"event.config.changed":return{type:"configChanged",changedFields:t.payload.changed_fields,config:i3(t.payload.config)};case"event.model_catalog.changed":return{type:"modelCatalogChanged",changed:t.payload.changed.map(n=>({providerId:n.provider_id,providerName:n.provider_name,added:n.added,removed:n.removed})),unchanged:t.payload.unchanged,failed:t.payload.failed};default:return{type:"unknown",raw:e}}}function MU(e){return{id:e.model,provider:e.provider,model:e.model,displayName:e.display_name,maxContextSize:e.max_context_size,capabilities:e.capabilities,supportEfforts:e.support_efforts,defaultEffort:e.default_effort}}function nd(e){return{id:e.id,type:e.type,baseUrl:e.base_url,defaultModel:e.default_model,hasApiKey:e.has_api_key,status:e.status,models:e.models}}function Uk(e){return{id:e.id,name:e.name,wireType:e.wire_type,guessed:e.guessed,needsBaseUrl:e.needs_base_url,rejected:e.rejected,rejectReason:e.reject_reason,envKey:e.env_key,models:e.models.map(t=>({id:t.id,name:t.name,maxContextSize:t.max_context_size,capabilities:t.capabilities,reasoning:t.reasoning}))}}function i3(e){const t={};for(const[n,o]of Object.entries(e.providers))t[n]={type:o.type,baseUrl:o.base_url,defaultModel:o.default_model,hasApiKey:o.has_api_key};return{providers:t,defaultProvider:e.default_provider,defaultModel:e.default_model,secondaryModel:e.secondary_model,models:e.models,thinking:e.thinking,planMode:e.plan_mode,yolo:e.yolo,defaultPermissionMode:e.default_permission_mode,defaultPlanMode:e.default_plan_mode,permission:e.permission,hooks:e.hooks,services:e.services,mergeAllAvailableSkills:e.merge_all_available_skills,extraSkillDirs:e.extra_skill_dirs,loopControl:e.loop_control,background:e.background,experimental:e.experimental,telemetry:e.telemetry,raw:e.raw}}function TU(e){return e.session_id}function EU(e){return e.seq}function IU(e){const t=Number(e.slice(1));return Number.isFinite(t)?t:0}const LU={items:[],tasks:new Map,interactions:new Map,attachments:new Map,todos:new Map,prompts:new Map,meta:{},pendingInteractions:new Set,hasMoreOlder:!1};function $U(e,t){switch(t.op){case"reset":return NU(e,t);case"turn.upsert":return RU(e,t.turn);case"step.upsert":return PU(e,t.turnId,t.step);case"frame.upsert":return BU(e,t);case"append":return zU(e,t);case"marker.upsert":return Vk(e,t.item,t.item.markerId,t.beforeTurn);case"taskref.upsert":return Vk(e,t.item,t.item.refId,t.beforeTurn);case"task.upsert":return jU(e,t.task);case"interaction.upsert":return VU(e,t.interaction);case"attachment.upsert":return KU(e,t.attachment);case"todo.upsert":return GU(e,t.todo);case"prompt.upsert":return XU(e,t.prompt);case"meta.merge":return ej(e,t.meta);case"items.remove":return UU(e,t.ids)}}function NU(e,t){const n=new Set;for(const o of t.snapshot.interactions)o.state==="pending"&&n.add(o.interactionId);return{state:{items:t.snapshot.items,tasks:new Map(t.snapshot.tasks.map(o=>[o.taskId,o])),interactions:new Map(t.snapshot.interactions.map(o=>[o.interactionId,o])),attachments:new Map(t.snapshot.attachments.map(o=>[o.attachmentId,o])),todos:new Map(t.snapshot.todos.map(o=>[o.todoId,o])),prompts:new Map(t.snapshot.prompts.map(o=>[o.promptId,o])),meta:t.snapshot.meta,pendingInteractions:n,hasMoreOlder:t.snapshot.hasMoreOlder??!1},changed:!0}}function jk(e,t){return{...e,kind:"turn",steps:[...t]}}function UM(e){return{kind:"turn",turnId:e,ordinal:IU(e),state:"running",origin:{kind:"other"},steps:[]}}function FU(e,t){const n=Number(e.slice(t.length+1))||0;return{kind:"step",stepId:e,turnId:t,ordinal:n,state:"running",frames:[]}}function n1(e,t){const n=e.items.find(o=>o.kind==="turn"&&o.turnId===t);return n?.kind==="turn"?n:void 0}function ly(e,t){const n=[...e];let o=n.length;for(let s=0;s<n.length;s+=1){const i=n[s];if(i?.kind==="turn"&&i.ordinal>t.ordinal){o=s;break}}return n.splice(o,0,t),n}function r2(e,t,n){return e.map(o=>o.kind==="turn"&&o.turnId===t?n(o):o)}function RU(e,t){const n=n1(e,t.turnId);return n?OU(n,t)?{state:e,changed:!1}:{state:{...e,items:r2(e.items,t.turnId,o=>jk(t,o.steps))},changed:!0}:{state:{...e,items:ly(e.items,jk(t,[]))},changed:!0}}function OU(e,t){return e.ordinal===t.ordinal&&e.state===t.state&&e.prompt===t.prompt&&e.attachmentIds===t.attachmentIds&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.origin.kind===t.origin.kind&&e.origin.payload===t.origin.payload&&e.usage===t.usage&&e.durationMs===t.durationMs&&e.error===t.error}function PU(e,t,n){const o=n1(e,t)??UM(t),s=o.steps.findIndex(u=>u.stepId===n.stepId);let i,r=!0;if(s>=0){const u=o.steps[s];u&&DU(u,n)?(r=!1,i=o.steps):i=o.steps.map(c=>c.stepId===n.stepId?{...n,kind:"step",frames:c.frames}:c)}else i=[...o.steps,{...n,kind:"step",frames:[]}].toSorted((u,c)=>u.ordinal-c.ordinal);if(!r)return{state:e,changed:!1};const l={...o,steps:[...i]},a=n1(e,t)?r2(e.items,t,()=>l):ly(e.items,l);return{state:{...e,items:a},changed:!0}}function DU(e,t){return e.ordinal===t.ordinal&&e.state===t.state&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.usage===t.usage&&e.finishReason===t.finishReason&&e.timing===t.timing&&e.retry===t.retry&&e.endReason===t.endReason&&e.endMessage===t.endMessage}function BU(e,t){const n=n1(e,t.turnId)??UM(t.turnId),o=n.steps.find(c=>c.stepId===t.stepId)??FU(t.stepId,t.turnId),s=o.frames.findIndex(c=>c.frameId===t.frame.frameId);let i;if(s>=0){const c=o.frames[s];if(c!==void 0&&HU(c,t.frame))return{state:e,changed:!1};i=o.frames.map(d=>d.frameId===t.frame.frameId?t.frame:d)}else i=[...o.frames,t.frame];const r={...o,frames:[...i]},l=n.steps.some(c=>c.stepId===t.stepId)?n.steps.map(c=>c.stepId===t.stepId?r:c):[...n.steps,r].toSorted((c,d)=>c.ordinal-d.ordinal),a={...n,steps:l},u=n1(e,t.turnId)?r2(e.items,t.turnId,()=>a):ly(e.items,a);return{state:{...e,items:u},changed:!0}}function HU(e,t){return e.kind!==t.kind?!1:e.kind==="text"&&t.kind==="text"?e.text===t.text&&e.role===t.role&&e.attachmentIds===t.attachmentIds&&e.taskId===t.taskId:e.kind==="thinking"&&t.kind==="thinking"?e.text===t.text:e.kind==="tool"&&t.kind==="tool"?e.state===t.state&&e.toolCallId===t.toolCallId&&e.name===t.name&&e.view===t.view&&e.input===t.input&&e.output===t.output&&e.display===t.display&&e.error===t.error&&e.inputText===t.inputText&&e.progress===t.progress&&e.taskId===t.taskId&&e.approvalId===t.approvalId&&e.todoId===t.todoId&&e.agentRefs===t.agentRefs:e.kind==="notice"&&t.kind==="notice"?e.message===t.message&&e.level===t.level&&e.detail===t.detail:!1}function zU(e,t){if(t.target.type==="task")return WU(e,t);const{turnId:n,stepId:o,frameId:s}=t.target,i=n1(e,n),r=i?.steps.find(f=>f.stepId===o),l=r?.frames.find(f=>f.frameId===s);if(!i||!r||!l||l.kind!=="text"&&l.kind!=="thinking")return{state:e,changed:!1,gap:{expected:0,got:t.offset}};const a=jM(l.text,t.offset,t.text);if(a.gap)return{state:e,changed:!1,gap:a.gap};if(!a.changed)return{state:e,changed:!1};const u={...l,text:a.text},c={...r,frames:r.frames.map(f=>f.frameId===s?u:f)},d={...i,steps:i.steps.map(f=>f.stepId===o?c:f)};return{state:{...e,items:r2(e.items,n,()=>d)},changed:!0}}function WU(e,t){if(t.target.type!=="task")throw new Error("unreachable");const n=t.target.taskId,o=e.tasks.get(n),s=o?.outputTail??"",i=jM(s,t.offset,t.text);if(i.gap)return{state:e,changed:!1,gap:i.gap};if(!i.changed)return{state:e,changed:!1};const r=o?{...o,outputTail:i.text}:{taskId:n,kind:"other",state:"running",detached:!1,outputTail:i.text},l=new Map(e.tasks);return l.set(n,r),{state:{...e,tasks:l},changed:!0}}function jM(e,t,n){if(t>e.length)return{text:e,changed:!1,gap:{expected:e.length,got:t}};if(e.slice(t,t+n.length)===n)return{text:e,changed:!1};const o=e.length-t;return e.slice(t)!==n.slice(0,o)?{text:e,changed:!1,gap:{expected:e.length,got:t}}:(o>0?n.slice(o):n).length===0?{text:e,changed:!1}:{text:e.slice(0,t)+n,changed:!0}}function Vk(e,t,n,o){if(e.items.some(i=>r3(i)===n)){let i=!1;const r=e.items.map(l=>r3(l)!==n||l===t?l:(i=!0,t));return i?{state:{...e,items:r},changed:!0}:{state:e,changed:!1}}if(o!==void 0){const i=[...e.items];let r=i.length;for(let l=0;l<i.length;l+=1){const a=i[l];if(a?.kind==="turn"&&a.ordinal>=o){r=l;break}}return i.splice(r,0,t),{state:{...e,items:i},changed:!0}}return{state:{...e,items:[...e.items,t]},changed:!0}}function r3(e){switch(e.kind){case"turn":return e.turnId;case"marker":return e.markerId;case"taskref":return e.refId}}function UU(e,t){const n=new Set(t),o=e.items.filter(l=>l.kind==="turn"&&n.has(l.turnId)),s=e.items.filter(l=>!n.has(r3(l)));if(s.length===e.items.length)return{state:e,changed:!1};let i=e.pendingInteractions,r=e.interactions;if(o.length>0){const l=new Set,a=new Set(i),u=new Set;for(const c of o)for(const d of c.steps)for(const f of d.frames)f.kind==="tool"&&l.add(f.toolCallId);for(const c of r.values())c.toolCallId!==void 0&&l.has(c.toolCallId)&&(u.add(c.interactionId),a.delete(c.interactionId));if(u.size>0){const c=new Map(r);for(const d of u)c.delete(d);r=c}i=a}return{state:{...e,items:s,interactions:r,pendingInteractions:i},changed:!0}}function jU(e,t){const n=e.tasks.get(t.taskId);if(n&&QU(n,t))return{state:e,changed:!1};const o=new Map(e.tasks);return o.set(t.taskId,t),{state:{...e,tasks:o},changed:!0}}function VU(e,t){const n=e.interactions.get(t.interactionId);if(n&&qU(n,t))return{state:e,changed:!1};const o=new Map(e.interactions);o.set(t.interactionId,t);let s=e.pendingInteractions;if(t.state==="pending"){if(!s.has(t.interactionId)){const i=new Set(s);i.add(t.interactionId),s=i}}else if(s.has(t.interactionId)){const i=new Set(s);i.delete(t.interactionId),s=i}return{state:{...e,interactions:o,pendingInteractions:s},changed:!0}}function qU(e,t){return e.interactionKind===t.interactionKind&&e.toolCallId===t.toolCallId&&e.state===t.state&&e.request===t.request&&e.response===t.response}function KU(e,t){const n=e.attachments.get(t.attachmentId);if(n&&ZU(n,t))return{state:e,changed:!1};const o=new Map(e.attachments);return o.set(t.attachmentId,t),{state:{...e,attachments:o},changed:!0}}function ZU(e,t){return e.mediaType===t.mediaType&&e.name===t.name&&e.size===t.size&&e.source===t.source&&e.placeholder===t.placeholder}function GU(e,t){const n=e.todos.get(t.todoId);if(n&&YU(n,t))return{state:e,changed:!1};const o=new Map(e.todos);return o.set(t.todoId,t),{state:{...e,todos:o},changed:!0}}function YU(e,t){return e.items===t.items&&e.updatedAt===t.updatedAt}function XU(e,t){const n=e.prompts.get(t.promptId);if(n&&JU(n,t))return{state:e,changed:!1};const o=new Map(e.prompts);return o.set(t.promptId,t),{state:{...e,prompts:o},changed:!0}}function JU(e,t){return e.status===t.status&&e.userMessageId===t.userMessageId&&e.content===t.content&&e.createdAt===t.createdAt&&e.finishedAt===t.finishedAt&&e.steeredAt===t.steeredAt}function QU(e,t){return e.kind===t.kind&&e.state===t.state&&e.detached===t.detached&&e.description===t.description&&e.agentId===t.agentId&&e.outputTail===t.outputTail&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.resultSummary===t.resultSummary&&e.error===t.error&&e.stateReason===t.stateReason&&e.usage===t.usage}function ej(e,t){const n=t.modes!==void 0?{plan:t.modes.plan===null?void 0:t.modes.plan??e.meta.modes?.plan,swarm:t.modes.swarm===null?void 0:t.modes.swarm??e.meta.modes?.swarm}:e.meta.modes,o=t.agent!==void 0?{...e.meta.agent,...t.agent}:e.meta.agent,s={goal:t.goal??e.meta.goal,activity:t.activity??e.meta.activity,modes:n!==void 0&&n.plan===void 0&&n.swarm===void 0?void 0:n,agent:o};return s.goal===e.meta.goal&&s.activity===e.meta.activity&&s.modes===e.meta.modes&&s.agent===e.meta.agent?{state:e,changed:!1}:{state:{...e,meta:s},changed:!0}}class tj{constructor(t){this.agentId=t}#e=LU;#t=new Set;receive(t){return this.apply(t)}apply(t){const n=[];let o,s=this.#e;for(const i of t){const r=$U(s,i);if(r.gap){o={target:i.target,...r.gap};continue}r.changed&&(s=r.state,n.push(i))}if(this.#e=s,n.length>0){const i={agentId:this.agentId,ops:n};for(const r of this.#t)r(i)}return{accepted:n,gap:o}}onChange(t){return this.#t.add(t),{dispose:()=>void this.#t.delete(t)}}getItems(){return this.#e.items}getTurn(t){const n=this.#e.items.find(o=>o.kind==="turn"&&o.turnId===t);return n?.kind==="turn"?n:void 0}getTasks(){return this.#e.tasks}getTask(t){return this.#e.tasks.get(t)}getInteractions(){return this.#e.interactions}getInteraction(t){return this.#e.interactions.get(t)}getAttachments(){return this.#e.attachments}getAttachment(t){return this.#e.attachments.get(t)}getTodos(){return this.#e.todos}getTodo(t){return this.#e.todos.get(t)}getPrompts(){return this.#e.prompts}getPrompt(t){return this.#e.prompts.get(t)}getMeta(){return this.#e.meta}listPendingInteractions(){return[...this.#e.pendingInteractions]}get hasMoreOlder(){return this.#e.hasMoreOlder}snapshot(t){let n=this.#e.items,o=this.#e.hasMoreOlder;if(t!==void 0){const s=n.reduce((i,r)=>r.kind==="turn"?i+1:i,0);if(s>t.tailTurns){const i=s-t.tailTurns,r=[];let l=0;for(const a of n)if(a.kind==="turn"){if(l+=1,l<=i)continue;r.push(a)}else l>i&&r.push(a);n=r,o=!0}}return{items:n,tasks:[...this.#e.tasks.values()],interactions:[...this.#e.interactions.values()],attachments:[...this.#e.attachments.values()],todos:[...this.#e.todos.values()],prompts:[...this.#e.prompts.values()],meta:this.#e.meta,hasMoreOlder:o}}}function ct(e,t,n){function o(l,a){if(l._zod||Object.defineProperty(l,"_zod",{value:{def:a,constr:r,traits:new Set},enumerable:!1}),l._zod.traits.has(e))return;l._zod.traits.add(e),t(l,a);const u=r.prototype,c=Object.keys(u);for(let d=0;d<c.length;d++){const f=c[d];f in l||(l[f]=u[f].bind(l))}}const s=n?.Parent??Object;class i extends s{}Object.defineProperty(i,"name",{value:e});function r(l){var a;const u=n?.Parent?new i:this;o(u,l),(a=u._zod).deferred??(a.deferred=[]);for(const c of u._zod.deferred)c();return u}return Object.defineProperty(r,"init",{value:o}),Object.defineProperty(r,Symbol.hasInstance,{value:l=>n?.Parent&&l instanceof n.Parent?!0:l?._zod?.traits?.has(e)}),Object.defineProperty(r,"name",{value:e}),r}class Bd extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class VM extends Error{constructor(t){super(`Encountered unidirectional transform during encode: ${t}`),this.name="ZodEncodeError"}}const qM={};function Xa(e){return qM}function KM(e){const t=Object.values(e).filter(o=>typeof o=="number");return Object.entries(e).filter(([o,s])=>t.indexOf(+o)===-1).map(([o,s])=>s)}function l3(e,t){return typeof t=="bigint"?t.toString():t}function l2(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function ay(e){return e==null}function uy(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}function nj(e,t){const n=(e.toString().split(".")[1]||"").length,o=t.toString();let s=(o.split(".")[1]||"").length;if(s===0&&/\d?e-\d?/.test(o)){const a=o.match(/\d?e-(\d?)/);a?.[1]&&(s=Number.parseInt(a[1]))}const i=n>s?n:s,r=Number.parseInt(e.toFixed(i).replace(".","")),l=Number.parseInt(t.toFixed(i).replace(".",""));return r%l/10**i}const qk=Symbol("evaluating");function Jn(e,t,n){let o;Object.defineProperty(e,t,{get(){if(o!==qk)return o===void 0&&(o=qk,o=n()),o},set(s){Object.defineProperty(e,t,{value:s})},configurable:!0})}function Mc(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function uu(...e){const t={};for(const n of e){const o=Object.getOwnPropertyDescriptors(n);Object.assign(t,o)}return Object.defineProperties({},t)}function Kk(e){return JSON.stringify(e)}function oj(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}const ZM="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function yp(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}const sj=l2(()=>{if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{const e=Function;return new e(""),!0}catch{return!1}});function o1(e){if(yp(e)===!1)return!1;const t=e.constructor;if(t===void 0||typeof t!="function")return!0;const n=t.prototype;return!(yp(n)===!1||Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")===!1)}function GM(e){return o1(e)?{...e}:Array.isArray(e)?[...e]:e}const ij=new Set(["string","number","symbol"]);function s1(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function cu(e,t,n){const o=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(o._zod.parent=e),o}function Jt(e){const t=e;if(!t)return{};if(typeof t=="string")return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,typeof t.error=="string"?{...t,error:()=>t.error}:t}function rj(e){return Object.keys(e).filter(t=>e[t]._zod.optin==="optional"&&e[t]._zod.optout==="optional")}const lj={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function aj(e,t){const n=e._zod.def,o=n.checks;if(o&&o.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");const i=uu(e._zod.def,{get shape(){const r={};for(const l in t){if(!(l in n.shape))throw new Error(`Unrecognized key: "${l}"`);t[l]&&(r[l]=n.shape[l])}return Mc(this,"shape",r),r},checks:[]});return cu(e,i)}function uj(e,t){const n=e._zod.def,o=n.checks;if(o&&o.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");const i=uu(e._zod.def,{get shape(){const r={...e._zod.def.shape};for(const l in t){if(!(l in n.shape))throw new Error(`Unrecognized key: "${l}"`);t[l]&&delete r[l]}return Mc(this,"shape",r),r},checks:[]});return cu(e,i)}function cj(e,t){if(!o1(t))throw new Error("Invalid input to extend: expected a plain object");const n=e._zod.def.checks;if(n&&n.length>0){const i=e._zod.def.shape;for(const r in t)if(Object.getOwnPropertyDescriptor(i,r)!==void 0)throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}const s=uu(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return Mc(this,"shape",i),i}});return cu(e,s)}function dj(e,t){if(!o1(t))throw new Error("Invalid input to safeExtend: expected a plain object");const n=uu(e._zod.def,{get shape(){const o={...e._zod.def.shape,...t};return Mc(this,"shape",o),o}});return cu(e,n)}function fj(e,t){const n=uu(e._zod.def,{get shape(){const o={...e._zod.def.shape,...t._zod.def.shape};return Mc(this,"shape",o),o},get catchall(){return t._zod.def.catchall},checks:[]});return cu(e,n)}function pj(e,t,n){const s=t._zod.def.checks;if(s&&s.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");const r=uu(t._zod.def,{get shape(){const l=t._zod.def.shape,a={...l};if(n)for(const u in n){if(!(u in l))throw new Error(`Unrecognized key: "${u}"`);n[u]&&(a[u]=e?new e({type:"optional",innerType:l[u]}):l[u])}else for(const u in l)a[u]=e?new e({type:"optional",innerType:l[u]}):l[u];return Mc(this,"shape",a),a},checks:[]});return cu(t,r)}function hj(e,t,n){const o=uu(t._zod.def,{get shape(){const s=t._zod.def.shape,i={...s};if(n)for(const r in n){if(!(r in i))throw new Error(`Unrecognized key: "${r}"`);n[r]&&(i[r]=new e({type:"nonoptional",innerType:s[r]}))}else for(const r in s)i[r]=new e({type:"nonoptional",innerType:s[r]});return Mc(this,"shape",i),i}});return cu(t,o)}function _d(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function xd(e,t){return t.map(n=>{var o;return(o=n).path??(o.path=[]),n.path.unshift(e),n})}function Q0(e){return typeof e=="string"?e:e?.message}function Ja(e,t,n){const o={...e,path:e.path??[]};if(!e.message){const s=Q0(e.inst?._zod.def?.error?.(e))??Q0(t?.error?.(e))??Q0(n.customError?.(e))??Q0(n.localeError?.(e))??"Invalid input";o.message=s}return delete o.inst,delete o.continue,t?.reportInput||delete o.input,o}function cy(e){return Array.isArray(e)?"array":typeof e=="string"?"string":"unknown"}function kp(...e){const[t,n,o]=e;return typeof t=="string"?{message:t,code:"custom",input:n,inst:o}:{...t}}const YM=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,l3,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},XM=ct("$ZodError",YM),JM=ct("$ZodError",YM,{Parent:Error});function mj(e,t=n=>n.message){const n={},o=[];for(const s of e.issues)s.path.length>0?(n[s.path[0]]=n[s.path[0]]||[],n[s.path[0]].push(t(s))):o.push(t(s));return{formErrors:o,fieldErrors:n}}function gj(e,t=n=>n.message){const n={_errors:[]},o=s=>{for(const i of s.issues)if(i.code==="invalid_union"&&i.errors.length)i.errors.map(r=>o({issues:r}));else if(i.code==="invalid_key")o({issues:i.issues});else if(i.code==="invalid_element")o({issues:i.issues});else if(i.path.length===0)n._errors.push(t(i));else{let r=n,l=0;for(;l<i.path.length;){const a=i.path[l];l===i.path.length-1?(r[a]=r[a]||{_errors:[]},r[a]._errors.push(t(i))):r[a]=r[a]||{_errors:[]},r=r[a],l++}}};return o(e),n}const dy=e=>(t,n,o,s)=>{const i=o?Object.assign(o,{async:!1}):{async:!1},r=t._zod.run({value:n,issues:[]},i);if(r instanceof Promise)throw new Bd;if(r.issues.length){const l=new(s?.Err??e)(r.issues.map(a=>Ja(a,i,Xa())));throw ZM(l,s?.callee),l}return r.value},fy=e=>async(t,n,o,s)=>{const i=o?Object.assign(o,{async:!0}):{async:!0};let r=t._zod.run({value:n,issues:[]},i);if(r instanceof Promise&&(r=await r),r.issues.length){const l=new(s?.Err??e)(r.issues.map(a=>Ja(a,i,Xa())));throw ZM(l,s?.callee),l}return r.value},a2=e=>(t,n,o)=>{const s=o?{...o,async:!1}:{async:!1},i=t._zod.run({value:n,issues:[]},s);if(i instanceof Promise)throw new Bd;return i.issues.length?{success:!1,error:new(e??XM)(i.issues.map(r=>Ja(r,s,Xa())))}:{success:!0,data:i.value}},vj=a2(JM),u2=e=>async(t,n,o)=>{const s=o?Object.assign(o,{async:!0}):{async:!0};let i=t._zod.run({value:n,issues:[]},s);return i instanceof Promise&&(i=await i),i.issues.length?{success:!1,error:new e(i.issues.map(r=>Ja(r,s,Xa())))}:{success:!0,data:i.value}},yj=u2(JM),kj=e=>(t,n,o)=>{const s=o?Object.assign(o,{direction:"backward"}):{direction:"backward"};return dy(e)(t,n,s)},bj=e=>(t,n,o)=>dy(e)(t,n,o),Cj=e=>async(t,n,o)=>{const s=o?Object.assign(o,{direction:"backward"}):{direction:"backward"};return fy(e)(t,n,s)},wj=e=>async(t,n,o)=>fy(e)(t,n,o),_j=e=>(t,n,o)=>{const s=o?Object.assign(o,{direction:"backward"}):{direction:"backward"};return a2(e)(t,n,s)},xj=e=>(t,n,o)=>a2(e)(t,n,o),Sj=e=>async(t,n,o)=>{const s=o?Object.assign(o,{direction:"backward"}):{direction:"backward"};return u2(e)(t,n,s)},Aj=e=>async(t,n,o)=>u2(e)(t,n,o),Mj=/^[cC][^\s-]{8,}$/,Tj=/^[0-9a-z]+$/,Ej=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,Ij=/^[0-9a-vA-V]{20}$/,Lj=/^[A-Za-z0-9]{27}$/,$j=/^[a-zA-Z0-9_-]{21}$/,Nj=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,Fj=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Zk=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,Rj=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,Oj="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function Pj(){return new RegExp(Oj,"u")}const Dj=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,Bj=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,Hj=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,zj=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,Wj=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,QM=/^[A-Za-z0-9_-]*$/,Uj=/^\+[1-9]\d{6,14}$/,eT="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",jj=new RegExp(`^${eT}$`);function tT(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return typeof e.precision=="number"?e.precision===-1?`${t}`:e.precision===0?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}function Vj(e){return new RegExp(`^${tT(e)}$`)}function qj(e){const t=tT({precision:e.precision}),n=["Z"];e.local&&n.push(""),e.offset&&n.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const o=`${t}(?:${n.join("|")})`;return new RegExp(`^${eT}T(?:${o})$`)}const Kj=e=>{const t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${t}$`)},Zj=/^-?\d+$/,nT=/^-?\d+(?:\.\d+)?$/,Gj=/^(?:true|false)$/i,Yj=/^[^A-Z]*$/,Xj=/^[^a-z]*$/,qi=ct("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),oT={number:"number",bigint:"bigint",object:"date"},sT=ct("$ZodCheckLessThan",(e,t)=>{qi.init(e,t);const n=oT[typeof t.value];e._zod.onattach.push(o=>{const s=o._zod.bag,i=(t.inclusive?s.maximum:s.exclusiveMaximum)??Number.POSITIVE_INFINITY;t.value<i&&(t.inclusive?s.maximum=t.value:s.exclusiveMaximum=t.value)}),e._zod.check=o=>{(t.inclusive?o.value<=t.value:o.value<t.value)||o.issues.push({origin:n,code:"too_big",maximum:typeof t.value=="object"?t.value.getTime():t.value,input:o.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),iT=ct("$ZodCheckGreaterThan",(e,t)=>{qi.init(e,t);const n=oT[typeof t.value];e._zod.onattach.push(o=>{const s=o._zod.bag,i=(t.inclusive?s.minimum:s.exclusiveMinimum)??Number.NEGATIVE_INFINITY;t.value>i&&(t.inclusive?s.minimum=t.value:s.exclusiveMinimum=t.value)}),e._zod.check=o=>{(t.inclusive?o.value>=t.value:o.value>t.value)||o.issues.push({origin:n,code:"too_small",minimum:typeof t.value=="object"?t.value.getTime():t.value,input:o.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),Jj=ct("$ZodCheckMultipleOf",(e,t)=>{qi.init(e,t),e._zod.onattach.push(n=>{var o;(o=n._zod.bag).multipleOf??(o.multipleOf=t.value)}),e._zod.check=n=>{if(typeof n.value!=typeof t.value)throw new Error("Cannot mix number and bigint in multiple_of check.");(typeof n.value=="bigint"?n.value%t.value===BigInt(0):nj(n.value,t.value)===0)||n.issues.push({origin:typeof n.value,code:"not_multiple_of",divisor:t.value,input:n.value,inst:e,continue:!t.abort})}}),Qj=ct("$ZodCheckNumberFormat",(e,t)=>{qi.init(e,t),t.format=t.format||"float64";const n=t.format?.includes("int"),o=n?"int":"number",[s,i]=lj[t.format];e._zod.onattach.push(r=>{const l=r._zod.bag;l.format=t.format,l.minimum=s,l.maximum=i,n&&(l.pattern=Zj)}),e._zod.check=r=>{const l=r.value;if(n){if(!Number.isInteger(l)){r.issues.push({expected:o,format:t.format,code:"invalid_type",continue:!1,input:l,inst:e});return}if(!Number.isSafeInteger(l)){l>0?r.issues.push({input:l,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:o,inclusive:!0,continue:!t.abort}):r.issues.push({input:l,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:o,inclusive:!0,continue:!t.abort});return}}l<s&&r.issues.push({origin:"number",input:l,code:"too_small",minimum:s,inclusive:!0,inst:e,continue:!t.abort}),l>i&&r.issues.push({origin:"number",input:l,code:"too_big",maximum:i,inclusive:!0,inst:e,continue:!t.abort})}}),eV=ct("$ZodCheckMaxLength",(e,t)=>{var n;qi.init(e,t),(n=e._zod.def).when??(n.when=o=>{const s=o.value;return!ay(s)&&s.length!==void 0}),e._zod.onattach.push(o=>{const s=o._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<s&&(o._zod.bag.maximum=t.maximum)}),e._zod.check=o=>{const s=o.value;if(s.length<=t.maximum)return;const r=cy(s);o.issues.push({origin:r,code:"too_big",maximum:t.maximum,inclusive:!0,input:s,inst:e,continue:!t.abort})}}),tV=ct("$ZodCheckMinLength",(e,t)=>{var n;qi.init(e,t),(n=e._zod.def).when??(n.when=o=>{const s=o.value;return!ay(s)&&s.length!==void 0}),e._zod.onattach.push(o=>{const s=o._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>s&&(o._zod.bag.minimum=t.minimum)}),e._zod.check=o=>{const s=o.value;if(s.length>=t.minimum)return;const r=cy(s);o.issues.push({origin:r,code:"too_small",minimum:t.minimum,inclusive:!0,input:s,inst:e,continue:!t.abort})}}),nV=ct("$ZodCheckLengthEquals",(e,t)=>{var n;qi.init(e,t),(n=e._zod.def).when??(n.when=o=>{const s=o.value;return!ay(s)&&s.length!==void 0}),e._zod.onattach.push(o=>{const s=o._zod.bag;s.minimum=t.length,s.maximum=t.length,s.length=t.length}),e._zod.check=o=>{const s=o.value,i=s.length;if(i===t.length)return;const r=cy(s),l=i>t.length;o.issues.push({origin:r,...l?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:o.value,inst:e,continue:!t.abort})}}),c2=ct("$ZodCheckStringFormat",(e,t)=>{var n,o;qi.init(e,t),e._zod.onattach.push(s=>{const i=s._zod.bag;i.format=t.format,t.pattern&&(i.patterns??(i.patterns=new Set),i.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=s=>{t.pattern.lastIndex=0,!t.pattern.test(s.value)&&s.issues.push({origin:"string",code:"invalid_format",format:t.format,input:s.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(o=e._zod).check??(o.check=()=>{})}),oV=ct("$ZodCheckRegex",(e,t)=>{c2.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),sV=ct("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=Yj),c2.init(e,t)}),iV=ct("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=Xj),c2.init(e,t)}),rV=ct("$ZodCheckIncludes",(e,t)=>{qi.init(e,t);const n=s1(t.includes),o=new RegExp(typeof t.position=="number"?`^.{${t.position}}${n}`:n);t.pattern=o,e._zod.onattach.push(s=>{const i=s._zod.bag;i.patterns??(i.patterns=new Set),i.patterns.add(o)}),e._zod.check=s=>{s.value.includes(t.includes,t.position)||s.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:s.value,inst:e,continue:!t.abort})}}),lV=ct("$ZodCheckStartsWith",(e,t)=>{qi.init(e,t);const n=new RegExp(`^${s1(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.onattach.push(o=>{const s=o._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(n)}),e._zod.check=o=>{o.value.startsWith(t.prefix)||o.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:o.value,inst:e,continue:!t.abort})}}),aV=ct("$ZodCheckEndsWith",(e,t)=>{qi.init(e,t);const n=new RegExp(`.*${s1(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.onattach.push(o=>{const s=o._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(n)}),e._zod.check=o=>{o.value.endsWith(t.suffix)||o.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:o.value,inst:e,continue:!t.abort})}}),uV=ct("$ZodCheckOverwrite",(e,t)=>{qi.init(e,t),e._zod.check=n=>{n.value=t.tx(n.value)}});class cV{constructor(t=[]){this.content=[],this.indent=0,this&&(this.args=t)}indented(t){this.indent+=1,t(this),this.indent-=1}write(t){if(typeof t=="function"){t(this,{execution:"sync"}),t(this,{execution:"async"});return}const o=t.split(` +`).filter(r=>r),s=Math.min(...o.map(r=>r.length-r.trimStart().length)),i=o.map(r=>r.slice(s)).map(r=>" ".repeat(this.indent*2)+r);for(const r of i)this.content.push(r)}compile(){const t=Function,n=this?.args,s=[...(this?.content??[""]).map(i=>` ${i}`)];return new t(...n,s.join(` +`))}}const dV={major:4,minor:3,patch:6},No=ct("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=dV;const o=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&o.unshift(e);for(const s of o)for(const i of s._zod.onattach)i(e);if(o.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const s=(r,l,a)=>{let u=_d(r),c;for(const d of l){if(d._zod.def.when){if(!d._zod.def.when(r))continue}else if(u)continue;const f=r.issues.length,h=d._zod.check(r);if(h instanceof Promise&&a?.async===!1)throw new Bd;if(c||h instanceof Promise)c=(c??Promise.resolve()).then(async()=>{await h,r.issues.length!==f&&(u||(u=_d(r,f)))});else{if(r.issues.length===f)continue;u||(u=_d(r,f))}}return c?c.then(()=>r):r},i=(r,l,a)=>{if(_d(r))return r.aborted=!0,r;const u=s(l,o,a);if(u instanceof Promise){if(a.async===!1)throw new Bd;return u.then(c=>e._zod.parse(c,a))}return e._zod.parse(u,a)};e._zod.run=(r,l)=>{if(l.skipChecks)return e._zod.parse(r,l);if(l.direction==="backward"){const u=e._zod.parse({value:r.value,issues:[]},{...l,skipChecks:!0});return u instanceof Promise?u.then(c=>i(c,r,l)):i(u,r,l)}const a=e._zod.parse(r,l);if(a instanceof Promise){if(l.async===!1)throw new Bd;return a.then(u=>s(u,o,l))}return s(a,o,l)}}Jn(e,"~standard",()=>({validate:s=>{try{const i=vj(e,s);return i.success?{value:i.data}:{issues:i.error?.issues}}catch{return yj(e,s).then(r=>r.success?{value:r.data}:{issues:r.error?.issues})}},vendor:"zod",version:1}))}),py=ct("$ZodString",(e,t)=>{No.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??Kj(e._zod.bag),e._zod.parse=(n,o)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value=="string"||n.issues.push({expected:"string",code:"invalid_type",input:n.value,inst:e}),n}}),Mo=ct("$ZodStringFormat",(e,t)=>{c2.init(e,t),py.init(e,t)}),fV=ct("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=Fj),Mo.init(e,t)}),pV=ct("$ZodUUID",(e,t)=>{if(t.version){const o={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(o===void 0)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=Zk(o))}else t.pattern??(t.pattern=Zk());Mo.init(e,t)}),hV=ct("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=Rj),Mo.init(e,t)}),mV=ct("$ZodURL",(e,t)=>{Mo.init(e,t),e._zod.check=n=>{try{const o=n.value.trim(),s=new URL(o);t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(s.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:t.hostname.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(s.protocol.endsWith(":")?s.protocol.slice(0,-1):s.protocol)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),t.normalize?n.value=s.href:n.value=o;return}catch{n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),gV=ct("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=Pj()),Mo.init(e,t)}),vV=ct("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=$j),Mo.init(e,t)}),yV=ct("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=Mj),Mo.init(e,t)}),kV=ct("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=Tj),Mo.init(e,t)}),bV=ct("$ZodULID",(e,t)=>{t.pattern??(t.pattern=Ej),Mo.init(e,t)}),CV=ct("$ZodXID",(e,t)=>{t.pattern??(t.pattern=Ij),Mo.init(e,t)}),wV=ct("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=Lj),Mo.init(e,t)}),_V=ct("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=qj(t)),Mo.init(e,t)}),xV=ct("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=jj),Mo.init(e,t)}),SV=ct("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=Vj(t)),Mo.init(e,t)}),AV=ct("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=Nj),Mo.init(e,t)}),MV=ct("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=Dj),Mo.init(e,t),e._zod.bag.format="ipv4"}),TV=ct("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=Bj),Mo.init(e,t),e._zod.bag.format="ipv6",e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:"invalid_format",format:"ipv6",input:n.value,inst:e,continue:!t.abort})}}}),EV=ct("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=Hj),Mo.init(e,t)}),IV=ct("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=zj),Mo.init(e,t),e._zod.check=n=>{const o=n.value.split("/");try{if(o.length!==2)throw new Error;const[s,i]=o;if(!i)throw new Error;const r=Number(i);if(`${r}`!==i)throw new Error;if(r<0||r>128)throw new Error;new URL(`http://[${s}]`)}catch{n.issues.push({code:"invalid_format",format:"cidrv6",input:n.value,inst:e,continue:!t.abort})}}});function rT(e){if(e==="")return!0;if(e.length%4!==0)return!1;try{return atob(e),!0}catch{return!1}}const LV=ct("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=Wj),Mo.init(e,t),e._zod.bag.contentEncoding="base64",e._zod.check=n=>{rT(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});function $V(e){if(!QM.test(e))return!1;const t=e.replace(/[-_]/g,o=>o==="-"?"+":"/"),n=t.padEnd(Math.ceil(t.length/4)*4,"=");return rT(n)}const NV=ct("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=QM),Mo.init(e,t),e._zod.bag.contentEncoding="base64url",e._zod.check=n=>{$V(n.value)||n.issues.push({code:"invalid_format",format:"base64url",input:n.value,inst:e,continue:!t.abort})}}),FV=ct("$ZodE164",(e,t)=>{t.pattern??(t.pattern=Uj),Mo.init(e,t)});function RV(e,t=null){try{const n=e.split(".");if(n.length!==3)return!1;const[o]=n;if(!o)return!1;const s=JSON.parse(atob(o));return!("typ"in s&&s?.typ!=="JWT"||!s.alg||t&&(!("alg"in s)||s.alg!==t))}catch{return!1}}const OV=ct("$ZodJWT",(e,t)=>{Mo.init(e,t),e._zod.check=n=>{RV(n.value,t.alg)||n.issues.push({code:"invalid_format",format:"jwt",input:n.value,inst:e,continue:!t.abort})}}),lT=ct("$ZodNumber",(e,t)=>{No.init(e,t),e._zod.pattern=e._zod.bag.pattern??nT,e._zod.parse=(n,o)=>{if(t.coerce)try{n.value=Number(n.value)}catch{}const s=n.value;if(typeof s=="number"&&!Number.isNaN(s)&&Number.isFinite(s))return n;const i=typeof s=="number"?Number.isNaN(s)?"NaN":Number.isFinite(s)?void 0:"Infinity":void 0;return n.issues.push({expected:"number",code:"invalid_type",input:s,inst:e,...i?{received:i}:{}}),n}}),PV=ct("$ZodNumberFormat",(e,t)=>{Qj.init(e,t),lT.init(e,t)}),DV=ct("$ZodBoolean",(e,t)=>{No.init(e,t),e._zod.pattern=Gj,e._zod.parse=(n,o)=>{if(t.coerce)try{n.value=!!n.value}catch{}const s=n.value;return typeof s=="boolean"||n.issues.push({expected:"boolean",code:"invalid_type",input:s,inst:e}),n}}),BV=ct("$ZodUnknown",(e,t)=>{No.init(e,t),e._zod.parse=n=>n}),HV=ct("$ZodNever",(e,t)=>{No.init(e,t),e._zod.parse=(n,o)=>(n.issues.push({expected:"never",code:"invalid_type",input:n.value,inst:e}),n)});function Gk(e,t,n){e.issues.length&&t.issues.push(...xd(n,e.issues)),t.value[n]=e.value}const zV=ct("$ZodArray",(e,t)=>{No.init(e,t),e._zod.parse=(n,o)=>{const s=n.value;if(!Array.isArray(s))return n.issues.push({expected:"array",code:"invalid_type",input:s,inst:e}),n;n.value=Array(s.length);const i=[];for(let r=0;r<s.length;r++){const l=s[r],a=t.element._zod.run({value:l,issues:[]},o);a instanceof Promise?i.push(a.then(u=>Gk(u,n,r))):Gk(a,n,r)}return i.length?Promise.all(i).then(()=>n):n}});function Fm(e,t,n,o,s){if(e.issues.length){if(s&&!(n in o))return;t.issues.push(...xd(n,e.issues))}e.value===void 0?n in o&&(t.value[n]=void 0):t.value[n]=e.value}function aT(e){const t=Object.keys(e.shape);for(const o of t)if(!e.shape?.[o]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${o}": expected a Zod schema`);const n=rj(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function uT(e,t,n,o,s,i){const r=[],l=s.keySet,a=s.catchall._zod,u=a.def.type,c=a.optout==="optional";for(const d in t){if(l.has(d))continue;if(u==="never"){r.push(d);continue}const f=a.run({value:t[d],issues:[]},o);f instanceof Promise?e.push(f.then(h=>Fm(h,n,d,t,c))):Fm(f,n,d,t,c)}return r.length&&n.issues.push({code:"unrecognized_keys",keys:r,input:t,inst:i}),e.length?Promise.all(e).then(()=>n):n}const WV=ct("$ZodObject",(e,t)=>{if(No.init(e,t),!Object.getOwnPropertyDescriptor(t,"shape")?.get){const l=t.shape;Object.defineProperty(t,"shape",{get:()=>{const a={...l};return Object.defineProperty(t,"shape",{value:a}),a}})}const o=l2(()=>aT(t));Jn(e._zod,"propValues",()=>{const l=t.shape,a={};for(const u in l){const c=l[u]._zod;if(c.values){a[u]??(a[u]=new Set);for(const d of c.values)a[u].add(d)}}return a});const s=yp,i=t.catchall;let r;e._zod.parse=(l,a)=>{r??(r=o.value);const u=l.value;if(!s(u))return l.issues.push({expected:"object",code:"invalid_type",input:u,inst:e}),l;l.value={};const c=[],d=r.shape;for(const f of r.keys){const h=d[f],m=h._zod.optout==="optional",v=h._zod.run({value:u[f],issues:[]},a);v instanceof Promise?c.push(v.then(k=>Fm(k,l,f,u,m))):Fm(v,l,f,u,m)}return i?uT(c,u,l,a,o.value,e):c.length?Promise.all(c).then(()=>l):l}}),UV=ct("$ZodObjectJIT",(e,t)=>{WV.init(e,t);const n=e._zod.parse,o=l2(()=>aT(t)),s=f=>{const h=new cV(["shape","payload","ctx"]),m=o.value,v=_=>{const g=Kk(_);return`shape[${g}]._zod.run({ value: input[${g}], issues: [] }, ctx)`};h.write("const input = payload.value;");const k=Object.create(null);let w=0;for(const _ of m.keys)k[_]=`key_${w++}`;h.write("const newResult = {};");for(const _ of m.keys){const g=k[_],x=Kk(_),T=f[_]?._zod?.optout==="optional";h.write(`const ${g} = ${v(_)};`),T?h.write(` + if (${g}.issues.length) { + if (${x} in input) { + payload.issues = payload.issues.concat(${g}.issues.map(iss => ({ + ...iss, + path: iss.path ? [${x}, ...iss.path] : [${x}] + }))); + } + } + + if (${g}.value === undefined) { + if (${x} in input) { + newResult[${x}] = undefined; + } + } else { + newResult[${x}] = ${g}.value; + } + + `):h.write(` + if (${g}.issues.length) { + payload.issues = payload.issues.concat(${g}.issues.map(iss => ({ + ...iss, + path: iss.path ? [${x}, ...iss.path] : [${x}] + }))); + } + + if (${g}.value === undefined) { + if (${x} in input) { + newResult[${x}] = undefined; + } + } else { + newResult[${x}] = ${g}.value; + } + + `)}h.write("payload.value = newResult;"),h.write("return payload;");const b=h.compile();return(_,g)=>b(f,_,g)};let i;const r=yp,l=!qM.jitless,u=l&&sj.value,c=t.catchall;let d;e._zod.parse=(f,h)=>{d??(d=o.value);const m=f.value;return r(m)?l&&u&&h?.async===!1&&h.jitless!==!0?(i||(i=s(t.shape)),f=i(f,h),c?uT([],m,f,h,d,e):f):n(f,h):(f.issues.push({expected:"object",code:"invalid_type",input:m,inst:e}),f)}});function Yk(e,t,n,o){for(const i of e)if(i.issues.length===0)return t.value=i.value,t;const s=e.filter(i=>!_d(i));return s.length===1?(t.value=s[0].value,s[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(i=>i.issues.map(r=>Ja(r,o,Xa())))}),t)}const cT=ct("$ZodUnion",(e,t)=>{No.init(e,t),Jn(e._zod,"optin",()=>t.options.some(s=>s._zod.optin==="optional")?"optional":void 0),Jn(e._zod,"optout",()=>t.options.some(s=>s._zod.optout==="optional")?"optional":void 0),Jn(e._zod,"values",()=>{if(t.options.every(s=>s._zod.values))return new Set(t.options.flatMap(s=>Array.from(s._zod.values)))}),Jn(e._zod,"pattern",()=>{if(t.options.every(s=>s._zod.pattern)){const s=t.options.map(i=>i._zod.pattern);return new RegExp(`^(${s.map(i=>uy(i.source)).join("|")})$`)}});const n=t.options.length===1,o=t.options[0]._zod.run;e._zod.parse=(s,i)=>{if(n)return o(s,i);let r=!1;const l=[];for(const a of t.options){const u=a._zod.run({value:s.value,issues:[]},i);if(u instanceof Promise)l.push(u),r=!0;else{if(u.issues.length===0)return u;l.push(u)}}return r?Promise.all(l).then(a=>Yk(a,s,e,i)):Yk(l,s,e,i)}}),jV=ct("$ZodDiscriminatedUnion",(e,t)=>{t.inclusive=!1,cT.init(e,t);const n=e._zod.parse;Jn(e._zod,"propValues",()=>{const s={};for(const i of t.options){const r=i._zod.propValues;if(!r||Object.keys(r).length===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(i)}"`);for(const[l,a]of Object.entries(r)){s[l]||(s[l]=new Set);for(const u of a)s[l].add(u)}}return s});const o=l2(()=>{const s=t.options,i=new Map;for(const r of s){const l=r._zod.propValues?.[t.discriminator];if(!l||l.size===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(r)}"`);for(const a of l){if(i.has(a))throw new Error(`Duplicate discriminator value "${String(a)}"`);i.set(a,r)}}return i});e._zod.parse=(s,i)=>{const r=s.value;if(!yp(r))return s.issues.push({code:"invalid_type",expected:"object",input:r,inst:e}),s;const l=o.value.get(r?.[t.discriminator]);return l?l._zod.run(s,i):t.unionFallback?n(s,i):(s.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",discriminator:t.discriminator,input:r,path:[t.discriminator],inst:e}),s)}}),VV=ct("$ZodIntersection",(e,t)=>{No.init(e,t),e._zod.parse=(n,o)=>{const s=n.value,i=t.left._zod.run({value:s,issues:[]},o),r=t.right._zod.run({value:s,issues:[]},o);return i instanceof Promise||r instanceof Promise?Promise.all([i,r]).then(([a,u])=>Xk(n,a,u)):Xk(n,i,r)}});function a3(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(o1(e)&&o1(t)){const n=Object.keys(t),o=Object.keys(e).filter(i=>n.indexOf(i)!==-1),s={...e,...t};for(const i of o){const r=a3(e[i],t[i]);if(!r.valid)return{valid:!1,mergeErrorPath:[i,...r.mergeErrorPath]};s[i]=r.data}return{valid:!0,data:s}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const n=[];for(let o=0;o<e.length;o++){const s=e[o],i=t[o],r=a3(s,i);if(!r.valid)return{valid:!1,mergeErrorPath:[o,...r.mergeErrorPath]};n.push(r.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function Xk(e,t,n){const o=new Map;let s;for(const l of t.issues)if(l.code==="unrecognized_keys"){s??(s=l);for(const a of l.keys)o.has(a)||o.set(a,{}),o.get(a).l=!0}else e.issues.push(l);for(const l of n.issues)if(l.code==="unrecognized_keys")for(const a of l.keys)o.has(a)||o.set(a,{}),o.get(a).r=!0;else e.issues.push(l);const i=[...o].filter(([,l])=>l.l&&l.r).map(([l])=>l);if(i.length&&s&&e.issues.push({...s,keys:i}),_d(e))return e;const r=a3(t.value,n.value);if(!r.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(r.mergeErrorPath)}`);return e.value=r.data,e}const qV=ct("$ZodRecord",(e,t)=>{No.init(e,t),e._zod.parse=(n,o)=>{const s=n.value;if(!o1(s))return n.issues.push({expected:"record",code:"invalid_type",input:s,inst:e}),n;const i=[],r=t.keyType._zod.values;if(r){n.value={};const l=new Set;for(const u of r)if(typeof u=="string"||typeof u=="number"||typeof u=="symbol"){l.add(typeof u=="number"?u.toString():u);const c=t.valueType._zod.run({value:s[u],issues:[]},o);c instanceof Promise?i.push(c.then(d=>{d.issues.length&&n.issues.push(...xd(u,d.issues)),n.value[u]=d.value})):(c.issues.length&&n.issues.push(...xd(u,c.issues)),n.value[u]=c.value)}let a;for(const u in s)l.has(u)||(a=a??[],a.push(u));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:s,inst:e,keys:a})}else{n.value={};for(const l of Reflect.ownKeys(s)){if(l==="__proto__")continue;let a=t.keyType._zod.run({value:l,issues:[]},o);if(a instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(typeof l=="string"&&nT.test(l)&&a.issues.length){const d=t.keyType._zod.run({value:Number(l),issues:[]},o);if(d instanceof Promise)throw new Error("Async schemas not supported in object keys currently");d.issues.length===0&&(a=d)}if(a.issues.length){t.mode==="loose"?n.value[l]=s[l]:n.issues.push({code:"invalid_key",origin:"record",issues:a.issues.map(d=>Ja(d,o,Xa())),input:l,path:[l],inst:e});continue}const c=t.valueType._zod.run({value:s[l],issues:[]},o);c instanceof Promise?i.push(c.then(d=>{d.issues.length&&n.issues.push(...xd(l,d.issues)),n.value[a.value]=d.value})):(c.issues.length&&n.issues.push(...xd(l,c.issues)),n.value[a.value]=c.value)}}return i.length?Promise.all(i).then(()=>n):n}}),KV=ct("$ZodEnum",(e,t)=>{No.init(e,t);const n=KM(t.entries),o=new Set(n);e._zod.values=o,e._zod.pattern=new RegExp(`^(${n.filter(s=>ij.has(typeof s)).map(s=>typeof s=="string"?s1(s):s.toString()).join("|")})$`),e._zod.parse=(s,i)=>{const r=s.value;return o.has(r)||s.issues.push({code:"invalid_value",values:n,input:r,inst:e}),s}}),ZV=ct("$ZodLiteral",(e,t)=>{if(No.init(e,t),t.values.length===0)throw new Error("Cannot create literal schema with no valid values");const n=new Set(t.values);e._zod.values=n,e._zod.pattern=new RegExp(`^(${t.values.map(o=>typeof o=="string"?s1(o):o?s1(o.toString()):String(o)).join("|")})$`),e._zod.parse=(o,s)=>{const i=o.value;return n.has(i)||o.issues.push({code:"invalid_value",values:t.values,input:i,inst:e}),o}}),GV=ct("$ZodTransform",(e,t)=>{No.init(e,t),e._zod.parse=(n,o)=>{if(o.direction==="backward")throw new VM(e.constructor.name);const s=t.transform(n.value,n);if(o.async)return(s instanceof Promise?s:Promise.resolve(s)).then(r=>(n.value=r,n));if(s instanceof Promise)throw new Bd;return n.value=s,n}});function Jk(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const dT=ct("$ZodOptional",(e,t)=>{No.init(e,t),e._zod.optin="optional",e._zod.optout="optional",Jn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),Jn(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${uy(n.source)})?$`):void 0}),e._zod.parse=(n,o)=>{if(t.innerType._zod.optin==="optional"){const s=t.innerType._zod.run(n,o);return s instanceof Promise?s.then(i=>Jk(i,n.value)):Jk(s,n.value)}return n.value===void 0?n:t.innerType._zod.run(n,o)}}),YV=ct("$ZodExactOptional",(e,t)=>{dT.init(e,t),Jn(e._zod,"values",()=>t.innerType._zod.values),Jn(e._zod,"pattern",()=>t.innerType._zod.pattern),e._zod.parse=(n,o)=>t.innerType._zod.run(n,o)}),XV=ct("$ZodNullable",(e,t)=>{No.init(e,t),Jn(e._zod,"optin",()=>t.innerType._zod.optin),Jn(e._zod,"optout",()=>t.innerType._zod.optout),Jn(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${uy(n.source)}|null)$`):void 0}),Jn(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(n,o)=>n.value===null?n:t.innerType._zod.run(n,o)}),JV=ct("$ZodDefault",(e,t)=>{No.init(e,t),e._zod.optin="optional",Jn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,o)=>{if(o.direction==="backward")return t.innerType._zod.run(n,o);if(n.value===void 0)return n.value=t.defaultValue,n;const s=t.innerType._zod.run(n,o);return s instanceof Promise?s.then(i=>Qk(i,t)):Qk(s,t)}});function Qk(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}const QV=ct("$ZodPrefault",(e,t)=>{No.init(e,t),e._zod.optin="optional",Jn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,o)=>(o.direction==="backward"||n.value===void 0&&(n.value=t.defaultValue),t.innerType._zod.run(n,o))}),eq=ct("$ZodNonOptional",(e,t)=>{No.init(e,t),Jn(e._zod,"values",()=>{const n=t.innerType._zod.values;return n?new Set([...n].filter(o=>o!==void 0)):void 0}),e._zod.parse=(n,o)=>{const s=t.innerType._zod.run(n,o);return s instanceof Promise?s.then(i=>eb(i,e)):eb(s,e)}});function eb(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const tq=ct("$ZodCatch",(e,t)=>{No.init(e,t),Jn(e._zod,"optin",()=>t.innerType._zod.optin),Jn(e._zod,"optout",()=>t.innerType._zod.optout),Jn(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,o)=>{if(o.direction==="backward")return t.innerType._zod.run(n,o);const s=t.innerType._zod.run(n,o);return s instanceof Promise?s.then(i=>(n.value=i.value,i.issues.length&&(n.value=t.catchValue({...n,error:{issues:i.issues.map(r=>Ja(r,o,Xa()))},input:n.value}),n.issues=[]),n)):(n.value=s.value,s.issues.length&&(n.value=t.catchValue({...n,error:{issues:s.issues.map(i=>Ja(i,o,Xa()))},input:n.value}),n.issues=[]),n)}}),nq=ct("$ZodPipe",(e,t)=>{No.init(e,t),Jn(e._zod,"values",()=>t.in._zod.values),Jn(e._zod,"optin",()=>t.in._zod.optin),Jn(e._zod,"optout",()=>t.out._zod.optout),Jn(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(n,o)=>{if(o.direction==="backward"){const i=t.out._zod.run(n,o);return i instanceof Promise?i.then(r=>eh(r,t.in,o)):eh(i,t.in,o)}const s=t.in._zod.run(n,o);return s instanceof Promise?s.then(i=>eh(i,t.out,o)):eh(s,t.out,o)}});function eh(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const oq=ct("$ZodReadonly",(e,t)=>{No.init(e,t),Jn(e._zod,"propValues",()=>t.innerType._zod.propValues),Jn(e._zod,"values",()=>t.innerType._zod.values),Jn(e._zod,"optin",()=>t.innerType?._zod?.optin),Jn(e._zod,"optout",()=>t.innerType?._zod?.optout),e._zod.parse=(n,o)=>{if(o.direction==="backward")return t.innerType._zod.run(n,o);const s=t.innerType._zod.run(n,o);return s instanceof Promise?s.then(tb):tb(s)}});function tb(e){return e.value=Object.freeze(e.value),e}const sq=ct("$ZodCustom",(e,t)=>{qi.init(e,t),No.init(e,t),e._zod.parse=(n,o)=>n,e._zod.check=n=>{const o=n.value,s=t.fn(o);if(s instanceof Promise)return s.then(i=>nb(i,n,o,e));nb(s,n,o,e)}});function nb(e,t,n,o){if(!e){const s={code:"custom",input:n,inst:o,path:[...o._zod.def.path??[]],continue:!o._zod.def.abort};o._zod.def.params&&(s.params=o._zod.def.params),t.issues.push(kp(s))}}var ob;class iq{constructor(){this._map=new WeakMap,this._idmap=new Map}add(t,...n){const o=n[0];return this._map.set(t,o),o&&typeof o=="object"&&"id"in o&&this._idmap.set(o.id,t),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(t){const n=this._map.get(t);return n&&typeof n=="object"&&"id"in n&&this._idmap.delete(n.id),this._map.delete(t),this}get(t){const n=t._zod.parent;if(n){const o={...this.get(n)??{}};delete o.id;const s={...o,...this._map.get(t)};return Object.keys(s).length?s:void 0}return this._map.get(t)}has(t){return this._map.has(t)}}function rq(){return new iq}(ob=globalThis).__zod_globalRegistry??(ob.__zod_globalRegistry=rq());const vf=globalThis.__zod_globalRegistry;function lq(e,t){return new e({type:"string",...Jt(t)})}function aq(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...Jt(t)})}function sb(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...Jt(t)})}function uq(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...Jt(t)})}function cq(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...Jt(t)})}function dq(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...Jt(t)})}function fq(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...Jt(t)})}function pq(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...Jt(t)})}function hq(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...Jt(t)})}function mq(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...Jt(t)})}function gq(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...Jt(t)})}function vq(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...Jt(t)})}function yq(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...Jt(t)})}function kq(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...Jt(t)})}function bq(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...Jt(t)})}function Cq(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...Jt(t)})}function wq(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...Jt(t)})}function _q(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...Jt(t)})}function xq(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...Jt(t)})}function Sq(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...Jt(t)})}function Aq(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...Jt(t)})}function Mq(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...Jt(t)})}function Tq(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...Jt(t)})}function Eq(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...Jt(t)})}function Iq(e,t){return new e({type:"string",format:"date",check:"string_format",...Jt(t)})}function Lq(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...Jt(t)})}function $q(e,t){return new e({type:"string",format:"duration",check:"string_format",...Jt(t)})}function Nq(e,t){return new e({type:"number",checks:[],...Jt(t)})}function Fq(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...Jt(t)})}function Rq(e,t){return new e({type:"boolean",...Jt(t)})}function Oq(e){return new e({type:"unknown"})}function Pq(e,t){return new e({type:"never",...Jt(t)})}function ib(e,t){return new sT({check:"less_than",...Jt(t),value:e,inclusive:!1})}function t9(e,t){return new sT({check:"less_than",...Jt(t),value:e,inclusive:!0})}function rb(e,t){return new iT({check:"greater_than",...Jt(t),value:e,inclusive:!1})}function n9(e,t){return new iT({check:"greater_than",...Jt(t),value:e,inclusive:!0})}function lb(e,t){return new Jj({check:"multiple_of",...Jt(t),value:e})}function fT(e,t){return new eV({check:"max_length",...Jt(t),maximum:e})}function Rm(e,t){return new tV({check:"min_length",...Jt(t),minimum:e})}function pT(e,t){return new nV({check:"length_equals",...Jt(t),length:e})}function Dq(e,t){return new oV({check:"string_format",format:"regex",...Jt(t),pattern:e})}function Bq(e){return new sV({check:"string_format",format:"lowercase",...Jt(e)})}function Hq(e){return new iV({check:"string_format",format:"uppercase",...Jt(e)})}function zq(e,t){return new rV({check:"string_format",format:"includes",...Jt(t),includes:e})}function Wq(e,t){return new lV({check:"string_format",format:"starts_with",...Jt(t),prefix:e})}function Uq(e,t){return new aV({check:"string_format",format:"ends_with",...Jt(t),suffix:e})}function g1(e){return new uV({check:"overwrite",tx:e})}function jq(e){return g1(t=>t.normalize(e))}function Vq(){return g1(e=>e.trim())}function qq(){return g1(e=>e.toLowerCase())}function Kq(){return g1(e=>e.toUpperCase())}function Zq(){return g1(e=>oj(e))}function Gq(e,t,n){return new e({type:"array",element:t,...Jt(n)})}function Yq(e,t,n){return new e({type:"custom",check:"custom",fn:t,...Jt(n)})}function Xq(e){const t=Jq(n=>(n.addIssue=o=>{if(typeof o=="string")n.issues.push(kp(o,n.value,t._zod.def));else{const s=o;s.fatal&&(s.continue=!1),s.code??(s.code="custom"),s.input??(s.input=n.value),s.inst??(s.inst=t),s.continue??(s.continue=!t._zod.def.abort),n.issues.push(kp(s))}},e(n.value,n)));return t}function Jq(e,t){const n=new qi({check:"custom",...Jt(t)});return n._zod.check=e,n}function hT(e){let t=e?.target??"draft-2020-12";return t==="draft-4"&&(t="draft-04"),t==="draft-7"&&(t="draft-07"),{processors:e.processors??{},metadataRegistry:e?.metadata??vf,target:t,unrepresentable:e?.unrepresentable??"throw",override:e?.override??(()=>{}),io:e?.io??"output",counter:0,seen:new Map,cycles:e?.cycles??"ref",reused:e?.reused??"inline",external:e?.external??void 0}}function cs(e,t,n={path:[],schemaPath:[]}){var o;const s=e._zod.def,i=t.seen.get(e);if(i)return i.count++,n.schemaPath.includes(e)&&(i.cycle=n.path),i.schema;const r={schema:{},count:1,cycle:void 0,path:n.path};t.seen.set(e,r);const l=e._zod.toJSONSchema?.();if(l)r.schema=l;else{const c={...n,schemaPath:[...n.schemaPath,e],path:n.path};if(e._zod.processJSONSchema)e._zod.processJSONSchema(t,r.schema,c);else{const f=r.schema,h=t.processors[s.type];if(!h)throw new Error(`[toJSONSchema]: Non-representable type encountered: ${s.type}`);h(e,t,f,c)}const d=e._zod.parent;d&&(r.ref||(r.ref=d),cs(d,t,c),t.seen.get(d).isParent=!0)}const a=t.metadataRegistry.get(e);return a&&Object.assign(r.schema,a),t.io==="input"&&gi(e)&&(delete r.schema.examples,delete r.schema.default),t.io==="input"&&r.schema._prefault&&((o=r.schema).default??(o.default=r.schema._prefault)),delete r.schema._prefault,t.seen.get(e).schema}function mT(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const o=new Map;for(const r of e.seen.entries()){const l=e.metadataRegistry.get(r[0])?.id;if(l){const a=o.get(l);if(a&&a!==r[0])throw new Error(`Duplicate schema id "${l}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);o.set(l,r[0])}}const s=r=>{const l=e.target==="draft-2020-12"?"$defs":"definitions";if(e.external){const d=e.external.registry.get(r[0])?.id,f=e.external.uri??(m=>m);if(d)return{ref:f(d)};const h=r[1].defId??r[1].schema.id??`schema${e.counter++}`;return r[1].defId=h,{defId:h,ref:`${f("__shared")}#/${l}/${h}`}}if(r[1]===n)return{ref:"#"};const u=`#/${l}/`,c=r[1].schema.id??`__schema${e.counter++}`;return{defId:c,ref:u+c}},i=r=>{if(r[1].schema.$ref)return;const l=r[1],{ref:a,defId:u}=s(r);l.def={...l.schema},u&&(l.defId=u);const c=l.schema;for(const d in c)delete c[d];c.$ref=a};if(e.cycles==="throw")for(const r of e.seen.entries()){const l=r[1];if(l.cycle)throw new Error(`Cycle detected: #/${l.cycle?.join("/")}/<root> + +Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(const r of e.seen.entries()){const l=r[1];if(t===r[0]){i(r);continue}if(e.external){const u=e.external.registry.get(r[0])?.id;if(t!==r[0]&&u){i(r);continue}}if(e.metadataRegistry.get(r[0])?.id){i(r);continue}if(l.cycle){i(r);continue}if(l.count>1&&e.reused==="ref"){i(r);continue}}}function gT(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const o=r=>{const l=e.seen.get(r);if(l.ref===null)return;const a=l.def??l.schema,u={...a},c=l.ref;if(l.ref=null,c){o(c);const f=e.seen.get(c),h=f.schema;if(h.$ref&&(e.target==="draft-07"||e.target==="draft-04"||e.target==="openapi-3.0")?(a.allOf=a.allOf??[],a.allOf.push(h)):Object.assign(a,h),Object.assign(a,u),r._zod.parent===c)for(const v in a)v==="$ref"||v==="allOf"||v in u||delete a[v];if(h.$ref&&f.def)for(const v in a)v==="$ref"||v==="allOf"||v in f.def&&JSON.stringify(a[v])===JSON.stringify(f.def[v])&&delete a[v]}const d=r._zod.parent;if(d&&d!==c){o(d);const f=e.seen.get(d);if(f?.schema.$ref&&(a.$ref=f.schema.$ref,f.def))for(const h in a)h==="$ref"||h==="allOf"||h in f.def&&JSON.stringify(a[h])===JSON.stringify(f.def[h])&&delete a[h]}e.override({zodSchema:r,jsonSchema:a,path:l.path??[]})};for(const r of[...e.seen.entries()].reverse())o(r[0]);const s={};if(e.target==="draft-2020-12"?s.$schema="https://json-schema.org/draft/2020-12/schema":e.target==="draft-07"?s.$schema="http://json-schema.org/draft-07/schema#":e.target==="draft-04"?s.$schema="http://json-schema.org/draft-04/schema#":e.target,e.external?.uri){const r=e.external.registry.get(t)?.id;if(!r)throw new Error("Schema is missing an `id` property");s.$id=e.external.uri(r)}Object.assign(s,n.def??n.schema);const i=e.external?.defs??{};for(const r of e.seen.entries()){const l=r[1];l.def&&l.defId&&(i[l.defId]=l.def)}e.external||Object.keys(i).length>0&&(e.target==="draft-2020-12"?s.$defs=i:s.definitions=i);try{const r=JSON.parse(JSON.stringify(s));return Object.defineProperty(r,"~standard",{value:{...t["~standard"],jsonSchema:{input:Om(t,"input",e.processors),output:Om(t,"output",e.processors)}},enumerable:!1,writable:!1}),r}catch{throw new Error("Error converting schema to JSON.")}}function gi(e,t){const n=t??{seen:new Set};if(n.seen.has(e))return!1;n.seen.add(e);const o=e._zod.def;if(o.type==="transform")return!0;if(o.type==="array")return gi(o.element,n);if(o.type==="set")return gi(o.valueType,n);if(o.type==="lazy")return gi(o.getter(),n);if(o.type==="promise"||o.type==="optional"||o.type==="nonoptional"||o.type==="nullable"||o.type==="readonly"||o.type==="default"||o.type==="prefault")return gi(o.innerType,n);if(o.type==="intersection")return gi(o.left,n)||gi(o.right,n);if(o.type==="record"||o.type==="map")return gi(o.keyType,n)||gi(o.valueType,n);if(o.type==="pipe")return gi(o.in,n)||gi(o.out,n);if(o.type==="object"){for(const s in o.shape)if(gi(o.shape[s],n))return!0;return!1}if(o.type==="union"){for(const s of o.options)if(gi(s,n))return!0;return!1}if(o.type==="tuple"){for(const s of o.items)if(gi(s,n))return!0;return!!(o.rest&&gi(o.rest,n))}return!1}const Qq=(e,t={})=>n=>{const o=hT({...n,processors:t});return cs(e,o),mT(o,e),gT(o,e)},Om=(e,t,n={})=>o=>{const{libraryOptions:s,target:i}=o??{},r=hT({...s??{},target:i,io:t,processors:n});return cs(e,r),mT(r,e),gT(r,e)},eK={guid:"uuid",url:"uri",datetime:"date-time",json_string:"json-string",regex:""},tK=(e,t,n,o)=>{const s=n;s.type="string";const{minimum:i,maximum:r,format:l,patterns:a,contentEncoding:u}=e._zod.bag;if(typeof i=="number"&&(s.minLength=i),typeof r=="number"&&(s.maxLength=r),l&&(s.format=eK[l]??l,s.format===""&&delete s.format,l==="time"&&delete s.format),u&&(s.contentEncoding=u),a&&a.size>0){const c=[...a];c.length===1?s.pattern=c[0].source:c.length>1&&(s.allOf=[...c.map(d=>({...t.target==="draft-07"||t.target==="draft-04"||t.target==="openapi-3.0"?{type:"string"}:{},pattern:d.source}))])}},nK=(e,t,n,o)=>{const s=n,{minimum:i,maximum:r,format:l,multipleOf:a,exclusiveMaximum:u,exclusiveMinimum:c}=e._zod.bag;typeof l=="string"&&l.includes("int")?s.type="integer":s.type="number",typeof c=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(s.minimum=c,s.exclusiveMinimum=!0):s.exclusiveMinimum=c),typeof i=="number"&&(s.minimum=i,typeof c=="number"&&t.target!=="draft-04"&&(c>=i?delete s.minimum:delete s.exclusiveMinimum)),typeof u=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(s.maximum=u,s.exclusiveMaximum=!0):s.exclusiveMaximum=u),typeof r=="number"&&(s.maximum=r,typeof u=="number"&&t.target!=="draft-04"&&(u<=r?delete s.maximum:delete s.exclusiveMaximum)),typeof a=="number"&&(s.multipleOf=a)},oK=(e,t,n,o)=>{n.type="boolean"},sK=(e,t,n,o)=>{n.not={}},iK=(e,t,n,o)=>{},rK=(e,t,n,o)=>{const s=e._zod.def,i=KM(s.entries);i.every(r=>typeof r=="number")&&(n.type="number"),i.every(r=>typeof r=="string")&&(n.type="string"),n.enum=i},lK=(e,t,n,o)=>{const s=e._zod.def,i=[];for(const r of s.values)if(r===void 0){if(t.unrepresentable==="throw")throw new Error("Literal `undefined` cannot be represented in JSON Schema")}else if(typeof r=="bigint"){if(t.unrepresentable==="throw")throw new Error("BigInt literals cannot be represented in JSON Schema");i.push(Number(r))}else i.push(r);if(i.length!==0)if(i.length===1){const r=i[0];n.type=r===null?"null":typeof r,t.target==="draft-04"||t.target==="openapi-3.0"?n.enum=[r]:n.const=r}else i.every(r=>typeof r=="number")&&(n.type="number"),i.every(r=>typeof r=="string")&&(n.type="string"),i.every(r=>typeof r=="boolean")&&(n.type="boolean"),i.every(r=>r===null)&&(n.type="null"),n.enum=i},aK=(e,t,n,o)=>{if(t.unrepresentable==="throw")throw new Error("Custom types cannot be represented in JSON Schema")},uK=(e,t,n,o)=>{if(t.unrepresentable==="throw")throw new Error("Transforms cannot be represented in JSON Schema")},cK=(e,t,n,o)=>{const s=n,i=e._zod.def,{minimum:r,maximum:l}=e._zod.bag;typeof r=="number"&&(s.minItems=r),typeof l=="number"&&(s.maxItems=l),s.type="array",s.items=cs(i.element,t,{...o,path:[...o.path,"items"]})},dK=(e,t,n,o)=>{const s=n,i=e._zod.def;s.type="object",s.properties={};const r=i.shape;for(const u in r)s.properties[u]=cs(r[u],t,{...o,path:[...o.path,"properties",u]});const l=new Set(Object.keys(r)),a=new Set([...l].filter(u=>{const c=i.shape[u]._zod;return t.io==="input"?c.optin===void 0:c.optout===void 0}));a.size>0&&(s.required=Array.from(a)),i.catchall?._zod.def.type==="never"?s.additionalProperties=!1:i.catchall?i.catchall&&(s.additionalProperties=cs(i.catchall,t,{...o,path:[...o.path,"additionalProperties"]})):t.io==="output"&&(s.additionalProperties=!1)},fK=(e,t,n,o)=>{const s=e._zod.def,i=s.inclusive===!1,r=s.options.map((l,a)=>cs(l,t,{...o,path:[...o.path,i?"oneOf":"anyOf",a]}));i?n.oneOf=r:n.anyOf=r},pK=(e,t,n,o)=>{const s=e._zod.def,i=cs(s.left,t,{...o,path:[...o.path,"allOf",0]}),r=cs(s.right,t,{...o,path:[...o.path,"allOf",1]}),l=u=>"allOf"in u&&Object.keys(u).length===1,a=[...l(i)?i.allOf:[i],...l(r)?r.allOf:[r]];n.allOf=a},hK=(e,t,n,o)=>{const s=n,i=e._zod.def;s.type="object";const r=i.keyType,a=r._zod.bag?.patterns;if(i.mode==="loose"&&a&&a.size>0){const c=cs(i.valueType,t,{...o,path:[...o.path,"patternProperties","*"]});s.patternProperties={};for(const d of a)s.patternProperties[d.source]=c}else(t.target==="draft-07"||t.target==="draft-2020-12")&&(s.propertyNames=cs(i.keyType,t,{...o,path:[...o.path,"propertyNames"]})),s.additionalProperties=cs(i.valueType,t,{...o,path:[...o.path,"additionalProperties"]});const u=r._zod.values;if(u){const c=[...u].filter(d=>typeof d=="string"||typeof d=="number");c.length>0&&(s.required=c)}},mK=(e,t,n,o)=>{const s=e._zod.def,i=cs(s.innerType,t,o),r=t.seen.get(e);t.target==="openapi-3.0"?(r.ref=s.innerType,n.nullable=!0):n.anyOf=[i,{type:"null"}]},gK=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType},vK=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType,n.default=JSON.parse(JSON.stringify(s.defaultValue))},yK=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType,t.io==="input"&&(n._prefault=JSON.parse(JSON.stringify(s.defaultValue)))},kK=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType;let r;try{r=s.catchValue(void 0)}catch{throw new Error("Dynamic catch values are not supported in JSON Schema")}n.default=r},bK=(e,t,n,o)=>{const s=e._zod.def,i=t.io==="input"?s.in._zod.def.type==="transform"?s.out:s.in:s.out;cs(i,t,o);const r=t.seen.get(e);r.ref=i},CK=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType,n.readOnly=!0},vT=(e,t,n,o)=>{const s=e._zod.def;cs(s.innerType,t,o);const i=t.seen.get(e);i.ref=s.innerType},wK=ct("ZodISODateTime",(e,t)=>{_V.init(e,t),Ro.init(e,t)});function _K(e){return Eq(wK,e)}const xK=ct("ZodISODate",(e,t)=>{xV.init(e,t),Ro.init(e,t)});function SK(e){return Iq(xK,e)}const AK=ct("ZodISOTime",(e,t)=>{SV.init(e,t),Ro.init(e,t)});function MK(e){return Lq(AK,e)}const TK=ct("ZodISODuration",(e,t)=>{AV.init(e,t),Ro.init(e,t)});function EK(e){return $q(TK,e)}const IK=(e,t)=>{XM.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:n=>gj(e,n)},flatten:{value:n=>mj(e,n)},addIssue:{value:n=>{e.issues.push(n),e.message=JSON.stringify(e.issues,l3,2)}},addIssues:{value:n=>{e.issues.push(...n),e.message=JSON.stringify(e.issues,l3,2)}},isEmpty:{get(){return e.issues.length===0}}})},Mr=ct("ZodError",IK,{Parent:Error}),LK=dy(Mr),$K=fy(Mr),NK=a2(Mr),FK=u2(Mr),RK=kj(Mr),OK=bj(Mr),PK=Cj(Mr),DK=wj(Mr),BK=_j(Mr),HK=xj(Mr),zK=Sj(Mr),WK=Aj(Mr),Fo=ct("ZodType",(e,t)=>(No.init(e,t),Object.assign(e["~standard"],{jsonSchema:{input:Om(e,"input"),output:Om(e,"output")}}),e.toJSONSchema=Qq(e,{}),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(uu(t,{checks:[...t.checks??[],...n.map(o=>typeof o=="function"?{_zod:{check:o,def:{check:"custom"},onattach:[]}}:o)]}),{parent:!0}),e.with=e.check,e.clone=(n,o)=>cu(e,n,o),e.brand=()=>e,e.register=((n,o)=>(n.add(e,o),e)),e.parse=(n,o)=>LK(e,n,o,{callee:e.parse}),e.safeParse=(n,o)=>NK(e,n,o),e.parseAsync=async(n,o)=>$K(e,n,o,{callee:e.parseAsync}),e.safeParseAsync=async(n,o)=>FK(e,n,o),e.spa=e.safeParseAsync,e.encode=(n,o)=>RK(e,n,o),e.decode=(n,o)=>OK(e,n,o),e.encodeAsync=async(n,o)=>PK(e,n,o),e.decodeAsync=async(n,o)=>DK(e,n,o),e.safeEncode=(n,o)=>BK(e,n,o),e.safeDecode=(n,o)=>HK(e,n,o),e.safeEncodeAsync=async(n,o)=>zK(e,n,o),e.safeDecodeAsync=async(n,o)=>WK(e,n,o),e.refine=(n,o)=>e.check(OZ(n,o)),e.superRefine=n=>e.check(PZ(n)),e.overwrite=n=>e.check(g1(n)),e.optional=()=>cb(e),e.exactOptional=()=>_Z(e),e.nullable=()=>db(e),e.nullish=()=>cb(db(e)),e.nonoptional=n=>EZ(e,n),e.array=()=>Wn(e),e.or=n=>hZ([e,n]),e.and=n=>vZ(e,n),e.transform=n=>fb(e,CZ(n)),e.default=n=>AZ(e,n),e.prefault=n=>TZ(e,n),e.catch=n=>LZ(e,n),e.pipe=n=>fb(e,n),e.readonly=()=>FZ(e),e.describe=n=>{const o=e.clone();return vf.add(o,{description:n}),o},Object.defineProperty(e,"description",{get(){return vf.get(e)?.description},configurable:!0}),e.meta=(...n)=>{if(n.length===0)return vf.get(e);const o=e.clone();return vf.add(o,n[0]),o},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e.apply=n=>n(e),e)),yT=ct("_ZodString",(e,t)=>{py.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(o,s,i)=>tK(e,o,s);const n=e._zod.bag;e.format=n.format??null,e.minLength=n.minimum??null,e.maxLength=n.maximum??null,e.regex=(...o)=>e.check(Dq(...o)),e.includes=(...o)=>e.check(zq(...o)),e.startsWith=(...o)=>e.check(Wq(...o)),e.endsWith=(...o)=>e.check(Uq(...o)),e.min=(...o)=>e.check(Rm(...o)),e.max=(...o)=>e.check(fT(...o)),e.length=(...o)=>e.check(pT(...o)),e.nonempty=(...o)=>e.check(Rm(1,...o)),e.lowercase=o=>e.check(Bq(o)),e.uppercase=o=>e.check(Hq(o)),e.trim=()=>e.check(Vq()),e.normalize=(...o)=>e.check(jq(...o)),e.toLowerCase=()=>e.check(qq()),e.toUpperCase=()=>e.check(Kq()),e.slugify=()=>e.check(Zq())}),UK=ct("ZodString",(e,t)=>{py.init(e,t),yT.init(e,t),e.email=n=>e.check(aq(jK,n)),e.url=n=>e.check(pq(VK,n)),e.jwt=n=>e.check(Tq(rZ,n)),e.emoji=n=>e.check(hq(qK,n)),e.guid=n=>e.check(sb(ab,n)),e.uuid=n=>e.check(uq(th,n)),e.uuidv4=n=>e.check(cq(th,n)),e.uuidv6=n=>e.check(dq(th,n)),e.uuidv7=n=>e.check(fq(th,n)),e.nanoid=n=>e.check(mq(KK,n)),e.guid=n=>e.check(sb(ab,n)),e.cuid=n=>e.check(gq(ZK,n)),e.cuid2=n=>e.check(vq(GK,n)),e.ulid=n=>e.check(yq(YK,n)),e.base64=n=>e.check(Sq(oZ,n)),e.base64url=n=>e.check(Aq(sZ,n)),e.xid=n=>e.check(kq(XK,n)),e.ksuid=n=>e.check(bq(JK,n)),e.ipv4=n=>e.check(Cq(QK,n)),e.ipv6=n=>e.check(wq(eZ,n)),e.cidrv4=n=>e.check(_q(tZ,n)),e.cidrv6=n=>e.check(xq(nZ,n)),e.e164=n=>e.check(Mq(iZ,n)),e.datetime=n=>e.check(_K(n)),e.date=n=>e.check(SK(n)),e.time=n=>e.check(MK(n)),e.duration=n=>e.check(EK(n))});function bt(e){return lq(UK,e)}const Ro=ct("ZodStringFormat",(e,t)=>{Mo.init(e,t),yT.init(e,t)}),jK=ct("ZodEmail",(e,t)=>{hV.init(e,t),Ro.init(e,t)}),ab=ct("ZodGUID",(e,t)=>{fV.init(e,t),Ro.init(e,t)}),th=ct("ZodUUID",(e,t)=>{pV.init(e,t),Ro.init(e,t)}),VK=ct("ZodURL",(e,t)=>{mV.init(e,t),Ro.init(e,t)}),qK=ct("ZodEmoji",(e,t)=>{gV.init(e,t),Ro.init(e,t)}),KK=ct("ZodNanoID",(e,t)=>{vV.init(e,t),Ro.init(e,t)}),ZK=ct("ZodCUID",(e,t)=>{yV.init(e,t),Ro.init(e,t)}),GK=ct("ZodCUID2",(e,t)=>{kV.init(e,t),Ro.init(e,t)}),YK=ct("ZodULID",(e,t)=>{bV.init(e,t),Ro.init(e,t)}),XK=ct("ZodXID",(e,t)=>{CV.init(e,t),Ro.init(e,t)}),JK=ct("ZodKSUID",(e,t)=>{wV.init(e,t),Ro.init(e,t)}),QK=ct("ZodIPv4",(e,t)=>{MV.init(e,t),Ro.init(e,t)}),eZ=ct("ZodIPv6",(e,t)=>{TV.init(e,t),Ro.init(e,t)}),tZ=ct("ZodCIDRv4",(e,t)=>{EV.init(e,t),Ro.init(e,t)}),nZ=ct("ZodCIDRv6",(e,t)=>{IV.init(e,t),Ro.init(e,t)}),oZ=ct("ZodBase64",(e,t)=>{LV.init(e,t),Ro.init(e,t)}),sZ=ct("ZodBase64URL",(e,t)=>{NV.init(e,t),Ro.init(e,t)}),iZ=ct("ZodE164",(e,t)=>{FV.init(e,t),Ro.init(e,t)}),rZ=ct("ZodJWT",(e,t)=>{OV.init(e,t),Ro.init(e,t)}),kT=ct("ZodNumber",(e,t)=>{lT.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(o,s,i)=>nK(e,o,s),e.gt=(o,s)=>e.check(rb(o,s)),e.gte=(o,s)=>e.check(n9(o,s)),e.min=(o,s)=>e.check(n9(o,s)),e.lt=(o,s)=>e.check(ib(o,s)),e.lte=(o,s)=>e.check(t9(o,s)),e.max=(o,s)=>e.check(t9(o,s)),e.int=o=>e.check(ub(o)),e.safe=o=>e.check(ub(o)),e.positive=o=>e.check(rb(0,o)),e.nonnegative=o=>e.check(n9(0,o)),e.negative=o=>e.check(ib(0,o)),e.nonpositive=o=>e.check(t9(0,o)),e.multipleOf=(o,s)=>e.check(lb(o,s)),e.step=(o,s)=>e.check(lb(o,s)),e.finite=()=>e;const n=e._zod.bag;e.minValue=Math.max(n.minimum??Number.NEGATIVE_INFINITY,n.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(n.maximum??Number.POSITIVE_INFINITY,n.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(n.format??"").includes("int")||Number.isSafeInteger(n.multipleOf??.5),e.isFinite=!0,e.format=n.format??null});function Ut(e){return Nq(kT,e)}const lZ=ct("ZodNumberFormat",(e,t)=>{PV.init(e,t),kT.init(e,t)});function ub(e){return Fq(lZ,e)}const aZ=ct("ZodBoolean",(e,t)=>{DV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>oK(e,n,o)});function Hp(e){return Rq(aZ,e)}const uZ=ct("ZodUnknown",(e,t)=>{BV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>iK()});function Cs(){return Oq(uZ)}const cZ=ct("ZodNever",(e,t)=>{HV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>sK(e,n,o)});function dZ(e){return Pq(cZ,e)}const fZ=ct("ZodArray",(e,t)=>{zV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>cK(e,n,o,s),e.element=t.element,e.min=(n,o)=>e.check(Rm(n,o)),e.nonempty=n=>e.check(Rm(1,n)),e.max=(n,o)=>e.check(fT(n,o)),e.length=(n,o)=>e.check(pT(n,o)),e.unwrap=()=>e.element});function Wn(e,t){return Gq(fZ,e,t)}const pZ=ct("ZodObject",(e,t)=>{UV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>dK(e,n,o,s),Jn(e,"shape",()=>t.shape),e.keyof=()=>So(Object.keys(e._zod.def.shape)),e.catchall=n=>e.clone({...e._zod.def,catchall:n}),e.passthrough=()=>e.clone({...e._zod.def,catchall:Cs()}),e.loose=()=>e.clone({...e._zod.def,catchall:Cs()}),e.strict=()=>e.clone({...e._zod.def,catchall:dZ()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=n=>cj(e,n),e.safeExtend=n=>dj(e,n),e.merge=n=>fj(e,n),e.pick=n=>aj(e,n),e.omit=n=>uj(e,n),e.partial=(...n)=>pj(CT,e,n[0]),e.required=(...n)=>hj(wT,e,n[0])});function $t(e,t){const n={type:"object",shape:e??{},...Jt(t)};return new pZ(n)}const bT=ct("ZodUnion",(e,t)=>{cT.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>fK(e,n,o,s),e.options=t.options});function hZ(e,t){return new bT({type:"union",options:e,...Jt(t)})}const mZ=ct("ZodDiscriminatedUnion",(e,t)=>{bT.init(e,t),jV.init(e,t)});function du(e,t,n){return new mZ({type:"union",options:t,discriminator:e,...Jt(n)})}const gZ=ct("ZodIntersection",(e,t)=>{VV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>pK(e,n,o,s)});function vZ(e,t){return new gZ({type:"intersection",left:e,right:t})}const yZ=ct("ZodRecord",(e,t)=>{qV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>hK(e,n,o,s),e.keyType=t.keyType,e.valueType=t.valueType});function hy(e,t,n){return new yZ({type:"record",keyType:e,valueType:t,...Jt(n)})}const u3=ct("ZodEnum",(e,t)=>{KV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(o,s,i)=>rK(e,o,s),e.enum=t.entries,e.options=Object.values(t.entries);const n=new Set(Object.keys(t.entries));e.extract=(o,s)=>{const i={};for(const r of o)if(n.has(r))i[r]=t.entries[r];else throw new Error(`Key ${r} not found in enum`);return new u3({...t,checks:[],...Jt(s),entries:i})},e.exclude=(o,s)=>{const i={...t.entries};for(const r of o)if(n.has(r))delete i[r];else throw new Error(`Key ${r} not found in enum`);return new u3({...t,checks:[],...Jt(s),entries:i})}});function So(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(o=>[o,o])):e;return new u3({type:"enum",entries:n,...Jt(t)})}const kZ=ct("ZodLiteral",(e,t)=>{ZV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>lK(e,n,o),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function mn(e,t){return new kZ({type:"literal",values:Array.isArray(e)?e:[e],...Jt(t)})}const bZ=ct("ZodTransform",(e,t)=>{GV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>uK(e,n),e._zod.parse=(n,o)=>{if(o.direction==="backward")throw new VM(e.constructor.name);n.addIssue=i=>{if(typeof i=="string")n.issues.push(kp(i,n.value,t));else{const r=i;r.fatal&&(r.continue=!1),r.code??(r.code="custom"),r.input??(r.input=n.value),r.inst??(r.inst=e),n.issues.push(kp(r))}};const s=t.transform(n.value,n);return s instanceof Promise?s.then(i=>(n.value=i,n)):(n.value=s,n)}});function CZ(e){return new bZ({type:"transform",transform:e})}const CT=ct("ZodOptional",(e,t)=>{dT.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>vT(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function cb(e){return new CT({type:"optional",innerType:e})}const wZ=ct("ZodExactOptional",(e,t)=>{YV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>vT(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function _Z(e){return new wZ({type:"optional",innerType:e})}const xZ=ct("ZodNullable",(e,t)=>{XV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>mK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function db(e){return new xZ({type:"nullable",innerType:e})}const SZ=ct("ZodDefault",(e,t)=>{JV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>vK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function AZ(e,t){return new SZ({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():GM(t)}})}const MZ=ct("ZodPrefault",(e,t)=>{QV.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>yK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function TZ(e,t){return new MZ({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():GM(t)}})}const wT=ct("ZodNonOptional",(e,t)=>{eq.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>gK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function EZ(e,t){return new wT({type:"nonoptional",innerType:e,...Jt(t)})}const IZ=ct("ZodCatch",(e,t)=>{tq.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>kK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function LZ(e,t){return new IZ({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}const $Z=ct("ZodPipe",(e,t)=>{nq.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>bK(e,n,o,s),e.in=t.in,e.out=t.out});function fb(e,t){return new $Z({type:"pipe",in:e,out:t})}const NZ=ct("ZodReadonly",(e,t)=>{oq.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>CK(e,n,o,s),e.unwrap=()=>e._zod.def.innerType});function FZ(e){return new NZ({type:"readonly",innerType:e})}const RZ=ct("ZodCustom",(e,t)=>{sq.init(e,t),Fo.init(e,t),e._zod.processJSONSchema=(n,o,s)=>aK(e,n)});function OZ(e,t={}){return Yq(RZ,e,t)}function PZ(e){return Xq(e)}const mc=bt().min(1),my=bt().min(1),zp=bt().min(1),gc=bt().min(1),ar=bt().min(1),DZ=/^[A-Za-z0-9._-]{1,128}$/;function BZ(e){return DZ.test(e)&&e!=="."&&e!==".."}const _T=du("kind",[$t({kind:mn("user"),payload:Cs().optional()}),$t({kind:mn("cron"),taskId:gc.optional(),payload:Cs().optional()}),$t({kind:mn("task"),taskId:gc,payload:Cs().optional()}),$t({kind:mn("hook"),payload:Cs().optional()}),$t({kind:mn("compaction"),payload:Cs().optional()}),$t({kind:mn("side"),payload:Cs().optional()}),$t({kind:mn("other"),payload:Cs().optional()})]),HZ=$t({inputTokens:Ut().optional(),outputTokens:Ut().optional(),cachedTokens:Ut().optional(),cost:Ut().optional()}),Df=$t({inputOther:Ut(),output:Ut(),inputCacheRead:Ut(),inputCacheCreation:Ut()}),zZ=$t({llmFirstTokenLatencyMs:Ut().optional(),llmStreamDurationMs:Ut().optional(),llmRequestBuildMs:Ut().optional(),llmServerFirstTokenMs:Ut().optional(),llmServerDecodeMs:Ut().optional(),llmClientConsumeMs:Ut().optional()}),WZ=$t({failedAttempt:Ut(),nextAttempt:Ut(),maxAttempts:Ut(),delayMs:Ut(),errorName:bt(),errorMessage:bt(),statusCode:Ut().optional()}),xT=So(["queued","running","completed","failed","cancelled"]),UZ=So(["running","completed","interrupted","failed"]),jZ=$t({kind:mn("text"),frameId:zp,role:So(["assistant","user"]),text:bt(),attachmentIds:Wn(bt()).optional(),taskId:gc.optional()}),VZ=$t({kind:mn("thinking"),frameId:zp,text:bt()}),qZ=$t({agentId:ar,role:So(["child","member"]).optional()}),KZ=$t({kind:So(["stdout","stderr","progress","status","custom"]),text:bt().optional(),percent:Ut().optional(),customKind:bt().optional(),customData:Cs().optional()}),ZZ=$t({kind:mn("tool"),frameId:zp,toolCallId:bt(),name:bt(),view:bt().optional(),state:So(["running","done","error"]),input:Cs().optional(),output:Cs().optional(),display:Cs().optional(),error:bt().optional(),inputText:bt().optional(),progress:KZ.optional(),taskId:gc.optional(),approvalId:bt().optional(),todoId:bt().optional(),agentRefs:Wn(qZ).optional()}),gy=$t({interactionId:bt(),interactionKind:So(["approval","question"]),toolCallId:bt().optional(),state:So(["pending","approved","rejected","cancelled","answered","dismissed"]),request:Cs().optional(),response:Cs().optional()}),GZ=$t({kind:mn("notice"),frameId:zp,level:So(["error","warning","info"]),source:bt().optional(),message:bt(),detail:Cs().optional()}),ST=du("kind",[jZ,VZ,ZZ,GZ]),AT=$t({kind:mn("step"),stepId:my,turnId:mc,ordinal:Ut().int(),state:UZ,frames:Wn(ST),startedAt:bt().optional(),endedAt:bt().optional(),usage:Df.optional(),finishReason:bt().optional(),timing:zZ.optional(),retry:WZ.optional(),endReason:bt().optional(),endMessage:bt().optional()}),MT=$t({kind:mn("turn"),turnId:mc,ordinal:Ut().int(),state:xT,origin:_T,prompt:bt().optional(),attachmentIds:Wn(bt()).optional(),steps:Wn(AT),startedAt:bt().optional(),endedAt:bt().optional(),usage:HZ.optional(),durationMs:Ut().optional(),error:bt().optional()}),TT=$t({kind:mn("marker"),markerId:bt(),marker:bt(),payload:Cs().optional(),at:bt().optional()}),ET=$t({kind:mn("taskref"),refId:bt(),taskId:gc,at:bt().optional()}),IT=du("kind",[MT,TT,ET]),vy=$t({taskId:gc,kind:So(["shell","subagent","tool","other"]),state:So(["running","completed","failed","timed_out","killed","lost"]),detached:Hp(),description:bt().optional(),agentId:ar.optional(),outputTail:bt(),startedAt:bt().optional(),endedAt:bt().optional(),resultSummary:bt().optional(),error:bt().optional(),stateReason:bt().optional(),usage:Df.optional()}),YZ=$t({objective:bt(),status:So(["active","paused","blocked","complete"]),completionCriterion:bt().optional(),budgetUsed:Ut().optional(),budgetLimit:Ut().optional()}),XZ=$t({plan:$t({reviewPath:bt().optional(),version:Ut().optional()}).optional(),swarm:$t({trigger:bt().optional()}).optional()}),JZ=$t({plan:$t({reviewPath:bt().optional(),version:Ut().optional()}).nullable().optional(),swarm:$t({trigger:bt().optional()}).nullable().optional()}),QZ=du("kind",[$t({kind:mn("idle")}),$t({kind:mn("running"),turnId:Ut(),step:Ut(),stepId:bt(),since:Ut()}),$t({kind:mn("streaming"),turnId:Ut(),step:Ut(),stepId:bt(),stream:So(["assistant","thinking","tool_call"]),toolCallId:bt().optional(),toolName:bt().optional(),since:Ut()}),$t({kind:mn("tool_call"),turnId:Ut(),step:Ut(),toolCallId:bt(),name:bt(),since:Ut()}),$t({kind:mn("retrying"),turnId:Ut(),step:Ut(),stepId:bt(),failedAttempt:Ut(),nextAttempt:Ut(),maxAttempts:Ut(),delayMs:Ut(),errorName:bt().optional(),statusCode:Ut().optional(),since:Ut()}),$t({kind:mn("awaiting_approval"),turnId:Ut(),step:Ut().optional(),approval:Cs().optional(),since:Ut()}),$t({kind:mn("interrupted"),turnId:Ut(),step:Ut().optional(),reason:So(["aborted","max_steps","error"]),message:bt().optional(),at:Ut()}),$t({kind:mn("ended"),turnId:Ut(),reason:So(["completed","cancelled","failed","blocked"]),durationMs:Ut().optional(),at:Ut()})]),eG=$t({byModel:hy(bt(),Df).optional(),currentTurn:Df.optional(),total:Df.optional()}),tG=$t({model:bt().optional(),thinkingEffort:bt().optional(),usage:eG.optional(),contextTokens:Ut().optional(),maxContextTokens:Ut().optional(),contextUsage:Ut().optional(),permission:So(["manual","yolo","auto"]).optional(),phase:QZ.optional()}),yy=$t({goal:YZ.optional(),modes:XZ.optional(),activity:So(["idle","turn","disposing","unknown"]).optional(),agent:tG.optional()}),nG=yy.extend({modes:JZ.optional()}),d2=$t({attachmentId:bt(),mediaType:bt(),name:bt().optional(),size:Ut().optional(),source:du("kind",[$t({kind:mn("url"),url:bt()}),$t({kind:mn("file"),fileId:bt()})]).optional(),placeholder:bt().optional()}),oG=$t({title:bt(),status:So(["pending","in_progress","done"])}),ky=$t({todoId:bt(),items:Wn(oG),updatedAt:bt().optional()}),by=$t({promptId:bt(),status:So(["running","queued","blocked","completed","failed","aborted"]),userMessageId:bt().optional(),content:Cs().optional(),createdAt:bt(),finishedAt:bt().optional(),steeredAt:bt().optional()}),LT=$t({items:Wn(IT),tasks:Wn(vy),interactions:Wn(gy).default([]),attachments:Wn(d2).default([]),todos:Wn(ky).default([]),prompts:Wn(by).default([]),meta:yy,hasMoreOlder:Hp().optional()}),sG=MT.omit({steps:!0}),iG=AT.omit({frames:!0}),rG=du("type",[$t({type:mn("frame"),turnId:mc,stepId:my,frameId:zp}),$t({type:mn("task"),taskId:gc})]),Cy=du("op",[$t({op:mn("reset"),agentId:ar,snapshot:LT}),$t({op:mn("turn.upsert"),turn:sG}),$t({op:mn("step.upsert"),turnId:mc,step:iG}),$t({op:mn("frame.upsert"),turnId:mc,stepId:my,frame:ST}),$t({op:mn("append"),target:rG,offset:Ut().int().nonnegative(),text:bt()}),$t({op:mn("marker.upsert"),item:TT,beforeTurn:Ut().int().optional()}),$t({op:mn("taskref.upsert"),item:ET,beforeTurn:Ut().int().optional()}),$t({op:mn("task.upsert"),task:vy}),$t({op:mn("interaction.upsert"),interaction:gy}),$t({op:mn("attachment.upsert"),attachment:d2}),$t({op:mn("todo.upsert"),todo:ky}),$t({op:mn("prompt.upsert"),prompt:by}),$t({op:mn("meta.merge"),meta:nG}),$t({op:mn("items.remove"),ids:Wn(bt())})]);$t({agentId:ar,ops:Wn(Cy)});const lG=So(["off","turn","block","delta"]),i1=Ut().int().nonnegative(),aG=hy(bt(),lG);$t({session_id:bt().min(1),transcript:aG,transcript_since:hy(bt(),i1).optional()});$t({agent_id:ar,before_turn:bt().min(1).optional(),after_turn:bt().min(1).optional(),page_size:Ut().int().min(1).max(100).optional()}).superRefine((e,t)=>{e.before_turn!==void 0&&e.after_turn!==void 0&&t.addIssue({code:"custom",message:"before_turn and after_turn are mutually exclusive",path:["before_turn"]}),BZ(e.agent_id)||t.addIssue({code:"custom",message:"agent_id must be a plain agent id (no path separators)",path:["agent_id"]})});const uG=$t({agentId:ar,type:So(["main","sub","independent"]).optional(),parentAgentId:ar.optional(),label:bt().optional(),createdAt:bt().optional(),disposedAt:bt().optional()}),cG=$t({agent_id:ar,items:Wn(IT),has_more:Hp(),tasks:Wn(vy),interactions:Wn(gy).default([]),attachments:Wn(d2).default([]),todos:Wn(ky).default([]),prompts:Wn(by).default([]),meta:yy,agents:Wn(uG),pending_interactions:Wn(bt()),seq:i1.optional()});$t({agent_id:ar,batches:Wn($t({seq:i1,ops:Wn(Cy)})),latest_seq:i1,complete:Hp()});const dG=$t({turn_id:mc,ordinal:Ut().int(),state:xT,origin:_T,prompt:bt(),attachment_ids:Wn(bt()).optional(),started_at:bt().optional()});$t({agents:Wn($t({agent_id:ar,messages:Wn(dG),attachments:Wn(d2).default([])}))});const fG=$t({state:So(["pending","approved","rejected","cancelled"]),selected_option:bt().optional(),feedback:bt().optional()}),pG=$t({tool_call_id:bt(),turn_id:mc,source:So(["interaction","display","output"]),plan:bt(),path:bt().optional(),options:Wn($t({label:bt(),description:bt().optional()})).optional(),review:fG.optional()});$t({agent_id:ar,plans:Wn(pG)});const hG=$t({agent_id:ar,snapshot:LT,has_more_older:Hp(),seq:i1.optional()}),mG=$t({agent_id:ar,ops:Wn(Cy),seq:i1.optional()}),$T=hG.extend({type:mn("transcript.reset")}),NT=mG.extend({type:mn("transcript.ops")});du("type",[$T,NT]);const pb=new Set(["turn.started","turn.step.started","turn.step.completed","turn.step.retrying","turn.step.interrupted","turn.ended","thinking.delta","assistant.delta","tool.call.started","tool.use","tool.call.delta","tool.progress","tool.result","agent.status.updated","prompt.submitted","prompt.completed","prompt.aborted","session.meta.updated","compaction.started","compaction.completed","compaction.cancelled","goal.updated","error","warning","subagent.spawned","subagent.started","subagent.suspended","subagent.completed","subagent.failed","task.started","task.terminated","background.task.started","background.task.terminated","cron.fired"]),gG=new Set(["session.created","session.updated","session.deleted","session.status_changed","session.usage_updated","session.history_compacted","message.created","message.updated","approval.requested","approval.resolved","approval.expired","question.requested","question.answered","question.dismissed","task.created","task.progress","task.completed","assistant.tool_use_started","assistant.tool_use_delta","assistant.tool_use_completed","assistant.completed","tool.started","tool.output","tool.completed"]),vG=new Set(["server_hello","ack","ping","resync_required","error","pong"]),yG=new Set(["assistant.delta","thinking.delta"]);function kG(e,t){if(vG.has(e))return{route:"ignore"};const n=e.startsWith("event."),o=n?e.slice(6):e;return yG.has(o)?bG(t)?{route:"agent",agentType:o}:{route:"protocol"}:n?gG.has(o)?{route:"protocol"}:pb.has(o)?{route:"agent",agentType:o}:{route:"protocol"}:pb.has(o)?{route:"agent",agentType:o}:{route:"agent",agentType:o}}function bG(e){if(!e||typeof e!="object")return!1;const t=e;return"message_id"in t||"content_index"in t?!1:typeof t.delta=="string"}const CG="kimi-code.bearer.",wG=3e4;class _G{constructor(t){this.opts=t,this.tracer=t.tracer??oy}ws=null;connected=!1;closed=!1;subscriptions=new Map;transcriptSubscriptions=new Map;sideChannelAgents=new Map;pendingSubscriptions=[];terminalAttachments=new Map;msgSeq=0;clientHelloId=null;reconnectAttempts=0;reconnectTimer=null;heartbeatMs=3e4;lastActivityAt=0;tracer;connect(){if(this.ws!==null||this.closed)return;this.lastActivityAt=Date.now(),this.tracer.wsEvent?.({kind:"lifecycle",event:"connect",detail:{url:this.opts.wsUrl,attempt:this.reconnectAttempts}});const t=this.opts.credentialStore?.getToken(),n=t!==void 0?[`${CG}${t}`]:void 0,o=new WebSocket(this.opts.wsUrl,n);this.ws=o,o.onopen=()=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"open"})},o.onmessage=s=>{this.lastActivityAt=Date.now();try{const i=JSON.parse(String(s.data));this.tracer.wsEvent?.({kind:"in",frame:i}),this.handleFrame(i)}catch(i){this.tracer.wsEvent?.({kind:"lifecycle",event:"parse-error",detail:{error:String(i)}}),this.opts.handlers.onError(0,`Failed to parse WS frame: ${String(i)}`,!1)}},o.onerror=()=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"error"}),this.opts.handlers.onError(0,"WebSocket error",!1)},o.onclose=s=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"close",detail:s?{code:s.code,reason:s.reason,wasClean:s.wasClean}:void 0}),this.connected=!1,this.ws=null,this.opts.handlers.onConnectionState(!1),this.scheduleReconnect()}}scheduleReconnect(){if(this.closed||this.reconnectTimer!==null)return;const n=Math.min(3e4,1e3*2**this.reconnectAttempts)+Math.floor(Math.random()*250);this.reconnectAttempts+=1,this.tracer.wsEvent?.({kind:"lifecycle",event:"reconnect-scheduled",detail:{delayMs:n,attempt:this.reconnectAttempts}}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},n)}subscribe(t,n={seq:0}){if(this.subscriptions.set(t,{...n}),this.connected)this.sendSubscribe([t],{[t]:n});else{const o=this.pendingSubscriptions.findIndex(s=>s.sessionId===t);o!==-1&&this.pendingSubscriptions.splice(o,1),this.pendingSubscriptions.push({sessionId:t,cursor:{...n}})}}unsubscribe(t){this.subscriptions.delete(t);const n=this.pendingSubscriptions.findIndex(o=>o.sessionId===t);n!==-1&&this.pendingSubscriptions.splice(n,1),this.connected&&this.ws&&this.send({type:"unsubscribe",id:this.nextId(),payload:{session_ids:[t]}})}subscribeTranscript(t,n,o){this.transcriptSubscriptions.set(t,{agentId:n,...o!==void 0?{sinceSeq:o}:{}}),this.connected&&this.sendTranscriptSubscribe(t,n,o)}unsubscribeTranscript(t,n){const o=this.transcriptSubscriptions.get(t);(n===void 0||o===void 0||n.includes(o.agentId))&&this.transcriptSubscriptions.delete(t),!(!this.connected||!this.ws)&&this.send({type:"unsubscribe_v2",id:this.nextId(),payload:{session_id:t,...n!==void 0?{agent_ids:n}:{}}})}markSideChannelAgent(t,n){if(!this.opts.mainAgentOnly)return;let o=this.sideChannelAgents.get(t);if(o===void 0&&(o=new Set,this.sideChannelAgents.set(t,o)),o.has(n))return;o.add(n);const s=this.subscriptions.get(t);this.connected&&s!==void 0&&this.sendSubscribe([t],{[t]:s})}abort(t,n){!this.connected||!this.ws||this.send({type:"abort",id:this.nextId(),payload:{session_id:t,prompt_id:n}})}terminalAttach(t,n,o){const s=nh(t,n),i=this.terminalAttachments.get(s),r=o??i?.lastSeq??0;this.terminalAttachments.set(s,{sessionId:t,terminalId:n,lastSeq:r}),!(!this.connected||!this.ws)&&this.sendTerminalAttach(t,n,r)}terminalInput(t,n,o){!this.connected||!this.ws||this.send({type:"terminal_input",id:this.nextId(),payload:{session_id:t,terminal_id:n,data:o}})}terminalResize(t,n,o,s){!this.connected||!this.ws||this.send({type:"terminal_resize",id:this.nextId(),payload:{session_id:t,terminal_id:n,cols:o,rows:s}})}terminalDetach(t,n){this.terminalAttachments.delete(nh(t,n)),!(!this.connected||!this.ws)&&this.send({type:"terminal_detach",id:this.nextId(),payload:{session_id:t,terminal_id:n}})}terminalClose(t,n){this.terminalAttachments.delete(nh(t,n)),!(!this.connected||!this.ws)&&this.send({type:"terminal_close",id:this.nextId(),payload:{session_id:t,terminal_id:n}})}close(){this.closed=!0,this.connected=!1,this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(1e3),this.ws=null)}health(){const t=this.ws!==null&&this.ws.readyState===WebSocket.OPEN,n=Math.max(this.heartbeatMs*2,wG),o=this.lastActivityAt>0&&Date.now()-this.lastActivityAt>n;return{connected:this.connected,open:t,stale:o}}reconnect(){if(this.closed)return;this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);const t=this.ws;if(t!==null){t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close(1e3,"reconnect")}catch{}}const n=this.connected;this.ws=null,this.connected=!1,n&&this.opts.handlers.onConnectionState(!1),this.connect()}handleFrame(t){const n=t,o=t.type;if(o==="transcript.reset"){const s=$T.safeParse({type:o,...n.payload}),i=n.session_id;if(!s.success||typeof i!="string"){this.opts.handlers.onError(0,"Invalid transcript.reset frame",!1);return}const r=s.data;this.opts.handlers.onTranscriptReset?.(i,r.agent_id,{...r.snapshot,hasMoreOlder:r.has_more_older},r.seq);const l=this.transcriptSubscriptions.get(i);l?.agentId===r.agent_id&&r.seq!==void 0&&(l.sinceSeq=r.seq);return}if(o==="transcript.ops"){const s=NT.safeParse({type:o,...n.payload}),i=n.session_id;if(!s.success||typeof i!="string"){this.opts.handlers.onError(0,"Invalid transcript.ops frame",!1);return}const r=s.data,l=this.opts.handlers.onTranscriptOps?.(i,r.agent_id,r.ops,r.seq),a=this.transcriptSubscriptions.get(i);l!==!1&&a?.agentId===r.agent_id&&r.seq!==void 0&&(a.sinceSeq=r.seq);return}switch(o){case"server_hello":{const s=n.payload?.heartbeat_ms;typeof s=="number"&&s>0&&(this.heartbeatMs=s),this.onServerHello();break}case"ping":this.send({type:"pong",payload:{nonce:n.payload.nonce}});break;case"resync_required":{const s=n.payload.session_id,i=n.payload.epoch;this.subscriptions.set(s,{seq:n.payload.current_seq,epoch:i}),this.opts.handlers.onResync(s,n.payload.current_seq,i);break}case"error":{const s=n.session_id;typeof s=="string"&&this.opts.handlers.onRawAgentEvent?this.opts.handlers.onRawAgentEvent({type:"error",seq:n.seq,session_id:s,timestamp:n.timestamp,payload:n.payload}):this.opts.handlers.onError(n.payload.code,n.payload.msg,n.payload.fatal);break}case"ack":n.id===this.clientHelloId&&(this.clientHelloId=null,n.code===0&&this.opts.handlers.onReplayComplete?.());break;case"terminal_output":{const s=n.session_id,i=n.terminal_id,r=n.seq,l=nh(s,i),a=this.terminalAttachments.get(l);a&&this.terminalAttachments.set(l,{...a,lastSeq:Math.max(a.lastSeq,r)});const u=typeof n.payload?.data=="string"?n.payload.data:"";this.opts.handlers.onTerminalOutput?.(s,i,u,r);break}case"terminal_exit":{const s=n.session_id,i=n.terminal_id,r=n.payload?.exit_code,l=typeof r=="number"?r:null;this.opts.handlers.onTerminalExit?.(s,i,l);break}default:{this.trackCursor(n);const s=n.type,i=kG(s,n.payload);if(i.route==="protocol"){this.opts.handlers.onWireEvent(n);break}if(i.route==="agent"){if(this.opts.handlers.onRawAgentEvent&&typeof n.session_id=="string"){const r=n,l=n;this.opts.handlers.onRawAgentEvent({type:i.agentType,seq:r.seq,session_id:r.session_id,timestamp:r.timestamp,payload:r.payload,...l.volatile!==void 0?{volatile:l.volatile}:{},...l.offset!==void 0?{offset:l.offset}:{}})}break}break}}}onServerHello(){this.connected=!0,this.reconnectAttempts=0,this.opts.handlers.onConnectionState(!0);const t=Array.from(this.subscriptions.keys());for(const s of this.pendingSubscriptions)this.subscriptions.set(s.sessionId,s.cursor),t.includes(s.sessionId)||t.push(s.sessionId);this.pendingSubscriptions.length=0;const n={};for(const[s,i]of this.subscriptions.entries())n[s]=i;const o=this.nextId();this.clientHelloId=o,this.send({type:"client_hello",id:o,payload:{client_id:this.opts.clientId,subscriptions:t,cursors:n,...this.opts.mainAgentOnly?{agent_filter:this.rawAgentFilter(t)}:{}}});for(const[s,i]of this.transcriptSubscriptions)this.sendTranscriptSubscribe(s,i.agentId,i.sinceSeq);for(const s of this.terminalAttachments.values())this.sendTerminalAttach(s.sessionId,s.terminalId,s.lastSeq)}sendSubscribe(t,n){this.send({type:"subscribe",id:this.nextId(),payload:{session_ids:t,cursors:n,...this.opts.mainAgentOnly?{agent_filter:this.rawAgentFilter(t)}:{}}})}rawAgentFilter(t){return Object.fromEntries(t.map(n=>[n,["main",...this.sideChannelAgents.get(n)??[]]]))}sendTranscriptSubscribe(t,n,o){this.send({type:"subscribe_v2",id:this.nextId(),payload:{session_id:t,transcript:{[n]:"delta"},...o!==void 0?{transcript_since:{[n]:o}}:{}}})}sendTerminalAttach(t,n,o){this.send({type:"terminal_attach",id:this.nextId(),payload:{session_id:t,terminal_id:n,since_seq:o>0?o:void 0}})}trackCursor(t){if(t.volatile===!0)return;const n=t.session_id,o=t.seq;if(typeof n!="string"||typeof o!="number")return;const s=this.subscriptions.get(n);if(!s||o<=s.seq&&s.epoch!==void 0)return;const i=typeof t.epoch=="string"?t.epoch:s.epoch;this.subscriptions.set(n,{seq:Math.max(o,s.seq),epoch:i})}send(t){if(!(!this.ws||this.ws.readyState!==WebSocket.OPEN))try{this.ws.send(JSON.stringify(t)),this.tracer.wsEvent?.({kind:"out",frame:t})}catch{}}nextId(){return`c_${++this.msgSeq}`}}function nh(e,t){return`${e}\0${t}`}async function xG(e,t,n){const o=await e.get(`/sessions/${encodeURIComponent(t)}/transcript`,{agent_id:n.agentId,before_turn:n.beforeTurn,after_turn:n.afterTurn,page_size:n.pageSize}),s=cG.parse(o),i={items:s.items,tasks:s.tasks,interactions:s.interactions,attachments:s.attachments,todos:s.todos,prompts:s.prompts,meta:s.meta,hasMoreOlder:s.has_more};return{agentId:s.agent_id,...i,agents:s.agents,pendingInteractions:s.pending_interactions,...s.seq!==void 0?{seq:s.seq}:{}}}const o9=10485760,SG=40001;function AG(e,t){if(e===void 0)return t;let n;const o=/filename\*\s*=\s*UTF-8''([^;]+)/i.exec(e)?.[1]?.trim();if(o!==void 0)try{n=decodeURIComponent(o.replaceAll(/^"|"$/g,""))}catch{return t}else n=/filename\s*=\s*"([^"]*)"/i.exec(e)?.[1]??/filename\s*=\s*([^;]+)/i.exec(e)?.[1]?.trim();return n===void 0||n.length===0||n.length>200||n==="."||n===".."||/[\u0000-\u001F\u007F/\\]/.test(n)||!n.toLowerCase().endsWith(".zip")?t:n}function hb(e){if(typeof e!="object"||e===null)return{errorName:typeof e};const t=e;return{errorName:typeof t.name=="string"?t.name:"Error",errorCode:typeof t.code=="number"?t.code:void 0,requestId:typeof t.requestId=="string"?t.requestId:void 0,phase:typeof t.phase=="string"?t.phase:void 0,httpStatus:typeof t.status=="number"?t.status:void 0}}function s9(e){return{id:e.id,sessionId:e.session_id,cwd:e.cwd,shell:e.shell,cols:e.cols,rows:e.rows,status:e.status,createdAt:e.created_at,exitedAt:e.exited_at,exitCode:e.exit_code}}function mb(e){return e==="auto_compact"||e==="manual_compact"}class MG{constructor(t){this.opts=t,this.tracer=t.tracer??oy,this.http=new Hk({origin:t.origin,identity:t.identity,tracer:this.tracer,credentialStore:t.credentialStore}),this.httpV2=new Hk({origin:t.origin,identity:t.identity,tracer:this.tracer,credentialStore:t.credentialStore,restBasePath:"/api/v2"})}http;httpV2;tracer;async getHealth(){return{status:"ok",uptimeSec:(await this.http.get("/healthz")).uptime_sec??0}}async getMeta(){const t=await this.http.get("/meta");return{serverVersion:t.server_version,serverId:t.server_id,startedAt:t.started_at,capabilities:t.capabilities,openInApps:Array.isArray(t.open_in_apps)?t.open_in_apps:[],dangerousBypassAuth:t.dangerous_bypass_auth===!0,experimentalFlags:t.experimental_flags??{},backend:t.backend==="v2"?"v2":"v1"}}async listSessions(t){const n={before_id:t?.beforeId,after_id:t?.afterId,page_size:t?.pageSize,busy:t?.busy,include_archive:t?.includeArchive,archived_only:t?.archivedOnly,exclude_empty:t?.excludeEmpty,workspace_id:t?.workspaceId},o=await this.http.get("/sessions",n);return{items:o.items.map(Fr),hasMore:o.has_more}}async listSessionsV2(t){const n={sort:t?.sort,page_size:t?.pageSize,page_token:t?.pageToken,"meta.updated_after":t?.updatedAfter,"meta.archived":t?.archived===void 0?void 0:String(t.archived),include:t?.include,"workspace.id":t?.workspaceIds,"activity.status":t?.statuses},o=await this.httpV2.get("/sessions",n);return{items:o.items,hasMore:o.has_more,nextPageToken:o.next_page_token}}async createSession(t){const n={metadata:t.cwd!==void 0?{cwd:t.cwd}:{}};t.workspaceId!==void 0&&(n.workspace_id=t.workspaceId),t.title!==void 0&&(n.title=t.title),t.model!==void 0&&(n.agent_config={model:t.model});const o=await this.http.post("/sessions",n);return Fr(o)}async getSession(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}`);return Fr(n)}async updateSession(t,n){const o={};n.title!==void 0&&(o.title=n.title),n.cwd!==void 0&&(o.metadata={cwd:n.cwd});const s={};n.model!==void 0&&(s.model=n.model),n.permissionMode!==void 0&&(s.permission_mode=n.permissionMode),n.planMode!==void 0&&(s.plan_mode=n.planMode),n.swarmMode!==void 0&&(s.swarm_mode=n.swarmMode),n.goalObjective!==void 0&&(s.goal_objective=n.goalObjective),n.goalControl!==void 0&&(s.goal_control=n.goalControl),n.thinking!==void 0&&(s.thinking=n.thinking),Object.keys(s).length>0&&(o.agent_config=s);const i=await this.http.post(`/sessions/${encodeURIComponent(t)}/profile`,o);return Fr(i)}async getSessionStatus(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}/status`);return{model:n.model&&n.model.length>0?n.model:null,thinkingEffort:n.thinking_level,permission:n.permission,planMode:n.plan_mode===!0,swarmMode:n.swarm_mode===!0,contextTokens:n.context_tokens??0,maxContextTokens:n.max_context_tokens??0,contextUsage:n.context_usage??0}}async getSessionGoal(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}/goal`);return WM(n)}async getSessionPlans(t,n){const o=await this.http.get(`/sessions/${encodeURIComponent(t)}/transcript/plan`,{agent_id:n.agentId,tool_call_id:n.toolCallId});return o.plans.map(s=>({agentId:o.agent_id,toolCallId:s.tool_call_id,turnId:s.turn_id,source:s.source,plan:s.plan,...s.path!==void 0?{path:s.path}:{},...s.options!==void 0?{options:s.options.map(i=>({label:i.label,...i.description!==void 0?{description:i.description}:{}}))}:{},...s.review!==void 0?{review:{state:s.review.state,...s.review.selected_option!==void 0?{selectedOption:s.review.selected_option}:{},...s.review.feedback!==void 0?{feedback:s.review.feedback}:{}}}:{}}))}async getSessionWarnings(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/warnings`)).warnings??[]}async archiveSession(t){return await this.http.post(`/sessions/${encodeURIComponent(t)}:archive`,{})}async restoreSession(t){const n=await this.http.post(`/sessions/${encodeURIComponent(t)}:restore`,{});return Fr(n)}async listMessages(t,n){const o={before_id:n?.beforeId,after_id:n?.afterId,page_size:n?.pageSize,role:n?.role},s=await this.http.get(`/sessions/${encodeURIComponent(t)}/messages`,o);return{items:s.items.map(s3),hasMore:s.has_more}}async getSessionSnapshot(t){const n=Date.now();this.tracer.traceKeyEvent?.("session:snapshot:start",{sessionId:t});try{const o=await this.http.get(`/sessions/${encodeURIComponent(t)}/snapshot`),s={asOfSeq:o.as_of_seq,epoch:o.epoch,session:Fr(o.session),messages:o.messages.items.map(s3),hasMoreMessages:o.messages.has_more,inFlightTurn:o.in_flight_turn===null?null:{turnId:o.in_flight_turn.turn_id,assistantText:o.in_flight_turn.assistant_text,thinkingText:o.in_flight_turn.thinking_text,runningTools:o.in_flight_turn.running_tools.map(i=>({toolCallId:i.tool_call_id,name:i.name,args:i.args,description:i.description,lastProgress:i.last_progress})),promptId:o.in_flight_turn.current_prompt_id},pendingApprovals:o.pending_approvals.map(HM),pendingQuestions:o.pending_questions.map(zM),subagents:(o.subagents??[]).map(i=>Hh(i,i.id))};return this.tracer.traceKeyEvent?.("session:snapshot:accepted",{sessionId:t,busy:s.session.busy,seq:s.asOfSeq,messageCount:s.messages.length,durationMs:Date.now()-n}),s}catch(o){throw this.tracer.traceKeyEvent?.("session:snapshot:failed",{sessionId:t,status:"failed",durationMs:Date.now()-n,...hb(o)}),o}}async getSessionTranscript(t,n){return xG(this.http,t,n)}async exportSession(t,n,o){const s=n===void 0?0:new TextEncoder().encode(n).byteLength,i=n===void 0||n.length===0?0:n.split(` +`).length,r=`/sessions/${encodeURIComponent(t)}/export`,l={web_log_bytes:s,web_log_entries:i},a=o?.desktop===!0;let u;try{u=await this.http.postZip(r,{web_log:n,...a?{desktop:!0}:{}},l)}catch(d){if(a&&Us(d)&&d.code===SG)u=await this.http.postZip(r,{web_log:n},l);else throw d}const c=`${t}.zip`;return{blob:u.blob,fileName:AG(u.contentDisposition,c)}}async submitPrompt(t,n){const o=Date.now();this.tracer.traceKeyEvent?.("prompt:start",{sessionId:t,contentCount:n.content.length,mediaCount:n.content.filter(s=>s.type==="image"||s.type==="video"||s.type==="file").length});try{const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts`,bU(n));return this.tracer.traceKeyEvent?.("prompt:accepted",{sessionId:t,promptId:s.prompt_id,status:s.status,durationMs:Date.now()-o}),{promptId:s.prompt_id,userMessageId:s.user_message_id,status:s.status}}catch(s){throw this.tracer.traceKeyEvent?.("prompt:failed",{sessionId:t,status:"failed",durationMs:Date.now()-o,...hb(s)}),s}}async steerPrompts(t,n){const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts:steer`,{prompt_ids:n});return{steered:o.steered,promptIds:o.prompt_ids}}async abortPrompt(t,n){const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts/${encodeURIComponent(n)}:abort`,void 0,{allowCodes:[40903]});return{aborted:o.aborted,atSeq:o.at_seq}}async abortSession(t){return{aborted:(await this.http.post(`/sessions/${encodeURIComponent(t)}:abort`,{})).aborted}}async compactSession(t,n){await this.http.post(`/sessions/${encodeURIComponent(t)}:compact`,n?{instruction:n}:{})}async undoSession(t,n=1){await this.http.post(`/sessions/${encodeURIComponent(t)}:undo`,{count:n})}async forkSession(t,n){const o={};n?.title!==void 0&&(o.title=n.title);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}:fork`,o);return Fr(s)}async createChildSession(t,n){const o={};n?.title!==void 0&&(o.title=n.title);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/children`,o);return Fr(s)}async listChildSessions(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/children`)).items.map(Fr)}async startBtw(t){return{agentId:(await this.http.post(`/sessions/${encodeURIComponent(t)}:btw`,{})).agent_id}}async respondApproval(t,n,o){const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/approvals/${encodeURIComponent(n)}`,CU(o));return{resolved:s.resolved,resolvedAt:s.resolved_at}}async respondQuestion(t,n,o){const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/questions/${encodeURIComponent(n)}`,SU(o));return{resolved:s.resolved,resolvedAt:s.resolved_at}}async dismissQuestion(t,n){return{dismissed:!0,dismissedAt:(await this.http.post(`/sessions/${encodeURIComponent(t)}/questions/${encodeURIComponent(n)}:dismiss`,void 0,{allowCodes:[40909]})).dismissed_at}}async listTasks(t,n){const o={status:n};return(await this.http.get(`/sessions/${encodeURIComponent(t)}/tasks`,o)).items.map(i=>Hh(i))}async getTask(t,n,o){const s={with_output:o?.withOutput,output_bytes:o?.outputBytes},i=await this.http.get(`/sessions/${encodeURIComponent(t)}/tasks/${encodeURIComponent(n)}`,s);return Hh(i)}async cancelTask(t,n){return await this.http.post(`/sessions/${encodeURIComponent(t)}/tasks/${encodeURIComponent(n)}:cancel`)}async listTerminals(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/terminals`)).items.map(s9)}async createTerminal(t,n={}){const o={cwd:n.cwd,shell:n.shell,cols:n.cols,rows:n.rows},s=await this.http.post(`/sessions/${encodeURIComponent(t)}/terminals`,o);return s9(s)}async getTerminal(t,n){const o=await this.http.get(`/sessions/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}`);return s9(o)}async closeTerminal(t,n){return this.http.post(`/sessions/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}:close`)}async listSkills(t){return((await this.http.get(`/sessions/${encodeURIComponent(t)}/skills`)).skills??[]).map(o=>({name:o.name,description:o.description,source:o.source}))}async listSkillsForWorkspace(t){return((await this.http.get(`/workspaces/${encodeURIComponent(t)}/skills`)).skills??[]).map(o=>({name:o.name,description:o.description,source:o.source}))}async activateSkill(t,n,o,s){const i={};o!==void 0&&o.length>0&&(i.args=o),s!==void 0&&s.length>0&&(i.attachments=s.map(BM));const r=await this.http.post(`/sessions/${encodeURIComponent(t)}/skills/${encodeURIComponent(n)}:activate`,i);return{activated:r.activated,skillName:r.skill_name}}async listDirectory(t,n){const o={};n.path!==void 0&&(o.path=n.path),n.depth!==void 0&&(o.depth=n.depth),n.includeGitStatus!==void 0&&(o.include_git_status=n.includeGitStatus);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:list`,o),i=s.children_by_path?Object.fromEntries(Object.entries(s.children_by_path).map(([r,l])=>[r,l.map(Wk)])):void 0;return{items:s.items.map(Wk),childrenByPath:i,truncated:s.truncated}}async readFile(t,n){const o={path:n.path};n.offset!==void 0&&(o.offset=n.offset),n.length!==void 0&&(o.length=n.length);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:read`,o);return{path:s.path,content:s.content,encoding:s.encoding,size:s.size,truncated:s.truncated,etag:s.etag,mime:s.mime,languageId:s.language_id,lineCount:s.line_count,isBinary:s.is_binary}}async searchFiles(t,n){const o={workspace:t,query:n.query};n.limit!==void 0&&(o.limit=n.limit);const s=await this.http.post("/workspace/fs:search",o);return{items:s.items.map(i=>({path:i.path,name:i.name,kind:i.kind,score:i.score,matchPositions:i.match_positions})),truncated:s.truncated}}async grepFiles(t,n){const o={pattern:n.pattern};n.regex!==void 0&&(o.regex=n.regex),n.caseSensitive!==void 0&&(o.case_sensitive=n.caseSensitive);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:grep`,o);return{files:s.files,filesScanned:s.files_scanned,truncated:s.truncated,elapsedMs:s.elapsed_ms}}async getGitStatus(t,n){const o={};n!==void 0&&(o.paths=n);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:git_status`,o);return{branch:s.branch,ahead:s.ahead,behind:s.behind,entries:s.entries,additions:s.additions,deletions:s.deletions,pullRequest:s.pullRequest??null}}async getFileDiff(t,n){const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:diff`,{path:n});return{path:o.path,diff:o.diff,truncated:o.truncated??!1}}getFileDownloadUrl(t,n){const o=n.split("/").map(s=>encodeURIComponent(s)).join("/");return Cd(this.opts.origin,`/sessions/${encodeURIComponent(t)}/fs/${o}:download`)}async openFile(t,n){const o={path:n.path};return n.line!==void 0&&(o.line=n.line),this.http.post(`/sessions/${encodeURIComponent(t)}/fs:open`,o)}async revealFile(t,n){return this.http.post(`/sessions/${encodeURIComponent(t)}/fs:reveal`,{path:n.path})}async openInApp(t,n,o,s){const i={app_id:n,path:o};s!==void 0&&(i.line=s),await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:open-in`,i)}async listWorkspaces(){try{return((await this.http.get("/workspaces")).items??[]).map(Pf)}catch{return[]}}async addWorkspace(t){const n={root:t.root};t.name!==void 0&&(n.name=t.name);const o=await this.http.post("/workspaces",n);return Pf(o)}async deleteWorkspace(t){await this.http.delete(`/workspaces/${encodeURIComponent(t)}`)}async updateWorkspace(t,n){const o=await this.http.patch(`/workspaces/${encodeURIComponent(t)}`,{name:n.name});return Pf(o)}async browseFs(t){try{const n=await this.http.get("/fs:browse",{path:t});return{path:n.path,parent:n.parent,entries:(n.entries??[]).map(o=>({name:o.name,path:o.path,isDir:o.is_dir}))}}catch{return{path:"",parent:null,entries:[]}}}async getFsHome(){try{const t=await this.http.get("/fs:home");return{home:t.home,recentRoots:t.recent_roots??[]}}catch{return{home:"",recentRoots:[]}}}async listModels(){return(await this.http.get("/models")).items.map(MU)}async listProviders(){return(await this.http.get("/providers")).items.map(nd)}async getProvider(t){const n=await this.http.get(`/providers/${encodeURIComponent(t)}`),o=nd(n);return n.api_key!==void 0?{...o,apiKey:n.api_key}:o}async addProvider(t){const n={id:t.id??"",type:t.type,models:(t.models??[]).map(s=>{const i={model:s.model,max_context_size:s.maxContextSize};return s.displayName!==void 0&&(i.display_name=s.displayName),s.capabilities!==void 0&&(i.capabilities=s.capabilities),s.maxOutputSize!==void 0&&(i.max_output_size=s.maxOutputSize),s.supportEfforts!==void 0&&(i.support_efforts=s.supportEfforts),s.adaptiveThinking!==void 0&&(i.adaptive_thinking=s.adaptiveThinking),i})};t.apiKey!==void 0&&(n.api_key=t.apiKey),t.baseUrl!==void 0&&(n.base_url=t.baseUrl),t.defaultModel!==void 0&&(n.default_model=t.defaultModel);const o=await this.http.post("/providers",n);return nd(o)}async updateProvider(t,n){const o={type:n.type,models:(n.models??[]).map(i=>{const r={model:i.model,max_context_size:i.maxContextSize};return i.displayName!==void 0&&(r.display_name=i.displayName),i.capabilities!==void 0&&(r.capabilities=i.capabilities),i.maxOutputSize!==void 0&&(r.max_output_size=i.maxOutputSize),i.supportEfforts!==void 0&&(r.support_efforts=i.supportEfforts),i.adaptiveThinking!==void 0&&(r.adaptive_thinking=i.adaptiveThinking),r})};n.newId!==void 0&&(o.new_id=n.newId),n.apiKey!==void 0&&(o.api_key=n.apiKey),n.baseUrl!==void 0&&(o.base_url=n.baseUrl),n.defaultModel!==void 0&&(o.default_model=n.defaultModel);const s=await this.http.put(`/providers/${encodeURIComponent(t)}`,o);return{provider:nd(s.provider)}}async deleteProvider(t){return await this.http.delete(`/providers/${encodeURIComponent(t)}`),{deleted:t}}async listCatalogProviders(){return(await this.http.get("/catalog/providers")).items.map(Uk)}async getCatalogProvider(t){const n=await this.http.get(`/catalog/providers/${encodeURIComponent(t)}`);return Uk(n)}async importCatalogProvider(t){const n={catalog_id:t.catalogId};t.apiKey!==void 0&&(n.api_key=t.apiKey),t.baseUrl!==void 0&&(n.base_url=t.baseUrl),t.id!==void 0&&(n.id=t.id);const o=await this.http.post("/providers:import_catalog",n);return{provider:nd(o.provider),modelsImported:o.models_imported}}async importCustomRegistry(t){const n={url:t.url};t.apiKey!==void 0&&(n.api_key=t.apiKey);const o=await this.http.post("/providers:import_registry",n);return{providers:o.providers.map(nd),modelsImported:o.models_imported}}async refreshProvider(t){const n=await this.http.post(`/providers/${encodeURIComponent(t)}:refresh`);return i9(n)}async refreshAllProviders(){const t=await this.http.post("/providers:refresh");return i9(t)}async refreshOAuthProviderModels(){const t=await this.http.post("/providers:refresh_oauth");return i9(t)}async getConfig(){const t=await this.http.get("/config");return i3(t)}async setConfig(t){const n={},o={providers:"providers",defaultProvider:"default_provider",defaultModel:"default_model",secondaryModel:"secondary_model",models:"models",thinking:"thinking",planMode:"plan_mode",yolo:"yolo",defaultPermissionMode:"default_permission_mode",defaultPlanMode:"default_plan_mode",permission:"permission",hooks:"hooks",services:"services",mergeAllAvailableSkills:"merge_all_available_skills",extraSkillDirs:"extra_skill_dirs",loopControl:"loop_control",background:"background",experimental:"experimental",telemetry:"telemetry",raw:"raw"};for(const[i,r]of Object.entries(t)){const l=o[i];l!==void 0&&(n[l]=r)}const s=await this.http.post("/config",n);return i3(s)}async getAuth(){const t=await this.http.get("/auth");return{ready:t.ready,providersCount:t.providers_count,defaultModel:t.default_model,managedProvider:t.managed_provider?{status:t.managed_provider.status}:null}}async startOAuthLogin(){const t=await this.http.post("/oauth/login",{});return t.status==="authenticated"?{flowId:t.flow_id,provider:t.provider,status:"authenticated"}:{flowId:t.flow_id,provider:t.provider,status:"pending",verificationUri:t.verification_uri,verificationUriComplete:t.verification_uri_complete,userCode:t.user_code,expiresIn:t.expires_in,interval:t.interval,expiresAt:t.expires_at}}async pollOAuthLogin(){const t=await this.http.get("/oauth/login");return t?{flowId:t.flow_id,status:t.status,resolvedAt:t.resolved_at}:null}async cancelOAuthLogin(){const t=await this.http.delete("/oauth/login");return{cancelled:t.cancelled,status:t.status}}async logout(){return{loggedOut:(await this.http.post("/oauth/logout",{})).logged_out}}async getUsage(){const t=await this.http.get("/oauth/usage");if(t.kind==="error")return{kind:"error",message:t.message,status:t.status};const n=o=>({name:o.name,window:o.window,used:o.used,limit:o.limit,resetAt:o.reset_at});return{kind:"ok",summary:t.summary===null?null:n(t.summary),limits:t.limits.map(n),extraUsage:t.extra_usage===null?null:{balanceCents:t.extra_usage.balance_cents,totalCents:t.extra_usage.total_cents,monthlyChargeLimitEnabled:t.extra_usage.monthly_charge_limit_enabled,monthlyChargeLimitCents:t.extra_usage.monthly_charge_limit_cents,monthlyUsedCents:t.extra_usage.monthly_used_cents,currency:t.extra_usage.currency}}}async getUserInfo(){return this.http.get("/oauth/userinfo")}async uploadFile(t){const n=new FormData;n.append("file",t.file,t.name??(t.file instanceof File?t.file.name:"upload")),t.name!==void 0&&n.append("name",t.name);const o=await this.http.postForm("/files",n);return{id:o.id,name:o.name,mediaType:o.media_type,size:o.size}}getFileUrl(t){return Cd(this.opts.origin,`/files/${encodeURIComponent(t)}`)}async getFileBlob(t){return this.http.getBlob(`/files/${encodeURIComponent(t)}`)}async readHostFileContent(t){const n=await this.http.getBlob("/fs:content",{path:t},{maxBytes:o9});if(n.size>o9)throw new sy({size:n.size,limit:o9});const o=n.type,s=!TG(o),i=o||(s?"application/octet-stream":"text/plain");if(s){const l=await EG(n);return{path:t,content:l,encoding:"base64",mime:i,isBinary:!0,size:n.size}}const r=await n.text();return{path:t,content:r,encoding:"utf-8",mime:i,isBinary:!1,size:n.size}}connectEvents(t){const n=fU(this.opts.origin,this.opts.identity.clientId),o=this.opts.projectorFactory(),s=new _G({wsUrl:n,clientId:this.opts.identity.clientId,tracer:this.tracer,credentialStore:this.opts.credentialStore,mainAgentOnly:this.opts.mainAgentOnly,handlers:{onWireEvent:i=>{const r=TU(i),l=EU(i),a=AU(i);a.type==="historyCompacted"&&!mb(a.reason)&&t.onResync(a.sessionId,a.beforeSeq),t.onEvent(a,{sessionId:r,seq:l})},onRawAgentEvent:i=>{const{type:r,seq:l,session_id:a,payload:u,offset:c}=i,d=o.project(r,u,a,{offset:c});for(const f of d){const h=u?.turnId,m=f.type==="assistantDelta"&&typeof h=="number"&&typeof c=="number"&&(r==="assistant.delta"||r==="thinking.delta")?{turnId:h,offset:c,kind:r==="assistant.delta"?"text":"thinking"}:void 0;f.type==="historyCompacted"&&!mb(f.reason)&&t.onResync(a,l),t.onEvent(f,{sessionId:a,seq:l,stream:m})}},onResync:(i,r,l)=>{o.reset(i),t.onResync(i,r,l)},onConnectionState:i=>{t.onConnectionChange(i)},onReplayComplete:()=>{t.onReplayComplete?.()},onError:(i,r,l)=>{t.onError(i,r,l)},onTerminalOutput:(i,r,l,a)=>{t.onTerminalOutput?.(i,r,l,a)},onTerminalExit:(i,r,l)=>{t.onTerminalExit?.(i,r,l)},onTranscriptReset:(i,r,l,a)=>{t.onTranscriptReset?.(i,r,l,a)},onTranscriptOps:(i,r,l,a)=>t.onTranscriptOps?.(i,r,l,a)??!0}});return s.connect(),{subscribe(i,r){s.subscribe(i,r??{seq:0})},unsubscribe(i){s.unsubscribe(i)},subscribeTranscript(i,r,l){s.subscribeTranscript(i,r,l)},unsubscribeTranscript(i,r){s.unsubscribeTranscript(i,r)},seedSnapshot(i,r){if(r.inFlightTurn===null){o.reset(i);return}const l=o.seedInFlight(i,r.inFlightTurn);for(const a of l)t.onEvent(a,{sessionId:i,seq:r.asOfSeq})},bindNextPromptId(i,r){o.bindNextPromptId(i,r)},abort(i,r){s.abort(i,r)},terminalAttach(i,r,l){s.terminalAttach(i,r,l)},terminalInput(i,r,l){s.terminalInput(i,r,l)},terminalResize(i,r,l,a){s.terminalResize(i,r,l,a)},terminalDetach(i,r){s.terminalDetach(i,r)},terminalClose(i,r){s.terminalClose(i,r)},markSideChannelAgent(i,r){s.markSideChannelAgent(i,r),o.markSideChannelAgent(r)},health(){return s.health()},reconnect(){s.reconnect()},close(){s.close()}}}}function i9(e){return{changed:e.changed.map(t=>({providerId:t.provider_id,providerName:t.provider_name,added:t.added,removed:t.removed})),unchanged:e.unchanged,failed:e.failed}}function TG(e){const t=e.toLowerCase().split(";")[0].trim();return t===""||t==="text/plain"||t.startsWith("text/")?!0:/(json|xml|javascript|typescript|x-yaml|yaml|svg|x-sh|x-python|markdown|csv|html|css)$/.test(t)}function EG(e){return new Promise((t,n)=>{const o=new FileReader;o.onload=()=>{const s=String(o.result);t(s.slice(s.indexOf(",")+1))},o.onerror=()=>n(o.error),o.readAsDataURL(e)})}function IG(){return window.kimiDesktop}function FT(e,t,n){const o=n.length===0?void 0:n.length===1?n[0]:n;try{IG()?.log?.(e,t,o)}catch{}}function gl(e,...t){console.warn(e,...t),FT("warn",e,t)}function Xl(e,...t){console.error(e,...t),FT("error",e,t)}const LG={multiedit:"multi_edit",multiedits:"multi_edit",shell:"bash",run:"bash",exec:"bash",ripgrep:"grep",rg:"grep",find:"glob",fetch:"web_fetch",webfetch:"web_fetch",url_fetch:"web_fetch",urlfetch:"web_fetch",list:"ls",listdir:"ls",list_dir:"ls",todowrite:"todo",todo_write:"todo",todoread:"todo",todolist:"todo",todo_list:"todo",agent:"task",subagent:"task",websearch:"search",web_search:"search",create_goal:"creategoal",get_goal:"getgoal",set_goal_budget:"setgoalbudget",update_goal:"updategoal"};function Gs(e){const t=(e??"").trim().toLowerCase().replace(/[\s-]+/g,"_");return LG[t]??t}const $G={read:"tools.label.read",bash:"tools.label.bash",edit:"tools.label.edit",multi_edit:"tools.label.edit",write:"tools.label.write",grep:"tools.label.grep",glob:"tools.label.glob",ls:"tools.label.ls",web_fetch:"tools.label.web_fetch",search:"tools.label.search",todo:"tools.label.todo",task:"tools.label.task",agentswarm:"tools.label.swarm",askuserquestion:"tools.label.ask_user",exitplanmode:"tools.label.plan",creategoal:"tools.label.goal_create",getgoal:"tools.label.goal_get",setgoalbudget:"tools.label.goal_budget",updategoal:"tools.label.goal_update"};function RT(e,t){const n=$G[Gs(t)];return n?e(n):t}const OT=80;function NG(e,t=OT){const n=e.trim();return n.length>t?n.slice(0,t-1)+"…":n}function FG(e,t){const n=e.trim();return!!(n===""||n==="{}"||n==="[]"||n==="null"||t&&Object.keys(t).length===0)}function RG(e){const t=e.trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function En(e){return typeof e=="string"&&e.length>0?e:void 0}function Ta(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function OG(e){try{const t=new URL(e),n=t.pathname.split("/").filter(Boolean)[0];return n?`${t.host}/${n}`:t.host}catch{return e.replace(/^https?:\/\//,"")}}function r9(e){return En(e.path)??En(e.file_path)??En(e.filePath)??En(e.filename)}const PG={active:"status.goalStatusActive",blocked:"status.goalStatusBlocked",complete:"status.goalStatusComplete"};function DG(e,t){const n=En(t);if(!n)return;const o=PG[n];return o?e(o):n}function BG(e,t){const n=Ta(t.value),o=En(t.unit);if(!(n===void 0||!o))switch(o){case"turns":return e("tools.goal.turns",{value:n});case"tokens":return e("tools.goal.tokens",{value:n});case"milliseconds":return e("tools.goal.milliseconds",{value:n});case"seconds":return e("tools.goal.seconds",{value:n});case"minutes":return e("tools.goal.minutes",{value:n});case"hours":return e("tools.goal.hours",{value:n});default:return e("tools.goal.budget",{value:n,unit:o})}}function wy(e,t,n,o=!1){const s=(i,r=OT)=>o?i.trim():NG(i,r);try{const i=RG(n);if(!o&&FG(n,i))return"";const r=()=>s(n.replace(/^·\s*/,""));if(!i)return r();switch(Gs(t)){case"read":{const l=r9(i);if(!l)return r();const a=Ta(i.offset)??Ta(i.line_start)??Ta(i.start_line),u=Ta(i.limit)??Ta(i.length),c=Ta(i.line_end)??Ta(i.end_line)??(a!==void 0&&u!==void 0?a+u:void 0);return s(a!==void 0&&c!==void 0?`${l}:${a}-${c}`:a!==void 0?`${l}:${a}`:l)}case"write":{const l=r9(i);return l?s(`${l} ${e("tools.chip.created")}`):r()}case"edit":case"multi_edit":{const l=r9(i);return l?s(l):r()}case"bash":{const l=En(i.command)??En(i.cmd)??En(i.script);return l?l.trim():r()}case"grep":case"search":{const l=En(i.pattern)??En(i.query)??En(i.regex),a=En(i.path)??En(i.glob)??En(i.include);return l&&a?s(e("tools.summary.inScope",{value:l,scope:a})):l?s(l):r()}case"glob":{const l=En(i.pattern)??En(i.glob)??En(i.query),a=En(i.path)??En(i.cwd);return l&&a?s(e("tools.summary.inScope",{value:l,scope:a})):l?s(l):En(i.path)?s(En(i.path)):r()}case"ls":{const l=En(i.path)??En(i.dir)??En(i.directory)??En(i.cwd);return l?s(l):r()}case"web_fetch":{const l=En(i.url)??En(i.uri);return l?s(OG(l)):r()}case"todo":case"task":{const l=En(i.description)??En(i.title)??En(i.prompt)??En(i.name)??En(i.subagent_type);if(l)return s(l);const a=Array.isArray(i.todos)?i.todos:Array.isArray(i.items)?i.items:void 0;return a?s(e("tools.chip.todos",{count:a.length})):r()}case"creategoal":{if(o)return r();const l=En(i.objective),a=En(i.completionCriterion);return l&&a?s(e("tools.goal.objectiveWithCriterion",{objective:l,criterion:a})):l?s(l):r()}case"getgoal":return o?r():"";case"setgoalbudget":{if(o)return r();const l=BG(e,i);return l?s(l):r()}case"updategoal":{if(o)return r();const l=DG(e,i.status);return l?s(e("tools.goal.status",{status:l})):r()}default:return r()}}catch{return n}}function HG(e,t){try{switch(Gs(t.name)){case"bash":return t.timing?t.timing:"";case"read":{if(t.output&&t.output.length>0){const n=t.output.length;return e("tools.chip.lines",{count:n})}return""}case"edit":case"multi_edit":case"write":{if(t.output){for(const o of t.output){const s=o.match(/\+(\d+).*[-−](\d+)/);if(s)return`+${s[1]} −${s[2]}`}const n=t.output.find(o=>/\d+/.test(o));if(n){const o=n.match(/\+(\d+)/),s=n.match(/[-−](\d+)/);if(o||s)return`${o?`+${o[1]}`:""} ${s?`−${s[1]}`:""}`.trim()}if(t.status!=="error")return e("tools.chip.edited")}return""}case"grep":case"search":return t.output&&t.output.length>0?e("tools.chip.results",{count:t.output.length}):"";default:return""}}catch{return""}}const zG="main",WG=new Set(["turn.started","turn.step.started","turn.step.completed","turn.step.retrying","turn.step.interrupted","turn.ended","thinking.delta","assistant.delta","tool.use","tool.call.started","tool.call.delta","tool.progress","tool.result","agent.status.updated","prompt.completed","prompt.aborted","error"]);function pl(e="msg_"){const t=Date.now().toString(36).padStart(10,"0"),n=Math.random().toString(36).slice(2,12).padEnd(10,"0");return`${e}${t}${n}`}function UG(e){if(!e||typeof e!="object")return{input:0,output:0,cacheRead:0,cacheCreate:0};const t=e;return{input:t.inputOther??t.input_tokens??0,output:t.output??t.output_tokens??0,cacheRead:t.inputCacheRead??t.cache_read_input_tokens??0,cacheCreate:t.inputCacheCreation??t.cache_creation_input_tokens??0}}function gb(){return{turnPromptId:new Map,currentPromptId:void 0,currentAssistantMsgId:void 0,turnTextLen:0,turnThinkLen:0,toolStartTimes:new Map,totalInput:0,totalOutput:0,totalCacheRead:0,totalCacheCreate:0,contextTokens:0,contextLimit:0,turnCount:0,model:"",messages:[],subagentMeta:new Map,retryReuseMsgId:void 0,retryActive:!1}}function _o(e,t){const n=e[t];return typeof n=="string"?n:void 0}function Ts(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:void 0}function hr(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null}function jG(e){if(!e||typeof e!="object")return null;const t=e,n=t.budget,o=n&&typeof n=="object"?n:{},s=_o(t,"status");if(s!=="active"&&s!=="paused"&&s!=="blocked"&&s!=="complete")return null;const i=_o(t,"goalId")??_o(t,"goal_id")??"goal",r=_o(t,"objective")??"";return{goalId:i,objective:r,completionCriterion:_o(t,"completionCriterion")??_o(t,"completion_criterion"),status:s,turnsUsed:Ts(t,"turnsUsed")??Ts(t,"turns_used")??0,tokensUsed:Ts(t,"tokensUsed")??Ts(t,"tokens_used")??0,wallClockMs:Ts(t,"wallClockMs")??Ts(t,"wall_clock_ms")??0,terminalReason:_o(t,"terminalReason")??_o(t,"terminal_reason"),budget:{tokenBudget:hr(o,"tokenBudget")??hr(o,"token_budget"),remainingTokens:hr(o,"remainingTokens")??hr(o,"remaining_tokens"),turnBudget:hr(o,"turnBudget")??hr(o,"turn_budget"),remainingTurns:hr(o,"remainingTurns")??hr(o,"remaining_turns"),wallClockBudgetMs:hr(o,"wallClockBudgetMs")??hr(o,"wall_clock_budget_ms"),remainingWallClockMs:hr(o,"remainingWallClockMs")??hr(o,"remaining_wall_clock_ms"),overBudget:o.overBudget===!0||o.over_budget===!0}}}function Ku(e,t,n,o,s){if(typeof o!="string"||o.length===0)return null;const r={...t.subagentMeta.get(o)??{id:o,agentId:o,sessionId:n,kind:"subagent",description:e("tasks.dockSubagent"),status:"running",createdAt:new Date().toISOString(),subagentPhase:"queued"},...s,id:o,sessionId:n,kind:"subagent"};return t.subagentMeta.set(o,r),r}function VG(e,t,n){if(t==="turn.step.started")return null;if(t==="tool.use"||t==="tool.call.started"){const o=_o(n,"name")??_o(n,"toolName")??"tool",s=RT(e,qG(o)),i=KG(e,o,n.args??n.input);return i?`Calling ${s}: ${i}`:`Calling ${s}`}if(t==="tool.progress"){const o=n.update;if(o&&typeof o=="object"){const i=_o(o,"text");if(i)return l9(i);const r=_o(o,"message");if(r)return l9(r)}const s=_o(n,"message");if(s)return l9(s)}return null}function qG(e){return e.replace(/_\d+$/,"")}const vb=2e3;function l9(e){return e.length>vb?`${e.slice(0,vb)}…`:e}function KG(e,t,n){if(n==null)return"";const o=typeof n=="string"?n:JSON.stringify(n);return wy(e,t,o)}function ZG(e,t,n,o,s,i,r){if(r.has(o)&&s==="turn.step.started")return[];if(s==="assistant.delta"){const d=_o(i,"delta");if(!d)return[];const f=t.subagentMeta.get(o),h=Ku(e,t,n,o,{status:"running",subagentPhase:"working",startedAt:f?.startedAt??new Date().toISOString()}),m=[];return h&&m.push({type:"taskCreated",sessionId:n,task:h}),m.push({type:"taskProgress",sessionId:n,taskId:o,outputChunk:d,stream:"stdout",kind:"text"}),m}const l=VG(e,s,i);if(l===null||l.length===0)return[];const a=t.subagentMeta.get(o),u=Ku(e,t,n,o,{status:"running",subagentPhase:"working",startedAt:a?.startedAt??new Date().toISOString()}),c=[];return u&&c.push({type:"taskCreated",sessionId:n,task:u}),c.push({type:"taskProgress",sessionId:n,taskId:o,outputChunk:l,stream:"stdout"}),c}function $u(e){return{...e,content:e.content.map(t=>({...t}))}}function yb(e,t,n){const o={id:pl("msg_"),sessionId:t,role:"assistant",content:[],createdAt:new Date().toISOString(),promptId:n};return e.messages.push(o),o}function GG(e,t,n,o,s,i){const r={id:o,sessionId:t,role:"user",content:s,createdAt:i,promptId:n};return e.messages.push(r),r}function kb(e){return Array.isArray(e)?e.map(t=>ry(t)):[]}function bb(e,t,n,o){const s=e.messages.find(r=>r.id===t);if(!s)return-1;const i=s.content.at(-1);return i&&i.type===n?(n==="text"?i.text+=o:i.thinking+=o,s.content.length-1):(s.content.push(n==="text"?{type:"text",text:o}:{type:"thinking",thinking:o}),s.content.length-1)}function YG(e,t,n,o,s,i){const r=e.messages.find(l=>l.id===t);r&&r.content.push({type:"toolUse",toolCallId:n,toolName:o,input:s,outputLines:i})}function XG(e){const t=e.update,n=t&&typeof t=="object"?t:null,s=(n?.stream??n?.kind??e.stream)==="stderr"?"stderr":"stdout",i=typeof n?.text=="string"&&n.text||typeof n?.message=="string"&&n.message||typeof e.chunk=="string"&&e.chunk||typeof e.output=="string"&&e.output||typeof e.message=="string"&&e.message||"";return i.length>0?{outputChunk:i,stream:s}:null}function Cb(e,t){e.messages.find(n=>n.id===t)}function JG(e,t,n,o,s,i){const r={id:pl("msg_"),sessionId:t,role:"tool",content:[{type:"toolResult",toolCallId:n,output:o,isError:s}],createdAt:new Date().toISOString(),promptId:i};return e.messages.push(r),r}function ef(e,t){return e.messages.find(n=>n.id===t)}function wb(e){return{inputTokens:e.totalInput,outputTokens:e.totalOutput,cacheReadTokens:e.totalCacheRead,cacheCreationTokens:e.totalCacheCreate,totalCostUsd:0,contextTokens:e.contextTokens,contextLimit:e.contextLimit,turnCount:e.turnCount}}function QG(e){const{t}=e,n=new Map,o=new Set;function s(f){let h=n.get(f);return h||(h=gb(),n.set(f,h)),h}function i(f){n.set(f,gb())}function r(f){o.add(f)}function l(f,h){const m=s(f);m.currentPromptId=h}function a(f,h){i(f);const m=s(f),v=h.promptId??pl("pr_");m.currentPromptId=v,m.turnPromptId.set(h.turnId,v);const k=yb(m,f,v);h.thinkingText.length>0&&k.content.push({type:"thinking",thinking:h.thinkingText}),h.assistantText.length>0&&k.content.push({type:"text",text:h.assistantText});for(const w of h.runningTools){const b=typeof w.lastProgress?.text=="string"&&w.lastProgress.text.length>0?[w.lastProgress.text]:void 0;k.content.push({type:"toolUse",toolCallId:w.toolCallId,toolName:w.name,input:w.args??{},outputLines:b}),m.toolStartTimes.set(w.toolCallId,Date.now())}return m.currentAssistantMsgId=k.id,m.turnTextLen=h.assistantText.length,m.turnThinkLen=h.thinkingText.length,[{type:"messageCreated",message:$u(k)}]}function u(f,h,m,v){try{return d(f,h,m,v)}catch(k){return Xl("[agentProjector] Error projecting event:",f,k instanceof Error?k.message:k),[]}}function c(f,h){return h===void 0?"append":h<f?"skip":h>f?"gap":"append"}function d(f,h,m,v){const k=s(m),w=h,b=[],_=w?.agentId;if(typeof _=="string"&&_!==zG){const g=o.has(_);if(f==="prompt.submitted"){if(!g)return[];const x=w?.promptId,S=w?.userMessageId;if(!x||!S)return[];const T=kb(w?.content);return T.length===0?[]:[{type:"messageCreated",agentId:_,message:{id:S,sessionId:m,role:"user",content:T,createdAt:typeof w?.createdAt=="string"?w.createdAt:new Date().toISOString(),promptId:x}}]}if(g&&(f==="thinking.delta"||f==="assistant.delta")){const x=w?.delta??"";return x?[{type:"agentDelta",sessionId:m,agentId:_,delta:{[f==="thinking.delta"?"thinking":"text"]:x}}]:[]}if(g&&f==="turn.ended")return[{type:"agentTurnEnded",sessionId:m,agentId:_,reason:w?.reason}];if(WG.has(f))return ZG(t,k,m,_,f,w??{},o)}switch(f){case"session.meta.updated":{const g=w?.patch?.title??w?.title,x=w?.patch?.lastPrompt,S={};typeof g=="string"&&g.length>0&&(S.title=g),typeof x=="string"&&(S.lastPrompt=x),(S.title!==void 0||S.lastPrompt!==void 0)&&b.push({type:"sessionMetaUpdated",sessionId:m,...S});break}case"prompt.submitted":{const g=w?.promptId,x=w?.userMessageId;if(!g||!x)break;const S=kb(w?.content);if(S.length===0)break;k.currentPromptId=g;const T=GG(k,m,g,x,S,typeof w?.createdAt=="string"?w.createdAt:new Date().toISOString());b.push({type:"messageCreated",message:$u(T),...typeof _=="string"?{agentId:_}:{}});break}case"turn.started":{const g=w?.turnId,x=k.currentPromptId??pl("pr_");k.currentPromptId=x,g!==void 0&&k.turnPromptId.set(g,x),k.turnTextLen=0,k.turnThinkLen=0;const S=w?.origin;if(S&&typeof S=="object"&&S.kind==="system_trigger"&&S.name==="goal_continuation"){const T={id:g!==void 0?`goal_cont_${g}`:pl("goal_"),sessionId:m,role:"user",content:[{type:"text",text:_o(w??{},"prompt")??""}],createdAt:new Date().toISOString(),metadata:{origin:S}};k.messages.push(T),b.push({type:"turnActiveChanged",sessionId:m,active:!0}),b.push({type:"messageCreated",message:$u(T)});break}b.push({type:"turnActiveChanged",sessionId:m,active:!0});break}case"turn.step.started":{const g=w?.turnId;k.retryActive&&(k.retryActive=!1,b.push({type:"turnRetry",sessionId:m,retry:void 0}));let x=k.turnPromptId.get(g)??k.currentPromptId;if(x||(x=pl("pr_"),k.currentPromptId=x,g!==void 0&&k.turnPromptId.set(g,x)),k.turnTextLen=0,k.turnThinkLen=0,k.retryReuseMsgId!==void 0){const T=k.retryReuseMsgId;if(k.retryReuseMsgId=void 0,ef(k,T)!==void 0){k.currentAssistantMsgId=T;break}}const S=yb(k,m,x);k.currentAssistantMsgId=S.id,b.push({type:"messageCreated",message:$u(S)});break}case"thinking.delta":{const g=k.currentAssistantMsgId;if(!g)break;const x=w?.delta??"";if(!x)break;v?.offset===0&&k.turnThinkLen>0&&(k.turnThinkLen=0);const S=c(k.turnThinkLen,v?.offset);if(S==="skip")break;if(S==="gap"){b.push({type:"historyCompacted",sessionId:m,beforeSeq:0,reason:"delta_gap"});break}const T=bb(k,g,"thinking",x);if(T<0)break;k.turnThinkLen+=x.length,b.push({type:"assistantDelta",sessionId:m,messageId:g,contentIndex:T,delta:{thinking:x}});break}case"assistant.delta":{const g=k.currentAssistantMsgId;if(!g)break;const x=w?.delta??"";if(!x)break;v?.offset===0&&k.turnTextLen>0&&(k.turnTextLen=0);const S=c(k.turnTextLen,v?.offset);if(S==="skip")break;if(S==="gap"){b.push({type:"historyCompacted",sessionId:m,beforeSeq:0,reason:"delta_gap"});break}const T=bb(k,g,"text",x);if(T<0)break;k.turnTextLen+=x.length,b.push({type:"assistantDelta",sessionId:m,messageId:g,contentIndex:T,delta:{text:x}});break}case"tool.use":case"tool.call.started":{const g=k.currentAssistantMsgId,x=w?.turnId,S=k.turnPromptId.get(x)??k.currentPromptId;if(!g||!S)break;const T=w?.toolCallId,A=w?.name??w?.toolName??"",E=w?.args??w?.input??{};YG(k,g,T,A,E);const P=ef(k,g);P&&P.content.length-1,k.toolStartTimes.set(T,Date.now()),P&&b.push({type:"messageUpdated",sessionId:m,messageId:g,content:P.content.map(D=>({...D})),status:"pending"});break}case"tool.call.delta":break;case"tool.progress":{const g=w?.toolCallId,x=XG(w??{});g&&x&&b.push({type:"toolOutput",sessionId:m,toolCallId:g,outputChunk:x.outputChunk,stream:x.stream});break}case"tool.result":{const g=w?.turnId;let x=k.turnPromptId.get(g)??k.currentPromptId;x||(x=pl("pr_"),k.currentPromptId=x,g!==void 0&&k.turnPromptId.set(g,x));const S=w?.toolCallId,T=w?.output,A=w?.isError??!1;k.toolStartTimes.get(S)??Date.now(),k.toolStartTimes.delete(S);const E=JG(k,m,S,T,A,x);b.push({type:"messageCreated",message:$u(E)}),k.currentAssistantMsgId=void 0;break}case"turn.step.completed":{const g=k.currentAssistantMsgId,x=UG(w?.usage);if(k.totalInput+=x.input,k.totalOutput+=x.output,k.totalCacheRead+=x.cacheRead,k.totalCacheCreate+=x.cacheCreate,g){Cb(k,g);const S=ef(k,g);S&&b.push({type:"messageUpdated",sessionId:m,messageId:g,content:S.content.map(T=>({...T})),status:"completed"})}break}case"agent.status.updated":{w?.model&&(k.model=w.model),w?.contextTokens!==void 0&&(k.contextTokens=w.contextTokens),w?.maxContextTokens!==void 0&&(k.contextLimit=w.maxContextTokens);const g=w?.phase;g!=null&&g.kind==="retrying"?(k.retryActive=!0,b.push({type:"turnRetry",sessionId:m,retry:{failedAttempt:Ts(g,"failedAttempt")??0,nextAttempt:Ts(g,"nextAttempt")??0,maxAttempts:Ts(g,"maxAttempts")??0,delayMs:Ts(g,"delayMs")??0,errorName:_o(g,"errorName"),statusCode:Ts(g,"statusCode"),turnId:Ts(g,"turnId")}})):k.retryActive&&g!==void 0&&g!==null&&typeof g.kind=="string"&&(k.retryActive=!1,b.push({type:"turnRetry",sessionId:m,retry:void 0})),b.push({type:"sessionUsageUpdated",sessionId:m,usage:wb(k),model:k.model||void 0,swarmMode:w?.swarmMode===!0?!0:w?.swarmMode===!1?!1:void 0,planMode:w?.planMode===!0?!0:w?.planMode===!1?!1:void 0,thinking:typeof w?.thinkingEffort=="string"&&w.thinkingEffort.length>0?w.thinkingEffort:void 0});break}case"turn.ended":{const g=k.currentAssistantMsgId,x=w?.reason??"completed",S=Ts(w??{},"durationMs"),T=w?.turnId,A=(T!==void 0?k.turnPromptId.get(T):void 0)??k.currentPromptId;if(b.push({type:"turnActiveChanged",sessionId:m,active:!1,reason:w?.reason,promptId:A}),g){Cb(k,g);const P=ef(k,g);P&&b.push({type:"messageUpdated",sessionId:m,messageId:g,content:P.content.map(D=>({...D})),status:x==="failed"||x==="blocked"?"error":"completed",durationMs:S})}k.turnCount++;const E=wb(k);b.push({type:"sessionUsageUpdated",sessionId:m,usage:E}),k.currentAssistantMsgId=void 0,k.currentPromptId=void 0,k.turnTextLen=0,k.turnThinkLen=0,k.retryReuseMsgId=void 0;break}case"prompt.completed":{const g=w?.promptId;typeof g=="string"&&g.length>0&&b.push({type:"promptCompleted",sessionId:m,promptId:g,reason:w?.reason??"completed"});break}case"prompt.aborted":{const g=w?.promptId;typeof g=="string"&&g.length>0&&b.push({type:"promptAborted",sessionId:m,promptId:g});break}case"turn.step.retrying":{k.retryActive=!0,b.push({type:"turnRetry",sessionId:m,retry:{failedAttempt:Ts(w??{},"failedAttempt")??0,nextAttempt:Ts(w??{},"nextAttempt")??0,maxAttempts:Ts(w??{},"maxAttempts")??0,delayMs:Ts(w??{},"delayMs")??0,errorName:_o(w??{},"errorName"),statusCode:Ts(w??{},"statusCode"),turnId:typeof w?.turnId=="number"?w.turnId:void 0}});const g=k.currentAssistantMsgId;if(g!==void 0){const x=ef(k,g);x!==void 0&&(x.content=x.content.filter(S=>S.type!=="text"&&S.type!=="thinking"&&S.type!=="toolUse"),b.push({type:"messageUpdated",sessionId:m,messageId:g,content:x.content.map(S=>({...S})),status:"pending"}),k.retryReuseMsgId=g)}k.turnTextLen=0,k.turnThinkLen=0,k.toolStartTimes.clear();break}case"turn.step.interrupted":{k.currentAssistantMsgId=void 0,k.retryReuseMsgId=void 0;break}case"subagent.spawned":{const g=typeof w?.subagentId=="string"&&w.subagentId.length>0?w.subagentId:pl("task_"),x={id:g,agentId:g,sessionId:m,kind:"subagent",description:typeof w?.description=="string"?w.description:w?.subagentName??t("tasks.dockSubagent"),status:"running",createdAt:new Date().toISOString(),subagentPhase:"queued",subagentType:typeof w?.subagentName=="string"?w.subagentName:void 0,model:typeof w?.model=="string"&&w.model.length>0?w.model:void 0,thinkingEffort:typeof w?.thinkingEffort=="string"&&w.thinkingEffort.length>0?w.thinkingEffort:void 0,parentToolCallId:typeof w?.parentToolCallId=="string"?w.parentToolCallId:void 0,swarmIndex:typeof w?.swarmIndex=="number"?w.swarmIndex:void 0,runInBackground:w?.runInBackground===!0};k.subagentMeta.set(x.id,x),b.push({type:"taskCreated",sessionId:m,task:x});break}case"subagent.started":{const g=Ku(t,k,m,w?.subagentId,{subagentPhase:"working",status:"running",startedAt:new Date().toISOString()});g&&b.push({type:"taskCreated",sessionId:m,task:g});break}case"subagent.suspended":{const g=Ku(t,k,m,w?.subagentId,{subagentPhase:"suspended",status:"running",suspendedReason:typeof w?.reason=="string"?w.reason:void 0});g&&b.push({type:"taskCreated",sessionId:m,task:g});break}case"subagent.completed":{const g=typeof w?.resultSummary=="string"?w.resultSummary:void 0,x=Ku(t,k,m,w?.subagentId,{subagentPhase:"completed",status:"completed",completedAt:new Date().toISOString(),outputPreview:g});x&&b.push({type:"taskCreated",sessionId:m,task:x}),b.push({type:"taskCompleted",sessionId:m,taskId:w?.subagentId??"",status:"completed",outputPreview:g});break}case"subagent.failed":{const g=typeof w?.error=="string"?w.error:void 0,x=Ku(t,k,m,w?.subagentId,{subagentPhase:"failed",status:"failed",completedAt:new Date().toISOString(),outputPreview:g});x&&b.push({type:"taskCreated",sessionId:m,task:x}),b.push({type:"taskCompleted",sessionId:m,taskId:w?.subagentId??"",status:"failed",outputPreview:g});break}case"error":{b.push({type:"unknown",raw:{_agentError:!0,code:w?.code,message:w?.message,name:w?.name,details:w?.details,retryable:w?.retryable}});break}case"task.notified":{const g=_o(w??{},"notificationType"),x=_o(w??{},"sourceKind"),S=_o(w??{},"sourceId");if(!g||!x||!S)break;const T=g.startsWith("task.")?g.slice(5):g,A=`task:${S}:${T}`,E=H=>H.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),P=_o(w??{},"title")??"",D=_o(w??{},"severity")??"",I=_o(w??{},"body")??"",$=`<notification id="${A}" category="task" type="${E(g)}" source_kind="${E(x)}" source_id="${E(S)}"> +`+(P!==""?`Title: ${E(P)} +`:"")+(D!==""?`Severity: ${E(D)} +`:"")+(I!==""?`${E(I)} +`:"")+"</notification>",B={id:`task_ntf_${A}`,sessionId:m,role:"user",content:[{type:"text",text:$}],createdAt:new Date().toISOString(),metadata:{origin:{kind:"task",taskId:S,status:T,notificationId:A}}};k.messages.push(B),b.push({type:"messageCreated",message:$u(B)});break}case"warning":{b.push({type:"unknown",raw:{_agentWarning:!0,message:w?.message}});break}case"task.started":case"background.task.started":{const g=w?.info??{},x=typeof g.startedAt=="number"?new Date(g.startedAt).toISOString():void 0,S=typeof g.taskId=="string"?g.taskId:typeof g.taskId=="number"?String(g.taskId):pl("task_"),T=typeof g.description=="string"?g.description:typeof g.command=="string"?g.command:t("tasks.defaultDescription");if(g.kind==="agent"){const E=typeof g.agentId=="string"&&g.agentId.length>0?g.agentId:void 0;if(E!==void 0){const P=Ku(t,k,m,E,{description:T,backgroundTaskId:S,runInBackground:!0});P&&b.push({type:"taskCreated",sessionId:m,task:P})}else b.push({type:"taskCreated",sessionId:m,task:{id:S,sessionId:m,kind:"subagent",description:T,status:"running",createdAt:x??new Date().toISOString(),startedAt:x,subagentPhase:"queued",runInBackground:!0}});break}const A=typeof g.command=="string"?g.command:void 0;b.push({type:"taskCreated",sessionId:m,task:{id:S,sessionId:m,kind:"bash",description:T,command:A,status:"running",createdAt:x??new Date().toISOString(),startedAt:x,outputPreview:A!==void 0?`$ ${A}`:void 0}});break}case"task.terminated":case"background.task.terminated":{const g=w?.info??{},x=g.status==="failed"||typeof g.exitCode=="number"&&g.exitCode!==0;b.push({type:"taskCompleted",sessionId:m,taskId:typeof g.taskId=="string"?g.taskId:typeof g.taskId=="number"?String(g.taskId):"",status:x?"failed":"completed"});break}case"compaction.completed":{const g=w?.result??{};b.push({type:"compactionCompleted",sessionId:m,tokensBefore:typeof g.tokensBefore=="number"?g.tokensBefore:void 0,tokensAfter:typeof g.tokensAfter=="number"?g.tokensAfter:void 0,summary:typeof g.summary=="string"?g.summary:void 0}),b.push({type:"historyCompacted",sessionId:m,beforeSeq:0,reason:"auto_compact"});break}case"compaction.started":{b.push({type:"compactionStarted",sessionId:m,trigger:w?.trigger==="manual"?"manual":"auto",instruction:typeof w?.instruction=="string"?w.instruction:void 0});break}case"compaction.cancelled":{b.push({type:"compactionCancelled",sessionId:m});break}case"goal.updated":{const g=jG(w?.snapshot??null);b.push({type:"goalUpdated",sessionId:m,goal:g?.status==="complete"?null:g});break}case"cron.fired":{const g=w?.origin,x=_o(w??{},"prompt");if(g&&typeof g=="object"&&g.kind==="cron_job"&&x){const S={id:pl("cron_"),sessionId:m,role:"user",content:[{type:"text",text:x}],createdAt:new Date().toISOString(),metadata:{origin:g}};k.messages.push(S),b.push({type:"messageCreated",message:$u(S)})}break}}return b}return{project:u,bindNextPromptId:l,seedInFlight:a,reset:i,markSideChannelAgent:r}}function eY(e){return new MG({origin:e.origin,identity:e.identity,tracer:e.tracer,credentialStore:e.credentialStore,projectorFactory:()=>QG({t:e.t}),mainAgentOnly:e.mainAgentOnly})}const PT="kimiWeb.compaction",tY={t:e=>e},nY="kimiWeb.optimisticUserMessage",_b="Sub Agent";function yf(e,t,n=e.length){for(let o=0;o<n;o++){const s=e[o];s.type==="thinking"&&s.startedAt!==void 0&&s.durationMs===void 0&&(e[o]={...s,durationMs:Math.max(0,t-Date.parse(s.startedAt))})}}function xb(e,t,n){const o=e.messagesBySession[t];if(o)for(let s=o.length-1;s>=0;s--){const i=o[s];if(i.role!=="assistant")continue;if(!i.content.some(u=>u.type==="thinking"&&u.startedAt!==void 0&&u.durationMs===void 0))return;const l=[...i.content];yf(l,n);const a=[...o];a[s]={...i,content:l},e.messagesBySession[t]=a;return}}function Sb(e){const t=Date.parse(e);return Number.isNaN(t)?Date.now():t}function oY(){return{sessions:[],activeSessionId:void 0,messagesBySession:{},approvalsBySession:{},planReviewByToolCallId:{},questionsBySession:{},tasksBySession:{},goalBySession:{},goalVersionBySession:{},lastSeqBySession:{},turnActiveBySession:{},turnEndedPromptIdBySession:{},turnErrorBySession:{},turnRetryBySession:{},compactionBySession:{},warnings:[]}}function sY(e){return{...e,sessions:e.sessions,messagesBySession:{...e.messagesBySession},approvalsBySession:{...e.approvalsBySession},planReviewByToolCallId:{...e.planReviewByToolCallId},questionsBySession:{...e.questionsBySession},tasksBySession:{...e.tasksBySession},goalBySession:{...e.goalBySession},goalVersionBySession:{...e.goalVersionBySession},lastSeqBySession:{...e.lastSeqBySession},turnActiveBySession:{...e.turnActiveBySession},turnEndedPromptIdBySession:{...e.turnEndedPromptIdBySession},turnErrorBySession:{...e.turnErrorBySession},turnRetryBySession:{...e.turnRetryBySession},compactionBySession:{...e.compactionBySession},warnings:[...e.warnings]}}function iY(e,t,n){if(t!==void 0&&n!==void 0&&n>0){const o=e.lastSeqBySession[t]??0;n>o&&(e.lastSeqBySession[t]=n)}}function od(e,t){const n=new Date().toISOString();e.sessions=e.sessions.map(o=>o.id===t&&n>o.updatedAt?{...o,updatedAt:n}:o)}function Ca(e,t){return t.seq>(e.lastSeqBySession[t.sessionId]??0)}function Ab(e){return e.role==="user"&&e.metadata?.[nY]===!0}function rY(e){const t=e.metadata?.origin;return t?.kind==="cron_job"||t?.kind==="cron_missed"}function lY(e){return e.metadata?.origin?.kind==="system_trigger"}function aY(e,t){const n=t.userMessageId??t.id;for(let s=e.length-1;s>=0;s--){const i=e[s];if(Ab(i)&&i.userMessageId===n)return s}const o=t.promptId;if(o!==void 0)for(let s=e.length-1;s>=0;s--){const i=e[s];if(Ab(i)&&i.promptId===o)return s}return-1}function uY(e,t,n){let o=!1;const s=e.map(i=>{let r=!1;const l=i.content.map(a=>a.type!=="toolUse"||a.toolCallId!==t?a:(r=!0,{...a,outputLines:[...a.outputLines??[],n]}));return r?(o=!0,{...i,content:l}):i});return o?s:e}const cY={"provider.connection_error":"connection","provider.auth_error":"auth","provider.rate_limit":"rateLimit","provider.overloaded":"overloaded","provider.filtered":"filtered","provider.api_error":"api","context.overflow":"contextOverflow"};function dY(e,t){const n=[],o=(r,l)=>{typeof l=="number"||typeof l=="boolean"?n.push({label:r,value:String(l)}):typeof l=="string"&&l.length>0&&n.push({label:r,value:l})};o(t("warnings.details.code"),e.code);const s=e.details??{};o(t("warnings.details.status"),s.statusCode),o(t("warnings.details.requestId"),s.requestId),o(t("warnings.details.errorName"),e.name);for(const[r,l]of Object.entries(s))r==="statusCode"||r==="requestId"||o(r,l);const i=(e.code!==void 0?cY[e.code]:void 0)??"title";return{severity:"error",title:t(`warnings.agentError.${i}`),message:e.message,details:n.length>0?n:void 0}}function fY(e,t,n,o=tY){const s=sY(e);switch(iY(s,n.sessionId,n.seq),t.type){case"sessionCreated":{s.sessions.some(r=>r.id===t.session.id)||(s.sessions=[t.session,...s.sessions]);break}case"sessionUpdated":{s.sessions=s.sessions.map(i=>i.id===t.session.id?{...t.session,pullRequest:i.pullRequest}:i);break}case"sessionDeleted":{const i=t.sessionId;s.sessions=s.sessions.filter(r=>r.id!==i),delete s.messagesBySession[i],delete s.tasksBySession[i],delete s.goalBySession[i],delete s.approvalsBySession[i],delete s.questionsBySession[i],delete s.lastSeqBySession[i],delete s.turnActiveBySession[i],delete s.turnEndedPromptIdBySession[i],delete s.turnErrorBySession[i],delete s.turnRetryBySession[i],s.activeSessionId===i&&(s.activeSessionId=void 0);break}case"sessionWorkChanged":{if(!Ca(e,n))break;let i;s.sessions=s.sessions.map(r=>r.id!==t.sessionId?r:(i=t.pendingInteraction??(t.busy?r.pendingInteraction:"none"),{...r,busy:t.busy,mainTurnActive:t.mainTurnActive??(t.busy?r.mainTurnActive:!1),pendingInteraction:i,lastTurnReason:t.lastTurnReason})),i==="none"?(delete s.approvalsBySession[t.sessionId],delete s.questionsBySession[t.sessionId]):i==="question"&&delete s.approvalsBySession[t.sessionId],t.mainTurnActive===!0?s.turnActiveBySession[t.sessionId]=!0:(t.mainTurnActive===!1||!t.busy)&&(e.turnActiveBySession[t.sessionId]&&od(s,t.sessionId),delete s.turnActiveBySession[t.sessionId],delete s.turnRetryBySession[t.sessionId]);break}case"sessionMetaUpdated":{s.sessions=s.sessions.map(i=>i.id===t.sessionId?{...i,title:t.title??i.title,lastPrompt:t.lastPrompt??i.lastPrompt}:i);break}case"sessionUsageUpdated":{s.sessions=s.sessions.map(i=>{if(i.id!==t.sessionId)return i;const r=t.model&&t.model.length>0?t.model:i.model;return{...i,usage:t.usage,model:r}});break}case"historyCompacted":break;case"compactionStarted":{s.compactionBySession={...s.compactionBySession,[t.sessionId]:{status:"running",trigger:t.trigger}};break}case"compactionCompleted":{const i=t.sessionId,r=s.compactionBySession[i],{[i]:l,...a}=s.compactionBySession;if(s.compactionBySession=a,Object.prototype.hasOwnProperty.call(s.messagesBySession,i)){const u=s.messagesBySession[i]??[],c=`compaction_${i}_${n.seq}`;if(!u.some(d=>d.id===c)){const d={trigger:r?.trigger??"auto",tokensBefore:t.tokensBefore,tokensAfter:t.tokensAfter};s.messagesBySession[i]=[...u,{id:c,sessionId:i,role:"assistant",content:t.summary?[{type:"text",text:t.summary}]:[],createdAt:new Date().toISOString(),metadata:{origin:{kind:"compaction_summary"},[PT]:d}}]}}break}case"compactionCancelled":{const{[t.sessionId]:i,...r}=s.compactionBySession;s.compactionBySession=r;break}case"messageCreated":{const i=t.message.sessionId,r=s.messagesBySession[i]??[];if(!r.some(a=>a.id===t.message.id)){if(t.message.role==="user"&&!rY(t.message)&&!lY(t.message)){const a=aY(r,t.message);if(a!==-1){const u=[...r],c=u[a];u[a]={...t.message,id:c.id,promptId:t.message.promptId??c.promptId,userMessageId:t.message.userMessageId??t.message.id,metadata:{...t.message.metadata,...c.metadata}},s.messagesBySession[i]=u;break}}s.messagesBySession[i]=[...r,t.message]}break}case"messageUpdated":{const i=t.sessionId,r=s.messagesBySession[i]??[];s.messagesBySession[i]=r.map(l=>{if(l.id!==t.messageId)return l;const a=t.content.map((c,d)=>{const f=l.content[d];return c.type==="thinking"&&f?.type==="thinking"?{...c,startedAt:f.startedAt,durationMs:f.durationMs}:c}),u=Date.now();return yf(a,u,a.length-1),(t.status!=="pending"||t.durationMs!==void 0)&&yf(a,u),{...l,content:a,durationMs:t.durationMs??l.durationMs}});break}case"assistantDelta":{const i=t.sessionId,r=s.messagesBySession[i]??[];s.messagesBySession[i]=r.map(l=>{if(l.id!==t.messageId)return l;const a=[...l.content],u=t.contentIndex,c=a.length<=u;for(;a.length<=u;)a.push({type:"text",text:""});const d=a[u];let f;return t.delta.text!==void 0?d.type==="text"&&!c?f={type:"text",text:d.text+t.delta.text}:(f={type:"text",text:t.delta.text},yf(a,Date.now(),u)):t.delta.thinking!==void 0?d.type==="thinking"?f={type:"thinking",thinking:d.thinking+t.delta.thinking,signature:d.signature,startedAt:d.startedAt,durationMs:d.durationMs}:(f={type:"thinking",thinking:t.delta.thinking,startedAt:new Date().toISOString()},yf(a,Date.now(),u)):f=d,a[u]=f,{...l,content:a}});break}case"toolOutput":{const i=t.sessionId,r=s.messagesBySession[i]??[];s.messagesBySession[i]=uY(r,t.toolCallId,t.outputChunk);break}case"approvalRequested":{const i=t.sessionId,r=s.approvalsBySession[i]??[];r.some(u=>u.approvalId===t.approval.approvalId)||(s.approvalsBySession[i]=[...r,t.approval],Ca(e,n)&&(xb(s,i,Sb(t.approval.createdAt)),od(s,i)));const a=t.approval.display;a?.kind==="plan_review"&&typeof a.plan=="string"&&a.plan.length>0&&(s.planReviewByToolCallId={...s.planReviewByToolCallId,[t.approval.toolCallId]:{plan:a.plan,path:typeof a.path=="string"?a.path:void 0}});break}case"approvalResolved":case"approvalExpired":{const i=t.sessionId,r=t.approvalId,l=s.approvalsBySession[i]??[];s.approvalsBySession[i]=l.filter(a=>a.approvalId!==r);break}case"questionRequested":{const i=t.sessionId,r=s.questionsBySession[i]??[];r.some(a=>a.questionId===t.question.questionId)||(s.questionsBySession[i]=[...r,t.question],Ca(e,n)&&(xb(s,i,Sb(t.question.createdAt)),od(s,i)));break}case"questionAnswered":case"questionDismissed":{const i=t.sessionId,r=t.questionId,l=s.questionsBySession[i]??[];s.questionsBySession[i]=l.filter(a=>a.questionId!==r);break}case"taskCreated":{const i=t.sessionId,r=s.tasksBySession[i]??[],l=r.findIndex(a=>a.id===t.task.id);if(l===-1)s.tasksBySession[i]=[...r,t.task];else{const a=[...r],u=r[l];a[l]={...t.task,outputLines:u.outputLines,text:u.text,description:t.task.description===_b&&u.description!==_b?u.description:t.task.description,swarmIndex:t.task.swarmIndex??u.swarmIndex,parentToolCallId:t.task.parentToolCallId??u.parentToolCallId,subagentType:t.task.subagentType??u.subagentType,model:t.task.model??u.model,thinkingEffort:t.task.thinkingEffort??u.thinkingEffort,runInBackground:t.task.runInBackground??u.runInBackground,backgroundTaskId:t.task.backgroundTaskId??u.backgroundTaskId,agentId:t.task.agentId??u.agentId},s.tasksBySession[i]=a}break}case"taskProgress":{const i=t.sessionId,r=s.tasksBySession[i]??[];s.tasksBySession[i]=r.map(l=>{if(l.id!==t.taskId)return l;if(l.kind==="subagent"&&t.kind==="text")return{...l,text:(l.text??"")+t.outputChunk};const a=l.outputLines??[];if(a.at(-1)===t.outputChunk)return l;const u=[...a,t.outputChunk];return{...l,outputLines:l.kind==="subagent"?u:u.slice(-40)}});break}case"taskCompleted":{const i=t.sessionId,r=s.tasksBySession[i]??[];s.tasksBySession[i]=r.map(l=>l.id!==t.taskId?l:{...l,status:t.status,outputPreview:t.outputPreview,outputBytes:t.outputBytes});break}case"goalUpdated":{const i=t.sessionId;s.goalVersionBySession[i]=(s.goalVersionBySession[i]??0)+1,t.goal===null||t.goal.status==="complete"?delete s.goalBySession[i]:s.goalBySession[i]=t.goal;break}case"configChanged":{s.config=t.config;break}case"modelCatalogChanged":break;case"agentDelta":case"agentTurnEnded":break;case"promptCompleted":{t.reason==="blocked"&&Ca(e,n)&&od(s,t.sessionId);break}case"promptAborted":{if(t.promptId===e.turnEndedPromptIdBySession[t.sessionId])break;Ca(e,n)&&od(s,t.sessionId);break}case"turnActiveChanged":{if(!Ca(e,n))break;s.sessions=s.sessions.map(i=>i.id===t.sessionId?{...i,mainTurnActive:t.active}:i),t.active?(s.turnActiveBySession[t.sessionId]=!0,delete s.turnEndedPromptIdBySession[t.sessionId],delete s.turnErrorBySession[t.sessionId],delete s.turnRetryBySession[t.sessionId]):(delete s.turnActiveBySession[t.sessionId],delete s.turnRetryBySession[t.sessionId],t.promptId!==void 0&&(s.turnEndedPromptIdBySession[t.sessionId]=t.promptId),od(s,t.sessionId));break}case"turnRetry":{if(!Ca(e,n))break;t.retry===void 0?delete s.turnRetryBySession[t.sessionId]:s.turnRetryBySession[t.sessionId]=t.retry;break}case"unknown":{const i=t.raw;if(!(i&&i._noop===!0))if(i&&i._agentError){if(Ca(e,n)){if(n.sessionId!==void 0){const r=i.details??{};s.turnErrorBySession[n.sessionId]={code:i.code,message:i.message,name:i.name,retryable:i.retryable,statusCode:typeof r.statusCode=="number"?r.statusCode:void 0,requestId:typeof r.requestId=="string"?r.requestId:void 0}}(n.sessionId===void 0||n.sessionId!==e.activeSessionId)&&(s.warnings=[...s.warnings,dY(i,o.t)])}}else if(i&&i._agentWarning){const r=i.message??i.code??o.t("warnings.agentWarningFallback");s.warnings=[...s.warnings,`${o.t("warnings.noteLabel")}: ${r}`]}else{const r=i?.type??"(unknown)";s.warnings=[...s.warnings,o.t("warnings.unhandledEvent",{type:r})]}break}}return s}function pY(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function Ni(e,t){for(const n of Object.keys(t))Object.is(e[n],t[n])||(e[n]=t[n]);for(const n of Object.keys(e))n in t||delete e[n]}const hY=[{pattern:/\brm\s+(?:-[a-zA-Z]*[rf][a-zA-Z]*|--recursive|--force)\b/,detail:"rm -rf"},{pattern:/\bsudo\b/,detail:"sudo"},{pattern:/\bmkfs(?:\.[a-z0-9]+)?\b/,detail:"mkfs"},{pattern:/\bdd\b[^|;&]*\bof=/,detail:"dd of=…"},{pattern:/>\s*\/dev\/(?:sd|nvme|disk|hd)/,detail:"> /dev/…"},{pattern:/:\(\)\s*\{/,detail:"fork bomb"},{pattern:/\bgit\s+push\b[^|;&]*(?:--force(?:-with-lease)?\b|\s-f\b)/,detail:"git push --force"},{pattern:/\bchmod\s+(?:-[a-zA-Z]+\s+)*777\b/,detail:"chmod 777"},{pattern:/\b(?:curl|wget)\b[^|;&]*\|\s*(?:sudo\s+)?(?:ba|z)?sh\b/,detail:"curl | sh"},{pattern:/\b(?:shutdown|reboot|poweroff|halt)\b/,detail:"shutdown / reboot"}];function DT(e){const t=e.replace(/"[^"]*"|'[^']*'/g," ");for(const{pattern:n,detail:o}of hY)if(n.test(t))return o}const BT="kimiWeb.taskNotification",mY=/<notification\b([^>]*)>([\s\S]*?)<\/notification>/g,gY=/([\w-]+)="([^"]*)"/g,vY=/<output-file\b([^>]*)>[\s\S]*?<\/output-file>/,yY=/^Title: (.*)$/m,kY=/^Severity: (.*)$/m;function c3(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function Mb(e){const t={};for(const n of e.matchAll(gY))n[1]!==void 0&&n[2]!==void 0&&(t[n[1]]=c3(n[2]));return t}function bY(e,t,n){const o=Mb(e),s=yY.exec(t)?.[1]?.trim()??"",i=kY.exec(t)?.[1]?.trim()??"";let r=t.split(` +`).filter(c=>!c.startsWith("Title: ")&&!c.startsWith("Severity: ")).join(` +`);const l=r.search(/^<\w/m);l!==-1&&(r=r.slice(0,l)),r=r.trim();const a=vY.exec(t),u=a?(()=>{const c=Mb(a[1]??""),d=Number(c.bytes);return c.path!==void 0&&c.path!==""?{path:c.path,bytes:Number.isFinite(d)?d:void 0}:void 0})():void 0;return{id:o.id??"",category:o.category??"",type:o.type??"",sourceKind:o.source_kind??"",sourceId:o.source_id??"",agentId:o.agent_id,title:c3(s),severity:i,body:c3(r),outputFile:u,raw:n}}function CY(e){if(!e.includes("<notification"))return[];const t=[];for(const n of e.matchAll(mY))n[1]===void 0||n[2]===void 0||t.push(bY(n[1],n[2],n[0]));return t}function wY(e){const t=e?.[BT];if(typeof t!="object"||t===null)return;const n=t;for(const o of["id","category","type","sourceKind","sourceId","title","severity","body","raw"])if(typeof n[o]!="string")return;return t}function zh(e){for(const t of["completed","failed","timed_out","killed","lost"])if(e.type.endsWith(`.${t}`))return t;return"info"}function _Y(e){const t=zh(e);return t==="completed"?"ok":t==="failed"||t==="timed_out"||t==="lost"?"err":t==="killed"?"warn":e.severity==="error"?"err":e.severity==="warning"?"warn":"info"}const xY=1e6,Tb=5e3;function Sl(e){return e===""?[]:e.endsWith(` +`)?e.slice(0,-1).split(` +`):e.split(` +`)}function r1(e,t){const n=Sl(e),o=Sl(t),s=n.length,i=o.length;if(s===0&&i===0)return[];if(s>Tb||i>Tb||(s+1)*(i+1)>xY)return null;const r=Array.from({length:s+1},()=>Array.from({length:i+1},()=>0));for(let h=1;h<=s;h++)for(let m=1;m<=i;m++)r[h][m]=n[h-1]===o[m-1]?r[h-1][m-1]+1:Math.max(r[h-1][m],r[h][m-1]);const l=[];let a=s,u=i;for(;a>0||u>0;)a>0&&u>0&&n[a-1]===o[u-1]?(l.push({type:"context",text:n[a-1]}),a--,u--):u>0&&(a===0||r[a][u-1]>=r[a-1][u])?(l.push({type:"add",text:o[u-1]}),u--):(l.push({type:"del",text:n[a-1]}),a--);l.reverse();const c=[];let d=1,f=1;for(const h of l)h.type==="context"?(c.push({type:"context",text:h.text,oldNo:d,newNo:f}),d++,f++):h.type==="add"?(c.push({type:"add",text:h.text,newNo:f}),f++):(c.push({type:"del",text:h.text,oldNo:d}),d++);return c}const Eb=500;function Pm(e,t){const n=[],o=Sl(e),s=Sl(t),i=Math.min(o.length,Eb),r=Math.min(s.length,Eb);for(let l=1;l<=i;l++)n.push({type:"del",text:o[l-1],oldNo:l});o.length>i&&n.push({type:"context",text:`… ${o.length-i} more lines …`});for(let l=1;l<=r;l++)n.push({type:"add",text:s[l-1],newNo:l});return s.length>r&&n.push({type:"context",text:`… ${s.length-r} more lines …`}),n}function HT(e){let t=0,n=0;for(const o of e)o.type==="add"?t++:o.type==="del"&&n++;return{added:t,removed:n}}const SY=/^read[_-]?media(?:file)?$/i,AY=/^data:([^;]+);base64,(.*)$/s,MY=/^<(image|video|audio)\s+path="([^"]+)">$/,TY=/^<(image|video|audio)\s+path="([^"]+)">(?:<\/\1>)?$/,EY=/Mime type:\s*([^.\s]+)/i,IY=/Size:\s*(\d+)\s*bytes/i,LY=/Original dimensions:\s*(\d+)x(\d+)\s*pixels/i,$Y="<system>Image compressed to fit model limits:",NY=/<system>Image compressed to fit model limits:[\s\S]*?<\/system>/g;function FY(e){return e.includes($Y)?e.replace(NY,""):e}function RY(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function Ib(e){const t=TY.exec(e.trim());return t?{kind:t[1],path:RY(t[2])}:null}const zT=/^f_(?:[0-9A-Za-z]{26}|[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})$/,OY=/^f_(?:[0-9A-Za-z]{26}|[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})(?=-)/;function d3(e){const t=e.split(/[\\/]/).at(-1)??"",n=t.lastIndexOf("."),o=n>0?t.slice(0,n):t;return zT.test(o)?o:void 0}const PY=/^Attached file "(.+)" \(([^,]+), (\d+) bytes\): (.+) — open it with the Read tool$/;function Lb(e){const t=PY.exec(e.trim());if(!t)return null;const n=(t[4]??"").split(/[\\/]/).at(-1)??"",o=OY.exec(n)?.[0];return{name:t[1],mediaType:t[2],size:Number(t[3]),fileId:o!==void 0&&zT.test(o)?o:void 0}}function DY(e){if(e.length===0)return 0;const t=e.endsWith("==")?2:e.endsWith("=")?1:0;return Math.floor(e.length*3/4)-t}function BY(e){if(Array.isArray(e))return e;if(typeof e!="string")return null;try{const t=JSON.parse(e);return Array.isArray(t)?t:null}catch{return null}}function HY(e){const t=e.type,n=t==="image_url"?"image":t==="video_url"?"video":t==="audio_url"?"audio":null;if(n===null)return null;const s=e[n==="image"?"imageUrl":n==="video"?"videoUrl":"audioUrl"];if(typeof s!="object"||s===null)return null;const i=s.url;return typeof i=="string"?{kind:n,url:i}:null}function zY(e,t){if(!SY.test(e))return;const n=BY(t);if(n===null)return;let o,s,i,r,l,a=null;for(const c of n){if(typeof c!="object"||c===null)continue;const d=c;if(d.type==="text"&&typeof d.text=="string"){const h=d.text,m=MY.exec(h);m&&(s=m[1],o=m[2]);const v=EY.exec(h);v?.[1]&&(i=v[1]);const k=IY.exec(h);k?.[1]&&(r=Number(k[1]));const w=LY.exec(h);w?.[1]&&w[2]&&(l=`${w[1]}x${w[2]}`);continue}const f=HY(d);f&&(a=f)}if(a===null)return;const u=AY.exec(a.url);return u?.[1]&&(i=u[1]),u?.[2]&&(r=DY(u[2])),{kind:a.kind??s??"image",url:a.url,path:o,fileId:a.url.startsWith("ms://")&&o!==void 0?d3(o):void 0,mimeType:i,bytes:Number.isFinite(r)?r:void 0,dimensions:l}}function WT(e){if(e!=null){if(typeof e=="string")return e.split(` +`);if(Array.isArray(e)){const t=[];for(const n of e)if(typeof n=="string")t.push(...n.split(` +`));else if(n&&typeof n=="object"){const o=n;o.type==="text"&&typeof o.text=="string"?t.push(...o.text.split(` +`)):o.type==="think"&&typeof o.think=="string"?t.push(...o.think.split(` +`)):o.type==="image_url"||o.type==="image"?t.push("[image]"):typeof o.type=="string"?t.push(`[${o.type}]`):t.push(JSON.stringify(n))}return t.length>0?t:void 0}return[JSON.stringify(e)]}}function WY(e,t){if(Gs(e)==="task")for(const n of t??[]){const o=/^agent_id:\s*(\S+)\s*$/.exec(n);if(o?.[1])return o[1]}}function UY(e){return{id:e.agentId??e.id,toolCallId:e.parentToolCallId,name:e.description,subagentType:e.subagentType,model:e.model,thinkingEffort:e.thinkingEffort,phase:e.subagentPhase??(e.status==="completed"?"completed":e.status==="failed"?"failed":"working"),status:e.status,summary:e.outputPreview,outputLines:e.outputLines,text:e.text,suspendedReason:e.suspendedReason,swarmIndex:e.swarmIndex}}function jY(e){const t=e.display??{},n=typeof t.kind=="string"?t.kind:"";if(n==="diff"){const o=typeof t.path=="string"?t.path:"";if(Array.isArray(t.diff))return{kind:"diff",path:o,diff:t.diff};const s=typeof t.old_text=="string"?t.old_text:typeof t.before=="string"?t.before:void 0,i=typeof t.new_text=="string"?t.new_text:typeof t.after=="string"?t.after:void 0;if(s!==void 0&&i!==void 0){const r=r1(s,i)??Pm(s,i);return{kind:"diff",path:o,diff:r}}return{kind:"diff",path:o,diff:[]}}if(n==="file_io"){const o=typeof t.path=="string"?t.path:"",s=typeof t.operation=="string"?t.operation:"";if(s==="write"&&typeof t.content=="string")return{kind:"file",path:o,content:t.content};if(s==="edit"&&typeof t.before=="string"&&typeof t.after=="string"){const r=r1(t.before,t.after)??Pm(t.before,t.after);return{kind:"diff",path:o,diff:r}}const i=typeof t.detail=="string"?t.detail:void 0;return{kind:"fileop",op:s||n,path:o,detail:i}}if(n==="shell"||n==="command"){const o=typeof t.command=="string"?t.command:e.action;return{kind:"shell",command:o,cwd:typeof t.cwd=="string"?t.cwd:void 0,danger:typeof t.danger=="string"?t.danger:DT(o)}}if(n==="file_content"||n==="file")return{kind:"file",path:typeof t.path=="string"?t.path:"",content:typeof t.content=="string"?t.content:"",language:typeof t.language=="string"?t.language:void 0};if(n==="file_op"||n==="fileop")return{kind:"fileop",op:typeof t.operation=="string"?t.operation:typeof t.op=="string"?t.op:n,path:typeof t.path=="string"?t.path:"",detail:typeof t.detail=="string"?t.detail:void 0};if(n==="url_fetch"||n==="url")return{kind:"url",method:typeof t.method=="string"?t.method:void 0,url:typeof t.url=="string"?t.url:e.action};if(n==="search")return{kind:"search",query:typeof t.query=="string"?t.query:e.action,scope:typeof t.scope=="string"?t.scope:void 0};if(n==="invocation"||n==="agent_call"||n==="skill_call")return{kind:"invocation",kind2:typeof t.kind=="string"?t.kind:n,name:typeof t.name=="string"?t.name:e.toolName,description:typeof t.description=="string"?t.description:void 0};if(n==="todo"||n==="todo_list")return{kind:"todo",items:(Array.isArray(t.items)?t.items:[]).map(i=>{const r=i??{};return{title:typeof r.title=="string"?r.title:"",status:typeof r.status=="string"?r.status:"pending"}})};if(n==="plan_review"){const o=typeof t.plan=="string"?t.plan:"",s=typeof t.path=="string"?t.path:void 0,r=(Array.isArray(t.options)?t.options:[]).map(l=>{const a=l??{},u=typeof a.label=="string"?a.label:"";if(!u)return null;const c=typeof a.description=="string"?a.description:void 0;return{label:u,description:c}}).filter(l=>l!==null);return{kind:"plan_review",plan:o,path:s,options:r.length>0?r:void 0}}return{kind:"generic",summary:e.action}}function VY(e){const t=`<prompt> +`,n=` +</prompt>`,o=e.indexOf(t),s=e.lastIndexOf(n);return o>=0&&s>=o+t.length?e.slice(o+t.length,s):qY(e)}function qY(e){const t=e.split(` +`);return t.length>=2&&t[0]?.startsWith("<cron-fire ")&&t.at(-1)==="</cron-fire>"?t.slice(1,-1).join(` +`):e}function KY(e){const t=e.metadata?.origin;if(t?.kind==="cron_job"||t?.kind==="cron_missed")return t.kind}function ZY(e){const t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(` +`);return VY(t)}function GY(e,t){const n=e.metadata?.origin??{},o=ZY(e);return t==="cron_missed"?{text:o,cron:{missedCount:typeof n.count=="number"?n.count:void 0}}:{text:o,cron:{jobId:typeof n.jobId=="string"?n.jobId:void 0,cron:typeof n.cron=="string"?n.cron:void 0,recurring:typeof n.recurring=="boolean"?n.recurring:void 0,coalescedCount:typeof n.coalescedCount=="number"?n.coalescedCount:void 0,stale:typeof n.stale=="boolean"?n.stale:void 0}}}function YY(e,t,n){const{text:o,cron:s}=GY(e,n);return{id:e.id,role:"cron",no:t,text:o,createdAt:e.createdAt,cron:s}}function XY(e){const t=e.metadata?.origin,n=t?.kind;return n===void 0||n==="user"?!0:n==="skill_activation"||n==="plugin_command"?t?.trigger==="user-slash":!1}function JY(e){return e.metadata?.origin?.kind==="compaction_summary"}function QY(e,t){return e===null?!1:e.promptId===void 0||t===void 0||e.promptId===t}function eX(e){if(!e||e.length===0)return;const t="Plan saved to: ";for(const n of e)if(n.startsWith(t))return n.slice(t.length).trim()}function tX(e){const t=[];for(const n of e){const o=t.at(-1);n.type==="text"&&o?.type==="text"?o.text+=n.text:n.type==="thinking"&&o?.type==="thinking"?o.thinking+=n.thinking:n.type==="thinking"?t.push({type:"thinking",thinking:n.thinking}):t.push({...n})}return JSON.stringify(t)}function UT(e,t,n,o=!0,s={},i={},r){const l=[];let a=r?.startNo??1;const u=r?.collect,c=new Map;for(const v of t)c.set(v.toolCallId,v);let d=null;function f(v=!1){if(!d)return;const k=d;if(d=null,!v&&k.blocks.length===0&&k.textParts.length===0&&k.thinkingParts.length===0&&k.tools.length===0)return;if(!v||!o)for(let b=0;b<k.tools.length;b++){const _=k.tools[b];if(_.status!=="running")continue;const g={..._,status:"ok"};k.tools[b]=g;const x=k.blocks.find(S=>S.kind==="tool"&&S.tool.id===g.id);x&&x.kind==="tool"&&(x.tool=g)}const w={id:k.id,role:"assistant",no:a++,text:k.textParts.join(` +`),thinking:k.thinkingParts.length>0?k.thinkingParts.join(` +`):void 0,tools:k.tools.length>0?k.tools:void 0,blocks:k.blocks.length>0?k.blocks:void 0,approval:k.approval,approvalId:k.approvalId,durationMs:k.durationMs,createdAt:k.createdAt,endedAt:k.endedAt,goalContinuation:k.goalContinuation};l.push(w),u?.(w,k.sources)}function h(v,k){let w=null;for(const b of k)if(b.type==="text"){if(b.text){w==="text"?v.textParts[v.textParts.length-1]+=b.text:v.textParts.push(b.text);const _=v.blocks.at(-1);_&&_.kind==="text"?_.text+=(w==="text"?"":` +`)+b.text:v.blocks.push({kind:"text",text:b.text}),w="text"}}else if(b.type==="thinking"){if(b.thinking){w==="thinking"?v.thinkingParts[v.thinkingParts.length-1]+=b.thinking:v.thinkingParts.push(b.thinking);const _=v.blocks.at(-1);if(_&&_.kind==="thinking"){_.thinking+=(w==="thinking"?"":` +`)+b.thinking;const g=[_.startedAt,b.startedAt].filter(T=>T!==void 0).sort()[0],x=_.startedAt!==void 0&&_.durationMs===void 0||b.startedAt!==void 0&&b.durationMs===void 0,S=[_,b].flatMap(T=>T.startedAt!==void 0&&T.durationMs!==void 0?[Date.parse(T.startedAt)+T.durationMs]:[]);_.startedAt=g,_.durationMs=!x&&g!==void 0&&S.length>0?Math.max(...S)-Date.parse(g):void 0}else v.blocks.push({kind:"thinking",thinking:b.thinking,startedAt:b.startedAt,durationMs:b.durationMs});w="thinking"}}else if(b.type==="toolUse"){w=null;const _=c.get(b.toolCallId),g=b.toolName==="ExitPlanMode"?i[b.toolCallId]:void 0,x={id:b.toolCallId,name:b.toolName,arg:typeof b.input=="string"?b.input:JSON.stringify(b.input),agentId:Gs(b.toolName)==="task"?b.agentRefs?.find(S=>S.role!=="member")?.agentId??b.agentRefs?.[0]?.agentId:void 0,status:"running",output:b.outputLines,plan:g,planPath:b.toolName==="ExitPlanMode"?g?.path??s[b.toolCallId]?.path:void 0};v.tools.push(x),v.blocks.push({kind:"tool",tool:x}),_&&(v.approval=jY(_),v.approvalId=_.approvalId)}else if(b.type==="toolResult"){w=null;const _=v.tools.findIndex(g=>g.id===b.toolCallId);if(_!==-1){const g=v.tools[_],x=WT(b.output),S={...g,status:b.isError?"error":"ok",output:x,media:b.isError?void 0:zY(g.name,b.output),agentId:g.agentId??WY(g.name,x)};S.name==="ExitPlanMode"&&!S.planPath&&(S.planPath=eX(S.output)),v.tools[_]=S;const T=v.blocks.find(A=>A.kind==="tool"&&A.tool.id===b.toolCallId);T&&T.kind==="tool"&&(T.tool=S)}}else w=null}function m(v){if(v.type==="image"||v.type==="video"){const k=v.type,w=v.source;if(w.kind==="url")return{url:w.url,kind:k};if(w.kind==="base64")return{url:`data:${w.mediaType};base64,${w.data}`,kind:k};if(w.kind==="file"&&n)return{url:n(w.fileId),kind:k,fileId:w.fileId}}if(v.type==="file"&&n){if(v.mediaType.startsWith("image/"))return{url:n(v.fileId),kind:"image",fileId:v.fileId};if(v.mediaType.startsWith("video/"))return{url:n(v.fileId),kind:"video",fileId:v.fileId}}}for(const v of e){if(v.role==="system")continue;if(JY(v)){f();const g=v.metadata?.[PT],x={id:v.id,role:"compaction",no:a,text:v.content.filter(S=>S.type==="text").map(S=>S.text).join(` +`),compaction:{trigger:g?.trigger,tokensBefore:g?.tokensBefore,tokensAfter:g?.tokensAfter}};l.push(x),u?.(x,[v]);continue}if(v.role==="user"){const g=KY(v),x=v.metadata?.origin?.kind,S=x==="skill_activation"&&v.metadata?.origin?.trigger!=="user-slash";if(g===void 0&&(x==="injection"||S))continue;if(g===void 0&&(x==="task"||x==="background_task"||x==="task_notification")){const $=v.content.filter(O=>O.type==="text").map(O=>O.text).join(` +`),B=wY(v.metadata),H=B!==void 0?[B]:CY($);if(H.length>0){d??={id:v.id,promptId:void 0,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[v],createdAt:v.createdAt};for(const O of H)d.blocks.push({kind:"notification",notification:{...O,createdAt:v.createdAt}})}continue}if(f(),g!==void 0){const $=YY(v,a++,g);l.push($),u?.($,[v]);continue}if(x==="system_trigger"&&v.metadata?.origin?.name==="goal_continuation"){d={id:v.id,promptId:void 0,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[v],createdAt:v.createdAt,goalContinuation:!0};continue}if(!XY(v))continue;const T=v.metadata?.origin,A=T?.kind==="skill_activation"&&T?.trigger==="user-slash",E=T?.kind==="plugin_command"&&T?.trigger==="user-slash",P=[],D=[];for(const $ of v.content){if($.type==="text")if(A){const H=Ib($.text);if(H&&(H.kind==="video"||H.kind==="image")&&n){const F=d3(H.path);if(F){D.push({url:n(F),kind:H.kind,fileId:F});continue}}const O=Lb($.text);O&&D.push({kind:"file",url:O.fileId&&n?n(O.fileId):"",fileId:O.fileId,name:O.name,mediaType:O.mediaType,size:O.size})}else if(E)P.push(T.commandArgs??"");else{const H=Ib($.text);if(H&&(H.kind==="video"||H.kind==="image")&&n){const U=d3(H.path);if(U){D.push({url:n(U),kind:H.kind,fileId:U});continue}}const O=Lb($.text);if(O){D.push({kind:"file",url:O.fileId&&n?n(O.fileId):"",fileId:O.fileId,name:O.name,mediaType:O.mediaType,size:O.size});continue}const F=FY($.text);if(F!==$.text&&F.trim().length===0)continue;P.push(F)}const B=m($);if(B){D.push({url:B.url,kind:B.kind,name:$.type==="file"?$.name:void 0,fileId:B.fileId});continue}$.type==="file"&&n&&D.push({kind:"file",url:n($.fileId),fileId:$.fileId,name:$.name,mediaType:$.mediaType||void 0,size:$.size})}const I={id:v.id,role:"user",no:a++,text:A?T?.skillArgs??"":P.join(` +`),attachments:D.length>0?D:void 0,skillActivation:A?{name:T.skillName,args:T.skillArgs}:void 0,pluginCommand:E?{pluginId:T.pluginId,commandName:T.commandName,args:T.commandArgs}:void 0,createdAt:v.createdAt};l.push(I),u?.(I,[v]);continue}if(v.role==="tool"){d&&(d.sources.push(v),h(d,v.content),d.endedAt=v.createdAt);continue}const k=v.promptId;QY(d,k)?d!==null&&d.promptId===void 0&&k!==void 0&&(d.promptId=k):(f(),d={id:v.id,promptId:k,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[],durationMs:v.durationMs,createdAt:v.createdAt});const b=d;if(b===null)continue;const _=tX(v.content);b.promptId!==void 0&&b.seenSigs.has(_)||(b.seenSigs.add(_),b.sources.push(v),v.durationMs!==void 0&&(b.durationMs=v.durationMs),h(b,v.content),v.id!==b.id&&(b.endedAt=v.createdAt))}return f(!0),l}function nX(e,t,n){const o=e.items.filter(u=>u.kind==="turn"),s=o[0]?.turnId,i=o.length===1?s:void 0,r=new Map(e.tasks.map(u=>[u.taskId,u])),l=e.items.flatMap(u=>u.kind==="turn"?oX(u,e.attachments,r,u.turnId===s?n?.createdAt:void 0,u.turnId===i?n?.disposedAt:void 0):[]),a=e.meta.activity==="turn";return UT(l,[],t,a).map(iX)}function oX(e,t,n,o,s){const i=[],r=new Map(t.map(d=>[d.attachmentId,d])),l=rX([e.startedAt,...e.steps.map(d=>d.startedAt),o])??"",a=$b(e.endedAt)??$b(s),u=e.turnId;if(e.prompt!==void 0&&e.prompt.length>0){const d=[{type:"text",text:e.prompt}];for(const f of e.attachmentIds??[]){const h=lX(r.get(f));h!==void 0&&d.push(h)}i.push({id:`${e.turnId}:input`,sessionId:"",role:"user",content:d,createdAt:l,promptId:u,metadata:e.origin.kind==="task"&&e.prompt.includes("<notification")?{origin:e.origin.payload??e.origin}:void 0})}for(const d of e.steps)for(const f of d.frames)if(f.kind==="text"){if(f.text.length===0)continue;if(f.role==="user"){if(f.taskId===void 0)continue;const h=sX(f.taskId,f.text,n.get(f.taskId));i.push({id:f.frameId,sessionId:"",role:"user",content:[{type:"text",text:f.text}],createdAt:d.startedAt??l,promptId:u,metadata:{origin:{kind:"task",taskId:f.taskId},[BT]:h}});continue}i.push({id:f.frameId,sessionId:"",role:"assistant",content:[{type:"text",text:f.text}],createdAt:d.startedAt??l,promptId:u})}else if(f.kind==="thinking"){if(f.text.length===0)continue;i.push({id:f.frameId,sessionId:"",role:"assistant",content:[{type:"thinking",thinking:f.text,startedAt:d.startedAt,durationMs:Nb(d.startedAt,d.endedAt)}],createdAt:d.startedAt??l,promptId:u})}else f.kind==="tool"&&(i.push({id:`${f.frameId}:call`,sessionId:"",role:"assistant",content:[{type:"toolUse",toolCallId:f.toolCallId,toolName:f.name,input:f.input??f.display??{},outputLines:f.state==="running"?WT(f.output):void 0,agentRefs:f.agentRefs}],createdAt:d.startedAt??l,promptId:u}),f.state!=="running"&&i.push({id:`${f.frameId}:result`,sessionId:"",role:"tool",content:[{type:"toolResult",toolCallId:f.toolCallId,output:f.output??f.error??"",isError:f.state==="error"}],createdAt:d.endedAt??d.startedAt??l,promptId:u}));const c=e.durationMs??Nb(l||void 0,a);if(c!==void 0){const d=i.findLastIndex(f=>f.role==="assistant");d>=0&&(i[d]={...i[d],durationMs:c})}return i}function sX(e,t,n){const[o="",...s]=t.split(` +`),i=n?.state??"info";return{id:`task:${e}:${i}`,category:"task",type:`task.${i}`,sourceKind:n?.kind==="subagent"?"subagent":"background_task",sourceId:e,agentId:n?.agentId,title:o.trim(),severity:i==="completed"?"info":"warning",body:s.join(` +`).trim(),raw:t}}function iX(e){if(e.createdAt!==""&&e.endedAt!=="")return e;const t={...e};return t.createdAt===""&&delete t.createdAt,t.endedAt===""&&delete t.endedAt,t}function rX(e){let t;for(const n of e){if(n===void 0)continue;const o=Date.parse(n);Number.isFinite(o)&&(t===void 0||o<t.time)&&(t={value:n,time:o})}return t?.value}function $b(e){return e!==void 0&&Number.isFinite(Date.parse(e))?e:void 0}function lX(e){if(e?.source!==void 0){if(e.mediaType.startsWith("image/"))return{type:"image",source:e.source.kind==="url"?{kind:"url",url:e.source.url}:{kind:"file",fileId:e.source.fileId}};if(e.mediaType.startsWith("video/"))return{type:"video",source:e.source.kind==="url"?{kind:"url",url:e.source.url}:{kind:"file",fileId:e.source.fileId}};if(e.source.kind==="file")return{type:"file",fileId:e.source.fileId,name:e.name??e.attachmentId,mediaType:e.mediaType,size:e.size??0}}}function Nb(e,t){if(e===void 0||t===void 0)return;const n=Date.parse(t)-Date.parse(e);return Number.isFinite(n)&&n>=0?n:void 0}const Fb=6e3,f3=256*1024,aX=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;function Rb(e,t){return t===0?e:e-1}function uX(e,t){const n=Sl(t),o=[];let s=0;for(const i of e){if(i.type==="hunk"){const r=aX.exec(i.text);if(!r)return null;const l=Rb(Number(r[1]),r[2]===void 0?1:Number(r[2])),a=Rb(Number(r[3]),r[4]===void 0?1:Number(r[4]));if(a<s||a>n.length)return null;for(;s<a;)o.push(n[s++]);if(o.length!==l)return null;continue}if(i.oldNo===void 0&&i.newNo===void 0)return null;if(i.type==="del"){o.push(i.text);continue}if(s>=n.length||n[s]!==i.text)return null;s++,i.type==="context"&&o.push(i.text)}for(;s<n.length;)o.push(n[s++]);return o.join(` +`)}async function cX(e,t){if(t.truncated||e.length===0)return null;const n=await t.readNewText()??"";if(n.length>f3||Sl(n).length>Fb)return null;const o=uX(e,n);return o===null||o.length>f3||Sl(o).length>Fb?null:{before:o,after:n}}const dX=new Set(["assistantDelta","agentDelta","toolOutput","taskProgress"]);function fX(e){return dX.has(e.type)}const pX=50,hX=100,p3=32*1024,mX={requestFrame(e){return typeof requestAnimationFrame=="function"?requestAnimationFrame(e):null},cancelFrame(e){typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(e)},requestTask(e){return setTimeout(e,pX)},cancelTask(e){clearTimeout(e)}};function gX(e,t,n={}){const o=n.scheduler??mX,s=Math.max(1,Math.floor(n.maxItemsPerSlice??hX)),i=[];let r=0,l=null,a=null,u=0,c=!1;const d=()=>i.length-r,f=()=>{u+=1,l!==null&&(o.cancelFrame(l),l=null),a!==null&&(o.cancelTask(a),a=null)},h=()=>{r===i.length?(i.length=0,r=0):r>=1024&&(i.splice(0,r),r=0)};let m;const v=()=>{if(c||l!==null||a!==null||d()===0)return;const w=++u,b=()=>{w===u&&m()};l=o.requestFrame(b),a=o.requestTask(b)};m=()=>{f();let w=0;for(;!c&&w<s&&r<i.length;){const b=i[r++];e(b),w+=1}h(),v()};const k=(w=>{if(!c){if(t(w)){const b=i.length>r?i.at(-1):void 0,_=b===void 0?void 0:n.coalesce?.(b,w);_===void 0?i.push(w):i[i.length-1]=_,v();return}if(d()===0){e(w);return}i.push(w),m()}});return k.flush=()=>{if(!c){for(f();!c&&r<i.length;)e(i[r++]);h()}},k.discard=w=>{if(c||d()===0)return;let b=r;for(let _=r;_<i.length;_+=1){const g=i[_];w(g)||(i[b++]=g)}i.length=b,h(),d()===0?f():v()},k.dispose=()=>{c||(c=!0,f(),i.length=0,r=0)},k}function h3(e){if(e.type==="assistantDelta"){if(e.delta.text!==void 0&&e.delta.thinking===void 0)return{kind:"text",value:e.delta.text};if(e.delta.thinking!==void 0&&e.delta.text===void 0)return{kind:"thinking",value:e.delta.thinking}}}function vX(e){if(e.appEvent.type!=="assistantDelta")return[e];const t=e.appEvent,n=e.meta.stream,o=h3(t);if(n===void 0||o===void 0||n.kind!==o.kind||o.value.length<=p3)return[e];const s=[];let i=0;for(;i<o.value.length;){let r=Math.min(i+p3,o.value.length);r<o.value.length&&r>i&&/[\uD800-\uDBFF]/u.test(o.value[r-1])&&/[\uDC00-\uDFFF]/u.test(o.value[r])&&(r-=1);const l=o.value.slice(i,r);s.push({appEvent:{...t,delta:o.kind==="text"?{text:l}:{thinking:l}},meta:{...e.meta,stream:{...n,offset:n.offset+i}}}),i=r}return s}function yX(e,t){if(e.appEvent.type!=="assistantDelta"||t.appEvent.type!=="assistantDelta")return;const n=e.meta.stream,o=t.meta.stream,s=h3(e.appEvent),i=h3(t.appEvent);if(n===void 0||o===void 0||s===void 0||i===void 0||e.meta.sessionId!==t.meta.sessionId||e.appEvent.sessionId!==t.appEvent.sessionId||e.appEvent.messageId!==t.appEvent.messageId||e.appEvent.contentIndex!==t.appEvent.contentIndex||n.turnId!==o.turnId||n.kind!==o.kind||s.kind!==i.kind||n.kind!==s.kind||o.kind!==i.kind||o.offset!==n.offset+s.value.length||s.value.length+i.value.length>p3)return;const r=s.value+i.value;return{appEvent:{...e.appEvent,delta:s.kind==="text"?{text:r}:{thinking:r}},meta:{...t.meta,stream:{...n}}}}function kX(e){return e==="in_progress"?"in_progress":e==="done"||e==="completed"?"done":"pending"}function bX(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.role==="assistant")for(let o=n.content.length-1;o>=0;o--){const s=n.content[o];if(s.type!=="toolUse"||Gs(s.toolName)!=="todo")continue;let i=s.input;if(typeof i=="string")try{i=JSON.parse(i)}catch{continue}const r=i?.todos;if(Array.isArray(r))return r.flatMap(l=>{const a=l??{},u=typeof a.title=="string"?a.title:typeof a.content=="string"?a.content:"";return u?[{title:u,status:kX(a.status)}]:[]})}}return[]}function CX(e){return e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("--- ")||e.startsWith("+++ ")||e.startsWith("new file mode")||e.startsWith("deleted file mode")||e.startsWith("old mode")||e.startsWith("new mode")||e.startsWith("similarity index")||e.startsWith("dissimilarity index")||e.startsWith("rename from")||e.startsWith("rename to")||e.startsWith("copy from")||e.startsWith("copy to")||e.startsWith("Binary files")}function wX(e){const t=[];if(!e)return t;let n=0,o=0,s=!1;for(const i of e.split(` +`)){if(i.startsWith("diff --git")){s=!1;continue}if(!s&&CX(i))continue;if(i.startsWith("@@")){const a=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(i);a&&(n=Number.parseInt(a[1],10),o=Number.parseInt(a[2],10)),s=!0,t.push({type:"hunk",text:i});continue}if(!s||i.startsWith("\\"))continue;const r=i.charAt(0),l=i.slice(1);r==="+"?(t.push({type:"add",text:l,newNo:o}),o+=1):r==="-"?(t.push({type:"del",text:l,oldNo:n}),n+=1):r===" "&&(t.push({type:"context",text:l,oldNo:n,newNo:o}),n+=1,o+=1)}return t}function Ob(e){return e?e.split(` +`).map(t=>t.trimEnd()).filter(Boolean).at(-1)??"":""}function _X(e){return e.suspendedReason||Ob(e.text)||Ob(e.outputLines?.join(` +`))||e.summary||""}function xX(e){return e.suspendedReason?e.suspendedReason:e.text?e.text:e.outputLines&&e.outputLines.length>0?e.outputLines.join(` +`):e.summary??""}function SX(e){return e==="completed"?"completed":e==="failed"||e==="aborted"?"failed":"working"}function Pb(e,t){return{id:e.agentId??e.item??`result-${t}`,agentId:e.agentId,name:e.item??`subagent ${t+1}`,activity:e.body.split(` +`)[0]??"",phase:SX(e.outcome),body:e.body}}function AX(e,t){return!!(t.agentId&&e.agentId===t.agentId||t.item&&e.name.includes(t.item))}function MX(e,t){const n=e.map(s=>({id:s.id,agentId:s.agentId,name:s.name,activity:_X(s),phase:s.phase,body:xX(s)}));if(!t)return n;const o=t.subagents.filter(s=>(s.outcome==="aborted"||s.state==="not_started")&&!e.some(i=>AX(i,s))).map((s,i)=>Pb(s,i));return n.length>0?[...n,...o]:t.subagents.map((s,i)=>Pb(s,i))}const TX=["queued","working","suspended","completed","failed"];function jT(e){return e.status==="completed"?"completed":e.status==="failed"||e.status==="cancelled"?"failed":e.subagentPhase?e.subagentPhase:"working"}function EX(){return{queued:0,working:0,suspended:0,completed:0,failed:0}}function IX(e){const t=new Map;for(const n of e){if(n.kind!=="subagent"||n.swarmIndex===void 0)continue;const o=n.parentToolCallId??"swarm",s=t.get(o)??[];s.push({id:n.id,agentId:n.agentId,name:n.description,subagentType:n.subagentType,model:n.model,thinkingEffort:n.thinkingEffort,phase:jT(n),summary:n.outputPreview,outputLines:n.outputLines,text:n.text,suspendedReason:n.suspendedReason,swarmIndex:n.swarmIndex}),t.set(o,s)}return[...t.entries()].map(([n,o])=>{const s=o.toSorted((r,l)=>r.swarmIndex-l.swarmIndex||r.id.localeCompare(l.id)),i=EX();for(const r of s)i[r.phase]++;return{id:n,members:s,counts:i}}).filter(n=>n.members.length>1).toSorted((n,o)=>{const s=n.members.at(0)?.swarmIndex??0,i=o.members.at(0)?.swarmIndex??0;return s!==i?s-i:n.id.localeCompare(o.id)})}function LX(e){let t=0,n=0;for(const o of e){n+=o.members.length;for(const s of TX)(s==="completed"||s==="failed")&&(t+=o.counts[s])}return{done:t,total:n}}function $X(e){const t=new Map;for(const n of e){if(n.kind!=="subagent"||!n.parentToolCallId)continue;const o=t.get(n.parentToolCallId)??[];o.push({id:n.id,agentId:n.agentId,name:n.description,subagentType:n.subagentType,model:n.model,thinkingEffort:n.thinkingEffort,phase:jT(n),summary:n.outputPreview,outputLines:n.outputLines,text:n.text,suspendedReason:n.suspendedReason,swarmIndex:n.swarmIndex??Number.MAX_SAFE_INTEGER}),t.set(n.parentToolCallId,o)}for(const[n,o]of t)t.set(n,o.toSorted((s,i)=>s.swarmIndex-i.swarmIndex||s.id.localeCompare(i.id)));return t}function _y(e){const t=e.trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function VT(e){for(const t of["path","file_path","filePath","filename"]){const n=e[t];if(typeof n=="string"&&n.length>0)return n}}const kf=100*1024;function qT(e){const t=Gs(e.name);if(t!=="edit"&&t!=="multi_edit")return null;const n=_y(e.arg);if(!n)return null;if(t==="edit"){if(n.replace_all===!0)return null;const l=typeof n.old_string=="string"?n.old_string:void 0,a=typeof n.new_string=="string"?n.new_string:void 0;return l===void 0||a===void 0||l.length>kf||a.length>kf?null:r1(l,a)}const o=Array.isArray(n.edits)?n.edits:void 0;if(!o||o.length===0)return null;const s=[];let i=0,r=0;for(const l of o){if(!l||typeof l!="object")return null;const a=l;if(a.replace_all===!0)return null;const u=typeof a.old_string=="string"?a.old_string:void 0,c=typeof a.new_string=="string"?a.new_string:void 0;if(u===void 0||c===void 0||u.length>kf||c.length>kf)return null;const d=r1(u,c);if(d===null)return null;s.length>0&&s.push({type:"hunk",text:"···"});for(const f of d)s.push({...f,oldNo:f.oldNo!==void 0?f.oldNo+i:void 0,newNo:f.newNo!==void 0?f.newNo+r:void 0});i+=Sl(u).length,r+=Sl(c).length}return s}const NX=5e3;function FX(e){if(Gs(e.name)!=="write")return null;const t=_y(e.arg);return!t||typeof t.content!="string"||t.content.length>kf||t.content.split(` +`).length>NX?null:{content:t.content,path:VT(t)}}function Db(e){const t=_y(e.arg);return t?VT(t):void 0}function KT(){let e=[],t=null,n=null,o=null,s,i=!0;const r=new WeakMap,l=a=>{const{messages:u,approvals:c}=a,d=a.sessionActive??!0,f=a.planReviewByToolCallId??{},h=a.plansByToolCallId??{},m=(T,A)=>r.set(T,A);let v=n!==null;if(v){const T=n,A=Object.keys(f);v=A.length===Object.keys(T).length&&A.every(E=>f[E]===T[E])}let k=o!==null;if(k){const T=o,A=Object.keys(h);k=A.length===Object.keys(T).length&&A.every(E=>h[E]===T[E])}const w=e.length>0&&c===t&&v&&k&&a.getFileUrl===s;let b=0,_=0,g=1;if(w){let T=-1;for(let A=e.length-1;A>=0;A--)if(e[A].role==="assistant"){T=A;break}for(let A=0;A<e.length;A++){const E=e[A],P=r.get(E);if(!P||P.length===0||A===T&&d!==i)break;let D=_+P.length<=u.length;for(let I=0;D&&I<P.length;I++)u[_+I]!==P[I]&&(D=!1);if(!D||A===T&&_+P.length!==u.length)break;b++,_+=P.length,E.role!=="compaction"&&g++}}const x=UT(u.slice(_),c,a.getFileUrl,d,f,h,{startNo:g,collect:m}),S=b>0?[...e.slice(0,b),...x]:x;return e=S,t=c,n={...f},o={...h},s=a.getFileUrl,i=d,S};return l.reset=()=>{e=[],t=null,n=null,o=null,s=void 0,i=!0},l}const ZT=["light","dark","system"],RX=["small","medium","large","xlarge"],a9="medium",GT="kimi-web.color-scheme",m3="kimi-web.font-scale",Bb="kimi-web.ui-font-size";function g3(e){try{return globalThis.localStorage.getItem(e)}catch{return null}}function xy(e,t){try{globalThis.localStorage.setItem(e,t)}catch{}}function OX(e){try{globalThis.localStorage.removeItem(e)}catch{}}function PX(){const e=g3(GT);return e&&ZT.includes(e)?e:"system"}const oh={light:"#ffffff",dark:"#121212"};function DX(e){if(typeof document>"u"||!document.documentElement)return;document.documentElement.dataset.colorScheme=e;const t=document.querySelectorAll('meta[name="theme-color"]');if(t.length===0)return;const n=e==="dark"?oh.dark:e==="light"?oh.light:null;t.forEach(o=>{const i=(o.getAttribute("media")??"").includes("dark")?oh.dark:oh.light;o.setAttribute("content",n??i)})}function YT(e){return RX.includes(e)}function BX(e){return e<=13?"small":e<=15?"medium":e<=17?"large":"xlarge"}function HX(){const e=g3(m3);if(e==="xxlarge")return"xlarge";if(e!==null)return YT(e)?e:a9;const t=g3(Bb);if(t===null)return a9;const n=Number(t),o=Number.isFinite(n)?BX(n):a9;return xy(m3,o),OX(Bb),o}function zX(e){typeof document>"u"||!document.documentElement||(document.documentElement.dataset.fontScale=e)}const Sy=Z(PX()),Ay=Z(HX());let Hb=!1;function WX(){Hb||(Hb=!0,Je(Sy,DX,{immediate:!0}),Je(Ay,zX,{immediate:!0}))}function UX(e){ZT.includes(e)&&(Sy.value=e,xy(GT,e))}function jX(e){YT(e)&&(Ay.value=e,xy(m3,e))}function XT(){return WX(),{colorScheme:Sy,fontScale:Ay,setColorScheme:UX,setFontScale:jX}}const sh=Z(!1);let zb=!1;function u9(){const e=document.documentElement.dataset.colorScheme;return e==="dark"?!0:e==="light"?!1:window.matchMedia("(prefers-color-scheme: dark)").matches}function f2(){return!zb&&typeof window<"u"&&typeof document<"u"&&(zb=!0,sh.value=u9(),new MutationObserver(()=>{sh.value=u9()}).observe(document.documentElement,{attributes:!0,attributeFilter:["data-color-scheme"]}),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{sh.value=u9()})),sh}const VX=Symbol("KimiWebClientFacade"),qX="modulepreload",KX=function(e){return"/"+e},Wb={},jo=function(t,n,o){let s=Promise.resolve();if(n&&n.length>0){let r=function(u){return Promise.all(u.map(c=>Promise.resolve(c).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};document.getElementsByTagName("link");const l=document.querySelector("meta[property=csp-nonce]"),a=l?.nonce||l?.getAttribute("nonce");s=r(n.map(u=>{if(u=KX(u),u in Wb)return;Wb[u]=!0;const c=u.endsWith(".css"),d=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const f=document.createElement("link");if(f.rel=c?"stylesheet":qX,c||(f.as="script"),f.crossOrigin="",f.href=u,a&&f.setAttribute("nonce",a),document.head.appendChild(f),c)return new Promise((h,m)=>{f.addEventListener("load",h),f.addEventListener("error",()=>m(new Error(`Unable to preload CSS for ${u}`)))})}))}function i(r){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=r,window.dispatchEvent(l),!l.defaultPrevented)throw r}return s.then(r=>{for(const l of r||[])l.status==="rejected"&&i(l.reason);return t().catch(i)})};function vc(e){const t=Math.max(0,Math.floor(e/1e3));if(t<60)return t===0?"":`${t}s`;const n=Math.floor(t/60);if(n<60){const i=t%60;return i===0?`${n}m`:`${n}m${i}s`}const o=Math.floor(n/60),s=n%60;return s===0?`${o}h`:`${o}h${s}m`}const JT=new Set(["read","bash","grep","search","glob","ls","web_fetch","edit","write"]);function QT(e){const t=Gs(e);return t==="multi_edit"?"edit":t}function eE(e){const t=[],n=new Map;for(const o of e){if(o.kind==="thinking")continue;const s=QT(o.tool.name);let i=n.get(s);i||(i={count:0,errors:0},n.set(s,i),t.push(s)),i.count++,o.tool.status==="error"&&i.errors++}return{order:t,byKind:n}}function tE(e,t,n){return JT.has(t)?e(`tools.group.typed.${t}.done`,{count:n}):e("tools.group.countOther",{count:n})}function nE(e,t){return{text:e("tools.activity.failedClause",{count:t}),tone:"danger"}}function oE(e){return e.map(t=>t.fragments.map(n=>n.text).join("")).join(" · ")}function ZX(e,t,n={}){const{order:o,byKind:s}=eE(t),i=[];let r=!1;for(const l of o){const a=s.get(l);if(!a)continue;const u=[{text:tE(e,l,a.count),tone:"normal"}];a.errors>0&&(r=!0,u.push(nE(e,a.errors))),i.push({fragments:u})}if(n.durationMs!==void 0){const l=vc(n.durationMs);l&&i.push({fragments:[{text:l,tone:"faint"}]})}return{clauses:i,plain:oE(i),hasError:r}}function GX(e,t){if(t.kind==="thinking")return{fragments:[{text:e("thinking.streaming"),tone:"normal"}]};const n=QT(t.tool.name);let o=wy(e,t.tool.name,t.tool.arg);if(n==="write"&&o){const i=e("tools.chip.created");o.endsWith(i)&&(o=o.slice(0,o.length-i.length).trimEnd())}return{fragments:[{text:o&&JT.has(n)?e(`tools.activity.doing.${n}`,{subject:o}):e("tools.activity.busy"),tone:"normal"}]}}function YX(e,t,n){const o=t.filter(c=>c!==n&&!(c.kind==="tool"&&c.tool.status==="running")),{order:s,byKind:i}=eE(o),r=e("tools.activity.liveDonePrefix"),l=[];for(const c of s){const d=i.get(c);if(!d)continue;const f=[{text:`${r}${tE(e,c,d.count)}`,tone:"faint"}];d.errors>0&&f.push(nE(e,d.errors)),l.push({fragments:f})}const a=n===null?null:GX(e,n),u=a?[a,...l]:l;return{current:a,done:l,plain:oE(u)}}async function Zs(e){const t=typeof navigator<"u"?navigator.clipboard:void 0;if(t&&typeof t.writeText=="function")try{return await t.writeText(e),!0}catch{}return XX(e)}function XX(e){if(typeof document>"u"||typeof document.execCommand!="function")return!1;const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.style.opacity="0",document.body.appendChild(t);let n=!1;try{t.focus(),t.select(),n=document.execCommand("copy")}catch{n=!1}finally{document.body.removeChild(t)}return n}const JX={ts:"ts",tsx:"tsx",js:"js",jsx:"jsx",mjs:"js",cjs:"js",vue:"vue",svelte:"svelte",py:"py",rb:"rb",go:"go",rs:"rs",java:"java",kt:"kt",kts:"kts",scala:"scala",swift:"swift",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",cs:"cs",php:"php",sh:"sh",bash:"bash",zsh:"zsh",fish:"fish",ps1:"ps1",bat:"bat",cmd:"bat",sql:"sql",graphql:"graphql",prisma:"prisma",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",sass:"sass",less:"less",json:"json",jsonc:"jsonc",json5:"json5",yaml:"yaml",yml:"yml",toml:"toml",ini:"ini",md:"md",markdown:"markdown",mdx:"mdx",lua:"lua",r:"r",dart:"dart",zig:"zig",mk:"makefile",cmake:"cmake",diff:"diff",proto:"proto"},QX={dockerfile:"dockerfile",makefile:"makefile","cmakelists.txt":"cmake"};function eJ(e){const t=e?.split(/[\\/]/).pop()?.toLowerCase()??"";if(!t)return;const n=QX[t];if(n)return n;const o=t.lastIndexOf(".");if(!(o<=0))return JX[t.slice(o+1)]}const tJ="kimi_desktop",nJ="platform",Ub="kimi-desktop",jb="kimi-desktop-platform";function oJ(){let e=!1,t=null;try{const n=new URLSearchParams(window.location.search);n.has(tJ)?(sessionStorage.setItem(Ub,"1"),e=!0):e=e||sessionStorage.getItem(Ub)==="1";const o=n.get(nJ);o?(sessionStorage.setItem(jb,o),t=o):t=sessionStorage.getItem(jb)}catch{}return{isDesktop:e,platform:t}}const v3=oJ(),Wp=v3.isDesktop,rc=v3.isDesktop&&v3.platform==="darwin",sJ=["faces","nature","food","activity","objects","symbols"],iJ=[["😀","faces","grinning smile happy 笑 开心"],["😄","faces","smile happy joy 笑 开心 高兴"],["😁","faces","grin beaming 咧嘴笑 开心"],["😂","faces","joy laugh tears 笑哭 爆笑"],["🤣","faces","rofl laugh rolling 笑翻 爆笑"],["😊","faces","blush shy happy 微笑 害羞"],["😉","faces","wink 眨眼"],["😍","faces","heart eyes love 爱心眼 喜欢 爱"],["🥰","faces","smiling hearts love 爱心 喜欢"],["😘","faces","kiss 飞吻 亲亲"],["😋","faces","yum tongue 好吃 馋"],["🤪","faces","zany crazy 鬼脸 疯"],["🤔","faces","thinking hmm consider 思考 想"],["🤨","faces","skeptical eyebrow 怀疑 挑眉"],["😐","faces","neutral meh 面无表情 无语"],["😑","faces","expressionless 面无表情 无语"],["🙄","faces","eye roll 翻白眼 无语"],["😶","faces","no mouth silent 无言 沉默"],["🫡","faces","salute 敬礼 收到"],["🤫","faces","shush quiet 嘘 安静"],["🤭","faces","oops giggle 捂嘴 偷笑"],["😴","faces","sleeping sleepy 睡觉 困"],["😪","faces","sleepy tired 困 疲惫"],["😷","faces","mask sick 口罩 生病"],["🤒","faces","sick fever 生病 发烧"],["🤕","faces","hurt bandage 受伤"],["🤢","faces","nauseated 恶心"],["🤯","faces","mind blown explode 震惊 爆炸"],["🥳","faces","party celebrate 庆祝 派对"],["🤩","faces","star struck 星星眼 激动"],["😎","faces","cool sunglasses 酷 墨镜"],["🥸","faces","disguise 伪装 假扮"],["🤓","faces","nerd geek 书呆子 学霸"],["😢","faces","cry sad 哭 难过"],["😭","faces","sob cry loudly 大哭 痛哭"],["😤","faces","triumph huff 哼 生气"],["😡","faces","angry rage mad 生气 愤怒"],["🤬","faces","swearing cursing 骂人 爆粗"],["😱","faces","scream fear 尖叫 害怕"],["😨","faces","fearful 害怕 恐惧"],["🥵","faces","hot heat 热 出汗"],["🥶","faces","cold freezing 冷 冻"],["🥴","faces","woozy drunk 晕 醉"],["😇","faces","angel innocent 天使 无辜"],["🙃","faces","upside down silly 倒脸 哭笑不得"],["💀","faces","skull dead 骷髅 笑死"],["👻","faces","ghost 鬼 幽灵"],["👍","faces","thumbs up like good 赞 好"],["👎","faces","thumbs down dislike 踩 差"],["👏","faces","clap applause 鼓掌 厉害"],["🙌","faces","raise hands celebrate 举手 庆祝"],["🙏","faces","pray thanks please 拜托 感谢 祈祷"],["💪","faces","muscle strong flex 加油 强壮 肌肉"],["👀","faces","eyes look watch 看 围观 眼睛"],["🤝","faces","handshake deal 握手 合作"],["✌️","faces","victory peace 胜利 耶"],["👋","faces","wave hello bye 挥手 你好 再见"],["🤞","faces","crossed fingers luck 祈祷 好运"],["👌","faces","ok okay 好的 可以"],["🫶","faces","heart hands love 比心 爱心"],["✍️","faces","writing hand 写字 记录"],["🧠","faces","brain smart 大脑 聪明"],["🦾","faces","mechanical arm 机械臂 力量"],["👤","faces","person user profile 个人 用户"],["👥","faces","people team group 团队 多人"],["🐶","nature","dog puppy 狗 小狗"],["🐱","nature","cat kitten 猫 小猫"],["🐭","nature","mouse rat 老鼠"],["🐹","nature","hamster 仓鼠"],["🐰","nature","rabbit bunny 兔子"],["🦊","nature","fox 狐狸"],["🐻","nature","bear 熊"],["🐼","nature","panda 熊猫"],["🐨","nature","koala 考拉"],["🐯","nature","tiger 老虎"],["🦁","nature","lion 狮子"],["🐮","nature","cow 牛"],["🐷","nature","pig 猪"],["🐸","nature","frog 青蛙"],["🐵","nature","monkey 猴子"],["🐔","nature","chicken 鸡"],["🐧","nature","penguin 企鹅"],["🐦","nature","bird 鸟"],["🐣","nature","chick hatching 小鸡 孵化"],["🦆","nature","duck 鸭子"],["🦉","nature","owl 猫头鹰"],["🐝","nature","bee 蜜蜂"],["🐛","nature","bug caterpillar 虫子 毛虫"],["🦋","nature","butterfly 蝴蝶"],["🐌","nature","snail slow 蜗牛 慢"],["🐢","nature","turtle slow 乌龟 慢"],["🐍","nature","snake 蛇"],["🐙","nature","octopus 章鱼"],["🦑","nature","squid 鱿鱼"],["🦐","nature","shrimp 虾"],["🦀","nature","crab 螃蟹"],["🐠","nature","tropical fish 鱼 热带鱼"],["🐳","nature","whale 鲸鱼"],["🦈","nature","shark 鲨鱼"],["🐊","nature","crocodile 鳄鱼"],["🦄","nature","unicorn 独角兽"],["🐴","nature","horse 马"],["🐑","nature","sheep 羊 绵羊"],["🐐","nature","goat 山羊"],["🦜","nature","parrot 鹦鹉"],["🌸","nature","blossom flower sakura 樱花 花"],["🌹","nature","rose flower 玫瑰 花"],["🌻","nature","sunflower 向日葵"],["🌷","nature","tulip 郁金香"],["🌱","nature","seedling sprout 发芽 幼苗"],["🌲","nature","tree evergreen 树 松树"],["🌳","nature","deciduous tree 树 大树"],["🌵","nature","cactus 仙人掌"],["🍀","nature","clover luck 四叶草 幸运"],["🍁","nature","maple leaf autumn 枫叶 秋天"],["🍄","nature","mushroom 蘑菇"],["🌈","nature","rainbow 彩虹"],["☀️","nature","sun sunny 太阳 晴"],["🌙","nature","moon crescent 月亮"],["⭐","nature","star 星星"],["🌟","nature","glowing star 星星 闪亮"],["☁️","nature","cloud 云"],["⛅","nature","partly cloudy 多云"],["🌧️","nature","rain rainy 下雨"],["❄️","nature","snowflake snow 雪 雪花"],["⛄","nature","snowman 雪人"],["⚡","nature","lightning bolt 闪电"],["🔥","nature","fire hot 火 燃"],["🌊","nature","wave ocean sea 海浪"],["🏔️","nature","mountain snow 雪山 山"],["☕","food","coffee 咖啡"],["🍵","food","tea 茶"],["🧋","food","bubble tea boba 奶茶"],["🥛","food","milk 牛奶"],["🍺","food","beer 啤酒"],["🍷","food","wine 红酒"],["🥂","food","champagne cheers 香槟 干杯"],["🥤","food","cup straw soda 饮料 可乐"],["🧃","food","juice box 果汁"],["🍎","food","apple 苹果"],["🍊","food","orange tangerine 橙子 橘子"],["🍋","food","lemon 柠檬"],["🍉","food","watermelon 西瓜"],["🍓","food","strawberry 草莓"],["🍑","food","peach 桃子"],["🥭","food","mango 芒果"],["🍍","food","pineapple 菠萝"],["🥝","food","kiwi 猕猴桃"],["🍇","food","grapes 葡萄"],["🍒","food","cherries 樱桃"],["🥑","food","avocado 牛油果"],["🥦","food","broccoli 西兰花"],["🌽","food","corn 玉米"],["🌶️","food","hot pepper spicy 辣椒 辣"],["🍔","food","burger hamburger 汉堡"],["🍟","food","fries 薯条"],["🍕","food","pizza 披萨"],["🌭","food","hot dog 热狗"],["🥪","food","sandwich 三明治"],["🌮","food","taco 墨西哥卷"],["🍜","food","ramen noodles 拉面 面条"],["🍝","food","spaghetti pasta 意面"],["🍣","food","sushi 寿司"],["🍱","food","bento 便当"],["🥟","food","dumpling 饺子"],["🍚","food","rice 米饭"],["🍞","food","bread 面包"],["🥐","food","croissant 可颂 牛角包"],["🧀","food","cheese 奶酪 芝士"],["🍳","food","cooking egg 煎蛋 做饭"],["🍦","food","ice cream 冰淇淋"],["🍰","food","cake 蛋糕"],["🎂","food","birthday cake 生日蛋糕"],["🍫","food","chocolate 巧克力"],["🍩","food","donut doughnut 甜甜圈"],["🍪","food","cookie 饼干"],["🍭","food","lollipop 棒棒糖"],["⚽","activity","soccer football 足球"],["🏀","activity","basketball 篮球"],["🏈","activity","american football 橄榄球"],["⚾","activity","baseball 棒球"],["🎾","activity","tennis 网球"],["🏐","activity","volleyball 排球"],["🏓","activity","ping pong 乒乓球"],["🏸","activity","badminton 羽毛球"],["🥊","activity","boxing 拳击"],["⛳","activity","golf 高尔夫"],["🎣","activity","fishing 钓鱼"],["🏊","activity","swim 游泳"],["🏄","activity","surf 冲浪"],["🚴","activity","cycling 骑行"],["🏋️","activity","weightlifting gym 举重 健身"],["🧘","activity","yoga meditation 瑜伽 冥想"],["🎮","activity","video game controller 游戏 游戏机"],["🎲","activity","dice 骰子"],["🎯","activity","target bullseye 目标 靶心"],["🎳","activity","bowling 保龄球"],["🎰","activity","slot machine 老虎机"],["♟️","activity","chess 国际象棋 棋"],["🎸","activity","guitar 吉他"],["🎹","activity","piano keyboard 钢琴"],["🥁","activity","drum 鼓"],["🎤","activity","microphone sing 麦克风 唱歌"],["🎧","activity","headphones 耳机"],["🎬","activity","clapper movie 电影 拍摄"],["🎨","activity","art palette paint 画画 艺术"],["🎭","activity","theater masks 戏剧 面具"],["🎪","activity","circus 马戏团"],["🎡","activity","ferris wheel 摩天轮"],["✈️","activity","airplane travel flight 飞机 旅行"],["🚗","activity","car drive 汽车 车"],["🚕","activity","taxi 出租车"],["🚌","activity","bus 公交车"],["🚑","activity","ambulance 救护车"],["🚒","activity","fire engine 消防车"],["🚀","activity","rocket launch ship 火箭 发射"],["🛸","activity","ufo flying saucer 飞碟"],["🚲","activity","bicycle bike 自行车"],["🛴","activity","scooter 滑板车"],["🚄","activity","bullet train 高铁 动车"],["🚢","activity","ship 船 轮船"],["⛵","activity","sailboat 帆船"],["🏠","activity","house home 房子 家"],["🏢","activity","office building 公司 办公楼"],["🏥","activity","hospital 医院"],["🏫","activity","school 学校"],["🏖️","activity","beach vacation 海滩 度假"],["⛺","activity","camping tent 露营 帐篷"],["🌋","activity","volcano 火山"],["🗺️","activity","map world 地图"],["🧭","activity","compass 指南针"],["💻","objects","laptop computer 电脑 笔记本"],["🖥️","objects","desktop computer 台式机 电脑"],["⌨️","objects","keyboard 键盘"],["🖱️","objects","computer mouse 鼠标"],["📱","objects","phone mobile 手机"],["🔋","objects","battery 电池"],["🔌","objects","plug electric 插头"],["💾","objects","floppy save 软盘 保存"],["📀","objects","cd disc 光盘"],["🎥","objects","movie camera 摄像机"],["📷","objects","camera 相机"],["🔭","objects","telescope 望远镜"],["📡","objects","satellite antenna 卫星 天线"],["🌐","objects","globe web internet 网络 全球 互联网"],["🕯️","objects","candle 蜡烛"],["💡","objects","bulb idea light 灯泡 点子"],["🔦","objects","flashlight 手电筒"],["📁","objects","folder 文件夹"],["📂","objects","open folder 文件夹 打开"],["🗂️","objects","card index archive 归档 索引"],["📅","objects","calendar date 日历 日期"],["📌","objects","pin pushpin 图钉 置顶"],["📍","objects","round pin location 定位 位置"],["📎","objects","paperclip attachment 回形针 附件"],["✂️","objects","scissors cut 剪刀 剪切"],["📏","objects","ruler 尺子"],["📝","objects","memo note write 备忘 记录"],["✏️","objects","pencil edit write 铅笔 编辑"],["📄","objects","document page 文档 文件"],["📃","objects","page curl 文档 文件"],["📑","objects","bookmark tabs 标签页 文档"],["📚","objects","books 书 书籍"],["📖","objects","open book 打开的书 阅读"],["🔖","objects","bookmark 书签"],["🏷️","objects","label tag 标签"],["📊","objects","bar chart stats 图表 统计"],["📈","objects","chart up growth 上涨 增长"],["📉","objects","chart down 下跌 下降"],["🔍","objects","search magnifier 搜索 查找"],["🔎","objects","search magnifier right 搜索 查找"],["🔒","objects","lock locked 锁 锁定"],["🔓","objects","unlock open 解锁"],["🔑","objects","key 钥匙 密钥"],["🔧","objects","wrench tool 扳手 工具"],["🔨","objects","hammer 锤子"],["🛠️","objects","tools hammer wrench 工具 修理"],["🧰","objects","toolbox 工具箱 工具"],["🪛","objects","screwdriver 螺丝刀 工具"],["🔩","objects","nut and bolt screw 螺母 螺栓"],["🏗️","objects","building construction crane 施工 建造"],["⚙️","objects","gear settings 齿轮 设置"],["🧲","objects","magnet 磁铁"],["⚗️","objects","alembic 蒸馏器 实验"],["🧪","objects","test tube experiment 实验 试管"],["🔬","objects","microscope science 显微镜 科学"],["🤖","objects","robot bot 机器人"],["👾","objects","alien monster game 外星人 游戏"],["💣","objects","bomb 炸弹"],["🧨","objects","firecracker 爆竹"],["🗑️","objects","trash delete 垃圾桶 删除"],["🧹","objects","broom clean 扫帚 清理"],["🧻","objects","toilet paper 纸巾"],["🧽","objects","sponge 海绵"],["📦","objects","package box 包裹 箱子"],["✉️","objects","envelope mail 邮件 信封"],["📮","objects","mailbox postbox 邮箱"],["📧","objects","email mail 邮件"],["📥","objects","inbox tray receive 收件箱 接收"],["📤","objects","outbox tray send 发件箱 发送"],["📞","objects","telephone receiver call phone 电话 通话"],["💬","objects","speech balloon chat message bubble 聊天 对话 气泡 消息"],["💭","objects","thought balloon thinking 思考 想法 气泡"],["📣","objects","megaphone announcement 喇叭 公告"],["📢","objects","loudspeaker broadcast 广播 喇叭 通知"],["🚨","objects","police light alert emergency 警报 告警 紧急"],["🗳️","objects","ballot box vote 投票箱 投票"],["🔗","objects","link chain 链接 连接"],["🧩","objects","puzzle piece plugin 拼图 插件"],["🪄","objects","magic wand 魔法 魔杖"],["🛡️","objects","shield security 盾牌 安全"],["⚔️","objects","crossed swords 交叉剑 战斗"],["💳","objects","credit card 信用卡"],["💰","objects","money bag 钱袋 钱"],["🧾","objects","receipt 收据 小票"],["📿","objects","prayer beads 念珠"],["💍","objects","ring 戒指"],["👑","objects","crown 皇冠"],["🎩","objects","top hat 礼帽"],["🎒","objects","backpack 背包 书包"],["👓","objects","glasses 眼镜"],["🌂","objects","umbrella 雨伞"],["🕰️","objects","mantel clock 座钟"],["⌚","objects","watch 手表"],["⏱️","objects","stopwatch 秒表"],["🧯","objects","fire extinguisher 灭火器"],["🩹","objects","bandage patch fix 创可贴 补丁 修复"],["🎓","objects","graduation cap study learn 毕业 学习"],["🎫","objects","ticket 票 门票 工单"],["✅","symbols","check done complete 完成 对勾"],["✔️","symbols","checkmark correct 对勾 正确"],["❌","symbols","cross x wrong 错误 叉"],["❓","symbols","question help 问题 问号"],["❔","symbols","white question 问题 问号"],["❗","symbols","exclamation important 感叹号 重要"],["❕","symbols","white exclamation 感叹号"],["⚠️","symbols","warning caution 警告 注意"],["🚧","symbols","construction wip 施工 进行中"],["🚫","symbols","prohibited no 禁止"],["💥","symbols","boom explosion 爆炸"],["✨","symbols","sparkles shiny 闪亮 星星"],["🎉","symbols","tada party celebrate 庆祝 撒花"],["🎊","symbols","confetti party 庆祝 彩带"],["🏆","symbols","trophy champion 奖杯 冠军"],["🥇","symbols","gold medal first 金牌 第一"],["🥈","symbols","silver medal second 银牌 第二"],["🥉","symbols","bronze medal third 铜牌 第三"],["🎖️","symbols","military medal 勋章"],["🚩","symbols","red flag mark 红旗 标记"],["🏁","symbols","checkered flag finish 终点 完成"],["⏳","symbols","hourglass time waiting 沙漏 时间"],["⌛","symbols","hourglass done 沙漏 时间"],["🕐","symbols","clock one time 时钟 一点"],["⏰","symbols","alarm clock 闹钟"],["🔔","symbols","bell notification 铃铛 通知"],["🔕","symbols","bell slash mute 静音 免打扰"],["🕹️","symbols","joystick game 摇杆 游戏"],["🔴","symbols","red circle record 红圆 录制"],["🟢","symbols","green circle online 绿圆 在线"],["🟡","symbols","yellow circle 黄圆"],["🟠","symbols","orange circle 橙圆"],["🔵","symbols","blue circle 蓝圆"],["🟣","symbols","purple circle 紫圆"],["⚫","symbols","black circle 黑圆"],["⚪","symbols","white circle 白圆"],["🟥","symbols","red square 红方"],["🟩","symbols","green square 绿方"],["🟦","symbols","blue square 蓝方"],["🔺","symbols","red triangle up 三角 上"],["🔻","symbols","triangle down 三角 下"],["🔸","symbols","diamond orange 菱形"],["🔹","symbols","diamond blue 菱形"],["💠","symbols","diamond dot 菱形 花"],["🔶","symbols","diamond orange big 菱形"],["🔷","symbols","diamond blue big 菱形"],["▶️","symbols","play 播放"],["⏸️","symbols","pause 暂停"],["⏹️","symbols","stop 停止"],["⏺️","symbols","record 录制"],["⏩","symbols","fast forward 快进"],["⏪","symbols","rewind 快退"],["🔀","symbols","shuffle 随机 打乱"],["🔁","symbols","repeat 重复 循环"],["🔂","symbols","repeat one 单曲循环"],["🔄","symbols","refresh sync 刷新 同步"],["🔃","symbols","reload 重载"],["➕","symbols","plus add 加 新增"],["➖","symbols","minus 减"],["➗","symbols","divide 除"],["✖️","symbols","multiply 乘"],["💲","symbols","dollar money 美元 钱"],["™️","symbols","trademark 商标"],["©️","symbols","copyright 版权"],["®️","symbols","registered 注册商标"],["↔️","symbols","left right arrow 左右箭头"],["⬆️","symbols","up arrow 上箭头"],["⬇️","symbols","down arrow 下箭头"],["➡️","symbols","right arrow 右箭头"],["⬅️","symbols","left arrow 左箭头"],["🔙","symbols","back 返回"],["🔜","symbols","soon 很快"],["🔝","symbols","top 置顶 顶部"],["💤","symbols","zzz sleep 睡觉"],["🆕","symbols","new 新 新品"],["🆒","symbols","cool 酷"],["🆓","symbols","free 免费"],["🆗","symbols","ok 可以"],["🆙","symbols","up 提升"],["🆚","symbols","vs versus 对比"],["♾️","symbols","infinity 无限"],["💯","symbols","hundred perfect 满分 一百"],["💢","symbols","anger 生气"],["♨️","symbols","hot springs 温泉"],["🚸","symbols","children crossing 注意儿童"],["🔞","symbols","no one under eighteen 十八禁"],["📵","symbols","no mobile phones 禁止手机"],["❤️","symbols","red heart love 红心 爱"],["🧡","symbols","orange heart 橙心"],["💛","symbols","yellow heart 黄心"],["💚","symbols","green heart 绿心"],["💙","symbols","blue heart 蓝心"],["💜","symbols","purple heart 紫心"],["🖤","symbols","black heart 黑心"],["🤍","symbols","white heart 白心"],["🤎","symbols","brown heart 棕心"],["💔","symbols","broken heart 心碎"],["💕","symbols","two hearts 双心 爱心"],["💖","symbols","sparkling heart 闪亮的心"],["💗","symbols","growing heart 心动"]],sE=iJ.map(([e,t,n])=>({emoji:e,group:t,keywords:n}));function rJ(e,t=24){const n=e.trim().toLowerCase();if(!n)return[];const o=[];for(const s of sE)if((s.keywords.includes(n)||s.emoji===n)&&(o.push(s.emoji),o.length>=t))break;return o}const lJ=8;function aJ(e,t,n=lJ){return[t,...e.filter(o=>o!==t)].slice(0,n)}function uJ(e,t){try{const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const o=new Date,s=c=>String(c).padStart(2,"0"),i=`${s(n.getHours())}:${s(n.getMinutes())}`,r=n.getFullYear()===o.getFullYear(),l=n.getMonth()===o.getMonth(),a=n.getDate()===o.getDate();if(r&&l&&a)return i;const u=new Date(o);return u.setDate(o.getDate()-1),n.getFullYear()===u.getFullYear()&&n.getMonth()===u.getMonth()&&n.getDate()===u.getDate()?`${t} ${i}`:r?`${s(n.getMonth()+1)}-${s(n.getDate())} ${i}`:`${n.getFullYear()}-${s(n.getMonth()+1)}-${s(n.getDate())} ${i}`}catch{return e}}function Al(e){if(e>=1024*1024)return`${Vb(e/(1024*1024))}M`;if(e>=1024){const t=e/1024;return`${t>=100?Math.round(t):Vb(t)}k`}return String(e)}function Vb(e){const t=e.toFixed(1);return t.endsWith(".0")?t.slice(0,-2):t}function v1(e){const t=e.split("/").filter(Boolean);return t.length>0?t[t.length-1]:e}const cJ=/^(?:[A-Za-z]:[\\/]|\\\\|\/\/)/;function Pr(e){const t=e.replaceAll("\\","/"),n=cJ.test(t),o=t.replace(/\/+$/,"");return n?o.toLowerCase():o}function dJ(e){const{workspaces:t,sessions:n,hiddenWorkspaceRoots:o,sessionsHasMoreByWorkspace:s}=e,i=new Set(o.map(Pr)),r=new Map;for(const f of t){const h=Pr(f.root);i.has(h)||r.has(h)||r.set(h,{...f})}for(const f of n){const h=f.cwd;if(!h)continue;const m=Pr(h);i.has(m)||r.has(m)||r.set(m,{id:f.workspaceId??h,root:h,name:v1(h),sessionCount:0})}const l=new Map;for(const f of t){const h=Pr(f.root);l.has(h)||l.set(h,f.id)}const a=new Map;for(const f of n){const h=l.get(Pr(f.cwd))??f.workspaceId??f.cwd;a.set(h,(a.get(h)??0)+1)}const u=[];for(const f of t){const h=Pr(f.root);!i.has(h)&&!u.includes(h)&&u.push(h)}const c=[...r.keys()].filter(f=>!u.includes(f));c.sort((f,h)=>r.get(f).root.localeCompare(r.get(h).root));const d=[];for(const f of[...u,...c]){const h=r.get(f),m=a.get(h.id)??a.get(h.root)??0,v=s[h.id]===!1?m:Math.max(h.sessionCount,m);d.push({...h,sessionCount:v})}return d}function fJ(e,t){if(e===void 0||e.length===0)return;const n=t?.find(o=>o.id===e)??t?.find(o=>o.model===e);return n?.displayName||n?.model||(e.includes("/")?e.split("/").pop():e)}function pJ(e){if(!(e===void 0||e.length===0||e==="off"||e==="on"))return e}function p2(e){if(e===void 0)return"toggle";const t=e.capabilities??[];return t.includes("always_thinking")?"always-on":t.includes("thinking")||e.adaptiveThinking===!0?"toggle":"unsupported"}function iE(e){return e?.supportEfforts??[]}function hJ(e){return e[Math.floor(e.length/2)]}function bp(e){if(p2(e)==="unsupported")return"off";const t=iE(e);return t.length>0?e?.defaultEffort??hJ(t):"on"}function Up(e){const t=iE(e),n=p2(e);return t.length>0?n==="always-on"?[...t]:["off",...t]:n==="always-on"?["on"]:n==="unsupported"?["off"]:["on","off"]}function y3(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function mJ(e){return e!=="off"}function gJ(e,t){return Up(e).includes(t)}function My(e,t){return t==="off"?"off":t==="on"?bp(e):t}function Dm(e,t){return t??bp(e)}function vJ(e,t){if(e==="off")return{enabled:!1};if(e==="on")return{enabled:!0};const n=t?.at(-1);return n!==void 0&&e===n?{enabled:!0}:{enabled:!0,effort:e}}function yJ(e,t,n){return!n||e===void 0?t:bp(e)}let kJ=0;function k3(e,t){const n=++kJ;return e.pendingThinkingBySession[t]=n,n}function vl(e,t,n){return n===void 0||e.pendingThinkingBySession[t]!==n?!1:(delete e.pendingThinkingBySession[t],!0)}function rE(e,t,n){e.pendingThinkingBySession[t]===void 0&&(e.thinkingBySession[t]=n)}function lE(){return window.kimiDesktop}function ih(){return typeof lE()?.getPathForFile=="function"}function aE(e){const t=lE()?.getPathForFile;if(typeof t!="function")return null;try{return t(e)}catch{return null}}function c9(e){return Array.from(e.dataTransfer?.items??[]).some(t=>t.kind==="file"&&t.type==="")}function b3(e,t=aE){const n=Array.from(e.dataTransfer?.items??[]);if(n.length===0)return{files:Array.from(e.dataTransfer?.files??[]),folderPaths:[]};const o=[],s=[],i=new Set;for(const r of n){if(r.kind!=="file")continue;const l=r.getAsFile();if(l)if(r.webkitGetAsEntry()?.isDirectory===!0){const a=t(l);if(!a||i.has(a))continue;i.add(a),s.push(a)}else o.push(l)}return{files:o,folderPaths:s}}function bJ(e,t=aE){return b3(e,t).folderPaths}const CJ=/<summary>([\s\S]*?)<\/summary>/,wJ=/<resume_hint>([\s\S]*?)<\/resume_hint>/,d9=/<subagent\b([^>]*)>|<\/subagent>/g,_J="</subagent>",qb=/(completed|failed|aborted):\s*(\d+)/g,Kb=/([a-z_]+)="([^"]*)"/g;function xJ(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function SJ(e){const t={};Kb.lastIndex=0;let n;for(;(n=Kb.exec(e))!==null;)t[n[1]]=xJ(n[2]);return t}function AJ(e){const t={completed:0,failed:0,aborted:0};qb.lastIndex=0;let n;for(;(n=qb.exec(e))!==null;){const o=n[1];t[o]=Number(n[2])}return t}function MJ(e,t){const n=SJ(e);return{outcome:n.outcome??"completed",item:n.item,agentId:n.agent_id,mode:n.mode,state:n.state,body:t.trim()}}function TJ(e){const t=[],n=[];d9.lastIndex=0;let o;for(;(o=d9.exec(e))!==null;)if(o[0]===_J){if(n.length===0)continue;const s=n.pop();s&&n.length===0&&t.push(MJ(s.attrs,e.slice(s.bodyStart,o.index)))}else n.length===0?n.push({attrs:o[1]??"",bodyStart:d9.lastIndex}):n.push(null);return t}function EJ(e){if(e==null)return null;const t=Array.isArray(e)?e.join(` +`):e;if(!t.includes("<agent_swarm_result>"))return null;const n=CJ.exec(t)?.[1]?.trim()??"",{completed:o,failed:s,aborted:i}=AJ(n),r=wJ.exec(t)?.[1]?.trim(),l=TJ(t),a=o+s+i;return{summary:n,completed:o,failed:s,aborted:i,total:a>0?a:l.length,subagents:l,resumeHint:r}}const IJ=/^[A-Za-z]:[\\/]/;function Zb(e){return IJ.test(e)||e.startsWith("\\\\")||e.startsWith("//")}function h2(e,t){if(!t)return null;const n=c=>c.replace(/\\/g,"/"),o=n(e);let s=n(t);s.length>1&&(s=s.replace(/\/+$/,""));const i=Zb(s)||Zb(o),r=i?s.toLowerCase():s,l=i?o.toLowerCase():o,a=r.endsWith("/")?r:`${r}/`;if(l!==r&&!l.startsWith(a))return null;const u=l===r?"":o.slice(a.length);return u.split("/").includes("..")?null:u||null}const Bf="application/x-kimi-session-row";function LJ(e,t){return e.includes(t)?e:[...e,t]}function uE(e,t){return e.includes(t)?e.filter(n=>n!==t):e}function cE(e,t){const n=new Set(e);return[...e,...t.filter(o=>!n.has(o))]}function $J(e,t){const n=new Set(t),o=new Map,s=[];for(const r of e)n.has(r.id)?o.set(r.id,r):s.push(r);const i=[];for(const r of t){const l=o.get(r);l!==void 0&&i.push(l)}return{pinned:i,unpinned:s}}function NJ(e,t,n,o){const s=e.filter(r=>r!==t),i=n===null?-1:s.indexOf(n);return i===-1?[...s,t]:(s.splice(o==="before"?i:i+1,0,t),s)}function FJ(e,t,n){return e.find(o=>o.window?.duration===t&&o.window?.unit===n)}const RJ=30;function OJ(e){return e!==void 0&&e<RJ}function dE(e,t){if(e.window!==void 0){const{duration:n,unit:o}=e.window;return o==="week"?t("settings.planUsage.weekLimit",{n}):o==="day"?t("settings.planUsage.dayLimit",{n}):o==="hour"?t("settings.planUsage.hourLimit",{n}):t("settings.planUsage.minuteLimit",{n})}return e.name??t("settings.planUsage.genericLimit")}function fE(e,t){const n=Date.parse(e);if(Number.isNaN(n))return"";const o=Math.floor((n-Date.now())/1e3);if(o<=0)return t("settings.planUsage.resetDone");const s=Math.floor(o/86400),i=Math.floor(o%86400/3600),r=Math.floor(o%3600/60),l=[];return s>0?(l.push(t("settings.planUsage.durationDay",{n:s})),l.push(t("settings.planUsage.durationHour",{n:i})),l.push(t("settings.planUsage.durationMinute",{n:r}))):i>0?(l.push(t("settings.planUsage.durationHour",{n:i})),l.push(t("settings.planUsage.durationMinute",{n:r}))):r>0?l.push(t("settings.planUsage.durationMinute",{n:r})):l.push(t("settings.planUsage.durationSecond",{n:o})),t("settings.planUsage.resetsIn",{duration:l.join(" ")})}function C3(e,t){if(t<=0)return"ok";const n=e/t;return n>=.85?"danger":n>=.5?"warn":"ok"}function Wh(e,t){return t<=0?0:Math.min(100,Math.round(e/t*100))}function PJ(e,t){const n=(e/100).toFixed(2);switch(t.toUpperCase()){case"CNY":return{symbol:"¥",number:n};case"USD":return{symbol:"$",number:n};default:return{symbol:"",number:`${n} ${t}`}}}const DJ=["kimi","openai","openai_responses","anthropic","google-genai","vertexai"];function rh(){return{model:"",maxContextSize:"",displayName:"",capabilities:["tool_use","thinking"],supportEfforts:[],adaptiveThinking:!0}}function w3(e,t){const n=[];for(const o of Object.values(t??{})){if(o===null||typeof o!="object")continue;const s=o;s.provider===e.id&&n.push({model:typeof s.model=="string"?s.model:"",maxContextSize:typeof s.maxContextSize=="number"?String(s.maxContextSize):"",displayName:typeof s.displayName=="string"?s.displayName:"",capabilities:Array.isArray(s.capabilities)?s.capabilities.filter(i=>typeof i=="string"):[],supportEfforts:Array.isArray(s.supportEfforts)?s.supportEfforts.filter(i=>typeof i=="string"):[],...typeof s.adaptiveThinking=="boolean"?{adaptiveThinking:s.adaptiveThinking}:{}})}return n}const pE=/^[\p{L}\p{N}][\p{L}\p{N}\-_ ]*$/u;function BJ(e,t={}){const n=e.id.trim();if(n==="")return"idRequired";if(!pE.test(n))return"idInvalid";if(t.requireApiKey===!0&&e.apiKey.trim()==="")return"apiKeyRequired";if(t.requireBaseUrl===!0&&e.baseUrl.trim()==="")return"baseUrlRequired";if(e.models.length===0)return"modelRequired";for(const o of e.models){if(o.model.trim()==="")return"modelRequired";const s=o.maxContextSize.trim();if(s==="")return"contextSizeRequired";if(!/^\d+$/.test(s)||Number(s)<1)return"contextSizeInvalid"}return null}function hE(e){return e.map(t=>{const n=t.displayName.trim();return{model:t.model.trim(),maxContextSize:Number(t.maxContextSize.trim()),...t.capabilities.length>0?{capabilities:[...t.capabilities]}:{},...t.supportEfforts.length>0?{supportEfforts:[...t.supportEfforts]}:{},...t.adaptiveThinking!==void 0?{adaptiveThinking:t.adaptiveThinking}:{},...n===""?{}:{displayName:n}}})}function HJ(e){const t=e.apiKey.trim(),n=e.baseUrl.trim();return{id:e.id.trim(),type:e.type,models:hE(e.models),...t===""?{}:{apiKey:t},...n===""?{}:{baseUrl:n}}}function zJ(e,t,n){const o=hE(e.models),s=e.id.trim(),i=e.apiKey.trim(),r=e.baseUrl.trim(),l=n?.existingDefaultModel?.trim()??"",a=l.indexOf("/")>=0?l.slice(l.indexOf("/")+1):l;return{...t!==void 0&&s!==""&&s!==t.id?{newId:s}:{},type:e.type,models:o,...i===""&&n?.includeBlankApiKey!==!0?{}:{apiKey:i},...r===""?{}:{baseUrl:r},...a!==""&&o.some(u=>u.model===a)?{defaultModel:a}:{}}}function mE(e){return e.id==="managed:kimi-code"&&e.type==="kimi"}const WJ=/^(\d+)\t(.*)$/;function UJ(e){const t=e.at(-1)===""?e.slice(0,-1):e;if(t.length===0)return null;const n=[],o=[];for(const s of t){const i=WJ.exec(s);if(!i)return null;o.push(Number(i[1])),n.push(i[2]??"")}return{contents:n,lineNumbers:o}}function gE(e,t){for(const n of e.stateMachineNames){const o=(e.stateMachineInputs(n)??[]).find(s=>s.name===t);if(o!==void 0)return o}return null}function jJ(e,t){const n=gE(e,t);return n!==null&&typeof n.fire=="function"?(n.fire(),!0):!1}function Gb(e,t,n){const o=gE(e,t);return o!==null&&typeof o.value==typeof n?(o.value=n,!0):!1}const VJ={"&":"&","<":"<",">":">",'"':""","'":"'"};function Yb(e){return e.replace(/[&<>"']/g,t=>VJ[t]??t)}function qJ(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function KJ(e,t,n=40){const o=e.replace(/\s+/g," ").trim();if(o.length===0)return"";const s=t.trim();if(s.length===0)return Xb(o,n*2);const i=o.toLowerCase().indexOf(s.toLowerCase());if(i<0)return Xb(o,n*2);const r=Math.max(0,i-n),l=Math.min(o.length,i+s.length+n),a=r>0,u=l<o.length;return`${a?"…":""}${o.slice(r,l)}${u?"…":""}`}function Xb(e,t){return e.length<=t?e:`${e.slice(0,t)}…`}function f9(e,t){const n=Yb(e),o=t.trim();if(o.length===0)return n;const s=new RegExp(qJ(Yb(o)),"gi");return n.replace(s,i=>`<mark>${i}</mark>`)}const zs="kimi-web.server-credential",ZJ="token",GJ=10080*60*1e3;let yl;const _3=new Set;function YJ(){if(typeof window>"u")return;const e=window.location.hash??"";if(!e.startsWith("#"))return;const n=new URLSearchParams(e.slice(1)).get(ZJ);if(!n)return;const o=new URL(window.location.href);return o.hash="",window.history.replaceState(window.history.state,"",`${o.pathname}${o.search}`),n}function x3(e){return{version:1,credential:e,expiresAt:Date.now()+GJ}}function XJ(e){return JSON.stringify(e)}function Ty(e){try{const t=JSON.parse(e);if(typeof t!="object"||t===null)return;const n=t;return n.version!==1||typeof n.credential!="string"||n.credential.length===0||typeof n.expiresAt!="number"||!Number.isFinite(n.expiresAt)?void 0:{version:1,credential:n.credential,expiresAt:n.expiresAt}}catch{return}}function S3(e){globalThis.localStorage?.setItem(zs,XJ(e))}function JJ(){try{const e=globalThis.localStorage?.getItem(zs);if(e){const n=Ty(e);if(n===void 0){const o=x3(e);let s=!1;try{S3(o),s=!0}catch{}if(!s)try{globalThis.localStorage?.getItem(zs)===e&&globalThis.localStorage?.removeItem(zs),s=!0}catch{}try{globalThis.sessionStorage?.removeItem(zs)}catch{}return s?o:void 0}if(n.expiresAt>Date.now())return n;globalThis.sessionStorage?.removeItem(zs),globalThis.localStorage?.getItem(zs)===e&&globalThis.localStorage?.removeItem(zs);return}const t=globalThis.sessionStorage?.getItem(zs);if(t){const n=x3(t);let o=!1;try{S3(n),o=!0}catch{}try{globalThis.sessionStorage?.removeItem(zs),o=!0}catch{}return o?n:void 0}return}catch{return}}function QJ(){const e=YJ();return e?(vE(e),!0):(yl=JJ(),yl!==void 0)}function eQ(){if(yl!==void 0){if(yl.expiresAt<=Date.now()){tQ(yl);return}return yl.credential}}function tQ(e){yl=void 0;try{globalThis.sessionStorage?.removeItem(zs);const t=globalThis.localStorage?.getItem(zs),n=t==null?void 0:Ty(t);(n===void 0?t===e.credential:n.credential===e.credential&&n.expiresAt===e.expiresAt)&&globalThis.localStorage?.removeItem(zs)}catch{}}function vE(e){const t=x3(e);yl=t;try{S3(t)}catch{}try{globalThis.sessionStorage?.removeItem(zs)}catch{}}function nQ(){const e=yl;yl=void 0;try{const t=globalThis.localStorage?.getItem(zs),o=(t==null?void 0:Ty(t))?.credential??t;e!==void 0&&o===e.credential&&globalThis.localStorage?.removeItem(zs),globalThis.sessionStorage?.removeItem(zs)}catch{}}function oQ(e){return _3.add(e),()=>{_3.delete(e)}}function sQ(){nQ();for(const e of _3)try{e()}catch{}}let Jb;function iQ(e){if(typeof Intl.Segmenter=="function")return Jb??=new Intl.Segmenter("und",{granularity:"grapheme"}),Jb.segment(e)}const rQ=/\p{Emoji_Presentation}/u,lQ=/\p{Regional_Indicator}/u,aQ=/\p{Extended_Pictographic}/u,uQ="️";function cQ(e){return rQ.test(e)||lQ.test(e)?!0:aQ.test(e)&&e.includes(uQ)}function yE(e){const t=iQ(e)?.[Symbol.iterator]().next().value;if(t===void 0||!cQ(t.segment))return{emoji:null,rest:e};const n=e.slice(t.index+t.segment.length).replace(/^\s+/,"");return{emoji:t.segment,rest:n}}function dQ(e,t){const{rest:n}=yE(e),o=t?.trim()??"";return o?n?`${o} ${n}`:o:n}const A3="/sessions/";function Qb(e){const{pathname:t}=e;if(!t.startsWith(A3))return;const n=t.slice(A3.length);if(!(!n||n.includes("/")))try{const o=decodeURIComponent(n);return o.length>0?o:void 0}catch{return}}function fQ(e){return e===void 0||e.length===0?"/":`${A3}${encodeURIComponent(e)}`}function kE(e){const t=!e.renaming&&(e.questionCount>0||e.pendingInteraction==="question"),n=!e.renaming&&(e.approvalCount>0||e.pendingInteraction==="approval"),o=!e.renaming&&!e.busy&&e.pendingInteraction!=="question"&&e.pendingInteraction!=="approval"&&e.questionCount===0&&e.approvalCount===0&&e.lastTurnReason==="failed",s=e.busy&&!t&&!n,i=e.busy||e.unread||t||n||o;return{showQuestionBadge:t,showApprovalBadge:n,showAbortedBadge:o,showBusySpinner:s,hasStatus:i}}const bE=[{name:"/new",desc:"commands.new.desc"},{name:"/clear",desc:"commands.clear.desc"},{name:"/login",desc:"commands.login.desc"},{name:"/plan",desc:"commands.plan.desc"},{name:"/swarm",desc:"commands.swarm.desc",acceptsInput:!0},{name:"/goal",desc:"commands.goal.desc",acceptsInput:!0},{name:"/btw",desc:"commands.btw.desc",acceptsInput:!0},{name:"/auto",desc:"commands.auto.desc"},{name:"/yolo",desc:"commands.yolo.desc"},{name:"/thinking",desc:"commands.thinking.desc"},{name:"/compact",desc:"commands.compact.desc",acceptsInput:!0},{name:"/undo",desc:"commands.undo.desc"},{name:"/fork",desc:"commands.fork.desc"},{name:"/export",desc:"commands.export.desc"},{name:"/status",desc:"commands.status.desc"}];function pQ(e){if(!e.startsWith("/"))return null;const t=e.indexOf(" ");return t===-1?{cmd:e,arg:""}:{cmd:e.slice(0,t),arg:e.slice(t+1)}}const Bm="skill:";function hQ(e){return e.startsWith(Bm)?e.slice(Bm.length):e}function CE(e=[]){const t=e.map(n=>({name:n.source==="builtin"?`/${n.name}`:`/${Bm}${n.name}`,desc:n.description,isSkill:!0,acceptsInput:!0}));return[...bE,...t]}function mQ(e,t=bE){const n=e.toLowerCase().trim().replace(/^\//,"");return n===""?t:t.map((o,s)=>{const i=o.name.toLowerCase().replace(/^\//,"");let r=0;return i===n?r=3:i.startsWith(n)?r=2:i.includes(n)&&(r=1),{item:o,index:s,score:r}}).filter(({score:o})=>o>0).sort((o,s)=>o.score!==s.score?s.score-o.score:o.index-s.index).map(({item:o})=>o)}function gQ(e,t){if(t.length===0||e.length===0)return t;const n=Date.parse(t[0].createdAt);if(Number.isNaN(n))return t;const o=new Set(t.map(r=>r.id)),s=new Set(t.flatMap(r=>r.role==="user"&&r.promptId!==void 0?[r.promptId]:[])),i=e.filter(r=>{const l=Date.parse(r.createdAt);return!(Number.isNaN(l)||l>=n||o.has(r.id)||r.role==="user"&&(r.userMessageId!==void 0&&o.has(r.userMessageId)||r.promptId!==void 0&&s.has(r.promptId)))});return i.length>0?[...i,...t]:t}function vQ(e){const t=new Map,n=new Set;function o(i){const r=t.get(i);if(r!==void 0)return r;const l=(async()=>e(i))().finally(()=>{t.delete(i),n.delete(i)&&o(i)});return t.set(i,l),l}function s(i){if(t.has(i)){n.add(i);return}o(i)}return{run:o,request:s}}const cn={permission:"kimi-web.permission",activeWorkspace:"kimi-active-workspace",planMode:"kimi-web.plan-mode",swarmMode:"kimi-web.swarm-mode",goalMode:"kimi-web.goal-mode",fontScale:"kimi-web.font-scale",starredModels:"kimi-web.starred-models",unread:"kimi-web.unread",onboarded:"kimi-web.onboarded",colorScheme:"kimi-web.color-scheme",hiddenWorkspaces:"kimi-web.hidden-workspaces",collapsedWorkspaces:"kimi-web.collapsed-workspaces",workspaceOrder:"kimi-web.workspace-order",pinnedSessions:"kimi-web.pinned-sessions",pinnedCollapsed:"kimi-web.pinned-collapsed",workspaceNameOverrides:"kimi-web.workspace-name-overrides",notifyEnabled:"kimi-web.notify-enabled",notifySound:"kimi-web.notify-sound",inputHistory:"kimi-web.input-history",locale:"kimi-locale",clientId:"kimi-web.client-id",debug:"kimi-web.debug",openInDefaultTarget:"kimi-web.open-in.default-target",openInLastTarget:"kimi-web.open-in.last-target",sidebarCollapsed:"kimi-web.sidebar-collapsed",sidebarWidth:"kimi-web.sidebar-width",sidebarViewMode:"kimi-web.sidebar-view-mode",shortcutOverrides:"kimi-web.shortcut-overrides",dockIconChoice:"kimi-web.dock-icon-choice",updateSkippedVersion:"kimi-web.update-skipped-version",codeFont:"kimi-web.code-font",contentAlign:"kimi-web.content-align",theme:"kimi-web.theme",thinking:"kimi-web.thinking",accent:"kimi-web.accent",notifyOnComplete:"kimi-web.notify-on-complete",notifyOnQuestion:"kimi-web.notify-on-question",notifyOnApproval:"kimi-web.notify-on-approval",soundOnComplete:"kimi-web.sound-on-complete"};function eC(e){return`kimi-web.draft.${e&&e.length>0?e:"__new__"}`}function ui(e){try{return globalThis.localStorage.getItem(e)}catch{return null}}function Ls(e,t){try{globalThis.localStorage.setItem(e,t)}catch{}}function ur(e){try{globalThis.localStorage.removeItem(e)}catch{}}function y1(e){const t=ui(e);if(t===null)return null;try{return JSON.parse(t)}catch{return null}}function Tc(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}function Ey(){const e=ui(cn.unread);if(!e)return{};try{const t=JSON.parse(e);if(!t||typeof t!="object")return{};const n={};for(const[o,s]of Object.entries(t))s===!0&&(n[o]=!0);return n}catch{return{}}}function Iy(e){const n={...Ey()};for(const[o,s]of Object.entries(e))s?n[o]=!0:delete n[o];Ls(cn.unread,JSON.stringify(n))}function yQ(){const e=y1(cn.collapsedWorkspaces);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function p9(e){Tc(cn.collapsedWorkspaces,Array.from(e))}function kQ(){return y1(cn.pinnedCollapsed)===!0}function M3(e){Tc(cn.pinnedCollapsed,e)}function bQ(){return ui(cn.sidebarViewMode)==="flat"?"flat":"grouped"}function CQ(e){Ls(cn.sidebarViewMode,e)}function wQ(){const e=y1(cn.workspaceOrder);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function wE(e){Tc(cn.workspaceOrder,Array.from(e))}function _E(){const e=y1(cn.pinnedSessions);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function k1(e){Tc(cn.pinnedSessions,Array.from(e))}function lh(){const e=y1(cn.workspaceNameOverrides);if(!e||typeof e!="object")return{};const t={};for(const[n,o]of Object.entries(e))typeof o=="string"&&(t[n]=o);return t}function tC(e){Tc(cn.workspaceNameOverrides,e)}function nC(e,t){const n=new Set(e.map(a=>a.id)),o=t.filter(a=>a.kind==="subagent"&&!n.has(a.id));if(o.length===0)return e;const s=new Map(e.map(a=>[a.id,a])),i=new Set,r=o.map(a=>{const u=a.backgroundTaskId!==void 0?s.get(a.backgroundTaskId):void 0;if(u===void 0)return a;i.add(u.id);const c=a.status==="running"&&u.status!=="running";return{...a,status:a.status==="running"?u.status:a.status,subagentPhase:c?u.status==="completed"?"completed":"failed":a.subagentPhase,completedAt:a.completedAt??u.completedAt,outputPreview:u.outputPreview??a.outputPreview,outputBytes:u.outputBytes??a.outputBytes,model:a.model??u.model,thinkingEffort:a.thinkingEffort??u.thinkingEffort}});return[...e.filter(a=>!i.has(a.id)),...r]}function _Q(e,t){if(e.length===0)return t;const n=new Map(t.map(r=>[r.id,r])),o=new Set(e.map(r=>r.id)),s=e.map(r=>{const l=n.get(r.id);return l?{...r,outputLines:l.outputLines,text:l.text,model:r.model??l.model,thinkingEffort:r.thinkingEffort??l.thinkingEffort}:r}),i=t.filter(r=>!o.has(r.id));return i.length===0?s:[...s,...i]}function xQ(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const e=navigator.userAgentData;return e?.platform==="macOS"||e?.platform==="iOS"}function SQ(e,t=xQ()){return(t?e.metaKey&&!e.ctrlKey:e.ctrlKey&&!e.metaKey)&&!e.altKey&&!e.shiftKey&&(e.code==="KeyF"||e.key.toLowerCase()==="f")&&!e.defaultPrevented}const AQ=new Map([["ς","σ"],["ß","ss"],["ſ","s"],["ff","ff"],["fi","fi"],["fl","fl"],["ffi","ffi"],["ffl","ffl"],["ſt","st"],["st","st"],["ʼn","ʼn"],["µ","μ"],["K","k"],["Å","å"],["Ω","ω"]]);function MQ(e){return e==="pre"||e==="pre-wrap"||e==="break-spaces"?"preserve":e==="pre-line"?"pre-line":"collapse"}function TQ(e,t){if(t==="preserve")return{text:e,map:Array.from({length:e.length},(r,l)=>l)};const n=t==="collapse"?/[\t\n\f\r ]/:/[\t ]/;let o="";const s=[];let i=!1;for(let r=0;r<e.length;r++)n.test(e[r])?i||(o+=" ",s.push(r),i=!0):(o+=e[r],s.push(r),i=!1);return{text:o,map:s}}function oC(e){let t="";const n=[];let o=0;for(const s of e){const i=s.toLowerCase(),r=AQ.get(i)??i;t+=r;for(let l=0;l<r.length;l++)n.push({start:o,length:s.length});o+=s.length}return{folded:t,map:n}}function*EQ(e,t){if(t.length===0||e.length===0)return;const n=e.map(c=>oC(c.text)),o="\0";let s="";const i=[];for(let c=0;c<e.length;c++)c>0&&e[c].gapBefore&&(s+=o),i[c]=s.length,s+=n[c].folded;const r=LQ(oC(t).folded);if(r===null)return;const l=new RegExp(r,"g");function a(c){let d=0,f=i.length-1,h=0;for(;d<=f;){const m=d+f>>1;i[m]<=c?(h=m,d=m+1):f=m-1}return h}let u;for(;;){const c=l.exec(s);if(c===null)return;const d=c.index,f=d+c[0].length-1,h=a(d),m=a(f),v=n[h].map[d-i[h]],k=n[m].map[f-i[m]],w={startSeg:h,startOffset:v.start,endSeg:m,endOffset:k.start+k.length};u!==void 0&&u.startSeg===w.startSeg&&u.startOffset===w.startOffset&&u.endSeg===w.endSeg&&u.endOffset===w.endOffset||(u=w,yield w)}}const IQ=/[.*+?^${}()|[\]\\]/g;function LQ(e){const t=[];let n=0;for(;n<e.length;){const o=/^\s+/.exec(e.slice(n));if(o!==null){t.push("\\s+"),n+=o[0].length;continue}const s=/^[^\s]+/.exec(e.slice(n));t.push(s[0].replaceAll(IQ,"\\$&")),n+=s[0].length}return t.length===0?null:t.join("")}const sC="script, style, noscript, template, [inert], .top-sentinel",$Q=new Set(["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","BR","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"]),NQ=new Set(["inline","inline-block","inline-flex","inline-grid","inline-table","contents","ruby"]);function FQ(e,t){const n=t.get(e);if(n!==void 0)return n;const o=$Q.has(e.tagName)||!NQ.has(getComputedStyle(e).display);return t.set(e,o),o}function RQ(e,t,n){let o=e.parentElement;for(;o!==null&&o!==t&&!FQ(o,n);)o=o.parentElement;return o??t}const OQ=1e3;function PQ(e,t){if(t.length===0)return{ranges:[],truncated:!1};const n=e.ownerDocument,o=n.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,{acceptNode(u){return u.nodeType===Node.ELEMENT_NODE?u.matches(sC)?NodeFilter.FILTER_REJECT:u.matches("br, hr, wbr")&&!u.closest(sC)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT}}),s=new WeakMap,i=new WeakMap,r=[];let l=!1;for(let u=o.nextNode();u!==null;u=o.nextNode()){if(u.nodeType===Node.ELEMENT_NODE){l=!0;continue}const c=u.nodeValue??"";if(c.length===0)continue;const d=u.parentElement;if(d===null)continue;let f=i.get(d);f===void 0&&(f=MQ(getComputedStyle(d).whiteSpace),i.set(d,f));let{text:h,map:m}=TQ(c,f);if(h.length===0)continue;const v=RQ(u,e,s),k=r.at(-1),w=l||k===void 0||k.block!==v;!w&&k.text.endsWith(" ")&&h.startsWith(" ")&&(h=h.slice(1),m=m.slice(1),h.length===0)||(r.push({text:h,gapBefore:w,node:u,block:v,wsMap:m}),l=!1)}const a=[];for(const u of EQ(r,t)){const c=r[u.startSeg],d=r[u.endSeg],f=n.createRange();if(f.setStart(c.node,c.wsMap[u.startOffset]),f.setEnd(d.node,d.wsMap[u.endOffset-1]+1),f.getClientRects().length!==0){if(a.length>=OQ)return{ranges:a,truncated:!0};a.push(f)}}return{ranges:a,truncated:!1}}const xE="kimi-transcript-search",T3="kimi-transcript-search-current";function SE(){return globalThis.CSS?.highlights??null}function h9(e,t){const n=SE(),o=globalThis.Highlight;if(!n||!o)return;if(e.length===0){E3();return}const s=new o;for(const r of e)s.add(r);n.set(xE,s);const i=e[t];if(i!==void 0){const r=new o;r.add(i),n.set(T3,r)}else n.delete(T3)}function E3(){const e=SE();e?.delete(xE),e?.delete(T3)}function DQ(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const e=navigator.userAgentData;return e?.platform==="macOS"||e?.platform==="iOS"}function BQ(e,t=DQ()){return(t?e.metaKey&&!e.ctrlKey:e.ctrlKey&&!e.metaKey)&&!e.altKey&&!e.shiftKey&&(e.code==="KeyA"||e.key.toLowerCase()==="a")&&!e.defaultPrevented}function HQ(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement&&(e.isContentEditable||e.closest("input, textarea")!==null)}function zQ(e,t){return typeof Element>"u"||!(e instanceof Element)?null:e.closest(t)}function iC(e){e.ownerDocument.getSelection()?.selectAllChildren(e)}const WQ=`https://www.kimi.com/code?from=${Wp?"kimi_code_desktop":"kimi_code_web"}`;function jp(){window.open(WQ,"_blank","noopener")}function UQ(e,t){if(e.length===0)return null;const n=new Set(e),o=t.filter(i=>n.has(i)),s=e.filter(i=>!t.includes(i));return s.length===0&&o.length===t.length?null:[...s,...o]}function jQ(e,t){const n=new Map(t.map((o,s)=>[o,s]));return e.toSorted((o,s)=>(n.get(o.id)??-1)-(n.get(s.id)??-1))}function AE(e,t,n,o="before"){const s=e.indexOf(t),i=e.indexOf(n);if(s===-1||i===-1||s===i)return e;const r=[...e];r.splice(s,1);const l=s<i?i-1:i,a=o==="before"?l:l+1;return r.splice(a,0,t),r}const VQ=5;function qQ(e,t,n,o=VQ){if(e.length<=o)return e;const s=e.slice(0,o);if(t&&!s.some(i=>i.id===t)){const i=e.find(r=>r.id===t);i&&(s[o-1]=i)}return s}const KQ={class:"sd-body"},ZQ={class:"sd-search"},GQ=["aria-label"],YQ=["aria-selected","onClick","onMousemove"],XQ={class:"sd-meta"},JQ=["innerHTML"],QQ={class:"sd-time"},eee=["innerHTML"],tee=["innerHTML"],nee={key:1,class:"sd-empty"},oee={class:"sd-foot","aria-hidden":"true"},see={class:"sd-hint"},iee={class:"sd-hint"},ree={class:"sd-hint"},lee=200,aee=et({__name:"SearchSessionsDialog",props:{sessions:{},activeId:{}},emits:["select","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z(!0),r=Z(""),l=Z(null),a=Z(null),u=R(()=>{const S=r.value.trim().toLowerCase(),T=[];for(const A of o.sessions){const E=A.title??"",P=A.lastPrompt??"",D=A.workspaceName??"",I=S.length>0&&E.toLowerCase().includes(S),$=S.length>0&&P.toLowerCase().includes(S),B=S.length>0&&D.toLowerCase().includes(S);if(!(S.length>0&&!I&&!$&&!B)&&(T.push({session:A,inTitle:I,inWorkspace:B,snippetText:P?KJ(P,r.value):""}),T.length>=lee))break}return T}),c=Z(0);Je(r,()=>{c.value=0});function d(S){const T=u.value.length;return T===0?0:Math.max(0,Math.min(T-1,S))}async function f(){await yt(),a.value?.querySelector('[aria-selected="true"]')?.scrollIntoView({block:"nearest"})}function h(S){c.value=d(c.value+S),f()}function m(S){s("select",S),s("close")}function v(){r.value="",l.value?.focus()}function k(){const S=u.value[c.value];S&&m(S.session.id)}function w(){return l.value?.el??null}const{handleCompositionStart:b,handleCompositionEnd:_,isComposingKeyEvent:g}=Ar();function x(S){if(g(S)){S.key==="Escape"&&S.stopPropagation();return}S.key==="ArrowDown"?(S.preventDefault(),h(1)):S.key==="ArrowUp"?(S.preventDefault(),h(-1)):S.key==="Enter"&&(S.preventDefault(),k())}return dn(()=>{l.value?.focus()}),(S,T)=>(y(),he(p(ua),{open:i.value,"onUpdate:open":T[1]||(T[1]=A=>i.value=A),title:p(n)("sidebar.searchPlaceholder"),size:"lg",height:"fixed",padded:!1,"initial-focus":w,onClose:T[2]||(T[2]=A=>s("close"))},{default:me(()=>[C("div",KQ,[C("div",ZQ,[j(p(js),{ref_key:"inputRef",ref:l,modelValue:r.value,"onUpdate:modelValue":T[0]||(T[0]=A=>r.value=A),placeholder:p(n)("sidebar.searchPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:x,onCompositionstart:p(b),onCompositionend:p(_)},null,8,["modelValue","placeholder","onCompositionstart","onCompositionend"]),j(p(pn),{text:p(n)("sidebar.searchClear")},{default:me(()=>[C("button",{type:"button",class:Re(["search-clear",{"is-on":r.value.length>0}]),tabindex:"-1","aria-label":p(n)("sidebar.searchClear"),onClick:v},[j(p(Te),{name:"close",size:"sm"})],10,GQ)]),_:1},8,["text"])]),C("div",{ref_key:"listRef",ref:a,class:"sd-list",role:"listbox"},[u.value.length>0?(y(!0),M(Pe,{key:0},pt(u.value,(A,E)=>(y(),M("button",{key:A.session.id,class:Re(["sd-row",{on:E===c.value,active:A.session.id===e.activeId}]),role:"option","aria-selected":E===c.value,onClick:P=>m(A.session.id),onMousemove:P=>c.value=E},[C("span",XQ,[j(p(Te),{class:"sd-folder",name:"folder-closed",size:"sm"}),C("span",{class:"sd-ws",innerHTML:p(f9)(A.session.workspaceName??A.session.workspaceId??"",A.inWorkspace?r.value:"")},null,8,JQ),C("span",QQ,N(A.session.time),1)]),C("span",{class:"sd-title",innerHTML:p(f9)(A.session.title,A.inTitle?r.value:"")},null,8,eee),A.snippetText?(y(),M("span",{key:0,class:"sd-snippet",innerHTML:p(f9)(A.snippetText,r.value)},null,8,tee)):ee("",!0)],42,YQ))),128)):(y(),M("div",nee,[j(p(SW),{title:r.value.trim()?p(n)("sidebar.searchNoResults"):p(n)("sidebar.searchEmpty")},{icon:me(()=>[j(p(Te),{name:"search",size:"lg"})]),_:1},8,["title"])]))],512),C("div",oee,[C("span",see,[j(p(oa),{keys:["↑","↓"]}),qe(N(p(n)("sidebar.searchHintSelect")),1)]),T[3]||(T[3]=C("span",{class:"sd-dot"},"·",-1)),C("span",iee,[j(p(oa),{keys:["Enter"]}),qe(N(p(n)("sidebar.searchHintOpen")),1)]),T[4]||(T[4]=C("span",{class:"sd-dot"},"·",-1)),C("span",ree,[j(p(oa),{keys:["Esc"]}),qe(N(p(n)("sidebar.searchHintClose")),1)])])])]),_:1},8,["open","title"]))}}),uee=ft(aee,[["__scopeId","data-v-d69c7a8c"]]);var cee=Object.create,Ly=Object.defineProperty,dee=Object.getOwnPropertyDescriptor,ME=Object.getOwnPropertyNames,fee=Object.getPrototypeOf,pee=Object.prototype.hasOwnProperty,TE=(e,t)=>function(){return t||(0,e[ME(e)[0]])((t={exports:{}}).exports,t),t.exports},EE=e=>{let t={};for(var n in e)Ly(t,n,{get:e[n],enumerable:!0});return t},hee=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(var s=ME(t),i=0,r=s.length,l;i<r;i++)l=s[i],!pee.call(e,l)&&l!==n&&Ly(e,l,{get:(a=>t[a]).bind(null,l),enumerable:!(o=dee(t,l))||o.enumerable});return e},IE=(e,t,n)=>(n=e!=null?cee(fee(e)):{},hee(Ly(n,"default",{value:e,enumerable:!0}),e));function mee(e,t,n,o){const s=Number(e[t].meta.id+1).toString();let i="";return typeof o.docId=="string"&&(i=`-${o.docId}-`),i+s}function gee(e,t){let n=Number(e[t].meta.id+1).toString();return e[t].meta.subId>0&&(n+=`:${e[t].meta.subId}`),`[${n}]`}function vee(e,t,n,o,s){const i=s.rules.footnote_anchor_name(e,t,n,o,s),r=s.rules.footnote_caption(e,t,n,o,s);let l=i;return e[t].meta.subId>0&&(l+=`:${e[t].meta.subId}`),`<sup class="footnote-ref"><a href="#fn${i}" id="fnref${l}">${r}</a></sup>`}function yee(e,t,n){return(n.xhtmlOut?`<hr class="footnotes-sep" /> +`:`<hr class="footnotes-sep"> +`)+`<section class="footnotes"> +<ol class="footnotes-list"> +`}function kee(){return`</ol> +</section> +`}function bee(e,t,n,o,s){let i=s.rules.footnote_anchor_name(e,t,n,o,s);return e[t].meta.subId>0&&(i+=`:${e[t].meta.subId}`),`<li id="fn${i}" class="footnote-item">`}function Cee(){return`</li> +`}function wee(e,t,n,o,s){let i=s.rules.footnote_anchor_name(e,t,n,o,s);return e[t].meta.subId>0&&(i+=`:${e[t].meta.subId}`),` <a href="#fnref${i}" class="footnote-backref">↩︎</a>`}function _ee(e){const t=e.helpers.parseLinkLabel,n=e.utils.isSpace;e.renderer.rules.footnote_ref=vee,e.renderer.rules.footnote_block_open=yee,e.renderer.rules.footnote_block_close=kee,e.renderer.rules.footnote_open=bee,e.renderer.rules.footnote_close=Cee,e.renderer.rules.footnote_anchor=wee,e.renderer.rules.footnote_caption=gee,e.renderer.rules.footnote_anchor_name=mee;function o(l,a,u,c){const d=l.bMarks[a]+l.tShift[a],f=l.eMarks[a];if(d+4>f||l.src.charCodeAt(d)!==91||l.src.charCodeAt(d+1)!==94)return!1;let h;for(h=d+2;h<f;h++){if(l.src.charCodeAt(h)===32)return!1;if(l.src.charCodeAt(h)===93)break}if(h===d+2||h+1>=f||l.src.charCodeAt(++h)!==58)return!1;if(c)return!0;h++,l.env.footnotes||(l.env.footnotes={}),l.env.footnotes.refs||(l.env.footnotes.refs={});const m=l.src.slice(d+2,h-2);l.env.footnotes.refs[`:${m}`]=-1;const v=new l.Token("footnote_reference_open","",1);v.meta={label:m},v.level=l.level++,l.tokens.push(v);const k=l.bMarks[a],w=l.tShift[a],b=l.sCount[a],_=l.parentType,g=h,x=l.sCount[a]+h-(l.bMarks[a]+l.tShift[a]);let S=x;for(;h<f;){const A=l.src.charCodeAt(h);if(n(A))A===9?S+=4-S%4:S++;else break;h++}l.tShift[a]=h-g,l.sCount[a]=S-x,l.bMarks[a]=g,l.blkIndent+=4,l.parentType="footnote",l.sCount[a]<l.blkIndent&&(l.sCount[a]+=l.blkIndent),l.md.block.tokenize(l,a,u,!0),l.parentType=_,l.blkIndent-=4,l.tShift[a]=w,l.sCount[a]=b,l.bMarks[a]=k;const T=new l.Token("footnote_reference_close","",-1);return T.level=--l.level,l.tokens.push(T),!0}function s(l,a){const u=l.posMax,c=l.pos;if(c+2>=u||l.src.charCodeAt(c)!==94||l.src.charCodeAt(c+1)!==91)return!1;const d=c+2,f=t(l,c+1);if(f<0)return!1;if(!a){l.env.footnotes||(l.env.footnotes={}),l.env.footnotes.list||(l.env.footnotes.list=[]);const h=l.env.footnotes.list.length,m=[];l.md.inline.parse(l.src.slice(d,f),l.md,l.env,m);const v=l.push("footnote_ref","",0);v.meta={id:h},l.env.footnotes.list[h]={content:l.src.slice(d,f),tokens:m}}return l.pos=f+1,l.posMax=u,!0}function i(l,a){const u=l.posMax,c=l.pos;if(c+3>u||!l.env.footnotes||!l.env.footnotes.refs||l.src.charCodeAt(c)!==91||l.src.charCodeAt(c+1)!==94)return!1;let d;for(d=c+2;d<u;d++){if(l.src.charCodeAt(d)===32||l.src.charCodeAt(d)===10)return!1;if(l.src.charCodeAt(d)===93)break}if(d===c+2||d>=u)return!1;d++;const f=l.src.slice(c+2,d-1);if(typeof l.env.footnotes.refs[`:${f}`]>"u")return!1;if(!a){l.env.footnotes.list||(l.env.footnotes.list=[]);let h;l.env.footnotes.refs[`:${f}`]<0?(h=l.env.footnotes.list.length,l.env.footnotes.list[h]={label:f,count:0},l.env.footnotes.refs[`:${f}`]=h):h=l.env.footnotes.refs[`:${f}`];const m=l.env.footnotes.list[h].count;l.env.footnotes.list[h].count++;const v=l.push("footnote_ref","",0);v.meta={id:h,subId:m,label:f}}return l.pos=d,l.posMax=u,!0}function r(l){let a,u,c,d=!1;const f={};if(!l.env.footnotes||(l.tokens=l.tokens.filter(function(m){return m.type==="footnote_reference_open"?(d=!0,u=[],c=m.meta.label,!1):m.type==="footnote_reference_close"?(d=!1,f[":"+c]=u,!1):(d&&u.push(m),!d)}),!l.env.footnotes.list))return;const h=l.env.footnotes.list;l.tokens.push(new l.Token("footnote_block_open","",1));for(let m=0,v=h.length;m<v;m++){const k=new l.Token("footnote_open","",1);if(k.meta={id:m,label:h[m].label},l.tokens.push(k),h[m].tokens){a=[];const _=new l.Token("paragraph_open","p",1);_.block=!0,a.push(_);const g=new l.Token("inline","",0);g.children=h[m].tokens,g.content=h[m].content,a.push(g);const x=new l.Token("paragraph_close","p",-1);x.block=!0,a.push(x)}else h[m].label&&(a=f[`:${h[m].label}`]);a&&(l.tokens=l.tokens.concat(a));let w;l.tokens[l.tokens.length-1].type==="paragraph_close"?w=l.tokens.pop():w=null;const b=h[m].count>0?h[m].count:1;for(let _=0;_<b;_++){const g=new l.Token("footnote_anchor","",0);g.meta={id:m,subId:_,label:h[m].label},l.tokens.push(g)}w&&l.tokens.push(w),l.tokens.push(new l.Token("footnote_close","",-1))}l.tokens.push(new l.Token("footnote_block_close","",-1))}e.block.ruler.before("reference","footnote_def",o,{alt:["paragraph","reference"]}),e.inline.ruler.after("image","footnote_inline",s),e.inline.ruler.after("footnote_inline","footnote_ref",i),e.core.ruler.after("inline","footnote_tail",r)}function xee(e){function t(o,s){const i=o.pos,r=o.src.charCodeAt(i);if(s||r!==43)return!1;const l=o.scanDelims(o.pos,!0);let a=l.length;const u=String.fromCharCode(r);if(a<2)return!1;if(a%2){const c=o.push("text","",0);c.content=u,a--}for(let c=0;c<a;c+=2){const d=o.push("text","",0);d.content=u+u,!(!l.can_open&&!l.can_close)&&o.delimiters.push({marker:r,length:0,jump:c/2,token:o.tokens.length-1,end:-1,open:l.can_open,close:l.can_close})}return o.pos+=l.length,!0}function n(o,s){let i;const r=[],l=s.length;for(let a=0;a<l;a++){const u=s[a];if(u.marker!==43||u.end===-1)continue;const c=s[u.end];i=o.tokens[u.token],i.type="ins_open",i.tag="ins",i.nesting=1,i.markup="++",i.content="",i=o.tokens[c.token],i.type="ins_close",i.tag="ins",i.nesting=-1,i.markup="++",i.content="",o.tokens[c.token-1].type==="text"&&o.tokens[c.token-1].content==="+"&&r.push(c.token-1)}for(;r.length;){const a=r.pop();let u=a+1;for(;u<o.tokens.length&&o.tokens[u].type==="ins_close";)u++;u--,a!==u&&(i=o.tokens[u],o.tokens[u]=o.tokens[a],o.tokens[a]=i)}}e.inline.ruler.before("emphasis","ins",t),e.inline.ruler2.before("emphasis","ins",function(o){const s=o.tokens_meta,i=(o.tokens_meta||[]).length;n(o,o.delimiters);for(let r=0;r<i;r++)s[r]&&s[r].delimiters&&n(o,s[r].delimiters)})}function See(e){function t(o,s){const i=o.pos,r=o.src.charCodeAt(i);if(s||r!==61)return!1;const l=o.scanDelims(o.pos,!0);let a=l.length;const u=String.fromCharCode(r);if(a<2)return!1;if(a%2){const c=o.push("text","",0);c.content=u,a--}for(let c=0;c<a;c+=2){const d=o.push("text","",0);d.content=u+u,!(!l.can_open&&!l.can_close)&&o.delimiters.push({marker:r,length:0,jump:c/2,token:o.tokens.length-1,end:-1,open:l.can_open,close:l.can_close})}return o.pos+=l.length,!0}function n(o,s){const i=[],r=s.length;for(let l=0;l<r;l++){const a=s[l];if(a.marker!==61||a.end===-1)continue;const u=s[a.end],c=o.tokens[a.token];c.type="mark_open",c.tag="mark",c.nesting=1,c.markup="==",c.content="";const d=o.tokens[u.token];d.type="mark_close",d.tag="mark",d.nesting=-1,d.markup="==",d.content="",o.tokens[u.token-1].type==="text"&&o.tokens[u.token-1].content==="="&&i.push(u.token-1)}for(;i.length;){const l=i.pop();let a=l+1;for(;a<o.tokens.length&&o.tokens[a].type==="mark_close";)a++;if(a--,l!==a){const u=o.tokens[a];o.tokens[a]=o.tokens[l],o.tokens[l]=u}}}e.inline.ruler.before("emphasis","mark",t),e.inline.ruler2.before("emphasis","mark",function(o){let s;const i=o.tokens_meta,r=(o.tokens_meta||[]).length;for(n(o,o.delimiters),s=0;s<r;s++)i[s]&&i[s].delimiters&&n(o,i[s].delimiters)})}const Aee=/\\([ \\!"#$%&'()*+,./:;<=>?@[\]^_`{|}~-])/g;function Mee(e,t){const n=e.posMax,o=e.pos;if(e.src.charCodeAt(o)!==126||t||o+2>=n)return!1;e.pos=o+1;let s=!1;for(;e.pos<n;){if(e.src.charCodeAt(e.pos)===126){s=!0;break}e.md.inline.skipToken(e)}if(!s||o+1===e.pos)return e.pos=o,!1;const i=e.src.slice(o+1,e.pos);if(i.match(/(^|[^\\])(\\\\)*\s/))return e.pos=o,!1;e.posMax=e.pos,e.pos=o+1;const r=e.push("sub_open","sub",1);r.markup="~";const l=e.push("text","",0);l.content=i.replace(Aee,"$1");const a=e.push("sub_close","sub",-1);return a.markup="~",e.pos=e.posMax+1,e.posMax=n,!0}function Tee(e){e.inline.ruler.after("emphasis","sub",Mee)}const Eee=/\\([ \\!"#$%&'()*+,./:;<=>?@[\]^_`{|}~-])/g;function Iee(e,t){const n=e.posMax,o=e.pos;if(e.src.charCodeAt(o)!==94||t||o+2>=n)return!1;e.pos=o+1;let s=!1;for(;e.pos<n;){if(e.src.charCodeAt(e.pos)===94){s=!0;break}e.md.inline.skipToken(e)}if(!s||o+1===e.pos)return e.pos=o,!1;const i=e.src.slice(o+1,e.pos);if(i.match(/(^|[^\\])(\\\\)*\s/))return e.pos=o,!1;e.posMax=e.pos,e.pos=o+1;const r=e.push("sup_open","sup",1);r.markup="^";const l=e.push("text","",0);l.content=i.replace(Eee,"$1");const a=e.push("sup_close","sup",-1);return a.markup="^",e.pos=e.posMax+1,e.posMax=n,!0}function Lee(e){e.inline.ruler.after("emphasis","sup",Iee)}var $ee=TE({"../../node_modules/.pnpm/markdown-it-task-checkbox@1.0.6/node_modules/markdown-it-task-checkbox/index.js":((e,t)=>{t.exports=function(v,k){k=Object.assign({},{disabled:!0,divWrap:!1,divClass:"checkbox",idPrefix:"cbx_",ulClass:"task-list",liClass:"task-list-item"},k),v.core.ruler.after("inline","github-task-lists",function(w){for(var b=w.tokens,_=0,g=2;g<b.length;g++)s(b,g)&&(i(b[g],_,k,w.Token),_+=1,n(b[g-2],"class",k.liClass),n(b[o(b,g-2)],"class",k.ulClass))})};function n(v,k,w){var b=v.attrIndex(k),_=[k,w];b<0?v.attrPush(_):v.attrs[b]=_}function o(v,k){for(var w=v[k].level-1,b=k-1;b>=0;b--)if(v[b].level===w)return b;return-1}function s(v,k){return d(v[k])&&f(v[k-1])&&h(v[k-2])&&m(v[k])}function i(v,k,w,b){var _=w.idPrefix+k;v.children[0].content=v.children[0].content.slice(3),v.children.unshift(l(_,b)),v.children.push(a(b)),v.children.unshift(r(v,_,w,b)),w.divWrap&&(v.children.unshift(u(w,b)),v.children.push(c(b)))}function r(v,k,w,b){var _=new b("checkbox_input","input",0);return _.attrs=[["type","checkbox"],["id",k]],/^\[[xX]\][ \u00A0]/.test(v.content)===!0&&_.attrs.push(["checked","true"]),w.disabled===!0&&_.attrs.push(["disabled","true"]),_}function l(v,k){var w=new k("label_open","label",1);return w.attrs=[["for",v]],w}function a(v){return new v("label_close","label",-1)}function u(v,k){var w=new k("checkbox_open","div",0);return w.attrs=[["class",v.divClass]],w}function c(v){return new v("checkbox_close","div",-1)}function d(v){return v.type==="inline"}function f(v){return v.type==="paragraph_open"}function h(v){return v.type==="list_item_open"}function m(v){return/^\[[xX \u00A0]\][ \u00A0]/.test(v.content)}})}),Nee=new Uint16Array('ᵁ<Õıʊҝջאٵ۞ޢߖࠏ੊ઑඡ๭༉༦჊ረዡᐕᒝᓃᓟᔥ\0\0\0\0\0\0ᕫᛍᦍᰒᷝ὾⁠↰⊍⏀⏻⑂⠤⤒ⴈ⹈⿎〖㊺㘹㞬㣾㨨㩱㫠㬮ࠀEMabcfglmnoprstu\\bfms„‹•˜¦³¹ÈÏlig耻Æ䃆P耻&䀦cute耻Á䃁reve;䄂Āiyx}rc耻Â䃂;䐐r;쀀𝔄rave耻À䃀pha;䎑acr;䄀d;橓Āgp¡on;䄄f;쀀𝔸plyFunction;恡ing耻Å䃅Ācs¾Ãr;쀀𝒜ign;扔ilde耻Ã䃃ml耻Ä䃄ЀaceforsuåûþėĜĢħĪĀcrêòkslash;或Ŷöø;櫧ed;挆y;䐑ƀcrtąċĔause;戵noullis;愬a;䎒r;쀀𝔅pf;쀀𝔹eve;䋘còēmpeq;扎܀HOacdefhilorsuōőŖƀƞƢƵƷƺǜȕɳɸɾcy;䐧PY耻©䂩ƀcpyŝŢźute;䄆Ā;iŧŨ拒talDifferentialD;慅leys;愭ȀaeioƉƎƔƘron;䄌dil耻Ç䃇rc;䄈nint;戰ot;䄊ĀdnƧƭilla;䂸terDot;䂷òſi;䎧rcleȀDMPTLJNjǑǖot;抙inus;抖lus;投imes;抗oĀcsǢǸkwiseContourIntegral;戲eCurlyĀDQȃȏoubleQuote;思uote;怙ȀlnpuȞȨɇɕonĀ;eȥȦ户;橴ƀgitȯȶȺruent;扡nt;戯ourIntegral;戮ĀfrɌɎ;愂oduct;成nterClockwiseContourIntegral;戳oss;樯cr;쀀𝒞pĀ;Cʄʅ拓ap;才րDJSZacefiosʠʬʰʴʸˋ˗ˡ˦̳ҍĀ;oŹʥtrahd;椑cy;䐂cy;䐅cy;䐏ƀgrsʿ˄ˇger;怡r;憡hv;櫤Āayː˕ron;䄎;䐔lĀ;t˝˞戇a;䎔r;쀀𝔇Āaf˫̧Ācm˰̢riticalȀADGT̖̜̀̆cute;䂴oŴ̋̍;䋙bleAcute;䋝rave;䁠ilde;䋜ond;拄ferentialD;慆Ѱ̽\0\0\0͔͂\0Ѕf;쀀𝔻ƀ;DE͈͉͍䂨ot;惜qual;扐blèCDLRUVͣͲ΂ϏϢϸontourIntegraìȹoɴ͹\0\0ͻ»͉nArrow;懓Āeo·ΤftƀARTΐΖΡrrow;懐ightArrow;懔eåˊngĀLRΫτeftĀARγιrrow;柸ightArrow;柺ightArrow;柹ightĀATϘϞrrow;懒ee;抨pɁϩ\0\0ϯrrow;懑ownArrow;懕erticalBar;戥ǹABLRTaВЪаўѿͼrrowƀ;BUНОТ憓ar;椓pArrow;懵reve;䌑eft˒к\0ц\0ѐightVector;楐eeVector;楞ectorĀ;Bљњ憽ar;楖ightǔѧ\0ѱeeVector;楟ectorĀ;BѺѻ懁ar;楗eeĀ;A҆҇护rrow;憧ĀctҒҗr;쀀𝒟rok;䄐ࠀNTacdfglmopqstuxҽӀӄӋӞӢӧӮӵԡԯԶՒ՝ՠեG;䅊H耻Ð䃐cute耻É䃉ƀaiyӒӗӜron;䄚rc耻Ê䃊;䐭ot;䄖r;쀀𝔈rave耻È䃈ement;戈ĀapӺӾcr;䄒tyɓԆ\0\0ԒmallSquare;旻erySmallSquare;斫ĀgpԦԪon;䄘f;쀀𝔼silon;䎕uĀaiԼՉlĀ;TՂՃ橵ilde;扂librium;懌Āci՗՚r;愰m;橳a;䎗ml耻Ë䃋Āipժկsts;戃onentialE;慇ʀcfiosօֈ֍ֲ׌y;䐤r;쀀𝔉lledɓ֗\0\0֣mallSquare;旼erySmallSquare;斪Ͱֺ\0ֿ\0\0ׄf;쀀𝔽All;戀riertrf;愱cò׋؀JTabcdfgorstר׬ׯ׺؀ؒؖ؛؝أ٬ٲcy;䐃耻>䀾mmaĀ;d׷׸䎓;䏜reve;䄞ƀeiy؇،ؐdil;䄢rc;䄜;䐓ot;䄠r;쀀𝔊;拙pf;쀀𝔾eater̀EFGLSTصلَٖٛ٦qualĀ;Lؾؿ扥ess;招ullEqual;执reater;檢ess;扷lantEqual;橾ilde;扳cr;쀀𝒢;扫ЀAacfiosuڅڋږڛڞڪھۊRDcy;䐪Āctڐڔek;䋇;䁞irc;䄤r;愌lbertSpace;愋ǰگ\0ڲf;愍izontalLine;攀Āctۃۅòکrok;䄦mpńېۘownHumðįqual;扏܀EJOacdfgmnostuۺ۾܃܇܎ܚܞܡܨ݄ݸދޏޕcy;䐕lig;䄲cy;䐁cute耻Í䃍Āiyܓܘrc耻Î䃎;䐘ot;䄰r;愑rave耻Ì䃌ƀ;apܠܯܿĀcgܴܷr;䄪inaryI;慈lieóϝǴ݉\0ݢĀ;eݍݎ戬Āgrݓݘral;戫section;拂isibleĀCTݬݲomma;恣imes;恢ƀgptݿރވon;䄮f;쀀𝕀a;䎙cr;愐ilde;䄨ǫޚ\0ޞcy;䐆l耻Ï䃏ʀcfosuެ޷޼߂ߐĀiyޱ޵rc;䄴;䐙r;쀀𝔍pf;쀀𝕁ǣ߇\0ߌr;쀀𝒥rcy;䐈kcy;䐄΀HJacfosߤߨ߽߬߱ࠂࠈcy;䐥cy;䐌ppa;䎚Āey߶߻dil;䄶;䐚r;쀀𝔎pf;쀀𝕂cr;쀀𝒦րJTaceflmostࠥࠩࠬࡐࡣ঳সে্਷ੇcy;䐉耻<䀼ʀcmnpr࠷࠼ࡁࡄࡍute;䄹bda;䎛g;柪lacetrf;愒r;憞ƀaeyࡗ࡜ࡡron;䄽dil;䄻;䐛Āfsࡨ॰tԀACDFRTUVarࡾࢩࢱࣦ࣠ࣼयज़ΐ४Ānrࢃ࢏gleBracket;柨rowƀ;BR࢙࢚࢞憐ar;懤ightArrow;懆eiling;挈oǵࢷ\0ࣃbleBracket;柦nǔࣈ\0࣒eeVector;楡ectorĀ;Bࣛࣜ懃ar;楙loor;挊ightĀAV࣯ࣵrrow;憔ector;楎Āerँगeƀ;AVउऊऐ抣rrow;憤ector;楚iangleƀ;BEतथऩ抲ar;槏qual;抴pƀDTVषूौownVector;楑eeVector;楠ectorĀ;Bॖॗ憿ar;楘ectorĀ;B॥०憼ar;楒ightáΜs̀EFGLSTॾঋকঝঢভqualGreater;拚ullEqual;扦reater;扶ess;檡lantEqual;橽ilde;扲r;쀀𝔏Ā;eঽা拘ftarrow;懚idot;䄿ƀnpw৔ਖਛgȀLRlr৞৷ਂਐeftĀAR০৬rrow;柵ightArrow;柷ightArrow;柶eftĀarγਊightáοightáϊf;쀀𝕃erĀLRਢਬeftArrow;憙ightArrow;憘ƀchtਾੀੂòࡌ;憰rok;䅁;扪Ѐacefiosuਗ਼੝੠੷੼અઋ઎p;椅y;䐜Ādl੥੯iumSpace;恟lintrf;愳r;쀀𝔐nusPlus;戓pf;쀀𝕄cò੶;䎜ҀJacefostuણધભીଔଙඑ඗ඞcy;䐊cute;䅃ƀaey઴હાron;䅇dil;䅅;䐝ƀgswે૰଎ativeƀMTV૓૟૨ediumSpace;怋hiĀcn૦૘ë૙eryThiî૙tedĀGL૸ଆreaterGreateòٳessLesóੈLine;䀊r;쀀𝔑ȀBnptଢନଷ଺reak;恠BreakingSpace;䂠f;愕ڀ;CDEGHLNPRSTV୕ୖ୪୼஡௫ఄ౞಄ದ೘ൡඅ櫬Āou୛୤ngruent;扢pCap;扭oubleVerticalBar;戦ƀlqxஃஊ஛ement;戉ualĀ;Tஒஓ扠ilde;쀀≂̸ists;戄reater΀;EFGLSTஶஷ஽௉௓௘௥扯qual;扱ullEqual;쀀≧̸reater;쀀≫̸ess;批lantEqual;쀀⩾̸ilde;扵umpń௲௽ownHump;쀀≎̸qual;쀀≏̸eĀfsఊధtTriangleƀ;BEచఛడ拪ar;쀀⧏̸qual;括s̀;EGLSTవశ఼ౄోౘ扮qual;扰reater;扸ess;쀀≪̸lantEqual;쀀⩽̸ilde;扴estedĀGL౨౹reaterGreater;쀀⪢̸essLess;쀀⪡̸recedesƀ;ESಒಓಛ技qual;쀀⪯̸lantEqual;拠ĀeiಫಹverseElement;戌ghtTriangleƀ;BEೋೌ೒拫ar;쀀⧐̸qual;拭ĀquೝഌuareSuĀbp೨೹setĀ;E೰ೳ쀀⊏̸qual;拢ersetĀ;Eഃആ쀀⊐̸qual;拣ƀbcpഓതൎsetĀ;Eഛഞ쀀⊂⃒qual;抈ceedsȀ;ESTലള഻െ抁qual;쀀⪰̸lantEqual;拡ilde;쀀≿̸ersetĀ;E൘൛쀀⊃⃒qual;抉ildeȀ;EFT൮൯൵ൿ扁qual;扄ullEqual;扇ilde;扉erticalBar;戤cr;쀀𝒩ilde耻Ñ䃑;䎝܀Eacdfgmoprstuvලෂ෉෕ෛ෠෧෼ขภยา฿ไlig;䅒cute耻Ó䃓Āiy෎ීrc耻Ô䃔;䐞blac;䅐r;쀀𝔒rave耻Ò䃒ƀaei෮ෲ෶cr;䅌ga;䎩cron;䎟pf;쀀𝕆enCurlyĀDQฎบoubleQuote;怜uote;怘;橔Āclวฬr;쀀𝒪ash耻Ø䃘iŬื฼de耻Õ䃕es;樷ml耻Ö䃖erĀBP๋๠Āar๐๓r;怾acĀek๚๜;揞et;掴arenthesis;揜Ҁacfhilors๿ງຊຏຒດຝະ໼rtialD;戂y;䐟r;쀀𝔓i;䎦;䎠usMinus;䂱Āipຢອncareplanåڝf;愙Ȁ;eio຺ູ໠໤檻cedesȀ;EST່້໏໚扺qual;檯lantEqual;扼ilde;找me;怳Ādp໩໮uct;戏ortionĀ;aȥ໹l;戝Āci༁༆r;쀀𝒫;䎨ȀUfos༑༖༛༟OT耻"䀢r;쀀𝔔pf;愚cr;쀀𝒬؀BEacefhiorsu༾གྷཇའཱིྦྷྪྭ႖ႩႴႾarr;椐G耻®䂮ƀcnrཎནབute;䅔g;柫rĀ;tཛྷཝ憠l;椖ƀaeyཧཬཱron;䅘dil;䅖;䐠Ā;vླྀཹ愜erseĀEUྂྙĀlq྇ྎement;戋uilibrium;懋pEquilibrium;楯r»ཹo;䎡ghtЀACDFTUVa࿁࿫࿳ဢဨၛႇϘĀnr࿆࿒gleBracket;柩rowƀ;BL࿜࿝࿡憒ar;懥eftArrow;懄eiling;按oǵ࿹\0စbleBracket;柧nǔည\0နeeVector;楝ectorĀ;Bဝသ懂ar;楕loor;挋Āerိ၃eƀ;AVဵံြ抢rrow;憦ector;楛iangleƀ;BEၐၑၕ抳ar;槐qual;抵pƀDTVၣၮၸownVector;楏eeVector;楜ectorĀ;Bႂႃ憾ar;楔ectorĀ;B႑႒懀ar;楓Āpuႛ႞f;愝ndImplies;楰ightarrow;懛ĀchႹႼr;愛;憱leDelayed;槴ڀHOacfhimoqstuფჱჷჽᄙᄞᅑᅖᅡᅧᆵᆻᆿĀCcჩხHcy;䐩y;䐨FTcy;䐬cute;䅚ʀ;aeiyᄈᄉᄎᄓᄗ檼ron;䅠dil;䅞rc;䅜;䐡r;쀀𝔖ortȀDLRUᄪᄴᄾᅉownArrow»ОeftArrow»࢚ightArrow»࿝pArrow;憑gma;䎣allCircle;战pf;쀀𝕊ɲᅭ\0\0ᅰt;戚areȀ;ISUᅻᅼᆉᆯ斡ntersection;抓uĀbpᆏᆞsetĀ;Eᆗᆘ抏qual;抑ersetĀ;Eᆨᆩ抐qual;抒nion;抔cr;쀀𝒮ar;拆ȀbcmpᇈᇛሉላĀ;sᇍᇎ拐etĀ;Eᇍᇕqual;抆ĀchᇠህeedsȀ;ESTᇭᇮᇴᇿ扻qual;檰lantEqual;扽ilde;承Tháྌ;我ƀ;esሒሓሣ拑rsetĀ;Eሜም抃qual;抇et»ሓրHRSacfhiorsሾቄ቉ቕ቞ቱቶኟዂወዑORN耻Þ䃞ADE;愢ĀHc቎ቒcy;䐋y;䐦Ābuቚቜ;䀉;䎤ƀaeyብቪቯron;䅤dil;䅢;䐢r;쀀𝔗Āeiቻ኉Dzኀ\0ኇefore;戴a;䎘Ācn኎ኘkSpace;쀀  Space;怉ldeȀ;EFTካኬኲኼ戼qual;扃ullEqual;扅ilde;扈pf;쀀𝕋ipleDot;惛Āctዖዛr;쀀𝒯rok;䅦ૡዷጎጚጦ\0ጬጱ\0\0\0\0\0ጸጽ፷ᎅ\0᏿ᐄᐊᐐĀcrዻጁute耻Ú䃚rĀ;oጇገ憟cir;楉rǣጓ\0጖y;䐎ve;䅬Āiyጞጣrc耻Û䃛;䐣blac;䅰r;쀀𝔘rave耻Ù䃙acr;䅪Ādiፁ፩erĀBPፈ፝Āarፍፐr;䁟acĀekፗፙ;揟et;掵arenthesis;揝onĀ;P፰፱拃lus;抎Āgp፻፿on;䅲f;쀀𝕌ЀADETadps᎕ᎮᎸᏄϨᏒᏗᏳrrowƀ;BDᅐᎠᎤar;椒ownArrow;懅ownArrow;憕quilibrium;楮eeĀ;AᏋᏌ报rrow;憥ownáϳerĀLRᏞᏨeftArrow;憖ightArrow;憗iĀ;lᏹᏺ䏒on;䎥ing;䅮cr;쀀𝒰ilde;䅨ml耻Ü䃜ҀDbcdefosvᐧᐬᐰᐳᐾᒅᒊᒐᒖash;披ar;櫫y;䐒ashĀ;lᐻᐼ抩;櫦Āerᑃᑅ;拁ƀbtyᑌᑐᑺar;怖Ā;iᑏᑕcalȀBLSTᑡᑥᑪᑴar;戣ine;䁼eparator;杘ilde;所ThinSpace;怊r;쀀𝔙pf;쀀𝕍cr;쀀𝒱dash;抪ʀcefosᒧᒬᒱᒶᒼirc;䅴dge;拀r;쀀𝔚pf;쀀𝕎cr;쀀𝒲Ȁfiosᓋᓐᓒᓘr;쀀𝔛;䎞pf;쀀𝕏cr;쀀𝒳ҀAIUacfosuᓱᓵᓹᓽᔄᔏᔔᔚᔠcy;䐯cy;䐇cy;䐮cute耻Ý䃝Āiyᔉᔍrc;䅶;䐫r;쀀𝔜pf;쀀𝕐cr;쀀𝒴ml;䅸ЀHacdefosᔵᔹᔿᕋᕏᕝᕠᕤcy;䐖cute;䅹Āayᕄᕉron;䅽;䐗ot;䅻Dzᕔ\0ᕛoWidtè૙a;䎖r;愨pf;愤cr;쀀𝒵௡ᖃᖊᖐ\0ᖰᖶᖿ\0\0\0\0ᗆᗛᗫᙟ᙭\0ᚕ᚛ᚲᚹ\0ᚾcute耻á䃡reve;䄃̀;Ediuyᖜᖝᖡᖣᖨᖭ戾;쀀∾̳;房rc耻â䃢te肻´̆;䐰lig耻æ䃦Ā;r²ᖺ;쀀𝔞rave耻à䃠ĀepᗊᗖĀfpᗏᗔsym;愵èᗓha;䎱ĀapᗟcĀclᗤᗧr;䄁g;樿ɤᗰ\0\0ᘊʀ;adsvᗺᗻᗿᘁᘇ戧nd;橕;橜lope;橘;橚΀;elmrszᘘᘙᘛᘞᘿᙏᙙ戠;榤e»ᘙsdĀ;aᘥᘦ戡ѡᘰᘲᘴᘶᘸᘺᘼᘾ;榨;榩;榪;榫;榬;榭;榮;榯tĀ;vᙅᙆ戟bĀ;dᙌᙍ抾;榝Āptᙔᙗh;戢»¹arr;捼Āgpᙣᙧon;䄅f;쀀𝕒΀;Eaeiop዁ᙻᙽᚂᚄᚇᚊ;橰cir;橯;扊d;手s;䀧roxĀ;e዁ᚒñᚃing耻å䃥ƀctyᚡᚦᚨr;쀀𝒶;䀪mpĀ;e዁ᚯñʈilde耻ã䃣ml耻ä䃤Āciᛂᛈoninôɲnt;樑ࠀNabcdefiklnoprsu᛭ᛱᜰ᜼ᝃᝈ᝸᝽០៦ᠹᡐᜍ᤽᥈ᥰot;櫭Ācrᛶ᜞kȀcepsᜀᜅᜍᜓong;扌psilon;䏶rime;怵imĀ;e᜚᜛戽q;拍Ŷᜢᜦee;抽edĀ;gᜬᜭ挅e»ᜭrkĀ;t፜᜷brk;掶Āoyᜁᝁ;䐱quo;怞ʀcmprtᝓ᝛ᝡᝤᝨausĀ;eĊĉptyv;榰séᜌnoõēƀahwᝯ᝱ᝳ;䎲;愶een;扬r;쀀𝔟g΀costuvwឍឝឳេ៕៛៞ƀaiuបពរðݠrc;旯p»፱ƀdptឤឨឭot;樀lus;樁imes;樂ɱឹ\0\0ើcup;樆ar;昅riangleĀdu៍្own;施p;斳plus;樄eåᑄåᒭarow;植ƀako៭ᠦᠵĀcn៲ᠣkƀlst៺֫᠂ozenge;槫riangleȀ;dlr᠒᠓᠘᠝斴own;斾eft;旂ight;斸k;搣Ʊᠫ\0ᠳƲᠯ\0ᠱ;斒;斑4;斓ck;斈ĀeoᠾᡍĀ;qᡃᡆ쀀=⃥uiv;쀀≡⃥t;挐Ȁptwxᡙᡞᡧᡬf;쀀𝕓Ā;tᏋᡣom»Ꮜtie;拈؀DHUVbdhmptuvᢅᢖᢪᢻᣗᣛᣬ᣿ᤅᤊᤐᤡȀLRlrᢎᢐᢒᢔ;敗;敔;敖;敓ʀ;DUduᢡᢢᢤᢦᢨ敐;敦;敩;敤;敧ȀLRlrᢳᢵᢷᢹ;敝;敚;敜;教΀;HLRhlrᣊᣋᣍᣏᣑᣓᣕ救;敬;散;敠;敫;敢;敟ox;槉ȀLRlrᣤᣦᣨᣪ;敕;敒;攐;攌ʀ;DUduڽ᣷᣹᣻᣽;敥;敨;攬;攴inus;抟lus;択imes;抠ȀLRlrᤙᤛᤝ᤟;敛;敘;攘;攔΀;HLRhlrᤰᤱᤳᤵᤷ᤻᤹攂;敪;敡;敞;攼;攤;攜Āevģ᥂bar耻¦䂦Ȁceioᥑᥖᥚᥠr;쀀𝒷mi;恏mĀ;e᜚᜜lƀ;bhᥨᥩᥫ䁜;槅sub;柈Ŭᥴ᥾lĀ;e᥹᥺怢t»᥺pƀ;Eeįᦅᦇ;檮Ā;qۜۛೡᦧ\0᧨ᨑᨕᨲ\0ᨷᩐ\0\0᪴\0\0᫁\0\0ᬡᬮ᭍᭒\0᯽\0ᰌƀcpr᦭ᦲ᧝ute;䄇̀;abcdsᦿᧀᧄ᧊᧕᧙戩nd;橄rcup;橉Āau᧏᧒p;橋p;橇ot;橀;쀀∩︀Āeo᧢᧥t;恁îړȀaeiu᧰᧻ᨁᨅǰ᧵\0᧸s;橍on;䄍dil耻ç䃧rc;䄉psĀ;sᨌᨍ橌m;橐ot;䄋ƀdmnᨛᨠᨦil肻¸ƭptyv;榲t脀¢;eᨭᨮ䂢räƲr;쀀𝔠ƀceiᨽᩀᩍy;䑇ckĀ;mᩇᩈ朓ark»ᩈ;䏇r΀;Ecefms᩟᩠ᩢᩫ᪤᪪᪮旋;槃ƀ;elᩩᩪᩭ䋆q;扗eɡᩴ\0\0᪈rrowĀlr᩼᪁eft;憺ight;憻ʀRSacd᪒᪔᪖᪚᪟»ཇ;擈st;抛irc;抚ash;抝nint;樐id;櫯cir;槂ubsĀ;u᪻᪼晣it»᪼ˬ᫇᫔᫺\0ᬊonĀ;eᫍᫎ䀺Ā;qÇÆɭ᫙\0\0᫢aĀ;t᫞᫟䀬;䁀ƀ;fl᫨᫩᫫戁îᅠeĀmx᫱᫶ent»᫩eóɍǧ᫾\0ᬇĀ;dኻᬂot;橭nôɆƀfryᬐᬔᬗ;쀀𝕔oäɔ脀©;sŕᬝr;愗Āaoᬥᬩrr;憵ss;朗Ācuᬲᬷr;쀀𝒸Ābpᬼ᭄Ā;eᭁᭂ櫏;櫑Ā;eᭉᭊ櫐;櫒dot;拯΀delprvw᭠᭬᭷ᮂᮬᯔ᯹arrĀlr᭨᭪;椸;椵ɰ᭲\0\0᭵r;拞c;拟arrĀ;p᭿ᮀ憶;椽̀;bcdosᮏᮐᮖᮡᮥᮨ截rcap;橈Āauᮛᮞp;橆p;橊ot;抍r;橅;쀀∪︀Ȁalrv᮵ᮿᯞᯣrrĀ;mᮼᮽ憷;椼yƀevwᯇᯔᯘqɰᯎ\0\0ᯒreã᭳uã᭵ee;拎edge;拏en耻¤䂤earrowĀlrᯮ᯳eft»ᮀight»ᮽeäᯝĀciᰁᰇoninôǷnt;戱lcty;挭ঀAHabcdefhijlorstuwz᰸᰻᰿ᱝᱩᱵᲊᲞᲬᲷ᳻᳿ᴍᵻᶑᶫᶻ᷆᷍rò΁ar;楥Ȁglrs᱈ᱍ᱒᱔ger;怠eth;愸òᄳhĀ;vᱚᱛ怐»ऊūᱡᱧarow;椏aã̕Āayᱮᱳron;䄏;䐴ƀ;ao̲ᱼᲄĀgrʿᲁr;懊tseq;橷ƀglmᲑᲔᲘ耻°䂰ta;䎴ptyv;榱ĀirᲣᲨsht;楿;쀀𝔡arĀlrᲳᲵ»ࣜ»သʀaegsv᳂͸᳖᳜᳠mƀ;oș᳊᳔ndĀ;ș᳑uit;晦amma;䏝in;拲ƀ;io᳧᳨᳸䃷de脀÷;o᳧ᳰntimes;拇nø᳷cy;䑒cɯᴆ\0\0ᴊrn;挞op;挍ʀlptuwᴘᴝᴢᵉᵕlar;䀤f;쀀𝕕ʀ;emps̋ᴭᴷᴽᵂqĀ;d͒ᴳot;扑inus;戸lus;戔quare;抡blebarwedgåúnƀadhᄮᵝᵧownarrowóᲃarpoonĀlrᵲᵶefôᲴighôᲶŢᵿᶅkaro÷གɯᶊ\0\0ᶎrn;挟op;挌ƀcotᶘᶣᶦĀryᶝᶡ;쀀𝒹;䑕l;槶rok;䄑Ādrᶰᶴot;拱iĀ;fᶺ᠖斿Āah᷀᷃ròЩaòྦangle;榦Āci᷒ᷕy;䑟grarr;柿ऀDacdefglmnopqrstuxḁḉḙḸոḼṉṡṾấắẽỡἪἷὄ὎὚ĀDoḆᴴoôᲉĀcsḎḔute耻é䃩ter;橮ȀaioyḢḧḱḶron;䄛rĀ;cḭḮ扖耻ê䃪lon;払;䑍ot;䄗ĀDrṁṅot;扒;쀀𝔢ƀ;rsṐṑṗ檚ave耻è䃨Ā;dṜṝ檖ot;檘Ȁ;ilsṪṫṲṴ檙nters;揧;愓Ā;dṹṺ檕ot;檗ƀapsẅẉẗcr;䄓tyƀ;svẒẓẕ戅et»ẓpĀ1;ẝẤijạả;怄;怅怃ĀgsẪẬ;䅋p;怂ĀgpẴẸon;䄙f;쀀𝕖ƀalsỄỎỒrĀ;sỊị拕l;槣us;橱iƀ;lvỚớở䎵on»ớ;䏵ȀcsuvỪỳἋἣĀioữḱrc»Ḯɩỹ\0\0ỻíՈantĀglἂἆtr»ṝess»Ṻƀaeiἒ἖Ἒls;䀽st;扟vĀ;DȵἠD;橸parsl;槥ĀDaἯἳot;打rr;楱ƀcdiἾὁỸr;愯oô͒ĀahὉὋ;䎷耻ð䃰Āmrὓὗl耻ë䃫o;悬ƀcipὡὤὧl;䀡sôծĀeoὬὴctatioîՙnentialåչৡᾒ\0ᾞ\0ᾡᾧ\0\0ῆῌ\0ΐ\0ῦῪ \0 ⁚llingdotseñṄy;䑄male;晀ƀilrᾭᾳ῁lig;耀ffiɩᾹ\0\0᾽g;耀ffig;耀ffl;쀀𝔣lig;耀filig;쀀fjƀaltῙ῜ῡt;晭ig;耀flns;斱of;䆒ǰ΅\0ῳf;쀀𝕗ĀakֿῷĀ;vῼ´拔;櫙artint;樍Āao‌⁕Ācs‑⁒ႉ‸⁅⁈\0⁐β•‥‧‪‬\0‮耻½䂽;慓耻¼䂼;慕;慙;慛Ƴ‴\0‶;慔;慖ʴ‾⁁\0\0⁃耻¾䂾;慗;慜5;慘ƶ⁌\0⁎;慚;慝8;慞l;恄wn;挢cr;쀀𝒻ࢀEabcdefgijlnorstv₂₉₟₥₰₴⃰⃵⃺⃿℃ℒℸ̗ℾ⅒↞Ā;lٍ₇;檌ƀcmpₐₕ₝ute;䇵maĀ;dₜ᳚䎳;檆reve;䄟Āiy₪₮rc;䄝;䐳ot;䄡Ȁ;lqsؾق₽⃉ƀ;qsؾٌ⃄lanô٥Ȁ;cdl٥⃒⃥⃕c;檩otĀ;o⃜⃝檀Ā;l⃢⃣檂;檄Ā;e⃪⃭쀀⋛︀s;檔r;쀀𝔤Ā;gٳ؛mel;愷cy;䑓Ȁ;Eajٚℌℎℐ;檒;檥;檤ȀEaesℛℝ℩ℴ;扩pĀ;p℣ℤ檊rox»ℤĀ;q℮ℯ檈Ā;q℮ℛim;拧pf;쀀𝕘Āci⅃ⅆr;愊mƀ;el٫ⅎ⅐;檎;檐茀>;cdlqr׮ⅠⅪⅮⅳⅹĀciⅥⅧ;檧r;橺ot;拗Par;榕uest;橼ʀadelsↄⅪ←ٖ↛ǰ↉\0↎proø₞r;楸qĀlqؿ↖lesó₈ií٫Āen↣↭rtneqq;쀀≩︀Å↪ԀAabcefkosy⇄⇇⇱⇵⇺∘∝∯≨≽ròΠȀilmr⇐⇔⇗⇛rsðᒄf»․ilôکĀdr⇠⇤cy;䑊ƀ;cwࣴ⇫⇯ir;楈;憭ar;意irc;䄥ƀalr∁∎∓rtsĀ;u∉∊晥it»∊lip;怦con;抹r;쀀𝔥sĀew∣∩arow;椥arow;椦ʀamopr∺∾≃≞≣rr;懿tht;戻kĀlr≉≓eftarrow;憩ightarrow;憪f;쀀𝕙bar;怕ƀclt≯≴≸r;쀀𝒽asè⇴rok;䄧Ābp⊂⊇ull;恃hen»ᱛૡ⊣\0⊪\0⊸⋅⋎\0⋕⋳\0\0⋸⌢⍧⍢⍿\0⎆⎪⎴cute耻í䃭ƀ;iyݱ⊰⊵rc耻î䃮;䐸Ācx⊼⊿y;䐵cl耻¡䂡ĀfrΟ⋉;쀀𝔦rave耻ì䃬Ȁ;inoܾ⋝⋩⋮Āin⋢⋦nt;樌t;戭fin;槜ta;愩lig;䄳ƀaop⋾⌚⌝ƀcgt⌅⌈⌗r;䄫ƀelpܟ⌏⌓inåގarôܠh;䄱f;抷ed;䆵ʀ;cfotӴ⌬⌱⌽⍁are;愅inĀ;t⌸⌹戞ie;槝doô⌙ʀ;celpݗ⍌⍐⍛⍡al;抺Āgr⍕⍙eróᕣã⍍arhk;樗rod;樼Ȁcgpt⍯⍲⍶⍻y;䑑on;䄯f;쀀𝕚a;䎹uest耻¿䂿Āci⎊⎏r;쀀𝒾nʀ;EdsvӴ⎛⎝⎡ӳ;拹ot;拵Ā;v⎦⎧拴;拳Ā;iݷ⎮lde;䄩ǫ⎸\0⎼cy;䑖l耻ï䃯̀cfmosu⏌⏗⏜⏡⏧⏵Āiy⏑⏕rc;䄵;䐹r;쀀𝔧ath;䈷pf;쀀𝕛ǣ⏬\0⏱r;쀀𝒿rcy;䑘kcy;䑔Ѐacfghjos␋␖␢␧␭␱␵␻ppaĀ;v␓␔䎺;䏰Āey␛␠dil;䄷;䐺r;쀀𝔨reen;䄸cy;䑅cy;䑜pf;쀀𝕜cr;쀀𝓀஀ABEHabcdefghjlmnoprstuv⑰⒁⒆⒍⒑┎┽╚▀♎♞♥♹♽⚚⚲⛘❝❨➋⟀⠁⠒ƀart⑷⑺⑼rò৆òΕail;椛arr;椎Ā;gঔ⒋;檋ar;楢ॣ⒥\0⒪\0⒱\0\0\0\0\0⒵Ⓔ\0ⓆⓈⓍ\0⓹ute;䄺mptyv;榴raîࡌbda;䎻gƀ;dlࢎⓁⓃ;榑åࢎ;檅uo耻«䂫rЀ;bfhlpst࢙ⓞⓦⓩ⓫⓮⓱⓵Ā;f࢝ⓣs;椟s;椝ë≒p;憫l;椹im;楳l;憢ƀ;ae⓿─┄檫il;椙Ā;s┉┊檭;쀀⪭︀ƀabr┕┙┝rr;椌rk;杲Āak┢┬cĀek┨┪;䁻;䁛Āes┱┳;榋lĀdu┹┻;榏;榍Ȁaeuy╆╋╖╘ron;䄾Ādi═╔il;䄼ìࢰâ┩;䐻Ȁcqrs╣╦╭╽a;椶uoĀ;rนᝆĀdu╲╷har;楧shar;楋h;憲ʀ;fgqs▋▌উ◳◿扤tʀahlrt▘▤▷◂◨rrowĀ;t࢙□aé⓶arpoonĀdu▯▴own»њp»०eftarrows;懇ightƀahs◍◖◞rrowĀ;sࣴࢧarpoonó྘quigarro÷⇰hreetimes;拋ƀ;qs▋ও◺lanôবʀ;cdgsব☊☍☝☨c;檨otĀ;o☔☕橿Ā;r☚☛檁;檃Ā;e☢☥쀀⋚︀s;檓ʀadegs☳☹☽♉♋pproøⓆot;拖qĀgq♃♅ôউgtò⒌ôছiíলƀilr♕࣡♚sht;楼;쀀𝔩Ā;Eজ♣;檑š♩♶rĀdu▲♮Ā;l॥♳;楪lk;斄cy;䑙ʀ;achtੈ⚈⚋⚑⚖rò◁orneòᴈard;楫ri;旺Āio⚟⚤dot;䅀ustĀ;a⚬⚭掰che»⚭ȀEaes⚻⚽⛉⛔;扨pĀ;p⛃⛄檉rox»⛄Ā;q⛎⛏檇Ā;q⛎⚻im;拦Ѐabnoptwz⛩⛴⛷✚✯❁❇❐Ānr⛮⛱g;柬r;懽rëࣁgƀlmr⛿✍✔eftĀar০✇ightá৲apsto;柼ightá৽parrowĀlr✥✩efô⓭ight;憬ƀafl✶✹✽r;榅;쀀𝕝us;樭imes;樴š❋❏st;戗áፎƀ;ef❗❘᠀旊nge»❘arĀ;l❤❥䀨t;榓ʀachmt❳❶❼➅➇ròࢨorneòᶌarĀ;d྘➃;業;怎ri;抿̀achiqt➘➝ੀ➢➮➻quo;怹r;쀀𝓁mƀ;egল➪➬;檍;檏Ābu┪➳oĀ;rฟ➹;怚rok;䅂萀<;cdhilqrࠫ⟒☹⟜⟠⟥⟪⟰Āci⟗⟙;檦r;橹reå◲mes;拉arr;楶uest;橻ĀPi⟵⟹ar;榖ƀ;ef⠀भ᠛旃rĀdu⠇⠍shar;楊har;楦Āen⠗⠡rtneqq;쀀≨︀Å⠞܀Dacdefhilnopsu⡀⡅⢂⢎⢓⢠⢥⢨⣚⣢⣤ઃ⣳⤂Dot;戺Ȁclpr⡎⡒⡣⡽r耻¯䂯Āet⡗⡙;時Ā;e⡞⡟朠se»⡟Ā;sျ⡨toȀ;dluျ⡳⡷⡻owîҌefôएðᏑker;斮Āoy⢇⢌mma;権;䐼ash;怔asuredangle»ᘦr;쀀𝔪o;愧ƀcdn⢯⢴⣉ro耻µ䂵Ȁ;acdᑤ⢽⣀⣄sôᚧir;櫰ot肻·Ƶusƀ;bd⣒ᤃ⣓戒Ā;uᴼ⣘;横ţ⣞⣡p;櫛ò−ðઁĀdp⣩⣮els;抧f;쀀𝕞Āct⣸⣽r;쀀𝓂pos»ᖝƀ;lm⤉⤊⤍䎼timap;抸ఀGLRVabcdefghijlmoprstuvw⥂⥓⥾⦉⦘⧚⧩⨕⨚⩘⩝⪃⪕⪤⪨⬄⬇⭄⭿⮮ⰴⱧⱼ⳩Āgt⥇⥋;쀀⋙̸Ā;v⥐௏쀀≫⃒ƀelt⥚⥲⥶ftĀar⥡⥧rrow;懍ightarrow;懎;쀀⋘̸Ā;v⥻ే쀀≪⃒ightarrow;懏ĀDd⦎⦓ash;抯ash;抮ʀbcnpt⦣⦧⦬⦱⧌la»˞ute;䅄g;쀀∠⃒ʀ;Eiop඄⦼⧀⧅⧈;쀀⩰̸d;쀀≋̸s;䅉roø඄urĀ;a⧓⧔普lĀ;s⧓ସdz⧟\0⧣p肻 ଷmpĀ;e௹ఀʀaeouy⧴⧾⨃⨐⨓ǰ⧹\0⧻;橃on;䅈dil;䅆ngĀ;dൾ⨊ot;쀀⩭̸p;橂;䐽ash;怓΀;Aadqsxஒ⨩⨭⨻⩁⩅⩐rr;懗rĀhr⨳⨶k;椤Ā;oᏲᏰot;쀀≐̸uiöୣĀei⩊⩎ar;椨í஘istĀ;s஠டr;쀀𝔫ȀEest௅⩦⩹⩼ƀ;qs஼⩭௡ƀ;qs஼௅⩴lanô௢ií௪Ā;rஶ⪁»ஷƀAap⪊⪍⪑rò⥱rr;憮ar;櫲ƀ;svྍ⪜ྌĀ;d⪡⪢拼;拺cy;䑚΀AEadest⪷⪺⪾⫂⫅⫶⫹rò⥦;쀀≦̸rr;憚r;急Ȁ;fqs఻⫎⫣⫯tĀar⫔⫙rro÷⫁ightarro÷⪐ƀ;qs఻⪺⫪lanôౕĀ;sౕ⫴»శiíౝĀ;rవ⫾iĀ;eచథiäඐĀpt⬌⬑f;쀀𝕟膀¬;in⬙⬚⬶䂬nȀ;Edvஉ⬤⬨⬮;쀀⋹̸ot;쀀⋵̸ǡஉ⬳⬵;拷;拶iĀ;vಸ⬼ǡಸ⭁⭃;拾;拽ƀaor⭋⭣⭩rȀ;ast୻⭕⭚⭟lleì୻l;쀀⫽⃥;쀀∂̸lint;樔ƀ;ceಒ⭰⭳uåಥĀ;cಘ⭸Ā;eಒ⭽ñಘȀAait⮈⮋⮝⮧rò⦈rrƀ;cw⮔⮕⮙憛;쀀⤳̸;쀀↝̸ghtarrow»⮕riĀ;eೋೖ΀chimpqu⮽⯍⯙⬄୸⯤⯯Ȁ;cerല⯆ഷ⯉uå൅;쀀𝓃ortɭ⬅\0\0⯖ará⭖mĀ;e൮⯟Ā;q൴൳suĀbp⯫⯭å೸åഋƀbcp⯶ⰑⰙȀ;Ees⯿ⰀഢⰄ抄;쀀⫅̸etĀ;eഛⰋqĀ;qണⰀcĀ;eലⰗñസȀ;EesⰢⰣൟⰧ抅;쀀⫆̸etĀ;e൘ⰮqĀ;qൠⰣȀgilrⰽⰿⱅⱇìௗlde耻ñ䃱çృiangleĀlrⱒⱜeftĀ;eచⱚñదightĀ;eೋⱥñ೗Ā;mⱬⱭ䎽ƀ;esⱴⱵⱹ䀣ro;愖p;怇ҀDHadgilrsⲏⲔⲙⲞⲣⲰⲶⳓⳣash;抭arr;椄p;쀀≍⃒ash;抬ĀetⲨⲬ;쀀≥⃒;쀀>⃒nfin;槞ƀAetⲽⳁⳅrr;椂;쀀≤⃒Ā;rⳊⳍ쀀<⃒ie;쀀⊴⃒ĀAtⳘⳜrr;椃rie;쀀⊵⃒im;쀀∼⃒ƀAan⳰⳴ⴂrr;懖rĀhr⳺⳽k;椣Ā;oᏧᏥear;椧ቓ᪕\0\0\0\0\0\0\0\0\0\0\0\0\0ⴭ\0ⴸⵈⵠⵥ⵲ⶄᬇ\0\0ⶍⶫ\0ⷈⷎ\0ⷜ⸙⸫⸾⹃Ācsⴱ᪗ute耻ó䃳ĀiyⴼⵅrĀ;c᪞ⵂ耻ô䃴;䐾ʀabios᪠ⵒⵗLjⵚlac;䅑v;樸old;榼lig;䅓Ācr⵩⵭ir;榿;쀀𝔬ͯ⵹\0\0⵼\0ⶂn;䋛ave耻ò䃲;槁Ābmⶈ෴ar;榵Ȁacitⶕ⶘ⶥⶨrò᪀Āir⶝ⶠr;榾oss;榻nå๒;槀ƀaeiⶱⶵⶹcr;䅍ga;䏉ƀcdnⷀⷅǍron;䎿;榶pf;쀀𝕠ƀaelⷔ⷗ǒr;榷rp;榹΀;adiosvⷪⷫⷮ⸈⸍⸐⸖戨rò᪆Ȁ;efmⷷⷸ⸂⸅橝rĀ;oⷾⷿ愴f»ⷿ耻ª䂪耻º䂺gof;抶r;橖lope;橗;橛ƀclo⸟⸡⸧ò⸁ash耻ø䃸l;折iŬⸯ⸴de耻õ䃵esĀ;aǛ⸺s;樶ml耻ö䃶bar;挽ૡ⹞\0⹽\0⺀⺝\0⺢⺹\0\0⻋ຜ\0⼓\0\0⼫⾼\0⿈rȀ;astЃ⹧⹲຅脀¶;l⹭⹮䂶leìЃɩ⹸\0\0⹻m;櫳;櫽y;䐿rʀcimpt⺋⺏⺓ᡥ⺗nt;䀥od;䀮il;怰enk;怱r;쀀𝔭ƀimo⺨⺰⺴Ā;v⺭⺮䏆;䏕maô੶ne;明ƀ;tv⺿⻀⻈䏀chfork»´;䏖Āau⻏⻟nĀck⻕⻝kĀ;h⇴⻛;愎ö⇴sҀ;abcdemst⻳⻴ᤈ⻹⻽⼄⼆⼊⼎䀫cir;樣ir;樢Āouᵀ⼂;樥;橲n肻±ຝim;樦wo;樧ƀipu⼙⼠⼥ntint;樕f;쀀𝕡nd耻£䂣Ԁ;Eaceinosu່⼿⽁⽄⽇⾁⾉⾒⽾⾶;檳p;檷uå໙Ā;c໎⽌̀;acens່⽙⽟⽦⽨⽾pproø⽃urlyeñ໙ñ໎ƀaes⽯⽶⽺pprox;檹qq;檵im;拨iíໟmeĀ;s⾈ຮ怲ƀEas⽸⾐⽺ð⽵ƀdfp໬⾙⾯ƀals⾠⾥⾪lar;挮ine;挒urf;挓Ā;t໻⾴ï໻rel;抰Āci⿀⿅r;쀀𝓅;䏈ncsp;怈̀fiopsu⿚⋢⿟⿥⿫⿱r;쀀𝔮pf;쀀𝕢rime;恗cr;쀀𝓆ƀaeo⿸〉〓tĀei⿾々rnionóڰnt;樖stĀ;e【】䀿ñἙô༔઀ABHabcdefhilmnoprstux぀けさすムㄎㄫㅇㅢㅲㆎ㈆㈕㈤㈩㉘㉮㉲㊐㊰㊷ƀartぇおがròႳòϝail;検aròᱥar;楤΀cdenqrtとふへみわゔヌĀeuねぱ;쀀∽̱te;䅕iãᅮmptyv;榳gȀ;del࿑らるろ;榒;榥å࿑uo耻»䂻rր;abcfhlpstw࿜ガクシスゼゾダッデナp;極Ā;f࿠ゴs;椠;椳s;椞ë≝ð✮l;楅im;楴l;憣;憝Āaiパフil;椚oĀ;nホボ戶aló༞ƀabrョリヮrò៥rk;杳ĀakンヽcĀekヹ・;䁽;䁝Āes㄂㄄;榌lĀduㄊㄌ;榎;榐Ȁaeuyㄗㄜㄧㄩron;䅙Ādiㄡㄥil;䅗ì࿲âヺ;䑀Ȁclqsㄴㄷㄽㅄa;椷dhar;楩uoĀ;rȎȍh;憳ƀacgㅎㅟངlȀ;ipsླྀㅘㅛႜnåႻarôྩt;断ƀilrㅩဣㅮsht;楽;쀀𝔯ĀaoㅷㆆrĀduㅽㅿ»ѻĀ;l႑ㆄ;楬Ā;vㆋㆌ䏁;䏱ƀgns㆕ㇹㇼht̀ahlrstㆤㆰ㇂㇘㇤㇮rrowĀ;t࿜ㆭaéトarpoonĀduㆻㆿowîㅾp»႒eftĀah㇊㇐rrowó࿪arpoonóՑightarrows;應quigarro÷ニhreetimes;拌g;䋚ingdotseñἲƀahm㈍㈐㈓rò࿪aòՑ;怏oustĀ;a㈞㈟掱che»㈟mid;櫮Ȁabpt㈲㈽㉀㉒Ānr㈷㈺g;柭r;懾rëဃƀafl㉇㉊㉎r;榆;쀀𝕣us;樮imes;樵Āap㉝㉧rĀ;g㉣㉤䀩t;榔olint;樒arò㇣Ȁachq㉻㊀Ⴜ㊅quo;怺r;쀀𝓇Ābu・㊊oĀ;rȔȓƀhir㊗㊛㊠reåㇸmes;拊iȀ;efl㊪ၙᠡ㊫方tri;槎luhar;楨;愞ൡ㋕㋛㋟㌬㌸㍱\0㍺㎤\0\0㏬㏰\0㐨㑈㑚㒭㒱㓊㓱\0㘖\0\0㘳cute;䅛quï➺Ԁ;Eaceinpsyᇭ㋳㋵㋿㌂㌋㌏㌟㌦㌩;檴ǰ㋺\0㋼;檸on;䅡uåᇾĀ;dᇳ㌇il;䅟rc;䅝ƀEas㌖㌘㌛;檶p;檺im;择olint;樓iíሄ;䑁otƀ;be㌴ᵇ㌵担;橦΀Aacmstx㍆㍊㍗㍛㍞㍣㍭rr;懘rĀhr㍐㍒ë∨Ā;oਸ਼਴t耻§䂧i;䀻war;椩mĀin㍩ðnuóñt;朶rĀ;o㍶⁕쀀𝔰Ȁacoy㎂㎆㎑㎠rp;景Āhy㎋㎏cy;䑉;䑈rtɭ㎙\0\0㎜iäᑤaraì⹯耻­䂭Āgm㎨㎴maƀ;fv㎱㎲㎲䏃;䏂Ѐ;deglnprካ㏅㏉㏎㏖㏞㏡㏦ot;橪Ā;q኱ኰĀ;E㏓㏔檞;檠Ā;E㏛㏜檝;檟e;扆lus;樤arr;楲aròᄽȀaeit㏸㐈㐏㐗Āls㏽㐄lsetmé㍪hp;樳parsl;槤Ādlᑣ㐔e;挣Ā;e㐜㐝檪Ā;s㐢㐣檬;쀀⪬︀ƀflp㐮㐳㑂tcy;䑌Ā;b㐸㐹䀯Ā;a㐾㐿槄r;挿f;쀀𝕤aĀdr㑍ЂesĀ;u㑔㑕晠it»㑕ƀcsu㑠㑹㒟Āau㑥㑯pĀ;sᆈ㑫;쀀⊓︀pĀ;sᆴ㑵;쀀⊔︀uĀbp㑿㒏ƀ;esᆗᆜ㒆etĀ;eᆗ㒍ñᆝƀ;esᆨᆭ㒖etĀ;eᆨ㒝ñᆮƀ;afᅻ㒦ְrť㒫ֱ»ᅼaròᅈȀcemt㒹㒾㓂㓅r;쀀𝓈tmîñiì㐕aræᆾĀar㓎㓕rĀ;f㓔ឿ昆Āan㓚㓭ightĀep㓣㓪psiloîỠhé⺯s»⡒ʀbcmnp㓻㕞ሉ㖋㖎Ҁ;Edemnprs㔎㔏㔑㔕㔞㔣㔬㔱㔶抂;櫅ot;檽Ā;dᇚ㔚ot;櫃ult;櫁ĀEe㔨㔪;櫋;把lus;檿arr;楹ƀeiu㔽㕒㕕tƀ;en㔎㕅㕋qĀ;qᇚ㔏eqĀ;q㔫㔨m;櫇Ābp㕚㕜;櫕;櫓c̀;acensᇭ㕬㕲㕹㕻㌦pproø㋺urlyeñᇾñᇳƀaes㖂㖈㌛pproø㌚qñ㌗g;晪ڀ123;Edehlmnps㖩㖬㖯ሜ㖲㖴㗀㗉㗕㗚㗟㗨㗭耻¹䂹耻²䂲耻³䂳;櫆Āos㖹㖼t;檾ub;櫘Ā;dሢ㗅ot;櫄sĀou㗏㗒l;柉b;櫗arr;楻ult;櫂ĀEe㗤㗦;櫌;抋lus;櫀ƀeiu㗴㘉㘌tƀ;enሜ㗼㘂qĀ;qሢ㖲eqĀ;q㗧㗤m;櫈Ābp㘑㘓;櫔;櫖ƀAan㘜㘠㘭rr;懙rĀhr㘦㘨ë∮Ā;oਫ਩war;椪lig耻ß䃟௡㙑㙝㙠ዎ㙳㙹\0㙾㛂\0\0\0\0\0㛛㜃\0㜉㝬\0\0\0㞇ɲ㙖\0\0㙛get;挖;䏄rë๟ƀaey㙦㙫㙰ron;䅥dil;䅣;䑂lrec;挕r;쀀𝔱Ȁeiko㚆㚝㚵㚼Dz㚋\0㚑eĀ4fኄኁaƀ;sv㚘㚙㚛䎸ym;䏑Ācn㚢㚲kĀas㚨㚮pproø዁im»ኬsðኞĀas㚺㚮ð዁rn耻þ䃾Ǭ̟㛆⋧es膀×;bd㛏㛐㛘䃗Ā;aᤏ㛕r;樱;樰ƀeps㛡㛣㜀á⩍Ȁ;bcf҆㛬㛰㛴ot;挶ir;櫱Ā;o㛹㛼쀀𝕥rk;櫚á㍢rime;怴ƀaip㜏㜒㝤dåቈ΀adempst㜡㝍㝀㝑㝗㝜㝟ngleʀ;dlqr㜰㜱㜶㝀㝂斵own»ᶻeftĀ;e⠀㜾ñम;扜ightĀ;e㊪㝋ñၚot;旬inus;樺lus;樹b;槍ime;樻ezium;揢ƀcht㝲㝽㞁Āry㝷㝻;쀀𝓉;䑆cy;䑛rok;䅧Āio㞋㞎xô᝷headĀlr㞗㞠eftarro÷ࡏightarrow»ཝऀAHabcdfghlmoprstuw㟐㟓㟗㟤㟰㟼㠎㠜㠣㠴㡑㡝㡫㢩㣌㣒㣪㣶ròϭar;楣Ācr㟜㟢ute耻ú䃺òᅐrǣ㟪\0㟭y;䑞ve;䅭Āiy㟵㟺rc耻û䃻;䑃ƀabh㠃㠆㠋ròᎭlac;䅱aòᏃĀir㠓㠘sht;楾;쀀𝔲rave耻ù䃹š㠧㠱rĀlr㠬㠮»ॗ»ႃlk;斀Āct㠹㡍ɯ㠿\0\0㡊rnĀ;e㡅㡆挜r»㡆op;挏ri;旸Āal㡖㡚cr;䅫肻¨͉Āgp㡢㡦on;䅳f;쀀𝕦̀adhlsuᅋ㡸㡽፲㢑㢠ownáᎳarpoonĀlr㢈㢌efô㠭ighô㠯iƀ;hl㢙㢚㢜䏅»ᏺon»㢚parrows;懈ƀcit㢰㣄㣈ɯ㢶\0\0㣁rnĀ;e㢼㢽挝r»㢽op;挎ng;䅯ri;旹cr;쀀𝓊ƀdir㣙㣝㣢ot;拰lde;䅩iĀ;f㜰㣨»᠓Āam㣯㣲rò㢨l耻ü䃼angle;榧ހABDacdeflnoprsz㤜㤟㤩㤭㦵㦸㦽㧟㧤㧨㧳㧹㧽㨁㨠ròϷarĀ;v㤦㤧櫨;櫩asèϡĀnr㤲㤷grt;榜΀eknprst㓣㥆㥋㥒㥝㥤㦖appá␕othinçẖƀhir㓫⻈㥙opô⾵Ā;hᎷ㥢ïㆍĀiu㥩㥭gmá㎳Ābp㥲㦄setneqĀ;q㥽㦀쀀⊊︀;쀀⫋︀setneqĀ;q㦏㦒쀀⊋︀;쀀⫌︀Āhr㦛㦟etá㚜iangleĀlr㦪㦯eft»थight»ၑy;䐲ash»ံƀelr㧄㧒㧗ƀ;beⷪ㧋㧏ar;抻q;扚lip;拮Ābt㧜ᑨaòᑩr;쀀𝔳tré㦮suĀbp㧯㧱»ജ»൙pf;쀀𝕧roð໻tré㦴Ācu㨆㨋r;쀀𝓋Ābp㨐㨘nĀEe㦀㨖»㥾nĀEe㦒㨞»㦐igzag;榚΀cefoprs㨶㨻㩖㩛㩔㩡㩪irc;䅵Ādi㩀㩑Ābg㩅㩉ar;機eĀ;qᗺ㩏;扙erp;愘r;쀀𝔴pf;쀀𝕨Ā;eᑹ㩦atèᑹcr;쀀𝓌ૣណ㪇\0㪋\0㪐㪛\0\0㪝㪨㪫㪯\0\0㫃㫎\0㫘ៜ៟tré៑r;쀀𝔵ĀAa㪔㪗ròσrò৶;䎾ĀAa㪡㪤ròθrò৫að✓is;拻ƀdptឤ㪵㪾Āfl㪺ឩ;쀀𝕩imåឲĀAa㫇㫊ròώròਁĀcq㫒ីr;쀀𝓍Āpt៖㫜ré។Ѐacefiosu㫰㫽㬈㬌㬑㬕㬛㬡cĀuy㫶㫻te耻ý䃽;䑏Āiy㬂㬆rc;䅷;䑋n耻¥䂥r;쀀𝔶cy;䑗pf;쀀𝕪cr;쀀𝓎Ācm㬦㬩y;䑎l耻ÿ䃿Ԁacdefhiosw㭂㭈㭔㭘㭤㭩㭭㭴㭺㮀cute;䅺Āay㭍㭒ron;䅾;䐷ot;䅼Āet㭝㭡træᕟa;䎶r;쀀𝔷cy;䐶grarr;懝pf;쀀𝕫cr;쀀𝓏Ājn㮅㮇;怍j;怌'.split("").map(e=>e.charCodeAt(0))),Fee=new Uint16Array("Ȁaglq \x1Bɭ\0\0p;䀦os;䀧t;䀾t;䀼uot;䀢".split("").map(e=>e.charCodeAt(0))),m9;const Ree=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]),Oee=(m9=String.fromCodePoint)!==null&&m9!==void 0?m9:function(e){let t="";return e>65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|e&1023),t+=String.fromCharCode(e),t};function Pee(e){var t;return e>=55296&&e<=57343||e>1114111?65533:(t=Ree.get(e))!==null&&t!==void 0?t:e}var Is;(function(e){e[e.NUM=35]="NUM",e[e.SEMI=59]="SEMI",e[e.EQUALS=61]="EQUALS",e[e.ZERO=48]="ZERO",e[e.NINE=57]="NINE",e[e.LOWER_A=97]="LOWER_A",e[e.LOWER_F=102]="LOWER_F",e[e.LOWER_X=120]="LOWER_X",e[e.LOWER_Z=122]="LOWER_Z",e[e.UPPER_A=65]="UPPER_A",e[e.UPPER_F=70]="UPPER_F",e[e.UPPER_Z=90]="UPPER_Z"})(Is||(Is={}));const Dee=32;var Ba;(function(e){e[e.VALUE_LENGTH=49152]="VALUE_LENGTH",e[e.BRANCH_LENGTH=16256]="BRANCH_LENGTH",e[e.JUMP_TABLE=127]="JUMP_TABLE"})(Ba||(Ba={}));function I3(e){return e>=Is.ZERO&&e<=Is.NINE}function Bee(e){return e>=Is.UPPER_A&&e<=Is.UPPER_F||e>=Is.LOWER_A&&e<=Is.LOWER_F}function Hee(e){return e>=Is.UPPER_A&&e<=Is.UPPER_Z||e>=Is.LOWER_A&&e<=Is.LOWER_Z||I3(e)}function zee(e){return e===Is.EQUALS||Hee(e)}var Ms;(function(e){e[e.EntityStart=0]="EntityStart",e[e.NumericStart=1]="NumericStart",e[e.NumericDecimal=2]="NumericDecimal",e[e.NumericHex=3]="NumericHex",e[e.NamedEntity=4]="NamedEntity"})(Ms||(Ms={}));var Ra;(function(e){e[e.Legacy=0]="Legacy",e[e.Strict=1]="Strict",e[e.Attribute=2]="Attribute"})(Ra||(Ra={}));var Wee=class{constructor(e,t,n){this.decodeTree=e,this.emitCodePoint=t,this.errors=n,this.state=Ms.EntityStart,this.consumed=1,this.result=0,this.treeIndex=0,this.excess=1,this.decodeMode=Ra.Strict}startEntity(e){this.decodeMode=e,this.state=Ms.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1}write(e,t){switch(this.state){case Ms.EntityStart:return e.charCodeAt(t)===Is.NUM?(this.state=Ms.NumericStart,this.consumed+=1,this.stateNumericStart(e,t+1)):(this.state=Ms.NamedEntity,this.stateNamedEntity(e,t));case Ms.NumericStart:return this.stateNumericStart(e,t);case Ms.NumericDecimal:return this.stateNumericDecimal(e,t);case Ms.NumericHex:return this.stateNumericHex(e,t);case Ms.NamedEntity:return this.stateNamedEntity(e,t)}}stateNumericStart(e,t){return t>=e.length?-1:(e.charCodeAt(t)|Dee)===Is.LOWER_X?(this.state=Ms.NumericHex,this.consumed+=1,this.stateNumericHex(e,t+1)):(this.state=Ms.NumericDecimal,this.stateNumericDecimal(e,t))}addToNumericResult(e,t,n,o){if(t!==n){const s=n-t;this.result=this.result*Math.pow(o,s)+parseInt(e.substr(t,s),o),this.consumed+=s}}stateNumericHex(e,t){const n=t;for(;t<e.length;){const o=e.charCodeAt(t);if(I3(o)||Bee(o))t+=1;else return this.addToNumericResult(e,n,t,16),this.emitNumericEntity(o,3)}return this.addToNumericResult(e,n,t,16),-1}stateNumericDecimal(e,t){const n=t;for(;t<e.length;){const o=e.charCodeAt(t);if(I3(o))t+=1;else return this.addToNumericResult(e,n,t,10),this.emitNumericEntity(o,2)}return this.addToNumericResult(e,n,t,10),-1}emitNumericEntity(e,t){var n;if(this.consumed<=t)return(n=this.errors)===null||n===void 0||n.absenceOfDigitsInNumericCharacterReference(this.consumed),0;if(e===Is.SEMI)this.consumed+=1;else if(this.decodeMode===Ra.Strict)return 0;return this.emitCodePoint(Pee(this.result),this.consumed),this.errors&&(e!==Is.SEMI&&this.errors.missingSemicolonAfterCharacterReference(),this.errors.validateNumericCharacterReference(this.result)),this.consumed}stateNamedEntity(e,t){const{decodeTree:n}=this;let o=n[this.treeIndex],s=(o&Ba.VALUE_LENGTH)>>14;for(;t<e.length;t++,this.excess++){const i=e.charCodeAt(t);if(this.treeIndex=Uee(n,o,this.treeIndex+Math.max(1,s),i),this.treeIndex<0)return this.result===0||this.decodeMode===Ra.Attribute&&(s===0||zee(i))?0:this.emitNotTerminatedNamedEntity();if(o=n[this.treeIndex],s=(o&Ba.VALUE_LENGTH)>>14,s!==0){if(i===Is.SEMI)return this.emitNamedEntityData(this.treeIndex,s,this.consumed+this.excess);this.decodeMode!==Ra.Strict&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}}return-1}emitNotTerminatedNamedEntity(){var e;const{result:t,decodeTree:n}=this,o=(n[t]&Ba.VALUE_LENGTH)>>14;return this.emitNamedEntityData(t,o,this.consumed),(e=this.errors)===null||e===void 0||e.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(e,t,n){const{decodeTree:o}=this;return this.emitCodePoint(t===1?o[e]&~Ba.VALUE_LENGTH:o[e+1],n),t===3&&this.emitCodePoint(o[e+2],n),n}end(){var e;switch(this.state){case Ms.NamedEntity:return this.result!==0&&(this.decodeMode!==Ra.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case Ms.NumericDecimal:return this.emitNumericEntity(0,2);case Ms.NumericHex:return this.emitNumericEntity(0,3);case Ms.NumericStart:return(e=this.errors)===null||e===void 0||e.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case Ms.EntityStart:return 0}}};function LE(e){let t="";const n=new Wee(e,o=>t+=Oee(o));return function(s,i){let r=0,l=0;for(;(l=s.indexOf("&",l))>=0;){t+=s.slice(r,l),n.startEntity(i);const u=n.write(s,l+1);if(u<0){r=l+n.end();break}r=l+u,l=u===0?r+1:r}const a=t+s.slice(r);return t="",a}}function Uee(e,t,n,o){const s=(t&Ba.BRANCH_LENGTH)>>7,i=t&Ba.JUMP_TABLE;if(s===0)return i!==0&&o===i?n:-1;if(i){const a=o-i;return a<0||a>=s?-1:e[n+a]-1}let r=n,l=r+s-1;for(;r<=l;){const a=r+l>>>1,u=e[a];if(u<o)r=a+1;else if(u>o)l=a-1;else return e[a+s]}return-1}const jee=LE(Nee);LE(Fee);function $y(e,t=Ra.Legacy){return jee(e,t)}var Vee=IE($ee());const rC={};function qee(e){let t=rC[e];if(t)return t;t=rC[e]=[];for(let n=0;n<128;n++){const o=String.fromCharCode(n);t.push(o)}for(let n=0;n<e.length;n++){const o=e.charCodeAt(n);t[o]="%"+("0"+o.toString(16).toUpperCase()).slice(-2)}return t}function m2(e,t){typeof t!="string"&&(t=m2.defaultChars);const n=qee(t);return e.replace(/(%[a-f0-9]{2})+/gi,function(o){let s="";for(let i=0,r=o.length;i<r;i+=3){const l=parseInt(o.slice(i+1,i+3),16);if(l<128){s+=n[l];continue}if((l&224)===192&&i+3<r){const a=parseInt(o.slice(i+4,i+6),16);if((a&192)===128){const u=l<<6&1984|a&63;u<128?s+="��":s+=String.fromCharCode(u),i+=3;continue}}if((l&240)===224&&i+6<r){const a=parseInt(o.slice(i+4,i+6),16),u=parseInt(o.slice(i+7,i+9),16);if((a&192)===128&&(u&192)===128){const c=l<<12&61440|a<<6&4032|u&63;c<2048||c>=55296&&c<=57343?s+="���":s+=String.fromCharCode(c),i+=6;continue}}if((l&248)===240&&i+9<r){const a=parseInt(o.slice(i+4,i+6),16),u=parseInt(o.slice(i+7,i+9),16),c=parseInt(o.slice(i+10,i+12),16);if((a&192)===128&&(u&192)===128&&(c&192)===128){let d=l<<18&1835008|a<<12&258048|u<<6&4032|c&63;d<65536||d>1114111?s+="����":(d-=65536,s+=String.fromCharCode(55296+(d>>10),56320+(d&1023))),i+=9;continue}}s+="�"}return s})}m2.defaultChars=";/?:@&=+$,#";m2.componentChars="";var L3=m2;const lC={};function Kee(e){let t=lC[e];if(t)return t;t=lC[e]=[];for(let n=0;n<128;n++){const o=String.fromCharCode(n);/^[0-9a-z]$/i.test(o)?t.push(o):t.push("%"+("0"+n.toString(16).toUpperCase()).slice(-2))}for(let n=0;n<e.length;n++)t[e.charCodeAt(n)]=e[n];return t}function g2(e,t,n){typeof t!="string"&&(n=t,t=g2.defaultChars),typeof n>"u"&&(n=!0);const o=Kee(t);let s="";for(let i=0,r=e.length;i<r;i++){const l=e.charCodeAt(i);if(n&&l===37&&i+2<r&&/^[0-9a-f]{2}$/i.test(e.slice(i+1,i+3))){s+=e.slice(i,i+3),i+=2;continue}if(l<128){s+=o[l];continue}if(l>=55296&&l<=57343){if(l>=55296&&l<=56319&&i+1<r){const a=e.charCodeAt(i+1);if(a>=56320&&a<=57343){s+=encodeURIComponent(e[i]+e[i+1]),i++;continue}}s+="%EF%BF%BD";continue}s+=encodeURIComponent(e[i])}return s}g2.defaultChars=";/?:@&=+$,-_.!~*'()#";g2.componentChars="-_.!~*'()";var $E=g2;function Ny(e){let t="";return t+=e.protocol||"",t+=e.slashes?"//":"",t+=e.auth?e.auth+"@":"",e.hostname&&e.hostname.indexOf(":")!==-1?t+="["+e.hostname+"]":t+=e.hostname||"",t+=e.port?":"+e.port:"",t+=e.pathname||"",t+=e.search||"",t+=e.hash||"",t}function Hm(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}const Zee=/^([a-z0-9.+-]+:)/i,Gee=/:[0-9]*$/,Yee=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,Xee=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r",` +`," "]),Jee=["'"].concat(Xee),aC=["%","/","?",";","#"].concat(Jee),uC=["/","?","#"],Qee=255,cC=/^[+a-z0-9A-Z_-]{0,63}$/,ete=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,dC={javascript:!0,"javascript:":!0},fC={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function tte(e,t){if(e&&e instanceof Hm)return e;const n=new Hm;return n.parse(e,t),n}Hm.prototype.parse=function(e,t){let n,o,s,i=e;if(i=i.trim(),!t&&e.split("#").length===1){const u=Yee.exec(i);if(u)return this.pathname=u[1],u[2]&&(this.search=u[2]),this}let r=Zee.exec(i);if(r&&(r=r[0],n=r.toLowerCase(),this.protocol=r,i=i.substr(r.length)),(t||r||i.match(/^\/\/[^@\/]+@[^@\/]+/))&&(s=i.substr(0,2)==="//",s&&!(r&&dC[r])&&(i=i.substr(2),this.slashes=!0)),!dC[r]&&(s||r&&!fC[r])){let u=-1;for(let m=0;m<uC.length;m++)o=i.indexOf(uC[m]),o!==-1&&(u===-1||o<u)&&(u=o);let c,d;u===-1?d=i.lastIndexOf("@"):d=i.lastIndexOf("@",u),d!==-1&&(c=i.slice(0,d),i=i.slice(d+1),this.auth=c),u=-1;for(let m=0;m<aC.length;m++)o=i.indexOf(aC[m]),o!==-1&&(u===-1||o<u)&&(u=o);u===-1&&(u=i.length),i[u-1]===":"&&u--;const f=i.slice(0,u);i=i.slice(u),this.parseHost(f),this.hostname=this.hostname||"";const h=this.hostname[0]==="["&&this.hostname[this.hostname.length-1]==="]";if(!h){const m=this.hostname.split(/\./);for(let v=0,k=m.length;v<k;v++){const w=m[v];if(w&&!w.match(cC)){let b="";for(let _=0,g=w.length;_<g;_++)w.charCodeAt(_)>127?b+="x":b+=w[_];if(!b.match(cC)){const _=m.slice(0,v),g=m.slice(v+1),x=w.match(ete);x&&(_.push(x[1]),g.unshift(x[2])),g.length&&(i=g.join(".")+i),this.hostname=_.join(".");break}}}}this.hostname.length>Qee&&(this.hostname=""),h&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}const l=i.indexOf("#");l!==-1&&(this.hash=i.substr(l),i=i.slice(0,l));const a=i.indexOf("?");return a!==-1&&(this.search=i.substr(a),i=i.slice(0,a)),i&&(this.pathname=i),fC[n]&&this.hostname&&!this.pathname&&(this.pathname=""),this};Hm.prototype.parseHost=function(e){let t=Gee.exec(e);t&&(t=t[0],t!==":"&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)};var Fy=tte,NE=EE({decode:()=>L3,encode:()=>$E,format:()=>Ny,parse:()=>Fy}),FE=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,RE=/[\0-\x1F\x7F-\x9F]/,nte=/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/,OE=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/,ote=/[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC2\uFD40-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF76\uDF7B-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC5\uDECE-\uDEDB\uDEE0-\uDEE8\uDEF0-\uDEF8\uDF00-\uDF92\uDF94-\uDFCA]/,PE=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/,ste=EE({Any:()=>FE,Cc:()=>RE,Cf:()=>nte,P:()=>OE,S:()=>ote,Z:()=>PE}),ite=Object.defineProperty,DE=e=>{let t={};for(var n in e)ite(t,n,{get:e[n],enumerable:!0});return t},ws=class{type;tag;attrs;map;nesting;level;children;content;markup;info;meta;block;hidden;constructor(e,t,n){this.type=e,this.tag=t,this.attrs=null,this.map=null,this.nesting=n,this.level=0,this.children=null,this.content="",this.markup="",this.info="",this.meta=null,this.block=!1,this.hidden=!1}attrIndex(e){if(!this.attrs)return-1;const t=this.attrs;for(let n=0,o=t.length;n<o;n++)if(t[n][0]===e)return n;return-1}attrPush(e){this.attrs?this.attrs.push(e):this.attrs=[e]}attrSet(e,t){const n=this.attrIndex(e),o=[e,t];n<0?this.attrPush(o):this.attrs[n]=o}attrGet(e){const t=this.attrIndex(e);let n=null;return t>=0&&(n=this.attrs[t][1]),n}attrJoin(e,t){const n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=`${this.attrs[n][1]} ${t}`}},rte=DE({arrayReplaceAt:()=>pte,assign:()=>dte,countLines:()=>Wo,escapeHtml:()=>wte,escapeRE:()=>xte,fromCodePoint:()=>wp,has:()=>cte,isMdAsciiPunct:()=>Um,isPunctChar:()=>Wm,isPunctCode:()=>$3,isSpace:()=>fte,isString:()=>ate,isValidEntityCode:()=>y2,isWhiteSpace:()=>Cp,lib:()=>Ste,mdurl:()=>NE,normalizeReference:()=>v2,ucmicro:()=>zm,unescapeAll:()=>_p,unescapeMd:()=>vte});const zm=ste;function lte(e){return Object.prototype.toString.call(e)}function ate(e){return lte(e)==="[object String]"}const ute=Object.prototype.hasOwnProperty;function cte(e,t){return ute.call(e,t)}function dte(e,...t){return t.forEach(n=>{if(n){if(typeof n!="object")throw new TypeError(`${String(n)}must be object`);Object.keys(n).forEach(o=>{e[o]=n[o]})}}),e}function fte(e){return e===9||e===32}function Cp(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function Wm(e){return zm.P.test(e)||zm.S.test(e)}const pC=new Map;function $3(e){if(Um(e))return!0;if(e>=0&&e<128)return!1;const t=pC.get(e);if(t!==void 0)return t;const n=Wm(String.fromCharCode(e));return pC.set(e,n),n}function Um(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function v2(e){return e=e.trim().replace(/\s+/g," "),"ẞ".toLowerCase()==="Ṿ"&&(e=e.replace(/ẞ/g,"ß")),e.toLowerCase().toUpperCase()}function pte(e,t,n){return[...e.slice(0,t),...n,...e.slice(t+1)]}function y2(e){return!(e>=55296&&e<=57343||e>=64976&&e<=65007||(e&65535)===65535||(e&65535)===65534||e>=0&&e<=8||e===11||e>=14&&e<=31||e>=127&&e<=159||e>1114111)}function wp(e){if(e>65535){e-=65536;const t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}const BE=/\\([!"#$%&'()*+,\-\./:;<=>?@[\\\]^_`{|}~])/g,hte=new RegExp(`${BE.source}|${/&([a-z#][a-z0-9]{1,31});/gi.source}`,"gi"),mte=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;function gte(e,t){if(t.charCodeAt(0)===35&&mte.test(t)){const o=t[1].toLowerCase()==="x"?Number.parseInt(t.slice(2),16):Number.parseInt(t.slice(1),10);return y2(o)?wp(o):e}const n=$y(e);return n!==e?n:e}function vte(e){return e.includes("\\")?e.replace(BE,"$1"):e}function _p(e){return!e.includes("\\")&&!e.includes("&")?e:e.replace(hte,(t,n,o)=>n||gte(t,o))}const yte=/[&<>"]/,kte=/[&<>"]/g,bte={"&":"&","<":"<",">":">",'"':"""};function Cte(e){return bte[e]}function wte(e){return yte.test(e)?e.replace(kte,Cte):e}const _te=/[.?*+^$[\]\\(){}|-]/g;function xte(e){return e.replace(_te,"\\$&")}const Ste={mdurl:NE,ucmicro:zm};function Wo(e){if(e.length===0)return 0;let t=0,n=-1;for(;(n=e.indexOf(` +`,n+1))!==-1;)t++;return t}const Ate=/(?:^|\n)[ \t]{0,3}\[\^[^\]\n]+\]:/m,Mte=/(?:^|\n)[ \t]{0,3}\*\[[^\]\n]+\]:/m,Tte=/(?:^|\n)[ \t]{0,3}\[(?!\^)(?:\\[\s\S]|[^\]\\[])+\][ \t]*:/m,Ry=["references","footnotes","abbreviations","abbr","abbrs"],Oy=Symbol.for("markdown-it-ts.global-state"),Py=Object.prototype.hasOwnProperty;function hC(e){return e==="reference-definition"||e==="footnote-definition"||e==="abbreviation-definition"}function Wr(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ja(e){if(Array.isArray(e))return e.map(t=>ja(t));if(Wr(e)){const t={};for(const n of Object.keys(e))t[n]=ja(e[n]);return t}return e}function jm(e){return Array.isArray(e)?e.map((t,n)=>String(n)):Wr(e)?Object.keys(e):[]}function N3(e,t){if(Array.isArray(e)||Array.isArray(t)){if(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!N3(e[n],t[n]))return!1;return!0}if(Wr(e)||Wr(t)){if(!Wr(e)||!Wr(t))return!1;const n=Object.keys(e),o=Object.keys(t);if(n.length!==o.length)return!1;for(const s of n)if(!Py.call(t,s)||!N3(e[s],t[s]))return!1;return!0}return Object.is(e,t)}function HE(e,t){if(Array.isArray(e))return e[Number(t)];if(Wr(e))return e[t]}function Ete(e,t){if(Array.isArray(e)&&Array.isArray(t)){e.length=t.length;for(let n=0;n<t.length;n++)e[n]=ja(t[n]);return e}if(Wr(e)&&Wr(t)){for(const n of Object.keys(e))Py.call(t,n)||delete e[n];for(const n of Object.keys(t))e[n]=ja(t[n]);return e}return ja(t)}function Ite(e,t,n){const o=n.ownedKeys??[],s=e[t];if(Wr(s)||Array.isArray(s)){const i=new Set(jm(n.value));for(const r of o)n.existed&&i.has(r)?s[r]=ja(HE(n.value,r)):delete s[r];!n.existed&&jm(s).length===0&&delete e[t];return}n.existed?e[t]=ja(n.value):delete e[t]}function Dy(e){const t=e[Oy];return hC(t)?{reason:t,snapshot:{}}:t&&typeof t=="object"&&hC(t.reason)&&t.snapshot&&typeof t.snapshot=="object"?t:null}function Lte(e,t){Object.defineProperty(e,Oy,{value:t,enumerable:!1,configurable:!0,writable:!0})}function Ri(e){return!e||!e.includes("]:")&&!e.includes("*[")?null:Ate.test(e)?"footnote-definition":Mte.test(e)?"abbreviation-definition":Tte.test(e)?"reference-definition":null}function Vp(e){return Dy(e)?.reason??null}function Hd(e,t,n){if(Vp(e)&&la(e),!t)return n();By(e,t);try{const o=n();return Hy(e),o}catch(o){throw la(e),o}}function By(e,t){try{la(e);const n={};for(const o of Ry)n[o]=Py.call(e,o)?{existed:!0,value:ja(e[o])}:{existed:!1};Lte(e,{reason:t,snapshot:n})}catch{}}function Hy(e){const t=Dy(e);if(t)for(const n of Ry){const o=t.snapshot[n];if(!o)continue;o.ownedKeys=[];const s=e[n];if(!Wr(s)&&!Array.isArray(s))continue;const i=new Set(jm(o.existed?o.value:void 0));o.ownedKeys=jm(s).filter(r=>i.has(r)?!N3(s[r],HE(o.value,r)):!0)}}function la(e){const t=Dy(e);if(t){for(const n of Ry){const o=t.snapshot[n];if(!o){delete e[n];continue}if(o.ownedKeys){Ite(e,n,o);continue}o.existed?e[n]=Ete(e[n],o.value):delete e[n]}delete e[Oy]}}function g9(e){return{area:e,attempted:!0,matched:!1,attemptMs:0,blocks:0,headings:0,paragraphs:0,lists:0,fences:0,paragraphCacheHits:0,paragraphCacheMisses:0,paragraphCacheBypasses:0,listCacheHits:0,listCacheMisses:0,fenceCacheHits:0,fenceCacheMisses:0}}const F3=Symbol.for("markdown-it-ts.diagnostics");function qp(e,t){if(e)try{const n=e[F3];if(n&&typeof n=="object")return n;if(!t)return;const o={};return e[F3]=o,o}catch{return}}function Vl(e){return qp(e,!1)}function $te(e){if(e)try{const t=e[F3];t&&typeof t=="object"&&(delete t.strategy,delete t.chunk,delete t.unbounded,delete t.editable,delete t.stockFast)}catch{}}function vi(e){$te(e)}function tf(e,t){const n=qp(e,!0);n&&(n.stockFast=t)}function ss(e,t){const n=qp(e,!0);n&&(n.strategy=t)}function v9(e,t){const n=qp(e,!0);n&&(n.chunk=t)}function zE(e,t){const n=qp(e,!0);n&&(n.unbounded=t)}function Nte(e){const t={};e=e||{},t.src_Any=FE.source,t.src_Cc=RE.source,t.src_Z=PE.source,t.src_P=OE.source,t.src_ZPCc=[t.src_Z,t.src_P,t.src_Cc].join("|"),t.src_ZCc=[t.src_Z,t.src_Cc].join("|");const n="[><|]";return t.src_pseudo_letter=`(?:(?!${n}|${t.src_ZPCc})${t.src_Any})`,t.src_ip4="(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)",t.src_auth=`(?:(?:(?!${t.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`,t.src_port="(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?",t.src_host_terminator=`(?=$|${n}|${t.src_ZPCc})(?!${e["---"]?"-(?!--)|":"-|"}_|:\\d|\\.-|\\.(?!$|${t.src_ZPCc}))`,t.src_path=`(?:[/?#](?:(?!${t.src_ZCc}|${n}|[()[\\]{}.,"'?!\\-;]).|\\[(?:(?!${t.src_ZCc}|\\]).)*\\]|\\((?:(?!${t.src_ZCc}|[)]).)*\\)|\\{(?:(?!${t.src_ZCc}|[}]).)*\\}|\\"(?:(?!${t.src_ZCc}|["]).)+\\"|\\'(?:(?!${t.src_ZCc}|[']).)+\\'|\\'(?=${t.src_pseudo_letter}|[-])|\\.{2,}[a-zA-Z0-9%/&]|\\.(?!${t.src_ZCc}|[.]|$)|`+(e["---"]?"\\-(?!--(?:[^-]|$))(?:-*)|":"\\-+|")+`,(?!${t.src_ZCc}|$)|;(?!${t.src_ZCc}|$)|\\!+(?!${t.src_ZCc}|[!]|$)|\\?(?!${t.src_ZCc}|[?]|$))+|\\/)?`,t.src_email_name='[\\-;:&=\\+\\$,\\.a-zA-Z0-9_][\\-;:&=\\+\\$,\\"\\.a-zA-Z0-9_]{0,63}',t.src_xn="xn--[a-z0-9\\-]{1,59}",t.src_domain_root="(?:"+t.src_xn+`|${t.src_pseudo_letter}{1,63})`,t.src_domain="(?:"+t.src_xn+`|(?:${t.src_pseudo_letter})|(?:${t.src_pseudo_letter}(?:-|${t.src_pseudo_letter}){0,61}${t.src_pseudo_letter}))`,t.src_host=`(?:(?:(?:(?:${t.src_domain})\\.)*${t.src_domain}))`,t.tpl_host_fuzzy="(?:"+t.src_ip4+`|(?:(?:(?:${t.src_domain})\\.)+(?:%TLDS%)))`,t.tpl_host_no_ip_fuzzy=`(?:(?:(?:${t.src_domain})\\.)+(?:%TLDS%))`,t.src_host_strict=t.src_host+t.src_host_terminator,t.tpl_host_fuzzy_strict=t.tpl_host_fuzzy+t.src_host_terminator,t.src_host_port_strict=t.src_host+t.src_port+t.src_host_terminator,t.tpl_host_port_fuzzy_strict=t.tpl_host_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_port_no_ip_fuzzy_strict=t.tpl_host_no_ip_fuzzy+t.src_port+t.src_host_terminator,t.tpl_host_fuzzy_test=`localhost|www\\.|\\.\\d{1,3}\\.|(?:\\.(?:%TLDS%)(?:${t.src_ZPCc}|>|$))`,t.tpl_email_fuzzy=`(^|${n}|"|\\(|${t.src_ZCc})(${t.src_email_name}@${t.tpl_host_fuzzy_strict})`,t.tpl_link_fuzzy=`(^|(?![.:/\\-_@])(?:[$+<=>^\`||]|${t.src_ZPCc}))((?![$+<=>^\`||])${t.tpl_host_port_fuzzy_strict}${t.src_path})`,t.tpl_link_no_ip_fuzzy=`(^|(?![.:/\\-_@])(?:[$+<=>^\`||]|${t.src_ZPCc}))((?![$+<=>^\`||])${t.tpl_host_port_no_ip_fuzzy_strict}${t.src_path})`,t}function R3(e){return Array.prototype.slice.call(arguments,1).forEach(function(t){t&&Object.keys(t).forEach(function(n){e[n]=t[n]})}),e}function k2(e){return Object.prototype.toString.call(e)}function Fte(e){return k2(e)==="[object String]"}function Rte(e){return k2(e)==="[object Object]"}function Ote(e){return k2(e)==="[object RegExp]"}function mC(e){return k2(e)==="[object Function]"}function Pte(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}const WE={fuzzyLink:!0,fuzzyEmail:!0,fuzzyIP:!1};function Dte(e){return Object.keys(e||{}).reduce(function(t,n){return t||WE.hasOwnProperty(n)},!1)}const Bte={"http:":{validate:function(e,t,n){const o=e.slice(t);return n.re.http||(n.re.http=new RegExp(`^\\/\\/${n.re.src_auth}${n.re.src_host_port_strict}${n.re.src_path}`,"i")),n.re.http.test(o)?o.match(n.re.http)[0].length:0}},"https:":"http:","ftp:":"http:","//":{validate:function(e,t,n){const o=e.slice(t);return n.re.no_http||(n.re.no_http=new RegExp("^"+n.re.src_auth+`(?:localhost|(?:(?:${n.re.src_domain})\\.)+${n.re.src_domain_root})`+n.re.src_port+n.re.src_host_terminator+n.re.src_path,"i")),n.re.no_http.test(o)?t>=3&&e[t-3]===":"||t>=3&&e[t-3]==="/"?0:o.match(n.re.no_http)[0].length:0}},"mailto:":{validate:function(e,t,n){const o=e.slice(t);return n.re.mailto||(n.re.mailto=new RegExp(`^${n.re.src_email_name}@${n.re.src_host_strict}`,"i")),n.re.mailto.test(o)?o.match(n.re.mailto)[0].length:0}}},Hte="a[cdefgilmnoqrstuwxz]|b[abdefghijmnorstvwyz]|c[acdfghiklmnoruvwxyz]|d[ejkmoz]|e[cegrstu]|f[ijkmor]|g[abdefghilmnpqrstuwy]|h[kmnrtu]|i[delmnoqrst]|j[emop]|k[eghimnprwyz]|l[abcikrstuvy]|m[acdeghklmnopqrstuvwxyz]|n[acefgilopruz]|om|p[aefghklmnrstwy]|qa|r[eosuw]|s[abcdeghijklmnortuvxyz]|t[cdfghjklmnortvwz]|u[agksyz]|v[aceginu]|w[fs]|y[et]|z[amw]",zte="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф".split("|");function Wte(e){return function(t,n){const o=t.slice(n);return e.test(o)?o.match(e)[0].length:0}}function gC(){return function(e,t){t.normalize(e)}}function Vm(e){const t=e.re=Nte(e.__opts__),n=e.__tlds__.slice();e.onCompile(),e.__tlds_replaced__||n.push(Hte),n.push(t.src_xn),t.src_tlds=n.join("|");function o(l){return l.replace("%TLDS%",t.src_tlds)}t.email_fuzzy=RegExp(o(t.tpl_email_fuzzy),"i"),t.email_fuzzy_global=RegExp(o(t.tpl_email_fuzzy),"ig"),t.link_fuzzy=RegExp(o(t.tpl_link_fuzzy),"i"),t.link_fuzzy_global=RegExp(o(t.tpl_link_fuzzy),"ig"),t.link_no_ip_fuzzy=RegExp(o(t.tpl_link_no_ip_fuzzy),"i"),t.link_no_ip_fuzzy_global=RegExp(o(t.tpl_link_no_ip_fuzzy),"ig"),t.host_fuzzy_test=RegExp(o(t.tpl_host_fuzzy_test),"i");const s=[];e.__compiled__={};function i(l,a){throw new Error(`(LinkifyIt) Invalid schema "${l}": ${a}`)}Object.keys(e.__schemas__).forEach(function(l){const a=e.__schemas__[l];if(a===null)return;const u={validate:null,link:null};if(e.__compiled__[l]=u,Rte(a)){Ote(a.validate)?u.validate=Wte(a.validate):mC(a.validate)?u.validate=a.validate:i(l,a),mC(a.normalize)?u.normalize=a.normalize:a.normalize?i(l,a):u.normalize=gC();return}if(Fte(a)){s.push(l);return}i(l,a)}),s.forEach(function(l){e.__compiled__[e.__schemas__[l]]&&(e.__compiled__[l].validate=e.__compiled__[e.__schemas__[l]].validate,e.__compiled__[l].normalize=e.__compiled__[e.__schemas__[l]].normalize)}),e.__compiled__[""]={validate:null,normalize:gC()};const r=Object.keys(e.__compiled__).filter(function(l){return l.length>0&&e.__compiled__[l]}).map(Pte).join("|");e.re.schema_test=RegExp(`(^|(?!_)(?:[><|]|${t.src_ZPCc}))(${r})`,"i"),e.re.schema_search=RegExp(`(^|(?!_)(?:[><|]|${t.src_ZPCc}))(${r})`,"ig"),e.re.schema_at_start=RegExp(`^${e.re.schema_search.source}`,"i"),e.re.pretest=RegExp(`(${e.re.schema_test.source})|(${e.re.host_fuzzy_test.source})|@`,"i")}function UE(e,t,n,o){const s=e.slice(n,o);this.schema=t.toLowerCase(),this.index=n,this.lastIndex=o,this.raw=s,this.text=s,this.url=s}function cr(e,t){if(!(this instanceof cr))return new cr(e,t);t||Dte(e)&&(t=e,e={}),this.__opts__=R3({},WE,t),this.__schemas__=R3({},Bte,e),this.__compiled__={},this.__tlds__=zte,this.__tlds_replaced__=!1,this.re={},Vm(this)}cr.prototype.add=function(t,n){return this.__schemas__[t]=n,Vm(this),this};cr.prototype.set=function(t){return this.__opts__=R3(this.__opts__,t),this};cr.prototype.test=function(t){if(!t.length)return!1;let n,o;if(this.re.schema_test.test(t)){for(o=this.re.schema_search,o.lastIndex=0;(n=o.exec(t))!==null;)if(this.testSchemaAt(t,n[2],o.lastIndex))return!0}return!!(this.__opts__.fuzzyLink&&this.__compiled__["http:"]&&t.search(this.re.host_fuzzy_test)>=0&&t.match(this.__opts__.fuzzyIP?this.re.link_fuzzy:this.re.link_no_ip_fuzzy)!==null||this.__opts__.fuzzyEmail&&this.__compiled__["mailto:"]&&t.indexOf("@")>=0&&t.match(this.re.email_fuzzy)!==null)};cr.prototype.pretest=function(t){return this.re.pretest.test(t)};cr.prototype.testSchemaAt=function(t,n,o){return this.__compiled__[n.toLowerCase()]?this.__compiled__[n.toLowerCase()].validate(t,o,this):0};cr.prototype.match=function(t){const n=[],o=[],s=[],i=[];let r,l,a;function u(f,h){return f?h?f.index!==h.index?f.index<h.index?f:h:f.lastIndex>=h.lastIndex?f:h:f:h}if(!t.length)return null;if(this.re.schema_test.test(t))for(a=this.re.schema_search,a.lastIndex=0;(r=a.exec(t))!==null;)l=this.testSchemaAt(t,r[2],a.lastIndex),l&&o.push({schema:r[2],index:r.index+r[1].length,lastIndex:r.index+r[0].length+l});if(this.__opts__.fuzzyLink&&this.__compiled__["http:"])for(a=this.__opts__.fuzzyIP?this.re.link_fuzzy_global:this.re.link_no_ip_fuzzy_global,a.lastIndex=0;(r=a.exec(t))!==null;)s.push({schema:"",index:r.index+r[1].length,lastIndex:r.index+r[0].length});if(this.__opts__.fuzzyEmail&&this.__compiled__["mailto:"])for(a=this.re.email_fuzzy_global,a.lastIndex=0;(r=a.exec(t))!==null;)i.push({schema:"mailto:",index:r.index+r[1].length,lastIndex:r.index+r[0].length});const c=[0,0,0];let d=0;for(;;){const f=[o[c[0]],i[c[1]],s[c[2]]],h=u(u(f[0],f[1]),f[2]);if(!h)break;if(h===f[0]?c[0]++:h===f[1]?c[1]++:c[2]++,h.index<d)continue;const m=new UE(t,h.schema,h.index,h.lastIndex);this.__compiled__[m.schema].normalize(m,this),n.push(m),d=h.lastIndex}return n.length?n:null};cr.prototype.matchAtStart=function(t){if(!t.length)return null;const n=this.re.schema_at_start.exec(t);if(!n)return null;const o=this.testSchemaAt(t,n[2],n[0].length);if(!o)return null;const s=new UE(t,n[2],n.index+n[1].length,n.index+n[0].length+o);return this.__compiled__[s.schema].normalize(s,this),s};cr.prototype.tlds=function(t,n){return t=Array.isArray(t)?t:[t],n?(this.__tlds__=this.__tlds__.concat(t).sort().filter(function(o,s,i){return o!==i[s-1]}).reverse(),Vm(this),this):(this.__tlds__=t.slice(),this.__tlds_replaced__=!0,Vm(this),this)};cr.prototype.normalize=function(t){t.schema||(t.url=`http://${t.url}`),t.schema==="mailto:"&&!/^mailto:/i.test(t.url)&&(t.url=`mailto:${t.url}`)};cr.prototype.onCompile=function(){};var jE=cr,Ute=TE({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js":((e,t)=>{const d=/^xn--/,f=/[^\0-\x7F]/,h=/[\x2E\u3002\uFF0E\uFF61]/g,m={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},v=35,k=Math.floor,w=String.fromCharCode;function b(H){throw new RangeError(m[H])}function _(H,O){const F=[];let U=H.length;for(;U--;)F[U]=O(H[U]);return F}function g(H,O){const F=H.split("@");let U="";F.length>1&&(U=F[0]+"@",H=F[1]),H=H.replace(h,".");const z=_(H.split("."),O).join(".");return U+z}function x(H){const O=[];let F=0;const U=H.length;for(;F<U;){const z=H.charCodeAt(F++);if(z>=55296&&z<=56319&&F<U){const W=H.charCodeAt(F++);(W&64512)==56320?O.push(((z&1023)<<10)+(W&1023)+65536):(O.push(z),F--)}else O.push(z)}return O}const S=H=>String.fromCodePoint(...H),T=function(H){return H>=48&&H<58?26+(H-48):H>=65&&H<91?H-65:H>=97&&H<123?H-97:36},A=function(H,O){return H+22+75*(H<26)-((O!=0)<<5)},E=function(H,O,F){let U=0;for(H=F?k(H/700):H>>1,H+=k(H/O);H>v*26>>1;U+=36)H=k(H/v);return k(U+(v+1)*H/(H+38))},P=function(H){const O=[],F=H.length;let U=0,z=128,W=72,K=H.lastIndexOf("-");K<0&&(K=0);for(let V=0;V<K;++V)H.charCodeAt(V)>=128&&b("not-basic"),O.push(H.charCodeAt(V));for(let V=K>0?K+1:0;V<F;){const ie=U;for(let X=1,le=36;;le+=36){V>=F&&b("invalid-input");const Ie=T(H.charCodeAt(V++));Ie>=36&&b("invalid-input"),Ie>k((2147483647-U)/X)&&b("overflow"),U+=Ie*X;const de=le<=W?1:le>=W+26?26:le-W;if(Ie<de)break;const pe=36-de;X>k(2147483647/pe)&&b("overflow"),X*=pe}const ne=O.length+1;W=E(U-ie,ne,ie==0),k(U/ne)>2147483647-z&&b("overflow"),z+=k(U/ne),U%=ne,O.splice(U++,0,z)}return String.fromCodePoint(...O)},D=function(H){const O=[];H=x(H);const F=H.length;let U=128,z=0,W=72;for(const ie of H)ie<128&&O.push(w(ie));const K=O.length;let V=K;for(K&&O.push("-");V<F;){let ie=2147483647;for(const X of H)X>=U&&X<ie&&(ie=X);const ne=V+1;ie-U>k((2147483647-z)/ne)&&b("overflow"),z+=(ie-U)*ne,U=ie;for(const X of H)if(X<U&&++z>2147483647&&b("overflow"),X===U){let le=z;for(let Ie=36;;Ie+=36){const de=Ie<=W?1:Ie>=W+26?26:Ie-W;if(le<de)break;const pe=le-de,ve=36-de;O.push(w(A(de+pe%ve,0))),le=k(pe/ve)}O.push(w(A(le,0))),W=E(z,ne,V===K),z=0,++V}++z,++U}return O.join("")},B={version:"2.3.1",ucs2:{decode:x,encode:S},decode:P,encode:D,toASCII:function(H){return g(H,function(O){return f.test(O)?"xn--"+D(O):O})},toUnicode:function(H){return g(H,function(O){return d.test(O)?P(O.slice(4).toLowerCase()):O})}};t.exports=B})}),VE=IE(Ute());function zy(e,t,n){let o,s=t;const i={ok:!1,pos:0,str:""};if(e.charCodeAt(s)===60){for(s++;s<n;){if(o=e.charCodeAt(s),o===10||o===60)return i;if(o===62)return i.pos=s+1,i.str=_p(e.slice(t+1,s)),i.ok=!0,i;if(o===92&&s+1<n){s+=2;continue}s++}return i}let r=0;for(;s<n&&(o=e.charCodeAt(s),!(o===32||o<32||o===127));){if(o===92&&s+1<n){if(e.charCodeAt(s+1)===32)break;s+=2;continue}if(o===40&&(r++,r>32))return i;if(o===41){if(r===0)break;r--}s++}return t===s||r!==0||(i.str=_p(e.slice(t,s)),i.pos=s,i.ok=!0),i}var qE=zy;const Uh=-2;function jte(e,t,n,o){let s=1,i=t+1;for(;i<n;){const r=e.charCodeAt(i);if(r===93){if(s--,s===0)return i;if(o){const l=i+1<n?e.charCodeAt(i+1):0;if(l===40||l===91)return Uh}i++;continue}if(r===92){i+=2;continue}if(r===96||r===60||r===33&&i+1<n&&e.charCodeAt(i+1)===91)return Uh;if(r===91){s++,i++;continue}i++}return-1}function Wy(e,t,n){let o=1,s=!1,i,r;const l=e.src,a=e.posMax,u=e.pos,c=e.linkLabelNoCloseFrom;if(c>=0&&t+1>=c)return-1;const d=l.indexOf("]",t+1);if(d<0||d>=a)return e.linkLabelNoCloseFrom=t+1,-1;const f=jte(l,t,a,n);if(f!==Uh)return f;for(e.pos=t+1;e.pos<a;){if(i=l.charCodeAt(e.pos),i===93&&(o--,o===0)){s=!0;break}if(r=e.pos,e.md.inline.skipToken(e),i===91){if(r===e.pos-1)o++;else if(n)return e.pos=u,-1}}let h=-1;return s&&(h=e.pos),e.pos=u,h}var qm=Wy;function Uy(e,t,n,o){let s,i=t;const r={ok:!1,can_continue:!1,pos:0,str:"",marker:0};if(o)r.str=o.str,r.marker=o.marker;else{if(i>=n)return r;let l=e.charCodeAt(i);if(l!==34&&l!==39&&l!==40)return r;t++,i++,l===40&&(l=41),r.marker=l}for(;i<n;){if(s=e.charCodeAt(i),s===r.marker)return r.pos=i+1,r.str+=_p(e.slice(t,i)),r.ok=!0,r;if(s===40&&r.marker===41)return r;s===92&&i+1<n&&i++,i++}return r.can_continue=!0,r.str+=_p(e.slice(t,i)),r}var KE=Uy;function b2(e,t){if(!e.attrs)return-1;for(let n=0;n<e.attrs.length;n++)if(e.attrs[n][0]===t)return n;return-1}function jy(e,t){e.attrs||(e.attrs=[]),e.attrs.push(t)}function Vte(e,t,n){const o=b2(e,t),s=[t,n];o<0?jy(e,s):e.attrs[o]=s}function qte(e,t){const n=b2(e,t);return n>=0?e.attrs[n][1]:null}function Kte(e,t,n){const o=b2(e,t);o<0?jy(e,[t,n]):e.attrs[o][1]=`${e.attrs[o][1]} ${n}`}var Zte=DE({attrGet:()=>qte,attrIndex:()=>b2,attrJoin:()=>Kte,attrPush:()=>jy,attrSet:()=>Vte,parseLinkDestination:()=>zy,parseLinkLabel:()=>Wy,parseLinkTitle:()=>Uy});function Gte(e){return e.includes("\r")||e.includes("\0")}function ZE(e){return typeof e=="string"?e:e.toString()}function Yte(e){if(e.inlineMode){const t=new ws("inline","",0);t.content=ZE(e.src),t.map=[0,1],t.children=[],t.level=0,e.tokens.push(t)}else e.md&&e.md.block&&e.md.block.parse(e.src,e.md,e.env,e.tokens)}const Xte=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,Jte=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function Qte(e,t){let n=e.pos;const o=e.src;if(o.charCodeAt(n)!==60)return!1;const s=n,i=e.posMax;for(;;){if(++n>=i)return!1;const l=o.charCodeAt(n);if(l===60)return!1;if(l===62)break}const r=o.slice(s+1,n);if(Jte.test(r)){const l=e.md.normalizeLink(r);if(!e.md.validateLink(l))return!1;if(!t){const a=e.push("link_open","a",1);a.attrs=[["href",l]],a.markup="autolink",a.info="auto";const u=e.push("text","",0);u.content=e.md.normalizeLinkText(r);const c=e.push("link_close","a",-1);c.markup="autolink",c.info="auto"}return e.pos+=r.length+2,!0}if(Xte.test(r)){const l=e.md.normalizeLink(`mailto:${r}`);if(!e.md.validateLink(l))return!1;if(!t){const a=e.push("link_open","a",1);a.attrs=[["href",l]],a.markup="autolink",a.info="auto";const u=e.push("text","",0);u.content=e.md.normalizeLinkText(r);const c=e.push("link_close","a",-1);c.markup="autolink",c.info="auto"}return e.pos+=r.length+2,!0}return!1}var GE=Qte;function ene(e,t){const n=e.src;let o=e.pos;if(n.charCodeAt(o)!==96)return!1;const s=o;o++;const i=e.posMax;for(;o<i&&n.charCodeAt(o)===96;)o++;const r=n.slice(s,o),l=r.length;if(e.backticksScanned&&(e.backticks[l]||0)<=s)return t||(e.pending+=r),e.pos+=l,!0;let a=o,u;for(;(u=n.indexOf("`",a))!==-1;){for(a=u+1;a<i&&n.charCodeAt(a)===96;)a++;const c=a-u;if(c===l){if(!t){const d=e.push("code_inline","code",0);d.markup=r;let f=n.slice(o,u);f.includes(` +`)&&(f=f.replace(/\n/g," ")),f.length>2&&f.charCodeAt(0)===32&&f.charCodeAt(f.length-1)===32&&(f=f.slice(1,-1)),d.content=f}return e.pos=a,!0}e.backticks[c]=u}return e.backticksScanned=!0,t||(e.pending+=r),e.pos+=l,!0}var YE=ene;function vC(e){const t={},n=e.length;if(!n)return;let o=0,s=-2;const i=[];for(let r=0;r<n;r++){const l=e[r];if(i.push(0),(e[o].marker!==l.marker||s!==l.token-1)&&(o=r),s=l.token,l.length=l.length||0,!l.close)continue;Object.prototype.hasOwnProperty.call(t,l.marker)||(t[l.marker]=[-1,-1,-1,-1,-1,-1]);const a=t[l.marker][(l.open?3:0)+l.length%3];let u=o-i[o]-1,c=u;for(;u>a;u-=i[u]+1){const d=e[u];if(d.marker===l.marker&&d.open&&d.end<0){let f=!1;if((d.close||l.open)&&(d.length+l.length)%3===0&&(d.length%3!==0||l.length%3!==0)&&(f=!0),!f){const h=u>0&&!e[u-1].open?i[u-1]+1:0;i[r]=r-u+h,i[u]=h,l.open=!1,d.end=r,d.close=!1,c=-1,s=-2;break}}}c!==-1&&(t[l.marker][(l.open?3:0)+(l.length||0)%3]=c)}}function tne(e){const t=e.tokens_meta,n=e.tokens_meta.length;vC(e.delimiters);for(let o=0;o<n;o++)t[o]&&t[o].delimiters&&vC(t[o].delimiters)}var nne=tne;const XE="*",JE="_";function one(e,t){if(t)return!1;const n=e.src.charCodeAt(e.pos);if(n!==95&&n!==42)return!1;const o=e.scanDelims(e.pos,n===42);if(!o||o.length===0)return!1;const s=n===42?XE:JE,i=o.length,r=o.can_open,l=o.can_close,a=e.tokens,u=e.delimiters;for(let c=0;c<i;c++){const d=e.push("text","",0);d.content=s,u.push({marker:n,length:i,token:a.length-1,end:-1,open:r,close:l})}return e.pos+=i,!0}function yC(e,t){const n=t.length,o=e.tokens;for(let s=n-1;s>=0;s--){const i=t[s],r=i.marker;if(r!==95&&r!==42||i.end===-1)continue;const l=t[i.end],a=i.token,u=l.token,c=s>0&&t[s-1].end===i.end+1&&t[s-1].marker===r&&t[s-1].token===a-1&&t[i.end+1].token===u+1,d=r===42?XE:JE,f=o[a];c?(f.type="strong_open",f.tag="strong",f.nesting=1,f.markup=d+d,f.content=""):(f.type="em_open",f.tag="em",f.nesting=1,f.markup=d,f.content="");const h=o[u];c?(h.type="strong_close",h.tag="strong",h.nesting=-1,h.markup=d+d,h.content=""):(h.type="em_close",h.tag="em",h.nesting=-1,h.markup=d,h.content=""),c&&(o[t[s-1].token].content="",o[t[i.end+1].token].content="",s--)}}function sne(e){const t=e.tokens_meta,n=e.tokens_meta.length;yC(e,e.delimiters);for(let o=0;o<n;o++)t[o]&&t[o].delimiters&&yC(e,t[o].delimiters)}const O3={tokenize:one,postProcess:sne};function QE(e){return $y(e)}function Vy(e){return e>=48&&e<=57}function ine(e){const t=e|32;return Vy(e)||t>=97&&t<=102}function eI(e){const t=e|32;return t>=97&&t<=122}function rne(e){return eI(e)||Vy(e)}function lne(e,t,n){let o=t+2;if(o>=n)return null;let s=!1,i=7,r=o;for((e.charCodeAt(o)|32)===120&&(s=!0,i=6,o++,r=o);o<n&&o-r<i;){const l=e.charCodeAt(o);if(!(s?ine(l):Vy(l)))break;o++}return o===r||o>=n||e.charCodeAt(o)!==59?null:e.slice(t,o+1)}function ane(e,t,n){let o=t+1;if(o>=n||!eI(e.charCodeAt(o)))return null;for(o++;o<n&&o-t-1<32&&rne(e.charCodeAt(o));)o++;if(o-t-1<2||o>=n||e.charCodeAt(o)!==59)return null;const s=e.slice(t,o+1);return QE(s)!==s?s:null}function une(e,t){const n=e.pos,o=e.posMax;if(e.src.charCodeAt(n)!==38||n+1>=o)return!1;if(e.src.charCodeAt(n+1)===35){const s=lne(e.src,n,o);if(s){if(!t){const i=(s.charCodeAt(2)|32)===120?Number.parseInt(s.slice(3,-1),16):Number.parseInt(s.slice(2,-1),10),r=e.push("text_special","",0);r.content=y2(i)?wp(i):wp(65533),r.markup=s,r.info="entity"}return e.pos+=s.length,!0}}else{const s=ane(e.src,n,o);if(s){const i=QE(s);if(!t){const r=e.push("text_special","",0);r.content=i,r.markup=s,r.info="entity"}return e.pos+=s.length,!0}}return!1}var tI=une;const nI=(()=>{const e=new Array(256).fill(0),t="\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-";for(let n=0;n<32;n++)e[t.charCodeAt(n)]=1;return e})(),P3=new Array(128),oI=new Array(128);for(let e=0;e<128;e++){const t=String.fromCharCode(e);P3[e]=`\\${t}`,oI[e]=nI[e]?t:P3[e]}function kC(e,t,n){e.pending&&e.pushPending();const o=new ws("text_special","",0);o.level=e.level,o.content=t,o.markup=n,o.info="escape",e.pendingLevel=e.level,e.tokens.push(o),e.tokens_meta.push(null)}function cne(e,t){let n=e.pos;const o=e.posMax,s=e.src;if(s.charCodeAt(n)!==92||(n++,n>=o))return!1;let i=s.charCodeAt(n);if(i===10){for(t||e.push("hardbreak","br",0),n++;n<o&&(i=s.charCodeAt(n),!(i!==9&&i!==32));)n++;return e.pos=n,!0}if(i<128)return t?(e.pos=n+1,!0):(kC(e,oI[i],P3[i]),e.pos=n+1,!0);if(t){if(i>=55296&&i<=56319&&n+1<o){const a=s.charCodeAt(n+1);a>=56320&&a<=57343&&n++}return e.pos=n+1,!0}let r=s.charAt(n);if(i>=55296&&i<=56319&&n+1<o){const a=s.charCodeAt(n+1);a>=56320&&a<=57343&&(r+=s.charAt(n+1),n++)}const l=`\\${r}`;return kC(e,i<256&&nI[i]?r:l,l),e.pos=n+1,!0}var sI=cne;function dne(e){let t,n,o=0;const s=e.tokens,i=e.tokens.length;for(t=n=0;t<i;t++){const r=s[t];r&&(r.nesting&&r.nesting<0&&o--,r.level=o,r.nesting&&r.nesting>0&&o++,r.type==="text"&&t+1<i&&s[t+1]?.type==="text"?s[t+1].content=r.content+s[t+1].content:(t!==n&&(s[n]=r),n++))}t!==n&&(s.length=n)}var fne=dne;const iI=`<[A-Za-z][A-Za-z0-9\\-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^"'=<>\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`,rI="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",pne=new RegExp(`^(?:${iI}|${rI}|<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->|<\\?[\\s\\S]*?\\?>|<![A-Za-z][^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`),hne=new RegExp(`^(?:${iI}|${rI})`);function lI(e){return e===32||e===9||e===10||e===12||e===13}function mne(e){if(e.length<3||e.charCodeAt(0)!==60||(e.charCodeAt(1)|32)!==97)return!1;const t=e.charCodeAt(2);return t===62||lI(t)}function gne(e){if(e.length<4||e.charCodeAt(0)!==60||e.charCodeAt(1)!==47||(e.charCodeAt(2)|32)!==97)return!1;for(let t=3;t<e.length;t++){const n=e.charCodeAt(t);if(n===62)return!0;if(!lI(n))return!1}return!1}function vne(e){const t=e|32;return t>=97&&t<=122}function yne(e,t){if(!e.md.options.html)return!1;const n=e.posMax,o=e.pos,s=e.src;if(s.charCodeAt(o)!==60||o+2>=n)return!1;const i=s.charCodeAt(o+1);if(i!==33&&i!==63&&i!==47&&!vne(i))return!1;const r=s.slice(o).match(pne);if(!r)return!1;const l=r[0];if(!t){const a=e.pushSimple("html_inline","");a.content=l,mne(l)&&e.linkLevel++,gne(l)&&e.linkLevel--}return e.pos+=l.length,!0}var aI=yne;function kne(e,t){let n,o,s,i,r,l,a,u,c="";const d=e.pos,f=e.posMax;if(e.src.charCodeAt(e.pos)!==33||e.src.charCodeAt(e.pos+1)!==91)return!1;const h=e.pos+2,m=qm(e,e.pos+1,!1);if(m<0)return!1;if(i=m+1,i<f&&e.src.charCodeAt(i)===40){for(i++;i<f&&(n=e.src.charCodeAt(i),!(n!==32&&n!==10));i++);if(i>=f)return!1;if(l=qE(e.src,i,e.posMax),l.ok){for(c=e.md.normalizeLink(l.str),e.md.validateLink(c)?i=l.pos:c="",u=i;i<f&&(n=e.src.charCodeAt(i),!(n!==32&&n!==10));i++);if(l=KE(e.src,i,e.posMax),i<f&&u!==i&&l.ok)for(a=l.str,i=l.pos;i<f&&(n=e.src.charCodeAt(i),!(n!==32&&n!==10));i++);else a=""}if(i>=f||e.src.charCodeAt(i)!==41)return e.pos=d,!1;i++}else{if(typeof e.env.references>"u")return!1;if(i<f&&e.src.charCodeAt(i)===91?(u=i+1,i=qm(e,i),i>=0?s=e.src.slice(u,i++):i=m+1):i=m+1,s||(s=e.src.slice(h,m)),r=e.env.references[v2(s)],!r)return e.pos=d,!1;c=r.href,a=r.title}if(!t){o=e.src.slice(h,m);const v=[];e.md.inline.parse(o,e.md,e.env,v);const k=e.push("image","img",0);k.attrs=[["src",c],["alt",""]],k.children=v,k.content=o,a&&k.attrs.push(["title",a])}return e.pos=i,e.posMax=f,!0}var uI=kne;function y9(e,t,n){for(;t<n;){const o=e.charCodeAt(t);if(o!==32&&o!==10)break;t++}return t}function bne(e,t){if(e.src.charCodeAt(e.pos)!==91)return!1;const n=e.src,o=e.pos,s=e.posMax,i=e.pos+1,r=qm(e,e.pos,!0);if(r<0)return!1;let l=r+1,a="",u="",c=!0;if(l<s&&n.charCodeAt(l)===40){l=y9(n,l+1,s);const d=qE(n,l,s);if(d.ok){const f=e.md.normalizeLink(d.str);e.md.validateLink(f)&&(a=f,l=d.pos,c=!1)}else l<s&&n.charCodeAt(l)===41&&(a="",c=!1);if(!c){if(l=y9(n,l,s),l<s&&n.charCodeAt(l)!==41){const f=KE(n,l,s);f.ok&&(u=f.str,l=y9(n,f.pos,s))}l<s&&n.charCodeAt(l)===41?l++:c=!0}}if(c){if(typeof e.env.references>"u")return!1;let d;if(l=r+1,l<s&&n.charCodeAt(l)===91){const h=l+1,m=qm(e,l);m>=0?(d=n.slice(h,m),d||(d=n.slice(i,r)),l=m+1):d=n.slice(i,r)}else d=n.slice(i,r);const f=e.env.references[v2(d)];if(!f)return e.pos=o,!1;a=f.href,u=f.title}if(!t){e.pos=i,e.posMax=r;const d=e.push("link_open","a",1);d.attrs=u?[["href",a],["title",u]]:[["href",a]],e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push("link_close","a",-1)}return e.pos=l,e.posMax=s,!0}var cI=bne;function dI(e){const t=e|32;return t>=97&&t<=122}function Cne(e){return e>=48&&e<=57}function wne(e){return dI(e)||Cne(e)||e===43||e===45||e===46}function _ne(e){if(e.length===0)return null;let t=e.length-1;for(;t>=0&&wne(e.charCodeAt(t));)t--;return t++,t>=e.length||!dI(e.charCodeAt(t))?null:e.slice(t)}function xne(e,t,n){let o=t;for(;o<n;){const s=e.charCodeAt(o);if(s<=32||s===127||s===60)break;o++}return e.slice(t,o)}function fI(e,t){if(!e.md.options.linkify||e.linkLevel>0)return!1;const n=e.pos,o=e.posMax;if(n+3>o||e.src.charCodeAt(n)!==58||e.src.charCodeAt(n+1)!==47||e.src.charCodeAt(n+2)!==47)return!1;const s=_ne(e.pending);if(!s)return!1;const i=xne(e.src,n-s.length,o),r=e.md.linkify.matchAtStart(i);if(!r)return!1;let l=r.url;if(l.length<=s.length)return!1;let a=l.length;for(;a>0&&l.charCodeAt(a-1)===42;)a--;a!==l.length&&(l=l.slice(0,a));const u=e.md.normalizeLink(l);if(!e.md.validateLink(u))return!1;if(!t){e.pending=e.pending.slice(0,-s.length);const c=e.push("link_open","a",1);c.attrs=[["href",u]],c.markup="linkify",c.info="auto";const d=e.push("text","",0);d.content=e.md.normalizeLinkText(l);const f=e.push("link_close","a",-1);f.markup="linkify",f.info="auto"}return e.pos+=l.length-s.length,!0}function Sne(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==10)return!1;const o=e.pending.length-1,s=e.posMax;if(!t)if(o>=0&&e.pending.charCodeAt(o)===32)if(o>=1&&e.pending.charCodeAt(o-1)===32){let i=o-1;for(;i>=1&&e.pending.charCodeAt(i-1)===32;)i--;e.pending=e.pending.slice(0,i),e.pushSimple("hardbreak","br")}else e.pending=e.pending.slice(0,-1),e.pushSimple("softbreak","br");else e.pushSimple("softbreak","br");for(n++;n<s;){const i=e.src.charCodeAt(n);if(i!==9&&i!==32)break;n++}return e.pos=n,!0}var pI=Sne;function Ane(e,t){const n=e.pos,o=e.src.charCodeAt(n);if(t||o!==126)return!1;const s=e.scanDelims(e.pos,!0);if(!s)return!1;let i=s.length;const r=String.fromCharCode(o);if(i<2)return!1;let l;i%2&&(l=e.push("text","",0),l.content=r,i--);for(let a=0;a<i;a+=2)l=e.push("text","",0),l.content=r+r,e.delimiters.push({marker:o,length:0,token:e.tokens.length-1,end:-1,open:s.can_open,close:s.can_close});return e.pos+=s.length,!0}function bC(e,t){let n;const o=[],s=t.length;for(let i=0;i<s;i++){const r=t[i];if(r.marker!==126||r.end===-1)continue;const l=t[r.end];n=e.tokens[r.token],n.type="s_open",n.tag="s",n.nesting=1,n.markup="~~",n.content="",n=e.tokens[l.token],n.type="s_close",n.tag="s",n.nesting=-1,n.markup="~~",n.content="",e.tokens[l.token-1].type==="text"&&e.tokens[l.token-1].content==="~"&&o.push(l.token-1)}for(;o.length;){const i=o.pop();let r=i+1;for(;r<e.tokens.length&&e.tokens[r].type==="s_close";)r++;r--,i!==r&&(n=e.tokens[r],e.tokens[r]=e.tokens[i],e.tokens[i]=n)}}function Mne(e){const t=e.delimiters;bC(e,t);const n=e.tokens_meta;if(n)for(let o=0;o<n.length;o++)n[o]&&n[o].delimiters&&bC(e,n[o].delimiters)}const D3={tokenize:Ane,postProcess:Mne};function CC(e){switch(e){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}function Tne(e,t){const n=e.src,o=e.pos,s=e.posMax;if(o>=s||CC(n.charCodeAt(o)))return!1;let i=o+1;for(;i<s&&!CC(n.charCodeAt(i));)i++;return t||(e.pending+=i===o+1?n.charAt(o):n.slice(o,i)),e.pos=i,!0}var hI=Tne;function qy(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function Ene(e){if(e.length===0)return 0;const t=e.slice().sort((o,s)=>o-s),n=Math.floor(t.length/2);return t.length%2===0?(t[n-1]+t[n])/2:t[n]}function Ine(e,t){return{chain:e,name:t,calls:0,hits:0,inclusiveMs:0,medianMs:0,maxMs:0,normalCalls:0,normalHits:0,silentCalls:0,silentHits:0,samples:[]}}function mI(e){const t=e;if(!t)return null;if(t.__mdtsRuleProfile)return t.__mdtsRuleProfile;if(!t.__mdtsProfileRules)return null;const n=t.__mdtsProfileRules===!0?{}:t.__mdtsProfileRules,o={enabled:!0,fixture:n.fixture,mode:n.mode,startedAt:qy(),records:Object.create(null)};return t.__mdtsRuleProfile=o,o}function zd(e,t,n,o,s,i){const r=mI(e);if(!r)return;const l=`${t}:${n}`,a=r.records[l]??(r.records[l]=Ine(t,n));a.calls++,a.inclusiveMs+=o,o>a.maxMs&&(a.maxMs=o),a.samples.push(o),i?(a.silentCalls++,s&&a.silentHits++):(a.normalCalls++,s&&a.normalHits++),s&&a.hits++,r.completedAt=qy()}function Lne(e){const t=mI(e);if(!t)return null;const n=Object.keys(t.records);for(let o=0;o<n.length;o++){const s=t.records[n[o]];s.medianMs=Ene(s.samples)}return t.completedAt=qy(),t}var wC=class{rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t,n){const o=this.rules.findIndex(s=>s.name===e);o>=0&&this.rules.splice(o,1),this.rules.push({name:e,fn:t,alt:n?.alt||[],enabled:!0}),this.invalidateCache()}at(e,t,n){const o=this.rules.findIndex(s=>s.name===e);if(t===void 0){if(o<0)return;const s=this.rules[o];return Object.freeze({name:s.name,fn:s.fn,alt:s.alt?Object.freeze(s.alt.slice()):void 0,enabled:s.enabled})}if(o<0)throw new Error(`Parser rule not found: ${e}`);this.rules[o].fn=t,n?.alt!==void 0&&(this.rules[o].alt=n.alt),this.invalidateCache()}before(e,t,n,o){const s=this.rules.findIndex(r=>r.name===e);if(s<0)throw new Error(`Parser rule not found: ${e}`);const i=this.rules.findIndex(r=>r.name===t);i>=0&&this.rules.splice(i,1),this.rules.splice(s,0,{name:t,fn:n,alt:o?.alt||[],enabled:!0}),this.invalidateCache()}after(e,t,n,o){const s=this.rules.findIndex(r=>r.name===e);if(s<0)throw new Error(`Parser rule not found: ${e}`);const i=this.rules.findIndex(r=>r.name===t);i>=0&&this.rules.splice(i,1),this.rules.splice(s+1,0,{name:t,fn:n,alt:o?.alt||[],enabled:!0}),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;for(const i of n){const r=this.rules.findIndex(l=>l.name===i);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${i}`);continue}o.push(i),this.rules[r].enabled||(this.rules[r].enabled=!0,s=!0)}return s&&this.invalidateCache(),o}disable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;for(const i of n){const r=this.rules.findIndex(l=>l.name===i);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${i}`);continue}o.push(i),this.rules[r].enabled&&(this.rules[r].enabled=!1,s=!0)}return s&&this.invalidateCache(),o}enableOnly(e){const t=new Set(e);let n=!1;for(const o of this.rules){const s=t.has(o.name);o.enabled!==s&&(o.enabled=s,n=!0)}n&&this.invalidateCache()}getRules(e){const t=e||"";return this.cache||this.compileCache(),this.cache.get(t)??[]}getNamedRules(e){const t=e||"";return this.namedCache||this.compileCache(),this.namedCache.get(t)??[]}compileCache(){const e=new Set([""]);for(const o of this.rules)if(o.enabled&&o.alt)for(const s of o.alt)e.add(s);const t=new Map,n=new Map;for(const o of e){const s=[],i=[];for(const r of this.rules)r.enabled&&(o!==""&&!r.alt?.includes(o)||(s.push(r.fn),i.push({name:r.name,fn:r.fn})));t.set(o,s),n.set(o,i)}this.cache=t,this.namedCache=n}},gI=class{src;md;env;tokens;tokens_meta;pos;posMax;level;pending;pendingLevel;cache;delimiters;_prev_delimiters;backticks;backticksScanned;linkLevel;linkLabelNoCloseFrom;maxNesting;constructor(e,t,n,o){this.src=e,this.md=t,this.env=n,this.tokens=o,this.tokens_meta=new Array(o.length),this.pos=0,this.posMax=e.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache=[],this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0,this.linkLabelNoCloseFrom=-1,this.maxNesting=t.options.maxNesting}pushPending(){const e=new ws("text","",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending="",e}pushSimple(e,t){this.pending&&this.pushPending();const n=new ws(e,t,0);return n.level=this.level,this.pendingLevel=this.level,this.tokens.push(n),this.tokens_meta.push(null),n}push(e,t,n){if(this.pending&&this.pushPending(),n===0)return this.pushSimple(e,t);const o=new ws(e,t,n);let s=null;return n<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),o.level=this.level,n>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],s={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(o),this.tokens_meta.push(s),o}scanDelims(e,t){const{src:n,posMax:o}=this,s=n.charCodeAt(e);let i=e;for(;i<o&&n.charCodeAt(i)===s;)i++;const r=i-e,l=e>0?n.charCodeAt(e-1):32,a=i<o?n.charCodeAt(i):32,u=Cp(l),c=Cp(a),d=$3(l),f=$3(a),h=!c&&(!f||u||d),m=!u&&(!d||c||f);return{can_open:h&&(t||!m||d),can_close:m&&(t||!h||f),length:r}}};gI.prototype.Token=ws;const $ne=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/;function _C(e,t){switch(e.src.charCodeAt(e.pos)){case 10:return pI(e,t);case 33:return uI(e,t);case 38:return tI(e,t);case 42:case 95:return O3.tokenize(e,t);case 58:return e.md.options.linkify&&fI(e,t);case 60:return GE(e,t)||aI(e,t);case 91:return cI(e,t);case 92:return sI(e,t);case 96:return YE(e,t);case 126:return D3.tokenize(e,t);default:return hI(e,t)}}function vI(e){return!$ne.test(e)}var Nne=class{ruler;ruler2;cachedRulesVersion=-1;cachedRules=[];cachedRules2Version=-1;cachedRules2=[];defaultRulerVersion;defaultRuler2Version;constructor(){this.ruler=new wC,this.ruler2=new wC,this.ruler.push("text",hI),this.ruler.push("linkify",fI),this.ruler.push("newline",pI),this.ruler.push("escape",sI),this.ruler.push("backticks",YE),this.ruler.push("strikethrough",D3.tokenize),this.ruler.push("emphasis",O3.tokenize),this.ruler.push("link",cI),this.ruler.push("image",uI),this.ruler.push("autolink",GE),this.ruler.push("html_inline",aI),this.ruler.push("entity",tI),this.ruler2.push("balance_pairs",nne),this.ruler2.push("strikethrough",D3.postProcess),this.ruler2.push("emphasis",O3.postProcess),this.ruler2.push("fragments_join",fne),this.defaultRulerVersion=this.ruler.version,this.defaultRuler2Version=this.ruler2.version}skipToken(e){const t=e.pos,n=this.getRules(),o=n.length,s=e.cache,i=s[t],r=!!e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules"));if(i!==void 0){e.pos=i;return}let l=!1;if(e.level<e.maxNesting){if(r){const a=this.ruler.getNamedRules("");for(let u=0;u<o;u++){e.level++;const c=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();l=a[u].fn(e,!0);const d=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if(zd(e.env,"inline",a[u].name,d-c,!!l,!0),e.level--,l){if(t>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}}else if(this.isDefaultRuleset()){if(e.level++,l=_C(e,!0),e.level--,l&&t>=e.pos)throw new Error("inline rule didn't increment state.pos")}else for(let a=0;a<o;a++)if(e.level++,l=n[a](e,!0),e.level--,l){if(t>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}else e.pos=e.posMax;l||e.pos++,s[t]=e.pos}tokenize(e){const t=this.getRules(),n=t.length,o=e.posMax;if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){const i=this.isDefaultRuleset();for(;e.pos<o;){const r=e.pos;let l=!1;if(e.level<e.maxNesting){if(i)l=_C(e,!1);else for(let a=0;a<n&&(l=t[a](e,!1),!l);a++);if(l&&r>=e.pos)throw new Error("inline rule didn't increment state.pos")}if(l){if(e.pos>=o)break;continue}e.pending+=e.src.charAt(e.pos++)}e.pending&&e.pushPending();return}const s=this.ruler.getNamedRules("");for(;e.pos<o;){const i=e.pos;let r=!1;if(e.level<e.maxNesting)for(let l=0;l<n;l++){const a=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();r=s[l].fn(e,!1);const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if(zd(e.env,"inline",s[l].name,u-a,!!r,!1),r){if(i>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}if(r){if(e.pos>=o)break;continue}e.pending+=e.src.charAt(e.pos++)}e.pending&&e.pushPending()}isDefaultRuleset(){return this.ruler.version===this.defaultRulerVersion&&this.ruler2.version===this.defaultRuler2Version}parseSource(e,t,n,o){if(typeof e=="string"&&e.length>0&&this.isDefaultRuleset()&&vI(e)){const a=new ws("text","",0);a.content=e,o.push(a);return}const s=new gI(e,t,n,o);this.tokenize(s);const i=this.getRules2(),r=i.length;if(!(s.env&&(Object.prototype.hasOwnProperty.call(s.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(s.env,"__mdtsProfileRules")))){for(let a=0;a<r;a++)i[a](s,!1);return}const l=this.ruler2.getNamedRules("");for(let a=0;a<r;a++){const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();l[a].fn(s,!1);const c=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();zd(s.env,"inline2",l[a].name,c-u,!0,!1)}}parse(e,t,n,o){this.parseSource(e,t,n,o)}getRules(){return this.cachedRulesVersion!==this.ruler.version&&(this.cachedRules=this.ruler.getRules(""),this.cachedRulesVersion=this.ruler.version),this.cachedRules}getRules2(){return this.cachedRules2Version!==this.ruler2.version&&(this.cachedRules2=this.ruler2.getRules(""),this.cachedRules2Version=this.ruler2.version),this.cachedRules2}};function Fne(e){const t=e.tokens,n=!!e.md?.inline?.isDefaultRuleset?.();for(let o=0,s=t.length;o<s;o++){const i=t[o];if(i.type==="inline"&&e.md){if(i.children||(i.children=[]),n&&i.content.length>0&&vI(i.content)){const r=new ws("text","",0);r.content=i.content,i.children.push(r);continue}e.md.inline.parse(i.content,e.md,e.env,i.children)}}}const Rne=/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u,One=/[0-9a-z]/i;function Pne(e){return/^<a[>\s]/i.test(e)}function Dne(e){return/^<\/a\s*>/i.test(e)}function Bne(e,t){if(t.schema||t.index!==0||!t.raw)return t;for(let n=1;n<t.raw.length;n++){const o=t.raw[n-1],s=t.raw[n];if(!Rne.test(o)||!One.test(s))continue;const i=t.raw.slice(n),r=e.match(i)?.[0];if(!(!r||r.index!==0||r.lastIndex!==i.length))return{...r,index:t.index+n,lastIndex:t.index+n+r.lastIndex}}return t}function Hne(e){const t=e.tokens;if(e.md?.options?.linkify)for(let n=0;n<t.length;n++){const o=t[n];if(o.type!=="inline"||!e.md.linkify.pretest(o.content))continue;let s=o.children;s||(s=[],o.children=s);let i=0;for(let r=s.length-1;r>=0;r--){const l=s[r];if(l.type==="link_close"){for(r--;r>=0&&s[r].level!==l.level&&s[r].type!=="link_open";)r--;continue}if(l.type==="html_inline"&&(Pne(l.content)&&i>0&&i--,Dne(l.content)&&i++),i>0||l.type!=="text"||!e.md.linkify.test(l.content))continue;const a=l.content;let u=(e.md.linkify.match(a)||[]).map(h=>Bne(e.md.linkify,h));if(u.length===0)continue;const c=[];let d=l.level,f=0;u.length>0&&u[0].index===0&&r>0&&s[r-1].type==="text_special"&&(u=u.slice(1));for(let h=0;h<u.length;h++){const m=u[h],v=e.md.normalizeLink(m.url);if(!e.md.validateLink(v))continue;let k=m.text;m.schema?m.schema==="mailto:"&&!/^mailto:/i.test(k)?k=e.md.normalizeLinkText(`mailto:${k}`).replace(/^mailto:/,""):k=e.md.normalizeLinkText(k):k=e.md.normalizeLinkText(`http://${k}`).replace(/^http:\/\//,"");const w=m.index;if(w>f){const x=new ws("text","",0);x.content=a.slice(f,w),x.level=d,c.push(x)}const b=new ws("link_open","a",1);b.attrs=[["href",v]],b.level=d++,b.markup="linkify",b.info="auto",c.push(b);const _=new ws("text","",0);_.content=k,_.level=d,c.push(_);const g=new ws("link_close","a",-1);g.level=--d,g.markup="linkify",g.info="auto",c.push(g),f=m.lastIndex}if(f!==0){if(f<a.length){const h=new ws("text","",0);h.content=a.slice(f),h.level=d,c.push(h)}s.splice(r,1,...c)}}}}const zne=/\r\n?|\n/g,Wne=/\0/g;function Une(e){if(!e||typeof e.src!="string")return;const t=e.src,n=t.includes("\r"),o=t.includes("\0");if(!n&&!o)return;let s=t;n&&(s=s.replace(zne,` +`)),o&&(s=s.replace(Wne,"�")),e.src=s}const yI=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,jne=/\((?:c|tm|r)\)/i,Vne=/\((c|tm|r)\)/gi,qne={c:"©",r:"®",tm:"™"};function Kne(e,t){return qne[t.toLowerCase()]}function Zne(e){let t=0;for(let n=e.length-1;n>=0;n--){const o=e[n];o.type==="text"&&!t&&(o.content=o.content.replace(Vne,Kne)),o.type==="link_open"&&o.info==="auto"&&t--,o.type==="link_close"&&o.info==="auto"&&t++}}function Gne(e){let t=0;for(let n=e.length-1;n>=0;n--){const o=e[n];o.type==="text"&&!t&&yI.test(o.content)&&(o.content=o.content.replace(/\+-/g,"±").replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---(?=[^-]|$)/gm,"$1—").replace(/(^|\s)--(?=\s|$)/gm,"$1–").replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,"$1–")),o.type==="link_open"&&o.info==="auto"&&t--,o.type==="link_close"&&o.info==="auto"&&t++}}function Yne(e){if(e.md?.options?.typographer)for(let t=e.tokens.length-1;t>=0;t--){const n=e.tokens[t];if(n.type!=="inline")continue;const o=n.content||(Array.isArray(n.children)?n.children.map(s=>s.type==="text"?s.content:"").join(""):"");jne.test(o)&&Zne(n.children||[]),yI.test(o)&&Gne(n.children||[])}}var Xne=class{rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t){const n=this.rules.findIndex(o=>o.name===e);n>=0&&this.rules.splice(n,1),this.rules.push({name:e,fn:t,enabled:!0}),this.invalidateCache()}at(e,t){const n=this.rules.findIndex(o=>o.name===e);if(n<0)throw new Error(`Parser rule not found: ${e}`);this.rules[n].fn=t,this.invalidateCache()}before(e,t,n){const o=this.rules.findIndex(i=>i.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this.rules.findIndex(i=>i.name===t);s>=0&&this.rules.splice(s,1),this.rules.splice(o,0,{name:t,fn:n,enabled:!0}),this.invalidateCache()}after(e,t,n){const o=this.rules.findIndex(i=>i.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this.rules.findIndex(i=>i.name===t);s>=0&&this.rules.splice(s,1),this.rules.splice(o+1,0,{name:t,fn:n,enabled:!0}),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;for(const i of n){const r=this.rules.findIndex(l=>l.name===i);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${i}`);continue}o.push(i),this.rules[r].enabled||(this.rules[r].enabled=!0,s=!0)}return s&&this.invalidateCache(),o}disable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;for(const i of n){const r=this.rules.findIndex(l=>l.name===i);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${i}`);continue}o.push(i),this.rules[r].enabled&&(this.rules[r].enabled=!1,s=!0)}return s&&this.invalidateCache(),o}enableOnly(e){const t=new Set(e);let n=!1;for(const o of this.rules){const s=t.has(o.name);o.enabled!==s&&(o.enabled=s,n=!0)}n&&this.invalidateCache()}compileCache(){this.cache=this.rules.filter(e=>e.enabled).map(e=>e.fn),this.namedCache=this.rules.filter(e=>e.enabled).map(e=>({name:e.name,fn:e.fn}))}getRules(e=""){return this.cache||this.compileCache(),this.cache}getNamedRules(e=""){return this.namedCache||this.compileCache(),this.namedCache}};const Jne=/['"]/,xC=/['"]/g,SC="’";function ah(e,t,n){return e.slice(0,t)+n+e.slice(t+1)}function Qne(e,t){let n;const o=[],s=t.md&&t.md.options&&t.md.options.quotes||"“”‘’";for(let i=0;i<e.length;i++){const r=e[i],l=e[i].level;for(n=o.length-1;n>=0&&!(o[n].level<=l);n--);if(o.length=n+1,r.type!=="text")continue;let a=r.content,u=0,c=a.length;e:for(;u<c;){xC.lastIndex=u;const d=xC.exec(a);if(!d)break;let f=!0,h=!0;u=d.index+1;const m=d[0]==="'";let v=32;if(d.index-1>=0)v=a.charCodeAt(d.index-1);else for(n=i-1;n>=0&&!(e[n].type==="softbreak"||e[n].type==="hardbreak");n--)if(e[n].content){v=e[n].content.charCodeAt(e[n].content.length-1);break}let k=32;if(u<c)k=a.charCodeAt(u);else for(n=i+1;n<e.length&&!(e[n].type==="softbreak"||e[n].type==="hardbreak");n++)if(e[n].content){k=e[n].content.charCodeAt(0);break}const w=Um(v)||Wm(String.fromCharCode(v)),b=Um(k)||Wm(String.fromCharCode(k)),_=Cp(v),g=Cp(k);if(g?f=!1:b&&(_||w||(f=!1)),_?h=!1:w&&(g||b||(h=!1)),k===34&&d[0]==='"'&&v>=48&&v<=57&&(h=f=!1),f&&h&&(f=w,h=b),!f&&!h){m&&(r.content=ah(r.content,d.index,SC));continue}if(h)for(n=o.length-1;n>=0;n--){let x=o[n];if(o[n].level<l)break;if(x.single===m&&o[n].level===l){x=o[n];let S,T;m?(S=s[2]||"‘",T=s[3]||"’"):(S=s[0]||"“",T=s[1]||"”"),r.content=ah(r.content,d.index,T),e[x.token].content=ah(e[x.token].content,x.pos,S),u+=T.length-1,x.token===i&&(u+=S.length-1),a=r.content,c=a.length,o.length=n;continue e}}f?o.push({token:i,pos:d.index,single:m,level:l}):h&&m&&(r.content=ah(r.content,d.index,SC))}}}function eoe(e){if(e.md.options.typographer)for(let t=e.tokens.length-1;t>=0;t--){const n=e.tokens[t];if(n.type!=="inline")continue;const o=typeof n.content=="string"?n.content:(n.children||[]).map(s=>s.content||"").join("");!Jne.test(o)||!n.children||Qne(n.children,e)}}function toe(e){const t=e.tokens||[],n=t.length;for(let o=0;o<n;o++){const s=t[o];if(s.type!=="inline"||!Array.isArray(s.children))continue;const i=s.children,r=i.length;for(let u=0;u<r;u++)i[u].type==="text_special"&&(i[u].type="text");let l=0,a=0;for(;a<r;a++)i[a].type==="text"&&a+1<r&&i[a+1].type==="text"?i[a+1].content=i[a].content+i[a+1].content:(a!==l&&(i[l]=i[a]),l++);a!==l&&(i.length=l)}}const noe=/^(?:vbscript|javascript|file|data):/,ooe=/^data:image\/(?:gif|png|jpeg|webp);/,kI=["http:","https:","mailto:"];function bI(e){const t=e.trim().toLowerCase();return noe.test(t)?ooe.test(t):!0}function CI(e){const t=Fy(e,!0);if(t.hostname&&(!t.protocol||kI.includes(t.protocol)))try{t.hostname=VE.default.toASCII(t.hostname)}catch{}return $E(Ny(t))}function wI(e){const t=Fy(e,!0);if(t.hostname&&(!t.protocol||kI.includes(t.protocol)))try{t.hostname=VE.default.toUnicode(t.hostname)}catch{}return L3(Ny(t),`${L3.defaultChars}%`)}function soe(e){switch(e){case 9:case 32:return!0}return!1}function ioe(e,t,n,o){const s=e.src,i=e.bMarks,r=e.eMarks,l=e.tShift,a=e.sCount,u=e.bsCount;let c=i[t]+l[t],d=r[t];const f=e.lineMax;if(a[t]-e.blkIndent>=4||s.charCodeAt(c)!==62)return!1;if(o)return!0;const h=[],m=[],v=[],k=[],w=e.md.block.ruler.getRulesForState(e,"blockquote"),b=e.parentType;e.parentType="blockquote";let _=!1,g;for(g=t;g<n;g++){const E=a[g]<e.blkIndent;if(c=i[g]+l[g],d=r[g],c>=d)break;if(s.charCodeAt(c++)===62&&!E){let D=a[g]+1,I,$;s.charCodeAt(c)===32?(c++,D++,$=!1,I=!0):s.charCodeAt(c)===9?(I=!0,(u[g]+D)%4===3?(c++,D++,$=!1):$=!0):I=!1;let B=D;for(h.push(i[g]),i[g]=c;c<d;){const H=s.charCodeAt(c);if(soe(H))H===9?B+=4-(B+u[g]+($?1:0))%4:B++;else break;c++}_=c>=d,m.push(u[g]),u[g]=a[g]+1+(I?1:0),v.push(a[g]),a[g]=B-D,k.push(l[g]),l[g]=c-i[g];continue}if(_)break;let P=!1;for(let D=0,I=w.length;D<I;D++)if(w[D](e,g,n,!0)){P=!0;break}if(P){e.lineMax=g,e.blkIndent!==0&&(h.push(i[g]),m.push(u[g]),k.push(l[g]),v.push(a[g]),a[g]-=e.blkIndent);break}h.push(i[g]),m.push(u[g]),k.push(l[g]),v.push(a[g]),a[g]=-1}const x=e.blkIndent;e.blkIndent=0;const S=e.push("blockquote_open","blockquote",1);S.markup=">";const T=[t,0];S.map=T,e.md.block.tokenize(e,t,g);const A=e.push("blockquote_close","blockquote",-1);A.markup=">",e.lineMax=f,e.parentType=b,T[1]=e.line;for(let E=0;E<k.length;E++)i[E+t]=h[E],l[E+t]=k[E],a[E+t]=v[E],u[E+t]=m[E];return e.blkIndent=x,!0}function roe(e,t,n){if(e.sCount[t]-e.blkIndent<4)return!1;let o=t+1,s=o;for(;o<n;){if(e.isEmpty(o)){o++;continue}if(e.sCount[o]-e.blkIndent>=4){o++,s=o;continue}break}e.line=s;const i=e.push("code_block","code",0);return i.content=`${e.getLines(t,s,4+e.blkIndent,!1)} +`,i.map=[t,e.line],!0}function loe(e,t,n,o){let s=e.bMarks[t]+e.tShift[t],i=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||s+3>i)return!1;const r=e.src.charCodeAt(s);if(r!==126&&r!==96)return!1;let l=s;s=e.skipChars(s,r);let a=s-l;if(a<3)return!1;const u=e.src.slice(l,s),c=e.src.slice(s,i);if(r===96&&c.includes(String.fromCharCode(r)))return!1;if(o)return!0;let d=t,f=!1;for(;d++,!(d>=n||(s=l=e.bMarks[d]+e.tShift[d],i=e.eMarks[d],s<i&&e.sCount[d]<e.blkIndent));)if(e.src.charCodeAt(s)===r&&!(e.sCount[d]-e.blkIndent>=4)&&(s=e.skipChars(s,r),!(s-l<a)&&(s=e.skipSpaces(s),!(s<i)))){f=!0;break}a=e.sCount[t],e.line=d+(f?1:0);const h=e.push("fence","code",0);return h.info=c,h.content=e.getLines(t+1,d,a,!0),h.markup=u,h.map=[t,e.line],!0}const AC=["","h1","h2","h3","h4","h5","h6"],MC=["","#","##","###","####","#####","######"];function TC(e){switch(e){case 9:case 32:return!0}return!1}function aoe(e,t,n,o){const s=e.src,i=e.bMarks,r=e.tShift,l=e.eMarks;let a=i[t]+r[t],u=l[t];if(e.sCount[t]-e.blkIndent>=4)return!1;let c=s.charCodeAt(a);if(c!==35||a>=u)return!1;let d=1;for(c=s.charCodeAt(++a);c===35&&a<u&&d<=6;)d++,c=s.charCodeAt(++a);if(d>6||a<u&&!TC(c))return!1;if(o)return!0;u=e.skipSpacesBack(u,a);const f=e.skipCharsBack(u,35,a);f>a&&TC(s.charCodeAt(f-1))&&(u=f),e.line=t+1;const h=e.push("heading_open",AC[d],1);h.markup=MC[d],h.map=[t,e.line];const m=e.push("inline","",0);m.content=s.slice(a,u).trim(),m.map=[t,e.line],m.children=[];const v=e.push("heading_close",AC[d],-1);return v.markup=MC[d],!0}function uoe(e){switch(e){case 9:case 32:return!0}return!1}function coe(e,t,n,o){const s=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4)return!1;let i=e.bMarks[t]+e.tShift[t];const r=e.src.charCodeAt(i++);if(r!==42&&r!==45&&r!==95)return!1;let l=1;for(;i<s;){const u=e.src.charCodeAt(i++);if(u!==r&&!uoe(u))return!1;u===r&&l++}if(l<3)return!1;if(o)return!0;e.line=t+1;const a=e.push("hr","hr",0);return a.map=[t,e.line],a.markup=new Array(l+1).join(String.fromCharCode(r)),!0}const sd=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^<!--/,/-->/,!0],[/^<\?/,/\?>/,!0],[/^<![A-Z]/,/>/,!0],[/^<!\[CDATA\[/,/\]\]>/,!0],[new RegExp(`^</?(${["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"].join("|")})(?=(\\s|/?>|$))`,"i"),/^$/,!0],[new RegExp(`${hne.source}\\s*$`),/^$/,!1]];function doe(e,t,n,o){let s=e.bMarks[t]+e.tShift[t],i=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||!e.md.options.html||e.src.charCodeAt(s)!==60)return!1;let r=e.src.slice(s,i),l=0;for(;l<sd.length&&!sd[l][0].test(r);l++);if(l===sd.length)return!1;if(o)return sd[l][2];let a=t+1;if(!sd[l][1].test(r)){for(;a<n&&!(e.sCount[a]<e.blkIndent);a++)if(s=e.bMarks[a]+e.tShift[a],i=e.eMarks[a],r=e.src.slice(s,i),sd[l][1].test(r)){r.length!==0&&a++;break}}e.line=a;const u=e.push("html_block","",0);return u.map=[t,a],u.content=e.getLines(t,a,e.blkIndent,!0),!0}function EC(e){switch(e){case 9:case 32:return!0}return!1}const Hf={Pipe:1,ParagraphTerminator:2};function foe(e){switch(e){case 35:case 42:case 43:case 45:case 60:case 62:case 95:case 96:case 124:case 126:return!0}return e>=48&&e<=57}var _I=class{src;md;env;tokens;bMarks=[];eMarks=[];tShift=[];sCount=[];bsCount=[];lineFlags=[];blkIndent=0;line=0;lineMax=0;tight=!1;ddIndent=-1;listIndent=-1;parentType="root";level=0;constructor(e,t,n,o){this.src=e,this.md=t,this.env=n,this.tokens=o;const s=this.src;let i=0,r=0,l=0,a=!1,u=0;for(let c=0,d=s.length;c<d;c++){const f=s.charCodeAt(c);if(f===124&&(u|=Hf.Pipe|Hf.ParagraphTerminator),!a)if(EC(f)){i++,f===9?r+=4-r%4:r++;continue}else a=!0,foe(f)&&(u|=Hf.ParagraphTerminator);(f===10||c===d-1)&&(f!==10&&c++,this.bMarks.push(l),this.eMarks.push(c),this.tShift.push(i),this.sCount.push(r),this.bsCount.push(0),this.lineFlags.push(u),a=!1,i=0,r=0,u=0,l=c+1)}this.bMarks.push(s.length),this.eMarks.push(s.length),this.tShift.push(0),this.sCount.push(0),this.bsCount.push(0),this.lineFlags.push(0),this.lineMax=this.bMarks.length-1}push(e,t,n){if(n===0){const s=new ws(e,t,0);return s.block=!0,s.level=this.level,this.tokens.push(s),s}const o=new ws(e,t,n);return o.block=!0,n<0&&this.level--,o.level=this.level,n>0&&this.level++,this.tokens.push(o),o}isEmpty(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]}skipEmptyLines(e){const t=this.bMarks,n=this.tShift,o=this.eMarks;for(let s=this.lineMax;e<s&&!(t[e]+n[e]<o[e]);e++);return e}skipSpaces(e){const t=this.src;for(let n=t.length;e<n;e++){const o=t.charCodeAt(e);if(o!==9&&o!==32)break}return e}skipSpacesBack(e,t){if(e<=t)return e;const n=this.src;for(;e>t;){const o=n.charCodeAt(--e);if(o!==9&&o!==32)return e+1}return e}skipChars(e,t){const n=this.src;for(let o=n.length;e<o&&n.charCodeAt(e)===t;e++);return e}skipCharsBack(e,t,n){if(e<=n)return e;const o=this.src;for(;e>n;)if(t!==o.charCodeAt(--e))return e+1;return e}getLines(e,t,n,o){if(e>=t)return"";if(e+1===t){const c=e,d=this.bMarks[c];let f=d;const h=o?this.eMarks[c]+1:this.eMarks[c];let m=0;const v=this.src,k=this.bsCount,w=this.tShift;for(;f<h&&m<n;){const b=v.charCodeAt(f);if(b===9||b===32)b===9?m+=4-(m+k[c])%4:m++;else if(f-d<w[c])m++;else break;f++}return m>n?new Array(m-n+1).join(" ")+v.slice(f,h):v.slice(f,h)}const s=new Array(t-e),i=this.src,r=this.bMarks,l=this.eMarks,a=this.bsCount,u=this.tShift;for(let c=0,d=e;d<t;d++,c++){let f=0;const h=r[d];let m=h,v;for(d+1<t||o?v=l[d]+1:v=l[d];m<v&&f<n;){const k=i.charCodeAt(m);if(EC(k))k===9?f+=4-(f+a[d])%4:f++;else if(m-h<u[d])f++;else break;m++}f>n?s[c]=new Array(f-n+1).join(" ")+i.slice(m,v):s[c]=i.slice(m,v)}return s.join("")}};_I.prototype.Token=ws;function poe(e,t,n){for(let o=t;o<n;o++)if(e.charCodeAt(o)===124)return!0;return!1}function xI(e){const t=e?.md?.block?.ruler;return t?t.version===t.__mdtsDefaultVersion:!1}function SI(e,t,n,o,s){if(e.lineFlags&&(e.lineFlags[t]&Hf.ParagraphTerminator)===0||o>=s)return!1;const i=n.charCodeAt(o);switch(i){case 35:case 42:case 43:case 45:case 60:case 62:case 95:case 96:case 126:return!0}return i>=48&&i<=57?!0:poe(n,o,s)}const IC=["","h1","h2"];function hoe(e,t,n){const o=e.md.block.ruler.getRulesForState(e,"paragraph"),s=e.src,i=e.bMarks,r=e.tShift,l=e.eMarks,a=e.sCount,u=e.blkIndent,c=xI(e);if(a[t]-u>=4)return!1;const d=e.parentType;e.parentType="paragraph";let f=0,h,m=t+1;for(;m<n;m++){const g=i[m]+r[m],x=l[m];if(g>=x)break;if(a[m]-u>3)continue;if(a[m]>=u&&(h=s.charCodeAt(g),h===45||h===61)){let T=g+1,A=T;for(;T<x&&s.charCodeAt(T)===h;)T++;for(A=T;T<x;){const E=s.charCodeAt(T);if(E!==9&&E!==32)break;T++}if(T>=x){f=h===61?1:2;break}if(A-g>1)continue}if(a[m]<0||c&&!SI(e,m,s,g,x))continue;let S=!1;for(let T=0,A=o.length;T<A;T++)if(o[T](e,m,n,!0)){S=!0;break}if(S)break}if(!f)return!1;let v;if(m===t+1){const g=i[t]+r[t];let x=l[t];for(;x>g;){const S=s.charCodeAt(x-1);if(S!==9&&S!==32)break;x--}v=s.slice(g,x)}else v=e.getLines(t,m,u,!1).trim();e.line=m+1;const k=h===61?"=":"-",w=e.push("heading_open",IC[f],1);w.markup=k,w.map=[t,e.line];const b=e.push("inline","",0);b.content=v,b.map=[t,e.line-1],b.children=[];const _=e.push("heading_close",IC[f],-1);return _.markup=k,e.parentType=d,!0}function AI(e){switch(e){case 9:case 32:return!0}return!1}function LC(e,t){const n=e.eMarks,o=e.bMarks,s=e.tShift,i=e.src,r=n[t];let l=o[t]+s[t];const a=i.charCodeAt(l++);return a!==42&&a!==45&&a!==43||l<r&&!AI(i.charCodeAt(l))?-1:l}function $C(e,t){const n=e.bMarks,o=e.tShift,s=e.eMarks,i=e.src,r=n[t]+o[t],l=s[t];let a=r;if(a+1>=l)return-1;let u=i.charCodeAt(a++);if(u<48||u>57)return-1;for(;;){if(a>=l)return-1;if(u=i.charCodeAt(a++),u>=48&&u<=57){if(a-r>=10)return-1;continue}if(u===41||u===46)break;return-1}return a<l&&(u=i.charCodeAt(a),!AI(u))?-1:a}function moe(e,t,n){const o=e.bMarks,s=e.tShift,i=e.src,r=o[t]+s[t];let l=0;for(let a=r;a<n-1;a++)l=l*10+i.charCodeAt(a)-48;return l}const goe=["0","1","2","3","4","5","6","7","8","9"];function voe(e,t){const n=e.level+2,o=e.tokens;for(let s=t+2,i=o.length-2;s<i;s++){const r=o[s];if(r.level===n){if(r.type==="paragraph_open"){r.hidden=!0,o[s+2].hidden=!0,s+=2;continue}if(r.nesting===1){let l=1;for(;l>0&&++s<i;)l+=o[s].nesting}}}}function yoe(e,t,n,o){let s,i,r=0,l=t,a=!0;if(e.sCount[l]-e.blkIndent>=4||e.listIndent>=0&&e.sCount[l]-e.listIndent>=4&&e.sCount[l]<e.blkIndent)return!1;let u=!1;o&&e.parentType==="paragraph"&&e.sCount[l]>=e.blkIndent&&(u=!0);let c,d,f;const h=e.src,m=e.bMarks,v=e.tShift,k=e.eMarks,w=e.sCount,b=e.bsCount,_=m[l]+v[l];if(_>=k[l])return!1;const g=h.charCodeAt(_);if(g>=48&&g<=57){if(f=$C(e,l),f<0||(c=!0,r=_,d=moe(e,l,f),u&&d!==1))return!1}else if(g===42||g===45||g===43){if(f=LC(e,l),f<0)return!1;c=!1}else return!1;if(u&&e.skipSpaces(f)>=k[l])return!1;if(o)return!0;const x=h.charCodeAt(f-1),S=String.fromCharCode(x);if(c){const I=e.push("ordered_list_open","ol",1);d!==void 0&&d!==1&&(I.attrs=[["start",String(d)]])}else e.push("bullet_list_open","ul",1);const T=[l,0];e.tokens[e.tokens.length-1].map=T,e.tokens[e.tokens.length-1].markup=S;let A=!1;const E=e.tokens.length-1,P=e.md.block.ruler.getRulesForState(e,"list"),D=e.parentType;for(e.parentType="list";l<n;){i=f,s=k[l];const I=w[l]+f-(m[l]+v[l]);let $=I;for(;i<s;){const ne=h.charCodeAt(i);if(ne===9)$+=4-($+b[l])%4;else if(ne===32)$++;else break;i++}const B=i;let H;B>=s?H=1:H=$-I,H>4&&(H=1);const O=I+H,F=e.push("list_item_open","li",1);F.markup=S;const U=[l,0];F.map=U,c&&(F.info=f-r-1===1?goe[h.charCodeAt(r)-48]:h.slice(r,f-1));const z=e.tight,W=e.tShift[l],K=e.sCount[l],V=e.listIndent;if(e.listIndent=e.blkIndent,e.blkIndent=O,e.tight=!0,e.tShift[l]=B-m[l],e.sCount[l]=$,B>=s&&e.isEmpty(l+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,l,n,!0),(!e.tight||A)&&(a=!1),A=e.line-l>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=V,e.tShift[l]=W,e.sCount[l]=K,e.tight=z,e.push("list_item_close","li",-1).markup=S,l=e.line,U[1]=l,l>=n||e.sCount[l]<e.blkIndent||e.sCount[l]-e.blkIndent>=4)break;let ie=!1;for(let ne=0,X=P.length;ne<X;ne++)if(P[ne](e,l,n,!0)){ie=!0;break}if(ie)break;if(c){if(f=$C(e,l),f<0)break;r=m[l]+v[l]}else if(f=LC(e,l),f<0)break;if(x!==h.charCodeAt(f-1))break}return c?e.push("ordered_list_close","ol",-1).markup=S:e.push("bullet_list_close","ul",-1).markup=S,T[1]=l,e.line=l,e.parentType=D,a&&voe(e,E),!0}function NC(e){return e===9||e===32}function koe(e,t,n){const o=e.md.block.ruler.getRulesForState(e,"paragraph"),s=e.parentType,i=e.src,r=e.bMarks,l=e.tShift,a=e.eMarks,u=e.sCount,c=e.blkIndent,d=xI(e);let f=t+1;for(e.parentType="paragraph";f<n&&!e.isEmpty(f);f++){if(u[f]-c>3||u[f]<0)continue;if(s==="list"&&u[f]>=c){const _=r[f]+l[f],g=a[f];if(_<g){const x=i.charCodeAt(_);if(x===42||x===45||x===43){if(_+1>=g||NC(i.charCodeAt(_+1)))break}else if(x>=48&&x<=57&&_+1<g){let S=_+1;for(;;){if(S>=g){S=-1;break}const T=i.charCodeAt(S++);if(T>=48&&T<=57){if(S-_>=10){S=-1;break}continue}if((T===41||T===46)&&(S>=g||NC(i.charCodeAt(S))))break;S=-1;break}if(S>=0)break}}}const k=r[f]+l[f],w=a[f];if(d&&!SI(e,f,i,k,w))continue;let b=!1;for(let _=0,g=o.length;_<g;_++)if(o[_](e,f,n,!0)){b=!0;break}if(b)break}const h=e.getLines(t,f,c,!1).trim();e.line=f;const m=e.push("paragraph_open","p",1);m.map=[t,e.line];const v=e.push("inline","",0);return v.content=h,v.map=[t,e.line],v.children=[],e.push("paragraph_close","p",-1),e.parentType=s,!0}function uh(e){switch(e){case 9:case 32:return!0}return!1}function boe(e,t,n,o){let s=e.bMarks[t]+e.tShift[t],i=e.eMarks[t],r=t+1;const l=e.md.block.ruler.getRulesForState(e,"reference");if(e.sCount[t]-e.blkIndent>=4||e.src.charCodeAt(s)!==91)return!1;function a(_){const g=e.lineMax;if(_>=g||e.isEmpty(_))return null;let x=!1;if(e.sCount[_]-e.blkIndent>3&&(x=!0),e.sCount[_]<0&&(x=!0),!x){const A=e.parentType;e.parentType="reference";let E=!1;for(let P=0,D=l.length;P<D;P++)if(l[P](e,_,g,!0)){E=!0;break}if(e.parentType=A,E)return null}const S=e.bMarks[_]+e.tShift[_],T=e.eMarks[_];return e.src.slice(S,T+1)}let u=e.src.slice(s,i+1);i=u.length;let c=-1;for(s=1;s<i;s++){const _=u.charCodeAt(s);if(_===91)return!1;if(_===93){c=s;break}else if(_===10){const g=a(r);g!==null&&(u+=g,i=u.length,r++)}else if(_===92&&(s++,s<i&&u.charCodeAt(s)===10)){const g=a(r);g!==null&&(u+=g,i=u.length,r++)}}if(c<0||u.charCodeAt(c+1)!==58)return!1;for(s=c+2;s<i;s++){const _=u.charCodeAt(s);if(_===10){const g=a(r);g!==null&&(u+=g,i=u.length,r++)}else if(!uh(_))break}const d=e.md.helpers.parseLinkDestination(u,s,i);if(!d.ok)return!1;const f=e.md.normalizeLink(d.str);if(!e.md.validateLink(f))return!1;s=d.pos;const h=s,m=r,v=s;for(;s<i;s++){const _=u.charCodeAt(s);if(_===10){const g=a(r);g!==null&&(u+=g,i=u.length,r++)}else if(!uh(_))break}let k=e.md.helpers.parseLinkTitle(u,s,i);for(;k.can_continue;){const _=a(r);if(_===null)break;u+=_,s=i,i=u.length,r++,k=e.md.helpers.parseLinkTitle(u,s,i,k)}let w;for(s<i&&v!==s&&k.ok?(w=k.str,s=k.pos):(w="",s=h,r=m);s<i&&uh(u.charCodeAt(s));)s++;if(s<i&&u.charCodeAt(s)!==10&&w)for(w="",s=h,r=m;s<i&&uh(u.charCodeAt(s));)s++;if(s<i&&u.charCodeAt(s)!==10)return!1;const b=v2(u.slice(1,c));return b?(o||(typeof e.env.references>"u"&&(e.env.references={}),typeof e.env.references[b]>"u"&&(e.env.references[b]={title:w,href:f}),e.line=r),!0):!1}function k9(e){switch(e){case 9:case 32:return!0}return!1}const Coe=65536;function b9(e,t){const n=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];return e.src.slice(n,o)}function woe(e,t){if(e.lineFlags)return(e.lineFlags[t]&Hf.Pipe)!==0;for(let n=e.bMarks[t]+e.tShift[t],o=e.eMarks[t];n<o;n++)if(e.src.charCodeAt(n)===124)return!0;return!1}function FC(e){const t=[],n=e.length;let o=0,s=e.charCodeAt(o),i=!1,r=0,l="";for(;o<n;)s===124&&(i?(l+=e.substring(r,o-1),r=o):(t.push(l+e.substring(r,o)),l="",r=o+1)),i=s===92,o++,s=e.charCodeAt(o);return t.push(l+e.substring(r)),t}function _oe(e,t,n,o){if(t+2>n)return!1;let s=t+1;if(e.sCount[s]<e.blkIndent||e.sCount[s]-e.blkIndent>=4)return!1;let i=e.bMarks[s]+e.tShift[s];if(i>=e.eMarks[s])return!1;const r=e.src.charCodeAt(i++);if(r!==124&&r!==45&&r!==58||i>=e.eMarks[s])return!1;const l=e.src.charCodeAt(i++);if(l!==124&&l!==45&&l!==58&&!k9(l)||r===45&&k9(l)||!woe(e,t))return!1;for(;i<e.eMarks[s];){const g=e.src.charCodeAt(i);if(g!==124&&g!==45&&g!==58&&!k9(g))return!1;i++}let a=b9(e,t+1),u=a.split("|");const c=[];for(let g=0;g<u.length;g++){const x=u[g].trim();if(!x){if(g===0||g===u.length-1)continue;return!1}if(!/^:?-+:?$/.test(x))return!1;x.charCodeAt(x.length-1)===58?c.push(x.charCodeAt(0)===58?"center":"right"):x.charCodeAt(0)===58?c.push("left"):c.push("")}if(a=b9(e,t).trim(),e.sCount[t]-e.blkIndent>=4)return!1;u=FC(a),u.length&&u[0]===""&&u.shift(),u.length&&u[u.length-1]===""&&u.pop();const d=u.length;if(d===0||d!==c.length)return!1;if(o)return!0;const f=e.parentType;e.parentType="table";const h=e.md.block.ruler.getRulesForState(e,"blockquote"),m=e.push("table_open","table",1),v=[t,0];m.map=v;const k=e.push("thead_open","thead",1);k.map=[t,t+1];const w=e.push("tr_open","tr",1);w.map=[t,t+1];for(let g=0;g<u.length;g++){const x=e.push("th_open","th",1);c[g]&&(x.attrs=[["style",`text-align:${c[g]}`]]);const S=e.push("inline","",0);S.content=u[g].trim(),S.children=[],e.push("th_close","th",-1)}e.push("tr_close","tr",-1),e.push("thead_close","thead",-1);let b,_=0;for(s=t+2;s<n&&!(e.sCount[s]<e.blkIndent);s++){let g=!1;for(let S=0,T=h.length;S<T;S++)if(h[S](e,s,n,!0)){g=!0;break}if(g||(a=b9(e,s).trim(),!a)||e.sCount[s]-e.blkIndent>=4||(u=FC(a),u.length&&u[0]===""&&u.shift(),u.length&&u[u.length-1]===""&&u.pop(),_+=d-u.length,_>Coe))break;if(s===t+2){const S=e.push("tbody_open","tbody",1);S.map=b=[t+2,0]}const x=e.push("tr_open","tr",1);x.map=[s,s+1];for(let S=0;S<d;S++){const T=e.push("td_open","td",1);c[S]&&(T.attrs=[["style",`text-align:${c[S]}`]]);const A=e.push("inline","",0);A.content=u[S]?u[S].trim():"",A.children=[],e.push("td_close","td",-1)}e.push("tr_close","tr",-1)}return b&&(e.push("tbody_close","tbody",-1),b[1]=s),e.push("table_close","table",-1),v[1]=s,e.parentType=f,e.line=s,!0}var xoe=class{_rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t,n){this._rules.push({name:e,enabled:!0,fn:t,alt:n?.alt||[]}),this.invalidateCache()}before(e,t,n,o){const s=this._rules.findIndex(r=>r.name===e);if(s<0)throw new Error(`Parser rule not found: ${e}`);const i=this._rules.findIndex(r=>r.name===t);i>=0&&this._rules.splice(i,1),this._rules.splice(s,0,{name:t,enabled:!0,fn:n,alt:o?.alt||[]}),this.invalidateCache()}after(e,t,n,o){const s=this._rules.findIndex(r=>r.name===e);if(s<0)throw new Error(`Parser rule not found: ${e}`);const i=this._rules.findIndex(r=>r.name===t);i>=0&&this._rules.splice(i,1),this._rules.splice(s+1,0,{name:t,enabled:!0,fn:n,alt:o?.alt||[]}),this.invalidateCache()}getRules(e){const t=e||"";return this.cache||this.compileCache(),this.cache[t]??[]}getNamedRules(e){const t=e||"";return this.namedCache||this.compileCache(),this.namedCache[t]??[]}getRulesForState(e,t){const n=e?.env;return n&&(Object.prototype.hasOwnProperty.call(n,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(n,"__mdtsProfileRules"))?this.getNamedRules(t).map(({name:o,fn:s})=>(i,r,l,a)=>{const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),c=s(i,r,l,a),d=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();return zd(i?.env,"block",o,d-u,c,!!a),c}):this.getRules(t)}at(e,t,n){const o=this._rules.findIndex(s=>s.name===e);if(o===-1)throw new Error(`Parser rule not found: ${e}`);this._rules[o].fn=t,n?.alt&&(this._rules[o].alt=n.alt),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;return n.forEach(i=>{const r=this._rules.findIndex(l=>l.name===i);if(r===-1){if(t)return;throw new Error(`Rules manager: invalid rule name ${i}`)}o.push(i),this._rules[r].enabled||(this._rules[r].enabled=!0,s=!0)}),s&&this.invalidateCache(),o}disable(e,t){const n=Array.isArray(e)?e:[e],o=[];let s=!1;return n.forEach(i=>{const r=this._rules.findIndex(l=>l.name===i);if(r===-1){if(t)return;throw new Error(`Rules manager: invalid rule name ${i}`)}o.push(i),this._rules[r].enabled&&(this._rules[r].enabled=!1,s=!0)}),s&&this.invalidateCache(),o}enableOnly(e){const t=new Set(e);let n=!1;for(const o of this._rules){const s=t.has(o.name);o.enabled!==s&&(o.enabled=s,n=!0)}n&&this.invalidateCache()}compileCache(){const e=new Set([""]);for(const o of this._rules)if(o.enabled)for(const s of o.alt)e.add(s);const t=Object.create(null),n=Object.create(null);for(const o of e){const s=[],i=[];for(const r of this._rules)r.enabled&&(o!==""&&!r.alt.includes(o)||(s.push(r.fn),i.push({name:r.name,fn:r.fn})));t[o]=s,n[o]=i}this.cache=t,this.namedCache=n}};const ch=[["table",_oe,["paragraph","reference"]],["code",roe],["fence",loe,["paragraph","reference","blockquote","list"]],["blockquote",ioe,["paragraph","reference","blockquote","list"]],["hr",coe,["paragraph","reference","blockquote","list"]],["list",yoe,["paragraph","reference","blockquote"]],["reference",boe],["html_block",doe,["paragraph","reference","blockquote"]],["heading",aoe,["paragraph","reference","blockquote"]],["lheading",hoe],["paragraph",koe]];var Soe=class{ruler;cachedRulesVersion=-1;cachedRules=[];constructor(){this.ruler=new xoe;for(let e=0;e<ch.length;e++)this.ruler.push(ch[e][0],ch[e][1],{alt:(ch[e][2]||[]).slice()});this.ruler.__mdtsDefaultVersion=this.ruler.version}tokenize(e,t,n){const o=this.getRules(),s=o.length,i=e.md.options.maxNesting,r=e.bMarks,l=e.tShift,a=e.eMarks,u=e.sCount;let c=t,d=!1;if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){for(;c<n;){for(;c<n&&r[c]+l[c]>=a[c];)c++;if(e.line=c,c>=n||u[c]<e.blkIndent)break;if(e.level>=i){e.line=n;break}const h=e.line;let m=!1;for(let v=0;v<s;v++)if(m=o[v](e,c,n,!1),m){if(h>=e.line)throw new Error("block rule didn't increment state.line");break}if(!m)throw new Error("none of the block rules matched");e.tight=!d,r[e.line-1]+l[e.line-1]>=a[e.line-1]&&(d=!0),c=e.line,c<n&&r[c]+l[c]>=a[c]&&(d=!0,c++,e.line=c)}return}const f=this.ruler.getNamedRules("");for(;c<n;){for(;c<n&&r[c]+l[c]>=a[c];)c++;if(e.line=c,c>=n||u[c]<e.blkIndent)break;if(e.level>=i){e.line=n;break}const h=e.line;let m=!1;for(let v=0;v<s;v++){const k=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();m=f[v].fn(e,c,n,!1);const w=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if(zd(e.env,"block",f[v].name,w-k,m,!1),m){if(h>=e.line)throw new Error("block rule didn't increment state.line");break}}if(!m)throw new Error("none of the block rules matched");e.tight=!d,r[e.line-1]+l[e.line-1]>=a[e.line-1]&&(d=!0),c=e.line,c<n&&r[c]+l[c]>=a[c]&&(d=!0,c++,e.line=c)}}parse(e,t,n,o){if(!e||e.length===0)return;const s=new _I(e,t,n,o);this.tokenize(s,s.line,s.lineMax)}getRules(){return this.cachedRulesVersion!==this.ruler.version&&(this.cachedRules=this.ruler.getRules(""),this.cachedRulesVersion=this.ruler.version),this.cachedRules}},MI=class{src;env;tokens;inlineMode;md;constructor(e,t,n={}){this.src=typeof e=="string"?e||"":e,this.env=n,this.tokens=[],this.inlineMode=!1,this.md=t}};MI.prototype.Token=ws;const RC=[["normalize",Une],["block",Yte],["inline",Fne],["linkify",Hne],["replacements",Yne],["smartquotes",eoe],["text_join",toe]],Aoe={html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",maxNesting:100},Moe={parseLinkLabel:Wy,parseLinkDestination:zy,parseLinkTitle:Uy};function Toe(){return{...Aoe}}function Eoe(){return{...Moe}}var Ioe=class{fallbackParser;lastState=null;block;inline;ruler;linkifyInstance=null;cachedCoreRulesVersion=-1;cachedCoreRules=[];cachedCoreNamedRulesVersion=-1;cachedCoreNamedRules=[];constructor(){this.block=new Soe,this.inline=new Nne,this.ruler=new Xne;for(let e=0;e<RC.length;e++){const[t,n]=RC[e];this.ruler.push(t,n)}this.fallbackParser={block:this.block,inline:this.inline,core:this,options:Toe(),helpers:Eoe(),normalizeLink:CI,normalizeLinkText:wI,validateLink:bI,linkify:null}}resolveParser(e){return e||(this.linkifyInstance||(this.linkifyInstance=new jE),this.fallbackParser.block!==this.block&&(this.fallbackParser.block=this.block),this.fallbackParser.inline!==this.inline&&(this.fallbackParser.inline=this.inline),this.fallbackParser.core=this,this.fallbackParser.linkify=this.linkifyInstance,this.fallbackParser)}createState(e,t={},n){return new MI(e,this.resolveParser(n),t)}getCoreRules(){return this.cachedCoreRulesVersion!==this.ruler.version&&(this.cachedCoreRules=this.ruler.getRules(""),this.cachedCoreRulesVersion=this.ruler.version),this.cachedCoreRules}getCoreNamedRules(){return this.cachedCoreNamedRulesVersion!==this.ruler.version&&(this.cachedCoreNamedRules=this.ruler.getNamedRules(""),this.cachedCoreNamedRulesVersion=this.ruler.version),this.cachedCoreNamedRules}process(e){if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){const n=this.getCoreRules();for(let o=0;o<n.length;o++)n[o](e);return}const t=this.getCoreNamedRules();for(let n=0;n<t.length;n++){const o=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();t[n].fn(e);const s=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();zd(e.env,"core",t[n].name,s-o,!0,!1)}Lne(e.env)}parseSource(e,t={},n){if(typeof e!="string"&&Gte(e))return this.parse(ZE(e),t,n);const o=this.createState(e,t,n);return this.process(o),this.lastState=o,o}parse(e,t={},n){if(typeof e!="string")throw new TypeError("Input data should be a String");return this.parseSource(e,t,n)}getTokens(){return this.lastState?this.lastState.tokens:[]}};const Loe=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/;function Km(e){return!Loe.test(e)}function bf(e,t){const n=e.indexOf(` +`,t);return n===-1?e.length:n}function jh(e,t,n){for(let o=t;o<n;o++){const s=e.charCodeAt(o);if(s!==32&&s!==9)return!1}return!0}function OC(e,t,n){return t+2<n&&e.charCodeAt(t)===96&&e.charCodeAt(t+1)===96&&e.charCodeAt(t+2)===96}function C9(e,t,n){return t+1<n&&e.charCodeAt(t)===45&&e.charCodeAt(t+1)===32}function $oe(e){if(e.length>3)return Km(e);for(let t=0;t<e.length;t++)switch(e.charCodeAt(t)){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!1}return!0}const Noe=["","h1","h2","h3","h4","h5","h6"],Foe=["","#","##","###","####","#####","######"],PC=0,w9=1,_9=2;function Cr(e,t,n,o){const s=new ws(e,t,n);return s.level=o,s.block=!0,s}function Ky(e,t,n){const o=Cr("inline","",0,n);o.map=[t,t+1],o.content=e;const s=new ws("text","",0);return s.content=e,o.children=[s],o}function Roe(e,t,n,o,s){let i=0,r=n;for(;r<o&&t.charCodeAt(r)===35&&i<6;)r++,i++;if(i===0||r>=o||t.charCodeAt(r)!==32)return!1;let l=r+1;for(;l<o&&t.charCodeAt(l)===32;)l++;let a=o;for(;a>l&&t.charCodeAt(a-1)===32;)a--;let u=a;for(;u>l&&t.charCodeAt(u-1)===35;)u--;if(u>l&&t.charCodeAt(u-1)===32)for(a=u-1;a>l&&t.charCodeAt(a-1)===32;)a--;const c=t.slice(l,a);if(!Km(c))return!1;const d=Noe[i],f=Foe[i],h=Cr("heading_open",d,1,0);h.map=[s,s+1],h.markup=f,e.push(h),e.push(Ky(c,s,1));const m=Cr("heading_close",d,-1,0);return m.markup=f,e.push(m),!0}function Ooe(e,t,n){const o=Cr("paragraph_open","p",1,0);o.map=[n,n+1],e.push(o),e.push(Ky(t,n,1)),e.push(Cr("paragraph_close","p",-1,0))}function Poe(e,t,n){const o=e.charCodeAt(n-1);return o===32||o===9?e.slice(t,n).trim():e.slice(t,n)}function x9(e,t){for(;t<e.length&&e.charCodeAt(t)===10;)t++;return t}function Doe(e,t){const n=Cr("bullet_list_open","ul",1,0);return n.map=[t,t],n.markup="-",e.push(n),n}function Boe(e,t,n){const o=Cr("list_item_open","li",1,1);o.map=[n,n+1],o.markup="-",e.push(o);const s=Cr("paragraph_open","p",1,2);s.map=[n,n+1],s.hidden=!0,e.push(s),e.push(Ky(t,n,3));const i=Cr("paragraph_close","p",-1,2);i.hidden=!0,e.push(i);const r=Cr("list_item_close","li",-1,1);return r.markup="-",e.push(r),o}function Hoe(e){const t=Cr("bullet_list_close","ul",-1,0);t.markup="-",e.push(t)}function zoe(e,t,n,o){if(!OC(e,t,n))return null;const s=e.slice(t+3,n);if(s.includes("`"))return null;const i=n<e.length?n+1:n;let r=i,l=i,a=o+1;for(;l<e.length;){const u=bf(e,l);if(OC(e,l,u)&&jh(e,l+3,u)){const c=Cr("fence","code",0,0);return c.map=[o,a+1],c.markup="```",c.info=s,c.content=e.slice(i,r),{token:c,nextPos:u<e.length?u+1:u,nextLine:a+1}}l=u<e.length?u+1:u,r=l,a++}return null}function Woe(e,t){if(e.length===0)return t&&(t.matched=!0),[];if(e.includes("\r")||e.includes("\0"))return null;const n=[];let o=e.length>=1e5?PC:_9,s="",i=!1,r=!1,l=0,a=0;for(;l<e.length;){const u=bf(e,l);if(l===u){l=u<e.length?u+1:u,a++;continue}const c=e.charCodeAt(l);if(c===32||c===9){if(!jh(e,l,u))return null;l=u<e.length?u+1:u,a++;continue}if(c===35){if(!Roe(n,e,l,u,a))return null;t&&(t.blocks++,t.headings++);const m=u<e.length?u+1:u;l=x9(e,m),a+=1+l-m;continue}if(c===45){if(!C9(e,l,u))return null;const m=a;let v=l,k=a,w=null,b=null;for(;v<e.length;){const x=bf(e,v);if(!C9(e,v,x))break;const S=v+2,T=x===S+1?e[S]:e.slice(S,x);if(!$oe(T))return null;w===null&&(w=Doe(n,m)),b=Boe(n,T,k),v=x<e.length?x+1:x,k++}if(w===null||b===null)return null;let _=v,g=k;for(;_<e.length;){if(e.charCodeAt(_)===10){_++,g++;continue}const x=bf(e,_);if(!jh(e,_,x)){if(C9(e,_,x))return null;break}_=x<e.length?x+1:x,g++}w.map[1]=g,b.map[1]=g,Hoe(n),t&&(t.blocks++,t.lists++),l=_,a=g;continue}if(c===96){const m=zoe(e,l,u,a);if(!m)return null;n.push(m.token),t&&(t.blocks++,t.fences++),l=x9(e,m.nextPos),a=m.nextLine+l-m.nextPos;continue}const d=Poe(e,l,u);let f;if(o===_9?(t&&t.paragraphCacheBypasses++,f=Km(d)):o===w9&&d===s?(t&&t.paragraphCacheHits++,f=i):(t&&t.paragraphCacheMisses++,f=Km(d),o===PC?(r&&(o=d===s?w9:_9),s=d,i=f,r=!0):o===w9&&(s=d,i=f)),!f)return null;const h=u<e.length?u+1:u;if(h<e.length&&e.charCodeAt(h)!==10&&!jh(e,h,bf(e,h)))return null;Ooe(n,d,a),t&&(t.blocks++,t.paragraphs++),l=x9(e,h),a+=1+l-h}return t&&(t.matched=!0),n}const Uoe=/[&<>"]/,DC=/[&<>"]/g,joe=/&/g,Voe=/[<>"]/g,qoe={"&":"&","<":"<",">":">",'"':"""};function S9(e){return qoe[e]||e}function eo(e){if(e.length===0)return"";if(e.length<32)return Uoe.test(e)?e.replace(DC,S9):e;const t=e.includes("&"),n=e.includes("<"),o=e.includes(">"),s=e.includes('"');return!t&&!n&&!o&&!s?e:t&&!n&&!o&&!s?e.replace(joe,"&"):t?e.replace(DC,S9):e.replace(Voe,S9)}const Koe=new RegExp(`${/\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g.source}|${/&([a-z#][a-z0-9]{1,31});/gi.source}`,"gi"),Zoe=/^#(?:x[a-f0-9]{1,8}|\d{1,8})$/i;function TI(e){return!e.includes("\\")&&!e.includes("&")?e:e.replace(Koe,(t,n,o)=>{if(n)return n;if(Zoe.test(o)){const i=o[1].toLowerCase()==="x"?Number.parseInt(o.slice(2),16):Number.parseInt(o.slice(1),10);return y2(i)?wp(i):"�"}const s=$y(t);return s!==t?s:t})}const Goe=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/,Yoe=/[\n!"#$%&*+\-:<=>@[\]\\^_`{}~]/,Xoe=/"/g;function Sd(e,t){const n=e.indexOf(` +`,t);return n===-1?e.length:n}function Zm(e,t,n){for(let o=t;o<n;o++){const s=e.charCodeAt(o);if(s!==32&&s!==9)return!1}return!0}function dh(e,t){for(;t<e.length&&e.charCodeAt(t)===10;)t++;return t}function Joe(e,t){return t>=e.length||e.charCodeAt(t)===10?!1:!Zm(e,t,Sd(e,t))}function BC(e,t,n){return t+2<n&&e.charCodeAt(t)===96&&e.charCodeAt(t+1)===96&&e.charCodeAt(t+2)===96}function Qoe(e,t,n){const o=e.charCodeAt(n-1);return o===32||o===9?e.slice(t,n).trim():e.slice(t,n)}function Zy(e){return Yoe.test(e)?Goe.test(e)?null:e.replace(Xoe,"""):e}function ese(e,t,n){let o=0,s=t;for(;s<n&&e.charCodeAt(s)===35&&o<6;)s++,o++;if(o===0||s>=n||e.charCodeAt(s)!==32)return null;let i=s+1;for(;i<n&&e.charCodeAt(i)===32;)i++;let r=n;for(;r>i&&e.charCodeAt(r-1)===32;)r--;let l=r;for(;l>i&&e.charCodeAt(l-1)===35;)l--;if(l>i&&e.charCodeAt(l-1)===32)for(r=l-1;r>i&&e.charCodeAt(r-1)===32;)r--;const a=Zy(e.slice(i,r));return a===null?null:`<h${o}>${a}</h${o}> +`}function HC(e,t,n){return t+1<n&&e.charCodeAt(t)===45&&e.charCodeAt(t+1)===32}function tse(e,t){switch(e.charCodeAt(t)){case 34:return`<li>"</li> +`;case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return null}return`<li>${e[t]}</li> +`}function nse(e,t,n){const o=t+2;if(n===o+1)return tse(e,o);const s=Zy(e.slice(t+2,n));return s===null?null:`<li>${s}</li> +`}function ose(e,t,n){for(;t<n;){const s=e.charCodeAt(t);if(s!==32&&s!==9)break;t++}for(;n>t;){const s=e.charCodeAt(n-1);if(s!==32&&s!==9)break;n--}let o=n;for(let s=t;s<n;s++){const i=e.charCodeAt(s);if(i===96)return null;if(i===32||i===9){o=s;break}}return e.slice(t,o)}function sse(e,t,n,o,s){if(!BC(e,t,n))return null;const i=ose(e,t+3,n);if(i===null)return null;const r=n<e.length?n+1:n;let l=r,a=r;for(;a<e.length;){const u=Sd(e,a);if(BC(e,a,u)&&Zm(e,a+3,u)){const c=e.slice(r,l);let d;return i===o.lang?(s&&s.fenceCacheHits++,d=o.open):(s&&s.fenceCacheMisses++,d=i?`<pre><code class="language-${eo(i)}">`:"<pre><code>",o.lang=i,o.open=d),{html:`${d}${eo(c)}</code></pre> +`,nextPos:u<e.length?u+1:u}}a=u<e.length?u+1:u,l=a}return null}function EI(e,t){if(e.length===0)return t&&(t.matched=!0),"";if(e.includes("\r")||e.includes("\0"))return null;let n=0,o="";const s=e.length>=25e4,i=[],r={lang:null,open:""};let l="",a="",u="",c="";for(;n<e.length;){const d=Sd(e,n);if(n===d){n=d<e.length?d+1:d;continue}const f=e.charCodeAt(n);if(f===32||f===9){if(!Zm(e,n,d))return null;n=d<e.length?d+1:d;continue}if(f===35){const k=ese(e,n,d);if(k===null)return null;t&&(t.blocks++,t.headings++),s?i.push(k):o+=k,n=dh(e,d<e.length?d+1:d);continue}if(f===45){let k=n;for(;k<e.length;){const g=Sd(e,k);if(!HC(e,k,g))break;k=g<e.length?g+1:g}if(k===n)return null;const w=e.slice(n,k);let b;if(w===l)t&&t.listCacheHits++,b=a;else{t&&t.listCacheMisses++;let g=n;for(b=`<ul> +`;g<k;){const x=Sd(e,g),S=nse(e,g,x);if(S===null)return null;b+=S,g=x<e.length?x+1:x}b+=`</ul> +`,l=w,a=b}let _=dh(e,k);for(;_<e.length;){if(e.charCodeAt(_)===10){_++;continue}const g=Sd(e,_);if(!Zm(e,_,g)){if(HC(e,_,g))return null;break}_=g<e.length?g+1:g}t&&(t.blocks++,t.lists++),s?i.push(b):o+=b,n=_;continue}if(f===96){const k=sse(e,n,d,r,t);if(!k)return null;t&&(t.blocks++,t.fences++),s?i.push(k.html):o+=k.html,n=dh(e,k.nextPos);continue}const h=Qoe(e,n,d);let m;if(h===u)t&&t.paragraphCacheHits++,m=c;else{t&&t.paragraphCacheMisses++;const k=Zy(h);if(k===null)return null;m=`<p>${k}</p> +`,u=h,c=m}const v=d<e.length?d+1:d;if(v<e.length&&e.charCodeAt(v)!==10&&Joe(e,v))return null;t&&(t.blocks++,t.paragraphs++),s?i.push(m):o+=m,n=dh(e,v)}return t&&(t.matched=!0),s?i.join(""):o}function zC(e){return EI(e)}function WC(e,t){return EI(e,t)}const ise={maxChunkChars:1e4,maxChunkLines:200,fenceAware:!0,maxChunks:void 0,fallbackOnGlobalState:!0};function Gm(e,t,n={},o){vi(n);const s={...ise,...o||{}},i=Ri(t);if(s.fallbackOnGlobalState!==!1&&i)return v9(n,{count:1,fallback:!0,fallbackReason:i,globalStateDetected:i,maxChunkChars:s.maxChunkChars,maxChunkLines:s.maxChunkLines}),Hd(n,i,()=>e.core.parse(t,n,e).tokens);let r=Vh(t,s);if(s.maxChunks&&r.length>s.maxChunks&&(r=use(r,s.maxChunks)),qh(t,r))return v9(n,{count:1,fallback:!0,fallbackReason:"unsafe-chunk-boundary",maxChunkChars:s.maxChunkChars,maxChunkLines:s.maxChunkLines}),Hd(n,i,()=>e.core.parse(t,n,e).tokens);let l=0;const a=[];return v9(n,{count:r.length,maxChunkChars:s.maxChunkChars,maxChunkLines:s.maxChunkLines,globalStateDetected:i||void 0,globalStateFallbackDisabled:s.fallbackOnGlobalState===!1&&!!i}),Hd(n,i,()=>{for(let u=0;u<r.length;u++){const c=r[u],d=t.slice(c.start,c.end),f=e.core.parse(d,n,e).tokens;l!==0&&f.length&&lse(f,l),ase(a,f),l+=c.lineCount}return a})}function Vh(e,t,n=!0){const o=[];let s=0,i=0,r=0,l=0,a=0,u=0,c=null;function d(f){f<=r||(o.push({start:r,end:f,lineCount:l}),r=f,s=0,i=0,l=0)}for(let f=0;f<e.length;){let h=e.indexOf(` +`,f),m=h;h===-1?(h=e.length,m=e.length):m=h+1;const v=cse(e,f,h);if(t.fenceAware){let b=f;for(;b<h;){const g=e.charCodeAt(b);if(g===32||g===9)b++;else break}const _=e[b];if(_==="`"||_==="~"){let g=b;for(;g<h&&e[g]===_;)g++;const x=g-b;x>=3&&(c?c.marker===_&&x>=c.length&&(c=null):c={marker:_,length:x})}}const k=m-f;s+=k,i+=1,l+=1,v?(a=0,u=0):(a+=1,u+=k);const w=v;if((s>=t.maxChunkChars||i>=t.maxChunkLines)&&!c)if(w)d(m);else{const b=Math.max(10,Math.floor(t.maxChunkLines*.5)),_=Math.max(t.maxChunkChars,8e3);(a>=b||u>=_)&&d(m)}f=m}return n&&d(e.length),o}function qh(e,t,n={rangesCoverWholeSource:!0}){const o=n.rangesCoverWholeSource?t.length-1:t.length;for(let s=0;s<o;s++)if(!rse(e,t[s].end))return!0;return!1}function rse(e,t){if(t<=0||t>e.length||e.charCodeAt(t-1)!==10)return!1;let n=t-2;for(;n>=0&&e.charCodeAt(n)!==10;)n--;for(let o=n+1;o<t-1;o++){const s=e.charCodeAt(o);if(s!==32&&s!==9&&s!==13)return!1}return!0}function lse(e,t){if(t===0)return;const n=[];for(let o=e.length-1;o>=0;o--)n.push(e[o]);for(;n.length;){const o=n.pop();if(o.map&&(o.map[0]+=t,o.map[1]+=t),o.children)for(let s=o.children.length-1;s>=0;s--)n.push(o.children[s])}}function ase(e,t){for(let n=0;n<t.length;n++)e.push(t[n])}function use(e,t){if(e.length<=t)return e;const n=[];let o=0;for(let s=0;s<t;s++){const i=t-s,r=e.length-o,l=Math.ceil(r/i),a=e.slice(o,o+l);let u=0;for(let c=0;c<a.length;c++)u+=a[c].lineCount;n.push({start:a[0].start,end:a[a.length-1].end,lineCount:u}),o+=l}return n}function cse(e,t,n){for(let o=t;o<n;o++){const s=e.charCodeAt(o);if(s!==32&&s!==9&&s!==13)return!1}return!0}const II=4e6,LI=8e4,dse=1e4,fse=200,pse=1e4,hse=200;function $I(e,t){for(let n=0;n<t.length;n++)e.push(t[n])}function mse(e,t){if(t===0)return;const n=[];for(let o=e.length-1;o>=0;o--)n.push(e[o]);for(;n.length;){const o=n.pop();if(o.map&&(o.map[0]+=t,o.map[1]+=t),o.children)for(let s=o.children.length-1;s>=0;s--)n.push(o.children[s])}}function wa(e){return e.length===0?0:Wo(e)+(e.charCodeAt(e.length-1)===10?0:1)}function gse(e,t,n){for(let o=t;o<n;o++){const s=e.charCodeAt(o);if(s!==32&&s!==9&&s!==13)return!1}return!0}function vse(e,t){if(!t||e.length===0)return!1;let n=null;for(let o=0;o<e.length;){let s=e.indexOf(` +`,o);s===-1&&(s=e.length);let i=o;for(;i<s;){const l=e.charCodeAt(i);if(l===32||l===9)i++;else break}const r=e[i];if(r==="`"||r==="~"){let l=i;for(;l<s&&e[l]===r;)l++;const a=l-i;a>=3&&(n?n.marker===r&&a>=n.length&&(n=null):n={marker:r,length:a})}o=s===e.length?e.length:s+1}return n!==null}function yse(e,t){if(e.length===0||e.charCodeAt(e.length-1)!==10)return!1;let n=e.length-2;for(;n>=0&&e.charCodeAt(n)!==10;)n--;return gse(e,n+1,e.length-1)?!vse(e,t):!1}function kse(e,t,n,o={}){const s=o.mode??"full",i=o.fenceAware??(s==="stream"?e.options.streamChunkFenceAware??!0:e.options.fullChunkFenceAware??!0);if(o.maxChunkChars!==void 0||o.maxChunkLines!==void 0||o.autoTune===!1){const r=o.maxChunkChars??(s==="stream"?e.options.streamChunkSizeChars??pse:e.options.fullChunkSizeChars??dse),l=o.maxChunkLines??(s==="stream"?e.options.streamChunkSizeLines??hse:e.options.fullChunkSizeLines??fse);return{maxChunkChars:r,maxChunkLines:l,holdBelowChars:r,holdBelowLines:l,fenceAware:i}}return s==="stream"?t<=5e3?{maxChunkChars:16e3,maxChunkLines:250,holdBelowChars:16e3,holdBelowLines:250,fenceAware:i}:t<=2e4?{maxChunkChars:16e3,maxChunkLines:200,holdBelowChars:16e3,holdBelowLines:200,fenceAware:i}:t<=5e4?{maxChunkChars:16e3,maxChunkLines:250,holdBelowChars:16e3,holdBelowLines:250,fenceAware:i}:t<=5e5?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:32e3,holdBelowLines:350,fenceAware:i}:{maxChunkChars:64e3,maxChunkLines:700,holdBelowChars:64e3,holdBelowLines:700,fenceAware:i}:t<=1e5&&n<=2500?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:1e5,holdBelowLines:2500,fenceAware:i}:t<=2e5?{maxChunkChars:2e4,maxChunkLines:150,holdBelowChars:2e4,holdBelowLines:150,fenceAware:i}:t<=5e5?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:32e3,holdBelowLines:350,fenceAware:i}:{maxChunkChars:64e3,maxChunkLines:700,holdBelowChars:64e3,holdBelowLines:700,fenceAware:i}}var Kp=class{md;options;pending="";tokens=[];committedChars=0;committedLines=0;fedChunks=0;parsedChunks=0;globalStateEnv=null;markedGlobalStateReason=null;constructor(e,t={}){if(this.md=e,this.options={mode:"full",autoTune:!0,retainTokens:!0,...t},this.options.retainTokens===!1&&!this.options.onChunkTokens)throw new Error("UnboundedBuffer with retainTokens=false requires onChunkTokens")}feed(e){e&&(this.pending+=e,this.fedChunks+=1)}flushAvailable(e={}){if(!this.pending)return null;const t=this.resolveWindow(),n=wa(this.pending);if(this.pending.length<t.holdBelowChars&&n<t.holdBelowLines)return this.updateEnvDiagnostics(e,t,n),null;const o=Vh(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!1);if(!o.length)return this.updateEnvDiagnostics(e,t,n),null;if(qh(this.pending,o,{rangesCoverWholeSource:!1}))return this.updateEnvDiagnostics(e,t,n),null;const s=this.commitRanges(o,e);return this.pending=this.pending.slice(s),this.updateEnvDiagnostics(e,t,wa(this.pending)),this.tokens}flushIfBoundary(e={}){if(!this.pending)return null;const t=this.resolveWindow();if(!yse(this.pending,t.fenceAware))return this.updateEnvDiagnostics(e,t,wa(this.pending)),null;const n=Vh(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!0);if(!n.length)return this.updateEnvDiagnostics(e,t,wa(this.pending)),null;const o=qh(this.pending,n,{rangesCoverWholeSource:!0})?[{start:0,end:this.pending.length,lineCount:wa(this.pending)}]:n;return this.commitRanges(o,e),this.pending="",this.updateEnvDiagnostics(e,t,0),this.tokens}flushForce(e={}){if(!this.pending){this.prepareGlobalStateEnv(e,"");const o=this.resolveWindow();return this.updateEnvDiagnostics(e,o,0),this.tokens}const t=this.resolveWindow(),n=Vh(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!0);if(n.length){const o=qh(this.pending,n,{rangesCoverWholeSource:!0})?[{start:0,end:this.pending.length,lineCount:wa(this.pending)}]:n;this.commitRanges(o,e),this.pending=""}return this.updateEnvDiagnostics(e,t,0),this.tokens}reset(){this.pending="",this.tokens=[],this.committedChars=0,this.committedLines=0,this.fedChunks=0,this.parsedChunks=0,this.globalStateEnv=null,this.markedGlobalStateReason=null}peek(){return this.tokens}pendingText(){return this.pending}stats(){return{mode:this.options.mode??"full",fedChunks:this.fedChunks,parsedChunks:this.parsedChunks,committedChars:this.committedChars,committedLines:this.committedLines,pendingChars:this.pending.length,pendingLines:wa(this.pending),retainedTokens:this.options.retainTokens!==!1}}resolveWindow(){const e=this.committedChars+this.pending.length,t=this.committedLines+wa(this.pending);return kse(this.md,e,t,this.options)}prepareGlobalStateEnv(e,t){if(this.globalStateEnv!==e&&(Vp(e)&&la(e),this.globalStateEnv=e,this.markedGlobalStateReason=null),this.markedGlobalStateReason)return;const n=Ri(t);n&&(By(e,n),this.markedGlobalStateReason=n)}commitRanges(e,t){if(!e.length)return 0;this.prepareGlobalStateEnv(t,this.pending);let n=0;try{for(let o=0;o<e.length;o++){const s=e[o],i=this.pending.slice(s.start,s.end),r=this.md.core.parse(i,t,this.md).tokens,l=this.committedChars,a=this.committedLines;a!==0&&r.length&&mse(r,a),this.options.retainTokens!==!1&&$I(this.tokens,r),this.committedChars+=i.length,this.committedLines+=s.lineCount,this.parsedChunks+=1,this.options.onChunkTokens&&this.options.onChunkTokens(r,{chunkIndex:this.parsedChunks,chunkChars:i.length,chunkLines:s.lineCount,tokenCount:r.length,startOffset:l,endOffset:this.committedChars,startLine:a,endLine:this.committedLines}),n=s.end}return this.markedGlobalStateReason&&Hy(t),n}catch(o){throw this.markedGlobalStateReason&&(la(t),this.globalStateEnv=null,this.markedGlobalStateReason=null),o}}updateEnvDiagnostics(e,t,n){zE(e,{mode:this.options.mode??"full",maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,committedChars:this.committedChars,committedLines:this.committedLines,pendingChars:this.pending.length,pendingLines:n,fedChunks:this.fedChunks,parsedChunks:this.parsedChunks,globalStateDetected:this.markedGlobalStateReason||void 0})}};function bse(e,t,n={},o={}){vi(n);const s=new Kp(e,{mode:"full",...o});for(const i of t)s.feed(i),s.flushAvailable(n);return s.flushForce(n)}async function Cse(e,t,n={},o={}){vi(n);const s=new Kp(e,{mode:"full",...o});for await(const i of t)s.feed(i),s.flushAvailable(n);return s.flushForce(n)}function wse(e,t,n,o={},s={}){vi(o);const i=new Kp(e,{mode:"full",...s,retainTokens:!1,onChunkTokens:n});for(const r of t)i.feed(r),i.flushAvailable(o);return i.flushForce(o),i.stats()}async function _se(e,t,n,o={},s={}){vi(o);const i=new Kp(e,{mode:"full",...s,retainTokens:!1,onChunkTokens:n});for await(const r of t)i.feed(r),i.flushAvailable(o);return i.flushForce(o),i.stats()}function NI(e,t,n){if(e.options.autoUnbounded===!1)return!1;const o=e.options.autoUnboundedThresholdChars??II,s=e.options.autoUnboundedThresholdLines??LI;return t>=o||n>=s}function FI(e,t,n){if(e.options.autoUnbounded===!1)return"no";if(t>=(e.options.autoUnboundedThresholdChars??II))return"yes";const o=e.options.autoUnboundedThresholdLines??LI;return n!==void 0?n>=o?"yes":"no":t+1<o?"no":"need-lines"}function zf(e,t,n={},o={}){vi(n);const s=Ri(t);if(Vp(n)&&la(n),o.fallbackOnGlobalState!==!1&&s)return zE(n,{mode:"full",fallback:!0,fallbackReason:s,committedChars:t.length,committedLines:Wo(t),pendingChars:0,pendingLines:0,fedChunks:1,parsedChunks:1,globalStateDetected:s}),Hd(n,s,()=>e.core.parse(t,n,e).tokens);const i=[],r=new Kp(e,{mode:"full",...o,retainTokens:!1,onChunkTokens(l){$I(i,l)}});if(s&&By(n,s),r.feed(t),r.flushForce(n),s&&(Hy(n),o.fallbackOnGlobalState===!1)){const l=Vl(n)?.unbounded;l&&(l.globalStateDetected=s,l.globalStateFallbackDisabled=!0)}return i}const Wd=(e,t,n)=>e<t?t:e>n?n:e;function RI(e){return e.experimental?{...e,...e.experimental}:e}const UC=[{max:5e3,strategy:"discrete",maxChunkChars:32e3,maxChunkLines:150,maxChunks:8,notes:"<=5k"},{max:2e4,strategy:"discrete",maxChunkChars:24e3,maxChunkLines:200,maxChunks:12,notes:"<=20k"},{max:1e5,strategy:"plain",notes:"<=100k plain"},{max:2e5,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:150,maxChunks:12,notes:"<=200k"},{max:5e5,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:16,notes:"<=500k"},{max:5e6,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:16,notes:"<=5M"}],jC=[{max:5e3,strategy:"discrete",maxChunkChars:16e3,maxChunkLines:250,maxChunks:8,notes:"<=5k"},{max:2e4,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:200,maxChunks:24,notes:"<=20k"},{max:1e5,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:200,maxChunks:24,notes:"<=100k"},{max:5e5,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:32,notes:"<=500k"},{max:5e6,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:32,notes:"<=5M"}];function OI(e,t){return{strategy:t.strategy,maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,maxChunks:t.maxChunks,fenceAware:e,notes:t.notes}}function xse(e,t=Math.max(0,e/40|0),n={}){const o=RI(n),s=o.fullChunkFenceAware??!0,i=o.fullChunkTargetChunks??8,r=o.fullChunkAdaptive!==!1;for(let l=0;l<UC.length;l++){const a=UC[l];if(e<=a.max){if(a.strategy!=="adaptive")return OI(s,a);break}}return e>5e6?{strategy:"plain",fenceAware:s,notes:">5M plain"}:r?{strategy:"adaptive",maxChunkChars:Wd(Math.ceil(e/i),8e3,64e3),maxChunkLines:Wd(Math.ceil(t/i),150,700),maxChunks:Wd(Math.ceil(e/64e3),i,16),fenceAware:s,notes:"adaptive fallback"}:{strategy:"discrete",maxChunkChars:o.fullChunkSizeChars??1e4,maxChunkLines:o.fullChunkSizeLines??200,fenceAware:s,maxChunks:o.fullChunkMaxChunks}}function VC(e,t=Math.max(0,e/40|0),n={}){const o=RI(n),s=o.streamChunkFenceAware??!0,i=o.streamChunkTargetChunks??8,r=o.streamChunkAdaptive!==!1;for(let l=0;l<jC.length;l++){const a=jC[l];if(e<=a.max){if(a.strategy!=="adaptive")return OI(s,a);break}}return e>5e6?{strategy:"plain",fenceAware:s,notes:">5M plain"}:r?{strategy:"adaptive",maxChunkChars:Wd(Math.ceil(e/i),8e3,64e3),maxChunkLines:Wd(Math.ceil(t/i),150,700),maxChunks:Wd(Math.ceil(e/64e3),i,32),fenceAware:s,notes:"adaptive fallback"}:{strategy:"discrete",maxChunkChars:o.streamChunkSizeChars??1e4,maxChunkLines:o.streamChunkSizeLines??200,maxChunks:o.streamChunkMaxChunks,fenceAware:s}}var Sse={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["blockquote","code","fence","heading","hr","html_block","lheading","list","reference","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","html_inline","image","link","newline","text"]},inline2:{rules:["balance_pairs","emphasis","fragments_join"]}}},Ase={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}},Mse={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["paragraph"]},inline:{rules:["text"]},inline2:{rules:["balance_pairs","fragments_join"]}}};function C2(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Kh(e,t){if(C2(e))throw new TypeError(`Renderer rule "${t}" returned a Promise. Use renderAsync() instead.`);return e}const qC=e=>C2(e)?e:Promise.resolve(e);function Wf(e){switch(e){case"alt":case"class":case"href":case"id":case"lang":case"rel":case"src":case"start":case"style":case"target":case"title":return e;default:return eo(e)}}function Qa(e){if(!e||e.length===0)return"";const t=e[0];let n=` ${Wf(t[0])}="${eo(t[1])}"`;for(let o=1;o<e.length;o++){const s=e[o];n+=` ${Wf(s[0])}="${eo(s[1])}"`}return n}function PI(e){if(!e)return{langName:"",langAttrs:""};let t=0;for(;t<e.length;){const o=e.charCodeAt(t);if(o===32||o===9||o===10)break;t++}if(t>=e.length)return{langName:e,langAttrs:""};let n=t;for(;n<e.length;){const o=e.charCodeAt(n);if(o!==32&&o!==9&&o!==10)break;n++}return{langName:e.slice(0,t),langAttrs:n<e.length?e.slice(n):""}}function Uf(e,t,n,o,s){if(t.indexOf("<pre")===0)return`${t} +`;if(n){if(!e.attrs||e.attrs.length===0)return`<pre><code class="${eo(`${s.langPrefix??"language-"}${o}`)}">${t}</code></pre> +`;const i=e.attrIndex("class"),r=e.attrs?e.attrs.slice():[],l=`${s.langPrefix??"language-"}${o}`;return i<0?r.push(["class",l]):(r[i]=r[i].slice(),r[i][1]+=` ${l}`),`<pre><code${Qa(r)}>${t}</code></pre> +`}return`<pre><code${Qa(e.attrs)}>${t}</code></pre> +`}function xp(e){return!e.attrs||e.attrs.length===0?`<code>${eo(e.content)}</code>`:`<code${Qa(e.attrs)}>${eo(e.content)}</code>`}function B3(e){const t=eo(e.content);return e.attrs?`<pre${Qa(e.attrs)}><code>${t}</code></pre> +`:`<pre><code>${t}</code></pre> +`}function Tse(e,t){const n=e.attrs;if(!n||n.length===0)switch(e.type){case"paragraph_open":return`${t}<p>`;case"heading_open":return`<${e.tag}>`;case"td_open":return`${t}<td>`;case"th_open":return`${t}<th>`;default:return null}if(n.length===1&&n[0][0]==="style"){if(e.type==="td_open")return`${t}<td style="${eo(n[0][1])}">`;if(e.type==="th_open")return`${t}<th style="${eo(n[0][1])}">`}return null}function KC(e){const t=e.attrs;return!t||t.length===0?"<a>":t.length===1?`<a ${Wf(t[0][0])}="${eo(t[0][1])}">`:t.length===2?`<a ${Wf(t[0][0])}="${eo(t[0][1])}" ${Wf(t[1][0])}="${eo(t[1][1])}">`:`<a${Qa(t)}>`}function Ese(e){switch(e.type){case"text":case"text_special":case"softbreak":case"hardbreak":case"html_inline":case"code_inline":case"image":return!0;default:return!1}}function ZC(e){switch(e.type){case"text":case"text_special":case"softbreak":case"hardbreak":case"html_inline":case"code_inline":return!0;default:return!1}}function Ym(e,t){if(e.hidden)return"";const n=e.attrs,o=e.nesting,s=e.tag;if(!n||n.length===0)return o===0?t?`<${s} />`:`<${s}>`:o===-1?`</${s}>`:`<${s}>`;let i=(o===-1?"</":"<")+s+Qa(n);return o===0&&t&&(i+=" /"),`${i}>`}const Ise={langPrefix:"language-",xhtmlOut:!1,breaks:!1},fh=Object.prototype.hasOwnProperty,On={code_inline(e,t){return xp(e[t])},code_block(e,t){return B3(e[t])},fence(e,t,n,o,s){const i=e[t],r=i.info?TI(i.info).trim():"",{langName:l,langAttrs:a}=PI(r),u=n.highlight,c=eo(i.content);if(!u)return Uf(i,c,r,l,n);const d=u(i.content,l,a);return C2(d)?d.then(f=>Uf(i,f||c,r,l,n)):Uf(i,d||c,r,l,n)},image(e,t,n,o,s){const i=e[t],r=s.renderInlineAsText(i.children||[],n,o),l=i.attrIndex("alt");return l>=0&&i.attrs?i.attrs[l][1]=r:i.attrs?i.attrs.push(["alt",r]):i.attrs=[["alt",r]],Ym(i,n.xhtmlOut===!0)},hardbreak(e,t,n){return n.xhtmlOut?`<br /> +`:`<br> +`},softbreak(e,t,n){return n.breaks?n.xhtmlOut?`<br /> +`:`<br> +`:` +`},text(e,t){return eo(e[t].content)},text_special(e,t){return eo(e[t].content)},html_block(e,t){return e[t].content},html_inline(e,t){return e[t].content}};function GC(e,t,n){const o=e.info?TI(e.info).trim():"",{langName:s,langAttrs:i}=PI(o),r=t.highlight,l=eo(e.content);if(!r)return Uf(e,l,o,s,t);const a=r(e.content,s,i);if(C2(a))throw new TypeError('Renderer rule "fence" returned a Promise. Use renderAsync() instead.');return Uf(e,a||l,o,s,t)}function A9(e,t,n,o){switch(e.type){case"text":return t.text===On.text?e.content.length===0?"":eo(e.content):null;case"text_special":return t.text_special===On.text_special?e.content.length===0?"":eo(e.content):null;case"softbreak":return t.softbreak===On.softbreak?o:null;case"hardbreak":return t.hardbreak===On.hardbreak?n:null;case"html_inline":return t.html_inline===On.html_inline?e.content:null;case"code_inline":return t.code_inline===On.code_inline?xp(e):null;default:return null}}function Lse(e,t,n,o,s){const i=e[0];switch(i.type){case"text":if(s.text===On.text)return i.content.length===0?"":eo(i.content);break;case"text_special":if(s.text_special===On.text_special)return i.content.length===0?"":eo(i.content);break;case"softbreak":if(s.softbreak===On.softbreak)return t.breaks?t.xhtmlOut?`<br /> +`:`<br> +`:` +`;break;case"hardbreak":if(s.hardbreak===On.hardbreak)return t.xhtmlOut?`<br /> +`:`<br> +`;break;case"html_inline":if(s.html_inline===On.html_inline)return i.content;break;case"code_inline":if(s.code_inline===On.code_inline)return xp(i);break}const r=s[i.type];if(!r)return Ym(i,t.xhtmlOut===!0);const l=r(e,0,t,n,o);return typeof l=="string"?l:Kh(l,i.type)}var $se=class{rules;baseOptions;normalizedBase;constructor(e={}){this.baseOptions={...e},this.normalizedBase=this.buildNormalizedBase(),this.rules={...On}}set(e){return this.baseOptions={...this.baseOptions,...e},this.normalizedBase=this.buildNormalizedBase(),this}render(e,t,n){if(!Array.isArray(e))throw new TypeError("render expects token array as first argument");if(e.length===1)return this.renderSingleToken(e,e[0],t,n);const o=this.mergeOptions(t),s=n??{},i=this.rules,r=o.xhtmlOut===!0;let l,a,u,c,d,f,h="",m="",v=!1,k="";for(let w=0;w<e.length;w++){const b=e[w],_=b.type,g=w>0&&e[w-1].hidden?` +`:"";if(_==="list_item_open"&&(!b.attrs||b.attrs.length===0)&&w+3<e.length){const T=e[w+1],A=e[w+2],E=e[w+3];if(T.type==="paragraph_open"&&T.hidden&&A.type==="inline"&&E.type==="paragraph_close"&&E.hidden){k+=`${g}<li>${this.renderInlineTokens(A.children||[],o,s)}`,w+=3;continue}}if(w+2<e.length){const T=e[w+1],A=e[w+2];if(T.type==="inline"&&A.nesting===-1&&A.tag===b.tag&&!A.hidden){const E=Tse(b,g);if(E!==null){k+=`${E+this.renderInlineTokens(T.children||[],o,s)}</${b.tag}> +`,w+=2;continue}}}if(_==="inline"){const T=b.children||[];if(T.length===1){v||(l=i.text,a=i.text_special,u=i.softbreak,c=i.hardbreak,d=i.html_inline,f=i.code_inline,h=o.xhtmlOut?`<br /> +`:`<br> +`,m=o.breaks?h:` +`,v=!0);const A=T[0];switch(A.type){case"text":if(l===On.text){k+=eo(A.content);continue}break;case"text_special":if(a===On.text_special){k+=eo(A.content);continue}break;case"softbreak":if(u===On.softbreak){k+=m;continue}break;case"hardbreak":if(c===On.hardbreak){k+=h;continue}break;case"html_inline":if(d===On.html_inline){k+=A.content;continue}break;case"code_inline":if(f===On.code_inline){k+=xp(A);continue}break}}k+=this.renderInlineTokens(T,o,s);continue}const x=i[_];if(!x){const T=b.attrs;if(!b.hidden){if(!T||T.length===0)switch(_){case"hr":k+=r?`<hr /> +`:`<hr> +`;continue;case"heading_open":k+=`<${b.tag}>`;continue;case"heading_close":k+=`</${b.tag}> +`;continue;case"paragraph_open":k+=`${g}<p>`;continue;case"paragraph_close":k+=`</p> +`;continue;case"list_item_open":{const A=e[w+1];k+=g+(A&&(A.type==="inline"||A.hidden||A.nesting===-1&&A.tag==="li")?"<li>":`<li> +`);continue}case"list_item_close":k+=`</li> +`;continue;case"bullet_list_open":k+=`${g}<ul> +`;continue;case"bullet_list_close":k+=`</ul> +`;continue;case"blockquote_open":k+=g+(e[w+1]&&e[w+1].nesting===-1&&e[w+1].tag==="blockquote"?"<blockquote>":`<blockquote> +`);continue;case"blockquote_close":k+=`</blockquote> +`;continue;case"ordered_list_open":k+=`${g}<ol> +`;continue;case"ordered_list_close":k+=`</ol> +`;continue;case"table_open":k+=`${g}<table> +`;continue;case"table_close":k+=`</table> +`;continue;case"thead_open":k+=`${g}<thead> +`;continue;case"thead_close":k+=`</thead> +`;continue;case"tbody_open":k+=`${g}<tbody> +`;continue;case"tbody_close":k+=`</tbody> +`;continue;case"tr_open":k+=`${g}<tr> +`;continue;case"tr_close":k+=`</tr> +`;continue;case"td_open":k+=`${g}<td>`;continue;case"td_close":k+=`</td> +`;continue;case"th_open":k+=`${g}<th>`;continue;case"th_close":k+=`</th> +`;continue}else if(T.length===1){const A=T[0];if(_==="ordered_list_open"&&A[0]==="start"){k+=`${g}<ol start="${eo(A[1])}"> +`;continue}if(_==="td_open"&&A[0]==="style"){k+=`${g}<td style="${eo(A[1])}">`;continue}if(_==="th_open"&&A[0]==="style"){k+=`${g}<th style="${eo(A[1])}">`;continue}}}k+=this.renderToken(e,w,o);continue}if(_==="code_block"&&x===On.code_block){k+=B3(b);continue}if(_==="fence"&&x===On.fence){k+=GC(b,o);continue}if(_==="html_block"&&x===On.html_block){k+=b.content;continue}const S=x(e,w,o,s,this);typeof S=="string"?k+=S:k+=Kh(S,b.type)}return k}async renderAsync(e,t,n){if(!Array.isArray(e))throw new TypeError("render expects token array as first argument");const o=this.mergeOptions(t),s=n??{},i=this.rules;let r="";for(let l=0;l<e.length;l++){const a=e[l];if(a.type==="inline"){r+=await this.renderInlineTokensAsync(a.children||[],o,s);continue}const u=i[a.type];u?r+=await qC(u(e,l,o,s,this)):r+=this.renderToken(e,l,o)}return r}renderInline(e,t,n){const o=this.mergeOptions(t),s=n??{};return this.renderInlineTokens(e,o,s)}async renderInlineAsync(e,t,n){const o=this.mergeOptions(t),s=n??{};return this.renderInlineTokensAsync(e,o,s)}renderInlineAsText(e,t,n){const o=this.mergeOptions(t),s=n??{};return this.renderInlineAsTextInternal(e,o,s)}renderAttrs(e){return Qa(e.attrs)}renderToken(e,t,n){const o=e[t];if(o.hidden)return"";const s=o.block,i=o.nesting,r=o.tag,l=o.attrs;let a=!1;if(s&&(a=!0,i===1&&t+1<e.length)){const f=e[t+1];(f.type==="inline"||f.hidden||f.nesting===-1&&f.tag===r)&&(a=!1)}const u=s&&i!==-1&&t>0&&e[t-1].hidden?` +`:"",c=a?`> +`:">";if(!l||l.length===0)return i===0?n.xhtmlOut?`${u}<${r} /${c}`:`${u}<${r}${c}`:i===-1?`${u}</${r}${c}`:`${u}<${r}${c}`;let d=u+(i===-1?"</":"<")+r+Qa(l);return i===0&&n.xhtmlOut&&(d+=" /"),d+c}mergeOptions(e){const t=this.normalizedBase;if(!e||e.highlight===t.highlight&&e.langPrefix===t.langPrefix&&e.xhtmlOut===t.xhtmlOut&&e.breaks===t.breaks)return t;let n=null;const o=()=>(n||(n={...t}),n);if(fh.call(e,"highlight")&&e.highlight!==t.highlight&&(o().highlight=e.highlight),fh.call(e,"langPrefix")){const s=e.langPrefix;s!==t.langPrefix&&(o().langPrefix=s)}if(fh.call(e,"xhtmlOut")){const s=e.xhtmlOut;s!==t.xhtmlOut&&(o().xhtmlOut=s)}if(fh.call(e,"breaks")){const s=e.breaks;s!==t.breaks&&(o().breaks=s)}return n||t}buildNormalizedBase(){return Object.freeze({...Ise,...this.baseOptions})}renderSingleToken(e,t,n,o){const s=this.rules,i=t.type;if(i==="code_block"&&s.code_block===On.code_block)return B3(t);if(i==="html_block"&&s.html_block===On.html_block)return t.content;const r=this.mergeOptions(n),l=o??{};if(i==="inline")return this.renderInlineTokens(t.children||[],r,l);const a=s[i];if(!a)return t.block?this.renderToken(e,0,r):Ym(t,r.xhtmlOut===!0);if(i==="fence"&&a===On.fence)return GC(t,r);const u=a(e,0,r,l,this);return typeof u=="string"?u:Kh(u,i)}renderInlineTokens(e,t,n){if(!e||e.length===0)return"";const o=this.rules;if(e.length===1)return Lse(e,t,n,this,o);const s=t.xhtmlOut===!0,i=s?`<br /> +`:`<br> +`,r=t.breaks?i:` +`,l=o.text,a=o.text_special,u=o.softbreak,c=o.hardbreak,d=o.html_inline,f=o.code_inline,h=o.link_open,m=o.link_close,v=o.em_open,k=o.em_close,w=o.strong_open,b=o.strong_close;let _="";for(let g=0;g<e.length;g++){const x=e[g];if(x.type==="link_open"&&!h&&!m&&g+2<e.length){const A=e[g+1];if(e[g+2].type==="link_close"&&Ese(A)){const E=A9(A,o,i,r);if(E!==null){const P=`${KC(x)+E}</a>`;if(u===On.softbreak&&g+3<e.length&&e[g+3].type==="softbreak"){_+=P+r,g+=3;continue}_+=P,g+=2;continue}}}if(x.type==="link_open"&&!h&&!m&&g+1<e.length&&e[g+1].type==="link_close"){_+=`${KC(x)}</a>`,g+=1;continue}if(x.type==="em_open"&&!v&&!k&&g+2<e.length){const A=e[g+1];if(e[g+2].type==="em_close"&&ZC(A)){const E=A9(A,o,i,r);if(E!==null){_+=`<em>${E}</em>`,g+=2;continue}}}if(x.type==="strong_open"&&!w&&!b&&g+2<e.length){const A=e[g+1];if(e[g+2].type==="strong_close"&&ZC(A)){const E=A9(A,o,i,r);if(E!==null){_+=`<strong>${E}</strong>`,g+=2;continue}}}switch(x.type){case"text":if(l===On.text){const A=x.content.length===0?"":eo(x.content);if(d===On.html_inline&&g+1<e.length&&e[g+1].type==="html_inline"){for(_+=A+e[++g].content;g+1<e.length&&e[g+1].type==="html_inline";)_+=e[++g].content;continue}_+=A;continue}break;case"text_special":if(a===On.text_special){x.content.length!==0&&(_+=eo(x.content));continue}break;case"softbreak":if(u===On.softbreak){_+=r;continue}break;case"hardbreak":if(c===On.hardbreak){_+=i;continue}break;case"html_inline":if(d===On.html_inline){for(_+=x.content;g+1<e.length&&e[g+1].type==="html_inline";)_+=e[++g].content;continue}break;case"code_inline":if(f===On.code_inline){_+=xp(x);continue}break}const S=o[x.type];if(!S){_+=x.block?this.renderToken(e,g,t):Ym(x,s);continue}const T=S(e,g,t,n,this);typeof T=="string"?_+=T:_+=Kh(T,x.type)}return _}async renderInlineTokensAsync(e,t,n){if(!e||e.length===0)return"";const o=this.rules;let s="";for(let i=0;i<e.length;i++){const r=o[e[i].type];r?s+=await qC(r(e,i,t,n,this)):s+=this.renderToken(e,i,t)}return s}renderInlineAsTextInternal(e,t,n){if(!e||e.length===0)return"";let o="";for(let s=0;s<e.length;s++){const i=e[s];switch(i.type){case"text":case"text_special":o+=i.content;break;case"image":o+=this.renderInlineAsTextInternal(i.children||[],t,n);break;case"html_inline":case"html_block":o+=i.content;break;case"softbreak":case"hardbreak":o+=` +`;break}}return o}},Nse=$se;const Fse=[],M9=4096;function Rse(e){const t=e.length;let n=0;for(;n<=t;){let o=e.indexOf(` +`,n);o===-1&&(o=t);const s=o<t;let i=n,r=0;for(;i<o;){const l=e.charCodeAt(i);if(l===32){if(r++,i++,r>=4)return!0;continue}if(l===9){if(r+=4-r%4,i++,r>=4)return!0;continue}break}if(i<o){const l=e.charCodeAt(i);switch(l){case 35:{let a=i;for(;a<o&&e.charCodeAt(a)===35;)a++;const u=a-i;if(u>0&&u<=6){if(a<o){const c=e.charCodeAt(a);if(c===32||c===9||c===13)return!0}else if(a===o&&s)return!0}break}case 62:{const a=i+1;if(a<o){const u=e.charCodeAt(a);if(u===32||u===9||u===13)return!0}else if(a===o&&s)return!0;break}case 45:case 42:case 43:{const a=i+1;if(a<o){const u=e.charCodeAt(a);if(u===32||u===9||u===13)return!0}else if(a===o&&s)return!0;break}case 96:case 126:{let a=i;for(;a<o&&e.charCodeAt(a)===l;)a++;if(a-i>=3)return!0;break}default:if(l>=48&&l<=57){let a=i+1;for(;a<o;){const u=e.charCodeAt(a);if(u<48||u>57)break;a++}if(a<o&&e.charCodeAt(a)===46){const u=a+1;if(u<o){const c=e.charCodeAt(u);if(c===32||c===9||c===13)return!0}else if(u===o&&s)return!0}}break}}if(o===t)break;n=o+1}return!1}function Ose(e,t){if(!e&&!t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n][0]!==t[n][0]||e[n][1]!==t[n][1])return!1;return!0}function Pse(e,t){if(!e&&!t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!DI(e[n],t[n]))return!1;return!0}function DI(e,t){if(!e||!t||e.type!==t.type)return!1;const n=e.map,o=t.map;return!!n!=!!o||n&&o&&(n[0]!==o[0]||n[1]!==o[1])||e.tag!==t.tag||e.nesting!==t.nesting||e.markup!==t.markup||e.info!==t.info||e.block!==t.block||e.hidden!==t.hidden||!Ose(e.attrs,t.attrs)||!Pse(e.children,t.children)?!1:(e.content||"")===(t.content||"")}function YC(){return{total:0,cacheHits:0,appendHits:0,unboundedAppendHits:0,tailHits:0,fullParses:0,resets:0,chunkedParses:0,lastMode:"idle"}}var Dse=class{core;cache=null;stats=YC();MIN_SIZE_FOR_OPTIMIZATION=1e3;DEFAULT_SKIP_CACHE_CHARS=1e6;DEFAULT_SKIP_CACHE_LINES=1e5;IMPLICIT_STREAM_CHUNK_MIN_CHARS=16e4;MIN_LIST_LINES_FOR_MERGE=80;MIN_LIST_CHARS_FOR_MERGE=800;MIN_TABLE_LINES_FOR_MERGE=48;MIN_TABLE_CHARS_FOR_MERGE=1200;MIN_UNBOUNDED_APPEND_TOTAL_CHARS=5e5;MIN_UNBOUNDED_APPEND_CHARS=64e3;MIN_UNBOUNDED_APPEND_LINES=700;constructor(e){this.core=e}reset(){this.cache=null,this.stats.resets+=1,this.stats.lastMode="reset"}resetStats(){const{resets:e}=this.stats;this.stats=YC(),this.stats.resets=e}parse(e,t,n){const o=t,s=this.cache;if(vi(o??s?.env),!s||o&&o!==s.env){const $=o??{},B=!!n.__explicitStreamChunkFallbackSetting,H=typeof n.__canUseImplicitLargeInputStrategy=="function"?n.__canUseImplicitLargeInputStrategy():!0,O=!!n.options?.streamChunkedFallback,F=!B&&H,U=O||F,z=n.options?.streamChunkAdaptive!==!1,W=n.options?.streamChunkTargetChunks??8,K=n.options?.streamChunkSizeChars,V=n.options?.streamChunkSizeLines,ie=n.options?.streamChunkMaxChunks,ne=!!n.__explicitStreamChunkConfig,X=n.options?.autoTuneChunks!==!1,le=n.options?.streamChunkFenceAware??!0,Ie=n.options?.streamLargeCachePolicy??"retain",de=n.options?.streamSkipCacheAboveChars??this.DEFAULT_SKIP_CACHE_CHARS,pe=n.options?.streamSkipCacheAboveLines??this.DEFAULT_SKIP_CACHE_LINES;let ve,oe=!1;if(Ie==="skip"&&(oe=e.length>=de,!oe&&pe!==void 0&&(ve=Wo(e),oe=ve>=pe)),oe){const G=this.parseFullDocument(e,$,n,ve,!1);return this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",ss($,{area:"stream",path:"stream-full",reason:"skip-cache-large-one-shot",unbounded:!!Vl($)?.unbounded}),G.tokens}else if(U){const G=(ce,ue,Se)=>ce<ue?ue:ce>Se?Se:ce;ve===void 0&&(ve=Wo(e));const Y=X&&!ne?VC(e.length,ve,n.options):null,fe=Y?.maxChunkChars??(z?G(Math.ceil(e.length/W),8e3,64e3):K??1e4),we=Y?.maxChunkLines??(z?G(Math.ceil(ve/W),150,700):V??200),ge=Y?.maxChunks??(z?G(Math.ceil(e.length/64e3),W,32):ie),Q=e.length>0&&e.charCodeAt(e.length-1)===10,te=F&&e.length>=this.IMPLICIT_STREAM_CHUNK_MIN_CHARS&&Y?.strategy!=="plain";if((O||te)&&(e.length>=fe*2||ve>=we*2)&&Q){const ce=Gm(n,e,$,{maxChunkChars:fe,maxChunkLines:we,fenceAware:Y?.fenceAware??le,maxChunks:ge});return this.cache={src:e,tokens:ce,env:$,lineCount:ve,lastSegment:void 0,globalStateReason:Ri(e)},this.updateCacheLineCount(this.cache,ve),this.recordChunkedParseResult($,O?"explicit-initial-large-doc":"default-initial-large-doc"),ce}}const ye=this.parseFullDocument(e,$,n,ve);return ve=ye.lineCount,this.cache={src:e,tokens:ye.tokens,env:$,lineCount:ve,lastSegment:void 0,globalStateReason:Ri(e)},this.updateCacheLineCount(this.cache,ve),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",ss($,{area:"stream",path:"stream-full",reason:"initial-parse",unbounded:!!Vl($)?.unbounded}),ye.tokens}if(e===s.src)return this.stats.total+=1,this.stats.cacheHits+=1,this.stats.lastMode="cache",ss(s.env,{area:"stream",path:"stream-cache",reason:"same-source"}),s.tokens;const i=e.startsWith(s.src)?e.slice(s.src.length):null;let r=s.globalStateReason;r===void 0&&(r=Ri(s.src),s.globalStateReason=r);const l=r?null:i!==null?this.detectGlobalStateForAppend(s,i):Ri(e),a=r||l;if(a){const $=o??s.env;la($);const B=Ri(e),H=this.parseFullDocument(e,$,n),O=H.tokens,F=H.lineCount;return this.cache={src:e,tokens:O,env:$,lineCount:F,lastSegment:void 0,globalStateReason:B},this.updateCacheLineCount(this.cache,F),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",ss($,{area:"stream",path:"stream-full",reason:`global-state:${a}`,unbounded:!!Vl($)?.unbounded}),O}const u=n.options?.streamOptimizationMinSize??this.MIN_SIZE_FOR_OPTIMIZATION;if(s.src.length<u&&e.length<u*1.5&&!e.startsWith(s.src)){const $=o??s.env,B=this.parseFullDocument(e,$,n),H=B.tokens,O=B.lineCount;return this.cache={src:e,tokens:H,env:$,lineCount:O,lastSegment:void 0,globalStateReason:Ri(e)},this.updateCacheLineCount(this.cache,O),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",ss($,{area:"stream",path:"stream-full",reason:"small-non-append",unbounded:!!Vl($)?.unbounded}),H}const c=this.getAppendedSegment(s.src,e,i);if(c&&!this.shouldPreferTailReparseForAppend(s)){const $=s.lineCount??Wo(s.src);let B=3;c.length>5e3?B=8:c.length>1e3?B=6:c.length>200&&(B=4),B=Math.min(B,$);let H=null;const O=n.options?.streamContextParseStrategy??"chars",F=n.options?.streamContextParseMinChars??200,U=n.options?.streamContextParseMinLines??2;let z;const W=()=>(z===void 0&&(z=Wo(c)),z),K=this.canDirectlyParseAppend(s),V=K&&this.shouldUseUnboundedAppend(e,s,c);let ie=!1;if(!K)switch(O){case"lines":ie=W()>=U;break;case"constructs":if(c.length>=F){ie=!0;break}if(Rse(c)){ie=!0;break}ie=W()>=U;break;case"chars":default:ie=c.length>=F}if(B>0&&ie){const le=this.getTailLines(s.src,B)+c;try{const Ie=this.core.parse(le,s.env,n).tokens,de=Ie.findIndex(pe=>pe.map&&typeof pe.map[1]=="number"&&pe.map[1]>B);if(de!==-1){const pe=Ie.slice(de),ve=$-B;ve!==0&&this.shiftTokenLines(pe,ve),H={tokens:pe}}}catch{H=null}}else H=null;if(!H){const le=$;if(V)H={tokens:zf(n,c,s.env,{mode:"stream"})},le>0&&this.shiftTokenLines(H.tokens,le);else{const Ie=this.core.parse(c,s.env,n);le>0&&this.shiftTokenLines(Ie.tokens,le),H=Ie}}let ne=0;if(s.tokens.length>0&&H.tokens.length>0){const le=s.tokens[s.tokens.length-1],Ie=H.tokens[0];try{le.type==="inline"&&Ie.type==="inline"&&(Ie.children&&Ie.children.length>0&&(le.children||(le.children=[]),this.appendTokens(le.children,Ie.children)),le.content=(le.content||"")+(Ie.content||""),ne=1)}catch{ne=0}}const X=s.tokens.length;if(H.tokens.length>ne){const le=s.tokens,Ie=H.tokens,de=Math.min(le.length,Ie.length-ne);let pe=0;for(let ve=de;ve>0;ve--){let oe=!0;for(let ye=0;ye<ve;ye++){const G=le[le.length-ve+ye],Y=Ie[ne+ye];if(!DI(G,Y)){oe=!1;break}}if(oe){pe=ve;break}}pe>0&&(ne+=pe),Ie.length>ne&&this.appendTokens(s.tokens,Ie,ne)}if(s.src=e,s.globalStateReason=null,s.lineCount=$+(z??W()),s.tokens.length>X){const le=this.getLastSegment(s.tokens,e,X,s.tokens.length,e.length-c.length,$);le?s.lastSegment=le:s.lastSegment=void 0}else s.lastSegment=void 0;return this.stats.total+=1,this.stats.appendHits+=1,V&&(this.stats.unboundedAppendHits=(this.stats.unboundedAppendHits||0)+1),this.stats.lastMode="append",ss(s.env,{area:"stream",path:V?"stream-unbounded-append":"stream-append",reason:V?"large-delta":"safe-append",unbounded:V}),s.tokens}const d=o??s.env,f=this.tryTailSegmentReparse(e,s,d,n);if(f)return this.stats.total+=1,this.stats.tailHits+=1,this.stats.lastMode="tail",ss(d,{area:"stream",path:"stream-tail",reason:"tail-reparse"}),f;const h=!!n.__explicitStreamChunkFallbackSetting,m=typeof n.__canUseImplicitLargeInputStrategy=="function"?n.__canUseImplicitLargeInputStrategy():!0,v=!!n.options?.streamChunkedFallback,k=!h&&!c&&m,w=v||k,b=n.options?.streamChunkAdaptive!==!1,_=n.options?.streamChunkTargetChunks??8,g=n.options?.streamChunkSizeChars,x=n.options?.streamChunkSizeLines,S=n.options?.streamChunkMaxChunks,T=!!n.__explicitStreamChunkConfig,A=n.options?.autoTuneChunks!==!1,E=n.options?.streamChunkFenceAware??!0;let P=c&&s.lineCount!==void 0?s.lineCount+Wo(c):void 0;if(w){P===void 0&&(P=Wo(e));const $=(W,K,V)=>W<K?K:W>V?V:W,B=A&&!T?VC(e.length,P,n.options):null,H=B?.maxChunkChars??(b?$(Math.ceil(e.length/_),8e3,64e3):g??1e4),O=B?.maxChunkLines??(b?$(Math.ceil(P/_),150,700):x??200),F=B?.maxChunks??(b?$(Math.ceil(e.length/64e3),_,32):S),U=e.length>0&&e.charCodeAt(e.length-1)===10,z=k&&e.length>=this.IMPLICIT_STREAM_CHUNK_MIN_CHARS&&B?.strategy!=="plain";if((v||z)&&(e.length>=H*2||P>=O*2)&&U){const W=Gm(n,e,d,{maxChunkChars:H,maxChunkLines:O,fenceAware:B?.fenceAware??E,maxChunks:F});return this.cache={src:e,tokens:W,env:d,lineCount:P,lastSegment:void 0,globalStateReason:Ri(e)},this.updateCacheLineCount(this.cache,P),this.recordChunkedParseResult(d,v?"explicit-fallback-large-doc":"default-fallback-large-doc"),W}}const D=this.parseFullDocument(e,d,n,P),I=D.tokens;return P=D.lineCount,this.cache={src:e,tokens:I,env:d,lineCount:P,lastSegment:void 0,globalStateReason:Ri(e)},this.updateCacheLineCount(this.cache,P),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",ss(d,{area:"stream",path:"stream-full",reason:"fallback-full",unbounded:!!Vl(d)?.unbounded}),I}recordChunkedParseResult(e,t){const n=Vl(e)?.chunk,o=n?.fallback?String(n.fallbackReason||"global-state"):null;if(this.stats.total+=1,o){this.stats.fullParses+=1,this.stats.lastMode="full",ss(e,{area:"stream",path:"stream-full",reason:`global-state:${o}`,unbounded:!!Vl(e)?.unbounded});return}this.stats.chunkedParses=(this.stats.chunkedParses||0)+1,this.stats.lastMode="chunked",ss(e,{area:"stream",path:"stream-chunked",chunked:!0,reason:t})}parseFullDocument(e,t,n,o,s=!0){const i=Ri(e);Vp(t)&&la(t);const r=typeof n.__canUseImplicitLargeInputStrategy!="function"||n.__canUseImplicitLargeInputStrategy()?FI(n,e.length,o):"no";if(r==="yes"){const a=zf(n,e,t);return ss(t,{area:"stream",path:"stream-full",reason:"auto-unbounded-char-threshold",unbounded:!0}),{tokens:a,lineCount:o??(s?Wo(e):0)}}let l=o;if(r==="need-lines"&&(l=Wo(e),NI(n,e.length,l))){const a=zf(n,e,t);return ss(t,{area:"stream",path:"stream-full",reason:"auto-unbounded-line-threshold",unbounded:!0}),{tokens:a,lineCount:l}}return l===void 0&&(l=s?Wo(e):0),{tokens:Hd(t,i,()=>this.core.parse(e,t,n).tokens),lineCount:l}}shouldUseUnboundedAppend(e,t,n){return!n||e.length<this.MIN_UNBOUNDED_APPEND_TOTAL_CHARS&&n.length<this.MIN_UNBOUNDED_APPEND_CHARS?!1:n.length>=this.MIN_UNBOUNDED_APPEND_CHARS?!0:Wo(n)>=this.MIN_UNBOUNDED_APPEND_LINES}getAppendedSegment(e,t,n){if(n===null||n===void 0&&!t.startsWith(e)||!e.endsWith(` +`))return null;const o=n??t.slice(e.length);if(!o)return null;const s=o.length;if(o.charCodeAt(s-1)!==10)return null;let i=0,r=-1;for(let a=0;a<s&&!(o.charCodeAt(a)===10&&(r===-1&&(r=a),i++,i>=2));a++);if(i<2)return null;const l=(r===-1?o:o.slice(0,r)).trim();if(l.length===0)return null;if(/^[-=]+$/.test(l)){const a=e.slice(0,-1),u=a.lastIndexOf(` +`);if(a.slice(u+1).trim().length>0)return null}return this.endsInsideOpenFence(e)||this.mayContainReferenceDefinition(o)?null:o}tryTailSegmentReparse(e,t,n,o){const s=this.ensureLastSegment(t);if(!s||s.srcOffset<=0&&s.tokenStart<=0)return null;const i=t.src.slice(0,s.srcOffset);if(!e.startsWith(i))return null;const r=t.src.slice(s.srcOffset),l=e.slice(s.srcOffset);if(l===r)return null;const a=e.startsWith(t.src)?e.slice(t.src.length):null;if(a){const u=this.tryContainerTailAppendMerge(e,t,n,o,s,a);if(u)return u}if(this.mayContainReferenceDefinition(r)||this.mayContainReferenceDefinition(l))return null;try{const u=this.core.parse(l,n,o),c=this.getLastSegment(u.tokens,l);return s.lineStart>0&&this.shiftTokenLines(u.tokens,s.lineStart),t.src=e,t.env=n,t.globalStateReason=null,t.globalStateCarry=void 0,t.tokens.length=s.tokenStart,this.appendTokens(t.tokens,u.tokens),t.lineCount=s.lineStart+Wo(l),c?t.lastSegment={tokenStart:s.tokenStart+c.tokenStart,tokenEnd:s.tokenStart+c.tokenEnd,lineStart:s.lineStart+c.lineStart,lineEnd:s.lineStart+c.lineEnd,srcOffset:s.srcOffset+c.srcOffset}:t.lastSegment=null,t.tokens}catch{return null}}getTailLines(e,t){if(t<=0)return"";let n=t;for(let o=e.length-1;o>=0;o--)if(e.charCodeAt(o)===10&&(n--,n===0))return e.slice(o+1);return e}endsInsideOpenFence(e){const n=e.length>4e3?e.length-4e3:0,o=e.slice(n),s=o.length;let i=null,r=0;for(;r<=s;){let l=o.indexOf(` +`,r);l===-1&&(l=s);let a=r;for(;a<l;){const u=o.charCodeAt(a);if(u===32||u===9)a++;else break}if(a<l){const u=o.charCodeAt(a);if(u===96||u===126){let c=a;for(;c<l&&o.charCodeAt(c)===u;)c++;const d=c-a;d>=3&&(i?i.marker===u&&d>=i.length&&(i=null):i={marker:u,length:d})}}if(l===s)break;r=l+1}return i!==null}peek(){return this.cache?.tokens??Fse}getStats(){return{...this.stats}}appendTokens(e,t,n=0,o=t.length){for(let s=n;s<o;s++)e.push(t[s])}updateCacheLineCount(e,t){e.lineCount=t??Wo(e.src),e.lastSegment=void 0,e.globalStateCarry=void 0}detectGlobalStateForAppend(e,t){if(e.globalStateReason)return e.globalStateReason;const n=(e.globalStateCarry??e.src.slice(-M9))+t,o=Ri(n);return e.globalStateCarry=n.length>M9?n.slice(n.length-M9):n,o&&(e.globalStateReason=o),o}ensureLastSegment(e){return e.lastSegment!==void 0||(e.lastSegment=this.getLastSegment(e.tokens,e.src)),e.lastSegment}getLastSegment(e,t,n=0,o=e.length,s,i){if(o<=n)return null;let r=Number.POSITIVE_INFINITY,l=-1,a=0;for(let u=o-1;u>=n;u--){const c=e[u];if(c.map&&(c.map[0]<r&&(r=c.map[0]),c.map[1]>l&&(l=c.map[1])),c.nesting<0){a+=-c.nesting;continue}if(c.nesting>0){if(a-=c.nesting,c.level===0&&a<=0){const d=Number.isFinite(r)?r:c.map?.[0]??0,f=l>=d?l:c.map?.[1]??d;return{tokenStart:u,tokenEnd:o,lineStart:d,lineEnd:f,srcOffset:this.getLineStartOffset(t,d,s,i)}}continue}if(c.level===0&&a===0){const d=Number.isFinite(r)?r:c.map?.[0]??0,f=l>=d?l:c.map?.[1]??d;return{tokenStart:u,tokenEnd:o,lineStart:d,lineEnd:f,srcOffset:this.getLineStartOffset(t,d,s,i)}}}return null}getLineStartOffset(e,t,n,o){if(n!==void 0&&o!==void 0&&t>=o)return this.getLineStartOffsetFrom(e,n,t-o);if(t<=0)return 0;let s=t,i=-1;for(;s>0;){if(i=e.indexOf(` +`,i+1),i===-1)return e.length;s--}return i+1}getLineStartOffsetFrom(e,t,n){if(n<=0)return t;let o=n,s=t-1;for(;o>0;){if(s=e.indexOf(` +`,s+1),s===-1)return e.length;o--}return s+1}mayContainReferenceDefinition(e){return e.includes("]:")?/(?:^|\n)[ \t]{0,3}\[[^\]\n]+\]:/.test(e):!1}canDirectlyParseAppend(e){if(!this.endsWithBlankLine(e.src))return!1;const t=this.ensureLastSegment(e);if(!t)return!1;switch(e.tokens[t.tokenStart]?.type){case"paragraph_open":case"heading_open":case"fence":case"code_block":case"html_block":case"hr":case"table_open":return!0;default:return!1}}tryContainerTailAppendMerge(e,t,n,o,s,i){if(!i||this.mayContainReferenceDefinition(i))return null;const r=t.tokens[s.tokenStart];switch(r?.type){case"bullet_list_open":case"ordered_list_open":return this.tryListTailAppendMerge(e,t,n,o,s,i,r);case"table_open":return this.tryTableTailAppendMerge(e,t,n,o,s,i,r);default:return null}}tryListTailAppendMerge(e,t,n,o,s,i,r){if(t.src.length===0||t.src.charCodeAt(t.src.length-1)!==10)return null;const l=s.lineEnd-s.lineStart,a=t.src.length-s.srcOffset;if(l<this.MIN_LIST_LINES_FOR_MERGE&&a<this.MIN_LIST_CHARS_FOR_MERGE)return null;const u=r.type==="bullet_list_open"?"bullet_list_close":"ordered_list_close";let c;try{c=this.core.parse(i,n,o).tokens}catch{return null}if(!this.isSingleTopLevelContainer(c,r.type,u,r.markup))return null;const d=c.slice(1,-1);if(d.length===0)return null;const f=t.lineCount??Wo(t.src);f>0&&this.shiftTokenLines(d,f);const h=this.getListParagraphMode(t.tokens,s.tokenStart,t.tokens.length,r.level),m=this.getListParagraphMode(c,0,c.length,0);(h==="loose"||m==="loose"||this.endsWithBlankLine(t.src)||(c[0]?.map?.[0]??0)>0)&&(this.setListParagraphVisibility(t.tokens,s.tokenStart,t.tokens.length,r.level,!1),this.setListParagraphVisibility(d,0,d.length,r.level,!1)),t.tokens.splice(t.tokens.length-1,0,...d),t.src=e,t.env=n,t.globalStateReason=null;const v=f+Wo(i);t.lineCount=v;const k=this.getDocLineCount(e,v);return r.map&&(r.map[1]=k),t.lastSegment={tokenStart:s.tokenStart,tokenEnd:t.tokens.length,lineStart:s.lineStart,lineEnd:k,srcOffset:s.srcOffset},t.tokens}tryTableTailAppendMerge(e,t,n,o,s,i,r){if(t.src.length===0||t.src.charCodeAt(t.src.length-1)!==10||/(?:^|\n)[ \t]*\n/.test(i))return null;const l=s.lineEnd-s.lineStart,a=t.src.length-s.srcOffset;if(l<this.MIN_TABLE_LINES_FOR_MERGE&&a<this.MIN_TABLE_CHARS_FOR_MERGE)return null;const u=this.getTableHeaderContext(t.src.slice(s.srcOffset));if(!u)return null;const c=`${u}${i}`;let d;try{d=this.core.parse(c,n,o).tokens}catch{return null}if(!this.isSingleTopLevelContainer(d,"table_open","table_close")||(d[0]?.map?.[1]??-1)!==this.getDocLineCount(c))return null;const f=this.getTableBodySection(d,0,d.length,0),h=this.getTableBodySection(t.tokens,s.tokenStart,t.tokens.length,r.level);if(!f||!h||f.tbodyOpenIndex<0||f.tbodyCloseIndex<0)return null;const m=h.tbodyOpenIndex>=0?d.slice(f.tbodyOpenIndex+1,f.tbodyCloseIndex):d.slice(f.tbodyOpenIndex,f.tbodyCloseIndex+1);if(m.length===0)return null;const v=s.lineEnd-2;v!==0&&this.shiftTokenLines(m,v);const k=h.tbodyCloseIndex>=0?h.tbodyCloseIndex:h.tableCloseIndex,w=t.lineCount??Wo(t.src);t.tokens.splice(k,0,...m),t.src=e,t.env=n,t.globalStateReason=null;const b=w+Wo(i);t.lineCount=b;const _=this.getDocLineCount(e,b);if(r.map&&(r.map[1]=_),h.tbodyOpenIndex>=0){const g=t.tokens[h.tbodyOpenIndex];g?.map&&(g.map[1]=_)}return t.lastSegment={tokenStart:s.tokenStart,tokenEnd:t.tokens.length,lineStart:s.lineStart,lineEnd:_,srcOffset:s.srcOffset},t.tokens}getTableHeaderContext(e){const t=e.indexOf(` +`);if(t<0)return null;const n=e.indexOf(` +`,t+1);return n<0?null:e.slice(0,n+1)}getTableBodySection(e,t,n,o){if(t<0||t>=n||e[t]?.type!=="table_open")return null;let s=-1;for(let l=n-1;l>t;l--){const a=e[l];if(a.type==="table_close"&&a.level===o){s=l;break}}if(s<0)return null;let i=-1,r=-1;for(let l=t+1;l<s;l++){const a=e[l];if(a.type==="tbody_open"&&a.level===o+1){i=l;break}}if(i>=0){for(let l=s-1;l>i;l--){const a=e[l];if(a.type==="tbody_close"&&a.level===o+1){r=l;break}}if(r<0)return null}return{tableCloseIndex:s,tbodyOpenIndex:i,tbodyCloseIndex:r}}isSingleTopLevelContainer(e,t,n,o){if(e.length<2)return!1;const s=e[0],i=e[e.length-1];if(s.type!==t||i.type!==n||s.level!==0||i.level!==0||o!==void 0&&s.markup!==o)return!1;let r=0;for(let l=0;l<e.length;l++){const a=e[l];if(a.level===0&&l>0&&l<e.length-1&&r===0)return!1;(a.nesting>0||a.nesting<0)&&(r+=a.nesting)}return r===0}getListParagraphMode(e,t,n,o){let s=!1,i=!1;const r=o+2;for(let l=t;l<n;l++){const a=e[l];if(!(a.type!=="paragraph_open"||a.level!==r)&&(a.hidden?s=!0:i=!0,s&&i))return"loose"}return i?"loose":s?"tight":"none"}setListParagraphVisibility(e,t,n,o,s){const i=o+2;for(let r=t;r<n;r++){const l=e[r];(l.type==="paragraph_open"||l.type==="paragraph_close")&&l.level===i&&(l.hidden=s)}}shouldPreferTailReparseForAppend(e){const t=this.ensureLastSegment(e);if(!t)return!1;switch(e.tokens[t.tokenStart]?.type){case"bullet_list_open":case"ordered_list_open":case"blockquote_open":case"table_open":return!0;case"paragraph_open":case"code_block":case"html_block":return!this.endsWithBlankLine(e.src);default:return!1}}endsWithBlankLine(e){const t=e.length;if(t<2||e.charCodeAt(t-1)!==10)return!1;let n=t-2;for(;n>=0;){const o=e.charCodeAt(n);if(o===32||o===9){n--;continue}return o===10}return!0}getDocLineCount(e,t=Wo(e)){return e.length===0?0:e.charCodeAt(e.length-1)===10?t:t+1}shiftTokenLines(e,t){if(t===0)return;let n=null;for(let o=0;o<e.length;o++){const s=e[o];if(s.map&&(s.map[0]+=t,s.map[1]+=t),s.children){n??=[];for(let i=s.children.length-1;i>=0;i--)n.push(s.children[i]);for(;n.length>0;){const i=n.pop();if(i.map&&(i.map[0]+=t,i.map[1]+=t),i.children)for(let r=i.children.length-1;r>=0;r--)n.push(i.children[r])}}}}};const XC={default:Ase,zero:Mse,commonmark:Sse};function Bse(e){return{core:e.core.ruler.version,block:e.block.ruler.version,inline:e.inline.ruler.version,inline2:e.inline.ruler2.version}}function Hse(e,t){return e.core.ruler.version!==t.core||e.block.ruler.version!==t.block||e.inline.ruler.version!==t.inline||e.inline.ruler2.version!==t.inline2}function JC(e){return e.experimental?{...e,...e.experimental}:e}function vr(e,t){if(!e)return!1;if(Object.prototype.hasOwnProperty.call(e,t)&&e[t]!==void 0)return!0;const n=e.experimental;return!!n&&Object.prototype.hasOwnProperty.call(n,t)&&n[t]!==void 0}function QC(e,t,n){for(let o=0;o<n.length;o++){const s=n[o];if(vr(t,s)||vr(e,s))return!0}return!1}function ew(e,t,n){return vr(t,n)||vr(e,n)}function tw(e,t){const n=Vl(e)?.chunk;if(n?.fallback){ss(e,{area:"parse",path:"plain",reason:`global-state:${n.fallbackReason||"unknown"}`});return}ss(e,{area:"parse",path:"full-chunk",chunked:!0,reason:t})}function id(){return typeof performance<"u"?performance.now():Date.now()}function zse(e,t){let n={html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:100,stream:!1,streamOptimizationMinSize:1e3,streamChunkedFallback:!1,streamChunkSizeChars:1e4,streamChunkSizeLines:200,streamChunkFenceAware:!0,streamChunkAdaptive:!0,streamChunkTargetChunks:8,streamChunkMaxChunks:void 0,streamLargeCachePolicy:"retain",streamSkipCacheAboveChars:1e6,streamSkipCacheAboveLines:1e5,fullChunkedFallback:!1,fullChunkThresholdChars:2e4,fullChunkThresholdLines:400,fullChunkSizeChars:1e4,fullChunkSizeLines:200,fullChunkFenceAware:!0,fullChunkAdaptive:!0,fullChunkTargetChunks:8,fullChunkMaxChunks:void 0,autoTuneChunks:!0,autoUnbounded:!0,autoUnboundedThresholdChars:4e6,autoUnboundedThresholdLines:8e4},o="default",s;!t&&typeof e!="string"?(s=e,o="default"):typeof e=="string"&&(o=e,s=t);const i=XC[o];if(!i)throw new Error(`Wrong \`markdown-it\` preset "${o}", check name`);if(i?.options&&(n={...n,...i.options}),s&&(n={...n,...s}),n=JC(n),typeof n.quotes=="string"){const A=n.quotes;A.length>=4?n.quotes=[A[0],A[1],A[2],A[3]]:n.quotes=["“","”","‘","’"]}let r=QC(i?.options,s,["fullChunkSizeChars","fullChunkSizeLines","fullChunkMaxChunks"]),l=QC(i?.options,s,["streamChunkSizeChars","streamChunkSizeLines","streamChunkMaxChunks"]),a=ew(i?.options,s,"fullChunkedFallback"),u=ew(i?.options,s,"streamChunkedFallback"),c=!1,d=null,f=null;const h=new Ioe;let m=null;const v=()=>(m||(m=new Nse(n)),m);let k=null;const w=()=>(k||(k=new Dse(h)),k);let b=null;const _=()=>(b||(b=new jE),b),g=A=>!c&&!!d&&!Hse(A,d),x=(A,E)=>o==="default"&&!c&&m===null&&f!==null&&A.parse===f&&g(A)&&!A.stream.enabled&&E<(A.options.autoUnboundedThresholdChars??4e6)&&A.options.html===!1&&A.options.xhtmlOut===!1&&A.options.breaks===!1&&A.options.langPrefix==="language-"&&A.options.linkify===!1&&A.options.typographer===!1&&A.options.highlight===null,S=(A,E)=>o==="default"&&!c&&g(A)&&!A.stream.enabled&&!A.options.fullChunkedFallback&&E<(A.options.autoUnboundedThresholdChars??4e6)&&A.options.html===!1&&A.options.linkify===!1&&A.options.typographer===!1,T={core:h,block:h.block,inline:h.inline,get linkify(){const A=_();return Object.defineProperty(this,"linkify",{value:A,writable:!0,configurable:!0}),A},get renderer(){const A=v();return Object.defineProperty(this,"renderer",{value:A,writable:!0,configurable:!0}),A},options:n,__explicitFullChunkConfig:r,__explicitStreamChunkConfig:l,__explicitFullChunkFallbackSetting:a,__explicitStreamChunkFallbackSetting:u,__canUseImplicitLargeInputStrategy(){return g(this)},set(A){const E=JC(A);return this.options={...this.options,...E},(vr(A,"fullChunkSizeChars")||vr(A,"fullChunkSizeLines")||vr(A,"fullChunkMaxChunks"))&&(r=!0,this.__explicitFullChunkConfig=!0),(vr(A,"streamChunkSizeChars")||vr(A,"streamChunkSizeLines")||vr(A,"streamChunkMaxChunks"))&&(l=!0,this.__explicitStreamChunkConfig=!0),vr(A,"fullChunkedFallback")&&(a=!0,this.__explicitFullChunkFallbackSetting=!0),vr(A,"streamChunkedFallback")&&(u=!0,this.__explicitStreamChunkFallbackSetting=!0),m&&m.set(E),typeof E.stream=="boolean"&&(this.stream.enabled=E.stream,k&&(k.reset(),k.resetStats())),this},configure(A){const E=typeof A=="string"?XC[A]:A;if(!E)throw new Error("Wrong `markdown-it` preset, can't be empty");if(E.options&&this.set(E.options),E.components){const P=E.components;P.core?.rules&&this.core.ruler.enableOnly(P.core.rules),P.block?.rules&&this.block.ruler.enableOnly(P.block.rules),P.inline?.rules&&this.inline.ruler.enableOnly(P.inline.rules),P.inline2?.rules&&this.inline.ruler2.enableOnly(P.inline2.rules)}return this},enable(A,E){const P=Array.isArray(A)?A:[A],D=[this.core?.ruler,this.block?.ruler,this.inline?.ruler,this.inline?.ruler2],I=new Set;for(const $ of D){if(!$)continue;const B=$.enable(P,!0);for(let H=0;H<B.length;H++)I.add(B[H])}if(!E){const $=P.filter(B=>!I.has(B));if($.length)throw new Error(`Rules manager: invalid rule name ${$.join(", ")}`)}return this},disable(A,E){const P=Array.isArray(A)?A:[A],D=[this.core?.ruler,this.block?.ruler,this.inline?.ruler,this.inline?.ruler2],I=new Set;for(const $ of D){if(!$)continue;const B=$.disable(P,!0);for(let H=0;H<B.length;H++)I.add(B[H])}if(!E){const $=P.filter(B=>!I.has(B));if($.length)throw new Error(`Rules manager: invalid rule name ${$.join(", ")}`)}return this},use(A,...E){const P=typeof A=="function"?A:A&&typeof A.default=="function"?A.default:void 0;if(!P)throw new TypeError("MarkdownIt.use: plugin must be a function");const D=[this,...E],I=A;return c=!0,P.apply(I,D),this},render(A,E){let P;if(x(this,A.length)){E!==void 0&&(vi(E),P=g9("render"));const $=P?id():0,B=P?WC(A,P):zC(A);if(P&&(P.attemptMs=id()-$,B===null&&(P.fallbackReason="unsupported-stock-subset"),tf(E,P)),B!==null)return E!==void 0&&ss(E,{area:"render",path:"stock-fast",reason:"stock-subset"}),B}const D=E??{},I=this.parse(A,D);return P&&tf(D,P),v().render(I,this.options,D)},async renderAsync(A,E){let P;if(x(this,A.length)){E!==void 0&&(vi(E),P=g9("render"));const $=P?id():0,B=P?WC(A,P):zC(A);if(P&&(P.attemptMs=id()-$,B===null&&(P.fallbackReason="unsupported-stock-subset"),tf(E,P)),B!==null)return E!==void 0&&ss(E,{area:"render",path:"stock-fast",reason:"stock-subset"}),B}const D=E??{},I=this.parse(A,D);return P&&tf(D,P),v().renderAsync(I,this.options,D)},renderIterable(A,E={}){const P=this.parseIterable(A,E);return v().render(P,this.options,E)},async renderAsyncIterable(A,E={}){const P=await this.parseAsyncIterable(A,E);return v().renderAsync(P,this.options,E)},renderInline(A,E={}){const P=this.parseInline(A,E);return v().render(P,this.options,E)},validateLink:bI,normalizeLink:CI,normalizeLinkText:wI,utils:rte,helpers:{...Zte},parse(A,E){if(typeof A!="string")throw new TypeError("Input data should be a String");if(E!==void 0&&vi(E),S(this,A.length)){const $=E===void 0?void 0:g9("parse"),B=$?id():0,H=Woe(A,$);if($&&($.attemptMs=id()-B,H===null&&($.fallbackReason="unsupported-stock-subset"),tf(E,$)),H!==null)return E!==void 0&&ss(E,{area:"parse",path:"stock-fast",reason:"stock-subset"}),H}const P=E??{};let D;if(!this.stream.enabled&&!this.options.fullChunkedFallback&&g(this)){const $=FI(this,A.length);if($==="yes"){const B=zf(this,A,P);return ss(E,{area:"parse",path:"auto-unbounded",unbounded:!0,reason:"char-threshold"}),B}$==="need-lines"&&(D=Wo(A))}if(!this.stream.enabled){const $=A.length,B=this.options.autoTuneChunks!==!1,H=r,O=!a&&g(this),F=!!this.options.fullChunkedFallback,U=O&&$>=2e5;let z;(F||U||D!==void 0)&&(z=D??Wo(A));const W=(F||U)&&B&&!H?xse($,z,this.options):null;if(F||U){const K=z??0;if(F?$>=(this.options.fullChunkThresholdChars??2e4)||K>=(this.options.fullChunkThresholdLines??400):U){if(W&&W.strategy!=="plain"){const V=Gm(this,A,P,{maxChunkChars:W.maxChunkChars,maxChunkLines:W.maxChunkLines,fenceAware:W.fenceAware,maxChunks:W.maxChunks});return E&&tw(E,F?"explicit-full-chunk":"default-large-string"),V}if(F){const V=(oe,ye,G)=>oe<ye?ye:oe>G?G:oe,ie=this.options.fullChunkAdaptive!==!1,ne=this.options.fullChunkTargetChunks??8,X=V(Math.ceil($/ne),8e3,64e3),le=V(Math.ceil(K/ne),150,700),Ie=ie?X:this.options.fullChunkSizeChars??1e4,de=ie?le:this.options.fullChunkSizeLines??200,pe=ie?V(Math.ceil($/64e3),ne,32):this.options.fullChunkMaxChunks,ve=Gm(this,A,P,{maxChunkChars:Ie,maxChunkLines:de,fenceAware:this.options.fullChunkFenceAware??!0,maxChunks:pe});return E&&tw(E,"explicit-full-chunk"),ve}}}if(D!==void 0&&g(this)&&NI(this,$,z??D)){const K=zf(this,A,P);return ss(E,{area:"parse",path:"auto-unbounded",unbounded:!0,reason:"line-threshold"}),K}}const I=Ri(A);return ss(E,{area:"parse",path:"plain",reason:"default-plain"}),Hd(P,I,()=>h.parse(A,P,this).tokens)},parseIterable(A,E={}){return vi(E),bse(this,A,E)},parseAsyncIterable(A,E={}){return vi(E),Cse(this,A,E)},parseIterableToSink(A,E,P={}){return vi(P),wse(this,A,E,P)},parseAsyncIterableToSink(A,E,P={}){return vi(P),_se(this,A,E,P)},parseInline(A,E={}){if(typeof A!="string")throw new TypeError("Input data should be a String");vi(E),Vp(E)&&la(E);const P=h.createState(A,E,this);return P.inlineMode=!0,h.process(P),P.tokens}};if(T.stream={enabled:!!n.stream,parse(A,E){return T.stream.enabled?w().parse(A,E,T):T.parse(A,E??{})},reset(){w().reset()},peek(){return k?k.peek():[]},stats(){return k?k.getStats():{total:0,cacheHits:0,appendHits:0,unboundedAppendHits:0,tailHits:0,fullParses:0,resets:0,chunkedParses:0,lastMode:"idle"}},resetStats(){k&&k.resetStats()}},i?.components){const A=i.components;A.core?.rules&&T.core.ruler.enableOnly(A.core.rules),A.block?.rules&&T.block.ruler.enableOnly(A.block.rules),A.inline?.rules&&T.inline.ruler.enableOnly(A.inline.rules),A.inline2?.rules&&T.inline.ruler2.enableOnly(A.inline2.rules)}return d=Bse(T),f=T.parse,T}var Wse=zse;const BI=["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],Use=["a","abbr","b","bdi","bdo","button","cite","code","data","del","dfn","em","font","i","ins","kbd","label","mark","q","s","samp","small","span","strong","sub","sup","time","u","var"],HI=["article","aside","blockquote","details","div","figcaption","figure","footer","header","h1","h2","h3","h4","h5","h6","li","main","nav","ol","p","pre","section","summary","table","tbody","td","th","thead","tr","ul"],jse=["svg","g","path"],Vse=["address","audio","body","canvas","caption","colgroup","datalist","dd","dialog","dl","dt","fieldset","form","head","hgroup","html","iframe","legend","map","menu","meter","noscript","object","optgroup","option","output","picture","progress","rp","rt","ruby","script","select","style","template","textarea","tfoot","title","video"],qse=["onclick","onerror","onload","onmouseover","onmouseout","onmousedown","onmouseup","onkeydown","onkeyup","onfocus","onblur","onsubmit","onreset","onchange","onselect","ondblclick","ontouchstart","ontouchend","ontouchmove","ontouchcancel","onwheel","onscroll","oncopy","oncut","onpaste","oninput","oninvalid","onsearch","innerhtml","outerhtml","textcontent","innertext","srcdoc","ping"],Kse=["action","data","href","src","srcset","poster","xlink:href","formaction"],Zse=["script"],Gse=["pre","iframe","picture","script","style","table","tbody","td","tfoot","th","thead","textarea","tr","title","video"],eu=new Set(BI),zI=new Set(HI),Sp=new Set([...BI,...Use,...HI,...jse]),WI=new Set([...Sp,...Vse]),Yse=new Set(qse),Xse=new Set(Kse),Zp=new Set(Zse),UI=new Set(Gse);function jI(e){let t="";for(const n of e){const o=n.charCodeAt(0);o<=31||o>=127&&o<=159||/\s/u.test(n)||(t+=n)}return t}const Jse={amp:"&",bsol:"\\",colon:":",newline:` +`,sol:"/",tab:" "};function VI(e){return e.replace(/&(?:#(\d+)|#x([0-9a-f]+)|([a-z][a-z0-9]+));?/gi,(t,n,o,s)=>{const i=n??o;if(i){const r=Number.parseInt(i,n?10:16);try{return Number.isFinite(r)?String.fromCodePoint(r):""}catch{return""}}return Jse[String(s??"").toLowerCase()]??t})}const ph=new Set(["http","https","mailto","tel"]),Qse=new Set(["javascript","vbscript","data","file","ftp","blob","filesystem","intent","chrome","chrome-extension","moz-extension","ms-browser-extension","view-source"]),Nu=new Set(["http","https"]);function qI(e){return e.match(/^([a-z][a-z0-9+.-]*):/i)?.[1]?.toLowerCase()??""}const eie=/^https?:\/\//i;function tie(e){if(!eie.test(e))return!1;for(const t of e){const n=t.charCodeAt(0);if(t==="&"||n<=32||n>=127&&n<=159||n>127&&/\s/u.test(t))return!1}return!0}function nie(e,t,n){if(!jf(t,n)||!e.startsWith("file:///"))return!1;const o=e.charAt(8);return o!=="/"&&o!=="\\"}function jf(e,t){return e?(e==="a"||e==="area")&&(!t||t==="href"||t==="xlink:href"):!t||t==="href"}function oie(e,t){return t==="href"||t==="xlink:href"?jf(e,t)?ph:Nu:t==="src"||t==="srcset"||t==="poster"||t==="action"||t==="formaction"||t==="data"?Nu:(jf(e,t),ph)}function lc(e,t={}){if(tie(e))return!1;const n=jI(VI(e)).toLowerCase(),o=String(t.tagName??"").toLowerCase(),s=String(t.attrName??"").toLowerCase();if(!n)return!1;if(n.startsWith("data:")){const r=/^data:image\/(?:png|gif|jpe?g|webp|avif|bmp);/i.test(n);return o==="img"&&s==="src"?!r:!0}if(/^[\\/]{2}/.test(n))return!0;if(n.startsWith("/")||n.startsWith("./")||n.startsWith("../")||n.startsWith("#")||n.startsWith("?"))return!1;const i=qI(n);return i?i==="file"?!nie(n,o,s):jf(o,s)?Qse.has(i):!oie(o,s).has(i):!1}function sie(e){const t=VI(String(e??"")).trim();if(!t||t.startsWith("#")||t.startsWith("/")||t.startsWith("./")||t.startsWith("../")||t.startsWith("?"))return!1;const n=qI(jI(t).toLowerCase());return n==="http"||n==="https"}function iie(e,t={}){const n=String(e??"").trim();return n?lc(n,t)?"":n:""}function nw(e){return iie(e,{tagName:"img",attrName:"src"})}function rie(e,t,n){function o(f){return f.trim().split(" ",2)[0]===t}function s(f,h,m,v,k){return f[h].nesting===1&&f[h].attrJoin("class",t),k.renderToken(f,h,m,v,k)}n=n||{};const i=3,r=n.marker||":",l=r.charCodeAt(0),a=r.length,u=n.validate||o,c=n.render||s;function d(f,h,m,v){let k,w=!1,b=f.bMarks[h]+f.tShift[h],_=f.eMarks[h];if(l!==f.src.charCodeAt(b))return!1;for(k=b+1;k<=_&&r[(k-b)%a]===f.src[k];k++);const g=Math.floor((k-b)/a);if(g<i)return!1;k-=(k-b)%a;const x=f.src.slice(b,k),S=f.src.slice(k,_);if(!u(S,x))return!1;if(v)return!0;let T=h;for(;T++,!(T>=m||(b=f.bMarks[T]+f.tShift[T],_=f.eMarks[T],b<_&&f.sCount[T]<f.blkIndent));)if(l===f.src.charCodeAt(b)&&!(f.sCount[T]-f.blkIndent>=4)){for(k=b+1;k<=_&&r[(k-b)%a]===f.src[k];k++);if(!(Math.floor((k-b)/a)<g)&&(k-=(k-b)%a,k=f.skipSpaces(k),!(k<_))){w=!0;break}}const A=f.parentType,E=f.lineMax;f.parentType="container",f.lineMax=T;const P=f.push("container_"+t+"_open","div",1);P.markup=x,P.block=!0,P.info=S,P.map=[h,T],f.md.block.tokenize(f,h+1,T);const D=f.push("container_"+t+"_close","div",-1);return D.markup=f.src.slice(b,k),D.block=!0,f.parentType=A,f.lineMax=E,f.line=T+(w?1:0),!0}e.block.ruler.before("fence","container_"+t,d,{alt:["paragraph","reference","blockquote","list"]}),e.renderer.rules["container_"+t+"_open"]=c,e.renderer.rules["container_"+t+"_close"]=c}function lie(e){const t=String(e??"").trim();if(!t.startsWith("{")||!t.endsWith("}"))return null;const n=t.slice(1,-1).trim();if(!n)return{};if(n.includes("{")||n.includes("[")||n.includes("]"))return null;const o=[];let s="",i=!1,r=!1;for(let a=0;a<n.length;a++){const u=n[a];if(u==="\\"){s+=u,a+1<n.length&&(s+=n[a+1],a++);continue}if(!r&&u==="'"){i=!i,s+=u;continue}if(!i&&u==='"'){r=!r,s+=u;continue}if(!i&&!r&&u===","){o.push(s.trim()),s="";continue}s+=u}s.trim()&&o.push(s.trim());const l={};for(const a of o){if(!a)continue;let u=!1,c=!1,d=-1;for(let k=0;k<a.length;k++){const w=a[k];if(w==="\\"){k++;continue}if(!c&&w==="'"){u=!u;continue}if(!u&&w==='"'){c=!c;continue}if(!u&&!c&&w===":"){d=k;break}}if(d===-1)return null;const f=a.slice(0,d).trim(),h=a.slice(d+1).trim();if(!f)return null;let m=f;if(m.startsWith('"')&&m.endsWith('"')||m.startsWith("'")&&m.endsWith("'"))try{m=JSON.parse(m.replace(/^'/,'"').replace(/'$/,'"'))}catch{return null}if(!/^[_$A-Z][\w$-]*$/i.test(m))return null;let v;if(!h)v="";else if(h.startsWith('"')&&h.endsWith('"')||h.startsWith("'")&&h.endsWith("'"))try{v=JSON.parse(h.replace(/^'/,'"').replace(/'$/,'"'))}catch{v=h}else/^-?\d+(?:\.\d+)?$/.test(h)?v=Number(h):h==="true"||h==="false"?v=h==="true":h==="null"?v=null:v=h;l[m]=v}return l}function KI(e,t,n){for(const o of e){const s=o,i=s.map;if(Array.isArray(i)&&i.length>=2){const r=Number(i[0]),l=Number(i[1]);Number.isFinite(r)&&Number.isFinite(l)&&(s.map=[r+t,Math.min(l+t,n)])}Array.isArray(s.children)&&KI(s.children,t,n)}}function aie(e){["admonition","info","warning","error","tip","danger","note","caution"].forEach(t=>{e.use(rie,t,{render(n,o){return n[o].nesting===1?`<div class="vmr-container vmr-container-${t}">`:`</div> +`}})}),e.block.ruler.before("fence","vmr_container_fallback",(t,n,o,s)=>{const i=t,r=i.bMarks[n]+i.tShift[n],l=i.eMarks[n],a=i.src.slice(r,l),u=a.match(/^:::\s*([^\s{]+)/);if(!u)return!1;const c=u[1];if(!c.trim())return!1;const d=a.slice(u[0].length).trim();let f,h;const m=d.indexOf("{"),v=m>=0?d.slice(m).trimStart():void 0;if(m===-1)f=d||void 0;else{if(f=d.slice(0,m).trim()||void 0,v?.startsWith("{")){let S=0,T=-1;for(let A=0;A<v.length;A++)if(v[A]==="{"?S++:v[A]==="}"&&S--,S===0){T=A+1;break}T>0&&(h=v.slice(0,T))}h||(f=d||void 0)}if(s)return!0;const k=!!i.env.__markstreamFinal;let w=n+1,b=!1;for(;w<=o;){const S=i.bMarks[w]+i.tShift[w],T=i.eMarks[w];if(i.src.slice(S,T).trim()===":::"){b=!0;break}w++}b||(w=o);const _=i.push("vmr_container_open","div",1);if(_.attrSet("class",`vmr-container vmr-container-${c}`),_.map=[n,b?w:o],_.meta={..._.meta??{},unclosed:!b&&!k},f&&_.attrSet("data-args",f),h)try{const S=JSON.parse(h);for(const[T,A]of Object.entries(S)){const E=A!=null&&typeof A=="object";_.attrSet(`data-${T}`,E?JSON.stringify(A):String(A))}}catch{const S=lie(h);if(S)for(const[T,A]of Object.entries(S)){const E=A!=null&&typeof A=="object";_.attrSet(`data-${T}`,E?JSON.stringify(A):String(A))}else _.attrSet("data-attrs",h)}const g=[];for(let S=n+1;S<w;S++){const T=i.bMarks[S]+i.tShift[S],A=i.eMarks[S];g.push(i.src.slice(T,A))}if(g.some(S=>S.trim().length>0)){let S=g.join(` +`);S.endsWith(` +`)||(S+=` +`),S.endsWith(` + +`)||(S+=` +`);const T=i.tokens[i.tokens.length-1];T&&(T.raw=S);const A=[];i.md.block.parse(S,i.md,i.env,A),KI(A,n+1,n+1+g.length),i.tokens.push(...A)}const x=i.push("vmr_container_close","div",-1);return b||(x.hidden=!0,x.map=[o,o]),i.line=b?w+1:w,!0},{alt:["paragraph","reference","blockquote","list"]})}function Gr(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Vo(e){let t=!1,n=!1;for(let o=0;o<e.length;o++){const s=e[o];if(s==="\\"){o++;continue}if(!n&&s==="'"){t=!t;continue}if(!t&&s==='"'){n=!n;continue}if(!t&&!n&&s===">")return o}return-1}function w2(e){const t=[],n=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let o;for(;(o=n.exec(e))!==null;){const s=o[1];if(!s)continue;const i=o[2]||o[3]||o[4]||"";t.push([s,i])}return t}const uie=/^[a-z][a-z0-9_-]*$/;function ow(e){return uie.test(String(e??"").trim().toLowerCase())}function Sr(e){const t=String(e??"").trim();if(!t)return"";if(!t.startsWith("<"))return ow(t)?t.toLowerCase():"";let n=1;for(;n<t.length&&/\s/.test(t[n]);)n++;if(t[n]==="/")for(n++;n<t.length&&/\s/.test(t[n]);)n++;const o=n;for(;n<t.length&&/[\w-]/.test(t[n]);)n++;const s=t.slice(o,n).toLowerCase(),i=t[n]??"";return i&&!/[\s/>]/.test(i)?"":ow(s)?s:""}function Ec(e){if(!e||e.length===0)return[];const t=new Set,n=[];for(const o of e){const s=Sr(o);!s||t.has(s)||(t.add(s),n.push(s))}return n}function cie(...e){const t=new Set,n=[];for(const o of e)for(const s of Ec(o))t.has(s)||(t.add(s),n.push(s));return n}function die(e){const t=Ec(e);return{key:t.join(","),tags:t}}function ZI(e){return Sr(e)}function fie(e,t){const n=String(e??""),o=Sr(t);if(!o)return!1;const s=Gr(o),i=n.match(new RegExp(String.raw`^\s*<\s*${s}(?:\s[^>]*)?(\s*\/)?>`,"i"));return i?i[1]?!0:new RegExp(String.raw`<\s*\/\s*${s}\s*>`,"i").test(n):!1}function GI(e,t){const n=Sr(t);return!!n&&!Sp.has(n)&&!fie(e,n)}function pie(e,t){const n=String(e??""),o=Sr(t);if(!o)return n;const s=Gr(o),i=new RegExp(String.raw`^\s*<\s*${s}(?:\s[^>]*)?>\s*`,"i"),r=new RegExp(String.raw`\s*<\s*\/\s*${s}\s*>\s*$`,"i");return n.replace(i,"").replace(r,"")}const YI=eu,hie=Sp,XI=new Set(zI);XI.delete("details");const mie=/<([A-Z][\w-]*)(?=[\s/>]|$)/gi,gie=/<\/\s*([A-Z][\w-]*)(?=[\s/>]|$)/gi,H3=/^<\s*(?:\/\s*)?([A-Z][\w-]*)/i,vie=/^<\s*([A-Z][\w:-]*)(?=[\s/>]|$)/i;function Xm(e){return(e.match(H3)?.[1]??"").toLowerCase()}function Gy(e){return/^\s*<\s*\//.test(e)}function Yy(e,t){return YI.has(t)||/\/\s*>\s*$/.test(e)}function yie(e,t){let n=0;for(let o=0;o<e.length;o++){const s=e[o];if(!s||s.type!=="html_inline")continue;const i=String(s.content??""),r=Xm(i);if(r===t){if(Gy(i)){if(n===0)return o;n--;continue}Yy(i,r)||n++}}return-1}function kie(e,t){let n=0;for(const o of e){if(!o||o.type!=="html_inline")continue;const s=String(o.content??""),i=Xm(s);if(i===t){if(Gy(s)){n>0&&n--;continue}Yy(s,i)||n++}}return n}function sw(e,t,n=0){const o=new RegExp(String.raw`<\s*(\/?)\s*${Gr(t)}(?=[\s>/])[^>]*>`,"gi");o.lastIndex=Math.max(0,n);let s=0,i;for(;(i=o.exec(e))!==null;){const r=i[0]??"",l=!!i[1],a=!l&&/\/\s*>$/.test(r);if(l){if(s===0)return{start:i.index,end:i.index+r.length};s--;continue}a||s++}return null}function bie(e,t){const n=new RegExp(String.raw`<\s*(\/?)\s*${Gr(t)}(?=[\s>/])[^>]*>`,"gi");let o=0,s;for(;(s=n.exec(e))!==null;){const i=s[0]??"",r=!!s[1],l=!r&&/\/\s*>$/.test(i);if(r){o>0&&o--;continue}l||o++}return o}function Jm(e){const t=e;return String(t.raw??t.content??t.markup??"")}function Cie(e){const t=e;return t.meta||(t.meta={}),t.meta}function T9(e,t,n){const o=Cie(e);o.markstreamCustomHtmlRaw=t,o.markstreamCustomHtmlInner=n}function wie(e,t){if(!t.size)return;const n=Array.from(t,h=>new RegExp(String.raw`<\s*${Gr(h)}(?=[\s>/])`,"i")),o=[];let s=!1;const i=h=>h?n.some(m=>m.test(h)):!1,r=h=>{if(!(!h||!o.length))for(const m of o)m.raw+=h,m.inner+=h},l=()=>{!o.length||!s||(r(` +`),s=!1)},a=h=>{r(h)},u=h=>{for(let v=0;v<o.length;v++)o[v].raw+=h,v<o.length-1&&(o[v].inner+=h);const m=o.pop();T9(m.token,m.raw,m.inner)},c=h=>{const m=o[o.length-1]?.tag;if(!m)return null;const v=new RegExp(String.raw`^\s*<\s*\/\s*${Gr(m)}\s*>`,"i");return h.match(v)?.[0]??null},d=h=>!!c(h),f=(h,m,v)=>{const k=v??(h.type==="html_inline"?Xm(m):"");if(!(k&&t.has(k))){r(m);return}const w=Gy(m),b=!w&&Yy(m,k);if(w){if(!o.length||o[o.length-1].tag!==k){r(m);return}u(m);return}if(r(m),b){T9(h,m,"");return}o.push({tag:k,token:h,raw:m,inner:""})};for(const h of e){if(h.type==="inline"&&Array.isArray(h.children)){const m=String(h.content??"");if(d(m)?s=!1:l(),!o.length&&!i(m)){s=!1;continue}let v=0,k=!0;for(const w of h.children){const b=Jm(w),_=w.type==="html_inline"?Xm(b):"",g=_&&t.has(_);let x=b;if(k&&m&&b&&(o.length||g)){const S=m.indexOf(b,v);if(S!==-1)a(m.slice(v,S)),x=m.slice(S,S+b.length),v=S+b.length;else{if(o.length&&!g)continue;k=!1}}f(w,x,_)}k&&m&&v<m.length&&o.length&&a(m.slice(v)),s=o.length>0;continue}if(o.length&&typeof h.content=="string"){const m=Jm(h),v=h.type==="html_block"?c(m):null;if(v){u(`${s?` +`:""}${v}`),s=o.length>0;continue}if(!h.content)continue;l(),r(h.content),s=!0}}for(const h of o)T9(h.token,h.raw,h.inner)}function _ie(e){return/^\s*<\s*[!?]/.test(e)}function xie(e){const t=new Set(hie);if(e&&Array.isArray(e))for(const n of e){const o=String(n??"").trim();if(!o)continue;const s=o.match(/^[<\s/]*([A-Z][\w-]*)/i);s&&t.add(s[1].toLowerCase())}return t}function iw(e,t){if(t.has(e))return!0;for(const n of t)if(n.startsWith(e))return!0;return!1}function Sie(e,t){let n=null;for(const i of e.matchAll(mie)){const r=i.index??-1;if(r<0)continue;const l=(i[1]??"").toLowerCase();iw(l,t)&&Vo(e.slice(r))===-1&&(!n||r<n.index)&&(n={index:r,tag:l,closing:!1})}for(const i of e.matchAll(gie)){const r=i.index??-1;if(r<0)continue;const l=(i[1]??"").toLowerCase();iw(l,t)&&Vo(e.slice(r))===-1&&(!n||r<n.index)&&(n={index:r,tag:l,closing:!0})}const o=/<\/\s*$/.exec(e);if(o&&typeof o.index=="number"){const i=o.index;!e.slice(i).includes(">")&&(!n||i<n.index)&&(n={index:i,tag:"",closing:!0})}const s=/<\s*$/.exec(e);if(s&&typeof s.index=="number"){const i=s.index,r=e.slice(i);!r.startsWith("</")&&!r.includes(">")&&(!n||i<n.index)&&(n={index:i,tag:"",closing:!1})}return n}function Aie(e,t){const n=e;return Object.assign(Object.create(Object.getPrototypeOf(n)),n,{type:"text",content:t,raw:t})}function Mie(e,t){if(!e.length)return{children:e};const n=[];let o=null,s=null;function i(a,u){a&&(u?n.push(Aie(u,a)):n.push({type:"text",content:a,raw:a}))}function r(a,u){let c=0;for(;c<a.length;){const d=a.indexOf("<",c);if(d===-1){i(a.slice(c),u);break}i(a.slice(c,d),u);const f=a.slice(d),h=f.match(H3);if(!h){i("<",u),c=d+1;continue}const m=Vo(f);if(m===-1){i("<",u),c=d+1;continue}const v=f.slice(0,m+1),k=(h[1]??"").toLowerCase();t.has(k)?n.push({type:"html_inline",tag:"",content:v,raw:v}):i(v,u),c=d+v.length}}function l(a,u){if(!a)return;const c=Sie(a,t);if(!c){r(a,u);return}const d=a.slice(0,c.index);d&&r(d,u),o={tag:c.tag,buffer:a.slice(c.index),closing:c.closing},s=o.buffer}for(const a of e){if(o){o.buffer+=Jm(a),s=o.buffer;const u=Vo(o.buffer);if(u===-1)continue;const c=o.buffer.slice(0,u+1),d=o.buffer.slice(u+1);n.push({type:"html_inline",tag:"",content:c,raw:c}),o=null,s=null,d&&l(d);continue}if(a.type==="html_inline"){const u=Jm(a),c=(u.match(H3)?.[1]??"").toLowerCase();if(c&&t.has(c)&&Vo(u)===-1){o={tag:c,buffer:u,closing:/^<\s*\//.test(u)},s=o.buffer;continue}}if(a.type==="text"){const u=String(a.content??"");if(!u.includes("<")){n.push(a);continue}l(u,a);continue}n.push(a)}return{children:n,pendingBuffer:s??void 0}}const Tie=["a","span","strong","em","b","i","u"];function Eie(e,t={}){const n=new Set;if(t.customHtmlTags?.length)for(const f of t.customHtmlTags){const h=Sr(f);h&&n.add(h)}const o=f=>{const h=f,m=new Set(n),v=Array.isArray(h.env?.__markstreamCustomHtmlTags)?h.env.__markstreamCustomHtmlTags:[];for(const _ of v){const g=Sr(String(_??""));g&&m.add(g)}const k=xie(Array.from(m)),w=new Set(Tie);for(const _ of m)w.add(_);return{autoCloseInlineTagSet:w,commonHtmlTags:k,customTagSet:m,shouldMergeHtmlBlockTag:_=>m.has(_)||!k.has(_)||XI.has(_)}},s=f=>{if(f.type==="html_block")return String(f.content??"");if(f.type!=="inline"||!Array.isArray(f.children)||f.children.length!==1)return"";const h=f.children[0];return h?.type!=="html_block"?"":String(f.content??h.content??"")},i=(f,h)=>{f.type="html_block",f.content=h,f.raw=h,f.children=[]},r=f=>f.replace(/^(?:\r?\n)+/,""),l=f=>/^(?: {4}|\t)/.test(f),a=f=>f.replace(/^(?: {4}|\t)/gm,""),u=(f,h)=>{const m=r(f);if(!/\S/.test(m))return[];if(l(m))return[{type:"code_block",content:a(m),raw:m}];const v=m.replace(/^[\t ]+/,"");if(!v)return[];if(v.startsWith("<"))return[{type:"html_block",content:v}];const k={type:"inline",tag:"",nesting:0,content:v,children:[{type:"text",content:v,raw:v}]};return h==="paragraph"?[{type:"paragraph_open",tag:"p",nesting:1},k,{type:"paragraph_close",tag:"p",nesting:-1}]:h==="text"?[{type:"text",content:v,raw:v}]:[k]},c=(f,h,m)=>f[h-1]?.type==="paragraph_open"&&f[h+1]?.type==="paragraph_close"?"inline":m,d=(f,h)=>{const m=r(h);return!/\S/.test(m)||f.type!=="inline"||!Array.isArray(f.children)?!1:(f.content=`${String(f.content??"")}${m}`,f.children.push({type:"text",content:m,raw:m}),!0)};e.core.ruler.after("inline","fix_html_inline_streaming",f=>{const h=f.tokens??[],{commonHtmlTags:m,customTagSet:v}=o(f);for(const k of h){const w=k;if(w.type!=="inline"||!Array.isArray(w.children))continue;const b=String(w.content??""),_=w.children.length?w.children:b.includes("<")?[{type:"text",content:b,raw:b}]:null;if(_)try{const g=Mie(_,m);if(w.children=g.children,g.pendingBuffer){const x=b.lastIndexOf(g.pendingBuffer);if(x!==-1){const S=b.slice(0,x);w.content=S,typeof w.raw=="string"&&(w.raw=S)}}}catch(g){console.error("[applyFixHtmlInlineTokens] failed to fix streaming html inline",g)}}wie(h,v)}),e.core.ruler.push("fix_html_inline_tokens",f=>{const h=f.tokens??[],{autoCloseInlineTagSet:m,customTagSet:v,shouldMergeHtmlBlockTag:k}=o(f),w=[];for(let b=0;b<h.length;b++){const _=h[b];if(w.length>0){const[x,S]=w[w.length-1];if(b!==S){if(_.type==="paragraph_open"||_.type==="paragraph_close"){h.splice(b,1),b--;continue}const T=String(_.content??_.raw??"");if(T){const A=h[S],E=`${String(A.content||"")} +${T}`,P=Vo(E),D=P===-1?null:sw(E,x,P+1);if(D){const I=E.slice(0,D.end),$=E.slice(D.end);A.content=I,A.loading=!1,h.splice(b,1),w.pop();const B=d(A,$)?[]:u($,c(h,b,"paragraph"));B.length&&h.splice(b,0,...B),b--;continue}A.content=E,A.loading!==!1&&(A.loading=!0)}h.splice(b,1),b--;continue}}const g=s(_);if(g){if(_ie(g))continue;const x=(g.match(/<\s*(?:\/\s*)?([^\s>/]+)/)?.[1]??"").toLowerCase(),S=/^\s*<\s*\//.test(g);if(!x||!k(x))continue;if(i(_,g),!S)x&&!new RegExp(`^\\s*<\\s*${x}\\b[^>]*\\/\\s*>`,"i").test(g)&&bie(g,x)>0&&w.push([x,b]);else if(w.length>0&&x&&w[w.length-1][0]===x){const[,T]=w[w.length-1],A=h[T];A.content=`${String(A.content||"")} +${g}`,A.loading=!1,w.pop(),h.splice(b,1),b--}continue}else if(w.length>0){if(_.type==="paragraph_open"||_.type==="paragraph_close"){h.splice(b,1),b--;continue}const x=_.content||"",S=new RegExp(`<\\s*\\/\\s*${w[w.length-1][0]}\\s*>`,"i").test(x);if(x){const[,T]=w[w.length-1],A=h[T];A.content=`${A.content||""} +${x}`,A.loading!==!1&&(A.loading=!S)}S&&w.pop(),h.splice(b,1),b--}else continue}if(v.size>0){const b=new Map,_=new Map,g=T=>{let A=b.get(T);return A||(A=new RegExp(`<\\s*${T}\\b`,"i"),b.set(T,A)),A},x=T=>{let A=_.get(T);return A||(A=new RegExp(`<\\s*\\/\\s*${T}\\s*>`,"i"),_.set(T,A)),A},S=[];for(let T=0;T<h.length;T++){const A=h[T],E=String(A.content??"");if(S.length>0){const D=S[S.length-1],I=h[D.index],$=A.type==="html_block"?x(D.tag).exec(E):null;if($){const O=$.index+$[0].length,F=E.slice(0,O),U=E.slice(O);I.content=`${String(I.content??"")} +${F}`,Array.isArray(I.children)&&I.children.push({type:"html_inline",content:`</${D.tag}>`,raw:`</${D.tag}>`}),S.pop();const z=d(I,U)?[]:u(U,c(h,T,"paragraph"));z.length?h.splice(T,1,...z):(h.splice(T,1),T--);continue}if(A.type!=="inline")continue;const B=Array.isArray(A.children)?A.children:[],H=yie(B,D.tag);if(H!==-1){const O=B.slice(0,H+1),F=B.slice(H+1),U=O.map(z=>String(z?.content??z?.raw??"")).join("");if(I.content=`${String(I.content??"")} +${U}`,Array.isArray(I.children)&&I.children.push(...O),F.length){const z=F.map(W=>String(W.content??W.raw??"")).join("");if(z.trim()){const W=z.replace(/^\s+/,"");if(d(I,z))h.splice(T,1),T--;else if(W.startsWith("<"))h.splice(T,1,{type:"html_block",content:W});else{const K=u(z,c(h,T,"paragraph"));h.splice(T,1,...K)}}else h.splice(T,1),T--}else h.splice(T,1),T--;S.pop();continue}I.content=`${String(I.content??"")} +${E}`,Array.isArray(I.children)&&I.children.push(...B),h.splice(T,1),T--;continue}if(A.type!=="inline")continue;const P=Array.isArray(A.children)?A.children:[];for(const D of v)if((P.length?kie(P,D):g(D).test(E)&&!x(D).test(E)?1:0)>0){S.push({tag:D,index:T});break}}}{let b=0;for(let _=0;_<h.length;_++){const g=h[_];if(g.type==="paragraph_open"){b++;continue}g.type==="paragraph_close"&&(b>0?b--:(h.splice(_,1),_--))}}for(let b=0;b<h.length;b++){const _=h[b];if(_.type==="html_block"){const A=(_.content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase();if(A.startsWith("!")||A.startsWith("?")){_.loading=!1;continue}if(v.has(A)){const H=String(_.content??""),O=Vo(H),F=O===-1?null:sw(H,A,O+1);_.loading=F?!1:_.loading!==void 0?_.loading:!0;const U=F?.start??-1,z=F?F.end-F.start:0;if(U!==-1){const W=H.slice(0,U+z);let K="";O!==-1&&O<U&&(K=H.slice(O+1,U)),_.children=[{type:A,content:K,raw:W,attrs:[],tag:A,loading:!1}],_.content=W,_.raw=W;const V=u(H.slice(U+z)||"","text");V.length&&h.splice(b+1,0,...V)}else _.children=[{type:A,content:"",raw:H,attrs:[],tag:A,loading:!0}];continue}if(["br","hr","img","input","link","meta","div","p","ul","li"].includes(A))continue;_.type="inline";const E=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let P;for(;(P=E.exec(_.content||""))!==null;)P[1],P[2]||P[3]||P[4];const D=String(_.content??""),I=new RegExp(`<\\/\\s*${A}\\s*>`,"i").exec(D),$=I?I.index:-1,B=I?I[0].length:0;if($!==-1){const H=D.slice(0,$+B),O=(D.slice($+B)||"").replace(/^\s+/,"");_.children=[{type:"html_block",content:H,tag:A,loading:!1}],_.content=H,_.raw=H,O&&h.splice(b+1,0,O.startsWith("<")?{type:"html_block",content:O}:{type:"text",content:O,raw:O})}else _.children=[{type:"html_block",content:_.content,tag:A,loading:!0}];continue}if(!_||_.type!=="inline")continue;if(_.children.length===2&&_.children[0].type==="html_inline"){const A=(_.children[0].content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase(),E=_.children[1],P=String(E?.content??"").match(/^<\s*\/\s*([^\s>]+)/)?.[1]?.toLowerCase()??"";if(E?.type==="html_inline"&&P===A)continue;m.has(A)?(_.children[0].loading=!0,_.children[0].tag=A,_.children.push({type:"html_inline",tag:A,loading:!0,content:`</${A}>`})):_.children=[{type:"html_block",loading:!0,tag:A,content:String(_.children[0]?.content??"")+String(_.children[1]?.content??"")}];continue}else if(_.children.length===3&&_.children[0].type==="html_inline"&&_.children[2].type==="html_inline"){const A=(_.children[0].content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase();if(m.has(A))continue;_.children=[{type:"html_block",loading:!1,tag:A,content:_.children.map(E=>E.content).join("")}];continue}if(!_.content?.startsWith("<")||_.children?.length!==1)continue;const g=String(_.content),x=_,S=x.children[0];if(S?.type!=="html_inline"){/^<\s*(?:\/\s*)?[A-Z][\w:-]*\s*$/i.test(g)&&(x.children.length=0);continue}const T=String(S.content??g).match(vie)?.[1]?.toLowerCase()??"";if(T){if(/\/\s*>\s*$/.test(g)||YI.has(T)){x.children=[{type:"html_inline",content:g}];continue}x.children.length=0}}})}function Iie(e){const t=e.trim();return!t||/^&[a-z0-9#]+;/i.test(t)?!1:!!(/^(?:const|let|var|function|class|import|export|if|for|while|return|await|async|yield|try|catch|throw|new|typeof|instanceof|switch|case|break|continue|def|ruby|perl|print|echo|true|false|null|undefined|NaN|Infinity|this)\b/.test(t)||/[a-z_$][\w$]*(?:\.[a-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[\d+\])*\s*\(/i.test(t)||/[a-z_$][\w$]*(?:\.[a-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[[\d+\]])+/i.test(t)||/\w+\s*(?:===?|!==?|<=?|>=?|\+\+|--|&&|\|\||\?\.)/.test(t)||/^(?:!!|\+\+|--)\s*\w/.test(t)||/[\w$]+\s*(?:\+=|-=|\*=|\/=|%=|\*\*=|=)/.test(t)||/^(?:https?:\/\/|ftp:\/\/|file:\/\/|\/\/|www\.)/i.test(t)||/`[^`]*\$\{[^}]*\}[^`]*`/.test(t)||/<\/?[A-Z][a-zA-Z0-9]*/.test(t)||/<[a-z][a-z0-9]*\s[^>]+>/.test(t)||/^(["'`]).*\1\s*[;,]?$/.test(t)||/^\[[\s\S]*\]$/.test(t)||/^\{[\s\S]*\}$/.test(t)||/^\(\s*\)$/.test(t)||/[\w$]+(?:\s*[+\-*/%<>=!&|^~:]+\s*[\w$]+|\s*\.\s*[\w$]+)/.test(t)||/=>|->|::/.test(t)||/^@[\w.$]+$/.test(t)||/^(?:0x[0-9a-fA-F]+|0b[01]+|0o[0-7]+|\d+(?:\.\d*)?(?:px|em|rem|%|vh|vw|deg|s|ms)?)$/.test(t)||/^\$[\w$]+\s*[=:]/.test(t)||/\|\s*\w+|\w+\s*\|/.test(t)||/^(?:git|npm|yarn|pnpm|bun|pip|cargo|go|rust|python|node|java|mvn|gradle|docker|kubectl)\s+/.test(t)||/(?:console|window|document|Math|JSON|Date|Array|Object|String|Number|Boolean)\.[a-zA-Z]/.test(t)||/^(?:\/\/|#|\/\*|\*\/|<!--|-->)/.test(t)||/^(?:<<<|<<\s*['"]?\w+['"]?)/.test(t))}function Lie(e,t={}){t.enabled!==!1&&e.core.ruler.after("inline","fix_indented_code_block",n=>{const o=n.tokens??[];for(let s=0;s<o.length;s++){const i=o[s];if(i.type!=="code_block")continue;const r=String(i.content??"").trim();if(!r)continue;const l=r.split(/\r?\n/).filter(a=>a.trim().length>0);if(l.length===1&&!Iie(l[0]??"")){const a=l[0]??"",u=i.level??0;o.splice(s,1,{type:"paragraph_open",tag:"p",nesting:1,level:u},{type:"inline",tag:"",nesting:0,level:u,content:a,children:[{type:"text",content:a,level:u+1,raw:a}],block:!0},{type:"paragraph_close",tag:"p",nesting:-1,level:u}),s+=2}}})}const JI=/\.([a-z0-9]{1,15})$/i,$ie=/[_()[\]{}<>]/u,Nie=/^(?:https?:\/\/|ftp:\/\/|mailto:|www\.)/i,Fie=/[?#@]/u,Rie=/[\\/]/u,Oie=/^[\p{L}\p{N}./\\-]+$/u,Pie=/^[A-Za-z0-9-]{1,63}$/u,Die=/^xn--[a-z0-9-]{2,59}$/i,Bie=/^(?:[A-Z]{1,6}|\d{1,8})$/u,Hie=/^(?=.{1,12}$)[A-Z0-9]+(?:[-.][A-Z0-9]+)*$/iu,zie=/文件名\s*[::]?|附件\s*[::]?|路径\s*[::]?|路徑\s*[::]?|文件列表\s*[::]?|文档列表\s*[::]?|文檔列表\s*[::]?|\bfile\s*names?\b\s*[::]?|\battachments?\b\s*[::]?|\bpaths?\b\s*[::]?|\bfile\s+lists?\b\s*[::]?|\bdocument\s+lists?\b\s*[::]?/iu,Wie=/文件名\s*[::]?|文件\s*[::]?|附件\s*[::]?|档案\s*[::]?|檔案\s*[::]?|文档\s*[::]?|文檔\s*[::]?|资料\s*[::]?|資料\s*[::]?|路径\s*[::]?|路徑\s*[::]?|\bfile\s*name\b\s*[::]?|\battachments?\b\s*[::]?|\bfiles?\b\s*[::]?|\bdocuments?\b\s*[::]?|\bdocs?\b\s*[::]?|\bpaths?\b\s*[::]?/iu,Uie=/股票代码|股票代碼|证券代码|證券代碼|(?:代码|代碼|交易所|后缀|後綴|市场|市場)(?=$|[\s::/|,,、()()])|\btickers?\b|\bsymbols?\b|\bexchanges?\b/iu,jie=2e3,Vie=512,qie={},Kie=new Set(["ai","md","py","rs","sh","zip"]),QI=new Set(["as","bj","de","hk","l","ln","ny","pa","sh","ss","sz","t","us"]),Zie=new Set([...QI,"at","ax","cn","co","it","jp","ks","mc","mx","nz","pl","sa","si","to","tw"]),Gie=new Set(["com","dev","io","page","site"]),Yie=new Set(["app","apk","dmg","exe","ipa","lock","log","markdown","webmanifest"]),Xie=new Set(["7z","ai","astro","avi","bash","bz2","c","cjs","cpp","cs","csv","doc","docx","fish","flac","gif","go","gz","h","hpp","html","java","jpeg","jpg","js","json","jsx","kt","md","mdx","mjs","mov","mp3","mp4","pdf","php","png","ppt","pptx","ps1","py","rar","rb","rs","sh","sql","svg","swift","svelte","tar","tgz","toml","ts","tsx","txt","vue","wav","webp","xls","xlsx","xml","yaml","yml","zip","zsh"]),Ju=new Map;function rw(e,t){if(!e||e.length>Vie)return t;for(Ju.set(e,t);Ju.size>jie;){const n=Ju.keys().next().value;if(!n)break;Ju.delete(n)}return t}function Ap(e){return e?.filename===!0||e?.explicitFilename===!0||e?.marketTicker===!0}function E9(e,t){const n={filename:e?.filename||t?.filename,explicitFilename:e?.explicitFilename||t?.explicitFilename,marketTicker:e?.marketTicker||t?.marketTicker};return Ap(n)?n:void 0}function lw(e,t){if(!Ap(t))return e;const n=e?.__linkifyDemotionContext;return{...e,__linkifyDemotionContext:{filename:n?.filename||t?.filename,explicitFilename:n?.explicitFilename||t?.explicitFilename,marketTicker:n?.marketTicker||t?.marketTicker}}}function aw(e){const t=Gp(e);return Ap(t)?t:void 0}function Jie(e){return e.replace(/^[\s>*_`[\]((【《"'“‘]+/u,"").replace(/[\s<*_`\]))】》"'.。;;,,、::!?!?]+$/u,"")}function uw(e,t){if(!Ap(t))return;const n=String(e??"").trim().split(/\s+/u).map(Jie).filter(Boolean);if(n.length===0)return;const o={};return t?.filename&&n.every(s=>Qm(s,{filename:!0,explicitFilename:t.explicitFilename}))&&(o.filename=!0),t?.explicitFilename&&o.filename&&(o.explicitFilename=!0),t?.marketTicker&&n.every(s=>Qm(s,{marketTicker:!0}))&&(o.marketTicker=!0),Ap(o)?o:void 0}function fu(e,t=!1){let n;return{options(o){return t||o==null?lw(e,n):lw(e,E9(aw(o),uw(o,n)))},remember(o){const s=aw(o);n=t?E9(n,s):E9(s,uw(o,n))},reset(){n=void 0}}}function cw(e){return Pie.test(e)&&!e.startsWith("-")&&!e.endsWith("-")}function Qie(e){const t=e.split(".");if(t.length<2)return!1;const n=t[t.length-1]?.toLowerCase()??"";return cw(n)||Die.test(n)?t.every(cw):!1}function eL(e){return Array.from(e).some(t=>t.charCodeAt(0)>127)}function ere(e){return e.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").split(/[/?#]/,1)[0]??""}function tre(e){return e.split(".").some(t=>t.toLowerCase().startsWith("xn--"))}function tL(e,t,n){const o=ere(t);return eL(e)&&tre(o)&&String(n??"").toLowerCase().includes(o.toLowerCase())}function nre(e){if(!e)return!1;if(e.includes("文件")||e.includes("附件")||e.includes("路径")||e.includes("路徑")||e.includes("文档")||e.includes("文檔")||e.includes("档案")||e.includes("檔案")||e.includes("资料")||e.includes("資料")||e.includes("股票")||e.includes("证券")||e.includes("證券")||e.includes("代码")||e.includes("代碼")||e.includes("交易所")||e.includes("后缀")||e.includes("後綴")||e.includes("市场")||e.includes("市場"))return!0;const t=e.toLowerCase();return t.includes("file")||t.includes("attachment")||t.includes("document")||t.includes("doc")||t.includes("path")||t.includes("ticker")||t.includes("symbol")||t.includes("exchange")}function Gp(e){const t=String(e??""),n=Ju.get(t);return n?(Ju.delete(t),Ju.set(t,n),n):nre(t)?rw(t,{explicitFilename:zie.test(t),filename:Wie.test(t),marketTicker:Uie.test(t)}):rw(t,qie)}function ore(e){return Qie(e.split(/[\\/]/)[0]??"")}function sre(e){const t=e.replace(/[^a-z]/gi,"");return t.length>=2&&t===t.toUpperCase()}function ire(e){if($ie.test(e)||!Oie.test(e))return!0;if(Rie.test(e))return!ore(e);const t=e.replace(JI,"");return eL(t)?!0:t.split(".").filter(Boolean).some(sre)}function rre(e,t,n){if(!(n?Zie:QI).has(t))return!1;const o=e.slice(0,-(t.length+1));return o===""?e.startsWith("."):(n?Hie:Bie).test(o)}function Qm(e,t={}){if(!e||Nie.test(e)||Fie.test(e))return!1;const n=e.match(JI);if(!n)return!1;const o=String(n[1]??"").toLowerCase();return rre(e,o,t.marketTicker===!0)?!0:Xie.has(o)?!Kie.has(o)||t.filename?!0:ire(e):!!(t.explicitFilename&&Gie.has(o)||t.filename&&Yie.has(o))}const dw=["!"];function $i(e){return{type:"text",content:e,raw:e}}function Fu(e,t){t===1?e.push({type:"em_open",tag:"em",nesting:1}):t===2?e.push({type:"strong_open",tag:"strong",nesting:1}):t===3&&(e.push({type:"strong_open",tag:"strong",nesting:1}),e.push({type:"em_open",tag:"em",nesting:1}))}function Ru(e,t){t===1?e.push({type:"em_close",tag:"em",nesting:-1}):t===2?e.push({type:"strong_close",tag:"strong",nesting:-1}):t===3&&(e.push({type:"em_close",tag:"em",nesting:-1}),e.push({type:"strong_close",tag:"strong",nesting:-1}))}function _a(e,t,n){let o="";if(t.includes('"')){const s=t.split('"');t=s[0].trim(),o=s[1].trim()}return{type:"link",loading:n,href:t,title:o,text:e,children:[{type:"text",content:e,raw:e}],raw:`[${e}](${t})`}}function lre(e,t){if(!(!e||!t)&&(e.href=String(e.href??"")+t,e.text=String(e.text??"")+t,e.raw=`[${e.text}](${e.href})`,Array.isArray(e.children)&&e.children.length)){const n=e.children[e.children.length-1];n?.type==="text"?(n.content=String(n.content??"")+t,n.raw=String(n.raw??"")+t):e.children.push($i(t))}}function fw(e,t){let n=-1;for(const o of t){const s=e.indexOf(o);s!==-1&&(n===-1||s<n)&&(n=s)}return n}function are(e){const t=e.attrs?.find(n=>n?.[0]==="href")?.[1];return typeof t=="string"?t:""}function ure(e,t){if(!e)return;e.attrs=Array.isArray(e.attrs)?e.attrs:[];const n=e.attrs.findIndex(o=>o?.[0]==="href");n>=0?e.attrs[n][1]=t:e.attrs.push(["href",t])}function pw(e,t,n){let o="";for(let s=t+1;s<n;s++){const i=e[s];if(i?.type!=="text"||typeof i.content!="string")return null;o+=i.content}return o||null}function hw(e){let t=0;for(let n=0;n<e.length;n++){const o=e[n];if(o==="(")t++;else if(o===")"){if(t===0)return n;t--}}return-1}function cre(e){e.core.ruler.after("inline","fix_link_tokens",t=>{const n=t.tokens??[];for(let o=0;o<n.length;o++){const s=n[o];if(s&&s.type==="inline"&&Array.isArray(s.children))try{s.children=dre(s.children,typeof s.content=="string"?s.content:void 0)}catch(i){console.error("[applyFixLinkTokens] failed to fix inline children",i)}}})}function dre(e,t){if(e.length<3)return e;const n=e.some(r=>r.type==="code_inline"),o=new Map;let s=0;for(let r=0;r<e.length;r++){const l=e[r];if(l.type==="link_open"){let a=-1;for(let u=r+1;u<e.length;u++)if(e[u]?.type==="link_close"){a=u;break}if(a!==-1&&l.markup==="linkify"){o.set(l,s);const u=pw(e,r,a),c=s>0&&u?hw(u):-1;if(c!==-1&&u)for(const d of u.slice(c))d==="("?s++:d===")"&&s>0&&s--}a!==-1&&(r=a);continue}if(!(l.type!=="text"||typeof l.content!="string"))for(const a of l.content)a==="("?s++:a===")"&&s>0&&s--}const i=Gp(t);for(let r=0;r<=e.length-1;r++){r<0&&(r=0);const l=e[r];if(!l)break;if(l.type==="link_open"&&(l.markup==="linkify"||l.markup==="autolink")){let a=-1;for(let u=r+1;u<e.length;u++)if(e[u]?.type==="link_close"){a=u;break}if(a!==-1){const u=pw(e,r,a),c=are(l);if(!n&&l.markup==="linkify"&&u&&!tL(u,c,t)&&Qm(u,i)){e.splice(r,a-r+1,$i(u));continue}let d=fw(u??"",dw);if(l.markup==="linkify"&&u?.includes(")")&&(o.get(l)??0)>0){const m=hw(u);m!==-1&&(d===-1||m<d)&&(d=m)}const f=fw(c,dw);let h=d;for(let m=r+1;m<a;m++){const v=e[m];if(v?.type!=="text"||typeof v.content!="string")continue;if(h>=v.content.length){h-=v.content.length;continue}if(h<0)break;const k=v.content[h],w=v.content.slice(0,h);let b=v.content.slice(h);for(let x=m+1;x<a;x++){const S=e[x];S?.type==="text"&&typeof S.content=="string"&&(b+=S.content)}v.content=w,v.raw=w;const _=a-(m+1);_>0&&(e.splice(m+1,_),a=m+1);let g=c;if(k==="!"&&f!==-1)g=c.slice(0,f);else if(b){const x=encodeURI(b);if(x&&c.endsWith(x))g=c.slice(0,c.length-x.length);else{const S=k?encodeURI(k):"",T=S?c.indexOf(S):-1;T!==-1&&(g=c.slice(0,T))}}g!==c&&ure(l,g),b&&e.splice(a+1,0,$i(b));break}}}if(!n){if(l?.type==="em_open"&&e[r-1]?.type==="text"&&e[r-1].content?.endsWith("*")){const a=e[r-1].content?.replace(/(\*+)$/,"")||"";e[r-1].content=a,l.type="strong_open",l.tag="strong",l.markup="**";for(let u=r+1;u<e.length;u++)if(e[u]?.type==="em_close"){e[u].type="strong_close",e[u].tag="strong",e[u].markup="**";break}}else if(l?.type==="text"&&l.content?.endsWith("(")&&e[r+1]?.type==="link_open"){const a=l.content.match(/\[([^\]]+)\]/);if(a){let u=l.content.slice(0,a.index);const c=u.match(/(\*+)$/),d=[];if(c){u=u.slice(0,c.index),u&&d.push($i(u));const f=a[1],h=c[1].length;Fu(d,h);let m=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(m+=e[r+4]?.content||"",e[r+4].content=""),d.push(_a(f,m,!e[r+4]?.content?.startsWith(")"))),Ru(d,h),e[r+4]?.type==="text"){const v=e[r+4].content?.replace(/^\)\**/,"");v&&d.push($i(v)),e.splice(r,5,...d)}else e.splice(r,4,...d)}else{u&&d.push($i(u));let f=a[1];const h=f.match(/^\*+/);if(h){const v=h[0].length;f=f.replace(/^\*+/,"").replace(/\*+$/,"");let k=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(k+=e[r+4]?.content||"",e[r+4].content=""),Fu(d,v),d.push(_a(f,k,!e[r+4]?.content?.startsWith(")"))),Ru(d,v),e[r+4]?.type==="text"){const w=e[r+4].content?.replace(/^\)/,"");w&&d.push($i(w)),e.splice(r,5,...d)}else e.splice(r,4,...d);r===0?r=d.length-1:r-=d.length+1;continue}let m=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(m+=e[r+4]?.content||"",e[r+4].content=""),d.push(_a(f,m,!e[r+4]?.content?.startsWith(")"))),e[r+4]?.type==="text"){const v=e[r+4].content?.replace(/^\)/,"");v&&d.push($i(v)),e.splice(r,5,...d)}else e.splice(r,4,...d)}r-=d.length+1;continue}}else if(l.type==="link_open"&&l.markup==="linkify"&&e[r-1]?.type==="text"&&e[r-1].content?.endsWith("(")){if(e[r-2]?.type==="link_close"){const a=[],u=e[r-3].content||"";let c=l.attrs?.find(d=>d[0]==="href")?.[1]||"";if(e[r+3]?.type==="text"){const d=(e[r+3]?.content??"").indexOf(")"),f=d===-1;d===-1&&(c+=e[r+3]?.content?.slice(0,d)||"",e[r+3].content=""),a.push(_a(u,c,f));const h=e[r+3].content?.replace(/^\)\**/,"");h&&a.push($i(h)),e.splice(r-4,8,...a)}else a.push({type:"link",loading:!0,href:c,title:"",text:u,children:[{type:"text",content:c,raw:c}],raw:`[${u}](${c})`}),e.splice(r-4,7,...a);continue}else if(e[r-1].content==="]("&&e[r-3]?.type==="text"&&e[r-3].content?.endsWith(")"))if(e[r-2]?.type==="strong_open"){const[a,u]=e[r-3].content?.split("[**")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}else if(e[r-2]?.type==="em_open"){const[a,u]=e[r-3].content?.split("[*")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}else{const[a,u]=e[r-3].content?.split("[")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}}if(l.type==="link_close"&&l.nesting===-1&&e[r-2]?.type==="link_open"&&e[r+1]?.type==="text"&&e[r-1]?.type==="text"){const a=e[r-1].content||"",u=e[r-2].attrs||[],c=u.find(w=>w[0]==="href")?.[1]||"",d=u.find(w=>w[0]==="title")?.[1]||"";let f=3,h=2;const m=(e[r-3]?.content||"").match(/^(\*+)$/),v=[];if(m){h+=1;const w=m[1].length;Fu(v,w)}if(l.markup!=="linkify"&&e[r+1].type==="text"&&e[r+1]?.content?.startsWith("](")){f+=1;for(let w=r+1;w<e.length;w++){const b=m?m[1].length:e[r-3].markup.length,_=e[w];if(b===1&&_.type==="em_close")break;if(b===2&&_.type==="strong_close")break;if(b===3&&(_.type==="em_close"||_.type==="strong_close"))break;f+=1}}const k={type:"link",loading:!1,href:c,title:d,text:a,children:[{type:"text",content:a,raw:a}],raw:`[${a}](${c})`};if(v.push(k),m){const w=m[1].length;Ru(v,w)}e.splice(r-h,f,...v),r-=v.length+1;continue}else if(l.content?.startsWith("](")&&e[r-1].markup?.includes("*")&&e[r-4]?.type==="text"&&e[r-4].content?.endsWith("[")){const a=e[r-1].markup.length,u=[],c=e[r-4].content.slice(0,e[r-4].content.length-a);c&&u.push($i(c)),Fu(u,a);const d=e[r-2].content||"";let f=l.content.slice(2),h=!0;if(e[r+1]?.type==="text"){const m=(e[r+1]?.content??"").indexOf(")");h=m===-1,m===-1&&(f+=e[r+1]?.content?.slice(0,m)||"",e[r+1].content="")}if(u.push(_a(d,f,h)),Ru(u,a),e[r+1]?.type==="text"){const m=e[r+1].content?.replace(/^\)\**/,"");m&&u.push($i(m)),e.splice(r-4,8,...u)}else e[r+1]?.type==="link_open"?e.splice(r-4,10,...u):e.splice(r-4,7,...u);r-=u.length+1;continue}else if(l.content?.startsWith("](")&&e[r-1].type==="strong_close"&&e[r-4]?.type==="text"&&e[r-4]?.content?.includes("**[")){const a=[],u=e[r-4].content.split("**[")[0];u&&a.push($i(u)),Fu(a,2);const c=e[r-2].content||"";let d=l.content.slice(2),f=!0;if(e[r+1]?.type==="text"){const h=(e[r+1]?.content??"").indexOf(")");f=h===-1,h===-1&&(d+=e[r+1]?.content?.slice(0,h)||"",e[r+1].content="")}if(a.push(_a(c,d,f)),Ru(a,2),e[r+1]?.type==="text"){const h=e[r+1].content?.replace(/^\)\**/,"");h&&a.push($i(h)),e.splice(r-4,8,...a)}else e[r+1]?.type==="link_open"?e.splice(r-4,10,...a):e.splice(r-4,7,...a);r-=a.length+1;continue}else if(l.type==="strong_close"&&e[r+1]?.type==="text"&&e[r+1].content?.includes("](")&&e[r-1].type==="text"&&/\[.*$/.test(e[r-1].content||"")){const a=[],[u,c]=e[r-1].content?.split("[")||["",""];u&&a.push($i(u)),Fu(a,2);let[d,f]=e[r+1].content.split("](");d=c+d;let h=4;if(e[r+2]?.type==="link_open"){const v=e[r+2].attrs?.find(k=>k[0]==="href")?.[1];e[r+5]?.type==="text"&&e[r+5].content==="."?(f=(v||f)+e[r+5].content,e[r+5].content=""):f=v||f,h+=3}let m=!0;if(l.nesting===-1&&(d=d.replace(/\*+$/,"")),e[r+2]?.type==="text"){const v=(e[r+2]?.content??"").indexOf(")");m=v===-1,v===-1&&(f+=e[r+2]?.content?.slice(0,v)||"",e[r+2].content="")}a.push(_a(d,f,m)),Ru(a,2),e.splice(r-2,h,...a)}if(l.type==="text"&&/\*+\[[^\]]*$/.test(l.content||"")&&e[r+1]?.type==="strong_open"&&e[r+2]?.type==="text"&&e[r+2].content==="]("&&e[r+3]?.type==="link_open"&&e[r+5]?.type==="link_close"&&e[r+6]?.type==="text"&&e[r+6].content===")"&&e[r+7]?.type==="strong_close"){const a=(l.content||"").match(/^(\*+)\[(.*)$/);if(a){const u=(a[2]||"")+a[1];let c=e[r+3]?.attrs?.find(f=>f[0]==="href")?.[1]||"";!c&&e[r+4]?.type==="text"&&(c=e[r+4].content||"");const d=[];Fu(d,2),d.push(_a(u,c,!1)),Ru(d,2),e.splice(r,9,...d),r-=d.length-1;continue}}}}if(n)return e;for(let r=0;r<e.length-1;r++){const l=e[r],a=e[r+1];if(l?.type!=="link"||a?.type!=="text"||typeof a.content!="string"||!a.content.startsWith("!"))continue;const u=String(l.href??"");if(String(l.text??"")!==u||!u.endsWith("=")&&!u.endsWith("#"))continue;lre(l,"!");const c=a.content.slice(1);c?(a.content=c,a.raw=c):e.splice(r+1,1)}return e}function fre(e){e.core.ruler.after("inline","fix_list_item_tokens",t=>{const n=t.tokens??[];for(let o=0;o<n.length;o++){const s=n[o];if(s&&s.type==="inline"&&Array.isArray(s.children))try{s.children=pre(s.children)}catch(i){console.error("[applyFixListItem] failed to fix inline children",i)}}})}function pre(e){const t=e[e.length-1],n=String(t?.content??"");return t?.type==="text"&&/^\s*\d+\.\s*$/.test(n)&&e[e.length-2]?.tag==="br"&&e.splice(e.length-1,1),e}function hre(e){e.core.ruler.after("inline","fix_strong_tokens",t=>{const n=t.tokens??[];for(let o=0;o<n.length;o++){const s=n[o];if(s&&s.type==="inline"&&Array.isArray(s.children))try{s.children=mre(s.children)}catch(i){console.error("[applyFixStrongTokens] failed to fix inline children",i)}}})}function mre(e){let t=0;const n=new Set,o=new Set;let s=0;for(let c=0;c<e.length;c++){const d=e[c],f=d.type;if(f==="strong_open"){t++;const h=String(d.markup??"");let m=c-1;for(;m>=0&&e[m].type==="text"&&e[m].content==="";)m--;const v=e[m];let k=c+1;for(;k<e.length&&e[k].type==="text"&&e[k].content==="";)k++;const w=e[k];h==="__"&&(v?.content?.endsWith("_")||w?.content?.startsWith("_")||w?.markup?.includes("_"))&&(d.type="text",d.tag="",d.content=h,d.raw=h,d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null,n.add(t))}else if(f==="strong_close")n.has(t)&&d.markup==="__"&&(d.type="text",d.content=d.markup,d.raw=String(d.markup??""),d.tag="",d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null),t--,t<0&&(t=0);else if(f==="em_open"){s++;const h=String(d.markup??"");let m=c-1;for(;m>=0&&e[m].type==="text"&&e[m].content==="";)m--;const v=e[m];let k=c+1;for(;k<e.length&&e[k].type==="text"&&e[k].content==="";)k++;const w=e[k];h==="_"&&(v?.content?.endsWith("_")||w?.content?.startsWith("_")||w?.markup?.includes("_"))&&(d.type="text",d.tag="",d.content=h,d.raw=h,d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null,o.add(s))}else f==="em_close"&&(o.has(s)&&d.markup==="_"&&(d.type="text",d.content=d.markup,d.raw=String(d.markup??""),d.tag="",d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null),s--,s<0&&(s=0))}if(e.length<5)return e;const i=e.length-4,r=e[i];let l=[...e];const a=e[i+1],u=String(r.content??"");if(r.type==="link_open"&&e[i-1]?.type==="em_open"&&e[i-2]?.type==="text"&&e[i-2].content?.endsWith("*")){const c=String(e[i-2].content??"").slice(0,-1),d=[{type:"strong_open",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""},e[i],e[i+1],e[i+2],{type:"strong_close",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""}];c&&d.unshift({type:"text",content:c,raw:c}),l.splice(i-2,6,...d)}else if(r.type==="text"&&u.endsWith("*")&&a.type==="em_open"){const c=e[i+2],d=c?.type==="text"?4:3,f=[{type:"strong_open",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""},{type:"text",content:c?.type==="text"?String(c.content??""):"",raw:c?.type==="text"?String(c.content??""):""},{type:"strong_close",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""}],h=u.slice(0,-1);h&&f.unshift({type:"text",content:h,raw:h}),l.splice(i,d,...f)}return l=gre(l),l}function gre(e){if(e.length<7)return e;const t=[];for(let n=0;n<e.length;n++){const o=e[n],s=e[n+1],i=e[n+2],r=e[n+3],l=e[n+4],a=e[n+5],u=e[n+6];if(o?.type==="strong_open"&&s?.type==="text"&&i?.type==="strong_close"&&r?.type==="strong_open"&&l?.type==="math_inline"&&a?.type==="strong_close"&&u?.type==="text"){const c=String(u.content??""),d=c.indexOf("**");if(d!==-1){const f=c.slice(0,d),h=c.slice(d+2);t.push(o),t.push(s),t.push(l),f&&t.push({...u,type:"text",content:f,raw:f}),t.push(a),h&&t.push({...u,type:"text",content:h,raw:h}),n+=6;continue}}if(o?.type==="strong_open"&&s?.type==="text"&&i?.type==="strong_close"&&r?.type==="strong_open"&&l?.type==="math_inline"&&a?.type==="strong_close"){const c=vre(e,n+6);if(c){t.push(o),t.push(s),t.push(l);for(let d=n+6;d<c.index;d++)t.push(e[d]);c.beforeClose&&t.push({...e[c.index],type:"text",content:c.beforeClose,raw:c.beforeClose}),t.push(a),c.afterClose&&t.push({...e[c.index],type:"text",content:c.afterClose,raw:c.afterClose}),n=c.index;continue}}t.push(o)}return t}function vre(e,t){for(let n=t;n<e.length;n++){const o=e[n];if(o?.type==="strong_open")return null;if(o?.type!=="text")continue;const s=String(o.content??""),i=s.indexOf("**");if(i!==-1)return{index:n,beforeClose:s.slice(0,i),afterClose:s.slice(i+2)}}return null}function yre(e){e.core.ruler.after("block","fix_table_tokens",t=>{const n=t;try{const o=xre(n.tokens??[],!!n.env?.__markstreamFinal,n.src??"");Array.isArray(o)&&(n.tokens=o)}catch(o){console.error("[applyFixTableTokens] failed to fix table tokens",o)}})}function mw(){return[{type:"table_open",tag:"table",attrs:null,map:null,children:null,content:"",markup:"",info:"",level:0,loading:!0,meta:null},{type:"thead_open",tag:"thead",attrs:null,block:!0,level:1,children:null},{type:"tr_open",tag:"tr",attrs:null,block:!0,level:2,children:null}]}function gw(){return[{type:"tr_close",tag:"tr",attrs:null,block:!0,level:2,children:null},{type:"thead_close",tag:"thead",attrs:null,block:!0,level:1,children:null},{type:"table_close",tag:"table",attrs:null,map:null,children:null,content:"",markup:"",info:"",level:0,meta:null}]}function vw(e){return[{type:"th_open",tag:"th",attrs:null,block:!0,level:3,children:null},{type:"inline",tag:"",children:null,content:e,level:4,attrs:null,block:!0},{type:"th_close",tag:"th",attrs:null,block:!0,level:3,children:null}]}function nL(e,t){if(!e.startsWith("|")||e.includes(` +`)||!e.endsWith("|"))return null;const n=e.slice(1).split("|");return n.at(-1)===""&&n.pop(),n.length>0&&n.every(o=>o.trim().length>0)?n:null}function I9(e){return nL(e)!==null}function oL(e){return/^:?-+:?$/.test(e.trim())}function kre(e){if(!e.startsWith("|"))return!1;const t=e.slice(1).split("|");return t.at(-1)===""&&t.pop(),t.length>0&&t.every(oL)}function bre(e){return/^(?:[::]-*|:?-+:?)?$/.test(e.trim())}function Cre(e){if(e==="")return!0;if(!e.startsWith("|"))return!1;const t=e.slice(1).split("|"),n=t.at(-1)??"";return t.slice(0,-1).every(oL)&&bre(n)}function wre(e){return e==="|"||e==="|:"}function _re(e){const t=nL(e);return t!==null&&t.every(n=>!n.includes(":"))}function xre(e,t=!1,n=""){const o=[...e];if(e.length<3)return o;const s=e.length-2,i=e[s];if(i.type==="inline"){const r=String(i.content??""),l=r.split(` +`)[0]??"",[a="",u="",...c]=r.split(` +`),d=!t&&!r.includes(` +`)&&/\r?\n$/.test(n)&&I9(r);if(!t&&(r.includes(` +`)&&c.length===0&&I9(a)&&Cre(u)||d)){const f=l.slice(1,-1).split("|").map(m=>m.trim()).flatMap(m=>vw(m)),h=[...mw(),...f,...gw()];o.splice(s-1,3,...h)}else if(r.includes(` +`)&&c.length===0&&I9(a)&&kre(u)){const f=l.slice(1,-1).split("|").map(m=>m.trim()).flatMap(m=>vw(m)),h=[...mw(),...f,...gw()];o.splice(s-1,3,...h)}else r.includes(` +`)&&c.length===0&&_re(a)&&wre(u)&&(i.content=r.slice(0,-2),i.children.splice(2,1))}return o}function Sre(e,t,n,o){const s=e.length;if(n==="$$"&&o==="$$"){let u=t;for(;u<s-1;){if(e[u]==="$"&&e[u+1]==="$"){let c=u-1,d=0;for(;c>=0&&e[c]==="\\";)d++,c--;if(d%2===0)return u}u++}return-1}const i=n[n.length-1],r=o;let l=0,a=t;for(;a<s;){if(e.slice(a,a+r.length)===r){let c=a-1,d=0;for(;c>=0&&e[c]==="\\";)d++,c--;if(d%2===0){if(l===0)return a;l--,a+=r.length;continue}}const u=e[a];if(u==="\\"){a+=2;continue}u===i?l++:u===r[r.length-1]&&l>0&&l--,a++}return-1}var Are=Sre;const Mre=["boldsymbol","mathbb","mathcal","mathfrak","mathrm","mathit","mathsf","vec","hat","bar","tilde","overline","underline","mathscr","mathnormal","operatorname","mathbf*"],eg=Mre.map(e=>e.replace(/[.*+?^${}()|[\\]"\]/g,"\\$&")).join("|"),Tre=/\\[a-z]+/i,sL="(?:\\\\|\\u0008)",Ere=new RegExp(String.raw`${sL}(?:${eg})\s*\{[^}]+\}`,"i"),Ire=new RegExp(String.raw`(?:${sL})?(?:${eg})\s*\{`,"i"),Lre=/\\(?:text|frac|left|right|times)/,$re=/(?:^|[^+])\+(?!\+)|[=\-*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/,Nre=/\b[A-Z]{2,}-[A-Z]{2,}\b/i,Fre=/[A-Z]+\s*\([^)]+\)/i,Rre=/^\(\s*[a-z](?:\s*,\s*[a-z])+\s*\)$/i,Ore=/\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/,Pre=/\b\d{4}\/\d{1,2}\/\d{1,2}(?:[ T]\d{1,2}:\d{2}(?::\d{2})?)?\b/,Dre={"\b":"\\b","\v":"\\v","\f":"\\f"};function Bre(e){let t="";for(const n of e)t+=Dre[n]??n;return t}function Oa(e){if(!e)return!1;const t=Bre(e),n=t.trim();if(Pre.test(n)||n.includes("**"))return!1;if(n.length>2e3)return!0;const o=Tre.test(t),s=Ere.test(t),i=Ire.test(t),r=Lre.test(t),l=/(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)_(?:\{[^}]+\}|[A-Z0-9\\])/i.test(t)||/(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)\^(?:\{[^}]+\}|[A-Z0-9\\])/i.test(t),a=$re.test(t)&&!Nre.test(t),u=Fre.test(t),c=Rre.test(n),d=Ore.test(t),f=/^\([a-z]\)$/i.test(n)||/^(?:[a-z]|pi)$/i.test(n),h=/^(?:[A-Z][a-z]?(?:_\{?\d+\}?|\^\{?\d+\}?)?)+$/.test(n);return o||s||i||r||l||a||u||c||d||f||h}const iL="__markstreamMathPluginApplied",z3=80,rL=2e4,yw=rL+4096;function Xy(e){return!!e[iL]}function Hre(e){e[iL]=!0}const lL=["ldots","cdots","quad","in","displaystyle","int_","lim","lim_","ce","pu","end","infty","perp","mid","operatorname","to","rightarrow","leftarrow","math","mathrm","mathit","mathbb","mathcal","mathfrak","implies","alpha","beta","gamma","delta","epsilon","lambda","sum","sum_","prod","sqrt","fbox","boxed","color","rule","edef","fcolorbox","hline","hdashline","cdot","times","pm","le","ge","neq","sin","cos","tan","log","ln","exp","frac","text","left","right"],zre=["cdot","mathbf{","partial","mu_{"],aL=lL.slice().sort((e,t)=>t.length-e.length).map(e=>e.replace(/[.*+?^${}()|[\\]\\\]/g,"\\$&")).join("|"),uL="[ \r\b\f\v]",Wre=new RegExp(`([^\\\\])(${zre.map(e=>e).join("|")})+`,"g"),Ure=/span\{([^}]+)\}/,jre=/\\operatorname\{span\}\{((?:[^{}]|\{[^}]*\})+)\}/,Vre=/(^|[^\\])\\\r?\n/g,qre=/(^|[^\\])\\$/g,Kre=/[\p{L}\p{M}\p{N}\p{Pe}\p{Pf}'′″‴|‖]/u,Zre=new RegExp(`(${uL})|(${aL})\\b`,"g"),kw=new Map,bw=new Map;function Gre(e){if(!e)return Zre;const t=[...e];t.sort((r,l)=>l.length-r.length);const n=t.join(""),o=kw.get(n);if(o)return o;const s=`(?:${t.map(r=>r.replace(/[.*+?^${}()|[\\]\\"\]/g,"\\$&")).join("|")})`,i=new RegExp(`(${uL})|(${s})\\b`,"g");return kw.set(n,i),i}function Yre(e,t){const n=e?[]:[...t??[]];e||n.sort((l,a)=>a.length-l.length);const o=e?"__default__":n.join(""),s=bw.get(o);if(s)return s;const i=e?[eg,aL].filter(Boolean).join("|"):[n.map(l=>l.replace(/[.*+?^${}()|[\\]\\\]/g,"\\$&")).join("|"),eg].filter(Boolean).join("|"),r=new RegExp(`(^|[^\\\\\\w])(${i})\\s*\\{`,"g");return bw.set(o,r),r}const Cw={" ":"t","\r":"r","\b":"b","\f":"f","\v":"v"};function ww(e){const t=/(^|[^\\])(__|\*\*)/g;let n=0;for(;t.exec(e)!==null;)n++;return n}function Xre(e){return e.replace(/(^|[^\\])!+/gu,(t,n)=>{if(n&&Kre.test(n))return t;const o=n?t.slice(n.length):t;return`${n}${"\\!".repeat(o.length)}`})}function _w(e){const t=/(^|[^\\])(__|\*\*)/g;let n,o=null;for(;(n=t.exec(e))!==null;)o={marker:n[2],index:n.index+(n[1]?.length??0)};return o}function xa(e,t){const n=t?.commands??lL,o=t?.escapeExclamation??!0,s=t?.commands==null,i=Gre(s?void 0:n);let r=e.replace(i,(u,c,d,f,h)=>{if(c!==void 0&&Cw[c]!==void 0)return`\\${Cw[c]}`;if(d&&n.includes(d)){const m=h&&typeof f=="number"?h[f-1]:void 0;return m==="\\"||m&&/\w/.test(m)?u:`\\${d}`}return u});o&&(r=Xre(r));let l=r;const a=Yre(s,s?void 0:n);return l=l.replace(a,(u,c,d)=>`${c}\\${d}{`),l=l.replace(Ure,"span\\{$1\\}").replace(jre,"\\operatorname{span}\\{$1\\}"),l=l.replace(Vre,`$1\\\\ +`),l=l.replace(qre,"$1\\\\"),l=l.replace(Wre,"$1\\$2"),l}function xw(e){const t=e.trim();return!(!Oa(t)||/"[^"\n]{1,80}"\s*:\s*/.test(t)||!(/\\[a-z]+/i.test(t)||/[=+*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/.test(t)||/[_^]/.test(t))&&/\s-\s/.test(t))}function cL(e){const t=[];let n=0;for(;n<e.length;){if(e[n]!=="`"){n++;continue}const o=n;let s=1;for(;o+s<e.length&&e[o+s]==="`";)s++;let i=o+s,r=-1;for(;i<e.length;){if(e[i]!=="`"){i++;continue}let l=1;for(;i+l<e.length&&e[i+l]==="`";)l++;if(l===s){r=i;break}i+=l}if(r!==-1){t.push([o,r+s]),n=r+s;continue}n=o+s}return t}function tg(e,t){for(const n of e)if(t>=n[0]&&t<n[1])return n;return null}function Jre(e,t=!1){const n=[];let o=0;for(;o<e.length-1;){if(e[o]==="!"&&e[o+1]==="["){const s=o;let i=o+2,r=1;for(;i<e.length&&r>0;){if(e[i]==="\\"&&i+1<e.length){i+=2;continue}e[i]==="["?r++:e[i]==="]"&&r--,i++}if(r===0&&i<e.length&&e[i]==="("){let l=i+1,a=1;for(;l<e.length&&a>0;){if(e[l]==="\\"&&l+1<e.length){l+=2;continue}e[l]==="("?a++:e[l]===")"&&a--,l++}if(a===0){n.push([s,l]),o=l;continue}if(t){n.push([s,e.length]),o=e.length;continue}}}o++}return n}function Yp(e,t){let n=t-1,o=0;for(;n>=0&&e[n]==="\\";)o++,n--;return o%2===1}function W3(e,t){let n=t;for(;n<e.length;){const o=e.indexOf("$",n);if(o===-1)return-1;if(Yp(e,o)){n=o+1;continue}return o}return-1}function L9(e,t){let n=t;for(;n<e.length;){const o=W3(e,n);if(o===-1)return-1;if(o>0&&e[o-1]==="$"||o+1<e.length&&e[o+1]==="$"){n=o+1;continue}return o}return-1}function md(e,t,n=0){let o=Math.max(0,n);for(;o<e.length;){const s=e.indexOf(t,o);if(s===-1)return-1;if(!Yp(e,s))return s;o=s+Math.max(1,t.length)}return-1}function Sw(e,t,n=0,o=e.length,s=[]){let i=0,r=Math.max(0,n);const l=Math.min(e.length,Math.max(0,o));for(;r<l;){const a=e.indexOf(t,r);if(a===-1||a>=l)break;const u=tg(s,a);if(u){r=Math.max(a+Math.max(1,t.length),u[1]);continue}Yp(e,a)||i++,r=a+Math.max(1,t.length)}return i}function Jy(e,t,n){const o=Tp(String(e??""));if(!o.endsWith(t))return-1;const s=o.length-t.length;if(s<=0||!Tp(o.slice(0,s)).trim()||Yp(o,s))return-1;const i=cL(o);if(tg(i,s))return-1;const r=Sw(o,t,0,s,i);if(t==="$$"){if(r%2===1)return-1}else if(r>Sw(o,n,0,s,i))return-1;return s}function Mp(e){return e===" "||e===" "}function Tp(e){let t=e.length;for(;t>0&&Mp(e[t-1]);)t--;return e.slice(0,t)}function Aw(e){let t=0;for(let n=0;n<e.length;n++)e[n]===` +`&&t++;return t}function Mw(e){if(!e)return!1;const t=e.charCodeAt(0);return t>=48&&t<=57}function Qre(e){if(e.length<3)return!1;const t=e[0];if(t!=="-"&&t!=="*"&&t!=="_"&&t!=="=")return!1;let n=0;for(let o=0;o<e.length;o++){const s=e[o];if(s===t){n++;continue}if(!Mp(s))return!1}return n>=3}function ele(e){const t=e.trim();if(!t)return!1;let n=0;t[n]===":"&&n++;let o=0;for(;t[n]==="-";)o++,n++;return o<3?!1:(t[n]===":"&&n++,n===t.length)}function tle(e){if(!e.includes("|"))return!1;const t=e[0]==="|"?e.slice(1):e;return(t.endsWith("|")?t.slice(0,-1):t).split("|").every(ele)}function nle(e){let t=0;if(!Mw(e[t]))return!1;for(;Mw(e[t]);)t++;return e[t]!=="."&&e[t]!==")"?!1:Mp(e[t+1])}function dL(e){const t=e.trimStart();if(!t||t.startsWith("```")||t.startsWith("~~~")||t.startsWith(":::")||t[0]===">"||t[0]==="<")return!0;if(t[0]==="#"){let n=0;for(;t[n]==="#";)n++;if(n>=1&&n<=6&&Mp(t[n]))return!0}return!!((t[0]==="-"||t[0]==="+"||t[0]==="*")&&Mp(t[1])||nle(t)||Qre(t)||tle(t))}function Tw(e,t){return e?t?`${e} +${t}`:e:t}function U3(e){const t=String(e??"").trim();return t?Oa(t):!1}function Ew(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)|0;return t.toString(36)}function fL(e){if(e.length<=yw)return{source:e,lineOffset:0};let t=e.length-yw;const n=e.indexOf(` +`,t);return n===-1?{source:"",lineOffset:Aw(e)}:(t=n+1,{source:e.slice(t),lineOffset:Aw(e.slice(0,t))})}function pL(e){const t=String(e??"");if(!t||!t.includes("$$")&&!t.includes("\\["))return!1;const{source:n}=fL(t);if(!n)return!1;const o=n.split(/\r?\n/),s=Math.max(0,o.length-z3-2),i=[["$$","$$"],["\\[","\\]"]];for(let r=s;r<o.length;r++){const l=Tp(o[r]);if(l&&!dL(l)){for(const[a,u]of i)if(Jy(l,a,u)!==-1)return!0}}return!1}function ole(e){const t=String(e??"");if(!t||!t.includes("$$")&&!t.includes("\\["))return null;const{source:n,lineOffset:o}=fL(t);if(!n)return null;const s=n.split(/\r?\n/),i=Math.max(0,s.length-z3-2),r=[["$$","$$"],["\\[","\\]"]];for(let l=i;l<s.length-1;l++){const a=Tp(s[l]);for(const[u,c]of r){const d=Jy(a,u,c);if(d===-1)continue;let f="",h=!1;for(let m=l+1;m<s.length;m++){if(m-l>z3){h=!0;break}const v=s[m],k=md(v,c);if(k!==-1){const w=Tw(f,v.slice(0,k));if(!U3(w)){h=!0;break}const b=v.slice(k+c.length),_=b.trim()?`suffix:${Ew(b)}`:"nosuffix";return["closed",u,o+l,d,o+m,k,Ew(w),_].join(":")}if(dL(v)){h=!0;break}if(f=Tw(f,v),f.length>rL){h=!0;break}}if(!h&&U3(f))return["pending",u,o+l,d].join(":")}}return null}function $9(e,t){const n=String(e??"").trim();return!n||!/^\d[\d,.]*\s*[~~-]\s*$/.test(n)?!1:/\d/.test(String(t??""))}function sle(e){const t=String(e??"").trimStart(),n=t.match(/^\d+(?:,\d{3})*(?:\.\d+)?/);if(!n)return!1;const o=t.slice(n[0].length);return/^\s*(?:[+\-*/^_=<>]|\\[a-z]+)/i.test(o)?!1:o===""||/^[)\s,.!?;:]/.test(o)}function N9(e){const t=String(e??"").trim();return t?/^(?:\.{3,}|…+)$/.test(t):!1}function ile(e,t){Hre(e);const n=(r,l,a)=>{const u=String(l??"").replace(/^[\t ]+/,"").replace(/[\t ]+$/,"");if(!u)return;const c=r.push("paragraph_open","p",1);c.map=[a,a+1];const d=r.push("inline","",0);d.content=u,d.map=[a,a+1],d.children=[],r.push("paragraph_close","p",-1)},o=(r,l)=>{const a=r,u=!!t?.strictDelimiters,c=!a?.env?.__markstreamFinal,d=(b,_)=>{let g=_;for(;g<b.length&&(b[g]===" "||b[g]===" ");)g++;if(g===_||!(b[g]===` +`||b[g]==="\r"&&b[g+1]===` +`))return _;const x=b.slice(_,g),S=a.push("text","",0);return S.content=x,g};if(/^\*[^*]+/.test(a.src))return!1;if(a.src[a.pos]==="$"){let b=a.pos+1;for(;a.src[b]==="$";)b++;const _=b-a.pos,g=a.src[b];if(_>=3&&(!g||/\s/.test(g))){const x=a.push("text","",0);return x.content=a.src.slice(a.pos,b),a.pos=b,!0}}const f=[["$$","$$"],["$","$"],["\\(","\\)"]],h=String(a.pending??""),m=Math.max(0,a.pos-h.length);let v=m,k=m;const w=m;for(const[b,_]of f){const g=a.src,x=cL(g),S=Jre(g,c);let T=!1;b==="$$"&&v!==w&&(v=w);let A=-1,E=-1,P=0;const D=I=>{if((I==="undefined"||I==null)&&(I=""),I==="\\"){a.pos=a.pos+I.length,v=a.pos;return}if(I==="\\)"||I==="\\("){const H=a.push("text_special","",0);H.content=I==="\\)"?")":"(",H.markup=I,a.pos=a.pos+I.length,v=a.pos;return}if(!I)return;if(b==="$$"&&I.includes("$")){let H=0;for(;H<I.length;){const O=W3(I,H);if(O===-1){const le=I.slice(H);if(le){const Ie=a.push("text","",0);Ie.content=le,a.pos=a.pos+le.length,v=a.pos}break}if(O>0&&I[O-1]==="$"||O+1<I.length&&I[O+1]==="$"){const le=I.slice(H,O+1);if(le){const Ie=a.push("text","",0);Ie.content=le,a.pos=a.pos+le.length,v=a.pos}H=O+1;continue}const F=I.slice(H,O);if(F){const le=a.push("text","",0);le.content=F,a.pos=a.pos+F.length,v=a.pos}const U=L9(I,O+1);if(U===-1){const le=I.slice(O),Ie=a.push("text","",0);Ie.content=le,a.pos=a.pos+le.length,v=a.pos;break}const z=I.slice(O+1,U),W=z.includes("`"),K=!z||!z.trim(),V=I[U+1],ie=$9(z,V),ne=N9(z);if(!W&&!K&&!ie&&!ne){const le=a.push("math_inline","math",0);le.content=xa(z,t),le.markup="$",le.raw=`$${z}$`,le.loading=!1,a.pos=a.pos+(U-O+1),v=a.pos,H=U+1;continue}const X=a.push("text","",0);X.content="$",a.pos=a.pos+1,v=a.pos,H=O+1}return}const $=I.indexOf("![");if($!==-1){if($>0){const F=I.slice(0,$),U=a.push("text","",0);U.content=F,a.pos=a.pos+F.length,v=a.pos}const H=I.slice($).match(/^!\[([^\]]*)\]\(([^)]+)\)/);if(H){const[,F,U]=H,z=U.match(/^(\S+)(?:\s+"([^"]+)")?\s*$/),W=z?z[1]:U,K=z&&z[2]?z[2]:null,V=a.push("image","img",0);V.attrs=[["src",W],["alt",F]],K&&V.attrs.push(["title",K]),V.content=F,V.children=[{type:"text",content:F,tag:""}],a.pos=a.pos+H[0].length,v=a.pos;const ie=I.slice($+H[0].length);ie&&D(ie);return}const O=a.push("text","",0);O.content=I,a.pos=a.pos+I.length,v=a.pos;return}const B=a.push("text","",0);B.content=I,a.pos=a.pos+I.length,v=a.pos};for(;!(v>=g.length);){const I=g.indexOf(b,v);if(I===-1)break;if(Yp(g,I)){v=I+Math.max(1,b.length);continue}const $=tg(x,I);if($){v=$[1];continue}const B=tg(S,I);if(B){v=B[1];continue}if(I===A&&v===E){if(P++,P>2){v=I+Math.max(1,b.length);continue}}else P=0,A=I,E=v;if(b==="("&&I>0){let ie=I-1;for(;ie>=0&&g[ie]===" ";)ie--;if(ie>=0&&g[ie]==="]"){v=I+b.length;continue}}if(b==="$"&&I>0&&g[I-1]==="$"){v=I+1;continue}if(b==="$"&&I<g.length-1&&g[I+1]==="$"){v=I+2;continue}const H=b==="$"?L9(g,I+b.length):Are(g,I+b.length,b,_);if(H===-1){const ie=g.slice(I+b.length);if(ie.includes(b)){v=g.indexOf(b,I+b.length);continue}if(H===-1){const ne=b==="$"&&sle(ie);if(c&&!u&&!ne&&Oa(ie)&&!ie.includes("`")){if(v=I+b.length,T=!0,!l){a.pending="";const X=k?g.slice(k,v):g.slice(0,v),le=ww(X)%2===1;if(k)D(g.slice(k,v));else{let Ie=g.slice(0,v);Ie.endsWith(b)&&(Ie=Ie.slice(0,Ie.length-b.length)),D(Ie)}if(le){const Ie=_w(X)?.marker??"**",de=a.push("strong_open","",0);de.markup=Ie;const pe=a.push("math_inline","math",0);pe.content=xa(ie,t),pe.markup=b==="$$"?"$$":b==="\\("?"\\(\\)":b==="$"?"$":"()",pe.raw=`${b}${ie}${_}`,pe.loading=!0,de.content=ie,a.push("strong_close","",0)}else{const Ie=a.push("math_inline","math",0);Ie.content=xa(ie,t),Ie.markup=b==="$$"?"$$":b==="\\("?"\\(\\)":b==="$"?"$":"()",Ie.raw=`${b}${ie}${_}`,Ie.loading=!0}a.pos=g.length}v=g.length,k=v}break}}const O=g.slice(I+b.length,H),F=O.includes("`"),U=!O||!O.trim(),z=b==="$",W=g[H+_.length],K=z&&$9(O,W),V=z&&N9(O);if(u?F||U||K||V:F||U||K||V||!z&&!Oa(O)){v=H+_.length;const ie=g.slice(a.pos,v);a.pending||(D(ie),k=v);continue}if(T=!0,!l){const ie=g.slice(a.pos-(a.pending??"").length,I);let ne=g.slice(0,v)?g.slice(k,I):ie;const X=ww(ne)%2===1;I!==a.pos&&X&&(ne=a.pending+g.slice(a.pos,I));const le=X?_w(ne):null,Ie=le?.marker??"**";if(a.pending!==ne)if(a.pending="",X)if(le){const de=ne.slice(le.index+Ie.length);D(ne.slice(0,le.index));const pe=a.push("strong_open","",0);pe.markup=Ie;const ve=a.push("text","",0);ve.content=de,a.push("strong_close","",0)}else D(ne);else D(ne);if(X){const de=a.push("strong_open","",0);de.markup=Ie;const pe=a.push("math_inline","math",0);pe.content=xa(O,t),pe.markup=b==="$$"?"$$":b==="\\("?"\\(\\)":b==="$"?"$":"()",pe.raw=`${b}${O}${_}`,pe.loading=!1;const ve=g.slice(H+_.length).startsWith(Ie);return ve&&a.push("strong_close","",0),a.pos=d(g,H+_.length),v=a.pos,k=v,ve||a.push("strong_close","",0),!0}else{const de=a.push("math_inline","math",0);de.content=xa(O,t),de.markup=b==="$$"?"$$":b==="\\("?"\\(\\)":b==="$"?"$":"()",de.raw=`${b}${O}${_}`,de.loading=!1}}return v=d(g,H+_.length),k=v,a.pos=v,!0}if(T){if(l)a.pos=v;else{if(b==="$$"&&v<g.length&&g.slice(v).includes("$")){let I=v;for(;!(I>=g.length);){const $=W3(g,I);if($===-1)break;if($+1<g.length&&g[$+1]==="$"){I=$+2;continue}if($>0&&g[$-1]==="$"){I=$+1;continue}const B=L9(g,$+1);if(B===-1)break;const H=g.slice($+1,B),O=H.includes("`"),F=!H||!H.trim(),U=g[B+1],z=$9(H,U),W=N9(H);if(!O&&!F&&!z&&!W){const K=g.slice(v,$);K&&D(K);const V=a.push("math_inline","math",0);V.content=xa(H,t),V.markup="$",V.raw=`$${H}$`,V.loading=!1,v=B+1,I=B+1}else D("$"),I=$+1}I<g.length&&D(g.slice(I))}else v<g.length&&D(g.slice(v));a.pos=g.length}return!0}}return!1},s=(r,l,a,u)=>{const c=r,d=!c?.env?.__markstreamFinal,f=t?.strictDelimiters,h=f?[["\\[","\\]"],["$$","$$"]]:[["\\[","\\]"],["[","]"],["$$","$$"]],m=c.bMarks[l]+c.tShift[l];let v=c.src.slice(m,c.eMarks[l]).trim(),k=!1,w="",b="",_=!1,g="",x=!1;for(const[K,V]of h)if(v.startsWith(K))if(K.includes("[")){const ie=K==="\\["?v.slice(K.length):"";if(K==="\\["&&md(ie,V)===-1&&!/^\s*!\[/.test(ie)&&!ie.includes("`")&&Oa(ie)){k=!0,w=K,b=V;break}if(t?.strictDelimiters){if(v.replace("\\","")==="["){if(l+1<a){k=!0,w=K,b=V;break}continue}}else if(v.replace("\\","")==="["){if(l+1<a){k=!0,w=K,b=V;break}continue}else{const ne=c.tokens[c.tokens.length-1];if(ne&&ne.type==="list_item_open"&&ne.mark==="-"&&v.slice(K.length,v.indexOf("]")).trim()==="x")continue;if(v.replace("\\","").startsWith("[")&&!v.includes("](")){const X=v.indexOf("]");if(v.slice(X).trim()!=="]")continue;const le=v.slice(K.length,X);if(K==="["?xw(le):Oa(le)){k=!0,w=K,b=V;break}continue}}}else{k=!0,w=K,b=V;break}else if((K==="$$"||K==="\\[")&&v.endsWith(K)&&l+1<a){const ie=Jy(v,K,V);if(ie===-1)continue;g=Tp(v.slice(0,ie)),x=!0;const ne=c.bMarks[l+1]+c.tShift[l+1];v=c.src.slice(ne,c.eMarks[l+1]).trim(),_=!0,k=!0,w=K,b=V;break}if(!k)return!1;if(u&&!x)return!0;const S=v.indexOf(w),T=S+w.length,A=!f&&w==="["?v.indexOf("\\]",T):-1,E=A>=0?"\\]":b,P=A>=0?A:md(v,b,T);if(!_&&P>w.length){const K=v.slice(S+w.length,P),V=c.push("math_block","math",0);V.content=xa(K),V.markup=w==="$$"?"$$":w==="["?"[]":"\\[\\]",V.map=[l,l+1],V.raw=`${w}${K}${E}`,V.block=!0,V.loading=!1,c.line=l+1;const ie=v.slice(P+E.length);return ie.trim()&&n(c,ie,l),!0}let D=l,I="",$=!1,B="",H=l;const O=_?v:v===w?"":v.slice(w.length),F=!f&&w==="\\["?"]":"",U=md(O,b);if(U!==-1){const K=U;I=O.slice(0,K),B=O.slice(K+b.length),H=_?l+1:l,$=!0,D=H}else for(O&&!_&&(I=O),D=l+1;D<a;D++){const K=c.bMarks[D]+c.tShift[D],V=c.eMarks[D],ie=c.src.slice(K,V),ne=ie.trim();if(!f&&w==="["&&ne==="\\]"){b="\\]",$=!0;break}if(F&&ie.trim()===F){b=F,$=!0;break}if(ne===b){$=!0;break}else if(!f&&w==="["&&ie.includes("\\]")){$=!0;const X=ie.indexOf("\\]");b="\\]";const le=ie.slice(0,X);le&&(I+=(I?` +`:"")+le),B=ie.slice(X+b.length),H=D;break}else if(md(ie,b)!==-1){$=!0;const X=md(ie,b),le=ie.slice(0,X);le&&(I+=(I?` +`:"")+le),B=ie.slice(X+b.length),H=D;break}I+=(I?` +`:"")+ie}if((!d||f)&&!$)return!1;const z=/^\s*!\[/.test(I);if(!(x?!z&&U3(I):w==="$$"?!z:w==="["?xw(I):Oa(I)))return!1;if(u)return!0;g&&n(c,g,l);const W=c.push("math_block","math",0);return W.content=xa(I),W.markup=w==="$$"?"$$":w==="["?"[]":"\\[\\]",W.raw=`${w}${I}${I.startsWith(` +`)?` +`:""}${b}`,W.map=[l,D+1],W.block=!0,W.loading=!$,c.line=D+1,B.trim()&&n(c,B,H),!0},i=(r,l,a,u)=>{const c=r,d=c.bMarks[l]+c.tShift[l],f=c.src.slice(d,c.eMarks[l]).trim();return!f.startsWith("$$")&&!f.startsWith("\\[")?!1:s(r,l,a,u)};e.inline.ruler.before("escape","math",o),e.block.ruler.before("lheading","explicit_math_block",i,{alt:["paragraph","reference","blockquote","list"]}),e.block.ruler.before("paragraph","math_block",s,{alt:["paragraph","reference","blockquote","list"]})}function rle(e){const t=e.renderer.rules.image||function(n,o,s,i,r){const l=n,a=r;return a.renderToken?a.renderToken(l,o,s):""};e.renderer.rules.image=(n,o,s,i,r)=>{const l=n;return l[o].attrSet?.("loading","lazy"),t(l,o,s,i,r)},e.renderer.rules.fence=e.renderer.rules.fence||((n,o)=>{const s=n[o],i=String(s.info??"").trim();return`<pre class="${i?`language-${e.utils.escapeHtml(i.split(/\s+/g)[0])}`:""}"><code>${e.utils.escapeHtml(String(s.content??""))}</code></pre>`})}const lle=/^<a[>\s]/i,ale=/^<\/a\s*>/i;function ule(e,t){if(e?.type!=="inline")return!1;const n=e.children;if(!Array.isArray(n)||n.length===0)return t.pretest(String(e.content??""));let o=0;for(let s=n.length-1;s>=0;s--){const i=n[s];if(i?.type==="link_close"){for(s--;s>=0&&n[s]?.level!==i.level&&n[s]?.type!=="link_open";)s--;continue}if(i?.type==="html_inline"){const r=String(i.content??"");lle.test(r)&&o>0&&o--,ale.test(r)&&o++}if(!(o>0)&&i?.type==="text"&&t.pretest(String(i.content??"")))return!0}return!1}function cle(e){const t=e.core?.ruler,n=t.getNamedRules?.().find(o=>o.name==="linkify")?.fn;typeof n=="function"&&t.at("linkify",o=>{if(!o.md?.options?.linkify)return;const s=Array.isArray(o.tokens)?o.tokens:[],i=o.md.linkify;if(!i)return;const r=s.filter(l=>ule(l,i));if(r.length)return n(Object.assign(Object.create(Object.getPrototypeOf(o)),o,{tokens:r}))})}function dle(e){const t=e.inline.ruler,n=t.getNamedRules?.(),o=n?.find(l=>l.name==="link")?.fn,s=n?.find(l=>l.name==="image")?.fn;if(typeof o!="function"||typeof s!="function")return;const i=e.validateLink,r=e;r.__markstreamOriginalValidateLink=i,t.at("link",(...l)=>{const a=l[0].md,u=a?.validateLink===i?a.options?.validateLink:a?.validateLink;if(!a||typeof u!="function")return o(...l);const c=a.validateLink;a.validateLink=u;try{return o(...l)}finally{a.validateLink=c}}),t.at("image",(...l)=>{const a=l[0].md;if(!a)return s(...l);const u=a.validateLink;a.validateLink=i;try{return s(...l)}finally{a.validateLink=u}})}function fle(e={}){const t=e.markdownItOptions??{},n=typeof t.experimental=="object"&&t.experimental!==null?t.experimental:{},o=Object.prototype.hasOwnProperty.call(t,"stream")?!!t.stream:!0,s=Object.prototype.hasOwnProperty.call(t,"validateLink"),i=new Wse({html:!0,linkify:!0,typographer:!0,...t,experimental:{stream:o,...n}});return s||i.set({validateLink:r=>!lc(r,{tagName:"a",attrName:"href"})}),dle(i),cle(i),(e.enableMath??!0)&&ile(i,{...e.mathOptions??{}}),(e.enableContainers??!0)&&aie(i),e.enableFixIndentedCodeBlock!==!1&&Lie(i),cre(i),hre(i),fre(i),yre(i),rle(i),Eie(i,{customHtmlTags:e.customHtmlTags}),i}function ac(e){const t=Object.assign(Object.create(Object.getPrototypeOf(e)),e);return Array.isArray(e.attrs)&&(t.attrs=e.attrs.map(n=>[...n])),Array.isArray(e.map)&&(t.map=[...e.map]),Array.isArray(e.children)&&(t.children=e.children.map(n=>ac(n))),t}function ple(e){const t=e.meta??{};return{type:"checkbox",checked:t.checked===!0,raw:t.checked?"[x]":"[ ]"}}function hle(e){const t=e,n=t.attrGet?t.attrGet("checked"):void 0,o=n===""||n==="true";return{type:"checkbox_input",checked:o,raw:o?"[x]":"[ ]"}}function mle(e){const t=String(e.content??"");return{type:"emoji",name:t,markup:String(e.markup??""),raw:`:${t}:`}}function hh(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="em_close";){const l=e[i];s+=String(e[i].content??l.text??""),r.push(e[i]),i++}return o.push(...$o(r,void 0,void 0,n)),{node:{type:"emphasis",children:o,raw:`*${s}*`},nextIndex:i<e.length?i+1:e.length}}const Iw=/\r?\n[ \t]*`+\s*$/,hL=["diff ","index ","--- ","+++ ","@@ "],gle=/\r?\n/;function vle(e){const t=String(e??"");return t?hL.some(n=>n.startsWith(t)||t.startsWith(n)):!1}function Lw(e,t,n,o){n.length>0&&e.push(...n),o.length>0&&t.push(...o),n.length=0,o.length=0}function $w(e,t){return!t&&e.startsWith(" ")&&!e.startsWith(" ")?` ${e}`:e}function yle(e,t){const n=[],o=[],s=[],i=[],r=e.split(gle),l=/\r?\n$/.test(e),a=r.some(h=>h.startsWith("diff ")||h.startsWith("--- ")||h.startsWith("+++ ")||h.startsWith("@@ ")),u=h=>{const m=h;if(!hL.some(v=>m.startsWith(v)))if(m.startsWith("-")){const v=m.slice(1);s.push($w(v,a))}else if(m.startsWith("+")){const v=m.slice(1);i.push($w(v,a))}else{Lw(n,o,s,i);const v=a&&m.startsWith(" ")?m.slice(1):m;n.push(v),o.push(v)}},c=l?Math.max(0,r.length-1):r.length;for(let h=0;h<c;h++){const m=r[h]??"";!t&&!l&&h===c-1&&vle(m)||u(m)}(t||s.length>0||i.length>0)&&Lw(n,o,s,i);const d=n.join(` +`),f=o.join(` +`);return{original:t&&l&&d?`${d} +`:d,updated:t&&l&&f?`${f} +`:f}}function Qy(e){const t=Array.isArray(e.map)&&e.map.length===2,n=e.meta??{},o=typeof n.closed=="boolean"?n.closed:void 0,s=o===!0||o!==!1&&t,i=String(e.info??""),r=i.startsWith("diff"),l=r?(()=>{const u=i,c=u.indexOf(" ");return c===-1?"":String(u.slice(c+1)??"")})():i;let a=String(e.content??"");if(Iw.test(a)&&(a=a.replace(Iw,"")),r){const{original:u,updated:c}=yle(a,s===!0);return{type:"code_block",language:l,code:String(c??""),raw:String(a??""),diff:r,loading:o===!0?!1:o===!1?!0:!t,originalCode:u,updatedCode:c}}return{type:"code_block",language:l,code:String(a??""),raw:String(a??""),diff:r,loading:o===!0?!1:o===!1?!0:!t}}function kle(e){const t=e.meta??{};return{type:"footnote_reference",id:String(t.label??""),raw:`[^${String(t.label??"")}]`}}function ble(){return{type:"hardbreak",raw:`\\ +`}}function Cle(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="mark_close";)s+=String(e[i].content??""),r.push(e[i]),i++;return o.push(...$o(r,void 0,void 0,n)),{node:{type:"highlight",children:o,raw:`==${s}==`},nextIndex:i<e.length?i+1:e.length}}let F9=null;const R9=new WeakMap;function Nw(){return F9||(F9={customTagSet:null,allowedTagSet:A2()}),F9}function mL(e){const t=e.match(/^<\s*(?:\/\s*)?([\w-]+)/);return t?t[1].toLowerCase():""}function gL(e){return/^<\s*\//.test(e)}function vL(e,t){return/\/\s*>\s*$/.test(t)||eu.has(e)}function wle(e){if(!e||e.length===0)return Nw();const t=R9.get(e);if(t)return t;const n=e.map(Sr).filter(Boolean);if(!n.length){const s=Nw();return R9.set(e,s),s}const o={customTagSet:new Set(n),allowedTagSet:A2({customHtmlTags:e})};return R9.set(e,o),o}function yL(e){const t=e,n=t.raw??t.content??t.markup??"";return String(n??"")}function _le(e){const t=e.meta,n=t?.markstreamCustomHtmlRaw,o=t?.markstreamCustomHtmlInner;return typeof n=="string"&&typeof o=="string"?{raw:n,inner:o}:null}function ng(e,t){const n=t.toLowerCase();for(let o=e.length-1;o>=0;o--){const[s,i]=e[o];if(String(s).toLowerCase()===n)return i}}function xle(e,t,n){const o=e.slice();return ng(o,"href")||o.push(["href",t]),n!=null&&!ng(o,"title")&&o.push(["title",n]),o}function j3(e){return e.map(yL).join("")}function Zh(e){const t=[],n=o=>{const s=String(o??"");if(!s)return;const i=t[t.length-1];if(i?.type==="text"){i.content=`${i.content}${s}`,i.raw=`${i.raw}${s}`;return}t.push({type:"text",content:s,raw:s})};for(const o of e)if(o){if(o.type==="reference"||o.type==="footnote_reference"){n(String(o.raw??""));continue}if("children"in o&&Array.isArray(o.children)){t.push({...o,children:Zh(o.children)});continue}t.push(o)}return t}function Sle(e,t,n){let o=0;for(let s=t;s<e.length;s++){const i=e[s];if(i.type!=="html_inline")continue;const r=String(i.content??""),l=mL(r),a=gL(r),u=vL(l,r);if(!a&&!u&&l===n){o++;continue}if(a&&l===n){if(o===0)return s;o--}}return-1}function O9(e,t,n){const o=[e[t]];let s=[],i=t+1,r=!1;const l=n?Sle(e,t+1,n):-1;return l!==-1?(s=e.slice(t+1,l),o.push(...s,e[l]),i=l+1,r=!0):(s=e.slice(t+1),s.length&&o.push(...s),i=e.length),{closed:r,html:j3(o),innerTokens:s,nextIndex:i}}function Ale(e,t,n,o,s,i,r){const l=String(e.content??""),a=mL(l),{customTagSet:u,allowedTagSet:c}=wle(r?.customHtmlTags);if(!a)return[{type:"inline_code",code:l,raw:l},n+1];if(!c.has(a)&&!O9(t,n,a).closed){const x=yL(e);return[{type:"text",content:x,raw:x},n+1]}if(a==="br")return[{type:"hardbreak",raw:l},n+1];const d=gL(l),f=vL(a,l);if(d)return[{type:"html_inline",tag:a,content:l,children:[],raw:l,loading:!1},n+1];if(a==="a"){const x=O9(t,n,a),S=w2(l),T=x.innerTokens,A=String(ng(S,"href")??""),E=ng(S,"title"),P=E==null?null:String(E),D=xle(S,A,P),I=Zh(T.length?o(T,s,i,r):[]),$=T.length?j3(T):A||"";return!I.length&&$&&I.push({type:"text",content:$,raw:$}),[{type:"link",href:A,title:P,text:$,attrs:D,children:I,loading:!x.closed,raw:x.html||l},x.nextIndex]}if(f)return[{type:u?.has(a)?a:"html_inline",tag:a,content:l,children:[],raw:l,loading:!1},n+1];const h=O9(t,n,a);if(a==="p"||a==="div")return[{type:"paragraph",children:Zh(h.innerTokens.length?o(h.innerTokens,s,i,r):[]),raw:h.html},h.nextIndex];const m=Zh(h.innerTokens.length?o(h.innerTokens,s,i,r):[]);let v=h.html||l,k=!h.closed,w=!1;if(!h.closed){const x=`</${a}>`;v.toLowerCase().includes(x.toLowerCase())||(v+=x),w=!0,k=!0}const b=[],_=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let g;for(;(g=_.exec(l))!==null;){const x=g[1],S=g[2]||g[3]||g[4]||"";b.push([x,S])}if(u?.has(a)){const x=_le(e);return[{type:a,tag:a,attrs:b,content:x?x.inner:h.innerTokens.length?j3(h.innerTokens):"",children:h.innerTokens.length?o(h.innerTokens,s,i,r):[],raw:x?.raw??v,loading:e.loading||k,autoClosed:w},h.nextIndex]}return[{type:"html_inline",tag:a,attrs:b,content:v,children:m,raw:v,loading:k,autoClosed:w},h.nextIndex]}function kL(e){if(e.type==="math_inline"){if(e.raw)return String(e.raw);const t=e.markup==="$$"?"$$":"$";return`${t}${String(e.content??"")}${t}`}return Array.isArray(e.children)&&e.children.length>0?e.children.map(t=>kL(t)).join(""):String(e.content??"")}function Mle(e){return!e||!Array.isArray(e.children)||e.children.length===0?"":e.children.map(t=>kL(t)).join("")}function Fw(e,t=!1){let n=e.attrs??[],o=null;if((!n||n.length===0)&&Array.isArray(e.children))for(const d of e.children){const f=d.attrs;if(Array.isArray(f)&&f.length>0){n=f,o=d;break}}const s=String(n.find(d=>d[0]==="src")?.[1]??""),i=n.find(d=>d[0]==="alt")?.[1],r=Mle(o??e);let l="";r?l=r:i!=null&&String(i).length>0?l=String(i):o?.content!=null&&String(o.content).length>0?l=String(o.content):Array.isArray(o?.children)&&o.children[0]?.content?l=String(o.children[0].content):Array.isArray(e.children)&&e.children[0]?.content?l=String(e.children[0].content):e.content!=null&&String(e.content).length>0&&(l=String(e.content));const a=n.find(d=>d[0]==="title")?.[1]??null,u=a===null?null:String(a),c=String(e.content??"");return{type:"image",src:s,alt:l,title:u,raw:c,loading:t}}function Tle(e){const t=String(e.content??"");return{type:"inline_code",code:t,raw:t}}function Ele(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="ins_close";)s+=String(e[i].content??""),r.push(e[i]),i++;return o.push(...$o(r,void 0,void 0,n)),{node:{type:"insert",children:o,raw:`++${String(s)}++`},nextIndex:i<e.length?i+1:e.length}}function Ile(e){const t=[];if(!Array.isArray(e))return t;for(const n of e){const o=n?.[0];o&&t.push([String(o),String(n?.[1]??"")])}return t}function og(e,t){const n=t.toLowerCase();for(let o=e.length-1;o>=0;o--){const[s,i]=e[o];if(String(s).toLowerCase()===n)return i}}function Lle(e,t,n){const o=e.slice();return og(o,"href")||o.push(["href",t]),n!=null&&!og(o,"title")&&o.push(["title",n]),o}function mh(e,t,n){const o=e[t],s=Ile(o.attrs),i=String(og(s,"href")??""),r=og(s,"title"),l=r==null?null:String(r),a=Lle(s,i,l);let u=t+1;const c=[];let d=!0;for(;u<e.length&&e[u].type!=="link_close";)c.push(e[u]),u++;e[u]?.type==="link_close"&&(d=!1);let f=c;const h=c[c.length-1];if(n?.__insideStrong&&h?.type==="text"&&String(h.content??"").endsWith("**")&&!c.some(k=>k.type==="strong_open")){const k=String(h.content??""),w=String(h.raw??k),b=ac(h);b.content=k.slice(0,-2),b.raw=w.replace(/\*\*$/,""),f=c.slice(),f[f.length-1]=b}const m=$o(f,void 0,void 0,n),v=m.map(k=>{const w=k;return"content"in k?String(w.content??""):String(w.raw??"")}).join("");return{node:{type:"link",href:i,title:l,text:v,children:m,raw:`[${v}](${i}${l?` "${l}"`:""})`,loading:d,attrs:a},nextIndex:u<e.length?u+1:e.length}}function Rw(e){const t=e.content??"",n=e.raw==="$$"?`$${t}$`:e.raw||"";return{type:"math_inline",content:t,loading:!!e.loading,raw:n,markup:e.markup}}function $le(e){return{type:"reference",id:String(e.content??""),raw:String(e.markup??`[${e.content??""}]`)}}function Ow(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="s_close";)s+=String(e[i].content??""),r.push(e[i]),i++;return o.push(...$o(r,void 0,void 0,n)),{node:{type:"strikethrough",children:o,raw:`~~${s}~~`},nextIndex:i<e.length?i+1:e.length}}const Nle=/\\([\\()[\]`$|*_\-!])/g;function Fle(e,t){if(!e)return;const n=String(e);if(n&&(n===t||n.replace(Nle,"$1")===t))return n}function nf(e,t,n,o){const s=[];let i="",r=t+1;const l=[];let a=1;for(;r<e.length;){if(e[r].type==="strong_close"){if(a===1)break;a--}e[r].type==="strong_open"&&a++,i+=String(e[r].content??""),l.push(e[r]),r++}const u={...o,__insideStrong:!0};return s.push(...$o(l,Fle(n,i),void 0,u)),{node:{type:"strong",children:s,raw:`**${String(i)}**`},nextIndex:r<e.length?r+1:e.length}}function Rle(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="sub_close";)s+=String(e[i].content??""),r.push(e[i]),i++;o.push(...$o(r,void 0,void 0,n));const l=String(e[t].content??""),a=s||l;return{node:{type:"subscript",children:o.length>0?o:[{type:"text",content:a,raw:a}],raw:`~${a}~`},nextIndex:i<e.length?i+1:e.length}}function Ole(e,t,n){const o=[];let s="",i=t+1;const r=[];for(;i<e.length&&e[i].type!=="sup_close";)s+=String(e[i].content??""),r.push(e[i]),i++;return o.push(...$o(r,void 0,void 0,n)),{node:{type:"superscript",children:o.length>0?o:[{type:"text",content:s||String(e[t].content??""),raw:s||String(e[t].content??"")}],raw:`^${s||String(e[t].content??"")}^`},nextIndex:i<e.length?i+1:e.length}}function Ple(e){const t=String(e.content??"");return{type:"text",content:t,raw:t}}const Dle=/[^~]*~{2,}[^~]+/,Ble=/\*\*/,Hle=/[[_*^~]/,zle=/\\([\\()[\]`$|*_\-!])/g,e5=new Set(["\\","(",")","[","]","`","$","|","*","_","-","!"]),Wle=/\s/u,Ule=/[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/,jle=/\p{P}/u,Vle=/^[《「『【〔〖〘〚〈([{“‘﹁﹃﹙﹛﹝]$/u,qle=/^[》」』】〕〗〙〛〉)]}”’﹂﹄﹚﹜﹞]$/u,Kle=/^(?:https?:\/\/|mailto:|ftp:\/\/)/i,Zle=/:\/\//,V3=1,bL=2,Gle=4,Yle=8,CL=16,Ea=32,Gh=64,Cf=128,wL=256,Xle=512,wf=1024,Jle=1982;function gh(e){let t=0;for(let n=0;n<e.length;n++)switch(e.charCodeAt(n)){case 33:t|=Cf;break;case 36:t|=wL;break;case 40:t|=wf;break;case 42:t|=bL;break;case 91:t|=Ea;break;case 92:t|=V3;break;case 93:t|=Gh;break;case 95:t|=Gle;break;case 96:t|=CL;break;case 124:t|=Xle;break;case 126:t|=Yle;break}return t}function Qle(e){let t=0,n=0;for(;n<e.length;){if(e[n]==="\\"&&n+1<e.length&&e[n+1]==="*"){n+=2;continue}e[n]==="*"&&t++,n++}return t}function _L(e,t=0){if(!e)return-1;let n=0;for(let o=0;o<e.length;o++){const s=e[o],i=e[o+1];if(s==="\\"&&i&&e5.has(i)){if(i==="*"&&n>=t){n++,o++;continue}n++,o++;continue}if(s==="*"&&n>=t)return n;n++}return-1}function tu(e){return!!e&&Wle.test(e)}function nu(e){return!!e&&(Ule.test(e)||jle.test(e))}function xL(e,t){return!!e&&!!t&&/^\p{Script=Han}$/u.test(t)&&Vle.test(e)}function SL(e,t){return!!e&&!!t&&/^[\p{L}\p{N}]$/u.test(t)&&qle.test(e)}function eae(e,t){const n=t>0?e[t-1]:void 0,o=e[t+1];return!o||tu(o)?!1:!(nu(o)&&!xL(o,n)&&n&&!tu(n)&&!nu(n))}function tae(e,t){const n=t>0?e[t-1]:void 0,o=e[t+1];return!n||tu(n)?!1:!(nu(n)&&!SL(n,o)&&o&&!tu(o)&&!nu(o))}function nae(e,t,n=0){let o=n,s=!1;for(;o<t.length;){const i=e?_L(e,o):t.indexOf("*",o);if(i===-1)break;if(tae(t,i))return{index:i,sawInvalidClose:s};s=!0,o=i+1}return{index:-1,sawInvalidClose:s}}function oae(e,t){const n=t>0?e[t-1]:void 0,o=e[t+2];return!o||tu(o)?!1:!(nu(o)&&!xL(o,n)&&n&&!tu(n)&&!nu(n))}function sae(e,t){const n=t>0?e[t-1]:void 0,o=e[t+2];return!n||tu(n)?!1:!(nu(n)&&!SL(n,o)&&o&&!tu(o)&&!nu(o))}function iae(e,t=0){let n=t,o=!1;for(;n<e.length;){const s=e.indexOf("**",n);if(s===-1)break;if(sae(e,s))return{index:s,sawInvalidClose:o};o=!0,n=s+2}return{index:-1,sawInvalidClose:o}}function rae(e){let t="",n=0;for(;n<e.length;){if(e[n]!=="\\"){t+=e[n],n++;continue}let o=0;for(;n+o<e.length&&e[n+o]==="\\";)o++;const s=e[n+o];if(t+="\\".repeat(Math.floor(o/2)),o%2===1){if(s&&e5.has(s)){t+=s,n+=o+1;continue}t+="\\"}n+=o}return t}function lae(e,t){let n=0;for(let o=0;o<e.length;o++){const s=e[o],i=e[o+1];if(s==="\\"&&i&&e5.has(i)){if(n===t)return o+1;n++,o++;continue}if(n===t)return o;n++}return-1}function aae(e,t,n){const o=lae(e,t);if(o===-1||e[o]!==n)return!1;let s=0;for(let i=o-1;i>=0&&e[i]==="\\";i--)s++;return s%2===1}const uae=/[\p{L}\p{N}]/u,cae=/^[\p{L}\p{N}]+$/u;function q3(e){return e?uae.test(e):!1}function AL(e){return e?cae.test(e):!1}function Vf(e,t){let n=t;for(;n<e.length&&e[n]==="*";)n++;const o=t>0?e[t-1]:void 0,s=n<e.length?e[n]:void 0;return{len:n-t,prev:o,next:s,intraword:q3(o)&&q3(s)}}function dae(e){const t=[];for(let n=0;n<e.length;){if(e[n]!=="*"){n++;continue}const o=Vf(e,n),s=n+o.len;o.len>=2&&o.intraword&&t.push({start:n,end:s}),n=s}for(let n=0;n<t.length-1;n++){const o=t[n],s=t[n+1];if(!AL(e.slice(o.end,s.start)))return s.end}return-1}function fae(e){return!!e&&e.trim()===e&&/^[\p{L}\p{N}\s]+$/u.test(e)}function pae(e,t){let n=t;for(;n<e.length;){const o=e.indexOf("***",n);if(o===-1)return-1;const s=Vf(e,o);if(s.len>=3)return o;n=o+s.len}return-1}function hae(e){return e?Kle.test(e)||Zle.test(e):!1}function mae(e,t){if(!e||!t)return null;const n=e.match(/\[([^\]\n]+)\]\(([^)]*)$/);return n&&n[2]===t?n[1]:null}function $o(e,t,n,o){if(!e||e.length===0)return[];const s=o?.__linkifyDemotionContext,i=Gp(t),r={filename:s?.filename||i.filename,explicitFilename:s?.explicitFilename||i.explicitFilename,marketTicker:s?.marketTicker||i.marketTicker};(r.filename||r.explicitFilename||r.marketTicker)&&(o={...o,__linkifyDemotionContext:r});const l=o,a=[];let u=null,c=0;const d=o?.requireClosingStrong,f=e;function h(){return e===f&&(e=e.slice()),e}function m(){u=null}function v(oe,ye){const G=e.length===1?t:String(ye.content??""),Y=[],fe=dae(oe);if(fe!==-1){x(oe.slice(0,fe),oe.slice(0,fe));const ge=oe.slice(fe);return ge&&(D({type:"text",content:ge,raw:ge}),c--),c++,!0}if(Dle.test(oe)){const ge=oe.indexOf("~~");ge!==-1&&Y.push({type:"strikethrough",index:ge})}if(Ble.test(oe)){const ge=oe.indexOf("**");ge!==-1&&Y.push({type:"strong",index:ge})}if(/[^*]*\*[^*]+/.test(oe)){const ge=G?_L(G,0):oe.indexOf("*");if(G&&ge===-1)return!1;ge!==-1&&Y.push({type:"emphasis",index:ge})}Y.sort((ge,Q)=>ge.index!==Q.index?ge.index-Q.index:ge.type===Q.type?0:ge.type==="strong"?-1:Q.type==="strong"?1:0);const we=Y[0];if(!we)return!1;if(we.type==="strikethrough"){const ge=we.index,Q=ge>-1?oe.slice(0,ge):"";if(Q&&x(Q,Q),ge===-1)return c++,!0;const te=oe.indexOf("~~",ge+2),ce=te===-1?oe.slice(ge+2):oe.slice(ge+2,te),ue=te===-1?"":oe.slice(te+2),{node:Se}=Ow([{type:"s_open",tag:"s",content:"",markup:"~~",info:"",meta:null},{type:"text",tag:"",content:ce,markup:"",info:"",meta:null},{type:"s_close",tag:"s",content:"",markup:"~~",info:"",meta:null}],0,o);return m(),g(Se),ue&&(D({type:"text",content:ue,raw:ue}),c--),c++,!0}if(we.type==="strong"){const ge=we.index,Q=ge>-1?oe.slice(0,ge):"";if(Q&&x(Q,Q),ge===-1)return c++,!0;if(t&&ge===0){let _e=!1,Ee=0;for(;Ee<oe.length&&oe[Ee]==="*";)Ee++;if(t.startsWith("\\*")&&(_e=!0),_e){let it=0,Fe=0;for(;Fe<t.length&&it<Ee;)if(t[Fe]==="\\"&&Fe+1<t.length&&t[Fe+1]==="*")it+=1,Fe+=2;else{if(t[Fe]==="*")break;Fe++}if(it>=2)return x(oe,oe),c++,!0}}if(t&&(oe.match(/\*/g)||[]).length>Qle(t))return x(oe.slice(Q.length),oe.slice(Q.length)),c++,!0;const te=Vf(oe,ge);if(te.len>=3){const _e=pae(oe,ge+te.len);if(_e!==-1){const Ee=oe.slice(ge+te.len,_e);if(fae(Ee)){const{node:it}=nf([{type:"strong_open",tag:"strong",content:"",markup:"**",info:"",meta:null},{type:"em_open",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"text",tag:"",content:Ee,markup:"",info:"",meta:null},{type:"em_close",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"strong_close",tag:"strong",content:"",markup:"**",info:"",meta:null}],0,t,o);m(),g(it);const Fe=oe.slice(_e+3);return Fe&&(D({type:"text",content:Fe,raw:Fe}),c--),c++,!0}}}if(!oae(oe,ge)){const _e=oe.slice(ge,ge+te.len);x(_e,_e);const Ee=oe.slice(ge+te.len);return Ee&&(D({type:"text",content:Ee,raw:Ee}),c--),c++,!0}const ce=iae(oe,ge+2);let ue="",Se="";if(ce.index!==-1){ue=oe.slice(ge+2,ce.index),Se=oe.slice(ce.index+2);const _e=ce.index,Ee=Vf(oe,_e);if(te.intraword&&Ee.intraword&&!AL(ue)||!ue&&te.len>=4&&te.intraword)return x(oe.slice(Q.length),oe.slice(Q.length)),c++,!0}else{if(d||ce.sawInvalidClose||te.intraword)return x(oe.slice(Q.length),oe.slice(Q.length)),c++,!0;ue=oe.slice(ge+2),Se=""}if(!ue&&/^\*+$/.test(Se))return x(oe,oe),c++,!0;const{node:ze}=nf([{type:"strong_open",tag:"strong",content:"",markup:"**",info:"",meta:null},{type:"text",tag:"",content:ue,markup:"",info:"",meta:null},{type:"strong_close",tag:"strong",content:"",markup:"**",info:"",meta:null}],0,t,o);return m(),g(ze),Se&&(D({type:"text",content:Se,raw:Se}),c--),c++,!0}if(we.type==="emphasis"){let ge=we.index;ge===-1&&(ge=0);const Q=oe.slice(0,ge);if(Q&&x(Q,Q),!eae(oe,ge)){x(oe[ge],oe[ge]);const _e=oe.slice(ge+1);return _e&&(D({type:"text",content:_e,raw:_e}),c--),c++,!0}const te=Vf(oe,ge),ce=nae(G,oe,ge+1),ue=ce.index,Se=e[c+1];if(o?.final&&Se?.type==="em_open"&&ue!==-1&&oe.slice(ge+1,ue).trim()!==oe.slice(ge+1,ue)||ue===-1&&(ce.sawInvalidClose||o?.final||te.intraword||!q3(oe[ge+1])))return x(oe.slice(ge),oe.slice(ge)),c++,!0;const{node:ze}=hh([{type:"em_open",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"text",tag:"",content:ue>-1?oe.slice(ge+1,ue):oe.slice(ge+1),markup:"",info:"",meta:null},{type:"em_close",tag:"em",content:"",markup:"*",info:"",meta:null}],0,o);if(m(),g(ze),ue!==-1&&ue<oe.length-1){const _e=oe.slice(ue+1);_e&&(D({type:"text",content:_e,raw:_e}),c--)}return c++,!0}return!1}function k(oe,ye){if(!oe.includes("`"))return!1;const Y=(Se=>{for(let ze=0;ze<Se.length;ze++){if(Se[ze]!=="`")continue;let _e=0;for(let Ee=ze-1;Ee>=0&&Se[Ee]==="\\";Ee--)_e++;if(_e%2===0)return ze}return-1})(oe);if(Y===-1)return!1;let fe=1;for(let Se=Y+1;Se<oe.length&&oe[Se]==="`";Se++)fe++;const we="`".repeat(fe),ge=Y+fe,Q=oe.indexOf(we,ge);if(Q===-1){if(fe===1){const ze=oe.slice(0,Y),_e=oe.slice(Y+1);return ze&&(v(ze,ye)?c--:x(ze,ze)),b({type:"inline_code",code:_e,raw:String(_e)}),c++,!0}let Se=oe;for(let ze=c+1;ze<e.length;ze++)Se+=String((e[ze].content??"")+(e[ze].markup??""));return c=e.length-1,x(Se,Se),c++,!0}m();const te=oe.slice(0,Y),ce=oe.slice(Y+fe,Q),ue=oe.slice(Q+fe);return te&&(v(te,ye)?c--:x(te,te)),b({type:"inline_code",code:ce,raw:String(ce??"")}),ue&&(D({type:"text",content:ue,raw:ue}),c--),c++,!0}function w(oe){const ye=l?.__markdownIt;if(!ye||e.length<=1||!e.some(we=>we?.type==="math_inline")||!Hle.test(oe))return null;const G=ye.parseInline(oe,{__markstreamFinal:!!o?.final});if(!Array.isArray(G)||G.length===0)return null;const Y=(G.find(we=>we?.type==="inline")?.children??[]).filter(we=>!(we?.type==="text"&&String(we.content??"")===""));if(!Y.length||!Y.some(we=>we?.type!=="text")||Y.length===1&&Y[0]?.type==="text"&&String(Y[0].content??"")===oe)return null;const fe=$o(Y,oe,n,o);return fe.length?fe:null}function b(oe){m(),a.push(oe)}function _(oe){m();const ye=ac(oe);a.push(ye)}function g(oe){b(oe)}function x(oe,ye){u?(u.content+=oe,u.raw+=ye??oe):(u={type:"text",content:String(oe??""),raw:String(ye??oe??"")},a.push(u))}function S(oe,ye){if(!oe)return;const G=$o([{...ye,type:"text",content:oe,raw:oe}],oe,n,o);if(G.length===1&&G[0]?.type==="text"){const Y=G[0];x(String(Y.content??""),String(Y.raw??Y.content??""));return}for(const Y of G)g(Y)}function T(oe,ye){return String(oe.markup??"").startsWith(ye)}function A(oe){if(!u||oe.loading!==!0||oe.markup!=="\\(\\)")return;const ye=e[c-1];!ye||ye.type!=="text"||!T(ye,"\\(")||u.content.endsWith("(")&&(u.content=u.content.slice(0,-1),u.raw.endsWith("(")&&(u.raw=u.raw.slice(0,-1)),!u.content&&a[a.length-1]===u&&(a.pop(),u=null))}function E(oe){return oe.endsWith("](")?e[c+1]?.type==="link_open"&&e[c+1]?.markup==="linkify"&&e[c+2]?.type==="text"&&e[c+3]?.type==="link_close"&&e[c+4]?.type==="text"&&String(e[c+4]?.content??"").startsWith(")"):!1}function P(oe,ye,G=gh(oe)){let Y=oe;const fe=String(ye.content??"");return(G&V3)!==0&&Y.endsWith("\\")&&!T(ye,"\\\\")&&!fe.endsWith("\\\\")&&(Y=Y.slice(0,-1)),(G&wf)!==0&&Y.endsWith("(")&&!T(ye,"\\(")&&!fe.endsWith("\\(")&&(Y=Y.slice(0,-1)),(G&bL)!==0&&/\*+$/.test(Y)&&!T(ye,"\\*")&&!fe.endsWith("\\*")&&(Y=Y.replace(/\*+$/,"")),Y}for(;c<e.length;){const oe=e[c];D(oe)}function D(oe){switch(oe.type){case"text":$(oe);break;case"softbreak":u?(u.content+=` +`,u.raw+=` +`):(u={type:"text",content:` +`,raw:` +`},a.push(u)),c++;break;case"code_inline":g(Tle(oe)),c++;break;case"html_inline":{const[ye,G]=Ale(oe,e,c,$o,t,n,o);g(ye),c=G;break}case"link_open":B(oe);break;case"image":ne(oe)||(m(),g(Fw(oe)),c++);break;case"strong_open":{m();const{node:ye,nextIndex:G}=nf(e,c,oe.content,o);g(ye),c=G;break}case"em_open":{m();const{node:ye,nextIndex:G}=hh(e,c,o);g(ye),c=G;break}case"s_open":{m();const{node:ye,nextIndex:G}=Ow(e,c,o);g(ye),c=G;break}case"mark_open":{m();const{node:ye,nextIndex:G}=Cle(e,c,o);g(ye),c=G;break}case"ins_open":{m();const{node:ye,nextIndex:G}=Ele(e,c,o);g(ye),c=G;break}case"sub_open":{m();const{node:ye,nextIndex:G}=Rle(e,c,o);g(ye),c=G;break}case"sup_open":{m();const{node:ye,nextIndex:G}=Ole(e,c,o);g(ye),c=G;break}case"sub":m(),g({type:"subscript",children:[{type:"text",content:String(oe.content??""),raw:String(oe.content??"")}],raw:`~${String(oe.content??"")}~`}),c++;break;case"sup":m(),g({type:"superscript",children:[{type:"text",content:String(oe.content??""),raw:String(oe.content??"")}],raw:`^${String(oe.content??"")}^`}),c++;break;case"emoji":{m();const ye=e[c-1];ye?.type==="text"&&/\|:-+/.test(String(ye.content??""))?x("",""):g(mle(oe)),c++;break}case"checkbox":m(),g(ple(oe)),c++;break;case"checkbox_input":m(),g(hle(oe)),c++;break;case"footnote_ref":m(),g(kle(oe)),c++;break;case"footnote_anchor":{m();const ye=oe.meta??{};b({type:"footnote_anchor",id:String(ye.label??oe.content??""),raw:String(oe.content??"")}),c++;break}case"hardbreak":m(),g(ble()),c++;break;case"fence":m(),g(Qy(e[c])),c++;break;case"math_inline":A(oe),m(),!oe.content&&oe.markup==="$"&&e[c+1]?.type==="text"&&e[c+2]?.type==="math_inline"?(g(Rw({...oe,content:e[c+1].content})),c+=2):g(Rw(oe)),c++;break;case"reference":O(oe);break;case"text_special":x(String(oe.content??""),String(oe.content??"")),c++;break;default:{const ye=oe;if(oe.type==="link"&&ye.href!=null&&o?.validateLink&&!o.validateLink(String(ye.href))){m();const G=String(ye.text??"");x(G,G),c++}else X(oe)||U(oe)||W(oe)||F(oe)||_(oe),c++;break}}}function I(oe,ye,G,Y,fe=gh(oe)){const we=Ple({...ye,content:oe});if(u){u.content+=P(we.content,ye,fe),u.raw+=we.raw;return}const ge=G?.tag==="br"&&e[c-2]?.content==="[";Y||(we.content=P(we.content,ye,fe)),u=we,u.center=ge,a.push(u)}function $(oe){const ye=String(oe.content??""),G=gh(ye),Y=(G&V3)!==0,fe=e.length===1&&Y&&typeof t=="string"?String(t):"";let we=fe?rae(fe):Y?ye.replace(zle,"$1"):ye;const ge=we===ye?G:gh(we);if(oe.content==="<"||we==="1"&&e[c-1]?.tag==="br"){c++;return}const Q=(ge&wL)!==0?we.indexOf("$"):-1;Q!==-1&&Q===we.lastIndexOf("$")&&we.endsWith("$")&&(we=we.slice(0,-1)),we.endsWith("undefined")&&!t?.endsWith("undefined")&&(we=we.slice(0,-9));let te=a.length,ce="";for(let _e=a.length-1;_e>=0;_e--){const Ee=a[_e];if(Ee.type!=="text")break;te=_e,ce=String(Ee.content??"")+ce}te<a.length&&(we.startsWith(ce)?(u=null,a.length=te):u=a[a.length-1]);const ue=e[c+1];if((we==="`"||we==="|"||we==="$")&&!T(oe,`\\${we}`)||/^\*+$/.test(we)&&!T(oe,"\\*")){c++;return}if(!ue&&(ge&wf)!==0&&/[^\]]\s*\(\s*$/.test(we)&&(we=we.replace(/\(\s*$/,"")),!we){c++;return}if((ge&(Ea|Cf))===(Ea|Cf)&&ie(we)||(ge&(Gh|wf))===(Gh|wf)&&le(we))return;if((ge&Jle)===0){I(we,oe,e[c-1],ue,ge),c++;return}if((ge&Ea)!==0&&ve(we))return;const Se=e[c-1];if((ge&Ea)!==0&&we==="["&&!ue?.markup?.includes("*")&&!T(oe,"\\[")||(ge&Gh)!==0&&we==="]"&&!Se?.markup?.includes("*")&&!T(oe,"\\]")){c++;return}if((ge&CL)!==0&&k(ye,oe)||(ge&(Cf|Ea))===(Cf|Ea)&&pe(we)||(ge&Ea)!==0&&(e[c+1]?.type!=="link_open"||E(we))&&de(we,oe))return;const ze=w(ye);if(ze){m();for(const _e of ze)g(_e);c++;return}v(we,oe)||(I(we,oe,Se,ue,ge),c++)}function B(oe){if(H(oe))return;if(Ie()){const{node:Q,nextIndex:te}=mh(e,c,o),ce=String(Q.text||Q.href||"");x(ce,ce),c=te;return}m();const{node:ye,nextIndex:G}=mh(e,c,o);c=G;const Y=ye.text||ye.href||"";if(oe.markup==="linkify"&&!tL(Y,ye.href,t)&&Qm(Y,l?.__linkifyDemotionContext)){x(Y,Y);return}const fe=ye.children.length===1&&ye.children[0]?.type==="text";if(ye.loading&&t&&ye.text===ye.href&&fe){const Q=mae(t,ye.href);Q&&(ye.text=Q,ye.children=[{type:"text",content:Q,raw:Q}],ye.raw=`[${Q}](${ye.href}${ye.title?` "${ye.title}"`:""})`)}if(o?.validateLink&&!o.validateLink(ye.href)){x(ye.text,ye.text);return}const we=oe.attrs?.find(([Q])=>Q==="href")?.[1],ge=String(we??"");if(t&&ge){const Q=t.indexOf("](");if(Q!==-1){const te=t.indexOf(")",Q+2);te===-1?ye.loading=!0:ye.loading&&t.slice(Q+2,te).includes(ge)&&(ye.loading=!1)}}F(ye)||b(ye)}function H(oe){if(oe.markup!=="linkify")return!1;const{node:ye,nextIndex:G}=mh(e,c,o);return z(ye,G)?(c=G,!0):!1}function O(oe){m(),g($le(oe)),c++}function F(oe){if(oe.type!=="link")return!1;const ye=a[a.length-1];if(!ye||ye.type!=="text")return!1;const G=String(ye.content??"").match(/^([^[]*)\[([^\]\n]+)\]\($/);if(!G)return!1;const Y=oe,fe=String(Y.href??""),we=String(Y.text??""),ge=String(G[2]??""),Q=fe.replace(/^(?:https?:\/\/|mailto:|ftp:\/\/)/i,"");if(!fe||!(we===fe||we===Q||hae(we)))return!1;const te=String(G[1]??"");return te?(ye.content=te,ye.raw=te):a.pop(),b({...oe,text:ge,children:[{type:"text",content:ge,raw:ge}],raw:`[${ge}](${fe}${Y.title?` "${Y.title}"`:""})`}),!0}function U(oe){if(oe.type!=="link")return!1;const ye=oe,G=String(ye.href??"");return G?z({href:G,title:ye.title==null||ye.title===""?null:String(ye.title),loading:!!ye.loading},c+1):!1}function z(oe,ye){const G=a[a.length-1];if(G?.type!=="image"||G.src||!G.loading||!String(G.raw??"").endsWith("]("))return!1;const Y=e[ye],fe=String(Y?.content??"");if(Y?.type!=="text"||!fe.startsWith(")"))return!1;a.pop(),u=null;const we=String(G.alt??"");b({type:"image",src:oe.href,alt:we,title:oe.title,raw:`![${we}](${oe.href}${oe.title?` "${oe.title}"`:""})`,loading:!!oe.loading});const ge=fe.slice(1),Q=ac(Y);return Q.content=ge,Q.raw=ge,h()[ye]=Q,!0}function W(oe){if(oe.type!=="link")return!1;const ye=a[a.length-1],G=e[c-1];if(!ye||ye.type!=="text"||G?.type!=="text")return!1;const Y=String(ye.content??""),fe=String(G.content??"");if(!Y.endsWith("!")||!fe.endsWith("!")||T(G,"\\!"))return!1;const we=Y.slice(0,-1);we?(ye.content=we,ye.raw=we,u=ye):(a.pop(),u=null);const ge=oe,Q=String(ge.text??ge.children?.map(ue=>String(ue?.content??ue?.raw??"")).join("")??""),te=String(ge.href??""),ce=ge.title==null||ge.title===""?null:String(ge.title);return b({type:"image",src:te,alt:Q,title:ce,raw:`![${Q}](${te}${ce?` "${ce}"`:""})`,loading:!!ge.loading}),!0}function K(oe,ye="",G=null){const Y=String(oe.alt??oe.raw??"");return{type:"link",href:ye,title:G,text:Y,children:[oe],raw:`[${Y}](${ye}${G?` "${G}"`:""})`,loading:!0}}function V(oe){const ye=oe.startsWith("![")?oe:`![${oe}`,G=ye.slice(2),Y=G.indexOf("](");return{type:"image",src:"",alt:Y===-1?G.replace(/\]$/,""):G.slice(0,Y),title:null,raw:ye,loading:!0}}function ie(oe){const ye=oe.indexOf("[![");if(ye===-1||typeof t=="string"&&e.length===1&&aae(t,ye,"["))return!1;const G=oe.slice(0,ye);return G&&x(G,G),b(K(V(oe.slice(ye+1)))),c++,!0}function ne(oe){if(o?.final)return!1;const ye=e[c-1];if(ye?.type!=="text"||!String(ye.content??"").endsWith("[")||T(ye,"\\["))return!1;const G=a[a.length-1];if(G?.type==="text"&&G.content.endsWith("[")){const Y=G.content.slice(0,-1);Y?(G.content=Y,G.raw=Y,u=G):(a.pop(),u=null)}return b(K(Fw(oe))),c++,!0}function X(oe){if(oe.type!=="link")return!1;const ye=oe,G=String(ye.raw??""),Y=String(ye.text??"");if(!G.startsWith("[![")&&!Y.startsWith("!["))return!1;const fe=ye.title==null||ye.title===""?null:String(ye.title);return b(K({type:"image",src:String(ye.href??""),alt:Y.replace(/^!\[/,"").replace(/\]$/,""),title:fe,raw:G.startsWith("[![")?G.slice(1):G,loading:!0})),!0}function le(oe){if(!oe.startsWith("]("))return!1;const ye=e[c-2];if(ye?.type==="text"&&String(ye.content??"").endsWith("[")&&T(ye,"\\["))return!1;const G=a[a.length-1];if(G?.type!=="image"&&G?.type!=="link")return!1;const Y=G,fe=G?.type==="link"&&Array.isArray(Y.children)&&Y.children.length===1&&Y.children[0]?.type==="image"?a.pop():null,we=fe?fe.children[0]:a.pop();if(!we||we.type!=="image")return!1;const ge=e[c+1];let Q=String(fe?.href??""),te=fe?.title==null?null:String(fe.title),ce=!0;if(ge?.type==="link_open"){const{node:Se,nextIndex:ze}=mh(e,c+1,o);Q=Se.href,te=Se.title,ce=!0,c=ze}else{if(Q=oe.slice(2),Q.includes('"')){const Se=Q.split('"');Q=String(Se[0]??"").trim(),te=Se[1]==null?null:String(Se[1]).trim()}c++}const ue=K(we,Q,te);return ue.loading=ce,b(ue),!0}function Ie(){const oe=e[c-3];return e[c-2]?.type==="image"&&e[c-1]?.type==="text"&&String(e[c-1].content??"")==="]("&&oe?.type==="text"&&String(oe.content??"").endsWith("[")&&T(oe,"\\[")}function de(oe,ye){const G=oe.indexOf("[");if(G===-1)return!1;let Y=oe.slice(0,G);const fe=oe.indexOf("](",G);if(fe!==-1){const we=e[c+2];let ge=oe.slice(G+1,fe);if(ge.includes("[")){const _e=ge.indexOf("[");Y+=oe.slice(0,G+_e+1);const Ee=G+_e+1;ge=oe.slice(Ee+1,fe)}const Q=e[c+1];if(oe.endsWith("](")&&Q?.type==="link_open"&&we){const _e=e[c+4];let Ee=4,it=!0;if(_e?.type==="text"){const Oe=String(_e.content??"");if(Oe.startsWith(")")){it=!1;const Ge=Oe.slice(1);if(Ge){const at=ac(_e);at.content=Ge,at.raw=Ge,h()[c+4]=at}else Ee++}else Oe==="."&&Ee++}S(Y,ye);const Fe=String(we.content??"");return o?.validateLink&&!o.validateLink(Fe)?x(ge,ge):b({type:"link",href:Fe,title:null,text:ge,children:[{type:"text",content:ge,raw:ge}],loading:it}),c+=Ee,!0}const te=oe.indexOf(")",fe),ce=te!==-1?oe.slice(fe+2,te):"",ue=te===-1;let Se=Y.match(/\*+$/);if(Se&&(Y=Y.replace(/\*+$/,"")),S(Y,ye),Se||(Se=ge.match(/^\*+/)),!d&&Se){const _e=Se[0].length;ge=ge.replace(/^\*+/,"").replace(/\*+$/,"");const Ee=[];if(_e===1?Ee.push({type:"em_open",tag:"em",nesting:1}):_e===2?Ee.push({type:"strong_open",tag:"strong",nesting:1}):_e===3&&(Ee.push({type:"strong_open",tag:"strong",nesting:1}),Ee.push({type:"em_open",tag:"em",nesting:1})),Ee.push({type:"link",href:ce,title:null,text:ge,children:[{type:"text",content:ge,raw:ge}],loading:ue}),_e===1){Ee.push({type:"em_close",tag:"em",nesting:-1});const{node:it}=hh(Ee,0,o);g(it)}else if(_e===2){Ee.push({type:"strong_close",tag:"strong",nesting:-1});const{node:it}=nf(Ee,0,void 0,o);g(it)}else if(_e===3){Ee.push({type:"em_close",tag:"em",nesting:-1}),Ee.push({type:"strong_close",tag:"strong",nesting:-1});const{node:it}=nf(Ee,0,void 0,o);g(it)}else{const{node:it}=hh(Ee,0,o);g(it)}}else o?.validateLink&&!o.validateLink(ce)?x(ge,ge):b({type:"link",href:ce,title:null,text:ge,children:[{type:"text",content:ge,raw:ge}],loading:ue});const ze=te!==-1?oe.slice(te+1):"";return ze&&(D({type:"text",content:ze,raw:ze}),c--),c++,!0}return!1}function pe(oe){const ye=oe.indexOf("![");if(ye===-1)return!1;const G=oe.slice(0,ye);return G&&!u?u={type:"text",content:G,raw:G}:G&&u&&(u.content+=G),u&&(a.push(u),u=null),b(V(oe.slice(ye))),c++,!0}function ve(oe){if(!(oe?.startsWith("[")&&n?.type==="list_item_open"))return!1;const ye=oe.slice(1).match(/[^\s\]]/);if(ye===null)return c++,!0;if(ye&&/x/i.test(ye[0])){const G=ye[0]==="x"||ye[0]==="X";return b({type:"checkbox_input",checked:G,raw:G?"[x]":"[ ]"}),c++,!0}return!1}return a}function t5(e,t,n){const o=n?.__sourceLineMapper;if(!o)return{startLine:e,endLine:t};const s=o(e),i=t>e?o(t-1).endLine:o(t).startLine;return{startLine:s.startLine,endLine:Math.max(s.startLine,i)}}function Pw(e,t){const n=Math.max(0,Math.min(e.length,Math.trunc(t)));let o=0;for(let s=0;s<n;s++)e[s]===` +`&&o++;return o}function gae(e,t,n){const o=Math.max(0,Math.min(e.length,Math.trunc(t))),s=Math.max(o,Math.min(e.length,Math.trunc(n))),i=Pw(e,o);let r=Pw(e,s);return s>o&&e[s-1]!==` +`&&r++,{startLine:i,endLine:r}}function Ep(e,t,n,o){const s=gae(e,t,n);return t5(s.startLine,s.endLine,o)}function vae(e,t){const n=e?.map;if(!Array.isArray(n)||n.length<2)return null;const o=Number(n[0]),s=Number(n[1]);return!Number.isFinite(o)||!Number.isFinite(s)?null:t5(o,s,t)}function Dn(e,t,n){if(!n?.includeSourceMap)return e;const o=vae(t,n);if(!o)return e;if(e.sourceMap=o,e.type==="code_block"){const s=e;s.startLine=o.startLine,s.endLine=o.endLine}return e}function yae(e,t,n,o){if(!o?.includeSourceMap)return e;const s=t?.map;if(!Array.isArray(s)||s.length<2)return e;const i=Number(s[0]),r=Number(s[1]),l=Number(n);return!Number.isFinite(i)||!Number.isFinite(r)||!Number.isFinite(l)||(e.sourceMap=t5(i,Math.max(r,l),o)),e}function kae(e){const t=String(e.content??""),n=t.replace(/[ \t\r\n]+$/g,"");if(n===t)return;e.content=n;const o=e.children;if(!(!Array.isArray(o)||o.length===0))for(;o.length;){const s=o[o.length-1];if(!s){o.pop();continue}if(s.type==="softbreak"||s.type==="hardbreak"){o.pop();continue}if(s.type==="text"){const i=String(s.content??""),r=i.replace(/[ \t\r\n]+$/g,"");if(r===i)break;if(r){s.content=r;break}o.pop();continue}break}}function bae(e){const t=String(e.content??""),n=t.match(/\r?\n\s*\d+[.)]?\s*$/);if(!n||typeof n.index!="number")return;e.content=t.slice(0,n.index);const o=e.children;if(!(!Array.isArray(o)||o.length===0))for(;o.length;){const s=o[o.length-1];if(!s){o.pop();continue}if(s.type==="softbreak"||s.type==="hardbreak"){o.pop();continue}if(s.type==="text"){const i=String(s.content??"");if(/^[ \t\r\n\d.)]*$/.test(i)){o.pop();continue}const r=i.replace(/[ \t\r\n\d.)]+$/g,"");r!==i&&(r?s.content=r:o.pop())}break}}function Cae(e){const t=String(e.content??"");return/[ \t\r\n]+$/.test(t)||/\r?\n\s*\d+[.)]?\s*$/.test(t)}function b1(e,t,n){const o=e[t],s=[],i=fu(n,!0);let r=t+1;for(;r<e.length&&e[r].type!=="bullet_list_close"&&e[r].type!=="ordered_list_close";)if(e[r].type==="list_item_open"){const a=[];let u=r+1;for(;u<e.length&&e[u].type!=="list_item_close";)if(e[u].type==="paragraph_open"){const d=e[u+1],f=Cae(d)?ac(d):d,h=e[u-1];f!==d&&(bae(f),kae(f));const m=String(f.content??""),v={type:"paragraph",children:$o(f.children||[],m,h,i.options()),raw:m};n?.includeSourceMap&&Dn(v,e[u],n),a.push(v),i.remember(m),u+=3}else if(e[u].type==="blockquote_open"){const[d,f]=C1(e,u,i.options());a.push(d),i.remember(d.raw),u=f}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[d,f]=b1(e,u,i.options());a.push(d),i.remember(d.raw),u=f}else{const d=o5(e,u,i.options(),n5);d?(a.push(d[0]),i.remember(d[0].raw),u=d[1]):u+=1}const c={type:"list_item",children:a,raw:a.map(d=>d.raw).join("")};n?.includeSourceMap&&Dn(c,e[r],n),s.push(c),r=u+1}else r+=1;const l={type:"list",ordered:o.type==="ordered_list_open",start:(()=>{if(o.attrs&&o.attrs.length){const a=o.attrs.find(u=>u[0]==="start");if(a){const u=Number(a[1]);return Number.isFinite(u)&&u!==0?u:1}}})(),items:s,raw:s.map(a=>a.raw).join(` +`)};return n?.includeSourceMap&&Dn(l,o,n),[l,r+1]}function wae(e,t,n,o){const s=String(n[1]??"note"),i=String(n[2]??s.charAt(0).toUpperCase()+s.slice(1)),r=[],l=fu(o,!0);let a=t+1;for(;a<e.length&&e[a].type!=="container_close";)if(e[a].type==="paragraph_open"){const u=e[a+1];if(u){const c={type:"paragraph",children:$o(u.children||[],String(u.content??""),void 0,l.options()),raw:String(u.content??"")};o?.includeSourceMap&&Dn(c,e[a],o),r.push(c),l.remember(c.raw)}a+=3}else if(e[a].type==="bullet_list_open"||e[a].type==="ordered_list_open"){const[u,c]=b1(e,a,l.options());o?.includeSourceMap&&Dn(u,e[a],o),r.push(u),l.remember(u.raw),a=c}else if(e[a].type==="blockquote_open"){const[u,c]=C1(e,a,l.options());o?.includeSourceMap&&Dn(u,e[a],o),r.push(u),l.remember(u.raw),a=c}else{const u=_2(e,a,l.options());u?(r.push(u[0]),l.remember(u[0].raw),a=u[1]):a++}return[{type:"admonition",kind:s,title:i,children:r,raw:`:::${s} ${i} +${r.map(u=>u.raw).join(` +`)} +:::`},a+1]}const _ae=new Set(["warning","info","note","tip","danger","caution"]);function xae(e){let t=0;for(;t<e.length&&t<3&&e[t]===":";)t++;if(t===0||e[t]===":")return null;const n=e.slice(t).trimStart();if(!n)return null;const o=n.search(/\s/),s=(o===-1?n:n.slice(0,o)).toLowerCase();return _ae.has(s)?{kind:s,title:o===-1?"":n.slice(o).trim()}:null}function Sae(e,t,n){const o=e[t];let s="note",i="";const r=o.type.match(/^container_(\w+)_open$/);if(r){s=r[1];const d=String(o.info??"").trim();if(d&&!d.startsWith(":::")&&d.toLowerCase().startsWith(s)){const f=d.slice(s.length).trim();f&&(i=f)}}else{const d=xae(String(o.info??"").trim());d&&(s=d.kind,i=d.title)}i||(i=s.charAt(0).toUpperCase()+s.slice(1));const l=[],a=fu(n,!0);let u=t+1;const c=new RegExp(`^container_${s}_close$`);for(;u<e.length&&e[u].type!=="container_close"&&!c.test(e[u].type);)if(e[u].type==="paragraph_open"){const d=e[u+1];if(d){const f=d.children||[];let h=-1;for(let v=f.length-1;v>=0;v--){const k=f[v];if(k.type==="text"&&/:+/.test(k.content)){h=v;break}}const m={type:"paragraph",children:$o((h!==-1?f.slice(0,h):f)||[],void 0,void 0,a.options()),raw:String(d.content??"").replace(/\n:+$/,"").replace(/\n\s*:::\s*$/,"")};n?.includeSourceMap&&Dn(m,e[u],n),l.push(m),a.remember(m.raw)}u+=3}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[d,f]=b1(e,u,a.options());n?.includeSourceMap&&Dn(d,e[u],n),l.push(d),a.remember(d.raw),u=f}else if(e[u].type==="blockquote_open"){const[d,f]=C1(e,u,a.options());n?.includeSourceMap&&Dn(d,e[u],n),l.push(d),a.remember(d.raw),u=f}else{const d=_2(e,u,a.options());d?(l.push(d[0]),a.remember(d[0].raw),u=d[1]):u++}return[{type:"admonition",kind:s,title:i,children:l,raw:`:::${s} ${i} +${l.map(d=>d.raw).join(` +`)} +:::`},u+1]}const Aae=/^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/;function Mae(e,t,n){const o=e[t];if(o.type!=="container_open")return null;const s=Aae.exec(String(o.info??""));return s?wae(e,t,s,n):null}const n5={parseContainer:(e,t,n)=>Sae(e,t,n),matchAdmonition:Mae};function C1(e,t,n){const o=[],s=fu(n,!0);let i=t+1;for(;i<e.length&&e[i].type!=="blockquote_close";){const l=e[i];switch(l.type){case"paragraph_open":{const a=e[i+1],u={type:"paragraph",children:$o(a.children||[],String(a.content??""),void 0,s.options()),raw:String(a.content??"")};n?.includeSourceMap&&Dn(u,l,n),o.push(u),s.remember(u.raw),i+=3;break}case"bullet_list_open":case"ordered_list_open":{const[a,u]=b1(e,i,s.options());o.push(a),s.remember(a.raw),i=u;break}case"blockquote_open":{const[a,u]=C1(e,i,s.options());o.push(a),s.remember(a.raw),i=u;break}default:{const a=o5(e,i,s.options(),n5);a?(o.push(a[0]),s.remember(a[0].raw),i=a[1]):i++;break}}}const r={type:"blockquote",children:o,raw:o.map(l=>l.raw).join(` +`)};return n?.includeSourceMap&&Dn(r,e[t],n),[r,i+1]}function Tae(e){if(e.info?.startsWith("diff"))return Qy(e);const t=String(e.content??""),n=t.match(/ type="application\/vnd\.ant\.([^"]+)"/);let o=t;n?.[1]&&(o=t.replace(/<antArtifact[^>]*>/g,"").replace(/<\/antArtifact>/g,""));const s=Array.isArray(e.map)&&e.map.length===2;return{type:"code_block",language:n?n[1]:String(e.info??""),code:o,raw:o,loading:!s}}function Eae(e,t,n){const o=[];let s=t+1,i=[],r=[];const l=fu(n,!0);for(;s<e.length&&e[s].type!=="dl_close";)if(e[s].type==="dt_open"){const a=e[s+1];i=$o(a.children||[],void 0,void 0,l.options()),l.remember(i.map(u=>u.raw).join("")),s+=3}else if(e[s].type==="dd_open"){let a=s+1;for(r=[];a<e.length&&e[a].type!=="dd_close";)if(e[a].type==="paragraph_open"){const u=e[a+1];r.push({type:"paragraph",children:$o(u.children||[],String(u.content??""),void 0,l.options()),raw:String(u.content??"")}),l.remember(String(u.content??"")),a+=3}else a++;i.length>0&&(o.push({type:"definition_item",term:i,definition:r,raw:`${i.map(u=>u.raw).join("")}: ${r.map(u=>u.raw).join(` +`)}`}),i=[]),s=a+1}else s++;return[{type:"definition_list",items:o,raw:o.map(a=>a.raw).join(` +`)},s+1]}function Iae(e,t,n){const o=e[t].meta??{},s=String(o?.label??"0"),i=[],r=fu(n,!0);let l=t+1;for(;l<e.length&&e[l].type!=="footnote_close";)if(e[l].type==="paragraph_open"){const a=e[l+1],u=a.children?[...a.children]:[];e[l+2].type==="footnote_anchor"&&u.push(e[l+2]);const c={type:"paragraph",children:$o(u,String(a.content??""),void 0,r.options()),raw:String(a.content??"")};i.push(c),r.remember(c.raw),l+=3}else l++;return[{type:"footnote",id:s,children:i,raw:`[^${s}]: ${i.map(a=>a.raw).join(` +`)}`},l+1]}function Lae(e,t,n){const o=e[t],s=o.attrs,i=Array.isArray(s)&&s.length?Object.fromEntries(s.filter(c=>Array.isArray(c)&&c.length>=1&&c[0]).map(([c,d])=>[String(c),d==null||d===""?!0:String(d)])):void 0,r=String(o.tag?.substring(1)??"1"),l=Number.parseInt(r,10),a=e[t+1],u=String(a.content??"");return{type:"heading",level:l,text:u,...i?{attrs:i}:{},children:$o(a.children||[],u,void 0,n),raw:u}}function $ae(e,t,n){const o=t.toLowerCase(),s=new RegExp(String.raw`^<\s*${o}(?=\s|>|/)`,"i"),i=new RegExp(String.raw`^<\s*\/\s*${o}(?=\s|>)`,"i");let r=0,l=Math.max(0,n);for(;l<e.length;){const a=e.indexOf("<",l);if(a===-1)return-1;const u=e.slice(a);if(i.test(u)){const c=Vo(u);if(c===-1)return-1;if(r===0)return a+c+1;r--,l=a+c+1;continue}if(s.test(u)){const c=Vo(u);if(c===-1)return-1;const d=u.slice(0,c+1);/\/\s*>$/.test(d)||r++,l=a+c+1;continue}l=a+1}return-1}function ML(e){const t=String(e.content??"");if(/^\s*<!--/.test(t)||/^\s*<!/.test(t)||/^\s*<\?/.test(t))return{type:"html_block",content:t,raw:t,tag:"",loading:!1};const n=(t.match(/^\s*<([A-Z][\w:-]*)/i)?.[1]||"").toLowerCase();if(!n)return{type:"html_block",content:t,raw:t,tag:"",loading:!1};const o=Vo(t),s=o===-1?t:t.slice(0,o+1),i=o!==-1&&/\/\s*>$/.test(s),r=eu.has(n),l=w2(s),a=(o===-1?-1:$ae(t,n,o+1))!==-1,u=!(r||i||a);return{type:"html_block",content:u?`${t.replace(/<[^>]*$/,"")} +</${n}>`:t,raw:t,tag:n,attrs:l.length?l:void 0,loading:u}}function Nae(e){const t=String(e.content??""),n=e.raw==="$$"?`$$${t}$$`:String(e.raw??"");return{type:"math_block",content:t,loading:!!e.loading,raw:n,markup:e.markup}}function Fae(e){if(!e)return"left";for(const t of e){if(!t)continue;const[n,o]=t;if(!o)continue;const s=String(o).trim().toLowerCase();if(n==="style"){const i=/text-align\s*:\s*(left|right|center)/i.exec(s);if(i)return i[1].toLowerCase()}}return"left"}function TL(e){return e?.filename===!0||e?.explicitFilename===!0||e?.marketTicker===!0}function EL(e,t){const n={filename:e?.filename||t?.filename,explicitFilename:e?.explicitFilename||t?.explicitFilename,marketTicker:e?.marketTicker||t?.marketTicker};return TL(n)?n:void 0}function Rae(e,t,n){const o=EL(Gp(t),n);if(!TL(o))return e;const s=e?.__linkifyDemotionContext;return{...e,__linkifyDemotionContext:{filename:s?.filename||o?.filename,explicitFilename:s?.explicitFilename||o?.explicitFilename,marketTicker:s?.marketTicker||o?.marketTicker}}}function Oae(e,t,n){let o=t+1,s=null;const i=[];let r=!1;for(;o<e.length&&e[o].type!=="table_close";)if(e[o].type==="thead_open")r=!0,o++;else if(e[o].type==="thead_close")r=!1,o++;else if(e[o].type==="tbody_open"||e[o].type==="tbody_close")o++;else if(e[o].type==="tr_open"){const a=[];let u=o+1,c;for(;u<e.length&&e[u].type!=="tr_close";)if(e[u].type==="th_open"||e[u].type==="td_open"){const f=e[u].type==="th_open",h=e[u+1],m=String(h.content??""),v=Fae(e[u].attrs),k=a.length,w=!f&&!r,b=w?s?.cells[k]?.raw:void 0;a.push({type:"table_cell",header:f||r,children:$o(h.children||[],m,void 0,Rae(n,b,w?c:void 0)),raw:m,align:v}),w&&(c=EL(c,Gp(m))),u+=3}else u++;const d={type:"table_row",cells:a,raw:a.map(f=>f.raw).join("|")};r?s=d:i.push(d),o=u+1}else o++;s||(s={type:"table_row",cells:[],raw:""});const l=e[t].loading===!0;return[{type:"table",header:s,rows:i,loading:l&&!n?.final&&i.length===0,raw:[s,...i].map(a=>a.raw).join(` +`)},o+1]}function Pae(){return{type:"thematic_break",raw:"---"}}let P9=null;const D9=new WeakMap;function Dw(){return P9||(P9={allowedTagSet:A2(),customTagSet:null}),P9}function Dae(e){if(!e||e.length===0)return Dw();const t=D9.get(e);if(t)return t;const n=e.map(Sr).filter(Boolean);if(!n.length){const s=Dw();return D9.set(e,s),s}const o={allowedTagSet:A2({customHtmlTags:e}),customTagSet:new Set(n)};return D9.set(e,o),o}function Bae(e,t,n){const o=e[t],s=o.attrs;let i="";const r={};if(s){for(const[h,m]of s)if(h==="class"){const v=m.match(/(?:\s|^)vmr-container-(\S+)/);v&&(i=v[1])}else if(h.startsWith("data-")){const v=h.slice(5);try{r[v]=JSON.parse(m)}catch{r[v]=m}}}const l=[],a=fu(n,!0);let u=t+1;for(;u<e.length&&e[u].type!=="vmr_container_close";)if(e[u].type==="paragraph_open"){const h=e[u+1];if(h){const m={type:"paragraph",children:$o(h.children||[],void 0,void 0,a.options()),raw:String(h.content??"")};n?.includeSourceMap&&Dn(m,e[u],n),l.push(m),a.remember(m.raw)}u+=3}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[h,m]=b1(e,u,a.options());n?.includeSourceMap&&Dn(h,e[u],n),l.push(h),a.remember(h.raw),u=m}else if(e[u].type==="blockquote_open"){const[h,m]=C1(e,u,a.options());n?.includeSourceMap&&Dn(h,e[u],n),l.push(h),a.remember(h.raw),u=m}else{const h=_2(e,u,a.options());h?(l.push(h[0]),a.remember(h[0].raw),u=h[1]):u++}const c=u<e.length&&e[u].type==="vmr_container_close",d=c&&o.meta?.unclosed!==!0||!!n?.final;let f=`::: ${i}`;return Object.keys(r).length>0&&(f+=` ${JSON.stringify(r)}`),f+=` +`,l.length>0&&(f+=o.raw??l.map(h=>h.raw).join(` +`),f+=` +`),f+=":::",[{type:"vmr_container",name:i,loading:!d,attrs:Object.keys(r).length>0?r:void 0,children:l,raw:f},c?u+1:u]}function B9(e,t,n,o){if(n?.type.endsWith("_close")){let s=Array.isArray(n.map)?Number(n.map[1]):NaN;return Number.isFinite(s)||(s=Array.isArray(t.map)?Number(t.map[1])+1:NaN),yae(e,t,s,o)}return Dn(e,t,o)}function Hae(e){return e.replace(/^\r?\n/,"").replace(/\r?\n$/,"")}function zae(e,t){if(!e||!t)return e;const n=new RegExp(String.raw`[\t ]*<\s*\/\s*${t}[^>]*$`,"i");return e.replace(n,"")}function Wae(e,t,n){if(!e||!t)return null;const o=t.toLowerCase(),s=new RegExp(String.raw`^<\s*${Gr(o)}(?=\s|>|/)`,"i"),i=new RegExp(String.raw`^<\s*\/\s*${Gr(o)}(?=\s|>)`,"i");let r=0,l=Math.max(0,n);for(;l<e.length;){const a=e.indexOf("<",l);if(a===-1)break;const u=e.slice(a);if(i.test(u)){const c=Vo(u);if(c===-1)return null;if(r===0)return{start:a,end:a+c+1};r--,l=a+c+1;continue}if(s.test(u)){const c=Vo(u);if(c===-1)return null;const d=u.slice(0,c+1);/\/\s*>$/.test(d)||r++,l=a+c+1;continue}l=a+1}return null}function Uae(e,t,n){if(!e||!t)return null;const o=t.toLowerCase(),s=new RegExp(String.raw`<\s*${o}(?=\s|>|/)`,"gi");s.lastIndex=Math.max(0,n||0);const i=s.exec(e);if(!i||i.index==null)return null;const r=i.index,l=e.slice(r),a=Vo(l);if(a===-1)return null;const u=r+a;if(/\/\s*>\s*$/.test(l.slice(0,a+1))){const m=u+1;return{raw:e.slice(r,m),start:r,end:m}}let c=1,d=u+1;const f=m=>{const v=e.slice(m);return new RegExp(String.raw`^<\s*${o}(?=\s|>|/)`,"i").test(v)},h=m=>{const v=e.slice(m);return new RegExp(String.raw`^<\s*\/\s*${o}(?=\s|>)`,"i").test(v)};for(;d<e.length;){const m=e.indexOf("<",d);if(m===-1)return{raw:e.slice(r),start:r,end:e.length};if(h(m)){const v=e.indexOf(">",m);if(v===-1)return null;if(c--,c===0){const k=v+1;return{raw:e.slice(r,k),start:r,end:k}}d=v+1;continue}if(f(m)){const v=Vo(e.slice(m));if(v===-1)return null;c++,d=m+v+1;continue}d=m+1}return{raw:e.slice(r),start:r,end:e.length}}function K3(e){return Number.isFinite(e)&&e>0?e:0}function jae(e,t){const n=K3(t);if(!e||n<=0)return 0;let o=0;for(let s=0;s<e.length;s++)if(e[s]===` +`&&(o++,o===n))return s+1;return e.length}function _2(e,t,n){const o=e[t],s=n?.includeSourceMap===!0;switch(o.type){case"heading_open":{const i=Lae(e,t,n);return s&&Dn(i,o,n),[i,t+3]}case"code_block":{const i=Tae(o);return s&&Dn(i,o,n),[i,t+1]}case"fence":{const i=Qy(o);return s&&Dn(i,o,n),[i,t+1]}case"math_block":{const i=Nae(o);return s&&Dn(i,o,n),[i,t+1]}case"html_block":{const i=ML(o),r=i.tag?Dae(n?.customHtmlTags):null;if(i.tag&&i.loading&&r&&!r.allowedTagSet.has(i.tag)){const l=String(o.content??"").replace(/\n+$/,""),a={type:"paragraph",children:l?[{type:"text",content:l,raw:l}]:[],raw:l};return s&&Dn(a,o,n),[a,t+1]}if(i.tag&&r?.customTagSet?.has(i.tag)){const l=i.tag,a=String(n?.__sourceMarkdown??""),u=Number(n?.__customHtmlBlockCursor??0),c=Array.isArray(o.map)?jae(a,Number(o.map?.[0]??0)):0,d=Uae(a,l,Math.max(K3(u),K3(c)));d&&n&&(n.__customHtmlBlockCursor=d.end);const f=String(d?.raw??i.raw??""),h=Vo(f),m=h!==-1?f.slice(0,h+1):f,v=h!==-1&&/\/\s*>\s*$/.test(m),k=h===-1?null:Wae(f,l,h+1),w=k?.start??-1;let b="";h!==-1&&(w!==-1&&h<w?b=f.slice(h+1,w):b=f.slice(h+1)),w===-1&&(b=zae(b,l));const _=[],g=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let x;for(;(x=g.exec(m))!==null;){const A=x[1];if(!A||A.toLowerCase()===l)continue;const E=x[2]||x[3]||x[4]||"";_.push([A,E])}const S=!n?.final&&!v&&k==null,T={type:l,tag:l,content:Hae(b),raw:String(d?.raw??i.raw??f),loading:S,attrs:_.length?_:void 0};return s&&(d?T.sourceMap=Ep(a,d.start,d.end,n):Dn(T,o,n)),[T,t+1]}return s&&Dn(i,o,n),[i,t+1]}case"table_open":{const[i,r]=Oae(e,t,n);return s&&Dn(i,o,n),[i,r]}case"dl_open":{const[i,r]=Eae(e,t,n);return s&&Dn(i,o,n),[i,r]}case"footnote_open":{const[i,r]=Iae(e,t,n);return s&&Dn(i,o,n),[i,r]}case"hr":{const i=Pae();return s&&Dn(i,o,n),[i,t+1]}}return null}function o5(e,t,n,o){const s=_2(e,t,n);if(s)return s;const i=e[t],r=n?.includeSourceMap===!0;switch(i.type){case"container_warning_open":case"container_info_open":case"container_note_open":case"container_tip_open":case"container_danger_open":case"container_caution_open":case"container_error_open":if(o?.parseContainer){const l=o.parseContainer(e,t,n);return r&&B9(l[0],i,e[l[1]-1],n),l}break;case"container_open":if(o?.matchAdmonition){const l=o.matchAdmonition(e,t,n);if(l)return r&&B9(l[0],i,e[l[1]-1],n),l}break;case"vmr_container_open":{const l=Bae(e,t,n);return r&&B9(l[0],i,e[l[1]-1],n),l}}return null}function Vae(){return{type:"hardbreak",raw:`\\ +`}}function qae(e,t,n){const o=e[t+1],s=String(o.content??"");return{type:"paragraph",children:$o(o.children||[],s,void 0,n),raw:s}}const Bw=new WeakMap,IL=new WeakMap,Hw=new WeakMap,zw=new WeakMap;function al(e,t,n){const o=t?.map,s=n?.__sourceMarkdown;if(!Array.isArray(o)||o.length<2||typeof s!="string"||!n)return;const i=Number(o[0]),r=Number(o[1]);if(!Number.isFinite(i)||!Number.isFinite(r))return;let l=Hw.get(n);if(!l){l=[0];for(let a=0;a<s.length;a++)s[a]===` +`&&l.push(a+1);Hw.set(n,l)}IL.set(e,{start:l[Math.max(0,Math.trunc(i))]??s.length,end:l[Math.max(0,Math.trunc(r))]??s.length})}const x2=new WeakMap,Ww=new WeakMap,Kae=["$$","\\["],Zae=/(^|\r?\n)[\t ]*:::[\t ]*(?:warning|info|note|tip|danger|caution|error)(?=[\t ]|\r?\n|$)[^\r\n]*(?:\r?\n[\t ]*)*$/,sg=new WeakMap,_f=new WeakMap,Gae=new Set(["code_inline","em_close","em_open","emoji","hardbreak","ins_close","ins_open","mark_close","mark_open","s_close","s_open","softbreak","strong_close","strong_open","sub","sup","text"]),Yae=new Map([["paragraph_open","paragraph_close"],["heading_open","heading_close"],["bullet_list_open","bullet_list_close"],["ordered_list_open","ordered_list_close"],["blockquote_open","blockquote_close"],["table_open","table_close"]]),Xae=new Set(["code_block","fence","hr","math_block"]);function l1(){return typeof performance<"u"?performance.now():Date.now()}function Ip(e,t,n){e&&(e[t]=(e[t]??0)+n)}function LL(e){return e.__timing}function $L(e,t,n){return t&&Ip(t,"parseMarkdownToStructureTotalMs",l1()-n),e}function NL(e,t){const n=t.postTransformNodes;if(typeof n!="function")return e;const o=n(e);return Array.isArray(o)?o:e}function Uw(e,t,n,o){return $L(NL(e,t),n,o)}function Yh(e,t,n){if(!n)return t_(e,t);Ip(n,"processTokensInputTokens",e.length);const o=l1(),s=t_(e,t);return Ip(n,"processTokensMs",l1()-o),s}function FL(e){return e.every(t=>{if(!Gae.has(t.type))return!1;const n=t.children;return!Array.isArray(n)||FL(n)})}function Jae(e){const t=[];let n=!1,o=0;for(;o<e.length;){const s=e[o];if(!s||s.level!==0)return null;const i=Yae.get(s.type);let r=o+1;if(i){if(s.nesting!==1)return null;for(;r<e.length;){const l=e[r];if(l.level===0){if(l.type!==i||l.nesting!==-1)return null;r++;break}r++}if(e[r-1]?.type!==i)return null;if(s.type==="paragraph_open"||s.type==="heading_open"){if(r!==o+3||e[o+1]?.type!=="inline")return null}else n=!0}else if(Xae.has(s.type)){if(s.nesting!==0)return null;n=!0}else return null;for(let l=o;l<r;l++){const a=e[l];if(a.type!=="inline")continue;const u=a.children;if(!Array.isArray(u)||!FL(u))return null}t.push(o),o=r}return{mixed:n,starts:t}}function Qae(e){return/\r?\n[\t ]*\r?\n[\t ]*$/.test(e)}function eue(e){return e.__reuseStableTopLevelNodes===!0&&e.final!==!0&&!e.preTransformTokens&&!e.postTransformTokens&&!e.postTransformNodes&&!e.customHtmlTags?.length&&e.includeSourceMap!==!0}function jw(e,t,n,o,s,i){const r=o.starts;if(r.length===0||s.length!==r.length){sg.delete(e);return}const l=r.map((a,u)=>{const c=r[u+1]??n.length;return{firstToken:n[a],lastToken:n[c-1],tokenCount:c-a}});sg.set(e,{groupBoundaries:l,source:t,nodes:s,stableGroupCount:o.mixed?Math.max(0,r.length-1):Qae(t)?r.length:Math.max(0,r.length-1),requireClosingStrong:i.requireClosingStrong})}function tue(e,t,n,o){for(let s=0;s<o;s++){const i=n[s],r=n[s+1]??t.length,l=e.groupBoundaries[s];if(!l||l.firstToken!==t[i]||l.lastToken!==t[r-1]||l.tokenCount!==r-i)return!1}return!0}function nue(e,t,n,o,s){const i=e,r=Jae(n);if(!(s5(e,o)&&eue(o)&&r!==null))return sg.delete(i),Yh(n,o,s);const l=r.starts,a=sg.get(i),u=_f.get(i),c=a&&r.mixed?Math.min(a.stableGroupCount,Math.max(0,a.groupBoundaries.length-1)):a?.stableGroupCount??0;if(a&&c>0&&a.requireClosingStrong===o.requireClosingStrong&&t.startsWith(a.source)&&l.length>=c&&(u==="append"||u==="tail")&&tue(a,n,l,c)){const f=l[c]??n.length,h=Yh(n.slice(f),o,s),m=l.length-c;if(h.length===m){const v=a.nodes.slice(0,c).concat(h);return Ip(s,"processTokensReusedTopLevelNodes",c),jw(e,t,n,r,v,o),v}}const d=Yh(n,o,s);return jw(e,t,n,r,d,o),d}function oue(e){const t=e?.customHtmlTags;if(!Array.isArray(t)||t.length===0)return null;const n=Ec(t);return n.length?new Set(n):null}function sue(e,t){const n=e;let o=Bw.get(n);o||(o=new Map,Bw.set(n,o));const s=t.__markstreamFinal===!0?"final":"streaming";let i=o.get(s);i||(i={},o.set(s,i));for(const r of Object.keys(i))Object.prototype.hasOwnProperty.call(t,r)||delete i[r];return Object.assign(i,t),i}function iue(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function vh(e,t,n){for(const o of Reflect.ownKeys(e)){const s=Object.getOwnPropertyDescriptor(e,o);if(!s||!("value"in s))continue;const i=Object.getOwnPropertyDescriptor(t,o);i&&(!("value"in i)||i.writable===!1)||(t[o]=Zu(s.value,n))}}function Zu(e,t=new WeakMap){if(!e||typeof e!="object")return e;const n=e,o=t.get(n);if(o)return o;if(Array.isArray(e)){const r=[];t.set(n,r);for(const l of e)r.push(Zu(l,t));return r}if(e instanceof Map){const r=new Map;t.set(n,r);for(const[l,a]of e)r.set(Zu(l,t),Zu(a,t));return r}if(e instanceof Set){const r=new Set;t.set(n,r);for(const l of e)r.add(Zu(l,t));return r}if(e instanceof Date){const r=new Date(e.getTime());return t.set(n,r),r}if(e instanceof RegExp){const r=new RegExp(e.source,e.flags);return r.lastIndex=e.lastIndex,t.set(n,r),r}if(typeof URL<"u"&&e instanceof URL){const r=new URL(e.href);return t.set(n,r),vh(n,r,t),r}if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams){const r=new URLSearchParams(e.toString());return t.set(n,r),vh(n,r,t),r}if(e instanceof Error){let r;const l=e.constructor;try{r=new l(e.message)}catch{r=new Error(e.message)}return Object.setPrototypeOf(r,Object.getPrototypeOf(e)),t.set(n,r),vh(n,r,t),r}if(typeof Promise<"u"&&e instanceof Promise||typeof Node<"u"&&e instanceof Node)return t.set(n,e),e;if(!iue(e)){const r=Object.create(Object.getPrototypeOf(e));return t.set(n,r),vh(n,r,t),r}const s={};t.set(n,s);const i=e;for(const r of Object.keys(i))s[r]=Zu(i[r],t);return s}function RL(e,t=!0){if(!t)return ac(e);const n=Object.create(Object.getPrototypeOf(e)),o=new WeakMap;for(const s of Reflect.ownKeys(e)){const i=Object.getOwnPropertyDescriptor(e,s);if(!i)continue;if(!("value"in i)){Object.defineProperty(n,s,i);continue}const r=i.value;let l=r;s==="attrs"&&Array.isArray(r)?l=r.map(a=>[...a]):s==="map"&&Array.isArray(r)?l=[...r]:s==="children"&&Array.isArray(r)?l=r.map(a=>RL(a,t)):t&&r&&typeof r=="object"&&(l=Zu(r,o)),Object.defineProperty(n,s,{...i,value:l})}return n}function Vw(e,t=!0){return e.map(n=>RL(n,t))}function s5(e,t){const n=t,o=e.stream,s=t.streamParse??"auto";return n.__disableStreamParse!==!0&&e.__markstreamHasCustomParserExtensions!==!0&&(s===!0||s==="auto"&&t.final!==!0)&&o?.enabled===!0&&typeof o.parse=="function"}function rue(e,t){const n=t,o=t.streamParse??"auto",s=e.stream;return t.final===!0&&o==="auto"&&n.__disableStreamParse!==!0&&e.__markstreamHasCustomParserExtensions!==!0&&s?.enabled===!0&&typeof s.reset=="function"}function lue(e){x2.delete(e)}function aue(){return{fenceChar:"",fenceInBlockquote:!1,fenceInList:!1,fenceLen:0,fenceListIndent:0,inDollarMath:!1,inFence:!1,inMath:!1,listContentIndent:null,dollarMathOpenOffset:null,mathOpenOffset:null}}function qf(e){return{...e}}function uue(e,t,n,o=S2(t).state){x2.set(e,{explicitBracketMath:o,source:t,key:n,pendingCandidate:n===null&&pL(t)})}function cue(e){return e.endsWith("$")||e.endsWith("\\")}function due(e){const t=Math.max(e.lastIndexOf(` +`)+1,0),n=e.slice(t).replace(/[\t ]+$/,"");return Kae.some(o=>n.endsWith(o))}function fue(e,t){return t?!!(t.includes("$$")||t.includes("\\[")||e.endsWith("$")&&t[0]==="$"||e.endsWith("\\")&&t[0]==="["||due(e)&&/[\r\n]/.test(t)):!1}function of(e,t){let n=t-1,o=0;for(;n>=0&&e[n]==="\\";)o++,n--;return o%2===1}function Z3(e){return e===" "||e===" "}function OL(e,t){return t===" "?e+1:e+4-e%4}function i5(e){let t=0,n=0;for(;t<e.length&&Z3(e[t]);)n=OL(n,e[t]),t++;return{index:t,column:n}}function w1(e){const t=i5(e);return t.column>3?null:t}function H9(e){const t=w1(e);if(!t)return null;const n=t.index,o=e[n];if(o!=="`"&&o!=="~")return null;let s=n;for(;s<e.length&&e[s]===o;)s++;const i=s-n;if(i<3)return null;const r=e.slice(s);return o==="`"&&r.includes("`")?null:{markerChar:o,markerLen:i,rest:r}}function r5(e){const t=w1(e);if(!t)return null;const n=e.slice(t.index),o=/^(?:[-+*]|\d{1,9}[.)])(?=[\t ]|$)/.exec(n)?.[0];if(!o)return null;let s=t.index+o.length,i=t.column+o.length;if(!Z3(e[s]))return null;for(;s<e.length&&Z3(e[s]);)i=OL(i,e[s]),s++;return{content:e.slice(s),contentIndent:i}}function l5(e){let t=e,n=!1;for(;;){const o=w1(t);if(!o)return n?t:null;let s=o.index;if(t[s]!==">")return n?t:null;n=!0,s++,(t[s]===" "||t[s]===" ")&&s++,t=t.slice(s)}}function PL(e){const t=H9(e);if(t)return{...t,inBlockquote:!1,inList:!1,listIndent:0};const n=l5(e),o=n==null?null:H9(n);if(o)return{...o,inBlockquote:!0,inList:!1,listIndent:0};const s=r5(e);if(!s)return null;const i=H9(s.content);return i==null?null:{...i,inBlockquote:!1,inList:!0,listIndent:s.contentIndent}}function pue(e,t){let n=!1,o="",s=0,i=!1,r=!1,l=0,a=null,u=0;for(;u<t;){const c=e.indexOf(` +`,u),d=c===-1||c>=t?t:c,f=e.slice(u,d),h=f.endsWith("\r")?f.slice(0,-1):f,m=i5(h),v=r5(h);n&&i&&h.trim()&&l5(h)==null&&(n=!1,o="",s=0,i=!1,r=!1,l=0),n&&r&&h.trim()&&m.column<l&&!v&&(n=!1,o="",s=0,i=!1,r=!1,l=0),v?a=v.contentIndent:h.trim()&&a!=null&&m.column<a&&!n&&(a=null);const k=PL(h);if(k&&(n?k.markerChar===o&&k.markerLen>=s&&/^\s*$/.test(k.rest)&&(n=!1,o="",s=0,i=!1,r=!1,l=0):(n=!0,o=k.markerChar,s=k.markerLen,i=k.inBlockquote,r=k.inList||a!=null&&!k.inBlockquote&&m.column>=a,l=k.listIndent||a||0)),c===-1||c>=t)break;u=c+1}return n}function hue(e,t){const n=d=>d===" "||d===" ",o=d=>{const f=d.charCodeAt(0);return f>=65&&f<=90||f>=97&&f<=122||f>=48&&f<=57||d==="_"||d==="-"||d===":"},s=d=>{if(d[0]!=="<")return null;let f=1;for(;f<d.length&&n(d[f]);)f++;const h=d[f]==="/";if(h)for(f++;f<d.length&&n(d[f]);)f++;const m=f;for(;f<d.length&&o(d[f]);)f++;if(f===m)return null;const v=d.slice(m,f).toLowerCase();if(!zI.has(v))return null;const k=d[f];if(k&&k!==" "&&k!==" "&&k!==">"&&k!=="/")return null;const w=Vo(d);if(w===-1)return null;let b=w-1;for(;b>=0&&n(d[b]);)b--;return{closing:h,tag:v,selfClosing:!h&&d[b]==="/",after:d.slice(w+1)}},i=(d,f)=>{const h=d.toLowerCase();let m=0;for(;m<h.length;){const v=h.indexOf("</",m);if(v===-1)return!1;for(m=v+2;m<h.length&&n(h[m]);)m++;if(h.startsWith(f,m)){const k=h[m+f.length];if(!k||k===" "||k===" "||k===">")return!0}}return!1},r=[];let l=!1,a=!1,u=!1,c=0;for(;c<t;){const d=e.indexOf(` +`,c),f=d===-1||d>=t?t:d,h=e.slice(c,f),m=h.endsWith("\r")?h.slice(0,-1):h,v=w1(m);if(v){const k=m.slice(v.index);if(l)l=!k.includes("-->");else if(a)a=!k.includes(">");else if(u)u=!k.includes("?>");else if(k.startsWith("<!--"))l=!k.includes("-->");else if(k.startsWith("<?"))u=!k.includes("?>");else if(k.startsWith("<!"))a=!k.includes(">");else{const w=s(k);if(w)if(w.closing){for(let b=r.length-1;b>=0;b--)if(r[b]===w.tag){r.length=b;break}}else w.selfClosing||i(w.after,w.tag)||r.push(w.tag)}}if(d===-1||d>=t)break;c=d+1}return l||a||u||r.length>0}function mue(e,t,n){if(!n?.length)return!1;const o=new Set(Ec(n));if(!o.size)return!1;const s=c=>{const d=c.charCodeAt(0);return d>=65&&d<=90||d>=97&&d<=122||d>=48&&d<=57||c==="_"||c==="-"||c===":"},i=c=>c===" "||c===" ",r=c=>{if(c[0]!=="<")return null;let d=1;for(;d<c.length&&i(c[d]);)d++;const f=c[d]==="/";if(f)for(d++;d<c.length&&i(c[d]);)d++;const h=d;for(;d<c.length&&s(c[d]);)d++;if(d===h)return null;const m=c.slice(h,d).toLowerCase();if(!o.has(m))return null;const v=c[d];if(v&&v!==" "&&v!==" "&&v!==">"&&v!=="/")return null;const k=c.indexOf(">",d);if(k===-1)return null;let w=k-1;for(;w>=0&&i(c[w]);)w--;return{closing:f,tag:m,selfClosing:!f&&c[w]==="/",after:c.slice(k+1)}},l=(c,d)=>{const f=c.toLowerCase();let h=0;for(;h<f.length;){const m=f.indexOf("</",h);if(m===-1)return!1;for(h=m+2;h<f.length&&i(f[h]);)h++;if(f.startsWith(d,h)){const v=f[h+d.length];if(!v||v===" "||v===" "||v===">")return!0}}return!1},a=[];let u=0;for(;u<t;){const c=e.indexOf(` +`,u),d=c===-1||c>=t?t:c,f=e.slice(u,d),h=f.endsWith("\r")?f.slice(0,-1):f,m=w1(h);if(m){const v=r(h.slice(m.index));if(v)if(v.closing){for(let k=a.length-1;k>=0;k--)if(a[k]===v.tag){a.length=k;break}}else v.selfClosing||l(v.after,v.tag)||a.push(v.tag)}if(c===-1||c>=t)break;u=c+1}return a.length>0}function gue(e,t){const n=Zae.exec(e);if(!n)return null;const o=n[1]??"",s=n.index+o.length,i=e.indexOf(` +`,s),r=e.slice(s,i===-1?e.length:i);return!w1(r.endsWith("\r")?r.slice(0,-1):r)||pue(e,s)||hue(e,s)||mue(e,s,t)?null:`${e.slice(0,n.index)}${o}`}function DL(e,t,n){let o=t;for(;o<e.length&&e[o]===n;)o++;return o-t}function vue(e,t,n){let o=t;for(;o<e.length;){const s=e.indexOf("`",o);if(s===-1)return-1;const i=DL(e,s,"`");if(i===n)return s;o=s+i}return-1}function z9(e){e.inFence=!1,e.fenceChar="",e.fenceLen=0,e.fenceInBlockquote=!1,e.fenceInList=!1,e.fenceListIndent=0}function qw(e,t,n,o,s){let i=0,r=!1;for(;i<e.length;){const l=i;if(t.inMath){if(e.startsWith("\\]",i)&&!of(e,l)){o!=null&&s&&n+i+2>o&&(r=!0),t.inMath=!1,t.mathOpenOffset=null,i+=2;continue}i++;continue}if(t.inDollarMath){if(e.startsWith("$$",i)&&!of(e,l)){o!=null&&s&&n+i+2>o&&(r=!0),t.inDollarMath=!1,t.dollarMathOpenOffset=null,i+=2;continue}i++;continue}if(e[i]==="`"&&!of(e,l)){const a=DL(e,i,"`"),u=vue(e,i+a,a);if(u===-1)break;i=u+a;continue}if(e.startsWith("\\[",i)&&!of(e,l)){t.inMath=!0,t.mathOpenOffset=n+i,i+=2;continue}if(e.startsWith("$$",i)&&!of(e,l)){t.inDollarMath=!0,t.dollarMathOpenOffset=n+i,i+=2;continue}i++}return r}function yue(e,t){if(!Xy(t))return e;const n=t,o=Ww.get(n),s=o?.source===e?o.state:o&&e.startsWith(o.source)?BL(o.state,e.slice(o.source.length),o.source.length-o.state.lineBuffer.length).state:S2(e).state;Ww.set(n,{source:e,state:s});const{context:i}=s,r=i.inMath?i.mathOpenOffset:i.inDollarMath?i.dollarMathOpenOffset:null;if(r==null)return e;const l=e.slice(r+2),a=e.lastIndexOf(` +`,r-1)+1;if(e.slice(a,r).trim()!==""&&!/^\r?\n/.test(l)||/^\s*!\[/.test(l))return e;const u=l.trim(),c=/^(?:[a-z]|pi)$/i.test(u);return Oa(l)&&!c?e:e.slice(0,r)}function kue(e,t,n,o,s){const i=i5(e),r=r5(e);if(t.inFence&&t.fenceInBlockquote&&e.trim()&&l5(e)==null&&z9(t),t.inFence&&t.fenceInList&&e.trim()&&i.column<t.fenceListIndent&&!r&&z9(t),r?t.listContentIndent=r.contentIndent:e.trim()&&t.listContentIndent!=null&&i.column<t.listContentIndent&&!t.inFence&&(t.listContentIndent=null),!t.inMath&&!t.inDollarMath){const l=PL(e);if(l)t.inFence?l.markerChar===t.fenceChar&&l.markerLen>=t.fenceLen&&/^\s*$/.test(l.rest)&&z9(t):(t.inFence=!0,t.fenceChar=l.markerChar,t.fenceLen=l.markerLen,t.fenceInBlockquote=l.inBlockquote,t.fenceInList=l.inList||t.listContentIndent!=null&&!l.inBlockquote&&i.column>=t.listContentIndent,t.fenceListIndent=l.listIndent||t.listContentIndent||0);else if(!t.inFence)return qw(e,t,n,o,s)}else return qw(e,t,n,o,s);return!1}function S2(e,t=aue(),n=null,o=!1,s=0){const i=qf(t);let r=qf(t),l="",a=!1,u=0;for(;u<e.length;){const c=e.indexOf(` +`,u),d=c!==-1,f=d&&c>u&&e[c-1]==="\r"?c-1:d?c:e.length,h=e.slice(u,f);kue(h,i,s+u,n,o)&&(a=!0),d?(r=qf(i),l=""):l=h,u=d?c+1:e.length}return{closedOpenMath:a,state:{committedContext:r,context:i,lineBuffer:l}}}function BL(e,t,n=0){return t&&!e.context.inMath&&!e.context.inDollarMath&&!e.context.inFence&&!e.committedContext.inFence&&!/[\\$`~\r\n]/.test(t)&&!(e.lineBuffer.endsWith("\\")&&(t[0]==="["||t[0]==="]"))?{closedOpenMath:!1,state:{committedContext:qf(e.committedContext),context:qf(e.context),lineBuffer:e.lineBuffer+t}}:S2(e.lineBuffer+t,e.committedContext,n+e.lineBuffer.length,e.context.inMath||e.context.inDollarMath,n)}function bue(e,t){if(!Xy(e))return;const n=e.stream;if(typeof n?.reset!="function")return;const o=e,s=x2.get(o);if(s?.source===t)return;const i=s?t.startsWith(s.source):!1,r=i&&s?t.slice(s.source.length):"",l=i&&s?BL(s.explicitBracketMath,r,s.source.length-s.explicitBracketMath.lineBuffer.length):S2(t),a=l.state,u=i&&s?l.closedOpenMath:!1;if(s&&i&&s.key===null&&s.pendingCandidate===!1&&!u&&!fue(s.source,r)&&!cue(t)){s.source=t,s.explicitBracketMath=a;return}const c=ole(t);(s&&(s&&!i||s.key!==c||u)||!s&&c)&&n.reset(),uue(e,t,c,a)}function Cue(e){return typeof e.preTransformTokens=="function"||typeof e.postTransformTokens=="function"}function wue(e,t){const n=e?.map,o=t?.map;return n===o?!0:!Array.isArray(n)||!Array.isArray(o)?!1:n.length===o.length&&n.every((s,i)=>s===o[i])}function W9(e,t){return!!e&&!!t&&e.type===t.type&&e.tag===t.tag&&e.nesting===t.nesting&&e.markup===t.markup&&e.content===t.content&&wue(e,t)}function Kw(e,t){return e[t]?.type==="paragraph_open"&&e[t+1]?.type==="inline"&&e[t+2]?.type==="paragraph_close"}function _ue(e){for(let t=0;t+5<e.length;t++)if(Kw(e,t)&&Kw(e,t+3)&&W9(e[t],e[t+3])&&W9(e[t+1],e[t+4])&&W9(e[t+2],e[t+5]))return!0;return!1}function xue(e,t,n){return Xy(e)&&pL(t)&&_ue(n)}function Sue(e){const t=x2.get(e);return typeof t?.key=="string"&&t.key.startsWith("pending:")}function Zw(e,t,n,o){const s=e;if(o.customHtmlTags?.length&&(n.__markstreamCustomHtmlTags=o.customHtmlTags),!s5(e,o)||(bue(e,t),Sue(e)))return _f.set(s,"sync"),e.parse(t,n);const i=e.stream.parse(t,sue(e,n));if(xue(e,t,i))return e.stream?.reset?.(),_f.set(s,"sync"),e.parse(t,n);const r=e.stream?.stats?.();if(_f.set(s,r?.lastMode??"stream"),!Cue(o))return i;const l=LL(o);if(!l)return Vw(i,!0);const a=l1(),u=Vw(i,!0);return Ip(l,"tokenCloneMs",l1()-a),u}function A2(e){const t=e?.customHtmlTags;if(!Array.isArray(t)||t.length===0)return Sp;const n=new Set(Sp);for(const o of Ec(t))o&&n.add(o);return n}function Aue(e){const t=e.raw;if(typeof t=="string")return t;const n=e.content;return typeof n=="string"?n:e.type==="hardbreak"?"<br>":""}function Gw(e){return{type:"paragraph",children:e,raw:e.map(Aue).join("")}}function Yw(e,t){if(t.sourceMap)for(const n of e)n.sourceMap||(n.sourceMap=t.sourceMap)}function Xw(e,t){if(e.type!=="paragraph")return null;const n=e.children,o=Array.isArray(n)?n:[];if(o.length===0)return null;const s=oue(t);if(!s?.size)return null;let i=-1;for(let c=0;c<o.length;c++){const d=o[c];if(!s.has(String(d?.type??"").toLowerCase()))continue;const f=o.slice(0,c);if(String(d.content??"").trim()&&f.some(h=>h?.type==="hardbreak")){i=c;break}}if(i===-1)return null;const r=o.slice(0,i),l=o[i];if(!l)return null;const a=[];r.length&&a.push(Gw(r)),a.push(l);const u=o.slice(i+1);return u.length&&a.push(Gw(u)),a}function Mue(e){const t=e.trim();if(!t)return null;const n=/^(?:<!doctype\s+html[^>]*>\s*)?<html(?:\s[^>]*)?>/i.test(t),o=/<\/html>\s*$/i.test(t);return!n||!o?null:[{type:"html_block",tag:"html",raw:e,content:e,loading:!1}]}function Kf(e){const t=e.raw;if(typeof t=="string")return t;const n=e.content;return typeof n=="string"?n:""}function Tue(e,t){if(e.type!=="html_block"||!t)return!1;const n=String(e.raw??e.content??"");return new RegExp(String.raw`^\s*<\s*\/\s*${Gr(t)}\s*>\s*$`,"i").test(n)}const U9=new Set(["iframe","script","style","textarea","title"]);function Xp(e,t,n){if(!e||!t)return null;const o=t.toLowerCase(),s=f=>{if(e.startsWith("<!--",f)){const _=e.indexOf("-->",f+4);return{closing:!1,end:_===-1?e.length:_+3,selfClosing:!1,tag:""}}if(e.startsWith("<![CDATA[",f)){const _=e.indexOf("]]>",f+9);return{closing:!1,end:_===-1?e.length:_+3,selfClosing:!1,tag:""}}const h=Vo(e.slice(f));if(h===-1)return null;const m=f+h+1,v=e.slice(f,m);if(/^<\s*[!?]/.test(v))return{closing:!1,end:m,selfClosing:!1,tag:""};let k=v.slice(1).trimStart();const w=k.startsWith("/");w&&(k=k.slice(1).trimStart());const b=k.match(/^([A-Z][\w:-]*)/i);return b?.[1]?{closing:w,end:m,selfClosing:/\/\s*>$/.test(v),tag:b[1].toLowerCase()}:{closing:!1,end:f+1,selfClosing:!1,tag:""}},i=(f,h)=>{const m=new RegExp(String.raw`<\s*\/\s*${Gr(f)}(?=\s|>)`,"gi");m.lastIndex=h;const v=m.exec(e);if(!v||v.index==null)return null;const k=s(v.index);return k?{start:v.index,end:k.end}:null};let r=-1,l=-1,a=Math.max(0,n);for(;a<e.length;){const f=e.indexOf("<",a);if(f===-1)return null;const h=s(f);if(!h)return null;if(!h.closing&&h.tag===o){r=f,l=h.end-1;break}if(!h.closing&&U9.has(h.tag)){a=i(h.tag,h.end)?.end??e.length;continue}a=h.end}if(r===-1||l===-1)return null;const u=e.slice(r,l+1);if(eu.has(o)||/\/\s*>$/.test(u))return{raw:u,start:r,end:l+1,closed:!0};if(U9.has(o)){const f=i(o,l+1);return f?{raw:e.slice(r,f.end),start:r,end:f.end,closeStart:f.start,closed:!0}:{raw:e.slice(r),start:r,end:e.length,closed:!1}}let c=1,d=l+1;for(;d<e.length;){const f=e.indexOf("<",d);if(f===-1)return{raw:e.slice(r),start:r,end:e.length,closed:!1};const h=s(f);if(!h)return null;if(h.closing&&h.tag===o){c--;const m=h.end;if(c===0)return{raw:e.slice(r,m),start:r,end:m,closeStart:f,closed:!0};d=m;continue}if(!h.closing&&h.tag===o){!h.selfClosing&&!eu.has(h.tag)&&c++,d=h.end;continue}if(!h.closing&&U9.has(h.tag)){d=i(h.tag,h.end)?.end??e.length;continue}d=h.end}return{raw:e.slice(r),start:r,end:e.length,closed:!1}}function Eue(e,t){if(!t)return 0;let n=0,o=0;for(;n<e.length&&o<t.length;){if(e[n]===t[o]){n++,o++;continue}if(e[n]==="\r"||e[n]===` +`){n++;continue}return-1}return o===t.length?n:-1}function Iue(e,t,n){return n?e:`${e.replace(/<[^>]*$/,"")} +</${t}>`}function Jw(e){return e.replace(/\r\n/g,` +`).replace(/(^|\n)[ \t]{1,4}/g,"$1")}function Lue(e,t,n){return n?e.includes(n,t)?!0:Jw(e.slice(Math.max(0,t))).includes(Jw(n)):!1}function $ue(e,t){let n=Math.max(0,t);for(;n<e.length&&(e[n]===" "||e[n]===" ");)n++;return e[n]==="\r"?(n++,e[n]===` +`&&n++,n):e[n]===` +`?n+1:t}function Qw(e){if(e.type!=="html_block"||String(e.tag??"").toLowerCase()!=="details")return!1;const t=String(e.raw??e.content??"");return/^\s*<details\b/i.test(t)}function Nue(e){if(e.type!=="html_block")return!1;const t=String(e.raw??e.content??"");return/^\s*<\/details\b/i.test(t)}function HL(e,t){const n=new RegExp(String.raw`<\s*\/\s*${Gr(t)}(?=\s|>)`,"gi");let o=-1,s;for(;(s=n.exec(e))!==null;)o=s.index;return o}function zL(e,t){return{final:t,__disableStreamParse:!0,requireClosingStrong:e.requireClosingStrong,customHtmlTags:e.customHtmlTags,validateLink:e.validateLink}}const Fue=new Set(["admonition","blockquote","code_block","definition_list","footnote","heading","list","math_block","table","thematic_break"]),Rue=/(?:^|\n)\s{0,3}(?:#{1,6}\s+\S|[-+*]\s+\S|\d+[.)]\s+\S|>\s*\S|`{3,}|~{3,}|(?:\*{3,}|-{3,}|_{3,})(?:\s|$)|\|.*\|)/m;function Oue(e){return/\n\s*\n/.test(e)||Rue.test(e)}function Pue(e,t){if(!e.trim()||t.length===0)return!1;if(t.some(o=>Fue.has(String(o?.type??"").toLowerCase()))||t.some(o=>{if(o?.type!=="html_block")return!1;const s=o;return Array.isArray(s.children)&&s.children.length>0}))return!0;if(!Oue(e))return!1;if(t.length>1)return!0;const[n]=t;return!!(n&&n.type==="paragraph")}function Due(e){const t=[];let n=0;for(;n<e.length;){for(;/\s/.test(e[n]??"");)n++;if(n>=e.length)break;const o=e.slice(n).match(/^<([A-Z][\w:-]*)/i);if(!o?.[1])return null;const s=Xp(e,o[1],n);if(!s||s.start!==n)return null;t.push(s.raw),n=s.end}return t.length>1?t:null}function Bue(e,t,n,o){const s=n.customHtmlTags?.join("\0")??"",i=t,r=zw.get(i),l=r&&r.final===o&&r.customHtmlTags===s&&r.requireClosingStrong===n.requireClosingStrong&&r.validateLink===n.validateLink,a=e.map((u,c)=>l&&r.blocks[c]===u?r.children[c]:Ud(u,t,n));return zw.set(i,{blocks:e,children:a,customHtmlTags:s,final:o,requireClosingStrong:n.requireClosingStrong,validateLink:n.validateLink}),a.flat()}function Hue(e,t,n,o){return e.map(s=>{if(s?.type!=="html_block")return s;const i=s,r=String(i.tag??"").toLowerCase();if(!r||r==="details"||UI.has(r)||Array.isArray(i.children))return s;const l=String(s.raw??i.content??"");if(!l)return s;const a=Vo(l);if(a===-1)return s;const u=Xp(l,r,0),c=u?.closeStart??-1,d=u?.closed===!0&&c>=a+1,f=d?l.slice(a+1,c):l.slice(a+1);if(!f.trim())return s;const h=zL(n,o),m=d?null:Due(f),v=m?Bue(m,t,h,o):Ud(f,t,h);return Pue(f,v)?{...s,children:v}:s})}function zue(e){for(const t of e)if(t?.type==="html_block")return!0;return!1}function Ud(e,t,n){return e.trim()?UL(e,t,{...n,__disableStreamParse:!0}):[]}function Wue(e,t,n){const o=Ud(e,t,n),s=o[0];return o.length===1&&s?.type==="paragraph"&&Array.isArray(s.children)?s.children:o}function Uue(e,t,n){const o=ML({content:e}),s=Vo(e),i=HL(e,"summary");if(s!==-1&&i!==-1&&i>=s+1){const r=Wue(e.slice(s+1,i),t,n);r.length>0&&(o.children=r)}return o.raw=e,o}function jue(e,t,n){const o=Vo(e);if(o===-1)return[];const s=e.slice(o+1);if(!s.trim())return[];const i=Xp(s,"summary",0);if(!i)return Ud(s,t,n);const r=s.slice(0,i.start),l=s.slice(i.end);return[...Ud(r,t,n),Uue(i.raw,t,n),...Ud(l,t,n)]}function WL(e,t,n,o,s,i=0){const r=[];let l=i;for(let a=0;a<e.length;a++){const u=e[a],c=Kf(u);let d=-1;if(c&&(d=t.indexOf(c,l),d!==-1&&(l=d+c.length)),!Qw(u)){r.push(u);continue}const f=String(u.raw??Kf(u)??""),h=d!==-1?d:t.indexOf(f,Math.max(0,l-f.length));if(h===-1){r.push(u);continue}let m=1,v=-1;for(let W=a+1;W<e.length;W++){const K=e[W];if(Qw(K)){m++;continue}if(Nue(K)&&(m--,m===0)){v=W;break}}const k=Xp(t,"details",h),w=v===-1&&k?.closed===!0,b=w?(()=>{const W=HL(f,"details");return W!==-1?f.slice(0,W):f})():f,[_]=WL(w?[]:v===-1?e.slice(a+1):e.slice(a+1,v),t,n,o,s,h+f.length),g=jue(b,n,zL(o,s)),x=v===-1?"</details>":String(e[v].raw??Kf(e[v])??"</details>"),S=w||v!==-1&&k?.closed===!0,T=x.replace(/[\t\r\n ]+$/,""),A=S?(()=>{const W=(k?.raw??"").lastIndexOf(T);return W===-1?t.length:h+W})():t.length,E=Vo(f),P=w&&E!==-1?h+E+1:h+f.length,D=t.slice(P,A===-1?t.length:A),I=n.parse(D,{__markstreamFinal:s}),$=n.renderer.render(I,n.options,{__markstreamFinal:s}),B=A+T.length,H=S?Math.max(A+x.length,$ue(t,B)):t.length,O=S?t.slice(A,H):x,F=S?t.slice(h,H):t.slice(h),U=w&&E!==-1?f.slice(0,E+1):f,z={...u,tag:"details",attrs:w2(f.slice(0,E+1)),raw:F,content:`${U}${$}${O}`,children:[...g,..._],loading:!s&&!S};if(o.includeSourceMap&&(z.sourceMap=Ep(t,h,S?H:t.length,o)),r.push(z),l=S?H:t.length,v===-1&&!w)break;v!==-1&&(a=v)}return[r,l]}function Vue(e,t,n,o){if(!n)return e;const s=e.slice();let i=0;for(let r=0;r<s.length;r++){const l=s[r],a=Kf(l),u=a?n.indexOf(a,i):-1;if(l?.type!=="html_block"){u!==-1&&(i=u+a.length);continue}const c=String(l.tag??"").toLowerCase();if(!c)continue;if(c==="details"){u!==-1&&(i=u+a.length);continue}const d=Xp(n,c,u!==-1?u:i);if(!d)continue;i=d.end;const f=String(l.content??a),h=String(l.raw??f),m=u+h.length;if(u!==-1&&d.end<m&&n.slice(u,m)===h){i=m,o?.includeSourceMap&&(l.sourceMap=Ep(n,u,m,o));continue}const v=Iue(d.raw,c,d.closed),k=!t&&!d.closed,w=f!==v||h!==d.raw||!!l.loading!==k,b=Vo(d.raw),_=b===-1?"":d.raw.slice(0,b+1),g=_?w2(_):[];if(l.content=v,l.raw=d.raw,l.loading=k,l.attrs=g.length?g:void 0,o?.includeSourceMap&&(l.sourceMap=Ep(n,d.start,d.end,o)),!w)continue;let x=Eue(d.raw,h);x===-1&&(x=0);const S=r+1;for(;S<s.length;){if(d.closed&&Tue(s[S],c)){s.splice(S,1);continue}const T=Kf(s[S]);if(!T)break;const A=d.raw.indexOf(T,x);if(A===-1){if(Lue(n,d.end,T))break;const E=IL.get(s[S]);if(!E)break;if(E.start>=d.start&&E.end<=d.end){s.splice(S,1);continue}break}x=A+T.length,s.splice(S,1)}}return s}function que(e){const t=l=>l===" "||l===" "||l===` +`||l==="\r",n=l=>{if(!l||l[0]!=="<"||l.includes(">"))return!1;let a=1;if(a<l.length&&t(l[a])||l.startsWith("<!--")||l.startsWith("<?")||l.startsWith("<!")||l[a]==="/"&&(a++,a<l.length&&t(l[a])))return!1;const u=v=>{const k=v.charCodeAt(0);return k>=65&&k<=90||k>=97&&k<=122},c=v=>{const k=v.charCodeAt(0);return k>=48&&k<=57},d=v=>v==="!"||u(v),f=v=>u(v)||c(v)||v===":"||v==="-",h=v=>u(v)||c(v)||v==="_"||v==="."||v===":"||v==="-",m=h;if(a>=l.length||!d(l[a]))return!1;for(a++;a<l.length&&f(l[a]);)a++;for(;a<l.length;){for(;a<l.length&&t(l[a]);)a++;if(a>=l.length)return!0;if(l[a]==="/"){for(a++;a<l.length&&t(l[a]);)a++;return a>=l.length}if(!h(l[a]))return!1;for(a++;a<l.length&&m(l[a]);)a++;for(;a<l.length&&t(l[a]);)a++;if(a<l.length&&l[a]==="="){for(a++;a<l.length&&t(l[a]);)a++;if(a>=l.length)return!0;const v=l[a];if(v==='"'||v==="'"){for(a++;a<l.length&&l[a]!==v;)a++;if(a>=l.length)return!0;a++}else{for(;a<l.length;){const k=l[a];if(t(k)||k==="<"||k===">"||k==='"'||k==="'"||k==="`")break;a++}if(a>=l.length)return!0}}}return!0},o=(l,a)=>{let u=!1,c="",d=0;const f=b=>b===" "||b===" ",h=b=>{let _=0;for(;_<b.length&&f(b[_]);)_++;const g=b[_];if(g!=="`"&&g!=="~")return null;let x=_;for(;x<b.length&&b[x]===g;)x++;const S=x-_;return S<3?null:{markerChar:g,markerLen:S,rest:b.slice(x)}},m=b=>{let _=0;for(;_<b.length&&f(b[_]);)_++;let g=!1;for(;_<b.length&&b[_]===">";)for(g=!0,_++;_<b.length&&f(b[_]);)_++;return g?b.slice(_):null},v=b=>{const _=h(b);if(_)return _;const g=m(b);return g==null?null:h(g)};let k=0;const w=l.split(/\r?\n/);for(const b of w){const _=k,g=k+b.length;if(a<_)break;const x=v(b);if(x){const S=x.markerChar,T=x.markerLen;u?S===c&&T>=d&&/^\s*$/.test(x.rest)&&(u=!1,c="",d=0):(u=!0,c=S,d=T)}if(a<=g)break;k=g+1}return u},s=String(e??""),i=s.lastIndexOf("<");if(i===-1||o(s,i))return s;if(i>0){const l=s[i-1],a=l===" "||l===" "||l===` +`||l==="\r",u=s[i-2];if(!a&&!((l==="n"||l==="r")&&u==="\\"))return s}const r=s.slice(i);return r.includes(">")||r.length>1&&(r[1]===" "||r[1]===" "||r[1]===` +`||r[1]==="\r")||!n(r)?s:s.slice(0,i)}function e_(e,t){if(e===t)return;const n=e.split(/\r?\n/),o=t.split(/\r?\n/),s=[];let i=0;for(let r=0;r<o.length;r++){const l=o[r]??"";if(n[i]===l){s[r]={startLine:i,endLine:i+1},i++;continue}const a=n[i]??"";if(l!==""&&a!==l&&a.startsWith(l)){let h=l,m=-1;for(let v=r+1;v<o.length;v++){if(h+=o[v]??"",h===a){m=v;break}if(!a.startsWith(h))break}if(m!==-1){for(let v=r;v<=m;v++)s[v]={startLine:i,endLine:i+1};i++,r=m;continue}s[r]={startLine:i,endLine:i+1};continue}let u=n[i]??"",c=-1;for(let h=i+1;h<n.length;h++){if(u+=`\\n${n[h]??""}`,u===l){c=h+1;break}if(!l.startsWith(u))break}if(c!==-1){s[r]={startLine:i,endLine:c},i=c;continue}let d=-1;if(l!==""){const h=Math.min(n.length,i+80);for(let m=i;m<h;m++)if(n[m]===l){d=m;break}}if(d!==-1){s[r]={startLine:d,endLine:d+1},i=d+1;continue}const f=Math.min(Math.max(0,n.length-1),Math.max(0,i-1));s[r]={startLine:f,endLine:f+1}}return r=>{const l=Number.isFinite(r)?Math.max(0,Math.trunc(r)):0;if(l<s.length)return s[l]??{startLine:0,endLine:0};const a=s[s.length-1]??{startLine:Math.max(0,n.length-1),endLine:n.length},u=Math.min(n.length,a.endLine+l-s.length);return{startLine:u,endLine:Math.min(n.length,u+1)}}}function Kue(e,t){if(!e||!t.length)return e;const n=new Set(t.map(m=>String(m??"").toLowerCase()).filter(Boolean));if(!n.size)return e;const o=m=>m===" "||m===" ",s=m=>{const v=m.charCodeAt(0);return v>=65&&v<=90||v>=97&&v<=122||v>=48&&v<=57||m==="_"||m==="-"||m===":"},i=m=>{if(!m)return!1;if(m[0]===" ")return!0;let v=0;for(let k=0;k<m.length;k++){const w=m[k];if(w===" "){if(v++,v>=4)return!0;continue}if(w===" ")return!0;break}return!1},r=m=>{let v=!1,k=!1;for(let w=0;w<m.length;w++){const b=m[w];if(b==="\\"){w++;continue}if(!k&&b==="'"){v=!v;continue}if(!v&&b==='"'){k=!k;continue}if(!v&&!k&&b===">")return w}return-1},l=m=>{let v=0;for(;v<m.length&&o(m[v]);)v++;const k=m[v];if(k!=="`"&&k!=="~")return null;let w=v;for(;w<m.length&&m[w]===k;)w++;const b=w-v;return b<3?null:{markerChar:k,markerLen:b,rest:m.slice(w)}},a=(m,v)=>{if(i(m))return-1;const k=m.replace(/^[ \t]+/,"");if(!k||k.startsWith(">")||k.startsWith("|")||/^(?:[*+-]|\d+[.)])[\t ]+/.test(k))return-1;let w=!1,b=0;for(;b<m.length;){const _=m[b];if(_!=="<"){o(_)||(w=!0),b++;continue}const g=r(m.slice(b));if(g===-1){w=!0,b++;continue}const x=m.slice(b,b+g+1);let S=1;for(;S<x.length&&o(x[S]);)S++;if(S>=x.length){w=!0,b++;continue}const T=x[S];if(T==="!"||T==="?"){w=!0,b+=g+1;continue}if(T==="/"){w=!0,b+=g+1;continue}const A=S;for(;S<x.length&&s(x[S]);)S++;if(S===A){w=!0,b++;continue}const E=x.slice(A,S).toLowerCase(),P=x[S];if(P&&P!==" "&&P!==" "&&P!==">"&&P!=="/"){w=!0,b++;continue}const D=new RegExp(String.raw`<\s*\/\s*${E}\s*>`,"i"),I=/\/\s*>$/.test(x),$=D.test(m.slice(b+g+1)),B=D.test(e.slice(v+b+g+1)),H=/[\r\n]/.test(e.slice(v+b+g+1));if(w&&n.has(E)&&!I&&!$&&(B||H))return b;w=!0,b+=g+1}return-1};let u=!1,c="",d=0,f="",h=0;for(;h<e.length;){const m=e.indexOf(` +`,h),v=m!==-1,k=v&&m>h&&e[m-1]==="\r",w=v?k?m-1:m:e.length,b=e.slice(h,w),_=v?k?`\r +`:` +`:"",g=l(b);let x=b;if(!u&&!g){const S=a(b,h);if(S!==-1){const T=_||` +`;x=`${b.slice(0,S).replace(/[ \t]+$/,"")}${T}${T}${b.slice(S).replace(/^[ \t]+/,"")}`}}f+=x,f+=_,g&&(u?g.markerChar===c&&g.markerLen>=d&&/^\s*$/.test(g.rest)&&(u=!1,c="",d=0):(u=!0,c=g.markerChar,d=g.markerLen)),h=v?m+1:e.length}return f}function Zue(e,t){if(!e||!t.length)return e;const n=new Set(t.map(d=>String(d??"").toLowerCase()));if(!n.size)return e;const o=d=>d===" "||d===" ",s=d=>{const f=d.charCodeAt(0);return f>=65&&f<=90||f>=97&&f<=122||f>=48&&f<=57||d==="_"||d==="-"},i=d=>{let f=0;for(;f<d.length&&o(d[f]);)f++;return d.slice(f)},r=d=>{let f=!1,h=!1;for(let m=0;m<d.length;m++){const v=d[m];if(v==="\\"){m++;continue}if(!h&&v==="'"){f=!f;continue}if(!f&&v==='"'){h=!h;continue}if(!f&&!h&&v===">")return m}return-1},l=(d,f,h)=>{const m=h.toLowerCase();let v=d.indexOf("<",f);for(;v!==-1;){let k=v+1;for(;k<d.length&&o(d[k]);)k++;if(k>=d.length||d[k]!=="/"){v=d.indexOf("<",v+1);continue}for(k++;k<d.length&&o(d[k]);)k++;if(k+m.length>d.length){v=d.indexOf("<",v+1);continue}let w=!0;for(let _=0;_<m.length;_++){const g=d[k+_];if((g>="A"&&g<="Z"?String.fromCharCode(g.charCodeAt(0)+32):g)!==m[_]){w=!1;break}}if(!w){v=d.indexOf("<",v+1);continue}let b=k+m.length;if(b<d.length&&s(d[b])){v=d.indexOf("<",v+1);continue}for(;b<d.length&&o(d[b]);)b++;if(b<d.length&&d[b]===">")return!0;v=d.indexOf("<",v+1)}return!1},a=d=>{let f=0;for(;f<d.length&&o(d[f]);)f++;if(f>=d.length||d[f]!=="<")return d;for(f++;f<d.length&&o(d[f]);)f++;if(f>=d.length||d[f]==="/")return d;const h=f;for(;f<d.length&&s(d[f]);)f++;if(f===h)return d;const m=d.slice(h,f).toLowerCase();if(!n.has(m))return d;const v=r(d.slice(f));if(v===-1)return d;const k=f+v;if(l(d,k+1,m))return d;const w=i(d.slice(k+1));return w?`${d.slice(0,k+1)} +${w}`:d};let u="",c=0;for(;c<e.length;){const d=e.indexOf(` +`,c);if(d===-1){u+=a(e.slice(c));break}const f=d>c&&e[d-1]==="\r",h=f?d-1:d,m=e.slice(c,h);u+=a(m),u+=f?`\r +`:` +`,c=d+1}return u}function Gue(e,t){if(!e||!t.length)return e;const n=new Set(t.map(f=>String(f??"").toLowerCase()));if(!n.size)return e;const o=f=>f===" "||f===" ",s=f=>{let h=0,m=!1,v=0;for(;h<f.length;){for(;h<f.length&&o(f[h]);)h++;if(h>=f.length||f[h]!==">")break;for(m=!0,h++;h<f.length&&o(f[h]);)h++;v=h}return m?{prefix:f.slice(0,v),content:f.slice(v)}:null},i=f=>{let h=0;for(;h<f.length&&o(f[h]);)h++;const m=f[h];if(m!=="`"&&m!=="~")return null;let v=h;for(;v<f.length&&f[v]===m;)v++;const k=v-h;return k<3?null:{markerChar:m,markerLen:k,rest:f.slice(v)}},r=Array.from(n).map(f=>new RegExp(String.raw`(<\s*\/\s*${f}\s*>)${"(?=[\\t ]*(?:#{1,6}[\\t ]+|>|(?:[*+-]|\\d+[.)])[\\t ]+|(?:`{3,}|~{3,})|\\||\\$\\$|:{3,}|\\[\\^[^\\]]+\\]:|(?:-{3,}|\\*{3,}|_{3,})))"}`,"gi"));let l=!1,a="",u=0,c="",d=0;for(;d<e.length;){const f=e.indexOf(` +`,d),h=f!==-1,m=h&&f>d&&e[f-1]==="\r",v=h?m?f-1:f:e.length,k=e.slice(d,v),w=h?m?`\r +`:` +`:"",b=s(k),_=b?.prefix??"",g=b?.content??k,x=i(g);x&&(l?x.markerChar===a&&x.markerLen>=u&&/^\s*$/.test(x.rest)&&(l=!1,a="",u=0):(l=!0,a=x.markerChar,u=x.markerLen));let S=g;if(!l&&S.includes("</"))for(const T of r)S=S.replace(T,(A,E,P,D)=>{if(D.replace(/^[\t ]+/,"").startsWith("|"))return A;const I=D.slice(0,P).replace(/^[\t ]+/,"");if(I.length>0){const $=E.match(/^<\s*\/\s*([A-Z][\w:-]*)/i)?.[1]?.toLowerCase()??"",B=I.match(/^<\s*([A-Z][\w:-]*)/i)?.[1]?.toLowerCase()??"";if(!$||!B||$!==B)return A}return`${E} + +`});if(_){const T=_+S.split(` +`).join(` +${_}`);c+=T}else c+=S;c+=w,d=h?f+1:e.length}return c}function Yue(e,t){if(!e||!t.length)return e;const n=new Set(t.map(I=>String(I??"").toLowerCase()));if(!n.size)return e;const o=I=>I===" "||I===" ",s=I=>{if(!I)return!1;if(I[0]===" ")return!0;let $=0;for(let B=0;B<I.length;B++){const H=I[B];if(H===" "){if($++,$>=4)return!0;continue}if(H===" ")return!0;break}return!1},i=I=>{const $=I.charCodeAt(0);return $>=65&&$<=90||$>=97&&$<=122||$>=48&&$<=57||I==="_"||I==="-"||I===":"},r=I=>{let $=0;for(;$<I.length&&o(I[$]);)$++;return I.slice($)},l=I=>{let $=0,B=!1,H=0;for(;$<I.length;){for(;$<I.length&&o(I[$]);)$++;if($>=I.length||I[$]!==">")break;for(B=!0,$++;$<I.length&&o(I[$]);)$++;H=$}if(!B)return null;const O=I.slice(0,H);return{prefix:O,key:O.replace(/[ \t]+$/,""),content:I.slice(H)}},a=I=>r(I).startsWith("<"),u=I=>{for(let $=0;$<I.length;$++){const B=I[$];if(B!==" "&&B!==" ")return!1}return!0},c=I=>{if(s(I))return"";const $=r(I);if(!$.startsWith("<"))return"";let B=1;for(;B<$.length&&o($[B]);)B++;if(B>=$.length||$[B]==="/"||$[B]==="!"||$[B]==="?")return"";const H=B;for(;B<$.length&&i($[B]);)B++;if(B===H)return"";const O=$.slice(H,B).toLowerCase();if(!n.has(O))return"";const F=$[B];return F&&F!==" "&&F!==" "&&F!==">"&&F!=="/"?"":O},d=I=>{if(s(I))return null;const $=r(I);if(!$.startsWith("<"))return null;let B=1;for(;B<$.length&&o($[B]);)B++;if(B>=$.length)return null;const H=$[B]==="/";if(H)for(B++;B<$.length&&o($[B]);)B++;const O=$[B];if(!O||O==="!"||O==="?")return null;const F=B;for(;B<$.length&&i($[B]);)B++;if(B===F)return null;const U=$.slice(F,B).toLowerCase();if(!n.has(U))return null;const z=$[B];if(z&&z!==" "&&z!==" "&&z!==">"&&z!=="/")return null;if(H)return{type:"close",name:U};if(/\/\s*>\s*$/.test($))return{type:"open",name:U,complete:!0};const W=$.indexOf(">",B);if(W!==-1){const K=$.slice(W+1);if(new RegExp(`<\\s*\\/\\s*${U}\\s*>`,"i").test(K))return{type:"open",name:U,complete:!0}}return{type:"open",name:U,complete:!1}},f=I=>{if(s(I))return null;const $=r(I).replace(/[ \t]+$/,"");if(!$.startsWith("<")||/^<\s*(?:!--|!doctype\b|\?)/i.test($))return null;const B=$.match(/^<\s*([A-Z][\w:-]*)\b[^>]*\/\s*>\s*$/i);if(B?.[1])return B[1].toLowerCase();const H=$.match(/^<\s*([A-Z][\w:-]*)\b[^>]*>[\s\S]*<\s*\/\s*([A-Z][\w:-]*)\s*>\s*$/i);if(!H?.[1]||!H[2])return null;const O=H[1].toLowerCase();return O===H[2].toLowerCase()?O:null};let h=!1,m="",v=0;const k=I=>{let $=0;for(;$<I.length&&o(I[$]);)$++;const B=I[$];if(B!=="`"&&B!=="~")return null;let H=$;for(;H<I.length&&I[H]===B;)H++;const O=H-$;return O<3?null:{markerChar:B,markerLen:O,rest:I.slice(H)}},w=I=>k(I),b=I=>{const $=r(I);return $?s(I)?!0:/^(?:#{1,6}[ \t]+|>|[*+-][ \t]+|\d+[.)][ \t]+|`{3,}|~{3,}|\||\$\$|:{3,}|\[\^[^\]]+\]:|-{3,}|\*{3,}|_{3,})/.test($):!1},_=(I,$,B)=>{let H=I,O=0;for(;H<e.length;){const F=e.indexOf(` +`,H),U=F!==-1,z=U&&F>H&&e[F-1]==="\r",W=U?z?F-1:F:e.length,K=e.slice(H,W),V=l(K),ie=V?.key??"";if(O>0&&$&&ie!==$)break;const ne=V?.content??K,X=d(ne);if(X?.name===B){if(X.type==="open")X.complete||O++;else if(O>0&&(O--,O===0))return!1}else if(O>0&&(u(ne)||b(ne)))return!0;if(U)H=F+1;else break}return!1};let g="",x=0,S=!0,T=!1,A=!1,E=` +`;const P=[];let D="";for(;x<e.length;){const I=e.indexOf(` +`,x),$=I!==-1,B=$&&I>x&&e[I-1]==="\r",H=$?B?I-1:I:e.length,O=e.slice(x,H),F=$?B?`\r +`:` +`:"",U=l(O),z=U?.key??"",W=U?.content??O,K=w(W);K&&(h?K.markerChar===m&&K.markerLen>=v&&/^\s*$/.test(K.rest)&&(h=!1,m="",v=0):(h=!0,m=K.markerChar,v=K.markerLen));const V=P.length>0;if(!h&&!V){const ne=c(W),X=!!ne&&!S&&T&&A&&_(x,z,ne);ne&&!S&&(!T||X)&&(z&&D&&z===D?g+=`${z}${E}`:z||(g+=E))}if(g+=O,g+=F,F&&(E=F),!h){const ne=d(W);if(ne){if(ne.type==="open")ne.complete||P.push(ne.name);else for(let X=P.length-1;X>=0;X--)if(P[X]===ne.name){P.length=X;break}}}const ie=u(W);S=ie,T=!ie&&a(W),A=!ie&&!!f(W),D=z,x=$?I+1:e.length}return g}function UL(e,t,n={}){const o=LL(n),s=o?l1():0,i=!!n.final,r=(e??"").toString();let l=r.replace(/([^\\])\r(ight|ho)/g,"$1\\r$2").replace(/([^\\])\r?\n(abla|eq|ot|exists)/g,"$1\\n$2");if(rue(t,n)&&(t.stream.reset(),lue(t)),i||(l.endsWith("- *")&&(l=l.replace(/- \*$/,"- \\*")),/(?:^|\n)\s*-\s*$/.test(l)?l=l.replace(/(?:^|\n)\s*-\s*$/,b=>b.startsWith(` +`)?` +`:""):/(?:^|\n)\s*--\s*$/.test(l)?l=l.replace(/(?:^|\n)\s*--\s*$/,b=>b.startsWith(` +`)?` +`:""):/(?:^|\n)\s*>\s*$/.test(l)?l=l.replace(/(?:^|\n)\s*>\s*$/,b=>b.startsWith(` +`)?` +`:""):/\n\s*[*+]\s*$/.test(l)?l=l.replace(/\n\s*[*+]\s*$/,` +`):/(?:^|\n)\s*\d+\s*$/.test(l)?/^\d+$/.test(l.trim())||(l=l.replace(/(?:^|\n)\s*\d+\s*$/,b=>b.startsWith(` +`)?` +`:"")):/(?:^|\n)\s*\d+[.)]\s+\*{1,3}\s*$/.test(l)?l=l.replace(/((?:^|\n)\s*\d+[.)]\s+)(\*{1,3})\s*$/,(b,_,g)=>`${_}${g.split("").map(()=>"\\*").join("")}`):/(?:^|\n)\s*\d+[.)]\s*$/.test(l)?l=l.replace(/(?:^|\n)\s*\d+[.)]\s*$/,b=>b.startsWith(` +`)?` +`:""):/\n[[(]\n*$/.test(l)&&(l=l.replace(/(\n\[|\n\()+\n*$/g,` +`)),l=yue(l,t),l=gue(l,n.customHtmlTags)??l),n.customHtmlTags?.length&&l.includes("<")){const b=Ec(n.customHtmlTags);if(b.length&&(l=Kue(l,b),l=Zue(l,b),l=Yue(l,b),l=Gue(l,b),l.includes("</")))for(const _ of b){const g=new RegExp(String.raw`(^[\t ]*<\s*\/\s*${_}\s*>[\t ]*)(\r?\n)(?![\t ]*\r?\n|$)`,"gim");l=l.replace(g,"$1$2$2")}}i||(l=que(l));const a=Mue(l);if(a){if(n.includeSourceMap){const g={...n,__sourceLineMapper:e_(r,l)};a[0].sourceMap=Ep(l,0,l.length,g)}const b=n.preTransformTokens,_=n.postTransformTokens;if(s5(t,n)||typeof b=="function"||typeof _=="function"){const g=Zw(t,l,{__markstreamFinal:i},n),x=typeof b=="function"&&b(g)||g;typeof _=="function"&&_(x)}return Uw(a,n,o,s)}const u=Zw(t,l,{__markstreamFinal:i},n);if(!u||!Array.isArray(u))return Uw([],n,o,s);const c=n.preTransformTokens,d=n.postTransformTokens;let f=u;c&&typeof c=="function"&&(f=c(f)||f);const h=t,m=typeof h.validateLink=="function"&&h.__markstreamOriginalValidateLink&&h.validateLink!==h.__markstreamOriginalValidateLink?h.validateLink:void 0,v=n.validateLink??m??h.options?.validateLink??(typeof h.validateLink=="function"?h.validateLink:void 0),k={...n,validateLink:v,__markdownIt:t,__sourceLineMapper:n.includeSourceMap===!0?e_(r,l):void 0,__sourceMarkdown:l,__customHtmlBlockCursor:0};let w=nue(t,l,f,k,o);if(d&&typeof d=="function"){const b=d(f);if(Array.isArray(b)){const _=b[0],g=_?.type;_&&typeof g=="string"?w=Yh(b,{...k,__customHtmlBlockCursor:0},o):w=b}}if(zue(w)&&(w=Vue(w,i,l,k),w=WL(w,l,t,k,i)[0],w=Hue(w,t,k,i)),i){const b=new WeakSet,_=g=>{if(!g||typeof g!="object"||b.has(g))return;if(b.add(g),Array.isArray(g)){for(const S of g)_(S);return}const x=g;x.type==="html_block"&&x.loading===!0&&(x.loading=!1);for(const S of Object.values(x))_(S)};_(w)}return w=NL(w,n),n.debug&&console.log("Parsed Markdown Tree Structure:",w),$L(w,o,s)}function t_(e,t){if(!e||!Array.isArray(e))return[];const n=[],o=fu(t),s=t?.includeSourceMap===!0;let i=0;for(;i<e.length;){const r=o5(e,i,o.options(),n5);if(r){al(r[0],e[i],t),n.push(r[0]),o.remember(r[0].raw),i=r[1];continue}const l=e[i];switch(l.type){case"paragraph_open":{const a=String(e[i+1]?.content??""),u=qae(e,i,o.options(a));s&&Dn(u,l,t);const c=Xw(u,t);if(c){s&&Yw(c,u);for(const d of c)al(d,l,t);n.push(...c)}else al(u,l,t),n.push(u);o.remember(u.raw),i+=3;break}case"bullet_list_open":case"ordered_list_open":{const[a,u]=b1(e,i,o.options());s&&Dn(a,l,t),al(a,l,t),n.push(a),o.remember(a.raw),i=u;break}case"blockquote_open":{const[a,u]=C1(e,i,o.options());s&&Dn(a,l,t),al(a,l,t),n.push(a),o.remember(a.raw),i=u;break}case"footnote_anchor":{const a=l.meta??{},u={type:"footnote_anchor",id:String(a.label??l.content??""),raw:String(l.content??"")};s&&Dn(u,l,t),al(u,l,t),n.push(u),o.remember(String(l.content??"")),i++;break}case"hardbreak":n.push(Vae()),o.reset(),i++;break;case"text":{const a=String(l.content??""),u={type:"paragraph",raw:a,children:a?[{type:"text",content:a,raw:a}]:[]};s&&Dn(u,l,t),al(u,l,t),n.push(u),o.remember(a),i++;break}case"inline":{const a=String(l.content??""),u=$o(l.children||[],a,void 0,o.options(a));if(u.length!==0)if(u.every(c=>c.type==="html_block")){if(s)for(const c of u)Dn(c,l,t);for(const c of u)al(c,l,t);n.push(...u)}else{const c={type:"paragraph",raw:a,children:u};s&&Dn(c,l,t);const d=Xw(c,t);if(d){s&&Yw(d,c);for(const f of d)al(f,l,t);n.push(...d)}else al(c,l,t),n.push(c)}o.remember(a)}i+=1;break;default:i+=1;break}}return n}const Xue=/^([a-z][\w-]*)(?=[\t\n\f\r />]|$)/i,Jue=new Set([...Zp,"base","button","datalist","dialog","embed","fieldset","form","iframe","input","legend","link","meta","object","optgroup","option","output","param","select","style","template","textarea","title"]),Que=new Set(["a","abbr","b","blockquote","br","caption","code","col","colgroup","dd","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","ins","kbd","li","mark","ol","p","picture","pre","s","small","source","span","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","ul"]);function n_(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function ece(e){return typeof e=="string"?e:e==null?"":String(e)}function jL(e){return/^[^\s"'<>`=]+$/.test(e)&&!/^on/i.test(e)}function Pa(e){return ece(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function VL(e){return Pa(e).replace(/`/g,"`")}function M2(e){return String(e??"").trim().toLowerCase()}function a5(e,t="safe"){const n=M2(e);return n?t==="escape"?!0:t==="trusted"?Zp.has(n):!Que.has(n):!1}function qL(e,t="safe"){const n=M2(e);return n?t==="escape"?!0:t==="trusted"?Zp.has(n):Jue.has(n):!1}function o_(e){const t=Object.entries(e);return t.length===0?"":t.map(([n,o])=>o===""?` ${n}`:` ${n}="${VL(o)}"`).join("")}function KL(e){const t=e.startsWith("/"),n=t?e.slice(1):e,o=n.match(Xue);return o?{attrsStr:t?"":n.slice(o[0].length).trimStart(),isClosing:t,isSelfClosing:!t&&e.trimEnd().endsWith("/"),tagName:o[1]}:null}function tce(e,t){const n=e.split(",").map(o=>o.trim()).filter(Boolean);return n.length===0?!1:n.some(o=>{const s=o.split(/\s+/,1)[0]??"";return!s||lc(s,{tagName:t,attrName:"srcset"})})}function ZL(e,t,n,o){return Yse.has(e)||n==="safe"&&e==="style"?!0:e==="srcset"?tce(t,o):!!(Xse.has(e)&&t&&lc(t,{tagName:o,attrName:e}))}function Gu(e,t){const n=t.toLowerCase();return Object.keys(e).find(o=>o.toLowerCase()===n)}function GL(e,t,n,o=!1){if(t!=="safe"||M2(n)!=="a")return e;const s=Gu(e,"href");if(o&&(!s||!e[s])){const a=Gu(e,"target"),u=Gu(e,"rel");return a&&delete e[a],u&&delete e[u],e}const i=Gu(e,"target");if((i?String(e[i]).trim():"").toLowerCase()!=="_blank")return e;const r=Gu(e,"rel"),l=new Set(String(r?e[r]:"").split(/\s+/).map(a=>a.trim()).filter(Boolean).filter(a=>a.toLowerCase()!=="opener"));return l.add("noopener"),l.add("noreferrer"),r&&r!=="rel"&&delete e[r],e.rel=Array.from(l).join(" "),e}function s_(e,t="safe",n){const o={};for(const[s,i]of Object.entries(e)){const r=s.trim(),l=r.toLowerCase();!r||!jL(r)||ZL(l,i,t,n)||(o[r]=i)}return GL(o,t,n,!!Gu(e,"href"))}function YL(e,t){const n=e.toLowerCase();return WI.has(n)?!1:n_(t,n)||n_(t,e)}function u5(e,t="safe",n){const o={};for(const[s,i]of Object.entries(e)){const r=s.trim(),l=r.toLowerCase();!r||!jL(r)||ZL(l,i,t,n)||(o[r]=i)}return GL(o,t,n,!!Gu(e,"href"))}function Zf(e){const t={};if(!Array.isArray(e)||e.length===0)return t;for(const[n,o]of e)n&&(t[String(n)]=o==null?"":String(o));return t}function Xh(e,t="safe",n){const o=u5(Zf(e),t,n),s=Object.entries(o).map(([i,r])=>[i,r]);return s.length>0?s:void 0}function nce(e,t){const n=t.toLowerCase();if(["checked","disabled","readonly","required","autofocus","multiple","hidden"].includes(n))return e==="true"||e===""||e===t;if(["value","min","max","step","width","height","size","maxlength"].includes(n)){const o=Number(e);if(e!==""&&!Number.isNaN(o))return o}return e}function oce(e){const t={};for(const[n,o]of Object.entries(e))t[n]=nce(o,n);return t}function j9(e){return e.trim().length>0}function XL(e){const t=[];let n=0;for(;n<e.length;){if(e.startsWith("<!--",n)){const r=e.indexOf("-->",n);if(r!==-1){n=r+3;continue}break}const o=e.indexOf("<",n);if(o===-1){if(n<e.length){const r=e.slice(n);j9(r)&&t.push({type:"text",content:r})}break}if(o>n){const r=e.slice(n,o);j9(r)&&t.push({type:"text",content:r})}if(e.startsWith("![CDATA[",o+1)){const r=e.indexOf("]]>",o);if(r!==-1){t.push({type:"text",content:e.slice(o,r+3)}),n=r+3;continue}break}if(e.startsWith("!",o+1)){const r=e.indexOf(">",o);if(r!==-1){n=r+1;continue}break}const s=e.indexOf(">",o);if(s===-1)break;const i=KL(e.slice(o+1,s));if(!i){const r=e.slice(o,s+1);j9(r)&&t.push({type:"text",content:r}),n=s+1;continue}if(i.isClosing)t.push({type:"tag_close",tagName:i.tagName});else{const r={};if(i.attrsStr){const l=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|(\S*)))?/g;let a;for(;(a=l.exec(i.attrsStr))!==null;){const u=a[1],c=a[2]??a[3]??a[4]??"";u&&!u.endsWith("/")&&(r[u]=c)}}t.push({type:i.isSelfClosing||eu.has(i.tagName.toLowerCase())?"self_closing":"tag_open",tagName:i.tagName,attrs:r})}n=s+1}return t}function sce(e){const t=[];let n=0;for(;n<e.length;){if(e.startsWith("<!--",n)){const l=e.indexOf("-->",n);if(l!==-1){n=l+3;continue}break}const o=e.indexOf("<",n);if(o===-1){n<e.length&&t.push({type:"text",content:e.slice(n)});break}if(o>n&&t.push({type:"text",content:e.slice(n,o)}),e.startsWith("![CDATA[",o+1)){const l=e.indexOf("]]>",o);if(l!==-1){t.push({type:"text",content:e.slice(o,l+3)}),n=l+3;continue}break}if(e.startsWith("!",o+1)){const l=e.indexOf(">",o);if(l!==-1){n=l+1;continue}break}const s=e.indexOf(">",o);if(s===-1)break;const i=KL(e.slice(o+1,s));if(!i){t.push({type:"text",content:e.slice(o,s+1)}),n=s+1;continue}if(i.isClosing){t.push({type:"tag_close",tagName:i.tagName}),n=s+1;continue}const r={};if(i.attrsStr){const l=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|(\S*)))?/g;let a;for(;(a=l.exec(i.attrsStr))!==null;){const u=a[1],c=a[2]??a[3]??a[4]??"";u&&!u.endsWith("/")&&(r[u]=c)}}t.push({type:i.isSelfClosing||eu.has(i.tagName.toLowerCase())?"self_closing":"tag_open",tagName:i.tagName,attrs:r}),n=s+1}return t}function ice(e){const t=String(e.tagName??"").trim();if(!t)return"";if(e.type==="tag_close")return`</${Pa(t)}>`;const n=Object.entries(e.attrs??{}).map(([o,s])=>s===""?` ${Pa(o)}`:` ${Pa(o)}="${VL(s)}"`).join("");return e.type==="self_closing"?`<${Pa(t)}${n} />`:`<${Pa(t)}${n}>`}function rce(e,t){if(!e||!e.includes("<")||!t||Object.keys(t).length===0)return!1;for(const n of XL(e))if((n.type==="tag_open"||n.type==="self_closing")&&YL(n.tagName??"",t))return!0;return!1}function jd(e,t="safe"){if(!e)return"";if(t==="escape")return Pa(e);const n=sce(e),o=[],s=[],i=[];for(const r of n){if(r.type==="text"){i.length===0&&s.push(Pa(r.content??""));continue}const l=M2(r.tagName);if(!l)continue;if(qL(l,t)){r.type==="tag_open"?i.push(l):r.type==="tag_close"&&i[i.length-1]===l&&i.pop();continue}if(i.length>0)continue;if(t==="safe"&&a5(l,t)){s.push(ice(r));continue}if(r.type==="self_closing"){s.push(`<${l}${o_(s_(r.attrs??{},t,l))}>`);continue}if(r.type==="tag_open"){s.push(`<${l}${o_(s_(r.attrs??{},t,l))}>`),eu.has(l)||o.push(l);continue}const a=o.lastIndexOf(l);if(a===-1)continue;for(;o.length>a+1;){const c=o.pop();c&&s.push(`</${c}>`)}const u=o.pop();u&&s.push(`</${u}>`)}for(;o.length>0;){const r=o.pop();r&&s.push(`</${r}>`)}return s.join("")}const lce=[/javascript:/i,/vbscript:/i,/data:text\/html/i,/expression\s*\(/i,/@import/i],i_="http://www.w3.org/2000/svg",ace=new Set(["script","style","iframe","object","embed","link","meta"]),uce=new Set(["svg","style","g","a","defs","marker","path","rect","circle","ellipse","line","polyline","polygon","text","tspan","title","desc","use","image","lineargradient","radialgradient","stop","clippath","mask","pattern"]),cce=new Set(["href","xlink:href","src","srcdoc","action","data","formaction","poster"]),dce=new Set(["clip-path","fill","filter","marker-end","marker-mid","marker-start","mask","stroke"]),fce=new Set(["circle","ellipse","image","line","path","polygon","polyline","rect","text","tspan","use"]);function pce(e){return(e.getAttribute("href")||e.getAttribute("xlink:href"))?.startsWith("#")===!0}function hce(e){return!!(e.getAttribute("href")||e.getAttribute("xlink:href")||e.getAttribute("src"))}function mce(e){const t=e.nodeName.toLowerCase();return t==="use"?pce(e):t==="image"?hce(e):t==="text"||t==="tspan"?!!e.textContent?.trim():fce.has(t)}function gce(e){return e.replace(/(["'])\s*javascript:/gi,"$1#").replace(/\bjavascript:/gi,"#").replace(/(["'])\s*vbscript:/gi,"$1#").replace(/\bvbscript:/gi,"#").replace(/\bdata:text\/html/gi,"#")}function vce(e,t,n){const o=e.toLowerCase(),s=t.toLowerCase(),i=String(n??"").trim();return i?(o==="use"||o==="marker"||o==="clippath"||o==="mask")&&(s==="href"||s==="xlink:href")?i.startsWith("#")?i:"":o==="a"&&(s==="href"||s==="xlink:href")?lc(i,{tagName:"a",attrName:"href"})?"":i:o==="image"&&(s==="href"||s==="xlink:href"||s==="src")?lc(i,{tagName:"img",attrName:"src"})?"":i:s==="href"||s==="xlink:href"?i.startsWith("#")?i:"":lc(i,{tagName:o,attrName:s})?"":i:""}function yce(e,t){let n=t+4;for(;n<e.length&&/\s/.test(e[n]??"");)n++;const o=e[n];if(o==='"'||o==="'"){const i=n+1,r=e.indexOf(o,i);if(r===-1)return{next:e.length,url:""};for(n=r+1;n<e.length&&/\s/.test(e[n]??"");)n++;return{next:n<e.length&&e[n]===")"?n+1:n,url:e.slice(i,r)}}const s=n;for(;n<e.length&&e[n]!==")";)n++;return{next:n<e.length?n+1:n,url:e.slice(s,n)}}function JL(e){return e.replace(/\\([0-9a-f]{1,6}\s?|.)/gi,(t,n)=>{const o=n.trim();if(/^[0-9a-f]+$/i.test(o)){const s=Number.parseInt(o,16);try{return Number.isFinite(s)?String.fromCodePoint(s):""}catch{return""}}return String(n).trim()})}function QL(e){const t=JL(e),n=t.toLowerCase();let o=0;for(;o<n.length;){const s=n.indexOf("url(",o);if(s===-1)return!1;const i=yce(t,s);if(o=Math.max(i.next,s+4),!i.url.trim().startsWith("#"))return!0}return!1}function r_(e){const t=JL(e);return lce.some(n=>n.test(t))||QL(t)}function kce(e){if(e.tagName.toLowerCase()!=="a"||e.getAttribute("target")?.trim().toLowerCase()!=="_blank")return;const t=new Set(String(e.getAttribute("rel")??"").split(/\s+/).map(n=>n.trim()).filter(Boolean).filter(n=>n.toLowerCase()!=="opener"));t.add("noopener"),t.add("noreferrer"),e.setAttribute("rel",Array.from(t).join(" "))}function yh(e){const t=Number.parseFloat(String(e??""));return Number.isFinite(t)?t:0}function e$(e,t){if(e.nodeType===Node.TEXT_NODE){const s=e.textContent??"";s&&t.push(s);return}if(e.nodeType!==Node.ELEMENT_NODE)return;const n=e,o=n.tagName.toLowerCase();if(!ace.has(o)){if(o==="br"){t.push(` +`);return}for(const s of Array.from(n.childNodes))e$(s,t)}}function bce(e){for(const t of Array.from(e.querySelectorAll("foreignObject"))){const n=[];e$(t,n);const o=n.join("").split(/\r?\n/).map(c=>c.trim()).filter(Boolean);if(!o.length){t.remove();continue}const s=yh(t.getAttribute("width")),i=yh(t.getAttribute("height")),r=yh(t.getAttribute("x")),l=yh(t.getAttribute("y")),a=e.ownerDocument.createElementNS(i_,"text");a.setAttribute("x",String(r+s/2)),a.setAttribute("y",String(l+i/2)),a.setAttribute("text-anchor","middle"),a.setAttribute("dominant-baseline","central");const u=t.querySelector(".nodeLabel");if(u?.getAttribute("class")&&a.setAttribute("class",u.getAttribute("class")),o.length===1)a.textContent=o[0];else{const c=-.6*(o.length-1);for(const[d,f]of o.entries()){const h=e.ownerDocument.createElementNS(i_,"tspan");h.setAttribute("x",String(r+s/2)),h.setAttribute("dy",d===0?`${c}em`:"1.2em"),h.textContent=f,a.appendChild(h)}}t.parentNode?.replaceChild(a,t)}}function Cce(e){bce(e);const t=[e,...Array.from(e.querySelectorAll("*"))];for(const n of t){const o=n.tagName.toLowerCase();if(!uce.has(o)){n.remove();continue}if(o==="style"&&r_(n.textContent??"")){n.remove();continue}const s=Array.from(n.attributes);for(const i of s){const r=i.name.toLowerCase();if(/^on/i.test(r)){n.removeAttribute(i.name);continue}if(r==="style"&&i.value&&r_(i.value)){n.removeAttribute(i.name);continue}if(r==="srcdoc"){n.removeAttribute(i.name);continue}if(cce.has(r)&&i.value){const l=vce(o,r,i.value);if(!l){n.removeAttribute(i.name);continue}l!==i.value&&n.setAttribute(i.name,l);continue}if(dce.has(r)&&i.value&&QL(i.value)){n.removeAttribute(i.name);continue}if(i.value){const l=gce(i.value);l!==i.value&&n.setAttribute(i.name,l)}}kce(n)}}function CVe(e){if(typeof DOMParser>"u"||!e)return null;try{const t=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;if(!t||t.nodeName.toLowerCase()!=="svg")return null;const n=t;return Cce(n),wce(n)?null:n}catch{return null}}function wce(e){const t=e.getAttribute("viewBox");if(t){const s=t.trim().split(/[\s,]+/);if(s.length===4){const i=Number.parseFloat(s[2]||""),r=Number.parseFloat(s[3]||"");if(!Number.isFinite(i)||!Number.isFinite(r)||i<=0||r<=0)return!0}}const n=[e,...Array.from(e.querySelectorAll("*"))];let o=!1;for(const s of n){mce(s)&&(o=!0);for(const i of Array.from(s.attributes))if(/\bNaN\b/i.test(i.value)||i.name==="style"&&/max-width:\s*0(?:px)?/i.test(i.value))return!0}return!o}const kh=[];function V9(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function _ce(e){return(String(e||"text").trim().split(/\s+/)[0]||"text").replace(/[^\w+.#:-]/g,"-").replace(/-+/g,"-")||"text"}function xce(e){return e.replace(/[^\w:.+-]/g,"-").replace(/-+/g,"-")}function l_(e=`editor-${Date.now()}`,t={}){const n=fle(t),o=n;o.__markstreamRegisteredPluginCount=kh.length,o.__markstreamHasCustomParserExtensions=!!(t.plugin?.length||t.apply?.length||kh.length);const s={"common.copy":"Copy"};let i;if(typeof t.i18n=="function")i=t.i18n;else if(t.i18n&&typeof t.i18n=="object"){const m=t.i18n;i=v=>m[v]??s[v]??v}else i=m=>s[m]??m;if(Array.isArray(t.plugin))for(const m of t.plugin){const v=m;if(Array.isArray(v)){const[k,...w]=v;typeof k=="function"&&n.use(k,...w)}else typeof v=="function"&&n.use(v)}if(Array.isArray(t.apply))for(const m of t.apply)try{m(n)}catch(v){console.error("[getMarkdown] apply function threw an error",v)}if(kh.length)for(const m of kh)if(Array.isArray(m)){const[v,...k]=m;typeof v=="function"&&n.use(v,...k)}else typeof m=="function"&&n.use(m);n.use(Tee),n.use(Lee),n.use(See);const r=Vee,l=r.default??r;n.use(l),n.use(xee),n.use(_ee),n.core.ruler.after("block","mark_fence_closed",m=>{const v=m,k=v.src,w=!!v.env?.__markstreamFinal,b=k.split(/\r?\n/);for(const _ of v.tokens){if(_.type!=="fence"||!_.map||!_.markup)continue;const g=_.map[0],x=_.map[1],S=_.markup,T=S[0],A=S.length,E=b[Math.max(0,x-1)]??"";let P=0;for(;P<E.length&&(E[P]===" "||E[P]===" ");)P++;let D=0;for(;P+D<E.length&&E[P+D]===T;)D++;let I=P+D;for(;I<E.length&&(E[I]===" "||E[I]===" ");)I++;const $=w?!0:x>g+1&&D>=A&&I===E.length,B=_;B.meta=B.meta??{},B.meta.unclosed=!$,B.meta.closed=!!$}});const a=(m,v)=>{const k=m,w=k.pos;if(k.src[w]!=="~")return!1;const b=k.src[w-1],_=k.src[w+1];if(/\d/.test(b)&&/\d/.test(_)){if(!v){const g=k.push("text","",0);g.content="~"}return k.pos+=1,!0}return!1};n.inline.ruler.before("sub","wave",a),n.renderer.rules.fence=(m,v)=>{const k=m[v],w=String(k.info??"").trim(),b=String(k.content??""),_=btoa(unescape(encodeURIComponent(b))),g=_ce(w),x=V9(g),S=xce(`editor-${e}-${v}-${g}`),T=V9(i("common.copy"));return`<div class="code-block" data-code="${_}" data-lang="${x}" id="${S}"> + <div class="code-header"> + <span class="code-lang">${V9(g.toUpperCase())}</span> + <button class="copy-button" data-code="${_}">${T}</button> + </div> + <div class="code-editor"></div> + </div>`};const u=/^\[(\d+)\]/,c=/^\[([^\]\n]+)\]/,d=m=>{if(!m.startsWith("["))return!1;const v=c.exec(m);if(!v)return m!=="["&&!/^\[\d+$/.test(m);const k=String(v[1]??"");return m.slice(v[0].length).startsWith("(")?!1:!/^\d+$/.test(k)},f=(m,v)=>{const k=m;if(k.src[k.pos]!=="[")return!1;const w=u.exec(k.src.slice(k.pos));if(!w)return!1;const b=k.src.slice(Math.max(0,k.pos-120),k.pos);if(/"[^"\n]{1,80}"\s*:\s*$/.test(b))return!1;const _=k.src.slice(k.pos+w[0].length);if(_.startsWith("](")||_.startsWith("(")||d(_))return!1;if(!v){const g=w[1],x=k.push("reference","span",0);x.content=g,x.markup=w[0],x.raw=w[0]}return k.pos+=w[0].length,!0};n.inline.ruler.before("escape","reference",f),n.renderer.rules.reference=(m,v)=>{const w=String(m[v].content??"");return`<span class="reference-link" data-reference-id="${w}" role="button" tabindex="0" title="Click to view reference">${w}</span>`};const h=n.use.bind(n);return n.use=((...m)=>(o.__markstreamHasCustomParserExtensions=!0,h(...m))),n}function Sce({nextContent:e,previousContent:t,typewriterEnabled:n}){return n?e===t?{settledContent:e,streamedDelta:"",appended:!1}:t&&e.startsWith(t)&&e.length>t.length?{settledContent:t,streamedDelta:e.slice(t.length),appended:!0}:{settledContent:e,streamedDelta:"",appended:!1}:{settledContent:e,streamedDelta:"",appended:!1}}function t$({nextContent:e,persistedContent:t,currentState:n,typewriterEnabled:o,streamRenderVersionChanged:s=!1}){const i=`${n.settledContent}${n.streamedDelta}`;return o?n.streamedDelta&&i===e?s?{settledContent:i,streamedDelta:"",appended:!1}:{settledContent:n.settledContent,streamedDelta:n.streamedDelta,appended:!1}:Sce({nextContent:e,previousContent:t??i,typewriterEnabled:o}):{settledContent:e,streamedDelta:"",appended:!1}}const Ace={plain:"plaintext",text:"plaintext",txt:"plaintext",js:"javascript",mjs:"javascript",cjs:"javascript",ts:"typescript",mts:"typescript",cts:"typescript",golang:"go",py:"python",rb:"ruby",rs:"rust",kt:"kotlin",kts:"kotlin",md:"markdown",yml:"yaml",sh:"shellscript",bash:"shellscript",zsh:"shellscript",shell:"shellscript",shellscript:"shellscript",ps:"powershell",ps1:"powershell",pwsh:"powershell","c++":"cpp","c#":"csharp",cs:"csharp",objc:"objective-c",objectivec:"objective-c","objective-c":"objective-c",objectivecpp:"objective-cpp","objective-c++":"objective-cpp","objective-cpp":"objective-cpp"};function Mce(e){const t=String(e??"").trim();if(!t)return"";const[n=""]=t.split(/\s+/);return n.split(":")[0]?.trim().toLowerCase()??""}function n$(e){const t=Mce(e);return Ace[t]??t}function Tce(e){if(!Array.isArray(e))return;const t=e.filter(o=>typeof o=="string").map(o=>n$(o)).filter(Boolean),n=Array.from(new Set(t)).sort();return n.length>0?n:void 0}function Ece(e){if(!Array.isArray(e))return;const t=[],n=new Set;for(const o of e){if(typeof o!="string")continue;const s=o.trim();!s||n.has(s)||(n.add(s),t.push(s))}return t.length>0?t:void 0}function Ice(e){return Ece(e)?.join("\0")??""}function Lce(e,t){return`${Ice(e)}\0\0${Tce(t)?.join("\0")??""}`}function rd(e,t,n=1){const o=Number(e);return Number.isFinite(o)?Math.max(n,o):t}function a_(e,t){const n=Number(e);return Number.isFinite(n)?Math.max(0,n):t}var $ce=class{constructor(e={},t){this.source="",this.visible="",this.done=!1,this.paused=!1,this.listeners=new Set,this.rafId=0,this.startedAt=0,this.lastTick=0,this.charBudget=0,this.hasStarted=!1,this.destroyed=!1,this.getSnapshot=()=>({source:this.source,visible:this.visible,done:this.done,paused:this.paused,pendingChars:this.pendingChars,caughtUp:this.caughtUp,final:this.final}),this.subscribe=d=>this.destroyed?()=>{}:(this.listeners.add(d),()=>{this.listeners.delete(d)}),this.enqueue=d=>{if(this.destroyed||!d)return;this.done&&(this.done=!1);const f=this.source.length>0,h=this.pendingChars<=0;if(this.source+=d,h){const m=u_();this.startedAt=f&&this.hasStarted?m-this.normalizedStartDelayMs:m,this.lastTick=m,this.charBudget=0}this.hasStarted=!0,this.emit(),this.ensureLoop()},this.finish=(d={})=>{if(!this.destroyed){if(this.done=!0,d.flush??this.flushOnFinish){this.visible=this.source,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.cancelLoop(),this.emit();return}this.emit(),this.ensureLoop()}},this.flush=()=>{this.destroyed||(this.visible=this.source,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.cancelLoop(),this.emit())},this.reset=(d="")=>{this.destroyed||(this.cancelLoop(),this.source=d,this.visible=d,this.done=!1,this.paused=!1,this.hasStarted=!1,this.startedAt=0,this.lastTick=0,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.emit())},this.pause=()=>{this.destroyed||this.paused||(this.paused=!0,this.cancelLoop(),this.emit())},this.resume=()=>{if(this.destroyed||!this.paused)return;this.paused=!1;const d=u_();this.lastTick=d,this.startedAt||=d,this.emit(),this.ensureLoop()},this.destroy=()=>{this.destroyed||(this.destroyed=!0,this.cancelLoop(),this.listeners.clear())},this.dispose=()=>{this.destroy()},this.tick=d=>{if(this.rafId=0,this.destroyed||this.paused)return;if(this.pendingChars<=0){this.startedAt=0,this.lastTick=0,this.charBudget=0,this.currentCps=this.minCharsPerSecond;return}if(d-this.startedAt<this.normalizedStartDelayMs){this.rafId=requestAnimationFrame(this.tick);return}const f=1e3/Math.max(1,this.maxCommitFps),h=Math.min(100,Math.max(0,d-this.lastTick));if(h<f){this.rafId=requestAnimationFrame(this.tick);return}this.lastTick=d;const m=this.pendingChars,v=m>this.normalizedCatchUpThreshold?this.normalizedCatchUpLatencyMs:this.normalizedTargetLatencyMs,k=Oce(m/Math.max(.001,v/1e3),this.minCharsPerSecond,this.maxCharsPerSecond);if(this.currentCps+=(k-this.currentCps)*.2,this.charBudget+=this.currentCps*(h/1e3),this.charBudget<1){this.ensureLoop();return}const w=Math.min(Math.floor(this.charBudget),this.maxCharsPerCommit),b=Rce(this.source.slice(this.visible.length),w,this.segmenter);b.text&&(this.visible+=b.text,this.charBudget=Math.max(0,this.charBudget-b.graphemeCount),this.emit()),this.ensureLoop()};const{minCharsPerSecond:n=40,maxCharsPerSecond:o=1e3,targetLatencyMs:s=900,catchUpLatencyMs:i=350,catchUpThreshold:r=600,maxCommitFps:l=30,startDelayMs:a=80,maxCharsPerCommit:u=80,flushOnFinish:c=!1}=e;this.minCharsPerSecond=rd(n,40,1),this.maxCharsPerSecond=Math.max(this.minCharsPerSecond,rd(o,1e3,1)),this.normalizedTargetLatencyMs=rd(s,900,1),this.normalizedCatchUpLatencyMs=rd(i,350,1),this.normalizedCatchUpThreshold=a_(r,600),this.normalizedStartDelayMs=a_(a,80),this.maxCommitFps=Math.trunc(rd(l,30,1)),this.maxCharsPerCommit=Math.trunc(rd(u,80,1)),this.flushOnFinish=c,this.segmenter=Fce(),t&&this.listeners.add(t),this.currentCps=this.minCharsPerSecond}get pendingChars(){return Math.max(0,this.source.length-this.visible.length)}get caughtUp(){return this.pendingChars===0}get final(){return this.done&&this.caughtUp}ensureLoop(){if(!(this.destroyed||this.rafId||this.paused||this.pendingChars<=0)){if(typeof requestAnimationFrame!="function"){this.flush();return}this.rafId=requestAnimationFrame(this.tick)}}cancelLoop(){this.rafId&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.rafId),this.rafId=0)}emit(){if(!this.destroyed)for(const e of this.listeners)e()}};function Nce(e={},t){const n=new $ce(e,t);return{getSnapshot:n.getSnapshot,subscribe:n.subscribe,enqueue:n.enqueue,finish:n.finish,flush:n.flush,reset:n.reset,pause:n.pause,resume:n.resume,destroy:n.destroy,dispose:n.dispose}}function Fce(){if(typeof Intl>"u")return null;const e=Intl.Segmenter;return e?new e(void 0,{granularity:"grapheme"}):null}function Rce(e,t,n){if(!e||t<=0)return{text:"",graphemeCount:0};if(!n){const i=Array.from(e).slice(0,t);return{text:i.join(""),graphemeCount:i.length}}let o="",s=0;for(const i of n.segment(e)){if(s>=t)break;o+=i.segment,s++}return{text:o,graphemeCount:s}}function u_(){return typeof performance<"u"?performance.now():Date.now()}function Oce(e,t,n){return Math.min(n,Math.max(t,e))}var Pce=(e,t,n)=>new Promise((o,s)=>{var i=a=>{try{l(n.next(a))}catch(u){s(u)}},r=a=>{try{l(n.throw(a))}catch(u){s(u)}},l=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,r);l((n=n.apply(e,t)).next())});const G3=Symbol.for("markstream-vue:node-lifecycle");function wVe(){}const c5=new Map;let o$="material";const Ad=new Map,c_=new Map;let Y3=null;function Dce(e){c5.set(e.id,e)}function Bce(e){const t=c5.get(o$);if(!t)return;const n=t.core[e];if(n)return n;const o=Ad.get(t.id);if(o){const s=o[e];if(s)return s}t.loadExtended&&!Ad.has(t.id)&&zce(t)}function Hce(){var e,t;return(t=(e=c5.get(o$))==null?void 0:e.fallback)!=null?t:""}function zce(e){return Pce(this,null,function*(){var t,n,o;if(Ad.has(e.id))return(t=Ad.get(e.id))!=null?t:null;let s=c_.get(e.id);return s||(s=((o=(n=e.loadExtended)==null?void 0:n.call(e))!=null?o:Promise.resolve(null)).then(i=>(Ad.set(e.id,i),Y3?.(),i)).catch(()=>(Ad.set(e.id,null),null)),c_.set(e.id,s)),s})}const d_='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M30 14v-2h-2V8h-2v4h-2V8h-2v4h-2v2h2v2h-2v2h2v4h2v-4h2v4h2v-4h2v-2h-2v-2Zm-4 2h-2v-2h2Zm-12.437 6A5.57 5.57 0 0 1 8 16.437v-2.873A5.57 5.57 0 0 1 13.563 8H18V2h-4.437A11.563 11.563 0 0 0 2 13.563v2.873A11.564 11.564 0 0 0 13.563 28H18v-6Z"/></svg>',f_='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/><path fill="#42a5f5" d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"/></svg>',Wce={id:"material",core:{"":f_,plain:'<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/><path fill="#42a5f5" d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"/></svg>',text:f_,javascript:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ffca28" d="M2 2v12h12V2zm6 6h1v4a1.003 1.003 0 0 1-1 1H7a1.003 1.003 0 0 1-1-1v-1h1v1h1zm3 0h2v1h-2v1h1a1.003 1.003 0 0 1 1 1v1a1.003 1.003 0 0 1-1 1h-2v-1h2v-1h-1a1.003 1.003 0 0 1-1-1V9a1.003 1.003 0 0 1 1-1"/></svg>',typescript:'<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 16 16"><path fill="#0288d1" d="M2 2v12h12V2zm4 6h3v1H8v4H7V9H6zm5 0h2v1h-2v1h1a1.003 1.003 0 0 1 1 1v1a1.003 1.003 0 0 1-1 1h-2v-1h2v-1h-1a1.003 1.003 0 0 1-1-1V9a1.003 1.003 0 0 1 1-1"/></svg>',jsx:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#00bcd4" d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4-12-2.59-12-4 4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6 14-2.686 14-6-6.268-6-14-6"/><path fill="#00bcd4" d="M16 14a2 2 0 1 0 2 2 2 2 0 0 0-2-2"/><path fill="#00bcd4" d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493 3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124-3.284-5.69-7.72-9.493-10.74-9.493Z"/><path fill="#00bcd4" d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"/></svg>',tsx:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4-12-2.59-12-4 4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6 14-2.686 14-6-6.268-6-14-6"/><path fill="#0288d1" d="M16 14a2 2 0 1 0 2 2 2 2 0 0 0-2-2"/><path fill="#0288d1" d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493 3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124-3.284-5.69-7.72-9.493-10.74-9.493Z"/><path fill="#0288d1" d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"/></svg>',html:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#e65100" d="m4 4 2 22 10 2 10-2 2-22Zm19.72 7H11.28l.29 3h11.86l-.802 9.335L15.99 25l-6.635-1.646L8.93 19h3.02l.19 2 3.86.77 3.84-.77.29-4H8.84L8 8h16Z"/></svg>',css:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#7e57c2" d="M20 18h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 20 22h2v2h2v-2c0-.388-.562-.851-1.254-1.034C20.356 20.34 20 18.84 20 18m-3.254 2.966C14.356 20.34 14 18.84 14 18h-2v-2h-2v8h2v-2h4v2h2v-2c0-.388-.562-.851-1.254-1.034"/><path fill="#7e57c2" d="M24 4H4v20a4 4 0 0 0 4 4h16.16A3.84 3.84 0 0 0 28 24.16V8a4 4 0 0 0-4-4m2 14h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 26 22v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2 2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2 2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2 2 2 0 0 1 2-2h2a2 2 0 0 1 2 2 2 2 0 0 1 2-2h2a2 2 0 0 1 2 2Z"/></svg>',scss:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ec407a" d="M27.837 5.673a4.33 4.33 0 0 0-2.293-2.701c-2.362-1.261-6.11-1.298-9.548-.092a26.3 26.3 0 0 0-8.76 4.966c-2.752 2.542-3.438 4.925-3.189 6.194.523 2.668 3.274 4.539 5.485 6.042.418.284.822.559 1.175.816-1.429.76-4.261 2.444-5.088 4.248a3.88 3.88 0 0 0-.118 3.332A2.37 2.37 0 0 0 6.869 29.8a5.6 5.6 0 0 0 1.49.2 6.35 6.35 0 0 0 5.19-2.856 6.74 6.74 0 0 0 .864-5.382 7.3 7.3 0 0 1 2.044-.03 3.92 3.92 0 0 1 2.816 1.311 1.82 1.82 0 0 1 .423 1.262 1.55 1.55 0 0 1-.772 1.05c-.234.14-.586.355-.504.803.036.194.198.633.894.512a2.93 2.93 0 0 0 2.145-2.651 4 4 0 0 0-1.197-2.904 5.94 5.94 0 0 0-4.396-1.626 10.6 10.6 0 0 0-2.672.304 20 20 0 0 0-2.203-1.846c-1.712-1.3-3.33-2.529-3.235-4.26.125-2.263 2.468-4.532 6.964-6.744 4.016-1.976 7.254-2.037 8.944-1.438a2 2 0 0 1 1.204.883 2.77 2.77 0 0 1-.36 2.47 9.71 9.71 0 0 1-7.425 4.304 3.86 3.86 0 0 1-3.238-.757c-.278-.302-.593-.645-1.074-.383q-.565.31-.225 1.189a3.9 3.9 0 0 0 2.407 1.92 11.7 11.7 0 0 0 7.128-.671c3.527-1.35 6.681-5.202 5.756-8.787M11.895 24.475a4 4 0 0 1-.192.468 4.5 4.5 0 0 1-.753 1.081 2.83 2.83 0 0 1-2.533 1.107c-.056-.032-.078-.146-.085-.193a3.28 3.28 0 0 1 1.076-2.284 11.3 11.3 0 0 1 2.644-1.933 3.85 3.85 0 0 1-.157 1.754"/></svg>',json:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="#f9a825" d="M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z"/></svg>',python:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#0288d1" d="M9.86 2A2.86 2.86 0 0 0 7 4.86v1.68h4.29c.39 0 .71.57.71.96H4.86A2.86 2.86 0 0 0 2 10.36v3.781a2.86 2.86 0 0 0 2.86 2.86h1.18v-2.68a2.85 2.85 0 0 1 2.85-2.86h5.25c1.58 0 2.86-1.271 2.86-2.851V4.86A2.86 2.86 0 0 0 14.14 2zm-.72 1.61c.4 0 .72.12.72.71s-.32.891-.72.891c-.39 0-.71-.3-.71-.89s.32-.711.71-.711"/><path fill="#fdd835" d="M17.959 7v2.68a2.85 2.85 0 0 1-2.85 2.859H9.86A2.85 2.85 0 0 0 7 15.389v3.75a2.86 2.86 0 0 0 2.86 2.86h4.28A2.86 2.86 0 0 0 17 19.14v-1.68h-4.291c-.39 0-.709-.57-.709-.96h7.14A2.86 2.86 0 0 0 22 13.64V9.86A2.86 2.86 0 0 0 19.14 7zM8.32 11.513l-.004.004.038-.004zm6.54 7.276c.39 0 .71.3.71.89a.71.71 0 0 1-.71.71c-.4 0-.72-.12-.72-.71s.32-.89.72-.89"/></svg>',ruby:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#f44336" d="M18.041 3.177c2.24.382 2.879 1.919 2.843 3.527V6.67l-1.013 13.266-13.132.897h.008c-1.093-.044-3.518-.151-3.634-3.545l1.217-2.222 2.462 5.74 2.097-6.77-.045.009.018-.018 6.85 2.186L13.945 9.3l6.53-.409-5.144-4.212 2.71-1.51v.009M3.113 17.252v.017zM6.916 6.874c2.63-2.622 6.033-4.168 7.34-2.844 1.297 1.306-.072 4.523-2.702 7.135-2.666 2.613-6.015 4.248-7.322 2.933-1.306-1.324.036-4.612 2.675-7.224z"/></svg>',go:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#00acc1" d="M2 12h4v2H2zm-2 4h6v2H0zm4 4h2v2H4zm16.954-5H14v3h3.239a4.42 4.42 0 0 1-3.531 2 2.65 2.65 0 0 1-2.053-.858 2.86 2.86 0 0 1-.628-2.28A4.515 4.515 0 0 1 15.292 13a2.73 2.73 0 0 1 1.749.584l2.962-1.185A5.6 5.6 0 0 0 15.292 10a7.526 7.526 0 0 0-7.243 6.5 5.614 5.614 0 0 0 5.659 6.5 7.526 7.526 0 0 0 7.243-6.5 6.4 6.4 0 0 0 .003-1.5"/><path fill="#00acc1" d="M26.292 10a7.526 7.526 0 0 0-7.243 6.5 5.614 5.614 0 0 0 5.659 6.5 7.526 7.526 0 0 0 7.243-6.5 5.614 5.614 0 0 0-5.659-6.5m2.681 6.137A4.515 4.515 0 0 1 24.708 20a2.65 2.65 0 0 1-2.053-.858 2.86 2.86 0 0 1-.628-2.28A4.515 4.515 0 0 1 26.292 13a2.65 2.65 0 0 1 2.053.858 2.86 2.86 0 0 1 .628 2.28Z"/></svg>',java:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#f44336" d="M4 26h24v2H4zM28 4H7a1 1 0 0 0-1 1v13a4 4 0 0 0 4 4h10a4 4 0 0 0 4-4v-4h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2m0 8h-4V6h4Z"/></svg>',kotlin:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><defs><linearGradient id="a" x1="1.725" x2="22.185" y1="22.67" y2="1.982" gradientTransform="translate(1.306 1.129)scale(.89324)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#7c4dff"/><stop offset=".5" stop-color="#d500f9"/><stop offset="1" stop-color="#ef5350"/></linearGradient></defs><path fill="url(#a)" d="M2.975 2.976v18.048h18.05v-.03l-4.478-4.511-4.48-4.515 4.48-4.515 4.443-4.477z"/></svg>',c:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M19.563 22A5.57 5.57 0 0 1 14 16.437v-2.873A5.57 5.57 0 0 1 19.563 8H24V2h-4.437A11.563 11.563 0 0 0 8 13.563v2.873A11.564 11.564 0 0 0 19.563 28H24v-6Z"/></svg>',cpp:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M28 14v-4h-2v4h-6v-4h-2v4h-4v2h4v4h2v-4h6v4h2v-4h4v-2z"/><path fill="#0288d1" d="M13.563 22A5.57 5.57 0 0 1 8 16.437v-2.873A5.57 5.57 0 0 1 13.563 8H18V2h-4.437A11.563 11.563 0 0 0 2 13.563v2.873A11.564 11.564 0 0 0 13.563 28H18v-6Z"/></svg>',cs:d_,csharp:d_,php:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#1e88e5" d="M12 18.08c-6.63 0-12-2.72-12-6.08s5.37-6.08 12-6.08S24 8.64 24 12s-5.37 6.08-12 6.08m-5.19-7.95c.54 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.58 1.09q-.42.33-1.29.33h-.87l.53-2.76zm-3.5 5.55h1.44l.34-1.75h1.23c.54 0 .98-.06 1.33-.17.35-.12.67-.31.96-.58.24-.22.43-.46.58-.73.15-.26.26-.56.31-.88.16-.78.05-1.39-.33-1.82-.39-.44-.99-.65-1.82-.65H4.59zm7.25-8.33-1.28 6.58h1.42l.74-3.77h1.14c.36 0 .6.06.71.18s.13.34.07.66l-.57 2.93h1.45l.59-3.07c.13-.62.03-1.07-.27-1.36-.3-.27-.85-.4-1.65-.4h-1.27L12 7.35zM18 10.13c.55 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.57 1.09-.29.22-.72.33-1.3.33h-.85l.5-2.76zm-3.5 5.55h1.44l.34-1.75h1.22c.55 0 1-.06 1.35-.17.35-.12.65-.31.95-.58.24-.22.44-.46.58-.73.15-.26.26-.56.32-.88.15-.78.04-1.39-.34-1.82-.36-.44-.99-.65-1.82-.65h-2.75z"/></svg>',shell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ff7043" d="M2 2a1 1 0 0 0-1 1v10c0 .554.446 1 1 1h12c.554 0 1-.446 1-1V3a1 1 0 0 0-1-1zm0 3h12v8H2zm1 2 2 2-2 2 1 1 3-3-3-3zm5 3.5V12h5v-1.5z"/></svg>',powershell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#03a9f4" d="M29.07 6H7.677A1.535 1.535 0 0 0 6.24 7.113l-4.2 17.774A.852.852 0 0 0 2.93 26h21.393a1.535 1.535 0 0 0 1.436-1.113L29.96 7.112A.852.852 0 0 0 29.07 6M8.626 23.797a1.4 1.4 0 0 1-1.814-.31l-.007-.009a1.075 1.075 0 0 1 .315-1.599l9.6-6.061-6.102-5.852-.01-.01a1.068 1.068 0 0 1 .084-1.625l.037-.03a1.38 1.38 0 0 1 1.8.07l7.233 6.957a1.1 1.1 0 0 1 .236.739 1.08 1.08 0 0 1-.412.79c-.074.04-.146.119-10.951 6.935ZM24 22.94A1.135 1.135 0 0 1 22.803 24h-5.634a1.061 1.061 0 1 1 .001-2.112h5.633A1.134 1.134 0 0 1 24 22.938Z"/></svg>',sql:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ffca28" d="M16 24c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-8c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-12C10.477 4 6 4.895 6 6v4c0 1.1 4.475 2 10 2s10-.9 10-2V6c0-1.105-4.477-2-10-2"/></svg>',yaml:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#ff5252" d="M13 9h5.5L13 3.5zM6 2h8l6 6v12c0 1.1-.9 2-2 2H6c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2m12 16v-2H9v2zm-4-4v-2H6v2z"/></svg>',markdown:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#42a5f5" d="m14 10-4 3.5L6 10H4v12h4v-6l2 2 2-2v6h4V10zm12 6v-6h-4v6h-4l6 8 6-8z"/></svg>',xml:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#8bc34a" d="M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5 3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41zm11.16 0-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41z"/></svg>',rust:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ff7043" d="m30 12-4-2V6h-4l-2-4-4 2-4-2-2 4H6v4l-4 2 2 4-2 4 4 2v4h4l2 4 4-2 4 2 2-4h4v-4l4-2-2-4ZM6 16a9.9 9.9 0 0 1 .842-4H10v8H6.842A9.9 9.9 0 0 1 6 16m10 10a9.98 9.98 0 0 1-7.978-4H16v-2h-2v-2h4c.819.819.297 2.308 1.179 3.37a1.89 1.89 0 0 0 1.46.63h3.34A9.98 9.98 0 0 1 16 26m-2-12v-2h4a1 1 0 0 1 0 2Zm11.158 6H24a2.006 2.006 0 0 1-2-2 2 2 0 0 0-2-2 3 3 0 0 0 3-3q0-.08-.004-.161A3.115 3.115 0 0 0 19.83 10H8.022a9.986 9.986 0 0 1 17.136 10"/></svg>',vue:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#41b883" d="M1.791 3.851 12 21.471 22.209 3.936V3.85H18.24l-6.18 10.616L5.906 3.851z"/><path fill="#35495e" d="m5.907 3.851 6.152 10.617L18.24 3.851h-3.723L12.084 8.03 9.66 3.85z"/></svg>',mermaid:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#42a5f5" d="m14 10-4 3.5L6 10H4v12h4v-6l2 2 2-2v6h4V10zm12 6v-6h-4v6h-4l6 8 6-8z"/></svg>'},fallback:'<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ff7043" d="M2 2a1 1 0 0 0-1 1v10c0 .554.446 1 1 1h12c.554 0 1-.446 1-1V3a1 1 0 0 0-1-1zm0 3h12v8H2zm1 2 2 2-2 2 1 1 3-3-3-3zm5 3.5V12h5v-1.5z"/></svg>',loadExtended:()=>jo(()=>import("./extended-p72mFE2C.js"),[]).then(e=>e.materialExtendedMap)},Uce=Xr(0);Y3=()=>{Uce.value++},Dce(Wce);const jce={"":"",javascript:"javascript",js:"javascript",mjs:"javascript",cjs:"javascript",typescript:"typescript",ts:"typescript",jsx:"jsx",tsx:"tsx",golang:"go",py:"python",rb:"ruby",sh:"shell",bash:"shell",zsh:"shell",shellscript:"shell",bat:"shell",batch:"shell",ps1:"powershell",plaintext:"plain",text:"plain",txt:"plain","c++":"cpp","c#":"csharp",cs:"csharp","objective-c":"objectivec","objective-c++":"objectivecpp",yml:"yaml",md:"markdown",rs:"rust",kt:"kotlin"};function T2(e){var t;const n=(function(o){if(!o)return"";const s=o.trim();if(!s)return"";const[i]=s.split(/\s+/),[r]=i.split(":");return r.toLowerCase()})(e);return(t=jce[n])!=null?t:n}function _Ve(e){const t=T2(e);if(!t)return"plaintext";switch(t){case"plain":return"plaintext";case"jsx":return"javascript";case"tsx":return"typescript";case"objectivec":return"objective-c";case"objectivecpp":return"objective-cpp";default:return t}}function xVe(e){return Bce(T2(e))||Hce()}const p_={js:"JavaScript",javascript:"JavaScript",ts:"TypeScript",jsx:"JSX",tsx:"TSX",html:"HTML",css:"CSS",scss:"SCSS",json:"JSON",py:"Python",python:"Python",rb:"Ruby",go:"Go",java:"Java",c:"C",cpp:"C++",cs:"C#",csharp:"C#",php:"PHP",sh:"Shell",bash:"Bash",sql:"SQL",yaml:"YAML",md:"Markdown",d2:"D2",d2lang:"D2","":"Plain Text",plain:"Plain Text"};var E2=(e,t,n)=>new Promise((o,s)=>{var i=a=>{try{l(n.next(a))}catch(u){s(u)}},r=a=>{try{l(n.throw(a))}catch(u){s(u)}},l=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,r);l((n=n.apply(e,t)).next())});let ki=null,Qu=!1,ec=null,I2=f5;function Jp(e){var t;const n=(t=e?.default)!=null?t:e;return n&&typeof n.renderToString=="function"?n:null}function d5(){try{const e=globalThis;return Jp(e?.katex)}catch{return null}}function f5(){return E2(null,null,function*(){const e=d5();if(e)return e;const t=yield jo(()=>import("./katex-DnlPpQZa.js"),[]);try{yield jo(()=>import("./mhchem-DtR62fUK.js"),__vite__mapDeps([0,1]))}catch{}return Jp(t)})}function s$(e){const t=Promise.resolve(e).then(n=>{var o;return ec===t&&n?(ki=(o=Jp(n))!=null?o:n,ki):null}).catch(()=>null).finally(()=>{ec===t&&(ec=null)});return ec=t,Qu=!0,t}function Vce(e){I2=e,ki=null,Qu=!1,ec=null}function qce(e){Vce(f5)}function i$(){return typeof I2=="function"}function SVe(){var e;const t=I2;if(!t||t===f5)return null;if(ki)return ki;const n=d5();if(n)return ki=n,ki;if(Qu)return null;try{const o=t();return o?typeof o?.then=="function"?(s$(o),null):(ki=(e=Jp(o))!=null?e:o,ki):null}catch{return null}}function r$(){return E2(this,null,function*(){var e;const t=d5();if(t)return ki=t,ki;if(ki)return ki;if(ec)return ec;if(Qu)return null;const n=I2;if(!n)return Qu=!0,null;try{const o=n();if(typeof o?.then=="function")return s$(o);if(o)return ki=(e=Jp(o))!=null?e:o,Qu=!0,ki}catch{}return Qu=!0,null})}function l$(e){return e?e.replace(/·/g,"⋅").replace(/℃/g,"°C"):""}let Ha=null,Na=null;const Ws=new Map,ea=new Map;let Lp=5;const uc=new Set;function Gf(){if(Ws.size<Lp&&uc.size){let e=Lp-Ws.size;for(const t of Array.from(uc)){if(e<=0)break;uc.delete(t),e--;try{t()}catch{}}}}function a$(){for(const e of Array.from(uc)){uc.delete(e);try{e()}catch{}}}function Kce(e){Ha=e,Na=null,Ha.onmessage=t=>{const{id:n,html:o,error:s}=t.data,i=Ws.get(n);if(i)if(Ws.delete(n),clearTimeout(i.timeoutId),i.cleanup(),Gf(),s)i.aborted||i.reject(new Error(s));else{const{content:r,displayMode:l}=t.data;if(r){const a=`${l?"d":"i"}:${r}`;if(ea.set(a,o),ea.size>200){const u=ea.keys().next().value;ea.delete(u)}}i.aborted||i.resolve(o)}},Ha.onerror=t=>{console.error("[katexWorkerClient] Worker error:",t);for(const[n,o]of Ws.entries())clearTimeout(o.timeoutId),o.cleanup(),o.aborted||o.reject(new Error(`Worker error: ${t.message}`));Ws.clear(),a$()}}function Zce(){var e;for(const t of Ws.values())clearTimeout(t.timeoutId),t.cleanup(),t.aborted||t.reject(new Error("Worker cleared"));Ws.clear(),a$(),Ha&&((e=Ha.terminate)==null||e.call(Ha)),Ha=null,Na=null}function Gce(e,t=!0,n=2e3,o){return E2(this,null,function*(){performance.now();const s=l$(e);if(!i$()){const a=new Error("KaTeX rendering disabled");return a.name="KaTeXDisabled",a.code="KATEX_DISABLED",Promise.reject(a)}if(Na)return Promise.reject(Na);const i=`${t?"d":"i"}:${s}`,r=ea.get(i);if(r)return Gf(),Promise.resolve(r);const l=Ha||(Na=new Error("[katexWorkerClient] No worker instance set. Please inject a Worker via setKaTeXWorker()."),Na.name="WorkerInitError",Na.code="WORKER_INIT_ERROR",null);if(!l)return Promise.reject(Na);if(Ws.size>=Lp){const a=new Error("Worker busy");return a.name="WorkerBusy",a.code="WORKER_BUSY",a.busy=!0,a.inFlight=Ws.size,a.max=Lp,Promise.reject(a)}return new Promise((a,u)=>{if(o?.aborted){const v=new Error("Aborted");return v.name="AbortError",void u(v)}const c=Math.random().toString(36).slice(2);let d=null;const f=globalThis.setTimeout(()=>{const v=Ws.get(c);if(!v)return;Ws.delete(c),v.cleanup();const k=new Error("Worker render timed out");k.name="WorkerTimeout",k.code="WORKER_TIMEOUT",v.aborted||v.reject(k),Gf()},n);d=()=>{const v=Ws.get(c);if(!v||v.aborted)return;v.aborted=!0,v.cleanup();const k=new Error("Aborted");k.name="AbortError",u(k)},o&&o.addEventListener("abort",d,{once:!0});const h=a,m=u;Ws.set(c,{resolve:v=>{h(v)},reject:v=>{m(v)},timeoutId:f,aborted:!1,cleanup:()=>{o&&d&&o.removeEventListener("abort",d),d=null}});try{l.postMessage({id:c,content:s,displayMode:t})}catch(v){const k=Ws.get(c);Ws.delete(c),clearTimeout(f),k?.cleanup(),k?.reject(v),Gf()}})})}function AVe(e,t=!0,n){const o=`${t?"d":"i"}:${l$(e)}`;if(ea.set(o,n),ea.size>200){const s=ea.keys().next().value;ea.delete(s)}}const Yce="WORKER_BUSY";function Xce(e=2e3,t){return Ws.size<Lp?Promise.resolve():new Promise((n,o)=>{let s,i=!1,r=null,l=()=>{};const a=()=>{s&&globalThis.clearTimeout(s),uc.delete(l),t&&r&&t.removeEventListener("abort",r),r=null};l=()=>{i||(i=!0,a(),n())},uc.add(l),s=globalThis.setTimeout(()=>{if(i)return;i=!0,a();const u=new Error("Wait for worker slot timed out");u.name="WorkerBusyTimeout",u.code="WORKER_BUSY_TIMEOUT",o(u)},e),queueMicrotask(()=>Gf()),t&&(r=()=>{if(i)return;i=!0,a();const u=new Error("Aborted");u.name="AbortError",o(u)},t.aborted?r():t.addEventListener("abort",r,{once:!0}))})}const sf={timeout:2e3,waitTimeout:1500,backoffMs:30,maxRetries:1};function MVe(e){return E2(this,arguments,function*(t,n=!0,o={}){var s,i,r,l;if(!i$()){const v=new Error("KaTeX rendering disabled");throw v.name="KaTeXDisabled",v.code="KATEX_DISABLED",v}const a=(s=o.timeout)!=null?s:sf.timeout,u=(i=o.waitTimeout)!=null?i:sf.waitTimeout,c=(r=o.backoffMs)!=null?r:sf.backoffMs,d=(l=o.maxRetries)!=null?l:sf.maxRetries,f=Number.isFinite(d)?Math.max(0,Math.min(Math.floor(d),8)):sf.maxRetries,h=o.signal;let m=0;for(;;){if(h?.aborted){const v=new Error("Aborted");throw v.name="AbortError",v}try{return yield Gce(t,n,a,h)}catch(v){if(v?.code!==Yce||m>=f)throw v;if(m++,yield Xce(u,h).catch(()=>{}),h?.aborted){const k=new Error("Aborted");throw k.name="AbortError",k}c>0&&(yield new Promise(k=>globalThis.setTimeout(k,c*m)))}}})}function Md(e){const t=typeof e=="number"?e:Number.parseFloat(String(e??""));return Number.isFinite(t)&&t>0?t:null}function Jce(e){var t;for(const n of e.split(/\r?\n/)){const o=n.trim();if(!o||o.startsWith("%%"))continue;const s=o.match(/^([A-Z][\w-]*)\b/i);return((t=s?.[1])==null?void 0:t.toLowerCase())||""}return""}function ig(e){const t=e.split(/\r?\n/).map(s=>s.trim()).filter(s=>s&&!s.startsWith("%%")),n=Math.max(1,t.length),o=Jce(e);return o==="gantt"?220+28*n:o==="sequencediagram"?180+26*n:o==="classdiagram"||o==="statediagram"||o==="erdiagram"?180+24*n:o==="flowchart"||o==="graph"?170+28*n:200+22*n}function rg(e){const t=e.split(/\r?\n/).filter(n=>/^\s*-\s+/.test(n)).length;return t>=3?500:t>0?280+60*t:360}function u$(e,t=360,n=500){return n==null?Math.max(t,e):Math.min(Math.max(t,e),n)}function lg(e,t=360,n=500){return u$(e,t,n)}function ag(e,t=360,n=500){return u$(e,t,n)}var Qce=Object.defineProperty,ede=Object.defineProperties,tde=Object.getOwnPropertyDescriptors,h_=Object.getOwnPropertySymbols,nde=Object.prototype.hasOwnProperty,ode=Object.prototype.propertyIsEnumerable,m_=(e,t,n)=>t in e?Qce(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,c$=(e,t)=>{for(var n in t||(t={}))nde.call(t,n)&&m_(e,n,t[n]);if(h_)for(var n of h_(t))ode.call(t,n)&&m_(e,n,t[n]);return e},g_=(e,t,n)=>new Promise((o,s)=>{var i=a=>{try{l(n.next(a))}catch(u){s(u)}},r=a=>{try{l(n.throw(a))}catch(u){s(u)}},l=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,r);l((n=n.apply(e,t)).next())});const ug=()=>jo(()=>import("./mermaid.core-CJB1tAev.js").then(e=>e.bp),__vite__mapDeps([2,3]));let Ul=null,Td=ug,xf=null,X3=!1,J3=!1,Sf=0;function sde(e){Td=e,Sf++,Ul=null,xf=null,X3=!1,J3=!1}function ide(e){sde(ug)}function v_(){return typeof Td=="function"}function y_(e){if(!e)return e;const t=e&&e.default?e.default:e;if(t&&(typeof t.render=="function"||typeof t.parse=="function"||typeof t.initialize=="function"))return t;if(t&&t.mermaidAPI&&(typeof t.mermaidAPI.render=="function"||typeof t.mermaidAPI.parse=="function")){const s=t.mermaidAPI;return n=c$({},t),o={render:s.render.bind(s),parse:s.parse?s.parse.bind(s):void 0,initialize:i=>typeof t.initialize=="function"?t.initialize(i):s.initialize?s.initialize(i):void 0},ede(n,tde(o))}var n,o;return e.mermaid&&typeof e.mermaid.render=="function"?e.mermaid:t}function k_(e){if(e)try{const t=e?.initialize;e.initialize=n=>{const o=c$({suppressErrorRendering:!0},n||{});return typeof t=="function"?t.call(e,o):e?.mermaidAPI&&typeof e.mermaidAPI.initialize=="function"?e.mermaidAPI.initialize(o):void 0}}catch{}}function TVe(){return g_(this,null,function*(){if(Ul)return Ul;const e=(function(){try{const o=globalThis;return y_(o?.mermaid)}catch{return null}})();if(e)return Ul=e,k_(Ul),Ul;const t=Td,n=Sf;return t?t===ug&&X3?null:xf||(xf=g_(null,null,function*(){let o;try{o=yield t()}catch(s){if(t===ug)return n===Sf&&t===Td&&(X3=!0,(function(i){J3||(J3=!0,console.warn('[markstream-vue] Optional dependency "mermaid" is not installed. Mermaid blocks will render as source.',i))})(s)),null;throw s}finally{n===Sf&&t===Td&&(xf=null)}return n!==Sf||t!==Td?null:o?(Ul=y_(o),k_(Ul),Ul):null}),xf):null})}let Oi=null,Fa=null;const Dr=new Map,Uu=new Map;function Jh(e){for(const t of Dr.values())t.reject(e);Dr.clear(),Uu.clear()}let b_=5,C_=!1;const rde="WORKER_BUSY",w_="MERMAID_DISABLED";function lde(e){if(Oi&&Oi!==e){const n=new Error("Worker replaced");n.code="WORKER_REPLACED",Jh(n)}Oi=e,Fa=null;const t=e;Oi.onmessage=n=>{if(Oi!==t)return;const{id:o,ok:s,result:i,error:r}=n.data,l=Dr.get(o);l&&(s===!1||r?l.reject(new Error(r||"Unknown error")):l.resolve(i))},Oi.onerror=n=>{var o,s;if(Oi===t)if(Dr.size!==0){try{C_?console.error("[mermaidWorkerClient] Worker error:",n?.message||n):(s=console.debug)==null||s.call(console,"[mermaidWorkerClient] Worker error:",n?.message||n)}catch{}Jh(new Error(`Worker error: ${n.message}`))}else(o=console.debug)==null||o.call(console,"[mermaidWorkerClient] Worker error (no pending):",n?.message||n)},Oi.onmessageerror=n=>{var o,s;if(Oi===t)if(Dr.size!==0){try{C_?console.error("[mermaidWorkerClient] Worker messageerror:",n):(s=console.debug)==null||s.call(console,"[mermaidWorkerClient] Worker messageerror:",n)}catch{}Jh(new Error("Worker messageerror"))}else(o=console.debug)==null||o.call(console,"[mermaidWorkerClient] Worker messageerror (no pending):",n)}}function ade(){var e;if(Oi)try{Jh(new Error("Worker cleared")),(e=Oi.terminate)==null||e.call(Oi)}catch{}Oi=null,Fa=null}function d$(e,t,n,o){if(!v_()){const r=new Error("Mermaid rendering disabled");return r.name="MermaidDisabled",r.code=w_,Promise.reject(r)}const s=`${e}\0${t.theme}\0${n}\0${t.code}`;let i=Uu.get(s);return i||(i=(function(r,l,a=1400){if(!v_()){const c=new Error("Mermaid rendering disabled");return c.name="MermaidDisabled",c.code=w_,Promise.reject(c)}if(Fa)return Promise.reject(Fa);const u=Oi||(Fa=new Error("[mermaidWorkerClient] No worker instance set. Please inject a Worker via setMermaidWorker()."),Fa.name="WorkerInitError",Fa.code="WORKER_INIT_ERROR",null);if(!u)return Promise.reject(Fa);if(Dr.size>=b_){const c=new Error("Worker busy");return c.name="WorkerBusy",c.code=rde,c.inFlight=Dr.size,c.max=b_,Promise.reject(c)}return new Promise((c,d)=>{const f=Math.random().toString(36).slice(2);let h,m=!1;const v=()=>{m||(m=!0,h!=null&&globalThis.clearTimeout(h),Dr.delete(f))},k={resolve:w=>{v(),c(w)},reject:w=>{v(),d(w)}};Dr.set(f,k);try{u.postMessage({id:f,action:r,payload:l})}catch(w){return Dr.delete(f),void d(w)}h=globalThis.setTimeout(()=>{const w=new Error("Worker call timed out");w.name="WorkerTimeout",w.code="WORKER_TIMEOUT";const b=Dr.get(f);b&&b.reject(w)},a)})})(e,t,n),Uu.set(s,i),i.then(()=>{Uu.get(s)===i&&Uu.delete(s)},()=>{Uu.get(s)===i&&Uu.delete(s)})),(function(r,l){if(!l)return r;if(l.aborted){const a=new Error("Aborted");return a.name="AbortError",Promise.reject(a)}return new Promise((a,u)=>{let c=()=>{};const d=()=>l.removeEventListener("abort",c);c=()=>{d();const f=new Error("Aborted");f.name="AbortError",u(f)},l.addEventListener("abort",c,{once:!0}),r.then(f=>{d(),a(f)},f=>{d(),u(f)})})})(i,o)}function EVe(e,t,n=1400,o){return d$("canParse",{code:e,theme:t},n,o)}function IVe(e,t,n=1400,o){return d$("findPrefix",{code:e,theme:t},n,o)}var ude=Object.defineProperty,cde=Object.defineProperties,dde=Object.getOwnPropertyDescriptors,__=Object.getOwnPropertySymbols,fde=Object.prototype.hasOwnProperty,pde=Object.prototype.propertyIsEnumerable,x_=(e,t,n)=>t in e?ude(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,mt=(e,t)=>{for(var n in t||(t={}))fde.call(t,n)&&x_(e,n,t[n]);if(__)for(var n of __(t))pde.call(t,n)&&x_(e,n,t[n]);return e},rn=(e,t)=>cde(e,dde(t)),mo=(e,t,n)=>new Promise((o,s)=>{var i=a=>{try{l(n.next(a))}catch(u){s(u)}},r=a=>{try{l(n.throw(a))}catch(u){s(u)}},l=a=>a.done?o(a.value):Promise.resolve(a.value).then(i,r);l((n=n.apply(e,t)).next())});const hde="__global__",q9="__MARKSTREAM_VUE_CUSTOM_COMPONENTS_STORE__",Q3=(()=>{const e=globalThis;if(e[q9])return e[q9];const t={scopedCustomComponents:{},revision:Xr(0)};return e[q9]=t,t})(),S_=Q3.revision,mde=Symbol("markstreamCustomComponents"),gde=new Set(["text","paragraph","heading","code_block","list","list_item","blockquote","table","table_row","table_cell","definition_list","definition_item","footnote","footnote_reference","footnote_anchor","admonition","hardbreak","link","image","thematic_break","math_inline","math_block","strong","emphasis","strikethrough","highlight","insert","subscript","superscript","emoji","checkbox","checkbox_input","inline_code","html_inline","html_block","reference","mermaid","infographic","d2","vmr_container"]);function Qp(e){return gde.has(String(e).trim().toLowerCase())}function vde(e){return e.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/[_\s]+/g,"-").toLowerCase()}function K9(e={}){const t={};for(const[n,o]of Object.entries(e))if(o!=null){t[n]=o;for(const s of new Set([Sr(n),Sr(vde(n))]))!s||Qp(s)||Object.prototype.hasOwnProperty.call(t,s)||(t[s]=o)}return t}function fs(e){const t=nn(mde,null);return R(()=>{var n;return S_.value,(function(o,s={}){return S_.value,mt(mt(mt({},K9(Q3.scopedCustomComponents[hde]||{})),K9(s)),K9((function(i){return i&&Q3.scopedCustomComponents[i]||{}})(o)))})(e?.(),(n=t?.value)!=null?n:{})})}const yde=["aria-label"],kde={key:0,xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",class:"checkbox-icon checkbox-unchecked"},bde={key:1,xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",class:"checkbox-icon checkbox-checked"},Gn=(e,t)=>{const n=e.__vccOpts||e;for(const[o,s]of t)n[o]=s;return n},nr=Gn(et({__name:"CheckboxNode",props:{node:{}},setup:e=>(t,n)=>(y(),M("span",{class:"checkbox-node",role:"img","aria-label":e.node.checked?"checked":"unchecked"},[e.node.checked?(y(),M("svg",bde,[...n[1]||(n[1]=[C("rect",{x:"3",y:"3",width:"18",height:"18",rx:"4",fill:"currentColor"},null,-1),C("path",{d:"M9 12l2 2 4-4",stroke:"hsl(var(--ms-background))","stroke-width":"2.5","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])):(y(),M("svg",kde,[...n[0]||(n[0]=[C("rect",{x:"3",y:"3",width:"18",height:"18",rx:"4",stroke:"currentColor","stroke-width":"2"},null,-1)])]))],8,yde))}),[["__scopeId","data-v-be21ab83"]]);nr.install=e=>{e.component(nr.__name,nr)};const Cde={class:"emoji-node"},zi=Gn(et({__name:"EmojiNode",props:{node:{}},setup:e=>(t,n)=>(y(),M("span",Cde,N(e.node.name),1))}),[["__scopeId","data-v-de55dc97"]]);zi.install=e=>{e.component(zi.__name,zi)};const wde=["id"],_de=["title"],or=Gn(et({__name:"FootnoteReferenceNode",props:{node:{}},setup(e){const t=`#fnref--${e.node.id}`;function n(){if(typeof document>"u")return;const o=document.querySelector(t);o?o.scrollIntoView({behavior:"smooth"}):console.warn(`Element with href: ${t} not found`)}return(o,s)=>(y(),M("sup",{id:`fnref-${e.node.id}`,class:"footnote-reference",onClick:n},[C("span",{href:t,title:`查看脚注 ${e.node.id}`,class:"footnote-link cursor-pointer"},"["+N(e.node.id)+"]",9,_de)],8,wde))}}),[["__scopeId","data-v-c1463a29"]]);or.install=e=>{e.component(or.__name,or)};const f$=(()=>{try{return!1}catch{}return!1})();function Z9(e){f$&&console.warn(e)}function A_(e,t="safe",n){return u5(e,t,n)}function p$(e){return oce(e)}function G9(e){return e===!0?"":e===!1?"false":e==null?null:String(e)}function p5(e,t="safe"){const n=String(e.tag||e.type||"").trim(),o=Xh((s=e.attrs)?Array.isArray(s)?s.every(Array.isArray)?s.map(([r,l])=>[String(r),G9(l)]):s.filter(r=>r&&typeof r=="object"&&!Array.isArray(r)&&"name"in r).map(r=>[String(r.name),G9(r.value)]):Object.entries(s).map(([r,l])=>[r,G9(l)]):null,t,n);var s;if(!o)return;const i=p$(Zf(o));return Object.keys(i).length>0?i:void 0}function M_(e,t,n=!1){const o=Object.entries(t??{}),s=o.length>0?o.map(([i,r])=>r===""?` ${i}`:` ${i}="${r}"`).join(""):"";return n?`<${e}${s} />`:`<${e}${s}>`}function rf(e,t){Array.isArray(t)?e.push(...t):t!=null&&e.push(t)}function Y9(e,t,n,o,s,i,r=!1){const l=(function(d,f){return YL(d,f)})(e,o);if(Zp.has(e.toLowerCase())||!l&&qL(e,i))return null;if(!l&&a5(e,i))return r?[M_(e,t,!0)]:[M_(e,t),...n,`</${e}>`];const a=u5(t,i,e),u=a.key,c=u!=null&&u!==""?u:s;if(l){const d=o[e]||o[e.toLowerCase()],f=p$(a);return tn(d,rn(mt({},f),{key:c}),n.length>0?n:void 0)}return tn(e,rn(mt({},a),{innerHTML:void 0,key:c}),n.length>0?n:void 0)}function h$(e,t){return rce(e,t)}function cg(e,t,n="safe"){if(!e)return[];try{return(function(i,r,l="safe"){let a=0;const u=[],c=[];for(const d of i)if(d.type==="text")(u.length>0?u[u.length-1].children:c).push(d.content);else if(d.type==="self_closing"){const f=Y9(d.tagName,d.attrs||{},[],r,"ms-html-"+a++,l,!0);rf(u.length>0?u[u.length-1].children:c,f)}else if(d.type==="tag_open")u.push({tagName:d.tagName,children:[],attrs:d.attrs,autoKey:"ms-html-"+a++});else if(d.type==="tag_close"){const f=d.tagName.toLowerCase();let h=-1;for(let m=u.length-1;m>=0;m--)if(u[m].tagName.toLowerCase()===f){h=m;break}if(h!==-1)for(;u.length>h;){const m=u.pop(),v=Y9(m.tagName,m.attrs||{},m.children,r,m.autoKey,l);u.length>0?rf(u[u.length-1].children,v):rf(c,v),m.tagName.toLowerCase()!==f&&u.length>h&&Z9(`Auto-closing unclosed tag: <${m.tagName}>`)}else Z9(`Ignoring closing tag with no matching opening tag: </${d.tagName}>`)}for(;u.length>0;){const d=u.pop(),f=Y9(d.tagName,d.attrs||{},d.children,r,d.autoKey,l);u.length>0?rf(u[u.length-1].children,f):rf(c,f),Z9(`Auto-closing unclosed tag: <${d.tagName}>`)}return c})(XL(e),t,n)}catch(s){return o=s,f$&&console.error("Failed to parse HTML to VNodes:",o),null}var o}const xde=["innerHTML"],sr=Gn(et({__name:"HtmlInlineNode",props:{node:{},customId:{},htmlPolicy:{}},setup(e){const t=e,n=nn("markstreamHtmlPolicy",void 0),o=R(()=>{var l,a;return(a=(l=t.htmlPolicy)!=null?l:n?.value)!=null?a:"safe"}),s=fs(()=>t.customId),i=et({name:"DynamicRenderer",props:{nodes:{type:Array,required:!0}},render(){return this.nodes}}),r=R(()=>{const l=t.node.content;if(!l)return{mode:"html",content:""};if(o.value==="escape")return{mode:"html",content:jd(l,o.value)};if(t.node.loading&&!t.node.autoClosed)return{mode:"text",content:l};if(t.node.loading&&t.node.autoClosed){const u=cg(l,s.value,o.value);if(u!==null)return{mode:"dynamic",nodes:u}}if(!h$(l,s.value))return{mode:"html",content:jd(l,o.value)};const a=cg(l,s.value,o.value);return a===null?{mode:"html",content:jd(l,o.value)}:{mode:"dynamic",nodes:a}});return(l,a)=>r.value.mode==="dynamic"?(y(),M("span",{key:0,class:Re(["html-inline-node",{"html-inline-node--loading":t.node.loading}])},[j(p(i),{nodes:r.value.nodes},null,8,["nodes"])],2)):r.value.mode==="text"?(y(),M("span",{key:1,class:Re(["html-inline-node",{"html-inline-node--loading":t.node.loading}])},N(r.value.content),3)):(y(),M("span",{key:2,class:Re(["html-inline-node",{"html-inline-node--loading":t.node.loading}]),innerHTML:r.value.content},null,10,xde))}}),[["__scopeId","data-v-d17f12b0"]]);sr.install=e=>{e.component(sr.__name,sr)};const Sde={class:"inline-code"},Ade={key:0},li=Gn(et({__name:"InlineCodeNode",props:{node:{}},setup(e){const t=e,n=p1(),o=nn("markstreamFade",void 0),s=nn("markstreamTextStreamState",void 0),i=nn("markstreamStreamVersion",void 0),r=R(()=>{const b=n.fade;return b===""||b===!0||b==="true"||b!==!1&&b!=="false"&&void 0}),l=R(()=>typeof r.value=="boolean"?r.value:typeof o?.value!="boolean"||o.value),a=R(()=>{var b;return String((b=t.node.code)!=null?b:"")}),u=R(()=>!l.value),c=R(()=>{var b;const _=(b=n["index-key"])!=null?b:n.indexKey;return _==null||_===""?"":String(_)}),d=Z(t.node.code),f=Z(""),h=Z(0);let m;function v(){m?.(),m=void 0}function k(){v(),f.value&&(d.value=d.value+f.value,f.value="")}Je([()=>t.node.code,c,l],([b])=>{const _=String(b??""),g=c.value,x=t$({nextContent:_,persistedContent:g?s?.get(g):void 0,currentState:{settledContent:d.value,streamedDelta:f.value},typewriterEnabled:l.value});d.value=x.settledContent,f.value=x.streamedDelta,x.appended?(h.value+=1,(function(){if(!f.value||m||!i)return;const S=i.value;m=Je(()=>i.value,T=>{T!==S&&k()},{flush:"sync"})})()):f.value||v(),g&&s?.set(g,_)},{immediate:!0}),d1(v);const w=R(()=>h.value%2==0?"inline-code-stream-delta--a":"inline-code-stream-delta--b");return(b,_)=>(y(),M("code",Sde,[u.value?(y(),M(Pe,{key:0},[qe(N(a.value),1)],64)):(y(),M(Pe,{key:1},[d.value?(y(),M("span",Ade,N(d.value),1)):ee("",!0),f.value?(y(),M("span",{key:1,class:Re(["inline-code-stream-delta",[w.value]]),onAnimationend:k},N(f.value),35)):ee("",!0)],64))]))}}),[["__scopeId","data-v-4e331c97"]]);li.install=e=>{e.component(li.__name,li)};const e8=Z(!1),T_=Z(""),E_=Z("top"),Yf=Z(null),Xf=Z(null),t8=Z(null),n8=Z(null),I_=Z(null);let Qh=null,em=null,o8=0;function m$(){Qh&&(clearTimeout(Qh),Qh=null),em&&(clearTimeout(em),em=null)}let bh=!1,Ch=null,L_=!1;function Mde(e,t,n="top",o=!1,s,i){if(!e)return;const r=++o8;m$();const l=()=>mo(null,null,function*(){var a,u;if(yield(function(){return mo(this,null,function*(){if(!bh&&!L_&&typeof document<"u"){Ch!=null||(Ch=mo(null,null,function*(){const[{createApp:c,h:d},{default:f}]=yield Promise.all([jo(()=>import("./vue.runtime.esm-bundler-J0WjtLlK.js"),[]),jo(()=>import("./Tooltip-DbYQWF1U.js"),[])]),h=document.createElement("div");h.setAttribute("data-singleton-tooltip","1"),document.body.appendChild(h),c({setup:()=>()=>{var m;return d(f,{visible:e8.value,"anchor-el":Yf.value,content:T_.value,placement:E_.value,id:Xf.value,originX:t8.value,originY:n8.value,isDark:(m=I_.value)!=null?m:void 0})}}).mount(h),bh=!0}));try{yield Ch}catch(c){bh=!1,Ch=null,L_=!0,console.warn("[markstream-vue] Failed to mount Tooltip component. Tooltips will be disabled.",c)}}})})(),bh&&r===o8){Xf.value=`tooltip-${Date.now()}-${Math.floor(1e3*Math.random())}`,Yf.value=e,T_.value=t,E_.value=n,t8.value=(a=s?.x)!=null?a:null,n8.value=(u=s?.y)!=null?u:null,I_.value=typeof i=="boolean"?i:null,e8.value=!0;try{e.setAttribute("aria-describedby",Xf.value)}catch{}}});o?l():Qh=setTimeout(l,80)}function Tde(e=!1){o8+=1,m$();const t=()=>{if(Yf.value&&Xf.value)try{Yf.value.removeAttribute("aria-describedby")}catch{}e8.value=!1,Yf.value=null,Xf.value=null,t8.value=null,n8.value=null};e?t():em=setTimeout(t,120)}const Ede={"common.copy":"Copy","common.copied":"Copied","common.decrease":"Decrease","common.reset":"Reset","common.increase":"Increase","common.expand":"Expand","common.collapse":"Collapse","common.preview":"Preview","common.source":"Source","common.export":"Export","common.open":"Open","common.minimize":"Minimize","common.zoomIn":"Zoom in","common.zoomOut":"Zoom out","common.resetZoom":"Reset zoom","image.loadError":"Image failed to load","image.loading":"Loading image..."},Ide=Symbol("markstreamI18nFallback");function g$(e,t){var n;return(n=t?.[e])!=null?n:Ede[e]}const s8=(e,t)=>{var n;return(n=g$(e,t))!=null?n:(function(o){return(o.split(".").pop()||o).replace(/[_-]/g," ").replace(/([A-Z])/g," $1").replace(/\s+/g," ").replace(/\b\w/g,s=>s.toUpperCase()).trim()})(e)};function $_(e,t){return{t(n){const o=g$(n,t);if(e.te&&o!=null&&!e.te(n))return s8(n,t);const s=e.t(n);return s===n&&o!=null?s8(n,t):s}}}function Lde(){const e=(function(){var n,o,s;try{const i=ds(),r=Ide,l=i?.provides,a=(n=i?.appContext)==null?void 0:n.provides;return(s=(o=l?.[r])!=null?o:a?.[r])!=null?s:null}catch{}return null})(),t=(function(){var n,o;try{const s=ds(),i=s?.proxy,r=i?.$t;if(typeof r=="function"){const u=i?.$te;return{t:r.bind(i),te:typeof u=="function"?u.bind(i):void 0}}const l=(o=(n=s?.appContext)==null?void 0:n.config)==null?void 0:o.globalProperties,a=l?.$t;if(typeof a=="function"){const u=l?.$te;return{t:a.bind(l),te:typeof u=="function"?u.bind(l):void 0}}}catch{}return null})();if(t)return $_(t,e);try{const n=globalThis.$vueI18nUse||null;if(n&&typeof n=="function")try{const o=n();if(o&&typeof o.t=="function")return $_({t:o.t.bind(o),te:typeof o.te=="function"?o.te.bind(o):void 0},e)}catch{}}catch{}return{t:n=>s8(n,e)}}const v$=Symbol("ViewportPriority"),y$=Symbol("ViewportPriorityOptions"),k$=Symbol("OffscreenHeavyNodeDeferral"),$de=R(()=>!1),yc="400px";function h5(){return nn(y$,void 0)}function m5(){return nn(k$,$de)}function Nde(e,t){var n,o;const s=typeof window<"u"&&typeof document<"u",i=typeof t=="boolean"?Z(t):t,r=s?(n=window.requestIdleCallback)!=null?n:T=>window.setTimeout(()=>T({didTimeout:!0,timeRemaining:()=>0}),16):null,l=s?(o=window.cancelIdleCallback)!=null?o:T=>window.clearTimeout(T):null,a=new WeakMap;let u=1;const c=new Map,d=new Map,f=new Set;let h=null,m=null;function v(T){if(!T)return"viewport";let A=a.get(T);return A||(A=u++,a.set(T,A)),String(A)}function k(){if(h!=null){try{l?.(h)}catch{}h=null}}function w(T){if(T){const A=c.get(T);if(A&&!A.targets.size){try{A.io.disconnect()}catch{}c.delete(T)}}d.size||f.size||k()}function b(T){const A=d.get(T);if(!A)return;const E=c.get(A.bucketKey);if(!A.visible.value){A.visible.value=!0;try{A.resolve()}catch{}}try{E?.io.unobserve(T)}catch{}E?.targets.delete(T),d.delete(T),f.delete(T),w(A.bucketKey)}function _(){window.__MARKSTREAM_DISABLE_VIEWPORT_PRIORITY_IDLE_DRAIN__!==!0&&r&&h==null&&f.size&&(h=r(()=>{h=null;const T=f.values().next().value;T&&(f.delete(T),b(T),f.size&&_())},{timeout:1200}))}function g(T,A){if(!s||typeof IntersectionObserver>"u")return null;const E=(function(H,O){var F,U,z;return{root:(F=e?.(H??null))!=null?F:null,rootMargin:(U=O?.rootMargin)!=null?U:yc,threshold:(z=O?.threshold)!=null?z:0}})(T,A),P=[v((D=E).root),D.rootMargin,D.threshold].join("\0");var D;const I=c.get(P);if(I)return{key:P,bucket:I};let $;try{$=new IntersectionObserver(H=>{for(const O of H)(O.isIntersecting||O.intersectionRatio>0)&&b(O.target)},{root:E.root,rootMargin:E.rootMargin,threshold:E.threshold})}catch{return null}const B={io:$,targets:new Map};return c.set(P,B),{key:P,bucket:B}}function x(){if(s&&i.value)for(const[T,A]of Array.from(d.entries())){const E=g(T,A.opts);if(!E){b(T);continue}if(E.key===A.bucketKey)continue;const P=A.bucketKey,D=c.get(P);try{D?.io.unobserve(T)}catch{}D?.targets.delete(T),A.bucketKey=E.key,E.bucket.targets.set(T,A),E.bucket.io.observe(T),w(P)}}Je(i,T=>{if(!T){for(const A of Array.from(d.keys()))b(A);k()}},{flush:"sync"});const S=(T,A)=>{const E=Z(!1);let P,D=!1;const I=new Promise(O=>{P=()=>{D||(D=!0,O())}}),$=()=>{const O=d.get(T);if(!O)return f.delete(T),void w();const F=c.get(O.bucketKey);try{F?.io.unobserve(T)}catch{}F?.targets.delete(T),d.delete(T),f.delete(T),w(O.bucketKey)};if(!s||!i.value)return E.value=!0,P(),{isVisible:E,whenVisible:I,destroy:$};const B=g(T,A);if(!B)return E.value=!0,P(),{isVisible:E,whenVisible:I,destroy:$};const H={resolve:P,visible:E,bucketKey:B.key,opts:A};return d.set(T,H),B.bucket.targets.set(T,H),B.bucket.io.observe(T),s&&m==null&&(m=window.requestAnimationFrame(()=>{m=null,x()})),A?.allowIdle!==!1&&(f.add(T),_()),{isVisible:E,whenVisible:I,destroy:$}};return S.refresh=x,Ln(v$,S),S}function g5(){var e,t;const n=nn(v$,void 0);if(n)return n;const o=new WeakMap,s=new Map,i=new Set;let r=null;const l=typeof window<"u"?(e=window.requestIdleCallback)!=null?e:h=>window.setTimeout(()=>h({didTimeout:!0,timeRemaining:()=>0}),16):null,a=typeof window<"u"?(t=window.cancelIdleCallback)!=null?t:h=>window.clearTimeout(h):null,u=()=>{if(r!=null){try{a?.(r)}catch{}r=null}},c=h=>{if(!h)return;const m=s.get(h);if(m&&!m.targets.size){try{m.io.disconnect()}catch{}s.delete(h)}},d=h=>{const m=o.get(h);if(!m)return;const v=s.get(m.bucketKey);if(!m.visible.value){m.visible.value=!0;try{m.resolve()}catch{}}try{v?.io.unobserve(h)}catch{}o.delete(h),v?.targets.delete(h),i.delete(h),c(m.bucketKey),i.size||u()},f=()=>{window.__MARKSTREAM_DISABLE_VIEWPORT_PRIORITY_IDLE_DRAIN__!==!0&&l&&r==null&&i.size&&(r=l(()=>{r=null;const h=i.values().next().value;h&&(i.delete(h),d(h),i.size&&f())},{timeout:1200}))};return(h,m)=>{const v=Z(!1);let k,w=!1;const b=new Promise(x=>{k=()=>{w||(w=!0,x())}}),_=()=>{const x=o.get(h);if(!x)return i.delete(h),void(i.size||u());const S=s.get(x.bucketKey);try{S?.io.unobserve(h)}catch{}o.delete(h),S?.targets.delete(h),i.delete(h),c(x.bucketKey),i.size||u()},g=(x=>{var S,T;if(typeof window>"u"||typeof IntersectionObserver>"u")return null;const A=($=>{var B,H;return[(B=$?.rootMargin)!=null?B:yc,(H=$?.threshold)!=null?H:0].join("\0")})(x),E=s.get(A);if(E)return{key:A,bucket:E};const P=(S=x?.rootMargin)!=null?S:yc;let D;try{D=new IntersectionObserver($=>{for(const B of $)(B.isIntersecting||B.intersectionRatio>0)&&d(B.target)},{root:null,rootMargin:P,threshold:(T=x?.threshold)!=null?T:0})}catch{return null}const I={io:D,targets:new Set};return s.set(A,I),{key:A,bucket:I}})(m);return g?(o.set(h,{resolve:k,visible:v,bucketKey:g.key}),g.bucket.targets.add(h),g.bucket.io.observe(h),m?.allowIdle!==!1&&(i.add(h),f()),{isVisible:v,whenVisible:b,destroy:_}):(v.value=!0,k(),{isVisible:v,whenVisible:b,destroy:_})}}function Fde(e,t){var n,o;const s=(o=(n=e.indexKey)!=null?n:t["index-key"])!=null?o:t.indexKey;return s==null||s===""?"":String(s)}const Rde=["data-markstream-viewport-pending"],Ode=["src","alt","title","loading","fetchpriority","decoding","tabindex","aria-label"],Pde={key:1,class:"image-placeholder"},Dde={key:1,class:"image-node__raw-text"},Bde={key:2,class:"image-shimmer-overlay"},Hde={key:1,class:"image-node__raw-text"},zde={key:3,class:"image-error"},Va=Gn(et({__name:"ImageNode",props:{node:{},fallbackSrc:{default:""},lazy:{type:Boolean,default:!1},usePlaceholder:{type:Boolean,default:!0}},emits:["load","error","click"],setup(e,{emit:t}){var n,o,s;const i=e,r=t,l=Z(!1),a=Z(!1),u=Z(""),c=Z("primary"),d=Z(null),f=p1(),h=nn(G3,null),m=g5(),v=h5(),k=m5(),w=R(()=>nw(i.node.src)),b=R(()=>nw(i.fallbackSrc)),_=(s=(o=(n=ds())==null?void 0:n.vnode.el)==null?void 0:o.querySelector)==null?void 0:s.call(o,"img"),g=typeof window<"u"&&_?.getAttribute("src")===(w.value||b.value),x=Z(typeof window>"u"||g||!k.value),S=Xr(null);let T="",A=null;const E=R(()=>u.value),P=R(()=>!i.lazy),D=R(()=>typeof window<"u"&&k.value&&!g),I=R(()=>!D.value||x.value),$=R(()=>I.value?E.value:""),B=R(()=>{var de,pe;return(pe=(de=v?.value.heavyBlockMargin)!=null?de:v?.value.rootMargin)!=null?pe:yc}),H=R(()=>!i.node.loading&&c.value!=="failed"&&u.value.length>0),O=R(()=>c.value==="failed"),F=R(()=>(!P.value||D.value&&!x.value)&&!l.value&&!a.value&&c.value!=="failed"&&u.value.length>0),U=R(()=>Fde(i,f));function z(de=U.value){de&&d.value&&h?.reportHeight(de,d.value.offsetHeight)}function W(de=U.value){de&&yt(()=>{z(de)})}function K(){A&&(clearTimeout(A),A=null)}function V(){const de=U.value;de&&T!==de&&(T&&h?.markSettled(T),K(),T=de,h?.markPending(de),typeof window<"u"&&(A=window.setTimeout(()=>{T===de&&(W(de),ie())},8e3)))}function ie(){return mo(this,null,function*(){const de=T;de&&(K(),T="",yield yt(),z(de),h?.markSettled(de))})}function ne(){if(c.value==="primary"&&b.value&&b.value!==u.value)return c.value="fallback",u.value=b.value,l.value=!1,a.value=!1,void W();c.value="failed",a.value=!0,r("error",u.value),W()}function X(){l.value=!0,a.value=!1,r("load",E.value),W()}function le(de){de.preventDefault(),l.value&&!a.value&&r("click",[de,E.value])}const{t:Ie}=Lde();return Je([w,b,()=>i.node.loading],()=>(l.value=!1,a.value=!1,i.node.loading||w.value?(u.value=w.value,void(c.value="primary")):b.value?(u.value=b.value,void(c.value="fallback")):(u.value="",c.value="failed",void(a.value=!0))),{immediate:!0}),typeof window<"u"&&Je([d,D],([de,pe],ve,oe)=>{var ye;if((ye=S.value)==null||ye.destroy(),S.value=null,!pe||x.value)return void(x.value=!0);if(!de)return void(x.value=!1);let G=!0;const Y=m(de,{rootMargin:B.value,allowIdle:!1});S.value=Y,x.value=Y.isVisible.value,Y.whenVisible.then(()=>{G&&S.value===Y&&(x.value=!0)}),oe(()=>{G=!1,Y.destroy(),S.value===Y&&(S.value=null)})},{immediate:!0}),Je([H,l,a,E,()=>i.lazy,I],([de,pe,ve,oe,ye,G])=>de&&oe&&!ve&&G?pe?(ie(),void W()):ye?(V(),void W()):void(pe||ve||V()):(ie(),void W()),{flush:"post",immediate:!0}),Vn(()=>{var de;(de=S.value)==null||de.destroy(),S.value=null,(function(){const pe=T;pe&&(K(),T="",h?.markSettled(pe))})()}),(de,pe)=>{var ve,oe,ye,G,Y;return y(),M("span",{ref_key:"rootRef",ref:d,class:"image-node-container","data-markstream-viewport-pending":D.value&&!x.value?"true":void 0},[H.value?(y(),M("img",{key:0,src:$.value||void 0,alt:String((oe=(ve=i.node.alt)!=null?ve:i.node.title)!=null?oe:""),title:String((G=(ye=i.node.title)!=null?ye:i.node.alt)!=null?G:""),class:Re(["image-node__img",{"is-loading":!P.value&&!l.value,"is-loaded":P.value||l.value,"has-natural-size":l.value,"cursor-pointer":l.value}]),loading:i.lazy?"lazy":void 0,fetchpriority:P.value?"high":void 0,decoding:P.value?"sync":"async",tabindex:l.value?0:-1,"aria-label":(Y=i.node.alt)!=null?Y:p(Ie)("image.preview"),onError:ne,onLoad:X,onClick:le},null,42,Ode)):ee("",!0),e.node.loading&&!a.value?(y(),M("span",Pde,[i.usePlaceholder?xn(de.$slots,"placeholder",{key:0,node:i.node,displaySrc:E.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:i.fallbackSrc,lazy:i.lazy},()=>[pe[0]||(pe[0]=C("span",{class:"image-shimmer"},null,-1))],!0):(y(),M("span",Dde,N(e.node.raw),1))])):ee("",!0),F.value&&!e.node.loading?(y(),M("span",Bde,[i.usePlaceholder?xn(de.$slots,"placeholder",{key:0,node:i.node,displaySrc:E.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:i.fallbackSrc,lazy:i.lazy},()=>[pe[1]||(pe[1]=C("span",{class:"image-shimmer"},null,-1))],!0):(y(),M("span",Hde,N(e.node.raw),1))])):ee("",!0),O.value?(y(),M("span",zde,[xn(de.$slots,"error",{node:i.node,displaySrc:E.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:i.fallbackSrc,lazy:i.lazy},()=>[pe[2]||(pe[2]=C("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24"},[C("path",{fill:"currentColor",d:"M2 2h20v10h-2V4H4v9.586l5-5L14.414 14L13 15.414l-4-4l-5 5V20h8v2H2zm13.547 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-3 1a3 3 0 1 1 6 0a3 3 0 0 1-6 0m3.625 6.757L19 17.586l2.828-2.829l1.415 1.415L20.414 19l2.829 2.828l-1.415 1.415L19 20.414l-2.828 2.829l-1.415-1.415L17.586 19l-2.829-2.828z"})],-1)),C("span",null,N(p(Ie)("image.loadError")),1)],!0)])):ee("",!0)],8,Rde)}}}),[["__scopeId","data-v-046e82ac"]]);Va.install=e=>{e.component(Va.__name,Va)};const Wde={key:2},El=et({__name:"NodeChildRenderer",props:{node:{},components:{},customId:{},indexKey:{},fallbackToText:{type:Boolean,default:!1}},setup(e){const t=e,n=fs(()=>t.customId),o=nn("markstreamHtmlPolicy",void 0),s=nn("markstreamNestedRendererProps",void 0),i=R(()=>{var m;return(m=o?.value)!=null?m:"safe"}),r=R(()=>{var m,v;const k=(m=s?.value)!=null?m:{};return rn(mt({},k),{customId:(v=t.customId)!=null?v:k.customId,htmlPolicy:i.value})}),l=zr({loader:()=>Promise.resolve().then(()=>M5),suspensible:!1}),a=R(()=>t.components[String(t.node.type)]),u=R(()=>!!(a.value&&n.value[t.node.type]&&!Qp(String(t.node.type)))),c=R(()=>u.value?p5(t.node,i.value):void 0),d=R(()=>Array.isArray(t.node.children)&&t.node.children.length>0),f=R(()=>{var m;return String((m=t.node.content)!=null?m:"")}),h=R(()=>{var m,v;return String((v=(m=t.node.content)!=null?m:t.node.raw)!=null?v:"")});return(m,v)=>a.value&&u.value?(y(),he(bs(a.value),zn({key:0},c.value,{node:e.node,loading:e.node.loading,"index-key":e.indexKey,"custom-id":e.customId,"is-dark":r.value.isDark}),{default:me(()=>[d.value?(y(),he(p(l),zn({key:0},r.value,{nodes:e.node.children,"index-key":e.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):f.value?(y(),he(p(l),zn({key:1},r.value,{content:f.value,final:!e.node.loading,"index-key":`${e.indexKey||"child"}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):ee("",!0)]),_:1},16,["node","loading","index-key","custom-id","is-dark"])):a.value?(y(),he(bs(a.value),{key:1,node:e.node,"custom-id":e.customId,"index-key":e.indexKey},null,8,["node","custom-id","index-key"])):e.fallbackToText?(y(),M("span",Wde,N(h.value),1)):ee("",!0)}}),N_=Object.freeze({enabled:!0,contextLineCount:2,minimumLineCount:4,revealLineCount:5});function Ude(e){var t;if(typeof e=="boolean")return e;if(e&&typeof e=="object"){const n=e;return rn(mt(mt({},N_),n),{enabled:(t=n.enabled)==null||t})}return mt({},N_)}function v5(e,t){if(e.renderSideBySide===!1)return!0;if(e.useInlineViewWhenSpaceIsLimited!==!0)return!1;const n=e.renderSideBySideInlineBreakpoint,o=typeof n=="number"&&Number.isFinite(n)?n:900;return t>0&&t<=o}function b$(e){var t,n;const o=(n=(t=String(e??"").split(/\r?\n/,1)[0])==null?void 0:t.trim())!=null?n:"";if(o.length<3)return"";const s=o[0];if(s!=="`"&&s!=="~"||o[1]!==s||o[2]!==s)return"";let i=3;for(;o[i]===s;)i+=1;return o.slice(i).trim()}function F_(e){var t;return((t=String(e??"").trim().split(/\s+/,1)[0])!=null?t:"")==="diff"}function jde(e){var t;return e.diff===!0||F_(e.language)||F_(b$(String((t=e.raw)!=null?t:"")))}function Vde(e,t,n){const o=(function(s){const i=b$(s);if(!i)return"";const r=i.split(/\s+/).filter(Boolean);if(!r.length)return"";const l=r[0]==="diff"?r.slice(1):r;for(const a of l){const u=a.includes(":")?a.slice(a.indexOf(":")+1):a;if(u&&/[./\\-]/.test(u))return u}return""})(e);return{title:o||t,caption:o?n?`Diff / ${t}`:t:""}}const qde=["aria-busy","aria-label","data-language","data-markstream-line-numbers"],Kde={key:0,translate:"no",class:"markstream-pre__diff-code"},Zde={class:"markstream-pre__diff-pane-content"},Gde={class:"markstream-pre__diff-number","aria-hidden":"true"},Yde={class:"markstream-pre__diff-content"},Xde={class:"markstream-pre__diff-content-inner"},Jde={key:0,class:"markstream-pre__line-numbers","aria-hidden":"true"},Qde=["textContent"],e1e=["textContent"],Pi=et({__name:"PreCodeNode",props:{node:{},loading:{type:Boolean},showLineNumbers:{type:Boolean},diffInline:{type:Boolean},diffHideUnchangedRegions:{type:[Boolean,Object]},reservedHeightPx:{}},setup(e){const t=e;function n(X,le){const Ie=String(X??"");return le?Ie:Ie.replace(/\r\n$|\n$|\r$/,"")}const o=R(()=>{var X,le,Ie;const de=String((le=(X=t.node)==null?void 0:X.language)!=null?le:"");return String((Ie=String(de).split(/\s+/g)[0])!=null?Ie:"").toLowerCase().replace(/[^\w-]/g,"")||"plaintext"}),s=R(()=>`language-${o.value}`),i=R(()=>{var X;return t.loading===!0||((X=t.node)==null?void 0:X.loading)===!0}),r=R(()=>{var X;return n((X=t.node)==null?void 0:X.code,i.value)});let l="",a=1;const u=R(()=>(function(X){let le=0,Ie=1;X.startsWith(l)&&(le=l.length,Ie=a,le>0&&X[le-1]==="\r"&&X[le]===` +`&&le++);for(let de=le;de<X.length;de++)X[de]===` +`?Ie++:X[de]==="\r"&&(Ie++,X[de+1]===` +`&&de++);return l=X,a=Ie,Ie})(r.value)),c=R(()=>r.value.split(/\r\n|\n|\r/));let d=0,f="";const h=R(()=>{const X=u.value;X<d&&(d=0,f="");for(let le=d+1;le<=X;le++)f+=`${f?` +`:""}${le}`;return d=X,f}),m=R(()=>{var X;return t.showLineNumbers===!0&&((X=t.node)==null?void 0:X.diff)===!0}),v=R(()=>m.value&&t.diffInline===!0),k=R(()=>{const X=Number(t.reservedHeightPx);if(!Number.isFinite(X)||X<=0)return;const le=`${Math.ceil(X)}px`;return i.value?{maxHeight:le,overflow:"auto"}:{height:le,minHeight:le,maxHeight:le,overflow:"auto"}}),w=["diff ","index ","--- ","+++ ","@@ "];function b(X){return String(X??"").trim().length===0}function _(X,le="context",Ie={}){const de=b(X);return{code:X,kind:de&&le!=="hunk"&&le!=="spacer"&&!Ie.preserveBlankKind?"context":le,empty:de}}function g(X){const le=n(X,i.value);return le?le.split(/\r\n|\n|\r/):[]}function x(X,le){return!b(X[le])||le<X.length-1}function S(X){return X.startsWith("-")&&!X.startsWith("---")}function T(X){return X.startsWith("+")&&!X.startsWith("+++")}function A(X){return X.some(le=>w.some(Ie=>le.startsWith(Ie)))}function E(X,le){return le||!X.startsWith(" ")||X.startsWith(" ")?X:` ${X}`}function P(X,le){const Ie=X.length,de=le.length,pe=[];let ve=0;for(;ve<Ie&&ve<de&&X[ve]===le[ve];)pe.push({originalIndex:ve,modifiedIndex:ve}),ve++;const oe=[];let ye=Ie-1,G=de-1;for(;ye>=ve&&G>=ve&&X[ye]===le[G];)oe.unshift({originalIndex:ye,modifiedIndex:G}),ye--,G--;const Y=ye-ve+1,fe=G-ve+1;if(Y<=0||fe<=0||i.value||(Y+1)*(fe+1)>15e5)return pe.concat(oe);const we=fe+1,ge=new Uint32Array((Y+1)*(fe+1));for(let ue=Y-1;ue>=0;ue--)for(let Se=fe-1;Se>=0;Se--){const ze=ue*we+Se;if(X[ve+ue]===le[ve+Se])ge[ze]=ge[(ue+1)*we+Se+1]+1;else{const _e=ge[(ue+1)*we+Se],Ee=ge[ue*we+Se+1];ge[ze]=_e>=Ee?_e:Ee}}const Q=[];let te=0,ce=0;for(;te<Y&&ce<fe;)X[ve+te]===le[ve+ce]?(Q.push({originalIndex:ve+te,modifiedIndex:ve+ce}),te++,ce++):ge[(te+1)*we+ce]>=ge[te*we+ce+1]?te++:ce++;return pe.concat(Q,oe)}function D(X){var le;const Ie=(function(){var G,Y;const fe=t.diffHideUnchangedRegions;if(fe==null||fe===!1)return null;const we=fe===!0?{}:fe;return we.enabled===!1?null:{contextLineCount:Math.max(0,Math.floor((G=we.contextLineCount)!=null?G:2)),minimumLineCount:Math.max(1,Math.floor((Y=we.minimumLineCount)!=null?Y:4))}})();if(!Ie||X.length<1||X.length>2||X.length===2&&X[0].lines.length!==X[1].lines.length)return X;const de=X[0].lines,pe=(le=X[1])==null?void 0:le.lines,ve=G=>de[G].kind==="context"&&(pe===void 0||pe[G].kind==="context"&&de[G].code===pe[G].code),oe=[];let ye=0;for(;ye<de.length;){const G=ye;for(;ye<de.length&&ve(ye);)ye++;const Y=ye;if(Y-G>=Ie.minimumLineCount){const fe=G+(G===0?0:Ie.contextLineCount),we=Y-(Y===de.length?0:Ie.contextLineCount);we-fe>=Ie.minimumLineCount&&oe.push({start:fe,end:we})}ye===G&&ye++}return oe.length?X.map((G,Y)=>{const fe=[];let we=0;for(const ge of oe)fe.push(...G.lines.slice(we,ge.start)),fe.push({code:Y===0?"Unmodified lines":"",kind:"collapsed",empty:!1,key:`${G.key}-collapsed-${ge.start}-${ge.end}`,number:""}),we=ge.end;return fe.push(...G.lines.slice(we)),rn(mt({},G),{lines:fe})}):X}const I=R(()=>{var X,le,Ie,de;if(!m.value)return[];const pe=(function(Y){const fe=Y.some(ge=>S(ge)),we=Y.some(ge=>T(ge));return fe&&we||(function(){var ge,Q,te,ce;if(o.value==="diff")return!0;const ue=(ce=(te=String((Q=(ge=t.node)==null?void 0:ge.raw)!=null?Q:"").split(/\r?\n/,1)[0])==null?void 0:te.trim())!=null?ce:"";return/^`{3,}\s*diff(?:\s|$)|^~{3,}\s*diff(?:\s|$)/.test(ue)})()&&(fe||we)})(c.value),ve=(function(){var Y,fe;return((Y=t.node)==null?void 0:Y.originalCode)!=null||((fe=t.node)==null?void 0:fe.updatedCode)!=null})();if(v.value){const Y=ve?(function(fe,we){const ge=g(fe),Q=g(we),te=P(ge,Q);if(te.length>0){const Ee=[];let it=0,Fe=0;for(const Oe of te){for(;it<Oe.originalIndex;)Ee.push(rn(mt({},_(ge[it],"removed",{preserveBlankKind:x(ge,it)})),{key:`inline-removed-source-${it}`,number:it+1})),it++;for(;Fe<Oe.modifiedIndex;)Ee.push(rn(mt({},_(Q[Fe],"added",{preserveBlankKind:x(Q,Fe)})),{key:`inline-added-source-${Fe}`,number:Fe+1})),Fe++;Ee.push(rn(mt({},_(Q[Oe.modifiedIndex])),{key:`inline-context-source-${Oe.originalIndex}-${Oe.modifiedIndex}`,number:Oe.modifiedIndex+1})),it=Oe.originalIndex+1,Fe=Oe.modifiedIndex+1}for(;it<ge.length;)Ee.push(rn(mt({},_(ge[it],"removed",{preserveBlankKind:x(ge,it)})),{key:`inline-removed-source-${it}`,number:it+1})),it++;for(;Fe<Q.length;)Ee.push(rn(mt({},_(Q[Fe],"added",{preserveBlankKind:x(Q,Fe)})),{key:`inline-added-source-${Fe}`,number:Fe+1})),Fe++;return Ee}const ce=[];let ue=0,Se=ge.length-1,ze=Q.length-1;for(;ue<=Se&&ue<=ze&&ge[ue]===Q[ue];)ce.push(rn(mt({},_(Q[ue])),{key:`inline-prefix-${ue}`,number:ue+1})),ue++;const _e=[];for(;Se>=ue&&ze>=ue&&ge[Se]===Q[ze];)_e.unshift(rn(mt({},_(Q[ze])),{key:`inline-suffix-${ze}`,number:ze+1})),Se--,ze--;for(let Ee=ue;Ee<=Se;Ee++)ce.push(rn(mt({},_(ge[Ee],"removed",{preserveBlankKind:x(ge,Ee)})),{key:`inline-removed-source-${Ee}`,number:Ee+1}));for(let Ee=ue;Ee<=ze;Ee++)ce.push(rn(mt({},_(Q[Ee],"added",{preserveBlankKind:x(Q,Ee)})),{key:`inline-added-source-${Ee}`,number:Ee+1}));return ce.concat(_e)})((X=t.node)==null?void 0:X.originalCode,(le=t.node)==null?void 0:le.updatedCode):(function(fe){const we=[];let ge=1,Q=1;const te=A(fe);for(const[ce,ue]of fe.entries())if(ue.startsWith("@@")){const Se=ue.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);Se&&(ge=Number(Se[1]),Q=Number(Se[2])),we.push(rn(mt({},_(ue,"hunk")),{key:`inline-hunk-${ce}`,number:""}))}else if(S(ue))we.push(rn(mt({},_(E(ue.slice(1),te),"removed",{preserveBlankKind:!0})),{key:`inline-removed-${ce}`,number:ge++}));else if(T(ue))we.push(rn(mt({},_(E(ue.slice(1),te),"added",{preserveBlankKind:!0})),{key:`inline-added-${ce}`,number:Q++}));else{const Se=te&&ue.startsWith(" ")?ue.slice(1):ue;we.push(rn(mt({},_(Se)),{key:`inline-context-${ce}`,number:Q})),ge++,Q++}return we})(c.value);return D([{key:"inline",className:"markstream-pre__diff-pane--inline",lines:Y}])}if(!pe&&ve)return(function(Y,fe){const we=g(Y),ge=g(fe),Q=P(we,ge),te=[],ce=[];let ue=0,Se=0,ze=0;const _e=(Ee,it)=>{const Fe=Math.max(Ee-ue,it-Se);for(let Oe=0;Oe<Fe;Oe++){const Ge=ue+Oe,at=Se+Oe;te.push(Ge<Ee?rn(mt({},_(we[Ge],"removed",{preserveBlankKind:x(we,Ge)})),{key:`original-changed-${ze}-${Ge}`,number:Ge+1}):rn(mt({},_("","spacer")),{key:`original-spacer-${ze}-${Oe}`,number:""})),ce.push(at<it?rn(mt({},_(ge[at],"added",{preserveBlankKind:x(ge,at)})),{key:`modified-changed-${ze}-${at}`,number:at+1}):rn(mt({},_("","spacer")),{key:`modified-spacer-${ze}-${Oe}`,number:""}))}ue=Ee,Se=it,ze++};for(const Ee of Q)_e(Ee.originalIndex,Ee.modifiedIndex),te.push(rn(mt({},_(we[Ee.originalIndex])),{key:`original-context-${Ee.originalIndex}-${Ee.modifiedIndex}`,number:Ee.originalIndex+1})),ce.push(rn(mt({},_(ge[Ee.modifiedIndex])),{key:`modified-context-${Ee.originalIndex}-${Ee.modifiedIndex}`,number:Ee.modifiedIndex+1})),ue=Ee.originalIndex+1,Se=Ee.modifiedIndex+1;return _e(we.length,ge.length),D([{key:"original",className:"markstream-pre__diff-pane--original",lines:te},{key:"modified",className:"markstream-pre__diff-pane--modified",lines:ce}])})((Ie=t.node)==null?void 0:Ie.originalCode,(de=t.node)==null?void 0:de.updatedCode);const oe=[],ye=[],G=A(c.value);for(const Y of c.value)if(Y.startsWith("@@"))oe.push(_(Y,"hunk")),ye.push(_(Y,"hunk"));else if(Y.startsWith("-")&&!Y.startsWith("---"))oe.push(_(E(Y.slice(1),G),"removed",{preserveBlankKind:!0}));else if(Y.startsWith("+")&&!Y.startsWith("+++"))ye.push(_(E(Y.slice(1),G),"added",{preserveBlankKind:!0}));else{const fe=G&&Y.startsWith(" ")?Y.slice(1):Y;oe.push(_(fe)),ye.push(_(fe))}return D([{key:"original",className:"markstream-pre__diff-pane--original",lines:oe.map((Y,fe)=>rn(mt({},Y),{key:`original-${fe}`,number:fe+1}))},{key:"modified",className:"markstream-pre__diff-pane--modified",lines:ye.map((Y,fe)=>rn(mt({},Y),{key:`modified-${fe}`,number:fe+1}))}])}),$=R(()=>I.value.some(X=>X.lines.some(le=>le.kind==="collapsed"))),B=R(()=>{const X=o.value;return X?`Code block: ${X}`:"Code block"}),H=Z(null),O=Z([]);let F=null,U=!1,z=null;function W(X){const le=Number.parseFloat(String(X??""));return Number.isFinite(le)&&le>0?le:0}function K(X,le){var Ie;if(!X)return le;if(X.classList.contains("markstream-pre__diff-line--collapsed"))return 32;const de=X.querySelector(".markstream-pre__diff-content"),pe=de?.getBoundingClientRect(),ve=(Ie=pe?.height)!=null?Ie:0;return Math.max(le,Math.ceil(ve))}function V(){U||typeof window>"u"||(F!=null&&window.cancelAnimationFrame(F),F=window.requestAnimationFrame(()=>{F=null,U||(function(){var X,le;F=null;const Ie=H.value;if(!Ie||!m.value||v.value||!Ie.classList.contains("is-wrap"))return void(O.value.length&&(O.value=[]));const de=(function(fe){const we=window.getComputedStyle(fe),ge=W(we.getPropertyValue("--markstream-pre-diff-line-height"));if(ge>0)return ge;const Q=W(we.lineHeight);return Q>0?Q:18})(Ie),pe=Array.from(Ie.querySelectorAll(".markstream-pre__diff-pane--original .markstream-pre__diff-line")),ve=Array.from(Ie.querySelectorAll(".markstream-pre__diff-pane--modified .markstream-pre__diff-line")),oe=Math.max(pe.length,ve.length),ye=[];for(let fe=0;fe<oe;fe++){const we=K((X=pe[fe])!=null?X:null,de),ge=K((le=ve[fe])!=null?le:null,de),Q=Math.max(de,we,ge);ye.push({rowHeight:Q,originalHeight:we,modifiedHeight:ge})}var G,Y;G=O.value,Y=ye,G.length===Y.length&&G.every((fe,we)=>{const ge=Y[we];return ge&&Math.abs(fe.rowHeight-ge.rowHeight)<=.5&&Math.abs(fe.originalHeight-ge.originalHeight)<=.5&&Math.abs(fe.modifiedHeight-ge.modifiedHeight)<=.5})||(O.value=ye)})()}))}function ie(X){z?.disconnect(),z=null,X&&m.value&&!v.value&&typeof ResizeObserver<"u"&&(z=new ResizeObserver(()=>{V()}),z.observe(X))}function ne(X,le){const Ie=O.value[X];if(!Ie)return;const de=le==="original"?Ie.originalHeight:Ie.modifiedHeight;return{"--markstream-pre-diff-synced-row-height":`${Math.ceil(Ie.rowHeight)}px`,"--markstream-pre-diff-content-height":`${Math.ceil(de)}px`}}return Je(H,X=>{ie(X),yt(()=>V())},{flush:"post"}),Je([m,v,I],()=>{ie(H.value),yt(()=>V())},{flush:"post",immediate:!0}),Vn(()=>{U=!0,F!=null&&(window.cancelAnimationFrame(F),F=null),z?.disconnect(),z=null}),(X,le)=>(y(),M("pre",{ref_key:"preRef",ref:H,style:Zt(k.value),class:Re([s.value,{"markstream-pre--line-numbers":t.showLineNumbers,"markstream-pre--diff-preview":m.value,"markstream-pre--diff-inline":v.value,"markstream-pre--diff-collapsed":$.value}]),"aria-busy":i.value,"aria-label":B.value,"data-language":o.value,"data-markstream-line-numbers":t.showLineNumbers?"1":void 0,"data-markstream-pre":"1",tabindex:"0"},[m.value?(y(),M("code",Kde,[(y(!0),M(Pe,null,pt(I.value,Ie=>(y(),M("span",{key:Ie.key,class:Re(["markstream-pre__diff-pane",Ie.className])},[C("span",Zde,[(y(!0),M(Pe,null,pt(Ie.lines,(de,pe)=>(y(),M("span",{key:de.key,class:Re(["markstream-pre__diff-line",[`markstream-pre__diff-line--${de.kind}`,{"markstream-pre__diff-line--empty":de.empty}]]),style:Zt(ne(pe,Ie.key))},[le[0]||(le[0]=C("span",{class:"markstream-pre__diff-rail","aria-hidden":"true"},null,-1)),C("span",Gde,N(de.number),1),C("span",Yde,[C("span",Xde,N(de.code),1)])],6))),128))])],2))),128))])):(y(),M(Pe,{key:1},[t.showLineNumbers?(y(),M("span",Jde,[C("span",{class:"markstream-pre__line-numbers-text",textContent:N(h.value)},null,8,Qde)])):ee("",!0),C("code",{translate:"no",class:"markstream-pre__code",textContent:N(r.value)},null,8,e1e)],64))],14,qde))}});Pi.install=e=>{e.component(Pi.__name,Pi)};const t1e={key:0},qo=Gn(et({__name:"TextNode",props:{node:{}},emits:["copy"],setup(e){const t=e,n=p1(),o=nn("markstreamFade",void 0),s=nn("markstreamTextStreamState",void 0),i=nn("markstreamStreamVersion",void 0),r=R(()=>{const k=n.fade;return k===""||k===!0||k==="true"||k!==!1&&k!=="false"&&void 0}),l=R(()=>typeof r.value=="boolean"?r.value:typeof o?.value!="boolean"||o.value),a=R(()=>{var k;const w=(k=n["index-key"])!=null?k:n.indexKey;return w==null||w===""?"":String(w)}),u=Z(t.node.content),c=Z(""),d=Z(0);let f;function h(){f?.(),f=void 0}function m(){h(),c.value&&(u.value=u.value+c.value,c.value="")}Je([()=>t.node.content,a,l],([k])=>{const w=String(k??""),b=a.value,_=t$({nextContent:w,persistedContent:b?s?.get(b):void 0,currentState:{settledContent:u.value,streamedDelta:c.value},typewriterEnabled:l.value});u.value=_.settledContent,c.value=_.streamedDelta,_.appended?(d.value+=1,(function(){if(!c.value||f||!i)return;const g=i.value;f=Je(()=>i.value,x=>{x!==g&&m()},{flush:"sync"})})()):c.value||h(),b&&s?.set(b,w)},{immediate:!0}),d1(h);const v=R(()=>d.value%2==0?"text-node-stream-delta--a":"text-node-stream-delta--b");return(k,w)=>(y(),M("span",{class:Re([[e.node.center?"text-node-center":""],"text-node"])},[u.value?(y(),M("span",t1e,N(u.value),1)):ee("",!0),c.value?(y(),M("span",{key:1,class:Re(["text-node-stream-delta",[v.value]]),onAnimationend:m},N(c.value),35)):ee("",!0)],2))}}),[["__scopeId","data-v-a7e90764"]]);function Af(e,t,n){return et({name:e,inheritAttrs:!1,setup(o,{attrs:s,slots:i}){var r,l;const a=g5(),u=h5(),c=m5(),d=typeof window<"u"&&((l=(r=ds())==null?void 0:r.vnode.el)==null?void 0:l.nodeType)===1,f=Z(typeof window>"u"||d||!c.value),h=Xr(null);let m=null;function v(k){const w=k&&"$el"in k?k.$el:k;h.value=w instanceof HTMLElement?w:null}return typeof window<"u"&&Je([h,c],([k,w],b,_)=>{if(m?.destroy(),m=null,!w||f.value)return void(f.value=!0);if(!k)return;let g=!0;const x=a(k,{rootMargin:u?.value.heavyBlockMargin,allowIdle:!1});m=x,f.value=x.isVisible.value,x.whenVisible.then(()=>{g&&m===x&&(f.value=!0)}),_(()=>{g=!1,x.destroy(),m===x&&(m=null)})},{immediate:!0}),Vn(()=>{m?.destroy(),m=null}),()=>tn(f.value?t:n,rn(mt({},s),{ref:v}),i)}})}qo.install=e=>{e.component(qo.__name,qo)};const dg=et({name:"CodeBlockNodeLoading",inheritAttrs:!1,props:["node","isDark","loading","stream","theme","darkTheme","lightTheme","isShowPreview","monacoOptions","enableFontSizeControl","minWidth","maxWidth","themes","showHeader","showCopyButton","showExpandButton","showPreviewButton","showCollapseButton","showFontSizeButtons","showTooltips","htmlPreviewAllowScripts","htmlPreviewSandbox","customId","estimatedHeightPx","estimatedContentHeightPx","estimatedDiffInline"],emits:["previewCode","copy"],setup(e,{attrs:t}){const n=e;return()=>{var o,s,i,r,l,a,u;const c=T2(String((s=(o=n.node)==null?void 0:o.language)!=null?s:"")),d=p_[c]||(c?c.charAt(0).toUpperCase()+c.slice(1):p_[""]),f=jde(n.node),h=Vde(String((r=(i=n.node)==null?void 0:i.raw)!=null?r:""),d,f),m=n.monacoOptions,v=f&&((l=n.estimatedDiffInline)!=null?l:v5(m??{},typeof window>"u"?0:window.innerWidth)),k=m?.diffAppearance,w=k==="dark"||k!=="light"&&n.isDark===!0,b=typeof m?.fontSize=="number"&&Number.isFinite(m.fontSize)&&m.fontSize>0?m.fontSize:12,_=typeof m?.lineHeight=="number"&&Number.isFinite(m.lineHeight)&&m.lineHeight>0?m.lineHeight:b===12?18:Math.max(12,Math.round(1.5*b)),g=typeof m?.tabSize=="number"&&Number.isFinite(m.tabSize)&&m.tabSize>0?m.tabSize:4,x=f?0:8,S=typeof((a=m?.padding)==null?void 0:a.top)=="number"&&Number.isFinite(m.padding.top)&&m.padding.top>=0?m.padding.top:x,T=typeof((u=m?.padding)==null?void 0:u.bottom)=="number"&&Number.isFinite(m.padding.bottom)&&m.padding.bottom>=0?m.padding.bottom:x,A=typeof m?.fontFamily=="string"?m.fontFamily.trim():"",E=mt(mt({fontSize:`${b}px`,lineHeight:`${_}px`,tabSize:g,paddingTop:`${S}px`,paddingBottom:`${T}px`,"--markstream-pre-line-number-top":`${S}px`},f?{"--markstream-pre-diff-line-height":`${_}px`}:{}),A?{"--markstream-code-font-family":A}:{}),P=()=>tn("button",{class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0","aria-hidden":"true",disabled:!0,tabindex:-1,type:"button"},[tn("svg",{class:"action-icon"})]),D=n.isShowPreview!==!1&&(c==="html"||c==="svg"),I=n.showFontSizeButtons!==!1&&n.enableFontSizeControl!==!1||n.showExpandButton!==!1||D&&n.showPreviewButton!==!1,$=H=>{if(H!=null)return typeof H=="number"?`${H}px`:String(H)},B=mt(mt(mt({"--markstream-code-layout-character-width":"1ch"},$(n.minWidth)?{minWidth:$(n.minWidth)}:{}),$(n.maxWidth)?{maxWidth:$(n.maxWidth)}:{}),f?{}:{color:"var(--vscode-editor-foreground, var(--markstream-code-fallback-fg, var(--code-fg)))",backgroundColor:"var(--vscode-editor-background, var(--markstream-code-fallback-bg, var(--code-bg)))",borderColor:"var(--markstream-code-border-color, var(--code-border))"});return tn("div",rn(mt({},t),{class:["code-block-container","rounded-lg","border",{dark:n.isDark===!0,"is-rendering":n.loading!==!1,"is-dark":w,"is-diff":f,"is-plain-text":c===""||c==="plaintext"||c==="text"},t.class],style:[B,t.style],"data-markstream-code-block":"1","data-markstream-enhanced":"false","data-markstream-code-block-state":n.loading?"streaming":"settled","data-markstream-code-loading":"1"}),[n.showHeader===!1?null:tn("div",{class:"code-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)] border-[var(--code-border)] bg-[var(--code-header-bg)] text-[var(--code-fg)]"},[tn("div",{class:"code-header-main"},[tn("span",{class:"icon-slot h-4 w-4 flex-shrink-0"}),tn("div",{class:"code-header-copy"},[tn("div",{class:"code-header-title"},h.title),h.caption?tn("div",{class:"code-header-caption"},h.caption):null])]),tn("div",{class:"flex items-center gap-0.5",style:{visibility:"hidden"}},[f?tn("div",{class:"code-diff-stats","aria-hidden":"true"},[tn("span",{class:"code-diff-stat removed"},"-0"),tn("span",{class:"code-diff-stat added"},"+0")]):null,n.showCopyButton===!1?null:P(),n.showCollapseButton===!1?null:P(),I?tn("div",{class:"relative"},[P()]):null])]),tn("div",{class:"code-block-shell-content",style:n.stream!==!1||n.loading===!1?void 0:{display:"none"}},[tn(Pi,{node:n.node,loading:n.loading,showLineNumbers:!0,reservedHeightPx:f?void 0:n.estimatedContentHeightPx,diffInline:v,diffHideUnchangedRegions:f?Ude(m?.diffHideUnchangedRegions):void 0,class:"code-pre-fallback",style:E,"data-markstream-code-loading":"1"})]),tn("div",{class:"code-loading-placeholder",style:n.stream===!1&&n.loading!==!1?void 0:{display:"none"}},[tn("div",{class:"loading-skeleton"},[tn("div",{class:"skeleton-line"}),tn("div",{class:"skeleton-line"}),tn("div",{class:"skeleton-line short"})])]),tn("span",{class:"sr-only","aria-live":"polite",role:"status"})])}}}),X9=Af("ViewportDeferredCodeBlockNode",zr({loader:()=>mo(null,null,function*(){try{return(yield jo(()=>import("./CodeBlockNode-BAtAs_qm.js"),__vite__mapDeps([4,5]))).default}catch(e){return console.warn('[markstream-vue] Optional peer dependency stream-diffs is missing. Falling back to preformatted code rendering. To enable enhanced code block features, please install "stream-diffs".',e),Pi}}),loadingComponent:dg,delay:0,suspensible:!1}),dg),Jr=zr(()=>mo(null,null,function*(){var e;if(((e=(function(){const t=Reflect.get(globalThis,"process");return t?.env})())==null?void 0:e.NODE_ENV)==="test"&&typeof window<"u")return t=>{var n,o,s,i;return tn(qo,rn(mt({},t),{node:{type:"text",content:(o=t.node.raw)!=null?o:`$${(n=t.node.content)!=null?n:""}$`,raw:(i=t.node.raw)!=null?i:`$${(s=t.node.content)!=null?s:""}$`}}))};try{return yield r$(),(yield jo(()=>import("./index7-BT2SBznQ.js"),[])).default}catch(t){console.warn('[markstream-vue] Optional peer dependencies for MathInlineNode are missing. Falling back to text rendering. To enable full math rendering features, please install "katex".',t)}return t=>{var n,o,s,i;return tn(qo,rn(mt({},t),{node:{type:"text",content:(o=t.node.raw)!=null?o:`$${(n=t.node.content)!=null?n:""}$`,raw:(i=t.node.raw)!=null?i:`$${(s=t.node.content)!=null?s:""}$`}}))}})),C$=zr(()=>mo(null,null,function*(){try{return yield r$(),(yield jo(()=>import("./index6-D4fZsFMu.js"),[])).default}catch(e){console.warn('[markstream-vue] Optional peer dependencies for MathBlockNode are missing. Falling back to text rendering. To enable full math rendering features, please install "katex".',e)}return e=>{var t,n,o,s;return tn(qo,rn(mt({},e),{node:{type:"text",content:(n=e.node.raw)!=null?n:`$$${(t=e.node.content)!=null?t:""}$$`,raw:(s=e.node.raw)!=null?s:`$$${(o=e.node.content)!=null?o:""}$$`}}))}})),xi=Gn(et({__name:"ReferenceNode",props:{node:{},messageId:{},threadId:{}},emits:["click","mouseEnter","mouseLeave"],setup:e=>(t,n)=>(y(),M("span",{class:"reference-node cursor-pointer text-xs rounded-md px-1.5 mx-0.5",role:"button",tabindex:"0",onClick:n[0]||(n[0]=o=>t.$emit("click",o,e.node.id,e.messageId,e.threadId)),onMouseenter:n[1]||(n[1]=o=>t.$emit("mouseEnter",o,e.node.id,e.messageId,e.threadId)),onMouseleave:n[2]||(n[2]=o=>t.$emit("mouseLeave",o,e.node.id,e.messageId,e.threadId))},N(e.node.id),33))}),[["__scopeId","data-v-775c65e4"]]);xi.install=e=>{e.component(xi.__name,xi)};const n1e={class:"superscript-node"},Wi=Gn(et({__name:"SuperscriptNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,emphasis:Ti,footnote_reference:or,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,emoji:zi,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("sup",n1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"superscript"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"superscript"}-${l}`,"fallback-to-text":""},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-24160b22"]]);Wi.install=e=>{e.component(Wi.__name,Wi)};const o1e={class:"subscript-node"},Ui=Gn(et({__name:"SubscriptNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,emphasis:Ti,footnote_reference:or,strikethrough:Ai,highlight:ir,insert:ji,superscript:Wi,emoji:zi,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("sub",o1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"subscript"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"subscript"}-${l}`,"fallback-to-text":""},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-197fa13b"]]);Ui.install=e=>{e.component(Ui.__name,Ui)};const s1e={class:"strong-node"},Si=Gn(et({__name:"StrongNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,emphasis:Ti,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,footnote_reference:or,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("strong",s1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"strong"}-${l}`,components:o.value,node:r,"index-key":`${e.indexKey||"strong"}-${l}`,"custom-id":t.customId},null,8,["components","node","index-key","custom-id"]))),128))]))}}),[["__scopeId","data-v-a8647104"]]);Si.install=e=>{e.component(Si.__name,Si)};const i1e={class:"strikethrough-node"},Ai=Gn(et({__name:"StrikethroughNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,emphasis:Ti,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,footnote_reference:or,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("del",i1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"strikethrough"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"strikethrough"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-b7a531fa"]]);Ai.install=e=>{e.component(Ai.__name,Ai)};const r1e=["href","title","aria-label","aria-hidden","target","rel"],l1e=["aria-hidden"],a1e={class:"link-text-wrapper relative inline-flex"},u1e={class:"leading-[normal] link-text"},Mi=Gn(et({__name:"LinkNode",props:{node:{},indexKey:{},customId:{},showTooltip:{type:Boolean,default:!0},color:{},underlineHeight:{},underlineBottom:{},animationDuration:{},animationOpacity:{},animationTiming:{},animationIteration:{}},setup(e){const t=e,n=nn("markstreamShowTooltips",void 0),o=R(()=>{const w=n?.value;return typeof w=="boolean"?w:t.showTooltip}),s=R(()=>{var w,b,_,g,x;const S=t.underlineBottom!==void 0?typeof t.underlineBottom=="number"?`${t.underlineBottom}px`:String(t.underlineBottom):"-3px",T=(w=t.animationOpacity)!=null?w:.35,A=Math.max(.12,Math.min(.5*T,T)),E={"--underline-height":`${(b=t.underlineHeight)!=null?b:2}px`,"--underline-bottom":S,"--underline-opacity":String(T),"--underline-rest-opacity":String(A),"--underline-duration":`${(_=t.animationDuration)!=null?_:1.6}s`,"--underline-timing":(g=t.animationTiming)!=null?g:"ease-in-out","--underline-iteration":typeof t.animationIteration=="number"?String(t.animationIteration):(x=t.animationIteration)!=null?x:"infinite"};return t.color&&(E["--link-color"]=t.color),E}),i=fs(()=>t.customId),r=R(()=>mt({text:qo,strong:Si,strikethrough:Ai,emphasis:Ti,image:Va,html_inline:sr,inline_code:li},i.value)),l=p1(),a=R(()=>{var w,b;const _=(w=t.node)==null?void 0:w.attrs;if(!_||typeof _!="object")return{};const g={};if(Array.isArray(_))for(const x of _)Array.isArray(x)&&x[0]&&(g[String(x[0])]=String((b=x[1])!=null?b:""));else for(const[x,S]of Object.entries(_))x&&S!=null&&S!==!1&&(g[x]=S===!0?"":String(S));return A_(g,"safe","a")}),u=R(()=>mt(mt({},l),a.value)),c=R(()=>{var w,b;return A_({href:String((b=(w=t.node)==null?void 0:w.href)!=null?b:"")},"safe","a").href}),d=R(()=>{if(!c.value)return;const w=u.value.target;return(typeof w=="string"?w.trim():String(w??"").trim())||(sie(c.value)?"_blank":void 0)}),f=R(()=>{var w;return String((w=d.value)!=null?w:"").trim().toLowerCase()==="_blank"}),h=R(()=>{if(!c.value)return;const w=u.value.rel,b=new Set((typeof w=="string"?w:String(w??"")).split(/\s+/).filter(Boolean)),_=new Set(Array.from(b).filter(g=>g.toLowerCase()!=="opener"));return f.value&&(_.add("noopener"),_.add("noreferrer")),_.size>0?Array.from(_).join(" "):void 0}),m=R(()=>{const w=mt({},u.value);return delete w.title,delete w.href,delete w.target,delete w.rel,w});function v(){o.value&&Tde()}const k=R(()=>{var w,b;const _=(w=t.node)==null?void 0:w.title;return typeof _=="string"&&_.trim().length>0?_:String((b=c.value)!=null?b:"")});return(w,b)=>{var _,g;return e.node.loading?(y(),M("span",zn({key:1,class:"link-loading inline-flex items-baseline gap-1.5","aria-hidden":e.node.loading?"false":"true"},p(l),{style:s.value}),[C("span",a1e,[C("span",u1e,[j(p(qo),{class:"leading-[normal] link-text",node:{type:"text",content:String((_=e.node.text)!=null?_:""),raw:String((g=e.node.text)!=null?g:"")},"index-key":`${e.indexKey||"link-text"}-loading`},null,8,["node","index-key"])]),b[1]||(b[1]=C("span",{class:"link-loading-indicator","aria-hidden":"true"},null,-1))])],16,l1e)):(y(),M("a",zn({key:0,class:"link-node",href:c.value,title:o.value?"":k.value,"aria-label":`Link: ${k.value}`,"aria-hidden":e.node.loading?"true":"false",target:d.value,rel:h.value},m.value,{style:s.value,onMouseenter:b[0]||(b[0]=x=>(function(S){var T,A,E,P;if(!o.value)return;const D=S,I=D?.clientX!=null&&D?.clientY!=null?{x:D.clientX,y:D.clientY}:void 0,$=((T=t.node)==null?void 0:T.title)||((A=c.value)!=null&&A.includes("xn--")&&((P=(E=t.node)==null?void 0:E.text)!=null&&P.includes("://"))?t.node.text:c.value)||"";Mde(S.currentTarget,$,"top",!1,I)})(x)),onMouseleave:v}),[(y(!0),M(Pe,null,pt(e.node.children,(x,S)=>(y(),he(p(El),{key:`${e.indexKey||"emphasis"}-${S}`,components:r.value,node:x,"custom-id":t.customId,"index-key":`${e.indexKey||"link-text"}-${S}`},null,8,["components","node","custom-id","index-key"]))),128))],16,r1e))}}}),[["__scopeId","data-v-367e6ca4"]]);Mi.install=e=>{e.component(Mi.__name,Mi)};const c1e={class:"insert-node"},ji=Gn(et({__name:"InsertNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,emphasis:Ti,strikethrough:Ai,highlight:ir,subscript:Ui,superscript:Wi,emoji:zi,footnote_reference:or,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("ins",c1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"insert"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"insert"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-1e2c29d4"]]);ji.install=e=>{e.component(ji.__name,ji)};const d1e={class:"highlight-node"},ir=Gn(et({__name:"HighlightNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,emphasis:Ti,strikethrough:Ai,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,footnote_reference:or,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("mark",d1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"highlight"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"highlight"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-7a62982a"]]);ir.install=e=>{e.component(ir.__name,ir)};const f1e={class:"emphasis-node"},Ti=Gn(et({__name:"EmphasisNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>mt({text:qo,inline_code:li,link:Mi,html_inline:sr,strong:Si,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,footnote_reference:or,math_inline:Jr,reference:xi},n.value));return(s,i)=>(y(),M("em",f1e,[(y(!0),M(Pe,null,pt(e.node.children,(r,l)=>(y(),he(p(El),{key:`${e.indexKey||"emphasis"}-${l}`,components:o.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"emphasis"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-2a5aafbf"]]);Ti.install=e=>{e.component(Ti.__name,Ti)};const p1e={class:"hard-break"},qa=Gn(et({__name:"HardBreakNode",props:{node:{}},setup:e=>(t,n)=>(y(),M("br",p1e))}),[["__scopeId","data-v-50c58f70"]]);qa.install=e=>{e.component(qa.__name,qa)};const $p=et({__name:"SimpleInlineRenderer",props:{nodes:{},customId:{},indexKey:{}},setup(e){const t=e,n=kt({checkbox:nr,checkbox_input:nr,emoji:zi,emphasis:Ti,hardbreak:qa,highlight:ir,inline_code:li,insert:ji,link:Mi,reference:xi,strikethrough:Ai,strong:Si,subscript:Ui,superscript:Wi,text:qo}),o=fs(()=>t.customId),s=R(()=>{const i=o.value;return Object.keys(i).length>0?mt(mt({},n),i):n});return(i,r)=>(y(!0),M(Pe,null,pt(e.nodes,(l,a)=>(y(),he(p(El),{key:a,components:s.value,node:l,"custom-id":t.customId,"index-key":`${e.indexKey||"inline"}-${a}`},null,8,["components","node","custom-id","index-key"]))),128))}});function i8(e){if(!e||typeof e!="object")return!1;const t=`|${e.type}|`;if(!"|checkbox|checkbox_input|emoji|emphasis|hardbreak|highlight|inline_code|insert|link|reference|strikethrough|strong|subscript|superscript|text|".includes(t))return!1;if(!"|emphasis|highlight|insert|link|strikethrough|strong|subscript|superscript|".includes(t))return!0;const n=e.children;return Array.isArray(n)&&n.every(i8)}function fg(e,t=!0,n=!1){if(!e||!n&&e.length===0)return null;if(e.every(i8))return e;if(!t||e.length!==1)return null;const o=e[0];if(o?.type!=="paragraph"||!Array.isArray(o.children))return null;const s=o.children;return(n||s.length>0)&&s.every(i8)?s:null}function kc(e){var t,n;if(!e?.length)return null;let o="";for(const s of e){if(s?.type!=="text"||s.center===!0)return null;o+=String((n=(t=s.content)!=null?t:s.raw)!=null?n:"")}return o}const h1e=["cite"],m1e={key:0,dir:"auto",class:"paragraph-node"},g1e=["custom-id"],tm=Gn(et({__name:"BlockquoteNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{},showTooltips:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=fs(()=>t.customId),o=R(()=>!!n.value.paragraph),s=R(()=>!!n.value.text),i=R(()=>fg(t.node.children,!o.value)),r=R(()=>t.fade!==!1||s.value?null:kc(i.value));return Ln("markstreamShowTooltips",R(()=>t.showTooltips)),Ln("markstreamFade",R(()=>t.fade)),(l,a)=>(y(),M("blockquote",{class:"blockquote blockquote-node",dir:"auto",cite:e.node.cite},[i.value?(y(),M("p",m1e,[r.value!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(r.value),9,g1e)):(y(),he(p($p),{key:1,nodes:i.value,"custom-id":t.customId,"index-key":`blockquote-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))])):(y(),he(p(Vi),{key:1,"show-tooltips":t.showTooltips,"index-key":`blockquote-${t.indexKey}`,nodes:t.node.children||[],"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:a[0]||(a[0]=u=>l.$emit("copy",u))},null,8,["show-tooltips","index-key","nodes","custom-id","typewriter","fade"]))],8,h1e))}}),[["__scopeId","data-v-abfecebc"]]);tm.install=e=>{e.component(tm.__name,tm)};const v1e={class:"definition-list"},y1e={class:"definition-term"},k1e={class:"definition-desc"},nm=Gn(et({__name:"DefinitionListNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e){const t=e;return(n,o)=>(y(),M("dl",v1e,[(y(!0),M(Pe,null,pt(t.node.items,(s,i)=>(y(),M(Pe,{key:i},[C("dt",y1e,[j(p(Vi),{"index-key":`definition-term-${t.indexKey}-${i}`,nodes:s.term,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:o[0]||(o[0]=r=>n.$emit("copy",r))},null,8,["index-key","nodes","custom-id","typewriter","fade"])]),C("dd",k1e,[j(p(Vi),{"index-key":`definition-desc-${t.indexKey}-${i}`,nodes:s.definition,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:o[1]||(o[1]=r=>n.$emit("copy",r))},null,8,["index-key","nodes","custom-id","typewriter","fade"])])],64))),128))]))}}),[["__scopeId","data-v-4e103b30"]]);nm.install=e=>{e.component(nm.__name,nm)};const b1e=["href","title"],Jf=Gn(et({__name:"FootnoteAnchorNode",props:{node:{}},setup(e){const t=e;function n(o){var s;if(o.preventDefault(),typeof document>"u")return;const i=`fnref-${String((s=t.node.id)!=null?s:"")}`,r=document.getElementById(i);r&&r.scrollIntoView({behavior:"smooth",block:"center"})}return(o,s)=>(y(),M("a",{class:"footnote-anchor text-sm hover:underline cursor-pointer",href:`#fnref-${e.node.id}`,title:`返回引用 ${e.node.id}`,onClick:n}," ↩︎ ",8,b1e))}}),[["__scopeId","data-v-e1eb37b6"]]);Jf.install=e=>{e.component(Jf.__name,Jf)};const C1e=["id"],w1e={class:"flex-1"},om=et({__name:"FootnoteNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e){const t=e;return(n,o)=>(y(),M("div",{id:`fnref--${e.node.id}`,class:"footnote-node flex text-sm leading-relaxed border-t border-[var(--footnote-border)] pt-2"},[C("div",w1e,[j(p(Vi),{"index-key":`footnote-${t.indexKey}`,nodes:t.node.children,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:o[0]||(o[0]=s=>n.$emit("copy",s))},null,8,["index-key","nodes","custom-id","typewriter","fade"])])],8,C1e))}});om.install=e=>{e.component(om.__name,om)};const _1e=["custom-id"],r8=Gn(et({__name:"HeadingNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=fs(()=>t.customId),o=nn("markstreamFade",void 0),s=R(()=>o?.value!==!1||n.value.text?null:kc(t.node.children)),i=R(()=>mt({text:qo,inline_code:li,link:Mi,image:Va,strong:Si,emphasis:Ti,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,checkbox:nr,checkbox_input:nr,footnote_reference:or,hardbreak:qa,math_inline:Jr,reference:xi},n.value));return(r,l)=>(y(),he(bs(`h${e.node.level}`),zn({class:["heading-node",[`heading-${e.node.level}`]],dir:"auto"},e.node.attrs),{default:me(()=>[s.value!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(s.value),9,_1e)):(y(!0),M(Pe,{key:1},pt(e.node.children,(a,u)=>(y(),he(p(El),{key:u,components:i.value,"custom-id":t.customId,node:a,"index-key":`${e.indexKey||"heading"}-${u}`},null,8,["components","custom-id","node","index-key"]))),128))]),_:1},16,["class"]))}}),[["__scopeId","data-v-7122dbe1"]]),L2=r8;L2.install=e=>{e.component(r8.__name,r8)};const x1e={key:0,dir:"auto",class:"paragraph-node"},S1e=["custom-id"],A1e={dir:"auto",class:"paragraph-node"},M1e=["custom-id"],Vd=Gn(et({__name:"ListItemNode",props:{node:{},item:{},indexKey:{},customId:{},typewriter:{type:Boolean},fade:{type:Boolean},showTooltips:{type:Boolean},value:{},isDark:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=R(()=>{var h;return(h=t.node)!=null?h:t.item}),o=fs(()=>t.customId),s=R(()=>!!o.value.paragraph),i=R(()=>!!o.value.text),r=R(()=>{var h;return fg((h=n.value)==null?void 0:h.children,!s.value)}),l=R(()=>{var h;if(s.value)return null;const m=(h=n.value)==null?void 0:h.children;if(!Array.isArray(m)||m.length<2)return null;const v=m[0];if(v?.type!=="paragraph"||!Array.isArray(v.children))return null;const k=m.slice(1);if(!k.every(b=>b?.type==="list"))return null;const w=fg([v]);return w?{paragraphChildren:w,nestedLists:k}:null});function a(){return t.fade===!1&&!i.value}const u=R(()=>a()?kc(r.value):null),c=R(()=>{var h;return a()?kc((h=l.value)==null?void 0:h.paragraphChildren):null}),d=Object.freeze({}),f=R(()=>{const{value:h}=t;return typeof h=="number"&&Number.isFinite(h)?{value:h}:d});return Ln("markstreamShowTooltips",R(()=>t.showTooltips)),Ln("markstreamFade",R(()=>t.fade)),(h,m)=>{var v,k;return y(),M("li",zn({class:"list-item",dir:"auto"},f.value),[r.value?(y(),M("p",x1e,[u.value!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(u.value),9,S1e)):(y(),he(p($p),{key:1,nodes:r.value,"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))])):l.value?(y(),M(Pe,{key:1},[C("p",A1e,[c.value!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(c.value),9,M1e)):(y(),he(p($p),{key:1,nodes:l.value.paragraphChildren,"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))]),(y(!0),M(Pe,null,pt(l.value.nestedLists,(w,b)=>(y(),he(p(Vi),{key:b,nodes:[w],"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-nested-${b}`,"show-tooltips":t.showTooltips,typewriter:t.typewriter,fade:t.fade,"is-dark":t.isDark,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0,onCopy:m[0]||(m[0]=_=>h.$emit("copy",_))},null,8,["nodes","custom-id","index-key","show-tooltips","typewriter","fade","is-dark"]))),128))],64)):(y(),he(p(Vi),{key:2,"show-tooltips":t.showTooltips,"index-key":`list-item-${t.indexKey}`,nodes:(k=(v=n.value)==null?void 0:v.children)!=null?k:[],"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"is-dark":t.isDark,"batch-rendering":!1,onCopy:m[1]||(m[1]=w=>h.$emit("copy",w))},null,8,["show-tooltips","index-key","nodes","custom-id","typewriter","fade","is-dark"]))],16)}}}),[["__scopeId","data-v-617214f9"]]);Vd.install=e=>{e.component(Vd.__name,Vd)};const qd=Gn(et({__name:"ListNode",props:{node:{},customId:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},showTooltips:{type:Boolean},isDark:{type:Boolean}},emits:["copy"],setup(e){const t=fs(()=>e.customId),n=R(()=>t.value.list_item||Vd);return(o,s)=>(y(),he(bs(e.node.ordered?"ol":"ul"),{class:Re(["list-node",{"list-decimal":e.node.ordered,"list-disc":!e.node.ordered}])},{default:me(()=>[(y(!0),M(Pe,null,pt(e.node.items,(i,r)=>{var l;return y(),he(bs(n.value),zn({key:`${e.indexKey||"list"}-${r}`},{ref_for:!0},{showTooltips:e.showTooltips},{node:i,"custom-id":e.customId,"index-key":`${e.indexKey||"list"}-${r}`,typewriter:e.typewriter,fade:e.fade,"is-dark":e.isDark,value:e.node.ordered?((l=e.node.start)!=null?l:1)+r:void 0,onCopy:s[0]||(s[0]=a=>o.$emit("copy",a))}),null,16,["node","custom-id","index-key","typewriter","fade","is-dark","value"])}),128))]),_:1},8,["class"]))}}),[["__scopeId","data-v-99cb95e0"]]);qd.install=e=>{e.component(qd.__name,qd)};const T1e={key:2,class:"html-block-node__raw"},E1e=["innerHTML"],I1e={key:1,class:"html-block-node__placeholder"},Qf=Gn(et({__name:"HtmlBlockNode",props:{node:{},customId:{},htmlPolicy:{}},setup(e){const t=e,n=nn("markstreamHtmlPolicy",void 0),o=nn("markstreamNestedRendererProps",void 0),s=R(()=>{var I,$;return($=(I=t.htmlPolicy)!=null?I:n?.value)!=null?$:"safe"}),i=R(()=>{var I,$;const B=(I=o?.value)!=null?I:{};return rn(mt({},B),{customId:($=t.customId)!=null?$:B.customId,htmlPolicy:s.value})}),r=zr({loader:()=>Promise.resolve().then(()=>M5),suspensible:!1}),l=R(()=>{const I=Xh(t.node.attrs,s.value);if(!I)return;const $=Zf(I);return Object.keys($).length>0?$:void 0}),a=R(()=>{const I=String(t.node.tag||"").trim(),$=Xh(t.node.attrs,s.value,I);if(!$)return;const B=Zf($);return Object.keys(B).length>0?B:void 0}),u=fs(()=>t.customId),c=et({name:"DynamicRenderer",props:{nodes:{type:Array,required:!0}},render(){return this.nodes}}),d=Z(null),f=Z(typeof window>"u"),h=Z(t.node.content),m=R(()=>Array.isArray(t.node.children)?t.node.children:[]),v=R(()=>String(t.node.tag||"div")),k=R(()=>{var I;if(v.value.trim().toLowerCase()!=="details"||(I=t.node.attrs)!=null&&I.some(([B])=>String(B).toLowerCase()==="open"))return null;const $=m.value[0];return $?.type==="html_block"&&String($.tag||"").toLowerCase()==="summary"?$:null}),w=R(()=>{var I;return kc((I=k.value)==null?void 0:I.children)}),b=R(()=>{const I=k.value;if(!I)return;const $=Xh(I.attrs,s.value,"summary");if(!$)return;const B=Zf($);return Object.keys(B).length>0?B:void 0}),_=R(()=>w.value==null?m.value:m.value.slice(1)),g=R(()=>{const I=v.value.trim().toLowerCase();return UI.has(I)||a5(I,s.value)}),x=R(()=>m.value.length>0&&!!t.node.tag&&!g.value),S=R(()=>{var I,$,B;if(x.value)return{mode:"structured"};if(!f.value)return{mode:"html",content:(I=h.value)!=null?I:""};const H=($=h.value)!=null?$:t.node.content;if(!H)return{mode:"html",content:""};if(s.value==="escape")return{mode:"html",content:jd(H,s.value)};if(t.node.loading){const F=cg(H,u.value,s.value);return F===null?{mode:"text",content:(B=t.node.raw)!=null?B:H}:{mode:"dynamic",nodes:F}}if(!h$(H,u.value))return{mode:"html",content:jd(H,s.value)};const O=cg(H,u.value,s.value);return O===null?{mode:"html",content:jd(H,s.value)}:{mode:"dynamic",nodes:O}}),T=g5(),A=h5(),E=m5(),P=Xr(null),D=!!t.node.loading;return typeof window<"u"?(Je([()=>d.value,()=>A?.value.heavyBlockMargin,()=>A?.value.rootMargin],([I],$,B)=>{var H,O,F,U;if((O=(H=P.value)==null?void 0:H.destroy)==null||O.call(H),P.value=null,!D)return f.value=!0,void(h.value=t.node.content);if(!I)return void(f.value=!1);let z=!0;const W=(U=(F=A?.value.heavyBlockMargin)!=null?F:A?.value.rootMargin)!=null?U:yc,K=T(I,{rootMargin:W,allowIdle:!E.value});P.value=K,f.value=f.value||K.isVisible.value,K.whenVisible.then(()=>{z&&P.value===K&&(f.value=!0)}),B(()=>{z=!1,K.destroy(),P.value===K&&(P.value=null)})},{immediate:!0}),Je(()=>t.node.content,I=>{D&&!f.value||(h.value=I)})):f.value=!0,Vn(()=>{var I,$;($=(I=P.value)==null?void 0:I.destroy)==null||$.call(I),P.value=null}),(I,$)=>(y(),he(bs(x.value?v.value:"div"),zn({ref_key:"htmlRef",ref:d,class:"html-block-node","data-markstream-viewport-pending":p(E)&&!f.value?"true":void 0},x.value?a.value:void 0),{default:me(()=>[f.value?(y(),M(Pe,{key:0},[S.value.mode==="structured"?(y(),M(Pe,{key:0},[w.value!==null?(y(),M(Pe,{key:0},[C("summary",xR(OA(b.value)),N(w.value),17),_.value.length?(y(),he(p(r),zn({key:0},i.value,{nodes:_.value,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes"])):ee("",!0)],64)):(y(),he(p(r),zn({key:1},i.value,{nodes:m.value,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes"]))],64)):S.value.mode==="dynamic"?(y(),he(p(c),{key:1,nodes:S.value.nodes},null,8,["nodes"])):S.value.mode==="text"?(y(),M("pre",T1e,N(S.value.content),1)):(y(),M("div",zn({key:3},l.value,{innerHTML:S.value.content}),null,16,E1e))],64)):(y(),M("div",I1e,[xn(I.$slots,"placeholder",{node:e.node},()=>[$[0]||($[0]=C("span",{class:"html-block-node__placeholder-bar"},null,-1)),$[1]||($[1]=C("span",{class:"html-block-node__placeholder-bar w-4/5"},null,-1)),$[2]||($[2]=C("span",{class:"html-block-node__placeholder-bar w-2/3"},null,-1))],!0)]))]),_:3},16,["data-markstream-viewport-pending"]))}}),[["__scopeId","data-v-e140a874"]]);Qf.install=e=>{e.component(Qf.__name,Qf)};const L1e={dir:"auto",class:"paragraph-node"},$1e=["custom-id"],cc=Gn(et({__name:"ParagraphNode",props:{node:{},customId:{},indexKey:{},customHtmlTags:{},parseOptions:{},customMarkdownIt:{type:Function}},setup(e){const t=e,n=fs(()=>t.customId),o=nn("markstreamHtmlPolicy",void 0),s=nn("markstreamFade",void 0),i=nn("markstreamParseOptions",void 0),r=nn("markstreamCustomMarkdownIt",void 0),l=nn("markstreamNestedRendererProps",void 0),a=R(()=>{var A;return(A=o?.value)!=null?A:"safe"}),u=R(()=>{var A;return(A=t.parseOptions)!=null?A:i?.value}),c=R(()=>{var A;return(A=t.customMarkdownIt)!=null?A:r?.value}),d=R(()=>{var A,E;return(E=t.customHtmlTags)!=null?E:(A=l?.value)==null?void 0:A.customHtmlTags}),f=R(()=>{var A,E;const P=(A=l?.value)!=null?A:{};return rn(mt({},P),{customId:(E=t.customId)!=null?E:P.customId,customHtmlTags:d.value,parseOptions:u.value,customMarkdownIt:c.value,htmlPolicy:a.value})}),h=zr({loader:()=>Promise.resolve().then(()=>M5),suspensible:!1});function m(A){var E;return A.type==="text"&&String((E=A.content)!=null?E:"").trim()===""}const v=R(()=>t.node.children.filter(A=>!m(A))),k=R(()=>v.value.length>0&&v.value.every(A=>A.type==="image"||(function(E){var P;const D=(function(I){return I.type==="link"&&Array.isArray(I.children)?I.children.filter($=>!m($)):[]})(E);return D.length===1&&((P=D[0])==null?void 0:P.type)==="image"})(A))),w=R(()=>new Set(Ec(d.value))),b=R(()=>{if(!k.value||v.value.length<=1)return t.node.children;const A=[];for(let E=0;E<t.node.children.length;E++){const P=t.node.children[E];if(!m(P)){A.push(P);continue}const D=A.length>0,I=t.node.children.slice(E+1).some($=>!m($));D&&I&&A.push(rn(mt({},P),{content:" ",raw:" "}))}return A}),_=R(()=>s?.value===!1&&!n.value.text),g=R(()=>_.value?kc(b.value):null);function x(A,E){return{node:A,"index-key":`${t.indexKey}-${E}`,"custom-id":t.customId,"custom-html-tags":d.value}}const S=R(()=>mt({inline_code:li,image:Va,link:Mi,hardbreak:qa,emphasis:Ti,strong:Si,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,html_inline:sr,html_block:Qf,emoji:zi,checkbox:nr,math_inline:Jr,checkbox_input:nr,reference:xi,footnote_anchor:Jf,footnote_reference:or,text:qo},n.value)),T=R(()=>b.value.map((A,E)=>{var P;const D=(function(I){var $,B,H,O;if(I.type==="html_block"||I.type==="html_inline"){const F=String(($=I.tag)!=null?$:"").trim().toLowerCase()||ZI(I.content);if(F&&!w.value.has(F)&&GI((B=I.content)!=null?B:I.raw,F)){const U=String((O=(H=I.content)!=null?H:I.raw)!=null?O:"");return{child:{type:"text",content:U,raw:U},component:qo,isCustomComponent:!1}}}return{child:I,component:S.value[I.type],isCustomComponent:!!(n.value[I.type]&&!Qp(String(I.type)))}})(A);return rn(mt({},D),{index:E,key:`${t.indexKey||"paragraph"}-${E}`,customAttrs:D.isCustomComponent?p5(D.child,a.value):void 0,hasSlotChildren:Array.isArray(D.child.children)&&D.child.children.length>0,slotContent:String((P=D.child.content)!=null?P:""),originalChild:A})}));return(A,E)=>(y(),M("p",L1e,[g.value!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(g.value),9,$1e)):(y(!0),M(Pe,{key:1},pt(T.value,P=>{return y(),M(Pe,{key:P.key},[k.value&&m(P.originalChild)?(y(),M(Pe,{key:0},[qe(N((D=P.originalChild,String((I=D.content)!=null?I:""))),1)],64)):P.isCustomComponent?(y(),he(bs(P.component),zn({key:1,ref_for:!0},P.customAttrs,{node:P.child,loading:P.child.loading,"index-key":P.key,"custom-id":t.customId,"custom-html-tags":d.value,"is-dark":f.value.isDark}),{default:me(()=>[P.hasSlotChildren?(y(),he(p(h),zn({key:0,ref_for:!0},f.value,{nodes:P.child.children,"index-key":P.key,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):P.slotContent?(y(),he(p(h),zn({key:1,ref_for:!0},f.value,{content:P.slotContent,final:!P.child.loading,"index-key":`${P.key}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):ee("",!0)]),_:2},1040,["node","loading","index-key","custom-id","custom-html-tags","is-dark"])):(y(),he(bs(P.component),zn({key:2,ref_for:!0},x(P.child,P.index)),null,16))],64);var D,I}),128))]))}}),[["__scopeId","data-v-c59ff506"]]);cc.install=e=>{e.component(cc.__name,cc)};const N1e={class:"table-node-wrapper"},F1e=["aria-busy"],R1e={key:0},O1e=["custom-id"],P1e=["aria-label","onPointerdown"],D1e=["custom-id"],B1e={key:0,class:"table-node__loading",role:"status","aria-live":"polite"},ep=Gn(et({__name:"TableNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{},showTooltips:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=R(()=>{var w;return(w=t.node.loading)!=null&&w}),o=R(()=>{var w;return(w=t.node.rows)!=null?w:[]}),s=Z(null),i=Z([]);let r=null;const l=R(()=>t.node.header.cells.length),a=R(()=>i.value.some(w=>Number.isFinite(w)&&w>0)),u=R(()=>a.value?i.value.map(w=>w>0?{width:`${w}px`}:void 0):[]);Ln("markstreamShowTooltips",R(()=>t.showTooltips)),Ln("markstreamFade",R(()=>t.fade));const c=fs(()=>t.customId),d=R(()=>!!c.value.text),f=R(()=>!!c.value.paragraph),h=new WeakMap;function m(w){const b=t.fade===!1&&!d.value,_=!f.value,g=h.get(w);if(g?.children===w.children&&g.textFastPath===b&&g.paragraphFastPath===_)return g.info;const x=fg(w.children,_,!0),S={simpleChildren:x,plainText:x&&b?kc(x):null};return h.set(w,{children:w.children,textFastPath:b,paragraphFastPath:_,info:S}),S}function v(w){if(!r)return;w.preventDefault();const b=r.startWidth+r.nextStartWidth,_=Math.min(48,Math.floor(b/2)),g=Math.max(_,Math.min(b-_,Math.round(r.startWidth+w.clientX-r.startX))),x=[...r.widths];x[r.index]=g,x[r.index+1]=b-g,i.value=x}function k(){r&&(window.removeEventListener("pointermove",v),window.removeEventListener("pointerup",k),window.removeEventListener("pointercancel",k),r=null)}return Je(l,()=>{k(),i.value=[]}),Vn(k),(w,b)=>(y(),M("div",N1e,[C("table",{ref_key:"tableRef",ref:s,class:Re(["table-node",{"table-node--loading":n.value}]),"aria-busy":n.value},[a.value?(y(),M("colgroup",R1e,[(y(!0),M(Pe,null,pt(e.node.header.cells,(_,g)=>(y(),M("col",{key:g,style:Zt(u.value[g])},null,4))),128))])):ee("",!0),C("thead",null,[C("tr",null,[(y(!0),M(Pe,null,pt(e.node.header.cells,(_,g)=>(y(),M("th",{key:g,dir:"auto",class:Re([_.align==="right"?"text-right":_.align==="center"?"text-center":"text-left"])},[m(_).plainText!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(m(_).plainText),9,O1e)):m(_).simpleChildren?(y(),he(p($p),{key:1,nodes:m(_).simpleChildren,"custom-id":t.customId,"index-key":`table-th-${t.indexKey}-${g}`},null,8,["nodes","custom-id","index-key"])):(y(),he(p(Vi),{key:2,nodes:_.children,"index-key":`table-th-${t.indexKey}`,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"show-tooltips":t.showTooltips,onCopy:b[0]||(b[0]=x=>w.$emit("copy",x))},null,8,["nodes","index-key","custom-id","typewriter","fade","show-tooltips"])),g<e.node.header.cells.length-1?(y(),M("button",{key:3,type:"button",class:"table-node__resize-handle","aria-label":`Resize columns ${g+1} and ${g+2}`,onPointerdown:x=>(function(S,T){if(T.button!==0)return;const A=(function(){var D;const I=(D=s.value)==null?void 0:D.querySelectorAll("thead th");return Array.from(I??[],$=>Math.round($.getBoundingClientRect().width))})(),E=A[S],P=A[S+1];E&&P&&(T.preventDefault(),r={index:S,startX:T.clientX,startWidth:E,nextStartWidth:P,widths:A},i.value=A,window.addEventListener("pointermove",v),window.addEventListener("pointerup",k),window.addEventListener("pointercancel",k))})(g,x)},null,40,P1e)):ee("",!0)],2))),128))])]),C("tbody",null,[(y(!0),M(Pe,null,pt(o.value,(_,g)=>(y(),M("tr",{key:g},[(y(!0),M(Pe,null,pt(_.cells,(x,S)=>(y(),M("td",{key:S,class:Re([x.align==="right"?"text-right":x.align==="center"?"text-center":"text-left"]),dir:"auto"},[m(x).plainText!==null?(y(),M("span",{key:0,class:"text-node","custom-id":t.customId},N(m(x).plainText),9,D1e)):m(x).simpleChildren?(y(),he(p($p),{key:1,nodes:m(x).simpleChildren,"custom-id":t.customId,"index-key":`table-td-${t.indexKey}-${g}-${S}`},null,8,["nodes","custom-id","index-key"])):(y(),he(p(Vi),{key:2,nodes:x.children,"index-key":`table-td-${t.indexKey}`,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"show-tooltips":t.showTooltips,onCopy:b[1]||(b[1]=T=>w.$emit("copy",T))},null,8,["nodes","index-key","custom-id","typewriter","fade","show-tooltips"]))],2))),128))]))),128))])],10,F1e),j(as,{name:"table-node-fade"},{default:me(()=>[n.value?(y(),M("div",B1e,[xn(w.$slots,"loading",{isLoading:n.value},()=>[b[2]||(b[2]=C("span",{class:"table-node__spinner animate-spin","aria-hidden":"true"},null,-1)),b[3]||(b[3]=C("span",{class:"sr-only"},"Loading",-1))],!0)])):ee("",!0)]),_:3})]))}}),[["__scopeId","data-v-39f87b5d"]]);ep.install=e=>{e.component(ep.__name,ep)};const H1e={class:"hr-node"},sm=Gn({},[["render",function(e,t){return y(),M("hr",H1e)}],["__scopeId","data-v-39b2349c"]]);sm.install=e=>{e.component(sm.__name,sm)};const z1e={class:"unknown-node"},l8=et({__name:"FallbackComponent",props:{node:{}},setup:e=>(t,n)=>(y(),M("div",z1e,N(e.node.raw),1))}),im=Gn(et({__name:"VmrContainerNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},setup(e){const t=e,n=R(()=>`vmr-container vmr-container-${t.node.name}`),o=fs(()=>t.customId),s=R(()=>mt({text:qo,paragraph:cc,heading:L2,inline_code:li,link:Mi,image:Va,strong:Si,emphasis:Ti,strikethrough:Ai,insert:ji,subscript:Ui,superscript:Wi,checkbox:nr,checkbox_input:nr,hardbreak:qa,math_inline:Jr,reference:xi,list:qd,math_block:C$,table:ep},o.value));return(i,r)=>(y(),M("div",zn({class:n.value},e.node.attrs),[(y(!0),M(Pe,null,pt(e.node.children,(l,a)=>{return y(),he(bs((u=l.type,s.value[u]||l8)),{key:`${e.indexKey||"vmr-container"}-${a}`,"custom-id":t.customId,node:l,"index-key":`${e.indexKey||"vmr-container"}-${a}`,typewriter:t.typewriter,fade:t.fade},null,8,["custom-id","node","index-key","typewriter","fade"]);var u}),128))],16))}}),[["__scopeId","data-v-911e41c4"]]);im.install=e=>{e.component(im.__name,im)};const W1e=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],R_=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function U1e(e){if(e<=255)return W1e[e];let t=0,n=R_.length-1;for(;t<=n;){const o=t+n>>1,s=R_[o];if(e<s[0])n=o-1;else{if(!(e>s[1]))return s[2];t=o+1}}return"L"}const j1e=/[ \t\n\r\f]+/g,V1e=/[\t\n\r\f]| {2,}|^ | $/;let J9=null;const q1e=new RegExp("\\p{Script=Arabic}","u"),ou=new RegExp("\\p{M}","u"),y5=new RegExp("\\p{Nd}","u");function O_(e){return q1e.test(e)}function P_(e){return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=183984&&e<=191471||e>=191472&&e<=192093||e>=194560&&e<=195103||e>=196608&&e<=201551||e>=201552&&e<=205743||e>=205744&&e<=210041||e>=63744&&e<=64255||e>=12288&&e<=12351||e>=12352&&e<=12447||e>=12448&&e<=12543||e>=12592&&e<=12687||e>=44032&&e<=55215||e>=65280&&e<=65519}function kl(e){for(let t=0;t<e.length;t++){const n=e.charCodeAt(t);if(!(n<12288)){if(n>=55296&&n<=56319&&t+1<e.length){const o=e.charCodeAt(t+1);if(o>=56320&&o<=57343){if(P_(o-56320+(n-55296<<10)+65536))return!0;t++;continue}}if(P_(n))return!0}}return!1}const K1e=new Set([" "," ","⁠","\uFEFF"]),Z1e=new Set(["-","‐","–","—"]);function w$(e,t){return!((function(n){const o=tp(n);return o!==null&&K1e.has(o)})(e)||t&&((function(n){const o=tp(n);return o!==null&&(k5.has(o)||bc.has(o))})(e)||(function(n){const o=tp(n);return o!==null&&Z1e.has(o)})(e)))}const k5=new Set([",",".","!",":",";","?","、","。","・",")","〕","〉","》","」","』","】","〗","〙","〛","ー","々","〻","ゝ","ゞ","ヽ","ヾ"]),$2=new Set(['"',"(","[","{","¡","¿","“","‘","‚","„","«","‹","⸘","(","〔","〈","《","「","『","【","〖","〘","〚"]),b5=new Set(["'","’"]),bc=new Set([".",",","!","?",":",";","،","؛","؟","।","॥","၊","။","၌","၍","၏",")","]","}","%",'"',"”","’","»","›","…"]),G1e=new Set([":",".","،","؛"]),Y1e=new Set(["၏"]),X1e=new Set(["”","’","»","›","」","』","】","》","〉","〕",")"]);function J1e(e){if(C5(e))return!0;let t=!1;for(const n of e)if(bc.has(n)||hg(n))t=!0;else if(!t||!ou.test(n))return!1;return t}function Q1e(e){for(const t of e)if(!k5.has(t)&&!bc.has(t))return!1;return e.length>0}function efe(e){if(C5(e))return!0;for(const t of e)if(!($2.has(t)||b5.has(t)||ou.test(t)||hg(t)))return!1;return e.length>0}function C5(e){let t=!1;for(const n of e)if(n!=="\\"&&!ou.test(n)){if(!($2.has(n)||bc.has(n)||b5.has(n)))return!1;t=!0}return t}function pg(e,t){const n=t-1;if(n<=0)return Math.max(n,0);const o=e.charCodeAt(n);if(o<56320||o>57343)return n;const s=n-1;if(s<0)return n;const i=e.charCodeAt(s);return i>=55296&&i<=56319?s:n}function tp(e){if(e.length===0)return null;const t=pg(e,e.length);return e.slice(t)}const tfe=[36,37,43,43,92,92,162,165,176,177,1423,1423,1545,1547,1642,1642,2046,2047,2546,2547,2553,2555,2801,2801,3065,3065,3449,3449,3647,3647,6107,6107,8240,8247,8279,8279,8352,8399,8451,8451,8457,8457,8470,8470,8722,8723,43064,43064,65020,65020,65129,65130,65284,65285,65504,65505,65509,65510,73693,73696,123647,123647,126124,126124,126128,126128];function hg(e){const t=e.codePointAt(0);return t!==void 0&&(function(n,o){for(let s=0;s<o.length;s+=2)if(n>=o[s]&&n<=o[s+1])return!0;return!1})(t,tfe)}function nfe(e){const t=(function(n){for(const o of n)if(!ou.test(o))return o;return null})(e);return t!==null&&y5.test(t)}function ofe(e){const t=Array.from(e);let n=t.length;for(;n>0;){const o=t[n-1];if(ou.test(o))n--;else{if(!$2.has(o)&&!b5.has(o))break;n--}}return n<=0||n===t.length?null:{head:t.slice(0,n).join(""),tail:t.slice(n).join("")}}function sfe(e,t,n){return n!=="text"||t||e.length!==1||e==="-"||e==="—"?null:e}function D_(e,t,n,o){const s=t[o],i=e[o];if(s==null)return i;const r=n[o];if(i.length===r)return i;const l=s.repeat(r);return e[o]=l,l}function B_(e,t){return e&&t!==null&&G1e.has(t)}function ife(e){const t=tp(e);return t!==null&&Y1e.has(t)}function rfe(e){if(e.length<2||e[0]!==" ")return null;const t=e.slice(1);return new RegExp("^\\p{M}+$","u").test(t)?{space:" ",marks:t}:null}function a8(e){let t=e.length;for(;t>0;){const n=pg(e,t),o=e.slice(n,t);if(X1e.has(o))return!0;if(!bc.has(o))return!1;t=n}return!1}function lfe(e,t){if(t.preserveOrdinarySpaces||t.preserveHardBreaks){if(e===" ")return"preserved-space";if(e===" ")return"tab";if(t.preserveHardBreaks&&e===` +`)return"hard-break"}return e===" "?"space":e===" "||e===" "||e==="⁠"||e==="\uFEFF"?"glue":e==="​"?"zero-width-break":e==="­"?"soft-hyphen":"text"}const afe=/[\x20\t\n\xA0\xAD\u200B\u202F\u2060\uFEFF]/;function Or(e){return e.length===1?e[0]:e.join("")}function ufe(e,t){const n=[];for(let o=e.length-1;o>=0;o--)n.push(e[o]);return n.push(t),Or(n)}function cfe(e,t,n,o){if(!afe.test(e))return[{text:e,isWordLike:t,kind:"text",start:n}];const s=[];let i=null,r=[],l=n,a=!1,u=0;for(const c of e){const d=lfe(c,o),f=d==="text"&&t;i===null||d!==i||f!==a?(i!==null&&s.push({text:Or(r),isWordLike:a,kind:i,start:l}),i=d,r=[c],l=n+u,a=f,u+=c.length):(r.push(c),u+=c.length)}return i!==null&&s.push({text:Or(r),isWordLike:a,kind:i,start:l}),s}function Q9(e){return e==="space"||e==="preserved-space"||e==="zero-width-break"||e==="hard-break"}const dfe=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function ffe(e,t){const n=e.texts[t];return!!n.startsWith("www.")||dfe.test(n)&&t+1<e.len&&e.kinds[t+1]==="text"&&e.texts[t+1]==="//"}function pfe(e){return e.includes("?")&&(e.includes("://")||e.startsWith("www."))}const hfe=new Set([":","-","/","×",",",".","+","–","—"]),mfe=/[\p{P}\p{S}\p{Co}]/u,gfe=new RegExp("\\p{Emoji_Presentation}","u"),vfe=new Set(["?","֊","-","‐","‒","–","—","…","‼","‽","⁉"]);function _$(e){const t=e.charCodeAt(0);return t<128?(function(n){return n>=33&&n<=47&&n!==45||n>=58&&n<=64&&n!==63||n>=91&&n<=96||n>=123&&n<=126})(t):!vfe.has(e)&&!gfe.test(e)&&mfe.test(e)}function H_(e){let t=!1;for(const n of e)if(!ou.test(n)){if(!_$(n))return!1;t=!0}return t}function yfe(e,t,n,o){const s=!t&&H_(e),i=!o&&H_(n),r=(function(a){const u=(function(c){for(let d=c.length;d>0;){const f=pg(c,d),h=c.slice(f,d);if(!ou.test(h))return h;d=f}return null})(a);return u!==null&&hg(u)})(e),l=(t||r)&&(function(a){for(let u=a.length;u>0;){const c=pg(a,u),d=a.slice(c,u);if(!ou.test(d))return _$(d)||hg(d);u=c}return!1})(e);return!!(s||i||l)&&!kl(e)&&!kl(n)&&(t||s||r)&&(o||i)}function z_(e){for(const t of e)if(y5.test(t))return!0;return!1}function rm(e){if(e.length===0)return!1;for(const t of e)if(!y5.test(t)&&!hfe.has(t))return!1;return!0}function kfe(e,t){if(e.len===0)return[];if(!t.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}];const n=[];let o=0;for(let s=0;s<e.len;s++)e.kinds[s]==="hard-break"&&(n.push({startSegmentIndex:o,endSegmentIndex:s,consumedEndSegmentIndex:s+1}),o=s+1);return o<e.len&&n.push({startSegmentIndex:o,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}),n}function bfe(e,t,n="normal",o="normal"){const s=(function(a){const u=a??"normal";return u==="pre-wrap"?{mode:u,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:u,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}})(n),i=s.mode==="pre-wrap"?(function(a){return/[\r\f]/.test(a)?a.replace(/\r\n/g,` +`).replace(/[\r\f]/g,` +`):a})(e):(function(a){if(!V1e.test(a))return a;let u=a.replace(j1e," ");return u.charCodeAt(0)===32&&(u=u.slice(1)),u.length>0&&u.charCodeAt(u.length-1)===32&&(u=u.slice(0,-1)),u})(e);if(i.length===0)return{normalized:i,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};const r=(function(a,u,c){var d,f,h;const m=(J9===null&&(J9=new Intl.Segmenter(void 0,{granularity:"word"})),J9);let v=0;const k=[],w=[],b=[],_=[],g=[],x=[],S=[],T=[],A=[],E=[],P=[],D=[];for(const O of m.segment(a))for(const F of cfe(O.segment,(d=O.isWordLike)!=null&&d,O.index,c)){let U=function(){x[le]!==null&&(w[le]=[D_(k,x,S,le)],x[le]=null),w[le].push(F.text),b[le]=b[le]||F.isWordLike,T[le]=T[le]||K,A[le]=A[le]||V,E[le]=ne,P[le]=X,D[le]=B_(A[le],ie)};const z=F.kind==="text",W=sfe(F.text,F.isWordLike,F.kind),K=kl(F.text),V=O_(F.text),ie=tp(F.text),ne=a8(F.text),X=ife(F.text),le=v-1;u.carryCJKAfterClosingQuote&&z&&v>0&&_[le]==="text"&&K&&T[le]&&E[le]||z&&v>0&&_[le]==="text"&&Q1e(F.text)&&T[le]||z&&v>0&&_[le]==="text"&&P[le]?U():z&&v>0&&_[le]==="text"&&F.isWordLike&&V&&D[le]?(U(),b[le]=!0):W!==null&&v>0&&_[le]==="text"&&x[le]===W?S[le]=((f=S[le])!=null?f:1)+1:z&&!F.isWordLike&&v>0&&_[le]==="text"&&!T[le]&&(J1e(F.text)||F.text==="-"&&b[le])?U():(k[v]=F.text,w[v]=[F.text],b[v]=F.isWordLike,_[v]=F.kind,g[v]=F.start,x[v]=W,S[v]=W===null?0:1,T[v]=K,A[v]=V,E[v]=ne,P[v]=X,D[v]=B_(V,ie),v++)}for(let O=0;O<v;O++)x[O]===null?k[O]=Or(w[O]):k[O]=D_(k,x,S,O);for(let O=1;O<v;O++)_[O]!=="text"||b[O]||!C5(k[O])||_[O-1]!=="text"||T[O-1]||(k[O-1]+=k[O],b[O-1]=b[O-1]||b[O],k[O]="");const I=Array.from({length:v},()=>null);let $=-1;for(let O=v-1;O>=0;O--){const F=k[O];if(F.length!==0){if(_[O]==="text"&&!b[O]&&$>=0&&_[$]==="text"&&(efe(F)||F==="-"&&nfe(k[$]))){const U=(h=I[$])!=null?h:[];U.push(F),I[$]=U,g[$]=g[O],k[O]="";continue}$=O}}for(let O=0;O<v;O++){const F=I[O];F!=null&&(k[O]=ufe(F,k[O]))}let B=0;for(let O=0;O<v;O++){const F=k[O];F.length!==0&&(B!==O&&(k[B]=F,b[B]=b[O],_[B]=_[O],g[B]=g[O]),B++)}k.length=B,b.length=B,_.length=B,g.length=B;const H=(function(O){const F=O.texts.slice(),U=O.isWordLike.slice(),z=O.kinds.slice(),W=O.starts.slice();for(let K=0;K<F.length-1;K++){if(z[K]!=="text"||z[K+1]!=="text"||!kl(F[K])||!kl(F[K+1]))continue;const V=ofe(F[K]);V!==null&&(F[K]=V.head,F[K+1]=V.tail+F[K+1],W[K+1]=W[K]+V.head.length)}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=[],U=[],z=[],W=[];let K=0;for(;K<O.len;){const V=O.texts[K],ie=O.kinds[K],ne=O.isWordLike[K];if(ie==="text"){const X=[V];let le=K+1,Ie=ne;for(;le<O.len&&O.kinds[le]==="text"&&yfe(O.texts[le-1],O.isWordLike[le-1],O.texts[le],O.isWordLike[le]);){const de=O.texts[le];X.push(de),Ie=Ie||O.isWordLike[le],le++}if(le>K+1){F.push(Or(X)),U.push(Ie),z.push("text"),W.push(O.starts[K]),K=le;continue}}F.push(V),U.push(ne),z.push(ie),W.push(O.starts[K]),K++}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=[],U=[],z=[],W=[];for(let K=0;K<O.len;K++){const V=O.texts[K];if(O.kinds[K]==="text"&&V.includes("-")){const ie=V.split("-");let ne=ie.length>1;for(let X=0;X<ie.length;X++){const le=ie[X];if(!ne)break;le.length!==0&&z_(le)&&rm(le)||(ne=!1)}if(ne){let X=0;for(let le=0;le<ie.length;le++){const Ie=ie[le],de=le<ie.length-1?`${Ie}-`:Ie;F.push(de),U.push(!0),z.push("text"),W.push(O.starts[K]+X),X+=de.length}continue}}F.push(V),U.push(O.isWordLike[K]),z.push(O.kinds[K]),W.push(O.starts[K])}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=[],U=[],z=[],W=[];for(let K=0;K<O.len;K++){const V=O.texts[K],ie=O.kinds[K];if(ie==="text"&&rm(V)&&z_(V)){const ne=[V];let X=K+1;for(;X<O.len&&O.kinds[X]==="text"&&rm(O.texts[X]);)ne.push(O.texts[X]),X++;F.push(Or(ne)),U.push(!0),z.push("text"),W.push(O.starts[K]),K=X-1;continue}F.push(V),U.push(O.isWordLike[K]),z.push(ie),W.push(O.starts[K])}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=[],U=[],z=[],W=[];for(let K=0;K<O.len;K++){const V=O.texts[K];if(F.push(V),U.push(O.isWordLike[K]),z.push(O.kinds[K]),W.push(O.starts[K]),!pfe(V))continue;const ie=K+1;if(ie>=O.len||Q9(O.kinds[ie]))continue;const ne=[],X=O.starts[ie];let le=ie;for(;le<O.len&&!Q9(O.kinds[le]);)ne.push(O.texts[le]),le++;ne.length>0&&(F.push(Or(ne)),U.push(!0),z.push("text"),W.push(X),K=le-1)}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=O.texts.slice(),U=O.isWordLike.slice(),z=O.kinds.slice(),W=O.starts.slice();for(let V=0;V<O.len;V++){if(z[V]!=="text"||!ffe(O,V))continue;const ie=[F[V]];let ne=V+1;for(;ne<O.len&&!Q9(z[ne]);){ie.push(F[ne]),U[V]=!0;const X=F[ne].includes("?");if(z[ne]="text",F[ne]="",ne++,X)break}F[V]=Or(ie)}let K=0;for(let V=0;V<F.length;V++){const ie=F[V];ie.length!==0&&(K!==V&&(F[K]=ie,U[K]=U[V],z[K]=z[V],W[K]=W[V]),K++)}return F.length=K,U.length=K,z.length=K,W.length=K,{len:K,texts:F,isWordLike:U,kinds:z,starts:W}})((function(O){const F=[],U=[],z=[],W=[];let K=0;for(;K<O.len;){const V=[O.texts[K]];let ie=O.isWordLike[K],ne=O.kinds[K],X=O.starts[K];if(ne==="glue"){const le=[V[0]],Ie=X;for(K++;K<O.len&&O.kinds[K]==="glue";)le.push(O.texts[K]),K++;const de=Or(le);if(!(K<O.len&&O.kinds[K]==="text")){F.push(de),U.push(!1),z.push("glue"),W.push(Ie);continue}V[0]=de,V.push(O.texts[K]),ie=O.isWordLike[K],ne="text",X=Ie,K++}else K++;if(ne==="text")for(;K<O.len&&O.kinds[K]==="glue";){const le=[];for(;K<O.len&&O.kinds[K]==="glue";)le.push(O.texts[K]),K++;const Ie=Or(le);K<O.len&&O.kinds[K]==="text"?(V.push(Ie,O.texts[K]),ie=ie||O.isWordLike[K],K++):V.push(Ie)}F.push(Or(V)),U.push(ie),z.push(ne),W.push(X)}return{len:F.length,texts:F,isWordLike:U,kinds:z,starts:W}})({len:B,texts:k,isWordLike:b,kinds:_,starts:g})))))));for(let O=0;O<H.len-1;O++){const F=rfe(H.texts[O]);F!==null&&(H.kinds[O]!=="space"&&H.kinds[O]!=="preserved-space"||H.kinds[O+1]!=="text"||!O_(H.texts[O+1])||(H.texts[O]=F.space,H.isWordLike[O]=!1,H.kinds[O]=H.kinds[O]==="preserved-space"?"preserved-space":"space",H.texts[O+1]=F.marks+H.texts[O+1],H.starts[O+1]=H.starts[O]+F.space.length))}return H})(i,t,s),l=o==="keep-all"?(function(a,u,c){if(u.len<=1)return u;const d=[],f=[],h=[],m=[];let v=-1,k=!1;function w(_){d.push(u.texts[_]),f.push(u.isWordLike[_]),h.push("text"),m.push(u.starts[_])}function b(_){if(!(v<0)){if(k)v+1===_?w(v):(function(g,x){let S=!1;for(let E=g;E<x;E++)S=S||u.isWordLike[E];const T=u.starts[g],A=x<u.len?u.starts[x]:a.length;d.push(a.slice(T,A)),f.push(S),h.push("text"),m.push(T)})(v,_);else for(let g=v;g<_;g++)w(g);v=-1,k=!1}}for(let _=0;_<u.len;_++){const g=u.texts[_],x=u.kinds[_];x!=="text"?(b(_),d.push(g),f.push(u.isWordLike[_]),h.push(x),m.push(u.starts[_])):(v>=0&&!w$(u.texts[_-1],c)&&b(_),v<0&&(v=_),k=k||kl(g))}return b(u.len),{len:d.length,texts:d,isWordLike:f,kinds:h,starts:m}})(i,r,t.breakKeepAllAfterPunctuation):r;return mt({normalized:i,chunks:kfe(l,s)},l)}let ld=null;const W_=new Map;let ad=null;const Cfe=new RegExp("\\p{Emoji_Presentation}","u"),wfe=/[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}\uFE0F\u20E3]/u;let e4=null;const U_=new Map;function u8(){if(ld!==null)return ld;if(typeof OffscreenCanvas<"u")return ld=new OffscreenCanvas(1,1).getContext("2d"),ld;if(typeof document<"u")return ld=document.createElement("canvas").getContext("2d"),ld;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function Sa(e,t){let n=t.get(e);return n===void 0&&(n={width:u8().measureText(e).width,containsCJK:kl(e)},t.set(e,n)),n}function mg(){if(ad!==null)return ad;if(typeof navigator>"u")return ad={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,breakKeepAllAfterPunctuation:!0,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},ad;const e=navigator.userAgent,t=navigator.vendor==="Apple Computer, Inc."&&e.includes("Safari/")&&!e.includes("Chrome/")&&!e.includes("Chromium/")&&!e.includes("CriOS/")&&!e.includes("FxiOS/")&&!e.includes("EdgiOS/"),n=e.includes("Chrome/")||e.includes("Chromium/")||e.includes("CriOS/")||e.includes("Edg/");return ad={lineFitEpsilon:t?1/64:.005,carryCJKAfterClosingQuote:n,breakKeepAllAfterPunctuation:!t,preferPrefixWidthsForBreakableRuns:t,preferEarlySoftHyphenBreak:t},ad}function x$(){return e4===null&&(e4=new Intl.Segmenter(void 0,{granularity:"grapheme"})),e4}function _fe(e){return Cfe.test(e)||e.includes("️")}function Ou(e,t,n){return n===0?t.width:t.width-(function(o,s){return s.emojiCount===void 0&&(s.emojiCount=(function(i){let r=0;const l=x$();for(const a of l.segment(i))_fe(a.segment)&&r++;return r})(o)),s.emojiCount})(e,t)*n}function xfe(e){return e==="space"||e==="zero-width-break"||e==="soft-hyphen"}function j_(e){return e==="space"||e==="preserved-space"||e==="tab"||e==="zero-width-break"||e==="soft-hyphen"}function V_(e,t,n=e.widths.length){for(;t<n&&xfe(e.kinds[t]);)t++;return t}function Sfe(e,t){if(t<=0)return 0;const n=e%t;return Math.abs(n)<=1e-6?t:t-n}function Afe(e,t,n){return e.letterSpacing!==0&&t&&e.spacingGraphemeCounts[n]>0?e.letterSpacing:0}function w5(e,t){return t===0?0:e+t}function Mfe(e,t,n,o,s){return w5(o,t==="tab"?s+(function(i,r){return i.letterSpacing!==0&&i.spacingGraphemeCounts[r]>0?i.letterSpacing:0})(e,n):e.lineEndFitAdvances[n])}function q_(e,t,n,o){return w5(o,t==="tab"?0:e.lineEndFitAdvances[n])}function K_(e,t,n,o,s){return w5(o,t==="tab"?s:e.lineEndPaintAdvances[n])}function Tfe(e,t,n){return e.letterSpacing!==0&&t?n+e.letterSpacing:n}function Efe(e,t){return e.letterSpacing===0?t:t+e.letterSpacing}function wh(e,t,n){let o=t;for(;o<e.length&&e[o]<n;)o++;return o}function Ife(e,t){return(function(n,o){if(n.simpleLineWalkFastPath)return(function(I,$){const{widths:B,kinds:H,breakableFitAdvances:O,breakablePreferredBreaks:F}=I;if(B.length===0)return 0;const U=$+mg().lineFitEpsilon;let z=0,W=0,K=!1,V=0,ie=0,ne=-1,X=0;function le(ye=V,G=ie,Y=W){z++,W=0,K=!1,ne=-1,X=0}function Ie(ye,G){K=!0,V=ye+1,ie=0,W=G}function de(ye,G,Y){K=!0,V=ye,ie=G+1,W=Y}function pe(ye,G){K?(W+=G,V=ye+1,ie=0):Ie(ye,G)}function ve(ye,G){var Y;const fe=O[ye],we=(Y=F[ye])!=null?Y:null;let ge=we===null?-1:wh(we,0,G+1),Q=-1,te=0,ce=G;for(;ce<fe.length;){const ue=fe[ce];if(K)if(W+ue>U){if(we!==null&&Q>G){le(ye,Q,te),ce=Q,ge=wh(we,ge,ce+1),Q=-1,te=0;continue}le(),de(ye,ce,ue)}else W+=ue,V=ye,ie=ce+1;else de(ye,ce,ue);const Se=ce+1;we!==null&&we[ge]===Se&&(Q=Se,te=W,ge++),ce++}K&&V===ye&&ie===fe.length&&(V=ye+1,ie=0)}let oe=0;for(;oe<B.length&&(K||(oe=V_(I,oe),!(oe>=B.length)));){const ye=B[oe],G=j_(H[oe]);if(K)if(W+ye>U){if(G){pe(oe,ye),le(oe+1,0,W-ye),oe++;continue}if(ne>=0){if(V>ne||V===ne&&ie>0){le();continue}le(ne,0,X);continue}if(ye>U&&O[oe]!==null){le(),ve(oe,0),oe++;continue}le()}else pe(oe,ye),G&&(ne=oe+1,X=W-ye),oe++;else ye>U&&O[oe]!==null?ve(oe,0):Ie(oe,ye),G&&(ne=oe+1,X=W-ye),oe++}return K&&le(),z})(n,o);const{widths:s,kinds:i,breakableFitAdvances:r,breakablePreferredBreaks:l,discretionaryHyphenWidth:a,chunks:u}=n;if(s.length===0||u.length===0)return 0;const c=mg(),d=o+c.lineFitEpsilon;let f=0,h=0,m=!1,v=0,k=0,w=-1,b=0,_=null;function g(){w=-1,b=0,_=null}function x(I=v,$=k,B){f++,h=0,m=!1,g()}function S(I,$){m=!0,v=I+1,k=0,h=$}function T(I,$,B){m=!0,v=I,k=$+1,h=B}function A(I,$){m?(h+=$,v=I+1,k=0):S(I,$)}function E(I,$,B,H,O,F){if(!$)return;const U=q_(n,I,B,O);K_(n,I,B,O,H),w=B+1,b=h-F+U,_=I}function P(I,$){var B;const H=r[I],O=(B=l[I])!=null?B:null;let F=O===null?-1:wh(O,0,$+1),U=-1,z=$;for(;z<H.length;){const W=H[z];if(m){const V=Tfe(n,!0,W),ie=h+V;if(Efe(n,ie)>d){if(O!==null&&U>$){x(I,U),z=U,F=wh(O,F,z+1),U=-1;continue}x(),T(I,z,W)}else h=ie,v=I,k=z+1}else T(I,z,W);const K=z+1;O!==null&&O[F]===K&&(U=K,F++),z++}m&&v===I&&k===H.length&&(v=I+1,k=0)}function D(I){f++,g()}for(let I=0;I<u.length;I++){const $=u[I];if($.startSegmentIndex===$.endSegmentIndex){D();continue}m=!1,h=0,$.startSegmentIndex,v=$.startSegmentIndex,k=0,g();let B=$.startSegmentIndex;for(;B<$.endSegmentIndex&&(m||(B=V_(n,B,$.endSegmentIndex),!(B>=$.endSegmentIndex)));){const H=i[B],O=j_(H),F=Afe(n,m,B),U=H==="tab"?Sfe(h+F,n.tabStopAdvance):s[B],z=F+U,W=Mfe(n,H,B,F,U);if(H!=="soft-hyphen")if(m){if(h+W>d){const K=h+q_(n,H,B,F);if(K_(n,H,B,F,U),_==="soft-hyphen"&&c.preferEarlySoftHyphenBreak&&b<=d){x(w,0);continue}if(O&&K<=d){A(B,z),x(B+1,0),B++;continue}if(w>=0&&b<=d){if(v>w||v===w&&k>0){x();continue}const V=w;x(V,0),B=V;continue}if(W>d&&r[B]!==null){x(),P(B,0),B++;continue}x();continue}A(B,z),E(H,O,B,U,F,z),B++}else W>d&&r[B]!==null?P(B,0):S(B,U),E(H,O,B,U,F,z),B++;else m&&(v=B+1,k=0,w=B+1,b=h+a,_=H),B++}m&&($.consumedEndSegmentIndex,x($.consumedEndSegmentIndex,0))}return f})(e,t)}let t4=null;function _5(){return t4===null&&(t4=new Intl.Segmenter(void 0,{granularity:"grapheme"})),t4}function Lfe(e,t){const n=[];let o=[],s=0,i=!1,r=!1,l=!1;function a(){o.length!==0&&(n.push({text:o.length===1?o[0]:o.join(""),start:s}),o=[],i=!1,r=!1,l=!1)}function u(d,f,h){o=[d],s=f,i=h,r=a8(d),l=$2.has(d)}function c(d,f){o.push(d),i=i||f;const h=a8(d);r=d.length===1&&bc.has(d)&&r||h,l=!1}for(const d of _5().segment(e)){const f=d.segment,h=kl(f);o.length!==0?l||k5.has(f)||bc.has(f)||t.carryCJKAfterClosingQuote&&h&&r?c(f,h):i||h?(a(),u(f,d.index,h)):c(f,h):u(f,d.index,h)}return a(),n}function $fe(e,t,n){if(t.length<=1)return t;const o=[];let s=-1,i=!1;function r(l){if(!(s<0)){if(i)s+1===l?o.push(t[s]):(function(a,u){const c=t[a].start,d=u<t.length?t[u].start:e.length;o.push({text:e.slice(c,d),start:c})})(s,l);else for(let a=s;a<l;a++)o.push(t[a]);s=-1,i=!1}}for(let l=0;l<t.length;l++){const a=t[l];s>=0&&!w$(t[l-1].text,n)&&r(l),s<0&&(s=l),i=i||kl(a.text)}return r(t.length),o}function Z_(e,t){if(t==="zero-width-break"||t==="soft-hyphen"||t==="hard-break")return 0;if(t==="tab")return 1;let n=0;const o=_5();for(const s of o.segment(e))n++;return n}function Nfe(e){return e==="-"||e==="֊"||e==="‐"||e==="‒"||e==="–"||e==="—"}function Ffe(e,t,n,o,s){const i=mg(),{cache:r,emojiCorrection:l}=(function(D,I){u8().font=D;const $=(function(O){let F=W_.get(O);return F||(F=new Map,W_.set(O,F)),F})(D),B=(function(O){const F=O.match(/(\d+(?:\.\d+)?)\s*px/);return F?parseFloat(F[1]):16})(D),H=I?(function(O,F){let U=U_.get(O);if(U!==void 0)return U;const z=u8();z.font=O;const W=z.measureText("😀").width;if(U=0,W>F+.5&&typeof document<"u"&&document.body!==null){const K=document.createElement("span");K.style.font=O,K.style.display="inline-block",K.style.visibility="hidden",K.style.position="absolute",K.textContent="😀",document.body.appendChild(K);const V=K.getBoundingClientRect().width;document.body.removeChild(K),W-V>.5&&(U=W-V)}return U_.set(O,U),U})(D,B):0;return{cache:$,fontSize:B,emojiCorrection:H}})(t,(a=e.normalized,wfe.test(a)));var a;const u=Ou("-",Sa("-",r),l)+(s===0?0:2*s),c=8*Ou(" ",Sa(" ",r),l),d=s!==0;if(e.len===0)return{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],breakablePreferredBreaks:[],letterSpacing:0,spacingGraphemeCounts:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[]};const f=[],h=[],m=[],v=[];let k=e.chunks.length<=1&&!d;const w=null,b=[],_=[],g=[],x=null,S=Array.from({length:e.len});function T(D,I,$,B,H,O,F,U,z){H!=="text"&&H!=="space"&&H!=="zero-width-break"&&(k=!1),f.push(I),h.push($),m.push(B),v.push(H),b.push(F),_.push(U),d&&g.push(z)}function A(D,I,$,B,H){const O=Sa(D,r),F=d?Z_(D,I):0,U=(function(V,ie,ne){return ie>1?V+(ie-1)*ne:V})(Ou(D,O,l),F,s),z=I==="space"||I==="preserved-space"||I==="zero-width-break"?0:U,W=z===0?0:z+(F>0?s:0),K=I==="space"||I==="zero-width-break"?0:U;if(H&&B&&D.length>1){let V="sum-graphemes";s!==0?V="segment-prefixes":rm(D)?V="pair-context":i.preferPrefixWidthsForBreakableRuns&&(V="segment-prefixes");const ie=(function(X,le,Ie,de,pe){if(le.breakableFitAdvances!==void 0&&le.breakableFitMode===pe)return le.breakableFitAdvances;le.breakableFitMode=pe;const ve=x$(),oe=[];for(const fe of ve.segment(X))oe.push(fe.segment);if(oe.length<=1)return le.breakableFitAdvances=null,le.breakableFitAdvances;if(pe==="sum-graphemes"){const fe=[];for(const we of oe){const ge=Sa(we,Ie);fe.push(Ou(we,ge,de))}return le.breakableFitAdvances=fe,le.breakableFitAdvances}if(pe==="pair-context"||oe.length>96){const fe=[];let we=null,ge=0;for(const Q of oe){const te=Ou(Q,Sa(Q,Ie),de);if(we===null)fe.push(te);else{const ce=we+Q,ue=Sa(ce,Ie);fe.push(Ou(ce,ue,de)-ge)}we=Q,ge=te}return le.breakableFitAdvances=fe,le.breakableFitAdvances}const ye=[];let G="",Y=0;for(const fe of oe){G+=fe;const we=Ou(G,Sa(G,Ie),de);ye.push(we-Y),Y=we}return le.breakableFitAdvances=ye,le.breakableFitAdvances})(D,O,r,l,V),ne=ie===null||o==="keep-all"?null:(function(X){if(!/[-\u058A\u2010\u2012\u2013\u2014]/u.test(X))return null;const le=[];let Ie=0;for(const de of _5().segment(X))Ie++,Nfe(de.segment)&&le.push(Ie);return le.length===0?null:le})(D);return void T(D,U,W,K,I,$,ie,ne,F)}T(D,U,W,K,I,$,null,null,F)}for(let D=0;D<e.len;D++){S[D]=f.length;const I=e.texts[D],$=e.isWordLike[D],B=e.kinds[D],H=e.starts[D];if(B==="soft-hyphen"){T(I,0,u,u,B,H,null,null,0);continue}if(B==="hard-break"){T(I,0,0,0,B,H,null,null,0);continue}if(B==="tab"){T(I,0,0,0,B,H,null,null,d?Z_(I,B):0);continue}const O=Sa(I,r);if(B==="text"&&O.containsCJK){const F=Lfe(I,i),U=o==="keep-all"?$fe(I,F,i.breakKeepAllAfterPunctuation):F;for(let z=0;z<U.length;z++){const W=U[z];A(W.text,"text",H+W.start,$,o==="keep-all"||!kl(W.text))}continue}A(I,B,H,$,!0)}const E=(function(D,I,$){const B=[];for(let H=0;H<D.length;H++){const O=D[H],F=O.startSegmentIndex<I.length?I[O.startSegmentIndex]:$,U=O.endSegmentIndex<I.length?I[O.endSegmentIndex]:$,z=O.consumedEndSegmentIndex<I.length?I[O.consumedEndSegmentIndex]:$;B.push({startSegmentIndex:F,endSegmentIndex:U,consumedEndSegmentIndex:z})}return B})(e.chunks,S,f.length),P=w===null?null:(function(D,I){const $=(function(H){const O=H.length;if(O===0)return null;const F=new Array(O);let U=!1;for(let ne=0;ne<O;){const X=H.charCodeAt(ne);let le=X,Ie=1;if(X>=55296&&X<=56319&&ne+1<O){const pe=H.charCodeAt(ne+1);pe>=56320&&pe<=57343&&(le=pe-56320+(X-55296<<10)+65536,Ie=2)}const de=U1e(le);de!=="R"&&de!=="AL"&&de!=="AN"||(U=!0);for(let pe=0;pe<Ie;pe++)F[ne+pe]=de;ne+=Ie}if(!U)return null;let z=0;for(let ne=0;ne<O;ne++){const X=F[ne];if(X==="L"){z=0;break}if(X==="R"||X==="AL"){z=1;break}}const W=new Int8Array(O);for(let ne=0;ne<O;ne++)W[ne]=z;const K=1&z?"R":"L",V=K;let ie=V;for(let ne=0;ne<O;ne++)F[ne]==="NSM"?F[ne]=ie:ie=F[ne];ie=V;for(let ne=0;ne<O;ne++){const X=F[ne];X==="EN"?F[ne]=ie==="AL"?"AN":"EN":X!=="R"&&X!=="L"&&X!=="AL"||(ie=X)}for(let ne=0;ne<O;ne++)F[ne]==="AL"&&(F[ne]="R");for(let ne=1;ne<O-1;ne++)F[ne]==="ES"&&F[ne-1]==="EN"&&F[ne+1]==="EN"&&(F[ne]="EN"),F[ne]!=="CS"||F[ne-1]!=="EN"&&F[ne-1]!=="AN"||F[ne+1]!==F[ne-1]||(F[ne]=F[ne-1]);for(let ne=0;ne<O;ne++){if(F[ne]!=="EN")continue;let X;for(X=ne-1;X>=0&&F[X]==="ET";X--)F[X]="EN";for(X=ne+1;X<O&&F[X]==="ET";X++)F[X]="EN"}for(let ne=0;ne<O;ne++){const X=F[ne];X!=="WS"&&X!=="ES"&&X!=="ET"&&X!=="CS"||(F[ne]="ON")}ie=V;for(let ne=0;ne<O;ne++){const X=F[ne];X==="EN"?F[ne]=ie==="L"?"L":"EN":X!=="R"&&X!=="L"||(ie=X)}for(let ne=0;ne<O;ne++){if(F[ne]!=="ON")continue;let X=ne+1;for(;X<O&&F[X]==="ON";)X++;const le=(ne>0?F[ne-1]:V)!=="L"?"R":"L";if(le===((X<O?F[X]:V)!=="L"?"R":"L"))for(let Ie=ne;Ie<X;Ie++)F[Ie]=le;ne=X-1}for(let ne=0;ne<O;ne++)F[ne]==="ON"&&(F[ne]=K);for(let ne=0;ne<O;ne++){const X=F[ne];1&W[ne]?X!=="L"&&X!=="AN"&&X!=="EN"||W[ne]++:X==="R"?W[ne]++:X!=="AN"&&X!=="EN"||(W[ne]+=2)}return W})(D);if($===null)return null;const B=new Int8Array(I.length);for(let H=0;H<I.length;H++)B[H]=$[I[H]];return B})(e.normalized,w);return x!==null?{widths:f,lineEndFitAdvances:h,lineEndPaintAdvances:m,kinds:v,simpleLineWalkFastPath:k,segLevels:P,breakableFitAdvances:b,breakablePreferredBreaks:_,letterSpacing:s,spacingGraphemeCounts:g,discretionaryHyphenWidth:u,tabStopAdvance:c,chunks:E,segments:x}:{widths:f,lineEndFitAdvances:h,lineEndPaintAdvances:m,kinds:v,simpleLineWalkFastPath:k,segLevels:P,breakableFitAdvances:b,breakablePreferredBreaks:_,letterSpacing:s,spacingGraphemeCounts:g,discretionaryHyphenWidth:u,tabStopAdvance:c,chunks:E}}const n4="__MARKSTREAM_VUE_HEIGHT_ESTIMATION_EXPERIMENT__",Rfe=["diff ","index ","--- ","+++ ","@@ "],ys=(()=>{const e=globalThis;if(e[n4])return e[n4];const t={configs:{},controllers:{},revision:Xr(0),preparedCache:new Map,blockEstimateCache:new Map};return e[n4]=t,t})();let lf=null;const o4=ys.revision;function G_(e){var t;return e&&(t=ys.configs[e])!=null?t:null}function Y_(e,t){const n=Number.parseFloat(String(e??""));return Number.isFinite(n)&&n>0?n:t}function Ofe(e){return e?.type==="text"||e?.type==="emoji"||e?.type==="hardbreak"}function s4(e){var t,n,o;if(!Array.isArray(e)||e.length===0)return null;let s="";for(const i of e){if(!Ofe(i))return null;i.type==="text"?s+=String((t=i.content)!=null?t:""):i.type==="emoji"?s+=String((o=(n=i.name)!=null?n:i.raw)!=null?o:""):i.type==="hardbreak"&&(s+=` +`)}return s.length>0?s:null}function i4(e,t,n){var o,s;if(!e||!Number.isFinite(t)||t<=0||!(function(){var i;if(lf!=null)return lf;if(typeof document>"u")return!1;try{const r=document.createElement("canvas");return lf=!!((i=r.getContext)!=null&&i.call(r,"2d")),lf}catch{return lf=!1,!1}})())return null;try{const i=Math.round(100*t)/100,r=[(o=n.whiteSpace)!=null?o:"pre-wrap",n.font,n.lineHeight,n.wrapperOverhead,n.widthAdjustment,i,e].join("\0"),l=ys.blockEstimateCache.get(r);if(l)return ys.blockEstimateCache.delete(r),ys.blockEstimateCache.set(r,l),{kind:"simple-text",height:l.height,contentHeight:l.contentHeight};const a=(s=n.whiteSpace)!=null?s:"pre-wrap",u=(function(h,m,v){const k=`${v}\0${m}\0${h}`,w=ys.preparedCache.get(k);if(w)return ys.preparedCache.delete(k),ys.preparedCache.set(k,w),w.prepared;const b=(function(_,g,x){return(function(S,T,A,E){var P,D;const I=(P=E?.wordBreak)!=null?P:"normal",$=(D=E?.letterSpacing)!=null?D:0;return Ffe(bfe(S,mg(),E?.whiteSpace,I),T,!1,I,$)})(_,g,0,x)})(h,m,{whiteSpace:v});for(ys.preparedCache.set(k,{prepared:b});ys.preparedCache.size>240;){const _=ys.preparedCache.keys().next().value;if(!_)break;ys.preparedCache.delete(_)}return b})(e,n.font,a),c=(function(h,m,v){const k=Ife(h,m);return{lineCount:k,height:k*v}})(u,Math.max(24,i-n.widthAdjustment),n.lineHeight),d=Math.max(n.lineHeight,c.height),f=Math.max(n.lineHeight,Math.round(d+n.wrapperOverhead));for(ys.blockEstimateCache.set(r,{height:f,contentHeight:Math.round(d)});ys.blockEstimateCache.size>4e3;){const h=ys.blockEstimateCache.keys().next().value;if(!h)break;ys.blockEstimateCache.delete(h)}return{kind:"simple-text",height:f,contentHeight:Math.round(d)}}catch{return null}}function S$(e,t,n){var o,s;if(!n||!e||!Number.isFinite(t)||t<=0)return null;if(e.type==="paragraph"){const i=s4(e.children);return i&&n.paragraph?i4(i,t,n.paragraph):null}if(e.type==="heading"){const i=Number(e.level||0),r=s4(e.children),l=n.headings[i];return r&&l?i4(r,t,l):null}if(e.type==="list_item"){const i=Array.isArray(e.children)?e.children:[];if(i.length!==1||((o=i[0])==null?void 0:o.type)!=="paragraph"||!n.listItem)return null;const r=s4((s=i[0])==null?void 0:s.children);return r?i4(r,t,n.listItem):null}if(e.type==="list"){const i=Array.isArray(e.items)?e.items:[];if(!i.length)return null;let r=Math.max(0,n.listWrapperOverhead);for(const l of i){const a=S$(l,t,n);if(!a)return null;r+=a.height}return{kind:"simple-text",height:Math.max(1,Math.round(r)),contentHeight:Math.max(1,Math.round(r))}}return null}function af(e){if(!e)return 1;const t=String(e).split(/\r?\n/);return Math.max(1,t.length)}function Pu(e,t){const n=String(e??"");return t?n:n.replace(/\r\n$|\n$|\r$/,"")}function r4(e,t,n=0){return e.diff?v5(t??{},n)?(function(o){const s=Pu(o.raw);if(s){const i=s.split(/\r?\n/);return o.originalCode!=null||o.updatedCode!=null?Math.max(1,i.filter(r=>!Rfe.some(l=>r.startsWith(l))).length):Math.max(1,i.length)}return af(Pu(o.originalCode))+af(Pu(o.updatedCode))})(e):(function(o){const s=o.originalCode,i=o.updatedCode;if(s!=null||i!=null)return Math.max(af(Pu(s)),af(Pu(i)));const r=Pu(o.code).split(/\r?\n/);let l=0,a=0;for(const u of r)u.startsWith("+")&&!u.startsWith("+++")?a++:u.startsWith("-")&&!u.startsWith("---")?l++:(l++,a++);return Math.max(1,l,a)})(e):af(Pu(e.code,e.loading===!0))}function Pfe(e){return e?`${e.fontStyle||"normal"} ${e.fontWeight||"400"} ${e.fontSize||"16px"} ${e.fontFamily||"sans-serif"}`:""}function l4(e,t,n="pre-wrap"){if(!e||!t||typeof window>"u")return null;const o=window.getComputedStyle(t),s=e.offsetHeight,i=Y_(o.lineHeight,1.5*Y_(o.fontSize,16)),r=e.getBoundingClientRect().width,l=t.getBoundingClientRect().width;return{font:Pfe(o),lineHeight:i,wrapperOverhead:Math.max(0,s-i),widthAdjustment:Math.max(0,r-l),whiteSpace:n}}const Dfe=new Set(["node","key","ref","ctx","renderNode","indexKey","__proto__","prototype","constructor"]);function X_(e,t={}){var n;const o={},s=new Set((n=t.omit)!=null?n:[]);if(!e||typeof e!="object")return o;const i=Object.getOwnPropertyDescriptors(e);for(const[r,l]of Object.entries(i))Dfe.has(r)||s.has(r)||l.enumerable&&"value"in l&&(o[r]=l.value);return o}function J_(e,t,n,o){var s;const i=(function(f){return Math.max(0,Math.ceil(f.scrollHeight||0)-Math.ceil(f.clientHeight||0))})(e),r=(function(f,h){return Number.isFinite(f)?Math.min(Math.max(0,f),h):0})(n,i);if(!o.isReverseFlexScrollRoot(e))return void(e.scrollTop=r);const l=Math.max(0,i-r),a=[-l,l];let u=a[0],c=Number.POSITIVE_INFINITY;for(const f of a){e.scrollTop=f;const h=o.getNormalizedScrollTop(e,t,!1),m=Math.abs(h-r);m<c&&(c=m,u=f)}e.scrollTop=u;const d=(s=o.epsilonPx)!=null?s:2;Math.abs(o.getNormalizedScrollTop(e,t,!1)-r)>d&&(e.scrollTop=u)}function Q_(e,t){let n=0,o=null,s=null;const i=()=>{const r=s;s=null,o=null,r&&(n=Date.now(),e(...r))};return function(...r){const l=Date.now(),a=t-(l-n);s=r,a<=0?(o&&(clearTimeout(o),o=null),n=l,s=null,e(...r)):o||(o=setTimeout(i,a))}}function ex(e){return e==="simple"?"simple":e===!0||e==="true"||e==="precise"?"precise":"off"}const A$=Symbol("MarkstreamMathBlockMinHeightCache");function LVe(){return nn(A$,null)}const Bfe=new Set(["text","inline_code","emoji","footnote_reference"]),Hfe=new Set(["strong","emphasis","strikethrough","highlight","insert","subscript","superscript","link"]);function uf(e){const t=Number(e);return!Number.isFinite(t)||t<=0?-1:Math.round(t/32)}function Du(e,t,n,o=22){const s=String(e??"");if(!s)return n;const i=Math.max(18,Math.floor(Math.max(320,t)/8)),r=s.split(/\r?\n/).length,l=Math.ceil(s.length/i),a=Math.max(1,r,l);return Math.max(n,Math.ceil(a*o+12))}function M$(e){var t;if(!e||typeof e!="object")return!1;const n=e,o=String((t=n.type)!=null?t:"");if(Bfe.has(o))return!0;if(!Hfe.has(o))return!1;const s=n.children;return!Array.isArray(s)||!s.length||s.every(M$)}function c8(e){var t,n,o,s,i,r,l,a;if(!e||typeof e!="object")return"";const u=e,c=String((t=u.type)!=null?t:"");if(c==="text")return String((o=(n=u.content)!=null?n:u.raw)!=null?o:"");if(c==="inline_code")return String((r=(i=(s=u.code)!=null?s:u.content)!=null?i:u.raw)!=null?r:"");if(c==="emoji")return String((a=(l=u.name)!=null?l:u.raw)!=null?a:"");if(typeof u.text=="string")return u.text;const d=[];for(const f of["children","items","cells","rows"]){const h=u[f];if(Array.isArray(h)){const m=h.map(c8).filter(Boolean).join(" ");m&&d.push(m)}}return d.join(" ").replace(/\s+/g," ").trim()}function T$(e){if(!e||typeof e!="object")return!1;const t=e;return t.type==="inline_code"||["children","items","cells","rows"].some(n=>{const o=t[n];return Array.isArray(o)&&o.some(T$)})}function zfe(e,t){if(!e)return 30;const n=Math.max(18,Math.floor(Math.max(320,t)/8)),o=e.split(/\r?\n/).length,s=Math.ceil(e.length/n),i=Math.max(1,o,s);return 30+26*Math.max(0,i-1)}function Wfe(e,t){var n,o,s,i,r,l,a,u,c,d,f,h,m,v;if(!e||typeof e!="object")return 32;const k=e,w=String((n=k.type)!=null?n:""),b=Number.isFinite(t)&&t>0?t:640;switch(w){case"heading":return(function(_){var g;const x=Number((g=_.level)!=null?g:_.depth);return x>=4?20:x===3?30:x===2?32:44})(k);case"paragraph":return(function(_,g){const x=String(_??"");if(!x)return 28;const S=Math.max(18,Math.floor(Math.max(320,g)/8)),T=x.split(/\r?\n/).length,A=Math.ceil(x.length/S);return Math.max(1,T,A)<=1?28:Du(x,g,34)})(String((s=(o=k.raw)!=null?o:k.content)!=null?s:""),b);case"list":return(function(_,g){var x;const S=Array.isArray(_.items)?_.items:[];if(!S.length)return 48;const T=Math.max(48,30*S.length+12);let A=12;for(const D of S)A+=zfe(c8(D)||String((x=D.raw)!=null?x:""),g);const E=Math.max(0,A-T);if(S.length>20){const D=Math.round(2.4*S.length);return Math.round(T+Math.max(D,Math.min(E,3*S.length)))}if(E<=0)return T;const P=S.length>8?8*S.length:E;return Math.round(T+Math.min(E,P))})(k,b);case"list_item":return Du(String((r=(i=k.raw)!=null?i:k.content)!=null?r:""),b,34);case"blockquote":return Du(String((a=(l=k.raw)!=null?l:k.content)!=null?a:""),b,56);case"table":return(function(_,g){const x=[..._.header?[_.header]:[],...Array.isArray(_.rows)?_.rows:[]];if(!x.length){const S=Array.isArray(_.children)?_.children.length:3;return Math.max(120,38*S+48)}return Math.max(120,Math.round(4+x.reduce((S,T)=>S+(function(A,E){const P=Math.max(1,A.length),D=Math.max(80,(E-32)/P),I=Math.max(10,Math.floor(D/8)),$=Math.max(1,...A.map(B=>{var H;const O=c8(B)||String((H=B?.raw)!=null?H:"");return Math.ceil(O.length/I)||1}));return 54+34*Math.max(0,$-1)+(P<=3&&A.some(T$)?14:0)})((function(A){var E;return Array.isArray(A?.cells)&&(E=A.cells)!=null?E:[]})(T),g),0)))})(k,b);case"code_block":{const _=String((u=k.language)!=null?u:"").trim().toLowerCase(),g=String((d=(c=k.code)!=null?c:k.raw)!=null?d:"");return _==="mermaid"?lg(ig(g)):_==="infographic"?ag(rg(g)):Du(g,b,96,20)}case"math_block":return 72;case"image":return 220;case"admonition":case"vmr_container":case"html_block":return(function(_,g){var x,S,T;const A=_.match(/^\s*<details\b([^>]*)>/i);return A&&!/(?:^|\s)open(?:\s|=|$)/i.test((x=A[1])!=null?x:"")?Du(((T=(S=_.match(/<summary\b[^>]*>([\s\S]*?)<\/summary>/i))==null?void 0:S[1])==null?void 0:T.replace(/<[^>]*>/g,"").trim())||"Details",g,28,28):Du(_,g,96)})(String((h=(f=k.raw)!=null?f:k.content)!=null?h:""),b);case"thematic_break":return 24;default:return Du(String((v=(m=k.raw)!=null?m:k.content)!=null?v:""),b,40)}}function tx(e,t,n){return Math.min(Math.max(e,t),n)}const Ufe=["total","cacheHits","appendHits","tailHits","fullParses","chunkedParses"],jfe=["tokenCloneMs","processTokensInputTokens","processTokensReusedTopLevelNodes","processTokensMs","parseMarkdownToStructureTotalMs"],Vfe=new Set(["attrs","data","items","header","payload","props","rows","cells","term","definition","sourceMap"]),E$=["raw","content","code","originalCode","updatedCode"],nx=new WeakMap,ox=new WeakMap;let qfe=1;function Rr(){return typeof performance<"u"?performance.now():Date.now()}function sx(e){const t=e.stream;return t&&typeof t.stats=="function"?t.stats():null}function Qi(e){if(typeof e!="object"&&typeof e!="function"||e===null)return"";const t=e;let n=nx.get(t);return n||(n=qfe++,nx.set(t,n)),String(n)}function ix(e,t,n,o={}){var s,i;const r=o.includeFinal!==!1,l={md:Qi(t),customMarkdownIt:Qi(n),requireClosingStrong:e.requireClosingStrong===!0,customHtmlTags:(s=e.customHtmlTags)!=null?s:[],includeSourceMap:e.includeSourceMap===!0,streamParse:(i=e.streamParse)!=null?i:"auto",validateLink:Qi(e.validateLink),preTransformTokens:Qi(e.preTransformTokens),postTransformTokens:Qi(e.postTransformTokens),postTransformNodes:Qi(e.postTransformNodes)};return r&&(l.final=e.final===!0),JSON.stringify(l)}function rx(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===10;)t-=1;const n=e.lastIndexOf(` +`,t-1)+1;return e.slice(n,t).trim()}function lx(e){const t=I$(e);return t.length>=2&&t.every(n=>{const o=n.trim();return o.length>=1&&o.replace(/^:/,"").replace(/:$/,"").split("").every(s=>s==="-")})}function I$(e){return e.includes("|")?e.replace(/^\|/,"").replace(/\|$/,"").split("|"):[]}function L$(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function x5(e){const t=String(e??"");return`${t.length}:${L$(t)}`}function d8(e,t=new WeakMap,n=0){if(e==null||typeof e=="number"||typeof e=="boolean")return String(e);if(typeof e=="string")return`s:${(function(r){return r.length<=8192?x5(r):`${r.length}:${L$(r.slice(0,8192))}:truncated`})(e)}`;if(typeof e=="function")return`fn:${Qi(e)}`;if(typeof e!="object")return typeof e;const o=e,s=t.get(o);if(s)return`cycle:${s}`;if(n>=6)return`object:${Qi(o)}`;const i=Qi(o);if(t.set(o,i),Array.isArray(e)){const r=e.slice(0,200);return`a:${e.length}:${r.map(l=>d8(l,t,n+1)).join(",")}`}if(typeof e=="object"){const r=e,l=Object.keys(r).sort(),a=l.slice(0,80);return`o:${l.length}:${a.sort().map(u=>`${u}:${d8(r[u],t,n+1)}`).join(";")}`}return typeof e}function gg(e){return typeof e=="object"&&e!==null&&typeof e.type=="string"&&typeof e.raw=="string"}function $$(e,t=new WeakMap,n=0){return Array.isArray(e)?`a:${e.length}:${e.slice(0,200).map(o=>gg(o)?su(o,t,n+1):$$(o,t,n+1)).join(",")}`:gg(e)?su(e,t,n):d8(e,t,n)}function Kfe(e,t,n){return Object.keys(e).sort().filter(o=>o!=="children"&&!E$.includes(o)).map(o=>{const s=e[o];return typeof s=="string"?`${o}=s:${x5(s)}`:typeof s=="number"||typeof s=="boolean"||s==null?`${o}=${String(s)}`:typeof s=="function"?`${o}=fn:${Qi(s)}`:Vfe.has(o)&&(Array.isArray(s)||typeof s=="object")?`${o}=${$$(s,t,n+1)}`:s&&typeof s=="object"?`${o}=object:${Qi(s)}`:""}).filter(Boolean).join(";")}function Zfe(e){return E$.map(t=>{const n=e[t];return typeof n=="string"?`${t}=s:${x5(n)}`:""}).filter(Boolean).join(";")}function su(e,t=new WeakMap,n=0){const o=ox.get(e);if(o)return o;const s=e,i=t.get(s);if(i)return`node-cycle:${i}`;if(n>=6)return`node:${e.type}:${Qi(s)}`;const r=Qi(s);t.set(s,r);const l=(function(a,u,c){const d=a,f=Array.isArray(d.children)?d.children:[],h=f.length?f.slice(0,200).map(m=>su(m,u,c+1)).join("|"):"";return[a.type,Zfe(d),Kfe(d,u,c),f.length,h].join(":")})(e,t,n);return ox.set(s,l),l}function N$(e,t){return su(e)===su(t)}function S5(e,t,n){const o=Rr(),s=t==="stabilizeSignatureMs"?"stabilizeSignatureCallCount":"primeSignatureCallCount";try{return n()}finally{e[t]+=Rr()-o,e[s]+=1,e.signatureMs=e.stabilizeSignatureMs+e.primeSignatureMs,e.signatureCallCount=e.stabilizeSignatureCallCount+e.primeSignatureCallCount}}function ax(e,t,n){return S5(t,n,()=>su(e))}function F$(e,t,n){return ax(e,n,"stabilizeSignatureMs")===ax(t,n,"stabilizeSignatureMs")}function _h(e){return{reusedNodeCount:0,dirtyStartIndex:e>0?0:-1,stablePrefixNodeCount:0,dirtyTailNodeCount:e}}function ux(e,t,n){return e<0?0:Math.max(t.length,n.length)-e}function cx(e){return e.__markstreamHasCustomParserExtensions===!0||(function(t){var n;return Number((n=t.__markstreamRegisteredPluginCount)!=null?n:0)>0})(e)}function Gfe(e,t){return e.length===t.length&&e===t}function A5(e,t,n=0){if(n>=4)return null;if(e.type!==t.type)return!1;const o=e,s=t,i=Object.keys(o).filter(c=>c!=="type"&&c!=="children").sort(),r=Object.keys(s).filter(c=>c!=="type"&&c!=="children").sort();if(i.length!==r.length)return!1;for(let c=0;c<i.length;c++){const d=i[c];if(d!==r[c])return!1;const f=o[d],h=s[d];if(typeof f!=typeof h)return!1;if(typeof f!="string"){if(typeof f!="number"&&typeof f!="boolean"&&f!=null)return null;if(!Object.is(f,h))return!1}else if(typeof h!="string"||!Gfe(f,h))return!1}const l=Object.prototype.hasOwnProperty.call(o,"children");if(l!==Object.prototype.hasOwnProperty.call(s,"children"))return!1;if(!l)return!0;const a=o.children,u=s.children;if(!Array.isArray(a)||!Array.isArray(u))return null;if(a.length!==u.length)return!1;for(let c=0;c<a.length;c++){const d=a[c],f=u[c];if(!gg(d)||!gg(f))return null;const h=A5(d,f,n+1);if(h==null)return null;if(!h)return!1}return!0}function Yfe(e,t){if(!e||!t)return!1;if(e===t)return!0;if(e.type!==t.type)return!1;const n=A5(e,t);return n??N$(e,t)}function Xfe(e,t,n){if(!e||!t)return!1;if(e===t)return!0;if(e.type!==t.type)return!1;let o=null;return S5(n,"stabilizeSignatureMs",()=>{o=A5(e,t)}),o??F$(e,t,n)}function Jfe(e,t){const n={};for(const o of Ufe){const s=e[o],i=t?.[o];typeof s=="number"&&(n[o]=s-(typeof i=="number"?i:0))}return n}function Qfe(e,t){var n;const o=l_(t.instanceMsgId),s=new Map,i=(n=t.smoothStreamingEnabled)!=null?n:R(()=>!1),r=Z(t.renderContent.value);let l=[],a="",u="",c="",d=!1;const f=(function(){let B="",H=0,O=!1,F=!1,U=!1,z=!1;function W(){B="",H=0,O=!1,F=!1,U=!1,z=!1}function K(V){let ie=!1;for(let ne=0;ne<V.length;ne++){const X=V.charCodeAt(ne);if(X===10||X===13){const Ie=X===10&&z;z=X===13,O=!1,Ie||(U||(F=!1,H=0),U=!1);continue}z=!1;const le=X===9||X===32;if(le||(U=!0,F&&(ie=!0)),H)if(H!==1)le||(X!==58?H=X===91?1:0:(ie=!0,F=!0));else{if(O){O=!1;continue}if(X===92){O=!0;continue}X===93&&(H=2)}else X===91&&(H=1)}return ie}return(V,ie)=>{if(!V||!ie.startsWith(V)||ie.length<=V.length)return W(),[!0,0];let ne=0;B!==V&&(W(),K(V),ne=V.length);const X=ie.slice(V.length),le=K(X);return B=ie,[le,ne+X.length]}})();let h,m=0,v=0,k=Rr(),w=-1,b=0;function _(B){w=Number.isInteger(B)?B:0,b+=1}function g(){h&&(clearTimeout(h),h=void 0)}function x(){g();const B=t.renderContent.value;r.value!==B&&(r.value=B),k=Rr()}Je([t.renderContent,t.effectiveFinal,i],([B,H,O])=>{r.value!==B&&(!O||H||(function(F,U){if(!F&&U||U.length<=80||U.length<F.length||!U.startsWith(F))return!0;const z=U.slice(F.length);return!!z&&(!!lx(rx(U))||!(!z.includes(` + +`)&&!/(?:^|\n)(?:#{1,6}\s|[-+*]\s+|\d+[.)]\s+|>\s*|`{3,}|~{3,})/.test(z))||z.endsWith(` +`)&&!(function(W){const K=rx(W);if(lx(K))return!1;const V=I$(K);return V.length>=2&&V.some(ie=>ie.trim())})(U))})(r.value,B)?x():(function(){if(v+=1,h)return;const F=Math.max(0,(function(U){const z=U.parseCoalesceMs;return typeof z=="number"&&Number.isFinite(z)&&z>=0?z:80})(e)-(Rr()-k));F<=0?x():h=setTimeout(x,F)})())},{flush:"sync",immediate:!0}),d1(g);const S=R(()=>{var B,H,O,F;return cie(e.customHtmlTags,(B=e.parseOptions)==null?void 0:B.customHtmlTags,(F=(O=(H=t.customComponentsMap)==null?void 0:H.value)!=null?O:{},Object.entries(F).map(([U,z])=>{const W=Sr(U);return z==null||!W||Qp(W)||WI.has(W)||Zp.has(W)?"":W}).filter(Boolean)))}),T=R(()=>{const{key:B,tags:H}=die(S.value);if(!B)return o;const O=s.get(B);if(O)return O;const F=l_(t.instanceMsgId,{customHtmlTags:H});return s.set(B,F),F}),A=R(()=>{const B=T.value;if(!e.customMarkdownIt)return B;const H=e.customMarkdownIt(B);return B.__markstreamHasCustomParserExtensions=!0,H.__markstreamHasCustomParserExtensions=!0,H}),E=R(()=>{var B,H;const O=(B=e.parseOptions)!=null?B:{},F=t.effectiveFinal.value,U=S.value,z=F!=null,W=U.length>0;return z||W||O.streamParse==null?mt(mt(rn(mt({},O),{streamParse:(H=O.streamParse)==null||H}),z?{final:F}:{}),W?{customHtmlTags:U}:{}):O}),P=R(()=>{var B;return new Set(((B=E.value.customHtmlTags)!=null?B:[]).map(H=>String(H).trim().toLowerCase()).filter(Boolean))}),D=R(()=>ix(E.value,A.value,e.customMarkdownIt,{includeFinal:!0})),I=R(()=>ix(E.value,A.value,e.customMarkdownIt,{includeFinal:!1}));Je([D,I],([B,H],[O,F])=>{O&&(B===O&&H===F||(x(),H!==F&&(l=[],c="")))},{flush:"sync"});const $=R(()=>{var B,H,O,F,U,z,W,K,V,ie,ne;if((B=e.nodes)!=null&&B.length)return l=[],c="",_(0),kt(e.nodes.slice());const X=r.value;if(!X)return l=[],c="",_(-1),[];const le=t.debugPerformanceEnabled.value,Ie=le?Rr():0,de=A.value,pe=D.value,ve=I.value;a&&pe!==a&&(function(Fe){var Oe,Ge;(Ge=(Oe=Fe.stream)==null?void 0:Oe.reset)==null||Ge.call(Oe)})(de),u&&ve!==u&&(l=[],c="");const oe=Object.keys((O=(H=t.customComponentsMap)==null?void 0:H.value)!=null?O:{}).length>0||typeof E.value.postTransformNodes=="function";oe!==d&&(l=[],c="");const ye=!oe&&l.length>0&&X.startsWith(c)&&ve===u,G=le?sx(de):null,Y=le?{}:void 0,fe=cx(de),we=!fe&&!oe,ge=mt(mt(rn(mt({},E.value),{__reuseStableTopLevelNodes:we}),fe?{__disableStreamParse:!0}:{}),Y?{__timing:Y}:{}),Q=UL(X,de,ge),te=le?Rr():0,ce=le?{signatureMs:0,stabilizeSignatureMs:0,primeSignatureMs:0,signatureCallCount:0,stabilizeSignatureCallCount:0,primeSignatureCallCount:0}:void 0;let ue,Se=le?_h(Q.length):void 0,ze=0,_e=0,Ee=0;if(ye){const Fe=le?Rr():0,[Oe,Ge]=(function(Tt){var Bt,Yt;const[Sn,on]=Tt.scanGlobalReferenceAppend(Tt.previousContent,Tt.content),en=Tt.parseOptions;return[Tt.previousDirtyStartIndex>0&&en.final!==!0&&!Tt.customMarkdownIt&&!cx(Tt.md)&&!Sn&&typeof en.preTransformTokens!="function"&&typeof en.postTransformTokens!="function"&&typeof en.postTransformNodes!="function"&&((Yt=(Bt=en.customHtmlTags)==null?void 0:Bt.length)!=null?Yt:0)===0?Tt.previousDirtyStartIndex:0,on]})({content:X,previousContent:c,previousDirtyStartIndex:w,parseOptions:E.value,customMarkdownIt:e.customMarkdownIt,md:de,scanGlobalReferenceAppend:f});Ee=Ge;const at=Oe<=0;if(ce){const Tt=(function(Bt,Yt,Sn,on={}){var en;if(!Yt.length)return{nodes:Bt,metrics:_h(Bt.length)};const Cn=(en=on.scanStartIndex)!=null?en:0,Mn=on.reuseDirtyTail!==!1,We=(function(Lt,gt,wn,yn=0){const go=Math.min(Lt.length,gt.length);for(let qt=Math.min(go,Math.max(0,yn));qt<go;qt++)if(!Xfe(gt[qt],Lt[qt],wn))return qt;return Lt.length===gt.length?-1:go})(Bt,Yt,Sn,Cn);if(We<0)return{nodes:Yt,metrics:{reusedNodeCount:Bt.length,dirtyStartIndex:We,stablePrefixNodeCount:Bt.length,dirtyTailNodeCount:0}};const tt=Bt.slice();let Ue=We;for(let Lt=0;Lt<We;Lt++)tt[Lt]=Yt[Lt];if(Mn)for(let Lt=We;Lt<Bt.length;Lt++){const gt=Yt[Lt],wn=Bt[Lt];gt&&F$(gt,wn,Sn)&&(tt[Lt]=gt,Ue+=1)}return{nodes:tt,metrics:{reusedNodeCount:Ue,dirtyStartIndex:We,stablePrefixNodeCount:We,dirtyTailNodeCount:ux(We,Bt,Yt)}}})(Q,l,ce,{reuseDirtyTail:at,scanStartIndex:Oe});ue=Tt.nodes,Se=Tt.metrics}else{const Tt=(function(Bt,Yt,Sn={}){var on;if(!Yt.length)return{nodes:Bt,metrics:_h(Bt.length)};const en=(on=Sn.scanStartIndex)!=null?on:0,Cn=Sn.reuseDirtyTail!==!1,Mn=(function(Ue,Lt,gt=0){const wn=Math.min(Ue.length,Lt.length);for(let yn=Math.min(wn,Math.max(0,gt));yn<wn;yn++)if(!Yfe(Lt[yn],Ue[yn]))return yn;return Ue.length===Lt.length?-1:wn})(Bt,Yt,en);if(Mn<0)return{nodes:Yt,metrics:{reusedNodeCount:Bt.length,dirtyStartIndex:Mn,stablePrefixNodeCount:Bt.length,dirtyTailNodeCount:0}};const We=Bt.slice();let tt=Mn;for(let Ue=0;Ue<Mn;Ue++)We[Ue]=Yt[Ue];if(Cn)for(let Ue=Mn;Ue<Bt.length;Ue++){const Lt=Yt[Ue],gt=Bt[Ue];Lt&&N$(Lt,gt)&&(We[Ue]=Lt,tt+=1)}return{nodes:We,metrics:{reusedNodeCount:tt,dirtyStartIndex:Mn,stablePrefixNodeCount:Mn,dirtyTailNodeCount:ux(Mn,Bt,Yt)}}})(Q,l,{reuseDirtyTail:at,scanStartIndex:Oe});ue=Tt.nodes,Se=Tt.metrics}ze=le?Rr()-Fe:0,_e=at?Se?.dirtyStartIndex==null||Se.dirtyStartIndex<0?ue.length:Se.dirtyStartIndex:ue.length}else ue=Q,Se=_h(ue.length);t.effectiveFinal.value!==!0&&(ce?(function(Fe,Oe,Ge=0){for(let at=Math.max(0,Ge);at<Fe.length;at++)S5(Oe,"primeSignatureMs",()=>su(Fe[at]))})(ue,ce,_e):(function(Fe,Oe=0){for(let Ge=Math.max(0,Oe);Ge<Fe.length;Ge++)su(Fe[Ge])})(ue,_e));const it=le?Rr()-te:0;if(m+=1,c=X,a=pe,u=ve,d=oe,l=ue,_((F=Se?.dirtyStartIndex)!=null?F:0),le){const Fe=sx(de),Oe=typeof Fe?.total=="number"&&Fe.total>((U=G?.total)!=null?U:0);t.logPerf(Oe?"parse(stream)":"parse(sync)",mt(mt(mt({rendererId:t.instanceMsgId,ms:Math.round(Rr()-Ie),nodes:ue.length,contentLength:X.length,parseCommitCount:m,parseCoalescedCount:v,nodeReuseMs:it,referenceDefinitionScanChars:Ee,signatureMs:(z=ce?.signatureMs)!=null?z:0,stabilizeSignatureMs:(W=ce?.stabilizeSignatureMs)!=null?W:0,primeSignatureMs:(K=ce?.primeSignatureMs)!=null?K:0,signatureCallCount:(V=ce?.signatureCallCount)!=null?V:0,stabilizeSignatureCallCount:(ie=ce?.stabilizeSignatureCallCount)!=null?ie:0,primeSignatureCallCount:(ne=ce?.primeSignatureCallCount)!=null?ne:0,stabilizeMs:ze},Se??{}),Y?Object.fromEntries(jfe.map(Ge=>{var at;return[Ge,(at=Y[Ge])!=null?at:0]})):{}),Fe?{streamMode:Fe.lastMode,streamDelta:Jfe(Fe,G),streamStats:Fe}:{}))}return kt(ue)});return{effectiveCustomHtmlTags:S,effectiveCustomHtmlTagsSet:P,mdBase:T,mdInstance:A,mergedParseOptions:E,getParsedNodesDirtyStartIndex:()=>w,getParsedNodesRevision:()=>b,parsedNodes:$}}function epe(e){const{isClient:t}=e,n=Z(new Set),o=new Map,s=new Map,i=new Map;function r(u){if(!t)return;const c=i.get(u);c!=null&&(window.clearTimeout(c),i.delete(u))}function l(){if(t)for(const u of i.values())window.clearTimeout(u);i.clear()}function a(){n.value=new Set}return{visibleNodeIndices:n,nodeVisibilityHandles:o,nodeVisibilityWatchStops:s,nodeVisibilityFallbackTimers:i,clearVisibilityFallback:r,clearAllVisibilityFallbacks:l,markNodeVisible:function(u,c=!0){var d;c&&r(u),(function(f,h){if((v=(m=e.shouldTrackVisibleNodeIndices)==null?void 0:m.call(e))!=null&&!v)return;var m,v;const k=n.value,w=k.has(f);if(h){if(w)return;const _=new Set(k);return _.add(f),void(n.value=_)}if(!w)return;const b=new Set(k);b.delete(f),n.value=b})(u,c),c&&((d=e.onNodeMarkedVisible)==null||d.call(e,u))},resetNodeVisibleState:a,cleanupNodeVisibility:function(u){var c;if(e.shouldCleanupNodeVisibility&&!e.shouldCleanupNodeVisibility())return;for(const[f,h]of s.entries())f<u||(h(),s.delete(f));for(const[f,h]of o.entries())f<u||(h.destroy(),o.delete(f),r(f),(c=e.onNodeVisibilityCleaned)==null||c.call(e,f));for(const f of Array.from(i.keys()))f<u||r(f);if(!n.value.size)return;const d=new Set;for(const f of n.value)f<u&&d.add(f);n.value=d},destroyNodeVisibilityState:function(){a();for(const u of s.values())u();s.clear();for(const u of o.values())u.destroy();o.clear(),l()}}}function tpe(e={}){const t=Z(""),n=Z(""),o=Z(!1),s=Nce(e),i=()=>{const c=s.getSnapshot();t.value=c.source,n.value=c.visible,o.value=c.done},r=s.subscribe(i);i();const l=R(()=>Math.max(0,t.value.length-n.value.length)),a=R(()=>l.value===0),u=R(()=>o.value&&a.value);return Kg()&&d1(()=>{r(),s.destroy()}),{source:t,visible:n,done:o,final:u,caughtUp:a,pendingChars:l,enqueue:c=>s.enqueue(c),finish:c=>s.finish(c),flush:()=>s.flush(),reset:c=>s.reset(c),pause:()=>s.pause(),resume:()=>s.resume()}}const npe={maxCharsPerSecond:3e3,maxCommitFps:20,maxCharsPerCommit:160,catchUpLatencyMs:220,catchUpThreshold:400},dx=/auto|scroll|overlay/i;function ope(e){if(!e)return!1;const t=(e.overflowY||"").toLowerCase(),n=(e.overflow||"").toLowerCase();return dx.test(t)||dx.test(n)}function spe(e){const t=Math.ceil(e.scrollHeight)>Math.ceil(e.clientHeight)+1,n=Math.ceil(e.scrollWidth)>Math.ceil(e.clientWidth)+1;return t||n}const ipe={class:"m-0 p-0"},rpe=["data-probe"],lpe=Gn(et(rn(mt({},{name:"HeightEstimationProbes"}),{__name:"HeightEstimationProbes",props:{width:{},flowRoot:{type:Boolean},paragraphNode:{},listItemNode:{},listNode:{},headingNodes:{},setParagraphWrapper:{type:Function},setListItemWrapper:{type:Function},setListWrapper:{type:Function},setHeadingWrapper:{type:Function}},setup(e){const t=e;function n(o){var s,i;return(i=(s=t.headingNodes)==null?void 0:s[o])!=null?i:null}return(o,s)=>(y(),M("div",{class:"height-estimation-probes",style:Zt({width:`${e.width}px`}),"aria-hidden":"true"},[C("div",{ref:i=>e.setParagraphWrapper(i),class:Re(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"paragraph"},[j(p(cc),{node:e.paragraphNode,"index-key":"probe-paragraph"},null,8,["node"])],2),C("div",{ref:i=>e.setListItemWrapper(i),class:Re(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"list-item"},[C("ul",ipe,[j(p(Vd),{node:e.listItemNode,"index-key":"probe-list-item"},null,8,["node"])])],2),C("div",{ref:i=>e.setListWrapper(i),class:Re(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"list"},[j(p(qd),{node:e.listNode,"index-key":"probe-list"},null,8,["node"])],2),(y(),M(Pe,null,pt(6,i=>C("div",{key:`probe-heading-${i}`,ref_for:!0,ref:r=>e.setHeadingWrapper(i,r),class:Re(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":`heading-${i}`},[j(p(L2),{node:n(i),"index-key":`probe-heading-${i}`},null,8,["node","index-key"])],10,rpe)),64))],4))}})),[["__scopeId","data-v-3e0766e2"]]),fx=et({name:"InfographicBlockNodeLoading",props:{node:{type:Object,required:!0},showHeader:{type:Boolean,default:!0},estimatedPreviewHeightPx:{type:Number,default:void 0}},setup(e){const t=R(()=>{var n,o;return ag((o=Md(e.estimatedPreviewHeightPx))!=null?o:rg(String((n=e.node.code)!=null?n:"")))});return()=>{var n;return tn("div",{class:"infographic-block-container rounded-lg border overflow-hidden",style:{margin:"var(--ms-flow-diagram-y) 0",background:"var(--diagram-bg)",borderColor:"var(--diagram-border)",color:"hsl(var(--ms-foreground))"},"data-markstream-infographic":"1","data-markstream-mode":"pending"},[e.showHeader?tn("div",{class:"infographic-block-header flex justify-between items-center border-b",style:{padding:"var(--ms-inset-panel-y) var(--ms-inset-panel-x)",background:"var(--diagram-header-bg)",borderColor:"var(--diagram-border)",minHeight:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding) + var(--ms-inset-panel-y) + var(--ms-inset-panel-y) + 1px)"}},[tn("div",{class:"flex items-center gap-x-2 overflow-hidden"},[tn("span",{class:"icon-slot action-icon shrink-0",style:{display:"inline-flex",width:"var(--ms-action-btn-icon)",height:"var(--ms-action-btn-icon)"}}),tn("span",{class:"infographic-label font-medium font-mono truncate",style:{fontSize:"var(--ms-text-label)",color:"hsl(var(--ms-muted-foreground))"}},"Infographic")]),tn("div",{class:"infographic-header-actions flex items-center opacity-0 pointer-events-none",style:{gap:"var(--ms-gap-header-actions)"},"aria-hidden":"true"},Array.from({length:4},()=>tn("span",{class:"infographic-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded",style:{width:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding))",height:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding))"}})))]):null,tn("div",{class:"infographic-preview relative overflow-hidden block",style:{height:`${t.value}px`,minHeight:"var(--ms-size-diagram-min-height)",background:"var(--diagram-bg)"}},[tn("pre",{class:"infographic-pending-source text-sm font-mono whitespace-pre-wrap",style:{position:"absolute",inset:"0",zIndex:"1",margin:"0",padding:"var(--ms-inset-panel-body)",overflow:"auto",textAlign:"left"}},String((n=e.node.code)!=null?n:"")),tn("div",{class:"absolute inset-0"},[tn("div",{class:"w-full text-center flex items-center justify-center min-h-full"})])])])}}}),px=et({name:"MermaidBlockNodeLoading",props:{node:{type:Object,required:!0},showHeader:{type:Boolean,default:!0},estimatedPreviewHeightPx:{type:Number,default:void 0}},setup(e){const t=R(()=>{var n,o;return lg((o=Md(e.estimatedPreviewHeightPx))!=null?o:ig(String((n=e.node.code)!=null?n:"")))});return()=>{var n;return tn("div",{class:"mermaid-block-container rounded-lg border overflow-hidden",style:{margin:"var(--ms-flow-diagram-y) 0",borderColor:"var(--diagram-border)"},"data-markstream-mermaid":"1","data-markstream-mode":"pending"},[e.showHeader?tn("div",{class:"mermaid-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)]",style:{background:"var(--diagram-header-bg)",borderColor:"var(--diagram-border)"}},[tn("div",{class:"flex items-center gap-x-2 overflow-hidden"},[tn("span",{class:"mermaid-label-text text-[length:var(--ms-text-label)] font-medium font-mono truncate",style:{color:"var(--code-action-fg)"}},"Mermaid")]),tn("div",{class:"mermaid-header-actions flex items-center gap-[var(--ms-gap-header-actions)] opacity-0 pointer-events-none","aria-hidden":"true"},Array.from({length:4},()=>tn("span",{class:"mermaid-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded"},[tn("span",{class:"action-icon block"})])))]):null,tn("div",{class:"mermaid-preview-area relative overflow-hidden block",style:{height:`${t.value}px`,minHeight:"var(--ms-size-diagram-min-height)",background:"var(--diagram-bg)"}},[tn("pre",{class:"mermaid-source-code text-sm font-mono whitespace-pre-wrap",style:{position:"absolute",inset:"0",margin:"0",padding:"var(--ms-inset-panel-body)",overflow:"auto",textAlign:"left"}},String((n=e.node.code)!=null?n:"")),tn("div",{class:"_mermaid w-full text-center flex items-center justify-center min-h-full",style:{fontFamily:"inherit",contentVisibility:"auto",contain:"content",containIntrinsicSize:"var(--ms-size-diagram-min-height) 240px"}})])])}}}),ape={docs:{showTooltips:!0,fade:!0,batchRendering:!0,initialRenderBatchSize:40,renderBatchSize:80,renderBatchDelay:16,renderBatchBudgetMs:6,renderBatchIdleTimeoutMs:120,deferNodesUntilVisible:!0,maxLiveNodes:220,liveNodeBuffer:60,nodeVirtual:"auto"},chat:{showTooltips:!1,fade:!1,batchRendering:!0,initialRenderBatchSize:32,renderBatchSize:48,renderBatchDelay:6,renderBatchBudgetMs:8,renderBatchIdleTimeoutMs:60,deferNodesUntilVisible:!0,maxLiveNodes:0,liveNodeBuffer:0,nodeVirtual:"auto"},minimal:{showTooltips:!1,fade:!1,batchRendering:!0,initialRenderBatchSize:32,renderBatchSize:48,renderBatchDelay:6,renderBatchBudgetMs:8,renderBatchIdleTimeoutMs:60,deferNodesUntilVisible:!0,maxLiveNodes:0,liveNodeBuffer:0,nodeVirtual:"auto"}};function As(e){if(e==null)return"";if(typeof e=="string"||typeof e=="number"||typeof e=="boolean")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}const upe=["data-custom-id"],cpe=["data-node-index","data-node-type"],hx="typewriter-simple-cursor-target",R$=Gn(et(rn(mt({},{name:"NodeRenderer"}),{__name:"NodeRenderer",props:{content:{},nodes:{},final:{type:Boolean},parseOptions:{},customMarkdownIt:{},debugPerformance:{type:Boolean,default:!1},customHtmlTags:{},mode:{},domMode:{},htmlPolicy:{},viewportPriority:{type:Boolean,default:void 0},viewportPriorityOptions:{},codeBlockStream:{type:Boolean,default:!0},codeBlockDarkTheme:{},codeBlockLightTheme:{},codeBlockMonacoOptions:{},codeRenderer:{},renderCodeBlocksAsPre:{type:Boolean,default:void 0},codeBlockMinWidth:{},codeBlockMaxWidth:{},codeBlockProps:{},mermaidProps:{},d2Props:{},infographicProps:{},showTooltips:{type:Boolean,default:void 0},themes:{},langs:{},isDark:{type:Boolean},customId:{},indexKey:{},typewriter:{type:[Boolean,String],default:!1},smoothStreaming:{type:[Boolean,String],default:"auto"},smoothStreamingOptions:{},parseCoalesceMs:{},fade:{type:Boolean,default:void 0},batchRendering:{type:Boolean,default:void 0},initialRenderBatchSize:{},renderBatchSize:{},renderBatchDelay:{},renderBatchBudgetMs:{},renderBatchIdleTimeoutMs:{},deferNodesUntilVisible:{type:Boolean,default:void 0},maxLiveNodes:{},liveNodeBuffer:{},nodeVirtual:{type:[Boolean,String],default:void 0},virtualScroll:{},renderAsFragment:{type:Boolean}},emits:["copy","copy-code","handleArtifactClick","click","mouseover","mouseout","virtual-state-change","height-change","render-settled","render-final","anchor-change"],setup(e,{expose:t,emit:n}){const o=e,s=n;function i(L){if(!(typeof Event<"u"&&L instanceof Event))return typeof L=="string"&&s("copy-code",L),void s("copy",L)}const r=ds(),l=nn("markstreamNestedRendererProps",void 0);function a(L){const q=r?.vnode.props;return!!q&&(Object.prototype.hasOwnProperty.call(q,L)||Object.prototype.hasOwnProperty.call(q,String(L).replace(/[A-Z]/g,re=>`-${re.toLowerCase()}`)))}function u(L){var q,re;const ae=o[L];return a(L)?ae:(re=(q=l?.value)==null?void 0:q[L])!=null?re:ae}const c=R(()=>{return(L=u("mode"))==="chat"||L==="minimal"||L==="docs"?L:"docs";var L}),d=R(()=>ex(u("typewriter"))),f=R(()=>d.value!=="off"),h=R(()=>u("domMode")==="minimal"?"minimal":"full"),m=R(()=>{return(L={mode:c.value,codeRenderer:u("codeRenderer"),renderCodeBlocksAsPre:u("renderCodeBlocksAsPre")}).renderCodeBlocksAsPre===!0?"pre":L.codeRenderer==="pre"||L.codeRenderer==="shiki"||L.codeRenderer==="monaco"?L.codeRenderer:L.renderCodeBlocksAsPre===!1||L.mode==="docs"?"monaco":"pre";var L}),v=R(()=>ape[c.value]),k=R(()=>{var L;return(L=u("showTooltips"))!=null?L:v.value.showTooltips}),w=R(()=>{var L;return(L=u("fade"))!=null?L:v.value.fade}),b=R(()=>{var L;return(L=u("batchRendering"))!=null?L:v.value.batchRendering}),_=R(()=>{var L;return(L=u("initialRenderBatchSize"))!=null?L:v.value.initialRenderBatchSize}),g=R(()=>{var L;return(L=u("renderBatchSize"))!=null?L:v.value.renderBatchSize}),x=R(()=>{var L;return(L=u("renderBatchDelay"))!=null?L:v.value.renderBatchDelay}),S=R(()=>{var L;return(L=u("renderBatchBudgetMs"))!=null?L:v.value.renderBatchBudgetMs}),T=R(()=>{var L;return(L=u("renderBatchIdleTimeoutMs"))!=null?L:v.value.renderBatchIdleTimeoutMs}),A=R(()=>{var L;return(L=u("deferNodesUntilVisible"))!=null?L:v.value.deferNodesUntilVisible}),E=R(()=>{var L;return(L=u("maxLiveNodes"))!=null?L:v.value.maxLiveNodes}),P=R(()=>{var L;return(L=u("liveNodeBuffer"))!=null?L:v.value.liveNodeBuffer}),D=R(()=>{var L;return(L=u("nodeVirtual"))!=null?L:v.value.nodeVirtual}),I={get content(){return o.content},get nodes(){return o.nodes},get final(){return o.final},get parseOptions(){return u("parseOptions")},get customMarkdownIt(){return u("customMarkdownIt")},get debugPerformance(){return o.debugPerformance},get customHtmlTags(){return u("customHtmlTags")},get mode(){return u("mode")},get domMode(){return h.value},get htmlPolicy(){return u("htmlPolicy")},get viewportPriority(){return u("viewportPriority")},get viewportPriorityOptions(){return u("viewportPriorityOptions")},get codeBlockStream(){return u("codeBlockStream")},get codeBlockDarkTheme(){return u("codeBlockDarkTheme")},get codeBlockLightTheme(){return u("codeBlockLightTheme")},get codeBlockMonacoOptions(){return u("codeBlockMonacoOptions")},get codeRenderer(){return u("codeRenderer")},get renderCodeBlocksAsPre(){return u("renderCodeBlocksAsPre")},get codeBlockMinWidth(){return u("codeBlockMinWidth")},get codeBlockMaxWidth(){return u("codeBlockMaxWidth")},get codeBlockProps(){return u("codeBlockProps")},get mermaidProps(){return u("mermaidProps")},get d2Props(){return u("d2Props")},get infographicProps(){return u("infographicProps")},get showTooltips(){return k.value},get themes(){return u("themes")},get langs(){return u("langs")},get isDark(){return u("isDark")},get customId(){return u("customId")},get indexKey(){return o.indexKey},get typewriter(){return u("typewriter")},get smoothStreaming(){return o.smoothStreaming},get smoothStreamingOptions(){return u("smoothStreamingOptions")},get parseCoalesceMs(){return u("parseCoalesceMs")},get fade(){return w.value},get batchRendering(){return b.value},get initialRenderBatchSize(){return _.value},get renderBatchSize(){return g.value},get renderBatchDelay(){return x.value},get renderBatchBudgetMs(){return S.value},get renderBatchIdleTimeoutMs(){return T.value},get deferNodesUntilVisible(){return A.value},get maxLiveNodes(){return E.value},get liveNodeBuffer(){return P.value},get nodeVirtual(){return D.value},get virtualScroll(){return o.virtualScroll},get renderAsFragment(){return o.renderAsFragment}};function $(L){s("height-change",L)}function B(L){s("virtual-state-change",L)}function H(L){s("anchor-change",L)}const O=Z(),F=Z(null),U=Z(null),z=Z(null),W=Go({1:null,2:null,3:null,4:null,5:null,6:null}),K=Z(!1),V=new Map,ie=Z(0),ne=Z(0),X=Z({paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}});function le(L,q){return typeof L!="string"?q:L.trim()||q}function Ie(L){const q=Number(L);return Number.isFinite(q)&&q>0?Math.max(1,Math.trunc(q)):640}const de=R(()=>{var L;const q=(L=I.viewportPriorityOptions)!=null?L:{},re=le(q.rootMargin,yc);return{rootMargin:re,heavyBlockMargin:le(q.heavyBlockMargin,re),maxTargets:Ie(q.maxTargets)}}),pe=R(()=>{var L;return(L=de.value.rootMargin)!=null?L:yc}),ve=R(()=>{var L;return(L=de.value.maxTargets)!=null?L:640});function oe(){var L,q;if(((L=o.virtualScroll)==null?void 0:L.enabled)!==!0)return null;const re=(q=o.virtualScroll)==null?void 0:q.scrollRoot;return ye(typeof re=="function"?re():re)}function ye(L){return L?typeof HTMLElement<"u"&&L instanceof HTMLElement?L:typeof L=="object"&&"value"in L?ye(L.value):typeof L=="object"&&"$el"in L?ye(L.$el):null:null}Ln(y$,de);const{isClient:G,renderAsFragment:Y,debugPerformanceEnabled:fe,resolvedShowTooltips:we,resolvedHtmlPolicy:ge,inheritedSmoothStreaming:Q,ownsTypewriterCursor:te}=(function(L){const q=typeof window<"u",re=p1(),ae=nn("markstreamHtmlPolicy",void 0),be=nn("markstreamTypewriterCursor",void 0),Ne=nn("markstreamSmoothStreaming",void 0),De=R(()=>L.renderAsFragment===!0),je=R(()=>!!(L.debugPerformance&&q&&typeof console<"u")),ot=R(()=>{var nt;if(typeof L.showTooltips=="boolean")return L.showTooltips;const Be=(nt=re.showTooltips)!=null?nt:re["show-tooltips"];return Be===""||Be===!0||Be==="true"||Be!==!1&&Be!=="false"&&void 0}),Ve=R(()=>{var nt,Be;return(Be=(nt=L.htmlPolicy)!=null?nt:ae?.value)!=null?Be:"safe"}),Ye=R(()=>be?.value!==!0);return{isClient:q,renderAsFragment:De,debugPerformanceEnabled:je,resolvedShowTooltips:ot,resolvedHtmlPolicy:Ve,inheritedSmoothStreaming:Ne,inheritedTypewriterCursor:be,ownsTypewriterCursor:Ye}})(I),{resolveViewportRoot:ce,resolveScrollContainer:ue,isReverseFlexScrollRoot:Se,getNormalizedScrollTop:ze,getOffsetTopWithinRoot:_e}=(function(L,q){function re(){var je,ot;return(ot=(je=q.scrollRoot)==null?void 0:je.call(q))!=null?ot:null}function ae(je){if(typeof window>"u")return null;const ot=re();if(ot)return ot;const Ve=je??L.value;if(!Ve)return null;const Ye=Ve.ownerDocument||document,nt=Ye.scrollingElement||Ye.documentElement;let Be=Ve;for(;Be&&Be!==Ye.body&&Be!==nt;){if(ope(window.getComputedStyle(Be))&&spe(Be))return Be;Be=Be.parentElement}return null}function be(je){if(!q.isClient)return!1;try{const ot=window.getComputedStyle(je);return!!(ot.display||"").toLowerCase().includes("flex")&&(ot.flexDirection||"").toLowerCase().endsWith("reverse")}catch{return!1}}function Ne(je,ot,Ve){var Ye,nt;if(Ve)return De(ot);const Be=je.scrollTop;if(!be(je))return Be;const Xe=Be<0?-Be:Be;return Math.max(0,((Ye=je.scrollHeight)!=null?Ye:0)-((nt=je.clientHeight)!=null?nt:0))-Xe}function De(je){var ot,Ve,Ye,nt,Be;const Xe=Number((ot=je.scrollingElement)==null?void 0:ot.scrollTop),lt=Number((Ye=(Ve=je.documentElement)==null?void 0:Ve.scrollTop)!=null?Ye:0),rt=Number((Be=(nt=je.body)==null?void 0:nt.scrollTop)!=null?Be:0);return Math.max(0,Number.isFinite(Xe)?Xe:0,Number.isFinite(lt)?lt:0,Number.isFinite(rt)?rt:0)}return{resolveViewportRoot:ae,resolveScrollContainer:function(je){var ot,Ve,Ye,nt;const Be=re();if(Be)return Be;const Xe=ae((ot=je??L.value)!=null?ot:null);if(Xe)return Xe;const lt=(nt=(Ye=je?.ownerDocument)!=null?Ye:(Ve=L.value)==null?void 0:Ve.ownerDocument)!=null?nt:typeof document<"u"?document:null;return lt?.scrollingElement||lt?.documentElement||null},isReverseFlexScrollRoot:be,getNormalizedScrollTop:Ne,getOffsetTopWithinRoot:function(je,ot){const Ve=ot.ownerDocument||je.ownerDocument||document;if((function(Xe,lt){return Xe===lt.documentElement||Xe===lt.body||Xe===lt.scrollingElement})(ot,Ve))return je.getBoundingClientRect().top+De(Ve);const Ye=ot.getBoundingClientRect(),nt=je.getBoundingClientRect(),Be=Ne(ot,Ve,!1);return nt.top-Ye.top+Be}}})(O,{isClient:G,scrollRoot:oe});Ln("markstreamShowTooltips",we),Ln("markstreamHtmlPolicy",ge),Ln("markstreamTypewriter",f),Ln("markstreamFade",R(()=>I.fade!==!1)),Ln("markstreamTypewriterCursor",R(()=>!0)),Ln("markstreamTextStreamState",V),Ln("markstreamStreamVersion",ie),Ln("markstreamParseOptions",R(()=>I.parseOptions)),Ln("markstreamCustomMarkdownIt",R(()=>I.customMarkdownIt));const{smoothStreamingEnabled:Ee,renderContent:it,requestedFinal:Fe,effectiveFinal:Oe}=(function(L,q){const re=tpe(mt(mt({},npe),L.smoothStreamingOptions)),ae=R(()=>{var Be,Xe,lt;return L.smoothStreaming!==!1&&!((Be=L.nodes)!=null&&Be.length)&&(L.smoothStreaming===!0||!((Xe=q.inheritedSmoothStreaming)!=null&&Xe.value))&&(L.smoothStreaming===!0||ex(L.typewriter)!=="off"||((lt=L.maxLiveNodes)!=null?lt:0)<=0)}),be=Z(!q.isClient||L.smoothStreaming===!0);dn(()=>{be.value=!0});const Ne=R(()=>be.value&&ae.value),De=R(()=>{var Be;return Ne.value?re.visible.value:(Be=L.content)!=null?Be:""}),je=R(()=>{var Be,Xe;const lt=(Be=L.parseOptions)!=null?Be:{};return(Xe=L.final)!=null?Xe:lt.final}),ot=R(()=>{const Be=je.value;return Ne.value&&Be!=null?!!Be&&re.caughtUp.value:Be});let Ve=0,Ye=!1;function nt(){Ve=0,Ye=!1}return Je([()=>L.content,()=>L.nodes,Ne,je],([Be,Xe,lt,rt])=>{if(Xe?.length)return nt(),void re.reset("");const wt=Be??"";if(!lt)return nt(),re.reset(wt),void(rt&&re.finish({flush:!0}));const dt=re.source.value;if(wt){if(wt!==dt)if(wt.startsWith(dt)){const Ft=wt.slice(dt.length),Ht=re.pendingChars.value;Ft.length<=8?(Ve++,Ye||Ve>=2&&Ht<=8?(Ye=!0,re.reset(wt)):re.enqueue(Ft)):(nt(),re.enqueue(Ft))}else nt(),re.reset(wt)}else nt(),re.reset("");rt&&re.finish()},{immediate:!0}),{smoothStream:re,smoothStreamingEligible:ae,smoothStreamingEnabled:Ne,renderContent:De,requestedFinal:je,effectiveFinal:ot}})(I,{isClient:G,inheritedSmoothStreaming:Q}),Ge=Fe.value===!0;Ln("markstreamSmoothStreaming",Ee);const at=Z(!1),Tt=Z(!1),Bt=Z(!1);let Yt="",Sn=!1,on=null;function en(){G&&on!=null&&(window.clearTimeout(on),on=null)}function Cn(){at.value=!1,en()}function Mn(L,q){if(!fe.value)return;const re=(function(){if(!fe.value)return null;const ae=gt(We),be=gt(tt),Ne=Math.max(Lt,be);if(ae<=0&&Ne<=0)return null;const De={total:ae,maxPerFrame:Ne,byLabel:(je=We,Object.fromEntries(Array.from(je.entries()).sort((ot,Ve)=>Ve[1]-ot[1]||ot[0].localeCompare(Ve[0]))))};var je;return We.clear(),tt.clear(),Lt=0,De})();console.info(`[markstream-vue][perf] ${L}`,re?rn(mt({},q),{layoutReads:re}):q)}Je([()=>I.indexKey,()=>I.customId],()=>{var L,q;Cn(),Tt.value=!1,Bt.value=!((L=o.nodes)!=null&&L.length)&&Fe.value!==!0&&!!o.content,Yt=(q=it.value)!=null?q:"",Sn=Yt.length>0},{flush:"sync"}),Je([()=>o.content,()=>o.nodes,Fe],([L,q,re])=>{!q?.length&&re!==!0&&L&&(Bt.value=!0)},{flush:"sync",immediate:!0}),Je([it,()=>o.nodes,Fe],([L,q,re])=>{const ae=L??"";return q?.length||re===!0?(Cn(),Tt.value=!1,Yt=ae,void(Sn=!0)):(ae.length>0&&(Bt.value=!0),Sn?(Yt&&ae.length>Yt.length&&ae.startsWith(Yt)?(at.value=!0,Tt.value=!0,G&&(en(),on=window.setTimeout(()=>{var be;on=null,Oe.value===!0||(be=o.nodes)!=null&&be.length||(qc(),at.value=!1,Ol())},1200))):(ae.length<Yt.length||!ae.startsWith(Yt))&&(Cn(),Tt.value=!1),void(Yt=ae)):(Yt=ae,void(Sn=!0)))},{flush:"sync",immediate:!0});const We=new Map,tt=new Map;let Ue=!1,Lt=0;function gt(L){let q=0;for(const re of L.values())q+=re;return q}function wn(){Lt=Math.max(Lt,gt(tt)),tt.clear(),Ue=!1}function yn(L){L.maxPerFrame=Math.max(Number(L.maxPerFrame||0),Number(L.currentFrameTotal||0)),L.currentFrameTotal=0,L.frameScheduled=!1}function go(L){var q,re;fe.value&&(We.set(L,((q=We.get(L))!=null?q:0)+1),tt.set(L,((re=tt.get(L))!=null?re:0)+1),(function(ae){const be=(function(){if(!G||typeof window>"u")return null;const Ne=window;if(Ne.__markstreamLayoutReadPerformance)return Ne.__markstreamLayoutReadPerformance;const De={total:0,maxPerFrame:0,byLabel:{}};return Ne.__markstreamLayoutReadPerformance=De,De})();be&&(be.total=Number(be.total||0)+1,be.byLabel[ae]=Number(be.byLabel[ae]||0)+1,be.currentFrameTotal=Number(be.currentFrameTotal||0)+1,be.frameScheduled||(be.frameScheduled=!0,typeof window.requestAnimationFrame!="function"?typeof queueMicrotask!="function"?setTimeout(()=>yn(be),0):queueMicrotask(()=>yn(be)):window.requestAnimationFrame(()=>yn(be))))})(L),Ue||(Ue=!0,G&&typeof window<"u"&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(wn):typeof queueMicrotask!="function"?setTimeout(wn,0):queueMicrotask(wn)))}function qt(L,q){return go(L),q()}const ps=I.customId?`renderer-${I.customId}`:`renderer-${Date.now()}-${Math.random().toString(36).slice(2)}`,xs=(function(L){const q=new Map;return{scope:L,cache:q,clear:()=>q.clear()}})(ps),_n=ps;Ln(A$,xs);const In=fs(()=>I.customId),{effectiveCustomHtmlTagsSet:To,mergedParseOptions:lo,parsedNodes:St,getParsedNodesDirtyStartIndex:hs,getParsedNodesRevision:Jo}=Qfe(I,{instanceMsgId:ps,renderContent:it,effectiveFinal:Oe,smoothStreamingEnabled:Ee,debugPerformanceEnabled:fe,customComponentsMap:In,logPerf:Mn});Je(St,()=>{at.value||xs.clear(),ie.value+=1},{immediate:!0});const uo=R(()=>({customId:I.customId,customHtmlTags:lo.value.customHtmlTags,parseOptions:I.parseOptions,customMarkdownIt:I.customMarkdownIt,htmlPolicy:ge.value,viewportPriority:I.viewportPriority,viewportPriorityOptions:de.value,mode:c.value,domMode:I.domMode,codeRenderer:m.value,codeBlockStream:I.codeBlockStream,codeBlockDarkTheme:I.codeBlockDarkTheme,codeBlockLightTheme:I.codeBlockLightTheme,codeBlockMonacoOptions:I.codeBlockMonacoOptions,renderCodeBlocksAsPre:I.renderCodeBlocksAsPre,codeBlockMinWidth:I.codeBlockMinWidth,codeBlockMaxWidth:I.codeBlockMaxWidth,codeBlockProps:I.codeBlockProps,mermaidProps:I.mermaidProps,d2Props:I.d2Props,infographicProps:I.infographicProps,showTooltips:we.value,themes:I.themes,langs:I.langs,isDark:I.isDark,typewriter:f.value,smoothStreamingOptions:I.smoothStreamingOptions,parseCoalesceMs:I.parseCoalesceMs,fade:I.fade}));Ln("markstreamNestedRendererProps",uo);const Ys=R(()=>St.value),Nn=R(()=>St.value.length),no=Z(null),$s=Z(null),Xs=Z(null),ci=Z(null),Oo=o.indexKey!=null&&String(o.indexKey).startsWith("list-item-"),vo=!Oo&&I.customId?G_(I.customId):null,Po=R(()=>vo?(o4.value,G_(I.customId)):null),co=R(()=>{var L;return!!(!Y.value&&I.customId&&!Oo&&((L=Po.value)!=null&&L.enabled))}),Tn=R(()=>!!(G&&co.value)),fo=R(()=>{var L;return!!(!Y.value&&((L=o.virtualScroll)!=null&&L.enabled))}),Qe=R(()=>fo.value),st=Z(!1);dn(()=>{st.value=!0});const Ct=R(()=>!!(G&&fo.value));Ln("markstreamHostScrollManaged",Ct);const Qt=R(()=>!!(st.value&&Ct.value)),kn=R(()=>Tn.value||Ct.value),Ko=R(()=>Tn.value||Qt.value),Eo=R(()=>{var L;return kn.value&&((L=Po.value)==null?void 0:L.textEstimation)!==!1});function bo(){const L=ne.value||qt("getMeasuredContainerWidth.clientWidth",()=>{var q;return((q=O.value)==null?void 0:q.clientWidth)||0});return Number.isFinite(L)&&L>0?L:0}const Ns=R(()=>{const L=bo();return L>0?Math.max(1,Math.round(L)):640}),Do=R(()=>{var L,q;return!(Oe.value!==!0||fo.value||c.value!=="chat"&&c.value!=="minimal"||a("maxLiveNodes")||a("liveNodeBuffer")||(L=o.nodes)!=null&&L.length||Bt.value||!(((q=I.maxLiveNodes)!=null?q:0)<=0))}),Io=R(()=>{var L;return Do.value?50:Math.max(1,(L=I.maxLiveNodes)!=null?L:320)}),Qo=R(()=>{var L;return Do.value?16:Math.max(0,(L=I.liveNodeBuffer)!=null?L:60)}),sn=R(()=>{var L;return!Y.value&&I.nodeVirtual!==!1&&!(((L=I.maxLiveNodes)!=null?L:0)<=0&&!Do.value)&&(I.nodeVirtual===!0?St.value.length>0:St.value.length>Io.value)}),es=R(()=>sn.value||Tn.value||Ct.value),ms=R(()=>I.viewportPriority!==!1),Tr=R(()=>!!ms.value&&!K.value);var ts;ts=R(()=>ms.value),Ln(k$,ts);const Ki=R(()=>{var L;return!(Y.value||I.deferNodesUntilVisible===!1||((L=I.maxLiveNodes)!=null?L:0)<=0||sn.value||St.value.length>900||I.viewportPriority===!1)}),Js=Nde(L=>{var q;return ce((q=L??O.value)!=null?q:null)},ms),{requestFrame:Bo,cancelFrame:Zo,hasIdleCallback:Il,isTestEnv:Zi}=(function(L){const q=L.isClient&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame.bind(window):null,re=L.isClient&&typeof window.cancelAnimationFrame=="function"?window.cancelAnimationFrame.bind(window):null,ae=L.isClient&&typeof window.requestIdleCallback=="function",be=(function(){var Ne;if(typeof globalThis>"u"||!("process"in globalThis))return;const De=(Ne=Object.getOwnPropertyDescriptor(globalThis,"process"))==null?void 0:Ne.value;return De?.env})();return{requestFrame:q,cancelFrame:re,hasIdleCallback:ae,isTestEnv:be?.NODE_ENV==="test"}})({isClient:G}),tl=R(()=>Oe.value===!0&&!fo.value),{resolvedBatchSize:Ho,resolvedInitialBatch:Co,batchingEnabled:Fs,incrementalRenderingActive:Rs,renderedCount:yo,previousRenderContext:ht,adaptiveBatchSize:Le,previousBatchConfig:Ze}=(function(L,q){var re;const ae=R(()=>{var nt;const Be=Math.trunc((nt=L.renderBatchSize)!=null?nt:80);return Number.isFinite(Be)?Math.max(0,Be):0}),be=R(()=>{var nt;const Be=Math.trunc((nt=L.initialRenderBatchSize)!=null?nt:ae.value);return Number.isFinite(Be)?Math.max(0,Be):ae.value}),Ne=R(()=>!q.renderAsFragment.value&&L.batchRendering!==!1&&ae.value>0&&q.isClient&&!q.isTestEnv),De=Z(0),je=Z({key:L.indexKey,total:0}),ot=Z(Math.max(1,ae.value||1)),Ve=R(()=>{var nt,Be,Xe;return Ne.value&&!((nt=q.continuousStreaming)!=null&&nt.value)&&!((Be=q.forceFullRenderFinalContent)!=null&&Be.value)&&((Xe=L.maxLiveNodes)!=null?Xe:0)<=0}),Ye=Z({batchSize:ae.value,initial:be.value,delay:(re=L.renderBatchDelay)!=null?re:16,enabled:Ve.value});return{resolvedBatchSize:ae,resolvedInitialBatch:be,batchingEnabled:Ne,incrementalRenderingActive:Ve,renderedCount:De,previousRenderContext:je,adaptiveBatchSize:ot,previousBatchConfig:Ye}})(I,{isClient:G,isTestEnv:Zi,renderAsFragment:Y,forceFullRenderFinalContent:tl,continuousStreaming:R(()=>Tt.value&&Oe.value!==!0)}),Xt=R(()=>{var L;return!Y.value&&I.batchRendering!==!1&&Ho.value>0&&!Zi&&((L=I.maxLiveNodes)!=null?L:0)<=0&&!tl.value}),gs=R(()=>Xt.value),di=R(()=>kn.value||gs.value),Ei=R(()=>{var L;return di.value&&((L=Po.value)==null?void 0:L.codeBlockEstimation)!==!1}),ao=new Map,Gi=new Map,Er=new WeakMap;let fi=null;const Ll=new WeakMap,zo=new Map,Ir=[];let Qs=[],pi=[],se=-1;const xe=Xr(Ir),J=new Set,Ce=Z(0);let $e=0;const He=Z(0),vt=R(()=>(He.value,Array.from(ao.entries()).sort((L,q)=>L[0]-q[0]))),ut=Z(null),Dt=Z(null);let Et,ln=null,oo=0,Ot=null;function Pt(){Et.markFallbackHeightPrefixDirty()}function Yn(L){return Et.getFallbackNodeHeight(L)}function ko(L,q){return Et.estimateHeightRange(L,q)}function vs(L){return Et.estimateIndexForOffset(L)}const{activeRestoreAnchor:Os,getRelativeScrollTopWithinContainer:ei,setRelativeScrollTopWithinContainer:Lc,resolveAnchorOffset:U2,clearRestoreReconcile:$c,scheduleRestoreReconcile:yu,captureRestoreAnchor:Nc,restoreAnchor:Fc,getAnchorDrift:j2}=(function(L){const{isClient:q,containerRef:re,parsedNodeCount:ae,requestFrame:be,cancelFrame:Ne,resolveScrollContainer:De,getNormalizedScrollTop:je,getOffsetTopWithinRoot:ot,isReverseFlexScrollRoot:Ve,estimateIndexForOffset:Ye,estimateHeightRange:nt,getFallbackNodeHeight:Be,clamp:Xe}=L,lt=Z(null);let rt=null,wt=[];function dt(){const Kt=De(),fn=re.value;if(!Kt||!fn)return null;const vn=Kt.ownerDocument||fn.ownerDocument||document;if(Kt===vn.documentElement||Kt===vn.body||Kt===vn.scrollingElement){const Qn=fn.getBoundingClientRect();return Math.max(0,-Qn.top)}return Math.max(0,je(Kt,vn,!1)-ot(fn,Kt))}function Ft(Kt){var fn;const vn=De(),Qn=re.value;if(!vn||!Qn)return;const Hs=Math.max(0,Kt),Ss=vn.ownerDocument||Qn.ownerDocument||document,$r=Ss.defaultView||(typeof window<"u"?window:null);if(vn===Ss.documentElement||vn===Ss.body||vn===Ss.scrollingElement){const il=je(vn,Ss,!0)+Qn.getBoundingClientRect().top;return void((fn=$r?.scrollTo)==null||fn.call($r,0,Math.max(0,il+Hs)))}J_(vn,Ss,ot(Qn,vn)+Hs,{isReverseFlexScrollRoot:il=>{var K1;return(K1=Ve?.(il))!=null&&K1},getNormalizedScrollTop:je})}function Ht(Kt){const fn=ae.value,vn=Xe(Kt.nodeIndex,0,Math.max(0,fn-1));return nt(0,vn)+Math.max(0,Kt.offsetWithinNodePx)}function Vt(){if(rt!=null&&(Ne?.(rt),rt=null),q)for(const Kt of wt)window.clearTimeout(Kt);wt=[]}function Wt(Kt){const fn=Ht(Kt),vn=dt();vn!=null&&Math.abs(vn-fn)<=.5||Ft(fn)}return{activeRestoreAnchor:lt,getRelativeScrollTopWithinContainer:dt,setRelativeScrollTopWithinContainer:Ft,resolveAnchorOffset:Ht,clearRestoreReconcile:Vt,applyRestoreAnchor:Wt,scheduleRestoreReconcile:function(){lt.value&&q&&rt==null&&(rt=be?be(()=>{rt=null,lt.value&&Wt(lt.value)}):null,rt==null&<.value&&Wt(lt.value))},captureRestoreAnchor:function(){const Kt=dt(),fn=ae.value;if(Kt==null||fn<=0)return null;const vn=Xe(Ye(Kt+1),0,fn-1),Qn=nt(0,vn),Hs=Be(vn);return{nodeIndex:vn,offsetWithinNodePx:Xe(Kt-Qn,0,Math.max(0,Hs-1))}},restoreAnchor:function(Kt){const fn=ae.value;if(lt.value={nodeIndex:Xe(Kt.nodeIndex,0,Math.max(0,fn-1)),offsetWithinNodePx:Math.max(0,Kt.offsetWithinNodePx)},Vt(),Wt(lt.value),q)for(const vn of[0,120,280,480])wt.push(window.setTimeout(()=>{lt.value&&Wt(lt.value)},vn))},getAnchorDrift:function(Kt){const fn=dt();return fn==null?null:fn-Ht(Kt)}}})({isClient:G,containerRef:O,parsedNodeCount:Nn,requestFrame:Bo,cancelFrame:Zo,resolveScrollContainer:()=>ut.value||ue(),getNormalizedScrollTop:ze,getOffsetTopWithinRoot:_e,isReverseFlexScrollRoot:Se,estimateIndexForOffset:vs,estimateHeightRange:ko,getFallbackNodeHeight:Yn,clamp:Bs}),{nodeHeights:$l,heightStats:hi,heightTreeSize:x1,heightSumTree:a0,heightKnownTree:u0,averageNodeHeight:S1,resetHeightMeasurements:c0,pruneHeightMeasurements:d0,rebuildHeightTrees:Rc,recordNodeHeight:V2,removeNodeHeights:q2,exportHeightCache:ke,importHeightCache:Ae,fenwickRangeSum:Ke}=(function(L={}){const q=Go({}),re=Go({total:0,count:0}),ae=Z(0),be=Z([]),Ne=Z([]);function De(){for(const Be of Object.keys(q))delete q[Number(Be)];re.total=0,re.count=0,ae.value=0,be.value=[],Ne.value=[]}function je(Be,Xe,lt){for(let rt=Xe+1;rt<Be.length;rt+=rt&-rt)Be[rt]+=lt}function ot(Be,Xe){let lt=0;for(let rt=Xe+1;rt>0;rt-=rt&-rt)lt+=Be[rt];return lt}function Ve(Be){ae.value=Be;const Xe=new Array(Be+1).fill(0),lt=new Array(Be+1).fill(0);for(const[rt,wt]of Object.entries(q)){const dt=Number(rt),Ft=Number(wt);!Number.isFinite(dt)||dt<0||dt>=Be||!Number.isFinite(Ft)||Ft<=0||(je(Xe,dt,Ft),je(lt,dt,1))}be.value=Xe,Ne.value=lt}function Ye(Be){if(!Number.isInteger(Be)||Be<0)return!1;const Xe=q[Be];if(!Number.isFinite(Xe)||Xe<=0)return!1;if(delete q[Be],re.total=Math.max(0,re.total-Xe),re.count=Math.max(0,re.count-1),ae.value>Be){const lt=be.value,rt=Ne.value;lt.length&&rt.length&&(je(lt,Be,-Xe),je(rt,Be,-1))}return!0}const nt=R(()=>re.count>0?Math.max(12,re.total/re.count):32);return{nodeHeights:q,heightStats:re,heightTreeSize:ae,heightSumTree:be,heightKnownTree:Ne,averageNodeHeight:nt,resetHeightMeasurements:De,pruneHeightMeasurements:function(Be){if(Be<=0)return void De();let Xe=0,lt=0;for(const[rt,wt]of Object.entries(q)){const dt=Number(rt),Ft=Number(wt);!Number.isFinite(dt)||dt<0||dt>=Be||!Number.isFinite(Ft)||Ft<=0?delete q[dt]:(Xe+=Ft,lt++)}re.total=Xe,re.count=lt},rebuildHeightTrees:Ve,recordNodeHeight:function(Be,Xe,lt={}){(function(rt,wt,dt={}){var Ft;if(!Number.isFinite(wt)||wt<=0)return!1;const Ht=q[rt];if(Ht&&(dt.allowShrink===!1&&wt<Ht||Math.abs(wt-Ht)<=1))return!1;if(q[rt]=wt,Ht?re.total+=wt-Ht:(re.total+=wt,re.count++),ae.value>rt){const Vt=be.value,Wt=Ne.value;if(Vt.length&&Wt.length)if(Ht){const Kt=wt-Ht;Kt!==0&&je(Vt,rt,Kt)}else je(Vt,rt,wt),je(Wt,rt,1)}dt.notify!==!1&&((Ft=L.onHeightRecorded)==null||Ft.call(L))})(Be,Xe,rn(mt({},lt),{notify:!0}))},removeNodeHeight:function(Be,Xe={}){var lt;const rt=Ye(Be);return rt&&Xe.notify!==!1&&((lt=L.onHeightRecorded)==null||lt.call(L)),rt},removeNodeHeights:function(Be,Xe={}){var lt;let rt=0;for(const wt of Be)Ye(Number(wt))&&rt++;return rt>0&&Xe.notify!==!1&&((lt=L.onHeightRecorded)==null||lt.call(L)),rt},exportHeightCache:function(){return Object.entries(q).map(([Be,Xe])=>({index:Number(Be),height:Number(Xe)})).filter(Be=>Number.isFinite(Be.index)&&Be.index>=0&&Number.isFinite(Be.height)&&Be.height>0).sort((Be,Xe)=>Be.index-Xe.index)},importHeightCache:function(Be,Xe={}){var lt;if(!Array.isArray(Be))return;const rt=ae.value;let wt=!1;if(Xe.mode!=="merge"){const dt=Object.keys(q);if(dt.length>0){for(const Ft of dt)delete q[Number(Ft)];wt=!0}}for(const dt of Be){const Ft=Number(dt.index),Ht=Number(dt.height);if(!Number.isInteger(Ft)||Ft<0||rt>0&&Ft>=rt||!Number.isFinite(Ht)||Ht<=0)continue;const Vt=q[Ft];Vt&&Math.abs(Vt-Ht)<=1||(q[Ft]=Ht,wt=!0)}wt&&((function(){let dt=0,Ft=0;const Ht=ae.value;for(const[Vt,Wt]of Object.entries(q)){const Kt=Number(Vt),fn=Number(Wt);!Number.isFinite(Kt)||Kt<0||Ht>0&&Kt>=Ht||!Number.isFinite(fn)||fn<=0?delete q[Kt]:(dt+=fn,Ft++)}re.total=dt,re.count=Ft})(),rt>0&&Ve(rt),(lt=L.onHeightRecorded)==null||lt.call(L))},fenwickRangeSum:function(Be,Xe,lt){if(lt<=Xe)return 0;const rt=ot(Be,lt-1);return Xe<=0?rt:rt-ot(Be,Xe-1)}}})({onHeightRecorded:()=>{Pt(),Ct.value&&z1(),Os.value&&yu(),Dt.value&&Uc(),po("node-resize")}});function Mt(L){Number.isInteger(L)&&L>=0&&J.add(L)}function Gt(L){for(const q of L)Mt(Number(q))}function an(L){$e++;let q=!0;try{const re=L();return q=re!==!1,re}finally{$e--,$e===0&&q&&Ce.value++}}function Fn(){Qs=[],pi=[],se=-1,J.clear(),xe.value=Ir}function so(){Fn(),an(()=>c0()),zo.clear()}function Ps(L){!Number.isInteger(L)||L<0||L>=St.value.length||zo.set(L,I1(L))}function ku(L,q,re={}){const ae=$l[L];Mt(L),V2(L,q,re);const be=$l[L];return Object.is(ae,be)?(J.delete(L),!1):(be&&be>0?Ps(L):ae&&zo.delete(L),!0)}function A1(L,q){const re=qt("getNodeLayoutHeight.slot.offsetHeight",()=>{var ae,be;return(be=(ae=ao.get(L))==null?void 0:ae.offsetHeight)!=null?be:0});return re>0?re:qt("getNodeLayoutHeight.content.offsetHeight",()=>q.offsetHeight)}function a6(L,q={}){q.mode!=="merge"?Fn():Gt(L.map(re=>re.index)),an(()=>Ae(L,q)),bv()}const nl=R(()=>Ki.value&&Tr.value),wF=R(()=>{var L;return!Y.value&&I.batchRendering!==!1&&Ho.value>0&&((L=I.maxLiveNodes)!=null?L:0)<=0}),_F=R(()=>!Y.value&&Ge&&Oe.value===!0&&!sn.value&&!fo.value&&!co.value&&!nl.value&&!wF.value),u6=R(()=>!!Js&&nl.value),c6=R(()=>sn.value||Ct.value),{focusIndex:Nl,liveRange:Ds,updateLiveRange:M1}=(function(L,q){const{parsedNodeCount:re,virtualizationEnabled:ae,maxLiveNodesResolved:be,liveNodeBufferResolved:Ne,clamp:De}=q,je=Ne??R(()=>{var Ye;return Math.max(0,(Ye=L.liveNodeBuffer)!=null?Ye:60)}),ot=Z(0),Ve=Go({start:0,end:0});return{liveNodeBufferResolved:je,focusIndex:ot,liveRange:Ve,updateLiveRange:function(){const Ye=re.value;if(!ae.value||Ye===0)return Ve.start=0,void(Ve.end=Ye);const nt=Math.min(be.value,Ye),Be=je.value,Xe=De(ot.value-Be,0,Math.max(0,Ye-nt));Ve.start=Xe,Ve.end=Math.min(Ye,Xe+nt)}}})(I,{parsedNodeCount:Nn,virtualizationEnabled:sn,maxLiveNodesResolved:Io,liveNodeBufferResolved:Qo,clamp:Bs}),ol=new Map,bu=new Map,da=new Map,f0=[],Fl=new Map,fa=new Set,d6=Z(0);let K2=!1;const f6=R(()=>(d6.value,fa.size)),Yi=new Map,sl=new Map,p6=Z(0),Z2=R(()=>{p6.value;let L=0;for(const q of Yi.values())L+=Math.max(0,q);return L});let Xi=null;const p0=R(()=>{if(!sn.value)return St.value.length;const L=Qo.value,q=Math.max(Ds.end+L,Co.value),re=Math.min(St.value.length,q);return Math.max(yo.value,re)});function h0(){K2||(K2=!0,queueMicrotask(()=>{K2=!1,d6.value+=1}))}function h6(L,q,re="node-resize"){if(!G||typeof window>"u")return null;const ae=window.setTimeout(()=>{fa.delete(ae)&&h0();try{q()}finally{po(re)}},Math.max(0,L));return fa.add(ae),h0(),ae}function m0(L){G&&L!=null&&(fa.delete(L)&&h0(),window.clearTimeout(L))}function m6(){if(G&&typeof window<"u")for(const L of fa)window.clearTimeout(L);fa.size&&(fa.clear(),h0()),f0.length=0,da.clear()}function xF(L){F.value=L}function SF(L){U.value=L}function AF(L){z.value=L}const{cancelScheduledFocusSync:G2,scheduleFocusSync:Lr}=(function(L){const{isClient:q,containerRef:re,virtualizationEnabled:ae,requestFrame:be,cancelFrame:Ne,syncFocusToScroll:De}=L;let je=null;function ot(){var Ye,nt,Be;return(Be=(nt=(Ye=re.value)==null?void 0:Ye.ownerDocument)==null?void 0:nt.defaultView)!=null?Be:typeof window<"u"?window:null}function Ve(){if(!je)return;const Ye=ot();je.viaTimeout?Ye?Ye.clearTimeout(je.id):clearTimeout(je.id):Ne?.(je.id),je=null}return{cancelScheduledFocusSync:Ve,scheduleFocusSync:function(Ye={}){if(!ae.value)return;if(!q)return void De(!0);if(Ye.immediate)return Ve(),void De(!0);if(je)return;const nt=()=>{je=null,De()};if(be)return void(je={id:be(nt),viaTimeout:!1});const Be=ot();je={id:Be?Be.setTimeout(nt,16):setTimeout(nt,16),viaTimeout:!0}}}})({isClient:G,containerRef:O,virtualizationEnabled:sn,requestFrame:Bo,cancelFrame:Zo,syncFocusToScroll:function(L=!1){var q;if(!sn.value)return;const re=ut.value||ue();if(!re)return;const ae=re.ownerDocument||((q=O.value)==null?void 0:q.ownerDocument)||document,be=ae?.defaultView||(typeof window<"u"?window:null),Ne=re===ae?.documentElement||re===ae?.body,De=St.value.length;if(De<=0)return;if(!Ne&&De>0&&Se(re)){const rt=qt("syncFocusToScroll.clientHeight",()=>re.clientHeight||0),wt=qt("syncFocusToScroll.scrollTop",()=>re.scrollTop),dt=wt<0?-wt:wt;return void y0(Bs((je=Math.max(0,dt)+.5*Math.max(0,rt),Et.estimateIndexForOffsetFromEnd(je)),0,Math.max(0,De-1)),L)}var je;const ot=(function(rt,wt,dt,Ft){const Ht=O.value;if(!Ht)return null;const Vt=Ft?0:qt("syncFocusToScroll.model.root.getBoundingClientRect",()=>rt.getBoundingClientRect().top),Wt=qt("syncFocusToScroll.model.container.getBoundingClientRect",()=>Ht.getBoundingClientRect().top),Kt=Math.max(0,Vt-Wt),fn=Ft?qt("syncFocusToScroll.model.viewport.clientHeight",()=>{var vn,Qn,Hs,Ss;return(Ss=(Hs=(Qn=dt?.innerHeight)!=null?Qn:(vn=wt.documentElement)==null?void 0:vn.clientHeight)!=null?Hs:rt.clientHeight)!=null?Ss:0}):qt("syncFocusToScroll.model.root.clientHeight",()=>rt.clientHeight);return Bs(vs(Kt+.5*Math.max(0,fn)),0,Math.max(0,St.value.length-1))})(re,ae,be,Ne);if(ot!=null)return void y0(ot,L);const Ve=Ne?null:qt("syncFocusToScroll.root.getBoundingClientRect",()=>re.getBoundingClientRect()),Ye=Ne?0:Ve.top,nt=Ne?qt("syncFocusToScroll.viewport.clientHeight",()=>{var rt,wt;return(wt=(rt=be?.innerHeight)!=null?rt:re.clientHeight)!=null?wt:0}):Ve.bottom,Be=vt.value;let Xe=null,lt=null;for(const[rt,wt]of Be){if(!wt)continue;const dt=qt("syncFocusToScroll.slot.getBoundingClientRect",()=>wt.getBoundingClientRect());dt.bottom<=Ye||dt.top>=nt||(Xe==null&&(Xe=rt),lt=rt)}if(Xe==null||lt==null){const rt=O.value;if(!rt)return;const wt=Ne?{top:0}:qt("syncFocusToScroll.fallback.root.getBoundingClientRect",()=>re.getBoundingClientRect()),dt=qt("syncFocusToScroll.fallback.scrollTop",()=>ze(re,ae,Ne)),Ft=Ne?(()=>{const Vt=qt("syncFocusToScroll.fallback.container.getBoundingClientRect",()=>rt.getBoundingClientRect()),Wt=(Ne?0:wt.top)-Vt.top;return Math.max(0,Wt)})():(()=>{const Vt=_e(rt,re);return Math.max(0,dt-Vt)})(),Ht=Ne?qt("syncFocusToScroll.fallback.viewport.clientHeight",()=>{var Vt,Wt,Kt,fn;return(fn=(Kt=(Wt=be?.innerHeight)!=null?Wt:(Vt=ae?.documentElement)==null?void 0:Vt.clientHeight)!=null?Kt:re.clientHeight)!=null?fn:0}):qt("syncFocusToScroll.fallback.root.clientHeight",()=>re.clientHeight);return void y0(Bs(vs(Ft+.5*Math.max(0,Ht)),0,Math.max(0,St.value.length-1)),!0)}y0(Math.round((Xe+lt)/2),L)}}),{visibleNodeIndices:Y2,nodeVisibilityHandles:Oc,nodeVisibilityWatchStops:g0,nodeVisibilityFallbackTimers:g6,clearVisibilityFallback:v0,markNodeVisible:pa,cleanupNodeVisibility:MF,destroyNodeVisibilityState:X2}=epe({isClient:G,shouldTrackVisibleNodeIndices:()=>nl.value,shouldCleanupNodeVisibility:()=>sn.value,onNodeMarkedVisible:L=>{sn.value?Lr():Nl.value=Bs(L,0,Math.max(0,St.value.length-1))},onNodeVisibilityCleaned:L=>{ao.delete(L)&&j6()}}),{cleanupScrollListener:v6,setupScrollListener:TF}=(function(L){const{isClient:q,virtualizationEnabled:re,listenerEnabled:ae,scrollRootElement:be,resolveScrollContainer:Ne,scheduleFocusSync:De,onScroll:je}=L;let ot=null,Ve=null;function Ye(){ot&&(ot(),ot=null),Ve=null,be.value=null}function nt(Be){const Xe=L.getScrollTop?L.getScrollTop(Be):Be.scrollTop;return Math.max(0,Number.isFinite(Xe)?Math.abs(Xe):0)}return{cleanupScrollListener:Ye,setupScrollListener:function(){if(!q)return;if(!((Be=ae?.value)!=null?Be:re.value))return void Ye();var Be;const Xe=Ne();if(!Xe)return void Ye();if(be.value===Xe&&ot)return;Ye(),Ve=nt(Xe);const lt=()=>{if(je?.(),re.value){const rt=(function(wt){const dt=nt(wt),Ft=Ve;Ve=dt;const Ht=Math.max(480,.75*(wt.clientHeight||0));return Ft==null?dt>Ht?{immediate:!0}:void 0:Math.abs(dt-Ft)>Ht?{immediate:!0}:void 0})(Xe);rt?De(rt):De()}};Xe.addEventListener("scroll",lt,{passive:!0}),be.value=Xe,ot=()=>{Xe.removeEventListener("scroll",lt)}}}})({isClient:G,virtualizationEnabled:sn,listenerEnabled:c6,scrollRootElement:ut,resolveScrollContainer:ue,scheduleFocusSync:Lr,onScroll:function(){const L=Dt.value;if(!L)return;const q=E1();if(!q||(function(ae){if(R1()>=oo)return Ot=null,!1;const be=Ot;if(be==null)return!0;const Ne=Math.abs(ae.scrollTop-be)<=2;return Ne||(Ot=null),Ne})(q))return;const re=$6(q);re!=null?(re<-32||Math.abs(Math.max(0,re)-Math.max(0,L.distanceFromBottomPx))>32)&&Wc("restore"):Wc("restore")},getScrollTop:L=>{var q;const re=L.ownerDocument||((q=O.value)==null?void 0:q.ownerDocument)||document,ae=L===re.documentElement||L===re.body||L===re.scrollingElement;return qt("scrollListener.getScrollTop",()=>ze(L,re,ae))}});function y0(L,q=!1){const re=Bs(L,0,Math.max(0,St.value.length-1));!q&&Math.abs(re-Nl.value)<=1||(Nl.value=re,M1())}function Bs(L,q,re){return Math.min(Math.max(L,q),re)}function J2(L=St.value.length){const q=hs();return!Number.isInteger(q)||q<0?L:Bs(q,0,L)}function Q2(L){return L?.firstElementChild}function y6(L,q){var re;return L?(re=L.matches)!=null&&re.call(L,q)?L:L.querySelector(q):null}function EF(L,q){L<1||L>6||(W[L]=q)}function k6(){if(!kn.value)return void(ne.value=0);const L=qt("updateExperimentContainerWidth.clientWidth",()=>{var q,re;return(re=(q=O.value)==null?void 0:q.clientWidth)!=null?re:0});ne.value=L>0?L:0}let T1=null;function ev(){T1?.disconnect(),T1=null}const b6=Af("ViewportDeferredMarkdownCodeBlockNode",zr({loader:()=>mo(null,null,function*(){return(yield jo(()=>import("./index5-Cn2jfVMX.js"),__vite__mapDeps([6,4,5]))).default}),loadingComponent:dg,delay:0,suspensible:!1}),dg);function C6(L){return L===b6}const w6=R(()=>m.value==="pre"?Pi:m.value==="shiki"?b6:X9);function _6(){var L;return((L=I.codeBlockProps)==null?void 0:L.showHeader)!==!1}function x6(L,q,re){const ae=$l[q],be=typeof ae=="number"&&ae>0;if(Eo.value&&!be&&!(function(Ne){return!!In.value.paragraph&&(Ne.type==="paragraph"||Ne.type==="list_item"||Ne.type==="list")})(L)){const Ne=S$(L,re,X.value);if(Ne)return Ne}if(Ei.value&&L.type==="code_block"){const Ne=(function(De){if(De.type!=="code_block")return null;const je=n7(De,T0(De));return C6(je)?"markdown":je===Pi?"pre":je===w6.value||je===X9?"monaco":null})(L);if(Ne==="monaco"||Ne==="markdown"||Ne==="pre")return(function(De,je){var ot,Ve,Ye;if(!De||De.type!=="code_block")return null;const nt=je.rendererKind,Be=nt!=="pre"&&je.showHeader!==!1,Xe=!!De.diff;let lt=0,rt=500;if(nt==="monaco"){const dt=(ot=je.monacoOptions)!=null?ot:{},Ft=r4(De,dt,je.width),Ht=(function(Wt){const Kt=typeof Wt?.fontSize=="number"&&Wt.fontSize>0?Wt.fontSize:12;return typeof Wt?.lineHeight=="number"&&Wt.lineHeight>0?Wt.lineHeight:Math.round(1.5*Kt)})(dt),Vt=(function(Wt,Kt){var fn,vn;const Qn=typeof((fn=Wt?.padding)==null?void 0:fn.top)=="number"?Wt.padding.top:Kt?0:8,Hs=typeof((vn=Wt?.padding)==null?void 0:vn.bottom)=="number"?Wt.padding.bottom:Kt?0:8;return Math.max(0,Qn)+Math.max(0,Hs)})(dt,Xe);rt=typeof dt.MAX_HEIGHT=="number"&&dt.MAX_HEIGHT>0?dt.MAX_HEIGHT:500,lt=Math.round(Ft*Ht+Vt)}else if(nt==="markdown"){const dt=r4(De);lt=Math.round(21*dt+32)}else{const dt=r4(De);lt=Math.round(28*dt),rt=Number.POSITIVE_INFINITY}const wt=Math.max(1,Math.min(lt,rt));return mt({kind:"code-block",height:Math.round(wt+(Be?40:0)),contentHeight:wt,rendererKind:nt},Xe&&nt==="monaco"?{diffInline:v5((Ve=je.monacoOptions)!=null?Ve:{},(Ye=je.width)!=null?Ye:0)}:{})})(L,{rendererKind:Ne,monacoOptions:I.codeBlockMonacoOptions,showHeader:_6(),width:re})}return null}I4(()=>{if(Ce.value,$e>0)return;const L=St.value,q=Jo();if(!L.length||!di.value)return Qs=[],pi=[],se=-1,J.clear(),void(xe.value=Ir);const re=ne.value||qt("estimatedNodeHeights.clientWidth",()=>{var Ve;return((Ve=O.value)==null?void 0:Ve.clientWidth)||0});if(!Number.isFinite(re)||re<=0)return Qs=[],pi=[],se=-1,J.clear(),void(xe.value=Ir);const ae=(function(Ve){return[Math.round(Ve),Eo.value,Ei.value,X.value,I.codeBlockMonacoOptions,_6(),m.value,In.value,o4.value]})(re),be=Qs.length<=L.length&&(De=ae,(Ne=pi).length===De.length&&Ne.every((Ve,Ye)=>Object.is(Ve,De[Ye])));var Ne,De;const je=be&&se===q?L.length:be?J2(L.length):0,ot=be?Array.from(J):[];Qs.length=L.length;for(let Ve=je;Ve<L.length;Ve++)Qs[Ve]=x6(L[Ve],Ve,re);for(const Ve of ot)Ve>=0&&Ve<L.length&&Ve<je&&(Qs[Ve]=x6(L[Ve],Ve,re));J.clear(),pi=ae,se=q,xe.value=Qs,GR(xe)},{flush:"sync"});const Pc=R(()=>xe.value);Et=(function(L){let q=!0,re=[0],ae="";function be(Ye){var nt;const Be=L.nodeHeights[Ye];if(Number.isFinite(Be)&&Be>0)return Be;const Xe=L.parsedNodes.value[Ye],lt=Xe?.type,rt=!!((nt=L.hasCustomParagraphComponent)!=null&&nt.call(L)),wt=L.estimatedNodeHeights.value[Ye],dt=wt?.height;if(!(function(Ht,Vt,Wt){return!!(Wt&&Vt?.kind==="simple-text"&&(Ht==="paragraph"||Ht==="list_item"||Ht==="list"))})(lt,wt,rt)&&Number.isFinite(dt)&&dt>0)return dt;const Ft=Wfe(Xe,L.getContainerWidth()||640);return lt==="heading"||lt==="paragraph"&&Ft<=28&&(function(Ht,Vt){if(Vt)return!1;const Wt=Ht.children;return!Array.isArray(Wt)||!Wt.length||Wt.every(M$)})(Xe,rt)?Ft:Math.max(L.averageNodeHeight.value,Ft)}function Ne(){var Ye;const nt=L.parsedNodes.value.length,Be=L.getPrefixCacheKeyParts().join(":");if(!q&&ae===Be)return re;const Xe=new Array(nt+1);Xe[0]=0;for(let lt=0;lt<nt;lt++)Xe[lt+1]=Xe[lt]+(L.heightEstimationActive.value?be(lt):(Ye=L.nodeHeights[lt])!=null?Ye:L.averageNodeHeight.value);return re=Xe,ae=Be,q=!1,Xe}function De(Ye){var nt,Be;const Xe=L.parsedNodes.value.length;if(Xe<=0||Ye<=0)return 0;const lt=Ne();if(Ye>=((nt=lt[Xe])!=null?nt:0))return Xe-1;let rt=0,wt=Xe-1,dt=Xe-1;for(;rt<=wt;){const Ft=rt+wt>>1;((Be=lt[Ft+1])!=null?Be:0)>=Ye?(dt=Ft,wt=Ft-1):rt=Ft+1}return dt}function je(Ye,nt){var Be,Xe;if(Ye>=nt)return 0;if(L.heightEstimationActive.value)return(function(wt,dt){var Ft,Ht;const Vt=L.parsedNodes.value.length,Wt=tx(Math.trunc(wt),0,Vt),Kt=tx(Math.trunc(dt),Wt,Vt);if(Wt>=Kt)return 0;const fn=Ne();return((Ft=fn[Kt])!=null?Ft:0)-((Ht=fn[Wt])!=null?Ht:0)})(Ye,nt);if(L.heightTreeSize.value!==L.parsedNodes.value.length){let wt=0;for(let dt=Ye;dt<nt;dt++)wt+=(Be=L.nodeHeights[dt])!=null?Be:L.averageNodeHeight.value;return wt}const lt=L.heightSumTree.value,rt=L.heightKnownTree.value;if(!lt.length||!rt.length){let wt=0;for(let dt=Ye;dt<nt;dt++)wt+=(Xe=L.nodeHeights[dt])!=null?Xe:L.averageNodeHeight.value;return wt}return L.fenwickRangeSum(lt,Ye,nt)+(nt-Ye-L.fenwickRangeSum(rt,Ye,nt))*L.averageNodeHeight.value}function ot(Ye){var nt;if(Ye<=0)return 0;const Be=L.parsedNodes.value;if(L.heightEstimationActive.value)return De(Ye);if(L.heightTreeSize.value===Be.length&&L.heightSumTree.value.length&&L.heightKnownTree.value.length){const lt=L.averageNodeHeight.value,rt=L.heightSumTree.value,wt=L.heightKnownTree.value,dt=Wt=>Wt<=0?0:L.fenwickRangeSum(rt,0,Wt)+(Wt-L.fenwickRangeSum(wt,0,Wt))*lt;let Ft=0,Ht=Be.length-1,Vt=Be.length-1;for(;Ft<=Ht;){const Wt=Ft+Ht>>1;dt(Wt+1)>=Ye?(Vt=Wt,Ht=Wt-1):Ft=Wt+1}return Vt}let Xe=Ye;for(let lt=0;lt<Be.length;lt++){const rt=(nt=L.nodeHeights[lt])!=null?nt:L.averageNodeHeight.value;if(Xe<=rt)return lt;Xe-=rt}return Math.max(0,Be.length-1)}function Ve(){if(!L.heightEstimationActive.value)return 0;let Ye=0;const nt=L.estimatedNodeHeights.value;for(let Be=0;Be<nt.length;Be++){if(!nt[Be])continue;const Xe=L.nodeHeights[Be];Number.isFinite(Xe)&&Xe>0||Ye++}return Ye}return{markFallbackHeightPrefixDirty:function(){q=!0},getFallbackNodeHeight:be,estimateHeightRange:je,estimateIndexForOffset:ot,estimateIndexForOffsetFromEnd:function(Ye){var nt,Be;const Xe=L.parsedNodes.value;if(!Xe.length)return 0;if(Ye<=0)return Math.max(0,Xe.length-1);if(L.heightEstimationActive.value){const rt=(nt=Ne()[Xe.length])!=null?nt:0;return De(Math.max(0,rt-Ye))}if(L.heightTreeSize.value===Xe.length){const rt=je(0,Xe.length);return ot(Math.max(0,rt-Ye))}let lt=Ye;for(let rt=Xe.length-1;rt>=0;rt--){const wt=(Be=L.nodeHeights[rt])!=null?Be:L.averageNodeHeight.value;if(lt<=wt)return rt;lt-=wt}return 0},getEstimatedNodeHeightCount:Ve,buildVirtualHeightSummary:function(Ye){var nt;const Be=L.parsedNodes.value.length;return{totalNodes:Be,measuredCount:L.heightStats.count,estimatedCount:Ve(),averageNodeHeight:L.averageNodeHeight.value,topSpacerHeight:Ye.topSpacerHeight,bottomSpacerHeight:Ye.bottomSpacerHeight,estimatedTotalHeight:je(0,Be),width:(nt=Ye.width)!=null?nt:L.getContainerWidth()}}}})({parsedNodes:St,nodeHeights:$l,heightStats:hi,heightTreeSize:x1,heightSumTree:a0,heightKnownTree:u0,averageNodeHeight:S1,heightEstimationActive:kn,estimatedNodeHeights:Pc,getContainerWidth:bo,hasCustomParagraphComponent:()=>!!In.value.paragraph,getPrefixCacheKeyParts:()=>{var L;const q=uf(ne.value||qt("getFallbackHeightPrefix.clientWidth",()=>{var ae;return((ae=O.value)==null?void 0:ae.clientWidth)||0})),re=((L=o.virtualScroll)==null?void 0:L.measurementKey)==null?"":String(o.virtualScroll.measurementKey);return[St.value.length,hi.count,Math.round(hi.total),Math.round(100*S1.value),re,q,kn.value?1:0,o4.value,ie.value,In.value.paragraph?1:0]},fenwickRangeSum:Ke}),Je(()=>St.value.length,L=>{var q;Pt(),L<=0?so():(L<x1.value&&(q=L,Fn(),an(()=>d0(q))),L!==x1.value&&Rc(L))},{immediate:!0});const IF=R(()=>{if(!sn.value)return St.value.map((ae,be)=>({node:ae,index:be}));const L=St.value.length,q=Bs(Ds.start,0,L),re=Bs(Ds.end,q,L);return St.value.slice(q,re).map((ae,be)=>({node:ae,index:q+be}))}),tv=R(()=>sn.value?ko(0,Math.min(Ds.start,St.value.length)):0),nv=R(()=>{if(!sn.value)return 0;const L=St.value.length;return ko(Math.min(Ds.end,L),L)});function S6(){return Et.buildVirtualHeightSummary({topSpacerHeight:tv.value,bottomSpacerHeight:nv.value,width:Cu()})}function LF(){const L=St.value,q=S6();return rn(mt({},q),{probe:{paragraphReady:!!X.value.paragraph,listItemReady:!!X.value.listItem,listWrapperOverhead:X.value.listWrapperOverhead,headingReadyLevels:Object.entries(X.value.headings).filter(([,re])=>!!re).map(([re])=>Number(re))},nodes:L.map((re,ae)=>{var be,Ne,De,je,ot,Ve,Ye,nt,Be;return{index:ae,type:re.type,estimateKind:(Ne=(be=Pc.value[ae])==null?void 0:be.kind)!=null?Ne:null,rendererKind:(je=(De=Pc.value[ae])==null?void 0:De.rendererKind)!=null?je:null,estimatedHeight:(Ve=(ot=Pc.value[ae])==null?void 0:ot.height)!=null?Ve:null,estimatedContentHeight:(nt=(Ye=Pc.value[ae])==null?void 0:Ye.contentHeight)!=null?nt:null,measuredHeight:(Be=$l[ae])!=null?Be:null}})})}function ov(){return o.indexKey!=null?String(o.indexKey):fo.value?`virtual-${wo()}`:"markdown-renderer"}function A6(L){const q=String(L),re=`${ov()}-`;if(!q.startsWith(re))return null;const ae=q.slice(re.length).match(/^(\d+)(?:$|-)/);if(!ae)return null;const be=Number(ae[1]);return!Number.isInteger(be)||be<0||be>=St.value.length?null:be}function wo(){var L,q,re;const ae=(L=o.virtualScroll)==null?void 0:L.sessionKey;return String(ae!=null&&ae!==""?ae:(re=(q=o.indexKey)!=null?q:I.customId)!=null?re:ps)}function ns(){var L;const q=(L=o.virtualScroll)==null?void 0:L.threadKey;return q==null||q===""?void 0:String(q)}const $F=R(()=>{var L,q,re;return(re=ns())!=null?re:String((q=(L=o.indexKey)!=null?L:I.customId)!=null?q:ps)});function sv(L){var q;return(L??"")===((q=ns())!=null?q:"")}function Rl(){var L,q,re;return q=(L=o.virtualScroll)==null?void 0:L.measurementKey,re=(function(){const ae=m.value;return(function(be){var Ne,De;const je=be.renderer,ot=je==="monaco"?be.codeBlockMonacoOptions:void 0,Ve=be.codeBlockProps,Ye=je==="shiki";return[be.isDark?"dark":"light",je==="monaco"?"code-rich":je==="pre"?"code-pre":"code-shiki",be.codeBlockStream===!1?"code-static":"code-stream",As(be.codeBlockMinWidth),As(be.codeBlockMaxWidth),...Ye?[Lce((Ne=Ve?.themes)!=null?Ne:be.themes,(De=Ve?.langs)!=null?De:be.langs)]:[],As(ot?.fontSize),As(ot?.lineHeight),As(ot?.fontFamily),As(ot?.tabSize),As(ot?.MAX_HEIGHT),As(ot?.wordWrap),As(ot?.wrappingIndent),As(ot?.padding),As(Ve?.showHeader),As(Ve?.showCopyButton),As(Ve?.showExpandButton),As(Ve?.showPreviewButton),As(Ve?.showCollapseButton),As(Ve?.showFontSizeButtons)].join("\0")})({renderer:ae,isDark:I.isDark,codeBlockStream:I.codeBlockStream,codeBlockMinWidth:I.codeBlockMinWidth,codeBlockMaxWidth:I.codeBlockMaxWidth,codeBlockMonacoOptions:ae==="monaco"?I.codeBlockMonacoOptions:void 0,codeBlockProps:I.codeBlockProps,themes:ae==="shiki"?I.themes:void 0,langs:ae==="shiki"?I.langs:void 0})})(),[q==null?"":String(q),re].join("\0")}function Cu(){return bo()}const k0=R(()=>uf(Cu())),Ji=R(()=>[Rl(),k0.value].join("\0")),NF=R(()=>{var L;return fo.value?["virtual",(L=ns())!=null?L:"",wo(),Ji.value].join("\0"):o.indexKey});function Dc(){p6.value+=1}function iv(L){return!(!L||!Number.isInteger(L.index)||L.index<0||L.index>=St.value.length||L.sessionKey!==wo()||L.threadKey!==ns()||L.layoutEpochKey!==Ji.value)}function M6(L){const q=String(L),re=sl.get(q);return re?iv(re)?re.index:null:A6(q)}function T6(L="async-node"){(Yi.size||sl.size)&&(Yi.clear(),sl.clear(),Dc(),po(L))}const Bc=nn(G3,null),rv={reportHeight(L,q){if(!Ct.value)return;const re=M6(L);if(re==null)return;const ae=ol.get(re);if(!ae)return;const be=Number(q),Ne=A1(re,ae);(function(De,je,ot={}){an(()=>ku(De,je,ot))})(re,Number.isFinite(be)&&be>0?Math.max(be,Ne||0):Ne)},markPending(L){if(!Ct.value)return;const q=A6(L);q!=null&&(function(re,ae){var be;const Ne=sl.get(re);if(Ne&&iv(Ne))return Yi.set(re,Math.max(0,(be=Yi.get(re))!=null?be:0)+1),Dc(),void po("async-node");Yi.set(re,1),sl.set(re,(function(De){return{index:De,sessionKey:wo(),threadKey:ns(),layoutEpochKey:Ji.value}})(ae)),Dc(),po("async-node")})(String(L),q)},markSettled(L){if(!Ct.value)return;const q=String(L),re=M6(L);(re!=null||(function(ae){return Yi.has(String(ae))})(q))&&(function(ae){var be;const Ne=(be=Yi.get(ae))!=null?be:0;return!(Ne<=0||(Ne<=1?(Yi.delete(ae),sl.delete(ae)):Yi.set(ae,Ne-1),Dc(),Ne===1&&po("async-node"),0))})(q)&&re!=null&&Ol()}};function FF(){let L=0;for(const q of ol.values())L+=qt("getVisibleDomHeight.offsetHeight",()=>{var re;return(re=q?.offsetHeight)!=null?re:0});return Math.ceil(Math.max(0,L))}Ln(G3,{reportHeight(L,q){rv.reportHeight(L,q),Bc?.reportHeight(L,q)},markPending(L){rv.markPending(L),Bc?.markPending(L)},markSettled(L){rv.markSettled(L),Bc?.markSettled(L)}});let lv,av=null,Hc=null;function b0(L){return L!==!1&&L!=null&&L!==""}function E6(){return sn.value?(function(){if(!sn.value)return!0;const L=St.value.length,q=Bs(Ds.start,0,L),re=Bs(Ds.end,q,L);if(q>=re)return!0;for(let ae=q;ae<re;ae++)if(!ao.has(ae)||x0(ae)&&!ol.has(ae))return!1;return!0})():yo.value>=p0.value}function uv(){return Oe.value===!0&&!at.value&&Z2.value===0&&fa.size===0&&Fl.size===0&&Xi==null&&E6()}function I6(){var L,q;if(((L=o.virtualScroll)==null?void 0:L.settleMode)!=="manual"||av===wo()&&lv===ns())return!0;const re=(q=o.virtualScroll)==null?void 0:q.settledToken;return!!b0(re)&&Hc===W1(re)}function cv(){return uv()&&I6()}function RF(L,q){return q.totalNodes<=0?L==="final"?"final":"estimate":q.measuredCount>=q.totalNodes?L==="final"?"final":"measured":q.measuredCount>0||q.estimatedCount>0?"mixed":"estimate"}function wu(L="manual",q){const re=S6(),ae=(function(be){return be||(Oe.value!==!0?St.value.length>0?"streaming":"estimating":!E6()||Fl.size>0||Xi!=null?"measuring":cv()?"settled":"settling")})(q);return{sessionKey:wo(),threadKey:ns(),phase:ae,nodeCount:re.totalNodes,liveRange:{start:Ds.start,end:Ds.end},renderedCount:yo.value,measuredCount:re.measuredCount,estimatedCount:re.estimatedCount,averageNodeHeight:re.averageNodeHeight,topSpacerHeight:re.topSpacerHeight,bottomSpacerHeight:re.bottomSpacerHeight,visibleDomHeight:FF(),totalHeight:L6(),width:re.width,final:Oe.value===!0,stable:cv(),confidence:RF(ae,re),reason:L}}function E1(){const L=ut.value||ue(),q=O.value;if(!L||!q)return null;const re=L.ownerDocument||q.ownerDocument||document,ae=L===re.documentElement||L===re.body||L===re.scrollingElement,be=qt("getScrollBox.scrollTop",()=>ze(L,re,ae)),Ne=qt("getScrollBox.scrollHeight",()=>{var je,ot,Ve,Ye,nt;return ae?Math.max((ot=(je=re.documentElement)==null?void 0:je.scrollHeight)!=null?ot:0,(Ye=(Ve=re.body)==null?void 0:Ve.scrollHeight)!=null?Ye:0,(nt=L.scrollHeight)!=null?nt:0):L.scrollHeight}),De=qt("getScrollBox.clientHeight",()=>{var je;return ae?((je=re.documentElement)==null?void 0:je.clientHeight)||L.clientHeight||0:L.clientHeight});return{root:L,doc:re,isViewportRoot:ae,scrollTop:be,scrollHeight:Ne,clientHeight:De}}function L6(){const L=St.value.length,q=Math.max(0,ko(0,L)),re=qt("getRendererLogicalHeight.offsetHeight",()=>{var be,Ne;return(Ne=(be=O.value)==null?void 0:be.offsetHeight)!=null?Ne:0}),ae=Math.max(0,re>0?re:qt("getRendererLogicalHeight.scrollHeight",()=>{var be,Ne;return(Ne=(be=O.value)==null?void 0:be.scrollHeight)!=null?Ne:0}));return L<=0?Math.ceil(re):sn.value?q>0?Math.max(1,Math.ceil(q),(function(){let be=tv.value+nv.value;for(const Ne of ao.values())Ne&&(be+=Math.max(0,qt("getVirtualizedDomLogicalHeight.offsetHeight",()=>Ne.offsetHeight||0)));return Math.ceil(Math.max(0,be))})(),(function(be,Ne){return be<=0||Ne<=0?0:Ne<=be+Math.max(512,.05*be)?Math.ceil(Ne):0})(q,ae)):Math.max(1,Math.ceil(ae)):Ct.value?q>0||hi.count>0||Et.getEstimatedNodeHeightCount()>0?(Rs.value&&yo.value,Math.max(1,Math.ceil(ae),Math.ceil(q))):Math.ceil(ae):Math.max(1,Math.ceil(ae),Math.ceil(q))}function $6(L){const q=O.value;if(!q)return null;const re=qt("getRendererBottomDistanceFromViewport.getBoundingClientRect",()=>q.getBoundingClientRect());return(function(be){return be.isViewportRoot?be.clientHeight:qt("getViewportBottomInRoot.getBoundingClientRect",()=>be.root.getBoundingClientRect().bottom)})(L)-re.bottom}function OF(L={}){const q=L.requireViewport!==!1,re=(function(Ne=64){const De=E1(),je=O.value;if(!De||!je)return!1;const ot=(function(Ye){if(Ye.isViewportRoot)return{top:0,bottom:Ye.clientHeight};const nt=qt("getVirtualViewportRect.getBoundingClientRect",()=>Ye.root.getBoundingClientRect());return{top:nt.top,bottom:nt.bottom}})(De),Ve=qt("isRendererNearVirtualViewport.getBoundingClientRect",()=>je.getBoundingClientRect());return Ve.bottom>=ot.top-Ne&&Ve.top<=ot.bottom+Ne})();if(q&&!re)return null;const ae=(function(){const Ne=E1(),De=O.value;if(!Ne||!De||Math.max(0,Ne.scrollHeight-Ne.scrollTop-Ne.clientHeight)>64)return null;const je=$6(Ne);return je==null?null:je>=-8&&je<=160?{type:"bottom",distanceFromBottomPx:Math.max(0,je)}:null})();if(ae)return{anchor:ae,captured:!0};const be=Nc();if(be)return{anchor:{type:"node",nodeIndex:be.nodeIndex,offsetWithinNodePx:be.offsetWithinNodePx},captured:re};if(L.allowFallback===!0){const Ne=(function(){const De=St.value.length;return De<=0?null:{type:"node",nodeIndex:Bs(Nl.value,0,Math.max(0,De-1)),offsetWithinNodePx:0}})();return Ne?{anchor:Ne,captured:!1}:null}return null}function dv(L){let q=2166136261;for(let re=0;re<L.length;re++)q^=L.charCodeAt(re),q=Math.imul(q,16777619);return(q>>>0).toString(36)}function PF(L,q){let re=L;for(let ae=0;ae<q.length;ae++)re^=q.charCodeAt(ae),re=Math.imul(re,16777619);return re^=31,re=Math.imul(re,16777619),re}const DF=new Set(["children","items","header","rows","cells","attrs","data","term","definition"]);function C0(L,q=new WeakSet,re=0){if(L==null||typeof L=="number"||typeof L=="boolean")return String(L);if(typeof L=="string")return`s:${(function(ae){const be=ae.length>8192?`${ae.slice(0,8192)}...${ae.length}`:ae;return`${ae.length}:${dv(be)}`})(L)}`;if(typeof L=="function")return"fn";if(typeof L!="object")return typeof L;if(q.has(L))return"cycle";if(re>=6)return"max-depth";q.add(L);try{if(Array.isArray(L)){if(L.length<=160){const Ve=[];for(let Ye=0;Ye<L.length;Ye++)Ve.push(C0(L[Ye],q,re+1));return`a:${L.length}:${Ve.join(",")}`}const Ne=[],De=[],je=Math.max(0,L.length-32);let ot=2166136261;for(let Ve=0;Ve<L.length;Ve++){const Ye=C0(L[Ve],q,re+1);ot=PF(ot,Ye),Ve<32&&Ne.push(Ye),Ve>=je&&De.push(Ye)}return[`a:${L.length}`,`h=${Ne.join(",")}`,`t=${De.join(",")}`,`all=${(ot>>>0).toString(36)}`].join(":")}const ae=L,be=Object.keys(ae).filter(Ne=>{const De=ae[Ne];return Ne!=="parent"&&Ne!=="el"&&Ne!=="component"&&(De==null||typeof De=="string"||typeof De=="number"||typeof De=="boolean"||DF.has(Ne))}).sort();return`o:${be.length}:${be.map(Ne=>`${Ne}=${C0(ae[Ne],q,re+1)}`).join(";")}`}finally{q.delete(L)}}let fv=-1,pv="",_u=[2166136261];function I1(L){const q=St.value[L];return q?dv(C0(q)):""}function BF(L,q){let re=L;for(let ae=0;ae<q.length;ae++)re^=q.charCodeAt(ae),re=Math.imul(re,16777619);return re>>>0}function hv(){var L,q;const re=ie.value;if(fv===re)return pv;const ae=St.value.length;let be=J2(ae);(fv!==re-1||be>ae||_u.length<be+1)&&(be=0),be===0?_u=[2166136261]:_u.length=be+1;for(let Ne=be;Ne<ae;Ne++){const De=I1(Ne);_u[Ne+1]=BF((L=_u[Ne])!=null?L:2166136261,De)}return _u.length=ae+1,pv=(((q=_u[ae])!=null?q:2166136261)>>>0).toString(36),fv=re,pv}function zc(L,q={}){var re;const ae=q.includeHeightCache===!0,be=(re=q.includeContentHash)!=null?re:ae,Ne=ae?(function(je){const ot=(function(){var rt,wt;const dt=Number((wt=(rt=o.virtualScroll)==null?void 0:rt.heightCacheLimit)!=null?wt:5e3);return!Number.isFinite(dt)||dt<=0?Number.POSITIVE_INFINITY:Math.max(1,Math.trunc(dt))})();if(!Number.isFinite(ot)||je.length<=ot)return je;const Ve=new Map,Ye=rt=>{!rt||Ve.size>=ot||Ve.set(rt.index,rt)},nt=St.value.length,Be=Bs(Ds.start-2*Qo.value,0,nt),Xe=Bs(Ds.end+2*Qo.value,Be,nt);for(const rt of je)rt.index>=Be&&rt.index<Xe&&Ye(rt);const lt=Math.max(1,Math.ceil(je.length/ot));for(let rt=0;rt<je.length&&Ve.size<ot;rt+=lt)Ye(je[rt]);for(let rt=je.length-1;rt>=0&&Ve.size<ot;rt-=lt)Ye(je[rt]);return Array.from(Ve.values()).sort((rt,wt)=>rt.index-wt.index).slice(0,ot)})(ke().map(je=>{var ot;const Ve=St.value[je.index];return Ve?rn(mt({},je),{nodeType:String((ot=Ve.type)!=null?ot:""),signature:I1(je.index)}):null}).filter(je=>!!je)):[],De=OF({allowFallback:q.allowAnchorFallback===!0,requireViewport:q.requireViewport});return De||Ne.length||q.includeEmptyState===!0?rn(mt({sessionKey:L.sessionKey,threadKey:L.threadKey},De?{anchor:De.anchor,anchorCaptured:De.captured}:{anchorCaptured:!1}),{metrics:L,width:L.width,contentHash:be?hv():void 0,measurementKey:Rl()||void 0,heightCache:Ne.length?Ne:void 0}):null}function mv(L){var q,re;const ae=E1();if(!ae)return;const be=(function(je){const ot=O.value;if(!ot)return null;const Ve=_e(ot,je.root),Ye=St.value.length,nt=qt("getRendererBottomOffsetWithinRoot.offsetHeight",()=>ot.offsetHeight||0),Be=Math.max(0,nt>0?nt:Ye>0?qt("getRendererBottomOffsetWithinRoot.scrollHeight",()=>ot.scrollHeight||0):0),Xe=L6();return Ve+Math.max(Be,Xe)})(ae);if(be==null)return;const Ne=Math.max(0,L.distanceFromBottomPx),De=Math.max(0,be-ae.clientHeight-Ne);(function(je){oo=R1()+120,Ot=je})(De),ae.isViewportRoot?(re=(q=ae.doc.defaultView)==null?void 0:q.scrollTo)==null||re.call(q,0,De):J_(ae.root,ae.doc,De,{isReverseFlexScrollRoot:Se,getNormalizedScrollTop:ze})}const gv=[];function N6(){if(G)for(ln!=null&&(Zo?.(ln),ln=null);gv.length;){const L=gv.pop();L!=null&&window.clearTimeout(L)}}function Wc(L){const q=!!Dt.value;Dt.value=null,oo=0,Ot=null,N6(),q&&L&&po(L)}function Uc(){if(!Dt.value||!G||ln!=null)return;const L=()=>{ln=null;const q=Dt.value;q&&mv(q)};ln=Bo?Bo(L):null,ln==null&&L()}function F6(L,q={}){const re=St.value.length;return re<=0?[]:L.filter(ae=>!(!Number.isInteger(ae.index)||ae.index<0||ae.index>=re)&&!(!Number.isFinite(ae.height)||ae.height<=0)&&!(q.requireSignature&&!ae.signature)&&!(q.requireCompatibilityMetadata&&!ae.nodeType&&!ae.signature)&&(function(be){var Ne;const De=St.value[be.index];return!(!De||be.nodeType&&be.nodeType!==String((Ne=De.type)!=null?Ne:"")||be.signature&&be.signature!==I1(be.index))})(ae))}function R6(L){const q=uf(Cu()),re=uf(L);return q!==-1&&re!==-1&&q===re}function vv(L){var q;const re=Number(L?.width);if(Number.isFinite(re)&&re>0)return re;const ae=Number((q=L?.metrics)==null?void 0:q.width);return Number.isFinite(ae)&&ae>0?ae:null}function O6(L){var q;return L.sessionKey===wo()&&!!sv(L.threadKey)&&((q=L.measurementKey)!=null?q:"")===Rl()&&!!R6(vv(L))&&!!(function(re){const ae=re.heightCache;return!!ae?.length&&(P6(re)?ae.some(be=>!!(be.nodeType||be.signature)):ae.some(be=>!!be.signature))})(L)}function P6(L){return!!(L.contentHash&&L.contentHash===hv())}function HF(L){return!P6(L)}let xu=null,Su=null,w0=null,L1=null,$1=null;function yv(L){var q;const re=L.map(be=>{var Ne,De;return[be.index,Math.round(10*be.height),(Ne=be.nodeType)!=null?Ne:"",(De=be.signature)!=null?De:""].join("")}).join(""),ae=uf(Cu());return[(q=ns())!=null?q:"",wo(),Rl(),St.value.length,ae,L.length,dv(re)].join(":")}function D6(L=(q=>(q=o.virtualScroll)==null?void 0:q.heightCache)()){if(!Ct.value||!L?.length||St.value.length<=0||!R6((q=o.virtualScroll)==null?void 0:q.heightCacheWidth))return!1;var q;const re=F6(L,{requireSignature:!0});if(!re.length)return!1;const ae=yv(re);return ae===xu?(Su="standalone",!0):(a6(re,{mode:"merge"}),Pt(),xu=ae,Su="standalone",P1(),po("restore"),!0)}function kv(L,q={}){var re,ae,be;if(!Ct.value||!L||L.sessionKey!==wo()||!sv(L.threadKey)||St.value.length<=0)return!1;const Ne=!!((re=L.heightCache)!=null&&re.length)&&!_0(),De=!L.anchor||L.anchorCaptured===!1&&q.allowUncapturedAnchor!==!0?null:L.anchor,je=q.restoreAnchor===!0&&!!De&&!_0()&&Number(vv(L))>0;let ot=!1;if((ae=L.heightCache)!=null&&ae.length&&O6(L)){const Ye=F6(L.heightCache,{requireCompatibilityMetadata:!L.contentHash,requireSignature:HF(L)});Ye.length&&(a6(Ye,{mode:"merge"}),Pt(),xu=yv(Ye),Su="restore",P1(),ot=!0)}if(Ne||je)return!1;if(!q.restoreAnchor||!De)return ot&&po("restore"),!0;const Ve=(function(Ye,nt){var Be;const Xe=Ye.anchor,lt=Xe?Xe.type==="bottom"?`bottom:${Math.round(Xe.distanceFromBottomPx)}`:`node:${Xe.nodeIndex}:${Math.round(Xe.offsetWithinNodePx)}`:"none";return[(Be=ns())!=null?Be:"",wo(),Rl(),k0.value,nt,lt].join(":")})(L,(be=q.restoreToken)!=null?be:"imperative");return w0===Ve?(ot&&po("restore"),!0):(w0=Ve,(function(Ye){const nt=()=>{if(Ye.type==="node")return Wc(),void Fc({nodeIndex:Ye.nodeIndex,offsetWithinNodePx:Ye.offsetWithinNodePx});if($c(),Os.value=null,Dt.value=Ye,N6(),mv(Ye),G)for(const Be of[0,120,280,480])gv.push(window.setTimeout(()=>{const Xe=Dt.value;Xe&&mv(Xe)},Be))};(function(Be){if(!sn.value)return!1;const Xe=St.value.length;return!(Xe<=0||(Nl.value=Be.type==="node"?Bs(Be.nodeIndex,0,Xe-1):Xe-1,M1(),0))})(Ye)?yt(nt):nt()})(De),po("restore"),!0)}function _0(){const L=Cu();return Number.isFinite(L)&&L>0}function B6(L){var q;return L.sessionKey===wo()&&!!sv(L.threadKey)&&(St.value.length<=0||!(!((q=L.heightCache)!=null&&q.length)||_0())||!(!(L.anchor&&Number(vv(L))>0)||_0()))}function bv(){zo.clear();for(const L of Object.keys($l)){const q=Number(L);Number.isInteger(q)&&q>=0&&q<St.value.length&&Ps(q)}}function N1(){Xi!=null&&(Zo?.(Xi),Xi=null),Ev()}function H6(){return!G||Zi?Promise.resolve():new Promise(L=>{let q=!1,re=null;const ae=()=>{q||(q=!0,re!=null&&window.clearTimeout(re),L())};if(Bo)return Bo(ae),void(re=window.setTimeout(ae,50));re=window.setTimeout(ae,0)})}function Cv(L,q=ns(),re=Ji.value){return wo()===L&&ns()===q&&Ji.value===re}function wv(){return mo(this,arguments,function*(L={}){var q,re,ae,be,Ne;const De=wo(),je=ns(),ot=Ji.value,Ve=(q=L.frames)!=null?q:2,Ye=(re=L.timeoutMs)!=null?re:120,nt=(ae=L.reason)!=null?ae:"manual",Be=L.expectedSettledTokenKey,Xe=L.flushPendingTimers===!0,lt=wu(nt),rt=()=>rn(mt({},lt),{phase:lt.final?"settling":lt.phase,stable:!1,confidence:lt.confidence==="final"?"mixed":lt.confidence,reason:nt}),wt=()=>Cv(De,je,ot)&&(Be==null||O1()===Be);for(let Vt=0;Vt<Ve;Vt++){if(yield yt(),!wt()||(yield H6(),!wt()))return rt();Ol(),N1()}if(yield(function(Vt){return!G||Vt<=0?Promise.resolve():new Promise(Wt=>window.setTimeout(Wt,Vt))})(Ye),!wt()||(Xe&&m6(),Ol(),N1(),!wt()))return rt();const dt=uv();dt&&(av=De,lv=je,((be=o.virtualScroll)==null?void 0:be.settleMode)==="manual"&&Be!=null&&b0((Ne=o.virtualScroll)==null?void 0:Ne.settledToken)&&O1()===Be&&(Hc=W1(o.virtualScroll.settledToken)));const Ft=wt()&&dt&&I6(),Ht=wu(nt,Ft?"final":void 0);return Mv(Ht,!0),Ht})}let _v="content",Au=null,Mu=null,xv=0,F1=null,jc=null,Sv=null,Av=null;function R1(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function z6(L){var q,re;const ae=F1;if(!ae)return!0;const be=(re=(q=o.virtualScroll)==null?void 0:q.heightDiffThresholdPx)!=null?re:1;return Math.abs(L.totalHeight-ae.totalHeight)>be||L.sessionKey!==ae.sessionKey||L.phase!==ae.phase||L.stable!==ae.stable||L.final!==ae.final||L.threadKey!==ae.threadKey||L.nodeCount!==ae.nodeCount||L.measuredCount!==ae.measuredCount||L.width!==ae.width}function O1(L=(q=>(q=o.virtualScroll)==null?void 0:q.settledToken)()){return As(L)}function W6(L,q){var re,ae;return[L,q.sessionKey,(re=q.threadKey)!=null?re:"",Rl(),hv(),As((ae=o.virtualScroll)==null?void 0:ae.settledToken),Math.round(q.totalHeight),Math.round(q.width)].join("\0")}function P1(){Sv=null,Av=null,jc=null}function zF(L){const q=L.heightCache;return q?.length?yv(q):""}function D1(L){var q,re,ae;const be=L.metrics,Ne=L.anchor?(De=L.anchor).type==="bottom"?`bottom:${Math.round(De.distanceFromBottomPx)}`:`node:${De.nodeIndex}:${Math.round(De.offsetWithinNodePx)}`:"none";var De;return[L.sessionKey,(q=L.threadKey)!=null?q:"",(re=L.measurementKey)!=null?re:Rl(),(ae=L.contentHash)!=null?ae:"",zF(L),Ne,L.anchorCaptured?1:0,be.liveRange.start,be.liveRange.end,be.renderedCount,be.nodeCount,Math.round(be.totalHeight),Math.round(be.width),be.phase,be.stable?1:0].join("\0")}function Mv(L,q=!1){if(!Ct.value||(function(De=!1){return!De&&fo.value&&!Qt.value})(q))return;const re=q||z6(L),ae=(function(De,je=!1){return je||De.stable||De.phase==="final"?{state:zc(De,{includeHeightCache:!0})}:{state:zc(De)}})(L,q),be=ae.state,Ne=!!(be&&(re||(function(De,je=!1){return!!je||D1(De)!==jc})(be,q)));if(re&&($(L),F1=L,xv=R1()),be&&Ne&&(B(be),be.anchor&&H(be.anchor),jc=D1(be)),L.stable){const De=W6("settled",L);if(De!==Sv){Sv=De;const je=zc(L,{includeHeightCache:!0});je&&(B(je),jc=D1(je)),(function(ot){s("render-settled",ot)})(L)}}if(L.phase==="final"){const De=W6("final",L);if(De!==Av){Av=De;const je=zc(L,{includeHeightCache:!0});je&&(B(je),jc=D1(je)),(function(ot){s("render-final",ot)})(L)}}}function Tv(){Au!=null&&(Zo?.(Au),Au=null),Mu!=null&&G&&(window.clearTimeout(Mu),Mu=null)}function U6(){Au=null,Mu=null,(function(L){if(Fl.size>0||Xi!=null)return!0;switch(L){case"node-resize":case"async-node":case"resize":case"restore":case"final":case"manual":return!0;default:return!1}})(_v)&&(Ol(),N1()),Mv(wu(_v))}function po(L){var q,re;if(!Ct.value||(_v=L,Au!=null||Mu!=null))return;const ae=Math.max(0,(re=(q=o.virtualScroll)==null?void 0:q.emitIntervalMs)!=null?re:32),be=Math.max(0,ae-(R1()-xv)),Ne=()=>{Mu=null,Au=Bo?Bo(U6):null,Au==null&&U6()};G&&be>0?Mu=window.setTimeout(Ne,be):Ne()}function j6(){He.value+=1}function x0(L){if(Rs.value&&L>=yo.value){const q=St.value[L],re=Fe.value===!0&&Oe.value!==!0&&L>=St.value.length-2,ae=q?.type==="code_block"||q?.type==="image"||q?.type==="mermaid"||q?.type==="infographic";if(!re||ae)return!1}return!nl.value||L<Co.value||Y2.value.has(L)}function Vc(L){const q=g0.get(L);q&&(q(),g0.delete(L));const re=Oc.get(L);re&&(re.destroy(),Oc.delete(L)),v0(L)}function S0(L,q){let re=!1;if(q){const Ne=ao.get(L);ao.set(L,q),Ne!==q&&(re=!0)}else ao.delete(L)&&(re=!0);if(re&&j6(),q||v0(L),!u6.value||!Js)return Vc(L),void(q&&nl.value&&pa(L,!0));if(!sn.value&&nl.value&&!K.value&&Oc.size>=ve.value&&(K.value||(K.value=!0,X2()),!u6.value||!Js))return Vc(L),void(q&&pa(L,!0));if(L<Co.value&&!sn.value||Y2.value.has(L))return Vc(L),void pa(L,!0);if(!q)return void Vc(L);Vc(L);const ae=Js(q,{rootMargin:pe.value});if(!ae)return;Oc.set(L,ae),pa(L,ae.isVisible.value),nl.value&&(function(Ne){if(!G||!nl.value)return;v0(Ne);const De=Ne%17*23,je=window.setTimeout(()=>{if(g6.delete(Ne),!nl.value||Y2.value.has(Ne))return;const ot=ao.get(Ne);if(!ot)return;const Ve=ue(ot),Ye=ot.ownerDocument||document,nt=Ye.defaultView||window,Be=!Ve||Ve===Ye.documentElement||Ve===Ye.body,Xe=!Be&&Ve?qt("nodeVisibilityFallback.root.getBoundingClientRect",()=>Ve.getBoundingClientRect()):null,lt=Be?0:Xe.top,rt=Be?qt("nodeVisibilityFallback.clientHeight",()=>{var dt,Ft;return(Ft=(dt=nt.innerHeight)!=null?dt:Ve?.clientHeight)!=null?Ft:0}):Xe.bottom,wt=qt("nodeVisibilityFallback.node.getBoundingClientRect",()=>ot.getBoundingClientRect());wt.bottom>=lt-500&&wt.top<=rt+500&&pa(Ne,!0)},1800+De);g6.set(Ne,je)})(L);let be=null;be=Je(()=>ae.isVisible.value,Ne=>{if(Ne){v0(L),pa(L,!0),be?.(),g0.delete(L),Oc.get(L)===ae&&Oc.delete(L);try{ae.destroy()}catch{}}},{immediate:!0}),g0.set(L,be),sn.value&&Lr()}function Ev(){Xi=null,an(()=>{let L=!1;for(const[q,re]of Fl)Fl.delete(q),ol.get(q)===re.el&&bu.get(q)===re.version&&(L=ku(q,re.height,{allowShrink:re.allowShrink})||L);return L})}function qc(){Xi!=null&&(Zo?.(Xi),Xi=null),Fl.clear()}function A0(L,q){(function(re,ae,be){var Ne;if(!Number.isFinite(be)||be<=0||ol.get(re)!==ae)return;const De=bu.get(re);if(De==null)return;const je=St.value[re],ot=at.value&&Oe.value!==!0&&!((Ne=o.nodes)!=null&&Ne.length)&&re>=St.value.length-2,Ve=!(je?.loading===!0||ot),Ye=Fl.get(re),nt=Ye?Ye.allowShrink&&Ve:Ve,Be=Ye&&!nt?Math.max(Ye.height,be):be;Fl.set(re,{height:Be,allowShrink:nt,version:De,el:ae}),Xi==null&&(Xi=Bo?Bo(Ev):null,Xi==null&&Ev())})(L,q,A1(L,q))}function Ol(){for(const[L,q]of ol)q&&A0(L,q)}function V6(){fi?.disconnect(),fi=null,Gi.clear()}function Iv(){for(;f0.length;)m0(f0.pop())}Je(Qt,L=>{L&&po("content")},{flush:"post"}),t({getVirtualMetrics:wu,captureVirtualState:function(L={}){var q;return zc(wu("manual"),{includeHeightCache:!0,includeContentHash:!0,allowAnchorFallback:L.allowFallbackAnchor===!0,requireViewport:L.requireViewport===!0,includeEmptyState:(q=L.includeEmptyState)==null||q})},restoreVirtualState:function(L,q={}){const re=q.restoreAnchor===!0,ae=q.restoreToken==null?"imperative":String(q.restoreToken);L1=L,$1={restoreAnchor:re,restoreToken:ae,allowUncapturedAnchor:q.allowUncapturedAnchor===!0},!kv(L,{restoreAnchor:re,restoreToken:ae,allowUncapturedAnchor:q.allowUncapturedAnchor===!0})&&B6(L)||(L1=null,$1=null)},forceMeasure:function(L="manual"){return mo(this,null,function*(){yield yt(),yield H6(),Ol(),N1(),yield yt();const q=wu(L);return Mv(q,!0),q})},settle:wv,scrollToNode:function(L,q="start"){Wc(),$c();const re=St.value.length;if(re<=0)return;const ae=Bs(L,0,re-1),be=()=>{var Ne;const De=U2({nodeIndex:ae,offsetWithinNodePx:0}),je=Yn(ae),ot=E1(),Ve=(Ne=ot?.clientHeight)!=null?Ne:0,Ye=ei();let nt=De;if(q==="center")nt=De-Ve/2+je/2;else if(q==="end")nt=De-Ve+je;else if(q==="nearest"&&Ye!=null){if(De>=Ye&&De+je<=Ye+Ve)return;nt=De<Ye?De:De-Ve+je}Lc(Math.max(0,nt)),Lr({immediate:!0}),sn.value&&(Nl.value=ae,M1())};if(sn.value)return Nl.value=ae,M1(),void yt(be);be()}}),Je(()=>es.value,L=>{if(!L){V6();for(const q of da.values())for(const re of q)m0(re);da.clear(),bu.clear(),Iv(),qc()}},{immediate:!0}),Je(Oe,L=>{L&&(function(){if(G&&Oe.value&&ol.size){Iv();for(const q of[80,240,640]){const re=h6(q,()=>{for(const[ae,be]of ol)be&&A0(ae,be)},"final");re!=null&&f0.push(re)}}})(),po(L?"final":"content")});const WF=Q_(()=>po("content"),16),UF=Q_(()=>po("batch"),16);Je([()=>St.value.length,()=>yo.value],()=>{Dt.value&&Uc(),WF()},{flush:"post",immediate:!0}),Je([()=>Ds.start,()=>Ds.end],()=>{UF()},{flush:"post"});const{cleanupBatchScheduler:jF}=(function(L){const{props:q,isClient:re,isTestEnv:ae,parsedNodesIdentity:be,parsedNodeCount:Ne,desiredRenderedCount:De,datasetKey:je,batchingEnabled:ot,incrementalRenderingActive:Ve,resolvedBatchSize:Ye,resolvedInitialBatch:nt,renderedCount:Be,adaptiveBatchSize:Xe,previousRenderContext:lt,previousBatchConfig:rt,requestFrame:wt,cancelFrame:dt,hasIdleCallback:Ft,cleanupNodeVisibility:Ht,onDatasetKeyChanged:Vt,onDatasetChanged:Wt}=L;let Kt=null,fn="raf",vn=null,Qn=0,Hs=!1,Ss=!1;const $r=new Set,il=new Set;function K1(){if(re){Kt!=null&&(fn==="raf"&&dt?dt(Kt):fn==="idle"&&typeof window.cancelIdleCallback=="function"?window.cancelIdleCallback(Kt):fn==="timeout"&&window.clearTimeout(Kt),Kt=null),Qn+=1;for(const ti of $r)dt&&dt(ti);for(const ti of il)window.clearTimeout(ti);$r.clear(),il.clear(),vn=null,Hs=!1,Ss=!1}}function R0(){return typeof performance<"u"?performance.now():Date.now()}function u7(ti){(function(Pl){var ma;if(!Ve.value)return;const Dl=Math.max(2,(ma=q.renderBatchBudgetMs)!=null?ma:6),Bl=Math.max(1,Ye.value||1),Nr=Math.max(1,Math.floor(Bl/4));Pl>1.5*Dl?Xe.value=Math.max(Nr,Math.floor(.8*Xe.value)):Pl<.6*Dl&&Xe.value<Bl&&(Xe.value=Math.min(Bl,Math.ceil(1.2*Xe.value)))})(ti),Hs=!1;const Li=Ss||Be.value<De.value;Ss=!1,Li&&f7()}function c7(ti,Li={}){var Pl,ma;if(!Ve.value)return;const Dl=De.value;if(Be.value>=Dl)return;const Bl=Math.max(1,ti),Nr=()=>{const Gc=R0();Kt=null;const Z1=vn??Bl;vn=null;const Yc=R0();Be.value=Math.min(Dl,Be.value+Z1),Ht(Be.value),(function(Pv,O0){if(!re)return void u7(O0);Hs=!0;const p7=++Qn;yt().then(()=>{var h7;if(p7!==Qn)return;const dR=R0(),fR=Math.max(O0,dR-Pv),m7=()=>{p7===Qn&&u7(fR)};if(wt){let Eu=null,Xc=null,v7=!1;const y7=()=>{v7||(v7=!0,Eu!==null&&($r.delete(Eu),Eu=null),Xc!==null&&(il.delete(Xc),window.clearTimeout(Xc),Xc=null),m7())};return Eu=wt(()=>{y7()}),$r.add(Eu),Xc=window.setTimeout(()=>{Eu!==null&&dt&&dt(Eu),y7()},Math.max(32,(h7=q.renderBatchIdleTimeoutMs)!=null?h7:120)),void il.add(Xc)}const g7=window.setTimeout(()=>{il.delete(g7),m7()},0);il.add(g7)})})(Gc,R0()-Yc)};if(!re||Li.immediate)return void Nr();const ga=Math.max(0,(Pl=q.renderBatchDelay)!=null?Pl:16);if(vn=vn!=null?Math.max(vn,Bl):Bl,Kt==null){if(!ae&&Ft&&window.requestIdleCallback){const Gc=Math.max(0,(ma=q.renderBatchIdleTimeoutMs)!=null?ma:120);return fn="idle",void(Kt=window.requestIdleCallback(()=>Nr(),{timeout:Gc}))}if(wt&&!ae)return fn="raf",void(Kt=wt(()=>{ga===0?Nr():(fn="timeout",Kt=window.setTimeout(()=>Nr(),ga))}));fn="timeout",Kt=window.setTimeout(()=>Nr(),ga)}}function d7(ti,Li={}){Hs?Ss=!0:ti==null?f7():c7(ti,Li)}function f7(){Ve.value&&c7(ot.value?Math.max(1,Math.round(Xe.value)):Math.max(1,Ye.value))}return Je([be,Ne,je,Ve,Ye,nt,()=>q.renderBatchDelay],()=>{var ti;const Li=Ne.value,Pl=lt.value,ma=je.value,Dl=!Object.is(ma,Pl.key),Bl=Li!==Pl.total,Nr=Dl||Bl;lt.value={key:ma,total:Li};const ga=rt.value,Gc=(ti=q.renderBatchDelay)!=null?ti:16,Z1=ga.batchSize!==Ye.value||ga.initial!==nt.value||ga.delay!==Gc||ga.enabled!==Ve.value;rt.value={batchSize:Ye.value,initial:nt.value,delay:Gc,enabled:Ve.value},Dl&&Vt(Li),(Nr||Z1||!Ve.value)&&K1(),(Nr||Z1)&&(Xe.value=Math.max(1,Ye.value||1)),Nr&&Wt();const Yc=De.value;if(!Li)return Be.value=0,void Ht(0);if(!Ve.value)return Be.value=Yc,void Ht(Be.value);const Pv=Dl||Pl.total===0;Be.value=Pv||Z1?Math.min(Yc,nt.value):Math.min(Be.value,Yc);const O0=Math.max(1,nt.value||Ye.value||Li);Be.value<Yc?d7(O0,{immediate:!re}):Ht(Be.value)},{immediate:!0}),Je(De,(ti,Li)=>{Ve.value&&(typeof Li=="number"&&ti<=Li||ti>Be.value&&d7())}),{cleanupBatchScheduler:K1}})({props:I,isClient:G,isTestEnv:Zi,parsedNodesIdentity:Ys,parsedNodeCount:Nn,desiredRenderedCount:p0,datasetKey:NF,batchingEnabled:Fs,incrementalRenderingActive:Rs,resolvedBatchSize:Ho,resolvedInitialBatch:Co,renderedCount:yo,adaptiveBatchSize:Le,previousRenderContext:ht,previousBatchConfig:Ze,requestFrame:Bo,cancelFrame:Zo,hasIdleCallback:Il,cleanupNodeVisibility:MF,onDatasetKeyChanged:L=>{qc(),so(),Pt(),P1(),L>0&&Rc(L)},onDatasetChanged:()=>{sn.value&&Lr({immediate:!0})}});Je([c6,sn,()=>O.value,()=>oe()],([L,q])=>{if(!L)return v6(),void G2();TF(),q?Lr({immediate:!0}):G2()},{flush:"post",immediate:!0}),Je([()=>St.value.length,()=>sn.value],L=>mo(null,[L],function*([q,re]){re&&q&&G&&(yield yt(),Lr({immediate:!0}))}),{flush:"post"}),Je(kn,L=>{L&&(function(){var q;if(no.value&&$s.value&&Xs.value&&((q=ci.value)!=null&&q[1]))return;const re=kt({type:"paragraph",children:[{type:"text",content:"Probe paragraph text",raw:"Probe paragraph text"}],raw:"Probe paragraph text"}),ae=kt({type:"list_item",children:[re],raw:"- Probe paragraph text"}),be=kt({type:"list",ordered:!1,items:[ae],raw:"- Probe paragraph text"});no.value=re,$s.value=ae,Xs.value=be;const Ne={1:null,2:null,3:null,4:null,5:null,6:null};for(let De=1;De<=6;De++)Ne[De]=kt({type:"heading",level:De,text:"Probe heading",children:[{type:"text",content:"Probe heading",raw:"Probe heading"}],raw:`${"#".repeat(De)} Probe heading`});ci.value=Ne})()},{immediate:!0}),Je([()=>O.value,kn],()=>{if(!kn.value)return ev(),void(ne.value=0);k6(),ev(),kn.value&&O.value&&typeof ResizeObserver<"u"&&(T1=new ResizeObserver(()=>{k6(),Os.value&&yu(),Dt.value&&Uc(),po("resize")}),T1.observe(O.value))},{immediate:!0}),Je([kn,Ns,Ji],()=>mo(null,null,function*(){if(!kn.value)return X.value={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},void Pt();yield yt(),(function(){if(!kn.value||typeof window>"u")return X.value={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},void Pt();const L={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},q=y6(Q2(F.value),".paragraph-node");L.paragraph=l4(F.value,q,"pre-wrap");const re=Q2(U.value),ae=re?.querySelector(".paragraph-node");L.listItem=l4(U.value,ae,"pre-wrap");const be=qt("readSimpleTextProbeProfile.list.offsetHeight",()=>{var De,je;return(je=(De=z.value)==null?void 0:De.offsetHeight)!=null?je:0}),Ne=qt("readSimpleTextProbeProfile.listItem.offsetHeight",()=>{var De,je;return(je=(De=U.value)==null?void 0:De.offsetHeight)!=null?je:0});L.listWrapperOverhead=Math.max(0,be-Ne);for(let De=1;De<=6;De++){const je=y6(Q2(W[De]),`h${De}`);L.headings[De]=l4(W[De],je,"pre-wrap")}X.value=L,Pt()})()}),{flush:"post",immediate:!0}),Je(()=>St.value.length,()=>{sn.value&&Lr({immediate:!0})}),Je([kn,ne],()=>{Pt(),sn.value&&Lr({immediate:!0}),Os.value&&yu(),Dt.value&&Uc(),po("resize")},{immediate:!1}),Je(()=>nl.value,L=>{if(L)for(const[q,re]of ao)S0(q,re);else if(X2(),sn.value)Lr({immediate:!0});else for(const[q,re]of ao)re&&pa(q,!0)},{immediate:!1}),Je([pe,ve,()=>oe()],()=>{var L;(L=Js.refresh)==null||L.call(Js);for(const[q,re]of ao)S0(q,re)},{immediate:!1}),Je([()=>I.viewportPriority,()=>St.value.length,ve],([L,q,re])=>{if(L!==!1){if(K.value&&(q<=200||q<=re)){K.value=!1;for(const[ae,be]of ao)S0(ae,be)}}else K.value=!1}),Je(()=>yo.value,()=>{sn.value&&Lr({immediate:!0})}),Je([Nl,Io,Qo,()=>St.value.length,sn],()=>{M1()},{immediate:!0});let B1=null,H1=!1,Kc=null;function z1(){B1=null,av=null,lv=void 0,Hc=null,P1()}function Lv(){qc(),so(),Pt(),zo.clear();const L=St.value.length;L>0&&Rc(L),bv()}function $v(){Tv(),m6(),F1=null,xu=null,Su=null,w0=null,L1=null,$1=null,H1=!1,z1(),T6("restore"),$c(),Wc()}function W1(L){var q;return[(q=ns())!=null?q:"",wo(),Rl(),k0.value,O1(L),St.value.length,Math.round(ko(0,St.value.length)),Math.round(Cu()),hi.count,Math.round(hi.total)].join(":")}function q6(){return mo(this,null,function*(){var L,q,re,ae;const be=(L=o.virtualScroll)==null?void 0:L.settledToken,Ne=O1(be),De=wo(),je=ns(),ot=Ji.value;if(Ct.value&&((q=o.virtualScroll)==null?void 0:q.settleMode)==="manual"&&b0(be))if(uv()){if(W1(be)!==Hc&&!H1){H1=!0;try{const Ve=yield wv({reason:"manual",expectedSettledTokenKey:Ne}),Ye=O1()===Ne;Cv(De,je,ot)&&Ve.sessionKey===De&&Ve.threadKey===je&&Ye&&Ve.stable&&Ve.phase==="final"&&(Hc=W1((re=o.virtualScroll)==null?void 0:re.settledToken))}finally{H1=!1,yield yt();const Ve=(ae=o.virtualScroll)==null?void 0:ae.settledToken,Ye=b0(Ve)?W1(Ve):"";Cv(De,je,ot)&&Ye&&Hc!==Ye&&q6()}}}else po("manual")})}Je(Ct,(L,q)=>{if(L!==q){if(!L)return $v(),void Tv();$v(),Lv(),Kc=Ji.value,po("content")}},{flush:"post"}),Je([Ct,Ji],([L,q])=>{L?Kc!=null?Kc!==q&&(Kc=q,(function(re="resize"){qc(),so(),Pt(),zo.clear();const ae=St.value.length;ae>0&&Rc(ae),bv(),xu=null,Su=null,w0=null,F1=null,H1=!1,z1(),D6(),yt(()=>{Ol(),Os.value&&yu(),Dt.value&&Uc(),po(re)})})("resize")):Kc=q:Kc=null},{flush:"post",immediate:!0}),Je([Ct,()=>wo(),()=>ns()],([L])=>{L&&($v(),Lv(),T6("content"),po("content"))}),Je([Ct,()=>wo(),()=>ns(),Ji,()=>St.value.length],([L])=>{L&&(function(q="async-node"){let re=!1;for(const[ae,be]of Array.from(sl.entries()))iv(be)||(sl.delete(ae),Yi.delete(ae),re=!0);re&&(Dc(),po(q))})("async-node")},{flush:"post"}),Je([Ct,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.sessionKey},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.measurementKey},()=>o.indexKey,()=>ie.value],([L])=>{L&&(P1(),(function(q="content"){if(!Ct.value)return;const re=[],ae=St.value.length,be=J2(ae);for(const Ne of Array.from(zo.keys())){if(Ne>=ae){re.push(Ne);continue}if(Ne<be)continue;const De=I1(Ne),je=zo.get(Ne);je!=null&&je!==De&&re.push(Ne),zo.set(Ne,De)}for(const Ne of Array.from(zo.keys()))Ne>=ae&&zo.delete(Ne);re.length&&((function(Ne,De={}){const je=Array.from(Ne,Number);Gt(je);let ot=0;if(an(()=>(ot=q2(je,De),ot>0)),ot>0)(function(Ve){for(const Ye of Ve)zo.delete(Ye)})(je);else for(const Ve of je)J.delete(Ve)})(re,{notify:!1}),Pt(),z1(),Os.value&&yu(),Dt.value&&Uc(),po(q))})("content"))},{flush:"post",immediate:!0}),Je([Ct,()=>St.value.length,()=>wo(),()=>ns()],([L,q,re,ae],[be,Ne,De,je])=>{L&&be&&re===De&&ae===je&&q!==Ne&&z1()},{flush:"post"}),Je([Ct,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.heightCache},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.heightCacheWidth},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.restoreState},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.measurementKey},()=>St.value.length,()=>wo(),ne],()=>{D6()},{flush:"post",immediate:!0}),Je([Ct,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.restoreState},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.restoreAnchor},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.measurementKey},()=>St.value.length,()=>wo(),ne],L=>mo(null,[L],function*([q,re]){if(!q||!re)return;yield yt();const ae=(function(){var be;const Ne=(be=o.virtualScroll)==null?void 0:be.restoreAnchor;return Ne==null||Ne===!1?null:Ne===!0?"true":String(Ne)})();kv(re,{restoreAnchor:ae!=null,restoreToken:ae??void 0})}),{flush:"post",immediate:!0}),Je([Ct,ne,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.restoreState},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.measurementKey}],([L])=>{var q;if(!L)return;const re=(q=o.virtualScroll)==null?void 0:q.restoreState;re&&xu&&Su==="restore"&&(O6(re)||(Lv(),xu=null,Su=null,po("resize")))},{flush:"post"}),Je([Ct,()=>St.value.length,()=>wo(),ne],L=>mo(null,[L],function*([q]){var re;const ae=L1,be=$1;q&&ae&&(yield yt(),!kv(ae,{restoreAnchor:be?.restoreAnchor===!0,restoreToken:(re=be?.restoreToken)!=null?re:"imperative",allowUncapturedAnchor:be?.allowUncapturedAnchor===!0})&&B6(ae)||(L1=null,$1=null))}),{flush:"post",immediate:!0}),Je([Ct,Oe,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.settleMode},()=>wo(),()=>ns(),Ji,Z2,f6,()=>yo.value,p0,()=>hi.count,()=>hi.total],([L,q,re])=>{if(!L||q!==!0||re==="manual"||!cv())return;const ae=(function(){var be;const Ne=St.value.length;return[(be=ns())!=null?be:"",wo(),Rl(),k0.value,Ne,Math.round(ko(0,Ne)),Math.round(Cu()),hi.count,Math.round(hi.total)].join(":")})();B1!==ae&&(B1=ae,wv({reason:"final"}).then(be=>{be.stable||B1!==ae||(B1=null)}))},{flush:"post",immediate:!0}),Je([Ct,Oe,()=>{var L;return(L=o.virtualScroll)==null?void 0:L.settleMode},()=>{var L;return(L=o.virtualScroll)==null?void 0:L.settledToken},()=>wo(),()=>ns(),Ji,Z2,f6,()=>yo.value,p0,()=>St.value.length,()=>hi.count,()=>hi.total],()=>{q6()},{flush:"post",immediate:!0}),Je([()=>St.value.length,sn,Io,Qo,()=>Ds.start,()=>Ds.end],([L,q,re,ae,be,Ne])=>{fe.value&&Mn("virtualization",{nodes:L,virtualization:q,maxLiveNodes:re,buffer:ae,focusIndex:Nl.value,scroll:q?(()=>{const De=ut.value||ue();return De?{reverse:Se(De),scrollTop:Math.round(De.scrollTop),scrollTopAbs:Math.round(Math.abs(De.scrollTop)),scrollHeight:Math.round(De.scrollHeight),clientHeight:Math.round(De.clientHeight)}:null})():null,liveRange:{start:be,end:Ne},rendered:yo.value})}),Je([()=>I.customId],([L],q,re)=>{if(!L||Oo)return;const ae=(function(be,Ne){return be?(ys.controllers[be]=Ne,()=>{ys.controllers[be]===Ne&&delete ys.controllers[be]}):()=>{}})(L,{captureRestoreAnchor:Nc,restoreAnchor:Fc,getAnchorDrift:j2,getReport:LF});re(()=>{ae()})},{immediate:!0}),Vn(()=>{(function(){if(Ct.value)try{Ol(),N1();const L=wu("manual");z6(L)&&($(L),F1=L,xv=R1());const q=zc(L,{includeHeightCache:!0,includeContentHash:!0,allowAnchorFallback:!1,requireViewport:!0,includeEmptyState:!0});q&&(B(q),q.anchor&&H(q.anchor),jc=D1(q))}catch{}})(),jF(),X2(),en(),V6();for(const L of da.values())for(const q of L)m0(q);da.clear(),bu.clear(),zo.clear(),Iv(),qc(),ev(),$c(),Wc(),Tv(),v6(),G2()});const VF=Af("ViewportDeferredMermaidBlockNode",zr({loader:()=>mo(null,null,function*(){try{return(yield jo(()=>import("./index11-Ci8_PlMN.js"),__vite__mapDeps([7,5]))).default}catch(L){return console.warn('[markstream-vue] Optional peer dependencies for MermaidBlockNode are missing. Falling back to preformatted code rendering. To enable Mermaid rendering, please install "mermaid".',L),Pi}}),loadingComponent:px,delay:0}),px),qF=Af("ViewportDeferredInfographicBlockNode",zr({loader:()=>mo(null,null,function*(){try{return(yield jo(()=>import("./index10-BCo1_xRY.js"),[])).default}catch(L){return console.warn('[markstream-vue] Failed to load InfographicBlockNode. Falling back to preformatted code rendering. To enable Infographic rendering, install "@antv/infographic" and configure setInfographicLoader with a dynamic loader.',L),Pi}}),loadingComponent:fx,delay:0}),fx),KF=Af("ViewportDeferredD2BlockNode",zr(()=>mo(null,null,function*(){try{return(yield jo(()=>import("./index8-BaK3y7fN.js"),[])).default}catch(L){return console.warn('[markstream-vue] Optional peer dependencies for D2BlockNode are missing. Falling back to preformatted code rendering. To enable D2 rendering, please install "@terrastruct/d2".',L),Pi}})),Pi),K6={text:qo,paragraph:cc,heading:L2,code_block:X9,list:qd,list_item:Vd,blockquote:tm,table:ep,definition_list:nm,footnote:om,footnote_reference:or,footnote_anchor:Jf,admonition:lm,vmr_container:im,hardbreak:qa,link:Mi,image:Va,thematic_break:sm,math_inline:Jr,math_block:C$,strong:Si,emphasis:Ti,strikethrough:Ai,highlight:ir,insert:ji,subscript:Ui,superscript:Wi,emoji:zi,checkbox:nr,checkbox_input:nr,inline_code:li,html_inline:sr,reference:xi,html_block:Qf},ZF=R(()=>ov()),Z6=R(()=>X_(I.codeBlockProps)),GF=R(()=>X_(I.codeBlockProps,{omit:["langs"]})),G6=R(()=>mt(mt({stream:I.codeBlockStream,darkTheme:I.codeBlockDarkTheme,lightTheme:I.codeBlockLightTheme,monacoOptions:I.codeBlockMonacoOptions,themes:I.themes,langs:m.value==="shiki"?I.langs:void 0,minWidth:I.codeBlockMinWidth,maxWidth:I.codeBlockMaxWidth},typeof we.value=="boolean"?{showTooltips:we.value}:{}),GF.value)),Y6=R(()=>mt(rn(mt({},G6.value),{langs:I.langs}),Z6.value));function X6(L){return typeof L=="boolean"?L:void 0}const YF=R(()=>{const L=I.codeBlockProps||{},q={},re=X6(L.showLineNumbers);re!==void 0&&(q.showLineNumbers=re);const ae=X6(L.diffInline);ae!==void 0&&(q.diffInline=ae);const be=(function(Ne){const De=Number(Ne);return Number.isFinite(De)&&De>0?De:void 0})(L.reservedHeightPx);return be!==void 0&&(q.reservedHeightPx=be),q}),XF=R(()=>mt(mt({stream:I.codeBlockStream,darkTheme:I.codeBlockDarkTheme,lightTheme:I.codeBlockLightTheme,themes:I.themes,langs:I.langs,minWidth:I.codeBlockMinWidth,maxWidth:I.codeBlockMaxWidth},typeof we.value=="boolean"?{showTooltips:we.value}:{}),Z6.value)),JF=R(()=>mt({},I.mermaidProps||{})),J6=R(()=>mt({},I.d2Props||{})),QF=R(()=>mt({},I.infographicProps||{})),U1=R(()=>({typewriter:f.value,fade:I.fade,customHtmlTags:lo.value.customHtmlTags})),eR=R(()=>mt(mt({},U1.value),typeof we.value=="boolean"?{showTooltip:we.value}:{})),tR=R(()=>mt(mt({},U1.value),typeof we.value=="boolean"?{showTooltips:we.value}:{})),nR=R(()=>mt(mt({},U1.value),typeof we.value=="boolean"?{showTooltips:we.value}:{})),oR=R(()=>mt(mt({},U1.value),typeof we.value=="boolean"?{showTooltips:we.value}:{}));function sR(L){return Array.isArray(L.children)&&L.children.length>0}const M0=R(()=>IF.value.map(L=>{var q,re,ae,be,Ne,De,je,ot;let Ve=(function(dt){var Ft,Ht,Vt,Wt,Kt,fn,vn;if(dt.type!=="code_block")return dt;const Qn=dt,Hs=[String((Ft=Qn.language)!=null?Ft:""),String((Ht=Qn.loading)!=null?Ht:""),String((Vt=Qn.diff)!=null?Vt:""),String((Wt=Qn.code)!=null?Wt:""),String((Kt=Qn.originalCode)!=null?Kt:""),String((fn=Qn.updatedCode)!=null?fn:""),String((vn=Qn.raw)!=null?vn:"")].join("\0"),Ss=Ll.get(Qn);if(Ss&&Ss.signature===Hs)return Ss.node;const $r=mt({},Qn);return Ll.set(Qn,{signature:Hs,node:$r}),$r})(L.node);const Ye=T0(Ve);let nt=n7(Ve,Ye);if((Ve.type==="html_block"||Ve.type==="html_inline")&&nt===K6[Ve.type]){const dt=Ve,Ft=String((q=dt.tag)!=null?q:"").trim().toLowerCase()||ZI(dt.content);if(Ft){const Ht=In.value[Ft];if(To.value.has(Ft)&&Ht)nt=Ht,Ve=rn(mt({},dt),{type:Ft,tag:Ft,content:pie(dt.content,Ft)});else if(GI((re=dt.content)!=null?re:dt.raw,Ft)){const Vt=String((be=(ae=dt.content)!=null?ae:dt.raw)!=null?be:"");Ve.type==="html_inline"?(nt=qo,Ve={type:"text",content:Vt,raw:Vt}):(nt=cc,Ve={type:"paragraph",children:[{type:"text",content:Vt,raw:Vt}],raw:Vt})}}}const Be=Ve.type==="code_block"&&m.value==="pre"&&nt===Pi&&!Nv(In.value,Ye);let Xe=mt({},(function(dt,Ft,Ht){const Vt=Ft??T0(dt);if(dt.type==="code_block"){const Wt=Vt?Nv(In.value,Vt):void 0;if(Ht&&m.value==="pre"&&!Wt&&Ht===Pi)return YF.value;if(Ht&&Vt&&Ht===Wt)return Vt==="mermaid"?e7(dt):Vt==="infographic"?t7(dt):Vt==="d2"||Vt==="d2lang"?J6.value:Y6.value;if(Ht&&Ht===In.value.code_block)return Y6.value;if(C6(Ht))return XF.value}return Vt==="mermaid"?e7(dt):Vt==="infographic"?t7(dt):Vt==="d2"||Vt==="d2lang"?J6.value:dt.type==="link"?eR.value:dt.type==="list"?tR.value:dt.type==="blockquote"?nR.value:dt.type==="table"?oR.value:dt.type==="code_block"?G6.value:U1.value})(Ve,Ye,nt));const lt=kn.value?Pc.value[L.index]:null;Ve.type==="code_block"&<?.kind==="code-block"&&(Xe=rn(mt({},Xe),Be?{reservedHeightPx:(Ne=lt.height)!=null?Ne:lt.contentHeight}:{estimatedHeightPx:lt.height,estimatedContentHeightPx:lt.contentHeight,estimatedDiffInline:lt.diffInline})),Be||Ve.type!=="code_block"||Ye!=="mermaid"||Md(Xe.estimatedPreviewHeightPx)!=null||(Xe=rn(mt({},Xe),{estimatedPreviewHeightPx:lg(ig(String((De=Ve.code)!=null?De:"")))})),Be||Ve.type!=="code_block"||Ye!=="infographic"||Md(Xe.estimatedPreviewHeightPx)!=null||(Xe=rn(mt({},Xe),{estimatedPreviewHeightPx:ag(rg(String((je=Ve.code)!=null?je:"")))})),Ve.type==="math_block"&&(Xe=rn(mt({},Xe),{cacheScope:_n}));const rt=(function(dt,Ft){const Ht=String(dt.type);return!Qp(Ht)&&In.value[Ht]===Ft})(Ve,nt),wt=rt?p5(Ve,ge.value):void 0;return rn(mt({},L),{node:Ve,component:nt,bindings:Xe,customBindings:mt(mt({},wt??{}),Xe),rendersCustomNode:rt,hasSlotChildren:sR(Ve),slotContent:String((ot=Ve.content)!=null?ot:""),isCodeBlock:Ve.type==="code_block",indexKey:`${ZF.value}-${L.index}`,vnodeKey:`${$F.value}\0${L.index}\0${Ve.type}`})}));function T0(L){var q;return L?.type==="code_block"?String((q=L.language)!=null?q:"").trim().toLowerCase():""}function Nv(L,q){const re=q.trim().toLowerCase();if(re)for(const ae of[re,T2(re),n$(re)]){const be=ae&&L[ae];if(be)return be}}function Q6(L,q,re,ae){var be,Ne;const De=mt({},L.value);return Md(De.estimatedPreviewHeightPx)==null&&(De.estimatedPreviewHeightPx=ae(re(String((be=q?.code)!=null?be:"")),void 0,De.maxHeight==="none"?null:(Ne=Md(De.maxHeight))!=null?Ne:void 0)),De}function e7(L){return Q6(JF,L,ig,lg)}function t7(L){return Q6(QF,L,rg,ag)}function n7(L,q){if(!L)return l8;const re=In.value,ae=re[String(L.type)];if(L.type==="code_block"){const be=q??T0(L),Ne=be?Nv(re,be):void 0;return Ne||(m.value==="pre"?re.code_block||Pi:be==="mermaid"?re.mermaid||VF:be==="infographic"?re.infographic||qF:be==="d2"||be==="d2lang"?re.d2||KF:ae||re.code_block||w6.value)}return ae||K6[String(L.type)]||l8}function Fv(L){s("click",L)}function iR(L){var q;(q=L.target)!=null&&q.closest("[data-node-index]")&&s("mouseover",L)}function rR(L){var q;(q=L.target)!=null&&q.closest("[data-node-index]")&&s("mouseout",L)}function o7(L){s("mouseover",L)}function s7(L){s("mouseout",L)}const Tu=Z(null),Ii=Z(!1),j1=Z(null),lR=R(()=>!(I.domMode!=="minimal"||Y.value||I.fade!==!1||f.value||Ii.value||Xt.value||sn.value||Qe.value||co.value||Ki.value||Object.keys(In.value).length!==0));let V1,Zc=null,Rv=0,E0=0,I0=0;const i7=["code_block","admonition","table","math_block","html_block","image","thematic_break"],aR=new Set(i7),r7=[".typewriter-cursor",".height-estimation-probes",...i7.map(L=>`[data-node-type="${L}"]`),"script","style"].join(",");function l7(L){if(!L||typeof L!="object")return!1;const q=L.type;return typeof q=="string"&&aR.has(q)}function L0(L){var q,re;if(!L||typeof L!="object")return 0;const ae=L,be=(re=(q=ae.raw)!=null?q:ae.content)!=null?re:ae.code;if(typeof be=="string")return be.length;const Ne=ae.children;if(Array.isArray(Ne))return Ne.reduce((je,ot)=>je+L0(ot),0);const De=ae.items;return Array.isArray(De)?De.reduce((je,ot)=>je+L0(ot),0):0}function $0(){V1&&(clearTimeout(V1),V1=void 0)}function Ov(){Rv+=1,Zc!=null&&(Zo?.(Zc),Zc=null)}function q1(){Ov(),ha(),Tu.value&&(Tu.value.style.visibility="hidden")}function uR(L){var q;if(L.nodeType!==Node.TEXT_NODE||!((q=L.textContent)!=null?q:"").trim())return!1;const re=L.parentElement;return!!re&&!re.closest(r7)}function cR(L){let q=L.lastChild;for(;q;){if(uR(q))return q;if(q.nodeType===Node.ELEMENT_NODE){const re=q;if(!re.matches(r7)&&re.lastChild){q=re.lastChild;continue}}for(;q&&q!==L&&!q.previousSibling;)q=q.parentNode;if(!q||q===L)break;q=q.previousSibling}return null}function a7(){const L=M0.value;for(let q=L.length-1;q>=0;q--){const re=L[q];if(!re||l7(re.node)||!x0(re.index))continue;const ae=ao.get(re.index);if(!ae)continue;const be=cR(ae);if(be)return be}return null}function ha(){j1.value&&(j1.value.classList.remove(hx),j1.value=null)}function N0(){if(d.value!=="simple"||!G||!Ii.value||!O.value)return void ha();const L=a7(),q=L?(function(re){var ae;const be=(ae=re.parentElement)==null?void 0:ae.closest(".text-node");return be instanceof HTMLElement?be:re.parentElement})(L):null;q!==j1.value&&(ha(),q&&(q.classList.add(hx),j1.value=q))}function F0(){if(d.value!=="precise"||!G||!Ii.value||Zc!=null)return;const L=Rv,q=()=>{Zc=null,L===Rv&&(function(){var re,ae;if(d.value!=="precise"||!(G&&Ii.value&&O.value&&Tu.value))return;const be=O.value,Ne=Tu.value;Ne.style.visibility="hidden";const De=a7();if(!De)return;let je=0,ot=0,Ve=20,Ye=!1;if(De?.textContent){const nt=De.textContent.length,Be=document.createRange();Be.setStart(De,Math.max(0,nt-1)),Be.setEnd(De,nt);const Xe=typeof Be.getClientRects=="function"?Be.getClientRects():void 0,lt=(ae=Xe?.[Xe.length-1])!=null?ae:(re=De.parentElement)==null?void 0:re.getBoundingClientRect();if(lt){const rt=qt("typewriterCursor.root.getBoundingClientRect",()=>be.getBoundingClientRect());je=lt.right-rt.left+be.scrollLeft,ot=lt.top-rt.top+be.scrollTop,Ve=lt.height||Ve,Ye=!0}Be.detach()}Ye&&(Ne.style.transform=`translate(${Math.max(0,je)}px, ${Math.max(0,ot)}px)`,Ne.style.height=`${Ve}px`,Ne.style.visibility="visible")})()};Bo?Zc=Bo(q):q()}return Je([it,()=>o.content,()=>o.nodes,()=>I.typewriter,Oe],()=>mo(null,null,function*(){var L,q;if(!G||Y.value||!te.value)return;if(Oe.value)return Ii.value=!1,$0(),void q1();if((L=o.nodes)!=null&&L.length)return Ii.value=!1,$0(),q1(),E0=((q=o.content)!=null?q:"").length,void(I0=it.value.length);const re=(function(){var je,ot;return(je=o.nodes)!=null&&je.length?o.nodes.reduce((Ve,Ye)=>Ve+L0(Ye),0):((ot=o.content)!=null?ot:"").length})(),ae=(function(){var je;return(je=o.nodes)!=null&&je.length?o.nodes.reduce((ot,Ve)=>ot+L0(Ve),0):it.value.length})(),be=!l7(St.value[St.value.length-1]),Ne=re>E0,De=ae>I0;if(!f.value||!be||!Ne&&!De)return f.value&&be||(Ii.value=!1,q1()),E0=re,void(I0=ae);E0=re,I0=ae,Ii.value=!0,d.value==="precise"&&Tu.value&&(Tu.value.style.visibility="hidden"),$0(),yield yt(),d.value==="simple"?N0():(ha(),F0()),V1=setTimeout(()=>{V1=void 0,Ii.value=!1},3e3)}),{flush:"post",immediate:!0}),Je(Ii,L=>mo(null,null,function*(){L?(yield yt(),d.value!=="simple"?(ha(),d.value==="precise"&&F0()):N0()):q1()}),{flush:"post"}),Je(d,()=>mo(null,null,function*(){if(G&&!Y.value&&te.value&&Ii.value){if(yield yt(),d.value==="simple")return Ov(),void N0();ha(),d.value!=="precise"?q1():F0()}}),{flush:"post"}),Je([()=>yo.value,()=>Ds.start,()=>Ds.end],()=>mo(null,null,function*(){G&&!Y.value&&te.value&&Ii.value&&(yield yt(),d.value!=="simple"?(ha(),d.value==="precise"&&F0()):N0())}),{flush:"post"}),Vn(()=>{$0(),Ov(),ha(),xs.clear()}),(L,q)=>{const re=zO("NodeRenderer",!0);return p(Y)?(y(!0),M(Pe,{key:0},pt(M0.value,ae=>(y(),M(Pe,{key:ae.vnodeKey},[ae.rendersCustomNode?(y(),he(bs(ae.component),zn({key:0,ref_for:!0},ae.customBindings,{node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onClick:Fv,onMouseover:o7,onMouseout:s7,onCopy:q[0]||(q[0]=be=>i(be)),onHandleArtifactClick:q[1]||(q[1]=be=>s("handleArtifactClick",be))}),{default:me(()=>[ae.hasSlotChildren?(y(),he(re,zn({key:0,ref_for:!0},uo.value,{nodes:ae.node.children,"index-key":ae.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):ae.slotContent?(y(),he(re,zn({key:1,ref_for:!0},uo.value,{content:ae.slotContent,final:!ae.node.loading,"index-key":`${ae.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):ee("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(y(),he(bs(ae.component),zn({key:1,node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey},{ref_for:!0},ae.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onClick:Fv,onMouseover:o7,onMouseout:s7,onCopy:q[2]||(q[2]=be=>i(be)),onHandleArtifactClick:q[3]||(q[3]=be=>s("handleArtifactClick",be))}),null,16,["node","loading","index-key","custom-id","is-dark"]))],64))),128)):(y(),M("div",{key:1,ref_key:"containerRef",ref:O,class:Re(["markstream-vue markdown-renderer",[{dark:I.isDark},{virtualized:sn.value},{"virtual-scroll-coordinated":Qt.value},{"stable-layout":_F.value},{"typewriter-simple-cursor":Ii.value&&d.value==="simple"}]]),"data-custom-id":I.customId,onClick:Fv,onMouseover:iR,onMouseout:rR},[Ko.value||sn.value?(y(),M(Pe,{key:0},[Ko.value?(y(),he(lpe,{key:0,width:Ns.value,"flow-root":sn.value||Qt.value,"paragraph-node":no.value,"list-item-node":$s.value,"list-node":Xs.value,"heading-nodes":ci.value,"set-paragraph-wrapper":xF,"set-list-item-wrapper":SF,"set-list-wrapper":AF,"set-heading-wrapper":EF},null,8,["width","flow-root","paragraph-node","list-item-node","list-node","heading-nodes"])):ee("",!0),sn.value?(y(),M("div",{key:1,class:"node-spacer",style:Zt({height:`${tv.value}px`}),"aria-hidden":"true"},null,4)):ee("",!0)],64)):ee("",!0),lR.value?(y(!0),M(Pe,{key:1},pt(M0.value,ae=>(y(),M(Pe,{key:ae.vnodeKey},[x0(ae.index)?(y(),he(bs(ae.component),zn({key:0,node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey},{ref_for:!0},ae.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onMouseover:q[4]||(q[4]=be=>s("mouseover",be)),onMouseout:q[5]||(q[5]=be=>s("mouseout",be)),onCopy:q[6]||(q[6]=be=>i(be)),onHandleArtifactClick:q[7]||(q[7]=be=>s("handleArtifactClick",be))}),null,16,["node","loading","index-key","custom-id","is-dark"])):ee("",!0)],64))),128)):(y(!0),M(Pe,{key:2},pt(M0.value,ae=>(y(),M("div",{key:ae.vnodeKey,ref_for:!0,ref:be=>S0(ae.index,be),class:"node-slot","data-node-index":ae.index,"data-node-type":ae.node.type},[x0(ae.index)?(y(),M("div",{key:0,ref_for:!0,ref:be=>(function(Ne,De){var je;De||(function(nt){const Be=`${ov()}-${nt}`;let Xe=!1;for(const lt of Array.from(Yi.keys())){const rt=sl.get(lt);(rt?.index===nt||lt===Be||lt.startsWith(`${Be}-`))&&(Yi.delete(lt),sl.delete(lt),Xe=!0)}Xe&&(Dc(),po("async-node"))})(Ne),Fl.delete(Ne),(function(nt){var Be;const Xe=((Be=bu.get(nt))!=null?Be:0)+1;bu.set(nt,Xe)})(Ne);const ot=da.get(Ne);if(ot){for(const nt of ot)m0(nt);da.delete(Ne)}if((function(nt){const Be=Gi.get(nt);Be&&(fi?.unobserve(Be),Er.delete(Be),Gi.delete(nt))})(Ne),!De||!es.value)return ol.delete(Ne),void bu.delete(Ne);ol.set(Ne,De);const Ve=()=>{A0(Ne,De)};queueMicrotask(Ve);const Ye=(fi||typeof ResizeObserver>"u"||(fi=new ResizeObserver(nt=>{if(nt.length)for(const Be of nt){const Xe=Er.get(Be.target),lt=Gi.get(Xe??-1);Xe!=null&<&&A0(Xe,lt)}else Ol()})),fi);if(Ye&&(Gi.set(Ne,De),Er.set(De,Ne),Ye.observe(De)),typeof window<"u"){const nt=((je=St.value[Ne])==null?void 0:je.type)==="code_block"?[16,80,240,800]:Oe.value?[80]:[];if(nt.length){const Be=nt.map(Xe=>h6(Xe,Ve,"node-resize")).filter(Xe=>Xe!=null);Be.length&&da.set(Ne,Be)}}})(ae.index,be),class:"node-content"},[ae.isCodeBlock?ae.rendersCustomNode?(y(),he(bs(ae.component),zn({key:1,ref_for:!0},ae.customBindings,{node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onCopy:q[12]||(q[12]=be=>i(be)),onHandleArtifactClick:q[13]||(q[13]=be=>s("handleArtifactClick",be))}),{default:me(()=>[ae.hasSlotChildren?(y(),he(re,zn({key:0,ref_for:!0},uo.value,{nodes:ae.node.children,"index-key":ae.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):ae.slotContent?(y(),he(re,zn({key:1,ref_for:!0},uo.value,{content:ae.slotContent,final:!ae.node.loading,"index-key":`${ae.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):ee("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(y(),he(bs(ae.component),zn({key:2,node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey},{ref_for:!0},ae.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onCopy:q[14]||(q[14]=be=>i(be)),onHandleArtifactClick:q[15]||(q[15]=be=>s("handleArtifactClick",be))}),null,16,["node","loading","index-key","custom-id","is-dark"])):(y(),he(as,{key:0,name:"fade",css:I.fade!==!1,appear:I.fade!==!1},{default:me(()=>[ae.rendersCustomNode?(y(),he(bs(ae.component),zn({key:0,ref_for:!0},ae.customBindings,{node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onCopy:q[8]||(q[8]=be=>i(be)),onHandleArtifactClick:q[9]||(q[9]=be=>s("handleArtifactClick",be))}),{default:me(()=>[ae.hasSlotChildren?(y(),he(re,zn({key:0,ref_for:!0},uo.value,{nodes:ae.node.children,"index-key":ae.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):ae.slotContent?(y(),he(re,zn({key:1,ref_for:!0},uo.value,{content:ae.slotContent,final:!ae.node.loading,"index-key":`${ae.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):ee("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(y(),he(bs(ae.component),zn({key:1,node:ae.node,loading:ae.node.loading,"index-key":ae.indexKey},{ref_for:!0},ae.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onCopy:q[10]||(q[10]=be=>i(be)),onHandleArtifactClick:q[11]||(q[11]=be=>s("handleArtifactClick",be))}),null,16,["node","loading","index-key","custom-id","is-dark"]))]),_:2},1032,["css","appear"]))],512)):(y(),M("div",{key:1,class:"node-placeholder",style:Zt({height:`${Yn(ae.index)}px`})},null,4))],8,cpe))),128)),Ii.value&&d.value==="precise"?(y(),M("span",{key:3,ref_key:"typewriterCursorRef",ref:Tu,class:"typewriter-cursor","aria-hidden":"true"},null,512)):ee("",!0),sn.value?(y(),M("div",{key:4,class:"node-spacer",style:Zt({height:`${nv.value}px`}),"aria-hidden":"true"},null,4)):ee("",!0)],42,upe))}}})),[["__scopeId","data-v-a9489508"]]),Vi=R$;Vi.install=e=>{const t=new Set(["MarkdownRender","NodeRenderer",Vi.__name,Vi.name].filter(n=>!!n));for(const n of t)e.component(n,R$)};const M5=Object.freeze(Object.defineProperty({__proto__:null,default:Vi},Symbol.toStringTag,{value:"Module"})),dpe={key:0,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},fpe={key:1,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},ppe={key:2,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},hpe={key:3,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},mpe={class:"admonition-title"},gpe=["aria-expanded","aria-controls"],vpe=["id"],lm=Gn(et({__name:"AdmonitionNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e,{emit:t}){var n;const o=e,s=t,i=R(()=>{if(o.node.title&&o.node.title.trim().length)return o.node.title;const u=o.node.kind||"note";return u.charAt(0).toUpperCase()+u.slice(1)}),r=Z(!!o.node.collapsible&&!((n=o.node.open)==null||n));function l(){o.node.collapsible&&(r.value=!r.value)}const a=`admonition-${Math.random().toString(36).slice(2,9)}`;return(u,c)=>(y(),M("div",{class:Re(["admonition",[`admonition-${o.node.kind}`]])},[C("div",{id:a,class:"admonition-legend"},[o.node.kind==="note"||o.node.kind==="info"?(y(),M("svg",dpe,[...c[1]||(c[1]=[C("circle",{cx:"12",cy:"12",r:"10"},null,-1),C("path",{d:"M12 16v-4"},null,-1),C("path",{d:"M12 8h.01"},null,-1)])])):o.node.kind==="tip"?(y(),M("svg",fpe,[...c[2]||(c[2]=[C("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"},null,-1),C("path",{d:"M9 18h6"},null,-1),C("path",{d:"M10 22h4"},null,-1)])])):o.node.kind==="warning"||o.node.kind==="caution"?(y(),M("svg",ppe,[...c[3]||(c[3]=[C("path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"},null,-1),C("path",{d:"M12 9v4"},null,-1),C("path",{d:"M12 17h.01"},null,-1)])])):o.node.kind==="danger"||o.node.kind==="error"?(y(),M("svg",hpe,[...c[4]||(c[4]=[C("polygon",{points:"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"},null,-1),C("path",{d:"M12 8v4"},null,-1),C("path",{d:"M12 16h.01"},null,-1)])])):ee("",!0),C("span",mpe,N(i.value),1),o.node.collapsible?(y(),M("button",{key:4,class:"admonition-toggle","aria-expanded":!r.value,"aria-controls":`${a}-content`,onClick:l},[(y(),M("svg",{style:Zt({rotate:r.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[...c[5]||(c[5]=[C("path",{d:"m9 18 6-6-6-6"},null,-1)])],4))],8,gpe)):ee("",!0)]),Bn(C("div",{id:`${a}-content`,class:"admonition-content","aria-labelledby":a},[j(p(Vi),{"index-key":`admonition-${e.indexKey}`,nodes:o.node.children,"custom-id":o.customId,typewriter:o.typewriter,fade:o.fade,onCopy:c[0]||(c[0]=d=>s("copy",d))},null,8,["index-key","nodes","custom-id","typewriter","fade"])],8,vpe),[[qs,!r.value]])],2))}}),[["__scopeId","data-v-a83480e1"]]);lm.install=e=>{e.component(lm.__name,lm)};const f8=()=>jo(()=>import("./d2_markstream-vue-yoD6TSFD.js"),[]);let xh=null,Sh=f8,Ah=null,mx=!1,gx=!1;function $Ve(){return mo(this,null,function*(){if(xh)return xh;const e=Sh;return e?e===f8&&mx?null:Ah||(Ah=mo(null,null,function*(){let t;try{t=yield e()}catch(n){if(e===f8)return e===Sh&&(mx=!0,(function(o){gx||(gx=!0,console.warn('[markstream-vue] Optional dependency "@terrastruct/d2" is not installed. D2 blocks will render as source.',o))})(n)),null;throw n}finally{e===Sh&&(Ah=null)}return e!==Sh?null:t?(xh=(function(n){var o;if(!n)return n;if(n.D2&&typeof n.D2=="function")return n.D2;if(n.default&&n.default.D2&&typeof n.default.D2=="function")return n.default.D2;const s=(o=n.default)!=null?o:n;return typeof s=="function"?s:s?.D2&&typeof s.D2=="function"?s.D2:s})(t),xh):null}),Ah):null})}let Mh=null,O$=null,Th=null;function NVe(){return typeof O$=="function"}function FVe(){return mo(this,null,function*(){if(Mh)return Mh;const e=O$;return e?Th||(Th=mo(null,null,function*(){const t=yield e(),n=(function(o){var s,i,r;if(!o)return null;const l=(s=o.default)!=null?s:o,a=typeof l=="function"&&typeof((i=l.prototype)==null?void 0:i.render)=="function"?l:(r=o.Infographic)!=null?r:l?.Infographic;return typeof a=="function"?a:null})(t);return n?(Mh=n,Mh):null}).finally(()=>{Th=null}),Th):null})}const RVe=Symbol("markstreamLanguageIconResolver"),P$=["cjs","css","csv","gif","htm","html","jpeg","jpg","js","json","jsx","log","md","mjs","pdf","png","scss","svg","ts","tsx","txt","vue","webp","xml","yaml","yml"],ype=new Set(["AGENTS.md","CHANGELOG.md","Dockerfile","LICENSE","Makefile","README.md","package.json","pnpm-lock.yaml","pnpm-workspace.yaml","tsconfig.json","vite.config.ts"]),p8=[...P$].sort((e,t)=>t.length-e.length).join("|"),a4=new RegExp([String.raw`(?:^|[\s([{"'`+"`"+String.raw`])`,String.raw`(`,String.raw`(?:~|\.{1,2}|/)?(?:[A-Za-z0-9_.@+()[\]-]+/)+[A-Za-z0-9_.@+()[\]-]+(?:\.(?:${p8}))?`,String.raw`|`,String.raw`[A-Za-z0-9_.@+()[\]-]+\.(?:${p8})`,String.raw`)`,String.raw`(?:#L?(\d+)|:(\d+))?`,String.raw`(?=$|[\s)"'\]}>.,;!?,。;!?)])`].join(""),"gi"),D$=/[),.;!?,。;!?)]+$/;function kpe(e){const t=e.toLowerCase();return P$.some(n=>t.endsWith(`.${n}`))}function bpe(e){const t=new Map,n=new RegExp(String.raw`\b(?:path|src)=["'](\/[^"']+\.(?:${p8}))["']`,"gi");let o;for(;(o=n.exec(e))!==null;){const s=o[1];if(!s)continue;const i=s.split("/").pop();i&&t.set(i,s)}return t}function Cpe(e,t={}){const n=e.trim();if(!n||/^[a-z][a-z0-9+.-]*:\/\//i.test(n))return null;const o=n.match(/^(.*?)(?:#L?(\d+)|:(\d+))?$/i);if(!o)return null;let s=(o[1]??"").replace(D$,"");if(!s)return null;const i=s.split("/").pop()??s,r=s.includes("/"),l=ype.has(i),a=kpe(i);if(r&&!l&&!a)return null;if(!r&&!l){const d=t.aliases?.get(i);if(!d)return null;s=d}const u=o[2]??o[3],c=u?Number(u):void 0;return{path:s,line:c!==void 0&&Number.isFinite(c)&&c>0?c:void 0}}function wpe(e,t={}){const n=[];a4.lastIndex=0;let o;for(;(o=a4.exec(e))!==null;){const s=o[0]??"",i=o[1]??"",r=s.indexOf(i);if(r<0)continue;const l=o[2]??o[3];let a=i+(l?s.slice(r+i.length):"");const u=a.replace(D$,""),c=a.length-u.length;a=u;const d=Cpe(a,t);if(!d)continue;const f=o.index+r,h=f+a.length;n.push({...d,start:f,end:h,text:a}),c>0&&(a4.lastIndex-=c)}return n}function u4(e,t){let n=0,o=t-1;for(;o>=0&&e[o]==="\\";)n++,o--;return n%2===1}const _pe=/\s/,xpe=/\p{Nd}/u;function Cc(e,t){const n=e.codePointAt(t);return n===void 0?void 0:String.fromCodePoint(n)}function Spe(e,t){if(t<=0)return;const n=e.charCodeAt(t-1),o=n>=56320&&n<=57343&&t>1?t-2:t-1,s=e.codePointAt(o);return s===void 0?void 0:String.fromCodePoint(s)}function vx(e){return e!==void 0&&_pe.test(e)}function a1(e){return e!==void 0&&xpe.test(e)}function Ape(e,t){const n=e[t+1];return a1(Cc(e,t+1))?!0:(n==="-"||n==="+"||n==="."||n==="−"||n==="+"||n==="-")&&a1(Cc(e,t+2))}function vg(e){return e!==void 0&&e>="A"&&e<="Z"}const B$=new RegExp(String.raw`^(?:AED|AFN|ALL|AMD|ANG|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BGN|BHD|BIF|BMD|BND|BOB|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHF|CLF|CLP|CNY|COP|CRC|CUC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HRK|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SLL|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|UYU|UZS|VED|VES|VND|VUV|WST|XAF|XCD|XOF|XPF|YER|ZAR|ZMW|ZWL|HK|US|SG|AU|CA|NZ|NT|TW|RMB|MEX|TT|BZ|EU|UK)$`);function Mpe(e,t){if(!vg(e[t-1]))return!1;let n=t-1;for(;n>0&&vg(e[n-1]);)n--;return B$.test(e.slice(n,t))||a1(Cc(e,t+1))?!0:t-n<=2&&!/[\p{L}\p{Nd}]/u.test(e[n-1]??"")&&!/\p{L}/u.test(Cc(e,t+1)??"")}function Tpe(e,t){if(!vg(e[t-1]))return!1;let n=t-1;for(;n>0&&vg(e[n-1]);)n--;return B$.test(e.slice(n,t))?!0:t-n<=2&&!/[\p{L}\p{Nd}]/u.test(e[n-1]??"")}const Epe=/^[-–—,,、;;::~~(([【//]$/;function Ipe(e,t){const n=e[t+1];if(n!=="-"&&n!=="+"&&n!=="."||!a1(Cc(e,t+2)))return!1;const o=e[t-1];return o!==void 0&&Epe.test(o)}function Lpe(e){const t=String.raw`[、,,;;::~~\-–—至到//\s()()=*×=]|和|跟|与|及|或|and|or`;let n=e.replace(new RegExp(String.raw`^(?:${t})+`,"u"),"");for(;;){const s=n.replace(new RegExp(String.raw`^\p{L}+(?:${t})+`,"u"),"").replace(/^[\p{L}][\p{L} ]*(?=\p{Nd})/u,"");if(s===n)break;n=s}if(!/\p{Nd}/u.test(n))return!1;const o=String.raw`[-+]?[\p{Nd}][\p{Nd},.'’]*`;return new RegExp(String.raw`^${o}(?:\p{L}+)?(?:(?:${t})+${o}(?:\p{L}+)?)*$`,"u").test(n)}const ul=-1,yx=1,kx=2,bx=3;function $pe(e){const t=e.length,n=new Uint8Array(t),o=new Int32Array(t+1).fill(ul),s=new Int32Array(t+1),i=new Int32Array(t+1),r=[],l=[];{const F=[];for(let K=0;K<t;K++)if(e[K]==="`"){if(u4(e,K))continue;let V=K+1;for(;V<t&&e[V]==="`";)V++;F.push([K,V]),K=V-1}const U=new Map;for(let K=0;K<F.length;K++){const V=F[K][1]-F[K][0],ie=U.get(V);ie?ie.push(K):U.set(V,[K])}const z=new Map;let W=0;for(;W<F.length;){const[K,V]=F[W],ie=V-K,ne=U.get(ie);let X=z.get(ie)??0;for(;X<ne.length&&ne[X]<=W;)X++;z.set(ie,X),X<ne.length?(l.push([K,F[ne[X]][1]]),W=ne[X]+1):W++}}let a=0;const u=F=>{for(;a<l.length&&F>=(l[a]?.[1]??0);)a++;const U=l[a];return U!==void 0&&F>=U[0]},c=new Set(' \n\r)。,、;:!?"<>`「」『』【】〔〕()*—–“”‘’'),d=[];for(const F of e.matchAll(/\b(?:https?:\/\/|ftp:\/\/|mailto:|www\.)/gi))d.push(F.index);for(const F of e.matchAll(/\b(?:localhost|(?:\d{1,3}\.){3}\d{1,3}|[\w-]+(?:\.[\w-]+)*\.[a-zA-Z]{2,})(?=(?:\/|\?|:\d))/gi))d.push(F.index);for(const F of e.matchAll(/(?:\.{1,2})?\/[\p{L}\p{Nd}._-]+(?:\/[\p{L}\p{Nd}._-]*)*\?/gu))(F.index===0||!/[\w~/.-]/.test(e[F.index-1]))&&d.push(F.index);d.sort((F,U)=>F-U);let f=-1;for(const F of d){if(F<f)continue;let U=F,z=0,W=0,K=0;for(;U<t;){const V=e[U];if(V==="(")z++;else if(V===")"){if(z===0)break;z--}else if(V==="[")W++;else if(V==="]"){if(W===0)break;W--}else if(V==="{")K++;else if(V==="}"){if(K===0)break;K--}else{if(c.has(V))break;if((V===","||V===";"||V==="!"||V==="?")&&!/[A-Za-z0-9$]/.test(e[U+1]??""))break;if(V===":"&&W===0&&U>F+7&&!/[\w/?#@~.+&=%-]/.test(e[U+1]??""))break}U++}r.push([F,U]),f=U}const h=[];for(let F=0;F<t;F++){if(e[F]!=="<"||e[F+1]===void 0||!/[a-zA-Z/]/.test(e[F+1]))continue;let U=F+1;const z=e[U]==="/";z&&U++;const W=/^[a-zA-Z][a-zA-Z0-9-]*/.exec(e.slice(U));if(!W)continue;U+=W[0].length;const K=e[U];if(K===void 0||!/[\s/>]/.test(K))continue;let V=U,ie=ul,ne=ul;for(;V<t;){const X=e[V];if(X===">"){ne=V;break}if(!z&&X==="/"&&e[V+1]===">"){ne=V+1;break}if(!/\s/.test(X)){ie=V;break}for(;V<t&&/\s/.test(e[V]);)V++;const le=e[V];if(le===void 0)break;if(le===">"){ne=V;break}if(z){ie=V;break}if(le==="/"&&e[V+1]===">"){ne=V+1;break}const Ie=/^[a-zA-Z_:][\w:.-]*/.exec(e.slice(V));if(!Ie){ie=V;break}V+=Ie[0].length;let de=V;for(;de<t&&/\s/.test(e[de]);)de++;if(e[de]==="="){for(de++;de<t&&/\s/.test(e[de]);)de++;const pe=e[de];if(pe==='"'||pe==="'"){const ve=e.indexOf(pe,de+1);if(ve===-1){ie=de;break}V=ve+1}else{const ve=/^[^\s"'=<>`]+/.exec(e.slice(de));if(!ve){ie=de;break}V=de+ve[0].length}}}if(ne!==ul)h.push([F,ne+1]),F=ne;else if(ie!==ul){const X=e.indexOf("<",F+1);F=(X!==-1&&X<ie?X:ie)-1}else break}let m=!0,v=!0,k=!0,w=!0;for(let F=0;F<t;F++){if(e[F]!=="<")continue;const U=e[F+1];let z=!1;if(U==="?"&&v){const ie=e.indexOf("?>",F+2);ie===-1?v=!1:(h.push([F,ie+2]),F=ie+1,z=!0)}else if(U==="!"){if(e[F+2]==="-"&&e[F+3]==="-"){if(m){const ie=e.indexOf("-->",F+4);ie===-1?m=!1:(h.push([F,ie+3]),F=ie+2,z=!0)}}else if(e.startsWith("[CDATA[",F+2)){if(k){const ie=e.indexOf("]]>",F+9);ie===-1?k=!1:(h.push([F,ie+3]),F=ie+2,z=!0)}}else if(w&&/[A-Z]/.test(e[F+2]??"")){const ie=e.indexOf(">",F+3);ie===-1?w=!1:(h.push([F,ie+1]),F=ie,z=!0)}}if(z)continue;if(U!==void 0&&/[a-zA-Z]/.test(U)){const ie=/^[a-zA-Z][a-zA-Z0-9+.-]{1,31}:/.exec(e.slice(F+1));if(ie){let ne=F+1+ie[0].length;for(;ne<t&&e[ne]!==">"&&e[ne]!=="<"&&!/\s/.test(e[ne]);)ne++;if(e[ne]===">"){h.push([F,ne+1]),F=ne;continue}}}if(U===void 0||!/[\w.!#$%&'*+/=?^`{|}~-]/.test(U))continue;let W=F+1;for(;W<t&&/[\w.!#$%&'*+/=?^`{|}~-]/.test(e[W]);)W++;if(e[W]!=="@")continue;W++;const K=/^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?/;let V=K.exec(e.slice(W));if(V){for(W+=V[0].length;e[W]==="."&&(V=K.exec(e.slice(W+1)),!!V);)W+=1+V[0].length;e[W]===">"&&(h.push([F,W+1]),F=W)}}h.sort((F,U)=>F[0]-U[0]);const b=[];for(const[F,U]of h){const z=b[b.length-1];z&&F<=z[1]?z[1]=Math.max(z[1],U):b.push([F,U])}r.push(...b);let _=0;const g=F=>{for(;_<b.length&&F>=(b[_]?.[1]??0);)_++;const U=b[_];return U!==void 0&&F>=U[0]},x=[];let S=null,T=0,A=!1;for(let F=0;F<t;F++)if(e[F]==="\\")F++;else if(A)e[F]===">"&&(A=!1);else if(!(u(F)||g(F))){if(S!==null)e[F]===S&&(S=null);else if(x.length>0&&(e[F]==='"'||e[F]==="'")&&F>0&&/\s/.test(e[F-1]))S=e[F];else if(e[F]==="[")T++;else if(e[F]==="]")T>0&&e[F+1]==="("&&(x.push(F),A=e[F+2]==="<",F++),T=Math.max(0,T-1);else if(e[F]==="("&&x.length>0)x.push(-1);else if(e[F]===")"&&x.length>0){const U=x.pop();if(U!==void 0&&U>=0){const z=e.slice(U+2,F);(/\s/.exec(z)===null||z.startsWith("<")&&/^<(?:\\[<>]|[^<>])*>$/.test(z)||/^[^\s]*\s+("([^"\\]|\\.)*"|'([^'\\]|\\.)*'|\(([^()\\]|\\.)*\))$/.test(z))&&r.push([U,F+1])}}}r.sort((F,U)=>F[0]-U[0]);const E=[];for(const[F,U]of r){const z=E[E.length-1];z&&F<=z[1]?z[1]=Math.max(z[1],U):E.push([F,U])}const P=F=>{let U=0,z=E.length-1;for(;U<=z;){const W=U+z>>1,K=E[W];if(K===void 0)return!1;if(F<K[0])z=W-1;else if(F>=K[1])U=W+1;else return!0}return!1};for(let F=0;F<t;F++)i[F+1]=(i[F]??0)+(e[F]==="`"&&!u4(e,F)?1:0),e[F]==="$"&&(u4(e,F)||P(F)?n[F]=yx:vx(e[F-1])||a1(Cc(e,F+1))||Ipe(e,F)?n[F]=kx:n[F]=bx),s[F+1]=(s[F]??0)+(n[F]===kx?1:0);let D=ul;for(let F=t-1;F>=0;F--)n[F]===bx&&(D=F),o[F]=D;const I=/^[\p{L}\p{Nd}\\|{([+.¬°-±×÷′-″←-⇿∀-⋿^_<>=-]$/u,$=/[^\p{L}\p{Nd}\s]$/u,B=/[^\s\u0020-\u007E\u0370-\u03FF\u{1D400}-\u{1D7FF}\p{Nd}¬°-±×÷′-″←-⇿∀-⋿]/u,H=/(?:^|\s)[a-z]{2,}/,O=(F,U)=>{const z=Cc(e,F+1);if(z===void 0||!I.test(z))return!1;const W=o[F+1]??ul;if(W!==ul){const K=e.slice(F+1,W);return!(K.length===((K.codePointAt(0)??0)>65535?2:1))&&B.test(K)||/[,;:!?]$/.test(K)||/^[a-z]{2,}$/.test(K)?!1:(s[W]??0)-(s[F+1]??0)===0&&(i[W]??0)-(i[F+1]??0)===0}return $.test(U)||B.test(U)||H.test(U)};return(F,U=-1)=>{if(e[F]!=="$"||n[F]===yx||e[F+1]==="$"||e[F-1]==="$"&&U!==F||Mpe(e,F)||F+1>=t||vx(e[F+1]))return null;const z=o[F+1]??ul;if(z===ul||(s[z]??0)-(s[F+1]??0)>0||(i[z]??0)-(i[F+1]??0)>0)return null;const W=e.slice(F+1,z);return/^\{[A-Z_][A-Z0-9_]*(?:\}$|[:-])/.test(W)||e[z+1]==="{"&&/^\{[A-Za-z_][A-Za-z0-9_]*(?:[:-][^{}]*)?\}$/.test(W)||a1(Spe(e,F))&&Lpe(W)||Ape(e,F)&&(O(z,W)||Tpe(e,z)||/\s/.test(W)&&/\p{Nd}$/u.test(W)&&!/[+\-*/^=_<>|\\¬°-±×÷′-″←-⇿∀-⋿]/.test(W)||e[z+1]==="$"&&!/\p{L}/u.test(W)&&/[^\p{L}\p{Nd}\s]$/u.test(W))?null:{content:W,end:z+1}}}const Cx=new WeakMap;function Npe(e,t){if(e.src[e.pos]!=="$")return!1;let n=Cx.get(e);(!n||n.src!==e.src)&&(n={src:e.src,match:$pe(e.src),lastEnd:-1},Cx.set(e,n));const o=n.match(e.pos,n.lastEnd);if(!o||o.end>e.posMax)return!1;if(n.lastEnd=o.end,t)return e.pos=o.end,!0;const s=e.push("math_inline","math",0);return s.content=o.content,s.markup="$",s.raw=e.src.slice(e.pos,o.end),s.loading=!1,e.pos=o.end,!0}function Fpe(e){return e.inline.ruler.disable("math"),e.inline.ruler.before("escape","math",Npe),e}const Rpe=12e4,Ope=6e4,Ppe=32,Dpe=3e4,wx=/(^|\n)(`{3,}|~{3,})[^\n]*\n([\s\S]*?)(?:\n)?\2(?=\n|$)/g;function Bpe(e){let t=0,n=0,o=0;wx.lastIndex=0;let s;for(;(s=wx.exec(e))!==null;){const r=s[3]??"";t+=1,n+=r.length,o=Math.max(o,r.length)}return{codeRenderer:e.length>=Rpe||n>=Ope||t>=Ppe||o>=Dpe?"pre":"shiki",codeFenceCount:t,codeChars:n}}async function H$(e){const t=typeof navigator<"u"?navigator.clipboard:void 0;if(t&&typeof t.writeText=="function")try{return await t.writeText(e),!0}catch{}return zpe(e)}function Hpe(e){if(typeof e!="string")return;const t=typeof navigator<"u"?navigator.clipboard:void 0;t&&typeof t.writeText=="function"||H$(e)}function zpe(e){if(typeof document>"u"||typeof document.execCommand!="function")return!1;const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.style.opacity="0",document.body.appendChild(t);let n=!1;try{t.focus(),t.select(),n=document.execCommand("copy")}catch{n=!1}finally{document.body.removeChild(t)}return n}const z$="md-table-wide",W$="md-table-toggle",U$="md-table-fade",_x="md-table-toggle--show",Wpe="md-table-at-end",Upe="kimi-table-layout",j$='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>',jpe='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" y1="10" x2="21" y2="3"/><line x1="3" y1="21" x2="10" y2="14"/></svg>';function e0(e){return e.querySelector(`button.${W$}`)}function V$(e){return e.querySelector(`.${U$}`)}const Vpe=26;function qpe(e){const t=e0(e);if(!t)return;const n=e.querySelector("thead tr")??e.querySelector("tr");if(!n)return;const o=n.getBoundingClientRect(),s=e.getBoundingClientRect().top,i=Math.max(2,Math.round(o.top-s+(o.height-Vpe)/2));t.style.top=`${i}px`,t.style.right=`${i}px`}function Kpe(e){return e.closest(".a-msg .msg")!==null}function Zpe(e){const t=e.querySelector("table");return t!==null&&t.scrollWidth>e.clientWidth+1}function q$(e){const t=`translateX(${e.scrollLeft}px)`,n=V$(e);n&&(n.style.transform=t);const o=e0(e);o&&(o.style.transform=t);const s=e.scrollLeft+e.clientWidth>=e.scrollWidth-2;e.classList.toggle(Wpe,s)}function Gpe(e,t){const n=e0(e);if(n)return n;if(!Kpe(e))return null;const o=document.createElement("div");o.className=U$,o.setAttribute("aria-hidden","true");const s=document.createElement("button");return s.type="button",s.className=W$,s.innerHTML=j$,s.setAttribute("aria-label",t.widen),s.title=t.widen,s.addEventListener("click",i=>{i.preventDefault(),i.stopPropagation(),Ype(e,t)}),e.appendChild(o),e.appendChild(s),e.addEventListener("scroll",()=>q$(e),{passive:!0}),T5(e),s}function Ype(e,t){const n=e.classList.toggle(z$),o=e0(e);if(o){o.innerHTML=n?jpe:j$;const s=n?t.restore:t.widen;o.setAttribute("aria-label",s),o.title=s}T5(e),e.dispatchEvent(new CustomEvent(Upe,{bubbles:!0}))}function T5(e){const t=e0(e);if(!t)return;const n=Zpe(e),o=e.classList.contains(z$);t.classList.toggle(_x,n||o);const s=V$(e);s&&s.classList.toggle(_x,n),qpe(e),q$(e)}function Xpe(e){return new Worker("/assets/katexRenderer.worker-CO_gEm4q.js",{type:"module",name:e?.name})}function Jpe(e){return new Worker("/assets/mermaidParser.worker-BFSlSHEW.js",{type:"module",name:e?.name})}const Qpe={key:1,class:"diff-wrap"},e0e={class:"diff-bar"},t0e=["aria-label","onClick"],n0e={class:"diff-pre"},o0e={key:0,class:"diff-sign"},s0e={class:"diff-text"},i0e="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",xx="github-light",Sx="github-dark",r0e=et({__name:"Markdown",props:{text:{},openFile:{},streaming:{type:Boolean,default:!1}},setup(e){qce(),ide(),Zce(),ade(),Kce(new Xpe),lde(new Jpe);const{t}=m1(),n=nn("resolveImage"),o=Z(null),s=e,i=R(()=>!s.streaming),r=R(()=>bpe(s.text??"")),l=R(()=>s.streaming?{codeRenderer:"shiki",codeFenceCount:0,codeChars:0}:Bpe(s.text??"")),a=f2(),u=R(()=>!s.streaming),c=Go(new Map),d=new Set,f=/(!\[[^\]]*\]\()\s*([^)\s]+)([^)]*\))/g,h=/(<img\b[^>]*?\bsrc=")([^"]+)(")/gi;function m(F){return!/^(https?:|data:|blob:)/i.test(F)}function v(F){if(!n)return;const U=[];for(const z of[f,h]){z.lastIndex=0;let W;for(;(W=z.exec(F))!==null;)U.push(W[2]??"")}for(const z of U)!z||!m(z)||c.has(z)||d.has(z)||(d.add(z),n(z).then(W=>{c.set(z,W!==z?W:"")}).catch(()=>{c.set(z,"")}).finally(()=>{d.delete(z)}))}function k(F){if(!n)return F;const U=z=>{if(!m(z))return null;const W=c.get(z);return W===void 0?i0e:W===""?null:W};return F.replace(f,(z,W,K,V)=>{const ie=U(K);return ie===null?z:`${W}${ie}${V}`}).replace(h,(z,W,K,V)=>{const ie=U(K);return ie===null?z:`${W}${ie}${V}`})}Je(()=>s.text,F=>v(F??""),{immediate:!0});function w(){if(!o.value||!s.openFile||s.streaming)return;const F=document.createTreeWalker(o.value,NodeFilter.SHOW_TEXT),U=[];let z=F.nextNode();for(;z;){const W=z,K=W.parentElement;K&&!K.closest("a, pre, .md-file-link, svg")&&W.data.trim().length>0&&U.push(W),z=F.nextNode()}for(const W of U){const K=wpe(W.data,{aliases:r.value});if(K.length===0||!W.parentNode)continue;const V=document.createDocumentFragment();let ie=0;for(const ne of K){ne.start>ie&&V.append(document.createTextNode(W.data.slice(ie,ne.start)));const X=document.createElement("button");X.type="button",X.className="md-file-link",X.textContent=ne.text,X.title=ne.line?`${ne.path}:${ne.line}`:ne.path,X.addEventListener("click",le=>{le.preventDefault(),le.stopPropagation(),s.openFile?.({path:ne.path,line:ne.line})}),V.append(X),ie=ne.end}ie<W.data.length&&V.append(document.createTextNode(W.data.slice(ie))),W.parentNode.replaceChild(V,W)}}function b(F){return!(!F||/^(https?:|mailto:|tel:|data:|blob:|#)/i.test(F))}function _(F){let U=F.length;for(const z of["#","?"]){const W=F.indexOf(z);W!==-1&&W<U&&(U=W)}return F.slice(0,U)}function g(){if(!o.value||!s.openFile||s.streaming)return;const F=o.value.querySelectorAll("a[href]");for(const U of F){if(U.dataset.mdLinkHandled==="true"||U.closest("svg"))continue;const z=U.getAttribute("href")??"";b(z)&&(U.dataset.mdLinkHandled="true",U.addEventListener("click",W=>{W.preventDefault(),W.stopPropagation(),s.openFile?.({path:_(z)})}))}}function x(){return{widen:t("conversation.widenTable"),restore:t("conversation.restoreTableWidth")}}function S(){if(!o.value||s.streaming)return;const F=x();for(const U of o.value.querySelectorAll(".table-node-wrapper"))Gpe(U,F)}function T(){if(!(!o.value||s.streaming))for(const F of o.value.querySelectorAll(".table-node-wrapper"))T5(F)}function A(){yt().then(()=>{w(),g(),S()})}Je(()=>s.text,A),Je(()=>s.streaming,A);let E=null,P=null;dn(()=>{A(),o.value&&(E=new MutationObserver(A),E.observe(o.value,{childList:!0,subtree:!0}),P=new ResizeObserver(T),P.observe(o.value))}),bn(()=>{E?.disconnect(),P?.disconnect()});const D={showHeader:!0,showCopyButton:!0,showExpandButton:!1,showPreviewButton:!1,showCollapseButton:!1,showFontSizeButtons:!1,loading:!1,monacoOptions:{lineNumbers:!1,fontSize:13,fontFamily:"var(--font-mono)",padding:{top:12,bottom:12}}},I=/(^|\n)(?:```|~~~)diff\b[^\n]*\n([\s\S]*?)(?:\n)?(?:```|~~~)(?=\n|$)/g,$=R(()=>{const F=k(s.text??""),U=[];let z=0;I.lastIndex=0;let W;for(;(W=I.exec(F))!==null;){const V=W[1]??"",ie=F.slice(z,W.index)+(V||"");ie.trim()&&U.push({kind:"md",text:ie}),U.push({kind:"diff",code:W[2]??""}),z=I.lastIndex}const K=F.slice(z);return(K.trim()||U.length===0)&&U.push({kind:"md",text:K}),U});function B(F){return F.split(` +`).map(U=>U.startsWith("@@")?{type:"hunk",sign:"",text:U}:/^\+(?!\+\+)/.test(U)?{type:"add",sign:"+",text:U.slice(1)}:/^-(?!--)/.test(U)?{type:"del",sign:"-",text:U.slice(1)}:U.startsWith(" ")?{type:"ctx",sign:"",text:U.slice(1)}:{type:"ctx",sign:"",text:U})}const H=Z(null);function O(F,U){H$(F).then(z=>{z&&(H.value=U,setTimeout(()=>{H.value=null},1400))})}return(F,U)=>(y(),M("div",{ref_key:"mdRef",ref:o,class:"md"},[(y(!0),M(Pe,null,pt($.value,(z,W)=>(y(),M(Pe,{key:W},[z.kind==="md"?(y(),he(p(Vi),{key:0,content:z.text,"custom-markdown-it":p(Fpe),mode:"chat","code-renderer":l.value.codeRenderer,"is-dark":p(a),"code-block-light-theme":xx,"code-block-dark-theme":Sx,themes:[xx,Sx],"code-block-props":D,final:i.value,"smooth-streaming":e.streaming,"batch-rendering":u.value,"defer-nodes-until-visible":!1,onCopy:p(Hpe)},null,8,["content","custom-markdown-it","code-renderer","is-dark","themes","final","smooth-streaming","batch-rendering","onCopy"])):(y(),M("div",Qpe,[C("div",e0e,[U[0]||(U[0]=C("span",{class:"diff-lang"},"diff",-1)),j(p(pn),{text:p(t)("filePreview.copyCode")},{default:me(()=>[C("button",{class:"diff-copy","aria-label":p(t)("filePreview.copyCode"),onClick:K=>O(z.code,W)},[j(p(Te),{name:H.value===W?"check":"copy",size:"sm"},null,8,["name"])],8,t0e)]),_:2},1032,["text"])]),C("pre",n0e,[C("code",null,[(y(!0),M(Pe,null,pt(B(z.code),(K,V)=>(y(),M("span",{key:V,class:Re(["diff-line",`diff-${K.type}`])},[K.type!=="hunk"?(y(),M("span",o0e,N(K.sign),1)):ee("",!0),C("span",s0e,N(K.text),1)],2))),128))])])]))],64))),128))],512))}}),Ic=ft(r0e,[["__scopeId","data-v-2a3e373d"]]),l0e={state:"idle"};function a0e(e){const t=Z(l0e),n=Z(ui(cn.updateSkippedVersion)),o=Z(!1);if(typeof e?.getUpdateAutoDownload=="function"&&e.getUpdateAutoDownload().then(i=>{o.value=i}).catch(()=>{}),e!==void 0){let i=!1;e.onUpdateStatus(r=>{i=!0,t.value=r}),e.getUpdateStatus().then(r=>{i||(t.value=r)}).catch(()=>{})}const s=R(()=>{const i=t.value;return!(i.state==="idle"||i.state==="available"&&i.version!==void 0&&i.version===n.value)});return{status:t,visible:s,canCheck:typeof e?.checkForUpdates=="function",autoDownload:o,canToggleAutoDownload:typeof e?.getUpdateAutoDownload=="function"&&typeof e?.setUpdateAutoDownload=="function",setAutoDownload:i=>{o.value=i,e?.setUpdateAutoDownload?.(i).catch(()=>{})},skipVersion:()=>{const i=t.value.version;t.value.state==="available"&&i!==void 0&&(n.value=i,Ls(cn.updateSkippedVersion,i))},check:async()=>{if(typeof e?.checkForUpdates!="function")return Promise.resolve({outcome:"unsupported"});const i=await e.checkForUpdates().catch(()=>({outcome:"error",message:"bridge call failed"}));return i.outcome==="available"&&i.version!==void 0&&i.version===n.value&&(n.value=null,ur(cn.updateSkippedVersion)),i},download:()=>{e?.downloadUpdate().catch(()=>{})},install:()=>{e?.installUpdate().catch(()=>{})}}}let c4=null;function K$(){return c4===null&&(c4=a0e(window.kimiDesktop)),c4}const u0e=["data-state"],c0e=["aria-label"],d0e={class:"upd-pill-text"},f0e={key:0,class:"upd-meta"},p0e={key:1,class:"upd-notes"},h0e={class:"upd-notes-title"},m0e={key:2,class:"upd-progress"},g0e={key:3,class:"upd-message"},v0e={class:"upd-foot"},y0e={class:"upd-foot-actions"},k0e=et({__name:"UpdateIndicator",setup(e){const{t,locale:n}=Nt(),{status:o,visible:s,skipVersion:i,download:r,install:l,autoDownload:a,setAutoDownload:u,canToggleAutoDownload:c}=K$(),d=Z(!1),f="0.33.0".trim()?"0.33.0":"",h=R(()=>{switch(o.value.state){case"available":return t("sidebar.update");case"downloading":return`${o.value.percent??0}%`;case"downloaded":return t("sidebar.updateDone");case"error":return t("sidebar.updateFailed");default:return""}}),m=R(()=>{switch(o.value.state){case"available":return t("sidebar.updateAvailable",{version:o.value.version??""});case"downloading":return t("sidebar.updateDownloading",{percent:o.value.percent??0});case"downloaded":return t("sidebar.updateReady",{version:o.value.version??""});case"error":return t("sidebar.updateFailed");default:return""}}),v=R(()=>{const T=o.value.releaseDate;if(T===void 0||T==="")return"";const A=new Date(T),E=Number.isNaN(A.getTime())?T:A.toLocaleDateString();return t("sidebar.updateReleaseDate",{date:E})}),k=R(()=>{const T=[];return v.value!==""&&T.push(v.value),f!==""&&T.push(t("sidebar.updateCurrentVersion",{version:f})),T.join(" · ")}),w=R(()=>o.value.percent??0),b=R(()=>{const T=o.value.releaseNotes;return T===void 0?"":((n.value.toLowerCase().startsWith("zh")?T.zh:T.en)??T.zh??T.en??"").trim()}),_=R(()=>{switch(o.value.state){case"error":return"alert-triangle";default:return"download"}});function g(){r()}function x(){i(),d.value=!1}function S(){l(),d.value=!1}return(T,A)=>p(s)?(y(),M("span",{key:0,class:"upd","data-state":p(o).state},[C("button",{class:"upd-pill",type:"button","aria-label":h.value,onClick:A[0]||(A[0]=E=>d.value=!0)},[j(p(Te),{class:"upd-pill-icon",name:_.value,size:"sm"},null,8,["name"]),C("span",d0e,N(h.value),1)],8,c0e),j(p(ua),{open:d.value,title:m.value,size:"lg","onUpdate:open":A[4]||(A[4]=E=>d.value=E)},{foot:me(()=>[C("div",v0e,[C("div",y0e,[p(o).state==="available"?(y(),M(Pe,{key:0},[j(p(Rt),{variant:"ghost",onClick:x},{default:me(()=>[qe(N(p(t)("sidebar.updateSkip")),1)]),_:1}),j(p(Rt),{onClick:g},{default:me(()=>[qe(N(p(t)("sidebar.updateDownloadNow")),1)]),_:1})],64)):p(o).state==="downloading"?(y(),he(p(Rt),{key:1,variant:"secondary",onClick:A[1]||(A[1]=E=>d.value=!1)},{default:me(()=>[qe(N(p(t)("sidebar.updateBackground")),1)]),_:1})):p(o).state==="downloaded"?(y(),M(Pe,{key:2},[j(p(Rt),{variant:"ghost",onClick:A[2]||(A[2]=E=>d.value=!1)},{default:me(()=>[qe(N(p(t)("sidebar.updateRestartLater")),1)]),_:1}),j(p(Rt),{onClick:S},{default:me(()=>[qe(N(p(t)("sidebar.updateRestartNow")),1)]),_:1})],64)):p(o).state==="error"?(y(),he(p(Rt),{key:3,variant:"danger-soft",onClick:g},{default:me(()=>[qe(N(p(t)("sidebar.updateRetry")),1)]),_:1})):ee("",!0)]),p(c)?(y(),he(p(rW),{key:0,class:"upd-auto","model-value":p(a),"onUpdate:modelValue":A[3]||(A[3]=E=>p(u)(E))},{default:me(()=>[qe(N(p(t)("sidebar.updateAutoDownload")),1)]),_:1},8,["model-value"])):ee("",!0)])]),default:me(()=>[(p(o).state==="available"||p(o).state==="downloaded")&&k.value?(y(),M("p",f0e,N(k.value),1)):ee("",!0),b.value?(y(),M("section",p0e,[C("h4",h0e,N(p(t)("sidebar.updateWhatsNew")),1),j(p(Ic),{text:b.value},null,8,["text"])])):ee("",!0),p(o).state==="downloading"?(y(),M("div",m0e,[C("div",{class:"upd-progress-fill",style:Zt({width:`${w.value}%`})},null,4)])):ee("",!0),p(o).state==="error"&&p(o).message?(y(),M("p",g0e,N(p(o).message),1)):ee("",!0)]),_:1},8,["open","title"])],8,u0e)):ee("",!0)}}),b0e=ft(k0e,[["__scopeId","data-v-c0a4acce"]]),yg=[{code:"en",label:"English"},{code:"zh",label:"简体中文"}],Hn=Mz({locale:$M()});function E5(e){Hn.global.locale.value=e,Ls(cn.locale,e)}const C0e=["app:load:start","app:load:complete","export:start","export:accepted","export:failed","prompt:start","prompt:accepted","prompt:failed","session:snapshot:start","session:snapshot:accepted","session:snapshot:failed","operation:failed","window:error","window:unhandled-rejection","ws:connection","ws:error","ws:resync","ws:stale-reconnect"],Z$=500,kg=256*1024,Ax=200,d4=16384,f4=500,p4=50,h4=50,w0e=6,_0e=/api[_-]?key|authorization|token|secret|password|cookie|credential|email|phone|nickname|avatar/i,x0e=/^[A-Za-z0-9+/=_-]{200,}$/;let m4=null;function Qr(){if(m4!==null)return m4;let e=!1;try{if(typeof location<"u"){const t=new URLSearchParams(location.search).get("debug");(t==="1"||t==="true")&&(e=!0)}}catch{}return e||(e=ui(cn.debug)==="1"),m4=e,e}const Ka=[],Ed=[];let Mf=0;const Yu=[];let Tf=0,S0e=1;const bg=new TextEncoder,A0e=new Set(C0e),I5=Z(0),Ef=Xr(!1);function M0e(){return Ka}function T0e(){Ka.length=0,Ed.length=0,Mf=0,Yu.length=0,Tf=0,I5.value++}function ca(e){if(!Ef.value){try{const t={id:S0e++,ts:Date.now(),source:e.source,kind:String(Kd(e.kind)),label:String(Kd(e.label)),sessionId:e.sessionId===void 0?void 0:String(Kd(e.sessionId)),method:e.method,path:e.path,eventType:e.eventType,seq:e.seq,offset:e.offset,status:e.status,code:e.code,requestId:e.requestId,durationMs:e.durationMs,detail:pu(e.detail)},n=JSON.stringify(t),o=bg.encode(n).byteLength;if(o>kg)return;for(Ka.push(t),Ed.push(n),Mf+=o+(Ed.length>1?1:0);Ka.length>Z$||Mf>kg;){const s=Ed.shift();Ka.shift(),s!==void 0&&(Mf-=bg.encode(s).byteLength,Ed.length>0&&(Mf-=1))}}catch{return}I5.value++}}function Bu(e){if(typeof e=="string")return e.length<=Ax?e:e.slice(0,Ax)}function mr(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function E0e(e,t){if(A0e.has(e))try{const n={ts:Date.now(),event:e,sessionId:Bu(t?.sessionId),status:Bu(t?.status),operation:Bu(t?.operation),seq:mr(t?.seq),durationMs:mr(t?.durationMs),messageCount:mr(t?.messageCount),contentCount:mr(t?.contentCount),mediaCount:mr(t?.mediaCount),sessionCount:mr(t?.sessionCount),workspaceCount:mr(t?.workspaceCount),promptId:Bu(t?.promptId),zipBytes:mr(t?.zipBytes),errorName:Bu(t?.errorName),errorCode:mr(t?.errorCode),requestId:Bu(t?.requestId),phase:Bu(t?.phase),httpStatus:mr(t?.httpStatus),fatal:typeof t?.fatal=="boolean"?t.fatal:void 0,line:mr(t?.line),col:mr(t?.col)},o=JSON.stringify(n),s=bg.encode(o).byteLength;if(s>kg)return;for(Yu.push(o),Tf+=s+(Yu.length>1?1:0);Yu.length>Z$||Tf>kg;){const i=Yu.shift();i!==void 0&&(Tf-=bg.encode(i).byteLength,Yu.length>0&&(Tf-=1))}}catch{return}}function Kd(e,t=0){if(e==null)return e;const n=typeof e;if(n==="number"||n==="boolean")return e;if(n==="string"){const i=e;return x0e.test(i)?`[base64-like, ${i.length} chars omitted]`:i.length>f4?`${i.slice(0,f4)}… [+${i.length-f4} chars]`:i}if(n!=="object")return String(e);if(t>=w0e)return"[max depth]";if(Array.isArray(e)){const i=e.slice(0,p4).map(r=>Kd(r,t+1));return e.length>p4&&i.push(`[+${e.length-p4} more items]`),i}const o={},s=Object.entries(e);for(const[i,r]of s.slice(0,h4))o[i]=_0e.test(i)?"[redacted]":Kd(r,t+1);return s.length>h4&&(o._truncatedKeys=s.length-h4),o}function pu(e){if(e===void 0)return;const t=Kd(e);try{const n=JSON.stringify(t);if(n!==void 0&&n.length>d4)return{_truncated:`detail JSON was ${n.length} chars; first ${d4} kept`,preview:n.slice(0,d4)}}catch{return"[unserializable detail]"}return t}function I0e(e){Qr()&&ca({source:"rest",kind:"rest:request",label:`→ ${e.method} ${e.path}`,method:e.method,path:e.path,requestId:e.requestId,detail:{url:e.url,body:pu(e.body)}})}function L0e(e){if(!Qr())return;const t=e.code!==0;ca({source:"rest",kind:t?"rest:error":"rest:response",label:`← ${e.method} ${e.path} ${e.status} code=${e.code}${t?` "${e.msg}"`:""} ${Math.round(e.durationMs)}ms`,method:e.method,path:e.path,requestId:e.requestId,status:e.status,code:e.code,durationMs:e.durationMs,detail:{envelope:{code:e.code,msg:e.msg,request_id:e.envelopeRequestId},data:pu(e.data)}})}function $0e(e){Qr()&&ca({source:"rest",kind:"rest:error",label:`✕ ${e.method} ${e.path} ${e.phase} error${e.status!==void 0?` (HTTP ${e.status})`:""} ${Math.round(e.durationMs)}ms`,method:e.method,path:e.path,requestId:e.requestId,status:e.status,durationMs:e.durationMs,detail:{phase:e.phase,error:String(e.error)}})}function N0e(e,t){Qr()&&ca({source:"ws",kind:"ws:lifecycle",eventType:e,label:`ws ${e}`,detail:pu(t)})}function F0e(e){if(!Qr())return;const t=e??{},n=typeof t.type=="string"?t.type:"(unknown)",o=t.payload,s=typeof o?.session_id=="string"?o.session_id:void 0;ca({source:"ws",kind:"ws:out",eventType:n,sessionId:s,label:`→ ${n}`,detail:pu(e)})}function R0e(e){if(!Qr())return;const t=e??{},n=typeof t.type=="string"?t.type:"(unknown)",o=typeof t.session_id=="string"?t.session_id:typeof t.payload?.session_id=="string"?t.payload.session_id:void 0,s=typeof t.seq=="number"?t.seq:void 0,i=typeof t.offset=="number"?t.offset:void 0,r=[o,s!==void 0?`seq=${s}`:void 0,i!==void 0?`offset=${i}`:void 0,t.volatile===!0?"volatile":void 0].filter(Boolean);ca({source:"ws",kind:"ws:in",eventType:n,sessionId:o,seq:s,offset:i,label:`← ${n}${r.length>0?` (${r.join(" ")})`:""}`,detail:pu(t.payload)})}const O0e={error:"✕",warn:"⚠",info:"ℹ",debug:"·",log:"·"};function P0e(e,t,n){Qr()&&ca({source:"client",kind:`client:${e}`,label:`${O0e[e]} ${t}`,detail:pu(n)})}function D0e(e,t){Qr()&&ca({source:"client",kind:"client:event",label:`· ${e}`,detail:pu(t)})}function bi(e,t){E0e(e,t),ca({source:"client",kind:"client:key",label:e,sessionId:typeof t?.sessionId=="string"?t.sessionId:void 0,seq:typeof t?.seq=="number"?t.seq:void 0,durationMs:typeof t?.durationMs=="number"?t.durationMs:void 0,detail:t})}let g4=!1,Eh=null;function B0e(){if(g4)return()=>Eh?.();g4=!0;const e=[];try{if(typeof window<"u"){const n=s=>{bi("window:error",{status:"failed",errorName:s.error instanceof Error?s.error.name:"Error",line:s.lineno,col:s.colno}),Xl(`[kimi-web] window error: ${s.message}`,s.error instanceof Error?s.error.stack:void 0)},o=s=>{const i=s.reason;bi("window:unhandled-rejection",{status:"failed",errorName:i instanceof Error?i.name:typeof i}),Xl(`[kimi-web] unhandled rejection: ${z0e(i)}`,i instanceof Error?i.stack:void 0)};window.addEventListener("error",n),window.addEventListener("unhandledrejection",o),e.push(()=>{window.removeEventListener("error",n)}),e.push(()=>{window.removeEventListener("unhandledrejection",o)})}}catch{}if(Qr())for(const n of["error","warn","log","info","debug"]){const o=console[n];if(typeof o!="function")continue;const s=(...i)=>{try{P0e(n,i.map(H0e).join(" "),i.length>1?i:i[0])}catch{}o.apply(console,i)};console[n]=s,e.push(()=>{console[n]===s&&(console[n]=o)})}const t=()=>{if(Eh===t){for(const n of e.toReversed())n();Eh=null,g4=!1}};return Eh=t,t}function H0e(e){if(typeof e=="string")return e;if(e instanceof Error)return`${e.name}: ${e.message}`;try{return JSON.stringify(e)}catch{return String(e)}}function z0e(e){if(e instanceof Error)return e.message;try{return String(e)}catch{return"[unstringifiable reason]"}}function G$(e=Ka){if(typeof document>"u")return;const t=new Blob([W0e(e)],{type:"application/x-ndjson"}),n=URL.createObjectURL(t);let o;try{o=document.createElement("a"),o.href=n,o.download=`kimi-web-log-${new Date().toISOString().replaceAll(/[:.]/g,"-")}.jsonl`,document.body.append(o),o.click()}finally{o?.remove(),setTimeout(()=>{try{URL.revokeObjectURL(n)}catch{}},0)}}function W0e(e=Ka){return e===Ka?Ed.join(` +`):e.map(t=>JSON.stringify(t)).join(` +`)}function U0e(){return Yu.join(` +`)}const Mx=cn.clientId,j0e="kimi-code-web",V0e="web";function q0e(){return{serverHttpUrl:Z0e(),clientId:Y0e(),clientName:j0e,clientVersion:X0e(),clientUiMode:V0e}}function K0e(){return typeof window<"u"&&window.location?.origin?window.location.origin:"http://127.0.0.1:58627"}function Z0e(){const e=Y$();return h8(e||void 0)}const Tx="kimi-desktop-server-origin";function Y$(){if(typeof window>"u")return;const e=new URLSearchParams(window.location.search).get("kimi_origin");try{return e?(window.sessionStorage.setItem(Tx,e),e):window.sessionStorage.getItem(Tx)??void 0}catch{return e??void 0}}function h8(e){const t=e&&e.trim()?e:K0e(),n=new URL(t);return n.pathname=n.pathname.replace(/\/v1\/?$/,"").replace(/\/$/,""),n.search="",n.hash="",n.toString().replace(/\/$/,"")}function Ex(e){return e.replace(/^https?:\/\//,"").replace(/\/$/,"")}function G0e(){if(typeof window<"u"){const t=Y$();if(t)return Ex(h8(t))}const e=typeof window<"u"&&window.location?.origin?window.location.origin:"";return Ex(e)}function Y0e(){const e=ui(Mx);if(e)return e;const t=`web_${globalThis.crypto?.randomUUID?.()||Math.random().toString(36).slice(2)}`;return Ls(Mx,t),t}function X0e(){return"0.33.0".trim()?"0.33.0":"0.0.0-dev"}const J0e={restRequest:e=>I0e(e),restResponse:e=>L0e(e),restFailure:e=>$0e(e),wsEvent:e=>{switch(e.kind){case"lifecycle":N0e(e.event,e.detail);break;case"in":R0e(e.frame);break;case"out":F0e(e.frame);break}},traceKeyEvent:(e,t)=>bi(e,t)},Q0e={getToken:eQ,markAuthRequired:sQ},ehe=(e,t)=>t===void 0?Hn.global.t(e):Hn.global.t(e,t);function the(){const e=q0e();return eY({origin:e.serverHttpUrl,identity:{clientId:e.clientId,clientName:e.clientName,clientVersion:e.clientVersion,clientUiMode:e.clientUiMode},tracer:J0e,credentialStore:Q0e,t:ehe})}const nhe=the();function _t(){return nhe}function ohe(e,t,n){return e==="idle"&&!t&&!n}function X$(e,t){const n=ui(e);return n===null?t:n==="1"}const Cg=Z(X$(cn.notifyEnabled,!0)),L5=Z(X$(cn.notifySound,!0)),$5=Z(typeof Notification<"u"?Notification.permission:"denied"),she="/favicon.ico";async function ihe(e){if(!e){Cg.value=!1,Ls(cn.notifyEnabled,"0");return}if(typeof Notification>"u")return;let t=Notification.permission;if(t==="default")try{t=await Notification.requestPermission()}catch{}$5.value=t,t==="granted"&&(Cg.value=!0,Ls(cn.notifyEnabled,"1"))}function rhe(e){L5.value=e,Ls(cn.notifySound,e?"1":"0")}function N5(...e){for(const t of e){const n=t?.trim();if(n)return n}return""}function lhe(e){return{title:Hn.global.t("settings.notifyTitle"),body:N5(e,Hn.global.t("settings.notifyFallback"))}}function ahe(e,t){return{title:Hn.global.t("settings.notifyQuestionTitle"),body:N5(t,e,Hn.global.t("settings.notifyQuestionFallback"))}}function uhe(e,t){return{title:Hn.global.t("settings.notifyApprovalTitle"),body:N5(t,e,Hn.global.t("settings.notifyApprovalFallback"))}}function F5(e,t,n){if(!Cg.value||typeof Notification>"u")return;const o=Notification.permission;if(o!=="denied"){if(o==="default"){Notification.requestPermission().then(s=>{$5.value=s,s==="granted"&&Ix(e,t,n)});return}Ix(e,t,n)}}function Ix(e,t,n){if(!e.isUserWatching)try{const o=new Notification(t.title,{body:t.body,tag:n,icon:she,silent:!L5.value});o.onclick=()=>{try{window.kimiDesktop?.showWindow?.(),window.focus()}catch{}e.onClick(),o.close()}}catch{}}function che(e,t){F5(t,lhe(t.sessionTitle),`kimi-complete-${e}-${t.promptId??Date.now()}`)}function dhe(e){F5(e,ahe(e.sessionTitle,e.questionPreview),`kimi-question-${e.questionId}`)}function fhe(e){F5(e,uhe(e.sessionTitle,e.toolName),`kimi-approval-${e.approvalId}`)}function phe(){return{notifyEnabled:Cg,notifySound:L5,notifyPermission:$5,setNotifyEnabled:ihe,setNotifySound:rhe,maybeNotifyCompletion:che,maybeNotifyQuestion:dhe,maybeNotifyApproval:fhe}}const hhe=1e3,mhe=4096,Lx=32*1024;function ghe(e,t){let n=null,o;const s=new Set;async function i(f){try{const m=await _t().listTasks(f);e.tasksBySession={...e.tasksBySession,[f]:nC(m,e.tasksBySession[f]??[])},await r(f,m)}catch{}}async function r(f,h){if(e.activeSessionId!==f)return;const m=h??e.tasksBySession[f]??[],v=_t(),k=new Map;if(await Promise.all(m.map(async b=>{if((b.status==="completed"||b.status==="failed"||b.status==="cancelled")&&!s.has(b.id)&&!((b.outputLines?.length??0)>0))try{const g=await v.getTask(f,b.id,{withOutput:!0,outputBytes:Lx});g.outputPreview!==void 0&&k.set(b.id,{preview:g.outputPreview,bytes:g.outputBytes}),s.add(b.id)}catch{}})),k.size===0)return;const w=e.tasksBySession[f]??[];e.tasksBySession={...e.tasksBySession,[f]:w.map(b=>{const _=k.get(b.id)??(b.backgroundTaskId!==void 0?k.get(b.backgroundTaskId):void 0);return _?{...b,outputPreview:_.preview,outputBytes:_.bytes}:b})}}async function l(f){if(e.activeSessionId!==f)return;const h=_t();let m;try{m=await h.listTasks(f)}catch{return}const v=new Map;await Promise.all(m.map(async _=>{const g=_.status==="running",x=_.status==="completed"||_.status==="failed"||_.status==="cancelled";if(!(!g&&!x)&&!(x&&(s.has(_.id)||(_.outputLines?.length??0)>0)))try{const S=await h.getTask(f,_.id,{withOutput:!0,outputBytes:g?mhe:Lx});S.outputPreview!==void 0&&v.set(_.id,{preview:S.outputPreview,bytes:S.outputBytes}),x&&s.add(_.id)}catch{}}));const k=e.tasksBySession[f]??[],w=new Map(k.map(_=>[_.id,_])),b=m.map(_=>{const g=w.get(_.id),x=v.get(_.id);return{..._,outputLines:g?.outputLines,text:g?.text,outputPreview:x?.preview??g?.outputPreview,outputBytes:x?.bytes??g?.outputBytes}});e.tasksBySession={...e.tasksBySession,[f]:nC(b,k)}}function a(f){n!==null&&o===f||(u(),o=f,l(f),n=setInterval(()=>{typeof document<"u"&&document.visibilityState==="hidden"||(e.activeSessionId===f?l(f):u())},hhe))}function u(){n!==null&&(clearInterval(n),n=null),o=void 0,s.clear()}const c=Z(0);let d=null;return Je(()=>t.value.some(f=>f.status==="running"),f=>{f&&d===null?d=setInterval(()=>{c.value=(c.value+1)%Number.MAX_SAFE_INTEGER},1e3):!f&&d!==null&&(clearInterval(d),d=null)},{immediate:!0}),Je(()=>{const f=e.activeSessionId;if(!f)return{sid:void 0,hasRunning:!1};const h=e.tasksBySession[f]??[];return{sid:f,hasRunning:h.some(m=>m.status==="running")}},({sid:f,hasRunning:h},m,v)=>{let k;h&&f!==void 0?a(f):f!==void 0?k=setTimeout(()=>{(e.tasksBySession[f]??[]).some(b=>b.status==="running")||u()},1500):u(),v(()=>{k!==void 0&&clearTimeout(k)})},{deep:!0,immediate:!0}),{taskClock:R(()=>c.value),loadTasksForSession:i}}function m8(e){const t=[];for(const n of e??[])n.kind==="video"?t.push({type:"video",source:{kind:"file",fileId:n.fileId}}):n.kind==="file"?t.push({type:"file",fileId:n.fileId,name:n.name??"",mediaType:n.mediaType||"application/octet-stream",size:n.size??0}):t.push({type:"image",source:{kind:"file",fileId:n.fileId}});return t}const vhe=640,yhe=`(max-width: ${vhe}px)`;function khe(){const e=Z(!1);if(typeof window>"u"||typeof window.matchMedia!="function")return e;const t=window.matchMedia(yhe);e.value=t.matches;const n=o=>{e.value=o.matches};return typeof t.addEventListener=="function"?(t.addEventListener("change",n),bn(()=>t.removeEventListener("change",n))):typeof t.addListener=="function"&&(t.addListener(n),bn(()=>t.removeListener(n))),e}const J$=Z(typeof window>"u"?0:window.innerWidth);let Ih=0,wg=!1;function g8(){J$.value=window.innerWidth}function bhe(){wg||typeof window>"u"||(window.addEventListener("resize",g8),wg=!0,g8())}function Che(){!wg||typeof window>"u"||(window.removeEventListener("resize",g8),wg=!1)}function Q$(e,t,n){return Math.max(t,e-n)}function v8(e,t,n){return Math.min(n,Math.max(t,e))}function eN(){return dn(()=>{Ih+=1,bhe()}),Vn(()=>{Ih=Math.max(0,Ih-1),Ih===0&&Che()}),{viewportWidth:J$}}const whe=24;function _he(e){const t=Z(null),n=Z(!0);let o=null,s=null,i=null,r=0,l=0,a=!1,u=0;function c(){const k=t.value;k&&(k.scrollTop=Math.max(k.scrollTop,r))}function d(){const w=t.value?.firstElementChild??null;w!==i&&(i&&o?.unobserve(i),i=w,w&&o?.observe(w))}function f(){const k=t.value;!k||a||(n.value=r-k.scrollTop-l<whe)}function h(k){k!==u||!a||(a=!1,f())}function m(){n.value=!1,a=!0;const k=++u;if(typeof requestAnimationFrame!="function"){queueMicrotask(()=>h(k));return}requestAnimationFrame(()=>{requestAnimationFrame(()=>h(k))})}function v(){const k=t.value;k&&(o?.disconnect(),s?.disconnect(),i=null,a=!1,u++,r=0,l=0,typeof ResizeObserver=="function"?(o=new ResizeObserver(()=>{const w=t.value;if(!w)return;const{scrollHeight:b,clientHeight:_}=w,g=b>r+1,x=_<l-1;if(r=b,l=_,a){h(u);return}n.value&&(g||x)&&c()}),o.observe(k),d()):(r=k.scrollHeight,l=k.clientHeight,c()),typeof MutationObserver=="function"&&(s=new MutationObserver(d),s.observe(k,{childList:!0})))}return Je(e,()=>{n.value=!0,yt(v)}),Je(t,()=>void yt(v)),dn(()=>void yt(v)),bn(()=>{u++,o?.disconnect(),s?.disconnect()}),{scroller:t,following:n,onScroll:f,pinScroll:m}}function xhe(e){try{const t=ui(e);if(t===null)return null;const n=Number(t);return Number.isFinite(n)?n:null}catch{return null}}function $x(e,t){try{Ls(e,String(t))}catch{}}function She(e){const{storageKey:t,defaultWidth:n,min:o,max:s,reverse:i=!1,axis:r="x",applyLive:l}=e;function a(D){return Number.isFinite(D)?Math.min(Rh(s),Math.max(o,Math.round(D))):n}const u=Z(a(xhe(t)??n)),c=Z(!1);function d(D){const I=D<=o,$=D>=Rh(s),B=r==="x"?"col-resize":"row-resize";if(I&&$)return B;const[H,O]=r==="x"?["e-resize","w-resize"]:["s-resize","n-resize"];return $?i?H:O:I?i?O:H:B}const f=Z(null),h=R(()=>d(f.value??u.value));function m(D){typeof document>"u"||(document.body.style.cursor=d(D))}function v(D){const I=a(D);u.value=I,$x(t,I)}Je(()=>Rh(s),D=>{!c.value&&u.value>D&&v(D)});let k=0,w=0,b=null,_=-1,g=0,x=0,S=0;function T(){if(x=0,!c.value)return;const D=g-k;S=a(w+(i?-D:D)),f.value=S,m(S),l?l(S):u.value=S}function A(D){if(c.value&&(g=r==="x"?D.clientX:D.clientY,x===0)){if(typeof requestAnimationFrame!="function"){T();return}x=requestAnimationFrame(T)}}function E(){if(c.value){if(x!==0&&(cancelAnimationFrame(x),T()),c.value=!1,l?v(S):$x(t,u.value),f.value=null,typeof document<"u"&&(document.body.style.userSelect="",document.body.style.cursor=""),b){try{b.releasePointerCapture(_)}catch{}b.removeEventListener("pointermove",A),b.removeEventListener("pointerup",E),b.removeEventListener("pointercancel",E)}b=null,_=-1}}function P(D){D.preventDefault(),c.value=!0,k=r==="x"?D.clientX:D.clientY,w=a(u.value),S=w,b=D.currentTarget,_=D.pointerId,typeof document<"u"&&(document.body.style.userSelect="none"),m(w);try{b.setPointerCapture(_)}catch{}b.addEventListener("pointermove",A),b.addEventListener("pointerup",E),b.addEventListener("pointercancel",E)}return Vn(E),{width:u,dragging:c,cursor:h,clamp:a,setWidth:v,onPointerDown:P}}const Hr=Z(null),Zd=Z(!1),Ahe=R(()=>Hr.value!==null);function R5(e){const t=Hr.value;!t||Zd.value||(Hr.value=null,t.resolve(e))}async function Mhe(){const e=Hr.value;if(!(!e||Zd.value)){if(!e.action){R5(!0);return}Zd.value=!0;try{await e.action(),Hr.value===e&&(Hr.value=null),e.resolve(!0)}catch(t){Hr.value===e&&(Hr.value=null),e.reject(t)}finally{Zd.value=!1}}}function The(e){return Zd.value?Promise.resolve(!1):(Hr.value&&R5(!1),new Promise((t,n)=>{Hr.value={...e,resolve:t,reject:n}}))}function hu(){return{current:Hr,busy:Zd,isConfirmOpen:Ahe,confirm:The,settle:R5,runAction:Mhe}}function Ehe(e){const{sessionId:t}=e;function n(u){return ui(eC(u))??""}function o(u,c){const d=eC(u);c?Ls(d,c):ur(d)}const s=Z(n(t())),i=Z(null);function r(){const u=i.value;u&&(u.style.height="auto",u.style.height=`${u.scrollHeight}px`)}Je(s,u=>{yt(r),o(t(),u)}),Je(t,(u,c)=>{u!==c&&(o(c,s.value),s.value=n(u),yt(r))});function l(u){s.value=u,yt(()=>{const c=i.value;if(!c)return;c.focus();const d=u.length;c.setSelectionRange(d,d),r()})}function a(){o(t(),"")}return{text:s,textareaRef:i,autosize:r,loadForEdit:l,clearDraft:a}}function Ihe(e){return e?e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable===!0:!1}function Lhe(e){const{sessionId:t,mobile:n,starting:o,dockedComposer:s,emptyComposer:i}=e,r=Z(!1);Je(t,()=>{n()||(r.value=!0)}),Je([r,s,i,o],()=>{if(!r.value)return;const l=s.value??i.value;if(!l)return;const a=typeof document<"u"?document.activeElement:null;if(Ihe(a)){r.value=!1;return}l.focus(),(typeof document>"u"||document.activeElement!==a)&&(r.value=!1)},{flush:"post"})}const _g=100;function $he(e){const t=y1(cn.inputHistory);if(Array.isArray(t)){const n=t.filter(i=>typeof i=="string"&&i.length>0);if(!e||n.length===0)return{};const o=n.length>_g?n.slice(-_g):n,s={[e]:o};return Tc(cn.inputHistory,s),s}return t&&typeof t=="object"?t:{}}function Nhe(e){const{text:t,textareaRef:n,autosize:o,sessionId:s}=e,i=Z($he(s())),r=R(()=>i.value[s()??""]??[]);let l=-1,a="";function u(w){const b=s();if(l=-1,!b)return;const _=w.trim();if(!_)return;const g=i.value[b]??[];if(g.at(-1)===_)return;const x=[...g,_],S=x.length>_g?x.slice(-_g):x;i.value={...i.value,[b]:S},Tc(cn.inputHistory,i.value)}function c(){const w=n.value;return w?(w.selectionStart??0)===0:!1}function d(w){t.value=w,yt(()=>{const b=n.value;if(!b)return;o();const _=w.length;b.setSelectionRange(_,_)})}function f(){const w=r.value;if(w.length!==0){if(l===-1)a=t.value,l=w.length-1;else if(l>0)l-=1;else return;d(w[l])}}function h(){if(l===-1)return;const w=r.value;l<w.length-1?(l+=1,d(w[l])):(l=-1,d(a))}function m(){l=-1}function v(){return l!==-1}function k(){return r.value.length>0}return Je(s,()=>{l=-1}),{push:u,caretAtTextStart:c,recallOlder:f,recallNewer:h,resetBrowsing:m,isBrowsing:v,hasHistory:k}}function Fhe(e){const{text:t,textareaRef:n,autosize:o,skills:s,emitCommand:i,historyPush:r,clearDraft:l}=e,a=Z(!1),u=Z([]),c=Z(0);function d(){const h=t.value;h.startsWith("/")&&!h.includes(" ")?(u.value=mQ(h,CE(s())),c.value=0,a.value=u.value.length>0):a.value=!1}function f(h){if(a.value=!1,h.acceptsInput){t.value=`${h.name} `,yt(()=>{const m=n.value;if(!m)return;const v=t.value.length;m.setSelectionRange(v,v),m.focus(),o()});return}t.value="",l?.(),r(h.name),i(h.name)}return{open:a,items:u,active:c,update:d,select:f}}function Rhe(e){const{text:t,textareaRef:n,autosize:o,searchFiles:s}=e,i=Z(!1),r=Z([]),l=Z(0),a=Z(!1);let u=null;function c(){const h=t.value,m=n.value?.selectionStart??h.length;let v=m-1;for(;v>=0&&!/\s/.test(h[v]);)v--;v++;const k=h.slice(v,m);return k.startsWith("@")?{token:k.slice(1),start:v,end:m}:null}function d(){const h=c(),m=s();if(u!==null&&clearTimeout(u),!h||!m||h.token.length===0){i.value=!1,a.value=!1;return}const v=h.token;u=setTimeout(async()=>{a.value=!0,i.value=!0,l.value=0;const k=()=>{const w=c();return w!==null&&w.token===v&&i.value};try{const w=await m(v);k()&&(r.value=w)}catch{k()&&(r.value=[])}finally{k()&&(a.value=!1)}},200)}function f(h){const m=c();if(!m)return;const v=t.value;t.value=v.slice(0,m.start)+h.path+v.slice(m.end),i.value=!1,yt(()=>{const k=n.value;if(!k)return;const w=m.start+h.path.length;k.setSelectionRange(w,w),k.focus(),o()})}return{open:i,items:r,active:l,loading:a,update:d,select:f}}const Ohe="kimi-web.file-preview-width",gd=320;function Phe({client:e,sideWidth:t,detailTarget:n,closeFilePreview:o}){const{viewportWidth:s}=eN(),i=R(()=>Math.max(0,s.value-t.value)),r=R(()=>Q$(i.value,gd,gd));function l(Y){return v8(Math.round(Y),gd,r.value)}function a(){return l(i.value/2)}const u=R(()=>a()),c=Z(u.value),d=R(()=>v8(c.value,gd,r.value)),f=Z(null),h=R(()=>{const Y=f.value;if(!Y)return null;const fe=e.turns.value.find(we=>we.id===Y.turnId);return fe?.role==="compaction"&&fe.text?fe.text:null}),m=R(()=>h.value!==null);function v(Y){if(f.value?.turnId===Y.turnId){f.value=null,n.value==="compaction"&&(n.value=null);return}n.value="compaction",f.value=Y}function k(){f.value=null,n.value==="compaction"&&(n.value=null)}const w=Z(null),b=R(()=>{const Y=w.value;if(!Y)return{entry:void 0,version:0};const fe=e.auxiliaryTranscripts.getEntry(Y.sessionId,Y.subagentId);return{entry:fe,version:fe?.version.value??0}});function _(Y){const fe=e.turns.value.flatMap(we=>we.tools??[]).find(we=>we.agentId===Y);if(!fe)return{};try{const we=JSON.parse(fe.arg);return{name:typeof we.description=="string"?we.description:void 0,subagentType:typeof we.subagent_type=="string"?we.subagent_type:void 0,status:fe.status,outputLines:fe.output}}catch{return{}}}const g=R(()=>{const Y=w.value;if(!Y)return null;const fe=e.activeAppTasks.value.find(Fe=>Fe.agentId===Y.subagentId||Fe.id===Y.subagentId);if(fe)return UY(fe);const we=b.value.entry?.channel,ge=we?.agents.find(Fe=>Fe.agentId===Y.subagentId),Q=we?.refreshError??!1,te=we===void 0||we.loading,ce=we?.snapshot.meta.activity==="turn",ue=_(Y.subagentId),Se=we?.snapshot.items.findLast(Fe=>Fe.kind==="turn"),ze=Se?.kind==="turn"&&Se.state==="cancelled",_e=Se?.kind==="turn"&&Se.state==="failed"||ue.status==="error",Ee=ce?"working":_e||ze?"failed":te?"queued":Q&&ue.status===void 0?"failed":"completed",it=ce?"running":ze?"cancelled":_e?"failed":te?"running":Q&&ue.status===void 0?"failed":"completed";return{id:Y.subagentId,name:ge?.label??ue.name??Y.subagentId,subagentType:ue.subagentType??(ge?.type==="sub"?"subagent":ge?.type),phase:Ee,status:it,outputLines:ue.outputLines}}),x=R(()=>{const Y=b.value.entry;if(!Y)return[];const fe=w.value,we=Y.channel.agents.find(ge=>ge.agentId===fe?.subagentId);return nX(Y.channel.snapshot,e.getFileUrl,we)}),S=R(()=>b.value.entry?.channel.loading??!1),T=R(()=>b.value.entry?.channel.refreshError??!1),A=R(()=>b.value.entry?.channel.loadingOlder??!1),E=R(()=>b.value.entry?.channel.loadOlderError??!1),P=R(()=>b.value.entry?.channel.snapshot.hasMoreOlder??!1),D=R(()=>b.value.entry?.channel.snapshot.meta.activity==="turn"),I=R(()=>g.value!==null);function $(Y){const fe=e.activeSessionId.value;if(!(!Y||!fe)){if(n.value==="agent"&&w.value?.sessionId===fe&&w.value.subagentId===Y){B();return}w.value={sessionId:fe,subagentId:Y},n.value="agent",e.auxiliaryTranscripts.activate(fe,Y)}}function B(){const Y=w.value;Y&&e.auxiliaryTranscripts.deactivate(Y.sessionId,Y.subagentId),w.value=null,n.value==="agent"&&(n.value=null)}Je(n,(Y,fe)=>{if(fe!=="agent"||Y==="agent")return;const we=w.value;we&&e.auxiliaryTranscripts.deactivate(we.sessionId,we.subagentId)});function H(){const Y=b.value.entry;Y&&Y.channel.loadOlder().catch(()=>{})}const O=Z("list"),F=Z(null);function U(){if(n.value==="diff"){z();return}n.value="diff",O.value="list",F.value=null,e.loadGitStatus(e.activeSessionId.value)}function z(){n.value==="diff"&&(n.value=null),O.value="list",F.value=null,e.clearFileDiff()}async function W(Y){O.value="detail",F.value=Y,await e.loadFileDiff(Y)}const K=Xr(null);function V(Y){if(K.value===Y&&n.value==="turn-diff"){ie();return}K.value=Y,n.value="turn-diff"}function ie(){K.value=null,n.value==="turn-diff"&&(n.value=null)}async function ne(Y){if(!e.activeSessionId.value&&e.activeWorkspaceId.value){const fe=await e.startSessionAndOpenSideChat(e.activeWorkspaceId.value,Y);return n.value="btw",fe}return await e.openSideChat(Y),n.value="btw",null}function X(){e.closeSideChat(),n.value==="btw"&&(n.value=null)}function le(){n.value==="btw"&&(n.value=null)}const Ie=R(()=>e.sideChatVisible.value),de=R(()=>n.value!==null&&(n.value!=="compaction"||m.value)&&(n.value!=="agent"||I.value)&&(n.value!=="btw"||Ie.value)),pe=Z(!1),ve=Z({});function oe(){switch(n.value){case"compaction":return f.value?{kind:"compaction",...f.value}:null;case"agent":return w.value?{kind:"agent",...w.value}:null;case"btw":return{kind:"btw"};default:return null}}function ye(Y){if(Y)switch(Y.kind){case"compaction":f.value={turnId:Y.turnId},n.value="compaction";break;case"agent":e.activeSessionId.value&&(w.value={sessionId:e.activeSessionId.value,subagentId:Y.subagentId},n.value="agent",e.auxiliaryTranscripts.activate(e.activeSessionId.value,Y.subagentId));break;case"btw":e.sideChatVisible.value&&(n.value="btw");break}}function G(){return n.value==="compaction"&&m.value?(k(),!0):n.value==="agent"&&I.value?(B(),!0):n.value==="file"?(o(),!0):n.value==="diff"?(z(),!0):n.value==="turn-diff"?(ie(),!0):n.value==="btw"?(X(),!0):!1}return Je(e.activeSessionId,(Y,fe)=>{if(fe){const we=oe();we?ve.value[fe]=we:delete ve.value[fe]}o(),k(),B(),z(),ie(),le(),Y&&ye(ve.value[Y])}),{PREVIEW_WIDTH_KEY:Ohe,PREVIEW_MIN:gd,previewDefaultWidth:u,previewMax:r,previewWidth:c,previewPanelWidth:d,compactionPanelText:h,compactionPanelVisible:m,openCompactionPanel:v,closeCompactionPanel:k,agentPanelMember:g,agentPanelTurns:x,agentPanelLoading:S,agentPanelLoadError:T,agentPanelLoadingMore:A,agentPanelLoadMoreError:E,agentPanelHasMore:P,agentPanelRunning:D,agentPanelVisible:I,openAgentPanel:$,closeAgentPanel:B,loadOlderAgentMessages:H,detailDiffMode:O,detailDiffPath:F,openDiffDetail:U,closeDiffDetail:z,selectDiffFile:W,turnDiffChange:K,openTurnDiff:V,closeTurnDiff:ie,btwVisible:Ie,openSideChatTab:ne,closeSideChat:X,hideSideChatPanel:le,sidePanelVisible:de,panelDragging:pe,closeOpenSidePanel:G}}const Dhe=cn.sidebarWidth,Nx=cn.sidebarCollapsed,Fx=270,v4=220,Bhe=480,Hhe=320;function zhe(e={}){const{viewportWidth:t}=eN(),n=Z(Fx),o=Z(!1),s=Z(!1),i=R(()=>{const c=Hhe+(Rh(e.previewOpen)?gd:0);return Math.min(Bhe,Q$(t.value,v4,c))}),r=R(()=>v8(n.value,v4,i.value));function l(){try{o.value=ui(Nx)==="true"}catch{o.value=!1}}function a(){try{Ls(Nx,String(o.value))}catch{}}function u(){o.value=!o.value,a()}return{SIDEBAR_WIDTH_KEY:Dhe,SIDEBAR_DEFAULT:Fx,SIDEBAR_MIN:v4,sidebarMax:i,sessionColWidth:n,sidebarCollapsed:o,sidebarDragging:s,sideWidth:r,loadSidebarCollapsed:l,toggleSidebarCollapse:u}}const Whe=40409;function Rx(e){return Us(e)&&e.code===Whe}function Ox(e){return e.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(e)||e.startsWith("\\\\")}function Px(e){if(e.startsWith("\\\\"))return e;const t=/^[a-zA-Z]:/.test(e)?e.slice(0,2):"",n=[];for(const o of e.slice(t.length).split(/[\\/]+/))if(!(!o||o===".")){if(o===".."){n.pop();continue}n.push(o)}return t?`${t}/${n.join("/")}`:`/${n.join("/")}`}function Uhe({client:e,detailTarget:t,t:n}){const o=Z(null),s=Z(null),i=Z(!1),r=Z(null),l=Z(null);let a=0;const u=R(()=>{const g=l.value;return g?e.getFileDownloadUrl(g):null}),c=R(()=>o.value!==null&&l.value!==null);function d(g){return g.length>1?g.replace(/\/+$/,""):g}function f(g){const x=h2(g,e.status.value.cwd);return x===null||x.split(/[\\/]+/).includes("..")?null:h(x)||null}function h(g){const x=[];for(const S of g.split(/[\\/]+/))if(!(!S||S===".")){if(S===".."){x.pop();continue}x.push(S)}return x.join("/")}function m(g){const x=g.trim();if(!x)return{error:n("filePreview.errors.emptyPath")};if(/^[a-z][a-z0-9+.-]*:\/\//i.test(x))return{error:n("filePreview.errors.unsupportedPath")};if(x.startsWith("~"))return{error:n("filePreview.errors.outsideWorkspace")};const S=d(e.status.value.cwd);if(x.startsWith("/")){if(!S||x!==S&&!x.startsWith(`${S}/`))return{error:n("filePreview.errors.outsideWorkspace")};const A=x===S?"":x.slice(S.length+1);if(A.split(/[\\/]+/).includes(".."))return{error:n("filePreview.errors.outsideWorkspace")};const E=h(A);return E?{path:E}:{error:n("filePreview.errors.isDirectory")}}if(x.split(/[\\/]+/).includes(".."))return{error:n("filePreview.errors.outsideWorkspace")};const T=h(x);return T?{path:T}:{error:n("filePreview.errors.emptyPath")}}async function v(g){const x=o.value;if(t.value==="file"&&x&&x.path===g.path&&x.line===g.line){w();return}const S=++a;if(t.value="file",s.value=null,r.value=null,i.value=!0,o.value=g,l.value=null,typeof g.content=="string"){i.value=!1,s.value={path:g.path,content:g.content,encoding:"utf-8",mime:"text/markdown",isBinary:!1,size:g.content.length};return}if(!Ox(g.path)&&g.path.split(/[\\/]+/).includes("..")){const A=d(e.status.value.cwd);A&&(g={...g,path:Px(`${A}/${g.path}`)})}if(Ox(g.path)){g={...g,path:Px(g.path)};const A=f(g.path);if(A!==null)g={...g,path:A};else{try{const E=await e.readHostFileContent(g.path);if(S!==a)return;l.value=null,s.value={path:g.path,content:E.content,encoding:E.encoding,mime:E.mime,isBinary:E.isBinary,size:E.size}}catch(E){if(S!==a)return;r.value=Rx(E)?n("filePreview.errors.notFound"):pU(E)?n("filePreview.errors.tooLarge"):E instanceof Error?E.message:n("filePreview.errors.loadFailed")}finally{S===a&&(i.value=!1)}return}}const T=m(g.path);if("error"in T){i.value=!1,r.value=T.error;return}l.value=T.path;try{const A=await e.readFileContent(T.path);if(S!==a)return;A?s.value={...A,path:A.path||T.path}:r.value=n("filePreview.errors.loadFailed")}catch(A){if(S!==a)return;r.value=Rx(A)?n("filePreview.errors.notFound"):A instanceof Error?A.message:n("filePreview.errors.loadFailed")}finally{S===a&&(i.value=!1)}}function k(){a+=1,o.value=null,l.value=null,s.value=null,r.value=null,i.value=!1}function w(){k(),t.value==="file"&&(t.value=null)}Je(t,(g,x)=>{x==="file"&&g!=="file"&&k()});function b(){const g=s.value?.path??o.value?.path;g&&e.openWorkspaceFile(g,o.value?.line)}function _(){const g=s.value?.path??o.value?.path;g&&e.revealWorkspaceFile(g)}return{previewTarget:o,previewFile:s,previewLoading:i,previewError:r,previewDownloadUrl:u,previewExternalActions:c,openFilePreview:v,closeFilePreview:w,openPreviewInEditor:b,revealPreviewFile:_}}function jhe({running:e,title:t="Kimi Code"}){if(Wp){I4(()=>{typeof document<"u"&&(document.title=t)});return}const n=["◐","◓","◑","◒"],o=Z(0);let s=null;function i(){s===null&&(o.value=0,s=setInterval(()=>{o.value=(o.value+1)%n.length},250))}function r(){s!==null&&(clearInterval(s),s=null),o.value=0}Je(e,a=>{a?i():r()},{immediate:!0});const l=R(()=>`${e.value?`${n[o.value]} `:""}${t}`);I4(()=>{typeof document<"u"&&(document.title=l.value)}),bn(()=>{r()})}const Vhe=50,am=5,O5=5,xg=50,qhe=40401,Khe=40402,Zhe=40410,Ghe=40409,Yhe=40902,Xhe=2e3,Jhe=10;function y4(e){return Us(e)&&e.code===Yhe}const Qhe=40904;function eme(e){return Us(e)&&e.code===Qhe}const Hu=Go({}),Lh=Go({}),k4=Go({}),cl=Go(new Set),N2=new Map,wc=new Map,Sg=new Map;let tme=0;const ju=new Map,nme=3;let Dx=0;function ome(){return Dx+=1,`${Date.now().toString(36)}-${Dx}`}function sme(e){return{generation:N2.get(e)??0,pending:(wc.get(e)?.size??0)>0}}function y8(e){const t=++tme;N2.set(e,t);const n=wc.get(e)??new Set;return n.add(t),wc.set(e,n),t}function k8(e,t){const n=wc.get(e);if(n===void 0||(n.delete(t),n.size>0))return;wc.delete(e);const o=Sg.get(e);Sg.delete(e),o?.()}function ime(e){N2.delete(e),wc.delete(e),Sg.delete(e),ju.delete(e)}function rme(e,t){return!t.pending&&t.generation===(N2.get(e)??0)}function lme(e,t){if((wc.get(e)?.size??0)===0){t();return}Sg.set(e,t)}function ame(e,t){const{t:n}=Hn.global,{confirm:o}=hu(),{taskPoller:s,sideChat:i,modelProvider:r,pushOperationFailure:l,activity:a,sessionsKnownEmpty:u,setSessions:c,updateSession:d,upsertSessionFront:f,appendSession:h,forgetSession:m,unpinSessions:v,setActiveSessionId:k,updateSessionMessages:w,nextOptimisticMsgId:b,getEventConn:_,syncSessionFromSnapshot:g,reopenSession:x,hasLoadedMessages:S,refreshSessionStatus:T,refreshSessionGoal:A,refreshSessionPlans:E,persistSessionProfile:P,mergedWorkspaces:D,workspacesView:I,status:$,workspaceIdForSession:B,savePermissionToStorage:H,savePlanModeToStorage:O,saveSwarmModeToStorage:F,saveGoalModeToStorage:U,draftModes:z,saveUnread:W,saveActiveWorkspaceToStorage:K,saveHiddenWorkspacesToStorage:V,goalErrorMessage:ie,initialized:ne,connectIssue:X,selectedDiffPath:le,fileDiffLines:Ie,fileDiffLoading:de,fileDiffTexts:pe,fileDiffEmptyFile:ve}=t;let oe=!1,ye=0;function G(se,xe,J,Ce){w(se,$e=>{const He=$e.findIndex(Et=>Et.id===xe);if(He===-1)return $e;const vt=$e.findIndex((Et,ln)=>ln!==He&&Et.role==="user"&&(Et.id===Ce||Et.userMessageId===Ce||Et.promptId===J)),ut=$e[He],Dt=vt===-1?ut:$e[vt];return $e.flatMap((Et,ln)=>ln===vt?[]:ln!==He?[Et]:[{...Dt,id:ut.id,promptId:J,userMessageId:Ce,metadata:{...Dt.metadata,...ut.metadata}}])})}async function Y(se){if(e.messagesLoadingMoreBySession[se])return;const xe=e.messagesBySession[se];if(!xe||xe.length===0)return;const J=xe[0].id;e.messagesLoadingMoreBySession={...e.messagesLoadingMoreBySession,[se]:!0},e.messagesLoadMoreErrorBySession={...e.messagesLoadMoreErrorBySession,[se]:!1};try{const Ce=await _t().listMessages(se,{beforeId:J,pageSize:Vhe}),$e=[...Ce.items].reverse();w(se,He=>[...$e,...He]),e.messagesHasMoreBySession={...e.messagesHasMoreBySession,[se]:Ce.hasMore}}catch(Ce){e.messagesLoadMoreErrorBySession={...e.messagesLoadMoreErrorBySession,[se]:!0},l("loadOlderMessages",Ce,{sessionId:se})}finally{e.messagesLoadingMoreBySession={...e.messagesLoadingMoreBySession,[se]:!1}}}function fe(se,xe){s.loadTasksForSession(se),Q(se),xe?.skipStatus!==!0&&T(se),A(se),E(se),Object.prototype.hasOwnProperty.call(r.skillsBySession.value,se)||r.loadSkillsForSession(se)}async function we(se){const xe=e.activeSessionId;if(xe){le.value=se,Ie.value=[],pe.value=null,ve.value=!1,de.value=!0;try{const Ce=await _t().getFileDiff(xe,se);if(le.value!==se||e.activeSessionId!==xe)return;const $e=wX(Ce.diff);if(Ie.value=$e,$e.length===0){const vt=await Ei(se).catch(()=>null);if(le.value!==se||e.activeSessionId!==xe)return;ve.value=vt!==null&&vt.size===0;return}de.value=!1;const He=await cX($e,{truncated:Ce.truncated,readNewText:async()=>{const vt=await Ei(se).catch(()=>null);return!vt||vt.isBinary||vt.encoding!=="utf-8"?null:vt.content}});if(le.value!==se||e.activeSessionId!==xe)return;pe.value=He}catch(J){le.value===se&&(Ie.value=[]),gl("[loadFileDiff] diff unavailable for",se,J)}finally{le.value===se&&(de.value=!1)}}}function ge(){le.value=null,Ie.value=[],pe.value=null,ve.value=!1,de.value=!1}async function Q(se){try{const J=await _t().getGitStatus(se);e.gitStatusBySession={...e.gitStatusBySession,[se]:J}}catch{}}let te=0;async function ce(se){try{const xe=await _t().getUserInfo();if(se!==te||e.managedProviderStatus!=="authenticated")return;e.managedUserInfo=xe.kind==="ok"?xe.userInfo:null,xe.kind==="ok"?e.managedMembership=xe.userInfo.userLevel===Jhe?"free":"member":e.managedMembership=xe.status===402?"free":null}catch{if(se!==te)return;e.managedProviderStatus==="authenticated"&&(e.managedUserInfo=null,e.managedMembership=null)}}async function ue(){e.managedProviderStatus==="authenticated"&&await ce(++te)}async function Se(){const se=++te;try{const J=await _t().getAuth();return e.authReady=J.ready,e.defaultModel=J.defaultModel,e.managedProviderStatus=J.managedProvider?.status??null,e.managedProviderStatus==="authenticated"?ce(se):(e.managedUserInfo=null,e.managedMembership=null),X.value=null,"proceed"}catch(xe){return Us(xe)&&(xe.code===401||xe.code===PM)?(X.value=null,"server-auth-required"):(X.value=(xe instanceof Error?xe.message:String(xe)).slice(0,140),"retry")}}async function ze(){let se=!0;for(;;){const xe=await Se();if(xe!=="retry")return xe;se&&(X.value=null,se=!1),await new Promise(J=>{setTimeout(J,Xhe)})}}async function _e(){try{const se=_t();e.config=await se.getConfig()}catch{}}async function Ee(se){try{const J=await _t().setConfig(se);return e.config=J,e.defaultModel=J.defaultModel??null,!0}catch(xe){return l("setConfig",xe),!1}}const it=100,Fe=720*60*1e3;async function Oe(se){const xe=_t(),J=[];let Ce,$e;for(;se?.shouldContinue?.()!==!1;){let He;try{He=await xe.listSessions({pageSize:it,beforeId:Ce,excludeEmpty:!0})}catch(vt){if(J.length===0)throw vt;$e=vt;break}if(J.push(...He.items),!He.hasMore||He.items.length===0)break;Ce=He.items[He.items.length-1].id}return{sessions:J,error:$e}}function Ge(se){const xe=new Map(e.sessions.map(J=>[J.id,J]));c(se.map(J=>{const Ce=xe.get(J.id);if(Ce===void 0)return J;const $e=o3(J.usage)&&!o3(Ce.usage),He=J.pullRequest??Ce.pullRequest;return!$e&&He===J.pullRequest?J:{...J,usage:$e?Ce.usage:J.usage,pullRequest:He}}))}function at(se){const xe=[...se],J=new Set(xe.map(Ce=>Ce.id));for(const Ce of e.sessions)J.has(Ce.id)||(xe.push(Ce),J.add(Ce.id));return xe.sort((Ce,$e)=>new Date($e.updatedAt).getTime()-new Date(Ce.updatedAt).getTime()),xe}async function Tt(se){const xe=_t(),J=[],Ce=Date.now(),$e=Et=>Ce-new Date(Et.updatedAt).getTime();let He,vt=!1,ut=!0,Dt;for(;;){let Et;try{Et=await xe.listSessions({workspaceId:se,pageSize:am,beforeId:He,excludeEmpty:!0})}catch(Ot){if(ut)throw Ot;Dt=Ot,vt=!0;break}if(vt=Et.hasMore,Et.items.length===0)break;const ln=Et.items[Et.items.length-1],oo=$e(ln)>=Fe;if(!ut&&oo){const Ot=Et.items.findIndex(Yn=>$e(Yn)>=Fe),Pt=Ot>=0?Ot+1:Et.items.length;J.push(...Et.items.slice(0,Pt)),vt=Et.hasMore||Pt<Et.items.length;break}if(J.push(...Et.items),ut=!1,!Et.hasMore||oo)break;He=ln.id}return{workspaceId:se,page:{items:J,hasMore:vt},error:Dt}}async function Bt(){const se=e.workspaces;if(se.length===0){const Ot=await Oe(),Pt=Ot.error===void 0?Ot.sessions:at(Ot.sessions);return e.sessionsHasMoreByWorkspace={},e.sessionsCursorByWorkspace={},e.sessionsInitialCountByWorkspace={},e.sessionsFullyLoaded=Ot.error===void 0,Ot.error!==void 0&&l("load",Ot.error),Pt}const xe=await Promise.allSettled(se.map(Ot=>Tt(Ot.id))),J=[],Ce=new Set,$e=new Map,He=new Set;let vt;for(let Ot=0;Ot<xe.length;Ot++){const Pt=xe[Ot];if(Pt.status==="fulfilled"){$e.set(Pt.value.workspaceId,Pt.value.page),Pt.value.error!==void 0&&(He.size===0&&(vt=Pt.value.error),He.add(Pt.value.workspaceId));for(const Yn of Pt.value.page.items)Ce.has(Yn.id)||(J.push(Yn),Ce.add(Yn.id));continue}He.size===0&&(vt=Pt.reason),He.add(se[Ot].id)}if($e.size===0){l("load",vt);return}const ut=new Set(se.filter(Ot=>He.has(Ot.id)).map(Ot=>Ot.root)),Dt=new Set(se.map(Ot=>Ot.id));for(const Ot of e.sessions)!(Ot.workspaceId!==void 0&&Dt.has(Ot.workspaceId)?He.has(Ot.workspaceId):ut.has(Ot.cwd)||He.has(B(Ot)))||Ce.has(Ot.id)||(J.push(Ot),Ce.add(Ot.id));const Et={},ln={},oo={};for(const{id:Ot}of se){const Pt=$e.get(Ot);if(Pt===void 0){const Yn=e.sessionsHasMoreByWorkspace[Ot],ko=e.sessionsCursorByWorkspace[Ot],vs=e.sessionsInitialCountByWorkspace[Ot];Yn!==void 0&&(Et[Ot]=Yn),ko!==void 0&&(ln[Ot]=ko),vs!==void 0&&(oo[Ot]=vs);continue}Et[Ot]=Pt.hasMore,ln[Ot]=Pt.items.length>0?Pt.items[Pt.items.length-1].id:void 0,oo[Ot]=Math.max(Pt.items.length,am)}return e.sessionsHasMoreByWorkspace=Et,e.sessionsCursorByWorkspace=ln,e.sessionsInitialCountByWorkspace=oo,e.sessionsFullyLoaded=!1,J.sort((Ot,Pt)=>new Date(Pt.updatedAt).getTime()-new Date(Ot.updatedAt).getTime()),He.size>0&&l("load",vt),J}async function Yt(se){if(!e.sessionsLoadingMoreByWorkspace[se]&&e.sessionsHasMoreByWorkspace[se]!==!1&&e.sessionsCursorByWorkspace[se]!==void 0){e.sessionsLoadingMoreByWorkspace={...e.sessionsLoadingMoreByWorkspace,[se]:!0};try{let xe=e.sessionsCursorByWorkspace[se],J;for(let He=0;He<3&&xe!==void 0&&(J=await _t().listSessions({workspaceId:se,pageSize:O5,beforeId:xe,excludeEmpty:!0}),e.sessionsCursorByWorkspace[se]!==xe);He+=1)J=void 0,xe=e.sessionsCursorByWorkspace[se];if(J===void 0)return;const Ce=new Set(e.sessions.map(He=>He.id)),$e=J.items.filter(He=>!Ce.has(He.id));$e.length>0&&c([...e.sessions,...$e]),e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[se]:J.items.length>0?J.items[J.items.length-1].id:xe},e.sessionsHasMoreByWorkspace={...e.sessionsHasMoreByWorkspace,[se]:J.hasMore}}catch(xe){l("loadMoreSessions",xe)}finally{e.sessionsLoadingMoreByWorkspace={...e.sessionsLoadingMoreByWorkspace,[se]:!1}}}}function Sn(se){return e.sessions.filter(xe=>!xe.parentSessionId&&B(xe)===se)}const on=5;function en(se,xe){const J=new Set(e.sessions.map(He=>He.id)),Ce=se.items.filter(He=>!J.has(He.id)&&(He.meta.last_prompt??"").length>0).map(kU);Ce.length>0&&c([...e.sessions,...Ce]);for(const He of se.items)if(J.has(He.id)&&He.git!==void 0){const vt=He.git.pull_request;d(He.id,ut=>ut.pullRequest===vt?ut:{...ut,pullRequest:vt})}if(se.items.length>0){const He=Math.min(...se.items.map(vt=>vt.meta.updated_at));e.flatSessionsFrontier=xe?.resetFrontier===!0||e.flatSessionsFrontier===null?He:Math.min(e.flatSessionsFrontier,He)}e.flatSessionsNextPageToken=se.nextPageToken,e.flatSessionsHasMore=se.hasMore;const $e=new Set(I.value.map(He=>He.id));return se.items.filter(He=>(He.meta.last_prompt??"").length>0&&$e.has(B({workspaceId:He.workspace.id,cwd:He.workspace.cwd??""}))).length}async function Cn(){const se=await _t().listSessionsV2({pageSize:xg,include:"git"});en(se,{resetFrontier:!0}),e.flatSessionsSeeded=!0}async function Mn(){if(!(e.flatSessionsSeeded||e.flatSessionsLoading)){e.flatSessionsLoading=!0;try{await Cn()}catch(se){l("ensureFlatSessions",se)}finally{e.flatSessionsLoading=!1}}}async function We(){if(!(e.flatSessionsLoading||e.flatSessionsLoadingMore)&&e.flatSessionsHasMore){e.flatSessionsLoadingMore=!0;try{if(!e.flatSessionsSeeded){await Cn();return}if(e.flatSessionsNextPageToken===null)return;for(let se=0;se<on;se+=1){const xe=e.flatSessionsNextPageToken;if(xe===null||!e.flatSessionsHasMore)break;let J;try{J=await _t().listSessionsV2({pageSize:xg,pageToken:xe,include:"git"})}catch(Ce){if(!mU(Ce))throw Ce;e.flatSessionsNextPageToken=null,await Cn();break}if(en(J)>0)break}}catch(se){l("loadMoreFlatSessions",se)}finally{e.flatSessionsLoadingMore=!1}}}async function tt(se,xe,J,Ce){if(e.sessionsCursorByWorkspace[se]===xe){const He=new Date(J).getTime();let vt;for(const ut of e.sessions){if(B(ut)!==se)continue;const Dt=new Date(ut.updatedAt).getTime();Dt<=He||(vt===void 0||Dt<new Date(vt.updatedAt).getTime())&&(vt=ut)}e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[se]:vt?.id}}let $e=3;for(;$e>0&&Sn(se).length<Ce&&(e.sessionsHasMoreByWorkspace[se]??!1);){const He=e.sessionsCursorByWorkspace[se],vt=Sn(se).length;if(He===void 0)try{const ut=await _t().listSessions({workspaceId:se,pageSize:am,excludeEmpty:!0}),Dt=new Set(e.sessions.map(ln=>ln.id)),Et=ut.items.filter(ln=>!Dt.has(ln.id));Et.length>0&&c([...e.sessions,...Et].sort((ln,oo)=>new Date(oo.updatedAt).getTime()-new Date(ln.updatedAt).getTime())),e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[se]:ut.items.length>0?ut.items[ut.items.length-1].id:void 0},e.sessionsHasMoreByWorkspace={...e.sessionsHasMoreByWorkspace,[se]:ut.hasMore}}catch(ut){l("loadMoreSessions",ut);break}else await Yt(se);if($e-=1,Sn(se).length===vt&&e.sessionsCursorByWorkspace[se]===He)break}}async function Ue(){if(e.sessionsFullyLoaded)return;const se=await Oe().catch(Ce=>(gl("[kimi-web] loadAllSessions failed; search covers only loaded sessions",Ce),null));if(se===null)return;const xe=se.error===void 0?se.sessions:at(se.sessions);if(Ge(xe),e.sessionsFullyLoaded=se.error===void 0,se.error!==void 0)return;const J={};for(const Ce of e.workspaces)J[Ce.id]=!1;e.sessionsHasMoreByWorkspace=J}async function Lt(){const se=await _t().getMeta().catch(()=>null);se!==null&&(e.serverVersion=se.serverVersion,e.availableOpenInApps=se.openInApps,e.dangerousBypassAuth=se.dangerousBypassAuth,e.experimentalFlags=se.experimentalFlags,e.backend=se.backend)}async function gt(){const se=Date.now();let xe="accepted";bi("app:load:start"),e.loading=!0;const J=!ne.value;let Ce=!0;try{if(J&&await ze()==="server-auth-required"){Ce=!1,xe="auth-required";return}const $e=_t();await Promise.all([$e.getHealth().catch(()=>null),Lt(),r.loadModels()]),J||await Se(),await _e(),await wn();const He=await Bt(),vt=He??e.sessions;if(He!==void 0&&Ge(He),!J&&He!==void 0&&e.flatSessionsSeeded){e.flatSessionsSeeded=!1,e.flatSessionsNextPageToken=null,e.flatSessionsHasMore=!0,e.flatSessionsFrontier=null;try{await Cn()}catch(Ot){l("ensureFlatSessions",Ot)}}const ut=_E().filter(Ot=>!e.sessions.some(Pt=>Pt.id===Ot));if(ut.length>0){const Ot=await Promise.all(ut.map(Yn=>$s(Yn))),Pt=ut.filter((Yn,ko)=>Ot[ko]==="stale");Pt.length>0&&v(Pt)}const Dt=vt[0],Et=e.activeWorkspaceId;!(Et!==null&&D.value.some(Ot=>Ot.id===Et))&&Dt&&go(B(Dt)),Oo();const oo=typeof window<"u"?Qb(window.location):void 0;!e.activeSessionId&&oo!==void 0&&(e.sessions.some(Pt=>Pt.id===oo)||await no(oo))&&await vo(oo,{urlMode:"replace"}),!e.activeSessionId&&vt.length>0&&await vo(vt[0].id,{urlMode:"replace"})}catch($e){xe="failed",l("load",$e)}finally{e.loading=!1,Ce&&(ne.value=!0),bi("app:load:complete",{status:xe,sessionId:e.activeSessionId,sessionCount:e.sessions.length,workspaceCount:e.workspaces.length,durationMs:Date.now()-se})}}async function wn(){try{const se=_t(),[xe,J]=await Promise.all([se.listWorkspaces().catch(()=>[]),se.getFsHome().catch(()=>({home:"",recentRoots:[]}))]);e.workspaces=yn(xe),e.fsHome=J.home||null,e.recentRoots=J.recentRoots}catch{}}function yn(se){const xe=lh();return Object.keys(xe).length===0?se:se.map(J=>{const Ce=xe[J.root];return Ce!==void 0?{...J,name:Ce}:J})}function go(se){e.activeWorkspaceId=se,K(se)}function qt(se){go(se);const xe=e.sessions.filter(J=>B(J)===se);if(xe.length>0){const J=xe[0];J&&J.id!==e.activeSessionId&&vo(J.id)}else k(void 0),Nn(void 0,"push")}function ps(se){const xe=lh()[se.root],J=xe!==void 0?{...se,name:xe}:se,Ce=Pr(J.root);e.hiddenWorkspaceRoots.some(vt=>Pr(vt)===Ce)&&(e.hiddenWorkspaceRoots=e.hiddenWorkspaceRoots.filter(vt=>Pr(vt)!==Ce),V(e.hiddenWorkspaceRoots));const $e=e.workspaces.findIndex(vt=>vt.id===J.id||vt.root===J.root);if($e===-1){e.workspaces=[J,...e.workspaces];return}const He=[...e.workspaces];He[$e]=J,e.workspaces=He}function xs(se){if(se.type==="workspaceCreated"||se.type==="workspaceUpdated"){ps(se.workspace);return}const xe=e.workspaces.find(Ce=>Ce.id===se.workspaceId)?.root??se.root;if(xe&&!e.hiddenWorkspaceRoots.includes(xe)&&(e.hiddenWorkspaceRoots=[...e.hiddenWorkspaceRoots,xe],V(e.hiddenWorkspaceRoots)),e.workspaces=e.workspaces.filter(Ce=>Ce.id!==se.workspaceId&&Ce.root!==xe),e.activeWorkspaceId===se.workspaceId||e.activeWorkspaceId===xe){const Ce=I.value[0]?.id??null;if(e.activeWorkspaceId=Ce,Ce)K(Ce);else try{ur(cn.activeWorkspace)}catch{}k(void 0),e.sessionLoading=!1,ge(),Nn(void 0,"replace")}}function _n(){k(void 0),Nn(void 0,"push")}function In(se){go(se),_n(),ge()}async function To(se){const xe=D.value.find(ln=>ln.id===se);if(!xe)return null;const J=e.thinking,Ce=_t();let $e,He=xe.root;try{const ln=await Ce.addWorkspace({root:xe.root});$e=ln.id,He=ln.root,ps(ln)}catch{}const vt=r.draftModel.value??void 0,ut=await Ce.createSession({workspaceId:$e,cwd:He,model:vt});r.draftModel.value=null;const Dt=vt!==void 0&&(!ut.model||ut.model.length===0)?{...ut,model:vt}:ut;f(Dt);const Et=ut.id;return J!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[Et]:J},k3(e,Et)),go(ut.workspaceId??$e??se),await vo(ut.id,{skipStatusRefresh:!0}),z.planMode&&(e.planModeBySession={...e.planModeBySession,[Et]:!0},O()),z.swarmMode&&(e.swarmModeBySession={...e.swarmModeBySession,[Et]:!0},F()),z.goalMode&&(e.goalModeBySession={...e.goalModeBySession,[Et]:!0},U()),z.planMode=!1,z.swarmMode=!1,z.goalMode=!1,Et}async function lo(se,xe,J){if(cl.has(se))return null;cl.add(se);let Ce=null;try{const $e=await To(se);return $e?(Ce=$e,await Po($e,xe,J),$e):null}catch($e){return l("startSessionAndSendPrompt",$e),Ce}finally{cl.delete(se)}}async function St(se,xe,J,Ce){if(cl.has(se))return null;cl.add(se);let $e=null;try{const He=await To(se);if(!He)return null;$e=He;const vt=e.planModeBySession[He]??!1,ut=e.swarmModeBySession[He]??!1,Dt=e.sessions.find(Ot=>Ot.id===He),Et=(Dt?.model&&Dt.model.length>0?Dt.model:e.defaultModel)??void 0,ln=await r.resolveThinkingForPrompt(He,Et)??e.thinking;return await P({model:Et,planMode:vt,swarmMode:ut,permissionMode:e.permission,thinking:ln},He)&&await r.activateSkill(xe,J,Ce,He,{skipThinkingPersist:!0}),He}catch(He){return l("startSessionAndActivateSkill",He),$e}finally{cl.delete(se)}}async function hs(se,xe){if(cl.has(se))return null;cl.add(se);let J=null;try{const Ce=await To(se);return Ce?(J=Ce,await i.openSideChatOn(Ce,xe),Ce):null}catch(Ce){return l("startSessionAndOpenSideChat",Ce),J}finally{cl.delete(se)}}async function Jo(se){const xe=se.trim();if(!xe)return!1;const J=_t();try{const Ce=await J.addWorkspace({root:xe});return ps(Ce),In(Ce.id),!0}catch(Ce){return gl("[kimi-web] addWorkspaceByPath failed for",xe,Ce),!1}}async function uo(se){try{return await _t().browseFs(se)}catch{return{path:"",parent:null,entries:[]}}}async function Ys(){try{return await _t().getFsHome()}catch{return{home:"",recentRoots:[]}}}function Nn(se,xe){if(xe==="none"||typeof window>"u"||!window.history)return;const J=fQ(se);if(window.location.pathname!==J)try{xe==="push"?window.history.pushState(null,"",J):window.history.replaceState(null,"",J)}catch{}}async function no(se){try{const xe=await _t().getSession(se);return e.sessions.some(J=>J.id===xe.id)||h(xe),!0}catch{return!1}}async function $s(se){try{const xe=await _t().getSession(se);return xe.archived?"stale":(e.sessions.some(J=>J.id===xe.id)||h(xe),"ok")}catch(xe){return Us(xe)&&xe.code===qhe?"stale":"retry"}}function Xs(){const se=Qb(window.location);if(se===void 0){k(void 0);return}if(se!==e.activeSessionId){if(e.sessions.some(xe=>xe.id===se)){vo(se,{urlMode:"none"});return}(async()=>{if(await no(se)){await vo(se,{urlMode:"none"});return}const xe=e.sessions[0];xe?await vo(xe.id,{urlMode:"replace"}):(k(void 0),Nn(void 0,"replace"))})()}}let ci=!1;function Oo(){ci||typeof window>"u"||(ci=!0,window.addEventListener("popstate",Xs))}async function vo(se,xe){if(!e.sessions.some($e=>$e.id===se)){const $e=++ye;if(!await no(se)||$e!==ye)return}const J=S(se),Ce=!J&&u.has(se);u.delete(se);try{Nn(se,xe?.urlMode??"push"),e.sessionLoading=!J&&!Ce,k(se),e.unreadBySession[se]&&(e.unreadBySession={...e.unreadBySession,[se]:!1},W({[se]:!1})),ge();const $e=e.sessions.find(He=>He.id===se);if($e){const He=B($e);e.activeWorkspaceId!==He&&go(He)}if(J){if(await x(se)==="not-found")return}else if(await g(se,{skipStatusRefresh:xe?.skipStatusRefresh===!0})==="not-found")return;fe(se,{skipStatus:xe?.skipStatusRefresh===!0})}catch($e){l("selectSession",$e,{sessionId:se})}finally{e.activeSessionId===se&&(e.sessionLoading=!1)}}async function Po(se,xe,J){const Ce=y8(se);e.inFlightBySession={...e.inFlightBySession,[se]:!0};const $e=b();let He=e.pendingThinkingBySession[se];try{const vt=_t(),ut=[];if(xe&&ut.push({type:"text",text:xe}),ut.push(...m8(J)),ut.length===0)return e.inFlightBySession={...e.inFlightBySession,[se]:!1},"rejected";const Dt={id:$e,sessionId:se,role:"user",content:ut,createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};w(se,vs=>[...vs,Dt]);const Et=e.sessions.find(vs=>vs.id===se),ln=(Et?.model&&Et.model.length>0?Et.model:e.defaultModel)??void 0,oo=e.planModeBySession[se]??!1,Ot=e.swarmModeBySession[se]??!1,Pt=e.goalModeBySession[se]??!1;if(Pt&&xe)try{await vt.updateSession(se,{goalObjective:xe.trim()})}catch(vs){return vl(e,se,He)&&T(se),l("createGoal",vs,{sessionId:se}),e.inFlightBySession={...e.inFlightBySession,[se]:!1},w(se,Os=>Os.some(ei=>ei.id===$e)?Os.filter(ei=>ei.id!==$e):Os),"rejected"}const Yn=await r.resolveThinkingForPrompt(se,ln)??e.thinking;He=e.pendingThinkingBySession[se];const ko=await vt.submitPrompt(se,{content:ut,model:ln,thinking:Yn,permissionMode:e.permission,planMode:oo,swarmMode:Ot});return Yn!==void 0&&vl(e,se,He),Pt&&(e.goalModeBySession={...e.goalModeBySession,[se]:!1},U()),e.promptIdBySession={...e.promptIdBySession,[se]:ko.promptId},G(se,$e,ko.promptId,ko.userMessageId),_()?.bindNextPromptId(se,ko.promptId),"ok"}catch(vt){return e.inFlightBySession={...e.inFlightBySession,[se]:!1},w(se,ut=>ut.some(Dt=>Dt.id===$e)?ut.filter(Dt=>Dt.id!==$e||Dt.promptId!==void 0||Dt.userMessageId!==void 0):ut),vl(e,se,He)&&T(se),l("sendPrompt",vt,{sessionId:se}),Us(vt)?"rejected":"uncertain"}finally{k8(se,Ce)}}async function co(se,xe){const J=e.activeSessionId;if(J){if(a.value!=="idle"||e.inFlightBySession[J]){Qe(se,xe);return}if((e.queuedBySession[J]?.length??0)>0){Qe(se,xe),st(J);return}await Po(J,se,xe)}}async function Tn(se,xe){const J=e.activeSessionId;if(!J)return;const Ce=e.queuedBySession[J]??[],$e=[],He=[];for(const Pt of Ce){const Yn=Pt.text.trim();Yn&&$e.push(Yn),Pt.attachments?.length&&He.push(...Pt.attachments)}const vt=se.trim();if(vt&&$e.push(vt),xe?.length&&He.push(...xe),$e.length===0&&He.length===0)return;Ce.length>0&&(e.queuedBySession={...e.queuedBySession,[J]:[]});const ut=$e.join(` + +`),Dt=()=>{if(Ce.length===0)return;const Pt=e.queuedBySession[J]??[];e.queuedBySession={...e.queuedBySession,[J]:[...Ce,...Pt]}};if(a.value==="idle"&&!e.inFlightBySession[J]){await Po(J,ut,He)==="rejected"&&Dt();return}const Et=[];ut&&Et.push({type:"text",text:ut});for(const Pt of He)Pt.kind==="video"?Et.push({type:"video",source:{kind:"file",fileId:Pt.fileId}}):Pt.kind==="file"?Et.push({type:"file",fileId:Pt.fileId,name:Pt.name??"",mediaType:Pt.mediaType||"application/octet-stream",size:Pt.size??0}):Et.push({type:"image",source:{kind:"file",fileId:Pt.fileId}});const ln=b(),oo={id:ln,sessionId:J,role:"user",content:Et,createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};w(J,Pt=>[...Pt,oo]);const Ot=y8(J);try{const Pt=_t(),Yn=e.sessions.find(Lc=>Lc.id===J),ko=(Yn?.model&&Yn.model.length>0?Yn.model:e.defaultModel)??void 0,vs=await r.resolveThinkingForPrompt(J,ko)??e.thinking,Os=e.pendingThinkingBySession[J],ei=await Pt.submitPrompt(J,{content:Et,model:ko,thinking:vs,permissionMode:e.permission,planMode:e.planModeBySession[J]??!1,swarmMode:e.swarmModeBySession[J]??!1});if(vs!==void 0&&vl(e,J,Os),G(J,ln,ei.promptId,ei.userMessageId),ei.status!=="queued"){e.promptIdBySession={...e.promptIdBySession,[J]:ei.promptId},_()?.bindNextPromptId(J,ei.promptId);return}try{await Pt.steerPrompts(J,[ei.promptId])}catch{}}catch(Pt){w(J,Yn=>Yn.filter(ko=>ko.id!==ln||ko.promptId!==void 0||ko.userMessageId!==void 0)),Us(Pt)&&Dt(),l("steer",Pt,{sessionId:J})}finally{k8(J,Ot)}}async function fo(se,xe){try{const Ce=await _t().uploadFile({file:se,name:xe});return{fileId:Ce.id,name:Ce.name,mediaType:Ce.mediaType}}catch(J){return l("uploadImage",J),null}}function Qe(se,xe){const J=e.activeSessionId;if(!J)return;const Ce=e.queuedBySession[J]??[],$e={text:se,attachments:xe,id:ome()};e.queuedBySession={...e.queuedBySession,[J]:[...Ce,$e]}}function st(se){const[xe,...J]=e.queuedBySession[se]??[];xe!==void 0&&(e.queuedBySession={...e.queuedBySession,[se]:J},Po(se,xe.text,xe.attachments).then(Ce=>{if(Ce==="ok"){ju.delete(se);return}if(Ce==="uncertain"){ju.delete(se);return}if(!e.sessions.some(Dt=>Dt.id===se)){ju.delete(se);return}const $e=xe.id??xe.text,He=ju.get(se),vt=He!==void 0&&He.key===$e?He.count+1:1;if(vt>=nme){ju.delete(se),(e.queuedBySession[se]?.length??0)>0&&st(se);return}ju.set(se,{key:$e,count:vt});const ut=e.queuedBySession[se]??[];e.queuedBySession={...e.queuedBySession,[se]:[xe,...ut]}}))}function Ct(se,xe){const J=e.inFlightBySession[se]===!0;if(e.inFlightBySession={...e.inFlightBySession,[se]:!1},e.promptIdBySession[se]!==void 0){const $e={...e.promptIdBySession};delete $e[se],e.promptIdBySession=$e}return(J||xe?.turnWasActive===!0||(e.turnActiveBySession[se]??!1))&&st(se),J}function Qt(se,xe){xe.inFlightTurn!==null&&xe.busy||Ct(se)}async function kn(){const se=e.activeSessionId;if(!se)return!1;const xe=e.sessions.find(ut=>ut.id===se);let J=e.promptIdBySession[se];if(J===void 0){const ut=xe?.currentPromptId;ut!==void 0&&ut.length>0&&!ut.startsWith("pr_")&&(J=ut)}const Ce=_t();let $e=!1;const He=()=>{e.inFlightBySession={...e.inFlightBySession,[se]:!1},e.turnActiveBySession={...e.turnActiveBySession,[se]:!1}};if(J!==void 0)try{if((await Ce.abortPrompt(se,J)).aborted)return!0;$e=!0;const Dt={...e.promptIdBySession};delete Dt[se],e.promptIdBySession=Dt,He()}catch(ut){if(Us(ut)&&ut.code===Khe){$e=!0;const Dt={...e.promptIdBySession};delete Dt[se],e.promptIdBySession=Dt,He()}else return l("abortCurrentPrompt",ut,{sessionId:se}),!1}if($e||!((e.inFlightBySession[se]??!1)||(e.turnActiveBySession[se]??!1)||(xe?.mainTurnActive??!1)))return!1;try{return(await Ce.abortSession(se)).aborted===!0}catch(ut){return l("abortCurrentPrompt",ut,{sessionId:se}),!1}}function Ko(se,xe){const J=e.approvalsBySession[se]??[];e.approvalsBySession={...e.approvalsBySession,[se]:J.filter(Ce=>Ce.approvalId!==xe)}}function Eo(se,xe){const J=e.questionsBySession[se]??[];e.questionsBySession={...e.questionsBySession,[se]:J.filter(Ce=>Ce.questionId!==xe)}}async function bo(se,xe){const J=e.activeSessionId;if(!J||Lh[se])return;Lh[se]=!0;const Ce=e.approvalsBySession[J]?.find($e=>$e.approvalId===se&&$e.toolName==="ExitPlanMode")?.toolCallId;try{const $e=_t(),He={decision:xe.decision,scope:xe.scope,feedback:xe.feedback,selectedLabel:xe.selectedLabel};await $e.respondApproval(J,se,He),Ko(J,se),Ce!==void 0&&E(J,Ce)}catch($e){y4($e)?(Ko(J,se),Ce!==void 0&&E(J,Ce)):l("respondApproval",$e,{sessionId:J})}finally{delete Lh[se]}}async function Ns(se,xe){const J=e.activeSessionId;if(J&&!Hu[se]){Hu[se]="answer";try{await _t().respondQuestion(J,se,xe),Eo(J,se)}catch(Ce){y4(Ce)?Eo(J,se):l("respondQuestion",Ce,{sessionId:J})}finally{delete Hu[se]}}}async function Do(se){const xe=e.activeSessionId;if(xe&&!Hu[se]){Hu[se]="dismiss";try{await _t().dismissQuestion(xe,se),Eo(xe,se)}catch(J){y4(J)?Eo(xe,se):l("dismissQuestion",J,{sessionId:xe})}finally{delete Hu[se]}}}async function Io(se){const xe=e.activeSessionId;if(xe&&!k4[se]){k4[se]=!0;try{const J=_t(),Ce=(e.tasksBySession[xe]??[]).find(He=>He.id===se)?.backgroundTaskId;await J.cancelTask(xe,Ce??se);const $e=e.tasksBySession[xe]??[];e.tasksBySession={...e.tasksBySession,[xe]:$e.map(He=>He.id===se?{...He,status:"cancelled"}:He)}}catch(J){eme(J)||l("cancelTask",J,{sessionId:xe})}finally{delete k4[se]}}}function Qo(se){const xe=e.activeSessionId;xe?(e.planModeBySession={...e.planModeBySession,[xe]:se},O(),P({planMode:se})):z.planMode=se}function sn(){const se=e.activeSessionId,xe=se?e.planModeBySession[se]??!1:z.planMode;Qo(!xe)}function es(se){const xe=e.activeSessionId;xe?(e.swarmModeBySession={...e.swarmModeBySession,[xe]:se},F(),P({swarmMode:se})):z.swarmMode=se}async function ms(){const se=e.activeSessionId,J=!(se?e.swarmModeBySession[se]??!1:z.swarmMode);J&&e.permission==="manual"&&!await o({title:n("workspace.swarmEnableTitle"),message:n("workspace.swarmEnableConfirm"),variant:"primary"})||es(J)}function Tr(se){const xe=e.activeSessionId;xe?(e.goalModeBySession={...e.goalModeBySession,[xe]:se},U()):z.goalMode=se}function ts(){const se=e.activeSessionId,xe=se?e.goalModeBySession[se]??!1:z.goalMode;Tr(!xe)}async function Ki(se){const xe=se.trim();if(!xe||e.permission==="manual"&&!await o({title:n("workspace.goalStartTitle"),message:n("workspace.goalStartConfirm",{objective:xe}),variant:"primary"}))return null;let J=e.activeSessionId,Ce=null;if(!J){const $e=e.activeWorkspaceId,He=$e&&I.value.some(vt=>vt.id===$e)?$e:I.value[0]?.id??null;if(!He)return null;try{J=await To(He)??void 0,Ce=J??null}catch(vt){return l("createGoal",vt),null}if(!J)return null}try{await _t().updateSession(J,{goalObjective:xe})}catch($e){return l("createGoal",$e,{sessionId:J,message:ie($e)}),Ce}return e.goalModeBySession[J]&&(e.goalModeBySession={...e.goalModeBySession,[J]:!1},U()),e.activeSessionId===J?await co(xe):await Po(J,xe),Ce}function Js(se){const xe=e.activeSessionId;xe&&Promise.resolve(_t().updateSession(xe,{goalControl:se})).catch(J=>{l("controlGoal",J,{sessionId:xe,message:ie(J)})})}function Bo(se){e.permission=se,H(se),P({permissionMode:se})}function Zo(se){const xe=[...e.warnings];xe.splice(se,1),e.warnings=xe}async function Il(se,xe){try{await _t().updateSession(se,{title:xe}),d(se,Ce=>({...Ce,title:xe}))}catch(J){l("renameSession",J,{sessionId:se})}}async function Zi(se,xe){const J=e.workspaces.find($e=>$e.id===se)?.root,Ce=()=>{e.workspaces=e.workspaces.map($e=>$e.id===se?{...$e,name:xe}:$e)};try{if(await _t().updateWorkspace(se,{name:xe}),J!==void 0){const $e=lh();J in $e&&(delete $e[J],tC($e))}Ce()}catch($e){if(J!==void 0&&Us($e)&&$e.code===Zhe){tC({...lh(),[J]:xe}),Ce();return}l("renameWorkspace",$e)}}async function tl(se){const xe=e.workspaces.find(He=>He.id===se)?.root??D.value.find(He=>He.id===se)?.root??se,J=e.activeSessionId?e.sessions.find(He=>He.id===e.activeSessionId):void 0,Ce=e.activeWorkspaceId===se||e.activeWorkspaceId===xe,$e=!!(J&&(J.cwd===xe||J.workspaceId===se||B(J)===se));xe&&!e.hiddenWorkspaceRoots.includes(xe)&&(e.hiddenWorkspaceRoots=[...e.hiddenWorkspaceRoots,xe],V(e.hiddenWorkspaceRoots));try{await _t().deleteWorkspace(se)}catch(He){gl("[kimi-web] deleteWorkspace registry cleanup failed for",se,He)}if(e.workspaces=e.workspaces.filter(He=>He.id!==se&&He.root!==xe),Ce||$e){const He=I.value[0]?.id??null;if(e.activeWorkspaceId=He,He)K(He);else try{ur(cn.activeWorkspace)}catch{}}(Ce||$e)&&(k(void 0),e.sessionLoading=!1,ge(),Nn(void 0,"replace"))}async function Ho(se){try{const xe=_t(),J=e.sessions.find(ut=>ut.id===se),Ce=J!==void 0?B(J):void 0,$e=Ce!==void 0?Sn(Ce).length:0;await xe.archiveSession(se),m(se),J!==void 0&&Ce!==void 0&&tt(Ce,se,J.updatedAt,$e),i.clearSideChatForSession(se);const{[se]:He,...vt}=e.sideChatUserMessageIdsBySession;if(e.sideChatUserMessageIdsBySession=vt,e.activeSessionId===se){const ut=e.sessions[0];ut?await vo(ut.id,{urlMode:"replace"}):(k(void 0),Nn(void 0,"replace"))}}catch(xe){l("archiveSession",xe,{sessionId:se})}}async function Co(se){if(oe)return;const xe=se??e.activeSessionId;if(!xe){const Ce=n("commands.export.noSession");bi("export:failed",{status:"no-session"}),l("exportSession",new Error(Ce),{message:Ce});return}oe=!0;const J=Date.now();bi("export:start",{sessionId:xe});try{const Ce=U0e(),{blob:$e,fileName:He}=await _t().exportSession(xe,Ce,{desktop:Wp});if(typeof document>"u")throw new Error("Document is unavailable");const vt=URL.createObjectURL($e);let ut;try{ut=document.createElement("a"),ut.href=vt,ut.download=He,document.body.append(ut),ut.click()}finally{ut?.remove(),setTimeout(()=>{try{URL.revokeObjectURL(vt)}catch{}},0)}bi("export:accepted",{sessionId:xe,status:"accepted",zipBytes:$e.size,durationMs:Date.now()-J})}catch(Ce){const $e=typeof Ce=="object"&&Ce!==null?Ce:void 0;bi("export:failed",{sessionId:xe,status:"failed",durationMs:Date.now()-J,errorName:typeof $e?.name=="string"?$e.name:typeof Ce,errorCode:typeof $e?.code=="number"?$e.code:void 0,requestId:typeof $e?.requestId=="string"?$e.requestId:void 0,phase:typeof $e?.phase=="string"?$e.phase:void 0,httpStatus:typeof $e?.status=="number"?$e.status:void 0}),l("exportSession",Ce,{sessionId:xe})}finally{oe=!1}}async function Fs(se){try{const xe=await _t().restoreSession(se);return f(xe),!0}catch(xe){return l("restoreSession",xe,{sessionId:se}),!1}}function Rs(se){return _t().listSessions({archivedOnly:!0,beforeId:se?.beforeId,pageSize:se?.pageSize??50})}async function yo(){try{await _t().logout(),await Se(),await gt()}catch(se){l("logout",se)}}function ht(se){const xe=e.activeSessionId;xe&&_t().compactSession(xe,se).catch(J=>{l("compact",J,{sessionId:xe})})}async function Le(se){const xe=se??e.activeSessionId;if(xe)try{const J=await _t().forkSession(xe);f(J),await vo(J.id)}catch(J){l("fork",J,{sessionId:xe})}}async function Ze(se=1){const xe=e.activeSessionId;if(!xe)return null;const J=e.messagesBySession[xe]??[];let Ce=-1;for(let ut=J.length-1;ut>=0;ut--){const Dt=J[ut];if(Dt.role==="user"&&!(Dt.metadata?.origin&&Dt.metadata.origin.kind!=="user")){Ce=ut;break}}const $e=Ce>=0?J[Ce].content.filter(ut=>ut.type==="text").map(ut=>ut.text).join(` +`):null,He=se===1&&Ce>=0&&J.slice(Ce+1).every(ut=>ut.role!=="user"),vt=He?e.sessions.find(ut=>ut.id===xe):void 0;if(He&&(e.messagesBySession={...e.messagesBySession,[xe]:J.slice(0,Ce)},vt!==void 0)){const ut={...vt};delete ut.lastTurnReason,f(ut)}try{return await _t().undoSession(xe,se),await g(xe),{text:$e}}catch(ut){return He&&(e.messagesBySession={...e.messagesBySession,[xe]:J},vt!==void 0&&f(vt),await g(xe).catch(()=>{})),l("undo",ut,{sessionId:xe}),null}}function Xt(se){const xe=e.activeSessionId;if(!xe)return;const J=e.queuedBySession[xe]??[];if(se<0||se>=J.length)return;const Ce=[...J];Ce.splice(se,1),e.queuedBySession={...e.queuedBySession,[xe]:Ce}}function gs(se,xe){const J=e.activeSessionId;if(!J)return;const Ce=e.queuedBySession[J]??[];if(se===xe||se<0||se>=Ce.length||xe<0||xe>=Ce.length)return;const $e=[...Ce],[He]=$e.splice(se,1);He!==void 0&&($e.splice(xe,0,He),e.queuedBySession={...e.queuedBySession,[J]:$e})}async function di(se){const xe=e.activeSessionId;if(!xe)return[];try{return(await _t().listDirectory(xe,{path:se,includeGitStatus:!0})).items}catch{return[]}}async function Ei(se){const xe=e.activeSessionId;if(!xe)return null;try{const Ce=await _t().readFile(xe,{path:se});return{path:Ce.path,content:Ce.content,encoding:Ce.encoding,mime:Ce.mime,languageId:Ce.languageId,isBinary:Ce.isBinary,size:Ce.size,lineCount:Ce.lineCount}}catch(J){if(gl("[kimi-web] readFileContent failed for",se,J),Us(J)&&J.code===Ghe)throw J;return null}}async function ao(se){return _t().readHostFileContent(se)}const Gi=10485760;function Er(se){const xe=e.activeSessionId;return xe?_t().getFileDownloadUrl(xe,se):null}async function fi(se,xe){const J=e.activeSessionId;if(!J)return!1;try{return await _t().openFile(J,{path:se,line:xe}),!0}catch(Ce){return l("openFile",Ce,{sessionId:J}),!1}}async function Ll(se){const xe=e.activeSessionId;if(!xe)return;const J=$.value.cwd||".";try{await _t().openInApp(xe,se,J)}catch(Ce){l("openInApp",Ce,{sessionId:xe})}}async function zo(se){const xe=e.activeSessionId;if(!xe)return!1;try{return await _t().revealFile(xe,{path:se}),!0}catch(J){return l("revealFile",J,{sessionId:xe}),!1}}function Ir(se){return se.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(se)||se.startsWith("\\\\")}async function Qs(se){if(/^(https?:|data:|blob:)/i.test(se))return se;const xe=e.activeSessionId;if(!xe)return se;let J=se;if(Ir(J)){const Ce=e.sessions.find(He=>He.id===xe)?.cwd,$e=Ce?h2(J,Ce):null;if($e)J=$e;else try{const He=await ao(J);return!He.isBinary||He.encoding!=="base64"?se:`data:${He.mime};base64,${He.content}`}catch{return se}}try{const $e=await _t().readFile(xe,{path:J,length:Gi});return!$e.isBinary||$e.encoding!=="base64"||$e.truncated?se:`data:${$e.mime};base64,${$e.content}`}catch{return se}}async function pi(se){const xe=e.sessions.find(Ce=>Ce.id===e.activeSessionId),J=xe===void 0?e.activeWorkspaceId:B(xe);if(!J)return[];try{return(await _t().searchFiles(J,{query:se,limit:20})).items.map(He=>({path:He.path,name:He.name}))}catch{return[]}}return{loadFileDiff:we,clearFileDiff:ge,loadGitStatus:Q,checkAuth:Se,probeManagedMembership:ue,loadConfig:_e,updateConfig:Ee,listAllSessionsGlobal:Oe,load:gt,refreshServerMeta:Lt,loadWorkspaces:wn,loadMoreSessions:Yt,loadAllSessions:Ue,ensureFlatSessions:Mn,loadMoreFlatSessions:We,selectWorkspace:go,openWorkspace:qt,upsertWorkspacePreserveOrder:ps,applyWorkspaceEvent:xs,clearActiveSession:_n,openWorkspaceDraft:In,startSessionAndSendPrompt:lo,startSessionAndActivateSkill:St,startSessionAndOpenSideChat:hs,addWorkspaceByPath:Jo,browseFs:uo,getFsHome:Ys,writeSessionUrl:Nn,fetchSessionIntoList:no,onSessionRoutePopState:Xs,bindSessionRoute:Oo,selectSession:vo,submitPromptInternal:Po,finishPromptLocal:Ct,localTurnStartState:sme,isLocalTurnSnapshotCurrent:rme,afterLocalTurnStartsSettle:lme,handleSessionSnapshot:Qt,sendPrompt:co,steerPrompt:Tn,uploadImage:fo,enqueue:Qe,unqueue:Xt,reorderQueue:gs,abortCurrentPrompt:kn,respondApproval:bo,respondQuestion:Ns,dismissQuestion:Do,pendingQuestionActions:Hu,pendingApprovalActions:Lh,cancelTask:Io,setPlanMode:Qo,togglePlanMode:sn,setSwarmMode:es,toggleSwarmMode:ms,setGoalMode:Tr,toggleGoalMode:ts,createGoal:Ki,controlGoal:Js,setPermission:Bo,dismissWarning:Zo,renameSession:Il,renameWorkspace:Zi,deleteWorkspace:tl,archiveSession:Ho,exportSession:Co,restoreSession:Fs,loadArchivedSessions:Rs,logout:yo,compact:ht,forkSession:Le,undo:Ze,listDir:di,readFileContent:Ei,readHostFileContent:ao,getFileDownloadUrl:Er,openWorkspaceFile:fi,openInApp:Ll,revealWorkspaceFile:zo,resolveImageUrl:Qs,searchFiles:pi,loadOlderMessages:Y,refreshSessionSidecars:fe,isStartingFirstPrompt:()=>cl.size>0}}const tN=cn.starredModels,Bx=new Error("profile persist failed");function ume(){try{const e=ui(tN);if(!e)return[];const t=JSON.parse(e);if(Array.isArray(t)&&t.every(n=>typeof n=="string"))return t}catch{}return[]}function cme(e){try{Ls(tN,JSON.stringify(e))}catch{}}function dme(e,t){const{pushOperationFailure:n,refreshSessionStatus:o,persistSessionProfile:s,activity:i,updateSession:r,updateSessionMessages:l,loadConfig:a,checkAuth:u}=t,c=Z([]),d=Z(ume()),f=Z({}),h=Z({}),m=Z([]),v=Z(null);function k(pe){if(!(pe==null||pe.length===0))return c.value.find(ve=>ve.id===pe)??c.value.find(ve=>ve.model===pe)}function w(){const pe=e.activeSessionId?e.sessions.find(oe=>oe.id===e.activeSessionId):void 0,ve=pe===void 0?v.value??e.defaultModel:pe.model||e.defaultModel;return k(ve)?.id??ve??void 0}function b(pe){if(pe===void 0)return;const ve=k(pe);return ve===void 0?void 0:bp(ve)}function _(pe,ve){const oe=pe==null?void 0:e.thinkingBySession[pe];return oe!==void 0&&gJ(ve,oe)?oe:bp(ve)}function g(pe,ve){if(ve===void 0)return;const oe=k(ve);return oe===void 0?void 0:_(pe,oe)}async function x(pe,ve){return pe!=null&&e.thinkingBySession[pe]===void 0&&await o(pe),g(pe,ve)}function S(pe){e.thinking=pe;const ve=e.activeSessionId;return pe!==void 0&&ve!==null&&ve!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ve]:pe},k3(e,ve)),pe}Je([()=>e.activeSessionId,()=>w(),()=>{const pe=e.activeSessionId;return pe==null?void 0:e.thinkingBySession[pe]}],()=>{const pe=k(w());pe!==void 0&&(e.thinking=_(e.activeSessionId,pe))});function T(pe){_t().setConfig({thinking:vJ(pe,k(w())?.supportEfforts)}).catch(ve=>n("setConfig",ve))}async function A(pe){try{const oe=await _t().listSkills(pe);f.value={...f.value,[pe]:oe}}catch{}}async function E(pe){try{const oe=await _t().listSkillsForWorkspace(pe);h.value={...h.value,[pe]:oe}}catch{}}async function P(){try{const pe=_t();c.value=await pe.listModels();const ve=k(w());ve!==void 0&&(e.thinking=_(e.activeSessionId,ve))}catch(pe){n("loadModels",pe)}}async function D(){try{const pe=_t();m.value=await pe.listProviders()}catch(pe){n("loadProviders",pe)}}async function I(pe){const ve=e.activeSessionId,oe=k(pe),ye=e.thinking,G=ve?e.sessions.find(ge=>ge.id===ve)?.model:void 0,Y=w()!==(oe?.id??pe),fe=yJ(oe,ye,Y);if(!ve)return v.value=pe,e.thinking=fe,fe!==ye&&fe!==void 0&&T(fe),!0;r(ve,ge=>({...ge,model:pe}));let we;fe!==ye&&(e.thinking=fe,fe!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ve]:fe},we=k3(e,ve)));try{await _t().updateSession(ve,{model:pe,thinking:fe!==ye?fe:void 0})}catch(ge){return r(ve,Q=>({...Q,model:G??Q.model})),fe!==ye&&(e.thinking=ye,ye!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ve]:ye}),vl(e,ve,we)&&o(ve)),n("setModel",ge,{sessionId:ve}),!1}return fe!==ye&&fe!==void 0&&T(fe),vl(e,ve,we),await o(ve),!0}function $(pe){const ve=new Set(d.value);ve.has(pe)?ve.delete(pe):ve.add(pe),d.value=Array.from(ve),cme(d.value)}async function B(pe,ve,oe,ye,G){const Y=ye??e.activeSessionId;if(!Y)return;const fe=i.value==="idle"&&!e.inFlightBySession[Y],we=`msg_skill_opt_${Date.now().toString(36)}`,ge=fe?y8(Y):void 0;if(fe){e.inFlightBySession={...e.inFlightBySession,[Y]:!0};const Q={id:we,sessionId:Y,role:"user",content:[{type:"text",text:`/${pe}${ve?` ${ve}`:""}`},...m8(oe)],createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0,origin:{kind:"skill_activation",trigger:"user-slash",skillName:pe,skillArgs:ve}}};l(Y,te=>[...te,Q])}try{if(G?.skipThinkingPersist!==!0){const Q=e.sessions.find(ue=>ue.id===Y)?.model,te=(Q&&Q.length>0?Q:e.defaultModel)??void 0;if(!await s({thinking:await x(Y,te)??e.thinking},Y))throw Bx}await _t().activateSkill(Y,pe,ve,m8(oe))}catch(Q){fe&&(e.inFlightBySession={...e.inFlightBySession,[Y]:!1},l(Y,te=>te.filter(ce=>ce.id!==we))),Q!==Bx&&n("activateSkill",Q,{sessionId:Y})}finally{ge!==void 0&&k8(Y,ge)}}async function H(pe){return _t().getProvider(pe)}async function O(pe){try{return await _t().addProvider(pe),await Promise.all([D(),P(),a()]),await u(),null}catch(ve){return Xl("[kimi-web] operation failed: addProvider",ve),ve instanceof Error?ve.message:String(ve)}}async function F(pe,ve){try{return await _t().updateProvider(pe,ve),await Promise.all([D(),P(),a()]),null}catch(oe){return Xl("[kimi-web] operation failed: updateProvider",oe),oe instanceof Error?oe.message:String(oe)}}async function U(pe){try{const oe=await _t().deleteProvider(pe);return await Promise.all([D(),P(),a()]),await u(),oe}catch(ve){return n("deleteProvider",ve),null}}async function z(pe){try{const ve=await _t().refreshProvider(pe);for(const oe of ve.failed)n("refreshProvider",new Error(oe.reason),{message:oe.provider});await Promise.all([D(),P(),a()])}catch(ve){n("refreshProvider",ve)}}async function W(){try{const pe=await _t().refreshAllProviders();for(const ve of pe.failed)n("refreshAllProviders",new Error(ve.reason),{message:ve.provider});await Promise.all([D(),P(),a()])}catch(pe){n("refreshAllProviders",pe)}}async function K(){try{return{kind:"ok",items:await _t().listCatalogProviders()}}catch(pe){return pe instanceof wd&&pe.code===void 0?{kind:"unsupported"}:(Xl("[kimi-web] operation failed: loadCatalogProviders",pe),{kind:"error"})}}async function V(pe){try{return await _t().importCatalogProvider(pe),await Promise.all([D(),P(),a()]),await u(),null}catch(ve){return Xl("[kimi-web] operation failed: importCatalogProvider",ve),ve instanceof Error?ve.message:String(ve)}}async function ie(pe){try{const oe=await _t().importCustomRegistry(pe);return await Promise.all([D(),P(),a()]),await u(),oe}catch(ve){return Xl("[kimi-web] operation failed: importCustomRegistry",ve),ve instanceof Error?ve.message:String(ve)}}async function ne(){try{return await _t().startOAuthLogin()}catch{return null}}async function X(){try{return await _t().pollOAuthLogin()}catch(pe){return gl("[kimi-web] pollOAuthLogin failed",pe),null}}async function le(){try{await _t().cancelOAuthLogin()}catch{}}async function Ie(){try{return await _t().getUsage()}catch(pe){return{kind:"error",message:pe instanceof Error?pe.message:String(pe)}}}function de(pe){const ve=S(pe);s({thinking:ve}),ve!==void 0&&T(ve)}return{models:c,starredModelIds:d,providers:m,draftModel:v,skillsBySession:f,skillsByWorkspace:h,loadSkillsForSession:A,loadSkillsForWorkspace:E,loadModels:P,loadProviders:D,setModel:I,thinkingLevelForModelId:b,thinkingLevelForSessionId:g,resolveThinkingForPrompt:x,toggleStarModel:$,activateSkill:B,addProvider:O,updateProvider:F,deleteProvider:U,getProvider:H,loadCatalogProviders:K,importCatalogProvider:V,importCustomRegistry:ie,refreshProvider:z,refreshAllProviders:W,startOAuthLogin:ne,pollOAuthLogin:X,cancelOAuthLogin:le,getUsage:Ie,setThinking:de}}function fme(e,t){const{pushOperationFailure:n,nextOptimisticMsgId:o,connectEventsIfNeeded:s,getEventConn:i,resolveThinkingForPrompt:r,refreshSessionStatus:l}=t,a=Z({}),u=R(()=>{const O=e.activeSessionId;if(!O)return null;const F=a.value[O];return F?{parentId:O,agentId:F.agentId}:null}),c=R(()=>u.value?.parentId??null),d=R(()=>u.value!==null),f=R(()=>{const O=u.value;return O?!!e.sideChatSendingByAgent[O.agentId]:!1}),h=R(()=>{const O=u.value;return O?e.sideChatSendingByAgent[O.agentId]?!0:(e.tasksBySession[O.parentId]??[]).some(F=>F.id===O.agentId&&F.status==="running"):!1}),m=O=>_t().getFileUrl(O),v=[],k=KT(),w=R(()=>{const O=u.value;return O?k({messages:e.sideChatMessagesByAgent[O.agentId]??[],approvals:v,getFileUrl:m,sessionActive:h.value}):[]});function b(O,F){e.sideChatMessagesByAgent[O]=F(e.sideChatMessagesByAgent[O]??[])}function _(O,F){b(O,U=>[...U,F])}function g(O,F){b(O,U=>{const z=U.find(W=>W.id===F);return z?.promptId!==void 0||z?.userMessageId!==void 0?U:U.filter(W=>W.id!==F)})}function x(O,F){const U=e.sideChatUserMessageIdsBySession[O]??[];U.includes(F)||(e.sideChatUserMessageIdsBySession={...e.sideChatUserMessageIdsBySession,[O]:[...U,F]})}function S(O,F,U,z){b(O,W=>{const K=W.findIndex(X=>X.id===F);if(K===-1)return W;const V=W.findIndex((X,le)=>le!==K&&X.role==="user"&&(X.id===z||X.userMessageId===z||X.promptId===U)),ie=W[K],ne=V===-1?ie:W[V];return W.flatMap((X,le)=>le===V?[]:le!==K?[X]:[{...ne,id:ie.id,promptId:U,userMessageId:z,metadata:{...ne.metadata,...ie.metadata}}])})}function T(O,F){x(F.sessionId,F.userMessageId??F.id),b(O,U=>{const z=U.findIndex(V=>V.role==="user"&&(V.userMessageId===(F.userMessageId??F.id)||V.promptId!==void 0&&V.promptId===F.promptId));if(z===-1)return[...U,F];const W=U[z],K=[...U];return K[z]={...F,id:W.id,promptId:F.promptId??W.promptId,userMessageId:F.userMessageId??F.id,metadata:{...F.metadata,...W.metadata}},K})}function A(O,F,U){U&&b(O,z=>{const W=z.at(-1);if(W?.role==="assistant"){const K=W.content[0],V=K?.type==="text"?K.text:"";return[...z.slice(0,-1),{...W,content:[{type:"text",text:`${V}${U}`}]}]}return[...z,{id:o(),sessionId:F,role:"assistant",content:[{type:"text",text:U}],createdAt:new Date().toISOString()}]})}function E(O,F,U){if(e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[O]:!1},!U)return;const W=(e.sideChatMessagesByAgent[O]??[]).at(-1);(W?.role==="assistant"&&W.content[0]?.type==="text"?W.content[0].text:"").trim().length>0||A(O,F,U)}async function P(O){const F=e.activeSessionId;F&&await D(F,O)}async function D(O,F){if(!a.value[O]){let U;try{({agentId:U}=await _t().startBtw(O))}catch(z){n("openSideChat",z,{sessionId:O});return}e.sideChatMessagesByAgent={...e.sideChatMessagesByAgent,[U]:e.sideChatMessagesByAgent[U]??[]},a.value={...a.value,[O]:{agentId:U}},s(),i()?.markSideChannelAgent(O,U)}F&&F.trim()&&await I(O,F.trim())}async function I(O,F){const U=a.value[O],z=F.trim();if(!U||!z)return;const W=O,K=U.agentId;e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[K]:!0};const V=o(),ie={id:V,sessionId:W,role:"user",content:[{type:"text",text:z}],createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};_(K,ie);let ne;try{const X=e.sessions.find(pe=>pe.id===W),le=(X?.model&&X.model.length>0?X.model:e.defaultModel)??void 0,Ie=await r(W,le)??e.thinking;ne=e.pendingThinkingBySession[W];const de=await _t().submitPrompt(W,{content:[{type:"text",text:z}],agentId:K,model:le,thinking:Ie,permissionMode:e.permission,planMode:e.planModeBySession[W]??!1,swarmMode:e.swarmModeBySession[W]??!1});Ie!==void 0&&vl(e,W,ne),S(K,V,de.promptId,de.userMessageId),x(W,de.userMessageId)}catch(X){vl(e,W,ne)&&l(W),n("sendSideChatPrompt",X,{sessionId:W}),g(K,V),e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[K]:!1}}}function $(){const O=e.activeSessionId;if(!O)return;const{[O]:F,...U}=a.value;a.value=U}async function B(O){const F=u.value;F&&await I(F.parentId,O)}function H(O){if(!a.value[O])return;const{[O]:F,...U}=a.value;a.value=U}return{sideChatTargetBySession:a,sideChatSessionId:c,sideChatVisible:d,sideChatSending:f,sideChatRunning:h,sideChatTurns:w,appendSideChatAssistantText:A,finishSideChatAgent:E,reconcileSideChatUserMessage:T,openSideChat:P,openSideChatOn:D,closeSideChat:$,sendSideChatPrompt:B,clearSideChatForSession:H}}class pme{transcript;sessionId;agentId;fetchPage;pageSize;onChange;onGap;refreshPromise=null;buffered=[];agents_=[];seq_;loadingOlder_=!1;loadOlderError_=!1;refreshError_=!1;constructor(t){this.sessionId=t.sessionId,this.agentId=t.agentId,this.transcript=new tj(t.agentId),this.fetchPage=t.fetchPage,this.pageSize=t.pageSize??20,this.onChange=t.onChange,this.onGap=t.onGap}get snapshot(){return this.transcript.snapshot()}get seq(){return this.seq_}get agents(){return this.agents_}get loading(){return this.refreshPromise!==null}get loadingOlder(){return this.loadingOlder_}get loadOlderError(){return this.loadOlderError_}get refreshError(){return this.refreshError_}refresh(){if(this.refreshPromise!==null)return this.refreshPromise;this.refreshError_=!1;const t=this.fetchPage({pageSize:this.pageSize}).then(n=>this.applyPage(n,!0)).catch(n=>{throw this.refreshError_=!0,n}).finally(()=>{this.refreshPromise=null;const n=this.buffered;this.buffered=[];for(const o of n)this.applyOps(o.ops,o.seq);this.onChange?.()});return this.refreshPromise=t,this.onChange?.(),t}receiveReset(t,n){this.transcript.receive([{op:"reset",agentId:this.agentId,snapshot:t}]),n!==void 0&&(this.seq_=n),this.refreshError_=!1,this.onChange?.()}applyOps(t,n){if(this.refreshPromise!==null||this.loadingOlder_)return this.buffered.push({ops:t,...n!==void 0?{seq:n}:{}}),!1;if(n!==void 0&&this.seq_!==void 0){if(n<=this.seq_)return!0;if(n!==this.seq_+1)return this.onGap?.(),!1}const o=this.transcript.apply(t);return n!==void 0&&(this.seq_=n),o.gap!==void 0&&this.onGap?.(),o.accepted.length>0&&this.onChange?.(),o.gap===void 0}async loadOlder(){if(!this.snapshot.hasMoreOlder||this.loadingOlder_)return;const t=this.snapshot.items.find(n=>n.kind==="turn");if(t?.kind==="turn"){this.loadingOlder_=!0,this.loadOlderError_=!1,this.onChange?.();try{const n=await this.fetchPage({beforeTurn:t.turnId,pageSize:this.pageSize});this.applyPage(n,!1)}catch(n){throw this.loadOlderError_=!0,n}finally{this.loadingOlder_=!1;const n=this.buffered;this.buffered=[];for(const o of n)this.applyOps(o.ops,o.seq);this.onChange?.()}}}applyPage(t,n){this.agents_=t.agents;const o=this.snapshot,s=n?t:{...t,items:hme(t.items,o.items),hasMoreOlder:t.hasMoreOlder};this.receiveReset(s,n?t.seq:void 0)}}function hme(e,t){const n=new Set,o=[];for(const s of[...e,...t]){const i=s.kind==="turn"?s.turnId:s.kind==="marker"?s.markerId:s.refId;n.has(i)||(n.add(i),o.push(s))}return o}function mme(e){const t=qS(new Map),n=new Map,o=new Map,s=new Set;let i=null,r=null;function l(){i!==null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(i),i=null),r!==null&&(clearTimeout(r),r=null);for(const _ of s)_.version.value+=1;s.clear()}function a(_){s.add(_),!(i!==null||r!==null)&&(typeof requestAnimationFrame=="function"&&(i=requestAnimationFrame(l)),r=setTimeout(l,50))}function u(_,g){return`${_}\0${g}`}function c(_,g,x){const S=e.getEventConnection();S!==null&&(S.subscribeTranscript(_,g,x),o.set(_,g))}function d(_,g){const x=u(_,g),S=t.get(x);if(S!==void 0)return S;const T={channel:new pme({sessionId:_,agentId:g,fetchPage:A=>e.api.getSessionTranscript(_,{...A,agentId:g}),onChange:()=>{a(T)},onGap:()=>{f(T)}}),version:Z(0),baselineLoaded:!1,resumePromise:null};return t.set(x,T),T}async function f(_){if(_.resumePromise!==null)return _.resumePromise;const g=h(_).finally(()=>{_.resumePromise===g&&(_.resumePromise=null)});return _.resumePromise=g,g}async function h(_){try{await _.channel.refresh(),_.baselineLoaded=!0,n.get(_.channel.sessionId)===_.channel.agentId&&c(_.channel.sessionId,_.channel.agentId,_.channel.seq)}catch{n.get(_.channel.sessionId)===_.channel.agentId&&c(_.channel.sessionId,_.channel.agentId)}}function m(_,g){e.connectEventsIfNeeded(),n.set(_,g);const x=d(_,g);return x.baselineLoaded?c(_,g,x.channel.seq):f(x),x}function v(_,g){if(n.get(_)!==g)return;n.delete(_);const x=o.get(_);x!==void 0&&(e.getEventConnection()?.unsubscribeTranscript(_,[x]),o.delete(_))}function k(_,g,x,S){if(n.get(_)!==g)return;const T=d(_,g);T.channel.receiveReset(x,S),T.baselineLoaded=!0}function w(_,g,x,S){return n.get(_)!==g?!0:d(_,g).channel.applyOps(x,S)}function b(_){n.delete(_),o.delete(_)&&e.getEventConnection()?.unsubscribeTranscript(_);for(const[g,x]of t)x.channel.sessionId===_&&(t.delete(g),s.delete(x))}return{getEntry:(_,g)=>t.get(u(_,g)),activate:m,deactivate:v,receiveReset:k,applyOps:w,forgetSession:b}}const $h=XT(),Da=phe(),nN=cn.permission,oN=cn.activeWorkspace,sN=cn.planMode,iN=cn.swarmMode,rN=cn.goalMode,Hx=40401,Ag=cn.onboarded;ur(cn.codeFont);ur(cn.accent);ur(cn.theme);ur(cn.thinking);ur(cn.notifyOnComplete);ur(cn.notifyOnQuestion);ur(cn.notifyOnApproval);ur(cn.soundOnComplete);function gme(){try{const e=ui(nN);if(e==="auto"||e==="yolo"||e==="manual")return e}catch{}return"manual"}function vme(e){try{Ls(nN,e)}catch{}}function b4(e){const t=ui(e);if(!t)return{};try{const n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))return{};const o={};for(const[s,i]of Object.entries(n))i===!0&&(o[s]=!0);return o}catch{return{}}}function P5(e,t){try{const n={};for(const[o,s]of Object.entries(t))s&&(n[o]=!0);Ls(e,JSON.stringify(n))}catch{}}function lN(){P5(sN,Me.planModeBySession)}function aN(){P5(iN,Me.swarmModeBySession)}function uN(){P5(rN,Me.goalModeBySession)}function yme(){try{return ui(oN)}catch{return null}}const cN=cn.hiddenWorkspaces;function kme(){try{const e=ui(cN);if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}catch{return[]}}function bme(e){try{Ls(cN,JSON.stringify(e))}catch{}}function Cme(e){try{Ls(oN,e)}catch{}}function wme(e,t){if(t&&e.startsWith(t)){const o=e.slice(t.length);return o?`~${o}`:"~"}const n=e.match(/^\/(?:Users|home)\/[^/]+(\/.*)?$/);return n?`~${n[1]??""}`:e}const Me=Go({...oY(),connected:!1,serverVersion:"",dangerousBypassAuth:!1,backend:"v1",experimentalFlags:{},workspaceName:"kimi-web",connection:"disconnected",permission:gme(),thinking:void 0,thinkingBySession:{},pendingThinkingBySession:{},planModeBySession:b4(sN),swarmModeBySession:b4(iN),goalModeBySession:b4(rN),loading:!1,sessionLoading:!1,queuedBySession:{},gitStatusBySession:{},promptIdBySession:{},inFlightBySession:{},unreadBySession:Ey(),authReady:!1,defaultModel:null,managedProviderStatus:null,managedUserInfo:null,managedMembership:null,workspaces:[],activeWorkspaceId:yme(),fsHome:null,recentRoots:[],hiddenWorkspaceRoots:kme(),availableOpenInApps:[],config:null,sideChatMessagesByAgent:{},sideChatSendingByAgent:{},sideChatUserMessageIdsBySession:{},messagesLoadingMoreBySession:{},messagesHasMoreBySession:{},messagesLoadMoreErrorBySession:{},sessionsHasMoreByWorkspace:{},sessionsLoadingMoreByWorkspace:{},sessionsCursorByWorkspace:{},sessionsInitialCountByWorkspace:{},sessionsFullyLoaded:!1,flatSessionsNextPageToken:null,flatSessionsHasMore:!0,flatSessionsLoading:!1,flatSessionsLoadingMore:!1,flatSessionsSeeded:!1,flatSessionsFrontier:null}),Mg=Go({}),np=new Map,If=new Map;function _me(e,t){return`${e}\0${t??"*"}`}async function b8(e,t){const n=_me(e,t),o=(np.get(n)??0)+1;np.set(n,o),t!==void 0&&If.set(e,(If.get(e)??0)+1);const s=If.get(e)??0;try{const i=await _t().getSessionPlans(e,{agentId:"main",toolCallId:t});if(np.get(n)!==o||t===void 0&&(If.get(e)??0)!==s||!Me.sessions.some(l=>l.id===e))return;const r=Object.fromEntries(i.map(l=>[l.toolCallId,l]));Mg[e]=t===void 0?r:{...Mg[e],...r}}catch(i){gl("[refreshSessionPlans] plan history unavailable for",e,i)}}function xme(e){const t=`${e}\0`;for(const n of np.keys())n.startsWith(t)&&np.delete(n);If.delete(e),delete Mg[e]}const F2=Go({planMode:!1,swarmMode:!1,goalMode:!1});function D5(e){Me.sessions=e}function R2(e,t){Me.sessions=Me.sessions.map(n=>n.id===e?t(n):n)}function Sme(e){Me.sessions=[e,...Me.sessions.filter(t=>t.id!==e.id)]}function Ame(e){Me.sessions=[...Me.sessions,e]}function Mme(e){Me.sessions=Me.sessions.filter(t=>t.id!==e)}function dN(){const e=Me.activeSessionId;e&&Me.unreadBySession[e]&&typeof document<"u"&&document.visibilityState==="visible"&&(Me.unreadBySession[e]=!1,Iy({[e]:!1}))}typeof window<"u"&&window.addEventListener("storage",e=>{e.key===cn.unread&&(Me.unreadBySession=Ey(),dN())});function C8(){if(rr===null||!rr.health().stale)return;bi("ws:stale-reconnect",{sessionId:Me.activeSessionId,status:"stale"}),D0e("ws: stale socket on focus, reconnecting",{activeSessionId:Me.activeSessionId}),rr.reconnect();const e=Me.activeSessionId;e&&Lg.request(e)}typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(dN(),C8())});typeof window<"u"&&(window.addEventListener("focus",C8),window.addEventListener("online",C8));function B5(e){Me.activeSessionId=e}function Tme(e){Ni(Me.messagesBySession,e)}function Eme(e,t){Me.messagesBySession[e]=t}function fN(e,t){Me.messagesBySession[e]=t(Me.messagesBySession[e]??[])}function Ime(e){delete Me.messagesBySession[e]}function pN(e){rr?.unsubscribe(e),Tg.forgetSession(e),ege(e),Gd.discard(({meta:t})=>t.sessionId===e),Mme(e),Ime(e),xme(e),delete Me.approvalsBySession[e],delete Me.questionsBySession[e],delete Me.tasksBySession[e],delete Me.goalBySession[e],delete Me.gitStatusBySession[e],delete Me.lastSeqBySession[e],delete Me.compactionBySession[e],delete Me.messagesLoadingMoreBySession[e],delete Me.messagesHasMoreBySession[e],delete Me.messagesLoadMoreErrorBySession[e],delete w8[e],Ig.delete(e),um.delete(e),MN.delete(e),ime(e),delete Me.queuedBySession[e],delete Me.promptIdBySession[e],delete Me.inFlightBySession[e],delete Me.turnActiveBySession[e],delete Me.turnEndedPromptIdBySession[e],delete Me.turnErrorBySession[e],delete Me.turnRetryBySession[e],delete Me.planModeBySession[e],delete Me.swarmModeBySession[e],delete Me.goalModeBySession[e],delete Me.thinkingBySession[e],delete Me.pendingThinkingBySession[e],lN(),aN(),uN(),Yo.value.includes(e)&&(Yo.value=uE(Yo.value,e),k1(Yo.value))}const hN=Z(null),mN=Z([]),gN=Z(!1),vN=Z(null),yN=Z(!1),kN=Z(!1),bN=Z(null);async function _c(e){let t;try{t=await _t().getSessionStatus(e)}catch{return}R2(e,n=>({...n,model:t.model||n.model,usage:{...n.usage,contextTokens:t.contextTokens,contextLimit:t.maxContextTokens}})),Me.swarmModeBySession[e]=t.swarmMode,Me.planModeBySession[e]=t.planMode,t.thinkingEffort.length>0&&rE(Me,e,t.thinkingEffort)}async function Lme(e){const t=Me.goalVersionBySession[e]??0;let n;try{n=await _t().getSessionGoal(e)}catch{return}(Me.goalVersionBySession[e]??0)===t&&(n===null||n.status==="complete"?delete Me.goalBySession[e]:Me.goalBySession[e]=n)}function CN(e,t){const n=t??Me.activeSessionId;if(!n)return Promise.resolve(!1);const o=e.thinking!==void 0?Me.pendingThinkingBySession[n]:void 0;return Promise.resolve(_t().updateSession(n,e)).then(()=>(vl(Me,n,o),_c(n))).then(()=>!0).catch(s=>(vl(Me,n,o)&&_c(n),t0("persistSessionProfile",s,{sessionId:n}),!1))}function wN(e){try{return ui(e)??""}catch{return""}}function $me(){return typeof window>"u"?!1:new URLSearchParams(window.location.search).get("kimi_onboarded")==="1"}const _N=$me();if(_N&&wN(Ag)!=="1")try{Ls(Ag,"1")}catch{}const xN=Z(_N||wN(Ag)==="1");function Nme(e){xN.value=e;try{Ls(Ag,e?"1":"0")}catch{}e&&window.kimiDesktop?.setOnboarded?.()}let rr=null;const Tg=mme({api:_t(),connectEventsIfNeeded:H5,getEventConnection:()=>rr});let zx=0;function SN(){return zx+=1,`msg_opt_${Date.now().toString(36)}_${zx}`}function Wx(e,t,n){const o={sessions:Me.sessions,activeSessionId:Me.activeSessionId,messagesBySession:Me.messagesBySession,approvalsBySession:Me.approvalsBySession,planReviewByToolCallId:Me.planReviewByToolCallId,questionsBySession:Me.questionsBySession,tasksBySession:Me.tasksBySession,goalBySession:Me.goalBySession,goalVersionBySession:Me.goalVersionBySession,lastSeqBySession:Me.lastSeqBySession,turnActiveBySession:Me.turnActiveBySession,turnEndedPromptIdBySession:Me.turnEndedPromptIdBySession,turnErrorBySession:Me.turnErrorBySession,turnRetryBySession:Me.turnRetryBySession,compactionBySession:Me.compactionBySession,config:Me.config,warnings:Me.warnings},s=fY(o,e,{sessionId:t,seq:n},{t:(i,r)=>r===void 0?Hn.global.t(i):Hn.global.t(i,r)});s.sessions!==o.sessions&&D5(s.sessions),s.activeSessionId!==o.activeSessionId&&B5(s.activeSessionId),Tme(s.messagesBySession),Ni(Me.approvalsBySession,s.approvalsBySession),Ni(Me.planReviewByToolCallId,s.planReviewByToolCallId),Ni(Me.questionsBySession,s.questionsBySession),Ni(Me.tasksBySession,s.tasksBySession),Ni(Me.goalBySession,s.goalBySession),Ni(Me.goalVersionBySession,s.goalVersionBySession),Ni(Me.lastSeqBySession,s.lastSeqBySession),Ni(Me.turnActiveBySession,s.turnActiveBySession),Ni(Me.turnEndedPromptIdBySession,s.turnEndedPromptIdBySession),Ni(Me.turnErrorBySession,s.turnErrorBySession),Ni(Me.turnRetryBySession,s.turnRetryBySession),Ni(Me.compactionBySession,s.compactionBySession),s.config!==o.config&&(Me.config=s.config??null),pY(s.warnings,o.warnings)||(Me.warnings=s.warnings),e.type==="configChanged"&&(Me.defaultModel=e.config.defaultModel??null),e.type==="modelCatalogChanged"&&(Rn.loadModels(),Rn.loadProviders()),e.type==="sessionUsageUpdated"&&(e.swarmMode!==void 0&&(Me.swarmModeBySession[e.sessionId]=e.swarmMode),e.planMode!==void 0&&(Me.planModeBySession[e.sessionId]=e.planMode),e.thinking!==void 0&&rE(Me,e.sessionId,e.thinking)),e.type==="sessionDeleted"&&V5(e.sessionId)}function Fme(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.role==="user")return;if(n.role==="assistant")for(let o=n.content.length-1;o>=0;o--){const s=n.content[o];if(s.type==="toolUse"&&s.toolName==="ExitPlanMode")return s.toolCallId}}}function Rme(e,t){const n=Me.lastSeqBySession[t.sessionId]??0,o=Me.turnActiveBySession[t.sessionId]??!1,s=e.type==="approvalResolved"||e.type==="approvalExpired"?Me.approvalsBySession[t.sessionId]?.find(r=>r.approvalId===e.approvalId&&r.toolName==="ExitPlanMode")?.toolCallId:void 0,i=si.sideChatTargetBySession.value[t.sessionId];if(e.type==="messageCreated"&&e.message.role==="user"&&e.agentId!==void 0&&Object.prototype.hasOwnProperty.call(Me.sideChatMessagesByAgent,e.agentId)){Wx({type:"unknown",raw:{_noop:!0}},t.sessionId,t.seq),si.reconcileSideChatUserMessage(e.agentId,e.message);return}if(Wx(e,t.sessionId,t.seq),i){const{agentId:r}=i,l=t.sessionId;e.type==="agentDelta"&&e.agentId===r?e.delta.text&&si.appendSideChatAssistantText(r,l,e.delta.text):e.type==="agentTurnEnded"&&e.agentId===r?si.finishSideChatAgent(r,l):e.type==="taskProgress"&&e.taskId===r?si.appendSideChatAssistantText(r,l,e.outputChunk):e.type==="taskCompleted"&&e.taskId===r&&si.finishSideChatAgent(r,l,e.outputPreview)}if(e.type==="messageCreated"&&e.message.role==="user"&&e.message.promptId!==void 0){const r=e.message.sessionId;Me.promptIdBySession[r]!==e.message.promptId&&(Me.promptIdBySession[r]=e.message.promptId)}if(e.type==="turnActiveChanged"&&!e.active&&t.seq>n){const r=e.reason;y2e(e.sessionId,r==="cancelled"||r==="failed"||r==="blocked"?"aborted":"idle",o);const l=Fme(Me.messagesBySession[e.sessionId]??[]);l!==void 0&&b8(e.sessionId,l)}e.type==="sessionWorkChanged"&&(e.mainTurnActive===!1&&o||e.mainTurnActive===void 0&&!e.busy)&&t.seq>n&&v2e(e.sessionId),(e.type==="promptAborted"||e.type==="promptCompleted"&&e.reason==="blocked")&&t.seq>n&&Me.promptIdBySession[e.sessionId]===e.promptId&&At.finishPromptLocal(e.sessionId),e.type==="questionRequested"&&k2e(e.sessionId,e.question),e.type==="approvalRequested"&&b2e(e.sessionId,e.approval),s!==void 0&&b8(t.sessionId,s)}const Gd=gX(({appEvent:e,meta:t})=>Rme(e,t),({appEvent:e})=>fX(e),{coalesce:yX}),Ome=3e4;let Ux=0,oi=null;const op=new Map;let Eg=0,Yd=null;function Pme(){Yd!==null&&(clearTimeout(Yd),Yd=null)}function jx(e){if(!Me.connected||Yd!==null)return;const t=Math.min(Ome,1e3*2**Eg);Eg+=1,gl("[kimi-web] session work reconciliation incomplete; retrying",e),Yd=setTimeout(()=>{Yd=null,Me.connected&&AN()},t)}function Dme(e,t){const n=new Map(e.map(u=>[u.id,u]));let o=!1,s=!1;const i={...Me.turnActiveBySession},r=[],l=new Map,a=Me.sessions.map(u=>{const c=n.get(u.id);if(c===void 0)return u;const d=t.workEventSeqBySession.get(u.id)??0,f=t.turnEventSeqBySession.get(u.id)??0,h=t.pendingEventBySession.get(u.id),m=d>c.lastSeq,v=f>c.lastSeq,k=h!==void 0&&h.seq>c.lastSeq,w=m||v&&u.mainTurnActive===!0?u.busy||u.mainTurnActive===!0:c.busy,b=m||v?u.mainTurnActive:c.mainTurnActive??(w?u.mainTurnActive:!1),_=k?h.source==="work"?u.pendingInteraction:(Me.approvalsBySession[u.id]?.length??0)>0?"approval":(Me.questionsBySession[u.id]?.length??0)>0?"question":"none":c.pendingInteraction??(w?u.pendingInteraction:"none");(k&&h.source==="work"||!k&&(c.pendingInteraction!==void 0||c.busy===!1))&&_!==void 0&&l.set(u.id,_);const g=m?u.lastTurnReason:c.lastTurnReason;op.set(u.id,Math.max(op.get(u.id)??0,c.lastSeq));const x=t.turnStartBySession.get(u.id);return(b===!1||b===void 0&&!w)&&t.witnessedTurnBySession.has(u.id)&&x!==void 0&&At.isLocalTurnSnapshotCurrent(u.id,x)&&r.push(u.id),b===!0&&!i[u.id]?(i[u.id]=!0,s=!0):(b===!1||!w)&&i[u.id]&&(delete i[u.id],s=!0),u.busy===w&&u.mainTurnActive===b&&u.pendingInteraction===_&&u.lastTurnReason===g?u:(o=!0,{...u,busy:w,mainTurnActive:b,pendingInteraction:_,lastTurnReason:g})});o&&D5(a),s&&Ni(Me.turnActiveBySession,i);for(const[u,c]of l)c==="none"?(delete Me.approvalsBySession[u],delete Me.questionsBySession[u]):c==="question"&&delete Me.approvalsBySession[u];for(const u of r)At.finishPromptLocal(u,{turnWasActive:!0})}async function AN(){const e={workEventSeqBySession:new Map,turnEventSeqBySession:new Map,pendingEventBySession:new Map,turnStartBySession:new Map(Me.sessions.map(t=>[t.id,At.localTurnStartState(t.id)])),witnessedTurnBySession:new Set(Me.sessions.filter(t=>Me.inFlightBySession[t.id]||Me.turnActiveBySession[t.id]).map(t=>t.id))};oi=e;try{const t=await At.listAllSessionsGlobal({shouldContinue:()=>oi===e&&Me.connected});if(oi!==e||!Me.connected)return;Gd.flush(),Dme(t.sessions,e),oi=null,t.error!==void 0?jx(t.error):Eg=0}catch(t){if(oi!==e||!Me.connected)return;oi=null,jx(t)}}function H5(){if(rr!==null||typeof WebSocket>"u")return;bi("ws:connection",{status:"connecting"}),Me.connection="connecting",rr=_t().connectEvents({onEvent(t,n){if(t.type==="workspaceCreated"||t.type==="workspaceUpdated"||t.type==="workspaceDeleted"){At.applyWorkspaceEvent(t);return}const o=t.type==="sessionWorkChanged",s=t.type==="turnActiveChanged",i=t.type==="approvalRequested"||t.type==="approvalResolved"||t.type==="approvalExpired"||t.type==="questionRequested"||t.type==="questionAnswered"||t.type==="questionDismissed";if((o||s||i)&&n.seq>0){const r=op.get(n.sessionId)??0;if(n.seq<=r)return;op.set(n.sessionId,n.seq)}if(oi!==null&&(o||s||i))if(o){const r=oi.workEventSeqBySession.get(n.sessionId)??0;if(n.seq>r&&oi.workEventSeqBySession.set(n.sessionId,n.seq),t.pendingInteraction!==void 0||!t.busy){const l=oi.pendingEventBySession.get(n.sessionId);(l===void 0||n.seq>l.seq)&&oi.pendingEventBySession.set(n.sessionId,{seq:n.seq,source:"work"})}}else if(s){const r=oi.turnEventSeqBySession.get(n.sessionId)??0;n.seq>r&&oi.turnEventSeqBySession.set(n.sessionId,n.seq)}else{const r=oi.pendingEventBySession.get(n.sessionId);(r===void 0||n.seq>r.seq)&&oi.pendingEventBySession.set(n.sessionId,{seq:n.seq,source:"interaction"})}for(const r of vX({appEvent:t,meta:n}))Gd(r)},onResync(t,n,o){bi("ws:resync",{sessionId:t,status:"required",seq:n}),Gd.flush(),Ig.add(t),Lg.request(t)},onError(t,n,o){bi("ws:error",{status:"failed",errorCode:t,fatal:o}),O2({severity:"error",title:Hn.global.t("warnings.wsTitle"),message:n,details:[Lo("message",n)].filter(s=>s!==void 0)})},onConnectionChange(t){bi("ws:connection",{status:t?"connected":"disconnected"}),Me.connected=t,Me.connection=t?"connected":"disconnected",t||(oi=null,op.clear(),Pme(),Eg=0),t&&(Ux+=1,qme(),At.refreshServerMeta())},onReplayComplete(){Gd.flush(),Ux>1&&AN()},onTranscriptReset(t,n,o,s){Tg.receiveReset(t,n,o,s)},onTranscriptOps(t,n,o,s){return Tg.applyOps(t,n,o,s)}})}const w8={},Ig=new Set,um=new Set,MN=new Set;function Bme(e){return Us(e)&&e.code===Hx?!0:typeof e=="object"&&e!==null&&e.code===Hx}function Lo(e,t){if(!(t==null||t===""))return{label:Hn.global.t(`warnings.details.${e}`),value:TN(t)}}function TN(e){if(e instanceof Error)return typeof e.stack=="string"&&e.stack?e.stack:e.message?`${e.name}: ${e.message}`:e.name;if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean"||typeof e=="bigint")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function Hme(e){return e instanceof Error||typeof e=="object"&&e!==null&&typeof e.name=="string"?e.name:void 0}function zme(e){return e instanceof Error||typeof e=="object"&&e!==null&&typeof e.message=="string"?e.message:void 0}function Wme(e){return e instanceof Error&&typeof e.stack=="string"&&e.stack?e.stack:void 0}function Ume(e){if(!(typeof e!="number"||!Number.isFinite(e)))return new Date(e).toISOString()}function Vx(e){if(!(typeof e!="number"||!Number.isFinite(e)))return`${Math.round(e)}ms`}function jme(e,t,n){const o=iy(t),s=Us(t),i=o||s?t.timestamp:void 0,r=o||s?t.durationMs:void 0,l=[Lo("operation",e),Lo("sessionId",n??Me.activeSessionId),Lo("connection",Me.connection),Lo("timestamp",Ume(i??Date.now()))];return o?l.push(Lo("duration",Vx(r)),Lo("request",`${t.method} ${t.path}`),Lo("endpoint",t.url),Lo("requestId",t.requestId),Lo("phase",t.phase),Lo("timeout",`${t.timeoutMs}ms`),Lo("status",t.status===void 0?void 0:`${t.status} ${t.statusText??""}`.trim()),Lo("contentType",t.contentType),Lo("responsePreview",t.bodyPreview),Lo("cause",t.cause)):s?l.push(Lo("duration",Vx(r)),Lo("code",t.code),Lo("requestId",t.requestId),Lo("message",t.message),Lo("details",t.details)):l.push(Lo("errorName",Hme(t)),Lo("message",zme(t)??TN(t)),Lo("stack",Wme(t))),l.filter(a=>a!==void 0)}function Vme(e,t,n={}){const o=iy(t),s=Us(t),i=n.title??(o?Hn.global.t("warnings.daemonNetworkTitle"):s?Hn.global.t("warnings.daemonApiTitle"):Hn.global.t("warnings.operationFailedTitle")),r=n.message??(o?Hn.global.t("warnings.daemonNetworkMessage"):s?t.message:Hn.global.t("warnings.operationFailedMessage"));return{severity:"error",title:i,message:r,details:jme(e,t,n.sessionId)}}function O2(e){Me.warnings=[...Me.warnings,e]}function qme(){const e=Hn.global.t("warnings.wsTitle"),t=Me.warnings.filter(n=>!(typeof n=="object"&&n!==null&&n.severity==="error"&&n.title===e));t.length!==Me.warnings.length&&(Me.warnings=t)}function t0(e,t,n){Xl(`[kimi-web] operation failed: ${e}`,t);const o=Us(t),s=iy(t);bi("operation:failed",{sessionId:n?.sessionId,status:"failed",operation:e,errorName:t instanceof Error?t.name:typeof t,errorCode:o?t.code:void 0,requestId:o||s?t.requestId:void 0,phase:s?t.phase:void 0,httpStatus:s?t.status:void 0}),O2(Vme(e,t,n))}const Kme={40913:"warnings.goal.alreadyExists",40914:"warnings.goal.notFound",40915:"warnings.goal.statusInvalid",40916:"warnings.goal.notResumable",40918:"warnings.goal.objectiveTooLong"};function Zme(e){if(!Us(e)||e.code===void 0)return;const t=Kme[e.code];return t?Hn.global.t(t):void 0}async function Gme(e){if(pN(e),Me.activeSessionId!==e)return;const t=Me.sessions[0];t?await At.selectSession(t.id,{urlMode:"replace"}):(B5(void 0),Me.sessionLoading=!1,At.writeSessionUrl(void 0,"replace"))}const qx=new Set;async function Yme(e){if(!qx.has(e)){qx.add(e);try{const t=await _t().getSessionWarnings(e),n=Hn.global.t("warnings.noteLabel");for(const o of t)O2(`${n}: ${o.message}`)}catch{}}}async function z5(e,t){const n=At.localTurnStartState(e);try{const s=await _t().getSessionSnapshot(e);if(!Me.sessions.some(c=>c.id===e))return"ok";Gd.flush();const i=Me.lastSeqBySession[e]??0,r=w8[e],l=Ig.has(e)||$g.has(e);if(!l&&r!==void 0&&r===s.epoch&&i>s.asOfSeq)return um.delete(e)||(um.add(e),Lg.request(e)),"ok";if(!At.isLocalTurnSnapshotCurrent(e,n))return At.afterLocalTurnStartsSettle(e,()=>{Lg.request(e)}),"ok";const a=Me.turnRetryBySession[e];a!==void 0&&a.turnId!==s.inFlightTurn?.turnId&&delete Me.turnRetryBySession[e],(l||s.session.lastTurnReason!=="failed")&&delete Me.turnErrorBySession[e];const u=o3(s.session.usage);R2(e,c=>({...s.session,model:s.session.model&&s.session.model.length>0?s.session.model:c.model,usage:u?c.usage:s.session.usage,updatedAt:!s.session.mainTurnActive&&s.session.updatedAt>c.updatedAt?s.session.updatedAt:c.updatedAt})),Eme(e,gQ(Me.messagesBySession[e]??[],s.messages)),Me.tasksBySession[e]=_Q(s.subagents,Me.tasksBySession[e]??[]),Me.messagesHasMoreBySession[e]=s.hasMoreMessages,Me.approvalsBySession[e]=s.pendingApprovals;for(const c of s.pendingApprovals){const d=c.display;d?.kind==="plan_review"&&typeof d.plan=="string"&&d.plan.length>0&&(Me.planReviewByToolCallId[c.toolCallId]={plan:d.plan,path:typeof d.path=="string"?d.path:void 0})}return Me.questionsBySession[e]=s.pendingQuestions,Me.lastSeqBySession[e]=s.asOfSeq,w8[e]=s.epoch,Ig.delete(e),um.delete(e),At.handleSessionSnapshot(e,{inFlightTurn:s.inFlightTurn,busy:s.session.busy}),s.session.mainTurnActive??(s.inFlightTurn!==null&&s.session.busy)?Me.turnActiveBySession[e]=!0:delete Me.turnActiveBySession[e],H5(),rr&&(rr.seedSnapshot(e,s),rr.subscribe(e,{seq:s.asOfSeq,epoch:s.epoch}),Qme(e)),$g.delete(e),u&&t?.skipStatusRefresh!==!0&&_c(e),Yme(e),"ok"}catch(o){return Bme(o)?(await Gme(e),"not-found"):(t0("getSessionSnapshot",o,{title:Hn.global.t("warnings.sessionSnapshotTitle"),message:Hn.global.t("warnings.sessionSnapshotMessage"),sessionId:e}),"failed")}}const Lg=vQ(z5);function Xme(e){return Object.prototype.hasOwnProperty.call(Me.messagesBySession,e)}const Jme=4,ql=[],$g=new Set;function Qme(e){const t=ql.indexOf(e);for(t!==-1&&ql.splice(t,1),ql.unshift(e);ql.length>Jme;){let n=-1;for(let s=ql.length-1;s>=0;s--)if(ql[s]!==Me.activeSessionId){n=s;break}if(n===-1)break;const[o]=ql.splice(n,1);if(o===void 0)break;rr?.unsubscribe(o),$g.add(o)}}function ege(e){const t=ql.indexOf(e);t!==-1&&ql.splice(t,1),$g.delete(e)}async function tge(e){return z5(e)}function u1(e,t){return(Me.inFlightBySession[e]??!1)||(Me.turnActiveBySession[e]??!1)||(t??Me.sessions.find(n=>n.id===e)?.mainTurnActive??!1)}function n0(e){try{const t=new Date(e),o=Date.now()-t.getTime(),s=o/36e5;if(o<6e4)return Hn.global.t("sessions.justNow");if(s<1)return`${Math.round(o/6e4)}m`;if(s<24)return`${Math.round(s)}h`;const i=o/864e5;return i<7?`${Math.round(i)}d`:i<30?`${Math.round(i/7)}w`:i<365?`${Math.round(i/30)}mo`:`${Math.round(i/365)}y`}catch{return e}}const nge=3e4,xc=Z(0);let C4=null;function oge(){C4===null&&(C4=setInterval(()=>{xc.value=(xc.value+1)%Number.MAX_SAFE_INTEGER},nge),C4.unref?.())}function sge(e){const t=e.display??{},n=typeof t.kind=="string"?t.kind:"";if(n==="diff"){const o=typeof t.path=="string"?t.path:"";if(Array.isArray(t.diff))return{kind:"diff",path:o,diff:t.diff};const s=typeof t.old_text=="string"?t.old_text:typeof t.before=="string"?t.before:void 0,i=typeof t.new_text=="string"?t.new_text:typeof t.after=="string"?t.after:void 0;if(s!==void 0&&i!==void 0){const r=r1(s,i)??Pm(s,i);return{kind:"diff",path:o,diff:r}}return{kind:"diff",path:o,diff:[]}}if(n==="file_io"){const o=typeof t.path=="string"?t.path:"",s=typeof t.operation=="string"?t.operation:"";if(s==="write"&&typeof t.content=="string")return{kind:"file",path:o,content:t.content};if(s==="edit"&&typeof t.before=="string"&&typeof t.after=="string"){const r=r1(t.before,t.after)??Pm(t.before,t.after);return{kind:"diff",path:o,diff:r}}const i=typeof t.detail=="string"?t.detail:void 0;return{kind:"fileop",op:s||n,path:o,detail:i}}if(n==="shell"||n==="command"){const o=typeof t.command=="string"?t.command:e.action,s=typeof t.cwd=="string"?t.cwd:void 0,i=typeof t.danger=="string"?t.danger:DT(o);return{kind:"shell",command:o,cwd:s,danger:i}}if(n==="file_content"||n==="file"){const o=typeof t.path=="string"?t.path:"",s=typeof t.content=="string"?t.content:"",i=typeof t.language=="string"?t.language:void 0;return{kind:"file",path:o,content:s,language:i}}if(n==="file_op"||n==="fileop"){const o=typeof t.operation=="string"?t.operation:typeof t.op=="string"?t.op:n,s=typeof t.path=="string"?t.path:"",i=typeof t.detail=="string"?t.detail:void 0;return{kind:"fileop",op:o,path:s,detail:i}}if(n==="url_fetch"||n==="url"){const o=typeof t.url=="string"?t.url:e.action;return{kind:"url",method:typeof t.method=="string"?t.method:void 0,url:o}}if(n==="search"){const o=typeof t.query=="string"?t.query:e.action,s=typeof t.scope=="string"?t.scope:void 0;return{kind:"search",query:o,scope:s}}if(n==="invocation"||n==="agent_call"||n==="skill_call"){const o=typeof t.kind=="string"?t.kind:n,s=typeof t.name=="string"?t.name:e.toolName,i=typeof t.description=="string"?t.description:void 0;return{kind:"invocation",kind2:o,name:s,description:i}}if(n==="todo"||n==="todo_list")return{kind:"todo",items:(Array.isArray(t.items)?t.items:[]).map(i=>{const r=i??{};return{title:typeof r.title=="string"?r.title:"",status:typeof r.status=="string"?r.status:"pending"}})};if(n==="plan_review"){const o=typeof t.plan=="string"?t.plan:"",s=typeof t.path=="string"?t.path:void 0,r=(Array.isArray(t.options)?t.options:[]).map(l=>{const a=l??{},u=typeof a.label=="string"?a.label:"";if(!u)return null;const c=typeof a.description=="string"?a.description:void 0;return{label:u,description:c}}).filter(l=>l!==null);return{kind:"plan_review",plan:o,path:s,options:r.length>0?r:void 0}}return{kind:"generic",summary:e.action}}function ige(e){return{questionId:e.questionId,sessionId:e.sessionId,toolCallId:e.toolCallId,questions:e.questions.map(t=>({id:t.id,question:t.question,header:t.header,body:t.body,options:t.options.map(n=>({id:n.id,label:n.label,description:n.description,recommended:n.recommended})),multiSelect:t.multiSelect,allowOther:t.allowOther,otherLabel:t.otherLabel}))}}function rge(e){const t=Me.messagesBySession[e.sessionId];if(!t||t.length===0)return;const n=new Map;for(const s of t)if(s.role==="assistant")for(const i of s.content){if(i.type!=="toolUse"||i.toolName!=="Bash"&&i.toolName!=="bash")continue;const r=i.input,l=r&&typeof r.command=="string"?r.command:void 0;l&&n.set(i.toolCallId,l)}if(n.size===0)return;const o=`task_id: ${e.id}`;for(const s of t)if(s.role==="tool")for(const i of s.content){if(i.type!=="toolResult")continue;if((typeof i.output=="string"?i.output:i.output!==void 0?JSON.stringify(i.output):"").includes(o)){const l=n.get(i.toolCallId);if(l)return l}}}function lge(e){let t;e.status==="running"?t="run":e.status==="completed"?t="done":t="fail";let n="";if(e.status==="running"&&e.startedAt){const r=Math.round((Date.now()-new Date(e.startedAt).getTime())/1e3),l=Math.floor(r/60),a=r%60;n=Hn.global.t("tasks.timingRunning",{time:`${l}:${String(a).padStart(2,"0")}`})}else if(e.completedAt&&e.startedAt){const r=Math.round((new Date(e.completedAt).getTime()-new Date(e.startedAt).getTime())/1e3);n=Hn.global.t("tasks.timingDone",{sec:r})}else n=e.status;const o=e.outputLines&&e.outputLines.length>0?e.outputLines:e.outputPreview?e.outputPreview.split(/\r?\n/):void 0,s=e.command??rge(e),i=e.kind==="bash"&&s?`$ ${s}`:void 0;return{id:e.id,agentId:e.agentId,name:e.description,kind:e.kind,state:t,timing:n,meta:i,output:o,runInBackground:e.runInBackground,parentToolCallId:e.parentToolCallId,model:e.model,thinkingEffort:e.thinkingEffort}}const age=R(()=>{const e=Me.sessions.find(n=>n.id===Me.activeSessionId),t=e?e.cwd.split("/").pop()??e.cwd:"main";return{name:Me.workspaceName,branch:t}}),uge=R(()=>(xc.value,Me.sessions.toSorted((e,t)=>new Date(t.updatedAt).getTime()-new Date(e.updatedAt).getTime()).map(e=>({id:e.id,title:e.title,time:n0(e.updatedAt),busy:u1(e.id,e.mainTurnActive),pendingInteraction:e.pendingInteraction,lastTurnReason:e.lastTurnReason,workspaceId:Ml(e),cwd:e.cwd})))),cge=R(()=>Me.activeSessionId??""),dge=R(()=>{const e=Me.activeSessionId;if(e)return Rn.skillsBySession.value[e]??[];const t=P2.value;return t?Rn.skillsByWorkspace.value[t]??[]:[]}),W5=R(()=>{const e=Me.activeSessionId;return e?Me.inFlightBySession[e]??!1:!1}),fge=R(()=>At.isStartingFirstPrompt()),si=fme(Me,{pushOperationFailure:t0,nextOptimisticMsgId:SN,connectEventsIfNeeded:H5,getEventConn:()=>rr,resolveThinkingForPrompt:(e,t)=>Rn.resolveThinkingForPrompt(e,t),refreshSessionStatus:_c}),o0=R(()=>{const e=Me.activeSessionId;if(!e)return[];const t=si.sideChatTargetBySession.value[e]?.agentId;return(Me.tasksBySession[e]??[]).filter(n=>n.id!==t)}),EN=ghe(Me,o0),s0=R(()=>{const e=Me.activeSessionId;return e?(Me.turnActiveBySession[e]??!1)||(Me.sessions.find(t=>t.id===e)?.mainTurnActive??!1):!1}),pge=R(()=>{const e=Me.activeSessionId;if(e)return Me.turnErrorBySession[e]}),hge=R(()=>{const e=Me.activeSessionId;if(e&&s0.value)return Me.turnRetryBySession[e]}),IN=e=>_t().getFileUrl(e),mge=[],gge=KT(),vge=R(()=>{const e=Me.activeSessionId;if(!e)return[];const t=new Set(Me.sideChatUserMessageIdsBySession[e]??[]);return gge({messages:(Me.messagesBySession[e]??[]).filter(n=>!t.has(n.id)),approvals:Me.approvalsBySession[e]??mge,getFileUrl:IN,sessionActive:s0.value,planReviewByToolCallId:Me.planReviewByToolCallId,plansByToolCallId:Mg[e]})}),yge=R(()=>W5.value||s0.value),kge=R(()=>(EN.taskClock.value,o0.value.map(lge))),LN=R(()=>IX(o0.value)),bge=R(()=>$X(o0.value)),vd=R(()=>{const e=Me.activeSessionId;return e?Me.goalBySession[e]??null:null}),Cge=R(()=>{const e=Me.activeSessionId;return e?bX(Me.messagesBySession[e]??[]):[]}),wge=R(()=>{const e=Me.activeSessionId;return e?Me.compactionBySession[e]??null:null}),_ge=R(()=>Me.connection),xge=R(()=>Me.loading),Sge=R(()=>Me.sessionLoading),Age=R(()=>{const e=Me.activeSessionId;return e?Me.messagesLoadingMoreBySession[e]??!1:!1}),Mge=R(()=>{const e=Me.activeSessionId;return e?Me.messagesHasMoreBySession[e]??!1:!1}),Tge=R(()=>{const e=Me.activeSessionId;return e?Me.messagesLoadMoreErrorBySession[e]??!1:!1}),Ege=R(()=>Me.serverVersion),Ige=R(()=>Me.experimentalFlags),Lge=R(()=>Me.backend),$ge=R(()=>Me.dangerousBypassAuth);function Nge(){Me.dangerousBypassAuth=!1}const Fge=R(()=>Me.permission),Rge=R(()=>Me.thinking),$N=R(()=>{const e=Me.activeSessionId;return e?Me.planModeBySession[e]??!1:F2.planMode}),Oge=R(()=>{const e=Me.activeSessionId;return e?Me.swarmModeBySession[e]??!1:F2.swarmMode}),Pge=R(()=>{const e=Me.activeSessionId;return e?Me.goalModeBySession[e]??!1:F2.goalMode}),Dge=R(()=>{const e=LX(LN.value);return{plan:$N.value,goal:vd.value&&vd.value.status!=="complete"?{status:vd.value.status,turnsUsed:vd.value.turnsUsed,elapsedMs:vd.value.wallClockMs}:null,swarm:e.total>0?e:null}}),Bge=R(()=>{const e=Me.activeSessionId;if(!e)return[];const t=_t();return(Me.queuedBySession[e]??[]).map(n=>({id:n.id??n.text,text:n.text,attachmentCount:n.attachments?.length??0,attachments:n.attachments?.map(o=>({fileId:o.fileId,kind:o.kind,url:t.getFileUrl(o.fileId),name:o.name}))}))}),Hge=R(()=>Me.warnings),zge=R(()=>{const e=Me.activeSessionId;return e?(Me.questionsBySession[e]??[]).map(ige):[]}),Wge=R(()=>{const e=Me.activeSessionId;return e?(Me.approvalsBySession[e]??[]).map(t=>({approvalId:t.approvalId,block:sge(t),agentName:t.agentName,toolCallId:t.toolCallId})):[]}),U5=R(()=>{const e=Me.activeSessionId;return e?(Me.approvalsBySession[e]??[]).length>0?"awaiting-approval":(Me.questionsBySession[e]??[]).length>0?"awaiting-question":W5.value||s0.value?"running":"idle":"idle"}),Rn=dme(Me,{pushOperationFailure:t0,refreshSessionStatus:_c,persistSessionProfile:CN,activity:U5,updateSession:R2,updateSessionMessages:fN,loadConfig:()=>At.loadConfig(),checkAuth:()=>At.checkAuth()}),_8=R(()=>{const e=Me.activeSessionId;if(!e)return null;const t=Me.gitStatusBySession[e];return t?{branch:t.branch,ahead:t.ahead,behind:t.behind}:null}),Uge=R(()=>{const e=Me.activeSessionId;return e?Me.gitStatusBySession[e]?.pullRequest??null:null}),jge=R(()=>{const e=Me.activeSessionId;if(!e)return[];const t=Me.gitStatusBySession[e];return t?Object.entries(t.entries).map(([n,o])=>({path:n,status:o})).sort((n,o)=>n.path.localeCompare(o.path)):[]}),Vge=R(()=>{const e=Me.activeSessionId;if(!e)return null;const t=Me.gitStatusBySession[e];return t?{totalAdditions:t.additions,totalDeletions:t.deletions}:null}),NN=R(()=>{const e=Me.sessions.find(r=>r.id===Me.activeSessionId),t=_8.value?.branch??(e?e.cwd.split("/").pop()??e.cwd:"main"),n=e===void 0?Rn.draftModel.value:null,o=(e?.model&&e.model.length>0?e.model:n??Me.defaultModel)??"—",s=Rn.models.value.find(r=>r.id===o)??Rn.models.value.find(r=>r.model===o);return{model:s?.displayName||s?.model||(o.includes("/")?o.split("/").pop():o),modelId:s?.id??o,ctxUsed:e?.usage.contextTokens??0,ctxMax:e?.usage.contextLimit??0,permission:Me.permission,branch:t,cwd:e?.cwd??"",isGitRepo:_8.value!==null}}),qge=R(()=>mN.value),Kge=R(()=>Me.sessions.find(t=>t.id===Me.activeSessionId)?.usage.totalCostUsd??0),Zge=R(()=>Me.authReady),Gge=R(()=>Me.defaultModel),Yge=R(()=>Me.managedProviderStatus),Xge=R(()=>Me.managedUserInfo),Jge=R(()=>Me.managedMembership),Qge=R(()=>Me.config),e2e=R(()=>{const e=Me.activeSessionId;if(!e)return{};const t=Me.gitStatusBySession[e];return t?{...t.entries}:{}}),t2e=R(()=>{const e=new Map;for(const t of Me.workspaces){const n=Pr(t.root);e.has(n)||e.set(n,t.id)}return e});function Ml(e){return t2e.value.get(Pr(e.cwd))??e.workspaceId??e.cwd}const j5=R(()=>dJ({workspaces:Me.workspaces,sessions:Me.sessions,hiddenWorkspaceRoots:Me.hiddenWorkspaceRoots,sessionsHasMoreByWorkspace:Me.sessionsHasMoreByWorkspace})),Ng=Z(wQ());Je(()=>[j5.value.map(e=>e.id).join("\0"),Me.loading],([e,t])=>{if(t)return;const n=e?e.split("\0"):[],o=UQ(n,Ng.value);o!==null&&(Ng.value=o,wE(o))});const Yo=Z(_E());function FN(e){const t=LJ(Yo.value,e);t!==Yo.value&&(Yo.value=t,k1(t))}function V5(e){const t=uE(Yo.value,e);t!==Yo.value&&(Yo.value=t,k1(t))}function n2e(e){const t=new Set(e),n=Yo.value.filter(o=>!t.has(o));n.length!==Yo.value.length&&(Yo.value=n,k1(n))}function o2e(e){Yo.value.includes(e)?V5(e):FN(e)}function s2e(e){const t=cE(e,Yo.value);Yo.value=t,k1(t)}function i2e(e,t,n){const o=ON.value.map(r=>r.id),s=NJ(o,e,t,n),i=cE(s,Yo.value);Yo.value=i,k1(i)}const Yr=R(()=>{const e=j5.value.map(t=>({id:t.id,name:t.name,root:t.root,shortPath:wme(t.root,Me.fsHome),sessionCount:t.sessionCount}));return jQ(e,Ng.value)}),P2=R(()=>{const e=Me.activeWorkspaceId,t=Yr.value;return e&&t.some(n=>n.id===e)?e:t[0]?.id??null});Je(P2,e=>{e&&(Object.prototype.hasOwnProperty.call(Rn.skillsByWorkspace.value,e)||Rn.loadSkillsForWorkspace(e))},{immediate:!0});const r2e=R(()=>{const e=P2.value;return e?Yr.value.find(t=>t.id===e)??null:null}),l2e=R(()=>{xc.value;const e=new Set(Yr.value.map(n=>n.id)),t=new Map(Yr.value.map(n=>[n.id,n.name]));return Me.sessions.filter(n=>!n.parentSessionId&&e.has(Ml(n))).map(n=>{const o=Ml(n);return{id:n.id,title:n.title,time:n0(n.updatedAt),busy:u1(n.id,n.mainTurnActive),pendingInteraction:n.pendingInteraction,lastTurnReason:n.lastTurnReason,lastPrompt:n.lastPrompt,workspaceId:o,workspaceName:t.get(o)}})}),Fg=Z(xg),q5=R(()=>{xc.value;const e=new Set(Yr.value.map(l=>l.id)),t=new Map(Yr.value.map(l=>[l.id,l.name])),n=new Set(Yo.value),o=(l,a)=>new Date(a.updatedAt).getTime()-new Date(l.updatedAt).getTime(),s=Me.flatSessionsFrontier,i=[],r=[];for(const l of Me.sessions){if(l.parentSessionId||l.archived||n.has(l.id)||!e.has(Ml(l)))continue;if(kE({busy:u1(l.id,l.mainTurnActive),unread:DN.value[l.id]??!1,renaming:!1,questionCount:x8.value[l.id]?.questions??0,approvalCount:x8.value[l.id]?.approvals??0,pendingInteraction:l.pendingInteraction,lastTurnReason:l.lastTurnReason}).hasStatus){i.push(l);continue}s!==null&&new Date(l.updatedAt).getTime()<s||r.push(l)}return i.sort(o),r.sort(o),[...i,...r].map(l=>{const a=Ml(l);return{id:l.id,title:l.title,time:n0(l.updatedAt),busy:u1(l.id,l.mainTurnActive),pendingInteraction:l.pendingInteraction,lastTurnReason:l.lastTurnReason,lastPrompt:l.lastPrompt,updatedAt:l.updatedAt,workspaceId:a,workspaceName:t.get(a),cwdLabel:l.cwd?v1(l.cwd):"-",pullRequest:l.pullRequest}})}),a2e=R(()=>q5.value.slice(0,Fg.value)),u2e=R(()=>Me.flatSessionsHasMore||Fg.value<q5.value.length);function c2e(){Fg.value+=xg,Fg.value>q5.value.length&&Me.flatSessionsHasMore&&At.loadMoreFlatSessions()}function RN(e){xc.value;const t=new Set(Yo.value),n=new Map,o=new Map;for(const s of Me.sessions.toSorted((i,r)=>new Date(r.updatedAt).getTime()-new Date(i.updatedAt).getTime())){if(s.parentSessionId)continue;const i=Ml(s);if(e&&t.has(s.id)){o.set(i,(o.get(i)??0)+1);continue}const r={id:s.id,title:s.title,time:n0(s.updatedAt),busy:u1(s.id,s.mainTurnActive),pendingInteraction:s.pendingInteraction,lastTurnReason:s.lastTurnReason,updatedAt:s.updatedAt},l=n.get(i)??[];l.push(r),n.set(i,l)}return Yr.value.map(s=>({workspace:s,sessions:n.get(s.id)??[],pinnedCount:o.get(s.id)??0,hasMore:Me.sessionsHasMoreByWorkspace[s.id]??!1,loadingMore:Me.sessionsLoadingMoreByWorkspace[s.id]??!1,initialCount:Me.sessionsInitialCountByWorkspace[s.id]??am}))}const d2e=R(()=>RN(!0)),f2e=R(()=>RN(!1)),ON=R(()=>{xc.value;const e=new Set(Yr.value.map(o=>o.id)),t=new Map(Yr.value.map(o=>[o.id,o.name])),n=Me.sessions.filter(o=>!o.parentSessionId&&!o.archived&&e.has(Ml(o)));return $J(n,Yo.value).pinned.map(o=>{const s=Ml(o);return{id:o.id,title:o.title,time:n0(o.updatedAt),busy:u1(o.id,o.mainTurnActive),pendingInteraction:o.pendingInteraction,lastTurnReason:o.lastTurnReason,updatedAt:o.updatedAt,workspaceId:s,workspaceName:t.get(s),pinned:!0,cwdLabel:o.cwd?v1(o.cwd):"-",pullRequest:o.pullRequest}})});function p2e(e){Ng.value=e,wE(e)}const PN=R(()=>{const e={};for(const[t,n]of Object.entries(Me.approvalsBySession))n.length>0&&(e[t]=(e[t]??0)+n.length);for(const[t,n]of Object.entries(Me.questionsBySession))n.length>0&&(e[t]=(e[t]??0)+n.length);return e}),x8=R(()=>{const e={};for(const[t,n]of Object.entries(Me.approvalsBySession))n.length>0&&((e[t]??={approvals:0,questions:0}).approvals=n.length);for(const[t,n]of Object.entries(Me.questionsBySession))n.length>0&&((e[t]??={approvals:0,questions:0}).questions=n.length);return e}),DN=R(()=>{const e={};for(const[t,n]of Object.entries(Me.unreadBySession))n&&(e[t]=!0);return e}),h2e=R(()=>{const e={},t=PN.value;for(const n of Me.sessions){const o=t[n.id]??0;if(o<=0)continue;const s=Ml(n);e[s]=(e[s]??0)+o}return e}),m2e=R(()=>Me.recentRoots),g2e=R(()=>Me.availableOpenInApps),At=ame(Me,{taskPoller:EN,sideChat:si,modelProvider:Rn,pushOperationFailure:t0,activity:U5,sessionsKnownEmpty:MN,setSessions:D5,updateSession:R2,upsertSessionFront:Sme,appendSession:Ame,forgetSession:pN,unpinSessions:n2e,setActiveSessionId:B5,updateSessionMessages:fN,nextOptimisticMsgId:SN,getEventConn:()=>rr,syncSessionFromSnapshot:z5,reopenSession:tge,hasLoadedMessages:Xme,refreshSessionStatus:_c,refreshSessionGoal:Lme,refreshSessionPlans:b8,persistSessionProfile:CN,mergedWorkspaces:j5,workspacesView:Yr,status:NN,workspaceIdForSession:Ml,savePermissionToStorage:vme,savePlanModeToStorage:lN,saveSwarmModeToStorage:aN,saveGoalModeToStorage:uN,draftModes:F2,saveUnread:Iy,saveActiveWorkspaceToStorage:Cme,saveHiddenWorkspacesToStorage:bme,goalErrorMessage:Zme,initialized:kN,connectIssue:bN,selectedDiffPath:hN,fileDiffLines:mN,fileDiffLoading:gN,fileDiffTexts:vN,fileDiffEmptyFile:yN});function K5(e){return e===Me.activeSessionId&&typeof document<"u"&&document.visibilityState==="visible"&&document.hasFocus()}function v2e(e){Me.turnActiveBySession[e]&&delete Me.turnActiveBySession[e],Me.inFlightBySession[e]&&(Me.inFlightBySession[e]=!1)}function y2e(e,t,n){const o=Me.promptIdBySession[e];At.finishPromptLocal(e,{turnWasActive:n}),e===Me.activeSessionId?(At.loadGitStatus(e),_c(e)):t==="idle"&&(Me.unreadBySession[e]=!0,Iy({[e]:!0}));const s=(Me.approvalsBySession[e]??[]).length>0,i=(Me.questionsBySession[e]??[]).length>0;ohe(t,s,i)&&Da.maybeNotifyCompletion(e,{isUserWatching:K5(e),sessionTitle:Me.sessions.find(r=>r.id===e)?.title??"",promptId:o,onClick:()=>{At.selectSession(e)}})}function k2e(e,t){const n=t.questions[0],o=n?.header?.trim()??"",s=n?.question?.trim()??"",i=o&&s?`${o}: ${s}`:s||o;Da.maybeNotifyQuestion({isUserWatching:K5(e),sessionTitle:Me.sessions.find(r=>r.id===e)?.title??"",questionPreview:i,questionId:t.questionId,onClick:()=>{At.selectSession(e)}})}function b2e(e,t){Da.maybeNotifyApproval({isUserWatching:K5(e),sessionTitle:Me.sessions.find(n=>n.id===e)?.title??"",toolName:t.toolName,approvalId:t.approvalId,onClick:()=>{At.selectSession(e)}})}function mu(){return oge(),{workspace:age,sessions:uge,activeSessionId:cge,workspacesView:Yr,visibleWorkspace:r2e,activeWorkspaceId:P2,sessionsForView:l2e,workspaceGroups:d2e,mobileWorkspaceGroups:f2e,pinnedSessions:ON,flatSessions:a2e,flatSessionsHasMore:u2e,flatSessionsLoadingMore:R(()=>Me.flatSessionsLoadingMore),attentionBySession:PN,pendingBySession:x8,attentionByWorkspace:h2e,unreadBySession:DN,recentRoots:m2e,turns:vge,tasks:kge,activeAppTasks:o0,auxiliaryTranscripts:Tg,getFileUrl:IN,todos:Cge,goal:vd,swarms:LN,swarmMembersByToolCallId:bge,activationBadges:Dge,compaction:wge,status:NN,sessionCost:Kge,fileDiff:qge,selectedDiffPath:hN,fileDiffLoading:gN,fileDiffTexts:vN,fileDiffEmptyFile:yN,changes:jge,gitInfo:_8,gitDiffStats:Vge,activePullRequest:Uge,changesByPath:e2e,pendingApprovals:Wge,availableOpenInApps:g2e,connection:_ge,loading:xge,sessionLoading:Sge,loadingMoreMessages:Age,hasMoreMessages:Mge,loadMoreMessagesError:Tge,serverVersion:Ege,backend:Lge,dangerousBypassAuth:$ge,experimentalFlags:Ige,clearDangerousBypassAuth:Nge,initialized:kN,connectIssue:bN,permission:Fge,thinking:Rge,planMode:$N,swarmMode:Oge,goalMode:Pge,queued:Bge,warnings:Hge,questions:zge,activity:U5,turnActive:s0,activeTurnError:pge,activeTurnRetry:hge,inFlight:W5,working:yge,isStartingFirstPrompt:fge,models:Rn.models,starredModelIds:Rn.starredModelIds,providers:Rn.providers,fontScale:$h.fontScale,setFontScale:$h.setFontScale,colorScheme:$h.colorScheme,setColorScheme:$h.setColorScheme,notifyEnabled:Da.notifyEnabled,notifySound:Da.notifySound,notifyPermission:Da.notifyPermission,setNotifyEnabled:Da.setNotifyEnabled,setNotifySound:Da.setNotifySound,onboarded:xN,setOnboarded:Nme,load:At.load,selectSession:At.selectSession,clearActiveSession:At.clearActiveSession,loadOlderMessages:At.loadOlderMessages,loadWorkspaces:At.loadWorkspaces,loadMoreSessions:At.loadMoreSessions,loadAllSessions:At.loadAllSessions,ensureFlatSessions:At.ensureFlatSessions,loadMoreFlatSessions:c2e,selectWorkspace:At.selectWorkspace,openWorkspace:At.openWorkspace,openWorkspaceDraft:At.openWorkspaceDraft,startSessionAndSendPrompt:At.startSessionAndSendPrompt,startSessionAndActivateSkill:At.startSessionAndActivateSkill,startSessionAndOpenSideChat:At.startSessionAndOpenSideChat,addWorkspaceByPath:At.addWorkspaceByPath,browseFs:At.browseFs,getFsHome:At.getFsHome,sendPrompt:At.sendPrompt,steerPrompt:At.steerPrompt,sideChatVisible:si.sideChatVisible,sideChatSessionId:si.sideChatSessionId,sideChatTurns:si.sideChatTurns,sideChatRunning:si.sideChatRunning,sideChatSending:si.sideChatSending,openSideChat:si.openSideChat,closeSideChat:si.closeSideChat,sendSideChatPrompt:si.sendSideChatPrompt,uploadImage:At.uploadImage,abortCurrentPrompt:At.abortCurrentPrompt,respondApproval:At.respondApproval,respondQuestion:At.respondQuestion,dismissQuestion:At.dismissQuestion,pendingQuestionActions:At.pendingQuestionActions,pendingApprovalActions:At.pendingApprovalActions,cancelTask:At.cancelTask,setPermission:At.setPermission,setThinking:Rn.setThinking,setPlanMode:At.setPlanMode,togglePlanMode:At.togglePlanMode,setSwarmMode:At.setSwarmMode,toggleSwarmMode:At.toggleSwarmMode,setGoalMode:At.setGoalMode,toggleGoalMode:At.toggleGoalMode,createGoal:At.createGoal,controlGoal:At.controlGoal,enqueue:At.enqueue,dismissWarning:At.dismissWarning,renameSession:At.renameSession,renameWorkspace:At.renameWorkspace,deleteWorkspace:At.deleteWorkspace,reorderWorkspaces:p2e,pinSession:FN,unpinSession:V5,togglePinSession:o2e,reorderPinnedSessions:s2e,pinSessionAt:i2e,archiveSession:At.archiveSession,exportSession:At.exportSession,restoreSession:At.restoreSession,loadArchivedSessions:At.loadArchivedSessions,compact:At.compact,forkSession:At.forkSession,undo:At.undo,unqueue:At.unqueue,reorderQueue:At.reorderQueue,searchFiles:At.searchFiles,loadGitStatus:At.loadGitStatus,loadFileDiff:At.loadFileDiff,clearFileDiff:At.clearFileDiff,listDir:At.listDir,readFileContent:At.readFileContent,readHostFileContent:At.readHostFileContent,getFileDownloadUrl:At.getFileDownloadUrl,openWorkspaceFile:At.openWorkspaceFile,openInApp:At.openInApp,revealWorkspaceFile:At.revealWorkspaceFile,resolveImageUrl:At.resolveImageUrl,loadModels:Rn.loadModels,loadProviders:Rn.loadProviders,skills:dge,activateSkill:Rn.activateSkill,setModel:Rn.setModel,toggleStarModel:Rn.toggleStarModel,addProvider:Rn.addProvider,updateProvider:Rn.updateProvider,getProvider:Rn.getProvider,deleteProvider:Rn.deleteProvider,refreshProvider:Rn.refreshProvider,refreshAllProviders:Rn.refreshAllProviders,loadCatalogProviders:Rn.loadCatalogProviders,importCatalogProvider:Rn.importCatalogProvider,importCustomRegistry:Rn.importCustomRegistry,authReady:Zge,defaultModel:Gge,managedProviderStatus:Yge,managedUserInfo:Xge,managedMembership:Jge,notify:O2,config:Qge,loadConfig:At.loadConfig,updateConfig:At.updateConfig,checkAuth:At.checkAuth,probeManagedMembership:At.probeManagedMembership,startOAuthLogin:Rn.startOAuthLogin,pollOAuthLogin:Rn.pollOAuthLogin,cancelOAuthLogin:Rn.cancelOAuthLogin,getUsage:Rn.getUsage,logout:At.logout}}const C2e=["aria-expanded"],w2e={class:"user-menu-avatar","aria-hidden":"true"},_2e=["src"],x2e={class:"user-menu-name"},S2e={class:"user-menu-name"},A2e={class:"user-menu-item-label"},M2e={class:"user-menu-item-label"},T2e={class:"user-menu-item-label user-menu-login-label"},E2e={class:"user-menu-item-label"},I2e={class:"user-menu-row-value"},L2e={class:"user-menu-item-label"},$2e={class:"user-menu-row-value"},N2e={class:"user-menu-item-label"},F2e={key:0,class:"user-menu-usage"},R2e={key:0,class:"user-menu-usage-state"},O2e={key:1,class:"user-menu-usage-state"},P2e={class:"user-menu-usage-error"},D2e={key:2,class:"user-menu-usage-state user-menu-usage-empty"},B2e={class:"user-menu-usage-main"},H2e={class:"user-menu-usage-label"},z2e={key:0,class:"user-menu-usage-hint"},W2e={class:"user-menu-item-label"},U2e={class:"user-menu-item-label"},j2e=et({__name:"UserMenu",emits:["login","openSettings"],setup(e,{emit:t}){const n=t,{t:o,locale:s}=Nt(),i=mu(),{confirm:r}=hu(),l=R(()=>i.managedProviderStatus.value==="authenticated"),a=i.managedUserInfo,u=i.managedMembership,c=R(()=>a.value?.nickname||o("sidebar.defaultUserName")),d=R(()=>u.value==="free"||OJ(a.value?.userLevel)),f=R(()=>u.value!=="free"),h=Z(!1);Je(()=>a.value?.avatar,()=>{h.value=!1});const m=R(()=>!!a.value?.avatar&&!h.value),v=i.colorScheme,k=R(()=>o(`theme.${v.value}`)),w=R(()=>v.value==="light"?"light-mode":v.value==="dark"?"dark-mode":"follow-system"),b=[{value:"light",labelKey:"theme.light",icon:"light-mode"},{value:"dark",labelKey:"theme.dark",icon:"dark-mode"},{value:"system",labelKey:"theme.system",icon:"follow-system"}];function _(te){i.setColorScheme(te)}const g=R(()=>yg.find(te=>te.code===s.value)?.label??s.value);function x(te){s.value!==te&&E5(te)}const S=Z(!1),T=Z({}),A=Z(null),E=Z(null);let P=null;function D(te){const ce=te.target;ce.closest(".user-menu")||ce.closest(".user-menu-trigger")||ce.closest(".user-submenu")||O()}function I(te){te.key==="Escape"&&(te.stopPropagation(),O())}async function $(){if(S.value){O();return}S.value=!0,document.addEventListener("mousedown",D),document.addEventListener("keydown",I,!0),window.addEventListener("resize",O),l.value&&oe(),await yt(),B();const te=E.value;te&&(P=new ResizeObserver(H),P.observe(te))}function B(){const te=E.value,ce=A.value?.el;if(!te||!ce)return;const ue=te.getBoundingClientRect(),Se=4,ze=8,_e=ce.offsetHeight,Ee={left:`${Math.round(ue.left)}px`,width:`${Math.round(ue.width)}px`};ue.top-_e-Se<ze?T.value={...Ee,top:`${Math.round(Math.min(ue.bottom+Se,window.innerHeight-_e-ze))}px`,bottom:"auto",transformOrigin:"top left","--menu-pop-shift":"-2px"}:T.value={...Ee,top:"auto",bottom:`${Math.round(window.innerHeight-ue.top+Se)}px`,transformOrigin:"bottom left","--menu-pop-shift":"2px"}}function H(){const te=E.value;if(!te)return;F.value=null;const ce=te.getBoundingClientRect();T.value={...T.value,left:`${Math.round(ce.left)}px`,width:`${Math.round(ce.width)}px`}}function O(){S.value=!1,F.value=null,le(),P?.disconnect(),P=null,document.removeEventListener("mousedown",D),document.removeEventListener("keydown",I,!0),window.removeEventListener("resize",O)}Vn(O);const F=Z(null),U=Z({}),z=Z(null),W={usage:null,theme:null,language:null};let K=null;function V(te){return ce=>{W[te]=ce instanceof HTMLElement?ce:ce?.$el??null}}function ie(te){le(),F.value!==te&&(F.value=te,yt(Ie))}function ne(te,ce){te.key!=="Enter"&&te.key!==" "&&te.key!=="ArrowRight"||(te.preventDefault(),ie(ce))}function X(){le(),K=setTimeout(()=>{F.value=null,K=null},250)}function le(){K!==null&&(clearTimeout(K),K=null)}function Ie(){const te=F.value,ce=A.value?.el,ue=z.value?.el,Se=te!==null?W[te]:null;if(!ce||!ue||!Se)return;const ze=4,_e=8,Ee=ce.getBoundingClientRect(),it=Se.getBoundingClientRect(),Fe=ue.offsetHeight,Oe=Math.min(ue.offsetWidth,Ee.width);let Ge=Ee.right+ze,at=!1;Ge+Oe>window.innerWidth-_e&&(Ge=Math.max(_e,Ee.left-Oe-ze),at=!0);const Tt=Math.max(_e,Math.min(it.top,window.innerHeight-Fe-_e));U.value={top:`${Math.round(Tt)}px`,left:`${Math.round(Ge)}px`,maxWidth:`${Math.round(Ee.width)}px`,transformOrigin:at?"top right":"top left","--menu-pop-shift":"-2px"}}const de=Z(!1),pe=Z(null);let ve=0;async function oe(){const te=++ve;de.value=!0;try{const ce=await i.getUsage();te===ve&&(pe.value=ce)}finally{te===ve&&(de.value=!1)}}const ye=R(()=>{if(pe.value?.kind!=="ok")return[];const{summary:te,limits:ce}=pe.value,ue=FJ(ce,5,"hour");return[te,ue].filter(Se=>Se!=null)}),G=R(()=>pe.value?.kind==="error"?pe.value.message:o("settings.planUsage.loadFailed"));function Y(te){return te.resetAt===void 0?"":fE(te.resetAt,o)}function fe(){O(),jp()}function we(){O(),n("login")}function ge(){O(),n("openSettings")}async function Q(){O(),await r({title:o("sidebar.logoutConfirmTitle"),message:o("sidebar.logoutConfirmMessage"),variant:"danger",action:()=>i.logout()})}return(te,ce)=>(y(),M(Pe,null,[C("button",{ref_key:"triggerRef",ref:E,class:"user-menu-trigger",type:"button","aria-haspopup":"menu","aria-expanded":S.value,onClick:It($,["stop"])},[l.value?(y(),M(Pe,{key:0},[C("span",w2e,[m.value?(y(),M("img",{key:0,src:p(a)?.avatar,alt:"",onError:ce[0]||(ce[0]=ue=>h.value=!0)},null,40,_2e)):(y(),he(p(Te),{key:1,name:"user",size:"sm"}))]),C("span",x2e,N(c.value),1)],64)):(y(),M(Pe,{key:1},[j(p(Te),{name:"user"}),C("span",S2e,N(p(o)("sidebar.notSignedIn")),1)],64))],8,C2e),(y(),he(Zr,{to:"body"},[j(as,{name:"menu-pop"},{default:me(()=>[S.value?(y(),he(p(Cl),{key:0,ref_key:"menuRef",ref:A,class:"user-menu",style:Zt(T.value),onClick:ce[14]||(ce[14]=It(()=>{},["stop"]))},{default:me(()=>[l.value?(y(),M(Pe,{key:0},[f.value?(y(),he(p(hn),{key:0,ref:V("usage"),"aria-haspopup":"true","aria-expanded":F.value==="usage",onMouseenter:ce[1]||(ce[1]=ue=>ie("usage")),onMouseleave:X,onFocus:ce[2]||(ce[2]=ue=>ie("usage")),onBlur:X,onClick:ce[3]||(ce[3]=ue=>ie("usage")),onKeydown:ce[4]||(ce[4]=ue=>ne(ue,"usage"))},{default:me(()=>[j(p(Te),{name:"histogram",size:"sm"}),C("span",A2e,N(p(o)("settings.planUsage.title")),1),j(p(Te),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"])):ee("",!0),d.value?(y(),he(p(hn),{key:1,onClick:fe,onMouseenter:X},{default:me(()=>[j(p(Te),{name:"music",size:"sm"}),C("span",M2e,N(p(o)("sidebar.upgrade")),1),j(p(Te),{name:"external-link",size:"sm"})]),_:1})):ee("",!0),j(p(hn),{separator:""})],64)):(y(),M(Pe,{key:1},[j(p(hn),{class:"user-menu-login",onClick:we,onMouseenter:X},{default:me(()=>[j(p(Te),{name:"log-in",size:"sm"}),C("span",T2e,N(p(o)("sidebar.signIn")),1)]),_:1}),j(p(hn),{separator:""})],64)),j(p(hn),{ref:V("theme"),"aria-haspopup":"true","aria-expanded":F.value==="theme",onMouseenter:ce[5]||(ce[5]=ue=>ie("theme")),onMouseleave:X,onFocus:ce[6]||(ce[6]=ue=>ie("theme")),onBlur:X,onClick:ce[7]||(ce[7]=ue=>ie("theme")),onKeydown:ce[8]||(ce[8]=ue=>ne(ue,"theme"))},{default:me(()=>[j(p(Te),{name:w.value,size:"sm"},null,8,["name"]),C("span",E2e,N(p(o)("theme.colorSchemeLabel")),1),C("span",I2e,N(k.value),1),j(p(Te),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"]),j(p(hn),{ref:V("language"),"aria-haspopup":"true","aria-expanded":F.value==="language",onMouseenter:ce[9]||(ce[9]=ue=>ie("language")),onMouseleave:X,onFocus:ce[10]||(ce[10]=ue=>ie("language")),onBlur:X,onClick:ce[11]||(ce[11]=ue=>ie("language")),onKeydown:ce[12]||(ce[12]=ue=>ne(ue,"language"))},{default:me(()=>[j(p(Te),{name:"translate",size:"sm"}),C("span",L2e,N(p(o)("sidebar.language")),1),C("span",$2e,N(g.value),1),j(p(Te),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"]),j(p(hn),{onClick:ge,onMouseenter:X},{default:me(()=>[j(p(Te),{name:"settings",size:"sm"}),C("span",N2e,N(p(o)("settings.title")),1)]),_:1}),l.value?(y(),M(Pe,{key:2},[j(p(hn),{separator:""}),j(p(hn),{onClick:ce[13]||(ce[13]=ue=>void Q()),onMouseenter:X},{default:me(()=>[j(p(Te),{name:"log-out",size:"sm"}),qe(" "+N(p(o)("sidebar.signOut")),1)]),_:1})],64)):ee("",!0)]),_:1},8,["style"])):ee("",!0)]),_:1})])),(y(),he(Zr,{to:"body"},[j(as,{name:"menu-pop"},{default:me(()=>[F.value!==null?(y(),he(p(Cl),{key:0,ref_key:"submenuRef",ref:z,class:"user-submenu",style:Zt(U.value),role:F.value==="usage"?"dialog":"menu",onClick:ce[16]||(ce[16]=It(()=>{},["stop"])),onMouseenter:le,onMouseleave:X,onFocusin:le,onFocusout:X},{default:me(()=>[F.value==="usage"?(y(),M("div",F2e,[de.value?(y(),M("div",R2e,[j(p(Ao),{size:"sm"})])):pe.value?.kind!=="ok"?(y(),M("div",O2e,[C("span",P2e,N(G.value),1),j(p(Rt),{variant:"ghost",size:"sm",onClick:ce[15]||(ce[15]=ue=>void oe())},{default:me(()=>[qe(N(p(o)("settings.planUsage.retry")),1)]),_:1})])):ye.value.length===0?(y(),M("span",D2e,N(p(o)("settings.planUsage.empty")),1)):(y(!0),M(Pe,{key:3},pt(ye.value,(ue,Se)=>(y(),M("div",{key:Se,class:"user-menu-usage-row"},[C("span",B2e,[C("span",H2e,N(p(dE)(ue,p(o))),1),Y(ue)?(y(),M("span",z2e,N(Y(ue)),1)):ee("",!0)]),C("span",{class:Re(["user-menu-usage-value",`sev-${p(C3)(ue.used,ue.limit)}`])},N(p(Wh)(ue.used,ue.limit))+"% ",3)]))),128))])):F.value==="theme"?(y(),M(Pe,{key:1},pt(b,ue=>j(p(hn),{key:ue.value,onClick:Se=>_(ue.value)},{default:me(()=>[j(p(Te),{name:ue.icon,size:"sm"},null,8,["name"]),C("span",W2e,N(p(o)(ue.labelKey)),1),p(v)===ue.value?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)]),_:2},1032,["onClick"])),64)):(y(!0),M(Pe,{key:2},pt(p(yg),ue=>(y(),he(p(hn),{key:ue.code,onClick:Se=>x(ue.code)},{default:me(()=>[C("span",U2e,N(ue.label),1),p(s)===ue.code?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)]),_:2},1032,["onClick"]))),128))]),_:1},8,["style","role"])):ee("",!0)]),_:1})]))],64))}}),V2e=ft(j2e,[["__scopeId","data-v-06f13413"]]),q2e={class:"ep-search"},K2e=["placeholder"],Z2e={class:"ep-scroll"},G2e={key:0,class:"ep-grid"},Y2e=["onClick"],X2e={key:1,class:"ep-empty"},J2e={class:"ep-label"},Q2e={class:"ep-grid"},eve=["onClick"],tve={class:"ep-label"},nve={class:"ep-grid"},ove=["onClick"],Kx="kimi-web.recent-emojis",sve=et({__name:"SessionEmojiPicker",props:{current:{default:null},removable:{type:Boolean,default:!0}},emits:["pick"],setup(e,{expose:t,emit:n}){const{t:o}=Nt(),{handleCompositionStart:s,handleCompositionEnd:i,isComposingKeyEvent:r}=Ar(),l=e,a=n,u=["⏳","⚠️","🐛","✨","🔥","🚀","🎯","🧪","📝","🔍","🛠️","💡","📦","🎨","🔒","📈","🧹","🚧","✅","❓","🌙","☕","🐳","🗂️","📊","🤖","🧩","⚙️","🌱","📌","💥","🕐"],c={faces:"sidebar.emojiGroupFaces",nature:"sidebar.emojiGroupNature",food:"sidebar.emojiGroupFood",activity:"sidebar.emojiGroupActivity",objects:"sidebar.emojiGroupObjects",symbols:"sidebar.emojiGroupSymbols"},d=sJ.map(S=>({id:S,labelKey:c[S],emojis:sE.filter(T=>T.group===S).map(T=>T.emoji)})),f=Z(h());function h(){try{const S=JSON.parse(localStorage.getItem(Kx)??"[]");return Array.isArray(S)?S.filter(T=>typeof T=="string"):[]}catch{return[]}}function m(S){f.value=aJ(f.value,S);try{localStorage.setItem(Kx,JSON.stringify(f.value))}catch{}a("pick",S)}const v=Z(""),k=R(()=>v.value.trim().length>0),w=R(()=>rJ(v.value)),b=Z(null);dn(()=>b.value?.focus());function _(S){if(r(S))return;const T=w.value[0];k.value&&T&&m(T)}function g(){let S=l.current??void 0;for(;S===void 0||S===l.current;)S=u[Math.floor(Math.random()*u.length)];m(S)}const x=Z(null);return t({el:R(()=>x.value?.el),isComposingKeyEvent:r}),(S,T)=>(y(),he(p(Cl),{ref_key:"menuRef",ref:x,class:"emoji-picker",role:"dialog","aria-label":p(o)("sidebar.sessionEmojiTitle"),onKeydown:T[4]||(T[4]=It(()=>{},["stop"]))},{default:me(()=>[C("div",q2e,[j(p(Te),{name:"search",size:"sm"}),Bn(C("input",{ref_key:"inputRef",ref:b,"onUpdate:modelValue":T[0]||(T[0]=A=>v.value=A),class:"ep-input",type:"text",placeholder:p(o)("sidebar.searchEmoji"),autocomplete:"off",spellcheck:"false",onKeydown:xl(_,["enter"]),onCompositionstart:T[1]||(T[1]=(...A)=>p(s)&&p(s)(...A)),onCompositionend:T[2]||(T[2]=(...A)=>p(i)&&p(i)(...A))},null,40,K2e),[[ai,v.value]])]),C("div",Z2e,[k.value?(y(),M(Pe,{key:0},[w.value.length?(y(),M("div",G2e,[(y(!0),M(Pe,null,pt(w.value,A=>(y(),M("button",{key:A,class:Re(["ep-e",{sel:A===e.current}]),type:"button",onClick:E=>m(A)},N(A),11,Y2e))),128))])):(y(),M("div",X2e,N(p(o)("sidebar.noEmojiResults")),1))],64)):(y(),M(Pe,{key:1},[f.value.length?(y(),M(Pe,{key:0},[C("div",J2e,N(p(o)("sidebar.recentEmojis")),1),C("div",Q2e,[(y(!0),M(Pe,null,pt(f.value,A=>(y(),M("button",{key:A,class:Re(["ep-e",{sel:A===e.current}]),type:"button",onClick:E=>m(A)},N(A),11,eve))),128))])],64)):ee("",!0),(y(!0),M(Pe,null,pt(p(d),A=>(y(),M(Pe,{key:A.id},[C("div",tve,N(p(o)(A.labelKey)),1),C("div",nve,[(y(!0),M(Pe,null,pt(A.emojis,E=>(y(),M("button",{key:E,class:Re(["ep-e",{sel:E===e.current}]),type:"button",onClick:P=>m(E)},N(E),11,ove))),128))])],64))),128))],64))]),j(p(hn),{separator:""}),j(p(hn),{role:"button",disabled:!(e.current&&e.removable),onClick:T[3]||(T[3]=A=>a("pick",null))},{default:me(()=>[j(p(Te),{name:"close",size:"sm"}),qe(" "+N(p(o)("sidebar.removeEmoji")),1)]),_:1},8,["disabled"]),j(p(hn),{role:"button",onClick:g},{default:me(()=>[j(p(Te),{name:"sparkles",size:"sm"}),qe(" "+N(p(o)("sidebar.randomEmoji")),1)]),_:1})]),_:1},8,["aria-label"]))}}),ive=ft(sve,[["__scopeId","data-v-05e46bbb"]]),rve={class:"row"},lve={key:0,class:"lead","aria-hidden":"true"},ave={key:1,class:"unread-dot"},uve={class:"left"},cve=["onKeydown"],dve=["aria-label"],fve={class:"act"},pve={key:0,class:"ts"},hve={key:1,class:"st"},mve={key:1,class:"unread-dot"},gve={key:2,class:"ha"},vve={key:0,class:"sub"},yve={class:"sub-text"},kve=["aria-label"],bve={class:"menu-time"},Cve=et({__name:"SessionRow",props:{session:{},active:{type:Boolean},approvalCount:{default:0},questionCount:{default:0},unread:{type:Boolean,default:!1}},emits:["select","rename","renameStateChange","archive","fork","export","pin"],setup(e,{expose:t,emit:n}){const{t:o}=Nt(),s=e,i=n;function r(ue){const Se=new Date(ue);if(Number.isNaN(Se.getTime()))return ue;const ze=_e=>String(_e).padStart(2,"0");return`${Se.getFullYear()}-${ze(Se.getMonth()+1)}-${ze(Se.getDate())} ${ze(Se.getHours())}:${ze(Se.getMinutes())}`}const l=R(()=>s.session.updatedAt?r(s.session.updatedAt):s.session.time),a=R(()=>s.session.cwdLabel!==void 0),u=R(()=>kE({busy:s.session.busy,unread:s.unread,renaming:W.value,questionCount:s.questionCount,approvalCount:s.approvalCount,pendingInteraction:s.session.pendingInteraction,lastTurnReason:s.session.lastTurnReason})),c=R(()=>u.value.showQuestionBadge),d=R(()=>u.value.showApprovalBadge),f=R(()=>u.value.showAbortedBadge),h=R(()=>u.value.showBusySpinner),m=R(()=>u.value.hasStatus),v=Z(!1),k=Z(null),w=Z({});function b(ue){const Se=ue.target;k.value?.el?.contains(Se)||g()}async function _(){$(),v.value=!0,setTimeout(()=>document.addEventListener("mousedown",b),0),window.addEventListener("resize",g),await yt()}function g(){v.value=!1,document.removeEventListener("mousedown",b),window.removeEventListener("resize",g)}bn(()=>{document.removeEventListener("mousedown",b),document.removeEventListener("mousedown",B),window.removeEventListener("keydown",H,!0),window.removeEventListener("resize",g),window.removeEventListener("resize",$)});const x=R(()=>yE(s.session.title)),S=R(()=>{const ue=x.value.emoji;return ue?s.session.title.slice(ue.length):s.session.title}),T=Z(!1),A=Z(null),E=Z({});let P=null;function D(ue,Se,ze){const _e=A.value?.el,Ee=4,it=8,Fe=_e?.offsetHeight??0,Oe=_e?.offsetWidth??0;let Ge=ue.bottom+Ee,at=!1;Ge+Fe>window.innerHeight-it&&(Ge=Math.max(it,ue.top-Fe-Ee),at=!0);const Tt=ze??(Se==="left"?ue.left:ue.right-Oe),Bt=Math.max(it,Math.min(Tt,window.innerWidth-Oe-it)),Yt=ze===void 0?Se:`${Math.round(Math.min(Math.max(ze-Bt,0),Oe))}px`;E.value={top:`${Math.round(Ge)}px`,left:`${Math.round(Bt)}px`,transformOrigin:`${Yt} ${at?"bottom":"top"}`,"--menu-pop-shift":at?"2px":"-2px"}}async function I(ue,Se,ze="left",_e){const Ee=Se??ue?.getBoundingClientRect();if(Ee){if(T.value){$();return}g(),P=ue??null,T.value=!0,setTimeout(()=>document.addEventListener("mousedown",B),0),window.addEventListener("keydown",H,!0),window.addEventListener("resize",$),await yt(),D(Ee,ze,_e)}}function $(){T.value=!1,P=null,document.removeEventListener("mousedown",B),window.removeEventListener("keydown",H,!0),window.removeEventListener("resize",$)}function B(ue){const Se=ue.target;A.value?.el?.contains(Se)||P?.contains(Se)||$()}function H(ue){ue.key==="Escape"&&(A.value?.isComposingKeyEvent(ue)||(ue.preventDefault(),ue.stopPropagation(),$()))}function O(ue){return ue.clientX||ue.clientY?new DOMRect(ue.clientX,ue.clientY,0,0):void 0}function F(ue){ue.stopPropagation();const Se=ue;I(Se.currentTarget,O(Se),"left",Se.clientX||void 0)}function U(ue){const Se=k.value?.el,ze=ue,_e=O(ze)??Se?.getBoundingClientRect();g(),I(Se,_e,"left",ze.clientX||void 0)}function z(ue){if($(),ue===x.value.emoji)return;const Se=dQ(s.session.title,ue);Se&&Se!==s.session.title&&i("rename",s.session.id,Se)}const W=Z(!1),K=Z(""),V=Z(null),{handleCompositionStart:ie,handleCompositionEnd:ne,isComposingKeyEvent:X}=Ar();async function le(){g(),$(),W.value=!0,K.value=s.session.title,await yt();try{V.value?.focus(),V.value?.select()}catch{}}function Ie(){const ue=K.value.trim();ue&&ue!==s.session.title&&i("rename",s.session.id,ue),W.value=!1}function de(ue){X(ue)||Ie()}function pe(ue){X(ue)||ve()}function ve(){W.value=!1}Je(W,ue=>i("renameStateChange",ue));async function oe(ue){W.value||(ue.preventDefault(),ue.stopPropagation(),v.value&&g(),await _(),ye(ue))}function ye(ue){const Se=k.value?.el,ze=8,_e=Se?.offsetHeight??0,Ee=Se?.offsetWidth??0;let it=ue.clientY,Fe=!1;it+_e>window.innerHeight-ze&&(it=Math.max(ze,ue.clientY-_e),Fe=!0);let Oe=ue.clientX,Ge=!1;Oe+Ee>window.innerWidth-ze&&(Oe=Math.max(ze,ue.clientX-Ee),Ge=!0),w.value={top:`${Math.round(it)}px`,left:`${Math.round(Oe)}px`,transformOrigin:`${Fe?"bottom":"top"} ${Ge?"right":"left"}`,"--menu-pop-shift":Fe?"2px":"-2px"}}const G=Z(!1),Y=Z(!1);async function fe(){const ue=await Zs(s.session.id);G.value=ue,Y.value=!ue,setTimeout(()=>{G.value=!1,Y.value=!1,g()},1500)}function we(){g(),i("fork",s.session.id)}function ge(){g(),i("export",s.session.id)}function Q(){g(),i("pin",s.session.id)}function te(){g(),i("archive",s.session.id)}t({closeMenu:g});function ce(){const ue=s.session.pullRequest?.url;ue&&window.open(ue,"_blank","noopener")}return(ue,Se)=>(y(),M("div",{class:Re(["se",{on:e.active,flat:a.value}]),onClick:Se[7]||(Se[7]=ze=>i("select",e.session.id)),onContextmenu:oe},[C("div",rve,[a.value?ee("",!0):(y(),M("span",lve,[e.session.busy?(y(),he(p(Ao),{key:0,size:"sm"})):e.unread?(y(),M("span",ave)):ee("",!0)])),C("div",uve,[W.value?Bn((y(),M("input",{key:0,ref_key:"renameInputRef",ref:V,"onUpdate:modelValue":Se[0]||(Se[0]=ze=>K.value=ze),class:"rename-input",onClick:Se[1]||(Se[1]=It(()=>{},["stop"])),onKeydown:[xl(It(de,["stop"]),["enter"]),xl(It(pe,["stop"]),["esc"])],onCompositionstart:Se[2]||(Se[2]=(...ze)=>p(ie)&&p(ie)(...ze)),onCompositionend:Se[3]||(Se[3]=(...ze)=>p(ne)&&p(ne)(...ze)),onBlur:Ie},null,40,cve)),[[ai,K.value]]):(y(),M("span",{key:1,class:"t",onDblclick:It(le,["stop"])},[x.value.emoji?(y(),M("button",{key:0,type:"button",class:"emoji","aria-label":p(o)("sidebar.setEmoji"),onClick:It(F,["stop"]),onDblclick:Se[4]||(Se[4]=It(()=>{},["stop"]))},N(x.value.emoji),41,dve)):ee("",!0),qe(N(S.value),1)],32))]),C("span",fve,[j(p(pn),{text:p(o)("workspace.awaitingAnswerTitle")},{default:me(()=>[c.value?(y(),he(p(Vr),{key:0,variant:"info",size:"sm"},{default:me(()=>[qe(N(p(o)("workspace.awaitingAnswer")),1)]),_:1})):ee("",!0)]),_:1},8,["text"]),j(p(pn),{text:p(o)("workspace.awaitingPermissionTitle")},{default:me(()=>[d.value?(y(),he(p(Vr),{key:0,variant:"warning",size:"sm"},{default:me(()=>[qe(N(p(o)("workspace.awaitingPermission")),1)]),_:1})):ee("",!0)]),_:1},8,["text"]),j(p(pn),{text:p(o)("workspace.abortedTitle")},{default:me(()=>[f.value?(y(),he(p(Vr),{key:0,variant:"danger",size:"sm"},{default:me(()=>[qe(N(p(o)("workspace.aborted")),1)]),_:1})):ee("",!0)]),_:1},8,["text"]),!a.value||!m.value?(y(),M("span",pve,N(e.session.time),1)):h.value||e.unread?(y(),M("span",hve,[h.value?(y(),he(p(Ao),{key:0,size:"sm"})):(y(),M("span",mve))])):ee("",!0),W.value?ee("",!0):(y(),M("span",gve,[j(p(pn),{text:e.session.pinned?p(o)("sidebar.unpin"):p(o)("sidebar.pin")},{default:me(()=>[j(p(gn),{class:"pin-btn",size:"sm",label:e.session.pinned?p(o)("sidebar.unpin"):p(o)("sidebar.pin"),onClick:It(Q,["stop"])},{default:me(()=>[j(p(Te),{name:e.session.pinned?"unpin":"pin"},null,8,["name"])]),_:1},8,["label"])]),_:1},8,["text"]),j(p(pn),{text:p(o)("sidebar.archive")},{default:me(()=>[j(p(gn),{class:"archive-btn",size:"sm",label:p(o)("sidebar.archive"),onClick:It(te,["stop"])},{default:me(()=>[j(p(Te),{name:"archive"})]),_:1},8,["label"])]),_:1},8,["text"])]))])]),e.session.cwdLabel!==void 0?(y(),M("div",vve,[j(p(Te),{class:"sub-icon",name:"folder-closed",size:"sm"}),C("span",yve,N(e.session.cwdLabel),1),e.session.pullRequest?(y(),M("button",{key:0,type:"button",class:Re(["pr",`pr--${e.session.pullRequest.state}`]),"aria-label":`PR #${e.session.pullRequest.number}`,onClick:It(ce,["stop"])},[j(p(Te),{name:"git-pull-request",size:"sm"}),C("span",null,"#"+N(e.session.pullRequest.number),1)],10,kve)):ee("",!0)])):ee("",!0),(y(),he(Zr,{to:"body"},[j(as,{name:"menu-pop"},{default:me(()=>[v.value?(y(),he(p(Cl),{key:0,ref_key:"menuRef",ref:k,class:"menu",style:Zt(w.value),onClick:Se[5]||(Se[5]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{danger:Y.value,onClick:fe},{default:me(()=>[j(p(Te),{name:"copy",size:"sm"}),qe(" "+N(Y.value?p(o)("sidebar.copyFailed"):G.value?p(o)("sidebar.copied"):p(o)("sidebar.copySessionId")),1)]),_:1},8,["danger"]),j(p(hn),{separator:""}),j(p(hn),{onClick:le},{default:me(()=>[j(p(Te),{name:"pencil",size:"sm"}),qe(" "+N(p(o)("sidebar.rename")),1)]),_:1}),j(p(hn),{onClick:U},{default:me(()=>[j(p(Te),{name:"emoji",size:"sm"}),qe(" "+N(p(o)("sidebar.setEmoji")),1)]),_:1}),j(p(hn),{onClick:we},{default:me(()=>[j(p(Te),{name:"git-fork",size:"sm"}),qe(" "+N(p(o)("sidebar.fork")),1)]),_:1}),j(p(hn),{onClick:ge},{default:me(()=>[j(p(Te),{name:"download",size:"sm"}),qe(" "+N(p(o)("sidebar.export")),1)]),_:1}),j(p(hn),{onClick:Q},{default:me(()=>[j(p(Te),{name:e.session.pinned?"unpin":"pin",size:"sm"},null,8,["name"]),qe(" "+N(e.session.pinned?p(o)("sidebar.unpin"):p(o)("sidebar.pin")),1)]),_:1}),j(p(hn),{onClick:te},{default:me(()=>[j(p(Te),{name:"archive",size:"sm"}),qe(" "+N(p(o)("sidebar.archive")),1)]),_:1}),j(p(hn),{separator:""}),C("div",bve,N(l.value),1)]),_:1},8,["style"])):ee("",!0)]),_:1})])),(y(),he(Zr,{to:"body"},[j(as,{name:"menu-pop"},{default:me(()=>[T.value?(y(),he(ive,{key:0,ref_key:"pickerRef",ref:A,class:"picker",style:Zt(E.value),current:x.value.emoji,removable:x.value.rest.length>0,onClick:Se[6]||(Se[6]=It(()=>{},["stop"])),onPick:z},null,8,["style","current","removable"])):ee("",!0)]),_:1})]))],34))}}),Z5=ft(Cve,[["__scopeId","data-v-341acfa2"]]),wve=["draggable"],_ve={class:"gh-top"},xve={class:"gh-name"},Sve=["inert"],Ave={key:0,class:"show-more-row"},Mve=["disabled"],Tve={class:"show-more-label"},Eve={key:1,class:"show-more-sep","aria-hidden":"true"},Ive={class:"show-more-label"},Lve={key:1,class:"group-empty"},$ve=et({__name:"WorkspaceGroup",props:{group:{},activeWorkspaceId:{},activeId:{},renamingId:{},renameValue:{},renameInputRef:{},pendingBySession:{},unreadBySession:{},wsMenuOpenId:{},dragging:{type:Boolean},isCollapsed:{type:Function},visibleLimit:{type:Function},pinnedDragSession:{}},emits:["groupClick","groupContextmenu","toggleWsMenu","createInWorkspace","selectSession","renameSession","archiveSession","forkSession","exportSession","pinSession","dropPinnedSession","expand","collapse","confirmRename","cancelRename","updateRenameValue","wsDragstart","wsDragend"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=R({get:()=>o.renameValue,set:P=>s("updateRenameValue",P)}),r=Z(!1),l=R(()=>o.pinnedDragSession!=null),a=R(()=>o.pinnedDragSession?.workspaceId===o.group.workspace.id);function u(P){if(o.pinnedDragSession!=null){if(!a.value){P.dataTransfer&&(P.dataTransfer.dropEffect="none");return}P.preventDefault(),P.dataTransfer&&(P.dataTransfer.dropEffect="move"),r.value=!0}}function c(P){o.pinnedDragSession==null||!a.value||(P.preventDefault(),r.value=!1,s("dropPinnedSession",o.pinnedDragSession.id))}function d(P){P.currentTarget.contains(P.relatedTarget)||(r.value=!1)}const f=R(()=>o.visibleLimit(o.group.workspace.id)??o.group.initialCount),h=R(()=>{const P=o.group.sessions.slice(0,f.value);if(o.activeId&&!P.some(D=>D.id===o.activeId)){const D=o.group.sessions.find(I=>I.id===o.activeId);if(D)return[...P,D]}return P}),m=R(()=>o.group.sessions.length>f.value||o.group.hasMore||o.group.loadingMore),v=R(()=>f.value>o.group.initialCount);function k(P){o.renameInputRef.value=P instanceof HTMLInputElement?P:null}const{handleCompositionStart:w,handleCompositionEnd:b,isComposingKeyEvent:_}=Ar();function g(P){_(P)||s("confirmRename")}function x(P){_(P)||s("cancelRename")}const S=Z(null);function T(P){o.renamingId!==o.group.workspace.id&&s("groupContextmenu",o.group.workspace,P)}function A(P){P.dataTransfer&&(P.dataTransfer.effectAllowed="move",P.dataTransfer.setData("text/plain",o.group.workspace.id),s("wsDragstart",o.group.workspace.id))}function E(P,D){D.dataTransfer&&(D.dataTransfer.effectAllowed="move",D.dataTransfer.setData(Bf,P),D.dataTransfer.setData("text/plain",P))}return(P,D)=>(y(),M("div",{class:Re(["group",{dragging:e.dragging,"pinned-drag-active":l.value&&a.value,"pinned-drop-hover":r.value,"pinned-drop-blocked":l.value&&!a.value}]),onDragover:u,onDrop:c,onDragleave:d},[C("div",{class:Re(["gh",{on:e.group.workspace.id===e.activeWorkspaceId&&e.activeId==="",collapsed:e.isCollapsed(e.group.workspace.id)}]),draggable:e.renamingId!==e.group.workspace.id,onClick:D[7]||(D[7]=It(I=>s("groupClick",e.group.workspace.id,I),["stop"])),onContextmenu:T,onDragstart:A,onDragend:D[8]||(D[8]=I=>s("wsDragend"))},[C("div",_ve,[e.isCollapsed(e.group.workspace.id)?(y(),he(p(Te),{key:0,class:"gh-folder",name:"folder-closed"})):(y(),he(p(Te),{key:1,class:"gh-folder",name:"folder"})),e.renamingId!==e.group.workspace.id?(y(),he(p(pn),{key:2,text:e.group.workspace.root},{default:me(()=>[C("span",xve,N(e.group.workspace.name),1)]),_:1},8,["text"])):Bn((y(),M("input",{key:3,ref:k,"onUpdate:modelValue":D[0]||(D[0]=I=>i.value=I),class:"gh-rename",type:"text",onKeydown:[xl(g,["enter"]),xl(x,["esc"])],onCompositionstart:D[1]||(D[1]=(...I)=>p(w)&&p(w)(...I)),onCompositionend:D[2]||(D[2]=(...I)=>p(b)&&p(b)(...I)),onBlur:D[3]||(D[3]=I=>s("cancelRename")),onClick:D[4]||(D[4]=It(()=>{},["stop"]))},null,544)),[[ai,i.value]]),e.renamingId!==e.group.workspace.id?(y(),M("div",{key:4,class:Re(["gh-actions",{open:e.wsMenuOpenId===e.group.workspace.id}])},[j(p(gn),{class:Re(["gh-more",{open:e.wsMenuOpenId===e.group.workspace.id}]),size:"sm",label:p(n)("sidebar.options"),tooltip:p(n)("sidebar.options"),"aria-haspopup":"menu","aria-expanded":e.wsMenuOpenId===e.group.workspace.id,onClick:D[5]||(D[5]=It(I=>s("toggleWsMenu",e.group.workspace,I),["stop"]))},{default:me(()=>[j(p(Te),{name:"dots-horizontal"})]),_:1},8,["class","label","tooltip","aria-expanded"]),j(p(gn),{class:"gh-add",size:"sm",label:p(n)("workspace.newInGroup"),tooltip:p(n)("workspace.newInGroup"),onClick:D[6]||(D[6]=It(I=>s("createInWorkspace",e.group.workspace.id),["stop"]))},{default:me(()=>[j(p(Te),{name:"chat-new"})]),_:1},8,["label","tooltip"])],2)):ee("",!0)])],42,wve),C("div",{class:Re(["group-sessions",{collapsed:e.isCollapsed(e.group.workspace.id)}]),inert:e.isCollapsed(e.group.workspace.id)},[(y(!0),M(Pe,null,pt(h.value,I=>(y(),he(Z5,{key:I.id,session:I,active:I.id===e.activeId,"approval-count":e.pendingBySession[I.id]?.approvals??0,"question-count":e.pendingBySession[I.id]?.questions??0,unread:e.unreadBySession[I.id]??!1,draggable:S.value!==I.id,onDragstart:$=>E(I.id,$),onRenameStateChange:$=>S.value=$?I.id:null,onSelect:D[9]||(D[9]=$=>s("selectSession",$)),onRename:D[10]||(D[10]=($,B)=>s("renameSession",$,B)),onArchive:D[11]||(D[11]=$=>s("archiveSession",$)),onFork:D[12]||(D[12]=$=>s("forkSession",$)),onExport:D[13]||(D[13]=$=>s("exportSession",$)),onPin:D[14]||(D[14]=$=>s("pinSession",$))},null,8,["session","active","approval-count","question-count","unread","draggable","onDragstart","onRenameStateChange"]))),128)),m.value||v.value?(y(),M("div",Ave,[m.value?(y(),M("button",{key:0,class:"show-more",disabled:e.group.loadingMore,onClick:D[15]||(D[15]=It(I=>s("expand",e.group.workspace.id),["stop"]))},[j(p(Te),{name:"chevron-down",size:"sm"}),C("span",Tve,N(e.group.loadingMore?p(n)("sidebar.loadingMore"):p(n)("sidebar.showMore")),1)],8,Mve)):ee("",!0),m.value&&v.value?(y(),M("span",Eve,"·")):ee("",!0),v.value?(y(),M("button",{key:2,class:"show-more",onClick:D[16]||(D[16]=It(I=>s("collapse",e.group.workspace.id),["stop"]))},[j(p(Te),{name:"chevron-up",size:"sm"}),C("span",Ive,N(p(n)("sidebar.showLess")),1)])):ee("",!0)])):ee("",!0),e.group.sessions.length===0?(y(),M("div",Lve,N(e.group.pinnedCount>0?p(n)("sidebar.allPinned",{count:e.group.pinnedCount}):p(n)("sidebar.noSessions")),1)):ee("",!0)],10,Sve)],34))}}),Nve=ft($ve,[["__scopeId","data-v-9586bfbe"]]),Fve={class:"pinned-label"},Rve={class:"pinned-title"},Ove={key:0,class:"pinned-rows"},Pve=["draggable","onDragstart","onDragover","onDrop"],Dve=et({__name:"PinnedSessionList",props:{sessions:{},activeId:{},pendingBySession:{},unreadBySession:{}},emits:["selectSession","renameSession","archiveSession","forkSession","exportSession","pinSession","pinSessionAt","sessionDragStart","sessionDragEnd","reorder"],setup(e,{expose:t,emit:n}){const{t:o}=Nt(),s=e,i=n,r=Z(kQ());function l(){r.value=!r.value,M3(r.value)}function a(){r.value&&(r.value=!1,M3(!1))}t({expand:a});const u=Z(null),c=Z(null),d=Z(null);function f(x,S){if(!S.dataTransfer)return;S.dataTransfer.effectAllowed="move",S.dataTransfer.setData("text/plain",x),u.value=x;const T=s.sessions.find(A=>A.id===x)?.workspaceId;T!==void 0&&i("sessionDragStart",x,T)}function h(){u.value=null,c.value=null,i("sessionDragEnd")}Je(()=>s.sessions,x=>{u.value!==null&&!x.some(S=>S.id===u.value)&&(u.value=null,c.value=null)});function m(x){const S=x.currentTarget.getBoundingClientRect();return x.clientY<S.top+S.height/2?"before":"after"}function v(x){return x.dataTransfer?.types.includes(Bf)??!1}function k(x,S){u.value!==S&&(u.value===null&&!v(x)||(x.preventDefault(),x.dataTransfer&&(x.dataTransfer.dropEffect="move"),c.value={id:S,position:m(x)}))}function w(x,S){const T=u.value,A=c.value?.id===x?c.value.position:"before";if(c.value=null,u.value=null,T!==null){T!==x&&i("reorder",AE(s.sessions.map(P=>P.id),T,x,A));return}const E=S.dataTransfer?.getData(Bf);E&&i("pinSessionAt",E,x,A)}function b(x){if(u.value===null&&!v(x))return;x.preventDefault(),x.dataTransfer&&(x.dataTransfer.dropEffect="move");const S=s.sessions[s.sessions.length-1];S!==void 0&&(c.value={id:S.id,position:"after"})}function _(x){const S=s.sessions.map(E=>E.id),T=u.value;if(c.value=null,u.value=null,T!==null){const E=S[S.length-1];E!==void 0&&T!==E&&i("reorder",[...S.filter(P=>P!==T),T]);return}const A=x.dataTransfer?.getData(Bf);A&&i("pinSessionAt",A,S[S.length-1]??null,"after")}function g(x){x.currentTarget.contains(x.relatedTarget)||(c.value=null)}return(x,S)=>(y(),M("div",{class:"pinned",onDragover:b,onDrop:_,onDragleave:g},[C("div",Fve,[C("span",Rve,N(p(o)("sidebar.pinned")),1),j(p(gn),{class:Re(["pinned-toggle",{"pinned-toggle--on":r.value}]),size:"sm",label:r.value?p(o)("sidebar.expandPinned"):p(o)("sidebar.collapsePinned"),tooltip:r.value?p(o)("sidebar.expandPinned"):p(o)("sidebar.collapsePinned"),onClick:It(l,["stop"])},{default:me(()=>[r.value?(y(),he(p(Te),{key:0,name:"chevron-right"})):(y(),he(p(Te),{key:1,name:"chevron-down"}))]),_:1},8,["class","label","tooltip"])]),r.value?ee("",!0):(y(),M("div",Ove,[(y(!0),M(Pe,null,pt(e.sessions,T=>(y(),M("div",{key:T.id,class:Re(["pin-drop-target",{dragging:u.value===T.id,"drop-before":c.value?.id===T.id&&c.value.position==="before","drop-after":c.value?.id===T.id&&c.value.position==="after"}]),draggable:d.value!==T.id,onDragstart:A=>f(T.id,A),onDragend:h,onDragover:It(A=>k(A,T.id),["stop"]),onDrop:It(A=>w(T.id,A),["stop"])},[j(Z5,{session:T,active:T.id===e.activeId,"approval-count":e.pendingBySession[T.id]?.approvals??0,"question-count":e.pendingBySession[T.id]?.questions??0,unread:e.unreadBySession[T.id]??!1,onRenameStateChange:A=>d.value=A?T.id:null,onSelect:S[0]||(S[0]=A=>i("selectSession",A)),onRename:S[1]||(S[1]=(A,E)=>i("renameSession",A,E)),onArchive:S[2]||(S[2]=A=>i("archiveSession",A)),onFork:S[3]||(S[3]=A=>i("forkSession",A)),onExport:S[4]||(S[4]=A=>i("exportSession",A)),onPin:S[5]||(S[5]=A=>i("pinSession",A))},null,8,["session","active","approval-count","question-count","unread","onRenameStateChange"])],42,Pve))),128))]))],32))}}),Bve=ft(Dve,[["__scopeId","data-v-aec340eb"]]),Hve={class:"ch"},zve={class:"ch-brand"},Wve={class:"ch-tail"},Uve={class:"search-input"},jve={class:"side-section-label"},Vve={class:"side-section-title"},qve={class:"side-section-actions"},Kve={key:0,class:"empty"},Zve=["onDragover","onDrop"],Gve={key:0,class:"empty"},Yve={key:1,class:"show-more-row"},Xve=["disabled"],Jve={class:"show-more-label"},Qve={class:"folder-drop-card"},e9e={class:"view-menu-label"},t9e={class:"view-menu-check"},n9e={class:"view-menu-check"},o9e=!1,s9e=1e3,i9e=et({__name:"Sidebar",props:{activeWorkspace:{default:null},activeWorkspaceId:{default:null},sessions:{},groups:{},pinnedSessions:{default:()=>[]},flatSessions:{default:()=>[]},flatHasMore:{type:Boolean,default:!1},flatLoadingMore:{type:Boolean,default:!1},initialized:{type:Boolean,default:!1},activeId:{},attentionBySession:{default:()=>({})},pendingBySession:{default:()=>({})},unreadBySession:{default:()=>({})},colWidth:{default:220},collapsed:{type:Boolean,default:!1},dragging:{type:Boolean,default:!1}},emits:["select","create","createInWorkspace","selectWorkspace","addWorkspace","addWorkspacePaths","rename","archive","fork","export","pin","reorderPinned","pinAt","unpin","renameWorkspace","deleteWorkspace","reorderWorkspaces","loadMoreSessions","loadAllSessions","ensureFlatSessions","loadMoreFlatSessions","openSettings","login","collapse"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z(!1),r=c()?["⌘","K"]:["Ctrl","K"],l=c()?["⌃","⇧","O"]:["Ctrl","Shift","O"];function a(){s("loadAllSessions"),i.value=!0}function u(Qe){(Qe.metaKey||Qe.ctrlKey)&&(Qe.key.toLowerCase()==="k"?(Qe.preventDefault(),a()):!Qe.metaKey&&Qe.ctrlKey&&Qe.shiftKey&&Qe.key.toLowerCase()==="o"&&(Qe.preventDefault(),s("create")))}dn(()=>window.addEventListener("keydown",u)),Vn(()=>window.removeEventListener("keydown",u));function c(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const Qe=navigator.userAgentData;return Qe?.platform==="macOS"||Qe?.platform==="iOS"}const d=Z(null),f=Z(!1),h=Z(!1),m=Z(!1);let v=null;function k(Qe=d.value){Qe&&(f.value=Qe.scrollTop>0,h.value=Qe.scrollTop+Qe.clientHeight<Qe.scrollHeight-1)}function w(Qe){k(Qe.target),m.value=!0,v&&clearTimeout(v),v=setTimeout(()=>{m.value=!1,v=null},900)}let b=null;dn(()=>{yt(()=>{k(),typeof ResizeObserver=="function"&&d.value&&(b=new ResizeObserver(()=>k()),b.observe(d.value))})}),Dp(()=>k()),Vn(()=>{b?.disconnect(),v&&clearTimeout(v)});const _=Z(new Set(yQ()));function g(Qe){return _.value.has(Qe)}function x(Qe){const st=new Set(_.value);st.has(Qe)?st.delete(Qe):st.add(Qe),_.value=st,p9(st)}function S(){const Qe=new Set(o.groups.map(st=>st.workspace.id));_.value=Qe,p9(Qe)}function T(){const Qe=new Set;_.value=Qe,p9(Qe)}const A=R(()=>o.groups.length>0&&o.groups.every(Qe=>_.value.has(Qe.workspace.id))),E=Z(new Map);function P(Qe){return E.value.get(Qe)}function D(Qe){const st=o.groups.find(kn=>kn.workspace.id===Qe);if(!st)return;const Ct=(E.value.get(Qe)??st.initialCount)+O5,Qt=new Map(E.value);Qt.set(Qe,Ct),E.value=Qt,st.sessions.length<Ct&&st.hasMore&&s("loadMoreSessions",Qe)}function I(Qe){if(!E.value.has(Qe))return;const st=new Map(E.value);st.delete(Qe),E.value=st}const $=Z(null),B=Z(null);function H(Qe){$.value=Qe}function O(){$.value=null,B.value=null}function F(Qe){const st=Qe.currentTarget.getBoundingClientRect();return Qe.clientY<st.top+st.height/2?"before":"after"}function U(Qe,st){$.value===null||$.value===st||(Qe.preventDefault(),Qe.dataTransfer&&(Qe.dataTransfer.dropEffect="move"),B.value={id:st,position:F(Qe)})}function z(Qe){const st=$.value,Ct=B.value?.id===Qe?B.value.position:"before";if(B.value=null,$.value=null,!st||st===Qe)return;const Qt=AE(o.groups.map(kn=>kn.workspace.id),st,Qe,Ct);s("reorderWorkspaces",Qt)}const W=Z(null);function K(Qe,st){W.value={id:Qe,workspaceId:st}}function V(){W.value=null}function ie(Qe){W.value=null,s("unpin",Qe)}const ne=Z(bQ());function X(Qe){ne.value!==Qe&&(ne.value=Qe,CQ(Qe),Qe==="flat"&&s("ensureFlatSessions"))}Je(()=>o.initialized,Qe=>{Qe&&ne.value==="flat"&&s("ensureFlatSessions")},{immediate:!0});const le=Z(!1),Ie=Z({}),de=Z(null);function pe(Qe){const st=Qe.target;st.closest(".view-menu")||st.closest(".side-section-view")||oe()}async function ve(Qe){if(le.value){oe();return}const st=Qe.currentTarget;le.value=!0,document.addEventListener("mousedown",pe),window.addEventListener("resize",oe),await yt();const Ct=de.value?.el,Qt=st.getBoundingClientRect(),kn=4,Ko=8,Eo=Ct?.offsetHeight??0,bo=Ct?.offsetWidth??0;let Ns=Qt.bottom+kn,Do=!1;Ns+Eo>window.innerHeight-Ko&&(Ns=Math.max(Ko,Qt.top-Eo-kn),Do=!0);let Io=Qt.right-bo;Io<Ko&&(Io=Ko),Ie.value={top:`${Math.round(Ns)}px`,left:`${Math.round(Io)}px`,transformOrigin:Do?"bottom right":"top right","--menu-pop-shift":Do?"2px":"-2px"}}function oe(){le.value=!1,document.removeEventListener("mousedown",pe),window.removeEventListener("resize",oe)}function ye(Qe){X(Qe),oe()}const G=Z(null);function Y(Qe,st){st.dataTransfer&&(st.dataTransfer.effectAllowed="move",st.dataTransfer.setData(Bf,Qe),st.dataTransfer.setData("text/plain",Qe))}const fe=Z(!1);function we(Qe){ne.value!=="flat"||W.value===null||(Qe.preventDefault(),Qe.dataTransfer&&(Qe.dataTransfer.dropEffect="move"),fe.value=!0)}function ge(Qe){ne.value!=="flat"||W.value===null||(Qe.preventDefault(),fe.value=!1,ie(W.value.id))}function Q(Qe){Qe.currentTarget.contains(Qe.relatedTarget)||(fe.value=!1)}function te(Qe,st){st.target.closest(".gh-more, .gh-add")||x(Qe)}function ce(Qe){s("select",Qe)}const ue=Z(null);function Se(Qe){ue.value?ue.value.expand():M3(!1),s("pin",Qe)}function ze(Qe,st,Ct){ue.value?.expand(),s("pinAt",Qe,st,Ct)}const _e=Z(0),Ee=Z(!1);function it(){_e.value=0,Ee.value=!1}function Fe(Qe){!ih()||!c9(Qe)||(Qe.preventDefault(),Qe.stopPropagation(),_e.value+=1,Ee.value=!0)}function Oe(Qe){!ih()||!c9(Qe)||(Qe.preventDefault(),Qe.stopPropagation(),Qe.dataTransfer&&(Qe.dataTransfer.dropEffect="copy"))}function Ge(Qe){!ih()||!c9(Qe)||(_e.value=Math.max(0,_e.value-1),_e.value===0&&(Ee.value=!1))}function at(Qe){if(it(),!ih())return;const st=bJ(Qe);st.length!==0&&(Qe.preventDefault(),Qe.stopPropagation(),s("addWorkspacePaths",st))}const Tt=Z(null),Bt=Z(""),Yt=Z(""),Sn=Z(null);function on(){return Sn}function en(Qe,st){Tt.value=Qe,Yt.value=st,Bt.value=st,yt().then(()=>Sn.value?.focus())}function Cn(){const Qe=Tt.value,st=Bt.value.trim();Qe&&st&&st!==Yt.value&&s("renameWorkspace",Qe,st),Tt.value=null}function Mn(){Tt.value=null}function We(Qe){Bt.value=Qe}const tt=Z(!1),Ue=Z(null),Lt=Z({}),gt=Z(null);function wn(Qe){gt.value?.el&&!gt.value.el.contains(Qe.target)&&go()}function yn(Qe,st){st.preventDefault(),st.stopPropagation(),Ue.value=Qe,Lt.value={top:`${st.clientY}px`,left:`${st.clientX}px`,transformOrigin:"top left","--menu-pop-shift":"-2px"},tt.value=!0,document.addEventListener("mousedown",wn,!0)}function go(){tt.value=!1,document.removeEventListener("mousedown",wn,!0),Ue.value=null}function qt(){Ue.value&&Zs(Ue.value.root),go()}function ps(){Ue.value&&en(Ue.value.id,Ue.value.name),go()}function xs(){const Qe=Ue.value;Qe&&(go(),s("deleteWorkspace",Qe.id))}const _n=Z(null),In=Z(null),To=Z({}),lo=Z(null);function St(Qe){const st=Qe.target;st.closest(".gh-more")||st.closest(".ws-menu")||Jo()}async function hs(Qe,st){if(_n.value===Qe.id){Jo();return}const Ct=st.currentTarget;In.value=Qe,_n.value=Qe.id,document.addEventListener("mousedown",St),window.addEventListener("resize",Jo),await yt();const Qt=lo.value?.el,kn=Ct.getBoundingClientRect(),Ko=4,Eo=8,bo=Qt?.offsetHeight??0,Ns=Qt?.offsetWidth??0;let Do=kn.bottom+Ko,Io=!1;Do+bo>window.innerHeight-Eo&&(Do=Math.max(Eo,kn.top-bo-Ko),Io=!0);let Qo=kn.right-Ns;Qo<Eo&&(Qo=Eo),To.value={top:`${Math.round(Do)}px`,left:`${Math.round(Qo)}px`,transformOrigin:Io?"bottom right":"top right","--menu-pop-shift":Io?"2px":"-2px"}}function Jo(){_n.value=null,In.value=null,document.removeEventListener("mousedown",St),window.removeEventListener("resize",Jo)}function uo(Qe){Zs(Qe.root),Jo()}function Ys(Qe){en(Qe.id,Qe.name),Jo()}function Nn(Qe){Jo(),s("deleteWorkspace",Qe.id)}Vn(()=>{document.removeEventListener("mousedown",wn,!0),document.removeEventListener("mousedown",St),document.removeEventListener("mousedown",pe),window.removeEventListener("resize",Jo),window.removeEventListener("resize",oe)});const no=Z(null);let $s;function Xs(){const Qe=no.value;Qe&&(Qe.classList.remove("blink-now"),Qe.getBoundingClientRect(),Qe.classList.add("blink-now"),clearTimeout($s),$s=setTimeout(()=>Qe.classList.remove("blink-now"),300))}const ci=zr(()=>jo(()=>import("./DesignSystemView-CTUhpkDe.js"),__vite__mapDeps([8,9]))),Oo=Z(!1);let vo,Po=!1;function co(Qe){Po=!1,clearTimeout(vo),Qe.currentTarget.setPointerCapture?.(Qe.pointerId),vo=setTimeout(()=>{Po=!0,Oo.value=!0},s9e)}function Tn(Qe){clearTimeout(vo);const st=Qe.currentTarget;st.hasPointerCapture?.(Qe.pointerId)&&st.releasePointerCapture(Qe.pointerId)}function fo(){if(Po){Po=!1;return}Xs()}return Vn(()=>{clearTimeout(vo)}),(Qe,st)=>(y(),M("aside",{class:Re(["side",{"macos-desktop":p(rc),collapsed:e.collapsed,"no-anim":e.dragging}]),style:Zt({width:e.collapsed?"0px":e.colWidth+"px"})},[C("div",{class:"col",style:Zt({width:e.colWidth+"px"}),onDragenter:Fe,onDragover:Oe,onDragleave:Ge,onDrop:at},[C("div",Hve,[C("div",zve,[p(rc)?ee("",!0):(y(),M(Pe,{key:0},[(y(),M("svg",{ref_key:"logoRef",ref:no,class:"ch-logo",viewBox:"0 0 32 22",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-label":"Kimi Code",onClick:fo,onPointerdown:co,onPointerup:Tn,onPointercancel:Tn},[...st[31]||(st[31]=[iu('<defs data-v-a80a4ba6><mask id="kimiEyes" maskUnits="userSpaceOnUse" data-v-a80a4ba6><rect x="0" y="0" width="32" height="22" fill="#fff" data-v-a80a4ba6></rect><g class="ch-eyes" fill="#000" data-v-a80a4ba6><rect class="ch-eye" x="11.8" y="7" width="2.8" height="8" rx="1.4" data-v-a80a4ba6></rect><rect class="ch-eye" x="17.4" y="7" width="2.8" height="8" rx="1.4" data-v-a80a4ba6></rect></g></mask></defs><rect x="1" y="1" width="30" height="20" rx="6" fill="var(--logo)" mask="url(#kimiEyes)" data-v-a80a4ba6></rect>',2)])],544)),st[32]||(st[32]=C("span",{class:"ch-name"},"Kimi Code",-1))],64))]),C("div",Wve,[p(rc)?ee("",!0):(y(),he(p(gn),{key:0,class:"ch-collapse",size:"sm",label:p(n)("sidebar.collapseSidebar"),tooltip:p(n)("sidebar.collapseSidebar"),onClick:st[0]||(st[0]=It(Ct=>s("collapse"),["stop"]))},{default:me(()=>[j(p(Te),{name:"panel-collapse"})]),_:1},8,["label","tooltip"])),j(b0e)])]),C("div",{class:Re(["sidebar-actions",{"sidebar-actions--has-workspace-action":o9e}])},[C("button",{class:"btn-new-chat",type:"button",onClick:st[1]||(st[1]=It(Ct=>s("create"),["stop"]))},[j(p(Te),{name:"chat-new"}),C("span",null,N(p(n)("sidebar.newChat")),1),j(p(oa),{keys:p(l)},null,8,["keys"])]),ee("",!0),C("button",{class:"search",type:"button",onClick:a},[j(p(Te),{class:"search-icon",name:"search"}),C("span",Uve,N(p(n)("sidebar.search")),1),j(p(oa),{keys:p(r)},null,8,["keys"])])],2),ne.value==="flat"||e.groups.length>0?(y(),M("div",{key:0,class:Re(["sessions-head",{"sessions-head--scrolled":f.value}])},[e.pinnedSessions.length>0?(y(),he(Bve,{key:0,ref_key:"pinnedListRef",ref:ue,sessions:e.pinnedSessions,"active-id":e.activeId,"pending-by-session":e.pendingBySession,"unread-by-session":e.unreadBySession,onSelectSession:ce,onRenameSession:st[3]||(st[3]=(Ct,Qt)=>s("rename",Ct,Qt)),onArchiveSession:st[4]||(st[4]=Ct=>s("archive",Ct)),onForkSession:st[5]||(st[5]=Ct=>s("fork",Ct)),onExportSession:st[6]||(st[6]=Ct=>s("export",Ct)),onPinSession:Se,onPinSessionAt:ze,onSessionDragStart:K,onSessionDragEnd:V,onReorder:st[7]||(st[7]=Ct=>s("reorderPinned",Ct))},null,8,["sessions","active-id","pending-by-session","unread-by-session"])):ee("",!0),C("div",jve,[C("span",Vve,N(p(n)("sidebar.sessionsHeader")),1),C("div",qve,[ne.value==="grouped"?(y(),he(p(gn),{key:0,class:"side-section-toggle",size:"sm",label:A.value?p(n)("sidebar.expandAll"):p(n)("sidebar.collapseAll"),tooltip:A.value?p(n)("sidebar.expandAll"):p(n)("sidebar.collapseAll"),onClick:st[8]||(st[8]=It(Ct=>A.value?T():S(),["stop"]))},{default:me(()=>[A.value?(y(),he(p(Te),{key:0,name:"expand"})):(y(),he(p(Te),{key:1,name:"collapse"}))]),_:1},8,["label","tooltip"])):ee("",!0),j(p(pn),{text:p(n)("sidebar.viewSwitcher")},{default:me(()=>[j(p(gn),{class:"side-section-toggle side-section-view",size:"sm",label:p(n)("sidebar.viewSwitcher"),onClick:It(ve,["stop"])},{default:me(()=>[j(p(Te),{name:"list-settings"})]),_:1},8,["label"])]),_:1},8,["text"])])])],2)):ee("",!0),C("div",{ref_key:"sessionsEl",ref:d,class:Re(["sessions",{scrolling:m.value,"pinned-drag-active":ne.value==="flat"&&W.value!==null,"flat-pinned-drop-hover":fe.value}]),onScroll:w,onDragover:we,onDrop:ge,onDragleave:Q},[ne.value==="grouped"?(y(),M(Pe,{key:0},[e.groups.length===0?(y(),M("div",Kve,N(p(n)("workspace.noWorkspace")),1)):(y(!0),M(Pe,{key:1},pt(e.groups,Ct=>(y(),M("div",{key:Ct.workspace.id,class:Re(["ws-drop-target",{"drop-before":B.value?.id===Ct.workspace.id&&B.value.position==="before","drop-after":B.value?.id===Ct.workspace.id&&B.value.position==="after"}]),onDragover:Qt=>U(Qt,Ct.workspace.id),onDrop:Qt=>z(Ct.workspace.id)},[j(Nve,{group:Ct,"active-workspace-id":e.activeWorkspaceId,"active-id":e.activeId,"renaming-id":Tt.value,"rename-value":Bt.value,"rename-input-ref":on(),"pending-by-session":e.pendingBySession,"unread-by-session":e.unreadBySession,"ws-menu-open-id":_n.value,dragging:$.value===Ct.workspace.id,"is-collapsed":g,"visible-limit":P,"pinned-drag-session":W.value,onGroupClick:te,onGroupContextmenu:yn,onToggleWsMenu:hs,onCreateInWorkspace:st[9]||(st[9]=Qt=>s("createInWorkspace",Qt)),onSelectSession:ce,onRenameSession:st[10]||(st[10]=(Qt,kn)=>s("rename",Qt,kn)),onArchiveSession:st[11]||(st[11]=Qt=>s("archive",Qt)),onForkSession:st[12]||(st[12]=Qt=>s("fork",Qt)),onExportSession:st[13]||(st[13]=Qt=>s("export",Qt)),onPinSession:Se,onDropPinnedSession:ie,onExpand:D,onCollapse:I,onConfirmRename:Cn,onCancelRename:Mn,onUpdateRenameValue:We,onWsDragstart:H,onWsDragend:O},null,8,["group","active-workspace-id","active-id","renaming-id","rename-value","rename-input-ref","pending-by-session","unread-by-session","ws-menu-open-id","dragging","pinned-drag-session"])],42,Zve))),128))],64)):(y(),M(Pe,{key:1},[(y(!0),M(Pe,null,pt(e.flatSessions,Ct=>(y(),he(Z5,{key:Ct.id,session:Ct,active:Ct.id===e.activeId,"approval-count":e.pendingBySession[Ct.id]?.approvals??0,"question-count":e.pendingBySession[Ct.id]?.questions??0,unread:e.unreadBySession[Ct.id]??!1,draggable:G.value!==Ct.id,onDragstart:Qt=>Y(Ct.id,Qt),onRenameStateChange:Qt=>G.value=Qt?Ct.id:null,onSelect:ce,onRename:st[14]||(st[14]=(Qt,kn)=>s("rename",Qt,kn)),onArchive:st[15]||(st[15]=Qt=>s("archive",Qt)),onFork:st[16]||(st[16]=Qt=>s("fork",Qt)),onExport:st[17]||(st[17]=Qt=>s("export",Qt)),onPin:Se},null,8,["session","active","approval-count","question-count","unread","draggable","onDragstart","onRenameStateChange"]))),128)),e.flatSessions.length===0&&!e.flatHasMore&&e.pinnedSessions.length===0?(y(),M("div",Gve,N(p(n)("sidebar.noSessions")),1)):ee("",!0),e.flatHasMore?(y(),M("div",Yve,[C("button",{class:"show-more",disabled:e.flatLoadingMore,onClick:st[18]||(st[18]=It(Ct=>s("loadMoreFlatSessions"),["stop"]))},[C("span",Jve,N(e.flatLoadingMore?p(n)("sidebar.loadingMore"):p(n)("sidebar.loadMore")),1),j(p(Te),{name:"chevron-down",size:"sm"})],8,Xve)])):ee("",!0)],64))],34),C("div",{class:Re(["side-footer",{"side-footer--shadowed":h.value}])},[j(V2e,{onLogin:st[19]||(st[19]=Ct=>s("login")),onOpenSettings:st[20]||(st[20]=Ct=>s("openSettings"))})],2),C("div",{class:Re(["folder-drop-overlay",{show:Ee.value}]),"aria-hidden":"true"},[C("div",Qve,[j(p(Te),{name:"folder",size:"lg"}),C("span",null,N(p(n)("sidebar.dropToAddWorkspace")),1)])],2)],36),j(as,{name:"menu-pop"},{default:me(()=>[tt.value?(y(),he(p(Cl),{key:0,ref_key:"ghMenuRef",ref:gt,class:"gh-menu",style:Zt(Lt.value),onClick:st[21]||(st[21]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{onClick:qt},{default:me(()=>[j(p(Te),{name:"copy",size:"sm"}),qe(" "+N(p(n)("sidebar.copyPath")),1)]),_:1}),j(p(hn),{class:"workspace-rename-item",onClick:ps},{default:me(()=>[j(p(Te),{name:"pencil",size:"sm"}),qe(" "+N(p(n)("sidebar.rename")),1)]),_:1}),j(p(hn),{danger:"",onClick:xs},{default:me(()=>[j(p(Te),{name:"close",size:"sm"}),qe(" "+N(p(n)("sidebar.removeWorkspace")),1)]),_:1})]),_:1},8,["style"])):ee("",!0)]),_:1}),j(as,{name:"menu-pop"},{default:me(()=>[_n.value!==null&&In.value?(y(),he(p(Cl),{key:0,ref_key:"wsMenuRef",ref:lo,class:"ws-menu",style:Zt(To.value),onClick:st[25]||(st[25]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{onClick:st[22]||(st[22]=Ct=>uo(In.value))},{default:me(()=>[j(p(Te),{name:"copy",size:"sm"}),qe(" "+N(p(n)("sidebar.copyPath")),1)]),_:1}),j(p(hn),{class:"workspace-rename-item",onClick:st[23]||(st[23]=Ct=>Ys(In.value))},{default:me(()=>[j(p(Te),{name:"pencil",size:"sm"}),qe(" "+N(p(n)("sidebar.rename")),1)]),_:1}),j(p(hn),{danger:"",onClick:st[24]||(st[24]=Ct=>Nn(In.value))},{default:me(()=>[j(p(Te),{name:"close",size:"sm"}),qe(" "+N(p(n)("sidebar.removeWorkspace")),1)]),_:1})]),_:1},8,["style"])):ee("",!0)]),_:1}),j(as,{name:"menu-pop"},{default:me(()=>[le.value?(y(),he(p(Cl),{key:0,ref_key:"viewMenuRef",ref:de,class:"view-menu",style:Zt(Ie.value),onClick:st[28]||(st[28]=It(()=>{},["stop"]))},{default:me(()=>[C("div",e9e,N(p(n)("sidebar.viewGroup")),1),j(p(hn),{onClick:st[26]||(st[26]=Ct=>ye("flat"))},{default:me(()=>[j(p(Te),{name:"list",size:"sm"}),qe(" "+N(p(n)("sidebar.viewFlat"))+" ",1),C("span",t9e,[ne.value==="flat"?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)])]),_:1}),j(p(hn),{onClick:st[27]||(st[27]=Ct=>ye("grouped"))},{default:me(()=>[j(p(Te),{name:"tree-view",size:"sm"}),qe(" "+N(p(n)("sidebar.viewGrouped"))+" ",1),C("span",n9e,[ne.value==="grouped"?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)])]),_:1})]),_:1},8,["style"])):ee("",!0)]),_:1}),i.value?(y(),he(uee,{key:0,sessions:e.sessions,"active-id":e.activeId,onSelect:ce,onClose:st[29]||(st[29]=Ct=>i.value=!1)},null,8,["sessions","active-id"])):ee("",!0),(y(),he(Zr,{to:"body"},[Oo.value?(y(),he(p(ci),{key:0,onClose:st[30]||(st[30]=Ct=>Oo.value=!1)})):ee("",!0)]))],6))}}),r9e=ft(i9e,[["__scopeId","data-v-a80a4ba6"]]),l9e=["aria-label"],a9e=et({__name:"ResizeHandle",props:{storageKey:{},defaultWidth:{},min:{},max:{},reverse:{type:Boolean},ariaLabel:{},applyLive:{}},emits:["update:width","update:dragging"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),{width:i,dragging:r,cursor:l,onPointerDown:a}=She({storageKey:n.storageKey,defaultWidth:n.defaultWidth,min:n.min,max:()=>n.max,reverse:n.reverse,applyLive:n.applyLive});return o("update:width",i.value),Je(i,u=>o("update:width",u)),Je(r,u=>o("update:dragging",u)),(u,c)=>(y(),M("div",{class:Re(["rh",{dragging:p(r)}]),style:Zt({cursor:p(l)}),role:"separator","aria-orientation":"vertical","aria-label":e.ariaLabel??p(s)("layout.resizeHandleAria"),onPointerdown:c[0]||(c[0]=(...d)=>p(a)&&p(a)(...d))},[...c[1]||(c[1]=[C("span",{class:"rh-bar","aria-hidden":"true"},null,-1)])],46,l9e))}}),Zx=ft(a9e,[["__scopeId","data-v-1c6dfdc5"]]),u9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function c9e(e,t){return y(),M("svg",u9e,[...t[0]||(t[0]=[C("path",{d:"M12.0684 2.03418C12.5654 2.03421 12.9687 2.43755 12.9688 2.93457V11.0996H21.0654C21.5625 11.0996 21.9658 11.503 21.9658 12C21.9658 12.497 21.5625 12.9004 21.0654 12.9004H12.9688V21.0654C12.9687 21.5624 12.5654 21.9658 12.0684 21.9658C11.5713 21.9658 11.168 21.5625 11.168 21.0654V12.9004H2.93457C2.43751 12.9004 2.03418 12.4971 2.03418 12C2.03418 11.5029 2.43751 11.0996 2.93457 11.0996H11.168V2.93457C11.168 2.43753 11.5713 2.03418 12.0684 2.03418Z",fill:"currentColor"},null,-1)])])}const d9e=kt({name:"kimi-add",render:c9e}),f9e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function p9e(e,t){return y(),M("svg",f9e,[...t[0]||(t[0]=[C("path",{id:"p0",d:"M 0 -9.9 C -5.468 -9.9 -9.9 -5.468 -9.9 0 C -9.9 1.923 -9.351 3.719 -8.402 5.239 C -8.402 5.239 -9.483 7.821 -9.483 7.821 C -9.896 8.809 -9.171 9.9 -8.099 9.9 C -8.099 9.9 0 9.9 0 9.9 C 5.468 9.9 9.9 5.468 9.9 0 C 9.9 -5.468 5.468 -9.9 0 -9.9 Z M -8.1 0 C -8.1 -4.474 -4.474 -8.1 0 -8.1 C 4.473 -8.1 8.1 -4.474 8.1 0 C 8.1 4.473 4.473 8.1 -0.001 8.1 C -0.001 8.1 -7.648 8.1 -7.648 8.1 L -6.365 5.035 C -6.365 5.035 -6.648 4.629 -6.648 4.629 C -7.563 3.317 -8.1 1.723 -8.1 0 Z",transform:"matrix(1 0 0 1 12 12)",fill:"currentColor","fill-rule":"evenodd"},null,-1),C("path",{id:"p1",d:"M 3.6 0.5 L -2.6 0.5 M 0.5 -2.573 L 0.5 3.573",transform:"translate(11.5 11.5)",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round"},null,-1)])])}const h9e=kt({name:"kimi-add-conversation",render:p9e}),m9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function g9e(e,t){return y(),M("svg",m9e,[...t[0]||(t[0]=[C("path",{d:"M15.0996 12C15.5967 12 16 12.4033 16 12.9004C15.9998 13.3973 15.5965 13.7998 15.0996 13.7998H8.90039C8.40346 13.7998 8.00021 13.3973 8 12.9004C8 12.4033 8.40333 12 8.90039 12H15.0996Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M19 3.2002C20.5464 3.2002 21.7998 4.4536 21.7998 6V7C21.7998 8.03565 21.2363 8.93754 20.4004 9.42188V17C20.4004 19.1539 18.6539 20.9004 16.5 20.9004H7.5C5.34609 20.9004 3.59961 19.1539 3.59961 17V9.42188C2.76374 8.93754 2.2002 8.03565 2.2002 7V6C2.2002 4.4536 3.4536 3.2002 5 3.2002H19ZM5.40039 17C5.40039 18.1598 6.3402 19.0996 7.5 19.0996H16.5C17.6598 19.0996 18.5996 18.1598 18.5996 17V9.7998H5.40039V17ZM4.89746 5.00488C4.39333 5.05621 4 5.48232 4 6V7L4.00488 7.10254C4.05278 7.57297 4.42703 7.94722 4.89746 7.99512L5 8H19C19.5523 8 20 7.55228 20 7V6C20 5.44772 19.5523 5 19 5H5L4.89746 5.00488Z",fill:"currentColor"},null,-1)])])}const v9e=kt({name:"kimi-archive",render:g9e}),y9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function k9e(e,t){return y(),M("svg",y9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.386 21.6387C11.7378 21.988 12.3059 21.987 12.6565 21.6364L18.1949 16.098C18.5464 15.7465 18.5464 15.1766 18.1949 14.8252C17.8434 14.4737 17.2736 14.4737 16.9221 14.8252L12.9201 18.8272V3.00002C12.9201 2.50297 12.5171 2.10003 12.0201 2.10003C11.523 2.10003 11.1201 2.50297 11.1201 3.00002V18.8383L7.07554 14.8229C6.7228 14.4727 6.15295 14.4747 5.80275 14.8275C5.45255 15.1802 5.45461 15.7501 5.80735 16.1003L11.386 21.6387Z",fill:"currentColor"},null,-1)])])}const b9e=kt({name:"kimi-arrow-down",render:k9e}),C9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function w9e(e,t){return y(),M("svg",C9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.16127 12.814C1.81197 12.4622 1.81299 11.8941 2.16357 11.5435L7.70203 6.00506C8.0535 5.65359 8.62335 5.65359 8.97482 6.00506C9.32629 6.35653 9.32629 6.92638 8.97482 7.27785L4.97276 11.2799H20.8C21.297 11.2799 21.7 11.6829 21.7 12.1799C21.7 12.677 21.297 13.0799 20.8 13.0799H4.96171L8.97712 17.1244C9.32732 17.4772 9.32526 18.047 8.97252 18.3972C8.61978 18.7474 8.04993 18.7454 7.69973 18.3926L2.16127 12.814Z",fill:"currentColor"},null,-1)])])}const _9e=kt({name:"kimi-arrow-left",render:w9e}),x9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function S9e(e,t){return y(),M("svg",x9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M21.4387 12.814C21.788 12.4622 21.787 11.8941 21.4364 11.5436L15.8979 6.0051C15.5464 5.65363 14.9766 5.65363 14.6251 6.0051C14.2737 6.35657 14.2737 6.92642 14.6251 7.27789L18.6272 11.28H2.79998C2.30293 11.28 1.89998 11.6829 1.89998 12.18C1.89998 12.677 2.30293 13.08 2.79998 13.08H18.6382L14.6228 17.1245C14.2726 17.4772 14.2747 18.0471 14.6274 18.3973C14.9802 18.7475 15.55 18.7454 15.9002 18.3927L21.4387 12.814Z",fill:"currentColor"},null,-1)])])}const A9e=kt({name:"kimi-arrow-right",render:S9e}),M9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function T9e(e,t){return y(),M("svg",M9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.386 2.36129C11.7378 2.01198 12.3059 2.013 12.6565 2.36358L18.1949 7.90204C18.5464 8.25351 18.5464 8.82336 18.1949 9.17483C17.8434 9.52631 17.2736 9.52631 16.9221 9.17483L12.9201 5.17277V21C12.9201 21.497 12.5171 21.9 12.0201 21.9C11.523 21.9 11.1201 21.497 11.1201 21V5.16172L7.07554 9.17713C6.7228 9.52733 6.15295 9.52527 5.80275 9.17253C5.45255 8.81979 5.45461 8.24995 5.80735 7.89975L11.386 2.36129Z",fill:"currentColor"},null,-1)])])}const E9e=kt({name:"kimi-arrow-up",render:T9e}),I9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function L9e(e,t){return y(),M("svg",I9e,[...t[0]||(t[0]=[C("path",{d:"M19.3027 5.9053C19.6542 5.55397 20.2247 5.55388 20.5761 5.9053C20.9273 6.25675 20.9273 6.82734 20.5761 7.17874L9.65911 18.0948C9.30773 18.4461 8.73814 18.446 8.38665 18.0948L3.42376 13.1328C3.0726 12.7814 3.07263 12.2118 3.42376 11.8604C3.77524 11.509 4.34575 11.5089 4.6972 11.8604L9.02239 16.1856L19.3027 5.9053Z",fill:"currentColor"},null,-1)])])}const $9e=kt({name:"kimi-check",render:L9e}),N9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function F9e(e,t){return y(),M("svg",N9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.3912 16.7134C11.743 17.0627 12.3111 17.0617 12.6617 16.7111L19.6364 9.73641C19.9878 9.38494 19.9878 8.81509 19.6364 8.46362C19.2849 8.11215 18.7151 8.11215 18.3636 8.46362L12.023 14.8042L5.63407 8.46132C5.28133 8.11112 4.71149 8.11318 4.36129 8.46592C4.01109 8.81866 4.01314 9.3885 4.36588 9.73871L11.3912 16.7134Z",fill:"currentColor"},null,-1)])])}const R9e=kt({name:"kimi-chevron-down",render:F9e}),O9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function P9e(e,t){return y(),M("svg",O9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M16.1261 12.6088C16.4754 12.257 16.4743 11.6889 16.1238 11.3383L9.14904 4.36363C8.79757 4.01216 8.22772 4.01216 7.87625 4.36363C7.52477 4.7151 7.52477 5.28495 7.87625 5.63642L14.2169 11.977L7.87395 18.3659C7.52375 18.7187 7.52581 19.2885 7.87855 19.6387C8.23129 19.9889 8.80113 19.9869 9.15133 19.6341L16.1261 12.6088Z",fill:"currentColor"},null,-1)])])}const D9e=kt({name:"kimi-chevron-right",render:P9e}),B9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function H9e(e,t){return y(),M("svg",B9e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.3912 8.46132C11.743 8.11202 12.3111 8.11304 12.6617 8.46362L19.6364 15.4383C19.9878 15.7898 19.9878 16.3597 19.6364 16.7111C19.2849 17.0626 18.7151 17.0626 18.3636 16.7111L12.023 10.3705L5.63407 16.7134C5.28133 17.0636 4.71149 17.0616 4.36129 16.7088C4.01109 16.3561 4.01314 15.7862 4.36588 15.436L11.3912 8.46132Z",fill:"currentColor"},null,-1)])])}const z9e=kt({name:"kimi-chevron-up",render:H9e}),W9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function U9e(e,t){return y(),M("svg",W9e,[...t[0]||(t[0]=[C("path",{d:"M11.8999 6.79965C12.397 6.79965 12.7997 7.20235 12.7997 7.69941V11.7266L14.7359 13.6629C15.0873 14.0143 15.0879 14.584 14.7366 14.9355C14.3852 15.287 13.8148 15.287 13.4633 14.9355L11.2632 12.7355C11.0947 12.5668 11.0002 12.338 11.0001 12.0995V7.69941C11.0001 7.20238 11.4029 6.7997 11.8999 6.79965Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 1.89893C17.4677 1.89893 21.9001 6.33147 21.9002 11.7991C21.9002 17.2669 17.4678 21.6993 12 21.6993C6.53228 21.6993 2.09985 17.2669 2.09985 11.7991C2.09998 6.33147 6.53236 1.89893 12 1.89893ZM20.1 11.7998C20.1 7.32616 16.4737 3.69984 12 3.69984C7.5264 3.69984 3.90008 7.32616 3.90008 11.7998C3.90032 16.2732 7.52655 19.8998 12 19.8998C16.4735 19.8998 20.0998 16.2732 20.1 11.7998Z",fill:"currentColor"},null,-1)])])}const j9e=kt({name:"kimi-clock",render:U9e}),V9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function q9e(e,t){return y(),M("svg",V9e,[...t[0]||(t[0]=[C("path",{d:"M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z",fill:"currentColor"},null,-1)])])}const K9e=kt({name:"kimi-close",render:q9e}),Z9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function G9e(e,t){return y(),M("svg",Z9e,[...t[0]||(t[0]=[C("path",{d:"M9.85815 11.957C10.9074 11.957 11.7583 12.8083 11.7585 13.8574V19.8574C11.7585 20.3545 11.3552 20.7578 10.8582 20.7578C10.3611 20.7578 9.95776 20.3545 9.95776 19.8574V13.8574C9.95755 13.8024 9.91325 13.7578 9.85815 13.7578H3.85815C3.3611 13.7578 2.95776 13.3545 2.95776 12.8574C2.95798 12.3605 3.36123 11.957 3.85815 11.957H9.85815Z",fill:"currentColor"},null,-1),C("path",{d:"M12.8582 2.95703C13.3551 2.95703 13.7583 3.36054 13.7585 3.85742V9.85742C13.7585 9.91265 13.8029 9.95703 13.8582 9.95703H19.8582C20.3551 9.95703 20.7583 10.3605 20.7585 10.8574C20.7585 11.3545 20.3552 11.7578 19.8582 11.7578H13.8582C12.8088 11.7578 11.9578 10.9068 11.9578 9.85742V3.85742C11.958 3.36054 12.3612 2.95703 12.8582 2.95703Z",fill:"currentColor"},null,-1)])])}const Y9e=kt({name:"kimi-collapse",render:G9e}),X9e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function J9e(e,t){return y(),M("svg",X9e,[...t[0]||(t[0]=[C("path",{d:"M11.9004 2.19995C17.3678 2.20016 21.7998 6.63285 21.7998 12.1003C21.7996 17.5677 17.3677 21.9995 11.9004 21.9998H3.80078C2.72946 21.9996 2.00334 20.9089 2.41699 19.9207L3.49805 17.3386C2.54871 15.8189 2.00007 14.0226 2 12.1003C2 6.63272 6.43277 2.19995 11.9004 2.19995ZM11.9004 3.99976C7.42688 3.99976 3.7998 7.62684 3.7998 12.1003C3.79989 13.8228 4.33669 15.4175 5.25195 16.7292L5.53516 17.1345L4.25195 20.2H11.8994C16.3727 20.1999 19.9998 16.5736 20 12.1003C20 7.62697 16.3737 3.99997 11.9004 3.99976ZM8.9541 10.8005C9.75473 10.8006 10.4041 11.4491 10.4043 12.2498C10.4043 13.0505 9.75482 13.6998 8.9541 13.7C8.15329 13.7 7.50391 13.0506 7.50391 12.2498C7.50406 11.4491 8.15339 10.8005 8.9541 10.8005ZM15.1533 10.8005C15.9539 10.8006 16.6034 11.4491 16.6035 12.2498C16.6035 13.0505 15.954 13.6998 15.1533 13.7C14.3525 13.7 13.7031 13.0506 13.7031 12.2498C13.7033 11.4491 14.3526 10.8005 15.1533 10.8005Z",fill:"currentColor"},null,-1)])])}const Q9e=kt({name:"kimi-comment",render:J9e}),e4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function t4e(e,t){return y(),M("svg",e4e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17 7.09961C19.1539 7.09961 20.9004 8.84609 20.9004 11V17C20.9004 19.1539 19.1539 20.9004 17 20.9004H11C8.84609 20.9004 7.09961 19.1539 7.09961 17V11C7.09961 8.84609 8.84609 7.09961 11 7.09961H17ZM11 8.90039C9.8402 8.90039 8.90039 9.8402 8.90039 11V17C8.90039 18.1598 9.8402 19.0996 11 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V11C19.0996 9.8402 18.1598 8.90039 17 8.90039H11Z",fill:"currentColor"},null,-1),C("path",{d:"M13 3.09961C14.4447 3.09961 15.705 3.88644 16.3779 5.0498C16.6265 5.47999 16.4789 6.03049 16.0488 6.2793C15.6186 6.52781 15.0681 6.38029 14.8193 5.9502C14.4548 5.32041 13.776 4.90039 13 4.90039H7C5.8402 4.90039 4.90039 5.8402 4.90039 7V13C4.90039 13.776 5.32041 14.4548 5.9502 14.8193C6.38029 15.0681 6.52781 15.6186 6.2793 16.0488C6.03049 16.4789 5.47999 16.6265 5.0498 16.3779C3.88644 15.705 3.09961 14.4447 3.09961 13V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H13Z",fill:"currentColor"},null,-1)])])}const n4e=kt({name:"kimi-copy",render:t4e}),o4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function s4e(e,t){return y(),M("svg",o4e,[...t[0]||(t[0]=[C("path",{d:"M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 10.2797 2.43414 8.66074 3.19922 7.24707C3.20172 7.24246 3.20453 7.23801 3.20703 7.2334C3.33385 6.99995 3.47181 6.77351 3.61621 6.55176C3.73214 6.37355 3.85079 6.19744 3.97754 6.02734C5.35905 4.17471 7.36856 2.81959 9.68945 2.27051C9.69952 2.26813 9.70965 2.26602 9.71973 2.26367C9.85224 2.23276 9.98563 2.2043 10.1201 2.17871C10.1542 2.17221 10.1884 2.16631 10.2227 2.16016C10.3466 2.13791 10.4712 2.11724 10.5967 2.09961C10.6301 2.09489 10.6637 2.0913 10.6973 2.08691C10.8216 2.07073 10.9465 2.05552 11.0723 2.04395C11.1125 2.04022 11.153 2.0384 11.1934 2.03516C11.4595 2.0139 11.7284 2 12 2ZM11.9941 3.7998C11.9968 3.86623 12 3.93292 12 4C12 6.76142 9.76142 9 7 9C6.14209 9 5.33517 8.78324 4.62988 8.40234C4.09862 9.48861 3.7998 10.7093 3.7998 12C3.7998 12.4438 3.83644 12.8791 3.9043 13.3037C4.52807 12.5673 5.45945 12.0996 6.5 12.0996C8.37777 12.0996 9.90039 13.6222 9.90039 15.5C9.90039 17.0702 8.83532 18.3903 7.38867 18.7812C8.70267 19.6765 10.2901 20.2002 12 20.2002C12.468 20.2002 12.9264 20.1583 13.373 20.083C13.1323 19.4342 13 18.7327 13 18C13 14.6863 15.6863 12 19 12C19.4098 12 19.8098 12.0416 20.1963 12.1201C20.1969 12.0801 20.2002 12.0401 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998H11.9941ZM19 13.7998C16.6804 13.7998 14.7998 15.6804 14.7998 18C14.7998 18.5617 14.9112 19.0972 15.1113 19.5869C17.5225 18.597 19.3558 16.4929 19.9727 13.9141C19.6605 13.8399 19.3349 13.7998 19 13.7998ZM6.5 13.9004C5.61634 13.9004 4.90039 14.6163 4.90039 15.5C4.90039 16.3837 5.61634 17.0996 6.5 17.0996C7.38366 17.0996 8.09961 16.3837 8.09961 15.5C8.09961 14.6163 7.38366 13.9004 6.5 13.9004ZM15.5 6.09961C16.8255 6.09961 17.9004 7.17452 17.9004 8.5C17.9004 9.82548 16.8255 10.9004 15.5 10.9004C14.1745 10.9004 13.0996 9.82548 13.0996 8.5C13.0996 7.17452 14.1745 6.09961 15.5 6.09961ZM15.5 7.90039C15.1686 7.90039 14.9004 8.16863 14.9004 8.5C14.9004 8.83137 15.1686 9.09961 15.5 9.09961C15.8314 9.09961 16.0996 8.83137 16.0996 8.5C16.0996 8.16863 15.8314 7.90039 15.5 7.90039ZM10.1992 4C8.35326 4.41375 6.74333 5.44923 5.59961 6.87598C6.02235 7.08306 6.49716 7.2002 7 7.2002C8.76731 7.2002 10.1992 5.76731 10.1992 4Z",fill:"currentColor"},null,-1)])])}const i4e=kt({name:"kimi-dark-mode",render:s4e}),r4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function l4e(e,t){return y(),M("svg",r4e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2.90002C12.4971 2.90002 12.9 3.30297 12.9 3.80002V12.2939L15.8081 9.38585C16.1595 9.03438 16.7294 9.03438 17.0808 9.38585C17.4323 9.73732 17.4323 10.3072 17.0808 10.6586L12.6364 15.1031C12.4676 15.2719 12.2387 15.3667 12 15.3667C11.7613 15.3667 11.5324 15.2719 11.3636 15.1031L6.91917 10.6586C6.5677 10.3072 6.5677 9.73732 6.91917 9.38585C7.27064 9.03438 7.84049 9.03438 8.19196 9.38585L11.1 12.2939V3.80002C11.1 3.30297 11.503 2.90002 12 2.90002ZM4.00001 13.5874C4.49706 13.5874 4.90001 13.9903 4.90001 14.4874V18.043C4.90001 18.2758 4.99249 18.499 5.1571 18.6636C5.32172 18.8282 5.54498 18.9207 5.77778 18.9207H18.2222C18.455 18.9207 18.6783 18.8283 18.8429 18.6636C19.0075 18.499 19.1 18.2758 19.1 18.043V14.4874C19.1 13.9903 19.5029 13.5874 20 13.5874C20.4971 13.5874 20.9 13.9903 20.9 14.4874V18.043C20.9 18.7531 20.6179 19.4342 20.1157 19.9364C19.6135 20.4386 18.9324 20.7207 18.2222 20.7207H5.77778C5.06759 20.7207 4.38649 20.4386 3.88431 19.9364C3.38213 19.4342 3.10001 18.7531 3.10001 18.043V14.4874C3.10001 13.9903 3.50295 13.5874 4.00001 13.5874Z",fill:"currentColor"},null,-1)])])}const a4e=kt({name:"kimi-download",render:l4e}),u4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function c4e(e,t){return y(),M("svg",u4e,[...t[0]||(t[0]=[C("path",{d:"M18.0179 3.09998C18.3963 3.10003 18.7709 3.17491 19.1205 3.31971C19.4701 3.46454 19.7884 3.67614 20.056 3.94373C20.3237 4.21144 20.5362 4.52965 20.681 4.87928C20.8258 5.22887 20.8997 5.60423 20.8997 5.9828C20.8997 6.36118 20.8257 6.73591 20.681 7.08533C20.5362 7.43497 20.3237 7.75317 20.056 8.02088L17.639 10.4379L9.15756 18.9183C8.5296 19.5463 7.74274 19.992 6.8812 20.2074L4.21811 20.8734C3.91148 20.95 3.5871 20.8596 3.36362 20.6361C3.14017 20.4126 3.05063 20.0883 3.12729 19.7816L3.79233 17.1185C4.00771 16.257 4.45344 15.4701 5.08139 14.8422L15.9798 3.94373C16.5203 3.40346 17.2536 3.09998 18.0179 3.09998ZM19.0003 19.1C19.4972 19.1002 19.8997 19.5034 19.8997 20.0004C19.8995 20.4971 19.4971 20.8996 19.0003 20.8998H12.0003C11.5034 20.8998 11.1001 20.4973 11.0999 20.0004C11.0999 19.5033 11.5033 19.1 12.0003 19.1H19.0003ZM18.0179 4.89979C17.7309 4.89979 17.4553 5.01417 17.2523 5.21717L6.35385 16.1146C5.95661 16.5119 5.67469 17.01 5.53842 17.5551L5.23666 18.7631L6.44467 18.4613C6.98971 18.3251 7.48782 18.0431 7.8851 17.6459L18.7826 6.74744C18.883 6.64702 18.9635 6.52821 19.0179 6.39686C19.0723 6.26558 19.0999 6.1247 19.0999 5.9828C19.0999 5.84075 19.0723 5.69916 19.0179 5.56776C18.9635 5.43645 18.883 5.31757 18.7826 5.21717C18.6821 5.11678 18.5631 5.03716 18.432 4.9828C18.3008 4.92845 18.16 4.89983 18.0179 4.89979Z",fill:"currentColor"},null,-1)])])}const d4e=kt({name:"kimi-edit",render:c4e}),f4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function p4e(e,t){return y(),M("svg",f4e,[...t[0]||(t[0]=[C("path",{d:"M5 11.0996C5.49693 11.0996 5.90018 11.5031 5.90039 12V18C5.90039 18.0552 5.94477 18.0996 6 18.0996H12C12.4969 18.0996 12.9002 18.5031 12.9004 19C12.9004 19.4971 12.4971 19.9004 12 19.9004H6C4.95066 19.9004 4.09961 19.0493 4.09961 18V12C4.09982 11.5031 4.50307 11.0996 5 11.0996ZM18 4.09961C19.0492 4.09961 19.9002 4.95084 19.9004 6V12C19.9004 12.4971 19.4971 12.9004 19 12.9004C18.5029 12.9004 18.0996 12.4971 18.0996 12V6C18.0994 5.94495 18.0551 5.90039 18 5.90039H12C11.5029 5.90039 11.0996 5.49706 11.0996 5C11.0998 4.50312 11.5031 4.09961 12 4.09961H18Z",fill:"currentColor"},null,-1)])])}const h4e=kt({name:"kimi-expand",render:p4e}),m4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function g4e(e,t){return y(),M("svg",m4e,[...t[0]||(t[0]=[C("g",null,[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M13.1723 2.1001C13.9413 2.10018 14.6793 2.40592 15.2231 2.94971L19.0512 6.77783C19.595 7.32162 19.9007 8.0596 19.9008 8.82861V18.0005C19.9008 20.1544 18.1543 21.9009 16.0004 21.9009H8.0004C5.84649 21.9009 4.10001 20.1544 4.10001 18.0005V6.00049C4.10001 3.84658 5.84649 2.1001 8.0004 2.1001H13.1723ZM8.0004 3.90088C6.8406 3.90088 5.90079 4.84069 5.90079 6.00049V18.0005C5.90079 19.1603 6.8406 20.1001 8.0004 20.1001H16.0004C17.1602 20.1001 18.1 19.1603 18.1 18.0005V9.90088H15.0004C13.3988 9.90088 12.1 8.60211 12.1 7.00049V3.90088H8.0004ZM13.9008 7.00049C13.9008 7.608 14.3929 8.1001 15.0004 8.1001H17.8217C17.8072 8.08375 17.7933 8.06681 17.7777 8.05127L13.9496 4.22314C13.9339 4.20745 13.9173 4.19286 13.9008 4.17822V7.00049Z",fill:"currentColor"})],-1)])])}const Gx=kt({name:"kimi-file",render:g4e}),v4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function y4e(e,t){return y(),M("svg",v4e,[...t[0]||(t[0]=[C("path",{d:"M15.4795 15.4971C15.9765 15.4971 16.3799 15.9004 16.3799 16.3975C16.3799 16.8945 15.9765 17.2978 15.4795 17.2979H8.52051C8.02345 17.2979 7.62012 16.8945 7.62012 16.3975C7.62012 15.9004 8.02345 15.4971 8.52051 15.4971H15.4795Z",fill:"currentColor"},null,-1),C("path",{d:"M12.3359 11.0996C12.8329 11.0997 13.2354 11.503 13.2354 12C13.2354 12.497 12.8329 12.9003 12.3359 12.9004H8.52051C8.02345 12.9004 7.62012 12.4971 7.62012 12C7.62012 11.5029 8.02345 11.0996 8.52051 11.0996H12.3359Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M13.1719 2.09961C13.9408 2.09969 14.6789 2.40555 15.2227 2.94922L19.0508 6.77734C19.5946 7.32113 19.9003 8.05911 19.9004 8.82812V18C19.9004 20.1539 18.1539 21.9004 16 21.9004H8C5.84626 21.9002 4.09961 20.1538 4.09961 18V6C4.09961 3.84621 5.84626 2.09981 8 2.09961H13.1719ZM8 3.90039C6.84037 3.90059 5.90039 4.84032 5.90039 6V18C5.90039 19.1597 6.84037 20.0994 8 20.0996H16C17.1598 20.0996 18.0996 19.1598 18.0996 18V9.90039H15C13.3985 9.90019 12.0996 8.6015 12.0996 7V3.90039H8ZM13.9004 7C13.9004 7.60739 14.3927 8.09941 15 8.09961H17.8213C17.8068 8.08333 17.7928 8.06626 17.7773 8.05078L13.9492 4.22266C13.9335 4.20696 13.9169 4.19237 13.9004 4.17773V7Z",fill:"currentColor"},null,-1)])])}const k4e=kt({name:"kimi-file-text",render:y4e}),b4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function C4e(e,t){return y(),M("svg",b4e,[...t[0]||(t[0]=[C("path",{d:"M9.2373 3.7002C10.4169 3.7002 11.5297 4.24779 12.249 5.18262L12.4424 5.43359H18C20.0987 5.43359 21.7998 7.13472 21.7998 9.2334V16.5C21.7998 18.5987 20.0987 20.2998 18 20.2998H6C3.90132 20.2998 2.2002 18.5987 2.2002 16.5V7.5C2.2002 5.40132 3.90132 3.7002 6 3.7002H9.2373ZM6 5.5C4.89543 5.5 4 6.39543 4 7.5V16.5C4 17.6046 4.89543 18.5 6 18.5H18C19.0357 18.5 19.887 17.7128 19.9893 16.7041L20 16.5V9.2334C20 8.19775 19.2128 7.34641 18.2041 7.24414L18 7.2334H12.0479L11.9326 7.22656C11.666 7.19561 11.4205 7.05812 11.2549 6.84277L10.8223 6.28027C10.4437 5.78834 9.85808 5.5 9.2373 5.5H6ZM16 9.59961C16.4971 9.59961 16.9004 10.0029 16.9004 10.5C16.9004 10.9971 16.4971 11.4004 16 11.4004H8C7.50294 11.4004 7.09961 10.9971 7.09961 10.5C7.09961 10.0029 7.50294 9.59961 8 9.59961H16Z",fill:"currentColor"},null,-1)])])}const w4e=kt({name:"kimi-folder",render:C4e}),_4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function x4e(e,t){return y(),M("svg",_4e,[...t[0]||(t[0]=[C("g",null,[C("path",{d:"M18.3623 9.99976L18.209 8.48999C18.2031 8.43161 18.2004 8.37289 18.2002 8.31421C18.1988 8.31196 18.1956 8.30842 18.1904 8.30347C18.1718 8.28559 18.1302 8.26245 18.0713 8.26245H11C10.261 8.26245 9.59753 7.81016 9.32617 7.1228L8.9082 6.06421C8.88101 5.9953 8.85737 5.92501 8.83887 5.85327C8.83778 5.85099 8.833 5.84268 8.81836 5.83179C8.79454 5.81475 8.7549 5.79939 8.70605 5.80054H3.92871C3.86986 5.80054 3.82825 5.82368 3.80957 5.84155C3.80816 5.8429 3.80675 5.84428 3.80566 5.84546L4.47559 14.0955L3.62109 17.5154L5.12109 11.5154C5.34367 10.6251 6.1438 9.99977 7.06152 9.99976H18.3623ZM7.06152 11.7996C6.96976 11.7996 6.88944 11.8629 6.86719 11.9519L5.36719 17.9519C5.33598 18.078 5.43158 18.1999 5.56152 18.2H19.4385C19.5302 18.1999 19.6106 18.1376 19.6328 18.0486L21.1328 12.0486C21.1644 11.9224 21.0686 11.7996 20.9385 11.7996H7.06152ZM20.9385 9.99976C22.2396 9.99977 23.1945 11.2228 22.8789 12.4851L21.3789 18.4851C21.1563 19.3754 20.3562 19.9997 19.4385 19.9998H4.92871C4.41722 19.9998 3.92613 19.8059 3.56445 19.4597C3.20281 19.1135 3.00004 18.6436 3 18.1541L2 5.84644C2.00006 5.35711 2.20311 4.88786 2.56445 4.54175C2.92613 4.19554 3.41722 4.00073 3.92871 4.00073H8.66406C9.10133 3.99051 9.5296 4.1225 9.87793 4.37573C10.2285 4.63118 10.4767 4.99457 10.582 5.40405L11 6.46167H18.0713C18.5828 6.46167 19.0739 6.65648 19.4355 7.00269C19.7971 7.34888 20 7.81883 20 8.30835L20.1719 9.99976H20.9385Z",fill:"currentColor"})],-1)])])}const S4e=kt({name:"kimi-folder-open",render:x4e}),A4e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function M4e(e,t){return y(),M("svg",A4e,[...t[0]||(t[0]=[C("path",{id:"af-p0",d:"M -2.619 -8.3 C -1.815 -8.3 -1.048 -7.97 -0.499 -7.39 C -0.499 -7.39 0.141 -6.712 0.141 -6.712 C 0.141 -6.712 5.75 -6.712 5.75 -6.712 C 7.904 -6.712 9.65 -4.986 9.65 -2.858 C 9.65 -2.858 9.65 -1.71 9.65 -1.71 C 9.65 -1.219 9.247 -0.821 8.75 -0.821 C 8.253 -0.821 7.85 -1.219 7.85 -1.71 C 7.85 -1.71 7.85 -2.858 7.85 -2.858 C 7.849 -4.004 6.91 -4.934 5.75 -4.934 C 5.75 -4.934 -0.207 -4.934 -0.207 -4.934 C -0.484 -4.934 -0.749 -5.047 -0.938 -5.247 C -0.938 -5.247 -1.815 -6.177 -1.815 -6.177 C -2.023 -6.397 -2.315 -6.521 -2.619 -6.521 C -2.619 -6.521 -6.25 -6.521 -6.25 -6.521 C -7.41 -6.521 -8.35 -5.592 -8.35 -4.446 C -8.35 -4.446 -8.35 4.446 -8.35 4.446 C -8.35 5.592 -7.41 6.521 -6.25 6.521 C -6.25 6.521 1.25 6.521 1.25 6.521 C 1.747 6.521 2.15 6.919 2.15 7.41 C 2.15 7.901 1.747 8.3 1.25 8.3 C 1.25 8.3 -6.25 8.3 -6.25 8.3 C -8.404 8.3 -10.15 6.574 -10.15 4.446 C -10.15 4.446 -10.15 -4.446 -10.15 -4.446 C -10.15 -6.574 -8.404 -8.3 -6.25 -8.3 C -6.25 -8.3 -2.619 -8.3 -2.619 -8.3 Z M 3.75 -2.5 C 4.247 -2.5 4.65 -2.097 4.65 -1.6 C 4.65 -1.103 4.247 -0.699 3.75 -0.699 C 3.75 -0.699 -4.25 -0.699 -4.25 -0.699 C -4.747 -0.699 -5.15 -1.103 -5.15 -1.6 C -5.15 -2.097 -4.747 -2.5 -4.25 -2.5 C -4.25 -2.5 3.75 -2.5 3.75 -2.5 Z",transform:"matrix(1 0 0 1 11.75 12)",fill:"currentColor"},null,-1),C("g",{id:"af-p1"},[C("path",{d:"M 2.635 0 L -2.635 0 M 0 -2.635 L 0 2.635",transform:"matrix(1 0 0 1 18.4 16.3)",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round"})],-1)])])}const T4e=kt({name:"kimi-folder-plus",render:M4e}),E4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function I4e(e,t){return y(),M("svg",E4e,[...t[0]||(t[0]=[C("path",{d:"M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3ZM12 19.2002C15.9764 19.2002 19.2002 15.9764 19.2002 12C19.2002 8.02355 15.9764 4.7998 12 4.7998V19.2002Z",fill:"currentColor"},null,-1)])])}const L4e=kt({name:"kimi-follow-system",render:I4e}),$4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function N4e(e,t){return y(),M("svg",$4e,[...t[0]||(t[0]=[C("path",{d:"M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7ZM12 15.6992C12.4968 15.6992 12.8994 16.1028 12.8994 16.5996C12.8994 17.0964 12.4968 17.5 12 17.5C11.5024 17.5 11.0996 17.0964 11.0996 16.5996C11.0996 16.1028 11.5024 15.6992 12 15.6992ZM12 6.49902C12.4969 6.49922 12.8994 6.86908 12.8994 7.3252V13.6729C12.8994 14.129 12.4969 14.4988 12 14.499C11.5029 14.499 11.0996 14.1291 11.0996 13.6729V7.3252C11.0996 6.86896 11.5029 6.49902 12 6.49902Z",fill:"currentColor"},null,-1)])])}const F4e=kt({name:"kimi-full-access",render:N4e}),R4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function O4e(e,t){return y(),M("svg",R4e,[...t[0]||(t[0]=[C("path",{d:"M12.5092 2.11279C17.7402 2.37781 21.8998 6.70364 21.8998 12.0005C21.8996 17.4153 17.5524 21.8108 12.1576 21.895C12.1056 21.898 12.0532 21.8999 12.0004 21.8999C11.948 21.8999 11.8954 21.8968 11.8432 21.896L11.8422 21.895C6.44751 21.8107 2.10022 17.4152 2.10001 12.0005C2.10001 6.53287 6.53278 2.1001 12.0004 2.1001L12.5092 2.11279ZM8.92715 13.0005C9.02896 14.9787 9.42581 16.721 9.99356 17.9985C10.3249 18.7441 10.6971 19.292 11.0639 19.6411C11.4259 19.9855 11.741 20.1001 12.0004 20.1001C12.2598 20.1 12.5749 19.9856 12.9369 19.6411C13.3037 19.292 13.6749 18.7441 14.0063 17.9985C14.574 16.721 14.9718 14.9788 15.0736 13.0005H8.92715ZM3.96329 13.0005C4.31462 15.8522 6.14714 18.2427 8.66837 19.3823C8.55544 19.1733 8.44916 18.9552 8.34903 18.73C7.66574 17.1926 7.22657 15.1926 7.12344 13.0005H3.96329ZM16.8764 13.0005C16.7732 15.1926 16.3341 17.1926 15.6508 18.73C15.5506 18.9554 15.4435 19.1732 15.3305 19.3823C17.8522 18.2429 19.6851 15.8525 20.0365 13.0005H16.8764ZM8.66934 4.6167C6.08869 5.78266 4.22826 8.25964 3.93985 11.1997H7.11661C7.20176 8.92954 7.64512 6.85497 8.34903 5.271C8.4494 5.04516 8.5561 4.82619 8.66934 4.6167ZM12.0004 3.8999C11.7411 3.8999 11.4259 4.01454 11.0639 4.35889C10.6971 4.70797 10.3249 5.25587 9.99356 6.00146C9.40671 7.32188 9.00186 9.13885 8.91739 11.1997H15.0834C14.9989 9.13884 14.5931 7.32189 14.0063 6.00146C13.6749 5.2559 13.3037 4.70796 12.9369 4.35889C12.5749 4.0144 12.2598 3.90002 12.0004 3.8999ZM15.3295 4.61572C15.443 4.82559 15.5502 5.04471 15.6508 5.271C16.3547 6.85498 16.799 8.92949 16.8842 11.1997H20.06C19.7715 8.25914 17.9108 5.78143 15.3295 4.61572Z",fill:"currentColor"},null,-1)])])}const P4e=kt({name:"kimi-globe",render:O4e}),D4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function B4e(e,t){return y(),M("svg",D4e,[...t[0]||(t[0]=[C("path",{d:"M8 17C8.82834 17 9.5 17.6717 9.5 18.5C9.5 19.3283 8.82834 20 8 20C7.17166 20 6.5 19.3283 6.5 18.5C6.5 17.6717 7.17166 17 8 17ZM16 17C16.8283 17 17.5 17.6717 17.5 18.5C17.5 19.3283 16.8283 20 16 20C15.1717 20 14.5 19.3283 14.5 18.5C14.5 17.6717 15.1717 17 16 17ZM8 10.5C8.82834 10.5 9.5 11.1717 9.5 12C9.5 12.8283 8.82834 13.5 8 13.5C7.17166 13.5 6.5 12.8283 6.5 12C6.5 11.1717 7.17166 10.5 8 10.5ZM16 10.5C16.8283 10.5 17.5 11.1717 17.5 12C17.5 12.8283 16.8283 13.5 16 13.5C15.1717 13.5 14.5 12.8283 14.5 12C14.5 11.1717 15.1717 10.5 16 10.5ZM8 4C8.82834 4 9.5 4.67166 9.5 5.5C9.5 6.32834 8.82834 7 8 7C7.17166 7 6.5 6.32834 6.5 5.5C6.5 4.67166 7.17166 4 8 4ZM16 4C16.8283 4 17.5 4.67166 17.5 5.5C17.5 6.32834 16.8283 7 16 7C15.1717 7 14.5 6.32834 14.5 5.5C14.5 4.67166 15.1717 4 16 4Z",fill:"currentColor"},null,-1)])])}const H4e=kt({name:"kimi-grip",render:B4e}),z4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function W4e(e,t){return y(),M("svg",z4e,[...t[0]||(t[0]=[C("path",{d:"M7.22264 6.10352C7.22264 5.5078 7.48259 4.95449 7.91405 4.56055C8.34271 4.16918 8.90831 3.96198 9.48241 3.96191C9.64155 3.96191 9.80001 3.97936 9.95507 4.01074C10.0127 3.5042 10.2586 3.04178 10.6338 2.69922C11.0625 2.30778 11.6279 2.09961 12.2021 2.09961C12.7763 2.09966 13.3418 2.30783 13.7705 2.69922C13.9947 2.90401 14.1709 3.15244 14.29 3.42676C14.4947 3.37044 14.7071 3.34182 14.9209 3.3418C15.4951 3.3418 16.0605 3.549 16.4892 3.94043C16.8644 4.28293 17.1093 4.74548 17.167 5.25195C17.3223 5.22045 17.4812 5.20312 17.6406 5.20312C18.2147 5.20318 18.7803 5.41135 19.209 5.80273C19.6402 6.19663 19.9004 6.74922 19.9004 7.34473V14.6543C19.9004 17.413 19.2914 19.0434 18.0137 20.21C16.82 21.2998 15.2175 21.9004 13.5615 21.9004C11.7538 21.9004 10.2315 21.5696 8.95702 20.8535C7.67664 20.1341 6.71683 19.0652 5.97362 17.708L3.3496 12.916C3.18848 12.6213 3.10112 12.2914 3.0996 11.9531C3.09812 11.6147 3.18309 11.2835 3.34179 10.9873C3.5001 10.692 3.72639 10.4416 3.99706 10.251C4.26771 10.0604 4.57776 9.93235 4.90136 9.87305C5.56617 9.75102 6.25934 9.84517 6.86425 10.1445C6.9942 10.2088 7.11461 10.2788 7.22264 10.3477V6.10352ZM9.02343 12.7969C9.02336 13.1912 8.76624 13.5395 8.38964 13.6562C8.0129 13.773 7.60387 13.6309 7.38085 13.3057L6.53514 12.0723C6.51218 12.0529 6.48411 12.0282 6.45018 12.002C6.34595 11.9213 6.20986 11.8289 6.06639 11.7578C5.81525 11.6335 5.51637 11.5904 5.22655 11.6436H5.22557C5.15055 11.6573 5.08558 11.6865 5.03417 11.7227C4.98289 11.7588 4.94815 11.7998 4.92772 11.8379C4.90762 11.8755 4.90023 11.9122 4.90038 11.9453C4.90057 11.9782 4.9084 12.0144 4.9287 12.0518L7.55272 16.8438C8.16912 17.9693 8.90989 18.7622 9.83886 19.2842C10.7737 19.8094 11.9704 20.0996 13.5615 20.0996C14.7902 20.0996 15.9536 19.6533 16.7998 18.8809C17.5619 18.185 18.0996 17.1383 18.0996 14.6543V7.34473C18.0996 7.28204 18.0734 7.20342 17.9951 7.13184C17.9139 7.05771 17.7875 7.00396 17.6406 7.00391C17.4937 7.00391 17.3674 7.05771 17.2861 7.13184C17.2077 7.20347 17.1807 7.28199 17.1807 7.34473V11.0693C17.1805 11.5661 16.778 11.9685 16.2812 11.9688C15.7843 11.9688 15.381 11.5662 15.3808 11.0693V5.48242C15.3808 5.41973 15.3537 5.34107 15.2754 5.26953C15.1941 5.19547 15.0677 5.1416 14.9209 5.1416C14.774 5.14166 14.6476 5.19541 14.5664 5.26953C14.4881 5.34105 14.462 5.41974 14.4619 5.48242V11.0693C14.4617 11.5662 14.0584 11.9688 13.5615 11.9688C13.0646 11.9687 12.6613 11.5662 12.6611 11.0693V4.24121C12.6611 4.17852 12.635 4.09989 12.5566 4.02832C12.4754 3.95419 12.349 3.90045 12.2021 3.90039C12.0552 3.90039 11.9289 3.95421 11.8476 4.02832C11.7692 4.09992 11.7422 4.17849 11.7422 4.24121V11.0693C11.742 11.5661 11.3395 11.9685 10.8428 11.9688C10.3458 11.9688 9.94257 11.5662 9.94237 11.0693V6.10352L9.93651 6.05371C9.92534 6.00177 9.89573 5.94433 9.8369 5.89062C9.75567 5.81647 9.62938 5.76172 9.48241 5.76172C9.33554 5.76179 9.2091 5.81651 9.12792 5.89062C9.04964 5.96222 9.02343 6.04084 9.02343 6.10352V12.7969Z",fill:"currentColor"},null,-1)])])}const U4e=kt({name:"kimi-hand",render:W4e}),j4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function V4e(e,t){return y(),M("svg",j4e,[...t[0]||(t[0]=[C("path",{d:"M4 3.33203C4.55224 3.33203 4.99993 3.7798 5 4.33203V18.0908H20.0674C20.6195 18.0908 21.0671 18.5388 21.0674 19.0908C21.0674 19.6431 20.6197 20.0908 20.0674 20.0908H5C3.89543 20.0908 3 19.1954 3 18.0908V4.33203C3.00007 3.7798 3.44776 3.33203 4 3.33203ZM8.19922 9.28418C8.7515 9.28418 9.19922 9.73189 9.19922 10.2842V15.6045C9.19908 16.1567 8.75142 16.6045 8.19922 16.6045C7.64719 16.6043 7.19936 16.1565 7.19922 15.6045V10.2842C7.19922 9.73202 7.6471 9.28438 8.19922 9.28418ZM17.2227 6.85645C17.7748 6.85658 18.2226 7.3043 18.2227 7.85645V15.6045C18.2225 16.1566 17.7747 16.6044 17.2227 16.6045C16.6705 16.6045 16.2228 16.1566 16.2227 15.6045V7.85645C16.2227 7.30422 16.6704 6.85645 17.2227 6.85645ZM12.7109 3.96387C13.2631 3.96387 13.7107 4.41175 13.7109 4.96387V15.6035C13.7109 16.1558 13.2632 16.6035 12.7109 16.6035C12.1587 16.6035 11.7109 16.1558 11.7109 15.6035V4.96387C11.7111 4.41175 12.1588 3.96387 12.7109 3.96387Z",fill:"currentColor"},null,-1)])])}const q4e=kt({name:"kimi-histogram",render:V4e}),K4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Z4e(e,t){return y(),M("svg",K4e,[...t[0]||(t[0]=[C("path",{d:"M8.00916 7.50488C8.47326 7.50488 8.91828 7.68943 9.24646 8.01758C9.57465 8.34577 9.75916 8.79075 9.75916 9.25488C9.75916 9.71901 9.57465 10.164 9.24646 10.4922C8.91828 10.8203 8.47326 11.0049 8.00916 11.0049C7.54507 11.0049 7.10001 10.8203 6.77185 10.4922C6.4437 10.164 6.25916 9.71898 6.25916 9.25488C6.25916 8.79078 6.4437 8.34576 6.77185 8.01758C7.10001 7.68942 7.54507 7.50492 8.00916 7.50488Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17.8998 4.09961C20.0537 4.09961 21.8002 5.84609 21.8002 8V16C21.8002 18.1539 20.0537 19.9004 17.8998 19.9004H5.89978C3.74598 19.9003 1.99939 18.1538 1.99939 16V8C1.99939 5.84617 3.74598 4.09974 5.89978 4.09961H17.8998ZM15.4867 12.2539C15.448 12.2184 15.3885 12.2192 15.351 12.2559L11.7338 15.8027C11.0146 16.5079 9.87305 16.5222 9.13708 15.835L6.98669 13.8262C6.95049 13.7924 6.89516 13.791 6.85681 13.8223L3.82361 16.2988C3.96873 17.3168 4.84165 18.0995 5.89978 18.0996H17.8998C18.9375 18.0996 19.7964 17.3466 19.9662 16.3574L15.4867 12.2539ZM5.89978 5.90039C4.74009 5.90052 3.80017 6.84028 3.80017 8V14.002L5.73181 12.4238C6.46046 11.8286 7.51253 11.8634 8.20056 12.5059L10.351 14.5146C10.3897 14.5508 10.4498 14.5497 10.4877 14.5127L14.1049 10.9658C14.819 10.2656 15.9506 10.2466 16.6879 10.9219L19.9994 13.9551V8C19.9994 6.8402 19.0596 5.90039 17.8998 5.90039H5.89978Z",fill:"currentColor"},null,-1)])])}const G4e=kt({name:"kimi-image",render:Z4e}),Y4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function X4e(e,t){return y(),M("svg",Y4e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M5.09375 2.81174C5.4825 2.50796 6.04376 2.56488 6.34766 2.93869L20.1855 19.9602C20.4895 20.3341 20.421 20.8836 20.0322 21.1877C19.6435 21.4917 19.0823 21.4355 18.7783 21.0617L17.9971 20.1008H5.99609C3.84224 20.1008 2.0958 18.3552 2.0957 16.2014V8.13889C2.09589 6.26755 3.41429 4.70428 5.17285 4.32639L4.93945 4.03928C4.63577 3.66536 4.7051 3.11573 5.09375 2.81174ZM7.13184 14.1096C7.09416 14.0738 7.03659 14.0713 6.99609 14.1037L3.92871 16.5569C4.09761 17.5472 4.95753 18.301 5.99609 18.301H16.5342L13.373 14.4133L11.9072 15.9455C11.1531 16.7324 9.92202 16.7621 9.13281 16.0119L7.13184 14.1096ZM5.99609 6.03928C4.83643 6.03928 3.89669 6.97927 3.89648 8.13889V14.1408L5.83496 12.5901C6.60469 11.9742 7.69929 12.022 8.41504 12.7024L10.416 14.6037C10.4575 14.6431 10.5218 14.642 10.5615 14.6008L12.1641 12.926L9.78906 10.0051C9.70282 10.2646 9.55682 10.5038 9.35645 10.7004C9.02202 11.0285 8.56767 11.2131 8.09473 11.2131C7.62195 11.213 7.1683 11.0284 6.83398 10.7004C6.49961 10.3724 6.31152 9.92701 6.31152 9.46311C6.3116 8.99941 6.49981 8.55474 6.83398 8.22678C7.12986 7.93654 7.51931 7.75901 7.93262 7.7219L6.56543 6.03928H5.99609Z",fill:"currentColor"},null,-1),C("path",{d:"M18.0049 4.31272C20.1587 4.31288 21.9043 6.0593 21.9043 8.21311V13.718C21.9039 15.4743 19.7248 16.2906 18.5713 14.966L14.9141 10.7658C14.5882 10.3912 14.6278 9.82271 15.002 9.49631C15.3768 9.16994 15.9451 9.20948 16.2715 9.5842L19.9287 13.7844C19.9528 13.812 19.9696 13.8167 19.9775 13.8186C19.9908 13.8216 20.0141 13.8213 20.04 13.8117C20.0655 13.8021 20.0826 13.7875 20.0908 13.7766C20.0955 13.7702 20.1044 13.7552 20.1045 13.718V8.21311C20.1045 7.05341 19.1645 6.11366 18.0049 6.1135H10.6328C10.1361 6.11327 9.73267 5.70981 9.73242 5.21311C9.73242 4.71619 10.136 4.31295 10.6328 4.31272H18.0049Z",fill:"currentColor"},null,-1)])])}const J4e=kt({name:"kimi-image-failed",render:X4e}),Q4e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function e3e(e,t){return y(),M("svg",Q4e,[...t[0]||(t[0]=[C("path",{d:"M12 2.1001C17.4676 2.10031 21.8994 6.53286 21.8994 12.0005C21.8992 17.4679 17.4674 21.8997 12 21.8999C6.53237 21.8999 2.09982 17.4681 2.09961 12.0005C2.09961 6.53273 6.53224 2.1001 12 2.1001ZM12 3.8999C7.52636 3.8999 3.89941 7.52684 3.89941 12.0005C3.89963 16.474 7.52649 20.1001 12 20.1001C16.4733 20.0999 20.0994 16.4738 20.0996 12.0005C20.0996 7.52697 16.4735 3.90011 12 3.8999ZM12 9.50049C12.4969 9.50068 12.8994 9.87055 12.8994 10.3267V16.6743C12.8992 17.1303 12.4968 17.5003 12 17.5005C11.503 17.5005 11.0998 17.1304 11.0996 16.6743V10.3267C11.0996 9.87043 11.5029 9.50049 12 9.50049ZM12 6.49951C12.4968 6.49951 12.8994 6.90313 12.8994 7.3999C12.8992 7.8965 12.4966 8.30029 12 8.30029C11.5025 8.30028 11.0998 7.8965 11.0996 7.3999C11.0996 6.90313 11.5024 6.49952 12 6.49951Z",fill:"currentColor"},null,-1)])])}const t3e=kt({name:"kimi-info",render:e3e}),n3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function o3e(e,t){return y(),M("svg",n3e,[...t[0]||(t[0]=[iu('<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.09998C6.53222 2.09998 2.09998 6.53222 2.09998 12C2.09998 17.4677 6.53222 21.9 12 21.9C17.4677 21.9 21.9 17.4677 21.9 12C21.9 6.53222 17.4677 2.09998 12 2.09998ZM3.89998 12C3.89998 7.52633 7.52633 3.89998 12 3.89998C16.4736 3.89998 20.1 7.52633 20.1 12C20.1 16.4736 16.4736 20.1 12 20.1C7.52633 20.1 3.89998 16.4736 3.89998 12Z" fill="currentColor"></path><path d="M9.4286 9.47153C9.4286 8.97448 9.83154 8.57153 10.3286 8.57153H11.1C11.5971 8.57153 12 8.97448 12 9.47153C12 9.96859 11.5971 10.3715 11.1 10.3715H10.3286C9.83154 10.3715 9.4286 9.96859 9.4286 9.47153Z" fill="currentColor"></path><path d="M5.14289 9.47155C5.14289 8.97449 5.54583 8.57155 6.04289 8.57155H7.67146C8.16851 8.57155 8.57146 8.97449 8.57146 9.47155C8.57146 9.9686 8.16851 10.3715 7.67146 10.3715H6.04289C5.54583 10.3715 5.14289 9.9686 5.14289 9.47155Z" fill="currentColor"></path><path d="M8.57146 16.3287C8.57146 15.8316 8.9744 15.4287 9.47145 15.4287H14.5286C15.0257 15.4287 15.4286 15.8316 15.4286 16.3287C15.4286 16.8257 15.0257 17.2287 14.5286 17.2287H9.47145C8.9744 17.2287 8.57146 16.8257 8.57146 16.3287Z" fill="currentColor"></path><path d="M6.04288 12.0001C5.54583 12.0001 5.14288 12.403 5.14288 12.9001C5.14288 13.3972 5.54583 13.8001 6.04288 13.8001H6.81431C7.31137 13.8001 7.71431 13.3972 7.71431 12.9001C7.71431 12.403 7.31137 12.0001 6.81431 12.0001H6.04288Z" fill="currentColor"></path><path d="M9.47145 12.0001C8.9744 12.0001 8.57146 12.403 8.57146 12.9001C8.57146 13.3972 8.9744 13.8001 9.47146 13.8001H10.2429C10.7399 13.8001 11.1429 13.3972 11.1429 12.9001C11.1429 12.403 10.7399 12.0001 10.2429 12.0001H9.47145Z" fill="currentColor"></path><path d="M12.8572 9.47153C12.8572 8.97448 13.2601 8.57153 13.7572 8.57153H14.5286C15.0257 8.57153 15.4286 8.97448 15.4286 9.47153C15.4286 9.96859 15.0257 10.3715 14.5286 10.3715H13.7572C13.2601 10.3715 12.8572 9.96859 12.8572 9.47153Z" fill="currentColor"></path><path d="M12.9 12.0001C12.403 12.0001 12 12.403 12 12.9001C12 13.3972 12.403 13.8001 12.9 13.8001H13.6715C14.1685 13.8001 14.5715 13.3972 14.5715 12.9001C14.5715 12.403 14.1685 12.0001 13.6715 12.0001H12.9Z" fill="currentColor"></path><path d="M16.2857 9.47153C16.2857 8.97448 16.6887 8.57153 17.1857 8.57153H17.9572C18.4542 8.57153 18.8572 8.97448 18.8572 9.47153C18.8572 9.96859 18.4542 10.3715 17.9572 10.3715H17.1857C16.6887 10.3715 16.2857 9.96859 16.2857 9.47153Z" fill="currentColor"></path><path d="M16.3286 12.0001C15.8315 12.0001 15.4286 12.403 15.4286 12.9001C15.4286 13.3972 15.8315 13.8001 16.3286 13.8001H17.9572C18.4542 13.8001 18.8572 13.3972 18.8572 12.9001C18.8572 12.403 18.4542 12.0001 17.9572 12.0001H16.3286Z" fill="currentColor"></path>',10)])])}const s3e=kt({name:"kimi-keyboard",render:o3e}),i3e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function r3e(e,t){return y(),M("svg",i3e,[...t[0]||(t[0]=[C("path",{id:"bar-divider",d:"M 9.3 18.951 L 9.3 4.3",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1),C("path",{id:"bar-box",d:"M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"butt","stroke-linejoin":"miter",transform:"matrix(1 0 0 1 11.8 11.8)"},null,-1),C("path",{id:"bar-arrow",d:"M -1.25 -2.5 L 1.25 0 L -1.25 2.5",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const l3e=kt({name:"kimi-left-panel",render:r3e}),a3e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function u3e(e,t){return y(),M("svg",a3e,[...t[0]||(t[0]=[C("path",{id:"bar-divider",d:"M 9.3 18.951 L 9.3 4.3",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1),C("path",{id:"bar-box",d:"M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"butt","stroke-linejoin":"miter",transform:"matrix(1 0 0 1 11.8 11.8)"},null,-1),C("path",{id:"bar-arrow-expand",d:"M -1.25 -2.5 L 1.25 0 L -1.25 2.5",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const c3e=kt({name:"kimi-left-panel-expand",render:u3e}),d3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function f3e(e,t){return y(),M("svg",d3e,[...t[0]||(t[0]=[iu('<g><path d="M12.9 1.7999C12.9 1.30285 12.4971 0.899902 12 0.899902C11.5029 0.899902 11.1 1.30285 11.1 1.7999V2.7999C11.1 3.29696 11.5029 3.6999 12 3.6999C12.4971 3.6999 12.9 3.29696 12.9 2.7999V1.7999Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M6.1 11.9999C6.1 8.7414 8.74152 6.09988 12 6.09988C15.2585 6.09988 17.9 8.7414 17.9 11.9999C17.9 15.2584 15.2585 17.8999 12 17.8999C8.74152 17.8999 6.1 15.2584 6.1 11.9999ZM12 7.89988C9.73563 7.89988 7.9 9.73551 7.9 11.9999C7.9 14.2642 9.73563 16.0999 12 16.0999C14.2644 16.0999 16.1 14.2642 16.1 11.9999C16.1 9.73551 14.2644 7.89988 12 7.89988Z" fill="currentColor"></path><path d="M0.899994 11.9999C0.899994 11.5028 1.30294 11.0999 1.79999 11.0999H2.79999C3.29705 11.0999 3.69999 11.5028 3.69999 11.9999C3.69999 12.4969 3.29705 12.8999 2.79999 12.8999H1.79999C1.30294 12.8999 0.899994 12.4969 0.899994 11.9999Z" fill="currentColor"></path><path d="M12 20.2991C12.4971 20.2991 12.9 20.702 12.9 21.1991V22.1991C12.9 22.6961 12.4971 23.0991 12 23.0991C11.5029 23.0991 11.1 22.6961 11.1 22.1991V21.1991C11.1 20.702 11.5029 20.2991 12 20.2991Z" fill="currentColor"></path><path d="M21.2016 11.0999C20.7045 11.0999 20.3016 11.5028 20.3016 11.9999C20.3016 12.4969 20.7045 12.8999 21.2016 12.8999H22.2016C22.6986 12.8999 23.1016 12.4969 23.1016 11.9999C23.1016 11.5028 22.6986 11.0999 22.2016 11.0999H21.2016Z" fill="currentColor"></path><path d="M20.1995 3.79903C20.551 4.1505 20.551 4.72035 20.1995 5.07182L19.4924 5.77893C19.141 6.1304 18.5711 6.1304 18.2196 5.77893C17.8682 5.42746 17.8682 4.85761 18.2196 4.50614L18.9268 3.79903C19.2782 3.44756 19.8481 3.44756 20.1995 3.79903Z" fill="currentColor"></path><path d="M19.4942 18.2215C19.1427 17.87 18.5729 17.87 18.2214 18.2215C17.87 18.573 17.87 19.1428 18.2214 19.4943L18.9285 20.2014C19.28 20.5529 19.8498 20.5529 20.2013 20.2014C20.5528 19.8499 20.5528 19.2801 20.2013 18.9286L19.4942 18.2215Z" fill="currentColor"></path><path d="M5.78079 18.2213C6.13227 18.5727 6.13227 19.1426 5.78079 19.4941L5.07369 20.2012C4.72222 20.5526 4.15237 20.5526 3.8009 20.2012C3.44942 19.8497 3.44942 19.2798 3.8009 18.9284L4.508 18.2213C4.85947 17.8698 5.42932 17.8698 5.78079 18.2213Z" fill="currentColor"></path><path d="M5.07077 3.79912C4.7193 3.44764 4.14945 3.44764 3.79798 3.79912C3.4465 4.15059 3.4465 4.72044 3.79798 5.07191L4.50508 5.77901C4.85655 6.13049 5.4264 6.13049 5.77787 5.77902C6.12935 5.42754 6.12935 4.85769 5.77787 4.50622L5.07077 3.79912Z" fill="currentColor"></path></g>',1)])])}const p3e=kt({name:"kimi-light-mode",render:f3e}),h3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function m3e(e,t){return y(),M("svg",h3e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M3.97427 8.06961C4.99348 7.33581 6.18946 7.1 7.00001 7.1H9.00001C9.49706 7.1 9.90001 7.50294 9.90001 8C9.90001 8.49706 9.49706 8.9 9.00001 8.9H7.00001C6.47755 8.9 5.67353 9.06419 5.02599 9.53039C4.42434 9.96356 3.90001 10.6934 3.90001 12C3.90001 13.3066 4.42434 14.0364 5.02599 14.4696C5.67353 14.9358 6.47755 15.1 7.00001 15.1H9.00001C9.49706 15.1 9.90001 15.5029 9.90001 16C9.90001 16.4971 9.49706 16.9 9.00001 16.9H7.00001C6.18946 16.9 4.99348 16.6642 3.97427 15.9304C2.90917 15.1636 2.10001 13.8934 2.10001 12C2.10001 10.1066 2.90917 8.83644 3.97427 8.06961ZM14.1 8C14.1 7.50294 14.5029 7.1 15 7.1H17C17.8105 7.1 19.0065 7.33581 20.0257 8.06961C21.0908 8.83644 21.9 10.1066 21.9 12C21.9 13.8934 21.0908 15.1636 20.0257 15.9304C19.0065 16.6642 17.8105 16.9 17 16.9H15C14.5029 16.9 14.1 16.4971 14.1 16C14.1 15.5029 14.5029 15.1 15 15.1H17C17.5225 15.1 18.3265 14.9358 18.974 14.4696C19.5757 14.0364 20.1 13.3066 20.1 12C20.1 10.6934 19.5757 9.96356 18.974 9.53039C18.3265 9.06419 17.5225 8.9 17 8.9H15C14.5029 8.9 14.1 8.49706 14.1 8ZM7.10001 12C7.10001 11.5029 7.50295 11.1 8.00001 11.1H16C16.4971 11.1 16.9 11.5029 16.9 12C16.9 12.4971 16.4971 12.9 16 12.9H8.00001C7.50295 12.9 7.10001 12.4971 7.10001 12Z",fill:"currentColor"},null,-1)])])}const g3e=kt({name:"kimi-link",render:m3e}),v3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function y3e(e,t){return y(),M("svg",v3e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M4.10001 5.99998C4.10001 5.50292 4.50295 5.09998 5.00001 5.09998H19C19.4971 5.09998 19.9 5.50292 19.9 5.99998C19.9 6.49703 19.4971 6.89998 19 6.89998H5.00001C4.50295 6.89998 4.10001 6.49703 4.10001 5.99998ZM4.10001 12C4.10001 11.5029 4.50295 11.1 5.00001 11.1H19C19.4971 11.1 19.9 11.5029 19.9 12C19.9 12.497 19.4971 12.9 19 12.9H5.00001C4.50295 12.9 4.10001 12.497 4.10001 12ZM4.10001 18C4.10001 17.5029 4.50295 17.1 5.00001 17.1H19C19.4971 17.1 19.9 17.5029 19.9 18C19.9 18.497 19.4971 18.9 19 18.9H5.00001C4.50295 18.9 4.10001 18.497 4.10001 18Z",fill:"currentColor"},null,-1)])])}const k3e=kt({name:"kimi-list",render:y3e}),b3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function C3e(e,t){return y(),M("svg",b3e,[...t[0]||(t[0]=[C("g",null,[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18 4.09961C20.1539 4.09961 21.9004 5.84609 21.9004 8V16C21.9004 18.1539 20.1539 19.9004 18 19.9004H6C3.84609 19.9004 2.09961 18.1539 2.09961 16V8C2.09961 5.84609 3.84609 4.09961 6 4.09961H18ZM3.90039 16C3.90039 17.1598 4.8402 18.0996 6 18.0996H18C19.1598 18.0996 20.0996 17.1598 20.0996 16V9.49805L13.5361 13.5361C12.5955 14.1147 11.4075 14.1084 10.4727 13.5205L3.90039 9.38672V16ZM6 5.90039C5.0746 5.90039 4.29039 6.49909 4.01074 7.33008L11.4316 11.9971C11.7861 12.2199 12.2361 12.2222 12.5928 12.0029L20.0195 7.43457C19.7725 6.54993 18.9636 5.90039 18 5.90039H6Z",fill:"currentColor"})],-1)])])}const w3e=kt({name:"kimi-mail",render:C3e}),_3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function x3e(e,t){return y(),M("svg",_3e,[...t[0]||(t[0]=[C("path",{d:"M17 11.0996C17.4971 11.0996 17.9004 11.5029 17.9004 12C17.9004 12.4971 17.4971 12.9004 17 12.9004H7C6.50294 12.9004 6.09961 12.4971 6.09961 12C6.09961 11.5029 6.50294 11.0996 7 11.0996H17Z",fill:"currentColor"},null,-1)])])}const S3e=kt({name:"kimi-minus",render:x3e}),A3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function M3e(e,t){return y(),M("svg",A3e,[...t[0]||(t[0]=[C("path",{d:"M15.182 3.32802C15.9304 2.72235 17.0309 2.76978 17.724 3.46767L18.5424 4.29189L18.6722 4.43642C19.2377 5.13495 19.234 6.1404 18.6635 6.83486L18.5326 6.97841L18.0248 7.48232C17.9549 7.55172 17.8793 7.61254 17.8021 7.66884C17.9794 8.18027 17.9316 8.7498 17.6595 9.22841C17.6847 9.24522 17.7091 9.2635 17.7328 9.2831L17.8002 9.3456L17.9847 9.53798C19.8515 11.5442 20.4549 14.0022 19.6224 16.2196C19.1921 17.3657 18.4025 18.3827 17.2992 19.203H19.0873L19.1801 19.2079C19.6337 19.2542 19.9877 19.6375 19.9877 20.1034C19.9876 20.5692 19.6337 20.9527 19.1801 20.9989L19.0873 21.0028H13.0385C13.0244 21.0033 13.0104 21.0031 12.9965 21.0028H4.9115C4.41448 21.0028 4.01117 20.6004 4.01111 20.1034C4.01111 19.6064 4.41444 19.203 4.9115 19.203H12.9047C15.7614 18.5471 17.3679 17.1023 17.9369 15.5868C18.4678 14.1726 18.179 12.4782 16.807 10.9188L16.5189 10.6093L16.4574 10.5399C16.4549 10.5368 16.453 10.5333 16.4506 10.5302L12.3011 14.6522C11.6031 15.3454 10.5023 15.3845 9.75818 14.7733L9.61365 14.6425L7.31091 12.3231C6.5717 11.5786 6.57617 10.376 7.32068 9.63662L12.3676 4.62392L12.5121 4.49404C13.0358 4.06988 13.7318 3.96755 14.3402 4.18251C14.3969 4.10597 14.4591 4.03197 14.5287 3.96279L15.0365 3.45791L15.182 3.32802ZM4.83044 12.9335C5.16112 12.6052 5.68305 12.5863 6.03552 12.8759L6.10291 12.9384L9.07361 15.9286L9.13513 15.997C9.42218 16.3514 9.3992 16.8727 9.06873 17.2011C8.7381 17.5294 8.21712 17.5482 7.86462 17.2587L7.79626 17.1972L4.82654 14.2069L4.76501 14.1376C4.47792 13.7831 4.49979 13.2619 4.83044 12.9335ZM13.6693 5.87978L13.6361 5.90126L8.58826 10.914C8.54935 10.9529 8.54943 11.0165 8.58826 11.0556L10.891 13.3739L10.9242 13.3964C10.9602 13.4111 11.0032 13.404 11.0326 13.3749L16.0795 8.3622L16.1019 8.329C16.1117 8.3049 16.1117 8.2779 16.1019 8.2538L16.0804 8.2206L13.7777 5.90224C13.7486 5.87289 13.7054 5.86535 13.6693 5.87978ZM16.3383 4.71376L16.3051 4.73525L15.7972 5.24013C15.7584 5.27904 15.7585 5.34166 15.7972 5.38076L16.6146 6.20498L16.6478 6.22744C16.6838 6.24221 16.7268 6.23487 16.7562 6.20595L17.264 5.70107L17.2865 5.66787C17.2962 5.64382 17.2963 5.61672 17.2865 5.59267L17.265 5.55947L16.4467 4.73623C16.4174 4.70681 16.3744 4.6992 16.3383 4.71376Z",fill:"currentColor"},null,-1)])])}const T3e=kt({name:"kimi-microscope",render:M3e}),E3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function I3e(e,t){return y(),M("svg",E3e,[...t[0]||(t[0]=[C("path",{d:"M6 12C6 12.8283 5.32834 13.5 4.5 13.5C3.67166 13.5 3 12.8283 3 12C3 11.1717 3.67166 10.5 4.5 10.5C5.32834 10.5 6 11.1717 6 12Z",fill:"currentColor"},null,-1),C("path",{d:"M13.5 12C13.5 12.8283 12.8283 13.5 12 13.5C11.1717 13.5 10.5 12.8283 10.5 12C10.5 11.1717 11.1717 10.5 12 10.5C12.8283 10.5 13.5 11.1717 13.5 12Z",fill:"currentColor"},null,-1),C("path",{d:"M19.5002 13.5C20.3287 13.5 21 12.8287 21 12.0002C21 11.1718 20.3287 10.5 19.5002 10.5C18.6718 10.5 18 11.1718 18 12.0002C18 12.8287 18.6718 13.5 19.5002 13.5Z",fill:"currentColor"},null,-1)])])}const L3e=kt({name:"kimi-more",render:I3e}),$3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function N3e(e,t){return y(),M("svg",$3e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M8 12.0993C8.49691 12.0993 8.90016 12.5028 8.90039 12.9997V17.9997C8.90039 19.6013 7.60163 20.9001 6 20.9001C4.39837 20.9001 3.09961 19.6013 3.09961 17.9997C3.09984 16.3982 4.39852 15.0993 6 15.0993C6.38939 15.0993 6.76033 15.1778 7.09961 15.317V12.9997C7.09984 12.5028 7.50309 12.0993 8 12.0993ZM6 16.9001C5.39263 16.9001 4.90062 17.3923 4.90039 17.9997C4.90039 18.6072 5.39249 19.0993 6 19.0993C6.60751 19.0993 7.09961 18.6072 7.09961 17.9997C7.09938 17.3923 6.60737 16.9001 6 16.9001Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.627 3.35611C19.8025 3.12106 20.9001 4.02068 20.9004 5.21939V15.9997C20.9004 17.6013 19.6016 18.9001 18 18.9001C16.3984 18.9001 15.0996 17.6013 15.0996 15.9997C15.0998 14.3982 16.3985 13.0993 18 13.0993C18.3894 13.0993 18.7603 13.1778 19.0996 13.317V9.21939C19.0993 9.15657 19.0421 9.10946 18.9805 9.12173L12.6768 10.3825C12.1894 10.4799 11.7148 10.1637 11.6172 9.67642C11.52 9.18922 11.8361 8.71439 12.3232 8.61685L18.627 7.35611C18.7868 7.32415 18.9452 7.31502 19.0996 7.32291V5.21939C19.0993 5.15657 19.0421 5.10946 18.9805 5.12173L12.6768 6.38248C12.1894 6.47994 11.7148 6.16372 11.6172 5.67642C11.52 5.18922 11.8361 4.71439 12.3232 4.61685L18.627 3.35611ZM18 14.9001C17.3926 14.9001 16.9006 15.3923 16.9004 15.9997C16.9004 16.6072 17.3925 17.0993 18 17.0993C18.6075 17.0993 19.0996 16.6072 19.0996 15.9997C19.0994 15.3923 18.6074 14.9001 18 14.9001Z",fill:"currentColor"},null,-1),C("path",{d:"M7.32422 5.38931C7.61669 4.87032 8.38346 4.87015 8.67578 5.38931L8.73047 5.50845L8.89551 5.95376L8.97949 6.1481C9.19937 6.58817 9.57968 6.93145 10.0459 7.10415L10.4912 7.26919C11.127 7.50461 11.1666 8.36217 10.6104 8.67544L10.4912 8.73013L10.0459 8.89517C9.5799 9.06783 9.19939 9.41141 8.97949 9.85123L8.89551 10.0456L8.73047 10.4909C8.49495 11.1267 7.63737 11.1665 7.32422 10.61L7.26953 10.4909L7.10449 10.0456C6.93172 9.57931 6.58767 9.19898 6.14746 8.97916L5.9541 8.89517L5.50879 8.73013C4.83054 8.47903 4.83061 7.52037 5.50879 7.26919L5.9541 7.10415L6.14746 7.02017C6.58757 6.80032 6.93176 6.41995 7.10449 5.95376L7.26953 5.50845L7.32422 5.38931Z",fill:"currentColor"},null,-1)])])}const F3e=kt({name:"kimi-music",render:N3e}),R3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function O3e(e,t){return y(),M("svg",R3e,[...t[0]||(t[0]=[C("path",{d:"M17.9551 6.32648C17.955 5.82951 17.5517 5.42706 17.0547 5.42706H15.4844C14.9875 5.42717 14.5851 5.82958 14.585 6.32648V17.6732C14.585 18.1701 14.9874 18.5734 15.4844 18.5735H17.0547C17.5518 18.5735 17.9551 18.1702 17.9551 17.6732V6.32648ZM19.7549 17.6732C19.7549 19.1643 18.5459 20.3734 17.0547 20.3734H15.4844C13.9933 20.3732 12.7842 19.1643 12.7842 17.6732V6.32648C12.7843 4.83546 13.9934 3.62639 15.4844 3.62628H17.0547C18.5458 3.62628 19.7548 4.8354 19.7549 6.32648V17.6732Z",fill:"currentColor"},null,-1),C("path",{d:"M9.41571 6.32648C9.41561 5.82951 9.01231 5.42706 8.51532 5.42706H6.94501C6.44811 5.42717 6.0457 5.82958 6.04559 6.32648V17.6732C6.04559 18.1701 6.44804 18.5734 6.94501 18.5735H8.51532C9.01238 18.5735 9.41571 18.1702 9.41571 17.6732V6.32648ZM11.2155 17.6732C11.2155 19.1643 10.0065 20.3734 8.51532 20.3734H6.94501C5.45393 20.3732 4.24481 19.1643 4.24481 17.6732V6.32648C4.24492 4.83546 5.45399 3.62639 6.94501 3.62628H8.51532C10.0064 3.62628 11.2154 4.8354 11.2155 6.32648V17.6732Z",fill:"currentColor"},null,-1)])])}const P3e=kt({name:"kimi-pause",render:O3e}),D3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function B3e(e,t){return y(),M("svg",D3e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.0176 4.89998C17.7305 4.89998 17.4552 5.014 17.2522 5.217L6.35429 16.1149C5.957 16.5122 5.67517 17.01 5.53889 17.5551L5.23691 18.763L6.44486 18.4611C6.98994 18.3248 7.48773 18.0429 7.88502 17.6456L18.783 6.74773C18.8834 6.64728 18.9631 6.52797 19.0176 6.39658C19.072 6.26517 19.1 6.12441 19.1 5.98236C19.1 5.84031 19.072 5.69956 19.0176 5.56815C18.9631 5.43676 18.8834 5.31745 18.783 5.217C18.6825 5.11649 18.5631 5.03676 18.4318 4.98237C18.3005 4.92798 18.1597 4.89998 18.0176 4.89998ZM15.9794 3.94421C16.52 3.40366 17.2531 3.09998 18.0176 3.09998C18.3961 3.09998 18.7709 3.17452 19.1207 3.31938C19.4704 3.46424 19.7881 3.67656 20.0558 3.94421C20.3235 4.21192 20.5357 4.52969 20.6805 4.87932C20.8254 5.22895 20.9 5.60375 20.9 5.98236C20.9 6.36098 20.8254 6.73578 20.6805 7.08541C20.5357 7.43504 20.3235 7.75281 20.0558 8.02052L17.6385 10.4378L9.15781 18.9184C8.52984 19.5464 7.74301 19.9919 6.88142 20.2073L4.21828 20.8731C3.91158 20.9498 3.58714 20.8599 3.3636 20.6364C3.14006 20.4128 3.05019 20.0884 3.12686 19.7817L3.79264 17.1185C4.00803 16.257 4.45351 15.4701 5.0815 14.8421L15.9794 3.94421Z",fill:"currentColor"},null,-1)])])}const H3e=kt({name:"kimi-pencil",render:B3e}),z3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function W3e(e,t){return y(),M("svg",z3e,[...t[0]||(t[0]=[C("path",{d:"M7.76251 3.10547C8.25776 3.10552 8.74422 3.23849 9.17072 3.49023L19.533 9.60742C20.8536 10.3869 21.2922 12.0901 20.5174 13.4121C20.2785 13.8195 19.9398 14.1604 19.533 14.4004L9.16974 20.5156C7.84721 21.2958 6.14595 20.8511 5.36993 19.5273C5.1196 19.1003 4.98719 18.6142 4.98712 18.1191V5.88672C4.98716 4.3537 6.2273 3.10547 7.76251 3.10547ZM6.7879 18.1191C6.78797 18.2945 6.8343 18.4664 6.92267 18.6172C7.19638 19.0841 7.79336 19.2377 8.25568 18.9648L18.618 12.8496C18.7607 12.7654 18.8803 12.6458 18.9647 12.502C19.2393 12.0334 19.082 11.4311 18.618 11.1572L8.25568 5.04102C8.1061 4.95273 7.93562 4.9063 7.76251 4.90625C7.22703 4.90625 6.78794 5.34218 6.7879 5.88672V18.1191Z",fill:"currentColor"},null,-1)])])}const U3e=kt({name:"kimi-play",render:W3e}),j3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function V3e(e,t){return y(),M("svg",j3e,[...t[0]||(t[0]=[C("path",{d:"M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z",fill:"currentColor"},null,-1),C("path",{d:"M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 3.7998C7.47126 3.7998 3.7998 7.47126 3.7998 12C3.7998 16.5287 7.47126 20.2002 12 20.2002C16.5287 20.2002 20.2002 16.5287 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998Z",fill:"currentColor"},null,-1)])])}const q3e=kt({name:"kimi-question",render:V3e}),K3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Z3e(e,t){return y(),M("svg",K3e,[...t[0]||(t[0]=[C("path",{d:"M12 2C13.1046 2 14 2.89543 14 4C14 4.78019 13.552 5.45353 12.9004 5.7832V7H16.5C18.1569 7 19.5 8.34315 19.5 10V17C19.5 18.6051 18.2394 19.9158 16.6543 19.9961L16.5 20H7.5L7.3457 19.9961C5.81166 19.9184 4.58163 18.6883 4.50391 17.1543L4.5 17V10C4.5 8.34315 5.84315 7 7.5 7H11.0996V5.7832C10.448 5.45353 10 4.78019 10 4C10 2.89543 10.8954 2 12 2ZM7.5 8.7998C6.83726 8.7998 6.2998 9.33726 6.2998 10V17C6.2998 17.6627 6.83726 18.2002 7.5 18.2002H16.5C17.1627 18.2002 17.7002 17.6627 17.7002 17V10C17.7002 9.33726 17.1627 8.7998 16.5 8.7998H7.5ZM3 10.7666C3.49706 10.7666 3.90039 11.1699 3.90039 11.667V15C3.90039 15.4971 3.49706 15.9004 3 15.9004C2.50294 15.9004 2.09961 15.4971 2.09961 15V11.667C2.09961 11.1699 2.50294 10.7666 3 10.7666ZM21 10.7666C21.4971 10.7666 21.9004 11.1699 21.9004 11.667V15C21.9004 15.4971 21.4971 15.9004 21 15.9004C20.5029 15.9004 20.0996 15.4971 20.0996 15V11.667C20.0996 11.1699 20.5029 10.7666 21 10.7666ZM9.5 11.0996C9.99706 11.0996 10.4004 11.5029 10.4004 12V14.5C10.4004 14.9971 9.99706 15.4004 9.5 15.4004C9.00294 15.4004 8.59961 14.9971 8.59961 14.5V12C8.59961 11.5029 9.00294 11.0996 9.5 11.0996ZM14.5 11.0996C14.9971 11.0996 15.4004 11.5029 15.4004 12V14.5C15.4004 14.9971 14.9971 15.4004 14.5 15.4004C14.0029 15.4004 13.5996 14.9971 13.5996 14.5V12C13.5996 11.5029 14.0029 11.0996 14.5 11.0996ZM12 3.5C11.7239 3.5 11.5 3.72386 11.5 4C11.5 4.27614 11.7239 4.5 12 4.5C12.2761 4.5 12.5 4.27614 12.5 4C12.5 3.72386 12.2761 3.5 12 3.5Z",fill:"currentColor"},null,-1)])])}const G3e=kt({name:"kimi-robot",render:Z3e}),Y3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function X3e(e,t){return y(),M("svg",Y3e,[...t[0]||(t[0]=[C("path",{d:"M11.5 3C16.1944 3 20 6.80558 20 11.5C20 13.523 19.2933 15.381 18.1132 16.8404L21.1364 19.8636C21.4879 20.2151 21.4879 20.7849 21.1364 21.1364C20.7849 21.4879 20.2151 21.4879 19.8636 21.1364L16.8404 18.1132C15.381 19.2933 13.523 20 11.5 20C6.80558 20 3 16.1944 3 11.5C3 6.80558 6.80558 3 11.5 3ZM11.5 18.2C15.2003 18.2 18.2 15.2003 18.2 11.5C18.2 7.79969 15.2003 4.8 11.5 4.8C7.79969 4.8 4.8 7.79969 4.8 11.5C4.8 15.2003 7.79969 18.2 11.5 18.2Z",fill:"currentColor"},null,-1)])])}const J3e=kt({name:"kimi-search",render:X3e}),Q3e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function e8e(e,t){return y(),M("svg",Q3e,[...t[0]||(t[0]=[C("path",{d:"M16.5364 10.1636C16.8879 10.5151 16.8879 11.0849 16.5364 11.4364C16.1849 11.7879 15.6151 11.7879 15.2636 11.4364L12.9 9.07281V17.1C12.9 17.597 12.4971 18 12 18C11.503 18 11.1 17.597 11.1 17.1V9.07281L8.73641 11.4364C8.38494 11.7879 7.81509 11.7879 7.46362 11.4364C7.11214 11.0849 7.11214 10.5151 7.46362 10.1636L11.3636 6.2636C11.7151 5.91211 12.2849 5.91211 12.6364 6.2636L16.5364 10.1636Z",fill:"currentColor"},null,-1)])])}const t8e=kt({name:"kimi-send",render:e8e}),n8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function o8e(e,t){return y(),M("svg",n8e,[...t[0]||(t[0]=[C("path",{d:"M16.0404 12C16.0404 9.76874 14.2313 7.9596 12.0001 7.9596C9.76883 7.9596 7.95972 9.76874 7.95972 12C7.95972 14.2313 9.76883 16.0404 12.0001 16.0404C14.2313 16.0404 16.0404 14.2313 16.0404 12ZM14.2222 12C14.2222 13.2271 13.2271 14.2222 12 14.2222C10.7729 14.2222 9.77783 13.2271 9.77783 12C9.77783 10.7729 10.7729 9.77778 12 9.77778C13.2271 9.77778 14.2222 10.7729 14.2222 12Z",fill:"currentColor"},null,-1),C("path",{d:"M9.91145 21.8009C9.29001 21.6797 8.76914 21.2612 8.50632 20.6922L8.07372 19.7556C7.88838 19.3544 7.43553 19.1048 6.95371 19.1549L5.89572 19.2647C5.2733 19.3293 4.64823 19.114 4.22298 18.6611C3.74343 18.1504 3.32454 17.6037 2.97033 17.0181C2.61571 16.4318 2.32839 15.8106 2.10407 15.1566C1.89769 14.5549 2.02148 13.8954 2.4089 13.3902L3.0376 12.5704C3.30043 12.2277 3.30042 11.7722 3.03758 11.4295L2.40413 10.6035C2.01474 10.0958 1.891 9.43198 2.10208 8.82826C2.55037 7.54612 3.27017 6.35997 4.22 5.34259C4.64518 4.8872 5.27275 4.67067 5.89701 4.73544L6.95383 4.84514C7.43561 4.89515 7.88844 4.6456 8.07377 4.24441L8.50266 3.31593C8.76494 2.74818 9.28448 2.33019 9.90423 2.20761C11.2916 1.9332 12.7148 1.93127 14.0885 2.19913C14.7099 2.32029 15.2308 2.73881 15.4937 3.3078L15.9263 4.24441C16.1116 4.6456 16.5644 4.89514 17.0462 4.84514L18.1043 4.73532C18.7267 4.67072 19.3518 4.88603 19.777 5.33886C20.2566 5.84953 20.6755 6.3963 21.0297 6.98193C21.3843 7.56823 21.6716 8.18942 21.8959 8.84339C22.1023 9.44509 21.9785 10.1046 21.5911 10.6098L20.9624 11.4295C20.6996 11.7722 20.6996 12.2278 20.9624 12.5705L21.5959 13.3964C21.9853 13.9042 22.109 14.568 21.8979 15.1717C21.4497 16.4538 20.7299 17.6399 19.7801 18.6573C19.3549 19.1128 18.7273 19.3294 18.103 19.2646L17.0462 19.1549C16.5645 19.1049 16.1116 19.3544 15.9263 19.7556L15.4974 20.6841C15.2351 21.2518 14.7156 21.6698 14.0958 21.7924C12.7083 22.0668 11.2852 22.0687 9.91145 21.8009ZM13.7432 20.0088C13.7844 20.0006 13.8259 19.9673 13.847 19.9216L14.2758 18.9931C14.7915 17.8768 15.9886 17.2171 17.2341 17.3464L18.2909 17.4561C18.3649 17.4638 18.4272 17.4423 18.4512 17.4166C19.2296 16.5828 19.8171 15.6146 20.1817 14.5716C20.1845 14.5636 20.1796 14.5373 20.1532 14.5029L19.5198 13.677C18.7564 12.6815 18.7564 11.3185 19.5198 10.323L20.1485 9.5033C20.1746 9.46927 20.1795 9.4429 20.1762 9.43327C19.9932 8.89965 19.7603 8.39623 19.4741 7.92293C19.1873 7.4489 18.846 7.00333 18.4517 6.58351C18.4272 6.55739 18.3656 6.53616 18.2921 6.54378L17.234 6.65361C15.9886 6.78287 14.7915 6.12317 14.2758 5.00689L13.8432 4.07027C13.822 4.02448 13.7811 3.9916 13.7406 3.98371C12.5983 3.76097 11.4132 3.76258 10.2571 3.99124C10.2158 3.99941 10.1744 4.03271 10.1533 4.07842L9.72441 5.00689C9.20875 6.12317 8.01164 6.7829 6.76619 6.6536L5.70942 6.54391C5.63535 6.53623 5.573 6.55774 5.54905 6.5834C4.77067 7.41713 4.18312 8.38534 3.81845 9.42835C3.81564 9.43637 3.82054 9.46265 3.84693 9.49706L4.48038 10.323C5.24381 11.3185 5.24383 12.6815 4.48041 13.6769L3.85171 14.4967C3.82561 14.5307 3.82066 14.5571 3.82396 14.5667C4.00701 15.1004 4.23986 15.6038 4.52613 16.0771C4.81284 16.5511 5.15421 16.9967 5.54845 17.4165C5.57298 17.4426 5.63461 17.4638 5.70811 17.4562L6.76608 17.3464C8.01157 17.2171 9.20871 17.8768 9.72438 18.9932L10.157 19.9297C10.1781 19.9755 10.2191 20.0084 10.2595 20.0163C11.4018 20.239 12.587 20.2374 13.7432 20.0088Z",fill:"currentColor"},null,-1)])])}const s8e=kt({name:"kimi-setting",render:o8e}),i8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function r8e(e,t){return y(),M("svg",i8e,[...t[0]||(t[0]=[C("path",{d:"M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7Z",fill:"currentColor"},null,-1),C("path",{d:"M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z",fill:"currentColor"},null,-1),C("path",{d:"M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z",fill:"currentColor"},null,-1)])])}const l8e=kt({name:"kimi-shield-question",render:r8e}),a8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function u8e(e,t){return y(),M("svg",a8e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.90005 12C2.90005 11.503 3.303 11.1 3.80005 11.1H12.2939L9.38588 8.19197C9.03441 7.8405 9.03441 7.27065 9.38588 6.91918C9.73735 6.56771 10.3072 6.56771 10.6587 6.91918L15.1031 11.3636C15.2719 11.5324 15.3667 11.7613 15.3667 12C15.3667 12.2387 15.2719 12.4676 15.1031 12.6364L10.6587 17.0809C10.3072 17.4323 9.73735 17.4323 9.38588 17.0809C9.03441 16.7294 9.03441 16.1595 9.38588 15.8081L12.2939 12.9H3.80005C3.303 12.9 2.90005 12.4971 2.90005 12ZM13.5874 20C13.5874 19.503 13.9904 19.1 14.4874 19.1H18.043C18.2758 19.1 18.4991 19.0075 18.6637 18.8429C18.8283 18.6783 18.9208 18.455 18.9208 18.2222V5.7778C18.9208 5.545 18.8283 5.32174 18.6637 5.15712C18.499 4.9925 18.2758 4.90002 18.043 4.90002H14.4874C13.9904 4.90002 13.5874 4.49708 13.5874 4.00002C13.5874 3.50297 13.9904 3.10003 14.4874 3.10003H18.043C18.7532 3.10003 19.4343 3.38215 19.9365 3.88433C20.4386 4.38651 20.7208 5.06761 20.7208 5.7778V18.2222C20.7208 18.9324 20.4386 19.6135 19.9365 20.1157C19.4343 20.6179 18.7532 20.9 18.043 20.9H14.4874C13.9904 20.9 13.5874 20.4971 13.5874 20Z",fill:"currentColor"},null,-1)])])}const c8e=kt({name:"kimi-sign-in",render:u8e}),d8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function f8e(e,t){return y(),M("svg",d8e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M20.6364 11.3636C20.9879 11.7151 20.9879 12.2849 20.6364 12.6364L16.1919 17.0808C15.8405 17.4323 15.2706 17.4323 14.9192 17.0808C14.5677 16.7293 14.5677 16.1595 14.9192 15.808L17.8272 12.9H9.33333C8.83627 12.9 8.43333 12.497 8.43333 12C8.43333 11.5029 8.83627 11.1 9.33333 11.1H17.8272L14.9192 8.19193C14.5677 7.84046 14.5677 7.27061 14.9192 6.91914C15.2706 6.56766 15.8405 6.56766 16.1919 6.91914L20.6364 11.3636ZM10.2333 3.99998C10.2333 4.49703 9.83038 4.89998 9.33333 4.89998H5.77777C5.54497 4.89998 5.3217 4.99246 5.15709 5.15707C4.99247 5.32169 4.89999 5.54495 4.89999 5.77775V18.2222C4.89999 18.455 4.99247 18.6783 5.15709 18.8429C5.32171 19.0075 5.54497 19.1 5.77777 19.1H9.33333C9.83038 19.1 10.2333 19.5029 10.2333 20C10.2333 20.497 9.83038 20.9 9.33333 20.9H5.77777C5.06758 20.9 4.38648 20.6179 3.8843 20.1157C3.38212 19.6135 3.09999 18.9324 3.09999 18.2222V5.77775C3.09999 5.06756 3.38212 4.38646 3.8843 3.88428C4.38648 3.3821 5.06758 3.09998 5.77777 3.09998H9.33333C9.83038 3.09998 10.2333 3.50292 10.2333 3.99998Z",fill:"currentColor"},null,-1)])])}const p8e=kt({name:"kimi-sign-out",render:f8e}),h8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function m8e(e,t){return y(),M("svg",h8e,[...t[0]||(t[0]=[iu('<path d="M4 6H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M18.0 6H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="16" cy="6" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M4 12H6.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M10.5 12H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="8.5" cy="12" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M4 18H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M18.0 18H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="16" cy="18" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle>',9)])])}const g8e=kt({name:"kimi-sliders",render:m8e}),v8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function y8e(e,t){return y(),M("svg",v8e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M7.78027 8.90405C7.5 9.45411 7.5 10.1742 7.5 11.6144V12.3856C7.5 13.8258 7.5 14.5459 7.78027 15.096C8.02681 15.5798 8.42019 15.9732 8.90405 16.2197C9.45411 16.5 10.1742 16.5 11.6144 16.5H12.3856C13.8258 16.5 14.5459 16.5 15.096 16.2197C15.5798 15.9732 15.9732 15.5798 16.2197 15.096C16.5 14.5459 16.5 13.8258 16.5 12.3856V11.6144C16.5 10.1742 16.5 9.45411 16.2197 8.90405C15.9732 8.42019 15.5798 8.02681 15.096 7.78027C14.5459 7.5 13.8258 7.5 12.3856 7.5H11.6144C10.1742 7.5 9.45411 7.5 8.90405 7.78027C8.42019 8.02681 8.02681 8.42019 7.78027 8.90405Z",fill:"currentColor"},null,-1)])])}const k8e=kt({name:"kimi-stop",render:y8e}),b8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function C8e(e,t){return y(),M("svg",b8e,[...t[0]||(t[0]=[C("path",{d:"M7.01562 3.41459C7.4446 3.16449 7.9954 3.30924 8.24609 3.73784C8.49645 4.167 8.35189 4.71868 7.92285 4.96928C5.51497 6.37506 3.90054 8.98498 3.90039 11.9703C3.90076 16.4435 7.52672 20.0699 12 20.0699C16.4733 20.0699 20.0992 16.4435 20.0996 11.9703C20.0996 11.2291 20 10.5116 19.8145 9.83159C19.6838 9.35222 19.967 8.85702 20.4463 8.72612C20.9256 8.59541 21.4207 8.87778 21.5518 9.35698C21.7792 10.1901 21.9004 11.0674 21.9004 11.9703C21.9 17.4376 17.4674 21.8697 12 21.8697C6.53261 21.8697 2.09998 17.4376 2.09961 11.9703C2.09976 8.31904 4.07782 5.12972 7.01562 3.41459ZM8.39258 8.24077C8.75015 7.89591 9.3199 7.90591 9.66504 8.26323C10.01 8.62076 9.99985 9.19051 9.64258 9.53569C9.00203 10.1541 8.60558 11.02 8.60547 11.979C8.60584 13.8536 10.1253 15.3736 12 15.3736C13.8746 15.3735 15.3942 13.8536 15.3945 11.979C15.3945 11.6847 15.3577 11.3989 15.2881 11.1285C15.1646 10.6474 15.4536 10.1568 15.9346 10.0328C16.4158 9.9089 16.9071 10.1991 17.0312 10.6802C17.1383 11.096 17.1943 11.5321 17.1943 11.979C17.194 14.8477 14.8688 17.1733 12 17.1734C9.1312 17.1734 6.80506 14.8478 6.80469 11.979C6.8048 10.5117 7.41519 9.18431 8.39258 8.24077ZM11.5459 1.12651C11.8216 0.965605 12.1631 0.963306 12.4414 1.11967L19.1953 4.91752C19.4859 5.08108 19.662 5.39277 19.6533 5.72612C19.6443 6.05972 19.4515 6.36154 19.1523 6.50932L12.9004 9.5933V12.2583C12.9004 12.7554 12.4971 13.1587 12 13.1587C11.5029 13.1587 11.0996 12.7554 11.0996 12.2583V1.90385C11.0999 1.58444 11.2702 1.2878 11.5459 1.12651ZM12.9004 7.58549L16.8252 5.64897L12.9004 3.44194V7.58549Z",fill:"currentColor"},null,-1)])])}const w8e=kt({name:"kimi-target",render:C8e}),_8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function x8e(e,t){return y(),M("svg",_8e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.9893 6.60743C20.5897 6.60757 21.8877 7.8926 21.8877 9.47736C21.8877 10.7416 21.0607 11.8129 19.9141 12.1955V14.257C19.914 15.8428 18.6152 17.1288 17.0137 17.1289H12.8438V20.1381C12.8437 20.6301 12.4412 21.0293 11.9443 21.0296C11.4473 21.0296 11.044 20.6302 11.0439 20.1381V16.4356C11.0441 15.8343 11.5363 15.3461 12.1436 15.3458H17.0137C17.6211 15.3457 18.1133 14.8585 18.1133 14.257V12.2129C16.9408 11.8451 16.0909 10.7598 16.0908 9.47736C16.0908 7.89251 17.3887 6.60743 18.9893 6.60743ZM18.9893 8.38953C18.3828 8.38953 17.8906 8.87684 17.8906 9.47736C17.8907 10.0778 18.3828 10.5642 18.9893 10.5642C19.5956 10.5641 20.0869 10.0777 20.0869 9.47736C20.0869 8.87693 19.5956 8.38967 18.9893 8.38953Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M4.89844 6.60743C6.49899 6.60747 7.79688 7.89254 7.79688 9.47736C7.79684 10.7388 6.97371 11.8078 5.83105 12.1926V14.4021C5.83105 15.0036 6.32315 15.4918 6.93066 15.4918H8.37109C8.86789 15.492 9.27038 15.8905 9.27051 16.3824C9.27051 16.8744 8.86797 17.2737 8.37109 17.2739H6.93066C5.32904 17.2739 4.03027 15.9879 4.03027 14.4021V12.2158C2.85382 11.8504 2.00004 10.7627 2 9.47736C2 7.89251 3.29784 6.60743 4.89844 6.60743ZM4.89844 8.38953C4.29196 8.38953 3.7998 8.87684 3.7998 9.47736C3.79985 10.0778 4.29198 10.5642 4.89844 10.5642C5.50485 10.5642 5.99605 10.0778 5.99609 9.47736C5.99609 8.87687 5.50488 8.38958 4.89844 8.38953Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.9434 2.9707C13.5439 2.97075 14.8418 4.25581 14.8418 5.84063C14.8418 7.11413 14.0035 8.1923 12.8438 8.56745V13.0135C12.8436 13.5056 12.4403 13.9041 11.9434 13.9041C11.4466 13.9039 11.0431 13.5055 11.043 13.0135V8.56745C9.8836 8.19209 9.04496 7.11387 9.04492 5.84063C9.04492 4.25592 10.343 2.97093 11.9434 2.9707ZM11.9434 4.75281C11.3371 4.75303 10.8447 5.24026 10.8447 5.84063C10.8448 6.44097 11.3371 6.92726 11.9434 6.92749C12.5498 6.92745 13.041 6.44108 13.041 5.84063C13.041 5.24014 12.5498 4.75285 11.9434 4.75281Z",fill:"currentColor"},null,-1)])])}const S8e=kt({name:"kimi-task",render:x8e}),A8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function M8e(e,t){return y(),M("svg",A8e,[...t[0]||(t[0]=[C("path",{d:"M16.5293 15.0596C16.9496 15.1021 17.2772 15.4572 17.2773 15.8887C17.2773 16.3202 16.9497 16.6753 16.5293 16.7178L16.4443 16.7217H12C11.5399 16.7216 11.167 16.3488 11.167 15.8887C11.1671 15.4286 11.54 15.0558 12 15.0557H16.4443L16.5293 15.0596Z",fill:"currentColor"},null,-1),C("path",{d:"M6.96582 7.52246C7.27077 7.21751 7.75375 7.1983 8.08105 7.46484L8.14453 7.52246L10.8232 10.2002C11.5102 10.8872 11.5102 12.0014 10.8232 12.6885L8.14453 15.3672L8.08105 15.4248C7.75377 15.6913 7.27075 15.6721 6.96582 15.3672C6.66114 15.0621 6.64234 14.5791 6.90918 14.252L6.96582 14.1885L9.64453 11.5098C9.68057 11.4736 9.68062 11.415 9.64453 11.3789L6.96582 8.7002C6.64116 8.37488 6.6411 7.84774 6.96582 7.52246Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17 3.09961C19.1539 3.09966 20.9004 4.84612 20.9004 7V17C20.9004 19.1539 19.1539 20.9003 17 20.9004H7C4.84609 20.9004 3.09961 19.1539 3.09961 17V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H17ZM7 4.90039C5.8402 4.90039 4.90039 5.8402 4.90039 7V17C4.90039 18.1598 5.8402 19.0996 7 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V7C19.0996 5.84024 18.1598 4.90044 17 4.90039H7Z",fill:"currentColor"},null,-1)])])}const T8e=kt({name:"kimi-terminal",render:M8e}),E8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function I8e(e,t){return y(),M("svg",E8e,[...t[0]||(t[0]=[C("path",{d:"M16.9971 3.90597C15.9799 2.99725 14.7342 2.38312 13.394 2.12966C12.0538 1.8762 10.6699 1.99301 9.39111 2.46751C8.11236 2.94202 6.98721 3.75626 6.13676 4.82261C5.2863 5.88896 4.74274 7.16703 4.56457 8.5193C4.40455 9.70501 4.53253 10.9118 4.93767 12.0376C5.34281 13.1634 6.01318 14.175 6.89207 14.9868C7.43557 15.4634 7.87413 16.0477 8.17997 16.7027C8.48581 17.3577 8.65224 18.0691 8.66873 18.7918V18.926C8.66962 19.7412 8.99387 20.5229 9.57035 21.0993C10.1468 21.6758 10.9285 22.0001 11.7437 22.001H12.2604C13.0757 22.0001 13.8573 21.6758 14.4338 21.0993C15.0103 20.5229 15.3345 19.7412 15.3354 18.926V18.4685C15.3479 17.8297 15.4982 17.2011 15.7761 16.6258C16.0539 16.0505 16.4528 15.542 16.9454 15.1351C17.7442 14.4355 18.3853 13.5741 18.826 12.608C19.2668 11.642 19.4973 10.5932 19.5022 9.53136C19.5071 8.46948 19.2863 7.41869 18.8544 6.4486C18.4225 5.4785 17.7894 4.61125 16.9971 3.9043V3.90597ZM12.2604 20.3343H11.7437C11.3704 20.3339 11.0124 20.1853 10.7484 19.9213C10.4844 19.6573 10.3358 19.2993 10.3354 18.926C10.3354 18.926 10.3296 18.7093 10.3287 18.6676H13.6687V18.926C13.6683 19.2993 13.5198 19.6573 13.2558 19.9213C12.9917 20.1853 12.6338 20.3339 12.2604 20.3343ZM15.8437 13.8835C14.8949 14.7064 14.2097 15.7908 13.8737 17.001H12.8354V11.0143C13.3212 10.8426 13.742 10.5249 14.0403 10.1049C14.3387 9.68482 14.4999 9.18285 14.5021 8.66763C14.5021 8.44662 14.4143 8.23466 14.258 8.07838C14.1017 7.9221 13.8897 7.8343 13.6687 7.8343C13.4477 7.8343 13.2358 7.9221 13.0795 8.07838C12.9232 8.23466 12.8354 8.44662 12.8354 8.66763C12.8354 8.88865 12.7476 9.10061 12.5913 9.25689C12.435 9.41317 12.2231 9.50097 12.0021 9.50097C11.7811 9.50097 11.5691 9.41317 11.4128 9.25689C11.2565 9.10061 11.1687 8.88865 11.1687 8.66763C11.1687 8.44662 11.0809 8.23466 10.9247 8.07838C10.7684 7.9221 10.5564 7.8343 10.3354 7.8343C10.1144 7.8343 9.90242 7.9221 9.74614 8.07838C9.58986 8.23466 9.50207 8.44662 9.50207 8.66763C9.5042 9.18285 9.66547 9.68482 9.96381 10.1049C10.2621 10.5249 10.683 10.8426 11.1687 11.0143V17.001H10.0671C9.69123 15.7586 8.98633 14.6411 8.02707 13.7668C7.21286 13.0081 6.63267 12.0324 6.35496 10.9547C6.07725 9.87703 6.1136 8.7424 6.45974 7.68471C6.80588 6.62702 7.44735 5.69042 8.30846 4.98543C9.16956 4.28045 10.2144 3.83649 11.3196 3.70597C11.5487 3.68039 11.779 3.66759 12.0096 3.66763C13.4409 3.66338 14.8226 4.19149 15.8862 5.1493C16.5026 5.69896 16.9952 6.37337 17.3312 7.12782C17.6672 7.88227 17.839 8.69952 17.8352 9.5254C17.8314 10.3513 17.6522 11.1669 17.3092 11.9183C16.9663 12.6696 16.4677 13.3395 15.8462 13.8835H15.8437Z",fill:"currentColor"},null,-1)])])}const L8e=kt({name:"kimi-thinking",render:I8e}),$8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function N8e(e,t){return y(),M("svg",$8e,[...t[0]||(t[0]=[iu('<path d="M9.28994 4.92561C9.6436 4.57634 9.64716 4.0065 9.29789 3.65284C8.94862 3.29918 8.37878 3.29563 8.02512 3.6449L5.91339 5.73041L5.16642 4.95888C4.82067 4.60177 4.2509 4.59256 3.89379 4.9383C3.53668 5.28404 3.52747 5.85382 3.87321 6.21093L5.25245 7.63551C5.41956 7.80811 5.64874 7.90674 5.88897 7.90943C6.1292 7.91213 6.36053 7.81866 6.53146 7.64985L9.28994 4.92561Z" fill="currentColor"></path><path d="M12 5.10022C11.503 5.10022 11.1 5.50316 11.1 6.00022C11.1 6.49728 11.503 6.90022 12 6.90022L19.9965 6.90022C20.4935 6.90022 20.8965 6.49728 20.8965 6.00022C20.8965 5.50316 20.4935 5.10022 19.9965 5.10022L12 5.10022Z" fill="currentColor"></path><path d="M12 11.1002C11.503 11.1002 11.1 11.5032 11.1 12.0002C11.1 12.4973 11.503 12.9002 12 12.9002H19.9965C20.4935 12.9002 20.8965 12.4973 20.8965 12.0002C20.8965 11.5032 20.4935 11.1002 19.9965 11.1002L12 11.1002Z" fill="currentColor"></path><path d="M11.1 18.0002C11.1 17.5032 11.503 17.1002 12 17.1002L19.9965 17.1002C20.4935 17.1002 20.8965 17.5032 20.8965 18.0002C20.8965 18.4973 20.4935 18.9002 19.9965 18.9002H12C11.503 18.9002 11.1 18.4973 11.1 18.0002Z" fill="currentColor"></path><path d="M9.29789 9.77064C9.64716 10.1243 9.6436 10.6941 9.28994 11.0434L6.53146 13.7676C6.36053 13.9365 6.1292 14.0299 5.88897 14.0272C5.64874 14.0245 5.41956 13.9259 5.25245 13.7533L3.87321 12.3287C3.52747 11.9716 3.53668 11.4018 3.89379 11.0561C4.2509 10.7104 4.82067 10.7196 5.16642 11.0767L5.91339 11.8482L8.02512 9.76269C8.37878 9.41342 8.94862 9.41698 9.29789 9.77064Z" fill="currentColor"></path><path d="M9.29789 15.7436C9.64716 16.0973 9.6436 16.6671 9.28994 17.0164L6.53146 19.7406C6.36053 19.9094 6.1292 20.0029 5.88897 20.0002C5.64874 19.9975 5.41956 19.8989 5.25245 19.7263L3.87321 18.3017C3.52747 17.9446 3.53668 17.3748 3.89379 17.0291C4.2509 16.6833 4.82067 16.6926 5.16642 17.0497L5.91339 17.8212L8.02512 15.7357C8.37878 15.3864 8.94862 15.39 9.29789 15.7436Z" fill="currentColor"></path>',6)])])}const F8e=kt({name:"kimi-todo",render:N8e}),R8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function O8e(e,t){return y(),M("svg",R8e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M8.09752 2.19507C8.5421 1.97278 9.08271 2.15298 9.305 2.59756L10.0562 4.10005H13.5C13.9971 4.10005 14.4 4.50299 14.4 5.00005C14.4 5.49711 13.9971 5.90005 13.5 5.90005H12.3106C12.2556 6.2319 12.1667 6.64073 12.0226 7.0987C11.7254 8.04355 11.191 9.20402 10.2334 10.3239C11.4166 11.196 12.5606 11.7524 13.4512 12.0987C13.978 12.3036 14.4136 12.434 14.7124 12.5122L14.7348 12.5181L15.695 10.5976C15.8475 10.2927 16.1591 10.1 16.5 10.1C16.8409 10.1 17.1525 10.2927 17.305 10.5976L20.7969 17.5814L20.8044 17.5959L20.8137 17.615L21.805 19.5976C22.0273 20.0421 21.8471 20.5827 21.4025 20.805C20.9579 21.0273 20.4173 20.8471 20.195 20.4025L19.4438 18.9H13.5562L12.805 20.4025C12.5827 20.8471 12.0421 21.0273 11.5975 20.805C11.1529 20.5827 10.9727 20.0421 11.195 19.5976L12.1863 17.615C12.1917 17.6036 12.1973 17.5924 12.2031 17.5814L13.9146 14.1583C13.6034 14.0667 13.2256 13.9423 12.7988 13.7764C11.7294 13.3605 10.3442 12.6802 8.92538 11.5924C7.79753 12.5167 6.69473 13.0764 5.83285 13.4112C5.33899 13.603 4.92286 13.7216 4.62401 13.7931C4.47449 13.8288 4.35399 13.8529 4.26741 13.8684C4.2241 13.8762 4.18924 13.8818 4.16343 13.8858L4.13156 13.8904L4.12084 13.8919L4.11682 13.8924L4.11514 13.8927C4.11514 13.8927 4.11368 13.8928 4.00001 13L4.11368 13.8928C3.62061 13.9556 3.17 13.6068 3.10722 13.1137C3.0446 12.6219 3.39148 12.1723 3.88256 12.1077L3.94947 12.0967C4.00428 12.0869 4.09114 12.0698 4.20543 12.0424C4.43422 11.9877 4.77156 11.8924 5.18106 11.7334C5.84103 11.477 6.68484 11.0564 7.56458 10.3753C7.15054 9.93496 6.78945 9.48388 6.50421 9.10102C6.26672 8.78224 6.07517 8.50172 5.94227 8.29973C5.87571 8.19858 5.82359 8.11671 5.78748 8.05909C5.76942 8.03027 5.75535 8.00749 5.74545 7.99135L5.73377 7.9722L5.73032 7.96651L5.72864 7.96371C5.71133 7.9349 5.69582 7.9055 5.68208 7.87566C5.49265 7.46416 5.6393 6.96717 6.03659 6.72853C6.09037 6.69623 6.14617 6.6702 6.20315 6.65023C6.59739 6.51205 7.04758 6.66421 7.27129 7.03623L7.27266 7.0385L7.28001 7.05054C7.28695 7.06186 7.29793 7.07964 7.31274 7.10328C7.34239 7.15059 7.38731 7.2212 7.44595 7.31032C7.56343 7.48886 7.73484 7.73997 7.94765 8.02562C8.21085 8.37889 8.52772 8.77187 8.8756 9.14201C9.64226 8.24147 10.0681 7.3133 10.3056 6.55854C10.381 6.3186 10.4372 6.09683 10.4791 5.90005H9.51951C9.50696 5.90031 9.49442 5.90031 9.48191 5.90005H4.00001C3.50296 5.90005 3.10001 5.49711 3.10001 5.00005C3.10001 4.50299 3.50296 4.10005 4.00001 4.10005H8.04378L7.69503 3.40254C7.67314 3.35877 7.65516 3.31407 7.64094 3.26883C7.51078 2.8546 7.69671 2.39547 8.09752 2.19507ZM16.5 13.0125L18.5438 17.1H14.4562L16.5 13.0125Z",fill:"currentColor"},null,-1),C("path",{d:"M15.1 4.00007C15.1 3.50301 15.5029 3.10007 16 3.10007H18C19.6016 3.10007 20.9 4.39844 20.9 6.00007V8.00007C20.9 8.49712 20.497 8.90007 20 8.90007C19.5029 8.90007 19.1 8.49712 19.1 8.00007V6.00007C19.1 5.39255 18.6075 4.90007 18 4.90007H16C15.5029 4.90007 15.1 4.49712 15.1 4.00007Z",fill:"currentColor"},null,-1),C("path",{d:"M3.99998 15.1001C4.49703 15.1001 4.89998 15.503 4.89998 16.0001V18.0001C4.89998 18.6076 5.39246 19.1001 5.99998 19.1001H7.99998C8.49703 19.1001 8.89998 19.503 8.89998 20.0001C8.89998 20.4971 8.49703 20.9001 7.99998 20.9001H5.99998C4.39835 20.9001 3.09998 19.6017 3.09998 18.0001V16.0001C3.09998 15.503 3.50292 15.1001 3.99998 15.1001Z",fill:"currentColor"},null,-1)])])}const P8e=kt({name:"kimi-translate",render:O8e}),D8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function B8e(e,t){return y(),M("svg",D8e,[...t[0]||(t[0]=[C("path",{d:"M8.10001 3C8.10001 2.50294 8.50295 2.1 9.00001 2.1H15C15.4971 2.1 15.9 2.50294 15.9 3C15.9 3.49706 15.4971 3.9 15 3.9H9.00001C8.50295 3.9 8.10001 3.49706 8.10001 3Z",fill:"currentColor"},null,-1),C("path",{d:"M10 15.9C9.50295 15.9 9.10001 15.4971 9.10001 15L9.10001 10C9.10001 9.50294 9.50295 9.1 10 9.1C10.4971 9.1 10.9 9.50294 10.9 10L10.9 15C10.9 15.4971 10.4971 15.9 10 15.9Z",fill:"currentColor"},null,-1),C("path",{d:"M13.1 15C13.1 15.4971 13.5029 15.9 14 15.9C14.4971 15.9 14.9 15.4971 14.9 15L14.9 10C14.9 9.50294 14.4971 9.1 14 9.1C13.5029 9.1 13.1 9.50294 13.1 10V15Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.10001 6C2.10001 5.50294 2.50295 5.1 3.00001 5.1H4.99152C4.99785 5.09993 5.00417 5.09993 5.01048 5.1H18.9895C18.9958 5.09993 19.0021 5.09993 19.0085 5.1H21C21.4971 5.1 21.9 5.50294 21.9 6C21.9 6.49706 21.4971 6.9 21 6.9H19.8281L18.8448 18.6993C18.7412 19.9432 17.7013 20.9 16.4531 20.9H7.54686C6.29865 20.9 5.25881 19.9432 5.15515 18.6993L4.17188 6.9H3.00001C2.50295 6.9 2.10001 6.49706 2.10001 6ZM5.97811 6.9L18.0219 6.9L17.0511 18.5498C17.0251 18.8608 16.7652 19.1 16.4531 19.1H7.54686C7.23481 19.1 6.97485 18.8608 6.94893 18.5498L5.97811 6.9Z",fill:"currentColor"},null,-1)])])}const H8e=kt({name:"kimi-trash",render:B8e}),z8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function W8e(e,t){return y(),M("svg",z8e,[...t[0]||(t[0]=[C("path",{d:"M7.36336 3.3634C7.71483 3.01192 8.28533 3.01192 8.6368 3.3634C8.98817 3.71488 8.98824 4.2854 8.6368 4.63683L6.17391 7.09972H15.0001C18.2585 7.09977 20.9005 9.74166 20.9005 13.0001C20.9004 16.2585 18.2585 18.9005 15.0001 18.9005H7.00008C6.50307 18.9005 6.09976 18.4971 6.09969 18.0001C6.09969 17.5031 6.50302 17.0997 7.00008 17.0997H15.0001C17.2644 17.0997 19.0996 15.2644 19.0997 13.0001C19.0997 10.7358 17.2644 8.90055 15.0001 8.90051H6.17391L8.6368 11.3634L8.69832 11.4318C8.98668 11.7853 8.96632 12.3073 8.6368 12.6368C8.30728 12.9663 7.78521 12.9867 7.43172 12.6984L7.36336 12.6368L3.36336 8.63683C3.33098 8.60445 3.30286 8.56908 3.27645 8.53332C3.25597 8.50559 3.23607 8.47741 3.21883 8.44738C3.20492 8.42311 3.19221 8.39837 3.18074 8.37316C3.1764 8.36365 3.17109 8.35453 3.16707 8.34484C3.1627 8.33427 3.1593 8.32331 3.15535 8.31261C3.12946 8.24274 3.11237 8.16872 3.10457 8.09191C3.09258 7.97426 3.10262 7.85446 3.1368 7.74035C3.14281 7.72035 3.15094 7.70114 3.15828 7.68176C3.16165 7.67283 3.16341 7.66325 3.16707 7.65441C3.17216 7.64216 3.17806 7.63025 3.18367 7.61828C3.19055 7.60356 3.19744 7.58874 3.20516 7.57433C3.24709 7.49624 3.3012 7.42556 3.36336 7.3634L7.36336 3.3634Z",fill:"currentColor"},null,-1)])])}const U8e=kt({name:"kimi-undo",render:W8e}),j8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function V8e(e,t){return y(),M("svg",j8e,[...t[0]||(t[0]=[C("path",{d:"M11.9997 12.8779C16.0197 12.878 19.4393 15.3848 20.7048 18.8828C21.0812 19.9234 20.2782 20.8962 19.2038 21.0137L18.9861 21.0264H5.0134L4.79562 21.0137C3.7213 20.8961 2.91743 19.9233 3.29367 18.8828C4.55905 15.3847 7.9797 12.8781 11.9997 12.8779ZM11.9997 14.6777C8.84467 14.6779 6.17462 16.5794 5.09152 19.2256H18.9079C17.8248 16.5793 15.1549 14.6778 11.9997 14.6777ZM12.2312 3.00586C14.6088 3.1264 16.4997 5.09239 16.4997 7.5L16.4939 7.73145C16.3734 10.1091 14.4073 11.9999 11.9997 12C9.59225 11.9998 7.62604 10.109 7.50558 7.73145L7.49973 7.5C7.49973 5.01485 9.51462 3.00021 11.9997 3L12.2312 3.00586ZM11.9997 4.7998C10.5087 4.80001 9.29953 6.00896 9.29953 7.5C9.29953 8.99104 10.5087 10.2 11.9997 10.2002C13.4908 10.2001 14.6999 8.99112 14.6999 7.5C14.6999 6.00888 13.4908 4.79989 11.9997 4.7998Z",fill:"currentColor"},null,-1)])])}const q8e=kt({name:"kimi-user",render:V8e}),K8e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Z8e(e,t){return y(),M("svg",K8e,[...t[0]||(t[0]=[C("path",{d:"M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z",fill:"currentColor"},null,-1),C("path",{d:"M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z",fill:"currentColor"},null,-1)])])}const G8e=kt({name:"kimi-warning",render:Z8e}),Y8e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function X8e(e,t){return y(),M("svg",Y8e,[...t[0]||(t[0]=[C("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[C("path",{d:"M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm11-2v16"}),C("path",{d:"m9 10l2 2l-2 2"})],-1)])])}const J8e=kt({name:"tabler-layout-sidebar-right-collapse",render:X8e}),Q8e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function eye(e,t){return y(),M("svg",Q8e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3L18 10a3 3 0 0 0-6-6l-6.5 6.5a4.5 4.5 0 0 0 9 9L21 13"},null,-1)])])}const tye=kt({name:"tabler-paperclip",render:eye}),nye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function oye(e,t){return y(),M("svg",nye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12A2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3m16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5"},null,-1)])])}const sye=kt({name:"ri-braces-line",render:oye}),iye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function rye(e,t){return y(),M("svg",iye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M9 3V1H7v2H3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4V1h-2v2zm-5 7h16v9H4zm0-5h3v1h2V5h6v1h2V5h3v3H4zm5.879 5.964L12 13.086l2.121-2.122l1.415 1.415l-2.122 2.121l2.121 2.121l-1.414 1.414L12 15.915l-2.121 2.12l-1.415-1.414l2.122-2.12l-2.122-2.122z"},null,-1)])])}const lye=kt({name:"ri-calendar-close-line",render:rye}),aye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function uye(e,t){return y(),M("svg",aye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M7 3V1h2v2h6V1h2v2h4a1 1 0 0 1 1 1v5h-2V5h-3v2h-2V5H9v2H7V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm10 9a4 4 0 1 0 0 8a4 4 0 0 0 0-8m-6 4a6 6 0 1 1 12 0a6 6 0 0 1-12 0m5-3v3.414l2.293 2.293l1.414-1.414L18 15.586V13z"},null,-1)])])}const cye=kt({name:"ri-calendar-schedule-line",render:uye}),dye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function fye(e,t){return y(),M("svg",dye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1zm11 10H4v8h16zM8 14v2H6v-2zm10 0v2h-8v-2zM7 5H4v4h16V5h-3v2h-2V5H9v2H7z"},null,-1)])])}const pye=kt({name:"ri-calendar-todo-line",render:fye}),hye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function mye(e,t){return y(),M("svg",hye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414z"},null,-1)])])}const gye=kt({name:"ri-code-line",render:mye}),vye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function yye(e,t){return y(),M("svg",vye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-4-7h8a4 4 0 0 1-8 0m0-2a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m8 0a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3"},null,-1)])])}const kye=kt({name:"ri-emotion-line",render:yye}),bye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Cye(e,t){return y(),M("svg",bye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"},null,-1)])])}const wye=kt({name:"ri-external-link-line",render:Cye}),_ye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function xye(e,t){return y(),M("svg",_ye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12 3c5.392 0 9.878 3.88 10.819 9c-.94 5.12-5.427 9-10.819 9s-9.878-3.88-10.818-9C2.122 6.88 6.608 3 12 3m0 16a9.005 9.005 0 0 0 8.778-7a9.005 9.005 0 0 0-17.555 0A9.005 9.005 0 0 0 12 19m0-2.5a4.5 4.5 0 1 1 0-9a4.5 4.5 0 0 1 0 9m0-2a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5"},null,-1)])])}const Sye=kt({name:"ri-eye-line",render:xye}),Aye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Mye(e,t){return y(),M("svg",Aye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M17.883 19.297A10.95 10.95 0 0 1 12 21c-5.392 0-9.878-3.88-10.818-9A11 11 0 0 1 4.52 5.935L1.394 2.808l1.414-1.414l19.799 19.798l-1.414 1.415zM5.936 7.35A8.97 8.97 0 0 0 3.223 12a9.005 9.005 0 0 0 13.201 5.838l-2.028-2.028A4.5 4.5 0 0 1 8.19 9.604zm6.978 6.978l-3.242-3.241a2.5 2.5 0 0 0 3.241 3.241m7.893 2.265l-1.431-1.431A8.9 8.9 0 0 0 20.778 12A9.005 9.005 0 0 0 9.552 5.338L7.974 3.76C9.221 3.27 10.58 3 12 3c5.392 0 9.878 3.88 10.819 9a10.95 10.95 0 0 1-2.012 4.593m-9.084-9.084Q11.86 7.5 12 7.5a4.5 4.5 0 0 1 4.492 4.778z"},null,-1)])])}const Tye=kt({name:"ri-eye-off-line",render:Mye}),Eye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Iye(e,t){return y(),M("svg",Eye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M15 4H5v16h14V8h-4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008zM11 11V8h2v3h3v2h-3v3h-2v-3H8v-2z"},null,-1)])])}const Lye=kt({name:"ri-file-add-line",render:Iye}),$ye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Nye(e,t){return y(),M("svg",$ye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M13 9h8L11 24v-9H4l9-15zm-2 2V7.22L7.532 13H13v4.394L17.263 11z"},null,-1)])])}const Fye=kt({name:"ri-flashlight-line",render:Nye}),Rye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Oye(e,t){return y(),M("svg",Rye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])}const Pye=kt({name:"ri-folder-fill",render:Oye}),Dye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Bye(e,t){return y(),M("svg",Dye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M6 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2M3 6a3 3 0 1 1 4 2.83V9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-.17a3.001 3.001 0 1 1 2 0V9a4 4 0 0 1-4 4h-2v2.17a3.001 3.001 0 1 1-2 0V13H9a4 4 0 0 1-4-4v-.17A3 3 0 0 1 3 6m15-1a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-6 12a1 1 0 1 0 0 2a1 1 0 0 0 0-2"},null,-1)])])}const Hye=kt({name:"ri-git-fork-line",render:Bye}),zye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Wye(e,t){return y(),M("svg",zye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M15 5h2a2 2 0 0 1 2 2v8.17a3.001 3.001 0 1 1-2 0V7h-2v3l-4.5-4L15 2zM5 8.83a3.001 3.001 0 1 1 2 0v6.34a3.001 3.001 0 1 1-2 0zM6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m0 12a1 1 0 1 0 0-2a1 1 0 0 0 0 2m12 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2"},null,-1)])])}const Uye=kt({name:"ri-git-pull-request-line",render:Wye}),jye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Vye(e,t){return y(),M("svg",jye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M2 18h7v2H2zm0-7h9v2H2zm0-7h20v2H2zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4 4 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391a4 4 0 0 1-1.435.83L19 21h-2l-.24-1.196a4 4 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4 4 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196a4 4 0 0 1 1.434.83M18 18a2 2 0 1 0 0-4a2 2 0 0 0 0 4"},null,-1)])])}const qye=kt({name:"ri-list-settings-line",render:Vye}),Kye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Zye(e,t){return y(),M("svg",Kye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M10 2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H8v2h5V9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H8v6h5v-1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H7a1 1 0 0 1-1-1V8H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm9 16h-4v2h4zm0-8h-4v2h4zM9 4H5v2h4z"},null,-1)])])}const Gye=kt({name:"ri-node-tree",render:Zye}),Yye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Xye(e,t){return y(),M("svg",Yye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m13.827 1.69l8.486 8.485l-1.415 1.414l-.707-.707l-4.242 4.243l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243l1.414-1.414l3.536-.707l4.242-4.243l-.707-.707zm.707 3.536l-4.67 4.67l-2.822.565l6.5 6.5l.564-2.822l4.671-4.67z"},null,-1)])])}const Jye=kt({name:"ri-pushpin-line",render:Xye}),Qye={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function e5e(e,t){return y(),M("svg",Qye,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M20 4v12h3l-4 5l-4-5h3V4zm-8 14v2H3v-2zm2-7v2H3v-2zm0-7v2H3V4z"},null,-1)])])}const t5e=kt({name:"ri-sort-desc",render:e5e}),n5e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function o5e(e,t){return y(),M("svg",n5e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928z"},null,-1)])])}const s5e=kt({name:"ri-star-fill",render:o5e}),i5e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function r5e(e,t){return y(),M("svg",i5e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928zm0-2.292l4.247 2.377l-.948-4.773l3.573-3.305l-4.833-.573l-2.038-4.419l-2.039 4.42l-4.833.572l3.573 3.305l-.948 4.773z"},null,-1)])])}const l5e=kt({name:"ri-star-line",render:r5e}),a5e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function u5e(e,t){return y(),M("svg",a5e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M5.33 3.272a3.5 3.5 0 0 1 4.254 4.962l10.709 10.71l-1.414 1.414l-10.71-10.71a3.502 3.502 0 0 1-4.962-4.255L5.444 7.63a1.5 1.5 0 0 0 2.121-2.121zm10.367 1.883l3.182-1.768l1.414 1.415l-1.768 3.182l-1.768.353l-2.12 2.121l-1.415-1.414l2.121-2.121zm-6.718 8.132l1.415 1.414l-5.304 5.303a1 1 0 0 1-1.492-1.327l.078-.087z"},null,-1)])])}const c5e=kt({name:"ri-tools-line",render:u5e}),d5e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function f5e(e,t){return y(),M("svg",d5e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m20.97 17.172l-1.414 1.414l-3.535-3.535l-.073.074l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243L5.34 8.761l3.536-.707l.073-.074l-3.536-3.536L6.828 3.03zM10.365 9.394l-.502.502l-2.822.565l6.5 6.5l.564-2.822l.502-.502zm8.411.074l-1.34 1.34l1.414 1.415l1.34-1.34l.707.707l1.415-1.415l-8.486-8.485l-1.414 1.414l.707.707l-1.34 1.34l1.414 1.415l1.34-1.34z"},null,-1)])])}const p5e=kt({name:"ri-unpin-line",render:f5e}),h5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12.0684 2.03418C12.5654 2.03421 12.9687 2.43755 12.9688 2.93457V11.0996H21.0654C21.5625 11.0996 21.9658 11.503 21.9658 12C21.9658 12.497 21.5625 12.9004 21.0654 12.9004H12.9688V21.0654C12.9687 21.5624 12.5654 21.9658 12.0684 21.9658C11.5713 21.9658 11.168 21.5625 11.168 21.0654V12.9004H2.93457C2.43751 12.9004 2.03418 12.4971 2.03418 12C2.03418 11.5029 2.43751 11.0996 2.93457 11.0996H11.168V2.93457C11.168 2.43753 11.5713 2.03418 12.0684 2.03418Z" fill="currentColor"/> +</svg> +`,m5e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path id="p0" d="M 0 -9.9 C -5.468 -9.9 -9.9 -5.468 -9.9 0 C -9.9 1.923 -9.351 3.719 -8.402 5.239 C -8.402 5.239 -9.483 7.821 -9.483 7.821 C -9.896 8.809 -9.171 9.9 -8.099 9.9 C -8.099 9.9 0 9.9 0 9.9 C 5.468 9.9 9.9 5.468 9.9 0 C 9.9 -5.468 5.468 -9.9 0 -9.9 Z M -8.1 0 C -8.1 -4.474 -4.474 -8.1 0 -8.1 C 4.473 -8.1 8.1 -4.474 8.1 0 C 8.1 4.473 4.473 8.1 -0.001 8.1 C -0.001 8.1 -7.648 8.1 -7.648 8.1 L -6.365 5.035 C -6.365 5.035 -6.648 4.629 -6.648 4.629 C -7.563 3.317 -8.1 1.723 -8.1 0 Z" transform="matrix(1 0 0 1 12 12)" fill="currentColor" fill-rule="evenodd"/> + <path id="p1" d="M 3.6 0.5 L -2.6 0.5 M 0.5 -2.573 L 0.5 3.573" transform="translate(11.5 11.5)" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/> +</svg> +`,g5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M15.0996 12C15.5967 12 16 12.4033 16 12.9004C15.9998 13.3973 15.5965 13.7998 15.0996 13.7998H8.90039C8.40346 13.7998 8.00021 13.3973 8 12.9004C8 12.4033 8.40333 12 8.90039 12H15.0996Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M19 3.2002C20.5464 3.2002 21.7998 4.4536 21.7998 6V7C21.7998 8.03565 21.2363 8.93754 20.4004 9.42188V17C20.4004 19.1539 18.6539 20.9004 16.5 20.9004H7.5C5.34609 20.9004 3.59961 19.1539 3.59961 17V9.42188C2.76374 8.93754 2.2002 8.03565 2.2002 7V6C2.2002 4.4536 3.4536 3.2002 5 3.2002H19ZM5.40039 17C5.40039 18.1598 6.3402 19.0996 7.5 19.0996H16.5C17.6598 19.0996 18.5996 18.1598 18.5996 17V9.7998H5.40039V17ZM4.89746 5.00488C4.39333 5.05621 4 5.48232 4 6V7L4.00488 7.10254C4.05278 7.57297 4.42703 7.94722 4.89746 7.99512L5 8H19C19.5523 8 20 7.55228 20 7V6C20 5.44772 19.5523 5 19 5H5L4.89746 5.00488Z" fill="currentColor"/> +</svg> +`,v5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M11.386 21.6387C11.7378 21.988 12.3059 21.987 12.6565 21.6364L18.1949 16.098C18.5464 15.7465 18.5464 15.1766 18.1949 14.8252C17.8434 14.4737 17.2736 14.4737 16.9221 14.8252L12.9201 18.8272V3.00002C12.9201 2.50297 12.5171 2.10003 12.0201 2.10003C11.523 2.10003 11.1201 2.50297 11.1201 3.00002V18.8383L7.07554 14.8229C6.7228 14.4727 6.15295 14.4747 5.80275 14.8275C5.45255 15.1802 5.45461 15.7501 5.80735 16.1003L11.386 21.6387Z" fill="currentColor"/> +</svg> +`,y5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M2.16127 12.814C1.81197 12.4622 1.81299 11.8941 2.16357 11.5435L7.70203 6.00506C8.0535 5.65359 8.62335 5.65359 8.97482 6.00506C9.32629 6.35653 9.32629 6.92638 8.97482 7.27785L4.97276 11.2799H20.8C21.297 11.2799 21.7 11.6829 21.7 12.1799C21.7 12.677 21.297 13.0799 20.8 13.0799H4.96171L8.97712 17.1244C9.32732 17.4772 9.32526 18.047 8.97252 18.3972C8.61978 18.7474 8.04993 18.7454 7.69973 18.3926L2.16127 12.814Z" fill="currentColor"/> +</svg> +`,k5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4387 12.814C21.788 12.4622 21.787 11.8941 21.4364 11.5436L15.8979 6.0051C15.5464 5.65363 14.9766 5.65363 14.6251 6.0051C14.2737 6.35657 14.2737 6.92642 14.6251 7.27789L18.6272 11.28H2.79998C2.30293 11.28 1.89998 11.6829 1.89998 12.18C1.89998 12.677 2.30293 13.08 2.79998 13.08H18.6382L14.6228 17.1245C14.2726 17.4772 14.2747 18.0471 14.6274 18.3973C14.9802 18.7475 15.55 18.7454 15.9002 18.3927L21.4387 12.814Z" fill="currentColor"/> +</svg> +`,b5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M11.386 2.36129C11.7378 2.01198 12.3059 2.013 12.6565 2.36358L18.1949 7.90204C18.5464 8.25351 18.5464 8.82336 18.1949 9.17483C17.8434 9.52631 17.2736 9.52631 16.9221 9.17483L12.9201 5.17277V21C12.9201 21.497 12.5171 21.9 12.0201 21.9C11.523 21.9 11.1201 21.497 11.1201 21V5.16172L7.07554 9.17713C6.7228 9.52733 6.15295 9.52527 5.80275 9.17253C5.45255 8.81979 5.45461 8.24995 5.80735 7.89975L11.386 2.36129Z" fill="currentColor"/> +</svg> +`,C5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M19.3027 5.9053C19.6542 5.55397 20.2247 5.55388 20.5761 5.9053C20.9273 6.25675 20.9273 6.82734 20.5761 7.17874L9.65911 18.0948C9.30773 18.4461 8.73814 18.446 8.38665 18.0948L3.42376 13.1328C3.0726 12.7814 3.07263 12.2118 3.42376 11.8604C3.77524 11.509 4.34575 11.5089 4.6972 11.8604L9.02239 16.1856L19.3027 5.9053Z" fill="currentColor"/> +</svg> +`,w5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3912 16.7134C11.743 17.0627 12.3111 17.0617 12.6617 16.7111L19.6364 9.73641C19.9878 9.38494 19.9878 8.81509 19.6364 8.46362C19.2849 8.11215 18.7151 8.11215 18.3636 8.46362L12.023 14.8042L5.63407 8.46132C5.28133 8.11112 4.71149 8.11318 4.36129 8.46592C4.01109 8.81866 4.01314 9.3885 4.36588 9.73871L11.3912 16.7134Z" fill="currentColor"/> +</svg> +`,_5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M16.1261 12.6088C16.4754 12.257 16.4743 11.6889 16.1238 11.3383L9.14904 4.36363C8.79757 4.01216 8.22772 4.01216 7.87625 4.36363C7.52477 4.7151 7.52477 5.28495 7.87625 5.63642L14.2169 11.977L7.87395 18.3659C7.52375 18.7187 7.52581 19.2885 7.87855 19.6387C8.23129 19.9889 8.80113 19.9869 9.15133 19.6341L16.1261 12.6088Z" fill="currentColor"/> +</svg> +`,x5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3912 8.46132C11.743 8.11202 12.3111 8.11304 12.6617 8.46362L19.6364 15.4383C19.9878 15.7898 19.9878 16.3597 19.6364 16.7111C19.2849 17.0626 18.7151 17.0626 18.3636 16.7111L12.023 10.3705L5.63407 16.7134C5.28133 17.0636 4.71149 17.0616 4.36129 16.7088C4.01109 16.3561 4.01314 15.7862 4.36588 15.436L11.3912 8.46132Z" fill="currentColor"/> +</svg> +`,S5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.8999 6.79965C12.397 6.79965 12.7997 7.20235 12.7997 7.69941V11.7266L14.7359 13.6629C15.0873 14.0143 15.0879 14.584 14.7366 14.9355C14.3852 15.287 13.8148 15.287 13.4633 14.9355L11.2632 12.7355C11.0947 12.5668 11.0002 12.338 11.0001 12.0995V7.69941C11.0001 7.20238 11.4029 6.7997 11.8999 6.79965Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M12 1.89893C17.4677 1.89893 21.9001 6.33147 21.9002 11.7991C21.9002 17.2669 17.4678 21.6993 12 21.6993C6.53228 21.6993 2.09985 17.2669 2.09985 11.7991C2.09998 6.33147 6.53236 1.89893 12 1.89893ZM20.1 11.7998C20.1 7.32616 16.4737 3.69984 12 3.69984C7.5264 3.69984 3.90008 7.32616 3.90008 11.7998C3.90032 16.2732 7.52655 19.8998 12 19.8998C16.4735 19.8998 20.0998 16.2732 20.1 11.7998Z" fill="currentColor"/> +</svg> +`,A5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z" fill="currentColor"/> +</svg> +`,M5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9.85815 11.957C10.9074 11.957 11.7583 12.8083 11.7585 13.8574V19.8574C11.7585 20.3545 11.3552 20.7578 10.8582 20.7578C10.3611 20.7578 9.95776 20.3545 9.95776 19.8574V13.8574C9.95755 13.8024 9.91325 13.7578 9.85815 13.7578H3.85815C3.3611 13.7578 2.95776 13.3545 2.95776 12.8574C2.95798 12.3605 3.36123 11.957 3.85815 11.957H9.85815Z" fill="currentColor"/> +<path d="M12.8582 2.95703C13.3551 2.95703 13.7583 3.36054 13.7585 3.85742V9.85742C13.7585 9.91265 13.8029 9.95703 13.8582 9.95703H19.8582C20.3551 9.95703 20.7583 10.3605 20.7585 10.8574C20.7585 11.3545 20.3552 11.7578 19.8582 11.7578H13.8582C12.8088 11.7578 11.9578 10.9068 11.9578 9.85742V3.85742C11.958 3.36054 12.3612 2.95703 12.8582 2.95703Z" fill="currentColor"/> +</svg> +`,T5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.9004 2.19995C17.3678 2.20016 21.7998 6.63285 21.7998 12.1003C21.7996 17.5677 17.3677 21.9995 11.9004 21.9998H3.80078C2.72946 21.9996 2.00334 20.9089 2.41699 19.9207L3.49805 17.3386C2.54871 15.8189 2.00007 14.0226 2 12.1003C2 6.63272 6.43277 2.19995 11.9004 2.19995ZM11.9004 3.99976C7.42688 3.99976 3.7998 7.62684 3.7998 12.1003C3.79989 13.8228 4.33669 15.4175 5.25195 16.7292L5.53516 17.1345L4.25195 20.2H11.8994C16.3727 20.1999 19.9998 16.5736 20 12.1003C20 7.62697 16.3737 3.99997 11.9004 3.99976ZM8.9541 10.8005C9.75473 10.8006 10.4041 11.4491 10.4043 12.2498C10.4043 13.0505 9.75482 13.6998 8.9541 13.7C8.15329 13.7 7.50391 13.0506 7.50391 12.2498C7.50406 11.4491 8.15339 10.8005 8.9541 10.8005ZM15.1533 10.8005C15.9539 10.8006 16.6034 11.4491 16.6035 12.2498C16.6035 13.0505 15.954 13.6998 15.1533 13.7C14.3525 13.7 13.7031 13.0506 13.7031 12.2498C13.7033 11.4491 14.3526 10.8005 15.1533 10.8005Z" fill="currentColor"/> +</svg> +`,E5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M17 7.09961C19.1539 7.09961 20.9004 8.84609 20.9004 11V17C20.9004 19.1539 19.1539 20.9004 17 20.9004H11C8.84609 20.9004 7.09961 19.1539 7.09961 17V11C7.09961 8.84609 8.84609 7.09961 11 7.09961H17ZM11 8.90039C9.8402 8.90039 8.90039 9.8402 8.90039 11V17C8.90039 18.1598 9.8402 19.0996 11 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V11C19.0996 9.8402 18.1598 8.90039 17 8.90039H11Z" fill="currentColor"/> +<path d="M13 3.09961C14.4447 3.09961 15.705 3.88644 16.3779 5.0498C16.6265 5.47999 16.4789 6.03049 16.0488 6.2793C15.6186 6.52781 15.0681 6.38029 14.8193 5.9502C14.4548 5.32041 13.776 4.90039 13 4.90039H7C5.8402 4.90039 4.90039 5.8402 4.90039 7V13C4.90039 13.776 5.32041 14.4548 5.9502 14.8193C6.38029 15.0681 6.52781 15.6186 6.2793 16.0488C6.03049 16.4789 5.47999 16.6265 5.0498 16.3779C3.88644 15.705 3.09961 14.4447 3.09961 13V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H13Z" fill="currentColor"/> +</svg> +`,I5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 10.2797 2.43414 8.66074 3.19922 7.24707C3.20172 7.24246 3.20453 7.23801 3.20703 7.2334C3.33385 6.99995 3.47181 6.77351 3.61621 6.55176C3.73214 6.37355 3.85079 6.19744 3.97754 6.02734C5.35905 4.17471 7.36856 2.81959 9.68945 2.27051C9.69952 2.26813 9.70965 2.26602 9.71973 2.26367C9.85224 2.23276 9.98563 2.2043 10.1201 2.17871C10.1542 2.17221 10.1884 2.16631 10.2227 2.16016C10.3466 2.13791 10.4712 2.11724 10.5967 2.09961C10.6301 2.09489 10.6637 2.0913 10.6973 2.08691C10.8216 2.07073 10.9465 2.05552 11.0723 2.04395C11.1125 2.04022 11.153 2.0384 11.1934 2.03516C11.4595 2.0139 11.7284 2 12 2ZM11.9941 3.7998C11.9968 3.86623 12 3.93292 12 4C12 6.76142 9.76142 9 7 9C6.14209 9 5.33517 8.78324 4.62988 8.40234C4.09862 9.48861 3.7998 10.7093 3.7998 12C3.7998 12.4438 3.83644 12.8791 3.9043 13.3037C4.52807 12.5673 5.45945 12.0996 6.5 12.0996C8.37777 12.0996 9.90039 13.6222 9.90039 15.5C9.90039 17.0702 8.83532 18.3903 7.38867 18.7812C8.70267 19.6765 10.2901 20.2002 12 20.2002C12.468 20.2002 12.9264 20.1583 13.373 20.083C13.1323 19.4342 13 18.7327 13 18C13 14.6863 15.6863 12 19 12C19.4098 12 19.8098 12.0416 20.1963 12.1201C20.1969 12.0801 20.2002 12.0401 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998H11.9941ZM19 13.7998C16.6804 13.7998 14.7998 15.6804 14.7998 18C14.7998 18.5617 14.9112 19.0972 15.1113 19.5869C17.5225 18.597 19.3558 16.4929 19.9727 13.9141C19.6605 13.8399 19.3349 13.7998 19 13.7998ZM6.5 13.9004C5.61634 13.9004 4.90039 14.6163 4.90039 15.5C4.90039 16.3837 5.61634 17.0996 6.5 17.0996C7.38366 17.0996 8.09961 16.3837 8.09961 15.5C8.09961 14.6163 7.38366 13.9004 6.5 13.9004ZM15.5 6.09961C16.8255 6.09961 17.9004 7.17452 17.9004 8.5C17.9004 9.82548 16.8255 10.9004 15.5 10.9004C14.1745 10.9004 13.0996 9.82548 13.0996 8.5C13.0996 7.17452 14.1745 6.09961 15.5 6.09961ZM15.5 7.90039C15.1686 7.90039 14.9004 8.16863 14.9004 8.5C14.9004 8.83137 15.1686 9.09961 15.5 9.09961C15.8314 9.09961 16.0996 8.83137 16.0996 8.5C16.0996 8.16863 15.8314 7.90039 15.5 7.90039ZM10.1992 4C8.35326 4.41375 6.74333 5.44923 5.59961 6.87598C6.02235 7.08306 6.49716 7.2002 7 7.2002C8.76731 7.2002 10.1992 5.76731 10.1992 4Z" fill="currentColor"/> +</svg> +`,L5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.90002C12.4971 2.90002 12.9 3.30297 12.9 3.80002V12.2939L15.8081 9.38585C16.1595 9.03438 16.7294 9.03438 17.0808 9.38585C17.4323 9.73732 17.4323 10.3072 17.0808 10.6586L12.6364 15.1031C12.4676 15.2719 12.2387 15.3667 12 15.3667C11.7613 15.3667 11.5324 15.2719 11.3636 15.1031L6.91917 10.6586C6.5677 10.3072 6.5677 9.73732 6.91917 9.38585C7.27064 9.03438 7.84049 9.03438 8.19196 9.38585L11.1 12.2939V3.80002C11.1 3.30297 11.503 2.90002 12 2.90002ZM4.00001 13.5874C4.49706 13.5874 4.90001 13.9903 4.90001 14.4874V18.043C4.90001 18.2758 4.99249 18.499 5.1571 18.6636C5.32172 18.8282 5.54498 18.9207 5.77778 18.9207H18.2222C18.455 18.9207 18.6783 18.8283 18.8429 18.6636C19.0075 18.499 19.1 18.2758 19.1 18.043V14.4874C19.1 13.9903 19.5029 13.5874 20 13.5874C20.4971 13.5874 20.9 13.9903 20.9 14.4874V18.043C20.9 18.7531 20.6179 19.4342 20.1157 19.9364C19.6135 20.4386 18.9324 20.7207 18.2222 20.7207H5.77778C5.06759 20.7207 4.38649 20.4386 3.88431 19.9364C3.38213 19.4342 3.10001 18.7531 3.10001 18.043V14.4874C3.10001 13.9903 3.50295 13.5874 4.00001 13.5874Z" fill="currentColor"/> +</svg> +`,$5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M18.0179 3.09998C18.3963 3.10003 18.7709 3.17491 19.1205 3.31971C19.4701 3.46454 19.7884 3.67614 20.056 3.94373C20.3237 4.21144 20.5362 4.52965 20.681 4.87928C20.8258 5.22887 20.8997 5.60423 20.8997 5.9828C20.8997 6.36118 20.8257 6.73591 20.681 7.08533C20.5362 7.43497 20.3237 7.75317 20.056 8.02088L17.639 10.4379L9.15756 18.9183C8.5296 19.5463 7.74274 19.992 6.8812 20.2074L4.21811 20.8734C3.91148 20.95 3.5871 20.8596 3.36362 20.6361C3.14017 20.4126 3.05063 20.0883 3.12729 19.7816L3.79233 17.1185C4.00771 16.257 4.45344 15.4701 5.08139 14.8422L15.9798 3.94373C16.5203 3.40346 17.2536 3.09998 18.0179 3.09998ZM19.0003 19.1C19.4972 19.1002 19.8997 19.5034 19.8997 20.0004C19.8995 20.4971 19.4971 20.8996 19.0003 20.8998H12.0003C11.5034 20.8998 11.1001 20.4973 11.0999 20.0004C11.0999 19.5033 11.5033 19.1 12.0003 19.1H19.0003ZM18.0179 4.89979C17.7309 4.89979 17.4553 5.01417 17.2523 5.21717L6.35385 16.1146C5.95661 16.5119 5.67469 17.01 5.53842 17.5551L5.23666 18.7631L6.44467 18.4613C6.98971 18.3251 7.48782 18.0431 7.8851 17.6459L18.7826 6.74744C18.883 6.64702 18.9635 6.52821 19.0179 6.39686C19.0723 6.26558 19.0999 6.1247 19.0999 5.9828C19.0999 5.84075 19.0723 5.69916 19.0179 5.56776C18.9635 5.43645 18.883 5.31757 18.7826 5.21717C18.6821 5.11678 18.5631 5.03716 18.432 4.9828C18.3008 4.92845 18.16 4.89983 18.0179 4.89979Z" fill="currentColor"/> +</svg> +`,N5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M5 11.0996C5.49693 11.0996 5.90018 11.5031 5.90039 12V18C5.90039 18.0552 5.94477 18.0996 6 18.0996H12C12.4969 18.0996 12.9002 18.5031 12.9004 19C12.9004 19.4971 12.4971 19.9004 12 19.9004H6C4.95066 19.9004 4.09961 19.0493 4.09961 18V12C4.09982 11.5031 4.50307 11.0996 5 11.0996ZM18 4.09961C19.0492 4.09961 19.9002 4.95084 19.9004 6V12C19.9004 12.4971 19.4971 12.9004 19 12.9004C18.5029 12.9004 18.0996 12.4971 18.0996 12V6C18.0994 5.94495 18.0551 5.90039 18 5.90039H12C11.5029 5.90039 11.0996 5.49706 11.0996 5C11.0998 4.50312 11.5031 4.09961 12 4.09961H18Z" fill="currentColor"/> +</svg> +`,Yx=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g> +<path fill-rule="evenodd" clip-rule="evenodd" d="M13.1723 2.1001C13.9413 2.10018 14.6793 2.40592 15.2231 2.94971L19.0512 6.77783C19.595 7.32162 19.9007 8.0596 19.9008 8.82861V18.0005C19.9008 20.1544 18.1543 21.9009 16.0004 21.9009H8.0004C5.84649 21.9009 4.10001 20.1544 4.10001 18.0005V6.00049C4.10001 3.84658 5.84649 2.1001 8.0004 2.1001H13.1723ZM8.0004 3.90088C6.8406 3.90088 5.90079 4.84069 5.90079 6.00049V18.0005C5.90079 19.1603 6.8406 20.1001 8.0004 20.1001H16.0004C17.1602 20.1001 18.1 19.1603 18.1 18.0005V9.90088H15.0004C13.3988 9.90088 12.1 8.60211 12.1 7.00049V3.90088H8.0004ZM13.9008 7.00049C13.9008 7.608 14.3929 8.1001 15.0004 8.1001H17.8217C17.8072 8.08375 17.7933 8.06681 17.7777 8.05127L13.9496 4.22314C13.9339 4.20745 13.9173 4.19286 13.9008 4.17822V7.00049Z" fill="currentColor"/> +</g> +</svg> +`,F5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M15.4795 15.4971C15.9765 15.4971 16.3799 15.9004 16.3799 16.3975C16.3799 16.8945 15.9765 17.2978 15.4795 17.2979H8.52051C8.02345 17.2979 7.62012 16.8945 7.62012 16.3975C7.62012 15.9004 8.02345 15.4971 8.52051 15.4971H15.4795Z" fill="currentColor"/> +<path d="M12.3359 11.0996C12.8329 11.0997 13.2354 11.503 13.2354 12C13.2354 12.497 12.8329 12.9003 12.3359 12.9004H8.52051C8.02345 12.9004 7.62012 12.4971 7.62012 12C7.62012 11.5029 8.02345 11.0996 8.52051 11.0996H12.3359Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M13.1719 2.09961C13.9408 2.09969 14.6789 2.40555 15.2227 2.94922L19.0508 6.77734C19.5946 7.32113 19.9003 8.05911 19.9004 8.82812V18C19.9004 20.1539 18.1539 21.9004 16 21.9004H8C5.84626 21.9002 4.09961 20.1538 4.09961 18V6C4.09961 3.84621 5.84626 2.09981 8 2.09961H13.1719ZM8 3.90039C6.84037 3.90059 5.90039 4.84032 5.90039 6V18C5.90039 19.1597 6.84037 20.0994 8 20.0996H16C17.1598 20.0996 18.0996 19.1598 18.0996 18V9.90039H15C13.3985 9.90019 12.0996 8.6015 12.0996 7V3.90039H8ZM13.9004 7C13.9004 7.60739 14.3927 8.09941 15 8.09961H17.8213C17.8068 8.08333 17.7928 8.06626 17.7773 8.05078L13.9492 4.22266C13.9335 4.20696 13.9169 4.19237 13.9004 4.17773V7Z" fill="currentColor"/> +</svg> +`,R5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9.2373 3.7002C10.4169 3.7002 11.5297 4.24779 12.249 5.18262L12.4424 5.43359H18C20.0987 5.43359 21.7998 7.13472 21.7998 9.2334V16.5C21.7998 18.5987 20.0987 20.2998 18 20.2998H6C3.90132 20.2998 2.2002 18.5987 2.2002 16.5V7.5C2.2002 5.40132 3.90132 3.7002 6 3.7002H9.2373ZM6 5.5C4.89543 5.5 4 6.39543 4 7.5V16.5C4 17.6046 4.89543 18.5 6 18.5H18C19.0357 18.5 19.887 17.7128 19.9893 16.7041L20 16.5V9.2334C20 8.19775 19.2128 7.34641 18.2041 7.24414L18 7.2334H12.0479L11.9326 7.22656C11.666 7.19561 11.4205 7.05812 11.2549 6.84277L10.8223 6.28027C10.4437 5.78834 9.85808 5.5 9.2373 5.5H6ZM16 9.59961C16.4971 9.59961 16.9004 10.0029 16.9004 10.5C16.9004 10.9971 16.4971 11.4004 16 11.4004H8C7.50294 11.4004 7.09961 10.9971 7.09961 10.5C7.09961 10.0029 7.50294 9.59961 8 9.59961H16Z" fill="currentColor"/> +</svg> +`,O5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g> +<path d="M18.3623 9.99976L18.209 8.48999C18.2031 8.43161 18.2004 8.37289 18.2002 8.31421C18.1988 8.31196 18.1956 8.30842 18.1904 8.30347C18.1718 8.28559 18.1302 8.26245 18.0713 8.26245H11C10.261 8.26245 9.59753 7.81016 9.32617 7.1228L8.9082 6.06421C8.88101 5.9953 8.85737 5.92501 8.83887 5.85327C8.83778 5.85099 8.833 5.84268 8.81836 5.83179C8.79454 5.81475 8.7549 5.79939 8.70605 5.80054H3.92871C3.86986 5.80054 3.82825 5.82368 3.80957 5.84155C3.80816 5.8429 3.80675 5.84428 3.80566 5.84546L4.47559 14.0955L3.62109 17.5154L5.12109 11.5154C5.34367 10.6251 6.1438 9.99977 7.06152 9.99976H18.3623ZM7.06152 11.7996C6.96976 11.7996 6.88944 11.8629 6.86719 11.9519L5.36719 17.9519C5.33598 18.078 5.43158 18.1999 5.56152 18.2H19.4385C19.5302 18.1999 19.6106 18.1376 19.6328 18.0486L21.1328 12.0486C21.1644 11.9224 21.0686 11.7996 20.9385 11.7996H7.06152ZM20.9385 9.99976C22.2396 9.99977 23.1945 11.2228 22.8789 12.4851L21.3789 18.4851C21.1563 19.3754 20.3562 19.9997 19.4385 19.9998H4.92871C4.41722 19.9998 3.92613 19.8059 3.56445 19.4597C3.20281 19.1135 3.00004 18.6436 3 18.1541L2 5.84644C2.00006 5.35711 2.20311 4.88786 2.56445 4.54175C2.92613 4.19554 3.41722 4.00073 3.92871 4.00073H8.66406C9.10133 3.99051 9.5296 4.1225 9.87793 4.37573C10.2285 4.63118 10.4767 4.99457 10.582 5.40405L11 6.46167H18.0713C18.5828 6.46167 19.0739 6.65648 19.4355 7.00269C19.7971 7.34888 20 7.81883 20 8.30835L20.1719 9.99976H20.9385Z" fill="currentColor"/> +</g> +</svg> +`,P5e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path id="af-p0" d="M -2.619 -8.3 C -1.815 -8.3 -1.048 -7.97 -0.499 -7.39 C -0.499 -7.39 0.141 -6.712 0.141 -6.712 C 0.141 -6.712 5.75 -6.712 5.75 -6.712 C 7.904 -6.712 9.65 -4.986 9.65 -2.858 C 9.65 -2.858 9.65 -1.71 9.65 -1.71 C 9.65 -1.219 9.247 -0.821 8.75 -0.821 C 8.253 -0.821 7.85 -1.219 7.85 -1.71 C 7.85 -1.71 7.85 -2.858 7.85 -2.858 C 7.849 -4.004 6.91 -4.934 5.75 -4.934 C 5.75 -4.934 -0.207 -4.934 -0.207 -4.934 C -0.484 -4.934 -0.749 -5.047 -0.938 -5.247 C -0.938 -5.247 -1.815 -6.177 -1.815 -6.177 C -2.023 -6.397 -2.315 -6.521 -2.619 -6.521 C -2.619 -6.521 -6.25 -6.521 -6.25 -6.521 C -7.41 -6.521 -8.35 -5.592 -8.35 -4.446 C -8.35 -4.446 -8.35 4.446 -8.35 4.446 C -8.35 5.592 -7.41 6.521 -6.25 6.521 C -6.25 6.521 1.25 6.521 1.25 6.521 C 1.747 6.521 2.15 6.919 2.15 7.41 C 2.15 7.901 1.747 8.3 1.25 8.3 C 1.25 8.3 -6.25 8.3 -6.25 8.3 C -8.404 8.3 -10.15 6.574 -10.15 4.446 C -10.15 4.446 -10.15 -4.446 -10.15 -4.446 C -10.15 -6.574 -8.404 -8.3 -6.25 -8.3 C -6.25 -8.3 -2.619 -8.3 -2.619 -8.3 Z M 3.75 -2.5 C 4.247 -2.5 4.65 -2.097 4.65 -1.6 C 4.65 -1.103 4.247 -0.699 3.75 -0.699 C 3.75 -0.699 -4.25 -0.699 -4.25 -0.699 C -4.747 -0.699 -5.15 -1.103 -5.15 -1.6 C -5.15 -2.097 -4.747 -2.5 -4.25 -2.5 C -4.25 -2.5 3.75 -2.5 3.75 -2.5 Z" transform="matrix(1 0 0 1 11.75 12)" fill="currentColor"/> + <g id="af-p1"> + <path d="M 2.635 0 L -2.635 0 M 0 -2.635 L 0 2.635" transform="matrix(1 0 0 1 18.4 16.3)" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/> + </g> +</svg> +`,D5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3ZM12 19.2002C15.9764 19.2002 19.2002 15.9764 19.2002 12C19.2002 8.02355 15.9764 4.7998 12 4.7998V19.2002Z" fill="currentColor"/> +</svg> +`,B5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7ZM12 15.6992C12.4968 15.6992 12.8994 16.1028 12.8994 16.5996C12.8994 17.0964 12.4968 17.5 12 17.5C11.5024 17.5 11.0996 17.0964 11.0996 16.5996C11.0996 16.1028 11.5024 15.6992 12 15.6992ZM12 6.49902C12.4969 6.49922 12.8994 6.86908 12.8994 7.3252V13.6729C12.8994 14.129 12.4969 14.4988 12 14.499C11.5029 14.499 11.0996 14.1291 11.0996 13.6729V7.3252C11.0996 6.86896 11.5029 6.49902 12 6.49902Z" fill="currentColor"/> +</svg> +`,H5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12.5092 2.11279C17.7402 2.37781 21.8998 6.70364 21.8998 12.0005C21.8996 17.4153 17.5524 21.8108 12.1576 21.895C12.1056 21.898 12.0532 21.8999 12.0004 21.8999C11.948 21.8999 11.8954 21.8968 11.8432 21.896L11.8422 21.895C6.44751 21.8107 2.10022 17.4152 2.10001 12.0005C2.10001 6.53287 6.53278 2.1001 12.0004 2.1001L12.5092 2.11279ZM8.92715 13.0005C9.02896 14.9787 9.42581 16.721 9.99356 17.9985C10.3249 18.7441 10.6971 19.292 11.0639 19.6411C11.4259 19.9855 11.741 20.1001 12.0004 20.1001C12.2598 20.1 12.5749 19.9856 12.9369 19.6411C13.3037 19.292 13.6749 18.7441 14.0063 17.9985C14.574 16.721 14.9718 14.9788 15.0736 13.0005H8.92715ZM3.96329 13.0005C4.31462 15.8522 6.14714 18.2427 8.66837 19.3823C8.55544 19.1733 8.44916 18.9552 8.34903 18.73C7.66574 17.1926 7.22657 15.1926 7.12344 13.0005H3.96329ZM16.8764 13.0005C16.7732 15.1926 16.3341 17.1926 15.6508 18.73C15.5506 18.9554 15.4435 19.1732 15.3305 19.3823C17.8522 18.2429 19.6851 15.8525 20.0365 13.0005H16.8764ZM8.66934 4.6167C6.08869 5.78266 4.22826 8.25964 3.93985 11.1997H7.11661C7.20176 8.92954 7.64512 6.85497 8.34903 5.271C8.4494 5.04516 8.5561 4.82619 8.66934 4.6167ZM12.0004 3.8999C11.7411 3.8999 11.4259 4.01454 11.0639 4.35889C10.6971 4.70797 10.3249 5.25587 9.99356 6.00146C9.40671 7.32188 9.00186 9.13885 8.91739 11.1997H15.0834C14.9989 9.13884 14.5931 7.32189 14.0063 6.00146C13.6749 5.2559 13.3037 4.70796 12.9369 4.35889C12.5749 4.0144 12.2598 3.90002 12.0004 3.8999ZM15.3295 4.61572C15.443 4.82559 15.5502 5.04471 15.6508 5.271C16.3547 6.85498 16.799 8.92949 16.8842 11.1997H20.06C19.7715 8.25914 17.9108 5.78143 15.3295 4.61572Z" fill="currentColor"/> +</svg> +`,z5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8 17C8.82834 17 9.5 17.6717 9.5 18.5C9.5 19.3283 8.82834 20 8 20C7.17166 20 6.5 19.3283 6.5 18.5C6.5 17.6717 7.17166 17 8 17ZM16 17C16.8283 17 17.5 17.6717 17.5 18.5C17.5 19.3283 16.8283 20 16 20C15.1717 20 14.5 19.3283 14.5 18.5C14.5 17.6717 15.1717 17 16 17ZM8 10.5C8.82834 10.5 9.5 11.1717 9.5 12C9.5 12.8283 8.82834 13.5 8 13.5C7.17166 13.5 6.5 12.8283 6.5 12C6.5 11.1717 7.17166 10.5 8 10.5ZM16 10.5C16.8283 10.5 17.5 11.1717 17.5 12C17.5 12.8283 16.8283 13.5 16 13.5C15.1717 13.5 14.5 12.8283 14.5 12C14.5 11.1717 15.1717 10.5 16 10.5ZM8 4C8.82834 4 9.5 4.67166 9.5 5.5C9.5 6.32834 8.82834 7 8 7C7.17166 7 6.5 6.32834 6.5 5.5C6.5 4.67166 7.17166 4 8 4ZM16 4C16.8283 4 17.5 4.67166 17.5 5.5C17.5 6.32834 16.8283 7 16 7C15.1717 7 14.5 6.32834 14.5 5.5C14.5 4.67166 15.1717 4 16 4Z" fill="currentColor"/> +</svg> +`,W5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.22264 6.10352C7.22264 5.5078 7.48259 4.95449 7.91405 4.56055C8.34271 4.16918 8.90831 3.96198 9.48241 3.96191C9.64155 3.96191 9.80001 3.97936 9.95507 4.01074C10.0127 3.5042 10.2586 3.04178 10.6338 2.69922C11.0625 2.30778 11.6279 2.09961 12.2021 2.09961C12.7763 2.09966 13.3418 2.30783 13.7705 2.69922C13.9947 2.90401 14.1709 3.15244 14.29 3.42676C14.4947 3.37044 14.7071 3.34182 14.9209 3.3418C15.4951 3.3418 16.0605 3.549 16.4892 3.94043C16.8644 4.28293 17.1093 4.74548 17.167 5.25195C17.3223 5.22045 17.4812 5.20312 17.6406 5.20312C18.2147 5.20318 18.7803 5.41135 19.209 5.80273C19.6402 6.19663 19.9004 6.74922 19.9004 7.34473V14.6543C19.9004 17.413 19.2914 19.0434 18.0137 20.21C16.82 21.2998 15.2175 21.9004 13.5615 21.9004C11.7538 21.9004 10.2315 21.5696 8.95702 20.8535C7.67664 20.1341 6.71683 19.0652 5.97362 17.708L3.3496 12.916C3.18848 12.6213 3.10112 12.2914 3.0996 11.9531C3.09812 11.6147 3.18309 11.2835 3.34179 10.9873C3.5001 10.692 3.72639 10.4416 3.99706 10.251C4.26771 10.0604 4.57776 9.93235 4.90136 9.87305C5.56617 9.75102 6.25934 9.84517 6.86425 10.1445C6.9942 10.2088 7.11461 10.2788 7.22264 10.3477V6.10352ZM9.02343 12.7969C9.02336 13.1912 8.76624 13.5395 8.38964 13.6562C8.0129 13.773 7.60387 13.6309 7.38085 13.3057L6.53514 12.0723C6.51218 12.0529 6.48411 12.0282 6.45018 12.002C6.34595 11.9213 6.20986 11.8289 6.06639 11.7578C5.81525 11.6335 5.51637 11.5904 5.22655 11.6436H5.22557C5.15055 11.6573 5.08558 11.6865 5.03417 11.7227C4.98289 11.7588 4.94815 11.7998 4.92772 11.8379C4.90762 11.8755 4.90023 11.9122 4.90038 11.9453C4.90057 11.9782 4.9084 12.0144 4.9287 12.0518L7.55272 16.8438C8.16912 17.9693 8.90989 18.7622 9.83886 19.2842C10.7737 19.8094 11.9704 20.0996 13.5615 20.0996C14.7902 20.0996 15.9536 19.6533 16.7998 18.8809C17.5619 18.185 18.0996 17.1383 18.0996 14.6543V7.34473C18.0996 7.28204 18.0734 7.20342 17.9951 7.13184C17.9139 7.05771 17.7875 7.00396 17.6406 7.00391C17.4937 7.00391 17.3674 7.05771 17.2861 7.13184C17.2077 7.20347 17.1807 7.28199 17.1807 7.34473V11.0693C17.1805 11.5661 16.778 11.9685 16.2812 11.9688C15.7843 11.9688 15.381 11.5662 15.3808 11.0693V5.48242C15.3808 5.41973 15.3537 5.34107 15.2754 5.26953C15.1941 5.19547 15.0677 5.1416 14.9209 5.1416C14.774 5.14166 14.6476 5.19541 14.5664 5.26953C14.4881 5.34105 14.462 5.41974 14.4619 5.48242V11.0693C14.4617 11.5662 14.0584 11.9688 13.5615 11.9688C13.0646 11.9687 12.6613 11.5662 12.6611 11.0693V4.24121C12.6611 4.17852 12.635 4.09989 12.5566 4.02832C12.4754 3.95419 12.349 3.90045 12.2021 3.90039C12.0552 3.90039 11.9289 3.95421 11.8476 4.02832C11.7692 4.09992 11.7422 4.17849 11.7422 4.24121V11.0693C11.742 11.5661 11.3395 11.9685 10.8428 11.9688C10.3458 11.9688 9.94257 11.5662 9.94237 11.0693V6.10352L9.93651 6.05371C9.92534 6.00177 9.89573 5.94433 9.8369 5.89062C9.75567 5.81647 9.62938 5.76172 9.48241 5.76172C9.33554 5.76179 9.2091 5.81651 9.12792 5.89062C9.04964 5.96222 9.02343 6.04084 9.02343 6.10352V12.7969Z" fill="currentColor"/> +</svg> +`,U5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M4 3.33203C4.55224 3.33203 4.99993 3.7798 5 4.33203V18.0908H20.0674C20.6195 18.0908 21.0671 18.5388 21.0674 19.0908C21.0674 19.6431 20.6197 20.0908 20.0674 20.0908H5C3.89543 20.0908 3 19.1954 3 18.0908V4.33203C3.00007 3.7798 3.44776 3.33203 4 3.33203ZM8.19922 9.28418C8.7515 9.28418 9.19922 9.73189 9.19922 10.2842V15.6045C9.19908 16.1567 8.75142 16.6045 8.19922 16.6045C7.64719 16.6043 7.19936 16.1565 7.19922 15.6045V10.2842C7.19922 9.73202 7.6471 9.28438 8.19922 9.28418ZM17.2227 6.85645C17.7748 6.85658 18.2226 7.3043 18.2227 7.85645V15.6045C18.2225 16.1566 17.7747 16.6044 17.2227 16.6045C16.6705 16.6045 16.2228 16.1566 16.2227 15.6045V7.85645C16.2227 7.30422 16.6704 6.85645 17.2227 6.85645ZM12.7109 3.96387C13.2631 3.96387 13.7107 4.41175 13.7109 4.96387V15.6035C13.7109 16.1558 13.2632 16.6035 12.7109 16.6035C12.1587 16.6035 11.7109 16.1558 11.7109 15.6035V4.96387C11.7111 4.41175 12.1588 3.96387 12.7109 3.96387Z" fill="currentColor"/> +</svg> +`,j5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.00916 7.50488C8.47326 7.50488 8.91828 7.68943 9.24646 8.01758C9.57465 8.34577 9.75916 8.79075 9.75916 9.25488C9.75916 9.71901 9.57465 10.164 9.24646 10.4922C8.91828 10.8203 8.47326 11.0049 8.00916 11.0049C7.54507 11.0049 7.10001 10.8203 6.77185 10.4922C6.4437 10.164 6.25916 9.71898 6.25916 9.25488C6.25916 8.79078 6.4437 8.34576 6.77185 8.01758C7.10001 7.68942 7.54507 7.50492 8.00916 7.50488Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M17.8998 4.09961C20.0537 4.09961 21.8002 5.84609 21.8002 8V16C21.8002 18.1539 20.0537 19.9004 17.8998 19.9004H5.89978C3.74598 19.9003 1.99939 18.1538 1.99939 16V8C1.99939 5.84617 3.74598 4.09974 5.89978 4.09961H17.8998ZM15.4867 12.2539C15.448 12.2184 15.3885 12.2192 15.351 12.2559L11.7338 15.8027C11.0146 16.5079 9.87305 16.5222 9.13708 15.835L6.98669 13.8262C6.95049 13.7924 6.89516 13.791 6.85681 13.8223L3.82361 16.2988C3.96873 17.3168 4.84165 18.0995 5.89978 18.0996H17.8998C18.9375 18.0996 19.7964 17.3466 19.9662 16.3574L15.4867 12.2539ZM5.89978 5.90039C4.74009 5.90052 3.80017 6.84028 3.80017 8V14.002L5.73181 12.4238C6.46046 11.8286 7.51253 11.8634 8.20056 12.5059L10.351 14.5146C10.3897 14.5508 10.4498 14.5497 10.4877 14.5127L14.1049 10.9658C14.819 10.2656 15.9506 10.2466 16.6879 10.9219L19.9994 13.9551V8C19.9994 6.8402 19.0596 5.90039 17.8998 5.90039H5.89978Z" fill="currentColor"/> +</svg> +`,V5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M5.09375 2.81174C5.4825 2.50796 6.04376 2.56488 6.34766 2.93869L20.1855 19.9602C20.4895 20.3341 20.421 20.8836 20.0322 21.1877C19.6435 21.4917 19.0823 21.4355 18.7783 21.0617L17.9971 20.1008H5.99609C3.84224 20.1008 2.0958 18.3552 2.0957 16.2014V8.13889C2.09589 6.26755 3.41429 4.70428 5.17285 4.32639L4.93945 4.03928C4.63577 3.66536 4.7051 3.11573 5.09375 2.81174ZM7.13184 14.1096C7.09416 14.0738 7.03659 14.0713 6.99609 14.1037L3.92871 16.5569C4.09761 17.5472 4.95753 18.301 5.99609 18.301H16.5342L13.373 14.4133L11.9072 15.9455C11.1531 16.7324 9.92202 16.7621 9.13281 16.0119L7.13184 14.1096ZM5.99609 6.03928C4.83643 6.03928 3.89669 6.97927 3.89648 8.13889V14.1408L5.83496 12.5901C6.60469 11.9742 7.69929 12.022 8.41504 12.7024L10.416 14.6037C10.4575 14.6431 10.5218 14.642 10.5615 14.6008L12.1641 12.926L9.78906 10.0051C9.70282 10.2646 9.55682 10.5038 9.35645 10.7004C9.02202 11.0285 8.56767 11.2131 8.09473 11.2131C7.62195 11.213 7.1683 11.0284 6.83398 10.7004C6.49961 10.3724 6.31152 9.92701 6.31152 9.46311C6.3116 8.99941 6.49981 8.55474 6.83398 8.22678C7.12986 7.93654 7.51931 7.75901 7.93262 7.7219L6.56543 6.03928H5.99609Z" fill="currentColor"/> +<path d="M18.0049 4.31272C20.1587 4.31288 21.9043 6.0593 21.9043 8.21311V13.718C21.9039 15.4743 19.7248 16.2906 18.5713 14.966L14.9141 10.7658C14.5882 10.3912 14.6278 9.82271 15.002 9.49631C15.3768 9.16994 15.9451 9.20948 16.2715 9.5842L19.9287 13.7844C19.9528 13.812 19.9696 13.8167 19.9775 13.8186C19.9908 13.8216 20.0141 13.8213 20.04 13.8117C20.0655 13.8021 20.0826 13.7875 20.0908 13.7766C20.0955 13.7702 20.1044 13.7552 20.1045 13.718V8.21311C20.1045 7.05341 19.1645 6.11366 18.0049 6.1135H10.6328C10.1361 6.11327 9.73267 5.70981 9.73242 5.21311C9.73242 4.71619 10.136 4.31295 10.6328 4.31272H18.0049Z" fill="currentColor"/> +</svg> +`,q5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12 2.1001C17.4676 2.10031 21.8994 6.53286 21.8994 12.0005C21.8992 17.4679 17.4674 21.8997 12 21.8999C6.53237 21.8999 2.09982 17.4681 2.09961 12.0005C2.09961 6.53273 6.53224 2.1001 12 2.1001ZM12 3.8999C7.52636 3.8999 3.89941 7.52684 3.89941 12.0005C3.89963 16.474 7.52649 20.1001 12 20.1001C16.4733 20.0999 20.0994 16.4738 20.0996 12.0005C20.0996 7.52697 16.4735 3.90011 12 3.8999ZM12 9.50049C12.4969 9.50068 12.8994 9.87055 12.8994 10.3267V16.6743C12.8992 17.1303 12.4968 17.5003 12 17.5005C11.503 17.5005 11.0998 17.1304 11.0996 16.6743V10.3267C11.0996 9.87043 11.5029 9.50049 12 9.50049ZM12 6.49951C12.4968 6.49951 12.8994 6.90313 12.8994 7.3999C12.8992 7.8965 12.4966 8.30029 12 8.30029C11.5025 8.30028 11.0998 7.8965 11.0996 7.3999C11.0996 6.90313 11.5024 6.49952 12 6.49951Z" fill="currentColor"/> +</svg> +`,K5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.09998C6.53222 2.09998 2.09998 6.53222 2.09998 12C2.09998 17.4677 6.53222 21.9 12 21.9C17.4677 21.9 21.9 17.4677 21.9 12C21.9 6.53222 17.4677 2.09998 12 2.09998ZM3.89998 12C3.89998 7.52633 7.52633 3.89998 12 3.89998C16.4736 3.89998 20.1 7.52633 20.1 12C20.1 16.4736 16.4736 20.1 12 20.1C7.52633 20.1 3.89998 16.4736 3.89998 12Z" fill="currentColor"/> +<path d="M9.4286 9.47153C9.4286 8.97448 9.83154 8.57153 10.3286 8.57153H11.1C11.5971 8.57153 12 8.97448 12 9.47153C12 9.96859 11.5971 10.3715 11.1 10.3715H10.3286C9.83154 10.3715 9.4286 9.96859 9.4286 9.47153Z" fill="currentColor"/> +<path d="M5.14289 9.47155C5.14289 8.97449 5.54583 8.57155 6.04289 8.57155H7.67146C8.16851 8.57155 8.57146 8.97449 8.57146 9.47155C8.57146 9.9686 8.16851 10.3715 7.67146 10.3715H6.04289C5.54583 10.3715 5.14289 9.9686 5.14289 9.47155Z" fill="currentColor"/> +<path d="M8.57146 16.3287C8.57146 15.8316 8.9744 15.4287 9.47145 15.4287H14.5286C15.0257 15.4287 15.4286 15.8316 15.4286 16.3287C15.4286 16.8257 15.0257 17.2287 14.5286 17.2287H9.47145C8.9744 17.2287 8.57146 16.8257 8.57146 16.3287Z" fill="currentColor"/> +<path d="M6.04288 12.0001C5.54583 12.0001 5.14288 12.403 5.14288 12.9001C5.14288 13.3972 5.54583 13.8001 6.04288 13.8001H6.81431C7.31137 13.8001 7.71431 13.3972 7.71431 12.9001C7.71431 12.403 7.31137 12.0001 6.81431 12.0001H6.04288Z" fill="currentColor"/> +<path d="M9.47145 12.0001C8.9744 12.0001 8.57146 12.403 8.57146 12.9001C8.57146 13.3972 8.9744 13.8001 9.47146 13.8001H10.2429C10.7399 13.8001 11.1429 13.3972 11.1429 12.9001C11.1429 12.403 10.7399 12.0001 10.2429 12.0001H9.47145Z" fill="currentColor"/> +<path d="M12.8572 9.47153C12.8572 8.97448 13.2601 8.57153 13.7572 8.57153H14.5286C15.0257 8.57153 15.4286 8.97448 15.4286 9.47153C15.4286 9.96859 15.0257 10.3715 14.5286 10.3715H13.7572C13.2601 10.3715 12.8572 9.96859 12.8572 9.47153Z" fill="currentColor"/> +<path d="M12.9 12.0001C12.403 12.0001 12 12.403 12 12.9001C12 13.3972 12.403 13.8001 12.9 13.8001H13.6715C14.1685 13.8001 14.5715 13.3972 14.5715 12.9001C14.5715 12.403 14.1685 12.0001 13.6715 12.0001H12.9Z" fill="currentColor"/> +<path d="M16.2857 9.47153C16.2857 8.97448 16.6887 8.57153 17.1857 8.57153H17.9572C18.4542 8.57153 18.8572 8.97448 18.8572 9.47153C18.8572 9.96859 18.4542 10.3715 17.9572 10.3715H17.1857C16.6887 10.3715 16.2857 9.96859 16.2857 9.47153Z" fill="currentColor"/> +<path d="M16.3286 12.0001C15.8315 12.0001 15.4286 12.403 15.4286 12.9001C15.4286 13.3972 15.8315 13.8001 16.3286 13.8001H17.9572C18.4542 13.8001 18.8572 13.3972 18.8572 12.9001C18.8572 12.403 18.4542 12.0001 17.9572 12.0001H16.3286Z" fill="currentColor"/> +</svg> +`,Z5e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path id="bar-divider" d="M 9.3 18.951 L 9.3 4.3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> + <path id="bar-box" d="M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="butt" stroke-linejoin="miter" transform="matrix(1 0 0 1 11.8 11.8)"/> + <path id="bar-arrow" d="M -1.25 -2.5 L 1.25 0 L -1.25 2.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> +</svg> +`,G5e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <path id="bar-divider" d="M 9.3 18.951 L 9.3 4.3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> + <path id="bar-box" d="M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="butt" stroke-linejoin="miter" transform="matrix(1 0 0 1 11.8 11.8)"/> + <path id="bar-arrow-expand" d="M -1.25 -2.5 L 1.25 0 L -1.25 2.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> +</svg> +`,Y5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g> +<path d="M12.9 1.7999C12.9 1.30285 12.4971 0.899902 12 0.899902C11.5029 0.899902 11.1 1.30285 11.1 1.7999V2.7999C11.1 3.29696 11.5029 3.6999 12 3.6999C12.4971 3.6999 12.9 3.29696 12.9 2.7999V1.7999Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M6.1 11.9999C6.1 8.7414 8.74152 6.09988 12 6.09988C15.2585 6.09988 17.9 8.7414 17.9 11.9999C17.9 15.2584 15.2585 17.8999 12 17.8999C8.74152 17.8999 6.1 15.2584 6.1 11.9999ZM12 7.89988C9.73563 7.89988 7.9 9.73551 7.9 11.9999C7.9 14.2642 9.73563 16.0999 12 16.0999C14.2644 16.0999 16.1 14.2642 16.1 11.9999C16.1 9.73551 14.2644 7.89988 12 7.89988Z" fill="currentColor"/> +<path d="M0.899994 11.9999C0.899994 11.5028 1.30294 11.0999 1.79999 11.0999H2.79999C3.29705 11.0999 3.69999 11.5028 3.69999 11.9999C3.69999 12.4969 3.29705 12.8999 2.79999 12.8999H1.79999C1.30294 12.8999 0.899994 12.4969 0.899994 11.9999Z" fill="currentColor"/> +<path d="M12 20.2991C12.4971 20.2991 12.9 20.702 12.9 21.1991V22.1991C12.9 22.6961 12.4971 23.0991 12 23.0991C11.5029 23.0991 11.1 22.6961 11.1 22.1991V21.1991C11.1 20.702 11.5029 20.2991 12 20.2991Z" fill="currentColor"/> +<path d="M21.2016 11.0999C20.7045 11.0999 20.3016 11.5028 20.3016 11.9999C20.3016 12.4969 20.7045 12.8999 21.2016 12.8999H22.2016C22.6986 12.8999 23.1016 12.4969 23.1016 11.9999C23.1016 11.5028 22.6986 11.0999 22.2016 11.0999H21.2016Z" fill="currentColor"/> +<path d="M20.1995 3.79903C20.551 4.1505 20.551 4.72035 20.1995 5.07182L19.4924 5.77893C19.141 6.1304 18.5711 6.1304 18.2196 5.77893C17.8682 5.42746 17.8682 4.85761 18.2196 4.50614L18.9268 3.79903C19.2782 3.44756 19.8481 3.44756 20.1995 3.79903Z" fill="currentColor"/> +<path d="M19.4942 18.2215C19.1427 17.87 18.5729 17.87 18.2214 18.2215C17.87 18.573 17.87 19.1428 18.2214 19.4943L18.9285 20.2014C19.28 20.5529 19.8498 20.5529 20.2013 20.2014C20.5528 19.8499 20.5528 19.2801 20.2013 18.9286L19.4942 18.2215Z" fill="currentColor"/> +<path d="M5.78079 18.2213C6.13227 18.5727 6.13227 19.1426 5.78079 19.4941L5.07369 20.2012C4.72222 20.5526 4.15237 20.5526 3.8009 20.2012C3.44942 19.8497 3.44942 19.2798 3.8009 18.9284L4.508 18.2213C4.85947 17.8698 5.42932 17.8698 5.78079 18.2213Z" fill="currentColor"/> +<path d="M5.07077 3.79912C4.7193 3.44764 4.14945 3.44764 3.79798 3.79912C3.4465 4.15059 3.4465 4.72044 3.79798 5.07191L4.50508 5.77901C4.85655 6.13049 5.4264 6.13049 5.77787 5.77902C6.12935 5.42754 6.12935 4.85769 5.77787 4.50622L5.07077 3.79912Z" fill="currentColor"/> +</g> +</svg> +`,X5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M3.97427 8.06961C4.99348 7.33581 6.18946 7.1 7.00001 7.1H9.00001C9.49706 7.1 9.90001 7.50294 9.90001 8C9.90001 8.49706 9.49706 8.9 9.00001 8.9H7.00001C6.47755 8.9 5.67353 9.06419 5.02599 9.53039C4.42434 9.96356 3.90001 10.6934 3.90001 12C3.90001 13.3066 4.42434 14.0364 5.02599 14.4696C5.67353 14.9358 6.47755 15.1 7.00001 15.1H9.00001C9.49706 15.1 9.90001 15.5029 9.90001 16C9.90001 16.4971 9.49706 16.9 9.00001 16.9H7.00001C6.18946 16.9 4.99348 16.6642 3.97427 15.9304C2.90917 15.1636 2.10001 13.8934 2.10001 12C2.10001 10.1066 2.90917 8.83644 3.97427 8.06961ZM14.1 8C14.1 7.50294 14.5029 7.1 15 7.1H17C17.8105 7.1 19.0065 7.33581 20.0257 8.06961C21.0908 8.83644 21.9 10.1066 21.9 12C21.9 13.8934 21.0908 15.1636 20.0257 15.9304C19.0065 16.6642 17.8105 16.9 17 16.9H15C14.5029 16.9 14.1 16.4971 14.1 16C14.1 15.5029 14.5029 15.1 15 15.1H17C17.5225 15.1 18.3265 14.9358 18.974 14.4696C19.5757 14.0364 20.1 13.3066 20.1 12C20.1 10.6934 19.5757 9.96356 18.974 9.53039C18.3265 9.06419 17.5225 8.9 17 8.9H15C14.5029 8.9 14.1 8.49706 14.1 8ZM7.10001 12C7.10001 11.5029 7.50295 11.1 8.00001 11.1H16C16.4971 11.1 16.9 11.5029 16.9 12C16.9 12.4971 16.4971 12.9 16 12.9H8.00001C7.50295 12.9 7.10001 12.4971 7.10001 12Z" fill="currentColor"/> +</svg> +`,J5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M4.10001 5.99998C4.10001 5.50292 4.50295 5.09998 5.00001 5.09998H19C19.4971 5.09998 19.9 5.50292 19.9 5.99998C19.9 6.49703 19.4971 6.89998 19 6.89998H5.00001C4.50295 6.89998 4.10001 6.49703 4.10001 5.99998ZM4.10001 12C4.10001 11.5029 4.50295 11.1 5.00001 11.1H19C19.4971 11.1 19.9 11.5029 19.9 12C19.9 12.497 19.4971 12.9 19 12.9H5.00001C4.50295 12.9 4.10001 12.497 4.10001 12ZM4.10001 18C4.10001 17.5029 4.50295 17.1 5.00001 17.1H19C19.4971 17.1 19.9 17.5029 19.9 18C19.9 18.497 19.4971 18.9 19 18.9H5.00001C4.50295 18.9 4.10001 18.497 4.10001 18Z" fill="currentColor"/> +</svg> +`,Q5e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<g> +<path fill-rule="evenodd" clip-rule="evenodd" d="M18 4.09961C20.1539 4.09961 21.9004 5.84609 21.9004 8V16C21.9004 18.1539 20.1539 19.9004 18 19.9004H6C3.84609 19.9004 2.09961 18.1539 2.09961 16V8C2.09961 5.84609 3.84609 4.09961 6 4.09961H18ZM3.90039 16C3.90039 17.1598 4.8402 18.0996 6 18.0996H18C19.1598 18.0996 20.0996 17.1598 20.0996 16V9.49805L13.5361 13.5361C12.5955 14.1147 11.4075 14.1084 10.4727 13.5205L3.90039 9.38672V16ZM6 5.90039C5.0746 5.90039 4.29039 6.49909 4.01074 7.33008L11.4316 11.9971C11.7861 12.2199 12.2361 12.2222 12.5928 12.0029L20.0195 7.43457C19.7725 6.54993 18.9636 5.90039 18 5.90039H6Z" fill="currentColor"/> +</g> +</svg> +`,e6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M17 11.0996C17.4971 11.0996 17.9004 11.5029 17.9004 12C17.9004 12.4971 17.4971 12.9004 17 12.9004H7C6.50294 12.9004 6.09961 12.4971 6.09961 12C6.09961 11.5029 6.50294 11.0996 7 11.0996H17Z" fill="currentColor"/> +</svg> +`,t6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M15.182 3.32802C15.9304 2.72235 17.0309 2.76978 17.724 3.46767L18.5424 4.29189L18.6722 4.43642C19.2377 5.13495 19.234 6.1404 18.6635 6.83486L18.5326 6.97841L18.0248 7.48232C17.9549 7.55172 17.8793 7.61254 17.8021 7.66884C17.9794 8.18027 17.9316 8.7498 17.6595 9.22841C17.6847 9.24522 17.7091 9.2635 17.7328 9.2831L17.8002 9.3456L17.9847 9.53798C19.8515 11.5442 20.4549 14.0022 19.6224 16.2196C19.1921 17.3657 18.4025 18.3827 17.2992 19.203H19.0873L19.1801 19.2079C19.6337 19.2542 19.9877 19.6375 19.9877 20.1034C19.9876 20.5692 19.6337 20.9527 19.1801 20.9989L19.0873 21.0028H13.0385C13.0244 21.0033 13.0104 21.0031 12.9965 21.0028H4.9115C4.41448 21.0028 4.01117 20.6004 4.01111 20.1034C4.01111 19.6064 4.41444 19.203 4.9115 19.203H12.9047C15.7614 18.5471 17.3679 17.1023 17.9369 15.5868C18.4678 14.1726 18.179 12.4782 16.807 10.9188L16.5189 10.6093L16.4574 10.5399C16.4549 10.5368 16.453 10.5333 16.4506 10.5302L12.3011 14.6522C11.6031 15.3454 10.5023 15.3845 9.75818 14.7733L9.61365 14.6425L7.31091 12.3231C6.5717 11.5786 6.57617 10.376 7.32068 9.63662L12.3676 4.62392L12.5121 4.49404C13.0358 4.06988 13.7318 3.96755 14.3402 4.18251C14.3969 4.10597 14.4591 4.03197 14.5287 3.96279L15.0365 3.45791L15.182 3.32802ZM4.83044 12.9335C5.16112 12.6052 5.68305 12.5863 6.03552 12.8759L6.10291 12.9384L9.07361 15.9286L9.13513 15.997C9.42218 16.3514 9.3992 16.8727 9.06873 17.2011C8.7381 17.5294 8.21712 17.5482 7.86462 17.2587L7.79626 17.1972L4.82654 14.2069L4.76501 14.1376C4.47792 13.7831 4.49979 13.2619 4.83044 12.9335ZM13.6693 5.87978L13.6361 5.90126L8.58826 10.914C8.54935 10.9529 8.54943 11.0165 8.58826 11.0556L10.891 13.3739L10.9242 13.3964C10.9602 13.4111 11.0032 13.404 11.0326 13.3749L16.0795 8.3622L16.1019 8.329C16.1117 8.3049 16.1117 8.2779 16.1019 8.2538L16.0804 8.2206L13.7777 5.90224C13.7486 5.87289 13.7054 5.86535 13.6693 5.87978ZM16.3383 4.71376L16.3051 4.73525L15.7972 5.24013C15.7584 5.27904 15.7585 5.34166 15.7972 5.38076L16.6146 6.20498L16.6478 6.22744C16.6838 6.24221 16.7268 6.23487 16.7562 6.20595L17.264 5.70107L17.2865 5.66787C17.2962 5.64382 17.2963 5.61672 17.2865 5.59267L17.265 5.55947L16.4467 4.73623C16.4174 4.70681 16.3744 4.6992 16.3383 4.71376Z" fill="currentColor"/> +</svg> +`,n6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M6 12C6 12.8283 5.32834 13.5 4.5 13.5C3.67166 13.5 3 12.8283 3 12C3 11.1717 3.67166 10.5 4.5 10.5C5.32834 10.5 6 11.1717 6 12Z" fill="currentColor"/> +<path d="M13.5 12C13.5 12.8283 12.8283 13.5 12 13.5C11.1717 13.5 10.5 12.8283 10.5 12C10.5 11.1717 11.1717 10.5 12 10.5C12.8283 10.5 13.5 11.1717 13.5 12Z" fill="currentColor"/> +<path d="M19.5002 13.5C20.3287 13.5 21 12.8287 21 12.0002C21 11.1718 20.3287 10.5 19.5002 10.5C18.6718 10.5 18 11.1718 18 12.0002C18 12.8287 18.6718 13.5 19.5002 13.5Z" fill="currentColor"/> +</svg> +`,o6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M8 12.0993C8.49691 12.0993 8.90016 12.5028 8.90039 12.9997V17.9997C8.90039 19.6013 7.60163 20.9001 6 20.9001C4.39837 20.9001 3.09961 19.6013 3.09961 17.9997C3.09984 16.3982 4.39852 15.0993 6 15.0993C6.38939 15.0993 6.76033 15.1778 7.09961 15.317V12.9997C7.09984 12.5028 7.50309 12.0993 8 12.0993ZM6 16.9001C5.39263 16.9001 4.90062 17.3923 4.90039 17.9997C4.90039 18.6072 5.39249 19.0993 6 19.0993C6.60751 19.0993 7.09961 18.6072 7.09961 17.9997C7.09938 17.3923 6.60737 16.9001 6 16.9001Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M18.627 3.35611C19.8025 3.12106 20.9001 4.02068 20.9004 5.21939V15.9997C20.9004 17.6013 19.6016 18.9001 18 18.9001C16.3984 18.9001 15.0996 17.6013 15.0996 15.9997C15.0998 14.3982 16.3985 13.0993 18 13.0993C18.3894 13.0993 18.7603 13.1778 19.0996 13.317V9.21939C19.0993 9.15657 19.0421 9.10946 18.9805 9.12173L12.6768 10.3825C12.1894 10.4799 11.7148 10.1637 11.6172 9.67642C11.52 9.18922 11.8361 8.71439 12.3232 8.61685L18.627 7.35611C18.7868 7.32415 18.9452 7.31502 19.0996 7.32291V5.21939C19.0993 5.15657 19.0421 5.10946 18.9805 5.12173L12.6768 6.38248C12.1894 6.47994 11.7148 6.16372 11.6172 5.67642C11.52 5.18922 11.8361 4.71439 12.3232 4.61685L18.627 3.35611ZM18 14.9001C17.3926 14.9001 16.9006 15.3923 16.9004 15.9997C16.9004 16.6072 17.3925 17.0993 18 17.0993C18.6075 17.0993 19.0996 16.6072 19.0996 15.9997C19.0994 15.3923 18.6074 14.9001 18 14.9001Z" fill="currentColor"/> +<path d="M7.32422 5.38931C7.61669 4.87032 8.38346 4.87015 8.67578 5.38931L8.73047 5.50845L8.89551 5.95376L8.97949 6.1481C9.19937 6.58817 9.57968 6.93145 10.0459 7.10415L10.4912 7.26919C11.127 7.50461 11.1666 8.36217 10.6104 8.67544L10.4912 8.73013L10.0459 8.89517C9.5799 9.06783 9.19939 9.41141 8.97949 9.85123L8.89551 10.0456L8.73047 10.4909C8.49495 11.1267 7.63737 11.1665 7.32422 10.61L7.26953 10.4909L7.10449 10.0456C6.93172 9.57931 6.58767 9.19898 6.14746 8.97916L5.9541 8.89517L5.50879 8.73013C4.83054 8.47903 4.83061 7.52037 5.50879 7.26919L5.9541 7.10415L6.14746 7.02017C6.58757 6.80032 6.93176 6.41995 7.10449 5.95376L7.26953 5.50845L7.32422 5.38931Z" fill="currentColor"/> +</svg> +`,s6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M17.9551 6.32648C17.955 5.82951 17.5517 5.42706 17.0547 5.42706H15.4844C14.9875 5.42717 14.5851 5.82958 14.585 6.32648V17.6732C14.585 18.1701 14.9874 18.5734 15.4844 18.5735H17.0547C17.5518 18.5735 17.9551 18.1702 17.9551 17.6732V6.32648ZM19.7549 17.6732C19.7549 19.1643 18.5459 20.3734 17.0547 20.3734H15.4844C13.9933 20.3732 12.7842 19.1643 12.7842 17.6732V6.32648C12.7843 4.83546 13.9934 3.62639 15.4844 3.62628H17.0547C18.5458 3.62628 19.7548 4.8354 19.7549 6.32648V17.6732Z" fill="currentColor"/> +<path d="M9.41571 6.32648C9.41561 5.82951 9.01231 5.42706 8.51532 5.42706H6.94501C6.44811 5.42717 6.0457 5.82958 6.04559 6.32648V17.6732C6.04559 18.1701 6.44804 18.5734 6.94501 18.5735H8.51532C9.01238 18.5735 9.41571 18.1702 9.41571 17.6732V6.32648ZM11.2155 17.6732C11.2155 19.1643 10.0065 20.3734 8.51532 20.3734H6.94501C5.45393 20.3732 4.24481 19.1643 4.24481 17.6732V6.32648C4.24492 4.83546 5.45399 3.62639 6.94501 3.62628H8.51532C10.0064 3.62628 11.2154 4.8354 11.2155 6.32648V17.6732Z" fill="currentColor"/> +</svg> +`,i6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M18.0176 4.89998C17.7305 4.89998 17.4552 5.014 17.2522 5.217L6.35429 16.1149C5.957 16.5122 5.67517 17.01 5.53889 17.5551L5.23691 18.763L6.44486 18.4611C6.98994 18.3248 7.48773 18.0429 7.88502 17.6456L18.783 6.74773C18.8834 6.64728 18.9631 6.52797 19.0176 6.39658C19.072 6.26517 19.1 6.12441 19.1 5.98236C19.1 5.84031 19.072 5.69956 19.0176 5.56815C18.9631 5.43676 18.8834 5.31745 18.783 5.217C18.6825 5.11649 18.5631 5.03676 18.4318 4.98237C18.3005 4.92798 18.1597 4.89998 18.0176 4.89998ZM15.9794 3.94421C16.52 3.40366 17.2531 3.09998 18.0176 3.09998C18.3961 3.09998 18.7709 3.17452 19.1207 3.31938C19.4704 3.46424 19.7881 3.67656 20.0558 3.94421C20.3235 4.21192 20.5357 4.52969 20.6805 4.87932C20.8254 5.22895 20.9 5.60375 20.9 5.98236C20.9 6.36098 20.8254 6.73578 20.6805 7.08541C20.5357 7.43504 20.3235 7.75281 20.0558 8.02052L17.6385 10.4378L9.15781 18.9184C8.52984 19.5464 7.74301 19.9919 6.88142 20.2073L4.21828 20.8731C3.91158 20.9498 3.58714 20.8599 3.3636 20.6364C3.14006 20.4128 3.05019 20.0884 3.12686 19.7817L3.79264 17.1185C4.00803 16.257 4.45351 15.4701 5.0815 14.8421L15.9794 3.94421Z" fill="currentColor"/> +</svg> +`,r6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.76251 3.10547C8.25776 3.10552 8.74422 3.23849 9.17072 3.49023L19.533 9.60742C20.8536 10.3869 21.2922 12.0901 20.5174 13.4121C20.2785 13.8195 19.9398 14.1604 19.533 14.4004L9.16974 20.5156C7.84721 21.2958 6.14595 20.8511 5.36993 19.5273C5.1196 19.1003 4.98719 18.6142 4.98712 18.1191V5.88672C4.98716 4.3537 6.2273 3.10547 7.76251 3.10547ZM6.7879 18.1191C6.78797 18.2945 6.8343 18.4664 6.92267 18.6172C7.19638 19.0841 7.79336 19.2377 8.25568 18.9648L18.618 12.8496C18.7607 12.7654 18.8803 12.6458 18.9647 12.502C19.2393 12.0334 19.082 11.4311 18.618 11.1572L8.25568 5.04102C8.1061 4.95273 7.93562 4.9063 7.76251 4.90625C7.22703 4.90625 6.78794 5.34218 6.7879 5.88672V18.1191Z" fill="currentColor"/> +</svg> +`,l6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z" fill="currentColor"/> +<path d="M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 3.7998C7.47126 3.7998 3.7998 7.47126 3.7998 12C3.7998 16.5287 7.47126 20.2002 12 20.2002C16.5287 20.2002 20.2002 16.5287 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998Z" fill="currentColor"/> +</svg> +`,a6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M12 2C13.1046 2 14 2.89543 14 4C14 4.78019 13.552 5.45353 12.9004 5.7832V7H16.5C18.1569 7 19.5 8.34315 19.5 10V17C19.5 18.6051 18.2394 19.9158 16.6543 19.9961L16.5 20H7.5L7.3457 19.9961C5.81166 19.9184 4.58163 18.6883 4.50391 17.1543L4.5 17V10C4.5 8.34315 5.84315 7 7.5 7H11.0996V5.7832C10.448 5.45353 10 4.78019 10 4C10 2.89543 10.8954 2 12 2ZM7.5 8.7998C6.83726 8.7998 6.2998 9.33726 6.2998 10V17C6.2998 17.6627 6.83726 18.2002 7.5 18.2002H16.5C17.1627 18.2002 17.7002 17.6627 17.7002 17V10C17.7002 9.33726 17.1627 8.7998 16.5 8.7998H7.5ZM3 10.7666C3.49706 10.7666 3.90039 11.1699 3.90039 11.667V15C3.90039 15.4971 3.49706 15.9004 3 15.9004C2.50294 15.9004 2.09961 15.4971 2.09961 15V11.667C2.09961 11.1699 2.50294 10.7666 3 10.7666ZM21 10.7666C21.4971 10.7666 21.9004 11.1699 21.9004 11.667V15C21.9004 15.4971 21.4971 15.9004 21 15.9004C20.5029 15.9004 20.0996 15.4971 20.0996 15V11.667C20.0996 11.1699 20.5029 10.7666 21 10.7666ZM9.5 11.0996C9.99706 11.0996 10.4004 11.5029 10.4004 12V14.5C10.4004 14.9971 9.99706 15.4004 9.5 15.4004C9.00294 15.4004 8.59961 14.9971 8.59961 14.5V12C8.59961 11.5029 9.00294 11.0996 9.5 11.0996ZM14.5 11.0996C14.9971 11.0996 15.4004 11.5029 15.4004 12V14.5C15.4004 14.9971 14.9971 15.4004 14.5 15.4004C14.0029 15.4004 13.5996 14.9971 13.5996 14.5V12C13.5996 11.5029 14.0029 11.0996 14.5 11.0996ZM12 3.5C11.7239 3.5 11.5 3.72386 11.5 4C11.5 4.27614 11.7239 4.5 12 4.5C12.2761 4.5 12.5 4.27614 12.5 4C12.5 3.72386 12.2761 3.5 12 3.5Z" fill="currentColor"/> +</svg> +`,u6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.5 3C16.1944 3 20 6.80558 20 11.5C20 13.523 19.2933 15.381 18.1132 16.8404L21.1364 19.8636C21.4879 20.2151 21.4879 20.7849 21.1364 21.1364C20.7849 21.4879 20.2151 21.4879 19.8636 21.1364L16.8404 18.1132C15.381 19.2933 13.523 20 11.5 20C6.80558 20 3 16.1944 3 11.5C3 6.80558 6.80558 3 11.5 3ZM11.5 18.2C15.2003 18.2 18.2 15.2003 18.2 11.5C18.2 7.79969 15.2003 4.8 11.5 4.8C7.79969 4.8 4.8 7.79969 4.8 11.5C4.8 15.2003 7.79969 18.2 11.5 18.2Z" fill="currentColor"/> +</svg> +`,c6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M16.5364 10.1636C16.8879 10.5151 16.8879 11.0849 16.5364 11.4364C16.1849 11.7879 15.6151 11.7879 15.2636 11.4364L12.9 9.07281V17.1C12.9 17.597 12.4971 18 12 18C11.503 18 11.1 17.597 11.1 17.1V9.07281L8.73641 11.4364C8.38494 11.7879 7.81509 11.7879 7.46362 11.4364C7.11214 11.0849 7.11214 10.5151 7.46362 10.1636L11.3636 6.2636C11.7151 5.91211 12.2849 5.91211 12.6364 6.2636L16.5364 10.1636Z" fill="currentColor"/> +</svg> +`,d6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M16.0404 12C16.0404 9.76874 14.2313 7.9596 12.0001 7.9596C9.76883 7.9596 7.95972 9.76874 7.95972 12C7.95972 14.2313 9.76883 16.0404 12.0001 16.0404C14.2313 16.0404 16.0404 14.2313 16.0404 12ZM14.2222 12C14.2222 13.2271 13.2271 14.2222 12 14.2222C10.7729 14.2222 9.77783 13.2271 9.77783 12C9.77783 10.7729 10.7729 9.77778 12 9.77778C13.2271 9.77778 14.2222 10.7729 14.2222 12Z" fill="currentColor"/> +<path d="M9.91145 21.8009C9.29001 21.6797 8.76914 21.2612 8.50632 20.6922L8.07372 19.7556C7.88838 19.3544 7.43553 19.1048 6.95371 19.1549L5.89572 19.2647C5.2733 19.3293 4.64823 19.114 4.22298 18.6611C3.74343 18.1504 3.32454 17.6037 2.97033 17.0181C2.61571 16.4318 2.32839 15.8106 2.10407 15.1566C1.89769 14.5549 2.02148 13.8954 2.4089 13.3902L3.0376 12.5704C3.30043 12.2277 3.30042 11.7722 3.03758 11.4295L2.40413 10.6035C2.01474 10.0958 1.891 9.43198 2.10208 8.82826C2.55037 7.54612 3.27017 6.35997 4.22 5.34259C4.64518 4.8872 5.27275 4.67067 5.89701 4.73544L6.95383 4.84514C7.43561 4.89515 7.88844 4.6456 8.07377 4.24441L8.50266 3.31593C8.76494 2.74818 9.28448 2.33019 9.90423 2.20761C11.2916 1.9332 12.7148 1.93127 14.0885 2.19913C14.7099 2.32029 15.2308 2.73881 15.4937 3.3078L15.9263 4.24441C16.1116 4.6456 16.5644 4.89514 17.0462 4.84514L18.1043 4.73532C18.7267 4.67072 19.3518 4.88603 19.777 5.33886C20.2566 5.84953 20.6755 6.3963 21.0297 6.98193C21.3843 7.56823 21.6716 8.18942 21.8959 8.84339C22.1023 9.44509 21.9785 10.1046 21.5911 10.6098L20.9624 11.4295C20.6996 11.7722 20.6996 12.2278 20.9624 12.5705L21.5959 13.3964C21.9853 13.9042 22.109 14.568 21.8979 15.1717C21.4497 16.4538 20.7299 17.6399 19.7801 18.6573C19.3549 19.1128 18.7273 19.3294 18.103 19.2646L17.0462 19.1549C16.5645 19.1049 16.1116 19.3544 15.9263 19.7556L15.4974 20.6841C15.2351 21.2518 14.7156 21.6698 14.0958 21.7924C12.7083 22.0668 11.2852 22.0687 9.91145 21.8009ZM13.7432 20.0088C13.7844 20.0006 13.8259 19.9673 13.847 19.9216L14.2758 18.9931C14.7915 17.8768 15.9886 17.2171 17.2341 17.3464L18.2909 17.4561C18.3649 17.4638 18.4272 17.4423 18.4512 17.4166C19.2296 16.5828 19.8171 15.6146 20.1817 14.5716C20.1845 14.5636 20.1796 14.5373 20.1532 14.5029L19.5198 13.677C18.7564 12.6815 18.7564 11.3185 19.5198 10.323L20.1485 9.5033C20.1746 9.46927 20.1795 9.4429 20.1762 9.43327C19.9932 8.89965 19.7603 8.39623 19.4741 7.92293C19.1873 7.4489 18.846 7.00333 18.4517 6.58351C18.4272 6.55739 18.3656 6.53616 18.2921 6.54378L17.234 6.65361C15.9886 6.78287 14.7915 6.12317 14.2758 5.00689L13.8432 4.07027C13.822 4.02448 13.7811 3.9916 13.7406 3.98371C12.5983 3.76097 11.4132 3.76258 10.2571 3.99124C10.2158 3.99941 10.1744 4.03271 10.1533 4.07842L9.72441 5.00689C9.20875 6.12317 8.01164 6.7829 6.76619 6.6536L5.70942 6.54391C5.63535 6.53623 5.573 6.55774 5.54905 6.5834C4.77067 7.41713 4.18312 8.38534 3.81845 9.42835C3.81564 9.43637 3.82054 9.46265 3.84693 9.49706L4.48038 10.323C5.24381 11.3185 5.24383 12.6815 4.48041 13.6769L3.85171 14.4967C3.82561 14.5307 3.82066 14.5571 3.82396 14.5667C4.00701 15.1004 4.23986 15.6038 4.52613 16.0771C4.81284 16.5511 5.15421 16.9967 5.54845 17.4165C5.57298 17.4426 5.63461 17.4638 5.70811 17.4562L6.76608 17.3464C8.01157 17.2171 9.20871 17.8768 9.72438 18.9932L10.157 19.9297C10.1781 19.9755 10.2191 20.0084 10.2595 20.0163C11.4018 20.239 12.587 20.2374 13.7432 20.0088Z" fill="currentColor"/> +</svg> +`,f6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7Z" fill="currentColor"/> +<path d="M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z" fill="currentColor"/> +<path d="M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z" fill="currentColor"/> +</svg> +`,p6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M2.90005 12C2.90005 11.503 3.303 11.1 3.80005 11.1H12.2939L9.38588 8.19197C9.03441 7.8405 9.03441 7.27065 9.38588 6.91918C9.73735 6.56771 10.3072 6.56771 10.6587 6.91918L15.1031 11.3636C15.2719 11.5324 15.3667 11.7613 15.3667 12C15.3667 12.2387 15.2719 12.4676 15.1031 12.6364L10.6587 17.0809C10.3072 17.4323 9.73735 17.4323 9.38588 17.0809C9.03441 16.7294 9.03441 16.1595 9.38588 15.8081L12.2939 12.9H3.80005C3.303 12.9 2.90005 12.4971 2.90005 12ZM13.5874 20C13.5874 19.503 13.9904 19.1 14.4874 19.1H18.043C18.2758 19.1 18.4991 19.0075 18.6637 18.8429C18.8283 18.6783 18.9208 18.455 18.9208 18.2222V5.7778C18.9208 5.545 18.8283 5.32174 18.6637 5.15712C18.499 4.9925 18.2758 4.90002 18.043 4.90002H14.4874C13.9904 4.90002 13.5874 4.49708 13.5874 4.00002C13.5874 3.50297 13.9904 3.10003 14.4874 3.10003H18.043C18.7532 3.10003 19.4343 3.38215 19.9365 3.88433C20.4386 4.38651 20.7208 5.06761 20.7208 5.7778V18.2222C20.7208 18.9324 20.4386 19.6135 19.9365 20.1157C19.4343 20.6179 18.7532 20.9 18.043 20.9H14.4874C13.9904 20.9 13.5874 20.4971 13.5874 20Z" fill="currentColor"/> +</svg> +`,h6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M20.6364 11.3636C20.9879 11.7151 20.9879 12.2849 20.6364 12.6364L16.1919 17.0808C15.8405 17.4323 15.2706 17.4323 14.9192 17.0808C14.5677 16.7293 14.5677 16.1595 14.9192 15.808L17.8272 12.9H9.33333C8.83627 12.9 8.43333 12.497 8.43333 12C8.43333 11.5029 8.83627 11.1 9.33333 11.1H17.8272L14.9192 8.19193C14.5677 7.84046 14.5677 7.27061 14.9192 6.91914C15.2706 6.56766 15.8405 6.56766 16.1919 6.91914L20.6364 11.3636ZM10.2333 3.99998C10.2333 4.49703 9.83038 4.89998 9.33333 4.89998H5.77777C5.54497 4.89998 5.3217 4.99246 5.15709 5.15707C4.99247 5.32169 4.89999 5.54495 4.89999 5.77775V18.2222C4.89999 18.455 4.99247 18.6783 5.15709 18.8429C5.32171 19.0075 5.54497 19.1 5.77777 19.1H9.33333C9.83038 19.1 10.2333 19.5029 10.2333 20C10.2333 20.497 9.83038 20.9 9.33333 20.9H5.77777C5.06758 20.9 4.38648 20.6179 3.8843 20.1157C3.38212 19.6135 3.09999 18.9324 3.09999 18.2222V5.77775C3.09999 5.06756 3.38212 4.38646 3.8843 3.88428C4.38648 3.3821 5.06758 3.09998 5.77777 3.09998H9.33333C9.83038 3.09998 10.2333 3.50292 10.2333 3.99998Z" fill="currentColor"/> +</svg> +`,m6e='<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 6H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M18.0 6H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="6" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 12H6.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M10.5 12H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="8.5" cy="12" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 18H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M18.0 18H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="18" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/></svg>',g6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M7.78027 8.90405C7.5 9.45411 7.5 10.1742 7.5 11.6144V12.3856C7.5 13.8258 7.5 14.5459 7.78027 15.096C8.02681 15.5798 8.42019 15.9732 8.90405 16.2197C9.45411 16.5 10.1742 16.5 11.6144 16.5H12.3856C13.8258 16.5 14.5459 16.5 15.096 16.2197C15.5798 15.9732 15.9732 15.5798 16.2197 15.096C16.5 14.5459 16.5 13.8258 16.5 12.3856V11.6144C16.5 10.1742 16.5 9.45411 16.2197 8.90405C15.9732 8.42019 15.5798 8.02681 15.096 7.78027C14.5459 7.5 13.8258 7.5 12.3856 7.5H11.6144C10.1742 7.5 9.45411 7.5 8.90405 7.78027C8.42019 8.02681 8.02681 8.42019 7.78027 8.90405Z" fill="currentColor"/> +</svg> +`,v6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.01562 3.41459C7.4446 3.16449 7.9954 3.30924 8.24609 3.73784C8.49645 4.167 8.35189 4.71868 7.92285 4.96928C5.51497 6.37506 3.90054 8.98498 3.90039 11.9703C3.90076 16.4435 7.52672 20.0699 12 20.0699C16.4733 20.0699 20.0992 16.4435 20.0996 11.9703C20.0996 11.2291 20 10.5116 19.8145 9.83159C19.6838 9.35222 19.967 8.85702 20.4463 8.72612C20.9256 8.59541 21.4207 8.87778 21.5518 9.35698C21.7792 10.1901 21.9004 11.0674 21.9004 11.9703C21.9 17.4376 17.4674 21.8697 12 21.8697C6.53261 21.8697 2.09998 17.4376 2.09961 11.9703C2.09976 8.31904 4.07782 5.12972 7.01562 3.41459ZM8.39258 8.24077C8.75015 7.89591 9.3199 7.90591 9.66504 8.26323C10.01 8.62076 9.99985 9.19051 9.64258 9.53569C9.00203 10.1541 8.60558 11.02 8.60547 11.979C8.60584 13.8536 10.1253 15.3736 12 15.3736C13.8746 15.3735 15.3942 13.8536 15.3945 11.979C15.3945 11.6847 15.3577 11.3989 15.2881 11.1285C15.1646 10.6474 15.4536 10.1568 15.9346 10.0328C16.4158 9.9089 16.9071 10.1991 17.0312 10.6802C17.1383 11.096 17.1943 11.5321 17.1943 11.979C17.194 14.8477 14.8688 17.1733 12 17.1734C9.1312 17.1734 6.80506 14.8478 6.80469 11.979C6.8048 10.5117 7.41519 9.18431 8.39258 8.24077ZM11.5459 1.12651C11.8216 0.965605 12.1631 0.963306 12.4414 1.11967L19.1953 4.91752C19.4859 5.08108 19.662 5.39277 19.6533 5.72612C19.6443 6.05972 19.4515 6.36154 19.1523 6.50932L12.9004 9.5933V12.2583C12.9004 12.7554 12.4971 13.1587 12 13.1587C11.5029 13.1587 11.0996 12.7554 11.0996 12.2583V1.90385C11.0999 1.58444 11.2702 1.2878 11.5459 1.12651ZM12.9004 7.58549L16.8252 5.64897L12.9004 3.44194V7.58549Z" fill="currentColor"/> +</svg> +`,y6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9893 6.60743C20.5897 6.60757 21.8877 7.8926 21.8877 9.47736C21.8877 10.7416 21.0607 11.8129 19.9141 12.1955V14.257C19.914 15.8428 18.6152 17.1288 17.0137 17.1289H12.8438V20.1381C12.8437 20.6301 12.4412 21.0293 11.9443 21.0296C11.4473 21.0296 11.044 20.6302 11.0439 20.1381V16.4356C11.0441 15.8343 11.5363 15.3461 12.1436 15.3458H17.0137C17.6211 15.3457 18.1133 14.8585 18.1133 14.257V12.2129C16.9408 11.8451 16.0909 10.7598 16.0908 9.47736C16.0908 7.89251 17.3887 6.60743 18.9893 6.60743ZM18.9893 8.38953C18.3828 8.38953 17.8906 8.87684 17.8906 9.47736C17.8907 10.0778 18.3828 10.5642 18.9893 10.5642C19.5956 10.5641 20.0869 10.0777 20.0869 9.47736C20.0869 8.87693 19.5956 8.38967 18.9893 8.38953Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M4.89844 6.60743C6.49899 6.60747 7.79688 7.89254 7.79688 9.47736C7.79684 10.7388 6.97371 11.8078 5.83105 12.1926V14.4021C5.83105 15.0036 6.32315 15.4918 6.93066 15.4918H8.37109C8.86789 15.492 9.27038 15.8905 9.27051 16.3824C9.27051 16.8744 8.86797 17.2737 8.37109 17.2739H6.93066C5.32904 17.2739 4.03027 15.9879 4.03027 14.4021V12.2158C2.85382 11.8504 2.00004 10.7627 2 9.47736C2 7.89251 3.29784 6.60743 4.89844 6.60743ZM4.89844 8.38953C4.29196 8.38953 3.7998 8.87684 3.7998 9.47736C3.79985 10.0778 4.29198 10.5642 4.89844 10.5642C5.50485 10.5642 5.99605 10.0778 5.99609 9.47736C5.99609 8.87687 5.50488 8.38958 4.89844 8.38953Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9434 2.9707C13.5439 2.97075 14.8418 4.25581 14.8418 5.84063C14.8418 7.11413 14.0035 8.1923 12.8438 8.56745V13.0135C12.8436 13.5056 12.4403 13.9041 11.9434 13.9041C11.4466 13.9039 11.0431 13.5055 11.043 13.0135V8.56745C9.8836 8.19209 9.04496 7.11387 9.04492 5.84063C9.04492 4.25592 10.343 2.97093 11.9434 2.9707ZM11.9434 4.75281C11.3371 4.75303 10.8447 5.24026 10.8447 5.84063C10.8448 6.44097 11.3371 6.92726 11.9434 6.92749C12.5498 6.92745 13.041 6.44108 13.041 5.84063C13.041 5.24014 12.5498 4.75285 11.9434 4.75281Z" fill="currentColor"/> +</svg> +`,k6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M16.5293 15.0596C16.9496 15.1021 17.2772 15.4572 17.2773 15.8887C17.2773 16.3202 16.9497 16.6753 16.5293 16.7178L16.4443 16.7217H12C11.5399 16.7216 11.167 16.3488 11.167 15.8887C11.1671 15.4286 11.54 15.0558 12 15.0557H16.4443L16.5293 15.0596Z" fill="currentColor"/> +<path d="M6.96582 7.52246C7.27077 7.21751 7.75375 7.1983 8.08105 7.46484L8.14453 7.52246L10.8232 10.2002C11.5102 10.8872 11.5102 12.0014 10.8232 12.6885L8.14453 15.3672L8.08105 15.4248C7.75377 15.6913 7.27075 15.6721 6.96582 15.3672C6.66114 15.0621 6.64234 14.5791 6.90918 14.252L6.96582 14.1885L9.64453 11.5098C9.68057 11.4736 9.68062 11.415 9.64453 11.3789L6.96582 8.7002C6.64116 8.37488 6.6411 7.84774 6.96582 7.52246Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M17 3.09961C19.1539 3.09966 20.9004 4.84612 20.9004 7V17C20.9004 19.1539 19.1539 20.9003 17 20.9004H7C4.84609 20.9004 3.09961 19.1539 3.09961 17V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H17ZM7 4.90039C5.8402 4.90039 4.90039 5.8402 4.90039 7V17C4.90039 18.1598 5.8402 19.0996 7 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V7C19.0996 5.84024 18.1598 4.90044 17 4.90039H7Z" fill="currentColor"/> +</svg> +`,b6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M16.9971 3.90597C15.9799 2.99725 14.7342 2.38312 13.394 2.12966C12.0538 1.8762 10.6699 1.99301 9.39111 2.46751C8.11236 2.94202 6.98721 3.75626 6.13676 4.82261C5.2863 5.88896 4.74274 7.16703 4.56457 8.5193C4.40455 9.70501 4.53253 10.9118 4.93767 12.0376C5.34281 13.1634 6.01318 14.175 6.89207 14.9868C7.43557 15.4634 7.87413 16.0477 8.17997 16.7027C8.48581 17.3577 8.65224 18.0691 8.66873 18.7918V18.926C8.66962 19.7412 8.99387 20.5229 9.57035 21.0993C10.1468 21.6758 10.9285 22.0001 11.7437 22.001H12.2604C13.0757 22.0001 13.8573 21.6758 14.4338 21.0993C15.0103 20.5229 15.3345 19.7412 15.3354 18.926V18.4685C15.3479 17.8297 15.4982 17.2011 15.7761 16.6258C16.0539 16.0505 16.4528 15.542 16.9454 15.1351C17.7442 14.4355 18.3853 13.5741 18.826 12.608C19.2668 11.642 19.4973 10.5932 19.5022 9.53136C19.5071 8.46948 19.2863 7.41869 18.8544 6.4486C18.4225 5.4785 17.7894 4.61125 16.9971 3.9043V3.90597ZM12.2604 20.3343H11.7437C11.3704 20.3339 11.0124 20.1853 10.7484 19.9213C10.4844 19.6573 10.3358 19.2993 10.3354 18.926C10.3354 18.926 10.3296 18.7093 10.3287 18.6676H13.6687V18.926C13.6683 19.2993 13.5198 19.6573 13.2558 19.9213C12.9917 20.1853 12.6338 20.3339 12.2604 20.3343ZM15.8437 13.8835C14.8949 14.7064 14.2097 15.7908 13.8737 17.001H12.8354V11.0143C13.3212 10.8426 13.742 10.5249 14.0403 10.1049C14.3387 9.68482 14.4999 9.18285 14.5021 8.66763C14.5021 8.44662 14.4143 8.23466 14.258 8.07838C14.1017 7.9221 13.8897 7.8343 13.6687 7.8343C13.4477 7.8343 13.2358 7.9221 13.0795 8.07838C12.9232 8.23466 12.8354 8.44662 12.8354 8.66763C12.8354 8.88865 12.7476 9.10061 12.5913 9.25689C12.435 9.41317 12.2231 9.50097 12.0021 9.50097C11.7811 9.50097 11.5691 9.41317 11.4128 9.25689C11.2565 9.10061 11.1687 8.88865 11.1687 8.66763C11.1687 8.44662 11.0809 8.23466 10.9247 8.07838C10.7684 7.9221 10.5564 7.8343 10.3354 7.8343C10.1144 7.8343 9.90242 7.9221 9.74614 8.07838C9.58986 8.23466 9.50207 8.44662 9.50207 8.66763C9.5042 9.18285 9.66547 9.68482 9.96381 10.1049C10.2621 10.5249 10.683 10.8426 11.1687 11.0143V17.001H10.0671C9.69123 15.7586 8.98633 14.6411 8.02707 13.7668C7.21286 13.0081 6.63267 12.0324 6.35496 10.9547C6.07725 9.87703 6.1136 8.7424 6.45974 7.68471C6.80588 6.62702 7.44735 5.69042 8.30846 4.98543C9.16956 4.28045 10.2144 3.83649 11.3196 3.70597C11.5487 3.68039 11.779 3.66759 12.0096 3.66763C13.4409 3.66338 14.8226 4.19149 15.8862 5.1493C16.5026 5.69896 16.9952 6.37337 17.3312 7.12782C17.6672 7.88227 17.839 8.69952 17.8352 9.5254C17.8314 10.3513 17.6522 11.1669 17.3092 11.9183C16.9663 12.6696 16.4677 13.3395 15.8462 13.8835H15.8437Z" fill="currentColor"/> +</svg> +`,C6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M9.28994 4.92561C9.6436 4.57634 9.64716 4.0065 9.29789 3.65284C8.94862 3.29918 8.37878 3.29563 8.02512 3.6449L5.91339 5.73041L5.16642 4.95888C4.82067 4.60177 4.2509 4.59256 3.89379 4.9383C3.53668 5.28404 3.52747 5.85382 3.87321 6.21093L5.25245 7.63551C5.41956 7.80811 5.64874 7.90674 5.88897 7.90943C6.1292 7.91213 6.36053 7.81866 6.53146 7.64985L9.28994 4.92561Z" fill="currentColor"/> +<path d="M12 5.10022C11.503 5.10022 11.1 5.50316 11.1 6.00022C11.1 6.49728 11.503 6.90022 12 6.90022L19.9965 6.90022C20.4935 6.90022 20.8965 6.49728 20.8965 6.00022C20.8965 5.50316 20.4935 5.10022 19.9965 5.10022L12 5.10022Z" fill="currentColor"/> +<path d="M12 11.1002C11.503 11.1002 11.1 11.5032 11.1 12.0002C11.1 12.4973 11.503 12.9002 12 12.9002H19.9965C20.4935 12.9002 20.8965 12.4973 20.8965 12.0002C20.8965 11.5032 20.4935 11.1002 19.9965 11.1002L12 11.1002Z" fill="currentColor"/> +<path d="M11.1 18.0002C11.1 17.5032 11.503 17.1002 12 17.1002L19.9965 17.1002C20.4935 17.1002 20.8965 17.5032 20.8965 18.0002C20.8965 18.4973 20.4935 18.9002 19.9965 18.9002H12C11.503 18.9002 11.1 18.4973 11.1 18.0002Z" fill="currentColor"/> +<path d="M9.29789 9.77064C9.64716 10.1243 9.6436 10.6941 9.28994 11.0434L6.53146 13.7676C6.36053 13.9365 6.1292 14.0299 5.88897 14.0272C5.64874 14.0245 5.41956 13.9259 5.25245 13.7533L3.87321 12.3287C3.52747 11.9716 3.53668 11.4018 3.89379 11.0561C4.2509 10.7104 4.82067 10.7196 5.16642 11.0767L5.91339 11.8482L8.02512 9.76269C8.37878 9.41342 8.94862 9.41698 9.29789 9.77064Z" fill="currentColor"/> +<path d="M9.29789 15.7436C9.64716 16.0973 9.6436 16.6671 9.28994 17.0164L6.53146 19.7406C6.36053 19.9094 6.1292 20.0029 5.88897 20.0002C5.64874 19.9975 5.41956 19.8989 5.25245 19.7263L3.87321 18.3017C3.52747 17.9446 3.53668 17.3748 3.89379 17.0291C4.2509 16.6833 4.82067 16.6926 5.16642 17.0497L5.91339 17.8212L8.02512 15.7357C8.37878 15.3864 8.94862 15.39 9.29789 15.7436Z" fill="currentColor"/> +</svg> +`,w6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path fill-rule="evenodd" clip-rule="evenodd" d="M8.09752 2.19507C8.5421 1.97278 9.08271 2.15298 9.305 2.59756L10.0562 4.10005H13.5C13.9971 4.10005 14.4 4.50299 14.4 5.00005C14.4 5.49711 13.9971 5.90005 13.5 5.90005H12.3106C12.2556 6.2319 12.1667 6.64073 12.0226 7.0987C11.7254 8.04355 11.191 9.20402 10.2334 10.3239C11.4166 11.196 12.5606 11.7524 13.4512 12.0987C13.978 12.3036 14.4136 12.434 14.7124 12.5122L14.7348 12.5181L15.695 10.5976C15.8475 10.2927 16.1591 10.1 16.5 10.1C16.8409 10.1 17.1525 10.2927 17.305 10.5976L20.7969 17.5814L20.8044 17.5959L20.8137 17.615L21.805 19.5976C22.0273 20.0421 21.8471 20.5827 21.4025 20.805C20.9579 21.0273 20.4173 20.8471 20.195 20.4025L19.4438 18.9H13.5562L12.805 20.4025C12.5827 20.8471 12.0421 21.0273 11.5975 20.805C11.1529 20.5827 10.9727 20.0421 11.195 19.5976L12.1863 17.615C12.1917 17.6036 12.1973 17.5924 12.2031 17.5814L13.9146 14.1583C13.6034 14.0667 13.2256 13.9423 12.7988 13.7764C11.7294 13.3605 10.3442 12.6802 8.92538 11.5924C7.79753 12.5167 6.69473 13.0764 5.83285 13.4112C5.33899 13.603 4.92286 13.7216 4.62401 13.7931C4.47449 13.8288 4.35399 13.8529 4.26741 13.8684C4.2241 13.8762 4.18924 13.8818 4.16343 13.8858L4.13156 13.8904L4.12084 13.8919L4.11682 13.8924L4.11514 13.8927C4.11514 13.8927 4.11368 13.8928 4.00001 13L4.11368 13.8928C3.62061 13.9556 3.17 13.6068 3.10722 13.1137C3.0446 12.6219 3.39148 12.1723 3.88256 12.1077L3.94947 12.0967C4.00428 12.0869 4.09114 12.0698 4.20543 12.0424C4.43422 11.9877 4.77156 11.8924 5.18106 11.7334C5.84103 11.477 6.68484 11.0564 7.56458 10.3753C7.15054 9.93496 6.78945 9.48388 6.50421 9.10102C6.26672 8.78224 6.07517 8.50172 5.94227 8.29973C5.87571 8.19858 5.82359 8.11671 5.78748 8.05909C5.76942 8.03027 5.75535 8.00749 5.74545 7.99135L5.73377 7.9722L5.73032 7.96651L5.72864 7.96371C5.71133 7.9349 5.69582 7.9055 5.68208 7.87566C5.49265 7.46416 5.6393 6.96717 6.03659 6.72853C6.09037 6.69623 6.14617 6.6702 6.20315 6.65023C6.59739 6.51205 7.04758 6.66421 7.27129 7.03623L7.27266 7.0385L7.28001 7.05054C7.28695 7.06186 7.29793 7.07964 7.31274 7.10328C7.34239 7.15059 7.38731 7.2212 7.44595 7.31032C7.56343 7.48886 7.73484 7.73997 7.94765 8.02562C8.21085 8.37889 8.52772 8.77187 8.8756 9.14201C9.64226 8.24147 10.0681 7.3133 10.3056 6.55854C10.381 6.3186 10.4372 6.09683 10.4791 5.90005H9.51951C9.50696 5.90031 9.49442 5.90031 9.48191 5.90005H4.00001C3.50296 5.90005 3.10001 5.49711 3.10001 5.00005C3.10001 4.50299 3.50296 4.10005 4.00001 4.10005H8.04378L7.69503 3.40254C7.67314 3.35877 7.65516 3.31407 7.64094 3.26883C7.51078 2.8546 7.69671 2.39547 8.09752 2.19507ZM16.5 13.0125L18.5438 17.1H14.4562L16.5 13.0125Z" fill="currentColor"/> +<path d="M15.1 4.00007C15.1 3.50301 15.5029 3.10007 16 3.10007H18C19.6016 3.10007 20.9 4.39844 20.9 6.00007V8.00007C20.9 8.49712 20.497 8.90007 20 8.90007C19.5029 8.90007 19.1 8.49712 19.1 8.00007V6.00007C19.1 5.39255 18.6075 4.90007 18 4.90007H16C15.5029 4.90007 15.1 4.49712 15.1 4.00007Z" fill="currentColor"/> +<path d="M3.99998 15.1001C4.49703 15.1001 4.89998 15.503 4.89998 16.0001V18.0001C4.89998 18.6076 5.39246 19.1001 5.99998 19.1001H7.99998C8.49703 19.1001 8.89998 19.503 8.89998 20.0001C8.89998 20.4971 8.49703 20.9001 7.99998 20.9001H5.99998C4.39835 20.9001 3.09998 19.6017 3.09998 18.0001V16.0001C3.09998 15.503 3.50292 15.1001 3.99998 15.1001Z" fill="currentColor"/> +</svg> +`,_6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M8.10001 3C8.10001 2.50294 8.50295 2.1 9.00001 2.1H15C15.4971 2.1 15.9 2.50294 15.9 3C15.9 3.49706 15.4971 3.9 15 3.9H9.00001C8.50295 3.9 8.10001 3.49706 8.10001 3Z" fill="currentColor"/> +<path d="M10 15.9C9.50295 15.9 9.10001 15.4971 9.10001 15L9.10001 10C9.10001 9.50294 9.50295 9.1 10 9.1C10.4971 9.1 10.9 9.50294 10.9 10L10.9 15C10.9 15.4971 10.4971 15.9 10 15.9Z" fill="currentColor"/> +<path d="M13.1 15C13.1 15.4971 13.5029 15.9 14 15.9C14.4971 15.9 14.9 15.4971 14.9 15L14.9 10C14.9 9.50294 14.4971 9.1 14 9.1C13.5029 9.1 13.1 9.50294 13.1 10V15Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M2.10001 6C2.10001 5.50294 2.50295 5.1 3.00001 5.1H4.99152C4.99785 5.09993 5.00417 5.09993 5.01048 5.1H18.9895C18.9958 5.09993 19.0021 5.09993 19.0085 5.1H21C21.4971 5.1 21.9 5.50294 21.9 6C21.9 6.49706 21.4971 6.9 21 6.9H19.8281L18.8448 18.6993C18.7412 19.9432 17.7013 20.9 16.4531 20.9H7.54686C6.29865 20.9 5.25881 19.9432 5.15515 18.6993L4.17188 6.9H3.00001C2.50295 6.9 2.10001 6.49706 2.10001 6ZM5.97811 6.9L18.0219 6.9L17.0511 18.5498C17.0251 18.8608 16.7652 19.1 16.4531 19.1H7.54686C7.23481 19.1 6.97485 18.8608 6.94893 18.5498L5.97811 6.9Z" fill="currentColor"/> +</svg> +`,x6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M7.36336 3.3634C7.71483 3.01192 8.28533 3.01192 8.6368 3.3634C8.98817 3.71488 8.98824 4.2854 8.6368 4.63683L6.17391 7.09972H15.0001C18.2585 7.09977 20.9005 9.74166 20.9005 13.0001C20.9004 16.2585 18.2585 18.9005 15.0001 18.9005H7.00008C6.50307 18.9005 6.09976 18.4971 6.09969 18.0001C6.09969 17.5031 6.50302 17.0997 7.00008 17.0997H15.0001C17.2644 17.0997 19.0996 15.2644 19.0997 13.0001C19.0997 10.7358 17.2644 8.90055 15.0001 8.90051H6.17391L8.6368 11.3634L8.69832 11.4318C8.98668 11.7853 8.96632 12.3073 8.6368 12.6368C8.30728 12.9663 7.78521 12.9867 7.43172 12.6984L7.36336 12.6368L3.36336 8.63683C3.33098 8.60445 3.30286 8.56908 3.27645 8.53332C3.25597 8.50559 3.23607 8.47741 3.21883 8.44738C3.20492 8.42311 3.19221 8.39837 3.18074 8.37316C3.1764 8.36365 3.17109 8.35453 3.16707 8.34484C3.1627 8.33427 3.1593 8.32331 3.15535 8.31261C3.12946 8.24274 3.11237 8.16872 3.10457 8.09191C3.09258 7.97426 3.10262 7.85446 3.1368 7.74035C3.14281 7.72035 3.15094 7.70114 3.15828 7.68176C3.16165 7.67283 3.16341 7.66325 3.16707 7.65441C3.17216 7.64216 3.17806 7.63025 3.18367 7.61828C3.19055 7.60356 3.19744 7.58874 3.20516 7.57433C3.24709 7.49624 3.3012 7.42556 3.36336 7.3634L7.36336 3.3634Z" fill="currentColor"/> +</svg> +`,S6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.9997 12.8779C16.0197 12.878 19.4393 15.3848 20.7048 18.8828C21.0812 19.9234 20.2782 20.8962 19.2038 21.0137L18.9861 21.0264H5.0134L4.79562 21.0137C3.7213 20.8961 2.91743 19.9233 3.29367 18.8828C4.55905 15.3847 7.9797 12.8781 11.9997 12.8779ZM11.9997 14.6777C8.84467 14.6779 6.17462 16.5794 5.09152 19.2256H18.9079C17.8248 16.5793 15.1549 14.6778 11.9997 14.6777ZM12.2312 3.00586C14.6088 3.1264 16.4997 5.09239 16.4997 7.5L16.4939 7.73145C16.3734 10.1091 14.4073 11.9999 11.9997 12C9.59225 11.9998 7.62604 10.109 7.50558 7.73145L7.49973 7.5C7.49973 5.01485 9.51462 3.00021 11.9997 3L12.2312 3.00586ZM11.9997 4.7998C10.5087 4.80001 9.29953 6.00896 9.29953 7.5C9.29953 8.99104 10.5087 10.2 11.9997 10.2002C13.4908 10.2001 14.6999 8.99112 14.6999 7.5C14.6999 6.00888 13.4908 4.79989 11.9997 4.7998Z" fill="currentColor"/> +</svg> +`,A6e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z" fill="currentColor"/> +<path d="M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z" fill="currentColor"/> +<path fill-rule="evenodd" clip-rule="evenodd" d="M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z" fill="currentColor"/> +</svg> +`,M6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm11-2v16"/><path d="m9 10l2 2l-2 2"/></g></svg>',T6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3L18 10a3 3 0 0 0-6-6l-6.5 6.5a4.5 4.5 0 0 0 9 9L21 13"/></svg>',E6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12A2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3m16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5"/></svg>',I6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M9 3V1H7v2H3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4V1h-2v2zm-5 7h16v9H4zm0-5h3v1h2V5h6v1h2V5h3v3H4zm5.879 5.964L12 13.086l2.121-2.122l1.415 1.415l-2.122 2.121l2.121 2.121l-1.414 1.414L12 15.915l-2.121 2.12l-1.415-1.414l2.122-2.12l-2.122-2.122z"/></svg>',L6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M7 3V1h2v2h6V1h2v2h4a1 1 0 0 1 1 1v5h-2V5h-3v2h-2V5H9v2H7V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm10 9a4 4 0 1 0 0 8a4 4 0 0 0 0-8m-6 4a6 6 0 1 1 12 0a6 6 0 0 1-12 0m5-3v3.414l2.293 2.293l1.414-1.414L18 15.586V13z"/></svg>',$6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1zm11 10H4v8h16zM8 14v2H6v-2zm10 0v2h-8v-2zM7 5H4v4h16V5h-3v2h-2V5H9v2H7z"/></svg>',N6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414z"/></svg>',F6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-4-7h8a4 4 0 0 1-8 0m0-2a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m8 0a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3"/></svg>',R6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"/></svg>',O6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12 3c5.392 0 9.878 3.88 10.819 9c-.94 5.12-5.427 9-10.819 9s-9.878-3.88-10.818-9C2.122 6.88 6.608 3 12 3m0 16a9.005 9.005 0 0 0 8.778-7a9.005 9.005 0 0 0-17.555 0A9.005 9.005 0 0 0 12 19m0-2.5a4.5 4.5 0 1 1 0-9a4.5 4.5 0 0 1 0 9m0-2a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5"/></svg>',P6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M17.883 19.297A10.95 10.95 0 0 1 12 21c-5.392 0-9.878-3.88-10.818-9A11 11 0 0 1 4.52 5.935L1.394 2.808l1.414-1.414l19.799 19.798l-1.414 1.415zM5.936 7.35A8.97 8.97 0 0 0 3.223 12a9.005 9.005 0 0 0 13.201 5.838l-2.028-2.028A4.5 4.5 0 0 1 8.19 9.604zm6.978 6.978l-3.242-3.241a2.5 2.5 0 0 0 3.241 3.241m7.893 2.265l-1.431-1.431A8.9 8.9 0 0 0 20.778 12A9.005 9.005 0 0 0 9.552 5.338L7.974 3.76C9.221 3.27 10.58 3 12 3c5.392 0 9.878 3.88 10.819 9a10.95 10.95 0 0 1-2.012 4.593m-9.084-9.084Q11.86 7.5 12 7.5a4.5 4.5 0 0 1 4.492 4.778z"/></svg>',D6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M15 4H5v16h14V8h-4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008zM11 11V8h2v3h3v2h-3v3h-2v-3H8v-2z"/></svg>',B6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M13 9h8L11 24v-9H4l9-15zm-2 2V7.22L7.532 13H13v4.394L17.263 11z"/></svg>',H6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg>',z6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M6 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2M3 6a3 3 0 1 1 4 2.83V9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-.17a3.001 3.001 0 1 1 2 0V9a4 4 0 0 1-4 4h-2v2.17a3.001 3.001 0 1 1-2 0V13H9a4 4 0 0 1-4-4v-.17A3 3 0 0 1 3 6m15-1a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-6 12a1 1 0 1 0 0 2a1 1 0 0 0 0-2"/></svg>',W6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M15 5h2a2 2 0 0 1 2 2v8.17a3.001 3.001 0 1 1-2 0V7h-2v3l-4.5-4L15 2zM5 8.83a3.001 3.001 0 1 1 2 0v6.34a3.001 3.001 0 1 1-2 0zM6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m0 12a1 1 0 1 0 0-2a1 1 0 0 0 0 2m12 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2"/></svg>',U6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M2 18h7v2H2zm0-7h9v2H2zm0-7h20v2H2zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4 4 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391a4 4 0 0 1-1.435.83L19 21h-2l-.24-1.196a4 4 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4 4 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196a4 4 0 0 1 1.434.83M18 18a2 2 0 1 0 0-4a2 2 0 0 0 0 4"/></svg>',j6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M10 2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H8v2h5V9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H8v6h5v-1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H7a1 1 0 0 1-1-1V8H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm9 16h-4v2h4zm0-8h-4v2h4zM9 4H5v2h4z"/></svg>',V6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m13.827 1.69l8.486 8.485l-1.415 1.414l-.707-.707l-4.242 4.243l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243l1.414-1.414l3.536-.707l4.242-4.243l-.707-.707zm.707 3.536l-4.67 4.67l-2.822.565l6.5 6.5l.564-2.822l4.671-4.67z"/></svg>',q6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M20 4v12h3l-4 5l-4-5h3V4zm-8 14v2H3v-2zm2-7v2H3v-2zm0-7v2H3V4z"/></svg>',K6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928z"/></svg>',Z6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928zm0-2.292l4.247 2.377l-.948-4.773l3.573-3.305l-4.833-.573l-2.038-4.419l-2.039 4.42l-4.833.572l3.573 3.305l-.948 4.773z"/></svg>',G6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M5.33 3.272a3.5 3.5 0 0 1 4.254 4.962l10.709 10.71l-1.414 1.414l-10.71-10.71a3.502 3.502 0 0 1-4.962-4.255L5.444 7.63a1.5 1.5 0 0 0 2.121-2.121zm10.367 1.883l3.182-1.768l1.414 1.415l-1.768 3.182l-1.768.353l-2.12 2.121l-1.415-1.414l2.121-2.121zm-6.718 8.132l1.415 1.414l-5.304 5.303a1 1 0 0 1-1.492-1.327l.078-.087z"/></svg>',Y6e='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m20.97 17.172l-1.414 1.414l-3.535-3.535l-.073.074l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243L5.34 8.761l3.536-.707l.073-.074l-3.536-3.536L6.828 3.03zM10.365 9.394l-.502.502l-2.822.565l6.5 6.5l.564-2.822l.502-.502zm8.411.074l-1.34 1.34l1.414 1.415l1.34-1.34l.707.707l1.415-1.415l-8.486-8.485l-1.414 1.414l.707.707l-1.34 1.34l1.414 1.415l1.34-1.34z"/></svg>',X6e={sm:14,md:16,lg:20};function xt(e,t){return{component:e,svg:t}}const BN={plus:xt(d9e,h5e),"chat-new":xt(h9e,m5e),"calendar-close":xt(lye,I6e),"calendar-schedule":xt(cye,L6e),"calendar-todo":xt(pye,$6e),close:xt(K9e,A5e),check:xt($9e,C5e),archive:xt(v9e,g5e),search:xt(J3e,u6e),copy:xt(n4e,E5e),link:xt(g3e,X5e),"external-link":xt(wye,R6e),download:xt(a4e,L5e),undo:xt(U8e,x6e),send:xt(t8e,c6e),image:xt(G4e,j5e),settings:xt(s8e,d6e),sliders:xt(g8e,m6e),"light-mode":xt(p3e,Y5e),"dark-mode":xt(i4e,I5e),"follow-system":xt(L4e,D5e),"log-in":xt(c8e,p6e),"log-out":xt(p8e,h6e),hand:xt(U4e,W5e),"full-access":xt(F4e,B5e),"shield-question":xt(l8e,f6e),"chevron-down":xt(R9e,w5e),"chevron-right":xt(D9e,_5e),"chevron-up":xt(z9e,x5e),"arrow-up":xt(E9e,b5e),"arrow-down":xt(b9e,v5e),"arrow-right":xt(A9e,k5e),"arrow-left":xt(_9e,y5e),minus:xt(S3e,e6e),microscope:xt(T3e,t6e),"panel-collapse":xt(l3e,Z5e),"panel-collapse-right":xt(J8e,M6e),"panel-expand":xt(c3e,G5e),expand:xt(h4e,N5e),collapse:xt(Y9e,M5e),list:xt(k3e,J5e),"list-settings":xt(qye,U6e),"tree-view":xt(Gye,j6e),sort:xt(t5e,q6e),grip:xt(H4e,z5e),folder:xt(S4e,O5e),"folder-closed":xt(w4e,R5e),"folder-plus":xt(T4e,P5e),"folder-solid":xt(Pye,H6e),file:xt(Gx,Yx),"file-text":xt(k4e,F5e),"file-edit":xt(d4e,$5e),"file-plus":xt(Lye,D6e),"file-off":xt(Gx,Yx),attachment:xt(tye,T6e),"image-off":xt(J4e,V5e),eye:xt(Sye,O6e),"eye-off":xt(Tye,P6e),code:xt(gye,N6e),terminal:xt(T8e,k6e),pencil:xt(H3e,i6e),tool:xt(c5e,G6e),glob:xt(sye,E6e),globe:xt(P4e,H5e),translate:xt(P8e,w6e),"check-list":xt(F8e,C6e),bolt:xt(Fye,B6e),keyboard:xt(s3e,K5e),trash:xt(H8e,_6e),"git-fork":xt(Hye,z6e),"git-pull-request":xt(Uye,W6e),message:xt(Q9e,T5e),mail:xt(w3e,Q5e),user:xt(q8e,S6e),info:xt(t3e,q5e),"help-circle":xt(q3e,l6e),"alert-triangle":xt(G8e,A6e),clock:xt(j9e,S5e),robot:xt(G3e,a6e),sparkles:xt(S8e,y6e),histogram:xt(q4e,U5e),music:xt(F3e,o6e),emoji:xt(kye,F6e),target:xt(w8e,v6e),pause:xt(P3e,s6e),play:xt(U3e,r6e),pin:xt(Jye,V6e),stop:xt(k8e,g6e),star:xt(s5e,K6e),"star-outline":xt(l5e,Z6e),unpin:xt(p5e,Y6e),"dots-horizontal":xt(L3e,n6e),thinking:xt(L8e,b6e)};function J6e(e){return BN[e]}function Q6e(e,t){return e.replace(/<svg\b[^>]*>/,n=>n.replace(/\s(?:width|height)="[^"]*"/g,"")).replace(/^<svg\b/,`<svg class="kw-icon" width="${t}" height="${t}" aria-hidden="true"`)}function yd(e,t="md"){const n=BN[e];return n?Q6e(n.svg,X6e[t]):""}const OVe=[["Actions",["plus","attachment","chat-new","close","check","search","copy","link","external-link","download","undo","send","image","settings","sliders","log-in","log-out","eye","eye-off"]],["Navigation & layout",["chevron-down","chevron-right","chevron-up","arrow-up","arrow-down","arrow-right","arrow-left","minus","panel-collapse","panel-collapse-right","panel-expand","expand","collapse","list","list-settings","tree-view","sort","grip"]],["Files & tools",["folder","folder-closed","folder-plus","folder-solid","file","file-text","file-edit","file-plus","file-off","image-off","code","terminal","pencil","tool","glob","globe","check-list","bolt","git-fork","git-pull-request","archive","pin","unpin","target","calendar-schedule","calendar-todo","calendar-close","keyboard","trash","microscope"]],["Communication",["message","mail","user","robot","emoji","translate"]],["Status & media",["info","help-circle","alert-triangle","hand","full-access","shield-question","clock","histogram","music","sparkles","pause","play","stop","star","star-outline","dots-horizontal","thinking","light-mode","dark-mode","follow-system"]]],G5=(e,t)=>t===void 0?Hn.global.t(e):Hn.global.t(e,t);function _1(e){return RT(G5,e)}function Xx(e,t,n=!1){return wy(G5,e,t,n)}function e7e(e){return HG(G5,e)}const t7e={read:"file-text",bash:"terminal",edit:"pencil",multi_edit:"pencil",write:"file-plus",grep:"search",search:"search",glob:"glob",ls:"folder",web_fetch:"globe",todo:"check-list",task:"sparkles",agentswarm:"sparkles",askuserquestion:"help-circle",exitplanmode:"file-text",creategoal:"target",getgoal:"target",setgoalbudget:"target",updategoal:"target",croncreate:"calendar-schedule",cronlist:"calendar-todo",crondelete:"calendar-close"};function HN(e){const t=Gs(e);let n=t7e[t];return!n&&(e??"").trim().toLowerCase().includes("skill")&&(n="bolt"),n||(n="tool"),n}function zN(e){return yd(HN(e),"sm")}const n7e={class:"op"},o7e={key:0,class:"op-empty"},s7e=et({__name:"OutputPanel",props:{lines:{default:void 0},emptyText:{default:""}},setup(e){const t=e,n=R(()=>t.lines??[]);return(o,s)=>(y(),M("div",n7e,[n.value.length===0&&e.emptyText?(y(),M("div",o7e,N(e.emptyText),1)):ee("",!0),(y(!0),M(Pe,null,pt(n.value,(i,r)=>(y(),M("div",{key:r},N(i),1))),128))]))}}),dr=ft(s7e,[["__scopeId","data-v-ab413c67"]]),i7e=["disabled","aria-label","aria-expanded"],r7e={class:"lead","aria-hidden":"true"},l7e={class:"main"},a7e={class:"task"},u7e={key:0,class:"type"},c7e={class:"tail"},d7e=["aria-label"],f7e=["aria-expanded"],p7e=et({__name:"AgentTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openAgent"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t;function i(g){if(!g)return{};try{const x=JSON.parse(g);return{description:typeof x.description=="string"?x.description:void 0,subagentType:typeof x.subagent_type=="string"?x.subagent_type:void 0}}catch{return{}}}const r=R(()=>i(o.tool.arg)),l=R(()=>o.tool.status),a=R(()=>r.value.description||r.value.subagentType||_1(o.tool.name)),u=R(()=>r.value.description?r.value.subagentType:""),c=nn("resolveAgentTaskId"),d=nn("resolveAgentModel"),f=R(()=>o.tool.agentId??c?.(o.tool.id)),h=R(()=>f.value!==void 0),m=R(()=>d?.(o.tool.id,f.value)),v=R(()=>[u.value,m.value?.display,m.value?.effort].filter(g=>g).join(" · ")),k=R(()=>!!o.tool.output&&o.tool.output.length>0),w=R(()=>h.value||k.value),b=Z(!1);function _(){if(f.value!==void 0){s("openAgent",f.value);return}k.value&&(b.value=!b.value)}return(g,x)=>(y(),M("div",{class:Re(["agent-card",{err:l.value==="error"}])},[C("button",{class:"head",type:"button",disabled:!w.value,"aria-label":h.value?p(n)("tasks.openDetail"):void 0,"aria-expanded":h.value?void 0:b.value,onClick:_},[C("span",r7e,[j(p(Te),{name:"robot",size:"sm"})]),C("span",l7e,[C("span",a7e,N(a.value),1),v.value?(y(),M("span",u7e,N(v.value),1)):ee("",!0)]),C("span",c7e,[C("span",{class:Re(["st",l.value]),role:"status","aria-label":l.value},[l.value==="ok"?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):l.value==="error"?(y(),he(p(Te),{key:1,name:"close",size:"sm"})):(y(),he(p(hc),{key:2,status:"running"}))],10,d7e),h.value?(y(),he(p(Te),{key:0,class:"go",name:"arrow-right",size:"sm","aria-hidden":"true"})):k.value?(y(),he(p(Te),{key:1,class:Re(["go car",{open:b.value}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"])):ee("",!0)])],8,i7e),h.value&&k.value?(y(),M("button",{key:0,class:"saved-result",type:"button","aria-expanded":b.value,onClick:x[0]||(x[0]=S=>b.value=!b.value)},[j(p(Te),{class:Re(["saved-result__chevron",{open:b.value}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"]),C("span",null,N(p(n)("tools.output.saved")),1)],8,f7e)):ee("",!0),k.value&&b.value?(y(),M("div",{key:1,class:Re(["result",{"result--legacy":!h.value}])},[j(dr,{lines:e.tool.output},null,8,["lines"])],2)):ee("",!0)],2))}}),h7e=ft(p7e,[["__scopeId","data-v-7cea5372"]]);function m7e(e){if(!e)return[];try{const n=JSON.parse(e).questions;if(!Array.isArray(n))return[];const o=[];for(const s of n){if(!s||typeof s!="object")continue;const i=s,r=Array.isArray(i.options)?i.options.map(l=>{const a=l&&typeof l=="object"?l:{};return{label:typeof a.label=="string"?a.label:"",description:typeof a.description=="string"?a.description:""}}):[];o.push({question:typeof i.question=="string"?i.question:"",header:typeof i.header=="string"?i.header:"",options:r,multiSelect:i.multi_select===!0})}return o}catch{return[]}}const Nh={recognized:!1,answers:{},note:""};function g7e(e){const t=e?.[0];if(!t)return Nh;let n;try{n=JSON.parse(t)}catch{return Nh}if(!n||typeof n!="object"||Array.isArray(n))return Nh;const o=n.answers;if(!o||typeof o!="object"||Array.isArray(o))return Nh;const s={};for(const[i,r]of Object.entries(o))typeof r=="string"?s[i]=r:r===!0&&(s[i]=!0);return{recognized:!0,answers:s,note:typeof n.note=="string"?n.note:""}}function v7e(e,t,n){return e[t]??e[`q_${n}`]}const y7e=/^opt_\d+_(\d+)$/;function k7e(e,t=[]){if(e===void 0)return{selected:new Set,otherText:"",indeterminate:!1};if(e===!0)return{selected:new Set,otherText:"",indeterminate:!0};const n=new Map;t.forEach((r,l)=>{r.label.length>0&&!n.has(r.label)&&n.set(r.label,l)});const o=n.get(e);if(o!==void 0)return{selected:new Set([o]),otherText:"",indeterminate:!1};const s=new Set,i=[];for(const r of e.split(",")){const l=r.trim(),a=n.get(l);if(a!==void 0){s.add(a);continue}const u=y7e.exec(l);u?s.add(Number(u[1])):l.length>0&&i.push(l)}return{selected:s,otherText:i.join(", "),indeterminate:!1}}const b7e={class:"tl-ic","aria-hidden":"true"},C7e={class:"tl-main"},w7e=["aria-expanded","aria-label"],_7e={class:"tl-tail"},x7e=["aria-label"],S7e=["inert"],A7e={class:"tl-body-inner"},M7e=et({__name:"ToolDisclosure",props:{status:{},open:{type:Boolean,default:!1},expandable:{type:Boolean,default:!1}},emits:["toggle"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=nn("pinScroll",()=>{}),r=Z(null);function l(){if(!n.expandable)return;o("toggle");const u=r.value;u&&yt(()=>i(u))}const a=R(()=>n.open?s("tools.disclosure.collapse"):s("tools.disclosure.expand"));return(u,c)=>(y(),M("div",{class:Re(["tool-line",{open:e.open,expandable:e.expandable,err:e.status==="error"}])},[C("div",{ref_key:"headEl",ref:r,class:Re(["tl-head",{clickable:e.expandable}]),onClick:l},[C("span",b7e,[xn(u.$slots,"leading")]),C("span",C7e,[xn(u.$slots,"default"),j(p(pn),{text:a.value},{default:me(()=>[e.expandable?(y(),M("button",{key:0,class:"tl-car",type:"button","aria-expanded":e.open,"aria-label":a.value,onClick:It(l,["stop"])},[j(p(Te),{class:"tl-car-ic",name:"chevron-right",size:"sm","aria-hidden":"true"})],8,w7e)):ee("",!0)]),_:1},8,["text"])]),C("span",_7e,[xn(u.$slots,"trailing"),C("span",{class:Re(["tl-status",e.status]),role:"status","aria-label":e.status},[e.status==="ok"?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):e.status==="error"?(y(),he(p(Te),{key:1,name:"close",size:"sm"})):e.status==="suspended"?(y(),he(p(hc),{key:2,status:"suspended"})):(y(),he(p(hc),{key:3,status:"running"}))],10,x7e)])],2),e.expandable?(y(),M("div",{key:0,class:Re(["tl-body",{open:e.open}]),inert:!e.open},[C("div",A7e,[xn(u.$slots,"body")])],10,S7e)):ee("",!0)],2))}}),el=ft(M7e,[["__scopeId","data-v-58658159"]]),T7e={key:0,class:"rc-flat"},E7e={class:"rc-head"},I7e={class:"rc-st"},L7e={class:"rc-qtext"},$7e={class:"rc-lb"},N7e={key:0,class:"rc-opt"},F7e={class:"rc-lb"},R7e={class:"rc-ds"},O7e={key:1,class:"rc-opt"},P7e={class:"rc-lb"},D7e={key:2,class:"rc-qskip"},B7e={class:"tl-name"},H7e={key:0,class:"tl-dim"},z7e={key:0,class:"tl-chip"},W7e=80,U7e=et({__name:"AskUserTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile"],setup(e){const t=e,{t:n}=Nt();function o(T,A=W7e){const E=T.trim();return E.length>A?E.slice(0,A-1)+"…":E}const s=R(()=>m7e(t.tool.arg)),i=R(()=>g7e(t.tool.output)),r=R(()=>i.value.recognized),l=R(()=>r.value&&Object.keys(i.value.answers).length===0&&i.value.note.length>0),a=R(()=>s.value.map((T,A)=>k7e(v7e(i.value.answers,T.question,A),T.options))),u=R(()=>Object.keys(i.value.answers).length);function c(T,A){return a.value[T]?.selected.has(A)??!1}function d(T){return a.value[T]?.otherText??""}function f(T){return a.value[T]?.indeterminate??!1}const h=R(()=>t.tool.status),m=R(()=>s.value.map((T,A)=>({q:T,selected:T.options.map((E,P)=>({o:E,oi:P})).filter(({oi:E})=>c(A,E))}))),v=R(()=>s.value.length===1?n("tools.ask.question",{count:1}):n("tools.ask.questions",{count:s.value.length})),k=R(()=>{const T=s.value[0]?.question??"",A=n("tools.ask.unanswered");return T?`${T} —— ${A}`:A}),w=R(()=>{if(!r.value)return o(t.tool.output?.[0]??"");if(l.value)return n("tools.ask.dismissed");const T=s.value[0]?.question??"",A=o(T);return s.value.length<=1?A:`${A} ${n("tools.ask.more",{count:s.value.length-1})}`}),b=R(()=>r.value?l.value?n("tools.ask.dismissed"):u.value===0?"":u.value===1?n("tools.ask.answer",{count:1}):n("tools.ask.answers",{count:u.value}):""),_=R(()=>!!t.tool.output&&t.tool.output.length>0),g=R(()=>r.value&&(s.value.length>0||l.value)||_.value),x=Z(t.tool.defaultExpanded===!0&&g.value),S=R(()=>_1(t.tool.name));return Je(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&g.value&&(x.value=!0)}),(T,A)=>r.value&&h.value==="ok"?(y(),M("div",{key:0,class:Re(["ask-receipt",{flat:l.value||u.value===0}])},[l.value||u.value===0?(y(),M("span",T7e,N(k.value),1)):(y(),M(Pe,{key:1},[C("div",E7e,[C("span",null,N(p(n)("tools.ask.collected"))+" · "+N(v.value),1),C("span",I7e,[j(p(Te),{name:"check",size:"sm"})])]),(y(!0),M(Pe,null,pt(m.value,(E,P)=>(y(),M("div",{key:P,class:"rc-q"},[C("div",L7e,[C("span",null,N(E.q.question),1)]),(y(!0),M(Pe,null,pt(E.selected,D=>(y(),M("div",{key:D.oi,class:"rc-opt"},[C("span",{class:Re(["rc-g on",E.q.multiSelect?"chk":"rad"])},null,2),C("span",$7e,N(D.o.label),1)]))),128)),d(P)?(y(),M("div",N7e,[C("span",{class:Re(["rc-g on",E.q.multiSelect?"chk":"rad"])},null,2),C("span",F7e,N(d(P)),1),C("span",R7e,N(p(n)("tools.ask.freeInput")),1)])):ee("",!0),f(P)?(y(),M("div",O7e,[A[1]||(A[1]=C("span",{class:"rc-g rad on"},null,-1)),C("span",P7e,N(p(n)("tools.ask.answered")),1)])):ee("",!0),E.selected.length===0&&!d(P)&&!f(P)?(y(),M("div",D7e,N(p(n)("tools.ask.unanswered")),1)):ee("",!0)]))),128))],64))],2)):(y(),he(el,{key:1,status:h.value,open:x.value,expandable:g.value,onToggle:A[0]||(A[0]=E=>x.value=!x.value)},{leading:me(()=>[j(p(Te),{name:"help-circle",size:"sm"})]),trailing:me(()=>[b.value?(y(),M("span",z7e,N(b.value),1)):ee("",!0)]),body:me(()=>[j(dr,{lines:e.tool.output},null,8,["lines"])]),default:me(()=>[C("span",B7e,N(S.value),1),w.value?(y(),M("span",H7e,N(w.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),j7e=ft(U7e,[["__scopeId","data-v-f29eda04"]]);function gu(e){const t=(e??"").trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function jn(e){return typeof e=="string"&&e.length>0?e:void 0}function Ia(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function WN(e){if(e)return jn(e.path)??jn(e.file_path)??jn(e.filePath)??jn(e.filename)}function UN(e){return/^(.*)[\\/][^\\/]+[\\/]?$/.exec(e)?.[1]??""}function V7e(e){try{const t=new URL(e),n=t.pathname.split("/").filter(Boolean)[0];return n?`${t.host}/${n}`:t.host}catch{return e.replace(/^https?:\/\//,"")}}const q7e={class:"tl-name"},K7e={class:"tl-mono"},Z7e={key:0,class:"tl-chip"},G7e={class:"cmd-echo"},Y7e=et({__name:"BashTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.tool.status),s=R(()=>{const u=gu(t.tool.arg);return(jn(u?.command)??jn(u?.cmd)??jn(u?.script)??t.tool.arg.replace(/^·\s*/,"")).trim()}),i=R(()=>t.tool.status==="running"),r=R(()=>!!t.tool.output&&t.tool.output.length>0),l=R(()=>r.value||i.value||s.value.length>0),a=Z(t.tool.defaultExpanded===!0&&l.value);return Je(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&l.value&&(a.value=!0)}),(u,c)=>(y(),he(el,{status:o.value,open:a.value,expandable:l.value,onToggle:c[0]||(c[0]=d=>a.value=!a.value)},{leading:me(()=>[j(p(Te),{name:"terminal",size:"sm"})]),trailing:me(()=>[e.tool.timing?(y(),M("span",Z7e,N(e.tool.timing),1)):ee("",!0)]),body:me(()=>[C("div",G7e,N(s.value),1),j(dr,{lines:e.tool.output,"empty-text":i.value?p(n)("tools.output.waiting"):p(n)("tools.output.empty")},null,8,["lines","empty-text"])]),default:me(()=>[C("span",q7e,N(p(n)("tools.label.bash")),1),C("span",K7e,N(s.value),1)]),_:1},8,["status","open","expandable"]))}}),X7e=ft(Y7e,[["__scopeId","data-v-8869dd42"]]),J7e={class:"hl-body"},Q7e={key:0,class:"hl-gutter"},eke={key:1,class:"hl-gutter new"},tke={class:"hl-sign"},nke={class:"hl-text"},oke=["data-line"],ske={key:0,class:"hl-gutter"},ike={class:"hl-text"},rke=200,lke=et({__name:"HighlightedCode",props:{code:{default:void 0},lines:{default:void 0},path:{default:void 0},lineNumbers:{type:[Boolean,Array],default:!1},framed:{type:Boolean,default:!0},fullTexts:{default:null},lineClass:{type:Function,default:void 0}},setup(e){const t=e,n=f2(),o=R(()=>eJ(t.path)),s=R(()=>t.lines!==void 0),i=R(()=>t.lineNumbers===!0&&s.value),r=R(()=>(t.lines??[]).some($=>$.oldNo!==void 0)),l=R(()=>(t.lines??[]).some($=>$.newNo!==void 0)),a=R(()=>Array.isArray(t.lineNumbers)?t.lineNumbers:null),u=R(()=>Array.isArray(t.code)?t.code:Sl(t.code??"")),c=R(()=>{const $=t.lines;return $?t.fullTexts?t.fullTexts:{before:$.filter(B=>B.oldNo!==void 0).map(B=>B.text).join(` +`),after:$.filter(B=>B.newNo!==void 0).map(B=>B.text).join(` +`)}:null}),d=Z(null),f=Z(null),h=Z(null);function m(){d.value=null,f.value=null,h.value=null}let v=null,k=0,w=0;async function b(){const $=++w;k=Date.now();const B=o.value;if(!B){$===w&&m();return}try{const{codeToTokens:H}=await jo(async()=>{const{codeToTokens:U}=await import("./index-BZFTzQ6y.js").then(z=>z.i);return{codeToTokens:U}},[]),O=n.value?"github-dark":"github-light",F=c.value;if(F){const[U,z]=await Promise.all([F.before?H(F.before,{lang:B,theme:O}):Promise.resolve(null),F.after?H(F.after,{lang:B,theme:O}):Promise.resolve(null)]);if($!==w)return;f.value=U?.tokens??null,h.value=z?.tokens??null}else{const U=u.value.length>0?await H(u.value.join(` +`),{lang:B,theme:O}):null;if($!==w)return;d.value=U?.tokens??null}}catch{$===w&&m()}}function _(){if(v!==null)return;const $=Math.max(0,rke-(Date.now()-k));v=setTimeout(()=>{v=null,b()},$)}const g=R(()=>u.value.join(` +`)),x=R(()=>c.value?.before??null),S=R(()=>c.value?.after??null);Je([g,x,S],_),Je([o,n,()=>t.fullTexts],()=>{w++,m(),_()}),dn(b),bn(()=>{w++,v!==null&&clearTimeout(v),v=null});const T=R(()=>{let $=0;if(Array.isArray(t.lineNumbers))for(const B of t.lineNumbers)B>$&&($=B);else for(const B of t.lines??[])B.oldNo!==void 0&&B.oldNo>$&&($=B.oldNo),B.newNo!==void 0&&B.newNo>$&&($=B.newNo);return Math.max(4,String($).length)});function A($){if($.type==="del"){if($.oldNo===void 0)return null;const H=t.fullTexts?$.oldNo-1:E.value.get($.oldNo);return H===void 0?null:f.value?.[H]??null}if($.newNo===void 0)return null;const B=t.fullTexts?$.newNo-1:P.value.get($.newNo);return B===void 0?null:h.value?.[B]??null}const E=R(()=>{const $=new Map;let B=0;for(const H of t.lines??[])H.oldNo!==void 0&&$.set(H.oldNo,B++);return $}),P=R(()=>{const $=new Map;let B=0;for(const H of t.lines??[])H.newNo!==void 0&&$.set(H.newNo,B++);return $});function D($){const B={};$.color&&(B.color=$.color);const H=$.fontStyle??0;return H&1&&(B.fontStyle="italic"),H&2&&(B.fontWeight="var(--weight-semibold)"),H&4&&(B.textDecoration="underline"),B}function I($){return $.type==="add"?"+":$.type==="del"?"-":" "}return($,B)=>(y(),M("div",{class:Re(["hl-code",{gutter:i.value,"plain-pad":!s.value&&!a.value,framed:e.framed}]),style:Zt({"--gutter-ch":`${T.value}ch`})},[C("div",J7e,[s.value?(y(!0),M(Pe,{key:0},pt(e.lines??[],(H,O)=>(y(),M("div",{key:O,class:Re(["hl-row",`row-${H.type}`])},[i.value?(y(),M(Pe,{key:0},[r.value?(y(),M("span",Q7e,N(H.oldNo??""),1)):ee("",!0),l.value?(y(),M("span",eke,N(H.newNo??""),1)):ee("",!0)],64)):ee("",!0),C("span",tke,N(I(H)),1),C("span",nke,[A(H)?(y(!0),M(Pe,{key:0},pt(A(H)??[],(F,U)=>(y(),M("span",{key:U,style:Zt(D(F))},N(F.content),5))),128)):(y(),M(Pe,{key:1},[qe(N(H.text),1)],64))])],2))),128)):(y(!0),M(Pe,{key:1},pt(u.value,(H,O)=>(y(),M("div",{key:O,class:Re(["hl-row",e.lineClass?.(a.value?.[O]??-1)]),"data-line":a.value?.[O]},[a.value?(y(),M("span",ske,N(a.value[O]??""),1)):ee("",!0),C("span",ike,[d.value?.[O]?(y(!0),M(Pe,{key:0},pt(d.value[O]??[],(F,U)=>(y(),M("span",{key:U,style:Zt(D(F))},N(F.content),5))),128)):(y(),M(Pe,{key:1},[qe(N(H),1)],64))])],10,oke))),128))])],6))}}),Ur=ft(lke,[["__scopeId","data-v-6735e4da"]]),ake={class:"tl-name"},uke={key:1,class:"tl-dim"},cke={key:2,class:"tl-faint"},dke={key:0,class:"tl-add"},fke={key:1,class:"tl-del"},pke={class:"diffbar","aria-hidden":"true"},hke={key:1,class:"tl-chip"},mke=et({__name:"EditTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.tool.status),r=R(()=>Gs(n.tool.name)==="write"),l=R(()=>WN(gu(n.tool.arg))??""),a=R(()=>l.value?v1(l.value):""),u=R(()=>l.value?UN(l.value):""),c=R(()=>qT(n.tool)),d=R(()=>FX(n.tool)),f=R(()=>{const x=c.value;return!x||n.tool.status==="error"?{added:0,removed:0}:HT(x)}),h=R(()=>f.value.added>0||f.value.removed>0),m=R(()=>!!n.tool.output&&n.tool.output.length>0),v=R(()=>c.value!==null&&n.tool.status!=="error"),k=R(()=>d.value!==null&&n.tool.status!=="error"),w=R(()=>v.value||k.value||m.value),b=Z(!1),_=Z(b.value);Je(b,x=>{x&&(_.value=!0)});function g(){l.value&&o("openFile",{path:l.value})}return(x,S)=>(y(),he(el,{status:i.value,open:b.value,expandable:w.value,onToggle:S[0]||(S[0]=T=>b.value=!b.value)},{leading:me(()=>[j(p(Te),{name:r.value?"file-plus":"pencil",size:"sm"},null,8,["name"])]),trailing:me(()=>[h.value?(y(),M(Pe,{key:0},[f.value.added>0?(y(),M("span",dke,"+"+N(f.value.added),1)):ee("",!0),f.value.removed>0?(y(),M("span",fke,"−"+N(f.value.removed),1)):ee("",!0),C("span",pke,[C("span",{class:"seg-add",style:Zt({flexGrow:f.value.added})},null,4),C("span",{class:"seg-del",style:Zt({flexGrow:f.value.removed})},null,4)])],64)):r.value&&i.value==="ok"?(y(),M("span",hke,N(p(s)("tools.chip.created")),1)):ee("",!0)]),body:me(()=>[v.value&&_.value?(y(),he(Ur,{key:0,lines:c.value??[],path:l.value},null,8,["lines","path"])):k.value&&_.value?(y(),he(Ur,{key:1,code:d.value?.content??"",path:d.value?.path},null,8,["code","path"])):(y(),he(dr,{key:2,lines:e.tool.output,"empty-text":p(s)("tools.output.waiting")},null,8,["lines","empty-text"]))]),default:me(()=>[C("span",ake,N(r.value?p(s)("tools.label.write"):p(s)("tools.label.edit")),1),a.value?(y(),M("button",{key:0,class:"tl-file",type:"button",onClick:It(g,["stop"])},N(a.value),1)):(y(),M("span",uke,N(l.value||e.tool.arg),1)),u.value?(y(),M("span",cke,N(u.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),gke=ft(mke,[["__scopeId","data-v-bbf61950"]]),vke=["innerHTML"],yke={class:"tl-name"},kke={key:0,class:"tl-dim"},bke={key:0,class:"tl-chip"},Cke={key:1,class:"tl-chip"},wke={key:0,class:"arg-full"},_ke=et({__name:"GenericTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile"],setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.tool.status),s=R(()=>_1(t.tool.name)),i=R(()=>zN(t.tool.name)),r=R(()=>Xx(t.tool.name,t.tool.arg)),l=R(()=>Xx(t.tool.name,t.tool.arg,!0)),a=R(()=>e7e({name:t.tool.name,arg:t.tool.arg,output:t.tool.output,timing:t.tool.timing,status:t.tool.status})),u=R(()=>!!t.tool.output&&t.tool.output.length>0),c=R(()=>u.value||!!l.value&&l.value!==r.value),d=Z(t.tool.defaultExpanded===!0&&c.value);return Je(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status,t.tool.name],()=>{t.tool.defaultExpanded===!0&&c.value&&(d.value=!0)}),(f,h)=>(y(),he(el,{status:o.value,open:d.value,expandable:c.value,onToggle:h[0]||(h[0]=m=>d.value=!d.value)},{leading:me(()=>[C("span",{class:"gl",innerHTML:i.value},null,8,vke)]),trailing:me(()=>[a.value?(y(),M("span",bke,N(a.value),1)):e.tool.timing?(y(),M("span",Cke,N(e.tool.timing),1)):ee("",!0)]),body:me(()=>[l.value&&l.value!==r.value?(y(),M("div",wke,N(l.value),1)):ee("",!0),j(dr,{lines:e.tool.output,"empty-text":o.value==="running"?p(n)("tools.output.waiting"):p(n)("tools.output.empty")},null,8,["lines","empty-text"])]),default:me(()=>[C("span",yke,N(s.value),1),r.value?(y(),M("span",kke,N(r.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),xke=ft(_ke,[["__scopeId","data-v-b12a8498"]]),Ske={class:"tl-name"},Ake={key:0,class:"tl-mono"},Mke={key:1,class:"tl-mono"},Tke={key:2,class:"tl-dim"},Eke={key:3,class:"tl-faint"},Ike={key:0,class:"tl-chip"},Lke={key:0,class:"file-list"},$ke=["onClick"],Nke=et({__name:"GlobTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.tool.status),r=R(()=>Gs(n.tool.name)==="glob"),l=R(()=>gu(n.tool.arg)),a=R(()=>{const v=l.value;return jn(v?.pattern)??jn(v?.glob)??jn(v?.query)??""}),u=R(()=>{const v=l.value;return jn(v?.path)??jn(v?.dir)??jn(v?.directory)??jn(v?.cwd)??""}),c=R(()=>(n.tool.output??[]).filter(v=>v.trim().length>0)),d=R(()=>c.value.length>0),f=R(()=>d.value),h=Z(n.tool.defaultExpanded===!0&&f.value);Je(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&f.value&&(h.value=!0)});function m(v){const k=v.trim();k&&o("openFile",{path:k})}return(v,k)=>(y(),he(el,{status:i.value,open:h.value,expandable:f.value,onToggle:k[0]||(k[0]=w=>h.value=!h.value)},{leading:me(()=>[j(p(Te),{name:r.value?"tree-view":"list",size:"sm"},null,8,["name"])]),trailing:me(()=>[r.value&&c.value.length>0?(y(),M("span",Ike,N(p(s)("tools.chip.files",{count:c.value.length})),1)):ee("",!0)]),body:me(()=>[r.value?(y(),M("div",Lke,[(y(!0),M(Pe,null,pt(c.value,(w,b)=>(y(),M("button",{key:b,class:"file-row",type:"button",onClick:_=>m(w)},N(w),9,$ke))),128))])):(y(),he(dr,{key:1,lines:e.tool.output},null,8,["lines"]))]),default:me(()=>[C("span",Ske,N(p(s)(r.value?"tools.label.glob":"tools.label.ls")),1),r.value&&a.value?(y(),M("span",Ake,N(a.value),1)):!r.value&&u.value?(y(),M("span",Mke,N(u.value),1)):(y(),M("span",Tke,N(e.tool.arg),1)),r.value&&u.value?(y(),M("span",Eke,N(u.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),Fke=ft(Nke,[["__scopeId","data-v-3936099e"]]),Rke={class:"tl-name"},Oke={key:0,class:"tl-dim"},Pke={key:1,class:"tl-pill pill-active"},Dke={key:0,class:"goal-block"},Bke={class:"goal-text"},Hke={key:0,class:"goal-criterion"},zke=et({__name:"GoalTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.tool.status),s=R(()=>Gs(t.tool.name)),i=R(()=>gu(t.tool.arg)),r=R(()=>jn(i.value?.objective)??""),l=R(()=>jn(i.value?.completionCriterion)??jn(i.value?.completion_criterion)??""),a={active:"status.goalStatusActive",blocked:"status.goalStatusBlocked",complete:"status.goalStatusComplete"},u=R(()=>jn(i.value?.status)??""),c=R(()=>{const b=a[u.value];return b?n(b):u.value}),d=R(()=>{switch(u.value){case"complete":return"pill-done";case"blocked":return"pill-blocked";default:return"pill-active"}}),f=R(()=>{const b=Ia(i.value?.value),_=jn(i.value?.unit);return b===void 0||!_?"":["turns","tokens","milliseconds","seconds","minutes","hours"].includes(_)?n(`tools.goal.${_}`,{value:b}):n("tools.goal.budget",{value:b,unit:_})}),h=R(()=>{switch(s.value){case"creategoal":return r.value;case"updategoal":return c.value;case"setgoalbudget":return f.value;default:return""}}),m=R(()=>!!t.tool.output&&t.tool.output.length>0),v=R(()=>!!l.value||s.value==="creategoal"&&m.value),k=R(()=>v.value||m.value),w=Z(t.tool.defaultExpanded===!0&&k.value);return Je(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&k.value&&(w.value=!0)}),(b,_)=>(y(),he(el,{status:o.value,open:w.value,expandable:k.value,onToggle:_[0]||(_[0]=g=>w.value=!w.value)},{leading:me(()=>[j(p(Te),{name:"target",size:"sm"})]),trailing:me(()=>[s.value==="updategoal"&&c.value?(y(),M("span",{key:0,class:Re(["tl-pill",d.value])},N(c.value),3)):s.value==="creategoal"?(y(),M("span",Pke,N(p(n)("status.goalStatusActive")),1)):ee("",!0)]),body:me(()=>[r.value?(y(),M("div",Dke,[C("div",Bke,N(r.value),1),l.value?(y(),M("div",Hke,N(l.value),1)):ee("",!0)])):ee("",!0),m.value?(y(),he(dr,{key:1,lines:e.tool.output},null,8,["lines"])):ee("",!0)]),default:me(()=>[C("span",Rke,N(p(_1)(e.tool.name)),1),h.value?(y(),M("span",Oke,N(h.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),Wke=ft(zke,[["__scopeId","data-v-862274de"]]),Uke={class:"tl-name"},jke={key:0,class:"tl-mono"},Vke={key:1,class:"tl-dim"},qke={key:2,class:"tl-faint"},Kke={key:0,class:"tl-chip"},Zke={key:0,class:"match-list"},Gke=["onClick"],Yke={key:0,class:"mref"},Xke={class:"mtext"},Jke=et({__name:"GrepTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.tool.status),r=R(()=>Gs(n.tool.name)==="grep"),l=R(()=>gu(n.tool.arg)),a=R(()=>{const k=l.value;return jn(k?.pattern)??jn(k?.query)??jn(k?.regex)??""}),u=R(()=>{const k=l.value;return jn(k?.path)??jn(k?.glob)??jn(k?.include)??""}),c=R(()=>(n.tool.output??[]).filter(k=>k.trim().length>0).map(k=>{const w=/^(.+?):(\d+)[:-](.*)$/.exec(k);return w?{path:w[1],line:Number(w[2]),text:(w[3]??"").trim()}:{text:k}})),d=R(()=>c.value.length),f=R(()=>d.value>0),h=R(()=>f.value),m=Z(n.tool.defaultExpanded===!0&&h.value);Je(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&h.value&&(m.value=!0)});function v(k){k.path&&o("openFile",{path:k.path,line:k.line})}return(k,w)=>(y(),he(el,{status:i.value,open:m.value,expandable:h.value,onToggle:w[0]||(w[0]=b=>m.value=!m.value)},{leading:me(()=>[j(p(Te),{name:"search",size:"sm"})]),trailing:me(()=>[d.value>0?(y(),M("span",Kke,N(p(s)("tools.chip.results",{count:d.value})),1)):ee("",!0)]),body:me(()=>[r.value?(y(),M("div",Zke,[(y(!0),M(Pe,null,pt(c.value,(b,_)=>(y(),M("button",{key:_,class:Re(["match-row",{link:b.path}]),type:"button",onClick:g=>v(b)},[b.path?(y(),M("span",Yke,N(b.path)+":"+N(b.line),1)):ee("",!0),C("span",Xke,N(b.text),1)],10,Gke))),128))])):(y(),he(dr,{key:1,lines:e.tool.output},null,8,["lines"]))]),default:me(()=>[C("span",Uke,N(p(s)(r.value?"tools.label.grep":"tools.label.search")),1),a.value?(y(),M("span",jke,N(a.value),1)):(y(),M("span",Vke,N(e.tool.arg),1)),u.value?(y(),M("span",qke,N(u.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),Qke=ft(Jke,[["__scopeId","data-v-899c1a48"]]),ebe=["src","controls","muted"],tbe=["src","alt"],nbe=et({__name:"AuthMedia",props:{url:{},kind:{},alt:{},fileId:{},mediaClass:{default:"u-img"},controls:{type:Boolean,default:!0},muted:{type:Boolean,default:!1}},setup(e){const t=e,n=Z(t.fileId?"":t.url),o=Z(null),s=Z(!t.fileId);let i=null,r=0,l=!1,a=null;function u(){i!==null&&(URL.revokeObjectURL(i),i=null)}async function c(){const d=++r;if(u(),!t.fileId){n.value=t.url;return}if(s.value)try{const f=await _t().getFileBlob(t.fileId),h=URL.createObjectURL(f);if(l||d!==r){URL.revokeObjectURL(h);return}i=h,n.value=i}catch{if(l||d!==r)return;n.value=t.url}}return Je(()=>[t.fileId,t.url,s.value],c,{immediate:!0}),dn(()=>{typeof IntersectionObserver=="function"&&o.value?(a=new IntersectionObserver(d=>{d[0]?.isIntersecting&&(s.value=!0,a?.disconnect(),a=null)},{rootMargin:"200px"}),a.observe(o.value)):s.value=!0}),Vn(()=>{l=!0,a?.disconnect(),a=null,u()}),(d,f)=>e.kind==="video"?(y(),M("video",{key:0,ref_key:"mediaEl",ref:o,class:Re(e.mediaClass),src:n.value||void 0,controls:e.controls,muted:e.muted,playsinline:"",preload:"metadata"},null,10,ebe)):(y(),M("img",{key:1,ref_key:"mediaEl",ref:o,class:Re([e.mediaClass,{"is-resolving":!n.value}]),src:n.value||void 0,alt:e.alt||"",loading:"lazy"},null,10,tbe))}}),i0=ft(nbe,[["__scopeId","data-v-0826404b"]]),obe={class:"media-title"},sbe=["src","alt"],ibe=["aria-label"],rbe={key:0,class:"media-video-tile","aria-hidden":"true"},lbe={class:"media-play-badge","aria-hidden":"true"},abe=["src"],ube=et({__name:"MediaTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia"],setup(e,{emit:t}){const n=e,o=t,s=R(()=>n.tool.status==="ok"?n.tool.media:void 0);function i(d){return d.split(/[\\/]+/).pop()||d}function r(d){return d<1024?`${d} B`:d<1024*1024?`${(d/1024).toFixed(1)} KB`:`${(d/1024/1024).toFixed(1)} MB`}const l=R(()=>{const d=s.value;if(!d)return"";const f=[d.path?i(d.path):n.tool.name];return d.mimeType&&f.push(d.mimeType),d.bytes!==void 0&&f.push(r(d.bytes)),d.dimensions&&f.push(d.dimensions),f.join(" · ")}),a=R(()=>s.value?.url.startsWith("blob:")??!1),u=R(()=>{const d=s.value;return d?.kind==="video"&&d.fileId!==void 0&&!a.value});function c(d){const f=s.value;if(f?.kind!=="image"&&f?.kind!=="video")return;const h=f.kind==="image"?d.currentTarget.querySelector("img"):null;o("openMedia",{media:f,originImg:h})}return(d,f)=>s.value?(y(),M("div",{key:0,class:Re(["media-tool",{mob:e.mobile}])},[j(p(pn),{text:s.value.path||l.value},{default:me(()=>[C("div",obe,N(l.value),1)]),_:1},8,["text"]),s.value.kind==="image"?(y(),he(p(pn),{key:0,text:s.value.path||l.value},{default:me(()=>[C("button",{type:"button",class:"media-image-button",onClick:c},[C("img",{class:"media-image",src:s.value.url,alt:s.value.path?i(s.value.path):l.value,loading:"lazy"},null,8,sbe)])]),_:1},8,["text"])):s.value.kind==="video"?(y(),he(p(pn),{key:1,text:s.value.path||l.value},{default:me(()=>[C("button",{type:"button",class:"media-image-button media-video-button","aria-label":s.value.path?i(s.value.path):l.value,onClick:c},[u.value?(y(),M("span",rbe)):(y(),he(i0,{key:1,url:s.value.url,kind:"video","file-id":a.value?void 0:s.value.fileId,"media-class":"media-video",controls:!1,muted:""},null,8,["url","file-id"])),C("span",lbe,[j(p(Te),{name:"play",size:"sm"})])],8,ibe)]),_:1},8,["text"])):(y(),M("audio",{key:2,class:"media-audio",src:s.value.url,controls:""},null,8,abe))],2)):ee("",!0)}}),cbe=ft(ube,[["__scopeId","data-v-3bc3ee1a"]]),dbe=["innerHTML"],fbe={class:"tl-name"},pbe={key:0,class:"tl-faint"},hbe={key:0,class:"tl-chip"},mbe=["title"],gbe={key:1,class:"plan-content"},vbe={key:2,class:"plan-review"},ybe={key:0},kbe={class:"review-label"},bbe={key:1},Cbe={class:"review-label"},wbe={class:"review-feedback"},_be=et({__name:"PlanTool",props:{tool:{},mobile:{type:Boolean}},emits:["openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=Z(n.tool.defaultExpanded===!0),r=R(()=>n.tool.plan),l=R(()=>r.value?.path??n.tool.planPath),a=R(()=>r.value!==void 0||l.value!==void 0||(n.tool.output?.length??0)>0),u=R(()=>{const d=r.value?.review?.state;return d?s(`tools.plan.review.${d}`):void 0});function c(){l.value&&o("openFile",{path:l.value,content:r.value?.plan})}return(d,f)=>(y(),he(el,{status:e.tool.status,open:i.value,expandable:a.value,onToggle:f[0]||(f[0]=h=>i.value=!i.value)},{leading:me(()=>[C("span",{class:"plan-glyph",innerHTML:p(zN)(e.tool.name)},null,8,dbe)]),trailing:me(()=>[e.tool.timing?(y(),M("span",hbe,N(e.tool.timing),1)):ee("",!0)]),body:me(()=>[l.value?(y(),M("button",{key:0,type:"button",class:"plan-path",title:l.value,onClick:c},N(l.value),9,mbe)):ee("",!0),r.value?(y(),M("div",gbe,[j(p(Ic),{text:r.value.plan,"open-file":h=>o("openFile",h)},null,8,["text","open-file"])])):ee("",!0),r.value?.review?.selectedOption||r.value?.review?.feedback?(y(),M("div",vbe,[r.value.review.selectedOption?(y(),M("div",ybe,[C("span",kbe,N(p(s)("tools.plan.selectedOption")),1),C("span",null,N(r.value.review.selectedOption),1)])):ee("",!0),r.value.review.feedback?(y(),M("div",bbe,[C("span",Cbe,N(p(s)("tools.plan.feedback")),1),C("span",wbe,N(r.value.review.feedback),1)])):ee("",!0)])):ee("",!0),r.value?ee("",!0):(y(),he(dr,{key:3,lines:e.tool.output,"empty-text":p(s)("tools.output.empty")},null,8,["lines","empty-text"]))]),default:me(()=>[C("span",fbe,N(p(_1)(e.tool.name)),1),u.value?(y(),M("span",pbe,N(u.value),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),xbe=ft(_be,[["__scopeId","data-v-8dff80a1"]]),Sbe={class:"tl-name"},Abe={key:1,class:"tl-faint"},Mbe={key:2,class:"tl-faint"},Tbe={key:3,class:"tl-dim"},Ebe={key:0,class:"tl-chip"},Ibe=et({__name:"ReadTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.tool.status),r=R(()=>gu(n.tool.arg)),l=R(()=>WN(r.value)??""),a=R(()=>l.value?v1(l.value):""),u=R(()=>l.value?UN(l.value):""),c=R(()=>{const S=r.value;if(S)return Ia(S.offset)??Ia(S.line_start)??Ia(S.start_line)}),d=R(()=>{const S=r.value;if(!S)return;const T=Ia(S.limit)??Ia(S.length);return Ia(S.line_end)??Ia(S.end_line)??(c.value!==void 0&&T!==void 0?c.value+T:void 0)}),f=R(()=>c.value!==void 0&&d.value!==void 0?`:${c.value}-${d.value}`:c.value!==void 0?`:${c.value}`:""),h=R(()=>n.tool.status==="ok"?UJ(n.tool.output??[]):null),m=R(()=>h.value?.contents??[]),v=R(()=>h.value?.lineNumbers),k=R(()=>h.value?.contents.length??n.tool.output?.length??0),w=R(()=>!!n.tool.output&&n.tool.output.length>0),b=R(()=>h.value!==null||w.value),_=Z(n.tool.defaultExpanded===!0&&b.value),g=Z(_.value);Je(_,S=>{S&&(g.value=!0)}),Je(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&b.value&&(_.value=!0)});function x(){l.value&&o("openFile",{path:l.value,line:c.value})}return(S,T)=>(y(),he(el,{status:i.value,open:_.value,expandable:b.value,onToggle:T[0]||(T[0]=A=>_.value=!_.value)},{leading:me(()=>[j(p(Te),{name:"file-text",size:"sm"})]),trailing:me(()=>[k.value>0?(y(),M("span",Ebe,N(p(s)("tools.chip.lines",{count:k.value})),1)):ee("",!0)]),body:me(()=>[l.value?(y(),M("button",{key:0,class:"path-link",type:"button",onClick:x},N(l.value),1)):ee("",!0),h.value&&g.value?(y(),he(Ur,{key:1,code:m.value,path:l.value,"line-numbers":v.value},null,8,["code","path","line-numbers"])):(y(),he(dr,{key:2,lines:e.tool.output,"empty-text":p(s)("tools.output.waiting")},null,8,["lines","empty-text"]))]),default:me(()=>[C("span",Sbe,N(p(s)("tools.label.read")),1),a.value?(y(),M("button",{key:0,class:"tl-file",type:"button",onClick:It(x,["stop"])},N(a.value),1)):ee("",!0),u.value?(y(),M("span",Abe,N(u.value),1)):ee("",!0),f.value?(y(),M("span",Mbe,N(f.value),1)):ee("",!0),a.value?ee("",!0):(y(),M("span",Tbe,N(l.value||e.tool.arg),1))]),_:1},8,["status","open","expandable"]))}}),Lbe=ft(Ibe,[["__scopeId","data-v-0edbdd82"]]),$be=["aria-expanded"],Nbe={class:"title"},Fbe={key:0,class:"meta"},Rbe={key:1,class:"sum-txt"},Obe={class:"rt"},Pbe={class:"status"},Dbe={key:0,class:"chip"},Bbe={key:1,class:"tm"},Hbe={class:"body"},zbe={class:"overview"},Wbe={class:"overview-line"},Ube={class:"big"},jbe={key:0,class:"lbl"},Vbe={key:1,class:"lbl"},qbe={key:2,class:"lbl"},Kbe={key:3,class:"lbl"},Zbe={key:0,class:"seg","aria-hidden":"true"},Gbe={key:1,class:"legend"},Ybe=["disabled","aria-label","aria-expanded","onClick"],Xbe={class:"mname"},Jbe={class:"mact"},Qbe={class:"mphase"},eCe=["aria-expanded","onClick"],tCe={key:1,class:"fallback-output"},nCe={key:2,class:"waiting"},oCe=et({__name:"SwarmTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t;function i(F){if(!F)return{};try{const U=JSON.parse(F),z=Array.isArray(U.items)?U.items:void 0;return{description:typeof U.description=="string"?U.description:void 0,itemCount:z?.length}}catch{return{}}}const r=nn("resolveSwarmMembers"),l=R(()=>i(o.tool.arg)),a=R(()=>_1(o.tool.name)),u=R(()=>l.value.description??""),c=R(()=>r?.(o.tool.id)??[]),d=R(()=>EJ(o.tool.output)),f=nn("modelDisplay"),h=nn("subagentEffort"),m=R(()=>{let F;for(const U of c.value){const z=f?.(U.model),W=h?.(U.thinkingEffort),K=[z,W].filter(ie=>ie!==void 0);if(K.length===0)continue;const V=K.join(" · ");if(F===void 0)F=V;else if(F!==V)return}return F}),v=R(()=>o.tool.status),k=R(()=>v.value==="running"?"running":v.value==="error"||(d.value?.failed??0)>0||(d.value?.aborted??0)>0?"error":"ok"),w=R(()=>MX(c.value,d.value)),b=R(()=>{const F={completed:0,working:0,suspended:0,queued:0,failed:0};for(const U of w.value)F[U.phase]++;return F}),_=R(()=>w.value.length||l.value.itemCount||0),g=R(()=>b.value.completed+b.value.failed),x=R(()=>b.value.working+b.value.suspended+b.value.queued),S=[{phase:"completed",cls:"s-ok"},{phase:"working",cls:"s-run"},{phase:"suspended",cls:"s-warn"},{phase:"failed",cls:"s-fail"},{phase:"queued",cls:"s-queue"}],T=R(()=>S.map(({phase:F,cls:U})=>({phase:F,count:b.value[F],cls:U})).filter(F=>F.count>0)),A=Z(v.value==="running"||x.value>0);function E(){A.value=!A.value}const P=R(()=>w.value.length>0||d.value||v.value==="running"?"":(o.tool.output??[]).join(` +`).trim()),D=Z(new Set);function I(F){return D.value.has(F)}function $(F){const U=new Set(D.value);U.has(F)?U.delete(F):U.add(F),D.value=U}function B(F){if(F.agentId){s("openAgent",F.agentId);return}F.body&&$(F.id)}function H(F){return F.agentId!==void 0&&F.body.length>0&&(F.phase==="completed"||F.phase==="failed")}function O(F){return n(`tools.swarm.phase${F[0].toUpperCase()}${F.slice(1)}`)}return(F,U)=>(y(),M("div",{class:Re(["swarm-card",{open:A.value,err:k.value==="error"}])},[C("button",{class:"head",type:"button","aria-expanded":A.value,onClick:E},[j(p(Te),{class:"ic",name:"sparkles",size:"sm"}),C("span",Nbe,N(a.value),1),u.value?(y(),M("span",Fbe,"·")):ee("",!0),u.value?(y(),M("span",Rbe,N(u.value),1)):ee("",!0),C("span",Obe,[C("span",Pbe,[k.value==="ok"?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):k.value==="error"?(y(),he(p(Te),{key:1,name:"close",size:"sm"})):(y(),he(p(hc),{key:2,status:"running"}))]),g.value>0||_.value>0?(y(),M("span",Dbe,N(g.value)+" / "+N(_.value),1)):ee("",!0),e.tool.timing?(y(),M("span",Bbe,N(e.tool.timing),1)):ee("",!0)]),j(p(Te),{class:"car",name:"chevron-right",size:"sm"})],8,$be),Bn(C("div",Hbe,[C("div",zbe,[C("div",Wbe,[C("span",Ube,N(p(n)("tools.swarm.progress",{done:g.value,total:_.value})),1),m.value?(y(),M("span",jbe,N(m.value),1)):ee("",!0),k.value==="running"&&_.value>0?(y(),M("span",Vbe,N(p(n)("tools.swarm.runningSub",{count:x.value})),1)):d.value?(y(),M("span",qbe,N(p(n)("tools.swarm.doneSub",{completed:d.value.completed,failed:d.value.failed+d.value.aborted})),1)):(y(),M("span",Kbe,N(p(n)("tools.swarm.waiting")),1))]),_.value>0&&T.value.length>0?(y(),M("div",Zbe,[(y(!0),M(Pe,null,pt(T.value,z=>(y(),M("span",{key:z.phase,class:Re(z.cls),style:Zt({flex:z.count})},null,6))),128))])):ee("",!0),T.value.length>1?(y(),M("div",Gbe,[(y(!0),M(Pe,null,pt(T.value,z=>(y(),M("span",{key:z.phase},[C("i",{class:Re(["lg-dot",z.cls])},null,2),qe(N(O(z.phase))+" "+N(z.count),1)]))),128))])):ee("",!0)]),w.value.length>0?(y(!0),M(Pe,{key:0},pt(w.value,z=>(y(),M("div",{key:z.id,class:Re(["member",[`phase-${z.phase}`,{open:!z.agentId&&I(z.id)}]])},[C("button",{class:"member-head",type:"button",disabled:!z.agentId&&!z.body,"aria-label":z.agentId?p(n)("tasks.openDetail"):void 0,"aria-expanded":!z.agentId&&z.body?I(z.id):void 0,onClick:W=>B(z)},[j(p(hc),{class:"row-dot",status:z.phase},null,8,["status"]),j(p(pn),{text:z.name},{default:me(()=>[C("span",Xbe,N(z.name),1)]),_:2},1032,["text"]),z.activity?(y(),he(p(pn),{key:0,text:z.activity},{default:me(()=>[C("span",Jbe,N(z.activity),1)]),_:2},1032,["text"])):ee("",!0),C("span",Qbe,N(O(z.phase)),1),z.agentId?(y(),he(p(Te),{key:1,class:"mcar",name:"arrow-right",size:"sm"})):z.body?(y(),he(p(Te),{key:2,class:"mcar",name:"chevron-right",size:"sm"})):ee("",!0)],8,Ybe),H(z)?(y(),M("button",{key:0,class:"member-saved",type:"button","aria-expanded":I(z.id),onClick:W=>$(z.id)},[j(p(Te),{class:Re(["member-saved-car",{open:I(z.id)}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"]),C("span",null,N(p(n)("tools.output.saved")),1)],8,eCe)):ee("",!0),z.body&&(!z.agentId||H(z))?Bn((y(),M("div",{key:1,class:"member-body"},N(z.body),513)),[[qs,I(z.id)]]):ee("",!0)],2))),128)):P.value?(y(),M("div",tCe,N(P.value),1)):(y(),M("div",nCe,N(p(n)("tools.swarm.waiting")),1))],512),[[qs,A.value]])],2))}}),sCe=ft(oCe,[["__scopeId","data-v-f360563e"]]),iCe=et({__name:"StatusGlyph",props:{status:{}},setup(e){const t=e;return(n,o)=>(y(),M("span",{class:Re(["status-glyph",`s-${t.status}`]),"aria-hidden":"true"},[t.status==="run"?(y(),he(p(hc),{key:0,status:"running"})):t.status==="pending"?(y(),he(p(hc),{key:1,status:"idle"})):t.status==="done"?(y(),he(p(Te),{key:2,name:"check",size:"sm"})):(y(),he(p(Te),{key:3,name:"close",size:"sm"}))],2))}}),Y5=ft(iCe,[["__scopeId","data-v-f1aedfd0"]]),rCe={class:"tl-name"},lCe={key:0,class:"tl-dim"},aCe={key:0,class:"tl-chip"},uCe={key:1,class:"todo-bar","aria-hidden":"true"},cCe={key:0,class:"todo-list"},dCe={class:"todo-title"},fCe=et({__name:"TodoTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=Nt();function o(m){const v=gu(m),k=v&&Array.isArray(v.todos)?v.todos:v&&Array.isArray(v.items)?v.items:void 0;if(!k)return[];const w=[];for(const b of k){if(!b||typeof b!="object")continue;const _=b,g=jn(_.title)??jn(_.content)??jn(_.activeForm)??jn(_.text);if(!g)continue;const x=jn(_.status)??"pending";w.push({title:g,status:x==="in_progress"?"in_progress":x==="done"||x==="completed"?"done":"pending"})}return w}const s=R(()=>t.tool.status),i=R(()=>o(t.tool.arg)),r=R(()=>i.value.filter(m=>m.status==="done").length),l=R(()=>i.value.length),a=R(()=>i.value.find(m=>m.status==="in_progress")),u=R(()=>l.value>0?r.value/l.value:0),c=R(()=>!!t.tool.output&&t.tool.output.length>0),d=R(()=>l.value>0||c.value),f=Z(t.tool.defaultExpanded===!0&&d.value);Je(()=>[t.tool.defaultExpanded,t.tool.status],()=>{t.tool.defaultExpanded===!0&&d.value&&(f.value=!0)});function h(m){return m.status==="in_progress"?"run":m.status}return(m,v)=>(y(),he(el,{status:s.value,open:f.value,expandable:d.value,onToggle:v[0]||(v[0]=k=>f.value=!f.value)},{leading:me(()=>[j(p(Te),{name:"check-list",size:"sm"})]),trailing:me(()=>[l.value>0?(y(),M("span",aCe,N(r.value)+"/"+N(l.value),1)):ee("",!0),l.value>0?(y(),M("span",uCe,[C("span",{class:"todo-fill",style:Zt({width:`${u.value*100}%`})},null,4)])):ee("",!0)]),body:me(()=>[l.value>0?(y(),M("div",cCe,[(y(!0),M(Pe,null,pt(i.value,(k,w)=>(y(),M("div",{key:w,class:Re(["todo-row",`s-${k.status}`])},[j(Y5,{status:h(k)},null,8,["status"]),C("span",dCe,N(k.title),1)],2))),128))])):c.value?(y(),he(dr,{key:1,lines:e.tool.output},null,8,["lines"])):ee("",!0)]),default:me(()=>[C("span",rCe,N(p(n)("tools.label.todo")),1),a.value?(y(),M("span",lCe,N(a.value.title),1)):ee("",!0)]),_:1},8,["status","open","expandable"]))}}),pCe=ft(fCe,[["__scopeId","data-v-1b7f51f3"]]),hCe={class:"tl-name"},mCe={key:0},gCe={key:1,class:"tl-dim"},vCe={key:0,class:"fetch-url"},yCe=et({__name:"WebFetchTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.tool.status),s=R(()=>{const u=gu(t.tool.arg);return jn(u?.url)??jn(u?.uri)??""}),i=R(()=>s.value?V7e(s.value):""),r=R(()=>!!t.tool.output&&t.tool.output.length>0),l=R(()=>r.value),a=Z(t.tool.defaultExpanded===!0&&l.value);return Je(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&l.value&&(a.value=!0)}),(u,c)=>(y(),he(el,{status:o.value,open:a.value,expandable:l.value,onToggle:c[0]||(c[0]=d=>a.value=!a.value)},{leading:me(()=>[j(p(Te),{name:"globe",size:"sm"})]),body:me(()=>[s.value?(y(),M("div",vCe,N(s.value),1)):ee("",!0),j(dr,{lines:e.tool.output,"empty-text":p(n)("tools.output.waiting")},null,8,["lines","empty-text"])]),default:me(()=>[C("span",hCe,N(p(n)("tools.label.web_fetch")),1),i.value?(y(),M("span",mCe,N(i.value),1)):(y(),M("span",gCe,N(e.tool.arg),1))]),_:1},8,["status","open","expandable"]))}}),kCe=ft(yCe,[["__scopeId","data-v-8c248fcc"]]);function bCe(e){if(e.media&&e.status==="ok")return cbe;switch(Gs(e.name)){case"bash":return X7e;case"read":return Lbe;case"edit":case"write":case"multi_edit":return gke;case"grep":case"search":return Qke;case"glob":case"ls":return Fke;case"web_fetch":return kCe;case"todo":return pCe;case"task":return h7e;case"agentswarm":return sCe;case"askuserquestion":return j7e;case"exitplanmode":return xbe;case"creategoal":case"getgoal":case"setgoalbudget":case"updategoal":return Wke;default:return xke}}const X5=et({__name:"ToolCall",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,o=t,s=R(()=>bCe(n.tool));return(i,r)=>(y(),he(bs(s.value),{tool:e.tool,mobile:e.mobile,onOpenMedia:r[0]||(r[0]=l=>o("openMedia",l)),onOpenFile:r[1]||(r[1]=l=>o("openFile",l)),onOpenAgent:r[2]||(r[2]=l=>o("openAgent",l))},null,40,["tool","mobile"]))}});function ta(e){if(e.blocks)return e.blocks;const t=[];e.thinking&&t.push({kind:"thinking",thinking:e.thinking}),e.text&&t.push({kind:"text",text:e.text});for(const n of e.tools??[])t.push({kind:"tool",tool:n});return t}function jN(e){return!(e.tool.status==="ok"&&e.tool.media)}function CCe(e){const t=ta(e),n=[];let o=[],s=null;const i=()=>{const[l]=o;o.length===1&&l?n.push(l):o.length>1&&n.push({kind:"activity-run",items:o}),o=[]},r=()=>{s&&n.push({kind:"notification",items:s.items,sourceIndex:s.sourceIndex}),s=null};return t.forEach((l,a)=>{if(l.kind==="notification"){i(),s?s.items.push(l.notification):s={items:[l.notification],sourceIndex:a};return}if(r(),l.kind==="thinking"){o.push({kind:"thinking",thinking:l.thinking,startedAt:l.startedAt,durationMs:l.durationMs,sourceIndex:a});return}if(l.kind==="tool"&&jN(l)){o.push({kind:"tool",tool:l.tool,sourceIndex:a});return}i(),l.kind==="text"?n.push({kind:"text",text:l.text,sourceIndex:a}):l.kind==="tool"&&n.push({kind:"tool",tool:l.tool,sourceIndex:a})}),i(),r(),n}const Jx=new WeakMap;function VN(e){const t=Jx.get(e);if(t!==void 0)return t;const n=wCe(e);return Jx.set(e,n),n}function wCe(e){const t=CCe(e);let n=-1;for(let r=t.length-1;r>=0;r--){const l=t[r];if(l?.kind==="text"&&l.text.trim().length>0){n=r;break}}if(n===-1){for(let r=0;r<t.length;r++){const l=t[r];if(l?.kind==="tool"&&!jN(l)){n=r;break}if(l?.kind==="notification"){n=r;break}}if(n===-1)return{folded:t,visible:[]}}const o=t.slice(0,n),s=t.slice(n),i=o.filter(r=>r.kind==="notification");return i.length>0?{folded:o.filter(r=>r.kind!=="notification"),visible:[...i,...s]}:{folded:o,visible:s}}function _Ce(e){let t;for(const n of e){if(n.kind!=="thinking"||n.startedAt===void 0)continue;const o=Date.parse(n.startedAt);Number.isNaN(o)||(t===void 0||o<t)&&(t=o)}return t}function Qx(e){if(e===void 0)return;const t=Date.parse(e);return Number.isNaN(t)?void 0:t}function xCe(e){if(e.state.phase==="settled")return e.durationMs!==void 0?Math.max(0,e.durationMs):e.startMs===void 0||e.endedMs===void 0?void 0:Math.max(0,e.endedMs-e.startMs);if(e.startMs!==void 0)return Math.max(0,e.state.nowMs-e.startMs)}function SCe(e){return VN(e).visible.flatMap(t=>t.kind==="text"&&t.text?[t.text]:[]).join(` + +`)}function ACe(e){const t=[];for(const n of ta(e))if(n.kind==="thinking"&&n.thinking)t.push(`> **Thinking** +> ${n.thinking.split(` +`).join(` +> `)}`);else if(n.kind==="text"&&n.text)t.push(n.text);else if(n.kind==="tool"&&n.tool.output&&n.tool.output.length>0){const o=n.tool.output.join(` +`);t.push(`\`\`\` +[${n.tool.name}] +${o} +\`\`\``)}else if(n.kind==="notification"){const o=n.notification,s=[o.title,o.type,...o.body.split(` +`)].filter(i=>i!=="");s.length>0&&t.push(`> **Notification** +> ${s.join(` +> `)}`)}return t.join(` + +`)}function qN(e){return e.tool.id||`tool-${e.sourceIndex}`}function KN(e,t){return e.kind==="activity-run"?`activity-run-${e.items[0]?.sourceIndex??t}`:e.kind==="tool"?qN({tool:e.tool,sourceIndex:e.sourceIndex}):`${e.kind}-${e.sourceIndex}`}function MCe(e){const t=new Map;for(const n of ta(e)){if(n.kind!=="tool"||n.tool.status==="error")continue;const o=n.tool,s=Gs(o.name);if(s!=="edit"&&s!=="multi_edit"&&s!=="write")continue;let i,r=0,l=0,a=!1,u=!1,c=null;if(s==="write")i=Db(o),a=!0,u=!0;else if(c=qT(o),i=Db(o),c){const h=HT(c);r=h.added,l=h.removed}else u=!0;if(!i)continue;const d=TCe(i),f=t.get(d);if(f)if(f.added+=r,f.removed+=l,f.hasWrite||=a,f.statsIncomplete||=u,f.diff!==null&&c!==null){let h=0,m=0;for(const k of f.diff)k.oldNo!==void 0&&k.oldNo>h&&(h=k.oldNo),k.newNo!==void 0&&k.newNo>m&&(m=k.newNo);const v=c.map(k=>({...k,oldNo:k.oldNo!==void 0?k.oldNo+h:void 0,newNo:k.newNo!==void 0?k.newNo+m:void 0}));f.diff=[...f.diff,{type:"hunk",text:"···"},...v]}else f.diff=null;else t.set(d,{path:i,added:r,removed:l,hasWrite:a,statsIncomplete:u,diff:c})}return[...t.values()]}function TCe(e){const t=e.replace(/\\/g,"/");let n="",o=t,s=!1;const i=/^\/\/([^/]+\/[^/]+)(\/|$)/.exec(t);i?(n=`//${i[1].toLowerCase()}/`,o=t.slice(i[0].length-(i[0].endsWith("/")?1:0)),s=!0):/^[a-zA-Z]:\//.test(t)?(n=`${t[0].toLowerCase()}:/`,o=t.slice(3),s=!0):t.startsWith("/")&&(n="/",o=t.slice(1));const r=n!=="",l=[];for(const c of o.split("/"))if(!(!c||c===".")){if(c===".."){l.length>0&&l[l.length-1]!==".."?l.pop():r||l.push(c);continue}l.push(c)}const a=l.join("/"),u=n+a;return s?u.toLowerCase():u}const ECe=2e3,cf=new Map;function ICe(e){const t=[];for(const n of ta(e)){if(n.kind!=="tool")continue;const o=n.tool,s=Gs(o.name);s!=="edit"&&s!=="multi_edit"&&s!=="write"||t.push(`${o.id}:${o.status}:${o.arg.length}`)}return t.join("|")}function LCe(e){const t=ICe(e),n=cf.get(e.id);if(n&&n.key===t)return n.changes;const o=MCe(e);if(cf.set(e.id,{key:t,changes:o}),cf.size>ECe){const s=cf.keys().next().value;s!==void 0&&cf.delete(s)}return o}const $Ce=["aria-expanded"],NCe={class:"think-title"},FCe={key:0,class:"think-time"},RCe=["inert"],OCe={class:"think-text"},PCe=et({__name:"ThinkingBlock",props:{text:{},mobile:{type:Boolean,default:!1},streaming:{type:Boolean,default:!1},startedAt:{default:void 0},durationMs:{default:void 0}},setup(e){const t=e,n=Z(!1),{t:o}=Nt();Je(()=>t.streaming,(d,f)=>{f&&!d&&(n.value=!1)});const s=Z(Date.now());Je(()=>[t.streaming,t.startedAt],([d,f],h,m)=>{if(!d||!f)return;s.value=Date.now();const v=setInterval(()=>{s.value=Date.now()},1e3);m(()=>clearInterval(v))},{immediate:!0});const i=R(()=>{if(t.streaming&&t.startedAt){const d=Date.parse(t.startedAt);return Number.isFinite(d)?vc(s.value-d):""}if(t.durationMs!==void 0){const d=vc(t.durationMs);return d?`· ${d}`:""}return""}),r=nn("pinScroll",()=>{}),l=Z(null),a=Z(null),u=Z(!1);function c(){if(!n.value){const f=(a.value?.scrollHeight??0)>(typeof window<"u"?window.innerHeight:0);u.value=t.streaming&&f}if(n.value=!n.value,t.streaming)return;const d=l.value;d&&yt(()=>r(d))}return(d,f)=>(y(),M("div",{class:Re(["think",{mob:e.mobile,open:n.value,streaming:e.streaming}])},[C("button",{ref_key:"headEl",ref:l,class:"think-head",type:"button","aria-expanded":n.value,onClick:c},[j(p(Te),{class:"think-bulb",name:"thinking",size:"sm"}),C("span",NCe,N(e.streaming?p(o)("thinking.streaming"):p(o)("thinking.panelTitle")),1),i.value?(y(),M("span",FCe,N(i.value),1)):ee("",!0),j(p(Te),{class:"think-car",name:"chevron-right",size:"sm"})],8,$Ce),C("div",{class:Re(["think-body",{open:n.value,instant:u.value}]),inert:!n.value},[C("div",{ref_key:"bodyInnerEl",ref:a,class:"think-body-inner"},[C("pre",OCe,N(e.text),1)],512)],10,RCe)],2))}}),J5=ft(PCe,[["__scopeId","data-v-7d463c2a"]]),ZN=(e,t)=>t===void 0?Hn.global.t(e):Hn.global.t(e,t);function DCe(e,t={}){return ZX(ZN,e,t)}function BCe(e,t){return YX(ZN,e,t)}const HCe=["aria-expanded"],zCe=["aria-label"],WCe=["title"],UCe={key:0,class:"ar-sep"},jCe=["inert"],VCe={class:"ar-body-inner"},qCe=et({__name:"ActivityRun",props:{items:{},mobile:{type:Boolean,default:!1},streaming:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,o=t,s=R(()=>n.items.at(-1)),i=R(()=>{const A=s.value;if(n.streaming&&A?.kind==="thinking")return A;for(let E=n.items.length-1;E>=0;E--){const P=n.items[E];if(P?.kind==="tool"&&P.tool.status==="running")return P}return null}),r=R(()=>{if(n.streaming)return"running";for(const A of n.items)if(A.kind==="tool"&&A.tool.status==="running")return"running";for(const A of n.items)if(A.kind==="tool"&&A.tool.status==="error")return"error";return"done"}),l=Z(r.value==="running"),a=nn("pinScroll",()=>{}),u=Z(null),c=Z(null),d=Z(void 0),f=Z(Date.now()),h=R(()=>{let A=null;for(const E of n.items)if(E.kind==="thinking"&&E.startedAt!==void 0){const P=Date.parse(E.startedAt);Number.isFinite(P)&&(A===null||P<A)&&(A=P)}return A});Je(r,(A,E,P)=>{if(A==="running"){E!==void 0&&E!=="running"&&(l.value=!0),c.value===null&&(c.value=h.value??Date.now()),d.value=void 0,f.value=Date.now();const D=setInterval(()=>{f.value=Date.now()},1e3);P(()=>clearInterval(D));return}E==="running"&&(l.value=!1,c.value!==null&&(d.value=Date.now()-c.value),c.value=null)},{immediate:!0});function m(){if(l.value=!l.value,n.streaming)return;const A=u.value;A&&yt(()=>a(A))}const v=R(()=>{if(r.value==="done")return"check";if(r.value==="error")return"close";const A=i.value??s.value;return A?A.kind==="thinking"?"thinking":HN(A.tool.name):"tool"}),k=R(()=>BCe(n.items,i.value)),w=R(()=>DCe(n.items,{durationMs:d.value})),b=R(()=>r.value!=="running"||c.value===null?"":vc(f.value-c.value)),_=R(()=>{if(r.value!=="running")return w.value.clauses;const A=[];return k.value.current&&A.push(k.value.current),A.push(...k.value.done),b.value&&A.push({fragments:[{text:b.value,tone:"faint"}]}),A}),g=R(()=>r.value!=="running"?w.value.plain:[k.value.plain,b.value].filter(Boolean).join(" · "));function x(A){if(A==="danger")return"ar-danger";if(A==="faint")return"ar-faint"}function S(A){return A.kind==="tool"?qN(A):`thinking-${A.sourceIndex}`}function T(A){return n.streaming&&A.kind==="thinking"&&A.durationMs===void 0&&A.sourceIndex===s.value?.sourceIndex}return(A,E)=>(y(),M("div",{class:Re(["activity-run",{open:l.value}])},[C("button",{ref_key:"headEl",ref:u,class:"ar-head",type:"button","aria-expanded":l.value,onClick:m},[C("span",{class:Re(["ar-glyph",{run:r.value==="running",err:r.value==="error",ok:r.value==="done"}]),role:"status","aria-label":r.value},[j(p(Te),{name:v.value,size:"sm","aria-hidden":"true"},null,8,["name"])],10,zCe),C("span",{class:"ar-sum",title:g.value},[(y(!0),M(Pe,null,pt(_.value,(P,D)=>(y(),M(Pe,{key:D},[D>0?(y(),M("span",UCe," · ")):ee("",!0),(y(!0),M(Pe,null,pt(P.fragments,(I,$)=>(y(),M("span",{key:$,class:Re(x(I.tone))},N(I.text),3))),128))],64))),128))],8,WCe),j(p(Te),{class:"ar-car",name:"chevron-right",size:"sm","aria-hidden":"true"})],8,HCe),C("div",{class:Re(["ar-body",{open:l.value}]),inert:!l.value},[C("div",VCe,[(y(!0),M(Pe,null,pt(e.items,P=>(y(),M(Pe,{key:S(P)},[P.kind==="thinking"?(y(),he(J5,{key:0,text:P.thinking,mobile:e.mobile,streaming:T(P),"started-at":P.startedAt,"duration-ms":P.durationMs},null,8,["text","mobile","streaming","started-at","duration-ms"])):(y(),he(X5,{key:1,tool:P.tool,mobile:e.mobile,onOpenMedia:E[0]||(E[0]=D=>o("openMedia",D)),onOpenFile:E[1]||(E[1]=D=>o("openFile",D)),onOpenAgent:E[2]||(E[2]=D=>o("openAgent",D))},null,8,["tool","mobile"]))],64))),128))])],10,jCe)],2))}}),GN=ft(qCe,[["__scopeId","data-v-91eb361a"]]),KCe={class:"msg-time"},ZCe=et({__name:"MessageTime",props:{time:{}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>uJ(t.time,n("conversation.yesterday")));return(s,i)=>(y(),M("span",KCe,N(o.value),1))}}),Rg=ft(ZCe,[["__scopeId","data-v-9153170e"]]),GCe=["aria-expanded"],YCe={class:"ntf-chip"},XCe={class:"ntf-main"},JCe={class:"ntf-title"},QCe={class:"ntf-sub"},ewe={class:"ntf-side"},twe={class:"ng-dots"},nwe={class:"ng-list"},owe=["aria-expanded","onClick"],swe={class:"ntf-chip"},iwe={class:"ntf-main"},rwe={class:"ntf-title"},lwe={class:"ntf-sub"},awe={class:"ntf-side"},uwe={class:"st"},cwe={class:"ntf-body"},dwe={class:"ntf-body-in"},fwe={class:"nd-fields"},pwe={class:"k"},hwe={class:"v"},mwe={class:"k"},gwe={class:"v"},vwe={class:"k"},ywe={class:"v"},kwe={key:0,class:"nd-body"},bwe={key:1,class:"nd-out"},Cwe=["title"],wwe=["onClick"],_we={class:"nd-raw"},xwe=["aria-expanded"],Swe={class:"ntf-chip"},Awe={class:"ntf-main"},Mwe={class:"ntf-title"},Twe={class:"ntf-sub"},Ewe={class:"ntf-side"},Iwe={class:"st"},Lwe={class:"ntf-body"},$we={class:"ntf-body-in"},Nwe={class:"nd-fields"},Fwe={class:"k"},Rwe={class:"v"},Owe={class:"k"},Pwe={class:"v"},Dwe={class:"k"},Bwe={class:"v"},Hwe={key:0,class:"nd-body"},zwe={key:1,class:"nd-out"},Wwe=["title"],Uwe={class:"nd-raw"},jwe=et({__name:"NotificationCard",props:{items:{}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.items.length>1),s=Z(!1),i=Z(new Set);function r(_,g){return _.id!==""?`${_.id}#${g}`:`ntf-${g}`}function l(_){const g=new Set(i.value);g.has(_)?g.delete(_):g.add(_),i.value=g}const a={completed:"check",failed:"alert-triangle",timed_out:"clock",killed:"stop",lost:"alert-triangle",info:"info"};function u(_){const g=zh(_);return g==="info"&&_.sourceKind==="subagent"?"robot":a[g]}function c(_){return _.sourceKind==="subagent"?n("conversation.notification.kindSubagent"):n("conversation.notification.kindTask")}function d(_){return n(`conversation.notification.title.${zh(_)}`,{kind:c(_)})}function f(_){return n(`conversation.notification.status.${zh(_)}`)}function h(_){return _Y(_)}function m(_){return _==="ok"?"done":_==="err"?"error":_==="warn"?"warn":""}const v=R(()=>t.items.map(_=>_.title).filter(_=>_!=="").join(" · ")),k=Z(null);let w=null;async function b(_,g){await Zs(_)&&(k.value=g,w!==null&&clearTimeout(w),w=setTimeout(()=>{w=null,k.value=null},1200))}return(_,g)=>o.value?(y(),M("div",{key:0,class:Re(["ntf-group-card",{open:s.value}])},[C("button",{class:"ntf-head",type:"button","aria-expanded":s.value,onClick:g[0]||(g[0]=x=>s.value=!s.value)},[C("span",YCe,[j(p(Te),{name:"terminal",size:"sm"})]),C("span",XCe,[C("span",JCe,N(p(n)("conversation.notification.groupTitle",{n:e.items.length})),1),C("span",QCe,N(v.value),1)]),C("span",ewe,[C("span",twe,[(y(!0),M(Pe,null,pt(e.items,(x,S)=>(y(),M("span",{key:r(x,S),class:Re(["dot",m(h(x))])},null,2))),128))]),j(p(Te),{class:"ntf-car",name:"chevron-right",size:"sm"})])],8,GCe),Bn(C("div",nwe,[(y(!0),M(Pe,null,pt(e.items,(x,S)=>(y(),M("div",{key:r(x,S),class:Re(["ng-item",[h(x),{open:i.value.has(r(x,S))}]])},[C("button",{class:"ntf-head",type:"button","aria-expanded":i.value.has(r(x,S)),onClick:T=>l(r(x,S))},[C("span",swe,[j(p(Te),{name:u(x),size:"sm"},null,8,["name"])]),C("span",iwe,[C("span",rwe,N(d(x)),1),C("span",lwe,N(x.title),1)]),C("span",awe,[C("span",uwe,N(f(x)),1),x.createdAt?(y(),he(Rg,{key:0,time:x.createdAt},null,8,["time"])):ee("",!0),j(p(Te),{class:"ntf-car",name:"chevron-right",size:"sm"})])],8,owe),Bn(C("div",cwe,[C("div",dwe,[C("div",fwe,[C("span",pwe,N(p(n)("conversation.notification.fields.type")),1),C("span",hwe,N(x.type),1),C("span",mwe,N(p(n)("conversation.notification.fields.source")),1),C("span",gwe,N(x.sourceKind)+" · "+N(x.sourceId),1),C("span",vwe,N(p(n)("conversation.notification.fields.severity")),1),C("span",ywe,N(x.severity||"—"),1)]),x.body?(y(),M("div",kwe,N(x.body),1)):ee("",!0),x.outputFile?(y(),M("div",bwe,[j(p(Te),{class:"nd-out-ic",name:"file-text",size:"sm"}),C("span",{class:"path",title:x.outputFile.path},N(x.outputFile.path),9,Cwe),C("button",{class:"nd-act",type:"button",onClick:It(T=>b(x.outputFile.path,r(x,S)),["stop"])},N(k.value===r(x,S)?p(n)("conversation.notification.copied"):p(n)("conversation.notification.copyPath")),9,wwe)])):ee("",!0),C("details",_we,[C("summary",null,[j(p(Te),{class:"nd-raw-car",name:"chevron-right",size:"sm"}),C("span",null,N(p(n)("conversation.notification.rawPayload")),1)]),C("pre",null,N(x.raw),1)])])],512),[[qs,i.value.has(r(x,S))]])],2))),128))],512),[[qs,s.value]])],2)):e.items[0]?(y(),M("div",{key:1,class:Re(["ntf",[h(e.items[0]),{open:i.value.has(r(e.items[0],0))}]])},[C("button",{class:"ntf-head",type:"button","aria-expanded":i.value.has(r(e.items[0],0)),onClick:g[1]||(g[1]=x=>l(r(e.items[0],0)))},[C("span",Swe,[j(p(Te),{name:u(e.items[0]),size:"sm"},null,8,["name"])]),C("span",Awe,[C("span",Mwe,N(d(e.items[0])),1),C("span",Twe,N(e.items[0].title),1)]),C("span",Ewe,[C("span",Iwe,N(f(e.items[0])),1),e.items[0].createdAt?(y(),he(Rg,{key:0,time:e.items[0].createdAt},null,8,["time"])):ee("",!0),j(p(Te),{class:"ntf-car",name:"chevron-right",size:"sm"})])],8,xwe),Bn(C("div",Lwe,[C("div",$we,[C("div",Nwe,[C("span",Fwe,N(p(n)("conversation.notification.fields.type")),1),C("span",Rwe,N(e.items[0].type),1),C("span",Owe,N(p(n)("conversation.notification.fields.source")),1),C("span",Pwe,N(e.items[0].sourceKind)+" · "+N(e.items[0].sourceId),1),C("span",Dwe,N(p(n)("conversation.notification.fields.severity")),1),C("span",Bwe,N(e.items[0].severity||"—"),1)]),e.items[0].body?(y(),M("div",Hwe,N(e.items[0].body),1)):ee("",!0),e.items[0].outputFile?(y(),M("div",zwe,[j(p(Te),{class:"nd-out-ic",name:"file-text",size:"sm"}),C("span",{class:"path",title:e.items[0].outputFile.path},N(e.items[0].outputFile.path),9,Wwe),C("button",{class:"nd-act",type:"button",onClick:g[2]||(g[2]=It(x=>b(e.items[0].outputFile.path,r(e.items[0],0)),["stop"]))},N(k.value===r(e.items[0],0)?p(n)("conversation.notification.copied"):p(n)("conversation.notification.copyPath")),1)])):ee("",!0),C("details",Uwe,[C("summary",null,[j(p(Te),{class:"nd-raw-car",name:"chevron-right",size:"sm"}),C("span",null,N(p(n)("conversation.notification.rawPayload")),1)]),C("pre",null,N(e.items[0].raw),1)])])],512),[[qs,i.value.has(r(e.items[0],0))]])],2)):ee("",!0)}}),YN=ft(jwe,[["__scopeId","data-v-69e0a1db"]]),Vwe=["aria-expanded"],qwe=["title"],Kwe=["inert"],Zwe={class:"tf-body-inner"},Gwe={key:1,class:"msg"},Ywe=et({__name:"TurnFold",props:{items:{},mobile:{type:Boolean,default:!1},streamingTailIndex:{default:null},live:{type:Boolean,default:!1},parked:{type:Boolean,default:!1},seedMs:{default:void 0},createdMs:{default:void 0},endedMs:{default:void 0},durationMs:{default:void 0}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.streamingTailIndex!==null),r=R(()=>n.live?n.parked?"parked":"live":"settled"),l=Z(!1),a=R(()=>i.value||l.value),u=Z(a.value),c=Z(a.value);let d=null;Je(a,T=>{if(T){if(d!==null&&(clearTimeout(d),d=null),u.value){c.value=!0;return}u.value=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{c.value=!0})});return}c.value=!1,d=setTimeout(()=>{d=null,u.value=!1},200)});const f=nn("pinScroll",()=>{}),h=Z(null),m=Z(Date.now());let v=null;function k(){v!==null&&(clearInterval(v),v=null)}bn(()=>{k(),d!==null&&clearTimeout(d)}),Je(r,(T,A)=>{T!=="settled"?(m.value=Date.now(),v===null&&(v=setInterval(()=>{m.value=Date.now()},1e3))):k(),A==="live"&&T!=="live"&&(l.value=!1)},{immediate:!0});const w=R(()=>n.seedMs===void 0?n.createdMs:n.createdMs===void 0?n.seedMs:Math.min(n.seedMs,n.createdMs)),b=R(()=>xCe({startMs:w.value,endedMs:n.endedMs,durationMs:n.durationMs,state:r.value==="settled"?{phase:"settled"}:{phase:"live",nowMs:m.value}}));function _(){l.value=!l.value,yt(()=>{const T=h.value;T&&f(T)})}const g=R(()=>{const T=b.value===void 0?"":vc(b.value);return T?s("conversation.fold.worked",{duration:T}):s("conversation.fold.workedUnknown")});function x(T){return n.streamingTailIndex===null||T.kind==="thinking"&&T.durationMs!==void 0?!1:T.sourceIndex===n.streamingTailIndex}function S(T){if(n.streamingTailIndex===null)return!1;const A=T.items.at(-1);return A?.kind==="thinking"&&A.durationMs!==void 0?!1:A!==void 0&&A.sourceIndex===n.streamingTailIndex}return(T,A)=>e.items.length>0?(y(),M("div",{key:0,class:Re(["turn-fold",{open:a.value,streaming:i.value}])},[i.value?ee("",!0):(y(),M("button",{key:0,ref_key:"headEl",ref:h,class:"tf-head",type:"button","aria-expanded":l.value,onClick:_},[C("span",{class:"tf-sum",title:g.value},N(g.value),9,qwe),j(p(Te),{class:"tf-car",name:"chevron-right",size:"sm","aria-hidden":"true"})],8,Vwe)),u.value?(y(),M("div",{key:1,class:Re(["tf-body",{open:c.value}]),inert:!a.value},[C("div",Zwe,[(y(!0),M(Pe,null,pt(e.items,(E,P)=>(y(),M(Pe,{key:p(KN)(E,P)},[E.kind==="thinking"?(y(),he(J5,{key:0,text:E.thinking,mobile:e.mobile,streaming:x(E),"started-at":E.startedAt,"duration-ms":E.durationMs},null,8,["text","mobile","streaming","started-at","duration-ms"])):E.kind==="text"&&E.text?(y(),M("div",Gwe,[j(p(Ic),{text:E.text,streaming:x(E),"open-file":D=>o("openFile",D)},null,8,["text","streaming","open-file"])])):E.kind==="activity-run"?(y(),he(GN,{key:2,items:E.items,mobile:e.mobile,streaming:S(E),onOpenMedia:A[0]||(A[0]=D=>o("openMedia",D)),onOpenFile:A[1]||(A[1]=D=>o("openFile",D)),onOpenAgent:A[2]||(A[2]=D=>o("openAgent",D))},null,8,["items","mobile","streaming"])):E.kind==="tool"?(y(),he(X5,{key:3,tool:E.tool,mobile:e.mobile,onOpenMedia:A[3]||(A[3]=D=>o("openMedia",D)),onOpenFile:A[4]||(A[4]=D=>o("openFile",D)),onOpenAgent:A[5]||(A[5]=D=>o("openAgent",D))},null,8,["tool","mobile"])):E.kind==="notification"?(y(),he(YN,{key:4,items:E.items},null,8,["items"])):ee("",!0)],64))),128))])],10,Kwe)):ee("",!0)],2)):ee("",!0)}}),Xwe=ft(Ywe,[["__scopeId","data-v-66797f5d"]]),Jwe={class:"turn-files"},Qwe={class:"tf-ic","aria-hidden":"true"},e_e={class:"tf-title"},t_e={key:0,class:"tf-stats"},n_e={key:0,class:"tf-add"},o_e={key:1,class:"tf-del"},s_e={class:"diffbar","aria-hidden":"true"},i_e={class:"tf-list"},r_e={key:0,class:"tf-dir"},l_e={class:"tf-base"},a_e={key:0,class:"tf-stats"},u_e={key:0,class:"tf-add"},c_e={key:1,class:"tf-del"},w4=3,d_e=et({__name:"TurnFilesSummary",props:{changes:{},cwd:{},interactive:{type:Boolean,default:!0}},emits:["openDiff","openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.interactive!==!1),r=R(()=>{const g=n.changes.length;return s(g===1?"conversation.turnFiles.titleOne":"conversation.turnFiles.titleOther",{number:g})}),l=R(()=>n.changes.some(g=>g.statsIncomplete)),a=R(()=>{let g=0,x=0;for(const S of n.changes)g+=S.added,x+=S.removed;return{added:g,removed:x}}),u=R(()=>!l.value&&(a.value.added>0||a.value.removed>0)),c=Z(!1),d=R(()=>c.value?n.changes:n.changes.slice(0,w4)),f=R(()=>Math.max(0,n.changes.length-w4)),h=R(()=>n.changes.length>w4),m=R(()=>c.value?s("conversation.turnFiles.showLess"):f.value===1?s("conversation.turnFiles.moreOne"):s("conversation.turnFiles.more",{number:f.value}));function v(g){const x=n.cwd?h2(g,n.cwd):null;return x!==null?x||v1(g):g}function k(g){const x=v(g),S=Math.max(x.lastIndexOf("/"),x.lastIndexOf("\\"));return S>0?x.slice(0,S+1):""}function w(g){const x=v(g),S=Math.max(x.lastIndexOf("/"),x.lastIndexOf("\\"));return S>=0?x.slice(S+1):x}function b(g){return g.statsIncomplete||g.added===0&&g.removed===0?null:{added:g.added,removed:g.removed}}function _(g){g.hasWrite?o("openFile",{path:g.path}):o("openDiff",g)}return(g,x)=>(y(),M("div",Jwe,[j(p(tW),null,fA({head:me(()=>[C("span",Qwe,[j(p(Te),{name:"pencil",size:"sm"})]),C("span",e_e,N(r.value),1),u.value?(y(),M("span",t_e,[a.value.added>0?(y(),M("span",n_e,"+"+N(a.value.added),1)):ee("",!0),a.value.removed>0?(y(),M("span",o_e,"−"+N(a.value.removed),1)):ee("",!0),C("span",s_e,[C("span",{class:"seg-add",style:Zt({flexGrow:a.value.added})},null,4),C("span",{class:"seg-del",style:Zt({flexGrow:a.value.removed})},null,4)])])):ee("",!0)]),default:me(()=>[C("ul",i_e,[(y(!0),M(Pe,null,pt(d.value,S=>(y(),M("li",{key:S.path,class:"tf-row"},[(y(),he(bs(i.value?"button":"span"),{class:"tf-file",type:i.value?"button":void 0,onClick:T=>i.value&&_(S)},{default:me(()=>[k(S.path)?(y(),M("span",r_e,N(k(S.path)),1)):ee("",!0),C("span",l_e,N(w(S.path)),1)]),_:2},1032,["type","onClick"])),b(S)?(y(),M("span",a_e,[b(S).added>0?(y(),M("span",u_e,"+"+N(b(S).added),1)):ee("",!0),b(S).removed>0?(y(),M("span",c_e,"−"+N(b(S).removed),1)):ee("",!0)])):ee("",!0)]))),128))])]),_:2},[h.value?{name:"foot",fn:me(()=>[j(p(Rt),{variant:"ghost",size:"sm",class:"tf-more","aria-expanded":c.value,onClick:x[0]||(x[0]=S=>c.value=!c.value)},{default:me(()=>[qe(N(m.value)+" ",1),j(p(Te),{class:Re(["tf-more-car",{open:c.value}]),name:"chevron-down",size:"sm","aria-hidden":"true"},null,8,["class"])]),_:1},8,["aria-expanded"])]),key:"0"}:void 0]),1024)]))}}),f_e=ft(d_e,[["__scopeId","data-v-f37da416"]]),p_e={class:"activity-notice",role:"status"},h_e={"aria-hidden":"true"},m_e={class:"an-label"},g_e=et({__name:"ActivityNotice",props:{label:{}},setup(e){return(t,n)=>(y(),M("div",p_e,[C("span",h_e,[j(p(Ao),{size:"sm"})]),C("span",m_e,N(e.label),1)]))}}),v_e=ft(g_e,[["__scopeId","data-v-cc29061f"]]),y_e=["data-turn-id"],k_e=["title"],b_e={class:"cn-head-text"},C_e={key:0,class:"cn-bubble"},w_e={class:"cn-prompt"},__e={key:1,class:"cn-meta"},x_e=et({__name:"CronNotice",props:{text:{},cron:{},turnId:{},createdAt:{}},setup(e){const t=e,{t:n}=Nt(),o=R(()=>t.cron),s=R(()=>o.value?.missedCount!==void 0),i=R(()=>s.value?n("conversation.cron.missed"):n("conversation.cron.fired")),r=R(()=>{const f=o.value;return!f?.cron||f.recurring===!1?"":f.cron}),l=R(()=>s.value?"error":"ok"),a=R(()=>{const f=o.value;if(!f)return"";const h=[];return f.recurring===!1&&h.push(n("conversation.cron.oneShot")),typeof f.coalescedCount=="number"&&f.coalescedCount>1&&h.push(n("conversation.cron.coalesced",{n:f.coalescedCount})),f.missedCount!==void 0&&h.push(n("conversation.cron.missedCount",{n:f.missedCount})),f.stale===!0&&h.push(n("conversation.cron.finalDelivery")),h.join(" · ")}),u=R(()=>{const f=[i.value];return r.value&&f.push(r.value),a.value&&f.push(a.value),f.join(" · ")}),c=R(()=>{const f=o.value?.jobId;return f?n("conversation.cron.job",{id:f}):void 0}),d=R(()=>t.text??"");return(f,h)=>(y(),M("div",{class:Re(["cn cron-notice",{"turn-anchor":!!e.turnId}]),"data-turn-id":e.turnId,role:"status"},[C("div",{class:Re(["cn-head",l.value]),title:c.value},[j(p(Te),{name:"clock",size:"sm",class:"cn-head-ico","aria-hidden":"true"}),C("span",b_e,N(u.value),1)],10,k_e),d.value?(y(),M("div",C_e,[C("span",w_e,N(d.value),1)])):ee("",!0),e.createdAt?(y(),M("div",__e,[j(Rg,{time:e.createdAt},null,8,["time"])])):ee("",!0)],10,y_e))}}),S_e=ft(x_e,[["__scopeId","data-v-9f79345d"]]),A_e=/^(application\/pdf|image\/(png|jpe?g|gif|webp|avif|bmp|x-icon|vnd\.microsoft\.icon)|video\/[\w.+-]+|audio\/[\w.+-]+)$/i,M_e=/^(txt|md|markdown|log|json|ya?ml|csv|tsv|ts|mts|tsx|jsx|css|py|go|rs|java|c|h|cc|cpp|hpp|sh|zsh|sql|toml|ini|cfg|conf|vue)$/i,T_e=/^(png|jpe?g|gif|webp|avif|bmp|ico)$/i,eS="text/plain;charset=utf-8";function E_e(e,t){const n=(t??"").toLowerCase();if(A_e.test(n))return n;if(n.startsWith("text/"))return n==="text/html"?null:eS;const o=e?.match(/\.([A-Za-z0-9]{1,8})$/)?.[1]?.toLowerCase();return o===void 0?null:M_e.test(o)?eS:T_e.test(o)?`image/${o==="jpg"?"jpeg":o==="ico"?"x-icon":o}`:o==="pdf"?"application/pdf":null}async function XN(e,t,n,o){const s=E_e(n,o);if(s===null)return"unsupported";const i=window.open("","_blank");i!==null&&(i.opener=null);const r=await e.getFileBlob(t).catch(()=>null);if(r===null)return i?.close(),"failed";const l=URL.createObjectURL(new Blob([r],{type:s}));if(i!==null)i.location.href=l;else{const a=document.createElement("a");a.href=l,a.download=n??t,a.click()}return setTimeout(()=>{URL.revokeObjectURL(l)},6e4),"previewed"}/*! + * PhotoSwipe 5.4.4 - https://photoswipe.com + * (c) 2024 Dmytro Semenov + */function er(e,t,n){const o=document.createElement(t);return e&&(o.className=e),n&&n.appendChild(o),o}function is(e,t){return e.x=t.x,e.y=t.y,t.id!==void 0&&(e.id=t.id),e}function JN(e){e.x=Math.round(e.x),e.y=Math.round(e.y)}function S8(e,t){const n=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y);return Math.sqrt(n*n+o*o)}function sp(e,t){return e.x===t.x&&e.y===t.y}function r0(e,t,n){return Math.min(Math.max(e,t),n)}function Np(e,t,n){let o=`translate3d(${e}px,${t||0}px,0)`;return n!==void 0&&(o+=` scale3d(${n},${n},1)`),o}function tc(e,t,n,o){e.style.transform=Np(t,n,o)}const I_e="cubic-bezier(.4,0,.22,1)";function QN(e,t,n,o){e.style.transition=t?`${t} ${n}ms ${o||I_e}`:"none"}function A8(e,t,n){e.style.width=typeof t=="number"?`${t}px`:t,e.style.height=typeof n=="number"?`${n}px`:n}function L_e(e){QN(e)}function $_e(e){return"decode"in e?e.decode().catch(()=>{}):e.complete?Promise.resolve(e):new Promise((t,n)=>{e.onload=()=>t(e),e.onerror=n})}const gr={IDLE:"idle",LOADING:"loading",LOADED:"loaded",ERROR:"error"};function N_e(e){return"button"in e&&e.button===1||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey}function F_e(e,t,n=document){let o=[];if(e instanceof Element)o=[e];else if(e instanceof NodeList||Array.isArray(e))o=Array.from(e);else{const s=typeof e=="string"?e:t;s&&(o=Array.from(n.querySelectorAll(s)))}return o}function tS(){return!!(navigator.vendor&&navigator.vendor.match(/apple/i))}let eF=!1;try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:()=>{eF=!0}}))}catch{}class R_e{constructor(){this._pool=[]}add(t,n,o,s){this._toggleListener(t,n,o,s)}remove(t,n,o,s){this._toggleListener(t,n,o,s,!0)}removeAll(){this._pool.forEach(t=>{this._toggleListener(t.target,t.type,t.listener,t.passive,!0,!0)}),this._pool=[]}_toggleListener(t,n,o,s,i,r){if(!t)return;const l=i?"removeEventListener":"addEventListener";n.split(" ").forEach(u=>{if(u){r||(i?this._pool=this._pool.filter(d=>d.type!==u||d.listener!==o||d.target!==t):this._pool.push({target:t,type:u,listener:o,passive:s}));const c=eF?{passive:s||!1}:!1;t[l](u,o,c)}})}}function tF(e,t){if(e.getViewportSizeFn){const n=e.getViewportSizeFn(e,t);if(n)return n}return{x:document.documentElement.clientWidth,y:window.innerHeight}}function Lf(e,t,n,o,s){let i=0;if(t.paddingFn)i=t.paddingFn(n,o,s)[e];else if(t.padding)i=t.padding[e];else{const r="padding"+e[0].toUpperCase()+e.slice(1);t[r]&&(i=t[r])}return Number(i)||0}function nF(e,t,n,o){return{x:t.x-Lf("left",e,t,n,o)-Lf("right",e,t,n,o),y:t.y-Lf("top",e,t,n,o)-Lf("bottom",e,t,n,o)}}class O_e{constructor(t){this.slide=t,this.currZoomLevel=1,this.center={x:0,y:0},this.max={x:0,y:0},this.min={x:0,y:0}}update(t){this.currZoomLevel=t,this.slide.width?(this._updateAxis("x"),this._updateAxis("y"),this.slide.pswp.dispatch("calcBounds",{slide:this.slide})):this.reset()}_updateAxis(t){const{pswp:n}=this.slide,o=this.slide[t==="x"?"width":"height"]*this.currZoomLevel,i=Lf(t==="x"?"left":"top",n.options,n.viewportSize,this.slide.data,this.slide.index),r=this.slide.panAreaSize[t];this.center[t]=Math.round((r-o)/2)+i,this.max[t]=o>r?Math.round(r-o)+i:this.center[t],this.min[t]=o>r?i:this.center[t]}reset(){this.center.x=0,this.center.y=0,this.max.x=0,this.max.y=0,this.min.x=0,this.min.y=0}correctPan(t,n){return r0(n,this.max[t],this.min[t])}}const nS=4e3;class oF{constructor(t,n,o,s){this.pswp=s,this.options=t,this.itemData=n,this.index=o,this.panAreaSize=null,this.elementSize=null,this.fit=1,this.fill=1,this.vFill=1,this.initial=1,this.secondary=1,this.max=1,this.min=1}update(t,n,o){const s={x:t,y:n};this.elementSize=s,this.panAreaSize=o;const i=o.x/s.x,r=o.y/s.y;this.fit=Math.min(1,i<r?i:r),this.fill=Math.min(1,i>r?i:r),this.vFill=Math.min(1,r),this.initial=this._getInitial(),this.secondary=this._getSecondary(),this.max=Math.max(this.initial,this.secondary,this._getMax()),this.min=Math.min(this.fit,this.initial,this.secondary),this.pswp&&this.pswp.dispatch("zoomLevelsUpdate",{zoomLevels:this,slideData:this.itemData})}_parseZoomLevelOption(t){const n=t+"ZoomLevel",o=this.options[n];if(o)return typeof o=="function"?o(this):o==="fill"?this.fill:o==="fit"?this.fit:Number(o)}_getSecondary(){let t=this._parseZoomLevelOption("secondary");return t||(t=Math.min(1,this.fit*3),this.elementSize&&t*this.elementSize.x>nS&&(t=nS/this.elementSize.x),t)}_getInitial(){return this._parseZoomLevelOption("initial")||this.fit}_getMax(){return this._parseZoomLevelOption("max")||Math.max(1,this.fit*4)}}class P_e{constructor(t,n,o){this.data=t,this.index=n,this.pswp=o,this.isActive=n===o.currIndex,this.currentResolution=0,this.panAreaSize={x:0,y:0},this.pan={x:0,y:0},this.isFirstSlide=this.isActive&&!o.opener.isOpen,this.zoomLevels=new oF(o.options,t,n,o),this.pswp.dispatch("gettingData",{slide:this,data:this.data,index:n}),this.content=this.pswp.contentLoader.getContentBySlide(this),this.container=er("pswp__zoom-wrap","div"),this.holderElement=null,this.currZoomLevel=1,this.width=this.content.width,this.height=this.content.height,this.heavyAppended=!1,this.bounds=new O_e(this),this.prevDisplayedWidth=-1,this.prevDisplayedHeight=-1,this.pswp.dispatch("slideInit",{slide:this})}setIsActive(t){t&&!this.isActive?this.activate():!t&&this.isActive&&this.deactivate()}append(t){this.holderElement=t,this.container.style.transformOrigin="0 0",this.data&&(this.calculateSize(),this.load(),this.updateContentSize(),this.appendHeavy(),this.holderElement.appendChild(this.container),this.zoomAndPanToInitial(),this.pswp.dispatch("firstZoomPan",{slide:this}),this.applyCurrentZoomPan(),this.pswp.dispatch("afterSetContent",{slide:this}),this.isActive&&this.activate())}load(){this.content.load(!1),this.pswp.dispatch("slideLoad",{slide:this})}appendHeavy(){const{pswp:t}=this;this.heavyAppended||!t.opener.isOpen||t.mainScroll.isShifted()||!this.isActive&&!1||this.pswp.dispatch("appendHeavy",{slide:this}).defaultPrevented||(this.heavyAppended=!0,this.content.append(),this.pswp.dispatch("appendHeavyContent",{slide:this}))}activate(){this.isActive=!0,this.appendHeavy(),this.content.activate(),this.pswp.dispatch("slideActivate",{slide:this})}deactivate(){this.isActive=!1,this.content.deactivate(),this.currZoomLevel!==this.zoomLevels.initial&&this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize(),this.pswp.dispatch("slideDeactivate",{slide:this})}destroy(){this.content.hasSlide=!1,this.content.remove(),this.container.remove(),this.pswp.dispatch("slideDestroy",{slide:this})}resize(){this.currZoomLevel===this.zoomLevels.initial||!this.isActive?(this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize()):(this.calculateSize(),this.bounds.update(this.currZoomLevel),this.panTo(this.pan.x,this.pan.y))}updateContentSize(t){const n=this.currentResolution||this.zoomLevels.initial;if(!n)return;const o=Math.round(this.width*n)||this.pswp.viewportSize.x,s=Math.round(this.height*n)||this.pswp.viewportSize.y;!this.sizeChanged(o,s)&&!t||this.content.setDisplayedSize(o,s)}sizeChanged(t,n){return t!==this.prevDisplayedWidth||n!==this.prevDisplayedHeight?(this.prevDisplayedWidth=t,this.prevDisplayedHeight=n,!0):!1}getPlaceholderElement(){var t;return(t=this.content.placeholder)===null||t===void 0?void 0:t.element}zoomTo(t,n,o,s){const{pswp:i}=this;if(!this.isZoomable()||i.mainScroll.isShifted())return;i.dispatch("beforeZoomTo",{destZoomLevel:t,centerPoint:n,transitionDuration:o}),i.animations.stopAllPan();const r=this.currZoomLevel;s||(t=r0(t,this.zoomLevels.min,this.zoomLevels.max)),this.setZoomLevel(t),this.pan.x=this.calculateZoomToPanOffset("x",n,r),this.pan.y=this.calculateZoomToPanOffset("y",n,r),JN(this.pan);const l=()=>{this._setResolution(t),this.applyCurrentZoomPan()};o?i.animations.startTransition({isPan:!0,name:"zoomTo",target:this.container,transform:this.getCurrentTransform(),onComplete:l,duration:o,easing:i.options.easing}):l()}toggleZoom(t){this.zoomTo(this.currZoomLevel===this.zoomLevels.initial?this.zoomLevels.secondary:this.zoomLevels.initial,t,this.pswp.options.zoomAnimationDuration)}setZoomLevel(t){this.currZoomLevel=t,this.bounds.update(this.currZoomLevel)}calculateZoomToPanOffset(t,n,o){if(this.bounds.max[t]-this.bounds.min[t]===0)return this.bounds.center[t];n||(n=this.pswp.getViewportCenterPoint()),o||(o=this.zoomLevels.initial);const i=this.currZoomLevel/o;return this.bounds.correctPan(t,(this.pan[t]-n[t])*i+n[t])}panTo(t,n){this.pan.x=this.bounds.correctPan("x",t),this.pan.y=this.bounds.correctPan("y",n),this.applyCurrentZoomPan()}isPannable(){return!!this.width&&this.currZoomLevel>this.zoomLevels.fit}isZoomable(){return!!this.width&&this.content.isZoomable()}applyCurrentZoomPan(){this._applyZoomTransform(this.pan.x,this.pan.y,this.currZoomLevel),this===this.pswp.currSlide&&this.pswp.dispatch("zoomPanUpdate",{slide:this})}zoomAndPanToInitial(){this.currZoomLevel=this.zoomLevels.initial,this.bounds.update(this.currZoomLevel),is(this.pan,this.bounds.center),this.pswp.dispatch("initialZoomPan",{slide:this})}_applyZoomTransform(t,n,o){o/=this.currentResolution||this.zoomLevels.initial,tc(this.container,t,n,o)}calculateSize(){const{pswp:t}=this;is(this.panAreaSize,nF(t.options,t.viewportSize,this.data,this.index)),this.zoomLevels.update(this.width,this.height,this.panAreaSize),t.dispatch("calcSlideSize",{slide:this})}getCurrentTransform(){const t=this.currZoomLevel/(this.currentResolution||this.zoomLevels.initial);return Np(this.pan.x,this.pan.y,t)}_setResolution(t){t!==this.currentResolution&&(this.currentResolution=t,this.updateContentSize(),this.pswp.dispatch("resolutionChanged"))}}const D_e=.35,B_e=.6,oS=.4,sS=.5;function H_e(e,t){return e*t/(1-t)}class z_e{constructor(t){this.gestures=t,this.pswp=t.pswp,this.startPan={x:0,y:0}}start(){this.pswp.currSlide&&is(this.startPan,this.pswp.currSlide.pan),this.pswp.animations.stopAll()}change(){const{p1:t,prevP1:n,dragAxis:o}=this.gestures,{currSlide:s}=this.pswp;if(o==="y"&&this.pswp.options.closeOnVerticalDrag&&s&&s.currZoomLevel<=s.zoomLevels.fit&&!this.gestures.isMultitouch){const i=s.pan.y+(t.y-n.y);if(!this.pswp.dispatch("verticalDrag",{panY:i}).defaultPrevented){this._setPanWithFriction("y",i,B_e);const r=1-Math.abs(this._getVerticalDragRatio(s.pan.y));this.pswp.applyBgOpacity(r),s.applyCurrentZoomPan()}}else this._panOrMoveMainScroll("x")||(this._panOrMoveMainScroll("y"),s&&(JN(s.pan),s.applyCurrentZoomPan()))}end(){const{velocity:t}=this.gestures,{mainScroll:n,currSlide:o}=this.pswp;let s=0;if(this.pswp.animations.stopAll(),n.isShifted()){const r=(n.x-n.getCurrSlideX())/this.pswp.viewportSize.x;t.x<-sS&&r<0||t.x<.1&&r<-.5?(s=1,t.x=Math.min(t.x,0)):(t.x>sS&&r>0||t.x>-.1&&r>.5)&&(s=-1,t.x=Math.max(t.x,0)),n.moveIndexBy(s,!0,t.x)}o&&o.currZoomLevel>o.zoomLevels.max||this.gestures.isMultitouch?this.gestures.zoomLevels.correctZoomPan(!0):(this._finishPanGestureForAxis("x"),this._finishPanGestureForAxis("y"))}_finishPanGestureForAxis(t){const{velocity:n}=this.gestures,{currSlide:o}=this.pswp;if(!o)return;const{pan:s,bounds:i}=o,r=s[t],l=this.pswp.bgOpacity<1&&t==="y",u=r+H_e(n[t],.995);if(l){const m=this._getVerticalDragRatio(r),v=this._getVerticalDragRatio(u);if(m<0&&v<-oS||m>0&&v>oS){this.pswp.close();return}}const c=i.correctPan(t,u);if(r===c)return;const d=c===u?1:.82,f=this.pswp.bgOpacity,h=c-r;this.pswp.animations.startSpring({name:"panGesture"+t,isPan:!0,start:r,end:c,velocity:n[t],dampingRatio:d,onUpdate:m=>{if(l&&this.pswp.bgOpacity<1){const v=1-(c-m)/h;this.pswp.applyBgOpacity(r0(f+(1-f)*v,0,1))}s[t]=Math.floor(m),o.applyCurrentZoomPan()}})}_panOrMoveMainScroll(t){const{p1:n,dragAxis:o,prevP1:s,isMultitouch:i}=this.gestures,{currSlide:r,mainScroll:l}=this.pswp,a=n[t]-s[t],u=l.x+a;if(!a||!r)return!1;if(t==="x"&&!r.isPannable()&&!i)return l.moveTo(u,!0),!0;const{bounds:c}=r,d=r.pan[t]+a;if(this.pswp.options.allowPanToNext&&o==="x"&&t==="x"&&!i){const f=l.getCurrSlideX(),h=l.x-f,m=a>0,v=!m;if(d>c.min[t]&&m){if(c.min[t]<=this.startPan[t])return l.moveTo(u,!0),!0;this._setPanWithFriction(t,d)}else if(d<c.max[t]&&v){if(this.startPan[t]<=c.max[t])return l.moveTo(u,!0),!0;this._setPanWithFriction(t,d)}else if(h!==0){if(h>0)return l.moveTo(Math.max(u,f),!0),!0;if(h<0)return l.moveTo(Math.min(u,f),!0),!0}else this._setPanWithFriction(t,d)}else t==="y"?!l.isShifted()&&c.min.y!==c.max.y&&this._setPanWithFriction(t,d):this._setPanWithFriction(t,d);return!1}_getVerticalDragRatio(t){var n,o;return(t-((n=(o=this.pswp.currSlide)===null||o===void 0?void 0:o.bounds.center.y)!==null&&n!==void 0?n:0))/(this.pswp.viewportSize.y/3)}_setPanWithFriction(t,n,o){const{currSlide:s}=this.pswp;if(!s)return;const{pan:i,bounds:r}=s;if(r.correctPan(t,n)!==n||o){const a=Math.round(n-i[t]);i[t]+=a*(o||D_e)}else i[t]=n}}const W_e=.05,U_e=.15;function iS(e,t,n){return e.x=(t.x+n.x)/2,e.y=(t.y+n.y)/2,e}class j_e{constructor(t){this.gestures=t,this._startPan={x:0,y:0},this._startZoomPoint={x:0,y:0},this._zoomPoint={x:0,y:0},this._wasOverFitZoomLevel=!1,this._startZoomLevel=1}start(){const{currSlide:t}=this.gestures.pswp;t&&(this._startZoomLevel=t.currZoomLevel,is(this._startPan,t.pan)),this.gestures.pswp.animations.stopAllPan(),this._wasOverFitZoomLevel=!1}change(){const{p1:t,startP1:n,p2:o,startP2:s,pswp:i}=this.gestures,{currSlide:r}=i;if(!r)return;const l=r.zoomLevels.min,a=r.zoomLevels.max;if(!r.isZoomable()||i.mainScroll.isShifted())return;iS(this._startZoomPoint,n,s),iS(this._zoomPoint,t,o);let u=1/S8(n,s)*S8(t,o)*this._startZoomLevel;if(u>r.zoomLevels.initial+r.zoomLevels.initial/15&&(this._wasOverFitZoomLevel=!0),u<l)if(i.options.pinchToClose&&!this._wasOverFitZoomLevel&&this._startZoomLevel<=r.zoomLevels.initial){const c=1-(l-u)/(l/1.2);i.dispatch("pinchClose",{bgOpacity:c}).defaultPrevented||i.applyBgOpacity(c)}else u=l-(l-u)*U_e;else u>a&&(u=a+(u-a)*W_e);r.pan.x=this._calculatePanForZoomLevel("x",u),r.pan.y=this._calculatePanForZoomLevel("y",u),r.setZoomLevel(u),r.applyCurrentZoomPan()}end(){const{pswp:t}=this.gestures,{currSlide:n}=t;(!n||n.currZoomLevel<n.zoomLevels.initial)&&!this._wasOverFitZoomLevel&&t.options.pinchToClose?t.close():this.correctZoomPan()}_calculatePanForZoomLevel(t,n){const o=n/this._startZoomLevel;return this._zoomPoint[t]-(this._startZoomPoint[t]-this._startPan[t])*o}correctZoomPan(t){const{pswp:n}=this.gestures,{currSlide:o}=n;if(!(o!=null&&o.isZoomable()))return;this._zoomPoint.x===0&&(t=!0);const s=o.currZoomLevel;let i,r=!0;s<o.zoomLevels.initial?i=o.zoomLevels.initial:s>o.zoomLevels.max?i=o.zoomLevels.max:(r=!1,i=s);const l=n.bgOpacity,a=n.bgOpacity<1,u=is({x:0,y:0},o.pan);let c=is({x:0,y:0},u);t&&(this._zoomPoint.x=0,this._zoomPoint.y=0,this._startZoomPoint.x=0,this._startZoomPoint.y=0,this._startZoomLevel=s,is(this._startPan,u)),r&&(c={x:this._calculatePanForZoomLevel("x",i),y:this._calculatePanForZoomLevel("y",i)}),o.setZoomLevel(i),c={x:o.bounds.correctPan("x",c.x),y:o.bounds.correctPan("y",c.y)},o.setZoomLevel(s);const d=!sp(c,u);if(!d&&!r&&!a){o._setResolution(i),o.applyCurrentZoomPan();return}n.animations.stopAllPan(),n.animations.startSpring({isPan:!0,start:0,end:1e3,velocity:0,dampingRatio:1,naturalFrequency:40,onUpdate:f=>{if(f/=1e3,d||r){if(d&&(o.pan.x=u.x+(c.x-u.x)*f,o.pan.y=u.y+(c.y-u.y)*f),r){const h=s+(i-s)*f;o.setZoomLevel(h)}o.applyCurrentZoomPan()}a&&n.bgOpacity<1&&n.applyBgOpacity(r0(l+(1-l)*f,0,1))},onComplete:()=>{o._setResolution(i),o.applyCurrentZoomPan()}})}}function rS(e){return!!e.target.closest(".pswp__container")}class V_e{constructor(t){this.gestures=t}click(t,n){const o=n.target.classList,s=o.contains("pswp__img"),i=o.contains("pswp__item")||o.contains("pswp__zoom-wrap");s?this._doClickOrTapAction("imageClick",t,n):i&&this._doClickOrTapAction("bgClick",t,n)}tap(t,n){rS(n)&&this._doClickOrTapAction("tap",t,n)}doubleTap(t,n){rS(n)&&this._doClickOrTapAction("doubleTap",t,n)}_doClickOrTapAction(t,n,o){var s;const{pswp:i}=this.gestures,{currSlide:r}=i,l=t+"Action",a=i.options[l];if(!i.dispatch(l,{point:n,originalEvent:o}).defaultPrevented){if(typeof a=="function"){a.call(i,n,o);return}switch(a){case"close":case"next":i[a]();break;case"zoom":r?.toggleZoom(n);break;case"zoom-or-close":r!=null&&r.isZoomable()&&r.zoomLevels.secondary!==r.zoomLevels.initial?r.toggleZoom(n):i.options.clickToCloseNonZoomable&&i.close();break;case"toggle-controls":(s=this.gestures.pswp.element)===null||s===void 0||s.classList.toggle("pswp--ui-visible");break}}}}const q_e=10,K_e=300,Z_e=25;class G_e{constructor(t){this.pswp=t,this.dragAxis=null,this.p1={x:0,y:0},this.p2={x:0,y:0},this.prevP1={x:0,y:0},this.prevP2={x:0,y:0},this.startP1={x:0,y:0},this.startP2={x:0,y:0},this.velocity={x:0,y:0},this._lastStartP1={x:0,y:0},this._intervalP1={x:0,y:0},this._numActivePoints=0,this._ongoingPointers=[],this._touchEventEnabled="ontouchstart"in window,this._pointerEventEnabled=!!window.PointerEvent,this.supportsTouch=this._touchEventEnabled||this._pointerEventEnabled&&navigator.maxTouchPoints>1,this._numActivePoints=0,this._intervalTime=0,this._velocityCalculated=!1,this.isMultitouch=!1,this.isDragging=!1,this.isZooming=!1,this.raf=null,this._tapTimer=null,this.supportsTouch||(t.options.allowPanToNext=!1),this.drag=new z_e(this),this.zoomLevels=new j_e(this),this.tapHandler=new V_e(this),t.on("bindEvents",()=>{t.events.add(t.scrollWrap,"click",this._onClick.bind(this)),this._pointerEventEnabled?this._bindEvents("pointer","down","up","cancel"):this._touchEventEnabled?(this._bindEvents("touch","start","end","cancel"),t.scrollWrap&&(t.scrollWrap.ontouchmove=()=>{},t.scrollWrap.ontouchend=()=>{})):this._bindEvents("mouse","down","up")})}_bindEvents(t,n,o,s){const{pswp:i}=this,{events:r}=i,l=s?t+s:"";r.add(i.scrollWrap,t+n,this.onPointerDown.bind(this)),r.add(window,t+"move",this.onPointerMove.bind(this)),r.add(window,t+o,this.onPointerUp.bind(this)),l&&r.add(i.scrollWrap,l,this.onPointerUp.bind(this))}onPointerDown(t){const n=t.type==="mousedown"||t.pointerType==="mouse";if(n&&t.button>0)return;const{pswp:o}=this;if(!o.opener.isOpen){t.preventDefault();return}o.dispatch("pointerDown",{originalEvent:t}).defaultPrevented||(n&&(o.mouseDetected(),this._preventPointerEventBehaviour(t,"down")),o.animations.stopAll(),this._updatePoints(t,"down"),this._numActivePoints===1&&(this.dragAxis=null,is(this.startP1,this.p1)),this._numActivePoints>1?(this._clearTapTimer(),this.isMultitouch=!0):this.isMultitouch=!1)}onPointerMove(t){this._preventPointerEventBehaviour(t,"move"),this._numActivePoints&&(this._updatePoints(t,"move"),!this.pswp.dispatch("pointerMove",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===1&&!this.isDragging?(this.dragAxis||this._calculateDragDirection(),this.dragAxis&&!this.isDragging&&(this.isZooming&&(this.isZooming=!1,this.zoomLevels.end()),this.isDragging=!0,this._clearTapTimer(),this._updateStartPoints(),this._intervalTime=Date.now(),this._velocityCalculated=!1,is(this._intervalP1,this.p1),this.velocity.x=0,this.velocity.y=0,this.drag.start(),this._rafStopLoop(),this._rafRenderLoop())):this._numActivePoints>1&&!this.isZooming&&(this._finishDrag(),this.isZooming=!0,this._updateStartPoints(),this.zoomLevels.start(),this._rafStopLoop(),this._rafRenderLoop())))}_finishDrag(){this.isDragging&&(this.isDragging=!1,this._velocityCalculated||this._updateVelocity(!0),this.drag.end(),this.dragAxis=null)}onPointerUp(t){this._numActivePoints&&(this._updatePoints(t,"up"),!this.pswp.dispatch("pointerUp",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===0&&(this._rafStopLoop(),this.isDragging?this._finishDrag():!this.isZooming&&!this.isMultitouch&&this._finishTap(t)),this._numActivePoints<2&&this.isZooming&&(this.isZooming=!1,this.zoomLevels.end(),this._numActivePoints===1&&(this.dragAxis=null,this._updateStartPoints()))))}_rafRenderLoop(){(this.isDragging||this.isZooming)&&(this._updateVelocity(),this.isDragging?sp(this.p1,this.prevP1)||this.drag.change():(!sp(this.p1,this.prevP1)||!sp(this.p2,this.prevP2))&&this.zoomLevels.change(),this._updatePrevPoints(),this.raf=requestAnimationFrame(this._rafRenderLoop.bind(this)))}_updateVelocity(t){const n=Date.now(),o=n-this._intervalTime;o<50&&!t||(this.velocity.x=this._getVelocity("x",o),this.velocity.y=this._getVelocity("y",o),this._intervalTime=n,is(this._intervalP1,this.p1),this._velocityCalculated=!0)}_finishTap(t){const{mainScroll:n}=this.pswp;if(n.isShifted()){n.moveIndexBy(0,!0);return}if(t.type.indexOf("cancel")>0)return;if(t.type==="mouseup"||t.pointerType==="mouse"){this.tapHandler.click(this.startP1,t);return}const o=this.pswp.options.doubleTapAction?K_e:0;this._tapTimer?(this._clearTapTimer(),S8(this._lastStartP1,this.startP1)<Z_e&&this.tapHandler.doubleTap(this.startP1,t)):(is(this._lastStartP1,this.startP1),this._tapTimer=setTimeout(()=>{this.tapHandler.tap(this.startP1,t),this._clearTapTimer()},o))}_clearTapTimer(){this._tapTimer&&(clearTimeout(this._tapTimer),this._tapTimer=null)}_getVelocity(t,n){const o=this.p1[t]-this._intervalP1[t];return Math.abs(o)>1&&n>5?o/n:0}_rafStopLoop(){this.raf&&(cancelAnimationFrame(this.raf),this.raf=null)}_preventPointerEventBehaviour(t,n){this.pswp.applyFilters("preventPointerEvent",!0,t,n)&&t.preventDefault()}_updatePoints(t,n){if(this._pointerEventEnabled){const o=t,s=this._ongoingPointers.findIndex(i=>i.id===o.pointerId);n==="up"&&s>-1?this._ongoingPointers.splice(s,1):n==="down"&&s===-1?this._ongoingPointers.push(this._convertEventPosToPoint(o,{x:0,y:0})):s>-1&&this._convertEventPosToPoint(o,this._ongoingPointers[s]),this._numActivePoints=this._ongoingPointers.length,this._numActivePoints>0&&is(this.p1,this._ongoingPointers[0]),this._numActivePoints>1&&is(this.p2,this._ongoingPointers[1])}else{const o=t;this._numActivePoints=0,o.type.indexOf("touch")>-1?o.touches&&o.touches.length>0&&(this._convertEventPosToPoint(o.touches[0],this.p1),this._numActivePoints++,o.touches.length>1&&(this._convertEventPosToPoint(o.touches[1],this.p2),this._numActivePoints++)):(this._convertEventPosToPoint(t,this.p1),n==="up"?this._numActivePoints=0:this._numActivePoints++)}}_updatePrevPoints(){is(this.prevP1,this.p1),is(this.prevP2,this.p2)}_updateStartPoints(){is(this.startP1,this.p1),is(this.startP2,this.p2),this._updatePrevPoints()}_calculateDragDirection(){if(this.pswp.mainScroll.isShifted())this.dragAxis="x";else{const t=Math.abs(this.p1.x-this.startP1.x)-Math.abs(this.p1.y-this.startP1.y);if(t!==0){const n=t>0?"x":"y";Math.abs(this.p1[n]-this.startP1[n])>=q_e&&(this.dragAxis=n)}}}_convertEventPosToPoint(t,n){return n.x=t.pageX-this.pswp.offset.x,n.y=t.pageY-this.pswp.offset.y,"pointerId"in t?n.id=t.pointerId:t.identifier!==void 0&&(n.id=t.identifier),n}_onClick(t){this.pswp.mainScroll.isShifted()&&(t.preventDefault(),t.stopPropagation())}}const Y_e=.35;class X_e{constructor(t){this.pswp=t,this.x=0,this.slideWidth=0,this._currPositionIndex=0,this._prevPositionIndex=0,this._containerShiftIndex=-1,this.itemHolders=[]}resize(t){const{pswp:n}=this,o=Math.round(n.viewportSize.x+n.viewportSize.x*n.options.spacing),s=o!==this.slideWidth;s&&(this.slideWidth=o,this.moveTo(this.getCurrSlideX())),this.itemHolders.forEach((i,r)=>{s&&tc(i.el,(r+this._containerShiftIndex)*this.slideWidth),t&&i.slide&&i.slide.resize()})}resetPosition(){this._currPositionIndex=0,this._prevPositionIndex=0,this.slideWidth=0,this._containerShiftIndex=-1}appendHolders(){this.itemHolders=[];for(let t=0;t<3;t++){const n=er("pswp__item","div",this.pswp.container);n.setAttribute("role","group"),n.setAttribute("aria-roledescription","slide"),n.setAttribute("aria-hidden","true"),n.style.display=t===1?"block":"none",this.itemHolders.push({el:n})}}canBeSwiped(){return this.pswp.getNumItems()>1}moveIndexBy(t,n,o){const{pswp:s}=this;let i=s.potentialIndex+t;const r=s.getNumItems();if(s.canLoop()){i=s.getLoopedIndex(i);const a=(t+r)%r;a<=r/2?t=a:t=a-r}else i<0?i=0:i>=r&&(i=r-1),t=i-s.potentialIndex;s.potentialIndex=i,this._currPositionIndex-=t,s.animations.stopMainScroll();const l=this.getCurrSlideX();if(!n)this.moveTo(l),this.updateCurrItem();else{s.animations.startSpring({isMainScroll:!0,start:this.x,end:l,velocity:o||0,naturalFrequency:30,dampingRatio:1,onUpdate:u=>{this.moveTo(u)},onComplete:()=>{this.updateCurrItem(),s.appendHeavy()}});let a=s.potentialIndex-s.currIndex;if(s.canLoop()){const u=(a+r)%r;u<=r/2?a=u:a=u-r}Math.abs(a)>1&&this.updateCurrItem()}return!!t}getCurrSlideX(){return this.slideWidth*this._currPositionIndex}isShifted(){return this.x!==this.getCurrSlideX()}updateCurrItem(){var t;const{pswp:n}=this,o=this._prevPositionIndex-this._currPositionIndex;if(!o)return;this._prevPositionIndex=this._currPositionIndex,n.currIndex=n.potentialIndex;let s=Math.abs(o),i;s>=3&&(this._containerShiftIndex+=o+(o>0?-3:3),s=3,this.itemHolders.forEach(r=>{var l;(l=r.slide)===null||l===void 0||l.destroy(),r.slide=void 0}));for(let r=0;r<s;r++)o>0?(i=this.itemHolders.shift(),i&&(this.itemHolders[2]=i,this._containerShiftIndex++,tc(i.el,(this._containerShiftIndex+2)*this.slideWidth),n.setContent(i,n.currIndex-s+r+2))):(i=this.itemHolders.pop(),i&&(this.itemHolders.unshift(i),this._containerShiftIndex--,tc(i.el,this._containerShiftIndex*this.slideWidth),n.setContent(i,n.currIndex+s-r-2)));Math.abs(this._containerShiftIndex)>50&&!this.isShifted()&&(this.resetPosition(),this.resize()),n.animations.stopAllPan(),this.itemHolders.forEach((r,l)=>{r.slide&&r.slide.setIsActive(l===1)}),n.currSlide=(t=this.itemHolders[1])===null||t===void 0?void 0:t.slide,n.contentLoader.updateLazy(o),n.currSlide&&n.currSlide.applyCurrentZoomPan(),n.dispatch("change")}moveTo(t,n){if(!this.pswp.canLoop()&&n){let o=(this.slideWidth*this._currPositionIndex-t)/this.slideWidth;o+=this.pswp.currIndex;const s=Math.round(t-this.x);(o<0&&s>0||o>=this.pswp.getNumItems()-1&&s<0)&&(t=this.x+s*Y_e)}this.x=t,this.pswp.container&&tc(this.pswp.container,t),this.pswp.dispatch("moveMainScroll",{x:t,dragging:n??!1})}}const J_e={Escape:27,z:90,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Tab:9},zu=(e,t)=>t?e:J_e[e];class Q_e{constructor(t){this.pswp=t,this._wasFocused=!1,t.on("bindEvents",()=>{t.options.trapFocus&&(t.options.initialPointerPos||this._focusRoot(),t.events.add(document,"focusin",this._onFocusIn.bind(this))),t.events.add(document,"keydown",this._onKeyDown.bind(this))});const n=document.activeElement;t.on("destroy",()=>{t.options.returnFocus&&n&&this._wasFocused&&n.focus()})}_focusRoot(){!this._wasFocused&&this.pswp.element&&(this.pswp.element.focus(),this._wasFocused=!0)}_onKeyDown(t){const{pswp:n}=this;if(n.dispatch("keydown",{originalEvent:t}).defaultPrevented||N_e(t))return;let o,s,i=!1;const r="key"in t;switch(r?t.key:t.keyCode){case zu("Escape",r):n.options.escKey&&(o="close");break;case zu("z",r):o="toggleZoom";break;case zu("ArrowLeft",r):s="x";break;case zu("ArrowUp",r):s="y";break;case zu("ArrowRight",r):s="x",i=!0;break;case zu("ArrowDown",r):i=!0,s="y";break;case zu("Tab",r):this._focusRoot();break}if(s){t.preventDefault();const{currSlide:l}=n;n.options.arrowKeys&&s==="x"&&n.getNumItems()>1?o=i?"next":"prev":l&&l.currZoomLevel>l.zoomLevels.fit&&(l.pan[s]+=i?-80:80,l.panTo(l.pan.x,l.pan.y))}o&&(t.preventDefault(),n[o]())}_onFocusIn(t){const{template:n}=this.pswp;n&&document!==t.target&&n!==t.target&&!n.contains(t.target)&&n.focus()}}const exe="cubic-bezier(.4,0,.22,1)";class txe{constructor(t){var n;this.props=t;const{target:o,onComplete:s,transform:i,onFinish:r=()=>{},duration:l=333,easing:a=exe}=t;this.onFinish=r;const u=i?"transform":"opacity",c=(n=t[u])!==null&&n!==void 0?n:"";this._target=o,this._onComplete=s,this._finished=!1,this._onTransitionEnd=this._onTransitionEnd.bind(this),this._helperTimeout=setTimeout(()=>{QN(o,u,l,a),this._helperTimeout=setTimeout(()=>{o.addEventListener("transitionend",this._onTransitionEnd,!1),o.addEventListener("transitioncancel",this._onTransitionEnd,!1),this._helperTimeout=setTimeout(()=>{this._finalizeAnimation()},l+500),o.style[u]=c},30)},0)}_onTransitionEnd(t){t.target===this._target&&this._finalizeAnimation()}_finalizeAnimation(){this._finished||(this._finished=!0,this.onFinish(),this._onComplete&&this._onComplete())}destroy(){this._helperTimeout&&clearTimeout(this._helperTimeout),L_e(this._target),this._target.removeEventListener("transitionend",this._onTransitionEnd,!1),this._target.removeEventListener("transitioncancel",this._onTransitionEnd,!1),this._finished||this._finalizeAnimation()}}const nxe=12,oxe=.75;class sxe{constructor(t,n,o){this.velocity=t*1e3,this._dampingRatio=n||oxe,this._naturalFrequency=o||nxe,this._dampedFrequency=this._naturalFrequency,this._dampingRatio<1&&(this._dampedFrequency*=Math.sqrt(1-this._dampingRatio*this._dampingRatio))}easeFrame(t,n){let o=0,s;n/=1e3;const i=Math.E**(-this._dampingRatio*this._naturalFrequency*n);if(this._dampingRatio===1)s=this.velocity+this._naturalFrequency*t,o=(t+s*n)*i,this.velocity=o*-this._naturalFrequency+s*i;else if(this._dampingRatio<1){s=1/this._dampedFrequency*(this._dampingRatio*this._naturalFrequency*t+this.velocity);const r=Math.cos(this._dampedFrequency*n),l=Math.sin(this._dampedFrequency*n);o=i*(t*r+s*l),this.velocity=o*-this._naturalFrequency*this._dampingRatio+i*(-this._dampedFrequency*t*l+this._dampedFrequency*s*r)}return o}}class ixe{constructor(t){this.props=t,this._raf=0;const{start:n,end:o,velocity:s,onUpdate:i,onComplete:r,onFinish:l=()=>{},dampingRatio:a,naturalFrequency:u}=t;this.onFinish=l;const c=new sxe(s,a,u);let d=Date.now(),f=n-o;const h=()=>{this._raf&&(f=c.easeFrame(f,Date.now()-d),Math.abs(f)<1&&Math.abs(c.velocity)<50?(i(o),r&&r(),this.onFinish()):(d=Date.now(),i(f+o),this._raf=requestAnimationFrame(h)))};this._raf=requestAnimationFrame(h)}destroy(){this._raf>=0&&cancelAnimationFrame(this._raf),this._raf=0}}class rxe{constructor(){this.activeAnimations=[]}startSpring(t){this._start(t,!0)}startTransition(t){this._start(t)}_start(t,n){const o=n?new ixe(t):new txe(t);return this.activeAnimations.push(o),o.onFinish=()=>this.stop(o),o}stop(t){t.destroy();const n=this.activeAnimations.indexOf(t);n>-1&&this.activeAnimations.splice(n,1)}stopAll(){this.activeAnimations.forEach(t=>{t.destroy()}),this.activeAnimations=[]}stopAllPan(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isPan?(t.destroy(),!1):!0)}stopMainScroll(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isMainScroll?(t.destroy(),!1):!0)}isPanRunning(){return this.activeAnimations.some(t=>t.props.isPan)}}class lxe{constructor(t){this.pswp=t,t.events.add(t.element,"wheel",this._onWheel.bind(this))}_onWheel(t){t.preventDefault();const{currSlide:n}=this.pswp;let{deltaX:o,deltaY:s}=t;if(n&&!this.pswp.dispatch("wheel",{originalEvent:t}).defaultPrevented)if(t.ctrlKey||this.pswp.options.wheelToZoom){if(n.isZoomable()){let i=-s;t.deltaMode===1?i*=.05:i*=t.deltaMode?1:.002,i=2**i;const r=n.currZoomLevel*i;n.zoomTo(r,{x:t.clientX,y:t.clientY})}}else n.isPannable()&&(t.deltaMode===1&&(o*=18,s*=18),n.panTo(n.pan.x-o,n.pan.y-s))}}function axe(e){if(typeof e=="string")return e;if(!e||!e.isCustomSVG)return"";const t=e;let n='<svg aria-hidden="true" class="pswp__icn" viewBox="0 0 %d %d" width="%d" height="%d">';return n=n.split("%d").join(t.size||32),t.outlineID&&(n+='<use class="pswp__icn-shadow" xlink:href="#'+t.outlineID+'"/>'),n+=t.inner,n+="</svg>",n}class uxe{constructor(t,n){var o;const s=n.name||n.className;let i=n.html;if(t.options[s]===!1)return;typeof t.options[s+"SVG"]=="string"&&(i=t.options[s+"SVG"]),t.dispatch("uiElementCreate",{data:n});let r="";n.isButton?(r+="pswp__button ",r+=n.className||`pswp__button--${n.name}`):r+=n.className||`pswp__${n.name}`;let l=n.isButton?n.tagName||"button":n.tagName||"div";l=l.toLowerCase();const a=er(r,l);if(n.isButton){l==="button"&&(a.type="button");let{title:d}=n;const{ariaLabel:f}=n;typeof t.options[s+"Title"]=="string"&&(d=t.options[s+"Title"]),d&&(a.title=d);const h=f||d;h&&a.setAttribute("aria-label",h)}a.innerHTML=axe(i),n.onInit&&n.onInit(a,t),n.onClick&&(a.onclick=d=>{typeof n.onClick=="string"?t[n.onClick]():typeof n.onClick=="function"&&n.onClick(d,a,t)});const u=n.appendTo||"bar";let c=t.element;u==="bar"?(t.topBar||(t.topBar=er("pswp__top-bar pswp__hide-on-close","div",t.scrollWrap)),c=t.topBar):(a.classList.add("pswp__hide-on-close"),u==="wrapper"&&(c=t.scrollWrap)),(o=c)===null||o===void 0||o.appendChild(t.applyFilters("uiElement",a,n))}}function sF(e,t,n){e.classList.add("pswp__button--arrow"),e.setAttribute("aria-controls","pswp__items"),t.on("change",()=>{t.options.loop||(n?e.disabled=!(t.currIndex<t.getNumItems()-1):e.disabled=!(t.currIndex>0))})}const cxe={name:"arrowPrev",className:"pswp__button--arrow--prev",title:"Previous",order:10,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'<path d="M29 43l-3 3-16-16 16-16 3 3-13 13 13 13z" id="pswp__icn-arrow"/>',outlineID:"pswp__icn-arrow"},onClick:"prev",onInit:sF},dxe={name:"arrowNext",className:"pswp__button--arrow--next",title:"Next",order:11,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'<use xlink:href="#pswp__icn-arrow"/>',outlineID:"pswp__icn-arrow"},onClick:"next",onInit:(e,t)=>{sF(e,t,!0)}},fxe={name:"close",title:"Close",order:20,isButton:!0,html:{isCustomSVG:!0,inner:'<path d="M24 10l-2-2-6 6-6-6-2 2 6 6-6 6 2 2 6-6 6 6 2-2-6-6z" id="pswp__icn-close"/>',outlineID:"pswp__icn-close"},onClick:"close"},pxe={name:"zoom",title:"Zoom",order:10,isButton:!0,html:{isCustomSVG:!0,inner:'<path d="M17.426 19.926a6 6 0 1 1 1.5-1.5L23 22.5 21.5 24l-4.074-4.074z" id="pswp__icn-zoom"/><path fill="currentColor" class="pswp__zoom-icn-bar-h" d="M11 16v-2h6v2z"/><path fill="currentColor" class="pswp__zoom-icn-bar-v" d="M13 12h2v6h-2z"/>',outlineID:"pswp__icn-zoom"},onClick:"toggleZoom"},hxe={name:"preloader",appendTo:"bar",order:7,html:{isCustomSVG:!0,inner:'<path fill-rule="evenodd" clip-rule="evenodd" d="M21.2 16a5.2 5.2 0 1 1-5.2-5.2V8a8 8 0 1 0 8 8h-2.8Z" id="pswp__icn-loading"/>',outlineID:"pswp__icn-loading"},onInit:(e,t)=>{let n,o=null;const s=(l,a)=>{e.classList.toggle("pswp__preloader--"+l,a)},i=l=>{n!==l&&(n=l,s("active",l))},r=()=>{var l;if(!((l=t.currSlide)!==null&&l!==void 0&&l.content.isLoading())){i(!1),o&&(clearTimeout(o),o=null);return}o||(o=setTimeout(()=>{var a;i(!!(!((a=t.currSlide)===null||a===void 0)&&a.content.isLoading())),o=null},t.options.preloaderDelay))};t.on("change",r),t.on("loadComplete",l=>{t.currSlide===l.slide&&r()}),t.ui&&(t.ui.updatePreloaderVisibility=r)}},mxe={name:"counter",order:5,onInit:(e,t)=>{t.on("change",()=>{e.innerText=t.currIndex+1+t.options.indexIndicatorSep+t.getNumItems()})}};function lS(e,t){e.classList.toggle("pswp--zoomed-in",t)}class gxe{constructor(t){this.pswp=t,this.isRegistered=!1,this.uiElementsData=[],this.items=[],this.updatePreloaderVisibility=()=>{},this._lastUpdatedZoomLevel=void 0}init(){const{pswp:t}=this;this.isRegistered=!1,this.uiElementsData=[fxe,cxe,dxe,pxe,hxe,mxe],t.dispatch("uiRegister"),this.uiElementsData.sort((n,o)=>(n.order||0)-(o.order||0)),this.items=[],this.isRegistered=!0,this.uiElementsData.forEach(n=>{this.registerElement(n)}),t.on("change",()=>{var n;(n=t.element)===null||n===void 0||n.classList.toggle("pswp--one-slide",t.getNumItems()===1)}),t.on("zoomPanUpdate",()=>this._onZoomPanUpdate())}registerElement(t){this.isRegistered?this.items.push(new uxe(this.pswp,t)):this.uiElementsData.push(t)}_onZoomPanUpdate(){const{template:t,currSlide:n,options:o}=this.pswp;if(this.pswp.opener.isClosing||!t||!n)return;let{currZoomLevel:s}=n;if(this.pswp.opener.isOpen||(s=n.zoomLevels.initial),s===this._lastUpdatedZoomLevel)return;this._lastUpdatedZoomLevel=s;const i=n.zoomLevels.initial-n.zoomLevels.secondary;if(Math.abs(i)<.01||!n.isZoomable()){lS(t,!1),t.classList.remove("pswp--zoom-allowed");return}t.classList.add("pswp--zoom-allowed");const r=s===n.zoomLevels.initial?n.zoomLevels.secondary:n.zoomLevels.initial;lS(t,r<=s),(o.imageClickAction==="zoom"||o.imageClickAction==="zoom-or-close")&&t.classList.add("pswp--click-to-zoom")}}function vxe(e){const t=e.getBoundingClientRect();return{x:t.left,y:t.top,w:t.width}}function yxe(e,t,n){const o=e.getBoundingClientRect(),s=o.width/t,i=o.height/n,r=s>i?s:i,l=(o.width-t*r)/2,a=(o.height-n*r)/2,u={x:o.left+l,y:o.top+a,w:t*r};return u.innerRect={w:o.width,h:o.height,x:l,y:a},u}function kxe(e,t,n){const o=n.dispatch("thumbBounds",{index:e,itemData:t,instance:n});if(o.thumbBounds)return o.thumbBounds;const{element:s}=t;let i,r;if(s&&n.options.thumbSelector!==!1){const l=n.options.thumbSelector||"img";r=s.matches(l)?s:s.querySelector(l)}return r=n.applyFilters("thumbEl",r,t,e),r&&(t.thumbCropped?i=yxe(r,t.width||t.w||0,t.height||t.h||0):i=vxe(r)),n.applyFilters("thumbBounds",i,t,e)}class bxe{constructor(t,n){this.type=t,this.defaultPrevented=!1,n&&Object.assign(this,n)}preventDefault(){this.defaultPrevented=!0}}class Cxe{constructor(){this._listeners={},this._filters={},this.pswp=void 0,this.options=void 0}addFilter(t,n,o=100){var s,i,r;this._filters[t]||(this._filters[t]=[]),(s=this._filters[t])===null||s===void 0||s.push({fn:n,priority:o}),(i=this._filters[t])===null||i===void 0||i.sort((l,a)=>l.priority-a.priority),(r=this.pswp)===null||r===void 0||r.addFilter(t,n,o)}removeFilter(t,n){this._filters[t]&&(this._filters[t]=this._filters[t].filter(o=>o.fn!==n)),this.pswp&&this.pswp.removeFilter(t,n)}applyFilters(t,...n){var o;return(o=this._filters[t])===null||o===void 0||o.forEach(s=>{n[0]=s.fn.apply(this,n)}),n[0]}on(t,n){var o,s;this._listeners[t]||(this._listeners[t]=[]),(o=this._listeners[t])===null||o===void 0||o.push(n),(s=this.pswp)===null||s===void 0||s.on(t,n)}off(t,n){var o;this._listeners[t]&&(this._listeners[t]=this._listeners[t].filter(s=>n!==s)),(o=this.pswp)===null||o===void 0||o.off(t,n)}dispatch(t,n){var o;if(this.pswp)return this.pswp.dispatch(t,n);const s=new bxe(t,n);return(o=this._listeners[t])===null||o===void 0||o.forEach(i=>{i.call(this,s)}),s}}class wxe{constructor(t,n){if(this.element=er("pswp__img pswp__img--placeholder",t?"img":"div",n),t){const o=this.element;o.decoding="async",o.alt="",o.src=t,o.setAttribute("role","presentation")}this.element.setAttribute("aria-hidden","true")}setDisplayedSize(t,n){this.element&&(this.element.tagName==="IMG"?(A8(this.element,250,"auto"),this.element.style.transformOrigin="0 0",this.element.style.transform=Np(0,0,t/250)):A8(this.element,t,n))}destroy(){var t;(t=this.element)!==null&&t!==void 0&&t.parentNode&&this.element.remove(),this.element=null}}class _xe{constructor(t,n,o){this.instance=n,this.data=t,this.index=o,this.element=void 0,this.placeholder=void 0,this.slide=void 0,this.displayedImageWidth=0,this.displayedImageHeight=0,this.width=Number(this.data.w)||Number(this.data.width)||0,this.height=Number(this.data.h)||Number(this.data.height)||0,this.isAttached=!1,this.hasSlide=!1,this.isDecoding=!1,this.state=gr.IDLE,this.data.type?this.type=this.data.type:this.data.src?this.type="image":this.type="html",this.instance.dispatch("contentInit",{content:this})}removePlaceholder(){this.placeholder&&!this.keepPlaceholder()&&setTimeout(()=>{this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0)},1e3)}load(t,n){if(this.slide&&this.usePlaceholder())if(this.placeholder){const o=this.placeholder.element;o&&!o.parentElement&&this.slide.container.prepend(o)}else{const o=this.instance.applyFilters("placeholderSrc",this.data.msrc&&this.slide.isFirstSlide?this.data.msrc:!1,this);this.placeholder=new wxe(o,this.slide.container)}this.element&&!n||this.instance.dispatch("contentLoad",{content:this,isLazy:t}).defaultPrevented||(this.isImageContent()?(this.element=er("pswp__img","img"),this.displayedImageWidth&&this.loadImage(t)):(this.element=er("pswp__content","div"),this.element.innerHTML=this.data.html||""),n&&this.slide&&this.slide.updateContentSize(!0))}loadImage(t){var n,o;if(!this.isImageContent()||!this.element||this.instance.dispatch("contentLoadImage",{content:this,isLazy:t}).defaultPrevented)return;const s=this.element;this.updateSrcsetSizes(),this.data.srcset&&(s.srcset=this.data.srcset),s.src=(n=this.data.src)!==null&&n!==void 0?n:"",s.alt=(o=this.data.alt)!==null&&o!==void 0?o:"",this.state=gr.LOADING,s.complete?this.onLoaded():(s.onload=()=>{this.onLoaded()},s.onerror=()=>{this.onError()})}setSlide(t){this.slide=t,this.hasSlide=!0,this.instance=t.pswp}onLoaded(){this.state=gr.LOADED,this.slide&&this.element&&(this.instance.dispatch("loadComplete",{slide:this.slide,content:this}),this.slide.isActive&&this.slide.heavyAppended&&!this.element.parentNode&&(this.append(),this.slide.updateContentSize(!0)),(this.state===gr.LOADED||this.state===gr.ERROR)&&this.removePlaceholder())}onError(){this.state=gr.ERROR,this.slide&&(this.displayError(),this.instance.dispatch("loadComplete",{slide:this.slide,isError:!0,content:this}),this.instance.dispatch("loadError",{slide:this.slide,content:this}))}isLoading(){return this.instance.applyFilters("isContentLoading",this.state===gr.LOADING,this)}isError(){return this.state===gr.ERROR}isImageContent(){return this.type==="image"}setDisplayedSize(t,n){if(this.element&&(this.placeholder&&this.placeholder.setDisplayedSize(t,n),!this.instance.dispatch("contentResize",{content:this,width:t,height:n}).defaultPrevented&&(A8(this.element,t,n),this.isImageContent()&&!this.isError()))){const o=!this.displayedImageWidth&&t;this.displayedImageWidth=t,this.displayedImageHeight=n,o?this.loadImage(!1):this.updateSrcsetSizes(),this.slide&&this.instance.dispatch("imageSizeChange",{slide:this.slide,width:t,height:n,content:this})}}isZoomable(){return this.instance.applyFilters("isContentZoomable",this.isImageContent()&&this.state!==gr.ERROR,this)}updateSrcsetSizes(){if(!this.isImageContent()||!this.element||!this.data.srcset)return;const t=this.element,n=this.instance.applyFilters("srcsetSizesWidth",this.displayedImageWidth,this);(!t.dataset.largestUsedSize||n>parseInt(t.dataset.largestUsedSize,10))&&(t.sizes=n+"px",t.dataset.largestUsedSize=String(n))}usePlaceholder(){return this.instance.applyFilters("useContentPlaceholder",this.isImageContent(),this)}lazyLoad(){this.instance.dispatch("contentLazyLoad",{content:this}).defaultPrevented||this.load(!0)}keepPlaceholder(){return this.instance.applyFilters("isKeepingPlaceholder",this.isLoading(),this)}destroy(){this.hasSlide=!1,this.slide=void 0,!this.instance.dispatch("contentDestroy",{content:this}).defaultPrevented&&(this.remove(),this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0),this.isImageContent()&&this.element&&(this.element.onload=null,this.element.onerror=null,this.element=void 0))}displayError(){if(this.slide){var t,n;let o=er("pswp__error-msg","div");o.innerText=(t=(n=this.instance.options)===null||n===void 0?void 0:n.errorMsg)!==null&&t!==void 0?t:"",o=this.instance.applyFilters("contentErrorElement",o,this),this.element=er("pswp__content pswp__error-msg-container","div"),this.element.appendChild(o),this.slide.container.innerText="",this.slide.container.appendChild(this.element),this.slide.updateContentSize(!0),this.removePlaceholder()}}append(){if(this.isAttached||!this.element)return;if(this.isAttached=!0,this.state===gr.ERROR){this.displayError();return}if(this.instance.dispatch("contentAppend",{content:this}).defaultPrevented)return;const t="decode"in this.element;this.isImageContent()?t&&this.slide&&(!this.slide.isActive||tS())?(this.isDecoding=!0,this.element.decode().catch(()=>{}).finally(()=>{this.isDecoding=!1,this.appendImage()})):this.appendImage():this.slide&&!this.element.parentNode&&this.slide.container.appendChild(this.element)}activate(){this.instance.dispatch("contentActivate",{content:this}).defaultPrevented||!this.slide||(this.isImageContent()&&this.isDecoding&&!tS()?this.appendImage():this.isError()&&this.load(!1,!0),this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","false"))}deactivate(){this.instance.dispatch("contentDeactivate",{content:this}),this.slide&&this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","true")}remove(){this.isAttached=!1,!this.instance.dispatch("contentRemove",{content:this}).defaultPrevented&&(this.element&&this.element.parentNode&&this.element.remove(),this.placeholder&&this.placeholder.element&&this.placeholder.element.remove())}appendImage(){this.isAttached&&(this.instance.dispatch("contentAppendImage",{content:this}).defaultPrevented||(this.slide&&this.element&&!this.element.parentNode&&this.slide.container.appendChild(this.element),(this.state===gr.LOADED||this.state===gr.ERROR)&&this.removePlaceholder()))}}const xxe=5;function iF(e,t,n){const o=t.createContentFromData(e,n);let s;const{options:i}=t;if(i){s=new oF(i,e,-1);let r;t.pswp?r=t.pswp.viewportSize:r=tF(i,t);const l=nF(i,r,e,n);s.update(o.width,o.height,l)}return o.lazyLoad(),s&&o.setDisplayedSize(Math.ceil(o.width*s.initial),Math.ceil(o.height*s.initial)),o}function Sxe(e,t){const n=t.getItemData(e);if(!t.dispatch("lazyLoadSlide",{index:e,itemData:n}).defaultPrevented)return iF(n,t,e)}class Axe{constructor(t){this.pswp=t,this.limit=Math.max(t.options.preload[0]+t.options.preload[1]+1,xxe),this._cachedItems=[]}updateLazy(t){const{pswp:n}=this;if(n.dispatch("lazyLoad").defaultPrevented)return;const{preload:o}=n.options,s=t===void 0?!0:t>=0;let i;for(i=0;i<=o[1];i++)this.loadSlideByIndex(n.currIndex+(s?i:-i));for(i=1;i<=o[0];i++)this.loadSlideByIndex(n.currIndex+(s?-i:i))}loadSlideByIndex(t){const n=this.pswp.getLoopedIndex(t);let o=this.getContentByIndex(n);o||(o=Sxe(n,this.pswp),o&&this.addToCache(o))}getContentBySlide(t){let n=this.getContentByIndex(t.index);return n||(n=this.pswp.createContentFromData(t.data,t.index),this.addToCache(n)),n.setSlide(t),n}addToCache(t){if(this.removeByIndex(t.index),this._cachedItems.push(t),this._cachedItems.length>this.limit){const n=this._cachedItems.findIndex(o=>!o.isAttached&&!o.hasSlide);n!==-1&&this._cachedItems.splice(n,1)[0].destroy()}}removeByIndex(t){const n=this._cachedItems.findIndex(o=>o.index===t);n!==-1&&this._cachedItems.splice(n,1)}getContentByIndex(t){return this._cachedItems.find(n=>n.index===t)}destroy(){this._cachedItems.forEach(t=>t.destroy()),this._cachedItems=[]}}class Mxe extends Cxe{getNumItems(){var t;let n=0;const o=(t=this.options)===null||t===void 0?void 0:t.dataSource;o&&"length"in o?n=o.length:o&&"gallery"in o&&(o.items||(o.items=this._getGalleryDOMElements(o.gallery)),o.items&&(n=o.items.length));const s=this.dispatch("numItems",{dataSource:o,numItems:n});return this.applyFilters("numItems",s.numItems,o)}createContentFromData(t,n){return new _xe(t,this,n)}getItemData(t){var n;const o=(n=this.options)===null||n===void 0?void 0:n.dataSource;let s={};Array.isArray(o)?s=o[t]:o&&"gallery"in o&&(o.items||(o.items=this._getGalleryDOMElements(o.gallery)),s=o.items[t]);let i=s;i instanceof Element&&(i=this._domElementToItemData(i));const r=this.dispatch("itemData",{itemData:i||{},index:t});return this.applyFilters("itemData",r.itemData,t)}_getGalleryDOMElements(t){var n,o;return(n=this.options)!==null&&n!==void 0&&n.children||(o=this.options)!==null&&o!==void 0&&o.childSelector?F_e(this.options.children,this.options.childSelector,t)||[]:[t]}_domElementToItemData(t){const n={element:t},o=t.tagName==="A"?t:t.querySelector("a");if(o){n.src=o.dataset.pswpSrc||o.href,o.dataset.pswpSrcset&&(n.srcset=o.dataset.pswpSrcset),n.width=o.dataset.pswpWidth?parseInt(o.dataset.pswpWidth,10):0,n.height=o.dataset.pswpHeight?parseInt(o.dataset.pswpHeight,10):0,n.w=n.width,n.h=n.height,o.dataset.pswpType&&(n.type=o.dataset.pswpType);const i=t.querySelector("img");if(i){var s;n.msrc=i.currentSrc||i.src,n.alt=(s=i.getAttribute("alt"))!==null&&s!==void 0?s:""}(o.dataset.pswpCropped||o.dataset.cropped)&&(n.thumbCropped=!0)}return this.applyFilters("domItemData",n,t,o)}lazyLoadData(t,n){return iF(t,this,n)}}const df=.003;class Txe{constructor(t){this.pswp=t,this.isClosed=!0,this.isOpen=!1,this.isClosing=!1,this.isOpening=!1,this._duration=void 0,this._useAnimation=!1,this._croppedZoom=!1,this._animateRootOpacity=!1,this._animateBgOpacity=!1,this._placeholder=void 0,this._opacityElement=void 0,this._cropContainer1=void 0,this._cropContainer2=void 0,this._thumbBounds=void 0,this._prepareOpen=this._prepareOpen.bind(this),t.on("firstZoomPan",this._prepareOpen)}open(){this._prepareOpen(),this._start()}close(){if(this.isClosed||this.isClosing||this.isOpening)return;const t=this.pswp.currSlide;this.isOpen=!1,this.isOpening=!1,this.isClosing=!0,this._duration=this.pswp.options.hideAnimationDuration,t&&t.currZoomLevel*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps(),setTimeout(()=>{this._start()},this._croppedZoom?30:0)}_prepareOpen(){if(this.pswp.off("firstZoomPan",this._prepareOpen),!this.isOpening){const t=this.pswp.currSlide;this.isOpening=!0,this.isClosing=!1,this._duration=this.pswp.options.showAnimationDuration,t&&t.zoomLevels.initial*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps()}}_applyStartProps(){const{pswp:t}=this,n=this.pswp.currSlide,{options:o}=t;if(o.showHideAnimationType==="fade"?(o.showHideOpacity=!0,this._thumbBounds=void 0):o.showHideAnimationType==="none"?(o.showHideOpacity=!1,this._duration=0,this._thumbBounds=void 0):this.isOpening&&t._initialThumbBounds?this._thumbBounds=t._initialThumbBounds:this._thumbBounds=this.pswp.getThumbBounds(),this._placeholder=n?.getPlaceholderElement(),t.animations.stopAll(),this._useAnimation=!!(this._duration&&this._duration>50),this._animateZoom=!!this._thumbBounds&&n?.content.usePlaceholder()&&(!this.isClosing||!t.mainScroll.isShifted()),!this._animateZoom)this._animateRootOpacity=!0,this.isOpening&&n&&(n.zoomAndPanToInitial(),n.applyCurrentZoomPan());else{var s;this._animateRootOpacity=(s=o.showHideOpacity)!==null&&s!==void 0?s:!1}if(this._animateBgOpacity=!this._animateRootOpacity&&this.pswp.options.bgOpacity>df,this._opacityElement=this._animateRootOpacity?t.element:t.bg,!this._useAnimation){this._duration=0,this._animateZoom=!1,this._animateBgOpacity=!1,this._animateRootOpacity=!0,this.isOpening&&(t.element&&(t.element.style.opacity=String(df)),t.applyBgOpacity(1));return}if(this._animateZoom&&this._thumbBounds&&this._thumbBounds.innerRect){var i;this._croppedZoom=!0,this._cropContainer1=this.pswp.container,this._cropContainer2=(i=this.pswp.currSlide)===null||i===void 0?void 0:i.holderElement,t.container&&(t.container.style.overflow="hidden",t.container.style.width=t.viewportSize.x+"px")}else this._croppedZoom=!1;this.isOpening?(this._animateRootOpacity?(t.element&&(t.element.style.opacity=String(df)),t.applyBgOpacity(1)):(this._animateBgOpacity&&t.bg&&(t.bg.style.opacity=String(df)),t.element&&(t.element.style.opacity="1")),this._animateZoom&&(this._setClosedStateZoomPan(),this._placeholder&&(this._placeholder.style.willChange="transform",this._placeholder.style.opacity=String(df)))):this.isClosing&&(t.mainScroll.itemHolders[0]&&(t.mainScroll.itemHolders[0].el.style.display="none"),t.mainScroll.itemHolders[2]&&(t.mainScroll.itemHolders[2].el.style.display="none"),this._croppedZoom&&t.mainScroll.x!==0&&(t.mainScroll.resetPosition(),t.mainScroll.resize()))}_start(){this.isOpening&&this._useAnimation&&this._placeholder&&this._placeholder.tagName==="IMG"?new Promise(t=>{let n=!1,o=!0;$_e(this._placeholder).finally(()=>{n=!0,o||t(!0)}),setTimeout(()=>{o=!1,n&&t(!0)},50),setTimeout(t,250)}).finally(()=>this._initiate()):this._initiate()}_initiate(){var t,n;(t=this.pswp.element)===null||t===void 0||t.style.setProperty("--pswp-transition-duration",this._duration+"ms"),this.pswp.dispatch(this.isOpening?"openingAnimationStart":"closingAnimationStart"),this.pswp.dispatch("initialZoom"+(this.isOpening?"In":"Out")),(n=this.pswp.element)===null||n===void 0||n.classList.toggle("pswp--ui-visible",this.isOpening),this.isOpening?(this._placeholder&&(this._placeholder.style.opacity="1"),this._animateToOpenState()):this.isClosing&&this._animateToClosedState(),this._useAnimation||this._onAnimationComplete()}_onAnimationComplete(){const{pswp:t}=this;if(this.isOpen=this.isOpening,this.isClosed=this.isClosing,this.isOpening=!1,this.isClosing=!1,t.dispatch(this.isOpen?"openingAnimationEnd":"closingAnimationEnd"),t.dispatch("initialZoom"+(this.isOpen?"InEnd":"OutEnd")),this.isClosed)t.destroy();else if(this.isOpen){var n;this._animateZoom&&t.container&&(t.container.style.overflow="visible",t.container.style.width="100%"),(n=t.currSlide)===null||n===void 0||n.applyCurrentZoomPan()}}_animateToOpenState(){const{pswp:t}=this;this._animateZoom&&(this._croppedZoom&&this._cropContainer1&&this._cropContainer2&&(this._animateTo(this._cropContainer1,"transform","translate3d(0,0,0)"),this._animateTo(this._cropContainer2,"transform","none")),t.currSlide&&(t.currSlide.zoomAndPanToInitial(),this._animateTo(t.currSlide.container,"transform",t.currSlide.getCurrentTransform()))),this._animateBgOpacity&&t.bg&&this._animateTo(t.bg,"opacity",String(t.options.bgOpacity)),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","1")}_animateToClosedState(){const{pswp:t}=this;this._animateZoom&&this._setClosedStateZoomPan(!0),this._animateBgOpacity&&t.bgOpacity>.01&&t.bg&&this._animateTo(t.bg,"opacity","0"),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","0")}_setClosedStateZoomPan(t){if(!this._thumbBounds)return;const{pswp:n}=this,{innerRect:o}=this._thumbBounds,{currSlide:s,viewportSize:i}=n;if(this._croppedZoom&&o&&this._cropContainer1&&this._cropContainer2){const r=-i.x+(this._thumbBounds.x-o.x)+o.w,l=-i.y+(this._thumbBounds.y-o.y)+o.h,a=i.x-o.w,u=i.y-o.h;t?(this._animateTo(this._cropContainer1,"transform",Np(r,l)),this._animateTo(this._cropContainer2,"transform",Np(a,u))):(tc(this._cropContainer1,r,l),tc(this._cropContainer2,a,u))}s&&(is(s.pan,o||this._thumbBounds),s.currZoomLevel=this._thumbBounds.w/s.width,t?this._animateTo(s.container,"transform",s.getCurrentTransform()):s.applyCurrentZoomPan())}_animateTo(t,n,o){if(!this._duration){t.style[n]=o;return}const{animations:s}=this.pswp,i={duration:this._duration,easing:this.pswp.options.easing,onComplete:()=>{s.activeAnimations.length||this._onAnimationComplete()},target:t};i[n]=o,s.startTransition(i)}}const Exe={allowPanToNext:!0,spacing:.1,loop:!0,pinchToClose:!0,closeOnVerticalDrag:!0,hideAnimationDuration:333,showAnimationDuration:333,zoomAnimationDuration:333,escKey:!0,arrowKeys:!0,trapFocus:!0,returnFocus:!0,maxWidthToAnimate:4e3,clickToCloseNonZoomable:!0,imageClickAction:"zoom-or-close",bgClickAction:"close",tapAction:"toggle-controls",doubleTapAction:"zoom",indexIndicatorSep:" / ",preloaderDelay:2e3,bgOpacity:.8,index:0,errorMsg:"The image cannot be loaded",preload:[1,2],easing:"cubic-bezier(.4,0,.22,1)"};class Ixe extends Mxe{constructor(t){super(),this.options=this._prepareOptions(t||{}),this.offset={x:0,y:0},this._prevViewportSize={x:0,y:0},this.viewportSize={x:0,y:0},this.bgOpacity=1,this.currIndex=0,this.potentialIndex=0,this.isOpen=!1,this.isDestroying=!1,this.hasMouse=!1,this._initialItemData={},this._initialThumbBounds=void 0,this.topBar=void 0,this.element=void 0,this.template=void 0,this.container=void 0,this.scrollWrap=void 0,this.currSlide=void 0,this.events=new R_e,this.animations=new rxe,this.mainScroll=new X_e(this),this.gestures=new G_e(this),this.opener=new Txe(this),this.keyboard=new Q_e(this),this.contentLoader=new Axe(this)}init(){if(this.isOpen||this.isDestroying)return!1;this.isOpen=!0,this.dispatch("init"),this.dispatch("beforeOpen"),this._createMainStructure();let t="pswp--open";return this.gestures.supportsTouch&&(t+=" pswp--touch"),this.options.mainClass&&(t+=" "+this.options.mainClass),this.element&&(this.element.className+=" "+t),this.currIndex=this.options.index||0,this.potentialIndex=this.currIndex,this.dispatch("firstUpdate"),this.scrollWheel=new lxe(this),(Number.isNaN(this.currIndex)||this.currIndex<0||this.currIndex>=this.getNumItems())&&(this.currIndex=0),this.gestures.supportsTouch||this.mouseDetected(),this.updateSize(),this.offset.y=window.pageYOffset,this._initialItemData=this.getItemData(this.currIndex),this.dispatch("gettingData",{index:this.currIndex,data:this._initialItemData,slide:void 0}),this._initialThumbBounds=this.getThumbBounds(),this.dispatch("initialLayout"),this.on("openingAnimationEnd",()=>{const{itemHolders:n}=this.mainScroll;n[0]&&(n[0].el.style.display="block",this.setContent(n[0],this.currIndex-1)),n[2]&&(n[2].el.style.display="block",this.setContent(n[2],this.currIndex+1)),this.appendHeavy(),this.contentLoader.updateLazy(),this.events.add(window,"resize",this._handlePageResize.bind(this)),this.events.add(window,"scroll",this._updatePageScrollOffset.bind(this)),this.dispatch("bindEvents")}),this.mainScroll.itemHolders[1]&&this.setContent(this.mainScroll.itemHolders[1],this.currIndex),this.dispatch("change"),this.opener.open(),this.dispatch("afterInit"),!0}getLoopedIndex(t){const n=this.getNumItems();return this.options.loop&&(t>n-1&&(t-=n),t<0&&(t+=n)),r0(t,0,n-1)}appendHeavy(){this.mainScroll.itemHolders.forEach(t=>{var n;(n=t.slide)===null||n===void 0||n.appendHeavy()})}goTo(t){this.mainScroll.moveIndexBy(this.getLoopedIndex(t)-this.potentialIndex)}next(){this.goTo(this.potentialIndex+1)}prev(){this.goTo(this.potentialIndex-1)}zoomTo(...t){var n;(n=this.currSlide)===null||n===void 0||n.zoomTo(...t)}toggleZoom(){var t;(t=this.currSlide)===null||t===void 0||t.toggleZoom()}close(){!this.opener.isOpen||this.isDestroying||(this.isDestroying=!0,this.dispatch("close"),this.events.removeAll(),this.opener.close())}destroy(){var t;if(!this.isDestroying){this.options.showHideAnimationType="none",this.close();return}this.dispatch("destroy"),this._listeners={},this.scrollWrap&&(this.scrollWrap.ontouchmove=null,this.scrollWrap.ontouchend=null),(t=this.element)===null||t===void 0||t.remove(),this.mainScroll.itemHolders.forEach(n=>{var o;(o=n.slide)===null||o===void 0||o.destroy()}),this.contentLoader.destroy(),this.events.removeAll()}refreshSlideContent(t){this.contentLoader.removeByIndex(t),this.mainScroll.itemHolders.forEach((n,o)=>{var s,i;let r=((s=(i=this.currSlide)===null||i===void 0?void 0:i.index)!==null&&s!==void 0?s:0)-1+o;if(this.canLoop()&&(r=this.getLoopedIndex(r)),r===t&&(this.setContent(n,t,!0),o===1)){var l;this.currSlide=n.slide,(l=n.slide)===null||l===void 0||l.setIsActive(!0)}}),this.dispatch("change")}setContent(t,n,o){if(this.canLoop()&&(n=this.getLoopedIndex(n)),t.slide){if(t.slide.index===n&&!o)return;t.slide.destroy(),t.slide=void 0}if(!this.canLoop()&&(n<0||n>=this.getNumItems()))return;const s=this.getItemData(n);t.slide=new P_e(s,n,this),n===this.currIndex&&(this.currSlide=t.slide),t.slide.append(t.el)}getViewportCenterPoint(){return{x:this.viewportSize.x/2,y:this.viewportSize.y/2}}updateSize(t){if(this.isDestroying)return;const n=tF(this.options,this);!t&&sp(n,this._prevViewportSize)||(is(this._prevViewportSize,n),this.dispatch("beforeResize"),is(this.viewportSize,this._prevViewportSize),this._updatePageScrollOffset(),this.dispatch("viewportSize"),this.mainScroll.resize(this.opener.isOpen),!this.hasMouse&&window.matchMedia("(any-hover: hover)").matches&&this.mouseDetected(),this.dispatch("resize"))}applyBgOpacity(t){this.bgOpacity=Math.max(t,0),this.bg&&(this.bg.style.opacity=String(this.bgOpacity*this.options.bgOpacity))}mouseDetected(){if(!this.hasMouse){var t;this.hasMouse=!0,(t=this.element)===null||t===void 0||t.classList.add("pswp--has_mouse")}}_handlePageResize(){this.updateSize(),/iPhone|iPad|iPod/i.test(window.navigator.userAgent)&&setTimeout(()=>{this.updateSize()},500)}_updatePageScrollOffset(){this.setScrollOffset(0,window.pageYOffset)}setScrollOffset(t,n){this.offset.x=t,this.offset.y=n,this.dispatch("updateScrollOffset")}_createMainStructure(){this.element=er("pswp","div"),this.element.setAttribute("tabindex","-1"),this.element.setAttribute("role","dialog"),this.template=this.element,this.bg=er("pswp__bg","div",this.element),this.scrollWrap=er("pswp__scroll-wrap","section",this.element),this.container=er("pswp__container","div",this.scrollWrap),this.scrollWrap.setAttribute("aria-roledescription","carousel"),this.container.setAttribute("aria-live","off"),this.container.setAttribute("id","pswp__items"),this.mainScroll.appendHolders(),this.ui=new gxe(this),this.ui.init(),(this.options.appendToEl||document.body).appendChild(this.element)}getThumbBounds(){return kxe(this.currIndex,this.currSlide?this.currSlide.data:this._initialItemData,this)}canLoop(){return this.options.loop&&this.getNumItems()>2}_prepareOptions(t){return window.matchMedia("(prefers-reduced-motion), (update: slow)").matches&&(t.showHideAnimationType="none",t.zoomAnimationDuration=0),{...Exe,...t}}}function Lxe(e){return new Promise(t=>{const n=new Image;n.onload=()=>t(n.naturalWidth>0?{w:n.naturalWidth,h:n.naturalHeight}:null),n.onerror=()=>t(null),n.src=e})}async function $xe(e,t,n){if(n?.currentSrc&&n.naturalWidth>0)return{src:n.currentSrc,w:n.naturalWidth,h:n.naturalHeight,objectUrl:null};let o=t.url,s=null;if(t.fileId)try{const r=await e.getFileBlob(t.fileId);s=URL.createObjectURL(r),o=s}catch{}const i=await Lxe(o);return i?{src:o,...i,objectUrl:s}:(s&&URL.revokeObjectURL(s),null)}function Nxe(e){const t=(s,i)=>{const r=parseFloat(e(s));return Number.isFinite(r)&&r>0?r:i},n=t("--space-6",24),o=t("--space-8",32)+n;return{top:o,bottom:o,left:n,right:n}}function Fxe(e){let t=!1,n=!1,o=null;return(async()=>{const s=await $xe(e.api,e.media,e.thumbImg);if(t){s?.objectUrl&&URL.revokeObjectURL(s.objectUrl);return}if(!s){e.onClose();return}const i=e.thumbImg?.currentSrc===s.src?e.thumbImg:null;o=new Ixe({dataSource:[{src:s.src,w:s.w,h:s.h,thumbCropped:!0,...i?{msrc:i.currentSrc,element:i}:{}}],index:0,showHideAnimationType:i?"zoom":"fade",arrowPrev:!1,arrowNext:!1,counter:!1,close:!1,zoom:!1,wheelToZoom:!0,escKey:!0,trapFocus:!1,bgOpacity:1,padding:Nxe(l=>getComputedStyle(document.documentElement).getPropertyValue(l))}),o.addFilter("thumbEl",l=>l?.isConnected?l:null);const r=e.media.path;o.on("uiRegister",()=>{const l=o?.ui;!l||!r||l.registerElement({name:"caption",className:"media-preview-caption",isButton:!1,appendTo:"root",onInit:a=>{a.textContent=r}})}),o.on("openingAnimationStart",()=>{Ci.value+=1,e.onOpen?.()}),o.on("destroy",()=>{n=!0,Ci.value=Math.max(0,Ci.value-1),s.objectUrl&&URL.revokeObjectURL(s.objectUrl),e.onClose()}),o.init()})(),()=>{t=!0,o&&!n&&o.close()}}const Rxe=["aria-label"],Oxe=["aria-label"],Pxe={class:"media-lightbox-card"},Dxe={class:"media-lightbox-frame"},Bxe={key:0,class:"media-lightbox-name"},Hxe=["aria-label"],zxe='button:not([disabled]), video[controls], [tabindex]:not([tabindex="-1"])',Wxe=et({__name:"MediaLightbox",props:{media:{},originImg:{}},emits:["close"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.media.kind==="image"),r=R(()=>n.media.path??null),l=R(()=>r.value??(n.media.kind==="video"?s("composer.attachmentVideo"):s("composer.attachmentImage"))),a=Z(null),u=Z(null),c=Z(!1);let d=null,f=null;function h(m){if(m.key==="Escape"){m.preventDefault(),o("close");return}if(m.key!=="Tab"||!a.value)return;const v=a.value.querySelectorAll(zxe),k=v[0],w=v[v.length-1];!k||!w||(a.value.contains(document.activeElement)?m.shiftKey&&document.activeElement===k?(m.preventDefault(),w.focus()):!m.shiftKey&&document.activeElement===w&&(m.preventDefault(),k.focus()):(m.preventDefault(),(m.shiftKey?w:k).focus()))}return dn(()=>{if(i.value){f=Fxe({api:_t(),media:n.media,thumbImg:n.originImg??null,onOpen:()=>{c.value=!0},onClose:()=>o("close")});return}Ci.value+=1,d=document.activeElement instanceof HTMLElement?document.activeElement:null,window.addEventListener("keydown",h),u.value?.focus()}),Vn(()=>{if(f){f(),f=null;return}Ci.value=Math.max(0,Ci.value-1),window.removeEventListener("keydown",h),d?.focus()}),(m,v)=>(y(),he(Zr,{to:"body"},[i.value?c.value?(y(),he(p(pn),{key:1,text:p(s)("model.close")},{default:me(()=>[C("button",{type:"button",class:"media-lightbox-close","aria-label":p(s)("model.close"),onClick:v[2]||(v[2]=k=>o("close"))},[j(p(Te),{name:"close",size:"sm"})],8,Hxe)]),_:1},8,["text"])):ee("",!0):(y(),M("div",{key:0,ref_key:"overlayRef",ref:a,class:"media-lightbox",role:"dialog","aria-modal":"true","aria-label":l.value,onMousedown:v[1]||(v[1]=It(k=>o("close"),["self"]))},[j(p(pn),{text:p(s)("model.close")},{default:me(()=>[C("button",{ref_key:"closeRef",ref:u,type:"button",class:"media-lightbox-close","aria-label":p(s)("model.close"),onClick:v[0]||(v[0]=k=>o("close"))},[j(p(Te),{name:"close",size:"sm"})],8,Oxe)]),_:1},8,["text"]),C("div",Pxe,[C("div",Dxe,[j(i0,{url:e.media.url,kind:e.media.kind==="video"?"video":"image","file-id":e.media.fileId,"media-class":"media-lightbox-media",controls:e.media.kind==="video"},null,8,["url","kind","file-id","controls"])]),r.value?(y(),M("div",Bxe,N(r.value),1)):ee("",!0)])],40,Rxe))]))}}),Q5=ft(Wxe,[["__scopeId","data-v-6c0c564d"]]),Uxe=["title","aria-label"],jxe={key:1,class:"media-thumb-media media-thumb-tile","aria-hidden":"true"},Vxe={key:2,class:"media-thumb-badge","aria-hidden":"true"},qxe={key:3,class:"media-thumb-badge is-error","aria-hidden":"true"},Kxe={key:4,class:"media-thumb-badge","aria-hidden":"true"},Zxe=["aria-label"],Gxe=et({__name:"MediaThumb",props:{kind:{},name:{},url:{},fileId:{},uploading:{type:Boolean,default:!1},error:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},removeLabel:{}},emits:["activate","remove"],setup(e,{emit:t}){const n=e,o=t;function s(u){o("activate",u.currentTarget.querySelector("img"))}const{t:i}=Nt(),r=R(()=>n.name?n.name:n.kind==="video"?i("composer.attachmentVideo"):i("composer.attachmentImage")),l=R(()=>n.url?.startsWith("blob:")??!1),a=R(()=>!n.url||n.kind==="video"&&n.fileId!==void 0&&!l.value);return(u,c)=>(y(),M("span",{class:Re(["media-thumb",{"is-error":e.error,uploading:e.uploading}])},[C("button",{type:"button",class:"media-thumb-btn",title:r.value,"aria-label":r.value,onClick:s},[a.value?(y(),M("span",jxe)):(y(),he(i0,{key:0,url:e.url,kind:e.kind,"file-id":l.value?void 0:e.fileId,"media-class":"media-thumb-media",controls:!1,muted:""},null,8,["url","kind","file-id"])),e.uploading?(y(),M("span",Vxe,[j(p(Ao),{size:"sm",label:p(i)("composer.uploading")},null,8,["label"])])):e.error?(y(),M("span",qxe,[j(p(Te),{name:"info",size:"sm"})])):e.kind==="video"?(y(),M("span",Kxe,[j(p(Te),{name:"play",size:"sm"})])):ee("",!0)],8,Uxe),e.removable?(y(),he(p(pn),{key:0,text:e.removeLabel??p(i)("composer.remove")},{default:me(()=>[C("button",{type:"button",class:"media-thumb-rm","aria-label":e.removeLabel??p(i)("composer.remove"),onClick:c[0]||(c[0]=d=>o("remove"))},[j(p(Te),{name:"close",size:"sm"})],8,Zxe)]),_:1},8,["text"])):ee("",!0)],2))}}),rF=ft(Gxe,[["__scopeId","data-v-a7ab7e98"]]),Yxe=["title","data-kind"],Xxe=["aria-label"],Jxe={class:"att-tile"},Qxe={class:"att-name"},eSe={key:1,class:"att-err"},tSe=["aria-label"],nSe=et({__name:"AttachmentChip",props:{kind:{},name:{},url:{},fileId:{},mediaType:{},size:{},uploading:{type:Boolean,default:!1},error:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},removeLabel:{}},emits:["activate","remove"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>{const d=n.name?.match(/\.([A-Za-z0-9]{1,8})$/)?.[1]??n.mediaType?.split("/")[1]?.split("+")[0];return d?d.toUpperCase():void 0}),r=R(()=>{const c=i.value??"";return/^(txt|md|doc|docx|rtf|log)$/i.test(c)?"file-text":"file"}),l=R(()=>n.name?n.name:n.kind==="image"?s("composer.attachmentImage"):n.kind==="video"?s("composer.attachmentVideo"):s("composer.attachmentFile"));function a(c){return c<1024?`${c} B`:c<1024*1024?`${Math.round(c/1024)} KB`:`${(c/(1024*1024)).toFixed(1)} MB`}const u=R(()=>{const c=[l.value];return n.size!==void 0&&c.push(a(n.size)),c.join(" · ")});return(c,d)=>(y(),M("span",{class:Re(["att-chip",{"is-error":e.error,uploading:e.uploading}]),title:u.value,"data-kind":e.kind},[C("button",{type:"button",class:"att-activate","aria-label":u.value,onClick:d[0]||(d[0]=f=>o("activate"))},[C("span",Jxe,[e.kind==="image"&&e.url?(y(),he(i0,{key:0,url:e.url,kind:"image",alt:e.name,"file-id":e.fileId,"media-class":"att-thumb"},null,8,["url","alt","file-id"])):e.kind==="video"?(y(),he(p(Te),{key:1,name:"play",size:"sm"})):e.kind==="image"?(y(),he(p(Te),{key:2,name:"image",size:"sm"})):(y(),he(p(Te),{key:3,name:r.value,size:"sm"},null,8,["name"]))]),C("span",Qxe,N(l.value),1),e.uploading?(y(),he(p(Ao),{key:0,size:"sm",label:p(s)("composer.uploading")},null,8,["label"])):e.error?(y(),M("span",eSe,[j(p(Te),{name:"info",size:"sm"})])):ee("",!0)],8,Xxe),e.removable?(y(),he(p(pn),{key:0,text:e.removeLabel??p(s)("composer.remove")},{default:me(()=>[C("button",{type:"button",class:"att-rm","aria-label":e.removeLabel??p(s)("composer.remove"),onClick:d[1]||(d[1]=f=>o("remove"))},[j(p(Te),{name:"close",size:"sm"})],8,tSe)]),_:1},8,["text"])):ee("",!0)],10,Yxe))}}),lF=ft(nSe,[["__scopeId","data-v-9af3d603"]]),oSe="/assets/kimi_avatar_default-srYjF2HV.riv",sSe={key:0,class:"mascot-fallback",viewBox:"5 0 240.776 240.776","aria-hidden":"true"},iSe="light/dark",rSe="click_avator",lSe="hoverspace",aSe=et({__name:"KimiMascot",setup(e){const t=Z(!1),n=Z(null),o=f2();let s=null,i=null;function r(){s!==null&&Gb(s,iSe,o.value?1:0)}dn(async()=>{if(!window.matchMedia("(prefers-reduced-motion: reduce)").matches)try{const[{Rive:u,RuntimeLoader:c},d,f]=await Promise.all([jo(()=>import("./rive-CeXCFBdn.js").then(w=>w.r),__vite__mapDeps([10,3])),jo(()=>import("./rive-BxcgqsjB.js"),[]).then(w=>w.default),jo(()=>import("./rive_fallback-ByshBW-N.js"),[]).then(w=>w.default)]),h=n.value;if(!h)return;c.setWasmUrl(d),c.setWasmFallbackUrl(f);const m=new u({canvas:h,src:oSe,autoplay:!0,onLoad(){const w=m.stateMachineNames[0];w!==void 0&&m.play(w),requestAnimationFrame(()=>{n.value&&(r(),m.resizeDrawingSurfaceToCanvas(),t.value=!0)})}});s=m;const v=Je(o,r),k=()=>m.resizeDrawingSurfaceToCanvas();window.addEventListener("resize",k),i=()=>{v(),window.removeEventListener("resize",k),m.cleanup(),s=null}}catch{}}),Vn(()=>{i?.(),i=null});function l(u){s!==null&&Gb(s,lSe,u)}function a(){s!==null&&jJ(s,rSe)}return(u,c)=>(y(),M("div",{class:"mascot-host",role:"img","aria-label":"Kimi mascot",onPointerenter:c[0]||(c[0]=d=>l(!0)),onPointerleave:c[1]||(c[1]=d=>l(!1)),onClick:a},[t.value?ee("",!0):(y(),M("svg",sSe,[...c[2]||(c[2]=[iu('<defs data-v-75a5cb70><radialGradient id="mascot-body-gradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(125.388 105.735) scale(121.866)" data-v-75a5cb70><stop stop-color="#117DFB" data-v-75a5cb70></stop><stop stop-color="#449BFF" offset="0.759254" data-v-75a5cb70></stop><stop stop-color="#77B6FF" offset="1" data-v-75a5cb70></stop></radialGradient></defs><g data-v-75a5cb70><path d="M125.388 0C191.877 0 245.776 53.8995 245.776 120.388C245.776 186.877 191.877 240.776 125.388 240.776C58.8996 240.776 5 186.877 5 120.388C5 53.8995 58.8996 0 125.388 0Z" fill="#2389FF" data-v-75a5cb70></path><path d="M125.388 0C191.877 0 245.776 53.8995 245.776 120.388C245.776 186.877 191.877 240.776 125.388 240.776C58.8996 240.776 5 186.877 5 120.388C5 53.8995 58.8996 0 125.388 0Z" fill="url(#mascot-body-gradient)" data-v-75a5cb70></path></g><g transform="translate(-33.4 0)" data-v-75a5cb70><g transform="rotate(7.8 127.94 83.94)" data-v-75a5cb70><path d="M111.089 73.2179C109.935 64.8166 115.756 57.078 124.091 55.9333C132.426 54.7886 140.117 60.6713 141.271 69.0726L144.785 94.6564C145.939 103.058 140.118 110.796 131.783 111.941C123.449 113.086 115.757 107.203 114.603 98.8018L111.089 73.2179Z" fill="#FFFFFF" data-v-75a5cb70></path></g><g transform="translate(0 8.5) rotate(7.8 189.67 75.44)" data-v-75a5cb70><path d="M174.422 65.1492C173.326 57.1679 178.518 49.8626 186.019 48.8324C193.52 47.8021 200.489 53.4371 201.586 61.4184L204.924 85.723C206.02 93.7042 200.828 101.01 193.327 102.04C185.825 103.07 178.856 97.435 177.76 89.4538L174.422 65.1492Z" fill="#FFFFFF" data-v-75a5cb70></path></g></g>',3)])])),C("canvas",{ref_key:"canvasRef",ref:n,class:Re(["mascot-canvas",{ready:t.value}])},null,2)],32))}}),uSe=ft(aSe,[["__scopeId","data-v-75a5cb70"]]),cSe={class:"working-indicator",role:"status"},dSe={class:"wi-mascot","aria-hidden":"true"},fSe={class:"wi-label"},pSe=et({__name:"WorkingIndicator",props:{label:{}},setup(e){return(t,n)=>(y(),M("div",cSe,[C("span",dSe,[j(uSe)]),C("span",fSe,N(e.label),1)]))}}),aF=ft(pSe,[["__scopeId","data-v-8abb44ef"]]),hSe={class:"chat"},mSe={key:0,class:"chat-loading"},gSe={class:"chat-loading-text"},vSe={key:1,class:"chat-empty"},ySe={key:1,class:"top-sentinel-text"},kSe={key:0,class:"u-turn"},bSe=["data-turn-id"],CSe={key:0,class:"u-media"},wSe={key:1,class:"u-atts"},_Se={key:2,class:"skill-act"},xSe={class:"skill-act-head"},SSe={key:3,class:"skill-act"},ASe={class:"skill-act-head"},MSe=["aria-expanded","onClick"],TSe={key:0,class:"u-meta"},ESe=["aria-label","onClick"],ISe={class:"u-edit-hint"},LSe=["aria-label","onClick"],$Se=["aria-label","onClick"],NSe=["data-turn-id"],FSe=["onClick"],RSe={class:"cd-view"},OSe={key:1,class:"cd-label"},PSe=["data-turn-id"],DSe={key:0,class:"goal-prov"},BSe={key:1,class:"msg"},HSe={key:3,class:"a-msg-ft"},zSe={key:0,class:"a-duration"},WSe=["aria-label","onClick"],USe={key:4,class:"compact-divider",role:"separator"},jSe={class:"cd-label",role:"status"},VSe={key:3,class:"turn-failed",role:"alert"},qSe={class:"tf-chip","aria-hidden":"true"},KSe={class:"tf-main"},ZSe={class:"tf-title"},GSe=["title"],YSe=["title"],XSe={key:5,class:"sending-placeholder"},JSe={key:6,class:"q-stack"},QSe={class:"q-head"},eAe={class:"q-title"},tAe={class:"q-hint"},nAe=["onDragover","onDrop"],oAe={class:"u-bub q-bub"},sAe=["title","onDragstart"],iAe=["title","onClick"],rAe={key:0,class:"u-text q-text"},lAe={key:1,class:"q-text q-text-placeholder"},aAe=["aria-expanded","onClick"],uAe={key:0,class:"q-imgs"},cAe={key:0,class:"q-file"},dAe={key:1,class:"q-tag q-tag-next"},fAe={key:2,class:"q-tag q-tag-idx"},pAe=["aria-label","onClick"],hAe={key:0,class:"open-unsupported",role:"status"},mAe=2500,gAe=10,vAe=et({__name:"ChatPane",props:{turns:{},cwd:{},turnFilesInteractive:{type:Boolean,default:!0},approvals:{default:()=>[]},questions:{default:()=>[]},turnActive:{type:Boolean,default:!1},working:{type:Boolean,default:!1},sessionLoading:{type:Boolean},compaction:{default:null},hasMoreMessages:{type:Boolean,default:!1},loadingMore:{type:Boolean,default:!1},loadingMoreError:{type:Boolean,default:!1},isFollowing:{type:Boolean,default:!1},readOnly:{type:Boolean,default:!1},queued:{default:()=>[]},undoHintTurnId:{default:null},interruptedTurnId:{default:null},turnFailed:{type:Boolean,default:!1},turnError:{default:null},turnRetry:{default:null}},emits:["openFile","openMedia","openTurnDiff","copyConversationCopied","openCompaction","openAgent","editMessage","armedUndo","loadOlderMessages","unqueue","editQueued","reorderQueue","resumeTurn"],setup(e,{expose:t,emit:n}){const{t:o}=Nt(),{confirm:s}=hu();bn(()=>{pe!==null&&(clearTimeout(pe),pe=null),V!==null&&(clearTimeout(V),V=null),U!==null&&(clearTimeout(U),U=null),at!==null&&(clearTimeout(at),at=null)});const i=e,r=Z(null);let l=null;function a(){!r.value||typeof IntersectionObserver>"u"||(l?.disconnect(),l=new IntersectionObserver(We=>{We[0]?.isIntersecting&&i.hasMoreMessages&&!i.loadingMore&&!i.loadingMoreError&&!i.sessionLoading&&!i.isFollowing&&v("loadOlderMessages")},{root:null,rootMargin:"200px 0px 0px 0px",threshold:0}),l.observe(r.value))}dn(a),bn(()=>{l?.disconnect(),l=null}),Je(()=>[i.hasMoreMessages,i.loadingMore,i.loadingMoreError],()=>{yt().then(a)});const u=R(()=>{if(!i.turnActive||i.turns.length===0)return null;const We=i.turns.at(-1);return We.role==="assistant"?We.id:null}),c=R(()=>{const We=new Map;for(const tt of i.turns){if(tt.role!=="assistant"||tt.id===u.value)continue;const Ue=LCe(tt);Ue.length>0&&We.set(tt.id,Ue)}return We}),d=R(()=>i.working),f=R(()=>{const We=i.turnRetry;if(We!=null)return o("conversation.workingRetry",{n:We.nextAttempt,max:We.maxAttempts});const tt=i.turns.at(-1),Ue=tt?.role==="assistant"&&(tt.text.trim().length>0||(tt.thinking?.trim().length??0)>0||(tt.tools?.length??0)>0);return o(Ue?"conversation.working":"conversation.requesting")}),h=R(()=>i.turnError?.code==="loop.max_steps_exceeded"?o("conversation.turnFailedMaxSteps"):o("conversation.turnFailed")),m=R(()=>{const We=i.turnError;if(!We)return"";const tt=[];return We.code!==void 0&&We.code.length>0&&tt.push(We.code),We.statusCode!==void 0&&tt.push(`HTTP ${We.statusCode}`),We.requestId!==void 0&&We.requestId.length>0&&tt.push(We.requestId),tt.join(" · ")}),v=n,k=We=>v("openFile",We),w=We=>v("openMedia",We),b=We=>v("openAgent",We),_=We=>v("openTurnDiff",We),g=Z(null),x=Z(null);function S(We){return(We.attachments?.length??0)>0}function T(We){v("editQueued",We)}function A(We,tt){if(g.value=We,!tt.dataTransfer)return;tt.dataTransfer.effectAllowed="move",tt.dataTransfer.setData("text/plain",String(We));const Ue=tt.currentTarget?.closest(".q-turn");Ue&&tt.dataTransfer.setDragImage(Ue,24,24)}function E(We,tt){if(g.value===null)return;tt.preventDefault(),tt.dataTransfer&&(tt.dataTransfer.dropEffect="move");const Ue=tt.currentTarget.getBoundingClientRect(),Lt=tt.clientY<Ue.top+Ue.height/2?"before":"after";x.value={index:We,position:Lt}}function P(We,tt){tt.preventDefault();const Ue=g.value,Lt=x.value?.position??"before";if(g.value=null,x.value=null,Ue===null)return;let gt=Lt==="before"?We:We+1;Ue<gt&&(gt-=1),Ue!==gt&&v("reorderQueue",{from:Ue,to:gt})}function D(){g.value=null,x.value=null}const I=R(()=>{for(let We=i.turns.length-1;We>=0;We--){const tt=i.turns[We];if(tt.goalContinuation)return null;if(tt.role==="user")return tt.id}return null});function $(We){return!i.readOnly&&We.role==="user"&&We.id===I.value&&!i.working&&!We.skillActivation&&!We.pluginCommand}function B(We){const tt=We.compaction,Ue=tt?.trigger==="auto"?o("conversation.compactedAuto"):o("conversation.compactedPlain");return typeof tt?.tokensBefore=="number"&&typeof tt?.tokensAfter=="number"?Ue+o("conversation.compactedTokens",{before:Al(tt.tokensBefore),after:Al(tt.tokensAfter)}):Ue}const H=Z(null);function O(We){return We.durationMs===void 0?"":vc(We.durationMs)}const F=Z(null);let U=null;async function z(We){await s({title:o("conversation.undo"),message:o("conversation.undoConfirm"),variant:"primary"})&&W(We)}function W(We){F.value===null&&(F.value=We.id,v("editMessage",{text:We.text,attachments:We.attachments}),U=setTimeout(()=>{U=null,F.value=null},mAe))}Je(()=>i.turns,We=>{F.value!==null&&(We.some(tt=>tt.id===F.value)||(F.value=null,U!==null&&(clearTimeout(U),U=null)))},{flush:"post"});const K=Z(!1);let V=null;function ie(){if(i.turns.length===0)return;const We=[];for(const Ue of i.turns){if(Ue.role==="compaction"||Ue.role==="cron")continue;const Lt=Ue.role==="user"?"User":"Assistant",gt=ACe(Ue);gt.trim()&&We.push(`**${Lt}** + +${gt}`)}const tt=We.join(` + +--- + +`);Zs(tt).then(Ue=>{Ue&&(K.value=!0,v("copyConversationCopied"),V!==null&&clearTimeout(V),V=setTimeout(()=>{V=null,K.value=!1},2e3))}).catch(()=>{})}function ne(We){const tt=[];for(let Ue=We;Ue>=0;Ue--){const Lt=i.turns[Ue];if(!Lt||Lt.role!=="assistant")break;tt.unshift(Lt)}return tt}function X(We){return ne(We).map(tt=>SCe(tt)).filter(Boolean).join(` + +`)}function le(){for(let We=i.turns.length-1;We>=0;We-=1)if(i.turns[We]?.role==="assistant")return X(We);return""}function Ie(){const We=le();We.trim()&&Zs(We).then(tt=>{tt&&(K.value=!0,v("copyConversationCopied"),V!==null&&clearTimeout(V),V=setTimeout(()=>{V=null,K.value=!1},2e3))}).catch(()=>{})}t({copyConversation:ie,copyFinalSummary:Ie});function de(We){const tt=i.turns[We];if(!tt||tt.role!=="assistant")return!1;const Ue=i.turns[We+1];return!Ue||Ue.role!=="assistant"}let pe=null;function ve(We){const tt=i.turns[We];if(!tt)return;const Ue=X(We);Ue.trim()&&Zs(Ue).then(Lt=>{Lt&&(H.value=tt.id,pe!==null&&clearTimeout(pe),pe=setTimeout(()=>{pe=null,H.value=null},1400))}).catch(()=>{})}function oe(We){const tt=We.text;tt.trim()&&Zs(tt).then(Ue=>{Ue&&(H.value=We.id,pe!==null&&clearTimeout(pe),pe=setTimeout(()=>{pe=null,H.value=null},1400))}).catch(()=>{})}const ye=Go(new Set),G=Go(new Set),Y=new Map,fe=new WeakMap,we=nn("pinScroll",()=>{}),ge=new ResizeObserver(We=>{for(const tt of We){const Ue=tt.target,Lt=fe.get(Ue);Lt!==void 0&&Q(Lt,Ue)}});bn(()=>ge.disconnect());function Q(We,tt){const Ue=parseFloat(getComputedStyle(tt).lineHeight);if(!Number.isFinite(Ue)||Ue<=0)return;const gt=(tt.textContent??"").match(/\n+$/)?.[0].length??0;tt.scrollHeight-Math.max(0,gt-1)*Ue>Ue*gAe+1?ye.add(We):ye.delete(We)}function te(We,tt){if(!(tt instanceof HTMLElement)||Y.get(We)===tt)return;const Ue=Y.get(We);Ue!==void 0&&ge.unobserve(Ue),Y.set(We,tt),fe.set(tt,We),ge.observe(tt),Q(We,tt)}function ce(We){return`queue:${We.id}`}Je([()=>i.turns,()=>i.queued],()=>{const We=new Set(i.turns.map(tt=>tt.id));for(const tt of i.queued)We.add(ce(tt));for(const[tt,Ue]of Y)We.has(tt)||(ge.unobserve(Ue),Y.delete(tt),ye.delete(tt),G.delete(tt))});function ue(We){return We.skillActivation?We.skillActivation.args||null:We.pluginCommand?We.pluginCommand.args||null:We.text||null}function Se(We){return We.skillActivation!==void 0||We.pluginCommand!==void 0}function ze(We){return ye.has(We)&&!G.has(We)}function _e(We,tt){const Ue=G.has(We);Ue&&tt.currentTarget instanceof HTMLElement&&we(tt.currentTarget),Ue?G.delete(We):G.add(We)}function Ee(We){return We.kind==="image"||We.kind==="video"}function it(We){return(We.attachments??[]).filter(Ee)}function Fe(We){return(We.attachments??[]).filter(tt=>!Ee(tt))}function Oe(We){return{kind:We.kind==="video"?"video":"image",url:We.url,path:We.name,fileId:We.fileId}}const Ge=Z(null);let at=null;const Tt=Z(null),Bt=Z(null);function Yt(We,tt){if(We.kind==="image"||We.kind==="video"){Bt.value=tt??null,Tt.value=Oe(We);return}We.fileId!==void 0&&XN(_t(),We.fileId,We.name,We.mediaType).then(Ue=>{Ue==="unsupported"&&(Ge.value=We.name??We.fileId??"",at!==null&&clearTimeout(at),at=setTimeout(()=>{at=null,Ge.value=null},2400))})}function Sn(We,tt){return We.id!==u.value||tt.kind==="thinking"&&tt.durationMs!==void 0?!1:tt.sourceIndex===ta(We).length-1}function on(We,tt){if(We.id!==u.value)return!1;const Ue=tt.items.at(-1);return Ue?.kind==="thinking"&&Ue.durationMs!==void 0?!1:Ue!==void 0&&Ue.sourceIndex===ta(We).length-1}const en={folded:[],visible:[]};function Cn(We){return We.role!=="assistant"?en:VN(We)}function Mn(We){if(We.id!==u.value)return null;const tt=ta(We),Ue=tt.at(-1);if(Ue?.kind==="thinking"&&Ue.durationMs!==void 0)return null;if(Ue?.kind==="tool"&&Ue.tool.status==="running"){const Lt=Ue.tool.id;if(i.approvals?.some(gt=>gt.toolCallId===Lt)||i.questions?.some(gt=>gt.toolCallId===Lt))return null}return tt.length-1}return(We,tt)=>(y(),M(Pe,null,[C("div",hSe,[e.sessionLoading?(y(),M("div",mSe,[j(p(Ao),{size:"sm"}),C("span",gSe,N(p(o)("conversation.loading")),1)])):e.turns.length===0&&(!e.approvals||e.approvals.length===0)?(y(),M("div",vSe)):ee("",!0),e.hasMoreMessages||e.loadingMore?(y(),M("div",{key:2,ref_key:"topSentinelRef",ref:r,class:Re(["top-sentinel",{"top-sentinel-loading":e.loadingMore}])},[e.loadingMore?(y(),M("span",ySe,[j(p(Ao),{size:"sm"}),qe(" "+N(p(o)("conversation.loadingOlder")),1)])):(y(),M("button",{key:0,type:"button",class:"top-sentinel-btn",onClick:tt[0]||(tt[0]=Ue=>v("loadOlderMessages"))},N(p(o)("conversation.loadOlder")),1))],2)):ee("",!0),(y(!0),M(Pe,null,pt(e.turns,(Ue,Lt)=>(y(),M(Pe,{key:Ue.id},[Ue.role==="user"?(y(),M("div",kSe,[C("div",{class:Re(["u-bub turn-anchor",{undoing:F.value===Ue.id}]),"data-turn-id":Ue.id},[it(Ue).length>0?(y(),M("div",CSe,[(y(!0),M(Pe,null,pt(it(Ue),(gt,wn)=>(y(),he(rF,{key:wn,kind:gt.kind,name:gt.name,url:gt.url,"file-id":gt.fileId,onActivate:yn=>Yt(gt,yn)},null,8,["kind","name","url","file-id","onActivate"]))),128))])):ee("",!0),Fe(Ue).length>0?(y(),M("div",wSe,[(y(!0),M(Pe,null,pt(Fe(Ue),(gt,wn)=>(y(),he(lF,{key:wn,kind:gt.kind,name:gt.name,url:gt.url,"file-id":gt.fileId,"media-type":gt.mediaType,size:gt.size,onActivate:yn=>Yt(gt)},null,8,["kind","name","url","file-id","media-type","size","onActivate"]))),128))])):ee("",!0),Ue.skillActivation?(y(),M("div",_Se,[C("div",xSe,[tt[3]||(tt[3]=C("span",{class:"skill-act-arrow"},"▶",-1)),C("span",null,N(p(o)("conversation.activatedSkill",{name:Ue.skillActivation.name})),1)])])):Ue.pluginCommand?(y(),M("div",SSe,[C("div",ASe,[tt[4]||(tt[4]=C("span",{class:"skill-act-arrow"},"▶",-1)),C("span",null,"/"+N(Ue.pluginCommand.pluginId)+":"+N(Ue.pluginCommand.commandName),1)])])):ee("",!0),ue(Ue)!==null?(y(),M("div",{key:4,class:Re(["u-text-wrap",{"is-clamped":ze(Ue.id),"u-text-wrap-args":Se(Ue)}])},[C("div",{class:Re(Se(Ue)?"skill-act-args":"u-text"),ref_for:!0,ref:gt=>te(Ue.id,gt)},N(ue(Ue)),3),ye.has(Ue.id)?(y(),M("button",{key:0,type:"button",class:"u-text-toggle","aria-expanded":!ze(Ue.id),onClick:gt=>_e(Ue.id,gt)},[C("span",null,N(ze(Ue.id)?p(o)("conversation.userMessage.expand"):p(o)("conversation.userMessage.collapse")),1),j(p(Te),{class:"u-text-toggle-car",name:"chevron-down",size:"sm","aria-hidden":"true"})],8,MSe)):ee("",!0)],2)):ee("",!0)],10,bSe),Ue.createdAt||$(Ue)||!e.readOnly&&e.undoHintTurnId===Ue.id?(y(),M("div",TSe,[$(Ue)||!e.readOnly&&e.undoHintTurnId===Ue.id?(y(),M("div",{key:0,class:Re(["u-edit-wrap",{undoing:F.value===Ue.id}])},[e.undoHintTurnId===Ue.id?(y(),he(p(pn),{key:0,text:p(o)("conversation.undoTooltip")},{default:me(()=>[C("button",{type:"button",class:"u-edit u-edit-armed","aria-label":p(o)("conversation.undoTooltip"),onClick:gt=>v("armedUndo",Ue.id)},[j(p(Te),{name:"undo",size:"sm"}),C("span",ISe,[qe(N(p(o)("conversation.escUndoHintPre")),1),j(p(oa),{keys:["Esc"]}),qe(N(p(o)("conversation.escUndoHintPost")),1)])],8,ESe)]),_:2},1032,["text"])):(y(),he(p(pn),{key:1,text:p(o)("conversation.undoTooltip")},{default:me(()=>[C("button",{type:"button",class:"u-edit","aria-label":p(o)("conversation.undoTooltip"),onClick:gt=>z(Ue)},[j(p(Te),{name:"undo",size:"sm"})],8,LSe)]),_:2},1032,["text"]))],2)):ee("",!0),j(p(pn),{text:p(o)("filePreview.copy")},{default:me(()=>[Ue.text.trim().length>0?(y(),M("button",{key:0,type:"button",class:"u-copy","aria-label":p(o)("filePreview.copy"),onClick:It(gt=>oe(Ue),["stop"])},[H.value!==Ue.id?(y(),he(p(Te),{key:0,name:"copy",size:"sm"})):(y(),he(p(Te),{key:1,name:"check",size:"sm"}))],8,$Se)):ee("",!0)]),_:2},1032,["text"]),Ue.createdAt?(y(),he(Rg,{key:1,time:Ue.createdAt},null,8,["time"])):ee("",!0)])):ee("",!0)])):Ue.role==="compaction"?(y(),M("div",{key:1,class:"compact-divider turn-anchor","data-turn-id":Ue.id,role:"separator"},[tt[5]||(tt[5]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1)),Ue.text?(y(),M("button",{key:0,type:"button",class:"cd-label cd-btn",onClick:gt=>v("openCompaction",{turnId:Ue.id})},[C("span",null,N(B(Ue)),1),C("span",RSe,N(p(o)("conversation.viewSummary")),1)],8,FSe)):(y(),M("span",OSe,N(B(Ue)),1)),tt[6]||(tt[6]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1))],8,NSe)):Ue.role==="cron"?(y(),he(S_e,{key:2,text:Ue.text,cron:Ue.cron,"turn-id":Ue.id,"created-at":Ue.createdAt},null,8,["text","cron","turn-id","created-at"])):(y(),M("div",{key:3,class:"a-msg turn-anchor","data-turn-id":Ue.id},[Ue.goalContinuation?(y(),M("div",DSe,[j(p(Te),{name:"target",size:"sm","aria-hidden":"true"}),C("span",null,N(p(o)("conversation.goal.continuation")),1)])):ee("",!0),Cn(Ue).folded.length>0?(y(),he(Xwe,{key:1,items:Cn(Ue).folded,mobile:"","streaming-tail-index":Mn(Ue),live:Ue.id===u.value,parked:Ue.id===u.value&&Mn(Ue)===null,"seed-ms":p(_Ce)(p(ta)(Ue)),"created-ms":p(Qx)(Ue.createdAt),"ended-ms":p(Qx)(Ue.endedAt),"duration-ms":Ue.durationMs,onOpenMedia:w,onOpenFile:k,onOpenAgent:b},null,8,["items","streaming-tail-index","live","parked","seed-ms","created-ms","ended-ms","duration-ms"])):ee("",!0),(y(!0),M(Pe,null,pt(Cn(Ue).visible,(gt,wn)=>(y(),M(Pe,{key:p(KN)(gt,wn)},[gt.kind==="thinking"?(y(),he(J5,{key:0,text:gt.thinking,mobile:"",streaming:Sn(Ue,gt),"started-at":gt.startedAt,"duration-ms":gt.durationMs},null,8,["text","streaming","started-at","duration-ms"])):gt.kind==="text"&>.text?(y(),M("div",BSe,[j(p(Ic),{text:gt.text,streaming:Sn(Ue,gt),"open-file":k},null,8,["text","streaming"])])):gt.kind==="activity-run"?(y(),he(GN,{key:2,items:gt.items,mobile:"",streaming:on(Ue,gt),onOpenMedia:w,onOpenFile:k,onOpenAgent:b},null,8,["items","streaming"])):gt.kind==="tool"?(y(),he(X5,{key:3,tool:gt.tool,mobile:"",onOpenMedia:w,onOpenFile:k,onOpenAgent:b},null,8,["tool"])):gt.kind==="notification"?(y(),he(YN,{key:4,items:gt.items},null,8,["items"])):ee("",!0)],64))),128)),c.value.get(Ue.id)?(y(),he(f_e,{key:2,changes:c.value.get(Ue.id),cwd:i.cwd,interactive:e.turnFilesInteractive,onOpenDiff:_,onOpenFile:k},null,8,["changes","cwd","interactive"])):ee("",!0),Ue.id!==u.value&&de(Lt)&&(X(Lt).trim().length>0||O(Ue))?(y(),M("div",HSe,[O(Ue)?(y(),M("span",zSe,N(O(Ue)),1)):ee("",!0),j(p(pn),{text:p(o)("filePreview.copy")},{default:me(()=>[X(Lt).trim().length>0?(y(),M("button",{key:0,class:"a-cpbtn","aria-label":p(o)("filePreview.copy"),onClick:gt=>ve(Lt)},[H.value!==Ue.id?(y(),he(p(Te),{key:0,name:"copy",size:"sm"})):(y(),he(p(Te),{key:1,name:"check",size:"sm"}))],8,WSe)):ee("",!0)]),_:2},1032,["text"])])):ee("",!0)],8,PSe)),Ue.role==="assistant"&&Ue.id===e.interruptedTurnId?(y(),M("div",USe,[tt[7]||(tt[7]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1)),C("span",jSe,N(p(o)("conversation.turnInterrupted")),1),tt[8]||(tt[8]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1))])):ee("",!0)],64))),128)),e.turnFailed?(y(),M("div",VSe,[C("span",qSe,[j(p(Te),{name:"alert-triangle",size:"sm"})]),C("div",KSe,[C("span",ZSe,N(h.value),1),e.turnError?.message?(y(),M("span",{key:0,class:"tf-sub",title:e.turnError.message},N(e.turnError.message),9,GSe)):ee("",!0),m.value?(y(),M("span",{key:1,class:"tf-meta",title:m.value},N(m.value),9,YSe)):ee("",!0)]),e.readOnly?ee("",!0):(y(),he(p(Rt),{key:0,variant:"secondary",size:"sm",onClick:tt[1]||(tt[1]=Ue=>v("resumeTurn"))},{default:me(()=>[qe(N(p(o)("conversation.turnFailedResume")),1)]),_:1}))])):ee("",!0),e.compaction?(y(),he(v_e,{key:4,label:p(o)("conversation.compacting")},null,8,["label"])):ee("",!0),d.value?(y(),M("div",XSe,[j(aF,{label:f.value},null,8,["label"])])):ee("",!0),e.queued.length>0?(y(),M("div",JSe,[C("div",QSe,[C("span",eAe,[j(p(Te),{name:"mail",size:"sm"}),qe(" "+N(p(o)("composer.queueLabel"))+" · ",1),C("b",null,N(e.queued.length),1)]),C("span",tAe,N(p(o)("composer.queueAutoDrain")),1)]),(y(!0),M(Pe,null,pt(e.queued,(Ue,Lt)=>(y(),M("div",{key:Ue.id,class:Re(["u-turn q-turn",{"q-dragging":g.value===Lt,"drop-before":x.value?.index===Lt&&x.value.position==="before","drop-after":x.value?.index===Lt&&x.value.position==="after"}]),onDragover:gt=>E(Lt,gt),onDrop:gt=>P(Lt,gt)},[C("div",oAe,[C("span",{class:"q-grip",title:p(o)("composer.queueDragTitle"),draggable:"true",onDragstart:gt=>A(Lt,gt),onDragend:D},[j(p(Te),{name:"grip",size:"sm"})],40,sAe),C("div",{class:Re(["q-clamp u-text-wrap",{"is-clamped":ze(ce(Ue))}])},[C("button",{type:"button",class:"q-body",title:p(o)("composer.editQueued"),ref_for:!0,ref:gt=>te(ce(Ue),gt),onClick:gt=>T(Lt)},[Ue.text?(y(),M("span",rAe,N(Ue.text),1)):(y(),M("span",lAe,[j(p(Te),{name:"file",size:"sm"}),qe(" "+N(p(o)("composer.queuedAttachments",{n:Ue.attachments?.length??0})),1)]))],8,iAe),ye.has(ce(Ue))?(y(),M("button",{key:0,type:"button",class:"u-text-toggle","aria-expanded":!ze(ce(Ue)),onClick:gt=>_e(ce(Ue),gt)},[C("span",null,N(ze(ce(Ue))?p(o)("conversation.userMessage.expand"):p(o)("conversation.userMessage.collapse")),1),j(p(Te),{class:"u-text-toggle-car",name:"chevron-down",size:"sm","aria-hidden":"true"})],8,aAe)):ee("",!0)],2),S(Ue)?(y(),M("div",uAe,[(y(!0),M(Pe,null,pt(Ue.attachments,(gt,wn)=>(y(),M(Pe,{key:wn},[gt.kind==="file"?(y(),M("span",cAe,[j(p(Te),{name:"file",size:"sm"}),qe(" "+N(gt.name??gt.fileId),1)])):(y(),he(i0,{key:1,url:gt.url,kind:gt.kind,"file-id":gt.fileId,"media-class":"q-img",controls:!1,muted:""},null,8,["url","kind","file-id"]))],64))),128))])):ee("",!0),Lt===0?(y(),M("span",dAe,N(p(o)("composer.queueNext")),1)):(y(),M("span",fAe,"#"+N(Lt+1),1)),j(p(pn),{text:p(o)("composer.remove")},{default:me(()=>[C("button",{type:"button",class:"q-rm","aria-label":p(o)("composer.remove"),onClick:It(gt=>v("unqueue",Lt),["stop"])},[j(p(Te),{name:"close",size:"sm"})],8,pAe)]),_:2},1032,["text"])])],42,nAe))),128))])):ee("",!0)]),Ge.value!==null?(y(),M("div",hAe,N(p(o)("composer.attachmentOpenUnsupported",{name:Ge.value})),1)):ee("",!0),Tt.value?(y(),he(Q5,{key:1,media:Tt.value,"origin-img":Bt.value,onClose:tt[2]||(tt[2]=Ue=>{Tt.value=null,Bt.value=null})},null,8,["media","origin-img"])):ee("",!0)],64))}}),e6=ft(vAe,[["__scopeId","data-v-7797947d"]]),yAe={class:"ch-id"},kAe=["title"],bAe={key:1,class:"ch-ws"},CAe={key:2,class:"ch-sep"},wAe=["onKeydown"],_Ae={class:"ch-ses"},xAe={key:0,class:"ch-pill ch-sync-pill"},SAe={key:0,class:"ch-ahead"},AAe={key:1,class:"ch-behind"},MAe={key:1,class:"ch-pill ch-diff-pill"},TAe={key:0,class:"ch-add"},EAe={key:1,class:"ch-del"},IAe=et({__name:"ChatHeader",props:{sessionId:{},workspaceName:{},workspaceRoot:{},sessionTitle:{},branch:{},ahead:{},behind:{},changesCount:{},gitDiffStats:{},isGitRepo:{type:Boolean},pr:{},copied:{type:Boolean}},emits:["copyAll","copyFinalSummary","openChanges","openPr","renameSession","forkSession","archiveSession","exportSession"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=R(()=>o.ahead??0),r=R(()=>o.behind??0),l=R(()=>o.gitDiffStats?.totalAdditions??0),a=R(()=>o.gitDiffStats?.totalDeletions??0),u=R(()=>l.value>0||a.value>0),c={open:"header.prStatusOpen",closed:"header.prStatusClosed",merged:"header.prStatusMerged",draft:"header.prStatusDraft"};function d(ne){return ne.trim().toLowerCase().replaceAll("_","-")}function f(ne){const X=d(ne);return c[X]?`pr-${X}`:"pr-unknown"}function h(ne){return n(c[d(ne)]??"header.prStatusUnknown")}const m=Z(!1),v=Z(null),k=Z(null),w=Z({});function b(ne){const X=ne.target;k.value?.el?.contains(X)||v.value?.el?.contains(X)||x()}function _(){x()}async function g(ne){if(ne.stopPropagation(),m.value){x();return}m.value=!0,document.addEventListener("mousedown",b),window.addEventListener("resize",_),await yt();const X=v.value?.el,le=k.value?.el;if(!X||!le)return;const Ie=X.getBoundingClientRect(),de=4,pe=8,ve=le.offsetWidth,oe=le.offsetHeight;let ye=Ie.bottom+de,G=!1;ye+oe>window.innerHeight-pe&&(ye=Math.max(pe,Ie.top-oe-de),G=!0);let Y=Ie.left,fe=!1;Y+ve>window.innerWidth-pe&&(Y=Math.max(pe,Ie.right-ve),fe=!0),w.value={top:`${Math.round(ye)}px`,left:`${Math.round(Y)}px`,transformOrigin:`${G?"bottom":"top"} ${fe?"right":"left"}`,"--menu-pop-shift":G?"2px":"-2px"}}function x(){m.value=!1,document.removeEventListener("mousedown",b),window.removeEventListener("resize",_)}bn(()=>{document.removeEventListener("mousedown",b),window.removeEventListener("resize",_)});function S(){s("copyAll"),x()}function T(){s("copyFinalSummary"),x()}const A=Z(!1);function E(){o.sessionId&&Zs(o.sessionId).then(ne=>{ne&&(A.value=!0,setTimeout(()=>{A.value=!1},1200))})}const P=Z(!1),D=Z(""),I=Z(null),{handleCompositionStart:$,handleCompositionEnd:B,isComposingKeyEvent:H}=Ar();async function O(){if(x(),!!o.sessionId){P.value=!0,D.value=o.sessionTitle??"",await yt();try{I.value?.focus(),I.value?.select()}catch{}}}function F(){const ne=D.value.trim();ne&&o.sessionId&&ne!==(o.sessionTitle??"").trim()&&s("renameSession",o.sessionId,ne),P.value=!1}function U(ne){H(ne)||F()}function z(){P.value=!1}function W(){o.sessionId&&(x(),s("forkSession",o.sessionId))}function K(){o.sessionId&&(x(),s("exportSession",o.sessionId))}function V(){o.sessionId&&(x(),s("archiveSession",o.sessionId))}const ie=!1;return(ne,X)=>(y(),M("header",{class:Re(["chat-header",{"macos-desktop":p(rc)}])},[C("div",yAe,[p(ie)?(y(),M("span",{key:0,class:"ch-dev",title:p(n)("header.devBadge")},"DEV",8,kAe)):ee("",!0),e.workspaceName?(y(),M("span",bAe,N(e.workspaceName),1)):ee("",!0),e.workspaceName&&e.sessionTitle?(y(),M("span",CAe,"/")):ee("",!0),P.value?Bn((y(),M("input",{key:3,ref_key:"renameInputRef",ref:I,"onUpdate:modelValue":X[0]||(X[0]=le=>D.value=le),class:"ch-rename",type:"text",onKeydown:[xl(It(U,["stop"]),["enter"]),xl(It(z,["stop"]),["esc"])],onCompositionstart:X[1]||(X[1]=(...le)=>p($)&&p($)(...le)),onCompositionend:X[2]||(X[2]=(...le)=>p(B)&&p(B)(...le)),onBlur:F,onClick:X[3]||(X[3]=It(()=>{},["stop"]))},null,40,wAe)),[[ai,D.value]]):e.sessionTitle?(y(),he(p(pn),{key:4,text:e.sessionTitle},{default:me(()=>[C("span",_Ae,N(e.sessionTitle),1)]),_:1},8,["text"])):ee("",!0)]),j(p(gn),{ref_key:"kebabRef",ref:v,class:Re(["ch-act-more",{open:m.value}]),label:p(n)("header.options"),tooltip:p(n)("header.options"),"aria-expanded":m.value,"aria-haspopup":"menu",onClick:X[4]||(X[4]=It(le=>g(le),["stop"]))},{default:me(()=>[j(p(Te),{name:"dots-horizontal",size:"sm"})]),_:1},8,["class","label","tooltip","aria-expanded"]),j(as,{name:"menu-pop"},{default:me(()=>[m.value?(y(),he(p(Cl),{key:0,ref_key:"menuRef",ref:k,class:"ch-menu",style:Zt(w.value),onClick:X[5]||(X[5]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{onClick:S},{default:me(()=>[j(p(Te),{name:e.copied?"check":"copy",size:"sm"},null,8,["name"]),qe(" "+N(e.copied?p(n)("header.copied"):p(n)("header.copyAll")),1)]),_:1}),j(p(hn),{onClick:T},{default:me(()=>[j(p(Te),{name:"file-text",size:"sm"}),qe(" "+N(p(n)("header.copyFinalSummary")),1)]),_:1}),e.sessionId?(y(),M(Pe,{key:0},[j(p(hn),{separator:""}),j(p(hn),{onClick:E},{default:me(()=>[j(p(Te),{name:A.value?"check":"copy",size:"sm"},null,8,["name"]),qe(" "+N(A.value?p(n)("header.copied"):p(n)("header.copySessionId")),1)]),_:1}),j(p(hn),{onClick:O},{default:me(()=>[j(p(Te),{name:"pencil",size:"sm"}),qe(" "+N(p(n)("header.renameSession")),1)]),_:1}),j(p(hn),{onClick:W},{default:me(()=>[j(p(Te),{name:"git-fork",size:"sm"}),qe(" "+N(p(n)("header.forkSession")),1)]),_:1}),j(p(hn),{onClick:K},{default:me(()=>[j(p(Te),{name:"download",size:"sm"}),qe(" "+N(p(n)("header.exportSession")),1)]),_:1}),j(p(hn),{onClick:V},{default:me(()=>[j(p(Te),{name:"archive",size:"sm"}),qe(" "+N(p(n)("header.archiveSession")),1)]),_:1})],64)):ee("",!0)]),_:1},8,["style"])):ee("",!0)]),_:1}),X[8]||(X[8]=C("div",{class:"ch-spacer"},null,-1)),e.isGitRepo?(y(),M("button",{key:0,type:"button",class:"ch-git",onClick:X[6]||(X[6]=le=>s("openChanges"))},[j(p(Te),{class:"ch-branch-icon",name:"git-fork",size:"sm"}),C("span",{class:Re(["ch-branch",{"ch-detached":!e.branch}])},N(e.branch||p(n)("header.detached")),3),i.value>0||r.value>0?(y(),M("span",xAe,[i.value>0?(y(),M("span",SAe,"↑"+N(i.value),1)):ee("",!0),r.value>0?(y(),M("span",AAe,"↓"+N(r.value),1)):ee("",!0)])):ee("",!0),u.value?(y(),M("span",MAe,[l.value>0?(y(),M("span",TAe,"+"+N(l.value),1)):ee("",!0),a.value>0?(y(),M("span",EAe,"-"+N(a.value),1)):ee("",!0)])):ee("",!0)])):ee("",!0),e.pr?(y(),M("button",{key:1,type:"button",class:Re(["ch-pill ch-pr",f(e.pr.state)]),onClick:X[7]||(X[7]=le=>e.pr&&s("openPr",e.pr.url))},[j(p(Te),{name:"git-pull-request",size:"sm"}),C("span",null,"PR #"+N(e.pr.number)+" · "+N(h(e.pr.state)),1)],2)):ee("",!0)],2))}}),LAe=ft(IAe,[["__scopeId","data-v-cac58d83"]]),$Ae=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],aS=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function NAe(e){if(e<=255)return $Ae[e];let t=0,n=aS.length-1;for(;t<=n;){const o=t+n>>1,s=aS[o];if(e<s[0]){n=o-1;continue}if(e>s[1]){t=o+1;continue}return s[2]}return"L"}function FAe(e){const t=e.length;if(t===0)return null;const n=new Array(t);let o=!1;for(let u=0;u<t;){const c=e.charCodeAt(u);let d=c,f=1;if(c>=55296&&c<=56319&&u+1<t){const m=e.charCodeAt(u+1);m>=56320&&m<=57343&&(d=(c-55296<<10)+(m-56320)+65536,f=2)}const h=NAe(d);(h==="R"||h==="AL"||h==="AN")&&(o=!0);for(let m=0;m<f;m++)n[u+m]=h;u+=f}if(!o)return null;let s=0;for(let u=0;u<t;u++){const c=n[u];if(c==="L"){s=0;break}if(c==="R"||c==="AL"){s=1;break}}const i=new Int8Array(t);for(let u=0;u<t;u++)i[u]=s;const r=s&1?"R":"L",l=r;let a=l;for(let u=0;u<t;u++)n[u]==="NSM"?n[u]=a:a=n[u];a=l;for(let u=0;u<t;u++){const c=n[u];c==="EN"?n[u]=a==="AL"?"AN":"EN":(c==="R"||c==="L"||c==="AL")&&(a=c)}for(let u=0;u<t;u++)n[u]==="AL"&&(n[u]="R");for(let u=1;u<t-1;u++)n[u]==="ES"&&n[u-1]==="EN"&&n[u+1]==="EN"&&(n[u]="EN"),n[u]==="CS"&&(n[u-1]==="EN"||n[u-1]==="AN")&&n[u+1]===n[u-1]&&(n[u]=n[u-1]);for(let u=0;u<t;u++){if(n[u]!=="EN")continue;let c;for(c=u-1;c>=0&&n[c]==="ET";c--)n[c]="EN";for(c=u+1;c<t&&n[c]==="ET";c++)n[c]="EN"}for(let u=0;u<t;u++){const c=n[u];(c==="WS"||c==="ES"||c==="ET"||c==="CS")&&(n[u]="ON")}a=l;for(let u=0;u<t;u++){const c=n[u];c==="EN"?n[u]=a==="L"?"L":"EN":(c==="R"||c==="L")&&(a=c)}for(let u=0;u<t;u++){if(n[u]!=="ON")continue;let c=u+1;for(;c<t&&n[c]==="ON";)c++;const d=u>0?n[u-1]:l,f=c<t?n[c]:l,h=d!=="L"?"R":"L";if(h===(f!=="L"?"R":"L"))for(let v=u;v<c;v++)n[v]=h;u=c-1}for(let u=0;u<t;u++)n[u]==="ON"&&(n[u]=r);for(let u=0;u<t;u++){const c=n[u];(i[u]&1)===0?c==="R"?i[u]++:(c==="AN"||c==="EN")&&(i[u]+=2):(c==="L"||c==="AN"||c==="EN")&&i[u]++}return i}function RAe(e,t){const n=FAe(e);if(n===null)return null;const o=new Int8Array(t.length);for(let s=0;s<t.length;s++)o[s]=n[t[s]];return o}const OAe=/[ \t\n\r\f]+/g,PAe=/[\t\n\r\f]| {2,}|^ | $/;function DAe(e){const t=e??"normal";return t==="pre-wrap"?{mode:t,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:t,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}}function BAe(e){if(!PAe.test(e))return e;let t=e.replace(OAe," ");return t.charCodeAt(0)===32&&(t=t.slice(1)),t.length>0&&t.charCodeAt(t.length-1)===32&&(t=t.slice(0,-1)),t}function HAe(e){return/[\r\f]/.test(e)?e.replace(/\r\n/g,` +`).replace(/[\r\f]/g,` +`):e}let _4=null,zAe;function WAe(){return _4===null&&(_4=new Intl.Segmenter(zAe,{granularity:"word"})),_4}const UAe=/\p{Script=Arabic}/u,vu=/\p{M}/u,t6=/\p{Nd}/u;function uS(e){return UAe.test(e)}function cS(e){return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=183984&&e<=191471||e>=191472&&e<=192093||e>=194560&&e<=195103||e>=196608&&e<=201551||e>=201552&&e<=205743||e>=205744&&e<=210041||e>=63744&&e<=64255||e>=12288&&e<=12351||e>=12352&&e<=12447||e>=12448&&e<=12543||e>=12592&&e<=12687||e>=44032&&e<=55215||e>=65280&&e<=65519}function Tl(e){for(let t=0;t<e.length;t++){const n=e.charCodeAt(t);if(!(n<12288)){if(n>=55296&&n<=56319&&t+1<e.length){const o=e.charCodeAt(t+1);if(o>=56320&&o<=57343){const s=(n-55296<<10)+(o-56320)+65536;if(cS(s))return!0;t++;continue}}if(cS(n))return!0}}return!1}function jAe(e){const t=l0(e);return t!==null&&(n6.has(t)||Sc.has(t))}const VAe=new Set([" "," ","⁠","\uFEFF"]),qAe=new Set(["-","‐","–","—"]);function KAe(e){const t=l0(e);return t!==null&&VAe.has(t)}function ZAe(e){const t=l0(e);return t!==null&&qAe.has(t)}function uF(e,t){return KAe(e)?!1:t?!(jAe(e)||ZAe(e)):!0}const n6=new Set([",",".","!",":",";","?","、","。","・",")","〕","〉","》","」","』","】","〗","〙","〛","ー","々","〻","ゝ","ゞ","ヽ","ヾ"]),D2=new Set(['"',"(","[","{","¡","¿","“","‘","‚","„","«","‹","⸘","(","〔","〈","《","「","『","【","〖","〘","〚"]),o6=new Set(["'","’"]),Sc=new Set([".",",","!","?",":",";","،","؛","؟","।","॥","၊","။","၌","၍","၏",")","]","}","%",'"',"”","’","»","›","…"]),GAe=new Set([":",".","،","؛"]),YAe=new Set(["၏"]),XAe=new Set(["”","’","»","›","」","』","】","》","〉","〕",")"]);function JAe(e){if(s6(e))return!0;let t=!1;for(const n of e){if(Sc.has(n)||H2(n)){t=!0;continue}if(!(t&&vu.test(n)))return!1}return t}function QAe(e){for(const t of e)if(!n6.has(t)&&!Sc.has(t))return!1;return e.length>0}function eMe(e){if(s6(e))return!0;for(const t of e)if(!D2.has(t)&&!o6.has(t)&&!vu.test(t)&&!H2(t))return!1;return e.length>0}function s6(e){let t=!1;for(const n of e)if(!(n==="\\"||vu.test(n))){if(D2.has(n)||Sc.has(n)||o6.has(n)){t=!0;continue}return!1}return t}function B2(e,t){const n=t-1;if(n<=0)return Math.max(n,0);const o=e.charCodeAt(n);if(o<56320||o>57343)return n;const s=n-1;if(s<0)return n;const i=e.charCodeAt(s);return i>=55296&&i<=56319?s:n}function l0(e){if(e.length===0)return null;const t=B2(e,e.length);return e.slice(t)}function tMe(e){for(const t of e)if(!vu.test(t))return t;return null}function nMe(e){for(let t=e.length;t>0;){const n=B2(e,t),o=e.slice(n,t);if(!vu.test(o))return o;t=n}return null}const oMe=[36,37,43,43,92,92,162,165,176,177,1423,1423,1545,1547,1642,1642,2046,2047,2546,2547,2553,2555,2801,2801,3065,3065,3449,3449,3647,3647,6107,6107,8240,8247,8279,8279,8352,8399,8451,8451,8457,8457,8470,8470,8722,8723,43064,43064,65020,65020,65129,65130,65284,65285,65504,65505,65509,65510,73693,73696,123647,123647,126124,126124,126128,126128];function sMe(e,t){for(let n=0;n<t.length;n+=2)if(e>=t[n]&&e<=t[n+1])return!0;return!1}function H2(e){const t=e.codePointAt(0);return t!==void 0&&sMe(t,oMe)}function iMe(e){const t=nMe(e);return t!==null&&H2(t)}function rMe(e){const t=tMe(e);return t!==null&&t6.test(t)}function lMe(e){const t=Array.from(e);let n=t.length;for(;n>0;){const o=t[n-1];if(vu.test(o)){n--;continue}if(D2.has(o)||o6.has(o)){n--;continue}break}return n<=0||n===t.length?null:{head:t.slice(0,n).join(""),tail:t.slice(n).join("")}}function aMe(e,t,n){return n==="text"&&!t&&e.length===1&&e!=="-"&&e!=="—"?e:null}function dS(e,t,n,o){const s=t[o],i=e[o];if(s==null)return i;const r=n[o];if(i.length===r)return i;const l=s.repeat(r);return e[o]=l,l}function fS(e,t){return e&&t!==null&&GAe.has(t)}function uMe(e){const t=l0(e);return t!==null&&YAe.has(t)}function cMe(e){if(e.length<2||e[0]!==" ")return null;const t=e.slice(1);return/^\p{M}+$/u.test(t)?{space:" ",marks:t}:null}function M8(e){let t=e.length;for(;t>0;){const n=B2(e,t),o=e.slice(n,t);if(XAe.has(o))return!0;if(!Sc.has(o))return!1;t=n}return!1}function dMe(e,t){if(t.preserveOrdinarySpaces||t.preserveHardBreaks){if(e===" ")return"preserved-space";if(e===" ")return"tab";if(t.preserveHardBreaks&&e===` +`)return"hard-break"}return e===" "?"space":e===" "||e===" "||e==="⁠"||e==="\uFEFF"?"glue":e==="​"?"zero-width-break":e==="­"?"soft-hyphen":"text"}const fMe=/[\x20\t\n\xA0\xAD\u200B\u202F\u2060\uFEFF]/;function qr(e){return e.length===1?e[0]:e.join("")}function pMe(e,t){const n=[];for(let o=e.length-1;o>=0;o--)n.push(e[o]);return n.push(t),qr(n)}function hMe(e,t,n,o){if(!fMe.test(e))return[{text:e,isWordLike:t,kind:"text",start:n}];const s=[];let i=null,r=[],l=n,a=!1,u=0;for(const c of e){const d=dMe(c,o),f=d==="text"&&t;if(i!==null&&d===i&&f===a){r.push(c),u+=c.length;continue}i!==null&&s.push({text:qr(r),isWordLike:a,kind:i,start:l}),i=d,r=[c],l=n+u,a=f,u+=c.length}return i!==null&&s.push({text:qr(r),isWordLike:a,kind:i,start:l}),s}function T8(e){return e==="space"||e==="preserved-space"||e==="zero-width-break"||e==="hard-break"}const mMe=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function gMe(e,t){const n=e.texts[t];return n.startsWith("www.")?!0:mMe.test(n)&&t+1<e.len&&e.kinds[t+1]==="text"&&e.texts[t+1]==="//"}function vMe(e){return e.includes("?")&&(e.includes("://")||e.startsWith("www."))}function yMe(e){const t=e.texts.slice(),n=e.isWordLike.slice(),o=e.kinds.slice(),s=e.starts.slice();for(let r=0;r<e.len;r++){if(o[r]!=="text"||!gMe(e,r))continue;const l=[t[r]];let a=r+1;for(;a<e.len&&!T8(o[a]);){l.push(t[a]),n[r]=!0;const u=t[a].includes("?");if(o[a]="text",t[a]="",a++,u)break}t[r]=qr(l)}let i=0;for(let r=0;r<t.length;r++){const l=t[r];l.length!==0&&(i!==r&&(t[i]=l,n[i]=n[r],o[i]=o[r],s[i]=s[r]),i++)}return t.length=i,n.length=i,o.length=i,s.length=i,{len:i,texts:t,isWordLike:n,kinds:o,starts:s}}function kMe(e){const t=[],n=[],o=[],s=[];for(let i=0;i<e.len;i++){const r=e.texts[i];if(t.push(r),n.push(e.isWordLike[i]),o.push(e.kinds[i]),s.push(e.starts[i]),!vMe(r))continue;const l=i+1;if(l>=e.len||T8(e.kinds[l]))continue;const a=[],u=e.starts[l];let c=l;for(;c<e.len&&!T8(e.kinds[c]);)a.push(e.texts[c]),c++;a.length>0&&(t.push(qr(a)),n.push(!0),o.push("text"),s.push(u),i=c-1)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}const bMe=new Set([":","-","/","×",",",".","+","–","—"]),CMe=/[\p{P}\p{S}\p{Co}]/u,wMe=/\p{Emoji_Presentation}/u,_Me=new Set(["?","֊","-","‐","‒","–","—","…","‼","‽","⁉"]);function xMe(e){return e>=33&&e<=47&&e!==45||e>=58&&e<=64&&e!==63||e>=91&&e<=96||e>=123&&e<=126}function cF(e){const t=e.charCodeAt(0);return t<128?xMe(t):!_Me.has(e)&&!wMe.test(e)&&CMe.test(e)}function pS(e){let t=!1;for(const n of e)if(!vu.test(n)){if(!cF(n))return!1;t=!0}return t}function SMe(e){for(let t=e.length;t>0;){const n=B2(e,t),o=e.slice(n,t);if(vu.test(o)){t=n;continue}return cF(o)||H2(o)}return!1}function AMe(e,t,n,o){const s=!t&&pS(e),i=!o&&pS(n),r=iMe(e),l=(t||r)&&SMe(e);return!s&&!i&&!l||Tl(e)||Tl(n)?!1:(t||s||r)&&(o||i)}function dF(e){for(const t of e)if(t6.test(t))return!0;return!1}function Og(e){if(e.length===0)return!1;for(const t of e)if(!(t6.test(t)||bMe.has(t)))return!1;return!0}function MMe(e){const t=[],n=[],o=[],s=[];for(let i=0;i<e.len;i++){const r=e.texts[i],l=e.kinds[i];if(l==="text"&&Og(r)&&dF(r)){const a=[r];let u=i+1;for(;u<e.len&&e.kinds[u]==="text"&&Og(e.texts[u]);)a.push(e.texts[u]),u++;t.push(qr(a)),n.push(!0),o.push("text"),s.push(e.starts[i]),i=u-1;continue}t.push(r),n.push(e.isWordLike[i]),o.push(l),s.push(e.starts[i])}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}function TMe(e){const t=[],n=[],o=[],s=[];let i=0;for(;i<e.len;){const r=e.texts[i],l=e.kinds[i],a=e.isWordLike[i];if(l==="text"){const u=[r];let c=i+1,d=a;for(;c<e.len&&e.kinds[c]==="text"&&AMe(e.texts[c-1],e.isWordLike[c-1],e.texts[c],e.isWordLike[c]);){const f=e.texts[c];u.push(f),d=d||e.isWordLike[c],c++}if(c>i+1){t.push(qr(u)),n.push(d),o.push("text"),s.push(e.starts[i]),i=c;continue}}t.push(r),n.push(a),o.push(l),s.push(e.starts[i]),i++}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}function EMe(e){const t=[],n=[],o=[],s=[];for(let i=0;i<e.len;i++){const r=e.texts[i];if(e.kinds[i]==="text"&&r.includes("-")){const l=r.split("-");let a=l.length>1;for(let u=0;u<l.length;u++){const c=l[u];if(!a)break;(c.length===0||!dF(c)||!Og(c))&&(a=!1)}if(a){let u=0;for(let c=0;c<l.length;c++){const d=l[c],f=c<l.length-1?`${d}-`:d;t.push(f),n.push(!0),o.push("text"),s.push(e.starts[i]+u),u+=f.length}continue}}t.push(r),n.push(e.isWordLike[i]),o.push(e.kinds[i]),s.push(e.starts[i])}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}function IMe(e){const t=[],n=[],o=[],s=[];let i=0;for(;i<e.len;){const r=[e.texts[i]];let l=e.isWordLike[i],a=e.kinds[i],u=e.starts[i];if(a==="glue"){const c=[r[0]],d=u;for(i++;i<e.len&&e.kinds[i]==="glue";)c.push(e.texts[i]),i++;const f=qr(c);if(i<e.len&&e.kinds[i]==="text")r[0]=f,r.push(e.texts[i]),l=e.isWordLike[i],a="text",u=d,i++;else{t.push(f),n.push(!1),o.push("glue"),s.push(d);continue}}else i++;if(a==="text")for(;i<e.len&&e.kinds[i]==="glue";){const c=[];for(;i<e.len&&e.kinds[i]==="glue";)c.push(e.texts[i]),i++;const d=qr(c);if(i<e.len&&e.kinds[i]==="text"){r.push(d,e.texts[i]),l=l||e.isWordLike[i],i++;continue}r.push(d)}t.push(qr(r)),n.push(l),o.push(a),s.push(u)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}function LMe(e){const t=e.texts.slice(),n=e.isWordLike.slice(),o=e.kinds.slice(),s=e.starts.slice();for(let i=0;i<t.length-1;i++){if(o[i]!=="text"||o[i+1]!=="text"||!Tl(t[i])||!Tl(t[i+1]))continue;const r=lMe(t[i]);r!==null&&(t[i]=r.head,t[i+1]=r.tail+t[i+1],s[i+1]=s[i]+r.head.length)}return{len:t.length,texts:t,isWordLike:n,kinds:o,starts:s}}function $Me(e,t,n){const o=WAe();let s=0;const i=[],r=[],l=[],a=[],u=[],c=[],d=[],f=[],h=[],m=[],v=[],k=[];for(const S of o.segment(e))for(const T of hMe(S.segment,S.isWordLike??!1,S.index,n)){let O=function(){c[H]!==null&&(r[H]=[dS(i,c,d,H)],c[H]=null),r[H].push(T.text),l[H]=l[H]||T.isWordLike,f[H]=f[H]||P,h[H]=h[H]||D,m[H]=$,v[H]=B,k[H]=fS(h[H],I)};const A=T.kind==="text",E=aMe(T.text,T.isWordLike,T.kind),P=Tl(T.text),D=uS(T.text),I=l0(T.text),$=M8(T.text),B=uMe(T.text),H=s-1;t.carryCJKAfterClosingQuote&&A&&s>0&&a[H]==="text"&&P&&f[H]&&m[H]||A&&s>0&&a[H]==="text"&&QAe(T.text)&&f[H]||A&&s>0&&a[H]==="text"&&v[H]?O():A&&s>0&&a[H]==="text"&&T.isWordLike&&D&&k[H]?(O(),l[H]=!0):E!==null&&s>0&&a[H]==="text"&&c[H]===E?d[H]=(d[H]??1)+1:A&&!T.isWordLike&&s>0&&a[H]==="text"&&!f[H]&&(JAe(T.text)||T.text==="-"&&l[H])?O():(i[s]=T.text,r[s]=[T.text],l[s]=T.isWordLike,a[s]=T.kind,u[s]=T.start,c[s]=E,d[s]=E===null?0:1,f[s]=P,h[s]=D,m[s]=$,v[s]=B,k[s]=fS(D,I),s++)}for(let S=0;S<s;S++){if(c[S]!==null){i[S]=dS(i,c,d,S);continue}i[S]=qr(r[S])}for(let S=1;S<s;S++)a[S]==="text"&&!l[S]&&s6(i[S])&&a[S-1]==="text"&&!f[S-1]&&(i[S-1]+=i[S],l[S-1]=l[S-1]||l[S],i[S]="");const w=Array.from({length:s},()=>null);let b=-1;for(let S=s-1;S>=0;S--){const T=i[S];if(T.length!==0){if(a[S]==="text"&&!l[S]&&b>=0&&a[b]==="text"&&(eMe(T)||T==="-"&&rMe(i[b]))){const A=w[b]??[];A.push(T),w[b]=A,u[b]=u[S],i[S]="";continue}b=S}}for(let S=0;S<s;S++){const T=w[S];T!=null&&(i[S]=pMe(T,i[S]))}let _=0;for(let S=0;S<s;S++){const T=i[S];T.length!==0&&(_!==S&&(i[_]=T,l[_]=l[S],a[_]=a[S],u[_]=u[S]),_++)}i.length=_,l.length=_,a.length=_,u.length=_;const g=IMe({len:_,texts:i,isWordLike:l,kinds:a,starts:u}),x=LMe(TMe(EMe(MMe(kMe(yMe(g))))));for(let S=0;S<x.len-1;S++){const T=cMe(x.texts[S]);T!==null&&(x.kinds[S]!=="space"&&x.kinds[S]!=="preserved-space"||x.kinds[S+1]!=="text"||!uS(x.texts[S+1])||(x.texts[S]=T.space,x.isWordLike[S]=!1,x.kinds[S]=x.kinds[S]==="preserved-space"?"preserved-space":"space",x.texts[S+1]=T.marks+x.texts[S+1],x.starts[S+1]=x.starts[S]+T.space.length))}return x}function NMe(e,t){if(e.len===0)return[];if(!t.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}];const n=[];let o=0;for(let s=0;s<e.len;s++)e.kinds[s]==="hard-break"&&(n.push({startSegmentIndex:o,endSegmentIndex:s,consumedEndSegmentIndex:s+1}),o=s+1);return o<e.len&&n.push({startSegmentIndex:o,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}),n}function FMe(e,t,n){if(t.len<=1)return t;const o=[],s=[],i=[],r=[];let l=-1,a=!1;function u(f){o.push(t.texts[f]),s.push(t.isWordLike[f]),i.push("text"),r.push(t.starts[f])}function c(f,h){let m=!1;for(let w=f;w<h;w++)m=m||t.isWordLike[w];const v=t.starts[f],k=h<t.len?t.starts[h]:e.length;o.push(e.slice(v,k)),s.push(m),i.push("text"),r.push(v)}function d(f){if(!(l<0)){if(a)l+1===f?u(l):c(l,f);else for(let h=l;h<f;h++)u(h);l=-1,a=!1}}for(let f=0;f<t.len;f++){const h=t.texts[f],m=t.kinds[f];if(m==="text"){l>=0&&!uF(t.texts[f-1],n)&&d(f),l<0&&(l=f),a=a||Tl(h);continue}d(f),o.push(h),s.push(t.isWordLike[f]),i.push(m),r.push(t.starts[f])}return d(t.len),{len:o.length,texts:o,isWordLike:s,kinds:i,starts:r}}function RMe(e,t,n="normal",o="normal"){const s=DAe(n),i=s.mode==="pre-wrap"?HAe(e):BAe(e);if(i.length===0)return{normalized:i,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};const r=$Me(i,t,s),l=o==="keep-all"?FMe(i,r,t.breakKeepAllAfterPunctuation):r;return{normalized:i,chunks:NMe(l,s),...l}}let ud=null;const hS=new Map;let cd=null;const OMe=96,PMe=/\p{Emoji_Presentation}/u,DMe=/[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}\uFE0F\u20E3]/u;let x4=null;const mS=new Map;function i6(){if(ud!==null)return ud;if(typeof OffscreenCanvas<"u")return ud=new OffscreenCanvas(1,1).getContext("2d"),ud;if(typeof document<"u")return ud=document.createElement("canvas").getContext("2d"),ud;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function BMe(e){let t=hS.get(e);return t||(t=new Map,hS.set(e,t)),t}function za(e,t){let n=t.get(e);return n===void 0&&(n={width:i6().measureText(e).width,containsCJK:Tl(e)},t.set(e,n)),n}function z2(){if(cd!==null)return cd;if(typeof navigator>"u")return cd={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,breakKeepAllAfterPunctuation:!0,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},cd;const e=navigator.userAgent,n=navigator.vendor==="Apple Computer, Inc."&&e.includes("Safari/")&&!e.includes("Chrome/")&&!e.includes("Chromium/")&&!e.includes("CriOS/")&&!e.includes("FxiOS/")&&!e.includes("EdgiOS/"),o=e.includes("Chrome/")||e.includes("Chromium/")||e.includes("CriOS/")||e.includes("Edg/");return cd={lineFitEpsilon:n?1/64:.005,carryCJKAfterClosingQuote:o,breakKeepAllAfterPunctuation:!n,preferPrefixWidthsForBreakableRuns:n,preferEarlySoftHyphenBreak:n},cd}function HMe(e){const t=e.match(/(\d+(?:\.\d+)?)\s*px/);return t?parseFloat(t[1]):16}function fF(){return x4===null&&(x4=new Intl.Segmenter(void 0,{granularity:"grapheme"})),x4}function zMe(e){return PMe.test(e)||e.includes("️")}function WMe(e){return DMe.test(e)}function UMe(e,t){let n=mS.get(e);if(n!==void 0)return n;const o=i6();o.font=e;const s=o.measureText("😀").width;if(n=0,s>t+.5&&typeof document<"u"&&document.body!==null){const i=document.createElement("span");i.style.font=e,i.style.display="inline-block",i.style.visibility="hidden",i.style.position="absolute",i.textContent="😀",document.body.appendChild(i);const r=i.getBoundingClientRect().width;document.body.removeChild(i),s-r>.5&&(n=s-r)}return mS.set(e,n),n}function jMe(e){let t=0;const n=fF();for(const o of n.segment(e))zMe(o.segment)&&t++;return t}function VMe(e,t){return t.emojiCount===void 0&&(t.emojiCount=jMe(e)),t.emojiCount}function nc(e,t,n){return n===0?t.width:t.width-VMe(e,t)*n}function qMe(e,t,n,o,s){if(t.breakableFitAdvances!==void 0&&t.breakableFitMode===s)return t.breakableFitAdvances;t.breakableFitMode=s;const i=fF(),r=[];for(const c of i.segment(e))r.push(c.segment);if(r.length<=1)return t.breakableFitAdvances=null,t.breakableFitAdvances;if(s==="sum-graphemes"){const c=[];for(const d of r){const f=za(d,n);c.push(nc(d,f,o))}return t.breakableFitAdvances=c,t.breakableFitAdvances}if(s==="pair-context"||r.length>OMe){const c=[];let d=null,f=0;for(const h of r){const m=za(h,n),v=nc(h,m,o);if(d===null)c.push(v);else{const k=d+h,w=za(k,n);c.push(nc(k,w,o)-f)}d=h,f=v}return t.breakableFitAdvances=c,t.breakableFitAdvances}const l=[];let a="",u=0;for(const c of r){a+=c;const d=za(a,n),f=nc(a,d,o);l.push(f-u),u=f}return t.breakableFitAdvances=l,t.breakableFitAdvances}function KMe(e,t){const n=i6();n.font=e;const o=BMe(e),s=HMe(e),i=t?UMe(e,s):0;return{cache:o,fontSize:s,emojiCorrection:i}}function ZMe(e){return e==="space"||e==="zero-width-break"||e==="soft-hyphen"}function pF(e){return e==="space"||e==="preserved-space"||e==="tab"||e==="zero-width-break"||e==="soft-hyphen"}function hF(e,t,n=e.widths.length){for(;t<n;){const o=e.kinds[t];if(!ZMe(o))break;t++}return t}function GMe(e,t){if(t<=0)return 0;const n=e%t;return Math.abs(n)<=1e-6?t:t-n}function YMe(e,t,n){return e.letterSpacing!==0&&t&&e.spacingGraphemeCounts[n]>0?e.letterSpacing:0}function r6(e,t){return t===0?0:e+t}function XMe(e,t){return e.letterSpacing!==0&&e.spacingGraphemeCounts[t]>0?e.letterSpacing:0}function JMe(e,t,n,o,s){const i=t==="tab"?s+XMe(e,n):e.lineEndFitAdvances[n];return r6(o,i)}function gS(e,t,n,o){const s=t==="tab"?0:e.lineEndFitAdvances[n];return r6(o,s)}function vS(e,t,n,o,s){const i=t==="tab"?s:e.lineEndPaintAdvances[n];return r6(o,i)}function QMe(e,t,n){return e.letterSpacing!==0&&t?n+e.letterSpacing:n}function eTe(e,t){return e.letterSpacing===0?t:t+e.letterSpacing}function Pg(e,t,n){let o=t;for(;o<e.length&&e[o]<n;)o++;return o}function tTe(e,t,n,o,s){if(e.letterSpacing===0)return 0;if(s>0)return e.spacingGraphemeCounts[o]>0?e.letterSpacing:0;for(let i=o-1;i>=t;i--){const r=e.kinds[i];if(!(r==="space"||r==="zero-width-break"||r==="hard-break")){if(r==="soft-hyphen"){if(i===o-1)return 0;continue}return i===t&&n>0||e.spacingGraphemeCounts[i]>0?e.letterSpacing:0}}return 0}function nTe(e,t,n,o,s,i){return t+tTe(e,n,o,s,i)}function oTe(e,t,n){const{widths:o,kinds:s,breakableFitAdvances:i,breakablePreferredBreaks:r}=e;if(o.length===0)return 0;const a=z2().lineFitEpsilon,u=t+a;let c=0,d=0,f=!1,h=0,m=0,v=0,k=0,w=-1,b=0;function _(){w=-1,b=0}function g(P=v,D=k,I=d){c++,n?.(I,h,m,P,D),d=0,f=!1,_()}function x(P,D){f=!0,h=P,m=0,v=P+1,k=0,d=D}function S(P,D,I){f=!0,h=P,m=D,v=P,k=D+1,d=I}function T(P,D){if(!f){x(P,D);return}d+=D,v=P+1,k=0}function A(P,D){const I=i[P],$=r[P]??null;let B=$===null?-1:Pg($,0,D+1),H=-1,O=0,F=D;for(;F<I.length;){const U=I[F];if(!f)S(P,F,U);else if(d+U>u){if($!==null&&H>D){g(P,H,O),F=H,B=Pg($,B,F+1),H=-1,O=0;continue}g(),S(P,F,U)}else d+=U,v=P,k=F+1;const z=F+1;$!==null&&$[B]===z&&(H=z,O=d,B++),F++}f&&v===P&&k===I.length&&(v=P+1,k=0)}let E=0;for(;E<o.length&&!(!f&&(E=hF(e,E),E>=o.length));){const P=o[E],D=s[E],I=pF(D);if(!f){P>u&&i[E]!==null?A(E,0):x(E,P),I&&(w=E+1,b=d-P),E++;continue}if(d+P>u){if(I){T(E,P),g(E+1,0,d-P),E++;continue}if(w>=0){if(v>w||v===w&&k>0){g();continue}g(w,0,b);continue}if(P>u&&i[E]!==null){g(),A(E,0),E++;continue}g();continue}T(E,P),I&&(w=E+1,b=d-P),E++}return f&&g(),c}function sTe(e,t,n){if(e.simpleLineWalkFastPath)return oTe(e,t,n);const{widths:o,kinds:s,breakableFitAdvances:i,breakablePreferredBreaks:r,discretionaryHyphenWidth:l,chunks:a}=e;if(o.length===0||a.length===0)return 0;const u=z2(),c=u.lineFitEpsilon,d=t+c;let f=0,h=0,m=!1,v=0,k=0,w=0,b=0,_=-1,g=0,x=0,S=null;function T(){_=-1,g=0,x=0,S=null}function A(){return S==="soft-hyphen"&&_===w&&b===0?x:h}function E(O=w,F=b,U){f++,n!==void 0&&n(nTe(e,U??A(),v,k,O,F),v,k,O,F),h=0,m=!1,T()}function P(O,F){m=!0,v=O,k=0,w=O+1,b=0,h=F}function D(O,F,U){m=!0,v=O,k=F,w=O,b=F+1,h=U}function I(O,F){if(!m){P(O,F);return}h+=F,w=O+1,b=0}function $(O,F,U,z,W,K){if(!F)return;const V=gS(e,O,U,W),ie=vS(e,O,U,W,z);_=U+1,g=h-K+V,x=h-K+ie,S=O}function B(O,F){const U=i[O],z=r[O]??null;let W=z===null?-1:Pg(z,0,F+1),K=-1,V=0,ie=F;for(;ie<U.length;){const ne=U[ie];if(!m)D(O,ie,ne);else{const le=QMe(e,!0,ne),Ie=h+le;if(eTe(e,Ie)>d){if(z!==null&&K>F){E(O,K,V),ie=K,W=Pg(z,W,ie+1),K=-1,V=0;continue}E(),D(O,ie,ne)}else h=Ie,w=O,b=ie+1}const X=ie+1;z!==null&&z[W]===X&&(K=X,V=h,W++),ie++}m&&w===O&&b===U.length&&(w=O+1,b=0)}function H(O){f++,n?.(0,O.startSegmentIndex,0,O.consumedEndSegmentIndex,0),T()}for(let O=0;O<a.length;O++){const F=a[O];if(F.startSegmentIndex===F.endSegmentIndex){H(F);continue}m=!1,h=0,v=F.startSegmentIndex,k=0,w=F.startSegmentIndex,b=0,T();let U=F.startSegmentIndex;for(;U<F.endSegmentIndex&&!(!m&&(U=hF(e,U,F.endSegmentIndex),U>=F.endSegmentIndex));){const z=s[U],W=pF(z),K=YMe(e,m,U),V=z==="tab"?GMe(h+K,e.tabStopAdvance):o[U],ie=K+V,ne=JMe(e,z,U,K,V);if(z==="soft-hyphen"){m&&(w=U+1,b=0,_=U+1,g=h+l,x=h+l,S=z),U++;continue}if(!m){ne>d&&i[U]!==null?B(U,0):P(U,V),$(z,W,U,V,K,ie),U++;continue}if(h+ne>d){const le=h+gS(e,z,U,K),Ie=h+vS(e,z,U,K,V);if(S==="soft-hyphen"&&u.preferEarlySoftHyphenBreak&&g<=d){E(_,0,x);continue}if(W&&le<=d){I(U,ie),E(U+1,0,Ie),U++;continue}if(_>=0&&g<=d){if(w>_||w===_&&b>0){E();continue}const de=_;E(de,0,x),U=de;continue}if(ne>d&&i[U]!==null){E(),B(U,0),U++;continue}E();continue}I(U,ie),$(z,W,U,V,K,ie),U++}if(m){const z=_===F.consumedEndSegmentIndex?x:h;E(F.consumedEndSegmentIndex,0,z)}}return f}let S4=null;function l6(){return S4===null&&(S4=new Intl.Segmenter(void 0,{granularity:"grapheme"})),S4}function iTe(e){return{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],breakablePreferredBreaks:[],letterSpacing:0,spacingGraphemeCounts:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[],segments:[]}}function rTe(e,t){const n=[];let o=[],s=0,i=!1,r=!1,l=!1;function a(){o.length!==0&&(n.push({text:o.length===1?o[0]:o.join(""),start:s}),o=[],i=!1,r=!1,l=!1)}function u(d,f,h){o=[d],s=f,i=h,r=M8(d),l=D2.has(d)}function c(d,f){o.push(d),i=i||f;const h=M8(d);d.length===1&&Sc.has(d)?r=r||h:r=h,l=!1}for(const d of l6().segment(e)){const f=d.segment,h=Tl(f);if(o.length===0){u(f,d.index,h);continue}if(l||n6.has(f)||Sc.has(f)||t.carryCJKAfterClosingQuote&&h&&r){c(f,h);continue}if(!i&&!h){c(f,h);continue}a(),u(f,d.index,h)}return a(),n}function lTe(e,t,n){if(t.length<=1)return t;const o=[];let s=-1,i=!1;function r(a,u){const c=t[a].start,d=u<t.length?t[u].start:e.length;o.push({text:e.slice(c,d),start:c})}function l(a){if(!(s<0)){if(i)s+1===a?o.push(t[s]):r(s,a);else for(let u=s;u<a;u++)o.push(t[u]);s=-1,i=!1}}for(let a=0;a<t.length;a++){const u=t[a];s>=0&&!uF(t[a-1].text,n)&&l(a),s<0&&(s=a),i=i||Tl(u.text)}return l(t.length),o}function yS(e,t){if(t==="zero-width-break"||t==="soft-hyphen"||t==="hard-break")return 0;if(t==="tab")return 1;let n=0;const o=l6();for(const s of o.segment(e))n++;return n}function aTe(e){return e==="-"||e==="֊"||e==="‐"||e==="‒"||e==="–"||e==="—"}function uTe(e){if(!/[-\u058A\u2010\u2012\u2013\u2014]/u.test(e))return null;const t=[];let n=0;for(const o of l6().segment(e))n++,aTe(o.segment)&&t.push(n);return t.length===0?null:t}function cTe(e,t,n){return t>1?e+(t-1)*n:e}function dTe(e,t,n,o,s){const i=z2(),{cache:r,emojiCorrection:l}=KMe(t,WMe(e.normalized)),a=nc("-",za("-",r),l)+(s===0?0:s*2),c=nc(" ",za(" ",r),l)*8,d=s!==0;if(e.len===0)return iTe();const f=[],h=[],m=[],v=[];let k=e.chunks.length<=1&&!d;const w=n?[]:null,b=[],_=[],g=[],x=n?[]:null,S=Array.from({length:e.len});function T(D,I,$,B,H,O,F,U,z){H!=="text"&&H!=="space"&&H!=="zero-width-break"&&(k=!1),f.push(I),h.push($),m.push(B),v.push(H),w?.push(O),b.push(F),_.push(U),d&&g.push(z),x!==null&&x.push(D)}function A(D,I,$,B,H){const O=za(D,r),F=d?yS(D,I):0,U=cTe(nc(D,O,l),F,s),z=I==="space"||I==="preserved-space"||I==="zero-width-break"?0:U,W=z===0?0:z+(F>0?s:0),K=I==="space"||I==="zero-width-break"?0:U;if(H&&B&&D.length>1){let V="sum-graphemes";s!==0?V="segment-prefixes":Og(D)?V="pair-context":i.preferPrefixWidthsForBreakableRuns&&(V="segment-prefixes");const ie=qMe(D,O,r,l,V),ne=ie===null||o==="keep-all"?null:uTe(D);T(D,U,W,K,I,$,ie,ne,F);return}T(D,U,W,K,I,$,null,null,F)}for(let D=0;D<e.len;D++){S[D]=f.length;const I=e.texts[D],$=e.isWordLike[D],B=e.kinds[D],H=e.starts[D];if(B==="soft-hyphen"){T(I,0,a,a,B,H,null,null,0);continue}if(B==="hard-break"){T(I,0,0,0,B,H,null,null,0);continue}if(B==="tab"){T(I,0,0,0,B,H,null,null,d?yS(I,B):0);continue}const O=za(I,r);if(B==="text"&&O.containsCJK){const F=rTe(I,i),U=o==="keep-all"?lTe(I,F,i.breakKeepAllAfterPunctuation):F;for(let z=0;z<U.length;z++){const W=U[z];A(W.text,"text",H+W.start,$,o==="keep-all"||!Tl(W.text))}continue}A(I,B,H,$,!0)}const E=fTe(e.chunks,S,f.length),P=w===null?null:RAe(e.normalized,w);return x!==null?{widths:f,lineEndFitAdvances:h,lineEndPaintAdvances:m,kinds:v,simpleLineWalkFastPath:k,segLevels:P,breakableFitAdvances:b,breakablePreferredBreaks:_,letterSpacing:s,spacingGraphemeCounts:g,discretionaryHyphenWidth:a,tabStopAdvance:c,chunks:E,segments:x}:{widths:f,lineEndFitAdvances:h,lineEndPaintAdvances:m,kinds:v,simpleLineWalkFastPath:k,segLevels:P,breakableFitAdvances:b,breakablePreferredBreaks:_,letterSpacing:s,spacingGraphemeCounts:g,discretionaryHyphenWidth:a,tabStopAdvance:c,chunks:E}}function fTe(e,t,n){const o=[];for(let s=0;s<e.length;s++){const i=e[s],r=i.startSegmentIndex<t.length?t[i.startSegmentIndex]:n,l=i.endSegmentIndex<t.length?t[i.endSegmentIndex]:n,a=i.consumedEndSegmentIndex<t.length?t[i.consumedEndSegmentIndex]:n;o.push({startSegmentIndex:r,endSegmentIndex:l,consumedEndSegmentIndex:a})}return o}function pTe(e,t,n,o){const s=o?.wordBreak??"normal",i=o?.letterSpacing??0,r=RMe(e,z2(),o?.whiteSpace,s);return dTe(r,t,n,s,i)}function hTe(e,t,n){return pTe(e,t,!0,n)}function mTe(e){let t=0;return sTe(e,Number.POSITIVE_INFINITY,n=>{n>t&&(t=n)}),t}const gTe={key:0,class:"slash-menu",role:"listbox"},vTe=["aria-selected","onMouseenter","onMousedown"],yTe={class:"slash-name"},kTe={class:"slash-desc"},bTe=et({__name:"SlashMenu",props:{items:{},activeIndex:{}},emits:["select","hover"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z([]);return Je(()=>o.activeIndex,r=>{i.value[r]?.scrollIntoView({block:"nearest"})}),(r,l)=>e.items.length>0?(y(),M("div",gTe,[(y(!0),M(Pe,null,pt(e.items,(a,u)=>(y(),M("div",{ref_for:!0,ref:c=>{c&&(i.value[u]=c)},key:`${a.name}-${u}`,class:Re(["slash-item",{active:u===o.activeIndex}]),role:"option","aria-selected":u===o.activeIndex,onMouseenter:c=>s("hover",u),onMousedown:It(c=>s("select",a),["prevent"])},[C("span",yTe,N(a.name),1),C("span",kTe,N(a.isSkill?a.desc:p(n)(a.desc)),1)],42,vTe))),128))])):ee("",!0)}}),CTe=ft(bTe,[["__scopeId","data-v-ca6fa882"]]),wTe={class:"mention-menu",role:"listbox"},_Te={key:0,class:"mention-state dim"},xTe={key:1,class:"mention-state dim"},STe=["aria-selected","onMouseenter","onMousedown"],ATe=["innerHTML"],MTe={class:"mention-name"},TTe={class:"mention-path"},ETe=et({__name:"MentionMenu",props:{items:{},activeIndex:{},loading:{type:Boolean}},emits:["select","hover"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=yd("folder","sm"),r=yd("code","sm"),l=yd("file-text","sm"),a=yd("image","sm"),u=yd("file","sm"),c=new Set(["ts","tsx","js","jsx","mjs","cjs","vue","json","py","go","rs","java","kt","c","h","cpp","cc","hpp","cs","rb","php","swift","sh","bash","zsh","css","scss","less","html","htm","xml","sql","yaml","yml","toml","lua","dart","scala","clj","ex","exs"]),d=new Set(["md","markdown","mdx","txt","rst","adoc","pdf","doc","docx"]),f=new Set(["png","jpg","jpeg","gif","svg","webp","bmp","ico","avif"]);function h(m){const v=m.path;if(v.endsWith("/"))return i;const k=m.name||v.split("/").pop()||v,w=k.lastIndexOf("."),b=w>0?k.slice(w+1).toLowerCase():"";return b?c.has(b)?r:d.has(b)?l:f.has(b)?a:u:u}return(m,v)=>(y(),M("div",wTe,[n.loading?(y(),M("div",_Te,N(p(s)("mention.searching")),1)):n.items.length===0?(y(),M("div",xTe,N(p(s)("mention.noMatch")),1)):(y(!0),M(Pe,{key:2},pt(n.items,(k,w)=>(y(),M("div",{key:k.path,class:Re(["mention-item",{active:w===n.activeIndex}]),role:"option","aria-selected":w===n.activeIndex,onMouseenter:b=>o("hover",w),onMousedown:It(b=>o("select",k),["prevent"])},[C("span",{class:"mention-icon",innerHTML:h(k),"aria-hidden":"true"},null,8,ATe),C("span",MTe,N(k.name),1),C("span",TTe,N(k.path),1)],42,STe))),128))]))}}),ITe=ft(ETe,[["__scopeId","data-v-181f2289"]]);function LTe(e){const{uploadImage:t,sessionId:n,insertFolderPaths:o}=e,s=Z({}),i=R(()=>s.value[n()??""]??[]),r=Z(null),l=Z(null),a=Z(!1);let u=0;function c(){return`att_${++u}`}function d(z,W){s.value={...s.value,[z]:W}}function f(z){if(z.previewUrl!==void 0)try{URL.revokeObjectURL(z.previewUrl)}catch{}}function h(z){return z.startsWith("image/")?"image":z.startsWith("video/")?"video":"file"}async function m(z){const W=t();if(!W)return;const K=n()??"";if(z.length!==0)for(const V of z){const ie=h(V.type),ne=c(),X=ie==="file"?void 0:URL.createObjectURL(V),le={localId:ne,name:V.name,kind:ie,previewUrl:X,mediaType:V.type||"application/octet-stream",size:V.size,uploading:!0};d(K,[...s.value[K]??[],le]),W(V,V.name).then(Ie=>{const de=s.value[K]??[];d(K,de.map(pe=>pe.localId===ne?{...pe,uploading:!1,fileId:Ie?.fileId,mediaType:Ie?.mediaType??pe.mediaType,error:Ie===null}:pe))}).catch(()=>{const Ie=s.value[K]??[];d(K,Ie.map(de=>de.localId===ne?{...de,uploading:!1,error:!0}:de))})}}function v(z){const W=n()??"",K=s.value[W]??[],V=K.find(ie=>ie.localId===z);r.value?.localId===z&&(r.value=null),V&&f(V),d(W,K.filter(ie=>ie.localId!==z))}function k(z){r.value=z}function w(){r.value=null}function b(){l.value?.click()}function _(z){const W=z.target,K=Array.from(W.files??[]);m(K),W.value=""}function g(z){if(!t())return;const W=z.clipboardData;if(!W)return;const K=[],V=new Set,ie=(ne,X)=>{const le=`${ne.size}:${ne.type}:${X}`;if(V.has(le))return;V.add(le);const Ie=ne.type.split("/")[1]??"png",de=X.includes(".")?X:`paste-${Date.now()}.${Ie}`;K.push(ne instanceof File?ne:new File([ne],de,{type:ne.type}))};for(const ne of Array.from(W.items))if(ne.kind==="file"){const X=ne.getAsFile();X&&ie(X,X.name||`paste-${Date.now()}.${ne.type.split("/")[1]??"png"}`)}for(const ne of Array.from(W.files))ie(ne,ne.name);K.length!==0&&(z.preventDefault(),m(K))}let x=0;function S(z){!t()||!Array.from(z.dataTransfer?.items??[]).some(K=>K.kind==="file")||(z.preventDefault(),z.stopPropagation(),a.value=!0)}function T(){a.value=!1}function A(z){x=0,a.value=!1;const{files:W,folderPaths:K}=b3(z);K.length>0&&(o?.(K),z.preventDefault(),z.stopPropagation()),t()&&(z.preventDefault(),z.stopPropagation(),m(W))}function E(z){return Array.from(z.dataTransfer?.items??[]).some(W=>W.kind==="file")}function P(z){!t()||!E(z)||(z.preventDefault(),x+=1,a.value=!0)}function D(z){!t()||!E(z)||z.preventDefault()}function I(z){!t()||!E(z)||(x=Math.max(0,x-1),x===0&&(a.value=!1))}function $(z){x=0,a.value=!1;const{files:W,folderPaths:K}=b3(z);K.length>0&&(o?.(K),z.preventDefault()),t()&&(z.preventDefault(),m(W))}function B(){const z=n()??"";for(const W of s.value[z]??[])f(W);d(z,[])}function H(){r.value=null,B()}function O(z,W,K){const V=s.value[z]??[];V.some(ie=>ie.localId===W)&&d(z,V.map(ie=>ie.localId===W?{...ie,...K}:ie))}function F(z){return fetch(z).then(W=>{if(!W.ok)throw new Error(`fetch failed: ${W.status}`);return W.blob()})}function U(z){const W=n()??"";for(const K of s.value[W]??[])f(K);d(W,[]);for(const K of z){const V=c(),ie=/^data:/i.test(K.url),ne=/^blob:/i.test(K.url),X=K.name??K.kind;if(K.fileId){const le={localId:V,name:X,kind:K.kind,previewUrl:K.kind==="file"?void 0:K.url,uploading:!1,fileId:K.fileId};d(W,[...s.value[W]??[],le]),K.kind==="image"&&!ie&&!ne&&_t().getFileBlob(K.fileId).then(Ie=>{const de=URL.createObjectURL(Ie);if(!(s.value[W]??[]).some(ve=>ve.localId===V)){URL.revokeObjectURL(de);return}O(W,V,{previewUrl:de})}).catch(()=>{})}else{if(!K.url)continue;const le=t();if(!le)continue;const Ie={localId:V,name:X,kind:K.kind,previewUrl:K.url,uploading:!0};d(W,[...s.value[W]??[],Ie]),F(K.url).then(de=>{const pe=X.includes(".")?X:`${X}.${de.type.split("/")[1]??"bin"}`;return le(de,pe)}).then(de=>{if(de===null){const pe=s.value[W]??[];d(W,pe.filter(ve=>ve.localId!==V));return}O(W,V,{uploading:!1,fileId:de.fileId})}).catch(()=>{const de=s.value[W]??[];d(W,de.filter(pe=>pe.localId!==V))})}}}return Je(n,()=>{r.value=null}),dn(()=>{document.addEventListener("paste",g),document.addEventListener("dragenter",P),document.addEventListener("dragover",D),document.addEventListener("dragleave",I),document.addEventListener("drop",$)}),bn(()=>{document.removeEventListener("paste",g),document.removeEventListener("dragenter",P),document.removeEventListener("dragover",D),document.removeEventListener("dragleave",I),document.removeEventListener("drop",$);for(const z of Object.values(s.value))for(const W of z)f(W);r.value=null}),{attachments:i,previewAttachment:r,fileInputRef:l,isDragOver:a,removeAttachment:v,openAttachmentPreview:k,closeAttachmentPreview:w,openFilePicker:b,handleFileInputChange:_,handleDragOver:S,handleDragLeave:T,handleDrop:A,clearAfterSubmit:B,clearAttachments:H,loadAttachments:U}}const $Te={class:"composer-card"},NTe={key:0,class:"att-strip"},FTe={key:1,class:"att-row"},RTe={key:0,class:"att-more"},OTe={class:"cin-wrap"},PTe={class:"input-row"},DTe=["placeholder","disabled"],BTe=["aria-label"],HTe={class:"toolbar-left"},zTe=["aria-label","onKeydown"],WTe={class:"perm-pill-label"},UTe=["onClick"],jTe={class:"pd-info"},VTe={class:"pd-desc"},qTe={class:"pd-check"},KTe={class:"mode-label"},ZTe={key:0,class:"mode-tag"},GTe={key:1,class:"mode-tag"},YTe={key:2,class:"mode-tag"},XTe={class:"mode-row-icon"},JTe={class:"mode-row-info"},QTe={class:"mode-row-name"},eEe={class:"mode-row-desc"},tEe={class:"mode-row-icon"},nEe={class:"mode-row-info"},oEe={class:"mode-row-name"},sEe={class:"mode-row-desc"},iEe={class:"mode-row-icon"},rEe={class:"mode-row-info"},lEe={class:"mode-row-name"},aEe={class:"mode-row-desc"},uEe={key:0,class:"mode-row-actions"},cEe={class:"toolbar-right"},dEe=["aria-label"],fEe=["aria-expanded"],pEe={class:"mp-name"},hEe={key:0,class:"think-suffix"},mEe={class:"mp-name"},gEe={class:"mp-name"},vEe=["aria-label"],yEe=["aria-label","disabled"],kEe={class:"md-list"},bEe={key:0,class:"md-section"},CEe=["onClick"],wEe={class:"md-check"},_Ee={class:"md-name"},xEe={class:"md-provider"},SEe={key:1,class:"md-divider"},AEe={key:2,class:"md-section"},MEe=["onClick"],TEe={class:"md-check"},EEe={class:"md-name"},IEe={key:0,class:"md-divider"},LEe={class:"md-thinking"},$Ee={class:"md-name"},NEe={key:0,class:"md-note"},FEe={key:2,class:"md-note"},REe={class:"md-cache-note"},OEe={class:"md-check md-more-icon"},PEe={class:"md-name"},DEe={key:1,class:"composer-footer"},BEe={class:"drop-card"},kS=36,HEe=et({__name:"Composer",props:{running:{type:Boolean,default:!1},working:{type:Boolean,default:!1},starting:{type:Boolean,default:!1},sessionId:{},queued:{default:()=>[]},searchFiles:{type:Function,default:void 0},uploadImage:{type:Function,default:void 0},status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},goalMode:{type:Boolean},goal:{},activationBadges:{},models:{default:()=>[]},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{default:()=>[]},skills:{default:()=>[]},hideContext:{type:Boolean}},emits:["submit","steer","command","interrupt","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","openBtw","createGoal","controlGoal","focusGoal","focusSwarm","compact","pickModel","selectModel","login"],setup(e,{expose:t,emit:n}){const o=e,s=R(()=>o.starting?r("composer.starting"):o.running?r("composer.placeholderRunning"):o.goalMode?r("status.goalPlaceholder"):r("composer.placeholder")),i=n,{t:r,locale:l}=Nt(),{text:a,textareaRef:u,autosize:c,loadForEdit:d,clearDraft:f}=Ehe({sessionId:()=>o.sessionId}),h=Z(!1);function m(){h.value=!h.value,yt(()=>{c(),b(),u.value?.focus()})}function v(){h.value&&(h.value=!1,yt(c))}function k(J){if(typeof getComputedStyle>"u")return kS;const Ce=Number.parseFloat(getComputedStyle(J).minHeight);return Number.isFinite(Ce)&&Ce>0?Ce:kS}const w=Z(!1);function b(){const J=u.value;w.value=!!J&&J.scrollHeight>k(J)}Je(a,()=>{yt(b)}),Je(()=>o.sessionId,()=>{h.value=!1});const _=Nhe({text:a,textareaRef:u,autosize:c,sessionId:()=>o.sessionId}),{open:g,items:x,active:S,update:T,select:A}=Fhe({text:a,textareaRef:u,autosize:c,skills:()=>o.skills,emitCommand:J=>i("command",{cmd:J,attachments:[]}),historyPush:J=>_.push(J),clearDraft:f}),{open:E,items:P,active:D,loading:I,update:$,select:B}=Rhe({text:a,textareaRef:u,autosize:c,searchFiles:()=>o.searchFiles});function H(){_.resetBrowsing(),T(),$()}function O(J){const Ce=J.map(Et=>/\s/.test(Et)?`"${Et}"`:Et).join(" "),$e=u.value,He=a.value,vt=$e&&document.activeElement===$e?$e.selectionStart:He.length,ut=vt>0&&!/\s/.test(He[vt-1])?" ":"",Dt=vt<He.length&&!/\s/.test(He[vt])?" ":"";_.resetBrowsing(),a.value=He.slice(0,vt)+ut+Ce+Dt+He.slice(vt),yt(()=>{const Et=u.value;if(!Et)return;const ln=vt+ut.length+Ce.length;Et.setSelectionRange(ln,ln),Et.focus(),c()})}const{attachments:F,previewAttachment:U,fileInputRef:z,isDragOver:W,removeAttachment:K,openAttachmentPreview:V,closeAttachmentPreview:ie,openFilePicker:ne,handleFileInputChange:X,handleDragOver:le,handleDragLeave:Ie,handleDrop:de,clearAfterSubmit:pe,clearAttachments:ve,loadAttachments:oe}=LTe({uploadImage:()=>o.uploadImage,sessionId:()=>o.sessionId,insertFolderPaths:O}),ye=J=>J.kind==="image"||J.kind==="video",G=R(()=>F.value.filter(ye)),Y=R(()=>F.value.filter(J=>!ye(J))),fe=Z(null),we=Z(null),ge=Z(!1);function Q(){const J=fe.value,Ce=we.value;ge.value=J!==null&&Ce!==null&&Ce.scrollHeight>J.clientHeight+1}let te=null;Je(fe,J=>{if(te?.disconnect(),te=null,J){const Ce=new ResizeObserver(Q);Ce.observe(J),te=Ce}Q()},{immediate:!0}),Je(F,()=>void yt(Q),{deep:!0}),bn(()=>te?.disconnect());const ce=Z(null);Je(()=>[G.value.length,Y.value.length],([J,Ce],[$e,He])=>{J<=$e&&Ce<=He||yt(()=>{const vt=fe.value;vt&&(J>$e&&ce.value?vt.scrollTop=ce.value.offsetHeight-vt.clientHeight:vt.scrollTop=vt.scrollHeight)})}),dn(()=>{a.value&&yt(()=>{c(),b()})}),bn(()=>{document.removeEventListener("mousedown",Io),Bt()});function ue(){u.value?.focus({preventScroll:!0})}function Se(J){oe(J)}function ze(J){return{fileId:J.fileId,kind:J.kind,name:J.name,mediaType:J.mediaType,size:J.size}}const _e=Z(null);function Ee(J,Ce){if(J.kind==="file"){J.fileId!==void 0&&XN(_t(),J.fileId,J.name,J.mediaType);return}_e.value=Ce??null,V(J)}const it=R(()=>{const J=U.value;return!J||!J.previewUrl?null:{kind:J.kind==="video"?"video":"image",url:J.previewUrl,path:J.name,fileId:J.previewUrl.startsWith("blob:")?void 0:J.fileId}}),Fe=R(()=>!F.value.some(J=>J.uploading)&&(a.value.trim()!==""||F.value.some(J=>!J.error&&J.fileId)));function Oe(){const J=a.value.trim();if(F.value.some(He=>He.uploading))return;const Ce=F.value.filter(He=>!He.uploading&&!He.error&&He.fileId);if(!J&&Ce.length===0)return;if(_.push(J),J){const He=pQ(J),vt=He?CE(o.skills).find(ut=>ut.name===He.cmd||ut.name===`/${Bm}${He.cmd.slice(1)}`):void 0;if(He&&vt){const ut=He.arg?`${He.cmd} ${He.arg}`:He.cmd,Dt=vt.isSkill===!0;a.value="",f(),g.value=!1,v(),Dt?(U.value=null,_e.value=null,pe(),E.value=!1,i("command",{cmd:ut,attachments:Ce.map(Et=>ze(Et))})):i("command",{cmd:ut,attachments:[]});return}}const $e={text:J,attachments:Ce.map(He=>ze(He))};U.value=null,_e.value=null,pe(),a.value="",f(),g.value=!1,E.value=!1,v(),i("submit",$e)}function Ge(){if(!o.running||F.value.some(He=>He.uploading))return;const J=a.value.trim(),Ce=F.value.filter(He=>!He.uploading&&!He.error&&He.fileId);if(!J&&Ce.length===0&&o.queued.length===0)return;const $e={text:J,attachments:Ce.map(He=>ze(He))};pe(),_.push(J),a.value="",f(),g.value=!1,E.value=!1,v(),i("steer",$e)}let at=!1,Tt=null;function Bt(){Tt!==null&&(clearTimeout(Tt),Tt=null)}function Yt(){Bt(),at=!0}function Sn(){Bt(),Tt=setTimeout(()=>{Tt=null,at=!1},0)}function on(J){return at||J.isComposing||J.keyCode===229}function en(J){if(!on(J)){if(J.key==="Escape"){if(We.value){J.preventDefault(),_n();return}if(tt.value){J.preventDefault(),To();return}}if(g.value){if(J.key==="ArrowDown"){J.preventDefault(),S.value=(S.value+1)%x.value.length;return}if(J.key==="ArrowUp"){J.preventDefault(),S.value=(S.value-1+x.value.length)%x.value.length;return}if(J.key==="Enter"||J.key==="Tab"){J.preventDefault();const Ce=x.value[S.value];Ce&&A(Ce);return}if(J.key==="Escape"){J.preventDefault(),g.value=!1;return}}if(E.value&&!I.value){if(J.key==="Escape"){J.preventDefault(),E.value=!1;return}if(P.value.length>0){if(J.key==="ArrowDown"){J.preventDefault(),D.value=(D.value+1)%P.value.length;return}if(J.key==="ArrowUp"){J.preventDefault(),D.value=(D.value-1+P.value.length)%P.value.length;return}if(J.key==="Enter"||J.key==="Tab"){J.preventDefault();const Ce=P.value[D.value];Ce&&B(Ce);return}}}if(J.key==="s"&&(J.ctrlKey||J.metaKey)&&!J.shiftKey&&!J.altKey){o.running&&(J.preventDefault(),Ge());return}if(!h.value&&!g.value&&!E.value&&!J.shiftKey&&!J.altKey&&!J.metaKey&&!J.ctrlKey){const Ce=_.isBrowsing();if(J.key==="ArrowUp"&&_.hasHistory()&&(Ce||_.caretAtTextStart())){J.preventDefault(),_.recallOlder();return}if(J.key==="ArrowDown"&&Ce){J.preventDefault(),_.recallNewer();return}}if(J.key==="Enter"&&!J.shiftKey){if(h.value&&!(J.metaKey||J.ctrlKey))return;J.preventDefault(),Oe()}}}const Cn=R(()=>r("composer.send")),Mn=R(()=>!!o.uploadImage),We=Z(!1),tt=Z(!1),Ue=Z(!1),Lt=Z(null),gt=Z(null),wn=Z(null),yn=Z(""),go=R(()=>{const J={};return yn.value&&(J.right=yn.value),J}),qt=R(()=>We.value||tt.value||Ue.value||g.value||E.value);t({loadForEdit:d,loadAttachmentsForEdit:Se,focus:ue,anyPopupOpen:qt,isEmpty:()=>a.value.trim().length===0&&F.value.length===0});function xs(){We.value=!We.value,We.value?(tl(),tt.value=!1,Do(),document.addEventListener("click",lo,!0)):document.removeEventListener("click",lo,!0)}function _n(){We.value=!1,tt.value||document.removeEventListener("click",lo,!0)}function In(){tt.value=!tt.value,tt.value?(Zi(),We.value=!1,Do(),document.addEventListener("click",lo,!0)):document.removeEventListener("click",lo,!0)}function To(){tt.value=!1,We.value||document.removeEventListener("click",lo,!0)}function lo(J){Lt.value&&!Lt.value.contains(J.target)&&(_n(),To())}bn(()=>{document.removeEventListener("click",lo,!0)});const St=R(()=>{const J=o.status?.ctxMax??0;return J<=0?0:Math.min(100,Math.max(0,Math.ceil((o.status?.ctxUsed??0)/J*100)))}),hs=R(()=>{const J=Al(o.status?.ctxUsed??0),Ce=Al(o.status?.ctxMax??0);return r("status.ctxTooltip",{used:J,max:Ce,pct:St.value})}),Jo=R(()=>St.value>=80),uo=R(()=>o.models?.find(J=>J.id===o.status?.modelId)),Ys=R(()=>p2(uo.value)),Nn=R(()=>Up(uo.value)),no=R(()=>Dm(uo.value,o.thinking)),$s=R(()=>Nn.value.includes(no.value)?no.value:""),Xs=R(()=>mJ(no.value)),ci=R(()=>Ys.value==="unsupported"||Nn.value.length<=1),Oo=R(()=>{if(!Xs.value)return"";const J=(uo.value?.supportEfforts?.length??0)>0,Ce=no.value;return J&&Ce!=="on"?r("composer.thinkingSuffixEffort",{level:Ce}):r("composer.thinkingSuffix")});function vo(J){ci.value||i("setThinking",My(uo.value,J))}function Po(J){return J==="on"?r("status.thinkingOn"):J==="off"?r("status.thinkingOff"):y3(J)}const co=R(()=>Nn.value.map(J=>({value:J,label:Po(J)}))),Tn=R(()=>o.planMode===!0),fo=R(()=>o.swarmMode===!0),Qe=R(()=>o.goal?.status??o.activationBadges?.goal?.status??null),st=R(()=>Qe.value!==null&&Qe.value!=="complete"),Ct=R(()=>st.value||o.goalMode===!0),Qt=R(()=>Qe.value==="active"),kn=R(()=>Qe.value==="paused"||Qe.value==="blocked"),Ko=Z(null),Eo=Z(null),bo=Z({}),Ns=R(()=>Tn.value||fo.value||Ct.value);function Do(){Ue.value=!1,document.removeEventListener("mousedown",Io)}function Io(J){const Ce=J.target;Ko.value?.contains(Ce)||Eo.value?.contains(Ce)||Do()}function Qo(){if(Ue.value){Do();return}_n(),To();const J=Ko.value?.getBoundingClientRect();J&&(bo.value={left:`${Math.round(J.left)}px`,bottom:`${Math.round(window.innerHeight-J.top+8)}px`}),Ue.value=!0,setTimeout(()=>document.addEventListener("mousedown",Io),0)}const sn=[{mode:"manual",icon:"hand",color:"var(--color-text)",labelKey:"status.permissionManual",descKey:"status.permissionManualDesc"},{mode:"yolo",icon:"shield-question",color:"var(--color-warning)",labelKey:"status.permissionYolo",descKey:"status.permissionYoloDesc"},{mode:"auto",icon:"full-access",color:"var(--color-danger)",labelKey:"status.permissionAuto",descKey:"status.permissionAutoDesc"}],es=["status.planDesc","status.swarmDesc","status.goalDesc"],ms=Z(null),Tr=Z(""),ts=Z(""),Ki=Z("");function Js(J){const Ce={};return J&&(Ce["--composer-menu-desc-width"]=J),Ce}const Bo=R(()=>({...Js(Tr.value),...ts.value?{left:ts.value}:{}})),Zo=R(()=>Js(Ki.value)),Il=R(()=>({...bo.value,...Zo.value}));function Zi(){const J=gt.value,Ce=Lt.value;if(!J||!Ce){ts.value="";return}ts.value=`${Math.round(J.getBoundingClientRect().left-Ce.getBoundingClientRect().left)}px`}function tl(){const J=wn.value,Ce=Lt.value;if(!J||!Ce){yn.value="";return}yn.value=`${Math.round(Ce.getBoundingClientRect().right-J.getBoundingClientRect().right)}px`}let Ho=null;function Co(J){const Ce=Number.parseFloat(J);return Number.isFinite(Ce)?Ce:0}function Fs(J){return`${J.fontStyle||"normal"} ${J.fontWeight||"400"} ${J.fontSize} ${J.fontFamily}`}function Rs(J){return J.letterSpacing==="normal"?0:Co(J.letterSpacing)}function yo(J,Ce){if(!J)return 0;const $e=hTe(J,Fs(Ce),{letterSpacing:Rs(Ce)});return mTe($e)}function ht(){const J=ms.value?.querySelector(".pd-desc");if(!J)return;const Ce=getComputedStyle(J),$e=Math.max(0,...sn.map(vt=>yo(r(vt.descKey),Ce))),He=Math.max(0,...es.map(vt=>yo(r(vt),Ce)));Tr.value=$e>0?`${Math.ceil($e)}px`:"",Ki.value=He>0?`${Math.ceil(He)}px`:""}function Le(){typeof window>"u"||(Ho!==null&&window.cancelAnimationFrame(Ho),yt(()=>{Ho=window.requestAnimationFrame(()=>{Ho=null,ht()})}))}Je(l,Le,{immediate:!0}),dn(()=>{Le(),document.fonts?.ready.then(Le)}),bn(()=>{Ho!==null&&(window.cancelAnimationFrame(Ho),Ho=null)});function Ze(J){i("setPermission",J),To()}const Xt=R(()=>sn.find(J=>J.mode===o.status?.permission)),gs=R(()=>Xt.value?r(Xt.value.labelKey):""),di=R(()=>Xt.value?.icon??"hand"),Ei=R(()=>uo.value?.provider??""),ao=R(()=>!Ei.value||!o.models?.length?[]:o.models.filter(J=>J.provider===Ei.value)),Gi=R(()=>(o.models?.length??0)>0),Er=R(()=>o.authReady===!1&&!Gi.value),fi=R(()=>Er.value&&!(o.managedSignedIn??!1)),Ll=R(()=>Er.value&&(o.managedSignedIn??!1)&&o.managedMembership==="free"),zo=R(()=>new Set(o.starredIds??[]));function Ir(J){return zo.value.has(J)}const Qs=R(()=>o.models?.length?o.models.filter(J=>Ir(J.id)&&J.provider!==Ei.value):[]),pi=Z(null);Je(We,async J=>{if(!J)return;await yt(),(pi.value?.querySelector(".md-row.is-current")??pi.value?.querySelector(".md-row"))?.focus()});function se(J){if(J.key!=="ArrowDown"&&J.key!=="ArrowUp")return;const Ce=Array.from(pi.value?.querySelectorAll(".md-row:not(:disabled)")??[]);if(!Ce.length)return;J.preventDefault();const $e=Ce.indexOf(document.activeElement),He=J.key==="ArrowDown"?($e+1)%Ce.length:($e-1+Ce.length)%Ce.length;Ce[He]?.focus()}function xe(J){i("selectModel",J),_n()}return(J,Ce)=>(y(),M("div",{class:Re(["composer",{"drag-over":p(W),expanded:h.value}]),onDragover:Ce[19]||(Ce[19]=(...$e)=>p(le)&&p(le)(...$e)),onDragleave:Ce[20]||(Ce[20]=(...$e)=>p(Ie)&&p(Ie)(...$e)),onDrop:Ce[21]||(Ce[21]=(...$e)=>p(de)&&p(de)(...$e))},[it.value?(y(),he(Q5,{key:0,media:it.value,"origin-img":_e.value,onClose:Ce[0]||(Ce[0]=$e=>{_e.value=null,p(ie)()})},null,8,["media","origin-img"])):ee("",!0),C("div",$Te,[p(F).length>0?(y(),M("div",NTe,[C("div",{ref_key:"attScrollRef",ref:fe,class:Re(["att-scroll",{"is-overflowing":ge.value}])},[C("div",{ref_key:"attScrollContentRef",ref:we,class:"att-scroll-content"},[G.value.length>0?(y(),M("div",{key:0,ref_key:"attMediaRowRef",ref:ce,class:"att-row att-row-media"},[(y(!0),M(Pe,null,pt(G.value,$e=>(y(),he(rF,{key:$e.localId,kind:$e.kind,name:$e.name,url:$e.previewUrl,"file-id":$e.fileId,uploading:$e.uploading,error:$e.error,removable:"","remove-label":p(r)("composer.removeNamed",{name:$e.name}),onActivate:He=>Ee($e,He),onRemove:He=>p(K)($e.localId)},null,8,["kind","name","url","file-id","uploading","error","remove-label","onActivate","onRemove"]))),128))],512)):ee("",!0),Y.value.length>0?(y(),M("div",FTe,[(y(!0),M(Pe,null,pt(Y.value,$e=>(y(),he(lF,{key:$e.localId,kind:"file",name:$e.name,"media-type":$e.mediaType,size:$e.size,uploading:$e.uploading,error:$e.error,removable:"","remove-label":p(r)("composer.removeNamed",{name:$e.name}),onActivate:He=>Ee($e),onRemove:He=>p(K)($e.localId)},null,8,["name","media-type","size","uploading","error","remove-label","onActivate","onRemove"]))),128))])):ee("",!0)],512)],2),ge.value?(y(),M("span",RTe,N(p(r)("composer.attachmentCount",{n:p(F).length})),1)):ee("",!0),p(F).length>=2?(y(),he(p(pn),{key:1,text:p(r)("composer.clearAll")},{default:me(()=>[j(p(gn),{class:"att-clear",size:"sm",label:p(r)("composer.clearAll"),onClick:p(ve)},{default:me(()=>[j(p(Te),{name:"trash"})]),_:1},8,["label","onClick"])]),_:1},8,["text"])):ee("",!0)])):ee("",!0),C("div",OTe,[p(g)?(y(),he(CTe,{key:0,items:p(x),"active-index":p(S),onSelect:p(A),onHover:Ce[1]||(Ce[1]=$e=>S.value=$e)},null,8,["items","active-index","onSelect"])):ee("",!0),p(E)?(y(),he(ITe,{key:1,items:p(P),"active-index":p(D),loading:p(I),onSelect:p(B),onHover:Ce[2]||(Ce[2]=$e=>D.value=$e)},null,8,["items","active-index","loading","onSelect"])):ee("",!0),C("div",PTe,[Bn(C("textarea",{ref_key:"textareaRef",ref:u,"onUpdate:modelValue":Ce[3]||(Ce[3]=$e=>Xo(a)?a.value=$e:null),class:"ph",placeholder:s.value,disabled:e.starting,autocomplete:"off",spellcheck:"false",rows:"1",onKeydown:en,onCompositionstart:Yt,onCompositionend:Sn,onInput:H},null,40,DTe),[[ai,p(a)]]),j(p(pn),{text:h.value?p(r)("composer.collapseTitle"):p(r)("composer.expandTitle")},{default:me(()=>[h.value||w.value?(y(),M("button",{key:0,class:"expand-btn",type:"button","aria-label":h.value?p(r)("composer.collapseTitle"):p(r)("composer.expandTitle"),onClick:m},[h.value?(y(),he(p(Te),{key:0,name:"collapse",size:"sm"})):(y(),he(p(Te),{key:1,name:"expand",size:"sm"}))],8,BTe)):ee("",!0)]),_:1},8,["text"])])]),Mn.value?(y(),M("input",{key:1,ref_key:"fileInputRef",ref:z,type:"file",multiple:"",class:"file-input-hidden",onChange:Ce[4]||(Ce[4]=(...$e)=>p(X)&&p(X)(...$e))},null,544)):ee("",!0),C("div",{ref_key:"toolbarRef",ref:Lt,class:"toolbar"},[C("div",{ref_key:"menuMeasureRef",ref:ms,class:"menu-measure","aria-hidden":"true"},[...Ce[22]||(Ce[22]=[C("span",{class:"pd-desc"},null,-1)])],512),C("div",HTe,[Mn.value?(y(),he(p(gn),{key:0,class:"composer-attach",size:"md",label:p(r)("composer.attachFile"),tooltip:p(r)("composer.attachFile"),onClick:p(ne)},{default:me(()=>[j(p(Te),{name:"attachment"})]),_:1},8,["label","tooltip","onClick"])):ee("",!0),e.status?(y(),M("span",{key:1,ref_key:"permPillRef",ref:gt,class:Re(["perm-pill",["perm-"+e.status.permission,{open:tt.value}]]),role:"button",tabindex:"0","aria-label":gs.value,onClick:It(In,["stop"]),onKeydown:[xl(In,["enter"]),xl(It(In,["prevent"]),["space"])]},[j(p(Te),{class:"perm-pill-icon",name:di.value,size:"sm"},null,8,["name"]),C("span",WTe,N(gs.value),1)],42,zTe)):ee("",!0),j(as,{name:"composer-menu-pop"},{default:me(()=>[tt.value&&e.status?(y(),M("div",{key:0,class:"perm-dropdown",style:Zt(Bo.value),role:"menu",onClick:Ce[5]||(Ce[5]=It(()=>{},["stop"]))},[(y(),M(Pe,null,pt(sn,$e=>C("button",{key:$e.mode,class:Re(["pd-row",{"is-current":$e.mode===e.status.permission}]),role:"menuitem",onClick:He=>Ze($e.mode)},[C("span",{class:"pd-icon",style:Zt({color:$e.color})},[j(p(Te),{name:$e.icon,size:"sm"},null,8,["name"])],4),C("span",jTe,[C("span",{class:"pd-name",style:Zt({color:$e.color})},N(p(r)($e.labelKey)),5),C("span",VTe,N(p(r)($e.descKey)),1)]),C("span",qTe,[$e.mode===e.status.permission?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)])],10,UTe)),64))],4)):ee("",!0)]),_:1}),e.status?(y(),M("div",{key:2,ref_key:"modesRef",ref:Ko,class:"modes"},[C("button",{type:"button",class:Re(["mode-pill",{on:Ns.value,open:Ue.value}]),onClick:It(Qo,["stop"])},[C("span",KTe,N(p(r)("status.modesLabel")),1),Tn.value?(y(),M("span",ZTe,N(p(r)("status.planLabel")),1)):ee("",!0),fo.value?(y(),M("span",GTe,N(p(r)("status.swarmLabel")),1)):ee("",!0),Ct.value?(y(),M("span",YTe,N(p(r)("status.goalLabel")),1)):ee("",!0)],2),j(as,{name:"composer-menu-pop"},{default:me(()=>[Ue.value?(y(),M("div",{key:0,ref_key:"modesMenuRef",ref:Eo,class:"modes-menu",style:Zt(Il.value),role:"menu"},[C("button",{type:"button",class:Re(["mode-row",{on:Tn.value}]),role:"menuitem",onClick:Ce[6]||(Ce[6]=$e=>i("togglePlan"))},[C("span",XTe,[j(p(Te),{name:"file-edit",size:"sm"})]),C("span",JTe,[C("span",QTe,N(p(r)("status.planLabel")),1),C("span",eEe,N(p(r)("status.planDesc")),1)]),C("span",{class:Re(["mode-switch",{on:Tn.value}])},[...Ce[23]||(Ce[23]=[C("span",{class:"mode-knob"},null,-1)])],2)],2),C("button",{type:"button",class:Re(["mode-row",{on:fo.value}]),role:"menuitem",onClick:Ce[7]||(Ce[7]=$e=>i("toggleSwarm"))},[C("span",tEe,[j(p(Te),{name:"sparkles",size:"sm"})]),C("span",nEe,[C("span",oEe,N(p(r)("status.swarmLabel")),1),C("span",sEe,N(p(r)("status.swarmDesc")),1)]),C("span",{class:Re(["mode-switch",{on:fo.value}])},[...Ce[24]||(Ce[24]=[C("span",{class:"mode-knob"},null,-1)])],2)],2),C("div",{class:Re(["mode-row mode-row-goal",{on:st.value||o.goalMode}])},[C("button",{type:"button",class:"mode-row-main",role:"menuitem",onClick:Ce[8]||(Ce[8]=$e=>st.value?i("focusGoal"):i("toggleGoal"))},[C("span",iEe,[j(p(Te),{name:"target",size:"sm"})]),C("span",rEe,[C("span",lEe,N(p(r)("status.goalLabel")),1),C("span",aEe,N(p(r)("status.goalDesc")),1)]),st.value?ee("",!0):(y(),M("span",{key:0,class:Re(["mode-switch",{on:o.goalMode}])},[...Ce[25]||(Ce[25]=[C("span",{class:"mode-knob"},null,-1)])],2))]),st.value?(y(),M("div",uEe,[Qt.value?(y(),he(p(Rt),{key:0,size:"sm",variant:"secondary",class:"mode-row-action",onClick:Ce[9]||(Ce[9]=$e=>i("controlGoal","pause"))},{default:me(()=>[j(p(Te),{name:"pause",size:"sm"}),C("span",null,N(p(r)("status.goalPause")),1)]),_:1})):ee("",!0),kn.value?(y(),he(p(Rt),{key:1,size:"sm",variant:"primary",class:"mode-row-action",onClick:Ce[10]||(Ce[10]=$e=>i("controlGoal","resume"))},{default:me(()=>[j(p(Te),{name:"play",size:"sm"}),C("span",null,N(p(r)("status.goalResume")),1)]),_:1})):ee("",!0),j(p(Rt),{size:"sm",variant:"danger-soft",class:"mode-row-action",onClick:Ce[11]||(Ce[11]=$e=>i("controlGoal","cancel"))},{default:me(()=>[j(p(Te),{name:"close",size:"sm"}),C("span",null,N(p(r)("status.goalCancel")),1)]),_:1})])):ee("",!0)],2)],4)):ee("",!0)]),_:1})],512)):ee("",!0)]),C("div",cEe,[Jo.value?(y(),M("button",{key:0,class:"compact-chip",onClick:Ce[12]||(Ce[12]=It($e=>i("compact"),["stop"]))},"/compact")):ee("",!0),j(p(pn),{text:hs.value},{default:me(()=>[e.status&&!e.hideContext?(y(),M("span",{key:0,class:"ctx-group",role:"img",tabindex:"0","aria-label":hs.value},[j(p(cW),{pct:St.value},null,8,["pct"])],8,dEe)):ee("",!0)]),_:1},8,["text"]),e.status&&!fi.value&&!Ll.value?(y(),M("button",{key:1,ref_key:"modelPillRef",ref:wn,type:"button",class:Re(["model-pill",{open:We.value}]),"aria-haspopup":"menu","aria-expanded":We.value,onClick:It(xs,["stop"])},[C("span",pEe,N(e.status.model),1),Oo.value?(y(),M("span",hEe,N(Oo.value),1)):ee("",!0),j(p(Te),{class:"cv",name:"chevron-down",size:"sm"})],10,fEe)):e.status&&Ll.value?(y(),M("button",{key:2,type:"button",class:"model-pill login-pill",onClick:Ce[13]||(Ce[13]=It($e=>p(jp)(),["stop"]))},[j(p(Te),{name:"music",size:"sm"}),C("span",mEe,N(p(r)("sidebar.upgrade")),1)])):e.status&&fi.value?(y(),M("button",{key:3,type:"button",class:"model-pill login-pill",onClick:Ce[14]||(Ce[14]=It($e=>i("login"),["stop"]))},[j(p(Te),{name:"log-in",size:"sm"}),C("span",gEe,N(p(r)("login.action")),1)])):ee("",!0),e.working?(y(),he(p(pn),{key:4,text:p(r)("composer.interruptTitle")},{default:me(()=>[C("button",{class:"stop","aria-label":p(r)("composer.interrupt"),onClick:Ce[15]||(Ce[15]=$e=>i("interrupt"))},[j(p(Te),{name:"stop",size:"sm"})],8,vEe)]),_:1},8,["text"])):ee("",!0),j(p(pn),{text:Cn.value},{default:me(()=>[C("button",{class:Re(["send",{"is-starting":e.starting}]),"aria-label":Cn.value,disabled:e.starting||!Fe.value,onClick:Ce[16]||(Ce[16]=$e=>Oe())},[e.starting?(y(),he(p(Ao),{key:0,size:"sm"})):(y(),he(p(Te),{key:1,name:"send",size:"sm"}))],10,yEe)]),_:1},8,["text"])]),j(as,{name:"composer-menu-pop"},{default:me(()=>[We.value&&e.status?(y(),M("div",{key:0,ref_key:"modelDropdownRef",ref:pi,class:"model-dropdown",style:Zt(go.value),role:"menu",onClick:Ce[18]||(Ce[18]=It(()=>{},["stop"])),onKeydown:se},[C("div",kEe,[Qs.value.length>0?(y(),M("div",bEe,N(p(r)("status.starredModels")),1)):ee("",!0),(y(!0),M(Pe,null,pt(Qs.value,$e=>(y(),M("button",{key:$e.id,class:Re(["md-row",{"is-current":$e.id===e.status.modelId}]),role:"menuitem",onClick:He=>xe($e.id)},[C("span",wEe,[$e.id===e.status.modelId?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)]),C("span",_Ee,N($e.displayName??$e.model),1),C("span",xEe,N($e.provider),1),j(p(Te),{class:"md-star",name:"star",size:"sm"})],10,CEe))),128)),Qs.value.length>0?(y(),M("div",SEe)):ee("",!0),ao.value.length>0?(y(),M("div",AEe,N(Ei.value),1)):ee("",!0),(y(!0),M(Pe,null,pt(ao.value,$e=>(y(),M("button",{key:$e.id,class:Re(["md-row",{"is-current":$e.id===e.status.modelId}]),role:"menuitem",onClick:He=>xe($e.id)},[C("span",TEe,[$e.id===e.status.modelId?(y(),he(p(Te),{key:0,name:"check",size:"sm"})):ee("",!0)]),C("span",EEe,N($e.displayName??$e.model),1),Ir($e.id)?(y(),he(p(Te),{key:0,class:"md-star",name:"star",size:"sm"})):ee("",!0)],10,MEe))),128))]),ao.value.length>0?(y(),M("div",IEe)):ee("",!0),C("div",LEe,[C("span",$Ee,N(p(r)("status.thinkingLabel")),1),Ys.value==="unsupported"?(y(),M("span",NEe,N(p(r)("status.modeNotSupported")),1)):Nn.value.length>1?(y(),he(p(wi),{key:1,"model-value":$s.value,options:co.value,size:"xs","onUpdate:modelValue":vo},null,8,["model-value","options"])):(y(),M("span",FEe,N(Po(Nn.value[0]??no.value)),1))]),Ce[26]||(Ce[26]=C("div",{class:"md-divider"},null,-1)),C("div",REe,N(p(r)("status.cacheNote")),1),Ce[27]||(Ce[27]=C("div",{class:"md-divider"},null,-1)),C("button",{class:"md-row md-row-more",role:"menuitem",onClick:Ce[17]||(Ce[17]=$e=>{_n(),i("pickModel")})},[C("span",OEe,[j(p(Te),{name:"list",size:"sm"})]),C("span",PEe,N(p(r)("status.moreModels")),1),j(p(Te),{class:"md-more-arrow",name:"chevron-right",size:"sm"})])],36)):ee("",!0)]),_:1})],512)]),J.$slots.footer?(y(),M("div",DEe,[xn(J.$slots,"footer",{},void 0,!0)])):ee("",!0),C("div",{class:Re(["drop-overlay",{show:p(W)}]),"aria-hidden":"true"},[C("div",BEe,[j(p(Te),{name:"file-plus",size:"lg"}),C("span",null,N(p(r)("composer.dropToAttach")),1)])],2)],34))}}),mF=ft(HEe,[["__scopeId","data-v-81ce0c45"]]),zEe={class:"goal-panel"},WEe={class:"goal-full"},UEe={key:0,class:"goal-criterion"},jEe={class:"goal-criterion-label"},VEe=et({__name:"GoalPanel",props:{goal:{}},setup(e){const{t}=Nt();return(n,o)=>(y(),M("div",zEe,[C("div",WEe,N(e.goal.objective),1),e.goal.completionCriterion?(y(),M("div",UEe,[C("span",jEe,[j(p(Te),{name:"check-list",size:"sm"}),qe(" "+N(p(t)("status.goalDoneWhen")),1)]),C("p",null,N(e.goal.completionCriterion),1)])):ee("",!0)]))}}),qEe=ft(VEe,[["__scopeId","data-v-104a665c"]]),KEe={key:0,class:"qh-chip"},ZEe={class:"qtitle"},GEe={class:"qbody"},YEe={class:"qopts"},XEe=["onClick"],JEe={class:"qopt-key"},QEe={class:"qopt-text"},eIe={class:"qopt-label"},tIe={key:0,class:"qopt-desc"},nIe={class:"qopt-label"},oIe=["placeholder"],sIe={class:"qfoot"},iIe={class:"qbtns"},rIe={class:"qhint"},lIe=et({__name:"QuestionCard",props:{question:{},busyKind:{}},emits:["answer","dismiss"],setup(e,{emit:t}){const n=e,{t:o}=Nt(),s=t,i=Z(0),r=Z(!1);function l(){r.value&&(r.value=!1)}const a=R(()=>n.question.questions[i.value]),u=R(()=>n.question.questions.length);function c(){i.value>0&&i.value--}function d(){i.value<u.value-1&&i.value++}function f(W){const K=m.value[W];return K?K.kind==="multi"?K.optionIds.length>0:K.kind==="multiWithOther"?K.optionIds.length>0||K.otherText.trim().length>0:K.kind==="other"?K.text.trim().length>0:!0:!1}function h(){return f(a.value.id)}const m=Z({});function v(W){return W.recommended===!0?!0:/\b(?:recommended|recommend)\b|推荐/.test(`${W.label} ${W.description??""}`.toLowerCase())}function k(){const W={...m.value};let K=!1;for(const V of n.question.questions){if(W[V.id])continue;const ie=V.options.filter(v);ie.length!==0&&(W[V.id]=V.multiSelect?{kind:"multi",optionIds:ie.map(ne=>ne.id)}:{kind:"single",optionId:ie[0].id},K=!0)}K&&(m.value=W)}Je(()=>n.question.questionId,()=>{i.value=0,r.value=!1,m.value={},_.value={}}),Je(()=>n.question,()=>{i.value>=n.question.questions.length&&(i.value=0),k()},{immediate:!0,deep:!0});function w(W,K){const V=m.value[W];if(V&&V.kind==="single"&&V.optionId===K){const ie={...m.value};delete ie[W],m.value=ie}else m.value={...m.value,[W]:{kind:"single",optionId:K}}}function b(W,K){const V=m.value[W],ie=V&&(V.kind==="multi"||V.kind==="multiWithOther")?V.kind==="multi"?[...V.optionIds]:[...V.optionIds]:[],ne=ie.indexOf(K);ne>=0?ie.splice(ne,1):ie.push(K);const X=m.value[W],le=X&&X.kind==="multiWithOther"?X.otherText:"";le?m.value={...m.value,[W]:{kind:"multiWithOther",optionIds:ie,otherText:le}}:m.value={...m.value,[W]:{kind:"multi",optionIds:ie}}}const _=Z({}),g=Z(null);function x(W){const K=n.question.questions.find(ie=>ie.id===W),V=_.value[W]??"";if(K.multiSelect){const ie=m.value[W],ne=ie&&(ie.kind==="multi"||ie.kind==="multiWithOther")?ie.kind==="multi"?[...ie.optionIds]:[...ie.optionIds]:[];m.value={...m.value,[W]:{kind:"multiWithOther",optionIds:ne,otherText:V}}}else m.value={...m.value,[W]:{kind:"other",text:V}}}function S(W){x(W),yt(()=>g.value?.focus())}function T(W,K){const V=m.value[W];return V?V.kind==="single"?V.optionId===K:V.kind==="multi"||V.kind==="multiWithOther"?V.optionIds.includes(K):!1:!1}function A(W){const K=m.value[W];return!!(K&&(K.kind==="other"||K.kind==="multiWithOther"))}function E(){return n.question.questions.every(W=>f(W.id))}const P=R(()=>n.busyKind==="answer"),D=R(()=>n.busyKind==="dismiss"),I=R(()=>!!n.busyKind);function $(){if(I.value||!E())return;const W={answers:m.value,method:"click"};s("answer",n.question.questionId,W)}function B(){I.value||s("dismiss",n.question.questionId)}const H=Z(0);Je([i,()=>n.question.questionId],()=>{H.value=0});const{handleCompositionStart:O,handleCompositionEnd:F,isComposingKeyEvent:U}=Ar();function z(W){const K=(document.activeElement?.tagName??"").toLowerCase(),V=K==="input"||K==="textarea";if(W.metaKey||W.ctrlKey||W.altKey||I.value||U(W)||Ci.value>0)return;if(W.key==="Enter"){if(W.preventDefault(),r.value)return;i.value<u.value-1&&h()?d():E()&&$();return}if(V)return;if(W.key==="Escape"){if(Ci.value>0||W.defaultPrevented)return;W.preventDefault(),B();return}if(r.value)return;if(W.key==="ArrowDown"||W.key==="ArrowUp"){const ne=a.value,X=ne.options.length+(ne.allowOther?1:0);if(X===0)return;W.preventDefault();const le=W.key==="ArrowDown"?1:-1,Ie=Math.min(X-1,Math.max(0,H.value+le));if(Ie===H.value)return;H.value=Ie;const de=ne.options[H.value];de?ne.multiSelect||w(ne.id,de.id):ne.allowOther&&!ne.multiSelect&&x(ne.id);return}if(W.key===" "&&a.value.multiSelect){W.preventDefault();const ne=a.value,X=ne.options[H.value];X?b(ne.id,X.id):ne.allowOther&&x(ne.id);return}const ie=parseInt(W.key,10);if(!isNaN(ie)&&ie>=1&&ie<=9){W.preventDefault();const ne=a.value,X=ie-1,le=ne.options[X];le&&(H.value=X,ne.multiSelect?b(ne.id,le.id):w(ne.id,le.id))}}return dn(()=>document.addEventListener("keydown",z)),bn(()=>document.removeEventListener("keydown",z)),(W,K)=>(y(),M("div",{class:Re(["qcard",{minimized:r.value}])},[C("div",{class:Re(["qh",{clickable:r.value}]),onClick:l},[u.value>1?(y(),M("span",KEe,N(i.value+1),1)):ee("",!0),C("span",ZEe,N(a.value.question),1),j(p(gn),{class:"qmin",size:"sm",label:r.value?p(o)("question.expand"):p(o)("question.minimize"),tooltip:r.value?p(o)("question.expand"):p(o)("question.minimize"),onClick:K[0]||(K[0]=It(V=>r.value=!r.value,["stop"]))},{default:me(()=>[r.value?(y(),he(p(Te),{key:0,name:"chevron-up",size:"md"})):(y(),he(p(Te),{key:1,name:"minus",size:"md"}))]),_:1},8,["label","tooltip"]),j(p(gn),{class:"qclose",size:"sm",label:p(o)("question.dismiss"),tooltip:p(o)("question.dismiss"),disabled:I.value,onClick:It(B,["stop"])},{default:me(()=>[j(p(Te),{name:"close",size:"md"})]),_:1},8,["label","tooltip","disabled"])],2),r.value?ee("",!0):(y(),M(Pe,{key:0},[C("div",GEe,[a.value.body?(y(),he(p(Ic),{key:0,text:a.value.body,class:"qmdbody"},null,8,["text"])):ee("",!0),C("div",YEe,[(y(!0),M(Pe,null,pt(a.value.options,(V,ie)=>(y(),M("label",{key:V.id,class:Re(["qopt",{selected:T(a.value.id,V.id),highlighted:a.value.multiSelect&&ie===H.value}]),onClick:It(ne=>{H.value=ie,a.value.multiSelect?b(a.value.id,V.id):w(a.value.id,V.id)},["prevent"])},[C("span",JEe,N(ie+1),1),C("span",{class:Re(["qopt-glyph",a.value.multiSelect?"chk":"rad"])},null,2),C("span",QEe,[C("span",eIe,N(V.label),1),V.description?(y(),M("span",tIe,N(V.description),1)):ee("",!0)])],10,XEe))),128)),a.value.allowOther?(y(),M("label",{key:0,class:Re(["qopt",{selected:A(a.value.id),highlighted:a.value.multiSelect&&H.value===a.value.options.length}]),onClick:K[6]||(K[6]=It(V=>{H.value=a.value.options.length,S(a.value.id)},["prevent"]))},[K[7]||(K[7]=C("span",{class:"qopt-key"},null,-1)),C("span",{class:Re(["qopt-glyph",a.value.multiSelect?"chk":"rad"])},null,2),C("span",nIe,N(a.value.otherLabel??p(o)("question.otherDefault")),1),Bn(C("input",{ref_key:"otherInputEl",ref:g,"onUpdate:modelValue":K[1]||(K[1]=V=>_.value[a.value.id]=V),class:"other-input",type:"text",placeholder:a.value.otherLabel??p(o)("question.otherDefault"),onInput:K[2]||(K[2]=V=>x(a.value.id)),onFocus:K[3]||(K[3]=V=>x(a.value.id)),onCompositionstart:K[4]||(K[4]=(...V)=>p(O)&&p(O)(...V)),onCompositionend:K[5]||(K[5]=(...V)=>p(F)&&p(F)(...V))},null,40,oIe),[[ai,_.value[a.value.id]]])],2)):ee("",!0)])]),C("div",sIe,[C("div",iIe,[i.value<u.value-1?(y(),he(p(Rt),{key:0,class:"qmain",size:"md",variant:"primary",disabled:!h(),onClick:d},{default:me(()=>[qe(N(p(o)("question.nextQuestion")),1)]),_:1},8,["disabled"])):(y(),he(p(Rt),{key:1,class:"qmain",size:"md",variant:"primary",disabled:!E(),loading:P.value,onClick:$},{default:me(()=>[qe(N(p(o)("question.submit")),1)]),_:1},8,["disabled","loading"])),u.value>1?(y(),he(p(Rt),{key:2,size:"md",variant:"ghost",disabled:i.value===0||I.value,onClick:c},{default:me(()=>[qe(N(p(o)("question.back")),1)]),_:1},8,["disabled"])):ee("",!0),j(p(Rt),{size:"md",variant:"ghost",loading:D.value,disabled:I.value,onClick:B},{default:me(()=>[qe(N(p(o)("question.dismiss")),1)]),_:1},8,["loading","disabled"])]),C("span",rIe,N(p(o)("question.hint")),1)])],64))],2))}}),aIe=ft(lIe,[["__scopeId","data-v-ca95f2cd"]]),uIe={class:"akind"},cIe={key:1,class:"apeek"},dIe={class:"ab"},fIe=["title"],pIe={class:"code-path"},hIe={key:2,class:"body-shell"},mIe={class:"shell-cmd"},gIe={key:0,class:"shell-cwd"},vIe={key:1,class:"shell-danger"},yIe={class:"code-path"},kIe={key:4,class:"body-chip"},bIe={class:"chip-label"},CIe={class:"chip-value"},wIe={key:0,class:"chip-detail"},_Ie={key:5,class:"body-chip"},xIe={key:0,class:"chip-label"},SIe={class:"chip-value"},AIe={key:6,class:"body-chip"},MIe={class:"chip-label"},TIe={class:"chip-value"},EIe={key:0,class:"chip-detail"},IIe={key:7,class:"body-chip"},LIe={class:"chip-label"},$Ie={class:"chip-value"},NIe={key:0,class:"chip-detail"},FIe={key:8,class:"body-todo"},RIe={class:"todo-glyph"},OIe={key:0,class:"plan-opts"},PIe=["disabled","onClick"],DIe={class:"popt-key"},BIe={class:"popt-text"},HIe={class:"popt-label"},zIe={key:0,class:"popt-desc"},WIe={key:10,class:"body-generic"},UIe={class:"gen-text"},jIe={key:11,class:"feedback-wrap"},VIe=["placeholder"],qIe={class:"feedback-hint"},KIe={class:"af"},ZIe={class:"abtns"},GIe={key:0,class:"knum"},YIe={key:0,class:"knum"},XIe=et({__name:"ApprovalCard",props:{block:{},agentName:{},busy:{type:Boolean},openFile:{type:Function}},emits:["decide"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>{const V=n.block;return V.kind!=="plan_review"?null:{plan:V.plan,path:V.path,options:V.options??[]}}),r=Z(!1),l=Z(null),a=Z(!1);function u(){a.value=(l.value?.scrollTop??0)>0}function c(V){a.value=V.target.scrollTop>0}const d=Z(!1),f=R(()=>{const V=n.block.kind;return V==="plan_review"||V==="diff"||V==="file"});function h(){r.value&&(r.value=!1)}const m=["shell","diff","file","fileop","url","search","invocation","todo","plan_review","generic"];function v(){return m.includes(n.block.kind)?n.block.kind:"generic"}function k(){return s(`approval.title.${v()}`)}const w=R(()=>{const V=n.block;switch(V.kind){case"diff":case"file":case"fileop":return V.path;case"shell":return V.command;case"url":return V.url;case"search":return V.query;case"invocation":return V.name;case"generic":return V.summary;default:return""}}),b=Z(!1),_=Z(""),g=Z(null);function x(){n.busy||(b.value=!0,_.value="",setTimeout(()=>g.value?.focus(),0))}function S(){if(n.busy)return;const V=_.value.trim();i.value?$("feedback",{decision:"rejected",selectedLabel:"Revise",feedback:V||void 0}):$("feedback",{decision:"rejected",feedback:V||void 0}),b.value=!1,_.value=""}function T(){n.busy||(b.value=!1,_.value="")}const{handleCompositionStart:A,handleCompositionEnd:E,isComposingKeyEvent:P}=Ar();function D(V){P(V)||(V.key==="Enter"&&!V.shiftKey?(V.preventDefault(),S()):V.key==="Escape"&&(V.preventDefault(),T()))}const I=Z(null);Je(()=>n.busy,V=>{V||(I.value=null)});function $(V,ie){n.busy||(I.value=V,o("decide",ie))}function B(){$("approve",{decision:"approved"})}function H(){$("approveSession",{decision:"approved",scope:"session"})}function O(){$("reject",{decision:"rejected"})}function F(){$("approvePlan",{decision:"approved"})}function U(V){$(`option:${V}`,{decision:"approved",selectedLabel:V})}function z(){n.busy||x()}function W(){$("rejectAndExit",{decision:"rejected",selectedLabel:"Reject and Exit"})}function K(V){const ie=(document.activeElement?.tagName??"").toLowerCase();if(ie==="input"||ie==="textarea"||V.metaKey||V.ctrlKey||V.altKey||Ci.value>0||V.defaultPrevented)return;if(b.value){V.key==="Escape"&&(V.preventDefault(),T());return}if(n.busy||r.value)return;const ne=i.value;if(ne){if(ne.options.length===0){V.key==="1"?(V.preventDefault(),F()):V.key==="2"?(V.preventDefault(),z()):V.key==="3"&&(V.preventDefault(),W());return}V.key==="1"&&ne.options[0]?(V.preventDefault(),U(ne.options[0].label)):V.key==="2"&&ne.options[1]?(V.preventDefault(),U(ne.options[1].label)):V.key==="3"&&ne.options[2]&&(V.preventDefault(),U(ne.options[2].label));return}V.key==="1"?(V.preventDefault(),B()):V.key==="2"?(V.preventDefault(),H()):V.key==="3"?(V.preventDefault(),O()):V.key==="4"&&(V.preventDefault(),x())}return dn(()=>document.addEventListener("keydown",K)),bn(()=>document.removeEventListener("keydown",K)),Dp(u),(V,ie)=>(y(),M("div",{class:Re(["appr",{minimized:r.value}])},[C("div",{class:Re(["ah",{clickable:r.value}]),onClick:h},[C("span",uIe,N(k()),1),e.agentName&&!r.value?(y(),he(p(Vr),{key:0,variant:"neutral",size:"sm"},{default:me(()=>[qe(N(p(s)("approval.subagentBadge",{name:e.agentName})),1)]),_:1})):ee("",!0),r.value&&w.value?(y(),M("span",cIe,N(w.value),1)):ee("",!0),f.value&&!r.value?(y(),he(p(gn),{key:2,class:"aexpand",size:"sm",label:d.value?p(s)("approval.collapsePlan"):p(s)("approval.expandPlan"),tooltip:d.value?p(s)("approval.collapsePlan"):p(s)("approval.expandPlan"),onClick:ie[0]||(ie[0]=ne=>d.value=!d.value)},{default:me(()=>[j(p(Te),{name:d.value?"collapse":"expand",size:"md"},null,8,["name"])]),_:1},8,["label","tooltip"])):ee("",!0),j(p(gn),{class:"amin",size:"sm",label:r.value?p(s)("question.expand"):p(s)("question.minimize"),tooltip:r.value?p(s)("question.expand"):p(s)("question.minimize"),onClick:ie[1]||(ie[1]=It(ne=>r.value=!r.value,["stop"]))},{default:me(()=>[r.value?(y(),he(p(Te),{key:0,name:"chevron-up",size:"md"})):(y(),he(p(Te),{key:1,name:"minus",size:"md"}))]),_:1},8,["label","tooltip"])],2),r.value?ee("",!0):(y(),M(Pe,{key:0},[C("div",dIe,[e.block.kind==="plan_review"&&e.block.path?(y(),M("button",{key:0,type:"button",class:"plan-path",title:e.block.path,onClick:ie[2]||(ie[2]=ne=>n.openFile?.({path:e.block.path,content:e.block.plan}))},N(e.block.path),9,fIe)):ee("",!0),e.block.kind==="diff"?(y(),M("div",{key:1,class:Re(["body-code",{expanded:d.value}])},[C("div",pIe,N(e.block.path),1),e.block.diff.length>0?(y(),he(Ur,{key:0,lines:e.block.diff,path:e.block.path},null,8,["lines","path"])):ee("",!0)],2)):e.block.kind==="shell"?(y(),M("div",hIe,[C("div",mIe,[ie[6]||(ie[6]=C("span",{class:"shell-dollar"},"$",-1)),qe(" "+N(e.block.command),1)]),e.block.cwd?(y(),M("div",gIe,"cwd: "+N(e.block.cwd),1)):ee("",!0),e.block.danger?(y(),M("div",vIe,[j(p(Te),{name:"alert-triangle",size:"sm",class:"shell-danger-ic"}),C("span",null,N(p(s)("approval.danger",{detail:e.block.danger})),1)])):ee("",!0)])):e.block.kind==="file"?(y(),M("div",{key:3,class:Re(["body-code",{expanded:d.value}])},[C("div",yIe,N(e.block.path),1),j(Ur,{code:e.block.content,path:e.block.path},null,8,["code","path"])],2)):e.block.kind==="fileop"?(y(),M("div",kIe,[C("span",bIe,N(e.block.op),1),C("span",CIe,N(e.block.path),1),e.block.detail?(y(),M("span",wIe,N(e.block.detail),1)):ee("",!0)])):e.block.kind==="url"?(y(),M("div",_Ie,[e.block.method?(y(),M("span",xIe,N(e.block.method),1)):ee("",!0),C("span",SIe,N(e.block.url),1)])):e.block.kind==="search"?(y(),M("div",AIe,[C("span",MIe,N(p(s)("approval.searchQueryLabel")),1),C("span",TIe,N(e.block.query),1),e.block.scope?(y(),M("span",EIe,N(p(s)("approval.searchScope",{scope:e.block.scope})),1)):ee("",!0)])):e.block.kind==="invocation"?(y(),M("div",IIe,[C("span",LIe,N(e.block.kind2),1),C("span",$Ie,N(e.block.name),1),e.block.description?(y(),M("span",NIe,N(e.block.description),1)):ee("",!0)])):e.block.kind==="todo"?(y(),M("div",FIe,[(y(!0),M(Pe,null,pt(e.block.items,(ne,X)=>(y(),M("div",{key:X,class:"todo-item"},[C("span",RIe,N(ne.status==="done"||ne.status==="completed"?"✓":"○"),1),C("span",{class:Re(["todo-title",{"todo-done":ne.status==="done"||ne.status==="completed"}])},N(ne.title),3)]))),128))])):e.block.kind==="plan_review"?(y(),M("div",{key:9,class:Re(["body-plan-wrap",{scrolled:a.value}])},[C("div",{ref_key:"planBodyEl",ref:l,class:Re(["body-plan",{expanded:d.value}]),onScroll:c},[j(p(Ic),{text:e.block.plan,"open-file":n.openFile},null,8,["text","open-file"])],34),i.value&&i.value.options.length>0?(y(),M("div",OIe,[(y(!0),M(Pe,null,pt(i.value.options,(ne,X)=>(y(),M("button",{key:X,type:"button",class:"popt",disabled:e.busy,onClick:le=>U(ne.label)},[C("span",DIe,N(X+1),1),C("span",BIe,[C("span",HIe,N(ne.label),1),ne.description?(y(),M("span",zIe,N(ne.description),1)):ee("",!0)]),I.value===`option:${ne.label}`?(y(),he(p(Ao),{key:0,size:"sm",class:"popt-spin"})):ee("",!0)],8,PIe))),128))])):ee("",!0)],2)):(y(),M("div",WIe,[C("span",UIe,N(e.block.summary),1)])),b.value?(y(),M("div",jIe,[Bn(C("textarea",{ref_key:"feedbackRef",ref:g,"onUpdate:modelValue":ie[3]||(ie[3]=ne=>_.value=ne),class:"feedback-ta",placeholder:p(s)("approval.feedbackPlaceholder"),rows:"2",onKeydown:D,onCompositionstart:ie[4]||(ie[4]=(...ne)=>p(A)&&p(A)(...ne)),onCompositionend:ie[5]||(ie[5]=(...ne)=>p(E)&&p(E)(...ne))},null,40,VIe),[[ai,_.value]]),C("div",qIe,N(p(s)("approval.feedbackHint")),1)])):ee("",!0)]),C("div",KIe,[C("div",ZIe,[b.value?(y(),M(Pe,{key:0},[j(p(Rt),{size:"md",variant:"danger-soft",loading:I.value==="feedback",disabled:e.busy,onClick:S},{default:me(()=>[qe(N(p(s)("approval.feedbackSubmit")),1)]),_:1},8,["loading","disabled"]),j(p(Rt),{size:"md",variant:"ghost",disabled:e.busy,onClick:T},{default:me(()=>[qe(N(p(s)("approval.feedbackCancel")),1)]),_:1},8,["disabled"])],64)):i.value?(y(),M(Pe,{key:1},[i.value.options.length===0?(y(),he(p(Rt),{key:0,class:"amain",size:"md",variant:"primary",loading:I.value==="approvePlan",disabled:e.busy,onClick:F},{default:me(()=>[ie[7]||(ie[7]=C("span",{class:"knum"},"1",-1)),qe(N(p(s)("approval.approvePlan")),1)]),_:1},8,["loading","disabled"])):ee("",!0),j(p(Rt),{size:"md",variant:"ghost",disabled:e.busy,onClick:z},{default:me(()=>[i.value.options.length===0?(y(),M("span",GIe,"2")):ee("",!0),qe(N(p(s)("approval.revise")),1)]),_:1},8,["disabled"]),j(p(Rt),{size:"md",variant:"ghost",loading:I.value==="rejectAndExit",disabled:e.busy,onClick:W},{default:me(()=>[i.value.options.length===0?(y(),M("span",YIe,"3")):ee("",!0),qe(N(p(s)("approval.rejectAndExit")),1)]),_:1},8,["loading","disabled"])],64)):(y(),M(Pe,{key:2},[j(p(Rt),{class:"amain",size:"md",variant:"primary",loading:I.value==="approve",disabled:e.busy,onClick:B},{default:me(()=>[ie[8]||(ie[8]=C("span",{class:"knum"},"1",-1)),qe(N(p(s)("approval.approve")),1)]),_:1},8,["loading","disabled"]),j(p(Rt),{size:"md",variant:"ghost",loading:I.value==="approveSession",disabled:e.busy,onClick:H},{default:me(()=>[ie[9]||(ie[9]=C("span",{class:"knum"},"2",-1)),qe(N(p(s)("approval.approveSession")),1)]),_:1},8,["loading","disabled"]),j(p(Rt),{size:"md",variant:"ghost",loading:I.value==="reject",disabled:e.busy,onClick:O},{default:me(()=>[ie[10]||(ie[10]=C("span",{class:"knum"},"3",-1)),qe(N(p(s)("approval.reject")),1)]),_:1},8,["loading","disabled"]),j(p(Rt),{size:"md",variant:"ghost",disabled:e.busy,onClick:x},{default:me(()=>[ie[11]||(ie[11]=C("span",{class:"knum"},"4",-1)),qe(N(p(s)("approval.feedback")),1)]),_:1},8,["disabled"])],64))])])],64))],2))}}),JIe=ft(XIe,[["__scopeId","data-v-cd852243"]]),QIe={class:"taskspane"},eLe={class:"tp-head"},tLe={class:"tp-title"},nLe={class:"tp-count"},oLe={class:"tp-list"},sLe={key:0,class:"tp-empty"},iLe=["role","onClick"],rLe={class:"tp-name"},lLe={key:0,class:"tp-model"},aLe={key:1,class:"tp-model"},uLe={class:"tp-time"},cLe=["onClick"],dLe={key:0,class:"tp-detail"},fLe={key:0,class:"tp-codebox"},pLe=["onClick"],hLe={class:"tp-pre"},mLe={class:"tp-cmd"},gLe={key:1,class:"tp-codebox"},vLe=["onClick"],yLe={class:"tp-pre"},kLe=et({__name:"TasksPane",props:{tasks:{}},emits:["cancel","open"],setup(e,{emit:t}){const n=t,{t:o}=Nt(),s=Go(new Set),i=Go(new Set),r=Go(new Set);function l(b){return!!(b.output&&b.output.length>0||b.meta)}function a(b){if(b.kind==="subagent"&&b.agentId){n("open",b.agentId);return}l(b)&&(s.has(b.id)?s.delete(b.id):s.add(b.id))}function u(b){return!!(b.kind==="subagent"&&b.agentId||l(b))}function c(b){return b==="run"||b==="done"||b==="fail"?b:"pending"}const d=nn("modelDisplay"),f=nn("subagentEffort");function h(b){if(b.kind==="subagent")return d?.(b.model)}function m(b){if(b.kind==="subagent")return f?.(b.thinkingEffort)}async function v(b,_,g){await Zs(b)&&(g.add(_),setTimeout(()=>g.delete(_),1500))}async function k(b){b.meta&&await v(b.meta,b.id,i)}async function w(b){const _=b.output?.join(` +`)??"";_&&await v(_,b.id,r)}return(b,_)=>(y(),M("div",QIe,[C("div",eLe,[C("span",tLe,N(p(o)("tasks.tag")),1),C("span",nLe,N(e.tasks.length),1)]),C("div",oLe,[e.tasks.length===0?(y(),M("div",sLe,N(p(o)("tasks.emptyTasks")),1)):(y(!0),M(Pe,{key:1},pt(e.tasks,g=>(y(),M("div",{key:g.id,class:Re(["tp-row",{done:g.state==="done",fail:g.state==="fail",expandable:u(g)}])},[C("div",{class:"tp-main",role:u(g)?"button":void 0,onClick:x=>a(g)},[j(Y5,{status:c(g.state)},null,8,["status"]),C("span",rLe,N(g.name),1),j(p(Vr),{variant:"neutral",size:"sm"},{default:me(()=>[qe(N(g.kind),1)]),_:2},1024),h(g)?(y(),M("span",lLe,N(h(g)),1)):ee("",!0),m(g)?(y(),M("span",aLe,N(m(g)),1)):ee("",!0),C("span",uLe,N(g.timing),1),g.state==="run"?(y(),M("button",{key:2,class:"tp-stop",onClick:It(x=>n("cancel",g.id),["stop"])},N(p(o)("tasks.stop")),9,cLe)):ee("",!0),g.kind==="subagent"&&g.agentId?(y(),he(p(Te),{key:3,class:"tp-chevron",name:"chevron-right",size:"sm"})):l(g)?(y(),he(p(Te),{key:4,class:Re(["tp-chevron",{open:s.has(g.id)}]),name:"chevron-right",size:"sm"},null,8,["class"])):ee("",!0)],8,iLe),s.has(g.id)&&l(g)?(y(),M("div",dLe,[g.meta?(y(),M("div",fLe,[C("button",{class:Re(["tp-copy",{copied:i.has(g.id)}]),onClick:It(x=>k(g),["stop"])},N(i.has(g.id)?p(o)("tasks.copied"):p(o)("tasks.copy")),11,pLe),C("pre",hLe,[C("code",null,[C("span",mLe,N(g.meta),1)])])])):ee("",!0),g.output&&g.output.length>0?(y(),M("div",gLe,[C("button",{class:Re(["tp-copy",{copied:r.has(g.id)}]),onClick:It(x=>w(g),["stop"])},N(r.has(g.id)?p(o)("tasks.copied"):p(o)("tasks.copy")),11,vLe),C("pre",yLe,[C("code",null,[_[0]||(_[0]=qe(` + `,-1)),(y(!0),M(Pe,null,pt(g.output,(x,S)=>(y(),M("span",{key:S,class:"tp-line"},N(x),1))),128)),_[1]||(_[1]=qe(` + `,-1))])])])):ee("",!0)])):ee("",!0)],2))),128))])]))}}),bS=ft(kLe,[["__scopeId","data-v-e5e66edb"]]),bLe={class:"todo-card"},CLe={key:0,class:"tc-empty"},wLe={class:"tc-name"},_Le=et({__name:"TodoCard",props:{todos:{}},setup(e){const t=e,{t:n}=Nt();function o(s){return s==="in_progress"?"run":s}return(s,i)=>(y(),M("div",bLe,[t.todos.length===0?(y(),M("div",CLe,[i[0]||(i[0]=C("svg",{class:"tc-empty-ico",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.6","stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},[C("path",{d:"M9 11l2 2 4-4"}),C("rect",{x:"4",y:"4",width:"16",height:"16",rx:"3"})],-1)),C("span",null,N(p(n)("tasks.emptyTodo")),1)])):ee("",!0),(y(!0),M(Pe,null,pt(t.todos,(r,l)=>(y(),M("div",{key:l,class:Re(["tc-row",`s-${r.status}`])},[j(Y5,{status:o(r.status)},null,8,["status"]),C("span",wLe,N(r.title),1)],2))),128))]))}}),xLe=ft(_Le,[["__scopeId","data-v-01c65735"]]),SLe={class:"dock-work-head"},ALe={key:0,class:"dock-work-tab static"},MLe={key:1,class:"dock-work-tab static"},TLe={key:2,class:"dock-work-tab static"},ELe={key:3,class:"dock-work-tab static"},ILe={key:4,class:"dock-work-head-actions"},LLe={key:0,class:"dock-work-foot"},$Le={key:0},NLe={key:1},FLe={key:0,class:"dock-workbar"},RLe={class:"dw-count"},OLe={class:"dw-count"},PLe={class:"dw-count"},DLe=et({__name:"ChatDock",props:{sessionId:{},running:{type:Boolean},working:{type:Boolean},starting:{type:Boolean},queued:{},searchFiles:{type:Function},uploadImage:{type:Function},status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},goalMode:{type:Boolean},activationBadges:{},models:{},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{},skills:{},goal:{},dockPanel:{},bashTasks:{},subagentTasks:{},bashRunning:{},subagentRunning:{},todoDoneCount:{},hasDockWork:{type:Boolean},todos:{},pendingQuestion:{},questionBusyKind:{},pendingApproval:{},approvalBusy:{type:Boolean},openFile:{type:Function},mobile:{type:Boolean}},emits:["submit","steer","command","interrupt","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","openBtw","createGoal","controlGoal","focusGoal","focusSwarm","compact","pickModel","selectModel","login","answer","dismiss","approval","cancelTask","toggle-dock-panel","close-dock-panel","openAgent"],setup(e,{expose:t,emit:n}){const o=e,s=n,{t:i}=Nt(),{confirm:r}=hu(),l=R(()=>{switch(o.goal?.status){case"active":return i("status.goalStatusActive");case"paused":return i("status.goalStatusPaused");case"blocked":return i("status.goalStatusBlocked");case"complete":return i("status.goalStatusComplete");default:return""}}),a=R(()=>{const I=o.goal?.budget.tokenBudget;return!o.goal||!I||I<=0?0:Math.max(0,Math.min(100,Math.round(o.goal.tokensUsed/I*100)))}),u=R(()=>o.goal?vc(o.goal.wallClockMs):"");async function c(){await r({title:i("status.goalCancel"),message:i("status.goalCancelConfirm"),confirmLabel:i("status.goalCancelConfirmYes"),cancelLabel:i("status.goalCancelConfirmNo"),variant:"danger"})&&s("controlGoal","cancel")}const d=Z(null),f=R(()=>d.value?.anyPopupOpen===!0),h=Z(null),m=Z(null);function v(I){return d.value?(d.value.loadForEdit(I),!0):!1}function k(I){d.value?.loadAttachmentsForEdit(I)}function w(){d.value?.focus()}const b=()=>d.value?.isEmpty?.()??!1;function _(I){if(!o.dockPanel)return;const $=I.target;$&&(h.value?.contains($)||$ instanceof Element&&$.closest(".ui-pill")||s("close-dock-panel"))}const g=Z(null),x=Z(!1),S=Z(!1);function T(){const I=g.value;if(!I){x.value=!1,S.value=!1;return}x.value=I.scrollTop>0,S.value=I.scrollTop+I.clientHeight<I.scrollHeight-1}function A(I){const $=I.target;x.value=$.scrollTop>0,S.value=$.scrollTop+$.clientHeight<$.scrollHeight-1}let E=null;Je(()=>o.dockPanel,async I=>{typeof document<"u"&&(document.removeEventListener("mousedown",_,!0),I&&document.addEventListener("mousedown",_,!0)),E?.disconnect(),E=null,I?(await yt(),T(),typeof ResizeObserver=="function"&&g.value&&(E=new ResizeObserver(T),E.observe(g.value))):(x.value=!1,S.value=!1)},{immediate:!0});let P=null;function D(){const I=m.value?.offsetHeight??0;document.documentElement.style.setProperty("--dock-h",`${I}px`)}return dn(()=>{typeof ResizeObserver!="function"||!m.value||(P=new ResizeObserver(D),P.observe(m.value),D())}),bn(()=>{typeof document<"u"&&document.removeEventListener("mousedown",_,!0),P?.disconnect(),P=null,E?.disconnect(),E=null}),t({loadForEdit:v,loadAttachmentsForEdit:k,focus:w,anyPopupOpen:f,isEmpty:b}),(I,$)=>(y(),M("div",{ref_key:"dockRef",ref:m,class:Re(["chat-dock",[e.mobile?"align-mobile":"align-center",{"has-popup":f.value,"has-approval":!!e.pendingApproval&&!e.pendingQuestion}]]),onClick:$[31]||($[31]=It(()=>{},["stop"]))},[j(as,{name:"dock-panel"},{default:me(()=>[e.dockPanel?(y(),M("div",{key:0,ref_key:"workPanelRef",ref:h,class:Re(["dock-work-panel",{"body-scrolled-up":x.value,"body-scrolled-down":S.value}]),onClick:$[5]||($[5]=It(()=>{},["stop"]))},[C("div",SLe,[e.dockPanel==="bash"?(y(),M("span",ALe,N(p(i)("tasks.dockBash"))+" · "+N(e.bashRunning)+" "+N(p(i)("tasks.running")),1)):e.dockPanel==="subagent"?(y(),M("span",MLe,N(p(i)("tasks.dockSubagent"))+" · "+N(e.subagentRunning)+" "+N(p(i)("tasks.running")),1)):e.dockPanel==="todos"?(y(),M("span",TLe,N(p(i)("tasks.dockTodos"))+" · "+N(e.todoDoneCount)+"/"+N(e.todos?.length??0),1)):e.dockPanel==="goal"?(y(),M("span",ELe,N(p(i)("status.goalLabel"))+" · "+N(l.value),1)):ee("",!0),e.dockPanel==="goal"&&e.goal?(y(),M("span",ILe,[e.goal.status==="active"?(y(),he(p(Rt),{key:0,size:"sm",variant:"secondary",class:"dock-goal-action",onClick:$[0]||($[0]=It(B=>s("controlGoal","pause"),["stop"]))},{default:me(()=>[j(p(Te),{name:"pause",size:"md"}),C("span",null,N(p(i)("status.goalPause")),1)]),_:1})):ee("",!0),e.goal.status==="paused"||e.goal.status==="blocked"?(y(),he(p(Rt),{key:1,size:"sm",variant:"primary",class:"dock-goal-action",onClick:$[1]||($[1]=It(B=>s("controlGoal","resume"),["stop"]))},{default:me(()=>[j(p(Te),{name:"play",size:"md"}),C("span",null,N(p(i)("status.goalResume")),1)]),_:1})):ee("",!0),j(p(Rt),{size:"sm",variant:"danger-soft",class:"dock-goal-action",onClick:It(c,["stop"])},{default:me(()=>[j(p(Te),{name:"close",size:"md"}),C("span",null,N(p(i)("status.goalCancel")),1)]),_:1})])):ee("",!0)]),C("div",{ref_key:"workBodyRef",ref:g,class:"dock-work-body",onScroll:A},[e.dockPanel==="bash"?(y(),he(bS,{key:0,tasks:e.bashTasks,onCancel:$[2]||($[2]=B=>s("cancelTask",B))},null,8,["tasks"])):e.dockPanel==="subagent"?(y(),he(bS,{key:1,tasks:e.subagentTasks,onCancel:$[3]||($[3]=B=>s("cancelTask",B)),onOpen:$[4]||($[4]=B=>s("openAgent",B))},null,8,["tasks"])):e.dockPanel==="todos"?(y(),he(xLe,{key:2,todos:e.todos??[]},null,8,["todos"])):e.dockPanel==="goal"&&e.goal?(y(),he(qEe,{key:3,goal:e.goal},null,8,["goal"])):ee("",!0)],544),e.dockPanel==="goal"&&e.goal?(y(),M("div",LLe,[C("span",null,N(e.goal.turnsUsed)+" turns",1),C("span",null,N(p(Al)(e.goal.tokensUsed))+" tokens",1),u.value?(y(),M("span",$Le,N(u.value),1)):ee("",!0),e.goal.budget.tokenBudget!==null?(y(),M("span",NLe,N(a.value)+"% token budget",1)):ee("",!0)])):ee("",!0)],2)):ee("",!0)]),_:1}),e.hasDockWork?(y(),M("div",FLe,[e.goal?(y(),he(p(G0),{key:0,active:e.dockPanel==="goal","aria-pressed":e.dockPanel==="goal",onClick:$[6]||($[6]=B=>s("toggle-dock-panel","goal"))},{default:me(()=>[j(p(Te),{name:"target",size:"md"}),C("span",null,N(p(i)("status.goalLabel")),1),C("span",{class:Re(["dw-goal-status",`dw-goal-status--${e.goal.status}`])},N(l.value),3)]),_:1},8,["active","aria-pressed"])):ee("",!0),e.bashTasks.length>0?(y(),he(p(G0),{key:1,active:e.dockPanel==="bash","aria-pressed":e.dockPanel==="bash",onClick:$[7]||($[7]=B=>s("toggle-dock-panel","bash"))},{default:me(()=>[j(p(Te),{name:"clock",size:"md"}),C("span",null,N(p(i)("tasks.dockBash")),1),C("span",RLe,[$[32]||($[32]=qe("(",-1)),C("b",null,N(e.bashTasks.length),1),$[33]||($[33]=qe(")",-1))])]),_:1},8,["active","aria-pressed"])):ee("",!0),e.subagentTasks.length>0?(y(),he(p(G0),{key:2,active:e.dockPanel==="subagent","aria-pressed":e.dockPanel==="subagent",onClick:$[8]||($[8]=B=>s("toggle-dock-panel","subagent"))},{default:me(()=>[j(p(Te),{name:"sparkles",size:"md"}),C("span",null,N(p(i)("tasks.dockSubagent")),1),C("span",OLe,[$[34]||($[34]=qe("(",-1)),C("b",null,N(e.subagentTasks.length),1),$[35]||($[35]=qe(")",-1))])]),_:1},8,["active","aria-pressed"])):ee("",!0),(e.todos?.length??0)>0?(y(),he(p(G0),{key:3,active:e.dockPanel==="todos","aria-pressed":e.dockPanel==="todos",onClick:$[9]||($[9]=B=>s("toggle-dock-panel","todos"))},{default:me(()=>[j(p(Te),{name:"check-list",size:"md"}),C("span",null,N(p(i)("tasks.dockTodos")),1),C("span",PLe,[$[36]||($[36]=qe("(",-1)),C("b",null,N(e.todoDoneCount)+"/"+N(e.todos?.length??0),1),$[37]||($[37]=qe(")",-1))])]),_:1},8,["active","aria-pressed"])):ee("",!0)])):ee("",!0),e.pendingQuestion?(y(),he(aIe,{key:e.pendingQuestion.questionId,question:e.pendingQuestion,"busy-kind":e.questionBusyKind,onAnswer:$[10]||($[10]=(B,H)=>s("answer",B,H)),onDismiss:$[11]||($[11]=B=>s("dismiss",B))},null,8,["question","busy-kind"])):e.pendingApproval?(y(),he(JIe,{key:e.pendingApproval.approvalId,class:"dock-approval",block:e.pendingApproval.block,"agent-name":e.pendingApproval.agentName,busy:e.approvalBusy,"open-file":e.openFile,onDecide:$[12]||($[12]=B=>s("approval",e.pendingApproval.approvalId,B))},null,8,["block","agent-name","busy","open-file"])):(y(),he(mF,{key:3,ref_key:"composerRef",ref:d,"session-id":e.sessionId,running:e.running,working:e.working,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,goal:e.goal,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,starting:e.starting,onSubmit:$[13]||($[13]=B=>s("submit",B)),onSteer:$[14]||($[14]=B=>s("steer",B)),onCommand:$[15]||($[15]=B=>s("command",B)),onInterrupt:$[16]||($[16]=B=>s("interrupt")),onSetPermission:$[17]||($[17]=B=>s("setPermission",B)),onSetThinking:$[18]||($[18]=B=>s("setThinking",B)),onTogglePlan:$[19]||($[19]=B=>s("togglePlan")),onToggleSwarm:$[20]||($[20]=B=>s("toggleSwarm")),onToggleGoal:$[21]||($[21]=B=>s("toggleGoal")),onOpenBtw:$[22]||($[22]=B=>s("openBtw")),onCreateGoal:$[23]||($[23]=B=>s("createGoal",B)),onControlGoal:$[24]||($[24]=B=>s("controlGoal",B)),onFocusGoal:$[25]||($[25]=B=>s("focusGoal")),onFocusSwarm:$[26]||($[26]=B=>s("focusSwarm")),onCompact:$[27]||($[27]=B=>s("compact")),onPickModel:$[28]||($[28]=B=>s("pickModel")),onSelectModel:$[29]||($[29]=B=>s("selectModel",B)),onLogin:$[30]||($[30]=B=>s("login"))},null,8,["session-id","running","working","queued","search-files","upload-image","status","thinking","plan-mode","swarm-mode","goal-mode","goal","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","starting"]))],2))}}),BLe=ft(DLe,[["__scopeId","data-v-6f1ea685"]]),HLe=["aria-label","aria-hidden"],zLe={class:"toc-scroll"},WLe=["onClick"],ULe={class:"toc-label"},jLe=240,VLe=et({__name:"ConversationToc",props:{items:{},activeTurnId:{},mobile:{type:Boolean},sessionLoading:{type:Boolean},occluded:{type:Boolean}},emits:["select"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=Z(null),r=Z(!0);let l=null;function a(){const c=i.value,d=c?.offsetParent;if(!c||!d)return;const f=c.getBoundingClientRect().left,h=d.getBoundingClientRect().right;r.value=h-f>=jLe}const u=R(()=>!n.mobile&&!n.sessionLoading&&n.items.length>1);return Je(u,c=>{l?.disconnect(),l=null,c&&yt(()=>{const d=i.value,f=d?.offsetParent;!d||!f||(typeof ResizeObserver<"u"&&(l=new ResizeObserver(a),l.observe(f)),a())})},{immediate:!0}),Vn(()=>{l?.disconnect(),l=null}),(c,d)=>u.value?(y(),M("nav",{key:0,ref_key:"navRef",ref:i,class:Re(["conversation-toc",{"toc-clipped":!r.value||e.occluded}]),"aria-label":p(s)("conversation.toc"),"aria-hidden":r.value&&!e.occluded?void 0:!0},[C("div",zLe,[(y(!0),M(Pe,null,pt(e.items,f=>(y(),M("button",{key:f.id,type:"button",class:Re(["toc-row",{active:e.activeTurnId===f.id}]),onClick:h=>o("select",f.id)},[d[0]||(d[0]=C("span",{class:"toc-bar"},null,-1)),C("span",ULe,N(f.title),1)],10,WLe))),128))])],10,HLe)):ee("",!0)}}),qLe=ft(VLe,[["__scopeId","data-v-b8ba267a"]]),KLe={class:"tsearch-main"},ZLe=["placeholder"],GLe={key:0,class:"tsearch-spin"},YLe=["inert"],XLe={class:"tsearch-foot"},JLe={class:"tsearch-count",role:"status"},QLe={class:"tsearch-rings","aria-hidden":"true"},e$e=800,t$e=400,n$e=1500,o$e=et({__name:"TranscriptSearch",props:{pane:{},reveal:{},mobile:{type:Boolean,default:!1}},emits:["close"],setup(e,{expose:t,emit:n}){const o=e,s=n,{t:i}=Nt(),{handleCompositionStart:r,handleCompositionEnd:l,isComposingKeyEvent:a}=Ar(),u=Z(""),c=Z(!1),d=Z([]),f=Z(0),h=Z(null),m=R(()=>d.value.length),v=R(()=>u.value.trim()!==""&&!c.value),k=Z(!1),w=R(()=>{if(m.value===0)return i("conversation.search.noResults");const V={current:f.value+1,total:m.value};return k.value?i("conversation.search.resultsCapped",V):i("conversation.search.results",V)});let b=null,_=null,g=null,x=null,S=null,T=0;const A=Z([]);function E(){const V=o.pane,ie=d.value[f.value];if(!V||ie===void 0){A.value=[];return}const ne=V.getBoundingClientRect(),X=[];for(const le of ie.getClientRects())X.push({top:`${le.top-ne.top+V.scrollTop}px`,left:`${le.left-ne.left}px`,width:`${le.width}px`,height:`${le.height}px`});A.value=X}function P(V,ie){return V.type==="attributes"&&V.target===ie?!0:D(V)}function D(V){const ie=ne=>ne instanceof Element&&(ne.classList.contains("tsearch-rings")||ne.closest(".tsearch-rings")!==null);if(ie(V.target))return!0;if(V.type==="childList"){const ne=[...V.addedNodes,...V.removedNodes];if(ne.length>0&&ne.every(ie))return!0}return!1}function I(){A.value.length!==0&&(S!==null&&clearTimeout(S),S=setTimeout(()=>{S=null,E()},120))}function $(){return o.pane?.querySelector(".chat")??null}function B(){if(b!==null&&(clearTimeout(b),b=null),u.value.trim()===""){c.value=!1,H();return}c.value=!0,b=setTimeout(H,e$e)}function H(V="first"){b!==null&&(clearTimeout(b),b=null),c.value=!1;const ie=$();if(u.value.trim()===""||ie===null){d.value=[],k.value=!1,f.value=0,E3(),E();return}const ne=d.value[f.value],X=ne?.startContainer??null,le=ne?.startOffset??0,Ie=PQ(ie,u.value.trim()),de=Ie.ranges;if(k.value=Ie.truncated,d.value=de,de.length===0){f.value=0,h9([],0),E();return}if(V!==!1){const ve=O(de);f.value=V==="backward"?(ve-1+de.length)%de.length:ve,F();return}const pe=X!==null?de.findIndex(ve=>ve.startContainer===X&&ve.startOffset===le):-1;f.value=pe>=0?pe:O(de),h9(de,f.value),E()}function O(V){const ie=o.pane?.getBoundingClientRect().top??0,ne=V.findIndex(X=>{const le=X.getClientRects(),Ie=le[le.length-1];return Ie!==void 0&&Ie.bottom>=ie});return ne===-1?0:ne}function F(){const V=d.value[f.value];h9(d.value,f.value),V!==void 0&&o.reveal(V),E()}function U(V){m.value!==0&&(f.value=(f.value+V+m.value)%m.value,F())}function z(V){if(V.key==="Enter"&&!a(V)){if(V.preventDefault(),b!==null){H(V.shiftKey?"backward":"first");return}U(V.shiftKey?-1:1)}}function W(V){V.key==="Escape"&&(a(V)||(V.preventDefault(),V.stopPropagation(),s("close")))}function K(){const V=h.value;V&&(V.focus(),V.select())}return t({focusInput:K}),dn(()=>{yt(()=>h.value?.focus()),o.pane&&typeof MutationObserver=="function"&&(g=new MutationObserver(ie=>{if(u.value.trim()!==""&&!ie.every(ne=>P(ne,o.pane))&&b===null){if(Date.now()-T>=n$e){T=Date.now(),_!==null&&(clearTimeout(_),_=null),H(!1);return}_!==null&&clearTimeout(_),_=setTimeout(()=>{_=null,b===null&&(T=Date.now(),H(!1))},t$e)}}),g.observe(o.pane,{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["inert","style","class"]})),o.pane?.addEventListener("scroll",I,{passive:!0});const V=[o.pane,o.pane?.querySelector(".content-wrap")??null];if(typeof ResizeObserver=="function"){x=new ResizeObserver(()=>E());for(const ie of V)ie&&x.observe(ie)}}),bn(()=>{b!==null&&clearTimeout(b),_!==null&&clearTimeout(_),S!==null&&clearTimeout(S),g?.disconnect(),g=null,x?.disconnect(),x=null,o.pane?.removeEventListener("scroll",I),E3()}),(V,ie)=>(y(),M("div",{class:Re(["tsearch",{mobile:e.mobile}]),role:"search",onKeydown:W},[C("div",KLe,[j(p(Te),{class:"tsearch-icon",name:"search",size:"sm","aria-hidden":"true"}),Bn(C("input",{ref_key:"inputRef",ref:h,"onUpdate:modelValue":ie[0]||(ie[0]=ne=>u.value=ne),type:"text",class:"tsearch-input",placeholder:p(i)("conversation.search.placeholder"),autocapitalize:"off",autocomplete:"off",spellcheck:"false",onInput:B,onKeydown:z,onCompositionstart:ie[1]||(ie[1]=(...ne)=>p(r)&&p(r)(...ne)),onCompositionend:ie[2]||(ie[2]=(...ne)=>p(l)&&p(l)(...ne))},null,40,ZLe),[[ai,u.value]]),c.value?(y(),M("span",GLe,[j(p(Ao),{size:"sm",label:p(i)("conversation.search.searching")},null,8,["label"])])):ee("",!0),ie[6]||(ie[6]=C("span",{class:"tsearch-sep","aria-hidden":"true"},null,-1)),j(p(gn),{class:"tsearch-close",size:"sm",label:p(i)("conversation.search.close"),tooltip:p(i)("conversation.search.close"),onClick:ie[3]||(ie[3]=ne=>s("close"))},{default:me(()=>[j(p(Te),{name:"close"})]),_:1},8,["label","tooltip"])]),C("div",{class:Re(["tsearch-foot-wrap",{open:v.value}]),inert:!v.value},[C("div",XLe,[j(p(gn),{size:"sm",label:p(i)("conversation.search.previous"),tooltip:p(i)("conversation.search.previous"),disabled:m.value===0,onClick:ie[4]||(ie[4]=ne=>U(-1))},{default:me(()=>[j(p(Te),{name:"arrow-up"})]),_:1},8,["label","tooltip","disabled"]),j(p(gn),{size:"sm",label:p(i)("conversation.search.next"),tooltip:p(i)("conversation.search.next"),disabled:m.value===0,onClick:ie[5]||(ie[5]=ne=>U(1))},{default:me(()=>[j(p(Te),{name:"arrow-down"})]),_:1},8,["label","tooltip","disabled"]),C("span",JLe,N(w.value),1)])],10,YLe),e.pane?(y(),he(Zr,{key:0,to:e.pane},[C("div",QLe,[(y(!0),M(Pe,null,pt(A.value,(ne,X)=>(y(),M("div",{key:X,class:"tsearch-ring",style:Zt(ne)},null,4))),128))])],8,["to"])):ee("",!0)],34))}}),s$e=ft(o$e,[["__scopeId","data-v-26f3fed5"]]),i$e="/assets/k3_doodle1-27EZ2HSw.riv",r$e={class:"doodle-host"},l$e={key:0,class:"doodle-fallback"},a$e=et({__name:"KimiDoodle",setup(e){const t=Z(!1),n=Z(null),o=f2();let s=null;return dn(async()=>{if(!window.matchMedia("(prefers-reduced-motion: reduce)").matches)try{let i=function(){const m=d.stateMachineNames[0];if(!m)return;const v=(d.stateMachineInputs(m)??[]).find(k=>k.name==="light/dark");v&&(v.value=o.value?1:0)};const[{Rive:r,RuntimeLoader:l},a,u]=await Promise.all([jo(()=>import("./rive-CeXCFBdn.js").then(m=>m.r),__vite__mapDeps([10,3])),jo(()=>import("./rive-BxcgqsjB.js"),[]).then(m=>m.default),jo(()=>import("./rive_fallback-ByshBW-N.js"),[]).then(m=>m.default)]),c=n.value;if(!c)return;l.setWasmUrl(a),l.setWasmFallbackUrl(u);const d=new r({canvas:c,src:i$e,autoplay:!0,onLoad(){const m=d.stateMachineNames[0];m&&d.play(m),requestAnimationFrame(()=>{n.value&&(i(),d.resizeDrawingSurfaceToCanvas(),t.value=!0)})}}),f=Je(o,i),h=()=>d.resizeDrawingSurfaceToCanvas();window.addEventListener("resize",h),s=()=>{f(),window.removeEventListener("resize",h),d.cleanup()}}catch{}}),Vn(()=>{s?.(),s=null}),(i,r)=>(y(),M("div",r$e,[t.value?ee("",!0):(y(),M("div",l$e,[xn(i.$slots,"fallback",{},void 0,!0)])),C("canvas",{ref_key:"canvasRef",ref:n,class:Re(["doodle-canvas",{ready:t.value}]),role:"img","aria-label":"Kimi"},null,2)]))}}),u$e=ft(a$e,[["__scopeId","data-v-b7d865dd"]]),c$e={class:"empty-hint"},d$e={class:"empty-hint-title"},f$e={key:1,class:"empty-hint-title is-starting"},p$e={key:2,class:"empty-hint-text"},h$e={key:0,class:"upgrade-banner"},m$e={class:"upgrade-banner-text"},g$e={class:"ws-bar"},v$e={key:0,class:"ws-anchor"},y$e=["aria-expanded"],k$e={class:"ws-chip-name"},b$e={class:"ws-caption"},C$e=["onClick"],w$e={class:"ws-info"},_$e={class:"ws-name"},x$e={class:"ws-path"},S$e=["aria-label"],A$e={key:0,class:"undo-toast",role:"status","aria-live":"polite"},M$e={class:"undo-toast-text"},T$e=48,ff=80,CS=1e3,E$e=420,I$e=3e3,L$e=5e3,$$e=1e4,N$e=2500,F$e=et({__name:"ConversationPane",props:{turns:{},sessionId:{},approvals:{},gitInfo:{},tasks:{},todos:{},goal:{},activationBadges:{},status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},goalMode:{type:Boolean},questions:{},pendingQuestionActions:{},pendingApprovalActions:{},running:{type:Boolean},turnActive:{type:Boolean},queued:{},searchFiles:{type:Function},uploadImage:{type:Function},changes:{},fileReloadKey:{},working:{type:Boolean},lastTurnReason:{},turnError:{},turnRetry:{},overlayOpen:{type:Boolean},starting:{type:Boolean},mobile:{type:Boolean},sessionLoading:{type:Boolean},compaction:{},hasMoreMessages:{type:Boolean},loadingMore:{type:Boolean},loadingMoreError:{type:Boolean},loadOlderMessages:{type:Function},models:{},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{},skills:{},workspaceName:{},workspaceRoot:{},gitDiffStats:{},workspaces:{},activeWorkspaceId:{},sessionTitle:{},pr:{}},emits:["submit","steer","approval","cancelTask","answer","dismiss","command","interrupt","unqueue","editQueued","reorderQueue","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","createGoal","controlGoal","compact","pickModel","selectModel","login","openFile","openMedia","openTurnDiff","openCompaction","openAgent","openChanges","refreshGitStatus","editMessage","selectWorkspace","addWorkspace","openPr","renameSession","forkSession","archiveSession","exportSession"],setup(e,{expose:t,emit:n}){const{t:o}=Nt(),s=e,i=n,r=Z(!1),l=Z(!1),a=Z(null),u=R(()=>s.workspaces?.find(Ae=>Ae.id===s.activeWorkspaceId)?.name??s.workspaceName??""),c=R(()=>(s.workspaces?.length??0)>0),d=R(()=>s.authReady===!1&&(s.models?.length??0)===0&&s.managedSignedIn===!0&&s.managedMembership==="free"),f=R(()=>qQ(s.workspaces??[],s.activeWorkspaceId));function h(ke){if(r.value){r.value=!1;return}const Ae=ke.currentTarget?.closest(".ws-anchor"),Ke=Ae?.closest(".panes");if(Ae instanceof HTMLElement&&Ke instanceof HTMLElement){const Mt=Ae.getBoundingClientRect(),Gt=Ke.getBoundingClientRect(),an=Gt.bottom-Mt.bottom-4,Fn=Mt.top-Gt.top-4;l.value=Fn>an;const so=Math.max(0,Math.floor(l.value?Fn:an));a.value=`min(calc(var(--space-8) * 10), ${so}px)`}else l.value=!1,a.value=null;r.value=!0}function m(ke){r.value=!1,ke!==s.activeWorkspaceId&&i("selectWorkspace",ke)}ur(cn.contentAlign);const v=Z(null),k=Z(null),w=Z(null),b=Z(!1);let _=null;function g(ke,Ae){const Ke=w.value??k.value;return!Ke||Ke.loadForEdit(ke)===!1?!1:(Ke.loadAttachmentsForEdit(Ae??[]),!0)}function x(){b.value=!0,_!==null&&clearTimeout(_),_=setTimeout(()=>{_=null,b.value=!1},2e3)}const S=R(()=>s.tasks.filter(ke=>ke.kind!=="subagent")),T=R(()=>s.tasks.filter(ke=>ke.kind==="subagent"&&ke.runInBackground)),A=R(()=>S.value.filter(ke=>ke.state==="run").length),E=R(()=>T.value.filter(ke=>ke.state==="run").length);function P(ke){const Ae=s.tasks,Ke=Ae.find(Gt=>Gt.id===ke)??Ae.find(Gt=>Gt.parentToolCallId===ke);if(Ke?.agentId)return Ke.agentId;const Mt=Ae.filter(Gt=>Gt.kind==="subagent"&&!Gt.parentToolCallId&&Gt.agentId);if(Mt.length===1)return Mt[0].agentId}Ln("resolveAgentTaskId",P);const D=nn("modelDisplay"),I=nn("subagentEffort");function $(ke,Ae){const Ke=Ae??P(ke);if(Ke===void 0)return;const Mt=s.tasks.find(Fn=>Fn.agentId===Ke||Fn.id===Ke),Gt=D?.(Mt?.model),an=I?.(Mt?.thinkingEffort);if(!(Gt===void 0&&an===void 0))return{display:Gt,effort:an}}Ln("resolveAgentModel",$),Ln("pinScroll",Ko);const B=R(()=>(s.todos??[]).filter(ke=>ke.status==="done").length),H=R(()=>s.goal!=null||S.value.length>0||T.value.length>0||(s.todos?.length??0)>0||(s.queued?.length??0)>0),O=Z(null),F=R(()=>s.gitInfo?s.changes?.length??0:0);function U(ke){O.value=O.value===ke?null:ke}function z(){O.value=null}function W(){s.goal&&(O.value="goal")}Je(()=>[s.goal,S.value.length,T.value.length,s.todos?.length],()=>{const ke=O.value;if(ke===null)return;ke==="goal"&&s.goal!=null||ke==="bash"&&S.value.length>0||ke==="subagent"&&T.value.length>0||ke==="todos"&&(s.todos?.length??0)>0||z()});function K(ke){if(ke.role==="compaction")return o("conversation.compactedPlain");if(ke.role==="user"){if(ke.skillActivation)return`/${ke.skillActivation.name}`;if(ke.pluginCommand)return`/${ke.pluginCommand.pluginId}:${ke.pluginCommand.commandName}`;const Ke=ke.text.trim().replaceAll(/\s+/g," ");return Ke.length>0?Ke:"user"}const Ae=(ke.text||ke.thinking||"").trim().replaceAll(/\s+/g," ");return Ae.length>0?Ae:(ke.tools?.length??0)>0?`${ke.tools.length} tools`:"kimi"}const V=R(()=>s.turns.filter(ke=>ke.role==="user").map((ke,Ae)=>({id:ke.id,role:ke.role,no:Ae+1,title:K(ke)}))),ie=Z(null);function ne(){const ke=te.value;if(!ke)return;const Ae=V.value;if(Ae.length===0)return;if(We()<=ff){ie.value=Ae[Ae.length-1].id;return}if(le||X===null){const an=ke.scrollTop,Fn=ke.getBoundingClientRect().top,so=[];for(const Ps of ke.querySelectorAll(".turn-anchor[data-turn-id]")){const ku=Ps.dataset.turnId;ku&&so.push({id:ku,top:Ps.getBoundingClientRect().top-Fn+an})}X=so,le=!1}const Ke=new Set(Ae.map(an=>an.id)),Mt=ke.scrollTop+ke.clientHeight/2;let Gt=null;for(const an of X)Ke.has(an.id)&&an.top<=Mt&&(Gt=an.id);ie.value=Gt??Ae[0].id}let X=null,le=!0;function Ie(){le=!0}let de=0;function pe(){de||(de=co(()=>{de=0,ne()}))}const ve=Z(!1);let oe=0;function ye(){oe||(oe=co(()=>{oe=0,Y()}))}function G(){ye(),Ie()}function Y(){const ke=te.value,Ae=!s.mobile&&ke?ke.closest(".con")?.querySelector(".conversation-toc"):null,Ke=Ae?.querySelector(".toc-bar");let Mt=!1;if(ke&&Ae&&Ke){const Gt=Ke.getBoundingClientRect(),an=Ae.getBoundingClientRect(),Fn=Gt.left+Gt.width/2;Mt=Array.from(ke.querySelectorAll(".table-node-wrapper")).some(so=>{const Ps=so.getBoundingClientRect();return Ps.left<=Fn&&Fn<=Ps.right&&Ps.top<an.bottom&&Ps.bottom>an.top})}ve.value!==Mt&&(ve.value=Mt)}const fe=R(()=>s.questions&&s.questions.length>0?s.questions[0]:void 0),we=R(()=>{const ke=fe.value;if(ke)return s.pendingQuestionActions?.[ke.questionId]}),ge=R(()=>s.approvals&&s.approvals.length>0?s.approvals[0]:void 0),Q=R(()=>{const ke=ge.value;return ke?!!s.pendingApprovalActions?.[ke.approvalId]:!1}),te=Z(null),ce=Z(null),ue=Z(0),Se=Z(0),ze=Z(!1),_e=Z(null);let Ee=null;function it(){if(s.turns.length!==0){if(ze.value){_e.value?.focusInput();return}Ee=document.activeElement,ze.value=!0}}function Fe(){ze.value=!1,yt(()=>{Ee instanceof HTMLElement&&Ee.isConnected&&Ee.focus(),Ee=null})}Je(()=>s.turns.length===0&&!s.sessionLoading,ke=>{ke&&ze.value&&Fe()});const Oe=R(()=>({"--panes-scrollbar-width":`${ue.value}px`})),Ge=R(()=>({"--chat-dock-height":`${Se.value+T$e}px`}));function at(ke){return ke instanceof HTMLElement?ke:ke&&"$el"in ke&&ke.$el instanceof HTMLElement?ke.$el:null}let Tt=0;function Bt(){Tt||(Tt=co(()=>{Tt=0;const ke=te.value,Ae=ke?Math.max(0,ke.offsetWidth-ke.clientWidth):0;Ae!==ue.value&&(ue.value=Ae);const Ke=ce.value?.offsetHeight??0;Ke!==Se.value&&(Se.value=Ke)}))}function Yt(ke){const Ae=at(ke);Ae!==te.value&&(te.value=Ae,Ae&&xe())}function Sn(ke){const Ae=at(ke);Ae!==ce.value&&(ce.value=Ae??null,ke&&"loadForEdit"in ke&&typeof ke.loadForEdit=="function"&&"focus"in ke&&typeof ke.focus=="function"?w.value={loadForEdit:ke.loadForEdit.bind(ke),loadAttachmentsForEdit:"loadAttachmentsForEdit"in ke&&typeof ke.loadAttachmentsForEdit=="function"?ke.loadAttachmentsForEdit.bind(ke):()=>{},focus:ke.focus.bind(ke),get anyPopupOpen(){return"anyPopupOpen"in ke&&ke.anyPopupOpen===!0},isEmpty:"isEmpty"in ke&&typeof ke.isEmpty=="function"?ke.isEmpty.bind(ke):void 0}:w.value=null,se())}const on=Z(!0),en=Z(!1),Cn=Z(!1);let Mn=null;function We(){const ke=te.value;return ke?yo-ke.scrollTop-ht:0}let tt=0,Ue=0,Lt=0,gt=0,wn=0,yn=0,go=0;function qt(){return Date.now()<Ue}function ps(){ye(),Cn.value=!0,Mn&&clearTimeout(Mn),Mn=setTimeout(()=>{Cn.value=!1,Mn=null},900);const ke=te.value;if(!ke)return;const Ae=ke.scrollTop;if(kn()){tt=Ae;return}if(performance.now()-Lt<100){tt=Ae;return}const Ke=We();if(qt()){on.value=!0,en.value=!1,tt=Ae;return}Ae<tt-1&&Ke>1?ke.scrollHeight-Ae-ke.clientHeight>1&&(on.value=!1,en.value=!0):Ke<=ff&&Ae>tt+1&&Date.now()>=gt&&(on.value=!0,en.value=!1),tt=Ae,pe()}function xs(ke=!1){const Ae=te.value;on.value=!0,en.value=!1,no(),Ae&&(!ke&&performance.now()<wn||(ke?In():Ae.scrollTop=Math.max(Ae.scrollTop,yo),tt=Ae.scrollTop))}let _n=0;function In(ke=320){const Ae=te.value;if(!Ae)return;if(_n&&(Tn(_n),_n=0),typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches){Ae.scrollTop=Ae.scrollHeight,tt=Ae.scrollTop;return}const Ke=Ae.scrollTop,Mt=performance.now();Lt=Mt,wn=Mt+ke+E$e;const Gt=()=>{_n=0;const an=Math.min(1,(performance.now()-Mt)/ke),Fn=1-Math.pow(1-an,3);Ae.scrollTop=Ke+(Ae.scrollHeight-Ke)*Fn,tt=Ae.scrollTop,an<1?_n=co(Gt):wn=0};_n=co(Gt)}function To(ke,Ae){return(Ae.closest("[inert]")?.closest(".tool-group, .activity-run, .turn-fold")??Ae).getBoundingClientRect().top-ke.getBoundingClientRect().top+ke.scrollTop}function lo(ke,Ae){const Ke=Array.from(ke.querySelectorAll(".turn-anchor[data-turn-id], [data-scroll-anchor-id]")).map(an=>({node:an,top:To(ke,an)})),Mt=Ke.findIndex(an=>an.top>=Ae),Gt=Mt<0?Math.max(0,Ke.length-1):Mt;return Ke.slice(Gt,Gt+2).flatMap(an=>{const Fn=an.node.dataset.scrollAnchorId,so=Fn??an.node.dataset.turnId;return so?[{kind:Fn?"tool":"turn",id:so,top:an.top}]:[]})}const St=new Map;function hs(ke,Ae){for(const Ke of Ae.anchors){const Mt=Ke.kind==="tool"?"data-scroll-anchor-id":"data-turn-id",Gt=ke.querySelector(`[${Mt}="${Ys(Ke.id)}"]`);if(Gt)return To(ke,Gt)-Ke.top}return ke.scrollHeight-Ae.oldHeight}function Jo(ke,Ae,Ke=ke.scrollTop){return ke.scrollTop=Ke+hs(ke,Ae),tt=ke.scrollTop,ke.scrollTop}async function uo(){if(!s.sessionId||!s.loadOlderMessages||s.loadingMore||Xt.value||!s.hasMoreMessages)return;const ke=s.sessionId,Ae=te.value,Ke=Ae?.scrollTop??0,Mt={anchors:Ae?lo(Ae,Ke):[],oldHeight:Ae?.scrollHeight??0};gs(ke,!0),Ei();try{if(await yt(),await s.loadOlderMessages(ke),await yt(),s.sessionId!==ke){St.set(ke,Mt);return}const Gt=te.value;if(!Gt)return;Jo(Gt,Mt),St.delete(ke)}finally{gs(ke,!1)}}function Ys(ke){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(ke):ke.replaceAll(/["\\]/g,"\\$&")}let Nn=null;function no(){Nn!==null&&(clearTimeout(Nn),Nn=null)}function $s(ke){ao(),on.value=!1,en.value=We()>ff,ke.scrollIntoView({behavior:"smooth",block:"center"}),no(),Nn=setTimeout(()=>{Nn=null;const Ae=te.value;if(!Ae||!ke.isConnected)return;const Ke=ke.getBoundingClientRect().top+ke.offsetHeight/2-(Ae.getBoundingClientRect().top+Ae.clientHeight/2);Math.abs(Ke)>48&&(Ae.scrollTop+=Ke)},480)}function Xs(ke){const Ae=te.value;if(!Ae)return;const Ke=Ae.querySelector(`.turn-anchor[data-turn-id="${Ys(ke)}"]`);Ke&&$s(Ke)}function ci(ke,Ae){const Ke=ke.startContainer.parentElement;if(Ke!==null)for(let Mt=Ke;Mt!==null&&Mt!==Ae;Mt=Mt.parentElement){const Gt=getComputedStyle(Mt),an=/(auto|scroll)/.test(Gt.overflowY)&&Mt.scrollHeight>Mt.clientHeight,Fn=/(auto|scroll)/.test(Gt.overflowX)&&Mt.scrollWidth>Mt.clientWidth;if(!an&&!Fn)continue;const so=ke.getClientRects()[0];if(!so)return;const Ps=Mt.getBoundingClientRect();an&&(Mt.scrollTop+=so.top+so.height/2-(Ps.top+Mt.clientHeight/2)),Fn&&(Mt.scrollLeft+=so.left+so.width/2-(Ps.left+Mt.clientWidth/2))}}function Oo(ke){const Ae=te.value;if(!Ae)return;const Ke=ke.startContainer.parentElement;ao(),on.value=!1,en.value=We()>ff,gt=Date.now()+700;const Mt=Ke?.closest(".u-text-wrap.is-clamped");if(Mt){Mt.querySelector(".u-text-toggle")?.click(),yt(()=>vo(ke,Ae));return}vo(ke,Ae)}function vo(ke,Ae){const Ke=ke.startContainer.parentElement;ci(ke,Ae);const Mt=ke.getClientRects()[0];if(!Mt){Ke instanceof HTMLElement&&$s(Ke);return}const Gt=Ae.getBoundingClientRect(),an=Mt.top+Mt.height/2-(Gt.top+Ae.clientHeight/2),Fn=typeof window>"u"||!window.matchMedia("(prefers-reduced-motion: reduce)").matches;Ae.scrollTo({top:Ae.scrollTop+an,behavior:Fn?"smooth":"auto"}),no(),Nn=setTimeout(()=>{Nn=null;const so=te.value,Ps=ke.getClientRects()[0];if(!so||!Ps)return;const ku=so.getBoundingClientRect(),A1=Ps.top+Ps.height/2-(ku.top+so.clientHeight/2);Math.abs(A1)>48&&(so.scrollTop+=A1)},480)}function Po(){const ke=te.value;if(!ke)return"none";const Ae=ke.firstElementChild,Ke=Ae instanceof HTMLElement?Ae.offsetHeight:0,Mt=ce.value?.offsetHeight??0;return`${ke.scrollHeight}:${ke.clientHeight}:${Ke}:${Mt}`}function co(ke){return typeof requestAnimationFrame=="function"?requestAnimationFrame(ke):setTimeout(ke,16)}function Tn(ke){typeof cancelAnimationFrame=="function"?cancelAnimationFrame(ke):clearTimeout(ke)}let fo=0,Qe=0,st=null,Ct=0;const Qt=Z(!1);function kn(){return performance.now()<fo}function Ko(ke,Ae=200){const Ke=te.value;if(!Ke||Xt.value||(ao(),on.value=!1,st=ke,Ct=ke.getBoundingClientRect().top,fo=performance.now()+Ae,Qt.value=!0,Qe))return;const Mt=()=>{if(Qe=0,!st)return;if(on.value){st=null,Qt.value=!1;return}if(performance.now()>=fo){st=null,Qt.value=!1,Eo();return}const Gt=st.getBoundingClientRect().top-Ct;Gt&&(Ke.scrollTop+=Gt),Qe=co(Mt)};Qe=co(Mt)}function Eo(){We()<=ff?(on.value=!0,en.value=!1):(on.value=!1,en.value=!0)}function bo(ke=36,Ae){if(!on.value&&!qt()){Ae?.();return}const Ke=++go;let Mt="",Gt=0,an=0;yn&&(Tn(yn),yn=0);const Fn=()=>{if(yn=0,Ke!==go)return;if(!on.value&&!qt()){Ae?.();return}xs(!1);const so=Po();Gt=so===Mt?Gt+1:0,Mt=so,an++,Gt<3&&an<ke?yn=co(Fn):Ae?.()};yn=co(Fn)}function Ns(ke,Ae){return ke!==void 0&&ke.length>0&&Ae.length>=ke.length&&ke.firstId!==Ae.firstId&&ke.lastId===Ae.lastId&&ke.lastTextLen===Ae.lastTextLen&&ke.lastThinkingLen===Ae.lastThinkingLen&&ke.lastToolsLen===Ae.lastToolsLen&&ke.approvalIds===Ae.approvalIds}const Do=R(()=>{const ke=(s.approvals??[]).map(an=>an.approvalId).join(","),Ae=s.turns,Ke=Ae.at(-1),Mt=Ke?.thinking?.length??0,Gt=Ke?.tools?.reduce((an,Fn)=>an+Fn.name.length+(Fn.arg?.length??0)+(Fn.output?.join("").length??0),0)??0;return{length:Ae.length,firstId:Ae[0]?.id??"",lastId:Ke?.id??"",lastTextLen:Ke?.text.length??0,lastThinkingLen:Mt,lastToolsLen:Gt,approvalIds:ke}});let Io=s.fileReloadKey;Je(Do,async(ke,Ae)=>{const Ke=s.fileReloadKey,Mt=Ke!==Io;if(Io=Ke,Xt.value&&Ns(Ae,ke)){pe();return}if(Mt){pe();return}await yt(),on.value||qt()?xs(ke.length<Ae.length):en.value=!0,pe()}),Je(ce,()=>{se()}),Je(()=>s.mobile,async()=>{await yt(),Bt()});const Qo=new Map,sn=Z(!1);let es=0,ms=null;function Tr(){sn.value=!0,es&&(Tn(es),es=0),ms&&clearTimeout(ms),ms=setTimeout(()=>{sn.value=!1,ms=null},1200)}function ts(){if(!sn.value)return;let ke=2;const Ae=()=>{if(es=0,ke--,ke>0){es=co(Ae);return}sn.value=!1,ms&&(clearTimeout(ms),ms=null)};es&&Tn(es),es=co(Ae)}Je(()=>s.fileReloadKey,async(ke,Ae)=>{const Ke=te.value;Ae&&Ke&&Qo.set(String(Ae),{top:Ke.scrollTop,following:on.value}),ao(),Tr(),await yt();const Mt=te.value,Gt=ke?Qo.get(String(ke)):void 0;if(Gt&&Mt){const an=St.get(String(ke)),Fn=an?Jo(Mt,an,Gt.top):Gt.top;an&&St.delete(String(ke)),on.value=Gt.following,Mt.scrollTop=Fn,tt=Mt.scrollTop,en.value=!Gt.following&&We()>1,Gt.following?bo(36,ts):ts()}else on.value=!0,tt=0,xs(!1),bo(36,ts);Ie(),ne()}),Je(()=>s.sessionLoading,async(ke,Ae)=>{ke||!Ae||(on.value=!0,await yt(),bo(36,ts),pe())}),Je(()=>s.turnActive,async(ke,Ae)=>{ke||!Ae||!on.value&&!qt()||(await yt(),bo(48),pe())});function Ki(){on.value=!0,en.value=!1,Ue=Date.now()+CS,yt(()=>{xs(!0),bo(16)})}function Js(ke){Ki(),i("submit",ke)}function Bo(ke){on.value=!0,en.value=!1,Ue=Date.now()+CS,i("editMessage",ke)}function Zo(ke){const Ae=s.queued?.[ke],Ke=Ae?.text??"";g(Ke,Ae?.attachments)&&i("editQueued",ke)}function Il(ke){i("reorderQueue",ke)}function Zi(ke,Ae){Ki(),i("answer",ke,Ae)}function tl(ke,Ae){!ke||!Ae||i("approval",ke,Ae)}let Ho=null,Co=null,Fs=null,Rs=null,yo=0,ht=0,Le=0;const Ze=Z(new Set),Xt=R(()=>!!s.sessionId&&Ze.value.has(s.sessionId));function gs(ke,Ae){const Ke=new Set(Ze.value);Ae?Ke.add(ke):Ke.delete(ke),Ze.value=Ke}function di(){Xt.value||Le||(Le=co(()=>{Le=0,!Xt.value&&(kn()||(on.value||qt())&&xs(!1))}))}function Ei(){go++,yn&&(Tn(yn),yn=0),Le&&(Tn(Le),Le=0)}function ao(){const ke=te.value;if(Ue=0,gt=0,Ei(),fo=0,st=null,Qt.value=!1,_n&&(Tn(_n),_n=0),no(),ke){const Ae=ke.scrollTop;typeof ke.scrollTo=="function"?ke.scrollTo({top:Ae,behavior:"auto"}):ke.scrollTop=Ae}wn=0,Lt=Number.NEGATIVE_INFINITY,ke&&(tt=ke.scrollTop)}function Gi(){const ke=te.value;!ke||ke.scrollHeight-ke.clientHeight<=1&&!s.hasMoreMessages||(on.value=!1,ao(),ke.scrollHeight-ke.clientHeight>1&&(en.value=!0))}function Er(ke){const Ae=te.value;if(!Ae)return!1;for(const Ke of ke.composedPath()){if(Ke===Ae)return!1;if(Ke instanceof HTMLElement&&Ke.scrollHeight>Ke.clientHeight+1&&Ke.scrollTop>1)return!0}return!1}function fi(ke){ke.defaultPrevented||ke.ctrlKey||ke.shiftKey||(no(),!(ke.deltaY>=0||Er(ke))&&Gi())}function Ll(ke){const Ae=te.value;if(!Ae||ke.defaultPrevented||ke.button!==0||ke.pointerType==="touch")return;const Ke=Ae.getBoundingClientRect(),Mt=Ae.offsetWidth-Ae.clientWidth,Gt=Mt>0?Mt:12;ke.target===Ae&&ke.clientX>=Ke.right-Gt&&Gi()}let zo=null;function Ir(ke){zo=ke.touches.length===1?ke.touches[0].clientY:null}function Qs(ke){const Ae=ke.touches.length===1?ke.touches[0].clientY:null;no(),Ae!==null&&zo!==null&&Ae>zo+2&&!Er(ke)&&Gi(),zo=Ae}function pi(){if(!Co)return;const ke=te.value?.firstElementChild??null;ke!==Fs&&(Fs&&Co.unobserve(Fs),Fs=ke,ke&&Co.observe(ke))}function se(){if(!Co)return;const ke=ce.value;ke!==Rs&&(Rs&&Co.unobserve(Rs),Rs=ke,ke&&Co.observe(ke))}function xe(){const ke=te.value;Bt(),Ho&&(Ho.disconnect(),ke&&Ho.observe(ke,{childList:!0,subtree:!0,characterData:!0})),Co&&(Co.disconnect(),Fs=null,Rs=null,ke&&Co.observe(ke),pi(),se()),yo=ke?.scrollHeight??0,ht=ke?.clientHeight??0,ye(),Ie()}function J(){pi(),di(),ye(),Ie()}function Ce(){typeof document>"u"||document.visibilityState==="visible"&&on.value&&bo()}const $e=Z(!1);let He=null;function vt(){$e.value=!0,He!==null&&clearTimeout(He),He=setTimeout(()=>{$e.value=!1},I$e)}const ut=Z(null);let Dt=null;const Et=Z(null);let ln=null,oo=!1;function Ot(){ut.value=null,Et.value=null,oo=!1,Dt!==null&&(clearTimeout(Dt),Dt=null),ln!==null&&(clearTimeout(ln),ln=null)}function Pt(){for(let ke=s.turns.length-1;ke>=0;ke--){const Ae=s.turns[ke];if(Ae.goalContinuation)return null;if(Ae.role==="user")return Ae}return null}function Yn(ke){return ta(ke).some(Ae=>Ae.kind==="thinking"&&Ae.thinking.trim().length>0||Ae.kind==="text"&&Ae.text.trim().length>0||Ae.kind==="tool")}function ko(){if(ut.value!==null||Et.value!==null||!s.working||(s.queued?.length??0)>0)return;const ke=Pt();if(ke===null||ke.skillActivation!==void 0||ke.pluginCommand!==void 0)return;s.turns.slice(s.turns.indexOf(ke)+1).every(Ke=>Ke.role==="assistant"&&!Yn(Ke))?(Et.value=ke.id,oo=!1,ln=setTimeout(()=>{Et.value=null},$$e)):ut.value=ke.id}let vs=!1,Os=null;function ei(ke){if(vs)return;Ot();const Ae=s.turns.find(Mt=>Mt.id===ke);Ae===void 0||Ae.role!=="user"||Pt()?.id!==Ae.id||(w.value??k.value)?.isEmpty?.()===!1||(vs=!0,Os=setTimeout(()=>{vs=!1,Os=null},N$e),Bo({text:Ae.text,attachments:Ae.attachments}))}function Lc(){Et.value===null||s.working||!oo||ei(Et.value)}Je(()=>s.working,(ke,Ae)=>{if(!(Ae!==!0||ke)){if(Et.value!==null){Lc();return}ut.value!==null&&Dt===null&&(Dt=setTimeout(()=>{ut.value=null,Dt=null},L$e))}}),Je(()=>Pt()?.id??null,(ke,Ae)=>{ke!==Ae&&Ot()}),Je(()=>s.sessionId,Ot),Je(()=>s.queued?.length,ke=>{(ke??0)>0&&Ot()});const U2=R(()=>{if(s.lastTurnReason!=="cancelled"||s.working||s.turnActive)return null;const ke=s.turns[s.turns.length-1];return ke?.role==="assistant"&&Yn(ke)?ke.id:null}),$c=R(()=>s.lastTurnReason==="failed"&&!s.working&&!s.turnActive&&s.turns.length>0);function yu(){Ki(),i("submit",{text:o("conversation.turnFailedResumeText"),attachments:[]})}const Nc=R(()=>s.working?null:ut.value);function Fc(){i("interrupt")}function j2(){return(w.value?.anyPopupOpen??k.value?.anyPopupOpen)===!0}const{handleCompositionStart:$l,handleCompositionEnd:hi,isComposingKeyEvent:x1}=Ar();let a0=null;function u0(ke){a0=ke.target}function S1(ke){const Ae=ke instanceof Element&&ke!==document.body?ke:a0,Ke=zQ(Ae,".global-preview");if(Ke){iC(Ke);return}const Mt=te.value?.querySelector(".chat");Mt&&iC(Mt)}function c0(ke){if(!(ke.target instanceof Element&&ke.target.closest(".terminal-host")!==null)){if(ke.key==="Escape"&&!s.overlayOpen&&!j2()&&!ke.defaultPrevented&&!ke.repeat&&!x1(ke)){Nc.value!==null?(ke.preventDefault(),ei(Nc.value)):s.working&&(ke.preventDefault(),ko(),Fc());return}if(SQ(ke)&&!s.overlayOpen&&s.turns.length>0){ke.preventDefault(),it();return}BQ(ke)&&!s.overlayOpen&&!HQ(ke.target)&&(ke.preventDefault(),S1(ke.target))}}function d0(){on.value&&di()}dn(()=>{yt(()=>{typeof MutationObserver=="function"&&(Ho=new MutationObserver(J)),typeof ResizeObserver=="function"&&(Co=new ResizeObserver(()=>{ye(),Ie(),Bt();const ke=te.value;if(!ke)return;const{scrollHeight:Ae,clientHeight:Ke}=ke,Mt=Ae>yo+1,Gt=Ke<ht-1;yo=Ae,ht=Ke,!kn()&&(Mt||Gt)&&di()})),xe(),bo(48),ne(),te.value?.addEventListener("kimi-table-layout",G),typeof document<"u"&&(document.addEventListener("visibilitychange",Ce),document.addEventListener("keydown",c0),document.addEventListener("pointerdown",u0,!0),document.addEventListener("compositionstart",$l),document.addEventListener("compositionend",hi)),window.visualViewport?.addEventListener("resize",d0)})}),bn(()=>{te.value?.removeEventListener("kimi-table-layout",G),Ho&&Ho.disconnect(),Co&&Co.disconnect(),Le&&Tn(Le),yn&&Tn(yn),Qe&&Tn(Qe),_n&&Tn(_n),oe&&Tn(oe),de&&Tn(de),Nn!==null&&clearTimeout(Nn),Mn&&clearTimeout(Mn),He!==null&&clearTimeout(He),Dt!==null&&clearTimeout(Dt),ln!==null&&clearTimeout(ln),Os!==null&&clearTimeout(Os),_!==null&&(clearTimeout(_),_=null),typeof document<"u"&&(document.removeEventListener("visibilitychange",Ce),document.removeEventListener("keydown",c0),document.removeEventListener("pointerdown",u0,!0),document.removeEventListener("compositionstart",$l),document.removeEventListener("compositionend",hi)),window.visualViewport?.removeEventListener("resize",d0)});function Rc(){(w.value??k.value)?.focus()}Lhe({sessionId:()=>s.sessionId,mobile:()=>s.mobile===!0,starting:()=>s.starting===!0,dockedComposer:w,emptyComposer:k});function V2(){vt()}function q2(ke){if(Et.value!==null){if(!ke){oo||Ot();return}oo=!0,Lc()}}return t({loadComposerForEdit:g,focusComposer:Rc,notifyUndone:V2,onAbortOutcome:q2,selectAllRegion:S1}),(ke,Ae)=>(y(),M("section",{class:Re(["con",{mobile:e.mobile}])},[!e.mobile&&!(e.turns.length===0&&!e.sessionLoading)?(y(),he(LAe,{key:0,"session-id":e.sessionId,"workspace-name":e.workspaceName,"workspace-root":e.workspaceRoot,"session-title":e.sessionTitle,branch:e.gitInfo?.branch,ahead:e.gitInfo?.ahead,behind:e.gitInfo?.behind,"changes-count":F.value,"git-diff-stats":e.gitDiffStats,"is-git-repo":!!e.gitInfo,pr:e.pr,copied:b.value,onOpenChanges:Ae[0]||(Ae[0]=Ke=>i("openChanges")),onCopyAll:Ae[1]||(Ae[1]=Ke=>v.value?.copyConversation()),onCopyFinalSummary:Ae[2]||(Ae[2]=Ke=>v.value?.copyFinalSummary()),onOpenPr:Ae[3]||(Ae[3]=Ke=>e.pr&&i("openPr",e.pr.url)),onRenameSession:Ae[4]||(Ae[4]=(Ke,Mt)=>i("renameSession",Ke,Mt)),onForkSession:Ae[5]||(Ae[5]=Ke=>i("forkSession",Ke)),onArchiveSession:Ae[6]||(Ae[6]=Ke=>i("archiveSession",Ke)),onExportSession:Ae[7]||(Ae[7]=Ke=>i("exportSession",Ke))},null,8,["session-id","workspace-name","workspace-root","session-title","branch","ahead","behind","changes-count","git-diff-stats","is-git-repo","pr","copied"])):e.mobile?ee("",!0):(y(),M("div",{key:1,class:Re(["empty-drag",{"macos-desktop":p(rc)}])},null,2)),j(qLe,{items:V.value,"active-turn-id":ie.value,mobile:e.mobile,"session-loading":e.sessionLoading,occluded:ve.value,onSelect:Xs},null,8,["items","active-turn-id","mobile","session-loading","occluded"]),C("div",{class:"chat-layout",style:Zt(Ge.value)},[C("div",{ref:Yt,class:Re(["panes chat-scroll",{"is-following":on.value,"history-prepending":Xt.value,"is-pinned":Qt.value,scrolling:Cn.value,"session-settling":sn.value}]),onScrollPassive:ps,onWheelPassive:fi,onPointerdownPassive:Ll,onTouchstartPassive:Ir,onTouchmovePassive:Qs},[C("div",{class:Re(["content-wrap",[e.mobile?"align-mobile":"align-center"]])},[e.turns.length===0&&!e.sessionLoading?(y(),M(Pe,{key:0},[Ae[55]||(Ae[55]=C("div",{class:"empty-spacer"},null,-1)),C("div",c$e,[e.starting?(y(),M("span",f$e,[j(p(Ao),{size:"sm"}),C("span",null,N(p(o)("conversation.starting")),1)])):(y(),he(u$e,{key:0,class:"empty-doodle"},{fallback:me(()=>[C("span",d$e,N(p(o)("composer.emptyConversationTitle")),1)]),_:1})),e.starting?ee("",!0):(y(),M("span",p$e,N(p(o)("composer.emptyConversation")),1))]),d.value?(y(),M("div",h$e,[j(p(Te),{class:"upgrade-banner-icon",name:"music",size:"sm"}),C("span",m$e,N(p(o)("composer.upgradeBanner")),1),C("button",{type:"button",class:"upgrade-banner-cta",onClick:Ae[8]||(Ae[8]=Ke=>p(jp)())},N(p(o)("sidebar.upgrade")),1)])):ee("",!0),j(mF,{ref_key:"emptyComposerRef",ref:k,class:"empty-composer","session-id":e.sessionId,running:e.running,working:e.working,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,goal:e.goal,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,starting:e.starting,"hide-context":"",onSubmit:Js,onSteer:Ae[11]||(Ae[11]=Ke=>i("steer",Ke)),onCommand:Ae[12]||(Ae[12]=Ke=>i("command",Ke)),onInterrupt:Fc,onUnqueue:Ae[13]||(Ae[13]=Ke=>i("unqueue",Ke)),onEditQueued:Ae[14]||(Ae[14]=Ke=>i("editQueued",Ke)),onSetPermission:Ae[15]||(Ae[15]=Ke=>i("setPermission",Ke)),onSetThinking:Ae[16]||(Ae[16]=Ke=>i("setThinking",Ke)),onTogglePlan:Ae[17]||(Ae[17]=Ke=>i("togglePlan")),onToggleSwarm:Ae[18]||(Ae[18]=Ke=>i("toggleSwarm")),onToggleGoal:Ae[19]||(Ae[19]=Ke=>i("toggleGoal")),onOpenBtw:Ae[20]||(Ae[20]=Ke=>i("command",{cmd:"/btw",attachments:[]})),onCreateGoal:Ae[21]||(Ae[21]=Ke=>i("createGoal",Ke)),onControlGoal:Ae[22]||(Ae[22]=Ke=>i("controlGoal",Ke)),onFocusGoal:W,onCompact:Ae[23]||(Ae[23]=Ke=>i("compact")),onPickModel:Ae[24]||(Ae[24]=Ke=>i("pickModel")),onSelectModel:Ae[25]||(Ae[25]=Ke=>i("selectModel",Ke)),onLogin:Ae[26]||(Ae[26]=Ke=>i("login"))},fA({_:2},[e.starting?void 0:{name:"footer",fn:me(()=>[C("div",g$e,[c.value?(y(),M("div",v$e,[j(p(pn),{text:p(o)("conversation.switchWorkspace")},{default:me(()=>[C("button",{type:"button",class:Re(["ws-chip",{open:r.value}]),"aria-expanded":r.value,onClick:It(h,["stop"])},[j(p(Te),{name:"folder"}),C("span",k$e,N(u.value),1),j(p(Te),{class:"ws-chip-chev",name:"chevron-down",size:"sm"})],10,y$e)]),_:1},8,["text"]),r.value?(y(),M("div",{key:0,class:Re(["ws-panel",{up:l.value}]),style:Zt(a.value?{maxHeight:a.value}:void 0),role:"menu"},[C("div",b$e,N(p(o)("workspace.recentLabel")),1),(y(!0),M(Pe,null,pt(f.value,Ke=>(y(),M("button",{key:Ke.id,type:"button",class:Re(["ws-row",{on:Ke.id===e.activeWorkspaceId}]),role:"menuitem",onClick:It(Mt=>m(Ke.id),["stop"])},[j(p(Te),{name:"folder"}),C("span",w$e,[C("span",_$e,N(Ke.name),1),C("span",x$e,N(Ke.shortPath),1)]),Ke.id===e.activeWorkspaceId?(y(),he(p(Te),{key:0,class:"ws-check",name:"check",size:"sm"})):ee("",!0)],10,C$e))),128)),Ae[54]||(Ae[54]=C("div",{class:"ws-divider"},null,-1)),C("button",{type:"button",class:"ws-action",role:"menuitem",onClick:Ae[9]||(Ae[9]=It(Ke=>{r.value=!1,i("addWorkspace")},["stop"]))},[j(p(Te),{name:"folder-plus"}),C("span",null,N(p(o)("conversation.pickFolder")),1)])],6)):ee("",!0)])):(y(),M("button",{key:1,type:"button",class:"ws-chip ws-ghost",onClick:Ae[10]||(Ae[10]=Ke=>i("addWorkspace"))},[j(p(Te),{name:"folder-plus"}),C("span",null,N(p(o)("conversation.pickFolder")),1)]))])]),key:"0"}]),1032,["session-id","running","working","queued","search-files","upload-image","status","thinking","plan-mode","swarm-mode","goal-mode","goal","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","starting"]),r.value?(y(),M("div",{key:1,class:"ws-backdrop",onClick:Ae[27]||(Ae[27]=Ke=>r.value=!1)})):ee("",!0),Ae[56]||(Ae[56]=C("div",{class:"empty-spacer"},null,-1))],64)):(y(),he(e6,{ref_key:"chatPaneRef",ref:v,key:e.fileReloadKey??"no-session",turns:e.turns,cwd:e.status.cwd,approvals:e.approvals,questions:e.questions,"turn-active":e.turnActive,working:e.working,"session-loading":e.sessionLoading,compaction:e.compaction,"has-more-messages":e.hasMoreMessages,"loading-more":e.loadingMore,"loading-more-error":e.loadingMoreError,"is-following":on.value,queued:e.queued,"undo-hint-turn-id":Nc.value,"interrupted-turn-id":U2.value,"turn-failed":$c.value,"turn-error":e.turnError??null,"turn-retry":e.turnRetry??null,onResumeTurn:yu,onOpenFile:Ae[28]||(Ae[28]=Ke=>i("openFile",Ke)),onOpenMedia:Ae[29]||(Ae[29]=Ke=>i("openMedia",Ke)),onOpenTurnDiff:Ae[30]||(Ae[30]=Ke=>i("openTurnDiff",Ke)),onCopyConversationCopied:x,onOpenCompaction:Ae[31]||(Ae[31]=Ke=>i("openCompaction",Ke)),onOpenAgent:Ae[32]||(Ae[32]=Ke=>i("openAgent",Ke)),onEditMessage:Bo,onArmedUndo:ei,onLoadOlderMessages:uo,onUnqueue:Ae[33]||(Ae[33]=Ke=>i("unqueue",Ke)),onEditQueued:Zo,onReorderQueue:Il},null,8,["turns","cwd","approvals","questions","turn-active","working","session-loading","compaction","has-more-messages","loading-more","loading-more-error","is-following","queued","undo-hint-turn-id","interrupted-turn-id","turn-failed","turn-error","turn-retry"]))],2)],34),e.turns.length===0&&!e.sessionLoading?ee("",!0):(y(),he(BLe,{key:0,ref:Sn,style:Zt(Oe.value),"session-id":e.sessionId,running:e.running,working:e.working,starting:e.starting,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,goal:e.goal,"dock-panel":O.value,"bash-tasks":S.value,"subagent-tasks":T.value,"bash-running":A.value,"subagent-running":E.value,"todo-done-count":B.value,"has-dock-work":H.value,todos:e.todos,"pending-question":fe.value,"question-busy-kind":we.value,"pending-approval":ge.value,"approval-busy":Q.value,mobile:e.mobile,onToggleDockPanel:Ae[34]||(Ae[34]=Ke=>U(Ke)),onCloseDockPanel:Ae[35]||(Ae[35]=Ke=>z()),onOpenAgent:Ae[36]||(Ae[36]=Ke=>i("openAgent",Ke)),"open-file":Ke=>i("openFile",Ke),onAnswer:Zi,onDismiss:Ae[37]||(Ae[37]=Ke=>i("dismiss",Ke)),onApproval:tl,onCancelTask:Ae[38]||(Ae[38]=Ke=>i("cancelTask",Ke)),onControlGoal:Ae[39]||(Ae[39]=Ke=>i("controlGoal",Ke)),onSubmit:Js,onSteer:Ae[40]||(Ae[40]=Ke=>i("steer",Ke)),onCommand:Ae[41]||(Ae[41]=Ke=>i("command",Ke)),onInterrupt:Fc,onSetPermission:Ae[42]||(Ae[42]=Ke=>i("setPermission",Ke)),onSetThinking:Ae[43]||(Ae[43]=Ke=>i("setThinking",Ke)),onTogglePlan:Ae[44]||(Ae[44]=Ke=>i("togglePlan")),onToggleSwarm:Ae[45]||(Ae[45]=Ke=>i("toggleSwarm")),onToggleGoal:Ae[46]||(Ae[46]=Ke=>i("toggleGoal")),onOpenBtw:Ae[47]||(Ae[47]=Ke=>i("command",{cmd:"/btw",attachments:[]})),onCreateGoal:Ae[48]||(Ae[48]=Ke=>i("createGoal",Ke)),onFocusGoal:W,onCompact:Ae[49]||(Ae[49]=Ke=>i("compact")),onPickModel:Ae[50]||(Ae[50]=Ke=>i("pickModel")),onSelectModel:Ae[51]||(Ae[51]=Ke=>i("selectModel",Ke)),onLogin:Ae[52]||(Ae[52]=Ke=>i("login"))},null,8,["style","session-id","running","working","starting","queued","search-files","upload-image","status","thinking","plan-mode","swarm-mode","goal-mode","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","goal","dock-panel","bash-tasks","subagent-tasks","bash-running","subagent-running","todo-done-count","has-dock-work","todos","pending-question","question-busy-kind","pending-approval","approval-busy","mobile","open-file"]))],4),ze.value?(y(),he(s$e,{key:2,ref_key:"transcriptSearchRef",ref:_e,pane:te.value,mobile:e.mobile,reveal:Oo,onClose:Fe},null,8,["pane","mobile"])):ee("",!0),j(as,{name:"pill"},{default:me(()=>[en.value?(y(),M("button",{key:0,class:"newmsg-pill",style:Zt({bottom:`${Se.value+12}px`}),"aria-label":p(o)("conversation.jumpToLatestAria"),onClick:Ae[53]||(Ae[53]=Ke=>xs(!0))},[j(p(Te),{class:"pill-chevron",name:"arrow-down",size:"sm"}),qe(" "+N(p(o)("conversation.newMessages")),1)],12,S$e)):ee("",!0)]),_:1}),j(as,{name:"undo-toast"},{default:me(()=>[$e.value?(y(),M("div",A$e,[C("span",M$e,N(p(o)("conversation.undone")),1)])):ee("",!0)]),_:1})],2))}}),R$e=ft(F$e,[["__scopeId","data-v-2ddf1d39"]]),O$e={key:0,class:"fp-empty fp-error"},P$e={key:1,class:"fp-empty"},D$e={key:2,class:"fp-loading"},B$e={class:"fp-path"},H$e={class:"fp-meta"},z$e={key:0,class:"fp-lines"},W$e={class:"fp-size"},U$e={key:3,class:"fp-search"},j$e=["placeholder"],V$e={key:0,class:"fp-search-count"},q$e=["href","aria-label"],K$e={key:1,class:"fp-code"},Z$e={key:1,class:"fp-body fp-code"},G$e={key:2,class:"fp-body"},Y$e=["srcdoc","title"],X$e={key:1,class:"fp-code"},J$e={key:3,class:"fp-body fp-pdf-wrap"},Q$e=["src","title"],eNe={key:1,class:"fp-binary-card"},tNe={class:"fp-binary-label"},nNe={key:4,class:"fp-body fp-table-wrap"},oNe={class:"fp-table"},sNe=["data-line"],iNe={key:5,class:"fp-body fp-image-wrap"},rNe=["src","alt"],lNe={key:1,class:"fp-binary-card"},aNe={class:"fp-binary-icon"},uNe={class:"fp-binary-label"},cNe={key:6,class:"fp-body fp-code"},dNe={key:7,class:"fp-body fp-binary-wrap"},fNe={class:"fp-binary-card"},pNe={class:"fp-binary-icon"},hNe={class:"fp-binary-label"},mNe=et({__name:"FilePreview",props:{file:{},loading:{type:Boolean},error:{},line:{},downloadUrl:{},closable:{type:Boolean},externalActions:{type:Boolean},openFile:{type:Function}},emits:["close","openExternal","reveal"],setup(e,{emit:t}){const{t:n}=Nt();function o(de,pe){const ve=pe.startsWith("/"),oe=pe.split("/").filter(Boolean);for(const ye of de.split("/"))ye===""||ye==="."||(ye===".."?oe.pop():oe.push(ye));return(ve?"/":"")+oe.join("/")}const s=nn("resolveImage",async de=>de),i=R(()=>{const de=u.file?.path??"",pe=de.lastIndexOf("/");return pe>0?de.slice(0,pe):""});function r(de){if(/^(https?:|data:|blob:)/i.test(de)||de.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(de)||de.startsWith("\\\\"))return de;const pe=i.value;return pe?o(de,pe):de}async function l(de){const pe=r(de);return s?s(pe):pe}Ln("resolveImage",l);function a(de){let pe=de.path;if(/^(https?:|mailto:|tel:|data:|blob:|#)/i.test(pe)||pe.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(pe)||pe.startsWith("\\\\"))return de;for(const oe of["#","?"]){const ye=pe.indexOf(oe);ye!==-1&&(pe=pe.slice(0,ye))}const ve=i.value;return{...de,path:o(pe,ve)}}const u=e,c=t;function d(de){u.openFile?.(a(de))}const f=Z(null),h=R(()=>{const de=u.file;if(!de)return"binary";const pe=de.mime??"",ve=de.languageId??"",oe=de.path.toLowerCase();return pe==="text/markdown"||ve==="markdown"||ve==="md"||oe.endsWith(".mdx")?"markdown":pe==="application/json"||ve==="json"?"json":pe==="text/html"||ve==="html"||oe.endsWith(".html")||oe.endsWith(".htm")?"html":pe==="application/pdf"||oe.endsWith(".pdf")?"pdf":pe==="text/csv"||ve==="csv"||oe.endsWith(".csv")?"csv":pe.startsWith("image/")?"image":de.isBinary?"binary":pe.startsWith("text/")||ve!==""?"text":"binary"});function m(de){const pe=atob(de),ve=Uint8Array.from(pe,oe=>oe.charCodeAt(0));return new TextDecoder().decode(ve)}const v=R(()=>{const de=u.file;if(!de)return"";if(de.encoding==="base64")try{return m(de.content)}catch{return de.content}return de.content}),k=R(()=>{if(h.value!=="json"||!u.file)return"";try{return JSON.stringify(JSON.parse(v.value),null,2)}catch{return v.value}}),w=R(()=>u.file?(h.value==="json"?k.value:v.value).split(` +`):[]),b=R(()=>u.file?h.value==="json"?k.value:v.value:""),_=R(()=>w.value.map((de,pe)=>pe+1)),g=R(()=>u.file&&b.value.length<=f3?u.file.path:void 0),x=Z(""),S=Z(0),T=R(()=>{const de=x.value.trim().toLowerCase();if(!de)return[];const pe=[];return w.value.forEach((ve,oe)=>{ve.toLowerCase().includes(de)&&pe.push(oe+1)}),pe});Je(x,()=>{S.value=0});function A(de,pe=!1){de&&yt(()=>{const ve=f.value?.querySelector(".fp-body"),oe=ve?.querySelector(`[data-line="${de}"]`);if(!ve||!oe)return;pe&&(ve.scrollTop=0);const ye=ve.getBoundingClientRect(),G=oe.getBoundingClientRect(),Y=G.top-ye.top+ve.scrollTop;ve.scrollTop=Y-ve.clientHeight/2+G.height/2})}Je(()=>[u.file?.path,u.line],()=>A(u.line,!0),{immediate:!0});function E(de){const pe=T.value;pe.length!==0&&(S.value=(S.value+de+pe.length)%pe.length,A(pe[S.value]))}function P(de){const pe=T.value;return{target:u.line===de,hit:pe.includes(de),active:pe[S.value]===de}}function D(de){return de<1024?`${de} B`:de<1024*1024?`${(de/1024).toFixed(1)} KB`:`${(de/(1024*1024)).toFixed(1)} MB`}const I=Z(!1),$=Z(!1);function B(){u.file&&Zs(b.value).then(de=>{de&&(I.value=!0,setTimeout(()=>{I.value=!1},1400))})}function H(){u.file&&Zs(u.file.path).then(de=>{de&&($.value=!0,setTimeout(()=>{$.value=!1},1400))})}const O=Z("preview"),F=Z("preview"),U=Z("fit");function z(de){O.value=de}function W(de){F.value=de}function K(de){U.value=de}Je(h,de=>{O.value=de==="html"?"preview":"source",F.value="preview",U.value="fit"});const V=R(()=>{const de=u.file;return!de||h.value!=="image"?null:de.encoding==="base64"?`data:${de.mime};base64,${de.content}`:de.mime==="image/svg+xml"?`data:${de.mime};charset=utf-8,${encodeURIComponent(de.content)}`:null}),ie=R(()=>{const de=u.file;return!de||h.value!=="pdf"?null:u.downloadUrl?u.downloadUrl:de.encoding==="base64"?`data:${de.mime};base64,${de.content}`:null}),ne=R(()=>u.file?["<!doctype html>",'<meta charset="utf-8">',`<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: blob:; style-src 'unsafe-inline'; font-src data:;">`,v.value].join(""):"");function X(de){const pe=[];let ve="",oe=!1;for(let ye=0;ye<de.length;ye++){const G=de[ye];G==='"'&&de[ye+1]==='"'?(ve+='"',ye++):G==='"'?oe=!oe:G===","&&!oe?(pe.push(ve),ve=""):ve+=G}return pe.push(ve),pe}const le=R(()=>w.value.slice(0,200).map(X));function Ie(de,pe=55){return!de||de.length<=pe?de:"…"+de.slice(de.length-pe+1)}return(de,pe)=>(y(),M("div",{ref_key:"rootRef",ref:f,class:"file-preview"},[e.error&&!e.loading?(y(),M("div",O$e,[C("span",null,N(e.error),1),e.closable?(y(),he(p(Rt),{key:0,variant:"secondary",size:"sm",onClick:pe[0]||(pe[0]=ve=>c("close"))},{default:me(()=>[qe(N(p(n)("filePreview.close")),1)]),_:1})):ee("",!0)])):!e.file&&!e.loading?(y(),M("div",P$e,N(p(n)("filePreview.empty")),1)):e.loading?(y(),M("div",D$e,[pe[7]||(pe[7]=C("span",{class:"spinner"},null,-1)),C("span",null,N(p(n)("filePreview.loading")),1)])):e.file?(y(),M(Pe,{key:3},[j(p(pc),{wrap:"",title:p(n)("common.preview"),closable:e.closable,"close-label":p(n)("filePreview.close"),onClose:pe[6]||(pe[6]=ve=>c("close"))},{default:me(()=>[j(p(pn),{text:e.file.path},{default:me(()=>[C("span",B$e,N(Ie(e.file.path)),1)]),_:1},8,["text"]),C("span",H$e,[e.file.lineCount?(y(),M("span",z$e,N(p(n)("filePreview.lineCount",{count:e.file.lineCount})),1)):ee("",!0),C("span",W$e,N(D(e.file.size)),1)]),h.value==="html"?(y(),he(p(wi),{key:0,"model-value":O.value,size:"sm",options:[{value:"preview",label:p(n)("filePreview.preview")},{value:"source",label:p(n)("filePreview.source")}],"onUpdate:modelValue":z},null,8,["model-value","options"])):ee("",!0),h.value==="markdown"?(y(),he(p(wi),{key:1,"model-value":F.value,size:"sm",options:[{value:"preview",label:p(n)("filePreview.preview")},{value:"source",label:p(n)("filePreview.source")}],"onUpdate:modelValue":W},null,8,["model-value","options"])):ee("",!0),h.value==="image"?(y(),he(p(wi),{key:2,"model-value":U.value,size:"sm",options:[{value:"fit",label:p(n)("filePreview.fit")},{value:"actual",label:p(n)("filePreview.actual")}],"onUpdate:modelValue":K},null,8,["model-value","options"])):ee("",!0),h.value==="text"||h.value==="json"||h.value==="html"||h.value==="csv"?(y(),M("div",U$e,[Bn(C("input",{"onUpdate:modelValue":pe[1]||(pe[1]=ve=>x.value=ve),class:"fp-search-input",type:"search",placeholder:p(n)("filePreview.search")},null,8,j$e),[[ai,x.value]]),x.value.trim()?(y(),M("span",V$e,N(T.value.length),1)):ee("",!0),j(p(gn),{size:"sm",disabled:T.value.length===0,label:p(n)("filePreview.prevMatch"),tooltip:p(n)("filePreview.prevMatch"),onClick:pe[2]||(pe[2]=ve=>E(-1))},{default:me(()=>[j(p(Te),{name:"arrow-up",size:"md"})]),_:1},8,["disabled","label","tooltip"]),j(p(gn),{size:"sm",disabled:T.value.length===0,label:p(n)("filePreview.nextMatch"),tooltip:p(n)("filePreview.nextMatch"),onClick:pe[3]||(pe[3]=ve=>E(1))},{default:me(()=>[j(p(Te),{name:"arrow-down",size:"md"})]),_:1},8,["disabled","label","tooltip"])])):ee("",!0),j(p(gn),{size:"sm",class:Re({copied:$.value}),label:$.value?p(n)("filePreview.copied"):p(n)("filePreview.copyPath"),tooltip:$.value?p(n)("filePreview.copied"):p(n)("filePreview.copyPath"),onClick:H},{default:me(()=>[$.value?(y(),he(p(Te),{key:1,class:"fp-check",name:"check",size:"md"})):(y(),he(p(Te),{key:0,name:"link",size:"md"}))]),_:1},8,["class","label","tooltip"]),e.externalActions?(y(),he(p(gn),{key:4,size:"sm",label:p(n)("filePreview.openInEditor"),tooltip:p(n)("filePreview.openInEditor"),onClick:pe[4]||(pe[4]=ve=>c("openExternal"))},{default:me(()=>[j(p(Te),{name:"external-link",size:"md"})]),_:1},8,["label","tooltip"])):ee("",!0),e.externalActions?(y(),he(p(gn),{key:5,size:"sm",label:p(n)("filePreview.reveal"),tooltip:p(n)("filePreview.reveal"),onClick:pe[5]||(pe[5]=ve=>c("reveal"))},{default:me(()=>[j(p(Te),{name:"folder",size:"md"})]),_:1},8,["label","tooltip"])):ee("",!0),e.downloadUrl?(y(),he(p(pn),{key:6,text:p(n)("filePreview.download")},{default:me(()=>[C("a",{class:"fp-download",href:e.downloadUrl,target:"_blank",rel:"noreferrer",download:"","aria-label":p(n)("filePreview.download")},[j(p(Te),{name:"download",size:"md"})],8,q$e)]),_:1},8,["text"])):ee("",!0),!e.file.isBinary&&h.value!=="image"?(y(),he(p(gn),{key:7,size:"sm",class:Re({copied:I.value}),label:I.value?p(n)("filePreview.copied"):p(n)("filePreview.copy"),tooltip:I.value?p(n)("filePreview.copied"):p(n)("filePreview.copy"),onClick:B},{default:me(()=>[I.value?(y(),he(p(Te),{key:1,class:"fp-check",name:"check",size:"md"})):(y(),he(p(Te),{key:0,name:"copy",size:"md"}))]),_:1},8,["class","label","tooltip"])):ee("",!0)]),_:1},8,["title","closable","close-label"]),h.value==="markdown"?(y(),M("div",{key:0,class:Re(["fp-body",{"fp-markdown":F.value==="preview"}])},[F.value==="preview"?(y(),he(p(Ic),{key:0,text:v.value,"open-file":u.openFile?d:void 0},null,8,["text","open-file"])):(y(),M("div",K$e,[j(Ur,{code:w.value,path:g.value,"line-numbers":_.value,framed:!1,"line-class":P},null,8,["code","path","line-numbers"])]))],2)):h.value==="json"?(y(),M("div",Z$e,[j(Ur,{code:w.value,path:g.value,"line-numbers":_.value,framed:!1,"line-class":P},null,8,["code","path","line-numbers"])])):h.value==="html"?(y(),M("div",G$e,[O.value==="preview"?(y(),M("iframe",{key:0,class:"fp-html-frame",sandbox:"",srcdoc:ne.value,title:e.file.path},null,8,Y$e)):(y(),M("div",X$e,[j(Ur,{code:w.value,path:g.value,"line-numbers":_.value,framed:!1,"line-class":P},null,8,["code","path","line-numbers"])]))])):h.value==="pdf"?(y(),M("div",J$e,[ie.value?(y(),M("iframe",{key:0,class:"fp-pdf-frame",src:ie.value,title:e.file.path},null,8,Q$e)):(y(),M("div",eNe,[C("span",tNe,N(p(n)("filePreview.pdfNoPreview")),1)]))])):h.value==="csv"?(y(),M("div",nNe,[C("table",oNe,[C("tbody",null,[(y(!0),M(Pe,null,pt(le.value,(ve,oe)=>(y(),M("tr",{key:oe,class:Re(P(oe+1)),"data-line":oe+1},[C("th",null,N(oe+1),1),(y(!0),M(Pe,null,pt(ve,(ye,G)=>(y(),M("td",{key:G},N(ye),1))),128))],10,sNe))),128))])])])):h.value==="image"?(y(),M("div",iNe,[V.value?(y(),M("img",{key:0,src:V.value,alt:e.file.path,class:Re(["fp-image",{actual:U.value==="actual"}])},null,10,rNe)):(y(),M("div",lNe,[C("span",aNe,[j(p(Te),{name:"image-off",size:"lg"})]),C("span",uNe,N(p(n)("filePreview.imageNoPreview",{mime:e.file.mime,size:D(e.file.size)})),1)]))])):h.value==="text"?(y(),M("div",cNe,[j(Ur,{code:w.value,path:g.value,"line-numbers":_.value,framed:!1,"line-class":P},null,8,["code","path","line-numbers"])])):(y(),M("div",dNe,[C("div",fNe,[C("span",pNe,[j(p(Te),{name:"file-off",size:"lg"})]),C("span",hNe,N(p(n)("filePreview.binaryNoPreview",{mime:e.file.mime||p(n)("filePreview.unknownType"),size:D(e.file.size)})),1)])]))],64)):ee("",!0)],512))}}),gNe=ft(mNe,[["__scopeId","data-v-4c55a361"]]),vNe={class:"tp"},yNe=et({__name:"ThinkingPanel",props:{text:{},subtitle:{}},emits:["close"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=Z(null);return Je(()=>n.text,()=>{const r=i.value;!r||!(r.scrollHeight-r.scrollTop-r.clientHeight<24)||yt(()=>{i.value&&(i.value.scrollTop=i.value.scrollHeight)})},{immediate:!0}),(r,l)=>(y(),M("div",vNe,[j(p(pc),{title:p(s)("common.preview"),subtitle:e.subtitle??p(s)("thinking.panelTitle"),"close-label":p(s)("thinking.close"),onClose:l[0]||(l[0]=a=>o("close"))},null,8,["title","subtitle","close-label"]),C("pre",{ref_key:"bodyEl",ref:i,class:"tp-body"},N(e.text),513)]))}}),kNe=ft(yNe,[["__scopeId","data-v-afb1f46f"]]),bNe={class:"agent-panel"},CNe={key:0,class:"agent-fallback"},wNe={key:0,class:"agent-error"},_Ne=et({__name:"AgentDetailPanel",props:{member:{},turns:{},running:{type:Boolean},loading:{type:Boolean},loadError:{type:Boolean},hasMore:{type:Boolean},loadingMore:{type:Boolean},loadMoreError:{type:Boolean}},emits:["close","loadOlderMessages","openAgent","openFile","openMedia","openTurnDiff"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.member.id),{scroller:r,following:l,onScroll:a,pinScroll:u}=_he(i),c=Z(!1);let d=null,f=null;function h(){d!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(d),f!==null&&clearTimeout(f),d=null,f=null}Je(i,()=>{c.value=!1,h();const _=()=>{h(),c.value=!0};typeof requestAnimationFrame=="function"?d=requestAnimationFrame(()=>{d=requestAnimationFrame(_)}):f=setTimeout(_,32)},{immediate:!0}),Vn(h);const m=R(()=>{const _=new Set,g=[];for(const x of[n.member.suspendedReason,n.member.text,n.member.outputLines?.join(` +`),n.member.summary]){const S=x?.trim();!S||_.has(S)||(_.add(S),g.push(S))}return g});Ln("pinScroll",()=>{r.value&&u()});function v(_){switch(_){case"queued":return s("tools.swarm.phaseQueued");case"working":return s("tools.swarm.phaseWorking");case"suspended":return s("tools.swarm.phaseSuspended");case"completed":return s("tools.swarm.phaseCompleted");case"failed":return s("tools.swarm.phaseFailed")}}const k=nn("modelDisplay"),w=nn("subagentEffort"),b=R(()=>{const _=[n.member.subagentType,k?.(n.member.model),w?.(n.member.thinkingEffort)].filter(g=>!!g);return _.length>0?_.join(" · "):void 0});return(_,g)=>(y(),M("div",bNe,[j(p(pc),{title:e.member.name,subtitle:b.value,"close-label":p(s)("thinking.close"),onClose:g[0]||(g[0]=x=>o("close"))},{default:me(()=>[j(p(Vr),{variant:"neutral",size:"sm"},{default:me(()=>[qe(N(v(e.member.phase)),1)]),_:1})]),_:1},8,["title","subtitle","close-label"]),C("div",{ref_key:"scroller",ref:r,class:"agent-transcript",onScrollPassive:g[6]||(g[6]=(...x)=>p(a)&&p(a)(...x))},[c.value?(y(),M(Pe,{key:0},[e.turns.length===0&&!e.loading&&(e.loadError||m.value.length>0)?(y(),M("div",CNe,[e.loadError?(y(),M("div",wNe,N(p(s)("tasks.transcriptLoadError")),1)):ee("",!0),m.value.length>0?(y(),he(dr,{key:1,lines:m.value},null,8,["lines"])):ee("",!0)])):(y(),he(e6,{key:1,turns:e.turns,"turn-active":e.running,"session-loading":e.loading&&e.turns.length===0,"has-more-messages":e.hasMore,"loading-more":e.loadingMore,"loading-more-error":e.loadMoreError,"is-following":p(l),"read-only":"",onLoadOlderMessages:g[1]||(g[1]=x=>o("loadOlderMessages")),onOpenAgent:g[2]||(g[2]=x=>o("openAgent",x)),onOpenFile:g[3]||(g[3]=x=>o("openFile",x)),onOpenMedia:g[4]||(g[4]=x=>o("openMedia",x)),onOpenTurnDiff:g[5]||(g[5]=x=>o("openTurnDiff",x))},null,8,["turns","turn-active","session-loading","has-more-messages","loading-more","loading-more-error","is-following"]))],64)):ee("",!0)],544)]))}}),xNe=ft(_Ne,[["__scopeId","data-v-95fdb6f0"]]),SNe={class:"sc"},ANe={key:0,class:"sc-empty"},MNe={key:2,class:"sc-loading"},TNe={class:"sc-composer"},ENe=["placeholder"],INe=["disabled"],LNe=et({__name:"SideChatPanel",props:{turns:{},running:{type:Boolean},sending:{type:Boolean},title:{},subtitle:{}},emits:["send","close","openMedia"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>n.turns.find(x=>x.role==="user")?.text?.trim()??""),r=R(()=>n.title?.trim()||s("sideChat.title")),l=R(()=>n.subtitle?.trim()?n.subtitle.trim():i.value||s("sideChat.subtitle")),a=Z(""),u=Z(null),c=Z(null);function d(){const g=a.value.trim();g&&(o("send",g),a.value="",yt(()=>{u.value&&(u.value.style.height="auto"),f()}))}function f(){const g=c.value;g&&(g.scrollTop=g.scrollHeight)}Ln("pinScroll",g=>{const x=c.value;if(!x)return;const S=g.getBoundingClientRect().top;requestAnimationFrame(()=>{x.scrollTop+=g.getBoundingClientRect().top-S})});const h=R(()=>{const g=n.turns;if(g.length===0)return"0";const x=g.at(-1),S=x.thinking?.length??0,T=x.tools?.reduce((A,E)=>A+E.name.length+(E.arg?.length??0)+(E.output?.join("").length??0),0)??0;return`${g.length}:${x.text.length}:${S}:${T}`});Je(h,async()=>{!n.running&&!n.sending||(await yt(),f())});const m=R(()=>n.sending?n.turns.at(-1)?.role==="user":!1),{handleCompositionStart:v,handleCompositionEnd:k,isComposingKeyEvent:w}=Ar();function b(g){g.key==="Enter"&&!g.shiftKey&&!w(g)&&(g.preventDefault(),d())}function _(){const g=u.value;g&&(g.style.height="auto",g.style.height=`${Math.min(g.scrollHeight,160)}px`)}return(g,x)=>(y(),M("div",SNe,[j(p(pc),{title:r.value,subtitle:l.value,"close-label":p(s)("thinking.close"),onClose:x[0]||(x[0]=S=>o("close"))},null,8,["title","subtitle","close-label"]),C("div",{ref_key:"bodyRef",ref:c,class:"sc-body"},[e.turns.length===0?(y(),M("div",ANe,N(p(s)("sideChat.empty")),1)):(y(),he(e6,{key:1,turns:e.turns,approvals:[],"turn-active":e.running,working:e.sending||e.running,"turn-files-interactive":!1,onOpenMedia:x[1]||(x[1]=S=>o("openMedia",S))},null,8,["turns","turn-active","working"])),m.value?(y(),M("div",MNe,[j(aF,{label:p(s)("conversation.requesting")},null,8,["label"])])):ee("",!0)],512),C("div",TNe,[Bn(C("textarea",{ref_key:"inputRef",ref:u,"onUpdate:modelValue":x[2]||(x[2]=S=>a.value=S),class:"sc-input",rows:"1",placeholder:p(s)("sideChat.placeholder"),onInput:_,onKeydown:b,onCompositionstart:x[3]||(x[3]=(...S)=>p(v)&&p(v)(...S)),onCompositionend:x[4]||(x[4]=(...S)=>p(k)&&p(k)(...S))},null,40,ENe),[[ai,a.value]]),j(p(pn),{text:p(s)("sideChat.send")},{default:me(()=>[C("button",{type:"button",class:"sc-send",disabled:!a.value.trim(),onClick:d},[j(p(Te),{name:"arrow-right",size:"sm"})],8,INe)]),_:1},8,["text"])])]))}}),$Ne=ft(LNe,[["__scopeId","data-v-753d11f0"]]),NNe={class:"changes-pane"},FNe={class:"dv-path"},RNe={class:"diff-head"},ONe={class:"back-label"},PNe={key:"loading",class:"empty-state diff-loading"},DNe={key:"lines",class:"dv-lines-wrap"},BNe={key:"empty",class:"empty-state"},HNe={class:"dv-change-count"},zNe={class:"ch-head"},WNe={class:"br-heading"},UNe={class:"br-label"},jNe={class:"br-name"},VNe={key:0,class:"sync-info"},qNe={key:0,class:"ahead"},KNe={key:0,class:"behind"},ZNe={key:1,class:"empty-head"},GNe={class:"ch-list-content"},YNe=["onClick"],XNe={class:"fpath"},JNe=["onClick"],QNe={class:"tree-name"},eFe=["onClick"],tFe={class:"tree-name"},nFe={key:2,class:"empty-state"},oFe={class:"empty-state-icon","aria-hidden":"true"},sFe={key:3,class:"empty-state"},iFe=et({__name:"DiffView",props:{changes:{},gitInfo:{},fileDiff:{},fullTexts:{},emptyFile:{type:Boolean},selectedDiffPath:{},fileDiffLoading:{type:Boolean},mode:{default:"full"},hideBack:{type:Boolean,default:!1},closable:{type:Boolean,default:!0}},emits:["open","back","close"],setup(e,{emit:t}){const{t:n}=Nt();function o($){return n($===1?"diff.fileCountOne":"diff.fileCountOther",{number:$})}const s=e,i=t;function r($){const B=$.toLowerCase();return B==="modified"?"modified":B==="added"?"added":B==="deleted"?"deleted":B==="renamed"?"renamed":B==="untracked"?"untracked":B==="conflicted"?"conflicted":B==="ignored"?"ignored":B==="clean"?"clean":"unknown"}const l={modified:"M",added:"+",deleted:"−",renamed:"→",untracked:"+",conflicted:"C",ignored:"I",clean:"·",unknown:"?"};function a($){return l[r($)]??"?"}function u($,B=60){return $.length<=B?$:"…"+$.slice($.length-B+1)}const c=R(()=>s.gitInfo!==null),d=R(()=>s.changes.length>0),f=R(()=>(s.selectedDiffPath??null)!==null),h=R(()=>s.mode==="detail"||s.mode==="full"&&f.value),m=R(()=>s.fileDiff??[]),v=R(()=>s.fileDiffLoading===!0);function k($){i("open",$)}function w(){i("back")}function b(){i("close")}const _=Z("list");function g($){_.value=$}function x($){const B={children:[]},H=[...$].sort((O,F)=>O.path.localeCompare(F.path));for(const O of H){const F=O.path.endsWith("/"),U=O.path.split("/").filter(Boolean);if(U.length===0)continue;let z=B;for(let W=0;W<U.length;W++){const K=U[W],V=W===U.length-1&&!F,ie=U.slice(0,W+1).join("/");let ne=z.children.find(X=>X.name===K&&X.kind===(V?"file":"folder"));ne||(ne={name:K,path:ie,kind:V?"file":"folder",status:V?O.status:void 0,children:[]},z.children.push(ne)),z=ne}}return B.children}const S=R(()=>x(s.changes)),T=Z(new Set);function A($){return!T.value.has($)}const E=R(()=>{const $=[];function B(H,O){for(const F of H)$.push({node:F,depth:O}),F.kind==="folder"&&A(F.path)&&B(F.children,O+1)}return B(S.value,0),$});function P($){const B=new Set(T.value);B.has($.path)?B.delete($.path):B.add($.path),T.value=B}function D($){return`calc(var(--tree-base-indent) + ${$} * var(--tree-indent-step))`}function I($){return{paddingLeft:D($),"--tree-depth":String($)}}return($,B)=>(y(),M("div",NNe,[h.value?(y(),M(Pe,{key:0},[j(p(pc),{title:p(n)("diff.title"),closable:e.closable,"close-label":p(n)("diff.close"),onClose:b},{default:me(()=>[j(p(pn),{text:e.selectedDiffPath??""},{default:me(()=>[C("span",FNe,N(u(e.selectedDiffPath??"",50)),1)]),_:1},8,["text"])]),_:1},8,["title","closable","close-label"]),C("div",RNe,[e.hideBack?ee("",!0):(y(),he(p(Rt),{key:0,variant:"ghost",size:"sm",onClick:w},{default:me(()=>[j(p(Te),{name:"arrow-left",size:"sm"}),C("span",ONe,N(p(n)("diff.back")),1)]),_:1}))]),j(as,{name:"diff-content",mode:"out-in"},{default:me(()=>[v.value?(y(),M("div",PNe,[j(p(Ao),{size:"md"}),C("span",null,N(p(n)("diff.loading")),1)])):m.value.length>0?(y(),M("div",DNe,[j(Ur,{lines:m.value,path:e.selectedDiffPath??void 0,"line-numbers":"",framed:!1,"full-texts":e.fullTexts??null},null,8,["lines","path","full-texts"])])):(y(),M("div",BNe,N(e.emptyFile?p(n)("diff.emptyFile"):p(n)("diff.noDiff")),1))]),_:1})],64)):(y(),M(Pe,{key:1},[j(p(pc),{title:p(n)("diff.title"),closable:e.closable,"close-label":p(n)("diff.close"),onClose:b},{default:me(()=>[C("span",HNe,N(o(e.changes.length)),1),j(p(wi),{"model-value":_.value,size:"sm",options:[{value:"list",label:p(n)("diff.list"),icon:"list"},{value:"tree",label:p(n)("diff.tree"),icon:"tree-view"}],"onUpdate:modelValue":g},null,8,["model-value","options"])]),_:1},8,["title","closable","close-label"]),C("div",zNe,[c.value?(y(),M(Pe,{key:0},[C("span",WNe,[j(p(Te),{class:"br-icon",name:"git-fork",size:"sm"}),C("span",UNe,N(p(n)("diff.branch")),1)]),C("span",jNe,N(e.gitInfo.branch),1),e.gitInfo.ahead>0||e.gitInfo.behind>0?(y(),M("span",VNe,[j(p(pn),{text:p(n)("diff.aheadTitle")},{default:me(()=>[e.gitInfo.ahead>0?(y(),M("span",qNe,"↑"+N(e.gitInfo.ahead),1)):ee("",!0)]),_:1},8,["text"]),j(p(pn),{text:p(n)("diff.behindTitle")},{default:me(()=>[e.gitInfo.behind>0?(y(),M("span",KNe,"↓"+N(e.gitInfo.behind),1)):ee("",!0)]),_:1},8,["text"])])):ee("",!0)],64)):(y(),M("span",ZNe,N(p(n)("diff.empty")),1))]),d.value&&_.value==="list"?(y(),he(p(Pk),{key:0,class:"ch-list"},{default:me(()=>[C("div",GNe,[(y(!0),M(Pe,null,pt(e.changes,H=>(y(),he(p(pn),{key:H.path,text:H.path},{default:me(()=>[C("button",{type:"button",class:"ch-row",onClick:O=>k(H.path)},[C("span",{class:Re(["badge",r(H.status)])},N(a(H.status)),3),C("span",XNe,N(u(H.path)),1)],8,YNe)]),_:2},1032,["text"]))),128))])]),_:1})):d.value&&_.value==="tree"?(y(),he(p(Pk),{key:1,class:"ch-list ch-tree"},{default:me(()=>[j(YA,{name:"tree-collapse",tag:"ul",class:"tree-list ch-list-content"},{default:me(()=>[(y(!0),M(Pe,null,pt(E.value,({node:H,depth:O})=>(y(),M("li",{key:H.path,class:"tree-node"},[H.kind==="folder"?(y(),M("button",{key:0,type:"button",class:"tree-row tree-folder",style:Zt(I(O)),onClick:F=>P(H)},[j(p(Te),{class:"tree-icon",name:"folder-solid",size:"sm"}),C("span",QNe,N(H.name),1)],12,JNe)):(y(),he(p(pn),{key:1,text:H.path},{default:me(()=>[C("button",{type:"button",class:"tree-row tree-file",style:Zt(I(O)),onClick:F=>k(H.path)},[C("span",{class:Re(["badge",r(H.status)])},N(a(H.status)),3),C("span",tFe,N(H.name),1)],12,eFe)]),_:2},1032,["text"]))]))),128))]),_:1})]),_:1})):c.value?(y(),M("div",nFe,[C("span",oFe,[j(p(Te),{name:"check",size:"lg"})]),qe(" "+N(p(n)("diff.clean")),1)])):(y(),M("div",sFe,N(p(n)("diff.empty")),1))],64))]))}}),rFe=ft(iFe,[["__scopeId","data-v-7d5ab9c7"]]),lFe={class:"td"},aFe={class:"td-path"},uFe={class:"td-body"},cFe={key:1,class:"td-empty"},dFe=et({__name:"TurnDiffPanel",props:{change:{},cwd:{},closable:{type:Boolean}},emits:["close","openFile"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=R(()=>{const a=n.cwd?h2(n.change.path,n.cwd):null;return r(a??n.change.path)});function r(a,u=48){return!a||a.length<=u?a:"…"+a.slice(a.length-u+1)}const l=R(()=>n.change.diff!==null&&n.change.diff.length>0);return(a,u)=>(y(),M("div",lFe,[j(p(pc),{title:p(s)("conversation.turnFiles.diffTitle"),closable:e.closable,"close-label":p(s)("filePreview.close"),onClose:u[1]||(u[1]=c=>o("close"))},{default:me(()=>[j(p(pn),{text:e.change.path},{default:me(()=>[C("span",aFe,N(i.value),1)]),_:1},8,["text"]),j(p(gn),{size:"sm",label:p(s)("conversation.turnFiles.openFile"),tooltip:p(s)("conversation.turnFiles.openFile"),onClick:u[0]||(u[0]=c=>o("openFile",e.change.path))},{default:me(()=>[j(p(Te),{name:"external-link",size:"md"})]),_:1},8,["label","tooltip"])]),_:1},8,["title","closable","close-label"]),C("div",uFe,[l.value?(y(),he(Ur,{key:0,lines:e.change.diff,path:e.change.path,framed:!1},null,8,["lines","path"])):(y(),M("div",cFe,[C("p",null,N(p(s)("conversation.turnFiles.diffUnavailable")),1),j(p(Rt),{variant:"ghost",size:"sm",onClick:u[2]||(u[2]=c=>o("openFile",e.change.path))},{default:me(()=>[qe(N(p(s)("conversation.turnFiles.openFile")),1)]),_:1})]))])]))}}),fFe=ft(dFe,[["__scopeId","data-v-fdd0bc05"]]);function gF(e,t){let n=null;dn(()=>{n=typeof document<"u"&&document.activeElement instanceof HTMLElement?document.activeElement:null,yt(()=>{const o=t?.value??e.value;try{o?.focus()}catch{}})}),Vn(()=>{const o=n;if(n=null,!(!o||typeof document>"u"||!document.contains(o)))try{o.focus()}catch{}})}const pFe={class:"search-wrap"},hFe=["aria-label"],mFe=["aria-label"],gFe=["aria-pressed","onClick"],vFe={key:1,class:"state-row"},yFe={key:2,class:"state-row unavail"},kFe=["aria-label"],bFe=["aria-selected","onClick","onMouseenter"],CFe={class:"model-main"},wFe={class:"model-name"},_Fe={class:"model-meta"},xFe={class:"model-side"},SFe={key:0,class:"empty"},AFe={class:"footer-hint","aria-hidden":"true"},MFe=et({__name:"ModelPicker",props:{models:{},current:{},starredIds:{},loading:{type:Boolean},unavailable:{type:Boolean}},emits:["select","toggle-star","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=R(()=>new Set(o.starredIds??[]));function r(D){return i.value.has(D)}const l=Z(""),a=Z(null),u=Z(null),c=Z(null),d=Z("all"),f={image_in:"model.capabilityImageInput",video_in:"model.capabilityVideoInput",tool_use:"model.capabilityToolUse",thinking:"model.capabilityThinking",always_thinking:"model.capabilityAlwaysThinking"};function h(D){const I=f[D];return I?n(I):D.replaceAll("_"," ")}function m(D){const I=[D.provider,n("model.contextSuffix",{size:Al(D.maxContextSize)})];for(const $ of D.capabilities??[])I.push(h($));return I.join(" · ")}gF(u,a);const v=R(()=>{const D=new Set,I=[{id:"all",label:n("model.allTab")}];for(const $ of o.models)D.has($.provider)||(D.add($.provider),I.push({id:$.provider,label:$.provider}));return I}),k=R(()=>{const D=l.value.toLowerCase().trim(),I=o.models.filter($=>{if(d.value!=="all"&&$.provider!==d.value)return!1;const B=($.displayName??$.model).toLowerCase().includes(D),H=$.provider.toLowerCase().includes(D),O=$.id.toLowerCase().includes(D);return!D||B||H||O});return d.value!=="all"?I:I.sort(($,B)=>{const H=r($.id)?1:0;return(r(B.id)?1:0)-H})}),w=R(()=>k.value),b=Z(0);Je([l,d],()=>{b.value=0}),Je(v,D=>{D.some(I=>I.id===d.value)||(d.value="all")}),Je(w,D=>{b.value=Math.min(b.value,Math.max(D.length-1,0))}),Je(b,async()=>{await yt(),c.value?.querySelector(".model-row.is-selected")?.scrollIntoView({block:"nearest"})});const{handleCompositionStart:_,handleCompositionEnd:g,isComposingKeyEvent:x}=Ar();function S(D){if(!x(D)){if(D.key==="Escape"){s("close");return}if(D.key==="ArrowDown")D.preventDefault(),b.value=Math.min(b.value+1,w.value.length-1);else if(D.key==="ArrowUp")D.preventDefault(),b.value=Math.max(b.value-1,0);else if(D.key==="Enter"){const I=w.value[b.value];I&&s("select",I.id)}}}dn(()=>{document.addEventListener("keydown",S)}),bn(()=>{document.removeEventListener("keydown",S)});function T(D){s("select",D)}function A(){l.value="",a.value?.focus()}function E(D){return w.value.indexOf(D)}function P(D){d.value=D}return(D,I)=>(y(),he(p(ua),{open:!0,"close-on-esc":!1,title:p(n)("model.title"),size:"lg",height:"fixed",padded:!1,onClose:I[1]||(I[1]=$=>s("close"))},{default:me(()=>[C("div",{ref_key:"dialogRef",ref:u,class:"mp"},[C("div",pFe,[j(p(js),{ref_key:"searchRef",ref:a,modelValue:l.value,"onUpdate:modelValue":I[0]||(I[0]=$=>l.value=$),placeholder:p(n)("model.searchPlaceholder"),autocomplete:"off",spellcheck:"false",autofocus:"",onCompositionstart:p(_),onCompositionend:p(g)},null,8,["modelValue","placeholder","onCompositionstart","onCompositionend"]),j(p(pn),{text:p(n)("model.clearSearch")},{default:me(()=>[C("button",{type:"button",class:Re(["search-clear",{"is-on":l.value.length>0}]),tabindex:"-1","aria-label":p(n)("model.clearSearch"),onClick:A},[j(p(Te),{name:"close",size:"sm"})],10,hFe)]),_:1},8,["text"])]),v.value.length>1?(y(),M("div",{key:0,class:"chip-strip","aria-label":p(n)("model.providerTabs")},[(y(!0),M(Pe,null,pt(v.value,$=>(y(),M("button",{key:$.id,type:"button",class:Re(["chip",{"is-active":$.id===d.value}]),"aria-pressed":$.id===d.value,onClick:B=>P($.id)},N($.label),11,gFe))),128))],8,mFe)):ee("",!0),e.loading?(y(),M("div",vFe,[j(p(Ao),{size:"sm"}),C("span",null,N(p(n)("model.loading")),1)])):e.unavailable?(y(),M("div",yFe,[j(p(Te),{name:"alert-triangle",size:"lg"}),C("span",null,N(p(n)("model.unavailable")),1)])):(y(),M("div",{key:3,ref_key:"listRef",ref:c,class:"model-list",role:"listbox","aria-label":p(n)("model.title")},[(y(!0),M(Pe,null,pt(w.value,$=>(y(),M("div",{key:$.id,class:Re(["model-row",{"is-current":$.id===e.current,"is-selected":E($)===b.value}]),role:"option","aria-selected":$.id===e.current,onClick:B=>T($.id),onMouseenter:B=>b.value=E($)},[C("span",CFe,[C("span",wFe,N($.displayName??$.model),1),C("span",_Fe,N(m($)),1)]),C("span",xFe,[$.id===e.current?(y(),he(p(Te),{key:0,class:"model-check",name:"check",size:"sm"})):ee("",!0),j(p(gn),{class:Re(["model-star",{"is-starred":r($.id)}]),size:"sm",label:r($.id)?p(n)("model.unstarTitle"):p(n)("model.starTitle"),tooltip:r($.id)?p(n)("model.unstarTitle"):p(n)("model.starTitle"),onClick:It(B=>s("toggle-star",$.id),["stop"])},{default:me(()=>[r($.id)?(y(),he(p(Te),{key:0,name:"star",size:"md"})):(y(),he(p(Te),{key:1,name:"star-outline",size:"md"}))]),_:2},1032,["class","label","tooltip","onClick"])])],42,bFe))),128)),w.value.length===0?(y(),M("div",SFe,N(o.models.length===0?p(n)("model.emptyNoModels"):p(n)("model.emptyNoMatch")),1)):ee("",!0)],8,kFe)),C("div",AFe,[j(p(oa),{keys:["↑","↓"]}),C("span",null,N(p(n)("model.hintNavigate")),1),I[2]||(I[2]=C("span",{class:"hint-dot"},"·",-1)),j(p(oa),{keys:["Enter"]}),C("span",null,N(p(n)("model.hintSelect")),1),I[3]||(I[3]=C("span",{class:"hint-dot"},"·",-1)),j(p(oa),{keys:["Esc"]}),C("span",null,N(p(n)("model.hintClose")),1)])],512)]),_:1},8,["title"]))}}),TFe=ft(MFe,[["__scopeId","data-v-3ba22330"]]),EFe=3;function vF(e){const t=Z("starting"),n=Z(!1),o=Z(null),s=Z(0);let i=null,r=null,l=null,a=0,u=!1,c=!1;function d(){i&&(clearTimeout(i),i=null),r&&(clearInterval(r),r=null),l&&(clearTimeout(l),l=null)}function f(w){d(),t.value="success",l=setTimeout(()=>{l=null,e.onSuccess?.()},w)}function h(){r&&clearInterval(r),r=setInterval(()=>{s.value>0?s.value--:(r&&clearInterval(r),r=null)},1e3)}function m(w){i&&clearTimeout(i),i=setTimeout(async()=>{const b=await e.onPollOAuthLogin();if(!c){if(b===null){if(a+=1,a>=EFe){d(),n.value=!0,t.value="error";return}m(w);return}a=0,b.status==="authenticated"?f(1200):b.status==="expired"||b.status==="cancelled"?(d(),t.value="expired"):m(w)}},w*1e3)}async function v(){d(),o.value=null,n.value=!1,a=0,u=!1,t.value="starting";const w=await e.onStartOAuthLogin();if(c){w!==null&&w.status!=="authenticated"&&e.onCancelOAuthLogin();return}if(!w){t.value="error";return}if(w.status==="authenticated"){f(800);return}o.value={flowId:w.flowId,verificationUri:w.verificationUri,verificationUriComplete:w.verificationUriComplete,userCode:w.userCode,expiresIn:w.expiresIn,interval:w.interval},s.value=w.expiresIn,t.value="device-code",h(),m(w.interval)}function k(){t.value!=="success"&&(d(),t.value==="device-code"&&!u&&(u=!0,e.onCancelOAuthLogin()))}return Kg()&&d1(()=>{c=!0,k()}),{step:t,pollError:n,flow:o,secondsLeft:s,startFlow:v,cancelFlow:k}}const IFe={key:0,class:"center-body"},LFe={class:"center-text"},$Fe={key:1,class:"nb"},NFe={class:"nb-lead"},FFe=["href"],RFe={class:"nb-code-row"},OFe=["title"],PFe={class:"nb-status"},DFe={class:"nb-status-text"},BFe={class:"nb-countdown"},HFe={key:2,class:"center-body"},zFe={class:"center-text success-text"},WFe={class:"center-hint"},UFe={class:"center-body"},jFe={class:"center-text err-text"},VFe={class:"center-hint"},qFe={class:"actions"},KFe={class:"center-body"},ZFe={class:"center-text warn-text"},GFe={class:"center-hint"},YFe={class:"actions"},XFe=et({__name:"LoginDialog",props:{onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function}},emits:["success","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=Z(!0),s=t,i=e,{step:r,pollError:l,flow:a,secondsLeft:u,startFlow:c,cancelFlow:d}=vF({onStartOAuthLogin:i.onStartOAuthLogin,onPollOAuthLogin:i.onPollOAuthLogin,onCancelOAuthLogin:i.onCancelOAuthLogin,onSuccess:()=>{s("success"),s("close")}}),f=Z(!1);dn(async()=>{await c()});async function h(){!a.value||!await Zs(a.value.verificationUriComplete)||(f.value=!0,setTimeout(()=>{f.value=!1},2e3))}async function m(){d(),s("close")}function v(k){const w=Math.floor(k/60),b=k%60;return`${w}:${String(b).padStart(2,"0")}`}return(k,w)=>(y(),he(p(ua),{open:o.value,"onUpdate:open":w[0]||(w[0]=b=>o.value=b),title:p(n)("login.title"),"close-on-overlay":!1,onClose:m},{default:me(()=>[p(r)==="starting"?(y(),M("div",IFe,[j(p(Ao),{size:"md"}),C("span",LFe,N(p(n)("login.starting")),1)])):p(r)==="device-code"&&p(a)?(y(),M("div",$Fe,[C("div",NFe,N(p(n)("login.lead")),1),C("a",{class:"nb-primary",href:p(a).verificationUriComplete,target:"_blank",rel:"noopener noreferrer"},[qe(N(p(n)("login.authorizeInBrowser"))+" ",1),j(p(Te),{name:"external-link",size:"sm"})],8,FFe),C("div",RFe,[C("span",{class:"nb-link",title:p(a).verificationUriComplete},N(p(a).verificationUriComplete),9,OFe),j(p(Rt),{class:Re(["nb-copy",{"is-copied":f.value}]),variant:"secondary",size:"sm",onClick:h},{default:me(()=>[f.value?(y(),M(Pe,{key:0},[j(p(Te),{name:"check",size:"sm"}),qe(" "+N(p(n)("login.copied")),1)],64)):(y(),M(Pe,{key:1},[j(p(Te),{name:"copy",size:"sm"}),qe(" "+N(p(n)("login.copyLink")),1)],64))]),_:1},8,["class"])]),C("div",PFe,[j(p(Ao),{size:"sm",label:p(n)("login.waitingAuth")},null,8,["label"]),C("span",DFe,N(p(n)("login.waitingAutoClose")),1),C("span",BFe,N(v(p(u))),1)])])):p(r)==="success"?(y(),M("div",HFe,[j(p(Dd),{kind:"success"}),C("span",zFe,N(p(n)("login.success")),1),C("span",WFe,N(p(n)("login.successHint")),1)])):p(r)==="expired"?(y(),M(Pe,{key:3},[C("div",UFe,[j(p(Dd),{kind:"expired"}),C("span",jFe,N(p(n)("login.expiredTitle")),1),C("span",VFe,N(p(n)("login.expiredHint")),1)]),C("div",qFe,[j(p(Rt),{variant:"primary",onClick:p(c)},{default:me(()=>[qe(N(p(n)("login.retry")),1)]),_:1},8,["onClick"]),j(p(Rt),{variant:"secondary",onClick:m},{default:me(()=>[qe(N(p(n)("login.closeBtn")),1)]),_:1})])],64)):p(r)==="error"?(y(),M(Pe,{key:4},[C("div",KFe,[j(p(Dd),{kind:"error"}),C("span",ZFe,N(p(l)?p(n)("login.pollErrorTitle"):p(n)("login.errorTitle")),1),C("span",GFe,N(p(l)?p(n)("login.pollErrorHint"):p(n)("login.errorHint")),1)]),C("div",YFe,[j(p(Rt),{variant:"primary",onClick:p(c)},{default:me(()=>[qe(N(p(n)("login.retry")),1)]),_:1},8,["onClick"]),j(p(Rt),{variant:"secondary",onClick:m},{default:me(()=>[qe(N(p(n)("login.closeBtn")),1)]),_:1})])],64)):ee("",!0)]),_:1},8,["open","title"]))}}),JFe=ft(XFe,[["__scopeId","data-v-c798a107"]]),yF=et({__name:"LanguageSwitcher",props:{size:{default:"md"}},setup(e){const{locale:t}=Nt(),n=yg.map(s=>({value:s.code,label:s.label}));function o(s){t.value!==s&&E5(s)}return(s,i)=>(y(),he(p(wi),{"model-value":p(t),options:p(n),size:e.size,"onUpdate:modelValue":o},null,8,["model-value","options","size"]))}}),QFe={class:"msg"},eRe={class:"pf-field"},tRe={class:"pf-field-label"},nRe={class:"pf-field"},oRe={class:"pf-field-label"},sRe={class:"pf-field"},iRe={class:"pf-field-label"},rRe={class:"pf-key-wrap"},lRe={class:"pf-field"},aRe={class:"pf-field-label"},uRe={class:"pf-field"},cRe={class:"pf-field-label"},dRe={class:"pf-models"},fRe={key:0,class:"pf-models-empty"},pRe={class:"pf-model-grid pf-model-head"},hRe={key:1},mRe={key:0},gRe={class:"pf-foot"},vRe={key:0,class:"pf-managed-note"},yRe={class:"pf-confirm-msg"},kRe=et({__name:"ProviderForm",props:{mode:{},provider:{},guard:{type:Boolean}},emits:["dirtyChange","guardStay","guardDiscard","added","saved","deleting","deleted","cancel"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=mu(),r=Go({id:"",type:"openai",apiKey:"",baseUrl:"",models:[rh()]}),l=Z(""),a=Z(!1),u=Z(!1),c=Z(!1),d=R(()=>n.mode==="add"),f=R(()=>n.provider!==void 0&&mE(n.provider)),h=R(()=>{const $=n.provider;return $===void 0?0:w3($,i.config.value?.models).length}),m=R(()=>f.value&&h.value===0),v=R(()=>DJ.map($=>({value:$,label:s(`providers.types.${$}`)}))),k=R(()=>f.value?s("providers.apiKeyManaged"):!d.value&&n.provider?.hasApiKey===!0?s("providers.apiKeySet"):"sk-…");function w(){l.value="",u.value=!1;const $=n.provider;if(d.value||$===void 0){r.id="",r.type="openai",r.apiKey="",r.baseUrl="",r.models=[rh()];return}r.id=$.id,r.type=$.type,r.apiKey="",r.baseUrl=$.baseUrl??"";const B=w3($,i.config.value?.models);r.models=B.length>0?B:[rh()]}dn(()=>{w(),g()});const b=Z(!1),_=Z(!1);async function g(){const $=n.provider;if(!(d.value||$===void 0||f.value||$.hasApiKey!==!0))try{const B=await i.getProvider($.id);if(_.value)return;B.apiKey!==void 0&&B.apiKey!==""&&(r.apiKey=B.apiKey,b.value=!0)}catch{}}function x(){o("dirtyChange",!0)}const S=Z(!1),T=Z();function A($){l.value=$,yt(()=>T.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}async function E(){if(a.value)return;const $=BJ(r,{requireApiKey:d.value,requireBaseUrl:d.value});if($!==null){A(s(`providers.error.${$}`));return}l.value="",a.value=!0;try{if(d.value){const B=await i.addProvider(HJ(r));if(B!==null){A(B);return}o("dirtyChange",!1),i.notify({severity:"success",title:s("providers.added")}),o("added",r.id.trim())}else{const B=n.provider;if(B===void 0)return;const H=i.config.value?.providers?.[B.id]?.defaultModel,O=await i.updateProvider(B.id,zJ(r,B,{includeBlankApiKey:b.value,existingDefaultModel:H}));if(O!==null){A(O);return}await i.checkAuth(),i.notify({severity:"success",title:s("providers.saved")}),o("dirtyChange",!1),o("saved",r.id.trim())}}finally{a.value=!1}}async function P(){const $=n.provider;if(!($===void 0||c.value)){c.value=!0,o("deleting"),await new Promise(B=>setTimeout(B,300));try{if(await i.deleteProvider($.id)===null){u.value=!1;return}o("dirtyChange",!1),o("deleted",$.id)}finally{c.value=!1}}}function D(){r.models.push(rh()),x()}function I($){r.models.length<=1||(r.models.splice($,1),x())}return($,B)=>(y(),M("div",{class:"pf-form",onInput:x},[e.guard?(y(),he(p(qu),{key:0,variant:"warning",class:"pf-guard"},{default:me(()=>[C("span",QFe,N(p(s)("providers.unsavedGuard")),1),j(p(Rt),{variant:"secondary",size:"sm",onClick:B[0]||(B[0]=H=>o("guardStay"))},{default:me(()=>[qe(N(p(s)("providers.guardStay")),1)]),_:1}),j(p(Rt),{variant:"danger",size:"sm",onClick:B[1]||(B[1]=H=>o("guardDiscard"))},{default:me(()=>[qe(N(p(s)("providers.guardDiscard")),1)]),_:1})]),_:1})):ee("",!0),l.value?(y(),M("div",{key:1,ref_key:"errorBox",ref:T},[j(p(qu),{variant:"danger"},{default:me(()=>[qe(N(l.value),1)]),_:1})],512)):ee("",!0),C("div",eRe,[C("label",tRe,[qe(N(p(s)("providers.fieldId")),1),B[11]||(B[11]=C("span",{class:"req"}," *",-1))]),j(p(js),{modelValue:r.id,"onUpdate:modelValue":B[2]||(B[2]=H=>r.id=H),placeholder:"my-openai",disabled:f.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","disabled"])]),C("div",nRe,[C("label",oRe,[qe(N(p(s)("providers.fieldType")),1),B[12]||(B[12]=C("span",{class:"req"}," *",-1))]),j(p(n3),{"model-value":r.type,options:v.value,disabled:f.value,"onUpdate:modelValue":B[3]||(B[3]=H=>{r.type=H,x()})},null,8,["model-value","options","disabled"])]),C("div",sRe,[C("label",iRe,[qe(N(p(s)("providers.fieldApiKey")),1),B[13]||(B[13]=C("span",{class:"req"}," *",-1))]),C("div",rRe,[j(p(js),{modelValue:r.apiKey,"onUpdate:modelValue":B[4]||(B[4]=H=>r.apiKey=H),type:S.value?"text":"password",placeholder:k.value,disabled:f.value,autocomplete:"off",spellcheck:"false",onInput:B[5]||(B[5]=H=>_.value=!0)},null,8,["modelValue","type","placeholder","disabled"]),f.value?ee("",!0):(y(),he(p(gn),{key:0,class:"pf-key-eye",size:"sm",label:p(s)(S.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:p(s)(S.value?"providers.hideApiKey":"providers.showApiKey"),onClick:B[6]||(B[6]=H=>S.value=!S.value)},{default:me(()=>[j(p(Te),{name:S.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"]))])]),C("div",lRe,[C("label",aRe,[qe(N(p(s)("providers.fieldBaseUrl")),1),B[14]||(B[14]=C("span",{class:"req"}," *",-1))]),j(p(js),{modelValue:r.baseUrl,"onUpdate:modelValue":B[7]||(B[7]=H=>r.baseUrl=H),placeholder:p(s)("providers.baseUrlPlaceholder"),disabled:f.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder","disabled"])]),C("div",uRe,[C("label",cRe,[qe(N(p(s)("providers.fieldModels")),1),B[15]||(B[15]=C("span",{class:"req"}," *",-1))]),C("div",dRe,[m.value?(y(),M("div",fRe,N(p(s)("providers.noModels")),1)):(y(),M(Pe,{key:1},[C("div",pRe,[C("span",null,[qe(N(p(s)("providers.colModelId")),1),B[16]||(B[16]=C("span",{class:"req"}," *",-1))]),C("span",null,[qe(N(p(s)("providers.colContext")),1),B[17]||(B[17]=C("span",{class:"req"}," *",-1))]),C("span",null,N(p(s)("providers.colDisplayName")),1),B[18]||(B[18]=C("span",null,null,-1))]),(y(!0),M(Pe,null,pt(r.models,(H,O)=>(y(),M("div",{key:O,class:"pf-model-grid"},[j(p(js),{modelValue:H.model,"onUpdate:modelValue":F=>H.model=F,placeholder:p(s)("providers.modelIdPlaceholder"),disabled:f.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),j(p(js),{modelValue:H.maxContextSize,"onUpdate:modelValue":F=>H.maxContextSize=F,inputmode:"numeric",placeholder:p(s)("providers.modelContextPlaceholder"),disabled:f.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),j(p(js),{modelValue:H.displayName,"onUpdate:modelValue":F=>H.displayName=F,placeholder:p(s)("providers.modelNamePlaceholder"),disabled:f.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),f.value?(y(),M("span",hRe)):(y(),he(p(gn),{key:0,size:"sm",label:p(s)("providers.removeModel"),tooltip:p(s)("providers.removeModel"),disabled:r.models.length<=1,onClick:F=>I(O)},{default:me(()=>[j(p(Te),{name:"trash",size:"sm"})]),_:1},8,["label","tooltip","disabled","onClick"]))]))),128)),f.value?ee("",!0):(y(),M("div",mRe,[j(p(Rt),{variant:"ghost",size:"sm",onClick:D},{default:me(()=>[j(p(Te),{name:"plus",size:"sm"}),qe(" "+N(p(s)("providers.addModel")),1)]),_:1})]))],64))])]),C("div",gRe,[f.value?(y(),M("span",vRe,N(p(s)("providers.managedHint")),1)):d.value?(y(),M(Pe,{key:1},[j(p(Rt),{variant:"secondary",size:"sm",onClick:B[8]||(B[8]=H=>o("cancel"))},{default:me(()=>[qe(N(p(s)("common.cancel")),1)]),_:1}),j(p(Rt),{variant:"primary",size:"sm",disabled:a.value,onClick:E},{default:me(()=>[qe(N(p(s)("providers.addProvider")),1)]),_:1},8,["disabled"])],64)):u.value&&n.provider!==void 0?(y(),M(Pe,{key:2},[C("span",yRe,N(p(s)("providers.deleteConfirm",{id:n.provider.id,count:h.value})),1),B[19]||(B[19]=C("span",{class:"spacer"},null,-1)),j(p(Rt),{variant:"secondary",size:"sm",disabled:c.value,onClick:B[9]||(B[9]=H=>u.value=!1)},{default:me(()=>[qe(N(p(s)("common.cancel")),1)]),_:1},8,["disabled"]),j(p(Rt),{variant:"danger",size:"sm",disabled:c.value,onClick:P},{default:me(()=>[qe(N(p(s)("providers.deleteConfirmYes")),1)]),_:1},8,["disabled"])],64)):(y(),M(Pe,{key:3},[j(p(Rt),{variant:"danger-soft",size:"sm",onClick:B[10]||(B[10]=H=>u.value=!0)},{default:me(()=>[qe(N(p(s)("providers.deleteProvider")),1)]),_:1}),B[20]||(B[20]=C("span",{class:"spacer"},null,-1)),j(p(Rt),{variant:"primary",size:"sm",disabled:a.value,onClick:E},{default:me(()=>[qe(N(p(s)("providers.save")),1)]),_:1},8,["disabled"])],64))])],32))}}),kF=ft(kRe,[["__scopeId","data-v-ac0597e3"]]),bRe={class:"af"},CRe={class:"msg"},wRe={key:2,class:"af-catalog"},_Re={key:0,class:"af-center"},xRe={key:1,class:"af-error"},SRe={class:"af-list"},ARe=["disabled","onClick"],MRe={class:"af-entry-name"},TRe={key:1,class:"af-entry-reason"},ERe={key:2,class:"af-entry-count"},IRe={key:0,class:"af-empty"},LRe={class:"af-field"},$Re={class:"af-label"},NRe={class:"af-field"},FRe={class:"af-label"},RRe={class:"af-key-wrap"},ORe={key:0,class:"af-field"},PRe={class:"af-label"},DRe={class:"af-note"},BRe={class:"af-foot"},HRe={class:"af-hint"},zRe={class:"af-field"},WRe={class:"af-label"},URe={class:"af-field"},jRe={class:"af-label"},VRe={class:"af-key-wrap"},qRe={class:"af-foot"},KRe={class:"af-manual"},ZRe=et({__name:"AddProviderFlow",props:{guard:{type:Boolean}},emits:["dirtyChange","guardStay","guardDiscard","added","cancel"],setup(e,{emit:t}){const n=t,{t:o,te:s}=Nt(),i=mu(),r=Z("catalog"),l=R(()=>[{value:"catalog",label:o("providers.catalog.sourceCatalog")},{value:"registry",label:o("providers.catalog.sourceRegistry")},{value:"manual",label:o("providers.catalog.sourceManual")}]),a=Z("loading"),u=Z([]);async function c(){a.value="loading";const U=await i.loadCatalogProviders();U.kind==="ok"?(u.value=U.items,a.value="ready"):U.kind==="unsupported"?(a.value="unsupported",r.value==="catalog"&&(r.value="manual")):a.value="error"}dn(c);const d=Z(""),f=R(()=>{const U=d.value.trim().toLowerCase();return U===""?u.value:u.value.filter(z=>z.name.toLowerCase().includes(U)||z.id.toLowerCase().includes(U))});function h(U){const z=U.rejectReason;return z!==null&&s(`providers.catalog.rejectReason.${z}`)?o(`providers.catalog.rejectReason.${z}`):o("providers.catalog.rejected")}const m=Z(null),v=Z({id:"",apiKey:"",baseUrl:""}),k=Z(!1),w=Z(!1),b=Z("");function _(U){m.value=U,v.value={id:U.id,apiKey:"",baseUrl:""},b.value="",k.value=!1}function g(){m.value=null,b.value="",n("dirtyChange",!1)}function x(){n("dirtyChange",!0)}const S=R(()=>{if(m.value===null)return!1;const z=v.value.id.trim();return z!==""&&i.providers.value.some(W=>W.id===z)}),T=Z();function A(U){b.value=U,yt(()=>T.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}function E(){const U=v.value,z=U.id.trim();return z===""?o("providers.error.idRequired"):pE.test(z)?U.apiKey.trim()===""?o("providers.error.apiKeyRequired"):m.value?.needsBaseUrl===!0&&U.baseUrl.trim()===""?o("providers.error.baseUrlRequired"):null:o("providers.error.idInvalid")}async function P(){const U=m.value;if(U===null||w.value)return;const z=E();if(z!==null){A(z);return}b.value="",w.value=!0;try{const W=v.value,K=W.id.trim(),V=W.baseUrl.trim(),ie=await i.importCatalogProvider({catalogId:U.id,apiKey:W.apiKey.trim(),...V===""?{}:{baseUrl:V},...K===U.id?{}:{id:K}});if(ie!==null){A(ie);return}i.notify({severity:"success",title:o("providers.added")}),n("dirtyChange",!1),n("added",K)}finally{w.value=!1}}const D=Z({url:"",apiKey:""}),I=Z(!1),$=Z(!1),B=Z(""),H=Z();function O(U){B.value=U,yt(()=>H.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}async function F(){if($.value)return;const U=D.value.url.trim();if(U===""){O(o("providers.error.registryUrlRequired"));return}B.value="",$.value=!0;try{const z=D.value.apiKey.trim(),W=await i.importCustomRegistry({url:U,...z===""?{}:{apiKey:z}});if(typeof W=="string"){O(W);return}i.notify({severity:"success",title:o("providers.catalog.registryImported",{count:W.providers.length})}),n("dirtyChange",!1);const K=W.providers[0];K!==void 0?n("added",K.id):n("cancel")}finally{$.value=!1}}return(U,z)=>(y(),M("div",bRe,[e.guard?(y(),he(p(qu),{key:0,variant:"warning",class:"af-guard"},{default:me(()=>[C("span",CRe,N(p(o)("providers.unsavedGuard")),1),j(p(Rt),{variant:"secondary",size:"sm",onClick:z[0]||(z[0]=W=>n("guardStay"))},{default:me(()=>[qe(N(p(o)("providers.guardStay")),1)]),_:1}),j(p(Rt),{variant:"danger",size:"sm",onClick:z[1]||(z[1]=W=>n("guardDiscard"))},{default:me(()=>[qe(N(p(o)("providers.guardDiscard")),1)]),_:1})]),_:1})):ee("",!0),a.value!=="unsupported"?(y(),he(p(wi),{key:1,modelValue:r.value,"onUpdate:modelValue":z[2]||(z[2]=W=>r.value=W),size:"sm",options:l.value},null,8,["modelValue","options"])):ee("",!0),a.value!=="unsupported"?Bn((y(),M("div",wRe,[a.value==="loading"?(y(),M("div",_Re,[j(p(Ao),{size:"sm"}),C("span",null,N(p(o)("providers.catalog.loading")),1)])):a.value==="error"?(y(),M("div",xRe,[j(p(qu),{variant:"danger"},{default:me(()=>[qe(N(p(o)("providers.catalog.loadError")),1)]),_:1}),C("div",null,[j(p(Rt),{variant:"secondary",size:"sm",onClick:c},{default:me(()=>[qe(N(p(o)("providers.catalog.retry")),1)]),_:1})])])):m.value===null?(y(),M(Pe,{key:2},[j(p(js),{modelValue:d.value,"onUpdate:modelValue":z[3]||(z[3]=W=>d.value=W),placeholder:p(o)("providers.catalog.searchPlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder"]),C("div",SRe,[(y(!0),M(Pe,null,pt(f.value,W=>(y(),M("button",{key:W.id,type:"button",class:"af-entry",disabled:W.rejected,onClick:K=>_(W)},[C("span",MRe,N(W.name),1),W.wireType!==null?(y(),he(p(Vr),{key:0,variant:"neutral",size:"sm"},{default:me(()=>[qe(N(W.wireType),1)]),_:2},1024)):ee("",!0),z[16]||(z[16]=C("span",{class:"grow"},null,-1)),W.rejected?(y(),M("span",TRe,N(h(W)),1)):(y(),M("span",ERe,N(p(o)("providers.modelCount",{count:W.models.length})),1))],8,ARe))),128)),f.value.length===0?(y(),M("div",IRe,N(p(o)("providers.catalog.empty")),1)):ee("",!0)])],64)):(y(),M("div",{key:3,class:"af-import",onInput:x},[C("button",{type:"button",class:"af-back",onClick:g},[j(p(Te),{name:"arrow-left",size:"sm"}),qe(" "+N(p(o)("providers.catalog.backToList")),1)]),C("div",LRe,[C("label",$Re,[qe(N(p(o)("providers.fieldId")),1),z[17]||(z[17]=C("span",{class:"req"}," *",-1))]),j(p(js),{modelValue:v.value.id,"onUpdate:modelValue":z[4]||(z[4]=W=>v.value.id=W),autocomplete:"off",spellcheck:"false"},null,8,["modelValue"])]),C("div",NRe,[C("label",FRe,[qe(N(p(o)("providers.fieldApiKey")),1),z[18]||(z[18]=C("span",{class:"req"}," *",-1))]),C("div",RRe,[j(p(js),{modelValue:v.value.apiKey,"onUpdate:modelValue":z[5]||(z[5]=W=>v.value.apiKey=W),type:k.value?"text":"password",placeholder:"sk-…",autocomplete:"off",spellcheck:"false"},null,8,["modelValue","type"]),j(p(gn),{class:"af-key-eye",size:"sm",label:p(o)(k.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:p(o)(k.value?"providers.hideApiKey":"providers.showApiKey"),onClick:z[6]||(z[6]=W=>k.value=!k.value)},{default:me(()=>[j(p(Te),{name:k.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])])]),m.value.needsBaseUrl?(y(),M("div",ORe,[C("label",PRe,[qe(N(p(o)("providers.fieldBaseUrl")),1),z[19]||(z[19]=C("span",{class:"req"}," *",-1))]),j(p(js),{modelValue:v.value.baseUrl,"onUpdate:modelValue":z[7]||(z[7]=W=>v.value.baseUrl=W),placeholder:p(o)("providers.baseUrlPlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder"])])):ee("",!0),S.value?(y(),he(p(qu),{key:1,variant:"warning"},{default:me(()=>[qe(N(p(o)("providers.catalog.overwriteWarning")),1)]),_:1})):ee("",!0),C("div",DRe,N(p(o)("providers.catalog.willImport",{count:m.value.models.length})),1),b.value?(y(),M("div",{key:2,ref_key:"importErrorBox",ref:T},[j(p(qu),{variant:"danger"},{default:me(()=>[qe(N(b.value),1)]),_:1})],512)):ee("",!0),C("div",BRe,[j(p(Rt),{variant:"secondary",size:"sm",onClick:z[8]||(z[8]=W=>n("cancel"))},{default:me(()=>[qe(N(p(o)("common.cancel")),1)]),_:1}),j(p(Rt),{variant:"primary",size:"sm",disabled:w.value,onClick:P},{default:me(()=>[qe(N(p(o)("providers.catalog.importAction")),1)]),_:1},8,["disabled"])])],32))],512)),[[qs,r.value==="catalog"]]):ee("",!0),Bn(C("div",{class:"af-registry",onInput:x},[C("div",HRe,N(p(o)("providers.catalog.registryHint")),1),C("div",zRe,[C("label",WRe,[qe(N(p(o)("providers.catalog.registryUrlLabel")),1),z[20]||(z[20]=C("span",{class:"req"}," *",-1))]),j(p(js),{modelValue:D.value.url,"onUpdate:modelValue":z[9]||(z[9]=W=>D.value.url=W),placeholder:"https://example.com/api.json",autocomplete:"off",spellcheck:"false"},null,8,["modelValue"])]),C("div",URe,[C("label",jRe,N(p(o)("providers.fieldApiKey")),1),C("div",VRe,[j(p(js),{modelValue:D.value.apiKey,"onUpdate:modelValue":z[10]||(z[10]=W=>D.value.apiKey=W),type:I.value?"text":"password",placeholder:p(o)("providers.modelNamePlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","type","placeholder"]),j(p(gn),{class:"af-key-eye",size:"sm",label:p(o)(I.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:p(o)(I.value?"providers.hideApiKey":"providers.showApiKey"),onClick:z[11]||(z[11]=W=>I.value=!I.value)},{default:me(()=>[j(p(Te),{name:I.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])])]),B.value?(y(),M("div",{key:0,ref_key:"registryErrorBox",ref:H},[j(p(qu),{variant:"danger"},{default:me(()=>[qe(N(B.value),1)]),_:1})],512)):ee("",!0),C("div",qRe,[j(p(Rt),{variant:"secondary",size:"sm",onClick:z[12]||(z[12]=W=>n("cancel"))},{default:me(()=>[qe(N(p(o)("common.cancel")),1)]),_:1}),j(p(Rt),{variant:"primary",size:"sm",disabled:$.value,onClick:F},{default:me(()=>[qe(N(p(o)("providers.catalog.importAction")),1)]),_:1},8,["disabled"])])],544),[[qs,r.value==="registry"]]),Bn(C("div",KRe,[j(kF,{mode:"add",guard:!1,onDirtyChange:z[13]||(z[13]=W=>n("dirtyChange",W)),onAdded:z[14]||(z[14]=W=>n("added",W)),onCancel:z[15]||(z[15]=W=>n("cancel"))})],512),[[qs,r.value==="manual"]])]))}}),GRe=ft(ZRe,[["__scopeId","data-v-9e5ec0a8"]]),YRe={class:"pp"},XRe={class:"pp-head"},JRe={class:"pp-title"},QRe={key:0,class:"pp-loading"},eOe={key:1,class:"pp-group"},tOe={class:"pp-add-label"},nOe={class:"pp-chev"},oOe={class:"pp-acc"},sOe={class:"pp-acc-in"},iOe={key:1,class:"pp-empty"},rOe=["onClick"],lOe={class:"grow"},aOe={class:"pp-id"},uOe={class:"pp-count"},cOe={class:"pp-chev"},dOe={class:"pp-acc"},fOe={class:"pp-acc-in"},Wu="$add",pOe=et({__name:"ProvidersPanel",setup(e){const{t}=Nt(),n=mu(),o=Z(!0),s=Z(null),i=Z(null);let r=0;const l=Z(!1),a=Z(!1),u=Z(null),c=Z("");let d=0;const f=R(()=>[...n.providers.value].sort((S,T)=>S.id.localeCompare(T.id)));function h(S){return w3(S,n.config.value?.models).length}Je(s,(S,T)=>{T!==null&&T!==S&&(i.value=T,window.clearTimeout(r),r=window.setTimeout(()=>{i.value=null},300)),l.value=!1}),Je(l,S=>{S||(a.value=!1,u.value=null)}),bn(()=>{window.clearTimeout(r),window.clearTimeout(d)});const m=Z(!1);Je(s,S=>{S===Wu?(m.value=!1,yt(()=>requestAnimationFrame(()=>{m.value=!0}))):m.value=!1}),dn(async()=>{o.value=!0;try{await Promise.all([n.loadProviders(),n.loadModels(),n.loadConfig()])}finally{o.value=!1}});function v(S){const T=s.value===S?null:S;if(l.value){u.value=T,a.value=!0;return}s.value=T}function k(){a.value=!1,u.value=null}function w(){a.value=!1,s.value=u.value,u.value=null}function b(S){c.value=S,window.clearTimeout(d),d=window.setTimeout(()=>{c.value=""},1200)}function _(S){s.value=S}function g(S){s.value=S,b(S)}function x(){s.value=null}return(S,T)=>(y(),M("section",YRe,[C("div",XRe,[C("h3",JRe,N(p(t)("settings.tabs.providers")),1),j(p(Rt),{variant:"secondary",size:"sm",onClick:T[0]||(T[0]=A=>v(Wu))},{default:me(()=>[j(p(Te),{name:"plus",size:"sm"}),qe(" "+N(p(t)("providers.addProvider")),1)]),_:1})]),o.value?(y(),M("div",QRe,[j(p(Ao),{size:"sm"}),C("span",null,N(p(t)("providers.loading")),1)])):(y(),M("div",eOe,[s.value===Wu||i.value===Wu?(y(),M("div",{key:0,class:Re(["pp-item pp-add-item",{open:s.value===Wu&&m.value}])},[C("button",{type:"button",class:"pp-row pp-add-row",onClick:T[1]||(T[1]=A=>v(Wu))},[C("span",tOe,N(p(t)("providers.addProvider")),1),T[6]||(T[6]=C("span",{class:"grow"},null,-1)),C("span",nOe,[j(p(Te),{name:"chevron-right",size:"sm"})])]),C("div",oOe,[C("div",sOe,[j(GRe,{guard:a.value&&s.value===Wu,onDirtyChange:T[2]||(T[2]=A=>l.value=A),onGuardStay:k,onGuardDiscard:w,onAdded:g,onCancel:T[3]||(T[3]=A=>s.value=null)},null,8,["guard"])])])],2)):ee("",!0),f.value.length===0?(y(),M("div",iOe,N(p(t)("providers.empty")),1)):ee("",!0),(y(!0),M(Pe,null,pt(f.value,A=>(y(),M("div",{key:A.id,class:Re(["pp-item",{open:s.value===A.id,flash:c.value===A.id}])},[C("button",{type:"button",class:"pp-row",onClick:E=>v(A.id)},[C("div",lOe,[C("span",aOe,N(A.id),1),j(p(Vr),{variant:"neutral",size:"sm"},{default:me(()=>[qe(N(A.type),1)]),_:2},1024),p(mE)(A)?(y(),he(p(Vr),{key:0,variant:"info",size:"sm"},{default:me(()=>[qe(N(p(t)("providers.managedBadge")),1)]),_:1})):ee("",!0)]),C("span",uOe,N(p(t)("providers.modelCount",{count:h(A)})),1),C("span",cOe,[j(p(Te),{name:"chevron-right",size:"sm"})])],8,rOe),C("div",dOe,[C("div",fOe,[s.value===A.id||i.value===A.id?(y(),he(kF,{key:0,mode:"edit",provider:A,guard:a.value&&s.value===A.id,onDirtyChange:T[4]||(T[4]=E=>l.value=E),onGuardStay:k,onGuardDiscard:w,onSaved:_,onDeleting:T[5]||(T[5]=E=>s.value=null),onDeleted:x},null,8,["provider","guard"])):ee("",!0)])])],2))),128))]))]))}}),hOe=ft(pOe,[["__scopeId","data-v-9aa0e3a8"]]),mOe={class:"sec"},gOe={class:"sec-title"},vOe={class:"pu-group"},yOe={class:"pu-row"},kOe={class:"pu-main"},bOe={class:"pu-label"},COe={class:"pu-hint"},wOe=et({__name:"PlanUpgradeCard",setup(e){const{t}=Nt();return(n,o)=>(y(),M("section",mOe,[C("h3",gOe,N(p(t)("settings.planUsage.title")),1),C("div",vOe,[C("div",yOe,[C("span",kOe,[C("span",bOe,N(p(t)("settings.planUsage.freeTitle")),1),C("span",COe,N(p(t)("settings.planUsage.freeHint")),1)]),j(p(Rt),{variant:"primary",size:"sm",onClick:o[0]||(o[0]=s=>p(jp)())},{default:me(()=>[qe(N(p(t)("sidebar.upgrade")),1)]),_:1})])])]))}}),bF=ft(wOe,[["__scopeId","data-v-5711dff8"]]),_Oe={class:"sec"},xOe={class:"sec-title"},SOe={class:"pu-group"},AOe={key:0,class:"pu-row pu-state"},MOe={key:1,class:"pu-row pu-state"},TOe={class:"pu-error-text"},EOe={key:2,class:"pu-row pu-state pu-empty"},IOe={class:"pu-main"},LOe={class:"pu-label"},$Oe={key:0,class:"pu-hint"},NOe={class:"pu-value"},FOe=["aria-valuenow","aria-valuemax"],ROe={key:0,class:"sec"},OOe={class:"sec-title"},POe={class:"pu-group"},DOe={class:"pu-row"},BOe={class:"pu-main"},HOe={class:"pu-label"},zOe={class:"pu-value"},WOe={key:0,class:"pu-value-sub"},UOe={key:0,class:"pu-meter"},jOe={class:"pu-row"},VOe={class:"pu-main"},qOe={class:"pu-label"},KOe={class:"pu-value"},ZOe={class:"pu-row"},GOe={class:"pu-main"},YOe={class:"pu-label"},XOe={class:"pu-value"},JOe={class:"pu-value-sub"},QOe=et({__name:"PlanUsageCard",props:{onFetchUsage:{type:Function}},setup(e){const t=e,{t:n}=Nt(),o=Z(!0),s=Z(null);async function i(){o.value=!0;try{s.value=await t.onFetchUsage()}finally{o.value=!1}}dn(i);const r=R(()=>s.value?.kind==="ok"?s.value:null),l=R(()=>r.value?.extraUsage??null),a=R(()=>{const v=r.value;return v===null?[]:v.summary===null?v.limits:[v.summary,...v.limits]}),u=R(()=>a.value.length>0),c=R(()=>s.value?.kind==="error"?s.value.message:n("settings.planUsage.loadFailed")),d=R(()=>s.value?.kind==="error"&&(s.value.status===402||s.value.status===403)),f=R(()=>l.value!==null&&l.value.monthlyChargeLimitEnabled&&l.value.monthlyChargeLimitCents>0);function h(v,k){const w=PJ(v,k);return`${w.symbol}${w.number}`}function m(v){return v.resetAt===void 0?"":fE(v.resetAt,n)}return(v,k)=>d.value?(y(),he(bF,{key:0})):(y(),M(Pe,{key:1},[C("section",_Oe,[C("h3",xOe,N(p(n)("settings.planUsage.title")),1),C("div",SOe,[o.value?(y(),M("div",AOe,[j(p(Ao),{size:"sm"})])):r.value===null?(y(),M("div",MOe,[C("span",TOe,N(c.value),1),j(p(Rt),{variant:"ghost",size:"sm",onClick:i},{default:me(()=>[qe(N(p(n)("settings.planUsage.retry")),1)]),_:1})])):u.value?(y(!0),M(Pe,{key:3},pt(a.value,(w,b)=>(y(),M("div",{key:b,class:"pu-row"},[C("span",IOe,[C("span",LOe,N(p(dE)(w,p(n))),1),m(w)?(y(),M("span",$Oe,N(m(w)),1)):ee("",!0)]),C("span",NOe,N(p(n)("settings.planUsage.usedPct",{pct:p(Wh)(w.used,w.limit)})),1),C("span",{class:"pu-meter",role:"progressbar","aria-valuenow":w.used,"aria-valuemax":w.limit},[C("i",{class:Re(`sev-${p(C3)(w.used,w.limit)}`),style:Zt({width:`${p(Wh)(w.used,w.limit)}%`})},null,6)],8,FOe)]))),128)):(y(),M("div",EOe,N(p(n)("settings.planUsage.empty")),1))])]),l.value!==null?(y(),M("section",ROe,[C("h3",OOe,N(p(n)("settings.planUsage.boosterTitle")),1),C("div",POe,[C("div",DOe,[C("span",BOe,[C("span",HOe,N(p(n)("settings.planUsage.monthlyUsed")),1)]),C("span",zOe,[qe(N(h(l.value.monthlyUsedCents,l.value.currency)),1),f.value?(y(),M("span",WOe," / "+N(h(l.value.monthlyChargeLimitCents,l.value.currency)),1)):ee("",!0)]),f.value?(y(),M("span",UOe,[C("i",{class:Re(`sev-${p(C3)(l.value.monthlyUsedCents,l.value.monthlyChargeLimitCents)}`),style:Zt({width:`${p(Wh)(l.value.monthlyUsedCents,l.value.monthlyChargeLimitCents)}%`})},null,6)])):ee("",!0)]),C("div",jOe,[C("span",VOe,[C("span",qOe,N(p(n)("settings.planUsage.monthlyLimit")),1)]),C("span",KOe,[f.value?(y(),M(Pe,{key:0},[qe(N(h(l.value.monthlyChargeLimitCents,l.value.currency)),1)],64)):(y(),M(Pe,{key:1},[qe(N(p(n)("settings.planUsage.unlimited")),1)],64))])]),C("div",ZOe,[C("span",GOe,[C("span",YOe,N(p(n)("settings.planUsage.boosterBalance")),1)]),C("span",XOe,[qe(N(h(l.value.balanceCents,l.value.currency)),1),C("span",JOe," / "+N(h(l.value.totalCents,l.value.currency)),1)])])])])):ee("",!0)],64))}}),ePe=ft(QOe,[["__scopeId","data-v-f39cdded"]]),tPe=["aria-expanded","aria-label"],nPe={class:"sm-picker__value-text"},oPe=["aria-label"],sPe=["aria-label"],iPe={class:"sm-picker__group"},rPe=["aria-selected","onMouseenter","onClick"],lPe={class:"sm-picker__option-label"},aPe=["aria-label"],uPe={class:"sm-picker__group"},cPe=["aria-selected","onMouseenter","onClick"],dPe={class:"sm-picker__option-label"},fPe=188,pPe=250,wS=8,hPe=et({__name:"SecondaryModelPicker",props:{modelValue:{},effort:{},groups:{},modelInfoById:{}},emits:["select"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt(),i=Z(null),r=Z(null),l=Z(null),a=new Map,u=Z(!1),c=Z(!1),d=Z({}),f=`sm-picker-${Math.random().toString(36).slice(2,9)}`,h=Z(""),m=Z(null),v=Z("right"),k=Z(0),w=Z("models"),b=Z(0),_=Z(0);let g=null;const x=R(()=>n.groups.flatMap(ve=>ve.options)),S=R(()=>n.modelValue?x.value.find(ve=>ve.id===n.modelValue)?.label??n.modelValue:""),T=R(()=>n.modelValue?n.effort?`${S.value} · ${n.effort}`:S.value:s("settings.noSecondaryModel")),A=R(()=>{const ve=m.value;if(ve===null)return[];const oe=Up(n.modelInfoById[ve]),ye=n.effort===""?[null,...oe]:[...oe];return n.modelValue===ve&&n.effort!==""&&!oe.includes(n.effort)&&ye.push(n.effort),ye});function E(ve){return n.modelValue!==m.value?!1:ve===null?n.effort==="":n.effort===ve}function P(){const ve=A.value.findIndex(oe=>E(oe));return ve>=0?ve:0}function D(ve,oe){ve instanceof HTMLElement?a.set(oe,ve):a.delete(oe)}function I(){g!==null&&(clearTimeout(g),g=null)}function $(){I(),g=setTimeout(()=>{m.value=null,w.value==="efforts"&&(w.value="models")},pPe)}function B(ve){ve!==h.value&&(h.value=ve,b.value=Math.max(0,x.value.findIndex(oe=>oe.id===ve)))}function H(){const ve=r.value,oe=l.value;if(!ve||!oe)return;const ye=ve.getBoundingClientRect(),G=oe.offsetHeight,Y=window.innerHeight-ye.bottom;c.value=Y<G+wS&&ye.top>G;const fe=Math.max(wS,window.innerWidth-ye.right);d.value=c.value?{right:`${fe}px`,bottom:`${window.innerHeight-ye.top+4}px`,top:"auto"}:{right:`${fe}px`,top:`${ye.bottom+4}px`,bottom:"auto"}}function O(){const ve=l.value,oe=m.value===null?void 0:a.get(m.value);if(!ve||!oe)return;const ye=ve.getBoundingClientRect(),G=oe.getBoundingClientRect();k.value=Math.max(0,Math.min(G.top-ye.top-4,ve.offsetHeight-40));const Y=window.innerWidth-ye.right,fe=ye.left;v.value=Y>=fPe||Y>=fe?"right":"left"}function F(ve,{moveFocus:oe=!1}={}){B(ve),I(),m.value=ve,oe&&(w.value="efforts",_.value=P()),yt(O)}function U(){m.value=null,w.value="models"}function z(){u.value||(u.value=!0,h.value=n.modelValue||(x.value[0]?.id??""),b.value=Math.max(0,x.value.findIndex(ve=>ve.id===h.value)),m.value=null,w.value="models",yt(H))}function W({restoreFocus:ve=!1}={}){u.value&&(I(),u.value=!1,m.value=null,ve&&yt(()=>r.value?.focus()))}function K(){u.value?W():z()}function V(ve){if(m.value===null)return;const oe={model:m.value,effort:ve??void 0};(oe.model!==n.modelValue||(oe.effort??"")!==n.effort)&&o("select",oe),W({restoreFocus:!0})}function ie(){yt(()=>{l.value?.querySelector(".sm-picker__option.is-kb-active")?.scrollIntoView({block:"nearest"})})}function ne(ve){const oe=x.value;if(oe.length===0)return;const ye=(b.value+ve+oe.length)%oe.length,G=oe[ye].id;B(G),m.value!==null&&F(G),ie()}function X(ve){const oe=A.value;oe.length!==0&&(_.value=(_.value+ve+oe.length)%oe.length,ie())}function le(ve){if(!u.value){(ve.key==="Enter"||ve.key===" "||ve.key==="ArrowDown")&&(ve.preventDefault(),z());return}if(ve.key==="ArrowDown")ve.preventDefault(),w.value==="models"?ne(1):X(1);else if(ve.key==="ArrowUp")ve.preventDefault(),w.value==="models"?ne(-1):X(-1);else if(ve.key==="ArrowRight")ve.preventDefault(),F(h.value,{moveFocus:!0});else if(ve.key==="ArrowLeft")ve.preventDefault(),m.value!==null&&U();else if(ve.key==="Enter"||ve.key===" ")ve.preventDefault(),w.value==="models"?F(h.value,{moveFocus:!0}):V(A.value[_.value]??null);else if(ve.key==="Home"||ve.key==="End"){ve.preventDefault();const oe=ve.key==="Home";if(w.value==="models"){const ye=x.value;if(ye.length===0)return;const G=(oe?ye[0]:ye.at(-1)).id;B(G),m.value!==null&&F(G)}else _.value=oe?0:A.value.length-1;ie()}else ve.key==="Escape"&&(ve.preventDefault(),W({restoreFocus:!0}))}function Ie(ve){const oe=ve.target;i.value?.contains(oe)||l.value?.contains(oe)||W()}function de(ve){if(u.value){if(l.value?.contains(ve.target)){O();return}H(),O()}}function pe(){W()}return dn(()=>{document.addEventListener("pointerdown",Ie),document.addEventListener("scroll",de,!0),window.addEventListener("resize",pe)}),bn(()=>{document.removeEventListener("pointerdown",Ie),document.removeEventListener("scroll",de,!0),window.removeEventListener("resize",pe),I()}),(ve,oe)=>(y(),M("div",{ref_key:"rootRef",ref:i,class:Re(["sm-picker",{"is-open":u.value}])},[C("button",{ref_key:"triggerRef",ref:r,class:"sm-picker__trigger",type:"button",role:"combobox","aria-controls":f,"aria-expanded":u.value,"aria-haspopup":"dialog","aria-label":p(s)("settings.secondaryModel"),onClick:K,onKeydown:le},[C("span",{class:Re(["sm-picker__value",{"is-placeholder":!e.modelValue}])},[C("span",nPe,N(T.value),1)],2),j(p(Te),{class:"sm-picker__chevron",name:"chevron-down",size:"sm"})],40,tPe),(y(),he(Zr,{to:"body"},[u.value?(y(),M("div",{key:0,id:f,ref_key:"menuRef",ref:l,class:Re(["sm-picker__menu",{"sm-picker__menu--up":c.value}]),style:Zt(d.value),role:"dialog","aria-label":p(s)("settings.secondaryModel")},[C("div",{class:"sm-picker__models",role:"listbox","aria-label":p(s)("settings.secondaryModel")},[(y(!0),M(Pe,null,pt(e.groups,ye=>(y(),M(Pe,{key:ye.provider},[C("div",iPe,N(ye.provider),1),(y(!0),M(Pe,null,pt(ye.options,G=>(y(),M("button",{key:G.id,ref_for:!0,ref:Y=>D(Y,G.id),class:Re(["sm-picker__option",{"is-selected":G.id===e.modelValue,"is-active":G.id===h.value,"is-kb-active":w.value==="models"&&G.id===h.value}]),type:"button",role:"option","aria-selected":G.id===e.modelValue,onMouseenter:Y=>F(G.id),onMouseleave:$,onClick:Y=>F(G.id,{moveFocus:!0})},[j(p(Te),{class:"sm-picker__check",name:"check",size:"sm"}),C("span",lPe,N(G.label),1),j(p(Te),{class:"sm-picker__flyout-caret",name:"chevron-right",size:"sm"})],42,rPe))),128))],64))),128))],8,sPe),m.value!==null?(y(),M("div",{key:0,class:Re(["sm-picker__flyout",`sm-picker__flyout--${v.value}`]),style:Zt({top:`${k.value}px`}),role:"listbox","aria-label":p(s)("settings.secondaryModelEffort"),onMouseenter:I,onMouseleave:$},[C("div",uPe,N(p(s)("settings.secondaryModelEffort")),1),(y(!0),M(Pe,null,pt(A.value,(ye,G)=>(y(),M("button",{key:ye??"__default__",class:Re(["sm-picker__option",{"is-selected":E(ye),"is-active":w.value==="efforts"&&G===_.value,"is-kb-active":w.value==="efforts"&&G===_.value,"is-muted":ye===null}]),type:"button",role:"option","aria-selected":E(ye),onMouseenter:Y=>{w.value="efforts",_.value=G},onClick:Y=>V(ye)},[j(p(Te),{class:"sm-picker__check",name:"check",size:"sm"}),C("span",dPe,N(ye??p(s)("settings.secondaryModelEffortAuto")),1)],42,cPe))),128))],46,aPe)):ee("",!0)],14,oPe)):ee("",!0)]))],2))}}),mPe=ft(hPe,[["__scopeId","data-v-f114c246"]]),gPe=["aria-label"],vPe={class:"settings-tabs-header"},yPe={class:"settings-dialog-title"},kPe={class:"settings-tab-list"},bPe=["aria-selected","onClick"],CPe={class:"settings-region"},wPe={class:"settings-region-header"},_Pe={class:"panel"},xPe={class:"sec"},SPe={class:"sec-title"},APe={class:"settings-group"},MPe={class:"row"},TPe={class:"rlabel"},EPe={class:"hint"},IPe={class:"row language-row"},LPe={class:"rlabel"},$Pe={class:"hint"},NPe={class:"row font-size-row"},FPe={class:"rlabel"},RPe={class:"hint"},OPe={class:"sec notification-settings"},PPe={class:"sec-title"},DPe={class:"settings-group"},BPe={class:"row"},HPe={class:"rlabel"},zPe={class:"hint"},WPe={key:0,class:"hint"},UPe={class:"row"},jPe={class:"rlabel"},VPe={class:"hint"},qPe={class:"panel"},KPe={class:"sec"},ZPe={class:"sec-title"},GPe={class:"settings-group"},YPe={class:"account-row"},XPe={class:"account-avatar","aria-hidden":"true"},JPe=["src"],QPe={class:"account-meta"},eDe={class:"account-name-row"},tDe={class:"account-name"},nDe={class:"account-sub"},oDe={key:0,class:"panel"},sDe={class:"panel"},iDe={class:"sec"},rDe={class:"sec-head"},lDe={class:"sec-title"},aDe={class:"settings-group"},uDe={class:"row"},cDe={class:"rlabel"},dDe={class:"hint"},fDe={key:0,class:"select-wrap"},pDe={key:1,class:"rvalue mono"},hDe={class:"row"},mDe={class:"rlabel"},gDe={class:"hint"},vDe={class:"row"},yDe={class:"rlabel"},kDe={class:"hint"},bDe={class:"row"},CDe={class:"rlabel"},wDe={class:"hint"},_De={key:1,class:"empty-config"},xDe={key:0,class:"sec"},SDe={class:"sec-head"},ADe={class:"sec-title"},MDe={class:"settings-group"},TDe={class:"row"},EDe={class:"rlabel"},IDe={class:"hint"},LDe={key:0,class:"select-wrap"},$De={key:1,class:"rvalue mono"},NDe={class:"panel"},FDe={class:"sec"},RDe={class:"sec-title"},ODe={class:"settings-group"},PDe={class:"row"},DDe={class:"rlabel"},BDe={class:"hint"},HDe={class:"rvalue"},zDe={class:"row"},WDe={class:"rlabel"},UDe={class:"hint"},jDe={class:"rvalue"},VDe={class:"row"},qDe={class:"rlabel"},KDe={class:"hint"},ZDe={class:"rvalue"},GDe={key:0,class:"row"},YDe={class:"rlabel"},XDe={key:0,class:"hint"},JDe={key:1,class:"hint"},QDe={key:1,class:"row"},eBe={class:"rlabel"},tBe={class:"hint"},nBe={key:0,class:"sec"},oBe={class:"sec-title"},sBe={class:"settings-group"},iBe={class:"row"},rBe={class:"rlabel"},lBe={class:"hint"},aBe={class:"hint"},uBe={class:"sec"},cBe={class:"sec-title"},dBe={class:"settings-group"},fBe={class:"row"},pBe={class:"rlabel"},hBe={class:"hint"},mBe={key:0,class:"hint"},gBe={class:"panel"},vBe={class:"panel-head"},yBe={class:"panel-title"},kBe={class:"panel-desc"},bBe={class:"archive-toolbar"},CBe={class:"archive-search"},wBe=["placeholder"],_Be={key:0,class:"archive-empty"},xBe={key:0,class:"archive-list"},SBe={class:"archive-workspace"},ABe={class:"path"},MBe={class:"count"},TBe={class:"setting-card"},EBe={class:"archive-meta"},IBe={class:"archive-name"},LBe={class:"archive-time"},$Be={key:1,class:"archive-empty"},NBe=100,FBe=et({__name:"SettingsDialog",props:{colorScheme:{},fontScale:{},initialTab:{},managedProviderStatus:{},managedUserInfo:{},onFetchUsage:{type:Function},notify:{type:Boolean},notifyPermission:{},notifySound:{type:Boolean},config:{},models:{},configSaving:{type:Boolean},serverVersion:{},experimentalFlags:{}},emits:["setColorScheme","setFontScale","setNotify","setNotifySound","login","logout","updateConfig","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=R(()=>o.managedProviderStatus==="authenticated"),r=R(()=>i.value?o.managedUserInfo?.nickname||n("sidebar.defaultUserName"):n("sidebar.notSignedIn")),l=R(()=>o.managedUserInfo?.userLevelName?.trim()??""),a=Z(!1);Je(()=>o.managedUserInfo?.avatar,()=>{a.value=!1});const u=R(()=>!!o.managedUserInfo?.avatar&&!a.value),c=R(()=>i.value?n("settings.signedIn"):n("settings.signedOutHint")),d=Z(o.initialTab??"general"),f=Z(!1);let h=null;function m(){f.value=!0,h&&clearTimeout(h),h=setTimeout(()=>{f.value=!1,h=null},900)}const v=[{id:"general",labelKey:"settings.tabs.general",icon:"sliders"},{id:"agent",labelKey:"settings.tabs.agent",icon:"robot"},{id:"account",labelKey:"settings.tabs.account",icon:"user"},{id:"providers",labelKey:"settings.tabs.providers",icon:"bolt"},{id:"advanced",labelKey:"settings.tabs.advanced",icon:"microscope"},{id:"archived",labelKey:"settings.tabs.archived",icon:"archive"}],k=G0e(),w=["manual","yolo","auto"],b={manual:"status.permissionManual",auto:"status.permissionAuto",yolo:"status.permissionYolo"},_=Z(null);gF(_);const{isConfirmOpen:g}=hu();function x(Fe){Fe.key==="Escape"&&!Fe.defaultPrevented&&!g.value&&s("close")}dn(()=>document.addEventListener("keydown",x)),bn(()=>{document.removeEventListener("keydown",x),h&&clearTimeout(h)});function S(){G$()}const T=(()=>{const Fe="0.33.0".trim()?"0.33.0":"";let Oe="";if("2026-08-12T03:30:09.051Z".trim()){const at=new Date("2026-08-12T03:30:09.051Z");if(!Number.isNaN(at.getTime())){const Tt=Bt=>String(Bt).padStart(2,"0");Oe=`${at.getFullYear()}-${Tt(at.getMonth()+1)}-${Tt(at.getDate())} ${Tt(at.getHours())}:${Tt(at.getMinutes())}`}}const Ge=Oe===""?Fe:`${Fe} · ${Oe}`;return Ge===""?"-":Ge})(),A=K$(),E=Z(!1),P=Z(null);async function D(){if(!E.value){E.value=!0,P.value=null;try{P.value=await A.check()}finally{E.value=!1}}}const I=R(()=>{const Fe=P.value;if(Fe===null)return"";switch(Fe.outcome){case"available":return A.status.value.state==="downloaded"?n("settings.updateCheckDownloaded",{version:Fe.version??""}):A.autoDownload.value?n("settings.updateCheckAvailableAuto",{version:Fe.version??""}):n("settings.updateCheckAvailable",{version:Fe.version??""});case"latest":return n("settings.updateCheckLatest");case"unsupported":return n("settings.updateCheckUnsupported");case"error":return n("settings.updateCheckFailed")}}),$=R(()=>{const Fe=new Map;for(const Oe of o.models??[])Fe.set(Oe.id,{id:Oe.id,label:Oe.displayName??Oe.model??Oe.id,provider:Oe.provider});for(const[Oe,Ge]of Object.entries(o.config?.models??{})){if(Fe.has(Oe))continue;const at=F(Ge);Fe.set(Oe,{id:Oe,label:U(Oe,Ge,at),provider:at??Oe})}return Array.from(Fe.values())}),B=R(()=>{const Fe=new Map;for(const Oe of $.value){const Ge=Fe.get(Oe.provider)??[];Ge.push(Oe),Fe.set(Oe.provider,Ge)}for(const Oe of Fe.values())Oe.sort((Ge,at)=>Ge.label.localeCompare(at.label));return Array.from(Fe.entries()).toSorted(([Oe],[Ge])=>Oe.localeCompare(Ge)).map(([Oe,Ge])=>({provider:Oe,options:Ge}))}),H=R(()=>{const Fe=B.value.flatMap(Oe=>Oe.options.map(Ge=>({value:Ge.id,label:Ge.label,group:Oe.provider})));return o.config?.defaultModel||Fe.unshift({value:"",label:n("settings.noDefaultModel"),group:"",disabled:!0}),Fe}),O=R(()=>{const Fe=o.config?.defaultPermissionMode;return Fe==="auto"||Fe==="yolo"||Fe==="manual"?Fe:"manual"});function F(Fe){if(!Fe||typeof Fe!="object")return;const Oe=Fe;return typeof Oe.provider=="string"?Oe.provider:void 0}function U(Fe,Oe,Ge){if(!Oe||typeof Oe!="object")return Fe;const at=Oe,Tt=typeof at.model=="string"?at.model:void 0,Bt=Ge??F(Oe);return Tt&&Bt?`${Fe} (${Bt}/${Tt})`:Tt?`${Fe} (${Tt})`:Fe}function z(Fe){return Fe===!0}function W(Fe){!Fe||Fe===o.config?.defaultModel||s("updateConfig",{defaultModel:Fe})}function K(Fe){Fe!==O.value&&s("updateConfig",{defaultPermissionMode:Fe})}const V=R(()=>(o.experimentalFlags?.["secondary-model"]??o.config?.experimental?.["secondary-model"])===!0),ie=R(()=>o.config?.secondaryModel?.model??""),ne=R(()=>o.config?.secondaryModel?.defaultEffort??""),X=R(()=>Object.fromEntries((o.models??[]).map(Fe=>[Fe.id,Fe])));function le(Fe){Fe.model===ie.value&&(Fe.effort??"")===ne.value||s("updateConfig",{secondaryModel:Fe.effort?{model:Fe.model,defaultEffort:Fe.effort}:{model:Fe.model}})}function Ie(Fe){const Oe=o.config?.[Fe];s("updateConfig",{[Fe]:!z(Oe)})}function de(){const Fe=o.config?.thinking;return!Fe||typeof Fe!="object"?!0:Fe.enabled!==!1}function pe(){s("updateConfig",{thinking:{enabled:!de()}})}function ve(){const Fe=o.config?.telemetry!==!1;s("updateConfig",{telemetry:!Fe})}function oe(Fe){d.value=Fe}const ye=mu(),G=R(()=>i.value&&ye.managedMembership.value==="free"),Y=Z([]),fe=Z(!1),we=Z(!1),ge=Z(""),Q=Z("all"),te=Z("archived-desc");async function ce(){if(!(fe.value||we.value)){fe.value=!0;try{const Fe=[];let Oe;for(;;){const Ge=await ye.loadArchivedSessions({beforeId:Oe,pageSize:NBe});if(Fe.push(...Ge.items),!Ge.hasMore||Ge.items.length===0)break;const at=Ge.items.at(-1)?.id;if(at===void 0)break;Oe=at}Y.value=Fe,we.value=!0}catch(Fe){gl("loadAllArchived failed",Fe)}finally{fe.value=!1}}}Je(d,Fe=>{Fe==="archived"&&!we.value&&ce()},{immediate:!0});const ue=R(()=>{const Fe=new Set;for(const Oe of Y.value)Fe.add(Oe.cwd);return Array.from(Fe).sort((Oe,Ge)=>Oe.localeCompare(Ge))}),Se=R(()=>[{value:"all",label:n("settings.archivedAllWorkspaces")},...ue.value.map(Fe=>({value:Fe,label:Fe}))]),ze=R(()=>{const Fe=ge.value.trim().toLowerCase();let Oe=Y.value.filter(Ge=>Ge.archived===!0);return Q.value!=="all"&&(Oe=Oe.filter(Ge=>Ge.cwd===Q.value)),Fe&&(Oe=Oe.filter(Ge=>Ge.title.toLowerCase().includes(Fe))),Oe=Oe.slice(),te.value==="archived-desc"?Oe.sort((Ge,at)=>at.updatedAt.localeCompare(Ge.updatedAt)):te.value==="created-desc"?Oe.sort((Ge,at)=>at.createdAt.localeCompare(Ge.createdAt)):Oe.sort((Ge,at)=>Ge.title.localeCompare(at.title,"zh")),Oe}),_e=R(()=>{const Fe=new Map;for(const Oe of ze.value){const Ge=Fe.get(Oe.cwd)??[];Ge.push(Oe),Fe.set(Oe.cwd,Ge)}return Array.from(Fe.entries()).map(([Oe,Ge])=>({cwd:Oe,items:Ge}))});async function Ee(Fe){await ye.restoreSession(Fe)&&(Y.value=Y.value.filter(Ge=>Ge.id!==Fe))}function it(Fe){const Oe=new Date(Fe);if(Number.isNaN(Oe.getTime()))return Fe;const Ge=at=>String(at).padStart(2,"0");return`${Oe.getFullYear()}-${Ge(Oe.getMonth()+1)}-${Ge(Oe.getDate())} ${Ge(Oe.getHours())}:${Ge(Oe.getMinutes())}`}return(Fe,Oe)=>(y(),he(p(ua),{open:!0,"close-on-esc":!1,"aria-label":p(n)("settings.title"),size:"xl",height:"fixed",padded:!1,level:"grouped",onClose:Oe[16]||(Oe[16]=Ge=>s("close"))},{default:me(()=>[C("div",{ref_key:"dialogRef",ref:_,class:"sd"},[C("nav",{class:"settings-tabs",role:"tablist","aria-label":p(n)("settings.title")},[C("header",vPe,[C("h2",yPe,N(p(n)("settings.title")),1)]),C("div",kPe,[(y(),M(Pe,null,pt(v,Ge=>C("button",{key:Ge.id,type:"button",class:Re(["tab",{on:d.value===Ge.id}]),role:"tab","aria-selected":d.value===Ge.id,onClick:at=>oe(Ge.id)},[j(p(Te),{name:Ge.icon,size:"md"},null,8,["name"]),C("span",null,N(p(n)(Ge.labelKey)),1)],10,bPe)),64))])],8,gPe),C("section",CPe,[C("header",wPe,[j(p(gn),{size:"sm",label:p(n)("settings.close"),tooltip:p(n)("settings.close"),onClick:Oe[0]||(Oe[0]=Ge=>s("close"))},{default:me(()=>[j(p(Te),{name:"close",size:"md"})]),_:1},8,["label","tooltip"])]),C("div",{class:Re(["body",{scrolling:f.value}]),onScroll:m},[Bn(C("section",_Pe,[C("section",xPe,[C("h3",SPe,N(p(n)("settings.appearance")),1),C("div",APe,[C("div",MPe,[C("span",TPe,[qe(N(p(n)("theme.colorSchemeLabel"))+" ",1),C("span",EPe,N(p(n)("settings.colorSchemeHint")),1)]),j(p(wi),{"model-value":e.colorScheme,options:[{value:"light",label:p(n)("theme.light"),icon:"light-mode"},{value:"dark",label:p(n)("theme.dark"),icon:"dark-mode"},{value:"system",label:p(n)("theme.system")}],"onUpdate:modelValue":Oe[1]||(Oe[1]=Ge=>s("setColorScheme",Ge))},null,8,["model-value","options"])]),C("div",IPe,[C("span",LPe,[qe(N(p(n)("sidebar.language"))+" ",1),C("span",$Pe,N(p(n)("settings.languageHint")),1)]),j(yF)]),C("div",NPe,[C("span",FPe,[qe(N(p(n)("settings.uiFontSize"))+" ",1),C("span",RPe,N(p(n)("settings.uiFontSizeHint")),1)]),j(p(wi),{"model-value":e.fontScale,options:[{value:"small",label:"S"},{value:"medium",label:"M"},{value:"large",label:"L"},{value:"xlarge",label:"XL"}],"aria-label":p(n)("settings.uiFontSize"),"onUpdate:modelValue":Oe[2]||(Oe[2]=Ge=>s("setFontScale",Ge))},null,8,["model-value","aria-label"])])])]),C("section",OPe,[C("h3",PPe,N(p(n)("settings.notifications")),1),C("div",DPe,[C("div",BPe,[C("span",HPe,[qe(N(p(n)("settings.notifyEnabled"))+" ",1),C("span",zPe,N(p(n)("settings.notifyEnabledHint")),1),e.notifyPermission==="denied"?(y(),M("span",WPe,N(p(n)("settings.notifyDenied")),1)):ee("",!0)]),j(p(ed),{"model-value":e.notify,disabled:e.notifyPermission==="denied",label:p(n)("settings.notifyEnabled"),"onUpdate:modelValue":Oe[3]||(Oe[3]=Ge=>s("setNotify",Ge))},null,8,["model-value","disabled","label"])]),C("div",UPe,[C("span",jPe,[qe(N(p(n)("settings.notifySound"))+" ",1),C("span",VPe,N(p(n)("settings.notifySoundHint")),1)]),j(p(ed),{"model-value":e.notifySound,label:p(n)("settings.notifySound"),"onUpdate:modelValue":Oe[4]||(Oe[4]=Ge=>s("setNotifySound",Ge))},null,8,["model-value","label"])])])])],512),[[qs,d.value==="general"]]),Bn(C("section",qPe,[C("section",KPe,[C("h3",ZPe,N(p(n)("settings.account")),1),C("div",GPe,[C("div",YPe,[C("span",XPe,[u.value?(y(),M("img",{key:0,src:o.managedUserInfo?.avatar,alt:"",onError:Oe[5]||(Oe[5]=Ge=>a.value=!0)},null,40,JPe)):(y(),he(p(Te),{key:1,name:"user",size:"md"}))]),C("span",QPe,[C("span",eDe,[C("span",tDe,N(r.value),1),l.value?(y(),he(p(Vr),{key:0,class:"account-level",variant:"neutral",size:"sm"},{default:me(()=>[qe(N(l.value),1)]),_:1})):ee("",!0)]),C("span",nDe,N(c.value),1)]),i.value?(y(),he(p(Rt),{key:0,variant:"danger-soft",size:"sm",onClick:Oe[6]||(Oe[6]=Ge=>s("logout"))},{default:me(()=>[qe(N(p(n)("sidebar.signOut")),1)]),_:1})):(y(),he(p(Rt),{key:1,variant:"primary",size:"sm",onClick:Oe[7]||(Oe[7]=Ge=>s("login"))},{default:me(()=>[qe(N(p(n)("sidebar.signIn")),1)]),_:1}))])])]),G.value?(y(),he(bF,{key:0})):i.value?(y(),he(ePe,{key:1,"on-fetch-usage":o.onFetchUsage},null,8,["on-fetch-usage"])):ee("",!0)],512),[[qs,d.value==="account"]]),d.value==="providers"?(y(),M("section",oDe,[j(hOe)])):ee("",!0),Bn(C("section",sDe,[C("section",iDe,[C("div",rDe,[C("h3",lDe,N(p(n)("settings.agentDefaults")),1)]),C("div",aDe,[e.config?(y(),M(Pe,{key:0},[C("div",uDe,[C("span",cDe,[qe(N(p(n)("settings.defaultModel"))+" ",1),C("span",dDe,N(p(n)("settings.defaultModelHint")),1)]),B.value.length>0?(y(),M("div",fDe,[j(p(n3),{"model-value":e.config.defaultModel??"",options:H.value,"aria-label":p(n)("settings.defaultModel"),"onUpdate:modelValue":W},null,8,["model-value","options","aria-label"])])):(y(),M("span",pDe,N(e.config.defaultModel??p(n)("settings.noDefaultModel")),1))]),C("div",hDe,[C("span",mDe,[qe(N(p(n)("settings.defaultPermission"))+" ",1),C("span",gDe,N(p(n)("settings.defaultPermissionHint")),1)]),j(p(wi),{"model-value":O.value,options:w.map(Ge=>({value:Ge,label:p(n)(b[Ge])})),"onUpdate:modelValue":Oe[8]||(Oe[8]=Ge=>K(Ge))},null,8,["model-value","options"])]),C("div",vDe,[C("span",yDe,[qe(N(p(n)("settings.defaultThinking"))+" ",1),C("span",kDe,N(p(n)("settings.defaultThinkingHint")),1)]),j(p(ed),{"model-value":de(),label:p(n)("settings.defaultThinking"),"onUpdate:modelValue":Oe[9]||(Oe[9]=Ge=>pe())},null,8,["model-value","label"])]),C("div",bDe,[C("span",CDe,[qe(N(p(n)("settings.defaultPlanMode"))+" ",1),C("span",wDe,N(p(n)("settings.defaultPlanModeHint")),1)]),j(p(ed),{"model-value":z(e.config.defaultPlanMode),label:p(n)("settings.defaultPlanMode"),"onUpdate:modelValue":Oe[10]||(Oe[10]=Ge=>Ie("defaultPlanMode"))},null,8,["model-value","label"])])],64)):(y(),M("div",_De,N(p(n)("settings.configUnavailable")),1))])]),e.config&&V.value?(y(),M("section",xDe,[C("div",SDe,[C("h3",ADe,N(p(n)("settings.secondaryModelSection")),1)]),C("div",MDe,[C("div",TDe,[C("span",EDe,[qe(N(p(n)("settings.secondaryModel"))+" ",1),C("span",IDe,N(p(n)("settings.secondaryModelHint")),1)]),B.value.length>0?(y(),M("div",LDe,[j(mPe,{"model-value":ie.value,effort:ne.value,groups:B.value,"model-info-by-id":X.value,onSelect:le},null,8,["model-value","effort","groups","model-info-by-id"])])):(y(),M("span",$De,N(ie.value||p(n)("settings.noSecondaryModel")),1))])])])):ee("",!0)],512),[[qs,d.value==="agent"]]),Bn(C("section",NDe,[C("section",FDe,[C("h3",RDe,N(p(n)("settings.versionAndUpdates")),1),C("div",ODe,[C("div",PDe,[C("span",DDe,[qe(N(p(n)("settings.appVersion"))+" ",1),C("span",BDe,N(p(n)("settings.appVersionHint")),1)]),C("span",HDe,N(p(T)),1)]),C("div",zDe,[C("span",WDe,[qe(N(p(n)("settings.serverVersion"))+" ",1),C("span",UDe,N(p(n)("settings.serverVersionHint")),1)]),C("span",jDe,N(e.serverVersion||"-"),1)]),C("div",VDe,[C("span",qDe,[qe(N(p(n)("settings.serverAddress"))+" ",1),C("span",KDe,N(p(n)("settings.serverAddressHint")),1)]),C("span",ZDe,N(p(k)),1)]),p(A).canCheck?(y(),M("div",GDe,[C("span",YDe,[qe(N(p(n)("settings.checkUpdate"))+" ",1),I.value?(y(),M("span",XDe,N(I.value),1)):(y(),M("span",JDe,N(p(n)("settings.checkUpdateHint")),1))]),j(p(Rt),{variant:"secondary",size:"sm",disabled:E.value,onClick:D},{default:me(()=>[qe(N(E.value?p(n)("settings.updateChecking"):p(n)("settings.checkUpdateBtn")),1)]),_:1},8,["disabled"])])):ee("",!0),p(A).canToggleAutoDownload?(y(),M("div",QDe,[C("span",eBe,[qe(N(p(n)("settings.autoDownloadUpdate"))+" ",1),C("span",tBe,N(p(n)("settings.autoDownloadUpdateHint")),1)]),j(p(ed),{"model-value":p(A).autoDownload.value,label:p(n)("settings.autoDownloadUpdate"),"onUpdate:modelValue":Oe[11]||(Oe[11]=Ge=>p(A).setAutoDownload(Ge))},null,8,["model-value","label"])])):ee("",!0)])]),e.config?(y(),M("section",nBe,[C("h3",oBe,N(p(n)("settings.privacy")),1),C("div",sBe,[C("div",iBe,[C("span",rBe,[qe(N(p(n)("settings.telemetry"))+" ",1),C("span",lBe,N(p(n)("settings.telemetryHint")),1),C("span",aBe,N(p(n)("settings.telemetryRestartHint")),1)]),j(p(ed),{"model-value":e.config.telemetry!==!1,disabled:e.configSaving,label:p(n)("settings.telemetry"),"onUpdate:modelValue":Oe[12]||(Oe[12]=Ge=>ve())},null,8,["model-value","disabled","label"])])])])):ee("",!0),C("section",uBe,[C("h3",cBe,N(p(n)("settings.diagnostics")),1),C("div",dBe,[C("div",fBe,[C("span",pBe,[qe(N(p(n)("settings.exportLog"))+" ",1),C("span",hBe,N(p(n)("settings.exportLogHint")),1),p(Qr)()?ee("",!0):(y(),M("span",mBe,N(p(n)("settings.logHint")),1))]),j(p(Rt),{variant:"secondary",size:"sm",onClick:S},{default:me(()=>[qe(N(p(n)("settings.exportLogBtn")),1)]),_:1})])])])],512),[[qs,d.value==="advanced"]]),Bn(C("section",gBe,[C("div",vBe,[C("h4",yBe,N(p(n)("settings.archivedTitle")),1),C("p",kBe,N(p(n)("settings.archivedDesc")),1)]),C("div",bBe,[C("label",CBe,[Oe[17]||(Oe[17]=C("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},[C("circle",{cx:"11",cy:"11",r:"7"}),C("path",{d:"m21 21-4.3-4.3"})],-1)),Bn(C("input",{"onUpdate:modelValue":Oe[13]||(Oe[13]=Ge=>ge.value=Ge),placeholder:p(n)("settings.archivedSearch")},null,8,wBe),[[ai,ge.value]])]),j(p(n3),{"model-value":Q.value,options:Se.value,size:"sm","aria-label":p(n)("settings.archivedAllWorkspaces"),"onUpdate:modelValue":Oe[14]||(Oe[14]=Ge=>Q.value=Ge)},null,8,["model-value","options","aria-label"]),j(p(wi),{size:"sm","model-value":te.value,options:[{value:"archived-desc",label:p(n)("settings.archivedSortArchived"),icon:"clock"},{value:"created-desc",label:p(n)("settings.archivedSortCreated"),icon:"calendar-schedule"},{value:"name-asc",label:p(n)("settings.archivedSortName"),icon:"sort"}],"onUpdate:modelValue":Oe[15]||(Oe[15]=Ge=>te.value=Ge)},null,8,["model-value","options"])]),fe.value?(y(),M("div",_Be,N(p(n)("settings.archivedLoadingAll")),1)):(y(),M(Pe,{key:1},[_e.value.length>0?(y(),M("div",xBe,[(y(!0),M(Pe,null,pt(_e.value,Ge=>(y(),M("section",{key:Ge.cwd,class:"archive-card"},[C("div",SBe,[j(p(Te),{name:"folder-closed",size:"md"}),C("span",ABe,N(Ge.cwd),1),C("span",MBe,N(p(n)("settings.archivedSessionsCount",{count:Ge.items.length})),1)]),C("div",TBe,[(y(!0),M(Pe,null,pt(Ge.items,at=>(y(),M("div",{key:at.id,class:"archive-row"},[C("div",EBe,[C("div",IBe,N(at.title),1),C("div",LBe,N(p(n)("settings.archivedAt",{time:it(at.updatedAt)})),1)]),j(p(Rt),{variant:"secondary",size:"sm",onClick:Tt=>Ee(at.id)},{default:me(()=>[j(p(Te),{name:"undo",size:"sm"}),C("span",null,N(p(n)("settings.archivedRestore")),1)]),_:1},8,["onClick"])]))),128))])]))),128))])):(y(),M("div",$Be,N(Y.value.length===0?p(n)("settings.archivedEmpty"):p(n)("settings.archivedNoMatch")),1))],64))],512),[[qs,d.value==="archived"]])],34)])],512)]),_:1},8,["aria-label"]))}}),RBe=ft(FBe,[["__scopeId","data-v-146a8c47"]]),OBe={class:"aw"},PBe={class:"crumbbar"},DBe={class:"crumbs"},BBe={key:0,class:"crumb-sep"},HBe=["onClick"],zBe={key:0,class:"filterbar"},WBe=["placeholder"],UBe={class:"folder-list"},jBe={key:0,class:"fl-loading"},VBe=["onClick"],qBe={class:"folder-name search-rel"},KBe={key:0,class:"fl-empty"},ZBe={key:1,class:"fl-loading"},GBe=["onClick"],YBe={class:"folder-name"},XBe={key:0,class:"fl-empty"},JBe={class:"paste-row"},QBe={class:"paste-input-wrap"},eHe={key:1,class:"add-error",role:"alert"},tHe={class:"actions"},nHe={class:"footer-hint"},oHe=600,sHe=6,_S=150,iHe=et({__name:"AddWorkspaceDialog",props:{browseFs:{type:Function},getFsHome:{type:Function},defaultPath:{},error:{}},emits:["add","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z(!0),r=Z(!1),l=Z(!1),a=Z(""),u=Z(null),c=Z([]),d=Z(""),f=Z(!1),h=Z([]),m=R(()=>d.value.trim().length>0);let v=0,k=null;function w(U,z){const W=U.toLowerCase(),K=z.toLowerCase();let V=0;for(let ie=0;ie<K.length&&V<W.length;ie++)K[ie]===W[V]&&V++;return V===W.length}async function b(U){const z=a.value,W=U.trim();if(!z||W===""){h.value=[],f.value=!1;return}const K=++v;f.value=!0;const V=[],ie=[{path:z,depth:0}];let ne=0;for(;ie.length>0&&ne<oHe&&V.length<_S;){if(K!==v)return;const X=ie.shift();ne++;let le;try{le=await o.browseFs(X.path)}catch{continue}if(K!==v)return;for(const Ie of le.entries){if(!Ie.isDir)continue;const de=Ie.path.startsWith(z)?Ie.path.slice(z.length).replace(/^\/+/,""):Ie.path;if(w(W,de||Ie.name)&&(V.push({path:Ie.path,name:Ie.name,rel:de||Ie.name}),V.length>=_S))break;X.depth+1<sHe&&ie.push({path:Ie.path,depth:X.depth+1})}K===v&&(h.value=[...V])}K===v&&(f.value=!1)}Je(d,U=>{if(k&&clearTimeout(k),U.trim()===""){v++,h.value=[],f.value=!1;return}k=setTimeout(()=>void b(U),220)});const _=Z(!1),g=Z(""),x=R(()=>g.value.trim()),S=R(()=>{const U=a.value;if(!U)return[];const z=U.split("/").filter(Boolean),W=[{label:"/",path:"/"}];let K="";for(const V of z)K+=`/${V}`,W.push({label:V,path:K});return W}),T=R(()=>a.value.length>0);async function A(U){r.value=!0;try{const z=await o.browseFs(U);if(!z.path){l.value=!0;return}a.value=z.path,u.value=z.parent,c.value=z.entries,d.value="",l.value=!1}catch{l.value=!0}finally{r.value=!1}}function E(U){U.isDir&&A(U.path)}function P(){u.value&&A(u.value)}function D(){T.value&&s("add",a.value)}function I(){x.value.length!==0&&s("add",x.value)}const{handleCompositionStart:$,handleCompositionEnd:B,isComposingKeyEvent:H}=Ar();function O(U){H(U)||I()}function F(U){U.key==="Escape"&&H(U)&&U.stopPropagation()}return dn(async()=>{r.value=!0;try{if(o.defaultPath&&(await A(o.defaultPath),!l.value))return;const U=await o.getFsHome();U.home?await A(U.home):l.value=!0}catch{l.value=!0}finally{r.value=!1}}),bn(()=>{k&&clearTimeout(k)}),(U,z)=>(y(),he(p(ua),{open:i.value,"onUpdate:open":z[5]||(z[5]=W=>i.value=W),title:p(n)("workspace.addTitle"),size:"lg",height:"fixed",padded:!1,onClose:z[6]||(z[6]=W=>s("close"))},{default:me(()=>[C("div",OBe,[l.value?ee("",!0):(y(),M(Pe,{key:0},[C("div",PBe,[j(p(gn),{size:"sm",disabled:!u.value,label:p(n)("workspace.up"),tooltip:p(n)("workspace.up"),onClick:P},{default:me(()=>[j(p(Te),{name:"arrow-up",size:"md"})]),_:1},8,["disabled","label","tooltip"]),C("div",DBe,[(y(!0),M(Pe,null,pt(S.value,(W,K)=>(y(),M(Pe,{key:W.path},[K>1?(y(),M("span",BBe,"/")):ee("",!0),C("button",{class:Re(["crumb",{last:K===S.value.length-1}]),onClick:V=>A(W.path)},N(W.label),11,HBe)],64))),128))])]),r.value?ee("",!0):(y(),M("div",zBe,[j(p(Te),{class:"filter-icon",name:"search",size:"md"}),Bn(C("input",{"onUpdate:modelValue":z[0]||(z[0]=W=>d.value=W),class:"filter-input",type:"text",placeholder:p(n)("workspace.searchPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:z[1]||(z[1]=It(()=>{},["stop"]))},null,40,WBe),[[ai,d.value]]),f.value?(y(),he(p(Ao),{key:0,size:"sm"})):ee("",!0)])),C("div",UBe,[r.value?(y(),M("div",jBe,N(p(n)("workspace.browsing")),1)):m.value?(y(),M(Pe,{key:1},[(y(!0),M(Pe,null,pt(h.value,W=>(y(),M("button",{key:W.path,class:"folder-row",onClick:K=>A(W.path)},[j(p(Te),{class:"dir-icon",name:"folder-closed",size:"sm"}),C("span",qBe,N(W.rel),1)],8,VBe))),128)),!f.value&&h.value.length===0?(y(),M("div",KBe,N(p(n)("workspace.noFilterMatch",{q:d.value.trim()})),1)):f.value&&h.value.length===0?(y(),M("div",ZBe,N(p(n)("workspace.searching")),1)):ee("",!0)],64)):(y(),M(Pe,{key:2},[(y(!0),M(Pe,null,pt(c.value,W=>(y(),M("button",{key:W.path,class:"folder-row",onClick:K=>E(W)},[j(p(Te),{class:"dir-icon",name:"folder-closed",size:"sm"}),C("span",YBe,N(W.name),1)],8,GBe))),128)),c.value.length===0?(y(),M("div",XBe,N(p(n)("workspace.noSubfolders")),1)):ee("",!0)],64))])],64)),C("div",{class:Re(["paste-section",{"paste-only":l.value}])},[!l.value&&!_.value?(y(),he(p(Rt),{key:0,variant:"ghost",size:"sm",onClick:z[2]||(z[2]=W=>_.value=!0)},{default:me(()=>[qe(N(p(n)("workspace.pasteToggle")),1)]),_:1})):(y(),he(p(IW),{key:1,label:p(n)("workspace.pathLabel")},{default:me(()=>[C("div",JBe,[C("div",QBe,[j(p(js),{modelValue:g.value,"onUpdate:modelValue":z[3]||(z[3]=W=>g.value=W),placeholder:p(n)("workspace.pathPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:[xl(It(O,["stop"]),["enter"]),F],onCompositionstart:p($),onCompositionend:p(B)},null,8,["modelValue","placeholder","onKeydown","onCompositionstart","onCompositionend"])]),j(p(gn),{disabled:x.value.length===0,label:p(n)("workspace.add"),tooltip:p(n)("workspace.add"),onClick:I},{default:me(()=>[j(p(Te),{name:"plus",size:"md"})]),_:1},8,["disabled","label","tooltip"])])]),_:1},8,["label"]))],2),e.error?(y(),M("div",eHe,N(e.error),1)):ee("",!0),C("div",tHe,[j(p(pn),{text:a.value},{default:me(()=>[l.value?ee("",!0):(y(),he(p(Rt),{key:0,variant:"primary",disabled:!T.value,onClick:D},{default:me(()=>[qe(N(p(n)("workspace.openThisFolder")),1)]),_:1},8,["disabled"]))]),_:1},8,["text"]),j(p(Rt),{variant:"secondary",onClick:z[4]||(z[4]=W=>s("close"))},{default:me(()=>[qe(N(p(n)("workspace.cancel")),1)]),_:1})]),C("div",nHe,N(p(n)("workspace.browseHint")),1)])]),_:1},8,["open","title"]))}}),rHe=ft(iHe,[["__scopeId","data-v-fea98be5"]]),lHe={key:0,class:"confirm-dialog__message"},aHe=et({__name:"ConfirmDialog",props:{open:{type:Boolean},title:{},message:{},confirmLabel:{},cancelLabel:{},variant:{default:"danger"},loading:{type:Boolean}},emits:["update:open","confirm","cancel"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt();function i(){n.loading||(o("update:open",!1),o("cancel"))}function r(l){if(l.key!=="Enter"||!n.open||n.loading)return;const a=l.target;a instanceof HTMLButtonElement||a instanceof HTMLAnchorElement||a instanceof HTMLTextAreaElement||a instanceof HTMLSelectElement||a instanceof HTMLInputElement||(l.preventDefault(),o("confirm"))}return typeof window<"u"&&window.addEventListener("keydown",r),Vn(()=>{typeof window<"u"&&window.removeEventListener("keydown",r)}),(l,a)=>(y(),he(p(ua),{open:e.open,title:e.title,height:"auto","initial-focus":".confirm-dialog__confirm","close-on-esc":!e.loading,"close-on-overlay":!e.loading,"onUpdate:open":a[1]||(a[1]=u=>o("update:open",u)),onClose:i},{foot:me(()=>[j(p(Rt),{variant:"secondary",disabled:e.loading,onClick:i},{default:me(()=>[qe(N(e.cancelLabel??p(s)("common.cancel")),1)]),_:1},8,["disabled"]),j(p(Rt),{class:"confirm-dialog__confirm",variant:e.variant,loading:e.loading,onClick:a[0]||(a[0]=u=>o("confirm"))},{default:me(()=>[qe(N(e.confirmLabel??p(s)("common.confirm")),1)]),_:1},8,["variant","loading"])]),default:me(()=>[e.message?(y(),M("p",lHe,N(e.message),1)):ee("",!0)]),_:1},8,["open","title","close-on-esc","close-on-overlay"]))}}),uHe=ft(aHe,[["__scopeId","data-v-aa5422da"]]),cHe=et({__name:"ConfirmDialogHost",setup(e){const{current:t,busy:n,settle:o,runAction:s}=hu();function i(){s()}return(r,l)=>p(t)!==null?(y(),he(uHe,{key:0,open:!0,title:p(t).title,message:p(t).message,"confirm-label":p(t).confirmLabel,"cancel-label":p(t).cancelLabel,variant:p(t).variant,loading:p(n),onConfirm:i,onCancel:l[0]||(l[0]=a=>p(o)(!1))},null,8,["title","message","confirm-label","cancel-label","variant","loading"])):ee("",!0)}}),dHe={class:"rows"},fHe={class:"row"},pHe={class:"row"},hHe={class:"row"},mHe={class:"row"},gHe={class:"row"},vHe={class:"row"},yHe={class:"ctx-text"},kHe={key:0,class:"bar"},bHe={class:"row"},CHe=et({__name:"StatusPanel",props:{status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},costUsd:{}},emits:["close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z(!0),r=R(()=>o.status.ctxMax<=0?0:Math.min(100,Math.max(0,Math.ceil(o.status.ctxUsed/o.status.ctxMax*100)))),l=R(()=>o.status.ctxMax>0?n("status.statusContextValue",{used:Al(o.status.ctxUsed),max:Al(o.status.ctxMax),pct:r.value}):n("status.statusNone"));function a(m){return n(m==="yolo"?"status.permissionYolo":m==="auto"?"status.permissionAuto":"status.permissionManual")}const u=R(()=>{const m=o.status.permission;return m==="auto"?"var(--color-danger)":m==="yolo"?"var(--color-warning)":"var(--color-text)"}),c=R(()=>o.planMode?n("status.planOn"):n("status.planOff")),d=R(()=>o.swarmMode?n("status.swarmOn"):n("status.swarmOff")),f=R(()=>typeof o.costUsd=="number"&&o.costUsd>0),h=R(()=>f.value?`$${o.costUsd.toFixed(4)}`:n("status.statusNone"));return(m,v)=>(y(),he(p(ua),{open:i.value,"onUpdate:open":v[0]||(v[0]=k=>i.value=k),title:p(n)("status.statusPanelTitle"),onClose:v[1]||(v[1]=k=>s("close"))},{default:me(()=>[C("dl",dHe,[C("div",fHe,[C("dt",null,N(p(n)("status.statusModel")),1),C("dd",null,N(e.status.model),1)]),C("div",pHe,[C("dt",null,N(p(n)("status.statusThinking")),1),C("dd",null,N(e.thinking),1)]),C("div",hHe,[C("dt",null,N(p(n)("status.statusPermission")),1),C("dd",{style:Zt({color:u.value})},N(a(e.status.permission)),5)]),C("div",mHe,[C("dt",null,N(p(n)("status.statusPlanMode")),1),C("dd",{class:Re({"plan-on":e.planMode})},N(c.value),3)]),C("div",gHe,[C("dt",null,N(p(n)("status.statusSwarmMode")),1),C("dd",{class:Re({"swarm-on":e.swarmMode})},N(d.value),3)]),C("div",vHe,[C("dt",null,N(p(n)("status.statusContext")),1),C("dd",null,[C("span",yHe,N(l.value),1),e.status.ctxMax>0?(y(),M("span",kHe,[C("i",{style:Zt({width:r.value+"%"})},null,4)])):ee("",!0)])]),C("div",bHe,[C("dt",null,N(p(n)("status.statusCost")),1),C("dd",null,N(h.value),1)])])]),_:1},8,["open","title"]))}}),wHe=ft(CHe,[["__scopeId","data-v-340d1b31"]]),_He={key:0,class:"actions"},xHe=["onClick"],SHe=["onClick"],AHe={key:1,class:"details"},MHe=et({__name:"WarningToasts",props:{warnings:{}},emits:["dismiss"],setup(e,{emit:t}){const n=e,o=t,{t:s}=Nt();function i(E){return typeof E=="object"&&E!==null}function r(E){return i(E)?E.title:E}function l(E){return i(E)?E.message??"":""}function a(E){return i(E)?E.details:void 0}function u(E){return i(E)?E.severity==="error":E.startsWith(`${s("warnings.errorLabel")}:`)||/\b4\d\d\b|error|失败|failed/i.test(E)}function c(E){return i(E)?E.severity==="error"?"danger":E.severity==="success"?"success":E.severity==="info"?"info":"warning":u(E)?"danger":"warning"}function d(E){return i(E)?`notice:${E.severity}:${E.title}:${E.message??""}:${JSON.stringify(E.details??[])}`:`text:${E}`}function f(E){if(!i(E))return E;const P=[E.title];E.message&&P.push(E.message);const D=E.details??[];if(D.length>0){P.push("",`${s("warnings.diagnostics")}:`);for(const I of D)P.push(`${I.label}: ${I.value}`)}return P.join(` +`)}let h=1;const m=Z([]),v=new Map,k=new Map;function w(E){const P=u(E)?12e3:6e3;return typeof window<"u"&&window.matchMedia?.("(hover: none)").matches===!0?P+5e3:P}function b(E,P){const D=v.get(E)??{handle:null,deadline:0,remaining:0};D.handle=setTimeout(()=>A(E),P),D.deadline=Date.now()+P,v.set(E,D)}function _(E){const P=v.get(E);P&&P.handle!==null&&clearTimeout(P.handle),v.delete(E)}function g(E){const P=v.get(E);!P||P.handle===null||(clearTimeout(P.handle),P.handle=null,P.remaining=Math.max(0,P.deadline-Date.now()))}function x(E){if(m.value.find(I=>I.id===E)?.detailsOpen)return;const D=v.get(E);!D||D.handle!==null||b(E,D.remaining)}function S(E){E.detailsOpen=!E.detailsOpen,E.detailsOpen?g(E.id):x(E.id)}async function T(E){if(!await Zs(f(E.warning)))return;E.copied=!0;const D=k.get(E.id);D&&clearTimeout(D),k.set(E.id,setTimeout(()=>{E.copied=!1,k.delete(E.id)},1400))}function A(E){_(E);const P=k.get(E);P&&clearTimeout(P),k.delete(E);const D=m.value.findIndex(I=>I.id===E);D!==-1&&(m.value=m.value.filter(I=>I.id!==E),o("dismiss",D))}return Je(()=>n.warnings,E=>{const P=[...m.value];m.value=E.map(D=>{const I=d(D),$=P.findIndex(O=>O.key===I),B=$===-1?void 0:P.splice($,1)[0];if(B)return B.warning=D,B;const H={id:h++,key:I,warning:D,detailsOpen:!1,copied:!1};return b(H.id,w(D)),H});for(const D of P){_(D.id);const I=k.get(D.id);I&&clearTimeout(I),k.delete(D.id)}},{immediate:!0,flush:"post"}),bn(()=>{v.forEach(E=>{E.handle!==null&&clearTimeout(E.handle)}),v.clear(),k.forEach(E=>clearTimeout(E)),k.clear()}),(E,P)=>(y(),he(YA,{name:"toast",tag:"div",class:"toasts",role:"status","aria-live":"polite"},{default:me(()=>[(y(!0),M(Pe,null,pt(m.value,D=>(y(),he(p(cU),{key:D.id,variant:c(D.warning),title:r(D.warning),message:l(D.warning),"dismiss-label":p(s)("warnings.dismiss"),onDismiss:I=>A(D.id),onPointerenter:I=>g(D.id),onPointerleave:I=>x(D.id)},{default:me(()=>[a(D.warning)?.length?(y(),M("div",_He,[C("button",{class:"link",type:"button",onClick:I=>S(D)},N(D.detailsOpen?p(s)("warnings.hideDetails"):p(s)("warnings.showDetails")),9,xHe),C("button",{class:"link",type:"button",onClick:I=>T(D)},N(D.copied?p(s)("warnings.copied"):p(s)("warnings.copyDetails")),9,SHe)])):ee("",!0),D.detailsOpen&&a(D.warning)?.length?(y(),M("dl",AHe,[(y(!0),M(Pe,null,pt(a(D.warning),I=>(y(),M("div",{key:`${I.label}:${I.value}`,class:"detail-row"},[C("dt",null,N(I.label),1),C("dd",null,N(I.value),1)]))),128))])):ee("",!0)]),_:2},1032,["variant","title","message","dismiss-label","onDismiss","onPointerenter","onPointerleave"]))),128))]),_:1}))}}),THe=ft(MHe,[["__scopeId","data-v-ac44e9ef"]]),EHe={class:"topbar"},IHe={class:"wsq"},LHe=["aria-label"],$He={class:"tb-path"},NHe={class:"ws"},FHe={class:"se"},RHe={class:"tb-sub"},OHe=et({__name:"MobileTopBar",props:{workspace:{default:null},sessionTitle:{default:""},running:{type:Boolean,default:!1},branch:{default:""},sessionCount:{default:0}},emits:["openSwitcher","openSettings"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=R(()=>{const a=o.workspace,c=(a?.name||a?.root||"").trim().charAt(0);return c?c.toUpperCase():"K"}),r=R(()=>o.workspace?.name??n("workspace.noWorkspace")),l=R(()=>o.running?n("mobile.running"):n("mobile.idle"));return(a,u)=>(y(),M("div",EHe,[C("span",IHe,N(i.value),1),C("button",{type:"button",class:"tb-mid","aria-label":p(n)("mobile.openSwitcher"),onClick:u[0]||(u[0]=c=>s("openSwitcher"))},[C("span",$He,[C("span",NHe,N(r.value),1),e.sessionTitle?(y(),M(Pe,{key:0},[u[2]||(u[2]=C("span",{class:"sl"},"/",-1)),C("span",FHe,N(e.sessionTitle),1)],64)):ee("",!0),u[3]||(u[3]=C("span",{class:"cv"},"⌄",-1))]),C("span",RHe,[C("span",{class:Re(["rd",{on:e.running}])},null,2),C("span",null,N(l.value),1),e.branch?(y(),M(Pe,{key:0},[qe(" · "+N(e.branch),1)],64)):ee("",!0),e.sessionCount>0?(y(),M(Pe,{key:1},[qe(" · "+N(p(n)("mobile.sessionCount",{n:e.sessionCount})),1)],64)):ee("",!0)])],8,LHe),j(p(gn),{size:"lg",label:p(n)("mobile.openSettings"),onClick:u[1]||(u[1]=c=>s("openSettings"))},{default:me(()=>[j(p(Te),{name:"sliders",size:"lg"})]),_:1},8,["label"])]))}}),PHe=ft(OHe,[["__scopeId","data-v-7f357087"]]),DHe={key:0,class:"sheet-root"},BHe=["aria-label"],HHe=["aria-label"],zHe={key:0,class:"sheet-head"},WHe={class:"sheet-title"},UHe={class:"sheet-body"},jHe=et({__name:"BottomSheet",props:{modelValue:{type:Boolean},title:{default:""},closeOnEsc:{type:Boolean,default:!0}},emits:["update:modelValue","close"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t;function i(){s("update:modelValue",!1),s("close")}function r(l){l.key==="Escape"&&o.closeOnEsc&&i()}return Je(()=>o.modelValue,l=>{typeof document>"u"||(l?document.addEventListener("keydown",r):document.removeEventListener("keydown",r))},{immediate:!0}),bn(()=>{typeof document<"u"&&document.removeEventListener("keydown",r)}),(l,a)=>(y(),he(as,{name:"sheet"},{default:me(()=>[e.modelValue?(y(),M("div",DHe,[C("div",{class:"sheet-scrim",onClick:i}),C("div",{class:"sheet-panel",role:"dialog","aria-label":e.title||p(n)("mobile.sheetLabel")},[C("button",{type:"button",class:"sheet-grab","aria-label":p(n)("mobile.closeSheet"),onClick:i},null,8,HHe),e.title?(y(),M("div",zHe,[C("span",WHe,N(e.title),1)])):ee("",!0),C("div",UHe,[xn(l.$slots,"default",{},void 0,!0)])],8,BHe)])):ee("",!0)]),_:3}))}}),CF=ft(jHe,[["__scopeId","data-v-c3d5dadc"]]),VHe={class:"mlist"},qHe={key:0,class:"mempty"},KHe=["onClick"],ZHe={class:"mgh-main"},GHe={class:"mgh-name"},YHe={class:"mgh-path"},XHe={key:2,class:"att"},JHe={key:0,class:"mempty small"},QHe=["onClick"],eze={class:"m"},tze={class:"s"},nze={key:0,class:"att"},oze={key:1,class:"mshow-more-row"},sze=["disabled","onClick"],ize={key:1,class:"mshow-more-sep","aria-hidden":"true"},rze=["onClick"],lze=et({__name:"MobileSwitcherSheet",props:{modelValue:{type:Boolean},groups:{},activeWorkspaceId:{default:null},activeId:{},attentionBySession:{default:()=>({})},attentionByWorkspace:{default:()=>({})}},emits:["update:modelValue","select","create","createInWorkspace","addWorkspace","rename","archive","deleteWorkspace","loadMore"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t;function i(){s("update:modelValue",!1)}function r($){s("select",$),i()}function l($){s("createInWorkspace",$),i()}function a(){s("create"),i()}function u(){s("addWorkspace"),i()}const c=Z(new Set);function d($){return c.value.has($)}function f($){const B=new Set(c.value);B.has($)?B.delete($):B.add($),c.value=B,x.value=null,E.value=null}const h=Z(new Map);function m($){return h.value.get($.workspace.id)??$.initialCount}function v($){const B=$.sessions.slice(0,m($));if(o.activeId&&!B.some(H=>H.id===o.activeId)){const H=$.sessions.find(O=>O.id===o.activeId);if(H)return[...B,H]}return B}function k($){return $.sessions.length>m($)||$.hasMore||$.loadingMore}function w($){return m($)>$.initialCount}function b($){const B=o.groups.find(F=>F.workspace.id===$);if(!B)return;const H=m(B)+O5,O=new Map(h.value);O.set($,H),h.value=O,B.sessions.length<H&&B.hasMore&&s("loadMore",$)}function _($){if(!h.value.has($))return;const B=new Map(h.value);B.delete($),h.value=B}function g($){return o.attentionByWorkspace[$]??0}const x=Z(null);function S($){x.value=x.value===$?null:$,E.value=null}function T($){x.value=null;const H=(typeof window<"u"?window.prompt(n("sidebar.rename"),$.title):null)?.trim();H&&s("rename",$.id,H)}function A($){x.value=null,s("archive",$)}const E=Z(null);function P($){E.value=E.value===$?null:$,x.value=null}function D($){Zs($.root),E.value=null}function I($){E.value=null,s("deleteWorkspace",$.id)}return($,B)=>(y(),he(CF,{"model-value":e.modelValue,"onUpdate:modelValue":B[2]||(B[2]=H=>s("update:modelValue",H))},{default:me(()=>[C("button",{type:"button",class:"newrow",onClick:a},[j(p(Te),{name:"message",size:"sm"}),qe(" "+N(p(n)("sidebar.newChat")),1)]),C("button",{type:"button",class:"newrow secondary",onClick:u},[j(p(Te),{name:"folder",size:"sm"}),qe(" "+N(p(n)("sidebar.newWorkspace")),1)]),C("div",VHe,[e.groups.length===0?(y(),M("div",qHe,N(p(n)("workspace.noWorkspace")),1)):ee("",!0),(y(!0),M(Pe,null,pt(e.groups,H=>(y(),M("div",{key:H.workspace.id,class:"mgroup"},[C("div",{class:Re(["mgh",{on:H.workspace.id===e.activeWorkspaceId}]),onClick:O=>f(H.workspace.id)},[d(H.workspace.id)?(y(),he(p(Te),{key:0,class:"mgh-folder",name:"folder-closed",size:"sm"})):(y(),he(p(Te),{key:1,class:"mgh-folder",name:"folder",size:"sm"})),C("div",ZHe,[C("span",GHe,N(H.workspace.name),1),j(p(pn),{text:H.workspace.root},{default:me(()=>[C("span",YHe,N(H.workspace.shortPath),1)]),_:2},1032,["text"])]),d(H.workspace.id)&&g(H.workspace.id)>0?(y(),M("span",XHe,N(g(H.workspace.id)),1)):ee("",!0),j(p(gn),{size:"lg",class:"mgh-more",label:p(n)("sidebar.options"),onClick:It(O=>P(H.workspace.id),["stop"])},{default:me(()=>[j(p(Te),{name:"dots-horizontal",size:"md"})]),_:1},8,["label","onClick"]),j(p(gn),{size:"lg",class:"mgh-add",label:p(n)("workspace.newInGroup"),onClick:It(O=>l(H.workspace.id),["stop"])},{default:me(()=>[j(p(Te),{name:"plus",size:"md"})]),_:1},8,["label","onClick"]),E.value===H.workspace.id?(y(),he(p(Cl),{key:3,class:"kmenu wsmenu",onClick:B[0]||(B[0]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{size:"lg",onClick:O=>D(H.workspace)},{default:me(()=>[qe(N(p(n)("sidebar.copyPath")),1)]),_:1},8,["onClick"]),j(p(hn),{size:"lg",danger:"",onClick:O=>I(H.workspace)},{default:me(()=>[qe(N(p(n)("sidebar.delete")),1)]),_:1},8,["onClick"])]),_:2},1024)):ee("",!0)],10,KHe),Bn(C("div",null,[H.sessions.length===0?(y(),M("div",JHe,N(p(n)("sidebar.noSessions")),1)):ee("",!0),(y(!0),M(Pe,null,pt(v(H),O=>(y(),M("div",{key:O.id,class:Re(["srow",{cur:O.id===e.activeId}]),onClick:F=>r(O.id)},[C("div",eze,[C("div",{class:Re(["t",{run:O.busy,aborted:!O.busy&&(e.attentionBySession[O.id]??0)===0&&O.lastTurnReason==="failed"}])},N(O.title),3),C("div",tze,N(O.time),1)]),(e.attentionBySession[O.id]??0)>0?(y(),M("span",nze,N(e.attentionBySession[O.id]),1)):ee("",!0),j(p(gn),{size:"lg",class:"kb",label:p(n)("sidebar.options"),onClick:It(F=>S(O.id),["stop"])},{default:me(()=>[j(p(Te),{name:"dots-horizontal",size:"md"})]),_:1},8,["label","onClick"]),x.value===O.id?(y(),he(p(Cl),{key:1,class:"kmenu",onClick:B[1]||(B[1]=It(()=>{},["stop"]))},{default:me(()=>[j(p(hn),{size:"lg",onClick:F=>T(O)},{default:me(()=>[qe(N(p(n)("sidebar.rename")),1)]),_:1},8,["onClick"]),j(p(hn),{size:"lg",onClick:F=>A(O.id)},{default:me(()=>[qe(N(p(n)("sidebar.archive")),1)]),_:1},8,["onClick"])]),_:2},1024)):ee("",!0)],10,QHe))),128)),k(H)||w(H)?(y(),M("div",oze,[k(H)?(y(),M("button",{key:0,type:"button",class:"mshow-more",disabled:H.loadingMore,onClick:It(O=>b(H.workspace.id),["stop"])},[j(p(Te),{name:"chevron-down",size:"sm"}),qe(" "+N(H.loadingMore?p(n)("sidebar.loadingMore"):p(n)("sidebar.showMore")),1)],8,sze)):ee("",!0),k(H)&&w(H)?(y(),M("span",ize,"·")):ee("",!0),w(H)?(y(),M("button",{key:2,type:"button",class:"mshow-more",onClick:It(O=>_(H.workspace.id),["stop"])},[j(p(Te),{name:"chevron-up",size:"sm"}),qe(" "+N(p(n)("sidebar.showLess")),1)],8,rze)):ee("",!0)])):ee("",!0)],512),[[qs,!d(H.workspace.id)]])]))),128))])]),_:1},8,["model-value"]))}}),aze=ft(lze,[["__scopeId","data-v-67278201"]]),uze={class:"group-title"},cze={class:"srow-main"},dze={class:"srow-label"},fze={class:"srow-sub"},pze={class:"srow read-only"},hze={class:"srow-main"},mze={class:"srow-label"},gze={key:0,class:"srow-sub"},vze={class:"cache-note"},yze={class:"srow-main"},kze={class:"srow-label"},bze={class:"srow-sub"},Cze=["aria-checked"],wze={class:"srow-main"},_ze={class:"srow-label"},xze={class:"srow-sub"},Sze=["aria-checked"],Aze={class:"srow-main"},Mze={class:"srow-label"},Tze={class:"srow read-only"},Eze={class:"srow-main"},Ize={class:"srow-label"},Lze={class:"srow-sub"},$ze=["aria-label"],Nze={class:"group-title"},Fze={class:"srow-main"},Rze={class:"srow-label"},Oze={class:"srow-sub"},Pze={class:"srow read-only pref"},Dze={class:"srow-main"},Bze={class:"srow-label"},Hze={class:"srow read-only pref"},zze={class:"srow-main"},Wze={class:"srow-label"},Uze={class:"srow read-only pref"},jze={class:"srow-main"},Vze={class:"srow-label"},qze={key:0,class:"srow read-only acct-profile"},Kze={class:"acct-avatar","aria-hidden":"true"},Zze=["src"],Gze={class:"srow-main"},Yze={class:"acct-name-row"},Xze={class:"srow-label"},Jze={class:"srow-sub"},Qze={class:"srow-main"},eWe={class:"srow-label"},tWe={class:"srow-main"},nWe={class:"srow-label"},oWe={key:3,class:"srow read-only"},sWe={class:"srow-main"},iWe={class:"srow-label"},rWe={class:"srow-val dim"},lWe={class:"arch-subhead"},aWe={class:"arch-count"},uWe={class:"arch-tools"},cWe={key:0,class:"arch-empty"},dWe={class:"arch-meta"},fWe={class:"arch-name"},pWe={class:"arch-time"},hWe={key:2,class:"arch-empty"},mWe=100,gWe=et({__name:"MobileSettingsSheet",props:{modelValue:{type:Boolean},initialView:{},status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},colorScheme:{default:"system"},fontScale:{default:"medium"},managedProviderStatus:{default:null},managedUserInfo:{default:null},serverVersion:{default:""},models:{default:()=>[]}},emits:["update:modelValue","pickModel","setThinking","togglePlan","toggleSwarm","setPermission","setColorScheme","setFontScale","login","logout"],setup(e,{emit:t}){const{t:n}=Nt(),{isConfirmOpen:o}=hu(),s=e,i=t;function r(X){i("setColorScheme",X)}const l=["manual","yolo","auto"],a=R(()=>s.models?.find(X=>X.id===s.status?.modelId)),u=R(()=>p2(a.value)),c=R(()=>Up(a.value)),d=R(()=>Dm(a.value,s.thinking)),f=R(()=>c.value.includes(d.value)?d.value:""),h=R(()=>c.value.map(X=>({value:X,label:y3(X)}))),m=R(()=>s.planMode===!0),v=R(()=>s.swarmMode===!0),k=Z(!1);Je(()=>s.managedUserInfo?.avatar,()=>{k.value=!1});const w=R(()=>!!s.managedUserInfo?.avatar&&!k.value),b=R(()=>s.managedUserInfo?.userLevelName?.trim()??""),_=R(()=>{const X=s.status.permission;return X==="auto"?"var(--color-danger)":X==="yolo"?"var(--color-warning)":"var(--color-text-muted)"}),g=R(()=>{const X=s.status.permission,le=n(X==="yolo"?"mobile.permYoloSub":X==="auto"?"mobile.permAutoSub":"mobile.permManualSub");return`${X} · ${le}`}),x=R(()=>s.status.ctxMax>0?Math.min(100,Math.max(0,Math.ceil(s.status.ctxUsed/s.status.ctxMax*100))):0),S=R(()=>s.status.ctxMax>0?`${Al(s.status.ctxUsed)}/${Al(s.status.ctxMax)}`:n("status.statusNone"));function T(X){i("setThinking",My(a.value,X))}function A(){const X=l.indexOf(s.status.permission),le=l[(X+1)%l.length];i("setPermission",le)}function E(){i("pickModel"),i("update:modelValue",!1)}function P(){i("login"),i("update:modelValue",!1)}function D(){i("logout"),i("update:modelValue",!1)}const I=mu(),$=Z("main"),B=Z([]),H=Z(!1),O=Z(!1),F=Z(""),U=Z("archived-desc");async function z(){if(!H.value){H.value=!0,O.value=!1;try{const X=[];let le;for(;;){const Ie=await I.loadArchivedSessions({beforeId:le,pageSize:mWe});if(X.push(...Ie.items),!Ie.hasMore||Ie.items.length===0)break;const de=Ie.items.at(-1)?.id;if(de===void 0)break;le=de}B.value=X,O.value=!0}catch(X){gl("loadAllArchived failed",X)}finally{H.value=!1}}}function W(){$.value="archived",F.value="",z()}Je(()=>s.modelValue,X=>{X&&s.initialView==="archived"&&W()});function K(){$.value="main"}const V=R(()=>{const X=F.value.trim().toLowerCase();let le=B.value.filter(Ie=>Ie.archived===!0);return X&&(le=le.filter(Ie=>Ie.title.toLowerCase().includes(X))),le=le.slice(),U.value==="archived-desc"?le.sort((Ie,de)=>de.updatedAt.localeCompare(Ie.updatedAt)):U.value==="created-desc"?le.sort((Ie,de)=>de.createdAt.localeCompare(Ie.createdAt)):le.sort((Ie,de)=>Ie.title.localeCompare(de.title,"zh")),le});async function ie(X){await I.restoreSession(X)&&(B.value=B.value.filter(Ie=>Ie.id!==X))}function ne(X){const le=new Date(X);if(Number.isNaN(le.getTime()))return X;const Ie=de=>String(de).padStart(2,"0");return`${le.getFullYear()}-${Ie(le.getMonth()+1)}-${Ie(le.getDate())} ${Ie(le.getHours())}:${Ie(le.getMinutes())}`}return Je(()=>s.modelValue,X=>{X||($.value="main")}),(X,le)=>(y(),he(CF,{"model-value":e.modelValue,title:p(n)("mobile.settingsTitle"),"close-on-esc":!p(o),"onUpdate:modelValue":le[6]||(le[6]=Ie=>i("update:modelValue",Ie))},{default:me(()=>[$.value==="main"?(y(),M(Pe,{key:0},[C("div",uze,N(p(n)("mobile.groupSession")),1),C("button",{type:"button",class:"srow",onClick:E},[C("span",cze,[C("span",dze,N(p(n)("status.statusModel")),1),C("span",fze,N(e.status.model),1)]),le[7]||(le[7]=C("span",{class:"chev"},"›",-1))]),C("div",pze,[C("span",hze,[C("span",mze,N(p(n)("status.statusThinking")),1),u.value==="unsupported"?(y(),M("span",gze,N(p(n)("status.modeNotSupported")),1)):ee("",!0)]),c.value.length>1?(y(),he(p(wi),{key:0,"model-value":f.value,options:h.value,size:"sm","onUpdate:modelValue":T},null,8,["model-value","options"])):(y(),M("span",{key:1,class:Re(["srow-val",{dim:d.value==="off"}])},N(d.value==="off"?p(n)("status.planOff"):p(y3)(d.value)),3))]),C("div",vze,N(p(n)("status.cacheNote")),1),C("button",{type:"button",class:"srow",onClick:le[0]||(le[0]=Ie=>i("togglePlan"))},[C("span",yze,[C("span",kze,N(p(n)("status.statusPlanMode")),1),C("span",bze,N(p(n)("mobile.planModeSub")),1)]),C("span",{class:Re(["toggle",{on:m.value}]),role:"switch","aria-checked":m.value},null,10,Cze)]),C("button",{type:"button",class:"srow",onClick:le[1]||(le[1]=Ie=>i("toggleSwarm"))},[C("span",wze,[C("span",_ze,N(p(n)("status.statusSwarmMode")),1),C("span",xze,N(p(n)("mobile.swarmModeSub")),1)]),C("span",{class:Re(["toggle",{on:v.value}]),role:"switch","aria-checked":v.value},null,10,Sze)]),C("button",{type:"button",class:"srow",onClick:A},[C("span",Aze,[C("span",Mze,N(p(n)("status.statusPermission")),1),C("span",{class:"srow-sub",style:Zt({color:_.value})},N(g.value),5)]),le[8]||(le[8]=C("span",{class:"chev"},"›",-1))]),C("div",Tze,[C("span",Eze,[C("span",Ize,N(p(n)("status.statusContext")),1),C("span",Lze,N(S.value),1)]),C("span",{class:"ctx-meter","aria-label":S.value},[C("i",{style:Zt({width:x.value+"%"})},null,4)],8,$ze)]),C("div",Nze,N(p(n)("mobile.groupApp")),1),C("button",{type:"button",class:"srow",onClick:W},[C("span",Fze,[C("span",Rze,N(p(n)("mobile.archivedSessions")),1),C("span",Oze,N(p(n)("mobile.archivedSessionsSub")),1)]),le[9]||(le[9]=C("span",{class:"chev"},"›",-1))]),C("div",Pze,[C("span",Dze,[C("span",Bze,N(p(n)("theme.colorSchemeLabel")),1)]),j(p(wi),{"model-value":e.colorScheme??"system",options:[{value:"light",label:p(n)("theme.light"),icon:"light-mode"},{value:"dark",label:p(n)("theme.dark"),icon:"dark-mode"},{value:"system",label:p(n)("theme.system")}],"onUpdate:modelValue":r},null,8,["model-value","options"])]),C("div",Hze,[C("span",zze,[C("span",Wze,N(p(n)("sidebar.language")),1)]),j(yF)]),C("div",Uze,[C("span",jze,[C("span",Vze,N(p(n)("settings.uiFontSize")),1)]),j(p(wi),{"model-value":e.fontScale,options:[{value:"small",label:"S"},{value:"medium",label:"M"},{value:"large",label:"L"},{value:"xlarge",label:"XL"}],"aria-label":p(n)("settings.uiFontSize"),"onUpdate:modelValue":le[2]||(le[2]=Ie=>i("setFontScale",Ie))},null,8,["model-value","aria-label"])]),e.managedProviderStatus==="authenticated"?(y(),M("div",qze,[C("span",Kze,[w.value?(y(),M("img",{key:0,src:e.managedUserInfo?.avatar,alt:"",onError:le[3]||(le[3]=Ie=>k.value=!0)},null,40,Zze)):(y(),he(p(Te),{key:1,name:"user",size:"md"}))]),C("span",Gze,[C("span",Yze,[C("span",Xze,N(e.managedUserInfo?.nickname||p(n)("sidebar.defaultUserName")),1),b.value?(y(),he(p(Vr),{key:0,class:"acct-level",variant:"neutral",size:"sm"},{default:me(()=>[qe(N(b.value),1)]),_:1})):ee("",!0)]),C("span",Jze,N(p(n)("settings.signedIn")),1)])])):ee("",!0),e.managedProviderStatus==="authenticated"?(y(),M("button",{key:1,type:"button",class:"srow acct out",onClick:D},[C("span",Qze,[C("span",eWe,N(p(n)("sidebar.signOut")),1)])])):(y(),M("button",{key:2,type:"button",class:"srow acct in",onClick:P},[C("span",tWe,[C("span",nWe,N(p(n)("sidebar.signIn")),1)])])),e.serverVersion?(y(),M("div",oWe,[C("span",sWe,[C("span",iWe,N(p(n)("settings.serverVersion")),1)]),C("span",rWe,N(e.serverVersion),1)])):ee("",!0)],64)):(y(),M(Pe,{key:1},[C("div",lWe,[C("button",{type:"button",class:"arch-back",onClick:K},[le[10]||(le[10]=C("span",{class:"chev back"},"‹",-1)),qe(" "+N(p(n)("mobile.archivedBack")),1)]),C("span",aWe,N(p(n)("mobile.sessionCount",{n:V.value.length})),1)]),C("div",uWe,[j(p(js),{class:"arch-search-input","model-value":F.value,size:"sm",placeholder:p(n)("settings.archivedSearch"),"onUpdate:modelValue":le[4]||(le[4]=Ie=>F.value=Ie)},null,8,["model-value","placeholder"]),j(p(wi),{size:"sm","model-value":U.value,options:[{value:"archived-desc",label:p(n)("settings.archivedSortArchived")},{value:"created-desc",label:p(n)("settings.archivedSortCreated")},{value:"name-asc",label:p(n)("settings.archivedSortName")}],"onUpdate:modelValue":le[5]||(le[5]=Ie=>U.value=Ie)},null,8,["model-value","options"])]),H.value?(y(),M("div",cWe,N(p(n)("settings.archivedLoadingAll")),1)):V.value.length>0?(y(!0),M(Pe,{key:1},pt(V.value,Ie=>(y(),M("div",{key:Ie.id,class:"arch-row"},[C("div",dWe,[C("div",fWe,N(Ie.title),1),C("div",pWe,N(p(n)("settings.archivedAt",{time:ne(Ie.updatedAt)})),1)]),j(p(Rt),{variant:"secondary",size:"sm",onClick:de=>ie(Ie.id)},{default:me(()=>[qe(N(p(n)("settings.archivedRestore")),1)]),_:1},8,["onClick"])]))),128)):(y(),M("div",hWe,N(B.value.length===0?p(n)("settings.archivedEmpty"):p(n)("settings.archivedNoMatch")),1))],64))]),_:1},8,["model-value","title","close-on-esc"]))}}),vWe=ft(gWe,[["__scopeId","data-v-41a9e678"]]),yWe=["mask"],kWe=et({__name:"BrandLogo",props:{size:{default:64}},setup(e){const t=`bl-eyes-${kO()}`,n=Z(null);let o;function s(){const i=n.value;i&&(i.classList.remove("blink-now"),i.getBoundingClientRect(),i.classList.add("blink-now"),clearTimeout(o),o=setTimeout(()=>i.classList.remove("blink-now"),300))}return Vn(()=>clearTimeout(o)),(i,r)=>(y(),M("svg",{ref_key:"logoRef",ref:n,class:"brand-logo",style:Zt({width:`${e.size}px`,height:`${e.size*22/32}px`}),viewBox:"0 0 32 22",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-label":"Kimi Code",onClick:s},[C("defs",null,[C("mask",{id:t,maskUnits:"userSpaceOnUse"},[...r[0]||(r[0]=[C("rect",{x:"0",y:"0",width:"32",height:"22",fill:"#fff"},null,-1),C("g",{class:"ch-eyes",fill:"#000"},[C("rect",{class:"ch-eye",x:"11.8",y:"7",width:"2.8",height:"8",rx:"1.4"}),C("rect",{class:"ch-eye",x:"17.4",y:"7",width:"2.8",height:"8",rx:"1.4"})],-1)])])]),C("rect",{x:"1",y:"1",width:"30",height:"20",rx:"6",fill:"var(--logo)",mask:`url(#${t})`},null,8,yWe)],4))}}),E8=ft(kWe,[["__scopeId","data-v-f04205a8"]]),bWe={key:0,class:"ls-done-card"},CWe={class:"ls-done-badge"},wWe={class:"ls-card-text"},_We={class:"ls-card-title"},xWe={class:"ls-card-hint"},SWe={key:1,class:"ls-cards"},AWe={class:"ls-card-text"},MWe={class:"ls-card-title"},TWe={class:"ls-reco"},EWe={class:"ls-card-hint"},IWe={class:"ls-card-logo ls-card-icon"},LWe={class:"ls-card-text"},$We={class:"ls-card-title"},NWe={class:"ls-card-hint"},FWe={key:2,class:"ls-flow"},RWe={key:0,class:"ls-center"},OWe={class:"ls-center-text"},PWe={key:1,class:"ls-device"},DWe={class:"ls-lead"},BWe=["href"],HWe={class:"ls-code-row"},zWe=["title"],WWe={class:"ls-status"},UWe={class:"ls-status-text"},jWe={class:"ls-countdown"},VWe={key:2,class:"ls-center"},qWe={class:"ls-center-text ls-success-text"},KWe={class:"ls-center-hint"},ZWe={class:"ls-center"},GWe={class:"ls-center-text ls-err-text"},YWe={class:"ls-center-hint"},XWe={class:"ls-actions"},JWe={class:"ls-center"},QWe={class:"ls-center-text ls-warn-text"},eUe={class:"ls-center-hint"},tUe={class:"ls-actions"},nUe=et({__name:"OnboardingLoginStep",props:{authReady:{type:Boolean},onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function}},emits:["success","addProvider"],setup(e,{emit:t}){const{t:n}=Nt(),o=e,s=t,i=Z("choice"),{step:r,pollError:l,flow:a,secondsLeft:u,startFlow:c,cancelFlow:d}=vF({onStartOAuthLogin:o.onStartOAuthLogin,onPollOAuthLogin:o.onPollOAuthLogin,onCancelOAuthLogin:o.onCancelOAuthLogin,onSuccess:()=>s("success")}),f=Z(!1);function h(){i.value="flow",c()}function m(){d(),i.value="choice"}async function v(){!a.value||!await Zs(a.value.verificationUriComplete)||(f.value=!0,setTimeout(()=>{f.value=!1},2e3))}function k(w){const b=Math.floor(w/60),_=w%60;return`${b}:${String(_).padStart(2,"0")}`}return(w,b)=>e.authReady?(y(),M("div",bWe,[C("span",CWe,[j(p(Te),{name:"check",size:"sm"})]),C("div",wWe,[C("div",_We,N(p(n)("onboarding.login.loggedInTitle")),1),C("div",xWe,N(p(n)("onboarding.login.loggedInHint")),1)])])):i.value==="choice"?(y(),M("div",SWe,[C("button",{class:"ls-card",type:"button",onClick:h},[j(E8,{size:40,class:"ls-card-logo"}),C("div",AWe,[C("div",MWe,[qe(N(p(n)("onboarding.login.kimiTitle"))+" ",1),C("span",TWe,N(p(n)("onboarding.login.recommended")),1)]),C("div",EWe,N(p(n)("onboarding.login.kimiHint")),1)]),j(p(Te),{name:"chevron-right",size:"lg",class:"ls-card-chevron"})]),C("button",{class:"ls-card",type:"button",onClick:b[0]||(b[0]=_=>s("addProvider"))},[C("span",IWe,[j(p(Te),{name:"bolt",size:"lg"})]),C("div",LWe,[C("div",$We,N(p(n)("onboarding.login.customProviderTitle")),1),C("div",NWe,N(p(n)("onboarding.login.customProviderHint")),1)]),j(p(Te),{name:"chevron-right",size:"lg",class:"ls-card-chevron"})])])):(y(),M("div",FWe,[p(r)==="starting"?(y(),M("div",RWe,[j(p(Ao),{size:"md"}),C("span",OWe,N(p(n)("login.starting")),1)])):p(r)==="device-code"&&p(a)?(y(),M("div",PWe,[C("div",DWe,N(p(n)("login.lead")),1),C("a",{class:"ls-primary",href:p(a).verificationUriComplete,target:"_blank",rel:"noopener noreferrer"},[qe(N(p(n)("login.authorizeInBrowser"))+" ",1),j(p(Te),{name:"external-link",size:"sm"})],8,BWe),C("div",HWe,[C("span",{class:"ls-link",title:p(a).verificationUriComplete},N(p(a).verificationUriComplete),9,zWe),j(p(Rt),{class:Re(["ls-copy",{"is-copied":f.value}]),variant:"secondary",size:"sm",onClick:v},{default:me(()=>[f.value?(y(),M(Pe,{key:0},[j(p(Te),{name:"check",size:"sm"}),qe(" "+N(p(n)("login.copied")),1)],64)):(y(),M(Pe,{key:1},[j(p(Te),{name:"copy",size:"sm"}),qe(" "+N(p(n)("login.copyLink")),1)],64))]),_:1},8,["class"])]),C("div",WWe,[j(p(Ao),{size:"sm",label:p(n)("login.waitingAuth")},null,8,["label"]),C("span",UWe,N(p(n)("login.waitingAutoClose")),1),C("span",jWe,N(k(p(u))),1)])])):p(r)==="success"?(y(),M("div",VWe,[j(p(Dd),{kind:"success"}),C("span",qWe,N(p(n)("login.success")),1),C("span",KWe,N(p(n)("login.successHint")),1)])):p(r)==="expired"?(y(),M(Pe,{key:3},[C("div",ZWe,[j(p(Dd),{kind:"expired"}),C("span",GWe,N(p(n)("login.expiredTitle")),1),C("span",YWe,N(p(n)("login.expiredHint")),1)]),C("div",XWe,[j(p(Rt),{variant:"secondary",onClick:m},{default:me(()=>[qe(N(p(n)("onboarding.back")),1)]),_:1}),j(p(Rt),{variant:"primary",onClick:p(c)},{default:me(()=>[qe(N(p(n)("login.retry")),1)]),_:1},8,["onClick"])])],64)):p(r)==="error"?(y(),M(Pe,{key:4},[C("div",JWe,[j(p(Dd),{kind:"error"}),C("span",QWe,N(p(l)?p(n)("login.pollErrorTitle"):p(n)("login.errorTitle")),1),C("span",eUe,N(p(l)?p(n)("login.pollErrorHint"):p(n)("login.errorHint")),1)]),C("div",tUe,[j(p(Rt),{variant:"secondary",onClick:m},{default:me(()=>[qe(N(p(n)("onboarding.back")),1)]),_:1}),j(p(Rt),{variant:"primary",onClick:p(c)},{default:me(()=>[qe(N(p(n)("login.retry")),1)]),_:1},8,["onClick"])])],64)):ee("",!0)]))}}),oUe=ft(nUe,[["__scopeId","data-v-0a67ec7e"]]),sUe=["aria-label"],iUe={class:"wiz-body"},rUe={key:0,class:"wiz-step"},lUe={class:"wiz-title"},aUe={class:"wiz-sub"},uUe={class:"pref-group"},cUe={class:"pref-label"},dUe={class:"lang-cards"},fUe=["onClick"],pUe={class:"opt-label"},hUe={class:"pref-group"},mUe={class:"pref-label"},gUe={class:"theme-cards"},vUe=["onClick"],yUe={class:"opt-label"},kUe={key:1,class:"wiz-step"},bUe={class:"wiz-title"},CUe={class:"wiz-sub"},wUe={class:"wiz-step-fill"},_Ue={class:"wiz-foot"},xUe={class:"wiz-foot-ghost"},SUe=et({__name:"OnboardingWizard",props:{authReady:{type:Boolean},onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function}},emits:["complete","loginSuccess","addProvider"],setup(e,{emit:t}){const{t:n,locale:o}=Nt(),s=e,i=t;function r(){i("addProvider")}const l=["preferences","login"],a=Z(0),u=R(()=>l[a.value]??"preferences");function c(){a.value<l.length-1&&a.value++}function d(){a.value>0&&a.value--}function f(w){o.value!==w&&E5(w)}const{colorScheme:h,setColorScheme:m}=XT(),v=[{value:"system",labelKey:"theme.system"},{value:"light",labelKey:"theme.light"},{value:"dark",labelKey:"theme.dark"}];function k(){i("loginSuccess")}return(w,b)=>(y(),M("div",{class:"wizard",role:"dialog","aria-modal":"true","aria-label":p(n)("onboarding.welcome.title")},[C("div",iUe,[u.value==="preferences"?(y(),M("section",rUe,[j(E8,{size:72}),C("h1",lUe,N(p(n)("onboarding.welcome.title")),1),C("p",aUe,N(p(n)("onboarding.welcome.subtitle")),1),C("div",uUe,[C("div",cUe,N(p(n)("onboarding.welcome.languageLabel")),1),C("div",dUe,[(y(!0),M(Pe,null,pt(p(yg),_=>(y(),M("button",{key:_.code,class:Re(["opt-card lang-card",{selected:p(o)===_.code}]),type:"button",onClick:g=>f(_.code)},[C("span",{class:Re(["opt-radio",{on:p(o)===_.code}])},null,2),C("span",pUe,N(_.label),1)],10,fUe))),128))])]),C("div",hUe,[C("div",mUe,N(p(n)("onboarding.welcome.themeLabel")),1),C("div",gUe,[(y(),M(Pe,null,pt(v,_=>C("button",{key:_.value,class:Re(["opt-card theme-card",{selected:p(h)===_.value}]),type:"button",onClick:g=>p(m)(_.value)},[C("span",{class:Re(["tp",`tp-${_.value}`]),"aria-hidden":"true"},[_.value==="system"?(y(),M(Pe,{key:0},[b[2]||(b[2]=iu('<span class="tp-half tp-half-light" data-v-a665ca6b><span class="tp-side" data-v-a665ca6b></span><span class="tp-lines" data-v-a665ca6b><span data-v-a665ca6b></span><span data-v-a665ca6b></span><span data-v-a665ca6b></span></span></span><span class="tp-half tp-half-dark" data-v-a665ca6b><span class="tp-side" data-v-a665ca6b></span><span class="tp-lines" data-v-a665ca6b><span data-v-a665ca6b></span><span data-v-a665ca6b></span><span data-v-a665ca6b></span></span></span>',2))],64)):(y(),M(Pe,{key:1},[b[3]||(b[3]=C("span",{class:"tp-side"},null,-1)),b[4]||(b[4]=C("span",{class:"tp-lines"},[C("span"),C("span"),C("span")],-1))],64))],2),C("span",yUe,N(p(n)(_.labelKey)),1)],10,vUe)),64))])])])):(y(),M("section",kUe,[j(E8,{size:72}),C("h1",bUe,N(p(n)("onboarding.login.title")),1),C("p",CUe,N(p(n)("onboarding.login.subtitle")),1),C("div",wUe,[j(oUe,{"auth-ready":s.authReady,"on-start-o-auth-login":s.onStartOAuthLogin,"on-poll-o-auth-login":s.onPollOAuthLogin,"on-cancel-o-auth-login":s.onCancelOAuthLogin,onSuccess:k,onAddProvider:r},null,8,["auth-ready","on-start-o-auth-login","on-poll-o-auth-login","on-cancel-o-auth-login"])])])),C("div",_Ue,[u.value==="preferences"?(y(),he(p(Rt),{key:0,variant:"primary",size:"lg",class:"wiz-primary",onClick:c},{default:me(()=>[qe(N(p(n)("onboarding.continue")),1)]),_:1})):u.value==="login"&&s.authReady?(y(),he(p(Rt),{key:1,variant:"primary",size:"lg",class:"wiz-primary",onClick:b[0]||(b[0]=_=>i("complete"))},{default:me(()=>[qe(N(p(n)("onboarding.login.finish")),1)]),_:1})):ee("",!0),C("div",xUe,[a.value>0?(y(),he(p(Rt),{key:0,variant:"ghost",onClick:d},{default:me(()=>[qe(N(p(n)("onboarding.back")),1)]),_:1})):ee("",!0),u.value==="login"&&s.authReady?ee("",!0):(y(),he(p(Rt),{key:1,variant:"ghost",onClick:b[1]||(b[1]=_=>i("complete"))},{default:me(()=>[qe(N(u.value==="login"?p(n)("onboarding.login.skip"):p(n)("onboarding.skip")),1)]),_:1}))])])])],8,sUe))}}),AUe=ft(SUe,[["__scopeId","data-v-a665ca6b"]]),MUe=["aria-label"],TUe={class:"gload-box"},EUe={class:"gload-text"},IUe=et({__name:"GlobalLoading",setup(e){const{t}=Nt();return(n,o)=>(y(),M("div",{class:"gload",role:"status","aria-label":p(t)("app.connecting")},[C("div",TUe,[o[0]||(o[0]=iu('<svg class="gload-logo" viewBox="0 0 96 32" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-v-ab85ede1><path fill="currentColor" d="M35.767 31.329c0 .37.3.671.67.671h4.305c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.672-.671h-4.304c-.37 0-.671.3-.671.671z" data-v-ab85ede1></path><path fill="currentColor" d="M90.353 31.329c0 .37.3.671.67.671h4.305c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.672-.671h-4.304a.67.67 0 0 0-.671.671z" data-v-ab85ede1></path><path fill="currentColor" d="M73.256 0a.67.67 0 0 0-.652.512l-6.366 26.1c-.106.428-.607.428-.71 0L59.159.512A.67.67 0 0 0 58.511 0H47.725c-.37 0-.668.3-.668.671V31.33c0 .37.3.671.67.671h4.781c.37 0 .671-.292.671-.662V5.554c0-.515.604-.622.726-.127l6.358 26.06a.67.67 0 0 0 .653.513h9.931c.31 0 .58-.212.653-.512L77.855 5.43c.122-.495.726-.388.726.127v25.772c0 .37.3.671.671.671h4.78c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.671-.671z" data-v-ab85ede1></path><path fill="currentColor" d="M15.279 14.837 28.264 1.133A.671.671 0 0 0 27.777 0h-6.043a.67.67 0 0 0-.477.199L6.374 15.223c-.231.234-.573.025-.573-.35V.672c0-.37-.3-.671-.671-.671H.67a.67.67 0 0 0-.67.67V31.33c0 .37.3.671.671.671H5.13c.37 0 .671-.3.671-.671v-6.114a.5.5 0 0 1 .13-.35l4.594-4.69a.293.293 0 0 1 .386-.045l12.286 9.305c1.796 1.245 4.083 2.06 6.178 2.401a.645.645 0 0 0 .743-.648v-5.537a.7.7 0 0 0-.562-.677c-1.215-.262-2.565-.758-3.59-1.468L15.332 15.58c-.22-.152-.248-.544-.052-.744" data-v-ab85ede1></path></svg>',1)),j(p(Ao),{size:"md",label:p(t)("app.connecting")},null,8,["label"]),C("div",EUe,N(p(t)("app.connecting")),1)])],8,MUe))}}),LUe=ft(IUe,[["__scopeId","data-v-ab85ede1"]]),$Ue={class:"kap-root"},NUe={class:"kap-head"},FUe={class:"kap-count"},RUe={class:"kap-head-actions"},OUe={class:"kap-filters"},PUe=["value"],DUe={class:"kap-check"},BUe={class:"kap-check"},HUe={class:"kap-view-toggle",role:"group"},zUe={key:0,class:"kap-empty"},WUe=["onClick"],UUe={class:"kap-ts"},jUe={class:"kap-label"},VUe={key:0,class:"kap-detail"},qUe={class:"kap-detail-actions"},KUe=["onClick"],ZUe={key:1,class:"kap-agg"},GUe={class:"mono"},YUe={class:"mono"},XUe={class:"num"},JUe={class:"num"},QUe={key:0},eje={class:"mono"},tje={class:"num"},nje={class:"num"},oje={key:0},sje=et({__name:"KapDebugView",emits:["close"],setup(e,{emit:t}){const n=t,o=Z("all"),s=Z(""),i=Z(""),r=Z(!1),l=Z("timeline"),a=R(()=>(I5.value,[...M0e()])),u=R(()=>{const E=new Set;for(const P of a.value)P.sessionId&&E.add(P.sessionId);return[...E].sort()});function c(E){return E.kind==="rest:error"||E.code!==void 0&&E.code!==0||E.eventType==="error"||E.eventType==="parse-error"}const d=R(()=>{const E=s.value.trim().toLowerCase();return a.value.filter(P=>!(o.value!=="all"&&P.source!==o.value||i.value&&P.sessionId!==i.value||r.value&&!c(P)||E&&!`${P.label} ${P.kind} ${P.eventType??""} ${P.sessionId??""} ${P.requestId??""}`.toLowerCase().includes(E)))}),f=R(()=>{const E=new Map;for(const P of d.value){if(P.kind!=="ws:in"&&P.kind!=="ws:out")continue;const D=P.kind==="ws:in"?"←":"→",I=`${D} ${P.eventType??"?"} @ ${P.sessionId??"-"}`,$=E.get(I)??{key:I,sessionId:P.sessionId??"-",eventType:P.eventType??"?",dir:D,count:0};$.count++,P.seq!==void 0&&($.lastSeq=P.seq),E.set(I,$)}return[...E.values()].sort((P,D)=>D.count-P.count)}),h=R(()=>{const E=new Map;for(const P of d.value){if(P.source!=="rest"||P.kind==="rest:request")continue;const D=`${P.method??"?"} ${P.path??"?"}`,I=E.get(D)??{count:0,errors:0,totalMs:0,timed:0};I.count++,c(P)&&I.errors++,P.durationMs!==void 0&&(I.totalMs+=P.durationMs,I.timed++),E.set(D,I)}return[...E.entries()].map(([P,D])=>({key:P,count:D.count,errors:D.errors,avgMs:D.timed>0?Math.round(D.totalMs/D.timed):0})).sort((P,D)=>D.count-P.count)}),m=Z(null),v=Z(!0),k=Z(null),w=Z(null);Je(()=>d.value.length,async()=>{if(!v.value||l.value!=="timeline")return;await yt();const E=k.value;E&&(E.scrollTop=E.scrollHeight)});function b(E){m.value=m.value===E?null:E}function _(E){const P=new Date(E),D=(I,$=2)=>String(I).padStart($,"0");return`${D(P.getHours())}:${D(P.getMinutes())}:${D(P.getSeconds())}.${D(P.getMilliseconds(),3)}`}function g(E){return JSON.stringify(E,null,2)}async function x(E){await Zs(g(E))&&(w.value=E.id,setTimeout(()=>{w.value===E.id&&(w.value=null)},1500))}function S(){G$(d.value)}function T(E){return c(E)||E.source==="client"?"b-err":E.source==="rest"?"b-rest":E.kind==="ws:lifecycle"?"b-life":E.kind==="ws:out"?"b-out":"b-in"}function A(E){return E.source==="rest"?"REST":E.source==="client"?"APP":"WS"}return(E,P)=>(y(),M("section",$Ue,[C("header",NUe,[P[11]||(P[11]=C("strong",null,"KAP debug",-1)),C("span",FUe,N(d.value.length)+"/"+N(a.value.length),1),C("div",RUe,[C("button",{type:"button",class:Re({on:p(Ef)}),onClick:P[0]||(P[0]=D=>Ef.value=!p(Ef))},N(p(Ef)?"resume":"pause"),3),C("button",{type:"button",onClick:P[1]||(P[1]=D=>p(T0e)())},"clear"),C("button",{type:"button",onClick:P[2]||(P[2]=D=>S())},"export jsonl"),j(p(pn),{text:"Close window"},{default:me(()=>[C("button",{type:"button",onClick:P[3]||(P[3]=D=>n("close"))},"✕")]),_:1})])]),C("div",OUe,[Bn(C("select",{"onUpdate:modelValue":P[4]||(P[4]=D=>o.value=D),"aria-label":"Source filter"},[...P[12]||(P[12]=[C("option",{value:"all"},"rest + ws + app",-1),C("option",{value:"rest"},"rest",-1),C("option",{value:"ws"},"ws",-1),C("option",{value:"client"},"app errors",-1)])],512),[[V4,o.value]]),Bn(C("select",{"onUpdate:modelValue":P[5]||(P[5]=D=>i.value=D),"aria-label":"Session filter"},[P[13]||(P[13]=C("option",{value:""},"all sessions",-1)),(y(!0),M(Pe,null,pt(u.value,D=>(y(),M("option",{key:D,value:D},N(D),9,PUe))),128))],512),[[V4,i.value]]),Bn(C("input",{"onUpdate:modelValue":P[6]||(P[6]=D=>s.value=D),type:"text",placeholder:"filter (type / path / id)","aria-label":"Text filter"},null,512),[[ai,s.value]]),C("label",DUe,[Bn(C("input",{"onUpdate:modelValue":P[7]||(P[7]=D=>r.value=D),type:"checkbox"},null,512),[[Em,r.value]]),P[14]||(P[14]=qe(" errors",-1))]),C("label",BUe,[Bn(C("input",{"onUpdate:modelValue":P[8]||(P[8]=D=>v.value=D),type:"checkbox"},null,512),[[Em,v.value]]),P[15]||(P[15]=qe(" follow",-1))]),C("div",HUe,[C("button",{type:"button",class:Re({on:l.value==="timeline"}),onClick:P[9]||(P[9]=D=>l.value="timeline")},"timeline",2),C("button",{type:"button",class:Re({on:l.value==="aggregate"}),onClick:P[10]||(P[10]=D=>l.value="aggregate")},"aggregate",2)])]),l.value==="timeline"?(y(),M("div",{key:0,ref_key:"listRef",ref:k,class:"kap-list"},[d.value.length===0?(y(),M("div",zUe," No trace entries yet. REST calls and WS frames will appear here. ")):ee("",!0),(y(!0),M(Pe,null,pt(d.value,D=>(y(),M("div",{key:D.id,class:"kap-row-wrap"},[C("button",{type:"button",class:Re(["kap-row",{expanded:m.value===D.id}]),onClick:I=>b(D.id)},[C("span",UUe,N(_(D.ts)),1),C("span",{class:Re(["kap-badge",T(D)])},N(A(D)),3),C("span",jUe,N(D.label),1)],10,WUe),m.value===D.id?(y(),M("div",VUe,[C("div",qUe,[C("button",{type:"button",onClick:I=>x(D)},N(w.value===D.id?"copied ✓":"copy json"),9,KUe)]),C("pre",null,N(g(D)),1)])):ee("",!0)]))),128))],512)):(y(),M("div",ZUe,[P[20]||(P[20]=C("h4",null,"WS frames by session / type",-1)),C("table",null,[P[17]||(P[17]=C("thead",null,[C("tr",null,[C("th",null,"dir"),C("th",null,"type"),C("th",null,"session"),C("th",null,"count"),C("th",null,"last seq")])],-1)),C("tbody",null,[(y(!0),M(Pe,null,pt(f.value,D=>(y(),M("tr",{key:D.key},[C("td",null,N(D.dir),1),C("td",GUe,N(D.eventType),1),C("td",YUe,N(D.sessionId),1),C("td",XUe,N(D.count),1),C("td",JUe,N(D.lastSeq??"—"),1)]))),128)),f.value.length===0?(y(),M("tr",QUe,[...P[16]||(P[16]=[C("td",{colspan:"5",class:"kap-empty"},"no ws frames",-1)])])):ee("",!0)])]),P[21]||(P[21]=C("h4",null,"REST by endpoint",-1)),C("table",null,[P[19]||(P[19]=C("thead",null,[C("tr",null,[C("th",null,"endpoint"),C("th",null,"count"),C("th",null,"errors"),C("th",null,"avg ms")])],-1)),C("tbody",null,[(y(!0),M(Pe,null,pt(h.value,D=>(y(),M("tr",{key:D.key},[C("td",eje,N(D.key),1),C("td",tje,N(D.count),1),C("td",{class:Re(["num",{err:D.errors>0}])},N(D.errors),3),C("td",nje,N(D.avgMs),1)]))),128)),h.value.length===0?(y(),M("tr",oje,[...P[18]||(P[18]=[C("td",{colspan:"4",class:"kap-empty"},"no rest calls",-1)])])):ee("",!0)])])]))]))}}),ije=ft(sje,[["__scopeId","data-v-2b13888e"]]),rje=et({__name:"DebugPanel",setup(e){const t=Z(!1);let n=null,o=null,s=null;const i=["data-color-scheme"];function r(c){const d=document.documentElement,f=c.documentElement;for(const h of i){const m=d.getAttribute(h);m!==null?f.setAttribute(h,m):f.removeAttribute(h)}}function l(c){const d=c.document;d.title="KAP debug";const f=d.createElement("base");f.href=location.href,d.head.appendChild(f);for(const m of Array.from(document.querySelectorAll('style, link[rel="stylesheet"]')))d.head.appendChild(m.cloneNode(!0));r(d),d.body.style.margin="0";const h=d.createElement("div");return h.style.height="100vh",d.body.appendChild(h),h}function a(){s?.disconnect(),s=null;try{o?.unmount()}catch{}o=null,n=null,t.value=!1}function u(){if(n&&!n.closed){n.focus();return}const c=window.open("","kap-debug","popup=yes,width=1040,height=760");if(!c)return;n=c;const d=l(c),f=Im(ije,{onClose:()=>c.close()});f.mount(d),o=f,t.value=!0,s=new MutationObserver(()=>{n&&!n.closed&&r(n.document)}),s.observe(document.documentElement,{attributes:!0,attributeFilter:[...i]}),c.addEventListener("pagehide",a),c.addEventListener("beforeunload",a)}return dn(()=>{u()}),Vn(()=>{n&&!n.closed&&n.close(),a()}),(c,d)=>(y(),he(p(pn),{text:t.value?"Focus KAP debug window":"Open KAP debug window"},{default:me(()=>[C("button",{class:"kap-fab",type:"button",onClick:u}," KAP ")]),_:1},8,["text"]))}}),lje=ft(rje,[["__scopeId","data-v-21de79fc"]]),aje=et({__name:"ServerAuthDialog",setup(e){const t=Z(""),n=Z(null),o=Z(!1);dn(()=>{yt(()=>n.value?.focus())});function s(){const r=t.value;!r||o.value||(o.value=!0,vE(r),window.location.reload())}function i(r){r.key==="Enter"&&(r.preventDefault(),s())}return(r,l)=>(y(),he(p(ua),{open:!0,title:"Server token required","hide-close":!0,"close-on-overlay":!1,"close-on-esc":!1},{foot:me(()=>[j(p(Rt),{variant:"primary",disabled:!t.value||o.value,loading:o.value,onClick:s},{default:me(()=>[qe(N(o.value?"Connecting…":"Connect"),1)]),_:1},8,["disabled","loading"])]),default:me(()=>[l[1]||(l[1]=C("p",{class:"server-auth-hint"},[qe(" This server is protected. Enter the bearer token printed when the server started (or the password set via "),C("code",null,"KIMI_CODE_PASSWORD"),qe("). ")],-1)),j(p(js),{ref_key:"inputRef",ref:n,modelValue:t.value,"onUpdate:modelValue":l[0]||(l[0]=a=>t.value=a),type:"password",autocomplete:"current-password",placeholder:"Token",disabled:o.value,onKeydown:i},null,8,["modelValue","disabled"])]),_:1}))}}),uje=ft(aje,[["__scopeId","data-v-331563ff"]]),cje=["aria-label"],dje=et({__name:"InternalBuildBanner",setup(e){const{t}=Nt(),n=Wp;return(o,s)=>p(n)?(y(),M("span",{key:0,class:"internal-build-tag",role:"note","aria-label":p(t)("app.internalBuildBanner")},[s[0]||(s[0]=C("svg",{viewBox:"0 0 16 16",width:"11",height:"11",fill:"none",stroke:"currentColor","stroke-width":"1.7","stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},[C("path",{d:"M8 2 14 13H2L8 2Z"}),C("path",{d:"M8 6v3.5"}),C("path",{d:"M8 11.5h.01"})],-1)),C("span",null,N(p(t)("app.internalBuildBanner")),1)],8,cje)):ee("",!0)}}),fje=ft(dje,[["__scopeId","data-v-14c3d0e0"]]),pje={class:"app-shell"},hje=["inert"],mje=["aria-label","aria-hidden"],gje=et({__name:"App",setup(e){QJ();const t=Z(!1);let n=null;const o=mu(),s=R(()=>!o.dangerousBypassAuth.value&&t.value);Ln("resolveImage",o.resolveImageUrl),Ln("resolveSwarmMembers",ht=>o.swarmMembersByToolCallId.value.get(ht)??[]),Ln("modelDisplay",ht=>fJ(ht,o.models.value));const{t:i}=Nt();Ln("subagentEffort",ht=>pJ(ht));const{confirm:r}=hu(),l=Qr(),a=khe(),u=Z(!1),c=Z(!1),d=R(()=>{const ht=o.activeSessionId.value;return o.sessions.value.find(Le=>Le.id===ht)?.title??""}),f=R(()=>{const ht=o.activeSessionId.value;return o.sessions.value.find(Le=>Le.id===ht)?.lastTurnReason??null}),h=R(()=>o.visibleWorkspace.value?.sessionCount??0),m=R(()=>o.activity.value!=="idle");jhe({running:m,title:"Kimi Code Web"});function v(ht){const Le=o.models.value.find(di=>di.id===o.status.value.modelId),Ze=Up(Le),Xt=Ze.indexOf(Dm(Le,ht)),gs=Ze[(Xt+1)%Ze.length]??Ze[0]??"off";return My(Le,gs)}const k=R(()=>{const ht=o.models.value.find(Le=>Le.id===o.status.value.modelId);return Dm(ht,o.thinking.value)}),w=Z(!o.onboarded.value);function b(){o.setOnboarded(!0),w.value=!1}function _(){b(),st.value="providers",hs.value=!0}let g=0;function x(){const ht=window.visualViewport,Le=document.documentElement.style;Le.setProperty("--app-height",`${ht?.height??window.innerHeight}px`),Le.setProperty("--app-top",`${ht?.offsetTop??0}px`)}function S(){g||(g=requestAnimationFrame(()=>{g=0,x()}))}dn(()=>{n=oQ(()=>{t.value=!0,o.clearDangerousBypassAuth()}),o.load(),oe(),x(),window.visualViewport?.addEventListener("resize",S),window.visualViewport?.addEventListener("scroll",S),window.addEventListener("resize",S),document.addEventListener("keydown",T,!0)}),bn(()=>{document.removeEventListener("keydown",T,!0),window.visualViewport?.removeEventListener("resize",S),window.visualViewport?.removeEventListener("scroll",S),window.removeEventListener("resize",S),g&&(cancelAnimationFrame(g),g=0),document.documentElement.style.removeProperty("--app-height"),document.documentElement.style.removeProperty("--app-top"),n!==null&&(n(),n=null)});function T(ht){ht.key==="Escape"&&(Nn.value||qt()&&(ht.stopPropagation(),ht.preventDefault()))}const A=Z(null),{previewTarget:E,previewFile:P,previewLoading:D,previewError:I,previewDownloadUrl:$,previewExternalActions:B,openFilePreview:H,closeFilePreview:O,openPreviewInEditor:F,revealPreviewFile:U}=Uhe({client:o,detailTarget:A,t:(ht,Le)=>Le===void 0?i(ht):i(ht,Le)}),z=R(()=>A.value!==null),W=Z(null),K=Z(null);function V(ht){K.value=ht.originImg??null,W.value=ht.media}const{SIDEBAR_WIDTH_KEY:ie,SIDEBAR_DEFAULT:ne,SIDEBAR_MIN:X,sidebarMax:le,sessionColWidth:Ie,sidebarCollapsed:de,sidebarDragging:pe,sideWidth:ve,loadSidebarCollapsed:oe,toggleSidebarCollapse:ye}=zhe({previewOpen:z}),{PREVIEW_WIDTH_KEY:G,PREVIEW_MIN:Y,previewDefaultWidth:fe,previewMax:we,previewWidth:ge,previewPanelWidth:Q,compactionPanelText:te,compactionPanelVisible:ce,openCompactionPanel:ue,closeCompactionPanel:Se,agentPanelMember:ze,agentPanelTurns:_e,agentPanelLoading:Ee,agentPanelLoadError:it,agentPanelLoadingMore:Fe,agentPanelLoadMoreError:Oe,agentPanelHasMore:Ge,agentPanelRunning:at,openAgentPanel:Tt,closeAgentPanel:Bt,loadOlderAgentMessages:Yt,detailDiffMode:Sn,detailDiffPath:on,openDiffDetail:en,closeDiffDetail:Cn,selectDiffFile:Mn,turnDiffChange:We,openTurnDiff:tt,closeTurnDiff:Ue,btwVisible:Lt,openSideChatTab:gt,closeSideChat:wn,sidePanelVisible:yn,panelDragging:go,closeOpenSidePanel:qt}=Phe({client:o,sideWidth:ve,detailTarget:A,closeFilePreview:O}),ps=Z(null);function xs(ht){ps.value?.style.setProperty("--preview-w",`${ht}px`)}Je([ps,Q],([ht,Le])=>ht?.style.setProperty("--preview-w",`${Le}px`),{immediate:!0});const _n=Z(null),In=Z(!1),To=Z(!1),lo=Z(!1),St=Z(!1),hs=Z(!1);let Jo;dn(()=>{Jo=window.kimiDesktop?.onMenuAction?.(ht=>{ht==="open-settings"?hs.value=!0:ht==="new-chat"&&Fs()})}),bn(()=>{Jo?.()});const uo=Z(null),Ys=Z(null),Nn=R(()=>Ci.value>0||In.value||To.value||lo.value||St.value||hs.value||w.value||u.value||c.value),no=Z(!1),$s=Z(!1),Xs=Z(!1);async function ci(){no.value=!0,$s.value=!1,In.value=!0;try{await o.refreshAllProviders()}catch{$s.value=!0}finally{no.value=!1}}function Oo(){To.value=!0}async function vo(){await r({title:i("sidebar.logoutConfirmTitle"),message:i("sidebar.logoutConfirmMessage"),variant:"danger",action:()=>o.logout()})}async function Po(ht){In.value=!1,await co(ht)}async function co(ht){await o.setModel(ht)&&ht!==o.defaultModel.value&&o.updateConfig({defaultModel:ht})}const Tn=Z(null);async function fo(ht){await o.archiveSession(ht),!o.sessionsForView.value.some(Le=>Le.id===ht)&&(Tn.value={id:ht})}async function Qe(){const ht=Tn.value;ht&&await o.restoreSession(ht.id)&&(Tn.value=null)}const st=Z(void 0),Ct=Z(void 0);Je(c,ht=>{ht||(Ct.value=void 0)});function Qt(){Tn.value=null,a.value?(Ct.value="archived",c.value=!0):(st.value="archived",hs.value=!0)}async function kn(ht){const Le=o.workspacesView.value.find(Ze=>Ze.id===ht)?.name??ht;await r({title:i("sidebar.removeWorkspace"),message:i("workspace.removeWorkspaceConfirm",{name:Le}),variant:"danger",action:()=>o.deleteWorkspace(ht)})}async function Ko(ht){Xs.value=!0;try{await o.updateConfig(ht)&&await o.checkAuth()}finally{Xs.value=!1}}async function Eo(){return o.startOAuthLogin()}async function bo(){return o.pollOAuthLogin()}async function Ns(){return o.cancelOAuthLogin()}async function Do(){To.value=!1,await o.checkAuth(),await o.load()}async function Io(){b(),await o.checkAuth(),await o.load()}async function Qo(ht){await o.undo(1)!==null&&(await yt(),_n.value?.loadComposerForEdit(ht.text,ht.attachments),_n.value?.notifyUndone())}async function sn(){const ht=await o.abortCurrentPrompt();_n.value?.onAbortOutcome(ht)}function es(ht){const Le=_t();return ht.map(Ze=>({kind:Ze.kind,url:Le.getFileUrl(Ze.fileId),fileId:Ze.fileId,name:Ze.name}))}async function ms(ht,Le){if(o.authReady.value)return!0;const Ze=o.managedProviderStatus.value==="authenticated";Ze&&o.managedMembership.value===null&&await o.probeManagedMembership();const Xt=Ze&&o.managedMembership.value==="free",gs=await r(Xt?{title:i("login.upgradeRequiredTitle"),message:i("login.upgradeRequiredMessage"),confirmLabel:i("sidebar.upgrade"),variant:"primary"}:{title:i("login.requiredTitle"),message:i("login.requiredMessage"),confirmLabel:i("login.goToLogin"),variant:"primary"});return _n.value?.loadComposerForEdit(ht,es(Le)),gs&&(Xt?jp():Oo()),!1}async function Tr(ht,Le=[]){if(o.activeSessionId.value||o.activeWorkspaceId.value)return!0;const Ze=await r({title:i("workspace.requiredTitle"),message:i("workspace.requiredMessage"),confirmLabel:i("conversation.pickFolder"),variant:"primary"});return _n.value?.loadComposerForEdit(ht,es(Le)),Ze&&(lo.value=!0),!1}async function ts(ht,Le=[]){return await ms(ht,Le)?Tr(ht,Le):!1}async function Ki(ht){const{cmd:Le,attachments:Ze}=ht;if(Le==="/compact"||Le.startsWith("/compact ")){if(!await ts(Le))return;o.compact(Le.slice(8).trim()||void 0);return}if(Le==="/swarm"||Le.startsWith("/swarm ")){const Xt=Le.slice(6).trim();if(Xt==="on")o.setSwarmMode(!0);else if(Xt==="off")o.setSwarmMode(!1);else if(Xt){if(!await ts(Le))return;o.setSwarmMode(!0),o.sendPrompt(Xt)}else o.toggleSwarmMode();return}if(Le==="/goal"||Le.startsWith("/goal ")){const Xt=Le.slice(5).trim();if(Xt==="pause"||Xt==="resume"||Xt==="cancel")o.controlGoal(Xt);else if(Xt){if(!await ts(Le))return;o.createGoal(Xt)}else o.toggleGoalMode();return}if(Le==="/btw"||Le.startsWith("/btw ")){const Xt=Le.slice(4).trim();if(!Xt&&o.sideChatVisible.value)wn();else{if(Xt&&!await ts(Le))return;gt(Xt||void 0)}return}switch(Le){case"/new":case"/clear":Fs();break;case"/fork":o.forkSession();break;case"/export":o.exportSession();break;case"/undo":o.undo();break;case"/plan":o.togglePlanMode();break;case"/auto":o.setPermission("auto");break;case"/yolo":o.setPermission("yolo");break;case"/thinking":o.setThinking(v(o.thinking.value));break;case"/status":St.value=!0;break;case"/login":Oo();break;default:{const Xt=Le.indexOf(" "),gs=hQ((Xt===-1?Le:Le.slice(0,Xt)).slice(1)),di=Xt===-1?void 0:Le.slice(Xt+1).trim()||void 0;if(!gs)break;if(!await ts(Le,Ze))return;!o.activeSessionId.value&&o.activeWorkspaceId.value?o.startSessionAndActivateSkill(o.activeWorkspaceId.value,gs,di,Ze):o.activateSkill(gs,di,Ze);break}}}function Js(ht){o.unqueue(ht)}function Bo(ht){o.unqueue(ht)}function Zo(ht){o.reorderQueue(ht.from,ht.to)}async function Il(ht){if(!await ms(ht.text,ht.attachments))return;const Le=o.activeWorkspaceId.value;if(!o.activeSessionId.value&&Le){await o.startSessionAndSendPrompt(Le,ht.text,ht.attachments);return}if(!o.activeSessionId.value&&!Le){uo.value=ht,await r({title:i("workspace.requiredTitle"),message:i("workspace.requiredMessage"),confirmLabel:i("conversation.pickFolder"),variant:"primary"})?lo.value=!0:Zi();return}o.sendPrompt(ht.text,ht.attachments)}function Zi(){const ht=uo.value;uo.value=null,ht&&_n.value?.loadComposerForEdit(ht.text,es(ht.attachments))}async function tl(ht){if(Ys.value=null,!await o.addWorkspaceByPath(ht)){Ys.value=i("workspace.addFailed");return}lo.value=!1;const Ze=uo.value;uo.value=null;const Xt=o.activeWorkspaceId.value;Ze&&Xt&&await o.startSessionAndSendPrompt(Xt,Ze.text,Ze.attachments)}function Ho(){Zi(),Ys.value=null,lo.value=!1}function Co(){yt(()=>{_n.value?.focusComposer()})}function Fs(){const ht=o.activeWorkspaceId.value;ht?o.openWorkspaceDraft(ht):o.clearActiveSession(),Co()}function Rs(ht){o.openWorkspaceDraft(ht),Co()}function yo(ht){ht&&window.open(ht,"_blank","noopener")}return(ht,Le)=>(y(),M("div",pje,[s.value?(y(),he(uje,{key:0})):ee("",!0),C("div",{class:Re(["app",{mobile:p(a),"sidebar-collapsed":p(de)&&!p(a),"macos-desktop":p(rc)}]),inert:w.value},[p(a)?(y(),he(PHe,{key:1,workspace:p(o).visibleWorkspace.value,"session-title":d.value,running:m.value,branch:p(o).status.value.branch,"session-count":h.value,onOpenSwitcher:Le[22]||(Le[22]=Ze=>u.value=!0),onOpenSettings:Le[23]||(Le[23]=Ze=>c.value=!0)},null,8,["workspace","session-title","running","branch","session-count"])):(y(),M(Pe,{key:0},[j(r9e,{collapsed:p(de),dragging:p(pe),"col-width":p(ve),"active-workspace":p(o).visibleWorkspace.value,"active-workspace-id":p(o).activeWorkspaceId.value,sessions:p(o).sessionsForView.value,groups:p(o).workspaceGroups.value,"pinned-sessions":p(o).pinnedSessions.value,"flat-sessions":p(o).flatSessions.value,"flat-has-more":p(o).flatSessionsHasMore.value,"flat-loading-more":p(o).flatSessionsLoadingMore.value,initialized:p(o).initialized.value,"active-id":p(o).activeSessionId.value,"attention-by-session":p(o).attentionBySession.value,"pending-by-session":p(o).pendingBySession.value,"unread-by-session":p(o).unreadBySession.value,onSelect:Le[0]||(Le[0]=Ze=>p(o).selectSession(Ze)),onCreate:Fs,onCreateInWorkspace:Le[1]||(Le[1]=Ze=>Rs(Ze)),onSelectWorkspace:Le[2]||(Le[2]=Ze=>p(o).openWorkspace(Ze)),onAddWorkspace:Le[3]||(Le[3]=Ze=>lo.value=!0),onRename:Le[4]||(Le[4]=(Ze,Xt)=>p(o).renameSession(Ze,Xt)),onArchive:Le[5]||(Le[5]=Ze=>fo(Ze)),onFork:Le[6]||(Le[6]=Ze=>p(o).forkSession(Ze)),onExport:Le[7]||(Le[7]=Ze=>p(o).exportSession(Ze)),onPin:Le[8]||(Le[8]=Ze=>p(o).togglePinSession(Ze)),onUnpin:Le[9]||(Le[9]=Ze=>p(o).unpinSession(Ze)),onReorderPinned:Le[10]||(Le[10]=Ze=>p(o).reorderPinnedSessions(Ze)),onPinAt:Le[11]||(Le[11]=(Ze,Xt,gs)=>p(o).pinSessionAt(Ze,Xt,gs)),onRenameWorkspace:Le[12]||(Le[12]=(Ze,Xt)=>p(o).renameWorkspace(Ze,Xt)),onDeleteWorkspace:Le[13]||(Le[13]=Ze=>kn(Ze)),onReorderWorkspaces:Le[14]||(Le[14]=Ze=>p(o).reorderWorkspaces(Ze)),onLoadMoreSessions:Le[15]||(Le[15]=Ze=>void p(o).loadMoreSessions(Ze)),onLoadAllSessions:Le[16]||(Le[16]=Ze=>void p(o).loadAllSessions()),onEnsureFlatSessions:Le[17]||(Le[17]=Ze=>void p(o).ensureFlatSessions()),onLoadMoreFlatSessions:Le[18]||(Le[18]=Ze=>void p(o).loadMoreFlatSessions()),onOpenSettings:Le[19]||(Le[19]=Ze=>hs.value=!0),onLogin:Oo,onCollapse:p(ye)},null,8,["collapsed","dragging","col-width","active-workspace","active-workspace-id","sessions","groups","pinned-sessions","flat-sessions","flat-has-more","flat-loading-more","initialized","active-id","attention-by-session","pending-by-session","unread-by-session","onCollapse"]),Bn(j(Zx,{class:"side-handle","storage-key":p(ie),"default-width":p(ne),min:p(X),max:p(le),"onUpdate:width":Le[20]||(Le[20]=Ze=>Ie.value=Ze),"onUpdate:dragging":Le[21]||(Le[21]=Ze=>pe.value=Ze)},null,8,["storage-key","default-width","min","max"]),[[qs,!p(de)]])],64)),j(R$e,{ref_key:"conversationPaneRef",ref:_n,mobile:p(a),turns:p(o).turns.value,"session-id":p(o).activeSessionId.value,approvals:p(o).pendingApprovals.value,changes:p(o).changes.value,"git-info":p(o).gitInfo.value,tasks:p(o).tasks.value,todos:p(o).todos.value,goal:p(o).goal.value,"activation-badges":p(o).activationBadges.value,status:p(o).status.value,thinking:p(o).thinking.value,"plan-mode":p(o).planMode.value,"swarm-mode":p(o).swarmMode.value,"goal-mode":p(o).goalMode.value,models:p(o).models.value,"auth-ready":p(o).authReady.value,"managed-signed-in":p(o).managedProviderStatus.value==="authenticated","managed-membership":p(o).managedMembership.value,"starred-ids":p(o).starredModelIds.value,skills:p(o).skills.value,questions:p(o).questions.value,"pending-question-actions":p(o).pendingQuestionActions,"pending-approval-actions":p(o).pendingApprovalActions,running:m.value,"overlay-open":Nn.value,"turn-active":p(o).turnActive.value,queued:p(o).queued.value,"search-files":p(o).searchFiles,"upload-image":p(o).uploadImage,working:p(o).working.value,"last-turn-reason":f.value,"turn-error":p(o).activeTurnError.value??null,"turn-retry":p(o).activeTurnRetry.value??null,starting:p(o).isStartingFirstPrompt.value,"file-reload-key":p(o).activeSessionId.value,"session-loading":p(o).sessionLoading.value,compaction:p(o).compaction.value,"has-more-messages":p(o).hasMoreMessages.value,"loading-more":p(o).loadingMoreMessages.value,"loading-more-error":p(o).loadMoreMessagesError.value,"load-older-messages":p(o).loadOlderMessages,"workspace-name":p(o).visibleWorkspace.value?.name,"workspace-root":p(o).visibleWorkspace.value?.root??p(o).status.value.cwd,"git-diff-stats":p(o).gitDiffStats.value,workspaces:p(o).workspacesView.value,"active-workspace-id":p(o).activeWorkspaceId.value,"session-title":d.value,pr:p(o).activePullRequest.value,onOpenChanges:Le[24]||(Le[24]=Ze=>p(en)()),onSelectWorkspace:Le[25]||(Le[25]=Ze=>Rs(Ze)),onAddWorkspace:Le[26]||(Le[26]=Ze=>lo.value=!0),onOpenPr:yo,onSubmit:Le[27]||(Le[27]=Ze=>Il(Ze)),onLogin:Le[28]||(Le[28]=Ze=>Oo()),onSteer:Le[29]||(Le[29]=Ze=>p(o).steerPrompt(Ze.text,Ze.attachments)),onApproval:Le[30]||(Le[30]=(Ze,Xt)=>p(o).respondApproval(Ze,Xt)),onCancelTask:Le[31]||(Le[31]=Ze=>p(o).cancelTask(Ze)),onAnswer:Le[32]||(Le[32]=(Ze,Xt)=>p(o).respondQuestion(Ze,Xt)),onDismiss:Le[33]||(Le[33]=Ze=>p(o).dismissQuestion(Ze)),onCommand:Ki,onInterrupt:sn,onUnqueue:Js,onEditQueued:Bo,onReorderQueue:Zo,onSetPermission:Le[34]||(Le[34]=Ze=>p(o).setPermission(Ze)),onSetThinking:Le[35]||(Le[35]=Ze=>p(o).setThinking(Ze)),onTogglePlan:Le[36]||(Le[36]=Ze=>p(o).togglePlanMode()),onToggleSwarm:Le[37]||(Le[37]=Ze=>p(o).toggleSwarmMode()),onToggleGoal:Le[38]||(Le[38]=Ze=>p(o).toggleGoalMode()),onCreateGoal:Le[39]||(Le[39]=Ze=>p(o).createGoal(Ze)),onControlGoal:Le[40]||(Le[40]=Ze=>p(o).controlGoal(Ze)),onRefreshGitStatus:Le[41]||(Le[41]=Ze=>p(o).activeSessionId.value&&p(o).loadGitStatus(p(o).activeSessionId.value)),onRenameSession:Le[42]||(Le[42]=(Ze,Xt)=>p(o).renameSession(Ze,Xt)),onForkSession:Le[43]||(Le[43]=Ze=>p(o).forkSession(Ze)),onArchiveSession:Le[44]||(Le[44]=Ze=>fo(Ze)),onExportSession:Le[45]||(Le[45]=Ze=>p(o).exportSession(Ze)),onCompact:Le[46]||(Le[46]=Ze=>p(o).compact()),onPickModel:Le[47]||(Le[47]=Ze=>ci()),onSelectModel:Le[48]||(Le[48]=Ze=>co(Ze)),onOpenFile:Le[49]||(Le[49]=Ze=>p(H)(Ze)),onOpenMedia:V,onOpenTurnDiff:Le[50]||(Le[50]=Ze=>p(tt)(Ze)),onOpenCompaction:Le[51]||(Le[51]=Ze=>p(ue)(Ze)),onOpenAgent:Le[52]||(Le[52]=Ze=>p(Tt)(Ze)),onEditMessage:Qo},null,8,["mobile","turns","session-id","approvals","changes","git-info","tasks","todos","goal","activation-badges","status","thinking","plan-mode","swarm-mode","goal-mode","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","questions","pending-question-actions","pending-approval-actions","running","overlay-open","turn-active","queued","search-files","upload-image","working","last-turn-reason","turn-error","turn-retry","starting","file-reload-key","session-loading","compaction","has-more-messages","loading-more","loading-more-error","load-older-messages","workspace-name","workspace-root","git-diff-stats","workspaces","active-workspace-id","session-title","pr"]),!p(a)&&(p(rc)||p(de))?(y(),he(p(gn),{key:2,class:"sidebar-toggle-btn",size:"sm",label:p(de)?p(i)("sidebar.expandSidebar"):p(i)("sidebar.collapseSidebar"),tooltip:p(de)?p(i)("sidebar.expandSidebar"):p(i)("sidebar.collapseSidebar"),onClick:p(ye)},{default:me(()=>[j(p(Te),{name:p(de)?"panel-expand":"panel-collapse"},null,8,["name"])]),_:1},8,["label","tooltip","onClick"])):ee("",!0),!p(a)&&p(de)?(y(),he(p(gn),{key:3,class:"new-chat-btn",size:"sm",label:p(i)("sidebar.newChat"),tooltip:p(i)("sidebar.newChat"),onClick:Fs},{default:me(()=>[j(p(Te),{name:"chat-new"})]),_:1},8,["label","tooltip"])):ee("",!0),p(yn)&&!p(a)?(y(),he(Zx,{key:4,class:"preview-handle","storage-key":p(G),"default-width":p(fe),min:p(Y),max:p(we),reverse:"","aria-label":p(i)("layout.resizePreviewAria"),"apply-live":xs,"onUpdate:width":Le[53]||(Le[53]=Ze=>ge.value=Ze),"onUpdate:dragging":Le[54]||(Le[54]=Ze=>go.value=Ze)},null,8,["storage-key","default-width","min","max","aria-label"])):ee("",!0),!p(a)||p(yn)?(y(),M("aside",{key:5,ref_key:"previewPanelEl",ref:ps,class:Re(["global-preview",{open:p(yn),mobile:p(a)}]),role:"complementary","aria-label":p(i)("layout.detailPanelAria"),"aria-hidden":!p(yn)},[A.value==="compaction"&&p(ce)?(y(),he(kNe,{key:0,text:p(te)??"",subtitle:p(i)("conversation.summaryTitle"),onClose:p(Se)},null,8,["text","subtitle","onClose"])):A.value==="agent"&&p(ze)?(y(),he(xNe,{key:1,member:p(ze),turns:p(_e),running:p(at),loading:p(Ee),"load-error":p(it),"has-more":p(Ge),"loading-more":p(Fe),"load-more-error":p(Oe),onClose:p(Bt),onLoadOlderMessages:p(Yt),onOpenAgent:p(Tt),onOpenFile:p(H),onOpenMedia:V,onOpenTurnDiff:Le[55]||(Le[55]=Ze=>p(tt)(Ze))},null,8,["member","turns","running","loading","load-error","has-more","loading-more","load-more-error","onClose","onLoadOlderMessages","onOpenAgent","onOpenFile"])):A.value==="btw"&&p(Lt)?(y(),he($Ne,{key:2,turns:p(o).sideChatTurns.value,running:p(o).sideChatRunning.value,sending:p(o).sideChatSending.value,onSend:Le[56]||(Le[56]=Ze=>p(o).sendSideChatPrompt(Ze)),onClose:p(wn),onOpenMedia:V},null,8,["turns","running","sending","onClose"])):A.value==="diff"?(y(),he(rFe,{key:3,mode:p(Sn),changes:p(o).changes.value,"git-info":p(o).gitInfo.value,"file-diff":p(o).fileDiff.value,"full-texts":p(o).fileDiffTexts.value,"empty-file":p(o).fileDiffEmptyFile.value,"selected-diff-path":p(o).selectedDiffPath.value,"file-diff-loading":p(o).fileDiffLoading.value,closable:"",onOpen:p(Mn),onBack:Le[57]||(Le[57]=Ze=>{Sn.value="list",on.value=null,p(o).clearFileDiff()}),onClose:p(Cn)},null,8,["mode","changes","git-info","file-diff","full-texts","empty-file","selected-diff-path","file-diff-loading","onOpen","onClose"])):A.value==="file"?(y(),he(gNe,{key:4,file:p(P),loading:p(D),error:p(I),line:p(E)?.line,"download-url":p($),closable:"","external-actions":p(B),"open-file":p(H),onClose:p(O),onOpenExternal:p(F),onReveal:p(U)},null,8,["file","loading","error","line","download-url","external-actions","open-file","onClose","onOpenExternal","onReveal"])):A.value==="turn-diff"&&p(We)?(y(),he(fFe,{key:5,change:p(We),cwd:p(o).status.value.cwd,closable:"",onClose:p(Ue),onOpenFile:Le[58]||(Le[58]=Ze=>p(H)({path:Ze}))},null,8,["change","cwd","onClose"])):ee("",!0)],10,mje)):ee("",!0),j(fje,{class:"internal-build-fab"}),In.value?(y(),he(TFe,{key:6,models:p(o).models.value,current:p(o).status.value.modelId,"starred-ids":p(o).starredModelIds.value,loading:no.value,unavailable:$s.value,onSelect:Le[59]||(Le[59]=Ze=>Po(Ze)),onToggleStar:Le[60]||(Le[60]=Ze=>p(o).toggleStarModel(Ze)),onClose:Le[61]||(Le[61]=Ze=>In.value=!1)},null,8,["models","current","starred-ids","loading","unavailable"])):ee("",!0),hs.value?(y(),he(RBe,{key:7,"color-scheme":p(o).colorScheme.value,"font-scale":p(o).fontScale.value,"managed-provider-status":p(o).managedProviderStatus.value,"managed-user-info":p(o).managedUserInfo.value,"on-fetch-usage":p(o).getUsage,notify:p(o).notifyEnabled.value,"notify-permission":p(o).notifyPermission.value,"notify-sound":p(o).notifySound.value,config:p(o).config.value,models:p(o).models.value,"config-saving":Xs.value,"server-version":p(o).serverVersion.value,backend:p(o).backend.value,"experimental-flags":p(o).experimentalFlags.value,"initial-tab":st.value,onSetColorScheme:Le[62]||(Le[62]=Ze=>p(o).setColorScheme(Ze)),onSetFontScale:Le[63]||(Le[63]=Ze=>p(o).setFontScale(Ze)),onSetNotify:Le[64]||(Le[64]=Ze=>p(o).setNotifyEnabled(Ze)),onSetNotifySound:Le[65]||(Le[65]=Ze=>p(o).setNotifySound(Ze)),onUpdateConfig:Le[66]||(Le[66]=Ze=>Ko(Ze)),onLogin:Le[67]||(Le[67]=()=>{hs.value=!1,Oo()}),onLogout:vo,onClose:Le[68]||(Le[68]=Ze=>{hs.value=!1,st.value=void 0})},null,8,["color-scheme","font-scale","managed-provider-status","managed-user-info","on-fetch-usage","notify","notify-permission","notify-sound","config","models","config-saving","server-version","backend","experimental-flags","initial-tab"])):ee("",!0),St.value?(y(),he(wHe,{key:8,status:p(o).status.value,thinking:k.value,"plan-mode":p(o).planMode.value,"swarm-mode":p(o).swarmMode.value,"cost-usd":p(o).sessionCost.value,onClose:Le[69]||(Le[69]=Ze=>St.value=!1)},null,8,["status","thinking","plan-mode","swarm-mode","cost-usd"])):ee("",!0),lo.value?(y(),he(rHe,{key:9,"browse-fs":p(o).browseFs,"get-fs-home":p(o).getFsHome,"default-path":p(o).visibleWorkspace.value?.root??p(o).status.value.cwd,error:Ys.value,onAdd:Le[70]||(Le[70]=Ze=>tl(Ze)),onClose:Ho},null,8,["browse-fs","get-fs-home","default-path","error"])):ee("",!0),j(as,{name:"gload-fade"},{default:me(()=>[p(o).initialized.value?ee("",!0):(y(),he(LUe,{key:0,issue:p(o).connectIssue.value},null,8,["issue"]))]),_:1}),j(THe,{warnings:p(o).warnings.value,onDismiss:p(o).dismissWarning},null,8,["warnings","onDismiss"]),(y(),he(Zr,{to:"body"},[j(as,{name:"action-toast"},{default:me(()=>[Tn.value?(y(),he(p(Pz),{key:Tn.value.id,onDismiss:Le[71]||(Le[71]=Ze=>Tn.value=null)},{default:me(()=>[C("button",{type:"button",onClick:Qe},N(p(i)("sidebar.archiveToastUndo")),1),qe(" "+N(p(i)("sidebar.archiveToastMid"))+" ",1),C("button",{type:"button",onClick:Qt},N(p(i)("sidebar.archiveToastSettings")),1),qe(" "+N(p(i)("sidebar.archiveToastTail")),1)]),_:1})):ee("",!0)]),_:1})])),p(l)?(y(),he(lje,{key:10})):ee("",!0),j(cHe),p(a)?(y(),he(aze,{key:11,modelValue:u.value,"onUpdate:modelValue":Le[72]||(Le[72]=Ze=>u.value=Ze),groups:p(o).mobileWorkspaceGroups.value,"active-workspace-id":p(o).activeWorkspaceId.value,"active-id":p(o).activeSessionId.value,"attention-by-session":p(o).attentionBySession.value,"attention-by-workspace":p(o).attentionByWorkspace.value,onSelect:Le[73]||(Le[73]=Ze=>p(o).selectSession(Ze)),onCreate:Fs,onCreateInWorkspace:Le[74]||(Le[74]=Ze=>Rs(Ze)),onAddWorkspace:Le[75]||(Le[75]=Ze=>lo.value=!0),onRename:Le[76]||(Le[76]=(Ze,Xt)=>p(o).renameSession(Ze,Xt)),onArchive:Le[77]||(Le[77]=Ze=>fo(Ze)),onDeleteWorkspace:Le[78]||(Le[78]=Ze=>kn(Ze)),onLoadMore:Le[79]||(Le[79]=Ze=>void p(o).loadMoreSessions(Ze))},null,8,["modelValue","groups","active-workspace-id","active-id","attention-by-session","attention-by-workspace"])):ee("",!0),p(a)?(y(),he(vWe,{key:12,modelValue:c.value,"onUpdate:modelValue":Le[80]||(Le[80]=Ze=>c.value=Ze),"initial-view":Ct.value,status:p(o).status.value,thinking:p(o).thinking.value,models:p(o).models.value,"plan-mode":p(o).planMode.value,"swarm-mode":p(o).swarmMode.value,"color-scheme":p(o).colorScheme.value,"font-scale":p(o).fontScale.value,"managed-provider-status":p(o).managedProviderStatus.value,"managed-user-info":p(o).managedUserInfo.value,"server-version":p(o).serverVersion.value,onPickModel:Le[81]||(Le[81]=Ze=>ci()),onSetThinking:Le[82]||(Le[82]=Ze=>p(o).setThinking(Ze)),onTogglePlan:Le[83]||(Le[83]=Ze=>p(o).togglePlanMode()),onToggleSwarm:Le[84]||(Le[84]=Ze=>p(o).toggleSwarmMode()),onSetPermission:Le[85]||(Le[85]=Ze=>p(o).setPermission(Ze)),onSetColorScheme:Le[86]||(Le[86]=Ze=>p(o).setColorScheme(Ze)),onSetFontScale:Le[87]||(Le[87]=Ze=>p(o).setFontScale(Ze)),onLogin:Le[88]||(Le[88]=()=>{c.value=!1,Oo()}),onLogout:vo},null,8,["modelValue","initial-view","status","thinking","models","plan-mode","swarm-mode","color-scheme","font-scale","managed-provider-status","managed-user-info","server-version"])):ee("",!0)],10,hje),p(o).initialized.value&&w.value?(y(),he(AUe,{key:1,"auth-ready":p(o).managedProviderStatus.value==="authenticated","on-start-o-auth-login":Eo,"on-poll-o-auth-login":bo,"on-cancel-o-auth-login":Ns,onComplete:b,onLoginSuccess:Io,onAddProvider:_},null,8,["auth-ready"])):ee("",!0),To.value?(y(),he(JFe,{key:2,"on-start-o-auth-login":Eo,"on-poll-o-auth-login":bo,"on-cancel-o-auth-login":Ns,onSuccess:Do,onClose:Le[89]||(Le[89]=Ze=>To.value=!1)})):ee("",!0),W.value?(y(),he(Q5,{key:3,media:W.value,"origin-img":K.value,onClose:Le[90]||(Le[90]=Ze=>{W.value=null,K.value=null})},null,8,["media","origin-img"])):ee("",!0)]))}}),vje=ft(gje,[["__scopeId","data-v-ac226647"]]);B0e();const W2=Im(vje).use(Hn),yje={t:(e,t)=>Hn.global.t(e,t)};W2.provide(NM,yje);W2.provide(RM,e=>J6e(e)?.component);W2.provide(VX,mu());W2.mount("#app");if(Wp){const e=window.kimiDesktop;if(e){const t=()=>{const n=document.documentElement.dataset.colorScheme;e.setTheme(n==="light"||n==="dark"?n:"system")};new MutationObserver(t).observe(document.documentElement,{attributes:!0,attributeFilter:["data-color-scheme"]}),t()}}export{ER as $,fA as A,yO as B,rs as C,hVe as D,IS as E,Pe as F,iu as G,qe as H,j as I,JR as J,Bje as K,zr as L,et as M,GP as N,Uje as O,jje as P,Kje as Q,dm as R,Od as S,Zr as T,Vje as U,K8 as V,Wje as W,gVe as X,qje as Y,uVe as Z,kje as _,iA as a,bs as a$,ds as a0,Kg as a1,Aje as a2,O8 as a3,OA as a4,tn as a5,f1 as a6,$je as a7,kVe as a8,Rje as a9,cA as aA,NO as aB,BO as aC,dn as aD,DO as aE,PO as aF,d1 as aG,OO as aH,bn as aI,Dp as aJ,oO as aK,y as aL,qP as aM,Ije as aN,Ln as aO,ZS as aP,Eje as aQ,mm as aR,Go as aS,E4 as aT,Z as aU,oVe as aV,cD as aW,pt as aX,xn as aY,zO as aZ,Hje as a_,Dje as aa,Pje as ab,Oje as ac,iVe as ad,bVe as ae,nn as af,_P as ag,Jg as ah,Wa as ai,ia as aj,Xo as ak,sVe as al,tr as am,Ga as an,kt as ao,Yje as ap,Xje as aq,zn as ar,yt as as,TP as at,Re as au,xR as av,Zt as aw,$O as ax,RO as ay,Vn as az,Tje as b,Lde as b$,fVe as b0,up as b1,wm as b2,cVe as b3,Za as b4,qS as b5,Cje as b6,Xr as b7,cO as b8,dVe as b9,ai as bA,qs as bB,xP as bC,lVe as bD,Je as bE,I4 as bF,Nje as bG,fO as bH,Qje as bI,me as bJ,Zje as bK,Bn as bL,xl as bM,rVe as bN,It as bO,Lje as bP,Gn as bQ,jo as bR,SVe as bS,AVe as bT,l$ as bU,MVe as bV,Yce as bW,r$ as bX,G3 as bY,LVe as bZ,Fde as b_,bje as ba,N as bb,Fh as bc,zje as bd,Pn as be,_je as bf,wje as bg,Rh as bh,nVe as bi,GR as bj,p as bk,p1 as bl,yVe as bm,mVe as bn,XP as bo,kO as bp,eVe as bq,dO as br,vVe as bs,Gje as bt,Fje as bu,sA as bv,Em as bw,iD as bx,JA as by,V4 as bz,aVe as c,g5 as c0,h5 as c1,m5 as c2,NVe as c3,ag as c4,Md as c5,rg as c6,Mde as c7,Tde as c8,FVe as c9,f_e as cA,ft as cB,$Ve as ca,wVe as cb,RVe as cc,T2 as cd,Pi as ce,jde as cf,Ude as cg,Uce as ch,xVe as ci,Bce as cj,Hce as ck,_Ve as cl,v5 as cm,Vde as cn,N_ as co,p_ as cp,Jce as cq,lg as cr,ig as cs,TVe as ct,IVe as cu,CVe as cv,EVe as cw,Te as cx,OVe as cy,aF as cz,tVe as d,Ua as e,xje as f,as as g,YA as h,Sje as i,Mje as j,xr as k,Rp as l,_s as m,Ug as n,ra as o,pVe as p,R as q,Im as r,he as s,ee as t,M as u,C as v,uP as w,Jje as x,aP as y,dD as z}; diff --git a/apps/kimi-code/dist-web/assets/index-D1h84VfZ.js b/apps/kimi-code/dist-web/assets/index-D1h84VfZ.js deleted file mode 100644 index 7247871a7..000000000 --- a/apps/kimi-code/dist-web/assets/index-D1h84VfZ.js +++ /dev/null @@ -1,683 +0,0 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/DesignSystemView-TDJEKkA2.js","assets/DesignSystemView-DId9_nyG.css","assets/mhchem-DtR62fUK.js","assets/katex-DnlPpQZa.js","assets/mermaid.core-DaDTfY6S.js","assets/_commonjsHelpers-CqkleIqs.js","assets/CodeBlockNode-CJGhujJE.js","assets/safeRaf-DGuzXxDK.js","assets/index5-L7WSqVk4.js","assets/index11-DwTakJcU.js","assets/rive-CeXCFBdn.js"])))=>i.map(i=>d[i]); -(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const o of document.querySelectorAll('link[rel="modulepreload"]'))i(o);new MutationObserver(o=>{for(const s of o)if(s.type==="childList")for(const r of s.addedNodes)r.tagName==="LINK"&&r.rel==="modulepreload"&&i(r)}).observe(document,{childList:!0,subtree:!0});function n(o){const s={};return o.integrity&&(s.integrity=o.integrity),o.referrerPolicy&&(s.referrerPolicy=o.referrerPolicy),o.crossOrigin==="use-credentials"?s.credentials="include":o.crossOrigin==="anonymous"?s.credentials="omit":s.credentials="same-origin",s}function i(o){if(o.ep)return;o.ep=!0;const s=n(o);fetch(o.href,s)}})();/** -* @vue/shared v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/function Dy(e){const t=Object.create(null);for(const n of e.split(","))t[n]=1;return n=>n in t}const Gn={},Ah=[],Bl=()=>{},HL=()=>!1,Q0=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&(e.charCodeAt(2)>122||e.charCodeAt(2)<97),By=e=>e.startsWith("onUpdate:"),Ei=Object.assign,L5=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},_W=Object.prototype.hasOwnProperty,ki=(e,t)=>_W.call(e,t),tn=Array.isArray,Ch=e=>i1(e)==="[object Map]",yf=e=>i1(e)==="[object Set]",qC=e=>i1(e)==="[object Date]",MW=e=>i1(e)==="[object RegExp]",xn=e=>typeof e=="function",zi=e=>typeof e=="string",gl=e=>typeof e=="symbol",Ai=e=>e!==null&&typeof e=="object",N5=e=>(Ai(e)||xn(e))&&xn(e.then)&&xn(e.catch),WL=Object.prototype.toString,i1=e=>WL.call(e),IW=e=>i1(e).slice(8,-1),$y=e=>i1(e)==="[object Object]",Ry=e=>zi(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,Ud=Dy(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),zy=e=>{const t=Object.create(null);return(n=>t[n]||(t[n]=e(n)))},EW=/-\w/g,ps=zy(e=>e.replace(EW,t=>t.slice(1).toUpperCase())),TW=/\B([A-Z])/g,Wr=zy(e=>e.replace(TW,"-$1").toLowerCase()),Oy=zy(e=>e.charAt(0).toUpperCase()+e.slice(1)),hv=zy(e=>e?`on${Oy(e)}`:""),Ts=(e,t)=>!Object.is(e,t),wh=(e,...t)=>{for(let n=0;n<e.length;n++)e[n](...t)},qL=(e,t,n,i=!1)=>{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:i,value:n})},Py=e=>{const t=parseFloat(e);return isNaN(t)?e:t},Vv=e=>{const t=zi(e)?Number(e):NaN;return isNaN(t)?e:t};let UC;const jy=()=>UC||(UC=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{}),LW="Infinity,undefined,NaN,isFinite,isNaN,parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,BigInt,console,Error,Symbol",NW=Dy(LW);function Kt(e){if(tn(e)){const t={};for(let n=0;n<e.length;n++){const i=e[n],o=zi(i)?$W(i):Kt(i);if(o)for(const s in o)t[s]=o[s]}return t}else if(zi(e)||Ai(e))return e}const FW=/;(?![^(]*\))/g,DW=/:([^]+)/,BW=/\/\*[^]*?\*\//g;function $W(e){const t={};return e.replace(BW,"").split(FW).forEach(n=>{if(n){const i=n.split(DW);i.length>1&&(t[i[0].trim()]=i[1].trim())}}),t}function Fe(e){let t="";if(zi(e))t=e;else if(tn(e))for(let n=0;n<e.length;n++){const i=Fe(e[n]);i&&(t+=i+" ")}else if(Ai(e))for(const n in e)e[n]&&(t+=n+" ");return t.trim()}function RW(e){if(!e)return null;let{class:t,style:n}=e;return t&&!zi(t)&&(e.class=Fe(t)),n&&(e.style=Kt(n)),e}const zW="itemscope,allowfullscreen,formnovalidate,ismap,nomodule,novalidate,readonly",OW=Dy(zW);function UL(e){return!!e||e===""}function PW(e,t){if(e.length!==t.length)return!1;let n=!0;for(let i=0;n&&i<e.length;i++)n=wu(e[i],t[i]);return n}function wu(e,t){if(e===t)return!0;let n=qC(e),i=qC(t);if(n||i)return n&&i?e.getTime()===t.getTime():!1;if(n=gl(e),i=gl(t),n||i)return e===t;if(n=tn(e),i=tn(t),n||i)return n&&i?PW(e,t):!1;if(n=Ai(e),i=Ai(t),n||i){if(!n||!i)return!1;const o=Object.keys(e).length,s=Object.keys(t).length;if(o!==s)return!1;for(const r in e){const l=e.hasOwnProperty(r),a=t.hasOwnProperty(r);if(l&&!a||!l&&a||!wu(e[r],t[r]))return!1}}return String(e)===String(t)}function Hy(e,t){return e.findIndex(n=>wu(n,t))}const KL=e=>!!(e&&e.__v_isRef===!0),D=e=>zi(e)?e:e==null?"":tn(e)||Ai(e)&&(e.toString===WL||!xn(e.toString))?KL(e)?D(e.value):JSON.stringify(e,VL,2):String(e),VL=(e,t)=>KL(t)?VL(e,t.value):Ch(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[i,o],s)=>(n[z4(i,s)+" =>"]=o,n),{})}:yf(t)?{[`Set(${t.size})`]:[...t.values()].map(n=>z4(n))}:gl(t)?z4(t):Ai(t)&&!tn(t)&&!$y(t)?String(t):t,z4=(e,t="")=>{var n;return gl(e)?`Symbol(${(n=e.description)!=null?n:t})`:e};function jW(e){return e==null?"initial":typeof e=="string"?e===""?" ":e:String(e)}/** -* @vue/reactivity v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let ds;class ZL{constructor(t=!1){this.detached=t,this._active=!0,this._on=0,this.effects=[],this.cleanups=[],this._isPaused=!1,this._warnOnRun=!0,this.__v_skip=!0,!t&&ds&&(ds.active?(this.parent=ds,this.index=(ds.scopes||(ds.scopes=[])).push(this)-1):(this._active=!1,this._warnOnRun=!1))}get active(){return this._active}pause(){if(this._active){this._isPaused=!0;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].pause();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].pause()}}resume(){if(this._active&&this._isPaused){this._isPaused=!1;let t,n;if(this.scopes)for(t=0,n=this.scopes.length;t<n;t++)this.scopes[t].resume();for(t=0,n=this.effects.length;t<n;t++)this.effects[t].resume()}}run(t){if(this._active){const n=ds;try{return ds=this,t()}finally{ds=n}}}on(){++this._on===1&&(this.prevScope=ds,ds=this)}off(){if(this._on>0&&--this._on===0){if(ds===this)ds=this.prevScope;else{let t=ds;for(;t;){if(t.prevScope===this){t.prevScope=this.prevScope;break}t=t.prevScope}}this.prevScope=void 0}}stop(t){if(this._active){this._active=!1;let n,i;for(n=0,i=this.effects.length;n<i;n++)this.effects[n].stop();for(this.effects.length=0,n=0,i=this.cleanups.length;n<i;n++)this.cleanups[n]();if(this.cleanups.length=0,this.scopes){for(n=0,i=this.scopes.length;n<i;n++)this.scopes[n].stop(!0);this.scopes.length=0}if(!this.detached&&this.parent&&!t){const o=this.parent.scopes.pop();o&&o!==this&&(this.parent.scopes[this.index]=o,o.index=this.index)}this.parent=void 0}}}function F5(e){return new ZL(e)}function Y0(){return ds}function Bc(e,t=!1){ds&&ds.cleanups.push(e)}let Yi;const O4=new WeakSet;class Zv{constructor(t){this.fn=t,this.deps=void 0,this.depsTail=void 0,this.flags=5,this.next=void 0,this.cleanup=void 0,this.scheduler=void 0,ds&&(ds.active?ds.effects.push(this):this.flags&=-2)}pause(){this.flags|=64}resume(){this.flags&64&&(this.flags&=-65,O4.has(this)&&(O4.delete(this),this.trigger()))}notify(){this.flags&2&&!(this.flags&32)||this.flags&8||QL(this)}run(){if(!(this.flags&1))return this.fn();this.flags|=2,KC(this),YL(this);const t=Yi,n=la;Yi=this,la=!0;try{return this.fn()}finally{JL(this),Yi=t,la=n,this.flags&=-3}}stop(){if(this.flags&1){for(let t=this.deps;t;t=t.nextDep)$5(t);this.deps=this.depsTail=void 0,KC(this),this.onStop&&this.onStop(),this.flags&=-2}}trigger(){this.flags&64?O4.add(this):this.scheduler?this.scheduler():this.runIfDirty()}runIfDirty(){qk(this)&&this.run()}get dirty(){return qk(this)}}let GL=0,Lp,Np;function QL(e,t=!1){if(e.flags|=8,t){e.next=Np,Np=e;return}e.next=Lp,Lp=e}function D5(){GL++}function B5(){if(--GL>0)return;if(Np){let t=Np;for(Np=void 0;t;){const n=t.next;t.next=void 0,t.flags&=-9,t=n}}let e;for(;Lp;){let t=Lp;for(Lp=void 0;t;){const n=t.next;if(t.next=void 0,t.flags&=-9,t.flags&1)try{t.trigger()}catch(i){e||(e=i)}t=n}}if(e)throw e}function YL(e){for(let t=e.deps;t;t=t.nextDep)t.version=-1,t.prevActiveLink=t.dep.activeLink,t.dep.activeLink=t}function JL(e){let t,n=e.depsTail,i=n;for(;i;){const o=i.prevDep;i.version===-1?(i===n&&(n=o),$5(i),HW(i)):t=i,i.dep.activeLink=i.prevActiveLink,i.prevActiveLink=void 0,i=o}e.deps=t,e.depsTail=n}function qk(e){for(let t=e.deps;t;t=t.nextDep)if(t.dep.version!==t.version||t.dep.computed&&(XL(t.dep.computed)||t.dep.version!==t.version))return!0;return!!e._dirty}function XL(e){if(e.flags&4&&!(e.flags&16)||(e.flags&=-17,e.globalVersion===d0)||(e.globalVersion=d0,!e.isSSR&&e.flags&128&&(!e.deps&&!e._dirty||!qk(e))))return;e.flags|=2;const t=e.dep,n=Yi,i=la;Yi=e,la=!0;try{YL(e);const o=e.fn(e._value);(t.version===0||Ts(o,e._value))&&(e.flags|=128,e._value=o,t.version++)}catch(o){throw t.version++,o}finally{Yi=n,la=i,JL(e),e.flags&=-3}}function $5(e,t=!1){const{dep:n,prevSub:i,nextSub:o}=e;if(i&&(i.nextSub=o,e.prevSub=void 0),o&&(o.prevSub=i,e.nextSub=void 0),n.subs===e&&(n.subs=i,!i&&n.computed)){n.computed.flags&=-5;for(let s=n.computed.deps;s;s=s.nextDep)$5(s,!0)}!t&&!--n.sc&&n.map&&n.map.delete(n.key)}function HW(e){const{prevDep:t,nextDep:n}=e;t&&(t.nextDep=n,e.prevDep=void 0),n&&(n.prevDep=t,e.nextDep=void 0)}function put(e,t){e.effect instanceof Zv&&(e=e.effect.fn);const n=new Zv(e);t&&Ei(n,t);try{n.run()}catch(o){throw n.stop(),o}const i=n.run.bind(n);return i.effect=n,i}function gut(e){e.effect.stop()}let la=!0;const eN=[];function Pa(){eN.push(la),la=!1}function ja(){const e=eN.pop();la=e===void 0?!0:e}function KC(e){const{cleanup:t}=e;if(e.cleanup=void 0,t){const n=Yi;Yi=void 0;try{t()}finally{Yi=n}}}let d0=0;class WW{constructor(t,n){this.sub=t,this.dep=n,this.version=n.version,this.nextDep=this.prevDep=this.nextSub=this.prevSub=this.prevActiveLink=void 0}}class Wy{constructor(t){this.computed=t,this.version=0,this.activeLink=void 0,this.subs=void 0,this.map=void 0,this.key=void 0,this.sc=0,this.__v_skip=!0}track(t){if(!Yi||!la||Yi===this.computed)return;let n=this.activeLink;if(n===void 0||n.sub!==Yi)n=this.activeLink=new WW(Yi,this),Yi.deps?(n.prevDep=Yi.depsTail,Yi.depsTail.nextDep=n,Yi.depsTail=n):Yi.deps=Yi.depsTail=n,tN(n);else if(n.version===-1&&(n.version=this.version,n.nextDep)){const i=n.nextDep;i.prevDep=n.prevDep,n.prevDep&&(n.prevDep.nextDep=i),n.prevDep=Yi.depsTail,n.nextDep=void 0,Yi.depsTail.nextDep=n,Yi.depsTail=n,Yi.deps===n&&(Yi.deps=i)}return n}trigger(t){this.version++,d0++,this.notify(t)}notify(t){D5();try{for(let n=this.subs;n;n=n.prevSub)n.sub.notify()&&n.sub.dep.notify()}finally{B5()}}}function tN(e){if(e.dep.sc++,e.sub.flags&4){const t=e.dep.computed;if(t&&!e.dep.subs){t.flags|=20;for(let i=t.deps;i;i=i.nextDep)tN(i)}const n=e.dep.subs;n!==e&&(e.prevSub=n,n&&(n.nextSub=e)),e.dep.subs=e}}const Gv=new WeakMap,Kd=Symbol(""),Uk=Symbol(""),f0=Symbol("");function nr(e,t,n){if(la&&Yi){let i=Gv.get(e);i||Gv.set(e,i=new Map);let o=i.get(n);o||(i.set(n,o=new Wy),o.map=i,o.key=n),o.track()}}function uu(e,t,n,i,o,s){const r=Gv.get(e);if(!r){d0++;return}const l=a=>{a&&a.trigger()};if(D5(),t==="clear")r.forEach(l);else{const a=tn(e),u=a&&Ry(n);if(a&&n==="length"){const c=Number(i);r.forEach((d,h)=>{(h==="length"||h===f0||!gl(h)&&h>=c)&&l(d)})}else switch((n!==void 0||r.has(void 0))&&l(r.get(n)),u&&l(r.get(f0)),t){case"add":a?u&&l(r.get("length")):(l(r.get(Kd)),Ch(e)&&l(r.get(Uk)));break;case"delete":a||(l(r.get(Kd)),Ch(e)&&l(r.get(Uk)));break;case"set":Ch(e)&&l(r.get(Kd));break}}B5()}function qW(e,t){const n=Gv.get(e);return n&&n.get(t)}function Hf(e){const t=si(e);return t===e?t:(nr(t,"iterate",f0),ul(e)?t:t.map(ua))}function qy(e){return nr(e=si(e),"iterate",f0),e}function La(e,t){return xu(e)?Uh(Ra(e)?ua(t):t):ua(t)}const UW={__proto__:null,[Symbol.iterator](){return P4(this,Symbol.iterator,e=>La(this,e))},concat(...e){return Hf(this).concat(...e.map(t=>tn(t)?Hf(t):t))},entries(){return P4(this,"entries",e=>(e[1]=La(this,e[1]),e))},every(e,t){return eu(this,"every",e,t,void 0,arguments)},filter(e,t){return eu(this,"filter",e,t,n=>n.map(i=>La(this,i)),arguments)},find(e,t){return eu(this,"find",e,t,n=>La(this,n),arguments)},findIndex(e,t){return eu(this,"findIndex",e,t,void 0,arguments)},findLast(e,t){return eu(this,"findLast",e,t,n=>La(this,n),arguments)},findLastIndex(e,t){return eu(this,"findLastIndex",e,t,void 0,arguments)},forEach(e,t){return eu(this,"forEach",e,t,void 0,arguments)},includes(...e){return j4(this,"includes",e)},indexOf(...e){return j4(this,"indexOf",e)},join(e){return Hf(this).join(e)},lastIndexOf(...e){return j4(this,"lastIndexOf",e)},map(e,t){return eu(this,"map",e,t,void 0,arguments)},pop(){return O1(this,"pop")},push(...e){return O1(this,"push",e)},reduce(e,...t){return VC(this,"reduce",e,t)},reduceRight(e,...t){return VC(this,"reduceRight",e,t)},shift(){return O1(this,"shift")},some(e,t){return eu(this,"some",e,t,void 0,arguments)},splice(...e){return O1(this,"splice",e)},toReversed(){return Hf(this).toReversed()},toSorted(e){return Hf(this).toSorted(e)},toSpliced(...e){return Hf(this).toSpliced(...e)},unshift(...e){return O1(this,"unshift",e)},values(){return P4(this,"values",e=>La(this,e))}};function P4(e,t,n){const i=qy(e),o=i[t]();return i!==e&&!ul(e)&&(o._next=o.next,o.next=()=>{const s=o._next();return s.done||(s.value=n(s.value)),s}),o}const KW=Array.prototype;function eu(e,t,n,i,o,s){const r=qy(e),l=r!==e&&!ul(e),a=r[t];if(a!==KW[t]){const d=a.apply(e,s);return l?ua(d):d}let u=n;r!==e&&(l?u=function(d,h){return n.call(this,La(e,d),h,e)}:n.length>2&&(u=function(d,h){return n.call(this,d,h,e)}));const c=a.call(r,u,i);return l&&o?o(c):c}function VC(e,t,n,i){const o=qy(e),s=o!==e&&!ul(e);let r=n,l=!1;o!==e&&(s?(l=i.length===0,r=function(u,c,d){return l&&(l=!1,u=La(e,u)),n.call(this,u,La(e,c),d,e)}):n.length>3&&(r=function(u,c,d){return n.call(this,u,c,d,e)}));const a=o[t](r,...i);return l?La(e,a):a}function j4(e,t,n){const i=si(e);nr(i,"iterate",f0);const o=i[t](...n);return(o===-1||o===!1)&&Vy(n[0])?(n[0]=si(n[0]),i[t](...n)):o}function O1(e,t,n=[]){Pa(),D5();const i=si(e)[t].apply(e,n);return B5(),ja(),i}const VW=Dy("__proto__,__v_isRef,__isVue"),nN=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(gl));function ZW(e){gl(e)||(e=String(e));const t=si(this);return nr(t,"has",e),t.hasOwnProperty(e)}class iN{constructor(t=!1,n=!1){this._isReadonly=t,this._isShallow=n}get(t,n,i){if(n==="__v_skip")return t.__v_skip;const o=this._isReadonly,s=this._isShallow;if(n==="__v_isReactive")return!o;if(n==="__v_isReadonly")return o;if(n==="__v_isShallow")return s;if(n==="__v_raw")return i===(o?s?uN:aN:s?lN:rN).get(t)||Object.getPrototypeOf(t)===Object.getPrototypeOf(i)?t:void 0;const r=tn(t);if(!o){let a;if(r&&(a=UW[n]))return a;if(n==="hasOwnProperty")return ZW}const l=Reflect.get(t,n,io(t)?t:i);if((gl(n)?nN.has(n):VW(n))||(o||nr(t,"get",n),s))return l;if(io(l)){const a=r&&Ry(n)?l:l.value;return o&&Ai(a)?Vk(a):a}return Ai(l)?o?Vk(l):jo(l):l}}class oN extends iN{constructor(t=!1){super(!1,t)}set(t,n,i,o){let s=t[n];const r=tn(t)&&Ry(n);if(!this._isShallow){const u=xu(s);if(!ul(i)&&!xu(i)&&(s=si(s),i=si(i)),!r&&io(s)&&!io(i))return u||(s.value=i),!0}const l=r?Number(n)<t.length:ki(t,n),a=Reflect.set(t,n,i,io(t)?t:o);return t===si(o)&&a&&(l?Ts(i,s)&&uu(t,"set",n,i):uu(t,"add",n,i)),a}deleteProperty(t,n){const i=ki(t,n);t[n];const o=Reflect.deleteProperty(t,n);return o&&i&&uu(t,"delete",n,void 0),o}has(t,n){const i=Reflect.has(t,n);return(!gl(n)||!nN.has(n))&&nr(t,"has",n),i}ownKeys(t){return nr(t,"iterate",tn(t)?"length":Kd),Reflect.ownKeys(t)}}class sN extends iN{constructor(t=!1){super(!0,t)}set(t,n){return!0}deleteProperty(t,n){return!0}}const GW=new oN,QW=new sN,YW=new oN(!0),JW=new sN(!0),Kk=e=>e,im=e=>Reflect.getPrototypeOf(e);function XW(e,t,n){return function(...i){const o=this.__v_raw,s=si(o),r=Ch(s),l=e==="entries"||e===Symbol.iterator&&r,a=e==="keys"&&r,u=o[e](...i),c=n?Kk:t?Uh:ua;return!t&&nr(s,"iterate",a?Uk:Kd),Ei(Object.create(u),{next(){const{value:d,done:h}=u.next();return h?{value:d,done:h}:{value:l?[c(d[0]),c(d[1])]:c(d),done:h}}})}}function om(e){return function(...t){return e==="delete"?!1:e==="clear"?void 0:this}}function eq(e,t){const n={get(o){const s=this.__v_raw,r=si(s),l=si(o);e||(Ts(o,l)&&nr(r,"get",o),nr(r,"get",l));const{has:a}=im(r),u=t?Kk:e?Uh:ua;if(a.call(r,o))return u(s.get(o));if(a.call(r,l))return u(s.get(l));s!==r&&s.get(o)},get size(){const o=this.__v_raw;return!e&&nr(si(o),"iterate",Kd),o.size},has(o){const s=this.__v_raw,r=si(s),l=si(o);return e||(Ts(o,l)&&nr(r,"has",o),nr(r,"has",l)),o===l?s.has(o):s.has(o)||s.has(l)},forEach(o,s){const r=this,l=r.__v_raw,a=si(l),u=t?Kk:e?Uh:ua;return!e&&nr(a,"iterate",Kd),l.forEach((c,d)=>o.call(s,u(c),u(d),r))}};return Ei(n,e?{add:om("add"),set:om("set"),delete:om("delete"),clear:om("clear")}:{add(o){const s=si(this),r=im(s),l=si(o),a=!t&&!ul(o)&&!xu(o)?l:o;return r.has.call(s,a)||Ts(o,a)&&r.has.call(s,o)||Ts(l,a)&&r.has.call(s,l)||(s.add(a),uu(s,"add",a,a)),this},set(o,s){!t&&!ul(s)&&!xu(s)&&(s=si(s));const r=si(this),{has:l,get:a}=im(r);let u=l.call(r,o);u||(o=si(o),u=l.call(r,o));const c=a.call(r,o);return r.set(o,s),u?Ts(s,c)&&uu(r,"set",o,s):uu(r,"add",o,s),this},delete(o){const s=si(this),{has:r,get:l}=im(s);let a=r.call(s,o);a||(o=si(o),a=r.call(s,o)),l&&l.call(s,o);const u=s.delete(o);return a&&uu(s,"delete",o,void 0),u},clear(){const o=si(this),s=o.size!==0,r=o.clear();return s&&uu(o,"clear",void 0,void 0),r}}),["keys","values","entries",Symbol.iterator].forEach(o=>{n[o]=XW(o,e,t)}),n}function Uy(e,t){const n=eq(e,t);return(i,o,s)=>o==="__v_isReactive"?!e:o==="__v_isReadonly"?e:o==="__v_raw"?i:Reflect.get(ki(n,o)&&o in i?n:i,o,s)}const tq={get:Uy(!1,!1)},nq={get:Uy(!1,!0)},iq={get:Uy(!0,!1)},oq={get:Uy(!0,!0)},rN=new WeakMap,lN=new WeakMap,aN=new WeakMap,uN=new WeakMap;function sq(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function jo(e){return xu(e)?e:Ky(e,!1,GW,tq,rN)}function cN(e){return Ky(e,!1,YW,nq,lN)}function Vk(e){return Ky(e,!0,QW,iq,aN)}function mut(e){return Ky(e,!0,JW,oq,uN)}function Ky(e,t,n,i,o){if(!Ai(e)||e.__v_raw&&!(t&&e.__v_isReactive)||e.__v_skip||!Object.isExtensible(e))return e;const s=o.get(e);if(s)return s;const r=sq(IW(e));if(r===0)return e;const l=new Proxy(e,r===2?i:n);return o.set(e,l),l}function Ra(e){return xu(e)?Ra(e.__v_raw):!!(e&&e.__v_isReactive)}function xu(e){return!!(e&&e.__v_isReadonly)}function ul(e){return!!(e&&e.__v_isShallow)}function Vy(e){return e?!!e.__v_raw:!1}function si(e){const t=e&&e.__v_raw;return t?si(t):e}function St(e){return!ki(e,"__v_skip")&&Object.isExtensible(e)&&qL(e,"__v_skip",!0),e}const ua=e=>Ai(e)?jo(e):e,Uh=e=>Ai(e)?Vk(e):e;function io(e){return e?e.__v_isRef===!0:!1}function K(e){return dN(e,!1)}function ha(e){return dN(e,!0)}function dN(e,t){return io(e)?e:new rq(e,t)}class rq{constructor(t,n){this.dep=new Wy,this.__v_isRef=!0,this.__v_isShallow=!1,this._rawValue=n?t:si(t),this._value=n?t:ua(t),this.__v_isShallow=n}get value(){return this.dep.track(),this._value}set value(t){const n=this._rawValue,i=this.__v_isShallow||ul(t)||xu(t);t=i?t:si(t),Ts(t,n)&&(this._rawValue=t,this._value=i?t:ua(t),this.dep.trigger())}}function lq(e){e.dep&&e.dep.trigger()}function f(e){return io(e)?e.value:e}function Yl(e){return xn(e)?e():f(e)}const aq={get:(e,t,n)=>t==="__v_raw"?e:f(Reflect.get(e,t,n)),set:(e,t,n,i)=>{const o=e[t];return io(o)&&!io(n)?(o.value=n,!0):Reflect.set(e,t,n,i)}};function fN(e){return Ra(e)?e:new Proxy(e,aq)}class uq{constructor(t){this.__v_isRef=!0,this._value=void 0;const n=this.dep=new Wy,{get:i,set:o}=t(n.track.bind(n),n.trigger.bind(n));this._get=i,this._set=o}get value(){return this._value=this._get()}set value(t){this._set(t)}}function cq(e){return new uq(e)}function dq(e){const t=tn(e)?new Array(e.length):{};for(const n in e)t[n]=hN(e,n);return t}class fq{constructor(t,n,i){this._object=t,this._defaultValue=i,this.__v_isRef=!0,this._value=void 0,this._key=gl(n)?n:String(n),this._raw=si(t);let o=!0,s=t;if(!tn(t)||gl(this._key)||!Ry(this._key))do o=!Vy(s)||ul(s);while(o&&(s=s.__v_raw));this._shallow=o}get value(){let t=this._object[this._key];return this._shallow&&(t=f(t)),this._value=t===void 0?this._defaultValue:t}set value(t){if(this._shallow&&io(this._raw[this._key])){const n=this._object[this._key];if(io(n)){n.value=t;return}}this._object[this._key]=t}get dep(){return qW(this._raw,this._key)}}class hq{constructor(t){this._getter=t,this.__v_isRef=!0,this.__v_isReadonly=!0,this._value=void 0}get value(){return this._value=this._getter()}}function vut(e,t,n){return io(e)?e:xn(e)?new hq(e):Ai(e)&&arguments.length>1?hN(e,t,n):K(e)}function hN(e,t,n){return new fq(e,t,n)}class pq{constructor(t,n,i){this.fn=t,this.setter=n,this._value=void 0,this.dep=new Wy(this),this.__v_isRef=!0,this.deps=void 0,this.depsTail=void 0,this.flags=16,this.globalVersion=d0-1,this.next=void 0,this.effect=this,this.__v_isReadonly=!n,this.isSSR=i}notify(){if(this.flags|=16,!(this.flags&8)&&Yi!==this)return QL(this,!0),!0}get value(){const t=this.dep.track();return XL(this),t&&(t.version=this.dep.version),this._value}set value(t){this.setter&&this.setter(t)}}function gq(e,t,n=!1){let i,o;return xn(e)?i=e:(i=e.get,o=e.set),new pq(i,o,n)}const yut={GET:"get",HAS:"has",ITERATE:"iterate"},kut={SET:"set",ADD:"add",DELETE:"delete",CLEAR:"clear"},sm={},Qv=new WeakMap;let tc;function but(){return tc}function mq(e,t=!1,n=tc){if(n){let i=Qv.get(n);i||Qv.set(n,i=[]),i.push(e)}}function vq(e,t,n=Gn){const{immediate:i,deep:o,once:s,scheduler:r,augmentJob:l,call:a}=n,u=A=>o?A:ul(A)||o===!1||o===0?cu(A,1):cu(A);let c,d,h,p,g=!1,m=!1;if(io(e)?(d=()=>e.value,g=ul(e)):Ra(e)?(d=()=>u(e),g=!0):tn(e)?(m=!0,g=e.some(A=>Ra(A)||ul(A)),d=()=>e.map(A=>{if(io(A))return A.value;if(Ra(A))return u(A);if(xn(A))return a?a(A,2):A()})):xn(e)?t?d=a?()=>a(e,2):e:d=()=>{if(h){Pa();try{h()}finally{ja()}}const A=tc;tc=c;try{return a?a(e,3,[p]):e(p)}finally{tc=A}}:d=Bl,t&&o){const A=d,T=o===!0?1/0:o;d=()=>cu(A(),T)}const k=Y0(),w=()=>{c.stop(),k&&k.active&&L5(k.effects,c)};if(s&&t){const A=t;t=(...T)=>{const S=A(...T);return w(),S}}let y=m?new Array(e.length).fill(sm):sm;const b=A=>{if(!(!(c.flags&1)||!c.dirty&&!A))if(t){const T=c.run();if(A||o||g||(m?T.some((S,x)=>Ts(S,y[x])):Ts(T,y))){h&&h();const S=tc;tc=c;try{const x=[T,y===sm?void 0:m&&y[0]===sm?[]:y,p];y=T,a?a(t,3,x):t(...x)}finally{tc=S}}}else c.run()};return l&&l(b),c=new Zv(d),c.scheduler=r?()=>r(b,!1):b,p=A=>mq(A,!1,c),h=c.onStop=()=>{const A=Qv.get(c);if(A){if(a)a(A,4);else for(const T of A)T();Qv.delete(c)}},t?i?b(!0):y=c.run():r?r(b.bind(null,!0),!0):c.run(),w.pause=c.pause.bind(c),w.resume=c.resume.bind(c),w.stop=w,w}function cu(e,t=1/0,n){if(t<=0||!Ai(e)||e.__v_skip||(n=n||new Map,(n.get(e)||0)>=t))return e;if(n.set(e,t),t--,io(e))cu(e.value,t,n);else if(tn(e))for(let i=0;i<e.length;i++)cu(e[i],t,n);else if(yf(e)||Ch(e))e.forEach(i=>{cu(i,t,n)});else if($y(e)){for(const i in e)cu(e[i],t,n);for(const i of Object.getOwnPropertySymbols(e))Object.prototype.propertyIsEnumerable.call(e,i)&&cu(e[i],t,n)}return e}/** -* @vue/runtime-core v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/const pN=[];function yq(e){pN.push(e)}function kq(){pN.pop()}function Aut(e,t){}const Cut={SETUP_FUNCTION:0,0:"SETUP_FUNCTION",RENDER_FUNCTION:1,1:"RENDER_FUNCTION",NATIVE_EVENT_HANDLER:5,5:"NATIVE_EVENT_HANDLER",COMPONENT_EVENT_HANDLER:6,6:"COMPONENT_EVENT_HANDLER",VNODE_HOOK:7,7:"VNODE_HOOK",DIRECTIVE_HOOK:8,8:"DIRECTIVE_HOOK",TRANSITION_HOOK:9,9:"TRANSITION_HOOK",APP_ERROR_HANDLER:10,10:"APP_ERROR_HANDLER",APP_WARN_HANDLER:11,11:"APP_WARN_HANDLER",FUNCTION_REF:12,12:"FUNCTION_REF",ASYNC_COMPONENT_LOADER:13,13:"ASYNC_COMPONENT_LOADER",SCHEDULER:14,14:"SCHEDULER",COMPONENT_UPDATE:15,15:"COMPONENT_UPDATE",APP_UNMOUNT_CLEANUP:16,16:"APP_UNMOUNT_CLEANUP"},bq={sp:"serverPrefetch hook",bc:"beforeCreate hook",c:"created hook",bm:"beforeMount hook",m:"mounted hook",bu:"beforeUpdate hook",u:"updated",bum:"beforeUnmount hook",um:"unmounted hook",a:"activated hook",da:"deactivated hook",ec:"errorCaptured hook",rtc:"renderTracked hook",rtg:"renderTriggered hook",0:"setup function",1:"render function",2:"watcher getter",3:"watcher callback",4:"watcher cleanup function",5:"native event handler",6:"component event handler",7:"vnode hook",8:"directive hook",9:"transition hook",10:"app errorHandler",11:"app warnHandler",12:"ref function",13:"async component loader",14:"scheduler flush",15:"component update",16:"app unmount cleanup function"};function J0(e,t,n,i){try{return i?e(...i):e()}catch(o){o1(o,t,n)}}function Rl(e,t,n,i){if(xn(e)){const o=J0(e,t,n,i);return o&&N5(o)&&o.catch(s=>{o1(s,t,n)}),o}if(tn(e)){const o=[];for(let s=0;s<e.length;s++)o.push(Rl(e[s],t,n,i));return o}}function o1(e,t,n,i=!0){const o=t?t.vnode:null,{errorHandler:s,throwUnhandledErrorInProduction:r}=t&&t.appContext.config||Gn;if(t){let l=t.parent;const a=t.proxy,u=`https://vuejs.org/error-reference/#runtime-${n}`;for(;l;){const c=l.ec;if(c){for(let d=0;d<c.length;d++)if(c[d](e,a,u)===!1)return}l=l.parent}if(s){Pa(),J0(s,null,10,[e,a,u]),ja();return}}Aq(e,n,o,i,r)}function Aq(e,t,n,i=!0,o=!1){if(o)throw e;console.error(e)}const vr=[];let Ia=-1;const xh=[];let nc=null,th=0;const gN=Promise.resolve();let Yv=null;function dt(e){const t=Yv||gN;return e?t.then(this?e.bind(this):e):t}function Cq(e){let t=Ia+1,n=vr.length;for(;t<n;){const i=t+n>>>1,o=vr[i],s=h0(o);s<e||s===e&&o.flags&2?t=i+1:n=i}return t}function R5(e){if(!(e.flags&1)){const t=h0(e),n=vr[vr.length-1];!n||!(e.flags&2)&&t>=h0(n)?vr.push(e):vr.splice(Cq(t),0,e),e.flags|=1,mN()}}function mN(){Yv||(Yv=gN.then(vN))}function Jv(e){tn(e)?xh.push(...e):nc&&e.id===-1?nc.splice(th+1,0,e):e.flags&1||(xh.push(e),e.flags|=1),mN()}function ZC(e,t,n=Ia+1){for(;n<vr.length;n++){const i=vr[n];if(i&&i.flags&2){if(e&&i.id!==e.uid)continue;vr.splice(n,1),n--,i.flags&4&&(i.flags&=-2),i(),i.flags&4||(i.flags&=-2)}}}function Xv(e){if(xh.length){const t=[...new Set(xh)].sort((n,i)=>h0(n)-h0(i));if(xh.length=0,nc){nc.push(...t);return}for(nc=t,th=0;th<nc.length;th++){const n=nc[th];n.flags&4&&(n.flags&=-2),n.flags&8||n(),n.flags&=-2}nc=null,th=0}}const h0=e=>e.id==null?e.flags&2?-1:1/0:e.id;function vN(e){try{for(Ia=0;Ia<vr.length;Ia++){const t=vr[Ia];t&&!(t.flags&8)&&(t.flags&4&&(t.flags&=-2),J0(t,t.i,t.i?15:14),t.flags&4||(t.flags&=-2))}}finally{for(;Ia<vr.length;Ia++){const t=vr[Ia];t&&(t.flags&=-2)}Ia=-1,vr.length=0,Xv(),Yv=null,(vr.length||xh.length)&&vN()}}let nh,rm=[];function yN(e,t){var n,i;nh=e,nh?(nh.enabled=!0,rm.forEach(({event:o,args:s})=>nh.emit(o,...s)),rm=[]):typeof window<"u"&&window.HTMLElement&&!((i=(n=window.navigator)==null?void 0:n.userAgent)!=null&&i.includes("jsdom"))?((t.__VUE_DEVTOOLS_HOOK_REPLAY__=t.__VUE_DEVTOOLS_HOOK_REPLAY__||[]).push(s=>{yN(s,t)}),setTimeout(()=>{nh||(t.__VUE_DEVTOOLS_HOOK_REPLAY__=null,rm=[])},3e3)):rm=[]}let Ks=null,Zy=null;function p0(e){const t=Ks;return Ks=e,Zy=e&&e.type.__scopeId||null,t}function wut(e){Zy=e}function xut(){Zy=null}const Sut=e=>de;function de(e,t=Ks,n){if(!t||e._n)return e;const i=(...o)=>{i._d&&s2(-1);const s=p0(t);let r;try{r=e(...o)}finally{p0(s),i._d&&s2(1)}return r};return i._n=!0,i._c=!0,i._d=!0,i}function Wn(e,t){if(Ks===null)return e;const n=tg(Ks),i=e.dirs||(e.dirs=[]);for(let o=0;o<t.length;o++){let[s,r,l,a=Gn]=t[o];s&&(xn(s)&&(s={mounted:s,updated:s}),s.deep&&cu(r),i.push({dir:s,instance:n,value:r,oldValue:void 0,arg:l,modifiers:a}))}return e}function Ta(e,t,n,i){const o=e.dirs,s=t&&t.dirs;for(let r=0;r<o.length;r++){const l=o[r];s&&(l.oldValue=s[r].value);let a=l.dir[i];a&&(Pa(),Rl(a,n,8,[e.el,l,e,t]),ja())}}function oi(e,t){if(Us){let n=Us.provides;const i=Us.parent&&Us.parent.provides;i===n&&(n=Us.provides=Object.create(i)),n[e]=t}}function hn(e,t,n=!1){const i=os();if(i||Vd){let o=Vd?Vd._context.provides:i?i.parent==null||i.ce?i.vnode.appContext&&i.vnode.appContext.provides:i.parent.provides:void 0;if(o&&e in o)return o[e];if(arguments.length>1)return n&&xn(t)?t.call(i&&i.proxy):t}}function wq(){return!!(os()||Vd)}const xq=Symbol.for("v-scx"),Sq=()=>hn(xq);function Zk(e,t){return X0(e,null,t)}function _ut(e,t){return X0(e,null,{flush:"post"})}function _q(e,t){return X0(e,null,{flush:"sync"})}function Pe(e,t,n){return X0(e,t,n)}function X0(e,t,n=Gn){const{immediate:i,deep:o,flush:s,once:r}=n,l=Ei({},n),a=t&&i||!t&&s!=="post";let u;if(sf){if(s==="sync"){const p=Sq();u=p.__watcherHandles||(p.__watcherHandles=[])}else if(!a){const p=()=>{};return p.stop=Bl,p.resume=Bl,p.pause=Bl,p}}const c=Us;l.call=(p,g,m)=>Rl(p,c,g,m);let d=!1;s==="post"?l.scheduler=p=>{Zo(p,c&&c.suspense)}:s!=="sync"&&(d=!0,l.scheduler=(p,g)=>{g?p():R5(p)}),l.augmentJob=p=>{t&&(p.flags|=4),d&&(p.flags|=2,c&&(p.id=c.uid,p.i=c))};const h=vq(e,t,l);return sf&&(u?u.push(h):a&&h()),h}function Mq(e,t,n){const i=this.proxy,o=zi(e)?e.includes(".")?kN(i,e):()=>i[e]:e.bind(i,i);let s;xn(t)?s=t:(s=t.handler,n=t);const r=l1(this),l=X0(o,s.bind(i),n);return r(),l}function kN(e,t){const n=t.split(".");return()=>{let i=e;for(let o=0;o<n.length&&i;o++)i=i[n[o]];return i}}const Gu=new WeakMap,bN=Symbol("_vte"),AN=e=>e.__isTeleport,Id=e=>e&&(e.disabled||e.disabled===""),Iq=e=>e&&(e.defer||e.defer===""),GC=e=>typeof SVGElement<"u"&&e instanceof SVGElement,QC=e=>typeof MathMLElement=="function"&&e instanceof MathMLElement,Gk=(e,t)=>{const n=e&&e.to;return zi(n)?t?t(n):null:n},Eq={name:"Teleport",__isTeleport:!0,process(e,t,n,i,o,s,r,l,a,u){const{mc:c,pc:d,pbc:h,o:{insert:p,querySelector:g,createText:m,createComment:k,parentNode:w}}=u,y=Id(t.props);let{dynamicChildren:b}=t;const A=(x,_,L)=>{x.shapeFlag&16&&c(x.children,_,L,o,s,r,l,a)},T=(x=t)=>{const _=Id(x.props),L=x.target=Gk(x.props,g),M=Qk(L,x,m,p);L&&(r!=="svg"&&GC(L)?r="svg":r!=="mathml"&&QC(L)&&(r="mathml"),o&&o.isCE&&(o.ce._teleportTargets||(o.ce._teleportTargets=new Set)).add(L),_||(A(x,L,M),lp(x,!1)))},S=x=>{const _=()=>{if(Gu.get(x)===_){if(Gu.delete(x),Id(x.props)){const L=w(x.el)||n;A(x,L,x.anchor),lp(x,!0)}T(x)}};Gu.set(x,_),Zo(_,s)};if(e==null){const x=t.el=m(""),_=t.anchor=m("");if(p(x,n,i),p(_,n,i),Iq(t.props)||s&&s.pendingBranch){S(t);return}y&&(A(t,n,_),lp(t,!0)),T()}else{t.el=e.el;const x=t.anchor=e.anchor,_=Gu.get(e);if(_){_.flags|=8,Gu.delete(e),S(t);return}t.targetStart=e.targetStart;const L=t.target=e.target,M=t.targetAnchor=e.targetAnchor,N=Id(e.props),I=N?n:L,z=N?x:M;if(r==="svg"||GC(L)?r="svg":(r==="mathml"||QC(L))&&(r="mathml"),b?(h(e.dynamicChildren,b,I,o,s,r,l),V5(e,t,!0)):a||d(e,t,I,z,o,s,r,l,!1),y)N?t.props&&e.props&&t.props.to!==e.props.to&&(t.props.to=e.props.to):lm(t,n,x,u,1);else if((t.props&&t.props.to)!==(e.props&&e.props.to)){const H=Gk(t.props,g);H&&(t.target=H,lm(t,H,null,u,0))}else N&&lm(t,L,M,u,1);lp(t,y)}},remove(e,t,n,{um:i,o:{remove:o}},s){const{shapeFlag:r,children:l,anchor:a,targetStart:u,targetAnchor:c,target:d,props:h}=e,p=Id(h),g=s||!p,m=Gu.get(e);if(m&&(m.flags|=8,Gu.delete(e)),d&&(o(u),o(c)),s&&o(a),!m&&(p||d)&&r&16)for(let k=0;k<l.length;k++){const w=l[k];i(w,t,n,g,!!w.dynamicChildren)}},move:lm,hydrate:Tq};function lm(e,t,n,{o:{insert:i},m:o},s=2){s===0&&i(e.targetAnchor,t,n);const{el:r,anchor:l,shapeFlag:a,children:u,props:c}=e,d=s===2;if(d&&i(r,t,n),!Gu.has(e)&&(!d||Id(c))&&a&16)for(let h=0;h<u.length;h++)o(u[h],t,n,2);d&&i(l,t,n)}function Tq(e,t,n,i,o,s,{o:{nextSibling:r,parentNode:l,querySelector:a,insert:u,createText:c}},d){function h(k,w){let y=w;for(;y;){if(y&&y.nodeType===8){if(y.data==="teleport start anchor")t.targetStart=y;else if(y.data==="teleport anchor"){t.targetAnchor=y,k._lpa=t.targetAnchor&&r(t.targetAnchor);break}}y=r(y)}}function p(k,w){w.anchor=d(r(k),w,l(k),n,i,o,s)}const g=t.target=Gk(t.props,a),m=Id(t.props);if(g){const k=g._lpa||g.firstChild;t.shapeFlag&16&&(m?(p(e,t),h(g,k),t.targetAnchor||Qk(g,t,c,u,l(e)===g?e:null)):(t.anchor=r(e),h(g,k),t.targetAnchor||Qk(g,t,c,u),d(k&&r(k),t,g,n,i,o,s))),lp(t,m)}else m&&t.shapeFlag&16&&(p(e,t),t.targetStart=e,t.targetAnchor=r(e));return t.anchor&&r(t.anchor)}const Ds=Eq;function lp(e,t){const n=e.ctx;if(n&&n.ut){let i,o;for(t?(i=e.el,o=e.anchor):(i=e.targetStart,o=e.targetAnchor);i&&i!==o;)i.nodeType===1&&i.setAttribute("data-v-owner",n.uid),i=i.nextSibling;n.ut()}}function Qk(e,t,n,i,o=null){const s=t.targetStart=n(""),r=t.targetAnchor=n("");return s[bN]=r,e&&(i(s,e,o),i(r,e,o)),r}const Il=Symbol("_leaveCb"),P1=Symbol("_enterCb");function CN(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return cn(()=>{e.isMounted=!0}),Hn(()=>{e.isUnmounting=!0}),e}const Cl=[Function,Array],wN={mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:Cl,onEnter:Cl,onAfterEnter:Cl,onEnterCancelled:Cl,onBeforeLeave:Cl,onLeave:Cl,onAfterLeave:Cl,onLeaveCancelled:Cl,onBeforeAppear:Cl,onAppear:Cl,onAfterAppear:Cl,onAppearCancelled:Cl},xN=e=>{const t=e.subTree;return t.component?xN(t.component):t},Lq={name:"BaseTransition",props:wN,setup(e,{slots:t}){const n=os(),i=CN();return()=>{const o=t.default&&z5(t.default(),!0),s=o&&o.length?SN(o):n.subTree?X():void 0;if(!s)return;const r=si(e),{mode:l}=r;if(i.isLeaving)return H4(s);const a=YC(s);if(!a)return H4(s);let u=g0(a,r,i,n,d=>u=d);a.type!==Yo&&Ac(a,u);let c=n.subTree&&YC(n.subTree);if(c&&c.type!==Yo&&!ea(c,a)&&xN(n).type!==Yo){let d=g0(c,r,i,n);if(Ac(c,d),l==="out-in"&&a.type!==Yo)return i.isLeaving=!0,d.afterLeave=()=>{i.isLeaving=!1,n.job.flags&8||n.update(),delete d.afterLeave,c=void 0},H4(s);l==="in-out"&&a.type!==Yo?d.delayLeave=(h,p,g)=>{const m=_N(i,c);m[String(c.key)]=c,h[Il]=()=>{p(),h[Il]=void 0,delete u.delayedLeave,c=void 0},u.delayedLeave=()=>{g(),delete u.delayedLeave,c=void 0}}:c=void 0}else c&&(c=void 0);return s}}};function SN(e){let t=e[0];if(e.length>1){for(const n of e)if(n.type!==Yo){t=n;break}}return t}const Nq=Lq;function _N(e,t){const{leavingVNodes:n}=e;let i=n.get(t.type);return i||(i=Object.create(null),n.set(t.type,i)),i}function g0(e,t,n,i,o){const{appear:s,mode:r,persisted:l=!1,onBeforeEnter:a,onEnter:u,onAfterEnter:c,onEnterCancelled:d,onBeforeLeave:h,onLeave:p,onAfterLeave:g,onLeaveCancelled:m,onBeforeAppear:k,onAppear:w,onAfterAppear:y,onAppearCancelled:b}=t,A=String(e.key),T=_N(n,e),S=(L,M)=>{L&&Rl(L,i,9,M)},x=(L,M)=>{const N=M[1];S(L,M),tn(L)?L.every(I=>I.length<=1)&&N():L.length<=1&&N()},_={mode:r,persisted:l,beforeEnter(L){let M=a;if(!n.isMounted)if(s)M=k||a;else return;L[Il]&&L[Il](!0);const N=T[A];N&&ea(e,N)&&N.el[Il]&&N.el[Il](),S(M,[L])},enter(L){if(T[A]===e)return;let M=u,N=c,I=d;if(!n.isMounted)if(s)M=w||u,N=y||c,I=b||d;else return;let z=!1;L[P1]=O=>{z||(z=!0,O?S(I,[L]):S(N,[L]),_.delayedLeave&&_.delayedLeave(),L[P1]=void 0)};const H=L[P1].bind(null,!1);M?x(M,[L,H]):H()},leave(L,M){const N=String(e.key);if(L[P1]&&L[P1](!0),n.isUnmounting)return M();S(h,[L]);let I=!1;L[Il]=H=>{I||(I=!0,M(),H?S(m,[L]):S(g,[L]),L[Il]=void 0,T[N]===e&&delete T[N])};const z=L[Il].bind(null,!1);T[N]=e,p?x(p,[L,z]):z()},clone(L){const M=g0(L,t,n,i,o);return o&&o(M),M}};return _}function H4(e){if(eg(e))return e=Su(e),e.children=null,e}function YC(e){if(!eg(e))return AN(e.type)&&e.children?SN(e.children):e;if(e.component)return e.component.subTree;const{shapeFlag:t,children:n}=e;if(n){if(t&16)return n[0];if(t&32&&xn(n.default))return n.default()}}function Ac(e,t){e.shapeFlag&6&&e.component?(e.transition=t,Ac(e.component.subTree,t)):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function z5(e,t=!1,n){let i=[],o=0;for(let s=0;s<e.length;s++){let r=e[s];const l=n==null?r.key:String(n)+String(r.key!=null?r.key:s);r.type===Ee?(r.patchFlag&128&&o++,i=i.concat(z5(r.children,t,l))):(t||r.type!==Yo)&&i.push(l!=null?Su(r,{key:l}):r)}if(o>1)for(let s=0;s<i.length;s++)i[s].patchFlag=-2;return i}function Xe(e,t){return xn(e)?Ei({name:e.name},t,{setup:e}):e}function Fq(){const e=os();return e?(e.appContext.config.idPrefix||"v")+"-"+e.ids[0]+e.ids[1]++:""}function O5(e){e.ids=[e.ids[0]+e.ids[2]+++"-",0,0]}function Mut(e){const t=os(),n=ha(null);if(t){const o=t.refs===Gn?t.refs={}:t.refs;Object.defineProperty(o,e,{enumerable:!0,get:()=>n.value,set:s=>n.value=s})}return n}function JC(e,t){let n;return!!((n=Object.getOwnPropertyDescriptor(e,t))&&!n.configurable)}const e2=new WeakMap;function Sh(e,t,n,i,o=!1){if(tn(e)){e.forEach((m,k)=>Sh(m,t&&(tn(t)?t[k]:t),n,i,o));return}if(yu(i)&&!o){i.shapeFlag&512&&i.type.__asyncResolved&&i.component.subTree.component&&Sh(e,t,n,i.component.subTree);return}const s=i.shapeFlag&4?tg(i.component):i.el,r=o?null:s,{i:l,r:a}=e,u=t&&t.r,c=l.refs===Gn?l.refs={}:l.refs,d=l.setupState,h=si(d),p=d===Gn?HL:m=>JC(c,m)?!1:ki(h,m),g=(m,k)=>!(k&&JC(c,k));if(u!=null&&u!==a){if(XC(t),zi(u))c[u]=null,p(u)&&(d[u]=null);else if(io(u)){const m=t;g(u,m.k)&&(u.value=null),m.k&&(c[m.k]=null)}}if(xn(a)){Pa();try{J0(a,l,12,[r,c])}finally{ja()}}else{const m=zi(a),k=io(a);if(m||k){const w=()=>{if(e.f){const y=m?p(a)?d[a]:c[a]:g()||!e.k?a.value:c[e.k];if(o)tn(y)&&L5(y,s);else if(tn(y))y.includes(s)||y.push(s);else if(m)c[a]=[s],p(a)&&(d[a]=c[a]);else{const b=[s];g(a,e.k)&&(a.value=b),e.k&&(c[e.k]=b)}}else m?(c[a]=r,p(a)&&(d[a]=r)):k&&(g(a,e.k)&&(a.value=r),e.k&&(c[e.k]=r))};if(r){const y=()=>{w(),e2.delete(e)};y.id=-1,e2.set(e,y),Zo(y,n)}else XC(e),w()}}}function XC(e){const t=e2.get(e);t&&(t.flags|=8,e2.delete(e))}let ew=!1;const Wf=()=>{ew||(console.error("Hydration completed but contains mismatches."),ew=!0)},Dq=e=>e.namespaceURI.includes("svg")&&e.tagName!=="foreignObject",Bq=e=>e.namespaceURI.includes("MathML"),am=e=>{if(e.nodeType===1){if(Dq(e))return"svg";if(Bq(e))return"mathml"}},fh=e=>e.nodeType===8;function $q(e){const{mt:t,p:n,o:{patchProp:i,createText:o,nextSibling:s,parentNode:r,remove:l,insert:a,createComment:u}}=e,c=(b,A)=>{if(!A.hasChildNodes()){n(null,b,A),Xv(),A._vnode=b;return}d(A.firstChild,b,null,null,null),Xv(),A._vnode=b},d=(b,A,T,S,x,_=!1)=>{_=_||!!A.dynamicChildren;const L=fh(b)&&b.data==="[",M=()=>m(b,A,T,S,x,L),{type:N,ref:I,shapeFlag:z,patchFlag:H}=A;let O=b.nodeType;A.el=b,H===-2&&(_=!1,A.dynamicChildren=null);let R=null;switch(N){case hc:O!==3?A.children===""?(a(A.el=o(""),r(b),b),R=b):R=M():(b.data!==A.children&&(Wf(),b.data=A.children),R=s(b));break;case Yo:y(b)?(R=s(b),w(A.el=b.content.firstChild,b,T)):O!==8||L?R=M():R=s(b);break;case Mh:if(L&&(b=s(b),O=b.nodeType),O===1||O===3){R=b;const j=!A.children.length;for(let $=0;$<A.staticCount;$++)j&&(A.children+=R.nodeType===1?R.outerHTML:R.data),$===A.staticCount-1&&(A.anchor=R),R=s(R);return L?s(R):R}else M();break;case Ee:L?R=g(b,A,T,S,x,_):R=M();break;default:if(z&1)(O!==1||A.type.toLowerCase()!==b.tagName.toLowerCase())&&!y(b)?R=M():R=h(b,A,T,S,x,_);else if(z&6){A.slotScopeIds=x;const j=r(b);if(L?R=k(b):fh(b)&&b.data==="teleport start"?R=k(b,b.data,"teleport end"):R=s(b),t(A,j,null,T,S,am(j),_),yu(A)&&!A.type.__asyncResolved){let $;L?($=U(Ee),$.anchor=R?R.previousSibling:j.lastChild):$=b.nodeType===3?$e(""):U("div"),$.el=b,A.component.subTree=$}}else z&64?O!==8?R=M():R=A.type.hydrate(b,A,T,S,x,_,e,p):z&128&&(R=A.type.hydrate(b,A,T,S,am(r(b)),x,_,e,d))}return I!=null&&Sh(I,null,S,A),R},h=(b,A,T,S,x,_)=>{_=_||!!A.dynamicChildren;const{type:L,dynamicProps:M,props:N,patchFlag:I,shapeFlag:z,dirs:H,transition:O}=A,R=L==="input"||L==="option",j=!!M;if(R||j||I!==-1){H&&Ta(A,null,T,"created");let $=!1;if(y(b)){$=KN(null,O)&&T&&T.vnode.props&&T.vnode.props.appear;const P=b.content.firstChild;if($){const Z=P.getAttribute("class");Z&&(P.$cls=Z),O.beforeEnter(P)}w(P,b,T),A.el=b=P}if(z&16&&!(N&&(N.innerHTML||N.textContent))){let P=p(b.firstChild,A,b,T,S,x,_);for(P&&!pv(b,1)&&Wf();P;){const Z=P;P=P.nextSibling,l(Z)}}else if(z&8){let P=A.children;P[0]===` -`&&(b.tagName==="PRE"||b.tagName==="TEXTAREA")&&(P=P.slice(1));const{textContent:Z}=b;Z!==P&&Z!==P.replace(/\r\n|\r/g,` -`)&&(pv(b,0)||Wf(),b.textContent=A.children)}if(N){if(R||j||!_||I&48){const P=b.tagName.includes("-");for(const Z in N)(R&&(Z.endsWith("value")||Z==="indeterminate")||Q0(Z)&&!Ud(Z)||Z[0]==="."||P&&!Ud(Z)||M&&M.includes(Z))&&i(b,Z,null,N[Z],void 0,T)}else if(N.onClick)i(b,"onClick",null,N.onClick,void 0,T);else if(I&4&&Ra(N.style))for(const P in N.style)N.style[P]}let W;(W=N&&N.onVnodeBeforeMount)&&zr(W,T,A),H&&Ta(A,null,T,"beforeMount"),((W=N&&N.onVnodeMounted)||H||$)&&QN(()=>{W&&zr(W,T,A),$&&O.enter(b),H&&Ta(A,null,T,"mounted")},S)}return b.nextSibling},p=(b,A,T,S,x,_,L)=>{L=L||!!A.dynamicChildren;const M=A.children,N=M.length;let I=!1;for(let z=0;z<N;z++){const H=L?M[z]:M[z]=Hr(M[z]),O=H.type===hc;b?(O&&!L&&z+1<N&&Hr(M[z+1]).type===hc&&(a(o(b.data.slice(H.children.length)),T,s(b)),b.data=H.children),b=d(b,H,S,x,_,L)):O&&!H.children?a(H.el=o(""),T):(I||(I=!0,pv(T,1)||Wf()),n(null,H,T,null,S,x,am(T),_))}return b},g=(b,A,T,S,x,_)=>{const{slotScopeIds:L}=A;L&&(x=x?x.concat(L):L);const M=r(b),N=p(s(b),A,M,T,S,x,_);return N&&fh(N)&&N.data==="]"?s(A.anchor=N):(Wf(),a(A.anchor=u("]"),M,N),N)},m=(b,A,T,S,x,_)=>{if(zq(b,A)||Wf(),A.el=null,_){const N=k(b);for(;;){const I=s(b);if(I&&I!==N)l(I);else break}}const L=s(b),M=r(b);return l(b),n(null,A,M,L,T,S,am(M),x),T&&(T.vnode.el=A.el,Yy(T,A.el)),L},k=(b,A="[",T="]")=>{let S=0;for(;b;)if(b=s(b),b&&fh(b)&&(b.data===A&&S++,b.data===T)){if(S===0)return s(b);S--}return b},w=(b,A,T)=>{const S=A.parentNode;S&&S.replaceChild(b,A);let x=T;for(;x;)x.vnode.el===A&&(x.vnode.el=x.subTree.el=b),x=x.parent},y=b=>b.nodeType===1&&b.tagName==="TEMPLATE";return[c,d]}const t2="data-allow-mismatch",Rq={0:"text",1:"children",2:"class",3:"style",4:"attribute"};function pv(e,t){if(t===0||t===1)for(;e&&!e.hasAttribute(t2);)e=e.parentElement;return P5(e&&e.getAttribute(t2),t)}function P5(e,t){if(e==null)return!1;if(e==="")return!0;{const n=e.split(",");return t===0&&n.includes("children")?!0:n.includes(Rq[t])}}function zq(e,t){return pv(e.parentElement,1)||Oq(e)||Pq(t)}function Oq(e){return e.nodeType===1&&P5(e.getAttribute(t2),1)}function Pq({props:e}){const t=e&&e[t2];return typeof t=="string"&&P5(t,1)}const jq=jy().requestIdleCallback||(e=>setTimeout(e,1)),Hq=jy().cancelIdleCallback||(e=>clearTimeout(e)),Iut=(e=1e4)=>t=>{const n=jq(t,{timeout:e});return()=>Hq(n)};function Wq(e){const{top:t,left:n,bottom:i,right:o}=e.getBoundingClientRect(),{innerHeight:s,innerWidth:r}=window;return(t>0&&t<s||i>0&&i<s)&&(n>0&&n<r||o>0&&o<r)}const Eut=e=>(t,n)=>{const i=new IntersectionObserver(o=>{for(const s of o)if(s.isIntersecting){i.disconnect(),t();break}},e);return n(o=>{if(o instanceof Element){if(Wq(o))return t(),i.disconnect(),!1;i.observe(o)}}),()=>i.disconnect()},Tut=e=>t=>{if(e){const n=matchMedia(e);if(n.matches)t();else return n.addEventListener("change",t,{once:!0}),()=>n.removeEventListener("change",t)}},Lut=(e=[])=>(t,n)=>{zi(e)&&(e=[e]);let i=!1;const o=r=>{i||(i=!0,s(),t(),r.target.dispatchEvent(new r.constructor(r.type,r)))},s=()=>{n(r=>{for(const l of e)r.removeEventListener(l,o)})};return n(r=>{for(const l of e)r.addEventListener(l,o,{once:!0})}),s};function qq(e,t){if(fh(e)&&e.data==="["){let n=1,i=e.nextSibling;for(;i;){if(i.nodeType===1){if(t(i)===!1)break}else if(fh(i))if(i.data==="]"){if(--n===0)break}else i.data==="["&&n++;i=i.nextSibling}}else t(e)}const yu=e=>!!e.type.__asyncLoader;function ia(e){xn(e)&&(e={loader:e});const{loader:t,loadingComponent:n,errorComponent:i,delay:o=200,hydrate:s,timeout:r,suspensible:l=!0,onError:a}=e;let u=null,c,d=0;const h=()=>(d++,u=null,p()),p=()=>{let g;return u||(g=u=t().catch(m=>{if(m=m instanceof Error?m:new Error(String(m)),a)return new Promise((k,w)=>{a(m,()=>k(h()),()=>w(m),d+1)});throw m}).then(m=>g!==u&&u?u:(m&&(m.__esModule||m[Symbol.toStringTag]==="Module")&&(m=m.default),c=m,m)))};return Xe({name:"AsyncComponentWrapper",__asyncLoader:p,__asyncHydrate(g,m,k){let w=!1;(m.bu||(m.bu=[])).push(()=>w=!0);const y=()=>{w||k()},b=s?()=>{const A=s(y,T=>qq(g,T));A&&(m.bum||(m.bum=[])).push(A)}:y;c?b():p().then(()=>!m.isUnmounted&&b())},get __asyncResolved(){return c},setup(){const g=Us;if(O5(g),c)return()=>um(c,g);const m=T=>{u=null,o1(T,g,13,!i)};if(l&&g.suspense||sf)return p().then(T=>()=>um(T,g)).catch(T=>(m(T),()=>i?U(i,{error:T}):null));const k=K(!1),w=K(),y=K(!!o);let b,A;return _n(()=>{b!=null&&clearTimeout(b),A!=null&&clearTimeout(A)}),o&&(A=setTimeout(()=>{g.isUnmounted||(y.value=!1)},o)),r!=null&&(b=setTimeout(()=>{if(!g.isUnmounted&&!k.value&&!w.value){const T=new Error(`Async component timed out after ${r}ms.`);m(T),w.value=T}},r)),p().then(()=>{g.isUnmounted||(k.value=!0,g.parent&&eg(g.parent.vnode)&&g.parent.update())}).catch(T=>{if(g.isUnmounted){u=null;return}m(T),w.value=T}),()=>{if(k.value&&c)return um(c,g);if(w.value&&i)return U(i,{error:w.value});if(n&&!y.value)return um(n,g)}}})}function um(e,t){const{ref:n,props:i,children:o,ce:s}=t.vnode,r=U(e,i,o);return r.ref=n,r.ce=s,delete t.vnode.ce,r}const eg=e=>e.type.__isKeepAlive,Uq={name:"KeepAlive",__isKeepAlive:!0,props:{include:[String,RegExp,Array],exclude:[String,RegExp,Array],max:[String,Number]},setup(e,{slots:t}){const n=os(),i=n.ctx;if(!i.renderer)return()=>{const y=t.default&&t.default();return y&&y.length===1?y[0]:y};const o=new Map,s=new Set;let r=null;const l=n.suspense,{renderer:{p:a,m:u,um:c,o:{createElement:d}}}=i,h=d("div");i.activate=(y,b,A,T,S)=>{const x=y.component;u(y,b,A,0,l),a(x.vnode,y,b,A,x,l,T,y.slotScopeIds,S),Zo(()=>{x.isDeactivated=!1,x.a&&wh(x.a);const _=y.props&&y.props.onVnodeMounted;_&&zr(_,x.parent,y)},l)},i.deactivate=y=>{const b=y.component;i2(b.m),i2(b.a),u(y,h,null,1,l),Zo(()=>{b.da&&wh(b.da);const A=y.props&&y.props.onVnodeUnmounted;A&&zr(A,b.parent,y),b.isDeactivated=!0},l)};function p(y){W4(y),c(y,n,l,!0)}function g(y){o.forEach((b,A)=>{const T=sb(yu(b)?b.type.__asyncResolved||{}:b.type);T&&!y(T)&&m(A)})}function m(y){const b=o.get(y);b&&(!r||!ea(b,r))?p(b):r&&W4(r),o.delete(y),s.delete(y)}Pe(()=>[e.include,e.exclude],([y,b])=>{y&&g(A=>ap(y,A)),b&&g(A=>!ap(b,A))},{flush:"post",deep:!0});let k=null;const w=()=>{k!=null&&(o2(n.subTree.type)?Zo(()=>{o.set(k,cm(n.subTree))},n.subTree.suspense):o.set(k,cm(n.subTree)))};return cn(w),s1(w),Hn(()=>{o.forEach(y=>{const{subTree:b,suspense:A}=n,T=cm(b);if(y.type===T.type&&y.key===T.key){W4(T);const S=T.component.da;S&&Zo(S,A);return}p(y)})}),()=>{if(k=null,!t.default)return r=null;const y=t.default(),b=y[0];if(y.length>1)return r=null,y;if(!Cc(b)||!(b.shapeFlag&4)&&!(b.shapeFlag&128))return r=null,b;let A=cm(b);if(A.type===Yo)return r=null,A;const T=A.type,S=sb(yu(A)?A.type.__asyncResolved||{}:T),{include:x,exclude:_,max:L}=e;if(x&&(!S||!ap(x,S))||_&&S&&ap(_,S))return A.shapeFlag&=-257,r=A,b;const M=A.key==null?T:A.key,N=o.get(M);return A.el&&(A=Su(A),b.shapeFlag&128&&(b.ssContent=A)),k=M,N?(A.el=N.el,A.component=N.component,A.transition&&Ac(A,A.transition),A.shapeFlag|=512,s.delete(M),s.add(M)):(s.add(M),L&&s.size>parseInt(L,10)&&m(s.values().next().value)),A.shapeFlag|=256,r=A,o2(b.type)?b:A}}},Nut=Uq;function ap(e,t){return tn(e)?e.some(n=>ap(n,t)):zi(e)?e.split(",").includes(t):MW(e)?(e.lastIndex=0,e.test(t)):!1}function Kq(e,t){MN(e,"a",t)}function Vq(e,t){MN(e,"da",t)}function MN(e,t,n=Us){const i=e.__wdc||(e.__wdc=()=>{let o=n;for(;o;){if(o.isDeactivated)return;o=o.parent}return e()});if(Gy(t,i,n),n){let o=n.parent;for(;o&&o.parent;)eg(o.parent.vnode)&&Zq(i,t,n,o),o=o.parent}}function Zq(e,t,n,i){const o=Gy(t,e,i,!0);_n(()=>{L5(i[t],o)},n)}function W4(e){e.shapeFlag&=-257,e.shapeFlag&=-513}function cm(e){return e.shapeFlag&128?e.ssContent:e}function Gy(e,t,n=Us,i=!1){if(n){const o=n[e]||(n[e]=[]),s=t.__weh||(t.__weh=(...r)=>{Pa();const l=l1(n),a=Rl(t,n,e,r);return l(),ja(),a});return i?o.unshift(s):o.push(s),s}}const Eu=e=>(t,n=Us)=>{(!sf||e==="sp")&&Gy(e,(...i)=>t(...i),n)},Gq=Eu("bm"),cn=Eu("m"),IN=Eu("bu"),s1=Eu("u"),Hn=Eu("bum"),_n=Eu("um"),Qq=Eu("sp"),Yq=Eu("rtg"),Jq=Eu("rtc");function Xq(e,t=Us){Gy("ec",e,t)}const j5="components",eU="directives";function tU(e,t){return H5(j5,e,!0,t)||e}const EN=Symbol.for("v-ndc");function Oo(e){return zi(e)?H5(j5,e,!1)||e:e||EN}function Fut(e){return H5(eU,e)}function H5(e,t,n=!0,i=!1){const o=Ks||Us;if(o){const s=o.type;if(e===j5){const l=sb(s,!1);if(l&&(l===t||l===ps(t)||l===Oy(ps(t))))return s}const r=tw(o[e]||s[e],t)||tw(o.appContext[e],t);return!r&&i?s:r}}function tw(e,t){return e&&(e[t]||e[ps(t)]||e[Oy(ps(t))])}function pt(e,t,n,i){let o;const s=n&&n[i],r=tn(e);if(r||zi(e)){const l=r&&Ra(e);let a=!1,u=!1;l&&(a=!ul(e),u=xu(e),e=qy(e)),o=new Array(e.length);for(let c=0,d=e.length;c<d;c++)o[c]=t(a?u?Uh(ua(e[c])):ua(e[c]):e[c],c,void 0,s&&s[c])}else if(typeof e=="number"){o=new Array(e);for(let l=0;l<e;l++)o[l]=t(l+1,l,void 0,s&&s[l])}else if(Ai(e))if(e[Symbol.iterator])o=Array.from(e,(l,a)=>t(l,a,void 0,s&&s[a]));else{const l=Object.keys(e);o=new Array(l.length);for(let a=0,u=l.length;a<u;a++){const c=l[a];o[a]=t(e[c],c,a,s&&s[a])}}else o=[];return n&&(n[i]=o),o}function TN(e,t){for(let n=0;n<t.length;n++){const i=t[n];if(tn(i))for(let o=0;o<i.length;o++)e[i[o].name]=i[o].fn;else i&&(e[i.name]=i.key?(...o)=>{const s=i.fn(...o);return s&&(s.key=i.key),s}:i.fn)}return e}function Rn(e,t,n={},i,o){if(Ks.ce||Ks.parent&&yu(Ks.parent)&&Ks.parent.ce){const u=Object.keys(n).length>0;return t!=="default"&&(n.name=t),v(),ce(Ee,null,[U("slot",n,i&&i())],u?-2:64)}let s=e[t];s&&s._c&&(s._d=!1),v();const r=s&&W5(s(n)),l=n.key||r&&r.key,a=ce(Ee,{key:(l&&!gl(l)?l:`_${t}`)+(!r&&i?"_fb":"")},r||(i?i():[]),r&&e._===1?64:-2);return!o&&a.scopeId&&(a.slotScopeIds=[a.scopeId+"-s"]),s&&s._c&&(s._d=!0),a}function W5(e){return e.some(t=>Cc(t)?!(t.type===Yo||t.type===Ee&&!W5(t.children)):!0)?e:null}function Dut(e,t){const n={};for(const i in e)n[t&&/[A-Z]/.test(i)?`on:${i}`:hv(i)]=e[i];return n}const Yk=e=>e?nF(e)?tg(e):Yk(e.parent):null,Fp=Ei(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Yk(e.parent),$root:e=>Yk(e.root),$host:e=>e.ce,$emit:e=>e.emit,$options:e=>q5(e),$forceUpdate:e=>e.f||(e.f=()=>{R5(e.update)}),$nextTick:e=>e.n||(e.n=dt.bind(e.proxy)),$watch:e=>Mq.bind(e)}),q4=(e,t)=>e!==Gn&&!e.__isScriptSetup&&ki(e,t),Jk={get({_:e},t){if(t==="__v_skip")return!0;const{ctx:n,setupState:i,data:o,props:s,accessCache:r,type:l,appContext:a}=e;if(t[0]!=="$"){const h=r[t];if(h!==void 0)switch(h){case 1:return i[t];case 2:return o[t];case 4:return n[t];case 3:return s[t]}else{if(q4(i,t))return r[t]=1,i[t];if(o!==Gn&&ki(o,t))return r[t]=2,o[t];if(ki(s,t))return r[t]=3,s[t];if(n!==Gn&&ki(n,t))return r[t]=4,n[t];Xk&&(r[t]=0)}}const u=Fp[t];let c,d;if(u)return t==="$attrs"&&nr(e.attrs,"get",""),u(e);if((c=l.__cssModules)&&(c=c[t]))return c;if(n!==Gn&&ki(n,t))return r[t]=4,n[t];if(d=a.config.globalProperties,ki(d,t))return d[t]},set({_:e},t,n){const{data:i,setupState:o,ctx:s}=e;return q4(o,t)?(o[t]=n,!0):i!==Gn&&ki(i,t)?(i[t]=n,!0):ki(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(s[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:i,appContext:o,props:s,type:r}},l){let a;return!!(n[l]||e!==Gn&&l[0]!=="$"&&ki(e,l)||q4(t,l)||ki(s,l)||ki(i,l)||ki(Fp,l)||ki(o.config.globalProperties,l)||(a=r.__cssModules)&&a[l])},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:ki(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}},nU=Ei({},Jk,{get(e,t){if(t!==Symbol.unscopables)return Jk.get(e,t,e)},has(e,t){return t[0]!=="_"&&!NW(t)}});function But(){return null}function $ut(){return null}function Rut(e){}function zut(e){}function Out(){return null}function Put(){}function jut(e,t){return null}function Hut(){return LN().slots}function r1(){return LN().attrs}function LN(e){const t=os();return t.setupContext||(t.setupContext=sF(t))}function m0(e){return tn(e)?e.reduce((t,n)=>(t[n]=null,t),{}):e}function Wut(e,t){const n=m0(e);for(const i in t){if(i.startsWith("__skip"))continue;let o=n[i];o?tn(o)||xn(o)?o=n[i]={type:o,default:t[i]}:o.default=t[i]:o===null&&(o=n[i]={default:t[i]}),o&&t[`__skip_${i}`]&&(o.skipFactory=!0)}return n}function qut(e,t){return!e||!t?e||t:tn(e)&&tn(t)?e.concat(t):Ei({},m0(e),m0(t))}function Uut(e,t){const n={};for(const i in e)t.includes(i)||Object.defineProperty(n,i,{enumerable:!0,get:()=>e[i]});return n}function Kut(e){const t=os(),n=sf;let i=e();y0(),n&&Ih(!1);const o=()=>{l1(t),n&&Ih(!0)},s=()=>{os()!==t&&t.scope.off(),y0(),n&&Ih(!1)};return N5(i)&&(i=i.catch(r=>{throw o(),Promise.resolve().then(()=>Promise.resolve().then(s)),r})),[i,()=>{o(),Promise.resolve().then(s)}]}let Xk=!0;function iU(e){const t=q5(e),n=e.proxy,i=e.ctx;Xk=!1,t.beforeCreate&&nw(t.beforeCreate,e,"bc");const{data:o,computed:s,methods:r,watch:l,provide:a,inject:u,created:c,beforeMount:d,mounted:h,beforeUpdate:p,updated:g,activated:m,deactivated:k,beforeDestroy:w,beforeUnmount:y,destroyed:b,unmounted:A,render:T,renderTracked:S,renderTriggered:x,errorCaptured:_,serverPrefetch:L,expose:M,inheritAttrs:N,components:I,directives:z,filters:H}=t;if(u&&oU(u,i,null),r)for(const j in r){const $=r[j];xn($)&&(i[j]=$.bind(n))}if(o){const j=o.call(n,n);Ai(j)&&(e.data=jo(j))}if(Xk=!0,s)for(const j in s){const $=s[j],W=xn($)?$.bind(n,n):xn($.get)?$.get.bind(n,n):Bl,P=!xn($)&&xn($.set)?$.set.bind(n):Bl,Z=F({get:W,set:P});Object.defineProperty(i,j,{enumerable:!0,configurable:!0,get:()=>Z.value,set:ae=>Z.value=ae})}if(l)for(const j in l)NN(l[j],i,n,j);if(a){const j=xn(a)?a.call(n):a;Reflect.ownKeys(j).forEach($=>{oi($,j[$])})}c&&nw(c,e,"c");function R(j,$){tn($)?$.forEach(W=>j(W.bind(n))):$&&j($.bind(n))}if(R(Gq,d),R(cn,h),R(IN,p),R(s1,g),R(Kq,m),R(Vq,k),R(Xq,_),R(Jq,S),R(Yq,x),R(Hn,y),R(_n,A),R(Qq,L),tn(M))if(M.length){const j=e.exposed||(e.exposed={});M.forEach($=>{Object.defineProperty(j,$,{get:()=>n[$],set:W=>n[$]=W,enumerable:!0})})}else e.exposed||(e.exposed={});T&&e.render===Bl&&(e.render=T),N!=null&&(e.inheritAttrs=N),I&&(e.components=I),z&&(e.directives=z),L&&O5(e)}function oU(e,t,n=Bl){tn(e)&&(e=eb(e));for(const i in e){const o=e[i];let s;Ai(o)?"default"in o?s=hn(o.from||i,o.default,!0):s=hn(o.from||i):s=hn(o),io(s)?Object.defineProperty(t,i,{enumerable:!0,configurable:!0,get:()=>s.value,set:r=>s.value=r}):t[i]=s}}function nw(e,t,n){Rl(tn(e)?e.map(i=>i.bind(t.proxy)):e.bind(t.proxy),t,n)}function NN(e,t,n,i){let o=i.includes(".")?kN(n,i):()=>n[i];if(zi(e)){const s=t[e];xn(s)&&Pe(o,s)}else if(xn(e))Pe(o,e.bind(n));else if(Ai(e))if(tn(e))e.forEach(s=>NN(s,t,n,i));else{const s=xn(e.handler)?e.handler.bind(n):t[e.handler];xn(s)&&Pe(o,s,e)}}function q5(e){const t=e.type,{mixins:n,extends:i}=t,{mixins:o,optionsCache:s,config:{optionMergeStrategies:r}}=e.appContext,l=s.get(t);let a;return l?a=l:!o.length&&!n&&!i?a=t:(a={},o.length&&o.forEach(u=>n2(a,u,r,!0)),n2(a,t,r)),Ai(t)&&s.set(t,a),a}function n2(e,t,n,i=!1){const{mixins:o,extends:s}=t;s&&n2(e,s,n,!0),o&&o.forEach(r=>n2(e,r,n,!0));for(const r in t)if(!(i&&r==="expose")){const l=sU[r]||n&&n[r];e[r]=l?l(e[r],t[r]):t[r]}return e}const sU={data:iw,props:ow,emits:ow,methods:up,computed:up,beforeCreate:dr,created:dr,beforeMount:dr,mounted:dr,beforeUpdate:dr,updated:dr,beforeDestroy:dr,beforeUnmount:dr,destroyed:dr,unmounted:dr,activated:dr,deactivated:dr,errorCaptured:dr,serverPrefetch:dr,components:up,directives:up,watch:lU,provide:iw,inject:rU};function iw(e,t){return t?e?function(){return Ei(xn(e)?e.call(this,this):e,xn(t)?t.call(this,this):t)}:t:e}function rU(e,t){return up(eb(e),eb(t))}function eb(e){if(tn(e)){const t={};for(let n=0;n<e.length;n++)t[e[n]]=e[n];return t}return e}function dr(e,t){return e?[...new Set([].concat(e,t))]:t}function up(e,t){return e?Ei(Object.create(null),e,t):t}function ow(e,t){return e?tn(e)&&tn(t)?[...new Set([...e,...t])]:Ei(Object.create(null),m0(e),m0(t??{})):t}function lU(e,t){if(!e)return t;if(!t)return e;const n=Ei(Object.create(null),e);for(const i in t)n[i]=dr(e[i],t[i]);return n}function FN(){return{app:null,config:{isNativeTag:HL,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let aU=0;function uU(e,t){return function(i,o=null){xn(i)||(i=Ei({},i)),o!=null&&!Ai(o)&&(o=null);const s=FN(),r=new WeakSet,l=[];let a=!1;const u=s.app={_uid:aU++,_component:i,_props:o,_container:null,_context:s,_instance:null,version:zU,get config(){return s.config},set config(c){},use(c,...d){return r.has(c)||(c&&xn(c.install)?(r.add(c),c.install(u,...d)):xn(c)&&(r.add(c),c(u,...d))),u},mixin(c){return s.mixins.includes(c)||s.mixins.push(c),u},component(c,d){return d?(s.components[c]=d,u):s.components[c]},directive(c,d){return d?(s.directives[c]=d,u):s.directives[c]},mount(c,d,h){if(!a){const p=u._ceVNode||U(i,o);return p.appContext=s,h===!0?h="svg":h===!1&&(h=void 0),d&&t?t(p,c):e(p,c,h),a=!0,u._container=c,c.__vue_app__=u,tg(p.component)}},onUnmount(c){l.push(c)},unmount(){a&&(Rl(l,u._instance,16),e(null,u._container),delete u._container.__vue_app__)},provide(c,d){return s.provides[c]=d,u},runWithContext(c){const d=Vd;Vd=u;try{return c()}finally{Vd=d}}};return u}}let Vd=null;function Vut(e,t,n=Gn){const i=os(),o=ps(t),s=Wr(t),r=DN(e,o),l=cq((a,u)=>{let c,d=Gn,h;return _q(()=>{const p=e[o];Ts(c,p)&&(c=p,u())}),{get(){return a(),n.get?n.get(c):c},set(p){const g=n.set?n.set(p):p;if(!Ts(g,c)&&!(d!==Gn&&Ts(p,d)))return;const m=i.vnode.props,k=!!(m&&(t in m||o in m||s in m)&&(`onUpdate:${t}`in m||`onUpdate:${o}`in m||`onUpdate:${s}`in m));k||(c=p,u()),i.emit(`update:${t}`,g),Ts(p,d)&&(Ts(p,g)&&!Ts(g,h)||k&&d!==Gn&&!Ts(g,c))&&u(),d=p,h=g}}});return l[Symbol.iterator]=()=>{let a=0;return{next(){return a<2?{value:a++?r||Gn:l,done:!1}:{done:!0}}}},l}const DN=(e,t)=>t==="modelValue"||t==="model-value"?e.modelModifiers:e[`${t}Modifiers`]||e[`${ps(t)}Modifiers`]||e[`${Wr(t)}Modifiers`];function cU(e,t,...n){if(e.isUnmounted)return;const i=e.vnode.props||Gn;let o=n;const s=t.startsWith("update:"),r=s&&DN(i,t.slice(7));r&&(r.trim&&(o=n.map(c=>zi(c)?c.trim():c)),r.number&&(o=n.map(Py)));let l,a=i[l=hv(t)]||i[l=hv(ps(t))];!a&&s&&(a=i[l=hv(Wr(t))]),a&&Rl(a,e,6,o);const u=i[l+"Once"];if(u){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,Rl(u,e,6,o)}}const dU=new WeakMap;function BN(e,t,n=!1){const i=n?dU:t.emitsCache,o=i.get(e);if(o!==void 0)return o;const s=e.emits;let r={},l=!1;if(!xn(e)){const a=u=>{const c=BN(u,t,!0);c&&(l=!0,Ei(r,c))};!n&&t.mixins.length&&t.mixins.forEach(a),e.extends&&a(e.extends),e.mixins&&e.mixins.forEach(a)}return!s&&!l?(Ai(e)&&i.set(e,null),null):(tn(s)?s.forEach(a=>r[a]=null):Ei(r,s),Ai(e)&&i.set(e,r),r)}function Qy(e,t){return!e||!Q0(t)?!1:(t=t.slice(2),t=t==="Once"?t:t.replace(/Once$/,""),ki(e,t[0].toLowerCase()+t.slice(1))||ki(e,Wr(t))||ki(e,t))}function gv(e){const{type:t,vnode:n,proxy:i,withProxy:o,propsOptions:[s],slots:r,attrs:l,emit:a,render:u,renderCache:c,props:d,data:h,setupState:p,ctx:g,inheritAttrs:m}=e,k=p0(e);let w,y;try{if(n.shapeFlag&4){const A=o||i,T=A;w=Hr(u.call(T,A,c,d,p,h,g)),y=l}else{const A=t;w=Hr(A.length>1?A(d,{attrs:l,slots:r,emit:a}):A(d,null)),y=t.props?l:hU(l)}}catch(A){Dp.length=0,o1(A,e,1),w=U(Yo)}let b=w;if(y&&m!==!1){const A=Object.keys(y),{shapeFlag:T}=b;A.length&&T&7&&(s&&A.some(By)&&(y=pU(y,s)),b=Su(b,y,!1,!0))}return n.dirs&&(b=Su(b,null,!1,!0),b.dirs=b.dirs?b.dirs.concat(n.dirs):n.dirs),n.transition&&Ac(b,n.transition),w=b,p0(k),w}function fU(e,t=!0){let n;for(let i=0;i<e.length;i++){const o=e[i];if(Cc(o)){if(o.type!==Yo||o.children==="v-if"){if(n)return;n=o}}else return}return n}const hU=e=>{let t;for(const n in e)(n==="class"||n==="style"||Q0(n))&&((t||(t={}))[n]=e[n]);return t},pU=(e,t)=>{const n={};for(const i in e)(!By(i)||!(i.slice(9)in t))&&(n[i]=e[i]);return n};function gU(e,t,n){const{props:i,children:o,component:s}=e,{props:r,children:l,patchFlag:a}=t,u=s.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&a>=0){if(a&1024)return!0;if(a&16)return i?sw(i,r,u):!!r;if(a&8){const c=t.dynamicProps;for(let d=0;d<c.length;d++){const h=c[d];if($N(r,i,h)&&!Qy(u,h))return!0}}}else return(o||l)&&(!l||!l.$stable)?!0:i===r?!1:i?r?sw(i,r,u):!0:!!r;return!1}function sw(e,t,n){const i=Object.keys(t);if(i.length!==Object.keys(e).length)return!0;for(let o=0;o<i.length;o++){const s=i[o];if($N(t,e,s)&&!Qy(n,s))return!0}return!1}function $N(e,t,n){const i=e[n],o=t[n];return n==="style"&&Ai(i)&&Ai(o)?!wu(i,o):i!==o}function Yy({vnode:e,parent:t,suspense:n},i){for(;t;){const o=t.subTree;if(o.suspense&&o.suspense.activeBranch===e&&(o.suspense.vnode.el=o.el=i,e=o),o===e)(e=t.vnode).el=i,t=t.parent;else break}n&&n.activeBranch===e&&(n.vnode.el=i)}const RN={},zN=()=>Object.create(RN),ON=e=>Object.getPrototypeOf(e)===RN;function mU(e,t,n,i=!1){const o={},s=zN();e.propsDefaults=Object.create(null),PN(e,t,o,s);for(const r in e.propsOptions[0])r in o||(o[r]=void 0);n?e.props=i?o:cN(o):e.type.props?e.props=o:e.props=s,e.attrs=s}function vU(e,t,n,i){const{props:o,attrs:s,vnode:{patchFlag:r}}=e,l=si(o),[a]=e.propsOptions;let u=!1;if((i||r>0)&&!(r&16)){if(r&8){const c=e.vnode.dynamicProps;for(let d=0;d<c.length;d++){let h=c[d];if(Qy(e.emitsOptions,h))continue;const p=t[h];if(a)if(ki(s,h))p!==s[h]&&(s[h]=p,u=!0);else{const g=ps(h);o[g]=tb(a,l,g,p,e,!1)}else p!==s[h]&&(s[h]=p,u=!0)}}}else{PN(e,t,o,s)&&(u=!0);let c;for(const d in l)(!t||!ki(t,d)&&((c=Wr(d))===d||!ki(t,c)))&&(a?n&&(n[d]!==void 0||n[c]!==void 0)&&(o[d]=tb(a,l,d,void 0,e,!0)):delete o[d]);if(s!==l)for(const d in s)(!t||!ki(t,d))&&(delete s[d],u=!0)}u&&uu(e.attrs,"set","")}function PN(e,t,n,i){const[o,s]=e.propsOptions;let r=!1,l;if(t)for(let a in t){if(Ud(a))continue;const u=t[a];let c;o&&ki(o,c=ps(a))?!s||!s.includes(c)?n[c]=u:(l||(l={}))[c]=u:Qy(e.emitsOptions,a)||(!(a in i)||u!==i[a])&&(i[a]=u,r=!0)}if(s){const a=si(n),u=l||Gn;for(let c=0;c<s.length;c++){const d=s[c];n[d]=tb(o,a,d,u[d],e,!ki(u,d))}}return r}function tb(e,t,n,i,o,s){const r=e[n];if(r!=null){const l=ki(r,"default");if(l&&i===void 0){const a=r.default;if(r.type!==Function&&!r.skipFactory&&xn(a)){const{propsDefaults:u}=o;if(n in u)i=u[n];else{const c=l1(o);i=u[n]=a.call(null,t),c()}}else i=a;o.ce&&o.ce._setProp(n,i)}r[0]&&(s&&!l?i=!1:r[1]&&(i===""||i===Wr(n))&&(i=!0))}return i}const yU=new WeakMap;function jN(e,t,n=!1){const i=n?yU:t.propsCache,o=i.get(e);if(o)return o;const s=e.props,r={},l=[];let a=!1;if(!xn(e)){const c=d=>{a=!0;const[h,p]=jN(d,t,!0);Ei(r,h),p&&l.push(...p)};!n&&t.mixins.length&&t.mixins.forEach(c),e.extends&&c(e.extends),e.mixins&&e.mixins.forEach(c)}if(!s&&!a)return Ai(e)&&i.set(e,Ah),Ah;if(tn(s))for(let c=0;c<s.length;c++){const d=ps(s[c]);rw(d)&&(r[d]=Gn)}else if(s)for(const c in s){const d=ps(c);if(rw(d)){const h=s[c],p=r[d]=tn(h)||xn(h)?{type:h}:Ei({},h),g=p.type;let m=!1,k=!0;if(tn(g))for(let w=0;w<g.length;++w){const y=g[w],b=xn(y)&&y.name;if(b==="Boolean"){m=!0;break}else b==="String"&&(k=!1)}else m=xn(g)&&g.name==="Boolean";p[0]=m,p[1]=k,(m||ki(p,"default"))&&l.push(d)}}const u=[r,l];return Ai(e)&&i.set(e,u),u}function rw(e){return e[0]!=="$"&&!Ud(e)}const U5=e=>e==="_"||e==="_ctx"||e==="$stable",K5=e=>tn(e)?e.map(Hr):[Hr(e)],kU=(e,t,n)=>{if(t._n)return t;const i=de((...o)=>K5(t(...o)),n);return i._c=!1,i},HN=(e,t,n)=>{const i=e._ctx;for(const o in e){if(U5(o))continue;const s=e[o];if(xn(s))t[o]=kU(o,s,i);else if(s!=null){const r=K5(s);t[o]=()=>r}}},WN=(e,t)=>{const n=K5(t);e.slots.default=()=>n},qN=(e,t,n)=>{for(const i in t)(n||!U5(i))&&(e[i]=t[i])},bU=(e,t,n)=>{const i=e.slots=zN();if(e.vnode.shapeFlag&32){const o=t._;o?(qN(i,t,n),n&&qL(i,"_",o,!0)):HN(t,i)}else t&&WN(e,t)},AU=(e,t,n)=>{const{vnode:i,slots:o}=e;let s=!0,r=Gn;if(i.shapeFlag&32){const l=t._;l?n&&l===1?s=!1:qN(o,t,n):(s=!t.$stable,HN(t,o)),r=t}else t&&(WN(e,t),r={default:1});if(s)for(const l in o)!U5(l)&&r[l]==null&&delete o[l]},Zo=QN;function CU(e){return UN(e)}function wU(e){return UN(e,$q)}function UN(e,t){const n=jy();n.__VUE__=!0;const{insert:i,remove:o,patchProp:s,createElement:r,createText:l,createComment:a,setText:u,setElementText:c,parentNode:d,nextSibling:h,setScopeId:p=Bl,insertStaticContent:g}=e,m=(Q,ue,Ae,se=null,re=null,G=null,le=void 0,ge=null,ke=!!ue.dynamicChildren)=>{if(Q===ue)return;Q&&!ea(Q,ue)&&(se=ne(Q),ae(Q,re,G,!0),Q=null),ue.patchFlag===-2&&(ke=!1,ue.dynamicChildren=null);const{type:Ie,ref:Oe,shapeFlag:we}=ue;switch(Ie){case hc:k(Q,ue,Ae,se);break;case Yo:w(Q,ue,Ae,se);break;case Mh:Q==null&&y(ue,Ae,se,le);break;case Ee:I(Q,ue,Ae,se,re,G,le,ge,ke);break;default:we&1?T(Q,ue,Ae,se,re,G,le,ge,ke):we&6?z(Q,ue,Ae,se,re,G,le,ge,ke):(we&64||we&128)&&Ie.process(Q,ue,Ae,se,re,G,le,ge,ke,Ne)}Oe!=null&&re?Sh(Oe,Q&&Q.ref,G,ue||Q,!ue):Oe==null&&Q&&Q.ref!=null&&Sh(Q.ref,null,G,Q,!0)},k=(Q,ue,Ae,se)=>{if(Q==null)i(ue.el=l(ue.children),Ae,se);else{const re=ue.el=Q.el;ue.children!==Q.children&&u(re,ue.children)}},w=(Q,ue,Ae,se)=>{Q==null?i(ue.el=a(ue.children||""),Ae,se):ue.el=Q.el},y=(Q,ue,Ae,se)=>{[Q.el,Q.anchor]=g(Q.children,ue,Ae,se,Q.el,Q.anchor)},b=({el:Q,anchor:ue},Ae,se)=>{let re;for(;Q&&Q!==ue;)re=h(Q),i(Q,Ae,se),Q=re;i(ue,Ae,se)},A=({el:Q,anchor:ue})=>{let Ae;for(;Q&&Q!==ue;)Ae=h(Q),o(Q),Q=Ae;o(ue)},T=(Q,ue,Ae,se,re,G,le,ge,ke)=>{if(ue.type==="svg"?le="svg":ue.type==="math"&&(le="mathml"),Q==null)S(ue,Ae,se,re,G,le,ge,ke);else{const Ie=Q.el&&Q.el._isVueCE?Q.el:null;try{Ie&&Ie._beginPatch(),L(Q,ue,re,G,le,ge,ke)}finally{Ie&&Ie._endPatch()}}},S=(Q,ue,Ae,se,re,G,le,ge)=>{let ke,Ie;const{props:Oe,shapeFlag:we,transition:Be,dirs:tt}=Q;if(ke=Q.el=r(Q.type,G,Oe&&Oe.is,Oe),we&8?c(ke,Q.children):we&16&&_(Q.children,ke,null,se,re,U4(Q,G),le,ge),tt&&Ta(Q,null,se,"created"),x(ke,Q,Q.scopeId,le,se),Oe){for(const _t in Oe)_t!=="value"&&!Ud(_t)&&s(ke,_t,null,Oe[_t],G,se);"value"in Oe&&s(ke,"value",null,Oe.value,G),(Ie=Oe.onVnodeBeforeMount)&&zr(Ie,se,Q)}tt&&Ta(Q,null,se,"beforeMount");const ut=KN(re,Be);ut&&Be.beforeEnter(ke),i(ke,ue,Ae),((Ie=Oe&&Oe.onVnodeMounted)||ut||tt)&&Zo(()=>{try{Ie&&zr(Ie,se,Q),ut&&Be.enter(ke),tt&&Ta(Q,null,se,"mounted")}finally{}},re)},x=(Q,ue,Ae,se,re)=>{if(Ae&&p(Q,Ae),se)for(let G=0;G<se.length;G++)p(Q,se[G]);if(re){let G=re.subTree;if(ue===G||o2(G.type)&&(G.ssContent===ue||G.ssFallback===ue)){const le=re.vnode;x(Q,le,le.scopeId,le.slotScopeIds,re.parent)}}},_=(Q,ue,Ae,se,re,G,le,ge,ke=0)=>{for(let Ie=ke;Ie<Q.length;Ie++){const Oe=Q[Ie]=ge?au(Q[Ie]):Hr(Q[Ie]);m(null,Oe,ue,Ae,se,re,G,le,ge)}},L=(Q,ue,Ae,se,re,G,le)=>{const ge=ue.el=Q.el;let{patchFlag:ke,dynamicChildren:Ie,dirs:Oe}=ue;ke|=Q.patchFlag&16;const we=Q.props||Gn,Be=ue.props||Gn;let tt;if(Ae&&ud(Ae,!1),(tt=Be.onVnodeBeforeUpdate)&&zr(tt,Ae,ue,Q),Oe&&Ta(ue,Q,Ae,"beforeUpdate"),Ae&&ud(Ae,!0),Ie&&(!Q.dynamicChildren||Q.dynamicChildren.length!==Ie.length)&&(ke=0,le=!1,Ie=null),(we.innerHTML&&Be.innerHTML==null||we.textContent&&Be.textContent==null)&&c(ge,""),Ie?M(Q.dynamicChildren,Ie,ge,Ae,se,U4(ue,re),G):le||$(Q,ue,ge,null,Ae,se,U4(ue,re),G,!1),ke>0){if(ke&16)N(ge,we,Be,Ae,re);else if(ke&2&&we.class!==Be.class&&s(ge,"class",null,Be.class,re),ke&4&&s(ge,"style",we.style,Be.style,re),ke&8){const ut=ue.dynamicProps;for(let _t=0;_t<ut.length;_t++){const Ct=ut[_t],$t=we[Ct],Vt=Be[Ct];(Vt!==$t||Ct==="value")&&s(ge,Ct,$t,Vt,re,Ae)}}ke&1&&Q.children!==ue.children&&c(ge,ue.children)}else!le&&Ie==null&&N(ge,we,Be,Ae,re);((tt=Be.onVnodeUpdated)||Oe)&&Zo(()=>{tt&&zr(tt,Ae,ue,Q),Oe&&Ta(ue,Q,Ae,"updated")},se)},M=(Q,ue,Ae,se,re,G,le)=>{for(let ge=0;ge<ue.length;ge++){const ke=Q[ge],Ie=ue[ge],Oe=ke.el&&(ke.type===Ee||!ea(ke,Ie)||ke.shapeFlag&198)?d(ke.el):Ae;m(ke,Ie,Oe,null,se,re,G,le,!0)}},N=(Q,ue,Ae,se,re)=>{if(ue!==Ae){if(ue!==Gn)for(const G in ue)!Ud(G)&&!(G in Ae)&&s(Q,G,ue[G],null,re,se);for(const G in Ae){if(Ud(G))continue;const le=Ae[G],ge=ue[G];le!==ge&&G!=="value"&&s(Q,G,ge,le,re,se)}"value"in Ae&&s(Q,"value",ue.value,Ae.value,re)}},I=(Q,ue,Ae,se,re,G,le,ge,ke)=>{const Ie=ue.el=Q?Q.el:l(""),Oe=ue.anchor=Q?Q.anchor:l("");let{patchFlag:we,dynamicChildren:Be,slotScopeIds:tt}=ue;tt&&(ge=ge?ge.concat(tt):tt),Q==null?(i(Ie,Ae,se),i(Oe,Ae,se),_(ue.children||[],Ae,Oe,re,G,le,ge,ke)):we>0&&we&64&&Be&&Q.dynamicChildren&&Q.dynamicChildren.length===Be.length?(M(Q.dynamicChildren,Be,Ae,re,G,le,ge),(ue.key!=null||re&&ue===re.subTree)&&V5(Q,ue,!0)):$(Q,ue,Ae,Oe,re,G,le,ge,ke)},z=(Q,ue,Ae,se,re,G,le,ge,ke)=>{ue.slotScopeIds=ge,Q==null?ue.shapeFlag&512?re.ctx.activate(ue,Ae,se,le,ke):H(ue,Ae,se,re,G,le,ke):O(Q,ue,ke)},H=(Q,ue,Ae,se,re,G,le)=>{const ge=Q.component=tF(Q,se,re);if(eg(Q)&&(ge.ctx.renderer=Ne),iF(ge,!1,le),ge.asyncDep){if(re&&re.registerDep(ge,R,le),!Q.el){const ke=ge.subTree=U(Yo);w(null,ke,ue,Ae),Q.placeholder=ke.el}}else R(ge,Q,ue,Ae,re,G,le)},O=(Q,ue,Ae)=>{const se=ue.component=Q.component;if(gU(Q,ue,Ae))if(se.asyncDep&&!se.asyncResolved){j(se,ue,Ae);return}else se.next=ue,se.update();else ue.el=Q.el,se.vnode=ue},R=(Q,ue,Ae,se,re,G,le)=>{const ge=()=>{if(Q.isMounted){let{next:we,bu:Be,u:tt,parent:ut,vnode:_t}=Q;{const gt=VN(Q);if(gt){we&&(we.el=_t.el,j(Q,we,le)),gt.asyncDep.then(()=>{Zo(()=>{Q.isUnmounted||Ie()},re)});return}}let Ct=we,$t;ud(Q,!1),we?(we.el=_t.el,j(Q,we,le)):we=_t,Be&&wh(Be),($t=we.props&&we.props.onVnodeBeforeUpdate)&&zr($t,ut,we,_t),ud(Q,!0);const Vt=gv(Q),nn=Q.subTree;Q.subTree=Vt,m(nn,Vt,d(nn.el),ne(nn),Q,re,G),we.el=Vt.el,Ct===null&&Yy(Q,Vt.el),tt&&Zo(tt,re),($t=we.props&&we.props.onVnodeUpdated)&&Zo(()=>zr($t,ut,we,_t),re)}else{let we;const{el:Be,props:tt}=ue,{bm:ut,m:_t,parent:Ct,root:$t,type:Vt}=Q,nn=yu(ue);if(ud(Q,!1),ut&&wh(ut),!nn&&(we=tt&&tt.onVnodeBeforeMount)&&zr(we,Ct,ue),ud(Q,!0),Be&&be){const gt=()=>{Q.subTree=gv(Q),be(Be,Q.subTree,Q,re,null)};nn&&Vt.__asyncHydrate?Vt.__asyncHydrate(Be,Q,gt):gt()}else{$t.ce&&$t.ce._hasShadowRoot()&&$t.ce._injectChildStyle(Vt,Q.parent?Q.parent.type:void 0);const gt=Q.subTree=gv(Q);m(null,gt,Ae,se,Q,re,G),ue.el=gt.el}if(_t&&Zo(_t,re),!nn&&(we=tt&&tt.onVnodeMounted)){const gt=ue;Zo(()=>zr(we,Ct,gt),re)}(ue.shapeFlag&256||Ct&&yu(Ct.vnode)&&Ct.vnode.shapeFlag&256)&&Q.a&&Zo(Q.a,re),Q.isMounted=!0,ue=Ae=se=null}};Q.scope.on();const ke=Q.effect=new Zv(ge);Q.scope.off();const Ie=Q.update=ke.run.bind(ke),Oe=Q.job=ke.runIfDirty.bind(ke);Oe.i=Q,Oe.id=Q.uid,ke.scheduler=()=>R5(Oe),ud(Q,!0),Ie()},j=(Q,ue,Ae)=>{ue.component=Q;const se=Q.vnode.props;Q.vnode=ue,Q.next=null,vU(Q,ue.props,se,Ae),AU(Q,ue.children,Ae),Pa(),ZC(Q),ja()},$=(Q,ue,Ae,se,re,G,le,ge,ke=!1)=>{const Ie=Q&&Q.children,Oe=Q?Q.shapeFlag:0,we=ue.children,{patchFlag:Be,shapeFlag:tt}=ue;if(Be>0){if(Be&128){P(Ie,we,Ae,se,re,G,le,ge,ke);return}else if(Be&256){W(Ie,we,Ae,se,re,G,le,ge,ke);return}}tt&8?(Oe&16&&q(Ie,re,G),we!==Ie&&c(Ae,we)):Oe&16?tt&16?P(Ie,we,Ae,se,re,G,le,ge,ke):q(Ie,re,G,!0):(Oe&8&&c(Ae,""),tt&16&&_(we,Ae,se,re,G,le,ge,ke))},W=(Q,ue,Ae,se,re,G,le,ge,ke)=>{Q=Q||Ah,ue=ue||Ah;const Ie=Q.length,Oe=ue.length,we=Math.min(Ie,Oe);let Be;for(Be=0;Be<we;Be++){const tt=ue[Be]=ke?au(ue[Be]):Hr(ue[Be]);m(Q[Be],tt,Ae,null,re,G,le,ge,ke)}Ie>Oe?q(Q,re,G,!0,!1,we):_(ue,Ae,se,re,G,le,ge,ke,we)},P=(Q,ue,Ae,se,re,G,le,ge,ke)=>{let Ie=0;const Oe=ue.length;let we=Q.length-1,Be=Oe-1;for(;Ie<=we&&Ie<=Be;){const tt=Q[Ie],ut=ue[Ie]=ke?au(ue[Ie]):Hr(ue[Ie]);if(ea(tt,ut))m(tt,ut,Ae,null,re,G,le,ge,ke);else break;Ie++}for(;Ie<=we&&Ie<=Be;){const tt=Q[we],ut=ue[Be]=ke?au(ue[Be]):Hr(ue[Be]);if(ea(tt,ut))m(tt,ut,Ae,null,re,G,le,ge,ke);else break;we--,Be--}if(Ie>we){if(Ie<=Be){const tt=Be+1,ut=tt<Oe?ue[tt].el:se;for(;Ie<=Be;)m(null,ue[Ie]=ke?au(ue[Ie]):Hr(ue[Ie]),Ae,ut,re,G,le,ge,ke),Ie++}}else if(Ie>Be)for(;Ie<=we;)ae(Q[Ie],re,G,!0),Ie++;else{const tt=Ie,ut=Ie,_t=new Map;for(Ie=ut;Ie<=Be;Ie++){const Ye=ue[Ie]=ke?au(ue[Ie]):Hr(ue[Ie]);Ye.key!=null&&_t.set(Ye.key,Ie)}let Ct,$t=0;const Vt=Be-ut+1;let nn=!1,gt=0;const Le=new Array(Vt);for(Ie=0;Ie<Vt;Ie++)Le[Ie]=0;for(Ie=tt;Ie<=we;Ie++){const Ye=Q[Ie];if($t>=Vt){ae(Ye,re,G,!0);continue}let Tt;if(Ye.key!=null)Tt=_t.get(Ye.key);else for(Ct=ut;Ct<=Be;Ct++)if(Le[Ct-ut]===0&&ea(Ye,ue[Ct])){Tt=Ct;break}Tt===void 0?ae(Ye,re,G,!0):(Le[Tt-ut]=Ie+1,Tt>=gt?gt=Tt:nn=!0,m(Ye,ue[Tt],Ae,null,re,G,le,ge,ke),$t++)}const ze=nn?xU(Le):Ah;for(Ct=ze.length-1,Ie=Vt-1;Ie>=0;Ie--){const Ye=ut+Ie,Tt=ue[Ye],on=ue[Ye+1],jt=Ye+1<Oe?on.el||ZN(on):se;Le[Ie]===0?m(null,Tt,Ae,jt,re,G,le,ge,ke):nn&&(Ct<0||Ie!==ze[Ct]?Z(Tt,Ae,jt,2):Ct--)}}},Z=(Q,ue,Ae,se,re=null)=>{const{el:G,type:le,transition:ge,children:ke,shapeFlag:Ie}=Q;if(Ie&6){Z(Q.component.subTree,ue,Ae,se);return}if(Ie&128){Q.suspense.move(ue,Ae,se);return}if(Ie&64){le.move(Q,ue,Ae,Ne);return}if(le===Ee){i(G,ue,Ae);for(let we=0;we<ke.length;we++)Z(ke[we],ue,Ae,se);i(Q.anchor,ue,Ae);return}if(le===Mh){b(Q,ue,Ae);return}if(se!==2&&Ie&1&&ge)if(se===0)ge.persisted&&!G[Il]?i(G,ue,Ae):(ge.beforeEnter(G),i(G,ue,Ae),Zo(()=>ge.enter(G),re));else{const{leave:we,delayLeave:Be,afterLeave:tt}=ge,ut=()=>{Q.ctx.isUnmounted?o(G):i(G,ue,Ae)},_t=()=>{const Ct=G._isLeaving||!!G[Il];G._isLeaving&&G[Il](!0),ge.persisted&&!Ct?ut():we(G,()=>{ut(),tt&&tt()})};Be?Be(G,ut,_t):_t()}else i(G,ue,Ae)},ae=(Q,ue,Ae,se=!1,re=!1)=>{const{type:G,props:le,ref:ge,children:ke,dynamicChildren:Ie,shapeFlag:Oe,patchFlag:we,dirs:Be,cacheIndex:tt,memo:ut}=Q;if(we===-2&&(re=!1),ge!=null&&(Pa(),Sh(ge,null,Ae,Q,!0),ja()),tt!=null&&(ue.renderCache[tt]=void 0),Oe&256){ue.ctx.deactivate(Q);return}const _t=Oe&1&&Be,Ct=!yu(Q);let $t;if(Ct&&($t=le&&le.onVnodeBeforeUnmount)&&zr($t,ue,Q),Oe&6)oe(Q.component,Ae,se);else{if(Oe&128){Q.suspense.unmount(Ae,se);return}_t&&Ta(Q,null,ue,"beforeUnmount"),Oe&64?Q.type.remove(Q,ue,Ae,Ne,se):Ie&&!Ie.hasOnce&&(G!==Ee||we>0&&we&64)?q(Ie,ue,Ae,!1,!0):(G===Ee&&we&384||!re&&Oe&16)&&q(ke,ue,Ae),se&&V(Q)}const Vt=ut!=null&&tt==null;(Ct&&($t=le&&le.onVnodeUnmounted)||_t||Vt)&&Zo(()=>{$t&&zr($t,ue,Q),_t&&Ta(Q,null,ue,"unmounted"),Vt&&(Q.el=null)},Ae)},V=Q=>{const{type:ue,el:Ae,anchor:se,transition:re}=Q;if(ue===Ee){Y(Ae,se);return}if(ue===Mh){A(Q);return}const G=()=>{o(Ae),re&&!re.persisted&&re.afterLeave&&re.afterLeave()};if(Q.shapeFlag&1&&re&&!re.persisted){const{leave:le,delayLeave:ge}=re,ke=()=>le(Ae,G);ge?ge(Q.el,G,ke):ke()}else G()},Y=(Q,ue)=>{let Ae;for(;Q!==ue;)Ae=h(Q),o(Q),Q=Ae;o(ue)},oe=(Q,ue,Ae)=>{const{bum:se,scope:re,job:G,subTree:le,um:ge,m:ke,a:Ie}=Q;i2(ke),i2(Ie),se&&wh(se),re.stop(),G&&(G.flags|=8,ae(le,Q,ue,Ae)),ge&&Zo(ge,ue),Zo(()=>{Q.isUnmounted=!0},ue)},q=(Q,ue,Ae,se=!1,re=!1,G=0)=>{for(let le=G;le<Q.length;le++)ae(Q[le],ue,Ae,se,re)},ne=Q=>{if(Q.shapeFlag&6)return ne(Q.component.subTree);if(Q.shapeFlag&128)return Q.suspense.next();const ue=h(Q.anchor||Q.el),Ae=ue&&ue[bN];return Ae?h(Ae):ue};let ie=!1;const pe=(Q,ue,Ae)=>{let se;Q==null?ue._vnode&&(ae(ue._vnode,null,null,!0),se=ue._vnode.component):m(ue._vnode||null,Q,ue,null,null,null,Ae),ue._vnode=Q,ie||(ie=!0,ZC(se),Xv(),ie=!1)},Ne={p:m,um:ae,m:Z,r:V,mt:H,mc:_,pc:$,pbc:M,n:ne,o:e};let te,be;return t&&([te,be]=t(Ne)),{render:pe,hydrate:te,createApp:uU(pe,te)}}function U4({type:e,props:t},n){return n==="svg"&&e==="foreignObject"||n==="mathml"&&e==="annotation-xml"&&t&&t.encoding&&t.encoding.includes("html")?void 0:n}function ud({effect:e,job:t},n){n?(e.flags|=32,t.flags|=4):(e.flags&=-33,t.flags&=-5)}function KN(e,t){return(!e||e&&!e.pendingBranch)&&t&&!t.persisted}function V5(e,t,n=!1){const i=e.children,o=t.children;if(tn(i)&&tn(o))for(let s=0;s<i.length;s++){const r=i[s];let l=o[s];l.shapeFlag&1&&!l.dynamicChildren&&((l.patchFlag<=0||l.patchFlag===32)&&(l=o[s]=au(o[s]),l.el=r.el),!n&&l.patchFlag!==-2&&V5(r,l)),l.type===hc&&(l.patchFlag===-1&&(l=o[s]=au(l)),l.el=r.el),l.type===Yo&&!l.el&&(l.el=r.el)}}function xU(e){const t=e.slice(),n=[0];let i,o,s,r,l;const a=e.length;for(i=0;i<a;i++){const u=e[i];if(u!==0){if(o=n[n.length-1],e[o]<u){t[i]=o,n.push(i);continue}for(s=0,r=n.length-1;s<r;)l=s+r>>1,e[n[l]]<u?s=l+1:r=l;u<e[n[s]]&&(s>0&&(t[i]=n[s-1]),n[s]=i)}}for(s=n.length,r=n[s-1];s-- >0;)n[s]=r,r=t[r];return n}function VN(e){const t=e.subTree.component;if(t)return t.asyncDep&&!t.asyncResolved?t:VN(t)}function i2(e){if(e)for(let t=0;t<e.length;t++)e[t].flags|=8}function ZN(e){if(e.placeholder)return e.placeholder;const t=e.component;return t?ZN(t.subTree):null}const o2=e=>e.__isSuspense;let nb=0;const SU={name:"Suspense",__isSuspense:!0,process(e,t,n,i,o,s,r,l,a,u){if(e==null)_U(t,n,i,o,s,r,l,a,u);else{if(s&&s.deps>0&&!e.suspense.isInFallback){t.suspense=e.suspense,t.suspense.vnode=t,t.el=e.el;return}MU(e,t,n,i,o,r,l,a,u)}},hydrate:IU,normalize:EU},Zut=SU;function v0(e,t){const n=e.props&&e.props[t];xn(n)&&n()}function _U(e,t,n,i,o,s,r,l,a){const{p:u,o:{createElement:c}}=a,d=c("div"),h=e.suspense=GN(e,o,i,t,d,n,s,r,l,a);u(null,h.pendingBranch=e.ssContent,d,null,i,h,s,r),h.deps>0?(v0(e,"onPending"),v0(e,"onFallback"),u(null,e.ssFallback,t,n,i,null,s,r),_h(h,e.ssFallback)):h.resolve(!1,!0)}function MU(e,t,n,i,o,s,r,l,{p:a,um:u,o:{createElement:c}}){const d=t.suspense=e.suspense;d.vnode=t,t.el=e.el;const h=t.ssContent,p=t.ssFallback,{activeBranch:g,pendingBranch:m,isInFallback:k,isHydrating:w}=d;if(m)d.pendingBranch=h,ea(m,h)?(a(m,h,d.hiddenContainer,null,o,d,s,r,l),d.deps<=0?d.resolve():k&&(w||(a(g,p,n,i,o,null,s,r,l),_h(d,p)))):(d.pendingId=nb++,w?(d.isHydrating=!1,d.activeBranch=m):u(m,o,d),d.deps=0,d.effects.length=0,d.hiddenContainer=c("div"),k?(a(null,h,d.hiddenContainer,null,o,d,s,r,l),d.deps<=0?d.resolve():(a(g,p,n,i,o,null,s,r,l),_h(d,p))):g&&ea(g,h)?(a(g,h,n,i,o,d,s,r,l),d.resolve(!0)):(a(null,h,d.hiddenContainer,null,o,d,s,r,l),d.deps<=0&&d.resolve()));else if(g&&ea(g,h))a(g,h,n,i,o,d,s,r,l),_h(d,h);else if(v0(t,"onPending"),d.pendingBranch=h,h.shapeFlag&512?d.pendingId=h.component.suspenseId:d.pendingId=nb++,a(null,h,d.hiddenContainer,null,o,d,s,r,l),d.deps<=0)d.resolve();else{const{timeout:y,pendingId:b}=d;y>0?setTimeout(()=>{d.pendingId===b&&d.fallback(p)},y):y===0&&d.fallback(p)}}function GN(e,t,n,i,o,s,r,l,a,u,c=!1){const{p:d,m:h,um:p,n:g,o:{parentNode:m,remove:k}}=u;let w;const y=TU(e);y&&t&&t.pendingBranch&&(w=t.pendingId,t.deps++);const b=e.props?Vv(e.props.timeout):void 0,A=s,T={vnode:e,parent:t,parentComponent:n,namespace:r,container:i,hiddenContainer:o,deps:0,pendingId:nb++,timeout:typeof b=="number"?b:-1,activeBranch:null,isFallbackMountPending:!1,pendingBranch:null,isInFallback:!c,isHydrating:c,isUnmounted:!1,effects:[],resolve(S=!1,x=!1){const{vnode:_,activeBranch:L,pendingBranch:M,pendingId:N,effects:I,parentComponent:z,container:H,isInFallback:O}=T;let R=!1;if(T.isHydrating)T.isHydrating=!1;else if(!S){R=L&&M.transition&&M.transition.mode==="out-in";let W=!1;R&&(L.transition.afterLeave=()=>{N===T.pendingId&&(h(M,H,s===A&&!W?g(L):s,0),Jv(I),O&&_.ssFallback&&(_.ssFallback.el=null))}),L&&!T.isFallbackMountPending&&(m(L.el)===H&&(s=g(L),W=!0),p(L,z,T,!0),!R&&O&&_.ssFallback&&Zo(()=>_.ssFallback.el=null,T)),R||h(M,H,s,0)}T.isFallbackMountPending=!1,_h(T,M),T.pendingBranch=null,T.isInFallback=!1;let j=T.parent,$=!1;for(;j;){if(j.pendingBranch){j.effects.push(...I),$=!0;break}j=j.parent}!$&&!R&&Jv(I),T.effects=[],y&&t&&t.pendingBranch&&w===t.pendingId&&(t.deps--,t.deps===0&&!x&&t.resolve()),v0(_,"onResolve")},fallback(S){if(!T.pendingBranch)return;const{vnode:x,activeBranch:_,parentComponent:L,container:M,namespace:N}=T;v0(x,"onFallback");const I=g(_),z=()=>{T.isFallbackMountPending=!1,T.isInFallback&&(d(null,S,M,I,L,null,N,l,a),_h(T,S))},H=S.transition&&S.transition.mode==="out-in";H&&(T.isFallbackMountPending=!0,_.transition.afterLeave=z),T.isInFallback=!0,p(_,L,null,!0),H||z()},move(S,x,_){T.activeBranch&&h(T.activeBranch,S,x,_),T.container=S},next(){return T.activeBranch&&g(T.activeBranch)},registerDep(S,x,_){const L=!!T.pendingBranch;L&&T.deps++;const M=S.vnode.el;S.asyncDep.catch(N=>{o1(N,S,0)}).then(N=>{if(S.isUnmounted||T.isUnmounted||T.pendingId!==S.suspenseId)return;y0(),S.asyncResolved=!0;const{vnode:I}=S;ib(S,N,!1),M&&(I.el=M);const z=!M&&S.subTree.el;x(S,I,m(M||S.subTree.el),M?null:g(S.subTree),T,r,_),z&&(I.placeholder=null,k(z)),Yy(S,I.el),L&&--T.deps===0&&T.resolve()})},unmount(S,x){T.isUnmounted=!0,T.activeBranch&&p(T.activeBranch,n,S,x),T.pendingBranch&&p(T.pendingBranch,n,S,x)}};return T}function IU(e,t,n,i,o,s,r,l,a){const u=t.suspense=GN(t,i,n,e.parentNode,document.createElement("div"),null,o,s,r,l,!0),c=a(e,u.pendingBranch=t.ssContent,n,u,s,r);return u.deps===0&&u.resolve(!1,!0),c}function EU(e){const{shapeFlag:t,children:n}=e,i=t&32;e.ssContent=lw(i?n.default:n),e.ssFallback=i?lw(n.fallback):U(Yo)}function lw(e){let t;if(xn(e)){const n=of&&e._c;n&&(e._d=!1,v()),e=e(),n&&(e._d=!0,t=sr,YN())}return tn(e)&&(e=fU(e)),e=Hr(e),t&&!e.dynamicChildren&&(e.dynamicChildren=t.filter(n=>n!==e)),e}function QN(e,t){t&&t.pendingBranch?tn(e)?t.effects.push(...e):t.effects.push(e):Jv(e)}function _h(e,t){e.activeBranch=t;const{vnode:n,parentComponent:i}=e;let o=t.el;for(;!o&&t.component;)t=t.component.subTree,o=t.el;n.el=o,i&&i.subTree===n&&(i.vnode.el=o,Yy(i,o))}function TU(e){const t=e.props&&e.props.suspensible;return t!=null&&t!==!1}const Ee=Symbol.for("v-fgt"),hc=Symbol.for("v-txt"),Yo=Symbol.for("v-cmt"),Mh=Symbol.for("v-stc"),Dp=[];let sr=null;function v(e=!1){Dp.push(sr=e?null:[])}function YN(){Dp.pop(),sr=Dp[Dp.length-1]||null}let of=1;function s2(e,t=!1){of+=e,e<0&&sr&&t&&(sr.hasOnce=!0)}function JN(e){return e.dynamicChildren=of>0?sr||Ah:null,YN(),of>0&&sr&&sr.push(e),e}function E(e,t,n,i,o,s){return JN(C(e,t,n,i,o,s,!0))}function ce(e,t,n,i,o){return JN(U(e,t,n,i,o,!0))}function Cc(e){return e?e.__v_isVNode===!0:!1}function ea(e,t){return e.type===t.type&&e.key===t.key}function Gut(e){}const XN=({key:e})=>e??null,mv=({ref:e,ref_key:t,ref_for:n})=>(typeof e=="number"&&(e=""+e),e!=null?zi(e)||io(e)||xn(e)?{i:Ks,r:e,k:t,f:!!n}:e:null);function C(e,t=null,n=null,i=0,o=null,s=e===Ee?0:1,r=!1,l=!1){const a={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&XN(t),ref:t&&mv(t),scopeId:Zy,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetStart:null,targetAnchor:null,staticCount:0,shapeFlag:s,patchFlag:i,dynamicProps:o,dynamicChildren:null,appContext:null,ctx:Ks};return l?(r2(a,n),s&128&&e.normalize(a)):n&&(a.shapeFlag|=zi(n)?8:16),of>0&&!r&&sr&&(a.patchFlag>0||s&6)&&a.patchFlag!==32&&sr.push(a),a}const U=LU;function LU(e,t=null,n=null,i=0,o=null,s=!1){if((!e||e===EN)&&(e=Yo),Cc(e)){const l=Su(e,t,!0);return n&&r2(l,n),of>0&&!s&&sr&&(l.shapeFlag&6?sr[sr.indexOf(e)]=l:sr.push(l)),l.patchFlag=-2,l}if($U(e)&&(e=e.__vccOpts),t){t=eF(t);let{class:l,style:a}=t;l&&!zi(l)&&(t.class=Fe(l)),Ai(a)&&(Vy(a)&&!tn(a)&&(a=Ei({},a)),t.style=Kt(a))}const r=zi(e)?1:o2(e)?128:AN(e)?64:Ai(e)?4:xn(e)?2:0;return C(e,t,n,i,o,r,s,!0)}function eF(e){return e?Vy(e)||ON(e)?Ei({},e):e:null}function Su(e,t,n=!1,i=!1){const{props:o,ref:s,patchFlag:r,children:l,transition:a}=e,u=t?ni(o||{},t):o,c={__v_isVNode:!0,__v_skip:!0,type:e.type,props:u,key:u&&XN(u),ref:t&&t.ref?n&&s?tn(s)?s.concat(mv(t)):[s,mv(t)]:mv(t):s,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:l,target:e.target,targetStart:e.targetStart,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==Ee?r===-1?16:r|16:r,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:a,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Su(e.ssContent),ssFallback:e.ssFallback&&Su(e.ssFallback),placeholder:e.placeholder,el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce};return a&&i&&Ac(c,a.clone(c)),c}function $e(e=" ",t=0){return U(hc,null,e,t)}function $c(e,t){const n=U(Mh,null,e);return n.staticCount=t,n}function X(e="",t=!1){return t?(v(),ce(Yo,null,e)):U(Yo,null,e)}function Hr(e){return e==null||typeof e=="boolean"?U(Yo):tn(e)?U(Ee,null,e.slice()):Cc(e)?au(e):U(hc,null,String(e))}function au(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Su(e)}function r2(e,t){let n=0;const{shapeFlag:i}=e;if(t==null)t=null;else if(tn(t))n=16;else if(typeof t=="object")if(i&65){const o=t.default;o&&(o._c&&(o._d=!1),r2(e,o()),o._c&&(o._d=!0));return}else{n=32;const o=t._;!o&&!ON(t)?t._ctx=Ks:o===3&&Ks&&(Ks.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else if(xn(t)){if(i&65){r2(e,{default:t});return}t={default:t,_ctx:Ks},n=32}else t=String(t),i&64?(n=16,t=[$e(t)]):n=8;e.children=t,e.shapeFlag|=n}function ni(...e){const t={};for(let n=0;n<e.length;n++){const i=e[n];for(const o in i)if(o==="class")t.class!==i.class&&(t.class=Fe([t.class,i.class]));else if(o==="style")t.style=Kt([t.style,i.style]);else if(Q0(o)){const s=t[o],r=i[o];r&&s!==r&&!(tn(s)&&s.includes(r))?t[o]=s?[].concat(s,r):r:r==null&&s==null&&!By(o)&&(t[o]=r)}else o!==""&&(t[o]=i[o])}return t}function zr(e,t,n,i=null){Rl(e,t,7,[n,i])}const NU=FN();let FU=0;function tF(e,t,n){const i=e.type,o=(t?t.appContext:e.appContext)||NU,s={uid:FU++,vnode:e,type:i,parent:t,appContext:o,root:null,next:null,subTree:null,effect:null,update:null,job:null,scope:new ZL(!0),render:null,proxy:null,exposed:null,exposeProxy:null,withProxy:null,provides:t?t.provides:Object.create(o.provides),ids:t?t.ids:["",0,0],accessCache:null,renderCache:[],components:null,directives:null,propsOptions:jN(i,o),emitsOptions:BN(i,o),emit:null,emitted:null,propsDefaults:Gn,inheritAttrs:i.inheritAttrs,ctx:Gn,data:Gn,props:Gn,attrs:Gn,slots:Gn,refs:Gn,setupState:Gn,setupContext:null,suspense:n,suspenseId:n?n.pendingId:0,asyncDep:null,asyncResolved:!1,isMounted:!1,isUnmounted:!1,isDeactivated:!1,bc:null,c:null,bm:null,m:null,bu:null,u:null,um:null,bum:null,da:null,a:null,rtg:null,rtc:null,ec:null,sp:null};return s.ctx={_:s},s.root=t?t.root:s,s.emit=cU.bind(null,s),e.ce&&e.ce(s),s}let Us=null;const os=()=>Us||Ks;let l2,Ih;{const e=jy(),t=(n,i)=>{let o;return(o=e[n])||(o=e[n]=[]),o.push(i),s=>{o.length>1?o.forEach(r=>r(s)):o[0](s)}};l2=t("__VUE_INSTANCE_SETTERS__",n=>Us=n),Ih=t("__VUE_SSR_SETTERS__",n=>sf=n)}const l1=e=>{const t=Us;return l2(e),e.scope.on(),()=>{e.scope.off(),l2(t)}},y0=()=>{Us&&Us.scope.off(),l2(null)};function nF(e){return e.vnode.shapeFlag&4}let sf=!1;function iF(e,t=!1,n=!1){t&&Ih(t);const{props:i,children:o}=e.vnode,s=nF(e);mU(e,i,s,t),bU(e,o,n||t);const r=s?DU(e,t):void 0;return t&&Ih(!1),r}function DU(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=new Proxy(e.ctx,Jk);const{setup:i}=n;if(i){Pa();const o=e.setupContext=i.length>1?sF(e):null,s=l1(e),r=J0(i,e,0,[e.props,o]),l=N5(r);if(ja(),s(),(l||e.sp)&&!yu(e)&&O5(e),l){if(r.then(y0,y0),t)return r.then(a=>{ib(e,a,t)}).catch(a=>{o1(a,e,0)});e.asyncDep=r}else ib(e,r,t)}else oF(e,t)}function ib(e,t,n){xn(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:Ai(t)&&(e.setupState=fN(t)),oF(e,n)}let a2,ob;function Qut(e){a2=e,ob=t=>{t.render._rc&&(t.withProxy=new Proxy(t.ctx,nU))}}const Yut=()=>!a2;function oF(e,t,n){const i=e.type;if(!e.render){if(!t&&a2&&!i.render){const o=i.template||q5(e).template;if(o){const{isCustomElement:s,compilerOptions:r}=e.appContext.config,{delimiters:l,compilerOptions:a}=i,u=Ei(Ei({isCustomElement:s,delimiters:l},r),a);i.render=a2(o,u)}}e.render=i.render||Bl,ob&&ob(e)}{const o=l1(e);Pa();try{iU(e)}finally{ja(),o()}}}const BU={get(e,t){return nr(e,"get",""),e[t]}};function sF(e){const t=n=>{e.exposed=n||{}};return{attrs:new Proxy(e.attrs,BU),slots:e.slots,emit:e.emit,expose:t}}function tg(e){return e.exposed?e.exposeProxy||(e.exposeProxy=new Proxy(fN(St(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in Fp)return Fp[n](e)},has(t,n){return n in t||n in Fp}})):e.proxy}function sb(e,t=!0){return xn(e)?e.displayName||e.name:e.name||t&&e.__name}function $U(e){return xn(e)&&"__vccOpts"in e}const F=(e,t)=>gq(e,t,sf);function yn(e,t,n){try{s2(-1);const i=arguments.length;return i===2?Ai(t)&&!tn(t)?Cc(t)?U(e,null,[t]):U(e,t):U(e,null,t):(i>3?n=Array.prototype.slice.call(arguments,2):i===3&&Cc(n)&&(n=[n]),U(e,t,n))}finally{s2(1)}}function Jut(){}function Xut(e,t,n,i){const o=n[i];if(o&&RU(o,e))return o;const s=t();return s.memo=e.slice(),s.cacheIndex=i,n[i]=s}function RU(e,t){const n=e.memo;if(n.length!=t.length)return!1;for(let i=0;i<n.length;i++)if(Ts(n[i],t[i]))return!1;return of>0&&sr&&sr.push(e),!0}const zU="3.5.39",ect=Bl,tct=bq,nct=nh,ict=yN,OU={createComponentInstance:tF,setupComponent:iF,renderComponentRoot:gv,setCurrentRenderingInstance:p0,isVNode:Cc,normalizeVNode:Hr,getComponentPublicInstance:tg,ensureValidVNode:W5,pushWarningContext:yq,popWarningContext:kq},oct=OU,sct=null,rct=null,lct=null;/** -* @vue/runtime-dom v3.5.39 -* (c) 2018-present Yuxi (Evan) You and Vue contributors -* @license MIT -**/let rb;const aw=typeof window<"u"&&window.trustedTypes;if(aw)try{rb=aw.createPolicy("vue",{createHTML:e=>e})}catch{}const rF=rb?e=>rb.createHTML(e):e=>e,PU="http://www.w3.org/2000/svg",jU="http://www.w3.org/1998/Math/MathML",su=typeof document<"u"?document:null,uw=su&&su.createElement("template"),HU={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,i)=>{const o=t==="svg"?su.createElementNS(PU,e):t==="mathml"?su.createElementNS(jU,e):n?su.createElement(e,{is:n}):su.createElement(e);return e==="select"&&i&&i.multiple!=null&&o.setAttribute("multiple",i.multiple),o},createText:e=>su.createTextNode(e),createComment:e=>su.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>su.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,i,o,s){const r=n?n.previousSibling:t.lastChild;if(o&&(o===s||o.nextSibling))for(;t.insertBefore(o.cloneNode(!0),n),!(o===s||!(o=o.nextSibling)););else{uw.innerHTML=rF(i==="svg"?`<svg>${e}</svg>`:i==="mathml"?`<math>${e}</math>`:e);const l=uw.content;if(i==="svg"||i==="mathml"){const a=l.firstChild;for(;a.firstChild;)l.appendChild(a.firstChild);l.removeChild(a)}t.insertBefore(l,n)}return[r?r.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}},Pu="transition",j1="animation",Kh=Symbol("_vtc"),lF={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String},aF=Ei({},wN,lF),WU=e=>(e.displayName="Transition",e.props=aF,e),fo=WU((e,{slots:t})=>yn(Nq,uF(e),t)),cd=(e,t=[])=>{tn(e)?e.forEach(n=>n(...t)):e&&e(...t)},cw=e=>e?tn(e)?e.some(t=>t.length>1):e.length>1:!1;function uF(e){const t={};for(const I in e)I in lF||(t[I]=e[I]);if(e.css===!1)return t;const{name:n="v",type:i,duration:o,enterFromClass:s=`${n}-enter-from`,enterActiveClass:r=`${n}-enter-active`,enterToClass:l=`${n}-enter-to`,appearFromClass:a=s,appearActiveClass:u=r,appearToClass:c=l,leaveFromClass:d=`${n}-leave-from`,leaveActiveClass:h=`${n}-leave-active`,leaveToClass:p=`${n}-leave-to`}=e,g=qU(o),m=g&&g[0],k=g&&g[1],{onBeforeEnter:w,onEnter:y,onEnterCancelled:b,onLeave:A,onLeaveCancelled:T,onBeforeAppear:S=w,onAppear:x=y,onAppearCancelled:_=b}=t,L=(I,z,H,O)=>{I._enterCancelled=O,Qu(I,z?c:l),Qu(I,z?u:r),H&&H()},M=(I,z)=>{I._isLeaving=!1,Qu(I,d),Qu(I,p),Qu(I,h),z&&z()},N=I=>(z,H)=>{const O=I?x:y,R=()=>L(z,I,H);cd(O,[z,R]),dw(()=>{Qu(z,I?a:s),_a(z,I?c:l),cw(O)||fw(z,i,m,R)})};return Ei(t,{onBeforeEnter(I){cd(w,[I]),_a(I,s),_a(I,r)},onBeforeAppear(I){cd(S,[I]),_a(I,a),_a(I,u)},onEnter:N(!1),onAppear:N(!0),onLeave(I,z){I._isLeaving=!0;const H=()=>M(I,z);_a(I,d),I._enterCancelled?(_a(I,h),lb(I)):(lb(I),_a(I,h)),dw(()=>{I._isLeaving&&(Qu(I,d),_a(I,p),cw(A)||fw(I,i,k,H))}),cd(A,[I,H])},onEnterCancelled(I){L(I,!1,void 0,!0),cd(b,[I])},onAppearCancelled(I){L(I,!0,void 0,!0),cd(_,[I])},onLeaveCancelled(I){M(I),cd(T,[I])}})}function qU(e){if(e==null)return null;if(Ai(e))return[K4(e.enter),K4(e.leave)];{const t=K4(e);return[t,t]}}function K4(e){return Vv(e)}function _a(e,t){t.split(/\s+/).forEach(n=>n&&e.classList.add(n)),(e[Kh]||(e[Kh]=new Set)).add(t)}function Qu(e,t){t.split(/\s+/).forEach(i=>i&&e.classList.remove(i));const n=e[Kh];n&&(n.delete(t),n.size||(e[Kh]=void 0))}function dw(e){requestAnimationFrame(()=>{requestAnimationFrame(e)})}let UU=0;function fw(e,t,n,i){const o=e._endId=++UU,s=()=>{o===e._endId&&i()};if(n!=null)return setTimeout(s,n);const{type:r,timeout:l,propCount:a}=cF(e,t);if(!r)return i();const u=r+"end";let c=0;const d=()=>{e.removeEventListener(u,h),s()},h=p=>{p.target===e&&++c>=a&&d()};setTimeout(()=>{c<a&&d()},l+1),e.addEventListener(u,h)}function cF(e,t){const n=window.getComputedStyle(e),i=g=>(n[g]||"").split(", "),o=i(`${Pu}Delay`),s=i(`${Pu}Duration`),r=hw(o,s),l=i(`${j1}Delay`),a=i(`${j1}Duration`),u=hw(l,a);let c=null,d=0,h=0;t===Pu?r>0&&(c=Pu,d=r,h=s.length):t===j1?u>0&&(c=j1,d=u,h=a.length):(d=Math.max(r,u),c=d>0?r>u?Pu:j1:null,h=c?c===Pu?s.length:a.length:0);const p=c===Pu&&/\b(?:transform|all)(?:,|$)/.test(i(`${Pu}Property`).toString());return{type:c,timeout:d,propCount:h,hasTransform:p}}function hw(e,t){for(;e.length<t.length;)e=e.concat(e);return Math.max(...t.map((n,i)=>pw(n)+pw(e[i])))}function pw(e){return e==="auto"?0:Number(e.slice(0,-1).replace(",","."))*1e3}function lb(e){return(e?e.ownerDocument:document).body.offsetHeight}function KU(e,t,n){const i=e[Kh];i&&(t=(t?[t,...i]:[...i]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}const u2=Symbol("_vod"),Z5=Symbol("_vsh"),Po={name:"show",beforeMount(e,{value:t},{transition:n}){e[u2]=e.style.display==="none"?"":e.style.display,n&&t?n.beforeEnter(e):H1(e,t)},mounted(e,{value:t},{transition:n}){n&&t&&n.enter(e)},updated(e,{value:t,oldValue:n},{transition:i}){!t!=!n&&(i?t?(i.beforeEnter(e),H1(e,!0),i.enter(e)):i.leave(e,()=>{H1(e,!1)}):H1(e,t))},beforeUnmount(e,{value:t}){H1(e,t)}};function H1(e,t){e.style.display=t?e[u2]:"none",e[Z5]=!t}function VU(){Po.getSSRProps=({value:e})=>{if(!e)return{style:{display:"none"}}}}const dF=Symbol("");function act(e){const t=os();if(!t)return;const n=t.ut=(o=e(t.proxy))=>{Array.from(document.querySelectorAll(`[data-v-owner="${t.uid}"]`)).forEach(s=>c2(s,o))},i=()=>{const o=e(t.proxy);t.ce?c2(t.ce,o):ab(t.subTree,o),n(o)};IN(()=>{Jv(i)}),cn(()=>{Pe(i,Bl,{flush:"post"});const o=new MutationObserver(i);o.observe(t.subTree.el.parentNode,{childList:!0}),_n(()=>o.disconnect())})}function ab(e,t){if(e.shapeFlag&128){const n=e.suspense;e=n.activeBranch,n.pendingBranch&&!n.isHydrating&&n.effects.push(()=>{ab(n.activeBranch,t)})}for(;e.component;)e=e.component.subTree;if(e.shapeFlag&1&&e.el)c2(e.el,t);else if(e.type===Ee)e.children.forEach(n=>ab(n,t));else if(e.type===Mh){let{el:n,anchor:i}=e;for(;n&&(c2(n,t),n!==i);)n=n.nextSibling}}function c2(e,t){if(e.nodeType===1){const n=e.style;let i="";for(const o in t){const s=jW(t[o]);n.setProperty(`--${o}`,s),i+=`--${o}: ${s};`}n[dF]=i}}const ZU=/(?:^|;)\s*display\s*:/;function GU(e,t,n){const i=e.style,o=zi(n);let s=!1;if(n&&!o){if(t)if(zi(t))for(const r of t.split(";")){const l=r.slice(0,r.indexOf(":")).trim();n[l]==null&&cp(i,l,"")}else for(const r in t)n[r]==null&&cp(i,r,"");for(const r in n){r==="display"&&(s=!0);const l=n[r];l!=null?YU(e,r,!zi(t)&&t?t[r]:void 0,l)||cp(i,r,l):cp(i,r,"")}}else if(o){if(t!==n){const r=i[dF];r&&(n+=";"+r),i.cssText=n,s=ZU.test(n)}}else t&&e.removeAttribute("style");u2 in e&&(e[u2]=s?i.display:"",e[Z5]&&(i.display="none"))}const gw=/\s*!important$/;function cp(e,t,n){if(tn(n))n.forEach(i=>cp(e,t,i));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const i=QU(e,t);gw.test(n)?e.setProperty(Wr(i),n.replace(gw,""),"important"):e[i]=n}}const mw=["Webkit","Moz","ms"],V4={};function QU(e,t){const n=V4[t];if(n)return n;let i=ps(t);if(i!=="filter"&&i in e)return V4[t]=i;i=Oy(i);for(let o=0;o<mw.length;o++){const s=mw[o]+i;if(s in e)return V4[t]=s}return t}function YU(e,t,n,i){return e.tagName==="TEXTAREA"&&(t==="width"||t==="height")&&zi(i)&&n===i}const vw="http://www.w3.org/1999/xlink";function yw(e,t,n,i,o,s=OW(t)){i&&t.startsWith("xlink:")?n==null?e.removeAttributeNS(vw,t.slice(6,t.length)):e.setAttributeNS(vw,t,n):n==null||s&&!UL(n)?e.removeAttribute(t):e.setAttribute(t,s?"":gl(n)?String(n):n)}function kw(e,t,n,i,o){if(t==="innerHTML"||t==="textContent"){n!=null&&(e[t]=t==="innerHTML"?rF(n):n);return}const s=e.tagName;if(t==="value"&&s!=="PROGRESS"&&!s.includes("-")){const l=s==="OPTION"?e.getAttribute("value")||"":e.value,a=n==null?e.type==="checkbox"?"on":"":String(n);(l!==a||!("_value"in e))&&(e.value=a),n==null&&e.removeAttribute(t),e._value=n;return}let r=!1;if(n===""||n==null){const l=typeof e[t];l==="boolean"?n=UL(n):n==null&&l==="string"?(n="",r=!0):l==="number"&&(n=0,r=!0)}try{e[t]=n}catch{}r&&e.removeAttribute(o||t)}function du(e,t,n,i){e.addEventListener(t,n,i)}function JU(e,t,n,i){e.removeEventListener(t,n,i)}const bw=Symbol("_vei");function XU(e,t,n,i,o=null){const s=e[bw]||(e[bw]={}),r=s[t];if(i&&r)r.value=i;else{const[l,a]=nK(t);if(i){const u=s[t]=sK(i,o);du(e,l,u,a)}else r&&(JU(e,l,r,a),s[t]=void 0)}}const eK=/(Once|Passive|Capture)$/,tK=/^on:?(?:Once|Passive|Capture)$/;function nK(e){let t,n;for(;(n=e.match(eK))&&!tK.test(e);)t||(t={}),e=e.slice(0,e.length-n[1].length),t[n[1].toLowerCase()]=!0;return[e[2]===":"?e.slice(3):Wr(e.slice(2)),t]}let Z4=0;const iK=Promise.resolve(),oK=()=>Z4||(iK.then(()=>Z4=0),Z4=Date.now());function sK(e,t){const n=i=>{if(!i._vts)i._vts=Date.now();else if(i._vts<=n.attached)return;const o=n.value;if(tn(o)){const s=i.stopImmediatePropagation;i.stopImmediatePropagation=()=>{s.call(i),i._stopped=!0};const r=o.slice(),l=[i];for(let a=0;a<r.length&&!i._stopped;a++){const u=r[a];u&&Rl(u,t,5,l)}}else Rl(o,t,5,[i])};return n.value=e,n.attached=oK(),n}const Aw=e=>e.charCodeAt(0)===111&&e.charCodeAt(1)===110&&e.charCodeAt(2)>96&&e.charCodeAt(2)<123,rK=(e,t,n,i,o,s)=>{const r=o==="svg";t==="class"?KU(e,i,r):t==="style"?GU(e,n,i):Q0(t)?By(t)||XU(e,t,n,i,s):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):lK(e,t,i,r))?(kw(e,t,i),!e.tagName.includes("-")&&(t==="value"||t==="checked"||t==="selected")&&yw(e,t,i,r,s,t!=="value")):e._isVueCE&&(aK(e,t)||e._def.__asyncLoader&&(/[A-Z]/.test(t)||!zi(i)))?kw(e,ps(t),i,s,t):(t==="true-value"?e._trueValue=i:t==="false-value"&&(e._falseValue=i),yw(e,t,i,r))};function lK(e,t,n,i){if(i)return!!(t==="innerHTML"||t==="textContent"||t in e&&Aw(t)&&xn(n));if(t==="spellcheck"||t==="draggable"||t==="translate"||t==="autocorrect"||t==="sandbox"&&e.tagName==="IFRAME"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA")return!1;if(t==="width"||t==="height"){const o=e.tagName;if(o==="IMG"||o==="VIDEO"||o==="CANVAS"||o==="SOURCE")return!1}return Aw(t)&&zi(n)?!1:t in e}function aK(e,t){const n=e._def.props;if(!n)return!1;const i=ps(t);return Array.isArray(n)?n.some(o=>ps(o)===i):Object.keys(n).some(o=>ps(o)===i)}const Cw={};function uK(e,t,n){let i=Xe(e,t);$y(i)&&(i=Ei({},i,t));class o extends G5{constructor(r){super(i,r,n)}}return o.def=i,o}const uct=((e,t)=>uK(e,t,SK)),cK=typeof HTMLElement<"u"?HTMLElement:class{};class G5 extends cK{constructor(t,n={},i=h2){super(),this._def=t,this._props=n,this._createApp=i,this._isVueCE=!0,this._instance=null,this._app=null,this._nonce=this._def.nonce,this._connected=!1,this._resolved=!1,this._patching=!1,this._dirty=!1,this._numberProps=null,this._styleChildren=new WeakSet,this._styleAnchors=new WeakMap,this._ob=null,this.shadowRoot&&i!==h2?this._root=this.shadowRoot:t.shadowRoot!==!1?(this.attachShadow(Ei({},t.shadowRootOptions,{mode:"open"})),this._root=this.shadowRoot):this._root=this}connectedCallback(){if(!this.isConnected)return;!this.shadowRoot&&!this._resolved&&this._parseSlots(),this._connected=!0;let t=this;for(;t=t&&(t.assignedSlot||t.parentNode||t.host);)if(t instanceof G5){this._parent=t;break}this._instance||(this._resolved?this._mount(this._def):t&&t._pendingResolve?this._pendingResolve=t._pendingResolve.then(()=>{this._pendingResolve=void 0,this._resolveDef()}):this._resolveDef())}_setParent(t=this._parent){t&&(this._instance.parent=t._instance,this._inheritParentContext(t))}_inheritParentContext(t=this._parent){t&&this._app&&Object.setPrototypeOf(this._app._context.provides,t._instance.provides)}disconnectedCallback(){this._connected=!1,dt(()=>{this._connected||(this._ob&&(this._ob.disconnect(),this._ob=null),this._app&&this._app.unmount(),this._instance&&(this._instance.ce=void 0),this._app=this._instance=null,this._teleportTargets&&(this._teleportTargets.clear(),this._teleportTargets=void 0))})}_processMutations(t){for(const n of t)this._setAttr(n.attributeName)}_resolveDef(){if(this._pendingResolve)return;for(let i=0;i<this.attributes.length;i++)this._setAttr(this.attributes[i].name);this._ob=new MutationObserver(this._processMutations.bind(this)),this._ob.observe(this,{attributes:!0});const t=(i,o=!1)=>{this._resolved=!0,this._pendingResolve=void 0;const{props:s,styles:r}=i;let l;if(s&&!tn(s))for(const a in s){const u=s[a];(u===Number||u&&u.type===Number)&&(a in this._props&&(this._props[a]=Vv(this._props[a])),(l||(l=Object.create(null)))[ps(a)]=!0)}this._numberProps=l,this._resolveProps(i),this.shadowRoot&&this._applyStyles(r),this._mount(i)},n=this._def.__asyncLoader;n?this._pendingResolve=n().then(i=>{i.configureApp=this._def.configureApp,t(this._def=i,!0)}):t(this._def)}_mount(t){this._app=this._createApp(t),this._inheritParentContext(),t.configureApp&&t.configureApp(this._app),this._app._ceVNode=this._createVNode(),this._app.mount(this._root);const n=this._instance&&this._instance.exposed;if(n)for(const i in n)ki(this,i)||Object.defineProperty(this,i,{get:()=>f(n[i])})}_resolveProps(t){const{props:n}=t,i=tn(n)?n:Object.keys(n||{});for(const o of Object.keys(this))o[0]!=="_"&&i.includes(o)&&this._setProp(o,this[o]);for(const o of i.map(ps))Object.defineProperty(this,o,{get(){return this._getProp(o)},set(s){this._setProp(o,s,!0,!this._patching)}})}_setAttr(t){if(t.startsWith("data-v-"))return;const n=this.hasAttribute(t);let i=n?this.getAttribute(t):Cw;const o=ps(t);n&&this._numberProps&&this._numberProps[o]&&(i=Vv(i)),this._setProp(o,i,!1,!0)}_getProp(t){return this._props[t]}_setProp(t,n,i=!0,o=!1){if(n!==this._props[t]&&(this._dirty=!0,n===Cw?delete this._props[t]:(this._props[t]=n,t==="key"&&this._app&&(this._app._ceVNode.key=n)),o&&this._instance&&this._update(),i)){const s=this._ob;s&&(this._processMutations(s.takeRecords()),s.disconnect()),n===!0?this.setAttribute(Wr(t),""):typeof n=="string"||typeof n=="number"?this.setAttribute(Wr(t),n+""):n||this.removeAttribute(Wr(t)),s&&s.observe(this,{attributes:!0})}}_update(){const t=this._createVNode();this._app&&(t.appContext=this._app._context),xK(t,this._root)}_createVNode(){const t={};this.shadowRoot||(t.onVnodeMounted=t.onVnodeUpdated=this._renderSlots.bind(this));const n=U(this._def,Ei(t,this._props));return this._instance||(n.ce=i=>{this._instance=i,i.ce=this,i.isCE=!0;const o=(s,r)=>{this.dispatchEvent(new CustomEvent(s,$y(r[0])?Ei({detail:r},r[0]):{detail:r}))};i.emit=(s,...r)=>{o(s,r),Wr(s)!==s&&o(Wr(s),r)},this._setParent()}),n}_applyStyles(t,n,i){if(!t)return;if(n){if(n===this._def||this._styleChildren.has(n))return;this._styleChildren.add(n)}const o=this._nonce,s=this.shadowRoot,r=i?this._getStyleAnchor(i)||this._getStyleAnchor(this._def):this._getRootStyleInsertionAnchor(s);let l=null;for(let a=t.length-1;a>=0;a--){const u=document.createElement("style");o&&u.setAttribute("nonce",o),u.textContent=t[a],s.insertBefore(u,l||r),l=u,a===0&&(i||this._styleAnchors.set(this._def,u),n&&this._styleAnchors.set(n,u))}}_getStyleAnchor(t){if(!t)return null;const n=this._styleAnchors.get(t);return n&&n.parentNode===this.shadowRoot?n:(n&&this._styleAnchors.delete(t),null)}_getRootStyleInsertionAnchor(t){for(let n=0;n<t.childNodes.length;n++){const i=t.childNodes[n];if(!(i instanceof HTMLStyleElement))return i}return null}_parseSlots(){const t=this._slots={};let n;for(;n=this.firstChild;){const i=n.nodeType===1&&n.getAttribute("slot")||"default";(t[i]||(t[i]=[])).push(n),this.removeChild(n)}}_renderSlots(){const t=this._getSlots(),n=this._instance.type.__scopeId;for(let i=0;i<t.length;i++){const o=t[i],s=o.getAttribute("name")||"default",r=this._slots[s],l=o.parentNode;if(r)for(const a of r){if(n&&a.nodeType===1){const u=n+"-s",c=document.createTreeWalker(a,1);a.setAttribute(u,"");let d;for(;d=c.nextNode();)d.setAttribute(u,"")}l.insertBefore(a,o)}else for(;o.firstChild;)l.insertBefore(o.firstChild,o);l.removeChild(o)}}_getSlots(){const t=[this];this._teleportTargets&&t.push(...this._teleportTargets);const n=new Set;for(const i of t){const o=i.querySelectorAll("slot");for(let s=0;s<o.length;s++)n.add(o[s])}return Array.from(n)}_injectChildStyle(t,n){this._applyStyles(t.styles,t,n)}_beginPatch(){this._patching=!0,this._dirty=!1}_endPatch(){this._patching=!1,this._dirty&&this._instance&&this._update()}_hasShadowRoot(){return this._def.shadowRoot!==!1}_removeChildStyle(t){}}function dK(e){const t=os(),n=t&&t.ce;return n||null}function cct(){const e=dK();return e&&e.shadowRoot}function dct(e="$style"){{const t=os();if(!t)return Gn;const n=t.type.__cssModules;if(!n)return Gn;const i=n[e];return i||Gn}}const fF=new WeakMap,hF=new WeakMap,d2=Symbol("_moveCb"),ww=Symbol("_enterCb"),fK=e=>(delete e.props.mode,e),hK=fK({name:"TransitionGroup",props:Ei({},aF,{tag:String,moveClass:String}),setup(e,{slots:t}){const n=os(),i=CN();let o,s;return s1(()=>{if(!o.length)return;const r=e.moveClass||`${e.name||"v"}-move`;if(!vK(o[0].el,n.vnode.el,r)){o=[];return}o.forEach(pK),o.forEach(gK);const l=o.filter(mK);lb(n.vnode.el),l.forEach(a=>{const u=a.el,c=u.style;_a(u,r),c.transform=c.webkitTransform=c.transitionDuration="";const d=u[d2]=h=>{h&&h.target!==u||(!h||h.propertyName.endsWith("transform"))&&(u.removeEventListener("transitionend",d),u[d2]=null,Qu(u,r))};u.addEventListener("transitionend",d)}),o=[]}),()=>{const r=si(e),l=uF(r);let a=r.tag||Ee;if(o=[],s)for(let u=0;u<s.length;u++){const c=s[u];c.el&&c.el instanceof Element&&!c.el[Z5]&&(o.push(c),Ac(c,g0(c,l,i,n)),fF.set(c,gF(c.el)))}s=t.default?z5(t.default()):[];for(let u=0;u<s.length;u++){const c=s[u];c.key!=null&&Ac(c,g0(c,l,i,n))}return U(a,null,s)}}}),pF=hK;function pK(e){const t=e.el;t[d2]&&t[d2](),t[ww]&&t[ww]()}function gK(e){hF.set(e,gF(e.el))}function mK(e){const t=fF.get(e),n=hF.get(e),i=t.left-n.left,o=t.top-n.top;if(i||o){const s=e.el,r=s.style,l=s.getBoundingClientRect();let a=1,u=1;return s.offsetWidth&&(a=l.width/s.offsetWidth),s.offsetHeight&&(u=l.height/s.offsetHeight),(!Number.isFinite(a)||a===0)&&(a=1),(!Number.isFinite(u)||u===0)&&(u=1),Math.abs(a-1)<.01&&(a=1),Math.abs(u-1)<.01&&(u=1),r.transform=r.webkitTransform=`translate(${i/a}px,${o/u}px)`,r.transitionDuration="0s",e}}function gF(e){const t=e.getBoundingClientRect();return{left:t.left,top:t.top}}function vK(e,t,n){const i=e.cloneNode(),o=e[Kh];o&&o.forEach(l=>{l.split(/\s+/).forEach(a=>a&&i.classList.remove(a))}),n.split(/\s+/).forEach(l=>l&&i.classList.add(l)),i.style.display="none";const s=t.nodeType===1?t:t.parentNode;s.appendChild(i);const{hasTransform:r}=cF(i);return s.removeChild(i),r}const wc=e=>{const t=e.props["onUpdate:modelValue"]||!1;return tn(t)?n=>wh(t,n):t};function yK(e){e.target.composing=!0}function xw(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const $l=Symbol("_assign");function Sw(e,t,n){return t&&(e=e.trim()),n&&(e=Py(e)),e}const Bs={created(e,{modifiers:{lazy:t,trim:n,number:i}},o){e[$l]=wc(o);const s=i||o.props&&o.props.type==="number";du(e,t?"change":"input",r=>{r.target.composing||e[$l](Sw(e.value,n,s))}),(n||s)&&du(e,"change",()=>{e.value=Sw(e.value,n,s)}),t||(du(e,"compositionstart",yK),du(e,"compositionend",xw),du(e,"change",xw))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,oldValue:n,modifiers:{lazy:i,trim:o,number:s}},r){if(e[$l]=wc(r),e.composing)return;const l=(s||e.type==="number")&&!/^0\d/.test(e.value)?Py(e.value):e.value,a=t??"";if(l===a)return;const u=e.getRootNode();(u instanceof Document||u instanceof ShadowRoot)&&u.activeElement===e&&e.type!=="range"&&(i&&t===n||o&&e.value.trim()===a)||(e.value=a)}},f2={deep:!0,created(e,t,n){e[$l]=wc(n),du(e,"change",()=>{const i=e._modelValue,o=Vh(e),s=e.checked,r=e[$l];if(tn(i)){const l=Hy(i,o),a=l!==-1;if(s&&!a)r(i.concat(o));else if(!s&&a){const u=[...i];u.splice(l,1),r(u)}}else if(yf(i)){const l=new Set(i);s?l.add(o):l.delete(o),r(l)}else r(vF(e,s))})},mounted:_w,beforeUpdate(e,t,n){e[$l]=wc(n),_w(e,t,n)}};function _w(e,{value:t,oldValue:n},i){e._modelValue=t;let o;if(tn(t))o=Hy(t,i.props.value)>-1;else if(yf(t))o=t.has(i.props.value);else{if(t===n)return;o=wu(t,vF(e,!0))}e.checked!==o&&(e.checked=o)}const mF={created(e,{value:t},n){e.checked=wu(t,n.props.value),e[$l]=wc(n),du(e,"change",()=>{e[$l](Vh(e))})},beforeUpdate(e,{value:t,oldValue:n},i){e[$l]=wc(i),t!==n&&(e.checked=wu(t,i.props.value))}},ub={deep:!0,created(e,{value:t,modifiers:{number:n}},i){const o=yf(t);du(e,"change",()=>{const s=Array.prototype.filter.call(e.options,r=>r.selected).map(r=>n?Py(Vh(r)):Vh(r));e[$l](e.multiple?o?new Set(s):s:s[0]),e._assigning=!0,dt(()=>{e._assigning=!1})}),e[$l]=wc(i)},mounted(e,{value:t}){Mw(e,t)},beforeUpdate(e,t,n){e[$l]=wc(n)},updated(e,{value:t}){e._assigning||Mw(e,t)}};function Mw(e,t){const n=e.multiple,i=tn(t);if(!(n&&!i&&!yf(t))){for(let o=0,s=e.options.length;o<s;o++){const r=e.options[o],l=Vh(r);if(n)if(i){const a=typeof l;a==="string"||a==="number"?r.selected=t.some(u=>String(u)===String(l)):r.selected=Hy(t,l)>-1}else r.selected=t.has(l);else if(wu(Vh(r),t)){e.selectedIndex!==o&&(e.selectedIndex=o);return}}!n&&e.selectedIndex!==-1&&(e.selectedIndex=-1)}}function Vh(e){return"_value"in e?e._value:e.value}function vF(e,t){const n=t?"_trueValue":"_falseValue";return n in e?e[n]:t}const kK={created(e,t,n){dm(e,t,n,null,"created")},mounted(e,t,n){dm(e,t,n,null,"mounted")},beforeUpdate(e,t,n,i){dm(e,t,n,i,"beforeUpdate")},updated(e,t,n,i){dm(e,t,n,i,"updated")}};function yF(e,t){switch(e){case"SELECT":return ub;case"TEXTAREA":return Bs;default:switch(t){case"checkbox":return f2;case"radio":return mF;default:return Bs}}}function dm(e,t,n,i,o){const r=yF(e.tagName,n.props&&n.props.type)[o];r&&r(e,t,n,i)}function bK(){Bs.getSSRProps=({value:e})=>({value:e}),mF.getSSRProps=({value:e},t)=>{if(t.props&&wu(t.props.value,e))return{checked:!0}},f2.getSSRProps=({value:e},t)=>{if(tn(e)){if(t.props&&Hy(e,t.props.value)>-1)return{checked:!0}}else if(yf(e)){if(t.props&&e.has(t.props.value))return{checked:!0}}else if(e)return{checked:!0}},kK.getSSRProps=(e,t)=>{if(typeof t.type!="string")return;const n=yF(t.type.toUpperCase(),t.props&&t.props.type);if(n.getSSRProps)return n.getSSRProps(e,t)}}const AK=["ctrl","shift","alt","meta"],CK={stop:e=>e.stopPropagation(),prevent:e=>e.preventDefault(),self:e=>e.target!==e.currentTarget,ctrl:e=>!e.ctrlKey,shift:e=>!e.shiftKey,alt:e=>!e.altKey,meta:e=>!e.metaKey,left:e=>"button"in e&&e.button!==0,middle:e=>"button"in e&&e.button!==1,right:e=>"button"in e&&e.button!==2,exact:(e,t)=>AK.some(n=>e[`${n}Key`]&&!t.includes(n))},wt=(e,t)=>{if(!e)return e;const n=e._withMods||(e._withMods={}),i=t.join(".");return n[i]||(n[i]=((o,...s)=>{for(let r=0;r<t.length;r++){const l=CK[t[r]];if(l&&l(o,t))return}return e(o,...s)}))},wK={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},Ho=(e,t)=>{const n=e._withKeys||(e._withKeys={}),i=t.join(".");return n[i]||(n[i]=(o=>{if(!("key"in o))return;const s=Wr(o.key);if(t.some(r=>r===s||wK[r]===s))return e(o)}))},kF=Ei({patchProp:rK},HU);let Bp,Iw=!1;function bF(){return Bp||(Bp=CU(kF))}function AF(){return Bp=Iw?Bp:wU(kF),Iw=!0,Bp}const xK=((...e)=>{bF().render(...e)}),fct=((...e)=>{AF().hydrate(...e)}),h2=((...e)=>{const t=bF().createApp(...e),{mount:n}=t;return t.mount=i=>{const o=wF(i);if(!o)return;const s=t._component;!xn(s)&&!s.render&&!s.template&&(s.template=o.innerHTML),o.nodeType===1&&(o.textContent="");const r=n(o,!1,CF(o));return o instanceof Element&&(o.removeAttribute("v-cloak"),o.setAttribute("data-v-app","")),r},t}),SK=((...e)=>{const t=AF().createApp(...e),{mount:n}=t;return t.mount=i=>{const o=wF(i);if(o)return n(o,!0,CF(o))},t});function CF(e){if(e instanceof SVGElement)return"svg";if(typeof MathMLElement=="function"&&e instanceof MathMLElement)return"mathml"}function wF(e){return zi(e)?document.querySelector(e):e}let Ew=!1;const hct=()=>{Ew||(Ew=!0,bK(),VU())},xF=Symbol("IconResolver"),_K={sm:14,md:16,lg:20},ve=Xe({__name:"Icon",props:{name:{},size:{default:"md"},label:{}},setup(e){const t=e,n=hn(xF,()=>{}),i=F(()=>n(t.name)),o=F(()=>_K[t.size]);return(s,r)=>i.value?(v(),ce(Oo(i.value),{key:0,class:"kw-icon",width:o.value,height:o.value,"aria-label":e.label,"aria-hidden":e.label?void 0:!0},null,8,["width","height","aria-label","aria-hidden"])):X("",!0)}}),MK=["disabled"],IK={key:0,class:"ui-action-card__leading"},EK={class:"ui-action-card__text"},TK={class:"ui-action-card__title"},LK={key:0,class:"ui-action-card__hint"},NK=Xe({__name:"ActionCard",props:{disabled:{type:Boolean,default:!1}},emits:["select"],setup(e){return(t,n)=>(v(),E("button",{class:"ui-action-card",type:"button",disabled:e.disabled,onClick:n[0]||(n[0]=i=>t.$emit("select"))},[t.$slots.leading?(v(),E("span",IK,[Rn(t.$slots,"leading",{},void 0,!0)])):X("",!0),C("span",EK,[C("span",TK,[Rn(t.$slots,"default",{},void 0,!0),Rn(t.$slots,"badge",{},void 0,!0)]),t.$slots.hint?(v(),E("span",LK,[Rn(t.$slots,"hint",{},void 0,!0)])):X("",!0)]),U(ve,{name:"chevron-right",size:"lg",class:"ui-action-card__chevron"})],8,MK))}}),kt=(e,t)=>{const n=e.__vccOpts||e;for(const[i,o]of t)n[i]=o;return n},cb=kt(NK,[["__scopeId","data-v-aa7ca9d9"]]);/*! - * shared v11.4.6 - * (c) 2026 kazuya kawaguchi - * Released under the MIT License. - */function FK(e,t){typeof console<"u"&&(console.warn("[intlify] "+e),t&&console.warn(t.stack))}const p2=typeof window<"u",Rc=(e,t=!1)=>t?Symbol.for(e):Symbol(e),DK=(e,t,n)=>BK({l:e,k:t,s:n}),BK=e=>JSON.stringify(e).replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029").replace(/\u0027/g,"\\u0027"),Jo=e=>typeof e=="number"&&isFinite(e),SF=e=>Y5(e)==="[object Date]",Zh=e=>Y5(e)==="[object RegExp]",Jy=e=>li(e)&&Object.keys(e).length===0,ts=Object.assign,$K=Object.create,Ri=(e=null)=>$K(e);let Tw;const Bd=()=>Tw||(Tw=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:Ri());function Lw(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/").replace(/=/g,"=")}function RK(e){return e.replace(/&(?![a-zA-Z0-9#]{2,6};)/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}const zK=/^\s*javascript\s*(?::|�*58;?|�*3a;?|:?)/i,OK=/^(?:href|src|action|formaction)$/i;function Q5(e){return zK.test(e)}function PK(e){const t=/url\s*\(/gi;let n="",i=0,o;for(;(o=t.exec(e))!==null;){const s=o.index,r=t.lastIndex-1;let l=r+1,a=1,u=null;for(;l<e.length;l++){const h=e[l];if(u){h===u&&(u=null);continue}if(h==='"'||h==="'")u=h;else if(h==="(")a++;else if(h===")"&&(a--,a===0))break}if(a!==0)break;const c=e.slice(r+1,l).trim(),d=c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'")?c.slice(1,-1).trim():c;n+=e.slice(i,s),n+=Q5(d)?"url(about:blank)":e.slice(s,l+1),i=l+1}return n+e.slice(i)}function Nw(e,t){if(OK.test(e)&&Q5(t))return"about:blank";const n=e.toLowerCase()==="style"?PK(t):t;return RK(n)}function jK(e){return e=e.replace(/([\w:-]+)\s*=\s*"([^"]*)"/g,(n,i,o)=>`${i}="${Nw(i,o)}"`),e=e.replace(/([\w:-]+)\s*=\s*'([^']*)'/g,(n,i,o)=>`${i}='${Nw(i,o)}'`),/\s*on\w+\s*=\s*["']?[^"'>]+["']?/gi.test(e)&&(e=e.replace(/(\s+)(on)(\w+\s*=)/gi,"$1on$3")),e=e.replace(/(\s+(?:href|src|action|formaction)\s*=\s*)([^\s"'=<>`]+)/gi,(n,i,o)=>Q5(o)?`${i}about:blank`:n),e}const HK=Object.prototype.hasOwnProperty;function Fl(e,t){return HK.call(e,t)}const No=Array.isArray,uo=e=>typeof e=="function",Gt=e=>typeof e=="string",pi=e=>typeof e=="boolean",mi=e=>e!==null&&typeof e=="object",WK=e=>mi(e)&&uo(e.then)&&uo(e.catch),_F=Object.prototype.toString,Y5=e=>_F.call(e),li=e=>Y5(e)==="[object Object]",qK=e=>e==null?"":No(e)||li(e)&&e.toString===_F?JSON.stringify(e,null,2):String(e);function J5(e,t=""){return e.reduce((n,i,o)=>o===0?n+i:n+t+i,"")}const fm=e=>!mi(e)||No(e);function vv(e,t){if(fm(e)||fm(t))throw new Error("Invalid value");const n=[{src:e,des:t}];for(;n.length;){const{src:i,des:o}=n.pop();Object.keys(i).forEach(s=>{s!=="__proto__"&&(mi(i[s])&&!mi(o[s])&&(o[s]=Array.isArray(i[s])?[]:Ri()),fm(o[s])||fm(i[s])?o[s]=i[s]:n.push({src:i[s],des:o[s]}))})}}/*! - * message-compiler v11.4.6 - * (c) 2026 kazuya kawaguchi - * Released under the MIT License. - */function UK(e,t,n){return{line:e,column:t,offset:n}}function db(e,t,n){return{start:e,end:t}}const xi={EXPECTED_TOKEN:1,INVALID_TOKEN_IN_PLACEHOLDER:2,UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER:3,UNKNOWN_ESCAPE_SEQUENCE:4,INVALID_UNICODE_ESCAPE_SEQUENCE:5,UNBALANCED_CLOSING_BRACE:6,UNTERMINATED_CLOSING_BRACE:7,EMPTY_PLACEHOLDER:8,NOT_ALLOW_NEST_PLACEHOLDER:9,INVALID_LINKED_FORMAT:10,MUST_HAVE_MESSAGES_IN_PLURAL:11,UNEXPECTED_EMPTY_LINKED_MODIFIER:12,UNEXPECTED_EMPTY_LINKED_KEY:13,UNEXPECTED_LEXICAL_ANALYSIS:14},KK=17;function Xy(e,t,n={}){const{domain:i,messages:o,args:s}=n,r=e,l=new SyntaxError(String(r));return l.code=e,t&&(l.location=t),l.domain=i,l}function VK(e){throw e}const Aa=" ",ZK="\r",er=` -`,GK="\u2028",QK="\u2029";function YK(e){const t=e;let n=0,i=1,o=1,s=0;const r=x=>t[x]===ZK&&t[x+1]===er,l=x=>t[x]===er,a=x=>t[x]===QK,u=x=>t[x]===GK,c=x=>r(x)||l(x)||a(x)||u(x),d=()=>n,h=()=>i,p=()=>o,g=()=>s,m=x=>r(x)||a(x)||u(x)?er:t[x],k=()=>m(n),w=()=>m(n+s);function y(){return s=0,c(n)&&(i++,o=0),r(n)&&n++,n++,o++,t[n]}function b(){return r(n+s)&&s++,s++,t[n+s]}function A(){n=0,i=1,o=1,s=0}function T(x=0){s=x}function S(){const x=n+s;for(;x!==n;)y();s=0}return{index:d,line:h,column:p,peekOffset:g,charAt:m,currentChar:k,currentPeek:w,next:y,peek:b,reset:A,resetPeek:T,skipToPeek:S}}const tu=void 0,JK=".",Fw="'",XK="tokenizer";function eV(e,t={}){const n=t.location!==!1,i=YK(e),o=()=>i.index(),s=()=>UK(i.line(),i.column(),i.index()),r=s(),l=o(),a={currentType:13,offset:l,startLoc:r,endLoc:r,lastType:13,lastOffset:l,lastStartLoc:r,lastEndLoc:r,braceNest:0,inLinked:!1,text:""},u=()=>a,{onError:c}=t;function d(G,le,ge,...ke){const Ie=u();if(le.column+=ge,le.offset+=ge,c){const Oe=n?db(Ie.startLoc,le):null,we=Xy(G,Oe,{domain:XK,args:ke});c(we)}}function h(G,le,ge){G.endLoc=s(),G.currentType=le;const ke={type:le};return n&&(ke.loc=db(G.startLoc,G.endLoc)),ge!=null&&(ke.value=ge),ke}const p=G=>h(G,13);function g(G,le){return G.currentChar()===le?(G.next(),le):(d(xi.EXPECTED_TOKEN,s(),0,le),"")}function m(G){let le="";for(;G.currentPeek()===Aa||G.currentPeek()===er;)le+=G.currentPeek(),G.peek();return le}function k(G){const le=m(G);return G.skipToPeek(),le}function w(G){if(G===tu)return!1;const le=G.charCodeAt(0);return le>=97&&le<=122||le>=65&&le<=90||le===95}function y(G){if(G===tu)return!1;const le=G.charCodeAt(0);return le>=48&&le<=57}function b(G,le){const{currentType:ge}=le;if(ge!==2)return!1;m(G);const ke=w(G.currentPeek());return G.resetPeek(),ke}function A(G,le){const{currentType:ge}=le;if(ge!==2)return!1;m(G);const ke=G.currentPeek()==="-"?G.peek():G.currentPeek(),Ie=y(ke);return G.resetPeek(),Ie}function T(G,le){const{currentType:ge}=le;if(ge!==2)return!1;m(G);const ke=G.currentPeek()===Fw;return G.resetPeek(),ke}function S(G,le){const{currentType:ge}=le;if(ge!==7)return!1;m(G);const ke=G.currentPeek()===".";return G.resetPeek(),ke}function x(G,le){const{currentType:ge}=le;if(ge!==8)return!1;m(G);const ke=w(G.currentPeek());return G.resetPeek(),ke}function _(G,le){const{currentType:ge}=le;if(!(ge===7||ge===11))return!1;m(G);const ke=G.currentPeek()===":";return G.resetPeek(),ke}function L(G,le){const{currentType:ge}=le;if(ge!==9)return!1;const ke=()=>{const Oe=G.currentPeek();return Oe==="{"?w(G.peek()):Oe==="@"||Oe==="|"||Oe===":"||Oe==="."||Oe===Aa||!Oe?!1:Oe===er?(G.peek(),ke()):N(G,!1)},Ie=ke();return G.resetPeek(),Ie}function M(G){m(G);const le=G.currentPeek()==="|";return G.resetPeek(),le}function N(G,le=!0){const ge=(Ie=!1,Oe="")=>{const we=G.currentPeek();return we==="{"||we==="@"||!we?Ie:we==="|"?!(Oe===Aa||Oe===er):we===Aa?(G.peek(),ge(!0,Aa)):we===er?(G.peek(),ge(!0,er)):!0},ke=ge();return le&&G.resetPeek(),ke}function I(G,le){const ge=G.currentChar();return ge===tu?tu:le(ge)?(G.next(),ge):null}function z(G){const le=G.charCodeAt(0);return le>=97&&le<=122||le>=65&&le<=90||le>=48&&le<=57||le===95||le===36}function H(G){return I(G,z)}function O(G){const le=G.charCodeAt(0);return le>=97&&le<=122||le>=65&&le<=90||le>=48&&le<=57||le===95||le===36||le===45}function R(G){return I(G,O)}function j(G){const le=G.charCodeAt(0);return le>=48&&le<=57}function $(G){return I(G,j)}function W(G){const le=G.charCodeAt(0);return le>=48&&le<=57||le>=65&&le<=70||le>=97&&le<=102}function P(G){return I(G,W)}function Z(G){let le="",ge="";for(;le=$(G);)ge+=le;return ge}function ae(G){let le="";for(;;){const ge=G.currentChar();if(ge==="\\"){const ke=G.peek();ke==="{"||ke==="}"||ke==="@"||ke==="|"||ke==="\\"?(le+=ge+ke,G.next(),G.next()):(G.resetPeek(),le+=ge,G.next())}else{if(ge==="{"||ge==="}"||ge==="@"||ge==="|"||!ge)break;if(ge===Aa||ge===er)if(N(G))le+=ge,G.next();else{if(M(G))break;le+=ge,G.next()}else le+=ge,G.next()}}return le}function V(G){k(G);let le="",ge="";for(;le=R(G);)ge+=le;const ke=G.currentChar();if(ke&&ke!=="}"&&ke!==tu&&ke!==Aa&&ke!==er&&ke!==" "){const Ie=Ne(G);return d(xi.INVALID_TOKEN_IN_PLACEHOLDER,s(),0,ge+Ie),ge+Ie}return G.currentChar()===tu&&d(xi.UNTERMINATED_CLOSING_BRACE,s(),0),ge}function Y(G){k(G);let le="";return G.currentChar()==="-"?(G.next(),le+=`-${Z(G)}`):le+=Z(G),G.currentChar()===tu&&d(xi.UNTERMINATED_CLOSING_BRACE,s(),0),le}function oe(G){return G!==Fw&&G!==er}function q(G){k(G),g(G,"'");let le="",ge="";for(;le=I(G,oe);)le==="\\"?ge+=ne(G):ge+=le;const ke=G.currentChar();return ke===er||ke===tu?(d(xi.UNTERMINATED_SINGLE_QUOTE_IN_PLACEHOLDER,s(),0),ke===er&&(G.next(),g(G,"'")),ge):(g(G,"'"),ge)}function ne(G){const le=G.currentChar();switch(le){case"\\":case"'":return G.next(),`\\${le}`;case"u":return ie(G,le,4);case"U":return ie(G,le,6);default:return d(xi.UNKNOWN_ESCAPE_SEQUENCE,s(),0,le),""}}function ie(G,le,ge){g(G,le);let ke="";for(let Ie=0;Ie<ge;Ie++){const Oe=P(G);if(!Oe){d(xi.INVALID_UNICODE_ESCAPE_SEQUENCE,s(),0,`\\${le}${ke}${G.currentChar()}`);break}ke+=Oe}return`\\${le}${ke}`}function pe(G){return G!=="{"&&G!=="}"&&G!==Aa&&G!==er}function Ne(G){k(G);let le="",ge="";for(;le=I(G,pe);)ge+=le;return ge}function te(G){let le="",ge="";for(;le=H(G);)ge+=le;return ge}function be(G){const le=ge=>{const ke=G.currentChar();return ke==="{"||ke==="@"||ke==="|"||ke==="("||ke===")"||!ke||ke===Aa?ge:(ge+=ke,G.next(),le(ge))};return le("")}function Q(G){k(G);const le=g(G,"|");return k(G),le}function ue(G,le){let ge=null;switch(G.currentChar()){case"{":return le.braceNest>=1&&d(xi.NOT_ALLOW_NEST_PLACEHOLDER,s(),0),G.next(),ge=h(le,2,"{"),k(G),le.braceNest++,ge;case"}":return le.braceNest>0&&le.currentType===2&&d(xi.EMPTY_PLACEHOLDER,s(),0),G.next(),ge=h(le,3,"}"),le.braceNest--,le.braceNest>0&&k(G),le.inLinked&&le.braceNest===0&&(le.inLinked=!1),ge;case"@":return le.braceNest>0&&d(xi.UNTERMINATED_CLOSING_BRACE,s(),0),ge=Ae(G,le)||p(le),le.braceNest=0,ge;default:{let Ie=!0,Oe=!0,we=!0;if(M(G))return le.braceNest>0&&d(xi.UNTERMINATED_CLOSING_BRACE,s(),0),ge=h(le,1,Q(G)),le.braceNest=0,le.inLinked=!1,ge;if(le.braceNest>0&&(le.currentType===4||le.currentType===5||le.currentType===6))return d(xi.UNTERMINATED_CLOSING_BRACE,s(),0),le.braceNest=0,se(G,le);if(Ie=b(G,le))return ge=h(le,4,V(G)),k(G),ge;if(Oe=A(G,le))return ge=h(le,5,Y(G)),k(G),ge;if(we=T(G,le))return ge=h(le,6,q(G)),k(G),ge;if(!Ie&&!Oe&&!we)return ge=h(le,12,Ne(G)),d(xi.INVALID_TOKEN_IN_PLACEHOLDER,s(),0,ge.value),k(G),ge;break}}return ge}function Ae(G,le){const{currentType:ge}=le;let ke=null;const Ie=G.currentChar();switch((ge===7||ge===8||ge===11||ge===9)&&(Ie===er||Ie===Aa)&&d(xi.INVALID_LINKED_FORMAT,s(),0),Ie){case"@":return G.next(),ke=h(le,7,"@"),le.inLinked=!0,ke;case".":return k(G),G.next(),h(le,8,".");case":":return k(G),G.next(),h(le,9,":");default:return M(G)?(ke=h(le,1,Q(G)),le.braceNest=0,le.inLinked=!1,ke):S(G,le)||_(G,le)?(k(G),Ae(G,le)):x(G,le)?(k(G),h(le,11,te(G))):L(G,le)?(k(G),Ie==="{"?ue(G,le)||ke:h(le,10,be(G))):(ge===7&&d(xi.INVALID_LINKED_FORMAT,s(),0),le.braceNest=0,le.inLinked=!1,se(G,le))}}function se(G,le){let ge={type:13};if(le.braceNest>0)return ue(G,le)||p(le);if(le.inLinked)return Ae(G,le)||p(le);switch(G.currentChar()){case"{":return ue(G,le)||p(le);case"}":return d(xi.UNBALANCED_CLOSING_BRACE,s(),0),G.next(),h(le,3,"}");case"@":return Ae(G,le)||p(le);default:{if(M(G))return ge=h(le,1,Q(G)),le.braceNest=0,le.inLinked=!1,ge;if(N(G))return h(le,0,ae(G));break}}return ge}function re(){const{currentType:G,offset:le,startLoc:ge,endLoc:ke}=a;return a.lastType=G,a.lastOffset=le,a.lastStartLoc=ge,a.lastEndLoc=ke,a.offset=o(),a.startLoc=s(),i.currentChar()===tu?h(a,13):se(i,a)}return{nextToken:re,currentOffset:o,currentPosition:s,context:u}}const tV="parser",nV=/(?:\\\\|\\'|\\u([0-9a-fA-F]{4})|\\U([0-9a-fA-F]{6}))/g,iV=/\\([\\@{}|])/g;function oV(e,t){return t}function sV(e,t,n){switch(e){case"\\\\":return"\\";case"\\'":return"'";default:{const i=parseInt(t||n,16);return i<=55295||i>=57344?String.fromCodePoint(i):"�"}}}function rV(e={}){const t=e.location!==!1,{onError:n}=e;function i(w,y,b,A,...T){const S=w.currentPosition();if(S.offset+=A,S.column+=A,n){const x=t?db(b,S):null,_=Xy(y,x,{domain:tV,args:T});n(_)}}function o(w,y,b){const A={type:w};return t&&(A.start=y,A.end=y,A.loc={start:b,end:b}),A}function s(w,y,b,A){t&&(w.end=y,w.loc&&(w.loc.end=b))}function r(w,y){const b=w.context(),A=o(3,b.offset,b.startLoc);return A.value=y.replace(iV,oV),s(A,w.currentOffset(),w.currentPosition()),A}function l(w,y){const b=w.context(),{lastOffset:A,lastStartLoc:T}=b,S=o(5,A,T);return S.index=parseInt(y,10),w.nextToken(),s(S,w.currentOffset(),w.currentPosition()),S}function a(w,y){const b=w.context(),{lastOffset:A,lastStartLoc:T}=b,S=o(4,A,T);return S.key=y,w.nextToken(),s(S,w.currentOffset(),w.currentPosition()),S}function u(w,y){const b=w.context(),{lastOffset:A,lastStartLoc:T}=b,S=o(9,A,T);return S.value=y.replace(nV,sV),w.nextToken(),s(S,w.currentOffset(),w.currentPosition()),S}function c(w){const y=w.nextToken(),b=w.context(),{lastOffset:A,lastStartLoc:T}=b,S=o(8,A,T);return y.type!==11?(i(w,xi.UNEXPECTED_EMPTY_LINKED_MODIFIER,b.lastStartLoc,0),S.value="",s(S,A,T),{nextConsumeToken:y,node:S}):(y.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,Ca(y)),S.value=y.value||"",s(S,w.currentOffset(),w.currentPosition()),{node:S})}function d(w,y){const b=w.context(),A=o(7,b.offset,b.startLoc);return A.value=y,s(A,w.currentOffset(),w.currentPosition()),A}function h(w){const y=w.context(),b=o(6,y.offset,y.startLoc);let A=w.nextToken();if(A.type===8){const T=c(w);b.modifier=T.node,A=T.nextConsumeToken||w.nextToken()}switch(A.type!==9&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(A)),A=w.nextToken(),A.type===2&&(A=w.nextToken()),A.type){case 10:A.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(A)),b.key=d(w,A.value||"");break;case 4:A.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(A)),b.key=a(w,A.value||"");break;case 5:A.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(A)),b.key=l(w,A.value||"");break;case 6:A.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(A)),b.key=u(w,A.value||"");break;default:{i(w,xi.UNEXPECTED_EMPTY_LINKED_KEY,y.lastStartLoc,0);const T=w.context(),S=o(7,T.offset,T.startLoc);return S.value="",s(S,T.offset,T.startLoc),b.key=S,s(b,T.offset,T.startLoc),{nextConsumeToken:A,node:b}}}return s(b,w.currentOffset(),w.currentPosition()),{node:b}}function p(w){const y=w.context(),b=y.currentType===1?w.currentOffset():y.offset,A=y.currentType===1?y.endLoc:y.startLoc,T=o(2,b,A);T.items=[];let S=null;do{const L=S||w.nextToken();switch(S=null,L.type){case 0:L.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(L)),T.items.push(r(w,L.value||""));break;case 5:L.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(L)),T.items.push(l(w,L.value||""));break;case 4:L.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(L)),T.items.push(a(w,L.value||""));break;case 6:L.value==null&&i(w,xi.UNEXPECTED_LEXICAL_ANALYSIS,y.lastStartLoc,0,Ca(L)),T.items.push(u(w,L.value||""));break;case 7:{const M=h(w);T.items.push(M.node),S=M.nextConsumeToken||null;break}}}while(y.currentType!==13&&y.currentType!==1);const x=y.currentType===1?y.lastOffset:w.currentOffset(),_=y.currentType===1?y.lastEndLoc:w.currentPosition();return s(T,x,_),T}function g(w,y,b,A){const T=w.context();let S=A.items.length===0;const x=o(1,y,b);x.cases=[],x.cases.push(A);do{const _=p(w);S||(S=_.items.length===0),x.cases.push(_)}while(T.currentType!==13);return S&&i(w,xi.MUST_HAVE_MESSAGES_IN_PLURAL,b,0),s(x,w.currentOffset(),w.currentPosition()),x}function m(w){const y=w.context(),{offset:b,startLoc:A}=y,T=p(w);return y.currentType===13?T:g(w,b,A,T)}function k(w){const y=eV(w,ts({},e)),b=y.context(),A=o(0,b.offset,b.startLoc);return t&&A.loc&&(A.loc.source=w),A.body=m(y),e.onCacheKey&&(A.cacheKey=e.onCacheKey(w)),b.currentType!==13&&i(y,xi.UNEXPECTED_LEXICAL_ANALYSIS,b.lastStartLoc,0,w[b.offset]||""),s(A,y.currentOffset(),y.currentPosition()),A}return{parse:k}}function Ca(e){if(e.type===13)return"EOF";const t=(e.value||"").replace(/\r?\n/gu,"\\n");return t.length>10?t.slice(0,9)+"…":t}function lV(e,t={}){const n={ast:e,helpers:new Set};return{context:()=>n,helper:s=>(n.helpers.add(s),s)}}function Dw(e,t){for(let n=0;n<e.length;n++)X5(e[n],t)}function X5(e,t){switch(e.type){case 1:Dw(e.cases,t),t.helper("plural");break;case 2:Dw(e.items,t);break;case 6:{X5(e.key,t),t.helper("linked"),t.helper("type");break}case 5:t.helper("interpolate"),t.helper("list");break;case 4:t.helper("interpolate"),t.helper("named");break}}function aV(e,t={}){const n=lV(e);n.helper("normalize"),e.body&&X5(e.body,n);const i=n.context();e.helpers=Array.from(i.helpers)}function uV(e){const t=e.body;return t.type===2?Bw(t):t.cases.forEach(n=>Bw(n)),e}function Bw(e){if(e.items.length===1){const t=e.items[0];(t.type===3||t.type===9)&&(e.static=t.value,delete t.value)}else{const t=[];for(let n=0;n<e.items.length;n++){const i=e.items[n];if(!(i.type===3||i.type===9)||i.value==null)break;t.push(i.value)}if(t.length===e.items.length){e.static=J5(t);for(let n=0;n<e.items.length;n++){const i=e.items[n];(i.type===3||i.type===9)&&delete i.value}}}}function ih(e){switch(e.t=e.type,e.type){case 0:{const t=e;ih(t.body),t.b=t.body,delete t.body;break}case 1:{const t=e,n=t.cases;for(let i=0;i<n.length;i++)ih(n[i]);t.c=n,delete t.cases;break}case 2:{const t=e,n=t.items;for(let i=0;i<n.length;i++)ih(n[i]);t.i=n,delete t.items,t.static&&(t.s=t.static,delete t.static);break}case 3:case 9:case 8:case 7:{const t=e;t.value&&(t.v=t.value,delete t.value);break}case 6:{const t=e;ih(t.key),t.k=t.key,delete t.key,t.modifier&&(ih(t.modifier),t.m=t.modifier,delete t.modifier);break}case 5:{const t=e;t.i=t.index,delete t.index;break}case 4:{const t=e;t.k=t.key,delete t.key;break}}delete e.type}function cV(e,t){const{filename:n,breakLineCode:i,needIndent:o}=t,s=t.location!==!1,r={filename:n,code:"",column:1,line:1,offset:0,map:void 0,breakLineCode:i,needIndent:o,indentLevel:0};s&&e.loc&&(r.source=e.loc.source);const l=()=>r;function a(m,k){r.code+=m}function u(m,k=!0){const w=k?i:"";a(o?w+" ".repeat(m):w)}function c(m=!0){const k=++r.indentLevel;m&&u(k)}function d(m=!0){const k=--r.indentLevel;m&&u(k)}function h(){u(r.indentLevel)}return{context:l,push:a,indent:c,deindent:d,newline:h,helper:m=>`_${m}`,needIndent:()=>r.needIndent}}function dV(e,t){const{helper:n}=e;e.push(`${n("linked")}(`),Gh(e,t.key),t.modifier?(e.push(", "),Gh(e,t.modifier),e.push(", _type")):e.push(", undefined, _type"),e.push(")")}function fV(e,t){const{helper:n,needIndent:i}=e;e.push(`${n("normalize")}([`),e.indent(i());const o=t.items.length;for(let s=0;s<o&&(Gh(e,t.items[s]),s!==o-1);s++)e.push(", ");e.deindent(i()),e.push("])")}function hV(e,t){const{helper:n,needIndent:i}=e;if(t.cases.length>1){e.push(`${n("plural")}([`),e.indent(i());const o=t.cases.length;for(let s=0;s<o&&(Gh(e,t.cases[s]),s!==o-1);s++)e.push(", ");e.deindent(i()),e.push("])")}}function pV(e,t){t.body?Gh(e,t.body):e.push("null")}function Gh(e,t){const{helper:n}=e;switch(t.type){case 0:pV(e,t);break;case 1:hV(e,t);break;case 2:fV(e,t);break;case 6:dV(e,t);break;case 8:e.push(JSON.stringify(t.value),t);break;case 7:e.push(JSON.stringify(t.value),t);break;case 5:e.push(`${n("interpolate")}(${n("list")}(${t.index}))`,t);break;case 4:e.push(`${n("interpolate")}(${n("named")}(${JSON.stringify(t.key)}))`,t);break;case 9:e.push(JSON.stringify(t.value),t);break;case 3:e.push(JSON.stringify(t.value),t);break}}const gV=(e,t={})=>{const n=Gt(t.mode)?t.mode:"normal",i=Gt(t.filename)?t.filename:"message.intl";t.sourceMap;const o=t.breakLineCode!=null?t.breakLineCode:n==="arrow"?";":` -`,s=t.needIndent?t.needIndent:n!=="arrow",r=e.helpers||[],l=cV(e,{filename:i,breakLineCode:o,needIndent:s});l.push(n==="normal"?"function __msg__ (ctx) {":"(ctx) => {"),l.indent(s),r.length>0&&(l.push(`const { ${J5(r.map(c=>`${c}: _${c}`),", ")} } = ctx`),l.newline()),l.push("return "),Gh(l,e),l.deindent(s),l.push("}"),delete e.helpers;const{code:a,map:u}=l.context();return{ast:e,code:a,map:u?u.toJSON():void 0}};function mV(e,t={}){const n=ts({},t),i=!!n.jit,o=!!n.minify,s=n.optimize==null?!0:n.optimize,l=rV(n).parse(e);return i?(s&&uV(l),o&&ih(l),{ast:l,code:""}):(aV(l,n),gV(l,n))}/*! - * core-base v11.4.6 - * (c) 2026 kazuya kawaguchi - * Released under the MIT License. - */function vV(){typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Bd().__INTLIFY_PROD_DEVTOOLS__=!1),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Bd().__INTLIFY_DROP_MESSAGE_COMPILER__=!1)}function za(e){return mi(e)&&e6(e)===0&&(Fl(e,"b")||Fl(e,"body"))}const MF=["b","body"];function yV(e){return zc(e,MF)}const IF=["c","cases"];function kV(e){return zc(e,IF,[])}const EF=["s","static"];function bV(e){return zc(e,EF)}const TF=["i","items"];function AV(e){return zc(e,TF,[])}const LF=["t","type"];function e6(e){return zc(e,LF)}const NF=["v","value"];function hm(e,t){const n=zc(e,NF);if(n!=null)return n;throw k0(t)}const FF=["m","modifier"];function CV(e){return zc(e,FF)}const DF=["k","key"];function wV(e){const t=zc(e,DF);if(t)return t;throw k0(6)}function zc(e,t,n){for(let i=0;i<t.length;i++){const o=t[i];if(Fl(e,o)&&e[o]!=null)return e[o]}return n}const BF=[...MF,...IF,...EF,...TF,...DF,...FF,...NF,...LF];function k0(e){return new Error(`unhandled node type: ${e}`)}function G4(e){return n=>xV(n,e)}function xV(e,t){const n=yV(t);if(n==null)throw k0(0);if(e6(n)===1){const s=kV(n);return e.plural(s.reduce((r,l)=>[...r,$w(e,l)],[]))}else return $w(e,n)}function $w(e,t){const n=bV(t);if(n!=null)return e.type==="text"?n:e.normalize([n]);{const i=AV(t).reduce((o,s)=>[...o,fb(e,s)],[]);return e.normalize(i)}}function fb(e,t){const n=e6(t);switch(n){case 3:return hm(t,n);case 9:return hm(t,n);case 4:{const i=t;if(Fl(i,"k")&&i.k)return e.interpolate(e.named(i.k));if(Fl(i,"key")&&i.key)return e.interpolate(e.named(i.key));throw k0(n)}case 5:{const i=t;if(Fl(i,"i")&&Jo(i.i))return e.interpolate(e.list(i.i));if(Fl(i,"index")&&Jo(i.index))return e.interpolate(e.list(i.index));throw k0(n)}case 6:{const i=t,o=CV(i),s=wV(i);return e.linked(fb(e,s),o?fb(e,o):void 0,e.type)}case 7:return hm(t,n);case 8:return hm(t,n);default:throw new Error(`unhandled node on format message part: ${n}`)}}const SV=e=>e;let pm=Ri();function _V(e,t={}){let n=!1;const i=t.onError||VK;return t.onError=o=>{n=!0,i(o)},{...mV(e,t),detectError:n}}function MV(e,t){if(!__INTLIFY_DROP_MESSAGE_COMPILER__&&Gt(e)){pi(t.warnHtmlMessage)&&t.warnHtmlMessage;const i=(t.onCacheKey||SV)(e),o=pm[i];if(o)return o;const{ast:s,detectError:r}=_V(e,{...t,location:!1,jit:!0}),l=G4(s);return r?l:pm[i]=l}else{const n=e.cacheKey;if(n){const i=pm[n];return i||(pm[n]=G4(e))}else return G4(e)}}let b0=null;function IV(e){b0=e}function EV(e,t,n){b0&&b0.emit("i18n:init",{timestamp:Date.now(),i18n:e,version:t,meta:n})}const TV=LV("function:translate");function LV(e){return t=>b0&&b0.emit(e,t)}const hu={INVALID_ARGUMENT:KK,INVALID_DATE_ARGUMENT:18,INVALID_ISO_DATE_ARGUMENT:19,NOT_SUPPORT_LOCALE_PROMISE_VALUE:21,NOT_SUPPORT_LOCALE_ASYNC_FUNCTION:22,NOT_SUPPORT_LOCALE_TYPE:23},NV=24;function pu(e){return Xy(e,null,void 0)}function t6(e,t){return t.locale!=null?Rw(t.locale):Rw(e.locale)}let Q4;function Rw(e){if(Gt(e))return e;if(uo(e)){if(e.resolvedOnce&&Q4!=null)return Q4;if(e.constructor.name==="Function"){const t=e();if(WK(t))throw pu(hu.NOT_SUPPORT_LOCALE_PROMISE_VALUE);return Q4=t}else throw pu(hu.NOT_SUPPORT_LOCALE_ASYNC_FUNCTION)}else throw pu(hu.NOT_SUPPORT_LOCALE_TYPE)}function FV(e,t,n){return[...new Set([n,...No(t)?t:mi(t)?Object.keys(t):Gt(t)?[t]:[n]])]}function hb(e,t,n){const i=Gt(n)?n:A0,o=e;o.__localeChainCache||(o.__localeChainCache=new Map);let s=o.__localeChainCache.get(i);if(!s){s=[];let r=[n];for(;No(r);)r=zw(s,r,t);const l=No(t)||!li(t)?t:t.default?t.default:null;r=Gt(l)?[l]:l,No(r)&&zw(s,r,!1),o.__localeChainCache.set(i,s)}return s}function zw(e,t,n){let i=!0;for(let o=0;o<t.length&&pi(i);o++){const s=t[o];Gt(s)&&(i=DV(e,t[o],n))}return i}function DV(e,t,n){let i;const o=t.split("-");do{const s=o.join("-");i=BV(e,s,n),o.splice(-1,1)}while(o.length&&i===!0);return i}function BV(e,t,n){let i=!1;if(!e.includes(t)&&(i=!0,t)){i=t[t.length-1]!=="!";const o=t.replace(/!/g,"");e.push(o),(No(n)||li(n))&&n[o]&&(i=n[o])}return i}const Oc=[];Oc[0]={w:[0],i:[3,0],"[":[4],o:[7]};Oc[1]={w:[1],".":[2],"[":[4],o:[7]};Oc[2]={w:[2],i:[3,0],0:[3,0]};Oc[3]={i:[3,0],0:[3,0],w:[1,1],".":[2,1],"[":[4,1],o:[7,1]};Oc[4]={"'":[5,0],'"':[6,0],"[":[4,2],"]":[1,3],o:8,l:[4,0]};Oc[5]={"'":[4,0],o:8,l:[5,0]};Oc[6]={'"':[4,0],o:8,l:[6,0]};const $V=/^\s?(?:true|false|-?[\d.]+|'[^']*'|"[^"]*")\s?$/;function RV(e){return $V.test(e)}function zV(e){const t=e.charCodeAt(0),n=e.charCodeAt(e.length-1);return t===n&&(t===34||t===39)?e.slice(1,-1):e}function OV(e){if(e==null)return"o";switch(e.charCodeAt(0)){case 91:case 93:case 46:case 34:case 39:return e;case 95:case 36:case 45:return"i";case 9:case 10:case 13:case 160:case 65279:case 8232:case 8233:return"w"}return"i"}function PV(e){const t=e.trim();return e.charAt(0)==="0"&&isNaN(parseInt(e))?!1:RV(t)?zV(t):"*"+t}function jV(e){const t=[];let n=-1,i=0,o=0,s,r,l,a,u,c,d;const h=[];h[0]=()=>{r===void 0?r=l:r+=l},h[1]=()=>{r!==void 0&&(t.push(r),r=void 0)},h[2]=()=>{h[0](),o++},h[3]=()=>{if(o>0)o--,i=4,h[0]();else{if(o=0,r===void 0||(r=PV(r),r===!1))return!1;h[1]()}};function p(){const g=e[n+1];if(i===5&&g==="'"||i===6&&g==='"')return n++,l="\\"+g,h[0](),!0}for(;i!==null;)if(n++,s=e[n],!(s==="\\"&&p())){if(a=OV(s),d=Oc[i],u=d[a]||d.l||8,u===8||(i=u[0],u[1]!==void 0&&(c=h[u[1]],c&&(l=s,c()===!1))))return;if(i===7)return t}}const Ow=new Map;function HV(e,t){return mi(e)?e[t]:null}function WV(e,t){if(!mi(e))return null;let n=Ow.get(t);if(n||(n=jV(t),n&&Ow.set(t,n)),!n)return null;const i=n.length;let o=e,s=0;for(;s<i;){const r=n[s];if(BF.includes(r)&&za(o)||!mi(o)||!Fl(o,r))return null;const l=o[r];if(l===void 0||uo(o))return null;o=l,s++}return o}const qV="11.4.6",e9=-1,A0="en-US",g2="",Pw=e=>`${e.charAt(0).toLocaleUpperCase()}${e.substr(1)}`;function UV(){return{upper:(e,t)=>t==="text"&&Gt(e)?e.toUpperCase():t==="vnode"&&mi(e)&&"__v_isVNode"in e?e.children.toUpperCase():e,lower:(e,t)=>t==="text"&&Gt(e)?e.toLowerCase():t==="vnode"&&mi(e)&&"__v_isVNode"in e?e.children.toLowerCase():e,capitalize:(e,t)=>t==="text"&&Gt(e)?Pw(e):t==="vnode"&&mi(e)&&"__v_isVNode"in e?Pw(e.children):e}}let $F;function KV(e){$F=e}let RF;function VV(e){RF=e}let zF;function ZV(e){zF=e}let OF=null;const GV=e=>{OF=e},QV=()=>OF;let PF=null;const jw=e=>{PF=e},YV=()=>PF;let Hw=0;function JV(e={}){const t=uo(e.onWarn)?e.onWarn:FK,n=Gt(e.version)?e.version:qV,i=Gt(e.locale)||uo(e.locale)?e.locale:A0,o=uo(i)?A0:i,s=No(e.fallbackLocale)||li(e.fallbackLocale)||Gt(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:o,r=li(e.messages)?e.messages:Y4(o),l=li(e.datetimeFormats)?e.datetimeFormats:Y4(o),a=li(e.numberFormats)?e.numberFormats:Y4(o),u=ts(Ri(),e.modifiers,UV()),c=e.pluralRules||Ri(),d=uo(e.missing)?e.missing:null,h=pi(e.missingWarn)||Zh(e.missingWarn)?e.missingWarn:!0,p=pi(e.fallbackWarn)||Zh(e.fallbackWarn)?e.fallbackWarn:!0,g=!!e.fallbackFormat,m=!!e.unresolving,k=uo(e.postTranslation)?e.postTranslation:null,w=li(e.processor)?e.processor:null,y=pi(e.warnHtmlMessage)?e.warnHtmlMessage:!0,b=!!e.escapeParameter,A=uo(e.messageCompiler)?e.messageCompiler:$F,T=uo(e.messageResolver)?e.messageResolver:RF||HV,S=uo(e.localeFallbacker)?e.localeFallbacker:zF||FV,x=mi(e.fallbackContext)?e.fallbackContext:void 0,_=e,L=mi(_.__datetimeFormatters)?_.__datetimeFormatters:new Map,M=mi(_.__numberFormatters)?_.__numberFormatters:new Map,N=mi(_.__meta)?_.__meta:{};Hw++;const I={version:n,cid:Hw,locale:i,fallbackLocale:s,messages:r,modifiers:u,pluralRules:c,missing:d,missingWarn:h,fallbackWarn:p,fallbackFormat:g,unresolving:m,postTranslation:k,processor:w,warnHtmlMessage:y,escapeParameter:b,messageCompiler:A,messageResolver:T,localeFallbacker:S,fallbackContext:x,onWarn:t,__meta:N};return I.datetimeFormats=l,I.numberFormats=a,I.__datetimeFormatters=L,I.__numberFormatters=M,__INTLIFY_PROD_DEVTOOLS__&&EV(I,n,N),I}const Y4=e=>({[e]:Ri()});function n6(e,t,n,i,o){const{missing:s,onWarn:r}=e;if(s!==null){const l=s(e,n,t,o);return Gt(l)?l:t}else return t}function W1(e,t,n){const i=e;i.__localeChainCache=new Map,e.localeFallbacker(e,n,t)}function XV(e,t){return e===t?!1:e.split("-")[0]===t.split("-")[0]}function eZ(e,t){const n=t.indexOf(e);if(n===-1)return!1;for(let i=n+1;i<t.length;i++)if(XV(e,t[i]))return!0;return!1}function Ww(e,...t){const{datetimeFormats:n,unresolving:i,fallbackLocale:o,onWarn:s,localeFallbacker:r}=e,{__datetimeFormatters:l}=e;if(!Gt(t[0])&&!SF(t[0])&&!Jo(t[0]))return g2;const[a,u,c,d]=pb(...t),h=pi(c.missingWarn)?c.missingWarn:e.missingWarn;pi(c.fallbackWarn)?c.fallbackWarn:e.fallbackWarn;const p=!!c.part,g=t6(e,c),m=r(e,o,g);if(!Gt(a)||a===""){const S=new Intl.DateTimeFormat(g.replace(/!/g,""),d);return p?S.formatToParts(u):S.format(u)}let k={},w,y=null;const b="datetime format";for(let S=0;S<m.length&&(w=m[S],k=n[w]||{},y=k[a],!li(y));S++)n6(e,a,w,h,b);if(!li(y)||!Gt(w))return i?e9:a;let A=`${w}__${a}`;Jy(d)||(A=`${A}__${JSON.stringify(d)}`);let T=l.get(A);return T||(T=new Intl.DateTimeFormat(w,ts({},y,d)),l.set(A,T)),p?T.formatToParts(u):T.format(u)}const jF=["localeMatcher","weekday","era","year","month","day","hour","minute","second","timeZoneName","formatMatcher","hour12","timeZone","dateStyle","timeStyle","calendar","dayPeriod","numberingSystem","hourCycle","fractionalSecondDigits"];function pb(...e){const[t,n,i,o]=e,s=Ri();let r=Ri(),l;if(Gt(t)){const a=t.match(/(\d{4}-\d{2}-\d{2})(T|\s)?(.*)/);if(!a)throw pu(hu.INVALID_ISO_DATE_ARGUMENT);const u=a[3]?a[3].trim().startsWith("T")?`${a[1].trim()}${a[3].trim()}`:`${a[1].trim()}T${a[3].trim()}`:a[1].trim();l=new Date(u);try{l.toISOString()}catch{throw pu(hu.INVALID_ISO_DATE_ARGUMENT)}}else if(SF(t)){if(isNaN(t.getTime()))throw pu(hu.INVALID_DATE_ARGUMENT);l=t}else if(Jo(t))l=t;else throw pu(hu.INVALID_ARGUMENT);return Gt(n)?s.key=n:li(n)&&Object.keys(n).forEach(a=>{jF.includes(a)?r[a]=n[a]:s[a]=n[a]}),Gt(i)?s.locale=i:li(i)&&(r=i),li(o)&&(r=o),[s.key||"",l,s,r]}function qw(e,t,n){const i=e;for(const o in n){const s=`${t}__${o}`;i.__datetimeFormatters.has(s)&&i.__datetimeFormatters.delete(s)}}function Uw(e,...t){const{numberFormats:n,unresolving:i,fallbackLocale:o,onWarn:s,localeFallbacker:r}=e,{__numberFormatters:l}=e;if(!Jo(t[0]))return g2;const[a,u,c,d]=gb(...t),h=pi(c.missingWarn)?c.missingWarn:e.missingWarn;pi(c.fallbackWarn)?c.fallbackWarn:e.fallbackWarn;const p=!!c.part,g=t6(e,c),m=r(e,o,g);if(!Gt(a)||a===""){const S=new Intl.NumberFormat(g.replace(/!/g,""),d);return p?S.formatToParts(u):S.format(u)}let k={},w,y=null;const b="number format";for(let S=0;S<m.length&&(w=m[S],k=n[w]||{},y=k[a],!li(y));S++)n6(e,a,w,h,b);if(!li(y)||!Gt(w))return i?e9:a;let A=`${w}__${a}`;Jy(d)||(A=`${A}__${JSON.stringify(d)}`);let T=l.get(A);return T||(T=new Intl.NumberFormat(w,ts({},y,d)),l.set(A,T)),p?T.formatToParts(u):T.format(u)}const HF=["localeMatcher","style","currency","currencyDisplay","currencySign","useGrouping","minimumIntegerDigits","minimumFractionDigits","maximumFractionDigits","minimumSignificantDigits","maximumSignificantDigits","compactDisplay","notation","signDisplay","unit","unitDisplay","roundingMode","roundingPriority","roundingIncrement","trailingZeroDisplay"];function gb(...e){const[t,n,i,o]=e,s=Ri();let r=Ri();if(!Jo(t))throw pu(hu.INVALID_ARGUMENT);const l=t;return Gt(n)?s.key=n:li(n)&&Object.keys(n).forEach(a=>{HF.includes(a)?r[a]=n[a]:s[a]=n[a]}),Gt(i)?s.locale=i:li(i)&&(r=i),li(o)&&(r=o),[s.key||"",l,s,r]}function Kw(e,t,n){const i=e;for(const o in n){const s=`${t}__${o}`;i.__numberFormatters.has(s)&&i.__numberFormatters.delete(s)}}const tZ=e=>e,nZ=e=>"",iZ="text",oZ=e=>e.length===0?"":J5(e),sZ=qK;function J4(e,t){return e=Math.abs(e),t===2?e===1?0:1:Math.min(e,2)}function rZ(e){const t=Jo(e.pluralIndex)?e.pluralIndex:-1;return Jo(e.named?.count)?e.named.count:Jo(e.named?.n)?e.named.n:t}function lZ(e={}){const t=e.locale,n=rZ(e),i=Gt(t)&&uo(e.pluralRules?.[t])?e.pluralRules[t]:J4,o=i===J4?void 0:J4,s=w=>w[i(n,w.length,o)],r=e.list||[],l=w=>r[w],a=e.named||Ri();Jo(e.pluralIndex)&&(a.count||=e.pluralIndex,a.n||=e.pluralIndex);const u=w=>a[w];function c(w,y){const b=uo(e.messages)?e.messages(w,!!y):mi(e.messages)?e.messages[w]:!1;return b||(e.parent?e.parent.message(w):nZ)}const d=w=>e.modifiers?e.modifiers[w]:tZ,h=uo(e.processor?.normalize)?e.processor.normalize:oZ,p=uo(e.processor?.interpolate)?e.processor.interpolate:sZ,g=Gt(e.processor?.type)?e.processor.type:iZ,k={list:l,named:u,plural:s,linked:(w,...y)=>{const[b,A]=y;let T="text",S="";y.length===1?mi(b)?(S=b.modifier||S,T=b.type||T):Gt(b)&&(S=b||S):y.length===2&&(Gt(b)&&(S=b||S),Gt(A)&&(T=A||T));const x=c(w,!0)(k),_=x===""||x===void 0?w:x,L=T==="vnode"&&No(_)&&S?_[0]:_;return S?d(S)(L,T):L},message:c,type:g,interpolate:p,normalize:h,values:ts(Ri(),r,a)};return k}const Vw=()=>"",Tl=e=>uo(e);function Zw(e,...t){const{fallbackFormat:n,postTranslation:i,unresolving:o,messageCompiler:s,fallbackLocale:r,messages:l}=e,[a,u]=mb(...t),c=pi(u.missingWarn)?u.missingWarn:e.missingWarn,d=pi(u.fallbackWarn)?u.fallbackWarn:e.fallbackWarn,h=pi(u.escapeParameter)?u.escapeParameter:e.escapeParameter,p=!!u.resolvedMessage,g=Gt(u.default)||pi(u.default)?pi(u.default)?s?a:()=>a:u.default:n?s?a:()=>a:null,m=n||g!=null&&(Gt(g)||uo(g)),k=t6(e,u);h&&aZ(u);let[w,y,b]=p?[a,k,l[k]||Ri()]:WF(e,a,k,r,d,c),A=w,T=a;if(!p&&!(Gt(A)||za(A)||Tl(A))&&m&&(A=g,T=A),!p&&(!(Gt(A)||za(A)||Tl(A))||!Gt(y)))return o?e9:a;let S=!1;const x=()=>{S=!0},_=Tl(A)?A:qF(e,a,y,A,T,x);if(S)return A;const L=dZ(e,y,b,u),M=lZ(L),N=uZ(e,_,M);let I=i?i(N,a):N;if(h&&Gt(I)&&(I=jK(I)),__INTLIFY_PROD_DEVTOOLS__){const z={timestamp:Date.now(),key:Gt(a)?a:Tl(A)?A.key:"",locale:y||(Tl(A)?A.locale:""),format:Gt(A)?A:Tl(A)?A.source:"",message:I};z.meta=ts({},e.__meta,QV()||{}),TV(z)}return I}function aZ(e){No(e.list)?e.list=e.list.map(t=>Gt(t)?Lw(t):t):mi(e.named)&&Object.keys(e.named).forEach(t=>{Gt(e.named[t])&&(e.named[t]=Lw(e.named[t]))})}function WF(e,t,n,i,o,s){const{messages:r,onWarn:l,messageResolver:a,localeFallbacker:u}=e,c=u(e,i,n);let d=Ri(),h,p=null;const g="translate";for(let m=0;m<c.length&&(h=c[m],d=r[h]||Ri(),(p=a(d,t))===null&&(p=d[t]),!(Gt(p)||za(p)||Tl(p)));m++)if(!eZ(h,c)){const k=n6(e,t,h,s,g);k!==t&&(p=k)}return[p,h,d]}function qF(e,t,n,i,o,s){const{messageCompiler:r,warnHtmlMessage:l}=e;if(Tl(i)){const u=i;return u.locale=u.locale||n,u.key=u.key||t,u}if(r==null){const u=(()=>i);return u.locale=n,u.key=t,u}const a=r(i,cZ(e,n,o,i,l,s));return a.locale=n,a.key=t,a.source=i,a}function uZ(e,t,n){return t(n)}function mb(...e){const[t,n,i]=e,o=Ri();if(!Gt(t)&&!Jo(t)&&!Tl(t)&&!za(t))throw pu(hu.INVALID_ARGUMENT);const s=Jo(t)?String(t):(Tl(t),t);return Jo(n)?o.plural=n:Gt(n)?o.default=n:li(n)&&!Jy(n)?o.named=n:No(n)&&(o.list=n),Jo(i)?o.plural=i:Gt(i)?o.default=i:li(i)&&ts(o,i),[s,o]}function cZ(e,t,n,i,o,s){return{locale:t,key:n,warnHtmlMessage:o,onError:r=>{throw s&&s(r),r},onCacheKey:r=>DK(t,n,r)}}function dZ(e,t,n,i){const{modifiers:o,pluralRules:s,messageResolver:r,fallbackLocale:l,fallbackWarn:a,missingWarn:u,fallbackContext:c}=e,h={locale:t,modifiers:o,pluralRules:s,messages:(p,g)=>{let m=r(n,p);if(m==null&&(c||g)){const[k,,w]=WF(c||e,p,t,l,a,u);m=k??r(w,p)}if(Gt(m)||za(m)){let k=!1;const y=qF(e,p,t,m,p,()=>{k=!0});return k?Vw:y}else return Tl(m)?m:Vw}};return e.processor&&(h.processor=e.processor),i.list&&(h.list=i.list),i.named&&(h.named=i.named),Jo(i.plural)&&(h.pluralIndex=i.plural),h}vV();/*! - * vue-i18n v11.4.6 - * (c) 2026 kazuya kawaguchi - * Released under the MIT License. - */const fZ="11.4.6";function hZ(){typeof __VUE_I18N_FULL_INSTALL__!="boolean"&&(Bd().__VUE_I18N_FULL_INSTALL__=!0),typeof __VUE_I18N_LEGACY_API__!="boolean"&&(Bd().__VUE_I18N_LEGACY_API__=!0),typeof __INTLIFY_DROP_MESSAGE_COMPILER__!="boolean"&&(Bd().__INTLIFY_DROP_MESSAGE_COMPILER__=!1),typeof __INTLIFY_PROD_DEVTOOLS__!="boolean"&&(Bd().__INTLIFY_PROD_DEVTOOLS__=!1)}const kr={UNEXPECTED_RETURN_TYPE:NV,INVALID_ARGUMENT:25,MUST_BE_CALL_SETUP_TOP:26,NOT_INSTALLED:27,REQUIRED_VALUE:28,INVALID_VALUE:29,NOT_INSTALLED_WITH_PROVIDE:31,UNEXPECTED_ERROR:32,NOT_AVAILABLE_COMPOSITION_IN_LEGACY:34};function qr(e,...t){return Xy(e,null,void 0)}const vb=Rc("__translateVNode"),yb=Rc("__datetimeParts"),kb=Rc("__numberParts"),UF=Rc("__setPluralRules"),KF=Rc("__injectWithOption"),hh=Rc("__dispose");function C0(e){if(!mi(e)||za(e))return e;for(const t in e)if(Fl(e,t))if(!t.includes("."))mi(e[t])&&C0(e[t]);else{const n=t.split("."),i=n.length-1;let o=e,s=!1;for(let r=0;r<i;r++){if(n[r]==="__proto__")throw new Error(`unsafe key: ${n[r]}`);if(n[r]in o||(o[n[r]]=Ri()),!mi(o[n[r]])){s=!0;break}o=o[n[r]]}if(s||(za(o)?BF.includes(n[i])||delete e[t]:(o[n[i]]=e[t],delete e[t])),!za(o)){const r=o[n[i]];mi(r)&&C0(r)}}return e}function i6(e,t){const{messages:n,__i18n:i,messageResolver:o,flatJson:s}=t,r=li(n)?n:No(i)?Ri():{[e]:Ri()};if(No(i)&&i.forEach(l=>{if("locale"in l&&"resource"in l){const{locale:a,resource:u}=l;a?(r[a]=r[a]||Ri(),vv(u,r[a])):vv(u,r)}else Gt(l)&&vv(JSON.parse(l),r)}),o==null&&s)for(const l in r)Fl(r,l)&&C0(r[l]);return r}function VF(e){return e.type}function ZF(e,t,n){let i=mi(t.messages)?t.messages:Ri();"__i18nGlobal"in n&&(i=i6(e.locale.value,{messages:i,__i18n:n.__i18nGlobal}));const o=Object.keys(i);o.length&&o.forEach(s=>{e.mergeLocaleMessage(s,i[s])});{if(mi(t.datetimeFormats)){const s=Object.keys(t.datetimeFormats);s.length&&s.forEach(r=>{e.mergeDateTimeFormat(r,t.datetimeFormats[r])})}if(mi(t.numberFormats)){const s=Object.keys(t.numberFormats);s.length&&s.forEach(r=>{e.mergeNumberFormat(r,t.numberFormats[r])})}}}function Gw(e){return U(hc,null,e,0)}function w0(){return os()}const Qw="__INTLIFY_META__",Yw=()=>[],pZ=()=>!1;let Jw=0;function Xw(e){return((t,n,i,o)=>e(n,i,w0()||void 0,o))}const gZ=()=>{const e=w0();let t=null;return e&&(t=VF(e)[Qw])?{[Qw]:t}:null};function m2(e={}){const{__root:t,__injectWithOption:n}=e,i=t===void 0,o=e.flatJson,s=p2?K:ha;let r=pi(e.inheritLocale)?e.inheritLocale:!0;const l=s(t&&r?t.locale.value:Gt(e.locale)?e.locale:A0),a=s(t&&r?t.fallbackLocale.value:Gt(e.fallbackLocale)||No(e.fallbackLocale)||li(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:l.value),u=s(i6(l.value,e)),c=s(li(e.datetimeFormats)?e.datetimeFormats:{[l.value]:{}}),d=s(li(e.numberFormats)?e.numberFormats:{[l.value]:{}});let h=t?t.missingWarn:pi(e.missingWarn)||Zh(e.missingWarn)?e.missingWarn:!0,p=t?t.fallbackWarn:pi(e.fallbackWarn)||Zh(e.fallbackWarn)?e.fallbackWarn:!0,g=t?t.fallbackRoot:pi(e.fallbackRoot)?e.fallbackRoot:!0,m=!!e.fallbackFormat,k=uo(e.missing)?e.missing:null,w=uo(e.missing)?Xw(e.missing):null,y=uo(e.postTranslation)?e.postTranslation:null,b=t?t.warnHtmlMessage:pi(e.warnHtmlMessage)?e.warnHtmlMessage:!0,A=!!e.escapeParameter;const T=t?t.modifiers:li(e.modifiers)?e.modifiers:{};let S=e.pluralRules||t&&t.pluralRules,x;x=(()=>{i&&jw(null);const we={version:fZ,locale:l.value,fallbackLocale:a.value,messages:u.value,modifiers:T,pluralRules:S,missing:w===null?void 0:w,missingWarn:h,fallbackWarn:p,fallbackFormat:m,unresolving:!0,postTranslation:y===null?void 0:y,warnHtmlMessage:b,escapeParameter:A,messageResolver:e.messageResolver,messageCompiler:e.messageCompiler,__meta:{framework:"vue"}};we.datetimeFormats=c.value,we.numberFormats=d.value,we.__datetimeFormatters=li(x)?x.__datetimeFormatters:void 0,we.__numberFormatters=li(x)?x.__numberFormatters:void 0;const Be=JV(we);return i&&jw(Be),Be})(),W1(x,l.value,a.value);function L(){return[l.value,a.value,u.value,c.value,d.value]}const M=F({get:()=>l.value,set:we=>{x.locale=we,l.value=we}}),N=F({get:()=>a.value,set:we=>{x.fallbackLocale=we,a.value=we,W1(x,l.value,we)}}),I=F(()=>u.value),z=F(()=>c.value),H=F(()=>d.value);function O(){return uo(y)?y:null}function R(we){y=we,x.postTranslation=we}function j(){return k}function $(we){we!==null&&(w=Xw(we)),k=we,x.missing=w}const W=(we,Be,tt,ut,_t,Ct)=>{L();let $t;try{__INTLIFY_PROD_DEVTOOLS__,i||(x.fallbackContext=t?YV():void 0),$t=we(x)}finally{__INTLIFY_PROD_DEVTOOLS__,i||(x.fallbackContext=void 0)}if(tt!=="translate exists"&&Jo($t)&&$t===e9||tt==="translate exists"&&!$t){const[Vt,nn]=Be();return t&&g?ut(t):_t(Vt)}else{if(Ct($t))return $t;throw qr(kr.UNEXPECTED_RETURN_TYPE)}};function P(...we){return W(Be=>Reflect.apply(Zw,null,[Be,...we]),()=>mb(...we),"translate",Be=>Reflect.apply(Be.t,Be,[...we]),Be=>Be,Be=>Gt(Be))}function Z(...we){const[Be,tt,ut]=we;if(ut&&!mi(ut))throw qr(kr.INVALID_ARGUMENT);return P(Be,tt,ts({resolvedMessage:!0},ut||{}))}function ae(...we){return W(Be=>Reflect.apply(Ww,null,[Be,...we]),()=>pb(...we),"datetime format",Be=>Reflect.apply(Be.d,Be,[...we]),()=>g2,Be=>Gt(Be)||No(Be))}function V(...we){return W(Be=>Reflect.apply(Uw,null,[Be,...we]),()=>gb(...we),"number format",Be=>Reflect.apply(Be.n,Be,[...we]),()=>g2,Be=>Gt(Be)||No(Be))}function Y(we){return we.map(Be=>Gt(Be)||Jo(Be)||pi(Be)?Gw(String(Be)):Be)}const q={normalize:Y,interpolate:we=>we,type:"vnode"};function ne(...we){return W(Be=>{let tt;const ut=Be;try{ut.processor=q,tt=Reflect.apply(Zw,null,[ut,...we])}finally{ut.processor=null}return tt},()=>mb(...we),"translate",Be=>Be[vb](...we),Be=>[Gw(Be)],Be=>No(Be))}function ie(...we){return W(Be=>Reflect.apply(Uw,null,[Be,...we]),()=>gb(...we),"number format",Be=>Be[kb](...we),Yw,Be=>Gt(Be)||No(Be))}function pe(...we){return W(Be=>Reflect.apply(Ww,null,[Be,...we]),()=>pb(...we),"datetime format",Be=>Be[yb](...we),Yw,Be=>Gt(Be)||No(Be))}function Ne(we){S=we,x.pluralRules=S}function te(we,Be){return W(()=>{if(!we)return!1;const tt=Gt(Be)?Be:l.value,ut=Gt(Be)?[tt]:hb(x,a.value,tt);for(let _t=0;_t<ut.length;_t++){const Ct=ue(ut[_t]);let $t=x.messageResolver(Ct,we);if($t===null&&($t=Ct[we]),za($t)||Tl($t)||Gt($t))return!0}return!1},()=>[we],"translate exists",tt=>Reflect.apply(tt.te,tt,[we,Be]),pZ,tt=>pi(tt))}function be(we){let Be=null;const tt=hb(x,a.value,l.value);for(let ut=0;ut<tt.length;ut++){const _t=u.value[tt[ut]]||{},Ct=x.messageResolver(_t,we);if(Ct!=null){Be=Ct;break}}return Be}function Q(we){const Be=be(we);return Be??(t?t.tm(we)||{}:{})}function ue(we){return u.value[we]||{}}function Ae(we,Be){if(o){const tt={[we]:Be};for(const ut in tt)Fl(tt,ut)&&C0(tt[ut]);Be=tt[we]}u.value[we]=Be,x.messages=u.value}function se(we,Be){u.value[we]=u.value[we]||{};const tt={[we]:Be};if(o)for(const ut in tt)Fl(tt,ut)&&C0(tt[ut]);Be=tt[we],vv(Be,u.value[we]),x.messages=u.value}function re(we){return c.value[we]||{}}function G(we,Be){c.value[we]=Be,x.datetimeFormats=c.value,qw(x,we,Be)}function le(we,Be){c.value[we]=ts(c.value[we]||{},Be),x.datetimeFormats=c.value,qw(x,we,Be)}function ge(we){return d.value[we]||{}}function ke(we,Be){d.value[we]=Be,x.numberFormats=d.value,Kw(x,we,Be)}function Ie(we,Be){d.value[we]=ts(d.value[we]||{},Be),x.numberFormats=d.value,Kw(x,we,Be)}Jw++,t&&p2&&(Pe(t.locale,we=>{r&&(l.value=we,x.locale=we,W1(x,l.value,a.value))}),Pe(t.fallbackLocale,we=>{r&&(a.value=we,x.fallbackLocale=we,W1(x,l.value,a.value))}));const Oe={id:Jw,locale:M,fallbackLocale:N,get inheritLocale(){return r},set inheritLocale(we){r=we,we&&t&&(l.value=t.locale.value,a.value=t.fallbackLocale.value,W1(x,l.value,a.value))},get availableLocales(){return Object.keys(u.value).sort()},messages:I,get modifiers(){return T},get pluralRules(){return S||{}},get isGlobal(){return i},get missingWarn(){return h},set missingWarn(we){h=we,x.missingWarn=h},get fallbackWarn(){return p},set fallbackWarn(we){p=we,x.fallbackWarn=p},get fallbackRoot(){return g},set fallbackRoot(we){g=we},get fallbackFormat(){return m},set fallbackFormat(we){m=we,x.fallbackFormat=m},get warnHtmlMessage(){return b},set warnHtmlMessage(we){b=we,x.warnHtmlMessage=we},get escapeParameter(){return A},set escapeParameter(we){A=we,x.escapeParameter=we},t:P,getLocaleMessage:ue,setLocaleMessage:Ae,mergeLocaleMessage:se,getPostTranslationHandler:O,setPostTranslationHandler:R,getMissingHandler:j,setMissingHandler:$,[UF]:Ne};return Oe.datetimeFormats=z,Oe.numberFormats=H,Oe.rt=Z,Oe.te=te,Oe.tm=Q,Oe.d=ae,Oe.n=V,Oe.getDateTimeFormat=re,Oe.setDateTimeFormat=G,Oe.mergeDateTimeFormat=le,Oe.getNumberFormat=ge,Oe.setNumberFormat=ke,Oe.mergeNumberFormat=Ie,Oe[KF]=n,Oe[vb]=ne,Oe[yb]=pe,Oe[kb]=ie,Oe}function mZ(e){const t=Gt(e.locale)?e.locale:A0,n=Gt(e.fallbackLocale)||No(e.fallbackLocale)||li(e.fallbackLocale)||e.fallbackLocale===!1?e.fallbackLocale:t,i=uo(e.missing)?e.missing:void 0,o=pi(e.silentTranslationWarn)||Zh(e.silentTranslationWarn)?!e.silentTranslationWarn:!0,s=pi(e.silentFallbackWarn)||Zh(e.silentFallbackWarn)?!e.silentFallbackWarn:!0,r=pi(e.fallbackRoot)?e.fallbackRoot:!0,l=!!e.formatFallbackMessages,a=li(e.modifiers)?e.modifiers:{},u=e.pluralizationRules,c=uo(e.postTranslation)?e.postTranslation:void 0,d=Gt(e.warnHtmlInMessage)?e.warnHtmlInMessage!=="off":!0,h=!!e.escapeParameterHtml,p=pi(e.sync)?e.sync:!0;let g=e.messages;if(li(e.sharedMessages)){const T=e.sharedMessages;g=Object.keys(T).reduce((x,_)=>{const L=x[_]||(x[_]={});return ts(L,T[_]),x},g||{})}const{__i18n:m,__root:k,__injectWithOption:w}=e,y=e.datetimeFormats,b=e.numberFormats,A=e.flatJson;return{locale:t,fallbackLocale:n,messages:g,flatJson:A,datetimeFormats:y,numberFormats:b,missing:i,missingWarn:o,fallbackWarn:s,fallbackRoot:r,fallbackFormat:l,modifiers:a,pluralRules:u,postTranslation:c,warnHtmlMessage:d,escapeParameter:h,messageResolver:e.messageResolver,inheritLocale:p,__i18n:m,__root:k,__injectWithOption:w}}function bb(e={}){const t=m2(mZ(e)),{__extender:n}=e,i={id:t.id,get locale(){return t.locale.value},set locale(o){t.locale.value=o},get fallbackLocale(){return t.fallbackLocale.value},set fallbackLocale(o){t.fallbackLocale.value=o},get messages(){return t.messages.value},get datetimeFormats(){return t.datetimeFormats.value},get numberFormats(){return t.numberFormats.value},get availableLocales(){return t.availableLocales},get missing(){return t.getMissingHandler()},set missing(o){t.setMissingHandler(o)},get silentTranslationWarn(){return pi(t.missingWarn)?!t.missingWarn:t.missingWarn},set silentTranslationWarn(o){t.missingWarn=pi(o)?!o:o},get silentFallbackWarn(){return pi(t.fallbackWarn)?!t.fallbackWarn:t.fallbackWarn},set silentFallbackWarn(o){t.fallbackWarn=pi(o)?!o:o},get modifiers(){return t.modifiers},get formatFallbackMessages(){return t.fallbackFormat},set formatFallbackMessages(o){t.fallbackFormat=o},get postTranslation(){return t.getPostTranslationHandler()},set postTranslation(o){t.setPostTranslationHandler(o)},get sync(){return t.inheritLocale},set sync(o){t.inheritLocale=o},get warnHtmlInMessage(){return t.warnHtmlMessage?"warn":"off"},set warnHtmlInMessage(o){t.warnHtmlMessage=o!=="off"},get escapeParameterHtml(){return t.escapeParameter},set escapeParameterHtml(o){t.escapeParameter=o},get pluralizationRules(){return t.pluralRules||{}},__composer:t,t(...o){return Reflect.apply(t.t,t,[...o])},rt(...o){return Reflect.apply(t.rt,t,[...o])},te(o,s){return t.te(o,s)},tm(o){return t.tm(o)},getLocaleMessage(o){return t.getLocaleMessage(o)},setLocaleMessage(o,s){t.setLocaleMessage(o,s)},mergeLocaleMessage(o,s){t.mergeLocaleMessage(o,s)},d(...o){return Reflect.apply(t.d,t,[...o])},getDateTimeFormat(o){return t.getDateTimeFormat(o)},setDateTimeFormat(o,s){t.setDateTimeFormat(o,s)},mergeDateTimeFormat(o,s){t.mergeDateTimeFormat(o,s)},n(...o){return Reflect.apply(t.n,t,[...o])},getNumberFormat(o){return t.getNumberFormat(o)},setNumberFormat(o,s){t.setNumberFormat(o,s)},mergeNumberFormat(o,s){t.mergeNumberFormat(o,s)}};return i.__extender=n,i}function vZ(e,t,n){return{beforeCreate(){const i=w0();if(!i)throw qr(kr.UNEXPECTED_ERROR);const o=this.$options;if(o.i18n){const s=o.i18n;if(o.__i18n&&(s.__i18n=o.__i18n),s.__root=t,this===this.$root)this.$i18n=ex(e,s);else{s.__injectWithOption=!0,s.__extender=n.__vueI18nExtend,this.$i18n=bb(s);const r=this.$i18n;r.__extender&&(r.__disposer=r.__extender(this.$i18n))}}else if(o.__i18n)if(this===this.$root)this.$i18n=ex(e,o);else{this.$i18n=bb({__i18n:o.__i18n,__injectWithOption:!0,__extender:n.__vueI18nExtend,__root:t});const s=this.$i18n;s.__extender&&(s.__disposer=s.__extender(this.$i18n))}else this.$i18n=e;o.__i18nGlobal&&ZF(t,o,o),this.$t=(...s)=>this.$i18n.t(...s),this.$rt=(...s)=>this.$i18n.rt(...s),this.$te=(s,r)=>this.$i18n.te(s,r),this.$d=(...s)=>this.$i18n.d(...s),this.$n=(...s)=>this.$i18n.n(...s),this.$tm=s=>this.$i18n.tm(s),n.__setInstance(i,this.$i18n)},mounted(){},unmounted(){const i=w0();if(!i)throw qr(kr.UNEXPECTED_ERROR);const o=this.$i18n;o&&(delete this.$t,delete this.$rt,delete this.$te,delete this.$d,delete this.$n,delete this.$tm,o?.__disposer&&(o.__disposer(),delete o.__disposer,delete o.__extender),n.__deleteInstance(i),delete this.$i18n)}}}function ex(e,t){e.locale=t.locale||e.locale,e.fallbackLocale=t.fallbackLocale||e.fallbackLocale,e.missing=t.missing||e.missing,e.silentTranslationWarn=t.silentTranslationWarn||e.silentFallbackWarn,e.silentFallbackWarn=t.silentFallbackWarn||e.silentFallbackWarn,e.formatFallbackMessages=t.formatFallbackMessages||e.formatFallbackMessages,e.postTranslation=t.postTranslation||e.postTranslation,e.warnHtmlInMessage=t.warnHtmlInMessage||e.warnHtmlInMessage,e.escapeParameterHtml=t.escapeParameterHtml||e.escapeParameterHtml,e.sync=t.sync||e.sync,e.__composer[UF](t.pluralizationRules||e.pluralizationRules);const n=i6(e.locale,{messages:t.messages,__i18n:t.__i18n});return Object.keys(n).forEach(i=>e.mergeLocaleMessage(i,n[i])),t.datetimeFormats&&Object.keys(t.datetimeFormats).forEach(i=>e.mergeDateTimeFormat(i,t.datetimeFormats[i])),t.numberFormats&&Object.keys(t.numberFormats).forEach(i=>e.mergeNumberFormat(i,t.numberFormats[i])),e}const o6={tag:{type:[String,Object]},locale:{type:String},scope:{type:String,validator:e=>e==="parent"||e==="global",default:"parent"},i18n:{type:Object}};function yZ({slots:e},t){return t.length===1&&t[0]==="default"?(e.default?e.default():[]).reduce((i,o)=>[...i,...o.type===Ee?o.children:[o]],[]):t.reduce((n,i)=>{const o=e[i];return o&&(n[i]=o()),n},Ri())}function GF(){return Ee}const kZ=Xe({name:"i18n-t",props:ts({keypath:{type:String,required:!0},plural:{type:[Number,String],validator:e=>Jo(e)||!isNaN(e)}},o6),setup(e,t){const{slots:n,attrs:i}=t,o=e.i18n||zt({useScope:e.scope,__useComponent:!0});return()=>{const s=()=>{const a=Object.keys(n).filter(d=>d[0]!=="_"),u=Ri();e.locale&&(u.locale=e.locale),e.plural!==void 0&&(u.plural=Gt(e.plural)?+e.plural:e.plural);const c=yZ(t,a);return o[vb](e.keypath,c,u)},r=ts(Ri(),i),l=Gt(e.tag)||mi(e.tag)?e.tag:GF();return mi(l)?yn(l,r,{default:s}):yn(l,r,s())}}}),tx=kZ;function bZ(e){return No(e)&&!Gt(e[0])}function QF(e,t,n,i){const{slots:o,attrs:s}=t;return()=>{const r=()=>{const u={part:!0};let c=Ri();e.locale&&(u.locale=e.locale),Gt(e.format)?u.key=e.format:mi(e.format)&&(Gt(e.format.key)&&(u.key=e.format.key),c=Object.keys(e.format).reduce((p,g)=>n.includes(g)?ts(Ri(),p,{[g]:e.format[g]}):p,Ri()));const d=i(e.value,u,c);let h=[u.key];return No(d)?h=d.map((p,g)=>{const m=o[p.type],k=m?m({[p.type]:p.value,index:g,parts:d}):[p.value];return bZ(k)&&(k[0].key=`${p.type}-${g}`),k}):Gt(d)&&(h=[d]),h},l=ts(Ri(),s),a=Gt(e.tag)||mi(e.tag)?e.tag:GF();return mi(a)?yn(a,l,{default:r}):yn(a,l,r())}}const AZ=Xe({name:"i18n-n",props:ts({value:{type:Number,required:!0},format:{type:[String,Object]}},o6),setup(e,t){const n=e.i18n||zt({useScope:e.scope,__useComponent:!0});return QF(e,t,HF,(...i)=>n[kb](...i))}}),nx=AZ;function CZ(e,t){const n=e;if(e.mode==="composition")return n.__getInstance(t)||e.global;{const i=n.__getInstance(t);return i!=null?i.__composer:e.global.__composer}}function wZ(e){const t=r=>{const{instance:l,value:a}=r;if(!l||!l.$)throw qr(kr.UNEXPECTED_ERROR);const u=CZ(e,l.$),c=ix(a);return[Reflect.apply(u.t,u,[...ox(c)]),u]};return{created:(r,l)=>{const[a,u]=t(l);p2&&(r.__i18nWatcher=Pe(u.locale,()=>{l.instance&&l.instance.$forceUpdate()})),r.__composer=u,r.textContent=a},unmounted:r=>{p2&&r.__i18nWatcher&&(r.__i18nWatcher(),r.__i18nWatcher=void 0,delete r.__i18nWatcher),r.__composer&&(r.__composer=void 0,delete r.__composer)},beforeUpdate:(r,{value:l})=>{if(r.__composer){const a=r.__composer,u=ix(l);r.textContent=Reflect.apply(a.t,a,[...ox(u)])}},getSSRProps:r=>{const[l]=t(r);return{textContent:l}}}}function ix(e){if(Gt(e))return{path:e};if(li(e)){if(!("path"in e))throw qr(kr.REQUIRED_VALUE,"path");return e}else throw qr(kr.INVALID_VALUE)}function ox(e){const{path:t,locale:n,args:i,choice:o,plural:s}=e,r={},l=i||{};return Gt(n)&&(r.locale=n),Jo(o)&&(r.plural=o),Jo(s)&&(r.plural=s),[t,l,r]}function xZ(e,t,...n){const i=li(n[0])?n[0]:{};(pi(i.globalInstall)?i.globalInstall:!0)&&([tx.name,"I18nT"].forEach(s=>e.component(s,tx)),[nx.name,"I18nN"].forEach(s=>e.component(s,nx)),[lx.name,"I18nD"].forEach(s=>e.component(s,lx))),e.directive("t",wZ(t))}const SZ=Rc("global-vue-i18n");function _Z(e={}){const t=__VUE_I18N_LEGACY_API__&&pi(e.legacy)?e.legacy:__VUE_I18N_LEGACY_API__,n=pi(e.globalInjection)?e.globalInjection:!0,i=new Map,[o,s]=MZ(e,t),r=Rc("");function l(d){return i.get(d)||null}function a(d,h){i.set(d,h)}function u(d){i.delete(d)}const c={get mode(){return __VUE_I18N_LEGACY_API__&&t?"legacy":"composition"},async install(d,...h){if(d.__VUE_I18N_SYMBOL__=r,d.provide(d.__VUE_I18N_SYMBOL__,c),li(h[0])){const m=h[0];c.__composerExtend=m.__composerExtend,c.__vueI18nExtend=m.__vueI18nExtend}let p=null;!t&&n&&(p=DZ(d,c.global)),__VUE_I18N_FULL_INSTALL__&&xZ(d,c,...h),__VUE_I18N_LEGACY_API__&&t&&d.mixin(vZ(s,s.__composer,c));const g=d.unmount;d.unmount=()=>{p&&p(),c.dispose(),g()}},get global(){return s},dispose(){o.stop()},__instances:i,__getInstance:l,__setInstance:a,__deleteInstance:u};return c}function zt(e={}){const t=w0();if(t==null)throw qr(kr.MUST_BE_CALL_SETUP_TOP);if(!t.isCE&&t.appContext.app!=null&&!t.appContext.app.__VUE_I18N_SYMBOL__)throw qr(kr.NOT_INSTALLED);const n=IZ(t),i=TZ(n),o=VF(t),s=EZ(e,o);if(s==="global")return ZF(i,e,o),i;if(s==="parent"){let a=sx(n,t,e.__useComponent);return a==null&&(a=i),a}if(s==="isolated"){if(n.mode!=="composition")throw qr(kr.NOT_AVAILABLE_COMPOSITION_IN_LEGACY);const a=n,u=ts({},e),c=sx(n,t);u.__root=c||i;const d=m2(u);return a.__composerExtend&&(d[hh]=a.__composerExtend(d)),Y0()&&Bc(()=>{const p=d[hh];p&&(p(),delete d[hh])}),d}const r=n;let l=r.__getInstance(t);if(l==null){const a=ts({},e);"__i18n"in o&&(a.__i18n=o.__i18n),i&&(a.__root=i),l=m2(a),r.__composerExtend&&(l[hh]=r.__composerExtend(l)),NZ(r,t,l),r.__setInstance(t,l)}return l}function MZ(e,t){const n=F5(),i=__VUE_I18N_LEGACY_API__&&t?n.run(()=>bb(e)):n.run(()=>m2(e));if(i==null)throw qr(kr.UNEXPECTED_ERROR);return[n,i]}function IZ(e){const t=hn(e.isCE?SZ:e.appContext.app.__VUE_I18N_SYMBOL__);if(!t)throw qr(e.isCE?kr.NOT_INSTALLED_WITH_PROVIDE:kr.UNEXPECTED_ERROR);return t}function EZ(e,t){return Jy(e)?"__i18n"in t?"local":"global":e.useScope?e.useScope:"local"}function TZ(e){return e.mode==="composition"?e.global:e.global.__composer}function sx(e,t,n=!1){let i=null;const o=t.root;let s=LZ(t,n);for(;s!=null;){const r=e;if(e.mode==="composition")i=r.__getInstance(s);else if(__VUE_I18N_LEGACY_API__){const l=r.__getInstance(s);l!=null&&(i=l.__composer,n&&i&&!i[KF]&&(i=null))}if(i!=null||o===s)break;s=s.parent}return i}function LZ(e,t=!1){return e==null?null:t&&e.vnode.ctx||e.parent}function NZ(e,t,n){cn(()=>{},t),_n(()=>{const i=n;e.__deleteInstance(t);const o=i[hh];o&&(o(),delete i[hh])},t)}const FZ=["locale","fallbackLocale","availableLocales"],rx=["t","rt","d","n","tm","te"];function DZ(e,t){const n=Object.create(null);return FZ.forEach(o=>{const s=Object.getOwnPropertyDescriptor(t,o);if(!s)throw qr(kr.UNEXPECTED_ERROR);const r=io(s.value)?{get(){return s.value.value},set(l){s.value.value=l}}:{get(){return s.get&&s.get()}};Object.defineProperty(n,o,r)}),e.config.globalProperties.$i18n=n,rx.forEach(o=>{const s=Object.getOwnPropertyDescriptor(t,o);if(!s||!s.value)throw qr(kr.UNEXPECTED_ERROR);Object.defineProperty(e.config.globalProperties,`$${o}`,s)}),()=>{delete e.config.globalProperties.$i18n,rx.forEach(o=>{delete e.config.globalProperties[`$${o}`]})}}const BZ=Xe({name:"i18n-d",props:ts({value:{type:[Number,Date],required:!0},format:{type:[String,Object]}},o6),setup(e,t){const n=e.i18n||zt({useScope:e.scope,__useComponent:!0});return QF(e,t,jF,(...i)=>n[yb](...i))}}),lx=BZ;hZ();KV(MV);VV(WV);ZV(hb);if(__INTLIFY_PROD_DEVTOOLS__){const e=Bd();e.__INTLIFY__=!0,IV(e.__INTLIFY_DEVTOOLS_GLOBAL_HOOK__)}const $Z={preview:"Preview",confirm:"Confirm",cancel:"Cancel",close:"Close",dismiss:"Dismiss",loading:"Loading",copy:"Copy"},RZ={authBannerMessage:"Not signed in · Sign in to Kimi Code to start a conversation",authBannerLogin:"Sign in",connecting:"Connecting…",internalBuildBanner:"Internal testing only",menuFile:"File",menuEdit:"Edit",menuView:"View",menuHelp:"Help",applicationMenu:"Application menu"},zZ={workspaceMeta:"workspace · {branch}",sessionsHeader:"sessions",workspaces:"workspaces",viewSwitcher:"List options",viewGroup:"View",viewFlat:"Flat list",viewGrouped:"Group by workspace",sortGroup:"Sort order",sortManual:"Manual",sortRecent:"Recent activity",sessionAdmin:"Manage Sessions",collapseAll:"Collapse all workspaces",expandAll:"Expand all workspaces",newSession:"New Session",newChat:"New Session",newWorkspace:"New Workspace",dropToAddWorkspace:"Drop to add workspace",emptyState:"No sessions yet · click New Session to start",options:"Options",rename:"Rename",genTitle:"Gen Title",genTitleUnavailable:"Title generation unavailable — needs a managed Kimi Code login and at least one message",setEmoji:"Set Emoji…",sessionEmojiTitle:"Pick an emoji",removeEmoji:"Remove emoji",randomEmoji:"Random",searchEmoji:"Search emoji",recentEmojis:"Recently used",noEmojiResults:"No matching emoji",emojiGroupFaces:"Smileys & People",emojiGroupNature:"Animals & Nature",emojiGroupFood:"Food & Drink",emojiGroupActivity:"Activities & Travel",emojiGroupObjects:"Objects & Work",emojiGroupSymbols:"Symbols & Status",copyPath:"Copy path",copySessionId:"Copy session ID",copied:"Copied ✓",copyFailed:"Copy failed",archive:"Archive",archiveToastUndo:"Undo",archiveToastMid:"or view archived chats in",archiveToastSettings:"Settings",archiveToastTail:"",tabOpen:"Open",tabDone:"Done",tabWorkspaces:"Workspaces",tagOpen:"Open",tagDone:"Done",complete:"Done",markDone:"Mark as done",reopen:"Mark as open",noDoneSessions:"No completed sessions yet",noOpenSessions:"No open sessions yet",completeToastLead:"Done",reopenToastLead:"Back to open",fork:"Fork session",export:"Export session",pin:"Pin",unpin:"Unpin",lastActive:"Last updated: {time}",pinned:"Pinned",collapsePinned:"Collapse pinned",expandPinned:"Expand pinned",resizePinnedAria:"Resize pinned section height",delete:"Delete",removeWorkspace:"Remove workspace",brand:"Kimi Code",signedIn:"Signed in",signOut:"Sign out",notSignedIn:"Not signed in",signIn:"Sign in",defaultUserName:"Kimi User",upgrade:"Upgrade",upgradeMembership:"Upgrade membership",logoutConfirmTitle:"Sign out",logoutConfirmMessage:"Are you sure you want to sign out?",language:"Language",backendTitle:"Backend {backend} · {endpoint} — click to switch",noSessions:"No conversations yet",allPinned:"{count} conversations pinned",showMore:"Show more",loadMore:"Load more",showLess:"Show less",loadingMore:"Loading…",collapseSidebar:"Collapse sidebar",expandSidebar:"Expand sidebar",searchPlaceholder:"Search sessions and workspaces",search:"Search",searchHint:"↑↓ navigate · ↵ open · Esc close",searchHintSelect:"navigate",searchHintOpen:"open",searchHintClose:"close",searchClear:"Clear search",searchNoResults:"No matching sessions or workspaces",searchEmpty:"No sessions yet",update:"Upgrade",updateAvailable:"v{version} available",updateDownloadingButton:"Downloading… ({percent}%)",updateReady:"v{version} ready",updateDone:"Restart",updateFailed:"Download failed",updateRetry:"Retry",updateDownloadNow:"Download & Update",updateSkip:"Skip This Version",updateRestartNow:"Restart Now",updateRestartLater:"Later",updateReleaseDate:"Released {date}",updateCurrentVersion:"Current v{version}",updateWhatsNew:"What’s new",updateBackground:"Download in Background",updateAutoDownload:"Automatically download and install updates",rcSelectDevice:"Select device",rcCurrentDevice:"Current device: {name}",rcConnectable:"Connectable",rcUnavailable:"Unavailable",rcOnline:"Online",rcOffline:"Offline",rcDevicesLoadFailed:"Failed to load devices"},OZ={title:"Session Management",subtitle:"Manage all sessions. Mark the finished ones as done. Filter by last updated to clean up old sessions in bulk.",back:"Back",filterWorkspace:"Workspace",filterStatus:"Status",filterTime:"Updated",allWorkspaces:"All workspaces",selectAll:"Select all",searchWorkspace:"Search workspaces",noWorkspaceMatch:"No matching workspaces",removeTag:"Remove {name}",statusAll:"All statuses",statusOpen:"Open",statusDone:"Done",timeAll:"Any time",timeDaysAgo:"{n} days ago",query:"Query",reset:"Reset",colStatus:"Status",colTitle:"Title",colWorkspace:"Workspace",colPrompt:"Last prompt",colUpdated:"Updated",colCompleted:"Completed",colActions:"Actions",empty:"No sessions match the current filters",loading:"Loading…",total:"{n} total",pageSize:"{n} / page",prevPage:"Previous page",nextPage:"Next page",selectPageAll:"Select all on this page",batchSelected:"{n} selected",selectAllMatching:"Select all {total} matching sessions",materializingAll:"Selecting…",allMatchingSelected:"All {n} selected",clearSelection:"Clear selection",markDone:"Mark as done",reopen:"Mark as open",markDoneCount:"Mark as done ({n})",reopenCount:"Mark as open ({n})",batchDoneToast:"{n} marked as done",batchReopenedToast:"{n} moved back to open",batchFailedSuffix:", {n} failed",batchDoneFailedNotice:"Could not mark {n} as done",batchReopenFailedNotice:"Could not move {n} back to open",undo:"Undo",open:"Open session",rename:"Rename…",fork:"Fork",export:"Export",moreActions:"More actions"},PZ={switcherTitle:"Switch workspace",switchTooltip:"Switch workspace",eyebrow:"Workspace",branchLabel:"branch: {branch}",noBranch:"no branch",sessionCount:"{count} session | {count} sessions",allWorkspaces:"All workspaces",currentWorkspace:"Current workspace only",addWorkspace:"Add workspace…",noWorkspace:"No workspace",deleteHasSessions:"This workspace still has sessions — archive them before deleting it",removeWorkspaceConfirm:'Remove workspace "{name}"?',swarmEnableTitle:"Enable swarm mode?",swarmEnableConfirm:"The agent will run multiple sub-agents in parallel.",goalStartTitle:"Start goal?",goalStartConfirm:'"{objective}" — the agent will run autonomously toward it.',scopeCurrent:"this workspace",scopeAll:"all workspaces",newInGroup:"New session in this workspace",addTitle:"Add workspace",pathLabel:"Path",pathPlaceholder:"/absolute/path/to/project",recentLabel:"Recent folders",add:"Add",cancel:"Cancel",addHint:"Paste an absolute folder path, or pick a recent one.",addFailed:"Couldn't open this folder. Check the path and try again.",requiredTitle:"Choose a workspace first",requiredMessage:"Pick a folder to use as your workspace before sending a message.",openThisFolder:"Open this folder",up:"Up",browsing:"Browsing…",filterPlaceholder:"Filter subfolders…",searchPlaceholder:"Fuzzy-search under this folder…",searching:"Searching…",pasteToggle:"Enter an absolute path",noFilterMatch:"No subfolders match “{q}”",noSubfolders:"No subfolders here",browseHint:'Click a folder to enter it, then "Open this folder" to add it as a workspace.',attentionTitle:"{count} item needs your attention | {count} items need your attention",awaitingAnswer:"Answer",awaitingAnswerTitle:"A question is waiting for your answer",awaitingPermission:"Approve",awaitingPermissionTitle:"An action is waiting for your approval",aborted:"Failed",abortedTitle:"This session's latest turn ended on an error"},jZ={jumpToLatestAria:"Jump to latest message",toc:"Conversation outline",newMessages:"Latest messages",loading:"Loading…",starting:"Starting conversation…",requesting:"Requesting…",working:"Working…",workingRetry:"Model request failed — retrying ({n}/{max})…",emptyWorkspaceHint:"Send in {name}",switchWorkspace:"Switch workspace",recentSessions:"Recent sessions",viewMoreSessions:"View more",sessionAdminTooltip:"View and manage more sessions in Session Management",addWorkspace:"New workspace",moreWorkspaces:"More workspaces ({count})",pickFolder:"Choose folder…",compacting:"Compacting context…",compactedPlain:"Context compacted",compactedAuto:"Context auto-compacted",compactedTokens:" ({before} → {after} tokens)",viewSummary:"View summary",summaryTitle:"Compaction summary",undo:"Undo",undoTooltip:"Undo edit",undoConfirm:"Undo last message?",escUndoHintPre:"Press",escUndoHintPost:"again to undo",undone:"Undone — the message is back in the composer",turnInterrupted:"Manually stopped",turnFailed:"Model request failed — this turn was interrupted",turnFailedMaxSteps:"Step limit reached — this turn was interrupted",turnFailedResume:"Continue",turnFailedResumeText:"Continue",yesterday:"Yesterday",loadOlder:"Load earlier messages",loadingOlder:"Loading earlier messages…",widenTable:"Widen table",restoreTableWidth:"Restore default width",cron:{fired:"Scheduled reminder fired",missed:"Missed scheduled reminders",job:"job {id}",oneShot:"one-shot",coalesced:"{n} fires coalesced",missedCount:"{n} missed",finalDelivery:"final delivery",expand:"Show more",collapse:"Show less"},fold:{worked:"Worked {duration}",workedUnknown:"Work details"},turnFiles:{titleOne:"{number} file changed",titleOther:"{number} files changed",more:"{number} more files",moreOne:"1 more file",showLess:"Show less",diffTitle:"Changes this turn",diffUnavailable:"This file’s changes can’t be shown line by line",openFile:"Open file"},goal:{continuation:"Goal continuation"},notification:{kindTask:"Background task",kindSubagent:"Subagent",title:{completed:"{kind} completed",failed:"{kind} failed",timed_out:"{kind} timed out",killed:"{kind} killed",lost:"{kind} lost",info:"{kind} notification"},status:{completed:"completed",failed:"failed",timed_out:"timed out",killed:"killed",lost:"lost",info:"info"},groupTitle:"{n} notifications",copyPath:"Copy path",copied:"Copied",rawPayload:"Raw payload",outputTruncated:"Output truncated — showing the tail",fields:{type:"Type",source:"Source",severity:"Severity"}},userMessage:{expand:"Show more",collapse:"Show less"},search:{placeholder:"Search chat…",searching:"Searching…",results:"{current}/{total} results",resultsCapped:"{current}/{total}+ results",noResults:"No results",previous:"Previous match",next:"Next match",close:"Close search"}},HZ={connectionConnected:"Connected",connectionConnecting:"Connecting…",connectionDisconnected:"Disconnected",ctxTooltip:"Used {used} / {max} tokens ({pct}%)",modelLabel:"Model",permissionManual:"Manual",permissionAuto:"Auto",permissionYolo:"YOLO",permissionManualDesc:"Ask for approval on every tool action",permissionAutoDesc:"Fully autonomous — agent decides everything without asking",permissionYoloDesc:"Auto-approve tool actions, but agent may still ask questions",planLabel:"Plan",planOn:"on",planOff:"off",planTooltip:"Toggle plan mode (research before editing)",workModeDismiss:"Exit mode",goalLabel:"Goal",timeUnitHour:"h",timeUnitMinute:"m",timeUnitSecond:"s",planEmptyArmed:"Plan mode is on — the plan the agent writes will show up here.",planEmptyIdle:"No plan yet — turn plan mode on and the agent’s plan will show up here.",swarmLabel:"Swarm",swarmDismiss:"Turn off Swarm",modeOff:"Off",goalPlaceholder:"What should the agent achieve?",planPlaceholder:"What should the agent plan for?",goalStart:"Start",goalPause:"Pause",goalResume:"Resume",goalCancel:"Cancel",goalCancelConfirm:"Cancel this goal? It cannot be resumed afterwards.",goalCancelConfirmYes:"Yes",goalCancelConfirmNo:"No",goalDoneWhen:"Done when",goalStatusActive:"Active",goalStatusPaused:"Paused",goalStatusBlocked:"Blocked",goalStatusComplete:"Complete",modeNotSupported:"Not supported",thinkingLabel:"Thinking",thinkingTooltip:"Toggle thinking mode",thinkingOn:"On",thinkingOff:"Off",cacheNote:"Note: Switching models or thinking effort invalidates the existing prompt cache. Start a new chat to avoid extra token costs.",starredModels:"Starred",moreModels:"More models…",statusPanelTitle:"Session status",statusPanelClose:"Close",statusModel:"Model",statusThinking:"Thinking",statusPermission:"Permission",statusPlanMode:"Plan mode",statusSwarmMode:"Swarm mode",swarmOn:"on",swarmOff:"off",statusContext:"Context",statusCost:"Cost",statusContextValue:"{used} / {max} ({pct}%)",statusNone:"—",activityRunning:"Running…",activityAwaitingApproval:"Awaiting approval",activityAwaitingQuestion:"Awaiting answer",interrupt:"Interrupt",runningShort:"in progress"},WZ={placeholder:"Type a message…",send:"Send ↵",queueLabel:"Queue",placeholderRunning:"Press Enter to queue · Ctrl+S to inject into the running turn",placeholderRunningMobile:"Press Enter to queue",starting:"Sending…",queuePending:"{n} waiting to send",queueSteer:"Send into the running turn",queueDragTitle:"Drag to reorder",editQueued:"Edit (load back into the input)",queuedAttachments:"attachment ×{n}",queuedHasImage:"Contains {n} image(s) — remove only, not editable",attachmentImage:"Image",attachmentVideo:"Video",attachmentFile:"File",attachmentOpenUnsupported:"Can’t open {name} — this file type isn’t supported",dropToAttach:"Drop files to attach",remove:"Remove",removeNamed:"Remove {name}",clearAll:"Clear all attachments",attachmentCount:"{n} attachments",uploading:"Uploading",uploadFailed:"Upload failed",attachFile:"Attach file",addMenu:"Add",addFiles:"Files",addFilesDesc:"Upload files",addGoalDesc:"Set a goal to keep pursuing",addPlanDesc:"Turn plan mode on",addSwarmDesc:"Turn swarm mode on",noCommands:"No commands",slashSheetTitle:"Commands",slashSearchPlaceholder:"Search commands…",mentionSheetTitle:"Files",mentionSearchPlaceholder:"Search files…",addSlash:"Commands",addSlashDesc:"Built-in commands or skills",addMention:"Mention",addMentionDesc:"Mention files in the project",previewAttachment:"Preview {name}",interrupt:"Interrupt",interruptTitle:"Interrupt current operation",expandTitle:"Expand input for multi-line editing",collapseTitle:"Collapse input",emptyConversationTitle:"Kimi Code",emptyConversation:"No messages yet — type below to start the conversation",upgradeBanner:"Upgrade your Kimi account to use Kimi Code",quickStartPlaceholder:"Type a message to start a new conversation…",thinkingSuffix:" · thinking",thinkingSuffixEffort:" · {level}"},qZ={title:"Sign in to Kimi Code",close:"Close (Esc)",regionCnTitle:"Kimi Code",regionCnHint:"Sign in with your kimi.com account",regionOverseasTitle:"Kimi Code",regionOverseasHint:"Sign in with your kimi.ai account",oauthTitle:"Sign in with Kimi",oauthHint:"Finish authorizing in your browser to sign in",starting:"Starting sign-in flow…",openedHint:"Finish authorizing in your browser ({time}).",blockedTitle:"Could not open the login page",blockedHint:"The browser blocked the automatic opening — use the button below to continue authorizing.",notOpened:"Didn't open in your browser?",authorizeInBrowser:"Sign in via browser",orDivider:"or",fallbackPrefix:"On another device? Open ",fallbackSuffix:" and enter the device code:",copy:"Copy",copied:"Copied",copyLink:"Copy link",success:"Signed in",successHint:"Loading, will close automatically…",expiredTitle:"Device code expired",expiredHint:"Please restart the sign-in flow",retry:"Retry",closeBtn:"Close",errorTitle:"The current version does not support login yet",errorHint:"Please upgrade kimi-code and try again",pollErrorTitle:"Lost connection",pollErrorHint:"Sign-in polling failed repeatedly. Check the kimi-code process and try again.",action:"Sign in",requiredTitle:"Sign in required",requiredMessage:"Sign in to your Kimi account and set up a model to start chatting.",goToLogin:"Sign in",upgradeRequiredTitle:"Upgrade required",upgradeRequiredMessage:"Your account is on the free plan. Upgrade to a membership to start chatting with Kimi models.",rcSubtitle:"Remote Control session",rcChecking:"Checking sign-in status…",rcLead:"This Remote Control session requires authorization. Sign in with your Kimi account to continue.",rcSuccessHint:"Redirecting…",rcExpiredTitle:"Authorization expired or declined",rcStartErrorTitle:"Could not start sign-in",rcSessionErrorTitle:"Could not create your session",rcConnectionErrorHint:"Check your connection and try again.",rcSuccessNoRedirect:"You can close this page now."},UZ={title:"Provider management",loading:"Loading providers…",unavailable:"Provider management is not available yet",empty:"No providers yet",status:{connected:"Connected",error:"Error",unconfigured:"Not configured"},keySet:"key set",keyNotSet:"key not set",managedBadge:"OAuth",modelCount:"{count} models",confirmDelete:"Confirm delete?",refresh:"Refresh",delete:"Delete",refreshTitle:"Refresh {type}",deleteTitle:"Delete {type}",loginKimi:"Sign in to Kimi",loginAnthropic:"Sign in to Anthropic",addProvider:"Add provider",added:"Provider added",enterApiKey:"Enter API Key",optional:"Optional",apiKeyRequired:"API Key cannot be empty",fieldId:"Name",fieldType:"API Protocol",types:{kimi:"Kimi",openai:"OpenAI",openai_responses:"OpenAI Responses",anthropic:"Anthropic","google-genai":"Google GenAI",vertexai:"Vertex AI"},fieldApiKey:"API Key",apiKeyManaged:"Signed in with OAuth",apiKeySet:"Set — enter a new key to replace",showApiKey:"Show API key",hideApiKey:"Hide API key",fieldBaseUrl:"Base URL",baseUrlPlaceholder:"https://api.example.com/v1",fieldModels:"Models",colModelId:"Model ID",colContext:"Context",colDisplayName:"Display name",modelIdPlaceholder:"kimi-k3",modelContextPlaceholder:"1048576",modelNamePlaceholder:"Optional",noModels:"No models",addModel:"Add model",removeModel:"Remove model",fieldDefaultModel:"Default model",save:"Save",saved:"Provider saved",deleteProvider:"Delete provider",deleteConfirm:"Delete {id} and its {count} models?",deleteConfirmYes:"Delete",managedHint:"Managed providers sign in and out on the Account tab",unsavedGuard:"You have unsaved changes.",guardStay:"Keep editing",guardDiscard:"Discard",add:"Add",catalog:{sourceCatalog:"From directory",sourceManual:"Manual",sourceRegistry:"Registry",registryHint:"Import providers and models from an api.json registry; re-importing the same URL refreshes it",registryUrlLabel:"Registry URL",registryImported:"{count} providers imported",searchPlaceholder:"Search providers",loading:"Loading directory…",loadError:"Failed to load the directory. Check your network and retry.",retry:"Retry",empty:"No matching providers",rejected:"Not importable",rejectReason:{"unknown-explicit-type":"Unsupported protocol","proprietary-sdk":"Proprietary SDK — cannot be imported","empty-base-url":"Blank base URL","placeholder-base-url":"Endpoint contains an env placeholder"},backToList:"Back to directory",willImport:"{count} models will be imported from the directory",overwriteWarning:"A provider with this name already exists; importing overwrites its config and models",importAction:"Import"},error:{idRequired:"Name cannot be empty",idInvalid:'Name must start with a letter or digit and may only contain letters, digits, "-", "_" and spaces',apiKeyRequired:"API Key cannot be empty",baseUrlRequired:"Base URL cannot be empty",registryUrlRequired:"Registry URL cannot be empty",modelRequired:"Model ID cannot be empty",contextSizeRequired:"Max context size cannot be empty",contextSizeInvalid:"Max context size must be a positive integer"},hintClose:"Close"},KZ={dialogLabel:"Switch model",title:"Switch model",close:"Close (Esc)",allTab:"All",providerTabs:"Model providers",searchPlaceholder:"Search models or providers…",clearSearch:"Clear search",loading:"Loading models…",unavailable:"Model list is unavailable",contextSuffix:"{size} ctx",capabilityImageInput:"Image input",capabilityVideoInput:"Video input",capabilityToolUse:"Tool use",capabilityThinking:"Thinking",capabilityAlwaysThinking:"Always thinking",emptyNoModels:"No models available",emptyNoMatch:"No matching models",starTitle:"Add to favorites",unstarTitle:"Remove from favorites",hintNavigate:"Navigate",hintSelect:"Select",hintClose:"Close"},VZ={justNow:"just now"},ZZ={title:{shell:"Run command?",diff:"Apply changes?",file:"Write file?",fileop:"File operation?",url:"Fetch URL?",search:"Search?",invocation:"Invoke?",todo:"Update todo?",plan_review:"Ready to build with this plan?",generic:"Approve action?"},subagentBadge:"sub agent · {name}",danger:"Danger: {detail}",searchQueryLabel:"query",searchScope:"scope: {scope}",feedbackPlaceholder:"Explain why you are rejecting… (Enter to submit, Shift+Enter for a new line, Esc to cancel)",feedbackHint:"Enter to submit · Shift+Enter for a new line · Esc to cancel",approve:"Approve",approveSession:"Approve for session",reject:"Reject",feedback:"Feedback",feedbackSubmit:"Reject with feedback",feedbackCancel:"Cancel",approvePlan:"Approve plan",revise:"Revise",rejectAndExit:"Reject and Exit",expandPlan:"Expand",collapsePlan:"Collapse"},GZ={back:"‹ Previous question",nextQuestion:"Next question ›",otherDefault:"Other…",submit:"Submit",dismiss:"Dismiss",minimize:"Minimize",expand:"Expand",hint:"↑↓ to choose · Enter to confirm"},QZ={tag:"tasks",summary:"{run} running · {done} done",copy:"Copy",calling:"Calling {label}",fieldTask:"Task",fieldOutput:"Output",fieldProgress:"Progress",fieldResult:"Result",moreLines:"… ({count} more)",copied:"Copied",stop:"stop",defaultDescription:"Background task",dockTasks:"Background tasks",dockBash:"Bash",dockSubagent:"Background Agent",dockTodos:"Todos",todoProgressTitle:"Progress",stateDone:"Done",stateFail:"Failed",stateCancelled:"Cancelled",filterRecent:"Recent",filterRunning:"Running",filterDone:"Done",filterAll:"All",running:"running",closePanel:"Close panel",openPanel:"Open in the side panel",timingRunning:"Running · {time}",timingDone:"Done · {time}",emptyTasks:"No background tasks running",emptyRecent:"No recent tasks",emptyRunning:"No running tasks",emptyDone:"No completed tasks",emptyBash:"No bash tasks running",emptySubagent:"No background agent tasks running",emptyTodo:"No todos yet",openTab:"Open the tasks tab",openDetail:"Open",collapse:"Collapse",expand:"Expand",transcriptLoadError:"Failed to load this sub agent’s conversation.",copyCommand:"Copy command",copyOutput:"Copy output",copyAll:"Copy all"},YZ={panelTitle:"Thinking",streaming:"Thinking…",close:"Close"},JZ={title:"Changes",branch:"branch",aheadTitle:"ahead of remote",behindTitle:"behind remote",fileCountOne:"{number} file",fileCountOther:"{number} files",empty:"No git changes",clean:"Working tree clean, no changes",back:"Back",loading:"Loading diff…",noDiff:"No line changes for this file",emptyFile:"Empty file",list:"List",tree:"Tree",close:"Close"},XZ={},eG={empty:"Select a file on the left to preview",loading:"Loading…",lineCount:"{count} lines",copy:"Copy",copied:"Copied",copyPath:"Copy path",openInEditor:"Open",reveal:"Reveal",download:"Download",close:"Close",search:"Search",prevMatch:"Previous match",nextMatch:"Next match",htmlMode:"HTML preview mode",markdownMode:"Markdown preview mode",preview:"Preview",source:"Source",imageFit:"Image sizing",fit:"Fit",actual:"Actual",pdfNoPreview:"This PDF cannot be embedded here. Download it to view.",imageNoPreview:"Image file · {mime} · {size} · preview unavailable",binaryNoPreview:"Binary file · {mime} · {size} bytes · preview unavailable",unknownType:"unknown type",copyCode:"Copy code",enlargeImage:"Enlarge image",errors:{emptyPath:"File path is empty",unsupportedPath:"URLs and remote paths cannot be previewed",outsideWorkspace:"Only files inside the current workspace can be previewed",isDirectory:"Select a file instead of a directory",notFound:"File no longer exists or was moved",tooLarge:"File is too large to preview",loadFailed:"Unable to read this file"}},tG={searching:"Searching…",noMatch:"No matches",files:"Files",skills:"Skills",openSkill:"Open skill file",copyPath:"Copy path"},nG={dismiss:"Close",errorLabel:"Error",noteLabel:"Note",agentWarningFallback:"agent warning",unhandledEvent:"Unhandled event: {type}",agentError:{title:"Model request failed",connection:"Cannot connect to the model service",auth:"Model authentication failed",rateLimit:"Model rate limit reached",overloaded:"Model overloaded",filtered:"Response filtered by the provider",api:"Model API error",contextOverflow:"Context size exceeded"},details:{cause:"Cause",code:"Error code",connection:"Connection",contentType:"Content type",details:"Server details",duration:"Duration",endpoint:"Endpoint",errorName:"Error type",message:"Message",operation:"Operation",phase:"Failure phase",request:"Request",requestId:"Request ID",responsePreview:"Response preview",sessionId:"Session ID",stack:"Stack",status:"HTTP status",timeout:"Timeout",timestamp:"Time"},daemonApiTitle:"Kimi server returned an error",daemonNetworkMessage:"Web did not receive a response from the Kimi server. Check that it is still running, or refresh the page.",daemonNetworkTitle:"Cannot connect to Kimi server",daemonTimeoutMessage:"The Kimi server did not respond within the wait limit. The operation may still complete in the background — refresh later to check, or try again.",daemonTimeoutTitle:"Kimi server response timed out",diagnostics:"Diagnostics",hideDetails:"Hide details",operationFailedMessage:"The last operation did not finish. Try again later.",operationFailedTitle:"Operation failed",sessionSnapshotMessage:"Web could not load the current conversation. Check that the Kimi server is still running, or refresh the page.",sessionSnapshotTitle:"Cannot load current conversation",showDetails:"Show details",copyDetails:"Copy diagnostics",copied:"Copied",wsTitle:"Realtime connection error",goal:{alreadyExists:"This session already has an active goal. Cancel it before starting a new one.",notFound:"No goal to act on — it may have already finished or been cancelled.",statusInvalid:"The current goal state does not allow this action.",notResumable:"This goal cannot be resumed (it may be cancelled or completed).",objectiveTooLong:"The objective is too long. Please shorten it and try again."}},iG={new:{desc:"Create a new session"},clear:{desc:"Clear and start a new session"},login:{desc:"Sign in to Kimi in the browser"},plan:{desc:"Toggle plan mode on/off"},swarm:{desc:"Toggle swarm mode; /swarm <task> runs a task in swarm"},goal:{desc:"Create/control a goal: /goal <objective>, /goal pause{'|'}resume{'|'}cancel"},btw:{desc:"Side chat: /btw <question> asks a forked side session"},compact:{desc:"Compact the conversation history"},fork:{desc:"Fork this session into a new one"},export:{desc:"Download this session and troubleshooting logs as a ZIP",noSession:"Open a session before exporting it.",started:"Exporting session…",done:"Session exported.",tooLarge:"Session data exceeds the export size limit. Export it from a terminal instead: kimi export {sessionId} -o session.zip"},status:{desc:"View session status"},undo:{desc:"Undo the last message"}},oG={label:{read:"Read",bash:"Run",edit:"Edit",write:"Write",grep:"Search",glob:"Find",ls:"List",web_fetch:"Fetch",search:"Search",todo:"Todo",task:"Task",swarm:"Swarm",ask_user:"Question",plan:"Plan",goal_create:"Start Goal",goal_get:"Read Goal",goal_budget:"Set Goal Budget",goal_update:"Update Goal",waitfor:"Wait"},waitfor:{waitingAny:"Waiting for any background task",waitingTask:"Waiting for {id}",noTasks:"No background tasks running",timedOut:"Timed out",stillRunning:"{count} still running",moreFinished:"+{count} finished during wait",moreRunning:"+{count} more"},swarm:{progress:"{done} / {total}",runningSub:"{count} in progress",doneSub:"{completed} completed · {failed} failed",doneSubWithCancelled:"{completed} completed · {failed} failed · {cancelled} cancelled",phaseQueued:"Queued",phaseWorking:"Working",phaseSuspended:"Suspended",phaseCompleted:"Completed",phaseFailed:"Failed",phaseCancelled:"Cancelled",waiting:"Waiting for subagents…"},chip:{lines:"{count} lines",results:"{count} results",files:"{count} files",edited:"edited",created:"created",todos:"{count} items"},disclosure:{expand:"Expand details",collapse:"Collapse details"},agent:{foreground:"Foreground",background:"Background"},output:{waiting:"Waiting for output…",empty:"No output",saved:"Saved result"},plan:{review:{pending:"Pending review",approved:"Approved",rejected:"Rejected",cancelled:"Cancelled"},selectedOption:"Selected",pathOnlyHint:"No inline content — open it in the side panel:",feedback:"Feedback"},summary:{inScope:"{value} in {scope}"},goal:{objectiveWithCriterion:"{objective} · {criterion}",status:"Status: {status}",budget:"{value} {unit}",turns:"{value} turns",tokens:"{value} tokens",milliseconds:"{value} ms",seconds:"{value} sec",minutes:"{value} min",hours:"{value} hr"},group:{countOther:"{count} tool call | {count} tool calls",typed:{read:{done:"Read {count} file | Read {count} files"},bash:{done:"Ran {count} command | Ran {count} commands"},grep:{done:"Searched {count} pattern | Searched {count} patterns"},search:{done:"Ran {count} web search | Ran {count} web searches"},glob:{done:"Matched {count} file pattern | Matched {count} file patterns"},ls:{done:"Listed {count} directory | Listed {count} directories"},web_fetch:{done:"Fetched {count} page | Fetched {count} pages"},edit:{done:"Made {count} edit | Made {count} edits"},write:{done:"Wrote {count} file | Wrote {count} files"}}},activity:{failedClause:" ({count} failed)",liveDonePrefix:"",busy:"Working…",doing:{read:"Reading {subject}",bash:"Running {subject}",grep:"Searching {subject}",search:"Searching {subject}",glob:"Matching {subject}",ls:"Listing {subject}",web_fetch:"Fetching {subject}",edit:"Editing {subject}",write:"Writing {subject}"}},ask:{dismissed:"Dismissed",answer:"{count} answer",answers:"{count} answers",answered:"Answered",more:"(+{count} more)",collected:"Collected your answers",question:"{count} question",questions:"{count} questions",freeInput:"(free text)",unanswered:"No answer"}},sG={resizeHandleAria:"Resize sidebar width",resizePreviewAria:"Resize preview panel width",detailPanelAria:"Detail panel"},rG={openSwitcher:"Switch session / workspace",openSettings:"Session settings",settingsTitle:"Settings",groupSession:"Current session",groupApp:"App preferences",groupAccount:"Account",sheetLabel:"Sheet",closeSheet:"Close",tapToCycle:"tap to cycle",running:"running",idle:"idle",sessionCount:"{n} sessions",newSession:"New session",permManualSub:"confirm every tool",permAutoSub:"fully autonomous, never asks",permYoloSub:"auto-approve tools, may still ask",planModeSub:"Plan mode",goalModeSub:"Goal mode",swarmModeSub:"Swarm mode",archivedSessions:"Archived sessions",archivedSessionsSub:"Browse and restore archived sessions",archivedBack:"Back",viewFlat:"Flat",viewGrouped:"By workspace"},lG={colorSchemeLabel:"Appearance",light:"Moon bright",dark:"Moon dark",system:"System"},aG={continue:"Continue",back:"Back",skip:"Skip",welcome:{title:"Welcome to Kimi Code",subtitle:"The AI coding workbench for professional developers",languageLabel:"Language",themeLabel:"Appearance"},login:{title:"Configure Model",subtitle:"Choose the model service that powers Kimi Code. You can change it later in Settings",kimiTitle:"Sign in with Kimi",kimiHint:"Ready out of the box with Kimi membership benefits",kimiCnTitle:"Kimi Code",kimiCnHint:"Sign in with your kimi.com account",kimiOverseasTitle:"Kimi Code",kimiOverseasHint:"Sign in with your kimi.ai account",customProviderTitle:"Add a custom provider",customProviderHint:"Bring your own API key for OpenAI-compatible and other services",loggedInTitle:"Logged in with Kimi",loggedInHint:"Your model service is ready to use",finish:"Finish",skip:"Skip for now"}},uG={title:"Settings",internalTest:"Internal Test",close:"Close (Esc)",tabs:{general:"General",agent:"Agent",account:"Account",providers:"Providers",advanced:"Advanced",archived:"Archived",shortcuts:"Hotkeys",plugins:"Plugins",lab:"Lab"},lab:{sidebarTabs:"Multi-tab sidebar",sidebarTabsHint:"The sidebar shows Open / Done / Workspaces tabs"},plugins:{retry:"Retry",builtIn:"Built-in",official:"Official",thirdParty:"Third-party",installed:"Installed",install:"Install",update:"Update",remove:"Remove",enabled:"Enabled",homepage:"Homepage",empty:"No plugins found",hasErrors:"Error",customInstall:"Install custom plugin",customInstallPlaceholder:"https://… or /path/to/plugin",customInstallHint:"Accepts an https zip URL, a GitHub repo URL, or a local directory path.",extensionHintTitle:"One step left: install the browser extension",extensionGuide:"Manual install",dismissHint:"Dismiss",catalogUnavailable:"The marketplace catalog is currently unreachable; installed plugins remain manageable below.",source:{"local-path":"Local","zip-url":"ZIP",github:"GitHub"},counts:{skill:"1 skill | {n} skills",mcp:"1 MCP server | {n} MCP servers",mcpEnabled:"{n} on",hook:"1 hook | {n} hooks",command:"1 command | {n} commands"}},appearance:"Appearance",notifications:"Notifications",notifyEnabled:"System notifications",notifyEnabledHint:"Send a system notification when a turn completes, needs an answer, or needs approval",notifySound:"Notification sound",notifySoundHint:"Play the system sound with notifications",notifyDenied:"Blocked in browser settings",notifyTitle:"Kimi Code · Turn finished",notifyQuestionTitle:"Kimi Code · Needs answer",notifyApprovalTitle:"Kimi Code · Approval required",notifyFallback:"View result",notifyQuestionFallback:"A question is waiting for your answer",notifyApprovalFallback:"A tool needs your approval",account:"Account",signedIn:"Signed in",signedOutHint:"Sign in to view your account and model access",planUsage:{title:"Plan Usage",retry:"Retry",loadFailed:"Failed to load",empty:"No usage data yet",weekLimit:"Weekly limit",genericLimit:"Limit",hourLimit:"{n}h limit",dayLimit:"{n}d limit",minuteLimit:"{n}m limit",resetsIn:"resets in {duration}",resetDone:"reset",durationDay:"{n}d",durationHour:"{n}h",durationMinute:"{n}m",durationSecond:"{n}s",usedPct:"{pct}% used",boosterTitle:"Booster",boosterBalance:"Balance",monthlyUsed:"Used this month",monthlyLimit:"Monthly limit",unlimited:"Unlimited",freeTitle:"Free account",freeHint:"Upgrade to a membership to use Kimi models and see plan usage"},colorSchemeHint:"Choose the app’s light or dark appearance",appIcon:"Dock icon",appIconHint:"Choose the icon shown in the Dock",appIconDefault:"Default",appIconBlack:"Black",uiFontSize:"Font size",uiFontSizeHint:"Adjust interface and message text size",vibrancy:"Frosted sidebar",vibrancyHint:"Use the native macOS frosted-glass material behind the sidebar — turn it off if the translucency is hard to read",languageHint:"Choose the interface language",defaultOpenInApp:"Default open-in app",defaultOpenInAppHint:"App used when opening files and folders from the header menu",openWith:"Open with",agentDefaults:"Agent defaults",saving:"Saving",defaultModel:"Default model",defaultModelHint:"New sessions prefer this model",noDefaultModel:"No default model",defaultPermission:"Default permission",defaultPermissionHint:"Only affects newly-created sessions",defaultThinking:"Thinking by default",defaultThinkingHint:"Whether new sessions start with thinking enabled",defaultPlanMode:"Plan mode by default",defaultPlanModeHint:"Whether new sessions start in plan mode",secondaryModelSection:"Subagents",secondaryModel:"Subagent model",secondaryModelHint:"Model and thinking effort that subagents use by default",secondaryModelEffort:"Thinking effort",noSecondaryModel:"Not set (inherit primary)",secondaryModelEffortAuto:"Model default",telemetry:"Improve product with usage data",telemetryHint:"When on, we collect anonymous interaction data (such as clicks, interruptions, and feature usage) to improve the product experience. You can turn it off at any time.",telemetryRestartHint:"Takes effect after restarting the service.",credentialReady:"Credential configured",credentialMissing:"Missing credential",configUnavailable:"The server did not return config yet. These settings are unavailable.",versionAndUpdates:"Version & updates",appVersion:"App version",appVersionHint:"The running app’s version and build time",checkUpdate:"Check for updates",checkUpdateHint:"Manually check whether a new version is available",checkUpdateBtn:"Check now",updateChecking:"Checking…",updateCheckLatest:"You’re on the latest version",updateCheckAvailable:"Version {version} is available — download it from the update entry in the sidebar",updateCheckUnsupported:"This build does not support update checks",updateCheckFailed:"Check failed. Please try again later.",updateCheckAvailableAuto:"Version {version} found — downloading in the background",updateCheckDownloaded:"Version {version} is ready — restart from the update entry in the sidebar",autoDownloadUpdate:"Auto-download updates",autoDownloadUpdateHint:"Download new versions in the background and install them on the next restart",privacy:"Data & privacy",diagnostics:"Diagnostics",build:"Build",serverVersion:"Server version",serverAddress:"Server address",serverAddressHint:"The address of the connected server",serverVersionHint:"The version of the connected service",copyServerVersion:"Copy server version",copyServerAddress:"Copy server address",copied:"Copied",exportLog:"Troubleshooting log",exportLogHint:"Export the troubleshooting log collected by the app",logHint:"Enable with ?debug=1 to capture",exportLogBtn:"Export log",archivedTitle:"Archived sessions",archivedDesc:"Browse archived sessions, see their workspace path, name, and archive time, and restore them to the session list.",archivedSearch:"Search archived sessions",archivedAllWorkspaces:"All workspaces",archivedSortLabel:"Sort by",archivedSortArchived:"Archive time",archivedSortCreated:"Created time",archivedSortName:"Name",archivedRestore:"Restore",archivedEmpty:"No archived sessions yet",archivedNoMatch:"No matching archived sessions",archivedSessionsCount:"{count} sessions",archivedAt:"Archived {time}",archivedLoadMore:"Load more",archivedLoading:"Loading…",archivedLoadingAll:"Loading all archived sessions…"},cG={openInEditor:"Open in editor",openInEditorShort:"Open",openInApp:"Open in {app}",chooseOpenApp:"Choose application",copyAll:"Copy all as Markdown",copyFinalSummary:"Copy final summary",copied:"Copied",lastUsed:"Last used",copyPath:"Copy path",changed:"{n} changed",gitTooltip:"Open Files > Changed",detached:"detached",openPr:"Open pull request",prStatusOpen:"open",prStatusClosed:"closed",prStatusMerged:"merged",prStatusDraft:"draft",prStatusUnknown:"unknown",options:"Options",copySessionId:"Copy session ID",pinSession:"Pin",unpinSession:"Unpin",renameSession:"Rename",forkSession:"Fork session",archiveSession:"Archive",markSessionDone:"Mark as done",sessionDone:"Done",reopenSession:"Mark as open",exportSession:"Export session",devBadge:"Running in development mode"},dG={title:"Side chat",subtitle:"forked from this session",empty:"Ask a quick question on the side — it shares this session’s context.",placeholder:"Ask the side chat…",send:"Send"},fG={actions:{summonApp:{label:"Show App Window",desc:"Bring the app window to the foreground from anywhere"},newSession:{label:"New Session",desc:"Start a new session in the current workspace"},searchSessions:{label:"Search Chats",desc:"Open the session search dialog"},archiveSession:{label:"Complete Chat",desc:"Mark the current chat as done right away (find it under Done)"},toggleSideChat:{label:"Toggle Side Chat",desc:"Open or close the /btw side chat"},toggleSidebar:{label:"Toggle Sidebar",desc:"Collapse or expand the session sidebar"},openFolder:{label:"Open Folder",desc:"Add a workspace folder with the native picker"},openInDefaultApp:{label:"Open in App",desc:"Open the workspace in your default editor/terminal"},openSettings:{label:"Open Settings",desc:"Show or hide the settings dialog"},toggleTerminal:{label:"Toggle Terminal",desc:"Show or hide the bottom terminal panel"},sidebarTabOpen:{label:"Open Tab",desc:"Switch to the Open list in the sidebar"},sidebarTabDone:{label:"Done Tab",desc:"Switch to the Done list in the sidebar"},sidebarTabWorkspaces:{label:"Workspaces Tab",desc:"Switch to the workspace directory in the sidebar"},selectPrevSibling:{label:"Previous Item",desc:"Select the previous chat / workspace in the current tab"},selectNextSibling:{label:"Next Item",desc:"Select the next chat / workspace in the current tab"},send:{label:"Send Message",desc:"Send the composer input"},newline:{label:"Newline",desc:"Insert a newline in the composer"}},searchPlaceholder:"Search shortcuts",unassigned:"Unassigned",unassign:"Unassign shortcut",edit:"Edit shortcut",reset:"Reset to default",resetAll:"Reset all to defaults",recording:"Press the new shortcut…",invalid:"This key combination can’t be used as a shortcut",notGlobal:"This key combination can’t be registered as a system-wide shortcut",globalTaken:"This shortcut is already taken by the system or another app",reserved:"Reserved by the system menu",reservedSteer:"Reserved for steer (Ctrl/Cmd+S)",reservedFind:"Reserved for transcript find (Ctrl/Cmd+F)",conflict:"Already used by “{action}”",customBadge:"Custom"},hG={panelAria:"Terminal",toolbarAria:"Terminal tabs",resizeAria:"Resize terminal panel height",toggle:"Toggle terminal",open:"Open terminal",close:"Close terminal",newTab:"New terminal",closeTab:"Close terminal",restartTab:"Restart terminal",collapse:"Collapse terminal panel",empty:"No terminal yet — click to start one",processExited:"[process exited]",processExitedWithCode:"[process exited with code {code}]"},pG={common:$Z,app:RZ,sidebar:zZ,admin:OZ,workspace:PZ,conversation:jZ,status:HZ,composer:WZ,login:qZ,providers:UZ,model:KZ,sessions:VZ,approval:ZZ,question:GZ,tasks:QZ,thinking:YZ,diff:JZ,fileTree:XZ,filePreview:eG,mention:tG,warnings:nG,commands:iG,tools:oG,layout:sG,mobile:rG,theme:lG,onboarding:aG,settings:uG,header:cG,sideChat:dG,shortcuts:fG,terminal:hG},gG={preview:"预览",confirm:"确认",cancel:"取消",close:"关闭",dismiss:"关闭",loading:"加载中",copy:"复制"},mG={authBannerMessage:"未登录 · 需要登录 Kimi Code 才能开始对话",authBannerLogin:"登录",connecting:"连接中…",internalBuildBanner:"仅供内部测试",menuFile:"文件",menuEdit:"编辑",menuView:"视图",menuHelp:"帮助",applicationMenu:"应用菜单"},vG={workspaceMeta:"workspace · {branch}",sessionsHeader:"会话",workspaces:"工作区",viewSwitcher:"列表管理",viewGroup:"视图",viewFlat:"平铺列表",viewGrouped:"按工作区分组",sortGroup:"排序",sortManual:"手动排序",sortRecent:"按最近活动",sessionAdmin:"会话管理",collapseAll:"折叠全部工作区",expandAll:"展开全部工作区",newSession:"新建会话",newChat:"新建会话",newWorkspace:"新建工作空间",dropToAddWorkspace:"松开鼠标添加工作区",emptyState:"还没有会话 · 点击 新建会话 开始",options:"选项",rename:"重命名",genTitle:"生成标题",genTitleUnavailable:"无法生成标题:需要登录 Kimi Code 托管账号,且会话中已有消息",setEmoji:"设置 Emoji…",sessionEmojiTitle:"选择 Emoji",removeEmoji:"移除 Emoji",randomEmoji:"随机",searchEmoji:"搜索 Emoji",recentEmojis:"最近使用",noEmojiResults:"没有匹配的 Emoji",emojiGroupFaces:"笑脸与人物",emojiGroupNature:"动物与自然",emojiGroupFood:"美食饮品",emojiGroupActivity:"活动与出行",emojiGroupObjects:"物品与工作",emojiGroupSymbols:"符号与状态",copyPath:"复制路径",copySessionId:"复制 Session ID",copied:"已复制 ✓",copyFailed:"复制失败",archive:"归档",archiveToastUndo:"撤销",archiveToastMid:"或到",archiveToastSettings:"设置",archiveToastTail:"查看已归档的会话",tabOpen:"进行中",tabDone:"已完成",tabWorkspaces:"工作空间",tagOpen:"Open",tagDone:"Done",complete:"完成",markDone:"标记为完成",reopen:"恢复进行中",noDoneSessions:"还没有已完成的会话",noOpenSessions:"还没有进行中的会话",completeToastLead:"已完成",reopenToastLead:"已恢复进行中",fork:"分叉会话",export:"导出会话",pin:"置顶",unpin:"取消置顶",lastActive:"最后更新:{time}",pinned:"置顶",collapsePinned:"折叠置顶区",expandPinned:"展开置顶区",resizePinnedAria:"调整置顶区高度",delete:"删除",removeWorkspace:"移除工作区",brand:"Kimi Code",signedIn:"已登录",signOut:"退出登录",notSignedIn:"未登录",signIn:"登录",defaultUserName:"Kimi 用户",upgrade:"升级",upgradeMembership:"会员升级",logoutConfirmTitle:"退出登录",logoutConfirmMessage:"确定要退出当前账号吗?",language:"语言",backendTitle:"后端 {backend} · {endpoint} — 点击切换",noSessions:"暂无对话",allPinned:"有 {count} 条对话被置顶",showMore:"展开更多",loadMore:"加载更多",showLess:"收起",loadingMore:"加载中…",collapseSidebar:"收起侧边栏",expandSidebar:"展开侧边栏",searchPlaceholder:"搜索会话或工作区",search:"搜索",searchHint:"↑↓ 选择 · ↵ 打开 · Esc 关闭",searchHintSelect:"选择",searchHintOpen:"打开",searchHintClose:"关闭",searchClear:"清除搜索",searchNoResults:"没有匹配的会话或工作区",searchEmpty:"暂无会话",update:"更新",updateAvailable:"发现新版本 v{version}",updateDownloadingButton:"下载中({percent}%)",updateReady:"v{version} 已就绪",updateDone:"重启并更新",updateFailed:"下载失败",updateRetry:"重试",updateDownloadNow:"下载并更新",updateSkip:"本次跳过",updateRestartNow:"立即重启",updateRestartLater:"下次启动",updateReleaseDate:"发布于 {date}",updateCurrentVersion:"当前版本 v{version}",updateWhatsNew:"更新内容",updateBackground:"后台下载",updateAutoDownload:"以后自动下载并安装更新",rcSelectDevice:"选择设备",rcCurrentDevice:"当前设备:{name}",rcConnectable:"可连接",rcUnavailable:"不可用",rcOnline:"在线",rcOffline:"离线",rcDevicesLoadFailed:"设备列表加载失败"},yG={title:"会话管理",subtitle:"管理所有会话,把任务完成的会话标记完成。旧会话按更新时间筛选,即可批量清理。",back:"返回",filterWorkspace:"工作空间",filterStatus:"状态",filterTime:"更新时间",allWorkspaces:"全部工作空间",selectAll:"全选",searchWorkspace:"搜索工作空间",noWorkspaceMatch:"没有匹配的工作空间",removeTag:"移除 {name}",statusAll:"全部状态",statusOpen:"进行中",statusDone:"已完成",timeAll:"全部时间",timeDaysAgo:"{n} 天以前",query:"查询",reset:"重置",colStatus:"状态",colTitle:"会话名",colWorkspace:"工作空间",colPrompt:"最后一条 prompt",colUpdated:"最后更新",colCompleted:"完成时间",colActions:"操作",empty:"没有符合当前筛选条件的会话",loading:"加载中…",total:"共 {n} 条",pageSize:"{n} 条/页",prevPage:"上一页",nextPage:"下一页",selectPageAll:"全选本页",batchSelected:"已选 {n} 项",selectAllMatching:"选中当前条件下的全部 {total} 项",materializingAll:"正在选中…",allMatchingSelected:"已选中全部 {n} 项",clearSelection:"清除选择",markDone:"标记完成",reopen:"恢复进行中",markDoneCount:"标记完成({n})",reopenCount:"恢复进行中({n})",batchDoneToast:"已标记完成 {n} 个会话",batchReopenedToast:"已将 {n} 个会话恢复为进行中",batchFailedSuffix:",{n} 个失败",batchDoneFailedNotice:"{n} 个会话未能标记完成",batchReopenFailedNotice:"{n} 个会话未能恢复为进行中",undo:"撤销",open:"打开会话",rename:"重命名…",fork:"Fork",export:"导出",moreActions:"更多操作"},kG={switcherTitle:"切换工作区",switchTooltip:"切换工作区",eyebrow:"工作区",branchLabel:"分支: {branch}",noBranch:"无分支",sessionCount:"{count} 个会话",allWorkspaces:"全部工作区",currentWorkspace:"仅当前工作区",addWorkspace:"添加工作区…",noWorkspace:"暂无工作区",deleteHasSessions:"工作区内还有会话,请先归档这些会话再删除",removeWorkspaceConfirm:"移除工作区「{name}」?",swarmEnableTitle:"启用 swarm 模式?",swarmEnableConfirm:"Agent 将并行运行多个子 agent。",goalStartTitle:"启动 goal?",goalStartConfirm:"「{objective}」——Agent 将自主执行。",scopeCurrent:"当前工作区",scopeAll:"全部工作区",newInGroup:"在此工作区新建会话",addTitle:"添加工作区",pathLabel:"路径",pathPlaceholder:"/项目的绝对路径",recentLabel:"最近的文件夹",add:"添加",cancel:"取消",addHint:"粘贴一个绝对路径,或从最近用过的文件夹中选择。",addFailed:"无法打开此文件夹,请检查路径后重试。",requiredTitle:"请先选择工作空间",requiredMessage:"发送消息前,需要先选择一个文件夹作为工作区。",openThisFolder:"打开此文件夹",up:"上一级",browsing:"加载中…",filterPlaceholder:"过滤子文件夹…",searchPlaceholder:"在此目录下模糊搜索…",searching:"搜索中…",pasteToggle:"直接输入绝对路径",noFilterMatch:"没有匹配「{q}」的子文件夹",noSubfolders:"此处没有子文件夹",browseHint:'点击文件夹进入,再点"打开此文件夹"将其添加为工作区。',attentionTitle:"{count} 项待处理",awaitingAnswer:"待回答",awaitingAnswerTitle:"有提问等待你回答",awaitingPermission:"待授权",awaitingPermissionTitle:"有操作等待你授权",aborted:"失败",abortedTitle:"此会话的上一轮对话因错误中断"},bG={jumpToLatestAria:"跳到最新消息",toc:"对话目录",newMessages:"最新消息",loading:"加载中…",starting:"正在创建对话…",requesting:"请求中…",working:"工作中…",workingRetry:"模型请求失败,正在重试(第 {n}/{max} 次)…",emptyWorkspaceHint:"在 {name} 中发送",switchWorkspace:"切换工作区",recentSessions:"最近会话",viewMoreSessions:"查看更多",sessionAdminTooltip:"在会话管理页面查看并管理更多会话",addWorkspace:"添加工作区",moreWorkspaces:"更多工作区 ({count})",pickFolder:"选择文件夹…",compacting:"正在压缩上下文…",compactedPlain:"上下文已压缩",compactedAuto:"已自动压缩上下文",compactedTokens:"({before} → {after} tokens)",viewSummary:"查看摘要",summaryTitle:"压缩摘要",undo:"撤销",undoTooltip:"撤回编辑",undoConfirm:"撤销上一条消息?",escUndoHintPre:"再按",escUndoHintPost:"撤销本条",undone:"已撤销,原文已放回输入框",turnInterrupted:"已手动终止",turnFailed:"模型请求失败,本轮对话已中断",turnFailedMaxSteps:"达到本轮步数上限,对话已中断",turnFailedResume:"继续",turnFailedResumeText:"继续",yesterday:"昨天",loadOlder:"加载更早的消息",loadingOlder:"正在加载更早的消息…",widenTable:"加宽表格",restoreTableWidth:"恢复默认宽度",cron:{fired:"定时任务已触发",missed:"错过的定时提醒",job:"任务 {id}",oneShot:"单次",coalesced:"已合并 {n} 次触发",missedCount:"错过 {n} 次",finalDelivery:"最后一次投递",expand:"展开",collapse:"收起"},fold:{worked:"已工作 {duration}",workedUnknown:"工作过程"},turnFiles:{titleOne:"{number} 个文件已修改",titleOther:"{number} 个文件已修改",more:"还有 {number} 个文件",moreOne:"还有 1 个文件",showLess:"收起",diffTitle:"本次改动",diffUnavailable:"此文件的改动无法逐项展示",openFile:"打开文件"},goal:{continuation:"目标续跑"},notification:{kindTask:"后台任务",kindSubagent:"子代理",title:{completed:"{kind}完成",failed:"{kind}失败",timed_out:"{kind}超时",killed:"{kind}被终止",lost:"{kind}丢失",info:"{kind}通知"},status:{completed:"完成",failed:"失败",timed_out:"超时",killed:"已终止",lost:"丢失",info:"信息"},groupTitle:"{n} 条通知",copyPath:"复制路径",copied:"已复制",rawPayload:"原始 payload",outputTruncated:"输出已截断,仅显示末尾",fields:{type:"类型",source:"来源",severity:"严重度"}},userMessage:{expand:"展开",collapse:"收起"},search:{placeholder:"搜索对话…",searching:"搜索中…",results:"{current}/{total} 条结果",resultsCapped:"{current}/{total}+ 条结果",noResults:"无结果",previous:"上一个匹配",next:"下一个匹配",close:"关闭搜索"}},AG={connectionConnected:"已连接",connectionConnecting:"连接中…",connectionDisconnected:"未连接",ctxTooltip:"使用 {used} / {max} tokens ({pct}%)",modelLabel:"模型",permissionManual:"逐条确认",permissionAuto:"完全自主",permissionYolo:"自动通过",permissionManualDesc:"每个工具操作都需要你手动确认",permissionAutoDesc:"完全自主运行,智能体自己做决定,不再询问",permissionYoloDesc:"自动批准工具操作,但遇到关键问题仍会询问",planLabel:"计划",planOn:"开",planOff:"关",planTooltip:"切换计划模式(先调研再修改)",workModeDismiss:"退出模式",goalLabel:"目标",timeUnitHour:"小时",timeUnitMinute:"分",timeUnitSecond:"秒",planEmptyArmed:"计划模式已开启,智能体写出计划后会显示在这里",planEmptyIdle:"还没有计划——开启计划模式后,智能体写出的计划会显示在这里",swarmLabel:"Swarm",swarmDismiss:"关闭 Swarm",modeOff:"未启用",goalPlaceholder:"让智能体完成什么目标?",planPlaceholder:"让智能体先规划什么?",goalStart:"开始",goalPause:"暂停",goalResume:"继续",goalCancel:"取消",goalCancelConfirm:"是否需要取消当前目标?取消后将无法恢复。",goalCancelConfirmYes:"是",goalCancelConfirmNo:"否",goalDoneWhen:"完成条件",goalStatusActive:"进行中",goalStatusPaused:"已暂停",goalStatusBlocked:"已阻塞",goalStatusComplete:"已完成",modeNotSupported:"暂不支持",thinkingLabel:"思考",thinkingTooltip:"切换思考模式",thinkingOn:"开",thinkingOff:"关",cacheNote:"提示:切换模型或思考程度会使已有的提示词缓存失效。建议新建会话,避免额外的 token 消耗。",starredModels:"收藏",moreModels:"更多模型…",statusPanelTitle:"会话状态",statusPanelClose:"关闭",statusModel:"模型",statusThinking:"思考强度",statusPermission:"权限",statusPlanMode:"计划模式",statusSwarmMode:"Swarm 模式",swarmOn:"开",swarmOff:"关",statusContext:"上下文",statusCost:"花费",statusContextValue:"{used} / {max} ({pct}%)",statusNone:"—",activityRunning:"运行中…",activityAwaitingApproval:"等待批准",activityAwaitingQuestion:"等待回答",interrupt:"中断",runningShort:"进行中"},CG={placeholder:"输入消息…",send:"发送 ↵",queueLabel:"队列",placeholderRunning:"输入会加入队列 · Ctrl+S 立即插入运行中的回合",placeholderRunningMobile:"输入会加入队列",starting:"正在发送…",queuePending:"{n} 个任务等待发送",queueSteer:"立即发送到当前回合",queueDragTitle:"拖拽排序",editQueued:"编辑(载入到输入框)",queuedAttachments:"附件 ×{n}",queuedHasImage:"包含 {n} 张图片 — 只能移除,不能编辑",attachmentImage:"图片",attachmentVideo:"视频",attachmentFile:"文件",attachmentOpenUnsupported:"无法打开 {name}:暂不支持此文件类型",dropToAttach:"松开鼠标添加附件",remove:"移除",removeNamed:"移除 {name}",clearAll:"清空全部附件",attachmentCount:"共 {n} 个附件",uploading:"上传中",uploadFailed:"上传失败",attachFile:"添加附件",addMenu:"添加",addFiles:"文件",addFilesDesc:"上传文件",addGoalDesc:"设定目标并持续推进",addPlanDesc:"启用计划模式",addSwarmDesc:"启用 swarm 模式",noCommands:"无匹配命令",slashSheetTitle:"命令",slashSearchPlaceholder:"搜索命令…",mentionSheetTitle:"文件",mentionSearchPlaceholder:"搜索文件…",addSlash:"命令",addSlashDesc:"内置命令或技能",addMention:"提及",addMentionDesc:"提及项目中的文件",previewAttachment:"预览 {name}",interrupt:"中断",interruptTitle:"中断当前操作",expandTitle:"展开输入框进行多行编辑",collapseTitle:"收起输入框",emptyConversationTitle:"Kimi Code",emptyConversation:"还没有消息 —— 在下方输入开始对话",upgradeBanner:"升级你的 Kimi 账户来使用 Kimi Code",quickStartPlaceholder:"输入消息开始新对话…",thinkingSuffix:" · 思考",thinkingSuffixEffort:" · {level}"},wG={title:"登录 Kimi Code",close:"关闭 (Esc)",regionCnTitle:"Kimi Code",regionCnHint:"使用 kimi.com 账号登录",regionOverseasTitle:"Kimi Code",regionOverseasHint:"使用 kimi.ai 账号登录",oauthTitle:"登录 Kimi 账号",oauthHint:"在浏览器中完成授权即可登录",starting:"正在启动登录流程…",openedHint:"请在浏览器中完成授权({time})",blockedTitle:"未能自动打开登录页",blockedHint:"浏览器拦截了自动打开,请点击下方按钮继续完成授权。",notOpened:"没有自动打开浏览器?",authorizeInBrowser:"在浏览器中登录",orDivider:"或者",fallbackPrefix:"换个设备?在浏览器打开 ",fallbackSuffix:" 输入设备码:",copy:"复制",copied:"已复制",copyLink:"复制链接",success:"已登录",successHint:"正在加载,稍后自动关闭…",expiredTitle:"设备码已过期",expiredHint:"请重新开始登录流程",retry:"重试",closeBtn:"关闭",errorTitle:"当前版本暂不支持登录",errorHint:"请升级 kimi-code 后重试",pollErrorTitle:"连接已断开",pollErrorHint:"登录轮询连续失败,请检查 kimi-code 进程后重试",action:"登录",requiredTitle:"请先登录",requiredMessage:"登录 Kimi 账号并配置模型后,才能开始对话。",goToLogin:"去登录",upgradeRequiredTitle:"请升级会员",upgradeRequiredMessage:"当前为免费账户,升级会员后即可使用 Kimi 模型开始对话。",rcSubtitle:"远程控制会话",rcChecking:"正在检查登录状态…",rcLead:"远程控制功能需要登录后使用。使用 Kimi 账号登录即可继续。",rcSuccessHint:"正在跳转…",rcExpiredTitle:"授权已过期或被取消",rcStartErrorTitle:"无法开始登录",rcSessionErrorTitle:"无法创建登录会话",rcConnectionErrorHint:"请检查网络连接后重试。",rcSuccessNoRedirect:"现在可以关闭本页了。"},xG={title:"供应商管理",loading:"加载提供商中…",unavailable:"暂不支持提供商管理",empty:"暂无提供商",status:{connected:"已连接",error:"错误",unconfigured:"未配置"},keySet:"key 已设置",keyNotSet:"未设置 key",managedBadge:"OAuth",modelCount:"{count} 个模型",confirmDelete:"确认删除?",refresh:"刷新",delete:"删除",refreshTitle:"刷新 {type}",deleteTitle:"删除 {type}",loginKimi:"登录 Kimi",loginAnthropic:"登录 Anthropic",addProvider:"添加供应商",added:"已添加",enterApiKey:"填写 API Key",optional:"可选",apiKeyRequired:"API Key 不能为空",fieldId:"名称",fieldType:"API 协议",types:{kimi:"Kimi",openai:"OpenAI",openai_responses:"OpenAI Responses",anthropic:"Anthropic","google-genai":"Google GenAI",vertexai:"Vertex AI"},fieldApiKey:"API Key",apiKeyManaged:"OAuth 托管登录",apiKeySet:"已设置,输入以更换",showApiKey:"显示 API Key",hideApiKey:"隐藏 API Key",fieldBaseUrl:"Base URL",baseUrlPlaceholder:"https://api.example.com/v1",fieldModels:"模型",colModelId:"模型 ID",colContext:"上下文",colDisplayName:"显示名",modelIdPlaceholder:"kimi-k3",modelContextPlaceholder:"1048576",modelNamePlaceholder:"可选",noModels:"暂无模型",addModel:"添加模型",removeModel:"移除模型",fieldDefaultModel:"默认模型",save:"保存",saved:"已保存",deleteProvider:"删除供应商",deleteConfirm:"确认删除 {id} 及其 {count} 个模型?",deleteConfirmYes:"确认删除",managedHint:"托管供应商在账户页登录 / 登出",unsavedGuard:"有未保存的修改。",guardStay:"继续编辑",guardDiscard:"丢弃",add:"添加",catalog:{sourceCatalog:"从目录添加",sourceManual:"手动添加",sourceRegistry:"注册表",registryHint:"从 api.json 注册表导入供应商与模型;同一 URL 重复导入即为刷新",registryUrlLabel:"注册表 URL",registryImported:"已导入 {count} 个供应商",searchPlaceholder:"搜索供应商",loading:"加载目录中…",loadError:"目录加载失败,请检查网络后重试",retry:"重试",empty:"没有匹配的供应商",rejected:"不可导入",rejectReason:{"unknown-explicit-type":"协议不受支持","proprietary-sdk":"私有协议,无法导入","empty-base-url":"Base URL 为空","placeholder-base-url":"端点包含环境变量占位符"},backToList:"返回目录列表",willImport:"将从目录导入 {count} 个模型",overwriteWarning:"已存在同名供应商,导入将覆盖其配置与模型",importAction:"导入"},error:{idRequired:"名称不能为空",idInvalid:'名称需以字母或数字开头,只能包含字母、数字、"-"、"_" 和空格',apiKeyRequired:"API Key 不能为空",baseUrlRequired:"Base URL 不能为空",registryUrlRequired:"注册表 URL 不能为空",modelRequired:"模型 ID 不能为空",contextSizeRequired:"上下文长度不能为空",contextSizeInvalid:"上下文长度需为正整数"},hintClose:"关闭"},SG={dialogLabel:"切换模型",title:"切换模型",close:"关闭 (Esc)",allTab:"全部",providerTabs:"模型提供商",searchPlaceholder:"搜索模型或提供商…",clearSearch:"清除搜索",loading:"加载模型中…",unavailable:"暂无可用模型列表",contextSuffix:"{size} ctx",capabilityImageInput:"图片输入",capabilityVideoInput:"视频输入",capabilityToolUse:"工具调用",capabilityThinking:"思考",capabilityAlwaysThinking:"始终思考",emptyNoModels:"暂无可用模型",emptyNoMatch:"无匹配模型",starTitle:"添加到收藏",unstarTitle:"取消收藏",hintNavigate:"导航",hintSelect:"选择",hintClose:"关闭"},_G={justNow:"刚刚"},MG={title:{shell:"运行命令?",diff:"应用修改?",file:"写入文件?",fileop:"文件操作?",url:"抓取 URL?",search:"搜索?",invocation:"调用?",todo:"更新 todo?",plan_review:"按这份 plan 开始实现?",generic:"批准操作?"},subagentBadge:"子 agent · {name}",danger:"危险: {detail}",searchQueryLabel:"查询",searchScope:"范围:{scope}",feedbackPlaceholder:"说明拒绝原因… (Enter 提交, Shift+Enter 换行, Esc 取消)",feedbackHint:"Enter 提交 · Shift+Enter 换行 · Esc 取消",approve:"批准",approveSession:"本会话内批准",reject:"拒绝",feedback:"反馈",feedbackSubmit:"提交并拒绝",feedbackCancel:"取消",approvePlan:"批准 plan",revise:"修改",rejectAndExit:"拒绝并退出",expandPlan:"放大",collapsePlan:"还原"},IG={back:"‹ 上一题",nextQuestion:"下一题 ›",otherDefault:"其他…",submit:"提交",dismiss:"放弃",minimize:"最小化",expand:"展开",hint:"↑↓ 选择 · Enter 确认"},EG={tag:"任务",summary:"{run} 运行中 · {done} 完成",copy:"复制",calling:"调用 {label}",fieldTask:"任务",fieldOutput:"输出",fieldProgress:"进度",fieldResult:"结果",moreLines:"…(还有 {count} 行)",copied:"已复制",stop:"stop",defaultDescription:"后台任务",dockTasks:"后台任务",dockBash:"后台 Bash",dockSubagent:"后台 Agent",dockTodos:"待办",todoProgressTitle:"当前进度",stateDone:"完成",stateFail:"失败",stateCancelled:"已取消",filterRecent:"最近",filterRunning:"进行中",filterDone:"已完成",filterAll:"全部",running:"运行中",closePanel:"关闭面板",openPanel:"在侧边栏打开",timingRunning:"运行中 · {time}",timingDone:"完成 · {time}",emptyTasks:"暂无后台任务",emptyRecent:"暂无最近任务",emptyRunning:"暂无运行中的任务",emptyDone:"暂无已完成的任务",emptyBash:"暂无后台 Bash 任务",emptySubagent:"暂无后台 Agent 任务",emptyTodo:"暂无待办事项",openTab:"查看全部后台任务",openDetail:"查看",collapse:"折叠",expand:"展开",transcriptLoadError:"无法加载这个子 Agent 的对话。",copyCommand:"复制命令",copyOutput:"复制输出",copyAll:"复制全部"},TG={panelTitle:"思考过程",streaming:"思考中…",close:"关闭"},LG={title:"改动",branch:"分支",aheadTitle:"领先远程",behindTitle:"落后远程",fileCountOne:"{number} 个文件",fileCountOther:"{number} 个文件",empty:"无 git 改动",clean:"工作区干净,无改动",back:"返回",loading:"正在加载 diff…",noDiff:"该文件没有行级改动",emptyFile:"空文件",list:"列表",tree:"树形",close:"关闭"},NG={},FG={empty:"选择左侧文件预览",loading:"加载中…",lineCount:"{count} 行",copy:"复制",copied:"已复制",copyPath:"复制路径",openInEditor:"打开",reveal:"显示",download:"下载",close:"关闭",search:"搜索",prevMatch:"上一个匹配",nextMatch:"下一个匹配",htmlMode:"HTML 预览模式",markdownMode:"Markdown 预览模式",preview:"预览",source:"源码",imageFit:"图片缩放",fit:"适应",actual:"原始",pdfNoPreview:"无法内嵌预览此 PDF,可以下载后查看",imageNoPreview:"图片文件 · {mime} · {size} · 暂不预览",binaryNoPreview:"二进制文件 · {mime} · {size} 字节 · 暂不预览",unknownType:"未知类型",copyCode:"复制代码",enlargeImage:"放大图片",errors:{emptyPath:"文件路径为空",unsupportedPath:"不支持预览 URL 或远程路径",outsideWorkspace:"只能预览当前 workspace 内的文件",isDirectory:"请选择具体文件,而不是目录",notFound:"文件不存在或已被移动",tooLarge:"文件过大,暂不支持预览",loadFailed:"无法读取这个文件"}},DG={searching:"搜索中…",noMatch:"无匹配",files:"文件",skills:"技能",openSkill:"打开技能文件",copyPath:"复制路径"},BG={dismiss:"关闭",errorLabel:"错误",noteLabel:"提示",agentWarningFallback:"agent 警告",unhandledEvent:"未处理的事件:{type}",agentError:{title:"模型请求失败",connection:"无法连接模型服务",auth:"模型认证失败",rateLimit:"模型请求被限流",overloaded:"模型服务过载",filtered:"响应被提供方过滤",api:"模型接口返回错误",contextOverflow:"上下文超出模型限制"},details:{cause:"底层原因",code:"错误码",connection:"连接状态",contentType:"响应类型",details:"服务端详情",duration:"耗时",endpoint:"请求地址",errorName:"错误类型",message:"错误信息",operation:"操作",phase:"失败阶段",request:"请求",requestId:"Request ID",responsePreview:"响应预览",sessionId:"Session ID",stack:"堆栈",status:"HTTP 状态",timeout:"超时设置",timestamp:"时间"},daemonApiTitle:"Kimi 服务器返回错误",daemonNetworkMessage:"Web 没有拿到 Kimi 服务器的响应。请确认它仍在运行,或刷新页面重试。",daemonNetworkTitle:"无法连接到 Kimi 服务器",daemonTimeoutMessage:"Kimi 服务器在等待时限内没有响应。操作可能仍在后台执行,请稍后刷新确认结果,或重试。",daemonTimeoutTitle:"Kimi 服务器响应超时",diagnostics:"诊断信息",hideDetails:"收起详情",operationFailedMessage:"刚才的操作没有完成,请稍后重试。",operationFailedTitle:"操作失败",sessionSnapshotMessage:"Web 没能加载当前会话内容。请确认 Kimi 服务器仍在运行,或刷新页面重试。",sessionSnapshotTitle:"无法加载当前会话内容",showDetails:"查看详情",copyDetails:"复制诊断信息",copied:"已复制",wsTitle:"实时连接出错",goal:{alreadyExists:"当前会话已有一个进行中的目标,请先取消它再创建新目标。",notFound:"没有找到可操作的目标,可能它已经结束或被取消。",statusInvalid:"当前目标状态不支持这个操作。",notResumable:"这个目标无法恢复(可能已取消或已完成)。",objectiveTooLong:"目标描述太长了,请精简后重试。"}},$G={new:{desc:"创建新会话"},clear:{desc:"清空并新建会话"},login:{desc:"在浏览器中登录 Kimi"},plan:{desc:"切换计划模式 开/关"},swarm:{desc:"切换 swarm 模式;/swarm <任务> 直接在 swarm 下执行"},goal:{desc:"创建/控制目标:/goal <目标>、/goal pause{'|'}resume{'|'}cancel"},btw:{desc:"侧边聊天:/btw <问题> 向 fork 的侧边会话提问"},compact:{desc:"压缩会话历史"},fork:{desc:"把当前会话 fork 出一个新会话"},export:{desc:"将当前会话和排障日志下载为 ZIP 压缩包",noSession:"请先打开一个会话再导出。",started:"正在导出会话…",done:"会话导出完成。",tooLarge:"会话数据超过导出大小限制,可在终端用 CLI 导出:kimi export {sessionId} -o session.zip"},status:{desc:"查看会话状态"},undo:{desc:"撤销上一条消息"}},RG={label:{read:"读取",bash:"运行",edit:"编辑",write:"写入",grep:"搜索",glob:"查找",ls:"列目录",web_fetch:"抓取",search:"搜索",todo:"待办",task:"任务",swarm:"Swarm",ask_user:"提问",plan:"计划",goal_create:"启动目标",goal_get:"读取目标",goal_budget:"设置目标预算",goal_update:"更新目标",waitfor:"等待"},waitfor:{waitingAny:"等待任一后台任务",waitingTask:"等待 {id}",noTasks:"没有后台任务在运行",timedOut:"等待超时",stillRunning:"{count} 个仍在运行",moreFinished:"另有 {count} 个在等待期间完成",moreRunning:"还有 {count} 个"},swarm:{progress:"{done} / {total}",runningSub:"{count} 个进行中",doneSub:"完成 {completed} · 失败 {failed}",doneSubWithCancelled:"完成 {completed} · 失败 {failed} · 已取消 {cancelled}",phaseQueued:"排队",phaseWorking:"运行中",phaseSuspended:"暂停",phaseCompleted:"完成",phaseFailed:"失败",phaseCancelled:"已取消",waiting:"等待子任务加入…"},chip:{lines:"{count} 行",results:"{count} 结果",files:"{count} 个文件",edited:"已编辑",created:"已创建",todos:"{count} 项"},disclosure:{expand:"展开详情",collapse:"收起详情"},agent:{foreground:"前台",background:"后台"},output:{waiting:"等待输出…",empty:"(无输出)",saved:"已保存的结果"},plan:{review:{pending:"待确认",approved:"已通过",rejected:"已拒绝",cancelled:"已取消"},selectedOption:"已选择",pathOnlyHint:"该计划未保存内联内容,可在侧边栏打开:",feedback:"反馈"},summary:{inScope:"{value} 在 {scope} 中"},goal:{objectiveWithCriterion:"{objective} · {criterion}",status:"状态:{status}",budget:"{value} {unit}",turns:"{value} 轮",tokens:"{value} token",milliseconds:"{value} 毫秒",seconds:"{value} 秒",minutes:"{value} 分钟",hours:"{value} 小时"},group:{countOther:"执行了 {count} 次工具调用",typed:{read:{done:"读取了 {count} 个文件"},bash:{done:"运行了 {count} 条命令"},grep:{done:"搜索了 {count} 个模式"},search:{done:"网络搜索了 {count} 次"},glob:{done:"找了 {count} 次文件"},ls:{done:"列出了 {count} 个目录"},web_fetch:{done:"抓取了 {count} 个页面"},edit:{done:"编辑了 {count} 处"},write:{done:"写入了 {count} 个文件"}}},activity:{failedClause:"({count} 失败)",liveDonePrefix:"已",busy:"正在执行…",doing:{read:"正在读取 {subject}",bash:"正在运行 {subject}",grep:"正在搜索 {subject}",search:"正在搜索 {subject}",glob:"正在匹配 {subject}",ls:"正在列出 {subject}",web_fetch:"正在抓取 {subject}",edit:"正在编辑 {subject}",write:"正在写入 {subject}"}},ask:{dismissed:"已忽略",answer:"{count} 个回答",answers:"{count} 个回答",answered:"已回答",more:"(还有 {count} 个)",collected:"已收集回答",question:"{count} 个问题",questions:"{count} 个问题",freeInput:"(自由输入)",unanswered:"未作答"}},zG={resizeHandleAria:"调整侧栏宽度",resizePreviewAria:"调整预览面板宽度",detailPanelAria:"详情面板"},OG={openSwitcher:"切换会话 / 工作区",openSettings:"会话设置",settingsTitle:"设置",groupSession:"当前会话",groupApp:"应用偏好",groupAccount:"账号",sheetLabel:"面板",closeSheet:"关闭",tapToCycle:"点击切换",running:"运行中",idle:"空闲",sessionCount:"{n} 个会话",newSession:"新建会话",permManualSub:"每个工具都确认",permAutoSub:"完全自主,不再提问",permYoloSub:"自动批准工具,仍可能提问",planModeSub:"计划模式",goalModeSub:"目标模式",swarmModeSub:"Swarm 模式",archivedSessions:"已归档会话",archivedSessionsSub:"查看并恢复已归档会话",archivedBack:"返回",viewFlat:"平铺",viewGrouped:"按工作区"},PG={colorSchemeLabel:"外观",light:"月之亮面",dark:"月之暗面",system:"跟随系统"},jG={continue:"继续",back:"上一步",skip:"跳过",welcome:{title:"欢迎使用 Kimi Code",subtitle:"为专业开发者打造的 AI 编程工作台",languageLabel:"语言",themeLabel:"外观"},login:{title:"选择配置模型",subtitle:"选择驱动 Kimi Code 的模型服务,之后可在「设置」中更改。",kimiTitle:"登录 Kimi 账号",kimiHint:"使用 Kimi 会员权益,开箱即用",kimiCnTitle:"Kimi Code",kimiCnHint:"使用 kimi.com 账号登录",kimiOverseasTitle:"Kimi Code",kimiOverseasHint:"使用 kimi.ai 账号登录",customProviderTitle:"添加自定义供应商",customProviderHint:"使用自己的 API Key,接入 OpenAI 兼容等模型服务",loggedInTitle:"已登录 Kimi 账号",loggedInHint:"模型服务已就绪,可以开始使用",finish:"完成",skip:"跳过,稍后再说"}},HG={title:"设置",internalTest:"内部测试",close:"关闭 (Esc)",tabs:{general:"通用",agent:"Agent",account:"账户",providers:"供应商",advanced:"高级",archived:"已归档",shortcuts:"快捷键",plugins:"插件",lab:"实验室"},lab:{sidebarTabs:"多标签页侧边栏",sidebarTabsHint:"侧边栏显示「进行中 / 已完成 / 工作空间」三个标签页"},plugins:{retry:"重试",builtIn:"内置",official:"官方",thirdParty:"第三方",installed:"已安装",install:"安装",update:"更新",remove:"移除",enabled:"启用",homepage:"主页",empty:"没有找到插件",hasErrors:"错误",customInstall:"安装自定义插件",customInstallPlaceholder:"https://… 或 /本地/目录",customInstallHint:"支持 https zip 链接、GitHub 仓库地址或本地目录路径。",extensionHintTitle:"还差一步:安装浏览器扩展",extensionGuide:"手动安装",dismissHint:"知道了",catalogUnavailable:"插件市场目录暂时不可达;已安装的插件仍可正常管理。",source:{"local-path":"本地","zip-url":"ZIP",github:"GitHub"},counts:{skill:"{n} 个技能",mcp:"{n} 个 MCP 服务",mcpEnabled:"启用 {n} 个",hook:"{n} 个钩子",command:"{n} 个命令"}},appearance:"外观",notifications:"通知",notifyEnabled:"系统通知",notifyEnabledHint:"回合完成、待回答或待审批时发送系统通知",notifySound:"通知提示音",notifySoundHint:"系统通知随附提示音",notifyDenied:"已在浏览器设置中被阻止",notifyTitle:"Kimi Code · 回合完成",notifyQuestionTitle:"Kimi Code · 待回答",notifyApprovalTitle:"Kimi Code · 等待审批",notifyFallback:"点击查看结果",notifyQuestionFallback:"有提问等待你回答",notifyApprovalFallback:"有工具等待你审批",account:"账户",signedIn:"已登录",signedOutHint:"登录后可查看账户和模型权益",planUsage:{title:"套餐用量",retry:"重试",loadFailed:"加载失败",empty:"暂无用量数据",weekLimit:"每周限额",genericLimit:"限额",hourLimit:"{n} 小时限额",dayLimit:"{n} 天限额",minuteLimit:"{n} 分钟限额",resetsIn:"{duration}后重置",resetDone:"已重置",durationDay:"{n} 天",durationHour:"{n} 小时",durationMinute:"{n} 分钟",durationSecond:"{n} 秒",usedPct:"已使用 {pct}%",boosterTitle:"加油包",boosterBalance:"余额",monthlyUsed:"本月已用",monthlyLimit:"每月上限",unlimited:"不限",freeTitle:"免费账户",freeHint:"升级会员后即可使用 Kimi 模型并查看套餐用量"},colorSchemeHint:"选择应用的明暗外观",appIcon:"程序坞图标",appIconHint:"选择程序坞中显示的图标",appIconDefault:"默认",appIconBlack:"黑色",uiFontSize:"字体大小",uiFontSizeHint:"调整界面和消息文字大小",vibrancy:"毛玻璃侧栏",vibrancyHint:"在侧栏使用 macOS 原生毛玻璃材质——如果半透明影响阅读可以关闭",languageHint:"选择界面显示语言",defaultOpenInApp:"默认打开应用",defaultOpenInAppHint:"从顶栏菜单打开文件和文件夹时默认使用的应用",openWith:"打开方式",agentDefaults:"Agent 默认值",saving:"保存中",defaultModel:"默认模型",defaultModelHint:"新会话会优先使用这个模型",noDefaultModel:"未设置默认模型",defaultPermission:"默认权限",defaultPermissionHint:"只影响之后新建的会话",defaultThinking:"默认开启思考",defaultThinkingHint:"新会话默认是否开启思考",defaultPlanMode:"默认计划模式",defaultPlanModeHint:"新会话默认进入计划模式",secondaryModelSection:"子智能体",secondaryModel:"子智能体模型",secondaryModelHint:"子智能体默认使用的模型与思考强度",secondaryModelEffort:"思考强度",noSecondaryModel:"未设置(跟随主模型)",secondaryModelEffortAuto:"模型默认",telemetry:"使用数据改进产品",telemetryHint:"开启后,我们会收集您的匿名交互数据(如点击、打断、功能使用等),用于改进产品体验。您可以随时关闭。",telemetryRestartHint:"更改后需重启服务生效。",credentialReady:"凭据已配置",credentialMissing:"缺少凭据",configUnavailable:"当前服务端没有返回 config,设置项暂不可用。",versionAndUpdates:"版本与更新",appVersion:"应用版本",appVersionHint:"当前应用的版本号和构建时间",checkUpdate:"检查更新",checkUpdateHint:"手动检查是否有新版本",checkUpdateBtn:"立即检查",updateChecking:"检查中…",updateCheckLatest:"已是最新版本",updateCheckAvailable:"发现新版本 {version},可从侧边栏的更新入口下载",updateCheckUnsupported:"当前构建不支持检查更新",updateCheckFailed:"检查失败,请稍后重试",updateCheckAvailableAuto:"发现新版本 {version},正在后台下载",updateCheckDownloaded:"新版本 {version} 已就绪,可从侧边栏的更新入口重启安装",autoDownloadUpdate:"自动下载更新",autoDownloadUpdateHint:"发现新版本时在后台自动下载,重启后完成安装",privacy:"数据与隐私",diagnostics:"诊断",build:"构建",serverVersion:"服务端版本",serverAddress:"服务器地址",serverAddressHint:"当前连接的服务器地址",serverVersionHint:"当前连接服务的版本",copyServerVersion:"复制服务端版本",copyServerAddress:"复制服务器地址",copied:"已复制",exportLog:"故障排查日志",exportLogHint:"导出已采集的故障排查日志",logHint:"加 ?debug=1 开启采集",exportLogBtn:"导出日志",archivedTitle:"已归档会话",archivedDesc:"查看已归档会话,确认其所属工作区路径、会话名称和归档时间,并可恢复到会话列表。",archivedSearch:"搜索已归档会话",archivedAllWorkspaces:"所有工作区",archivedSortLabel:"排序方式",archivedSortArchived:"归档时间",archivedSortCreated:"创建时间",archivedSortName:"按字母顺序",archivedRestore:"恢复",archivedEmpty:"还没有归档的会话",archivedNoMatch:"没有匹配的已归档会话",archivedSessionsCount:"{count} 个会话",archivedAt:"归档于 {time}",archivedLoadMore:"加载更多",archivedLoading:"加载中…",archivedLoadingAll:"正在加载全部归档会话…"},WG={openInEditor:"在编辑器中打开",openInEditorShort:"打开",openInApp:"用 {app} 打开",chooseOpenApp:"选择应用",copyAll:"复制全部对话为 Markdown",copyFinalSummary:"仅复制最终总结",copied:"已复制",lastUsed:"上次使用",copyPath:"复制路径",changed:"{n} 处改动",gitTooltip:"打开「文件 > 改动」",detached:"游离",openPr:"打开 Pull Request",prStatusOpen:"已打开",prStatusClosed:"已关闭",prStatusMerged:"已合并",prStatusDraft:"草稿",prStatusUnknown:"未知",options:"选项",copySessionId:"复制 Session ID",pinSession:"置顶",unpinSession:"取消置顶",renameSession:"重命名",forkSession:"分叉会话",archiveSession:"归档",markSessionDone:"标记为完成",sessionDone:"已完成",reopenSession:"恢复进行中",exportSession:"导出会话",devBadge:"开发环境运行中"},qG={title:"侧边聊天",subtitle:"从当前会话 fork",empty:"在侧边随手问一句 —— 它共享当前会话的上下文。",placeholder:"问问侧边聊天…",send:"发送"},UG={actions:{summonApp:{label:"显示应用窗口",desc:"从任意位置将应用窗口唤起到前台"},newSession:{label:"新建会话",desc:"在当前工作区开始一个新会话"},searchSessions:{label:"搜索会话",desc:"打开会话搜索弹窗"},archiveSession:{label:"完成任务",desc:"立即完成当前会话(可在已完成列表找回)"},toggleSideChat:{label:"侧边聊天",desc:"打开或关闭 /btw 侧边聊天"},toggleSidebar:{label:"展开/收起侧边栏",desc:"收起或展开会话侧边栏"},openFolder:{label:"打开文件夹",desc:"通过系统原生选择器添加工作目录"},openInDefaultApp:{label:"在默认应用中打开",desc:"在默认编辑器或终端中打开当前工作目录"},openSettings:{label:"打开设置",desc:"显示或隐藏设置窗口"},toggleTerminal:{label:"切换终端",desc:"显示或隐藏底部终端面板"},sidebarTabOpen:{label:"进行中标签页",desc:"切换到侧栏的进行中列表"},sidebarTabDone:{label:"已完成标签页",desc:"切换到侧栏的已完成列表"},sidebarTabWorkspaces:{label:"工作空间标签页",desc:"切换到侧栏的工作空间目录"},selectPrevSibling:{label:"上一条",desc:"在当前标签页中选中上一条会话 / 上一个工作空间"},selectNextSibling:{label:"下一条",desc:"在当前标签页中选中下一条会话 / 下一个工作空间"},send:{label:"发送消息",desc:"发送输入框中的内容"},newline:{label:"换行",desc:"在输入框中插入换行"}},searchPlaceholder:"搜索快捷键",unassigned:"未分配",unassign:"取消分配",edit:"编辑快捷键",reset:"恢复默认",resetAll:"全部恢复默认",recording:"按下新的快捷键…",invalid:"该按键组合不能用作快捷键",notGlobal:"该按键组合无法注册为系统级快捷键",globalTaken:"该快捷键已被系统或其他应用占用",reserved:"系统菜单已占用该快捷键",reservedSteer:"steer 固定快捷键(Ctrl/Cmd+S),不可占用",reservedFind:"对话搜索固定快捷键(Ctrl/Cmd+F),不可占用",conflict:"已被「{action}」占用",customBadge:"自定义"},KG={panelAria:"终端",toolbarAria:"终端标签页",resizeAria:"调整终端面板高度",toggle:"切换终端",open:"打开终端",close:"关闭终端",newTab:"新建终端",closeTab:"关闭终端",restartTab:"重启终端",collapse:"收起终端面板",empty:"还没有终端,点击新建一个",processExited:"[进程已退出]",processExitedWithCode:"[进程已退出,退出码 {code}]"},VG={common:gG,app:mG,sidebar:vG,admin:yG,workspace:kG,conversation:bG,status:AG,composer:CG,login:wG,providers:xG,model:SG,sessions:_G,approval:MG,question:IG,tasks:EG,thinking:TG,diff:LG,fileTree:NG,filePreview:FG,mention:DG,warnings:BG,commands:$G,tools:RG,layout:zG,mobile:OG,theme:PG,onboarding:jG,settings:HG,header:WG,sideChat:qG,shortcuts:UG,terminal:KG},ZG={en:pG,zh:VG},GG="kimi-locale";function YF(){let e=null;try{e=globalThis.localStorage?.getItem(GG)??null}catch{e=null}return e==="en"||e==="zh"?e:globalThis.navigator?.language?.toLowerCase().startsWith("zh")?"zh":"en"}function QG(e){const t=e.locale??YF();return _Z({legacy:!1,locale:t,fallbackLocale:"en",messages:ZG})}const JF=Symbol("KimiI18n"),YG={t:e=>e};function a1(){const e=hn(JF,null);if(e)return e;try{const t=zt();return{t:(n,i)=>t.t(n,i),locale:t.locale.value}}catch{return YG}}const Ab=K(0),ax=F(()=>Ab.value>0),Cb=new Set;function XF(e){Cb.add(e),Ab.value+=1;let t=!1;return()=>{t||(t=!0,Cb.delete(e)&&(Ab.value-=1))}}function ux(e){if(!e)return!1;for(const t of Cb)if(t===e||t.contains(e))return!0;return!1}function JG(e){return typeof e=="object"&&e!==null&&typeof e.contains=="function"}function sc(e,t){let n;Pe([e,t],([i,o])=>{n?.(),n=void 0,i&&JG(o)&&(n=XF(o))},{flush:"post",immediate:!0}),Bc(()=>{n?.(),n=void 0})}const ju=6,Hu=8,XG=150,eQ=Xe({__name:"TooltipBubble",props:{target:{default:null},delegate:{default:null},text:{},placement:{default:"top"},maxWidth:{default:280},maxLines:{default:6}},setup(e){const t=e,n=K(),i=K(!1),o=K(!1),s=K({maxWidth:`${t.maxWidth}px`});let r,l=null,a;function u(){if(t.target)return t.target;const _=t.delegate;return _?_.firstElementChild??_:null}function c(_){const L=n.value;if(!L)return;const M=_.getBoundingClientRect(),N=L.offsetWidth,I=L.offsetHeight,z=window.innerWidth,H=window.innerHeight;let O=t.placement;O==="top"&&M.top-ju-I<Hu?O="bottom":O==="bottom"&&M.bottom+ju+I>H-Hu?O="top":O==="left"&&M.left-ju-N<Hu?O="right":O==="right"&&M.right+ju+N>z-Hu&&(O="left");let R=0,j=0;O==="top"?(R=M.top-ju-I,j=M.left+M.width/2-N/2):O==="bottom"?(R=M.bottom+ju,j=M.left+M.width/2-N/2):O==="left"?(R=M.top+M.height/2-I/2,j=M.left-ju-N):(R=M.top+M.height/2-I/2,j=M.right+ju),j=Math.min(Math.max(j,Hu),z-Hu-N),R=Math.min(Math.max(R,Hu),H-Hu-I),s.value={maxWidth:`${t.maxWidth}px`,top:`${Math.round(R)}px`,left:`${Math.round(j)}px`}}function d(){return ax.value&&!ux(u())}function h(){if(!t.text||d())return;const _=u();_&&(window.clearTimeout(r),r=window.setTimeout(()=>{i.value=!0,o.value=!1,dt(()=>{c(_),o.value=!0})},XG))}function p(){window.clearTimeout(r),i.value=!1,o.value=!1}function g(){h()}function m(){p()}function k(_){return _ instanceof Element?_.closest(".ui-tip"):null}function w(_){const L=t.delegate;if(!L)return;if(k(_.target)!==L){p();return}const M=_.relatedTarget;M instanceof Element&&L.contains(M)&&k(M)===L||h()}function y(_){const L=t.delegate;if(!L)return;const M=_.relatedTarget;M instanceof Element&&L.contains(M)||p()}function b(_){k(_.target)===t.delegate&&h()}function A(){p()}function T(){l&&(t.delegate?(l.removeEventListener("mouseover",w),l.removeEventListener("mouseout",y),l.removeEventListener("focusin",b),l.removeEventListener("focusout",A)):(l.removeEventListener("mouseenter",g),l.removeEventListener("mouseleave",m),l.removeEventListener("focusin",g),l.removeEventListener("focusout",m)),l=null)}function S(){T(),a?.disconnect(),a=void 0;const _=t.target??t.delegate;_&&(l=_,t.delegate?(_.addEventListener("mouseover",w),_.addEventListener("mouseout",y),_.addEventListener("focusin",b),_.addEventListener("focusout",A),a=new MutationObserver(()=>{i.value&&p()}),a.observe(_,{childList:!0})):(_.addEventListener("mouseenter",g),_.addEventListener("mouseleave",m),_.addEventListener("focusin",g),_.addEventListener("focusout",m)))}Pe(()=>[t.target,t.delegate],()=>{p(),S()}),Pe(ax,_=>{_&&!ux(u())&&p()});function x(){i.value&&p()}return cn(()=>{S(),window.addEventListener("scroll",x,!0),window.addEventListener("resize",x)}),Hn(()=>{window.clearTimeout(r),a?.disconnect(),T(),window.removeEventListener("scroll",x,!0),window.removeEventListener("resize",x)}),(_,L)=>i.value?(v(),ce(Ds,{key:0,to:"body"},[C("div",{ref_key:"bubble",ref:n,class:Fe(["ui-tip__bubble",{positioned:o.value}]),style:Kt([s.value,{"--tip-lines":e.maxLines}]),role:"tooltip"},D(e.text),7)])):X("",!0)}}),eD=kt(eQ,[["__scopeId","data-v-890c262c"]]),tQ=["type","disabled","aria-label"],nQ=Xe({__name:"IconButton",props:{size:{default:"md"},disabled:{type:Boolean},label:{},tooltip:{},type:{default:"button"}},setup(e,{expose:t}){const n=K();return t({el:n}),(i,o)=>(v(),E("button",{ref_key:"el",ref:n,class:Fe(["ui-icon-button",`ui-icon-button--${e.size}`]),type:e.type,disabled:e.disabled,"aria-label":e.label},[Rn(i.$slots,"default",{},void 0,!0),e.tooltip?(v(),ce(eD,{key:0,target:n.value??null,text:e.tooltip},null,8,["target","text"])):X("",!0)],10,tQ))}}),Jt=kt(nQ,[["__scopeId","data-v-2cbeca98"]]),iQ={class:"ui-action-toast-host"},oQ={class:"ui-action-toast__body"},sQ=Xe({__name:"ActionToast",props:{duration:{default:8e3},dismissLabel:{},dismissToken:{}},emits:["dismiss"],setup(e,{emit:t}){const n=e,i=t,{t:o}=a1();let s=null,r=0,l=0;function a(d){s=setTimeout(()=>i("dismiss",n.dismissToken),d),r=Date.now()+d}function u(){s!==null&&(clearTimeout(s),s=null,l=Math.max(0,r-Date.now()))}function c(){s===null&&a(l)}return a(n.duration),_n(()=>{s!==null&&clearTimeout(s)}),(d,h)=>(v(),E("div",iQ,[C("div",{class:"ui-action-toast",role:"status",onPointerenter:u,onPointerleave:c},[C("span",oQ,[Rn(d.$slots,"default")]),U(Jt,{class:"ui-action-toast__close",size:"sm",label:e.dismissLabel??f(o)("common.dismiss"),tooltip:e.dismissLabel??f(o)("common.dismiss"),onClick:h[0]||(h[0]=p=>i("dismiss",e.dismissToken))},{default:de(()=>[U(ve,{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])],32)]))}}),rQ=kt(sQ,[["__scopeId","data-v-e67fcfa0"]]),lQ={key:0,width:"36",height:"36",viewBox:"0 0 36 36",fill:"none",stroke:"var(--color-success)","stroke-width":"2","aria-hidden":"true"},aQ={key:1,width:"28",height:"28",viewBox:"0 0 28 28",fill:"none",stroke:"var(--color-danger)","stroke-width":"1.5","aria-hidden":"true"},uQ={key:2,width:"28",height:"28",viewBox:"0 0 28 28",fill:"none",stroke:"var(--color-warning)","stroke-width":"1.5","aria-hidden":"true"},Eh=Xe({__name:"AuthStateIcon",props:{kind:{}},setup(e){return(t,n)=>e.kind==="success"?(v(),E("svg",lQ,[...n[0]||(n[0]=[C("circle",{cx:"18",cy:"18",r:"15"},null,-1),C("polyline",{points:"10,18 15,24 26,12"},null,-1)])])):e.kind==="expired"?(v(),E("svg",aQ,[...n[1]||(n[1]=[C("circle",{cx:"14",cy:"14",r:"12"},null,-1),C("line",{x1:"14",y1:"8",x2:"14",y2:"15"},null,-1),C("circle",{cx:"14",cy:"19",r:"1.2",fill:"var(--color-danger)"},null,-1)])])):(v(),E("svg",uQ,[...n[2]||(n[2]=[C("path",{d:"M14 3 L26 24 H2 Z"},null,-1),C("line",{x1:"14",y1:"12",x2:"14",y2:"18"},null,-1),C("circle",{cx:"14",cy:"21.5",r:"1",fill:"var(--color-warning)"},null,-1)])]))}}),cQ={key:0,class:"ui-badge__dot","aria-hidden":"true"},dQ=Xe({__name:"Badge",props:{variant:{default:"neutral"},size:{default:"md"},dot:{type:Boolean}},setup(e){return(t,n)=>(v(),E("span",{class:Fe(["ui-badge",[`ui-badge--${e.variant}`,`ui-badge--${e.size}`]])},[e.dot?(v(),E("span",cQ)):X("",!0),Rn(t.$slots,"default",{},void 0,!0)],2))}}),br=kt(dQ,[["__scopeId","data-v-d879fe18"]]),fQ={class:"ui-banner__icon","aria-hidden":"true"},hQ={class:"ui-banner__text"},pQ=Xe({__name:"Banner",props:{variant:{default:"info"}},setup(e){return(t,n)=>(v(),E("div",{class:Fe(["ui-banner",`ui-banner--${e.variant}`]),role:"status"},[C("span",fQ,[Rn(t.$slots,"icon",{},()=>[e.variant==="info"?(v(),ce(ve,{key:0,name:"info",size:"md"})):(v(),ce(ve,{key:1,name:"alert-triangle",size:"md"}))],!0)]),C("span",hQ,[Rn(t.$slots,"default",{},void 0,!0)])],2))}}),Ed=kt(pQ,[["__scopeId","data-v-6d739c6d"]]),gQ=["aria-label"],mQ=Xe({__name:"Spinner",props:{size:{default:"md"},label:{}},setup(e){const{t}=a1(),n=K(null);let i,o;function s(){const r=n.value;if(r){if(o?.matches){i?.cancel(),i=void 0;return}i||(i=r.animate([{transform:"rotate(0deg)"},{transform:"rotate(360deg)"}],{duration:850,iterations:1/0}),i.startTime=0)}}return cn(()=>{const r=n.value;!r||typeof r.animate!="function"||(o=window.matchMedia("(prefers-reduced-motion: reduce)"),o.addEventListener("change",s),s())}),Hn(()=>{o?.removeEventListener("change",s),o=void 0,i?.cancel(),i=void 0}),(r,l)=>(v(),E("span",{ref_key:"boxRef",ref:n,class:Fe(["ui-spinner",`ui-spinner--${e.size}`]),role:"status","aria-label":e.label??f(t)("common.loading")},[...l[0]||(l[0]=[C("svg",{class:"ui-spinner__svg",viewBox:"0 0 24 24","aria-hidden":"true"},[C("circle",{class:"ui-spinner__track",cx:"12",cy:"12",r:"9"}),C("circle",{class:"ui-spinner__arc",cx:"12",cy:"12",r:"9"})],-1)])],10,gQ))}}),Oi=kt(mQ,[["__scopeId","data-v-476ed1b4"]]),vQ=["type","disabled"],yQ={class:"ui-button__content"},kQ=Xe({__name:"Button",props:{variant:{default:"primary"},size:{default:"md"},disabled:{type:Boolean},loading:{type:Boolean},type:{default:"button"}},setup(e){return(t,n)=>(v(),E("button",{class:Fe(["ui-button",[`ui-button--${e.variant}`,`ui-button--${e.size}`,{"is-loading":e.loading}]]),type:e.type,disabled:e.disabled||e.loading},[e.loading?(v(),ce(Oi,{key:0,size:"sm",class:"ui-button__spinner"})):X("",!0),C("span",yQ,[Rn(t.$slots,"default",{},void 0,!0)])],10,vQ))}}),Qt=kt(kQ,[["__scopeId","data-v-8e78b113"]]),bQ={key:0,class:"ui-card__head"},AQ={class:"ui-card__body"},CQ={key:1,class:"ui-card__foot"},wQ=Xe({__name:"Card",props:{elevated:{type:Boolean,default:!1}},setup(e){return(t,n)=>(v(),E("div",{class:Fe(["ui-card",{"is-elevated":e.elevated}])},[t.$slots.head?(v(),E("div",bQ,[Rn(t.$slots,"head",{},void 0,!0)])):X("",!0),C("div",AQ,[Rn(t.$slots,"default",{},void 0,!0)]),t.$slots.foot?(v(),E("div",CQ,[Rn(t.$slots,"foot",{},void 0,!0)])):X("",!0)],2))}}),xQ=kt(wQ,[["__scopeId","data-v-fbd05138"]]),SQ={class:"ctx-ring",viewBox:"0 0 20 20","aria-hidden":"true"},_Q=["stroke-dasharray","stroke-dashoffset"],X4=7,MQ=Xe({__name:"ContextRing",props:{pct:{}},setup(e){const t=e,n=2*Math.PI*X4;return(i,o)=>(v(),E("svg",SQ,[C("circle",{class:"ctx-ring-track",cx:"10",cy:"10",r:X4,fill:"none","stroke-width":"2.5"}),C("circle",{class:"ctx-ring-fill",cx:"10",cy:"10",r:X4,fill:"none","stroke-width":"2.5","stroke-linecap":"round","stroke-dasharray":`${n}`,"stroke-dashoffset":`${n*(1-t.pct/100)}`},null,8,_Q)]))}}),IQ=kt(MQ,[["__scopeId","data-v-de787cf2"]]),Fs=K(0),oh=K(0),EQ=["aria-label"],TQ={key:0,class:"ui-dialog__head"},LQ={class:"ui-dialog__titles"},NQ={key:0,class:"ui-dialog__title"},FQ={key:1,class:"ui-dialog__desc"},DQ={class:"ui-dialog__body"},BQ={key:1,class:"ui-dialog__foot"},$Q='a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])',RQ=Xe({__name:"Dialog",props:{open:{type:Boolean},title:{},ariaLabel:{},description:{},closeOnOverlay:{type:Boolean,default:!0},closeOnEsc:{type:Boolean,default:!0},size:{default:"md"},height:{default:"auto"},padded:{type:Boolean,default:!0},hideClose:{type:Boolean},level:{default:"raised"},initialFocus:{},focusOnOpen:{type:Boolean,default:!0}},emits:["update:open","close"],setup(e,{emit:t}){const n=e,i=t,{t:o}=a1(),s=K(null);let r=null;function l(){i("update:open",!1),i("close")}function a(){return s.value?Array.from(s.value.querySelectorAll($Q)):[]}function u(){const{initialFocus:h}=n;return h?typeof h=="function"?h()??null:typeof h=="string"?s.value?.querySelector(h)??null:s.value?.contains(h)?h:null:null}function c(h){if(!n.open)return;if(h.key==="Escape"&&n.closeOnEsc){h.preventDefault(),l();return}if(h.key!=="Tab")return;const p=a(),g=p[0],m=p[p.length-1];if(!g||!m){h.preventDefault(),s.value?.focus();return}const k=document.activeElement;h.shiftKey&&k===g?(h.preventDefault(),m.focus()):!h.shiftKey&&k===m&&(h.preventDefault(),g.focus())}function d(h){n.closeOnOverlay&&h.target===h.currentTarget&&l()}return Pe(()=>n.open,async h=>{if(h){if(Fs.value+=1,r=document.activeElement,n.focusOnOpen){await dt();const p=u(),g=a();(p??g[0]??s.value)?.focus()}}else Fs.value=Math.max(0,Fs.value-1),r instanceof HTMLElement&&(r.focus(),r=null)},{immediate:!0}),typeof window<"u"&&window.addEventListener("keydown",c),Hn(()=>{typeof window<"u"&&window.removeEventListener("keydown",c),n.open&&(Fs.value=Math.max(0,Fs.value-1),r instanceof HTMLElement&&r.focus())}),(h,p)=>(v(),ce(Ds,{to:"body"},[e.open?(v(),E("div",{key:0,class:"ui-dialog__overlay",onMousedown:d},[C("div",{ref_key:"panel",ref:s,class:Fe(["ui-dialog",[`ui-dialog--${e.size}`,{"ui-dialog--flush":!e.padded,"ui-dialog--fixed-height":e.height==="fixed","ui-dialog--grouped":e.level==="grouped"}]]),role:"dialog","aria-modal":"true","aria-label":e.ariaLabel??e.title,tabindex:"-1"},[e.title||h.$slots.head?(v(),E("div",TQ,[Rn(h.$slots,"head",{},()=>[C("div",LQ,[e.title?(v(),E("div",NQ,D(e.title),1)):X("",!0),e.description?(v(),E("div",FQ,D(e.description),1)):X("",!0)])],!0),e.hideClose?X("",!0):(v(),ce(Jt,{key:0,class:"ui-dialog__close",size:"sm",label:f(o)("common.close"),tooltip:f(o)("common.close"),onClick:l},{default:de(()=>[U(ve,{name:"close",size:"md"})]),_:1},8,["label","tooltip"]))])):X("",!0),C("div",DQ,[Rn(h.$slots,"default",{},void 0,!0)]),h.$slots.foot?(v(),E("div",BQ,[Rn(h.$slots,"foot",{},void 0,!0)])):X("",!0)],10,EQ)],32)):X("",!0)]))}}),Pc=kt(RQ,[["__scopeId","data-v-41ce75e5"]]),zQ={class:"ui-empty"},OQ={key:0,class:"ui-empty__icon","aria-hidden":"true"},PQ={key:1,class:"ui-empty__title"},jQ={key:2,class:"ui-empty__hint"},HQ=Xe({__name:"EmptyState",props:{title:{},hint:{}},setup(e){return(t,n)=>(v(),E("div",zQ,[t.$slots.icon?(v(),E("span",OQ,[Rn(t.$slots,"icon",{},void 0,!0)])):X("",!0),e.title?(v(),E("div",PQ,D(e.title),1)):X("",!0),e.hint?(v(),E("div",jQ,D(e.hint),1)):X("",!0),Rn(t.$slots,"default",{},void 0,!0)]))}}),WQ=kt(HQ,[["__scopeId","data-v-6da80932"]]),qQ={key:0,class:"ui-field__label"},UQ={key:1,class:"ui-field__error"},KQ={key:2,class:"ui-field__hint"},VQ=Xe({__name:"Field",props:{label:{},hint:{},error:{}},setup(e){return(t,n)=>(v(),E("div",{class:Fe(["ui-field",{"has-error":!!e.error}])},[e.label?(v(),E("label",qQ,D(e.label),1)):X("",!0),Rn(t.$slots,"default",{},void 0,!0),e.error?(v(),E("span",UQ,D(e.error),1)):e.hint?(v(),E("span",KQ,D(e.hint),1)):X("",!0)],2))}}),ZQ=kt(VQ,[["__scopeId","data-v-a8de5f7f"]]),GQ=["type","value","placeholder","disabled","readonly"],QQ=Xe({__name:"Input",props:{modelValue:{},size:{default:"md"},type:{default:"text"},placeholder:{},disabled:{type:Boolean},readonly:{type:Boolean},error:{type:Boolean}},emits:["update:modelValue","focus","blur"],setup(e,{expose:t,emit:n}){const i=n,o=K();function s(a){i("update:modelValue",a.target.value)}function r(){o.value?.focus()}function l(){o.value?.select()}return t({focus:r,select:l,el:o}),(a,u)=>(v(),E("input",{ref_key:"el",ref:o,class:Fe(["ui-input",[`ui-input--${e.size}`,{"has-error":e.error}]]),type:e.type,value:e.modelValue,placeholder:e.placeholder,disabled:e.disabled,readonly:e.readonly,onInput:s,onFocus:u[0]||(u[0]=c=>a.$emit("focus",c)),onBlur:u[1]||(u[1]=c=>a.$emit("blur",c))},null,42,GQ))}}),Ns=kt(QQ,[["__scopeId","data-v-f1cdf732"]]),YQ={class:"ui-kbd"},JQ=Xe({__name:"Kbd",props:{keys:{}},setup(e){return(t,n)=>(v(),E("span",YQ,[(v(!0),E(Ee,null,pt(e.keys,i=>(v(),E("kbd",{key:i,class:"ui-kbd__key"},D(i),1))),128))]))}}),ku=kt(JQ,[["__scopeId","data-v-04b30ce2"]]),XQ=["role"],eY=Xe({__name:"Menu",props:{role:{default:"menu"}},setup(e,{expose:t}){const n=K();t({el:n});let i;return cn(()=>{n.value&&(i=XF(n.value))}),Hn(()=>i?.()),(o,s)=>(v(),E("div",{ref_key:"el",ref:n,class:"ui-menu",role:e.role},[Rn(o.$slots,"default",{},void 0,!0)],8,XQ))}}),Zs=kt(eY,[["__scopeId","data-v-18d99605"]]),tY={key:0,class:"ui-menu-sep",role:"separator"},nY=["role","disabled"],iY=Xe({__name:"MenuItem",props:{active:{type:Boolean},danger:{type:Boolean},disabled:{type:Boolean},separator:{type:Boolean},size:{default:"md"},role:{default:"menuitem"}},emits:["click"],setup(e){return(t,n)=>e.separator?(v(),E("div",tY)):(v(),E("button",{key:1,class:Fe(["ui-menu-item",[`ui-menu-item--${e.size}`,{"is-active":e.active,"is-danger":e.danger}]]),type:"button",role:e.role,disabled:e.disabled,onClick:n[0]||(n[0]=i=>t.$emit("click",i))},[Rn(t.$slots,"default",{},void 0,!0)],10,nY))}}),Ut=kt(iY,[["__scopeId","data-v-607794d8"]]),oY=Xe({__name:"Tooltip",props:{text:{},placement:{default:"top"},maxWidth:{default:280},maxLines:{default:6}},setup(e){const t=K();return(n,i)=>(v(),E(Ee,null,[C("span",{ref_key:"trigger",ref:t,class:"ui-tip"},[Rn(n.$slots,"default",{},void 0,!0)],512),U(eD,{delegate:t.value??null,text:e.text,placement:e.placement,"max-width":e.maxWidth,"max-lines":e.maxLines},null,8,["delegate","text","placement","max-width","max-lines"])],64))}}),gn=kt(oY,[["__scopeId","data-v-414bd903"]]),sY={class:"ui-panel-header__title"},rY={key:0,class:"ui-panel-header__sub"},lY=Xe({__name:"PanelHeader",props:{title:{},subtitle:{},closable:{type:Boolean,default:!0},closeLabel:{},closeIcon:{default:"close"},wrap:{type:Boolean}},emits:["close"],setup(e){const{t}=a1();return(n,i)=>(v(),E("div",{class:Fe(["ui-panel-header",{wrap:e.wrap}])},[U(gn,{text:e.title},{default:de(()=>[C("span",sY,D(e.title),1)]),_:1},8,["text"]),U(gn,{text:e.subtitle},{default:de(()=>[e.subtitle?(v(),E("span",rY,D(e.subtitle),1)):X("",!0)]),_:1},8,["text"]),Rn(n.$slots,"default",{},void 0,!0),e.closable?(v(),ce(Jt,{key:0,class:"ui-panel-header__close",size:"sm",label:e.closeLabel??f(t)("common.close"),tooltip:e.closeLabel??f(t)("common.close"),onClick:i[0]||(i[0]=o=>n.$emit("close"))},{default:de(()=>[U(ve,{name:e.closeIcon,size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])):X("",!0)],2))}}),rf=kt(lY,[["__scopeId","data-v-2650aff3"]]),aY=["disabled","aria-pressed"],uY=Xe({__name:"Pill",props:{clickable:{type:Boolean,default:!0},active:{type:Boolean},disabled:{type:Boolean},ariaPressed:{type:Boolean}},emits:["click"],setup(e){return(t,n)=>e.clickable?(v(),E("button",{key:0,class:Fe(["ui-pill",{"is-active":e.active}]),type:"button",disabled:e.disabled,"aria-pressed":e.ariaPressed,onClick:n[0]||(n[0]=i=>t.$emit("click",i))},[Rn(t.$slots,"default",{},void 0,!0)],10,aY)):(v(),E("span",{key:1,class:Fe(["ui-pill",{"is-active":e.active}])},[Rn(t.$slots,"default",{},void 0,!0)],2))}}),tD=kt(uY,[["__scopeId","data-v-fe6a2873"]]),cY=Xe({__name:"ScrollArea",props:{orientation:{default:"vertical"},hideDelay:{default:600}},setup(e,{expose:t}){const n=e,i=K(null),o=K(null),s=K(!1),r=K({overflow:!1,size:0,offset:0}),l=K({overflow:!1,size:0,offset:0}),a=K(null);let u=null,c=null,d=null;const h=F(()=>({overflowX:n.orientation==="vertical"?"hidden":"auto",overflowY:n.orientation==="horizontal"?"hidden":"auto"})),p=F(()=>({height:`${r.value.size}px`,transform:`translateY(${r.value.offset}px)`})),g=F(()=>({width:`${l.value.size}px`,transform:`translateX(${l.value.offset}px)`}));function m(L,M,N){if(!(M>L+1)||L<=0)return{overflow:!1,size:0,offset:0};const z=Math.max(0,L-4),H=Math.min(z,Math.max(24,z*L/M)),O=Math.max(0,z-H),R=Math.max(1,M-L);return{overflow:!0,size:H,offset:O*N/R}}function k(){const L=o.value;if(!L)return;const M=m(L.clientHeight,L.scrollHeight,L.scrollTop),N=m(L.clientWidth,L.scrollWidth,L.scrollLeft);(M.overflow!==r.value.overflow||M.size!==r.value.size||M.offset!==r.value.offset)&&(r.value=M),(N.overflow!==l.value.overflow||N.size!==l.value.size||N.offset!==l.value.offset)&&(l.value=N)}function w(){u!==null&&clearTimeout(u),u=null}function y(){w(),s.value=!0}function b(){w(),!(a.value||i.value?.matches(":hover, :focus-within"))&&(u=setTimeout(()=>{s.value=!1,u=null},n.hideDelay))}function A(){k(),y(),b()}function T(L,M){const N=o.value;N&&(M.preventDefault(),y(),a.value={axis:L,pointerId:M.pointerId,startPointer:L==="vertical"?M.clientY:M.clientX,startScroll:L==="vertical"?N.scrollTop:N.scrollLeft},M.currentTarget.setPointerCapture(M.pointerId))}function S(L){const M=a.value,N=o.value;if(!M||M.pointerId!==L.pointerId||!N)return;const I=M.axis==="vertical"?L.clientY:L.clientX,z=M.axis==="vertical"?N.clientHeight:N.clientWidth,H=M.axis==="vertical"?N.scrollHeight:N.scrollWidth,O=M.axis==="vertical"?r.value.size:l.value.size,R=Math.max(1,z-4-O),j=(I-M.startPointer)*(H-z)/R;M.axis==="vertical"?N.scrollTop=M.startScroll+j:N.scrollLeft=M.startScroll+j}function x(L){!a.value||a.value.pointerId!==L.pointerId||(a.value=null,b())}function _(){const L=o.value;if(!(!L||!c))for(const M of L.children)c.observe(M)}return cn(async()=>{await dt();const L=o.value;L&&(c=new ResizeObserver(k),c.observe(L),_(),d=new MutationObserver(()=>{_(),k()}),d.observe(L,{childList:!0,subtree:!0,characterData:!0}),k())}),Hn(()=>{w(),c?.disconnect(),d?.disconnect()}),t({viewport:o,updateMetrics:k}),(L,M)=>(v(),E("div",{ref_key:"root",ref:i,class:"ui-scroll-area",onPointerenter:y,onPointerleave:b,onFocusin:y,onFocusout:b},[C("div",{ref_key:"viewport",ref:o,class:"ui-scroll-area__viewport",style:Kt(h.value),tabindex:"0",onScroll:A},[Rn(L.$slots,"default",{},void 0,!0)],36),r.value.overflow&&n.orientation!=="horizontal"?(v(),E("div",{key:0,class:Fe(["ui-scroll-area__bar ui-scroll-area__bar--vertical",{"is-visible":s.value}]),"aria-hidden":"true"},[C("span",{class:"ui-scroll-area__thumb",style:Kt(p.value),onPointerdown:M[0]||(M[0]=N=>T("vertical",N)),onPointermove:S,onPointerup:x,onPointercancel:x},null,36)],2)):X("",!0),l.value.overflow&&n.orientation!=="vertical"?(v(),E("div",{key:1,class:Fe(["ui-scroll-area__bar ui-scroll-area__bar--horizontal",{"is-visible":s.value}]),"aria-hidden":"true"},[C("span",{class:"ui-scroll-area__thumb",style:Kt(g.value),onPointerdown:M[1]||(M[1]=N=>T("horizontal",N)),onPointermove:S,onPointerup:x,onPointercancel:x},null,36)],2)):X("",!0)],544))}}),cx=kt(cY,[["__scopeId","data-v-9c504ebc"]]),dY=["data-icon","aria-selected","onClick"],fY=Xe({__name:"SegmentedControl",props:{modelValue:{},options:{},size:{}},emits:["update:modelValue"],setup(e,{emit:t}){const n=e,i=t,o=K(null),s=K([]),r=K(!1),l=K({});let a=null;function u(d,h){d instanceof HTMLElement&&(s.value[h]=d)}async function c(){await dt();const d=n.options.findIndex(p=>p.value===n.modelValue),h=s.value[d];h&&(l.value={width:`${h.offsetWidth}px`,height:`${h.offsetHeight}px`,transform:`translate(${h.offsetLeft}px, ${h.offsetTop}px)`},r.value=!0)}return Pe(()=>[n.modelValue,n.options.length],c,{immediate:!0}),cn(()=>{a=new ResizeObserver(()=>c()),o.value&&a.observe(o.value);for(const d of s.value)a.observe(d);c()}),Hn(()=>a?.disconnect()),(d,h)=>(v(),E("div",{ref_key:"root",ref:o,class:Fe(["ui-seg",`ui-seg--${e.size??"md"}`]),role:"tablist"},[C("span",{class:Fe(["ui-seg__indicator",{"is-ready":r.value}]),style:Kt(l.value),"aria-hidden":"true"},null,6),(v(!0),E(Ee,null,pt(e.options,(p,g)=>(v(),E("button",{key:p.value,ref_for:!0,ref:m=>u(m,g),class:Fe(["ui-seg__item",{"is-on":p.value===e.modelValue}]),"data-icon":p.icon,type:"button",role:"tab","aria-selected":p.value===e.modelValue,onClick:m=>i("update:modelValue",p.value)},[p.icon?(v(),ce(ve,{key:0,class:"ui-seg__icon",name:p.icon,size:"sm"},null,8,["name"])):X("",!0),p.swatch?(v(),E("span",{key:1,class:"ui-seg__swatch",style:Kt({backgroundColor:p.swatch})},null,4)):X("",!0),$e(" "+D(p.label),1)],10,dY))),128))],2))}}),Vs=kt(fY,[["__scopeId","data-v-b09ef1d1"]]);function hY(e){const{anchor:t,menuHeight:n,viewportWidth:i,viewportHeight:o,gap:s,margin:r}=e,l=o-r-(t.bottom+s),a=t.top-s-r,u=l<n&&a>l,c=u?a:l,d=Math.min(t.width,Math.max(0,i-2*r)),h=Math.min(Math.max(t.left,r),Math.max(r,i-r-d)),p={left:`${Math.round(h)}px`,width:`${Math.round(d)}px`};return c<n&&(p.maxHeight=`${Math.max(0,Math.round(c))}px`),u?(p.top="auto",p.bottom=`${Math.round(o-t.top+s)}px`):(p.top=`${Math.round(t.bottom+s)}px`,p.bottom="auto"),{style:p,flipUp:u}}function pY(e,t){return!(t&&e&&t.contains(e))}const gY=["aria-expanded","disabled"],mY=["src"],vY={class:"ui-select__value-text"},yY={key:0,class:"ui-select__group"},kY=["aria-selected","disabled","onMouseenter","onClick"],bY=["src"],dx=4,fx=8,AY=Xe({inheritAttrs:!1,__name:"Select",props:{modelValue:{},options:{},placeholder:{default:""},size:{default:"md"},disabled:{type:Boolean},error:{type:Boolean}},emits:["update:modelValue"],setup(e,{emit:t}){const n=e,i=t,o=r1(),s=K(null),r=K(null),l=K(null),a=K([]),u=K(!1),c=K(-1),d=`ui-select-${Math.random().toString(36).slice(2,9)}`,h=K({});sc(u,l);let p=!1,g=!1,m=!1,k=dx,w=fx;function y(oe,q){const ne=getComputedStyle(document.documentElement).getPropertyValue(oe),ie=Number.parseFloat(ne);return Number.isFinite(ie)?ie:q}const b=F(()=>n.options.findIndex(oe=>String(oe.value)===String(n.modelValue??""))),A=F(()=>n.options[b.value]),T=F(()=>A.value?.label??n.placeholder);function S(oe,q){a.value[q]=oe instanceof HTMLElement?oe:null}function x(){const oe=l.value,q=a.value[c.value];!oe||!q||(oe.scrollTop=q.offsetTop-(oe.clientHeight-q.offsetHeight)/2)}function _(){const oe=r.value,q=l.value;if(!oe||!q)return;q.style.maxHeight="";const ne=oe.getBoundingClientRect();h.value=hY({anchor:ne,menuHeight:q.offsetHeight,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,gap:k,margin:w}).style}function L(){n.disabled||u.value||(u.value=!0,c.value=b.value>=0?b.value:n.options.findIndex(oe=>!oe.disabled),k=y("--space-1",dx),w=y("--space-2",fx),ae(),dt(()=>{_(),dt(x)}))}function M({restoreFocus:oe=!1}={}){u.value&&(u.value=!1,Y(),oe&&dt(()=>r.value?.focus()))}function N(){u.value?M():L()}function I(oe){oe.disabled||(String(oe.value)!==String(n.modelValue??"")&&i("update:modelValue",oe.value),M({restoreFocus:!0}))}function z(oe){if(u.value||L(),n.options.length===0)return;let q=c.value;for(let ne=0;ne<n.options.length;ne+=1)if(q=(q+oe+n.options.length)%n.options.length,!n.options[q]?.disabled){c.value=q,dt(x);return}}function H(oe){if(oe.key==="ArrowDown")oe.preventDefault(),z(1);else if(oe.key==="ArrowUp")oe.preventDefault(),z(-1);else if(oe.key==="Enter"||oe.key===" ")if(oe.preventDefault(),!u.value)L();else{const q=n.options[c.value];q&&I(q)}else if(oe.key==="Escape")oe.preventDefault(),M();else if(oe.key==="Tab")M();else if(oe.key==="PageUp"||oe.key==="PageDown")u.value&&oe.preventDefault();else if(oe.key==="Home"||oe.key==="End"){oe.preventDefault();const q=n.options.map((ne,ie)=>ne.disabled?-1:ie).filter(ne=>ne>=0);c.value=oe.key==="Home"?q[0]??-1:q.at(-1)??-1,dt(x)}}function O(oe){g=u.value;const q=oe.target;s.value?.contains(q)||l.value?.contains(q)||M()}function R(){const oe=m;g=!1,m=!1,Y(),oe&&u.value&&r.value?.focus()}function j(){m=!0}function $(oe){const q=oe.relatedTarget;q instanceof Node&&(s.value?.contains(q)||l.value?.contains(q))||requestAnimationFrame(()=>{if(!u.value||m)return;const ne=document.activeElement;ne&&(s.value?.contains(ne)||l.value?.contains(ne))||M()})}function W(oe){u.value&&(l.value?.contains(oe.target)||_())}function P(){u.value&&_()}Pe(()=>n.options.length,()=>{u.value&&dt(_)});function Z(oe){(oe.type==="touchmove"?u.value||g:u.value)&&pY(oe.target,l.value)&&oe.preventDefault()}function ae(){p||(p=!0,document.addEventListener("wheel",Z,{capture:!0,passive:!1}),document.addEventListener("touchmove",Z,{capture:!0,passive:!1}))}function V(){p&&(p=!1,document.removeEventListener("wheel",Z,{capture:!0}),document.removeEventListener("touchmove",Z,{capture:!0}))}function Y(){u.value||g||V()}return cn(()=>{document.addEventListener("pointerdown",O,{passive:!0}),document.addEventListener("pointerup",R,{passive:!0}),document.addEventListener("pointercancel",R,{passive:!0}),document.addEventListener("scroll",W,!0),window.addEventListener("resize",P)}),_n(()=>{g=!1,V(),document.removeEventListener("pointerdown",O),document.removeEventListener("pointerup",R),document.removeEventListener("pointercancel",R),document.removeEventListener("scroll",W,!0),window.removeEventListener("resize",P)}),(oe,q)=>(v(),E("div",{ref_key:"rootRef",ref:s,class:Fe(["ui-select",[`ui-select--${e.size}`,{"has-error":e.error,"is-open":u.value,"is-disabled":e.disabled}]])},[C("button",ni({ref_key:"triggerRef",ref:r},f(o),{class:"ui-select__trigger",type:"button",role:"combobox","aria-controls":d,"aria-expanded":u.value,"aria-haspopup":"listbox",disabled:e.disabled,onClick:N,onKeydown:H,onFocusout:$}),[C("span",{class:Fe(["ui-select__value",{"is-placeholder":!A.value}])},[A.value?.icon?(v(),E("img",{key:0,class:"ui-select__icon",src:A.value.icon,alt:""},null,8,mY)):X("",!0),C("span",vY,D(T.value),1)],2),U(ve,{class:"ui-select__chevron",name:"chevron-down",size:"sm"})],16,gY),(v(),ce(Ds,{to:"body"},[u.value?(v(),E("div",{key:0,id:d,ref_key:"listRef",ref:l,class:"ui-select__menu",style:Kt(h.value),role:"listbox",onPointerdown:j,onFocusout:$},[(v(!0),E(Ee,null,pt(e.options,(ne,ie)=>(v(),E(Ee,{key:`${ne.group??""}:${ne.value}`},[ne.group&&ne.group!==e.options[ie-1]?.group?(v(),E("div",yY,D(ne.group),1)):X("",!0),C("button",{ref_for:!0,ref:pe=>S(pe,ie),class:Fe(["ui-select__option",{"is-selected":ie===b.value,"is-active":ie===c.value}]),type:"button",role:"option","aria-selected":ie===b.value,disabled:ne.disabled,onMouseenter:pe=>c.value=ie,onClick:pe=>I(ne)},[U(ve,{class:"ui-select__check",name:"check",size:"sm"}),ne.icon?(v(),E("img",{key:0,class:"ui-select__icon ui-select__icon--option",src:ne.icon,alt:""},null,8,bY)):X("",!0),C("span",null,D(ne.label),1)],42,kY)],64))),128))],36)):X("",!0)]))],2))}}),wb=kt(AY,[["__scopeId","data-v-285335af"]]),CY=Xe({__name:"StatusDot",props:{status:{}},setup(e){const t=e;function n(o){switch(o){case"ok":case"done":case"completed":case"success":return"ok";case"error":case"failed":case"fail":case"danger":return"error";case"running":case"run":case"working":case"in_progress":case"active":return"running";case"suspended":return"suspended";default:return"idle"}}const i=F(()=>n(t.status));return(o,s)=>(v(),E("span",{class:Fe(["kw-dot",`kw-dot--${i.value}`]),"aria-hidden":"true"},null,2))}}),ml=kt(CY,[["__scopeId","data-v-390a778a"]]),wY=["aria-checked","aria-label","disabled"],xY=Xe({__name:"Switch",props:{modelValue:{type:Boolean},disabled:{type:Boolean},label:{}},emits:["update:modelValue"],setup(e,{emit:t}){const n=t;return(i,o)=>(v(),E("button",{class:Fe(["ui-switch",{"is-on":e.modelValue}]),type:"button",role:"switch","aria-checked":e.modelValue,"aria-label":e.label,disabled:e.disabled,onClick:o[0]||(o[0]=s=>n("update:modelValue",!e.modelValue))},[...o[1]||(o[1]=[C("span",{class:"ui-switch__thumb"},null,-1)])],10,wY))}}),dd=kt(xY,[["__scopeId","data-v-2fc56545"]]),SY=["value","rows","placeholder","disabled","readonly"],_Y=Xe({__name:"Textarea",props:{modelValue:{},rows:{default:3},placeholder:{},disabled:{type:Boolean},readonly:{type:Boolean},error:{type:Boolean},resize:{type:Boolean,default:!0}},emits:["update:modelValue","focus","blur"],setup(e,{expose:t,emit:n}){const i=n;function o(r){i("update:modelValue",r.target.value)}const s=K(null);return t({el:s}),(r,l)=>(v(),E("textarea",{ref_key:"textareaRef",ref:s,class:Fe(["ui-textarea",{"has-error":e.error,"no-resize":!e.resize}]),value:e.modelValue,rows:e.rows,placeholder:e.placeholder,disabled:e.disabled,readonly:e.readonly,onInput:o,onFocus:l[0]||(l[0]=a=>r.$emit("focus",a)),onBlur:l[1]||(l[1]=a=>r.$emit("blur",a))},null,42,SY))}}),MY=kt(_Y,[["__scopeId","data-v-07cc9fb9"]]),IY={class:"ui-toast__icon","aria-hidden":"true"},EY={class:"ui-toast__body"},TY={class:"ui-toast__title"},LY={key:0,class:"ui-toast__msg"},NY=Xe({__name:"Toast",props:{variant:{default:"info"},title:{},message:{},dismissLabel:{}},emits:["dismiss"],setup(e){const{t}=a1();return(n,i)=>(v(),E("div",{class:Fe(["ui-toast",`ui-toast--${e.variant}`])},[C("span",IY,[Rn(n.$slots,"icon",{},()=>[e.variant==="success"?(v(),ce(ve,{key:0,name:"check"})):e.variant==="danger"?(v(),ce(ve,{key:1,name:"close"})):e.variant==="warning"?(v(),ce(ve,{key:2,name:"alert-triangle"})):(v(),ce(ve,{key:3,name:"info"}))],!0)]),C("div",EY,[C("div",TY,D(e.title),1),e.message?(v(),E("div",LY,D(e.message),1)):X("",!0),Rn(n.$slots,"default",{},void 0,!0)]),U(Jt,{class:"ui-toast__close",size:"sm",label:e.dismissLabel??f(t)("common.dismiss"),tooltip:e.dismissLabel??f(t)("common.dismiss"),onClick:i[0]||(i[0]=o=>n.$emit("dismiss"))},{default:de(()=>[U(ve,{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])],2))}}),FY=kt(NY,[["__scopeId","data-v-62bc76d1"]]),DY=100;function bl(){let e=!1,t=0;function n(){e=!0,t=0}function i(){e=!1,t=Date.now()}function o(){e=!1,t=0}function s(r){return e||r.isComposing||r.keyCode===229||Date.now()-t<DY}return typeof window<"u"&&(window.addEventListener("focusin",o,!0),window.addEventListener("focusout",o,!0)),_n(()=>{typeof window<"u"&&(window.removeEventListener("focusin",o,!0),window.removeEventListener("focusout",o,!0))}),{handleCompositionStart:n,handleCompositionEnd:i,resetComposition:o,isComposingKeyEvent:s}}function $d(e,t,n="/api/v1"){return`${e}${n}${t.startsWith("/")?t:`/${t}`}`}function BY(e,t){const n=new URL(`${e}/api/v1/ws`);return n.protocol=n.protocol==="https:"?"wss:":"ws:",n.searchParams.set("client_id",t),n.toString()}const s6={};class cc extends Error{code;requestId;details;timestamp;durationMs;constructor(t){super(t.msg),this.name="DaemonApiError",this.code=t.code,this.requestId=t.requestId,this.details=t.details,this.timestamp=t.timestamp,this.durationMs=t.durationMs}}class nu extends Error{cause;method;path;url;requestId;phase;timeoutMs;status;statusText;contentType;bodyPreview;timestamp;durationMs;constructor(t){super(t.message),this.name="DaemonNetworkError",this.cause=t.cause,this.method=t.method,this.path=t.path,this.url=t.url,this.requestId=t.requestId,this.phase=t.phase,this.timeoutMs=t.timeoutMs,this.status=t.status,this.statusText=t.statusText,this.contentType=t.contentType,this.bodyPreview=t.bodyPreview,this.timestamp=t.timestamp,this.durationMs=t.durationMs}}class r6 extends Error{size;limit;constructor(t){super(`file too large to preview: ${t.size} bytes (limit ${t.limit})`),this.name="FileTooLargeError",this.size=t.size,this.limit=t.limit}}function ko(e){return e instanceof cc||typeof e=="object"&&e!==null&&e.name==="DaemonApiError"&&typeof e.code=="number"}function t9(e){return e instanceof nu||typeof e=="object"&&e!==null&&e.name==="DaemonNetworkError"&&typeof e.method=="string"&&typeof e.path=="string"}function $Y(e){return t9(e)&&typeof e.cause=="object"&&e.cause!==null&&e.cause.name==="TimeoutError"}function RY(e){return e instanceof r6||typeof e=="object"&&e!==null&&e.name==="FileTooLargeError"&&typeof e.limit=="number"}const zY=41301,OY=40922;function hx(e){return ko(e)&&e.code===OY}const dp=3e4,gm=5*6e4,px=5*6e4,nD="0123456789ABCDEFGHJKMNPQRSTVWXYZ",gx=500,iD=40101;function mx(e,t){for(const[n,i]of Object.entries(t))if(i!==void 0)if(Array.isArray(i))for(const o of i)o!==void 0&&e.append(n,String(o));else e.set(n,String(i))}function mm(e=dp){try{return AbortSignal.timeout(e)}catch{return}}function PY(e,t){let n="",i=e;for(let o=0;o<t;o++)n=nD[i%32]+n,i=Math.floor(i/32);return n}function jY(e){const t=new Uint8Array(e);if(globalThis.crypto?.getRandomValues)globalThis.crypto.getRandomValues(t);else for(let n=0;n<t.length;n++)t[n]=Math.floor(Math.random()*256);return Array.from(t,n=>nD[n%32]).join("")}function vm(){return`${PY(Date.now(),10)}${jY(16)}`}function HY(e){try{const t=[];return e.forEach((n,i)=>{typeof n=="string"?t.push({field:i,value:n}):t.push({field:i,file:n.name,size:n.size,type:n.type})}),{formData:t}}catch{return"[FormData]"}}async function e3(e){try{const t=await e.text();return t?t.length>gx?`${t.slice(0,gx)}...`:t:void 0}catch{return}}class vx{constructor(t){this.opts=t,this.tracer=t.tracer??s6}tracer;async get(t,n){return this.request("GET",t,void 0,n)}async getBlob(t,n,i){let o=$d(this.opts.origin,t,this.opts.restBasePath);if(n){const c=new URLSearchParams;mx(c,n);const d=c.toString();d&&(o=`${o}?${d}`)}const s=vm(),r={"X-Request-Id":s};this.addClientHeaders(r);const l=Date.now();this.tracer.restRequest?.({method:"GET",path:t,url:o,requestId:s});let a;try{a=await fetch(o,{method:"GET",headers:r,signal:mm()})}catch(c){throw this.tracer.restFailure?.({method:"GET",path:t,requestId:s,phase:"fetch",durationMs:Date.now()-l,error:c}),new nu({message:`Network error calling GET ${t}`,cause:c,method:"GET",path:t,url:o,requestId:s,phase:"fetch",timeoutMs:dp,timestamp:Date.now(),durationMs:Date.now()-l})}if(a.ok){this.tracer.restResponse?.({method:"GET",path:t,requestId:s,status:a.status,durationMs:Date.now()-l,code:0,msg:""});const c=Number(a.headers.get("content-length")??0);if(i?.maxBytes!==void 0&&c>i.maxBytes)throw a.body?.cancel(),new r6({size:c,limit:i.maxBytes});return a.blob()}let u;try{u=await a.clone().json()}catch{}throw this.checkAuthRequired(a,u?.code??0),this.tracer.restResponse?.({method:"GET",path:t,requestId:s,status:a.status,durationMs:Date.now()-l,code:u?.code??a.status,msg:u?.msg??a.statusText,envelopeRequestId:u?.request_id}),new cc({code:u?.code??a.status,msg:u?.msg??a.statusText,requestId:u?.request_id??s,details:u?.details,timestamp:Date.now(),durationMs:Date.now()-l})}async post(t,n,i){return this.request("POST",t,n,void 0,i?.allowCodes,i?.timeoutMs)}async postZip(t,n,i){const o="POST",s=$d(this.opts.origin,t,this.opts.restBasePath),r=vm(),l={"X-Request-Id":r,"Content-Type":"application/json; charset=utf-8"};this.addClientHeaders(l);const a=Date.now();this.tracer.restRequest?.({method:o,path:t,url:s,requestId:r,body:i});let u;try{u=await fetch(s,{method:o,headers:l,body:JSON.stringify(n),signal:mm(gm)})}catch(p){throw this.tracer.restFailure?.({method:o,path:t,requestId:r,phase:"fetch",durationMs:Date.now()-a,error:p}),new nu({message:`Network error calling ${o} ${t}`,cause:p,method:o,path:t,url:s,requestId:r,phase:"fetch",timeoutMs:gm,timestamp:Date.now(),durationMs:Date.now()-a})}const c=u.headers.get("content-type")??void 0,d=c?.split(";",1)[0]?.trim().toLowerCase();if(!u.ok||d!=="application/zip"){let p;try{p=await u.clone().json()}catch{}if(this.checkAuthRequired(u,p?.code??0),!u.ok||p!==void 0&&p.code!==0){const k=p?.code??u.status,w=p?.msg??u.statusText;throw this.tracer.restResponse?.({method:o,path:t,requestId:r,status:u.status,durationMs:Date.now()-a,code:k,msg:w,envelopeRequestId:p?.request_id}),new cc({code:k,msg:w,requestId:p?.request_id??r,details:p?.details,timestamp:Date.now(),durationMs:Date.now()-a})}const g=u.clone(),m=new TypeError(`Expected application/zip, received ${c??"no content type"}`);throw this.tracer.restFailure?.({method:o,path:t,requestId:r,phase:"parse",durationMs:Date.now()-a,status:u.status,error:m}),new nu({message:`Invalid ZIP response from ${o} ${t}`,cause:m,method:o,path:t,url:s,requestId:r,phase:"parse",timeoutMs:gm,status:u.status,statusText:u.statusText,contentType:c,bodyPreview:await e3(g),timestamp:Date.now(),durationMs:Date.now()-a})}let h;try{h=await u.blob()}catch(p){throw this.tracer.restFailure?.({method:o,path:t,requestId:r,phase:"parse",durationMs:Date.now()-a,status:u.status,error:p}),new nu({message:`Failed to read ZIP response from ${o} ${t}`,cause:p,method:o,path:t,url:s,requestId:r,phase:"parse",timeoutMs:gm,status:u.status,statusText:u.statusText,contentType:c,timestamp:Date.now(),durationMs:Date.now()-a})}return this.tracer.restResponse?.({method:o,path:t,requestId:r,status:u.status,durationMs:Date.now()-a,code:0,msg:""}),{blob:h,contentDisposition:u.headers.get("content-disposition")??void 0}}async postForm(t,n){const i=$d(this.opts.origin,t,this.opts.restBasePath),o=vm(),s={"X-Request-Id":o};this.addClientHeaders(s);const r=Date.now();this.tracer.restRequest?.({method:"POST",path:t,url:i,requestId:o,body:HY(n)});let l;try{l=await fetch(i,{method:"POST",headers:s,body:n,signal:mm()})}catch(c){throw this.tracer.restFailure?.({method:"POST",path:t,requestId:o,phase:"fetch",durationMs:Date.now()-r,error:c}),new nu({message:`Network error calling POST ${t}`,cause:c,method:"POST",path:t,url:i,requestId:o,phase:"fetch",timeoutMs:dp,timestamp:Date.now(),durationMs:Date.now()-r})}let a;const u=l.clone();try{a=await l.json()}catch(c){throw this.tracer.restFailure?.({method:"POST",path:t,requestId:o,phase:"parse",durationMs:Date.now()-r,status:l.status,error:c}),new nu({message:`Failed to parse JSON response from POST ${t}`,cause:c,method:"POST",path:t,url:i,requestId:o,phase:"parse",timeoutMs:dp,status:l.status,statusText:l.statusText,contentType:l.headers.get("content-type")??void 0,bodyPreview:await e3(u),timestamp:Date.now(),durationMs:Date.now()-r})}if(this.tracer.restResponse?.({method:"POST",path:t,requestId:o,status:l.status,durationMs:Date.now()-r,code:a.code,msg:a.msg,envelopeRequestId:a.request_id,data:a.data}),this.checkAuthRequired(l,a.code),a.code!==0){const c=a.code??l.status;throw new cc({code:c,msg:a.msg??l.statusText,requestId:a.request_id??o,details:a.details,timestamp:Date.now(),durationMs:Date.now()-r})}return a.data}async patch(t,n){return this.request("PATCH",t,n)}async put(t,n){return this.request("PUT",t,n)}async delete(t){return this.request("DELETE",t)}async request(t,n,i,o,s=[],r=dp){let l=$d(this.opts.origin,n,this.opts.restBasePath);if(o){const g=new URLSearchParams;mx(g,o);const m=g.toString();m&&(l=`${l}?${m}`)}const a=vm(),u={"X-Request-Id":a};this.addClientHeaders(u),i!==void 0&&(u["Content-Type"]="application/json; charset=utf-8");const c=Date.now();this.tracer.restRequest?.({method:t,path:n,url:l,requestId:a,body:i});let d;try{d=await fetch(l,{method:t,headers:u,body:i!==void 0?JSON.stringify(i):void 0,signal:mm(r)})}catch(g){throw this.tracer.restFailure?.({method:t,path:n,requestId:a,phase:"fetch",durationMs:Date.now()-c,error:g}),new nu({message:`Network error calling ${t} ${n}`,cause:g,method:t,path:n,url:l,requestId:a,phase:"fetch",timeoutMs:r,timestamp:Date.now(),durationMs:Date.now()-c})}let h;const p=d.clone();try{const g=await d.text();h=d.status===204&&g===""?{code:0,msg:"",data:null,request_id:a}:JSON.parse(g)}catch(g){throw this.tracer.restFailure?.({method:t,path:n,requestId:a,phase:"parse",durationMs:Date.now()-c,status:d.status,error:g}),new nu({message:`Failed to parse JSON response from ${t} ${n}`,cause:g,method:t,path:n,url:l,requestId:a,phase:"parse",timeoutMs:r,status:d.status,statusText:d.statusText,contentType:d.headers.get("content-type")??void 0,bodyPreview:await e3(p),timestamp:Date.now(),durationMs:Date.now()-c})}if(this.tracer.restResponse?.({method:t,path:n,requestId:a,status:d.status,durationMs:Date.now()-c,code:h.code,msg:h.msg,envelopeRequestId:h.request_id,data:h.data}),this.checkAuthRequired(d,h.code),h.code!==0&&!s.includes(h.code))throw new cc({code:typeof h.code=="number"?h.code:d.status,msg:typeof h.msg=="string"&&h.msg.length>0?h.msg:`HTTP ${d.status}${d.statusText?` ${d.statusText}`:""}`,requestId:h.request_id??a,details:h.details,timestamp:Date.now(),durationMs:Date.now()-c});return h.data}addClientHeaders(t){const n=this.opts.credentialStore?.getToken();n!==void 0&&(t.Authorization=`Bearer ${n}`);const i=this.opts.identity;i!==void 0&&(t["X-Kimi-Client-Id"]=i.clientId,t["X-Kimi-Client-Name"]=i.clientName,t["X-Kimi-Client-Version"]=i.clientVersion,t["X-Kimi-Client-Ui-Mode"]=i.clientUiMode)}checkAuthRequired(t,n){(t.status===401||n===iD)&&this.opts.credentialStore?.markAuthRequired?.()}}function oD(e){return{inputTokens:e.input_tokens,outputTokens:e.output_tokens,cacheReadTokens:e.cache_read_tokens,cacheCreationTokens:e.cache_creation_tokens,totalCostUsd:e.total_cost_usd,contextTokens:e.context_tokens,contextLimit:e.context_limit,turnCount:e.turn_count}}function v2(e){return e.contextTokens===0&&e.contextLimit===0&&e.inputTokens===0&&e.outputTokens===0&&e.turnCount===0}function WY(e,t,n){return{...t,model:t.model.length>0?t.model:e.model,usage:v2(t.usage)?e.usage:t.usage,updatedAt:!n&&t.updatedAt>e.updatedAt?t.updatedAt:e.updatedAt,pullRequest:t.pullRequest??e.pullRequest}}function Vl(e){return{id:e.id,title:e.title,createdAt:e.created_at,updatedAt:e.updated_at,busy:e.busy,mainTurnActive:e.main_turn_active,pendingInteraction:e.pending_interaction,lastTurnReason:e.last_turn_reason,archived:e.archived??!1,archivedAt:e.archived_at,currentPromptId:e.current_prompt_id,lastPrompt:e.last_prompt,cwd:e.metadata.cwd,model:e.agent_config.model,usage:oD(e.usage),messageCount:e.message_count,lastSeq:e.last_seq,workspaceId:e.workspace_id,parentSessionId:typeof e.metadata.parent_session_id=="string"?e.metadata.parent_session_id:void 0}}function ym(e){const t=e.activity.status;return{id:e.id,title:e.meta.title??e.meta.last_prompt??e.id.slice(0,12),createdAt:new Date(e.meta.created_at).toISOString(),updatedAt:new Date(e.meta.updated_at).toISOString(),busy:t==="running",pendingInteraction:t==="approval"?"approval":t==="question"?"question":void 0,lastTurnReason:t==="failed"?"failed":void 0,archived:e.meta.archived,archivedAt:e.meta.archived_at==null?void 0:new Date(e.meta.archived_at).toISOString(),lastPrompt:e.meta.last_prompt??void 0,cwd:e.workspace.cwd??"",model:"",pullRequest:e.git===void 0?void 0:e.git.pull_request,usage:{inputTokens:0,outputTokens:0,cacheReadTokens:0,cacheCreationTokens:0,totalCostUsd:0,contextTokens:0,contextLimit:0,turnCount:0},messageCount:0,lastSeq:0,workspaceId:e.workspace.id.length>0?e.workspace.id:void 0}}function $p(e){return{id:e.id,root:e.root,name:e.name,lastOpenedAt:e.last_opened_at,sessionCount:e.session_count}}function yx(e){return e.kind==="base64"?{kind:"base64",mediaType:e.media_type,data:e.data}:e.kind==="file"?{kind:"file",fileId:e.file_id}:e.kind==="session_media"?{kind:"sessionMedia",fileId:e.file_id}:{kind:"url",url:e.url}}function l6(e){switch(e.type){case"text":return{type:"text",text:e.text};case"tool_use":return{type:"toolUse",toolCallId:e.tool_call_id,toolName:e.tool_name,input:e.input};case"tool_result":return{type:"toolResult",toolCallId:e.tool_call_id,output:e.output,isError:e.is_error};case"image":return{type:"image",source:yx(e.source)};case"video":return{type:"video",source:yx(e.source)};case"file":return{type:"file",fileId:e.file_id,name:e.name,mediaType:e.media_type,size:e.size};case"thinking":return{type:"thinking",thinking:e.thinking,signature:e.signature};default:return{type:"unknown",raw:e}}}function xb(e){return{id:e.id,sessionId:e.session_id,role:e.role,content:e.content.map(l6),createdAt:e.created_at,promptId:e.prompt_id,parentMessageId:e.parent_message_id,metadata:e.metadata}}function sD(e){switch(e.type){case"text":return{type:"text",text:e.text};case"toolUse":return{type:"tool_use",tool_call_id:e.toolCallId,tool_name:e.toolName,input:e.input};case"toolResult":return{type:"tool_result",tool_call_id:e.toolCallId,output:e.output,is_error:e.isError};case"image":case"video":{const t=e.source;let n;return t.kind==="base64"?n={kind:"base64",media_type:t.mediaType,data:t.data}:t.kind==="file"?n={kind:"file",file_id:t.fileId}:t.kind==="sessionMedia"?n={kind:"session_media",file_id:t.fileId}:n={kind:"url",url:t.url},{type:e.type,source:n}}case"file":return{type:"file",file_id:e.fileId,name:e.name,media_type:e.mediaType,size:e.size};case"thinking":return{type:"thinking",thinking:e.thinking,signature:e.signature};case"unknown":return e.raw}}function qY(e){return{content:e.content.map(sD),metadata:e.metadata,agent_id:e.agentId,model:e.model,thinking:e.thinking,permission_mode:e.permissionMode,plan_mode:e.planMode,swarm_mode:e.swarmMode,goal_objective:e.goalObjective,goal_control:e.goalControl}}function UY(e){return{decision:e.decision,scope:e.scope,feedback:e.feedback,selected_label:e.selectedLabel}}function rD(e){return{approvalId:e.approval_id,sessionId:e.session_id,turnId:e.turn_id,toolCallId:e.tool_call_id,toolName:e.tool_name,action:e.action,display:e.tool_input_display??e.display,expiresAt:e.expires_at,createdAt:e.created_at}}function KY(e){return{id:e.id,label:e.label,description:e.description,recommended:e.recommended===!0||e.is_recommended===!0}}function VY(e){return{id:e.id,question:e.question,header:e.header,body:e.body,options:e.options.map(KY),multiSelect:e.multi_select,allowOther:e.allow_other,otherLabel:e.other_label,otherDescription:e.other_description}}function lD(e){return{questionId:e.question_id,sessionId:e.session_id,turnId:e.turn_id,toolCallId:e.tool_call_id,questions:e.questions.map(VY),createdAt:e.created_at}}function ZY(e){switch(e.kind){case"single":return{kind:"single",option_id:e.optionId};case"multi":return{kind:"multi",option_ids:e.optionIds};case"other":return{kind:"other",text:e.text};case"multiWithOther":return{kind:"multi_with_other",option_ids:e.optionIds,other_text:e.otherText};case"skipped":return{kind:"skipped"}}}function GY(e){const t={};for(const[n,i]of Object.entries(e.answers))t[n]=ZY(i);return{answers:t,method:e.method,note:e.note}}function yv(e,t){return{id:e.id,agentId:e.agent_id??t,sessionId:e.session_id,kind:e.kind,description:e.description,status:e.status,command:e.command,createdAt:e.created_at,startedAt:e.started_at,completedAt:e.completed_at,outputPreview:e.output_preview,outputBytes:e.output_bytes,subagentPhase:e.subagent_phase,subagentType:e.subagent_type,model:e.model,thinkingEffort:e.thinking_effort,parentToolCallId:e.parent_tool_call_id,suspendedReason:e.suspended_reason,swarmIndex:e.swarm_index,runInBackground:e.run_in_background??(e.kind==="subagent"?!0:void 0)}}function kx(e){return{path:e.path,name:e.name,kind:e.kind,size:e.size,modifiedAt:e.modified_at,etag:e.etag,mime:e.mime,languageId:e.language_id,isBinary:e.is_binary,isSymlinkTo:e.is_symlink_to,gitStatus:e.git_status,childCount:e.child_count}}function Wu(e,t){const n=e[t];return typeof n=="string"?n:void 0}function qf(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:void 0}function wl(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null}function aD(e){if(!e||typeof e!="object")return null;const t=e,n=Wu(t,"status");if(n!=="active"&&n!=="paused"&&n!=="blocked"&&n!=="complete")return null;const i=t.budget,o=i&&typeof i=="object"?i:{};return{goalId:Wu(t,"goalId")??Wu(t,"goal_id")??"goal",objective:Wu(t,"objective")??"",completionCriterion:Wu(t,"completionCriterion")??Wu(t,"completion_criterion"),status:n,turnsUsed:qf(t,"turnsUsed")??qf(t,"turns_used")??0,tokensUsed:qf(t,"tokensUsed")??qf(t,"tokens_used")??0,wallClockMs:qf(t,"wallClockMs")??qf(t,"wall_clock_ms")??0,terminalReason:Wu(t,"terminalReason")??Wu(t,"terminal_reason"),budget:{tokenBudget:wl(o,"tokenBudget")??wl(o,"token_budget"),remainingTokens:wl(o,"remainingTokens")??wl(o,"remaining_tokens"),turnBudget:wl(o,"turnBudget")??wl(o,"turn_budget"),remainingTurns:wl(o,"remainingTurns")??wl(o,"remaining_turns"),wallClockBudgetMs:wl(o,"wallClockBudgetMs")??wl(o,"wall_clock_budget_ms"),remainingWallClockMs:wl(o,"remainingWallClockMs")??wl(o,"remaining_wall_clock_ms"),overBudget:o.overBudget===!0||o.over_budget===!0}}}function QY(e){const t=e;switch(e.type){case"event.session.created":return{type:"sessionCreated",session:Vl(t.payload.session)};case"event.session.updated":return{type:"sessionUpdated",session:Vl(t.payload.session),changedFields:t.payload.changed_fields};case"event.session.deleted":return{type:"sessionDeleted",sessionId:t.session_id};case"event.session.archived":{const n=t.payload?.sessionId??t.payload?.session_id;if(typeof n!="string"||n.length===0)return{type:"unknown",raw:{_noop:!0,_wireType:t.type}};const i=t.payload?.workspace_id;return{type:"sessionArchived",sessionId:n,workspaceId:typeof i=="string"&&i.length>0?i:void 0}}case"event.workspace.created":return{type:"workspaceCreated",workspace:$p(t.payload.workspace)};case"event.workspace.updated":return{type:"workspaceUpdated",workspace:$p(t.payload.workspace)};case"event.workspace.deleted":return{type:"workspaceDeleted",workspaceId:t.payload.workspace_id,root:t.payload.root};case"event.session.work_changed":return{type:"sessionWorkChanged",sessionId:t.session_id,busy:t.payload.busy,mainTurnActive:t.payload.main_turn_active,pendingInteraction:t.payload.pending_interaction,lastTurnReason:t.payload.last_turn_reason};case"event.session.status_changed":return{type:"sessionWorkChanged",sessionId:t.session_id,busy:t.payload.status!=="idle"&&t.payload.status!=="aborted",mainTurnActive:t.payload.status!=="idle"&&t.payload.status!=="aborted",pendingInteraction:t.payload.status==="awaiting_approval"?"approval":t.payload.status==="awaiting_question"?"question":"none",lastTurnReason:t.payload.status==="aborted"?"cancelled":void 0};case"event.session.usage_updated":return{type:"sessionUsageUpdated",sessionId:t.session_id,usage:oD(t.payload.usage)};case"event.session.history_compacted":return{type:"historyCompacted",sessionId:t.session_id,beforeSeq:t.payload.before_seq,reason:t.payload.reason,summaryMessageId:t.payload.summary_message_id};case"event.goal.updated":{const n=aD(t.payload.snapshot??null);return{type:"goalUpdated",sessionId:t.session_id,goal:n?.status==="complete"?null:n}}case"event.message.created":return{type:"messageCreated",message:xb(t.payload.message)};case"event.message.updated":return{type:"messageUpdated",sessionId:t.session_id,messageId:t.payload.message_id,content:t.payload.content.map(l6),status:t.payload.status};case"event.assistant.delta":return{type:"assistantDelta",sessionId:t.session_id,messageId:t.payload.message_id,contentIndex:t.payload.content_index,delta:t.payload.delta};case"event.assistant.tool_use_started":case"event.assistant.tool_use_delta":case"event.assistant.tool_use_completed":case"event.assistant.completed":case"event.tool.started":return{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.tool.output":return{type:"toolOutput",sessionId:t.session_id,toolCallId:t.payload.tool_call_id,outputChunk:t.payload.chunk,stream:t.payload.stream};case"event.tool.progress":return typeof t.payload.message=="string"&&t.payload.message.length>0?{type:"toolOutput",sessionId:t.session_id,toolCallId:t.payload.tool_call_id,outputChunk:t.payload.message,stream:"stdout"}:{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.tool.completed":return{type:"unknown",raw:{_noop:!0,_wireType:t.type}};case"event.approval.requested":return{type:"approvalRequested",sessionId:t.session_id,approval:rD(t.payload)};case"event.approval.resolved":return{type:"approvalResolved",sessionId:t.session_id,approvalId:t.payload.approval_id,decision:t.payload.decision,resolvedAt:t.payload.resolved_at,feedback:t.payload.feedback,selectedLabel:t.payload.selected_label};case"event.approval.expired":return{type:"approvalExpired",sessionId:t.session_id,approvalId:t.payload.approval_id};case"event.question.requested":return{type:"questionRequested",sessionId:t.session_id,question:lD(t.payload)};case"event.question.answered":return{type:"questionAnswered",sessionId:t.session_id,questionId:t.payload.question_id,resolvedAt:t.payload.resolved_at};case"event.question.dismissed":return{type:"questionDismissed",sessionId:t.session_id,questionId:t.payload.question_id,dismissedAt:t.payload.dismissed_at};case"event.task.created":return{type:"taskCreated",sessionId:t.session_id,task:yv(t.payload.task)};case"event.task.progress":return{type:"taskProgress",sessionId:t.session_id,taskId:t.payload.task_id,outputChunk:t.payload.output_chunk,stream:t.payload.stream};case"event.task.completed":return{type:"taskCompleted",sessionId:t.session_id,taskId:t.payload.task_id,status:t.payload.status,outputPreview:t.payload.output_preview,outputBytes:t.payload.output_bytes};case"event.plugin.changed":return{type:"pluginsChanged"};case"event.capability.changed":return{type:"capabilityChanged",capabilityId:t.payload.capability_id,install:t.payload.install};case"event.config.changed":return{type:"configChanged",changedFields:t.payload.changed_fields,config:Sb(t.payload.config)};case"event.model_catalog.changed":return{type:"modelCatalogChanged",changed:t.payload.changed.map(n=>({providerId:n.provider_id,providerName:n.provider_name,added:n.added,removed:n.removed})),unchanged:t.payload.unchanged,failed:t.payload.failed};default:return{type:"unknown",raw:e}}}function YY(e){return{id:e.model,provider:e.provider,model:e.model,displayName:e.display_name,maxContextSize:e.max_context_size,capabilities:e.capabilities,supportEfforts:e.support_efforts,defaultEffort:e.default_effort}}function Uf(e){return{id:e.id,type:e.type,baseUrl:e.base_url,defaultModel:e.default_model,hasApiKey:e.has_api_key,status:e.status,models:e.models}}function bx(e){return{id:e.id,name:e.name,wireType:e.wire_type,guessed:e.guessed,needsBaseUrl:e.needs_base_url,rejected:e.rejected,rejectReason:e.reject_reason,envKey:e.env_key,models:e.models.map(t=>({id:t.id,name:t.name,maxContextSize:t.max_context_size,capabilities:t.capabilities,reasoning:t.reasoning}))}}function Sb(e){const t={};for(const[n,i]of Object.entries(e.providers))t[n]={type:i.type,baseUrl:i.base_url,defaultModel:i.default_model,hasApiKey:i.has_api_key};return{providers:t,defaultProvider:e.default_provider,defaultModel:e.default_model,secondaryModel:e.secondary_model,models:e.models,thinking:e.thinking,planMode:e.plan_mode,yolo:e.yolo,defaultPermissionMode:e.default_permission_mode,defaultPlanMode:e.default_plan_mode,permission:e.permission,hooks:e.hooks,services:e.services,mergeAllAvailableSkills:e.merge_all_available_skills,extraSkillDirs:e.extra_skill_dirs,loopControl:e.loop_control,background:e.background,experimental:e.experimental,telemetry:e.telemetry,raw:e.raw}}function JY(e){return e.session_id}function XY(e){return e.seq}function eJ(e){const t=Number(e.slice(1));return Number.isFinite(t)?t:0}const tJ={items:[],tasks:new Map,interactions:new Map,attachments:new Map,todos:new Map,prompts:new Map,meta:{},pendingInteractions:new Set,hasMoreOlder:!1};function nJ(e,t){switch(t.op){case"reset":return iJ(e,t);case"turn.upsert":return sJ(e,t.turn);case"step.upsert":return lJ(e,t.turnId,t.step);case"frame.upsert":return uJ(e,t);case"append":return dJ(e,t);case"marker.upsert":return Cx(e,t.item,t.item.markerId,t.beforeTurn);case"taskref.upsert":return Cx(e,t.item,t.item.refId,t.beforeTurn);case"task.upsert":return pJ(e,t.task);case"interaction.upsert":return gJ(e,t.interaction);case"attachment.upsert":return vJ(e,t.attachment);case"todo.upsert":return kJ(e,t.todo);case"prompt.upsert":return AJ(e,t.prompt);case"meta.merge":return xJ(e,t.meta);case"items.remove":return hJ(e,t.ids)}}function iJ(e,t){const n=new Set;for(const i of t.snapshot.interactions)i.state==="pending"&&n.add(i.interactionId);return{state:{items:t.snapshot.items,tasks:new Map(t.snapshot.tasks.map(i=>[i.taskId,i])),interactions:new Map(t.snapshot.interactions.map(i=>[i.interactionId,i])),attachments:new Map(t.snapshot.attachments.map(i=>[i.attachmentId,i])),todos:new Map(t.snapshot.todos.map(i=>[i.todoId,i])),prompts:new Map(t.snapshot.prompts.map(i=>[i.promptId,i])),meta:t.snapshot.meta,pendingInteractions:n,hasMoreOlder:t.snapshot.hasMoreOlder??!1},changed:!0}}function Ax(e,t){return{...e,kind:"turn",steps:[...t]}}function uD(e){return{kind:"turn",turnId:e,ordinal:eJ(e),state:"running",origin:{kind:"other"},steps:[]}}function oJ(e,t){const n=Number(e.slice(t.length+1))||0;return{kind:"step",stepId:e,turnId:t,ordinal:n,state:"running",frames:[]}}function Qh(e,t){const n=e.items.find(i=>i.kind==="turn"&&i.turnId===t);return n?.kind==="turn"?n:void 0}function a6(e,t){const n=[...e];let i=n.length;for(let o=0;o<n.length;o+=1){const s=n[o];if(s?.kind==="turn"&&s.ordinal>t.ordinal){i=o;break}}return n.splice(i,0,t),n}function n9(e,t,n){return e.map(i=>i.kind==="turn"&&i.turnId===t?n(i):i)}function sJ(e,t){const n=Qh(e,t.turnId);return n?rJ(n,t)?{state:e,changed:!1}:{state:{...e,items:n9(e.items,t.turnId,i=>Ax(t,i.steps))},changed:!0}:{state:{...e,items:a6(e.items,Ax(t,[]))},changed:!0}}function rJ(e,t){return e.ordinal===t.ordinal&&e.state===t.state&&e.prompt===t.prompt&&e.attachmentIds===t.attachmentIds&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.origin.kind===t.origin.kind&&e.origin.payload===t.origin.payload&&e.usage===t.usage&&e.durationMs===t.durationMs&&e.error===t.error}function lJ(e,t,n){const i=Qh(e,t)??uD(t),o=i.steps.findIndex(u=>u.stepId===n.stepId);let s,r=!0;if(o>=0){const u=i.steps[o];u&&aJ(u,n)?(r=!1,s=i.steps):s=i.steps.map(c=>c.stepId===n.stepId?{...n,kind:"step",frames:c.frames}:c)}else s=[...i.steps,{...n,kind:"step",frames:[]}].toSorted((u,c)=>u.ordinal-c.ordinal);if(!r)return{state:e,changed:!1};const l={...i,steps:[...s]},a=Qh(e,t)?n9(e.items,t,()=>l):a6(e.items,l);return{state:{...e,items:a},changed:!0}}function aJ(e,t){return e.ordinal===t.ordinal&&e.state===t.state&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.usage===t.usage&&e.finishReason===t.finishReason&&e.timing===t.timing&&e.retry===t.retry&&e.endReason===t.endReason&&e.endMessage===t.endMessage}function uJ(e,t){const n=Qh(e,t.turnId)??uD(t.turnId),i=n.steps.find(c=>c.stepId===t.stepId)??oJ(t.stepId,t.turnId),o=i.frames.findIndex(c=>c.frameId===t.frame.frameId);let s;if(o>=0){const c=i.frames[o];if(c!==void 0&&cJ(c,t.frame))return{state:e,changed:!1};s=i.frames.map(d=>d.frameId===t.frame.frameId?t.frame:d)}else s=[...i.frames,t.frame];const r={...i,frames:[...s]},l=n.steps.some(c=>c.stepId===t.stepId)?n.steps.map(c=>c.stepId===t.stepId?r:c):[...n.steps,r].toSorted((c,d)=>c.ordinal-d.ordinal),a={...n,steps:l},u=Qh(e,t.turnId)?n9(e.items,t.turnId,()=>a):a6(e.items,a);return{state:{...e,items:u},changed:!0}}function cJ(e,t){return e.kind!==t.kind?!1:e.kind==="text"&&t.kind==="text"?e.text===t.text&&e.role===t.role&&e.attachmentIds===t.attachmentIds&&e.taskId===t.taskId:e.kind==="thinking"&&t.kind==="thinking"?e.text===t.text:e.kind==="tool"&&t.kind==="tool"?e.state===t.state&&e.toolCallId===t.toolCallId&&e.name===t.name&&e.view===t.view&&e.input===t.input&&e.output===t.output&&e.display===t.display&&e.error===t.error&&e.inputText===t.inputText&&e.progress===t.progress&&e.taskId===t.taskId&&e.approvalId===t.approvalId&&e.todoId===t.todoId&&e.agentRefs===t.agentRefs:e.kind==="notice"&&t.kind==="notice"?e.message===t.message&&e.level===t.level&&e.detail===t.detail:!1}function dJ(e,t){if(t.target.type==="task")return fJ(e,t);const{turnId:n,stepId:i,frameId:o}=t.target,s=Qh(e,n),r=s?.steps.find(h=>h.stepId===i),l=r?.frames.find(h=>h.frameId===o);if(!s||!r||!l||l.kind!=="text"&&l.kind!=="thinking")return{state:e,changed:!1,gap:{expected:0,got:t.offset}};const a=cD(l.text,t.offset,t.text);if(a.gap)return{state:e,changed:!1,gap:a.gap};if(!a.changed)return{state:e,changed:!1};const u={...l,text:a.text},c={...r,frames:r.frames.map(h=>h.frameId===o?u:h)},d={...s,steps:s.steps.map(h=>h.stepId===i?c:h)};return{state:{...e,items:n9(e.items,n,()=>d)},changed:!0}}function fJ(e,t){if(t.target.type!=="task")throw new Error("unreachable");const n=t.target.taskId,i=e.tasks.get(n),o=i?.outputTail??"",s=cD(o,t.offset,t.text);if(s.gap)return{state:e,changed:!1,gap:s.gap};if(!s.changed)return{state:e,changed:!1};const r=i?{...i,outputTail:s.text}:{taskId:n,kind:"other",state:"running",detached:!1,outputTail:s.text},l=new Map(e.tasks);return l.set(n,r),{state:{...e,tasks:l},changed:!0}}function cD(e,t,n){if(t>e.length)return{text:e,changed:!1,gap:{expected:e.length,got:t}};if(e.slice(t,t+n.length)===n)return{text:e,changed:!1};const i=e.length-t;return e.slice(t)!==n.slice(0,i)?{text:e,changed:!1,gap:{expected:e.length,got:t}}:(i>0?n.slice(i):n).length===0?{text:e,changed:!1}:{text:e.slice(0,t)+n,changed:!0}}function Cx(e,t,n,i){if(e.items.some(s=>_b(s)===n)){let s=!1;const r=e.items.map(l=>_b(l)!==n||l===t?l:(s=!0,t));return s?{state:{...e,items:r},changed:!0}:{state:e,changed:!1}}if(i!==void 0){const s=[...e.items];let r=s.length;for(let l=0;l<s.length;l+=1){const a=s[l];if(a?.kind==="turn"&&a.ordinal>=i){r=l;break}}return s.splice(r,0,t),{state:{...e,items:s},changed:!0}}return{state:{...e,items:[...e.items,t]},changed:!0}}function _b(e){switch(e.kind){case"turn":return e.turnId;case"marker":return e.markerId;case"taskref":return e.refId}}function hJ(e,t){const n=new Set(t),i=e.items.filter(l=>l.kind==="turn"&&n.has(l.turnId)),o=e.items.filter(l=>!n.has(_b(l)));if(o.length===e.items.length)return{state:e,changed:!1};let s=e.pendingInteractions,r=e.interactions;if(i.length>0){const l=new Set,a=new Set(s),u=new Set;for(const c of i)for(const d of c.steps)for(const h of d.frames)h.kind==="tool"&&l.add(h.toolCallId);for(const c of r.values())c.toolCallId!==void 0&&l.has(c.toolCallId)&&(u.add(c.interactionId),a.delete(c.interactionId));if(u.size>0){const c=new Map(r);for(const d of u)c.delete(d);r=c}s=a}return{state:{...e,items:o,interactions:r,pendingInteractions:s},changed:!0}}function pJ(e,t){const n=e.tasks.get(t.taskId);if(n&&wJ(n,t))return{state:e,changed:!1};const i=new Map(e.tasks);return i.set(t.taskId,t),{state:{...e,tasks:i},changed:!0}}function gJ(e,t){const n=e.interactions.get(t.interactionId);if(n&&mJ(n,t))return{state:e,changed:!1};const i=new Map(e.interactions);i.set(t.interactionId,t);let o=e.pendingInteractions;if(t.state==="pending"){if(!o.has(t.interactionId)){const s=new Set(o);s.add(t.interactionId),o=s}}else if(o.has(t.interactionId)){const s=new Set(o);s.delete(t.interactionId),o=s}return{state:{...e,interactions:i,pendingInteractions:o},changed:!0}}function mJ(e,t){return e.interactionKind===t.interactionKind&&e.toolCallId===t.toolCallId&&e.state===t.state&&e.request===t.request&&e.response===t.response}function vJ(e,t){const n=e.attachments.get(t.attachmentId);if(n&&yJ(n,t))return{state:e,changed:!1};const i=new Map(e.attachments);return i.set(t.attachmentId,t),{state:{...e,attachments:i},changed:!0}}function yJ(e,t){return e.mediaType===t.mediaType&&e.name===t.name&&e.size===t.size&&e.source===t.source&&e.placeholder===t.placeholder}function kJ(e,t){const n=e.todos.get(t.todoId);if(n&&bJ(n,t))return{state:e,changed:!1};const i=new Map(e.todos);return i.set(t.todoId,t),{state:{...e,todos:i},changed:!0}}function bJ(e,t){return e.items===t.items&&e.updatedAt===t.updatedAt}function AJ(e,t){const n=e.prompts.get(t.promptId);if(n&&CJ(n,t))return{state:e,changed:!1};const i=new Map(e.prompts);return i.set(t.promptId,t),{state:{...e,prompts:i},changed:!0}}function CJ(e,t){return e.status===t.status&&e.userMessageId===t.userMessageId&&e.content===t.content&&e.createdAt===t.createdAt&&e.finishedAt===t.finishedAt&&e.steeredAt===t.steeredAt}function wJ(e,t){return e.kind===t.kind&&e.state===t.state&&e.detached===t.detached&&e.description===t.description&&e.agentId===t.agentId&&e.outputTail===t.outputTail&&e.startedAt===t.startedAt&&e.endedAt===t.endedAt&&e.resultSummary===t.resultSummary&&e.error===t.error&&e.stateReason===t.stateReason&&e.usage===t.usage}function xJ(e,t){const n=t.modes!==void 0?{plan:t.modes.plan===null?void 0:t.modes.plan??e.meta.modes?.plan,swarm:t.modes.swarm===null?void 0:t.modes.swarm??e.meta.modes?.swarm,tower:t.modes.tower===null?void 0:t.modes.tower??e.meta.modes?.tower}:e.meta.modes,i=t.agent!==void 0?{...e.meta.agent,...t.agent}:e.meta.agent,o={goal:t.goal===null?void 0:t.goal??e.meta.goal,activity:t.activity??e.meta.activity,modes:n!==void 0&&n.plan===void 0&&n.swarm===void 0&&n.tower===void 0?void 0:n,agent:i};return o.goal===e.meta.goal&&o.activity===e.meta.activity&&o.modes===e.meta.modes&&o.agent===e.meta.agent?{state:e,changed:!1}:{state:{...e,meta:o},changed:!0}}class SJ{constructor(t){this.agentId=t}#e=tJ;#t=new Set;receive(t){return this.apply(t)}apply(t){const n=[];let i,o=this.#e;for(const s of t){const r=nJ(o,s);if(r.gap){i={target:s.target,...r.gap};continue}r.changed&&(o=r.state,n.push(s))}if(this.#e=o,n.length>0){const s={agentId:this.agentId,ops:n};for(const r of this.#t)r(s)}return{accepted:n,gap:i}}onChange(t){return this.#t.add(t),{dispose:()=>void this.#t.delete(t)}}getItems(){return this.#e.items}getTurn(t){const n=this.#e.items.find(i=>i.kind==="turn"&&i.turnId===t);return n?.kind==="turn"?n:void 0}getTasks(){return this.#e.tasks}getTask(t){return this.#e.tasks.get(t)}getInteractions(){return this.#e.interactions}getInteraction(t){return this.#e.interactions.get(t)}getAttachments(){return this.#e.attachments}getAttachment(t){return this.#e.attachments.get(t)}getTodos(){return this.#e.todos}getTodo(t){return this.#e.todos.get(t)}getPrompts(){return this.#e.prompts}getPrompt(t){return this.#e.prompts.get(t)}getMeta(){return this.#e.meta}listPendingInteractions(){return[...this.#e.pendingInteractions]}get hasMoreOlder(){return this.#e.hasMoreOlder}snapshot(t){let n=this.#e.items,i=this.#e.hasMoreOlder;if(t!==void 0){const o=n.reduce((s,r)=>r.kind==="turn"?s+1:s,0);if(o>t.tailTurns){const s=o-t.tailTurns,r=[];let l=0;for(const a of n)if(a.kind==="turn"){if(l+=1,l<=s)continue;r.push(a)}else l>s&&r.push(a);n=r,i=!0}}return{items:n,tasks:[...this.#e.tasks.values()],interactions:[...this.#e.interactions.values()],attachments:[...this.#e.attachments.values()],todos:[...this.#e.todos.values()],prompts:[...this.#e.prompts.values()],meta:this.#e.meta,hasMoreOlder:i}}}function bt(e,t,n){function i(l,a){if(l._zod||Object.defineProperty(l,"_zod",{value:{def:a,constr:r,traits:new Set},enumerable:!1}),l._zod.traits.has(e))return;l._zod.traits.add(e),t(l,a);const u=r.prototype,c=Object.keys(u);for(let d=0;d<c.length;d++){const h=c[d];h in l||(l[h]=u[h].bind(l))}}const o=n?.Parent??Object;class s extends o{}Object.defineProperty(s,"name",{value:e});function r(l){var a;const u=n?.Parent?new s:this;i(u,l),(a=u._zod).deferred??(a.deferred=[]);for(const c of u._zod.deferred)c();return u}return Object.defineProperty(r,"init",{value:i}),Object.defineProperty(r,Symbol.hasInstance,{value:l=>n?.Parent&&l instanceof n.Parent?!0:l?._zod?.traits?.has(e)}),Object.defineProperty(r,"name",{value:e}),r}class Th extends Error{constructor(){super("Encountered Promise during synchronous parse. Use .parseAsync() instead.")}}class dD extends Error{constructor(t){super(`Encountered unidirectional transform during encode: ${t}`),this.name="ZodEncodeError"}}const fD={};function xc(e){return fD}function hD(e){const t=Object.values(e).filter(i=>typeof i=="number");return Object.entries(e).filter(([i,o])=>t.indexOf(+i)===-1).map(([i,o])=>o)}function Mb(e,t){return typeof t=="bigint"?t.toString():t}function i9(e){return{get value(){{const t=e();return Object.defineProperty(this,"value",{value:t}),t}}}}function u6(e){return e==null}function c6(e){const t=e.startsWith("^")?1:0,n=e.endsWith("$")?e.length-1:e.length;return e.slice(t,n)}function _J(e,t){const n=(e.toString().split(".")[1]||"").length,i=t.toString();let o=(i.split(".")[1]||"").length;if(o===0&&/\d?e-\d?/.test(i)){const a=i.match(/\d?e-(\d?)/);a?.[1]&&(o=Number.parseInt(a[1]))}const s=n>o?n:o,r=Number.parseInt(e.toFixed(s).replace(".","")),l=Number.parseInt(t.toFixed(s).replace(".",""));return r%l/10**s}const wx=Symbol("evaluating");function Si(e,t,n){let i;Object.defineProperty(e,t,{get(){if(i!==wx)return i===void 0&&(i=wx,i=n()),i},set(o){Object.defineProperty(e,t,{value:o})},configurable:!0})}function kf(e,t,n){Object.defineProperty(e,t,{value:n,writable:!0,enumerable:!0,configurable:!0})}function jc(...e){const t={};for(const n of e){const i=Object.getOwnPropertyDescriptors(n);Object.assign(t,i)}return Object.defineProperties({},t)}function xx(e){return JSON.stringify(e)}function MJ(e){return e.toLowerCase().trim().replace(/[^\w\s-]/g,"").replace(/[\s_-]+/g,"-").replace(/^-+|-+$/g,"")}const pD="captureStackTrace"in Error?Error.captureStackTrace:(...e)=>{};function x0(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}const IJ=i9(()=>{if(typeof navigator<"u"&&navigator?.userAgent?.includes("Cloudflare"))return!1;try{const e=Function;return new e(""),!0}catch{return!1}});function Yh(e){if(x0(e)===!1)return!1;const t=e.constructor;if(t===void 0||typeof t!="function")return!0;const n=t.prototype;return!(x0(n)===!1||Object.prototype.hasOwnProperty.call(n,"isPrototypeOf")===!1)}function gD(e){return Yh(e)?{...e}:Array.isArray(e)?[...e]:e}const EJ=new Set(["string","number","symbol"]);function Jh(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Hc(e,t,n){const i=new e._zod.constr(t??e._zod.def);return(!t||n?.parent)&&(i._zod.parent=e),i}function pn(e){const t=e;if(!t)return{};if(typeof t=="string")return{error:()=>t};if(t?.message!==void 0){if(t?.error!==void 0)throw new Error("Cannot specify both `message` and `error` params");t.error=t.message}return delete t.message,typeof t.error=="string"?{...t,error:()=>t.error}:t}function TJ(e){return Object.keys(e).filter(t=>e[t]._zod.optin==="optional"&&e[t]._zod.optout==="optional")}const LJ={safeint:[Number.MIN_SAFE_INTEGER,Number.MAX_SAFE_INTEGER],int32:[-2147483648,2147483647],uint32:[0,4294967295],float32:[-34028234663852886e22,34028234663852886e22],float64:[-Number.MAX_VALUE,Number.MAX_VALUE]};function NJ(e,t){const n=e._zod.def,i=n.checks;if(i&&i.length>0)throw new Error(".pick() cannot be used on object schemas containing refinements");const s=jc(e._zod.def,{get shape(){const r={};for(const l in t){if(!(l in n.shape))throw new Error(`Unrecognized key: "${l}"`);t[l]&&(r[l]=n.shape[l])}return kf(this,"shape",r),r},checks:[]});return Hc(e,s)}function FJ(e,t){const n=e._zod.def,i=n.checks;if(i&&i.length>0)throw new Error(".omit() cannot be used on object schemas containing refinements");const s=jc(e._zod.def,{get shape(){const r={...e._zod.def.shape};for(const l in t){if(!(l in n.shape))throw new Error(`Unrecognized key: "${l}"`);t[l]&&delete r[l]}return kf(this,"shape",r),r},checks:[]});return Hc(e,s)}function DJ(e,t){if(!Yh(t))throw new Error("Invalid input to extend: expected a plain object");const n=e._zod.def.checks;if(n&&n.length>0){const s=e._zod.def.shape;for(const r in t)if(Object.getOwnPropertyDescriptor(s,r)!==void 0)throw new Error("Cannot overwrite keys on object schemas containing refinements. Use `.safeExtend()` instead.")}const o=jc(e._zod.def,{get shape(){const s={...e._zod.def.shape,...t};return kf(this,"shape",s),s}});return Hc(e,o)}function BJ(e,t){if(!Yh(t))throw new Error("Invalid input to safeExtend: expected a plain object");const n=jc(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t};return kf(this,"shape",i),i}});return Hc(e,n)}function $J(e,t){const n=jc(e._zod.def,{get shape(){const i={...e._zod.def.shape,...t._zod.def.shape};return kf(this,"shape",i),i},get catchall(){return t._zod.def.catchall},checks:[]});return Hc(e,n)}function RJ(e,t,n){const o=t._zod.def.checks;if(o&&o.length>0)throw new Error(".partial() cannot be used on object schemas containing refinements");const r=jc(t._zod.def,{get shape(){const l=t._zod.def.shape,a={...l};if(n)for(const u in n){if(!(u in l))throw new Error(`Unrecognized key: "${u}"`);n[u]&&(a[u]=e?new e({type:"optional",innerType:l[u]}):l[u])}else for(const u in l)a[u]=e?new e({type:"optional",innerType:l[u]}):l[u];return kf(this,"shape",a),a},checks:[]});return Hc(t,r)}function zJ(e,t,n){const i=jc(t._zod.def,{get shape(){const o=t._zod.def.shape,s={...o};if(n)for(const r in n){if(!(r in s))throw new Error(`Unrecognized key: "${r}"`);n[r]&&(s[r]=new e({type:"nonoptional",innerType:o[r]}))}else for(const r in o)s[r]=new e({type:"nonoptional",innerType:o[r]});return kf(this,"shape",s),s}});return Hc(t,i)}function ph(e,t=0){if(e.aborted===!0)return!0;for(let n=t;n<e.issues.length;n++)if(e.issues[n]?.continue!==!0)return!0;return!1}function gh(e,t){return t.map(n=>{var i;return(i=n).path??(i.path=[]),n.path.unshift(e),n})}function km(e){return typeof e=="string"?e:e?.message}function Sc(e,t,n){const i={...e,path:e.path??[]};if(!e.message){const o=km(e.inst?._zod.def?.error?.(e))??km(t?.error?.(e))??km(n.customError?.(e))??km(n.localeError?.(e))??"Invalid input";i.message=o}return delete i.inst,delete i.continue,t?.reportInput||delete i.input,i}function d6(e){return Array.isArray(e)?"array":typeof e=="string"?"string":"unknown"}function S0(...e){const[t,n,i]=e;return typeof t=="string"?{message:t,code:"custom",input:n,inst:i}:{...t}}const mD=(e,t)=>{e.name="$ZodError",Object.defineProperty(e,"_zod",{value:e._zod,enumerable:!1}),Object.defineProperty(e,"issues",{value:t,enumerable:!1}),e.message=JSON.stringify(t,Mb,2),Object.defineProperty(e,"toString",{value:()=>e.message,enumerable:!1})},vD=bt("$ZodError",mD),yD=bt("$ZodError",mD,{Parent:Error});function OJ(e,t=n=>n.message){const n={},i=[];for(const o of e.issues)o.path.length>0?(n[o.path[0]]=n[o.path[0]]||[],n[o.path[0]].push(t(o))):i.push(t(o));return{formErrors:i,fieldErrors:n}}function PJ(e,t=n=>n.message){const n={_errors:[]},i=o=>{for(const s of o.issues)if(s.code==="invalid_union"&&s.errors.length)s.errors.map(r=>i({issues:r}));else if(s.code==="invalid_key")i({issues:s.issues});else if(s.code==="invalid_element")i({issues:s.issues});else if(s.path.length===0)n._errors.push(t(s));else{let r=n,l=0;for(;l<s.path.length;){const a=s.path[l];l===s.path.length-1?(r[a]=r[a]||{_errors:[]},r[a]._errors.push(t(s))):r[a]=r[a]||{_errors:[]},r=r[a],l++}}};return i(e),n}const f6=e=>(t,n,i,o)=>{const s=i?Object.assign(i,{async:!1}):{async:!1},r=t._zod.run({value:n,issues:[]},s);if(r instanceof Promise)throw new Th;if(r.issues.length){const l=new(o?.Err??e)(r.issues.map(a=>Sc(a,s,xc())));throw pD(l,o?.callee),l}return r.value},h6=e=>async(t,n,i,o)=>{const s=i?Object.assign(i,{async:!0}):{async:!0};let r=t._zod.run({value:n,issues:[]},s);if(r instanceof Promise&&(r=await r),r.issues.length){const l=new(o?.Err??e)(r.issues.map(a=>Sc(a,s,xc())));throw pD(l,o?.callee),l}return r.value},o9=e=>(t,n,i)=>{const o=i?{...i,async:!1}:{async:!1},s=t._zod.run({value:n,issues:[]},o);if(s instanceof Promise)throw new Th;return s.issues.length?{success:!1,error:new(e??vD)(s.issues.map(r=>Sc(r,o,xc())))}:{success:!0,data:s.value}},jJ=o9(yD),s9=e=>async(t,n,i)=>{const o=i?Object.assign(i,{async:!0}):{async:!0};let s=t._zod.run({value:n,issues:[]},o);return s instanceof Promise&&(s=await s),s.issues.length?{success:!1,error:new e(s.issues.map(r=>Sc(r,o,xc())))}:{success:!0,data:s.value}},HJ=s9(yD),WJ=e=>(t,n,i)=>{const o=i?Object.assign(i,{direction:"backward"}):{direction:"backward"};return f6(e)(t,n,o)},qJ=e=>(t,n,i)=>f6(e)(t,n,i),UJ=e=>async(t,n,i)=>{const o=i?Object.assign(i,{direction:"backward"}):{direction:"backward"};return h6(e)(t,n,o)},KJ=e=>async(t,n,i)=>h6(e)(t,n,i),VJ=e=>(t,n,i)=>{const o=i?Object.assign(i,{direction:"backward"}):{direction:"backward"};return o9(e)(t,n,o)},ZJ=e=>(t,n,i)=>o9(e)(t,n,i),GJ=e=>async(t,n,i)=>{const o=i?Object.assign(i,{direction:"backward"}):{direction:"backward"};return s9(e)(t,n,o)},QJ=e=>async(t,n,i)=>s9(e)(t,n,i),YJ=/^[cC][^\s-]{8,}$/,JJ=/^[0-9a-z]+$/,XJ=/^[0-9A-HJKMNP-TV-Za-hjkmnp-tv-z]{26}$/,eX=/^[0-9a-vA-V]{20}$/,tX=/^[A-Za-z0-9]{27}$/,nX=/^[a-zA-Z0-9_-]{21}$/,iX=/^P(?:(\d+W)|(?!.*W)(?=\d|T\d)(\d+Y)?(\d+M)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+([.,]\d+)?S)?)?)$/,oX=/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$/,Sx=e=>e?new RegExp(`^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-${e}[0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12})$`):/^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$/,sX=/^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$/,rX="^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$";function lX(){return new RegExp(rX,"u")}const aX=/^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/,uX=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:))$/,cX=/^((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/([0-9]|[1-2][0-9]|3[0-2])$/,dX=/^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/,fX=/^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/,kD=/^[A-Za-z0-9_-]*$/,hX=/^\+[1-9]\d{6,14}$/,bD="(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))",pX=new RegExp(`^${bD}$`);function AD(e){const t="(?:[01]\\d|2[0-3]):[0-5]\\d";return typeof e.precision=="number"?e.precision===-1?`${t}`:e.precision===0?`${t}:[0-5]\\d`:`${t}:[0-5]\\d\\.\\d{${e.precision}}`:`${t}(?::[0-5]\\d(?:\\.\\d+)?)?`}function gX(e){return new RegExp(`^${AD(e)}$`)}function mX(e){const t=AD({precision:e.precision}),n=["Z"];e.local&&n.push(""),e.offset&&n.push("([+-](?:[01]\\d|2[0-3]):[0-5]\\d)");const i=`${t}(?:${n.join("|")})`;return new RegExp(`^${bD}T(?:${i})$`)}const vX=e=>{const t=e?`[\\s\\S]{${e?.minimum??0},${e?.maximum??""}}`:"[\\s\\S]*";return new RegExp(`^${t}$`)},yX=/^-?\d+$/,CD=/^-?\d+(?:\.\d+)?$/,kX=/^(?:true|false)$/i,bX=/^[^A-Z]*$/,AX=/^[^a-z]*$/,Jr=bt("$ZodCheck",(e,t)=>{var n;e._zod??(e._zod={}),e._zod.def=t,(n=e._zod).onattach??(n.onattach=[])}),wD={number:"number",bigint:"bigint",object:"date"},xD=bt("$ZodCheckLessThan",(e,t)=>{Jr.init(e,t);const n=wD[typeof t.value];e._zod.onattach.push(i=>{const o=i._zod.bag,s=(t.inclusive?o.maximum:o.exclusiveMaximum)??Number.POSITIVE_INFINITY;t.value<s&&(t.inclusive?o.maximum=t.value:o.exclusiveMaximum=t.value)}),e._zod.check=i=>{(t.inclusive?i.value<=t.value:i.value<t.value)||i.issues.push({origin:n,code:"too_big",maximum:typeof t.value=="object"?t.value.getTime():t.value,input:i.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),SD=bt("$ZodCheckGreaterThan",(e,t)=>{Jr.init(e,t);const n=wD[typeof t.value];e._zod.onattach.push(i=>{const o=i._zod.bag,s=(t.inclusive?o.minimum:o.exclusiveMinimum)??Number.NEGATIVE_INFINITY;t.value>s&&(t.inclusive?o.minimum=t.value:o.exclusiveMinimum=t.value)}),e._zod.check=i=>{(t.inclusive?i.value>=t.value:i.value>t.value)||i.issues.push({origin:n,code:"too_small",minimum:typeof t.value=="object"?t.value.getTime():t.value,input:i.value,inclusive:t.inclusive,inst:e,continue:!t.abort})}}),CX=bt("$ZodCheckMultipleOf",(e,t)=>{Jr.init(e,t),e._zod.onattach.push(n=>{var i;(i=n._zod.bag).multipleOf??(i.multipleOf=t.value)}),e._zod.check=n=>{if(typeof n.value!=typeof t.value)throw new Error("Cannot mix number and bigint in multiple_of check.");(typeof n.value=="bigint"?n.value%t.value===BigInt(0):_J(n.value,t.value)===0)||n.issues.push({origin:typeof n.value,code:"not_multiple_of",divisor:t.value,input:n.value,inst:e,continue:!t.abort})}}),wX=bt("$ZodCheckNumberFormat",(e,t)=>{Jr.init(e,t),t.format=t.format||"float64";const n=t.format?.includes("int"),i=n?"int":"number",[o,s]=LJ[t.format];e._zod.onattach.push(r=>{const l=r._zod.bag;l.format=t.format,l.minimum=o,l.maximum=s,n&&(l.pattern=yX)}),e._zod.check=r=>{const l=r.value;if(n){if(!Number.isInteger(l)){r.issues.push({expected:i,format:t.format,code:"invalid_type",continue:!1,input:l,inst:e});return}if(!Number.isSafeInteger(l)){l>0?r.issues.push({input:l,code:"too_big",maximum:Number.MAX_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:i,inclusive:!0,continue:!t.abort}):r.issues.push({input:l,code:"too_small",minimum:Number.MIN_SAFE_INTEGER,note:"Integers must be within the safe integer range.",inst:e,origin:i,inclusive:!0,continue:!t.abort});return}}l<o&&r.issues.push({origin:"number",input:l,code:"too_small",minimum:o,inclusive:!0,inst:e,continue:!t.abort}),l>s&&r.issues.push({origin:"number",input:l,code:"too_big",maximum:s,inclusive:!0,inst:e,continue:!t.abort})}}),xX=bt("$ZodCheckMaxLength",(e,t)=>{var n;Jr.init(e,t),(n=e._zod.def).when??(n.when=i=>{const o=i.value;return!u6(o)&&o.length!==void 0}),e._zod.onattach.push(i=>{const o=i._zod.bag.maximum??Number.POSITIVE_INFINITY;t.maximum<o&&(i._zod.bag.maximum=t.maximum)}),e._zod.check=i=>{const o=i.value;if(o.length<=t.maximum)return;const r=d6(o);i.issues.push({origin:r,code:"too_big",maximum:t.maximum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),SX=bt("$ZodCheckMinLength",(e,t)=>{var n;Jr.init(e,t),(n=e._zod.def).when??(n.when=i=>{const o=i.value;return!u6(o)&&o.length!==void 0}),e._zod.onattach.push(i=>{const o=i._zod.bag.minimum??Number.NEGATIVE_INFINITY;t.minimum>o&&(i._zod.bag.minimum=t.minimum)}),e._zod.check=i=>{const o=i.value;if(o.length>=t.minimum)return;const r=d6(o);i.issues.push({origin:r,code:"too_small",minimum:t.minimum,inclusive:!0,input:o,inst:e,continue:!t.abort})}}),_X=bt("$ZodCheckLengthEquals",(e,t)=>{var n;Jr.init(e,t),(n=e._zod.def).when??(n.when=i=>{const o=i.value;return!u6(o)&&o.length!==void 0}),e._zod.onattach.push(i=>{const o=i._zod.bag;o.minimum=t.length,o.maximum=t.length,o.length=t.length}),e._zod.check=i=>{const o=i.value,s=o.length;if(s===t.length)return;const r=d6(o),l=s>t.length;i.issues.push({origin:r,...l?{code:"too_big",maximum:t.length}:{code:"too_small",minimum:t.length},inclusive:!0,exact:!0,input:i.value,inst:e,continue:!t.abort})}}),r9=bt("$ZodCheckStringFormat",(e,t)=>{var n,i;Jr.init(e,t),e._zod.onattach.push(o=>{const s=o._zod.bag;s.format=t.format,t.pattern&&(s.patterns??(s.patterns=new Set),s.patterns.add(t.pattern))}),t.pattern?(n=e._zod).check??(n.check=o=>{t.pattern.lastIndex=0,!t.pattern.test(o.value)&&o.issues.push({origin:"string",code:"invalid_format",format:t.format,input:o.value,...t.pattern?{pattern:t.pattern.toString()}:{},inst:e,continue:!t.abort})}):(i=e._zod).check??(i.check=()=>{})}),MX=bt("$ZodCheckRegex",(e,t)=>{r9.init(e,t),e._zod.check=n=>{t.pattern.lastIndex=0,!t.pattern.test(n.value)&&n.issues.push({origin:"string",code:"invalid_format",format:"regex",input:n.value,pattern:t.pattern.toString(),inst:e,continue:!t.abort})}}),IX=bt("$ZodCheckLowerCase",(e,t)=>{t.pattern??(t.pattern=bX),r9.init(e,t)}),EX=bt("$ZodCheckUpperCase",(e,t)=>{t.pattern??(t.pattern=AX),r9.init(e,t)}),TX=bt("$ZodCheckIncludes",(e,t)=>{Jr.init(e,t);const n=Jh(t.includes),i=new RegExp(typeof t.position=="number"?`^.{${t.position}}${n}`:n);t.pattern=i,e._zod.onattach.push(o=>{const s=o._zod.bag;s.patterns??(s.patterns=new Set),s.patterns.add(i)}),e._zod.check=o=>{o.value.includes(t.includes,t.position)||o.issues.push({origin:"string",code:"invalid_format",format:"includes",includes:t.includes,input:o.value,inst:e,continue:!t.abort})}}),LX=bt("$ZodCheckStartsWith",(e,t)=>{Jr.init(e,t);const n=new RegExp(`^${Jh(t.prefix)}.*`);t.pattern??(t.pattern=n),e._zod.onattach.push(i=>{const o=i._zod.bag;o.patterns??(o.patterns=new Set),o.patterns.add(n)}),e._zod.check=i=>{i.value.startsWith(t.prefix)||i.issues.push({origin:"string",code:"invalid_format",format:"starts_with",prefix:t.prefix,input:i.value,inst:e,continue:!t.abort})}}),NX=bt("$ZodCheckEndsWith",(e,t)=>{Jr.init(e,t);const n=new RegExp(`.*${Jh(t.suffix)}$`);t.pattern??(t.pattern=n),e._zod.onattach.push(i=>{const o=i._zod.bag;o.patterns??(o.patterns=new Set),o.patterns.add(n)}),e._zod.check=i=>{i.value.endsWith(t.suffix)||i.issues.push({origin:"string",code:"invalid_format",format:"ends_with",suffix:t.suffix,input:i.value,inst:e,continue:!t.abort})}}),FX=bt("$ZodCheckOverwrite",(e,t)=>{Jr.init(e,t),e._zod.check=n=>{n.value=t.tx(n.value)}});class DX{constructor(t=[]){this.content=[],this.indent=0,this&&(this.args=t)}indented(t){this.indent+=1,t(this),this.indent-=1}write(t){if(typeof t=="function"){t(this,{execution:"sync"}),t(this,{execution:"async"});return}const i=t.split(` -`).filter(r=>r),o=Math.min(...i.map(r=>r.length-r.trimStart().length)),s=i.map(r=>r.slice(o)).map(r=>" ".repeat(this.indent*2)+r);for(const r of s)this.content.push(r)}compile(){const t=Function,n=this?.args,o=[...(this?.content??[""]).map(s=>` ${s}`)];return new t(...n,o.join(` -`))}}const BX={major:4,minor:3,patch:6},Co=bt("$ZodType",(e,t)=>{var n;e??(e={}),e._zod.def=t,e._zod.bag=e._zod.bag||{},e._zod.version=BX;const i=[...e._zod.def.checks??[]];e._zod.traits.has("$ZodCheck")&&i.unshift(e);for(const o of i)for(const s of o._zod.onattach)s(e);if(i.length===0)(n=e._zod).deferred??(n.deferred=[]),e._zod.deferred?.push(()=>{e._zod.run=e._zod.parse});else{const o=(r,l,a)=>{let u=ph(r),c;for(const d of l){if(d._zod.def.when){if(!d._zod.def.when(r))continue}else if(u)continue;const h=r.issues.length,p=d._zod.check(r);if(p instanceof Promise&&a?.async===!1)throw new Th;if(c||p instanceof Promise)c=(c??Promise.resolve()).then(async()=>{await p,r.issues.length!==h&&(u||(u=ph(r,h)))});else{if(r.issues.length===h)continue;u||(u=ph(r,h))}}return c?c.then(()=>r):r},s=(r,l,a)=>{if(ph(r))return r.aborted=!0,r;const u=o(l,i,a);if(u instanceof Promise){if(a.async===!1)throw new Th;return u.then(c=>e._zod.parse(c,a))}return e._zod.parse(u,a)};e._zod.run=(r,l)=>{if(l.skipChecks)return e._zod.parse(r,l);if(l.direction==="backward"){const u=e._zod.parse({value:r.value,issues:[]},{...l,skipChecks:!0});return u instanceof Promise?u.then(c=>s(c,r,l)):s(u,r,l)}const a=e._zod.parse(r,l);if(a instanceof Promise){if(l.async===!1)throw new Th;return a.then(u=>o(u,i,l))}return o(a,i,l)}}Si(e,"~standard",()=>({validate:o=>{try{const s=jJ(e,o);return s.success?{value:s.data}:{issues:s.error?.issues}}catch{return HJ(e,o).then(r=>r.success?{value:r.data}:{issues:r.error?.issues})}},vendor:"zod",version:1}))}),p6=bt("$ZodString",(e,t)=>{Co.init(e,t),e._zod.pattern=[...e?._zod.bag?.patterns??[]].pop()??vX(e._zod.bag),e._zod.parse=(n,i)=>{if(t.coerce)try{n.value=String(n.value)}catch{}return typeof n.value=="string"||n.issues.push({expected:"string",code:"invalid_type",input:n.value,inst:e}),n}}),po=bt("$ZodStringFormat",(e,t)=>{r9.init(e,t),p6.init(e,t)}),$X=bt("$ZodGUID",(e,t)=>{t.pattern??(t.pattern=oX),po.init(e,t)}),RX=bt("$ZodUUID",(e,t)=>{if(t.version){const i={v1:1,v2:2,v3:3,v4:4,v5:5,v6:6,v7:7,v8:8}[t.version];if(i===void 0)throw new Error(`Invalid UUID version: "${t.version}"`);t.pattern??(t.pattern=Sx(i))}else t.pattern??(t.pattern=Sx());po.init(e,t)}),zX=bt("$ZodEmail",(e,t)=>{t.pattern??(t.pattern=sX),po.init(e,t)}),OX=bt("$ZodURL",(e,t)=>{po.init(e,t),e._zod.check=n=>{try{const i=n.value.trim(),o=new URL(i);t.hostname&&(t.hostname.lastIndex=0,t.hostname.test(o.hostname)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid hostname",pattern:t.hostname.source,input:n.value,inst:e,continue:!t.abort})),t.protocol&&(t.protocol.lastIndex=0,t.protocol.test(o.protocol.endsWith(":")?o.protocol.slice(0,-1):o.protocol)||n.issues.push({code:"invalid_format",format:"url",note:"Invalid protocol",pattern:t.protocol.source,input:n.value,inst:e,continue:!t.abort})),t.normalize?n.value=o.href:n.value=i;return}catch{n.issues.push({code:"invalid_format",format:"url",input:n.value,inst:e,continue:!t.abort})}}}),PX=bt("$ZodEmoji",(e,t)=>{t.pattern??(t.pattern=lX()),po.init(e,t)}),jX=bt("$ZodNanoID",(e,t)=>{t.pattern??(t.pattern=nX),po.init(e,t)}),HX=bt("$ZodCUID",(e,t)=>{t.pattern??(t.pattern=YJ),po.init(e,t)}),WX=bt("$ZodCUID2",(e,t)=>{t.pattern??(t.pattern=JJ),po.init(e,t)}),qX=bt("$ZodULID",(e,t)=>{t.pattern??(t.pattern=XJ),po.init(e,t)}),UX=bt("$ZodXID",(e,t)=>{t.pattern??(t.pattern=eX),po.init(e,t)}),KX=bt("$ZodKSUID",(e,t)=>{t.pattern??(t.pattern=tX),po.init(e,t)}),VX=bt("$ZodISODateTime",(e,t)=>{t.pattern??(t.pattern=mX(t)),po.init(e,t)}),ZX=bt("$ZodISODate",(e,t)=>{t.pattern??(t.pattern=pX),po.init(e,t)}),GX=bt("$ZodISOTime",(e,t)=>{t.pattern??(t.pattern=gX(t)),po.init(e,t)}),QX=bt("$ZodISODuration",(e,t)=>{t.pattern??(t.pattern=iX),po.init(e,t)}),YX=bt("$ZodIPv4",(e,t)=>{t.pattern??(t.pattern=aX),po.init(e,t),e._zod.bag.format="ipv4"}),JX=bt("$ZodIPv6",(e,t)=>{t.pattern??(t.pattern=uX),po.init(e,t),e._zod.bag.format="ipv6",e._zod.check=n=>{try{new URL(`http://[${n.value}]`)}catch{n.issues.push({code:"invalid_format",format:"ipv6",input:n.value,inst:e,continue:!t.abort})}}}),XX=bt("$ZodCIDRv4",(e,t)=>{t.pattern??(t.pattern=cX),po.init(e,t)}),eee=bt("$ZodCIDRv6",(e,t)=>{t.pattern??(t.pattern=dX),po.init(e,t),e._zod.check=n=>{const i=n.value.split("/");try{if(i.length!==2)throw new Error;const[o,s]=i;if(!s)throw new Error;const r=Number(s);if(`${r}`!==s)throw new Error;if(r<0||r>128)throw new Error;new URL(`http://[${o}]`)}catch{n.issues.push({code:"invalid_format",format:"cidrv6",input:n.value,inst:e,continue:!t.abort})}}});function _D(e){if(e==="")return!0;if(e.length%4!==0)return!1;try{return atob(e),!0}catch{return!1}}const tee=bt("$ZodBase64",(e,t)=>{t.pattern??(t.pattern=fX),po.init(e,t),e._zod.bag.contentEncoding="base64",e._zod.check=n=>{_D(n.value)||n.issues.push({code:"invalid_format",format:"base64",input:n.value,inst:e,continue:!t.abort})}});function nee(e){if(!kD.test(e))return!1;const t=e.replace(/[-_]/g,i=>i==="-"?"+":"/"),n=t.padEnd(Math.ceil(t.length/4)*4,"=");return _D(n)}const iee=bt("$ZodBase64URL",(e,t)=>{t.pattern??(t.pattern=kD),po.init(e,t),e._zod.bag.contentEncoding="base64url",e._zod.check=n=>{nee(n.value)||n.issues.push({code:"invalid_format",format:"base64url",input:n.value,inst:e,continue:!t.abort})}}),oee=bt("$ZodE164",(e,t)=>{t.pattern??(t.pattern=hX),po.init(e,t)});function see(e,t=null){try{const n=e.split(".");if(n.length!==3)return!1;const[i]=n;if(!i)return!1;const o=JSON.parse(atob(i));return!("typ"in o&&o?.typ!=="JWT"||!o.alg||t&&(!("alg"in o)||o.alg!==t))}catch{return!1}}const ree=bt("$ZodJWT",(e,t)=>{po.init(e,t),e._zod.check=n=>{see(n.value,t.alg)||n.issues.push({code:"invalid_format",format:"jwt",input:n.value,inst:e,continue:!t.abort})}}),MD=bt("$ZodNumber",(e,t)=>{Co.init(e,t),e._zod.pattern=e._zod.bag.pattern??CD,e._zod.parse=(n,i)=>{if(t.coerce)try{n.value=Number(n.value)}catch{}const o=n.value;if(typeof o=="number"&&!Number.isNaN(o)&&Number.isFinite(o))return n;const s=typeof o=="number"?Number.isNaN(o)?"NaN":Number.isFinite(o)?void 0:"Infinity":void 0;return n.issues.push({expected:"number",code:"invalid_type",input:o,inst:e,...s?{received:s}:{}}),n}}),lee=bt("$ZodNumberFormat",(e,t)=>{wX.init(e,t),MD.init(e,t)}),aee=bt("$ZodBoolean",(e,t)=>{Co.init(e,t),e._zod.pattern=kX,e._zod.parse=(n,i)=>{if(t.coerce)try{n.value=!!n.value}catch{}const o=n.value;return typeof o=="boolean"||n.issues.push({expected:"boolean",code:"invalid_type",input:o,inst:e}),n}}),uee=bt("$ZodUnknown",(e,t)=>{Co.init(e,t),e._zod.parse=n=>n}),cee=bt("$ZodNever",(e,t)=>{Co.init(e,t),e._zod.parse=(n,i)=>(n.issues.push({expected:"never",code:"invalid_type",input:n.value,inst:e}),n)});function _x(e,t,n){e.issues.length&&t.issues.push(...gh(n,e.issues)),t.value[n]=e.value}const dee=bt("$ZodArray",(e,t)=>{Co.init(e,t),e._zod.parse=(n,i)=>{const o=n.value;if(!Array.isArray(o))return n.issues.push({expected:"array",code:"invalid_type",input:o,inst:e}),n;n.value=Array(o.length);const s=[];for(let r=0;r<o.length;r++){const l=o[r],a=t.element._zod.run({value:l,issues:[]},i);a instanceof Promise?s.push(a.then(u=>_x(u,n,r))):_x(a,n,r)}return s.length?Promise.all(s).then(()=>n):n}});function y2(e,t,n,i,o){if(e.issues.length){if(o&&!(n in i))return;t.issues.push(...gh(n,e.issues))}e.value===void 0?n in i&&(t.value[n]=void 0):t.value[n]=e.value}function ID(e){const t=Object.keys(e.shape);for(const i of t)if(!e.shape?.[i]?._zod?.traits?.has("$ZodType"))throw new Error(`Invalid element at key "${i}": expected a Zod schema`);const n=TJ(e.shape);return{...e,keys:t,keySet:new Set(t),numKeys:t.length,optionalKeys:new Set(n)}}function ED(e,t,n,i,o,s){const r=[],l=o.keySet,a=o.catchall._zod,u=a.def.type,c=a.optout==="optional";for(const d in t){if(l.has(d))continue;if(u==="never"){r.push(d);continue}const h=a.run({value:t[d],issues:[]},i);h instanceof Promise?e.push(h.then(p=>y2(p,n,d,t,c))):y2(h,n,d,t,c)}return r.length&&n.issues.push({code:"unrecognized_keys",keys:r,input:t,inst:s}),e.length?Promise.all(e).then(()=>n):n}const fee=bt("$ZodObject",(e,t)=>{if(Co.init(e,t),!Object.getOwnPropertyDescriptor(t,"shape")?.get){const l=t.shape;Object.defineProperty(t,"shape",{get:()=>{const a={...l};return Object.defineProperty(t,"shape",{value:a}),a}})}const i=i9(()=>ID(t));Si(e._zod,"propValues",()=>{const l=t.shape,a={};for(const u in l){const c=l[u]._zod;if(c.values){a[u]??(a[u]=new Set);for(const d of c.values)a[u].add(d)}}return a});const o=x0,s=t.catchall;let r;e._zod.parse=(l,a)=>{r??(r=i.value);const u=l.value;if(!o(u))return l.issues.push({expected:"object",code:"invalid_type",input:u,inst:e}),l;l.value={};const c=[],d=r.shape;for(const h of r.keys){const p=d[h],g=p._zod.optout==="optional",m=p._zod.run({value:u[h],issues:[]},a);m instanceof Promise?c.push(m.then(k=>y2(k,l,h,u,g))):y2(m,l,h,u,g)}return s?ED(c,u,l,a,i.value,e):c.length?Promise.all(c).then(()=>l):l}}),hee=bt("$ZodObjectJIT",(e,t)=>{fee.init(e,t);const n=e._zod.parse,i=i9(()=>ID(t)),o=h=>{const p=new DX(["shape","payload","ctx"]),g=i.value,m=b=>{const A=xx(b);return`shape[${A}]._zod.run({ value: input[${A}], issues: [] }, ctx)`};p.write("const input = payload.value;");const k=Object.create(null);let w=0;for(const b of g.keys)k[b]=`key_${w++}`;p.write("const newResult = {};");for(const b of g.keys){const A=k[b],T=xx(b),x=h[b]?._zod?.optout==="optional";p.write(`const ${A} = ${m(b)};`),x?p.write(` - if (${A}.issues.length) { - if (${T} in input) { - payload.issues = payload.issues.concat(${A}.issues.map(iss => ({ - ...iss, - path: iss.path ? [${T}, ...iss.path] : [${T}] - }))); - } - } - - if (${A}.value === undefined) { - if (${T} in input) { - newResult[${T}] = undefined; - } - } else { - newResult[${T}] = ${A}.value; - } - - `):p.write(` - if (${A}.issues.length) { - payload.issues = payload.issues.concat(${A}.issues.map(iss => ({ - ...iss, - path: iss.path ? [${T}, ...iss.path] : [${T}] - }))); - } - - if (${A}.value === undefined) { - if (${T} in input) { - newResult[${T}] = undefined; - } - } else { - newResult[${T}] = ${A}.value; - } - - `)}p.write("payload.value = newResult;"),p.write("return payload;");const y=p.compile();return(b,A)=>y(h,b,A)};let s;const r=x0,l=!fD.jitless,u=l&&IJ.value,c=t.catchall;let d;e._zod.parse=(h,p)=>{d??(d=i.value);const g=h.value;return r(g)?l&&u&&p?.async===!1&&p.jitless!==!0?(s||(s=o(t.shape)),h=s(h,p),c?ED([],g,h,p,d,e):h):n(h,p):(h.issues.push({expected:"object",code:"invalid_type",input:g,inst:e}),h)}});function Mx(e,t,n,i){for(const s of e)if(s.issues.length===0)return t.value=s.value,t;const o=e.filter(s=>!ph(s));return o.length===1?(t.value=o[0].value,o[0]):(t.issues.push({code:"invalid_union",input:t.value,inst:n,errors:e.map(s=>s.issues.map(r=>Sc(r,i,xc())))}),t)}const TD=bt("$ZodUnion",(e,t)=>{Co.init(e,t),Si(e._zod,"optin",()=>t.options.some(o=>o._zod.optin==="optional")?"optional":void 0),Si(e._zod,"optout",()=>t.options.some(o=>o._zod.optout==="optional")?"optional":void 0),Si(e._zod,"values",()=>{if(t.options.every(o=>o._zod.values))return new Set(t.options.flatMap(o=>Array.from(o._zod.values)))}),Si(e._zod,"pattern",()=>{if(t.options.every(o=>o._zod.pattern)){const o=t.options.map(s=>s._zod.pattern);return new RegExp(`^(${o.map(s=>c6(s.source)).join("|")})$`)}});const n=t.options.length===1,i=t.options[0]._zod.run;e._zod.parse=(o,s)=>{if(n)return i(o,s);let r=!1;const l=[];for(const a of t.options){const u=a._zod.run({value:o.value,issues:[]},s);if(u instanceof Promise)l.push(u),r=!0;else{if(u.issues.length===0)return u;l.push(u)}}return r?Promise.all(l).then(a=>Mx(a,o,e,s)):Mx(l,o,e,s)}}),pee=bt("$ZodDiscriminatedUnion",(e,t)=>{t.inclusive=!1,TD.init(e,t);const n=e._zod.parse;Si(e._zod,"propValues",()=>{const o={};for(const s of t.options){const r=s._zod.propValues;if(!r||Object.keys(r).length===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(s)}"`);for(const[l,a]of Object.entries(r)){o[l]||(o[l]=new Set);for(const u of a)o[l].add(u)}}return o});const i=i9(()=>{const o=t.options,s=new Map;for(const r of o){const l=r._zod.propValues?.[t.discriminator];if(!l||l.size===0)throw new Error(`Invalid discriminated union option at index "${t.options.indexOf(r)}"`);for(const a of l){if(s.has(a))throw new Error(`Duplicate discriminator value "${String(a)}"`);s.set(a,r)}}return s});e._zod.parse=(o,s)=>{const r=o.value;if(!x0(r))return o.issues.push({code:"invalid_type",expected:"object",input:r,inst:e}),o;const l=i.value.get(r?.[t.discriminator]);return l?l._zod.run(o,s):t.unionFallback?n(o,s):(o.issues.push({code:"invalid_union",errors:[],note:"No matching discriminator",discriminator:t.discriminator,input:r,path:[t.discriminator],inst:e}),o)}}),gee=bt("$ZodIntersection",(e,t)=>{Co.init(e,t),e._zod.parse=(n,i)=>{const o=n.value,s=t.left._zod.run({value:o,issues:[]},i),r=t.right._zod.run({value:o,issues:[]},i);return s instanceof Promise||r instanceof Promise?Promise.all([s,r]).then(([a,u])=>Ix(n,a,u)):Ix(n,s,r)}});function Ib(e,t){if(e===t)return{valid:!0,data:e};if(e instanceof Date&&t instanceof Date&&+e==+t)return{valid:!0,data:e};if(Yh(e)&&Yh(t)){const n=Object.keys(t),i=Object.keys(e).filter(s=>n.indexOf(s)!==-1),o={...e,...t};for(const s of i){const r=Ib(e[s],t[s]);if(!r.valid)return{valid:!1,mergeErrorPath:[s,...r.mergeErrorPath]};o[s]=r.data}return{valid:!0,data:o}}if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length)return{valid:!1,mergeErrorPath:[]};const n=[];for(let i=0;i<e.length;i++){const o=e[i],s=t[i],r=Ib(o,s);if(!r.valid)return{valid:!1,mergeErrorPath:[i,...r.mergeErrorPath]};n.push(r.data)}return{valid:!0,data:n}}return{valid:!1,mergeErrorPath:[]}}function Ix(e,t,n){const i=new Map;let o;for(const l of t.issues)if(l.code==="unrecognized_keys"){o??(o=l);for(const a of l.keys)i.has(a)||i.set(a,{}),i.get(a).l=!0}else e.issues.push(l);for(const l of n.issues)if(l.code==="unrecognized_keys")for(const a of l.keys)i.has(a)||i.set(a,{}),i.get(a).r=!0;else e.issues.push(l);const s=[...i].filter(([,l])=>l.l&&l.r).map(([l])=>l);if(s.length&&o&&e.issues.push({...o,keys:s}),ph(e))return e;const r=Ib(t.value,n.value);if(!r.valid)throw new Error(`Unmergable intersection. Error path: ${JSON.stringify(r.mergeErrorPath)}`);return e.value=r.data,e}const mee=bt("$ZodRecord",(e,t)=>{Co.init(e,t),e._zod.parse=(n,i)=>{const o=n.value;if(!Yh(o))return n.issues.push({expected:"record",code:"invalid_type",input:o,inst:e}),n;const s=[],r=t.keyType._zod.values;if(r){n.value={};const l=new Set;for(const u of r)if(typeof u=="string"||typeof u=="number"||typeof u=="symbol"){l.add(typeof u=="number"?u.toString():u);const c=t.valueType._zod.run({value:o[u],issues:[]},i);c instanceof Promise?s.push(c.then(d=>{d.issues.length&&n.issues.push(...gh(u,d.issues)),n.value[u]=d.value})):(c.issues.length&&n.issues.push(...gh(u,c.issues)),n.value[u]=c.value)}let a;for(const u in o)l.has(u)||(a=a??[],a.push(u));a&&a.length>0&&n.issues.push({code:"unrecognized_keys",input:o,inst:e,keys:a})}else{n.value={};for(const l of Reflect.ownKeys(o)){if(l==="__proto__")continue;let a=t.keyType._zod.run({value:l,issues:[]},i);if(a instanceof Promise)throw new Error("Async schemas not supported in object keys currently");if(typeof l=="string"&&CD.test(l)&&a.issues.length){const d=t.keyType._zod.run({value:Number(l),issues:[]},i);if(d instanceof Promise)throw new Error("Async schemas not supported in object keys currently");d.issues.length===0&&(a=d)}if(a.issues.length){t.mode==="loose"?n.value[l]=o[l]:n.issues.push({code:"invalid_key",origin:"record",issues:a.issues.map(d=>Sc(d,i,xc())),input:l,path:[l],inst:e});continue}const c=t.valueType._zod.run({value:o[l],issues:[]},i);c instanceof Promise?s.push(c.then(d=>{d.issues.length&&n.issues.push(...gh(l,d.issues)),n.value[a.value]=d.value})):(c.issues.length&&n.issues.push(...gh(l,c.issues)),n.value[a.value]=c.value)}}return s.length?Promise.all(s).then(()=>n):n}}),vee=bt("$ZodEnum",(e,t)=>{Co.init(e,t);const n=hD(t.entries),i=new Set(n);e._zod.values=i,e._zod.pattern=new RegExp(`^(${n.filter(o=>EJ.has(typeof o)).map(o=>typeof o=="string"?Jh(o):o.toString()).join("|")})$`),e._zod.parse=(o,s)=>{const r=o.value;return i.has(r)||o.issues.push({code:"invalid_value",values:n,input:r,inst:e}),o}}),yee=bt("$ZodLiteral",(e,t)=>{if(Co.init(e,t),t.values.length===0)throw new Error("Cannot create literal schema with no valid values");const n=new Set(t.values);e._zod.values=n,e._zod.pattern=new RegExp(`^(${t.values.map(i=>typeof i=="string"?Jh(i):i?Jh(i.toString()):String(i)).join("|")})$`),e._zod.parse=(i,o)=>{const s=i.value;return n.has(s)||i.issues.push({code:"invalid_value",values:t.values,input:s,inst:e}),i}}),kee=bt("$ZodTransform",(e,t)=>{Co.init(e,t),e._zod.parse=(n,i)=>{if(i.direction==="backward")throw new dD(e.constructor.name);const o=t.transform(n.value,n);if(i.async)return(o instanceof Promise?o:Promise.resolve(o)).then(r=>(n.value=r,n));if(o instanceof Promise)throw new Th;return n.value=o,n}});function Ex(e,t){return e.issues.length&&t===void 0?{issues:[],value:void 0}:e}const LD=bt("$ZodOptional",(e,t)=>{Co.init(e,t),e._zod.optin="optional",e._zod.optout="optional",Si(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,void 0]):void 0),Si(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${c6(n.source)})?$`):void 0}),e._zod.parse=(n,i)=>{if(t.innerType._zod.optin==="optional"){const o=t.innerType._zod.run(n,i);return o instanceof Promise?o.then(s=>Ex(s,n.value)):Ex(o,n.value)}return n.value===void 0?n:t.innerType._zod.run(n,i)}}),bee=bt("$ZodExactOptional",(e,t)=>{LD.init(e,t),Si(e._zod,"values",()=>t.innerType._zod.values),Si(e._zod,"pattern",()=>t.innerType._zod.pattern),e._zod.parse=(n,i)=>t.innerType._zod.run(n,i)}),Aee=bt("$ZodNullable",(e,t)=>{Co.init(e,t),Si(e._zod,"optin",()=>t.innerType._zod.optin),Si(e._zod,"optout",()=>t.innerType._zod.optout),Si(e._zod,"pattern",()=>{const n=t.innerType._zod.pattern;return n?new RegExp(`^(${c6(n.source)}|null)$`):void 0}),Si(e._zod,"values",()=>t.innerType._zod.values?new Set([...t.innerType._zod.values,null]):void 0),e._zod.parse=(n,i)=>n.value===null?n:t.innerType._zod.run(n,i)}),Cee=bt("$ZodDefault",(e,t)=>{Co.init(e,t),e._zod.optin="optional",Si(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,i)=>{if(i.direction==="backward")return t.innerType._zod.run(n,i);if(n.value===void 0)return n.value=t.defaultValue,n;const o=t.innerType._zod.run(n,i);return o instanceof Promise?o.then(s=>Tx(s,t)):Tx(o,t)}});function Tx(e,t){return e.value===void 0&&(e.value=t.defaultValue),e}const wee=bt("$ZodPrefault",(e,t)=>{Co.init(e,t),e._zod.optin="optional",Si(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,i)=>(i.direction==="backward"||n.value===void 0&&(n.value=t.defaultValue),t.innerType._zod.run(n,i))}),xee=bt("$ZodNonOptional",(e,t)=>{Co.init(e,t),Si(e._zod,"values",()=>{const n=t.innerType._zod.values;return n?new Set([...n].filter(i=>i!==void 0)):void 0}),e._zod.parse=(n,i)=>{const o=t.innerType._zod.run(n,i);return o instanceof Promise?o.then(s=>Lx(s,e)):Lx(o,e)}});function Lx(e,t){return!e.issues.length&&e.value===void 0&&e.issues.push({code:"invalid_type",expected:"nonoptional",input:e.value,inst:t}),e}const See=bt("$ZodCatch",(e,t)=>{Co.init(e,t),Si(e._zod,"optin",()=>t.innerType._zod.optin),Si(e._zod,"optout",()=>t.innerType._zod.optout),Si(e._zod,"values",()=>t.innerType._zod.values),e._zod.parse=(n,i)=>{if(i.direction==="backward")return t.innerType._zod.run(n,i);const o=t.innerType._zod.run(n,i);return o instanceof Promise?o.then(s=>(n.value=s.value,s.issues.length&&(n.value=t.catchValue({...n,error:{issues:s.issues.map(r=>Sc(r,i,xc()))},input:n.value}),n.issues=[]),n)):(n.value=o.value,o.issues.length&&(n.value=t.catchValue({...n,error:{issues:o.issues.map(s=>Sc(s,i,xc()))},input:n.value}),n.issues=[]),n)}}),_ee=bt("$ZodPipe",(e,t)=>{Co.init(e,t),Si(e._zod,"values",()=>t.in._zod.values),Si(e._zod,"optin",()=>t.in._zod.optin),Si(e._zod,"optout",()=>t.out._zod.optout),Si(e._zod,"propValues",()=>t.in._zod.propValues),e._zod.parse=(n,i)=>{if(i.direction==="backward"){const s=t.out._zod.run(n,i);return s instanceof Promise?s.then(r=>bm(r,t.in,i)):bm(s,t.in,i)}const o=t.in._zod.run(n,i);return o instanceof Promise?o.then(s=>bm(s,t.out,i)):bm(o,t.out,i)}});function bm(e,t,n){return e.issues.length?(e.aborted=!0,e):t._zod.run({value:e.value,issues:e.issues},n)}const Mee=bt("$ZodReadonly",(e,t)=>{Co.init(e,t),Si(e._zod,"propValues",()=>t.innerType._zod.propValues),Si(e._zod,"values",()=>t.innerType._zod.values),Si(e._zod,"optin",()=>t.innerType?._zod?.optin),Si(e._zod,"optout",()=>t.innerType?._zod?.optout),e._zod.parse=(n,i)=>{if(i.direction==="backward")return t.innerType._zod.run(n,i);const o=t.innerType._zod.run(n,i);return o instanceof Promise?o.then(Nx):Nx(o)}});function Nx(e){return e.value=Object.freeze(e.value),e}const Iee=bt("$ZodCustom",(e,t)=>{Jr.init(e,t),Co.init(e,t),e._zod.parse=(n,i)=>n,e._zod.check=n=>{const i=n.value,o=t.fn(i);if(o instanceof Promise)return o.then(s=>Fx(s,n,i,e));Fx(o,n,i,e)}});function Fx(e,t,n,i){if(!e){const o={code:"custom",input:n,inst:i,path:[...i._zod.def.path??[]],continue:!i._zod.def.abort};i._zod.def.params&&(o.params=i._zod.def.params),t.issues.push(S0(o))}}var Dx;class Eee{constructor(){this._map=new WeakMap,this._idmap=new Map}add(t,...n){const i=n[0];return this._map.set(t,i),i&&typeof i=="object"&&"id"in i&&this._idmap.set(i.id,t),this}clear(){return this._map=new WeakMap,this._idmap=new Map,this}remove(t){const n=this._map.get(t);return n&&typeof n=="object"&&"id"in n&&this._idmap.delete(n.id),this._map.delete(t),this}get(t){const n=t._zod.parent;if(n){const i={...this.get(n)??{}};delete i.id;const o={...i,...this._map.get(t)};return Object.keys(o).length?o:void 0}return this._map.get(t)}has(t){return this._map.has(t)}}function Tee(){return new Eee}(Dx=globalThis).__zod_globalRegistry??(Dx.__zod_globalRegistry=Tee());const fp=globalThis.__zod_globalRegistry;function Lee(e,t){return new e({type:"string",...pn(t)})}function Nee(e,t){return new e({type:"string",format:"email",check:"string_format",abort:!1,...pn(t)})}function Bx(e,t){return new e({type:"string",format:"guid",check:"string_format",abort:!1,...pn(t)})}function Fee(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,...pn(t)})}function Dee(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v4",...pn(t)})}function Bee(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v6",...pn(t)})}function $ee(e,t){return new e({type:"string",format:"uuid",check:"string_format",abort:!1,version:"v7",...pn(t)})}function Ree(e,t){return new e({type:"string",format:"url",check:"string_format",abort:!1,...pn(t)})}function zee(e,t){return new e({type:"string",format:"emoji",check:"string_format",abort:!1,...pn(t)})}function Oee(e,t){return new e({type:"string",format:"nanoid",check:"string_format",abort:!1,...pn(t)})}function Pee(e,t){return new e({type:"string",format:"cuid",check:"string_format",abort:!1,...pn(t)})}function jee(e,t){return new e({type:"string",format:"cuid2",check:"string_format",abort:!1,...pn(t)})}function Hee(e,t){return new e({type:"string",format:"ulid",check:"string_format",abort:!1,...pn(t)})}function Wee(e,t){return new e({type:"string",format:"xid",check:"string_format",abort:!1,...pn(t)})}function qee(e,t){return new e({type:"string",format:"ksuid",check:"string_format",abort:!1,...pn(t)})}function Uee(e,t){return new e({type:"string",format:"ipv4",check:"string_format",abort:!1,...pn(t)})}function Kee(e,t){return new e({type:"string",format:"ipv6",check:"string_format",abort:!1,...pn(t)})}function Vee(e,t){return new e({type:"string",format:"cidrv4",check:"string_format",abort:!1,...pn(t)})}function Zee(e,t){return new e({type:"string",format:"cidrv6",check:"string_format",abort:!1,...pn(t)})}function Gee(e,t){return new e({type:"string",format:"base64",check:"string_format",abort:!1,...pn(t)})}function Qee(e,t){return new e({type:"string",format:"base64url",check:"string_format",abort:!1,...pn(t)})}function Yee(e,t){return new e({type:"string",format:"e164",check:"string_format",abort:!1,...pn(t)})}function Jee(e,t){return new e({type:"string",format:"jwt",check:"string_format",abort:!1,...pn(t)})}function Xee(e,t){return new e({type:"string",format:"datetime",check:"string_format",offset:!1,local:!1,precision:null,...pn(t)})}function ete(e,t){return new e({type:"string",format:"date",check:"string_format",...pn(t)})}function tte(e,t){return new e({type:"string",format:"time",check:"string_format",precision:null,...pn(t)})}function nte(e,t){return new e({type:"string",format:"duration",check:"string_format",...pn(t)})}function ite(e,t){return new e({type:"number",checks:[],...pn(t)})}function ote(e,t){return new e({type:"number",check:"number_format",abort:!1,format:"safeint",...pn(t)})}function ste(e,t){return new e({type:"boolean",...pn(t)})}function rte(e){return new e({type:"unknown"})}function lte(e,t){return new e({type:"never",...pn(t)})}function $x(e,t){return new xD({check:"less_than",...pn(t),value:e,inclusive:!1})}function t3(e,t){return new xD({check:"less_than",...pn(t),value:e,inclusive:!0})}function Rx(e,t){return new SD({check:"greater_than",...pn(t),value:e,inclusive:!1})}function n3(e,t){return new SD({check:"greater_than",...pn(t),value:e,inclusive:!0})}function zx(e,t){return new CX({check:"multiple_of",...pn(t),value:e})}function ND(e,t){return new xX({check:"max_length",...pn(t),maximum:e})}function k2(e,t){return new SX({check:"min_length",...pn(t),minimum:e})}function FD(e,t){return new _X({check:"length_equals",...pn(t),length:e})}function ate(e,t){return new MX({check:"string_format",format:"regex",...pn(t),pattern:e})}function ute(e){return new IX({check:"string_format",format:"lowercase",...pn(e)})}function cte(e){return new EX({check:"string_format",format:"uppercase",...pn(e)})}function dte(e,t){return new TX({check:"string_format",format:"includes",...pn(t),includes:e})}function fte(e,t){return new LX({check:"string_format",format:"starts_with",...pn(t),prefix:e})}function hte(e,t){return new NX({check:"string_format",format:"ends_with",...pn(t),suffix:e})}function u1(e){return new FX({check:"overwrite",tx:e})}function pte(e){return u1(t=>t.normalize(e))}function gte(){return u1(e=>e.trim())}function mte(){return u1(e=>e.toLowerCase())}function vte(){return u1(e=>e.toUpperCase())}function yte(){return u1(e=>MJ(e))}function kte(e,t,n){return new e({type:"array",element:t,...pn(n)})}function bte(e,t,n){return new e({type:"custom",check:"custom",fn:t,...pn(n)})}function Ate(e){const t=Cte(n=>(n.addIssue=i=>{if(typeof i=="string")n.issues.push(S0(i,n.value,t._zod.def));else{const o=i;o.fatal&&(o.continue=!1),o.code??(o.code="custom"),o.input??(o.input=n.value),o.inst??(o.inst=t),o.continue??(o.continue=!t._zod.def.abort),n.issues.push(S0(o))}},e(n.value,n)));return t}function Cte(e,t){const n=new Jr({check:"custom",...pn(t)});return n._zod.check=e,n}function DD(e){let t=e?.target??"draft-2020-12";return t==="draft-4"&&(t="draft-04"),t==="draft-7"&&(t="draft-07"),{processors:e.processors??{},metadataRegistry:e?.metadata??fp,target:t,unrepresentable:e?.unrepresentable??"throw",override:e?.override??(()=>{}),io:e?.io??"output",counter:0,seen:new Map,cycles:e?.cycles??"ref",reused:e?.reused??"inline",external:e?.external??void 0}}function ns(e,t,n={path:[],schemaPath:[]}){var i;const o=e._zod.def,s=t.seen.get(e);if(s)return s.count++,n.schemaPath.includes(e)&&(s.cycle=n.path),s.schema;const r={schema:{},count:1,cycle:void 0,path:n.path};t.seen.set(e,r);const l=e._zod.toJSONSchema?.();if(l)r.schema=l;else{const c={...n,schemaPath:[...n.schemaPath,e],path:n.path};if(e._zod.processJSONSchema)e._zod.processJSONSchema(t,r.schema,c);else{const h=r.schema,p=t.processors[o.type];if(!p)throw new Error(`[toJSONSchema]: Non-representable type encountered: ${o.type}`);p(e,t,h,c)}const d=e._zod.parent;d&&(r.ref||(r.ref=d),ns(d,t,c),t.seen.get(d).isParent=!0)}const a=t.metadataRegistry.get(e);return a&&Object.assign(r.schema,a),t.io==="input"&&fr(e)&&(delete r.schema.examples,delete r.schema.default),t.io==="input"&&r.schema._prefault&&((i=r.schema).default??(i.default=r.schema._prefault)),delete r.schema._prefault,t.seen.get(e).schema}function BD(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const i=new Map;for(const r of e.seen.entries()){const l=e.metadataRegistry.get(r[0])?.id;if(l){const a=i.get(l);if(a&&a!==r[0])throw new Error(`Duplicate schema id "${l}" detected during JSON Schema conversion. Two different schemas cannot share the same id when converted together.`);i.set(l,r[0])}}const o=r=>{const l=e.target==="draft-2020-12"?"$defs":"definitions";if(e.external){const d=e.external.registry.get(r[0])?.id,h=e.external.uri??(g=>g);if(d)return{ref:h(d)};const p=r[1].defId??r[1].schema.id??`schema${e.counter++}`;return r[1].defId=p,{defId:p,ref:`${h("__shared")}#/${l}/${p}`}}if(r[1]===n)return{ref:"#"};const u=`#/${l}/`,c=r[1].schema.id??`__schema${e.counter++}`;return{defId:c,ref:u+c}},s=r=>{if(r[1].schema.$ref)return;const l=r[1],{ref:a,defId:u}=o(r);l.def={...l.schema},u&&(l.defId=u);const c=l.schema;for(const d in c)delete c[d];c.$ref=a};if(e.cycles==="throw")for(const r of e.seen.entries()){const l=r[1];if(l.cycle)throw new Error(`Cycle detected: #/${l.cycle?.join("/")}/<root> - -Set the \`cycles\` parameter to \`"ref"\` to resolve cyclical schemas with defs.`)}for(const r of e.seen.entries()){const l=r[1];if(t===r[0]){s(r);continue}if(e.external){const u=e.external.registry.get(r[0])?.id;if(t!==r[0]&&u){s(r);continue}}if(e.metadataRegistry.get(r[0])?.id){s(r);continue}if(l.cycle){s(r);continue}if(l.count>1&&e.reused==="ref"){s(r);continue}}}function $D(e,t){const n=e.seen.get(t);if(!n)throw new Error("Unprocessed schema. This is a bug in Zod.");const i=r=>{const l=e.seen.get(r);if(l.ref===null)return;const a=l.def??l.schema,u={...a},c=l.ref;if(l.ref=null,c){i(c);const h=e.seen.get(c),p=h.schema;if(p.$ref&&(e.target==="draft-07"||e.target==="draft-04"||e.target==="openapi-3.0")?(a.allOf=a.allOf??[],a.allOf.push(p)):Object.assign(a,p),Object.assign(a,u),r._zod.parent===c)for(const m in a)m==="$ref"||m==="allOf"||m in u||delete a[m];if(p.$ref&&h.def)for(const m in a)m==="$ref"||m==="allOf"||m in h.def&&JSON.stringify(a[m])===JSON.stringify(h.def[m])&&delete a[m]}const d=r._zod.parent;if(d&&d!==c){i(d);const h=e.seen.get(d);if(h?.schema.$ref&&(a.$ref=h.schema.$ref,h.def))for(const p in a)p==="$ref"||p==="allOf"||p in h.def&&JSON.stringify(a[p])===JSON.stringify(h.def[p])&&delete a[p]}e.override({zodSchema:r,jsonSchema:a,path:l.path??[]})};for(const r of[...e.seen.entries()].reverse())i(r[0]);const o={};if(e.target==="draft-2020-12"?o.$schema="https://json-schema.org/draft/2020-12/schema":e.target==="draft-07"?o.$schema="http://json-schema.org/draft-07/schema#":e.target==="draft-04"?o.$schema="http://json-schema.org/draft-04/schema#":e.target,e.external?.uri){const r=e.external.registry.get(t)?.id;if(!r)throw new Error("Schema is missing an `id` property");o.$id=e.external.uri(r)}Object.assign(o,n.def??n.schema);const s=e.external?.defs??{};for(const r of e.seen.entries()){const l=r[1];l.def&&l.defId&&(s[l.defId]=l.def)}e.external||Object.keys(s).length>0&&(e.target==="draft-2020-12"?o.$defs=s:o.definitions=s);try{const r=JSON.parse(JSON.stringify(o));return Object.defineProperty(r,"~standard",{value:{...t["~standard"],jsonSchema:{input:b2(t,"input",e.processors),output:b2(t,"output",e.processors)}},enumerable:!1,writable:!1}),r}catch{throw new Error("Error converting schema to JSON.")}}function fr(e,t){const n=t??{seen:new Set};if(n.seen.has(e))return!1;n.seen.add(e);const i=e._zod.def;if(i.type==="transform")return!0;if(i.type==="array")return fr(i.element,n);if(i.type==="set")return fr(i.valueType,n);if(i.type==="lazy")return fr(i.getter(),n);if(i.type==="promise"||i.type==="optional"||i.type==="nonoptional"||i.type==="nullable"||i.type==="readonly"||i.type==="default"||i.type==="prefault")return fr(i.innerType,n);if(i.type==="intersection")return fr(i.left,n)||fr(i.right,n);if(i.type==="record"||i.type==="map")return fr(i.keyType,n)||fr(i.valueType,n);if(i.type==="pipe")return fr(i.in,n)||fr(i.out,n);if(i.type==="object"){for(const o in i.shape)if(fr(i.shape[o],n))return!0;return!1}if(i.type==="union"){for(const o of i.options)if(fr(o,n))return!0;return!1}if(i.type==="tuple"){for(const o of i.items)if(fr(o,n))return!0;return!!(i.rest&&fr(i.rest,n))}return!1}const wte=(e,t={})=>n=>{const i=DD({...n,processors:t});return ns(e,i),BD(i,e),$D(i,e)},b2=(e,t,n={})=>i=>{const{libraryOptions:o,target:s}=i??{},r=DD({...o??{},target:s,io:t,processors:n});return ns(e,r),BD(r,e),$D(r,e)},xte={guid:"uuid",url:"uri",datetime:"date-time",json_string:"json-string",regex:""},Ste=(e,t,n,i)=>{const o=n;o.type="string";const{minimum:s,maximum:r,format:l,patterns:a,contentEncoding:u}=e._zod.bag;if(typeof s=="number"&&(o.minLength=s),typeof r=="number"&&(o.maxLength=r),l&&(o.format=xte[l]??l,o.format===""&&delete o.format,l==="time"&&delete o.format),u&&(o.contentEncoding=u),a&&a.size>0){const c=[...a];c.length===1?o.pattern=c[0].source:c.length>1&&(o.allOf=[...c.map(d=>({...t.target==="draft-07"||t.target==="draft-04"||t.target==="openapi-3.0"?{type:"string"}:{},pattern:d.source}))])}},_te=(e,t,n,i)=>{const o=n,{minimum:s,maximum:r,format:l,multipleOf:a,exclusiveMaximum:u,exclusiveMinimum:c}=e._zod.bag;typeof l=="string"&&l.includes("int")?o.type="integer":o.type="number",typeof c=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(o.minimum=c,o.exclusiveMinimum=!0):o.exclusiveMinimum=c),typeof s=="number"&&(o.minimum=s,typeof c=="number"&&t.target!=="draft-04"&&(c>=s?delete o.minimum:delete o.exclusiveMinimum)),typeof u=="number"&&(t.target==="draft-04"||t.target==="openapi-3.0"?(o.maximum=u,o.exclusiveMaximum=!0):o.exclusiveMaximum=u),typeof r=="number"&&(o.maximum=r,typeof u=="number"&&t.target!=="draft-04"&&(u<=r?delete o.maximum:delete o.exclusiveMaximum)),typeof a=="number"&&(o.multipleOf=a)},Mte=(e,t,n,i)=>{n.type="boolean"},Ite=(e,t,n,i)=>{n.not={}},Ete=(e,t,n,i)=>{},Tte=(e,t,n,i)=>{const o=e._zod.def,s=hD(o.entries);s.every(r=>typeof r=="number")&&(n.type="number"),s.every(r=>typeof r=="string")&&(n.type="string"),n.enum=s},Lte=(e,t,n,i)=>{const o=e._zod.def,s=[];for(const r of o.values)if(r===void 0){if(t.unrepresentable==="throw")throw new Error("Literal `undefined` cannot be represented in JSON Schema")}else if(typeof r=="bigint"){if(t.unrepresentable==="throw")throw new Error("BigInt literals cannot be represented in JSON Schema");s.push(Number(r))}else s.push(r);if(s.length!==0)if(s.length===1){const r=s[0];n.type=r===null?"null":typeof r,t.target==="draft-04"||t.target==="openapi-3.0"?n.enum=[r]:n.const=r}else s.every(r=>typeof r=="number")&&(n.type="number"),s.every(r=>typeof r=="string")&&(n.type="string"),s.every(r=>typeof r=="boolean")&&(n.type="boolean"),s.every(r=>r===null)&&(n.type="null"),n.enum=s},Nte=(e,t,n,i)=>{if(t.unrepresentable==="throw")throw new Error("Custom types cannot be represented in JSON Schema")},Fte=(e,t,n,i)=>{if(t.unrepresentable==="throw")throw new Error("Transforms cannot be represented in JSON Schema")},Dte=(e,t,n,i)=>{const o=n,s=e._zod.def,{minimum:r,maximum:l}=e._zod.bag;typeof r=="number"&&(o.minItems=r),typeof l=="number"&&(o.maxItems=l),o.type="array",o.items=ns(s.element,t,{...i,path:[...i.path,"items"]})},Bte=(e,t,n,i)=>{const o=n,s=e._zod.def;o.type="object",o.properties={};const r=s.shape;for(const u in r)o.properties[u]=ns(r[u],t,{...i,path:[...i.path,"properties",u]});const l=new Set(Object.keys(r)),a=new Set([...l].filter(u=>{const c=s.shape[u]._zod;return t.io==="input"?c.optin===void 0:c.optout===void 0}));a.size>0&&(o.required=Array.from(a)),s.catchall?._zod.def.type==="never"?o.additionalProperties=!1:s.catchall?s.catchall&&(o.additionalProperties=ns(s.catchall,t,{...i,path:[...i.path,"additionalProperties"]})):t.io==="output"&&(o.additionalProperties=!1)},$te=(e,t,n,i)=>{const o=e._zod.def,s=o.inclusive===!1,r=o.options.map((l,a)=>ns(l,t,{...i,path:[...i.path,s?"oneOf":"anyOf",a]}));s?n.oneOf=r:n.anyOf=r},Rte=(e,t,n,i)=>{const o=e._zod.def,s=ns(o.left,t,{...i,path:[...i.path,"allOf",0]}),r=ns(o.right,t,{...i,path:[...i.path,"allOf",1]}),l=u=>"allOf"in u&&Object.keys(u).length===1,a=[...l(s)?s.allOf:[s],...l(r)?r.allOf:[r]];n.allOf=a},zte=(e,t,n,i)=>{const o=n,s=e._zod.def;o.type="object";const r=s.keyType,a=r._zod.bag?.patterns;if(s.mode==="loose"&&a&&a.size>0){const c=ns(s.valueType,t,{...i,path:[...i.path,"patternProperties","*"]});o.patternProperties={};for(const d of a)o.patternProperties[d.source]=c}else(t.target==="draft-07"||t.target==="draft-2020-12")&&(o.propertyNames=ns(s.keyType,t,{...i,path:[...i.path,"propertyNames"]})),o.additionalProperties=ns(s.valueType,t,{...i,path:[...i.path,"additionalProperties"]});const u=r._zod.values;if(u){const c=[...u].filter(d=>typeof d=="string"||typeof d=="number");c.length>0&&(o.required=c)}},Ote=(e,t,n,i)=>{const o=e._zod.def,s=ns(o.innerType,t,i),r=t.seen.get(e);t.target==="openapi-3.0"?(r.ref=o.innerType,n.nullable=!0):n.anyOf=[s,{type:"null"}]},Pte=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType},jte=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType,n.default=JSON.parse(JSON.stringify(o.defaultValue))},Hte=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType,t.io==="input"&&(n._prefault=JSON.parse(JSON.stringify(o.defaultValue)))},Wte=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType;let r;try{r=o.catchValue(void 0)}catch{throw new Error("Dynamic catch values are not supported in JSON Schema")}n.default=r},qte=(e,t,n,i)=>{const o=e._zod.def,s=t.io==="input"?o.in._zod.def.type==="transform"?o.out:o.in:o.out;ns(s,t,i);const r=t.seen.get(e);r.ref=s},Ute=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType,n.readOnly=!0},RD=(e,t,n,i)=>{const o=e._zod.def;ns(o.innerType,t,i);const s=t.seen.get(e);s.ref=o.innerType},Kte=bt("ZodISODateTime",(e,t)=>{VX.init(e,t),xo.init(e,t)});function Vte(e){return Xee(Kte,e)}const Zte=bt("ZodISODate",(e,t)=>{ZX.init(e,t),xo.init(e,t)});function Gte(e){return ete(Zte,e)}const Qte=bt("ZodISOTime",(e,t)=>{GX.init(e,t),xo.init(e,t)});function Yte(e){return tte(Qte,e)}const Jte=bt("ZodISODuration",(e,t)=>{QX.init(e,t),xo.init(e,t)});function Xte(e){return nte(Jte,e)}const ene=(e,t)=>{vD.init(e,t),e.name="ZodError",Object.defineProperties(e,{format:{value:n=>PJ(e,n)},flatten:{value:n=>OJ(e,n)},addIssue:{value:n=>{e.issues.push(n),e.message=JSON.stringify(e.issues,Mb,2)}},addIssues:{value:n=>{e.issues.push(...n),e.message=JSON.stringify(e.issues,Mb,2)}},isEmpty:{get(){return e.issues.length===0}}})},Ol=bt("ZodError",ene,{Parent:Error}),tne=f6(Ol),nne=h6(Ol),ine=o9(Ol),one=s9(Ol),sne=WJ(Ol),rne=qJ(Ol),lne=UJ(Ol),ane=KJ(Ol),une=VJ(Ol),cne=ZJ(Ol),dne=GJ(Ol),fne=QJ(Ol),wo=bt("ZodType",(e,t)=>(Co.init(e,t),Object.assign(e["~standard"],{jsonSchema:{input:b2(e,"input"),output:b2(e,"output")}}),e.toJSONSchema=wte(e,{}),e.def=t,e.type=t.type,Object.defineProperty(e,"_def",{value:t}),e.check=(...n)=>e.clone(jc(t,{checks:[...t.checks??[],...n.map(i=>typeof i=="function"?{_zod:{check:i,def:{check:"custom"},onattach:[]}}:i)]}),{parent:!0}),e.with=e.check,e.clone=(n,i)=>Hc(e,n,i),e.brand=()=>e,e.register=((n,i)=>(n.add(e,i),e)),e.parse=(n,i)=>tne(e,n,i,{callee:e.parse}),e.safeParse=(n,i)=>ine(e,n,i),e.parseAsync=async(n,i)=>nne(e,n,i,{callee:e.parseAsync}),e.safeParseAsync=async(n,i)=>one(e,n,i),e.spa=e.safeParseAsync,e.encode=(n,i)=>sne(e,n,i),e.decode=(n,i)=>rne(e,n,i),e.encodeAsync=async(n,i)=>lne(e,n,i),e.decodeAsync=async(n,i)=>ane(e,n,i),e.safeEncode=(n,i)=>une(e,n,i),e.safeDecode=(n,i)=>cne(e,n,i),e.safeEncodeAsync=async(n,i)=>dne(e,n,i),e.safeDecodeAsync=async(n,i)=>fne(e,n,i),e.refine=(n,i)=>e.check(rie(n,i)),e.superRefine=n=>e.check(lie(n)),e.overwrite=n=>e.check(u1(n)),e.optional=()=>jx(e),e.exactOptional=()=>Vne(e),e.nullable=()=>Hx(e),e.nullish=()=>jx(Hx(e)),e.nonoptional=n=>Xne(e,n),e.array=()=>hi(e),e.or=n=>zne([e,n]),e.and=n=>jne(e,n),e.transform=n=>Wx(e,Une(n)),e.default=n=>Qne(e,n),e.prefault=n=>Jne(e,n),e.catch=n=>tie(e,n),e.pipe=n=>Wx(e,n),e.readonly=()=>oie(e),e.describe=n=>{const i=e.clone();return fp.add(i,{description:n}),i},Object.defineProperty(e,"description",{get(){return fp.get(e)?.description},configurable:!0}),e.meta=(...n)=>{if(n.length===0)return fp.get(e);const i=e.clone();return fp.add(i,n[0]),i},e.isOptional=()=>e.safeParse(void 0).success,e.isNullable=()=>e.safeParse(null).success,e.apply=n=>n(e),e)),zD=bt("_ZodString",(e,t)=>{p6.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(i,o,s)=>Ste(e,i,o);const n=e._zod.bag;e.format=n.format??null,e.minLength=n.minimum??null,e.maxLength=n.maximum??null,e.regex=(...i)=>e.check(ate(...i)),e.includes=(...i)=>e.check(dte(...i)),e.startsWith=(...i)=>e.check(fte(...i)),e.endsWith=(...i)=>e.check(hte(...i)),e.min=(...i)=>e.check(k2(...i)),e.max=(...i)=>e.check(ND(...i)),e.length=(...i)=>e.check(FD(...i)),e.nonempty=(...i)=>e.check(k2(1,...i)),e.lowercase=i=>e.check(ute(i)),e.uppercase=i=>e.check(cte(i)),e.trim=()=>e.check(gte()),e.normalize=(...i)=>e.check(pte(...i)),e.toLowerCase=()=>e.check(mte()),e.toUpperCase=()=>e.check(vte()),e.slugify=()=>e.check(yte())}),hne=bt("ZodString",(e,t)=>{p6.init(e,t),zD.init(e,t),e.email=n=>e.check(Nee(pne,n)),e.url=n=>e.check(Ree(gne,n)),e.jwt=n=>e.check(Jee(Tne,n)),e.emoji=n=>e.check(zee(mne,n)),e.guid=n=>e.check(Bx(Ox,n)),e.uuid=n=>e.check(Fee(Am,n)),e.uuidv4=n=>e.check(Dee(Am,n)),e.uuidv6=n=>e.check(Bee(Am,n)),e.uuidv7=n=>e.check($ee(Am,n)),e.nanoid=n=>e.check(Oee(vne,n)),e.guid=n=>e.check(Bx(Ox,n)),e.cuid=n=>e.check(Pee(yne,n)),e.cuid2=n=>e.check(jee(kne,n)),e.ulid=n=>e.check(Hee(bne,n)),e.base64=n=>e.check(Gee(Mne,n)),e.base64url=n=>e.check(Qee(Ine,n)),e.xid=n=>e.check(Wee(Ane,n)),e.ksuid=n=>e.check(qee(Cne,n)),e.ipv4=n=>e.check(Uee(wne,n)),e.ipv6=n=>e.check(Kee(xne,n)),e.cidrv4=n=>e.check(Vee(Sne,n)),e.cidrv6=n=>e.check(Zee(_ne,n)),e.e164=n=>e.check(Yee(Ene,n)),e.datetime=n=>e.check(Vte(n)),e.date=n=>e.check(Gte(n)),e.time=n=>e.check(Yte(n)),e.duration=n=>e.check(Xte(n))});function Ft(e){return Lee(hne,e)}const xo=bt("ZodStringFormat",(e,t)=>{po.init(e,t),zD.init(e,t)}),pne=bt("ZodEmail",(e,t)=>{zX.init(e,t),xo.init(e,t)}),Ox=bt("ZodGUID",(e,t)=>{$X.init(e,t),xo.init(e,t)}),Am=bt("ZodUUID",(e,t)=>{RX.init(e,t),xo.init(e,t)}),gne=bt("ZodURL",(e,t)=>{OX.init(e,t),xo.init(e,t)}),mne=bt("ZodEmoji",(e,t)=>{PX.init(e,t),xo.init(e,t)}),vne=bt("ZodNanoID",(e,t)=>{jX.init(e,t),xo.init(e,t)}),yne=bt("ZodCUID",(e,t)=>{HX.init(e,t),xo.init(e,t)}),kne=bt("ZodCUID2",(e,t)=>{WX.init(e,t),xo.init(e,t)}),bne=bt("ZodULID",(e,t)=>{qX.init(e,t),xo.init(e,t)}),Ane=bt("ZodXID",(e,t)=>{UX.init(e,t),xo.init(e,t)}),Cne=bt("ZodKSUID",(e,t)=>{KX.init(e,t),xo.init(e,t)}),wne=bt("ZodIPv4",(e,t)=>{YX.init(e,t),xo.init(e,t)}),xne=bt("ZodIPv6",(e,t)=>{JX.init(e,t),xo.init(e,t)}),Sne=bt("ZodCIDRv4",(e,t)=>{XX.init(e,t),xo.init(e,t)}),_ne=bt("ZodCIDRv6",(e,t)=>{eee.init(e,t),xo.init(e,t)}),Mne=bt("ZodBase64",(e,t)=>{tee.init(e,t),xo.init(e,t)}),Ine=bt("ZodBase64URL",(e,t)=>{iee.init(e,t),xo.init(e,t)}),Ene=bt("ZodE164",(e,t)=>{oee.init(e,t),xo.init(e,t)}),Tne=bt("ZodJWT",(e,t)=>{ree.init(e,t),xo.init(e,t)}),OD=bt("ZodNumber",(e,t)=>{MD.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(i,o,s)=>_te(e,i,o),e.gt=(i,o)=>e.check(Rx(i,o)),e.gte=(i,o)=>e.check(n3(i,o)),e.min=(i,o)=>e.check(n3(i,o)),e.lt=(i,o)=>e.check($x(i,o)),e.lte=(i,o)=>e.check(t3(i,o)),e.max=(i,o)=>e.check(t3(i,o)),e.int=i=>e.check(Px(i)),e.safe=i=>e.check(Px(i)),e.positive=i=>e.check(Rx(0,i)),e.nonnegative=i=>e.check(n3(0,i)),e.negative=i=>e.check($x(0,i)),e.nonpositive=i=>e.check(t3(0,i)),e.multipleOf=(i,o)=>e.check(zx(i,o)),e.step=(i,o)=>e.check(zx(i,o)),e.finite=()=>e;const n=e._zod.bag;e.minValue=Math.max(n.minimum??Number.NEGATIVE_INFINITY,n.exclusiveMinimum??Number.NEGATIVE_INFINITY)??null,e.maxValue=Math.min(n.maximum??Number.POSITIVE_INFINITY,n.exclusiveMaximum??Number.POSITIVE_INFINITY)??null,e.isInt=(n.format??"").includes("int")||Number.isSafeInteger(n.multipleOf??.5),e.isFinite=!0,e.format=n.format??null});function en(e){return ite(OD,e)}const Lne=bt("ZodNumberFormat",(e,t)=>{lee.init(e,t),OD.init(e,t)});function Px(e){return ote(Lne,e)}const Nne=bt("ZodBoolean",(e,t)=>{aee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Mte(e,n,i)});function ng(e){return ste(Nne,e)}const Fne=bt("ZodUnknown",(e,t)=>{uee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Ete()});function fs(){return rte(Fne)}const Dne=bt("ZodNever",(e,t)=>{cee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Ite(e,n,i)});function Bne(e){return lte(Dne,e)}const $ne=bt("ZodArray",(e,t)=>{dee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Dte(e,n,i,o),e.element=t.element,e.min=(n,i)=>e.check(k2(n,i)),e.nonempty=n=>e.check(k2(1,n)),e.max=(n,i)=>e.check(ND(n,i)),e.length=(n,i)=>e.check(FD(n,i)),e.unwrap=()=>e.element});function hi(e,t){return kte($ne,e,t)}const Rne=bt("ZodObject",(e,t)=>{hee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Bte(e,n,i,o),Si(e,"shape",()=>t.shape),e.keyof=()=>ho(Object.keys(e._zod.def.shape)),e.catchall=n=>e.clone({...e._zod.def,catchall:n}),e.passthrough=()=>e.clone({...e._zod.def,catchall:fs()}),e.loose=()=>e.clone({...e._zod.def,catchall:fs()}),e.strict=()=>e.clone({...e._zod.def,catchall:Bne()}),e.strip=()=>e.clone({...e._zod.def,catchall:void 0}),e.extend=n=>DJ(e,n),e.safeExtend=n=>BJ(e,n),e.merge=n=>$J(e,n),e.pick=n=>NJ(e,n),e.omit=n=>FJ(e,n),e.partial=(...n)=>RJ(jD,e,n[0]),e.required=(...n)=>zJ(HD,e,n[0])});function Ot(e,t){const n={type:"object",shape:e??{},...pn(t)};return new Rne(n)}const PD=bt("ZodUnion",(e,t)=>{TD.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>$te(e,n,i,o),e.options=t.options});function zne(e,t){return new PD({type:"union",options:e,...pn(t)})}const One=bt("ZodDiscriminatedUnion",(e,t)=>{PD.init(e,t),pee.init(e,t)});function Wc(e,t,n){return new One({type:"union",options:t,discriminator:e,...pn(n)})}const Pne=bt("ZodIntersection",(e,t)=>{gee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Rte(e,n,i,o)});function jne(e,t){return new Pne({type:"intersection",left:e,right:t})}const Hne=bt("ZodRecord",(e,t)=>{mee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>zte(e,n,i,o),e.keyType=t.keyType,e.valueType=t.valueType});function g6(e,t,n){return new Hne({type:"record",keyType:e,valueType:t,...pn(n)})}const Eb=bt("ZodEnum",(e,t)=>{vee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(i,o,s)=>Tte(e,i,o),e.enum=t.entries,e.options=Object.values(t.entries);const n=new Set(Object.keys(t.entries));e.extract=(i,o)=>{const s={};for(const r of i)if(n.has(r))s[r]=t.entries[r];else throw new Error(`Key ${r} not found in enum`);return new Eb({...t,checks:[],...pn(o),entries:s})},e.exclude=(i,o)=>{const s={...t.entries};for(const r of i)if(n.has(r))delete s[r];else throw new Error(`Key ${r} not found in enum`);return new Eb({...t,checks:[],...pn(o),entries:s})}});function ho(e,t){const n=Array.isArray(e)?Object.fromEntries(e.map(i=>[i,i])):e;return new Eb({type:"enum",entries:n,...pn(t)})}const Wne=bt("ZodLiteral",(e,t)=>{yee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Lte(e,n,i),e.values=new Set(t.values),Object.defineProperty(e,"value",{get(){if(t.values.length>1)throw new Error("This schema contains multiple valid literal values. Use `.values` instead.");return t.values[0]}})});function $n(e,t){return new Wne({type:"literal",values:Array.isArray(e)?e:[e],...pn(t)})}const qne=bt("ZodTransform",(e,t)=>{kee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Fte(e,n),e._zod.parse=(n,i)=>{if(i.direction==="backward")throw new dD(e.constructor.name);n.addIssue=s=>{if(typeof s=="string")n.issues.push(S0(s,n.value,t));else{const r=s;r.fatal&&(r.continue=!1),r.code??(r.code="custom"),r.input??(r.input=n.value),r.inst??(r.inst=e),n.issues.push(S0(r))}};const o=t.transform(n.value,n);return o instanceof Promise?o.then(s=>(n.value=s,n)):(n.value=o,n)}});function Une(e){return new qne({type:"transform",transform:e})}const jD=bt("ZodOptional",(e,t)=>{LD.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>RD(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function jx(e){return new jD({type:"optional",innerType:e})}const Kne=bt("ZodExactOptional",(e,t)=>{bee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>RD(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function Vne(e){return new Kne({type:"optional",innerType:e})}const Zne=bt("ZodNullable",(e,t)=>{Aee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Ote(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function Hx(e){return new Zne({type:"nullable",innerType:e})}const Gne=bt("ZodDefault",(e,t)=>{Cee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>jte(e,n,i,o),e.unwrap=()=>e._zod.def.innerType,e.removeDefault=e.unwrap});function Qne(e,t){return new Gne({type:"default",innerType:e,get defaultValue(){return typeof t=="function"?t():gD(t)}})}const Yne=bt("ZodPrefault",(e,t)=>{wee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Hte(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function Jne(e,t){return new Yne({type:"prefault",innerType:e,get defaultValue(){return typeof t=="function"?t():gD(t)}})}const HD=bt("ZodNonOptional",(e,t)=>{xee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Pte(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function Xne(e,t){return new HD({type:"nonoptional",innerType:e,...pn(t)})}const eie=bt("ZodCatch",(e,t)=>{See.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Wte(e,n,i,o),e.unwrap=()=>e._zod.def.innerType,e.removeCatch=e.unwrap});function tie(e,t){return new eie({type:"catch",innerType:e,catchValue:typeof t=="function"?t:()=>t})}const nie=bt("ZodPipe",(e,t)=>{_ee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>qte(e,n,i,o),e.in=t.in,e.out=t.out});function Wx(e,t){return new nie({type:"pipe",in:e,out:t})}const iie=bt("ZodReadonly",(e,t)=>{Mee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Ute(e,n,i,o),e.unwrap=()=>e._zod.def.innerType});function oie(e){return new iie({type:"readonly",innerType:e})}const sie=bt("ZodCustom",(e,t)=>{Iee.init(e,t),wo.init(e,t),e._zod.processJSONSchema=(n,i,o)=>Nte(e,n)});function rie(e,t={}){return bte(sie,e,t)}function lie(e){return Ate(e)}const lf=Ft().min(1),m6=Ft().min(1),ig=Ft().min(1),af=Ft().min(1),vl=Ft().min(1),aie=/^[A-Za-z0-9._-]{1,128}$/;function uie(e){return aie.test(e)&&e!=="."&&e!==".."}const WD=Wc("kind",[Ot({kind:$n("user"),payload:fs().optional()}),Ot({kind:$n("cron"),taskId:af.optional(),payload:fs().optional()}),Ot({kind:$n("task"),taskId:af,payload:fs().optional()}),Ot({kind:$n("hook"),payload:fs().optional()}),Ot({kind:$n("compaction"),payload:fs().optional()}),Ot({kind:$n("side"),payload:fs().optional()}),Ot({kind:$n("other"),payload:fs().optional()})]),cie=Ot({inputTokens:en().optional(),outputTokens:en().optional(),cachedTokens:en().optional(),cost:en().optional()}),Rp=Ot({inputOther:en(),output:en(),inputCacheRead:en(),inputCacheCreation:en()}),die=Ot({llmFirstTokenLatencyMs:en().optional(),llmStreamDurationMs:en().optional(),llmRequestBuildMs:en().optional(),llmServerFirstTokenMs:en().optional(),llmServerDecodeMs:en().optional(),llmClientConsumeMs:en().optional()}),fie=Ot({failedAttempt:en(),nextAttempt:en(),maxAttempts:en(),delayMs:en(),errorName:Ft(),errorMessage:Ft(),statusCode:en().optional()}),qD=ho(["queued","running","completed","failed","cancelled"]),hie=ho(["running","completed","interrupted","failed"]),pie=Ot({kind:$n("text"),frameId:ig,role:ho(["assistant","user"]),text:Ft(),attachmentIds:hi(Ft()).optional(),taskId:af.optional()}),gie=Ot({kind:$n("thinking"),frameId:ig,text:Ft()}),mie=Ot({agentId:vl,role:ho(["child","member"]).optional()}),vie=Ot({kind:ho(["stdout","stderr","progress","status","custom"]),text:Ft().optional(),percent:en().optional(),customKind:Ft().optional(),customData:fs().optional()}),yie=Ot({kind:$n("tool"),frameId:ig,toolCallId:Ft(),name:Ft(),view:Ft().optional(),state:ho(["running","done","error"]),input:fs().optional(),output:fs().optional(),display:fs().optional(),error:Ft().optional(),inputText:Ft().optional(),progress:vie.optional(),taskId:af.optional(),approvalId:Ft().optional(),todoId:Ft().optional(),agentRefs:hi(mie).optional()}),v6=Ot({interactionId:Ft(),interactionKind:ho(["approval","question"]),toolCallId:Ft().optional(),state:ho(["pending","approved","rejected","cancelled","answered","dismissed"]),request:fs().optional(),response:fs().optional()}),kie=Ot({kind:$n("notice"),frameId:ig,level:ho(["error","warning","info"]),source:Ft().optional(),message:Ft(),detail:fs().optional()}),UD=Wc("kind",[pie,gie,yie,kie]),KD=Ot({kind:$n("step"),stepId:m6,turnId:lf,ordinal:en().int(),state:hie,frames:hi(UD),startedAt:Ft().optional(),endedAt:Ft().optional(),usage:Rp.optional(),finishReason:Ft().optional(),timing:die.optional(),retry:fie.optional(),endReason:Ft().optional(),endMessage:Ft().optional()}),VD=Ot({kind:$n("turn"),turnId:lf,ordinal:en().int(),state:qD,origin:WD,prompt:Ft().optional(),attachmentIds:hi(Ft()).optional(),steps:hi(KD),startedAt:Ft().optional(),endedAt:Ft().optional(),usage:cie.optional(),durationMs:en().optional(),error:Ft().optional()}),ZD=Ot({kind:$n("marker"),markerId:Ft(),marker:Ft(),payload:fs().optional(),at:Ft().optional()}),GD=Ot({kind:$n("taskref"),refId:Ft(),taskId:af,at:Ft().optional()}),QD=Wc("kind",[VD,ZD,GD]),y6=Ot({taskId:af,kind:ho(["shell","subagent","tool","other"]),state:ho(["running","completed","failed","timed_out","killed","lost"]),detached:ng(),description:Ft().optional(),agentId:vl.optional(),outputTail:Ft(),startedAt:Ft().optional(),endedAt:Ft().optional(),resultSummary:Ft().optional(),error:Ft().optional(),stateReason:Ft().optional(),usage:Rp.optional()}),YD=Ot({objective:Ft(),status:ho(["active","paused","blocked","complete"]),completionCriterion:Ft().optional(),budgetUsed:en().optional(),budgetLimit:en().optional()}),bie=Ot({plan:Ot({reviewPath:Ft().optional(),version:en().optional()}).optional(),swarm:Ot({trigger:Ft().optional()}).optional(),tower:Ot({}).optional()}),Aie=Ot({plan:Ot({reviewPath:Ft().optional(),version:en().optional()}).nullable().optional(),swarm:Ot({trigger:Ft().optional()}).nullable().optional(),tower:Ot({}).nullable().optional()}),Cie=Wc("kind",[Ot({kind:$n("idle")}),Ot({kind:$n("running"),turnId:en(),step:en(),stepId:Ft(),since:en()}),Ot({kind:$n("streaming"),turnId:en(),step:en(),stepId:Ft(),stream:ho(["assistant","thinking","tool_call"]),toolCallId:Ft().optional(),toolName:Ft().optional(),since:en()}),Ot({kind:$n("tool_call"),turnId:en(),step:en(),toolCallId:Ft(),name:Ft(),since:en()}),Ot({kind:$n("retrying"),turnId:en(),step:en(),stepId:Ft(),failedAttempt:en(),nextAttempt:en(),maxAttempts:en(),delayMs:en(),errorName:Ft().optional(),statusCode:en().optional(),since:en()}),Ot({kind:$n("awaiting_approval"),turnId:en(),step:en().optional(),approval:fs().optional(),since:en()}),Ot({kind:$n("interrupted"),turnId:en(),step:en().optional(),reason:ho(["aborted","max_steps","error"]),message:Ft().optional(),at:en()}),Ot({kind:$n("ended"),turnId:en(),reason:ho(["completed","cancelled","failed","blocked"]),durationMs:en().optional(),at:en()})]),wie=Ot({byModel:g6(Ft(),Rp).optional(),currentTurn:Rp.optional(),total:Rp.optional()}),xie=Ot({model:Ft().optional(),thinkingEffort:Ft().optional(),usage:wie.optional(),contextTokens:en().optional(),maxContextTokens:en().optional(),contextUsage:en().optional(),permission:ho(["manual","yolo","auto"]).optional(),phase:Cie.optional()}),k6=Ot({goal:YD.optional(),modes:bie.optional(),activity:ho(["idle","turn","disposing","unknown"]).optional(),agent:xie.optional()}),Sie=k6.extend({goal:YD.nullable().optional(),modes:Aie.optional()}),l9=Ot({attachmentId:Ft(),mediaType:Ft(),name:Ft().optional(),size:en().optional(),source:Wc("kind",[Ot({kind:$n("url"),url:Ft()}),Ot({kind:$n("file"),fileId:Ft()}),Ot({kind:$n("session_media"),fileId:Ft()})]).optional(),placeholder:Ft().optional()}),_ie=Ot({title:Ft(),status:ho(["pending","in_progress","done"])}),b6=Ot({todoId:Ft(),items:hi(_ie),updatedAt:Ft().optional()}),A6=Ot({promptId:Ft(),status:ho(["running","queued","blocked","completed","failed","aborted"]),userMessageId:Ft().optional(),content:fs().optional(),createdAt:Ft(),finishedAt:Ft().optional(),steeredAt:Ft().optional()}),JD=Ot({items:hi(QD),tasks:hi(y6),interactions:hi(v6).default([]),attachments:hi(l9).default([]),todos:hi(b6).default([]),prompts:hi(A6).default([]),meta:k6,hasMoreOlder:ng().optional()}),Mie=VD.omit({steps:!0}),Iie=KD.omit({frames:!0}),Eie=Wc("type",[Ot({type:$n("frame"),turnId:lf,stepId:m6,frameId:ig}),Ot({type:$n("task"),taskId:af})]),C6=Wc("op",[Ot({op:$n("reset"),agentId:vl,snapshot:JD}),Ot({op:$n("turn.upsert"),turn:Mie}),Ot({op:$n("step.upsert"),turnId:lf,step:Iie}),Ot({op:$n("frame.upsert"),turnId:lf,stepId:m6,frame:UD}),Ot({op:$n("append"),target:Eie,offset:en().int().nonnegative(),text:Ft()}),Ot({op:$n("marker.upsert"),item:ZD,beforeTurn:en().int().optional()}),Ot({op:$n("taskref.upsert"),item:GD,beforeTurn:en().int().optional()}),Ot({op:$n("task.upsert"),task:y6}),Ot({op:$n("interaction.upsert"),interaction:v6}),Ot({op:$n("attachment.upsert"),attachment:l9}),Ot({op:$n("todo.upsert"),todo:b6}),Ot({op:$n("prompt.upsert"),prompt:A6}),Ot({op:$n("meta.merge"),meta:Sie}),Ot({op:$n("items.remove"),ids:hi(Ft())})]);Ot({agentId:vl,ops:hi(C6)});const Tie=ho(["off","turn","block","delta"]),Xh=en().int().nonnegative(),Lie=g6(Ft(),Tie);Ot({session_id:Ft().min(1),transcript:Lie,transcript_since:g6(Ft(),Xh).optional()});Ot({agent_id:vl,before_turn:Ft().min(1).optional(),after_turn:Ft().min(1).optional(),page_size:en().int().min(1).max(100).optional()}).superRefine((e,t)=>{e.before_turn!==void 0&&e.after_turn!==void 0&&t.addIssue({code:"custom",message:"before_turn and after_turn are mutually exclusive",path:["before_turn"]}),uie(e.agent_id)||t.addIssue({code:"custom",message:"agent_id must be a plain agent id (no path separators)",path:["agent_id"]})});const Nie=Ot({agentId:vl,type:ho(["main","sub","independent"]).optional(),parentAgentId:vl.optional(),label:Ft().optional(),createdAt:Ft().optional(),disposedAt:Ft().optional()}),Fie=Ot({agent_id:vl,items:hi(QD),has_more:ng(),tasks:hi(y6),interactions:hi(v6).default([]),attachments:hi(l9).default([]),todos:hi(b6).default([]),prompts:hi(A6).default([]),meta:k6,agents:hi(Nie),pending_interactions:hi(Ft()),seq:Xh.optional()});Ot({agent_id:vl,batches:hi(Ot({seq:Xh,ops:hi(C6)})),latest_seq:Xh,complete:ng()});const Die=Ot({turn_id:lf,ordinal:en().int(),state:qD,origin:WD,prompt:Ft(),attachment_ids:hi(Ft()).optional(),started_at:Ft().optional()});Ot({agents:hi(Ot({agent_id:vl,messages:hi(Die),attachments:hi(l9).default([])}))});const Bie=Ot({state:ho(["pending","approved","rejected","cancelled"]),selected_option:Ft().optional(),feedback:Ft().optional()}),$ie=Ot({tool_call_id:Ft(),turn_id:lf,source:ho(["interaction","display","output"]),plan:Ft(),path:Ft().optional(),options:hi(Ot({label:Ft(),description:Ft().optional()})).optional(),review:Bie.optional()});Ot({agent_id:vl,plans:hi($ie)});const Rie=Ot({agent_id:vl,snapshot:JD,has_more_older:ng(),seq:Xh.optional()}),zie=Ot({agent_id:vl,ops:hi(C6),seq:Xh.optional()}),XD=Rie.extend({type:$n("transcript.reset")}),eB=zie.extend({type:$n("transcript.ops")});Wc("type",[XD,eB]);const qx=new Set(["turn.started","turn.step.started","turn.step.completed","turn.step.retrying","turn.step.interrupted","turn.ended","thinking.delta","assistant.delta","tool.call.started","tool.use","tool.call.delta","tool.progress","tool.result","agent.status.updated","prompt.submitted","prompt.completed","prompt.aborted","session.meta.updated","compaction.started","compaction.completed","compaction.cancelled","goal.updated","error","warning","subagent.spawned","subagent.started","subagent.suspended","subagent.completed","subagent.failed","task.started","task.terminated","background.task.started","background.task.terminated","cron.fired"]),Oie=new Set(["session.created","session.updated","session.deleted","session.status_changed","session.usage_updated","session.history_compacted","message.created","message.updated","approval.requested","approval.resolved","approval.expired","question.requested","question.answered","question.dismissed","task.created","task.progress","task.completed","assistant.tool_use_started","assistant.tool_use_delta","assistant.tool_use_completed","assistant.completed","tool.started","tool.output","tool.completed"]),Pie=new Set(["server_hello","ack","ping","resync_required","error","pong"]),jie=new Set(["assistant.delta","thinking.delta"]);function Hie(e,t){if(Pie.has(e))return{route:"ignore"};const n=e.startsWith("event."),i=n?e.slice(6):e;return jie.has(i)?Wie(t)?{route:"agent",agentType:i}:{route:"protocol"}:n?Oie.has(i)?{route:"protocol"}:qx.has(i)?{route:"agent",agentType:i}:{route:"protocol"}:qx.has(i)?{route:"agent",agentType:i}:{route:"agent",agentType:i}}function Wie(e){if(!e||typeof e!="object")return!1;const t=e;return"message_id"in t||"content_index"in t?!1:typeof t.delta=="string"}const qie="kimi-code.bearer.",Uie=3e4;class Kie{constructor(t){this.opts=t,this.tracer=t.tracer??s6}ws=null;connected=!1;closed=!1;subscriptions=new Map;transcriptSubscriptions=new Map;sideChannelAgents=new Map;pendingSubscriptions=[];terminalAttachments=new Map;msgSeq=0;clientHelloId=null;reconnectAttempts=0;reconnectTimer=null;heartbeatMs=3e4;lastActivityAt=0;tracer;connect(){if(this.ws!==null||this.closed)return;this.lastActivityAt=Date.now(),this.tracer.wsEvent?.({kind:"lifecycle",event:"connect",detail:{url:this.opts.wsUrl,attempt:this.reconnectAttempts}});const t=this.opts.credentialStore?.getToken(),n=t!==void 0?[`${qie}${t}`]:void 0,i=new WebSocket(this.opts.wsUrl,n);this.ws=i,i.onopen=()=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"open"})},i.onmessage=o=>{this.lastActivityAt=Date.now();try{const s=JSON.parse(String(o.data));this.tracer.wsEvent?.({kind:"in",frame:s}),this.handleFrame(s)}catch(s){this.tracer.wsEvent?.({kind:"lifecycle",event:"parse-error",detail:{error:String(s)}}),this.opts.handlers.onError(0,`Failed to parse WS frame: ${String(s)}`,!1)}},i.onerror=()=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"error"}),this.opts.handlers.onError(0,"WebSocket error",!1)},i.onclose=o=>{this.tracer.wsEvent?.({kind:"lifecycle",event:"close",detail:o?{code:o.code,reason:o.reason,wasClean:o.wasClean}:void 0}),this.connected=!1,this.ws=null,this.opts.handlers.onConnectionState(!1),this.scheduleReconnect()}}scheduleReconnect(){if(this.closed||this.reconnectTimer!==null)return;const n=Math.min(3e4,1e3*2**this.reconnectAttempts)+Math.floor(Math.random()*250);this.reconnectAttempts+=1,this.tracer.wsEvent?.({kind:"lifecycle",event:"reconnect-scheduled",detail:{delayMs:n,attempt:this.reconnectAttempts}}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},n)}subscribe(t,n={seq:0}){if(this.subscriptions.set(t,{...n}),this.connected)this.sendSubscribe([t],{[t]:n});else{const i=this.pendingSubscriptions.findIndex(o=>o.sessionId===t);i!==-1&&this.pendingSubscriptions.splice(i,1),this.pendingSubscriptions.push({sessionId:t,cursor:{...n}})}}unsubscribe(t){this.subscriptions.delete(t);const n=this.pendingSubscriptions.findIndex(i=>i.sessionId===t);n!==-1&&this.pendingSubscriptions.splice(n,1),this.connected&&this.ws&&this.send({type:"unsubscribe",id:this.nextId(),payload:{session_ids:[t]}})}subscribeTranscript(t,n,i){this.transcriptSubscriptions.set(t,{agentId:n,...i!==void 0?{sinceSeq:i}:{}}),this.connected&&this.sendTranscriptSubscribe(t,n,i)}unsubscribeTranscript(t,n){const i=this.transcriptSubscriptions.get(t);(n===void 0||i===void 0||n.includes(i.agentId))&&this.transcriptSubscriptions.delete(t),!(!this.connected||!this.ws)&&this.send({type:"unsubscribe_v2",id:this.nextId(),payload:{session_id:t,...n!==void 0?{agent_ids:n}:{}}})}markSideChannelAgent(t,n){if(!this.opts.mainAgentOnly)return;let i=this.sideChannelAgents.get(t);if(i===void 0&&(i=new Set,this.sideChannelAgents.set(t,i)),i.has(n))return;i.add(n);const o=this.subscriptions.get(t);this.connected&&o!==void 0&&this.sendSubscribe([t],{[t]:o})}abort(t,n){!this.connected||!this.ws||this.send({type:"abort",id:this.nextId(),payload:{session_id:t,prompt_id:n}})}terminalAttach(t,n,i){const o=Cm(t,n),s=this.terminalAttachments.get(o),r=i??s?.lastSeq??0;this.terminalAttachments.set(o,{sessionId:t,terminalId:n,lastSeq:r}),!(!this.connected||!this.ws)&&this.sendTerminalAttach(t,n,r)}terminalInput(t,n,i){!this.connected||!this.ws||this.send({type:"terminal_input",id:this.nextId(),payload:{session_id:t,terminal_id:n,data:i}})}terminalResize(t,n,i,o){!this.connected||!this.ws||this.send({type:"terminal_resize",id:this.nextId(),payload:{session_id:t,terminal_id:n,cols:i,rows:o}})}terminalDetach(t,n){this.terminalAttachments.delete(Cm(t,n)),!(!this.connected||!this.ws)&&this.send({type:"terminal_detach",id:this.nextId(),payload:{session_id:t,terminal_id:n}})}terminalClose(t,n){this.terminalAttachments.delete(Cm(t,n)),!(!this.connected||!this.ws)&&this.send({type:"terminal_close",id:this.nextId(),payload:{session_id:t,terminal_id:n}})}close(){this.closed=!0,this.connected=!1,this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.ws&&(this.ws.close(1e3),this.ws=null)}health(){const t=this.ws!==null&&this.ws.readyState===WebSocket.OPEN,n=Math.max(this.heartbeatMs*2,Uie),i=this.lastActivityAt>0&&Date.now()-this.lastActivityAt>n;return{connected:this.connected,open:t,stale:i}}reconnect(){if(this.closed)return;this.reconnectTimer!==null&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null);const t=this.ws;if(t!==null){t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null;try{t.close(1e3,"reconnect")}catch{}}const n=this.connected;this.ws=null,this.connected=!1,n&&this.opts.handlers.onConnectionState(!1),this.connect()}handleFrame(t){const n=t,i=t.type;if(i==="transcript.reset"){const o=XD.safeParse({type:i,...n.payload}),s=n.session_id;if(!o.success||typeof s!="string"){this.opts.handlers.onError(0,"Invalid transcript.reset frame",!1);return}const r=o.data;this.opts.handlers.onTranscriptReset?.(s,r.agent_id,{...r.snapshot,hasMoreOlder:r.has_more_older},r.seq);const l=this.transcriptSubscriptions.get(s);l?.agentId===r.agent_id&&r.seq!==void 0&&(l.sinceSeq=r.seq);return}if(i==="transcript.ops"){const o=eB.safeParse({type:i,...n.payload}),s=n.session_id;if(!o.success||typeof s!="string"){this.opts.handlers.onError(0,"Invalid transcript.ops frame",!1);return}const r=o.data,l=this.opts.handlers.onTranscriptOps?.(s,r.agent_id,r.ops,r.seq),a=this.transcriptSubscriptions.get(s);l!==!1&&a?.agentId===r.agent_id&&r.seq!==void 0&&(a.sinceSeq=r.seq);return}switch(i){case"server_hello":{const o=n.payload?.heartbeat_ms;typeof o=="number"&&o>0&&(this.heartbeatMs=o),this.onServerHello();break}case"ping":this.send({type:"pong",payload:{nonce:n.payload.nonce}});break;case"resync_required":{const o=n.payload.session_id,s=n.payload.epoch;this.subscriptions.set(o,{seq:n.payload.current_seq,epoch:s}),this.opts.handlers.onResync(o,n.payload.current_seq,s);break}case"error":{const o=n.session_id;typeof o=="string"&&this.opts.handlers.onRawAgentEvent?this.opts.handlers.onRawAgentEvent({type:"error",seq:n.seq,session_id:o,timestamp:n.timestamp,payload:n.payload}):this.opts.handlers.onError(n.payload.code,n.payload.msg,n.payload.fatal);break}case"ack":n.id===this.clientHelloId&&(this.clientHelloId=null,n.code===0&&this.opts.handlers.onReplayComplete?.());break;case"terminal_output":{const o=n.session_id,s=n.terminal_id,r=n.seq,l=Cm(o,s),a=this.terminalAttachments.get(l);a&&this.terminalAttachments.set(l,{...a,lastSeq:Math.max(a.lastSeq,r)});const u=typeof n.payload?.data=="string"?n.payload.data:"";this.opts.handlers.onTerminalOutput?.(o,s,u,r);break}case"terminal_exit":{const o=n.session_id,s=n.terminal_id,r=n.payload?.exit_code,l=typeof r=="number"?r:null;this.opts.handlers.onTerminalExit?.(o,s,l);break}default:{this.trackCursor(n);const o=n.type,s=Hie(o,n.payload);if(s.route==="protocol"){this.opts.handlers.onWireEvent(n);break}if(s.route==="agent"){if(this.opts.handlers.onRawAgentEvent&&typeof n.session_id=="string"){const r=n,l=n;this.opts.handlers.onRawAgentEvent({type:s.agentType,seq:r.seq,session_id:r.session_id,timestamp:r.timestamp,payload:r.payload,...l.volatile!==void 0?{volatile:l.volatile}:{},...l.offset!==void 0?{offset:l.offset}:{}})}break}break}}}onServerHello(){this.connected=!0,this.reconnectAttempts=0,this.opts.handlers.onConnectionState(!0);const t=Array.from(this.subscriptions.keys());for(const o of this.pendingSubscriptions)this.subscriptions.set(o.sessionId,o.cursor),t.includes(o.sessionId)||t.push(o.sessionId);this.pendingSubscriptions.length=0;const n={};for(const[o,s]of this.subscriptions.entries())n[o]=s;const i=this.nextId();this.clientHelloId=i,this.send({type:"client_hello",id:i,payload:{client_id:this.opts.clientId,subscriptions:t,cursors:n,...this.opts.mainAgentOnly?{agent_filter:this.rawAgentFilter(t)}:{}}});for(const[o,s]of this.transcriptSubscriptions)this.sendTranscriptSubscribe(o,s.agentId,s.sinceSeq);for(const o of this.terminalAttachments.values())this.sendTerminalAttach(o.sessionId,o.terminalId,o.lastSeq)}sendSubscribe(t,n){this.send({type:"subscribe",id:this.nextId(),payload:{session_ids:t,cursors:n,...this.opts.mainAgentOnly?{agent_filter:this.rawAgentFilter(t)}:{}}})}rawAgentFilter(t){return Object.fromEntries(t.map(n=>[n,["main",...this.sideChannelAgents.get(n)??[]]]))}sendTranscriptSubscribe(t,n,i){this.send({type:"subscribe_v2",id:this.nextId(),payload:{session_id:t,transcript:{[n]:"delta"},...i!==void 0?{transcript_since:{[n]:i}}:{}}})}sendTerminalAttach(t,n,i){this.send({type:"terminal_attach",id:this.nextId(),payload:{session_id:t,terminal_id:n,since_seq:i>0?i:void 0}})}trackCursor(t){if(t.volatile===!0)return;const n=t.session_id,i=t.seq;if(typeof n!="string"||typeof i!="number")return;const o=this.subscriptions.get(n);if(!o||i<=o.seq&&o.epoch!==void 0)return;const s=typeof t.epoch=="string"?t.epoch:o.epoch;this.subscriptions.set(n,{seq:Math.max(i,o.seq),epoch:s})}send(t){if(!(!this.ws||this.ws.readyState!==WebSocket.OPEN))try{this.ws.send(JSON.stringify(t)),this.tracer.wsEvent?.({kind:"out",frame:t})}catch{}}nextId(){return`c_${++this.msgSeq}`}}function Cm(e,t){return`${e}\0${t}`}async function Vie(e,t,n){const i=await e.get(`/sessions/${encodeURIComponent(t)}/transcript`,{agent_id:n.agentId,before_turn:n.beforeTurn,after_turn:n.afterTurn,page_size:n.pageSize}),o=Fie.parse(i),s={items:o.items,tasks:o.tasks,interactions:o.interactions,attachments:o.attachments,todos:o.todos,prompts:o.prompts,meta:o.meta,hasMoreOlder:o.has_more};return{agentId:o.agent_id,...s,agents:o.agents,pendingInteractions:o.pending_interactions,...o.seq!==void 0?{seq:o.seq}:{}}}const i3=10485760,Zie=5e3,Ux=40001;function Gie(e,t){if(e===void 0)return t;let n;const i=/filename\*\s*=\s*UTF-8''([^;]+)/i.exec(e)?.[1]?.trim();if(i!==void 0)try{n=decodeURIComponent(i.replaceAll(/^"|"$/g,""))}catch{return t}else n=/filename\s*=\s*"([^"]*)"/i.exec(e)?.[1]??/filename\s*=\s*([^;]+)/i.exec(e)?.[1]?.trim();return n===void 0||n.length===0||n.length>200||n==="."||n===".."||/[\u0000-\u001F\u007F/\\]/.test(n)||!n.toLowerCase().endsWith(".zip")?t:n}function Kx(e){if(typeof e!="object"||e===null)return{errorName:typeof e};const t=e;return{errorName:typeof t.name=="string"?t.name:"Error",errorCode:typeof t.code=="number"?t.code:void 0,requestId:typeof t.requestId=="string"?t.requestId:void 0,phase:typeof t.phase=="string"?t.phase:void 0,httpStatus:typeof t.status=="number"?t.status:void 0}}function o3(e){return{id:e.id,sessionId:e.session_id,cwd:e.cwd,shell:e.shell,cols:e.cols,rows:e.rows,status:e.status,createdAt:e.created_at,exitedAt:e.exited_at,exitCode:e.exit_code}}function Vx(e){return e==="auto_compact"||e==="manual_compact"}class Qie{constructor(t){this.opts=t,this.tracer=t.tracer??s6,this.http=new vx({origin:t.origin,identity:t.identity,tracer:this.tracer,credentialStore:t.credentialStore}),this.httpV2=new vx({origin:t.origin,identity:t.identity,tracer:this.tracer,credentialStore:t.credentialStore,restBasePath:"/api/v2"})}http;httpV2;tracer;async getHealth(){return{status:"ok",uptimeSec:(await this.http.get("/healthz")).uptime_sec??0}}async getMeta(){const t=await this.http.get("/meta");return{serverVersion:t.server_version,serverId:t.server_id,startedAt:t.started_at,capabilities:t.capabilities,openInApps:Array.isArray(t.open_in_apps)?t.open_in_apps:[],dangerousBypassAuth:t.dangerous_bypass_auth===!0,experimentalFlags:t.experimental_flags??{},backend:t.backend==="v2"?"v2":"v1",webTitle:t.web_title??""}}async listSessions(t){const n={before_id:t?.beforeId,after_id:t?.afterId,page_size:t?.pageSize,busy:t?.busy,include_archive:t?.includeArchive,archived_only:t?.archivedOnly,exclude_empty:t?.excludeEmpty,workspace_id:t?.workspaceId},i=await this.http.get("/sessions",n);return{items:i.items.map(Vl),hasMore:i.has_more}}async listSessionsV2(t){const n={sort:t?.sort,page_size:t?.pageSize,page_token:t?.pageToken,page:t?.page,"meta.updated_after":t?.updatedAfter,"meta.updated_before":t?.updatedBefore,"meta.archived":t?.archived===void 0?void 0:String(t.archived),include:t?.include,"workspace.id":t?.workspaceIds,"activity.status":t?.statuses},i=await this.httpV2.get("/sessions",n);return{items:i.items,hasMore:i.has_more,nextPageToken:i.next_page_token,total:i.total}}async listSessionIdsV2(t){const n={sort:t?.sort,page_size:t?.pageSize,page_token:t?.pageToken,page:t?.page,"meta.updated_after":t?.updatedAfter,"meta.updated_before":t?.updatedBefore,"meta.archived":t?.archived===void 0?void 0:String(t.archived),fields:"id,archived","workspace.id":t?.workspaceIds,"activity.status":t?.statuses},i=await this.httpV2.get("/sessions",n);return{items:i.items,hasMore:i.has_more,nextPageToken:i.next_page_token,total:i.total}}async listSessionGroupsV2(t){const n={view:"by_workspace","group.page_size":t?.groupPageSize,"meta.has_prompt":t?.hasPrompt===void 0?void 0:String(t.hasPrompt),sort:t?.sort,page_size:t?.pageSize,page_token:t?.pageToken,"meta.archived":t?.archived===void 0?void 0:String(t.archived),"workspace.id":t?.workspaceIds,"activity.status":t?.statuses},i=await this.httpV2.get("/sessions",n);return{groups:i.groups,hasMore:i.has_more,nextPageToken:i.next_page_token,total:i.total}}async createSession(t){const n={metadata:t.cwd!==void 0?{cwd:t.cwd}:{}};t.workspaceId!==void 0&&(n.workspace_id=t.workspaceId),t.title!==void 0&&(n.title=t.title),t.model!==void 0&&(n.agent_config={model:t.model});const i=await this.http.post("/sessions",n);return Vl(i)}async getSession(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}`);return Vl(n)}async updateSession(t,n){const i={};n.title!==void 0&&(i.title=n.title),n.cwd!==void 0&&(i.metadata={cwd:n.cwd});const o={};n.model!==void 0&&(o.model=n.model),n.permissionMode!==void 0&&(o.permission_mode=n.permissionMode),n.planMode!==void 0&&(o.plan_mode=n.planMode),n.swarmMode!==void 0&&(o.swarm_mode=n.swarmMode),n.goalObjective!==void 0&&(o.goal_objective=n.goalObjective),n.goalControl!==void 0&&(o.goal_control=n.goalControl),n.thinking!==void 0&&(o.thinking=n.thinking),Object.keys(o).length>0&&(i.agent_config=o);const s=await this.http.post(`/sessions/${encodeURIComponent(t)}/profile`,i);return Vl(s)}async getSessionStatus(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}/status`);return{model:n.model&&n.model.length>0?n.model:null,thinkingEffort:n.thinking_level,permission:n.permission,planMode:n.plan_mode===!0,swarmMode:n.swarm_mode===!0,contextTokens:n.context_tokens??0,maxContextTokens:n.max_context_tokens??0,contextUsage:n.context_usage??0}}async getSessionGoal(t){const n=await this.http.get(`/sessions/${encodeURIComponent(t)}/goal`);return aD(n)}async getSessionPlans(t,n){const i=await this.http.get(`/sessions/${encodeURIComponent(t)}/transcript/plan`,{agent_id:n.agentId,tool_call_id:n.toolCallId});return i.plans.map(o=>({agentId:i.agent_id,toolCallId:o.tool_call_id,turnId:o.turn_id,source:o.source,plan:o.plan,...o.path!==void 0?{path:o.path}:{},...o.options!==void 0?{options:o.options.map(s=>({label:s.label,...s.description!==void 0?{description:s.description}:{}}))}:{},...o.review!==void 0?{review:{state:o.review.state,...o.review.selected_option!==void 0?{selectedOption:o.review.selected_option}:{},...o.review.feedback!==void 0?{feedback:o.review.feedback}:{}}}:{}}))}async getSessionWarnings(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/warnings`)).warnings??[]}async archiveSession(t){return await this.http.post(`/sessions/${encodeURIComponent(t)}:archive`,{})}async restoreSession(t){const n=await this.http.post(`/sessions/${encodeURIComponent(t)}:restore`,{});return Vl(n)}async archiveSessions(t){return this.httpV2.post("/sessions:archive",{ids:t})}async restoreSessions(t){return this.httpV2.post("/sessions:restore",{ids:t})}async listMessages(t,n){const i={before_id:n?.beforeId,after_id:n?.afterId,page_size:n?.pageSize,role:n?.role},o=await this.http.get(`/sessions/${encodeURIComponent(t)}/messages`,i);return{items:o.items.map(xb),hasMore:o.has_more}}async getSessionSnapshot(t){const n=Date.now();this.tracer.traceKeyEvent?.("session:snapshot:start",{sessionId:t});try{const i=await this.http.get(`/sessions/${encodeURIComponent(t)}/snapshot`),o={asOfSeq:i.as_of_seq,epoch:i.epoch,session:Vl(i.session),messages:i.messages.items.map(xb),hasMoreMessages:i.messages.has_more,inFlightTurn:i.in_flight_turn===null?null:{turnId:i.in_flight_turn.turn_id,assistantText:i.in_flight_turn.assistant_text,thinkingText:i.in_flight_turn.thinking_text,runningTools:i.in_flight_turn.running_tools.map(s=>({toolCallId:s.tool_call_id,name:s.name,args:s.args,description:s.description,lastProgress:s.last_progress})),promptId:i.in_flight_turn.current_prompt_id},pendingApprovals:i.pending_approvals.map(rD),pendingQuestions:i.pending_questions.map(lD),subagents:(i.subagents??[]).map(s=>yv(s,s.id))};return this.tracer.traceKeyEvent?.("session:snapshot:accepted",{sessionId:t,busy:o.session.busy,seq:o.asOfSeq,messageCount:o.messages.length,durationMs:Date.now()-n}),o}catch(i){throw this.tracer.traceKeyEvent?.("session:snapshot:failed",{sessionId:t,status:"failed",durationMs:Date.now()-n,...Kx(i)}),i}}async getSessionTranscript(t,n){return Vie(this.http,t,n)}async exportSession(t,n,i){const o=n===void 0?0:new TextEncoder().encode(n).byteLength,s=n===void 0||n.length===0?0:n.split(` -`).length,r=`/sessions/${encodeURIComponent(t)}/export`,l={web_log_bytes:o,web_log_entries:s},a=i?.desktop===!0;let u;try{u=await this.http.postZip(r,{web_log:n,...a?{desktop:!0}:{}},l)}catch(d){if(a&&ko(d)&&d.code===Ux)u=await this.http.postZip(r,{web_log:n},l);else throw d}const c=`${t}.zip`;return{blob:u.blob,fileName:Gie(u.contentDisposition,c)}}async submitPrompt(t,n){const i=Date.now();this.tracer.traceKeyEvent?.("prompt:start",{sessionId:t,contentCount:n.content.length,mediaCount:n.content.filter(o=>o.type==="image"||o.type==="video"||o.type==="file").length});try{const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts`,qY(n));return this.tracer.traceKeyEvent?.("prompt:accepted",{sessionId:t,promptId:o.prompt_id,status:o.status,durationMs:Date.now()-i}),{promptId:o.prompt_id,userMessageId:o.user_message_id,status:o.status}}catch(o){throw this.tracer.traceKeyEvent?.("prompt:failed",{sessionId:t,status:"failed",durationMs:Date.now()-i,...Kx(o)}),o}}async steerPrompts(t,n){const i=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts:steer`,{prompt_ids:n});return{steered:i.steered,promptIds:i.prompt_ids}}async abortPrompt(t,n){const i=await this.http.post(`/sessions/${encodeURIComponent(t)}/prompts/${encodeURIComponent(n)}:abort`,void 0,{allowCodes:[40903]});return{aborted:i.aborted,atSeq:i.at_seq}}async abortSession(t){return{aborted:(await this.http.post(`/sessions/${encodeURIComponent(t)}:abort`,{})).aborted}}async compactSession(t,n){await this.http.post(`/sessions/${encodeURIComponent(t)}:compact`,n?{instruction:n}:{})}async undoSession(t,n=1){await this.http.post(`/sessions/${encodeURIComponent(t)}:undo`,{count:n})}async generateSessionTitle(t,n){try{const i={};n?.force===!0&&(i.force=!0),n?.source!==void 0&&(i.source=n.source);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/title/generate`,i);return typeof o?.title=="string"&&o.title.length>0?o.title:null}catch{return null}}async forkSession(t,n){const i={};n?.title!==void 0&&(i.title=n.title);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}:fork`,i,{timeoutMs:px});return Vl(o)}async createChildSession(t,n){const i={};n?.title!==void 0&&(i.title=n.title);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/children`,i,{timeoutMs:px});return Vl(o)}async listChildSessions(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/children`)).items.map(Vl)}async startBtw(t){return{agentId:(await this.http.post(`/sessions/${encodeURIComponent(t)}:btw`,{})).agent_id}}async respondApproval(t,n,i){const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/approvals/${encodeURIComponent(n)}`,UY(i));return{resolved:o.resolved,resolvedAt:o.resolved_at}}async respondQuestion(t,n,i){const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/questions/${encodeURIComponent(n)}`,GY(i));return{resolved:o.resolved,resolvedAt:o.resolved_at}}async dismissQuestion(t,n){return{dismissed:!0,dismissedAt:(await this.http.post(`/sessions/${encodeURIComponent(t)}/questions/${encodeURIComponent(n)}:dismiss`,void 0,{allowCodes:[40909]})).dismissed_at}}async listTasks(t,n){const i={status:n};return(await this.http.get(`/sessions/${encodeURIComponent(t)}/tasks`,i)).items.map(s=>yv(s))}async getTask(t,n,i){const o={with_output:i?.withOutput,output_bytes:i?.outputBytes},s=await this.http.get(`/sessions/${encodeURIComponent(t)}/tasks/${encodeURIComponent(n)}`,o);return yv(s)}async cancelTask(t,n){return await this.http.post(`/sessions/${encodeURIComponent(t)}/tasks/${encodeURIComponent(n)}:cancel`)}async listTerminals(t){return(await this.http.get(`/sessions/${encodeURIComponent(t)}/terminals`)).items.map(o3)}async createTerminal(t,n={}){const i={cwd:n.cwd,shell:n.shell,cols:n.cols,rows:n.rows},o=await this.http.post(`/sessions/${encodeURIComponent(t)}/terminals`,i);return o3(o)}async getTerminal(t,n){const i=await this.http.get(`/sessions/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}`);return o3(i)}async closeTerminal(t,n){return this.http.post(`/sessions/${encodeURIComponent(t)}/terminals/${encodeURIComponent(n)}:close`)}async listSkills(t){return((await this.http.get(`/sessions/${encodeURIComponent(t)}/skills`)).skills??[]).map(i=>({name:i.name,description:i.description,path:i.path,source:i.source}))}async listSkillsForWorkspace(t){return((await this.http.get(`/workspaces/${encodeURIComponent(t)}/skills`)).skills??[]).map(i=>({name:i.name,description:i.description,path:i.path,source:i.source}))}async activateSkill(t,n,i,o){const s={};i!==void 0&&i.length>0&&(s.args=i),o!==void 0&&o.length>0&&(s.attachments=o.map(sD));const r=await this.http.post(`/sessions/${encodeURIComponent(t)}/skills/${encodeURIComponent(n)}:activate`,s);return{activated:r.activated,skillName:r.skill_name}}async listCapabilities(){return(await this.http.get("/capabilities")).capabilities??[]}async getCapability(t){return this.http.get(`/capabilities/${encodeURIComponent(t)}`)}async installCapability(t){return this.http.post(`/capabilities/${encodeURIComponent(t)}:install`,{})}async listPlugins(){return(await this.http.get("/plugins")).plugins??[]}async listPluginMarketplace(){return(await this.http.get("/plugins/marketplace")).entries??[]}async installPlugin(t){return this.http.post("/plugins",{source:t})}async setPluginEnabled(t,n){return this.http.post(`/plugins/${encodeURIComponent(t)}:${n?"enable":"disable"}`,{})}async removePlugin(t){return this.http.post(`/plugins/${encodeURIComponent(t)}:remove`,{})}async listDirectory(t,n){const i={};n.path!==void 0&&(i.path=n.path),n.depth!==void 0&&(i.depth=n.depth),n.includeGitStatus!==void 0&&(i.include_git_status=n.includeGitStatus);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:list`,i),s=o.children_by_path?Object.fromEntries(Object.entries(o.children_by_path).map(([r,l])=>[r,l.map(kx)])):void 0;return{items:o.items.map(kx),childrenByPath:s,truncated:o.truncated}}async readFile(t,n){const i={path:n.path};n.offset!==void 0&&(i.offset=n.offset),n.length!==void 0&&(i.length=n.length);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:read`,i);return{path:o.path,content:o.content,encoding:o.encoding,size:o.size,truncated:o.truncated,etag:o.etag,mime:o.mime,languageId:o.language_id,lineCount:o.line_count,isBinary:o.is_binary}}async searchFiles(t,n){const i={workspace:t,query:n.query};n.limit!==void 0&&(i.limit=n.limit);const o=await this.http.post("/workspace/fs:search",i);return{items:o.items.map(s=>({path:s.path,name:s.name,kind:s.kind,score:s.score,matchPositions:s.match_positions})),truncated:o.truncated}}async suggestFiles(t,n){const i={workspace:t,query:n.query};n.limit!==void 0&&(i.limit=n.limit);const o=await this.http.post("/workspace/fs:suggest",i);return{items:o.items.map(s=>({path:s.path,name:s.name,kind:s.kind,score:s.score,matchPositions:s.match_positions})),truncated:o.truncated}}async grepFiles(t,n){const i={pattern:n.pattern};n.regex!==void 0&&(i.regex=n.regex),n.caseSensitive!==void 0&&(i.case_sensitive=n.caseSensitive);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:grep`,i);return{files:o.files,filesScanned:o.files_scanned,truncated:o.truncated,elapsedMs:o.elapsed_ms}}async getGitStatus(t,n){const i={};n!==void 0&&(i.paths=n);const o=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:git_status`,i);return{branch:o.branch,ahead:o.ahead,behind:o.behind,entries:o.entries,additions:o.additions,deletions:o.deletions,pullRequest:o.pullRequest??null}}async getFileDiff(t,n){const i=await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:diff`,{path:n});return{path:i.path,diff:i.diff,truncated:i.truncated??!1}}getFileDownloadUrl(t,n){const i=n.split("/").map(o=>encodeURIComponent(o)).join("/");return $d(this.opts.origin,`/sessions/${encodeURIComponent(t)}/fs/${i}:download`)}async openFile(t,n){const i={path:n.path};return n.line!==void 0&&(i.line=n.line),this.http.post(`/sessions/${encodeURIComponent(t)}/fs:open`,i)}async revealFile(t,n){return this.http.post(`/sessions/${encodeURIComponent(t)}/fs:reveal`,{path:n.path})}async openInApp(t,n,i,o){const s={app_id:n,path:i};o!==void 0&&(s.line=o),await this.http.post(`/sessions/${encodeURIComponent(t)}/fs:open-in`,s)}async listWorkspaces(){try{return((await this.http.get("/workspaces")).items??[]).map($p)}catch{return[]}}async addWorkspace(t){const n={root:t.root};t.name!==void 0&&(n.name=t.name);const i=await this.http.post("/workspaces",n);return $p(i)}async deleteWorkspace(t){await this.http.delete(`/workspaces/${encodeURIComponent(t)}`)}async updateWorkspace(t,n){const i=await this.http.patch(`/workspaces/${encodeURIComponent(t)}`,{name:n.name});return $p(i)}async browseFs(t){try{const n=await this.http.get("/fs:browse",{path:t});return{path:n.path,parent:n.parent,entries:(n.entries??[]).map(i=>({name:i.name,path:i.path,isDir:i.is_dir}))}}catch{return{path:"",parent:null,entries:[]}}}async getFsHome(){try{const t=await this.http.get("/fs:home");return{home:t.home,recentRoots:t.recent_roots??[]}}catch{return{home:"",recentRoots:[]}}}async listModels(){return(await this.http.get("/models")).items.map(YY)}async listProviders(){return(await this.http.get("/providers")).items.map(Uf)}async getProvider(t){const n=await this.http.get(`/providers/${encodeURIComponent(t)}`),i=Uf(n);return n.api_key!==void 0?{...i,apiKey:n.api_key}:i}async addProvider(t){const n={id:t.id??"",type:t.type,models:(t.models??[]).map(o=>{const s={model:o.model,max_context_size:o.maxContextSize};return o.displayName!==void 0&&(s.display_name=o.displayName),o.capabilities!==void 0&&(s.capabilities=o.capabilities),o.maxOutputSize!==void 0&&(s.max_output_size=o.maxOutputSize),o.supportEfforts!==void 0&&(s.support_efforts=o.supportEfforts),o.adaptiveThinking!==void 0&&(s.adaptive_thinking=o.adaptiveThinking),s})};t.apiKey!==void 0&&(n.api_key=t.apiKey),t.baseUrl!==void 0&&(n.base_url=t.baseUrl),t.defaultModel!==void 0&&(n.default_model=t.defaultModel);const i=await this.http.post("/providers",n);return Uf(i)}async updateProvider(t,n){const i={type:n.type,models:(n.models??[]).map(s=>{const r={model:s.model,max_context_size:s.maxContextSize};return s.displayName!==void 0&&(r.display_name=s.displayName),s.capabilities!==void 0&&(r.capabilities=s.capabilities),s.maxOutputSize!==void 0&&(r.max_output_size=s.maxOutputSize),s.supportEfforts!==void 0&&(r.support_efforts=s.supportEfforts),s.adaptiveThinking!==void 0&&(r.adaptive_thinking=s.adaptiveThinking),r})};n.newId!==void 0&&(i.new_id=n.newId),n.apiKey!==void 0&&(i.api_key=n.apiKey),n.baseUrl!==void 0&&(i.base_url=n.baseUrl),n.defaultModel!==void 0&&(i.default_model=n.defaultModel);const o=await this.http.put(`/providers/${encodeURIComponent(t)}`,i);return{provider:Uf(o.provider)}}async deleteProvider(t){return await this.http.delete(`/providers/${encodeURIComponent(t)}`),{deleted:t}}async listCatalogProviders(){return(await this.http.get("/catalog/providers")).items.map(bx)}async getCatalogProvider(t){const n=await this.http.get(`/catalog/providers/${encodeURIComponent(t)}`);return bx(n)}async importCatalogProvider(t){const n={catalog_id:t.catalogId};t.apiKey!==void 0&&(n.api_key=t.apiKey),t.baseUrl!==void 0&&(n.base_url=t.baseUrl),t.id!==void 0&&(n.id=t.id);const i=await this.http.post("/providers:import_catalog",n);return{provider:Uf(i.provider),modelsImported:i.models_imported}}async importCustomRegistry(t){const n={url:t.url};t.apiKey!==void 0&&(n.api_key=t.apiKey);const i=await this.http.post("/providers:import_registry",n);return{providers:i.providers.map(Uf),modelsImported:i.models_imported}}async refreshProvider(t){const n=await this.http.post(`/providers/${encodeURIComponent(t)}:refresh`);return s3(n)}async refreshAllProviders(){const t=await this.http.post("/providers:refresh");return s3(t)}async refreshOAuthProviderModels(){const t=await this.http.post("/providers:refresh_oauth");return s3(t)}async getConfig(){const t=await this.http.get("/config");return Sb(t)}async setConfig(t){const n={},i={providers:"providers",defaultProvider:"default_provider",defaultModel:"default_model",secondaryModel:"secondary_model",models:"models",thinking:"thinking",planMode:"plan_mode",yolo:"yolo",defaultPermissionMode:"default_permission_mode",defaultPlanMode:"default_plan_mode",permission:"permission",hooks:"hooks",services:"services",mergeAllAvailableSkills:"merge_all_available_skills",extraSkillDirs:"extra_skill_dirs",loopControl:"loop_control",background:"background",experimental:"experimental",telemetry:"telemetry",raw:"raw"};for(const[s,r]of Object.entries(t)){const l=i[s];l!==void 0&&(n[l]=r)}const o=await this.http.post("/config",n);return Sb(o)}async getAuth(){const t=await this.http.get("/auth");return{ready:t.ready,providersCount:t.providers_count,defaultModel:t.default_model,managedProvider:t.managed_provider?{status:t.managed_provider.status}:null}}async startOAuthLogin(t){let n;try{n=await this.http.post("/oauth/login",t===void 0?{}:{region:t})}catch(i){if(t!==void 0&&ko(i)&&i.code===Ux)n=await this.http.post("/oauth/login",{});else throw i}return n.status==="authenticated"?{flowId:n.flow_id,provider:n.provider,status:"authenticated"}:{flowId:n.flow_id,provider:n.provider,status:"pending",verificationUri:n.verification_uri,verificationUriComplete:n.verification_uri_complete,userCode:n.user_code,expiresIn:n.expires_in,interval:n.interval,expiresAt:n.expires_at}}async pollOAuthLogin(){const t=await this.http.get("/oauth/login");return t?{flowId:t.flow_id,status:t.status,resolvedAt:t.resolved_at}:null}async cancelOAuthLogin(){const t=await this.http.delete("/oauth/login");return{cancelled:t.cancelled,status:t.status}}async logout(){return{loggedOut:(await this.http.post("/oauth/logout",{})).logged_out}}async getUsage(){const t=await this.http.get("/oauth/usage");if(t.kind==="error")return{kind:"error",message:t.message,status:t.status};const n=i=>({name:i.name,window:i.window,used:i.used,limit:i.limit,resetAt:i.reset_at});return{kind:"ok",summary:t.summary===null?null:n(t.summary),limits:t.limits.map(n),extraUsage:t.extra_usage===null?null:{balanceCents:t.extra_usage.balance_cents,totalCents:t.extra_usage.total_cents,monthlyChargeLimitEnabled:t.extra_usage.monthly_charge_limit_enabled,monthlyChargeLimitCents:t.extra_usage.monthly_charge_limit_cents,monthlyUsedCents:t.extra_usage.monthly_used_cents,currency:t.extra_usage.currency}}}async getUserInfo(){return this.http.get("/oauth/userinfo")}async getOAuthRegion(){try{const t=await Promise.race([this.http.get("/oauth/region"),new Promise((n,i)=>{setTimeout(()=>i(new Error("oauth region probe timed out")),Zie)})]);return t.region==="mainland-cn"||t.region==="global"?t.region:null}catch{return null}}async uploadFile(t){const n=new FormData;n.append("file",t.file,t.name??(t.file instanceof File?t.file.name:"upload")),t.name!==void 0&&n.append("name",t.name);const i=await this.http.postForm("/files",n);return{id:i.id,name:i.name,mediaType:i.media_type,size:i.size}}getFileUrl(t){return $d(this.opts.origin,`/files/${encodeURIComponent(t)}`)}async getFileBlob(t){return this.http.getBlob(`/files/${encodeURIComponent(t)}`)}getSessionMediaUrl(t,n){return $d(this.opts.origin,`/sessions/${encodeURIComponent(t)}/media/${encodeURIComponent(n)}`)}async getSessionMediaBlob(t,n){return this.http.getBlob(`/sessions/${encodeURIComponent(t)}/media/${encodeURIComponent(n)}`)}async readHostFileContent(t){const n=await this.http.getBlob("/fs:content",{path:t},{maxBytes:i3});if(n.size>i3)throw new r6({size:n.size,limit:i3});const i=n.type,o=!Yie(i),s=i||(o?"application/octet-stream":"text/plain");if(o){const l=await Jie(n);return{path:t,content:l,encoding:"base64",mime:s,isBinary:!0,size:n.size}}const r=await n.text();return{path:t,content:r,encoding:"utf-8",mime:s,isBinary:!1,size:n.size}}connectEvents(t){const n=BY(this.opts.origin,this.opts.identity.clientId),i=this.opts.projectorFactory(),o=new Kie({wsUrl:n,clientId:this.opts.identity.clientId,tracer:this.tracer,credentialStore:this.opts.credentialStore,mainAgentOnly:this.opts.mainAgentOnly,handlers:{onWireEvent:s=>{const r=JY(s),l=XY(s),a=QY(s);a.type==="historyCompacted"&&!Vx(a.reason)&&t.onResync(a.sessionId,a.beforeSeq),t.onEvent(a,{sessionId:r,seq:l})},onRawAgentEvent:s=>{const{type:r,seq:l,session_id:a,payload:u,offset:c}=s,d=i.project(r,u,a,{offset:c});for(const h of d){const p=u?.turnId,g=h.type==="assistantDelta"&&typeof p=="number"&&typeof c=="number"&&(r==="assistant.delta"||r==="thinking.delta")?{turnId:p,offset:c,kind:r==="assistant.delta"?"text":"thinking"}:void 0;h.type==="historyCompacted"&&!Vx(h.reason)&&t.onResync(a,l),t.onEvent(h,{sessionId:a,seq:l,stream:g})}},onResync:(s,r,l)=>{i.reset(s),t.onResync(s,r,l)},onConnectionState:s=>{t.onConnectionChange(s)},onReplayComplete:()=>{t.onReplayComplete?.()},onError:(s,r,l)=>{t.onError(s,r,l)},onTerminalOutput:(s,r,l,a)=>{t.onTerminalOutput?.(s,r,l,a)},onTerminalExit:(s,r,l)=>{t.onTerminalExit?.(s,r,l)},onTranscriptReset:(s,r,l,a)=>{t.onTranscriptReset?.(s,r,l,a)},onTranscriptOps:(s,r,l,a)=>t.onTranscriptOps?.(s,r,l,a)??!0}});return o.connect(),{subscribe(s,r){o.subscribe(s,r??{seq:0})},unsubscribe(s){o.unsubscribe(s),i.forgetSession(s)},subscribeTranscript(s,r,l){o.subscribeTranscript(s,r,l)},unsubscribeTranscript(s,r){o.unsubscribeTranscript(s,r)},seedSnapshot(s,r){if(r.inFlightTurn===null){i.reset(s);return}const l=i.seedInFlight(s,r.inFlightTurn);for(const a of l)t.onEvent(a,{sessionId:s,seq:r.asOfSeq})},bindNextPromptId(s,r){i.bindNextPromptId(s,r)},abort(s,r){o.abort(s,r)},terminalAttach(s,r,l){o.terminalAttach(s,r,l)},terminalInput(s,r,l){o.terminalInput(s,r,l)},terminalResize(s,r,l,a){o.terminalResize(s,r,l,a)},terminalDetach(s,r){o.terminalDetach(s,r)},terminalClose(s,r){o.terminalClose(s,r)},markSideChannelAgent(s,r){o.markSideChannelAgent(s,r),i.markSideChannelAgent(r)},health(){return o.health()},reconnect(){o.reconnect()},close(){o.close()}}}}function s3(e){return{changed:e.changed.map(t=>({providerId:t.provider_id,providerName:t.provider_name,added:t.added,removed:t.removed})),unchanged:e.unchanged,failed:e.failed}}function Yie(e){const t=e.toLowerCase().split(";")[0].trim();return t===""||t==="text/plain"||t.startsWith("text/")?!0:/(json|xml|javascript|typescript|x-yaml|yaml|svg|x-sh|x-python|markdown|csv|html|css)$/.test(t)}function Jie(e){return new Promise((t,n)=>{const i=new FileReader;i.onload=()=>{const o=String(i.result);t(o.slice(o.indexOf(",")+1))},i.onerror=()=>n(i.error),i.readAsDataURL(e)})}function Xie(){return window.kimiDesktop}function tB(e,t,n){const i=n.length===0?void 0:n.length===1?n[0]:n;try{Xie()?.log?.(e,t,i)}catch{}}function bu(e,...t){console.warn(e,...t),tB("warn",e,t)}function fu(e,...t){console.error(e,...t),tB("error",e,t)}const eoe={multiedit:"multi_edit",multiedits:"multi_edit",shell:"bash",run:"bash",exec:"bash",ripgrep:"grep",rg:"grep",find:"glob",fetch:"web_fetch",webfetch:"web_fetch",url_fetch:"web_fetch",urlfetch:"web_fetch",list:"ls",listdir:"ls",list_dir:"ls",todowrite:"todo",todo_write:"todo",todoread:"todo",todolist:"todo",todo_list:"todo",agent:"task",subagent:"task",websearch:"search",web_search:"search",create_goal:"creategoal",get_goal:"getgoal",set_goal_budget:"setgoalbudget",update_goal:"updategoal",wait_for:"waitfor"};function Gs(e){const t=(e??"").trim().toLowerCase().replace(/[\s-]+/g,"_");return eoe[t]??t}const toe={read:"tools.label.read",bash:"tools.label.bash",edit:"tools.label.edit",multi_edit:"tools.label.edit",write:"tools.label.write",grep:"tools.label.grep",glob:"tools.label.glob",ls:"tools.label.ls",web_fetch:"tools.label.web_fetch",search:"tools.label.search",todo:"tools.label.todo",task:"tools.label.task",agentswarm:"tools.label.swarm",askuserquestion:"tools.label.ask_user",exitplanmode:"tools.label.plan",creategoal:"tools.label.goal_create",getgoal:"tools.label.goal_get",setgoalbudget:"tools.label.goal_budget",updategoal:"tools.label.goal_update",waitfor:"tools.label.waitfor"};function nB(e,t){const n=toe[Gs(t)];return n?e(n):t}const iB=80;function noe(e,t=iB){const n=e.trim();return n.length>t?n.slice(0,t-1)+"…":n}function ioe(e,t){const n=e.trim();return!!(n===""||n==="{}"||n==="[]"||n==="null"||t&&Object.keys(t).length===0)}function ooe(e){const t=e.trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function ti(e){return typeof e=="string"&&e.length>0?e:void 0}function Yu(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function soe(e){try{const t=new URL(e),n=t.pathname.split("/").filter(Boolean)[0];return n?`${t.host}/${n}`:t.host}catch{return e.replace(/^https?:\/\//,"")}}function r3(e){return ti(e.path)??ti(e.file_path)??ti(e.filePath)??ti(e.filename)}const roe={active:"status.goalStatusActive",blocked:"status.goalStatusBlocked",complete:"status.goalStatusComplete"};function loe(e,t){const n=ti(t);if(!n)return;const i=roe[n];return i?e(i):n}function aoe(e,t){const n=Yu(t.value),i=ti(t.unit);if(!(n===void 0||!i))switch(i){case"turns":return e("tools.goal.turns",{value:n});case"tokens":return e("tools.goal.tokens",{value:n});case"milliseconds":return e("tools.goal.milliseconds",{value:n});case"seconds":return e("tools.goal.seconds",{value:n});case"minutes":return e("tools.goal.minutes",{value:n});case"hours":return e("tools.goal.hours",{value:n});default:return e("tools.goal.budget",{value:n,unit:i})}}function w6(e,t,n,i=!1){const o=(s,r=iB)=>i?s.trim():noe(s,r);try{const s=ooe(n);if(!i&&ioe(n,s))return"";const r=()=>o(n.replace(/^·\s*/,""));if(!s)return r();switch(Gs(t)){case"read":{const l=r3(s);if(!l)return r();const a=Yu(s.offset)??Yu(s.line_start)??Yu(s.start_line),u=Yu(s.limit)??Yu(s.length),c=Yu(s.line_end)??Yu(s.end_line)??(a!==void 0&&u!==void 0?a+u:void 0);return o(a!==void 0&&c!==void 0?`${l}:${a}-${c}`:a!==void 0?`${l}:${a}`:l)}case"write":{const l=r3(s);return l?o(`${l} ${e("tools.chip.created")}`):r()}case"edit":case"multi_edit":{const l=r3(s);return l?o(l):r()}case"bash":{const l=ti(s.command)??ti(s.cmd)??ti(s.script);return l?l.trim():r()}case"grep":case"search":{const l=ti(s.pattern)??ti(s.query)??ti(s.regex),a=ti(s.path)??ti(s.glob)??ti(s.include);return l&&a?o(e("tools.summary.inScope",{value:l,scope:a})):l?o(l):r()}case"glob":{const l=ti(s.pattern)??ti(s.glob)??ti(s.query),a=ti(s.path)??ti(s.cwd);return l&&a?o(e("tools.summary.inScope",{value:l,scope:a})):l?o(l):ti(s.path)?o(ti(s.path)):r()}case"ls":{const l=ti(s.path)??ti(s.dir)??ti(s.directory)??ti(s.cwd);return l?o(l):r()}case"web_fetch":{const l=ti(s.url)??ti(s.uri);return l?o(soe(l)):r()}case"todo":case"task":{const l=ti(s.description)??ti(s.title)??ti(s.prompt)??ti(s.name)??ti(s.subagent_type);if(l)return o(l);const a=Array.isArray(s.todos)?s.todos:Array.isArray(s.items)?s.items:void 0;return a?o(e("tools.chip.todos",{count:a.length})):r()}case"creategoal":{if(i)return r();const l=ti(s.objective),a=ti(s.completionCriterion);return l&&a?o(e("tools.goal.objectiveWithCriterion",{objective:l,criterion:a})):l?o(l):r()}case"getgoal":return i?r():"";case"setgoalbudget":{if(i)return r();const l=aoe(e,s);return l?o(l):r()}case"updategoal":{if(i)return r();const l=loe(e,s.status);return l?o(e("tools.goal.status",{status:l})):r()}default:return r()}}catch{return n}}function uoe(e,t){try{switch(Gs(t.name)){case"bash":return t.timing?t.timing:"";case"read":{if(t.output&&t.output.length>0){const n=t.output.length;return e("tools.chip.lines",{count:n})}return""}case"edit":case"multi_edit":case"write":{if(t.output){for(const i of t.output){const o=i.match(/\+(\d+).*[-−](\d+)/);if(o)return`+${o[1]} −${o[2]}`}const n=t.output.find(i=>/\d+/.test(i));if(n){const i=n.match(/\+(\d+)/),o=n.match(/[-−](\d+)/);if(i||o)return`${i?`+${i[1]}`:""} ${o?`−${o[1]}`:""}`.trim()}if(t.status!=="error")return e("tools.chip.edited")}return""}case"grep":case"search":return t.output&&t.output.length>0?e("tools.chip.results",{count:t.output.length}):"";default:return""}}catch{return""}}const coe="main",doe=new Set(["turn.started","turn.step.started","turn.step.completed","turn.step.retrying","turn.step.interrupted","turn.ended","thinking.delta","assistant.delta","tool.use","tool.call.started","tool.call.delta","tool.progress","tool.result","agent.status.updated","prompt.completed","prompt.aborted","error"]);function Ea(e="msg_"){const t=Date.now().toString(36).padStart(10,"0"),n=Math.random().toString(36).slice(2,12).padEnd(10,"0");return`${e}${t}${n}`}function foe(e){if(!e||typeof e!="object")return{input:0,output:0,cacheRead:0,cacheCreate:0};const t=e;return{input:t.inputOther??t.input_tokens??0,output:t.output??t.output_tokens??0,cacheRead:t.inputCacheRead??t.cache_read_input_tokens??0,cacheCreate:t.inputCacheCreation??t.cache_creation_input_tokens??0}}function Zx(){return{turnPromptId:new Map,currentPromptId:void 0,currentAssistantMsgId:void 0,turnTextLen:0,turnThinkLen:0,toolStartTimes:new Map,totalInput:0,totalOutput:0,totalCacheRead:0,totalCacheCreate:0,contextTokens:0,contextLimit:0,turnCount:0,model:"",messages:[],subagentMeta:new Map,restartedThisRun:new Set,settledByKernel:new Set,retiredBindings:new Set,registrationSeq:0,registrationOrderByKey:new Map,retryReuseMsgId:void 0,retryActive:!1}}function ao(e,t){const n=e[t];return typeof n=="string"?n:void 0}function Es(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:void 0}function xl(e,t){const n=e[t];return typeof n=="number"&&Number.isFinite(n)?n:null}function hoe(e){if(!e||typeof e!="object")return null;const t=e,n=t.budget,i=n&&typeof n=="object"?n:{},o=ao(t,"status");if(o!=="active"&&o!=="paused"&&o!=="blocked"&&o!=="complete")return null;const s=ao(t,"goalId")??ao(t,"goal_id")??"goal",r=ao(t,"objective")??"";return{goalId:s,objective:r,completionCriterion:ao(t,"completionCriterion")??ao(t,"completion_criterion"),status:o,turnsUsed:Es(t,"turnsUsed")??Es(t,"turns_used")??0,tokensUsed:Es(t,"tokensUsed")??Es(t,"tokens_used")??0,wallClockMs:Es(t,"wallClockMs")??Es(t,"wall_clock_ms")??0,terminalReason:ao(t,"terminalReason")??ao(t,"terminal_reason"),budget:{tokenBudget:xl(i,"tokenBudget")??xl(i,"token_budget"),remainingTokens:xl(i,"remainingTokens")??xl(i,"remaining_tokens"),turnBudget:xl(i,"turnBudget")??xl(i,"turn_budget"),remainingTurns:xl(i,"remainingTurns")??xl(i,"remaining_turns"),wallClockBudgetMs:xl(i,"wallClockBudgetMs")??xl(i,"wall_clock_budget_ms"),remainingWallClockMs:xl(i,"remainingWallClockMs")??xl(i,"remaining_wall_clock_ms"),overBudget:i.overBudget===!0||i.over_budget===!0}}}function ic(e,t,n,i,o){if(typeof i!="string"||i.length===0)return null;const r={...t.subagentMeta.get(i)??{id:i,agentId:i,sessionId:n,kind:"subagent",description:e("tasks.dockSubagent"),status:"running",createdAt:new Date().toISOString(),subagentPhase:"queued"},...o,id:i,sessionId:n,kind:"subagent"};return t.subagentMeta.set(i,r),r}function poe(e,t,n){if(t==="turn.step.started")return null;if(t==="tool.use"||t==="tool.call.started"){const i=ao(n,"name")??ao(n,"toolName")??"tool",o=nB(e,goe(i)),s=moe(e,i,n.args??n.input);return s?`Calling ${o}: ${s}`:`Calling ${o}`}if(t==="tool.progress"){const i=n.update;if(i&&typeof i=="object"){const s=ao(i,"text");if(s)return l3(s);const r=ao(i,"message");if(r)return l3(r)}const o=ao(n,"message");if(o)return l3(o)}return null}function goe(e){return e.replace(/_\d+$/,"")}const Gx=2e3;function l3(e){return e.length>Gx?`${e.slice(0,Gx)}…`:e}function moe(e,t,n){if(n==null)return"";const i=typeof n=="string"?n:JSON.stringify(n);return w6(e,t,i)}function voe(e,t,n,i,o,s,r){if(r.has(i)&&o==="turn.step.started")return[];if(o==="assistant.delta"){const p=ao(s,"delta");if(!p)return[];const g=t.subagentMeta.get(i),m=ic(e,t,n,i,{status:"running",subagentPhase:"working",startedAt:g?.startedAt??new Date().toISOString()}),k=[];return m&&k.push({type:"taskCreated",sessionId:n,task:m}),k.push({type:"taskProgress",sessionId:n,taskId:i,outputChunk:p,stream:"stdout",kind:"text"}),k}const l=poe(e,o,s);if(l===null||l.length===0)return[];const a=o==="tool.progress"?s.update:void 0,u=a!=null&&typeof a=="object"?a.replace===!0:!1,c=t.subagentMeta.get(i),d=ic(e,t,n,i,{status:"running",subagentPhase:"working",startedAt:c?.startedAt??new Date().toISOString()}),h=[];return d&&h.push({type:"taskCreated",sessionId:n,task:d}),h.push({type:"taskProgress",sessionId:n,taskId:i,outputChunk:l,stream:"stdout",replace:u}),h}function fd(e){return{...e,content:e.content.map(t=>({...t}))}}function Qx(e,t,n){const i={id:Ea("msg_"),sessionId:t,role:"assistant",content:[],createdAt:new Date().toISOString(),promptId:n};return e.messages.push(i),i}function yoe(e,t,n,i,o,s){const r={id:i,sessionId:t,role:"user",content:o,createdAt:s,promptId:n};return e.messages.push(r),r}function Yx(e){return Array.isArray(e)?e.map(t=>l6(t)):[]}function Jx(e,t,n,i){const o=e.messages.find(r=>r.id===t);if(!o)return-1;const s=o.content.at(-1);return s&&s.type===n?(n==="text"?s.text+=i:s.thinking+=i,o.content.length-1):(o.content.push(n==="text"?{type:"text",text:i}:{type:"thinking",thinking:i}),o.content.length-1)}function koe(e,t,n,i,o,s){const r=e.messages.find(l=>l.id===t);r&&r.content.push({type:"toolUse",toolCallId:n,toolName:i,input:o,outputLines:s})}function boe(e){const t=e.update,n=t&&typeof t=="object"?t:null,o=(n?.stream??n?.kind??e.stream)==="stderr"?"stderr":"stdout",s=typeof n?.text=="string"&&n.text||typeof n?.message=="string"&&n.message||typeof e.chunk=="string"&&e.chunk||typeof e.output=="string"&&e.output||typeof e.message=="string"&&e.message||"",r=n?.replace===!0;return s.length>0?{outputChunk:s,stream:o,replace:r}:null}function Xx(e,t){e.messages.find(n=>n.id===t)}function Aoe(e,t,n,i,o,s){const r={id:Ea("msg_"),sessionId:t,role:"tool",content:[{type:"toolResult",toolCallId:n,output:i,isError:o}],createdAt:new Date().toISOString(),promptId:s};return e.messages.push(r),r}function q1(e,t){return e.messages.find(n=>n.id===t)}function U1(e){const t=new Set;e.currentAssistantMsgId!==void 0&&t.add(e.currentAssistantMsgId),e.retryReuseMsgId!==void 0&&t.add(e.retryReuseMsgId),e.messages.length>t.size&&(e.messages=e.messages.filter(n=>t.has(n.id)))}function eS(e){return{inputTokens:e.totalInput,outputTokens:e.totalOutput,cacheReadTokens:e.totalCacheRead,cacheCreationTokens:e.totalCacheCreate,totalCostUsd:0,contextTokens:e.contextTokens,contextLimit:e.contextLimit,turnCount:e.turnCount}}const Coe=new Set(["session.meta.updated","goal.updated","compaction.completed","compaction.started","compaction.cancelled","compaction.blocked","hook.result","mcp.server.status","skill.activated","tool.list.updated"]);function woe(e,t,n){switch(e){case"session.meta.updated":{const i=t?.patch?.title??t?.title,o=t?.patch?.lastPrompt,s={};return typeof i=="string"&&i.length>0&&(s.title=i),typeof o=="string"&&(s.lastPrompt=o),s.title!==void 0||s.lastPrompt!==void 0?[{type:"sessionMetaUpdated",sessionId:n,...s}]:[]}case"goal.updated":{const i=hoe(t?.snapshot??null);return[{type:"goalUpdated",sessionId:n,goal:i?.status==="complete"?null:i}]}case"compaction.completed":{const i=t?.result??{};return[{type:"compactionCompleted",sessionId:n,tokensBefore:typeof i.tokensBefore=="number"?i.tokensBefore:void 0,tokensAfter:typeof i.tokensAfter=="number"?i.tokensAfter:void 0,summary:typeof i.summary=="string"?i.summary:void 0},{type:"historyCompacted",sessionId:n,beforeSeq:0,reason:"auto_compact"}]}case"compaction.started":return[{type:"compactionStarted",sessionId:n,trigger:t?.trigger==="manual"?"manual":"auto",instruction:typeof t?.instruction=="string"?t.instruction:void 0}];case"compaction.cancelled":return[{type:"compactionCancelled",sessionId:n}];default:return[]}}function xoe(e){const{t}=e,n=new Map,i=new Set;function o(g){let m=n.get(g);return m||(m=Zx(),n.set(g,m)),m}function s(g){n.set(g,Zx())}function r(g){n.delete(g)}function l(g){return n.get(g)?.messages.length}function a(g){i.add(g)}function u(g,m){const k=o(g);k.currentPromptId=m}function c(g,m){s(g);const k=o(g),w=m.promptId??Ea("pr_");k.currentPromptId=w,k.turnPromptId.set(m.turnId,w);const y=Qx(k,g,w);m.thinkingText.length>0&&y.content.push({type:"thinking",thinking:m.thinkingText}),m.assistantText.length>0&&y.content.push({type:"text",text:m.assistantText});for(const b of m.runningTools){const A=typeof b.lastProgress?.text=="string"&&b.lastProgress.text.length>0?[b.lastProgress.text]:void 0;y.content.push({type:"toolUse",toolCallId:b.toolCallId,toolName:b.name,input:b.args??{},outputLines:A}),k.toolStartTimes.set(b.toolCallId,Date.now())}return k.currentAssistantMsgId=y.id,k.turnTextLen=m.assistantText.length,k.turnThinkLen=m.thinkingText.length,[{type:"messageCreated",message:fd(y)}]}function d(g,m,k,w){try{return p(g,m,k,w)}catch(y){return fu("[agentProjector] Error projecting event:",g,y instanceof Error?y.message:y),[]}}function h(g,m){return m===void 0?"append":m<g?"skip":m>g?"gap":"append"}function p(g,m,k,w){if(Coe.has(g))return woe(g,m,k);const y=o(k),b=m,A=[],T=b?.agentId;if(typeof T=="string"&&T!==coe){const S=i.has(T);if(g==="prompt.submitted"){if(!S)return[];const x=b?.promptId,_=b?.userMessageId;if(!x||!_)return[];const L=Yx(b?.content);return L.length===0?[]:[{type:"messageCreated",agentId:T,message:{id:_,sessionId:k,role:"user",content:L,createdAt:typeof b?.createdAt=="string"?b.createdAt:new Date().toISOString(),promptId:x}}]}if(S&&(g==="thinking.delta"||g==="assistant.delta")){const x=b?.delta??"";return x?[{type:"agentDelta",sessionId:k,agentId:T,delta:{[g==="thinking.delta"?"thinking":"text"]:x}}]:[]}if(S&&g==="turn.ended")return[{type:"agentTurnEnded",sessionId:k,agentId:T,reason:b?.reason}];if(doe.has(g))return voe(t,y,k,T,g,b??{},i)}switch(g){case"prompt.submitted":{const S=b?.promptId,x=b?.userMessageId;if(!S||!x)break;const _=Yx(b?.content);if(_.length===0)break;y.currentPromptId=S;const L=yoe(y,k,S,x,_,typeof b?.createdAt=="string"?b.createdAt:new Date().toISOString());A.push({type:"messageCreated",message:fd(L),...typeof T=="string"?{agentId:T}:{}});break}case"turn.started":{const S=b?.turnId,x=y.currentPromptId??Ea("pr_");y.currentPromptId=x,S!==void 0&&y.turnPromptId.set(S,x),y.turnTextLen=0,y.turnThinkLen=0;const _=b?.origin;if(_&&typeof _=="object"&&_.kind==="system_trigger"&&_.name==="goal_continuation"){const L={id:S!==void 0?`goal_cont_${S}`:Ea("goal_"),sessionId:k,role:"user",content:[{type:"text",text:ao(b??{},"prompt")??""}],createdAt:new Date().toISOString(),metadata:{origin:_}};y.messages.push(L),A.push({type:"turnActiveChanged",sessionId:k,active:!0}),A.push({type:"messageCreated",message:fd(L)});break}A.push({type:"turnActiveChanged",sessionId:k,active:!0});break}case"turn.step.started":{const S=b?.turnId;y.retryActive&&(y.retryActive=!1,A.push({type:"turnRetry",sessionId:k,retry:void 0}));let x=y.turnPromptId.get(S)??y.currentPromptId;if(x||(x=Ea("pr_"),y.currentPromptId=x,S!==void 0&&y.turnPromptId.set(S,x)),y.turnTextLen=0,y.turnThinkLen=0,y.retryReuseMsgId!==void 0){const L=y.retryReuseMsgId;if(y.retryReuseMsgId=void 0,q1(y,L)!==void 0){y.currentAssistantMsgId=L,U1(y);break}}const _=Qx(y,k,x);y.currentAssistantMsgId=_.id,U1(y),A.push({type:"messageCreated",message:fd(_)});break}case"thinking.delta":{const S=y.currentAssistantMsgId;if(!S)break;const x=b?.delta??"";if(!x)break;w?.offset===0&&y.turnThinkLen>0&&(y.turnThinkLen=0);const _=h(y.turnThinkLen,w?.offset);if(_==="skip")break;if(_==="gap"){A.push({type:"historyCompacted",sessionId:k,beforeSeq:0,reason:"delta_gap"});break}const L=Jx(y,S,"thinking",x);if(L<0)break;y.turnThinkLen+=x.length,A.push({type:"assistantDelta",sessionId:k,messageId:S,contentIndex:L,delta:{thinking:x}});break}case"assistant.delta":{const S=y.currentAssistantMsgId;if(!S)break;const x=b?.delta??"";if(!x)break;w?.offset===0&&y.turnTextLen>0&&(y.turnTextLen=0);const _=h(y.turnTextLen,w?.offset);if(_==="skip")break;if(_==="gap"){A.push({type:"historyCompacted",sessionId:k,beforeSeq:0,reason:"delta_gap"});break}const L=Jx(y,S,"text",x);if(L<0)break;y.turnTextLen+=x.length,A.push({type:"assistantDelta",sessionId:k,messageId:S,contentIndex:L,delta:{text:x}});break}case"tool.use":case"tool.call.started":{const S=y.currentAssistantMsgId,x=b?.turnId,_=y.turnPromptId.get(x)??y.currentPromptId;if(!S||!_)break;const L=b?.toolCallId,M=b?.name??b?.toolName??"",N=b?.args??b?.input??{};koe(y,S,L,M,N);const I=q1(y,S);I&&I.content.length-1,y.toolStartTimes.set(L,Date.now()),I&&A.push({type:"messageUpdated",sessionId:k,messageId:S,content:I.content.map(z=>({...z})),status:"pending"});break}case"tool.call.delta":break;case"tool.progress":{const S=b?.toolCallId,x=boe(b??{});S&&x&&A.push({type:"toolOutput",sessionId:k,toolCallId:S,outputChunk:x.outputChunk,stream:x.stream,replace:x.replace});break}case"tool.result":{const S=b?.turnId;let x=y.turnPromptId.get(S)??y.currentPromptId;x||(x=Ea("pr_"),y.currentPromptId=x,S!==void 0&&y.turnPromptId.set(S,x));const _=b?.toolCallId,L=b?.output,M=b?.isError??!1;y.toolStartTimes.get(_)??Date.now(),y.toolStartTimes.delete(_);const N=Aoe(y,k,_,L,M,x);A.push({type:"messageCreated",message:fd(N)}),y.currentAssistantMsgId=void 0,U1(y);break}case"turn.step.completed":{const S=y.currentAssistantMsgId,x=foe(b?.usage);if(y.totalInput+=x.input,y.totalOutput+=x.output,y.totalCacheRead+=x.cacheRead,y.totalCacheCreate+=x.cacheCreate,S){Xx(y,S);const _=q1(y,S);_&&A.push({type:"messageUpdated",sessionId:k,messageId:S,content:_.content.map(L=>({...L})),status:"completed"})}break}case"agent.status.updated":{b?.model&&(y.model=b.model),b?.contextTokens!==void 0&&(y.contextTokens=b.contextTokens),b?.maxContextTokens!==void 0&&(y.contextLimit=b.maxContextTokens);const S=b?.phase;S!=null&&S.kind==="retrying"?(y.retryActive=!0,A.push({type:"turnRetry",sessionId:k,retry:{failedAttempt:Es(S,"failedAttempt")??0,nextAttempt:Es(S,"nextAttempt")??0,maxAttempts:Es(S,"maxAttempts")??0,delayMs:Es(S,"delayMs")??0,errorName:ao(S,"errorName"),statusCode:Es(S,"statusCode"),turnId:Es(S,"turnId")}})):y.retryActive&&S!==void 0&&S!==null&&typeof S.kind=="string"&&(y.retryActive=!1,A.push({type:"turnRetry",sessionId:k,retry:void 0})),A.push({type:"sessionUsageUpdated",sessionId:k,usage:eS(y),model:y.model||void 0,swarmMode:b?.swarmMode===!0?!0:b?.swarmMode===!1?!1:void 0,planMode:b?.planMode===!0?!0:b?.planMode===!1?!1:void 0,thinking:typeof b?.thinkingEffort=="string"&&b.thinkingEffort.length>0?b.thinkingEffort:void 0});break}case"turn.ended":{const S=y.currentAssistantMsgId,x=b?.reason??"completed",_=Es(b??{},"durationMs"),L=b?.turnId,M=(L!==void 0?y.turnPromptId.get(L):void 0)??y.currentPromptId;if(A.push({type:"turnActiveChanged",sessionId:k,active:!1,reason:b?.reason,promptId:M}),S){Xx(y,S);const I=q1(y,S);I&&A.push({type:"messageUpdated",sessionId:k,messageId:S,content:I.content.map(z=>({...z})),status:x==="failed"||x==="blocked"?"error":"completed",durationMs:_})}y.turnCount++;const N=eS(y);A.push({type:"sessionUsageUpdated",sessionId:k,usage:N}),y.currentAssistantMsgId=void 0,y.currentPromptId=void 0,y.turnTextLen=0,y.turnThinkLen=0,y.retryReuseMsgId=void 0,U1(y);break}case"prompt.completed":{const S=b?.promptId;typeof S=="string"&&S.length>0&&A.push({type:"promptCompleted",sessionId:k,promptId:S,reason:b?.reason??"completed"});break}case"prompt.aborted":{const S=b?.promptId;typeof S=="string"&&S.length>0&&A.push({type:"promptAborted",sessionId:k,promptId:S});break}case"turn.step.retrying":{y.retryActive=!0,A.push({type:"turnRetry",sessionId:k,retry:{failedAttempt:Es(b??{},"failedAttempt")??0,nextAttempt:Es(b??{},"nextAttempt")??0,maxAttempts:Es(b??{},"maxAttempts")??0,delayMs:Es(b??{},"delayMs")??0,errorName:ao(b??{},"errorName"),statusCode:Es(b??{},"statusCode"),turnId:typeof b?.turnId=="number"?b.turnId:void 0}});const S=y.currentAssistantMsgId;if(S!==void 0){const x=q1(y,S);x!==void 0&&(x.content=x.content.filter(_=>_.type!=="text"&&_.type!=="thinking"&&_.type!=="toolUse"),A.push({type:"messageUpdated",sessionId:k,messageId:S,content:x.content.map(_=>({..._})),status:"pending"}),y.retryReuseMsgId=S)}y.turnTextLen=0,y.turnThinkLen=0,y.toolStartTimes.clear();break}case"turn.step.interrupted":{y.currentAssistantMsgId=void 0,y.retryReuseMsgId=void 0,U1(y);break}case"subagent.spawned":{const S=typeof b?.subagentId=="string"&&b.subagentId.length>0?b.subagentId:Ea("task_"),x=typeof b?.taskId=="string"&&b.taskId.length>0?b.taskId:void 0,_=x!==void 0&&x!==S?y.subagentMeta.get(x):void 0,L=y.subagentMeta.get(S);_!==void 0&&y.subagentMeta.delete(x),x!==void 0&&!y.registrationOrderByKey.has(x)&&y.registrationOrderByKey.set(x,++y.registrationSeq);const M=L===void 0||_===void 0?L??_:{...L,createdAt:_.createdAt,startedAt:_.startedAt??L.startedAt,runInBackground:!0,backgroundTaskId:L.backgroundTaskId??x},N=M?.backgroundTaskId??(M!==void 0&&x!==void 0&&M.id===x?x:void 0),I=x!==void 0?y.registrationOrderByKey.get(x):void 0,z=N!==void 0?y.registrationOrderByKey.get(N):void 0,H=y.retiredBindings.has(x??"")||I!==void 0&&z!==void 0&&I<z,O=M!==void 0&&(x===void 0&&(M.status!=="running"?!0:N!==void 0&&y.restartedThisRun.has(S))||x!==void 0&&x!==N&&!H&&!(M.status==="running"&&N===void 0)),R=M?.subagentPhase==="working"&&(x===void 0||x===N||y.restartedThisRun.has(S));O&&(y.restartedThisRun.delete(S),N!==void 0&&N!==x&&y.retiredBindings.add(N));const j={id:S,agentId:M?.agentId??S,sessionId:k,kind:"subagent",description:typeof b?.description=="string"?b.description:b?.subagentName??M?.description??t("tasks.dockSubagent"),status:O?"running":M?.status??"running",createdAt:O&&!R?new Date().toISOString():M?.createdAt??new Date().toISOString(),startedAt:O&&!R?void 0:M?.startedAt,completedAt:O?void 0:M?.completedAt,completedAtEstimated:O?void 0:M?.completedAtEstimated,subagentPhase:O?R?"working":"queued":M?.subagentPhase??"queued",subagentType:typeof b?.subagentName=="string"?b.subagentName:M?.subagentType,model:typeof b?.model=="string"&&b.model.length>0?b.model:M?.model,thinkingEffort:typeof b?.thinkingEffort=="string"&&b.thinkingEffort.length>0?b.thinkingEffort:M?.thinkingEffort,parentToolCallId:typeof b?.parentToolCallId=="string"?b.parentToolCallId:M?.parentToolCallId,swarmIndex:typeof b?.swarmIndex=="number"?b.swarmIndex:M?.swarmIndex,runInBackground:O?b?.runInBackground===!0||b?.runInBackground===void 0&&M?.runInBackground===!0:b?.runInBackground===!0||M?.runInBackground===!0,outputPreview:O?void 0:M?.outputPreview,outputBytes:O?void 0:M?.outputBytes,outputLines:O?void 0:M?.outputLines,suspendedReason:O?void 0:M?.suspendedReason,text:O?void 0:M?.text,backgroundTaskId:H?M?.backgroundTaskId:O?x:x??M?.backgroundTaskId};y.subagentMeta.set(j.id,j),A.push({type:"taskCreated",sessionId:k,task:j});break}case"subagent.started":{const S=typeof b?.subagentId=="string"?b.subagentId:void 0,x=S!==void 0&&(y.subagentMeta.get(S)?.status!==void 0&&y.subagentMeta.get(S).status!=="running"||y.settledByKernel.has(S));x&&y.settledByKernel.delete(S);const _=ic(t,y,k,b?.subagentId,{subagentPhase:"working",status:"running",startedAt:new Date().toISOString(),suspendedReason:void 0,...x?{createdAt:new Date().toISOString(),completedAt:void 0,completedAtEstimated:void 0,outputPreview:void 0,outputBytes:void 0,outputLines:void 0,text:void 0}:{}});x&&S!==void 0&&y.restartedThisRun.add(S),_&&A.push({type:"taskCreated",sessionId:k,task:_});break}case"subagent.suspended":{const S=ic(t,y,k,b?.subagentId,{subagentPhase:"suspended",status:"running",suspendedReason:typeof b?.reason=="string"?b.reason:void 0});S&&A.push({type:"taskCreated",sessionId:k,task:S});break}case"subagent.completed":{const S=typeof b?.resultSummary=="string"?b.resultSummary:void 0,x=ic(t,y,k,b?.subagentId,{subagentPhase:"completed",status:"completed",completedAt:new Date().toISOString(),completedAtEstimated:!0,outputPreview:S});x&&A.push({type:"taskCreated",sessionId:k,task:x}),x!==null&&y.restartedThisRun.delete(x.id),A.push({type:"taskCompleted",sessionId:k,taskId:b?.subagentId??"",status:"completed",outputPreview:S});break}case"subagent.failed":{const S=typeof b?.error=="string"?b.error:void 0,x=ic(t,y,k,b?.subagentId,{subagentPhase:"failed",status:"failed",completedAt:new Date().toISOString(),completedAtEstimated:!0,outputPreview:S});x&&A.push({type:"taskCreated",sessionId:k,task:x}),x!==null&&y.restartedThisRun.delete(x.id),A.push({type:"taskCompleted",sessionId:k,taskId:b?.subagentId??"",status:"failed",outputPreview:S});break}case"error":{A.push({type:"unknown",raw:{_agentError:!0,code:b?.code,message:b?.message,name:b?.name,details:b?.details,retryable:b?.retryable}});break}case"task.notified":{const S=ao(b??{},"notificationType"),x=ao(b??{},"sourceKind"),_=ao(b??{},"sourceId");if(!S||!x||!_)break;const L=S.startsWith("task.")?S.slice(5):S,M=`task:${_}:${L}`,N=j=>j.replaceAll("&","&").replaceAll("<","<").replaceAll(">",">"),I=ao(b??{},"title")??"",z=ao(b??{},"severity")??"",H=ao(b??{},"body")??"",O=`<notification id="${M}" category="task" type="${N(S)}" source_kind="${N(x)}" source_id="${N(_)}"> -`+(I!==""?`Title: ${N(I)} -`:"")+(z!==""?`Severity: ${N(z)} -`:"")+(H!==""?`${N(H)} -`:"")+"</notification>",R={id:`task_ntf_${M}`,sessionId:k,role:"user",content:[{type:"text",text:O}],createdAt:new Date().toISOString(),metadata:{origin:{kind:"task",taskId:_,status:L,notificationId:M}}};y.messages.push(R),A.push({type:"messageCreated",message:fd(R)});break}case"warning":{A.push({type:"unknown",raw:{_agentWarning:!0,message:b?.message}});break}case"task.started":case"background.task.started":{const S=b?.info??{},x=typeof S.startedAt=="number"?new Date(S.startedAt).toISOString():void 0,_=typeof S.taskId=="string"?S.taskId:typeof S.taskId=="number"?String(S.taskId):Ea("task_"),L=typeof S.description=="string"?S.description:typeof S.command=="string"?S.command:t("tasks.defaultDescription");if(S.kind==="agent"){const N=typeof S.agentId=="string"&&S.agentId.length>0?S.agentId:void 0;if(N!==void 0){const I=y.subagentMeta.get(N),z=y.registrationOrderByKey.get(_),H=I?.backgroundTaskId!==void 0?y.registrationOrderByKey.get(I.backgroundTaskId):void 0;if(y.retiredBindings.has(_)||z!==void 0&&H!==void 0&&z<H){I!==void 0&&A.push({type:"taskCreated",sessionId:k,task:I});break}y.registrationOrderByKey.has(_)||y.registrationOrderByKey.set(_,++y.registrationSeq);const O=I!==void 0&&I.backgroundTaskId!==_&&!(I.status==="running"&&I.backgroundTaskId===void 0),R=ic(t,y,k,N,{description:L,backgroundTaskId:_,runInBackground:!0,...I===void 0||I.status==="running"?{status:"running",subagentPhase:"working",startedAt:I?.startedAt??x}:{},...O?{status:"running",subagentPhase:"working",createdAt:x??new Date().toISOString(),startedAt:x,completedAt:void 0,completedAtEstimated:void 0,outputPreview:void 0,outputBytes:void 0,outputLines:void 0,suspendedReason:void 0,text:void 0}:{}});R&&A.push({type:"taskCreated",sessionId:k,task:R}),y.restartedThisRun.delete(N)}else{const I=[...y.subagentMeta.values()].find(H=>H.backgroundTaskId===_);if(I===void 0&&(y.retiredBindings.has(_)||y.registrationOrderByKey.has(_)&&y.registrationOrderByKey.get(_)<y.registrationSeq))break;if(I!==void 0){const H=ic(t,y,k,I.agentId??I.id,{description:typeof S.description=="string"||typeof S.command=="string"?L:I.description,status:"running",subagentPhase:"working",runInBackground:!0,startedAt:I.startedAt??x});H&&A.push({type:"taskCreated",sessionId:k,task:H});break}const z={id:_,sessionId:k,kind:"subagent",description:L,status:"running",createdAt:x??new Date().toISOString(),startedAt:x,subagentPhase:"working",runInBackground:!0};y.subagentMeta.set(_,z),y.registrationOrderByKey.has(_)||y.registrationOrderByKey.set(_,++y.registrationSeq),A.push({type:"taskCreated",sessionId:k,task:z})}break}const M=typeof S.command=="string"?S.command:void 0;A.push({type:"taskCreated",sessionId:k,task:{id:_,sessionId:k,kind:"bash",description:L,command:M,status:"running",createdAt:x??new Date().toISOString(),startedAt:x,outputPreview:M!==void 0?`$ ${M}`:void 0}});break}case"task.terminated":case"background.task.terminated":{const S=b?.info??{},x=S.status==="failed"||S.status==="timed_out"||S.status==="lost"||typeof S.exitCode=="number"&&S.exitCode!==0;S.kind==="agent"&&typeof S.agentId=="string"&&S.agentId.length>0&&y.settledByKernel.add(S.agentId),A.push({type:"taskCompleted",sessionId:k,taskId:typeof S.taskId=="string"?S.taskId:typeof S.taskId=="number"?String(S.taskId):"",status:S.status==="killed"?"cancelled":x?"failed":"completed"});break}case"cron.fired":{const S=b?.origin,x=ao(b??{},"prompt");if(S&&typeof S=="object"&&S.kind==="cron_job"&&x){const _={id:Ea("cron_"),sessionId:k,role:"user",content:[{type:"text",text:x}],createdAt:new Date().toISOString(),metadata:{origin:S}};y.messages.push(_),A.push({type:"messageCreated",message:fd(_)})}break}}return A}return{project:d,bindNextPromptId:u,seedInFlight:c,reset:s,forgetSession:r,retainedMessageCount:l,markSideChannelAgent:a}}function Soe(e){return new Qie({origin:e.origin,identity:e.identity,tracer:e.tracer,credentialStore:e.credentialStore,projectorFactory:()=>xoe({t:e.t}),mainAgentOnly:e.mainAgentOnly})}const oB="kimiWeb.compaction",_oe={t:e=>e},Moe="kimiWeb.optimisticUserMessage",tS="Sub Agent";function hp(e,t,n=e.length){for(let i=0;i<n;i++){const o=e[i];o.type==="thinking"&&o.startedAt!==void 0&&o.durationMs===void 0&&(e[i]={...o,durationMs:Math.max(0,t-Date.parse(o.startedAt))})}}function nS(e,t,n){const i=e.messagesBySession[t];if(i)for(let o=i.length-1;o>=0;o--){const s=i[o];if(s.role!=="assistant")continue;if(!s.content.some(u=>u.type==="thinking"&&u.startedAt!==void 0&&u.durationMs===void 0))return;const l=[...s.content];hp(l,n);const a=[...i];a[o]={...s,content:l},e.messagesBySession[t]=a;return}}function iS(e){const t=Date.parse(e);return Number.isNaN(t)?Date.now():t}function Ioe(){return{sessions:[],activeSessionId:void 0,messagesBySession:{},approvalsBySession:{},planReviewByToolCallId:{},questionsBySession:{},tasksBySession:{},goalBySession:{},goalVersionBySession:{},lastSeqBySession:{},turnActiveBySession:{},turnEndedPromptIdBySession:{},turnErrorBySession:{},turnRetryBySession:{},compactionBySession:{},warnings:[]}}function Eoe(e){return{...e,sessions:e.sessions,messagesBySession:{...e.messagesBySession},approvalsBySession:{...e.approvalsBySession},planReviewByToolCallId:{...e.planReviewByToolCallId},questionsBySession:{...e.questionsBySession},tasksBySession:{...e.tasksBySession},goalBySession:{...e.goalBySession},goalVersionBySession:{...e.goalVersionBySession},lastSeqBySession:{...e.lastSeqBySession},turnActiveBySession:{...e.turnActiveBySession},turnEndedPromptIdBySession:{...e.turnEndedPromptIdBySession},turnErrorBySession:{...e.turnErrorBySession},turnRetryBySession:{...e.turnRetryBySession},compactionBySession:{...e.compactionBySession},warnings:[...e.warnings]}}function Toe(e,t,n){if(t!==void 0&&n!==void 0&&n>0){const i=e.lastSeqBySession[t]??0;n>i&&(e.lastSeqBySession[t]=n)}}function hd(e,t){const n=new Date().toISOString();e.sessions=e.sessions.map(i=>i.id===t&&n>i.updatedAt?{...i,updatedAt:n}:i)}function qu(e,t){return t.seq>(e.lastSeqBySession[t.sessionId]??0)}function oS(e){return e.role==="user"&&e.metadata?.[Moe]===!0}function Loe(e){const t=e.metadata?.origin;return t?.kind==="cron_job"||t?.kind==="cron_missed"}function Noe(e){return e.metadata?.origin?.kind==="system_trigger"}function Foe(e,t){const n=t.userMessageId??t.id;for(let o=e.length-1;o>=0;o--){const s=e[o];if(oS(s)&&s.userMessageId===n)return o}const i=t.promptId;if(i!==void 0)for(let o=e.length-1;o>=0;o--){const s=e[o];if(oS(s)&&s.promptId===i)return o}return-1}function Doe(e,t,n,i){let o=!1;const s=e.map(r=>{let l=!1;const a=r.content.map(u=>{if(u.type!=="toolUse"||u.toolCallId!==t)return u;l=!0;const c=u.outputLines??[],d=i&&c.length>0?[...c.slice(0,-1),n]:[...c,n];return{...u,outputLines:d}});return l?(o=!0,{...r,content:a}):r});return o?s:e}const Boe={"provider.connection_error":"connection","provider.auth_error":"auth","provider.rate_limit":"rateLimit","provider.overloaded":"overloaded","provider.filtered":"filtered","provider.api_error":"api","context.overflow":"contextOverflow"};function $oe(e,t){const n=[],i=(r,l)=>{typeof l=="number"||typeof l=="boolean"?n.push({label:r,value:String(l)}):typeof l=="string"&&l.length>0&&n.push({label:r,value:l})};i(t("warnings.details.code"),e.code);const o=e.details??{};i(t("warnings.details.status"),o.statusCode),i(t("warnings.details.requestId"),o.requestId),i(t("warnings.details.errorName"),e.name);for(const[r,l]of Object.entries(o))r==="statusCode"||r==="requestId"||i(r,l);const s=(e.code!==void 0?Boe[e.code]:void 0)??"title";return{severity:"error",title:t(`warnings.agentError.${s}`),message:e.message,details:n.length>0?n:void 0}}function Roe(e,t,n,i=_oe){const o=Eoe(e);switch(Toe(o,n.sessionId,n.seq),t.type){case"sessionCreated":{o.sessions.some(r=>r.id===t.session.id)||(o.sessions=[t.session,...o.sessions]);break}case"sessionUpdated":{o.sessions=o.sessions.map(s=>s.id===t.session.id?{...t.session,pullRequest:s.pullRequest}:s);break}case"sessionDeleted":{const s=t.sessionId;o.sessions=o.sessions.filter(r=>r.id!==s),delete o.messagesBySession[s],delete o.tasksBySession[s],delete o.goalBySession[s],delete o.approvalsBySession[s],delete o.questionsBySession[s],delete o.lastSeqBySession[s],delete o.turnActiveBySession[s],delete o.turnEndedPromptIdBySession[s],delete o.turnErrorBySession[s],delete o.turnRetryBySession[s],o.activeSessionId===s&&(o.activeSessionId=void 0);break}case"sessionWorkChanged":{if(!qu(e,n))break;let s;o.sessions=o.sessions.map(r=>r.id!==t.sessionId?r:(s=t.pendingInteraction??(t.busy?r.pendingInteraction:"none"),{...r,busy:t.busy,mainTurnActive:t.mainTurnActive??(t.busy?r.mainTurnActive:!1),pendingInteraction:s,lastTurnReason:t.lastTurnReason})),s==="none"?(delete o.approvalsBySession[t.sessionId],delete o.questionsBySession[t.sessionId]):s==="question"&&delete o.approvalsBySession[t.sessionId],t.mainTurnActive===!0?o.turnActiveBySession[t.sessionId]=!0:(t.mainTurnActive===!1||!t.busy)&&(e.turnActiveBySession[t.sessionId]&&hd(o,t.sessionId),delete o.turnActiveBySession[t.sessionId],delete o.turnRetryBySession[t.sessionId]);break}case"sessionMetaUpdated":{o.sessions=o.sessions.map(s=>s.id===t.sessionId?{...s,title:t.title??s.title,lastPrompt:t.lastPrompt??s.lastPrompt}:s);break}case"sessionUsageUpdated":{o.sessions=o.sessions.map(s=>{if(s.id!==t.sessionId)return s;const r=t.model&&t.model.length>0?t.model:s.model;return{...s,usage:t.usage,model:r}});break}case"historyCompacted":break;case"compactionStarted":{o.compactionBySession={...o.compactionBySession,[t.sessionId]:{status:"running",trigger:t.trigger}};break}case"compactionCompleted":{const s=t.sessionId,r=o.compactionBySession[s],{[s]:l,...a}=o.compactionBySession;if(o.compactionBySession=a,Object.prototype.hasOwnProperty.call(o.messagesBySession,s)){const u=o.messagesBySession[s]??[],c=`compaction_${s}_${n.seq}`;if(!u.some(d=>d.id===c)){const d={trigger:r?.trigger??"auto",tokensBefore:t.tokensBefore,tokensAfter:t.tokensAfter};o.messagesBySession[s]=[...u,{id:c,sessionId:s,role:"assistant",content:t.summary?[{type:"text",text:t.summary}]:[],createdAt:new Date().toISOString(),metadata:{origin:{kind:"compaction_summary"},[oB]:d}}]}}break}case"compactionCancelled":{const{[t.sessionId]:s,...r}=o.compactionBySession;o.compactionBySession=r;break}case"messageCreated":{const s=t.message.sessionId,r=o.messagesBySession[s]??[];if(!r.some(a=>a.id===t.message.id)){if(t.message.role==="user"&&!Loe(t.message)&&!Noe(t.message)){const a=Foe(r,t.message);if(a!==-1){const u=[...r],c=u[a];u[a]={...t.message,id:c.id,promptId:t.message.promptId??c.promptId,userMessageId:t.message.userMessageId??t.message.id,metadata:{...t.message.metadata,...c.metadata}},o.messagesBySession[s]=u;break}}o.messagesBySession[s]=[...r,t.message]}break}case"messageUpdated":{const s=t.sessionId,r=o.messagesBySession[s]??[];o.messagesBySession[s]=r.map(l=>{if(l.id!==t.messageId)return l;const a=t.content.map((c,d)=>{const h=l.content[d];return c.type==="thinking"&&h?.type==="thinking"?{...c,startedAt:h.startedAt,durationMs:h.durationMs}:c}),u=Date.now();return hp(a,u,a.length-1),(t.status!=="pending"||t.durationMs!==void 0)&&hp(a,u),{...l,content:a,durationMs:t.durationMs??l.durationMs,endedAt:t.durationMs!==void 0?l.endedAt??new Date(u).toISOString():l.endedAt}});break}case"assistantDelta":{const s=t.sessionId,r=o.messagesBySession[s]??[];o.messagesBySession[s]=r.map(l=>{if(l.id!==t.messageId)return l;const a=[...l.content],u=t.contentIndex,c=a.length<=u;for(;a.length<=u;)a.push({type:"text",text:""});const d=a[u];let h;return t.delta.text!==void 0?d.type==="text"&&!c?h={type:"text",text:d.text+t.delta.text}:(h={type:"text",text:t.delta.text},hp(a,Date.now(),u)):t.delta.thinking!==void 0?d.type==="thinking"?h={type:"thinking",thinking:d.thinking+t.delta.thinking,signature:d.signature,startedAt:d.startedAt,durationMs:d.durationMs}:(h={type:"thinking",thinking:t.delta.thinking,startedAt:new Date().toISOString()},hp(a,Date.now(),u)):h=d,a[u]=h,{...l,content:a}});break}case"toolOutput":{const s=t.sessionId,r=o.messagesBySession[s]??[];o.messagesBySession[s]=Doe(r,t.toolCallId,t.outputChunk,t.replace===!0);break}case"approvalRequested":{const s=t.sessionId,r=o.approvalsBySession[s]??[];r.some(u=>u.approvalId===t.approval.approvalId)||(o.approvalsBySession[s]=[...r,t.approval],qu(e,n)&&(nS(o,s,iS(t.approval.createdAt)),hd(o,s)));const a=t.approval.display;a?.kind==="plan_review"&&typeof a.plan=="string"&&a.plan.length>0&&(o.planReviewByToolCallId={...o.planReviewByToolCallId,[t.approval.toolCallId]:{plan:a.plan,path:typeof a.path=="string"?a.path:void 0}});break}case"approvalResolved":case"approvalExpired":{const s=t.sessionId,r=t.approvalId,l=o.approvalsBySession[s]??[];o.approvalsBySession[s]=l.filter(a=>a.approvalId!==r);break}case"questionRequested":{const s=t.sessionId,r=o.questionsBySession[s]??[];r.some(a=>a.questionId===t.question.questionId)||(o.questionsBySession[s]=[...r,t.question],qu(e,n)&&(nS(o,s,iS(t.question.createdAt)),hd(o,s)));break}case"questionAnswered":case"questionDismissed":{const s=t.sessionId,r=t.questionId,l=o.questionsBySession[s]??[];o.questionsBySession[s]=l.filter(a=>a.questionId!==r);break}case"taskCreated":{const s=t.sessionId,r=o.tasksBySession[s]??[],l=r.findIndex(h=>h.id===t.task.id),a=t.task.backgroundTaskId===void 0?-1:r.findIndex(h=>h.id===t.task.backgroundTaskId),u=a!==-1&&l!==-1&&a!==l?r[a]:void 0,c=u!==void 0?r.filter((h,p)=>p!==a):r,d=c.findIndex(h=>h.id===t.task.id||t.task.backgroundTaskId!==void 0&&h.id===t.task.backgroundTaskId);if(d===-1)o.tasksBySession[s]=[...c,t.task];else{const h=[...c],p=c[d],g=t.task.backgroundTaskId!==void 0&&(t.task.backgroundTaskId===p.backgroundTaskId||p.id===t.task.backgroundTaskId)||p.id===t.task.id&&(p.kind!=="subagent"||p.agentId===void 0),m=(g&&p.status!=="running"?p:void 0)??(u!==void 0&&u.status!=="running"?u:void 0),k=m!==void 0&&(t.task.status==="running"||t.task.status!==m.status),w=!g&&p.status!=="running"||t.task.backgroundTaskId!==void 0&&p.backgroundTaskId!==void 0&&t.task.backgroundTaskId!==p.backgroundTaskId,y=g&&p.completedAt!==void 0&&p.completedAtEstimated!==!0;h[d]={...t.task,status:k?m.status:t.task.status,subagentPhase:k?m.subagentPhase:t.task.subagentPhase,completedAt:k?m.completedAt:y?p.completedAt:t.task.completedAt,completedAtEstimated:k?m.completedAtEstimated:y?p.completedAtEstimated:t.task.completedAtEstimated,outputLines:k?m.outputLines:w?u?.outputLines??t.task.outputLines:p.outputLines??u?.outputLines??t.task.outputLines,text:k?m.text:w?u?.text??t.task.text:p.text??u?.text??t.task.text,outputPreview:k?m.outputPreview:t.task.outputPreview??(w?u?.outputPreview:p.outputPreview??u?.outputPreview),outputBytes:k?m.outputBytes:t.task.outputBytes??(w?u?.outputBytes:p.outputBytes??u?.outputBytes),description:t.task.description===tS&&p.description!==tS?p.description:t.task.description,swarmIndex:t.task.swarmIndex??p.swarmIndex,parentToolCallId:t.task.parentToolCallId??p.parentToolCallId,subagentType:t.task.subagentType??p.subagentType,model:t.task.model??p.model,thinkingEffort:t.task.thinkingEffort??p.thinkingEffort,runInBackground:w?t.task.runInBackground:t.task.runInBackground??p.runInBackground,backgroundTaskId:w?t.task.backgroundTaskId:t.task.backgroundTaskId??p.backgroundTaskId,agentId:t.task.agentId??p.agentId},o.tasksBySession[s]=h}break}case"taskProgress":{const s=t.sessionId,r=o.tasksBySession[s]??[];o.tasksBySession[s]=r.map(l=>{if(l.id!==t.taskId)return l;if(l.kind==="subagent"&&t.kind==="text")return{...l,text:(l.text??"")+t.outputChunk};const a=l.outputLines??[];if(t.replace===!0){const c=a.length>0?[...a.slice(0,-1),t.outputChunk]:[t.outputChunk];return{...l,outputLines:c}}if(a.at(-1)===t.outputChunk)return l;const u=[...a,t.outputChunk];return{...l,outputLines:l.kind==="subagent"?u:u.slice(-40)}});break}case"taskCompleted":{const s=t.sessionId,r=o.tasksBySession[s]??[];o.tasksBySession[s]=r.map(l=>l.id!==t.taskId&&l.backgroundTaskId!==t.taskId||t.status==="completed"&&(l.status==="cancelled"||l.status==="failed")||t.status==="failed"&&l.status==="cancelled"?l:{...l,status:t.status,completedAt:l.completedAt??new Date().toISOString(),completedAtEstimated:l.completedAt===void 0?!0:l.completedAtEstimated,outputPreview:t.outputPreview??l.outputPreview,outputBytes:t.outputBytes??l.outputBytes});break}case"goalUpdated":{const s=t.sessionId;o.goalVersionBySession[s]=(o.goalVersionBySession[s]??0)+1,t.goal===null||t.goal.status==="complete"?delete o.goalBySession[s]:o.goalBySession[s]=t.goal;break}case"configChanged":{o.config=t.config;break}case"modelCatalogChanged":break;case"agentDelta":case"agentTurnEnded":break;case"promptCompleted":{t.reason==="blocked"&&qu(e,n)&&hd(o,t.sessionId);break}case"promptAborted":{if(t.promptId===e.turnEndedPromptIdBySession[t.sessionId])break;qu(e,n)&&hd(o,t.sessionId);break}case"turnActiveChanged":{if(!qu(e,n))break;if(o.sessions=o.sessions.map(s=>s.id===t.sessionId?{...s,mainTurnActive:t.active}:s),t.active)o.turnActiveBySession[t.sessionId]=!0,delete o.turnEndedPromptIdBySession[t.sessionId],delete o.turnErrorBySession[t.sessionId],delete o.turnRetryBySession[t.sessionId],hd(o,t.sessionId);else{delete o.turnActiveBySession[t.sessionId],delete o.turnRetryBySession[t.sessionId],t.promptId!==void 0&&(o.turnEndedPromptIdBySession[t.sessionId]=t.promptId);const s=t.reason===void 0||t.reason==="completed"?"completed":"failed",r=o.tasksBySession[t.sessionId];r!==void 0&&(o.tasksBySession[t.sessionId]=r.map(l=>l.kind!=="subagent"||l.status!=="running"||l.runInBackground===!0?l:{...l,status:s,subagentPhase:s,completedAt:l.completedAt??new Date().toISOString(),completedAtEstimated:l.completedAt===void 0?!0:l.completedAtEstimated,suspendedReason:void 0})),hd(o,t.sessionId)}break}case"turnRetry":{if(!qu(e,n))break;t.retry===void 0?delete o.turnRetryBySession[t.sessionId]:o.turnRetryBySession[t.sessionId]=t.retry;break}case"unknown":{const s=t.raw;if(!(s&&s._noop===!0))if(s&&s._agentError){if(qu(e,n)){if(n.sessionId!==void 0){const r=s.details??{};o.turnErrorBySession[n.sessionId]={code:s.code,message:s.message,name:s.name,retryable:s.retryable,statusCode:typeof r.statusCode=="number"?r.statusCode:void 0,requestId:typeof r.requestId=="string"?r.requestId:void 0}}(n.sessionId===void 0||n.sessionId!==e.activeSessionId)&&(o.warnings=[...o.warnings,$oe(s,i.t)])}}else if(s&&s._agentWarning){const r=s.message??s.code??i.t("warnings.agentWarningFallback");o.warnings=[...o.warnings,`${i.t("warnings.noteLabel")}: ${r}`]}else{const r=s?.type??"(unknown)";o.warnings=[...o.warnings,i.t("warnings.unhandledEvent",{type:r})]}break}}return o}function zoe(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n+=1)if(e[n]!==t[n])return!1;return!0}function Or(e,t){for(const n of Object.keys(t))Object.is(e[n],t[n])||(e[n]=t[n]);for(const n of Object.keys(e))n in t||delete e[n]}const Ooe=[{pattern:/\brm\s+(?:-[a-zA-Z]*[rf][a-zA-Z]*|--recursive|--force)\b/,detail:"rm -rf"},{pattern:/\bsudo\b/,detail:"sudo"},{pattern:/\bmkfs(?:\.[a-z0-9]+)?\b/,detail:"mkfs"},{pattern:/\bdd\b[^|;&]*\bof=/,detail:"dd of=…"},{pattern:/>\s*\/dev\/(?:sd|nvme|disk|hd)/,detail:"> /dev/…"},{pattern:/:\(\)\s*\{/,detail:"fork bomb"},{pattern:/\bgit\s+push\b[^|;&]*(?:--force(?:-with-lease)?\b|\s-f\b)/,detail:"git push --force"},{pattern:/\bchmod\s+(?:-[a-zA-Z]+\s+)*777\b/,detail:"chmod 777"},{pattern:/\b(?:curl|wget)\b[^|;&]*\|\s*(?:sudo\s+)?(?:ba|z)?sh\b/,detail:"curl | sh"},{pattern:/\b(?:shutdown|reboot|poweroff|halt)\b/,detail:"shutdown / reboot"}];function Poe(e){const t=e.replace(/"[^"]*"|'[^']*'/g," ");for(const{pattern:n,detail:i}of Ooe)if(n.test(t))return i}const sB="kimiWeb.taskNotification",joe=/<notification\b([^>]*)>([\s\S]*?)<\/notification>/g,Hoe=/([\w-]+)="([^"]*)"/g,Woe=/<output-file\b([^>]*)>[\s\S]*?<\/output-file>/,qoe=/<output-preview\b([^>]*)>([\s\S]*?)<\/output-preview>/,Uoe=/^Title: (.*)$/m,Koe=/^Severity: (.*)$/m;function kv(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function a3(e){const t={};for(const n of e.matchAll(Hoe))n[1]!==void 0&&n[2]!==void 0&&(t[n[1]]=kv(n[2]));return t}function Voe(e,t,n){const i=a3(e),o=Uoe.exec(t)?.[1]?.trim()??"",s=Koe.exec(t)?.[1]?.trim()??"";let r=t.split(` -`).filter(h=>!h.startsWith("Title: ")&&!h.startsWith("Severity: ")).join(` -`);const l=r.search(/^<\w/m);l!==-1&&(r=r.slice(0,l)),r=r.trim();const a=Woe.exec(t),u=a?(()=>{const h=a3(a[1]??""),p=Number(h.bytes);return h.path!==void 0&&h.path!==""?{path:h.path,bytes:Number.isFinite(p)?p:void 0}:void 0})():void 0,c=qoe.exec(t),d=c?(()=>{const h=a3(c[1]??""),p=(c[2]??"").replace(/^\n/,""),g=p.indexOf(` -`),m=kv(g===-1?"":p.slice(g+1)).replace(/\n$/,""),k=Number(h.bytes),w=Number(h.total_bytes);return{text:m,bytes:Number.isFinite(k)?k:void 0,totalBytes:Number.isFinite(w)?w:void 0,truncated:h.truncated==="true"?!0:h.truncated==="false"?!1:void 0}})():void 0;return{id:i.id??"",category:i.category??"",type:i.type??"",sourceKind:i.source_kind??"",sourceId:i.source_id??"",agentId:i.agent_id,title:kv(o),severity:s,body:kv(r),outputFile:u,outputPreview:d,raw:n}}function Zoe(e){if(!e.includes("<notification"))return[];const t=[];for(const n of e.matchAll(joe))n[1]===void 0||n[2]===void 0||t.push(Voe(n[1],n[2],n[0]));return t}function Goe(e){const t=e?.[sB];if(typeof t!="object"||t===null)return;const n=t;for(const i of["id","category","type","sourceKind","sourceId","title","severity","body","raw"])if(typeof n[i]!="string")return;return t}function Tb(e){for(const t of["completed","failed","timed_out","killed","lost"])if(e.type.endsWith(`.${t}`))return t;return"info"}function Qoe(e){const t=Tb(e);return t==="completed"?"ok":t==="failed"||t==="timed_out"||t==="lost"?"err":t==="killed"?"warn":e.severity==="error"?"err":e.severity==="warning"?"warn":"info"}const Yoe=1e6,sS=5e3;function Ha(e){return e===""?[]:e.endsWith(` -`)?e.slice(0,-1).split(` -`):e.split(` -`)}function A2(e,t){const n=Ha(e),i=Ha(t),o=n.length,s=i.length;if(o===0&&s===0)return[];if(o>sS||s>sS||(o+1)*(s+1)>Yoe)return null;const r=Array.from({length:o+1},()=>Array.from({length:s+1},()=>0));for(let p=1;p<=o;p++)for(let g=1;g<=s;g++)r[p][g]=n[p-1]===i[g-1]?r[p-1][g-1]+1:Math.max(r[p-1][g],r[p][g-1]);const l=[];let a=o,u=s;for(;a>0||u>0;)a>0&&u>0&&n[a-1]===i[u-1]?(l.push({type:"context",text:n[a-1]}),a--,u--):u>0&&(a===0||r[a][u-1]>=r[a-1][u])?(l.push({type:"add",text:i[u-1]}),u--):(l.push({type:"del",text:n[a-1]}),a--);l.reverse();const c=[];let d=1,h=1;for(const p of l)p.type==="context"?(c.push({type:"context",text:p.text,oldNo:d,newNo:h}),d++,h++):p.type==="add"?(c.push({type:"add",text:p.text,newNo:h}),h++):(c.push({type:"del",text:p.text,oldNo:d}),d++);return c}const rS=500;function lS(e,t){const n=[],i=Ha(e),o=Ha(t),s=Math.min(i.length,rS),r=Math.min(o.length,rS);for(let l=1;l<=s;l++)n.push({type:"del",text:i[l-1],oldNo:l});i.length>s&&n.push({type:"context",text:`… ${i.length-s} more lines …`});for(let l=1;l<=r;l++)n.push({type:"add",text:o[l-1],newNo:l});return o.length>r&&n.push({type:"context",text:`… ${o.length-r} more lines …`}),n}function rB(e){let t=0,n=0;for(const i of e)i.type==="add"?t++:i.type==="del"&&n++;return{added:t,removed:n}}const Joe=/^read[_-]?media(?:file)?$/i,Xoe=/^data:([^;]+);base64,(.*)$/s,ese=/^<(image|video|audio)\s+path="([^"]+)">$/,tse=/^<(image|video|audio)\s+path="([^"]+)">(?:<\/\1>)?$/,nse=/Mime type:\s*([^.\s]+)/i,ise=/Size:\s*(\d+)\s*bytes/i,ose=/Original dimensions:\s*(\d+)x(\d+)\s*pixels/i,sse="<system>Image compressed to fit model limits:",rse=/<system>Image compressed to fit model limits:[\s\S]*?<\/system>/g;function lse(e){return e.includes(sse)?e.replace(rse,""):e}function ase(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function aS(e){const t=tse.exec(e.trim());return t?{kind:t[1],path:ase(t[2])}:null}const lB=/^f_(?:[0-9A-Za-z]{26}|[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})$/,use=/^f_(?:[0-9A-Za-z]{26}|[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12})(?=-)/;function Lb(e){const t=e.split(/[\\/]/).at(-1)??"",n=t.lastIndexOf("."),i=n>0?t.slice(0,n):t;return lB.test(i)?i:void 0}const cse=/^Attached file "(.+)" \(([^,]+), (\d+) bytes\): (.+) — open it with the Read tool$/;function uS(e){const t=cse.exec(e.trim());if(!t)return null;const n=(t[4]??"").split(/[\\/]/).at(-1)??"",i=use.exec(n)?.[0];return{name:t[1],mediaType:t[2],size:Number(t[3]),fileId:i!==void 0&&lB.test(i)?i:void 0}}function dse(e){if(e.length===0)return 0;const t=e.endsWith("==")?2:e.endsWith("=")?1:0;return Math.floor(e.length*3/4)-t}function fse(e){if(Array.isArray(e))return e;if(typeof e!="string")return null;try{const t=JSON.parse(e);return Array.isArray(t)?t:null}catch{return null}}function hse(e){const t=e.type,n=t==="image_url"?"image":t==="video_url"?"video":t==="audio_url"?"audio":null;if(n===null)return null;const o=e[n==="image"?"imageUrl":n==="video"?"videoUrl":"audioUrl"];if(typeof o!="object"||o===null)return null;const s=o.url;return typeof s=="string"?{kind:n,url:s}:null}function pse(e,t){if(!Joe.test(e))return;const n=fse(t);if(n===null)return;let i,o,s,r,l,a=null;for(const c of n){if(typeof c!="object"||c===null)continue;const d=c;if(d.type==="text"&&typeof d.text=="string"){const p=d.text,g=ese.exec(p);g&&(o=g[1],i=g[2]);const m=nse.exec(p);m?.[1]&&(s=m[1]);const k=ise.exec(p);k?.[1]&&(r=Number(k[1]));const w=ose.exec(p);w?.[1]&&w[2]&&(l=`${w[1]}x${w[2]}`);continue}const h=hse(d);h&&(a=h)}if(a===null)return;const u=Xoe.exec(a.url);return u?.[1]&&(s=u[1]),u?.[2]&&(r=dse(u[2])),{kind:a.kind??o??"image",url:a.url,path:i,fileId:a.url.startsWith("ms://")&&i!==void 0?Lb(i):void 0,mimeType:s,bytes:Number.isFinite(r)?r:void 0,dimensions:l}}function x6(e){if(e!=null){if(typeof e=="string")return e.split(` -`);if(Array.isArray(e)){const t=[];for(const n of e)if(typeof n=="string")t.push(...n.split(` -`));else if(n&&typeof n=="object"){const i=n;i.type==="text"&&typeof i.text=="string"?t.push(...i.text.split(` -`)):i.type==="think"&&typeof i.think=="string"?t.push(...i.think.split(` -`)):i.type==="image_url"||i.type==="image"?t.push("[image]"):typeof i.type=="string"?t.push(`[${i.type}]`):t.push(JSON.stringify(n))}return t.length>0?t:void 0}return[JSON.stringify(e)]}}function gse(e,t){if(Gs(e)==="task")for(const n of t??[]){const i=/^agent_id:\s*(\S+)\s*$/.exec(n);if(i?.[1])return i[1]}}function mse(e,t){return{id:e.agentId??e.id,toolCallId:e.parentToolCallId,name:e.description,subagentType:e.subagentType,prompt:e.command??t,model:e.model,thinkingEffort:e.thinkingEffort,phase:e.status==="completed"?"completed":e.status==="failed"?"failed":e.status==="cancelled"?"cancelled":e.subagentPhase??"working",status:e.status,summary:e.outputPreview,outputLines:e.outputLines,text:e.text,suspendedReason:e.suspendedReason,swarmIndex:e.swarmIndex}}function aB(e){const t=e.display??{},n=typeof t.kind=="string"?t.kind:"";if(n==="diff"){const i=typeof t.path=="string"?t.path:"";if(Array.isArray(t.diff))return{kind:"diff",path:i,diff:t.diff};const o=typeof t.old_text=="string"?t.old_text:typeof t.before=="string"?t.before:void 0,s=typeof t.new_text=="string"?t.new_text:typeof t.after=="string"?t.after:void 0;if(o!==void 0&&s!==void 0){const r=A2(o,s)??lS(o,s);return{kind:"diff",path:i,diff:r}}return{kind:"diff",path:i,diff:[]}}if(n==="file_io"){const i=typeof t.path=="string"?t.path:"",o=typeof t.operation=="string"?t.operation:"";if(o==="write"&&typeof t.content=="string")return{kind:"file",path:i,content:t.content};if(o==="edit"&&typeof t.before=="string"&&typeof t.after=="string"){const r=A2(t.before,t.after)??lS(t.before,t.after);return{kind:"diff",path:i,diff:r}}const s=typeof t.detail=="string"?t.detail:void 0;return{kind:"fileop",op:o||n,path:i,detail:s}}if(n==="shell"||n==="command"){const i=typeof t.command=="string"?t.command:e.action;return{kind:"shell",command:i,cwd:typeof t.cwd=="string"?t.cwd:void 0,danger:typeof t.danger=="string"?t.danger:Poe(i)}}if(n==="file_content"||n==="file")return{kind:"file",path:typeof t.path=="string"?t.path:"",content:typeof t.content=="string"?t.content:"",language:typeof t.language=="string"?t.language:void 0};if(n==="file_op"||n==="fileop")return{kind:"fileop",op:typeof t.operation=="string"?t.operation:typeof t.op=="string"?t.op:n,path:typeof t.path=="string"?t.path:"",detail:typeof t.detail=="string"?t.detail:void 0};if(n==="url_fetch"||n==="url")return{kind:"url",method:typeof t.method=="string"?t.method:void 0,url:typeof t.url=="string"?t.url:e.action};if(n==="search")return{kind:"search",query:typeof t.query=="string"?t.query:e.action,scope:typeof t.scope=="string"?t.scope:void 0};if(n==="invocation"||n==="agent_call"||n==="skill_call")return{kind:"invocation",kind2:typeof t.kind=="string"?t.kind:n,name:typeof t.name=="string"?t.name:e.toolName,description:typeof t.description=="string"?t.description:void 0};if(n==="todo"||n==="todo_list")return{kind:"todo",items:(Array.isArray(t.items)?t.items:[]).map(s=>{const r=s??{};return{title:typeof r.title=="string"?r.title:"",status:typeof r.status=="string"?r.status:"pending"}})};if(n==="plan_review"){const i=typeof t.plan=="string"?t.plan:"",o=typeof t.path=="string"?t.path:void 0,r=(Array.isArray(t.options)?t.options:[]).map(l=>{const a=l??{},u=typeof a.label=="string"?a.label:"";if(!u)return null;const c=typeof a.description=="string"?a.description:void 0;return{label:u,description:c}}).filter(l=>l!==null);return{kind:"plan_review",plan:i,path:o,options:r.length>0?r:void 0}}return{kind:"generic",summary:e.action}}function vse(e){const t=`<prompt> -`,n=` -</prompt>`,i=e.indexOf(t),o=e.lastIndexOf(n);return i>=0&&o>=i+t.length?e.slice(i+t.length,o):yse(e)}function yse(e){const t=e.split(` -`);return t.length>=2&&t[0]?.startsWith("<cron-fire ")&&t.at(-1)==="</cron-fire>"?t.slice(1,-1).join(` -`):e}function kse(e){const t=e.metadata?.origin;if(t?.kind==="cron_job"||t?.kind==="cron_missed")return t.kind}function bse(e){const t=e.content.filter(n=>n.type==="text").map(n=>n.text).join(` -`);return vse(t)}function Ase(e,t){const n=e.metadata?.origin??{},i=bse(e);return t==="cron_missed"?{text:i,cron:{missedCount:typeof n.count=="number"?n.count:void 0}}:{text:i,cron:{jobId:typeof n.jobId=="string"?n.jobId:void 0,cron:typeof n.cron=="string"?n.cron:void 0,recurring:typeof n.recurring=="boolean"?n.recurring:void 0,coalescedCount:typeof n.coalescedCount=="number"?n.coalescedCount:void 0,stale:typeof n.stale=="boolean"?n.stale:void 0}}}function Cse(e,t,n){const{text:i,cron:o}=Ase(e,n);return{id:e.id,role:"cron",no:t,text:i,createdAt:e.createdAt,cron:o}}function wse(e){const t=e.metadata?.origin,n=t?.kind;return n===void 0||n==="user"?!0:n==="skill_activation"||n==="plugin_command"?t?.trigger==="user-slash":!1}function xse(e){return e.metadata?.origin?.kind==="compaction_summary"}function Sse(e,t){return e===null?!1:e.promptId===void 0||t===void 0||e.promptId===t}function _se(e){if(!e||e.length===0)return;const t="Plan saved to: ";for(const n of e)if(n.startsWith(t))return n.slice(t.length).trim()}function Mse(e){const t=[];for(const n of e){const i=t.at(-1);n.type==="text"&&i?.type==="text"?i.text+=n.text:n.type==="thinking"&&i?.type==="thinking"?i.thinking+=n.thinking:n.type==="thinking"?t.push({type:"thinking",thinking:n.thinking}):t.push({...n})}return JSON.stringify(t)}function uB(e,t,n,i=!0,o={},s={},r){const l=[];let a=r?.startNo??1;const u=r?.collect,c=new Map;for(const m of t)c.set(m.toolCallId,m);let d=null;function h(m=!1){if(!d)return;const k=d;if(d=null,!m&&k.blocks.length===0&&k.textParts.length===0&&k.thinkingParts.length===0&&k.tools.length===0)return;if(!m||!i)for(let y=0;y<k.tools.length;y++){const b=k.tools[y];if(b.status!=="running")continue;const A={...b,status:"ok"};k.tools[y]=A;const T=k.blocks.find(S=>S.kind==="tool"&&S.tool.id===A.id);T&&T.kind==="tool"&&(T.tool=A)}const w={id:k.id,role:"assistant",no:a++,text:k.textParts.join(` -`),thinking:k.thinkingParts.length>0?k.thinkingParts.join(` -`):void 0,tools:k.tools.length>0?k.tools:void 0,blocks:k.blocks.length>0?k.blocks:void 0,approval:k.approval,approvalId:k.approvalId,durationMs:k.durationMs,createdAt:k.createdAt,endedAt:k.endedAt,goalContinuation:k.goalContinuation};l.push(w),u?.(w,k.sources)}function p(m,k){let w=null;for(const y of k)if(y.type==="text"){if(y.text){w==="text"?m.textParts[m.textParts.length-1]+=y.text:m.textParts.push(y.text);const b=m.blocks.at(-1);b&&b.kind==="text"?b.text+=(w==="text"?"":` -`)+y.text:m.blocks.push({kind:"text",text:y.text}),w="text"}}else if(y.type==="thinking"){if(y.thinking){w==="thinking"?m.thinkingParts[m.thinkingParts.length-1]+=y.thinking:m.thinkingParts.push(y.thinking);const b=m.blocks.at(-1);if(b&&b.kind==="thinking"){b.thinking+=(w==="thinking"?"":` -`)+y.thinking;const A=[b.startedAt,y.startedAt].filter(x=>x!==void 0).sort()[0],T=b.startedAt!==void 0&&b.durationMs===void 0||y.startedAt!==void 0&&y.durationMs===void 0,S=[b,y].flatMap(x=>x.startedAt!==void 0&&x.durationMs!==void 0?[Date.parse(x.startedAt)+x.durationMs]:[]);b.startedAt=A,b.durationMs=!T&&A!==void 0&&S.length>0?Math.max(...S)-Date.parse(A):void 0}else m.blocks.push({kind:"thinking",thinking:y.thinking,startedAt:y.startedAt,durationMs:y.durationMs});w="thinking"}}else if(y.type==="toolUse"){w=null;const b=c.get(y.toolCallId),A=y.toolName==="ExitPlanMode"?s[y.toolCallId]:void 0,T={id:y.toolCallId,name:y.toolName,arg:typeof y.input=="string"?y.input:JSON.stringify(y.input),agentId:Gs(y.toolName)==="task"?y.agentRefs?.find(S=>S.role!=="member")?.agentId??y.agentRefs?.[0]?.agentId:void 0,status:"running",output:y.outputLines,plan:A,planPath:y.toolName==="ExitPlanMode"?A?.path??o[y.toolCallId]?.path:void 0};m.tools.push(T),m.blocks.push({kind:"tool",tool:T}),b&&(m.approval=aB(b),m.approvalId=b.approvalId)}else if(y.type==="toolResult"){w=null;const b=m.tools.findIndex(A=>A.id===y.toolCallId);if(b!==-1){const A=m.tools[b],T=x6(y.output),S={...A,status:y.isError?"error":"ok",output:T,media:y.isError?void 0:pse(A.name,y.output),agentId:A.agentId??gse(A.name,T)};S.name==="ExitPlanMode"&&!S.planPath&&(S.planPath=_se(S.output)),m.tools[b]=S;const x=m.blocks.find(_=>_.kind==="tool"&&_.tool.id===y.toolCallId);x&&x.kind==="tool"&&(x.tool=S)}}else w=null}function g(m,k){if(m.type==="image"||m.type==="video"){const w=m.type,y=m.source;if(y.kind==="url")return{url:y.url,kind:w};if(y.kind==="base64")return{url:`data:${y.mediaType};base64,${y.data}`,kind:w};if(y.kind==="file"&&n)return{url:n(y.fileId),kind:w,fileId:y.fileId};if(y.kind==="sessionMedia")return{url:r?.getSessionMediaUrl?.(k,y.fileId)??"",kind:w,fileId:y.fileId,sessionId:k}}if(m.type==="file"&&n){if(m.mediaType.startsWith("image/"))return{url:n(m.fileId),kind:"image",fileId:m.fileId};if(m.mediaType.startsWith("video/"))return{url:n(m.fileId),kind:"video",fileId:m.fileId}}}for(const m of e){if(m.role==="system")continue;if(xse(m)){h();const A=m.metadata?.[oB],T={id:m.id,role:"compaction",no:a,text:m.content.filter(S=>S.type==="text").map(S=>S.text).join(` -`),compaction:{trigger:A?.trigger,tokensBefore:A?.tokensBefore,tokensAfter:A?.tokensAfter}};l.push(T),u?.(T,[m]);continue}if(m.role==="user"){const A=kse(m),T=m.metadata?.origin?.kind,S=T==="skill_activation"&&m.metadata?.origin?.trigger!=="user-slash";if(A===void 0&&(T==="injection"||S))continue;if(A===void 0&&(T==="task"||T==="background_task"||T==="task_notification")){const z=m.content.filter(R=>R.type==="text").map(R=>R.text).join(` -`),H=Goe(m.metadata),O=H!==void 0?[H]:Zoe(z);if(O.length>0){d??={id:m.id,promptId:void 0,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[m],createdAt:m.createdAt};for(const R of O)d.blocks.push({kind:"notification",notification:{...R,createdAt:m.createdAt}})}continue}if(h(),A!==void 0){const z=Cse(m,a++,A);l.push(z),u?.(z,[m]);continue}if(T==="system_trigger"&&m.metadata?.origin?.name==="goal_continuation"){d={id:m.id,promptId:void 0,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[m],createdAt:m.createdAt,goalContinuation:!0};continue}if(!wse(m))continue;const x=m.metadata?.origin,_=x?.kind==="skill_activation"&&x?.trigger==="user-slash",L=x?.kind==="plugin_command"&&x?.trigger==="user-slash",M=[],N=[];for(const z of m.content){if(z.type==="text")if(_){const O=aS(z.text);if(O&&(O.kind==="video"||O.kind==="image")&&n){const j=Lb(O.path);if(j){N.push({url:n(j),kind:O.kind,fileId:j});continue}}const R=uS(z.text);R&&N.push({kind:"file",url:R.fileId&&n?n(R.fileId):"",fileId:R.fileId,name:R.name,mediaType:R.mediaType,size:R.size})}else if(L)M.push(x.commandArgs??"");else{const O=aS(z.text);if(O&&(O.kind==="video"||O.kind==="image")&&n){const $=Lb(O.path);if($){N.push({url:n($),kind:O.kind,fileId:$});continue}}const R=uS(z.text);if(R){N.push({kind:"file",url:R.fileId&&n?n(R.fileId):"",fileId:R.fileId,name:R.name,mediaType:R.mediaType,size:R.size});continue}const j=lse(z.text);if(j!==z.text&&j.trim().length===0)continue;M.push(j)}const H=g(z,m.sessionId);if(H){N.push({url:H.url,kind:H.kind,name:z.type==="file"?z.name:void 0,fileId:H.fileId,sessionId:H.sessionId});continue}z.type==="file"&&n&&N.push({kind:"file",url:n(z.fileId),fileId:z.fileId,name:z.name,mediaType:z.mediaType||void 0,size:z.size})}const I={id:m.id,role:"user",no:a++,text:_?x?.skillArgs??"":M.join(` -`),attachments:N.length>0?N:void 0,skillActivation:_?{name:x.skillName,args:x.skillArgs}:void 0,pluginCommand:L?{pluginId:x.pluginId,commandName:x.commandName,args:x.commandArgs}:void 0,createdAt:m.createdAt};l.push(I),u?.(I,[m]);continue}if(m.role==="tool"){d&&(d.sources.push(m),p(d,m.content),d.endedAt=m.createdAt);continue}const k=m.promptId;Sse(d,k)?d!==null&&d.promptId===void 0&&k!==void 0&&(d.promptId=k):(h(),d={id:m.id,promptId:k,textParts:[],thinkingParts:[],tools:[],blocks:[],approval:void 0,approvalId:void 0,seenSigs:new Set,sources:[],durationMs:m.durationMs,createdAt:m.createdAt});const y=d;if(y===null)continue;const b=Mse(m.content);y.promptId!==void 0&&y.seenSigs.has(b)||(y.seenSigs.add(b),y.sources.push(m),m.durationMs!==void 0&&(y.durationMs=m.durationMs),p(y,m.content),m.endedAt!==void 0?y.endedAt=m.endedAt:m.id!==y.id&&(y.endedAt=m.createdAt))}return h(!0),l}function Ise(e,t,n,i){const o=e.items.filter(c=>c.kind==="turn"),s=o[0]?.turnId,r=o.length===1?s:void 0,l=new Map(e.tasks.map(c=>[c.taskId,c])),a=e.items.flatMap(c=>c.kind==="turn"?Ese(c,e.attachments,l,c.turnId===s?n?.createdAt:void 0,c.turnId===r?n?.disposedAt:void 0,i?.sessionId):[]),u=e.meta.activity==="turn";return uB(a,[],t,u,{},{},{getSessionMediaUrl:i?.getSessionMediaUrl}).map(Lse)}function Ese(e,t,n,i,o,s=""){const r=[],l=new Map(t.map(h=>[h.attachmentId,h])),a=Nse([e.startedAt,...e.steps.map(h=>h.startedAt),i])??"",u=cS(e.endedAt)??cS(o),c=e.turnId;if(e.prompt!==void 0&&e.prompt.length>0){const h=[{type:"text",text:e.prompt}];for(const p of e.attachmentIds??[]){const g=Fse(l.get(p));g!==void 0&&h.push(g)}r.push({id:`${e.turnId}:input`,sessionId:s,role:"user",content:h,createdAt:a,promptId:c,metadata:e.origin.kind==="task"&&e.prompt.includes("<notification")?{origin:e.origin.payload??e.origin}:void 0})}for(const h of e.steps)for(const p of h.frames)if(p.kind==="text"){if(p.text.length===0)continue;if(p.role==="user"){if(p.taskId===void 0)continue;const g=Tse(p.taskId,p.text,n.get(p.taskId));r.push({id:p.frameId,sessionId:"",role:"user",content:[{type:"text",text:p.text}],createdAt:h.startedAt??a,promptId:c,metadata:{origin:{kind:"task",taskId:p.taskId},[sB]:g}});continue}r.push({id:p.frameId,sessionId:"",role:"assistant",content:[{type:"text",text:p.text}],createdAt:h.startedAt??a,promptId:c})}else if(p.kind==="thinking"){if(p.text.length===0)continue;r.push({id:p.frameId,sessionId:"",role:"assistant",content:[{type:"thinking",thinking:p.text,startedAt:h.startedAt,durationMs:dS(h.startedAt,h.endedAt)}],createdAt:h.startedAt??a,promptId:c})}else p.kind==="tool"&&(r.push({id:`${p.frameId}:call`,sessionId:"",role:"assistant",content:[{type:"toolUse",toolCallId:p.toolCallId,toolName:p.name,input:p.input??p.display??{},outputLines:p.state==="running"?x6(p.output):void 0,agentRefs:p.agentRefs}],createdAt:h.startedAt??a,promptId:c}),p.state!=="running"&&r.push({id:`${p.frameId}:result`,sessionId:"",role:"tool",content:[{type:"toolResult",toolCallId:p.toolCallId,output:p.output??p.error??"",isError:p.state==="error"}],createdAt:h.endedAt??h.startedAt??a,promptId:c}));const d=e.durationMs??dS(a||void 0,u);if(d!==void 0){const h=r.findLastIndex(p=>p.role==="assistant");h>=0&&(r[h]={...r[h],durationMs:d})}return r}function Tse(e,t,n){const[i="",...o]=t.split(` -`),s=n?.state??"info";return{id:`task:${e}:${s}`,category:"task",type:`task.${s}`,sourceKind:n?.kind==="subagent"?"subagent":"background_task",sourceId:e,agentId:n?.agentId,title:i.trim(),severity:s==="completed"?"info":"warning",body:o.join(` -`).trim(),raw:t}}function Lse(e){if(e.createdAt!==""&&e.endedAt!=="")return e;const t={...e};return t.createdAt===""&&delete t.createdAt,t.endedAt===""&&delete t.endedAt,t}function Nse(e){let t;for(const n of e){if(n===void 0)continue;const i=Date.parse(n);Number.isFinite(i)&&(t===void 0||i<t.time)&&(t={value:n,time:i})}return t?.value}function cS(e){return e!==void 0&&Number.isFinite(Date.parse(e))?e:void 0}function Fse(e){if(e?.source===void 0)return;const t=e.source.kind==="url"?{kind:"url",url:e.source.url}:e.source.kind==="session_media"?{kind:"sessionMedia",fileId:e.source.fileId}:{kind:"file",fileId:e.source.fileId};if(e.mediaType.startsWith("image/"))return{type:"image",source:t};if(e.mediaType.startsWith("video/"))return{type:"video",source:t};if(e.source.kind==="file")return{type:"file",fileId:e.source.fileId,name:e.name??e.attachmentId,mediaType:e.mediaType,size:e.size??0}}function dS(e,t){if(e===void 0||t===void 0)return;const n=Date.parse(t)-Date.parse(e);return Number.isFinite(n)&&n>=0?n:void 0}const fS=6e3,Nb=256*1024,Dse=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;function hS(e,t){return t===0?e:e-1}function Bse(e,t){const n=Ha(t),i=[];let o=0;for(const s of e){if(s.type==="hunk"){const r=Dse.exec(s.text);if(!r)return null;const l=hS(Number(r[1]),r[2]===void 0?1:Number(r[2])),a=hS(Number(r[3]),r[4]===void 0?1:Number(r[4]));if(a<o||a>n.length)return null;for(;o<a;)i.push(n[o++]);if(i.length!==l)return null;continue}if(s.oldNo===void 0&&s.newNo===void 0)return null;if(s.type==="del"){i.push(s.text);continue}if(o>=n.length||n[o]!==s.text)return null;o++,s.type==="context"&&i.push(s.text)}for(;o<n.length;)i.push(n[o++]);return i.join(` -`)}async function $se(e,t){if(t.truncated||e.length===0)return null;const n=await t.readNewText()??"";if(n.length>Nb||Ha(n).length>fS)return null;const i=Bse(e,n);return i===null||i.length>Nb||Ha(i).length>fS?null:{before:i,after:n}}const Rse=new Set(["assistantDelta","agentDelta","toolOutput","taskProgress"]);function zse(e){return Rse.has(e.type)}const Ose=50,Pse=100,Fb=32*1024,jse={requestFrame(e){return typeof requestAnimationFrame=="function"?requestAnimationFrame(e):null},cancelFrame(e){typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(e)},requestTask(e){return setTimeout(e,Ose)},cancelTask(e){clearTimeout(e)}};function Hse(e,t,n={}){const i=n.scheduler??jse,o=Math.max(1,Math.floor(n.maxItemsPerSlice??Pse)),s=[];let r=0,l=null,a=null,u=0,c=!1;const d=()=>s.length-r,h=()=>{u+=1,l!==null&&(i.cancelFrame(l),l=null),a!==null&&(i.cancelTask(a),a=null)},p=()=>{r===s.length?(s.length=0,r=0):r>=1024&&(s.splice(0,r),r=0)};let g;const m=()=>{if(c||l!==null||a!==null||d()===0)return;const w=++u,y=()=>{w===u&&g()};l=i.requestFrame(y),a=i.requestTask(y)};g=()=>{h();let w=0;for(;!c&&w<o&&r<s.length;){const y=s[r++];e(y),w+=1}p(),m()};const k=(w=>{if(!c){if(t(w)){const y=s.length>r?s.at(-1):void 0,b=y===void 0?void 0:n.coalesce?.(y,w);b===void 0?s.push(w):s[s.length-1]=b,m();return}if(d()===0){e(w);return}s.push(w),g()}});return k.flush=()=>{if(!c){for(h();!c&&r<s.length;)e(s[r++]);p()}},k.discard=w=>{if(c||d()===0)return;let y=r;for(let b=r;b<s.length;b+=1){const A=s[b];w(A)||(s[y++]=A)}s.length=y,p(),d()===0?h():m()},k.dispose=()=>{c||(c=!0,h(),s.length=0,r=0)},k}function Db(e){if(e.type==="assistantDelta"){if(e.delta.text!==void 0&&e.delta.thinking===void 0)return{kind:"text",value:e.delta.text};if(e.delta.thinking!==void 0&&e.delta.text===void 0)return{kind:"thinking",value:e.delta.thinking}}}function Wse(e){if(e.appEvent.type!=="assistantDelta")return[e];const t=e.appEvent,n=e.meta.stream,i=Db(t);if(n===void 0||i===void 0||n.kind!==i.kind||i.value.length<=Fb)return[e];const o=[];let s=0;for(;s<i.value.length;){let r=Math.min(s+Fb,i.value.length);r<i.value.length&&r>s&&/[\uD800-\uDBFF]/u.test(i.value[r-1])&&/[\uDC00-\uDFFF]/u.test(i.value[r])&&(r-=1);const l=i.value.slice(s,r);o.push({appEvent:{...t,delta:i.kind==="text"?{text:l}:{thinking:l}},meta:{...e.meta,stream:{...n,offset:n.offset+s}}}),s=r}return o}function qse(e,t){if(e.appEvent.type!=="assistantDelta"||t.appEvent.type!=="assistantDelta")return;const n=e.meta.stream,i=t.meta.stream,o=Db(e.appEvent),s=Db(t.appEvent);if(n===void 0||i===void 0||o===void 0||s===void 0||e.meta.sessionId!==t.meta.sessionId||e.appEvent.sessionId!==t.appEvent.sessionId||e.appEvent.messageId!==t.appEvent.messageId||e.appEvent.contentIndex!==t.appEvent.contentIndex||n.turnId!==i.turnId||n.kind!==i.kind||o.kind!==s.kind||n.kind!==o.kind||i.kind!==s.kind||i.offset!==n.offset+o.value.length||o.value.length+s.value.length>Fb)return;const r=o.value+s.value;return{appEvent:{...e.appEvent,delta:o.kind==="text"?{text:r}:{thinking:r}},meta:{...t.meta,stream:{...n}}}}function Use(e){return e==="in_progress"?"in_progress":e==="done"||e==="completed"?"done":"pending"}function Kse(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.role==="assistant")for(let i=n.content.length-1;i>=0;i--){const o=n.content[i];if(o.type!=="toolUse"||Gs(o.toolName)!=="todo")continue;let s=o.input;if(typeof s=="string")try{s=JSON.parse(s)}catch{continue}const r=s?.todos;if(Array.isArray(r))return r.flatMap(l=>{const a=l??{},u=typeof a.title=="string"?a.title:typeof a.content=="string"?a.content:"";return u?[{title:u,status:Use(a.status)}]:[]})}}return[]}function Vse(e){return e.startsWith("diff --git")||e.startsWith("index ")||e.startsWith("--- ")||e.startsWith("+++ ")||e.startsWith("new file mode")||e.startsWith("deleted file mode")||e.startsWith("old mode")||e.startsWith("new mode")||e.startsWith("similarity index")||e.startsWith("dissimilarity index")||e.startsWith("rename from")||e.startsWith("rename to")||e.startsWith("copy from")||e.startsWith("copy to")||e.startsWith("Binary files")}function Zse(e){const t=[];if(!e)return t;let n=0,i=0,o=!1;for(const s of e.split(` -`)){if(s.startsWith("diff --git")){o=!1;continue}if(!o&&Vse(s))continue;if(s.startsWith("@@")){const a=/^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/.exec(s);a&&(n=Number.parseInt(a[1],10),i=Number.parseInt(a[2],10)),o=!0,t.push({type:"hunk",text:s});continue}if(!o||s.startsWith("\\"))continue;const r=s.charAt(0),l=s.slice(1);r==="+"?(t.push({type:"add",text:l,newNo:i}),i+=1):r==="-"?(t.push({type:"del",text:l,oldNo:n}),n+=1):r===" "&&(t.push({type:"context",text:l,oldNo:n,newNo:i}),n+=1,i+=1)}return t}function pS(e){return e?e.split(` -`).map(t=>t.trimEnd()).filter(Boolean).at(-1)??"":""}function Gse(e){return e.suspendedReason||pS(e.text)||pS(e.outputLines?.join(` -`))||e.summary||""}function Qse(e){return e.suspendedReason?e.suspendedReason:e.text?e.text:e.outputLines&&e.outputLines.length>0?e.outputLines.join(` -`):e.summary??""}function Yse(e){return e==="completed"?"completed":e==="failed"?"failed":e==="aborted"?"cancelled":"working"}function gS(e,t){return{id:e.agentId??e.item??`result-${t}`,agentId:e.agentId,name:e.item??`subagent ${t+1}`,activity:e.body.split(` -`)[0]??"",phase:Yse(e.outcome),body:e.body}}function Jse(e,t){return!!(t.agentId&&e.agentId===t.agentId||t.item&&e.name.includes(t.item))}function Xse(e,t){const n=e.map(o=>({id:o.id,agentId:o.agentId,name:o.name,activity:Gse(o),phase:o.phase,body:Qse(o)}));if(!t)return n;const i=t.subagents.filter(o=>(o.outcome==="aborted"||o.state==="not_started")&&!e.some(s=>Jse(s,o))).map((o,s)=>gS(o,s));return n.length>0?[...n,...i]:t.subagents.map((o,s)=>gS(o,s))}const ere=["queued","working","suspended","completed","failed","cancelled"];function cB(e){return e.status==="completed"?"completed":e.status==="failed"?"failed":e.status==="cancelled"?"cancelled":e.subagentPhase?e.subagentPhase:"working"}function tre(){return{queued:0,working:0,suspended:0,completed:0,failed:0,cancelled:0}}function nre(e){const t=new Map;for(const n of e){if(n.kind!=="subagent"||n.swarmIndex===void 0)continue;const i=n.parentToolCallId??"swarm",o=t.get(i)??[];o.push({id:n.id,agentId:n.agentId,name:n.description,subagentType:n.subagentType,model:n.model,thinkingEffort:n.thinkingEffort,phase:cB(n),summary:n.outputPreview,outputLines:n.outputLines,text:n.text,suspendedReason:n.suspendedReason,swarmIndex:n.swarmIndex}),t.set(i,o)}return[...t.entries()].map(([n,i])=>{const o=i.toSorted((r,l)=>r.swarmIndex-l.swarmIndex||r.id.localeCompare(l.id)),s=tre();for(const r of o)s[r.phase]++;return{id:n,members:o,counts:s}}).filter(n=>n.members.length>1).toSorted((n,i)=>{const o=n.members.at(0)?.swarmIndex??0,s=i.members.at(0)?.swarmIndex??0;return o!==s?o-s:n.id.localeCompare(i.id)})}function ire(e){let t=0,n=0;for(const i of e){n+=i.members.length;for(const o of ere)(o==="completed"||o==="failed"||o==="cancelled")&&(t+=i.counts[o])}return{done:t,total:n}}function ore(e){const t=new Map;for(const n of e){if(n.kind!=="subagent"||!n.parentToolCallId)continue;const i=t.get(n.parentToolCallId)??[];i.push({id:n.id,agentId:n.agentId,name:n.description,subagentType:n.subagentType,model:n.model,thinkingEffort:n.thinkingEffort,phase:cB(n),summary:n.outputPreview,outputLines:n.outputLines,text:n.text,suspendedReason:n.suspendedReason,swarmIndex:n.swarmIndex??Number.MAX_SAFE_INTEGER}),t.set(n.parentToolCallId,i)}for(const[n,i]of t)t.set(n,i.toSorted((o,s)=>o.swarmIndex-s.swarmIndex||o.id.localeCompare(s.id)));return t}function S6(e){const t=e.trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function dB(e){for(const t of["path","file_path","filePath","filename"]){const n=e[t];if(typeof n=="string"&&n.length>0)return n}}const pp=100*1024;function fB(e){const t=Gs(e.name);if(t!=="edit"&&t!=="multi_edit")return null;const n=S6(e.arg);if(!n)return null;if(t==="edit"){if(n.replace_all===!0)return null;const l=typeof n.old_string=="string"?n.old_string:void 0,a=typeof n.new_string=="string"?n.new_string:void 0;return l===void 0||a===void 0||l.length>pp||a.length>pp?null:A2(l,a)}const i=Array.isArray(n.edits)?n.edits:void 0;if(!i||i.length===0)return null;const o=[];let s=0,r=0;for(const l of i){if(!l||typeof l!="object")return null;const a=l;if(a.replace_all===!0)return null;const u=typeof a.old_string=="string"?a.old_string:void 0,c=typeof a.new_string=="string"?a.new_string:void 0;if(u===void 0||c===void 0||u.length>pp||c.length>pp)return null;const d=A2(u,c);if(d===null)return null;o.length>0&&o.push({type:"hunk",text:"···"});for(const h of d)o.push({...h,oldNo:h.oldNo!==void 0?h.oldNo+s:void 0,newNo:h.newNo!==void 0?h.newNo+r:void 0});s+=Ha(u).length,r+=Ha(c).length}return o}const sre=5e3;function rre(e){if(Gs(e.name)!=="write")return null;const t=S6(e.arg);return!t||typeof t.content!="string"||t.content.length>pp||t.content.split(` -`).length>sre?null:{content:t.content,path:dB(t)}}function mS(e){const t=S6(e.arg);return t?dB(t):void 0}function hB(){let e=[],t=null,n=null,i=null,o,s,r=!0;const l=new WeakMap,a=u=>{const{messages:c,approvals:d}=u,h=u.sessionActive??!0,p=u.planReviewByToolCallId??{},g=u.plansByToolCallId??{},m=(_,L)=>l.set(_,L);let k=n!==null;if(k){const _=n,L=Object.keys(p);k=L.length===Object.keys(_).length&&L.every(M=>p[M]===_[M])}let w=i!==null;if(w){const _=i,L=Object.keys(g);w=L.length===Object.keys(_).length&&L.every(M=>g[M]===_[M])}const y=e.length>0&&d===t&&k&&w&&u.getFileUrl===o&&u.getSessionMediaUrl===s;let b=0,A=0,T=1;if(y){let _=-1;for(let L=e.length-1;L>=0;L--)if(e[L].role==="assistant"){_=L;break}for(let L=0;L<e.length;L++){const M=e[L],N=l.get(M);if(!N||N.length===0||L===_&&h!==r)break;let I=A+N.length<=c.length;for(let z=0;I&&z<N.length;z++)c[A+z]!==N[z]&&(I=!1);if(!I||L===_&&A+N.length!==c.length)break;b++,A+=N.length,M.role!=="compaction"&&T++}}const S=uB(c.slice(A),d,u.getFileUrl,h,p,g,{startNo:T,collect:m,getSessionMediaUrl:u.getSessionMediaUrl}),x=b>0?[...e.slice(0,b),...S]:S;return e=x,t=d,n={...p},i={...g},o=u.getFileUrl,s=u.getSessionMediaUrl,r=h,x};return a.reset=()=>{e=[],t=null,n=null,i=null,o=void 0,r=!0},a}const pB=["light","dark","system"],lre=["small","medium","large","xlarge"],u3="medium",gB="kimi-web.color-scheme",Bb="kimi-web.font-scale",vS="kimi-web.ui-font-size";function $b(e){try{return globalThis.localStorage.getItem(e)}catch{return null}}function _6(e,t){try{globalThis.localStorage.setItem(e,t)}catch{}}function are(e){try{globalThis.localStorage.removeItem(e)}catch{}}function ure(){const e=$b(gB);return e&&pB.includes(e)?e:"system"}const wm={light:"#ffffff",dark:"#121212"};function cre(e){if(typeof document>"u"||!document.documentElement)return;document.documentElement.dataset.colorScheme=e;const t=document.querySelectorAll('meta[name="theme-color"]');if(t.length===0)return;const n=e==="dark"?wm.dark:e==="light"?wm.light:null;t.forEach(i=>{const s=(i.getAttribute("media")??"").includes("dark")?wm.dark:wm.light;i.setAttribute("content",n??s)})}function mB(e){return lre.includes(e)}function dre(e){return e<=13?"small":e<=15?"medium":e<=17?"large":"xlarge"}function fre(){const e=$b(Bb);if(e==="xxlarge")return"xlarge";if(e!==null)return mB(e)?e:u3;const t=$b(vS);if(t===null)return u3;const n=Number(t),i=Number.isFinite(n)?dre(n):u3;return _6(Bb,i),are(vS),i}function hre(e){typeof document>"u"||!document.documentElement||(document.documentElement.dataset.fontScale=e)}const M6=K(ure()),I6=K(fre());let yS=!1;function pre(){yS||(yS=!0,Pe(M6,cre,{immediate:!0}),Pe(I6,hre,{immediate:!0}))}function gre(e){pB.includes(e)&&(M6.value=e,_6(gB,e))}function mre(e){mB(e)&&(I6.value=e,_6(Bb,e))}function c1(){return pre(),{colorScheme:M6,fontScale:I6,setColorScheme:gre,setFontScale:mre}}const xm=K(!1);let kS=!1;function c3(){const e=document.documentElement.dataset.colorScheme;return e==="dark"?!0:e==="light"?!1:window.matchMedia("(prefers-color-scheme: dark)").matches}function a9(){return!kS&&typeof window<"u"&&typeof document<"u"&&(kS=!0,xm.value=c3(),new MutationObserver(()=>{xm.value=c3()}).observe(document.documentElement,{attributes:!0,attributeFilter:["data-color-scheme"]}),window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change",()=>{xm.value=c3()})),xm}const vB="kimi-web.sidebar-multi-tab";function vre(e){try{return globalThis.localStorage.getItem(e)}catch{return null}}function yre(e,t){try{globalThis.localStorage.setItem(e,t)}catch{}}function kre(){return vre(vB)==="1"}const yB=K(kre());function bre(e){yB.value=e,yre(vB,e?"1":"0")}function d1(){return{sidebarTabs:yB,setSidebarTabs:bre}}const Are=Symbol("KimiWebClientFacade"),Cre="modulepreload",wre=function(e){return"/"+e},bS={},Fo=function(t,n,i){let o=Promise.resolve();if(n&&n.length>0){let r=function(u){return Promise.all(u.map(c=>Promise.resolve(c).then(d=>({status:"fulfilled",value:d}),d=>({status:"rejected",reason:d}))))};document.getElementsByTagName("link");const l=document.querySelector("meta[property=csp-nonce]"),a=l?.nonce||l?.getAttribute("nonce");o=r(n.map(u=>{if(u=wre(u),u in bS)return;bS[u]=!0;const c=u.endsWith(".css"),d=c?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${u}"]${d}`))return;const h=document.createElement("link");if(h.rel=c?"stylesheet":Cre,c||(h.as="script"),h.crossOrigin="",h.href=u,a&&h.setAttribute("nonce",a),document.head.appendChild(h),c)return new Promise((p,g)=>{h.addEventListener("load",p),h.addEventListener("error",()=>g(new Error(`Unable to preload CSS for ${u}`)))})}))}function s(r){const l=new Event("vite:preloadError",{cancelable:!0});if(l.payload=r,window.dispatchEvent(l),!l.defaultPrevented)throw r}return o.then(r=>{for(const l of r||[])l.status==="rejected"&&s(l.reason);return t().catch(s)})};function Wa(e,t){const n=t??{h:"h",m:"m",s:"s"},i=Math.max(0,Math.floor(e/1e3));if(i<60)return i===0?"":`${i}${n.s}`;const o=Math.floor(i/60);if(o<60){const l=i%60;return l===0?`${o}${n.m}`:`${o}${n.m}${l}${n.s}`}const s=Math.floor(o/60),r=o%60;return r===0?`${s}${n.h}`:`${s}${n.h}${r}${n.m}`}const kB=new Set(["read","bash","grep","search","glob","ls","web_fetch","edit","write"]);function bB(e){const t=Gs(e);return t==="multi_edit"?"edit":t}function AB(e){const t=[],n=new Map;for(const i of e){if(i.kind==="thinking")continue;const o=bB(i.tool.name);let s=n.get(o);s||(s={count:0,errors:0},n.set(o,s),t.push(o)),s.count++,i.tool.status==="error"&&s.errors++}return{order:t,byKind:n}}function CB(e,t,n){return kB.has(t)?e(`tools.group.typed.${t}.done`,{count:n}):e("tools.group.countOther",{count:n})}function wB(e,t){return{text:e("tools.activity.failedClause",{count:t}),tone:"danger"}}function xB(e){return e.map(t=>t.fragments.map(n=>n.text).join("")).join(" · ")}function xre(e,t,n={}){const{order:i,byKind:o}=AB(t),s=[];let r=!1;for(const l of i){const a=o.get(l);if(!a)continue;const u=[{text:CB(e,l,a.count),tone:"normal"}];a.errors>0&&(r=!0,u.push(wB(e,a.errors))),s.push({fragments:u})}if(n.durationMs!==void 0){const l=Wa(n.durationMs);l&&s.push({fragments:[{text:l,tone:"faint"}]})}return{clauses:s,plain:xB(s),hasError:r}}function Sre(e,t){if(t.kind==="thinking")return{fragments:[{text:e("thinking.streaming"),tone:"normal"}]};const n=bB(t.tool.name);let i=w6(e,t.tool.name,t.tool.arg);if(n==="write"&&i){const s=e("tools.chip.created");i.endsWith(s)&&(i=i.slice(0,i.length-s.length).trimEnd())}return{fragments:[{text:i&&kB.has(n)?e(`tools.activity.doing.${n}`,{subject:i}):e("tools.activity.busy"),tone:"normal"}]}}function _re(e,t,n){const i=t.filter(c=>c!==n&&!(c.kind==="tool"&&c.tool.status==="running")),{order:o,byKind:s}=AB(i),r=e("tools.activity.liveDonePrefix"),l=[];for(const c of o){const d=s.get(c);if(!d)continue;const h=[{text:`${r}${CB(e,c,d.count)}`,tone:"faint"}];d.errors>0&&h.push(wB(e,d.errors)),l.push({fragments:h})}const a=n===null?null:Sre(e,n),u=a?[a,...l]:l;return{current:a,done:l,plain:xB(u)}}async function Xo(e){const t=typeof navigator<"u"?navigator.clipboard:void 0;if(t&&typeof t.writeText=="function")try{return await t.writeText(e),!0}catch{}return Mre(e)}function Mre(e){if(typeof document>"u"||typeof document.execCommand!="function")return!1;const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.style.opacity="0",document.body.appendChild(t);let n=!1;try{t.focus(),t.select(),n=document.execCommand("copy")}catch{n=!1}finally{document.body.removeChild(t)}return n}const Ire={ts:"ts",tsx:"tsx",js:"js",jsx:"jsx",mjs:"js",cjs:"js",vue:"vue",svelte:"svelte",py:"py",rb:"rb",go:"go",rs:"rs",java:"java",kt:"kt",kts:"kts",scala:"scala",swift:"swift",c:"c",h:"c",cpp:"cpp",cc:"cpp",cxx:"cpp",hpp:"cpp",cs:"cs",php:"php",sh:"sh",bash:"bash",zsh:"zsh",fish:"fish",ps1:"ps1",bat:"bat",cmd:"bat",sql:"sql",graphql:"graphql",prisma:"prisma",html:"html",htm:"html",xml:"xml",svg:"xml",css:"css",scss:"scss",sass:"sass",less:"less",json:"json",jsonc:"jsonc",json5:"json5",yaml:"yaml",yml:"yml",toml:"toml",ini:"ini",md:"md",markdown:"markdown",mdx:"mdx",lua:"lua",r:"r",dart:"dart",zig:"zig",mk:"makefile",cmake:"cmake",diff:"diff",proto:"proto"},Ere={dockerfile:"dockerfile",makefile:"makefile","cmakelists.txt":"cmake"};function Tre(e){const t=e?.split(/[\\/]/).pop()?.toLowerCase()??"";if(!t)return;const n=Ere[t];if(n)return n;const i=t.lastIndexOf(".");if(!(i<=0))return Ire[t.slice(i+1)]}const Lre="kimi_desktop",Nre="platform",AS="kimi-desktop",CS="kimi-desktop-platform";function Fre(){let e=!1,t=null;try{const n=new URLSearchParams(window.location.search);n.has(Lre)?(sessionStorage.setItem(AS,"1"),e=!0):e=e||sessionStorage.getItem(AS)==="1";const i=n.get(Nre);i?(sessionStorage.setItem(CS,i),t=i):t=sessionStorage.getItem(CS)}catch{}return{isDesktop:e,platform:t}}const Rb=Fre(),bf=Rb.isDesktop,pc=Rb.isDesktop&&Rb.platform==="darwin",Dre=["faces","nature","food","activity","objects","symbols"],Bre=[["😀","faces","grinning smile happy 笑 开心"],["😄","faces","smile happy joy 笑 开心 高兴"],["😁","faces","grin beaming 咧嘴笑 开心"],["😂","faces","joy laugh tears 笑哭 爆笑"],["🤣","faces","rofl laugh rolling 笑翻 爆笑"],["😊","faces","blush shy happy 微笑 害羞"],["😉","faces","wink 眨眼"],["😍","faces","heart eyes love 爱心眼 喜欢 爱"],["🥰","faces","smiling hearts love 爱心 喜欢"],["😘","faces","kiss 飞吻 亲亲"],["😋","faces","yum tongue 好吃 馋"],["🤪","faces","zany crazy 鬼脸 疯"],["🤔","faces","thinking hmm consider 思考 想"],["🤨","faces","skeptical eyebrow 怀疑 挑眉"],["😐","faces","neutral meh 面无表情 无语"],["😑","faces","expressionless 面无表情 无语"],["🙄","faces","eye roll 翻白眼 无语"],["😶","faces","no mouth silent 无言 沉默"],["🫡","faces","salute 敬礼 收到"],["🤫","faces","shush quiet 嘘 安静"],["🤭","faces","oops giggle 捂嘴 偷笑"],["😴","faces","sleeping sleepy 睡觉 困"],["😪","faces","sleepy tired 困 疲惫"],["😷","faces","mask sick 口罩 生病"],["🤒","faces","sick fever 生病 发烧"],["🤕","faces","hurt bandage 受伤"],["🤢","faces","nauseated 恶心"],["🤯","faces","mind blown explode 震惊 爆炸"],["🥳","faces","party celebrate 庆祝 派对"],["🤩","faces","star struck 星星眼 激动"],["😎","faces","cool sunglasses 酷 墨镜"],["🥸","faces","disguise 伪装 假扮"],["🤓","faces","nerd geek 书呆子 学霸"],["😢","faces","cry sad 哭 难过"],["😭","faces","sob cry loudly 大哭 痛哭"],["😤","faces","triumph huff 哼 生气"],["😡","faces","angry rage mad 生气 愤怒"],["🤬","faces","swearing cursing 骂人 爆粗"],["😱","faces","scream fear 尖叫 害怕"],["😨","faces","fearful 害怕 恐惧"],["🥵","faces","hot heat 热 出汗"],["🥶","faces","cold freezing 冷 冻"],["🥴","faces","woozy drunk 晕 醉"],["😇","faces","angel innocent 天使 无辜"],["🙃","faces","upside down silly 倒脸 哭笑不得"],["💀","faces","skull dead 骷髅 笑死"],["👻","faces","ghost 鬼 幽灵"],["👍","faces","thumbs up like good 赞 好"],["👎","faces","thumbs down dislike 踩 差"],["👏","faces","clap applause 鼓掌 厉害"],["🙌","faces","raise hands celebrate 举手 庆祝"],["🙏","faces","pray thanks please 拜托 感谢 祈祷"],["💪","faces","muscle strong flex 加油 强壮 肌肉"],["👀","faces","eyes look watch 看 围观 眼睛"],["🤝","faces","handshake deal 握手 合作"],["✌️","faces","victory peace 胜利 耶"],["👋","faces","wave hello bye 挥手 你好 再见"],["🤞","faces","crossed fingers luck 祈祷 好运"],["👌","faces","ok okay 好的 可以"],["🫶","faces","heart hands love 比心 爱心"],["✍️","faces","writing hand 写字 记录"],["🧠","faces","brain smart 大脑 聪明"],["🦾","faces","mechanical arm 机械臂 力量"],["👤","faces","person user profile 个人 用户"],["👥","faces","people team group 团队 多人"],["🐶","nature","dog puppy 狗 小狗"],["🐱","nature","cat kitten 猫 小猫"],["🐭","nature","mouse rat 老鼠"],["🐹","nature","hamster 仓鼠"],["🐰","nature","rabbit bunny 兔子"],["🦊","nature","fox 狐狸"],["🐻","nature","bear 熊"],["🐼","nature","panda 熊猫"],["🐨","nature","koala 考拉"],["🐯","nature","tiger 老虎"],["🦁","nature","lion 狮子"],["🐮","nature","cow 牛"],["🐷","nature","pig 猪"],["🐸","nature","frog 青蛙"],["🐵","nature","monkey 猴子"],["🐔","nature","chicken 鸡"],["🐧","nature","penguin 企鹅"],["🐦","nature","bird 鸟"],["🐣","nature","chick hatching 小鸡 孵化"],["🦆","nature","duck 鸭子"],["🦉","nature","owl 猫头鹰"],["🐝","nature","bee 蜜蜂"],["🐛","nature","bug caterpillar 虫子 毛虫"],["🦋","nature","butterfly 蝴蝶"],["🐌","nature","snail slow 蜗牛 慢"],["🐢","nature","turtle slow 乌龟 慢"],["🐍","nature","snake 蛇"],["🐙","nature","octopus 章鱼"],["🦑","nature","squid 鱿鱼"],["🦐","nature","shrimp 虾"],["🦀","nature","crab 螃蟹"],["🐠","nature","tropical fish 鱼 热带鱼"],["🐳","nature","whale 鲸鱼"],["🦈","nature","shark 鲨鱼"],["🐊","nature","crocodile 鳄鱼"],["🦄","nature","unicorn 独角兽"],["🐴","nature","horse 马"],["🐑","nature","sheep 羊 绵羊"],["🐐","nature","goat 山羊"],["🦜","nature","parrot 鹦鹉"],["🌸","nature","blossom flower sakura 樱花 花"],["🌹","nature","rose flower 玫瑰 花"],["🌻","nature","sunflower 向日葵"],["🌷","nature","tulip 郁金香"],["🌱","nature","seedling sprout 发芽 幼苗"],["🌲","nature","tree evergreen 树 松树"],["🌳","nature","deciduous tree 树 大树"],["🌵","nature","cactus 仙人掌"],["🍀","nature","clover luck 四叶草 幸运"],["🍁","nature","maple leaf autumn 枫叶 秋天"],["🍄","nature","mushroom 蘑菇"],["🌈","nature","rainbow 彩虹"],["☀️","nature","sun sunny 太阳 晴"],["🌙","nature","moon crescent 月亮"],["⭐","nature","star 星星"],["🌟","nature","glowing star 星星 闪亮"],["☁️","nature","cloud 云"],["⛅","nature","partly cloudy 多云"],["🌧️","nature","rain rainy 下雨"],["❄️","nature","snowflake snow 雪 雪花"],["⛄","nature","snowman 雪人"],["⚡","nature","lightning bolt 闪电"],["🔥","nature","fire hot 火 燃"],["🌊","nature","wave ocean sea 海浪"],["🏔️","nature","mountain snow 雪山 山"],["☕","food","coffee 咖啡"],["🍵","food","tea 茶"],["🧋","food","bubble tea boba 奶茶"],["🥛","food","milk 牛奶"],["🍺","food","beer 啤酒"],["🍷","food","wine 红酒"],["🥂","food","champagne cheers 香槟 干杯"],["🥤","food","cup straw soda 饮料 可乐"],["🧃","food","juice box 果汁"],["🍎","food","apple 苹果"],["🍊","food","orange tangerine 橙子 橘子"],["🍋","food","lemon 柠檬"],["🍉","food","watermelon 西瓜"],["🍓","food","strawberry 草莓"],["🍑","food","peach 桃子"],["🥭","food","mango 芒果"],["🍍","food","pineapple 菠萝"],["🥝","food","kiwi 猕猴桃"],["🍇","food","grapes 葡萄"],["🍒","food","cherries 樱桃"],["🥑","food","avocado 牛油果"],["🥦","food","broccoli 西兰花"],["🌽","food","corn 玉米"],["🌶️","food","hot pepper spicy 辣椒 辣"],["🍔","food","burger hamburger 汉堡"],["🍟","food","fries 薯条"],["🍕","food","pizza 披萨"],["🌭","food","hot dog 热狗"],["🥪","food","sandwich 三明治"],["🌮","food","taco 墨西哥卷"],["🍜","food","ramen noodles 拉面 面条"],["🍝","food","spaghetti pasta 意面"],["🍣","food","sushi 寿司"],["🍱","food","bento 便当"],["🥟","food","dumpling 饺子"],["🍚","food","rice 米饭"],["🍞","food","bread 面包"],["🥐","food","croissant 可颂 牛角包"],["🧀","food","cheese 奶酪 芝士"],["🍳","food","cooking egg 煎蛋 做饭"],["🍦","food","ice cream 冰淇淋"],["🍰","food","cake 蛋糕"],["🎂","food","birthday cake 生日蛋糕"],["🍫","food","chocolate 巧克力"],["🍩","food","donut doughnut 甜甜圈"],["🍪","food","cookie 饼干"],["🍭","food","lollipop 棒棒糖"],["⚽","activity","soccer football 足球"],["🏀","activity","basketball 篮球"],["🏈","activity","american football 橄榄球"],["⚾","activity","baseball 棒球"],["🎾","activity","tennis 网球"],["🏐","activity","volleyball 排球"],["🏓","activity","ping pong 乒乓球"],["🏸","activity","badminton 羽毛球"],["🥊","activity","boxing 拳击"],["⛳","activity","golf 高尔夫"],["🎣","activity","fishing 钓鱼"],["🏊","activity","swim 游泳"],["🏄","activity","surf 冲浪"],["🚴","activity","cycling 骑行"],["🏋️","activity","weightlifting gym 举重 健身"],["🧘","activity","yoga meditation 瑜伽 冥想"],["🎮","activity","video game controller 游戏 游戏机"],["🎲","activity","dice 骰子"],["🎯","activity","target bullseye 目标 靶心"],["🎳","activity","bowling 保龄球"],["🎰","activity","slot machine 老虎机"],["♟️","activity","chess 国际象棋 棋"],["🎸","activity","guitar 吉他"],["🎹","activity","piano keyboard 钢琴"],["🥁","activity","drum 鼓"],["🎤","activity","microphone sing 麦克风 唱歌"],["🎧","activity","headphones 耳机"],["🎬","activity","clapper movie 电影 拍摄"],["🎨","activity","art palette paint 画画 艺术"],["🎭","activity","theater masks 戏剧 面具"],["🎪","activity","circus 马戏团"],["🎡","activity","ferris wheel 摩天轮"],["✈️","activity","airplane travel flight 飞机 旅行"],["🚗","activity","car drive 汽车 车"],["🚕","activity","taxi 出租车"],["🚌","activity","bus 公交车"],["🚑","activity","ambulance 救护车"],["🚒","activity","fire engine 消防车"],["🚀","activity","rocket launch ship 火箭 发射"],["🛸","activity","ufo flying saucer 飞碟"],["🚲","activity","bicycle bike 自行车"],["🛴","activity","scooter 滑板车"],["🚄","activity","bullet train 高铁 动车"],["🚢","activity","ship 船 轮船"],["⛵","activity","sailboat 帆船"],["🏠","activity","house home 房子 家"],["🏢","activity","office building 公司 办公楼"],["🏥","activity","hospital 医院"],["🏫","activity","school 学校"],["🏖️","activity","beach vacation 海滩 度假"],["⛺","activity","camping tent 露营 帐篷"],["🌋","activity","volcano 火山"],["🗺️","activity","map world 地图"],["🧭","activity","compass 指南针"],["💻","objects","laptop computer 电脑 笔记本"],["🖥️","objects","desktop computer 台式机 电脑"],["⌨️","objects","keyboard 键盘"],["🖱️","objects","computer mouse 鼠标"],["📱","objects","phone mobile 手机"],["🔋","objects","battery 电池"],["🔌","objects","plug electric 插头"],["💾","objects","floppy save 软盘 保存"],["📀","objects","cd disc 光盘"],["🎥","objects","movie camera 摄像机"],["📷","objects","camera 相机"],["🔭","objects","telescope 望远镜"],["📡","objects","satellite antenna 卫星 天线"],["🌐","objects","globe web internet 网络 全球 互联网"],["🕯️","objects","candle 蜡烛"],["💡","objects","bulb idea light 灯泡 点子"],["🔦","objects","flashlight 手电筒"],["📁","objects","folder 文件夹"],["📂","objects","open folder 文件夹 打开"],["🗂️","objects","card index archive 归档 索引"],["📅","objects","calendar date 日历 日期"],["📌","objects","pin pushpin 图钉 置顶"],["📍","objects","round pin location 定位 位置"],["📎","objects","paperclip attachment 回形针 附件"],["✂️","objects","scissors cut 剪刀 剪切"],["📏","objects","ruler 尺子"],["📝","objects","memo note write 备忘 记录"],["✏️","objects","pencil edit write 铅笔 编辑"],["📄","objects","document page 文档 文件"],["📃","objects","page curl 文档 文件"],["📑","objects","bookmark tabs 标签页 文档"],["📚","objects","books 书 书籍"],["📖","objects","open book 打开的书 阅读"],["🔖","objects","bookmark 书签"],["🏷️","objects","label tag 标签"],["📊","objects","bar chart stats 图表 统计"],["📈","objects","chart up growth 上涨 增长"],["📉","objects","chart down 下跌 下降"],["🔍","objects","search magnifier 搜索 查找"],["🔎","objects","search magnifier right 搜索 查找"],["🔒","objects","lock locked 锁 锁定"],["🔓","objects","unlock open 解锁"],["🔑","objects","key 钥匙 密钥"],["🔧","objects","wrench tool 扳手 工具"],["🔨","objects","hammer 锤子"],["🛠️","objects","tools hammer wrench 工具 修理"],["🧰","objects","toolbox 工具箱 工具"],["🪛","objects","screwdriver 螺丝刀 工具"],["🔩","objects","nut and bolt screw 螺母 螺栓"],["🏗️","objects","building construction crane 施工 建造"],["⚙️","objects","gear settings 齿轮 设置"],["🧲","objects","magnet 磁铁"],["⚗️","objects","alembic 蒸馏器 实验"],["🧪","objects","test tube experiment 实验 试管"],["🔬","objects","microscope science 显微镜 科学"],["🤖","objects","robot bot 机器人"],["👾","objects","alien monster game 外星人 游戏"],["💣","objects","bomb 炸弹"],["🧨","objects","firecracker 爆竹"],["🗑️","objects","trash delete 垃圾桶 删除"],["🧹","objects","broom clean 扫帚 清理"],["🧻","objects","toilet paper 纸巾"],["🧽","objects","sponge 海绵"],["📦","objects","package box 包裹 箱子"],["✉️","objects","envelope mail 邮件 信封"],["📮","objects","mailbox postbox 邮箱"],["📧","objects","email mail 邮件"],["📥","objects","inbox tray receive 收件箱 接收"],["📤","objects","outbox tray send 发件箱 发送"],["📞","objects","telephone receiver call phone 电话 通话"],["💬","objects","speech balloon chat message bubble 聊天 对话 气泡 消息"],["💭","objects","thought balloon thinking 思考 想法 气泡"],["📣","objects","megaphone announcement 喇叭 公告"],["📢","objects","loudspeaker broadcast 广播 喇叭 通知"],["🚨","objects","police light alert emergency 警报 告警 紧急"],["🗳️","objects","ballot box vote 投票箱 投票"],["🔗","objects","link chain 链接 连接"],["🧩","objects","puzzle piece plugin 拼图 插件"],["🪄","objects","magic wand 魔法 魔杖"],["🛡️","objects","shield security 盾牌 安全"],["⚔️","objects","crossed swords 交叉剑 战斗"],["💳","objects","credit card 信用卡"],["💰","objects","money bag 钱袋 钱"],["🧾","objects","receipt 收据 小票"],["📿","objects","prayer beads 念珠"],["💍","objects","ring 戒指"],["👑","objects","crown 皇冠"],["🎩","objects","top hat 礼帽"],["🎒","objects","backpack 背包 书包"],["👓","objects","glasses 眼镜"],["🌂","objects","umbrella 雨伞"],["🕰️","objects","mantel clock 座钟"],["⌚","objects","watch 手表"],["⏱️","objects","stopwatch 秒表"],["🧯","objects","fire extinguisher 灭火器"],["🩹","objects","bandage patch fix 创可贴 补丁 修复"],["🎓","objects","graduation cap study learn 毕业 学习"],["🎫","objects","ticket 票 门票 工单"],["✅","symbols","check done complete 完成 对勾"],["✔️","symbols","checkmark correct 对勾 正确"],["❌","symbols","cross x wrong 错误 叉"],["❓","symbols","question help 问题 问号"],["❔","symbols","white question 问题 问号"],["❗","symbols","exclamation important 感叹号 重要"],["❕","symbols","white exclamation 感叹号"],["⚠️","symbols","warning caution 警告 注意"],["🚧","symbols","construction wip 施工 进行中"],["🚫","symbols","prohibited no 禁止"],["💥","symbols","boom explosion 爆炸"],["✨","symbols","sparkles shiny 闪亮 星星"],["🎉","symbols","tada party celebrate 庆祝 撒花"],["🎊","symbols","confetti party 庆祝 彩带"],["🏆","symbols","trophy champion 奖杯 冠军"],["🥇","symbols","gold medal first 金牌 第一"],["🥈","symbols","silver medal second 银牌 第二"],["🥉","symbols","bronze medal third 铜牌 第三"],["🎖️","symbols","military medal 勋章"],["🚩","symbols","red flag mark 红旗 标记"],["🏁","symbols","checkered flag finish 终点 完成"],["⏳","symbols","hourglass time waiting 沙漏 时间"],["⌛","symbols","hourglass done 沙漏 时间"],["🕐","symbols","clock one time 时钟 一点"],["⏰","symbols","alarm clock 闹钟"],["🔔","symbols","bell notification 铃铛 通知"],["🔕","symbols","bell slash mute 静音 免打扰"],["🕹️","symbols","joystick game 摇杆 游戏"],["🔴","symbols","red circle record 红圆 录制"],["🟢","symbols","green circle online 绿圆 在线"],["🟡","symbols","yellow circle 黄圆"],["🟠","symbols","orange circle 橙圆"],["🔵","symbols","blue circle 蓝圆"],["🟣","symbols","purple circle 紫圆"],["⚫","symbols","black circle 黑圆"],["⚪","symbols","white circle 白圆"],["🟥","symbols","red square 红方"],["🟩","symbols","green square 绿方"],["🟦","symbols","blue square 蓝方"],["🔺","symbols","red triangle up 三角 上"],["🔻","symbols","triangle down 三角 下"],["🔸","symbols","diamond orange 菱形"],["🔹","symbols","diamond blue 菱形"],["💠","symbols","diamond dot 菱形 花"],["🔶","symbols","diamond orange big 菱形"],["🔷","symbols","diamond blue big 菱形"],["▶️","symbols","play 播放"],["⏸️","symbols","pause 暂停"],["⏹️","symbols","stop 停止"],["⏺️","symbols","record 录制"],["⏩","symbols","fast forward 快进"],["⏪","symbols","rewind 快退"],["🔀","symbols","shuffle 随机 打乱"],["🔁","symbols","repeat 重复 循环"],["🔂","symbols","repeat one 单曲循环"],["🔄","symbols","refresh sync 刷新 同步"],["🔃","symbols","reload 重载"],["➕","symbols","plus add 加 新增"],["➖","symbols","minus 减"],["➗","symbols","divide 除"],["✖️","symbols","multiply 乘"],["💲","symbols","dollar money 美元 钱"],["™️","symbols","trademark 商标"],["©️","symbols","copyright 版权"],["®️","symbols","registered 注册商标"],["↔️","symbols","left right arrow 左右箭头"],["⬆️","symbols","up arrow 上箭头"],["⬇️","symbols","down arrow 下箭头"],["➡️","symbols","right arrow 右箭头"],["⬅️","symbols","left arrow 左箭头"],["🔙","symbols","back 返回"],["🔜","symbols","soon 很快"],["🔝","symbols","top 置顶 顶部"],["💤","symbols","zzz sleep 睡觉"],["🆕","symbols","new 新 新品"],["🆒","symbols","cool 酷"],["🆓","symbols","free 免费"],["🆗","symbols","ok 可以"],["🆙","symbols","up 提升"],["🆚","symbols","vs versus 对比"],["♾️","symbols","infinity 无限"],["💯","symbols","hundred perfect 满分 一百"],["💢","symbols","anger 生气"],["♨️","symbols","hot springs 温泉"],["🚸","symbols","children crossing 注意儿童"],["🔞","symbols","no one under eighteen 十八禁"],["📵","symbols","no mobile phones 禁止手机"],["❤️","symbols","red heart love 红心 爱"],["🧡","symbols","orange heart 橙心"],["💛","symbols","yellow heart 黄心"],["💚","symbols","green heart 绿心"],["💙","symbols","blue heart 蓝心"],["💜","symbols","purple heart 紫心"],["🖤","symbols","black heart 黑心"],["🤍","symbols","white heart 白心"],["🤎","symbols","brown heart 棕心"],["💔","symbols","broken heart 心碎"],["💕","symbols","two hearts 双心 爱心"],["💖","symbols","sparkling heart 闪亮的心"],["💗","symbols","growing heart 心动"]],SB=Bre.map(([e,t,n])=>({emoji:e,group:t,keywords:n}));function $re(e,t=24){const n=e.trim().toLowerCase();if(!n)return[];const i=[];for(const o of SB)if((o.keywords.includes(n)||o.emoji===n)&&(i.push(o.emoji),i.length>=t))break;return i}const Rre=8;function zre(e,t,n=Rre){return[t,...e.filter(i=>i!==t)].slice(0,n)}function _B(e,t){try{const n=new Date(e);if(Number.isNaN(n.getTime()))return e;const i=new Date,o=c=>String(c).padStart(2,"0"),s=`${o(n.getHours())}:${o(n.getMinutes())}`,r=n.getFullYear()===i.getFullYear(),l=n.getMonth()===i.getMonth(),a=n.getDate()===i.getDate();if(r&&l&&a)return s;const u=new Date(i);return u.setDate(i.getDate()-1),n.getFullYear()===u.getFullYear()&&n.getMonth()===u.getMonth()&&n.getDate()===u.getDate()?`${t} ${s}`:r?`${o(n.getMonth()+1)}-${o(n.getDate())} ${s}`:`${n.getFullYear()}-${o(n.getMonth()+1)}-${o(n.getDate())} ${s}`}catch{return e}}function _u(e){if(e>=1024*1024)return`${wS(e/(1024*1024))}M`;if(e>=1024){const t=e/1024;return`${t>=100?Math.round(t):wS(t)}k`}return String(e)}function wS(e){const t=e.toFixed(1);return t.endsWith(".0")?t.slice(0,-2):t}function Tu(e){const t=e.split("/").filter(Boolean);return t.length>0?t[t.length-1]:e}const Ore=/^(?:[A-Za-z]:[\\/]|\\\\|\/\/)/;function ol(e){const t=e.replaceAll("\\","/"),n=Ore.test(t),i=t.replace(/\/+$/,"");return n?i.toLowerCase():i}function Pre(e){const{workspaces:t,sessions:n,hiddenWorkspaceRoots:i,sessionsHasMoreByWorkspace:o}=e,s=new Set(i.map(ol)),r=new Map;for(const h of t){const p=ol(h.root);s.has(p)||r.has(p)||r.set(p,{...h})}for(const h of n){const p=h.cwd;if(!p)continue;const g=ol(p);s.has(g)||r.has(g)||r.set(g,{id:h.workspaceId??p,root:p,name:Tu(p),sessionCount:0})}const l=new Map;for(const h of t){const p=ol(h.root);l.has(p)||l.set(p,h.id)}const a=new Map;for(const h of n){const p=l.get(ol(h.cwd))??h.workspaceId??h.cwd;a.set(p,(a.get(p)??0)+1)}const u=[];for(const h of t){const p=ol(h.root);!s.has(p)&&!u.includes(p)&&u.push(p)}const c=[...r.keys()].filter(h=>!u.includes(h));c.sort((h,p)=>r.get(h).root.localeCompare(r.get(p).root));const d=[];for(const h of[...u,...c]){const p=r.get(h),g=a.get(p.id)??a.get(p.root)??0,m=o[p.id]===!1?g:Math.max(p.sessionCount,g);d.push({...p,sessionCount:m})}return d}function jre(e,t){if(e===void 0||e.length===0)return;const n=t?.find(i=>i.id===e)??t?.find(i=>i.model===e);return n?.displayName||n?.model||(e.includes("/")?e.split("/").pop():e)}function Hre(e){if(!(e===void 0||e.length===0||e==="off"||e==="on"))return e}function u9(e){if(e===void 0)return"toggle";const t=e.capabilities??[];return t.includes("always_thinking")?"always-on":t.includes("thinking")||e.adaptiveThinking===!0?"toggle":"unsupported"}function MB(e){return e?.supportEfforts??[]}function Wre(e){return e[Math.floor(e.length/2)]}function _0(e){if(u9(e)==="unsupported")return"off";const t=MB(e);return t.length>0?e?.defaultEffort??Wre(t):"on"}function c9(e){const t=MB(e),n=u9(e);return t.length>0?n==="always-on"?[...t]:["off",...t]:n==="always-on"?["on"]:n==="unsupported"?["off"]:["on","off"]}function zb(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function qre(e){return e!=="off"}function Ure(e,t){return c9(e).includes(t)}function IB(e,t){return t==="off"?"off":t==="on"?_0(e):t}function E6(e,t){return t??_0(e)}function Kre(e,t){if(e==="off")return{enabled:!1};if(e==="on")return{enabled:!0};const n=t?.at(-1);return n!==void 0&&e===n?{enabled:!0}:{enabled:!0,effort:e}}function Vre(e,t,n){return!n||e===void 0?t:_0(e)}let Zre=0;function Ob(e,t){const n=++Zre;return e.pendingThinkingBySession[t]=n,n}function Au(e,t,n){return n===void 0||e.pendingThinkingBySession[t]!==n?!1:(delete e.pendingThinkingBySession[t],!0)}function EB(e,t,n){e.pendingThinkingBySession[t]===void 0&&(e.thinkingBySession[t]=n)}function TB(){return window.kimiDesktop}function Sm(){return typeof TB()?.getPathForFile=="function"}function T6(e){const t=TB()?.getPathForFile;if(typeof t!="function")return null;try{return t(e)}catch{return null}}function d3(e){return Array.from(e.dataTransfer?.items??[]).some(t=>t.kind==="file"&&t.type==="")}function Pb(e,t=T6){const n=Array.from(e.dataTransfer?.items??[]);if(n.length===0)return{files:Array.from(e.dataTransfer?.files??[]),folderPaths:[]};const i=[],o=[],s=new Set;for(const r of n){if(r.kind!=="file")continue;const l=r.getAsFile();if(l)if(r.webkitGetAsEntry()?.isDirectory===!0){const a=t(l);if(!a||s.has(a))continue;s.add(a),o.push(a)}else i.push(l)}return{files:i,folderPaths:o}}function Gre(e,t=T6){return Pb(e,t).folderPaths}function Qre(e,t=T6){const n=u=>`${u.size}:${u.type}:${u.name}`,i=[],o=new Set,s=new Set,r=[],l=new Set;let a=!1;for(const u of Array.from(e.items??[])){if(u.kind!=="file")continue;const c=u.getAsFile();if(u.webkitGetAsEntry?.()?.isDirectory===!0){a=!0,c&&s.add(n(c));const h=c?t(c):null;if(!h||l.has(h))continue;l.add(h),r.push(h);continue}if(!c)continue;const d=n(c);o.has(d)||(o.add(d),i.push(c))}for(const u of Array.from(e.files??[])){const c=n(u);s.has(c)||o.has(c)||(o.add(c),i.push(u))}return{files:i,folderPaths:r,hasFolders:a}}function LB(e,t,n){return e==="unsupported"?[{titleKey:n.titleKey,hintKey:n.hintKey,disabled:!1}]:t.map(i=>({...i,disabled:e==="pending"}))}function Yre(e,t,n){return n?e.filter(i=>i.sessions.length>0||i.workspace.id===t):e}const Jre=/<summary>([\s\S]*?)<\/summary>/,Xre=/<resume_hint>([\s\S]*?)<\/resume_hint>/,f3=/<subagent\b([^>]*)>|<\/subagent>/g,ele="</subagent>",xS=/(completed|failed|aborted):\s*(\d+)/g,SS=/([a-z_]+)="([^"]*)"/g;function tle(e){return e.replaceAll(""",'"').replaceAll("<","<").replaceAll(">",">").replaceAll("&","&")}function nle(e){const t={};SS.lastIndex=0;let n;for(;(n=SS.exec(e))!==null;)t[n[1]]=tle(n[2]);return t}function ile(e){const t={completed:0,failed:0,aborted:0};xS.lastIndex=0;let n;for(;(n=xS.exec(e))!==null;){const i=n[1];t[i]=Number(n[2])}return t}function ole(e,t){const n=nle(e);return{outcome:n.outcome??"completed",item:n.item,agentId:n.agent_id,mode:n.mode,state:n.state,body:t.trim()}}function sle(e){const t=[],n=[];f3.lastIndex=0;let i;for(;(i=f3.exec(e))!==null;)if(i[0]===ele){if(n.length===0)continue;const o=n.pop();o&&n.length===0&&t.push(ole(o.attrs,e.slice(o.bodyStart,i.index)))}else n.length===0?n.push({attrs:i[1]??"",bodyStart:f3.lastIndex}):n.push(null);return t}function rle(e){if(e==null)return null;const t=Array.isArray(e)?e.join(` -`):e;if(!t.includes("<agent_swarm_result>"))return null;const n=Jre.exec(t)?.[1]?.trim()??"",{completed:i,failed:o,aborted:s}=ile(n),r=Xre.exec(t)?.[1]?.trim(),l=sle(t),a=i+o+s;return{summary:n,completed:i,failed:o,aborted:s,total:a>0?a:l.length,subagents:l,resumeHint:r}}const lle=3,ale="Use TaskOutput with one of the task_id values above to read the full output.";function Td(e,t){return new RegExp(`^${t}: (.+)$`,"m").exec(e)?.[1]}function ule(e,t){const n=Number(Td(e,t)??0);return Number.isFinite(n)?n:0}function NB(e,t){return e.match(t)?.length??0}function _S(e,t,n){const i=new RegExp(`^\\[${t}\\]$`,"gm"),o=[];let s;for(;(s=i.exec(e))!==null;)s.index>=n&&o.push(s.index);return o}function MS(e,t){return t>=2&&e[t-1]===` -`&&e[t-2]===` -`}function IS(e,t,n){const i=e.slice(t+n.length+2),o=/^\[/m.exec(i);return(o===null?i:i.slice(0,o.index)).trim()}function cle(e){return e.endsWith(ale)}function dle(e){const t=Td(e,"active_background_tasks");if(t===void 0)return!1;const n=Number(t);return Number.isFinite(n)?NB(e,/^task_id: /gm)===n:!1}function fle(e,t){return[...e.matchAll(/^description: (.+)$/gm)].map(i=>i[1]??"").slice(0,Math.min(lle,t))}function hle(e){if(e==null)return null;const t=Array.isArray(e)?e.join(` -`):e,n=/^\[/m.exec(t),i=n===null?t:t.slice(0,n.index),o=Td(i,"wait_status");if(o!=="completed"&&o!=="timed_out"&&o!=="no_tasks")return null;const s=Number(Td(i,"waited_ms")??0);let r,l=n?.index??t.length;o==="completed"&&n!==null&&t.slice(n.index).startsWith("[finished]")&&(r=IS(t,n.index,"finished"),l=n.index+10);let a=0,u=-1;for(const h of _S(t,"completed_during_wait",l)){if(!MS(t,h))continue;const p=IS(t,h,"completed_during_wait");cle(p)&&(a=NB(p,/^task_id: /gm),u=h)}let c=0,d=[];for(const h of _S(t,"still_running",l)){if(u>=0&&h<u||!MS(t,h))continue;const p=t.slice(h+15);if(/^\[/m.test(p))continue;const g=p.trim();dle(g)&&(c=ule(g,"active_background_tasks"),d=fle(g,c))}return{status:o,waitedMs:Number.isFinite(s)?s:0,taskId:Td(i,"task_id"),finishedStatus:r===void 0?void 0:Td(r,"status"),finishedDescription:r===void 0?void 0:Td(r,"description"),extraCount:a,runningCount:c,runningSamples:d}}function ple(e){const t=Math.max(e.lastIndexOf("/"),e.lastIndexOf("\\"));return t<0?"":t===0?e[0]:e.slice(0,t)}const gle=/^[A-Za-z]:[\\/]/;function ES(e){return gle.test(e)||e.startsWith("\\\\")||e.startsWith("//")}function d9(e,t){if(!t)return null;const n=c=>c.replace(/\\/g,"/"),i=n(e);let o=n(t);o.length>1&&(o=o.replace(/\/+$/,""));const s=ES(o)||ES(i),r=s?o.toLowerCase():o,l=s?i.toLowerCase():i,a=r.endsWith("/")?r:`${r}/`;if(l!==r&&!l.startsWith(a))return null;const u=l===r?"":i.slice(a.length);return u.split("/").includes("..")?null:u||null}const mle=50,vle=3,FB=mle*2;function yle(e){const t=(e??[]).filter(n=>typeof n=="number"&&Number.isFinite(n)&&n>0).slice(0,2);return t.length===0?FB:Math.round(t.reduce((n,i)=>n+i,0))}function DB(e){return e==null||!Number.isFinite(e)||e<=0?FB:Math.round(e)}const jb=96;function kle(e,t,n){const i=e.filter(r=>r.visible),o=i[0],s=i[2];return{firstRowHeight:o?o.height:null,spanToThirdRow:s?s.viewportBottom-t+n:null}}function ble(e,t,n){const i=s=>s!=null&&Number.isFinite(s)&&s>0;return(s=>s!=null&&Number.isFinite(s)&&s>=0)(t)?i(e)?Math.round(e)+Math.round(t):i(n)?Math.round(n)*3+Math.round(t):jb:jb}function Ale(e){return e>vle}function TS(e){return Math.round(e*.4)}function Cle(e){return e==null||!Number.isFinite(e)||e<=0?jb:Math.round(e)}function wle(e,t,n,i){const o=DB(n),s=Cle(i),r=Math.max(o,Math.round(e*.6));if(t===void 0||!Number.isFinite(t))return r;const l=Math.round(t)-s;return Math.max(o,Math.min(r,l))}function h3(e,t,n){return t==null||!Number.isFinite(t)?e:Math.max(DB(n),Math.min(e,Math.round(t)))}function xle(e,t,n,i){return Math.max(Math.round(i),Math.min(Math.round(e+t),Math.round(n)))}function Sle(e,t){return t===null||t===e}const C2="application/x-kimi-session-row";function _le(e,t){return e.includes(t)?e:[...e,t]}function Mle(e,t){return e.includes(t)?e.filter(n=>n!==t):e}function Ile(e,t){const n=new Set(t),i=new Map,o=[];for(const r of e)n.has(r.id)?i.set(r.id,r):o.push(r);const s=[];for(const r of t){const l=i.get(r);l!==void 0&&s.push(l)}return{pinned:s,unpinned:o}}function Ele(e,t,n){return e.find(i=>i.window?.duration===t&&i.window?.unit===n)}const Tle=30;function Lle(e){return e!==void 0&&e<Tle}function BB(e,t){if(e.window!==void 0){const{duration:n,unit:i}=e.window;return i==="week"?t("settings.planUsage.weekLimit",{n}):i==="day"?t("settings.planUsage.dayLimit",{n}):i==="hour"?t("settings.planUsage.hourLimit",{n}):t("settings.planUsage.minuteLimit",{n})}return e.name??t("settings.planUsage.genericLimit")}function $B(e,t){const n=Date.parse(e);if(Number.isNaN(n))return"";const i=Math.floor((n-Date.now())/1e3);if(i<=0)return t("settings.planUsage.resetDone");const o=Math.floor(i/86400),s=Math.floor(i%86400/3600),r=Math.floor(i%3600/60),l=[];return o>0?(l.push(t("settings.planUsage.durationDay",{n:o})),l.push(t("settings.planUsage.durationHour",{n:s})),l.push(t("settings.planUsage.durationMinute",{n:r}))):s>0?(l.push(t("settings.planUsage.durationHour",{n:s})),l.push(t("settings.planUsage.durationMinute",{n:r}))):r>0?l.push(t("settings.planUsage.durationMinute",{n:r})):l.push(t("settings.planUsage.durationSecond",{n:i})),t("settings.planUsage.resetsIn",{duration:l.join(" ")})}function Hb(e,t){if(t<=0)return"ok";const n=e/t;return n>=.85?"danger":n>=.5?"warn":"ok"}function bv(e,t){return t<=0?0:Math.min(100,Math.round(e/t*100))}function Nle(e,t){const n=(e/100).toFixed(2);switch(t.toUpperCase()){case"CNY":return{symbol:"¥",number:n};case"USD":return{symbol:"$",number:n};default:return{symbol:"",number:`${n} ${t}`}}}const Fle=["kimi","openai","openai_responses","anthropic","google-genai","vertexai"];function _m(){return{model:"",maxContextSize:"",displayName:"",capabilities:["tool_use","thinking"],supportEfforts:[],adaptiveThinking:!0}}function Wb(e,t){const n=[];for(const i of Object.values(t??{})){if(i===null||typeof i!="object")continue;const o=i;o.provider===e.id&&n.push({model:typeof o.model=="string"?o.model:"",maxContextSize:typeof o.maxContextSize=="number"?String(o.maxContextSize):"",displayName:typeof o.displayName=="string"?o.displayName:"",capabilities:Array.isArray(o.capabilities)?o.capabilities.filter(s=>typeof s=="string"):[],supportEfforts:Array.isArray(o.supportEfforts)?o.supportEfforts.filter(s=>typeof s=="string"):[],...typeof o.adaptiveThinking=="boolean"?{adaptiveThinking:o.adaptiveThinking}:{}})}return n}const RB=/^[\p{L}\p{N}][\p{L}\p{N}\-_ ]*$/u;function Dle(e,t={}){const n=e.id.trim();if(n==="")return"idRequired";if(!RB.test(n))return"idInvalid";if(t.requireApiKey===!0&&e.apiKey.trim()==="")return"apiKeyRequired";if(t.requireBaseUrl===!0&&e.baseUrl.trim()==="")return"baseUrlRequired";if(e.models.length===0)return"modelRequired";for(const i of e.models){if(i.model.trim()==="")return"modelRequired";const o=i.maxContextSize.trim();if(o==="")return"contextSizeRequired";if(!/^\d+$/.test(o)||Number(o)<1)return"contextSizeInvalid"}return null}function zB(e){return e.map(t=>{const n=t.displayName.trim();return{model:t.model.trim(),maxContextSize:Number(t.maxContextSize.trim()),...t.capabilities.length>0?{capabilities:[...t.capabilities]}:{},...t.supportEfforts.length>0?{supportEfforts:[...t.supportEfforts]}:{},...t.adaptiveThinking!==void 0?{adaptiveThinking:t.adaptiveThinking}:{},...n===""?{}:{displayName:n}}})}function Ble(e){const t=e.apiKey.trim(),n=e.baseUrl.trim();return{id:e.id.trim(),type:e.type,models:zB(e.models),...t===""?{}:{apiKey:t},...n===""?{}:{baseUrl:n}}}function $le(e,t,n){const i=zB(e.models),o=e.id.trim(),s=e.apiKey.trim(),r=e.baseUrl.trim(),l=n?.existingDefaultModel?.trim()??"",a=l.indexOf("/")>=0?l.slice(l.indexOf("/")+1):l;return{...t!==void 0&&o!==""&&o!==t.id?{newId:o}:{},type:e.type,models:i,...s===""&&n?.includeBlankApiKey!==!0?{}:{apiKey:s},...r===""?{}:{baseUrl:r},...a!==""&&i.some(u=>u.model===a)?{defaultModel:a}:{}}}function OB(e){return e.id==="managed:kimi-code"&&e.type==="kimi"}const w2="/devices/",PB="kimi-rc-device-id";function Rle(e){return new URLSearchParams(e.search).get("rc")==="1"}function jB(e){const{pathname:t}=e;if(!t.startsWith(w2))return;const n=t.slice(w2.length).split("/")[0];if(n)try{const i=decodeURIComponent(n);return i.length>0?i:void 0}catch{return}}function zle(e){if(jB({pathname:e})===void 0)return e;const t=e.slice(w2.length),n=t.indexOf("/");return n<0?"/":t.slice(n)}function Ole(e){return`${w2}${encodeURIComponent(e)}/`}function HB(e,t){const n=new URLSearchParams(t),i=n.get("rc"),o=n.get("from");if(i===null&&o===null)return e;const s=new URLSearchParams;return i!==null&&s.set("rc",i),o!==null&&s.set("from",o),`${e}?${s.toString()}`}function Ple(e){const t=jB(e);return t!==void 0?(Hle(t),t):jle()}function jle(){try{return window.sessionStorage.getItem(PB)??void 0}catch{return}}function Hle(e){try{window.sessionStorage.setItem(PB,e)}catch{}}const Wle=/^(\d+)\t(.*)$/;function qle(e){const t=e.at(-1)===""?e.slice(0,-1):e;if(t.length===0)return null;const n=[],i=[];for(const o of t){const s=Wle.exec(o);if(!s)return null;i.push(Number(s[1])),n.push(s[2]??"")}return{contents:n,lineNumbers:i}}function LS(e,t){let n="",i=t;const o=/^((?:\\\\|\/\/)[^\\/]+[\\/][^\\/]+)/.exec(t),s=/^([a-zA-Z]:)[\\/]?/.exec(t);o?(n=o[1],i=t.slice(o[1].length)):t.startsWith("/")?(n="/",i=t.slice(1)):s&&(n=s[1],i=t.slice(s[0].length));const r=n!=="",l=i.split(/[\\/]+/).filter(Boolean);for(const u of e.split("/"))u===""||u==="."||(u===".."?l.length>0&&l[l.length-1]!==".."?l.pop():r||l.push(".."):l.push(u));const a=l.join("/");return n==="/"?`/${a}`:n!==""?a?`${n}/${a}`:`${n}/`:a}function WB(e,t){for(const n of e.stateMachineNames){const i=(e.stateMachineInputs(n)??[]).find(o=>o.name===t);if(i!==void 0)return i}return null}function Ule(e,t){const n=WB(e,t);return n!==null&&typeof n.fire=="function"?(n.fire(),!0):!1}function NS(e,t,n){const i=WB(e,t);return i!==null&&typeof i.value==typeof n?(i.value=n,!0):!1}const p3={isPageHidden:()=>typeof document<"u"&&document.hidden,onVisibilityChange:e=>typeof document>"u"?()=>{}:(document.addEventListener("visibilitychange",e),()=>document.removeEventListener("visibilitychange",e)),observeIntersection:(e,t)=>{if(typeof IntersectionObserver!="function")return()=>{};const n=new IntersectionObserver(i=>{const o=i[0];o!==void 0&&t(o.isIntersecting)});return n.observe(e),()=>n.disconnect()}};function qB(e,t,n={}){const i=n.isPageHidden??p3.isPageHidden,o=n.onVisibilityChange??p3.onVisibilityChange,s=n.observeIntersection??p3.observeIntersection;let r=!i(),l=!0,a=!1;function u(){const h=!r||!l;h!==a&&(a=h,a?e.pause():e.play())}const c=o(()=>{r=!i(),u()}),d=s(t,h=>{l=h,u()});return u(),()=>{c(),d()}}const Kle={"&":"&","<":"<",">":">",'"':""","'":"'"};function FS(e){return e.replace(/[&<>"']/g,t=>Kle[t]??t)}function Vle(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Zle(e,t,n=40){const i=e.replace(/\s+/g," ").trim();if(i.length===0)return"";const o=t.trim();if(o.length===0)return DS(i,n*2);const s=i.toLowerCase().indexOf(o.toLowerCase());if(s<0)return DS(i,n*2);const r=Math.max(0,s-n),l=Math.min(i.length,s+o.length+n),a=r>0,u=l<i.length;return`${a?"…":""}${i.slice(r,l)}${u?"…":""}`}function DS(e,t){return e.length<=t?e:`${e.slice(0,t)}…`}function K1(e,t){const n=FS(e),i=t.trim();if(i.length===0)return n;const o=new RegExp(Vle(FS(i)),"gi");return n.replace(o,s=>`<mark>${s}</mark>`)}const js="kimi-web.server-credential",Gle="token",Qle=10080*60*1e3;let Da;const qb=new Set;function Yle(){if(typeof window>"u")return;const e=window.location.hash??"";if(!e.startsWith("#"))return;const n=new URLSearchParams(e.slice(1)).get(Gle);if(!n)return;const i=new URL(window.location.href);return i.hash="",window.history.replaceState(window.history.state,"",`${i.pathname}${i.search}`),n}function Ub(e){return{version:1,credential:e,expiresAt:Date.now()+Qle}}function Jle(e){return JSON.stringify(e)}function L6(e){try{const t=JSON.parse(e);if(typeof t!="object"||t===null)return;const n=t;return n.version!==1||typeof n.credential!="string"||n.credential.length===0||typeof n.expiresAt!="number"||!Number.isFinite(n.expiresAt)?void 0:{version:1,credential:n.credential,expiresAt:n.expiresAt}}catch{return}}function Kb(e){globalThis.localStorage?.setItem(js,Jle(e))}function Xle(){try{const e=globalThis.localStorage?.getItem(js);if(e){const n=L6(e);if(n===void 0){const i=Ub(e);let o=!1;try{Kb(i),o=!0}catch{}if(!o)try{globalThis.localStorage?.getItem(js)===e&&globalThis.localStorage?.removeItem(js),o=!0}catch{}try{globalThis.sessionStorage?.removeItem(js)}catch{}return o?i:void 0}if(n.expiresAt>Date.now())return n;globalThis.sessionStorage?.removeItem(js),globalThis.localStorage?.getItem(js)===e&&globalThis.localStorage?.removeItem(js);return}const t=globalThis.sessionStorage?.getItem(js);if(t){const n=Ub(t);let i=!1;try{Kb(n),i=!0}catch{}try{globalThis.sessionStorage?.removeItem(js),i=!0}catch{}return i?n:void 0}return}catch{return}}function eae(){const e=Yle();return e?(UB(e),!0):(Da=Xle(),Da!==void 0)}function tae(){if(Da!==void 0){if(Da.expiresAt<=Date.now()){nae(Da);return}return Da.credential}}function nae(e){Da=void 0;try{globalThis.sessionStorage?.removeItem(js);const t=globalThis.localStorage?.getItem(js),n=t==null?void 0:L6(t);(n===void 0?t===e.credential:n.credential===e.credential&&n.expiresAt===e.expiresAt)&&globalThis.localStorage?.removeItem(js)}catch{}}function UB(e){const t=Ub(e);Da=t;try{Kb(t)}catch{}try{globalThis.sessionStorage?.removeItem(js)}catch{}}function iae(){const e=Da;Da=void 0;try{const t=globalThis.localStorage?.getItem(js),i=(t==null?void 0:L6(t))?.credential??t;e!==void 0&&i===e.credential&&globalThis.localStorage?.removeItem(js),globalThis.sessionStorage?.removeItem(js)}catch{}}function oae(e){return qb.add(e),()=>{qb.delete(e)}}function sae(){iae();for(const e of qb)try{e()}catch{}}function og(e){return e.approvalCount>0?"awaiting-approval":e.questionCount>0?"awaiting-question":e.pendingInteraction==="approval"?"awaiting-approval":e.pendingInteraction==="question"?"awaiting-question":e.busy?"running":e.lastTurnReason==="failed"?"aborted":e.unread?"unread":"idle"}function BS(e){let t=null;for(const n of e){const i=og(n);if(i==="awaiting-approval")return"approval";i==="awaiting-question"?t="question":i==="aborted"?t!=="question"&&(t="aborted"):i==="unread"&&t===null&&(t="unread")}return t}let $S;function rae(e){if(typeof Intl.Segmenter=="function")return $S??=new Intl.Segmenter("und",{granularity:"grapheme"}),$S.segment(e)}const lae=/\p{Emoji_Presentation}/u,aae=/\p{Regional_Indicator}/u,uae=/\p{Extended_Pictographic}/u,cae="️";function dae(e){return lae.test(e)||aae.test(e)?!0:uae.test(e)&&e.includes(cae)}function KB(e){const t=rae(e)?.[Symbol.iterator]().next().value;if(t===void 0||!dae(t.segment))return{emoji:null,rest:e};const n=e.slice(t.index+t.segment.length).replace(/^\s+/,"");return{emoji:t.segment,rest:n}}function fae(e,t){const{rest:n}=KB(e),i=t?.trim()??"";return i?n?`${i} ${n}`:i:n}function VB(e,t){const n=e.findIndex(s=>s.id===t.id);if(n!==-1&&e[n].updatedAt===t.updatedAt)return e.map(s=>s.id===t.id?t:s);const i=e.filter(s=>s.id!==t.id),o=i.findIndex(s=>s.updatedAt<t.updatedAt);return o===-1?[...i,t]:[...i.slice(0,o),t,...i.slice(o)]}const Vb="/sessions/",ZB="/admin/sessions";function RS(e){return e.pathname===ZB}function zS(e){const{pathname:t}=e;if(!t.startsWith(Vb))return;const n=t.slice(Vb.length);if(!(!n||n.includes("/")))try{const i=decodeURIComponent(n);return i.length>0?i:void 0}catch{return}}function hae(e){return e===void 0||e.length===0?"/":`${Vb}${encodeURIComponent(e)}`}function GB(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const e=navigator.userAgentData;return e?.platform==="macOS"||e?.platform==="iOS"}function pae(e,t=GB()){return(t?e.metaKey&&!e.ctrlKey:e.ctrlKey&&!e.metaKey)&&!e.altKey&&!e.shiftKey&&(e.code==="KeyA"||e.key.toLowerCase()==="a")&&!e.defaultPrevented}function gae(e){return typeof HTMLElement<"u"&&e instanceof HTMLElement&&(e.isContentEditable||e.closest("input, textarea")!==null)}function mae(e,t){return typeof Element>"u"||!(e instanceof Element)?null:e.closest(t)}function OS(e){e.ownerDocument.getSelection()?.selectAllChildren(e)}function vae(e,t=GB()){return(t?e.metaKey&&!e.ctrlKey:e.ctrlKey&&!e.metaKey)&&!e.altKey&&!e.shiftKey&&(e.code==="KeyK"||e.key.toLowerCase()==="k")&&!e.defaultPrevented}function qc(e){return Array.isArray?Array.isArray(e):YB(e)==="[object Array]"}function yae(e){if(typeof e=="string")return e;if(typeof e=="bigint")return e.toString();const t=e+"";return t=="0"&&1/e==-1/0?"-0":t}function Zb(e){return e==null?"":yae(e)}function ir(e){return typeof e=="string"}function Av(e){return typeof e=="number"}function kae(e){return e===!0||e===!1||bae(e)&&YB(e)=="[object Boolean]"}function QB(e){return typeof e=="object"}function bae(e){return QB(e)&&e!==null}function sl(e){return e!=null}function Mm(e){return!e.trim().length}function YB(e){return e==null?e===void 0?"[object Undefined]":"[object Null]":Object.prototype.toString.call(e)}const Aae="Incorrect 'index' type",Gb="Invalid doc index: must be a non-negative integer within the bounds of the docs array",Cae=e=>`Invalid value for key ${e}`,wae=e=>`Pattern length exceeds max of ${e}.`,xae=e=>`Missing ${e} property in key`,Sae=e=>`Property 'weight' in key '${e}' must be a positive integer`,_ae="Fuse.match does not support useTokenSearch: token search requires corpus-level statistics (df, fieldCount) that a one-off string comparison does not have. Use new Fuse(...).search(...) instead.",PS=Object.prototype.hasOwnProperty;var Mae=class{constructor(e){this._keys=[],this._keyMap={};let t=0;e.forEach(n=>{const i=JB(n);this._keys.push(i),this._keyMap[i.id]=i,t+=i.weight}),this._keys.forEach(n=>{n.weight/=t})}get(e){return this._keyMap[e]}keys(){return this._keys}toJSON(){return JSON.stringify(this._keys)}};function JB(e){let t=null,n=null,i=null,o=1,s=null;if(ir(e)||qc(e))i=e,t=jS(e),n=Cv(e);else{if(!PS.call(e,"name"))throw new Error(xae("name"));const r=e.name;if(i=r,PS.call(e,"weight")&&e.weight!==void 0&&(o=e.weight,o<=0))throw new Error(Sae(Cv(r)));t=jS(r),n=Cv(r),s=e.getFn??null}return{path:t,id:n,weight:o,src:i,getFn:s}}function jS(e){return qc(e)?e:e.split(".")}function Cv(e){return qc(e)?e.join("."):e}function Iae(e,t){const n=[];let i=!1;const o=(s,r,l,a)=>{if(sl(s))if(!r[l])n.push(a!==void 0?{v:s,i:a}:s);else{const u=s[r[l]];if(!sl(u))return;if(l===r.length-1&&(ir(u)||Av(u)||kae(u)||typeof u=="bigint"))n.push(a!==void 0?{v:Zb(u),i:a}:Zb(u));else if(qc(u)){i=!0;for(let c=0,d=u.length;c<d;c+=1)o(u[c],r,l+1,c)}else r.length&&o(u,r,l+1,a)}};return o(e,ir(t)?t.split("."):t,0),i?n:n[0]}const Eae={includeMatches:!1,findAllMatches:!1,minMatchCharLength:1},Tae={isCaseSensitive:!1,ignoreDiacritics:!1,includeScore:!1,keys:[],shouldSort:!0,sortFn:(e,t)=>e.score===t.score?e.idx<t.idx?-1:1:e.score<t.score?-1:1},Lae={location:0,threshold:.6,distance:100},Nae={useExtendedSearch:!1,useTokenSearch:!1,tokenize:void 0,tokenMatch:"any",getFn:Iae,ignoreLocation:!1,ignoreFieldNorm:!1,fieldNormWeight:1},In=Object.freeze({...Tae,...Eae,...Lae,...Nae});function Fae(e){return e>=9&&e<=13||e===32||e===160}function Dae(e=1,t=3){const n=new Map,i=Math.pow(10,t);return{get(o){let s=0,r=!1;for(let a=0;a<o.length;a++)Fae(o.charCodeAt(a))?r=!1:r||(s++,r=!0);if(s===0&&(s=1),n.has(s))return n.get(s);const l=Math.round(i/Math.pow(s,.5*e))/i;return n.set(s,l),l},clear(){n.clear()}}}var N6=class{constructor({getFn:e=In.getFn,fieldNormWeight:t=In.fieldNormWeight}={}){this.norm=Dae(t,3),this.getFn=e,this.isCreated=!1,this.docs=[],this.keys=[],this._keysMap={},this.setIndexRecords()}setSources(e=[]){this.docs=e}setIndexRecords(e=[]){this.records=e}setKeys(e=[]){this.keys=e,this._keysMap={},e.forEach((t,n)=>{this._keysMap[t.id]=n})}create(){if(this.isCreated||!this.docs.length)return;this.isCreated=!0;const e=this.docs.length;this.records=new Array(e);let t=0;if(ir(this.docs[0]))for(let n=0;n<e;n++){const i=this._createStringRecord(this.docs[n],n);i&&(this.records[t++]=i)}else for(let n=0;n<e;n++)this.records[t++]=this._createObjectRecord(this.docs[n],n);this.records.length=t,this.norm.clear()}add(e,t){if(!Number.isInteger(t)||t<0)throw new Error(Gb);if(ir(e)){const i=this._createStringRecord(e,t);return i&&this.records.push(i),i}const n=this._createObjectRecord(e,t);return this.records.push(n),n}removeAt(e){if(!Number.isInteger(e)||e<0)throw new Error(Gb);for(let t=0,n=this.records.length;t<n;t+=1)if(this.records[t].i===e){this.records.splice(t,1);break}for(let t=0,n=this.records.length;t<n;t+=1)this.records[t].i>e&&(this.records[t].i-=1)}removeAll(e){const t=new Set;for(const i of e)Number.isInteger(i)&&i>=0&&t.add(i);if(t.size===0)return;this.records=this.records.filter(i=>!t.has(i.i));const n=Array.from(t).sort((i,o)=>i-o);for(const i of this.records){let o=0,s=n.length;for(;o<s;){const r=o+s>>>1;n[r]<i.i?o=r+1:s=r}i.i-=o}}getValueForItemAtKeyId(e,t){return e[this._keysMap[t]]}size(){return this.records.length}_createStringRecord(e,t){return!sl(e)||Mm(e)?null:{v:e,i:t,n:this.norm.get(e)}}_createObjectRecord(e,t){const n={i:t,$:{}};for(let i=0,o=this.keys.length;i<o;i++){const s=this.keys[i],r=s.getFn?s.getFn(e):this.getFn(e,s.path);if(sl(r)){if(qc(r)){const l=[];for(let a=0,u=r.length;a<u;a+=1){const c=r[a];if(sl(c)){if(ir(c)){if(!Mm(c)){const d={v:c,i:a,n:this.norm.get(c)};l.push(d)}}else if(sl(c.v)){const d=ir(c.v)?c.v:Zb(c.v);if(!Mm(d)){const h={v:d,i:c.i,n:this.norm.get(d)};l.push(h)}}}}n.$[i]=l}else if(ir(r)&&!Mm(r)){const l={v:r,n:this.norm.get(r)};n.$[i]=l}}}return n}toJSON(){return{keys:this.keys.map(({getFn:e,...t})=>t),records:this.records}}};function XB(e,t,{getFn:n=In.getFn,fieldNormWeight:i=In.fieldNormWeight}={}){const o=new N6({getFn:n,fieldNormWeight:i});return o.setKeys(e.map(JB)),o.setSources(t),o.create(),o}function Bae(e,{getFn:t=In.getFn,fieldNormWeight:n=In.fieldNormWeight}={}){const{keys:i,records:o}=e,s=new N6({getFn:t,fieldNormWeight:n});return s.setKeys(i),s.setIndexRecords(o),s}function $ae(e=[],t=In.minMatchCharLength){const n=[];let i=-1,o=-1,s=0;for(let r=e.length;s<r;s+=1){const l=e[s];l&&i===-1?i=s:!l&&i!==-1&&(o=s-1,o-i+1>=t&&n.push([i,o]),i=-1)}return e[s-1]&&s-i>=t&&n.push([i,s-1]),n}function Rae(e,t,n,{location:i=In.location,distance:o=In.distance,threshold:s=In.threshold,findAllMatches:r=In.findAllMatches,minMatchCharLength:l=In.minMatchCharLength,includeMatches:a=In.includeMatches,ignoreLocation:u=In.ignoreLocation}={}){if(t.length>32)throw new Error(wae(32));const c=t.length,d=e.length,h=Math.max(0,Math.min(i,d));let p=s,g=h;const m=(L,M)=>{const N=L/c;if(u)return N;const I=Math.abs(h-M);return o?N+I/o:I?1:N},k=l>1||a,w=k?Array(d):[];let y;for(;(y=e.indexOf(t,g))>-1;){const L=m(0,y);if(p=Math.min(L,p),g=y+c,k){let M=0;for(;M<c;)w[y+M]=1,M+=1}}g=-1;let b=[],A=1,T=0,S=c+d;const x=1<<c-1;for(let L=0;L<c;L+=1){let M=0,N=S;for(;M<N;)m(L,h+N)<=p?M=N:S=N,N=Math.floor((S-M)/2+M);S=N;let I=Math.max(1,h-N+1);const z=r?d:Math.min(h+N,d)+c,H=Array(z+2);H[z+1]=(1<<L)-1;for(let O=z;O>=I;O-=1){const R=O-1,j=n[e[R]];if(H[O]=(H[O+1]<<1|1)&j,L&&(H[O]|=(b[O+1]|b[O])<<1|1|b[O+1]),H[O]&x&&(A=m(L,R),A<=p)){if(p=A,g=R,T=L,g<=h)break;I=Math.max(1,2*h-g)}}if(m(L+1,h)>p)break;b=H}if(k&&g>=0){const L=Math.min(d-1,g+c-1+T);for(let M=g;M<=L;M+=1)n[e[M]]&&(w[M]=1)}const _={isMatch:g>=0,score:Math.max(.001,A)};if(k){const L=$ae(w,l);L.length?a&&(_.indices=L):_.isMatch=!1}return _}function zae(e){const t={};for(let n=0,i=e.length;n<i;n+=1){const o=e.charAt(n);t[o]=(t[o]||0)|1<<i-n-1}return t}function F6(e){if(e.length<=1)return e;e.sort((n,i)=>n[0]-i[0]||n[1]-i[1]);const t=[e[0]];for(let n=1,i=e.length;n<i;n+=1){const o=t[t.length-1],s=e[n];s[0]<=o[1]+1?o[1]=Math.max(o[1],s[1]):t.push(s)}return t}const e$={ł:"l",Ł:"L",đ:"d",Đ:"D",ø:"o",Ø:"O",ħ:"h",Ħ:"H",ŧ:"t",Ŧ:"T",ı:"i",ß:"ss"},Oae=new RegExp("["+Object.keys(e$).join("")+"]","g"),M0=typeof String.prototype.normalize=="function"?e=>e.normalize("NFD").replace(/[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/g,"").replace(Oae,t=>e$[t]):e=>e;var D6=class{constructor(e,{location:t=In.location,threshold:n=In.threshold,distance:i=In.distance,includeMatches:o=In.includeMatches,findAllMatches:s=In.findAllMatches,minMatchCharLength:r=In.minMatchCharLength,isCaseSensitive:l=In.isCaseSensitive,ignoreDiacritics:a=In.ignoreDiacritics,ignoreLocation:u=In.ignoreLocation}={}){if(this.options={location:t,threshold:n,distance:i,includeMatches:o,findAllMatches:s,minMatchCharLength:r,isCaseSensitive:l,ignoreDiacritics:a,ignoreLocation:u},e=l?e:e.toLowerCase(),e=a?M0(e):e,this.pattern=e,this.chunks=[],!this.pattern.length)return;const c=(h,p)=>{this.chunks.push({pattern:h,alphabet:zae(h),startIndex:p})},d=this.pattern.length;if(d>32){let h=0;const p=d%32,g=d-p;for(;h<g;)c(this.pattern.substr(h,32),h),h+=32;if(p){const m=d-32;c(this.pattern.substr(m),m)}}else c(this.pattern,0)}searchIn(e){const{isCaseSensitive:t,ignoreDiacritics:n,includeMatches:i}=this.options;if(e=t?e:e.toLowerCase(),e=n?M0(e):e,this.pattern===e){if(e.length<this.options.minMatchCharLength)return{isMatch:!1,score:1};const g={isMatch:!0,score:0};return i&&(g.indices=[[0,e.length-1]]),g}const{location:o,distance:s,threshold:r,findAllMatches:l,minMatchCharLength:a,ignoreLocation:u}=this.options,c=[];let d=0,h=!1;this.chunks.forEach(({pattern:g,alphabet:m,startIndex:k})=>{const{isMatch:w,score:y,indices:b}=Rae(e,g,m,{location:o+k,distance:s,threshold:r,findAllMatches:l,minMatchCharLength:a,includeMatches:i,ignoreLocation:u});w&&(h=!0),d+=y,w&&b&&c.push(...b)});const p={isMatch:h,score:h?d/this.chunks.length:1};return h&&i&&(p.indices=F6(c)),p}};const Pae=new Set(["fuzzy","include"]);function jae(e){return e.startsWith("inverse")}const Qb=[{type:"exact",multiRegex:/^="(.*)"$/,singleRegex:/^=(.*)$/,create:e=>({type:"exact",search(t){const n=t===e;return{isMatch:n,score:n?0:1,indices:[0,e.length-1]}}})},{type:"include",multiRegex:/^'"(.*)"$/,singleRegex:/^'(.*)$/,create:e=>({type:"include",search(t){let n=0,i;const o=[],s=e.length;for(;(i=t.indexOf(e,n))>-1;)n=i+s,o.push([i,n-1]);const r=!!o.length;return{isMatch:r,score:r?0:1,indices:o}}})},{type:"prefix-exact",multiRegex:/^\^"(.*)"$/,singleRegex:/^\^(.*)$/,create:e=>({type:"prefix-exact",search(t){const n=t.startsWith(e);return{isMatch:n,score:n?0:1,indices:[0,e.length-1]}}})},{type:"inverse-prefix-exact",multiRegex:/^!\^"(.*)"$/,singleRegex:/^!\^(.*)$/,create:e=>({type:"inverse-prefix-exact",search(t){const n=!t.startsWith(e);return{isMatch:n,score:n?0:1,indices:[0,t.length-1]}}})},{type:"inverse-suffix-exact",multiRegex:/^!"(.*)"\$$/,singleRegex:/^!(.*)\$$/,create:e=>({type:"inverse-suffix-exact",search(t){const n=!t.endsWith(e);return{isMatch:n,score:n?0:1,indices:[0,t.length-1]}}})},{type:"suffix-exact",multiRegex:/^"(.*)"\$$/,singleRegex:/^(.*)\$$/,create:e=>({type:"suffix-exact",search(t){const n=t.endsWith(e);return{isMatch:n,score:n?0:1,indices:[t.length-e.length,t.length-1]}}})},{type:"inverse-exact",multiRegex:/^!"(.*)"$/,singleRegex:/^!(.*)$/,create:e=>({type:"inverse-exact",search(t){const n=t.indexOf(e)===-1;return{isMatch:n,score:n?0:1,indices:[0,t.length-1]}}})},{type:"fuzzy",multiRegex:/^"(.*)"$/,singleRegex:/^(.*)$/,create:(e,t={})=>{const n=new D6(e,{location:t.location??In.location,threshold:t.threshold??In.threshold,distance:t.distance??In.distance,includeMatches:t.includeMatches??In.includeMatches,findAllMatches:t.findAllMatches??In.findAllMatches,minMatchCharLength:t.minMatchCharLength??In.minMatchCharLength,isCaseSensitive:t.isCaseSensitive??In.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics??In.ignoreDiacritics,ignoreLocation:t.ignoreLocation??In.ignoreLocation});return{type:"fuzzy",search(i){return n.searchIn(i)}}}}],HS=Qb.length,Hae="\0",Wae="|";function qae(e){const t=[],n=e.length;let i=0;for(;i<n;){for(;i<n&&e[i]===" ";)i++;if(i>=n)break;let o=i;for(;o<n&&e[o]!==" "&&e[o]!=='"';)o++;if(o<n&&e[o]==='"'){for(o++;o<n;){if(e[o]==='"'){const s=o+1;if(s>=n||e[s]===" "){o++;break}if(e[s]==="$"&&(s+1>=n||e[s+1]===" ")){o+=2;break}}o++}t.push(e.substring(i,o)),i=o}else{for(;o<n&&e[o]!==" ";)o++;t.push(e.substring(i,o)),i=o}}return t}function WS(e,t){const n=e.match(t);return n?n[1]:null}function Uae(e,t={}){return e.replace(/\\\|/g,Hae).split(Wae).map(n=>{const i=qae(n.replace(/\u0000/g,"|").trim()).filter(s=>s&&!!s.trim()),o=[];for(let s=0,r=i.length;s<r;s+=1){const l=i[s];let a=!1,u=-1;for(;!a&&++u<HS;){const c=Qb[u],d=WS(l,c.multiRegex);d&&(o.push(c.create(d,t)),a=!0)}if(!a)for(u=-1;++u<HS;){const c=Qb[u],d=WS(l,c.singleRegex);if(d){o.push(c.create(d,t));break}}}return o})}var Kae=class{constructor(e,{isCaseSensitive:t=In.isCaseSensitive,ignoreDiacritics:n=In.ignoreDiacritics,includeMatches:i=In.includeMatches,minMatchCharLength:o=In.minMatchCharLength,ignoreLocation:s=In.ignoreLocation,findAllMatches:r=In.findAllMatches,location:l=In.location,threshold:a=In.threshold,distance:u=In.distance}={}){this.query=null,this.options={isCaseSensitive:t,ignoreDiacritics:n,includeMatches:i,minMatchCharLength:o,findAllMatches:r,ignoreLocation:s,location:l,threshold:a,distance:u},e=t?e:e.toLowerCase(),e=n?M0(e):e,this.pattern=e,this.query=Uae(this.pattern,this.options)}static condition(e,t){return t.useExtendedSearch}searchIn(e){const t=this.query;if(!t)return{isMatch:!1,score:1};const{includeMatches:n,isCaseSensitive:i,ignoreDiacritics:o}=this.options;e=i?e:e.toLowerCase(),e=o?M0(e):e;let s=0;const r=[];let l=0,a=!1;for(let u=0,c=t.length;u<c;u+=1){const d=t[u];r.length=0,s=0,a=!1;for(let h=0,p=d.length;h<p;h+=1){const g=d[h],{isMatch:m,indices:k,score:w}=g.search(e);if(m)s+=1,l+=w,jae(g.type)&&(a=!0),n&&(Pae.has(g.type)?r.push(...k):r.push(k));else{l=0,s=0,r.length=0,a=!1;break}}if(s){const h={isMatch:!0,score:l/s};return a&&(h.hasInverse=!0),n&&(h.indices=F6(r)),h}}return{isMatch:!1,score:1}}};const Yb=[];function B6(...e){Yb.push(...e)}function x2(e,t){for(let n=0,i=Yb.length;n<i;n+=1){const o=Yb[n];if(o.condition(e,t))return new o(e,t)}return new D6(e,t)}const S2={AND:"$and",OR:"$or"},Jb={PATH:"$path",PATTERN:"$val"},Xb=e=>!!(e[S2.AND]||e[S2.OR]),Vae=e=>!!e[Jb.PATH],Zae=e=>!qc(e)&&QB(e)&&!Xb(e),qS=e=>({[S2.AND]:Object.keys(e).map(t=>({[t]:e[t]}))});function t$(e,t,{auto:n=!0}={}){const i=o=>{if(ir(o)){const a={keyId:null,pattern:o};return n&&(a.searcher=x2(o,t)),a}const s=Object.keys(o),r=Vae(o);if(!r&&s.length>1&&!Xb(o))return i(qS(o));if(Zae(o)){const a=r?o[Jb.PATH]:s[0],u=r?o[Jb.PATTERN]:o[a];if(!ir(u))throw new Error(Cae(a));const c={keyId:Cv(a),pattern:u};return n&&(c.searcher=x2(u,t)),c}const l={children:[],operator:s[0]};return s.forEach(a=>{const u=o[a];qc(u)&&u.forEach(c=>{l.children.push(i(c))})}),l};return Xb(e)||(e=qS(e)),i(e)}function e8(e,{ignoreFieldNorm:t=In.ignoreFieldNorm}){let n=1;return e.forEach(({key:i,norm:o,score:s})=>{const r=i?i.weight:null;n*=Math.pow(s===0&&r?Number.EPSILON:s,(r||1)*(t?1:o))}),n}function Gae(e,{ignoreFieldNorm:t=In.ignoreFieldNorm}){e.forEach(n=>{n.score=e8(n.matches,{ignoreFieldNorm:t})})}var Qae=class{constructor(e,t){this.limit=e,this.heap=[],this.comparator=t}get size(){return this.heap.length}insert(e){this.size<this.limit?(this.heap.push(e),this._bubbleUp(this.size-1)):this.comparator(e,this.heap[0])<0&&(this.heap[0]=e,this._sinkDown(0))}extractSorted(){return this.heap.sort(this.comparator)}_bubbleUp(e){const t=this.heap;for(;e>0;){const n=e-1>>1;if(this.comparator(t[e],t[n])<=0)break;const i=t[e];t[e]=t[n],t[n]=i,e=n}}_sinkDown(e){const t=this.heap,n=t.length;let i=e;do{e=i;const o=2*e+1,s=2*e+2;if(o<n&&this.comparator(t[o],t[i])>0&&(i=o),s<n&&this.comparator(t[s],t[i])>0&&(i=s),i!==e){const r=t[e];t[e]=t[i],t[i]=r}}while(i!==e)}};function Yae(e){const t=[];return e.matches.forEach(n=>{if(!sl(n.indices)||!n.indices.length)return;const i={indices:n.indices,value:n.value};n.key&&(i.key=n.key.id),n.idx>-1&&(i.refIndex=n.idx),t.push(i)}),t}function Jae(e,t,{includeMatches:n=In.includeMatches,includeScore:i=In.includeScore}={}){return e.map(o=>{const{idx:s}=o,r={item:t[s],refIndex:s};return n&&(r.matches=Yae(o)),i&&(r.score=o.score),r})}const Xae=/[\p{L}\p{M}\p{N}_]+/gu,US=new WeakSet;function eue(e){US.has(e)||(US.add(e),console.warn(`[Fuse] tokenize regex ${e} lacks the global flag; only the first match per text will be returned. Add the 'g' flag.`))}function tue(e){if(typeof e=="function"){let t=!1;return n=>{const i=e(n);if(!t&&(t=!0,!Array.isArray(i)||i.some(o=>typeof o!="string")))throw new Error(`[Fuse] tokenize function must return string[]; received ${Array.isArray(i)?"array containing non-strings":typeof i}.`);return i}}return e instanceof RegExp?(e.global||eue(e),t=>t.match(e)||[]):t=>t.match(Xae)||[]}function t8({isCaseSensitive:e=!1,ignoreDiacritics:t=!1,tokenize:n}={}){const i=tue(n);return{tokenize(o){return e||(o=o.toLowerCase()),t&&(o=M0(o)),i(o)}}}var nue=class{static condition(e,t){return t.useTokenSearch}constructor(e,t){this.options=t,this.analyzer=t8({isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics,tokenize:t.tokenize});const n=this.analyzer.tokenize(e),{df:i,fieldCount:o}=t._invertedIndex;this.termSearchers=[],this.idfWeights=[];for(const s of n){this.termSearchers.push(new D6(s,{location:t.location,threshold:t.threshold,distance:t.distance,includeMatches:t.includeMatches,findAllMatches:t.findAllMatches,minMatchCharLength:t.minMatchCharLength,isCaseSensitive:t.isCaseSensitive,ignoreDiacritics:t.ignoreDiacritics,ignoreLocation:!0}));const r=i.get(s)||0,l=Math.log(1+(o-r+.5)/(r+.5));this.idfWeights.push(l)}this.combineAll=t.tokenMatch==="all",this.numTerms=this.termSearchers.length,this.useMask=this.numTerms<=31}searchIn(e){if(!this.termSearchers.length)return{isMatch:!1,score:1};const t=[];let n=0,i=0,o=0,s=0;const r=this.combineAll&&!this.useMask?new Set:null;for(let u=0;u<this.termSearchers.length;u++){const c=this.termSearchers[u].searchIn(e),d=this.idfWeights[u];i+=d,c.isMatch&&(o++,n+=d*(1-c.score),c.indices&&t.push(...c.indices),this.combineAll&&(this.useMask?s|=1<<u:r.add(u)))}if(o===0)return{isMatch:!1,score:1};const l=i>0?1-n/i:0,a={isMatch:!0,score:Math.max(.001,l)};return this.options.includeMatches&&t.length&&(a.indices=F6(t)),this.combineAll&&(this.useMask?a.matchedMask=s:a.matchedTerms=r,a.termCount=this.numTerms),a}};function g3(e,t,n,i){const o=i.tokenize(t);if(!o.length)return;e.fieldCount++,e.docFieldCount.set(n,(e.docFieldCount.get(n)||0)+1);const s=new Set(o);let r=e.docTermFieldHits.get(n);r||(r=new Map,e.docTermFieldHits.set(n,r));for(const l of s)r.set(l,(r.get(l)||0)+1),e.df.set(l,(e.df.get(l)||0)+1)}function n$(e,t,n,i){const{i:o,v:s,$:r}=t;if(s!==void 0){g3(e,s,o,i);return}if(r)for(let l=0;l<n;l++){const a=r[l];if(a)if(Array.isArray(a))for(const u of a)g3(e,u.v,o,i);else g3(e,a.v,o,i)}}function iue(e,t,n){const i={fieldCount:0,df:new Map,docFieldCount:new Map,docTermFieldHits:new Map};for(const o of e)n$(i,o,t,n);return i}function oue(e,t,n,i){n$(e,t,n,i)}function sue(e,t){const n=e.docFieldCount.get(t);if(n===void 0)return;e.fieldCount-=n,e.docFieldCount.delete(t);const i=e.docTermFieldHits.get(t);if(i){for(const[o,s]of i){const r=(e.df.get(o)||0)-s;r<=0?e.df.delete(o):e.df.set(o,r)}e.docTermFieldHits.delete(t)}}function KS(e,t){if(t.length===0)return;const n=Array.from(new Set(t)).sort((l,a)=>l-a);for(const l of n)sue(e,l);const i=l=>{let a=0,u=n.length;for(;a<u;){const c=a+u>>>1;n[c]<l?a=c+1:u=c}return l-a},o=n[0],s=new Map;for(const[l,a]of e.docFieldCount)s.set(l>o?i(l):l,a);e.docFieldCount=s;const r=new Map;for(const[l,a]of e.docTermFieldHits)r.set(l>o?i(l):l,a);e.docTermFieldHits=r}var Uc=class{constructor(e,t,n){this.options={...In,...t},this.options.useExtendedSearch,this.options.useTokenSearch,this._keyStore=new Mae(this.options.keys),this._docs=e,this._myIndex=null,this._invertedIndex=null,this.setCollection(e,n),this._lastQuery=null,this._lastSearcher=null}_getSearcher(e){if(this._lastQuery===e)return this._lastSearcher;const t=x2(e,this._invertedIndex?{...this.options,_invertedIndex:this._invertedIndex}:this.options);return this._lastQuery=e,this._lastSearcher=t,t}setCollection(e,t){if(this._docs=e,t&&!(t instanceof N6))throw new Error(Aae);if(this._myIndex=t||XB(this.options.keys,this._docs,{getFn:this.options.getFn,fieldNormWeight:this.options.fieldNormWeight}),this.options.useTokenSearch){const n=t8({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics,tokenize:this.options.tokenize});this._invertedIndex=iue(this._myIndex.records,this._myIndex.keys.length,n)}this._invalidateSearcherCache()}add(e){if(!sl(e))return;this._docs.push(e);const t=this._myIndex.add(e,this._docs.length-1);if(this._invertedIndex&&t){const n=t8({isCaseSensitive:this.options.isCaseSensitive,ignoreDiacritics:this.options.ignoreDiacritics,tokenize:this.options.tokenize});oue(this._invertedIndex,t,this._myIndex.keys.length,n)}this._invalidateSearcherCache()}remove(e=()=>!1){const t=[],n=[];for(let i=0,o=this._docs.length;i<o;i+=1)e(this._docs[i],i)&&(t.push(this._docs[i]),n.push(i));if(n.length){this._invertedIndex&&KS(this._invertedIndex,n);const i=new Set(n);this._docs=this._docs.filter((o,s)=>!i.has(s)),this._myIndex.removeAll(n),this._invalidateSearcherCache()}return t}removeAt(e){if(!Number.isInteger(e)||e<0||e>=this._docs.length)throw new Error(Gb);this._invertedIndex&&KS(this._invertedIndex,[e]);const t=this._docs.splice(e,1)[0];return this._myIndex.removeAt(e),this._invalidateSearcherCache(),t}_invalidateSearcherCache(){this._lastQuery=null,this._lastSearcher=null}getIndex(){return this._myIndex}_normalizedKeys(){return this._myIndex.keys.map(e=>this._keyStore.get(e.id)||e)}search(e,t){const{limit:n=-1}=t||{},{includeMatches:i,includeScore:o,shouldSort:s,sortFn:r,ignoreFieldNorm:l}=this.options;if(ir(e)&&!e.trim()){let h=this._docs.map((p,g)=>({item:p,refIndex:g}));return Av(n)&&n>-1&&(h=h.slice(0,n)),h}const a=s&&Av(n)&&n>0&&ir(e),u=r,c=(h,p)=>u(h,p)||h.idx-p.idx;let d;if(a){const h=new Qae(n,c);ir(this._docs[0])?this._searchStringList(e,{heap:h,ignoreFieldNorm:l}):this._searchObjectList(e,{heap:h,ignoreFieldNorm:l}),d=h.extractSorted()}else d=ir(e)?ir(this._docs[0])?this._searchStringList(e):this._searchObjectList(e):this._searchLogical(e),Gae(d,{ignoreFieldNorm:l}),s&&d.sort(ir(e)?c:u),Av(n)&&n>-1&&(d=d.slice(0,n));return Jae(d,this._docs,{includeMatches:i,includeScore:o})}_searchStringList(e,{heap:t,ignoreFieldNorm:n}={}){const i=this._getSearcher(e),o=this.options.useTokenSearch&&this.options.tokenMatch==="all",{records:s}=this._myIndex,r=t?null:[];return s.forEach(({v:l,i:a,n:u})=>{if(!sl(l))return;const c=i.searchIn(l);if(c.isMatch){const d={score:c.score,value:l,norm:u,indices:c.indices};o&&(d.matchedMask=c.matchedMask,d.matchedTerms=c.matchedTerms,d.termCount=c.termCount);const h=[d];if(!o||this._coversAllTokens(h)){const p={item:l,idx:a,matches:h};t?(p.score=e8(p.matches,{ignoreFieldNorm:n}),t.insert(p)):r.push(p)}}}),r}_searchLogical(e){const t=t$(e,this.options),n=this._normalizedKeys(),i=(l,a,u)=>{if(!("children"in l)){const{keyId:p,searcher:g}=l;let m;return p===null?(m=[],n.forEach((k,w)=>{m.push(...this._findMatches({key:k,value:a[w],searcher:g}))})):m=this._findMatches({key:this._keyStore.get(p),value:this._myIndex.getValueForItemAtKeyId(a,p),searcher:g}),m&&m.length?[{idx:u,item:a,matches:m}]:[]}const{children:c,operator:d}=l,h=[];for(let p=0,g=c.length;p<g;p+=1){const m=c[p],k=i(m,a,u);if(k.length)h.push(...k);else if(d===S2.AND)return[]}return h},o=this._myIndex.records,s=new Map,r=[];return o.forEach(({$:l,i:a})=>{if(sl(l)){const u=i(t,l,a);u.length&&(s.has(a)||(s.set(a,{idx:a,item:l,matches:[]}),r.push(s.get(a))),u.forEach(({matches:c})=>{s.get(a).matches.push(...c)}))}}),r}_searchObjectList(e,{heap:t,ignoreFieldNorm:n}={}){const i=this._getSearcher(e),o=this.options.useTokenSearch&&this.options.tokenMatch==="all",{records:s}=this._myIndex,r=this._normalizedKeys(),l=t?null:[];return s.forEach(({$:a,i:u})=>{if(!sl(a))return;const c=[];let d=!1,h=!1;if(r.forEach((p,g)=>{const m=this._findMatches({key:p,value:a[g],searcher:i});m.length?(c.push(...m),m[0].hasInverse&&(h=!0)):d=!0}),!(h&&d)&&c.length&&(!o||this._coversAllTokens(c))){const p={idx:u,item:a,matches:c};t?(p.score=e8(p.matches,{ignoreFieldNorm:n}),t.insert(p)):l.push(p)}}),l}_findMatches({key:e,value:t,searcher:n}){if(!sl(t))return[];const i=[];if(qc(t))t.forEach(({v:o,i:s,n:r})=>{if(!sl(o))return;const l=n.searchIn(o);if(l.isMatch){const a={score:l.score,key:e,value:o,idx:s,norm:r,indices:l.indices,hasInverse:l.hasInverse};l.termCount!==void 0&&(a.matchedMask=l.matchedMask,a.matchedTerms=l.matchedTerms,a.termCount=l.termCount),i.push(a)}});else{const{v:o,n:s}=t,r=n.searchIn(o);if(r.isMatch){const l={score:r.score,key:e,value:o,norm:s,indices:r.indices,hasInverse:r.hasInverse};r.termCount!==void 0&&(l.matchedMask=r.matchedMask,l.matchedTerms=r.matchedTerms,l.termCount=r.termCount),i.push(l)}}return i}_coversAllTokens(e){const t=e.length?e[0].termCount:void 0;if(t===void 0)return!0;if(t<=31){let i=0;for(let o=0;o<e.length;o++)i|=e[o].matchedMask||0;return i===2**t-1}const n=new Set;for(let i=0;i<e.length;i++){const o=e[i].matchedTerms;if(o)for(const s of o)n.add(s)}return n.size===t}};Uc.version="7.5.0";Uc.createIndex=XB;Uc.parseIndex=Bae;Uc.config=In;Uc.match=function(e,t,n){if(n&&n.useTokenSearch)throw new Error(_ae);return x2(e,{...In,...n}).searchIn(t)};Uc.parseQuery=t$;B6(Kae);B6(nue);Uc.use=function(...e){e.forEach(t=>B6(t))};var rue=Uc;const lue=/^[\uD800-\uDBFF]$/,aue=/^[\uDC00-\uDFFF]$/,uue=/[\uD800-\uDBFF][\uDC00-\uDFFF]/g;var VS;(function(e){e[e.Unknown=1e-13]="Unknown",e[e.Rule=1e-12]="Rule",e[e.DICT=2e-8]="DICT",e[e.Surname=1]="Surname",e[e.Custom=1]="Custom"})(VS||(VS={}));const yl={Normal:1,Surname:10,Custom:100};function ta(e){var t;return e.length-(((t=e.match(uue))===null||t===void 0?void 0:t.length)||0)}function n8(e){const t=[];let n=0;for(;n<e.length;){const i=e[n];lue.test(i)&&aue.test(e[n+1])?(t.push(e.substring(n,n+2)),n+=2):(t.push(i),n+=1)}return t}class i${constructor(){this.NumberDICT=[],this.StringDICT=new Map}get(t){if(t.length>1)return this.StringDICT.get(t);{const n=t.charCodeAt(0);return this.NumberDICT[n]}}set(t,n){if(t.length>1)this.StringDICT.set(t,n);else{const i=t.charCodeAt(0);this.NumberDICT[i]=n}}clear(){this.NumberDICT=[],this.StringDICT.clear()}}const cue=["zh","ch","sh","z","c","s","b","p","m","f","d","t","n","l","g","k","h","j","q","x","r","y","w",""],due=["j","q","x"],fue=["uān","uán","uǎn","uàn","uan","uē","ué","uě","uè","ue","ūn","ún","ǔn","ùn","un","ū","ú","ǔ","ù","u"],hue={uān:"üān",uán:"üán",uǎn:"üǎn",uàn:"üàn",uan:"üan",uē:"üē",ué:"üé",uě:"üě",uè:"üè",ue:"üe",ūn:"ǖn",ún:"ǘn",ǔn:"ǚn",ùn:"ǜn",un:"ün",ū:"ǖ",ú:"ǘ",ǔ:"ǚ",ù:"ǜ",u:"ü"},pue=["ia","ian","iang","iao","ie","iu","iong","ua","uai","uan","uang","ue","ui","uo","üan","üe","van","ve"],ZS={一:"yì",二:"èr",三:"sān",四:"sì",五:"wǔ",六:"liù",七:"qī",八:"bā",九:"jiǔ",十:"shí",百:"bǎi",千:"qiān",万:"wàn",亿:"yì",单:"dān",两:"liǎng",双:"shuāng",多:"duō",几:"jǐ",十一:"shí yī",零一:"líng yī",第一:"dì yī",一十:"yī shí",一十一:"yī shí yī"},GS={重:"chóng",行:"háng",斗:"dǒu",更:"gēng"};function gue(){const e={零一:"líng yī","〇一":"líng yī",十一:"shí yī",一十:"yī shí",第一:"dì yī",一十一:"yī shí yī"};for(let t in ZS)for(let n in GS){const i=`${t}${n}`,o=`${ZS[t]} ${GS[n]}`;e[i]=o}return e}const QS=gue(),mue=Object.keys(QS).map(e=>({zh:e,pinyin:QS[e],probability:1e-12,length:ta(e),priority:yl.Normal,dict:Symbol("rule")})),o$={不:{bú:[4]},一:{yí:[4],yì:[1,2,3]}},vue={不:["的","而","之","后","也","还","地"],一:["的","而","之","后","也","还","是"]},yue=Object.keys(o$),i8={南宫:"nán gōng",第五:"dì wǔ",万俟:"mò qí",司马:"sī mǎ",上官:"shàng guān",欧阳:"ōu yáng",夏侯:"xià hóu",诸葛:"zhū gě",闻人:"wén rén",东方:"dōng fāng",赫连:"hè lián",皇甫:"huáng fǔ",尉迟:"yù chí",公羊:"gōng yáng",澹台:"tán tái",公冶:"gōng yě",宗政:"zōng zhèng",濮阳:"pú yáng",淳于:"chún yú",太叔:"tài shū",申屠:"shēn tú",公孙:"gōng sūn",仲孙:"zhòng sūn",轩辕:"xuān yuán",令狐:"líng hú",钟离:"zhōng lí",宇文:"yǔ wén",长孙:"zhǎng sūn",慕容:"mù róng",鲜于:"xiān yú",闾丘:"lǘ qiū",司徒:"sī tú",司空:"sī kōng",亓官:"qí guān",司寇:"sī kòu",仉督:"zhǎng dū",子车:"zǐ jū",颛孙:"zhuān sūn",端木:"duān mù",巫马:"wū mǎ",公西:"gōng xī",漆雕:"qī diāo",乐正:"yuè zhèng",壤驷:"rǎng sì",公良:"gōng liáng",拓跋:"tuò bá",夹谷:"jiá gǔ",宰父:"zǎi fǔ",榖梁:"gǔ liáng",段干:"duàn gān",百里:"bǎi lǐ",东郭:"dōng guō",南门:"nán mén",呼延:"hū yán",羊舌:"yáng shé",梁丘:"liáng qiū",左丘:"zuǒ qiū",东门:"dōng mén",西门:"xī mén",句龙:"gōu lóng",毌丘:"guàn qiū",赵:"zhào",钱:"qián",孙:"sūn",李:"lǐ",周:"zhōu",吴:"wú",郑:"zhèng",王:"wáng",冯:"féng",陈:"chén",褚:"chǔ",卫:"wèi",蒋:"jiǎng",沈:"shěn",韩:"hán",杨:"yáng",朱:"zhū",秦:"qín",尤:"yóu",许:"xǔ",何:"hé",吕:"lǚ",施:"shī",张:"zhāng",孔:"kǒng",曹:"cáo",严:"yán",华:"huà",金:"jīn",魏:"wèi",陶:"táo",姜:"jiāng",戚:"qī",谢:"xiè",邹:"zōu",喻:"yù",柏:"bǎi",水:"shuǐ",窦:"dòu",章:"zhāng",云:"yún",苏:"sū",潘:"pān",葛:"gě",奚:"xī",范:"fàn",彭:"péng",郎:"láng",鲁:"lǔ",韦:"wéi",昌:"chāng",马:"mǎ",苗:"miáo",凤:"fèng",花:"huā",方:"fāng",俞:"yú",任:"rén",袁:"yuán",柳:"liǔ",酆:"fēng",鲍:"bào",史:"shǐ",唐:"táng",费:"fèi",廉:"lián",岑:"cén",薛:"xuē",雷:"léi",贺:"hè",倪:"ní",汤:"tāng",滕:"téng",殷:"yīn",罗:"luó",毕:"bì",郝:"hǎo",邬:"wū",安:"ān",常:"cháng",乐:"yuè",于:"yú",时:"shí",傅:"fù",皮:"pí",卞:"biàn",齐:"qí",康:"kāng",伍:"wǔ",余:"yú",元:"yuán",卜:"bǔ",顾:"gù",孟:"mèng",平:"píng",黄:"huáng",和:"hé",穆:"mù",萧:"xiāo",尹:"yǐn",姚:"yáo",邵:"shào",湛:"zhàn",汪:"wāng",祁:"qí",毛:"máo",禹:"yǔ",狄:"dí",米:"mǐ",贝:"bèi",明:"míng",臧:"zāng",计:"jì",伏:"fú",成:"chéng",戴:"dài",谈:"tán",宋:"sòng",茅:"máo",庞:"páng",熊:"xióng",纪:"jǐ",舒:"shū",屈:"qū",项:"xiàng",祝:"zhù",董:"dǒng",梁:"liáng",杜:"dù",阮:"ruǎn",蓝:"lán",闵:"mǐn",席:"xí",季:"jì",麻:"má",强:"qiáng",贾:"jiǎ",路:"lù",娄:"lóu",危:"wēi",江:"jiāng",童:"tóng",颜:"yán",郭:"guō",梅:"méi",盛:"shèng",林:"lín",刁:"diāo",钟:"zhōng",徐:"xú",邱:"qiū",骆:"luò",高:"gāo",夏:"xià",蔡:"cài",田:"tián",樊:"fán",胡:"hú",凌:"líng",霍:"huò",虞:"yú",万:"wàn",支:"zhī",柯:"kē",昝:"zǎn",管:"guǎn",卢:"lú",莫:"mò",经:"jīng",房:"fáng",裘:"qiú",缪:"miào",干:"gān",解:"xiè",应:"yīng",宗:"zōng",丁:"dīng",宣:"xuān",贲:"bēn",邓:"dèng",郁:"yù",单:"shàn",杭:"háng",洪:"hóng",包:"bāo",诸:"zhū",左:"zuǒ",石:"shí",崔:"cuī",吉:"jí",钮:"niǔ",龚:"gōng",程:"chéng",嵇:"jī",邢:"xíng",滑:"huá",裴:"péi",陆:"lù",荣:"róng",翁:"wēng",荀:"xún",羊:"yáng",於:"yū",惠:"huì",甄:"zhēn",曲:"qū",家:"jiā",封:"fēng",芮:"ruì",羿:"yì",储:"chǔ",靳:"jìn",汲:"jí",邴:"bǐng",糜:"mí",松:"sōng",井:"jǐng",段:"duàn",富:"fù",巫:"wū",乌:"wū",焦:"jiāo",巴:"bā",弓:"gōng",牧:"mù",隗:"wěi",山:"shān",谷:"gǔ",车:"chē",侯:"hóu",宓:"mì",蓬:"péng",全:"quán",郗:"xī",班:"bān",仰:"yǎng",秋:"qiū",仲:"zhòng",伊:"yī",宫:"gōng",宁:"nìng",仇:"qiú",栾:"luán",暴:"bào",甘:"gān",钭:"tǒu",厉:"lì",戎:"róng",祖:"zǔ",武:"wǔ",符:"fú",刘:"liú",景:"jǐng",詹:"zhān",束:"shù",龙:"lóng",叶:"yè",幸:"xìng",司:"sī",韶:"sháo",郜:"gào",黎:"lí",蓟:"jì",薄:"bó",印:"yìn",宿:"sù",白:"bái",怀:"huái",蒲:"pú",邰:"tái",从:"cóng",鄂:"è",索:"suǒ",咸:"xián",籍:"jí",赖:"lài",卓:"zhuó",蔺:"lìn",屠:"tú",蒙:"méng",池:"chí",乔:"qiáo",阴:"yīn",鬱:"yù",胥:"xū",能:"nài",苍:"cāng",双:"shuāng",闻:"wén",莘:"shēn",党:"dǎng",翟:"zhái",谭:"tán",贡:"gòng",劳:"láo",逄:"páng",姬:"jī",申:"shēn",扶:"fú",堵:"dǔ",冉:"rǎn",宰:"zǎi",郦:"lì",雍:"yōng",郤:"xì",璩:"qú",桑:"sāng",桂:"guì",濮:"pú",牛:"niú",寿:"shòu",通:"tōng",边:"biān",扈:"hù",燕:"yān",冀:"jì",郏:"jiá",浦:"pǔ",尚:"shàng",农:"nóng",温:"wēn",别:"bié",庄:"zhuāng",晏:"yàn",柴:"chái",瞿:"qú",阎:"yán",充:"chōng",慕:"mù",连:"lián",茹:"rú",习:"xí",宦:"huàn",艾:"ài",鱼:"yú",容:"róng",向:"xiàng",古:"gǔ",易:"yì",慎:"shèn",戈:"gē",廖:"liào",庾:"yǔ",终:"zhōng",暨:"jì",居:"jū",衡:"héng",步:"bù",都:"dū",耿:"gěng",满:"mǎn",弘:"hóng",匡:"kuāng",国:"guó",文:"wén",寇:"kòu",广:"guǎng",禄:"lù",阙:"quē",东:"dōng",欧:"ōu",殳:"shū",沃:"wò",利:"lì",蔚:"wèi",越:"yuè",夔:"kuí",隆:"lóng",师:"shī",巩:"gǒng",厍:"shè",聂:"niè",晁:"cháo",勾:"gōu",敖:"áo",融:"róng",冷:"lěng",訾:"zī",辛:"xīn",阚:"kàn",那:"nā",简:"jiǎn",饶:"ráo",空:"kōng",曾:"zēng",母:"mǔ",沙:"shā",乜:"niè",养:"yǎng",鞠:"jū",须:"xū",丰:"fēng",巢:"cháo",关:"guān",蒯:"kuǎi",相:"xiàng",查:"zhā",后:"hòu",荆:"jīng",红:"hóng",游:"yóu",竺:"zhú",权:"quán",逯:"lù",盖:"gě",益:"yì",桓:"huán",公:"gōng",牟:"móu",哈:"hǎ",言:"yán",福:"fú",肖:"xiāo",区:"ōu",覃:"qín",朴:"piáo",繁:"pó",员:"yùn",句:"gōu",要:"yāo",过:"guō",钻:"zuān",谌:"chén",折:"shé",召:"shào",郄:"qiè",撒:"sǎ",甯:"nìng",六:"lù",啜:"chuài",行:"xíng"},kue=Object.keys(i8).map(e=>({zh:e,pinyin:i8[e],probability:1+ta(e),length:ta(e),priority:yl.Surname,dict:Symbol("surname")})),YS={"bǎng páng pāng":["膀"],líng:["〇","伶","凌","刢","囹","坽","夌","姈","婈","孁","岺","彾","掕","昤","朎","柃","棂","櫺","欞","泠","淩","澪","灵","燯","爧","狑","玲","琌","瓴","皊","砱","祾","秢","竛","笭","紷","綾","绫","羐","羚","翎","聆","舲","苓","菱","蓤","蔆","蕶","蛉","衑","裬","詅","跉","軨","輘","酃","醽","鈴","錂","铃","閝","陵","零","霊","霗","霛","霝","靈","駖","魿","鯪","鲮","鴒","鸰","鹷","麢","齡","齢","龄","龗","㥄"],yī:["一","乊","伊","依","医","吚","咿","噫","壱","壹","夁","嫛","嬄","弌","揖","撎","檹","毉","洢","渏","漪","瑿","畩","祎","禕","稦","繄","蛜","衤","譩","辷","郼","醫","銥","铱","鷖","鹥","黟","黳"],"dīng zhēng":["丁"],"kǎo qiǎo yú":["丂"],qī:["七","倛","僛","凄","嘁","墄","娸","悽","慼","慽","戚","捿","柒","桤","桼","棲","榿","欺","沏","淒","漆","紪","緀","萋","褄","諆","迉","郪","鏚","霋","魌","鶈"],shàng:["丄","尙","尚","恦","緔","绱"],xià:["丅","下","乤","圷","夏","夓","懗","梺","疜","睱","罅","鎼","鏬"],hǎn:["丆","喊","浫","罕","豃","㘎"],"wàn mò":["万"],zhàng:["丈","仗","墇","嶂","帐","帳","幛","扙","杖","涱","痮","瘬","瘴","瞕","粀","胀","脹","賬","账","障"],sān:["三","厁","叁","弎","毵","毶","毿","犙","鬖"],"shàng shǎng shang":["上"],"qí jī":["丌","其","奇"],"bù fǒu":["不"],"yǔ yù yú":["与"],miǎn:["丏","偭","免","冕","勉","勔","喕","娩","愐","汅","沔","湎","睌","緬","缅","腼","葂","靦","鮸","𩾃"],gài:["丐","乢","匃","匄","戤","概","槩","槪","溉","漑","瓂","葢","鈣","钙","𬮿"],chǒu:["丑","丒","侴","吜","杽","瞅","矁","醜","魗"],zhuān:["专","叀","嫥","専","專","瑼","甎","砖","磗","磚","蟤","諯","鄟","顓","颛","鱄","䏝"],"qiě jū":["且"],pī:["丕","伓","伾","噼","坯","岯","憵","批","披","炋","狉","狓","砒","磇","礔","礕","秛","秠","耚","豾","邳","鈚","鉟","銔","錃","錍","霹","駓","髬","魾","𬳵"],shì:["世","丗","亊","事","仕","侍","冟","势","勢","卋","呩","嗜","噬","士","奭","嬕","室","市","式","弑","弒","恀","恃","戺","拭","揓","是","昰","枾","柿","栻","澨","烒","煶","眂","眎","眡","睗","示","礻","筮","簭","舐","舓","襫","視","视","觢","試","誓","諡","謚","试","谥","貰","贳","軾","轼","逝","遾","釈","释","釋","鈰","鉃","鉽","铈","飾","餙","餝","饰","鰘","䏡","𬤊"],qiū:["丘","丠","坵","媝","恘","恷","楸","秋","秌","穐","篍","緧","萩","蘒","蚯","蝵","蟗","蠤","趥","邱","鞦","鞧","鰌","鰍","鳅","鶖","鹙","龝"],bǐng:["丙","屛","怲","抦","昞","昺","柄","棅","炳","禀","秉","稟","苪","蛃","邴","鈵","陃","鞆","餅","餠","饼"],yè:["业","亱","僷","墷","夜","嶪","嶫","抴","捙","擛","擪","擫","晔","曄","曅","曗","曳","曵","枼","枽","業","洂","液","澲","烨","燁","爗","璍","皣","瞱","瞸","礏","腋","葉","謁","谒","邺","鄴","鍱","鐷","靥","靨","頁","页","餣","饁","馌","驜","鵺","鸈"],cóng:["丛","从","叢","婃","孮","従","徔","徖","悰","樷","欉","淙","灇","爜","琮","藂","誴","賨","賩","錝"],dōng:["东","倲","冬","咚","埬","岽","崬","徚","昸","東","氡","氭","涷","笗","苳","菄","蝀","鮗","鯟","鶇","鶫","鸫","鼕","𬟽"],sī:["丝","俬","凘","厮","司","咝","嘶","噝","媤","廝","恖","撕","斯","楒","泀","澌","燍","禗","禠","私","糹","絲","緦","纟","缌","罳","蕬","虒","蛳","蜤","螄","蟖","蟴","鉰","銯","鍶","鐁","锶","颸","飔","騦","鷥","鸶","鼶","㟃"],chéng:["丞","呈","城","埕","堘","塍","塖","宬","峸","惩","懲","成","承","挰","掁","揨","枨","棖","橙","檙","洆","溗","澂","珵","珹","畻","程","窚","筬","絾","脭","荿","誠","诚","郕","酲","鋮","铖","騬","鯎"],diū:["丟","丢","銩","铥"],liǎng:["両","两","兩","唡","啢","掚","緉","脼","蜽","裲","魉","魎","𬜯"],yǒu:["丣","卣","友","梄","湵","牖","禉","羑","聈","苃","莠","蜏","酉","銪","铕","黝"],yán:["严","厳","啱","喦","嚴","塩","壛","壧","妍","姸","娫","娮","岩","嵒","嵓","巌","巖","巗","延","揅","昖","楌","檐","櫩","欕","沿","炎","炏","狿","琂","盐","碞","筵","簷","莚","蔅","虤","蜒","言","訁","訮","詽","讠","郔","閆","閻","闫","阎","顏","顔","颜","鹽","麣","𫄧"],bìng:["並","併","倂","傡","垪","摒","栤","病","窉","竝","誁","靐","鮩"],"sàng sāng":["丧"],gǔn:["丨","惃","滚","滾","磙","緄","绲","蓘","蔉","衮","袞","輥","辊","鮌","鯀","鲧"],jiū:["丩","勼","啾","揪","揫","朻","究","糾","纠","萛","赳","阄","鬏","鬮","鳩","鸠"],"gè gě":["个","個","各"],yā:["丫","圧","孲","庘","押","枒","桠","椏","錏","鐚","鴉","鴨","鵶","鸦","鸭"],pán:["丬","媻","幋","槃","洀","瀊","爿","盘","盤","磐","縏","蒰","蟠","蹒","蹣","鎜","鞶"],"zhōng zhòng":["中"],jǐ:["丮","妀","己","戟","挤","掎","撠","擠","橶","泲","犱","脊","虮","蟣","魢","鱾","麂"],jiè:["丯","介","借","唶","堺","屆","届","岕","庎","徣","戒","楐","犗","玠","琾","界","畍","疥","砎","蚧","蛶","衸","褯","誡","诫","鎅","骱","魪"],fēng:["丰","仹","偑","僼","凨","凬","凮","妦","寷","封","峯","峰","崶","枫","楓","檒","沣","沨","渢","灃","烽","犎","猦","琒","疯","瘋","盽","砜","碸","篈","蘴","蜂","蠭","豐","鄷","酆","鋒","鎽","鏠","锋","霻","靊","飌","麷"],"guàn kuàng":["丱"],chuàn:["串","汌","玔","賗","釧","钏"],chǎn:["丳","产","冁","剷","囅","嵼","旵","浐","滻","灛","產","産","簅","蒇","蕆","諂","譂","讇","谄","鏟","铲","閳","闡","阐","骣","𬊤"],lín:["临","冧","壣","崊","嶙","斴","晽","暽","林","潾","瀶","燐","琳","璘","瞵","碄","磷","粦","粼","繗","翷","臨","轔","辚","遴","邻","鄰","鏻","阾","隣","霖","驎","鱗","鳞","麐","麟","𬴊","𬭸"],zhuó:["丵","劅","卓","啄","圴","妰","娺","撯","擆","擢","斫","斮","斱","斲","斵","晫","椓","浊","浞","濁","灼","烵","琸","硺","禚","窡","籗","籱","罬","茁","蠗","蠿","諁","諑","謶","诼","酌","鐲","镯","鵫","鷟","䓬","𬸦"],zhǔ:["丶","主","劯","嘱","囑","宔","帾","拄","渚","濐","煑","煮","燝","瞩","矚","罜","詝","陼","鸀","麈","𬣞"],bā:["丷","仈","八","叭","哵","夿","岜","巴","捌","朳","玐","疤","笆","粑","羓","芭","蚆","豝","釟"],wán:["丸","刓","完","岏","抏","捖","汍","烷","玩","琓","笂","紈","纨","翫","芄","貦","頑","顽"],dān:["丹","勯","匰","単","妉","媅","殚","殫","甔","眈","砃","箪","簞","耼","耽","聃","聸","褝","襌","躭","郸","鄲","酖","頕"],"wèi wéi":["为"],"jǐng dǎn":["丼"],"lì lí":["丽"],jǔ:["举","弆","挙","擧","椇","榉","榘","櫸","欅","矩","筥","聥","舉","莒","蒟","襷","踽","齟","龃"],piě:["丿","苤","鐅","𬭯"],fú:["乀","伏","俘","凫","刜","匐","咈","哹","垘","孚","岪","巿","帗","幅","幞","弗","彿","怫","扶","柫","栿","桴","氟","泭","浮","涪","澓","炥","玸","甶","畉","癁","祓","福","稪","符","箙","紱","紼","絥","綍","绂","绋","罘","罦","翇","艀","芙","芣","苻","茀","茯","菔","葍","虙","蚨","蜉","蝠","袚","袱","襆","襥","諨","豧","踾","輻","辐","郛","鉘","鉜","韍","韨","颫","髴","鮄","鮲","鳧","鳬","鴔","鵩","黻"],"yí jí":["乁"],yì:["乂","义","亄","亦","亿","伇","伿","佾","俋","億","兿","刈","劓","劮","勚","勩","匇","呓","呭","呹","唈","囈","圛","坄","垼","埸","奕","嫕","嬑","寱","屹","峄","嶧","帟","帠","幆","廙","异","弈","弋","役","忆","怈","怿","悒","意","憶","懌","懿","抑","挹","敡","易","晹","曀","曎","杙","枍","棭","榏","槸","檍","歝","殔","殪","殹","毅","浂","浥","浳","湙","溢","潩","澺","瀷","炈","焲","熠","熤","熼","燚","燡","燱","獈","玴","異","疫","痬","瘗","瘞","瘱","癔","益","瞖","穓","竩","篒","縊","繶","繹","绎","缢","義","羿","翊","翌","翳","翼","耴","肄","肊","膉","臆","艗","艺","芅","苅","萟","蓺","薏","藙","藝","蘙","虉","蜴","螠","衪","袣","裔","裛","褹","襼","訲","訳","詍","詣","誼","譯","議","讛","议","译","诣","谊","豙","豛","豷","貖","贀","跇","轶","逸","邑","鄓","醷","釴","鈠","鎰","鐿","镒","镱","阣","隿","霬","饐","駅","驛","驿","骮","鮨","鶂","鶃","鶍","鷁","鷊","鷧","鷾","鸃","鹝","鹢","黓","齸","𬬩","㑊","𫄷","𬟁"],nǎi:["乃","倷","奶","嬭","廼","氖","疓","艿","迺","釢"],wǔ:["乄","五","仵","伍","侮","倵","儛","午","啎","妩","娬","嫵","庑","廡","忤","怃","憮","摀","武","潕","熓","牾","玝","珷","瑦","甒","碔","舞","躌","迕","逜","陚","鵡","鹉","𣲘"],jiǔ:["久","乆","九","乣","奺","杦","汣","灸","玖","紤","舏","酒","镹","韭","韮"],"tuō zhé":["乇","杔","馲"],"me mó ma yāo":["么"],zhī:["之","倁","卮","巵","搘","支","栀","梔","椥","榰","汁","泜","疷","祗","祬","秓","稙","綕","肢","胑","胝","脂","芝","蘵","蜘","衼","隻","鳷","鴲","鼅","𦭜"],"wū wù":["乌"],zhà:["乍","咤","宱","搾","榨","溠","痄","蚱","詐","诈","醡","霅","䃎"],hū:["乎","乯","匢","匫","呼","唿","嘑","垀","寣","幠","忽","惚","昒","歑","泘","淴","滹","烀","苸","虍","虖","謼","軤","轷","雐"],fá:["乏","伐","傠","坺","垡","墢","姂","栰","浌","瞂","笩","筏","罚","罰","罸","藅","閥","阀"],"lè yuè yào lào":["乐","樂"],yín:["乑","吟","噖","嚚","圁","垠","夤","婬","寅","峾","崟","崯","檭","殥","泿","淫","滛","烎","犾","狺","璌","硍","碒","荶","蔩","訔","訚","訡","誾","鄞","鈝","銀","银","霪","鷣","齦"],pīng:["乒","俜","娉","涄","甹","砯","聠","艵","頩"],pāng:["乓","滂","胮","膖","雱","霶"],qiáo:["乔","侨","僑","嫶","憔","桥","槗","樵","橋","櫵","犞","瞧","硚","礄","荍","荞","蕎","藮","譙","趫","鐈","鞒","鞽","顦"],hǔ:["乕","琥","萀","虎","虝","錿","鯱"],guāi:["乖"],"chéng shèng":["乗","乘","娍"],yǐ:["乙","乛","以","倚","偯","嬟","崺","已","庡","扆","攺","敼","旑","旖","檥","矣","礒","笖","舣","艤","苡","苢","蚁","螘","蟻","裿","踦","輢","轙","逘","酏","釔","鈘","鉯","钇","顗","鳦","齮","𫖮","𬺈"],"háo yǐ":["乚"],"niè miē":["乜"],qǐ:["乞","企","启","唘","啓","啔","啟","婍","屺","杞","棨","玘","盀","綺","绮","芑","諬","起","邔","闙"],yě:["也","冶","嘢","埜","壄","漜","野"],xí:["习","喺","媳","嶍","席","椺","檄","漝","習","蓆","袭","襲","覡","觋","謵","趘","郋","鎴","隰","霫","飁","騱","騽","驨","鰼","鳛","𠅤","𫘬"],xiāng:["乡","厢","廂","忀","楿","欀","湘","瓖","稥","箱","緗","缃","膷","芗","萫","葙","薌","襄","郷","鄉","鄊","鄕","鑲","镶","香","驤","骧","鱜","麘","𬙋"],shū:["书","倏","倐","儵","叔","姝","尗","抒","掓","摅","攄","書","枢","梳","樞","殊","殳","毹","毺","淑","瀭","焂","疎","疏","紓","綀","纾","舒","菽","蔬","踈","軗","輸","输","鄃","陎","鮛","鵨"],dǒu:["乧","抖","枓","蚪","鈄","阧","陡"],shǐ:["乨","使","兘","史","始","宩","屎","榁","矢","笶","豕","鉂","駛","驶"],jī:["乩","僟","击","刉","刏","剞","叽","唧","喞","嗘","嘰","圾","基","墼","姬","屐","嵆","嵇","撃","擊","朞","机","枅","樭","機","毄","激","犄","玑","璣","畸","畿","癪","矶","磯","积","積","笄","筓","箕","簊","緁","羁","羇","羈","耭","肌","芨","虀","覉","覊","譏","譤","讥","賫","賷","赍","跻","踑","躋","躸","銈","錤","鐖","鑇","鑙","隮","雞","鞿","韲","飢","饑","饥","魕","鳮","鶏","鶺","鷄","鸄","鸡","齎","齏","齑","𬯀","𫓯","𫓹","𫌀"],náng:["乪","嚢","欜","蠰","饢"],jiā:["乫","佳","傢","加","嘉","抸","枷","梜","毠","泇","浃","浹","犌","猳","珈","痂","笳","糘","耞","腵","葭","袈","豭","貑","跏","迦","鉫","鎵","镓","鴐","麚","𬂩"],jù:["乬","倨","倶","具","剧","劇","勮","埧","埾","壉","姖","屦","屨","岠","巨","巪","怇","惧","愳","懅","懼","拒","拠","昛","歫","洰","澽","炬","烥","犋","秬","窭","窶","簴","粔","耟","聚","虡","蚷","詎","讵","豦","距","踞","躆","遽","邭","醵","鉅","鐻","钜","颶","飓","駏","鮔"],shí:["乭","十","埘","塒","姼","实","実","寔","實","峕","嵵","时","旹","時","榯","湜","溡","炻","祏","竍","蚀","蝕","辻","遈","鉐","飠","饣","鮖","鰣","鲥","鼫","鼭"],mǎo:["乮","冇","卯","峁","戼","昴","泖","笷","蓩","鉚","铆"],mǎi:["买","嘪","荬","蕒","買","鷶"],luàn:["乱","亂","釠"],rǔ:["乳","擩","汝","肗","辱","鄏"],xué:["乴","学","學","峃","嶨","斈","泶","澩","燢","穴","茓","袕","踅","鷽","鸴"],yǎn:["䶮","乵","俨","偃","儼","兖","兗","厣","厴","噞","孍","嵃","巘","巚","弇","愝","戭","扊","抁","掩","揜","曮","椼","檿","沇","渷","演","琰","甗","眼","罨","萒","蝘","衍","褗","躽","遃","郾","隒","顩","魇","魘","鰋","鶠","黡","黤","黬","黭","黶","鼴","鼹","齴","龑","𬸘","𬙂","𪩘"],fǔ:["乶","俌","俛","俯","府","弣","抚","拊","撫","斧","椨","滏","焤","甫","盙","簠","腐","腑","蜅","輔","辅","郙","釜","釡","阝","頫","鬴","黼","㕮","𫖯"],shā:["乷","唦","杀","桬","殺","毮","猀","痧","砂","硰","紗","繺","纱","蔱","裟","鎩","铩","閷","髿","魦","鯊","鯋","鲨"],nǎ:["乸","雫"],qián:["乹","亁","仱","偂","前","墘","媊","岒","拑","掮","榩","橬","歬","潛","潜","濳","灊","箝","葥","虔","軡","鈐","鉗","銭","錢","鎆","钤","钱","钳","靬","騚","騝","鰬","黔","黚"],suǒ:["乺","唢","嗩","所","暛","溑","溹","琐","琑","瑣","索","褨","鎖","鎻","鏁","锁"],yú:["乻","于","亐","伃","余","堣","堬","妤","娛","娯","娱","嬩","崳","嵎","嵛","愚","扵","揄","旟","楡","楰","榆","欤","歈","歟","歶","渔","渝","湡","漁","澞","牏","狳","玗","玙","瑜","璵","盂","睮","窬","竽","籅","羭","腴","臾","舁","舆","艅","茰","萮","萸","蕍","蘛","虞","虶","蝓","螸","衧","褕","覦","觎","諛","謣","谀","踰","輿","轝","逾","邘","酑","鍝","隅","雓","雩","餘","馀","騟","骬","髃","魚","魣","鮽","鯲","鰅","鱼","鷠","鸆","齵"],zhù:["乼","伫","佇","住","坾","墸","壴","嵀","拀","杼","柱","樦","殶","注","炷","疰","眝","祝","祩","竚","筯","箸","篫","簗","紵","紸","纻","羜","翥","苎","莇","蛀","註","貯","贮","跓","軴","鉒","鋳","鑄","铸","馵","駐","驻"],zhě:["乽","者","褶","襵","赭","踷","鍺","锗"],"qián gān":["乾"],"zhì luàn":["乿"],guī:["亀","圭","妫","媯","嫢","嬀","帰","归","摫","椝","槻","槼","櫷","歸","珪","瑰","璝","瓌","皈","瞡","硅","茥","蘬","規","规","邽","郌","閨","闺","騩","鬶","鬹"],"lǐn lìn":["亃"],jué:["亅","决","刔","劂","匷","厥","噊","孒","孓","崛","崫","嶥","彏","憠","憰","戄","抉","挗","掘","攫","桷","橛","橜","欮","氒","決","灍","焳","熦","爑","爴","爵","獗","玃","玦","玨","珏","瑴","瘚","矍","矡","砄","絕","絶","绝","臄","芵","蕝","蕨","虳","蟨","蟩","觖","觮","觼","訣","譎","诀","谲","貜","赽","趉","蹷","躩","鈌","鐍","鐝","钁","镢","鴂","鴃","鷢","𫘝","㵐","𫔎"],"le liǎo":["了"],"gè mā":["亇"],"yǔ yú":["予","懙"],zhēng:["争","佂","凧","姃","媜","峥","崝","崢","征","徰","炡","烝","爭","狰","猙","癥","眐","睁","睜","筝","箏","篜","聇","脀","蒸","踭","鉦","錚","鏳","鬇"],èr:["二","刵","咡","弍","弐","樲","誀","貮","貳","贰","髶"],chù:["亍","傗","儊","怵","憷","搐","斶","歜","珿","琡","矗","竌","絀","绌","臅","触","觸","豖","鄐","閦","黜"],kuī:["亏","刲","岿","巋","盔","窥","窺","聧","虧","闚","顝"],yún:["云","伝","勻","匀","囩","妘","愪","抣","昀","橒","沄","涢","溳","澐","熉","畇","秐","筼","篔","紜","縜","纭","耘","芸","蒷","蕓","郧","鄖","鋆","雲"],hù:["互","冱","嗀","嚛","婟","嫭","嫮","岵","帍","弖","怙","戶","户","戸","戽","扈","护","昈","槴","沍","沪","滬","熩","瓠","祜","笏","簄","粐","綔","蔰","護","豰","鄠","鍙","頀","鱯","鳠","鳸","鸌","鹱"],qí:["亓","剘","埼","岐","岓","崎","嵜","愭","掑","斉","斊","旂","旗","棊","棋","檱","櫀","歧","淇","濝","猉","玂","琦","琪","璂","畦","疧","碁","碕","祁","祈","祺","禥","竒","簯","簱","籏","粸","綥","綦","肵","脐","臍","艩","芪","萁","萕","蕲","藄","蘄","蚑","蚚","蛴","蜝","蜞","螧","蠐","褀","軝","鄿","釮","錡","锜","陭","頎","颀","騎","騏","騹","骐","骑","鬐","鬿","鯕","鰭","鲯","鳍","鵸","鶀","麒","麡","𨙸","𬨂","䓫"],jǐng:["井","儆","刭","剄","坓","宑","幜","憬","暻","殌","汫","汬","澋","璄","璟","璥","穽","肼","蟼","警","阱","頚","頸"],sì:["亖","佀","価","儩","兕","嗣","四","姒","娰","孠","寺","巳","柶","榹","汜","泗","泤","洍","洠","涘","瀃","牭","祀","禩","竢","笥","耜","肂","肆","蕼","覗","貄","釲","鈶","鈻","飤","飼","饲","駟","騃","驷"],suì:["亗","嬘","岁","嵗","旞","檖","歲","歳","澻","煫","燧","璲","砕","碎","祟","禭","穂","穗","穟","繀","繐","繸","襚","誶","譢","谇","賥","邃","鐆","鐩","隧","韢","𫟦","𬭼"],gèn:["亘","亙","揯","搄","茛"],yà:["亚","亜","俹","冴","劜","圔","圠","埡","娅","婭","揠","氩","氬","犽","砑","稏","聐","襾","覀","訝","讶","迓","齾"],"xiē suò":["些"],"qí zhāi":["亝","齊"],"yā yà":["亞","压","垭","壓","铔"],"jí qì":["亟","焏"],tóu:["亠","投","頭","骰"],"wáng wú":["亡"],"kàng háng gāng":["亢"],dà:["亣","眔"],jiāo:["交","僬","娇","嬌","峧","嶕","嶣","憍","椒","浇","澆","焦","礁","穚","簥","胶","膠","膲","茭","茮","蕉","虠","蛟","蟭","跤","轇","郊","鐎","驕","骄","鮫","鲛","鵁","鷦","鷮","鹪","䴔"],hài:["亥","嗐","害","氦","餀","饚","駭","駴","骇"],"hēng pēng":["亨"],mǔ:["亩","姆","峔","拇","母","牡","牳","畂","畆","畒","畝","畞","畮","砪","胟","踇","鉧","𬭁","𧿹"],ye:["亪"],xiǎng:["享","亯","响","想","晑","蚃","蠁","響","飨","餉","饗","饷","鮝","鯗","鱶","鲞"],jīng:["京","亰","兢","坕","坙","婛","惊","旌","旍","晶","橸","泾","涇","猄","睛","秔","稉","粳","精","経","經","綡","聙","腈","茎","荆","荊","菁","葏","驚","鯨","鲸","鶁","鶄","麖","麠","鼱","䴖"],tíng:["亭","停","婷","嵉","庭","廷","楟","榳","筳","聤","莛","葶","蜓","蝏","諪","邒","霆","鼮","䗴"],liàng:["亮","喨","悢","晾","湸","諒","谅","輌","輛","辆","鍄"],"qīn qìng":["亲","親"],bó:["亳","仢","侼","僰","博","帛","愽","懪","挬","搏","欂","浡","淿","渤","煿","牔","狛","瓝","礴","秡","箔","簙","糪","胉","脖","膊","舶","艊","萡","葧","袯","襏","襮","謈","踣","郣","鈸","鉑","鋍","鎛","鑮","钹","铂","镈","餺","馎","馛","馞","駁","駮","驳","髆","鵓","鹁"],yòu:["亴","佑","佦","侑","又","右","哊","唀","囿","姷","宥","峟","幼","狖","祐","蚴","誘","诱","貁","迶","酭","釉","鼬"],xiè:["亵","伳","偞","偰","僁","卨","卸","噧","塮","夑","媟","屑","屧","廨","徢","懈","暬","械","榍","榭","泻","洩","渫","澥","瀉","瀣","灺","炧","炨","燮","爕","獬","祄","禼","糏","紲","絏","絬","繲","纈","绁","缷","薢","薤","蟹","蠏","褉","褻","謝","谢","躞","邂","靾","韰","齂","齘","齛","齥","𬹼","𤫉"],"dǎn dàn":["亶","馾"],lián:["亷","劆","匲","匳","嗹","噒","奁","奩","嫾","帘","廉","怜","憐","涟","漣","濂","濓","瀮","熑","燫","簾","籢","籨","縺","翴","联","聨","聫","聮","聯","臁","莲","蓮","薕","螊","蠊","裢","褳","覝","謰","蹥","连","連","鎌","鐮","镰","鬑","鰱","鲢"],duǒ:["亸","哚","嚲","埵","崜","朵","朶","綞","缍","趓","躱","躲","軃"],"wěi mén":["亹","斖"],rén:["人","亻","仁","壬","忈","忎","朲","秂","芢","魜","鵀"],jí:["亼","亽","伋","佶","偮","卙","即","卽","及","叝","吉","堲","塉","姞","嫉","岌","嵴","嶯","彶","忣","急","愱","戢","揤","极","棘","楫","極","槉","檝","殛","汲","湒","潗","疾","瘠","皍","笈","箿","籍","級","级","膌","艥","蒺","蕀","蕺","蝍","螏","襋","觙","谻","踖","蹐","躤","輯","轚","辑","郆","銡","鍓","鏶","集","雧","霵","鹡","㴔"],wáng:["亾","仼","兦","莣","蚟"],"shén shí":["什"],lè:["仂","叻","忇","氻","泐","玏","砳","簕","艻","阞","韷","餎","鰳","鱳","鳓"],dīng:["仃","叮","帄","玎","疔","盯","耵","虰","靪"],zè:["仄","崱","庂","捑","昃","昗","汄"],"jǐn jìn":["仅","僅","嫤"],"pú pū":["仆"],"chóu qiú":["仇"],zhǎng:["仉","幥","掌","礃"],jīn:["今","堻","巾","惍","斤","津","珒","琻","璡","砛","筋","荕","衿","襟","觔","金","釒","釿","钅","鹶","黅","𬬱"],bīng:["仌","仒","兵","冫","冰","掤","氷","鋲"],réng:["仍","礽","芿","辸","陾"],fó:["仏","坲","梻"],"jīn sǎn":["仐"],lún:["仑","伦","侖","倫","囵","圇","婨","崘","崙","棆","沦","淪","磮","腀","菕","蜦","踚","輪","轮","錀","陯","鯩","𬬭"],cāng:["仓","仺","倉","凔","嵢","沧","滄","濸","獊","舱","艙","苍","蒼","螥","鸧"],"zǎi zǐ zī":["仔"],tā:["他","塌","它","榙","溻","牠","祂","褟","趿","遢","闧"],fù:["付","偩","傅","冨","副","咐","坿","复","妇","婦","媍","嬔","富","復","椱","祔","禣","竎","緮","縛","缚","腹","萯","蕧","蚹","蛗","蝜","蝮","袝","複","覄","覆","訃","詂","讣","負","賦","賻","负","赋","赙","赴","輹","鍑","鍢","阜","附","馥","駙","驸","鮒","鰒","鲋","鳆","㳇"],xiān:["仙","仚","佡","僊","僲","先","嘕","奾","屳","廯","忺","憸","掀","暹","杴","氙","珗","祆","秈","籼","繊","纎","纖","苮","褼","襳","跹","蹮","躚","酰","鍁","锨","韯","韱","馦","鱻","鶱","𬸣"],"tuō chà duó":["仛"],hóng:["仜","吰","垬","妅","娂","宏","宖","弘","彋","汯","泓","洪","浤","渱","潂","玒","玜","竑","竤","篊","粠","紘","紭","綋","纮","翃","翝","耾","苰","荭","葒","葓","谹","谼","鈜","鉷","鋐","閎","闳","霐","霟","鞃","魟","鴻","鸿","黉","黌","𫟹","𬭎"],tóng:["仝","佟","哃","峂","峝","庝","彤","晍","曈","桐","氃","浵","潼","犝","獞","眮","瞳","砼","秱","童","粡","膧","茼","蚒","詷","赨","酮","鉖","鉵","銅","铜","餇","鮦","鲖","𫍣","𦒍"],rèn:["仞","仭","刃","刄","妊","姙","屻","岃","扨","牣","祍","紉","紝","絍","纫","纴","肕","腍","衽","袵","訒","認","认","讱","軔","轫","鈓","靭","靱","韌","韧","飪","餁","饪"],qiān:["仟","佥","僉","千","圲","奷","孯","岍","悭","愆","慳","扦","拪","搴","撁","攐","攑","攓","杄","櫏","汘","汧","牵","牽","竏","签","簽","籖","籤","粁","芊","茾","蚈","褰","諐","謙","谦","谸","迁","遷","釺","鈆","鉛","鏲","钎","阡","韆","顅","騫","骞","鬜","鬝","鵮","鹐"],"gǎn hàn":["仠"],"yì gē":["仡"],dài:["代","侢","叇","垈","埭","岱","帒","带","帯","帶","廗","怠","戴","曃","柋","殆","瀻","玳","瑇","甙","簤","紿","緿","绐","艜","蝳","袋","襶","貣","贷","蹛","軑","軚","軩","轪","迨","霴","靆","鴏","黛","黱"],"lìng líng lǐng":["令"],chào:["仦","耖","觘"],"cháng zhǎng":["仧","兏","長","长"],sā:["仨"],cháng:["仩","偿","償","嘗","嚐","嫦","尝","常","徜","瑺","瓺","甞","肠","腸","膓","苌","萇","镸","鱨","鲿"],yí:["仪","侇","儀","冝","匜","咦","圯","夷","姨","宐","宜","宧","寲","峓","嶬","嶷","巸","彛","彜","彝","彞","怡","恞","扅","暆","栘","椬","椸","沂","洟","熪","瓵","痍","移","簃","籎","羠","胰","萓","蛦","螔","觺","謻","貽","贻","跠","迻","遺","鏔","頉","頤","頥","顊","颐","饴","鮧","鴺"],mù:["仫","凩","募","墓","幕","幙","慔","慕","暮","暯","木","楘","毣","沐","炑","牧","狇","目","睦","穆","艒","苜","莯","蚞","鉬","钼","雮","霂"],"men mén":["们"],fǎn:["仮","反","橎","返"],"chào miǎo":["仯"],"yǎng áng":["仰"],zhòng:["仲","众","堹","妕","媑","狆","眾","祌","筗","茽","蚛","衆","衶","諥"],"pǐ pí":["仳"],wò:["仴","偓","卧","媉","幄","握","楃","沃","渥","濣","瓁","瞃","硪","肟","腛","臥","齷","龌"],jiàn:["件","俴","健","僭","剑","剣","剱","劍","劎","劒","劔","墹","寋","建","徤","擶","旔","楗","毽","洊","涧","澗","牮","珔","瞷","磵","礀","箭","糋","繝","腱","臶","舰","艦","荐","薦","覸","諓","諫","譛","谏","賎","賤","贱","趝","践","踐","踺","轞","鉴","鍳","鍵","鐱","鑑","鑒","鑬","鑳","键","間","餞","饯","𬣡"],"jià jiè jie":["价"],"yǎo fó":["仸"],"rèn rén":["任"],"fèn bīn":["份"],dī:["仾","低","啲","埞","堤","岻","彽","樀","滴","磾","秪","羝","袛","趆","隄","鞮","䃅"],fǎng:["仿","倣","旊","昉","昘","瓬","眆","紡","纺","舫","訪","访","髣","鶭"],zhōng:["伀","刣","妐","幒","彸","忠","柊","汷","泈","炂","盅","籦","終","终","舯","蔠","蜙","螤","螽","衳","衷","蹱","鈡","鍾","鐘","钟","锺","鴤","鼨"],pèi:["伂","佩","姵","帔","斾","旆","沛","浿","珮","蓜","轡","辔","配","霈","馷"],diào:["伄","吊","弔","掉","瘹","盄","窎","窵","竨","訋","釣","鈟","銱","鋽","鑃","钓","铞","雿","魡"],dùn:["伅","潡","炖","燉","盾","砘","碷","踲","逇","遁","遯","鈍","钝"],wěn:["伆","刎","吻","呅","抆","桽","稳","穏","穩","紊","肳","脗"],xǐn:["伈"],kàng:["伉","匟","囥","抗","炕","鈧","钪"],ài:["伌","僾","塧","壒","嫒","嬡","愛","懓","暧","曖","爱","瑷","璦","皧","瞹","砹","硋","碍","礙","薆","譺","賹","鑀","隘","靉","餲","馤","鱫","鴱"],"jì qí":["伎","薺"],"xiū xǔ":["休"],"jìn yín":["伒"],dǎn:["伔","刐","撢","玬","瓭","紞","胆","膽","衴","賧","赕","黕","𬘘"],fū:["伕","呋","娐","孵","尃","怤","懯","敷","旉","玞","砆","稃","筟","糐","綒","肤","膚","荂","荴","衭","趺","跗","邞","鄜","酜","鈇","麩","麬","麱","麸","𫓧"],tǎng:["伖","傥","儻","埫","戃","曭","爣","矘","躺","鎲","钂","镋"],yōu:["优","優","呦","嚘","峳","幽","忧","悠","憂","攸","櫌","滺","瀀","纋","羪","耰","逌","鄾","麀"],huǒ:["伙","夥","火","煷","邩","鈥","钬"],"huì kuài":["会","會","浍","璯"],yǔ:["伛","俁","俣","偊","傴","匬","噳","圄","圉","宇","寙","屿","嶼","庾","挧","敔","斞","楀","瑀","瘐","祤","禹","穥","窳","羽","與","萭","貐","鄅","頨","麌","齬","龉","㺄"],cuì:["伜","啛","忰","悴","毳","淬","焠","疩","瘁","竁","粋","粹","紣","綷","翆","翠","脃","脆","脺","膬","膵","臎","萃","襊","顇"],sǎn:["伞","傘","糤","繖","饊","馓"],wěi:["伟","伪","偉","偽","僞","儰","娓","寪","屗","崣","嶉","徫","愇","捤","暐","梶","洧","浘","渨","炜","煒","猥","玮","瑋","痿","緯","纬","腲","艉","芛","苇","荱","萎","葦","蒍","蔿","蜼","諉","诿","踓","鍡","韑","韙","韡","韪","頠","颹","骩","骪","骫","鮪","鲔","𫇭","𬀩","𬱟"],"chuán zhuàn":["传","傳"],"chē jū":["伡","俥","车"],"jū chē":["車"],yá:["伢","厑","厓","堐","岈","崕","崖","涯","漄","牙","玡","琊","睚","笌","芽","蚜","衙","齖"],qiàn:["伣","俔","倩","儙","刋","壍","嬱","悓","棈","椠","槧","欠","歉","皘","篏","篟","縴","芡","蒨","蔳","輤","𬘬"],shāng:["伤","傷","商","墒","慯","殇","殤","滳","漡","熵","蔏","螪","觞","觴","謪","鬺"],chāng:["伥","倀","娼","昌","椙","淐","猖","琩","菖","裮","錩","锠","閶","阊","鯧","鲳","鼚"],"chen cāng":["伧"],xùn:["伨","侚","卂","噀","巺","巽","徇","愻","殉","殾","汛","潠","狥","蕈","訊","訓","訙","训","讯","迅","迿","逊","遜","鑂","顨","馴","驯"],xìn:["伩","囟","孞","脪","舋","衅","訫","釁","阠","顖"],chǐ:["伬","侈","卶","叺","呎","垑","恥","歯","耻","肔","胣","蚇","裭","褫","豉","鉹","齒","齿"],"xián xuán":["伭"],"nú nǔ":["伮"],"bó bǎi":["伯"],"gū gù":["估"],nǐ:["伱","你","儞","孴","拟","擬","旎","晲","狔","苨","薿","隬"],"nì ní":["伲"],bàn:["伴","办","半","姅","怑","扮","瓣","秚","絆","绊","辦","鉡","靽"],xù:["伵","侐","勖","勗","卹","叙","垿","壻","婿","序","恤","敍","敘","旭","昫","朂","槒","欰","殈","汿","沀","洫","溆","漵","潊","烅","烼","煦","獝","珬","盢","瞁","稸","絮","続","緒","緖","續","绪","续","聓","聟","蓄","藚","訹","賉","酗","頊","鱮","㳚"],zhòu:["伷","僽","冑","呪","咒","咮","宙","昼","晝","甃","皱","皺","籀","籒","籕","粙","紂","縐","纣","绉","胄","荮","葤","詋","酎","駎","驟","骤","㤘","㑇"],shēn:["伸","侁","兟","呻","堔","妽","娠","屾","峷","扟","敒","曑","柛","氠","深","燊","珅","甡","甧","申","眒","砷","穼","籶","籸","糂","紳","绅","罙","罧","葠","蓡","蔘","薓","裑","訷","詵","诜","身","駪","鯓","鯵","鰺","鲹","鵢","𬳽"],qū:["伹","佉","匤","呿","坥","屈","岖","岴","嶇","憈","抾","敺","浀","煀","祛","筁","粬","胠","蛆","蛐","袪","覻","詘","诎","趍","躯","軀","阹","駆","駈","驅","驱","髷","魼","鰸","鱋","鶌","麯","麴","麹","黢","㭕","𪨰","䓛"],"sì cì":["伺"],bēng:["伻","嘣","奟","崩","嵭","閍"],"sì shì":["似"],"jiā qié gā":["伽"],"yǐ chì":["佁"],"diàn tián":["佃","钿"],"hān gàn":["佄"],mài:["佅","劢","勱","卖","唛","売","脈","衇","賣","迈","邁","霡","霢","麥","麦","鿏"],dàn:["但","僤","啖","啗","啿","噉","嚪","帎","憺","旦","柦","氮","沊","泹","淡","狚","疍","癚","禫","窞","腅","萏","蓞","蛋","蜑","觛","訑","誕","诞","贉","霮","餤","饏","駳","髧","鴠","𫢸"],bù:["佈","勏","吥","咘","埗","埠","布","廍","怖","悑","步","歨","歩","瓿","篰","荹","蔀","踄","部","郶","鈈","钚","餢"],bǐ:["佊","俾","匕","夶","妣","彼","朼","柀","比","毞","沘","疕","秕","笔","筆","粃","聛","舭","貏","鄙"],"zhāo shào":["佋"],cǐ:["佌","此","泚","皉","𫚖"],wèi:["位","卫","味","喂","墛","媦","慰","懀","未","渭","煟","熭","犚","猬","畏","緭","罻","胃","苿","菋","藯","蘶","蝟","螱","衛","衞","褽","謂","讆","讏","谓","躗","躛","軎","轊","鏏","霨","餧","餵","饖","魏","鮇","鳚"],zuǒ:["佐","左","繓"],yǎng:["佒","傟","养","坱","岟","慃","懩","攁","氧","氱","炴","痒","癢","礢","紻","蝆","軮","養","駚"],"tǐ tī":["体","體"],zhàn:["佔","偡","嶘","战","戦","戰","栈","桟","棧","湛","站","綻","绽","菚","蘸","虥","虦","譧","轏","驏"],"hé hē hè":["何"],bì:["佖","咇","哔","嗶","坒","堛","壁","奰","妼","婢","嬖","币","幣","幤","庇","庳","廦","弊","弻","弼","彃","必","怭","愊","愎","敝","斃","梐","毕","毖","毙","湢","滗","滭","潷","煏","熚","狴","獘","獙","珌","璧","畀","畢","疪","痹","痺","皕","睤","碧","筚","箅","箆","篦","篳","粊","綼","縪","繴","罼","腷","苾","荜","萆","萞","蓖","蓽","蔽","薜","蜌","袐","襅","襞","襣","觱","詖","诐","貱","贔","赑","跸","蹕","躃","躄","避","邲","鄨","鄪","鉍","鏎","鐴","铋","閇","閉","閟","闭","陛","韠","飶","饆","馝","駜","驆","髀","魓","鮅","鷝","鷩","鼊"],tuó:["佗","坨","堶","岮","槖","橐","沱","砣","砤","碢","紽","詑","跎","酡","阤","陀","陁","駝","駞","騨","驒","驝","驼","鮀","鴕","鸵","鼉","鼍","鼧","𬶍"],shé:["佘","舌","虵","蛥"],"yì dié":["佚","昳","泆","軼"],"fó fú bì bó":["佛"],"zuò zuō":["作"],gōu:["佝","沟","溝","痀","篝","簼","緱","缑","袧","褠","鈎","鉤","钩","鞲","韝"],nìng:["佞","侫","倿","寕","泞","澝","濘"],qú:["佢","劬","戵","斪","欋","欔","氍","淭","灈","爠","璖","璩","癯","磲","籧","絇","胊","臞","菃","葋","蕖","蘧","蟝","蠷","蠼","衐","衢","躣","軥","鑺","鴝","鸜","鸲","鼩"],"yōng yòng":["佣"],wǎ:["佤","咓","砙","邷"],kǎ:["佧","垰","胩","裃","鉲"],bāo:["佨","勹","包","孢","煲","笣","胞","苞","蕔","裦","褒","襃","闁","齙","龅"],"huái huí":["佪"],"gé hè":["佫"],lǎo:["佬","咾","恅","栳","狫","珯","硓","老","耂","荖","蛯","轑","銠","铑","鮱"],xiáng:["佭","庠","栙","祥","絴","翔","詳","跭"],gé:["佮","匌","呄","嗝","塥","愅","挌","搿","槅","櫊","滆","膈","臵","茖","觡","諽","輵","轕","閣","阁","隔","鞷","韐","韚","騔","骼","鮯"],yáng:["佯","劷","垟","崸","徉","扬","揚","敭","旸","昜","暘","杨","楊","洋","炀","珜","疡","瘍","眻","蛘","諹","輰","鍚","钖","阦","阳","陽","霷","颺","飏","鰑","鴹","鸉"],bǎi:["佰","捭","摆","擺","栢","百","竡","粨","襬"],fǎ:["佱","峜","法","灋","砝","鍅"],mǐng:["佲","凕","姳","慏","酩"],"èr nài":["佴"],hěn:["佷","很","狠","詪","𬣳"],huó:["佸","活"],guǐ:["佹","匦","匭","厬","垝","姽","宄","庋","庪","恑","晷","湀","癸","祪","簋","蛫","蟡","觤","詭","诡","軌","轨","陒","鬼"],quán:["佺","全","啳","埢","姾","峑","巏","拳","搼","权","楾","権","權","泉","洤","湶","牷","犈","瑔","痊","硂","筌","縓","荃","葲","蜷","蠸","觠","詮","诠","跧","踡","輇","辁","醛","銓","铨","闎","顴","颧","駩","騡","鬈","鰁","鳈","齤"],tiāo:["佻","庣","旫","祧","聎"],jiǎo:["佼","儌","孂","挢","搅","撟","撹","攪","敫","敽","敿","晈","暞","曒","灚","燞","狡","璬","皎","皦","絞","纐","绞","腳","臫","蟜","譑","賋","踋","鉸","铰","餃","饺","鱎","龣"],cì:["佽","刾","庛","朿","栨","次","絘","茦","莿","蛓","螆","賜","赐"],xíng:["侀","刑","哘","型","娙","形","洐","硎","蛵","邢","郉","鈃","鉶","銒","钘","铏","陉","陘","餳","𫰛"],tuō:["侂","咃","咜","圫","托","拕","拖","汑","脫","脱","莌","袥","託","讬","飥","饦","魠","鮵"],kǎn:["侃","偘","冚","坎","惂","砍","莰","輡","轗","顑"],zhí:["侄","値","值","埴","執","姪","嬂","戠","执","摭","植","樴","淔","漐","直","禃","絷","縶","聀","职","職","膱","蟙","跖","踯","蹠","躑","軄","釞","馽"],gāi:["侅","垓","姟","峐","晐","畡","祴","荄","該","该","豥","賅","賌","赅","陔"],lái:["來","俫","倈","崃","崍","庲","来","梾","棶","涞","淶","猍","琜","筙","箂","莱","萊","逨","郲","錸","铼","騋","鯠","鶆","麳"],kuǎ:["侉","咵","垮","銙"],gōng:["侊","公","功","匑","匔","塨","宫","宮","工","幊","弓","恭","攻","杛","碽","糼","糿","肱","觥","觵","躬","躳","髸","龔","龚","䢼"],lì:["例","俐","俪","傈","儮","儷","凓","利","力","励","勵","历","厉","厤","厯","厲","叓","吏","呖","唎","唳","嚦","囇","坜","塛","壢","娳","婯","屴","岦","悧","悷","慄","戾","搮","暦","曆","曞","朸","枥","栃","栗","栛","檪","櫔","櫪","欐","歴","歷","沥","沴","涖","溧","濿","瀝","爏","犡","猁","珕","瑮","瓅","瓑","瓥","疬","痢","癧","盭","睙","砅","砺","砾","磿","礪","礫","礰","禲","秝","立","笠","篥","粒","粝","糲","脷","苈","茘","荔","莅","莉","蒚","蒞","藶","蚸","蛎","蛠","蜧","蝷","蠇","蠣","詈","讈","赲","轢","轣","轹","酈","鉝","隶","隷","雳","靂","靋","鬁","鳨","鴗","鷅","麜","𫵷","𬍛"],yīn:["侌","凐","喑","噾","囙","因","垔","堙","姻","婣","愔","慇","栶","氤","洇","溵","濦","瘖","禋","秵","筃","絪","緸","茵","蒑","蔭","裀","諲","銦","铟","闉","阥","阴","陰","陻","隂","霒","霠","鞇","音","韾","駰","骃","齗","𬘡","𬤇","𬮱"],mǐ:["侎","孊","弭","敉","洣","渳","灖","米","粎","羋","脒","芈","葞","蔝","銤"],zhū:["侏","株","槠","橥","櫧","櫫","洙","潴","瀦","猪","珠","硃","秼","絑","茱","蕏","蛛","蝫","蠩","袾","誅","諸","诛","诸","豬","跦","邾","銖","铢","駯","鮢","鯺","鴸","鼄"],ān:["侒","偣","媕","安","峖","庵","桉","氨","盦","盫","腤","菴","萻","葊","蓭","誝","諳","谙","鞌","鞍","韽","馣","鮟","鵪","鶕","鹌","𩽾"],lù:["侓","僇","勎","勠","圥","坴","塶","娽","峍","廘","彔","录","戮","摝","椂","樚","淕","淥","渌","漉","潞","琭","璐","甪","盝","睩","硉","祿","禄","稑","穋","箓","簏","簬","簵","簶","籙","粶","蔍","蕗","虂","螰","賂","赂","趢","路","踛","蹗","輅","轆","辂","辘","逯","醁","錄","録","錴","鏴","陸","騄","騼","鯥","鴼","鵦","鵱","鷺","鹭","鹿","麓","𫘧"],móu:["侔","劺","恈","眸","蛑","謀","谋","踎","鍪","鴾","麰"],ér:["侕","儿","児","兒","峏","栭","洏","粫","而","胹","荋","袻","輀","轜","陑","隭","髵","鮞","鲕","鴯","鸸"],"dòng tǒng tóng":["侗"],chà:["侘","奼","姹","岔","汊","詫","诧"],chì:["侙","傺","勅","勑","叱","啻","彳","恜","慗","憏","懘","抶","敕","斥","杘","湁","灻","炽","烾","熾","痓","痸","瘛","翄","翅","翤","翨","腟","赤","趩","遫","鉓","雴","飭","饬","鶒","鷘"],"gòng gōng":["供","共"],zhōu:["侜","周","喌","州","徟","洲","淍","炿","烐","珘","矪","舟","謅","譸","诌","賙","赒","輈","輖","辀","週","郮","銂","霌","駲","騆","鵃","鸼"],rú:["侞","儒","嚅","如","嬬","孺","帤","曘","桇","渪","濡","筎","茹","蕠","薷","蝡","蠕","袽","襦","邚","醹","銣","铷","顬","颥","鱬","鴑","鴽"],"jiàn cún":["侟"],xiá:["侠","俠","匣","峡","峽","敮","暇","柙","炠","烚","狎","狭","狹","珨","瑕","硖","硤","碬","祫","筪","縖","翈","舝","舺","蕸","赮","轄","辖","遐","鍜","鎋","陜","陿","霞","騢","魻","鶷","黠"],lǚ:["侣","侶","儢","吕","呂","屡","屢","履","挔","捛","旅","梠","焒","祣","稆","穭","絽","縷","缕","膂","膐","褛","褸","郘","鋁","铝"],ta:["侤"],"jiǎo yáo":["侥","僥","徺"],zhēn:["侦","偵","寊","帧","帪","幀","搸","斟","桢","楨","榛","樼","殝","浈","湞","潧","澵","獉","珍","珎","瑧","甄","眞","真","砧","碪","祯","禎","禛","箴","胗","臻","葴","蒖","蓁","薽","貞","贞","轃","遉","酙","針","鉁","錱","鍼","针","鱵"],"cè zè zhāi":["侧","側"],kuài:["侩","儈","凷","哙","噲","圦","块","塊","巜","廥","快","旝","欳","狯","獪","筷","糩","脍","膾","郐","鄶","鱠","鲙"],chái:["侪","儕","喍","柴","犲","祡","豺"],nóng:["侬","儂","农","哝","噥","檂","欁","浓","濃","燶","禯","秾","穠","脓","膿","蕽","襛","譨","農","辳","醲","鬞","𬪩"],jǐn:["侭","儘","卺","厪","巹","槿","漌","瑾","紧","緊","菫","蓳","謹","谨","錦","锦","饉","馑"],"hóu hòu":["侯","矦"],jiǒng:["侰","僒","冏","囧","泂","澃","炯","烱","煚","煛","熲","燛","窘","綗","褧","迥","逈","顈","颎","䌹"],"chěng tǐng":["侱"],"zhèn zhēn":["侲","揕"],zuò:["侳","做","唑","坐","岝","岞","座","祚","糳","胙","葃","葄","蓙","袏","阼"],qīn:["侵","兓","媇","嵚","嶔","欽","衾","誛","钦","顉","駸","骎","鮼"],jú:["侷","啹","婅","局","巈","椈","橘","泦","淗","湨","焗","犑","狊","粷","菊","蘜","趜","跼","蹫","輂","郹","閰","駶","驧","鵙","鵴","鶪","鼰","鼳","䴗"],"shù dōu":["侸"],tǐng:["侹","圢","娗","挺","涏","烶","珽","脡","艇","誔","頲","颋"],shèn:["侺","愼","慎","昚","涁","渗","滲","瘆","瘮","眘","祳","肾","胂","脤","腎","蜃","蜄","鋠"],"tuì tuó":["侻"],nán:["侽","喃","娚","抩","暔","枏","柟","楠","男","畘","莮","萳","遖"],xiāo:["侾","哓","嘵","嚻","囂","婋","宯","宵","庨","彇","揱","枭","枵","梟","櫹","歊","毊","消","潇","瀟","灱","灲","烋","焇","猇","獢","痚","痟","硝","硣","窙","箫","簘","簫","綃","绡","翛","膮","萧","蕭","虈","虓","蟂","蟏","蟰","蠨","踃","逍","銷","销","霄","颵","驍","骁","髇","髐","魈","鴞","鴵","鷍","鸮"],"biàn pián":["便","緶","缏"],tuǐ:["俀","腿","蹆","骽"],xì:["係","匸","卌","呬","墍","屃","屓","屭","忥","怬","恄","椞","潝","潟","澙","熂","犔","磶","禊","細","綌","縘","细","绤","舃","舄","蕮","虩","衋","覤","赩","趇","郤","釳","阋","隙","隟","霼","餼","饩","鬩","黖"],cù:["促","媨","憱","猝","瘄","瘯","簇","縬","脨","蔟","誎","趗","踧","踿","蹙","蹴","蹵","醋","顣","鼀"],é:["俄","囮","娥","峉","峨","峩","涐","珴","皒","睋","磀","莪","訛","誐","譌","讹","迗","鈋","鋨","锇","頟","額","额","魤","鵝","鵞","鹅"],qiú:["俅","叴","唒","囚","崷","巯","巰","扏","梂","殏","毬","求","汓","泅","浗","湭","煪","犰","玌","球","璆","皳","盚","紌","絿","肍","芁","莍","虬","虯","蛷","裘","觓","觩","訄","訅","賕","赇","逎","逑","遒","酋","釚","釻","銶","頄","鮂","鯄","鰽","鼽","𨱇"],xú:["俆","徐","禑"],"guàng kuāng":["俇"],kù:["俈","喾","嚳","库","庫","廤","瘔","絝","绔","袴","裤","褲","酷"],wù:["俉","务","務","勿","卼","坞","塢","奦","婺","寤","屼","岉","嵨","忢","悞","悟","悮","戊","扤","晤","杌","溩","焐","熃","物","痦","矹","窹","粅","蘁","誤","误","鋈","阢","隖","雾","霚","霧","靰","騖","骛","鶩","鹜","鼿","齀"],jùn:["俊","儁","呁","埈","寯","峻","懏","捃","攟","晙","棞","燇","珺","畯","竣","箟","蜠","賐","郡","陖","餕","馂","駿","骏","鵔","鵕","鵘","䐃"],liáng:["俍","墚","梁","椋","樑","粮","粱","糧","良","輬","辌","𫟅"],zǔ:["俎","唨","爼","祖","組","组","詛","诅","鎺","阻","靻"],"qiào xiào":["俏"],yǒng:["俑","勇","勈","咏","埇","塎","嵱","彮","怺","恿","悀","惥","愑","愹","慂","柡","栐","永","泳","湧","甬","蛹","詠","踊","踴","鯒","鲬"],hùn:["俒","倱","圂","尡","慁","掍","溷","焝","睴","觨","諢","诨"],jìng:["俓","傹","境","妌","婙","婧","弪","弳","径","徑","敬","曔","桱","梷","浄","瀞","獍","痉","痙","竞","竟","竫","競","竸","胫","脛","莖","誩","踁","迳","逕","鏡","镜","靖","静","靜","鵛"],sàn:["俕","閐"],pěi:["俖"],sú:["俗"],xī:["俙","僖","兮","凞","卥","厀","吸","唏","唽","嘻","噏","嚱","夕","奚","嬆","嬉","屖","嵠","巇","希","徆","徯","息","悉","悕","惁","惜","昔","晞","晰","晳","曦","析","桸","榽","樨","橀","欷","氥","汐","浠","淅","渓","溪","烯","焁","焈","焟","熄","熈","熙","熹","熺","熻","燨","爔","牺","犀","犠","犧","琋","瘜","皙","睎","瞦","矽","硒","磎","礂","稀","穸","窸","粞","糦","緆","繥","羲","翕","翖","肸","肹","膝","舾","莃","菥","蒠","蜥","螅","蟋","蠵","西","觹","觽","觿","譆","谿","豀","豨","豯","貕","赥","邜","鄎","酅","醯","釸","錫","鏭","鐊","鑴","锡","隵","餏","饎","饻","鯑","鵗","鸂","鼷"],lǐ:["俚","娌","峢","峲","李","欚","浬","澧","理","礼","禮","粴","裏","裡","豊","逦","邐","醴","鋰","锂","鯉","鱧","鱱","鲤","鳢"],bǎo:["保","堢","媬","宝","寚","寳","寶","珤","緥","葆","藵","褓","賲","靌","飹","飽","饱","駂","鳵","鴇","鸨"],"yú shù yù":["俞"],"sì qí":["俟"],"xìn shēn":["信"],xiū:["俢","修","咻","庥","樇","烌","羞","脙","脩","臹","貅","銝","鎀","飍","饈","馐","髤","髹","鮴","鱃","鵂","鸺","䗛"],dì:["俤","偙","僀","埊","墑","墬","娣","帝","怟","旳","梊","焍","玓","甋","眱","睇","碲","祶","禘","第","締","缔","腣","菂","蒂","蔕","蝃","蝭","螮","諦","谛","踶","递","逓","遞","遰","鉪","𤧛","䗖"],chóu:["俦","儔","嬦","惆","愁","懤","栦","燽","畴","疇","皗","稠","筹","籌","絒","綢","绸","菗","詶","讎","讐","踌","躊","酧","酬","醻","雔","雠","雦"],zhì:["俧","偫","儨","制","劕","垁","娡","寘","帙","帜","幟","庢","庤","廌","彘","徏","徝","志","忮","懥","懫","挃","挚","掷","摯","擲","旘","晊","智","栉","桎","梽","櫍","櫛","治","洷","滍","滞","滯","潌","瀄","炙","熫","狾","猘","璏","瓆","痔","痣","礩","祑","秩","秷","稚","稺","穉","窒","紩","緻","置","翐","膣","至","致","芖","蛭","袟","袠","製","覟","觗","觯","觶","誌","豑","豒","貭","質","贄","质","贽","跱","踬","躓","輊","轾","郅","銍","鋕","鑕","铚","锧","陟","隲","雉","駤","騭","騺","驇","骘","鯯","鴙","鷙","鸷","𬃊"],"liǎ liǎng":["俩"],jiǎn:["俭","倹","儉","减","剪","堿","弿","彅","戩","戬","拣","挸","捡","揀","撿","枧","柬","梘","检","検","檢","減","湕","瀽","瑐","睑","瞼","硷","碱","礆","笕","筧","简","簡","絸","繭","翦","茧","藆","蠒","裥","襇","襉","襺","詃","謇","謭","譾","谫","趼","蹇","鐗","鬋","鰎","鹸","鹻","鹼"],huò:["俰","咟","嚯","嚿","奯","彠","惑","或","擭","旤","曤","檴","沎","湱","瀖","獲","癨","眓","矐","祸","禍","穫","窢","耯","臛","艧","获","蒦","藿","蠖","謋","貨","货","鍃","鑊","镬","雘","霍","靃","韄","㸌"],"jù jū":["俱","据","鋸","锯"],xiào:["俲","傚","効","咲","哮","啸","嘋","嘨","嘯","孝","效","斅","斆","歗","涍","熽","笑","詨","誟"],pái:["俳","徘","牌","犤","猅","簰","簲","輫"],biào:["俵","鰾","鳔"],"chù tì":["俶"],fèi:["俷","剕","厞","吠","屝","废","廃","廢","昲","曊","櫠","沸","濷","狒","癈","肺","萉","費","费","鐨","镄","陫","靅","鼣"],fèng:["俸","凤","奉","湗","焨","煈","賵","赗","鳯","鳳","鴌"],ǎn:["俺","唵","埯","揞","罯","銨","铵"],bèi:["俻","倍","偝","偹","備","僃","备","悖","惫","愂","憊","昁","梖","焙","牬","犕","狈","狽","珼","琲","碚","禙","糒","苝","蓓","蛽","褙","貝","贝","軰","輩","辈","邶","郥","鄁","鋇","鐾","钡","鞁","鞴","𬇙"],yù:["俼","儥","喅","喩","喻","域","堉","妪","嫗","寓","峪","嶎","庽","彧","御","愈","慾","戫","昱","棛","棜","棫","櫲","欎","欝","欲","毓","浴","淯","滪","潏","澦","灪","焴","煜","燏","燠","爩","狱","獄","玉","琙","瘉","癒","砡","硢","硲","礇","礖","礜","禦","秗","稢","稶","篽","籞","籲","粖","緎","罭","聿","肀","艈","芋","芌","茟","蒮","蓣","蓹","蕷","蘌","蜟","蜮","袬","裕","誉","諭","譽","谕","豫","軉","輍","逳","遇","遹","郁","醧","鈺","鋊","錥","鐭","钰","閾","阈","雤","霱","預","预","飫","饇","饫","馭","驈","驭","鬰","鬱","鬻","魊","鱊","鳿","鴥","鴧","鴪","鵒","鷸","鸒","鹆","鹬"],xīn:["俽","噺","妡","嬜","廞","心","忄","忻","惞","新","昕","杺","欣","歆","炘","盺","薪","訢","辛","邤","鈊","鋅","鑫","锌","馨","馫","䜣","𫷷"],"hǔ chí":["俿"],jiù:["倃","僦","匓","匛","匶","厩","咎","就","廄","廏","廐","慦","捄","救","旧","柩","柾","桕","欍","殧","疚","臼","舅","舊","鯦","鷲","鹫","麔","齨","㠇"],yáo:["倄","傜","嗂","垚","堯","姚","媱","尧","尭","峣","嶢","嶤","徭","揺","搖","摇","摿","暚","榣","烑","爻","猺","珧","瑤","瑶","磘","窑","窯","窰","肴","蘨","謠","謡","谣","軺","轺","遙","遥","邎","顤","颻","飖","餆","餚","鰩","鱙","鳐"],"cuì zú":["倅"],"liǎng liǎ":["倆"],wǎn:["倇","唍","婉","惋","挽","晚","晥","晩","晼","梚","椀","琬","畹","皖","盌","碗","綩","綰","绾","脘","萖","踠","輓","鋔"],zǒng:["倊","偬","傯","嵸","总","惣","捴","搃","摠","燪","総","緫","縂","總","蓗"],guān:["倌","关","官","棺","瘝","癏","窤","蒄","関","闗","關","鰥","鱞","鳏"],tiǎn:["倎","唺","忝","悿","晪","殄","淟","睓","腆","舔","覥","觍","賟","錪","餂"],mén:["們","扪","捫","璊","菛","虋","鍆","钔","門","閅","门","𫞩"],"dǎo dào":["倒"],"tán tàn":["倓","埮"],"juè jué":["倔"],chuí:["倕","垂","埀","捶","搥","桘","棰","槌","箠","腄","菙","錘","鎚","锤","陲","顀"],xìng:["倖","姓","婞","嬹","幸","性","悻","杏","涬","緈","臖","荇","莕","葕"],péng:["倗","傰","塜","塳","弸","憉","捀","朋","棚","椖","樥","硼","稝","竼","篷","纄","膨","芃","蓬","蘕","蟚","蟛","袶","輣","錋","鑝","韸","韼","騯","髼","鬅","鬔","鵬","鹏"],"tǎng cháng":["倘"],hòu:["候","厚","后","垕","堠","後","洉","茩","豞","逅","郈","鮜","鱟","鲎","鲘"],tì:["倜","剃","嚏","嚔","屉","屜","悌","悐","惕","惖","戻","掦","替","朑","歒","殢","涕","瓋","笹","籊","薙","褅","逖","逷","髰","鬀","鬄"],gàn:["倝","凎","幹","榦","檊","淦","灨","盰","紺","绀","詌","贑","赣","骭","㽏"],"liàng jìng":["倞","靓"],suī:["倠","哸","夊","滖","濉","眭","睢","芕","荽","荾","虽","雖","鞖"],"chàng chāng":["倡"],jié:["倢","偼","傑","刦","刧","刼","劫","劼","卩","卪","婕","媫","孑","岊","崨","嵥","嶻","巀","幯","截","捷","掶","擮","昅","杢","杰","桀","桝","楬","楶","榤","洁","滐","潔","狤","睫","礍","竭","節","羯","莭","蓵","蛣","蜐","蠘","蠞","蠽","衱","袺","訐","詰","誱","讦","踕","迼","鉣","鍻","镼","頡","鮚","鲒","㛃"],"kǒng kōng":["倥"],juàn:["倦","劵","奆","慻","桊","淃","狷","獧","眷","睊","睠","絭","絹","绢","罥","羂","腃","蔨","鄄","餋"],zōng:["倧","堫","宗","嵏","嵕","惾","朡","棕","椶","熧","猣","磫","緃","翪","腙","葼","蝬","豵","踨","踪","蹤","鍐","鑁","騌","騣","骔","鬃","鬉","鬷","鯮","鯼"],ní:["倪","坭","埿","尼","屔","怩","淣","猊","籾","聣","蚭","蜺","觬","貎","跜","輗","郳","鈮","铌","霓","馜","鯢","鲵","麑","齯","𫐐","𫠜"],zhuō:["倬","拙","捉","桌","梲","棁","棳","槕","涿","窧","鐯","䦃"],"wō wēi":["倭"],luǒ:["倮","剆","曪","瘰","癳","臝","蓏","蠃","裸","躶"],sōng:["倯","凇","娀","崧","嵩","庺","憽","松","枀","枩","柗","梥","檧","淞","濍","硹","菘","鬆"],lèng:["倰","堎","愣","睖","踜"],zì:["倳","剚","字","恣","渍","漬","牸","眥","眦","胔","胾","自","茡","荢"],bèn:["倴","坌","捹","撪","渀","笨","逩"],cǎi:["倸","啋","婇","彩","採","棌","毝","睬","綵","跴","踩"],zhài:["债","債","寨","瘵","砦"],yē:["倻","吔","噎","擨","暍","椰","歋","潱","蠮"],shà:["倽","唼","喢","歃","箑","翜","翣","萐","閯","霎"],qīng:["倾","傾","卿","圊","寈","氢","氫","淸","清","蜻","軽","輕","轻","郬","錆","鑋","靑","青","鯖"],yīng:["偀","嘤","噟","嚶","婴","媖","嫈","嬰","孆","孾","愥","撄","攖","朠","桜","樱","櫻","渶","煐","珱","瑛","璎","瓔","甇","甖","碤","礯","緓","纓","绬","缨","罂","罃","罌","膺","英","莺","蘡","蝧","蠳","褮","譻","賏","軈","鑍","锳","霙","韺","鴬","鶑","鶧","鶯","鷪","鷹","鸎","鸚","鹦","鹰","䓨"],"chēng chèn":["偁","爯"],ruǎn:["偄","朊","瑌","瓀","碝","礝","腝","軟","輭","软","阮"],"zhòng tóng":["偅"],chǔn:["偆","惷","睶","萶","蠢","賰"],"jiǎ jià":["假"],"jì jié":["偈"],"bǐng bìng":["偋"],ruò:["偌","叒","嵶","弱","楉","焫","爇","箬","篛","蒻","鄀","鰙","鰯","鶸"],tí:["偍","厗","啼","嗁","崹","漽","瑅","睼","禵","稊","緹","缇","罤","蕛","褆","謕","趧","蹄","蹏","醍","鍗","題","题","騠","鮷","鯷","鳀","鵜","鷤","鹈","𫘨"],wēi:["偎","危","喴","威","媙","嶶","巍","微","愄","揋","揻","椳","楲","溦","烓","煨","燰","癓","縅","葨","葳","薇","蜲","蝛","覣","詴","逶","隇","隈","霺","鰃","鰄","鳂"],piān:["偏","囨","媥","楄","犏","篇","翩","鍂"],yàn:["偐","厌","厭","唁","喭","嚈","嚥","堰","妟","姲","嬊","嬿","宴","彥","彦","敥","晏","暥","曕","曣","滟","灎","灔","灧","灩","焔","焰","焱","熖","燄","牪","猒","砚","硯","艳","艶","艷","覎","觃","觾","諺","讌","讞","谚","谳","豓","豔","贋","贗","赝","軅","酀","酽","醼","釅","雁","餍","饜","騐","験","騴","驗","驠","验","鬳","鳫","鴈","鴳","鷃","鷰","齞"],"tǎng dàng":["偒"],è:["偔","匎","卾","厄","呝","咢","噩","垩","堊","堮","岋","崿","廅","悪","愕","戹","扼","搤","搹","擜","櫮","歞","歺","湂","琧","砈","砐","硆","腭","苊","萼","蕚","蚅","蝁","覨","諤","讍","谔","豟","軛","軶","轭","遌","遏","遻","鄂","鈪","鍔","鑩","锷","阨","阸","頞","顎","颚","餓","餩","饿","鰐","鰪","鱷","鳄","鶚","鹗","齃","齶","𫫇","𥔲"],xié:["偕","勰","协","協","嗋","垥","奊","恊","愶","拹","携","撷","擕","擷","攜","斜","旪","熁","燲","綊","緳","縀","缬","翓","胁","脅","脇","脋","膎","蝢","衺","襭","諧","讗","谐","鞋","鞵","龤","㙦"],chě:["偖","扯","撦"],shěng:["偗","渻","眚"],chā:["偛","嗏","扠","挿","插","揷","疀","臿","艖","銟","鍤","锸","餷"],huáng:["偟","凰","喤","堭","墴","媓","崲","徨","惶","楻","湟","煌","獚","瑝","璜","癀","皇","磺","穔","篁","簧","艎","葟","蝗","蟥","諻","趪","遑","鍠","鐄","锽","隍","韹","餭","騜","鰉","鱑","鳇","鷬","黃","黄","𨱑"],yǎo:["偠","咬","婹","宎","岆","杳","柼","榚","溔","狕","窅","窈","舀","苭","闄","騕","鷕","齩"],"chǒu qiào":["偢"],yóu:["偤","尤","庮","怣","沋","油","浟","游","犹","猶","猷","由","疣","秞","肬","莜","莸","蕕","蚰","蝣","訧","輏","輶","逰","遊","邮","郵","鈾","铀","駀","魷","鮋","鱿","鲉","𬨎"],xū:["偦","墟","媭","嬃","楈","欨","歔","燸","疞","盱","綇","縃","繻","胥","蕦","虗","虚","虛","蝑","裇","訏","許","諝","譃","谞","鑐","需","須","须","顼","驉","鬚","魆","魖","𬣙","𦈡"],zhā:["偧","哳","抯","挓","揸","摣","樝","渣","皶","觰","譇","齄","齇"],cī:["偨","疵","蠀","趀","骴","髊","齹"],bī:["偪","屄","楅","毴","豍","逼","鰏","鲾","鵖"],xún:["偱","噚","寻","尋","峋","巡","廵","循","恂","揗","攳","旬","杊","栒","桪","樳","洵","浔","潯","燅","燖","珣","璕","畃","紃","荀","蟳","詢","询","鄩","鱏","鱘","鲟","𬘓","𬩽","𬍤","𬊈"],"cāi sī":["偲"],duān:["偳","媏","端","褍","鍴"],ǒu:["偶","吘","嘔","耦","腢","蕅","藕","𬉼","𠙶"],tōu:["偷","偸","鍮"],"zán zá zǎ":["偺"],"lǚ lóu":["偻","僂"],fèn:["偾","僨","奋","奮","弅","忿","愤","憤","瀵","瞓","秎","粪","糞","膹","鱝","鲼"],"kuǐ guī":["傀"],sǒu:["傁","叜","叟","嗾","櫢","瞍","薮","藪"],"zhì sī tí":["傂"],sù:["傃","僳","嗉","塐","塑","夙","嫊","愫","憟","榡","樎","樕","殐","泝","涑","溯","溸","潚","潥","玊","珟","璛","簌","粛","粟","素","縤","肃","肅","膆","蔌","藗","觫","訴","謖","诉","谡","趚","蹜","速","遡","遬","鋉","餗","驌","骕","鱐","鷫","鹔","𫗧"],xiā:["傄","煆","瞎","虲","谺","颬","鰕"],"yuàn yuán":["傆","媛"],rǒng:["傇","冗","宂","氄","軵"],nù:["傉","怒"],yùn:["傊","孕","恽","惲","愠","慍","枟","腪","蕴","薀","藴","蘊","褞","貟","运","運","郓","鄆","酝","醖","醞","韗","韞","韵","韻","餫"],"gòu jiǎng":["傋"],mà:["傌","嘜","榪","睰","祃","禡","罵","閁","駡","骂","鬕"],bàng:["傍","塝","棒","玤","稖","艕","蒡","蜯","謗","谤","鎊","镑"],diān:["傎","厧","嵮","巅","巓","巔","掂","攧","敁","槇","滇","癫","癲","蹎","顚","顛","颠","齻"],táng:["傏","唐","啺","坣","堂","塘","搪","棠","榶","溏","漟","煻","瑭","磄","禟","篖","糃","糖","糛","膅","膛","蓎","螗","螳","赯","踼","鄌","醣","鎕","隚","餹","饄","鶶","䣘"],hào:["傐","哠","恏","昊","昦","晧","暠","暤","暭","曍","浩","淏","澔","灏","灝","皓","皜","皞","皡","皥","耗","聕","薃","號","鄗","顥","颢","鰝"],"xī xì":["傒"],shān:["傓","删","刪","剼","圸","山","挻","搧","柵","檆","潸","澘","煽","狦","珊","笘","縿","羴","羶","脠","舢","芟","衫","跚","軕","邖","閊","鯅"],"qiàn jiān":["傔"],"què jué":["傕","埆"],"cāng chen":["傖"],róng:["傛","媶","嫆","嬫","容","峵","嵘","嶸","戎","搈","曧","栄","榕","榮","榵","毧","溶","瀜","烿","熔","狨","瑢","穁","絨","绒","羢","肜","茙","茸","荣","蓉","蝾","融","螎","蠑","褣","鎔","镕","駥"],"tà tàn":["傝"],suō:["傞","唆","嗍","嗦","娑","摍","桫","梭","睃","簑","簔","羧","莏","蓑","趖","鮻"],dǎi:["傣","歹"],zài:["傤","儎","再","在","扗","洅","載","酨"],gǔ:["傦","古","啒","尳","愲","榖","榾","汩","淈","濲","瀔","牯","皷","皼","盬","瞽","穀","罟","羖","股","脵","臌","薣","蛊","蠱","詁","诂","轂","逧","鈷","钴","餶","馉","鼓","鼔","𦙶"],bīn:["傧","宾","彬","斌","椕","滨","濒","濱","濵","瀕","繽","缤","虨","豩","豳","賓","賔","邠","鑌","镔","霦","顮"],chǔ:["储","儲","杵","椘","楚","楮","檚","濋","璴","础","礎","禇","處","齭","齼","𬺓"],nuó:["傩","儺","挪","梛","橠"],"cān càn":["傪"],lěi:["傫","儡","厽","垒","塁","壘","壨","櫐","灅","癗","矋","磊","礨","耒","蕌","蕾","藟","蘽","蠝","誄","讄","诔","鑸","鸓"],cuī:["催","凗","墔","崔","嵟","慛","摧","榱","獕","磪","鏙"],yōng:["傭","嗈","墉","壅","嫞","庸","廱","慵","拥","擁","滽","灉","牅","痈","癕","癰","臃","邕","郺","鄘","鏞","镛","雍","雝","饔","鱅","鳙","鷛"],"zāo cáo":["傮"],sǒng:["傱","嵷","怂","悚","愯","慫","竦","耸","聳","駷","㧐"],ào:["傲","坳","垇","墺","奡","嫯","岙","岰","嶴","懊","擙","澳","鏊","驁","骜"],"qī còu":["傶"],chuǎng:["傸","磢","闖","闯"],shǎ:["傻","儍"],hàn:["傼","垾","悍","憾","扞","捍","撖","撼","旱","晘","暵","汉","涆","漢","瀚","焊","猂","皔","睅","翰","莟","菡","蛿","蜭","螒","譀","輚","釬","銲","鋎","雗","頷","顄","颔","駻","鶾"],zhāng:["傽","嫜","张","張","彰","慞","暲","樟","漳","獐","璋","章","粻","蔁","蟑","遧","鄣","鏱","餦","騿","鱆","麞"],"yān yàn":["傿","墕","嬮"],"piào biāo":["僄","骠"],liàn:["僆","堜","媡","恋","戀","楝","殓","殮","湅","潋","澰","瀲","炼","煉","瑓","練","纞","练","萰","錬","鍊","鏈","链","鰊","𬶠"],màn:["㵘","僈","墁","幔","慢","曼","漫","澷","熳","獌","縵","缦","蔄","蘰","鄤","鏝","镘","𬜬"],"tàn tǎn":["僋"],yíng:["僌","営","塋","嬴","攍","楹","櫿","溁","溋","滢","潆","濙","濚","濴","瀅","瀛","瀠","瀯","灐","灜","熒","營","瑩","盁","盈","禜","籝","籯","縈","茔","荧","莹","萤","营","萦","萾","蓥","藀","蛍","蝇","蝿","螢","蠅","謍","贏","赢","迎","鎣"],dòng:["働","冻","凍","动","動","姛","戙","挏","栋","棟","湩","硐","胨","胴","腖","迵","霘","駧"],zhuàn:["僎","啭","囀","堟","撰","灷","瑑","篆","腞","蒃","襈","譔","饌","馔"],xiàng:["像","勨","向","嚮","姠","嶑","曏","橡","珦","缿","蟓","衖","襐","象","鐌","項","项","鱌"],shàn:["僐","善","墠","墡","嬗","擅","敾","椫","樿","歚","汕","灗","疝","磰","繕","缮","膳","蟮","蟺","訕","謆","譱","讪","贍","赡","赸","鄯","鐥","饍","騸","骟","鱓","鱔","鳝","𫮃"],"tuí tuǐ":["僓"],zǔn:["僔","噂","撙","譐"],pú:["僕","匍","圤","墣","濮","獛","璞","瞨","穙","莆","菐","菩","葡","蒱","蒲","贌","酺","鏷","镤"],láo:["僗","劳","労","勞","哰","崂","嶗","憥","朥","浶","牢","痨","癆","窂","簩","醪","鐒","铹","顟","髝","𫭼"],chǎng:["僘","厰","廠","敞","昶","氅","鋹","𬬮"],guāng:["僙","光","咣","垙","姯","洸","灮","炗","炚","炛","烡","珖","胱","茪","輄","銧","黆","𨐈"],liáo:["僚","嘹","嫽","寥","寮","尞","屪","嵺","嶚","嶛","廫","憀","敹","暸","橑","獠","璙","疗","療","竂","簝","繚","缭","聊","膋","膫","藔","蟟","豂","賿","蹘","辽","遼","飉","髎","鷯","鹩"],dèng:["僜","凳","墱","嶝","櫈","瞪","磴","覴","邓","鄧","隥"],"chán zhàn zhuàn":["僝"],bō:["僠","嶓","拨","撥","播","波","溊","玻","癶","盋","砵","碆","礡","缽","菠","袰","蹳","鉢","钵","餑","饽","驋","鱍","𬭛"],huì:["僡","匯","卉","喙","嘒","嚖","圚","嬒","寭","屶","屷","彗","彙","彚","徻","恚","恵","惠","慧","憓","懳","晦","暳","槥","橞","檅","櫘","汇","泋","滙","潓","烩","燴","獩","璤","瞺","硊","秽","穢","篲","絵","繪","绘","翙","翽","荟","蔧","蕙","薈","薉","蟪","詯","誨","諱","譓","譿","讳","诲","賄","贿","鐬","闠","阓","靧","頮","顪","颒","餯","𬤝","𬭬"],chuǎn:["僢","喘","舛","荈","踳"],"tiě jiàn":["僣"],sēng:["僧","鬙"],xiàn:["僩","僴","哯","垷","塪","姭","娊","宪","岘","峴","憲","撊","晛","橌","橺","涀","瀗","献","獻","现","現","県","睍","粯","糮","絤","綫","線","线","缐","羡","羨","腺","臔","臽","苋","莧","誢","豏","鋧","錎","限","陥","陷","霰","餡","馅","麲","鼸","𬀪","𪾢"],"yù jú":["僪"],"è wū":["僫"],"tóng zhuàng":["僮"],lǐn:["僯","凛","凜","廩","廪","懍","懔","撛","檁","檩","澟","癛","癝"],gù:["僱","凅","固","堌","崓","崮","故","梏","棝","牿","痼","祻","錮","锢","雇","顧","顾","鯝","鲴"],jiāng:["僵","壃","姜","橿","殭","江","畕","疅","礓","繮","缰","翞","茳","葁","薑","螀","螿","豇","韁","鱂","鳉"],mǐn:["僶","冺","刡","勄","悯","惽","愍","慜","憫","抿","敃","敏","敯","泯","潣","皿","笢","笽","簢","蠠","閔","閩","闵","闽","鰵","鳘","黽"],jìn:["僸","凚","噤","嚍","墐","壗","妗","嬧","搢","晉","晋","枃","殣","浕","浸","溍","濅","濜","烬","煡","燼","琎","瑨","璶","盡","祲","縉","缙","荩","藎","覲","觐","賮","贐","赆","近","进","進","靳","齽"],"jià jie":["價"],qiào:["僺","峭","帩","撬","殻","窍","竅","誚","诮","躈","陗","鞩","韒","髚"],pì:["僻","媲","嫓","屁","澼","甓","疈","譬","闢","鷿","鸊","䴙"],sài:["僿","簺","賽","赛"],"chán tǎn shàn":["儃"],"dāng dàng":["儅","当","闣"],xuān:["儇","喧","塇","媗","宣","愃","愋","揎","昍","暄","煊","煖","瑄","睻","矎","禤","箮","翧","翾","萱","萲","蓒","蕿","藼","蘐","蝖","蠉","諠","諼","譞","谖","軒","轩","鍹","駽","鰚","𫓶","𫍽"],"dān dàn":["儋","擔","瘅"],càn:["儏","澯","灿","燦","璨","粲","薒","謲"],"bīn bìn":["儐"],"án àn":["儑"],tái:["儓","坮","嬯","抬","擡","檯","炱","炲","籉","臺","薹","跆","邰","颱","鮐","鲐"],lán:["儖","兰","囒","婪","岚","嵐","幱","拦","攔","斓","斕","栏","欄","欗","澜","瀾","灆","灡","燣","燷","璼","篮","籃","籣","繿","葻","蓝","藍","蘫","蘭","褴","襕","襤","襴","襽","譋","讕","谰","躝","鑭","镧","闌","阑","韊","𬒗"],"nǐ yì ài yí":["儗"],méng:["儚","幪","曚","朦","橗","檬","氋","溕","濛","甍","甿","盟","礞","艨","莔","萌","蕄","虻","蝱","鄳","鄸","霿","靀","顭","饛","鯍","鸏","鹲","𫑡","㠓"],níng:["儜","凝","咛","嚀","嬣","柠","橣","檸","狞","獰","聍","聹","薴","鑏","鬡","鸋"],qióng:["儝","卭","宆","惸","憌","桏","橩","焪","焭","煢","熍","琼","瓊","睘","穷","穹","窮","竆","笻","筇","舼","茕","藑","藭","蛩","蛬","赹","跫","邛","銎","䓖"],liè:["儠","冽","列","劣","劽","埒","埓","姴","峛","巤","挒","捩","栵","洌","浖","烈","烮","煭","犣","猎","猟","獵","聗","脟","茢","蛚","趔","躐","迾","颲","鬛","鬣","鮤","鱲","鴷","䴕","𫚭"],kuǎng:["儣","夼","懭"],bào:["儤","勽","報","忁","报","抱","曓","爆","犦","菢","虣","蚫","豹","鉋","鑤","铇","骲","髱","鮑","鲍"],biāo:["儦","墂","幖","彪","标","標","滮","瀌","熛","爂","猋","瘭","磦","膘","臕","謤","贆","鏢","鑣","镖","镳","颮","颷","飆","飇","飈","飊","飑","飙","飚","驫","骉","髟"],zǎn:["儧","儹","噆","攅","昝","趱","趲"],háo:["儫","嗥","嘷","噑","嚎","壕","椃","毜","毫","濠","獆","獔","竓","籇","蚝","蠔","譹","豪"],qìng:["儬","凊","庆","慶","櫦","濪","碃","磬","罄","靘"],chèn:["儭","嚫","榇","櫬","疢","衬","襯","讖","谶","趁","趂","齓","齔","龀"],téng:["儯","幐","滕","漛","疼","籐","籘","縢","腾","藤","虅","螣","誊","謄","邆","駦","騰","驣","鰧","䲢"],"lǒng lóng lòng":["儱"],"chán chàn":["儳"],"ráng xiāng":["儴","勷"],"huì xié":["儶"],luó:["儸","攞","椤","欏","猡","玀","箩","籮","罗","羅","脶","腡","萝","蘿","螺","覼","逻","邏","鏍","鑼","锣","镙","饠","騾","驘","骡","鸁"],léi:["儽","嫘","檑","欙","瓃","畾","縲","纍","纝","缧","罍","羸","蔂","蘲","虆","轠","鐳","鑘","镭","雷","靁","鱩","鼺"],"nàng nāng":["儾"],"wù wū":["兀"],yǔn:["允","喗","夽","抎","殒","殞","狁","磒","荺","賱","鈗","阭","陨","隕","霣","馻","齫","齳"],zān:["兂","橵","簪","簮","糌","鐕","鐟","鵤"],yuán:["元","円","原","厡","厵","园","圆","圎","園","圓","垣","塬","媴","嫄","援","榞","榬","橼","櫞","沅","湲","源","溒","爰","猨","猿","笎","緣","縁","缘","羱","茒","薗","蝝","蝯","螈","袁","褤","謜","轅","辕","邍","邧","酛","鈨","鎱","騵","魭","鶢","鶰","黿","鼋","𫘪"],xiōng:["兄","兇","凶","匂","匈","哅","忷","恟","汹","洶","胷","胸","芎","訩","詾","讻"],chōng:["充","嘃","忡","憃","憧","摏","沖","浺","珫","罿","翀","舂","艟","茺","衝","蹖","㳘"],zhào:["兆","垗","旐","曌","枛","櫂","照","燳","狣","瞾","笊","罀","罩","羄","肁","肇","肈","詔","诏","赵","趙","鮡","𬶐"],"duì ruì yuè":["兊","兌","兑"],kè:["克","刻","勀","勊","堁","娔","客","恪","愙","氪","溘","碦","緙","缂","艐","衉","課","课","錁","锞","騍","骒"],tù:["兎","兔","堍","迌","鵵"],dǎng:["党","攩","欓","譡","讜","谠","黨","𣗋"],dōu:["兜","兠","唗","橷","篼","蔸"],huǎng:["兤","奛","幌","怳","恍","晄","炾","熀","縨","詤","謊","谎"],rù:["入","嗕","媷","扖","杁","洳","溽","縟","缛","蓐","褥","鳰"],nèi:["內","氝","氞","錗"],"yú shù":["兪"],"liù lù":["六"],han:["兯","爳"],tiān:["兲","天","婖","添","酟","靔","靝","黇"],"xīng xìng":["兴"],diǎn:["典","嚸","奌","婰","敟","椣","点","碘","蒧","蕇","踮","點"],"zī cí":["兹"],jiān:["兼","冿","囏","坚","堅","奸","姦","姧","尖","幵","惤","戋","戔","搛","椾","樫","櫼","歼","殱","殲","湔","瀐","瀸","煎","熞","熸","牋","瑊","睷","礛","礷","笺","箋","緘","縑","缄","缣","肩","艰","艱","菅","菺","葌","蒹","蔪","蕑","蕳","虃","譼","豜","鑯","雃","鞯","韀","韉","餰","馢","鰔","鰜","鰹","鲣","鳒","鵑","鵳","鶼","鹣","麉"],shòu:["兽","受","售","壽","夀","寿","授","狩","獣","獸","痩","瘦","綬","绶","膄"],jì:["兾","冀","剂","剤","劑","勣","坖","垍","塈","妓","季","寂","寄","廭","彑","徛","忌","悸","惎","懻","技","旡","既","旣","暨","暩","曁","梞","檕","檵","洎","漃","漈","瀱","痵","癠","禝","稩","稷","穄","穊","穧","紀","継","績","繋","繼","继","绩","罽","臮","芰","茍","茤","葪","蓟","蔇","薊","蘎","蘮","蘻","裚","襀","覬","觊","計","記","誋","计","记","跡","跽","蹟","迹","际","際","霁","霽","驥","骥","髻","鬾","魝","魥","鯚","鯽","鰶","鰿","鱀","鱭","鲚","鲫","鵋","鷑","齌","𪟝","𬶨","𬶭"],jiōng:["冂","冋","坰","埛","扃","蘏","蘔","駉","駫","𬳶"],mào:["冃","冐","媢","帽","愗","懋","暓","柕","楙","毷","瑁","皃","眊","瞀","耄","茂","萺","蝐","袤","覒","貌","貿","贸","鄚","鄮"],rǎn:["冄","冉","姌","媣","染","珃","苒","蒅","䎃"],"nèi nà":["内"],gāng:["冈","冮","刚","剛","堈","堽","岡","掆","摃","棡","牨","犅","疘","綱","纲","缸","罁","罡","肛","釭","鎠","㭎"],cè:["冊","册","厕","厠","夨","廁","恻","惻","憡","敇","测","測","笧","策","筞","筴","箣","荝","萗","萴","蓛"],guǎ:["冎","剐","剮","叧","寡"],"mào mò":["冒"],gòu:["冓","啂","坸","垢","够","夠","媾","彀","搆","撀","构","構","煹","覯","觏","訽","詬","诟","購","购","遘","雊"],xǔ:["冔","喣","暊","栩","珝","盨","糈","詡","諿","诩","鄦","醑"],mì:["冖","冪","嘧","塓","宻","密","峚","幂","幎","幦","怽","榓","樒","櫁","汨","淧","滵","漞","濗","熐","羃","蔤","蜜","覓","覔","覛","觅","謐","谧","鼏"],"yóu yín":["冘"],xiě:["写","冩","藛"],jūn:["军","君","均","桾","汮","皲","皸","皹","碅","莙","蚐","袀","覠","軍","鈞","銁","銞","鍕","钧","頵","鮶","鲪","麏"],mí:["冞","擟","瀰","爢","猕","獼","祢","禰","縻","蒾","藌","蘪","蘼","袮","詸","謎","迷","醚","醾","醿","釄","镾","鸍","麊","麋","麛"],"guān guàn":["冠","覌","観","觀","观"],měng:["冡","勐","懵","掹","猛","獴","艋","蜢","蠓","錳","锰","鯭","鼆"],zhǒng:["冢","塚","尰","歱","煄","瘇","肿","腫","踵"],zuì:["冣","嶵","晬","最","栬","槜","檇","檌","祽","絊","罪","蕞","辠","酔","酻","醉","錊"],yuān:["冤","剈","囦","嬽","寃","棩","淵","渁","渆","渊","渕","灁","眢","肙","葾","蒬","蜎","蜵","駌","鳶","鴛","鵷","鸢","鸳","鹓","鼘","鼝"],míng:["冥","名","明","暝","朙","榠","洺","溟","猽","眀","眳","瞑","茗","螟","覭","詺","鄍","銘","铭","鳴","鸣"],kòu:["冦","叩","宼","寇","扣","敂","滱","窛","筘","簆","蔲","蔻","釦","鷇"],tài:["冭","太","夳","忲","态","態","汰","汱","泰","溙","肽","舦","酞","鈦","钛"],"féng píng":["冯","馮"],"chōng chòng":["冲"],kuàng:["况","圹","壙","岲","懬","旷","昿","曠","框","況","爌","眖","眶","矿","砿","礦","穬","絋","絖","纊","纩","貺","贶","軦","邝","鄺","鉱","鋛","鑛","黋"],lěng:["冷"],pàn:["冸","判","叛","沜","泮","溿","炍","牉","畔","盼","聁","袢","襻","詊","鋬","鑻","頖","鵥"],fā:["冹","彂","沷","発","發"],xiǎn:["冼","尟","尠","崄","嶮","幰","攇","显","櫶","毨","灦","烍","燹","狝","猃","獫","獮","玁","禒","筅","箲","藓","蘚","蚬","蜆","譣","赻","跣","鍌","险","険","險","韅","顕","顯","㬎"],qià:["冾","圶","帢","恰","殎","洽","硈","胢","髂"],"jìng chēng":["净","凈","淨"],sōu:["凁","嗖","廀","廋","捜","搜","摉","溲","獀","艘","蒐","螋","鄋","醙","鎪","锼","颼","飕","餿","馊","騪"],měi:["凂","媄","媺","嬍","嵄","挴","毎","每","浼","渼","燘","美","躾","鎂","镁","黣"],tú:["凃","図","图","圖","圗","塗","屠","峹","嵞","庩","廜","徒","悇","揬","涂","瘏","筡","腯","荼","蒤","跿","途","酴","鈯","鍎","馟","駼","鵌","鶟","鷋","鷵","𬳿"],zhǔn:["准","凖","埻","準","𬘯"],"liáng liàng":["凉","涼","量"],diāo:["凋","刁","刟","叼","奝","弴","彫","汈","琱","碉","簓","虭","蛁","貂","錭","雕","鮉","鯛","鲷","鵰","鼦"],còu:["凑","湊","腠","輳","辏"],ái:["凒","啀","嘊","捱","溰","癌","皑","皚"],duó:["凙","剫","夺","奪","痥","踱","鈬","鐸","铎"],dú:["凟","匵","嬻","椟","櫝","殰","涜","牍","牘","犊","犢","独","獨","瓄","皾","裻","読","讀","讟","豄","贕","錖","鑟","韇","韣","韥","騳","髑","黩","黷"],"jǐ jī":["几"],fán:["凡","凢","凣","匥","墦","杋","柉","棥","樊","瀿","烦","煩","燔","璠","矾","礬","笲","籵","緐","羳","舤","舧","薠","蘩","蠜","襎","蹯","釩","鐇","鐢","钒","鷭","𫔍","𬸪"],jū:["凥","匊","娵","婮","居","崌","抅","挶","掬","梮","椐","檋","毩","毱","泃","涺","狙","琚","疽","砠","罝","腒","艍","蜛","裾","諊","跔","踘","躹","陱","雎","鞠","鞫","駒","驹","鮈","鴡","鶋","𬶋"],"chù chǔ":["処","处"],zhǐ:["凪","劧","咫","址","坧","帋","恉","扺","指","旨","枳","止","汦","沚","洔","淽","疻","砋","祉","秖","紙","纸","芷","藢","衹","襧","訨","趾","軹","轵","酯","阯","黹"],píng:["凭","凴","呯","坪","塀","岼","帡","帲","幈","平","慿","憑","枰","洴","焩","玶","瓶","甁","竮","箳","簈","缾","荓","萍","蓱","蚲","蛢","評","评","軿","輧","郱","鮃","鲆"],kǎi:["凯","凱","剀","剴","垲","塏","恺","愷","慨","暟","蒈","輆","鍇","鎧","铠","锴","闓","闿","颽"],gān:["凲","坩","尲","尴","尶","尷","柑","泔","漧","玕","甘","疳","矸","竿","筸","粓","肝","苷","迀","酐","魐"],"kǎn qiǎn":["凵"],tū:["凸","堗","嶀","捸","涋","湥","痜","禿","秃","突","葖","鋵","鵚","鼵","㻬"],"āo wā":["凹"],chū:["出","初","岀","摴","榋","樗","貙","齣","䢺","䝙"],dàng:["凼","圵","垱","壋","档","檔","氹","璗","瓽","盪","瞊","砀","碭","礑","簜","荡","菪","蕩","蘯","趤","逿","雼","𬍡"],hán:["函","凾","含","圅","娢","寒","崡","晗","梒","浛","涵","澏","焓","琀","甝","筨","蜬","邗","邯","鋡","韓","韩"],záo:["凿","鑿"],dāo:["刀","刂","忉","氘","舠","螩","釖","魛","鱽"],chuāng:["刅","摐","牎","牕","疮","瘡","窓","窗","窻"],"fēn fèn":["分"],"qiè qiē":["切"],kān:["刊","勘","堪","戡","栞","龕","龛"],cǔn:["刌","忖"],chú:["刍","厨","幮","廚","橱","櫉","櫥","滁","犓","篨","耡","芻","蒢","蒭","蜍","蟵","豠","趎","蹰","躇","躕","鉏","鋤","锄","除","雏","雛","鶵"],"huà huá":["划"],lí:["刕","剓","剺","劙","厘","喱","嚟","囄","嫠","孷","廲","悡","梨","梸","棃","漓","灕","犁","犂","狸","琍","璃","瓈","盠","睝","离","穲","竰","筣","篱","籬","糎","縭","缡","罹","艃","荲","菞","蓠","蔾","藜","蘺","蜊","蟍","蟸","蠫","褵","謧","貍","醨","鋫","錅","鏫","鑗","離","驪","骊","鯏","鯬","鱺","鲡","鵹","鸝","鹂","黎","黧","㰀"],yuè:["刖","嬳","岄","岳","嶽","恱","悅","悦","戉","抈","捳","月","樾","瀹","爚","玥","礿","禴","篗","籆","籥","籰","粤","粵","蘥","蚎","蚏","説","越","跀","跃","躍","軏","鈅","鉞","鑰","钺","閱","閲","阅","鸑","鸙","黦","龠","𫐄","𬸚"],liú:["刘","劉","嚠","媹","嵧","旈","旒","榴","橊","流","浏","瀏","琉","瑠","瑬","璢","畄","留","畱","疁","瘤","癅","硫","蒥","蓅","蟉","裗","鎏","鏐","鐂","镠","飀","飅","飗","駠","駵","騮","驑","骝","鰡","鶹","鹠","麍"],zé:["则","則","啧","嘖","嫧","帻","幘","択","樍","歵","沢","泎","溭","皟","瞔","矠","礋","箦","簀","舴","蔶","蠌","襗","謮","賾","赜","迮","鸅","齚","齰"],"chuàng chuāng":["创","創"],qù:["刞","厺","去","閴","闃","阒","麮","鼁"],"bié biè":["別","别"],"páo bào":["刨"],"chǎn chàn":["刬","剗","幝"],guā:["刮","劀","桰","歄","煱","瓜","胍","踻","颪","颳","騧","鴰","鸹"],gēng:["刯","庚","椩","浭","焿","畊","絚","羮","羹","耕","菮","賡","赓","鶊","鹒"],dào:["到","噵","悼","椡","檤","燾","瓙","盗","盜","稲","稻","纛","翿","艔","菿","衜","衟","軇","道"],chuàng:["刱","剏","剙","怆","愴"],kū:["刳","哭","圐","堀","枯","桍","矻","窟","跍","郀","骷","鮬"],duò:["刴","剁","墯","尮","惰","憜","挅","桗","舵","跥","跺","陊","陏","飿","饳","鵽"],"shuā shuà":["刷"],"quàn xuàn":["券"],"chà shā":["刹","剎"],"cì cī":["刺"],guì:["刽","刿","劊","劌","撌","攰","昋","桂","椢","槶","樻","櫃","猤","禬","筀","蓕","襘","貴","贵","跪","鐀","鑎","鞼","鱖","鱥"],lóu:["剅","娄","婁","廔","楼","樓","溇","漊","熡","耧","耬","艛","蒌","蔞","蝼","螻","謱","軁","遱","鞻","髅","髏","𪣻"],cuò:["剉","剒","厝","夎","挫","措","棤","莝","莡","蓌","逪","銼","錯","锉","错"],"xiāo xuē":["削"],"kēi kè":["剋","尅"],"là lá":["剌"],tī:["剔","梯","踢","銻","锑","鷈","鷉","䏲","䴘"],pōu:["剖"],wān:["剜","塆","壪","帵","弯","彎","湾","潫","灣","睕","蜿","豌"],"bāo bō":["剝","剥"],duō:["剟","咄","哆","嚉","多","夛","掇","毲","畓","裰","㙍"],qíng:["剠","勍","夝","情","擎","晴","暒","棾","樈","檠","氰","甠","硘","葝","黥"],"yǎn shàn":["剡"],"dū zhuó":["剢"],yān:["剦","嫣","崦","嶖","恹","懕","懨","樮","淊","淹","漹","烟","焉","焑","煙","珚","篶","胭","臙","菸","鄢","醃","閹","阉","黫"],huō:["剨","劐","吙","攉","秴","耠","锪","騞","𬴃"],shèng:["剩","剰","勝","圣","墭","嵊","晠","榺","橳","琞","聖","蕂","貹","賸"],"duān zhì":["剬"],wū:["剭","呜","嗚","圬","屋","巫","弙","杇","歍","汙","汚","污","洿","烏","窏","箼","螐","誈","誣","诬","邬","鄔","鎢","钨","鰞","鴮"],gē:["割","哥","圪","彁","戈","戓","戨","歌","滒","犵","肐","袼","謌","鎶","鴚","鴿","鸽"],"dá zhá":["剳"],chuán:["剶","暷","椽","篅","舡","舩","船","輲","遄"],"tuán zhuān":["剸","漙","篿"],"lù jiū":["剹"],pēng:["剻","匉","嘭","怦","恲","抨","梈","烹","砰","軯","駍"],piāo:["剽","勡","慓","旚","犥","翲","螵","飃","飄","飘","魒"],kōu:["剾","彄","抠","摳","眍","瞘","芤","𫸩"],"jiǎo chāo":["剿","劋","勦","摷"],qiāo:["劁","勪","墝","幧","敲","橇","毃","燆","硗","磽","繑","趬","跷","踍","蹺","蹻","郻","鄡","鄥","鍫","鍬","鐰","锹","頝"],"huá huà":["劃"],"zhā zhá":["劄"],"pī pǐ":["劈","悂"],tāng:["劏","嘡","羰","薚","蝪","蹚","鞺","鼞"],chán:["劖","嚵","壥","婵","嬋","巉","廛","棎","毚","湹","潹","潺","澶","瀍","瀺","煘","獑","磛","緾","纏","纒","缠","艬","蝉","蟐","蟬","蟾","誗","讒","谗","躔","鄽","酁","鋋","鑱","镵","饞","馋"],zuān:["劗","躜","躦","鉆","鑚"],mó:["劘","嫫","嬤","嬷","尛","摹","擵","橅","糢","膜","藦","蘑","謨","謩","谟","饃","饝","馍","髍","魔","魹"],zhú:["劚","斸","曯","欘","灟","炢","烛","燭","爥","瘃","竹","笁","笜","舳","茿","蓫","蠋","蠾","躅","逐","逫","钃","鱁"],quàn:["劝","勧","勸","牶","韏"],"jìn jìng":["劤","劲","勁"],kēng:["劥","坑","牼","硁","硜","誙","銵","鍞","鏗","铿","阬"],"xié liè":["劦"],"zhù chú":["助"],nǔ:["努","弩","砮","胬"],shào:["劭","卲","哨","潲","紹","綤","绍","袑","邵"],miǎo:["劰","杪","淼","渺","眇","秒","篎","緲","缈","藐","邈"],kǒu:["劶","口"],wā:["劸","娲","媧","屲","挖","攨","洼","溛","漥","瓾","畖","穵","窊","窪","蛙","韈","鼃"],kuāng:["劻","匡","匩","哐","恇","洭","筐","筺","誆","诓","軭","邼"],hé:["劾","咊","啝","姀","峆","敆","曷","柇","楁","毼","河","涸","渮","澕","熆","皬","盇","盉","盍","盒","禾","篕","籺","粭","翮","菏","萂","覈","訸","詥","郃","釛","鉌","鑉","閡","闔","阂","阖","鞨","頜","餄","饸","魺","鹖","麧","齕","龁","龢","𬌗"],gào:["勂","吿","告","峼","祮","祰","禞","筶","誥","诰","郜","鋯","锆"],"bó bèi":["勃"],láng:["勆","嫏","廊","斏","桹","榔","樃","欴","狼","琅","瑯","硠","稂","艆","蓈","蜋","螂","躴","郒","郞","鋃","鎯","锒"],xūn:["勋","勛","勲","勳","嚑","坃","埙","塤","壎","壦","曛","燻","獯","矄","纁","臐","薫","薰","蘍","醺","𫄸"],"juàn juān":["勌","瓹"],"lè lēi":["勒"],kài:["勓","炌","烗","鎎"],"wěng yǎng":["勜"],qín:["勤","嗪","噙","嶜","庈","懃","懄","捦","擒","斳","檎","澿","珡","琴","琹","瘽","禽","秦","耹","芩","芹","菦","螓","蠄","鈙","鈫","雂","靲","鳹","鵭"],jiàng:["勥","匞","匠","嵹","弜","弶","摾","櫤","洚","滰","犟","糡","糨","絳","绛","謽","酱","醤","醬"],fān:["勫","嬏","帆","幡","忛","憣","旙","旛","繙","翻","藩","轓","颿","飜","鱕"],juān:["勬","姢","娟","捐","涓","蠲","裐","鎸","鐫","镌","鹃"],"tóng dòng":["勭","烔","燑","狪"],lǜ:["勴","垏","嵂","律","慮","氯","滤","濾","爈","箻","綠","繂","膟","葎","虑","鑢"],chè:["勶","坼","彻","徹","掣","撤","澈","烢","爡","瞮","硩","聅","迠","頙","㬚"],sháo:["勺","玿","韶"],"gōu gòu":["勾"],cōng:["匆","囪","囱","忩","怱","悤","暰","樬","漗","瑽","璁","瞛","篵","繱","聡","聦","聪","聰","苁","茐","葱","蓯","蔥","蟌","鍯","鏓","鏦","騘","驄","骢"],"táo yáo":["匋","陶"],páo:["匏","咆","垉","庖","爮","狍","袍","褜","軳","鞄","麅"],dá:["匒","妲","怛","炟","燵","畣","笪","羍","荙","薘","蟽","詚","达","迏","迖","迚","逹","達","鐽","靼","鞑","韃","龖","龘","𫟼"],"huà huā":["化"],"běi bèi":["北"],nǎo:["匘","垴","堖","嫐","恼","悩","惱","瑙","碯","脑","脳","腦"],"chí shi":["匙"],fāng:["匚","堏","方","淓","牥","芳","邡","鈁","錺","钫","鴋"],zā:["匝","咂","帀","沞","臜","臢","迊","鉔","魳"],qiè:["匧","厒","妾","怯","悏","惬","愜","挈","穕","窃","竊","笡","箧","篋","籡","踥","鍥","锲","鯜"],"zāng cáng":["匨"],fěi:["匪","奜","悱","棐","榧","篚","翡","蕜","誹","诽"],"kuì guì":["匮","匱"],suǎn:["匴"],pǐ:["匹","噽","嚭","圮","庀","痞","癖","脴","苉","銢","鴄"],"qū ōu":["区","區"],"kē qià":["匼"],"yǎn yàn":["匽","棪"],biǎn:["匾","惼","揙","碥","稨","窆","藊","褊","貶","贬","鴘"],nì:["匿","堄","嫟","嬺","惄","愵","昵","暱","氼","眤","睨","縌","胒","腻","膩","逆","𨺙"],niàn:["卄","唸","埝","廿","念","惗","艌"],sà:["卅","櫒","脎","萨","蕯","薩","鈒","隡","颯","飒","馺"],zú:["卆","哫","崪","族","箤","足","踤","镞"],shēng:["升","呏","声","斘","昇","曻","枡","殅","泩","湦","焺","牲","珄","生","甥","竔","笙","聲","鉎","鍟","阩","陞","陹","鵿","鼪"],wàn:["卍","卐","忨","杤","瞣","脕","腕","萬","蟃","贎","輐","錽","𬇕"],"huá huà huā":["华","華"],bēi:["卑","悲","揹","杯","桮","盃","碑","藣","鵯","鹎"],"zú cù":["卒"],"dān shàn chán":["单","單"],"nán nā":["南"],"shuài lǜ":["卛"],"bǔ bo pú":["卜"],"kuàng guàn":["卝"],biàn:["卞","变","変","峅","弁","徧","忭","抃","昪","汳","汴","玣","艑","苄","覍","諚","變","辡","辧","辨","辩","辫","辮","辯","遍","釆","𨚕"],bǔ:["卟","哺","捕","补","補","鸔","𬷕"],"zhàn zhān":["占","覱"],"kǎ qiǎ":["卡"],lú:["卢","嚧","垆","壚","庐","廬","曥","枦","栌","櫨","泸","瀘","炉","爐","獹","玈","瓐","盧","矑","籚","纑","罏","胪","臚","舮","舻","艫","芦","蘆","蠦","轤","轳","鈩","鑪","顱","颅","馿","髗","魲","鱸","鲈","鸕","鸬","黸","𬬻"],lǔ:["卤","塷","掳","擄","樐","橹","櫓","氌","滷","澛","瀂","硵","磠","穞","艣","艪","蓾","虏","虜","鏀","鐪","鑥","镥","魯","鲁","鹵"],guà:["卦","啩","挂","掛","罣","褂","詿","诖"],"áng yǎng":["卬"],yìn:["印","垽","堷","廕","慭","憖","憗","懚","洕","湚","猌","癊","胤","茚","酳","鮣","䲟"],què:["却","卻","塙","崅","悫","愨","慤","搉","榷","燩","琷","皵","确","確","礭","闋","阕","鵲","鹊","𬒈"],luǎn:["卵"],"juàn juǎn":["卷","巻"],"chǎng ān hàn":["厂"],"wěi yán":["厃"],tīng:["厅","厛","听","庁","廰","廳","汀","烃","烴","綎","耓","聴","聼","聽","鞓","𬘩"],"zhé zhái":["厇"],"hàn àn":["厈","屽"],yǎ:["厊","唖","庌","痖","瘂","蕥"],shè:["厍","厙","弽","慑","慴","懾","摂","欇","涉","涻","渉","滠","灄","社","舎","蔎","蠂","設","设","赦","騇","麝"],dǐ:["厎","呧","坘","弤","抵","拞","掋","牴","砥","菧","觝","詆","诋","軧","邸","阺","骶","鯳"],"zhǎ zhǎi":["厏"],páng:["厐","嫎","庞","徬","舽","螃","逄","鰟","鳑","龎","龐"],"zhì shī":["厔"],máng:["厖","吂","哤","娏","忙","恾","杗","杧","汒","浝","牻","痝","盲","硭","笀","芒","茫","蘉","邙","釯","鋩","铓","駹"],zuī:["厜","樶","纗","蟕"],"shà xià":["厦","廈"],áo:["厫","嗷","嗸","廒","敖","滶","獒","獓","璈","翱","翶","翺","聱","蔜","螯","謷","謸","遨","鏖","隞","鰲","鳌","鷔","鼇"],"lán qiān":["厱"],"sī mǒu":["厶"],"gōng hóng":["厷"],"lín miǎo":["厸"],"qiú róu":["厹"],dū:["厾","嘟","督","醏"],"xiàn xuán":["县","縣"],"cān shēn cēn sān":["参","參","叄","叅"],"ài yǐ":["叆"],"chā chà chǎ chá":["叉"],shuāng:["双","孀","孇","欆","礵","艭","雙","霜","騻","驦","骦","鷞","鸘","鹴"],shōu:["収","收"],guái:["叏"],bá:["叐","妭","抜","拔","炦","癹","胈","茇","菝","詙","跋","軷","魃","鼥"],"fā fà":["发"],"zhuó yǐ lì jué":["叕"],qǔ:["取","娶","竬","蝺","詓","齲","龋"],"jiǎ xiá":["叚","徦"],"wèi yù":["叞","尉","蔚"],dié:["叠","垤","堞","峌","幉","恎","惵","戜","曡","殜","氎","牃","牒","瓞","畳","疂","疉","疊","碟","絰","绖","耊","耋","胅","艓","苵","蜨","蝶","褋","詄","諜","谍","跮","蹀","迭","镻","鰈","鲽","鴩","𫶇"],ruì:["叡","枘","汭","瑞","睿","芮","蚋","蜹","銳","鋭","锐"],"jù gōu":["句"],lìng:["另","呤","炩","蘦"],"dāo dáo tāo":["叨"],"zhī zhǐ":["只"],jiào:["叫","呌","嘂","嘦","噍","嬓","斍","斠","滘","漖","獥","珓","皭","窖","藠","訆","譥","趭","較","轎","轿","较","酵","醮","釂"],"zhào shào":["召"],"kě kè":["可"],"tái tāi":["台","苔"],pǒ:["叵","尀","笸","箥","鉕","钷","駊"],"yè xié":["叶"],"hào háo":["号"],tàn:["叹","嘆","探","歎","湠","炭","碳","舕"],"hōng hóng":["叿"],miē:["吀","咩","哶","孭"],"xū yū yù":["吁"],chī:["吃","哧","喫","嗤","噄","妛","媸","彨","彲","摛","攡","殦","瓻","痴","癡","眵","瞝","笞","粚","胵","蚩","螭","訵","魑","鴟","鵄","鸱","黐","齝","𫄨"],"xuān sòng":["吅"],yāo:["吆","喓","夭","妖","幺","楆","殀","祅","腰","葽","訞","邀","鴁","鴢","㙘"],zǐ:["吇","姉","姊","子","杍","梓","榟","橴","滓","矷","秭","笫","籽","紫","耔","虸","訿","釨"],"hé gě":["合","鲄"],"cùn dòu":["吋"],"tóng tòng":["同"],"tǔ tù":["吐","唋"],"zhà zhā":["吒","奓"],"xià hè":["吓"],"ā yā":["吖"],"ma má mǎ":["吗"],lìn:["吝","恡","悋","橉","焛","甐","膦","蔺","藺","賃","赁","蹸","躏","躙","躪","轥","閵"],tūn:["吞","暾","朜","焞"],"bǐ pǐ":["吡"],qìn:["吢","吣","唚","抋","揿","搇","撳","沁","瀙","菣","藽"],"jiè gè":["吤"],"fǒu pǐ":["否"],"ba bā":["吧"],dūn:["吨","噸","墩","墪","惇","撉","撴","犜","獤","礅","蜳","蹾","驐"],fēn:["吩","帉","昐","朆","梤","棻","氛","竕","紛","纷","翂","芬","衯","訜","躮","酚","鈖","雰","餴","饙","馚"],"é huā":["吪"],"kēng háng":["吭","妔"],shǔn:["吮"],"zhī zī":["吱"],"yǐn shěn":["吲"],wú:["吳","吴","呉","墲","峿","梧","橆","毋","洖","浯","無","珸","璑","祦","芜","茣","莁","蕪","蜈","蟱","譕","郚","鋙","铻","鯃","鵐","鷡","鹀","鼯"],"chǎo chāo":["吵"],"nà nè":["吶"],"xuè chuò jué":["吷"],chuī:["吹","炊","龡"],"dōu rú":["吺"],hǒu:["吼","犼"],"hōng hǒu ōu":["吽"],"wú yù":["吾"],"ya yā":["呀"],"è e":["呃"],dāi:["呆","懛","獃"],"mèn qǐ":["呇"],hōng:["呍","嚝","揈","灴","烘","焢","硡","薨","訇","谾","軣","輷","轟","轰","鍧"],nà:["呐","捺","笝","納","纳","肭","蒳","衲","豽","貀","軜","郍","鈉","钠","靹","魶"],"tūn tiān":["呑"],"fǔ ḿ":["呒","嘸"],"dāi tǎi":["呔"],"ǒu ōu òu":["呕"],"bài bei":["呗"],"yuán yún yùn":["员","員"],guō:["呙","啯","嘓","埚","堝","墎","崞","彉","彍","懖","猓","瘑","聒","蝈","蟈","郭","鈛","鍋","锅"],"huá qì":["呚"],"qiàng qiāng":["呛","跄"],shī:["呞","失","尸","屍","师","師","施","浉","湤","湿","溮","溼","濕","狮","獅","瑡","絁","葹","蒒","蓍","虱","蝨","褷","襹","詩","诗","邿","釃","鉇","鍦","鯴","鰤","鲺","鳲","鳾","鶳","鸤","䴓","𫚕"],juǎn:["呟","埍","臇","菤","錈","锩"],pěn:["呠","翸"],"wěn mǐn":["呡"],"ne ní":["呢"],"ḿ m̀ móu":["呣"],rán:["呥","嘫","然","燃","繎","肰","蚦","蚺","衻","袇","袡","髥","髯"],"tiè chè":["呫"],"qì zhī":["呮"],"zǐ cī":["呰"],"guā gū guǎ":["呱"],"cī zī":["呲"],"hǒu xǔ gòu":["呴"],"hē ā á ǎ à a":["呵"],náo:["呶","夒","峱","嶩","巎","挠","撓","猱","硇","蛲","蟯","詉","譊","鐃","铙"],"xiā gā":["呷"],pēi:["呸","怌","肧","胚","衃","醅"],"háo xiāo":["呺"],mìng:["命","掵"],"dá dàn":["呾"],"zuǐ jǔ":["咀"],"xián gān":["咁"],pǒu:["咅","哣","犃"],"yǎng yāng":["咉"],"zǎ zé zhā":["咋"],"hé hè huó huò hú":["和"],hāi:["咍"],dā:["咑","哒","噠","墶","搭","撘","耷","褡","鎝","𨱏"],"kǎ kā":["咔"],gū:["咕","唂","唃","姑","嫴","孤","巬","巭","柧","橭","沽","泒","稒","笟","箍","箛","篐","罛","苽","菇","菰","蓇","觚","軱","軲","轱","辜","酤","鈲","鮕","鴣","鸪"],"kā gā":["咖"],zuo:["咗"],lóng:["咙","嚨","嶐","巃","巄","昽","曨","朧","栊","槞","櫳","湰","滝","漋","爖","珑","瓏","癃","眬","矓","砻","礱","礲","窿","竜","聋","聾","胧","茏","蘢","蠪","蠬","襱","豅","鏧","鑨","霳","靇","驡","鸗","龍","龒","龙"],"xiàn xián":["咞"],qì:["咠","唭","噐","器","夡","弃","憇","憩","暣","棄","欫","气","気","氣","汔","汽","泣","湆","湇","炁","甈","盵","矵","碛","碶","磜","磧","罊","芞","葺","藒","蟿","訖","讫","迄","鐑"],"xì dié":["咥"],"liē liě lié lie":["咧"],zī:["咨","嗞","姕","姿","孜","孳","孶","崰","嵫","栥","椔","淄","湽","滋","澬","玆","禌","秶","粢","紎","緇","緕","纃","缁","茊","茲","葘","諮","谘","貲","資","赀","资","赼","趑","趦","輜","輺","辎","鄑","鈭","錙","鍿","鎡","锱","镃","頾","頿","髭","鯔","鰦","鲻","鶅","鼒","齍","齜","龇"],mī:["咪"],"jī xī qià":["咭"],"gē luò kǎ lo":["咯"],"shù xún":["咰"],"zán zá zǎ zan":["咱"],"hāi ké":["咳"],huī:["咴","噅","噕","婎","媈","幑","徽","恢","拻","挥","揮","晖","暉","楎","洃","瀈","灰","灳","烣","睳","禈","翚","翬","蘳","袆","褘","詼","诙","豗","輝","辉","鰴","麾","㧑"],"huài shì":["咶"],táo:["咷","啕","桃","檮","洮","淘","祹","綯","绹","萄","蜪","裪","迯","逃","醄","鋾","鞀","鞉","饀","駣","騊","鼗","𫘦"],xián:["咸","啣","娴","娹","婱","嫌","嫺","嫻","弦","挦","撏","涎","湺","澖","甉","痫","癇","癎","絃","胘","舷","藖","蚿","蛝","衔","衘","誸","諴","賢","贒","贤","輱","醎","銜","鑦","閑","闲","鷳","鷴","鷼","鹇","鹹","麙","𫍯"],"è àn":["咹"],"xuān xuǎn":["咺","烜"],"wāi hé wǒ guǎ guō":["咼"],"yàn yè yān":["咽"],āi:["哀","哎","埃","溾","銰","鎄","锿"],pǐn:["品","榀"],shěn:["哂","婶","嬸","审","宷","審","弞","曋","渖","瀋","瞫","矤","矧","覾","訠","諗","讅","谂","谉","邥","頣","魫"],"hǒng hōng hòng":["哄"],"wā wa":["哇"],"hā hǎ hà":["哈"],zāi:["哉","栽","渽","溨","災","灾","烖","睵","賳"],"dì diè":["哋"],pài:["哌","沠","派","渒","湃","蒎","鎃"],"gén hěn":["哏"],"yǎ yā":["哑","雅"],"yuě huì":["哕","噦"],nián:["哖","年","秊","秥","鮎","鯰","鲇","鲶","鵇","黏"],"huá huā":["哗","嘩"],"jì jiē zhāi":["哜","嚌"],mōu:["哞"],"yō yo":["哟","喲"],lòng:["哢","梇","贚"],"ò ó é":["哦"],"lī lǐ li":["哩"],"nǎ na nǎi né něi":["哪"],hè:["哬","垎","壑","寉","惒","焃","煂","燺","爀","癋","碋","翯","褐","謞","賀","贺","赫","靍","靎","靏","鶴","鸖","鹤"],"bō pò bā":["哱"],zhé:["哲","啠","喆","嚞","埑","悊","摺","晢","晣","歽","矺","砓","磔","籷","粍","虴","蛰","蟄","袩","詟","謫","謺","讁","讋","谪","輒","輙","轍","辄","辙","鮿"],"liàng láng":["哴"],"liè lǜ":["哷"],hān:["哻","憨","蚶","谽","酣","頇","顸","馠","魽","鼾"],"hēng hng":["哼"],gěng:["哽","埂","峺","挭","梗","綆","绠","耿","莄","郠","骾","鯁","鲠","𬒔"],"chuò yuè":["哾"],"gě jiā":["哿"],"bei bài":["唄"],"hán hàn":["唅"],chún:["唇","浱","湻","滣","漘","犉","純","纯","脣","莼","蒓","蓴","醇","醕","錞","陙","鯙","鶉","鹑","𬭚"],"ài āi":["唉"],"jiá qiǎn":["唊"],"yán dàn xián":["唌"],chē:["唓","砗","硨","莗","蛼"],"wú ńg ń":["唔"],zào:["唕","唣","噪","慥","梍","灶","煰","燥","皁","皂","竃","竈","簉","艁","譟","趮","躁","造","𥖨"],dí:["唙","啇","嘀","嚁","嫡","廸","敌","敵","梑","涤","滌","狄","笛","籴","糴","苖","荻","蔋","蔐","藡","覿","觌","豴","迪","靮","頔","馰","髢","鸐","𬱖"],"gòng hǒng gǒng":["唝","嗊"],dóu:["唞"],"lào láo":["唠","嘮","憦"],huàn:["唤","喚","奂","奐","宦","嵈","幻","患","愌","换","換","擐","攌","梙","槵","浣","涣","渙","漶","澣","烉","焕","煥","瑍","痪","瘓","睆","肒","藧","豢","轘","逭","鯇","鯶","鰀","鲩"],léng:["唥","塄","楞","碐","薐"],"wō wěi":["唩"],fěng:["唪","覂","諷","讽"],"yín jìn":["唫"],"hǔ xià":["唬"],wéi:["唯","围","圍","壝","峗","峞","嵬","帏","帷","幃","惟","桅","沩","洈","涠","湋","溈","潍","潙","潿","濰","犩","矀","維","维","蓶","覹","违","違","鄬","醀","鍏","闈","闱","韋","韦","鮠","𣲗","𬶏"],shuā:["唰"],chàng:["唱","怅","悵","暢","焻","畅","畼","誯","韔","鬯"],"ér wā":["唲"],qiàng:["唴","炝","熗","羻"],yō:["唷"],yū:["唹","淤","瘀","盓","箊","紆","纡","込","迂","迃","陓"],lài:["唻","濑","瀨","瀬","癞","癩","睐","睞","籁","籟","藾","賚","賴","赉","赖","頼","顂","鵣"],tuò:["唾","嶞","柝","毤","毻","箨","籜","萚","蘀","跅"],"zhōu zhāo tiào":["啁"],kěn:["啃","垦","墾","恳","懇","肎","肯","肻","豤","錹"],"zhuó zhào":["啅","濯"],"hēng hèng":["啈","悙"],"lín lán":["啉"],"a ā á ǎ à":["啊"],qiāng:["啌","嗴","嶈","戕","摤","斨","枪","槍","溬","牄","猐","獇","羌","羗","腔","蜣","謒","鏘","锖","锵"],"tūn zhūn xiāng duǐ":["啍"],wèn:["問","妏","揾","搵","璺","问","顐"],"cuì qi":["啐"],"dié shà jié tì":["啑"],"yuē wā":["啘"],"zǐ cǐ":["啙"],"bǐ tú":["啚"],"chuò chuài":["啜"],"yǎ yā è":["啞"],fēi:["啡","婓","婔","扉","暃","渄","猆","緋","绯","裶","霏","非","靟","飛","飝","飞","餥","馡","騑","騛","鯡","鲱","𬴂"],pí:["啤","壀","枇","毗","毘","焷","琵","疲","皮","篺","罴","羆","脾","腗","膍","蚍","蚽","蜱","螷","蠯","豼","貔","郫","鈹","阰","陴","隦","魮","鮍","鲏","鵧","鼙"],shá:["啥"],"lā la":["啦"],"yīng qíng":["啨"],pā:["啪","妑","舥","葩","趴"],"zhě shì":["啫"],sè:["啬","嗇","懎","擌","栜","歮","涩","渋","澀","澁","濇","濏","瀒","瑟","璱","瘷","穑","穡","穯","繬","譅","轖","銫","鏼","铯","飋"],niè:["啮","嗫","噛","嚙","囁","囓","圼","孼","孽","嵲","嶭","巕","帇","敜","枿","槷","櫱","涅","湼","痆","篞","籋","糱","糵","聂","聶","臬","臲","蘖","蠥","讘","踂","踗","踙","蹑","躡","錜","鎳","鑈","鑷","钀","镊","镍","闑","陧","隉","顳","颞","齧","𫔶"],"luō luó luo":["啰","囉"],"tān chǎn tuō":["啴"],bo:["啵","蔔"],dìng:["啶","定","椗","矴","碇","碠","磸","聢","腚","萣","蝊","訂","订","錠","锭","顁","飣","饤"],lāng:["啷"],"án ān":["啽"],kā:["喀","擖"],"yóng yú":["喁"],"lā lá lǎ":["喇"],jiē:["喈","喼","嗟","堦","媘","接","掲","擑","湝","煯","疖","痎","癤","皆","秸","稭","脻","蝔","街","謯","阶","階","鞂","鶛"],hóu:["喉","帿","猴","瘊","睺","篌","糇","翭","葔","鄇","鍭","餱","骺","鯸","𬭤"],"dié zhá":["喋"],wāi:["喎","歪","竵"],"nuò rě":["喏"],"xù huò guó":["喐"],zán:["喒"],"wō ō":["喔"],hú:["喖","嘝","囫","壶","壷","壺","媩","弧","搰","斛","楜","槲","湖","瀫","焀","煳","狐","猢","瑚","瓳","箶","絗","縠","胡","葫","蔛","蝴","螜","衚","觳","醐","鍸","頶","餬","鬍","魱","鰗","鵠","鶘","鶦","鹕"],"huàn yuán xuǎn hé":["喛"],xǐ:["喜","囍","壐","屣","徙","憙","枲","橲","歖","漇","玺","璽","矖","禧","縰","葈","葸","蓰","蟢","謑","蹝","躧","鈢","鉨","鉩","鱚","𬭳","𬶮"],"hē hè yè":["喝"],kuì:["喟","嘳","媿","嬇","愦","愧","憒","篑","簣","籄","聩","聭","聵","膭","蕢","謉","餽","饋","馈"],"zhǒng chuáng":["喠"],"wéi wèi":["喡","為","爲"],"duó zhà":["喥"],"sāng sàng":["喪"],"qiáo jiāo":["喬"],"pèn bēn":["喯"],"cān sūn qī":["喰"],"zhā chā":["喳"],miāo:["喵"],"pēn pèn":["喷"],kuí:["喹","夔","奎","巙","戣","揆","晆","暌","楏","楑","櫆","犪","睽","葵","藈","蘷","虁","蝰","躨","逵","鄈","鍨","鍷","頯","馗","騤","骙","魁"],"lou lóu":["喽"],"zào qiāo":["喿"],"hè xiāo xiào hù":["嗃"],"á shà":["嗄"],xiù:["嗅","岫","峀","溴","珛","琇","璓","秀","綉","繍","繡","绣","螑","袖","褎","褏","銹","鏥","鏽","锈","齅"],"qiāng qiàng":["嗆","戗","戧","蹌","蹡"],"ài yì":["嗌","艾"],"má mǎ ma":["嗎"],"kè kē":["嗑"],"dā tà":["嗒","鎉"],sǎng:["嗓","搡","磉","褬","鎟","顙","颡"],chēn:["嗔","抻","琛","瞋","諃","謓","賝","郴","𬘭"],"wā gǔ":["嗗"],"pǎng bēng":["嗙"],"xián qiǎn qiān":["嗛"],lào:["嗠","嫪","橯","涝","澇","耢","耮","躼","軂","酪"],wēng:["嗡","翁","聬","螉","鎓","鶲","鹟","𬭩"],wà:["嗢","腽","膃","袜","襪","韤"],"hēi hāi":["嗨"],hē:["嗬","欱","蠚","訶","诃"],zi:["嗭"],sǎi:["嗮"],"ǹg ńg ňg":["嗯"],gě:["嗰","舸"],ná:["嗱","拏","拿","鎿","镎"],diǎ:["嗲"],"ài ǎi āi":["嗳"],tōng:["嗵","樋","炵","蓪"],"zuī suī":["嗺"],"zhē zhè zhù zhe":["嗻"],mò:["嗼","圽","塻","墨","妺","嫼","寞","帞","昩","末","枺","歿","殁","沫","漠","爅","獏","瘼","皌","眽","眿","瞐","瞙","砞","礳","秣","絈","纆","耱","茉","莈","蓦","蛨","蟔","貃","貊","貘","銆","鏌","镆","陌","靺","驀","魩","默","黙","𬙊"],sòu:["嗽","瘶"],tǎn:["嗿","坦","忐","憳","憻","暺","毯","璮","菼","袒","襢","醓","鉭","钽"],"jiào dǎo":["嘄"],"kǎi gě":["嘅"],"shān càn":["嘇"],cáo:["嘈","嶆","曹","曺","槽","漕","艚","蓸","螬","褿","鏪","𥕢"],piào:["嘌","徱","蔈","驃"],"lóu lou":["嘍"],gǎ:["尕","玍"],"gǔ jiǎ":["嘏"],"jiāo xiāo":["嘐"],"xū shī":["嘘","噓"],pó:["嘙","嚩","婆","櫇","皤","鄱"],"dē dēi":["嘚"],"ma má":["嘛"],"lē lei":["嘞"],"gā gá gǎ":["嘠"],sāi:["嘥","噻","毢","腮","顋","鰓"],"zuō chuài":["嘬"],"cháo zhāo":["嘲","朝","鼂"],zuǐ:["嘴","噿","嶊","璻"],"qiáo qiào":["嘺","翹","谯"],"chù xù shòu":["嘼"],"tān chǎn":["嘽"],"dàn tán":["嘾","弾","彈","惔","澹"],"hēi mò":["嘿"],ě:["噁","砨","頋","騀","鵈"],"fān bo":["噃"],chuáng:["噇","床","牀"],"cù zā hé":["噈"],"tūn kuò":["噋"],"cēng chēng":["噌"],dēng:["噔","嬁","灯","燈","璒","登","竳","簦","艠","豋"],pū:["噗","扑","撲","攴","攵","潽","炇","陠"],juē:["噘","屩","屫","撧"],lū:["噜","嚕","撸","擼","謢"],zhān:["噡","岾","惉","旃","旜","枬","栴","毡","氈","氊","沾","瞻","薝","蛅","詀","詹","譫","谵","趈","邅","閚","霑","飦","饘","驙","魙","鱣","鸇","鹯","𫗴"],ō:["噢"],"zhòu zhuó":["噣"],"jiào qiào chī":["噭"],yuàn:["噮","妴","怨","愿","掾","瑗","禐","苑","衏","裫","褑","院","願"],"ǎi ài āi":["噯"],"yōng yǒng":["噰","澭"],"jué xué":["噱"],"pēn pèn fèn":["噴"],gá:["噶","尜","釓","錷","钆"],"xīn hěn hèn":["噷"],dāng:["噹","澢","珰","璫","筜","簹","艡","蟷","裆","襠"],làn:["嚂","滥","濫","烂","燗","爁","爛","爤","瓓","糷","钄"],tà:["嚃","嚺","崉","挞","搨","撻","榻","橽","毾","涾","澾","濌","禢","粏","誻","譶","蹋","蹹","躂","躢","遝","錔","闒","闥","闼","阘","鞜","鞳"],"huō huò ǒ":["嚄"],hāo:["嚆","茠","蒿","薅"],"hè xià":["嚇"],"xiù pì":["嚊"],"zhōu chóu":["嚋","盩","诪"],mē:["嚒"],"chā cā":["嚓"],"bó pào bào":["嚗"],"me mèi mò":["嚜"],"xié hái":["嚡"],"áo xiāo":["嚣"],mō:["嚤","摸"],pín:["嚬","娦","嫔","嬪","玭","矉","薲","蠙","貧","贫","顰","颦","𬞟"],mè:["嚰","濹"],"rǎng rāng":["嚷"],lá:["嚹","旯"],"jiáo jué jiào":["嚼"],chuò:["嚽","娖","擉","歠","涰","磭","踀","輟","辍","辵","辶","酫","鑡","餟","齪","龊"],"huān huàn":["嚾"],"zá cà":["囃"],chài:["囆","虿","蠆","袃","訍"],"náng nāng":["囊"],"zá zàn cān":["囋"],sū:["囌","櫯","甦","稣","穌","窣","蘇","蘓","酥","鯂"],zèng:["囎","熷","甑","贈","赠","鋥","锃"],"zá niè yàn":["囐"],nāng:["囔"],"luó luō luo":["囖"],"wéi guó":["囗"],huí:["囘","回","囬","廻","廽","恛","洄","痐","茴","蚘","蛔","蛕","蜖","迴","逥","鮰"],nín:["囜","您","脌"],"jiǎn nān":["囝"],nān:["囡"],tuán:["团","団","團","慱","抟","摶","檲","糰","鏄","鷒","鷻"],"tún dùn":["囤","坉"],guó:["囯","囶","囻","国","圀","國","帼","幗","慖","摑","漍","聝","腘","膕","蔮","虢","馘","𬇹"],kùn:["困","涃","睏"],"wéi tōng":["囲"],qūn:["囷","夋","逡"],rì:["囸","日","衵","鈤","馹","驲"],tāi:["囼","孡","胎"],pǔ:["圃","圑","擈","普","暜","樸","檏","氆","浦","溥","烳","諩","譜","谱","蹼","鐠","镨"],"quān juàn juān":["圈","圏"],"chuí chuán":["圌"],tuǎn:["圕","畽","疃"],lüè:["圙","掠","略","畧","稤","鋝","鋢","锊","䂮"],"huán yuán":["圜"],luán:["圝","圞","奱","娈","孌","孪","孿","峦","巒","挛","攣","曫","栾","欒","滦","灤","癴","癵","羉","脔","臠","虊","銮","鑾","鵉","鸞","鸾"],tǔ:["土","圡","釷","钍"],"xū wéi":["圩"],"dì de":["地","嶳"],"qiān sú":["圱"],zhèn:["圳","塦","挋","振","朕","栚","甽","眹","紖","絼","纼","誫","賑","赈","鋴","鎭","鎮","镇","阵","陣","震","鴆","鸩"],"chǎng cháng":["场","場","塲"],"qí yín":["圻"],jiá:["圿","忦","恝","戞","扴","脥","荚","莢","蛱","蛺","裌","跲","郏","郟","鋏","铗","頬","頰","颊","鴶","鵊"],"zhǐ zhì":["坁"],bǎn:["坂","岅","昄","板","版","瓪","粄","舨","蝂","鈑","钣","阪","魬"],qǐn:["坅","寑","寝","寢","昑","梫","笉","螼","赾","鋟","锓"],"méi fén":["坆"],"rǒng kēng":["坈"],"fāng fáng":["坊"],"fèn bèn":["坋"],tān:["坍","怹","摊","擹","攤","滩","灘","瘫","癱","舑","貪","贪"],"huài pēi pī péi":["坏"],"dì làn":["坔"],tán:["坛","墰","墵","壇","壜","婒","憛","昙","曇","榃","檀","潭","燂","痰","磹","罈","罎","藫","談","譚","譠","谈","谭","貚","郯","醰","錟","顃"],bà:["坝","垻","壩","弝","欛","灞","爸","矲","覇","霸","鮁","鲅"],fén:["坟","墳","妢","岎","幩","枌","棼","汾","焚","燌","燓","羒","羵","蒶","蕡","蚠","蚡","豮","豶","轒","鐼","隫","馩","魵","黂","鼖","鼢","𣸣"],zhuì:["坠","墜","惴","甀","畷","礈","綴","縋","缀","缒","腏","膇","諈","贅","赘","醊","錣","鑆"],pō:["坡","岥","泼","溌","潑","釙","鏺","钋","頗","颇","䥽"],"pǎn bàn":["坢"],kūn:["坤","堃","堒","崐","崑","昆","晜","潉","焜","熴","猑","琨","瑻","菎","蜫","裈","裩","褌","醌","錕","锟","騉","髠","髡","髨","鯤","鲲","鵾","鶤","鹍"],diàn:["坫","垫","墊","壂","奠","婝","店","惦","扂","橂","殿","淀","澱","玷","琔","电","癜","簟","蜔","鈿","電","靛","驔"],"mù mǔ":["坶"],"kē kě":["坷","軻"],xuè:["坹","岤","桖","瀥","狘","瞲","謔","谑","趐"],"dǐ chí":["坻","柢"],lā:["垃","柆","菈","邋"],lǒng:["垄","垅","壟","壠","拢","攏","竉","陇","隴","𬕂"],mín:["垊","姄","岷","崏","捪","旻","旼","民","珉","琘","琝","瑉","痻","盿","砇","緍","緡","缗","罠","苠","鈱","錉","鍲","鴖"],"dòng tóng":["垌","峒","洞"],cí:["垐","嬨","慈","柌","濨","珁","瓷","甆","磁","礠","祠","糍","茨","詞","词","辝","辞","辤","辭","雌","飺","餈","鴜","鶿","鷀","鹚"],duī:["垖","堆","塠","痽","磓","鐓","鐜","鴭"],"duò duǒ":["垛"],"duǒ duò":["垜","挆"],chá:["垞","察","嵖","搽","槎","檫","猹","茬","茶","詧","靫","𥻗"],shǎng:["垧","晌","樉","賞","贘","赏","鋿","鏛","鑜"],shǒu:["垨","守","手","扌","艏","首"],da:["垯","繨","跶"],háng:["垳","斻","杭","筕","絎","绗","航","苀","蚢","裄","貥","迒","頏","颃","魧"],"ān ǎn":["垵"],xīng:["垶","惺","星","曐","煋","猩","瑆","皨","篂","腥","興","觪","觲","謃","騂","骍","鮏","鯹"],"yuàn huán":["垸"],bāng:["垹","帮","幇","幚","幫","捠","梆","浜","邦","邫","鞤","𠳐"],"póu fú":["垺"],cén:["埁","岑","涔"],"běng fēng":["埄"],"dì fáng":["埅"],"xiá jiā":["埉"],"mái mán":["埋"],làng:["埌","崀","浪","蒗","閬","㫰"],"shān yán":["埏"],"qín jīn":["埐"],"pǔ bù":["埔"],huā:["埖","婲","椛","硴","糀","花","蒊","蘤","誮","錵"],"suì sù":["埣"],"pí pì":["埤"],"qīng zhēng":["埥","鲭"],"wǎn wān":["埦"],lǔn:["埨","稐","𫭢"],"zhēng chéng":["埩"],kōng:["埪","崆","箜","躻","錓","鵼"],"cǎi cài":["埰","寀","采"],"chù tòu":["埱"],běng:["埲","琫","菶","鞛"],"kǎn xiàn":["埳"],"yì shì":["埶","醳"],péi:["培","毰","裴","裵","賠","赔","錇","锫","阫","陪"],"sào sǎo":["埽"],"jǐn qīn jìn":["堇"],"péng bèng":["堋"],"qiàn zàn jiàn":["堑"],àn:["堓","屵","岸","按","暗","案","胺","荌","豻","貋","錌","闇","隌","黯"],"duò huī":["堕","墮"],huán:["堚","寏","寰","峘","桓","洹","澴","獂","环","環","糫","繯","缳","羦","荁","萈","萑","豲","鍰","鐶","锾","镮","闤","阛","雈","鬟","鹮","𬘫","𤩽"],"bǎo bǔ pù":["堡"],"máo móu wǔ":["堥"],ruán:["堧","壖","撋"],"ài è yè":["堨"],gèng:["堩","暅"],méi:["堳","塺","媒","嵋","徾","攗","枚","栂","梅","楣","楳","槑","湄","湈","煤","猸","玫","珻","瑂","眉","睂","禖","脄","脢","腜","苺","莓","葿","郿","酶","鎇","镅","霉","鶥","鹛","黴"],dǔ:["堵","琽","睹","笃","篤","覩","賭","赌"],féng:["堸","綘","艂","逢"],hèng:["堼"],chūn:["堾","媋","旾","春","暙","杶","椿","槆","橁","櫄","瑃","箺","萅","蝽","輴","鰆","鶞","䲠"],jiǎng:["塂","奖","奨","奬","桨","槳","獎","耩","膙","蒋","蔣","講","讲","顜"],huāng:["塃","巟","慌","肓","荒","衁"],duàn:["塅","断","斷","椴","段","毈","煅","瑖","碫","簖","籪","緞","缎","腶","葮","躖","鍛","锻"],tǎ:["塔","墖","獭","獺","鮙","鰨","鳎"],wěng:["塕","奣","嵡","攚","暡","瞈","蓊"],"sāi sài sè":["塞"],zàng:["塟","弉","臓","臟","葬","蔵","銺"],tián:["塡","屇","恬","沺","湉","璳","甛","甜","田","畋","畑","碵","磌","胋","闐","阗","鴫","鷆","鷏"],zhèng:["塣","幁","政","証","諍","證","证","诤","郑","鄭","靕","鴊"],"tián zhèn":["填"],wēn:["塭","昷","榲","殟","温","溫","瑥","瘟","蕰","豱","輼","轀","辒","鎾","饂","鰛","鰮","鳁"],liù:["塯","廇","磟","翏","雡","霤","餾","鬸","鷚","鹨"],hǎi:["塰","海","烸","酼","醢"],lǎng:["塱","朖","朗","朤","烺","蓢","㮾"],bèng:["塴","揼","泵","甏","綳","蹦","迸","逬","鏰","镚"],chén:["塵","宸","尘","忱","敐","敶","晨","曟","栕","樄","沉","煁","瘎","臣","茞","莀","莐","蔯","薼","螴","訦","諶","軙","辰","迧","鈂","陈","陳","霃","鷐","麎"],"ōu qiū":["塸"],"qiàn jiàn":["塹"],"zhuān tuán":["塼"],shuǎng:["塽","慡","漺","爽","縔","鏯"],shú:["塾","婌","孰","璹","秫","贖","赎"],lǒu:["塿","嵝","嶁","甊","篓","簍"],chí:["墀","弛","持","池","漦","竾","筂","箎","篪","茌","荎","蚳","謘","貾","赿","踟","迟","迡","遅","遟","遲","鍉","馳","驰"],shù:["墅","庶","庻","怷","恕","戍","束","树","樹","沭","漱","潄","濖","竖","竪","絉","腧","荗","蒁","虪","術","裋","豎","述","鉥","錰","鏣","霔","鶐","𬬸"],"dì zhì":["墆","疐"],kàn:["墈","崁","瞰","矙","磡","衎","鬫"],chěn:["墋","夦","硶","碜","磣","贂","趻","踸","鍖"],"zhǐ zhuó":["墌"],qiǎng:["墏","繈","繦","羥","襁"],zēng:["増","增","憎","璔","矰","磳","罾","譄","鄫","鱛","䎖"],qiáng:["墙","墻","嫱","嬙","樯","檣","漒","牆","艢","蔃","蔷","蘠"],"kuài tuí":["墤"],"tuǎn dǒng":["墥"],"qiáo què":["墧"],"zūn dūn":["墫"],"qiāo áo":["墽"],"yì tú":["墿"],"xué bó jué":["壆"],lǎn:["壈","嬾","孄","孏","懒","懶","揽","擥","攬","榄","欖","浨","漤","灠","纜","缆","罱","覧","覽","览","醂","顲"],huài:["壊","壞","蘾"],rǎng:["壌","壤","攘","爙"],"làn xiàn":["壏"],dǎo:["壔","导","導","岛","島","嶋","嶌","嶹","捣","搗","擣","槝","祷","禂","禱","蹈","陦","隝","隯"],ruǐ:["壡","桵","橤","繠","蕊","蕋","蘂","蘃"],san:["壭"],zhuàng:["壮","壯","壵","撞","焋","状","狀"],"ké qiào":["壳","殼"],kǔn:["壸","壼","悃","捆","梱","硱","祵","稇","稛","綑","裍","閫","閸","阃"],mǎng:["壾","漭","茻","莽","莾","蠎"],cún:["壿","存"],"zhǐ zhōng":["夂"],"gǔ yíng":["夃"],"jiàng xiáng":["夅","降"],"páng féng fēng":["夆"],zhāi:["夈","捚","摘","斋","斎","榸","粂","齋"],"xuàn xiòng":["夐"],wài:["外","顡"],"wǎn yuàn wān yuān":["夗"],"mǎo wǎn":["夘"],mèng:["夢","夣","孟","梦","癦","霥"],"dà dài":["大"],"fū fú":["夫","姇","枎","粰"],guài:["夬","怪","恠"],yāng:["央","姎","抰","殃","泱","秧","胦","鉠","鍈","雵","鴦","鸯"],"hāng bèn":["夯"],gǎo:["夰","搞","杲","槀","槁","檺","稁","稾","稿","縞","缟","菒","藁","藳"],"tāo běn":["夲"],"tóu tou":["头"],"yǎn tāo":["夵"],"kuā kuà":["夸","誇"],"jiá jiā gā xiá":["夹"],huà:["夻","婳","嫿","嬅","崋","摦","杹","枠","桦","槬","樺","澅","画","畫","畵","繣","舙","話","諙","譮","话","黊"],"jiā jiá gā xiá":["夾"],ēn:["奀","恩","蒽"],"dī tì":["奃"],"yǎn yān":["奄","渰"],pào:["奅","疱","皰","砲","礟","礮","靤","麭"],nài:["奈","柰","渿","耐","萘","褦","錼","鼐"],"quān juàn":["奍","弮","棬"],zòu:["奏","揍"],"qì qiè xiè":["契"],kāi:["奒","开","揩","鐦","锎","開"],"bēn bèn":["奔","泍"],tào:["套"],"zàng zhuǎng":["奘"],běn:["奙","本","楍","畚","翉","苯"],"xùn zhuì":["奞"],shē:["奢","檨","猞","畭","畲","賒","賖","赊","輋","𪨶"],"hǎ pò tǎi":["奤"],"ào yù":["奥","奧","澚"],yūn:["奫","氲","氳","蒀","蒕","蝹","贇","赟","𫖳"],"duǒ chě":["奲"],"nǚ rǔ":["女"],nú:["奴","孥","笯","駑","驽"],"dīng dǐng tiǎn":["奵"],"tā jiě":["她"],nuán:["奻"],"hǎo hào":["好"],fàn:["奿","嬎","梵","汎","泛","滼","瀪","犯","畈","盕","笵","範","范","訉","販","贩","軬","輽","飯","飰","饭"],shuò:["妁","搠","朔","槊","烁","爍","矟","蒴","鎙","鑠","铄"],"fēi pèi":["妃"],wàng:["妄","忘","旺","望","朢"],zhuāng:["妆","妝","娤","庄","庒","桩","梉","樁","粧","糚","荘","莊","装","裝"],mā:["妈","媽"],"fū yōu":["妋"],"hài jiè":["妎"],dù:["妒","妬","杜","殬","渡","秺","芏","荰","螙","蠧","蠹","鍍","镀","靯","𬭊"],miào:["妙","庙","庿","廟","玅","竗"],"fǒu pēi pī":["妚"],"yuè jué":["妜"],niū:["妞"],"nà nàn":["妠"],tuǒ:["妥","嫷","庹","椭","楕","橢","鬌","鰖","鵎"],"wàn yuán":["妧"],fáng:["妨","房","肪","防","魴","鲂"],nī:["妮"],zhóu:["妯","碡"],zhāo:["妱","巶","招","昭","釗","鉊","鍣","钊","駋","𬬿"],"nǎi nǐ":["妳"],tǒu:["妵","敨","紏","蘣","黈"],"xián xuán xù":["妶"],"zhí yì":["妷","秇"],ē:["妸","妿","婀","屙"],mèi:["妹","媚","寐","抺","旀","昧","沬","煝","痗","眛","睸","祙","篃","蝞","袂","跊","鬽","魅"],"qī qì":["妻"],"xū xǔ":["姁","稰"],"shān shàn":["姍","姗","苫","釤","钐"],mán:["姏","慲","樠","蛮","蠻","謾","饅","馒","鬗","鬘","鰻","鳗"],jiě:["姐","媎","檞","毑","飷"],"wěi wēi":["委"],pīn:["姘","拼","礗","穦","馪","驞"],"huá huó":["姡"],"jiāo xiáo":["姣"],"gòu dù":["姤"],"lǎo mǔ":["姥"],"nián niàn":["姩"],zhěn:["姫","屒","弫","抮","昣","枕","畛","疹","眕","稹","縝","縥","缜","聄","萙","袗","裖","覙","診","诊","軫","轸","辴","駗","鬒"],héng:["姮","恆","恒","烆","珩","胻","蘅","衡","鑅","鴴","鵆","鸻"],"jūn xún":["姰"],"kuā hù":["姱"],"è yà":["姶"],"xiān shēn":["姺"],wá:["娃"],"ráo rǎo":["娆","嬈"],"shào shāo":["娋"],xiē:["娎","揳","楔","歇","蝎","蠍"],"wǔ méi mǔ":["娒"],"chuò lài":["娕"],niáng:["娘","嬢","孃"],"nà nuó":["娜","𦰡"],"pōu bǐ":["娝"],"něi suī":["娞"],tuì:["娧","煺","蛻","蜕","退","駾"],mǎn:["娨","屘","満","满","滿","螨","蟎","襔","鏋"],"wú wù yú":["娪"],"xī āi":["娭"],"zhuì shuì":["娷"],"dōng dòng":["娻"],"ǎi ái è":["娾"],"ē ě":["娿"],mián:["婂","嬵","宀","杣","棉","檰","櫋","眠","矈","矊","矏","綿","緜","绵","芇","蝒"],"pǒu péi bù":["婄"],biǎo:["婊","脿","表","裱","褾","諘","錶"],"fù fàn":["婏"],wǒ:["婐","婑","我"],"ní nǐ":["婗","棿"],"quán juàn":["婘","惓"],hūn:["婚","昏","昬","棔","涽","睧","睯","碈","荤","葷","蔒","轋","閽","阍"],"qiān jǐn":["婜"],"wān wà":["婠"],"lái lài":["婡","徕","徠"],"zhōu chōu":["婤"],"chuò nào":["婥"],"nüè àn":["婩"],"hùn kūn":["婫"],"dàng yáng":["婸"],nàn:["婻"],"ruò chuò":["婼"],jiǎ:["婽","岬","斚","斝","榎","槚","檟","玾","甲","胛","鉀","钾"],"tōu yú":["婾","媮"],"yù yú":["媀"],"wéi wěi":["媁"],"dì tí":["媂","珶","苐"],róu:["媃","揉","柔","渘","煣","瑈","瓇","禸","粈","糅","脜","腬","葇","蝚","蹂","輮","鍒","鞣","騥","鰇","鶔","𫐓"],"ruǎn nèn":["媆"],miáo:["媌","嫹","描","瞄","苗","鶓","鹋"],"yí pèi":["媐"],"mián miǎn":["媔"],"tí shì":["媞","惿"],"duò tuó":["媠","沲"],ǎo:["媪","媼","艹","芺","袄","襖","镺"],"chú zòu":["媰"],yìng:["媵","映","暎","硬","膡","鱦"],"qín shēn":["嫀"],jià:["嫁","幏","架","榢","稼","駕","驾"],sǎo:["嫂"],"zhēn zhěn":["嫃"],"jiē suǒ":["嫅"],"míng mǐng":["嫇"],niǎo:["嫋","嬝","嬲","茑","蔦","袅","裊","褭","鸟"],tāo:["嫍","幍","弢","慆","掏","搯","槄","涛","滔","濤","瑫","絛","縚","縧","绦","詜","謟","轁","鞱","韜","韬","飸","饕"],biáo:["嫑"],"piáo piāo":["嫖","薸"],xuán:["嫙","悬","懸","暶","檈","漩","玄","璇","璿","痃","蜁","𫠊"],"màn mān":["嫚"],kāng:["嫝","嵻","康","慷","槺","漮","砊","穅","糠","躿","鏮","鱇","𡐓","𩾌"],"hān nǎn":["嫨"],nèn:["嫩","嫰"],zhē:["嫬","遮"],"mā má":["嫲"],piè:["嫳"],zhǎn:["嫸","展","搌","斩","斬","琖","盏","盞","輾","醆","颭","飐"],"xiān yǎn jìn":["嬐"],liǎn:["嬚","敛","斂","琏","璉","羷","脸","臉","蔹","蘝","蘞","裣","襝","鄻"],"qióng huán xuān":["嬛"],dǒng:["嬞","懂","箽","董","蕫","諌"],cān:["嬠","湌","爘","飡","餐","驂","骖"],tiǎo:["嬥","宨","晀","朓","窱","脁"],bí:["嬶","荸","鼻"],liǔ:["嬼","柳","栁","桞","桺","橮","熮","珋","綹","绺","罶","羀","鋶","锍"],"qiān xiān":["孅","欦"],"xié huī":["孈"],"huān quán":["孉"],"lí lì":["孋","麗"],"zhú chuò":["孎"],kǒng:["孔","恐"],"mā zī":["孖"],"sūn xùn":["孙","孫"],"bèi bó":["孛","誖"],"yòu niū":["孧"],zhuǎn:["孨","竱","轉"],hái:["孩","骸"],nāo:["孬"],"chán càn":["孱"],bò:["孹","檗","蘗","譒"],nái:["孻","腉"],"níng nìng":["宁","寍","寗","寜","寧","甯"],zhái:["宅"],"tū jiā":["宊"],sòng:["宋","訟","誦","讼","诵","送","鎹","頌","颂","餸"],ròu:["宍","肉","譳"],zhūn:["宒","窀","衠","諄","谆","迍"],"mì fú":["宓"],"dàng tàn":["宕"],"wǎn yuān":["宛"],chǒng:["宠","寵"],qún:["宭","峮","帬","羣","群","裙","裠"],zǎi:["宰","崽"],"bǎo shí":["宲"],"jiā jia jie":["家"],"huāng huǎng":["宺"],kuān:["宽","寛","寬","臗","鑧","髋","髖"],"sù xiǔ xiù":["宿"],"jié zǎn":["寁"],"bìng bǐng":["寎"],"jìn qǐn":["寖"],"lóu jù":["寠"],"xiě xiè":["寫"],"qīn qìn":["寴"],cùn:["寸","籿"],duì:["对","対","對","怼","憝","懟","濧","瀩","碓","祋","綐","薱","譈","譵","轛","队","陮"],"lüè luó":["寽"],"shè yè yì":["射"],"jiāng jiàng qiāng":["将"],"jiāng jiàng":["將","浆","漿","畺"],zūn:["尊","嶟","樽","罇","遵","鐏","鱒","鳟","鶎","鷷","𨱔"],"shù zhù":["尌","澍"],xiǎo:["小","晓","暁","曉","皛","皢","筱","筿","篠","謏","𫍲"],"jié jí":["尐","诘","鞊"],"shǎo shào":["少"],ěr:["尒","尓","尔","栮","毦","洱","爾","珥","耳","薾","衈","趰","迩","邇","鉺","铒","餌","饵","駬"],"wāng yóu":["尢"],wāng:["尣","尩","尪","尫","汪"],liào:["尥","尦","廖","撂","料","炓","窷","鐐","镣","𪤗"],"méng máng lóng páng":["尨"],gà:["尬","魀"],"kuì kuǐ":["尯"],tuí:["尵","弚","穨","蘈","蹪","隤","頹","頺","頽","颓","魋","𬯎"],yǐn:["尹","嶾","引","朄","檃","檼","櫽","淾","濥","瘾","癮","粌","蘟","蚓","螾","讔","赺","趛","輑","鈏","靷"],"chǐ chě":["尺"],kāo:["尻","髛"],"jìn jǐn":["尽"],"wěi yǐ":["尾"],"niào suī":["尿"],céng:["层","層","嶒","驓"],diǎo:["屌"],"píng bǐng bīng":["屏"],lòu:["屚","漏","瘘","瘺","瘻","鏤","镂","陋"],"shǔ zhǔ":["属","屬"],"xiè tì":["屟"],"chè cǎo":["屮"],"tún zhūn":["屯"],"nì jǐ":["屰"],"hóng lóng":["屸"],"qǐ kǎi":["岂","豈"],áng:["岇","昂","昻"],"gǎng gāng":["岗","崗"],kě:["岢","敤","渇","渴","炣"],gǒu:["岣","狗","玽","笱","耇","耈","耉","苟","豿"],tiáo:["岧","岹","樤","祒","笤","芀","萔","蓚","蓨","蜩","迢","鋚","鎥","鞗","髫","鯈","鰷","鲦","齠","龆"],"qū jū":["岨"],lǐng:["岭","嶺","領","领"],pò:["岶","敀","洦","湐","烞","珀","破","砶","粕","蒪","魄"],"bā kè":["峇"],luò:["峈","摞","洛","洜","犖","珞","笿","纙","荦","詻","雒","駱","骆","鵅"],"fù niè":["峊"],ěn:["峎"],"zhì shì":["峙","崻"],qiǎ:["峠","跒","酠","鞐"],"qiáo jiào":["峤","癄"],"xié yé":["峫"],bū:["峬","庯","晡","誧","逋","鈽","錻","钸","餔","鵏"],chóng:["崇","崈","爞","虫","蝩","蟲","褈","隀"],"zú cuì":["崒","椊"],"líng léng":["崚"],"dòng dōng":["崠"],xiáo:["崤","洨","淆","訤","誵"],"pí bǐ":["崥","芘"],"zhǎn chán":["崭","嶃","嶄"],"wǎi wēi":["崴"],"yáng dàng":["崵"],"shì dié":["崼"],yào:["崾","曜","熎","燿","矅","穾","窔","筄","耀","艞","药","葯","薬","藥","袎","覞","詏","讑","靿","鷂","鹞","鼼"],"kān zhàn":["嵁"],"hán dǎng":["嵅"],"qiàn kàn":["嵌"],"wù máo":["嵍"],"kě jié":["嵑","嶱"],"wēi wěi":["嵔"],kē:["嵙","柯","棵","榼","樖","牁","牱","犐","珂","疴","瞌","磕","礚","科","稞","窠","萪","薖","蚵","蝌","趷","轲","醘","鈳","钶","頦","顆","颗","髁"],"dàng táng":["嵣"],"róng yíng":["嵤","爃"],"ái kǎi":["嵦"],"kāo qiāo":["嵪"],cuó:["嵯","嵳","痤","矬","蒫","蔖","虘","鹺","鹾"],"qiǎn qīn":["嵰"],"dì dié":["嵽"],cēn:["嵾"],dǐng:["嵿","艼","薡","鐤","頂","顶","鼎","鼑"],"áo ào":["嶅"],"pǐ pèi":["嶏"],"jiào qiáo":["嶠","潐"],"jué guì":["嶡","鳜"],"zhān shàn":["嶦","鳣"],"xiè jiè":["嶰"],"guī xī juàn":["嶲"],rū:["嶿"],"lì liè":["巁","棙","爄","綟"],"xī guī juàn":["巂"],"yíng hōng":["巆"],yǐng:["巊","廮","影","摬","梬","潁","瘿","癭","矨","穎","郢","鐛","頴","颍","颕","颖"],chǎo:["巐","炒","煼","眧","麨"],cuán:["巑","櫕","欑"],chuān:["巛","川","氚","瑏","穿"],"jīng xíng":["巠"],cháo:["巢","巣","晁","漅","潮","牊","窲","罺","謿","轈","鄛","鼌"],qiǎo:["巧","愀","髜"],gǒng:["巩","廾","拱","拲","栱","汞","珙","輁","鞏"],"chà chā chāi cī":["差"],"xiàng hàng":["巷"],shuài:["帅","帥","蟀"],pà:["帊","帕","怕","袙"],"tǎng nú":["帑"],"mò wà":["帓"],"tiē tiě tiè":["帖"],zhǒu:["帚","晭","疛","睭","箒","肘","菷","鯞"],"juǎn juàn":["帣"],shuì:["帨","涗","涚","睡","稅","税","裞"],"chóu dào":["帱","幬"],"jiǎn jiān sàn":["帴"],"shà qiè":["帹"],"qí jì":["帺","荠"],"shān qiāo shēn":["幓"],"zhuàng chuáng":["幢"],"chān chàn":["幨"],miè:["幭","懱","搣","滅","灭","烕","礣","篾","蔑","薎","蠛","衊","鑖","鱴","鴓"],"gān gàn":["干"],"bìng bīng":["并","幷"],"jī jǐ":["幾"],"guǎng ān":["广"],guǎng:["広","廣","犷","獷"],me:["庅"],"dùn tún":["庉"],"bài tīng":["庍"],"yìng yīng":["应"],"dǐ de":["底"],"dù duó":["度"],"máng méng páng":["庬"],"bìng píng":["庰"],chěng:["庱","悜","睈","逞","騁","骋"],"jī cuò":["庴"],qǐng:["庼","廎","檾","漀","苘","請","謦","请","頃","顷"],"guī wěi huì":["廆"],"jǐn qín":["廑"],kuò:["廓","扩","拡","擴","濶","筈","萿","葀","蛞","闊","阔","霩","鞟","鞹","韕","頢","鬠"],"qiáng sè":["廧","薔"],"yǐn yìn":["廴","隐","隠","隱","飮","飲","饮"],"pò pǎi":["廹","迫"],"nòng lòng":["弄"],"dì tì tuí":["弟"],"jué zhāng":["弡"],"mí mǐ":["弥","彌","靡"],chāo:["弨","怊","抄","欩","訬","超","鈔","钞"],yi:["弬"],shāo:["弰","旓","烧","焼","燒","筲","艄","萷","蕱","輎","髾","鮹"],"xuān yuān":["弲"],"qiáng qiǎng jiàng":["強","强"],"tán dàn":["弹","醈"],biè:["彆"],"qiáng jiàng qiǎng":["彊"],"jì xuě":["彐"],tuàn:["彖","褖"],yuē:["彟","曰","曱","矱"],"shān xiǎn":["彡"],wén:["彣","文","炆","珳","瘒","繧","聞","芠","蚉","蚊","螡","蟁","閺","閿","闅","闦","闻","阌","雯","馼","駇","魰","鳼","鴍","鼤","𫘜"],"péng bāng":["彭"],"piāo piào":["彯"],"zhuó bó":["彴"],"tuǒ yí":["彵"],"páng fǎng":["彷"],wǎng:["彺","往","徃","惘","枉","棢","網","网","罒","罓","罔","罖","菵","蛧","蝄","誷","輞","辋","魍"],cú:["徂","殂"],"dài dāi":["待"],huái:["徊","怀","懐","懷","槐","淮","耲","蘹","褢","褱","踝"],"wā wàng jiā":["徍"],"chěng zhèng":["徎"],"dé děi de":["得"],"cóng zòng":["從"],"shì tǐ":["徥"],"tí chí":["徲","鶗","鶙"],dé:["徳","德","恴","悳","惪","淂","鍀","锝"],"zhǐ zhēng":["徴","徵"],bié:["徶","癿","莂","蛂","襒","蹩"],"chōng zhǒng":["徸"],"jiǎo jiào":["徼","笅","筊"],"lòng lǒng":["徿"],"qú jù":["忂","渠","瞿","螶"],"dìng tìng":["忊"],gǎi:["忋","改"],rěn:["忍","栠","栣","秹","稔","綛","荏","荵","躵"],chàn:["忏","懴","懺","硟","羼","韂","顫"],tè:["忑","慝","特","蟘","鋱","铽"],"tè tēi tuī":["忒"],"gān hàn":["忓","攼"],"yì qì":["忔"],"tài shì":["忕"],"xī liě":["忚"],"yīng yìng":["応","應","譍"],"mǐn wěn mín":["忞","忟"],"sōng zhōng":["忪"],"yù shū":["忬","悆"],"qí shì":["忯","耆"],"tún zhūn dùn":["忳"],"qián qín":["忴","扲"],hún:["忶","浑","渾","餛","馄","魂","鼲"],niǔ:["忸","扭","炄","狃","紐","纽","莥","鈕","钮","靵"],"kuáng wǎng":["忹"],"kāng hàng":["忼"],"kài xì":["忾","愾"],òu:["怄","慪"],"bǎo bào":["怉"],"mín mén":["怋"],"zuò zhà":["怍"],zěn:["怎"],yàng:["怏","恙","样","様","樣","漾","羕","詇"],"kòu jù":["怐"],"náo niú":["怓"],"zhēng zhèng":["怔","掙","钲","铮"],"tiē zhān":["怗"],"hù gù":["怘"],"cū jù zū":["怚"],"sī sāi":["思"],"yóu chóu":["怞"],"tū dié":["怢"],"yōu yào":["怮"],xuàn:["怰","昡","楦","泫","渲","炫","琄","眩","碹","絢","縼","繏","绚","蔙","衒","袨","贙","鉉","鏇","铉","镟","颴"],"xù xuè":["怴"],"bì pī":["怶"],"xī shù":["怸"],"nèn nín":["恁"],"tiāo yáo":["恌"],"xī qī xù":["恓"],"xiào jiǎo":["恔"],"hū kuā":["恗"],nǜ:["恧","朒","衂","衄"],hèn:["恨"],"dòng tōng":["恫"],"quán zhuān":["恮"],"è wù ě wū":["恶","惡"],tòng:["恸","慟","憅","痛","衕"],"yuān juàn":["悁"],"qiāo qiǎo":["悄"],"jiè kè":["悈"],"hào jiào":["悎"],huǐ:["悔","檓","毀","毁","毇","燬","譭"],"mán mèn":["悗","鞔"],"yī yì":["悘","衣"],quān:["悛","箞","鐉","𨟠"],"kuī lǐ":["悝"],"yì niàn":["悥"],"mèn mēn":["悶"],guàn:["悹","悺","惯","慣","掼","摜","樌","欟","泴","涫","潅","灌","爟","瓘","盥","礶","祼","罆","罐","貫","贯","躀","遦","鏆","鑵","鱹","鸛","鹳"],"kōng kǒng":["悾"],"lǔn lùn":["惀"],guǒ:["惈","果","椁","槨","粿","綶","菓","蜾","裹","褁","輠","餜","馃"],"yuān wǎn":["惌","箢"],"lán lín":["惏"],"yù xù":["惐","淢"],"chuò chuì":["惙"],"hūn mèn":["惛"],"chǎng tǎng":["惝"],"suǒ ruǐ":["惢"],cǎn:["惨","慘","憯","黪","黲","䅟"],cán:["惭","慙","慚","残","殘","蚕","蝅","蠶","蠺"],"dàn dá":["惮","憚"],rě:["惹"],"yú tōu":["愉"],"kài qì":["愒"],"dàng táng shāng yáng":["愓"],"chén xìn dān":["愖"],"kè qià":["愘"],nuò:["愞","懦","懧","掿","搦","榒","稬","穤","糑","糥","糯","諾","诺","蹃","逽","鍩","锘"],gǎn:["感","擀","敢","桿","橄","澉","澸","皯","秆","稈","笴","芉","衦","赶","趕","鱤","鳡"],"còng sōng":["愡"],"sāi sī sǐ":["愢"],"gōng gòng hǒng":["愩","慐"],"shuò sù":["愬","洬"],"yáo yào":["愮"],huàng:["愰","曂","榥","滉","皝","皩","鎤","㿠"],zhěng:["愸","抍","拯","整","晸"],cǎo:["愺","艸","草","騲"],"xì xié":["慀"],"cǎo sāo":["慅"],"xù chù":["慉"],"qiè qiàn":["慊"],"cáo cóng":["慒"],"ào áo":["慠"],"lián liǎn":["慩","梿","槤","櫣"],"jìn qín jǐn":["慬"],"dì chì":["慸"],"zhí zhé":["慹"],"lóu lǚ":["慺","鷜"],còng:["憁","謥"],"zhī zhì":["憄","知","織","织"],chēng:["憆","摚","撐","撑","晿","柽","棦","橕","檉","泟","浾","琤","瞠","碀","緽","罉","蛏","蟶","赪","赬","鏿","鐣","阷","靗","頳","饓"],biē:["憋","虌","鱉","鳖","鼈","龞"],"chéng dèng zhèng":["憕"],"xǐ xī":["憘"],"duì dùn tūn":["憞"],"xiāo jiāo":["憢"],"xián xiàn":["憪"],"liáo liǎo":["憭","燎","爎","爒"],shéng:["憴","縄","繉","繩","绳","譝"],"náo nǎo náng":["憹"],"jǐng jìng":["憼"],"jǐ jiǎo":["憿"],"xuān huān":["懁"],"cǎo sāo sào":["懆"],mèn:["懑","懣","暪","焖","燜"],"mèng méng měng":["懜"],"ài yì nǐ":["懝"],"méng měng":["懞","瞢","矒"],"qí jī jì":["懠"],mǒ:["懡"],"lán xiàn":["懢"],"yōu yǒu":["懮"],"liú liǔ":["懰","藰"],ràng:["懹","譲","讓","让"],huān:["懽","欢","歓","歡","獾","讙","貛","酄","驩","鴅","鵍"],nǎn:["戁","揇","湳","煵","腩","蝻","赧"],"mí mó":["戂"],"gàng zhuàng":["戅","戆"],"zhuàng gàng":["戇"],"xū qu":["戌"],"xì hū":["戏","戯","戲"],"jiá gā":["戛"],zéi:["戝","蠈","賊","贼","鰂","鱡","鲗"],děng:["戥","等"],"hū xì":["戱"],chuō:["戳","踔","逴"],"biǎn piān":["扁"],"shǎng jiōng":["扄"],"shàn shān":["扇"],cái:["才","材","纔","裁","財","财"],"zhā zā zhá":["扎"],"lè lì cái":["扐"],"bā pá":["扒"],"dǎ dá":["打"],rēng:["扔"],"fǎn fú":["払"],"diǎo dí yuē lì":["扚"],"káng gāng":["扛"],"yū wū":["扜"],"yū wū kū":["扝"],"tuō chǐ yǐ":["扡"],"gǔ jié xì gē":["扢"],dèn:["扥","扽"],"sǎo sào":["扫","掃"],rǎo:["扰","擾","隢"],"xī chā qì":["扱"],"bān pān":["扳"],"bā ào":["扷"],"xī zhé":["扸"],"zhì sǔn kǎn":["扻"],zhǎo:["找","沼","瑵"],"kuáng wǎng zài":["抂"],"hú gǔ":["抇","鹄","鹘"],"bǎ bà":["把"],"dǎn shěn":["抌"],"nè nì ruì nà":["抐"],zhuā:["抓","檛","簻","膼","髽"],póu:["抔","裒"],"zhé shé zhē":["折"],"póu pōu fū":["抙","捊"],pāo:["抛","拋","脬","萢"],"ǎo ào niù":["抝"],"lūn lún":["抡","掄"],"qiǎng qiāng chēng":["抢"],"zhǐ zhǎi":["抧"],"bù pū":["抪","柨"],"yǎo tāo":["抭"],"hē hè qiā":["抲"],"nǐ ní":["抳"],"pī pēi":["抷"],"mǒ mò mā":["抹"],chōu:["抽","犨","犫","瘳","篘"],"jiā yá":["拁"],"fú bì":["拂","畐","鶝"],zhǎ:["拃","眨","砟","鮺","鲝"],"dān dàn dǎn":["担"],"chāi cā":["拆"],niān:["拈","蔫"],"lā lá lǎ là":["拉"],"bàn pàn":["拌"],pāi:["拍"],līn:["拎"],guǎi:["拐","枴","柺"],"tuò tà zhí":["拓"],"ào ǎo niù":["拗"],"jū gōu":["拘"],"pīn pàn fān":["拚"],"bài bái":["拜"],bài:["拝","敗","稗","粺","薭","贁","败","韛"],qiá:["拤"],"nǐng níng nìng":["拧"],"zé zhái":["择","擇"],hén:["拫","痕","鞎"],"kuò guā":["括"],"jié jiá":["拮"],nǐn:["拰"],shuān:["拴","栓","閂","闩"],"cún zùn":["拵"],"zā zǎn":["拶","桚"],kǎo:["拷","攷","栲","烤","考"],"yí chǐ hài":["拸"],"cè sè chuò":["拺"],"zhuài zhuāi yè":["拽"],"shí shè":["拾"],bāi:["挀","掰"],"kuò guāng":["挄"],nòng:["挊","挵","齈"],"jiào jiāo":["挍","敎","教"],"kuà kū":["挎"],"ná rú":["挐"],"tiāo tiǎo":["挑"],"dié shè":["挕"],liě:["挘","毟"],"yà yǎ":["挜","掗"],"wō zhuā":["挝"],"xié jiā":["挟","挾"],"dǎng dàng":["挡","擋"],"zhèng zhēng":["挣","正","症"],"āi ái":["挨"],"tuō shuì":["挩","捝"],"tǐ tì":["挮"],"suō shā":["挱"],"sā shā suō":["挲"],"kēng qiān":["挳","摼"],"bàng péng":["挷"],"ruó ruá":["挼"],"jiǎo kù":["捁"],"wǔ wú":["捂"],tǒng:["捅","桶","筒","筩","統","綂","统","㛚"],"huò chì":["捇"],"tú shū chá":["捈"],"lǚ luō":["捋"],"shāo shào":["捎","稍"],niē:["捏","揑"],"shù sǒng sōu":["捒"],"yé yú":["捓"],"jué zhuó":["捔"],"bù pú zhì":["捗"],zùn:["捘","銌"],lāo:["捞","撈","粩"],sǔn:["损","損","榫","笋","筍","箰","鎨","隼"],"wàn wǎn wān yù":["捥"],pěng:["捧","淎","皏"],shě:["捨"],"fǔ fù bǔ":["捬"],dáo:["捯"],"luò luǒ wǒ":["捰"],"juǎn quán":["捲"],"chēn tiǎn":["捵"],"niǎn niē":["捻"],"ruó wěi ré":["捼"],zuó:["捽","昨","秨","稓","筰","莋","鈼"],"wò xiá":["捾"],"qìng qiàn":["掅"],"póu pǒu":["掊"],qiā:["掐","葜"],"pái pǎi":["排"],"qiān wàn":["掔"],"yè yē":["掖"],"niè nǐ yì":["掜"],"huò xù":["掝"],"yàn shàn yǎn":["掞"],"zhěng dìng":["掟"],kòng:["控","鞚"],tuī:["推","蓷","藬"],"zōu zhōu chōu":["掫"],tiàn:["掭","舚"],kèn:["掯","裉","褃"],pá:["掱","杷","潖","爬","琶","筢"],"guó guāi":["掴"],"dǎn shàn":["掸","撣"],"chān xiān càn shǎn":["掺"],sāo:["掻","搔","溞","繅","缫","螦","騒","騷","鰠","鱢","鳋"],pèng:["掽","椪","槰","碰","踫"],"zhēng kēng":["揁"],"jiū yóu":["揂"],"jiān jiǎn":["揃","籛"],"pì chè":["揊"],"sāi zǒng cāi":["揌"],"tí dī dǐ":["提"],"zǒng sōng":["揔"],"huáng yóng":["揘"],"zǎn zuàn":["揝"],"xū jū":["揟"],"ké qiā":["揢"],"chuāi chuǎi chuài tuán zhuī":["揣"],"dì tì":["揥"],"lá là":["揦"],là:["揧","楋","溂","瓎","瘌","翋","臘","蝋","蝲","蠟","辢","辣","鑞","镴","鬎","鯻","𬶟"],"jiē qì":["揭"],"chòng dǒng":["揰"],"dié shé yè":["揲"],"jiàn qián jiǎn":["揵"],yé:["揶","爷","爺","瑘","鋣","鎁","铘"],chān:["搀","摻","攙","裧","襜","覘","觇","辿","鋓"],"gē gé":["搁","擱"],"lǒu lōu":["搂","摟"],"chōu zǒu":["搊"],chuāi:["搋"],sūn:["搎","槂","狲","猻","荪","蓀","蕵","薞","飧","飱"],"róng náng nǎng":["搑"],"péng bàng":["搒"],cuō:["搓","瑳","磋","蹉","遳","醝"],"kē è":["搕"],"nù nuò nòu":["搙"],"lā xié xiàn":["搚"],qiǔ:["搝","糗"],"xiǎn xiān":["搟"],"jié zhé":["搩"],"pán bān pó":["搫"],bān:["搬","攽","斑","斒","班","瘢","癍","肦","螁","螌","褩","辬","頒","颁","𨭉"],"zhì nái":["搱"],"wā wǎ wà":["搲"],huá:["搳","撶","滑","猾","蕐","螖","譁","鏵","铧","驊","骅","鷨"],"qiāng qiǎng chēng":["搶"],"tián shēn":["搷"],"ná nuò":["搻"],èn:["摁"],"shè niè":["摄","攝"],bìn:["摈","擯","殡","殯","膑","臏","髌","髕","髩","鬂","鬓","鬢"],"shā sà shǎi":["摋"],"chǎn sùn":["摌"],"jiū liú liáo jiǎo náo":["摎"],"féng pěng":["摓"],shuāi:["摔"],"dì tú zhí":["摕"],"qì jì chá":["摖"],"sōu sǒng":["摗"],"liǎn liàn":["摙"],"gài xì":["摡"],"hù chū":["摢"],tàng:["摥","烫","燙","鐋"],"nái zhì":["摨"],"mó mā":["摩"],"jiāng qiàng":["摪"],"áo qiáo":["摮"],"niè chè":["摰"],"mán màn":["摱"],"chàn cán":["摲"],"sè mí sù":["摵"],"biāo biào":["摽"],"juē jué":["撅"],piē:["撆","暼","氕","瞥"],"piě piē":["撇"],"zǎn zān zēn qián":["撍"],"sā sǎ":["撒"],hòng:["撔","訌","讧","闀","鬨"],"héng guàng":["撗"],niǎn:["撚","撵","攆","涊","焾","碾","簐","蹍","蹨","躎","輦","辇"],"chéng zhěng":["撜"],"huī wéi":["撝"],cāo:["撡","操","糙"],"xiāo sōu":["撨"],"liáo liāo":["撩"],"cuō zuǒ":["撮"],"wěi tuǒ":["撱"],cuān:["撺","攛","汆","蹿","躥","鑹","镩"],"qiào yāo jī":["撽"],"zhuā wō":["撾"],"lèi léi":["擂"],nǎng:["擃","攮","曩","灢"],"qíng jǐng":["擏"],kuǎi:["擓","蒯","㧟"],"pǐ bò":["擗"],"bò bāi":["擘"],"jù jǐ":["據"],mēng:["擝"],"sǒu sòu":["擞"],xǐng:["擤","箵","醒"],cā:["擦"],"níng nǐng nìng":["擰"],"zhì jié":["擳"],"là liè":["擸","爉"],"sòu sǒu":["擻"],"lì luò yuè":["擽"],"tī zhāi zhì":["擿"],pān:["攀","潘","眅","萠"],lèi:["攂","泪","涙","淚","禷","类","纇","蘱","酹","銇","錑","頛","頪","類","颣"],"cā sǎ":["攃"],"jùn pèi":["攈"],"lì luò":["攊","躒"],"là lài":["攋","櫴"],"lú luó":["攎"],"zǎn cuán":["攒"],"xiān jiān":["攕"],"mí mǐ mó":["攠"],"zǎn cuán zàn zuān":["攢"],zuàn:["攥"],"lì shài":["攦"],"lì luǒ":["攭"],"guǐ guì":["攱"],"jī qī yǐ":["攲"],fàng:["放"],"wù móu":["敄"],"chù shōu":["敊"],"gé guó è":["敋"],"duó duì":["敓","敚"],"duō què":["敠","敪"],"sàn sǎn":["散"],"dūn duì":["敦","镦"],"qī yǐ jī":["敧"],"xiào xué":["敩"],"shù shǔ shuò":["数","數"],"ái zhú":["敱","敳"],"xiòng xuàn":["敻"],"zhuó zhú":["斀"],"yì dù":["斁"],"lí tái":["斄"],"fěi fēi":["斐"],"yǔ zhōng":["斔"],"dòu dǒu":["斗"],"wò guǎn":["斡"],"tǒu tiǎo":["斢"],dòu:["斣","梪","浢","痘","窦","竇","脰","荳","豆","逗","郖","酘","閗","闘","餖","饾","鬥","鬦","鬪","鬬","鬭"],"yín zhì":["斦"],"chǎn jiè":["斺"],"wū yū yú":["於"],"yóu liú":["斿"],"páng bàng":["旁"],"máo mào":["旄"],"pī bì":["旇"],"xuán xuàn":["旋"],"wú mó":["无"],zǎo:["早","枣","栆","棗","澡","璪","薻","藻","蚤"],gā:["旮"],"gàn hàn":["旰"],"tái yīng":["旲"],"xū xù":["旴"],"tūn zhùn":["旽"],"wù wǔ":["旿"],"pò pèi":["昢"],zòng:["昮","猔","疭","瘲","粽","糉","糭","縦"],ǎi:["昹","毐","矮","蔼","藹","譪","躷","霭","靄"],"huàng huǎng":["晃"],xuǎn:["晅","癣","癬","选","選"],"xù kuā":["晇"],hǒng:["晎"],shài:["晒","曬"],"yūn yùn":["晕","煴"],"shèng chéng":["晟","椉","盛"],"jǐng yǐng":["景"],shǎn:["晱","熌","睒","覢","閃","闪","陕","陝"],"qǐ dù":["晵"],"ǎn àn yǎn":["晻"],"wǎng wàng":["暀"],zàn:["暂","暫","瓉","瓒","瓚","禶","襸","讃","讚","賛","贊","赞","蹔","鄼","錾","鏨","饡"],"yùn yūn":["暈"],"mín mǐn":["暋"],"dǔ shǔ":["暏"],shǔ:["暑","曙","潻","癙","糬","署","薥","薯","藷","蜀","蠴","襡","襩","鱪","鱰","黍","鼠","鼡"],"jiǎn lán":["暕"],nuǎn:["暖","煗","餪"],"bào pù":["暴"],"xī xǐ":["暿"],"pù bào":["曝","瀑"],"qū qǔ":["紶"],"qǔ qū":["曲"],"gèng gēng":["更"],"hū hù":["曶","雽"],"zēng céng":["曽","橧"],"céng zēng":["曾","竲"],"cǎn qián jiàn":["朁"],"qiè hé":["朅"],"bì pí":["朇","禆","笓","裨"],"yǒu yòu":["有"],"bān fén":["朌","鳻"],"fú fù":["服","洑"],"fěi kū":["朏","胐"],"qú xù chǔn":["朐"],"juān zuī":["朘"],"huāng máng wáng":["朚"],"qī jī":["期"],"tóng chuáng":["朣","橦"],zhá:["札","牐","箚","蚻","譗","鍘","铡","閘","闸"],"zhú shù shú":["朮"],"shù shú zhú":["术"],"zhū shú":["朱"],"pǔ pò pō piáo":["朴"],"dāo tiáo mù":["朷"],"guǐ qiú":["朹"],xiǔ:["朽","滫","潃","糔"],"chéng chēng":["朾"],zá:["杂","沯","砸","襍","雑","雜","雥","韴"],"yú wū":["杅"],"gān gǎn":["杆"],"chā chà":["杈"],"shān shā":["杉"],cūn:["村","皴","竴","膥","踆","邨"],"rèn ér":["杒","梕"],"sháo biāo":["杓"],"dì duò":["杕","枤"],"gū gài":["杚"],"yí zhì lí duò":["杝"],"gàng gāng":["杠"],"tiáo tiāo":["条","條"],"mà mǎ":["杩"],"sì zhǐ xǐ":["杫"],"yuán wán":["杬","蚖"],"bèi fèi":["杮"],"shū duì":["杸"],"niǔ chǒu":["杻"],"wò yuè":["枂","臒"],máo:["枆","毛","氂","渵","牦","矛","罞","茅","茆","蝥","蟊","軞","酕","鉾","錨","锚","髦","鶜"],"pī mì":["枈"],àng:["枊","盎","醠"],"fāng bìng":["枋"],"hù dǐ":["枑"],xín:["枔","襑","鐔","鬵"],"yāo yǎo":["枖"],"ě è":["枙"],"zhī qí":["枝"],"cōng zōng":["枞","樅"],"xiān zhēn":["枮"],"tái sì":["枱"],"gǒu jǔ gōu":["枸"],"bāo fú":["枹"],"yì xiè":["枻","栧"],"tuó duò":["柁","馱","駄","驮"],"yí duò lí":["柂"],"nǐ chì":["柅"],"pán bàn":["柈","跘"],"yǎng yàng yāng yīng":["柍"],"fù fū fǔ":["柎"],"bǎi bó bò":["柏"],mǒu:["某"],"sháo shào":["柖"],zhè:["柘","樜","浙","淛","蔗","蟅","這","鷓","鹧","䗪"],"yòu yóu":["柚","櫾"],"guì jǔ":["柜"],"zhà zuò":["柞"],"dié zhì":["柣","眰"],"zhā zǔ zū":["柤"],"chá zhā":["查","査"],"āo ào":["柪","軪"],"bā fú pèi bó biē":["柭"],"duò zuó wù":["柮"],"bì bié":["柲"],"zhù chù":["柷"],"bēi pēi":["柸"],"shì fèi":["柹"],"shān zhà shi cè":["栅"],"lì yuè":["栎","櫟"],"qì qiè":["栔","砌"],"qī xī":["栖","蹊"],"guā kuò":["栝"],"bīng bēn":["栟"],"xiào jiào":["校"],"jiàn zùn":["栫","袸"],"yǒu yù":["栯"],"hé hú":["核"],gēn:["根","跟"],"zhī yì":["栺"],"gé gē":["格"],"héng háng":["桁"],"guàng guāng":["桄"],"yí tí":["桋","荑"],sāng:["桑","桒","槡"],"jú jié":["桔"],"yú móu":["桙"],"ráo náo":["桡","橈"],"guì huì":["桧","檜"],"chén zhèn":["桭"],"tīng yíng":["桯"],"bó po":["桲"],"bèn fàn":["桳"],"fēng fèng":["桻","葑"],"sù yìn":["梀"],"tǐng tìng":["梃"],"xuān juān xié":["梋"],"tú chá":["梌"],"āo yòu":["梎"],kuǎn:["梡","欵","款","歀"],"shāo sào":["梢"],"qín chén cén":["梣"],"lí sì qǐ":["梩"],"chān yán":["梴"],"bīn bīng":["梹","槟","檳"],"táo chóu dào":["梼"],"cōng sōng":["棇"],"gùn hùn":["棍"],"dé zhé":["棏"],"pái bèi pèi":["棑"],"bàng pǒu bèi bēi":["棓"],"dì dài tì":["棣"],sēn:["森","椮","槮","襂"],"rěn shěn":["棯"],"léng lēng líng":["棱"],"fú sù":["棴"],"zōu sǒu":["棷"],zōu:["棸","箃","緅","諏","诹","邹","郰","鄒","鄹","陬","騶","驺","鯫","鲰","黀","齱","齺"],"zhào zhuō":["棹"],"chēn shēn":["棽"],"jiē qiè":["椄"],"yǐ yī":["椅"],"chóu zhòu diāo":["椆"],"qiāng kōng":["椌"],"zhuī chuí":["椎"],"bēi pí":["椑"],mēn:["椚"],"quān juàn quán":["椦"],"duǒ chuán":["椯"],"wěi huī":["椲"],"jiǎ jiā":["椵"],"hán jiān":["椷"],"shèn zhēn":["椹"],"yàn yà":["椻"],"zhā chá":["楂"],"guō kuǎ":["楇"],"jí zhì":["楖"],"kǔ hù":["楛"],"yóu yǒu":["楢"],"sǒng cōng":["楤"],"yuán xuàn":["楥"],"yǎng yàng yīng":["楧"],pián:["楩","胼","腁","賆","蹁","駢","騈","骈","骿","㛹"],"dié yè":["楪"],"dùn shǔn":["楯"],"còu zòu":["楱"],"dì dǐ shì":["楴"],"kǎi jiē":["楷"],"róu ròu":["楺"],"lè yuè":["楽"],"wēn yùn":["榅","鞰"],lǘ:["榈","櫚","氀","膢","藘","閭","闾","驢","驴"],shén:["榊","神","鉮","鰰","𬬹"],"bī pi":["榌"],"zhǎn niǎn zhèn":["榐"],"fú fù bó":["榑"],"jiàn jìn":["榗"],"bǎng bàng":["榜"],"shā xiè":["榝","樧"],nòu:["槈","耨","鎒","鐞"],"qiǎn lián xiàn":["槏"],gàng:["槓","焵","焹","筻","鿍"],gāo:["槔","槹","橰","櫜","睾","篙","糕","羔","臯","韟","餻","高","髙","鷎","鷱","鼛"],"diān zhěn zhēn":["槙"],"kǎn jiàn":["槛"],"xí dié":["槢"],"jī guī":["槣"],"róng yōng":["槦"],"tuán shuàn quán":["槫"],"qì sè":["槭"],"cuī zhǐ":["槯"],"yǒu chǎo":["槱"],"màn wàn":["槾"],"lí chī":["樆"],"léi lěi":["樏","櫑","礌"],"cháo jiǎo chāo":["樔"],"chēng táng":["樘"],"jiū liáo":["樛"],"mó mú":["模"],"niǎo mù":["樢"],"héng hèng":["横","橫"],xuě:["樰","膤","艝","轌","雪","鱈","鳕"],"fá fèi":["橃"],rùn:["橍","润","潤","膶","閏","閠","闰"],"zhǎn jiǎn":["橏"],shùn:["橓","瞚","瞬","舜","蕣","順","顺","鬊"],"tuí dūn":["橔"],"táng chēng":["橖"],"sù qiū":["橚"],"tán diàn":["橝"],"fén fèn fèi":["橨"],"rǎn yān":["橪"],"cū chu":["橻"],"shū qiāo":["橾"],"píng bò":["檘"],"zhái shì tú":["檡"],"biǎo biāo":["檦"],"qiān lián":["檶"],"nǐ mí":["檷"],"jiàn kǎn":["檻"],"nòu ruǎn rú":["檽"],"jī jì":["櫅","禨"],"huǎng guǒ gǔ":["櫎"],"lǜ chū":["櫖"],"miè mèi":["櫗"],ōu:["櫙","欧","歐","殴","毆","瓯","甌","膒","藲","謳","讴","鏂","鴎","鷗","鸥"],"zhù zhuó":["櫡"],"jué jì":["櫭"],"huái guī":["櫰"],"chán zhàn":["欃"],"wéi zuì":["欈"],cáng:["欌","鑶"],"yù yì":["欥"],"chù qù xì":["欪"],"kài ài":["欬"],"yì yīn":["欭"],"xì kài":["欯"],"shuò sòu":["欶"],"ǎi ēi éi ěi èi ê̄ ế ê̌ ề":["欸"],"qī yī":["欹"],"chuā xū":["欻"],"chǐ chuài":["欼"],"kǎn qiàn":["欿"],"kǎn kè":["歁"],"chuǎn chuán":["歂"],"yīn yān":["歅"],"jìn qūn":["歏"],pēn:["歕"],"xū chuā":["歘"],"xī shè":["歙"],"liǎn hān":["歛"],"zhì chí":["歭"],"sè shà":["歰"],sǐ:["死"],"wěn mò":["歾"],piǎo:["殍","皫","瞟","醥","顠"],"qíng jìng":["殑"],"fǒu bó":["殕"],"zhí shi":["殖"],"yè yān yàn":["殗"],"hūn mèi":["殙"],chòu:["殠","臰","遚"],"kuì huì":["殨","溃","潰"],cuàn:["殩","熶","爨","窜","竄","篡","簒"],"yīn yān yǐn":["殷"],"qìng kēng shēng":["殸"],"yáo xiáo xiào":["殽"],"gū gǔ":["毂","蛄"],"guàn wān":["毌"],"dú dài":["毒"],"xún xùn":["毥"],mú:["毪","氁"],"dòu nuò":["毭"],"sāi suī":["毸"],lu:["氇"],sào:["氉","瘙","矂","髞"],"shì zhī":["氏"],"dī dǐ":["氐"],"máng méng":["氓"],"yáng rì":["氜"],shuǐ:["水","氵","氺","閖"],"zhěng chéng zhèng":["氶"],tǔn:["氽"],"fán fàn":["氾"],"guǐ jiǔ":["氿"],"bīn pà pā":["汃"],"zhuó què":["汋"],"dà tài":["汏"],pìn:["汖","牝","聘"],"hàn hán":["汗","馯"],tu:["汢"],"tāng shāng":["汤","湯"],"zhī jì":["汥"],"gàn hán cén":["汵"],"wèn mén":["汶"],"fāng pāng":["汸"],"hǔ huǎng":["汻"],"niú yóu":["汼"],hàng:["沆"],"shěn chén":["沈"],"dùn zhuàn":["沌"],"nǜ niǔ":["沑"],"méi mò":["沒","没"],"tà dá":["沓"],"mì wù":["沕"],"hóng pāng":["沗"],"shā shà":["沙"],"zhuǐ zǐ":["沝"],"ōu òu":["沤","漚"],"jǔ jù":["沮"],"tuō duó":["沰"],"mǐ lì":["沵"],"yí chí":["沶"],"xiè yì":["泄"],"bó pō":["泊"],"mì bì":["泌","秘"],"chù shè":["泏"],"yōu yòu āo":["泑"],"pēng píng":["泙","硑"],"pào pāo":["泡"],"ní nì":["泥","秜"],"yuè sà":["泧"],"jué xuè":["泬","疦"],"lóng shuāng":["泷","瀧"],"luò pō":["泺","濼"],"zé shì":["泽","澤"],"sǎ xǐ":["洒"],"sè qì zì":["洓"],"xǐ xiǎn":["洗"],"kǎo kào":["洘"],"àn yàn è":["洝"],"lěi lèi":["洡"],"qiè jié":["洯"],"qiǎn jiān":["浅"],"jì jǐ":["济","済","濟","纪"],"hǔ xǔ":["浒","滸"],"jùn xùn":["浚","濬"],"yǐng chéng yíng":["浧"],"liàn lì":["浰"],"féng hóng":["浲","溄"],"jiǒng jiōng":["浻"],"suī něi":["浽"],"yǒng chōng":["涌"],"tūn yūn":["涒"],"wō guō":["涡","渦"],hēng:["涥","脝"],"zhǎng zhàng":["涨","漲"],"shòu tāo":["涭"],shuàn:["涮","腨"],"kōng náng":["涳"],"wò wǎn yuān":["涴"],"tuō tuò":["涶"],wō:["涹","猧","窝","窩","莴","萵","蜗","蝸","踒"],"qiè jí":["淁"],"guǒ guàn":["淉"],"lín lìn":["淋","獜","疄"],"tǎng chǎng":["淌"],"nào chuò zhuō":["淖"],"péng píng":["淜"],féi:["淝","肥","腓","蜰"],"pì pèi":["淠"],"niǎn shěn":["淰"],"biāo hǔ":["淲"],"chún zhūn":["淳"],"hùn hún":["混"],qiǎn:["淺","繾","缱","肷","膁","蜸","譴","谴","遣","鑓"],"wèn mín":["渂"],"rè ruò luò":["渃"],"dú dòu":["渎","瀆","读"],"jiàn jiān":["渐","溅","漸","濺"],"miǎn shéng":["渑","澠"],"nuǎn nuán":["渜"],"qiú wù":["渞"],"tíng tīng":["渟"],"dì tí dī":["渧"],"gǎng jiǎng":["港"],"hōng qìng":["渹"],tuān:["湍","煓"],"huì mǐn xū":["湏"],"xǔ xù":["湑"],pén:["湓","瓫","盆","葐"],"mǐn hūn":["湣"],"tuàn nuǎn":["湪"],"qiū jiǎo":["湫","湬"],"yān yīn":["湮"],"bàn pán":["湴"],"zhuāng hún":["湷"],"yàn guì":["溎"],"lián liǎn nián xián xiàn":["溓"],"dá tǎ":["溚","鿎"],"liū liù":["溜","澑","蹓"],lùn:["溣"],mǎ:["溤","犸","獁","玛","瑪","码","碼","遤","鎷","馬","马","鰢","鷌"],"zhēn qín":["溱"],"nì niào":["溺"],"chù xù":["滀","畜"],"wěng wēng":["滃"],"hào xuè":["滈"],"qì xì xiē":["滊"],"xíng yíng":["滎"],"zé hào":["滜"],"piāo piào piǎo":["漂"],"cóng sǒng":["漎"],"féng péng":["漨"],"luò tà":["漯"],"pēng bēn":["漰"],"chóng shuāng":["漴"],"huǒ kuò huò":["漷"],"liáo liú":["漻"],"cuǐ cuī":["漼"],"cóng zǒng":["潀"],"cóng zōng":["潈"],"pì piē":["潎"],"dàng xiàng":["潒"],"huáng guāng":["潢"],"liáo lào lǎo":["潦"],"cōng zòng":["潨"],"zhí zhì":["潪"],"tān shàn":["潬"],"tú zhā":["潳"],"sàn sǎ":["潵"],hēi:["潶","黑","黒","𬭶"],"chéng dèng":["澄","瀓"],"cūn cún":["澊"],"péng pēng":["澎"],"hòng gǒng":["澒","銾"],"wàn màn":["澫"],"kuài huì":["澮"],"guō wō":["濄"],"pēn fén":["濆"],"jí shà":["濈"],"huì huò":["濊"],"dǐng tìng":["濎"],"mǐ nǐ":["濔"],"bì pì":["濞"],"cuì zuǐ":["濢"],"hù huò":["濩"],"ǎi kài kè":["濭"],"wěi duì":["濻","瀢"],"zàn cuán":["濽","灒"],"yǎng yàng":["瀁"],"wǎng wāng":["瀇"],"mò miè":["瀎","眜"],suǐ:["瀡","膸","髓"],"huái wāi":["瀤"],"zùn jiàn":["瀳"],"yīng yǐng yìng":["瀴"],"ráng ràng":["瀼"],shuàng:["灀"],"zhuó jiào zé":["灂"],sǎ:["灑","訯","靸"],"luán luàn":["灓"],"dǎng tǎng":["灙"],"xún quán quàn":["灥"],"huǒ biāo":["灬"],"zhà yù":["灹"],"fén bèn":["炃"],"jiǒng guì":["炅"],"pàng fēng":["炐"],quē:["炔","缺","缼","蒛"],biān:["炞","煸","甂","砭","笾","箯","籩","編","编","蝙","邉","邊","鍽","鞭","鯾","鯿","鳊"],"zhāo zhào":["炤"],"zhuō chù":["炪"],"pào páo bāo":["炮"],"páo fǒu":["炰"],"shǎn qián shān":["炶"],"zhà zhá":["炸"],"jiǎo yào":["烄"],quǎn:["烇","犬","犭","畎","綣","绻","虇"],"yàng yáng":["烊"],"lào luò":["烙"],"huí huǐ":["烠"],rè:["热","熱"],"fú páo":["烰"],"xiè chè":["烲","焎"],"yàn shān":["烻"],"hūn xūn":["焄"],kào:["焅","犒","銬","铐","靠","鮳","鯌","鲓","㸆"],"juān yè":["焆"],"jùn qū":["焌"],"tāo dào":["焘"],"chǎo jù":["焣"],"wò ài":["焥"],"zǒng cōng":["焧"],"xī yì":["焬"],"xìn xīn":["焮"],"chāo zhuō":["焯"],"xiǒng yīng":["焸","焽"],kuǐ:["煃","跬","蹞","頍","𫠆"],"huī yùn xūn":["煇"],"jiǎo qiāo":["煍"],"qián shǎn shān":["煔"],"xī yí":["煕"],"shà shā":["煞"],"yè zhá":["煠"],"yáng yàng":["煬"],"ēn yūn":["煾"],"yūn yǔn":["熅"],"hè xiāo":["熇"],xióng:["熊","熋","雄"],"xūn xùn":["熏","爋"],gòng:["熕","貢","贡"],liū:["熘"],"cōng zǒng":["熜"],"lù āo":["熝"],"shú shóu":["熟"],"fēng péng":["熢"],"cuǐ suī":["熣"],tēng:["熥","膯","鼟"],"yùn yù":["熨"],"áo āo":["熬"],"hàn rǎn":["熯"],"ōu ǒu":["熰"],"huáng huǎng":["熿"],"chǎn dǎn chàn":["燀"],"jiāo zhuó qiáo jué":["燋"],"yàn yān":["燕"],"tài liè":["燤"],āo:["爊"],"yàn xún":["爓"],"jué jiào":["爝","覐","覚","覺","觉"],"lǎn làn":["爦"],"zhuǎ zhǎo":["爪"],"zhǎo zhuǎ":["爫"],"fù fǔ":["父"],diē:["爹","褺","跌"],zāng:["牂","羘","臧","賍","賘","贓","贜","赃","髒"],"piàn piān":["片"],"biān miàn":["牑"],bǎng:["牓","綁","绑"],"yǒu yōng":["牗"],"chēng chèng":["牚","竀"],niú:["牛","牜"],"jiū lè":["牞"],"mù móu":["牟"],māng:["牤"],"gē qiú":["牫"],"yòu chōu":["牰"],"tè zhí":["犆"],bēn:["犇","錛","锛"],"jiān qián":["犍","玪"],má:["犘","痲","蔴","蟇","麻"],"máo lí":["犛"],"bá quǎn":["犮"],"zhuó bào":["犳"],"àn hān":["犴"],"kàng gǎng":["犺"],"pèi fèi":["犻"],"fān huān":["犿"],kuáng:["狂","狅","誑","诳","軖","軠","鵟","𫛭"],"yí quán chí":["狋"],"xīng shēng":["狌"],"tuó yí":["狏"],kǔ:["狜","苦"],"huán huān":["狟"],"hé mò":["狢"],"tà shì":["狧"],"máng dòu":["狵"],"xī shǐ":["狶"],suān:["狻","痠","酸"],"bài pí":["猈"],"jiān yàn":["猏","豣"],"yī yǐ":["猗"],"yá wèi":["猚"],cāi:["猜"],"māo máo":["猫","貓"],"chuàn chuān":["猭"],"tuān tuàn":["猯","貒"],"yà jiá qiè":["猰"],"hè xiē gé hài":["猲"],"biān piàn":["猵","獱"],"bó pò":["猼"],"háo gāo":["獋"],"fén fèn":["獖"],"yào xiāo":["獟"],"shuò xī":["獡"],"gé liè xiē":["獦"],"nòu rú":["獳"],"náo nǎo yōu":["獶"],ráng:["獽","瓤","禳","穣","穰","蘘","躟","鬤"],"náo yōu":["獿"],"lǜ shuài":["率"],"wáng wàng":["王"],"yáng chàng":["玚"],"mín wén":["玟"],"bīn fēn":["玢"],"mén yǔn":["玧"],"qiāng cāng":["玱","瑲","篬"],"án gān":["玵"],"xuán xián":["玹"],"cī cǐ":["玼","跐"],"yí tāi":["珆"],"zǔ jù":["珇"],fà:["珐","琺","蕟","髪","髮"],"yín kèn":["珢"],"huī hún":["珲"],"xuán qióng":["琁"],"fú fū":["琈"],"bǐng pín":["琕"],"cuì sè":["琗"],"yù wéi":["琟"],"tiǎn tiàn":["琠"],"zhuó zuó":["琢"],"běng pěi":["琣"],guǎn:["琯","璭","痯","筦","管","舘","輨","錧","館","馆","鳤"],"hún huī":["琿"],"xié jiē":["瑎"],"chàng dàng yáng":["瑒"],"tiàn zhèn":["瑱"],"bīn pián":["瑸","璸"],"tú shū":["瑹"],cuǐ:["璀","皠","趡"],"zǎo suǒ":["璅"],"jué qióng":["璚"],"lú fū":["璷"],"jì zī":["璾"],suí:["瓍","綏","绥","遀","随","隨","髄"],"mí xǐ":["瓕"],"qióng wěi wèi":["瓗"],"huán yè yà":["瓛"],"bó páo":["瓟"],"zhí hú":["瓡"],piáo:["瓢","闝"],"wǎ wà":["瓦"],"xiáng hóng":["瓨"],wèng:["瓮","甕","罋","蕹","齆"],"shèn shén":["甚"],ruí:["甤","緌","蕤"],yòng:["用","砽","苚","蒏","醟","㶲"],shuǎi:["甩"],béng:["甭","甮"],"yóu zhá":["甴"],"diàn tián shèng":["甸"],"tǐng dīng":["町","甼"],"zāi zī":["甾"],"bì qí":["畁"],"dá fú":["畗"],"cè jì":["畟"],"zāi zī tián":["畠"],"zhì chóu shì":["畤"],"fān pān":["畨","番"],"shē yú":["畬"],"dāng dàng dǎng":["當"],"jiāng qiáng":["疆"],"pǐ yǎ shū":["疋"],"jié qiè":["疌"],"yí nǐ":["疑"],nè:["疒","眲","訥","讷"],"gē yì":["疙"],"nüè yào":["疟","瘧"],"lì lài":["疠","癘"],"yǎ xiā":["疨"],xuē:["疶","蒆","薛","辥","辪","靴","鞾"],"dǎn da":["疸"],"fá biǎn":["疺"],"fèi féi":["疿","痱"],"shān diàn":["痁"],"téng chóng":["痋"],"tōng tóng":["痌"],"wěi yòu yù":["痏"],"tān shǐ":["痑"],"pū pù":["痡","鋪"],"bēng péng":["痭"],"má lìn":["痳"],"tiǎn diàn":["痶"],"ān yè è":["痷"],"kē ē":["痾"],"zhì chì":["瘈"],"jiǎ xiá xiā":["瘕"],"lěi huì":["瘣"],"chài cuó":["瘥"],"diān chēn":["瘨"],"da dá":["瘩"],"biě biē":["瘪"],qué:["瘸"],"dàn dān":["癉"],"guì wēi":["癐"],"nòng nóng":["癑"],"biē biě":["癟"],"bō bǒ":["癷"],bái:["白"],"jí bī":["皀"],"de dì dí dī":["的"],"pā bà":["皅"],"gāo háo":["皋"],"gāo yáo":["皐"],"lì luò bō":["皪"],"zhā cǔ":["皻"],"zhāo zhǎn dǎn":["皽"],"jiān jiàn":["监","監","鋻","间","鞬"],"gài gě hé":["盖"],"máng wàng":["盳"],yuǎn:["盶","逺","遠"],"tián xián":["盷"],"xiāng xiàng":["相"],dǔn:["盹","趸","躉"],"xì pǎn":["盻"],"shěng xǐng":["省"],"yún hùn":["眃"],"miǎn miàn":["眄"],"kàn kān":["看"],"yìng yāng yǎng":["眏"],"yǎo āo ǎo":["眑"],"jū xū kōu":["眗"],"yí chì":["眙"],"dié tì":["眣"],"bǐng fǎng":["眪"],"pàng pán":["眫"],"mī mí":["眯","瞇"],"xuàn shùn xún":["眴"],tiào:["眺","粜","糶","覜","趒"],"zhe zhuó zháo zhāo":["着"],"qiáo shào xiāo":["睄"],"cuó zhuài":["睉"],gùn:["睔","謴"],"suì zuì":["睟"],"pì bì":["睥","稫","辟"],"yì zé gāo":["睪"],"xǐng xìng":["睲"],"guì wèi kuì":["瞆"],"kòu jì":["瞉"],"qióng huán":["瞏"],"mán mén":["瞒","瞞"],"diāo dōu":["瞗"],"lou lóu lǘ":["瞜"],"shùn rún":["瞤"],"liào liǎo":["瞭","钌"],"jiàn xián":["瞯"],"wǔ mí":["瞴"],"guì kuì":["瞶"],"nǐng chēng":["矃"],"huò yuè":["矆"],"mēng méng":["矇"],"kuàng guō":["矌"],"guàn quán":["矔"],"mǎn mán":["矕"],"jīn guān qín":["矜"],"jīn qín guān":["矝"],"yù xù jué":["矞"],"jiǎo jiáo":["矫","矯"],duǎn:["短"],"shí dàn":["石"],"gāng qiāng kòng":["矼"],"huā xū":["砉"],"pīn bīn fēn":["砏"],"yán yàn":["研","硏"],"luǒ kē":["砢"],"fú fèi":["砩","笰"],"zhǔ zhù":["砫"],"lá lì lā":["砬"],"kuāng guāng":["硄"],"gè luò":["硌"],"shuò shí":["硕","碩"],"wèi wéi ái":["硙"],"què kè kù":["硞"],"mǎng bàng":["硥"],"luò lòng":["硦"],"yǒng tóng":["硧"],nüè:["硸","虐"],"kēng kěng":["硻"],"yān yǎn":["硽"],"zhuì chuí duǒ":["硾"],"kōng kòng":["硿"],"zòng cóng":["碂"],"jiān zhàn":["碊"],"lù liù":["碌","陆"],"què xī":["碏"],"lún lǔn lùn":["碖"],"náo gāng":["碙"],"jié yà":["碣"],"wèi wěi":["碨"],"tí dī":["碮"],"chá chā":["碴"],"qiāo què":["碻"],"sù xiè":["碿"],"liú liù":["磂","遛","鎦","馏"],"sī tí":["磃"],"bàng páng":["磅"],"huá kě gū":["磆"],"wěi kuǐ":["磈"],"xiá qià yà":["磍"],"lián qiān":["磏"],"wèi ái gài":["磑"],"lá lā":["磖"],"áo qiāo":["磝"],"pēng pèng":["磞","閛"],"yīn yǐn":["磤"],"lěi léi":["磥"],"mó mò":["磨"],"qì zhú":["磩"],"láo luò":["磱"],"pán bō":["磻"],"jí shé":["磼"],"hé qiāo qiào":["礉"],"kè huò":["礊"],"què hú":["礐"],"è qì":["礘"],cǎ:["礤","礸"],"xián xín":["礥"],"léi lěi lèi":["礧"],"yán yǎn":["礹"],"qí zhǐ":["祇","蚔"],"bēng fāng":["祊"],"bì mì":["祕"],suàn:["祘","笇","筭","算","蒜"],"piào piāo":["票"],"jì zhài":["祭"],"shuì lèi":["祱"],"jìn jīn":["禁"],"chán shàn":["禅"],"yáng shāng":["禓"],"zhī zhǐ tí":["禔"],"shàn chán":["禪"],"yú yù ǒu":["禺"],"zǐ zì":["秄"],"chá ná":["秅"],"zhǒng zhòng chóng":["种"],"hào mào":["秏"],"kù kū":["秙"],zū:["租","葅"],chèng:["秤","穪"],"huó kuò":["秮","秳"],"chēng chèn chèng":["称","稱"],"shì zhì":["秲","銴"],"fù pū":["秿"],"xùn zè":["稄"],"tú shǔ":["稌"],"zhùn zhǔn":["稕"],"jī qí":["稘","綨","觭"],"léng líng":["稜"],"zuì zú sū":["稡"],"xì qiè":["稧","郄"],"zhǒng zhòng":["種"],"zōng zǒng":["稯"],"xián jiān liàn":["稴"],"zī jiū":["稵"],"jī qǐ":["稽"],ròng:["穃"],"shān cǎn cēn":["穇"],"mén méi":["穈"],"jǐ jì":["穖"],"xiāo rào":["穘"],"zhuō bó":["穛"],"tóng zhǒng zhòng":["穜"],zuō:["穝"],"biāo pāo":["穮","藨"],"zhuō jué":["穱"],"cuán zàn":["穳"],"kōng kòng kǒng":["空"],"yū yǔ":["穻"],zhǎi:["窄","鉙"],báo:["窇","雹"],"kū zhú":["窋"],"jiào liáo liù":["窌"],"wā guī":["窐"],"tiǎo yáo":["窕"],"xūn yìn":["窨"],"yà yē":["窫"],"tián diān yǎn":["窴"],"chāo kē":["窼"],"kuǎn cuàn":["窽","窾"],"chù qì":["竐"],"qǔ kǒu":["竘"],"jìng zhěn":["竧"],"kǎn kàn":["竷"],"zhú dǔ":["竺"],"lè jīn":["竻"],"zhuì ruì":["笍"],"háng hàng":["笐"],"cén jìn hán":["笒"],"dā xiá nà":["笚"],"zé zuó":["笮"],"lóng lǒng":["笼","篭","籠","躘","龓"],"zhù zhú":["筑","築"],"dá dā":["答","荅"],shāi:["筛","篩","簁","籭"],"yún jūn":["筠"],"láng làng":["筤","郎","阆"],"zhì zhǐ":["筫"],o:["筽"],"póu bù fú pú":["箁"],"pái bēi":["箄"],gè:["箇","虼","鉻","铬"],"tái chí":["箈"],"guǎi dài":["箉"],"zhào dào":["箌"],"jīng qìng":["箐"],"lín lǐn":["箖"],"jùn qūn":["箘"],"shī yí":["箷","釶"],"yuē yào chuò":["箹"],"xiāo shuò qiào":["箾"],"gōng gǎn lǒng":["篢"],"páng péng":["篣"],"zhuó huò":["篧"],"jiǎn jiān":["篯"],"dí zhú":["篴"],"zān cēn cǎn":["篸"],"zhuàn suǎn zuàn":["篹"],"piǎo biāo":["篻"],"guó guì":["簂"],"cè jí":["簎"],"mì miè":["簚"],"shāi sī":["簛"],"sǔn zhuàn":["簨"],"gàn gǎn":["簳"],"bò bǒ":["簸"],"bó bù":["簿"],shi:["籂"],"zhēn jiān":["籈"],"zhuàn zuǎn":["籑"],"fān pān biān":["籓"],"sǒu shǔ":["籔"],zuǎn:["籫","繤","纂","纉","纘","缵"],nǚ:["籹","釹","钕"],"shā chǎo":["粆"],"kāng jīng":["粇"],fěn:["粉","黺"],cū:["粗","觕","麁","麄","麤"],"nián zhān":["粘"],"cè sè":["粣"],"zhōu yù":["粥"],"shēn sǎn":["糁"],"biān biǎn":["糄","萹"],miàn:["糆","面","靣","麪","麫","麵","麺"],"hú hū hù":["糊"],"gǔ gòu":["糓"],"mí méi":["糜"],"sǎn shēn":["糝","糣"],zāo:["糟","蹧","遭","醩"],"mì sī":["糸"],"jiū jiǔ":["糺"],"xì jì":["系","繫"],"zhēng zhěng":["糽"],"chà chǎ":["紁","衩"],"yuē yāo":["約","约"],"hóng gōng":["紅","红"],"hé gē":["紇","纥"],"wén wèn":["紋","纹"],fóu:["紑"],"jì jié jiè":["紒"],"pī pí bǐ":["紕","纰"],"jīn jìn":["紟"],"zhā zā":["紥","紮"],hā:["紦"],"fū fù":["紨"],"chōu chóu":["紬"],"lèi léi lěi":["累"],"bō bì":["紴"],"tiǎn zhěn":["紾"],"jiōng jiǒng":["絅"],"jié jiē":["結","结","节"],"guà kuā":["絓"],"bǎi mò":["絔"],"gēng huán":["絙"],"jié xié":["絜"],"quán shuān":["絟"],"gǎi ǎi":["絠"],"luò lào":["絡","络"],"bīng bēng pēng":["絣"],"gěi jǐ":["給","给"],"tóng tōng dòng":["絧"],"tiào diào dào":["絩"],"lěi lèi léi":["絫"],"gāi hài":["絯"],"chī zhǐ":["絺"],"wèn miǎn mán wàn":["絻"],"huán huàn wàn":["綄"],"qīn xiān":["綅"],"tì tí":["綈"],"yán xiàn":["綖"],"zōng zèng zòng":["綜"],"chēn lín":["綝"],"zhǔn zhùn":["綧"],"qiàn qīng zhēng":["綪"],"qìng qǐ":["綮"],"lún guān":["綸","纶"],"chuò chāo":["綽","绰"],"tián tǎn chān":["緂"],"lǜ lù":["緑","绿"],"ruǎn ruàn":["緛"],"jí qī":["緝"],"zhòng chóng":["緟","重"],"miáo máo":["緢"],"xiè yè":["緤"],huǎn:["緩","缓","㬊"],"gēng gèng":["緪","縆"],"tōu xū shū":["緰"],"zōng zòng":["緵","繌"],"yùn gǔn":["緷"],"guā wō":["緺"],"yùn yūn wēn":["緼","縕"],"bāng bàng":["縍"],"gǔ hú":["縎","鶻"],"cī cuò suǒ":["縒"],"cuī shuāi":["縗"],"róng rǒng ròng":["縙"],"zài zēng":["縡"],cài:["縩","菜","蔡"],"féng fèng":["縫"],"suō sù":["縮","缩"],"yǎn yǐn":["縯","酓"],"zòng zǒng":["縱","纵"],"zhuàn juàn":["縳"],"mò mù":["縸","莫"],"piǎo piāo":["縹","缥"],"fán pó":["繁"],"bēng bèng":["繃"],"móu miù miào liǎo":["繆"],"yáo yóu zhòu":["繇"],"zēng zèng":["繒","缯"],"jú jué":["繘"],"chuō chuò":["繛"],"zūn zǔn":["繜"],rào:["繞","绕","遶"],"chǎn chán":["繟"],"huì huí":["繢","缋","藱"],"qiāo sāo zǎo":["繰"],"jiǎo zhuó":["繳","缴"],"dàn tán chán":["繵"],nǒng:["繷"],"pú fú":["纀"],"yào lì":["纅"],"rǎng xiāng":["纕"],"lí sǎ xǐ lǐ":["纚"],"xiān qiàn":["纤"],"jīng jìng":["经"],"tí tì":["绨"],"bēng běng bèng":["绷"],"zōng zèng":["综"],"jī qī":["缉"],"wēn yùn yūn":["缊"],"fèng féng":["缝"],"shuāi cuī suī":["缞"],"miù móu liáo miào mù":["缪"],"qiāo sāo":["缲"],fǒu:["缶","缹","缻","雬","鴀"],"bà ba pí":["罢","罷"],"guà guǎi":["罫"],"yáng xiáng":["羊","羏"],"měi gāo":["羙"],"yì xī":["羛"],"qiǎng qiān":["羟"],"qiāng kòng":["羫"],"qián xián yán":["羬"],nóu:["羺"],"hóng gòng":["羾"],"pī bì pō":["翍"],"qú yù":["翑"],ké:["翗"],"qiào qiáo":["翘"],"zhái dí":["翟"],"dào zhōu":["翢"],"hóu qú":["翵"],shuǎ:["耍"],"ruǎn nuò":["耎"],"ér nài":["耏"],"zhuān duān":["耑"],"pá bà":["耙"],"chí sì":["耛"],"qù chú":["耝"],"lún lǔn":["耣"],"jí jiè":["耤"],"tāng tǎng":["耥"],pǎng:["耪","覫"],"zhá zé":["耫"],"yē yé":["耶"],"yún yíng":["耺"],"wà tuǐ zhuó":["聉"],"ér nǜ":["聏"],"tiē zhé":["聑"],"dǐ zhì":["聜"],qié:["聺"],"nǐ jiàn":["聻"],"lèi lē":["肋"],cào:["肏","襙","鄵","鼜"],"bó dí":["肑"],"xiào xiāo":["肖"],"dù dǔ":["肚"],chāi:["肞","釵","钗"],"hán qín hàn":["肣"],"pàng pán pàn":["肨","胖"],"zhūn chún":["肫"],āng:["肮","骯"],"yù yō":["育"],"pí bǐ bì":["肶"],"fèi bì":["胇"],"bèi bēi":["背"],"fèi zǐ":["胏"],"píng pēng":["胓","苹"],"fū fú zhǒu":["胕"],"shèng shēng":["胜"],kuà:["胯","跨","骻"],"gǎi hǎi":["胲"],"gē gé gā":["胳"],"néng nài":["能"],"guī kuì":["胿"],"mài mò":["脉"],"zāng zàng":["脏"],"jiǎo jué":["脚","角"],cuǒ:["脞"],"de te":["脦"],"zuī juān":["脧"],něi:["脮","腇","餒","馁","鮾","鯘"],"pú fǔ":["脯"],niào:["脲"],shuí:["脽"],guò:["腂","過","鐹"],"là xī":["腊"],"yān ā":["腌"],"gāo gào":["膏"],"lù biāo":["膔"],chuái:["膗"],"zhuān chuán chún zhuǎn":["膞"],chuài:["膪","踹"],"fán pán":["膰"],"wǔ hū":["膴"],"shān dàn":["膻"],tún:["臀","臋","蛌","豘","豚","軘","霕","飩","饨","魨","鲀","黗"],"bì bei":["臂"],"là gé":["臈"],"sào sāo":["臊"],nào:["臑","閙","闹","鬧"],"ní luán":["臡"],"qiān xián":["臤"],"guàng jiǒng":["臦"],"guǎng jiǒng":["臩"],"chòu xiù":["臭"],"mián biān":["臱"],"dié zhí":["臷"],"zhī jìn":["臸"],"shè shě":["舍"],pù:["舖","舗"],"bān bō pán":["般"],kuā:["舿"],"gèn gěn":["艮"],"sè shǎi":["色"],"fú bó":["艴"],"jiāo qiú":["艽"],"chāi chā":["芆"],"sháo què":["芍"],"hù xià":["芐"],"zì zǐ":["芓"],"huì hū":["芔"],"tún chūn":["芚"],"jiè gài":["芥"],"xù zhù":["芧"],"yuán yán":["芫"],"xīn xìn":["芯"],"lún huā":["芲"],"wù hū":["芴"],"gōu gǒu":["芶"],"mào máo":["芼"],"fèi fú":["芾"],"chán yín":["苂"],qiē:["苆"],"sū sù":["苏"],"tiáo sháo":["苕"],"lì jī":["苙"],"kē hē":["苛"],"jù qǔ":["苣"],"ruò rě":["若"],"zhù níng":["苧"],"pā bó":["苩"],xiú:["苬"],"zhǎ zuó":["苲"],"jū chá":["苴"],nié:["苶"],"shēng ruí":["苼"],"qié jiā":["茄"],"zǐ cí":["茈"],"qiàn xī":["茜"],chǎi:["茝"],"fá pèi":["茷"],ráo:["荛","蕘","襓","饒","饶"],"yíng xíng":["荥"],"qián xún":["荨","蕁"],"yìn yīn":["荫"],"hé hè":["荷"],"shā suō":["莎"],"péng fēng":["莑"],"shēn xīn":["莘"],"wǎn guān guǎn":["莞"],"yóu sù":["莤"],"shāo xiāo":["莦","蛸"],"làng liáng":["莨"],"piǎo fú":["莩"],"wèn wǎn miǎn":["莬"],"shì shí":["莳","蒔"],"tù tú":["莵"],"xiān liǎn":["莶","薟"],"wǎn yù":["菀"],"zōu chù":["菆"],"lù lǜ":["菉"],"jūn jùn":["菌"],"niè rěn":["菍"],"zī zì zāi":["菑"],"tú tù":["菟"],"jiē shà":["菨"],"qiáo zhǎo":["菬"],"tái zhī chí":["菭"],"fēi fěi":["菲","蜚"],"qín qīn jīn":["菳"],"zū jù":["菹","蒩"],"lǐn má":["菻"],"tián tiàn":["菾"],tiē:["萜","貼","贴"],"luò là lào luō":["落"],"zhù zhuó zhe":["著"],"shèn rèn":["葚"],"gě gé":["葛"],"jùn suǒ":["葰"],"kuì kuài":["蒉"],"rú ná":["蒘"],"méng mēng měng":["蒙"],"yuán huán":["蒝"],"xú shú":["蒣"],"xí xì":["蒵"],"mì míng":["蓂"],"sōu sǒu":["蓃"],"gài gě hé hài":["蓋"],"yǎo zhuó":["蓔"],"diào tiáo dí":["蓧"],"xū qiū fū":["蓲"],"zí jú":["蓻"],"liǎo lù":["蓼"],xu:["蓿"],"hàn hǎn":["蔊"],"màn wàn mán":["蔓"],"pó bò":["蔢"],"fān fán bō":["蕃"],"hóng hòng":["蕻"],"yù ào":["薁","隩"],"xí xiào":["薂"],"báo bó bò":["薄"],"cí zī":["薋"],"wàn luàn":["薍"],"kǎo hāo":["薧"],"yuǎn wěi":["薳"],"zhòu chóu":["薵"],"wō mái":["薶"],"xiāo hào":["藃"],"yù xù xū":["藇"],"jiè jí":["藉"],"diào zhuó":["藋"],"cáng zàng":["藏"],lǎ:["藞"],"chú zhū":["藸"],"pín píng":["蘋"],"gān hán":["虷"],"hóng jiàng":["虹"],"huī huǐ":["虺"],"xiā há":["虾"],"mǎ mà mā":["蚂"],"fāng bàng":["蚄"],"bàng bèng":["蚌"],"jué quē":["蚗"],"qín qián":["蚙"],"gōng zhōng":["蚣"],"fǔ fù":["蚥"],"dài dé":["蚮"],"gǒu qú xù":["蚼"],"bǒ pí":["蚾"],"shé yí":["蛇"],tiě:["蛈","鉄","銕","鐡","鐵","铁","驖"],"gé luò":["蛒"],"máng bàng":["蛖"],"yì xǔ":["蛡"],"há gé":["蛤"],"qiè ní":["蛪"],"é yǐ":["蛾"],"zhē zhé":["蜇"],"là zhà":["蜡"],suò:["蜶","逤"],"yóu qiú":["蝤"],"xiā hā":["蝦"],"xī qī":["螇"],"bī pí":["螕"],"nài něng":["螚"],"hé xiá":["螛"],"guì huǐ":["螝"],"mǎ mā mà":["螞"],"shì zhē":["螫"],"zhì dié":["螲"],"jiàn chán":["螹"],"ma má mò":["蟆"],"mǎng měng":["蟒"],"biē bié":["蟞"],"bēn fèi":["蟦"],"láo liáo":["蟧"],"yín xún":["蟫"],"lí lǐ":["蠡"],"xuè xiě":["血"],"xíng háng hàng héng":["行"],"shuāi cuī":["衰"],"tuó tuō":["袉"],"lǐng líng":["袊"],"bào páo pào":["袌"],"jù jiē":["袓"],"hè kè":["袔"],"yí yì":["袘","貤"],"nà jué":["袦"],"bèi pī":["被"],"chǐ nuǒ":["袲"],"chǐ qǐ duǒ nuǒ":["袳"],"jiá qiā jié":["袷"],"bó mò":["袹"],"guī guà":["袿"],"liè liě":["裂"],"chéng chěng":["裎"],"jiē gé":["裓"],"dāo chóu":["裯"],"shang cháng":["裳"],"yuān gǔn":["裷"],"yǎn ān":["裺"],"tì xī":["裼"],"fù fú":["褔"],"chǔ zhǔ":["褚"],"tuì tùn":["褪"],lǎi:["襰"],"yào yāo":["要"],"qín tán":["覃"],"jiàn xiàn":["見","见"],piǎn:["覑","諞","谝","貵","𡎚"],"piē miè":["覕"],"yíng yǐng":["覮"],"qù qū":["覰","覷","觑"],"jiàn biǎn":["覵"],"luó luǎn":["覶"],"zī zuǐ":["觜"],"huà xiè":["觟"],"jiě jiè xiè":["解","觧"],"xué hù":["觷"],"lì lù":["觻"],tǎo:["討","讨"],zhùn:["訰"],"zī zǐ":["訾"],"yí dài":["詒","诒"],xiòng:["詗","诇"],"diào tiǎo":["誂"],"yí chǐ chì":["誃"],"lǎng làng":["誏"],"ēi éi ěi èi xī":["誒","诶"],shuà:["誜"],"yǔ yù":["語","语","雨"],"shuō shuì yuè":["說","说"],"shuí shéi":["誰","谁"],"qū juè":["誳"],"chī lài":["誺"],"nì ná":["誽"],"diào tiáo":["調"],"pǐ bēi":["諀"],"jì jī":["諅"],"zé zuò zhǎ cuò":["諎"],"chù jí":["諔"],"háo xià":["諕"],"lùn lún":["論","论"],"shì dì":["諟"],"huà guā":["諣"],"xǐ shāi āi":["諰"],"nán nàn":["諵","難"],miù:["謬","谬"],zèn:["譖","谮"],"shí zhì":["識","识"],"juàn xuān":["讂"],"yí tuī":["讉"],zhán:["讝"],"xǔ hǔ":["许"],"xiáng yáng":["详"],"tiáo diào zhōu":["调"],"chén shèn":["谌"],"mí mèi":["谜"],"màn mán":["谩"],"gǔ yù":["谷"],"huō huò huá":["豁"],"zhì zhài":["豸"],"huān huán":["貆"],"kěn kūn":["貇"],"mò hé":["貈"],"mò hé háo":["貉"],"jù lóu":["貗"],"zé zhài":["責","责"],"dài tè":["貸"],"bì bēn":["賁"],"jiǎ gǔ jià":["賈"],"xiōng mín":["賯"],càng:["賶"],"zhuàn zuàn":["賺","赚"],"wàn zhuàn":["贃"],"gàn gòng zhuàng":["贛"],"yuán yùn":["贠"],"bēn bì":["贲"],"jiǎ gǔ":["贾"],zǒu:["走","赱","鯐"],"dié tú":["趃"],"jū qiè":["趄"],"qū cù":["趋","趨"],"jí jié":["趌"],"guā huó":["趏"],"què qì jí":["趞"],"tàng tāng":["趟"],"chuō zhuó":["趠"],"qù cù":["趣"],"yuè tì":["趯"],"bō bào":["趵"],"kuà wù":["趶"],"guì jué":["趹"],"fāng fàng páng":["趽"],"páo bà":["跁"],"qí qǐ":["跂"],"jiàn chén":["跈"],"pǎo páo":["跑"],"diǎn diē tiē":["跕"],"jū jù qiè":["跙"],bǒ:["跛"],"luò lì":["跞"],"dài duò duō chí":["跢"],zhuǎi:["跩"],"bèng pián":["跰"],"tiào táo":["跳"],"shū chōu":["跾"],"liàng liáng":["踉"],"tà tā":["踏"],chǎ:["蹅","鑔","镲"],"dí zhí":["蹢"],"dēng dèng":["蹬","鐙","镫"],cèng:["蹭"],"dūn cún":["蹲"],"juě jué":["蹶"],liāo:["蹽"],"xiè sǎ":["躠"],tǐ:["躰","軆","骵"],"yà zhá gá":["轧","軋"],"xìn xiàn":["軐"],"fàn guǐ":["軓"],"zhuàn zhuǎn":["転"],"zhóu zhòu":["軸","轴"],bú:["轐","醭","鳪"],"zhuǎn zhuàn zhuǎi":["转"],"zǎi zài":["载"],"niǎn zhǎn":["辗"],"biān bian":["边"],"dào biān":["辺"],"yǐ yí":["迆","迤","迱"],"guò guo guō":["过"],"wàng kuāng":["迋"],"hái huán":["还"],"zhè zhèi":["这"],"yuǎn yuàn":["远"],"zhì lì":["迣"],"zhù wǎng":["迬"],"zhuī duī":["追"],"shì kuò":["适"],tòu:["透"],"tōng tòng":["通"],guàng:["逛"],"dǎi dài":["逮"],"suì suí":["遂"],"tí dì":["遆"],"yí wèi":["遗"],"shì dí zhé":["適"],cà:["遪"],"huán hái":["還"],"lí chí":["邌"],"kàng háng":["邟"],"nà nèi nā":["那"],"xié yá yé yú xú":["邪"],"gāi hái":["郂"],"huán xún":["郇"],"chī xī":["郗"],hǎo:["郝"],"lì zhí":["郦"],"xiáo ǎo":["郩"],"dōu dū":["都"],liǎo:["曢","鄝","镽"],"zàn cuán cuó":["酂","酇"],"dīng dǐng":["酊"],"cù zuò":["酢"],"fā pō":["酦"],"shāi shī":["酾"],niàng:["酿","醸"],"qiú chōu":["醔"],"pō fā":["醗","醱"],"chǎn chěn":["醦"],"yàn liǎn xiān":["醶"],"niàng niáng":["釀"],"lǐ li":["里"],"lí xǐ xī":["釐"],"liǎo liào":["釕"],"dīng dìng":["釘","钉"],"qiǎo jiǎo":["釥"],"yú huá":["釪"],"huá wū":["釫"],"rì rèn jiàn":["釰","釼"],"dì dài":["釱"],"pī zhāo":["釽"],"yá yé":["釾"],"bǎ pá":["鈀","钯"],"tā tuó":["鉈","铊"],běi:["鉳"],"bǐng píng":["鉼"],"hā kē":["鉿","铪"],chòng:["銃","铳"],"xiǎng jiōng":["銄"],"yù sì":["銉"],"xù huì":["銊"],"rén rěn":["銋"],"shàn shuò":["銏"],"chì lì":["銐"],"xiǎn xǐ":["銑","铣"],"hóu xiàng":["銗"],"diào tiáo yáo":["銚"],"xiān kuò tiǎn guā":["銛","銽","铦"],"zhé niè":["銸"],"zhōng yōng":["銿"],"tōu tù dòu":["鋀"],"méi méng":["鋂"],"wàn jiǎn":["鋄","鎫"],"tǐng dìng":["鋌","铤"],"juān jiān cuān":["鋑"],"sī tuó":["鋖"],"juān xuān juàn":["鋗"],"wú huá wū":["鋘"],"zhuó chuò":["鋜"],"xíng xìng jīng":["鋞"],"jū jú":["鋦","锔"],"zuì niè":["鋷"],"yuān yuǎn wǎn wān":["鋺"],"gāng gàng":["鋼","钢"],zhuī:["錐","锥","騅","骓","鵻"],ā:["錒","锕"],"cuō chā":["鎈"],"suǒ sè":["鎍"],"yáo zú":["鎐"],"yè tà gé":["鎑"],"qiāng chēng":["鎗"],"gé lì":["鎘","镉","鬲"],"bī pī bì":["鎞"],"gǎo hào":["鎬"],"zú chuò":["鏃"],"xiū xiù":["鏅"],"shòu sōu":["鏉"],"dí dī":["鏑","镝"],"qiāo sǎn càn":["鏒"],"lù áo":["鏕"],"tāng táng":["鏜"],"jiàn zàn":["鏩"],"huì suì ruì":["鏸"],"qiǎng qiāng":["鏹","镪"],"sǎn xiàn sà":["鏾"],"jiǎn jiàn":["鐧","锏"],"dāng chēng":["鐺","铛"],"zuān zuàn":["鑽"],"sà xì":["钑"],"yào yuè":["钥"],"tǒu dǒu":["钭"],"zuàn zuān":["钻"],"qiān yán":["铅"],"pí pī":["铍"],"yáo diào tiáo":["铫"],"tāng tàng":["铴"],"pù pū":["铺"],"tán xiān":["锬"],"liù liú":["镏"],"hào gǎo":["镐"],"táng tāng":["镗"],"tán chán xín":["镡"],"huò shǎn":["閄"],"hàn bì":["閈","闬"],"kāng kàng":["閌","闶"],"xián jiàn jiān jiǎn":["閒"],"xiā xiǎ":["閕"],"xiǎ kě":["閜"],"biàn guān":["閞"],"hé gé":["閤","颌"],"hòng xiàng":["閧"],"sē xī":["閪"],"tíng tǐng":["閮"],"è yān":["閼","阏"],"hòng juǎn xiàng":["闂"],"bǎn pàn":["闆"],"dū shé":["闍","阇"],"què quē":["闕"],"tāng táng chāng":["闛"],"kàn hǎn":["闞","阚"],"xì sè tà":["闟"],"mēn mèn":["闷"],"quē què":["阙"],"yán diàn":["阽"],"ā ē":["阿"],"bēi pō pí":["陂"],"yàn yǎn":["隁"],"yú yáo shù":["隃"],"lóng lōng":["隆"],"duì zhuì":["隊"],"suí duò":["隋"],"gāi qí ái":["隑"],"huī duò":["隓","隳"],"wěi kuí":["隗"],"lì dài":["隸"],"zhuī cuī wéi":["隹"],"hè hú":["隺","鶮"],"jùn juàn":["隽","雋"],"nán nàn nuó":["难"],"què qiāo qiǎo":["雀"],"guàn huán":["雚"],"guī xī":["雟"],"sè xí":["雭"],án:["雸"],"wù méng":["雺"],tèng:["霯"],"lù lòu":["露"],mái:["霾"],"jìng liàng":["靚"],"gé jí":["革"],bǎ:["靶"],"yāng yàng":["鞅"],"gé tà sǎ":["鞈"],"biān yìng":["鞕"],"qiào shāo":["鞘"],"juān xuān":["鞙"],"shàng zhǎng":["鞝"],"pí bǐng bì bēi":["鞞"],la:["鞡"],"xiè dié":["鞢"],ēng:["鞥"],"móu mù":["鞪"],"bì bǐng":["鞸"],"mèi wà":["韎"],rǒu:["韖"],"shè xiè":["韘"],"yùn wēn":["韫"],"dùn dú":["頓","顿"],duǐ:["頧"],luō:["頱"],"bīn pín":["頻"],yóng:["顒","颙","鰫"],mān:["顢","颟"],"jǐng gěng":["颈"],"jié xié jiá":["颉"],"kē ké":["颏"],"pín bīn":["频"],"chàn zhàn":["颤"],"fēng fěng":["風","风"],"biāo diū":["颩"],"bá fú":["颰"],"sāo sōu":["颾"],"liù liáo":["飂"],"shí sì yì":["食"],"yǎng juàn":["飬"],"zhù tǒu":["飳"],"yí sì":["飴"],"zuò zé zhā":["飵"],tiè:["飻","餮"],"xiǎng náng":["饟"],"táng xíng":["饧"],"gē le":["饹"],"chā zha":["馇"],"náng nǎng":["馕"],"yūn wò":["馧"],"zhī shì":["馶"],"xìn jìn":["馸"],"kuài jué":["駃"],zǎng:["駔","驵"],"tái dài":["駘"],"xún xuān":["駨"],"liáng láng":["駺"],piàn:["騗","騙","骗","魸"],"dài tái":["骀"],"sāo sǎo":["骚"],"gǔ gū":["骨"],"bèi mó":["骳"],"xiāo qiāo":["骹"],"bǎng pǎng":["髈"],"bó jué":["髉"],"bì pǒ":["髲"],"máo méng":["髳"],"kuò yuè":["髺"],"bā bà":["魞","鲃"],"jì cǐ":["鮆"],"bó bà":["鮊"],"zhǎ zhà":["鮓","鲊"],"chóu dài":["鮘"],"luò gé":["鮥"],"guī xié wā kuí":["鮭"],"xiān xiǎn":["鮮","鲜"],"pū bū":["鯆"],"yì sī":["鯣"],"bà bó":["鲌"],"guī xié":["鲑"],"sāi xǐ":["鳃"],"niǎo diǎo":["鳥"],"diāo zhāo":["鳭"],"gān hàn yàn":["鳱"],"fū guī":["鳺"],"jiān qiān zhān":["鳽"],"hé jiè":["鶡"],"piān biǎn":["鶣"],"chuàn zhì":["鶨"],"cāng qiāng":["鶬"],"sǔn xùn":["鶽"],"biāo páo":["麃"],"zhù cū":["麆"],"jūn qún":["麇","麕"],chi:["麶"],"mó me":["麼"],"mó me ma":["麽"],"mí mǒ":["麿"],"dàn shèn":["黮"],"zhěn yān":["黰"],"dǎn zhǎn":["黵"],"miǎn mǐn měng":["黾"],hōu:["齁"],nàng:["齉"],"qí jì zī zhāi":["齐"],"yín kěn yǎn":["龂"],"yín kěn":["龈"],"gōng wò":["龏"],"guī jūn qiū":["龜","龟"],"kuí wā":["䖯"],lōu:["䁖"],"ōu qū":["𫭟"],"lóu lǘ":["𦝼"],"gǎ gā gá":["嘎"],"wā guà":["坬"],"zhǐ dǐ":["茋"],"gǒng hóng":["硔"],"yáo xiào":["滧"]},_c=new i$;Object.keys(YS).forEach(e=>{const t=YS[e];for(let n of t)_c.set(n,e)});const JS={这个:"zhè ge",成为:"chéng wéi",认为:"rèn wéi",作为:"zuò wéi",部分:"bù fen",要求:"yāo qiú",应该:"yīng gāi",增长:"zēng zhǎng",提供:"tí gōng",觉得:"jué de",任务:"rèn wu",那个:"nà ge",称为:"chēng wéi",为主:"wéi zhǔ",了解:"liǎo jiě",处理:"chǔ lǐ",皇上:"huáng shang",只要:"zhǐ yào",大量:"dà liàng",力量:"lì liàng",几乎:"jī hū",干部:"gàn bù",目的:"mù dì",行为:"xíng wéi",只见:"zhǐ jiàn",认识:"rèn shi",市长:"shì zhǎng",师父:"shī fu",调查:"diào chá",重新:"chóng xīn",分为:"fēn wéi",知识:"zhī shi",导弹:"dǎo dàn",质量:"zhì liàng",行款:"háng kuǎn",行列:"háng liè",行话:"háng huà",行业:"háng yè",隔行:"gé háng",在行:"zài háng",行家:"háng jia",内行:"nèi háng",外行:"wài háng",同行:"tóng háng",本行:"běn háng",行伍:"háng wǔ",洋行:"yáng háng",银行:"yín háng",商行:"shāng háng",支行:"zhī háng",总行:"zǒng háng",行情:"háng qíng",懂行:"dǒng háng",行规:"háng guī",行当:"háng dang",行货:"háng huò",太行:"tài háng",入行:"rù háng",中行:"zhōng háng",农行:"nóng háng",工行:"gōng háng",建行:"jiàn háng",各行:"gè háng",行号:"háng hào",行高:"háng gāo",行首:"háng shǒu",行尾:"háng wěi",行末:"háng mò",行长:"háng zhǎng",行距:"háng jù",换行:"huàn háng",行会:"háng huì",行辈:"háng bèi",行道:"háng dào",道行:"dào heng",参与:"cān yù",充分:"chōng fèn",尽管:"jǐn guǎn",生长:"shēng zhǎng",数量:"shù liàng",应当:"yīng dāng",院长:"yuàn zhǎng",强调:"qiáng diào",只能:"zhǐ néng",音乐:"yīn yuè",以为:"yǐ wéi",处于:"chǔ yú",部长:"bù zhǎng",蒙古:"měng gǔ",只有:"zhǐ yǒu",适当:"shì dàng",只好:"zhǐ hǎo",成长:"chéng zhǎng",高兴:"gāo xìng",不了:"bù liǎo",产量:"chǎn liàng",胖子:"pàng zi",显得:"xiǎn de",只是:"zhǐ shì",似的:"shì de",率领:"shuài lǐng",改为:"gǎi wéi",不禁:"bù jīn",成分:"chéng fèn",答应:"dā ying",少年:"shào nián",兴趣:"xìng qù",太监:"tài jian",休息:"xiū xi",校长:"xiào zhǎng",更新:"gēng xīn",合同:"hé tong",喝道:"hè dào",重庆:"chóng qìng",重建:"chóng jiàn",使得:"shǐ de",审查:"shěn chá",累计:"lěi jì",给予:"jǐ yǔ",极为:"jí wéi",冠军:"guàn jūn",仿佛:"fǎng fú",头发:"tóu fa",投降:"tóu xiáng",家长:"jiā zhǎng",仔细:"zǐ xì",要是:"yào shi",将领:"jiàng lǐng",含量:"hán liàng",更为:"gèng wéi",积累:"jī lěi",地处:"dì chǔ",县长:"xiàn zhǎng",少女:"shào nǚ",路上:"lù shang",只怕:"zhǐ pà",能量:"néng liàng",储量:"chǔ liàng",供应:"gōng yìng",挑战:"tiǎo zhàn",西藏:"xī zàng",记得:"jì de",总量:"zǒng liàng",当真:"dàng zhēn",将士:"jiàng shì",差别:"chā bié",较为:"jiào wéi",长老:"zhǎng lǎo",大夫:"dài fu",差异:"chā yì",懂得:"dǒng de",尽量:"jǐn liàng",模样:"mú yàng",的确:"dí què",为首:"wéi shǒu",便宜:"pián yi",更名:"gēng míng",石头:"shí tou",州长:"zhōu zhǎng",为止:"wéi zhǐ",漂亮:"piào liang",炮弹:"pào dàn",藏族:"zàng zú",角色:"jué sè",当作:"dàng zuò",尽快:"jǐn kuài",人为:"rén wéi",重复:"chóng fù",胡同:"hú tòng",差距:"chā jù",弟兄:"dì xiong",大将:"dà jiàng",睡觉:"shuì jiào",一觉:"yí jiào",团长:"tuán zhǎng",队长:"duì zhǎng",区长:"qū zhǎng",难得:"nán dé",丫头:"yā tou",会长:"huì zhǎng",弟弟:"dì di",王爷:"wáng ye",重量:"zhòng liàng",誉为:"yù wéi",家伙:"jiā huo",华山:"huà shān",椅子:"yǐ zi",流量:"liú liàng",长大:"zhǎng dà",勉强:"miǎn qiǎng",会计:"kuài jì",过分:"guò fèn",济南:"jǐ nán",调动:"diào dòng",燕京:"yān jīng",少将:"shào jiàng",中毒:"zhòng dú",晓得:"xiǎo de",变更:"biàn gēng",打更:"dǎ gēng",认得:"rèn de",苹果:"píng guǒ",念头:"niàn tou",挣扎:"zhēng zhá",三藏:"sān zàng",剥削:"bō xuē",丞相:"chéng xiàng",少量:"shǎo liàng",寻思:"xún si",夺得:"duó dé",干线:"gàn xiàn",呼吁:"hū yù",处罚:"chǔ fá",长官:"zhǎng guān",柏林:"bó lín",亲戚:"qīn qi",身分:"shēn fèn",胳膊:"gē bo",着手:"zhuó shǒu",炸弹:"zhà dàn",咳嗽:"ké sou",叶子:"yè zi",外长:"wài zhǎng",供给:"gōng jǐ",师长:"shī zhǎng",变量:"biàn liàng",应有:"yīng yǒu",下载:"xià zài",乐器:"yuè qì",间接:"jiàn jiē",底下:"dǐ xià",打扮:"dǎ bàn",子弹:"zǐ dàn",弹药:"dàn yào",热量:"rè liàng",削弱:"xuē ruò",骨干:"gǔ gàn",容量:"róng liàng",模糊:"mó hu",转动:"zhuàn dòng",称呼:"chēng hu",科长:"kē zhǎng",处置:"chǔ zhì",着重:"zhuó zhòng",着急:"zháo jí",强迫:"qiǎng pò",庭长:"tíng zhǎng",首相:"shǒu xiàng",喇嘛:"lǎ ma",镇长:"zhèn zhǎng",只管:"zhǐ guǎn",重重:"chóng chóng",免得:"miǎn de",着实:"zhuó shí",度假:"dù jià",真相:"zhēn xiàng",相貌:"xiàng mào",处分:"chǔ fèn",委屈:"wěi qu",为期:"wéi qī",伯伯:"bó bo",伯子:"bǎi zi",圈子:"quān zi",见识:"jiàn shi",笼罩:"lǒng zhào",与会:"yù huì",都督:"dū du",都市:"dū shì",成都:"chéng dū",首都:"shǒu dū",帝都:"dì dū",王都:"wáng dū",东都:"dōng dū",都护:"dū hù",都城:"dū chéng",建都:"jiàn dū",迁都:"qiān dū",故都:"gù dū",定都:"dìng dū",中都:"zhōng dū",六安:"lù ān",宰相:"zǎi xiàng",较量:"jiào liàng",对称:"duì chèn",总长:"zǒng zhǎng",相公:"xiàng gong",空白:"kòng bái",打量:"dǎ liang",水分:"shuǐ fèn",舌头:"shé tou",没收:"mò shōu",行李:"xíng li",判处:"pàn chǔ",散文:"sǎn wén",处境:"chǔ jìng",孙子:"sūn zi",拳头:"quán tou",打发:"dǎ fā",组长:"zǔ zhǎng",骨头:"gǔ tou",宁可:"nìng kě",更换:"gēng huàn",薄弱:"bó ruò",还原:"huán yuán",重修:"chóng xiū",重来:"chóng lái",只顾:"zhǐ gù",爱好:"ài hào",馒头:"mán tou",军长:"jūn zhǎng",首长:"shǒu zhǎng",厂长:"chǎng zhǎng",司长:"sī zhǎng",长子:"zhǎng zǐ",强劲:"qiáng jìng",恰当:"qià dàng",头儿:"tóu er",站长:"zhàn zhǎng",折腾:"zhē teng",相处:"xiāng chǔ",统率:"tǒng shuài",中将:"zhōng jiàng",命中:"mìng zhòng",名将:"míng jiàng",木头:"mù tou",动弹:"dòng tan",地壳:"dì qiào",干活:"gàn huó",少爷:"shào ye",水量:"shuǐ liàng",补给:"bǔ jǐ",尾巴:"wěi ba",来得:"lái de",好奇:"hào qí",钥匙:"yào shi",当做:"dàng zuò",沉着:"chén zhuó",哑巴:"yǎ ba",车子:"chē zi",上将:"shàng jiàng",恶心:"ě xīn",担子:"dàn zi",应届:"yīng jiè",主角:"zhǔ jué",运转:"yùn zhuǎn",兄长:"xiōng zhǎng",格式:"gé shì",正月:"zhēng yuè",营长:"yíng zhǎng",当成:"dàng chéng",女婿:"nǚ xu",咽喉:"yān hóu",重阳:"chóng yáng",化为:"huà wéi",吐蕃:"tǔ bō",钻进:"zuān jìn",乐队:"yuè duì",亮相:"liàng xiàng",被子:"bèi zi",舍得:"shě de",杉木:"shā mù",击中:"jī zhòng",排长:"pái zhǎng",假期:"jià qī",分量:"fèn liàng",数次:"shù cì",提防:"dī fáng",吆喝:"yāo he",查处:"chá chǔ",量子:"liàng zǐ",里头:"lǐ tou",调研:"diào yán",伺候:"cì hou",重申:"chóng shēn",枕头:"zhěn tou",拚命:"pīn mìng",社长:"shè zhǎng",归还:"guī huán",批量:"pī liàng",畜牧:"xù mù",点着:"diǎn zháo",甚为:"shèn wéi",小将:"xiǎo jiàng",着眼:"zhuó yǎn",处死:"chǔ sǐ",厌恶:"yàn wù",鼓乐:"gǔ yuè",树干:"shù gàn",秘鲁:"bì lǔ",大方:"dà fāng",外头:"wài tou",班长:"bān zhǎng",星宿:"xīng xiù",宁愿:"nìng yuàn",钦差:"qīn chāi",为数:"wéi shù",勾当:"gòu dàng",削减:"xuē jiǎn",间谍:"jiàn dié",埋怨:"mán yuàn",结实:"jiē shi",计量:"jì liáng",淹没:"yān mò",村长:"cūn zhǎng",连长:"lián zhǎng",自给:"zì jǐ",武将:"wǔ jiàng",温差:"wēn chā",直奔:"zhí bèn",供求:"gōng qiú",剂量:"jì liàng",道长:"dào zhǎng",泄露:"xiè lòu",王八:"wáng ba",切割:"qiē gē",间隔:"jiàn gé",一晃:"yì huǎng",长假:"cháng jià",令狐:"líng hú",为害:"wéi hài",句子:"jù zi",偿还:"cháng huán",疙瘩:"gē da",燕山:"yān shān",堵塞:"dǔ sè",夺冠:"duó guàn",扎实:"zhā shi",电荷:"diàn hè",看守:"kān shǒu",复辟:"fù bì",郁闷:"yù mèn",尽早:"jǐn zǎo",切断:"qiē duàn",指头:"zhǐ tou",为生:"wéi shēng",畜生:"chù sheng",切除:"qiē chú",着力:"zhuó lì",着想:"zhuó xiǎng",级差:"jí chā",投奔:"tóu bèn",棍子:"gùn zi",含糊:"hán hu",少妇:"shào fù",兴致:"xìng zhì",纳闷:"nà mèn",干流:"gàn liú",卷起:"juǎn qǐ",扇子:"shàn zi",更改:"gēng gǎi",笼络:"lǒng luò",喇叭:"lǎ ba",载荷:"zài hè",妥当:"tuǒ dàng",为难:"wéi nán",着陆:"zhuó lù",燕子:"yàn zi",干吗:"gàn má",白发:"bái fà",总得:"zǒng děi",夹击:"jiā jī",曝光:"bào guāng",曲调:"qǔ diào",相机:"xiàng jī",叫化:"jiào huà",角逐:"jué zhú",啊哟:"ā yō",载重:"zài zhòng",长辈:"zhǎng bèi",出差:"chū chāi",垛口:"duǒ kǒu",撇开:"piē kāi",厅长:"tīng zhǎng",组分:"zǔ fèn",误差:"wù chā",家当:"jiā dàng",传记:"zhuàn jì",个子:"gè zi",铺设:"pū shè",干事:"gàn shì",杆菌:"gǎn jūn",定量:"dìng liàng",运载:"yùn zài",会儿:"huì er",酋长:"qiú zhǎng",重返:"chóng fǎn",差额:"chā é",露面:"lòu miàn",钻研:"zuān yán",大城:"dài chéng",上当:"shàng dàng",销量:"xiāo liàng",作坊:"zuō fang",照相:"zhào xiàng",哎呀:"āi yā",调集:"diào jí",看中:"kàn zhòng",议长:"yì zhǎng",风筝:"fēng zheng",辟邪:"bì xié",空隙:"kòng xì",更迭:"gēng dié",偏差:"piān chā",声调:"shēng diào",适量:"shì liàng",屯子:"tún zi",无量:"wú liàng",空地:"kòng dì",调度:"diào dù",散射:"sǎn shè",创伤:"chuāng shāng",海参:"hǎi shēn",满载:"mǎn zài",重叠:"chóng dié",落差:"luò chā",单调:"dān diào",老将:"lǎo jiàng",人参:"rén shēn",间断:"jiàn duàn",重现:"chóng xiàn",夹杂:"jiā zá",调用:"diào yòng",萝卜:"luó bo",附着:"fù zhuó",应声:"yìng shēng",主将:"zhǔ jiàng",罪过:"zuì guo",咀嚼:"jǔ jué",为政:"wéi zhèng",过量:"guò liàng",乐曲:"yuè qǔ",负荷:"fù hè",枪弹:"qiāng dàn",悄然:"qiǎo rán",处方:"chǔ fāng",悄声:"qiǎo shēng",曲子:"qǔ zi",情调:"qíng diào",挑衅:"tiǎo xìn",代为:"dài wéi",了结:"liǎo jié",打中:"dǎ zhòng",酒吧:"jiǔ bā",懒得:"lǎn de",增量:"zēng liàng",衣着:"yī zhuó",部将:"bù jiàng",要塞:"yào sài",茶几:"chá jī",杠杆:"gàng gǎn",出没:"chū mò",鲜有:"xiǎn yǒu",间隙:"jiàn xì",重担:"zhòng dàn",重演:"chóng yǎn",重试:"chóng shì",应酬:"yìng chou",只当:"zhǐ dāng",毋宁:"wú nìng",包扎:"bāo zā",前头:"qián tou",卷烟:"juǎn yān",非得:"fēi děi",弹道:"dàn dào",杆子:"gān zi",门将:"mén jiàng",后头:"hòu tou",喝彩:"hè cǎi",暖和:"nuǎn huo",累积:"lěi jī",调遣:"diào qiǎn",倔强:"jué jiàng",宝藏:"bǎo zàng",丧事:"sāng shì",约莫:"yuē mo",纤夫:"qiàn fū",更替:"gēng tì",装载:"zhuāng zài",背包:"bēi bāo",帖子:"tiě zi",松散:"sōng sǎn",呼喝:"hū hè",可恶:"kě wù",自转:"zì zhuàn",供电:"gōng diàn",反省:"fǎn xǐng",坦率:"tǎn shuài",苏打:"sū dá",本分:"běn fèn",落得:"luò de",鄙薄:"bǐ bó",相间:"xiāng jiàn",单薄:"dān bó",混蛋:"hún dàn",贞观:"zhēn guān",附和:"fù hè",能耐:"néng nài",吓唬:"xià hu",未了:"wèi liǎo",引着:"yǐn zháo",抽调:"chōu diào",沙子:"shā zi",席卷:"xí juǎn",标的:"biāo dì",别扭:"biè niu",思量:"sī liang",喝采:"hè cǎi",论语:"lún yǔ",盖子:"gài zi",分外:"fèn wài",弄堂:"lòng táng",乐舞:"yuè wǔ",雨量:"yǔ liàng",毛发:"máo fà",差遣:"chāi qiǎn",背负:"bēi fù",转速:"zhuàn sù",声乐:"shēng yuè",夹攻:"jiā gōng",供水:"gōng shuǐ",主干:"zhǔ gàn",惩处:"chéng chǔ",长相:"zhǎng xiàng",公差:"gōng chāi",榴弹:"liú dàn",省得:"shěng de",条子:"tiáo zi",重围:"chóng wéi",阻塞:"zǔ sè",劲风:"jìng fēng",纠葛:"jiū gé",颠簸:"diān bǒ",点中:"diǎn zhòng",重创:"zhòng chuāng",姥姥:"lǎo lao",迷糊:"mí hu",公家:"gōng jia",几率:"jī lǜ",苦闷:"kǔ mèn",度量:"dù liàng",差错:"chā cuò",暑假:"shǔ jià",参差:"cēn cī",搭载:"dā zài",助长:"zhù zhǎng",相称:"xiāng chèn",红晕:"hóng yùn",舍命:"shě mìng",喜好:"xǐ hào",列传:"liè zhuàn",劲敌:"jìng dí",蛤蟆:"há ma",请假:"qǐng jià",钉子:"dīng zi",沉没:"chén mò",高丽:"gāo lí",休假:"xiū jià",无为:"wú wéi",巴结:"bā jie",了得:"liǎo dé",变相:"biàn xiàng",核弹:"hé dàn",亲家:"qìng jia",承载:"chéng zài",喝问:"hè wèn",还击:"huán jī",交还:"jiāo huán",将令:"jiàng lìng",单于:"chán yú",空缺:"kòng quē",绿林:"lù lín",胆量:"dǎn liàng",执着:"zhí zhuó",低调:"dī diào",闭塞:"bì sè",轻薄:"qīng bó",得当:"dé dàng",占卜:"zhān bǔ",扫帚:"sào zhou",龟兹:"qiū cí",年长:"nián zhǎng",外传:"wài zhuàn",头子:"tóu zi",裁缝:"cái feng",礼乐:"lǐ yuè",血泊:"xuè pō",散乱:"sǎn luàn",动量:"dòng liàng",倒腾:"dǎo teng",取舍:"qǔ shě",咱家:"zán jiā",长发:"cháng fà",爪哇:"zhǎo wā",弹壳:"dàn ké",省悟:"xǐng wù",嚷嚷:"rāng rang",连累:"lián lèi",应得:"yīng dé",族长:"zú zhǎng",柜子:"guì zi",擂鼓:"léi gǔ",眩晕:"xuàn yùn",调配:"tiáo pèi",躯干:"qū gàn",差役:"chāi yì",坎坷:"kǎn kě",少儿:"shào ér",乐团:"yuè tuán",养分:"yǎng fèn",退还:"tuì huán",格调:"gé diào",语调:"yǔ diào",音调:"yīn diào",乐府:"yuè fǔ",古朴:"gǔ pǔ",打点:"dǎ diǎn",差使:"chāi shǐ",匀称:"yún chèn",瘦削:"shòu xuē",膏药:"gāo yao",吞没:"tūn mò",调任:"diào rèn",散居:"sǎn jū",上头:"shàng tóu",风靡:"fēng mǐ",放假:"fàng jià",估量:"gū liang",失当:"shī dàng",中弹:"zhòng dàn",妄为:"wàng wéi",长者:"zhǎng zhě",起哄:"qǐ hòng",末了:"mò liǎo",相声:"xiàng sheng",校正:"jiào zhèng",劝降:"quàn xiáng",矢量:"shǐ liàng",沉闷:"chén mèn",给与:"jǐ yǔ",解法:"jiě fǎ",塞外:"sài wài",将校:"jiàng xiào",嗜好:"shì hào",没落:"mò luò",朴刀:"pō dāo",片子:"piān zi",切削:"qiē xiāo",弹丸:"dàn wán",稀薄:"xī bó",亏得:"kuī dé",间歇:"jiàn xiē",翘首:"qiáo shǒu",色调:"sè diào",处决:"chǔ jué",表率:"biǎo shuài",尺子:"chǐ zi",招降:"zhāo xiáng",称职:"chèn zhí",斗篷:"dǒu peng",铺子:"pù zi",底子:"dǐ zi",负载:"fù zài",干警:"gàn jǐng",倒数:"dào shǔ",将官:"jiàng guān",锄头:"chú tou",归降:"guī xiáng",疟疾:"nüè ji",唠叨:"láo dao",限量:"xiàn liàng",屏息:"bǐng xī",重逢:"chóng féng",器乐:"qì yuè",氢弹:"qīng dàn",脖颈:"bó gěng",妃子:"fēi zi",处事:"chǔ shì",参量:"cān liàng",轻率:"qīng shuài",缥缈:"piāo miǎo",中奖:"zhòng jiǎng",才干:"cái gàn",施舍:"shī shě",卷子:"juàn zi",游说:"yóu shuì",巷子:"xiàng zi",膀胱:"páng guāng",切勿:"qiè wù",看管:"kān guǎn",风头:"fēng tou",精干:"jīng gàn",高差:"gāo chā",恐吓:"kǒng hè",扁担:"biǎn dàn",给养:"jǐ yǎng",格子:"gé zi",供需:"gōng xū",反差:"fǎn chā",飞弹:"fēi dàn",微薄:"wēi bó",发型:"fà xíng",即兴:"jí xìng",攒动:"cuán dòng",间或:"jiàn huò",浅薄:"qiǎn bó",乐章:"yuè zhāng",顺差:"shùn chā",调子:"diào zi",相位:"xiàng wèi",转子:"zhuàn zǐ",劲旅:"jìng lǚ",咔嚓:"kā chā",了事:"liǎo shì",转悠:"zhuàn you",当铺:"dàng pù",爪子:"zhuǎ zi",单子:"dān zi",好战:"hào zhàn",燕麦:"yàn mài",只许:"zhǐ xǔ",干练:"gàn liàn",女将:"nǚ jiàng",酒量:"jiǔ liàng",划船:"huá chuán",伎俩:"jì liǎng",挑拨:"tiǎo bō",少校:"shào xiào",着落:"zhuó luò",憎恶:"zēng wù",刻薄:"kè bó",要挟:"yāo xié",用处:"yòng chu",还手:"huán shǒu",模具:"mú jù",执著:"zhí zhuó",喝令:"hè lìng",保长:"bǎo zhǎng",吸着:"xī zhe",症结:"zhēng jié",公转:"gōng zhuàn",校勘:"jiào kān",重提:"chóng tí",扫兴:"sǎo xìng",铺盖:"pū gài",长史:"zhǎng shǐ",差价:"chā jià",压根:"yà gēn",怔住:"zhèng zhù",应允:"yīng yǔn",切入:"qiē rù",战将:"zhàn jiàng",年少:"nián shào",舍身:"shě shēn",执拗:"zhí niù",处世:"chǔ shì",中风:"zhòng fēng",等量:"děng liàng",放量:"fàng liàng",腔调:"qiāng diào",老少:"lǎo shào",没入:"mò rù",瓜葛:"guā gé",将帅:"jiàng shuài",车载:"chē zài",窝囊:"wō nang",长进:"zhǎng jìn",可汗:"kè hán",并州:"bīng zhōu",供销:"gōng xiāo",切片:"qiē piàn",差事:"chāi shì",知会:"zhī hui",鹰爪:"yīng zhǎo",处女:"chǔ nǚ",切磋:"qiē cuō",日头:"rì tou",押解:"yā jiè",滋长:"zī zhǎng",道观:"dào guàn",脚色:"jué sè",当量:"dāng liàng",婆家:"pó jia",缘分:"yuán fèn",空闲:"kòng xián",好色:"hào sè",怒喝:"nù hè",笼统:"lǒng tǒng",边塞:"biān sài",何曾:"hé céng",重合:"chóng hé",零散:"líng sǎn",轰隆:"hōng lōng",化子:"huà zi",内蒙:"nèi měng",数落:"shǔ luò",逆差:"nì chā",牟利:"móu lì",栅栏:"zhà lan",中标:"zhòng biāo",调档:"diào dàng",佝偻:"gōu lóu",场子:"chǎng zi",甲壳:"jiǎ qiào",重温:"chóng wēn",炮制:"páo zhì",返还:"fǎn huán",自传:"zì zhuàn",高调:"gāo diào",殷红:"yān hóng",固着:"gù zhuó",强求:"qiǎng qiú",本相:"běn xiàng",骄横:"jiāo hèng",草率:"cǎo shuài",气闷:"qì mèn",着色:"zhuó sè",宁肯:"nìng kěn",兴头:"xìng tou",拘泥:"jū nì",夹角:"jiā jiǎo",发髻:"fà jì",猛将:"měng jiàng",约摸:"yuē mo",拖累:"tuō lěi",呢绒:"ní róng",钻探:"zuān tàn",夹层:"jiā céng",落魄:"luò pò",巷道:"hàng dào",运量:"yùn liàng",解闷:"jiě mèn",空儿:"kòng er",估摸:"gū mo",好客:"hào kè",钻孔:"zuān kǒng",糊弄:"hù nòng",荥阳:"xíng yáng",烦闷:"fán mèn",仓卒:"cāng cù",分叉:"fēn chà",厂子:"chǎng zi",小调:"xiǎo diào",少阳:"shào yáng",受降:"shòu xiáng",染坊:"rǎn fáng",胳臂:"gē bei",将门:"jiàng mén",模板:"mú bǎn",配给:"pèi jǐ",为伍:"wéi wǔ",跟头:"gēn tou",划算:"huá suàn",累赘:"léi zhui",哄笑:"hōng xiào",晕眩:"yūn xuàn",干掉:"gàn diào",缝制:"féng zhì",难处:"nán chù",着意:"zhuó yì",蛮横:"mán hèng",奇数:"jī shù",短发:"duǎn fà",生还:"shēng huán",还清:"huán qīng",看护:"kān hù",直率:"zhí shuài",奏乐:"zòu yuè",载客:"zài kè",专横:"zhuān hèng",湮没:"yān mò",空格:"kòng gé",铺垫:"pū diàn",良将:"liáng jiàng",哗啦:"huā lā",散漫:"sǎn màn",脱发:"tuō fà",送还:"sòng huán",埋没:"mái mò",累及:"lěi jí",薄雾:"bó wù",调离:"diào lí",舌苔:"shé tāi",机长:"jī zhǎng",栓塞:"shuān sè",配角:"pèi jué",切口:"qiē kǒu",创口:"chuāng kǒu",哈欠:"hā qian",实弹:"shí dàn",铺平:"pū píng",哈达:"hǎ dá",懒散:"lǎn sǎn",实干:"shí gàn",填空:"tián kòng",刁钻:"diāo zuān",乐师:"yuè shī",量变:"liàng biàn",诱降:"yòu xiáng",搪塞:"táng sè",征调:"zhēng diào",夹道:"jiā dào",干咳:"gān ké",止咳:"zhǐ ké",乐工:"yuè gōng",划过:"huá guò",着火:"zháo huǒ",更正:"gēng zhèng",给付:"jǐ fù",空子:"kòng zi",哪吒:"né zhā",正着:"zhèng zháo",刷子:"shuā zi",丧葬:"sāng zàng",夹带:"jiā dài",安分:"ān fèn",中意:"zhòng yì",长孙:"zhǎng sūn",校订:"jiào dìng",卷曲:"juǎn qū",载运:"zài yùn",投弹:"tóu dàn",柞蚕:"zuò cán",份量:"fèn liàng",调换:"diào huàn",了然:"liǎo rán",咧嘴:"liě zuǐ",典当:"diǎn dàng",寒假:"hán jià",长兄:"zhǎng xiōng",给水:"jǐ shuǐ",须发:"xū fà",枝干:"zhī gàn",属相:"shǔ xiàng",哄抢:"hōng qiǎng",刻划:"kè huà",塞子:"sāi zi",单干:"dān gàn",还乡:"huán xiāng",兆头:"zhào tou",寺观:"sì guàn",督率:"dū shuài",啊哈:"ā ha",割舍:"gē shě",抹布:"mā bù",好恶:"hào wù",下处:"xià chǔ",消长:"xiāo zhǎng",离间:"lí jiàn",准头:"zhǔn tou",校对:"jiào duì",什物:"shí wù",番禺:"pān yú",佛爷:"fó ye",吗啡:"mǎ fēi",盐分:"yán fèn",虎将:"hǔ jiàng",薄荷:"bò he",独处:"dú chǔ",空位:"kòng wèi",铺路:"pū lù",乌拉:"wū lā",调回:"diào huí",来头:"lái tou",闲散:"xián sǎn",胶卷:"jiāo juǎn",冒失:"mào shi",干劲:"gàn jìn",弦乐:"xián yuè",相国:"xiàng guó",丹参:"dān shēn",助兴:"zhù xìng",铺开:"pū kāi",次长:"cì zhǎng",发卡:"fà qiǎ",拮据:"jié jū",刹车:"shā chē",生发:"shēng fà",重播:"chóng bō",缝合:"féng hé",音量:"yīn liàng",少尉:"shào wèi",冲压:"chòng yā",苍劲:"cāng jìng",厚薄:"hòu báo",威吓:"wēi hè",外相:"wài xiàng",呼号:"hū háo",着迷:"zháo mí",挑担:"tiāo dàn",纹路:"wén lù",还俗:"huán sú",强横:"qiáng hèng",着数:"zhāo shù",降顺:"xiáng shùn",挑明:"tiǎo míng",眯缝:"mī feng",分内:"fèn nèi",更衣:"gēng yī",软和:"ruǎn huo",尽兴:"jìn xìng",号子:"hào zi",爪牙:"zhǎo yá",败将:"bài jiàng",猜中:"cāi zhòng",结扎:"jié zā",没空:"méi kòng",夹缝:"jiā fèng",拾掇:"shí duo",掺和:"chān huo",簸箕:"bò ji",电量:"diàn liàng",荷载:"hè zǎi",调式:"diào shì",处身:"chǔ shēn",打手:"dǎ shǒu",弹弓:"dàn gōng",横蛮:"hèng mán",能干:"néng gàn",校点:"jiào diǎn",加载:"jiā zài",干校:"gàn xiào",哄传:"hōng chuán",校注:"jiào zhù",淤塞:"yū sè",马扎:"mǎ zhá",月氏:"yuè zhī",高干:"gāo gàn",经传:"jīng zhuàn",曾孙:"zēng sūn",好斗:"hào dòu",关卡:"guān qiǎ",逃奔:"táo bèn",磨蹭:"mó ceng",牟取:"móu qǔ",颤栗:"zhàn lì",蚂蚱:"mà zha",撮合:"cuō he",趔趄:"liè qie",摔打:"shuāi dǎ",台子:"tái zi",分得:"fēn de",粘着:"nián zhuó",采邑:"cài yì",散装:"sǎn zhuāng",婀娜:"ē nuó",兴味:"xìng wèi",行头:"xíng tou",气量:"qì liàng",调运:"diào yùn",处治:"chǔ zhì",乐音:"yuè yīn",充塞:"chōng sè",恫吓:"dòng hè",论调:"lùn diào",相中:"xiāng zhòng",民乐:"mín yuè",炮仗:"pào zhang",丧服:"sāng fú",骁将:"xiāo jiàng",量刑:"liàng xíng",缝补:"féng bǔ",财会:"cái kuài",大干:"dà gàn",历数:"lì shǔ",校场:"jiào chǎng",塞北:"sài běi",识相:"shí xiàng",辱没:"rǔ mò",鲜亮:"xiān liàng",语塞:"yǔ sè",露脸:"lòu liǎn",凉快:"liáng kuai",腰杆:"yāo gǎn",溜达:"liū da",嘎嘎:"gā gā",公干:"gōng gàn",桔梗:"jié gěng",挑逗:"tiǎo dòu",看门:"kān mén",乐歌:"yuè gē",拓片:"tà piàn",挑动:"tiǎo dòng",准将:"zhǔn jiàng",遒劲:"qiú jìng",磨坊:"mò fáng",逶迤:"wēi yí",搅和:"jiǎo huo",摩挲:"mó suō",作弄:"zuò nòng",苗头:"miáo tou",打颤:"dǎ zhàn",大藏:"dà zàng",畜牲:"chù shēng",勾搭:"gōu da",树荫:"shù yīn",树杈:"shù chà",铁杆:"tiě gǎn",将相:"jiàng xiàng",份子:"fèn zi",视差:"shì chā",绿荫:"lǜ yīn",枪杆:"qiāng gǎn",缝纫:"féng rèn",愁闷:"chóu mèn",点将:"diǎn jiàng",华佗:"huà tuó",劲射:"jìng shè",箱笼:"xiāng lǒng",终了:"zhōng liǎo",鬓发:"bìn fà",结巴:"jiē ba",苦干:"kǔ gàn",看家:"kān jiā",正旦:"zhēng dàn",中肯:"zhòng kěn",厦门:"xià mén",东莞:"dōng guǎn",食量:"shí liàng",宫调:"gōng diào",间作:"jiàn zuò",弹片:"dàn piàn",差池:"chā chí",漂白:"piǎo bái",杠子:"gàng zi",调处:"tiáo chǔ",好动:"hào dòng",转炉:"zhuàn lú",屏气:"bǐng qì",夹板:"jiā bǎn",哀乐:"āi yuè",干道:"gàn dào",苦处:"kǔ chù",劈柴:"pǐ chái",长势:"zhǎng shì",天华:"tiān huá",共处:"gòng chǔ",校验:"jiào yàn",出塞:"chū sài",磨盘:"mò pán",萎靡:"wěi mǐ",奔丧:"bēn sāng",唱和:"chàng hè",大调:"dà diào",非分:"fēi fèn",钻营:"zuān yíng",夹子:"jiā zi",超载:"chāo zài",更始:"gēng shǐ",铃铛:"líng dang",披散:"pī sàn",发还:"fā huán",转轮:"zhuàn lún",横财:"hèng cái",泡桐:"pāo tóng",抛撒:"pāo sǎ",天呀:"tiān yā",糊糊:"hū hu",躯壳:"qū qiào",通量:"tōng liàng",奉还:"fèng huán",午觉:"wǔ jiào",闷棍:"mèn gùn",浪头:"làng tou",砚台:"yàn tái",油坊:"yóu fáng",学长:"xué zhǎng",过载:"guò zài",笔调:"bǐ diào",衣被:"yī bèi",畜产:"xù chǎn",调阅:"diào yuè",蛮干:"mán gàn",曾祖:"zēng zǔ",提干:"tí gàn",变调:"biàn diào",覆没:"fù mò",模子:"mú zi",乐律:"yuè lǜ",称心:"chèn xīn",木杆:"mù gān",重印:"chóng yìn",自省:"zì xǐng",提调:"tí diào",看相:"kàn xiàng",芋头:"yù tou",下切:"xià qiē",塞上:"sài shàng",铺张:"pū zhāng",藤蔓:"téng wàn",薄幸:"bó xìng",解数:"xiè shù",褪去:"tuì qù",霰弹:"xiàn dàn",柚木:"yóu mù",痕量:"hén liàng",雅乐:"yǎ yuè",号哭:"háo kū",诈降:"zhà xiáng",猪圈:"zhū juàn",咋舌:"zé shé",铣床:"xǐ chuáng",防弹:"fáng dàn",健将:"jiàn jiàng",丽水:"lí shuǐ",削发:"xuē fà",空当:"kòng dāng",多相:"duō xiàng",鲜见:"xiǎn jiàn",划桨:"huá jiǎng",载波:"zài bō",跳蚤:"tiào zao",俏皮:"qiào pí",吧嗒:"bā dā",结发:"jié fà",了断:"liǎo duàn",同调:"tóng diào",石磨:"shí mò",时差:"shí chā",鼻塞:"bí sè",挑子:"tiāo zi",推磨:"tuī mò",武侯:"wǔ hóu",抹煞:"mǒ shā",调转:"diào zhuǎn",籍没:"jí mò",还债:"huán zhài",调演:"diào yǎn",分划:"fēn huá",奇偶:"jī ǒu",断喝:"duàn hè",闷雷:"mèn léi",狼藉:"láng jí",饭量:"fàn liàng",还礼:"huán lǐ",转调:"zhuǎn diào",星相:"xīng xiàng",手相:"shǒu xiàng",配乐:"pèi yuè",盖头:"gài tou",连杆:"lián gǎn",簿记:"bù jì",刀把:"dāo bà",量词:"liàng cí",名角:"míng jué",步调:"bù diào",校本:"jiào běn",账簿:"zhàng bù",隽永:"juàn yǒng",稍为:"shāo wéi",易传:"yì zhuàn",乐谱:"yuè pǔ",牵累:"qiān lěi",答理:"dā li",喝斥:"hè chì",吟哦:"yín é",干渠:"gàn qú",海量:"hǎi liàng",精当:"jīng dàng",着床:"zhuó chuáng",月相:"yuè xiàng",庶几:"shù jī",宫观:"gōng guàn",论处:"lùn chǔ",征辟:"zhēng bì",厚朴:"hòu pò",介壳:"jiè qiào",吭哧:"kēng chī",咯血:"kǎ xiě",铺陈:"pū chén",重生:"chóng shēng",乐理:"yuè lǐ",哀号:"āi háo",藏历:"zàng lì",刚劲:"gāng jìng",削平:"xuē píng",浓荫:"nóng yīn",城垛:"chéng duǒ",当差:"dāng chāi",正传:"zhèng zhuàn",并处:"bìng chǔ",创面:"chuāng miàn",旦角:"dàn jué",薄礼:"bó lǐ",晃荡:"huàng dang",臊子:"sào zi",家什:"jiā shí",闷头:"mēn tóu",美发:"měi fà",度数:"dù shu",着凉:"zháo liáng",闯将:"chuǎng jiàng",几案:"jī àn",姘头:"pīn tou",差数:"chā shù",散碎:"sǎn suì",壅塞:"yōng sè",寒颤:"hán zhàn",牵强:"qiān qiǎng",无间:"wú jiàn",轮转:"lún zhuàn",号叫:"háo jiào",铺排:"pū pái",降伏:"xiáng fú",轧钢:"zhá gāng",东阿:"dōng ē",病假:"bìng jià",累加:"lěi jiā",梗塞:"gěng sè",弹夹:"dàn jiā",钻心:"zuān xīn",晃眼:"huǎng yǎn",魔爪:"mó zhǎo",标量:"biāo liàng",憋闷:"biē mèn",猜度:"cāi duó",处士:"chǔ shì",官差:"guān chāi",讨还:"tǎo huán",长门:"cháng mén",馏分:"liú fēn",里弄:"lǐ lòng",色相:"sè xiàng",雅兴:"yǎ xìng",角力:"jué lì",弹坑:"dàn kēng",枝杈:"zhī chà",夹具:"jiā jù",处刑:"chǔ xíng",悍将:"hàn jiàng",好学:"hào xué",好好:"hǎo hǎo",银发:"yín fà",扫把:"sào bǎ",法相:"fǎ xiàng",贵干:"guì gàn",供气:"gōng qì",空余:"kòng yú",捆扎:"kǔn zā",瘠薄:"jí bó",浆糊:"jiàng hu",嘎吱:"gā zhī",调令:"diào lìng",法帖:"fǎ tiè",淋病:"lìn bìng",调派:"diào pài",转盘:"zhuàn pán",供稿:"gōng gǎo",差官:"chāi guān",忧闷:"yōu mèn",教长:"jiào zhǎng",重唱:"chóng chàng",酒兴:"jiǔ xìng",乐坛:"yuè tán",花呢:"huā ní",叱喝:"chì hè",膀臂:"bǎng bì",得空:"dé kòng",转圈:"zhuàn quān",横暴:"hèng bào",哄抬:"hōng tái",引吭:"yǐn háng",载货:"zài huò",中计:"zhòng jì",官长:"guān zhǎng",相面:"xiàng miàn",看头:"kàn tou",盼头:"pàn tou",意兴:"yì xìng",军乐:"jūn yuè",累次:"lěi cì",骨嘟:"gǔ dū",燕赵:"yān zhào",报丧:"bào sāng",弥撒:"mí sa",挨斗:"ái dòu",扁舟:"piān zhōu",丑角:"chǒu jué",吊丧:"diào sāng",强将:"qiáng jiàng",重奏:"chóng zòu",发辫:"fà biàn",着魔:"zháo mó",着法:"zhāo fǎ",盛放:"shèng fàng",填塞:"tián sè",凶横:"xiōng hèng",稽首:"qǐ shǒu",碑帖:"bēi tiè",冲量:"chōng liàng",发菜:"fà cài",假发:"jiǎ fà",翻卷:"fān juǎn",小量:"xiǎo liàng",胶着:"jiāo zhuó",里子:"lǐ zi",调调:"diào diao",散兵:"sǎn bīng",高挑:"gāo tiǎo",播撒:"bō sǎ",夹心:"jiā xīn",扇动:"shān dòng",叨扰:"tāo rǎo",霓裳:"ní cháng",捻子:"niǎn zi",弥缝:"mí féng",撒布:"sǎ bù",场院:"cháng yuàn",省亲:"xǐng qīn",提拉:"tí lā",惯量:"guàn liàng",强逼:"qiáng bī",强征:"qiáng zhēng",晕车:"yùn chē",数道:"shù dào",带累:"dài lèi",拓本:"tà běn",嫌恶:"xián wù",宿将:"sù jiàng",龟裂:"jūn liè",缠夹:"chán jiā",发式:"fà shì",隔扇:"gé shàn",天分:"tiān fèn",癖好:"pǐ hào",四通:"sì tōng",白术:"bái zhú",划伤:"huá shāng",角斗:"jué dòu",听差:"tīng chāi",岁差:"suì chā",丧礼:"sāng lǐ",脉脉:"mò mò",削瘦:"xuē shòu",撒播:"sǎ bō",莎草:"suō cǎo",犍为:"qián wéi",调头:"diào tóu",龙卷:"lóng juǎn",外调:"wài diào",字帖:"zì tiè",卷发:"juǎn fà",揣度:"chuǎi duó",洋相:"yáng xiàng",散光:"sǎn guāng",骨碌:"gū lu",薄命:"bó mìng",笼头:"lóng tóu",咽炎:"yān yán",碌碡:"liù zhou",片儿:"piàn er",纤手:"qiàn shǒu",散体:"sǎn tǐ",内省:"nèi xǐng",强留:"qiáng liú",解送:"jiè sòng",反间:"fǎn jiàn",少壮:"shào zhuàng",留空:"liú kōng",告假:"gào jià",咳血:"ké xuè",薄暮:"bó mù",铺轨:"pū guǐ",磨削:"mó xuē",治丧:"zhì sāng",叉子:"chā zi",哄动:"hōng dòng",蛾子:"é zi",出落:"chū luò",股长:"gǔ zhǎng",贵处:"guì chù",还魂:"huán hún",例假:"lì jià",刹住:"shā zhù",身量:"shēn liàng",同好:"tóng hào",模量:"mó liàng",更生:"gēng shēng",服丧:"fú sāng",率直:"shuài zhí",字模:"zì mú",散架:"sǎn jià",答腔:"dā qiāng",交恶:"jiāo wù",薄情:"bó qíng",眼泡:"yǎn pāo",袅娜:"niǎo nuó",草垛:"cǎo duò",冲劲:"chòng jìn",呢喃:"ní nán",切中:"qiè zhòng",挑灯:"tiǎo dēng",还愿:"huán yuàn",激将:"jī jiàng",更鼓:"gēng gǔ",没药:"mò yào",败兴:"bài xìng",切面:"qiē miàn",散户:"sǎn hù",累进:"lěi jìn",背带:"bēi dài",秤杆:"chèng gǎn",碾坊:"niǎn fáng",簿子:"bù zi",扳手:"bān shǒu",铅山:"yán shān",儒将:"rú jiàng",重光:"chóng guāng",剪发:"jiǎn fà",长上:"zhǎng shàng",小传:"xiǎo zhuàn",压轴:"yā zhòu",弱冠:"ruò guàn",花卷:"huā juǎn",横祸:"hèng huò",夹克:"jiā kè",光晕:"guāng yùn",披靡:"pī mǐ",对调:"duì diào",夹持:"jiā chí",空额:"kòng é",平调:"píng diào",铺床:"pū chuáng",丧钟:"sāng zhōng",作乐:"zuò lè",少府:"shào fǔ",数数:"shuò shuò",奔头:"bèn tou",进给:"jìn jǐ",率性:"shuài xìng",乐子:"lè zi",绑扎:"bǎng zā",挑唆:"tiǎo suō",漂洗:"piǎo xǐ",夹墙:"jiā qiáng",咳喘:"ké chuǎn",乜斜:"miē xie",错处:"cuò chù",闷酒:"mèn jiǔ",时调:"shí diào",重孙:"chóng sūn",经幢:"jīng chuáng",圩场:"xū chǎng",调门:"diào mén",花头:"huā tóu",划拉:"huá la",套色:"tào shǎi",粗率:"cū shuài",相率:"xiāng shuài",款识:"kuǎn zhì",吁请:"yù qǐng",荫蔽:"yīn bì",文蛤:"wén gé",嘀嗒:"dī dā",调取:"diào qǔ",交差:"jiāo chāi",落子:"luò zǐ",相册:"xiàng cè",絮叨:"xù dao",落发:"luò fà",异相:"yì xiàng",浸没:"jìn mò",角抵:"jué dǐ",卸载:"xiè zài",春卷:"chūn juǎn",扎挣:"zhá zheng",畜养:"xù yǎng",吡咯:"bǐ luò",垛子:"duò zi",恶少:"è shào",发际:"fà jì",红苕:"hóng sháo",糨糊:"jiàng hu",哭丧:"kū sāng",稍息:"shào xī",晕船:"yùn chuán",校样:"jiào yàng",外差:"wài chā",脚爪:"jiǎo zhǎo",铺展:"pū zhǎn",芫荽:"yán sui",夹紧:"jiā jǐn",尿泡:"suī pào",丧乱:"sāng luàn",凶相:"xiōng xiàng",华发:"huá fà",打场:"dǎ cháng",云量:"yún liàng",正切:"zhèng qiē",划拳:"huá quán",划艇:"huá tǐng",评传:"píng zhuàn",拉纤:"lā qiàn",句读:"jù dòu",散剂:"sǎn jì",骨殖:"gǔ shi",塞音:"sè yīn",铺叙:"pū xù",阏氏:"yān zhī",冷颤:"lěng zhàn",煞住:"shā zhù",少男:"shào nán",管乐:"guǎn yuè",号啕:"háo táo",纳降:"nà xiáng",拥塞:"yōng sè",万乘:"wàn shèng",杆儿:"gǎn ér",葛藤:"gé téng",簿籍:"bù jí",皮夹:"pí jiā",校准:"jiào zhǔn",允当:"yǔn dàng",器量:"qì liàng",选调:"xuǎn diào",扮相:"bàn xiàng",干才:"gàn cái",基干:"jī gàn",割切:"gē qiē",国乐:"guó yuè",卡壳:"qiǎ ké",辟谷:"bì gǔ",磨房:"mò fáng",咿呀:"yī yā",芥末:"jiè mo",薄技:"bó jì",产假:"chǎn jià",诗兴:"shī xìng",重出:"chóng chū",转椅:"zhuàn yǐ",酌量:"zhuó liang",簿册:"bù cè",藏青:"zàng qīng",的士:"dī shì",调人:"diào rén",解元:"jiè yuán",茎干:"jīng gàn",巨量:"jù liàng",榔头:"láng tou",率真:"shuài zhēn",喷香:"pèn xiāng",锁钥:"suǒ yuè",虾蟆:"há má",相图:"xiàng tú",兴会:"xìng huì",灶头:"zào tóu",重婚:"chóng hūn",钻洞:"zuān dòng",忖度:"cǔn duó",党参:"dǎng shēn",调温:"diào wēn",杆塔:"gān tǎ",葛布:"gé bù",拱券:"gǒng xuàn",夹生:"jiā shēng",露馅:"lòu xiàn",恰切:"qià qiè",散见:"sǎn jiàn",哨卡:"shào qiǎ",烫发:"tàng fà",体量:"tǐ liàng",挺括:"tǐng kuò",系带:"jì dài",相士:"xiàng shì",羊圈:"yáng juàn",转矩:"zhuàn jǔ",吧台:"bā tái",苍术:"cāng zhú",菲薄:"fěi bó",蛤蚧:"gé jiè",蛤蜊:"gé lí",瓜蔓:"guā wàn",怪相:"guài xiàng",临帖:"lín tiè",女红:"nǚ gōng",刨床:"bào chuáng",翘楚:"qiáo chǔ",数九:"shǔ jiǔ",谈兴:"tán xìng",雄劲:"xióng jìng",扎染:"zā rǎn",遮荫:"zhē yīn",周正:"zhōu zhèng",赚头:"zhuàn tou",扒手:"pá shǒu",搀和:"chān huo",诚朴:"chéng pǔ",肚量:"dù liàng",干结:"gān jié",工尺:"gōng chě",家累:"jiā lěi",曲水:"qū shuǐ",沙参:"shā shēn",挑花:"tiǎo huā",阿门:"ā mén",背篓:"bēi lǒu",瘪三:"biē sān",裁处:"cái chǔ",创痛:"chuāng tòng",福相:"fú xiàng",更动:"gēng dòng",豪兴:"háo xìng",还阳:"huán yáng",还嘴:"huán zuǐ",借调:"jiè diào",卷云:"juǎn yún",流弹:"liú dàn",想头:"xiǎng tou",削价:"xuē jià",校阅:"jiào yuè",雅量:"yǎ liàng",别传:"bié zhuàn",薄酒:"bó jiǔ",春假:"chūn jià",发妻:"fà qī",哗哗:"huā huā",宽绰:"kuān chuo",了悟:"liǎo wù",切花:"qiē huā",审度:"shěn duó",应许:"yīng xǔ",转台:"zhuàn tái",仔猪:"zǐ zhū",裁量:"cái liáng",藏戏:"zàng xì",乘兴:"chéng xìng",绸缪:"chóu móu",摧折:"cuī zhé",调经:"tiáo jīng",调职:"diào zhí",缝缀:"féng zhuì",骨朵:"gū duǒ",核儿:"hú er",恒量:"héng liàng",还价:"huán jià",浑朴:"hún pǔ",苦差:"kǔ chāi",面糊:"miàn hù",煞车:"shā chē",省视:"xǐng shì",什锦:"shí jǐn",信差:"xìn chāi",余切:"yú qiē",攒眉:"cuán méi",炸糕:"zhá gāo",钻杆:"zuàn gǎn",扒灰:"pá huī",拌和:"bàn huò",长调:"cháng diào",大溜:"dà liù",抖搂:"dǒu lōu",飞转:"fēi zhuàn",干仗:"gàn zhàng",好胜:"hào shèng",画片:"huà piàn",搅混:"jiǎo hún",螺杆:"luó gǎn",木模:"mù mú",怒号:"nù háo",频数:"pín shù",无宁:"wú níng",遗少:"yí shào",邮差:"yóu chāi",占卦:"zhān guà",占星:"zhān xīng",重审:"chóng shěn",自量:"zì liàng",调防:"diào fáng",发廊:"fà láng",反调:"fǎn diào",缝子:"fèng zi",更夫:"gēng fū",骨子:"gǔ zi",光杆:"guāng gǎn",夹棍:"jiā gùn",居丧:"jū sāng",巨贾:"jù gǔ",看押:"kān yā",空转:"kōng zhuàn",量力:"liàng lì",炮烙:"páo luò",赔还:"péi huán",扑扇:"pū shān",散记:"sǎn jì",散件:"sǎn jiàn",删削:"shān xuē",射干:"shè gàn",条几:"tiáo jī",偷空:"tōu kòng",削壁:"xuē bì",校核:"jiào hé",阴干:"yīn gān",择菜:"zhái cài",重九:"chóng jiǔ",主调:"zhǔ diào",自禁:"zì jīn",吧唧:"bā jī",便溺:"biàn niào",词调:"cí diào",叨咕:"dáo gu",落枕:"lào zhěn",铺砌:"pū qì",刷白:"shuà bái",委靡:"wěi mǐ",系泊:"xì bó",相马:"xiàng mǎ",熨帖:"yù tiē",转筋:"zhuàn jīn",棒喝:"bàng hè",傧相:"bīn xiàng",镐头:"gǎo tóu",间苗:"jiàn miáo",乐池:"yuè chí",卖相:"mài xiàng",屏弃:"bǐng qì",铅弹:"qiān dàn",切变:"qiē biàn",请调:"qǐng diào",群氓:"qún méng",散板:"sǎn bǎn",省察:"xǐng chá",事假:"shì jià",纤绳:"qiàn shéng",重影:"chóng yǐng",耕种:"gēng zhòng",种地:"zhòng dì",种菜:"zhòng cài",栽种:"zāi zhòng",接种:"jiē zhòng",垦种:"kěn zhòng",种殖:"zhòng zhí",种瓜:"zhòng guā",种豆:"zhòng dòu",种树:"zhòng shù",睡着:"shuì zháo",笼子:"lóng zi",重启:"chóng qǐ",重整:"chóng zhěng",重弹:"chóng tán",重足:"chóng zú",重山:"chóng shān",重游:"chóng yóu",重峦:"chóng luán",爷爷:"yé ye",奶奶:"nǎi nai",姥爷:"lǎo ye",爸爸:"bà ba",妈妈:"mā ma",婶婶:"shěn shen",舅舅:"jiù jiu",姑姑:"gū gu",叔叔:"shū shu",姨夫:"yí fu",舅母:"jiù mu",姑父:"gū fu",姐夫:"jiě fu",婆婆:"pó po",公公:"gōng gong",舅子:"jiù zi",姐姐:"jiě jie",哥哥:"gē ge",妹妹:"mèi mei",妹夫:"mèi fu",姨子:"yí zi",宝宝:"bǎo bao",娃娃:"wá wa",孩子:"hái zi",日子:"rì zi",样子:"yàng zi",狮子:"shī zi",身子:"shēn zi",架子:"jià zi",嫂子:"sǎo zi",鼻子:"bí zi",亭子:"tíng zi",折子:"zhé zi",面子:"miàn zi",脖子:"bó zi",辈子:"bèi zi",帽子:"mào zi",拍子:"pāi zi",柱子:"zhù zi",辫子:"biàn zi",鸽子:"gē zi",房子:"fáng zi",丸子:"wán zi",摊子:"tān zi",牌子:"pái zi",胡子:"hú zi",鬼子:"guǐ zi",矮子:"ǎi zi",鸭子:"yā zi",小子:"xiǎo zi",影子:"yǐng zi",屋子:"wū zi",对子:"duì zi",点子:"diǎn zi",本子:"běn zi",种子:"zhǒng zi",儿子:"ér zi",兔子:"tù zi",骗子:"piàn zi",院子:"yuàn zi",猴子:"hóu zi",嗓子:"sǎng zi",侄子:"zhí zi",柿子:"shì zi",钳子:"qián zi",虱子:"shī zi",瓶子:"píng zi",豹子:"bào zi",筷子:"kuài zi",篮子:"lán zi",绳子:"shéng zi",嘴巴:"zuǐ ba",耳朵:"ěr duo",茄子:"qié zi",蚌埠:"bèng bù",崆峒:"kōng tóng",琵琶:"pí pa",蘑菇:"mó gu",葫芦:"hú lu",狐狸:"hú li",桔子:"jú zi",盒子:"hé zi",桌子:"zhuō zi",竹子:"zhú zi",师傅:"shī fu",衣服:"yī fu",袜子:"wà zi",杯子:"bēi zi",刺猬:"cì wei",麦子:"mài zi",队伍:"duì wu",知了:"zhī liǎo",鱼儿:"yú er",馄饨:"hún tun",灯笼:"dēng long",庄稼:"zhuāng jia",聪明:"cōng ming",镜子:"jìng zi",银子:"yín zi",盘子:"pán zi",了却:"liǎo què",力气:"lì qi",席子:"xí zi",林子:"lín zi",朝霞:"zhāo xiá",朝夕:"zhāo xī",朝气:"zhāo qì",翅膀:"chì bǎng",省长:"shěng zhǎng",臧否:"zāng pǐ",否泰:"pǐ tài",变得:"biàn de",丈夫:"zhàng fu",豆腐:"dòu fu",笔杆:"bǐ gǎn",枞阳:"zōng yáng",行人:"xíng rén",打着:"dǎ zhe",第一:"dì yī",万一:"wàn yī",之一:"zhī yī",得之:"dé zhī",统一:"tǒng yī",唯一:"wéi yī",专一:"zhuān yī",单一:"dān yī",如一:"rú yī",其一:"qí yī",合一:"hé yī",逐一:"zhú yī",周一:"zhōu yī",初一:"chū yī",研一:"yán yī",归一:"guī yī",假一:"jiǎ yī",闻一:"wén yī",了了:"liǎo liǎo",公了:"gōng liǎo",私了:"sī liǎo",一月:"yī yuè",一号:"yī hào",一级:"yī jí",一等:"yī děng",一哥:"yī gē",月一:"yuè yī",一一:"yī yī",二一:"èr yī",三一:"sān yī",四一:"sì yī",五一:"wǔ yī",六一:"liù yī",七一:"qī yī",八一:"bā yī",九一:"jiǔ yī","一〇":"yī líng",一零:"yī líng",一二:"yī èr",一三:"yī sān",一四:"yī sì",一五:"yī wǔ",一六:"yī liù",一七:"yī qī",一八:"yī bā",一九:"yī jiǔ",一又:"yī yòu",一饼:"yī bǐng",一楼:"yī lóu",为例:"wéi lì",为准:"wéi zhǔn",沧海:"cāng hǎi",难为:"nán wéi",责难:"zé nàn",患难:"huàn nàn",磨难:"mó nàn",大难:"dà nàn",刁难:"diāo nàn",殉难:"xùn nàn",落难:"luò nàn",罹难:"lí nàn",灾难:"zāi nàn",难民:"nàn mín",苦难:"kǔ nàn",危难:"wēi nàn",发难:"fā nàn",逃难:"táo nàn",避难:"bì nàn",遇难:"yù nàn",阻难:"zǔ nàn",厄难:"è nàn",徇难:"xùn nàn",空难:"kōng nàn",喜欢:"xǐ huan",朝朝:"zhāo zhāo",不行:"bù xíng",轧轧:"yà yà",弯曲:"wān qū",扭曲:"niǔ qū",曲直:"qū zhí",委曲:"wěi qū",酒曲:"jiǔ qū",曲径:"qū jìng",曲解:"qū jiě",歪曲:"wāi qū",曲线:"qū xiàn",曲阜:"qū fù",九曲:"jiǔ qū",曲折:"qū zhé",曲肱:"qū gōng",曲意:"qū yì",仡佬:"gē lǎo"},bue=Object.keys(JS).map(e=>({zh:e,pinyin:JS[e],probability:2e-8,length:2,priority:yl.Normal,dict:Symbol("dict2")})),XS={为什么:"wèi shén me",实际上:"shí jì shang",检察长:"jiǎn chá zhǎng",干什么:"gàn shén me",这会儿:"zhè huì er",尽可能:"jǐn kě néng",董事长:"dǒng shì zhǎng",了不起:"liǎo bù qǐ",参谋长:"cān móu zhǎng",朝鲜族:"cháo xiǎn zú",海内外:"hǎi nèi wài",禁不住:"jīn bú zhù",柏拉图:"bó lā tú",不在乎:"bú zài hu",洛杉矶:"luò shān jī",有点儿:"yǒu diǎn er",迫击炮:"pǎi jī pào",不得了:"bù dé liǎo",马尾松:"mǎ wěi sōng",运输量:"yùn shū liàng",发脾气:"fā pí qi",士大夫:"shì dà fū",鸭绿江:"yā lù jiāng",压根儿:"yà gēn er",对得起:"duì de qǐ",那会儿:"nà huì er",自个儿:"zì gě er",物理量:"wù lǐ liàng",怎么着:"zěn me zhāo",明晃晃:"míng huǎng huǎng",节假日:"jié jià rì",心里话:"xīn lǐ huà",发行量:"fā xíng liàng",兴冲冲:"xìng chōng chōng",分子量:"fēn zǐ liàng",国子监:"guó zǐ jiàn",老大难:"lǎo dà nán",党内外:"dǎng nèi wài",这么着:"zhè me zhāo",少奶奶:"shào nǎi nai",暗地里:"àn dì lǐ",更年期:"gēng nián qī",工作量:"gōng zuò liàng",背地里:"bèi dì lǐ",山里红:"shān li hóng",好好儿:"hǎo hāo er",交响乐:"jiāo xiǎng yuè",好意思:"hǎo yì si",吐谷浑:"tǔ yù hún",没意思:"méi yì si",理发师:"lǐ fà shī",塔什干:"tǎ shí gān",充其量:"chōng qí liàng",靠得住:"kào de zhù",车行道:"chē xíng dào",人行道:"rén xíng dào",中郎将:"zhōng láng jiàng",照明弹:"zhào míng dàn",烟幕弹:"yān mù dàn",没奈何:"mò nài hé",乱哄哄:"luàn hōng hōng",惠更斯:"huì gēng sī",载重量:"zài zhòng liàng",瞧得起:"qiáo de qǐ",纪传体:"jì zhuàn tǐ",阿房宫:"ē páng gōng",卷心菜:"juǎn xīn cài",戏班子:"xì bān zi",过得去:"guò de qù",花岗石:"huā gāng shí",外甥女:"wài sheng nǚ",团团转:"tuán tuán zhuàn",大堡礁:"dà bǎo jiāo",燃烧弹:"rán shāo dàn",劳什子:"láo shí zi",摇滚乐:"yáo gǔn yuè",夹竹桃:"jiā zhú táo",闹哄哄:"nào hōng hōng",三连冠:"sān lián guàn",重头戏:"zhòng tóu xì",二人转:"èr rén zhuàn",节骨眼:"jiē gǔ yǎn",知识面:"zhī shi miàn",护士长:"hù shi zhǎng",信号弹:"xìn hào dàn",干电池:"gān diàn chí",枪杆子:"qiāng gǎn zi",哭丧棒:"kū sāng bàng",鼻咽癌:"bí yān ái",瓦岗军:"wǎ gāng jūn",买得起:"mǎi de qǐ",癞蛤蟆:"lài há ma",脊梁骨:"jǐ liang gǔ",子母弹:"zǐ mǔ dàn",开小差:"kāi xiǎo chāi",女强人:"nǚ qiáng rén",英雄传:"yīng xióng zhuàn",爵士乐:"jué shì yuè",说笑话:"shuō xiào hua",碰头会:"pèng tóu huì",玻璃钢:"bō li gāng",曳光弹:"yè guāng dàn",少林拳:"shào lín quán",咏叹调:"yǒng tàn diào",少先队:"shào xiān duì",灵长目:"líng zhǎng mù",对着干:"duì zhe gàn",蒙蒙亮:"méng méng liàng",软骨头:"ruǎn gǔ tou",铺盖卷:"pū gài juǎn",和稀泥:"huò xī ní",背黑锅:"bēi hēi guō",红彤彤:"hóng tōng tōng",武侯祠:"wǔ hóu cí",打哆嗦:"dǎ duō suo",户口簿:"hù kǒu bù",马尾藻:"mǎ wěi zǎo",夜猫子:"yè māo zi",打手势:"dǎ shǒu shì",龙王爷:"lóng wáng yé",气头上:"qì tóu shang",糊涂虫:"hú tu chóng",笔杆子:"bǐ gǎn zi",占便宜:"zhàn pián yi",打主意:"dǎ zhǔ yì",多弹头:"duō dàn tóu",露一手:"lòu yì shǒu",堰塞湖:"yàn sè hú",保得住:"bǎo de zhù",趵突泉:"bào tū quán",奥得河:"ào de hé",司务长:"sī wù zhǎng",禁不起:"jīn bù qǐ",什刹海:"shí chà hǎi",莲花落:"lián huā lào",见世面:"jiàn shì miàn",豁出去:"huō chū qù",电位差:"diàn wèi chā",挨个儿:"āi gè er",那阵儿:"nà zhèn er",肺活量:"fèi huó liàng",大师傅:"dà shī fu",掷弹筒:"zhì dàn tǒng",打呼噜:"dǎ hū lu",广渠门:"ān qú mén",未见得:"wèi jiàn dé",大婶儿:"dà shěn er",谈得来:"tán de lái",脚丫子:"jiǎo yā zi",空包弹:"kōng bāo dàn",窝里斗:"wō li dòu",弹着点:"dàn zhuó diǎn",个头儿:"gè tóu er",看得起:"kàn de qǐ",糊涂账:"hú tu zhàng",大猩猩:"dà xīng xing",禁得起:"jīn de qǐ",法相宗:"fǎ xiàng zōng",可怜相:"kě lián xiàng",吃得下:"chī de xià",汉堡包:"hàn bǎo bāo",闹嚷嚷:"nào rāng rāng",数来宝:"shǔ lái bǎo",合得来:"hé de lái",干性油:"gān xìng yóu",闷葫芦:"mèn hú lu",呱呱叫:"guā guā jiào",西洋参:"xī yáng shēn",林荫道:"lín yīn dào",拉家常:"lā jiā cháng",卷铺盖:"juǎn pū gài",过得硬:"guò de yìng",飞将军:"fēi jiāng jūn",挑大梁:"tiǎo dà liáng",哈巴狗:"hǎ ba gǒu",过家家:"guò jiā jiā",催泪弹:"cuī lèi dàn",雨夹雪:"yǔ jiā xuě",敲竹杠:"qiāo zhú gàng",列车长:"liè chē zhǎng",华达呢:"huá dá ní",犯得着:"fàn de zháo",土疙瘩:"tǔ gē da",煞风景:"shā fēng jǐng",轻量级:"qīng liàng jí",羞答答:"xiū dā dā",石子儿:"shí zǐ er",达姆弹:"dá mǔ dàn",科教片:"kē jiào piān",侃大山:"kǎn dà shān",丁点儿:"dīng diǎn er",吃得消:"chī de xiāo",捋虎须:"luō hǔ xū",高丽参:"gāo lí shēn",众生相:"zhòng shēng xiàng",咽峡炎:"yān xiá yán",禁得住:"jīn de zhù",吃得开:"chī de kāi",柞丝绸:"zuò sī chóu",应声虫:"yìng shēng chóng",数得着:"shǔ de zháo",傻劲儿:"shǎ jìn er",铅玻璃:"qiān bō li",可的松:"kě dì sōng",划得来:"huá de lái",晕乎乎:"yūn hū hū",屎壳郎:"shǐ ke làng",尥蹶子:"liào juě zi",藏红花:"zàng hóng huā",闷罐车:"mèn guàn chē",卡脖子:"qiǎ bó zi",红澄澄:"hóng deng deng",赶得及:"gǎn de jí",当间儿:"dāng jiàn er",露马脚:"lòu mǎ jiǎo",鸡内金:"jī nèi jīn",犯得上:"fàn de shàng",钉齿耙:"dīng chǐ bà",饱和点:"bǎo hé diǎn",龙爪槐:"lóng zhǎo huái",喝倒彩:"hè dào cǎi",定冠词:"dìng guàn cí",担担面:"dàn dan miàn",吃得住:"chī de zhù",爪尖儿:"zhuǎ jiān er",支着儿:"zhī zhāo er",折跟头:"zhē gēn tou",阴着儿:"yīn zhāo er",烟卷儿:"yān juǎn er",宣传弹:"xuān chuán dàn",信皮儿:"xìn pí er",弦切角:"xián qiē jiǎo",缩砂密:"sù shā mì",说得来:"shuō de lái",水漂儿:"shuǐ piāo er",耍笔杆:"shuǎ bǐ gǎn",数得上:"shǔ de shàng",数不着:"shǔ bù zháo",数不清:"shǔ bù qīng",什件儿:"shí jiàn er",生死簿:"shēng sǐ bù",扇风机:"shān fēng jī",撒呓挣:"sā yì zheng",日记簿:"rì jì bù",热得快:"rè de kuài",亲家公:"qìng jia gōng",奇函数:"jī hán shù",拍纸簿:"pāi zhǐ bù",努劲儿:"nǔ jìn er",泥娃娃:"ní wá wa",内切圆:"nèi qiē yuán",哪会儿:"nǎ huì er",闷头儿:"mēn tóu er",没谱儿:"méi pǔ er",铆劲儿:"mǎo jìn er",溜肩膀:"liū jiān bǎng",了望台:"liào wàng tái",老来少:"lǎo lái shào",坤角儿:"kūn jué er",考勤簿:"kǎo qín bù",卷笔刀:"juǎn bǐ dāo",进给量:"jìn jǐ liàng",划不来:"huá bù lái",汗褂儿:"hàn guà er",鼓囊囊:"gǔ nāng nāng",够劲儿:"gòu jìn er",公切线:"gōng qiē xiàn",搁得住:"gé de zhù",赶浪头:"gǎn làng tóu",赶得上:"gǎn de shàng",干酵母:"gān jiào mǔ",嘎渣儿:"gā zhā er",嘎嘣脆:"gā bēng cuì",对得住:"duì de zhù",逗闷子:"dòu mèn zi",顶呱呱:"dǐng guā guā",滴溜儿:"dī liù er",大轴子:"dà zhòu zi",打板子:"dǎ bǎn zi",寸劲儿:"cùn jìn er",醋劲儿:"cù jìn er",揣手儿:"chuāi shǒu er",冲劲儿:"chòng jìn er",吃得来:"chī de lái",不更事:"bù gēng shì",奔头儿:"bèn tou er",百夫长:"bǎi fū zhǎng",娃娃亲:"wá wa qīn",死劲儿:"sǐ jìn er",骨朵儿:"gū duǒ er",功劳簿:"gōng láo bù",都江堰:"dū jiāng yàn",一担水:"yí dàn shuǐ",否极泰:"pǐ jí tài",泰来否:"tài lái pǐ",咳特灵:"ké tè líng",开户行:"kāi hù háng",郦食其:"lì yì jī",花事了:"huā shì liǎo",一更更:"yì gēng gēng",一重山:"yì chóng shān",风一更:"fēng yì gēng",雪一更:"xuě yì gēng",归一码:"guī yì mǎ",星期一:"xīng qī yī",礼拜一:"lǐ bài yī",一季度:"yī jì dù",一月一:"yī yuè yī",一字马:"yī zì mǎ",一是一:"yī shì yī",一次方:"yī cì fāng",一阳指:"yī yáng zhǐ",一字决:"yī zì jué",一年级:"yī nián jí",一不做:"yī bú zuò",屈戌儿:"qū qu ér",难为水:"nán wéi shuǐ",难为情:"nán wéi qíng",行一行:"xíng yì háng",别别的:"biè bié de",干哪行:"gàn nǎ háng",干一行:"gàn yì háng",曲别针:"qū bié zhēn"},Aue=Object.keys(XS).map(e=>({zh:e,pinyin:XS[e],probability:2e-8,length:3,priority:yl.Normal,dict:Symbol("dict3")})),e_={成吉思汗:"chéng jí sī hán",四通八达:"sì tōng bā dá",一模一样:"yì mú yí yàng",青藏高原:"qīng zàng gāo yuán",阿弥陀佛:"ē mí tuó fó",解放思想:"jiè fàng sī xiǎng",所作所为:"suǒ zuò suǒ wéi",迷迷糊糊:"mí mí hu hū",荷枪实弹:"hè qiāng shí dàn",兴高采烈:"xìng gāo cǎi liè",无能为力:"wú néng wéi lì",布鲁塞尔:"bù lǔ sài ěr",为所欲为:"wéi suǒ yù wéi",克什米尔:"kè shí mǐ ěr",没完没了:"méi wán méi liǎo",不为人知:"bù wéi rén zhī",结结巴巴:"jiē jiē bā bā",前仆后继:"qián pū hòu jì",铺天盖地:"pū tiān gài dì",直截了当:"zhí jié liǎo dàng",供不应求:"gōng bú yìng qiú",御史大夫:"yù shǐ dà fū",不为瓦全:"bù wéi wǎ quán",不可收拾:"bù kě shōu shi",胡作非为:"hú zuò fēi wéi",分毫不差:"fēn háo bú chà",模模糊糊:"mó mó hu hū",不足为奇:"bù zú wéi qí",悄无声息:"qiǎo wú shēng xī",了如指掌:"liǎo rú zhǐ zhǎng",深恶痛绝:"shēn wù tòng jué",高高兴兴:"gāo gāo xìng xìng",唉声叹气:"āi shēng tàn qì",汉藏语系:"hàn zàng yǔ xì",处心积虑:"chǔ xīn jī lǜ",泣不成声:"qì bù chéng shēng",半夜三更:"bàn yè sān gēng",失魂落魄:"shī hún luò pò",二十八宿:"èr shí bā xiù",转来转去:"zhuàn lái zhuàn qù",数以万计:"shǔ yǐ wàn jì",相依为命:"xiāng yī wéi mìng",恋恋不舍:"liàn liàn bù shě",屈指可数:"qū zhǐ kě shǔ",神出鬼没:"shén chū guǐ mò",结结实实:"jiē jiē shí shí",有的放矢:"yǒu dì fàng shǐ",叽哩咕噜:"jī lǐ gū lū",调兵遣将:"diào bīng qiǎn jiàng",载歌载舞:"zài gē zài wǔ",转危为安:"zhuǎn wēi wéi ān",踏踏实实:"tā tā shi shí",桑给巴尔:"sāng jǐ bā ěr",装模作样:"zhuāng mú zuò yàng",见义勇为:"jiàn yì yǒng wéi",相差无几:"xiāng chā wú jǐ",叹为观止:"tàn wéi guān zhǐ",闷闷不乐:"mèn mèn bú lè",喜怒哀乐:"xǐ nù āi lè",鲜为人知:"xiǎn wéi rén zhī",张牙舞爪:"zhāng yá wǔ zhǎo",为非作歹:"wéi fēi zuò dǎi",含糊其辞:"hán hú qí cí",疲于奔命:"pí yú bēn mìng",勉为其难:"miǎn wéi qí nán",依依不舍:"yī yī bù shě",顶头上司:"dǐng tóu shàng si",不着边际:"bù zhuó biān jì",大模大样:"dà mú dà yàng",寻欢作乐:"xún huān zuò lè",一走了之:"yì zǒu liǎo zhī",字里行间:"zì lǐ háng jiān",含含糊糊:"hán hán hu hū",恰如其分:"qià rú qí fèn",破涕为笑:"pò tì wéi xiào",深更半夜:"shēn gēng bàn yè",千差万别:"qiān chā wàn bié",数不胜数:"shǔ bú shèng shǔ",据为己有:"jù wéi jǐ yǒu",天旋地转:"tiān xuán dì zhuàn",养尊处优:"yǎng zūn chǔ yōu",玻璃纤维:"bō li xiān wéi",吵吵闹闹:"chāo chao nào nào",晕头转向:"yūn tóu zhuàn xiàng",土生土长:"tǔ shēng tǔ zhǎng",宁死不屈:"nìng sǐ bù qū",不省人事:"bù xǐng rén shì",尽力而为:"jìn lì ér wéi",精明强干:"jīng míng qiáng gàn",唠唠叨叨:"láo lao dāo dāo",叽叽喳喳:"jī ji zhā zhā",功不可没:"gōng bù kě mò",锲而不舍:"qiè ér bù shě",排忧解难:"pái yōu jiě nàn",稀里糊涂:"xī li hú tú",各有所长:"gè yǒu suǒ cháng",的的确确:"dí dí què què",哄堂大笑:"hōng táng dà xiào",听而不闻:"tīng ér bù wén",刀耕火种:"dāo gēng huǒ zhòng",内分泌腺:"nèi fèn mì xiàn",化险为夷:"huà xiǎn wéi yí",百发百中:"bǎi fā bǎi zhòng",重见天日:"chóng jiàn tiān rì",反败为胜:"fǎn bài wéi shèng",一了百了:"yì liǎo bǎi liǎo",大大咧咧:"dà da liē liē",心急火燎:"xīn jí huǒ liǎo",粗心大意:"cū xīn dà yi",鸡皮疙瘩:"jī pí gē da",夷为平地:"yí wéi píng dì",日积月累:"rì jī yuè lěi",设身处地:"shè shēn chǔ dì",投其所好:"tóu qí suǒ hào",间不容发:"jiān bù róng fà",人满为患:"rén mǎn wéi huàn",穷追不舍:"qióng zhuī bù shě",为时已晚:"wéi shí yǐ wǎn",如数家珍:"rú shǔ jiā zhēn",心里有数:"xīn lǐ yǒu shù",以牙还牙:"yǐ yá huán yá",神不守舍:"shén bù shǒu shě",孟什维克:"mèng shí wéi kè",各自为战:"gè zì wéi zhàn",怨声载道:"yuàn shēng zài dào",救苦救难:"jiù kǔ jiù nàn",好好先生:"hǎo hǎo xiān sheng",怪模怪样:"guài mú guài yàng",抛头露面:"pāo tóu lù miàn",游手好闲:"yóu shǒu hào xián",无所不为:"wú suǒ bù wéi",调虎离山:"diào hǔ lí shān",步步为营:"bù bù wéi yíng",好大喜功:"hào dà xǐ gōng",众矢之的:"zhòng shǐ zhī dì",长生不死:"cháng shēng bù sǐ",蔚为壮观:"wèi wéi zhuàng guān",不可胜数:"bù kě shèng shǔ",鬼使神差:"guǐ shǐ shén chāi",洁身自好:"jié shēn zì hào",敢作敢为:"gǎn zuò gǎn wéi",茅塞顿开:"máo sè dùn kāi",走马换将:"zǒu mǎ huàn jiàng",为时过早:"wéi shí guò zǎo",为人师表:"wéi rén shī biǎo",阴差阳错:"yīn chā yáng cuò",油腔滑调:"yóu qiāng huá diào",重蹈覆辙:"chóng dǎo fù zhé",骂骂咧咧:"mà ma liē liē",絮絮叨叨:"xù xù dāo dāo",如履薄冰:"rú lǚ bó bīng",损兵折将:"sǔn bīng zhé jiàng",拐弯抹角:"guǎi wān mò jiǎo",像模像样:"xiàng mú xiàng yàng",供过于求:"gōng guò yú qiú",开花结果:"kāi huā jiē guǒ",仔仔细细:"zǐ zǐ xì xì",川藏公路:"chuān zàng gōng lù",河北梆子:"hé běi bāng zi",长年累月:"cháng nián lěi yuè",正儿八经:"zhèng er bā jīng",不识抬举:"bù shí tái ju",重振旗鼓:"chóng zhèn qí gǔ",气息奄奄:"qì xī yān yān",紧追不舍:"jǐn zhuī bù shě",服服帖帖:"fú fu tiē tiē",强词夺理:"qiǎng cí duó lǐ",噼里啪啦:"pī li pā lā",人才济济:"rén cái jǐ jǐ",发人深省:"fā rén shēn xǐng",不足为凭:"bù zú wéi píng",为富不仁:"wéi fù bù rén",连篇累牍:"lián piān lěi dú",呼天抢地:"hū tiān qiāng dì",落落大方:"luò luò dà fāng",自吹自擂:"zì chuī zì léi",乐善好施:"lè shàn hào shī",以攻为守:"yǐ gōng wéi shǒu",磨磨蹭蹭:"mó mó cèng cèng",削铁如泥:"xuē tiě rú ní",助纣为虐:"zhù zhòu wéi nüè",以退为进:"yǐ tuì wéi jìn",嘁嘁喳喳:"qī qī chā chā",枪林弹雨:"qiāng lín dàn yǔ",令人发指:"lìng rén fà zhǐ",转败为胜:"zhuǎn bài wéi shèng",转弯抹角:"zhuǎn wān mò jiǎo",在劫难逃:"zài jié nán táo",正当防卫:"zhèng dàng fáng wèi",不足为怪:"bù zú wéi guài",难兄难弟:"nàn xiōng nàn dì",咿咿呀呀:"yī yī yā yā",弹尽粮绝:"dàn jìn liáng jué",阿谀奉承:"ē yú fèng chéng",稀里哗啦:"xī li huā lā",返老还童:"fǎn lǎo huán tóng",好高骛远:"hào gāo wù yuǎn",鹿死谁手:"lù sǐ shéi shǒu",差强人意:"chā qiáng rén yì",大吹大擂:"dà chuī dà léi",成家立业:"chéng jiā lì yè",自怨自艾:"zì yuàn zì yì",负债累累:"fù zhài lěi lěi",古为今用:"gǔ wéi jīn yòng",入土为安:"rù tǔ wéi ān",下不为例:"xià bù wéi lì",一哄而上:"yì hōng ér shàng",没头苍蝇:"méi tóu cāng ying",天差地远:"tiān chā dì yuǎn",风卷残云:"fēng juǎn cán yún",多灾多难:"duō zāi duō nàn",乳臭未干:"rǔ xiù wèi gān",行家里手:"háng jiā lǐ shǒu",狼狈为奸:"láng bèi wéi jiān",处变不惊:"chǔ biàn bù jīng",一唱一和:"yí chàng yí hè",一念之差:"yí niàn zhī chā",金蝉脱壳:"jīn chán tuō qiào",滴滴答答:"dī dī dā dā",硕果累累:"shuò guǒ léi léi",好整以暇:"hào zhěng yǐ xiá",红得发紫:"hóng de fā zǐ",传为美谈:"chuán wéi měi tán",富商大贾:"fù shāng dà gǔ",四海为家:"sì hǎi wéi jiā",了若指掌:"liǎo ruò zhǐ zhǎng",大有可为:"dà yǒu kě wéi",出头露面:"chū tóu lù miàn",鼓鼓囊囊:"gǔ gu nāng nāng",窗明几净:"chuāng míng jī jìng",泰然处之:"tài rán chǔ zhī",怒发冲冠:"nù fà chōng guān",有机玻璃:"yǒu jī bō li",骨头架子:"gǔ tou jià zi",义薄云天:"yì bó yún tiān",一丁点儿:"yī dīng diǎn er",时来运转:"shí lái yùn zhuǎn",陈词滥调:"chén cí làn diào",化整为零:"huà zhěng wéi líng",火烧火燎:"huǒ shāo huǒ liǎo",干脆利索:"gàn cuì lì suǒ",吊儿郎当:"diào er láng dāng",广种薄收:"guǎng zhòng bó shōu",种瓜得瓜:"zhòng guā dé guā",种豆得豆:"zhòng dòu dé dòu",难舍难分:"nán shě nán fēn",歃血为盟:"shà xuè wéi méng",奋发有为:"fèn fā yǒu wéi",阴错阳差:"yīn cuò yáng chā",东躲西藏:"dōng duǒ xī cáng",烟熏火燎:"yān xūn huǒ liǎo",钻牛角尖:"zuān niú jiǎo jiān",乔装打扮:"qiáo zhuāng dǎ bàn",改弦更张:"gǎi xián gēng zhāng",河南梆子:"hé nán bāng zi",好吃懒做:"hào chī lǎn zuò",何乐不为:"hé lè bù wéi",大出风头:"dà chū fēng tóu",攻城掠地:"gōng chéng lüè dì",漂漂亮亮:"piào piào liang liang",折衷主义:"zhé zhōng zhǔ yì",大马哈鱼:"dà mǎ hǎ yú",绿树成荫:"lǜ shù chéng yīn",率先垂范:"shuài xiān chuí fàn",家长里短:"jiā cháng lǐ duǎn",宽大为怀:"kuān dà wéi huái",左膀右臂:"zuǒ bǎng yòu bì",一笑了之:"yí xiào liǎo zhī",天下为公:"tiān xià wéi gōng",还我河山:"huán wǒ hé shān",何足为奇:"hé zú wéi qí",好自为之:"hǎo zì wéi zhī",风姿绰约:"fēng zī chuò yuē",大雨滂沱:"dà yǔ pāng tuó",传为佳话:"chuán wéi jiā huà",吃里扒外:"chī lǐ pá wài",重操旧业:"chóng cāo jiù yè",小家子气:"xiǎo jiā zi qì",少不更事:"shào bù gēng shì",难分难舍:"nán fēn nán shě",添砖加瓦:"tiān zhuān jiā wǎ",是非分明:"shì fēi fēn míng",舍我其谁:"shě wǒ qí shuí",偏听偏信:"piān tīng piān xìn",量入为出:"liàng rù wéi chū",降龙伏虎:"xiáng lóng fú hǔ",钢化玻璃:"gāng huà bō li",正中下怀:"zhèng zhòng xià huái",以身许国:"yǐ shēn xǔ guó",一语中的:"yì yǔ zhòng dì",丧魂落魄:"sàng hún luò pò",三座大山:"sān zuò dà shān",济济一堂:"jǐ jǐ yì táng",好事之徒:"hào shì zhī tú",干净利索:"gàn jìng lì suǒ",出将入相:"chū jiàng rù xiàng",袅袅娜娜:"niǎo niǎo nuó nuó",狐狸尾巴:"hú li wěi ba",好逸恶劳:"hào yì wù láo",大而无当:"dà ér wú dàng",打马虎眼:"dǎ mǎ hu yǎn",板上钉钉:"bǎn shàng dìng dīng",吆五喝六:"yāo wǔ hè liù",虾兵蟹将:"xiā bīng xiè jiàng",水调歌头:"shuǐ diào gē tóu",数典忘祖:"shǔ diǎn wàng zǔ",人事不省:"rén shì bù xǐng",曲高和寡:"qǔ gāo hè guǎ",屡教不改:"lǚ jiào bù gǎi",互为因果:"hù wéi yīn guǒ",互为表里:"hù wéi biǎo lǐ",厚此薄彼:"hòu cǐ bó bǐ",过关斩将:"guò guān zhǎn jiàng",疙疙瘩瘩:"gē ge dā dā",大腹便便:"dà fù pián pián",走为上策:"zǒu wéi shàng cè",冤家对头:"yuān jia duì tóu",有隙可乘:"yǒu xì kě chèng",一鳞半爪:"yì lín bàn zhǎo",片言只语:"piàn yán zhǐ yǔ",开花结实:"kāi huā jié shí",经年累月:"jīng nián lěi yuè",含糊其词:"hán hú qí cí",寡廉鲜耻:"guǎ lián xiǎn chǐ",成年累月:"chéng nián lěi yuè",不徇私情:"bú xùn sī qíng",不当人子:"bù dāng rén zǐ",膀大腰圆:"bǎng dà yāo yuán",指腹为婚:"zhǐ fù wéi hūn",这么点儿:"zhè me diǎn er",意兴索然:"yì xīng suǒ rán",绣花枕头:"xiù huā zhěn tou",无的放矢:"wú dì fàng shǐ",望闻问切:"wàng wén wèn qiè",舍己为人:"shě jǐ wèi rén",穷年累月:"qióng nián lěi yuè",排难解纷:"pái nàn jiě fēn",处之泰然:"chǔ zhī tài rán",指鹿为马:"zhǐ lù wéi mǎ",危如累卵:"wēi rú lěi luǎn",天兵天将:"tiān bīng tiān jiàng",舍近求远:"shě jìn qiú yuǎn",南腔北调:"nán qiāng běi diào",苦中作乐:"kǔ zhōng zuò lè",厚积薄发:"hòu jī bó fā",臭味相投:"xiù wèi xiāng tóu",长幼有序:"zhǎng yòu yǒu xù",逼良为娼:"bī liáng wéi chāng",悲悲切切:"bēi bēi qiè qiē",败军之将:"bài jūn zhī jiàng",欺行霸市:"qī háng bà shì",削足适履:"xuē zú shì lǚ",先睹为快:"xiān dǔ wéi kuài",啼饥号寒:"tí jī háo hán",疏不间亲:"shū bú jiàn qīn",神差鬼使:"shén chāi guǐ shǐ",敲敲打打:"qiāo qiāo dǎ dǎ",平铺直叙:"píng pū zhí xù",没头没尾:"méi tóu mò wěi",寥寥可数:"liáo liáo kě shǔ",哼哈二将:"hēng hā èr jiàng",鹤发童颜:"hè fà tóng yán",各奔前程:"gè bèn qián chéng",弹无虚发:"dàn wú xū fā",大人先生:"dà rén xiān sheng",与民更始:"yǔ mín gēng shǐ",树碑立传:"shù bēi lì zhuàn",是非得失:"shì fēi dé shī",实逼处此:"shí bī chǔ cǐ",塞翁失马:"sài wēng shī mǎ",日薄西山:"rì bó xī shān",切身体会:"qiè shēn tǐ huì",片言只字:"piàn yán zhǐ zì",跑马卖解:"pǎo mǎ mài xiè",宁折不弯:"nìng zhé bù wān",零零散散:"líng líng sǎn sǎn",量体裁衣:"liàng tǐ cái yī",连中三元:"lián zhòng sān yuán",礼崩乐坏:"lǐ bēng yuè huài",不为已甚:"bù wéi yǐ shèn",转悲为喜:"zhuǎn bēi wéi xǐ",以眼还眼:"yǐ yǎn huán yǎn",蔚为大观:"wèi wéi dà guān",未为不可:"wèi wéi bù kě",童颜鹤发:"tóng yán hè fà",朋比为奸:"péng bǐ wéi jiān",莫此为甚:"mò cǐ wéi shèn",夹枪带棒:"jiā qiāng dài bàng",富商巨贾:"fù shāng jù jiǎ",淡然处之:"dàn rán chǔ zhī",箪食壶浆:"dān shí hú jiāng",创巨痛深:"chuāng jù tòng shēn",草长莺飞:"cǎo zhǎng yīng fēi",坐视不救:"zuò shī bú jiù",以己度人:"yǐ jǐ duó rén",随行就市:"suí háng jiù shì",文以载道:"wén yǐ zài dào",文不对题:"wén bú duì tí",铁板钉钉:"tiě bǎn dìng dīng",身体发肤:"shēn tǐ fà fū",缺吃少穿:"quē chī shǎo chuān",目无尊长:"mù wú zūn zhǎng",吉人天相:"jí rén tiān xiàng",毁家纾难:"huǐ jiā shū nàn",钢筋铁骨:"gāng jīn tiě gǔ",丢卒保车:"diū zú bǎo jū",丢三落四:"diū sān là sì",闭目塞听:"bì mù sè tīng",削尖脑袋:"xuē jiān nǎo dài",为非作恶:"wéi fēi zuò è",人才难得:"rén cái nán dé",情非得已:"qíng fēi dé yǐ",切中要害:"qiè zhòng yào hài",火急火燎:"huǒ jí huǒ liǎo",画地为牢:"huà dì wéi láo",好酒贪杯:"hào jiǔ tān bēi",长歌当哭:"cháng gē dàng kū",载沉载浮:"zài chén zài fú",遇难呈祥:"yù nàn chéng xiáng",榆木疙瘩:"yú mù gē da",以邻为壑:"yǐ lín wéi hè",洋为中用:"yáng wéi zhōng yòng",言为心声:"yán wéi xīn shēng",言必有中:"yán bì yǒu zhòng",图穷匕见:"tú qióng bǐ xiàn",滂沱大雨:"páng tuó dà yǔ",目不暇给:"mù bù xiá jǐ",量才录用:"liàng cái lù yòng",教学相长:"jiào xué xiāng zhǎng",悔不当初:"huǐ bù dāng chū",呼幺喝六:"hū yāo hè liù",不足为训:"bù zú wéi xùn",不拘形迹:"bù jū xíng jī",傍若无人:"páng ruò wú rén",罪责难逃:"zuì zé nán táo",自我吹嘘:"zì wǒ chuī xū",转祸为福:"zhuǎn huò wéi fú",勇冠三军:"yǒng guàn sān jūn",易地而处:"yì dì ér chǔ",卸磨杀驴:"xiè mò shā lǘ",玩儿不转:"wán ér bú zhuàn",天道好还:"tiān dào hǎo huán",身单力薄:"shēn dān lì bó",撒豆成兵:"sǎ dòu chéng bīng",片纸只字:"piàn zhǐ zhī zì",宁缺毋滥:"nìng quē wú làn",没没无闻:"mò mò wú wén",量力而为:"liàng lì ér wéi",历历可数:"lì lì kě shǔ",口碑载道:"kǒu bēi zài dào",君子好逑:"jūn zǐ hǎo qiú",好为人师:"hào wéi rén shī",豪商巨贾:"háo shāng jù jiǎ",各有所好:"gè yǒu suǒ hào",度德量力:"duó dé liàng lì",指天为誓:"zhǐ tiān wéi shì",逸兴遄飞:"yì xìng chuán fēi",心宽体胖:"xīn kuān tǐ pán",为德不卒:"wéi dé bù zú",天下为家:"tiān xià wéi jiā",视为畏途:"shì wéi wèi tú",三灾八难:"sān zāi bā nàn",沐猴而冠:"mù hóu ér guàn",哩哩啦啦:"lī li lā lā",见缝就钻:"jiàn fèng jiù zuān",夹层玻璃:"jiā céng bō li",急公好义:"jí gōng hào yì",积年累月:"jī nián lěi yuè",划地为牢:"huá dì wéi láo",更名改姓:"gēng míng gǎi xìng",奉为圭臬:"fèng wéi guī niè",多难兴邦:"duō nàn xīng bāng",不破不立:"bú pò bú lì",坐地自划:"zuò dì zì huá",坐不重席:"zuò bù chóng xí",坐不窥堂:"zuò bù kuī táng",作嫁衣裳:"zuò jià yī shang",左枝右梧:"zuǒ zhī yòu wú",左宜右有:"zuǒ yí yòu yǒu",钻头觅缝:"zuān tóu mì fèng",钻天打洞:"zuān tiān dǎ dòng",钻皮出羽:"zuān pí chū yǔ",钻火得冰:"zuān huǒ dé bīng",钻洞觅缝:"zuàn dòng mì féng",钻冰求火:"zuān bīng qiú huǒ",子为父隐:"zǐ wéi fù yǐn",擢发难数:"zhuó fà nán shǔ",着人先鞭:"zhuó rén xiān biān",斫雕为朴:"zhuó diāo wéi pǔ",锥处囊中:"zhuī chǔ náng zhōng",椎心饮泣:"chuí xīn yǐn qì",椎心泣血:"chuí xīn qì xuè",椎牛飨士:"chuí niú xiǎng shì",椎牛歃血:"chuí niú shà xuè",椎牛发冢:"chuí niú fà zhǒng",椎埋屠狗:"chuí mái tú gǒu",椎埋狗窃:"chuí mái gǒu qiè",壮发冲冠:"zhuàng fā chōng guàn",庄严宝相:"zhuāng yán bǎo xiàng",转愁为喜:"zhuǎn chóu wéi xǐ",转嗔为喜:"zhuǎn chēn wéi xǐ",拽巷啰街:"zhuài xiàng luó jiē",拽耙扶犁:"zhuāi pá fú lí",拽布拖麻:"zhuài bù tuō má",箸长碗短:"zhù cháng wǎn duǎn",铸剑为犁:"zhù jiàn wéi lí",杼柚其空:"zhù yòu qí kōng",杼柚空虚:"zhù yòu kōng xū",助天为虐:"zhù tiān wéi nüè",属垣有耳:"zhǔ yuán yǒu ěr",属毛离里:"zhǔ máo lí lǐ",属辞比事:"zhǔ cí bǐ shì",逐物不还:"zhú wù bù huán",铢量寸度:"zhū liáng cùn duó",铢两悉称:"zhū liǎng xī chèn",侏儒观戏:"zhū rú guān xì",朱轓皁盖:"zhū fān zào gài",昼度夜思:"zhòu duó yè sī",诪张为幻:"zhōu zhāng wéi huàn",重明继焰:"chóng míng jì yàn",众啄同音:"zhòng zhuó tóng yīn",众毛攒裘:"zhòng máo cuán qiú",众好众恶:"zhòng hào zhòng wù",擿埴索涂:"zhāi zhí suǒ tú",稚齿婑媠:"zhì chǐ wǒ tuó",至当不易:"zhì dàng bú yì",指皂为白:"zhǐ zào wéi bái",指雁为羹:"zhǐ yàn wéi gēng",指树为姓:"zhǐ shù wéi xìng",指山说磨:"zhǐ shān shuō mò",止戈为武:"zhǐ gē wéi wǔ",枝干相持:"zhī gàn xiāng chí",枝大于本:"zh dà yú běn",支吾其词:"zhī wú qí cí",正身率下:"zhèng shēn shuài xià",正冠李下:"zhèng guàn lǐ xià",整冠纳履:"zhěng guān nà lǚ",整躬率物:"zhěng gōng shuài wù",整顿干坤:"zhěng dùn gàn kūn",针头削铁:"zhēn tóu xuē tiě",贞松劲柏:"zhēn sōng jìng bǎi",赭衣塞路:"zhě yī sè lù",折箭为誓:"shé jiàn wéi shì",折而族之:"zhé ér zú zhī",昭德塞违:"zhāo dé sè wéi",章句小儒:"zhāng jù xiǎo rú",湛恩汪濊:"zhàn ēn wāng huì",占风望气:"zhān fēng wàng qì",斩将搴旗:"zhǎn jiàng qiān qí",曾母投杼:"zēng mǔ tóu zhù",曾参杀人:"zēng shēn shā rén",造谣中伤:"zào yáo zhòng shāng",早占勿药:"zǎo zhān wù yào",凿龟数策:"záo guī shǔ cè",攒三聚五:"cuán sān jù wǔ",攒眉蹙额:"cuán mei cù é",攒零合整:"cuán líng hé zhěng",攒锋聚镝:"cuán fēng jù dí",载笑载言:"zài xiào zài yán",载酒问字:"zài jiǔ wèn zì",殒身不恤:"yǔn shēn bú xù",云舒霞卷:"yún shū xiá juǎn",月中折桂:"yuè zhōng shé guì",月落参横:"yuè luò shēn héng",鬻驽窃价:"yù nú qiè jià",鬻鸡为凤:"yù jī wéi fèng",遇难成祥:"yù nàn chéng xiáng",郁郁累累:"yù yù lěi lěi",玉卮无当:"yù zhī wú dàng",语笑喧阗:"yǔ xiào xuān tián",与世沉浮:"yǔ shì chén fú",与时消息:"yǔ shí xiāo xi",逾墙钻隙:"yú qiáng zuān xì",渔夺侵牟:"yú duó qīn móu",杅穿皮蠹:"yú chuān pí dù",余勇可贾:"yú yǒng kě gǔ",予智予雄:"yú zhì yú xióng",予取予求:"yú qǔ yú qiú",于家为国:"yú jiā wéi guó",有借无还:"yǒu jiè wú huán",有加无已:"yǒu jiā wú yǐ",有国难投:"yǒu guó nán tóu",游必有方:"yóu bì yǒu fāng",油干灯尽:"yóu gàn dēng jìn",尤云殢雨:"yóu yún tì yǔ",庸中皦皦:"yōng zhōng jiǎo jiǎo",郢书燕说:"yǐng shū yān shuō",营蝇斐锦:"yíng yíng fēi jǐn",鹰心雁爪:"yīng xīn yàn zhǎo",莺吟燕儛:"yīng yín yàn wǔ",应天顺时:"yīng tiān shùn shí",印累绶若:"yìn léi shòu ruò",隐占身体:"yǐn zhàn shēn tǐ",饮犊上流:"yìn dú shàng liú",引绳切墨:"yǐn shéng qiē mò",龈齿弹舌:"yín chǐ dàn shé",因缘为市:"yīn yuán wéi shì",因树为屋:"yīn shù wéi wū",溢美溢恶:"yì měi yì wù",抑塞磊落:"yì sè lěi luò",倚闾望切:"yǐ lǘ wàng qiē",以意为之:"yǐ yì wéi zhī",以言为讳:"yǐ yán wéi huì",以疏间亲:"yǐ shū jiàn qīn",以水济水:"yǐ shuǐ jǐ shuǐ",以书为御:"yǐ shū wéi yù",以守为攻:"yǐ shǒu wéi gōng",以升量石:"yǐ shēng liáng dàn",以慎为键:"yǐ shèn wéi jiàn",以筌为鱼:"yǐ quán wéi yú",以利累形:"yǐ lì lěi xíng",以毁为罚:"yǐ huǐ wéi fá",以黑为白:"yǐ hēi wéi bái",以规为瑱:"yǐ guī wéi tiàn",以古为鉴:"yǐ gǔ wéi jiàn",以宫笑角:"yǐ gōng xiào jué",以法为教:"yǐ fǎ wéi jiào",以大恶细:"yǐ dà wù xì",遗世忘累:"yí shì wàng lěi",遗寝载怀:"yí qǐn zài huái",移的就箭:"yí dì jiù jiàn",依头缕当:"yī tóu lǚ dàng",衣租食税:"yì zū shí shuì",衣轻乘肥:"yì qīng chéng féi",衣裳之会:"yī shang zhī huì",衣单食薄:"yī dān shí bó",一还一报:"yì huán yí bào",叶公好龙:"yè gōng hào lóng",野调无腔:"yě diào wú qiāng",瑶池女使:"yáo chí nǚ shǐ",幺麽小丑:"yāo mó xiǎo chǒu",养精畜锐:"yǎng jīng xù ruì",卬首信眉:"áng shǒu shēn méi",洋洋纚纚:"yáng yáng sǎ sǎ",羊羔美酒:"yáng gāo měi jiǔ",扬风扢雅:"yáng fēng jié yǎ",燕昭市骏:"yān zhāo shì jùn",燕昭好马:"yān zhāo hǎo mǎ",燕石妄珍:"yān shí wàng zhēn",燕骏千金:"yān jùn qiān jīn",燕金募秀:"yān jīn mù xiù",燕驾越毂:"yān jià yuè gǔ",燕歌赵舞:"yān gē zhào wǔ",燕岱之石:"yān dài zhī shí",燕处危巢:"yàn chǔ wēi cháo",掞藻飞声:"shàn zǎo fēi shēng",偃革为轩:"yǎn gé wéi xuān",妍蚩好恶:"yán chī hǎo è",压良为贱:"yā liáng wéi jiàn",搀行夺市:"chān háng duó shì",泣数行下:"qì shù háng xià",当行出色:"dāng háng chū sè",秀出班行:"xiù chū bān háng",儿女成行:"ér nǚ chéng háng",大行大市:"dà háng dà shì",寻行数墨:"xún háng shǔ mò",埙篪相和:"xūn chí xiāng hè",血债累累:"xuè zhài lěi lěi",炫玉贾石:"xuàn yù gǔ shí",炫石为玉:"xuàn shí wéi yù",悬石程书:"xuán dàn chéng shū",悬狟素飡:"xuán huán sù cān",悬龟系鱼:"xuán guī xì yú",揎拳捋袖:"xuān quán luō xiù",轩鹤冠猴:"xuān hè guàn hóu",畜妻养子:"xù qī yǎng zǐ",羞人答答:"xiū rén dā dā",修鳞养爪:"xiū lín yǎng zhǎo",熊据虎跱:"xióng jù hǔ zhì",兄死弟及:"xiōng sǐ dì jí",腥闻在上:"xīng wén zài shàng",兴文匽武:"xīng wén yǎn wǔ",兴观群怨:"xìng guān qún yuàn",兴高彩烈:"xìng gāo cǎi liè",心手相应:"xīn shǒu xiāng yìng",心口相应:"xīn kǒu xiāng yīng",挟势弄权:"xié shì nòng quán",胁肩累足:"xié jiān lěi zú",校短量长:"jiào duǎn liáng cháng",小眼薄皮:"xiǎo yǎn bó pí",硝云弹雨:"xiāo yún dàn yǔ",鸮鸣鼠暴:"xiāo míng shǔ bào",削株掘根:"xuē zhū jué gēn",削铁无声:"xuē tiě wú shēng",削职为民:"xuē zhí wéi mín",削木为吏:"xuē mù wéi lì",想望风褱:"xiǎng wàng fēng huái",香培玉琢:"xiang pei yu zhuó",相鼠有皮:"xiàng shǔ yǒu pí",相时而动:"xiàng shí ér dòng",相切相磋:"xiāng qiē xiāng cuō",相女配夫:"xiàng nǚ pèi fū",相门有相:"xiàng mén yǒu xiàng",挦章撦句:"xián zhāng chě jù",先我着鞭:"xiān wǒ zhuó biān",习焉不察:"xí yān bù chá",歙漆阿胶:"shè qī ē jiāo",晰毛辨发:"xī máo biàn fà",悉索薄赋:"xī suǒ bó fù",雾鳞云爪:"wù lín yún zhǎo",物稀为贵:"wù xī wéi guì",碔砆混玉:"wǔ fū hùn yù",武断专横:"wǔ duàn zhuān héng",五石六鹢:"wǔ shí liù yì",五色相宣:"wǔ sè xiāng xuān",五侯七贵:"wǔ hóu qī guì",五侯蜡烛:"wǔ hòu là zhú",五羖大夫:"wǔ gǔ dà fū",吾自有处:"wú zì yǒu chǔ",无下箸处:"wú xià zhù chǔ",无伤无臭:"wú shāng wú xiù",无能为役:"wú néng wéi yì",无寇暴死:"wú kòu bào sǐ",无孔不钻:"wú kǒng bú zuàn",无间可乘:"wú jiān kě chéng",无间冬夏:"wú jiān dōng xià",无恶不为:"wú è bù wéi",无动为大:"wú dòng wéi dà",诬良为盗:"wū liáng wéi dào",握拳透爪:"wò quán tòu zhǎo",文武差事:"wén wǔ chāi shì",委委佗佗:"wēi wēi tuó tuó",惟日为岁:"wéi rì wéi suì",帷薄不修:"wéi bó bù xiū",为善最乐:"wéi shàn zuì lè",为山止篑:"wéi shān zhǐ kuì",为仁不富:"wéi rén bú fù",为裘为箕:"wéi qiú wéi jī",为民父母:"wéi mín fù mǔ",为虺弗摧:"wéi huǐ fú cuī",为好成歉:"wéi hǎo chéng qiàn",为鬼为蜮:"wéi guǐ wéi yù",望风响应:"wàng fēng xiǎng yīng",望尘僄声:"wàng chén piào shēng",往渚还汀:"wǎng zhǔ huán tīng",王贡弹冠:"wáng gòng dàn guàn",亡国大夫:"wáng guó dà fū",万贯家私:"wàn guàn jiā sī",晚食当肉:"wǎn shí dàng ròu",晚节不保:"wǎn jié bù bǎo",玩岁愒时:"wán suì kài shí",蛙蟆胜负:"wā má shèng fù",吞言咽理:"tūn yán yàn lǐ",颓垣断堑:"tuí yuán duàn qiàn",推干就湿:"tuī gàn jiù shī",剸繁决剧:"tuán fán jué jù",团头聚面:"tuán tóu jù miàn",兔丝燕麦:"tù sī yàn mài",兔头麞脑:"tù tóu zhāng nǎo",兔葵燕麦:"tù kuí yàn mài",吐哺握发:"tǔ bǔ wò fà",投传而去:"tóu zhuàn ér qù",头没杯案:"tóu mò bēi àn",头昏脑闷:"tóu hūn nǎo mèn",头会箕敛:"tóu kuài jī liǎn",头出头没:"tóu chū tóu mò",痛自创艾:"tòng zì chuāng yì",同恶相助:"tóng wù xiāng zhù",同恶相恤:"tóng wù xiāng xù",痌瘝在抱:"tōng guān zài bào",通文调武:"tōng wén diào wǔ",停留长智:"tíng liú zhǎng zhì",铁树开华:"tiě shù kāi huā",条贯部分:"tiáo guàn bù fēn",挑牙料唇:"tiǎo yá liào chún",挑么挑六:"tiāo yāo tiāo liù",挑唇料嘴:"tiǎo chún liào zuǐ",恬不为意:"tián bù wéi yì",恬不为怪:"tián bù wéi guài",天下为笼:"tiān xià wéi lóng",天台路迷:"tiān tái lù mí",天年不遂:"tiān nián bú suì",探囊胠箧:"tàn náng qū qiè",谭言微中:"tán yán wēi zhòng",谈言微中:"tán yán wēi zhòng",狧穅及米:"shì kāng jí mǐ",随物应机:"suí wù yīng jī",搜岩采干:"sōu yán cǎi gàn",宋斤鲁削:"sòng jīn lǔ xuē",松筠之节:"sōng yún zhī jié",四亭八当:"sì tíng bā dàng",四马攒蹄:"sì mǎ cuán tí",四不拗六:"sì bú niù liù",思所逐之:"sī suǒ zhú zhī",丝恩发怨:"sī ēn fà yuàn",硕望宿德:"shuò wàng xiǔ dé",铄古切今:"shuò gǔ qiē jīn",顺风而呼:"shùn fēng ér hū",顺风吹火:"shùn fēng chuī huǒ",水中著盐:"shuǐ zhōng zhuó yán",双柑斗酒:"shuāng gān dǒu jiǔ",数米而炊:"shǔ mǐ ér chuī",数米量柴:"shǔ mǐ liáng chái",数理逻辑:"shù lǐ luó ji",数黑论黄:"shǔ hēi lùn huáng",数白论黄:"shǔ bái lùn huáng",束缊还妇:"shù yūn huán fù",束蒲为脯:"shù pú wéi pú",束椽为柱:"shù chuán wéi zhù",书缺有间:"shū quē yǒu jiàn",手足重茧:"shǒu zú chóng jiǎn",手足异处:"shǒu zú yì chǔ",手脚干净:"shǒu jiǎo gàn jìng",手不应心:"shǒu bù yīng xīn",螫手解腕:"shì shǒu jiě wàn",释知遗形:"shì zhī yí xíng",适时应务:"shì shí yīng wù",适情率意:"shì qíng shuài yì",适当其冲:"shì dāng qí chōng",视为知己:"shì wéi zhī jǐ",使羊将狼:"shǐ yáng jiàng láng",食为民天:"shí wéi mín tiān",拾掇无遗:"shí duō wú yí",实与有力:"shí yù yǒu lì",石英玻璃:"shí yīng bō li",石室金匮:"shí shì jīn guì",什袭珍藏:"shí xí zhēn cáng",什伍东西:"shí wǔ dōng xī",什围伍攻:"shí wéi wǔ gōng",十魔九难:"shí mó jiǔ nàn",诗书发冢:"shī shū fà zhǒng",虱处裈中:"shī chǔ kūn zhōng",师直为壮:"shī zhí wéi zhuàng",尸居龙见:"shī jū lóng xiàn",圣经贤传:"shèng jīng xián zhuàn",圣君贤相:"shèng jūn xián xiàng",生拖死拽:"shēng tuō sǐ zhuài",审己度人:"shěn jǐ duó rén",神武挂冠:"shén wǔ guà guàn",神龙失埶:"shén lóng shī shì",深文曲折:"shēn wén qǔ shé",深厉浅揭:"shēn lì qiǎn qì",深谷为陵:"shēn gǔ wéi líng",深恶痛疾:"shēn wù tòng jí",深仇宿怨:"shēn chóu xiǔ yuàn",舍己为公:"shě jǐ wèi gōng",舍短取长:"shě duǎn qǔ cháng",舍策追羊:"shě cè zhuī yáng",蛇蝎为心:"shé xiē wéi xīn",少成若性:"shào chéng ruò xìng",上当学乖:"shàng dàng xué guāi",赏不当功:"shǎng bù dāng gōng",善自为谋:"shàn zì wéi móu",善为说辞:"shàn wéi shuō cí",善善恶恶:"shàn shàn wù è",善财难舍:"shàn cái nán shě",苫眼铺眉:"shān yǎn pū méi",讪牙闲嗑:"shàn yá xián kē",山阴乘兴:"shān yīn chéng xīng",山殽野湋:"shān yáo yě wéi",山溜穿石:"shān liù chuān shí",山节藻棁:"shān jié zǎo zhuō",杀鸡为黍:"shā jī wéi shǔ",色厉胆薄:"sè lì dǎn bó",桑荫未移:"sāng yīn wèi yí",桑荫不徙:"sāng yīn bù xǐ",桑土绸缪:"sāng tǔ chóu miù",桑户棬枢:"sāng hù juàn shū",三战三北:"sān zhàn sān běi",三瓦两舍:"sān wǎ liǎng shě",三人为众:"sān rén wèi zhòng",三差两错:"sān chā liǎng cuò",塞井焚舍:"sāi jǐng fén shě",洒心更始:"sǎ xīn gèng shǐ",洒扫应对:"sǎ sǎo yìng duì",软红香土:"ruǎn hóng xiāng tǔ",入吾彀中:"rù wú gòu zhōng",入铁主簿:"rù tiě zhǔ bù",入理切情:"rù lǐ qiē qíng",汝成人耶:"rǔ chéng rén yé",如水投石:"rú shuǐ tóu shí",如切如磋:"rú qiē rú cuō",如登春台:"rú dēng chūn tái",肉薄骨并:"ròu bó gǔ bìng",柔情绰态:"róu qíng chuò tài",戎马劻勷:"róng mǎ kuāng ráng",日中为市:"rì zhōng wéi shì",日月参辰:"rì yuè shēn chén",日省月修:"rì xǐng yuè xiū",日削月割:"rì xuē yuè gē",日省月试:"rì xǐng yuè shì",任达不拘:"rèn dá bù jū",人言藉藉:"rén yán jí jí",人模狗样:"rén mú gǒu yàng",人莫予毒:"rén mò yú dú",热熬翻饼:"rè áo fān bǐng",圈牢养物:"juàn láo yǎng wù",取予有节:"qǔ yǔ yǒu jié",诎要桡腘:"qū yāo ráo guó",穷形尽相:"qióng xíng jìn xiàng",情凄意切:"qíng qī yì qiè",情见势屈:"qíng xiàn shì qū",情见乎辞:"qíng xiàn hū cí",清都绛阙:"qīng dōu jiàng què",倾肠倒肚:"qīng cháng dào dǔ",青紫被体:"qīng zǐ pī tǐ",青林黑塞:"qīng lín hēi sài",螓首蛾眉:"qín shǒu é méi",琴瑟之好:"qín sè zhī hào",且住为佳:"qiě zhù wéi jiā",切树倒根:"qiē shù dǎo gēn",切理餍心:"qiē lǐ yàn xīn",切近的当:"qiē jìn de dāng",翘足引领:"qiáo zú yǐn lǐng",巧发奇中:"qiǎo fā qí zhòng",强嘴拗舌:"jiàng zuǐ niù shé",强直自遂:"qiáng zhí zì suí",强死强活:"qiǎng sǐ qiǎng huó",强食自爱:"qiǎng shí zì ài",强食靡角:"qiǎng shí mí jiǎo",强弓劲弩:"qiáng gōng jìng nǔ",强聒不舍:"qiǎng guō bù shě",强凫变鹤:"qiáng fú biàn hè",强而后可:"qiǎng ér hòu kě",强得易贫:"qiǎng dé yì pín",遣兴陶情:"qiǎn xìng táo qíng",牵羊担酒:"qiān yáng dān jiǔ",千了百当:"qiān liǎo bǎi dàng",泣下如雨:"qì xià rú yǔ",起偃为竖:"qǐ yǎn wéi shù",岂弟君子:"kǎi tì jūn zǐ",綦溪利跂:"qí xī lì qí",棋输先著:"qí shū xiān zhuó",齐王舍牛:"qí wáng shě niú",欺天诳地:"qī tiān kuáng dì",普天率土:"pǔ tiān shuài tǔ",铺胸纳地:"pū xiōng nà dì",铺锦列绣:"pū jǐn liè xiù",破家为国:"pò jiā wèi guó",破觚为圜:"pò gū wéi yuán",萍飘蓬转:"píng piāo péng zhuàn",帡天极地:"píng tiān jí dì",屏声息气:"bǐng shēng xī qì",凭几据杖:"píng jī jù zhàng",贫嘴薄舌:"pín zuǐ bó shé",片语只辞:"piàn yǔ zhī cí",披发文身:"pī fà wén shēn",烹龙炮凤:"pēng lóng páo fèng",炰鳖脍鲤:"fǒu biē kuài lǐ",庞眉皓发:"páng méi hào fà",攀花折柳:"pān huā zhé liǔ",攀蟾折桂:"pān chán shé guì",女大难留:"nǚ dà nán liú",弄玉吹箫:"nòng yù chuī xiāo",弄管调弦:"nòng guǎn tiáo xián",弄粉调朱:"nòng fěn diào zhū",浓抹淡妆:"nóng mò dàn zhuāng",捻土为香:"niǎn tǔ wéi xiāng",年谊世好:"nián yì shì hǎo",年华垂暮:"nián huá chuí mù",儗不于伦:"nǐ bù yú lún",泥而不滓:"ní ér bù zǐ",能者为师:"néng zhě wéi shī",能不称官:"néng bú chèn guān",挠直为曲:"náo zhí wéi qū",难进易退:"nán jìn yì tuì",难得糊涂:"nán dé hú tú",南蛮鴂舌:"nán mán jué shé",南贩北贾:"nán fàn běi gǔ",牧猪奴戏:"mù zhū nú xì",目眢心忳:"mù yuān xīn tún",目挑心招:"mù tiǎo xīn zhāo",目量意营:"mù liàng yì yíng",木头木脑:"mù tóu mù nǎo",木干鸟栖:"mù gàn niǎo qī",侔色揣称:"móu sè chuǎi chèn",莫予毒也:"mò yú dú yě",抹粉施脂:"mò fěn shī zhī",磨砻镌切:"mó lóng juān qiē",磨棱刓角:"mó léng wán jiǎo",摸门不着:"mō mén bù zháo",摸不着边:"mō bù zhuó biān",命中注定:"mìng zhōng zhù dìng",鸣鹤之应:"míng hè zhī yìng",明效大验:"míng xiào dà yàn",名我固当:"míng wǒ gù dāng",邈处欿视:"miǎo chǔ kǎn shì",黾穴鸲巢:"měng xué qú cháo",绵里薄材:"mián lǐ bó cái",靡有孑遗:"mǐ yǒu jié yí",靡衣偷食:"mǐ yī tōu shí",迷恋骸骨:"mí liàn hái gǔ",扪参历井:"mén shēn lì jǐng",门单户薄:"mén dān hù bó",昧旦晨兴:"mèi dàn chén xīng",冒名接脚:"mào míng jiē jiǎo",毛遂堕井:"máo suí duò jǐng",毛发倒竖:"máo fā dǎo shù",卖文为生:"mài wén wéi shēng",卖李钻核:"mài lǐ zuān hé",买椟还珠:"mǎi dú huán zhū",埋三怨四:"mán sān yuàn sì",马入华山:"mǎ rù huá shān",落魄江湖:"luò pò jiāng hú",落落难合:"luò luò nán hé",落草为寇:"luò cǎo wéi kòu",罗织构陷:"luó zhī gòu xiàn",鸾凤和鸣:"luán fèng hè míng",率由旧章:"shuài yóu jiù zhāng",率土同庆:"shuài tǔ tóng qìng",率兽食人:"shuài shòu shí rén",率土归心:"shuài tǔ guī xīn",率马以骥:"shuài mǎ yǐ jì",率尔成章:"shuài ěr chéng zhāng",鲁斤燕削:"lǔ jīn yàn xuē",漏尽更阑:"lòu jìn gēng lán",笼鸟槛猿:"lóng niǎo jiàn yuán",笼鸟池鱼:"lóng niǎo chí yú",龙游曲沼:"lóng yóu qū zhǎo",龙血玄黄:"lóng xuè xuán huáng",龙雕凤咀:"lóng diāo fèng jǔ",六尺之讬:"liù chǐ zhī tuō",令原之戚:"líng yuán zhī qī",令人捧腹:"lìng rén pěng fù",陵劲淬砺:"líng jìng cuì lì",临敌易将:"lín dí yì jiàng",裂裳衣疮:"liè shang yī chuāng",裂冠毁冕:"liè guàn huǐ miǎn",了无惧色:"liǎo wú jù sè",了身达命:"liǎo shēn dá mìng",了然无闻:"liǎo rán wú wén",了不可见:"liǎo bù kě jiàn",了不长进:"liǎo bù zhǎng jìn",燎发摧枯:"liǎo fà cuī kū",审时度势:"shěn shí duó shì",量小力微:"liàng xiǎo lì wēi",相时度力:"xiāng shí duó lì",量枘制凿:"liàng ruì zhì záo",量如江海:"liàng rú jiāng hǎi",量金买赋:"liàng jīn mǎi fù",量己审分:"liàng jǐ shěn fēn",敛骨吹魂:"liǎn gǔ chuī hún",詈夷为跖:"lì yí wéi zhí",利令志惛:"lì lìng zhì hūn",李广不侯:"lǐ guǎng bú hòu",礼为情貌:"lǐ wéi qíng mào",礼让为国:"lǐ ràng wéi guó",犁生骍角:"lí shēng xīng jiǎo",离本徼末:"lí běn jiǎo mò",楞眉横眼:"léng méi hèng yǎn",擂天倒地:"léi tiān dǎo dì",累足成步:"lěi zú chéng bù",累瓦结绳:"lěi wǎ jié shéng",累土至山:"lěi tǔ zhì shān",累土聚沙:"lěi tǔ jù shā",累卵之危:"lěi luǎn zhī wēi",累累如珠:"lěi lěi rú zhū",累块积苏:"lěi kuài jī sū",乐山乐水:"lè shān lè shuǐ",潦原浸天:"lǎo yuán jìn tiān",老师宿儒:"lǎo shī xiǔ rú",牢什古子:"láo shí gǔ zi",琅嬛福地:"láng huán fú dì",揆情度理:"kuí qíng duó lǐ",旷日累时:"kuàng rì lěi shí",匡救弥缝:"kuāng jiù mí fèng",枯树生华:"kū shù shēng huā",口轻舌薄:"kǒu qīng shé bó",口角生风:"kǒu jiǎo shēng fēng",口角春风:"kǒu jiǎo chūn fēng",口角风情:"kǒu jiǎo fēng qíng",口干舌焦:"kǒu gān shé jiāo",口腹之累:"kǒu fù zhī lěi",空腹便便:"kōng fù pián pián",嗑牙料嘴:"kē yá liào zuǐ",刻木为鹄:"kè mù wéi hú",咳珠唾玉:"ké zhū tuò yù",咳唾成珠:"ké tuò chéng zhū",抗颜为师:"kàng yán wéi shī",开华结果:"kāi huā jié guǒ",峻阪盐车:"jùn bǎn yán chē",嚼铁咀金:"jiáo tiě jǔ jīn",嚼墨喷纸:"jué mò pēn zhǐ",倔头强脑:"juè tóu jiàng nǎo",倔头倔脑:"juè tóu juè nǎo",倦鸟知还:"juàn niǎo zhī huán",卷席而葬:"juǎn xí ér zàng",卷甲倍道:"juǎn jiǎ bèi dào",聚米为山:"jù mǐ wéi shān",举手相庆:"jǔ shǒu xiāng qìng",举世混浊:"jǔ shì hún zhuó",鞠为茂草:"jū wéi mào cǎo",拘神遣将:"jū shén qiǎn jiàng",居下讪上:"jū xià shàn shàng",久要不忘:"jiǔ yāo bú wàng",九转功成:"jiǔ zhuǎn gōng chéng",九蒸三熯:"jiǔ zhēng sān hàn",敬业乐群:"jìng yè lè qún",井底虾蟆:"jǐng dǐ xiā má",旌旗卷舒:"jīng qí juǎn shū",荆棘载途:"jīng jí zài tú",禁舍开塞:"jìn shě kāi sāi",祲威盛容:"jìn wēi shèng róng",进退消长:"jìn tuì xiāo cháng",进退应矩:"jìn tuì yīng jǔ",进退触籓:"jìn tuì chù fān",进退跋疐:"jìn tuì bá zhì",尽多尽少:"jǐn duō jǐn shǎo",锦囊还矢:"jǐn náng huán shǐ",矜己自饰:"jīn jǐ zì shì",矜功负气:"jīn gōng fù qì",津关险塞:"jīn guān xiǎn sài",金吾不禁:"jīn wú bú jìn",金翅擘海:"jīn chì bāi hǎi",解衣衣人:"jiě yī yī rén",解人难得:"jiě rén nán dé",解铃系铃:"jiě líng xì líng",解发佯狂:"jiě fà yáng kuáng",诘屈磝碻:"jié qū áo qiāo",教猱升木:"jiāo náo shēng mù",较瘦量肥:"jiào shòu liàng féi",角立杰出:"jiǎo lì jié chū",焦沙烂石:"jiāo shā làn shí",骄儿騃女:"jiāo ér sì nǚ",浇风薄俗:"jiāo fēng bó sú",降妖捉怪:"xiáng yāo zhuō guài",将取固予:"jiāng qǔ gù yǔ",将门有将:"jiàng mén yǒu jiàng",将夺固与:"jiāng duó gù yǔ",槛花笼鹤:"jiàn huā lóng hè",鉴影度形:"jiàn yǐng duó xíng",渐不可长:"jiàn bù kě zhǎng",见素抱朴:"xiàn sù bào pǔ",见弃于人:"jiàn qì yú rén",简丝数米:"jiǎn sī shǔ mǐ",俭不中礼:"jiǎn bú zhòng lǐ",间见层出:"jiàn xiàn céng chū",尖嘴薄舌:"jiān zuǐ bó shé",甲冠天下:"jiǎ guàn tiān xià",葭莩之亲:"jiā fú zhī qīn",家累千金:"jiā lèi qiān jīn",家给人足:"jiā jǐ rén zú",家道从容:"jiā dào cóng róng",夹袋人物:"jiā dài rén wù",霁风朗月:"jì fēng lǎng yuè",寄兴寓情:"jì xìng yù qíng",计深虑远:"jì shēn lǜ yuǎn",计功量罪:"jì gōng liàng zuì",掎裳连襼:"jǐ shang lián yì",虮虱相吊:"jǐ shī xiāng diào",疾不可为:"jí bù kě wéi",极深研几:"jí shēn yán jī",及宾有鱼:"jí bīn yǒu yú",激薄停浇:"jī bó tíng jiāo",积素累旧:"jī sù lěi jiù",积时累日:"jī shí lěi rì",积露为波:"jī lù wéi bō",积德累功:"jī dé lěi gōng",积谗糜骨:"jī chán méi gǔ",击排冒没:"jī pái mào mò",祸为福先:"huò wéi fú xiān",祸福相依:"huò fú xiāng yī",获隽公车:"huò jùn gōng chē",混应滥应:"hùn yīng làn yīng",毁舟为杕:"huǐ zhōu wéi duò",毁钟为铎:"huǐ zhōng wéi duó",毁冠裂裳:"huǐ guān liè cháng",晦盲否塞:"huì máng pǐ sè",回船转舵:"huí chuán zhuàn duò",潢池盗弄:"huáng chí dào nòng",黄冠草履:"huáng guàn cǎo lǚ",黄发儿齿:"huáng fà ér chǐ",黄发垂髫:"huáng fà chuí tiáo",还珠返璧:"huán zhū fǎn bì",还年驻色:"huán nián zhù sè",还年却老:"huán nián què lǎo",坏裳为裤:"huài shang wéi kù",画荻和丸:"huà dí huò wán",化枭为鸠:"huà xiāo wéi jiū",化腐为奇:"huà fǔ wéi qí",化鸱为凤:"huà chī wéi fèng",花不棱登:"huā bu lēng dēng",户限为穿:"hù xiàn wéi chuān",呼卢喝雉:"hū lú hè zhì",呼来喝去:"hū lái hè qù",呼不给吸:"hū bù jǐ xī",厚味腊毒:"hòu wèi xī dú",厚德载物:"hòu dé zài wù",鸿渐于干:"hóng jiàn yú gàn",洪炉燎发:"hóng lú liáo fà",红绳系足:"hóng shéng jì zú",红不棱登:"hóng bu lēng dēng",横抢硬夺:"hèng qiǎng yìng duó",横恩滥赏:"hèng ēn làn shǎng",恨海难填:"hèn hǎi nán tián",鹤发鸡皮:"hè fà jī pí",涸思干虑:"hé sī gān lǜ",河涸海干:"hé hé hǎi gān",和颜说色:"hé yán yuè sè",合从连衡:"hé zòng lián héng",浩浩汤汤:"hào hào shāng shāng",好勇斗狠:"hào yǒng dòu hěn",好问则裕:"hào wèn zé yù",好为事端:"hào wéi shì duān",好问决疑:"hào wèn jué yí",好生之德:"hào shēng zhī dé",好奇尚异:"hǎo qí shàng yì",好恶不同:"hǎo è bù tóng",好丹非素:"hào dān fēi sù",豪干暴取:"háo gàn bào qǔ",毫发不爽:"háo fà bù shuǎng",寒酸落魄:"hán suān luò pò",含英咀华:"hán yīng jǔ huá",含糊不明:"hán hú bù míng",过为已甚:"guò wéi yǐ shèn",桂折兰摧:"guì shé lán cuī",规旋矩折:"guī xuán jǔ shé",广文先生:"guǎng wén xiān sheng",广陵散绝:"guǎng líng sǎn jué",冠山戴粒:"guàn shān dài lì",冠屦倒施:"guàn jù dǎo shī",挂席为门:"guà xí wéi mén",寡见鲜闻:"guǎ jiàn xiǎn wén",瓜葛相连:"guā gé xiāng lián",鼓吻奋爪:"gǔ wěn fèn zhǎo",古调单弹:"gǔ diào dān tán",古调不弹:"gǔ diào bù tán",姑射神人:"gū yè shén rén",苟合取容:"gǒu hé qǔ róng",狗续侯冠:"gǒu xù hòu guàn",钩爪锯牙:"gōu zhǎo jù yá",共枝别干:"gòng zhī bié gàn",共为唇齿:"gòng wéi chún chǐ",拱手而降:"gǒng shǒu ér xiáng",拱肩缩背:"gǒng jiān suō bèi",功薄蝉翼:"gōng bó chán yì",弓调马服:"gōng diào mǎ fú",更姓改物:"gēng xìng gǎi wù",更仆难数:"gēng pú nán shǔ",更令明号:"gēng lìng míng hào",更待干罢:"gèng dài gàn bà",更唱迭和:"gēng chàng dié hé",更长梦短:"gēng cháng mèng duǎn",各色名样:"gè sè míng yàng",格格不纳:"gé gé bú nà",格格不吐:"gé gé bù tǔ",告朔饩羊:"gù shuò xì yáng",膏车秣马:"gào chē mò mǎ",高义薄云:"gāo yì bó yún",岗头泽底:"gāng tóu zé dǐ",敢为敢做:"gǎn wéi gǎn zuò",甘分随时:"gān fèn suí shí",甘处下流:"gān chǔ xià liú",干啼湿哭:"gàn tí shī kū",干名犯义:"gàn míng fàn yì",干将莫邪:"gān jiāng mò yé",干城之将:"gān chéng zhī jiàng",腹载五车:"fù zài wǔ chē",父债子还:"fù zhài zǐ huán",父为子隐:"fù wéi zǐ yǐn",辅世长民:"fǔ shì zhǎng mín",福为祸始:"fú wéi huò shǐ",符号逻辑:"fú hào luó jí",浮收勒折:"fú shōu lè shé",肤受之愬:"fū shòu zhī sù",否终则泰:"pǐ zhōng zé tài",佛头著粪:"fó tóu zhuó fèn",奉为楷模:"fèng wéi kǎi mó",凤靡鸾吪:"fèng mǐ luán é",封豨修蛇:"fēng xī xiū shé",风影敷衍:"fēng yǐng fū yǎn",丰屋蔀家:"fēng wū bù jiā",粪土不如:"fèn tǔ bù rú",分风劈流:"fēn fēng pǐ liú",沸沸汤汤:"fèi fèi shāng shāng",菲食薄衣:"fěi shí bó yī",飞将数奇:"fēi jiàng shù qí",放辟邪侈:"fàng pì xié chǐ",方领圆冠:"fāng lǐng yuán guàn",犯而不校:"fàn ér bú jiào",返本还源:"fǎn běn huán yuán",反劳为逸:"fǎn láo wéi yì",法轮常转:"fǎ lún cháng zhuàn",罚不当罪:"fá bù dāng zuì",发引千钧:"fà yǐn qiān jūn",发奸擿伏:"fā jiān tī fú",发短心长:"fà duǎn xīn cháng",二竖为虐:"èr shù wéi nüè",儿女心肠:"ér nǚ xīn cháng",儿女亲家:"ér nǚ qìng jiā",遏恶扬善:"è wù yáng shàn",饿殍枕藉:"è piǎo zhěn jí",饿殍载道:"è piǎo zài dào",恶醉强酒:"wù zuì qiǎng jiǔ",恶意中伤:"è yì zhòng shāng",恶湿居下:"wù shī jū xià",恶居下流:"wù jū xià liú",恶不去善:"wù bú qù shàn",扼吭夺食:"è háng duó shí",扼襟控咽:"è jīn kòng yān",峨峨汤汤:"é é shāng shāng",屙金溺银:"ē jīn niào yín",朵颐大嚼:"duǒ yí dà jiáo",夺人所好:"duó rén suǒ hào",多言数穷:"duō yán shuò qióng",多文为富:"duō wén wéi fù",多端寡要:"duō duān guǎ yào",多财善贾:"duō cái shàn gǔ",遁世无闷:"dùn shì wú mèn",遁迹黄冠:"dùn jì huáng guàn",堆案盈几:"duī àn yíng jī",断还归宗:"duàn huán guī zōng",短见薄识:"duǎn jiàn bó shí",蠹居棊处:"dù jū qí chǔ",度己以绳:"duó jǐ yǐ shéng",杜默为诗:"dù mò wéi shī",杜鹃啼血:"dù juān tí xuè",笃近举远:"dǔ jìn jǔ yuǎn",独有千秋:"dú yǒu qiān qiū",读书得间:"dú shū dé jiàn",斗转参横:"dǒu zhuǎn shēn héng",兜肚连肠:"dōu dǔ lián cháng",洞见症结:"dòng jiàn zhèng jié",恫疑虚喝:"dòng yí xū hè",动中窾要:"dòng zhōng kuǎn yào",东鸣西应:"dōng míng xī yīng",东鳞西爪:"dōng lín xī zhǎo",东量西折:"dōng liàng xī shé",东家西舍:"dōng jiā xī shè",东扯西拽:"dōng chě xī zhuāi",鼎铛有耳:"dǐng chēng yǒu ěr",鼎铛玉石:"dǐng chēng yù shí",钉头磷磷:"dīng tóu lín lín",跌宕不羁:"diē dàng bù jī",跌弹斑鸠:"diē dàn bān jiū",雕心雁爪:"diāo xīn yàn zhǎo",颠倒衣裳:"diān dǎo yī cháng",德薄能鲜:"dé bó néng xiǎn",得马折足:"dé mǎ shé zú",蹈其覆辙:"dǎo qí fù zhé",捣虚撇抗:"dǎo xū piē kàng",倒载干戈:"dào zài gān gē",倒裳索领:"dào cháng suǒ lǐng",倒果为因:"dào guǒ wéi yīn",叨在知己:"tāo zài zhī jǐ",叨陪末座:"tāo péi mò zuò",党豺为虐:"dǎng chái wéi nüè",当轴处中:"dāng zhóu chǔ zhōng",当着不着:"dāng zhuó bù zhuó",当务始终:"dāng wù shǐ zhōng",淡汝浓抹:"dàn rǔ nóng mǒ",弹丸脱手:"tán wán tuō shǒu",弹铗无鱼:"dàn jiá wú yú",箪食瓢饮:"dān sì piáo yǐn",大璞不完:"dà pú bù wán",大明法度:"dà míng fǎ dù",大车以载:"dà chē yǐ zài",打闷葫芦:"dǎ mèn hú lu",沓来踵至:"tà lái zhǒng zhì",厝火燎原:"cuò huǒ liǎo yuán",撮科打哄:"cuō kē dǎ hòng",寸积铢累:"cùn jī zhū lěi",啛啛喳喳:"cuì cuì chā chā",摧折豪强:"cuī zhé háo qiáng",摧刚为柔:"cuī gāng wéi róu",从俗就简:"cóng sú jiù jiǎn",此发彼应:"cǐ fā bǐ yīng",此唱彼和:"cǐ chàng bǐ hè",慈悲为本:"cí bēi wéi běn",纯属骗局:"chún shǔ piàn jú",春笋怒发:"chūn sǔn nù fā",垂头搨翼:"chuí tóu tà yì",传为笑谈:"chuán wéi xiào tán",传风扇火:"chuán fēng shān huǒ",穿红着绿:"chuān hóng zhuó lǜ",触处机来:"chù chǔ jī lái",处尊居显:"chǔ zūn jū xiǎn",处堂燕雀:"chǔ táng yàn què",处实效功:"chǔ shí xiào gōng",处高临深:"chǔ gāo lín shēn",出入无间:"chū rù wú jiān",出门应辙:"chū mén yīng zhé",出处语默:"chū chǔ yǔ mò",出处殊途:"chū chǔ shū tú",出处进退:"chū chǔ jìn tuì",愁山闷海:"chóu shān mèn hǎi",冲冠眦裂:"chōng guàn zì liè",齿牙为祸:"chǐ yá wéi huò",尺二冤家:"chǐ èr yuān jia",尺短寸长:"chǐ duǎn cùn cháng",尺寸之功:"chǐ cùn zhī gōng",城北徐公:"chéng běi xú gōng",成败兴废:"chéng bài xīng fèi",趁水和泥:"chèn shuǐ huò ní",称雨道晴:"chēng yǔ dào qíng",称体载衣:"chēng tǐ zài yī",称体裁衣:"chèn tǐ cái yī",称家有无:"chèn jiā yǒu wú",称德度功:"chēng dé duó gōng",沉吟章句:"chén yín zhāng jù",沉吟不决:"chén yín bù jué",沉疴宿疾:"chén kē sù jí",扯纤拉烟:"chě qiàn lā yān",扯顺风旗:"chě shùn fēng qí",车载船装:"chē zǎi chuán zhuāng",朝升暮合:"zhāo shēng mù gě",朝攀暮折:"zhāo pān mù shé",超今冠古:"chāo jīn guàn gǔ",倡而不和:"chàng ér bú hè",畅所欲为:"chàng suǒ yù wéi",苌弘碧血:"cháng hóng bì xiě",长幼尊卑:"zhǎng yòu zūn bēi",长绳系日:"cháng shéng jì rì",长年三老:"zhǎng nián sān lǎo",长春不老:"cháng chūn bù lǎo",长傲饰非:"zhǎng ào shì fēi",昌亭旅食:"chāng tíng lǚ shí",禅絮沾泥:"chán xù zhān ní",差三错四:"chā sān cuò sì",层台累榭:"céng tái lěi xiè",层见迭出:"céng xiàn dié chū",藏踪蹑迹:"cáng zōng niè jì",苍蝇见血:"cāng yíng jiàn xiě",餐松啖柏:"cān sōng dàn bó",骖风驷霞:"cān fēng sì xiá",参伍错综:"cēn wǔ cuò zōng",参辰卯酉:"shēn chén mǎo yǒu",材优干济:"cái yōu gān jǐ",材薄质衰:"cái bó zhì shuāi",才大难用:"cái dà nán yòng",才薄智浅:"cái bó zhì qiǎn",不足为意:"bù zú wéi yì",不足为据:"bù zú wéi jù",不足为法:"bù zú wéi fǎ",不足齿数:"bù zú chǐ shǔ",不着疼热:"bù zhuó téng rè",不知薡蕫:"bù zhī dǐng dǒng",不越雷池:"bú yuè léi chí",不相为谋:"bù xiāng wéi móu",不贪为宝:"bù tān wéi bǎo",不了而了:"bù liǎo ér liǎo",不可揆度:"bù kě kuí duó",不遑启处:"bù huáng qǐ chǔ",不当不正:"bù dāng bú zhèng",不差什么:"bú chà shén me",不差累黍:"bù chā lěi shǔ",擘两分星:"bò liǎng fēn xīng",簸土扬沙:"bǒ tǔ yáng shā",薄物细故:"bó wù xì gù",薄寒中人:"bó hán zhòng rén",博文约礼:"bó wén yuē lǐ",播糠眯目:"bō kāng mí mù",剥皮抽筋:"bō pí chōu jīn",剥肤椎髓:"bō fū chuí suǐ",波属云委:"bō zhǔ yún wěi",波骇云属:"bō hài yún zhǔ",兵微将寡:"bīng wēi jiàng guǎ",兵强将勇:"bīng qiáng jiàng yǒng",兵多将广:"bīng duō jiàng guǎng",兵不由将:"bīng bù yóu jiàng",冰解的破:"bīng jiě dì pò",彬彬济济:"bīn bīn jǐ jǐ",摽梅之年:"biào méi zhī nián",表里为奸:"biǎo lǐ wéi jiān",飙发电举:"biāo fā diàn jǔ",变贪厉薄:"biàn tān lì bó",敝盖不弃:"bì gài bú qì",秕言谬说:"bǐ yán miù shuō",比物属事:"bǐ wù zhǔ shì",被山带河:"pī shān dài hé",被甲枕戈:"pī jiǎ zhěn gē",被甲据鞍:"pī jiǎ jù ān",被褐怀玉:"pī hè huái yù",被发缨冠:"pī fà yīng guàn",背曲腰躬:"bèi qǔ yāo gōng",北窗高卧:"běi chuāng gāo wò",北辰星拱:"běi chén xīng gǒng",北鄙之音:"běi bǐ zhī yīn",卑宫菲食:"bēi gōng fěi shí",暴衣露冠:"pù yī lù guàn",暴腮龙门:"pù sāi lóng mén",暴露文学:"bào lù wén xué",暴虎冯河:"bào hǔ píng hé",抱蔓摘瓜:"bào wàn zhāi guā",抱法处势:"bào fǎ chǔ shì",褒贬与夺:"bāo biǎn yǔ duó",帮闲钻懒:"bāng xián zuān lǎn",拜将封侯:"bài jiàng fēng hóu",百兽率舞:"bǎi shòu shuài wǔ",百孔千创:"bǎi kǒng qiān chuāng",白衣卿相:"bái yī qīng xiàng",白首为郎:"bái shǒu wéi láng",白首相知:"bái shǒu xiāng zhī",把玩无厌:"bǎ wán wú yàn",拔锅卷席:"bá guō juǎn xí",拔本塞源:"bá běn sè yuán",傲不可长:"ào bù kě zhǎng",熬更守夜:"áo gēng shǒu yè",安时处顺:"ān shí chǔ shùn",安身为乐:"ān shēn wéi lè",安老怀少:"ān lǎo huái shào",安步当车:"ān bù dàng chē",爱人好士:"ài rén hào shì",矮人观场:"ǎi rén guān chǎng",捱风缉缝:"ái fēng jī fèng",挨山塞海:"āi shān sè hǎi",阿家阿翁:"ā jiā ā wēng",阿党相为:"ē dǎng xiāng wéi",追亡逐北:"zhuī wáng zhú běi",竹篮打水:"zhú lán dá shuǐ",知疼着热:"zhī téng zháo rè",语不惊人:"yǔ bù jīng rén",于今为烈:"yú jīn wéi liè",一日三省:"yí rì sān xǐng",穴居野处:"xué jū yě chǔ",五脊六兽:"wǔ jǐ liù shòu",无声无臭:"wú shēng wú xiù",谓予不信:"wèi yú bú xìn",舍身为国:"shě shēn wéi guó",杀妻求将:"shā qī qiú jiàng",强作解人:"qiǎng zuò jiě rén",气冲斗牛:"qì chōng dǒu niú",临深履薄:"lín shēn lǚ bó",钧天广乐:"jūn tiān guǎng yuè",艰难竭蹶:"jiān nán jié jué",夹七夹八:"jiā qī jiā bā",混混噩噩:"hún hún è è",厚古薄今:"hòu gǔ bó jīn",鬼怕恶人:"guǐ pà è rén",伽马射线:"gā mǎ shè xiàn",佛头着粪:"fó tóu zhuó fèn",奉为至宝:"fèng wéi zhì bǎo",登坛拜将:"dēng tán bài jiàng",晨昏定省:"chén hūn dìng xǐng",察察为明:"chá chá wéi míng",博闻强识:"bó wén qiáng zhì",避难就易:"bì nán jiù yì",了无生机:"liǎo wú shēng jī",有一说一:"yǒu yī shuō yī",独一无二:"dú yī wú èr",说一不二:"shuō yī bù èr",举一反三:"jǔ yī fǎn sān",数一数二:"shǔ yī shǔ èr",杀一儆百:"shā yī jǐng bǎi",丁一卯二:"dīng yī mǎo èr",丁一确二:"dīng yī què èr",不一而止:"bù yī ér zhǐ",无一幸免:"wú yī xìng miǎn",表里不一:"biǎo lǐ bù yī",良莠不一:"liáng yǒu bù yī",心口不一:"xīn kǒu bù yī",言行不一:"yán xíng bù yī",政令不一:"zhèng lìng bù yī",参差不一:"cēn cī bù yī",纷纷不一:"fēn fēn bù yī",毁誉不一:"huǐ yù bù yī",不一而三:"bù yī ér sān",百不一遇:"bǎi bù yī yù",言行抱一:"yán xíng bào yī",瑜百瑕一:"yú bǎi xiá yī",背城借一:"bèi chéng jiè yī",凭城借一:"píng chéng jiè yī",劝百讽一:"quàn bǎi fěng yī",群居和一:"qún jū hé yī",百不获一:"bǎi bù huò yī",百不失一:"bǎi bù shī yī",百无失一:"bǎi wú shī yī",万不失一:"wàn bù shī yī",万无失一:"wàn wú shī yī",合而为一:"hé ér wéi yī",合两为一:"hé liǎng wéi yī",合二为一:"hé èr wéi yī",天下为一:"tiān xià wéi yī",相与为一:"xiāng yǔ wéi yī",较若画一:"jiào ruò huà yī",较如画一:"jiào rú huà yī",斠若画一:"jiào ruò huà yī",言行若一:"yán xíng ruò yī",始终若一:"shǐ zhōng ruò yī",终始若一:"zhōng shǐ ruò yī",惟精惟一:"wéi jīng wéi yī",众多非一:"zhòng duō fēi yī",不能赞一:"bù néng zàn yī",问一答十:"wèn yī dá shí",一不扭众:"yī bù niǔ zhòng",一以贯之:"yī yǐ guàn zhī",一以当百:"yī yǐ dāng bǎi",百不当一:"bǎi bù dāng yī",十不当一:"shí bù dāng yī",以一警百:"yǐ yī jǐng bǎi",以一奉百:"yǐ yī fèng bǎi",以一持万:"yǐ yī chí wàn",以一知万:"yǐ yī zhī wàn",百里挑一:"bǎi lǐ tiāo yī",整齐划一:"zhěng qí huà yī",一来二去:"yī lái èr qù",一路公交:"yī lù gōng jiāo",一路汽车:"yī lù qì chē",一路巴士:"yī lù bā shì",朝朝朝落:"zhāo cháo zhāo luò",曲意逢迎:"qū yì féng yíng",一行不行:"yì háng bù xíng",行行不行:"háng háng bù xíng"},Cue=Object.keys(e_).map(e=>({zh:e,pinyin:e_[e],probability:2e-8,length:4,priority:yl.Normal,dict:Symbol("dict4")})),t_={巴尔干半岛:"bā ěr gàn bàn dǎo",巴尔喀什湖:"bā ěr kā shí hú",不幸而言中:"bú xìng ér yán zhòng",布尔什维克:"bù ěr shí wéi kè",何乐而不为:"hé lè ér bù wéi",苛政猛于虎:"kē zhèng měng yú hǔ",蒙得维的亚:"méng dé wéi dì yà",民以食为天:"mín yǐ shí wéi tiān",事后诸葛亮:"shì hòu zhū gě liàng",物以稀为贵:"wù yǐ xī wéi guì",先下手为强:"xiān xià shǒu wéi qiáng",行行出状元:"háng háng chū zhuàng yuan",亚得里亚海:"yà dé lǐ yà hǎi",眼不见为净:"yǎn bú jiàn wéi jìng",竹筒倒豆子:"zhú tǒng dào dòu zi"},wue=Object.keys(t_).map(e=>({zh:e,pinyin:t_[e],probability:2e-8,length:5,priority:yl.Normal,dict:Symbol("dict5")}));function n_(e,t){return e&&(e.decimal<t.decimal||e.decimal===t.decimal&&e.probability>t.probability)?e:t}function i_(e){e.probability<1e-300&&(e.probability*=1e300,e.decimal+=1)}function xue(e){return e.priority===yl.Custom?-(e.length*e.length*100):e.priority===yl.Surname?-(e.length*e.length*10):0}function Sue(e,t){const n=[];let i=e.length-1,o=e[i];for(let s=t-1;s>=0;s--){const r=s+1>=t?{probability:1,decimal:0,patterns:[]}:n[s+1];for(;o&&o.index+o.length-1===s;){const a=o.index,u={probability:o.probability*r.probability,decimal:r.decimal+xue(o),patterns:r.patterns,concatPattern:o};i_(u),n[a]=n_(n[a],u),o=e[--i]}const l={probability:1e-13*r.probability,decimal:0,patterns:r.patterns};i_(l),n[s]=n_(n[s],l),n[s].concatPattern&&(n[s].patterns=n[s].patterns.concat(n[s].concatPattern),n[s].concatPattern=void 0,delete n[s+1])}return n[0].patterns.reverse()}function o_(e,t){return e&&e.count<=t.count?e:t}function _ue(e){return e.priority===yl.Custom?-(e.length*e.length*1e5):e.priority===yl.Surname?-(e.length*e.length*100):1}function Mue(e,t){const n=[];let i=e.length-1,o=e[i];for(let s=t-1;s>=0;s--){const r=s+1>=t?{count:0,patterns:[]}:n[s+1];for(;o&&o.index+o.length-1===s;){const a=o.index,u={count:_ue(o)+r.count,patterns:r.patterns,concatPattern:o};n[a]=o_(n[a],u),o=e[--i]}const l={count:1+r.count,patterns:r.patterns};n[s]=o_(n[s],l),n[s].concatPattern&&(n[s].patterns=n[s].patterns.concat(n[s].concatPattern),n[s].concatPattern=void 0,delete n[s+1])}return n[0].patterns.reverse()}function Iue(e,t){return!(t.index+t.length<=e.index||t.priority>e.priority||t.priority===e.priority&&t.length>e.length)}function Eue(e){const t=[];for(let n=e.length-1;n>=0;){const{index:i}=e[n];let o=n-1;for(;o>=0&&Iue(e[n],e[o]);)o--;(o<0||e[o].index+e[o].length<=i)&&t.push(e[n]),n=o}return t.reverse()}var s_;(function(e){e[e.ReverseMaxMatch=1]="ReverseMaxMatch",e[e.MaxProbability=2]="MaxProbability",e[e.MinTokenization=3]="MinTokenization"})(s_||(s_={}));class r_{constructor(t,n="",i=""){this.children=new Map,this.fail=null,this.patterns=[],this.parent=t,this.prefix=n,this.key=i}}class Tue{constructor(){this.dictMap=new Map,this.queues=[],this.root=new r_(null)}build(t){this.buildTrie(t),this.buildFailPointer()}buildTrie(t){for(let n of t){const i=n8(n.zh);let o=this.root;for(let s=0;s<i.length;s++){let r=i[s];if(!o.children.has(r)){const l=new r_(o,i.slice(0,s).join(""),r);o.children.set(r,l),this.addNodeToQueues(l)}o=o.children.get(r)}this.insertPattern(o.patterns,n),n.node=o,this.addPatternToDictMap(n)}}buildFailPointer(){let t=[],n=0;for(this.queues.forEach(i=>{t=t.concat(i)}),this.queues=[];t.length>n;){let i=t[n++],o=i.parent&&i.parent.fail,s=i.key;for(;o&&!o.children.has(s);)o=o.fail;o?i.fail=o.children.get(s):i.fail=this.root}}addPatternToDictMap(t){this.dictMap.has(t.dict)||this.dictMap.set(t.dict,new Set),this.dictMap.get(t.dict).add(t)}addNodeToQueues(t){this.queues[ta(t.prefix)]||(this.queues[ta(t.prefix)]=[]),this.queues[ta(t.prefix)].push(t)}insertPattern(t,n){for(let i=t.length-1;i>=0;i--){const o=t[i];if(n.priority===o.priority&&n.probability>=o.probability)t[i+1]=o;else if(n.priority>o.priority)t[i+1]=o;else{t[i+1]=n;return}}t[0]=n}removeDict(t){this.dictMap.has(t)&&(this.dictMap.get(t).forEach(i=>{i.node.patterns=i.node.patterns.filter(o=>o!==i)}),this.dictMap.delete(t))}match(t,n){let i=this.root,o=[];const s=n8(t);for(let r=0;r<s.length;r++){let l=s[r];for(;i!==null&&!i.children.has(l);)i=i.fail;if(i===null)i=this.root;else{i=i.children.get(l);const a=i.patterns.find(c=>n==="off"?c.priority!==yl.Surname:n==="head"?c.length-1-r===0:!0);a&&o.push(Object.assign(Object.assign({},a),{index:r-a.length+1}));let u=i.fail;for(;u!==null;){const c=u.patterns.find(d=>n==="off"?d.priority!==yl.Surname:n==="head"?d.length-1-r===0:!0);c&&o.push(Object.assign(Object.assign({},c),{index:r-c.length+1})),u=u.fail}}}return o}search(t,n,i=2){const o=this.match(t,n);return i===1?Eue(o):i===3?Mue(o,ta(t)):Sue(o,ta(t))}}const Lue=[...wue,...Cue,...Aue,...bue,...mue,...kue],s$=new Tue;s$.build(Lue);const Nue=new i$,Fue=()=>Nue,Due=[];function Bue(){return Due}const gp=e=>{const t=_c.get(e);return t?t.split(" ")[0]:e},$ue=e=>{const t=[],n=Bue();for(let i=0;i<e.length;i++){const o=e[i],s=o.charCodeAt(0);n[s]?t[i]=n[s]:t[i]=o}return t.join("")},Rue=(e,t,n,i,o)=>{const s=o?$ue(e):e,r=s$.search(s,n,i);let l=0;const a=n8(e);for(let u=0;u<a.length;){const c=r[l];if(c&&u===c.index){if(c.length===1&&c.priority<=yl.Normal){const p=a[u];c.zh=p;let g="";g=l_(p,a[u-1],a[u+1]),t[u]={origin:p,result:g,isZh:g!==p,originPinyin:g},u++,l++;continue}const d=c.pinyin.split(" ");let h=0;o&&(c.zh=a.slice(c.index,c.index+c.length).join(""));for(let p=0;p<c.length;p++)t[u+p]={origin:a[p+c.index],result:d[h]||"",isZh:!0,originPinyin:d[h]||""},h++;u+=c.length,l++}else{const d=a[u];let h="";h=l_(d,a[u-1],a[u+1]),t[u]={origin:d,result:h,isZh:h!==d,originPinyin:h},u++}}return{list:t,matches:r}},f9=e=>e.replace(/(ā|á|ǎ|à)/g,"a").replace(/(ō|ó|ǒ|ò)/g,"o").replace(/(ē|é|ě|è)/g,"e").replace(/(ī|í|ǐ|ì)/g,"i").replace(/(ū|ú|ǔ|ù)/g,"u").replace(/(ǖ|ǘ|ǚ|ǜ)/g,"ü").replace(/(n̄|ń|ň|ǹ)/g,"n").replace(/(m̄|ḿ|m̌|m̀)/g,"m").replace(/(ê̄|ế|ê̌|ề)/g,"ê"),r$=(e,t="off")=>{const n=Fue();let i=_c.get(e)?_c.get(e).split(" "):[];if(n.get(e))i=n.get(e).split(" ");else if(t!=="off"){const o=i8[e];o&&(i=[o].concat(i.filter(s=>s!==o)))}return i},zue=(e,t="off")=>{let n=r$(e,t);return n.length>0?n.map(i=>({origin:e,result:i,isZh:!0,originPinyin:i})):[{origin:e,result:e,isZh:!1,originPinyin:e}]},_2=(e,t)=>{const n=e.split(" "),i=[],o=[];for(let s of n)for(let r of cue)if(s.startsWith(r)){let l=s.slice(r.length);due.indexOf(r)!==-1&&fue.indexOf(l)!==-1&&(l=hue[l]),i.push(r),o.push(l);break}return t==="standard"&&i.forEach((s,r)=>{(s==="y"||s==="w")&&(i[r]="")}),{final:o.join(" "),initial:i.join(" ")}},wv=e=>{const{final:t}=_2(e);let n="",i="",o="";return pue.indexOf(f9(t))!==-1?(n=t[0],i=t[1],o=t.slice(2)):(i=t[0]||"",o=t.slice(1)||""),{head:n,body:i,tail:o}},h9=e=>{const t=/(ā|ō|ē|ī|ū|ǖ|n̄|m̄|ê̄)/,n=/(á|ó|é|í|ú|ǘ|ń|ḿ|ế)/,i=/(ǎ|ǒ|ě|ǐ|ǔ|ǚ|ň|m̌|ê̌)/,o=/(à|ò|è|ì|ù|ǜ|ǹ|m̀|ề)/,s=/(a|o|e|i|u|ü|ê)/,r=/(n|m)$/,l=[];return e.split(" ").forEach(u=>{t.test(u)?l.push("1"):n.test(u)?l.push("2"):i.test(u)?l.push("3"):o.test(u)?l.push("4"):s.test(u)||r.test(u)?l.push("0"):l.push("")}),l.join(" ")},Oue=(e,t)=>{const n=f9(e).split(" "),i=h9(t).split(" "),o=[];return n.forEach((s,r)=>{o.push(`${s}${i[r]}`)}),o.join(" ")},l$=(e,t)=>{const n=[];return e.split(" ").forEach(o=>{n.push(t?o[0]:o)}),n.join(" ")};function Pue(e,t,n){if(yue.indexOf(e)===-1)return gp(e);if(t===n&&t&&gp(t)!==t)return f9(gp(e));if(n&&!vue[e].includes(n)){const i=gp(n);if(i!==n){const o=h9(i),s=o$[e];for(let r in s)if(s[r].indexOf(Number(o))!==-1)return r}}}function jue(e,t){if(e==="了"&&(!t||!_c.get(t)))return"liǎo"}function Hue(e,t){if(e==="々")return!t||!_c.get(t)?"tóng":_c.get(t).split(" ")[0]}function l_(e,t,n){return Hue(e,t)||jue(e,t)||Pue(e,t,n)||gp(e)}const Wue=e=>typeof e!="string"?(console.error("The first param of pinyin is error: "+e+' is not assignable to type "string".'),!1):!0;function m3(e,t){return t instanceof RegExp?t.test(e):!0}const que=(e,t)=>{let n=t.nonZh;if(n==="removed")return e.filter(i=>i.isZh||!m3(i.origin,t.nonZhScope));if(n==="consecutive"){for(let i=e.length-2;i>=0;i--){const o=e[i],s=e[i+1];!o.isZh&&!s.isZh&&m3(o.origin,t.nonZhScope)&&m3(s.origin,t.nonZhScope)&&(o.origin+=s.origin,o.result+=s.result,s.delete=!0)}return e.filter(i=>!i.delete)}else return e},a_=(e,t)=>ta(e)===1&&t.multiple?zue(e,t.surname):!1,Uue=(e,t)=>{switch(t.pattern){case"pinyin":break;case"num":e.forEach(n=>{n.result=n.isZh?h9(n.result):""});break;case"initial":e.forEach(n=>{n.result=n.isZh?_2(n.result,t.initialPattern).initial:""});break;case"final":e.forEach(n=>{n.result=n.isZh?_2(n.result,t.initialPattern).final:""});break;case"first":e.forEach(n=>{n.result=l$(n.result,n.isZh)});break;case"finalHead":e.forEach(n=>{n.result=n.isZh?wv(n.result).head:""});break;case"finalBody":e.forEach(n=>{n.result=n.isZh?wv(n.result).body:""});break;case"finalTail":e.forEach(n=>{n.result=n.isZh?wv(n.result).tail:""});break}},Kue=(e,t)=>{switch(t.toneType){case"symbol":break;case"none":e.forEach(n=>{n.isZh&&(n.result=f9(n.result))});break;case"num":{e.forEach(n=>{n.isZh&&(n.result=Oue(n.result,n.originPinyin))});break}}},Vue=(e,t)=>{t.v&&e.forEach(n=>{n.isZh&&(n.result=n.result.replace(/ü/g,typeof t.v=="string"?t.v:"v"))})},Zue=(e,t,n)=>{if(t.multiple&&ta(n)===1){let i="";e=e.filter(o=>{const s=o.result!==i;return i=o.result,s})}return t.type==="array"?e.map(i=>i.result):t.type==="all"?e.map(i=>{const o=i.isZh?i.result:"",{initial:s,final:r}=_2(o,t.initialPattern),{head:l,body:a,tail:u}=wv(o);let c=[];return o!==""&&(c=[o].concat(r$(i.origin,t.surname).filter(d=>d!==o))),{origin:i.origin,pinyin:o,initial:s,final:r,first:l$(i.result,i.isZh),finalHead:l,finalBody:a,finalTail:u,num:Number(h9(i.originPinyin)),isZh:i.isZh,polyphonic:c,inZhRange:!!_c.get(i.origin),result:i.result}}):e.map(i=>i.result).join(t.separator)},Gue=(e,t)=>(t===!1&&e.forEach(n=>{n.origin==="一"?n.result=n.originPinyin="yī":n.origin==="不"&&(n.result=n.originPinyin="bù")}),e),Que={pattern:"pinyin",toneType:"symbol",type:"string",multiple:!1,mode:"normal",removeNonZh:!1,nonZh:"spaced",v:!1,separator:" ",toneSandhi:!0,segmentit:2};function M2(e,t){if(t=Object.assign(Object.assign({},Que),t||{}),!Wue(e))return e;if(e==="")return t.type==="array"||t.type==="all"?[]:"";t.surname===void 0&&(t.mode==="surname"?t.surname="all":t.surname="off"),t.type==="all"&&(t.pattern="pinyin"),t.pattern==="num"&&(t.toneType="none"),t.removeNonZh&&(t.nonZh="removed");let i=Array(ta(e)),{list:o}=Rue(e,i,t.surname,t.segmentit,t.traditional);return o=Gue(o,t.toneSandhi),o=que(o,t),a_(e,t)&&(o=a_(e,t)),Uue(o,t),Kue(o,t),Vue(o,t),Zue(o,t,e)}var o8;(function(e){e[e.AllSegment=1]="AllSegment",e[e.AllArray=2]="AllArray",e[e.AllString=3]="AllString",e[e.PinyinSegment=4]="PinyinSegment",e[e.PinyinArray=5]="PinyinArray",e[e.PinyinString=6]="PinyinString",e[e.ZhSegment=7]="ZhSegment",e[e.ZhArray=8]="ZhArray",e[e.ZhString=9]="ZhString"})(o8||(o8={}));o8.AllSegment;const a$=[{name:"/new",desc:"commands.new.desc"},{name:"/clear",desc:"commands.clear.desc"},{name:"/login",desc:"commands.login.desc"},{name:"/plan",desc:"commands.plan.desc"},{name:"/swarm",desc:"commands.swarm.desc"},{name:"/goal",desc:"commands.goal.desc"},{name:"/btw",desc:"commands.btw.desc",acceptsInput:!0},{name:"/compact",desc:"commands.compact.desc",acceptsInput:!0},{name:"/undo",desc:"commands.undo.desc"},{name:"/fork",desc:"commands.fork.desc"},{name:"/export",desc:"commands.export.desc"},{name:"/status",desc:"commands.status.desc"}];function Yue(e){if(!e.startsWith("/"))return null;const t=e.indexOf(" ");return t===-1?{cmd:e,arg:""}:{cmd:e.slice(0,t),arg:e.slice(t+1)}}const Zd="skill:";function Jue(e,t){const n=e.find(r=>r.name===t);if(n!==void 0)return n;const i=`/${Zd}${t.slice(1)}`,o=e.find(r=>r.name===i);if(o!==void 0)return o;if(!t.startsWith(`/${Zd}`))return;const s=t.slice(1+Zd.length);if(!(s.length===0||s.includes(" ")))return e.find(r=>r.isSkill===!0&&u$(r.name)===s)}function u$(e){const t=e.startsWith("/")?e.slice(1):e;return t.startsWith(Zd)?t.slice(Zd.length):t}function c$(e=[]){const t=e.map(n=>({name:n.source==="builtin"?`/${n.name}`:`/${Zd}${n.name}`,desc:n.description,isSkill:!0,acceptsInput:!0}));return[...a$,...t]}const u_=new Map;function d$(e){let t=u_.get(e);if(!t){const n=M2(e,{toneType:"none",type:"array"}),i=M2(e,{pattern:"first",toneType:"none",type:"array"});t=Xue(e,n,i),u_.set(e,t)}return t}const c_={full:[],first:[],offsets:[],literal:[]};function Xue(e,t,n){if(t.length!==n.length)return c_;const i=[],o=[];let s=0;for(let r=0;r<t.length;r++){i.push(s);const l=t[r];l.length>0&&e.slice(s,s+l.length).toLowerCase()===l.toLowerCase()?(o.push(!0),s+=l.length):(o.push(!1),s+=Array.from(e.slice(s))[0]?.length??0)}return i.push(s),s!==e.length?c_:{full:t,first:n,offsets:i,literal:o}}function s8(e,t,n,i){const o=e[t];let s=0,r=-1,l=-1,a=0,u=0;for(let h=0;h<o.length;h++){const p=s+(o[h]?.length??0);if(r<0&&n<p&&(r=h,a=s),i<=p){l=h,u=s;break}s=p}if(r<0||l<0)return;const c=e.literal[r]?e.offsets[r]+(n-a):e.offsets[r],d=e.literal[l]?e.offsets[l]+(i-u):e.offsets[l+1];return[c,d]}const d_=new Map;function ece(e){let t=d_.get(e);return t||(t={full:M2(e,{toneType:"none",type:"string",separator:""}),first:M2(e,{pattern:"first",toneType:"none",type:"string",separator:""})},d_.set(e,t)),t}function f$(e,t){const n=e.toLowerCase().indexOf(t);return n<0?void 0:[n,n+t.length]}function tce(e,t){const n=e.toLowerCase();let i=0,o=-1,s=-1;for(let r=0;r<n.length&&i<t.length;r++)n[r]===t[i]&&(i===0&&(o=r),s=r,i++);return i===t.length?[o,s+1]:void 0}function nce(e,t){return f$(e,t)??tce(e,t)}function ice(e,t){const n=f$(e,t);if(n)return n;if(!/^[\x21-\x7e]+$/.test(t))return;const i=d$(e),o=i.first.join("").indexOf(t);if(o>=0)return s8(i,"first",o,o+t.length);const s=i.full.join("").indexOf(t);if(!(s<0))return s8(i,"full",s,s+t.length)}function oce(e,t,n){const i=e.trim().replace(/^\//,"").toLowerCase();if(i==="")return{};const o=nce(t,i),s=ice(n,i);return{name:o?[o]:void 0,desc:s?[s]:void 0}}const sce={keys:[{name:"name",weight:3},{name:"desc",weight:1},{name:"pinyinFull",weight:1},{name:"pinyinFirst",weight:1}],includeScore:!0,includeMatches:!0,ignoreLocation:!0,threshold:.4};function rce(e,t){const n=e.toLowerCase(),i=t.toLowerCase();return n===i?0:n.startsWith(i)?1:2}function f_(e){const t=[...e].sort((i,o)=>i[0]-o[0]),n=[];for(const i of t){const o=n[n.length-1];o&&i[0]<=o[1]?o[1]=Math.max(o[1],i[1]):n.push([...i])}return n}function lce(e,t){const n=[],i=[];for(const o of t??[])for(const[s,r]of o.indices)if(o.key==="name")n.push([s+1,r+2]);else if(o.key==="desc")i.push([s,r+1]);else if(o.key==="pinyinFirst"||o.key==="pinyinFull"){const l=s8(d$(e.desc),o.key==="pinyinFirst"?"first":"full",s,r+1);l&&i.push(l)}return{name:n.length>0?f_(n):void 0,desc:i.length>0?f_(i):void 0}}function ace(e,t=a$,n=i=>i.desc){const i=e.trim().replace(/^\//,"");if(i==="")return t.map(s=>({item:s,ranges:{}}));const o=t.map((s,r)=>{const l=n(s),a=ece(l);return{index:r,item:s,name:s.name.replace(/^\//,""),desc:l,pinyinFull:a.full,pinyinFirst:a.first}});return new rue(o,sce).search(i).map(({item:s,score:r,matches:l})=>({doc:s,score:r??1,rank:rce(s.name,i),ranges:lce(s,l)})).sort((s,r)=>s.rank!==r.rank?s.rank-r.rank:s.score!==r.score?s.score-r.score:s.doc.index-r.doc.index).map(({doc:s,ranges:r})=>({item:s.item,ranges:r}))}function uce(e,t){if(t.length===0||e.length===0)return t;const n=Date.parse(t[0].createdAt);if(Number.isNaN(n))return t;const i=new Set(t.map(r=>r.id)),o=new Set(t.flatMap(r=>r.role==="user"&&r.promptId!==void 0?[r.promptId]:[])),s=e.filter(r=>{const l=Date.parse(r.createdAt);return!(Number.isNaN(l)||l>=n||i.has(r.id)||r.role==="user"&&(r.userMessageId!==void 0&&i.has(r.userMessageId)||r.promptId!==void 0&&o.has(r.promptId)))});return s.length>0?[...s,...t]:t}function cce(e){const t=new Map,n=new Set;function i(s){const r=t.get(s);if(r!==void 0)return r;const l=(async()=>e(s))().finally(()=>{t.delete(s),n.delete(s)&&i(s)});return t.set(s,l),l}function o(s){if(t.has(s)){n.add(s);return}i(s)}return{run:i,request:o}}const un={permission:"kimi-web.permission",activeWorkspace:"kimi-active-workspace",planArmed:"kimi-web.plan-armed",swarmMode:"kimi-web.swarm-mode",goalMode:"kimi-web.goal-mode",fontScale:"kimi-web.font-scale",starredModels:"kimi-web.starred-models",unread:"kimi-web.unread",onboarded:"kimi-web.onboarded",colorScheme:"kimi-web.color-scheme",hiddenWorkspaces:"kimi-web.hidden-workspaces",collapsedWorkspaces:"kimi-web.collapsed-workspaces",workspaceOrder:"kimi-web.workspace-order",workspaceSort:"kimi-web.workspace-sort",workspaceRecencyFloor:"kimi-web.workspace-recency-floor",pinnedSessions:"kimi-web.pinned-sessions",pinnedCollapsed:"kimi-web.pinned-collapsed",workspaceNameOverrides:"kimi-web.workspace-name-overrides",notifyEnabled:"kimi-web.notify-enabled",notifySound:"kimi-web.notify-sound",inputHistory:"kimi-web.input-history",locale:"kimi-locale",clientId:"kimi-web.client-id",debug:"kimi-web.debug",openInDefaultTarget:"kimi-web.open-in.default-target",openInLastTarget:"kimi-web.open-in.last-target",sidebarCollapsed:"kimi-web.sidebar-collapsed",sidebarWidth:"kimi-web.sidebar-width",sidebarViewMode:"kimi-web.sidebar-view-mode",mobileSwitcherViewMode:"kimi-web.mobile-switcher-view-mode",sidebarPinnedHeight:"kimi-web.sidebar-pinned-height",shortcutOverrides:"kimi-web.shortcut-overrides",dockIconChoice:"kimi-web.dock-icon-choice",updateSkippedVersion:"kimi-web.update-skipped-version",planMode:"kimi-web.plan-mode",codeFont:"kimi-web.code-font",contentAlign:"kimi-web.content-align",theme:"kimi-web.theme",thinking:"kimi-web.thinking",accent:"kimi-web.accent",notifyOnComplete:"kimi-web.notify-on-complete",notifyOnQuestion:"kimi-web.notify-on-question",notifyOnApproval:"kimi-web.notify-on-approval",soundOnComplete:"kimi-web.sound-on-complete"};function h_(e){return`kimi-web.draft.${e&&e.length>0?e:"__new__"}`}function p_(e){return`kimi-web.attachment-draft.${e&&e.length>0?e:"__new__"}`}function gs(e){try{return globalThis.localStorage.getItem(e)}catch{return null}}function is(e,t){try{globalThis.localStorage.setItem(e,t)}catch{}}function _r(e){try{globalThis.localStorage.removeItem(e)}catch{}}function Kc(e){const t=gs(e);if(t===null)return null;try{return JSON.parse(t)}catch{return null}}function Lu(e,t){try{globalThis.localStorage.setItem(e,JSON.stringify(t))}catch{}}function $6(){const e=gs(un.unread);if(!e)return{};try{const t=JSON.parse(e);if(!t||typeof t!="object")return{};const n={};for(const[i,o]of Object.entries(t))o===!0&&(n[i]=!0);return n}catch{return{}}}function R6(e){const n={...$6()};for(const[i,o]of Object.entries(e))o?n[i]=!0:delete n[i];is(un.unread,JSON.stringify(n))}function dce(){const e=Kc(un.collapsedWorkspaces);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function v3(e){Lu(un.collapsedWorkspaces,Array.from(e))}function fce(){return Kc(un.pinnedCollapsed)===!0}function r8(e){Lu(un.pinnedCollapsed,e)}function hce(){return gs(un.sidebarViewMode)==="flat"?"flat":"grouped"}function pce(e){is(un.sidebarViewMode,e)}function gce(){return gs(un.mobileSwitcherViewMode)==="grouped"?"grouped":"flat"}function mce(e){is(un.mobileSwitcherViewMode,e)}function vce(){const e=Kc(un.workspaceOrder);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function h$(e){Lu(un.workspaceOrder,Array.from(e))}function yce(){return gs(un.workspaceSort)==="recent"?"recent":"manual"}function kce(e){is(un.workspaceSort,e)}function bce(){const e=Kc(un.workspaceRecencyFloor);if(!e||typeof e!="object")return{};const t={};for(const[n,i]of Object.entries(e))typeof i=="number"&&Number.isFinite(i)&&(t[n]=i);return t}function p$(e){Lu(un.workspaceRecencyFloor,e)}function g$(){const e=Kc(un.pinnedSessions);return Array.isArray(e)?e.filter(t=>typeof t=="string"):[]}function y3(e){Lu(un.pinnedSessions,Array.from(e))}function Im(){const e=Kc(un.workspaceNameOverrides);if(!e||typeof e!="object")return{};const t={};for(const[n,i]of Object.entries(e))typeof i=="string"&&(t[n]=i);return t}function g_(e){Lu(un.workspaceNameOverrides,e)}function Ace(e,t,n,i,o){const s=n-o-(t.right+i),r=t.left-i-o,l=e>s&&r>s,a=Math.min(e,l?r:s);return{left:l?t.left-i-a:t.right+i,maxWidth:a,flipped:l}}function m_(e,t){const n=new Set(e.map(u=>u.id)),i=t.filter(u=>u.kind==="subagent"&&!n.has(u.id));if(i.length===0)return e;const o=new Map(e.map(u=>[u.id,u])),s=new Map(e.filter(u=>u.kind==="subagent"&&u.agentId!==void 0).map(u=>[u.agentId,u])),r=new Set,l=i.map(u=>{const c=(u.backgroundTaskId!==void 0?o.get(u.backgroundTaskId):void 0)??s.get(u.agentId??u.id);if(c===void 0)return u;r.add(c.id);const d=u.status==="running"&&c.status!=="running";return{...u,status:u.status==="running"?c.status:u.status,subagentPhase:d?c.status==="completed"?"completed":"failed":u.subagentPhase,completedAt:c.completedAt??u.completedAt,completedAtEstimated:c.completedAt!==void 0?void 0:u.completedAtEstimated,outputPreview:c.outputPreview??u.outputPreview,outputBytes:c.outputBytes??u.outputBytes,model:u.model??c.model,thinkingEffort:u.thinkingEffort??c.thinkingEffort}});return[...e.filter(u=>!r.has(u.id)),...l]}function Cce(e,t){if(e.length===0)return t;const n=new Map(t.map(r=>[r.id,r])),i=new Set(e.map(r=>r.id)),o=e.map(r=>{const l=n.get(r.id);if(!l)return r;const a=r.completedAt===void 0&&l.completedAt===void 0&&l.status==="running"&&r.status!=="running";return{...r,outputLines:l.outputLines,text:l.text,completedAt:r.completedAt??l.completedAt??(a?new Date().toISOString():void 0),completedAtEstimated:r.completedAt!==void 0?void 0:l.completedAt!==void 0?l.completedAtEstimated:a?!0:void 0,model:r.model??l.model,thinkingEffort:r.thinkingEffort??l.thinkingEffort}}),s=t.filter(r=>!i.has(r.id));return s.length===0?o:[...o,...s]}function wce(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const e=navigator.userAgentData;return e?.platform==="macOS"||e?.platform==="iOS"}function xce(e,t=wce()){return(t?e.metaKey&&!e.ctrlKey:e.ctrlKey&&!e.metaKey)&&!e.altKey&&!e.shiftKey&&(e.code==="KeyF"||e.key.toLowerCase()==="f")&&!e.defaultPrevented}const Sce=new Map([["ς","σ"],["ß","ss"],["ſ","s"],["ff","ff"],["fi","fi"],["fl","fl"],["ffi","ffi"],["ffl","ffl"],["ſt","st"],["st","st"],["ʼn","ʼn"],["µ","μ"],["K","k"],["Å","å"],["Ω","ω"]]);function _ce(e){return e==="pre"||e==="pre-wrap"||e==="break-spaces"?"preserve":e==="pre-line"?"pre-line":"collapse"}function Mce(e,t){if(t==="preserve")return{text:e,map:Array.from({length:e.length},(r,l)=>l)};const n=t==="collapse"?/[\t\n\f\r ]/:/[\t ]/;let i="";const o=[];let s=!1;for(let r=0;r<e.length;r++)n.test(e[r])?s||(i+=" ",o.push(r),s=!0):(i+=e[r],o.push(r),s=!1);return{text:i,map:o}}function v_(e){let t="";const n=[];let i=0;for(const o of e){const s=o.toLowerCase(),r=Sce.get(s)??s;t+=r;for(let l=0;l<r.length;l++)n.push({start:i,length:o.length});i+=o.length}return{folded:t,map:n}}function*Ice(e,t){if(t.length===0||e.length===0)return;const n=e.map(c=>v_(c.text)),i="\0";let o="";const s=[];for(let c=0;c<e.length;c++)c>0&&e[c].gapBefore&&(o+=i),s[c]=o.length,o+=n[c].folded;const r=Tce(v_(t).folded);if(r===null)return;const l=new RegExp(r,"g");function a(c){let d=0,h=s.length-1,p=0;for(;d<=h;){const g=d+h>>1;s[g]<=c?(p=g,d=g+1):h=g-1}return p}let u;for(;;){const c=l.exec(o);if(c===null)return;const d=c.index,h=d+c[0].length-1,p=a(d),g=a(h),m=n[p].map[d-s[p]],k=n[g].map[h-s[g]],w={startSeg:p,startOffset:m.start,endSeg:g,endOffset:k.start+k.length};u!==void 0&&u.startSeg===w.startSeg&&u.startOffset===w.startOffset&&u.endSeg===w.endSeg&&u.endOffset===w.endOffset||(u=w,yield w)}}const Ece=/[.*+?^${}()|[\]\\]/g;function Tce(e){const t=[];let n=0;for(;n<e.length;){const i=/^\s+/.exec(e.slice(n));if(i!==null){t.push("\\s+"),n+=i[0].length;continue}const o=/^[^\s]+/.exec(e.slice(n));t.push(o[0].replaceAll(Ece,"\\$&")),n+=o[0].length}return t.length===0?null:t.join("")}const y_="script, style, noscript, template, [inert], .top-sentinel",Lce=new Set(["ADDRESS","ARTICLE","ASIDE","BLOCKQUOTE","BR","DD","DIV","DL","DT","FIELDSET","FIGCAPTION","FIGURE","FOOTER","FORM","H1","H2","H3","H4","H5","H6","HEADER","HR","LI","MAIN","NAV","OL","P","PRE","SECTION","TABLE","TBODY","TD","TFOOT","TH","THEAD","TR","UL"]),Nce=new Set(["inline","inline-block","inline-flex","inline-grid","inline-table","contents","ruby"]);function Fce(e,t){const n=t.get(e);if(n!==void 0)return n;const i=Lce.has(e.tagName)||!Nce.has(getComputedStyle(e).display);return t.set(e,i),i}function Dce(e,t,n){let i=e.parentElement;for(;i!==null&&i!==t&&!Fce(i,n);)i=i.parentElement;return i??t}const Bce=1e3;function $ce(e,t){if(t.length===0)return{ranges:[],truncated:!1};const n=e.ownerDocument,i=n.createTreeWalker(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,{acceptNode(u){return u.nodeType===Node.ELEMENT_NODE?u.matches(y_)?NodeFilter.FILTER_REJECT:u.matches("br, hr, wbr")&&!u.closest(y_)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP:NodeFilter.FILTER_ACCEPT}}),o=new WeakMap,s=new WeakMap,r=[];let l=!1;for(let u=i.nextNode();u!==null;u=i.nextNode()){if(u.nodeType===Node.ELEMENT_NODE){l=!0;continue}const c=u.nodeValue??"";if(c.length===0)continue;const d=u.parentElement;if(d===null)continue;let h=s.get(d);h===void 0&&(h=_ce(getComputedStyle(d).whiteSpace),s.set(d,h));let{text:p,map:g}=Mce(c,h);if(p.length===0)continue;const m=Dce(u,e,o),k=r.at(-1),w=l||k===void 0||k.block!==m;!w&&k.text.endsWith(" ")&&p.startsWith(" ")&&(p=p.slice(1),g=g.slice(1),p.length===0)||(r.push({text:p,gapBefore:w,node:u,block:m,wsMap:g}),l=!1)}const a=[];for(const u of Ice(r,t)){const c=r[u.startSeg],d=r[u.endSeg],h=n.createRange();if(h.setStart(c.node,c.wsMap[u.startOffset]),h.setEnd(d.node,d.wsMap[u.endOffset-1]+1),h.getClientRects().length!==0){if(a.length>=Bce)return{ranges:a,truncated:!0};a.push(h)}}return{ranges:a,truncated:!1}}const m$="kimi-transcript-search",l8="kimi-transcript-search-current";function v$(){return globalThis.CSS?.highlights??null}function k3(e,t){const n=v$(),i=globalThis.Highlight;if(!n||!i)return;if(e.length===0){a8();return}const o=new i;for(const r of e)o.add(r);n.set(m$,o);const s=e[t];if(s!==void 0){const r=new i;r.add(s),n.set(l8,r)}else n.delete(l8)}function a8(){const e=v$();e?.delete(m$),e?.delete(l8)}let y$=null;function Rce(e){e!==null&&(y$=e)}let k_=0,Em=null;async function u8(e){const t=++k_,n=(async()=>{const o=await e();t===k_&&Rce(o)})(),i=(async()=>{await n,Em!==null&&Em.seq>t&&await Em.promise})();return Em={seq:t,promise:i},i}let k$=null;function zce(e){k$=e}const Oce=5e3;function Pce(e){return Promise.race([e(),new Promise(t=>{setTimeout(()=>t(null),Oce)})])}function Tm(){return`${y$==="global"?"https://www.kimi.ai":"https://www.kimi.com"}/code?from=${bf?"kimi_code_desktop":"kimi_code_web"}`}function sg(){const e=k$;if(e===null){window.open(Tm(),"_blank","noopener");return}const t=()=>Pce(e);if(bf){u8(t).then(()=>{window.open(Tm(),"_blank","noopener")});return}const n=window.open("","_blank");if(n===null){window.open(Tm(),"_blank","noopener");return}try{n.opener=null}catch{}u8(t).then(()=>{try{n.location.href=Tm()}catch{}})}function jce(e,t,n){if(e.length===0)return null;const i=new Set(e),o=t.filter(r=>i.has(r)),s=e.filter(r=>!t.includes(r));return s.length===0&&o.length===t.length?null:t.length===0&&n!==void 0?s.toSorted((r,l)=>(n.get(l)??Number.NEGATIVE_INFINITY)-(n.get(r)??Number.NEGATIVE_INFINITY)):[...s,...o]}function Hce(e,t){const n=new Map(t.map((i,o)=>[i,o]));return e.toSorted((i,o)=>(n.get(i.id)??-1)-(n.get(o.id)??-1))}function Wce(e,t,n,i="before"){const o=e.indexOf(t),s=e.indexOf(n);if(o===-1||s===-1||o===s)return e;const r=[...e];r.splice(o,1);const l=o<s?s-1:s,a=i==="before"?l:l+1;return r.splice(a,0,t),r}function qce(e,t){return e.toSorted((n,i)=>(t.get(i.id)??Number.NEGATIVE_INFINITY)-(t.get(n.id)??Number.NEGATIVE_INFINITY))}function Uce(e,t){let n=!1;const i={...e};for(const[o,s]of t)s>(i[o]??Number.NEGATIVE_INFINITY)&&(i[o]=s,n=!0);return{next:i,changed:n}}function Kce(e,t){const n=new Map;for(const i of e){if(i.parentSessionId||i.archived)continue;const o=new Date(i.updatedAt).getTime();if(Number.isNaN(o))continue;const s=t(i);o>(n.get(s)??Number.NEGATIVE_INFINITY)&&n.set(s,o)}return n}function Vce(e,t){const n=new Map;for(const i of e){const o=t[i.id]??Number.NEGATIVE_INFINITY,s=i.lastOpenedAt?Date.parse(i.lastOpenedAt):Number.NaN,r=Number.isNaN(s)?Number.NEGATIVE_INFINITY:s;n.set(i.id,Math.max(o,r))}return n}function Zce(e,t){const n=Object.keys(e);if(!n.some(o=>!t.has(o)))return{next:e,changed:!1};const i={};for(const o of n)t.has(o)&&(i[o]=e[o]);return{next:i,changed:!0}}const Gce=5;function Qce(e,t,n,i=Gce){if(e.length<=i)return e;const o=e.slice(0,i);if(t&&!o.some(s=>s.id===t)){const s=e.find(r=>r.id===t);s&&(o[i-1]=s)}return o}const Yce={class:"sd-body"},Jce={class:"sd-search"},Xce=["aria-label"],ede={key:0,class:"sd-section","aria-hidden":"true"},tde={class:"sd-section-count"},nde=["aria-selected","onClick","onMousemove"],ide=["innerHTML"],ode=["innerHTML"],sde=["aria-selected","onClick","onMousemove"],rde={class:"sd-line1"},lde=["innerHTML"],ade={class:"sd-time"},ude={class:"sd-line2"},cde=["innerHTML"],dde=["innerHTML"],fde={key:1,class:"sd-empty"},hde={class:"sd-foot","aria-hidden":"true"},pde={class:"sd-hint"},gde={class:"sd-hint"},mde={class:"sd-hint"},vde=200,yde=3,kde=Xe({__name:"SearchSessionsDialog",props:{sessions:{},workspaces:{},activeId:{}},emits:["select","selectWorkspace","close"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=K(!0),r=K(""),l=K(null),a=K(null),u=F(()=>{const x=r.value.trim().toLowerCase(),_=[];if(x.length===0)for(const M of i.workspaces.slice(0,yde))_.push({kind:"workspace",key:`ws:${M.id}`,hit:{workspace:M,inName:!1,inPath:!1}});else for(const M of i.workspaces){const N=M.name.toLowerCase().includes(x),I=M.shortPath.toLowerCase().includes(x);!N&&!I||_.push({kind:"workspace",key:`ws:${M.id}`,hit:{workspace:M,inName:N,inPath:I}})}const L=[];for(const M of i.sessions){const N=M.title??"",I=M.lastPrompt??"",z=M.workspaceName??"",H=x.length>0&&N.toLowerCase().includes(x),O=x.length>0&&I.toLowerCase().includes(x),R=x.length>0&&z.toLowerCase().includes(x);if(!(x.length>0&&!H&&!O&&!R)&&(L.push({kind:"session",key:`s:${M.id}`,hit:{session:M,inTitle:H,inWorkspace:R,snippetText:I?Zle(I,r.value):""}}),L.length>=vde))break}return _.length>0&&L.length>0&&(_[0].section={label:n("sidebar.workspaces"),count:_.length},L[0].section={label:n("sidebar.sessionsHeader"),count:L.length}),[..._,...L]}),c=K(0);Pe(r,()=>{c.value=0});function d(x){const _=u.value.length;return _===0?0:Math.max(0,Math.min(_-1,x))}async function h(){await dt(),a.value?.querySelector('[aria-selected="true"]')?.scrollIntoView({block:"nearest"})}function p(x){c.value=d(c.value+x),h()}function g(x){o("select",x),o("close")}function m(x){o("selectWorkspace",x),o("close")}function k(){r.value="",l.value?.focus()}function w(){const x=u.value[c.value];x&&(x.kind==="workspace"?m(x.hit.workspace.id):g(x.hit.session.id))}function y(){return l.value?.el??null}const{handleCompositionStart:b,handleCompositionEnd:A,isComposingKeyEvent:T}=bl();function S(x){if(T(x)){x.key==="Escape"&&x.stopPropagation();return}x.key==="ArrowDown"?(x.preventDefault(),p(1)):x.key==="ArrowUp"?(x.preventDefault(),p(-1)):x.key==="Enter"&&(x.preventDefault(),w())}return cn(()=>{l.value?.focus()}),(x,_)=>(v(),ce(f(Pc),{open:s.value,"onUpdate:open":_[1]||(_[1]=L=>s.value=L),title:f(n)("sidebar.searchPlaceholder"),size:"lg",height:"fixed",padded:!1,"initial-focus":y,onClose:_[2]||(_[2]=L=>o("close"))},{default:de(()=>[C("div",Yce,[C("div",Jce,[U(f(Ns),{ref_key:"inputRef",ref:l,modelValue:r.value,"onUpdate:modelValue":_[0]||(_[0]=L=>r.value=L),placeholder:f(n)("sidebar.searchPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:S,onCompositionstart:f(b),onCompositionend:f(A)},null,8,["modelValue","placeholder","onCompositionstart","onCompositionend"]),U(f(gn),{text:f(n)("sidebar.searchClear")},{default:de(()=>[C("button",{type:"button",class:Fe(["search-clear",{"is-on":r.value.length>0}]),tabindex:"-1","aria-label":f(n)("sidebar.searchClear"),onClick:k},[U(f(ve),{name:"close",size:"sm"})],10,Xce)]),_:1},8,["text"])]),C("div",{ref_key:"listRef",ref:a,class:"sd-list",role:"listbox"},[u.value.length>0?(v(!0),E(Ee,{key:0},pt(u.value,(L,M)=>(v(),E(Ee,{key:L.key},[L.section?(v(),E("div",ede,[C("span",null,D(L.section.label),1),C("span",tde,D(L.section.count),1)])):X("",!0),L.kind==="workspace"?(v(),E("button",{key:1,class:Fe(["sd-row sd-row-ws",{on:M===c.value}]),role:"option","aria-selected":M===c.value,onClick:N=>m(L.hit.workspace.id),onMousemove:N=>c.value=M},[U(f(ve),{class:"sd-folder",name:"folder-closed",size:"sm"}),C("span",{class:"sd-ws-name",innerHTML:f(K1)(L.hit.workspace.name,L.hit.inName?r.value:"")},null,8,ide),C("span",{class:"sd-ws-path",innerHTML:f(K1)(L.hit.workspace.shortPath,L.hit.inPath?r.value:"")},null,8,ode)],42,nde)):(v(),E("button",{key:2,class:Fe(["sd-row",{on:M===c.value,active:L.hit.session.id===e.activeId}]),role:"option","aria-selected":M===c.value,onClick:N=>g(L.hit.session.id),onMousemove:N=>c.value=M},[C("span",rde,[C("span",{class:"sd-title",innerHTML:f(K1)(L.hit.session.title,L.hit.inTitle?r.value:"")},null,8,lde),C("span",ade,D(L.hit.session.time),1)]),C("span",ude,[C("span",{class:"sd-meta-ws",innerHTML:f(K1)(L.hit.session.workspaceName??L.hit.session.workspaceId??"",L.hit.inWorkspace?r.value:"")},null,8,cde),L.hit.snippetText?(v(),E(Ee,{key:0},[_[3]||(_[3]=C("span",{class:"sd-meta-sep","aria-hidden":"true"},"·",-1)),C("span",{class:"sd-meta-snippet",innerHTML:f(K1)(L.hit.snippetText,r.value)},null,8,dde)],64)):X("",!0)])],42,sde))],64))),128)):(v(),E("div",fde,[U(f(WQ),{title:r.value.trim()?f(n)("sidebar.searchNoResults"):f(n)("sidebar.searchEmpty")},{icon:de(()=>[U(f(ve),{name:"search",size:"lg"})]),_:1},8,["title"])]))],512),C("div",hde,[C("span",pde,[U(f(ku),{keys:["↑","↓"]}),$e(D(f(n)("sidebar.searchHintSelect")),1)]),_[4]||(_[4]=C("span",{class:"sd-dot"},"·",-1)),C("span",gde,[U(f(ku),{keys:["Enter"]}),$e(D(f(n)("sidebar.searchHintOpen")),1)]),_[5]||(_[5]=C("span",{class:"sd-dot"},"·",-1)),C("span",mde,[U(f(ku),{keys:["Esc"]}),$e(D(f(n)("sidebar.searchHintClose")),1)])])])]),_:1},8,["open","title"]))}}),bde=kt(kde,[["__scopeId","data-v-5bf43f78"]]),Ade=640,Cde=`(max-width: ${Ade}px)`;function rg(){const e=K(!1);if(typeof window>"u"||typeof window.matchMedia!="function")return e;const t=window.matchMedia(Cde);e.value=t.matches;const n=i=>{e.value=i.matches};return typeof t.addEventListener=="function"?(t.addEventListener("change",n),_n(()=>t.removeEventListener("change",n))):typeof t.addListener=="function"&&(t.addListener(n),_n(()=>t.removeListener(n))),e}const b$=K(typeof window>"u"?0:window.innerWidth);let Lm=0,I2=!1;function c8(){b$.value=window.innerWidth}function wde(){I2||typeof window>"u"||(window.addEventListener("resize",c8),I2=!0,c8())}function xde(){!I2||typeof window>"u"||(window.removeEventListener("resize",c8),I2=!1)}function A$(e,t,n){return Math.max(t,e-n)}function d8(e,t,n){return Math.min(n,Math.max(t,e))}function C$(){return cn(()=>{Lm+=1,wde()}),Hn(()=>{Lm=Math.max(0,Lm-1),Lm===0&&xde()}),{viewportWidth:b$}}const Sde=24;function _de(e){const t=K(null),n=K(!0);let i=null,o=null,s=null,r=0,l=0,a=!1,u=0;function c(){const k=t.value;k&&(k.scrollTop=Math.max(k.scrollTop,r))}function d(){const w=t.value?.firstElementChild??null;w!==s&&(s&&i?.unobserve(s),s=w,w&&i?.observe(w))}function h(){const k=t.value;!k||a||(n.value=r-k.scrollTop-l<Sde)}function p(k){k!==u||!a||(a=!1,h())}function g(){n.value=!1,a=!0;const k=++u;if(typeof requestAnimationFrame!="function"){queueMicrotask(()=>p(k));return}requestAnimationFrame(()=>{requestAnimationFrame(()=>p(k))})}function m(){const k=t.value;k&&(i?.disconnect(),o?.disconnect(),s=null,a=!1,u++,r=0,l=0,typeof ResizeObserver=="function"?(i=new ResizeObserver(()=>{const w=t.value;if(!w)return;const{scrollHeight:y,clientHeight:b}=w,A=y>r+1,T=b<l-1;if(r=y,l=b,a){p(u);return}n.value&&(A||T)&&c()}),i.observe(k),d()):(r=k.scrollHeight,l=k.clientHeight,c()),typeof MutationObserver=="function"&&(o=new MutationObserver(d),o.observe(k,{childList:!0})))}return Pe(e,()=>{n.value=!0,dt(m)}),Pe(t,()=>void dt(m)),cn(()=>void dt(m)),_n(()=>{u++,i?.disconnect(),o?.disconnect()}),{scroller:t,following:n,onScroll:h,pinScroll:g}}function Mde(e){try{const t=gs(e);if(t===null)return null;const n=Number(t);return Number.isFinite(n)?n:null}catch{return null}}function Ide(e,t){try{is(e,String(t))}catch{}}function w$(e){const{storageKey:t,defaultWidth:n,min:i,max:o,reverse:s=!1,axis:r="x",applyLive:l,persist:a}=e;function u(z){return Number.isFinite(z)?Math.min(Yl(o),Math.max(Yl(i),Math.round(z))):n}const c=K(u(Mde(t)??n)),d=K(!1);function h(z){const H=z<=Yl(i),O=z>=Yl(o),R=r==="x"?"col-resize":"row-resize";if(H&&O)return R;const[j,$]=r==="x"?["e-resize","w-resize"]:["s-resize","n-resize"];return O?s?j:$:H?s?$:j:R}const p=K(null),g=F(()=>h(p.value??c.value));function m(z){typeof document>"u"||(document.body.style.cursor=h(z))}function k(z){a&&!a()||Ide(t,z)}function w(z){const H=u(z);c.value=H,k(H)}Pe(()=>Yl(o),z=>{!d.value&&c.value>z&&w(z)}),Pe(()=>Yl(i),z=>{!d.value&&c.value<z&&w(z)});let y=0,b=0,A=null,T=-1,S=0,x=0,_=0;function L(){if(x=0,!d.value)return;const z=S-y;_=u(b+(s?-z:z)),p.value=_,m(_),l?l(_):c.value=_}function M(z){if(d.value&&(S=r==="x"?z.clientX:z.clientY,x===0)){if(typeof requestAnimationFrame!="function"){L();return}x=requestAnimationFrame(L)}}function N(){if(d.value){if(x!==0&&(cancelAnimationFrame(x),L()),d.value=!1,_!==b?l?w(_):k(c.value):c.value=u(c.value),p.value=null,typeof document<"u"&&(document.body.style.userSelect="",document.body.style.cursor=""),A){try{A.releasePointerCapture(T)}catch{}A.removeEventListener("pointermove",M),A.removeEventListener("pointerup",N),A.removeEventListener("pointercancel",N)}A=null,T=-1}}function I(z){z.preventDefault(),d.value=!0,y=r==="x"?z.clientX:z.clientY,b=u(c.value),_=b,A=z.currentTarget,T=z.pointerId,typeof document<"u"&&(document.body.style.userSelect="none"),m(b);try{A.setPointerCapture(T)}catch{}A.addEventListener("pointermove",M),A.addEventListener("pointerup",N),A.addEventListener("pointercancel",N)}return Hn(N),{width:c,dragging:d,cursor:g,clamp:u,setWidth:w,onPointerDown:I}}function Ede(e,t,n,i,o){if(t<=n+1)return null;const s=n-i*2;if(s<=0)return null;const r=Math.min(s,Math.max(o,n/t*s)),l=t-n;return{top:i+e/l*(s-r),height:r}}const Tde=900;function b3(e,t,n){const i=Number.parseFloat(getComputedStyle(e).getPropertyValue(t));return Number.isFinite(i)?i:n}function x$(e){const t=K(null),n=K(!1),i=K(!1),o=K(!1),s=K(!1),r=F(()=>t.value!==null&&(n.value||i.value||o.value||s.value));function l(){const k=e.value;if(!k){t.value=null;return}const w=Ede(k.scrollTop,k.scrollHeight,k.clientHeight,b3(k,"--overlay-scrollbar-track-inset",0),b3(k,"--overlay-scrollbar-thumb-min",24)),y=w===null?null:{top:k.offsetTop+w.top,height:w.height},b=t.value;b!==null&&y!==null&&b.top===y.top&&b.height===y.height||(t.value=y)}let a=null;function u(){o.value=!0,a&&clearTimeout(a),a=setTimeout(()=>{o.value=!1,a=null},Tde)}let c=null;function d(k){const w=e.value,y=t.value;if(!w||!y)return;k.preventDefault(),c?.();const b=k.pointerId;k.target.setPointerCapture?.(k.pointerId);const A=b3(w,"--overlay-scrollbar-track-inset",0),T=w.clientHeight-A*2-y.height,S=w.scrollHeight-w.clientHeight,x=k.clientY,_=w.scrollTop;s.value=!0;const L=I=>{I.pointerId!==b||T<=0||(w.scrollTop=_+(I.clientY-x)/T*S)},M=I=>{I.pointerId===b&&N()},N=()=>{window.removeEventListener("pointerup",M),window.removeEventListener("pointermove",L),window.removeEventListener("pointercancel",M),s.value=!1,c===N&&(c=null)};c=N,window.addEventListener("pointermove",L),window.addEventListener("pointerup",M),window.addEventListener("pointercancel",M)}function h(){n.value=!0}function p(){n.value=!1}function g(){i.value=!0}function m(){i.value=!1}return Hn(()=>{a&&clearTimeout(a),c?.()}),{thumb:t,thumbVisible:r,scrolling:o,update:l,markScrolling:u,onThumbPointerDown:d,onListMouseEnter:h,onListMouseLeave:p,onThumbMouseEnter:g,onThumbMouseLeave:m}}const na=K(null),Lh=K(!1),Lde=F(()=>na.value!==null);function z6(e){const t=na.value;!t||Lh.value||(na.value=null,t.resolve(e))}async function Nde(){const e=na.value;if(!(!e||Lh.value)){if(!e.action){z6(!0);return}Lh.value=!0;try{await e.action(),na.value===e&&(na.value=null),e.resolve(!0)}catch(t){na.value===e&&(na.value=null),e.reject(t)}finally{Lh.value=!1}}}function Fde(e){return Lh.value?Promise.resolve(!1):(na.value&&z6(!1),new Promise((t,n)=>{na.value={...e,resolve:t,reject:n}}))}function Vc(){return{current:na,busy:Lh,isConfirmOpen:Lde,confirm:Fde,settle:z6,runAction:Nde}}function Dde(e){const{sessionId:t}=e;function n(a){return gs(h_(a))??""}function i(a,u){const c=h_(a);u?is(c,u):_r(c)}const o=K(n(t())),s=K(null);Pe(o,a=>{i(t(),a)}),Pe(t,(a,u)=>{a!==u&&(i(u,o.value),o.value=n(a))});function r(a){o.value=a,dt(()=>{const u=s.value;if(!u)return;u.focus();const c=a.length;u.setSelectionRange(c,c)})}function l(){i(t(),"")}return{text:o,editorRef:s,loadForEdit:r,clearDraft:l}}function Bde(e){return e?e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable===!0:!1}function $de(e){const{sessionId:t,mobile:n,starting:i,dockedComposer:o,emptyComposer:s}=e,r=K(!1);Pe(t,()=>{n()||(r.value=!0)}),Pe([r,o,s,i],()=>{if(!r.value)return;const l=o.value??s.value;if(!l)return;const a=typeof document<"u"?document.activeElement:null;if(Bde(a)){r.value=!1;return}l.focus(),(typeof document>"u"||document.activeElement!==a)&&(r.value=!1)},{flush:"post"})}const E2=100;function Rde(e){const t=Kc(un.inputHistory);if(Array.isArray(t)){const n=t.filter(s=>typeof s=="string"&&s.length>0);if(!e||n.length===0)return{};const i=n.length>E2?n.slice(-E2):n,o={[e]:i};return Lu(un.inputHistory,o),o}return t&&typeof t=="object"?t:{}}function zde(e){const{text:t,editorRef:n,sessionId:i}=e,o=K(Rde(i())),s=F(()=>o.value[i()??""]??[]);let r=-1,l="";function a(k){const w=i();if(r=-1,!w)return;const y=k.trim();if(!y)return;const b=o.value[w]??[];if(b.at(-1)===y)return;const A=[...b,y],T=A.length>E2?A.slice(-E2):A;o.value={...o.value,[w]:T},Lu(un.inputHistory,o.value)}function u(){const k=n.value;return k?(k.selectionStart??0)===0:!1}function c(k){t.value=k,dt(()=>{const w=n.value;if(!w)return;const y=k.length;w.setSelectionRange(y,y)})}function d(){const k=s.value;if(k.length!==0){if(r===-1)l=t.value,r=k.length-1;else if(r>0)r-=1;else return;c(k[r])}}function h(){if(r===-1)return;const k=s.value;r<k.length-1?(r+=1,c(k[r])):(r=-1,c(l))}function p(){r=-1}function g(){return r!==-1}function m(){return s.value.length>0}return Pe(i,()=>{r=-1}),{push:a,caretAtTextStart:u,recallOlder:d,recallNewer:h,resetBrowsing:p,isBrowsing:g,hasHistory:m}}function Ode(e){const{text:t,editorRef:n,skills:i,emitCommand:o,historyPush:s,clearDraft:r,resolveDesc:l}=e,a=K(!1),u=K([]),c=K([]),d=K(0);function h(){const g=t.value;if(/^\/\S*$/.test(g)){const m=ace(g,c$(i()),l);u.value=m.map(k=>k.item),c.value=m.map(k=>k.ranges),d.value=0,a.value=!0}else a.value=!1}function p(g){if(a.value=!1,g.acceptsInput){t.value=`${g.name} `,dt(()=>{const m=n.value;if(!m)return;const k=t.value.length;m.setSelectionRange(k,k),m.focus()});return}t.value="",r?.(),s(g.name),o(g.name)}return{open:a,items:u,ranges:c,active:d,update:h,select:p}}function Pde(e){const t=e.toLowerCase(),n=[];let i=0;for(const o of e){const s=o.toLowerCase().length;for(let r=0;r<s;r++)n.push(i+Math.min(r,o.length-1));i+=o.length}return{lower:t,map:n}}function S$(e,t){const n=[];let i=0;for(const o of t){const s=e.indexOf(o,i);if(s<0)return null;for(let r=0;r<o.length;r++)n.push(s+r);i=s+o.length}return n}function jde(e,t){return e===t?4:e.startsWith(t)?3:e.includes(t)?2:[...t].length>=3&&S$(e,t)!==null?1:0}function b_(e,t){const n=t.toLowerCase(),i=[];for(const o of e){const{lower:s,map:r}=Pde(o.name),l=jde(s,n);if(l===0)continue;const a=l>=2?Array.from({length:n.length},(u,c)=>s.indexOf(n)+c):S$(s,n);i.push({skill:o,tier:l,positions:a.map(u=>r[u])})}return i}function Hde(e,t){return t.includes("/")?!0:e.name.toLowerCase().includes(t)}function A_(e){return e.kind==="directory"||e.path.endsWith("/")?"folder":"file"}function Wde(e){const{text:t,editorRef:n,searchFiles:i,skills:o,insertMention:s}=e,r=K(!1),l=K([]),a=K(""),u=K(!1),c=K([]),d=K(0),h=K(!1),p=F(()=>{const O=a.value,R=[],j=[];for(const ae of l.value){const V={kind:A_(ae),file:ae};(Hde(ae,O)?R:j).push(V)}const $=[],W=[],P=[],Z=[];for(const{skill:ae,tier:V,positions:Y}of c.value){const oe={kind:"skill",skill:ae,matchPositions:Y};V===4?$.push(oe):V===3?W.push(oe):V===2?P.push(oe):Z.push(oe)}return[...$,...W,...R,...P,...Z,...j]});let g=0,m=null,k=!1;function w(){const O=t.value,R=n.value?.selectionStart??O.length,j=n.value?.inlineTextRunStart?.()??0;let $=R-1;for(;$>=j&&!/\s/.test(O[$]);)$--;$++,$=Math.max($,j);const W=O.slice($,R);return!W.startsWith("@")&&!W.startsWith("@")?null:{token:W.slice(1),start:$,end:R}}function y(O){return O.kind==="skill"?`skill:${O.skill.name}`:`${O.kind}:${O.file.path}`}let b=!1,A=!1;Pe(d,()=>{A||(b=!0)},{flush:"sync"});function T(O){A=!0,d.value=O,A=!1}function S(O){b=!0,T(O)}function x(O){if(O===null||!b){T(0);return}const R=p.value.findIndex(j=>y(j)===O);T(R===-1?0:R)}function _(O,R){const j=p.value[d.value],$=j?y(j):null;u.value=!1,a.value=R.toLowerCase(),l.value=O,x($)}async function L(O,R){const j=++g,$=performance.now();h.value=!0,r.value=!0;const W=()=>{const P=w();return j===g&&P!==null&&P.token===R&&r.value};try{const P=await O(R);W()&&_(P,R)}catch{W()&&_([],R)}finally{W()&&(console.debug(`[mention] search "${R}" → ${l.value.length} items in ${Math.round(performance.now()-$)}ms`),h.value=!1)}}function M(){const O=w(),R=i();if(k=!1,b=!1,!O){m=null,r.value=!1,h.value=!1,u.value=!1;return}const j=O.token;if(j!==m&&(l.value.length>0&&(u.value=!0),g+=1),m=j,c.value=j.length>0?b_(o?.()??[],j):[],T(0),!R){l.value=[],h.value=!1,u.value=!1,r.value=c.value.length>0;return}if(j.length===0){L(R,j);return}c.value.length>0&&(r.value=!0),L(R,j)}function N(){const O=w();if(!O)return;const R=p.value[d.value],j=R?y(R):null;c.value=O.token.length>0?b_(o?.()??[],O.token):[],x(j)}Pe(()=>o?.(),()=>{k||N()});function I(O){if(O.kind==="skill")return{kind:"skill",name:O.skill.name};const R=O.file.path;return{kind:A_(O.file),path:R,name:O.file.name||R.split("/").filter(Boolean).pop()||R}}function z(){k=!0,b=!1,r.value=!1,h.value=!1,u.value=!1,l.value=[],m=null,g+=1}function H(O){const R=w();if(!R||O.kind!=="skill"&&u.value)return;if(z(),s){s(I(O),{start:R.start,end:R.end});return}if(O.kind==="skill")return;const j=t.value;t.value=j.slice(0,R.start)+O.file.path+j.slice(R.end),dt(()=>{const $=n.value;if(!$)return;const W=R.start+O.file.path.length;$.setSelectionRange(W,W),$.focus()})}return{open:r,items:p,fileItems:l,fileStale:u,skillItems:c,active:d,loading:h,update:M,close:z,select:H,navigate:S,getToken:w}}const qde="kimi-web.file-preview-width",sh=320;function Ude({client:e,sideWidth:t,detailTarget:n,closeFilePreview:i}){const{viewportWidth:o}=C$(),s=F(()=>Math.max(0,o.value-t.value)),r=F(()=>A$(s.value,sh,sh));function l(se){return d8(Math.round(se),sh,r.value)}function a(){return l(s.value/2)}const u=F(()=>a()),c=K(u.value),d=F(()=>d8(c.value,sh,r.value)),h=K(null),p=F(()=>{const se=h.value;if(!se)return null;const re=e.turns.value.find(G=>G.id===se.turnId);return re?.role==="compaction"&&re.text?re.text:null}),g=F(()=>p.value!==null);function m(se){if(h.value?.turnId===se.turnId){h.value=null,n.value==="compaction"&&(n.value=null);return}n.value="compaction",h.value=se}function k(){h.value=null,n.value==="compaction"&&(n.value=null)}const w=K(null),y=F(()=>{const se=w.value;if(!se)return{entry:void 0,version:0};const re=e.auxiliaryTranscripts.getEntry(se.sessionId,se.subagentId);return{entry:re,version:re?.version.value??0}});function b(se){const re=e.turns.value.flatMap(G=>G.tools??[]).find(G=>G.agentId===se);if(!re)return{};try{const G=JSON.parse(re.arg);return{name:typeof G.description=="string"?G.description:void 0,subagentType:typeof G.subagent_type=="string"?G.subagent_type:void 0,status:re.status,outputLines:re.output}}catch{return{}}}const A=F(()=>{const se=w.value;if(!se)return null;const re=e.activeAppTasks.value.find(Ct=>Ct.agentId===se.subagentId||Ct.id===se.subagentId||Ct.backgroundTaskId===se.subagentId);if(re)return mse(re,e.findBashCommandForTask(re));const G=y.value.entry?.channel,le=G?.agents.find(Ct=>Ct.agentId===se.subagentId),ge=G?.refreshError??!1,ke=G===void 0||G.loading,Ie=G?.snapshot.meta.activity==="turn",Oe=b(se.subagentId),we=G?.snapshot.items.findLast(Ct=>Ct.kind==="turn"),Be=we?.kind==="turn"&&we.state==="cancelled",tt=we?.kind==="turn"&&we.state==="failed"||Oe.status==="error",ut=Ie?"working":Be?"cancelled":tt?"failed":ke?"queued":ge&&Oe.status===void 0?"failed":"completed",_t=Ie?"running":Be?"cancelled":tt?"failed":ke?"running":ge&&Oe.status===void 0?"failed":"completed";return{id:se.subagentId,name:le?.label??Oe.name??se.subagentId,subagentType:Oe.subagentType??(le?.type==="sub"?"subagent":le?.type),phase:ut,status:_t,outputLines:Oe.outputLines}}),T=F(()=>{const se=y.value.entry;if(!se)return[];const re=w.value,G=se.channel.agents.find(le=>le.agentId===re?.subagentId);return Ise(se.channel.snapshot,e.getFileUrl,G,{sessionId:re?.sessionId,getSessionMediaUrl:e.getSessionMediaUrl})}),S=F(()=>y.value.entry?.channel.loading??!1),x=F(()=>y.value.entry?.channel.refreshError??!1),_=F(()=>y.value.entry?.channel.loadingOlder??!1),L=F(()=>y.value.entry?.channel.loadOlderError??!1),M=F(()=>y.value.entry?.channel.snapshot.hasMoreOlder??!1),N=F(()=>y.value.entry?.channel.snapshot.meta.activity==="turn"),I=F(()=>A.value!==null);function z(se){const re=e.activeAppTasks.value.find(G=>G.agentId===se||G.id===se||G.backgroundTaskId===se);return!re||re.kind==="subagent"&&re.agentId===se}function H(se){return e.activeAppTasks.value.find(G=>G.agentId===se||G.id===se||G.backgroundTaskId===se)?.agentId??se}function O(se){const re=e.activeSessionId.value;if(!se||!re)return;const G=H(se);if(n.value==="agent"&&w.value?.sessionId===re&&w.value.subagentId===G){R();return}const le=w.value;le&&le.subagentId!==G&&e.auxiliaryTranscripts.deactivate(le.sessionId,le.subagentId),w.value={sessionId:re,subagentId:G},n.value="agent",z(G)&&e.auxiliaryTranscripts.activate(re,G)}Pe(()=>e.activeAppTasks.value,se=>{const re=w.value;if(!re)return;const G=se.find(le=>le.backgroundTaskId===re.subagentId&&le.agentId!==void 0);!G||G.agentId===re.subagentId||(e.auxiliaryTranscripts.deactivate(re.sessionId,re.subagentId),w.value={sessionId:re.sessionId,subagentId:G.agentId},n.value==="agent"&&e.auxiliaryTranscripts.activate(re.sessionId,G.agentId))});function R(){const se=w.value;se&&e.auxiliaryTranscripts.deactivate(se.sessionId,se.subagentId),w.value=null,n.value==="agent"&&(n.value=null)}Pe(n,(se,re)=>{if(re!=="agent"||se==="agent")return;const G=w.value;G&&e.auxiliaryTranscripts.deactivate(G.sessionId,G.subagentId)});function j(){const se=y.value.entry;se&&se.channel.loadOlder().catch(()=>{})}const $=K("list"),W=K(null);function P(){if(n.value==="diff"){Z();return}n.value="diff",$.value="list",W.value=null,e.loadGitStatus(e.activeSessionId.value)}function Z(){n.value==="diff"&&(n.value=null),$.value="list",W.value=null,e.clearFileDiff()}async function ae(se){$.value="detail",W.value=se,await e.loadFileDiff(se)}const V=ha(null);function Y(se){if(V.value===se&&n.value==="turn-diff"){oe();return}V.value=se,n.value="turn-diff"}function oe(){V.value=null,n.value==="turn-diff"&&(n.value=null)}async function q(se){if(!e.activeSessionId.value&&e.activeWorkspaceId.value){const re=await e.startSessionAndOpenSideChat(e.activeWorkspaceId.value,se);return n.value="btw",re}return await e.openSideChat(se),n.value="btw",null}function ne(){e.closeSideChat(),n.value==="btw"&&(n.value=null)}function ie(){n.value==="btw"&&(n.value=null)}const pe=F(()=>e.sideChatVisible.value),Ne=F(()=>n.value!==null&&(n.value!=="compaction"||g.value)&&(n.value!=="agent"||I.value)&&(n.value!=="btw"||pe.value)),te=K(!1),be=K({});function Q(){switch(n.value){case"compaction":return h.value?{kind:"compaction",...h.value}:null;case"agent":return w.value?{kind:"agent",...w.value}:null;case"btw":return{kind:"btw"};default:return null}}function ue(se){if(se)switch(se.kind){case"compaction":h.value={turnId:se.turnId},n.value="compaction";break;case"agent":if(e.activeSessionId.value){const re=H(se.subagentId);w.value={sessionId:e.activeSessionId.value,subagentId:re},n.value="agent",z(re)&&e.auxiliaryTranscripts.activate(e.activeSessionId.value,re)}break;case"btw":e.sideChatVisible.value&&(n.value="btw");break}}function Ae(){return n.value==="compaction"&&g.value?(k(),!0):n.value==="agent"&&I.value?(R(),!0):n.value==="file"?(i(),!0):n.value==="diff"?(Z(),!0):n.value==="turn-diff"?(oe(),!0):n.value==="btw"?(ne(),!0):!1}return Pe(e.activeSessionId,(se,re)=>{if(re){const G=Q();G?be.value[re]=G:delete be.value[re]}i(),k(),R(),Z(),oe(),ie(),se&&ue(be.value[se])}),{PREVIEW_WIDTH_KEY:qde,PREVIEW_MIN:sh,previewDefaultWidth:u,previewMax:r,previewWidth:c,previewPanelWidth:d,compactionPanelText:p,compactionPanelVisible:g,openCompactionPanel:m,closeCompactionPanel:k,agentPanelMember:A,agentPanelTurns:T,agentPanelLoading:S,agentPanelLoadError:x,agentPanelLoadingMore:_,agentPanelLoadMoreError:L,agentPanelHasMore:M,agentPanelRunning:N,agentPanelVisible:I,openAgentPanel:O,closeAgentPanel:R,loadOlderAgentMessages:j,detailDiffMode:$,detailDiffPath:W,openDiffDetail:P,closeDiffDetail:Z,selectDiffFile:ae,turnDiffChange:V,openTurnDiff:Y,closeTurnDiff:oe,btwVisible:pe,openSideChatTab:q,closeSideChat:ne,hideSideChatPanel:ie,sidePanelVisible:Ne,panelDragging:te,closeOpenSidePanel:Ae}}const Kde=un.sidebarWidth,C_=un.sidebarCollapsed,w_=270,A3=220,Vde=480,Zde=320;function Gde(e={}){const{viewportWidth:t}=C$(),n=K(w_),i=K(!1),o=K(!1),s=F(()=>{const c=Zde+(Yl(e.previewOpen)?sh:0);return Math.min(Vde,A$(t.value,A3,c))}),r=F(()=>d8(n.value,A3,s.value));function l(){try{i.value=gs(C_)==="true"}catch{i.value=!1}}function a(){try{is(C_,String(i.value))}catch{}}function u(){i.value=!i.value,a()}return{SIDEBAR_WIDTH_KEY:Kde,SIDEBAR_DEFAULT:w_,SIDEBAR_MIN:A3,sidebarMax:s,sessionColWidth:n,sidebarCollapsed:i,sidebarDragging:o,sideWidth:r,loadSidebarCollapsed:l,toggleSidebarCollapse:u}}const Qde=40409;function x_(e){return ko(e)&&e.code===Qde}function S_(e){return e.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(e)||e.startsWith("\\\\")}function __(e){if(e.startsWith("\\\\"))return e;const t=/^[a-zA-Z]:/.test(e)?e.slice(0,2):"",n=[];for(const i of e.slice(t.length).split(/[\\/]+/))if(!(!i||i===".")){if(i===".."){n.pop();continue}n.push(i)}return t?`${t}/${n.join("/")}`:`/${n.join("/")}`}function Yde({client:e,detailTarget:t,t:n}){const i=K(null),o=K(null),s=K(!1),r=K(null),l=K(null);let a=0;const u=F(()=>{const A=l.value;return A?e.getFileDownloadUrl(A):null}),c=F(()=>i.value!==null&&l.value!==null);function d(A){return A.length>1?A.replace(/\/+$/,""):A}function h(A){const T=d9(A,e.status.value.cwd);return T===null||T.split(/[\\/]+/).includes("..")?null:p(T)||null}function p(A){const T=[];for(const S of A.split(/[\\/]+/))if(!(!S||S===".")){if(S===".."){T.pop();continue}T.push(S)}return T.join("/")}function g(A){const T=A.trim();if(!T)return{error:n("filePreview.errors.emptyPath")};if(/^[a-z][a-z0-9+.-]*:\/\//i.test(T))return{error:n("filePreview.errors.unsupportedPath")};if(T.startsWith("~"))return{error:n("filePreview.errors.outsideWorkspace")};const S=d(e.status.value.cwd);if(T.startsWith("/")){if(!S||T!==S&&!T.startsWith(`${S}/`))return{error:n("filePreview.errors.outsideWorkspace")};const _=T===S?"":T.slice(S.length+1);if(_.split(/[\\/]+/).includes(".."))return{error:n("filePreview.errors.outsideWorkspace")};const L=p(_);return L?{path:L}:{error:n("filePreview.errors.isDirectory")}}if(T.split(/[\\/]+/).includes(".."))return{error:n("filePreview.errors.outsideWorkspace")};const x=p(T);return x?{path:x}:{error:n("filePreview.errors.emptyPath")}}async function m(A){const T=i.value;if(t.value==="file"&&T&&T.path===A.path&&T.line===A.line&&(T.content??"")===(A.content??"")){w();return}const S=++a;if(t.value="file",o.value=null,r.value=null,s.value=!0,i.value=A,l.value=null,typeof A.content=="string"){s.value=!1,o.value={path:A.path,content:A.content,encoding:"utf-8",mime:"text/markdown",isBinary:!1,size:A.content.length};return}if(!S_(A.path)&&A.path.split(/[\\/]+/).includes("..")){const _=d(e.status.value.cwd);_&&(A={...A,path:__(`${_}/${A.path}`)})}if(S_(A.path)){A={...A,path:__(A.path)};const _=h(A.path);if(_!==null)A={...A,path:_};else{try{const L=await e.readHostFileContent(A.path);if(S!==a)return;l.value=null,o.value={path:A.path,content:L.content,encoding:L.encoding,mime:L.mime,isBinary:L.isBinary,size:L.size}}catch(L){if(S!==a)return;r.value=x_(L)?n("filePreview.errors.notFound"):RY(L)?n("filePreview.errors.tooLarge"):L instanceof Error?L.message:n("filePreview.errors.loadFailed")}finally{S===a&&(s.value=!1)}return}}const x=g(A.path);if("error"in x){s.value=!1,r.value=x.error;return}l.value=x.path;try{const _=await e.readFileContent(x.path);if(S!==a)return;_?o.value={..._,path:_.path||x.path}:r.value=n("filePreview.errors.loadFailed")}catch(_){if(S!==a)return;r.value=x_(_)?n("filePreview.errors.notFound"):_ instanceof Error?_.message:n("filePreview.errors.loadFailed")}finally{S===a&&(s.value=!1)}}function k(){a+=1,i.value=null,l.value=null,o.value=null,r.value=null,s.value=!1}function w(){k(),t.value==="file"&&(t.value=null)}Pe(t,(A,T)=>{T==="file"&&A!=="file"&&k()});function y(){const A=o.value?.path??i.value?.path;A&&e.openWorkspaceFile(A,i.value?.line)}function b(){const A=o.value?.path??i.value?.path;A&&e.revealWorkspaceFile(A)}return{previewTarget:i,previewFile:o,previewLoading:s,previewError:r,previewDownloadUrl:u,previewExternalActions:c,openFilePreview:m,closeFilePreview:w,openPreviewInEditor:y,revealPreviewFile:b}}function Jde(e){const t=e.replace(/[/\\]+$/,"");return t===""?e:t.split(/[/\\]/).pop()??t}function Xde(e,t){return e!==""?e:t?`${Jde(t)} | Kimi Code`:"Kimi Code"}function efe(e){return F(()=>Xde(Yl(e.webTitle),Yl(e.activeWorkspaceRoot)))}function tfe({running:e,title:t="Kimi Code"}){if(bf){Zk(()=>{typeof document<"u"&&(document.title=Yl(t))});return}const n=["◐","◓","◑","◒"],i=K(0);let o=null;function s(){o===null&&(i.value=0,o=setInterval(()=>{i.value=(i.value+1)%n.length},250))}function r(){o!==null&&(clearInterval(o),o=null),i.value=0}Pe(e,a=>{a?s():r()},{immediate:!0});const l=F(()=>`${e.value?`${n[i.value]} `:""}${Yl(t)}`);Zk(()=>{typeof document<"u"&&(document.title=l.value)}),_n(()=>{r()})}function nfe(e,t,n){return e==="idle"&&!t&&!n}function O6(...e){for(const t of e){const n=t?.trim();if(n)return n}return""}function ife(e,t){return{title:e("settings.notifyTitle"),body:O6(t,e("settings.notifyFallback"))}}function ofe(e,t,n){return{title:e("settings.notifyQuestionTitle"),body:O6(n,t,e("settings.notifyQuestionFallback"))}}function sfe(e,t,n){return{title:e("settings.notifyApprovalTitle"),body:O6(n,t,e("settings.notifyApprovalFallback"))}}function Nm(e){return{fileId:e.fileId,kind:e.kind,sessionId:e.kind==="file"?void 0:e.sessionId,name:e.name,mediaType:e.mediaType,size:e.size}}function P6(e,t){const n=t.kind==="file"?void 0:t.sessionId;return{kind:t.kind,url:n?e.getSessionMediaUrl(n,t.fileId):e.getFileUrl(t.fileId),fileId:t.fileId,sessionId:n,name:t.name,mediaType:t.mediaType,size:t.size}}function T2(e){const t=[];for(const n of e??[])n.kind==="video"?t.push({type:"video",source:n.sessionId?{kind:"sessionMedia",fileId:n.fileId}:{kind:"file",fileId:n.fileId}}):n.kind==="file"?t.push({type:"file",fileId:n.fileId,name:n.name??"",mediaType:n.mediaType||"application/octet-stream",size:n.size??0}):t.push({type:"image",source:n.sessionId?{kind:"sessionMedia",fileId:n.fileId}:{kind:"file",fileId:n.fileId}});return t}function rfe(e){const{api:t,uploadImage:n,sessionId:i,insertFolderPaths:o}=e,s=K({}),r=F(()=>s.value[i()??""]??[]),l=K(null),a=K(null),u=K(!1);let c=0;function d(){return`att_${++c}`}function h(Y,oe){const q=p_(Y),ne=[];for(const ie of oe)ie.uploading||ie.error||!ie.fileId||ne.push({fileId:ie.fileId,kind:ie.kind,name:ie.name,mediaType:ie.mediaType,size:ie.size,sessionId:ie.sessionId});ne.length===0?_r(q):Lu(q,ne)}let p=!1;function g(Y,oe){p||(s.value={...s.value,[Y]:oe},h(Y,oe))}function m(Y){if(s.value[Y]!==void 0)return;const oe=Kc(p_(Y));if(!Array.isArray(oe)||oe.length===0)return;const q=[];for(const ne of oe)!ne||typeof ne.fileId!="string"||ne.fileId===""||ne.kind!=="image"&&ne.kind!=="video"&&ne.kind!=="file"||q.push({fileId:ne.fileId,kind:ne.kind,name:typeof ne.name=="string"&&ne.name!==""?ne.name:ne.kind,mediaType:typeof ne.mediaType=="string"?ne.mediaType:void 0,size:typeof ne.size=="number"?ne.size:void 0,sessionId:typeof ne.sessionId=="string"?ne.sessionId:void 0});q.length!==0&&V(q.map(ne=>P6(t,ne)),Y,{append:!0})}function k(Y){if(Y.previewUrl!==void 0)try{URL.revokeObjectURL(Y.previewUrl)}catch{}}function w(Y){return Y.startsWith("image/")?"image":Y.startsWith("video/")?"video":"file"}function y(Y){return Y<1024*1024?"<1mb":Y<10*1024*1024?"1-10mb":Y<50*1024*1024?"10-50mb":"50mb+"}async function b(Y,oe){const q=n();if(!q)return;const ne=i()??"";if(Y.length!==0)for(const ie of Y){const pe=w(ie.type);y(ie.size),Math.min(Y.length,100);const Ne=d(),te=pe==="file"?void 0:URL.createObjectURL(ie),be={localId:Ne,name:ie.name,kind:pe,previewUrl:te,mediaType:ie.type||"application/octet-stream",size:ie.size,uploading:!0};g(ne,[...s.value[ne]??[],be]),q(ie,ie.name).then(Q=>{const ue=s.value[ne]??[];g(ne,ue.map(Ae=>Ae.localId===Ne?{...Ae,uploading:!1,fileId:Q?.fileId,mediaType:Q?.mediaType??Ae.mediaType,error:Q===null}:Ae))}).catch(()=>{const Q=s.value[ne]??[];g(ne,Q.map(ue=>ue.localId===Ne?{...ue,uploading:!1,error:!0}:ue))})}}function A(Y){const oe=i()??"",q=s.value[oe]??[],ne=q.find(ie=>ie.localId===Y);l.value?.localId===Y&&(l.value=null),ne&&k(ne),g(oe,q.filter(ie=>ie.localId!==Y))}function T(Y){l.value=Y}function S(){l.value=null}function x(){a.value?.click()}function _(Y){const oe=Y.target,q=Array.from(oe.files??[]);b(q),oe.value=""}function L(Y){const oe=Y.clipboardData;if(!oe)return;const{files:q,folderPaths:ne,hasFolders:ie}=Qre(oe);if(ne.length>0?(o?.(ne),Y.preventDefault()):ie&&Y.preventDefault(),!n()||q.length===0)return;const pe=q.map(Ne=>{if(Ne.name.includes("."))return Ne;const te=Ne.type.split("/")[1]??"png";return new File([Ne],`paste-${Date.now()}.${te}`,{type:Ne.type})});Y.preventDefault(),b(pe)}let M=0;function N(Y){!n()||!Array.from(Y.dataTransfer?.items??[]).some(q=>q.kind==="file")||(Y.preventDefault(),Y.stopPropagation(),u.value=!0)}function I(){u.value=!1}function z(Y){M=0,u.value=!1;const{files:oe,folderPaths:q}=Pb(Y);q.length>0&&(o?.(q),Y.preventDefault(),Y.stopPropagation()),n()&&(Y.preventDefault(),Y.stopPropagation(),b(oe))}function H(Y){return Array.from(Y.dataTransfer?.items??[]).some(oe=>oe.kind==="file")}function O(Y){!n()||!H(Y)||(Y.preventDefault(),M+=1,u.value=!0)}function R(Y){!n()||!H(Y)||Y.preventDefault()}function j(Y){!n()||!H(Y)||(M=Math.max(0,M-1),M===0&&(u.value=!1))}function $(Y){M=0,u.value=!1;const{files:oe,folderPaths:q}=Pb(Y);q.length>0&&(o?.(q),Y.preventDefault()),n()&&(Y.preventDefault(),b(oe))}function W(){const Y=i()??"";for(const oe of s.value[Y]??[])k(oe);g(Y,[])}function P(){l.value=null,W()}function Z(Y,oe,q){const ne=s.value[Y]??[];ne.some(ie=>ie.localId===oe)&&g(Y,ne.map(ie=>ie.localId===oe?{...ie,...q}:ie))}function ae(Y){return fetch(Y).then(oe=>{if(!oe.ok)throw new Error(`fetch failed: ${oe.status}`);return oe.blob()})}function V(Y,oe,q){const ne=oe??i()??"";if(q?.append!==!0){for(const ie of s.value[ne]??[])k(ie);g(ne,[])}for(const ie of Y){const pe=d(),Ne=/^data:/i.test(ie.url),te=/^blob:/i.test(ie.url),be=ie.name??ie.kind;if(ie.fileId){const Q={localId:pe,name:be,kind:ie.kind,previewUrl:ie.kind==="file"?void 0:ie.url,uploading:!1,fileId:ie.fileId,sessionId:ie.sessionId,mediaType:ie.mediaType,size:ie.size};g(ne,[...s.value[ne]??[],Q]),ie.kind==="image"&&!Ne&&!te&&(ie.sessionId?t.getSessionMediaBlob(ie.sessionId,ie.fileId):t.getFileBlob(ie.fileId)).then(Ae=>{if(p)return;const se=URL.createObjectURL(Ae);if(!(s.value[ne]??[]).some(G=>G.localId===pe)){URL.revokeObjectURL(se);return}Z(ne,pe,{previewUrl:se})}).catch(()=>{})}else{if(!ie.url)continue;const Q=n();if(!Q)continue;const ue={localId:pe,name:be,kind:ie.kind,previewUrl:ie.url,uploading:!0};g(ne,[...s.value[ne]??[],ue]),ae(ie.url).then(Ae=>{const se=be.includes(".")?be:`${be}.${Ae.type.split("/")[1]??"bin"}`;return Q(Ae,se)}).then(Ae=>{if(Ae===null){const se=s.value[ne]??[];g(ne,se.filter(re=>re.localId!==pe));return}Z(ne,pe,{uploading:!1,fileId:Ae.fileId})}).catch(()=>{const Ae=s.value[ne]??[];g(ne,Ae.filter(se=>se.localId!==pe))})}}}return Pe(i,()=>{l.value=null,m(i()??"")}),m(i()??""),cn(()=>{document.addEventListener("paste",L),document.addEventListener("dragenter",O),document.addEventListener("dragover",R),document.addEventListener("dragleave",j),document.addEventListener("drop",$)}),_n(()=>{p=!0,document.removeEventListener("paste",L),document.removeEventListener("dragenter",O),document.removeEventListener("dragover",R),document.removeEventListener("dragleave",j),document.removeEventListener("drop",$);for(const Y of Object.values(s.value))for(const oe of Y)k(oe);l.value=null}),{attachments:r,previewAttachment:l,fileInputRef:a,isDragOver:u,removeAttachment:A,openAttachmentPreview:T,closeAttachmentPreview:S,openFilePicker:x,handleFileInputChange:_,handleDragOver:N,handleDragLeave:I,handleDrop:z,clearAfterSubmit:W,clearAttachments:P,loadAttachments:V}}const lfe=3;function _$(e){const t=K("starting"),n=K(!1),i=K(null),o=K(0),s=K(!1);let r=null,l=null,a=null,u=0,c=0,d=!1,h,p=!1,g=null,m=!1;function k(){r&&(clearTimeout(r),r=null),l&&(clearInterval(l),l=null),a&&(clearTimeout(a),a=null)}function w(L){k(),b(),t.value="success",a=setTimeout(()=>{a=null,e.onSuccess?.()},L)}function y(){l&&clearInterval(l),l=setInterval(()=>{o.value>0?o.value--:(l&&clearInterval(l),l=null)},1e3)}function b(){g?.(),g=null}async function A(L){p=!0;try{const M=await e.onPollOAuthLogin();if(m||d)return;if(M===null){if(u+=1,u>=lfe){k(),b(),n.value=!0,t.value="error",e.autoOpen?.settle(!1,{keepNavigated:!0}),Date.now()-c;return}T(L);return}u=0,M.status==="authenticated"?w(1200):M.status==="expired"||M.status==="cancelled"?(k(),b(),t.value="expired",e.autoOpen?.settle(!1),Date.now()-c,M.status,void 0):T(L)}finally{p=!1}}function T(L){r&&clearTimeout(r),r=setTimeout(()=>{r=null,A(L)},L*1e3)}function S(){t.value!=="device-code"||i.value===null||d||p||(r&&(clearTimeout(r),r=null),A(i.value.interval))}async function x(L){L!==void 0&&(h=L),k(),b(),i.value=null,n.value=!1,u=0,d=!1,c=Date.now(),t.value="starting",s.value=!1,e.autoOpen?.onGesture?.();const M=await e.onStartOAuthLogin(h);if(m){M!==null&&M.status!=="authenticated"&&e.onCancelOAuthLogin();return}if(!M){t.value="error",e.autoOpen?.settle(!1);return}if(M.status==="authenticated"){e.autoOpen?.settle(!0),w(800);return}if(i.value={flowId:M.flowId,verificationUri:M.verificationUri,verificationUriComplete:M.verificationUriComplete,userCode:M.userCode,expiresIn:M.expiresIn,interval:M.interval},o.value=M.expiresIn,t.value="device-code",e.autoOpen){const N=e.autoOpen.openUrl(M.verificationUriComplete,M.flowId);if(N===!1)s.value=!0;else if(N instanceof Promise){const I=M.flowId;N.then(z=>{!z&&!m&&i.value?.flowId===I&&(s.value=!0)})}}y(),T(M.interval),g=e.authWake?.subscribe(S)??null}function _(){t.value!=="success"&&(k(),b(),e.autoOpen?.settle(!1),t.value==="device-code"&&!d&&(d=!0,e.onCancelOAuthLogin()))}return Y0()&&Bc(()=>{m=!0,_()}),{step:t,pollError:n,flow:i,secondsLeft:o,autoOpenBlocked:s,startFlow:x,cancelFlow:_,pollNow:S}}const afe={state:"idle"};function ufe(e){const t=K(afe),n=K(gs(un.updateSkippedVersion)),i=K(!1);if(typeof e?.getUpdateAutoDownload=="function"&&e.getUpdateAutoDownload().then(s=>{i.value=s}).catch(()=>{}),e!==void 0){let s=!1;e.onUpdateStatus(r=>{s=!0,t.value=r}),e.getUpdateStatus().then(r=>{s||(t.value=r)}).catch(()=>{})}const o=F(()=>{const s=t.value;return!(s.state==="idle"||s.state==="available"&&s.version!==void 0&&s.version===n.value)});return{status:t,visible:o,canCheck:typeof e?.checkForUpdates=="function",autoDownload:i,canToggleAutoDownload:typeof e?.getUpdateAutoDownload=="function"&&typeof e?.setUpdateAutoDownload=="function",setAutoDownload:(s,r)=>{i.value=s,typeof e?.setUpdateAutoDownload=="function"&&e.setUpdateAutoDownload(s).then(()=>{}).catch(()=>{})},skipVersion:()=>{const s=t.value.version;t.value.state==="available"&&s!==void 0&&(n.value=s,is(un.updateSkippedVersion,s))},check:async()=>{if(typeof e?.checkForUpdates!="function")return Promise.resolve({outcome:"unsupported"});const s=await e.checkForUpdates().catch(()=>({outcome:"error",message:"bridge call failed"}));return s.outcome==="available"&&s.version!==void 0&&s.version===n.value&&(n.value=null,_r(un.updateSkippedVersion)),s},download:()=>{e?.downloadUpdate().catch(()=>{})},install:()=>{e?.installUpdate().catch(()=>{})}}}let C3=null;function cfe(){return C3===null&&(C3=ufe(window.kimiDesktop)),C3}class dfe{transcript;sessionId;agentId;fetchPage;pageSize;onChange;onGap;refreshPromise=null;buffered=[];agents_=[];seq_;loadingOlder_=!1;loadOlderError_=!1;refreshError_=!1;constructor(t){this.sessionId=t.sessionId,this.agentId=t.agentId,this.transcript=new SJ(t.agentId),this.fetchPage=t.fetchPage,this.pageSize=t.pageSize??20,this.onChange=t.onChange,this.onGap=t.onGap}get snapshot(){return this.transcript.snapshot()}get seq(){return this.seq_}get agents(){return this.agents_}get loading(){return this.refreshPromise!==null}get loadingOlder(){return this.loadingOlder_}get loadOlderError(){return this.loadOlderError_}get refreshError(){return this.refreshError_}refresh(){if(this.refreshPromise!==null)return this.refreshPromise;this.refreshError_=!1;const t=this.fetchPage({pageSize:this.pageSize}).then(n=>this.applyPage(n,!0)).catch(n=>{throw this.refreshError_=!0,n}).finally(()=>{this.refreshPromise=null;const n=this.buffered;this.buffered=[];for(const i of n)this.applyOps(i.ops,i.seq);this.onChange?.()});return this.refreshPromise=t,this.onChange?.(),t}receiveReset(t,n){this.transcript.receive([{op:"reset",agentId:this.agentId,snapshot:t}]),n!==void 0&&(this.seq_=n),this.refreshError_=!1,this.onChange?.()}applyOps(t,n){if(this.refreshPromise!==null||this.loadingOlder_)return this.buffered.push({ops:t,...n!==void 0?{seq:n}:{}}),!1;if(n!==void 0&&this.seq_!==void 0){if(n<=this.seq_)return!0;if(n!==this.seq_+1)return this.onGap?.(),!1}const i=this.transcript.apply(t);return n!==void 0&&(this.seq_=n),i.gap!==void 0&&this.onGap?.(),i.accepted.length>0&&this.onChange?.(),i.gap===void 0}async loadOlder(){if(!this.snapshot.hasMoreOlder||this.loadingOlder_)return;const t=this.snapshot.items.find(n=>n.kind==="turn");if(t?.kind==="turn"){this.loadingOlder_=!0,this.loadOlderError_=!1,this.onChange?.();try{const n=await this.fetchPage({beforeTurn:t.turnId,pageSize:this.pageSize});this.applyPage(n,!1)}catch(n){throw this.loadOlderError_=!0,n}finally{this.loadingOlder_=!1;const n=this.buffered;this.buffered=[];for(const i of n)this.applyOps(i.ops,i.seq);this.onChange?.()}}}applyPage(t,n){this.agents_=t.agents;const i=this.snapshot,o=n?t:{...t,items:ffe(t.items,i.items),hasMoreOlder:t.hasMoreOlder};this.receiveReset(o,n?t.seq:void 0)}}function ffe(e,t){const n=new Set,i=[];for(const o of[...e,...t]){const s=o.kind==="turn"?o.turnId:o.kind==="marker"?o.markerId:o.refId;n.has(s)||(n.add(s),i.push(o))}return i}function hfe(e){const t=cN(new Map),n=new Map,i=new Map,o=new Set;let s=null,r=null;function l(){s!==null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(s),s=null),r!==null&&(clearTimeout(r),r=null);for(const b of o)b.version.value+=1;o.clear()}function a(b){o.add(b),!(s!==null||r!==null)&&(typeof requestAnimationFrame=="function"&&(s=requestAnimationFrame(l)),r=setTimeout(l,50))}function u(b,A){return`${b}\0${A}`}function c(b,A,T){const S=e.getEventConnection();S!==null&&(S.subscribeTranscript(b,A,T),i.set(b,A))}function d(b,A){const T=u(b,A),S=t.get(T);if(S!==void 0)return S;const x={channel:new dfe({sessionId:b,agentId:A,fetchPage:_=>e.api.getSessionTranscript(b,{..._,agentId:A}),onChange:()=>{a(x)},onGap:()=>{h(x)}}),version:K(0),baselineLoaded:!1,resumePromise:null};return t.set(T,x),x}async function h(b){if(b.resumePromise!==null)return b.resumePromise;const A=p(b).finally(()=>{b.resumePromise===A&&(b.resumePromise=null)});return b.resumePromise=A,A}async function p(b){const A=()=>t.get(u(b.channel.sessionId,b.channel.agentId))===b;try{await b.channel.refresh(),b.baselineLoaded=!0,A()&&n.get(b.channel.sessionId)===b.channel.agentId&&c(b.channel.sessionId,b.channel.agentId,b.channel.seq)}catch{A()&&n.get(b.channel.sessionId)===b.channel.agentId&&c(b.channel.sessionId,b.channel.agentId)}}function g(b,A){e.connectEventsIfNeeded(),n.set(b,A);const T=d(b,A);return T.baselineLoaded?c(b,A,T.channel.seq):h(T),T}function m(b,A){if(n.get(b)!==A)return;n.delete(b);const T=i.get(b);T!==void 0&&(e.getEventConnection()?.unsubscribeTranscript(b,[T]),i.delete(b));const S=u(b,A),x=t.get(S);x!==void 0&&(t.delete(S),o.delete(x))}function k(b,A,T,S){if(n.get(b)!==A)return;const x=d(b,A);x.channel.receiveReset(T,S),x.baselineLoaded=!0}function w(b,A,T,S){return n.get(b)!==A?!0:d(b,A).channel.applyOps(T,S)}function y(b){n.delete(b),i.delete(b)&&e.getEventConnection()?.unsubscribeTranscript(b);for(const[A,T]of t)T.channel.sessionId===b&&(t.delete(A),o.delete(T))}return{getEntry:(b,A)=>t.get(u(b,A)),activate:g,deactivate:m,receiveReset:k,applyOps:w,forgetSession:y}}async function pfe(){const e=await fetch("/v1/remote/devices",{credentials:"same-origin"});if(!e.ok)throw new Error(`rc devices fetch failed: ${e.status}`);const t=await e.json();return{devices:Array.isArray(t.devices)?t.devices:[],max_devices:typeof t.max_devices=="number"?t.max_devices:void 0}}const gfe=["aria-label","aria-expanded"],mfe={class:"rc-dev-name"},vfe={key:0,class:"rc-dev-state"},yfe={key:1,class:"rc-dev-state rc-dev-failed"},kfe={class:"rc-dev-caption"},bfe={class:"rc-dev-item-name"},Afe={class:"rc-dev-item-status"},Cfe={class:"rc-dev-item-check"},wfe={class:"rc-dev-caption"},xfe=["aria-current"],Sfe={class:"rc-dev-offline-row"},_fe={class:"rc-dev-item-name"},Mfe={class:"rc-dev-item-status"},Ife={class:"rc-dev-item-check"},Efe=Xe({__name:"RcDeviceSwitcher",setup(e){const{t}=zt(),n=rg(),i=Rle(window.location),o=Ple(window.location),s=K(null),r=K(void 0),l=K(!1),a=K(!1),u=F(()=>(s.value??[]).filter(L=>L.status==="online")),c=F(()=>(s.value??[]).filter(L=>L.status!=="online")),d=F(()=>s.value?.find(L=>L.device_id===o)?.platform??t("sidebar.rcSelectDevice"));let h=0;async function p(){const L=++h;s.value===null&&(l.value=!0);try{const M=await pfe();if(L!==h)return;s.value=M.devices,r.value=M.max_devices,a.value=!1}catch{if(L!==h)return;s.value===null&&(a.value=!0)}finally{L===h&&(l.value=!1)}g.value&&(await dt(),S())}cn(()=>{i&&p()});const g=K(!1),m=K({}),k=K(null),w=K(null);let y=null;function b(L){const M=L.target;M.closest(".rc-dev-menu")||M.closest(".rc-dev-trigger")||x()}function A(L){L.key==="Escape"&&(L.stopPropagation(),x())}async function T(){if(g.value){x();return}g.value=!0,document.addEventListener("mousedown",b),document.addEventListener("keydown",A,!0),window.addEventListener("resize",x),p(),await dt(),S();const L=w.value;L&&!n.value&&(y=new ResizeObserver(()=>S()),y.observe(L))}function S(){if(n.value)return;const L=w.value,M=k.value?.el;if(!L||!M)return;const N=L.getBoundingClientRect(),I=4,z=8,H=M.offsetHeight,O={left:`${Math.round(N.left)}px`,width:`${Math.round(N.width)}px`},R=window.innerHeight-N.bottom-I-z,j=N.top-I-z;H>R&&j>R?m.value={...O,top:"auto",bottom:`${Math.round(window.innerHeight-N.top+I)}px`,maxHeight:`${Math.round(j)}px`,transformOrigin:"bottom left","--menu-pop-shift":"2px"}:m.value={...O,top:`${Math.round(N.bottom+I)}px`,bottom:"auto",maxHeight:`${Math.round(R)}px`,transformOrigin:"top left","--menu-pop-shift":"-2px"}}function x(){g.value=!1,y?.disconnect(),y=null,document.removeEventListener("mousedown",b),document.removeEventListener("keydown",A,!0),window.removeEventListener("resize",x)}Hn(x);function _(L){L.device_id!==o&&window.location.assign(HB(Ole(L.device_id),window.location.search))}return(L,M)=>f(i)?(v(),E("div",{key:0,class:Fe(["rc-dev",{"rc-dev--mobile":f(n)}])},[C("button",{ref_key:"triggerRef",ref:w,class:"rc-dev-trigger",type:"button","aria-label":f(t)("sidebar.rcCurrentDevice",{name:d.value}),"aria-haspopup":"dialog","aria-expanded":g.value,onClick:wt(T,["stop"])},[U(f(ve),{name:"device-desktop",size:"sm"}),C("span",mfe,D(d.value),1),U(f(ve),{class:"rc-dev-chevron",name:"chevron-down",size:"sm"})],8,gfe),(v(),ce(Ds,{to:"body",disabled:f(n)},[U(fo,{name:"menu-pop"},{default:de(()=>[g.value?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:k,class:Fe(["rc-dev-menu",{"rc-dev-menu--mobile":f(n)}]),role:"dialog",style:Kt(f(n)?void 0:m.value),onClick:M[0]||(M[0]=wt(()=>{},["stop"]))},{default:de(()=>[l.value?(v(),E("div",vfe,[U(f(Oi),{size:"sm"})])):a.value?(v(),E("div",yfe,D(f(t)("sidebar.rcDevicesLoadFailed")),1)):(v(),E(Ee,{key:2},[u.value.length>0?(v(),E(Ee,{key:0},[C("div",kfe,D(f(t)("sidebar.rcConnectable")),1),(v(!0),E(Ee,null,pt(u.value,N=>(v(),ce(f(Ut),{key:N.device_id,role:"button",size:f(n)?"lg":"md",active:N.device_id===f(o),"aria-current":N.device_id===f(o)?"true":void 0,onClick:I=>_(N)},{default:de(()=>[U(f(ve),{name:"device-desktop",size:"sm"}),C("span",bfe,D(N.platform),1),C("span",Afe,[U(f(ml),{status:"ok"}),$e(D(f(t)("sidebar.rcOnline")),1)]),C("span",Cfe,[N.device_id===f(o)?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])]),_:2},1032,["size","active","aria-current","onClick"]))),128))],64)):X("",!0),c.value.length>0?(v(),E(Ee,{key:1},[C("div",wfe,D(f(t)("sidebar.rcUnavailable")),1),(v(!0),E(Ee,null,pt(c.value,N=>(v(),E("div",{key:N.device_id,class:Fe(["rc-dev-offline",{"is-current":N.device_id===f(o)}]),"aria-current":N.device_id===f(o)?"true":void 0},[C("div",Sfe,[U(f(ve),{name:"device-desktop",size:"sm"}),C("span",_fe,D(N.platform),1),C("span",Mfe,[U(f(ml)),$e(D(f(t)("sidebar.rcOffline")),1)]),C("span",Ife,[N.device_id===f(o)?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])])],10,xfe))),128))],64)):X("",!0)],64))]),_:1},8,["class","style"])):X("",!0)]),_:1})],8,["disabled"]))],2)):X("",!0)}}),M$=kt(Efe,[["__scopeId","data-v-4dd165fb"]]),Tfe=1e3,Lfe=4096,M_=32*1024;function Nfe(e,t,n){let i=null,o;const s=new Set;async function r(p){try{const m=await n.api.listTasks(p),k=e.tasksBySession[p]??[],w=new Map(k.map(A=>[A.id,A])),y=new Map(k.filter(A=>A.backgroundTaskId!==void 0).map(A=>[A.backgroundTaskId,A])),b=m.map(A=>{const T=w.get(A.id)??y.get(A.id),S=A.completedAt===void 0&&T?.completedAt===void 0&&T?.status==="running"&&A.status!=="running";return{...A,completedAt:A.completedAt??T?.completedAt??(S?new Date().toISOString():void 0),completedAtEstimated:A.completedAt!==void 0?void 0:T?.completedAt!==void 0?T.completedAtEstimated:S?!0:void 0}});e.tasksBySession={...e.tasksBySession,[p]:m_(b,k)},await l(p,m)}catch{}}async function l(p,g){if(e.activeSessionId!==p)return;const m=g??e.tasksBySession[p]??[],k=n.api,w=new Map;if(await Promise.all(m.map(async b=>{if((b.status==="completed"||b.status==="failed"||b.status==="cancelled")&&!s.has(b.id)&&!((b.outputLines?.length??0)>0))try{const T=await k.getTask(p,b.id,{withOutput:!0,outputBytes:M_});T.outputPreview!==void 0&&w.set(b.id,{preview:T.outputPreview,bytes:T.outputBytes}),s.add(b.id)}catch{}})),w.size===0)return;const y=e.tasksBySession[p]??[];e.tasksBySession={...e.tasksBySession,[p]:y.map(b=>{const A=w.get(b.id)??(b.backgroundTaskId!==void 0?w.get(b.backgroundTaskId):void 0);return A?{...b,outputPreview:A.preview,outputBytes:A.bytes}:b})}}async function a(p){if(e.activeSessionId!==p)return;const g=n.api;let m;try{m=await g.listTasks(p)}catch{return}const k=new Map;await Promise.all(m.map(async T=>{const S=T.status==="running",x=T.status==="completed"||T.status==="failed"||T.status==="cancelled";if(!(!S&&!x)&&!(x&&(s.has(T.id)||(T.outputLines?.length??0)>0)))try{const _=await g.getTask(p,T.id,{withOutput:!0,outputBytes:S?Lfe:M_});_.outputPreview!==void 0&&k.set(T.id,{preview:_.outputPreview,bytes:_.outputBytes}),x&&s.add(T.id)}catch{}}));const w=e.tasksBySession[p]??[],y=new Map(w.map(T=>[T.id,T])),b=new Map(w.filter(T=>T.backgroundTaskId!==void 0).map(T=>[T.backgroundTaskId,T])),A=m.map(T=>{const S=y.get(T.id)??b.get(T.id),x=k.get(T.id),_=T.completedAt===void 0&&S?.completedAt===void 0&&S?.status==="running"&&T.status!=="running";return{...T,outputLines:S?.outputLines,text:S?.text,completedAt:T.completedAt??S?.completedAt??(_?new Date().toISOString():void 0),completedAtEstimated:T.completedAt!==void 0?void 0:S?.completedAt!==void 0?S.completedAtEstimated:_?!0:void 0,outputPreview:x?.preview??S?.outputPreview,outputBytes:x?.bytes??S?.outputBytes}});e.tasksBySession={...e.tasksBySession,[p]:m_(A,w)}}function u(p){i!==null&&o===p||(c(),o=p,a(p),i=setInterval(()=>{typeof document<"u"&&document.visibilityState==="hidden"||(e.activeSessionId===p?a(p):c())},Tfe))}function c(){i!==null&&(clearInterval(i),i=null),o=void 0,s.clear()}const d=K(0);let h=null;return Pe(()=>t.value.some(p=>p.status==="running"),p=>{p&&h===null?h=setInterval(()=>{d.value=(d.value+1)%Number.MAX_SAFE_INTEGER},1e3):!p&&h!==null&&(clearInterval(h),h=null)},{immediate:!0}),Pe(()=>{const p=e.activeSessionId;if(!p)return{sid:void 0,hasRunning:!1};const g=e.tasksBySession[p]??[];return{sid:p,hasRunning:g.some(m=>m.status==="running")}},({sid:p,hasRunning:g},m,k)=>{let w;g&&p!==void 0?u(p):p!==void 0?w=setTimeout(()=>{(e.tasksBySession[p]??[]).some(b=>b.status==="running")||c()},1500):c(),k(()=>{w!==void 0&&clearTimeout(w)})},{deep:!0,immediate:!0}),{taskClock:F(()=>d.value),loadTasksForSession:r}}function Ffe(e,t){const{api:n,pushOperationFailure:i,nextOptimisticMsgId:o,connectEventsIfNeeded:s,getEventConn:r,resolveThinkingForPrompt:l,refreshSessionStatus:a}=t,u=K({}),c=F(()=>{const j=e.activeSessionId;if(!j)return null;const $=u.value[j];return $?{parentId:j,agentId:$.agentId}:null}),d=F(()=>c.value?.parentId??null),h=F(()=>c.value!==null),p=F(()=>{const j=c.value;return j?!!e.sideChatSendingByAgent[j.agentId]:!1}),g=F(()=>{const j=c.value;return j?e.sideChatSendingByAgent[j.agentId]?!0:(e.tasksBySession[j.parentId]??[]).some($=>$.id===j.agentId&&$.status==="running"):!1}),m=j=>n.getFileUrl(j),k=[],w=hB(),y=F(()=>{const j=c.value;return j?w({messages:e.sideChatMessagesByAgent[j.agentId]??[],approvals:k,getFileUrl:m,sessionActive:g.value}):[]});function b(j,$){e.sideChatMessagesByAgent[j]=$(e.sideChatMessagesByAgent[j]??[])}function A(j,$){b(j,W=>[...W,$])}function T(j,$){b(j,W=>{const P=W.find(Z=>Z.id===$);return P?.promptId!==void 0||P?.userMessageId!==void 0?W:W.filter(Z=>Z.id!==$)})}function S(j,$){const W=e.sideChatUserMessageIdsBySession[j]??[];W.includes($)||(e.sideChatUserMessageIdsBySession={...e.sideChatUserMessageIdsBySession,[j]:[...W,$]})}function x(j,$,W,P){b(j,Z=>{const ae=Z.findIndex(q=>q.id===$);if(ae===-1)return Z;const V=Z.findIndex((q,ne)=>ne!==ae&&q.role==="user"&&(q.id===P||q.userMessageId===P||q.promptId===W)),Y=Z[ae],oe=V===-1?Y:Z[V];return Z.flatMap((q,ne)=>ne===V?[]:ne!==ae?[q]:[{...oe,id:Y.id,promptId:W,userMessageId:P,metadata:{...oe.metadata,...Y.metadata}}])})}function _(j,$){S($.sessionId,$.userMessageId??$.id),b(j,W=>{const P=W.findIndex(V=>V.role==="user"&&(V.userMessageId===($.userMessageId??$.id)||V.promptId!==void 0&&V.promptId===$.promptId));if(P===-1)return[...W,$];const Z=W[P],ae=[...W];return ae[P]={...$,id:Z.id,promptId:$.promptId??Z.promptId,userMessageId:$.userMessageId??$.id,metadata:{...$.metadata,...Z.metadata}},ae})}function L(j,$,W){W&&b(j,P=>{const Z=P.at(-1);if(Z?.role==="assistant"){const ae=Z.content[0],V=ae?.type==="text"?ae.text:"";return[...P.slice(0,-1),{...Z,content:[{type:"text",text:`${V}${W}`}]}]}return[...P,{id:o(),sessionId:$,role:"assistant",content:[{type:"text",text:W}],createdAt:new Date().toISOString()}]})}function M(j,$,W){if(e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[j]:!1},!W)return;const Z=(e.sideChatMessagesByAgent[j]??[]).at(-1);(Z?.role==="assistant"&&Z.content[0]?.type==="text"?Z.content[0].text:"").trim().length>0||L(j,$,W)}async function N(j){const $=e.activeSessionId;return $?I($,j):!1}async function I(j,$){if(!u.value[j]){let W;try{({agentId:W}=await n.startBtw(j))}catch(P){return i("openSideChat",P,{sessionId:j}),!1}e.sideChatMessagesByAgent={...e.sideChatMessagesByAgent,[W]:e.sideChatMessagesByAgent[W]??[]},u.value={...u.value,[j]:{agentId:W}},s(),r()?.markSideChannelAgent(j,W)}return $&&$.trim()?z(j,$.trim()):!0}async function z(j,$){const W=u.value[j],P=$.trim();if(!W||!P)return!1;const Z=j,ae=W.agentId;e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[ae]:!0};const V=o(),Y={id:V,sessionId:Z,role:"user",content:[{type:"text",text:P}],createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};A(ae,Y);let oe,q=!1;try{const ne=e.sessions.find(te=>te.id===Z),ie=(ne?.model&&ne.model.length>0?ne.model:e.defaultModel)??void 0,pe=await l(Z,ie)??e.thinking;oe=e.pendingThinkingBySession[Z],q=!0;const Ne=await n.submitPrompt(Z,{content:[{type:"text",text:P}],agentId:ae,model:ie,thinking:pe,permissionMode:e.permission,planMode:e.planModeBySession[Z]??!1,swarmMode:e.swarmModeBySession[Z]??!1});return pe!==void 0&&Au(e,Z,oe),u.value[Z]?.agentId===ae&&(x(ae,V,Ne.promptId,Ne.userMessageId),S(Z,Ne.userMessageId)),!0}catch(ne){return Au(e,Z,oe)&&a(Z),i("sendSideChatPrompt",ne,{sessionId:Z}),u.value[Z]?.agentId===ae&&(T(ae,V),e.sideChatSendingByAgent={...e.sideChatSendingByAgent,[ae]:!1}),!(!q||ne instanceof cc)}}function H(){const j=e.activeSessionId;if(!j)return;const{[j]:$,...W}=u.value;u.value=W}async function O(j){const $=c.value;return $?z($.parentId,j):!1}function R(j){if(e.sideChatUserMessageIdsBySession[j]!==void 0){const{[j]:ae,...V}=e.sideChatUserMessageIdsBySession;e.sideChatUserMessageIdsBySession=V}const $=u.value[j];if(!$)return;const{[j]:W,...P}=u.value;u.value=P;const Z=$.agentId;if(Object.prototype.hasOwnProperty.call(e.sideChatMessagesByAgent,Z)){const{[Z]:ae,...V}=e.sideChatMessagesByAgent;e.sideChatMessagesByAgent=V}if(Object.prototype.hasOwnProperty.call(e.sideChatSendingByAgent,Z)){const{[Z]:ae,...V}=e.sideChatSendingByAgent;e.sideChatSendingByAgent=V}}return{sideChatTargetBySession:u,sideChatSessionId:d,sideChatVisible:h,sideChatSending:p,sideChatRunning:g,sideChatTurns:y,appendSideChatAssistantText:L,finishSideChatAgent:M,reconcileSideChatUserMessage:_,openSideChat:N,openSideChatOn:I,closeSideChat:H,sendSideChatPrompt:O,clearSideChatForSession:R}}/*! - * pinia v4.0.3 - * (c) 2026 Eduardo San Martin Morote - * @license MIT - */let I$;const p9=e=>I$=e,E$=Symbol();function I_(e){return e&&typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"&&typeof e.toJSON!="function"}function Dfe(){const e=F5(!0),t=e.run(()=>K({}));let n=[],i=[];const o=St({install(s){p9(o),o._a=s,s.provide(E$,o),s.config.globalProperties.$pinia=o,i.forEach(r=>n.push(r)),i=[]},use(s){return this._a?n.push(s):i.push(s),this},_p:n,_a:null,_e:e,_s:new Map,state:t});return o}const f8=()=>{};function E_(e,t,n,i=f8){e.add(t);const o=()=>{e.delete(t)&&i()};return!n&&Y0()&&Bc(o),o}function Kf(e,...t){e.forEach(n=>{n(...t)})}const Bfe=e=>e(),T_=Symbol(),w3=Symbol();function h8(e,t){e instanceof Map&&t instanceof Map?t.forEach((n,i)=>e.set(i,n)):e instanceof Set&&t instanceof Set&&t.forEach(e.add,e);for(const n in t){if(!Object.hasOwn(t,n))continue;const i=t[n],o=e[n];I_(o)&&I_(i)&&Object.hasOwn(e,n)&&!io(i)&&!Ra(i)?e[n]=h8(o,i):e[n]=i}return e}const $fe=Symbol();function Rfe(e){return!e||typeof e!="object"||!Object.hasOwn(e,$fe)}const{assign:Ju}=Object;function zfe(e){return!!(io(e)&&e.effect)}function Ofe(e,t,n,i){const{state:o,actions:s,getters:r}=t,l=n.state.value[e];let a;function u(){l||(n.state.value[e]=o?o():{});const c=dq(n.state.value[e]);return Ju(c,s,Object.keys(r||{}).reduce((d,h)=>(d[h]=St(F(()=>{p9(n);const p=n._s.get(e);return r[h].call(p,p)})),d),{}))}return a=T$(e,u,t,n,i,!0),a}function T$(e,t,n={},i,o,s){let r;const l=Ju({actions:{}},n),a={deep:!0};let u,c,d=new Set,h=new Set,p;const g=i.state.value[e];!s&&!g&&(i.state.value[e]={});let m;function k(x){let _;u=c=!1,typeof x=="function"?(x(i.state.value[e]),_={type:"patch function",storeId:e,events:p}):(h8(i.state.value[e],x),_={type:"patch object",payload:x,storeId:e,events:p});const L=m=Symbol();dt().then(()=>{m===L&&(u=!0)}),c=!0,Kf(d,_,i.state.value[e])}const w=s?function(){const{state:_}=n,L=_?_():{};this.$patch(M=>{Ju(M,L)})}:f8;function y(){r.stop(),d.clear(),h.clear(),i._s.delete(e)}const b=(x,_="")=>{if(T_ in x)return x[w3]=_,x;const L=function(){p9(i);const M=Array.from(arguments),N=new Set,I=new Set;function z(R){N.add(R)}function H(R){I.add(R)}Kf(h,{args:M,name:L[w3],store:T,after:z,onError:H});let O;try{O=x.apply(this&&this.$id===e?this:T,M)}catch(R){throw Kf(I,R),R}return O instanceof Promise?O.then(R=>(Kf(N,R),R)).catch(R=>(Kf(I,R),Promise.reject(R))):(Kf(N,O),O)};return L[T_]=!0,L[w3]=_,L},A={_p:i,$id:e,$onAction:E_.bind(null,h),$patch:k,$reset:w,$subscribe(x,_={}){if(d.has(x))return f8;const L=E_(d,x,_.detached,()=>M()),M=r.run(()=>Pe(()=>i.state.value[e],N=>{(_.flush==="sync"?c:u)&&x({storeId:e,type:"direct",events:p},N)},Ju({},a,_)));return L},$dispose:y},T=jo(A);i._s.set(e,T);const S=(i._a&&i._a.runWithContext||Bfe)(()=>i._e.run(()=>(r=F5()).run(()=>t({action:b}))));for(const x in S){const _=S[x];io(_)&&!zfe(_)||Ra(_)?s||(g&&Rfe(_)&&(io(_)?_.value=g[x]:((_ instanceof Set||_ instanceof Map)&&_.clear(),h8(_,g[x]))),i.state.value[e][x]=_):typeof _=="function"&&(S[x]=b(_,x),l.actions[x]=_)}return Ju(T,S),Ju(si(T),S),Object.defineProperty(T,"$state",{get:()=>i.state.value[e],set:x=>{k(_=>{Ju(_,x)})}}),i._p.forEach(x=>{const _=r.run(()=>x({store:T,app:i._a,pinia:i,options:l}));Ju(T,_)}),g&&s&&n.hydrate&&n.hydrate(T.$state,g),u=!0,c=!0,T}/*! #__NO_SIDE_EFFECTS__ */function lg(e,t,n){let i;const o=typeof t=="function";i=o?n:t;function s(r,l){const a=wq();return r=r||(a?hn(E$,null):null),r&&p9(r),r=I$,r._s.has(e)||(o?T$(e,t,i,r):Ofe(e,i,r)),r._s.get(e)}return s.$id=e,s}const Pfe={api:()=>{throw new Error("[@moonshot-ai/app-client] client deps not installed — call setKimiClientDeps() at app bootstrap")},t:e=>e},ca=globalThis.__kimiAppClientDeps??={current:Pfe};function jfe(e){ca.current=e}const Hfe=new Proxy({},{get(e,t){return ca.current.api()[t]}});function Wt(){return Hfe}function gi(e,t){return ca.current.t(e,t)}function Wfe(e,t){ca.current.traceClientEvent?.(e,t)}function Ll(e,t){ca.current.traceKeyEvent?.(e,t)}function qfe(){return ca.current.sessionExportTraceToJsonl?.()??""}function p8(e){ca.current.onSessionDestroyed?.(e)}function Ufe(e,t,n){ca.current.onWorkspaceDestroyed?.(e,t,n)}function Kfe(e){return ca.current.consumeSessionIntent?.(e)??e}function Vfe(e){return ca.current.onPluginsShelfEvent?(ca.current.onPluginsShelfEvent(e),!0):!1}const f1=Dfe(),L$=un.starredModels;function Zfe(){try{const e=gs(L$);if(!e)return[];const t=JSON.parse(e);if(Array.isArray(t)&&t.every(n=>typeof n=="string"))return t}catch{}return[]}function Gfe(e){try{is(L$,JSON.stringify(e))}catch{}}const Qfe=lg("kimi.models",()=>{const e=K([]),t=K(Zfe()),n=K([]),i=K({}),o=K({}),s=K({}),r=K({}),l=new Set,a=new Set,u=K(null);function c(y){e.value=y}function d(y){n.value=y}function h(y){u.value=y}function p(y,b){i.value={...i.value,[y]:b}}function g(y,b){o.value={...o.value,[y]:b}}function m(y){const b=new Set(t.value);b.has(y)?b.delete(y):b.add(y),t.value=Array.from(b),Gfe(t.value)}async function k(y){if(l.has(y))return;l.add(y);const b={...s.value};delete b[y],s.value=b;try{const A=await Wt().listSkills(y);p(y,A)}catch{}finally{l.delete(y),s.value={...s.value,[y]:!0}}}async function w(y){if(a.has(y))return;a.add(y);const b={...r.value};delete b[y],r.value=b;try{const A=await Wt().listSkillsForWorkspace(y);g(y,A)}catch{}finally{a.delete(y),r.value={...r.value,[y]:!0}}}return{models:e,starredModelIds:t,providers:n,draftModel:u,skillsBySession:i,skillsByWorkspace:o,skillsFetchedBySession:s,skillsFetchedByWorkspace:r,setModels:c,setProviders:d,setDraftModel:h,setSkillsForSession:p,setSkillsForWorkspace:g,toggleStarModel:m,loadSkillsForSession:k,loadSkillsForWorkspace:w}});function g8(){return Qfe(f1)}const L_=new Error("profile persist failed");function Yfe(e,t){const{api:n,pushOperationFailure:i,refreshSessionStatus:o,persistSessionProfile:s,savePlanModeToStorage:r,activity:l,updateSession:a,updateSessionMessages:u,loadConfig:c,checkAuth:d,beginLocalTurn:h,settleLocalTurn:p}=t,g=g8();function m(q){if(!(q==null||q.length===0))return g.models.find(ne=>ne.id===q)??g.models.find(ne=>ne.model===q)}function k(){const q=e.activeSessionId?e.sessions.find(ie=>ie.id===e.activeSessionId):void 0,ne=q===void 0?g.draftModel??e.defaultModel:q.model||e.defaultModel;return m(ne)?.id??ne??void 0}function w(q){if(q===void 0)return;const ne=m(q);return ne===void 0?void 0:_0(ne)}function y(q,ne){const ie=q==null?void 0:e.thinkingBySession[q];return ie!==void 0&&Ure(ne,ie)?ie:_0(ne)}function b(q,ne){if(ne===void 0)return;const ie=m(ne);return ie===void 0?void 0:y(q,ie)}async function A(q,ne){return q!=null&&e.thinkingBySession[q]===void 0&&await o(q),b(q,ne)}function T(q){e.thinking=q;const ne=e.activeSessionId;return q!==void 0&&ne!==null&&ne!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ne]:q},Ob(e,ne)),q}Pe([()=>e.activeSessionId,()=>k(),()=>{const q=e.activeSessionId;return q==null?void 0:e.thinkingBySession[q]}],()=>{const q=m(k());q!==void 0&&(e.thinking=y(e.activeSessionId,q))});function S(q){n.setConfig({thinking:Kre(q,m(k())?.supportEfforts)}).catch(ne=>i("setConfig",ne))}async function x(){try{g.setModels(await n.listModels());const q=m(k());q!==void 0&&(e.thinking=y(e.activeSessionId,q))}catch(q){i("loadModels",q)}}async function _(){try{g.setProviders(await n.listProviders())}catch(q){i("loadProviders",q)}}async function L(q){const ne=e.activeSessionId,ie=m(q),pe=e.thinking,Ne=ne?e.sessions.find(ue=>ue.id===ne)?.model:void 0,te=k()!==(ie?.id??q),be=Vre(ie,pe,te);if(!ne)return g.setDraftModel(q),e.thinking=be,be!==pe&&be!==void 0&&S(be),!0;a(ne,ue=>({...ue,model:q}));let Q;be!==pe&&(e.thinking=be,be!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ne]:be},Q=Ob(e,ne)));try{await n.updateSession(ne,{model:q,thinking:be!==pe?be:void 0})}catch(ue){return a(ne,Ae=>({...Ae,model:Ne??Ae.model})),be!==pe&&(e.thinking=pe,pe!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[ne]:pe}),Au(e,ne,Q)&&o(ne)),i("setModel",ue,{sessionId:ne}),!1}return be!==pe&&be!==void 0&&S(be),Au(e,ne,Q),await o(ne),!0}async function M(q,ne,ie,pe,Ne){const te=pe??e.activeSessionId;if(!te)return!1;const be=l.value==="idle"&&!e.inFlightBySession[te],Q=`msg_skill_opt_${Date.now().toString(36)}`,ue=be?h(te):void 0;let Ae=!1;if(be){e.inFlightBySession={...e.inFlightBySession,[te]:!0};const se={id:Q,sessionId:te,role:"user",content:[{type:"text",text:`/${q}${ne?` ${ne}`:""}`},...T2(ie)],createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0,origin:{kind:"skill_activation",trigger:"user-slash",skillName:q,skillArgs:ne}}};u(te,re=>[...re,se])}try{if(Ne?.skipThinkingPersist!==!0){const se=e.sessions.find(ge=>ge.id===te)?.model,re=(se&&se.length>0?se:e.defaultModel)??void 0,G=e.planArmedBySession[te]??!1;if(!await s({thinking:await A(te,re)??e.thinking,swarmMode:e.swarmModeBySession?.[te]??!1,permissionMode:e.permission,...G?{planMode:!0}:{}},te))throw L_;G&&(e.planArmedBySession={...e.planArmedBySession,[te]:!1},r(),e.planModeBySession={...e.planModeBySession,[te]:!0})}return Ae=!0,await n.activateSkill(te,q,ne,T2(ie)),!0}catch(se){return be&&(e.inFlightBySession={...e.inFlightBySession,[te]:!1},u(te,re=>re.filter(G=>G.id!==Q))),se!==L_&&i("activateSkill",se,{sessionId:te}),!(!Ae||se instanceof cc)}finally{ue!==void 0&&p(te,ue)}}async function N(q){return n.getProvider(q)}async function I(q){try{return await n.addProvider(q),await Promise.all([_(),x(),c()]),await d(),null}catch(ne){return fu("[kimi-code] operation failed: addProvider",ne),ne instanceof Error?ne.message:String(ne)}}async function z(q,ne){try{return await n.updateProvider(q,ne),await Promise.all([_(),x(),c()]),null}catch(ie){return fu("[kimi-code] operation failed: updateProvider",ie),ie instanceof Error?ie.message:String(ie)}}async function H(q){try{const ne=await n.deleteProvider(q);return await Promise.all([_(),x(),c()]),await d(),ne}catch(ne){return i("deleteProvider",ne),null}}async function O(q){try{const ne=await n.refreshProvider(q);for(const ie of ne.failed)i("refreshProvider",new Error(ie.reason),{message:ie.provider});await Promise.all([_(),x(),c()])}catch(ne){i("refreshProvider",ne)}}async function R(){try{const q=await n.refreshAllProviders();for(const ne of q.failed)i("refreshAllProviders",new Error(ne.reason),{message:ne.provider});await Promise.all([_(),x(),c()])}catch(q){i("refreshAllProviders",q)}}async function j(){try{return{kind:"ok",items:await n.listCatalogProviders()}}catch(q){return q instanceof cc&&q.code===void 0?{kind:"unsupported"}:(fu("[kimi-code] operation failed: loadCatalogProviders",q),{kind:"error"})}}async function $(q){try{return await n.importCatalogProvider(q),await Promise.all([_(),x(),c()]),await d(),null}catch(ne){return fu("[kimi-code] operation failed: importCatalogProvider",ne),ne instanceof Error?ne.message:String(ne)}}async function W(q){try{const ne=await n.importCustomRegistry(q);return await Promise.all([_(),x(),c()]),await d(),ne}catch(ne){return fu("[kimi-code] operation failed: importCustomRegistry",ne),ne instanceof Error?ne.message:String(ne)}}async function P(q){try{return await n.startOAuthLogin(q)}catch{return null}}async function Z(){return n.getOAuthRegion()}async function ae(){try{return await n.pollOAuthLogin()}catch(q){return bu("[kimi-code] pollOAuthLogin failed",q),null}}async function V(){try{await n.cancelOAuthLogin()}catch{}}async function Y(){try{return await n.getUsage()}catch(q){return{kind:"error",message:q instanceof Error?q.message:String(q)}}}function oe(q){const ne=T(q);s({thinking:ne}),ne!==void 0&&S(ne)}return{models:F(()=>g.models),starredModelIds:F(()=>g.starredModelIds),providers:F(()=>g.providers),draftModel:F(()=>g.draftModel),skillsBySession:F(()=>g.skillsBySession),skillsByWorkspace:F(()=>g.skillsByWorkspace),skillsFetchedBySession:F(()=>g.skillsFetchedBySession),skillsFetchedByWorkspace:F(()=>g.skillsFetchedByWorkspace),loadSkillsForSession:g.loadSkillsForSession,loadSkillsForWorkspace:g.loadSkillsForWorkspace,loadModels:x,loadProviders:_,setModel:L,thinkingLevelForModelId:w,thinkingLevelForSessionId:b,resolveThinkingForPrompt:A,toggleStarModel:g.toggleStarModel,activateSkill:M,addProvider:I,updateProvider:z,deleteProvider:H,getProvider:N,loadCatalogProviders:j,importCatalogProvider:$,importCustomRegistry:W,refreshProvider:O,refreshAllProviders:R,startOAuthLogin:P,pollOAuthLogin:ae,cancelOAuthLogin:V,getOAuthRegion:Z,getUsage:Y,setThinking:oe}}const Jfe=lg("kimi.approvals",()=>{const e=K({}),t=K({});function n(c){Or(e.value,c)}function i(c){Or(t.value,c)}function o(c,d){e.value[c]=d}function s(c,d){t.value[c]=d}function r(c,d){const h=e.value[c]??[];e.value[c]=h.filter(p=>p.approvalId!==d)}function l(c,d){const h=t.value[c]??[];t.value[c]=h.filter(p=>p.questionId!==d)}function a(c){delete e.value[c]}function u(c){delete t.value[c]}return{approvalsBySession:e,questionsBySession:t,applyApprovalsDiff:n,applyQuestionsDiff:i,setSessionApprovals:o,setSessionQuestions:s,removePendingApproval:r,removePendingQuestion:l,clearSessionApprovals:a,clearSessionQuestions:u}});function qs(){return Jfe(f1)}const Xfe=lg("kimi.sessions",()=>{const e=K([]),t=K(void 0),n=K(g$());function i(p){e.value=p}function o(p,g){e.value=e.value.map(m=>m.id===p?g(m):m)}function s(p){e.value=VB(e.value,p)}function r(p){e.value=[...e.value,p]}function l(p){e.value=e.value.filter(g=>g.id!==p)}function a(p){t.value=p}function u(p){const g=_le(n.value,p);g!==n.value&&(n.value=g,y3(g))}function c(p){const g=Mle(n.value,p);g!==n.value&&(n.value=g,y3(g))}function d(p){const g=new Set(p),m=n.value.filter(k=>!g.has(k));m.length!==n.value.length&&(n.value=m,y3(m))}function h(p){n.value.includes(p)?c(p):u(p)}return{sessions:e,activeSessionId:t,pinnedSessionIds:n,setSessions:i,updateSession:o,upsertSessionSorted:s,appendSession:r,removeSession:l,setActiveSessionId:a,pinSession:u,unpinSession:c,unpinSessions:d,togglePinSession:h}});function or(){return Xfe(f1)}const ehe=40409;function the(e){return!e||e.state!=="open"&&e.state!=="closed"&&e.state!=="merged"?null:{number:e.number,state:e.state,url:e.url}}function nhe(e,t){return e==null||t==null?e==null&&t==null:e.number===t.number&&e.state===t.state&&e.url===t.url}const ihe=lg("kimi.files",()=>{const e=K(null),t=K([]),n=K(!1),i=K(null),o=K(!1),s=K({});async function r(d){const h=or().activeSessionId;if(!h)return null;try{const g=await Wt().readFile(h,{path:d});return{path:g.path,content:g.content,encoding:g.encoding,mime:g.mime,languageId:g.languageId,isBinary:g.isBinary,size:g.size,lineCount:g.lineCount}}catch(p){if(bu("[kimi-code] readFileContent failed for",d,p),ko(p)&&p.code===ehe)throw p;return null}}async function l(d){const h=or().activeSessionId;if(h){e.value=d,t.value=[],i.value=null,o.value=!1,n.value=!0;try{const g=await Wt().getFileDiff(h,d);if(e.value!==d||or().activeSessionId!==h)return;const m=Zse(g.diff);if(t.value=m,m.length===0){const w=await r(d).catch(()=>null);if(e.value!==d||or().activeSessionId!==h)return;o.value=w!==null&&w.size===0;return}n.value=!1;const k=await $se(m,{truncated:g.truncated,readNewText:async()=>{const w=await r(d).catch(()=>null);return!w||w.isBinary||w.encoding!=="utf-8"?null:w.content}});if(e.value!==d||or().activeSessionId!==h)return;i.value=k}catch(p){e.value===d&&(t.value=[]),bu("[loadFileDiff] diff unavailable for",d,p)}finally{e.value===d&&(n.value=!1)}}}function a(){e.value=null,t.value=[],i.value=null,o.value=!1,n.value=!1}async function u(d){try{const p=await Wt().getGitStatus(d);s.value[d]=p;const g=the(p.pullRequest);or().updateSession(d,m=>nhe(m.pullRequest,g)?m:{...m,pullRequest:g})}catch{}}function c(d){delete s.value[d]}return{selectedDiffPath:e,fileDiffLines:t,fileDiffLoading:n,fileDiffTexts:i,fileDiffEmptyFile:o,gitStatusBySession:s,readFileContent:r,loadFileDiff:l,clearFileDiff:a,loadGitStatus:u,clearSessionGitStatus:c}});function Hs(){return ihe(f1)}const ohe=50,mp=5,j6=5,dc=50,N_=40401,she=40402,rhe=40410,F_=40409,lhe=40902,ahe=2e3,uhe=10;function x3(e){return ko(e)&&e.code===lhe}const che=40904;function dhe(e){return ko(e)&&e.code===che}const pd=jo({}),Fm=jo({}),S3=jo({}),wa=jo(new Set),g9=new Map,uf=new Map,L2=new Map;let fhe=0;const xd=new Map,hhe=3,iu=new Map,vp=new Map,phe=3,xv=new Map;function ghe(e){const t=xv.get(e);if(!(t!==void 0&&(t.done||t.attempts>=phe))){xv.set(e,{attempts:(t?.attempts??0)+1,done:!1});try{Wt().generateSessionTitle(e,{source:"first_turn"}).then(n=>{n!==null&&xv.set(e,{attempts:0,done:!0})}).catch(()=>{})}catch{}}}let D_=0;function mhe(){return D_+=1,`${Date.now().toString(36)}-${D_}`}function vhe(e){return{generation:g9.get(e)??0,pending:(uf.get(e)?.size??0)>0}}function m8(e){const t=++fhe;g9.set(e,t);const n=uf.get(e)??new Set;return n.add(t),uf.set(e,n),t}function v8(e,t){const n=uf.get(e);if(n===void 0||(n.delete(t),n.size>0))return;uf.delete(e);const i=L2.get(e);L2.delete(e),i?.()}function yhe(e){g9.delete(e),uf.delete(e),L2.delete(e),xd.delete(e),iu.delete(e),vp.delete(e)}function khe(e,t){return!t.pending&&t.generation===(g9.get(e)??0)}function bhe(e,t){if((uf.get(e)?.size??0)===0){t();return}L2.set(e,t)}function Ahe(e,t){const{confirm:n}=Vc(),{taskPoller:i,sideChat:o,modelProvider:s,pushOperationFailure:r,notify:l,activity:a,sessionsKnownEmpty:u,setSessions:c,updateSession:d,upsertSessionSorted:h,appendSession:p,forgetSession:g,unpinSessions:m,setActiveSessionId:k,updateSessionMessages:w,nextOptimisticMsgId:y,getEventConn:b,syncSessionFromSnapshot:A,reopenSession:T,hasLoadedMessages:S,refreshSessionStatus:x,refreshSessionGoal:_,refillSessionGoalOnReload:L,refreshSessionPlans:M,settlePlanReviewLocally:N,persistSessionProfile:I,mergedWorkspaces:z,workspacesView:H,status:O,workspaceIdForSession:R,savePermissionToStorage:j,savePlanModeToStorage:$,saveSwarmModeToStorage:W,saveGoalModeToStorage:P,draftModes:Z,saveUnread:ae,saveActiveWorkspaceToStorage:V,saveHiddenWorkspacesToStorage:Y,goalErrorMessage:oe,initialized:q,connectIssue:ne}=t;let ie=0,pe=!1;function Ne(ee,me,Me,Re){w(ee,Qe=>{const Je=Qe.findIndex(fn=>fn.id===me);if(Je===-1)return Qe;const ft=Qe.findIndex((fn,dn)=>dn!==Je&&fn.role==="user"&&(fn.id===Re||fn.userMessageId===Re||fn.promptId===Me)),vt=Qe[Je],Pt=ft===-1?vt:Qe[ft];return Qe.flatMap((fn,dn)=>dn===ft?[]:dn!==Je?[fn]:[{...Pt,id:vt.id,promptId:Me,userMessageId:Re,metadata:{...Pt.metadata,...vt.metadata}}])})}async function te(ee){if(e.messagesLoadingMoreBySession[ee])return;const me=e.messagesBySession[ee];if(!me||me.length===0)return;const Me=me[0].id;e.messagesLoadingMoreBySession={...e.messagesLoadingMoreBySession,[ee]:!0},e.messagesLoadMoreErrorBySession={...e.messagesLoadMoreErrorBySession,[ee]:!1};try{const Re=await Wt().listMessages(ee,{beforeId:Me,pageSize:ohe}),Qe=[...Re.items].reverse();w(ee,Je=>[...Qe,...Je]),e.messagesHasMoreBySession={...e.messagesHasMoreBySession,[ee]:Re.hasMore}}catch(Re){e.messagesLoadMoreErrorBySession={...e.messagesLoadMoreErrorBySession,[ee]:!0},r("loadOlderMessages",Re,{sessionId:ee})}finally{e.messagesLoadingMoreBySession={...e.messagesLoadingMoreBySession,[ee]:!1}}}function be(ee,me){i.loadTasksForSession(ee),Hs().loadGitStatus(ee),me?.skipStatus!==!0&&x(ee),_(ee),M(ee),Object.prototype.hasOwnProperty.call(s.skillsBySession.value,ee)||s.loadSkillsForSession(ee)}let Q=0;async function ue(ee){try{const me=await Wt().getUserInfo();if(ee!==Q||e.managedProviderStatus!=="authenticated")return;e.managedUserInfo=me.kind==="ok"?me.userInfo:null,me.kind==="ok"?e.managedMembership=me.userInfo.userLevel===uhe?"free":"member":e.managedMembership=me.status===402?"free":null}catch{if(ee!==Q)return;e.managedProviderStatus==="authenticated"&&(e.managedUserInfo=null,e.managedMembership=null)}}async function Ae(){e.managedProviderStatus==="authenticated"&&await ue(++Q)}async function se(){const ee=++Q;try{const Me=await Wt().getAuth();return e.authReady=Me.ready,e.defaultModel=Me.defaultModel,e.managedProviderStatus=Me.managedProvider?.status??null,e.managedProviderStatus==="authenticated"?ue(ee):(e.managedUserInfo=null,e.managedMembership=null),ne.value=null,"proceed"}catch(me){return ko(me)&&(me.code===401||me.code===iD)?(ne.value=null,"server-auth-required"):(ne.value=(me instanceof Error?me.message:String(me)).slice(0,140),"retry")}}async function re(){let ee=!0;for(;;){const me=await se();if(me!=="retry")return me;ee&&(ne.value=null,ee=!1),await new Promise(Me=>{setTimeout(Me,ahe)})}}async function G(){try{const ee=Wt();e.config=await ee.getConfig()}catch{}}async function le(ee){try{const Me=await Wt().setConfig(ee);return e.config=Me,e.defaultModel=Me.defaultModel??null,!0}catch(me){return r("setConfig",me),!1}}const ge=100;async function ke(ee){const me=Wt(),Me=[];let Re,Qe;for(;ee?.shouldContinue?.()!==!1;){let Je;try{Je=await me.listSessions({pageSize:ge,beforeId:Re,excludeEmpty:!0})}catch(ft){if(Me.length===0)throw ft;Qe=ft;break}if(Me.push(...Je.items),!Je.hasMore||Je.items.length===0)break;Re=Je.items[Je.items.length-1].id}return{sessions:Me,error:Qe}}const Ie=new Set;function Oe(ee){const me=On.size===0?ee:ee.filter(ft=>!On.has(ft.id)),Me=new Set(me.map(ft=>ft.id)),Re=e.sessions.filter(ft=>Ie.has(ft.id)&&!Me.has(ft.id)&&!On.has(ft.id)),Qe=Re.length===0?me:[...me,...Re].sort((ft,vt)=>new Date(vt.updatedAt).getTime()-new Date(ft.updatedAt).getTime()),Je=new Map(e.sessions.map(ft=>[ft.id,ft]));c(Qe.map(ft=>{const vt=Je.get(ft.id);if(vt===void 0)return ft;const Pt=v2(ft.usage)&&!v2(vt.usage),fn=ft.pullRequest??vt.pullRequest,dn=(ft.model??"")===""?vt.model:ft.model;return!Pt&&fn===ft.pullRequest&&dn===ft.model?ft:{...ft,usage:Pt?vt.usage:ft.usage,pullRequest:fn,model:dn}}))}function we(ee){const me=[...ee],Me=new Set(me.map(Re=>Re.id));for(const Re of e.sessions)Me.has(Re.id)||(me.push(Re),Me.add(Re.id));return me.sort((Re,Qe)=>new Date(Qe.updatedAt).getTime()-new Date(Re.updatedAt).getTime()),me}async function Be(){const ee=Wt(),me={groupPageSize:mp,hasPrompt:!0};let Me;try{Me=await ee.listSessionGroupsV2(me)}catch(Ln){r("load",Ln);return}const Re=[...Me.groups];let Qe=Me.nextPageToken;for(;Qe!==null;){let Ln;try{Ln=await ee.listSessionGroupsV2({...me,pageToken:Qe})}catch(Sn){r("load",Sn);return}Re.push(...Ln.groups),Qe=Ln.nextPageToken}const Je=new Map(Re.map(Ln=>[Ln.workspace.id,Ln])),ft=new Map(Re.filter(Ln=>Ln.workspace.cwd!==null).map(Ln=>[ol(Ln.workspace.cwd),Ln])),vt=[],Pt=new Set,fn={},dn={},ui={};for(const Ln of e.workspaces){const Sn=Je.get(Ln.id)??ft.get(ol(Ln.root));if(Sn===void 0){fn[Ln.id]=!1,dn[Ln.id]=void 0,ui[Ln.id]=mp;continue}const fi=Sn.sessions.filter(Ui=>!On.has(Ui.id)&&(Ui.meta.last_prompt??"").length>0).map(Ui=>ym(Ui.workspace.cwd===null?{...Ui,workspace:{...Ui.workspace,cwd:Ln.root}}:Ui));for(const Ui of fi)Pt.has(Ui.id)||(vt.push(Ui),Pt.add(Ui.id));fn[Ln.id]=Sn.sessions.length<Sn.total,dn[Ln.id]=fi.length>0?fi[fi.length-1].id:void 0,ui[Ln.id]=Math.max(fi.length,mp)}e.sessionsHasMoreByWorkspace=fn,e.sessionsCursorByWorkspace=dn,e.sessionsInitialCountByWorkspace=ui,e.sessionsFullyLoaded=!1;for(const Ln of Re)for(const Sn of Ln.sessions){const fi=Sn.activity.status;(fi==="running"||fi==="approval"||fi==="question")&&tt.push(Sn.id)}return vt.sort((Ln,Sn)=>new Date(Sn.updatedAt).getTime()-new Date(Ln.updatedAt).getTime()),vt}const tt=[];async function ut(ee){const me=e.lastSeqBySession[ee]??0;let Me;try{Me=await Wt().getSession(ee)}catch{return}(e.lastSeqBySession[ee]??0)>me||d(ee,Re=>({...Re,busy:Me.busy,mainTurnActive:Me.mainTurnActive??Re.mainTurnActive,pendingInteraction:Me.pendingInteraction??Re.pendingInteraction,lastTurnReason:Me.lastTurnReason??Re.lastTurnReason}))}async function _t(){if(tt.length=0,e.workspaces.length===0){const me=await ke(),Me=me.error===void 0?me.sessions:we(me.sessions);return e.sessionsHasMoreByWorkspace={},e.sessionsCursorByWorkspace={},e.sessionsInitialCountByWorkspace={},e.sessionsFullyLoaded=me.error===void 0,me.error!==void 0&&r("load",me.error),Me}return Be()}async function Ct(ee){if(!e.sessionsLoadingMoreByWorkspace[ee]&&e.sessionsHasMoreByWorkspace[ee]!==!1&&e.sessionsCursorByWorkspace[ee]!==void 0){e.sessionsLoadingMoreByWorkspace={...e.sessionsLoadingMoreByWorkspace,[ee]:!0};try{let me=e.sessionsCursorByWorkspace[ee],Me;for(let ft=0;ft<3&&me!==void 0&&(Me=await Wt().listSessions({workspaceId:ee,pageSize:j6,beforeId:me,excludeEmpty:!0}),e.sessionsCursorByWorkspace[ee]!==me);ft+=1)Me=void 0,me=e.sessionsCursorByWorkspace[ee];if(Me===void 0)return;const Re=new Set(e.sessions.map(ft=>ft.id)),Qe=Me.items.filter(ft=>!Re.has(ft.id)&&!On.has(ft.id));for(const ft of Qe)Ie.add(ft.id);Qe.length>0&&c([...e.sessions,...Qe]);const Je=Me.items.filter(ft=>!On.has(ft.id)).at(-1);e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[ee]:Je?.id??me},e.sessionsHasMoreByWorkspace={...e.sessionsHasMoreByWorkspace,[ee]:Me.hasMore}}catch(me){r("loadMoreSessions",me)}finally{e.sessionsLoadingMoreByWorkspace={...e.sessionsLoadingMoreByWorkspace,[ee]:!1}}}}function $t(ee){return e.sessions.filter(me=>!me.parentSessionId&&R(me)===ee)}const Vt=5;function nn(ee,me){const Me=new Set(e.sessions.map(Je=>Je.id)),Re=ee.items.filter(Je=>!Me.has(Je.id)&&!On.has(Je.id)&&(Je.meta.last_prompt??"").length>0).map(ym);for(const Je of Re)Ie.add(Je.id);Re.length>0&&c([...e.sessions,...Re]);for(const Je of ee.items)if(Me.has(Je.id)&&Je.git!==void 0){const ft=Je.git.pull_request;d(Je.id,vt=>vt.pullRequest===ft?vt:{...vt,pullRequest:ft})}if(ee.items.length>0){const Je=Math.min(...ee.items.map(ft=>ft.meta.updated_at));e.flatSessionsFrontier=me?.resetFrontier===!0||e.flatSessionsFrontier===null?Je:Math.min(e.flatSessionsFrontier,Je)}e.flatSessionsNextPageToken=ee.nextPageToken,e.flatSessionsHasMore=ee.hasMore;const Qe=new Set(H.value.map(Je=>Je.id));return ee.items.filter(Je=>(Je.meta.last_prompt??"").length>0&&!On.has(Je.id)&&Qe.has(R({workspaceId:Je.workspace.id,cwd:Je.workspace.cwd??""}))).length}async function gt(){const ee=await Wt().listSessionsV2({pageSize:dc,include:"git"});nn(ee,{resetFrontier:!0}),e.flatSessionsSeeded=!0}async function Le(){if(!(e.flatSessionsSeeded||e.flatSessionsLoading)){e.flatSessionsLoading=!0;try{await gt()}catch(ee){r("ensureFlatSessions",ee)}finally{e.flatSessionsLoading=!1}}}async function ze(){if(!(e.flatSessionsLoading||e.flatSessionsLoadingMore)&&e.flatSessionsHasMore){e.flatSessionsLoadingMore=!0;try{if(!e.flatSessionsSeeded){await gt();return}if(e.flatSessionsNextPageToken===null)return;for(let ee=0;ee<Vt;ee+=1){const me=e.flatSessionsNextPageToken;if(me===null||!e.flatSessionsHasMore)break;let Me;try{Me=await Wt().listSessionsV2({pageSize:dc,pageToken:me,include:"git"})}catch(Re){if(!hx(Re))throw Re;e.flatSessionsNextPageToken=null,await gt();break}if(nn(Me)>0)break}}catch(ee){r("loadMoreFlatSessions",ee)}finally{e.flatSessionsLoadingMore=!1}}}async function Ye(){const ee=await Wt().listSessionsV2({pageSize:dc,include:"git",archived:!0}),me=new Set,Me=ee.items.filter(Qe=>(Qe.meta.last_prompt??"").length>0).filter(Qe=>!Wi.has(Qe.id)).filter(Qe=>me.has(Qe.id)?!1:(me.add(Qe.id),!0)).map(ym),Re=e.doneSessions.filter(Qe=>On.has(Qe.id)&&!me.has(Qe.id));e.doneSessions=[...Re,...Me],e.doneSessionsNextPageToken=ee.nextPageToken,e.doneSessionsHasMore=ee.hasMore}async function Tt(){if(!(e.doneSessionsSeeded||e.doneSessionsLoading)){e.doneSessionsLoading=!0;try{await Ye(),e.doneSessionsSeeded=!0}catch(ee){r("ensureDoneSessions",ee)}finally{e.doneSessionsLoading=!1}}}async function on(){if(!(e.doneSessionsLoading||e.doneSessionsLoadingMore)&&e.doneSessionsHasMore){e.doneSessionsLoadingMore=!0;try{if(!e.doneSessionsSeeded){await Ye(),e.doneSessionsSeeded=!0;return}let ee=3;for(;;){const me=e.doneSessionsNextPageToken;if(me===null)return;let Me;try{Me=await Wt().listSessionsV2({pageSize:dc,pageToken:me,include:"git",archived:!0})}catch(Je){if(!hx(Je))throw Je;e.doneSessionsNextPageToken=null,await Ye();return}const Re=new Set(e.doneSessions.map(Je=>Je.id)),Qe=Me.items.filter(Je=>!Re.has(Je.id)&&!Wi.has(Je.id)&&(Je.meta.last_prompt??"").length>0).map(ym);if(Qe.length>0&&(e.doneSessions=[...e.doneSessions,...Qe]),e.doneSessionsNextPageToken=Me.nextPageToken,e.doneSessionsHasMore=Me.hasMore,ee-=1,Qe.length>0||!Me.hasMore||ee<=0)return}}catch(ee){r("loadMoreDoneSessions",ee)}finally{e.doneSessionsLoadingMore=!1}}}async function jt(ee,me,Me,Re){if(e.sessionsCursorByWorkspace[ee]===me){const Je=new Date(Me).getTime();let ft;for(const vt of e.sessions){if(R(vt)!==ee)continue;const Pt=new Date(vt.updatedAt).getTime();Pt<=Je||(ft===void 0||Pt<new Date(ft.updatedAt).getTime())&&(ft=vt)}e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[ee]:ft?.id}}let Qe=3;for(;Qe>0&&$t(ee).length<Re&&(e.sessionsHasMoreByWorkspace[ee]??!1);){const Je=e.sessionsCursorByWorkspace[ee],ft=$t(ee).length;if(Je===void 0)try{const vt=await Wt().listSessions({workspaceId:ee,pageSize:mp,excludeEmpty:!0}),Pt=new Set(e.sessions.map(dn=>dn.id)),fn=vt.items.filter(dn=>!Pt.has(dn.id)&&!On.has(dn.id));for(const dn of fn)Ie.add(dn.id);fn.length>0&&c([...e.sessions,...fn].sort((dn,ui)=>new Date(ui.updatedAt).getTime()-new Date(dn.updatedAt).getTime())),e.sessionsCursorByWorkspace={...e.sessionsCursorByWorkspace,[ee]:vt.items.length>0?vt.items[vt.items.length-1].id:void 0},e.sessionsHasMoreByWorkspace={...e.sessionsHasMoreByWorkspace,[ee]:vt.hasMore}}catch(vt){r("loadMoreSessions",vt);break}else await Ct(ee);if(Qe-=1,$t(ee).length===ft&&e.sessionsCursorByWorkspace[ee]===Je)break}}async function kn(){if(e.sessionsFullyLoaded)return;const ee=await ke().catch(Re=>(bu("[kimi-code] loadAllSessions failed; search covers only loaded sessions",Re),null));if(ee===null)return;const me=ee.error===void 0?ee.sessions:we(ee.sessions);if(Oe(me),e.sessionsFullyLoaded=ee.error===void 0,ee.error!==void 0)return;const Me={};for(const Re of e.workspaces)Me[Re.id]=!1;e.sessionsHasMoreByWorkspace=Me}async function bn(){const ee=await Wt().getMeta().catch(()=>null);ee!==null&&(e.serverVersion=ee.serverVersion,e.availableOpenInApps=ee.openInApps,e.dangerousBypassAuth=ee.dangerousBypassAuth,e.experimentalFlags=ee.experimentalFlags,e.backend=ee.backend,e.webTitle=ee.webTitle)}async function mn(){const ee=Date.now();let me="accepted";Ll("app:load:start"),e.loading=!0,Ie.clear();const Me=!q.value;let Re=!0;try{if(Me&&await re()==="server-auth-required"){Re=!1,me="auth-required";return}const Qe=Wt();await Promise.all([Qe.getHealth().catch(()=>null),bn(),s.loadModels()]),Me||await se(),await G(),await zn();const Je=await _t();Je!==void 0&&Oe(Je);const ft=e.sessions;if(tt.length>0){const Sn=tt.splice(0);await Promise.allSettled(Sn.map(fi=>ut(fi)))}if(!Me&&Je!==void 0&&e.flatSessionsSeeded){e.flatSessionsSeeded=!1,e.flatSessionsNextPageToken=null,e.flatSessionsHasMore=!0,e.flatSessionsFrontier=null;try{await gt()}catch(Sn){r("ensureFlatSessions",Sn)}}const vt=g$().filter(Sn=>!e.sessions.some(fi=>fi.id===Sn));if(vt.length>0){const Sn=await Promise.all(vt.map(Ui=>Un(Ui))),fi=vt.filter((Ui,Fr)=>Sn[Fr]==="stale");fi.length>0&&m(fi)}e.activeSessionId!==void 0&&!e.sessions.some(Sn=>Sn.id===e.activeSessionId)&&await Tn(e.activeSessionId)==="not-found"&&(k(void 0),_i(void 0,"replace")),e.activeSessionId!==void 0&&await x(e.activeSessionId);for(const Sn of e.sessions)(Sn.mainTurnActive??Sn.busy)&&e.goalBySession[Sn.id]===void 0&&L(Sn.id);const Pt=ft[0],fn=e.activeWorkspaceId;!(fn!==null&&z.value.some(Sn=>Sn.id===fn))&&Pt&&st(R(Pt)),Io();const ui=typeof window<"u"&&RS(mo());ui&&(e.mainView="sessionAdmin");const Ln=typeof window<"u"?zS(mo()):void 0;!e.activeSessionId&&Ln!==void 0&&(e.sessions.some(fi=>fi.id===Ln)||await Tn(Ln)==="ok")&&await Ki(Ln,{urlMode:"replace",skipTrack:!0}),!e.activeSessionId&&ft.length>0&&await Ki(ft[0].id,{urlMode:ui?"none":"replace",skipTrack:!0})}catch(Qe){me="failed",r("load",Qe)}finally{e.loading=!1,Re&&(q.value=!0),Ll("app:load:complete",{status:me,sessionId:e.activeSessionId,sessionCount:e.sessions.length,workspaceCount:e.workspaces.length,durationMs:Date.now()-ee})}}async function zn(){try{const ee=Wt(),[me,Me]=await Promise.all([ee.listWorkspaces().catch(()=>[]),ee.getFsHome().catch(()=>({home:"",recentRoots:[]}))]);e.workspaces=He(me),e.fsHome=Me.home||null,e.recentRoots=Me.recentRoots}catch{}}function He(ee){const me=Im();return Object.keys(me).length===0?ee:ee.map(Me=>{const Re=me[Me.root];return Re!==void 0?{...Me,name:Re}:Me})}function st(ee){e.activeWorkspaceId=ee,V(ee)}function et(ee){e.mainView="chat",st(ee);const me=e.sessions.filter(Me=>R(Me)===ee);if(me.length>0){const Me=me[0];Me&&Me.id!==e.activeSessionId&&Ki(Me.id,{skipTrack:!0})}else k(void 0),_i(void 0,"push")}function Nt(ee){const me=Im()[ee.root],Me=me!==void 0?{...ee,name:me}:ee,Re=ol(Me.root);e.hiddenWorkspaceRoots.some(ft=>ol(ft)===Re)&&(e.hiddenWorkspaceRoots=e.hiddenWorkspaceRoots.filter(ft=>ol(ft)!==Re),Y(e.hiddenWorkspaceRoots));const Qe=e.workspaces.findIndex(ft=>ft.id===Me.id||ft.root===Me.root);if(Qe===-1){e.workspaces=[Me,...e.workspaces];return}const Je=[...e.workspaces];Je[Qe]=Me,e.workspaces=Je}function Lt(ee){if(ee.type==="workspaceCreated"||ee.type==="workspaceUpdated"){Nt(ee.workspace);return}const me=e.workspaces.find(Re=>Re.id===ee.workspaceId)?.root??ee.root;if(me&&!e.hiddenWorkspaceRoots.includes(me)&&(e.hiddenWorkspaceRoots=[...e.hiddenWorkspaceRoots,me],Y(e.hiddenWorkspaceRoots)),e.workspaces=e.workspaces.filter(Re=>Re.id!==ee.workspaceId&&Re.root!==me),e.activeWorkspaceId===ee.workspaceId||e.activeWorkspaceId===me){const Re=H.value[0]?.id??null;if(e.activeWorkspaceId=Re,Re)V(Re);else try{_r(un.activeWorkspace)}catch{}k(void 0),e.sessionLoading=!1,Hs().clearFileDiff(),_i(void 0,"replace")}}function qn(){k(void 0),e.mainView="chat",_i(void 0,"push")}function So(ee,me){me?.entry!==void 0&&(e.draftEntry=me.entry),st(ee),qn(),Hs().clearFileDiff()}async function Yn(ee){const me=z.value.find(dn=>dn.id===ee);if(!me)return null;Kfe("sidebar");const Me=e.thinking,Re=Wt();let Qe,Je=me.root;try{const dn=await Re.addWorkspace({root:me.root});Qe=dn.id,Je=dn.root,Nt(dn)}catch{}const ft=g8().draftModel??void 0,vt=await Re.createSession({workspaceId:Qe,cwd:Je,model:ft});g8().setDraftModel(null);const Pt=ft!==void 0&&(!vt.model||vt.model.length===0)?{...vt,model:ft}:vt;h(Pt);const fn=vt.id;return Me!==void 0&&(e.thinkingBySession={...e.thinkingBySession,[fn]:Me},Ob(e,fn)),st(vt.workspaceId??Qe??ee),await Ki(vt.id,{skipTrack:!0,skipStatusRefresh:!0}),Z.planMode&&(e.planArmedBySession={...e.planArmedBySession,[fn]:!0},$()),Z.swarmMode&&(e.swarmModeBySession={...e.swarmModeBySession,[fn]:!0},W()),Z.goalMode&&(e.goalModeBySession={...e.goalModeBySession,[fn]:!0},P()),Z.planMode=!1,Z.swarmMode=!1,Z.goalMode=!1,fn}async function Ir(ee,me,Me){if(wa.has(ee))return null;wa.add(ee);let Re=null;try{const Qe=await Yn(ee);return Qe?(Re=Qe,await Ti(Qe,me,Me),Qe):null}catch(Qe){return r("startSessionAndSendPrompt",Qe),Re}finally{wa.delete(ee)}}async function _o(ee,me,Me,Re){if(wa.has(ee))return{sessionId:null,activated:!1};wa.add(ee);let Qe=null;try{const Je=await Yn(ee);if(!Je)return{sessionId:null,activated:!1};Qe=Je;const ft=e.planArmedBySession[Je]??!1,vt=e.swarmModeBySession[Je]??!1,Pt=e.sessions.find(Sn=>Sn.id===Je),fn=(Pt?.model&&Pt.model.length>0?Pt.model:e.defaultModel)??void 0,dn=await s.resolveThinkingForPrompt(Je,fn)??e.thinking;if(!await I({model:fn,planMode:ft,swarmMode:vt,permissionMode:e.permission,thinking:dn},Je))return{sessionId:Je,activated:!1};ft&&(e.planArmedBySession={...e.planArmedBySession,[Je]:!1},$(),e.planModeBySession={...e.planModeBySession,[Je]:!0});const Ln=await s.activateSkill(me,Me,Re,Je,{skipThinkingPersist:!0});return{sessionId:Je,activated:Ln}}catch(Je){return r("startSessionAndActivateSkill",Je),{sessionId:Qe,activated:!1}}finally{wa.delete(ee)}}async function It(ee,me){if(wa.has(ee))return null;wa.add(ee);let Me=null;try{const Re=await Yn(ee);return Re?(Me=Re,await o.openSideChatOn(Re,me),Re):null}catch(Re){return r("startSessionAndOpenSideChat",Re),Me}finally{wa.delete(ee)}}async function ms(ee){const me=ee.trim();if(!me)return!1;const Me=Wt();try{const Re=await Me.addWorkspace({root:me});return Nt(Re),So(Re.id,{entry:"workspace"}),!0}catch(Re){return bu("[kimi-code] addWorkspaceByPath failed for",me,Re),!1}}async function Er(ee){try{return await Wt().browseFs(ee)}catch{return{path:"",parent:null,entries:[]}}}async function go(){try{return await Wt().getFsHome()}catch{return{home:"",recentRoots:[]}}}function mo(){return{pathname:zle(window.location.pathname)}}function vs(ee,me){if(me==="none"||typeof window>"u"||!window.history||mo().pathname===ee)return;const Me=HB(ee,window.location.search);try{me==="push"?window.history.pushState(null,"",Me):window.history.replaceState(null,"",Me)}catch{}}function _i(ee,me){e.mainView==="chat"&&vs(hae(ee),me)}function Mo(){e.mainView!=="sessionAdmin"&&(e.mainView="sessionAdmin",vs(ZB,"push"))}function ys(ee){e.mainView==="sessionAdmin"&&(e.mainView="chat",_i(e.activeSessionId,ee?.urlMode??"push"))}async function Tn(ee){try{const me=await Wt().getSession(ee);return!me.archived&&On.has(ee)?"not-found":(e.sessions.some(Me=>Me.id===me.id)||(Ie.add(me.id),p(me)),"ok")}catch(me){return ko(me)&&me.code===N_?"not-found":"error"}}async function Un(ee){try{const me=await Wt().getSession(ee);return me.archived||On.has(ee)?"stale":(e.sessions.some(Me=>Me.id===me.id)||p(me),"ok")}catch(me){return ko(me)&&me.code===N_?"stale":"retry"}}function Kn(){if(RS(mo())){e.mainView="sessionAdmin";return}e.mainView="chat";const ee=zS(mo());if(ee===void 0){k(void 0);return}if(ee!==e.activeSessionId){if(e.sessions.some(me=>me.id===ee)){Ki(ee,{urlMode:"none",skipTrack:!0});return}(async()=>{if(await Tn(ee)==="ok"){await Ki(ee,{urlMode:"none",skipTrack:!0});return}const me=e.sessions[0];me?await Ki(me.id,{urlMode:"replace",skipTrack:!0}):(k(void 0),_i(void 0,"replace"))})()}}let Pi=!1;function Io(){Pi||typeof window>"u"||(Pi=!0,window.addEventListener("popstate",Kn))}async function Ki(ee,me){const Me=me?.source??"sidebar";if(!e.sessions.some(ft=>ft.id===ee)){const ft=++ie;if(await Tn(ee)!=="ok"||ft!==ie)return}const Re=S(ee),Qe=!Re&&u.has(ee);u.delete(ee);const Je=e.activeSessionId!==ee;try{(me?.urlMode??"push")==="push"&&(e.mainView="chat"),_i(ee,me?.urlMode??"push"),e.sessionLoading=!Re&&!Qe,k(ee),!me?.skipTrack&&Je&&void 0,e.unreadBySession[ee]&&(e.unreadBySession={...e.unreadBySession,[ee]:!1},ae({[ee]:!1})),Hs().clearFileDiff();const ft=e.sessions.find(vt=>vt.id===ee);if(ft){const vt=R(ft);e.activeWorkspaceId!==vt&&st(vt)}if(Re){if(await T(ee)==="not-found")return}else if(await A(ee,{skipStatusRefresh:me?.skipStatusRefresh===!0})==="not-found")return;be(ee,{skipStatus:me?.skipStatusRefresh===!0})}catch(ft){r("selectSession",ft,{sessionId:ee})}finally{e.activeSessionId===ee&&(e.sessionLoading=!1)}}async function Ti(ee,me,Me){const Re=m8(ee);e.inFlightBySession={...e.inFlightBySession,[ee]:!0};const Qe=y();let Je=e.pendingThinkingBySession[ee];try{const ft=Wt(),vt=[];if(me&&vt.push({type:"text",text:me}),vt.push(...T2(Me)),vt.length===0)return e.inFlightBySession={...e.inFlightBySession,[ee]:!1},"rejected";const Pt={id:Qe,sessionId:ee,role:"user",content:vt,createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};w(ee,ya=>[...ya,Pt]);const fn=e.sessions.find(ya=>ya.id===ee),dn=(fn?.model&&fn.model.length>0?fn.model:e.defaultModel)??void 0,ui=e.planArmedBySession[ee]??!1,Ln=ui||(e.planModeBySession[ee]??!1),Sn=e.swarmModeBySession[ee]??!1,fi=e.goalModeBySession[ee]??!1;ui&&(e.planArmedBySession={...e.planArmedBySession,[ee]:!1},$(),(e.planModeBySession[ee]??!1)||(await ft.updateSession(ee,{planMode:!0}),e.planModeBySession={...e.planModeBySession,[ee]:!0})),fi&&me&&(await ft.updateSession(ee,{goalObjective:me.trim(),planMode:!1}),e.planModeBySession={...e.planModeBySession,[ee]:!1});const Ui=await s.resolveThinkingForPrompt(ee,dn)??e.thinking;Je=e.pendingThinkingBySession[ee];const Fr=await ft.submitPrompt(ee,{content:vt,model:dn,thinking:Ui,permissionMode:e.permission,planMode:Ln&&!(fi&&me),swarmMode:Sn});return Ui!==void 0&&Au(e,ee,Je),fi&&me&&(e.goalModeBySession={...e.goalModeBySession,[ee]:!1},P()),e.promptIdBySession={...e.promptIdBySession,[ee]:Fr.promptId},Ne(ee,Qe,Fr.promptId,Fr.userMessageId),b()?.bindNextPromptId(ee,Fr.promptId),"ok"}catch(ft){return e.inFlightBySession={...e.inFlightBySession,[ee]:!1},w(ee,vt=>vt.some(Pt=>Pt.id===Qe)?vt.filter(Pt=>Pt.id!==Qe||Pt.promptId!==void 0||Pt.userMessageId!==void 0):vt),Au(e,ee,Je)&&x(ee),r("sendPrompt",ft,{sessionId:ee}),ko(ft)?"rejected":"uncertain"}finally{v8(ee,Re)}}async function Qs(ee,me){const Me=e.activeSessionId;if(Me){if(a.value!=="idle"||e.inFlightBySession[Me]){wi(ee,me);return}if((e.queuedBySession[Me]?.length??0)>0||(iu.get(Me)??0)>0){wi(ee,me),$o(Me);return}await Ti(Me,ee,me)}}async function Li(ee,me,Me){iu.set(ee,(iu.get(ee)??0)+1);try{if(a.value==="idle"&&!e.inFlightBySession[ee])return await Ti(ee,me,Me);const Re=[];me&&Re.push({type:"text",text:me}),Re.push(...T2(Me));const Qe=y(),Je={id:Qe,sessionId:ee,role:"user",content:Re,createdAt:new Date().toISOString(),metadata:{"kimiWeb.optimisticUserMessage":!0}};w(ee,Pt=>[...Pt,Je]);const ft=m8(ee);let vt=!1;try{const Pt=Wt(),fn=e.sessions.find(fi=>fi.id===ee),dn=(fn?.model&&fn.model.length>0?fn.model:e.defaultModel)??void 0,ui=await s.resolveThinkingForPrompt(ee,dn)??e.thinking,Ln=e.pendingThinkingBySession[ee];vt=!0;const Sn=await Pt.submitPrompt(ee,{content:Re,model:dn,thinking:ui,permissionMode:e.permission,planMode:e.planModeBySession[ee]??!1,swarmMode:e.swarmModeBySession[ee]??!1});if(ui!==void 0&&Au(e,ee,Ln),Ne(ee,Qe,Sn.promptId,Sn.userMessageId),Sn.status!=="queued")return e.promptIdBySession={...e.promptIdBySession,[ee]:Sn.promptId},b()?.bindNextPromptId(ee,Sn.promptId),"ok";try{await Pt.steerPrompts(ee,[Sn.promptId])}catch{}return"ok"}catch(Pt){return w(ee,fn=>fn.filter(dn=>dn.id!==Qe||dn.promptId!==void 0||dn.userMessageId!==void 0)),r("steer",Pt,{sessionId:ee}),ko(Pt)||!vt?"rejected":"uncertain"}finally{v8(ee,ft)}}finally{const Re=(iu.get(ee)??1)-1;Re<=0?iu.delete(ee):iu.set(ee,Re)}}function an(ee){(iu.get(ee)??0)>0||a.value!=="idle"||e.inFlightBySession[ee]||$o(ee)}async function to(ee,me){const Me=e.activeSessionId;if(!Me)return;const Qe=(vp.get(Me)??Promise.resolve()).catch(()=>{}).then(()=>Jn(Me,ee,me));return vp.set(Me,Qe),Qe}async function Jn(ee,me,Me){const Re=e.queuedBySession[ee]??[],Qe=[],Je=[];for(const dn of Re){const ui=dn.text.trim();ui&&Qe.push(ui),dn.attachments?.length&&Je.push(...dn.attachments)}const ft=me.trim();if(ft&&Qe.push(ft),Me?.length&&Je.push(...Me),Qe.length===0&&Je.length===0)return;Re.length>0&&(e.queuedBySession={...e.queuedBySession,[ee]:[]});const vt=Qe.join(` - -`),Pt=()=>{if(Re.length===0)return;const dn=e.queuedBySession[ee]??[];e.queuedBySession={...e.queuedBySession,[ee]:[...Re,...dn]}},fn=await Li(ee,vt,Je);fn==="rejected"&&Pt(),fn!=="ok"&&an(ee)}async function Wo(ee){const me=e.activeSessionId;if(!me)return;const Me=(e.queuedBySession[me]??[])[ee];if(Me===void 0)return;const Re=Me.id??Me.text,Je=(vp.get(me)??Promise.resolve()).catch(()=>{}).then(()=>Mn(me,Re));return vp.set(me,Je),Je}async function Mn(ee,me){const Me=e.queuedBySession[ee]??[],Re=Me.findIndex(Pt=>(Pt.id??Pt.text)===me),Qe=Re>=0?Me[Re]:void 0;if(Qe===void 0)return;const Je=Qe.attachments??[];if(Qe.text.trim().length===0&&Je.length===0)return;const ft=[...Me];ft.splice(Re,1),e.queuedBySession={...e.queuedBySession,[ee]:ft};const vt=await Li(ee,Qe.text,Je);if(vt==="rejected"&&e.sessions.some(Pt=>Pt.id===ee)){const fn=[...e.queuedBySession[ee]??[]];fn.splice(Math.min(Re,fn.length),0,Qe),e.queuedBySession={...e.queuedBySession,[ee]:fn}}vt!=="ok"&&an(ee)}async function Ni(ee,me){try{const Re=await Wt().uploadFile({file:ee,name:me});return{fileId:Re.id,name:Re.name,mediaType:Re.mediaType}}catch(Me){return r("uploadImage",Me),null}}function wi(ee,me){const Me=e.activeSessionId;if(!Me)return;const Re=e.queuedBySession[Me]??[],Qe={text:ee,attachments:me,id:mhe()};e.queuedBySession={...e.queuedBySession,[Me]:[...Re,Qe]}}function $o(ee){if((iu.get(ee)??0)>0)return;const[me,...Me]=e.queuedBySession[ee]??[];me!==void 0&&(e.queuedBySession={...e.queuedBySession,[ee]:Me},Ti(ee,me.text,me.attachments).then(Re=>{if(Re==="ok"){xd.delete(ee);return}if(Re==="uncertain"){xd.delete(ee);return}if(!e.sessions.some(Pt=>Pt.id===ee)){xd.delete(ee);return}const Qe=me.id??me.text,Je=xd.get(ee),ft=Je!==void 0&&Je.key===Qe?Je.count+1:1;if(ft>=hhe){xd.delete(ee),(e.queuedBySession[ee]?.length??0)>0&&$o(ee);return}xd.set(ee,{key:Qe,count:ft});const vt=e.queuedBySession[ee]??[];e.queuedBySession={...e.queuedBySession,[ee]:[me,...vt]}}))}function $s(ee,me){const Me=e.inFlightBySession[ee]===!0;if(e.inFlightBySession={...e.inFlightBySession,[ee]:!1},e.promptIdBySession[ee]!==void 0){const Qe={...e.promptIdBySession};delete Qe[ee],e.promptIdBySession=Qe}return(Me||me?.turnWasActive===!0||(e.turnActiveBySession[ee]??!1))&&$o(ee),Me}function Vi(ee,me){me.inFlightTurn!==null&&me.busy||$s(ee)}async function Cn(){const ee=e.activeSessionId;if(!ee)return!1;const me=e.sessions.find(vt=>vt.id===ee);let Me=e.promptIdBySession[ee];if(Me===void 0){const vt=me?.currentPromptId;vt!==void 0&&vt.length>0&&!vt.startsWith("pr_")&&(Me=vt)}const Re=Wt();let Qe=!1;const Je=()=>{e.inFlightBySession={...e.inFlightBySession,[ee]:!1},e.turnActiveBySession={...e.turnActiveBySession,[ee]:!1}};if(Me!==void 0)try{if((await Re.abortPrompt(ee,Me)).aborted)return!0;Qe=!0;const Pt={...e.promptIdBySession};delete Pt[ee],e.promptIdBySession=Pt,Je()}catch(vt){if(ko(vt)&&vt.code===she){Qe=!0;const Pt={...e.promptIdBySession};delete Pt[ee],e.promptIdBySession=Pt,Je()}else return r("abortCurrentPrompt",vt,{sessionId:ee}),!1}if(Qe||!((e.inFlightBySession[ee]??!1)||(e.turnActiveBySession[ee]??!1)||(me?.mainTurnActive??!1)))return!1;try{return(await Re.abortSession(ee)).aborted===!0}catch(vt){return r("abortCurrentPrompt",vt,{sessionId:ee}),!1}}async function Rs(ee,me){const Me=e.activeSessionId;if(!Me||Fm[ee])return;Fm[ee]=!0;const Re=e.approvalsBySession[Me]?.find(Qe=>Qe.approvalId===ee&&Qe.toolName==="ExitPlanMode")?.toolCallId;try{const Qe=Wt(),Je={decision:me.decision,scope:me.scope,feedback:me.feedback,selectedLabel:me.selectedLabel};await Qe.respondApproval(Me,ee,Je),qs().removePendingApproval(Me,ee),Re!==void 0&&(N(Me,Re,{state:me.decision,selectedOption:me.selectedLabel,feedback:me.feedback}),M(Me,Re))}catch(Qe){x3(Qe)?(qs().removePendingApproval(Me,ee),Re!==void 0&&M(Me,Re)):r("respondApproval",Qe,{sessionId:Me})}finally{delete Fm[ee]}}async function qo(ee,me){const Me=e.activeSessionId;if(Me&&!pd[ee]){pd[ee]="answer";try{await Wt().respondQuestion(Me,ee,me),qs().removePendingQuestion(Me,ee)}catch(Re){x3(Re)?qs().removePendingQuestion(Me,ee):r("respondQuestion",Re,{sessionId:Me})}finally{delete pd[ee]}}}async function ar(ee){const me=e.activeSessionId;if(me&&!pd[ee]){pd[ee]="dismiss";try{await Wt().dismissQuestion(me,ee),qs().removePendingQuestion(me,ee)}catch(Me){x3(Me)?qs().removePendingQuestion(me,ee):r("dismissQuestion",Me,{sessionId:me})}finally{delete pd[ee]}}}async function ks(ee){const me=e.activeSessionId;if(me&&!S3[ee]){S3[ee]=!0;try{const Me=Wt(),Re=(e.tasksBySession[me]??[]).find(Je=>Je.id===ee)?.backgroundTaskId;await Me.cancelTask(me,Re??ee);const Qe=e.tasksBySession[me]??[];e.tasksBySession={...e.tasksBySession,[me]:Qe.map(Je=>(Re!==void 0?Je.backgroundTaskId===Re:Je.id===ee||Je.backgroundTaskId===ee)?{...Je,status:"cancelled",completedAt:Je.completedAt??new Date().toISOString(),completedAtEstimated:Je.completedAt===void 0?!0:Je.completedAtEstimated}:Je)}}catch(Me){dhe(Me)||r("cancelTask",Me,{sessionId:me})}finally{delete S3[ee]}}}function yi(ee){const me=e.activeSessionId;me?(e.planArmedBySession={...e.planArmedBySession,[me]:ee},$(),!ee&&(e.planModeBySession[me]??!1)&&(e.planModeBySession={...e.planModeBySession,[me]:!1},I({planMode:!1},me))):Z.planMode=ee}function Vn(){const ee=e.activeSessionId,me=ee?(e.planArmedBySession[ee]??!1)||(e.planModeBySession[ee]??!1):Z.planMode;yi(!me)}function ji(ee){const me=e.activeSessionId;me?(e.swarmModeBySession={...e.swarmModeBySession,[me]:ee},W(),I({swarmMode:ee})):Z.swarmMode=ee}async function Fi(){const ee=e.activeSessionId,Me=!(ee?e.swarmModeBySession[ee]??!1:Z.swarmMode);Me&&e.permission==="manual"&&!await n({title:gi("workspace.swarmEnableTitle"),message:gi("workspace.swarmEnableConfirm"),variant:"primary"})||ji(Me)}function bs(ee){const me=e.activeSessionId;me?(e.goalModeBySession={...e.goalModeBySession,[me]:ee},P()):Z.goalMode=ee}function As(){const ee=e.activeSessionId,me=ee?e.goalModeBySession[ee]??!1:Z.goalMode;bs(!me)}async function Eo(ee){const me=ee.trim();if(!me||e.permission==="manual"&&!await n({title:gi("workspace.goalStartTitle"),message:gi("workspace.goalStartConfirm",{objective:me}),variant:"primary"}))return null;let Me=e.activeSessionId,Re=null;if(!Me){const Qe=e.activeWorkspaceId,Je=Qe&&H.value.some(ft=>ft.id===Qe)?Qe:H.value[0]?.id??null;if(!Je)return null;try{Me=await Yn(Je)??void 0,Re=Me??null}catch(ft){return r("createGoal",ft),null}if(!Me)return null}try{await Wt().updateSession(Me,{goalObjective:me,planMode:!1}),e.planModeBySession={...e.planModeBySession,[Me]:!1}}catch(Qe){return r("createGoal",Qe,{sessionId:Me,message:oe(Qe)}),Re}return e.goalModeBySession[Me]&&(e.goalModeBySession={...e.goalModeBySession,[Me]:!1},P()),e.activeSessionId===Me?await Qs(me):await Ti(Me,me),Re}function Tr(ee){const me=e.activeSessionId;me&&Promise.resolve(Wt().updateSession(me,{goalControl:ee})).catch(Me=>{r("controlGoal",Me,{sessionId:me,message:oe(Me)})})}function Lr(ee){e.permission=ee,j(ee),I({permissionMode:ee})}function jl(ee){const me=[...e.warnings];me.splice(ee,1),e.warnings=me}async function Nr(ee,me){try{await Wt().updateSession(ee,{title:me}),d(ee,Re=>({...Re,title:me})),e.doneSessions.some(Re=>Re.id===ee)&&(e.doneSessions=e.doneSessions.map(Re=>Re.id===ee?{...Re,title:me}:Re))}catch(Me){r("renameSession",Me,{sessionId:ee})}}async function Di(ee){const me=await Wt().generateSessionTitle(ee,{force:!0,source:"digest"});return me===null?l({severity:"info",title:gi("sidebar.genTitleUnavailable")}):e.doneSessions.some(Me=>Me.id===ee)&&(e.doneSessions=e.doneSessions.map(Me=>Me.id===ee?{...Me,title:me}:Me)),me}async function Xn(ee,me){const Me=e.workspaces.find(Qe=>Qe.id===ee)?.root,Re=()=>{e.workspaces=e.workspaces.map(Qe=>Qe.id===ee?{...Qe,name:me}:Qe)};try{if(await Wt().updateWorkspace(ee,{name:me}),Me!==void 0){const Qe=Im();Me in Qe&&(delete Qe[Me],g_(Qe))}Re()}catch(Qe){if(Me!==void 0&&ko(Qe)&&Qe.code===rhe){g_({...Im(),[Me]:me}),Re();return}r("renameWorkspace",Qe)}}async function Cs(ee){const me=e.workspaces.find(Je=>Je.id===ee)?.root??z.value.find(Je=>Je.id===ee)?.root??ee,Me=e.activeSessionId?e.sessions.find(Je=>Je.id===e.activeSessionId):void 0,Re=e.activeWorkspaceId===ee||e.activeWorkspaceId===me,Qe=!!(Me&&(Me.cwd===me||Me.workspaceId===ee||R(Me)===ee));me&&!e.hiddenWorkspaceRoots.includes(me)&&(e.hiddenWorkspaceRoots=[...e.hiddenWorkspaceRoots,me],Y(e.hiddenWorkspaceRoots));try{await Wt().deleteWorkspace(ee)}catch(Je){bu("[kimi-code] deleteWorkspace registry cleanup failed for",ee,Je)}if(e.workspaces=e.workspaces.filter(Je=>Je.id!==ee&&Je.root!==me),Re||Qe){const Je=H.value[0]?.id??null;if(e.activeWorkspaceId=Je,Je)V(Je);else try{_r(un.activeWorkspace)}catch{}}(Re||Qe)&&(k(void 0),e.sessionLoading=!1,Hs().clearFileDiff(),_i(void 0,"replace"))}const Uo=500,On=new Set;function Hi(ee){if(!On.has(ee)){if(On.size>=Uo){const me=On.values().next().value;me!==void 0&&On.delete(me)}On.add(ee)}}const Wi=new Set;function rs(ee){if(!Wi.has(ee)){if(Wi.size>=Uo){const me=Wi.values().next().value;me!==void 0&&Wi.delete(me)}Wi.add(ee)}}const jn=new Map;function Ke(ee){if(jn.has(ee)&&jn.delete(ee),jn.size>=Uo){const me=jn.keys().next().value;me!==void 0&&jn.delete(me)}jn.set(ee,Date.now())}const Ue=new Set,yt=new Set;async function xt(ee,me){const Me=new Set(ee);if(me){for(const ft of ee)Hi(ft);const Qe=new Date().toISOString(),Je=e.sessions.filter(ft=>Me.has(ft.id));Je.length>0&&(e.doneSessions=[...Je.map(ft=>({...ft,archived:!0,archivedAt:Qe})),...e.doneSessions.filter(ft=>!Me.has(ft.id))]);for(const ft of ee)g(ft),xv.delete(ft);if(e.activeSessionId!==void 0&&Me.has(e.activeSessionId)){const ft=e.sessions[0];ft?await Ki(ft.id,{urlMode:"replace",skipTrack:!0}):(k(void 0),_i(void 0,"replace"))}return}for(const Qe of ee)On.delete(Qe),rs(Qe),Ke(Qe);const Re=e.doneSessions.filter(Qe=>Me.has(Qe.id));e.doneSessions=e.doneSessions.filter(Qe=>!Me.has(Qe.id));for(const Qe of Re)e.sessions.some(Je=>Je.id===Qe.id)||(Ie.add(Qe.id),h({...Qe,archived:!1}))}async function rn(ee){try{const me=Wt();yt.delete(ee),Ue.add(ee);const Me=e.sessions.find(Je=>Je.id===ee),Re=Me!==void 0?R(Me):void 0,Qe=Re!==void 0?$t(Re).length:0;await me.archiveSession(ee),await xt([ee],!0),Me!==void 0&&Re!==void 0&&jt(Re,ee,Me.updatedAt,Qe),Ue.delete(ee),yt.delete(ee)}catch(me){Ue.delete(ee),yt.delete(ee)||r("archiveSession",me,{sessionId:ee})}}async function Zi(ee,me){if(jn.has(ee)){let Je;try{Je=(await Wt().getSession(ee)).archived}catch{return!1}if(!Je)return!1}Ue.delete(ee)&&yt.add(ee),Wi.delete(ee),jn.delete(ee),Hi(ee);const Me=e.sessions.find(Je=>Je.id===ee);if(Me===void 0&&e.activeSessionId!==ee)return!0;const Re=me??(Me!==void 0?R(Me):void 0),Qe=Re!==void 0?$t(Re).length:0;return await xt([ee],!0),Me!==void 0&&Re!==void 0&&jt(Re,ee,Me.updatedAt,Qe),!0}async function Gi(ee){if(pe)return!1;const me=ee??e.activeSessionId;if(!me){const Re=gi("commands.export.noSession");return Ll("export:failed",{status:"no-session"}),r("exportSession",new Error(Re),{message:Re}),!1}pe=!0;const Me=Date.now();Ll("export:start",{sessionId:me});try{const Re=qfe(),{blob:Qe,fileName:Je}=await Wt().exportSession(me,Re,{desktop:bf});if(typeof document>"u")throw new Error("Document is unavailable");const ft=URL.createObjectURL(Qe);let vt;try{vt=document.createElement("a"),vt.href=ft,vt.download=Je,document.body.append(vt),vt.click()}finally{vt?.remove(),setTimeout(()=>{try{URL.revokeObjectURL(ft)}catch{}},0)}return Ll("export:accepted",{sessionId:me,status:"accepted",zipBytes:Qe.size,durationMs:Date.now()-Me}),!0}catch(Re){const Qe=typeof Re=="object"&&Re!==null?Re:void 0;return Ll("export:failed",{sessionId:me,status:"failed",durationMs:Date.now()-Me,errorName:typeof Qe?.name=="string"?Qe.name:typeof Re,errorCode:typeof Qe?.code=="number"?Qe.code:void 0,requestId:typeof Qe?.requestId=="string"?Qe.requestId:void 0,phase:typeof Qe?.phase=="string"?Qe.phase:void 0,httpStatus:typeof Qe?.status=="number"?Qe.status:void 0}),r("exportSession",Re,{sessionId:me,...ko(Re)&&Re.code===zY?{message:gi("commands.export.tooLarge",{sessionId:me})}:{}}),!1}finally{pe=!1}}async function oo(ee){try{const me=await Wt().restoreSession(ee);return h(me),await xt([ee],!1),!0}catch(me){return r("restoreSession",me,{sessionId:ee}),!1}}function qi(ee){return Wt().listSessions({archivedOnly:!0,beforeId:ee?.beforeId,pageSize:ee?.pageSize??50})}async function vo(){try{await Wt().logout(),await se(),await mn()}catch(ee){r("logout",ee)}}function so(ee){const me=e.activeSessionId;me&&Wt().compactSession(me,ee).catch(Me=>{r("compact",Me,{sessionId:me})})}async function Ro(ee){const me=ee??e.activeSessionId;if(me)try{const Me=await Wt().forkSession(me);h(Me),await Ki(Me.id,{skipTrack:!0})}catch(Me){r("fork",Me,{sessionId:me})}}async function ot(ee=1){const me=e.activeSessionId;if(!me)return null;const Me=e.messagesBySession[me]??[];let Re=-1;for(let vt=Me.length-1;vt>=0;vt--){const Pt=Me[vt];if(Pt.role==="user"&&!(Pt.metadata?.origin&&Pt.metadata.origin.kind!=="user")){Re=vt;break}}const Qe=Re>=0?Me[Re].content.filter(vt=>vt.type==="text").map(vt=>vt.text).join(` -`):null,Je=ee===1&&Re>=0&&Me.slice(Re+1).every(vt=>vt.role!=="user"),ft=Je?e.sessions.find(vt=>vt.id===me):void 0;if(Je&&(e.messagesBySession={...e.messagesBySession,[me]:Me.slice(0,Re)},ft!==void 0)){const vt={...ft};delete vt.lastTurnReason,h(vt)}try{return await Wt().undoSession(me,ee),await A(me),{text:Qe}}catch(vt){return Je&&(e.messagesBySession={...e.messagesBySession,[me]:Me},ft!==void 0&&h(ft),await A(me).catch(()=>{})),r("undo",vt,{sessionId:me}),null}}function xe(ee){const me=e.activeSessionId;if(!me)return;const Me=e.queuedBySession[me]??[];if(ee<0||ee>=Me.length)return;const Re=[...Me];Re.splice(ee,1),e.queuedBySession={...e.queuedBySession,[me]:Re}}function je(ee,me){const Me=e.activeSessionId;if(!Me)return;const Re=e.queuedBySession[Me]??[];if(ee===me||ee<0||ee>=Re.length||me<0||me>=Re.length)return;const Qe=[...Re],[Je]=Qe.splice(ee,1);Je!==void 0&&(Qe.splice(me,0,Je),e.queuedBySession={...e.queuedBySession,[Me]:Qe})}async function Dn(ee){const me=e.activeSessionId;if(!me)return[];try{return(await Wt().listDirectory(me,{path:ee,includeGitStatus:!0})).items}catch{return[]}}async function vn(ee,me){const Me=e.activeSessionId;if(!Me){let Re=ee;if(!Ss(ee)){const Qe=e.activeWorkspaceId,Je=Qe&&H.value.some(vt=>vt.id===Qe)?Qe:H.value[0]?.id??null,ft=Je?z.value.find(vt=>vt.id===Je)?.root:void 0;if(!ft)return!0;Re=`${ft.replace(/[\\/]+$/,"")}/${ee}`}try{return await ii(Re),!0}catch(Qe){return!(ko(Qe)&&Qe.code===F_)}}try{if(Ss(ee))return await ii(ee),!0;const Re=Wt();return me==="folder"?await Re.listDirectory(Me,{path:ee}):await Re.readFile(Me,{path:ee,length:1}),!0}catch(Re){return!(ko(Re)&&Re.code===F_)}}async function ii(ee){return Wt().readHostFileContent(ee)}const ws=10485760;function xs(ee){const me=e.activeSessionId;return me?Wt().getFileDownloadUrl(me,ee):null}async function ro(ee,me){const Me=e.activeSessionId;if(!Me)return!1;try{return await Wt().openFile(Me,{path:ee,line:me}),!0}catch(Re){return r("openFile",Re,{sessionId:Me}),!1}}async function ai(ee){const me=e.activeSessionId;if(!me)return;const Me=O.value.cwd||".";try{await Wt().openInApp(me,ee,Me)}catch(Re){r("openInApp",Re,{sessionId:me})}}async function Ys(ee){const me=e.activeSessionId;if(!me)return!1;try{return await Wt().revealFile(me,{path:ee}),!0}catch(Me){return r("revealFile",Me,{sessionId:me}),!1}}function Ss(ee){return ee.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(ee)||ee.startsWith("\\\\")}async function el(ee){if(/^(https?:|data:|blob:)/i.test(ee))return ee;const me=e.activeSessionId;if(!me)return ee;let Me=ee;if(Ss(Me)){const Re=e.sessions.find(Je=>Je.id===me)?.cwd,Qe=Re?d9(Me,Re):null;if(Qe)Me=Qe;else try{const Je=await ii(Me);return!Je.isBinary||Je.encoding!=="base64"?ee:`data:${Je.mime};base64,${Je.content}`}catch{return ee}}try{const Qe=await Wt().readFile(me,{path:Me,length:ws});return!Qe.isBinary||Qe.encoding!=="base64"||Qe.truncated?ee:`data:${Qe.mime};base64,${Qe.content}`}catch{return ee}}let ur=!1;async function tl(ee){const me=e.sessions.find(Re=>Re.id===e.activeSessionId),Me=me===void 0?e.activeWorkspaceId:R(me);if(!Me)return[];try{const Re=Wt();if(!ur)try{return(await Re.suggestFiles(Me,{query:ee,limit:20})).items.map(ft=>({path:ft.path,name:ft.name,kind:ft.kind,matchPositions:ft.matchPositions}))}catch(Je){if(!ko(Je)||Je.code!==404)throw Je;ur=!0}return(await Re.searchFiles(Me,{query:ee,limit:20})).items.map(Je=>({path:Je.path,name:Je.name,kind:Je.kind,matchPositions:Je.matchPositions}))}catch{return[]}}return{checkAuth:se,probeManagedMembership:Ae,loadConfig:G,updateConfig:le,listAllSessionsGlobal:ke,load:mn,refreshServerMeta:bn,loadWorkspaces:zn,loadMoreSessions:Ct,loadAllSessions:kn,ensureFlatSessions:Le,loadMoreFlatSessions:ze,ensureDoneSessions:Tt,loadMoreDoneSessions:on,selectWorkspace:st,openWorkspace:et,upsertWorkspacePreserveOrder:Nt,applyWorkspaceEvent:Lt,clearActiveSession:qn,openWorkspaceDraft:So,startSessionAndSendPrompt:Ir,startSessionAndActivateSkill:_o,startSessionAndOpenSideChat:It,addWorkspaceByPath:ms,browseFs:Er,getFsHome:go,writeSessionUrl:_i,openSessionAdmin:Mo,closeSessionAdmin:ys,fetchSessionIntoList:Tn,onSessionRoutePopState:Kn,bindSessionRoute:Io,selectSession:Ki,submitPromptInternal:Ti,finishPromptLocal:$s,maybeGenerateSessionTitle:ghe,localTurnStartState:vhe,isLocalTurnSnapshotCurrent:khe,afterLocalTurnStartsSettle:bhe,handleSessionSnapshot:Vi,sendPrompt:Qs,steerPrompt:to,steerQueued:Wo,uploadImage:Ni,enqueue:wi,unqueue:xe,reorderQueue:je,abortCurrentPrompt:Cn,respondApproval:Rs,respondQuestion:qo,dismissQuestion:ar,pendingQuestionActions:pd,pendingApprovalActions:Fm,cancelTask:ks,setPlanMode:yi,togglePlanMode:Vn,setSwarmMode:ji,toggleSwarmMode:Fi,setGoalMode:bs,toggleGoalMode:As,createGoal:Eo,controlGoal:Tr,setPermission:Lr,dismissWarning:jl,renameSession:Nr,regenerateSessionTitle:Di,renameWorkspace:Xn,deleteWorkspace:Cs,archiveSession:rn,applySessionsArchivedLocally:xt,applyRemoteSessionArchived:Zi,exportSession:Gi,restoreSession:oo,loadArchivedSessions:qi,logout:vo,compact:so,forkSession:Ro,undo:ot,listDir:Dn,readHostFileContent:ii,probeWorkspacePath:vn,getFileDownloadUrl:xs,openWorkspaceFile:ro,openInApp:ai,revealWorkspaceFile:Ys,resolveImageUrl:el,searchFiles:tl,loadOlderMessages:te,refreshSessionSidecars:be,isStartingFirstPrompt:()=>wa.size>0}}const Che=20,whe=300,xhe=1e4,B_=5e3;function N$(e){const[t,n,i]=e.split("-").map(Number);return new Date(t??0,(n??1)-1,i??1,0,0,0,0).getTime()}function F$(e){const[t,n,i]=e.split("-").map(Number);return new Date(t??0,(n??1)-1,i??1,23,59,59,999).getTime()}function She(e,t,n){return{workspaceIds:e.workspaceIds.length>0?[...e.workspaceIds]:void 0,archived:e.status==="all"?"all":e.status==="done",updatedAfter:e.updatedFrom!==""?N$(e.updatedFrom):void 0,updatedBefore:e.updatedTo!==""?F$(e.updatedTo):void 0,sort:"meta.updated_at_desc",page:t,pageSize:n}}function _he(e){return{workspaceIds:e.workspaceIds.length>0?[...e.workspaceIds]:void 0,archived:e.status==="all"?"all":e.status==="done",updatedAfter:e.updatedFrom!==""?N$(e.updatedFrom):void 0,updatedBefore:e.updatedTo!==""?F$(e.updatedTo):void 0,sort:"meta.updated_at_desc"}}function Dm(e){return JSON.stringify([[...e.workspaceIds].toSorted(),e.status,e.updatedFrom,e.updatedTo])}function Mhe(e){const t=jo({filters:{workspaceIds:[],status:"all",updatedFrom:"",updatedTo:""},page:1,pageSize:Che,items:[],total:0,loading:!1,seeded:!1,selectedIds:new Set,selectedArchivedById:new Map,allMatching:!1,materializingAll:!1});let n=0,i=null;async function o(){i!==null&&(clearTimeout(i),i=null);const x=++n;t.loading=!0;try{const _=await Wt().listSessionsV2(She(t.filters,t.page,t.pageSize));if(x!==n)return;t.items=_.items,t.total=_.total;for(const M of _.items)t.selectedArchivedById.has(M.id)&&t.selectedArchivedById.set(M.id,M.meta.archived);const L=Math.max(1,Math.ceil(_.total/t.pageSize));t.page>L&&(t.page=L,o())}catch(_){if(x!==n)return;e.pushOperationFailure("sessionAdmin",_)}finally{x===n&&(t.loading=!1)}}function s(){i!==null&&clearTimeout(i),i=setTimeout(()=>{i=null,o()},whe)}function r(){t.seeded||(t.seeded=!0,o())}async function l(){await o()}function a(x){t.allMatching&&Dm(x)!==Dm(t.filters)&&w(),t.filters.workspaceIds=[...x.workspaceIds],t.filters.status=x.status,t.filters.updatedFrom=x.updatedFrom,t.filters.updatedTo=x.updatedTo,t.page=1,t.seeded=!0,o()}function u(x){t.allMatching&&w(),t.filters.workspaceIds=[...x],t.page=1,s()}function c(x){t.allMatching&&w(),t.filters.status=x,t.page=1,s()}function d(x,_){t.allMatching&&w(),t.filters.updatedFrom=x,t.filters.updatedTo=_,t.page=1,s()}function h(x){x!==t.page&&(t.page=x,s())}function p(x){x!==t.pageSize&&(t.pageSize=x,t.page=1,s())}function g(x,_){if(t.selectedIds.has(x)){t.selectedIds.delete(x),t.selectedArchivedById.delete(x),t.selectedIds.size===0&&(t.allMatching=!1);return}t.selectedIds.add(x),t.selectedArchivedById.set(x,_)}function m(x){const _=x.length>0&&x.every(L=>t.selectedIds.has(L.id));for(const L of x)_?(t.selectedIds.delete(L.id),t.selectedArchivedById.delete(L.id)):(t.selectedIds.add(L.id),t.selectedArchivedById.set(L.id,L.archived));t.selectedIds.size===0&&(t.allMatching=!1)}function k(x){t.selectedIds=new Set(x.map(_=>_.id)),t.selectedArchivedById=new Map(x.map(_=>[_.id,_.archived])),t.allMatching=!1}function w(){t.selectedIds=new Set,t.selectedArchivedById=new Map,t.allMatching=!1}async function y(){if(t.allMatching||t.materializingAll)return;t.materializingAll=!0;const x=_he(t.filters),_=Dm(t.filters);try{const L=[];let M;for(;;){const N=await Wt().listSessionIdsV2({...x,pageSize:xhe,pageToken:M});if(L.push(...N.items),!N.hasMore||N.nextPageToken===null)break;M=N.nextPageToken}if(Dm(t.filters)!==_)return;for(const N of L)t.selectedIds.add(N.id),t.selectedArchivedById.set(N.id,N.archived);t.allMatching=!0}catch(L){e.pushOperationFailure("sessionAdmin",L)}finally{t.materializingAll=!1}}function b(x){const _=[];for(const[L,M]of t.selectedArchivedById)M===x&&_.push(L);return _}async function A(x,_,L){const M=[];let N=0,I=0;for(let z=0;z<x.length;z+=B_){const H=x.slice(z,z+B_);try{const O=await L(H),R=O.results.filter(j=>j.ok).map(j=>j.id);M.push(...R),N+=O.succeeded,I+=O.failed}catch(O){I+=x.length-z,e.pushOperationFailure(_?"archiveSessions":"restoreSessions",O);break}}if(M.length>0){await e.applySessionsArchivedLocally(M,_);for(const z of M)t.selectedIds.delete(z),t.selectedArchivedById.delete(z);t.selectedIds.size===0&&(t.allMatching=!1),await l()}return{okIds:M,succeeded:N,failed:I}}async function T(x){return A(x,!0,_=>Wt().archiveSessions(_))}async function S(x){return A(x,!1,_=>Wt().restoreSessions(_))}return{state:t,ensureSeeded:r,refresh:l,applyFilters:a,setWorkspaceIds:u,setStatus:c,setTimeRange:d,setPage:h,setPageSize:p,toggleSelection:g,togglePageSelection:m,setSelection:k,clearSelection:w,selectAllMatching:y,selectedIdsByArchived:b,archiveSessions:T,restoreSessions:S}}function Ihe(e){if(e.startsWith("kimi-complete-"))return"turn_complete";if(e.startsWith("kimi-question-"))return"question";if(e.startsWith("kimi-approval-"))return"approval"}function $_(e,t){const n=gs(e);return n===null?t:n==="1"}const Ehe="/favicon.ico",The=lg("kimi.notifications",()=>{const e=K($_(un.notifyEnabled,!0)),t=K($_(un.notifySound,!0)),n=K(typeof Notification<"u"?Notification.permission:"denied");async function i(c){if(!c){e.value=!1,is(un.notifyEnabled,"0");return}if(typeof Notification>"u")return;let d=Notification.permission;if(d==="default")try{d=await Notification.requestPermission()}catch{}n.value=d,d==="granted"&&(e.value=!0,is(un.notifyEnabled,"1"))}function o(c){t.value=c,is(un.notifySound,c?"1":"0")}function s(c,d,h){if(!e.value||typeof Notification>"u")return;const p=Notification.permission;if(p!=="denied"){if(p==="default"){Notification.requestPermission().then(g=>{n.value=g,g==="granted"&&r(c,d,h)});return}r(c,d,h)}}function r(c,d,h){if(!c.isUserWatching)try{const p=new Notification(d.title,{body:d.body,tag:h,icon:Ehe,silent:!t.value}),g=Ihe(h);g!==void 0&&void 0,p.onclick=()=>{try{window.kimiDesktop?.showWindow?.(),window.focus()}catch{}g!==void 0&&void 0,c.onClick(),p.close()}}catch{}}function l(c,d){s(d,ife(gi,d.sessionTitle),`kimi-complete-${c}-${d.promptId??Date.now()}`)}function a(c){s(c,ofe(gi,c.sessionTitle,c.questionPreview),`kimi-question-${c.questionId}`)}function u(c){s(c,sfe(gi,c.sessionTitle,c.toolName),`kimi-approval-${c.approvalId}`)}return{notifyEnabled:e,notifySound:t,notifyPermission:n,setNotifyEnabled:i,setNotifySound:o,maybeNotifyCompletion:l,maybeNotifyQuestion:a,maybeNotifyApproval:u}});function rc(){return The(f1)}const Bm=c1(),D$=un.permission,B$=un.activeWorkspace,$$=un.planArmed,R$=un.swarmMode,z$=un.goalMode,R_=40401,N2=un.onboarded;_r(un.codeFont);_r(un.accent);_r(un.theme);_r(un.thinking);_r(un.notifyOnComplete);_r(un.notifyOnQuestion);_r(un.notifyOnApproval);_r(un.soundOnComplete);function Lhe(){try{const e=gs(D$);if(e==="auto"||e==="yolo"||e==="manual")return e}catch{}return"manual"}function Nhe(e){try{is(D$,e)}catch{}}function $m(e){const t=gs(e);if(!t)return{};try{const n=JSON.parse(t);if(!n||typeof n!="object"||Array.isArray(n))return{};const i={};for(const[o,s]of Object.entries(n))s===!0&&(i[o]=!0);return i}catch{return{}}}function H6(e,t){try{const n={};for(const[i,o]of Object.entries(t))o&&(n[i]=!0);is(e,JSON.stringify(n))}catch{}}function W6(){H6($$,_e.planArmedBySession)}function O$(){H6(R$,_e.swarmModeBySession)}function P$(){H6(z$,_e.goalModeBySession)}function Fhe(){try{return gs(B$)}catch{return null}}const j$=un.hiddenWorkspaces;function Dhe(){try{const e=gs(j$);if(!e)return[];const t=JSON.parse(e);return Array.isArray(t)?t.filter(n=>typeof n=="string"):[]}catch{return[]}}function Bhe(e){try{is(j$,JSON.stringify(e))}catch{}}function $he(e){try{is(B$,e)}catch{}}function Rhe(e,t){if(t&&e.startsWith(t)){const i=e.slice(t.length);return i?`~${i}`:"~"}const n=e.match(/^\/(?:Users|home)\/[^/]+(\/.*)?$/);return n?`~${n[1]??""}`:e}const _e=jo({...Ioe(),get sessions(){return or().sessions},set sessions(e){or().setSessions(e)},get activeSessionId(){return or().activeSessionId},set activeSessionId(e){or().setActiveSessionId(e)},get approvalsBySession(){return qs().approvalsBySession},get questionsBySession(){return qs().questionsBySession},get gitStatusBySession(){return Hs().gitStatusBySession},connected:!1,serverVersion:"",webTitle:"",dangerousBypassAuth:!1,backend:"v1",experimentalFlags:{},workspaceName:"kimi-code",connection:"disconnected",permission:Lhe(),thinking:void 0,thinkingBySession:{},pendingThinkingBySession:{},planModeBySession:$m(un.planMode),planArmedBySession:$m($$),swarmModeBySession:$m(R$),goalModeBySession:$m(z$),loading:!1,sessionLoading:!1,queuedBySession:{},promptIdBySession:{},inFlightBySession:{},unreadBySession:$6(),authReady:!1,defaultModel:null,managedProviderStatus:null,managedUserInfo:null,managedMembership:null,workspaces:[],activeWorkspaceId:Fhe(),fsHome:null,recentRoots:[],hiddenWorkspaceRoots:Dhe(),availableOpenInApps:[],config:null,sideChatMessagesByAgent:{},sideChatSendingByAgent:{},sideChatUserMessageIdsBySession:{},messagesLoadingMoreBySession:{},messagesHasMoreBySession:{},messagesLoadMoreErrorBySession:{},sessionsHasMoreByWorkspace:{},sessionsLoadingMoreByWorkspace:{},sessionsCursorByWorkspace:{},sessionsInitialCountByWorkspace:{},sessionsFullyLoaded:!1,flatSessionsNextPageToken:null,flatSessionsHasMore:!0,flatSessionsLoading:!1,flatSessionsLoadingMore:!1,flatSessionsSeeded:!1,flatSessionsFrontier:null,doneSessions:[],doneSessionsNextPageToken:null,doneSessionsHasMore:!0,doneSessionsLoading:!1,doneSessionsLoadingMore:!1,doneSessionsSeeded:!1,draftEntry:"newChat",mainView:"chat"}),Cu=jo({}),q6=jo({}),zp=new Map,yp=new Map;function zhe(e,t){return`${e}\0${t??"*"}`}function H$(e,t,n){q6[t]=n;const i=Cu[e]?.[t];i&&(Cu[e]={...Cu[e],[t]:{...i,review:n}})}async function I0(e,t){if(t!==void 0){I0(e);return}const n=zhe(e,t),i=(zp.get(n)??0)+1;zp.set(n,i),t!==void 0&&yp.set(e,(yp.get(e)??0)+1);const o=yp.get(e)??0;try{const s=await Wt().getSessionPlans(e,{agentId:"main",toolCallId:t});if(zp.get(n)!==i||t===void 0&&(yp.get(e)??0)!==o||!_e.sessions.some(l=>l.id===e))return;const r=Object.fromEntries(s.map(l=>[l.toolCallId,l]));for(const[l,a]of Object.entries(r)){const u=q6[l];u&&(!a.review||a.review.state==="pending")&&(r[l]={...a,review:u})}Cu[e]=t===void 0?r:{...Cu[e],...r}}catch(s){bu("[refreshSessionPlans] plan history unavailable for",e,s)}}function Ohe(e){const t=`${e}\0`;for(const n of zp.keys())n.startsWith(t)&&zp.delete(n);yp.delete(e),delete Cu[e]}function Phe(e){delete Cu[e]}const ag=jo({planMode:!1,swarmMode:!1,goalMode:!1});function U6(e){_e.sessions=e}function m9(e,t){_e.sessions=_e.sessions.map(n=>n.id===e?t(n):n)}function jhe(e){_e.sessions=VB(_e.sessions,e)}function Hhe(e){_e.sessions=[..._e.sessions,e]}function Whe(e){_e.sessions=_e.sessions.filter(t=>t.id!==e)}function W$(){const e=_e.activeSessionId;e&&_e.unreadBySession[e]&&typeof document<"u"&&document.visibilityState==="visible"&&(_e.unreadBySession[e]=!1,R6({[e]:!1}))}typeof window<"u"&&window.addEventListener("storage",e=>{e.key===un.unread&&(_e.unreadBySession=$6(),W$())});function y8(){if(cl===null||!cl.health().stale)return;Ll("ws:stale-reconnect",{sessionId:_e.activeSessionId,status:"stale"}),Wfe("ws: stale socket on focus, reconnecting",{activeSessionId:_e.activeSessionId}),cl.reconnect();const e=_e.activeSessionId;e&&R2.request(e)}typeof document<"u"&&document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"&&(W$(),y8())});typeof window<"u"&&(window.addEventListener("focus",y8),window.addEventListener("online",y8));function K6(e){_e.activeSessionId=e}function qhe(e){Or(_e.messagesBySession,e)}function Uhe(e,t){_e.messagesBySession[e]=t}function q$(e,t){_e.messagesBySession[e]=t(_e.messagesBySession[e]??[])}function Khe(e){delete _e.messagesBySession[e]}function V6(e){cl?.unsubscribe(e),D2.forgetSession(e),Ws.clearSideChatForSession(e),b8.delete(e),m1e(e),Nh.discard(({meta:t})=>t.sessionId===e),Whe(e),Khe(e),Ohe(e),qs().clearSessionApprovals(e),qs().clearSessionQuestions(e),delete _e.tasksBySession[e],delete _e.goalBySession[e],Hs().clearSessionGitStatus(e),delete _e.lastSeqBySession[e],delete _e.compactionBySession[e],delete _e.messagesLoadingMoreBySession[e],delete _e.messagesHasMoreBySession[e],delete _e.messagesLoadMoreErrorBySession[e],delete k8[e],$2.delete(e),Sv.delete(e),eR.delete(e),yhe(e),delete _e.queuedBySession[e],delete _e.promptIdBySession[e],delete _e.inFlightBySession[e],delete _e.turnActiveBySession[e],delete _e.turnEndedPromptIdBySession[e],delete _e.turnErrorBySession[e],delete _e.turnRetryBySession[e],delete _e.planModeBySession[e],delete _e.planArmedBySession[e],delete _e.swarmModeBySession[e],delete _e.goalModeBySession[e],delete _e.thinkingBySession[e],delete _e.pendingThinkingBySession[e],W6(),O$(),P$(),or().unpinSession(e)}const U$=K(!1),K$=K(null);async function cf(e){let t;try{t=await Wt().getSessionStatus(e)}catch{return}m9(e,n=>({...n,model:t.model||n.model,usage:{...n.usage,contextTokens:t.contextTokens,contextLimit:t.maxContextTokens}})),_e.swarmModeBySession[e]=t.swarmMode,_e.planModeBySession[e]=t.planMode,_r(un.planMode),t.thinkingEffort.length>0&&EB(_e,e,t.thinkingEffort)}const F2=new Set;function Vhe(e){F2.add(e),V$(e).finally(()=>{F2.delete(e)})}async function V$(e){const t=_e.goalVersionBySession[e]??0;let n;try{n=await Wt().getSessionGoal(e)}catch{return}(_e.goalVersionBySession[e]??0)===t&&(n===null||n.status==="complete"?delete _e.goalBySession[e]:_e.goalBySession[e]=n)}function Z$(e,t){const n=t??_e.activeSessionId;if(!n)return Promise.resolve(!1);const i=e.thinking!==void 0?_e.pendingThinkingBySession[n]:void 0;return Promise.resolve(Wt().updateSession(n,e)).then(()=>(Au(_e,n,i),cf(n))).then(()=>!0).catch(o=>(Au(_e,n,i)&&cf(n),h1("persistSessionProfile",o,{sessionId:n}),!1))}function G$(e){try{return gs(e)??""}catch{return""}}function Zhe(){return typeof window>"u"?!1:new URLSearchParams(window.location.search).get("kimi_onboarded")==="1"}const Q$=Zhe();if(Q$&&G$(N2)!=="1")try{is(N2,"1")}catch{}const Y$=K(Q$||G$(N2)==="1");function Ghe(e){Y$.value=e;try{is(N2,e?"1":"0")}catch{}e&&window.kimiDesktop?.setOnboarded?.()}let cl=null;const D2=hfe({api:Wt(),connectEventsIfNeeded:Z6,getEventConnection:()=>cl});let z_=0;function J$(){return z_+=1,`msg_opt_${Date.now().toString(36)}_${z_}`}function O_(e,t,n){const i={sessions:_e.sessions,activeSessionId:_e.activeSessionId,messagesBySession:_e.messagesBySession,approvalsBySession:_e.approvalsBySession,planReviewByToolCallId:_e.planReviewByToolCallId,questionsBySession:_e.questionsBySession,tasksBySession:_e.tasksBySession,goalBySession:_e.goalBySession,goalVersionBySession:_e.goalVersionBySession,lastSeqBySession:_e.lastSeqBySession,turnActiveBySession:_e.turnActiveBySession,turnEndedPromptIdBySession:_e.turnEndedPromptIdBySession,turnErrorBySession:_e.turnErrorBySession,turnRetryBySession:_e.turnRetryBySession,compactionBySession:_e.compactionBySession,config:_e.config,warnings:_e.warnings},o=Roe(i,e,{sessionId:t,seq:n},{t:(s,r)=>r===void 0?gi(s):gi(s,r)});o.sessions!==i.sessions&&U6(o.sessions),o.activeSessionId!==i.activeSessionId&&K6(o.activeSessionId),qhe(o.messagesBySession),qs().applyApprovalsDiff(o.approvalsBySession),Or(_e.planReviewByToolCallId,o.planReviewByToolCallId),qs().applyQuestionsDiff(o.questionsBySession),Or(_e.tasksBySession,o.tasksBySession),Or(_e.goalBySession,o.goalBySession),Or(_e.goalVersionBySession,o.goalVersionBySession),Or(_e.lastSeqBySession,o.lastSeqBySession),Or(_e.turnActiveBySession,o.turnActiveBySession),Or(_e.turnEndedPromptIdBySession,o.turnEndedPromptIdBySession),Or(_e.turnErrorBySession,o.turnErrorBySession),Or(_e.turnRetryBySession,o.turnRetryBySession),Or(_e.compactionBySession,o.compactionBySession),o.config!==i.config&&(_e.config=o.config??null),zoe(o.warnings,i.warnings)||(_e.warnings=o.warnings),e.type==="goalUpdated"&&F2.delete(t),e.type==="configChanged"&&(_e.defaultModel=e.config.defaultModel??null),e.type==="modelCatalogChanged"&&(Zn.loadModels(),Zn.loadProviders()),e.type==="sessionUsageUpdated"&&(e.swarmMode!==void 0&&(_e.swarmModeBySession[e.sessionId]=e.swarmMode),e.planMode!==void 0&&(_e.planModeBySession[e.sessionId]=e.planMode),e.thinking!==void 0&&EB(_e,e.sessionId,e.thinking)),e.type==="sessionDeleted"&&(V6(e.sessionId),p8(e.sessionId)),e.type==="sessionUpdated"&&e.session.archived===!0&&p8(e.session.id)}function Qhe(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n.role==="user")return;if(n.role==="assistant")for(let i=n.content.length-1;i>=0;i--){const o=n.content[i];if(o.type==="toolUse"&&o.toolName==="ExitPlanMode")return o.toolCallId}}}function Yhe(e,t){const n=_e.lastSeqBySession[t.sessionId]??0,i=_e.turnActiveBySession[t.sessionId]??!1,o=e.type==="approvalResolved"||e.type==="approvalExpired"?_e.approvalsBySession[t.sessionId]?.find(r=>r.approvalId===e.approvalId&&r.toolName==="ExitPlanMode")?.toolCallId:void 0,s=Ws.sideChatTargetBySession.value[t.sessionId];if(e.type==="messageCreated"&&e.message.role==="user"&&e.agentId!==void 0&&Object.prototype.hasOwnProperty.call(_e.sideChatMessagesByAgent,e.agentId)){O_({type:"unknown",raw:{_noop:!0}},t.sessionId,t.seq),Ws.reconcileSideChatUserMessage(e.agentId,e.message);return}if(O_(e,t.sessionId,t.seq),s){const{agentId:r}=s,l=t.sessionId;e.type==="agentDelta"&&e.agentId===r?e.delta.text&&Ws.appendSideChatAssistantText(r,l,e.delta.text):e.type==="agentTurnEnded"&&e.agentId===r?Ws.finishSideChatAgent(r,l):e.type==="taskProgress"&&e.taskId===r?Ws.appendSideChatAssistantText(r,l,e.outputChunk):e.type==="taskCompleted"&&e.taskId===r&&Ws.finishSideChatAgent(r,l,e.outputPreview)}if(e.type==="messageCreated"&&e.message.role==="user"&&e.message.promptId!==void 0){const r=e.message.sessionId;_e.promptIdBySession[r]!==e.message.promptId&&(_e.promptIdBySession[r]=e.message.promptId)}if(e.type==="turnActiveChanged"&&!e.active&&t.seq>n){const r=e.reason;Kpe(e.sessionId,r==="cancelled"||r==="failed"||r==="blocked"?"aborted":"idle",i);const l=Qhe(_e.messagesBySession[e.sessionId]??[]);l!==void 0&&I0(e.sessionId,l)}if(e.type==="sessionWorkChanged"&&(e.mainTurnActive===!1&&i||e.mainTurnActive===void 0&&!e.busy)&&t.seq>n&&Upe(e.sessionId),(e.type==="promptAborted"||e.type==="promptCompleted"&&e.reason==="blocked")&&t.seq>n&&_e.promptIdBySession[e.sessionId]===e.promptId&&Bt.finishPromptLocal(e.sessionId),e.type==="questionRequested"&&Vpe(e.sessionId,e.question),e.type==="approvalRequested"&&Zpe(e.sessionId,e.approval),o!==void 0){const r=e.type==="approvalResolved"?{state:e.decision,selectedOption:e.selectedLabel,feedback:e.feedback}:{state:"cancelled"};H$(t.sessionId,o,r),I0(t.sessionId,o)}}const Nh=Hse(({appEvent:e,meta:t})=>Yhe(e,t),({appEvent:e})=>zse(e),{coalesce:qse}),Jhe=3e4;let P_=0,tr=null;const Op=new Map;let B2=0,Fh=null;function Xhe(){Fh!==null&&(clearTimeout(Fh),Fh=null)}function j_(e){if(!_e.connected||Fh!==null)return;const t=Math.min(Jhe,1e3*2**B2);B2+=1,bu("[kimi-code] session work reconciliation incomplete; retrying",e),Fh=setTimeout(()=>{Fh=null,_e.connected&&X$()},t)}function e1e(e,t){const n=new Map(e.map(u=>[u.id,u]));let i=!1,o=!1;const s={..._e.turnActiveBySession},r=[],l=new Map,a=_e.sessions.map(u=>{const c=n.get(u.id);if(c===void 0)return u;const d=t.workEventSeqBySession.get(u.id)??0,h=t.turnEventSeqBySession.get(u.id)??0,p=t.pendingEventBySession.get(u.id),g=d>c.lastSeq,m=h>c.lastSeq,k=p!==void 0&&p.seq>c.lastSeq,w=g||m&&u.mainTurnActive===!0?u.busy||u.mainTurnActive===!0:c.busy,y=g||m?u.mainTurnActive:c.mainTurnActive??(w?u.mainTurnActive:!1),b=k?p.source==="work"?u.pendingInteraction:(_e.approvalsBySession[u.id]?.length??0)>0?"approval":(_e.questionsBySession[u.id]?.length??0)>0?"question":"none":c.pendingInteraction??(w?u.pendingInteraction:"none");(k&&p.source==="work"||!k&&(c.pendingInteraction!==void 0||c.busy===!1))&&b!==void 0&&l.set(u.id,b);const A=g?u.lastTurnReason:c.lastTurnReason;Op.set(u.id,Math.max(Op.get(u.id)??0,c.lastSeq));const T=t.turnStartBySession.get(u.id);return(y===!1||y===void 0&&!w)&&t.witnessedTurnBySession.has(u.id)&&T!==void 0&&Bt.isLocalTurnSnapshotCurrent(u.id,T)&&r.push(u.id),y===!0&&!s[u.id]?(s[u.id]=!0,o=!0):(y===!1||!w)&&s[u.id]&&(delete s[u.id],o=!0),u.busy===w&&u.mainTurnActive===y&&u.pendingInteraction===b&&u.lastTurnReason===A?u:(i=!0,{...u,busy:w,mainTurnActive:y,pendingInteraction:b,lastTurnReason:A})});i&&U6(a),o&&Or(_e.turnActiveBySession,s);for(const[u,c]of l)c==="none"?(qs().clearSessionApprovals(u),qs().clearSessionQuestions(u)):c==="question"&&qs().clearSessionApprovals(u);for(const u of r)Bt.finishPromptLocal(u,{turnWasActive:!0})}async function X$(){const e={workEventSeqBySession:new Map,turnEventSeqBySession:new Map,pendingEventBySession:new Map,turnStartBySession:new Map(_e.sessions.map(t=>[t.id,Bt.localTurnStartState(t.id)])),witnessedTurnBySession:new Set(_e.sessions.filter(t=>_e.inFlightBySession[t.id]||_e.turnActiveBySession[t.id]).map(t=>t.id))};tr=e;try{const t=await Bt.listAllSessionsGlobal({shouldContinue:()=>tr===e&&_e.connected});if(tr!==e||!_e.connected)return;Nh.flush(),e1e(t.sessions,e),tr=null,t.error!==void 0?j_(t.error):B2=0}catch(t){if(tr!==e||!_e.connected)return;tr=null,j_(t)}}function Z6(){if(cl!==null||typeof WebSocket>"u")return;Ll("ws:connection",{status:"connecting"}),_e.connection="connecting",cl=Wt().connectEvents({onEvent(t,n){if(t.type==="sessionArchived"){Bt.applyRemoteSessionArchived(t.sessionId,t.workspaceId).then(r=>{r&&p8(t.sessionId)});return}if(t.type==="workspaceCreated"||t.type==="workspaceUpdated"||t.type==="workspaceDeleted"){if(t.type==="workspaceDeleted"){const r=_e.sessions.filter(l=>l.workspaceId===t.workspaceId||l.cwd===t.root).map(l=>l.id);Ufe(t.workspaceId,t.root,r)}Bt.applyWorkspaceEvent(t);return}if((t.type==="pluginsChanged"||t.type==="capabilityChanged")&&Vfe(t))return;const i=t.type==="sessionWorkChanged",o=t.type==="turnActiveChanged",s=t.type==="approvalRequested"||t.type==="approvalResolved"||t.type==="approvalExpired"||t.type==="questionRequested"||t.type==="questionAnswered"||t.type==="questionDismissed";if((i||o||s)&&n.seq>0){const r=Op.get(n.sessionId)??0;if(n.seq<=r)return;Op.set(n.sessionId,n.seq)}if(tr!==null&&(i||o||s))if(i){const r=tr.workEventSeqBySession.get(n.sessionId)??0;if(n.seq>r&&tr.workEventSeqBySession.set(n.sessionId,n.seq),t.pendingInteraction!==void 0||!t.busy){const l=tr.pendingEventBySession.get(n.sessionId);(l===void 0||n.seq>l.seq)&&tr.pendingEventBySession.set(n.sessionId,{seq:n.seq,source:"work"})}}else if(o){const r=tr.turnEventSeqBySession.get(n.sessionId)??0;n.seq>r&&tr.turnEventSeqBySession.set(n.sessionId,n.seq)}else{const r=tr.pendingEventBySession.get(n.sessionId);(r===void 0||n.seq>r.seq)&&tr.pendingEventBySession.set(n.sessionId,{seq:n.seq,source:"interaction"})}for(const r of Wse({appEvent:t,meta:n}))Nh(r)},onResync(t,n,i){Ll("ws:resync",{sessionId:t,status:"required",seq:n}),Nh.flush(),$2.add(t),R2.request(t)},onError(t,n,i){Ll("ws:error",{status:"failed",errorCode:t,fatal:i}),ug({severity:"error",title:gi("warnings.wsTitle"),message:n,details:[yo("message",n)].filter(o=>o!==void 0)})},onConnectionChange(t){Ll("ws:connection",{status:t?"connected":"disconnected"}),_e.connected=t,_e.connection=t?"connected":"disconnected",t||(tr=null,Op.clear(),Xhe(),B2=0),t&&(P_+=1,a1e(),Bt.refreshServerMeta())},onReplayComplete(){Nh.flush(),P_>1&&X$()},onTranscriptReset(t,n,i,o){D2.receiveReset(t,n,i,o)},onTranscriptOps(t,n,i,o){return D2.applyOps(t,n,i,o)}})}const k8={},$2=new Set,Sv=new Set,eR=new Set;function t1e(e){return ko(e)&&e.code===R_?!0:typeof e=="object"&&e!==null&&e.code===R_}function yo(e,t){if(!(t==null||t===""))return{label:gi(`warnings.details.${e}`),value:tR(t)}}function tR(e){if(e instanceof Error)return typeof e.stack=="string"&&e.stack?e.stack:e.message?`${e.name}: ${e.message}`:e.name;if(typeof e=="string")return e;if(typeof e=="number"||typeof e=="boolean"||typeof e=="bigint")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}function n1e(e){return e instanceof Error||typeof e=="object"&&e!==null&&typeof e.name=="string"?e.name:void 0}function i1e(e){return e instanceof Error||typeof e=="object"&&e!==null&&typeof e.message=="string"?e.message:void 0}function o1e(e){return e instanceof Error&&typeof e.stack=="string"&&e.stack?e.stack:void 0}function s1e(e){if(!(typeof e!="number"||!Number.isFinite(e)))return new Date(e).toISOString()}function H_(e){if(!(typeof e!="number"||!Number.isFinite(e)))return`${Math.round(e)}ms`}function r1e(e,t,n){const i=t9(t),o=ko(t),s=i||o?t.timestamp:void 0,r=i||o?t.durationMs:void 0,l=[yo("operation",e),yo("sessionId",n??_e.activeSessionId),yo("connection",_e.connection),yo("timestamp",s1e(s??Date.now()))];return i?l.push(yo("duration",H_(r)),yo("request",`${t.method} ${t.path}`),yo("endpoint",t.url),yo("requestId",t.requestId),yo("phase",t.phase),yo("timeout",`${t.timeoutMs}ms`),yo("status",t.status===void 0?void 0:`${t.status} ${t.statusText??""}`.trim()),yo("contentType",t.contentType),yo("responsePreview",t.bodyPreview),yo("cause",t.cause)):o?l.push(yo("duration",H_(r)),yo("code",t.code),yo("requestId",t.requestId),yo("message",t.message),yo("details",t.details)):l.push(yo("errorName",n1e(t)),yo("message",i1e(t)??tR(t)),yo("stack",o1e(t))),l.filter(a=>a!==void 0)}function l1e(e,t,n={}){const i=t9(t),o=ko(t),s=$Y(t),r=n.title??gi(i?s?"warnings.daemonTimeoutTitle":"warnings.daemonNetworkTitle":o?"warnings.daemonApiTitle":"warnings.operationFailedTitle"),l=n.message??(i?gi(s?"warnings.daemonTimeoutMessage":"warnings.daemonNetworkMessage"):o?t.message:gi("warnings.operationFailedMessage"));return{severity:"error",title:r,message:l,details:r1e(e,t,n.sessionId)}}function ug(e){_e.warnings=[..._e.warnings,e]}function a1e(){const e=gi("warnings.wsTitle"),t=_e.warnings.filter(n=>!(typeof n=="object"&&n!==null&&n.severity==="error"&&n.title===e));t.length!==_e.warnings.length&&(_e.warnings=t)}function h1(e,t,n){fu(`[kimi-code] operation failed: ${e}`,t);const i=ko(t),o=t9(t);Ll("operation:failed",{sessionId:n?.sessionId,status:"failed",operation:e,errorName:t instanceof Error?t.name:typeof t,errorCode:i?t.code:void 0,requestId:i||o?t.requestId:void 0,phase:o?t.phase:void 0,httpStatus:o?t.status:void 0}),ug(l1e(e,t,n))}const u1e={40913:"warnings.goal.alreadyExists",40914:"warnings.goal.notFound",40915:"warnings.goal.statusInvalid",40916:"warnings.goal.notResumable",40918:"warnings.goal.objectiveTooLong"};function c1e(e){if(!ko(e)||e.code===void 0)return;const t=u1e[e.code];return t?gi(t):void 0}async function d1e(e){if(V6(e),_e.activeSessionId!==e)return;const t=_e.sessions[0];t?await Bt.selectSession(t.id,{urlMode:"replace",skipTrack:!0}):(K6(void 0),_e.sessionLoading=!1,Bt.writeSessionUrl(void 0,"replace"))}const W_=new Set;async function f1e(e){if(!W_.has(e)){W_.add(e);try{const t=await Wt().getSessionWarnings(e),n=gi("warnings.noteLabel");for(const i of t)ug(`${n}: ${i.message}`)}catch{}}}async function G6(e,t){const n=Bt.localTurnStartState(e);try{const o=await Wt().getSessionSnapshot(e);if(!_e.sessions.some(d=>d.id===e))return"ok";Nh.flush();const s=_e.lastSeqBySession[e]??0,r=k8[e],l=$2.has(e)||z2.has(e);if(!l&&r!==void 0&&r===o.epoch&&s>o.asOfSeq)return Sv.delete(e)||(Sv.add(e),R2.request(e)),"ok";if(!Bt.isLocalTurnSnapshotCurrent(e,n))return Bt.afterLocalTurnStartsSettle(e,()=>{R2.request(e)}),"ok";const a=_e.turnRetryBySession[e];a!==void 0&&a.turnId!==o.inFlightTurn?.turnId&&delete _e.turnRetryBySession[e],(l||o.session.lastTurnReason!=="failed")&&delete _e.turnErrorBySession[e];const u=v2(o.session.usage),c=o.session.mainTurnActive??(o.inFlightTurn!==null&&o.session.busy);m9(e,d=>WY(d,o.session,c)),Uhe(e,uce(_e.messagesBySession[e]??[],o.messages)),_e.tasksBySession[e]=Cce(o.subagents,_e.tasksBySession[e]??[]),_e.messagesHasMoreBySession[e]=o.hasMoreMessages,qs().setSessionApprovals(e,o.pendingApprovals);for(const d of o.pendingApprovals){const h=d.display;h?.kind==="plan_review"&&typeof h.plan=="string"&&h.plan.length>0&&(_e.planReviewByToolCallId[d.toolCallId]={plan:h.plan,path:typeof h.path=="string"?h.path:void 0})}return qs().setSessionQuestions(e,o.pendingQuestions),_e.lastSeqBySession[e]=o.asOfSeq,k8[e]=o.epoch,$2.delete(e),Sv.delete(e),Bt.handleSessionSnapshot(e,{inFlightTurn:o.inFlightTurn,busy:o.session.busy}),c?_e.turnActiveBySession[e]=!0:delete _e.turnActiveBySession[e],Z6(),cl&&(cl.seedSnapshot(e,o),cl.subscribe(e,{seq:o.asOfSeq,epoch:o.epoch}),g1e(e)),z2.delete(e),u&&t?.skipStatusRefresh!==!0&&cf(e),f1e(e),"ok"}catch(i){return t1e(i)?(await d1e(e),"not-found"):(h1("getSessionSnapshot",i,{title:gi("warnings.sessionSnapshotTitle"),message:gi("warnings.sessionSnapshotMessage"),sessionId:e}),"failed")}}const R2=cce(G6);function h1e(e){return Object.prototype.hasOwnProperty.call(_e.messagesBySession,e)}const p1e=4,ru=[],z2=new Set;function g1e(e){const t=ru.indexOf(e);for(t!==-1&&ru.splice(t,1),ru.unshift(e);ru.length>p1e;){let n=-1;for(let o=ru.length-1;o>=0;o--)if(ru[o]!==_e.activeSessionId){n=o;break}if(n===-1)break;const[i]=ru.splice(n,1);if(i===void 0)break;cl?.unsubscribe(i),z2.add(i)}}function m1e(e){const t=ru.indexOf(e);t!==-1&&ru.splice(t,1),z2.delete(e)}async function v1e(e){return G6(e)}function df(e,t){return(_e.inFlightBySession[e]??!1)||(_e.turnActiveBySession[e]??!1)||(t??_e.sessions.find(n=>n.id===e)?.mainTurnActive??!1)}function Af(e){try{const t=new Date(e),i=Date.now()-t.getTime(),o=i/36e5;if(i<6e4)return gi("sessions.justNow");if(o<1)return`${Math.round(i/6e4)}m`;if(o<24)return`${Math.round(o)}h`;const s=i/864e5;return s<7?`${Math.round(s)}d`:s<30?`${Math.round(s/7)}w`:s<365?`${Math.round(s/30)}mo`:`${Math.round(s/365)}y`}catch{return e}}const y1e=3e4,Mc=K(0);let _3=null;function k1e(){_3===null&&(_3=setInterval(()=>{Mc.value=(Mc.value+1)%Number.MAX_SAFE_INTEGER},y1e),_3.unref?.())}function b1e(e){return{questionId:e.questionId,sessionId:e.sessionId,toolCallId:e.toolCallId,questions:e.questions.map(t=>({id:t.id,question:t.question,header:t.header,body:t.body,options:t.options.map(n=>({id:n.id,label:n.label,description:n.description,recommended:n.recommended})),multiSelect:t.multiSelect,allowOther:t.allowOther,otherLabel:t.otherLabel}))}}const A1e=F(()=>{const e=_e.activeSessionId,t=e?_e.messagesBySession[e]??[]:[],n=new Map;for(const o of t)if(o.role==="assistant")for(const s of o.content){if(s.type!=="toolUse"||s.toolName!=="Bash"&&s.toolName!=="bash")continue;const r=s.input,l=r&&typeof r.command=="string"?r.command:void 0;l&&n.set(s.toolCallId,l)}const i=new Map;if(n.size===0)return i;for(const o of t)if(o.role==="tool")for(const s of o.content){if(s.type!=="toolResult")continue;const r=x6(s.output);if(!r)continue;let l;for(const u of r){const c=/task_id:\s*(\S+)/.exec(u);if(c?.[1]){l=c[1];break}}if(!l)continue;const a=n.get(s.toolCallId);a&&i.set(l,a)}return i});function nR(e){return A1e.value.get(e.id)}const C1e=F(()=>{const e=_e.activeSessionId,t=e?_e.messagesBySession[e]??[]:[],n=new Map;for(const i of t)if(i.role==="assistant")for(const o of i.content){if(o.type!=="toolUse")continue;const s=o.input,r=s&&typeof s.prompt=="string"?s.prompt:void 0;r&&!n.has(o.toolCallId)&&n.set(o.toolCallId,r);const l=s?.items;if(!r&&Array.isArray(l)&&!n.has(o.toolCallId)){const a=l.filter(u=>typeof u=="string");a.length>0&&n.set(o.toolCallId,a)}}return n});function w1e(e){if(!e.parentToolCallId)return;const t=C1e.value.get(e.parentToolCallId);return Array.isArray(t)?e.swarmIndex!==void 0?t[e.swarmIndex]:void 0:t}function x1e(e){let t;e.status==="running"?t="run":e.status==="completed"?t="done":e.status==="cancelled"?t="cancelled":t="fail";let n="",i;if(e.status==="running"&&e.startedAt){i=Date.now()-new Date(e.startedAt).getTime();const l=Math.round(i/1e3),a=Math.floor(l/60),u=l%60;n=gi("tasks.timingRunning",{time:`${a}:${String(u).padStart(2,"0")}`})}else e.completedAt&&e.startedAt&&!e.completedAtEstimated?(i=new Date(e.completedAt).getTime()-new Date(e.startedAt).getTime(),n=gi("tasks.timingDone",{time:Wa(i,{h:gi("status.timeUnitHour"),m:gi("status.timeUnitMinute"),s:gi("status.timeUnitSecond")})})):n=e.status;const o=e.outputLines&&e.outputLines.length>0?e.outputLines:e.outputPreview?e.outputPreview.split(/\r?\n/):void 0,s=e.command??nR(e),r=e.kind==="bash"&&s?`$ ${s}`:e.kind==="subagent"?w1e(e)??e.subagentType:void 0;return{id:e.id,agentId:e.agentId,backgroundTaskId:e.backgroundTaskId,name:e.description,kind:e.kind,state:t,timing:n,durationMs:i,meta:r,output:o,runInBackground:e.runInBackground,parentToolCallId:e.parentToolCallId,swarmIndex:e.swarmIndex,completedAt:e.completedAt,createdAt:e.createdAt,model:e.model,thinkingEffort:e.thinkingEffort}}const S1e=F(()=>{const e=_e.sessions.find(n=>n.id===_e.activeSessionId),t=e?e.cwd.split("/").pop()??e.cwd:"main";return{name:_e.workspaceName,branch:t}}),_1e=F(()=>(Mc.value,_e.sessions.toSorted((e,t)=>new Date(t.updatedAt).getTime()-new Date(e.updatedAt).getTime()).map(e=>({id:e.id,title:e.title,time:Af(e.updatedAt),busy:df(e.id,e.mainTurnActive),pendingInteraction:e.pendingInteraction,lastTurnReason:e.lastTurnReason,workspaceId:Mr(e),cwd:e.cwd})))),M1e=F(()=>_e.activeSessionId??""),I1e=F(()=>{const e=_e.activeSessionId;if(e)return Zn.skillsBySession.value[e]??[];const t=fg.value;return t?Zn.skillsByWorkspace.value[t]??[]:[]}),E1e=F(()=>{const e=_e.activeSessionId;if(e)return Zn.skillsFetchedBySession.value[e]===!0;const t=fg.value;return t?Zn.skillsFetchedByWorkspace.value[t]===!0:!1}),Q6=F(()=>{const e=_e.activeSessionId;return e?_e.inFlightBySession[e]??!1:!1}),T1e=F(()=>Bt.isStartingFirstPrompt()),Ws=Ffe(_e,{api:Wt(),pushOperationFailure:h1,nextOptimisticMsgId:J$,connectEventsIfNeeded:Z6,getEventConn:()=>cl,resolveThinkingForPrompt:(e,t)=>Zn.resolveThinkingForPrompt(e,t),refreshSessionStatus:cf}),cg=F(()=>{const e=_e.activeSessionId;if(!e)return[];const t=Ws.sideChatTargetBySession.value[e]?.agentId;return(_e.tasksBySession[e]??[]).filter(n=>n.id!==t)}),iR=Nfe(_e,cg,{api:Wt()}),dg=F(()=>{const e=_e.activeSessionId;return e?(_e.turnActiveBySession[e]??!1)||(_e.sessions.find(t=>t.id===e)?.mainTurnActive??!1):!1}),L1e=F(()=>{const e=_e.activeSessionId;if(e)return _e.turnErrorBySession[e]}),N1e=F(()=>{const e=_e.activeSessionId;if(e&&dg.value)return _e.turnRetryBySession[e]}),oR=e=>Wt().getFileUrl(e),sR=(e,t)=>Wt().getSessionMediaUrl(e,t),F1e=[],D1e=hB(),rR=F(()=>{const e=_e.activeSessionId;if(!e)return[];const t=new Set(_e.sideChatUserMessageIdsBySession[e]??[]);return D1e({messages:(_e.messagesBySession[e]??[]).filter(n=>!t.has(n.id)),approvals:_e.approvalsBySession[e]??F1e,getFileUrl:oR,getSessionMediaUrl:sR,sessionActive:dg.value,planReviewByToolCallId:_e.planReviewByToolCallId,plansByToolCallId:Cu[e]})}),B1e=F(()=>Q6.value||dg.value),b8=new Map,$1e=F(()=>{iR.taskClock.value;const e=cg.value.map(x1e),t=_e.activeSessionId;if(t){let n=b8.get(t);n||(n=new Map,b8.set(t,n));const i=e.filter(r=>r.kind==="subagent"&&r.runInBackground);for(const r of i){const l=r.agentId??r.id;if(r.agentId!==void 0&&r.backgroundTaskId!==void 0&&!n.has(l)){const a=n.get(r.backgroundTaskId);a!==void 0&&(n.delete(r.backgroundTaskId),n.set(l,a))}}const o=i.filter(r=>!n.has(r.agentId??r.id)).sort((r,l)=>(r.createdAt??"").localeCompare(l.createdAt??""));let s=n.size===0?0:Math.max(...n.values())+1;for(const r of o)n.set(r.agentId??r.id,s++);for(const r of i)r.swarmIndex=n.get(r.agentId??r.id)}return e}),lR=F(()=>nre(cg.value)),R1e=F(()=>ore(cg.value)),rh=F(()=>{const e=_e.activeSessionId;return e?_e.goalBySession[e]??null:null}),z1e=F(()=>{const e=_e.activeSessionId;return e?Kse(_e.messagesBySession[e]??[]):[]}),O1e=F(()=>{const e=_e.activeSessionId;return e?_e.compactionBySession[e]??null:null}),P1e=F(()=>_e.connection),j1e=F(()=>_e.loading),H1e=F(()=>_e.sessionLoading),W1e=F(()=>{const e=_e.activeSessionId;return e?_e.messagesLoadingMoreBySession[e]??!1:!1}),q1e=F(()=>{const e=_e.activeSessionId;return e?_e.messagesHasMoreBySession[e]??!1:!1}),U1e=F(()=>{const e=_e.activeSessionId;return e?_e.messagesLoadMoreErrorBySession[e]??!1:!1}),K1e=F(()=>_e.serverVersion),aR=F(()=>_e.webTitle),V1e=F(()=>_e.experimentalFlags),Z1e=F(()=>_e.backend),G1e=F(()=>_e.dangerousBypassAuth);function Q1e(){_e.dangerousBypassAuth=!1}const Y1e=F(()=>_e.permission),J1e=F(()=>_e.thinking),uR=F(()=>{const e=_e.activeSessionId;return e?_e.planModeBySession[e]??!1:ag.planMode}),X1e=F(()=>{const e=_e.activeSessionId;return e?_e.planArmedBySession[e]??!1:ag.planMode}),epe=F(()=>{const e=_e.activeSessionId;return e?_e.swarmModeBySession[e]??!1:ag.swarmMode}),tpe=F(()=>{const e=_e.activeSessionId;return e?_e.goalModeBySession[e]??!1:ag.goalMode}),npe=F(()=>{const e=_e.activeSessionId,t=(e?Cu[e]:void 0)??{},n={},i=new Set;for(const s of rR.value)for(const r of s.tools??[]){if(r.name!=="ExitPlanMode")continue;i.add(r.id);const l=t[r.id];if(l){n[r.id]=l;continue}const a=_e.planReviewByToolCallId[r.id],u=ipe(r.arg),c=a?.plan??u?.plan,d=r.planPath??a?.path;!c&&!d||(n[r.id]={agentId:"main",toolCallId:r.id,turnId:s.id,source:"interaction",plan:c??"",path:d,options:u?.options,review:q6[r.id]})}return{...Object.fromEntries(Object.entries(t).filter(([s])=>!i.has(s))),...n}});function ipe(e){try{const t=JSON.parse(e);return{plan:typeof t.plan=="string"?t.plan:void 0,options:Array.isArray(t.options)?t.options:void 0}}catch{return}}const ope=F(()=>{const e=ire(lR.value);return{plan:uR.value,goal:rh.value&&rh.value.status!=="complete"?{status:rh.value.status,turnsUsed:rh.value.turnsUsed,elapsedMs:rh.value.wallClockMs}:null,swarm:e.total>0?e:null}}),spe=F(()=>{const e=_e.activeSessionId;if(!e)return[];const t=Wt();return(_e.queuedBySession[e]??[]).map(n=>({id:n.id??n.text,text:n.text,attachmentCount:n.attachments?.length??0,attachments:n.attachments?.map(i=>P6(t,i))}))}),rpe=F(()=>_e.warnings),lpe=F(()=>{const e=_e.activeSessionId;return e?(_e.questionsBySession[e]??[]).map(b1e):[]}),ape=F(()=>{const e=_e.activeSessionId;return e?(_e.approvalsBySession[e]??[]).map(t=>({approvalId:t.approvalId,block:aB(t),agentName:t.agentName,toolCallId:t.toolCallId})):[]}),Y6=F(()=>{const e=_e.activeSessionId;return e?(_e.approvalsBySession[e]??[]).length>0?"awaiting-approval":(_e.questionsBySession[e]??[]).length>0?"awaiting-question":Q6.value||dg.value?"running":"idle":"idle"}),Zn=Yfe(_e,{api:Wt(),pushOperationFailure:h1,refreshSessionStatus:cf,persistSessionProfile:Z$,savePlanModeToStorage:W6,activity:Y6,updateSession:m9,updateSessionMessages:q$,loadConfig:()=>Bt.loadConfig(),checkAuth:()=>Bt.checkAuth(),beginLocalTurn:m8,settleLocalTurn:v8}),A8=F(()=>{const e=_e.activeSessionId;if(!e)return null;const t=_e.gitStatusBySession[e];return t?{branch:t.branch,ahead:t.ahead,behind:t.behind}:null}),upe=F(()=>{const e=_e.activeSessionId;return e?_e.gitStatusBySession[e]?.pullRequest??null:null}),cpe=F(()=>{const e=_e.activeSessionId;if(!e)return[];const t=_e.gitStatusBySession[e];return t?Object.entries(t.entries).map(([n,i])=>({path:n,status:i})).sort((n,i)=>n.path.localeCompare(i.path)):[]}),dpe=F(()=>{const e=_e.activeSessionId;if(!e)return null;const t=_e.gitStatusBySession[e];return t?{totalAdditions:t.additions,totalDeletions:t.deletions}:null}),cR=F(()=>{const e=_e.sessions.find(r=>r.id===_e.activeSessionId),t=A8.value?.branch??(e?e.cwd.split("/").pop()??e.cwd:"main"),n=e===void 0?Zn.draftModel.value:null,i=(e?.model&&e.model.length>0?e.model:n??_e.defaultModel)??"—",o=Zn.models.value.find(r=>r.id===i)??Zn.models.value.find(r=>r.model===i);return{model:o?.displayName||o?.model||(i.includes("/")?i.split("/").pop():i),modelId:o?.id??i,ctxUsed:e?.usage.contextTokens??0,ctxMax:e?.usage.contextLimit??0,permission:_e.permission,branch:t,cwd:e?.cwd??"",isGitRepo:A8.value!==null}}),fpe=F(()=>Hs().fileDiffLines),hpe=F(()=>_e.sessions.find(t=>t.id===_e.activeSessionId)?.usage.totalCostUsd??0),ppe=F(()=>_e.authReady),gpe=F(()=>_e.defaultModel),mpe=F(()=>_e.managedProviderStatus),vpe=F(()=>_e.managedUserInfo),ype=F(()=>_e.managedMembership),kpe=F(()=>_e.config),bpe=F(()=>{const e=_e.activeSessionId;if(!e)return{};const t=_e.gitStatusBySession[e];return t?{...t.entries}:{}}),Ape=F(()=>{const e=new Map;for(const t of _e.workspaces){const n=ol(t.root);e.has(n)||e.set(n,t.id)}return e});function Mr(e){return Ape.value.get(ol(e.cwd))??e.workspaceId??e.cwd}const v9=F(()=>Pre({workspaces:_e.workspaces,sessions:_e.sessions,hiddenWorkspaceRoots:_e.hiddenWorkspaceRoots,sessionsHasMoreByWorkspace:_e.sessionsHasMoreByWorkspace})),O2=K(vce()),P2=K(yce());function Cpe(e){P2.value!==e&&(P2.value=e,kce(e))}const E0=K(bce());Pe(()=>_e.sessions,e=>{const t=Kce(e,Mr),{next:n,changed:i}=Uce(E0.value,t);i&&(E0.value=n,p$(n))});const dR=F(()=>Vce(v9.value,E0.value));Pe(()=>[v9.value.map(e=>e.id).join("\0"),_e.loading],([e,t])=>{if(t)return;const n=e?e.split("\0"):[],i=jce(n,O2.value,dR.value);i!==null&&(O2.value=i,h$(i));const{next:o,changed:s}=Zce(E0.value,new Set(n));s&&(E0.value=o,p$(o))});const y9=F(()=>or().pinnedSessionIds);function wpe(e){or().pinSession(e)}function xpe(e){or().unpinSession(e)}function Spe(e){or().unpinSessions(e)}function _pe(e){or().togglePinSession(e)}const Yr=F(()=>{const e=v9.value.map(t=>({id:t.id,name:t.name,root:t.root,shortPath:Rhe(t.root,_e.fsHome),sessionCount:t.sessionCount}));return P2.value==="recent"?qce(e,dR.value):Hce(e,O2.value)}),fg=F(()=>{const e=_e.activeWorkspaceId,t=Yr.value;return e&&t.some(n=>n.id===e)?e:t[0]?.id??null});Pe(fg,e=>{e&&(Object.prototype.hasOwnProperty.call(Zn.skillsByWorkspace.value,e)||Zn.loadSkillsForWorkspace(e))},{immediate:!0});const fR=F(()=>{const e=fg.value;return e?Yr.value.find(t=>t.id===e)??null:null}),Mpe=efe({webTitle:aR,activeWorkspaceRoot:()=>fR.value?.root??null}),Ipe=F(()=>{Mc.value;const e=new Set(Yr.value.map(n=>n.id)),t=new Map(Yr.value.map(n=>[n.id,n.name]));return _e.sessions.filter(n=>!n.parentSessionId&&e.has(Mr(n))).map(n=>{const i=Mr(n);return{id:n.id,title:n.title,time:Af(n.updatedAt),busy:df(n.id,n.mainTurnActive),pendingInteraction:n.pendingInteraction,lastTurnReason:n.lastTurnReason,lastPrompt:n.lastPrompt,workspaceId:i,workspaceName:t.get(i)}})}),C8=K(dc),k9=F(()=>{Mc.value;const e=new Set(Yr.value.map(r=>r.id)),t=new Map(Yr.value.map(r=>[r.id,r.name])),n=new Set(y9.value),i=(r,l)=>new Date(l.updatedAt).getTime()-new Date(r.updatedAt).getTime(),o=_e.flatSessionsFrontier,s=[];for(const r of _e.sessions)r.parentSessionId||r.archived||n.has(r.id)||!e.has(Mr(r))||!(og({busy:df(r.id,r.mainTurnActive),unread:e7.value[r.id]??!1,questionCount:T0.value[r.id]?.questions??0,approvalCount:T0.value[r.id]?.approvals??0,pendingInteraction:r.pendingInteraction,lastTurnReason:r.lastTurnReason})!=="idle")&&o!==null&&new Date(r.updatedAt).getTime()<o||s.push(r);return s.sort(i),s.map(r=>{const l=Mr(r);return{id:r.id,title:r.title,time:Af(r.updatedAt),busy:df(r.id,r.mainTurnActive),pendingInteraction:r.pendingInteraction,lastTurnReason:r.lastTurnReason,lastPrompt:r.lastPrompt,updatedAt:r.updatedAt,workspaceId:l,workspaceName:t.get(l),cwdLabel:r.cwd?Tu(r.cwd):"-",pullRequest:r.pullRequest}})});function Epe(e){return og({busy:e.busy,unread:e7.value[e.id]??!1,questionCount:T0.value[e.id]?.questions??0,approvalCount:T0.value[e.id]?.approvals??0,pendingInteraction:e.pendingInteraction,lastTurnReason:e.lastTurnReason})!=="idle"}const J6=F(()=>{const e=k9.value;let t=C8.value;for(let n=e.length-1;n>=t;n--)if(Epe(e[n])){t=n+1;break}return t}),Tpe=F(()=>k9.value.slice(0,J6.value)),Lpe=F(()=>_e.flatSessionsHasMore||J6.value<k9.value.length);function Npe(){C8.value=J6.value+dc,C8.value>k9.value.length&&_e.flatSessionsHasMore&&Bt.loadMoreFlatSessions()}const j2=K(dc),X6=F(()=>{Mc.value;const e=new Set(Yr.value.map(n=>n.id)),t=new Map(Yr.value.map(n=>[n.id,n.name]));return _e.doneSessions.filter(n=>e.has(Mr(n))).map(n=>{const i=Mr(n),o=_e.sessions.find(r=>r.id===n.id),s=o!==void 0&&new Date(o.updatedAt).getTime()>new Date(n.updatedAt).getTime()?o.updatedAt:n.updatedAt;return{id:n.id,title:n.title,time:Af(s),busy:o?.busy??n.busy,pendingInteraction:o?.pendingInteraction??n.pendingInteraction,lastTurnReason:o?.lastTurnReason??n.lastTurnReason,lastPrompt:n.lastPrompt,updatedAt:s,workspaceId:i,workspaceName:t.get(i),archived:!0,cwdLabel:n.cwd?Tu(n.cwd):"-",pullRequest:n.pullRequest}}).sort((n,i)=>new Date(i.updatedAt).getTime()-new Date(n.updatedAt).getTime())}),Fpe=F(()=>X6.value.slice(0,j2.value)),Dpe=F(()=>_e.doneSessionsHasMore||j2.value<X6.value.length);function Bpe(){j2.value+=dc,j2.value>X6.value.length&&_e.doneSessionsHasMore&&Bt.loadMoreDoneSessions()}const $pe=F(()=>{const e=_e.activeSessionId;return e?_e.sessions.find(t=>t.id===e)?.archived===!0:!1});function Rpe(e,t=6){if(!e)return[];const n=new Map(Yr.value.map(r=>[r.id,r.name])),i=(r,l)=>({id:r.id,title:r.title,time:Af(l??r.updatedAt),busy:l===void 0&&df(r.id,r.mainTurnActive),pendingInteraction:l===void 0?r.pendingInteraction:void 0,lastTurnReason:l===void 0?r.lastTurnReason:void 0,lastPrompt:r.lastPrompt,updatedAt:l??r.updatedAt,workspaceId:e,workspaceName:n.get(e),archived:l!==void 0,cwdLabel:r.cwd?Tu(r.cwd):"-",pullRequest:r.pullRequest}),o=_e.sessions.filter(r=>!r.parentSessionId&&!r.archived&&Mr(r)===e).sort((r,l)=>new Date(l.updatedAt).getTime()-new Date(r.updatedAt).getTime()),s=_e.doneSessions.filter(r=>Mr(r)===e);return[...o.map(r=>i(r)),...s.map(r=>i(r,r.updatedAt))].slice(0,t)}function hR(e){Mc.value;const t=new Set(y9.value),n=new Map,i=new Map;for(const o of _e.sessions.toSorted((s,r)=>new Date(r.updatedAt).getTime()-new Date(s.updatedAt).getTime())){if(o.parentSessionId||o.archived)continue;const s=Mr(o);if(e&&t.has(o.id)){i.set(s,(i.get(s)??0)+1);continue}const r={id:o.id,title:o.title,time:Af(o.updatedAt),busy:df(o.id,o.mainTurnActive),pendingInteraction:o.pendingInteraction,lastTurnReason:o.lastTurnReason,updatedAt:o.updatedAt},l=n.get(s)??[];l.push(r),n.set(s,l)}return Yr.value.map(o=>({workspace:o,sessions:n.get(o.id)??[],pinnedCount:i.get(o.id)??0,hasMore:_e.sessionsHasMoreByWorkspace[o.id]??!1,loadingMore:_e.sessionsLoadingMoreByWorkspace[o.id]??!1,initialCount:_e.sessionsInitialCountByWorkspace[o.id]??mp}))}const zpe=F(()=>hR(!0)),Ope=F(()=>hR(!1)),Ppe=F(()=>{Mc.value;const e=new Set(Yr.value.map(o=>o.id)),t=new Map(Yr.value.map(o=>[o.id,o.name])),n=_e.sessions.filter(o=>!o.parentSessionId&&!o.archived&&e.has(Mr(o)));return Ile(n,y9.value).pinned.toSorted((o,s)=>new Date(s.updatedAt).getTime()-new Date(o.updatedAt).getTime()).map(o=>{const s=Mr(o);return{id:o.id,title:o.title,time:Af(o.updatedAt),busy:df(o.id,o.mainTurnActive),pendingInteraction:o.pendingInteraction,lastTurnReason:o.lastTurnReason,updatedAt:o.updatedAt,workspaceId:s,workspaceName:t.get(s),pinned:!0,cwdLabel:o.cwd?Tu(o.cwd):"-",pullRequest:o.pullRequest}})});function jpe(e){O2.value=e,h$(e)}const pR=F(()=>{const e={};for(const[t,n]of Object.entries(_e.approvalsBySession))n.length>0&&(e[t]=(e[t]??0)+n.length);for(const[t,n]of Object.entries(_e.questionsBySession))n.length>0&&(e[t]=(e[t]??0)+n.length);return e}),T0=F(()=>{const e={};for(const[t,n]of Object.entries(_e.approvalsBySession))n.length>0&&((e[t]??={approvals:0,questions:0}).approvals=n.length);for(const[t,n]of Object.entries(_e.questionsBySession))n.length>0&&((e[t]??={approvals:0,questions:0}).questions=n.length);return e}),e7=F(()=>{const e={};for(const[t,n]of Object.entries(_e.unreadBySession))n&&(e[t]=!0);return e}),Hpe=F(()=>{const e={},t=pR.value;for(const n of _e.sessions){const i=t[n.id]??0;if(i<=0)continue;const o=Mr(n);e[o]=(e[o]??0)+i}return e}),Wpe=F(()=>_e.recentRoots),qpe=F(()=>_e.availableOpenInApps),Bt=Ahe(_e,{taskPoller:iR,sideChat:Ws,modelProvider:Zn,pushOperationFailure:h1,notify:ug,activity:Y6,sessionsKnownEmpty:eR,setSessions:U6,updateSession:m9,upsertSessionSorted:jhe,appendSession:Hhe,forgetSession:V6,unpinSessions:Spe,setActiveSessionId:K6,updateSessionMessages:q$,nextOptimisticMsgId:J$,getEventConn:()=>cl,syncSessionFromSnapshot:G6,reopenSession:v1e,hasLoadedMessages:h1e,refreshSessionStatus:cf,refreshSessionGoal:V$,refillSessionGoalOnReload:Vhe,refreshSessionPlans:I0,settlePlanReviewLocally:H$,persistSessionProfile:Z$,mergedWorkspaces:v9,workspacesView:Yr,status:cR,workspaceIdForSession:Mr,savePermissionToStorage:Nhe,savePlanModeToStorage:W6,saveSwarmModeToStorage:O$,saveGoalModeToStorage:P$,draftModes:ag,saveUnread:R6,saveActiveWorkspaceToStorage:$he,saveHiddenWorkspacesToStorage:Bhe,goalErrorMessage:c1e,initialized:U$,connectIssue:K$}),$i=Mhe({pushOperationFailure:h1,applySessionsArchivedLocally:Bt.applySessionsArchivedLocally});Pe(()=>_e.mainView,e=>{e==="sessionAdmin"&&$i.ensureSeeded()});function t7(e){return e===_e.activeSessionId&&typeof document<"u"&&document.visibilityState==="visible"&&document.hasFocus()}function Upe(e){_e.turnActiveBySession[e]&&delete _e.turnActiveBySession[e],_e.inFlightBySession[e]&&(_e.inFlightBySession[e]=!1)}function Kpe(e,t,n){const i=_e.promptIdBySession[e],o=_e.goalBySession[e]?.status==="active"||F2.has(e);Bt.finishPromptLocal(e,{turnWasActive:n}),(_e.experimentalFlags?.auto_session_title??_e.config?.experimental?.auto_session_title)===!0&&Bt.maybeGenerateSessionTitle(e),Hs().loadGitStatus(e),e===_e.activeSessionId?cf(e):t==="idle"&&!o&&(_e.unreadBySession[e]=!0,R6({[e]:!0}));const s=(_e.approvalsBySession[e]??[]).length>0,r=(_e.questionsBySession[e]??[]).length>0;!o&&nfe(t,s,r)&&rc().maybeNotifyCompletion(e,{isUserWatching:t7(e),sessionTitle:_e.sessions.find(l=>l.id===e)?.title??"",promptId:i,onClick:()=>{Bt.selectSession(e,{source:"notification"})}})}function Vpe(e,t){const n=t.questions[0],i=n?.header?.trim()??"",o=n?.question?.trim()??"",s=i&&o?`${i}: ${o}`:o||i;rc().maybeNotifyQuestion({isUserWatching:t7(e),sessionTitle:_e.sessions.find(r=>r.id===e)?.title??"",questionPreview:s,questionId:t.questionId,onClick:()=>{Bt.selectSession(e,{source:"notification"})}})}function Zpe(e,t){rc().maybeNotifyApproval({isUserWatching:t7(e),sessionTitle:_e.sessions.find(n=>n.id===e)?.title??"",toolName:t.toolName,approvalId:t.approvalId,onClick:()=>{Bt.selectSession(e,{source:"notification"})}})}function pa(){return k1e(),{workspace:S1e,sessions:_1e,activeSessionId:M1e,workspacesView:Yr,workspaceSortMode:P2,visibleWorkspace:fR,activeWorkspaceId:fg,sessionsForView:Ipe,workspaceGroups:zpe,mobileWorkspaceGroups:Ope,pinnedSessions:Ppe,pinnedSessionIds:y9,flatSessions:Tpe,flatSessionsHasMore:Lpe,flatSessionsLoadingMore:F(()=>_e.flatSessionsLoadingMore),doneSessions:Fpe,doneSessionsHasMore:Dpe,doneSessionsLoadingMore:F(()=>_e.doneSessionsLoadingMore),activeSessionArchived:$pe,recentSessionsForWorkspace:Rpe,draftEntry:F(()=>_e.draftEntry),mainView:F(()=>_e.mainView),attentionBySession:pR,pendingBySession:T0,attentionByWorkspace:Hpe,unreadBySession:e7,recentRoots:Wpe,turns:rR,tasks:$1e,activeAppTasks:cg,findBashCommandForTask:nR,auxiliaryTranscripts:D2,getFileUrl:oR,getSessionMediaUrl:sR,todos:z1e,goal:rh,sessionPlans:npe,refreshSessionPlans:I0,invalidateSessionPlans:Phe,swarms:lR,swarmMembersByToolCallId:R1e,activationBadges:ope,compaction:O1e,status:cR,sessionCost:hpe,fileDiff:fpe,selectedDiffPath:F(()=>Hs().selectedDiffPath),fileDiffLoading:F(()=>Hs().fileDiffLoading),fileDiffTexts:F(()=>Hs().fileDiffTexts),fileDiffEmptyFile:F(()=>Hs().fileDiffEmptyFile),changes:cpe,gitInfo:A8,gitDiffStats:dpe,activePullRequest:upe,changesByPath:bpe,pendingApprovals:ape,availableOpenInApps:qpe,connection:P1e,loading:j1e,sessionLoading:H1e,loadingMoreMessages:W1e,hasMoreMessages:q1e,loadMoreMessagesError:U1e,serverVersion:K1e,webTitle:aR,documentBaseTitle:Mpe,backend:Z1e,dangerousBypassAuth:G1e,experimentalFlags:V1e,clearDangerousBypassAuth:Q1e,initialized:U$,connectIssue:K$,permission:Y1e,thinking:J1e,planMode:uR,planArmed:X1e,swarmMode:epe,goalMode:tpe,queued:spe,warnings:rpe,questions:lpe,activity:Y6,turnActive:dg,activeTurnError:L1e,activeTurnRetry:N1e,inFlight:Q6,working:B1e,isStartingFirstPrompt:T1e,models:Zn.models,starredModelIds:Zn.starredModelIds,providers:Zn.providers,fontScale:Bm.fontScale,setFontScale:Bm.setFontScale,colorScheme:Bm.colorScheme,setColorScheme:Bm.setColorScheme,notifyEnabled:F(()=>rc().notifyEnabled),notifySound:F(()=>rc().notifySound),notifyPermission:F(()=>rc().notifyPermission),setNotifyEnabled:e=>rc().setNotifyEnabled(e),setNotifySound:e=>rc().setNotifySound(e),onboarded:Y$,setOnboarded:Ghe,load:Bt.load,selectSession:Bt.selectSession,clearActiveSession:Bt.clearActiveSession,openSessionAdmin:e=>{e!==void 0&&$i.applyFilters({workspaceIds:[e],status:"all",updatedFrom:"",updatedTo:""}),Bt.openSessionAdmin()},closeSessionAdmin:Bt.closeSessionAdmin,sessionAdminItems:F(()=>$i.state.items),sessionAdminTotal:F(()=>$i.state.total),sessionAdminLoading:F(()=>$i.state.loading),sessionAdminFilters:F(()=>$i.state.filters),sessionAdminPage:F(()=>$i.state.page),sessionAdminPageSize:F(()=>$i.state.pageSize),refreshSessionAdminSessions:$i.refresh,applySessionAdminFilters:$i.applyFilters,setSessionAdminWorkspaceFilter:$i.setWorkspaceIds,setSessionAdminStatusFilter:$i.setStatus,setSessionAdminTimeRange:$i.setTimeRange,setSessionAdminPage:$i.setPage,setSessionAdminPageSize:$i.setPageSize,sessionAdminSelectedIds:F(()=>$i.state.selectedIds),sessionAdminSelectedCount:F(()=>$i.state.selectedIds.size),sessionAdminOpenSelectedIds:F(()=>$i.selectedIdsByArchived(!1)),sessionAdminDoneSelectedIds:F(()=>$i.selectedIdsByArchived(!0)),toggleSessionAdminSelection:$i.toggleSelection,toggleSessionAdminPageSelection:$i.togglePageSelection,setSessionAdminSelection:$i.setSelection,clearSessionAdminSelection:$i.clearSelection,selectSessionAdminAllMatching:$i.selectAllMatching,sessionAdminAllMatching:F(()=>$i.state.allMatching),sessionAdminMaterializingAll:F(()=>$i.state.materializingAll),archiveSessions:$i.archiveSessions,restoreSessions:$i.restoreSessions,loadOlderMessages:Bt.loadOlderMessages,loadWorkspaces:Bt.loadWorkspaces,loadMoreSessions:Bt.loadMoreSessions,loadAllSessions:Bt.loadAllSessions,ensureFlatSessions:Bt.ensureFlatSessions,loadMoreFlatSessions:Npe,ensureDoneSessions:Bt.ensureDoneSessions,loadMoreDoneSessions:Bpe,selectWorkspace:Bt.selectWorkspace,openWorkspace:Bt.openWorkspace,openWorkspaceDraft:Bt.openWorkspaceDraft,startSessionAndSendPrompt:Bt.startSessionAndSendPrompt,startSessionAndActivateSkill:Bt.startSessionAndActivateSkill,startSessionAndOpenSideChat:Bt.startSessionAndOpenSideChat,addWorkspaceByPath:Bt.addWorkspaceByPath,browseFs:Bt.browseFs,getFsHome:Bt.getFsHome,sendPrompt:Bt.sendPrompt,steerPrompt:Bt.steerPrompt,steerQueued:Bt.steerQueued,sideChatVisible:Ws.sideChatVisible,sideChatSessionId:Ws.sideChatSessionId,sideChatTurns:Ws.sideChatTurns,sideChatRunning:Ws.sideChatRunning,sideChatSending:Ws.sideChatSending,openSideChat:Ws.openSideChat,closeSideChat:Ws.closeSideChat,sendSideChatPrompt:Ws.sendSideChatPrompt,uploadImage:Bt.uploadImage,abortCurrentPrompt:Bt.abortCurrentPrompt,respondApproval:Bt.respondApproval,respondQuestion:Bt.respondQuestion,dismissQuestion:Bt.dismissQuestion,pendingQuestionActions:Bt.pendingQuestionActions,pendingApprovalActions:Bt.pendingApprovalActions,cancelTask:Bt.cancelTask,setPermission:Bt.setPermission,setThinking:Zn.setThinking,setPlanMode:Bt.setPlanMode,togglePlanMode:Bt.togglePlanMode,setSwarmMode:Bt.setSwarmMode,toggleSwarmMode:Bt.toggleSwarmMode,setGoalMode:Bt.setGoalMode,toggleGoalMode:Bt.toggleGoalMode,createGoal:Bt.createGoal,controlGoal:Bt.controlGoal,enqueue:Bt.enqueue,dismissWarning:Bt.dismissWarning,renameSession:Bt.renameSession,regenerateSessionTitle:Bt.regenerateSessionTitle,renameWorkspace:Bt.renameWorkspace,deleteWorkspace:Bt.deleteWorkspace,reorderWorkspaces:jpe,setWorkspaceSortMode:Cpe,pinSession:wpe,unpinSession:xpe,togglePinSession:_pe,archiveSession:Bt.archiveSession,exportSession:Bt.exportSession,restoreSession:Bt.restoreSession,loadArchivedSessions:Bt.loadArchivedSessions,compact:Bt.compact,forkSession:Bt.forkSession,undo:Bt.undo,unqueue:Bt.unqueue,reorderQueue:Bt.reorderQueue,searchFiles:Bt.searchFiles,loadGitStatus:Hs().loadGitStatus,loadFileDiff:Hs().loadFileDiff,clearFileDiff:Hs().clearFileDiff,listDir:Bt.listDir,readFileContent:Hs().readFileContent,readHostFileContent:Bt.readHostFileContent,probeWorkspacePath:Bt.probeWorkspacePath,getFileDownloadUrl:Bt.getFileDownloadUrl,openWorkspaceFile:Bt.openWorkspaceFile,openInApp:Bt.openInApp,revealWorkspaceFile:Bt.revealWorkspaceFile,resolveImageUrl:Bt.resolveImageUrl,loadModels:Zn.loadModels,loadProviders:Zn.loadProviders,skills:I1e,skillsLoaded:E1e,activateSkill:Zn.activateSkill,setModel:Zn.setModel,toggleStarModel:Zn.toggleStarModel,addProvider:Zn.addProvider,updateProvider:Zn.updateProvider,getProvider:Zn.getProvider,deleteProvider:Zn.deleteProvider,refreshProvider:Zn.refreshProvider,refreshAllProviders:Zn.refreshAllProviders,loadCatalogProviders:Zn.loadCatalogProviders,importCatalogProvider:Zn.importCatalogProvider,importCustomRegistry:Zn.importCustomRegistry,authReady:ppe,defaultModel:gpe,managedProviderStatus:mpe,managedUserInfo:vpe,managedMembership:ype,notify:ug,config:kpe,loadConfig:Bt.loadConfig,updateConfig:Bt.updateConfig,checkAuth:Bt.checkAuth,probeManagedMembership:Bt.probeManagedMembership,startOAuthLogin:Zn.startOAuthLogin,pollOAuthLogin:Zn.pollOAuthLogin,cancelOAuthLogin:Zn.cancelOAuthLogin,getOAuthRegion:Zn.getOAuthRegion,getUsage:Zn.getUsage,logout:Bt.logout}}const H2=[{code:"en",label:"English"},{code:"zh",label:"简体中文"}],da=QG({locale:YF()});function n7(e){da.global.locale.value=e,is(un.locale,e)}const Gpe=["aria-expanded"],Qpe={class:"user-menu-avatar","aria-hidden":"true"},Ype=["src"],Jpe={class:"user-menu-name"},Xpe={class:"user-menu-name"},e0e={class:"user-menu-item-label"},t0e={class:"user-menu-item-label"},n0e={class:"user-menu-item-label user-menu-login-label"},i0e={class:"user-menu-item-label"},o0e={class:"user-menu-row-value"},s0e={class:"user-menu-item-label"},r0e={class:"user-menu-row-value"},l0e={class:"user-menu-item-label"},a0e={key:0,class:"user-menu-usage"},u0e={key:0,class:"user-menu-usage-state"},c0e={key:1,class:"user-menu-usage-state"},d0e={class:"user-menu-usage-error"},f0e={key:2,class:"user-menu-usage-state user-menu-usage-empty"},h0e={class:"user-menu-usage-label"},p0e={key:0,class:"user-menu-usage-hint"},g0e={class:"user-menu-item-label"},m0e={class:"user-menu-item-label"},v0e=Xe({__name:"UserMenu",emits:["login","openSettings"],setup(e,{emit:t}){const n=t,{t:i,locale:o}=zt(),s=pa(),{confirm:r}=Vc(),l=F(()=>s.managedProviderStatus.value==="authenticated"),a=s.managedUserInfo,u=s.managedMembership,c=F(()=>a.value?.nickname||i("sidebar.defaultUserName")),d=F(()=>u.value==="free"||Lle(a.value?.userLevel)),h=F(()=>u.value!=="free"),p=K(!1);Pe(()=>a.value?.avatar,()=>{p.value=!1});const g=F(()=>!!a.value?.avatar&&!p.value),m=s.colorScheme,k=F(()=>i(`theme.${m.value}`)),w=F(()=>m.value==="light"?"light-mode":m.value==="dark"?"dark-mode":"follow-system"),y=[{value:"light",labelKey:"theme.light",icon:"light-mode"},{value:"dark",labelKey:"theme.dark",icon:"dark-mode"},{value:"system",labelKey:"theme.system",icon:"follow-system"}];function b(le){s.setColorScheme(le)}const A=F(()=>H2.find(le=>le.code===o.value)?.label??o.value);function T(le){o.value!==le&&n7(le)}const S=K(!1),x=K({}),_=K(null),L=K(null);let M=null;function N(le){const ge=le.target;ge.closest(".user-menu")||ge.closest(".user-menu-trigger")||ge.closest(".user-submenu")||R()}function I(le){le.key==="Escape"&&(le.stopPropagation(),R())}async function z(){if(S.value){R();return}S.value=!0,document.addEventListener("mousedown",N),document.addEventListener("keydown",I,!0),window.addEventListener("resize",R),l.value&&te(),await dt(),H();const le=L.value;le&&(M=new ResizeObserver(O),M.observe(le))}function H(){const le=L.value,ge=_.value?.el;if(!le||!ge)return;const ke=le.getBoundingClientRect(),Ie=4,Oe=8,we=ge.offsetHeight,Be={left:`${Math.round(ke.left)}px`,width:`${Math.round(ke.width)}px`};ke.top-we-Ie<Oe?x.value={...Be,top:`${Math.round(Math.min(ke.bottom+Ie,window.innerHeight-we-Oe))}px`,bottom:"auto",transformOrigin:"top left","--menu-pop-shift":"-2px"}:x.value={...Be,top:"auto",bottom:`${Math.round(window.innerHeight-ke.top+Ie)}px`,transformOrigin:"bottom left","--menu-pop-shift":"2px"}}function O(){const le=L.value;if(!le)return;j.value=null;const ge=le.getBoundingClientRect();x.value={...x.value,left:`${Math.round(ge.left)}px`,width:`${Math.round(ge.width)}px`}}function R(){S.value=!1,j.value=null,q(),M?.disconnect(),M=null,document.removeEventListener("mousedown",N),document.removeEventListener("keydown",I,!0),window.removeEventListener("resize",R)}Hn(R);const j=K(null),$=K({}),W=K(null),P={usage:null,theme:null,language:null};let Z=null;function ae(le){return ge=>{P[le]=ge instanceof HTMLElement?ge:ge?.$el??null}}function V(le){q(),j.value!==le&&(j.value=le,dt(ne))}function Y(le,ge){le.key!=="Enter"&&le.key!==" "&&le.key!=="ArrowRight"||(le.preventDefault(),V(ge))}function oe(){q(),Z=setTimeout(()=>{j.value=null,Z=null},250)}function q(){Z!==null&&(clearTimeout(Z),Z=null)}function ne(){const le=j.value,ge=_.value?.el,ke=W.value?.el,Ie=le!==null?P[le]:null;if(!ge||!ke||!Ie)return;const Oe=4,we=8,Be=ge.getBoundingClientRect(),tt=Ie.getBoundingClientRect();ke.style.maxWidth="none";const ut=ke.offsetHeight,_t=ke.offsetWidth,{left:Ct,maxWidth:$t,flipped:Vt}=Ace(_t,Be,window.innerWidth,Oe,we),nn=Math.max(we,Math.min(tt.top,window.innerHeight-ut-we));$.value={top:`${Math.round(nn)}px`,left:`${Math.round(Ct)}px`,maxWidth:`${Math.round($t)}px`,transformOrigin:Vt?"top right":"top left","--menu-pop-shift":"-2px"}}const ie=K(!1),pe=K(null);let Ne=0;async function te(){const le=++Ne;ie.value=!0;try{const ge=await s.getUsage();le===Ne&&(pe.value=ge)}finally{le===Ne&&(ie.value=!1)}}Pe([ie,pe],async()=>{j.value==="usage"&&(await dt(),ne())});const be=F(()=>{if(pe.value?.kind!=="ok")return[];const{summary:le,limits:ge}=pe.value,ke=Ele(ge,5,"hour");return[le,ke].filter(Ie=>Ie!=null)}),Q=F(()=>pe.value?.kind==="error"?pe.value.message:i("settings.planUsage.loadFailed"));function ue(le){return le.resetAt===void 0?"":$B(le.resetAt,i)}function Ae(){R(),sg()}function se(){R(),n("login")}function re(){R(),n("openSettings")}async function G(){R(),await r({title:i("sidebar.logoutConfirmTitle"),message:i("sidebar.logoutConfirmMessage"),variant:"danger",action:()=>s.logout()})}return(le,ge)=>(v(),E(Ee,null,[C("button",{ref_key:"triggerRef",ref:L,class:"user-menu-trigger",type:"button","aria-haspopup":"menu","aria-expanded":S.value,onClick:wt(z,["stop"])},[l.value?(v(),E(Ee,{key:0},[C("span",Qpe,[g.value?(v(),E("img",{key:0,src:f(a)?.avatar,alt:"",onError:ge[0]||(ge[0]=ke=>p.value=!0)},null,40,Ype)):(v(),ce(f(ve),{key:1,name:"user",size:"sm"}))]),C("span",Jpe,D(c.value),1)],64)):(v(),E(Ee,{key:1},[U(f(ve),{name:"user"}),C("span",Xpe,D(f(i)("sidebar.notSignedIn")),1)],64))],8,Gpe),(v(),ce(Ds,{to:"body"},[U(fo,{name:"menu-pop"},{default:de(()=>[S.value?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:_,class:"user-menu",style:Kt(x.value),onClick:ge[14]||(ge[14]=wt(()=>{},["stop"]))},{default:de(()=>[l.value?(v(),E(Ee,{key:0},[h.value?(v(),ce(f(Ut),{key:0,ref:ae("usage"),"aria-haspopup":"true","aria-expanded":j.value==="usage",onMouseenter:ge[1]||(ge[1]=ke=>V("usage")),onMouseleave:oe,onFocus:ge[2]||(ge[2]=ke=>V("usage")),onBlur:oe,onClick:ge[3]||(ge[3]=ke=>V("usage")),onKeydown:ge[4]||(ge[4]=ke=>Y(ke,"usage"))},{default:de(()=>[U(f(ve),{name:"histogram",size:"sm"}),C("span",e0e,D(f(i)("settings.planUsage.title")),1),U(f(ve),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"])):X("",!0),d.value?(v(),ce(f(Ut),{key:1,onClick:Ae,onMouseenter:oe},{default:de(()=>[U(f(ve),{name:"music",size:"sm"}),C("span",t0e,D(f(i)("sidebar.upgradeMembership")),1),U(f(ve),{name:"external-link",size:"sm"})]),_:1})):X("",!0),U(f(Ut),{separator:""})],64)):(v(),E(Ee,{key:1},[U(f(Ut),{class:"user-menu-login",onClick:se,onMouseenter:oe},{default:de(()=>[U(f(ve),{name:"log-in",size:"sm"}),C("span",n0e,D(f(i)("sidebar.signIn")),1)]),_:1}),U(f(Ut),{separator:""})],64)),U(f(Ut),{ref:ae("theme"),"aria-haspopup":"true","aria-expanded":j.value==="theme",onMouseenter:ge[5]||(ge[5]=ke=>V("theme")),onMouseleave:oe,onFocus:ge[6]||(ge[6]=ke=>V("theme")),onBlur:oe,onClick:ge[7]||(ge[7]=ke=>V("theme")),onKeydown:ge[8]||(ge[8]=ke=>Y(ke,"theme"))},{default:de(()=>[U(f(ve),{name:w.value,size:"sm"},null,8,["name"]),C("span",i0e,D(f(i)("theme.colorSchemeLabel")),1),C("span",o0e,D(k.value),1),U(f(ve),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"]),U(f(Ut),{ref:ae("language"),"aria-haspopup":"true","aria-expanded":j.value==="language",onMouseenter:ge[9]||(ge[9]=ke=>V("language")),onMouseleave:oe,onFocus:ge[10]||(ge[10]=ke=>V("language")),onBlur:oe,onClick:ge[11]||(ge[11]=ke=>V("language")),onKeydown:ge[12]||(ge[12]=ke=>Y(ke,"language"))},{default:de(()=>[U(f(ve),{name:"translate",size:"sm"}),C("span",s0e,D(f(i)("sidebar.language")),1),C("span",r0e,D(A.value),1),U(f(ve),{name:"chevron-right",size:"sm"})]),_:1},8,["aria-expanded"]),U(f(Ut),{onClick:re,onMouseenter:oe},{default:de(()=>[U(f(ve),{name:"settings",size:"sm"}),C("span",l0e,D(f(i)("settings.title")),1)]),_:1}),l.value?(v(),E(Ee,{key:2},[U(f(Ut),{separator:""}),U(f(Ut),{onClick:ge[13]||(ge[13]=ke=>void G()),onMouseenter:oe},{default:de(()=>[U(f(ve),{name:"log-out",size:"sm"}),$e(" "+D(f(i)("sidebar.signOut")),1)]),_:1})],64)):X("",!0)]),_:1},8,["style"])):X("",!0)]),_:1})])),(v(),ce(Ds,{to:"body"},[U(fo,{name:"menu-pop"},{default:de(()=>[j.value!==null?(v(),ce(f(Zs),{key:0,ref_key:"submenuRef",ref:W,class:"user-submenu",style:Kt($.value),role:j.value==="usage"?"dialog":"menu",onClick:ge[16]||(ge[16]=wt(()=>{},["stop"])),onMouseenter:q,onMouseleave:oe,onFocusin:q,onFocusout:oe},{default:de(()=>[j.value==="usage"?(v(),E("div",a0e,[ie.value?(v(),E("div",u0e,[U(f(Oi),{size:"sm"})])):pe.value?.kind!=="ok"?(v(),E("div",c0e,[C("span",d0e,D(Q.value),1),U(f(Qt),{variant:"ghost",size:"sm",onClick:ge[15]||(ge[15]=ke=>void te())},{default:de(()=>[$e(D(f(i)("settings.planUsage.retry")),1)]),_:1})])):be.value.length===0?(v(),E("span",f0e,D(f(i)("settings.planUsage.empty")),1)):(v(!0),E(Ee,{key:3},pt(be.value,(ke,Ie)=>(v(),E("div",{key:Ie,class:"user-menu-usage-row"},[C("span",h0e,D(f(BB)(ke,f(i))),1),C("span",{class:Fe(["user-menu-usage-value",`sev-${f(Hb)(ke.used,ke.limit)}`])},D(f(i)("settings.planUsage.usedPct",{pct:f(bv)(ke.used,ke.limit)})),3),ue(ke)?(v(),E("span",p0e,D(ue(ke)),1)):X("",!0)]))),128))])):j.value==="theme"?(v(),E(Ee,{key:1},pt(y,ke=>U(f(Ut),{key:ke.value,onClick:Ie=>b(ke.value)},{default:de(()=>[U(f(ve),{name:ke.icon,size:"sm"},null,8,["name"]),C("span",g0e,D(f(i)(ke.labelKey)),1),f(m)===ke.value?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)]),_:2},1032,["onClick"])),64)):(v(!0),E(Ee,{key:2},pt(f(H2),ke=>(v(),ce(f(Ut),{key:ke.code,onClick:Ie=>T(ke.code)},{default:de(()=>[C("span",m0e,D(ke.label),1),f(o)===ke.code?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)]),_:2},1032,["onClick"]))),128))]),_:1},8,["style","role"])):X("",!0)]),_:1})]))],64))}}),y0e=kt(v0e,[["__scopeId","data-v-7472da32"]]),k0e={class:"ep-search"},b0e=["placeholder"],A0e={class:"ep-scroll"},C0e={key:0,class:"ep-grid"},w0e=["onClick"],x0e={key:1,class:"ep-empty"},S0e={class:"ep-label"},_0e={class:"ep-grid"},M0e=["onClick"],I0e={class:"ep-label"},E0e={class:"ep-grid"},T0e=["onClick"],q_="kimi-web.recent-emojis",L0e=Xe({__name:"SessionEmojiPicker",props:{current:{default:null},removable:{type:Boolean,default:!0}},emits:["pick"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),{handleCompositionStart:o,handleCompositionEnd:s,isComposingKeyEvent:r}=bl(),l=e,a=n,u=["⏳","⚠️","🐛","✨","🔥","🚀","🎯","🧪","📝","🔍","🛠️","💡","📦","🎨","🔒","📈","🧹","🚧","✅","❓","🌙","☕","🐳","🗂️","📊","🤖","🧩","⚙️","🌱","📌","💥","🕐"],c={faces:"sidebar.emojiGroupFaces",nature:"sidebar.emojiGroupNature",food:"sidebar.emojiGroupFood",activity:"sidebar.emojiGroupActivity",objects:"sidebar.emojiGroupObjects",symbols:"sidebar.emojiGroupSymbols"},d=Dre.map(S=>({id:S,labelKey:c[S],emojis:SB.filter(x=>x.group===S).map(x=>x.emoji)})),h=K(p());function p(){try{const S=JSON.parse(localStorage.getItem(q_)??"[]");return Array.isArray(S)?S.filter(x=>typeof x=="string"):[]}catch{return[]}}function g(S,x){h.value=zre(h.value,S);try{localStorage.setItem(q_,JSON.stringify(h.value))}catch{}a("pick",S,x)}const m=K(""),k=F(()=>m.value.trim().length>0),w=F(()=>$re(m.value)),y=K(null);cn(()=>y.value?.focus());function b(S){if(r(S))return;const x=w.value[0];k.value&&x&&g(x)}function A(){let S=l.current??void 0;for(;S===void 0||S===l.current;)S=u[Math.floor(Math.random()*u.length)];g(S,"random")}const T=K(null);return t({el:F(()=>T.value?.el),isComposingKeyEvent:r}),(S,x)=>(v(),ce(f(Zs),{ref_key:"menuRef",ref:T,class:"emoji-picker",role:"dialog","aria-label":f(i)("sidebar.sessionEmojiTitle"),onKeydown:x[4]||(x[4]=wt(()=>{},["stop"]))},{default:de(()=>[C("div",k0e,[U(f(ve),{name:"search",size:"sm"}),Wn(C("input",{ref_key:"inputRef",ref:y,"onUpdate:modelValue":x[0]||(x[0]=_=>m.value=_),class:"ep-input",type:"text",placeholder:f(i)("sidebar.searchEmoji"),autocomplete:"off",spellcheck:"false",onKeydown:Ho(b,["enter"]),onCompositionstart:x[1]||(x[1]=(..._)=>f(o)&&f(o)(..._)),onCompositionend:x[2]||(x[2]=(..._)=>f(s)&&f(s)(..._))},null,40,b0e),[[Bs,m.value]])]),C("div",A0e,[k.value?(v(),E(Ee,{key:0},[w.value.length?(v(),E("div",C0e,[(v(!0),E(Ee,null,pt(w.value,_=>(v(),E("button",{key:_,class:Fe(["ep-e",{sel:_===e.current}]),type:"button",onClick:L=>g(_)},D(_),11,w0e))),128))])):(v(),E("div",x0e,D(f(i)("sidebar.noEmojiResults")),1))],64)):(v(),E(Ee,{key:1},[h.value.length?(v(),E(Ee,{key:0},[C("div",S0e,D(f(i)("sidebar.recentEmojis")),1),C("div",_0e,[(v(!0),E(Ee,null,pt(h.value,_=>(v(),E("button",{key:_,class:Fe(["ep-e",{sel:_===e.current}]),type:"button",onClick:L=>g(_)},D(_),11,M0e))),128))])],64)):X("",!0),(v(!0),E(Ee,null,pt(f(d),_=>(v(),E(Ee,{key:_.id},[C("div",I0e,D(f(i)(_.labelKey)),1),C("div",E0e,[(v(!0),E(Ee,null,pt(_.emojis,L=>(v(),E("button",{key:L,class:Fe(["ep-e",{sel:L===e.current}]),type:"button",onClick:M=>g(L)},D(L),11,T0e))),128))])],64))),128))],64))]),U(f(Ut),{separator:""}),U(f(Ut),{role:"button",disabled:!(e.current&&e.removable),onClick:x[3]||(x[3]=_=>a("pick",null))},{default:de(()=>[U(f(ve),{name:"close",size:"sm"}),$e(" "+D(f(i)("sidebar.removeEmoji")),1)]),_:1},8,["disabled"]),U(f(Ut),{role:"button",onClick:A},{default:de(()=>[U(f(ve),{name:"sparkles",size:"sm"}),$e(" "+D(f(i)("sidebar.randomEmoji")),1)]),_:1})]),_:1},8,["aria-label"]))}}),N0e=kt(L0e,[["__scopeId","data-v-b0dbbae4"]]),F0e={class:"row"},D0e={key:0,class:"lead"},B0e={class:"left"},$0e=["readonly","onKeydown"],R0e={key:0,class:"gen-dots","aria-hidden":"true"},z0e=["aria-label"],O0e={key:1,class:"act"},P0e={key:0,class:"ts"},j0e={key:1,class:"st"},H0e={key:1,class:"unread-dot"},W0e={key:2,class:"ha"},q0e={key:0,class:"sub"},U0e={class:"sub-text"},K0e=["aria-label"],V0e={class:"menu-time"},Z0e=Xe({__name:"SessionRow",props:{session:{},active:{type:Boolean},approvalCount:{default:0},questionCount:{default:0},unread:{type:Boolean,default:!1},stateTag:{default:void 0}},emits:["select","rename","generateTitle","renameStateChange","archive","restore","fork","export","pin"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),{sidebarTabs:o}=d1(),s=e,r=n;function l(gt){const Le=new Date(gt);if(Number.isNaN(Le.getTime()))return gt;const ze=Ye=>String(Ye).padStart(2,"0");return`${Le.getFullYear()}-${ze(Le.getMonth()+1)}-${ze(Le.getDate())} ${ze(Le.getHours())}:${ze(Le.getMinutes())}`}const a=F(()=>s.session.updatedAt?l(s.session.updatedAt):s.session.time),u=F(()=>s.session.cwdLabel!==void 0),c=F(()=>Y.value?"idle":og({busy:s.session.busy,unread:s.unread,questionCount:s.questionCount,approvalCount:s.approvalCount,pendingInteraction:s.session.pendingInteraction,lastTurnReason:s.session.lastTurnReason})),d=F(()=>c.value==="awaiting-question"),h=F(()=>c.value==="awaiting-approval"),p=F(()=>c.value==="aborted"),g=F(()=>c.value==="running"),m=F(()=>c.value==="unread"),k=F(()=>c.value!=="idle"),w=K(!1),y=K(null),b=K({});function A(gt){const Le=gt.target;y.value?.el?.contains(Le)||S()}async function T(){O(),w.value=!0,setTimeout(()=>document.addEventListener("mousedown",A),0),window.addEventListener("resize",S),await dt()}function S(){w.value=!1,document.removeEventListener("mousedown",A),window.removeEventListener("resize",S)}_n(()=>{document.removeEventListener("mousedown",A),document.removeEventListener("mousedown",R),window.removeEventListener("keydown",j,!0),window.removeEventListener("resize",S),window.removeEventListener("resize",O)});const x=F(()=>KB(s.session.title)),_=F(()=>{const gt=x.value.emoji;return gt?s.session.title.slice(gt.length):s.session.title}),L=K(!1),M=K(null),N=K({});let I=null;function z(gt,Le,ze){const Ye=M.value?.el,Tt=4,on=8,jt=Ye?.offsetHeight??0,kn=Ye?.offsetWidth??0;let bn=gt.bottom+Tt,mn=!1;bn+jt>window.innerHeight-on&&(bn=Math.max(on,gt.top-jt-Tt),mn=!0);const zn=ze??(Le==="left"?gt.left:gt.right-kn),He=Math.max(on,Math.min(zn,window.innerWidth-kn-on)),st=ze===void 0?Le:`${Math.round(Math.min(Math.max(ze-He,0),kn))}px`;N.value={top:`${Math.round(bn)}px`,left:`${Math.round(He)}px`,transformOrigin:`${st} ${mn?"bottom":"top"}`,"--menu-pop-shift":mn?"2px":"-2px"}}async function H(gt,Le,ze="left",Ye){const Tt=Le??gt?.getBoundingClientRect();if(Tt){if(L.value){O();return}S(),I=gt??null,L.value=!0,setTimeout(()=>document.addEventListener("mousedown",R),0),window.addEventListener("keydown",j,!0),window.addEventListener("resize",O),await dt(),z(Tt,ze,Ye)}}function O(){L.value=!1,I=null,document.removeEventListener("mousedown",R),window.removeEventListener("keydown",j,!0),window.removeEventListener("resize",O)}function R(gt){const Le=gt.target;M.value?.el?.contains(Le)||I?.contains(Le)||O()}function j(gt){gt.key==="Escape"&&(M.value?.isComposingKeyEvent(gt)||(gt.preventDefault(),gt.stopPropagation(),O()))}function $(gt){return gt.clientX||gt.clientY?new DOMRect(gt.clientX,gt.clientY,0,0):void 0}function W(gt){gt.stopPropagation();const Le=gt;H(Le.currentTarget,$(Le),"left",Le.clientX||void 0)}function P(gt){const Le=y.value?.el,ze=gt,Ye=$(ze)??Le?.getBoundingClientRect();S(),H(Le,Ye,"left",ze.clientX||void 0)}function Z(gt){if(O(),gt===x.value.emoji)return;const Le=fae(s.session.title,gt);Le&&Le!==s.session.title&&r("rename",s.session.id,Le)}const ae=pa(),V=F(()=>(ae.experimentalFlags.value.auto_session_title??ae.config.value?.experimental?.auto_session_title)===!0),Y=K(!1),oe=K(""),q=K(null),ne=K(null),ie=K(!1);let pe="",Ne=null;const{handleCompositionStart:te,handleCompositionEnd:be,isComposingKeyEvent:Q}=bl();async function ue(){S(),O(),Y.value=!0,oe.value=s.session.title,await dt();try{q.value?.focus(),q.value?.select()}catch{}}function Ae(){if(!Y.value)return;const gt=oe.value.trim();gt&>!==Ne&>!==s.session.title&&r("rename",s.session.id,gt),Y.value=!1}function se(){ie.value||Ae()}function re(gt){Q(gt)||ie.value||Ae()}function G(gt){Q(gt)||le()}function le(){ie.value=!1,Y.value=!1}function ge(gt){const Le=ne.value;if(!(Le===null||!(gt.target instanceof Node)||Le.contains(gt.target))){if(ie.value){ie.value=!1,Y.value=!1;return}Ae()}}Pe(Y,gt=>{gt?document.addEventListener("pointerdown",ge,!0):document.removeEventListener("pointerdown",ge,!0)}),_n(()=>document.removeEventListener("pointerdown",ge,!0));function ke(){ie.value||(ie.value=!0,pe=oe.value,Ne=null,oe.value="",r("generateTitle",s.session.id,gt=>{ie.value=!1,Y.value&&(oe.value=gt??pe,Ne=gt,dt(()=>{try{q.value?.focus(),q.value?.select()}catch{}}))}))}Pe(Y,gt=>r("renameStateChange",gt));async function Ie(gt){Y.value||(gt.preventDefault(),gt.stopPropagation(),w.value&&S(),await T(),Oe(gt))}function Oe(gt){const Le=y.value?.el,ze=8,Ye=Le?.offsetHeight??0,Tt=Le?.offsetWidth??0;let on=gt.clientY,jt=!1;on+Ye>window.innerHeight-ze&&(on=Math.max(ze,gt.clientY-Ye),jt=!0);let kn=gt.clientX,bn=!1;kn+Tt>window.innerWidth-ze&&(kn=Math.max(ze,gt.clientX-Tt),bn=!0),b.value={top:`${Math.round(on)}px`,left:`${Math.round(kn)}px`,transformOrigin:`${jt?"bottom":"top"} ${bn?"right":"left"}`,"--menu-pop-shift":jt?"2px":"-2px"}}const we=K(!1),Be=K(!1);async function tt(){const gt=await Xo(s.session.id);we.value=gt,Be.value=!gt,setTimeout(()=>{we.value=!1,Be.value=!1,S()},1500)}function ut(){S(),r("fork",s.session.id)}function _t(){S(),r("export",s.session.id)}function Ct(){S(),r("pin",s.session.id)}function $t(){S(),r("archive",s.session.id)}function Vt(){S(),r("restore",s.session.id)}t({closeMenu:S});function nn(){const gt=s.session.pullRequest?.url;gt&&window.open(gt,"_blank","noopener")}return(gt,Le)=>(v(),E("div",{class:Fe(["se",{on:e.active,flat:u.value}]),onClick:Le[8]||(Le[8]=ze=>r("select",e.session.id)),onContextmenu:Ie},[C("div",F0e,[u.value?X("",!0):(v(),E("span",D0e)),C("div",B0e,[Y.value?(v(),E("div",{key:0,ref_key:"renameWrapRef",ref:ne,class:Fe(["rename-wrap",{generating:ie.value}]),onClick:Le[4]||(Le[4]=wt(()=>{},["stop"]))},[Wn(C("input",{ref_key:"renameInputRef",ref:q,"onUpdate:modelValue":Le[0]||(Le[0]=ze=>oe.value=ze),class:"rename-input",readonly:ie.value,onKeydown:[Ho(wt(re,["stop"]),["enter"]),Ho(wt(G,["stop"]),["esc"])],onCompositionstart:Le[1]||(Le[1]=(...ze)=>f(te)&&f(te)(...ze)),onCompositionend:Le[2]||(Le[2]=(...ze)=>f(be)&&f(be)(...ze)),onBlur:se},null,40,$0e),[[Bs,oe.value]]),ie.value?(v(),E("span",R0e,[...Le[9]||(Le[9]=[C("i",null,null,-1),C("i",null,null,-1),C("i",null,null,-1)])])):X("",!0),V.value?(v(),ce(f(gn),{key:1,text:f(i)("sidebar.genTitle")},{default:de(()=>[U(f(Jt),{class:"gen-title-btn",size:"sm",label:f(i)("sidebar.genTitle"),disabled:ie.value,onMousedown:Le[3]||(Le[3]=wt(()=>{},["prevent","stop"])),onClick:wt(ke,["stop"])},{default:de(()=>[U(f(ve),{name:"gen-title"})]),_:1},8,["label","disabled"])]),_:1},8,["text"])):X("",!0)],2)):(v(),E("span",{key:1,class:"t",onDblclick:wt(ue,["stop"])},[x.value.emoji?(v(),E("button",{key:0,type:"button",class:"emoji","aria-label":f(i)("sidebar.setEmoji"),onClick:wt(W,["stop"]),onDblclick:Le[5]||(Le[5]=wt(()=>{},["stop"]))},D(x.value.emoji),41,z0e)):X("",!0),$e(D(_.value),1)],32))]),Y.value?X("",!0):(v(),E("span",O0e,[U(f(gn),{text:f(i)("workspace.awaitingAnswerTitle")},{default:de(()=>[d.value?(v(),ce(f(br),{key:0,variant:"info",size:"sm"},{default:de(()=>[$e(D(f(i)("workspace.awaitingAnswer")),1)]),_:1})):X("",!0)]),_:1},8,["text"]),U(f(gn),{text:f(i)("workspace.awaitingPermissionTitle")},{default:de(()=>[h.value?(v(),ce(f(br),{key:0,variant:"warning",size:"sm"},{default:de(()=>[$e(D(f(i)("workspace.awaitingPermission")),1)]),_:1})):X("",!0)]),_:1},8,["text"]),U(f(gn),{text:f(i)("workspace.abortedTitle")},{default:de(()=>[p.value?(v(),ce(f(br),{key:0,variant:"danger",size:"sm"},{default:de(()=>[$e(D(f(i)("workspace.aborted")),1)]),_:1})):X("",!0)]),_:1},8,["text"]),k.value?g.value||m.value?(v(),E("span",j0e,[g.value?(v(),ce(f(Oi),{key:0,size:"sm"})):(v(),E("span",H0e))])):X("",!0):(v(),E("span",P0e,D(e.session.time),1)),Y.value?X("",!0):(v(),E("span",W0e,[e.stateTag==="done"?(v(),ce(f(gn),{key:0,text:f(i)("sidebar.reopen")},{default:de(()=>[U(f(Jt),{class:"reopen-btn",size:"sm",label:f(i)("sidebar.reopen"),onClick:wt(Vt,["stop"])},{default:de(()=>[U(f(ve),{name:"undo"})]),_:1},8,["label"])]),_:1},8,["text"])):(v(),E(Ee,{key:1},[U(f(gn),{text:e.session.pinned?f(i)("sidebar.unpin"):f(i)("sidebar.pin")},{default:de(()=>[U(f(Jt),{class:"pin-btn",size:"sm",label:e.session.pinned?f(i)("sidebar.unpin"):f(i)("sidebar.pin"),onClick:wt(Ct,["stop"])},{default:de(()=>[U(f(ve),{name:e.session.pinned?"unpin":"pin"},null,8,["name"])]),_:1},8,["label"])]),_:1},8,["text"]),U(f(gn),{text:f(o)?f(i)("sidebar.complete"):f(i)("sidebar.archive")},{default:de(()=>[U(f(Jt),{class:Fe(f(o)?"complete-btn":"archive-btn"),size:"sm",label:f(o)?f(i)("sidebar.complete"):f(i)("sidebar.archive"),onClick:wt($t,["stop"])},{default:de(()=>[U(f(ve),{name:f(o)?"state-done":"archive"},null,8,["name"])]),_:1},8,["class","label"])]),_:1},8,["text"])],64))]))]))]),e.session.cwdLabel!==void 0?(v(),E("div",q0e,[U(f(ve),{class:"sub-icon",name:"folder-closed",size:"sm"}),C("span",U0e,D(e.session.cwdLabel),1),e.session.pullRequest?(v(),E("button",{key:0,type:"button",class:Fe(["pr",`pr--${e.session.pullRequest.state}`]),"aria-label":`PR #${e.session.pullRequest.number}`,onClick:wt(nn,["stop"])},[U(f(ve),{name:"git-pull-request",size:"sm"}),C("span",null,"#"+D(e.session.pullRequest.number),1)],10,K0e)):X("",!0)])):X("",!0),(v(),ce(Ds,{to:"body"},[U(fo,{name:"menu-pop"},{default:de(()=>[w.value?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:y,class:"menu",style:Kt(b.value),onClick:Le[6]||(Le[6]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{danger:Be.value,onClick:tt},{default:de(()=>[U(f(ve),{name:"copy",size:"sm"}),$e(" "+D(Be.value?f(i)("sidebar.copyFailed"):we.value?f(i)("sidebar.copied"):f(i)("sidebar.copySessionId")),1)]),_:1},8,["danger"]),U(f(Ut),{separator:""}),U(f(Ut),{onClick:ue},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(i)("sidebar.rename")),1)]),_:1}),U(f(Ut),{onClick:P},{default:de(()=>[U(f(ve),{name:"emoji",size:"sm"}),$e(" "+D(f(i)("sidebar.setEmoji")),1)]),_:1}),U(f(Ut),{onClick:ut},{default:de(()=>[U(f(ve),{name:"git-fork",size:"sm"}),$e(" "+D(f(i)("sidebar.fork")),1)]),_:1}),U(f(Ut),{onClick:_t},{default:de(()=>[U(f(ve),{name:"download",size:"sm"}),$e(" "+D(f(i)("sidebar.export")),1)]),_:1}),e.stateTag!=="done"?(v(),ce(f(Ut),{key:0,onClick:Ct},{default:de(()=>[U(f(ve),{name:e.session.pinned?"unpin":"pin",size:"sm"},null,8,["name"]),$e(" "+D(e.session.pinned?f(i)("sidebar.unpin"):f(i)("sidebar.pin")),1)]),_:1})):X("",!0),e.stateTag==="done"?(v(),ce(f(Ut),{key:1,onClick:Vt},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),$e(" "+D(f(i)("sidebar.reopen")),1)]),_:1})):(v(),ce(f(Ut),{key:2,onClick:$t},{default:de(()=>[U(f(ve),{name:f(o)?"state-done":"archive",size:"sm"},null,8,["name"]),$e(" "+D(f(o)?f(i)("sidebar.markDone"):f(i)("sidebar.archive")),1)]),_:1})),U(f(Ut),{separator:""}),C("div",V0e,D(f(i)("sidebar.lastActive",{time:a.value})),1)]),_:1},8,["style"])):X("",!0)]),_:1})])),(v(),ce(Ds,{to:"body"},[U(fo,{name:"menu-pop"},{default:de(()=>[L.value?(v(),ce(N0e,{key:0,ref_key:"pickerRef",ref:M,class:"picker",style:Kt(N.value),current:x.value.emoji,removable:x.value.rest.length>0,onClick:Le[7]||(Le[7]=wt(()=>{},["stop"])),onPick:Z},null,8,["style","current","removable"])):X("",!0)]),_:1})]))],34))}}),Pp=kt(Z0e,[["__scopeId","data-v-9068e4e1"]]),G0e=["draggable"],Q0e={class:"gh-top"},Y0e={class:"gh-name"},J0e=["inert"],X0e={key:0,class:"show-more-row"},ege=["disabled"],tge={class:"show-more-label"},nge={key:1,class:"show-more-sep","aria-hidden":"true"},ige={class:"show-more-label"},oge={key:1,class:"group-empty"},sge=Xe({__name:"WorkspaceGroup",props:{group:{},activeWorkspaceId:{},activeId:{},renamingId:{},renameValue:{},renameInputRef:{},pendingBySession:{},unreadBySession:{},wsMenuOpenId:{},dragging:{type:Boolean},sortable:{type:Boolean},isCollapsed:{type:Function},visibleLimit:{type:Function},flashSessionId:{},pinnedDragSession:{},stateTag:{}},emits:["groupClick","groupContextmenu","toggleWsMenu","createInWorkspace","selectSession","renameSession","generateSessionTitle","archiveSession","forkSession","exportSession","pinSession","dropPinnedSession","expand","collapse","confirmRename","cancelRename","updateRenameValue","wsDragstart","wsDragend"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=F({get:()=>i.renameValue,set:M=>o("updateRenameValue",M)}),r=K(!1),l=F(()=>i.pinnedDragSession!=null),a=F(()=>i.pinnedDragSession?.workspaceId===i.group.workspace.id);function u(M){if(i.pinnedDragSession!=null){if(!a.value){M.dataTransfer&&(M.dataTransfer.dropEffect="none");return}M.preventDefault(),M.dataTransfer&&(M.dataTransfer.dropEffect="move"),r.value=!0}}function c(M){i.pinnedDragSession==null||!a.value||(M.preventDefault(),r.value=!1,o("dropPinnedSession",i.pinnedDragSession.id))}function d(M){M.currentTarget.contains(M.relatedTarget)||(r.value=!1)}const h=F(()=>i.visibleLimit(i.group.workspace.id)??i.group.initialCount),p=F(()=>{const M=i.group.sessions.slice(0,h.value);if(i.activeId&&!M.some(N=>N.id===i.activeId)){const N=i.group.sessions.find(I=>I.id===i.activeId);if(N)return[...M,N]}return M}),g=F(()=>i.group.sessions.length>h.value||i.group.hasMore||i.group.loadingMore),m=F(()=>h.value>i.group.initialCount);function k(M){i.renameInputRef.value=M instanceof HTMLInputElement?M:null}const{handleCompositionStart:w,handleCompositionEnd:y,isComposingKeyEvent:b}=bl();function A(M){b(M)||o("confirmRename")}function T(M){b(M)||o("cancelRename")}const S=K(null);function x(M){i.renamingId!==i.group.workspace.id&&o("groupContextmenu",i.group.workspace,M)}function _(M){i.sortable!==!1&&M.dataTransfer&&(M.dataTransfer.effectAllowed="move",M.dataTransfer.setData("text/plain",i.group.workspace.id),o("wsDragstart",i.group.workspace.id))}function L(M,N){N.dataTransfer&&(N.dataTransfer.effectAllowed="move",N.dataTransfer.setData(C2,M),N.dataTransfer.setData("text/plain",M))}return(M,N)=>(v(),E("div",{class:Fe(["group",{dragging:e.dragging,"pinned-drag-active":l.value&&a.value,"pinned-drop-hover":r.value,"pinned-drop-blocked":l.value&&!a.value}]),onDragover:u,onDrop:c,onDragleave:d},[C("div",{class:Fe(["gh",{on:e.group.workspace.id===e.activeWorkspaceId&&e.activeId==="",collapsed:e.isCollapsed(e.group.workspace.id)}]),draggable:e.sortable!==!1&&e.renamingId!==e.group.workspace.id,onClick:N[7]||(N[7]=wt(I=>o("groupClick",e.group.workspace.id,I),["stop"])),onContextmenu:x,onDragstart:_,onDragend:N[8]||(N[8]=I=>o("wsDragend"))},[C("div",Q0e,[e.isCollapsed(e.group.workspace.id)?(v(),ce(f(ve),{key:0,class:"gh-folder",name:"folder-closed"})):(v(),ce(f(ve),{key:1,class:"gh-folder",name:"folder"})),e.renamingId!==e.group.workspace.id?(v(),ce(f(gn),{key:2,text:e.group.workspace.root},{default:de(()=>[C("span",Y0e,D(e.group.workspace.name),1)]),_:1},8,["text"])):Wn((v(),E("input",{key:3,ref:k,"onUpdate:modelValue":N[0]||(N[0]=I=>s.value=I),class:"gh-rename",type:"text",onKeydown:[Ho(A,["enter"]),Ho(T,["esc"])],onCompositionstart:N[1]||(N[1]=(...I)=>f(w)&&f(w)(...I)),onCompositionend:N[2]||(N[2]=(...I)=>f(y)&&f(y)(...I)),onBlur:N[3]||(N[3]=I=>o("cancelRename")),onClick:N[4]||(N[4]=wt(()=>{},["stop"]))},null,544)),[[Bs,s.value]]),e.renamingId!==e.group.workspace.id?(v(),E("div",{key:4,class:Fe(["gh-actions",{open:e.wsMenuOpenId===e.group.workspace.id}])},[U(f(Jt),{class:Fe(["gh-more",{open:e.wsMenuOpenId===e.group.workspace.id}]),size:"sm",label:f(n)("sidebar.options"),tooltip:f(n)("sidebar.options"),"aria-haspopup":"menu","aria-expanded":e.wsMenuOpenId===e.group.workspace.id,onClick:N[5]||(N[5]=wt(I=>o("toggleWsMenu",e.group.workspace,I),["stop"]))},{default:de(()=>[U(f(ve),{name:"dots-horizontal"})]),_:1},8,["class","label","tooltip","aria-expanded"]),U(f(Jt),{class:"gh-add",size:"sm",label:f(n)("workspace.newInGroup"),tooltip:f(n)("workspace.newInGroup"),onClick:N[6]||(N[6]=wt(I=>o("createInWorkspace",e.group.workspace.id),["stop"]))},{default:de(()=>[U(f(ve),{name:"chat-new"})]),_:1},8,["label","tooltip"])],2)):X("",!0)])],42,G0e),C("div",{class:Fe(["group-sessions",{collapsed:e.isCollapsed(e.group.workspace.id)}]),inert:e.isCollapsed(e.group.workspace.id)},[(v(!0),E(Ee,null,pt(p.value,I=>(v(),ce(Pp,{key:I.id,session:I,active:I.id===e.activeId,"approval-count":e.pendingBySession[I.id]?.approvals??0,"question-count":e.pendingBySession[I.id]?.questions??0,unread:e.unreadBySession[I.id]??!1,"state-tag":i.stateTag,draggable:S.value!==I.id,"data-session-id":I.id,class:Fe({"se-locate-flash":e.flashSessionId===I.id}),onDragstart:z=>L(I.id,z),onRenameStateChange:z=>S.value=z?I.id:null,onSelect:N[9]||(N[9]=z=>o("selectSession",z)),onRename:N[10]||(N[10]=(z,H)=>o("renameSession",z,H)),onGenerateTitle:N[11]||(N[11]=(z,H)=>o("generateSessionTitle",z,H)),onArchive:N[12]||(N[12]=z=>o("archiveSession",z)),onFork:N[13]||(N[13]=z=>o("forkSession",z)),onExport:N[14]||(N[14]=z=>o("exportSession",z)),onPin:N[15]||(N[15]=z=>o("pinSession",z))},null,8,["session","active","approval-count","question-count","unread","state-tag","draggable","data-session-id","class","onDragstart","onRenameStateChange"]))),128)),g.value||m.value?(v(),E("div",X0e,[g.value?(v(),E("button",{key:0,class:"show-more",disabled:e.group.loadingMore,onClick:N[16]||(N[16]=wt(I=>o("expand",e.group.workspace.id),["stop"]))},[U(f(ve),{name:"chevron-down",size:"sm"}),C("span",tge,D(e.group.loadingMore?f(n)("sidebar.loadingMore"):f(n)("sidebar.showMore")),1)],8,ege)):X("",!0),g.value&&m.value?(v(),E("span",nge,"·")):X("",!0),m.value?(v(),E("button",{key:2,class:"show-more",onClick:N[17]||(N[17]=wt(I=>o("collapse",e.group.workspace.id),["stop"]))},[U(f(ve),{name:"chevron-up",size:"sm"}),C("span",ige,D(f(n)("sidebar.showLess")),1)])):X("",!0)])):X("",!0),e.group.sessions.length===0?(v(),E("div",oge,D(e.group.pinnedCount>0?f(n)("sidebar.allPinned",{count:e.group.pinnedCount}):f(n)("sidebar.noSessions")),1)):X("",!0)],10,J0e)],34))}}),rge=kt(sge,[["__scopeId","data-v-8a2d5457"]]),lge={class:"pinned-label"},age={class:"pinned-title"},uge=["draggable","onDragstart"],cge=["aria-label","aria-valuenow","aria-valuemin","aria-valuemax"],dge=Xe({__name:"PinnedSessionList",props:{sessions:{},activeId:{},pendingBySession:{},unreadBySession:{},stateTag:{},flashSessionId:{}},emits:["selectSession","renameSession","generateSessionTitle","archiveSession","forkSession","exportSession","pinSession","dropPin","sessionDragStart","sessionDragEnd"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),o=e,s=n,r=K(fce());function l(){r.value=!r.value,r8(r.value)}function a(){r.value&&(r.value=!1,r8(!1))}t({expand:a});const u=F(()=>!r.value&&Ale(o.sessions.length)),c=K(window.innerHeight);function d(){c.value=window.innerHeight}cn(()=>window.addEventListener("resize",d)),Hn(()=>window.removeEventListener("resize",d));const h=K(null),p=K(null);function g(){return h.value?.parentElement?.nextElementSibling??null}const m=K(void 0);function k(){const Le=p.value,ze=g();if(!Le||!ze){m.value=void 0;return}m.value=Le.getBoundingClientRect().height+ze.getBoundingClientRect().height}const w=K(null),y=K(null),b=K(null);function A(){const Le=g();if(!Le)return;const ze=Le.querySelectorAll(".se"),Ye=[];let Tt=0;for(let kn=0;kn<ze.length&&Tt<3;kn++){const bn=ze.item(kn);if(bn.closest(".group-sessions.collapsed")!==null){Ye.push({visible:!1,height:0,viewportBottom:0});continue}Tt+=1;const mn=bn.getBoundingClientRect();Ye.push({visible:!0,height:mn.height,viewportBottom:mn.bottom})}const on=kle(Ye,Le.getBoundingClientRect().top,Le.scrollTop);on.firstRowHeight!==null&&(w.value=on.firstRowHeight),y.value=on.spanToThirdRow;const jt=Number.parseFloat(globalThis.getComputedStyle(Le).paddingBottom);b.value=Number.isFinite(jt)?jt:null}let T=null,S=null;function x(Le){Le.propertyName==="height"&&Le.target.classList.contains("group-sessions")&&A()}cn(()=>{dt(()=>{k(),A();const Le=g();typeof ResizeObserver=="function"&&Le&&(T=new ResizeObserver(k),T.observe(Le)),typeof MutationObserver=="function"&&Le&&(S=new MutationObserver(A),S.observe(Le,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class"]})),Le?.addEventListener("transitionend",x)})}),Hn(()=>{T?.disconnect(),S?.disconnect(),g()?.removeEventListener("transitionend",x)});const _=K(null);function L(Le){_.value=Le,Y!==null&&Le!==Y&&(z.value=!0),p.value?.style.setProperty("max-height",`${Le}px`)}const M=K(null),N=K([]);let I=!1;const z=K(gs(un.sidebarPinnedHeight)!==null),H=F(()=>yle(N.value)),O=F(()=>ble(y.value,b.value,w.value)),R=F(()=>wle(c.value,m.value,H.value,O.value)),{width:j,dragging:$,cursor:W,clamp:P,setWidth:Z,onPointerDown:ae}=w$({storageKey:un.sidebarPinnedHeight,defaultWidth:TS(window.innerHeight),min:()=>H.value,max:()=>I?h3(R.value,M.value,H.value):R.value,axis:"y",applyLive:L,persist:()=>z.value});Pe([c,R],()=>{z.value||(j.value=P(TS(c.value)))});let V=null,Y=null,oe=!1;function q(Le){const ze=p.value;ze&&(A(),I=!0,V=j.value,oe=z.value,Y=P(ze.getBoundingClientRect().height),j.value=Y),ae(Le)}Pe($,Le=>{if(Le)return;I=!1;const ze=_.value;V!==null&&Sle(Y,ze)&&(j.value=P(V),z.value=oe),V=null,Y=null,_.value=null});const ne=F(()=>u.value||$.value);Pe([p,ne,j],([Le,ze,Ye])=>{Le&&(ze?Le.style.setProperty("max-height",`${Ye}px`):Le.style.removeProperty("max-height"))},{immediate:!0});function ie(Le){if(Le.key!=="ArrowUp"&&Le.key!=="ArrowDown")return;Le.preventDefault(),A();const ze=p.value,Ye=h3(R.value,ze?.scrollHeight??null,H.value),Tt=ze?P(ze.getBoundingClientRect().height):j.value,on=(Le.key==="ArrowDown"?1:-1)*(Le.shiftKey?48:16),jt=xle(Tt,on,Ye,H.value);jt!==Tt&&(z.value=!0,Z(jt))}const pe=F(()=>{if(_.value!==null)return _.value;const Le=M.value;return Le===null?j.value:Math.min(j.value,Le)}),Ne=K(!1),te=K(!1),{thumb:be,thumbVisible:Q,update:ue,markScrolling:Ae,onThumbPointerDown:se,onListMouseEnter:re,onListMouseLeave:G,onThumbMouseEnter:le,onThumbMouseLeave:ge}=x$(p);function ke(Le=p.value){if(!Le)return;M.value=Le.scrollHeight;const ze=[Le.children.item(0),Le.children.item(1)].map(Ye=>Ye?Ye.getBoundingClientRect().height:null);(ze.length!==N.value.length||ze.some((Ye,Tt)=>Ye!==N.value[Tt]))&&(N.value=ze),Ne.value=Le.scrollTop>0,te.value=Le.scrollTop+Le.clientHeight<Le.scrollHeight-1,ue()}function Ie(){ke(),Ae()}let Oe=null;Pe(p,(Le,ze)=>{ze&&Oe?.disconnect(),Oe=null,Le&&typeof ResizeObserver=="function"&&(Oe=new ResizeObserver(()=>ke()),Oe.observe(Le)),Le?ke(Le):(M.value=null,N.value=[],Ne.value=!1,te.value=!1,ue())}),s1(()=>ke()),Hn(()=>Oe?.disconnect());const{fontScale:we}=c1();Pe(we,()=>{dt(()=>{ke(),A()})});const Be=K(null),tt=K(null);function ut(Le,ze){if(!ze.dataTransfer)return;ze.dataTransfer.effectAllowed="move",ze.dataTransfer.setData("text/plain",Le),Be.value=Le;const Ye=o.sessions.find(Tt=>Tt.id===Le)?.workspaceId;Ye!==void 0&&s("sessionDragStart",Le,Ye)}function _t(){Be.value=null,s("sessionDragEnd")}Pe(()=>o.sessions,Le=>{Be.value!==null&&!Le.some(ze=>ze.id===Be.value)&&(Be.value=null)});const Ct=K(!1);function $t(Le){return Le.dataTransfer?.types.includes(C2)??!1}function Vt(Le){$t(Le)&&(Le.preventDefault(),Le.dataTransfer&&(Le.dataTransfer.dropEffect="move"),Ct.value=!0)}function nn(Le){Ct.value=!1;const ze=Le.dataTransfer?.getData(C2);ze&&s("dropPin",ze)}function gt(Le){Le.currentTarget.contains(Le.relatedTarget)||(Ct.value=!1)}return(Le,ze)=>(v(),E("div",{ref_key:"pinnedRootEl",ref:h,class:Fe(["pinned",{"drop-active":Ct.value}]),onDragover:Vt,onDrop:nn,onDragleave:gt},[C("div",lge,[C("span",age,D(f(i)("sidebar.pinned")),1),U(f(Jt),{class:Fe(["pinned-toggle",{"pinned-toggle--on":r.value}]),size:"sm",label:r.value?f(i)("sidebar.expandPinned"):f(i)("sidebar.collapsePinned"),tooltip:r.value?f(i)("sidebar.expandPinned"):f(i)("sidebar.collapsePinned"),onClick:wt(l,["stop"])},{default:de(()=>[r.value?(v(),ce(f(ve),{key:0,name:"chevron-right"})):(v(),ce(f(ve),{key:1,name:"chevron-down"}))]),_:1},8,["class","label","tooltip"])]),r.value?X("",!0):(v(),E("div",{key:0,class:Fe(["pinned-rows-wrap",{scrolled:Ne.value,"more-below":te.value}]),onMouseenter:ze[10]||(ze[10]=(...Ye)=>f(re)&&f(re)(...Ye)),onMouseleave:ze[11]||(ze[11]=(...Ye)=>f(G)&&f(G)(...Ye))},[C("div",{ref_key:"pinnedRowsEl",ref:p,class:"pinned-rows",onScroll:Ie},[(v(!0),E(Ee,null,pt(e.sessions,Ye=>(v(),E("div",{key:Ye.id,class:Fe(["pin-row",{dragging:Be.value===Ye.id}]),draggable:tt.value!==Ye.id,onDragstart:Tt=>ut(Ye.id,Tt),onDragend:_t},[U(Pp,{session:Ye,active:Ye.id===e.activeId,"approval-count":e.pendingBySession[Ye.id]?.approvals??0,"question-count":e.pendingBySession[Ye.id]?.questions??0,unread:e.unreadBySession[Ye.id]??!1,"state-tag":o.stateTag,"data-session-id":Ye.id,class:Fe({"se-locate-flash":e.flashSessionId===Ye.id}),onRenameStateChange:Tt=>tt.value=Tt?Ye.id:null,onSelect:ze[0]||(ze[0]=Tt=>s("selectSession",Tt)),onRename:ze[1]||(ze[1]=(Tt,on)=>s("renameSession",Tt,on)),onGenerateTitle:ze[2]||(ze[2]=(Tt,on)=>s("generateSessionTitle",Tt,on)),onArchive:ze[3]||(ze[3]=Tt=>s("archiveSession",Tt)),onFork:ze[4]||(ze[4]=Tt=>s("forkSession",Tt)),onExport:ze[5]||(ze[5]=Tt=>s("exportSession",Tt)),onPin:ze[6]||(ze[6]=Tt=>s("pinSession",Tt))},null,8,["session","active","approval-count","question-count","unread","state-tag","data-session-id","class","onRenameStateChange"])],42,uge))),128))],544),ze[12]||(ze[12]=C("span",{class:"pinned-seam pinned-seam--top","aria-hidden":"true"},null,-1)),ze[13]||(ze[13]=C("span",{class:"pinned-seam pinned-seam--bottom","aria-hidden":"true"},null,-1)),f(be)?(v(),E("span",{key:0,class:Fe(["pinned-thumb",{visible:f(Q)}]),style:Kt({top:`${f(be).top}px`,height:`${f(be).height}px`}),"aria-hidden":"true",onPointerdown:ze[7]||(ze[7]=(...Ye)=>f(se)&&f(se)(...Ye)),onMouseenter:ze[8]||(ze[8]=(...Ye)=>f(le)&&f(le)(...Ye)),onMouseleave:ze[9]||(ze[9]=(...Ye)=>f(ge)&&f(ge)(...Ye))},null,38)):X("",!0)],34)),ne.value?(v(),E("div",{key:1,class:Fe(["pinned-resize",{dragging:f($)}]),style:Kt({cursor:f(W)}),role:"separator","aria-orientation":"horizontal","aria-label":f(i)("sidebar.resizePinnedAria"),"aria-valuenow":Math.round(pe.value),"aria-valuemin":H.value,"aria-valuemax":f(h3)(R.value,M.value,H.value),tabindex:"0",onPointerdown:q,onKeydown:ie},[...ze[14]||(ze[14]=[C("span",{class:"pinned-resize-bar","aria-hidden":"true"},null,-1)])],46,cge)):X("",!0)],34))}}),fge=kt(dge,[["__scopeId","data-v-0c30d45b"]]),hge={class:"ch"},pge={class:"ch-brand"},gge={class:"ch-tail"},mge={class:"search-input"},vge={key:0,class:"status-tabs"},yge={class:"side-section-label"},kge={class:"side-section-title"},bge={class:"side-section-actions"},Age={key:0,class:"empty"},Cge={key:1,class:"show-more-row"},wge=["disabled"],xge={class:"show-more-label"},Sge={key:0,class:"empty"},_ge={key:1,class:"empty"},Mge=["data-ws-id","onDragover","onDrop"],Ige=["onClick","onContextmenu"],Ege={class:"done-gh-name"},Tge={class:"done-gh-count"},Lge={class:"done-gh-act"},Nge={key:0,class:"done-sessions"},Fge={key:2,class:"empty"},Dge={key:3,class:"show-more-row"},Bge=["disabled"],$ge={class:"show-more-label"},Rge=["onClick","onContextmenu"],zge={class:"ws-dir-row"},Oge=["onKeydown"],Pge={key:1,class:"ws-dir-name"},jge={class:"ws-dir-act"},Hge={class:"ws-dir-sub"},Wge={key:0,class:"empty"},qge={class:"folder-drop-card"},Uge={class:"view-menu-label"},Kge={class:"view-menu-check"},Vge={class:"view-menu-check"},Zge={class:"view-menu-label"},Gge={class:"view-menu-check"},Qge={class:"view-menu-check"},U_="var(--color-accent)",Yge=!1,Jge=1e3,Xge=Xe({__name:"Sidebar",props:{activeWorkspace:{default:null},activeWorkspaceId:{default:null},sessions:{},groups:{},workspaceSortMode:{default:"manual"},pinnedSessions:{default:()=>[]},flatSessions:{default:()=>[]},flatHasMore:{type:Boolean,default:!1},flatLoadingMore:{type:Boolean,default:!1},doneSessions:{default:()=>[]},doneHasMore:{type:Boolean,default:!1},doneLoadingMore:{type:Boolean,default:!1},initialized:{type:Boolean,default:!1},activeId:{},attentionBySession:{default:()=>({})},pendingBySession:{default:()=>({})},unreadBySession:{default:()=>({})},colWidth:{default:220},collapsed:{type:Boolean,default:!1},dragging:{type:Boolean,default:!1}},emits:["select","create","createInWorkspace","selectWorkspace","addWorkspace","addWorkspacePaths","rename","generateTitle","archive","restore","fork","export","pin","dropPin","unpin","renameWorkspace","deleteWorkspace","reorderWorkspaces","setWorkspaceSortMode","loadMoreSessions","loadAllSessions","ensureFlatSessions","loadMoreFlatSessions","ensureDoneSessions","loadMoreDoneSessions","openSessionAdmin","openSettings","login","collapse"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),o=e,s=n,r=K(!1),l=d()?["⌘","K"]:["Ctrl","K"],a=d()?["⌃","⇧","O"]:["Ctrl","Shift","O"];function u(){s("loadAllSessions"),r.value=!0}function c(Ke){if(vae(Ke)){Ke.preventDefault(),u();return}!Ke.metaKey&&Ke.ctrlKey&&Ke.shiftKey&&Ke.key.toLowerCase()==="o"&&(Ke.preventDefault(),s("create"))}cn(()=>window.addEventListener("keydown",c)),Hn(()=>window.removeEventListener("keydown",c));function d(){if(typeof navigator>"u")return!1;if(/Mac|iPod|iPhone|iPad/.test(navigator.platform))return!0;const Ke=navigator.userAgentData;return Ke?.platform==="macOS"||Ke?.platform==="iOS"}const h=K(null),p=K(!1),g=K(!1),{thumb:m,thumbVisible:k,scrolling:w,update:y,markScrolling:b,onThumbPointerDown:A,onListMouseEnter:T,onListMouseLeave:S,onThumbMouseEnter:x,onThumbMouseLeave:_}=x$(h);function L(Ke=h.value){Ke&&(p.value=Ke.scrollTop>0,g.value=Ke.scrollTop+Ke.clientHeight<Ke.scrollHeight-1,y())}function M(Ke){L(Ke.target),b()}let N=null;cn(()=>{dt(()=>{L(),typeof ResizeObserver=="function"&&h.value&&(N=new ResizeObserver(()=>L()),N.observe(h.value))})}),s1(()=>L());const{fontScale:I}=c1();Pe(I,()=>void dt(()=>L())),Hn(()=>{N?.disconnect(),Yn&&clearTimeout(Yn),He&&clearTimeout(He)});const z=K(new Set(dce()));function H(Ke){return z.value.has(Ke)}function O(Ke){const Ue=new Set(z.value);Ue.has(Ke)?Ue.delete(Ke):Ue.add(Ke),z.value=Ue,v3(Ue)}function R(){const Ke=new Set(o.groups.map(Ue=>Ue.workspace.id));z.value=Ke,v3(Ke)}function j(){const Ke=new Set;z.value=Ke,v3(Ke)}const $=F(()=>o.groups.length>0&&o.groups.every(Ke=>z.value.has(Ke.workspace.id))),W=K(new Map);function P(Ke){return W.value.get(Ke)}function Z(Ke){const Ue=o.groups.find(rn=>rn.workspace.id===Ke);if(!Ue)return;const yt=(W.value.get(Ke)??Ue.initialCount)+j6,xt=new Map(W.value);xt.set(Ke,yt),W.value=xt,Ue.sessions.length<yt&&Ue.hasMore&&s("loadMoreSessions",Ke)}function ae(Ke){if(!W.value.has(Ke))return;const Ue=new Map(W.value);Ue.delete(Ke),W.value=Ue}const V=K(null),Y=K(null);function oe(Ke){V.value=Ke}function q(){V.value=null,Y.value=null}function ne(Ke){const Ue=Ke.currentTarget.getBoundingClientRect();return Ke.clientY<Ue.top+Ue.height/2?"before":"after"}function ie(Ke,Ue){V.value===null||V.value===Ue||(Ke.preventDefault(),Ke.dataTransfer&&(Ke.dataTransfer.dropEffect="move"),Y.value={id:Ue,position:ne(Ke)})}function pe(Ke){const Ue=V.value,yt=Y.value?.id===Ke?Y.value.position:"before";if(Y.value=null,V.value=null,!Ue||Ue===Ke)return;const xt=Wce(o.groups.map(rn=>rn.workspace.id),Ue,Ke,yt);s("reorderWorkspaces",xt)}const Ne=K(null);function te(Ke,Ue){Ne.value={id:Ke,workspaceId:Ue}}function be(){Ne.value=null}function Q(Ke){Ne.value=null,s("unpin",Ke)}const ue=K(hce());function Ae(Ke){ue.value!==Ke&&(ue.value=Ke,pce(Ke))}const se=K("open"),{sidebarTabs:re}=d1();Pe(re,Ke=>{!Ke&&se.value!=="open"&&(se.value="open")});const G=F(()=>BS([...o.pinnedSessions,...o.flatSessions].map(Ke=>({busy:Ke.busy,unread:o.unreadBySession[Ke.id]??!1,questionCount:o.pendingBySession[Ke.id]?.questions??0,approvalCount:o.pendingBySession[Ke.id]?.approvals??0,pendingInteraction:Ke.pendingInteraction,lastTurnReason:Ke.lastTurnReason})))),le=F(()=>BS(o.doneSessions.map(Ke=>({busy:Ke.busy,unread:o.unreadBySession[Ke.id]??!1,questionCount:o.pendingBySession[Ke.id]?.questions??0,approvalCount:o.pendingBySession[Ke.id]?.approvals??0,pendingInteraction:Ke.pendingInteraction,lastTurnReason:Ke.lastTurnReason})))),ge=F(()=>[{value:"open",label:i("sidebar.tabOpen"),swatch:G.value===null?void 0:U_},{value:"done",label:i("sidebar.tabDone"),swatch:le.value===null?void 0:U_},{value:"workspaces",label:i("sidebar.tabWorkspaces")}]);function ke(Ke){re.value&&(se.value=Ke,Ke==="done"&&s("ensureDoneSessions"))}const Ie=F(()=>Yre(o.groups,o.activeWorkspaceId,re.value)),Oe=F(()=>o.groups.map(Ke=>({workspace:Ke.workspace,sessions:o.doneSessions.filter(Ue=>Ue.workspaceId===Ke.workspace.id).map(Ue=>({...Ue,cwdLabel:void 0}))})).filter(Ke=>Ke.sessions.length>0));Pe(()=>o.initialized,Ke=>{Ke&&(s("ensureFlatSessions"),s("ensureDoneSessions"))},{immediate:!0});const we=K(!1),Be=K({}),tt=K(null);function ut(Ke){const Ue=Ke.target;Ue.closest(".view-menu")||Ue.closest(".side-section-view")||Ct()}async function _t(Ke){if(we.value){Ct();return}const Ue=Ke.currentTarget;we.value=!0,document.addEventListener("mousedown",ut),window.addEventListener("resize",Ct),await dt();const yt=tt.value?.el,xt=Ue.getBoundingClientRect(),rn=4,Zi=8,Gi=yt?.offsetHeight??0,oo=yt?.offsetWidth??0;let qi=xt.bottom+rn,vo=!1;qi+Gi>window.innerHeight-Zi&&(qi=Math.max(Zi,xt.top-Gi-rn),vo=!0);let so=xt.right-oo;so<Zi&&(so=Zi),Be.value={top:`${Math.round(qi)}px`,left:`${Math.round(so)}px`,transformOrigin:vo?"bottom right":"top right","--menu-pop-shift":vo?"2px":"-2px"}}function Ct(){we.value=!1,document.removeEventListener("mousedown",ut),window.removeEventListener("resize",Ct)}function $t(Ke){Ae(Ke),Ct()}function Vt(Ke){s("setWorkspaceSortMode",Ke),Ct()}function nn(){s("openSessionAdmin"),Ct()}const gt=K(null);function Le(Ke,Ue){Ue.dataTransfer&&(Ue.dataTransfer.effectAllowed="move",Ue.dataTransfer.setData(C2,Ke),Ue.dataTransfer.setData("text/plain",Ke))}const ze=F(()=>se.value==="open"&&ue.value==="flat"),Ye=K(!1);function Tt(Ke){!ze.value||Ne.value===null||(Ke.preventDefault(),Ke.dataTransfer&&(Ke.dataTransfer.dropEffect="move"),Ye.value=!0)}function on(Ke){!ze.value||Ne.value===null||(Ke.preventDefault(),Ye.value=!1,Q(Ne.value.id))}function jt(Ke){Ke.currentTarget.contains(Ke.relatedTarget)||(Ye.value=!1)}function kn(Ke,Ue){Ue.target.closest(".gh-more, .gh-add")||O(Ke)}function bn(Ke){s("select",Ke)}function mn(Ke){s("select",Ke),qn(Ke)}const zn=K(null);let He=null;const st=F(()=>o.groups.map(Ke=>Ke.workspace));function et(Ke,Ue){const yt=getComputedStyle(Ke).getPropertyValue(Ue).trim(),xt=/^([\d.]+)(ms|s)$/.exec(yt);if(!xt)return 0;const rn=Number.parseFloat(xt[1]);return xt[2]==="s"?rn*1e3:rn}function Nt(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches?"auto":"smooth"}function Lt(Ke,Ue){zn.value=Ke,He&&clearTimeout(He),He=setTimeout(()=>{zn.value=null,He=null},et(Ue,"--duration-flash"))}function qn(Ke){const Ue=o.groups.find(yt=>yt.sessions.some(xt=>xt.id===Ke));if(!Ue){_o.value?.expand(),dt(()=>{const xt=[..._o.value?.$el?.querySelectorAll("[data-session-id]")??[]].find(rn=>rn.dataset.sessionId===Ke);xt?.scrollIntoView({block:"nearest",behavior:Nt()}),xt&&Lt(Ke,xt)});return}se.value!=="open"&&ke("open"),ue.value!=="grouped"&&Ae("grouped"),H(Ue.workspace.id)&&O(Ue.workspace.id),dt(()=>{const yt=[...h.value?.querySelectorAll("[data-session-id]")??[]].find(xt=>xt.dataset.sessionId===Ke);yt?.scrollIntoView({block:"start",behavior:Nt()}),yt&&Lt(Ke,yt)})}const So=K(null);let Yn=null;function Ir(Ke){se.value!=="open"&&ke("open"),ue.value!=="grouped"&&Ae("grouped"),H(Ke)&&O(Ke),s("selectWorkspace",Ke),dt(()=>{const Ue=[...h.value?.querySelectorAll("[data-ws-id]")??[]].find(yt=>yt.dataset.wsId===Ke);Ue?.scrollIntoView({block:"start",behavior:Nt()}),Ue&&(So.value=Ke,Yn&&clearTimeout(Yn),Yn=setTimeout(()=>{So.value=null,Yn=null},et(Ue,"--duration-flash")))})}const _o=K(null);function It(){se.value!=="open"&&ke("open"),_o.value?_o.value.expand():r8(!1)}t({revealPinnedSection:It});function ms(Ke){It(),s("pin",Ke)}function Er(Ke){_o.value?.expand(),s("dropPin",Ke)}const go=K(0),mo=K(!1);function vs(){go.value=0,mo.value=!1}function _i(Ke){!Sm()||!d3(Ke)||(Ke.preventDefault(),Ke.stopPropagation(),go.value+=1,mo.value=!0)}function Mo(Ke){!Sm()||!d3(Ke)||(Ke.preventDefault(),Ke.stopPropagation(),Ke.dataTransfer&&(Ke.dataTransfer.dropEffect="copy"))}function ys(Ke){!Sm()||!d3(Ke)||(go.value=Math.max(0,go.value-1),go.value===0&&(mo.value=!1))}function Tn(Ke){if(vs(),!Sm())return;const Ue=Gre(Ke);Ue.length!==0&&(Ke.preventDefault(),Ke.stopPropagation(),s("addWorkspacePaths",Ue))}const Un=K(null),Kn=K(""),Pi=K(""),Io=K(null);function Ki(){return Io}function Ti(Ke,Ue){Un.value=Ke,Pi.value=Ue,Kn.value=Ue,dt().then(()=>Io.value?.focus())}function Qs(){const Ke=Un.value,Ue=Kn.value.trim();Ke&&Ue&&Ue!==Pi.value&&s("renameWorkspace",Ke,Ue),Un.value=null}function Li(){Un.value=null}function an(Ke){Kn.value=Ke}const{handleCompositionStart:to,handleCompositionEnd:Jn,isComposingKeyEvent:Wo}=bl();function Mn(Ke){Wo(Ke)||Qs()}const Ni=K(!1),wi=K(null),$o=K({}),$s=K(null);function Vi(Ke){$s.value?.el&&!$s.value.el.contains(Ke.target)&&Rs()}function Cn(Ke,Ue){Ue.preventDefault(),Ue.stopPropagation(),wi.value=Ke,$o.value={top:`${Ue.clientY}px`,left:`${Ue.clientX}px`,transformOrigin:"top left","--menu-pop-shift":"-2px"},Ni.value=!0,document.addEventListener("mousedown",Vi,!0)}function Rs(){Ni.value=!1,document.removeEventListener("mousedown",Vi,!0),wi.value=null}function qo(){wi.value&&Xo(wi.value.root),Rs()}function ar(){wi.value&&Ti(wi.value.id,wi.value.name),Rs()}function ks(){const Ke=wi.value;Ke&&(Rs(),s("deleteWorkspace",Ke.id))}const yi=K(null),Vn=K(null),ji=K({}),Fi=K(null);function bs(Ke){const Ue=Ke.target;Ue.closest(".gh-more")||Ue.closest(".ws-menu")||Eo()}async function As(Ke,Ue){if(yi.value===Ke.id){Eo();return}const yt=Ue.currentTarget;Vn.value=Ke,yi.value=Ke.id,document.addEventListener("mousedown",bs),window.addEventListener("resize",Eo),await dt();const xt=Fi.value?.el,rn=yt.getBoundingClientRect(),Zi=4,Gi=8,oo=xt?.offsetHeight??0,qi=xt?.offsetWidth??0;let vo=rn.bottom+Zi,so=!1;vo+oo>window.innerHeight-Gi&&(vo=Math.max(Gi,rn.top-oo-Zi),so=!0);let Ro=rn.right-qi;Ro<Gi&&(Ro=Gi),ji.value={top:`${Math.round(vo)}px`,left:`${Math.round(Ro)}px`,transformOrigin:so?"bottom right":"top right","--menu-pop-shift":so?"2px":"-2px"}}function Eo(){yi.value=null,Vn.value=null,document.removeEventListener("mousedown",bs),window.removeEventListener("resize",Eo)}function Tr(Ke){Xo(Ke.root),Eo()}function Lr(Ke){Ti(Ke.id,Ke.name),Eo()}function jl(Ke){Eo(),s("deleteWorkspace",Ke.id)}Hn(()=>{document.removeEventListener("mousedown",Vi,!0),document.removeEventListener("mousedown",bs),document.removeEventListener("mousedown",ut),window.removeEventListener("resize",Eo),window.removeEventListener("resize",Ct)});const Nr=K(null);let Di;function Xn(){const Ke=Nr.value;Ke&&(Ke.classList.remove("blink-now"),Ke.getBoundingClientRect(),Ke.classList.add("blink-now"),clearTimeout(Di),Di=setTimeout(()=>Ke.classList.remove("blink-now"),300))}const Cs=ia(()=>Fo(()=>import("./DesignSystemView-TDJEKkA2.js"),__vite__mapDeps([0,1]))),Uo=K(!1);let On,Hi=!1;function Wi(Ke){Hi=!1,clearTimeout(On),Ke.currentTarget.setPointerCapture?.(Ke.pointerId),On=setTimeout(()=>{Hi=!0,Uo.value=!0},Jge)}function rs(Ke){clearTimeout(On);const Ue=Ke.currentTarget;Ue.hasPointerCapture?.(Ke.pointerId)&&Ue.releasePointerCapture(Ke.pointerId)}function jn(){if(Hi){Hi=!1;return}Xn()}return Hn(()=>{clearTimeout(On)}),(Ke,Ue)=>(v(),E("aside",{class:Fe(["side",{"macos-desktop":f(pc),collapsed:e.collapsed,"no-anim":e.dragging}]),style:Kt({width:e.collapsed?"0px":e.colWidth+"px"})},[C("div",{class:"col",style:Kt({width:e.colWidth+"px"}),onDragenter:_i,onDragover:Mo,onDragleave:ys,onDrop:Tn},[C("div",hge,[C("div",pge,[f(pc)?X("",!0):(v(),E(Ee,{key:0},[(v(),E("svg",{ref_key:"logoRef",ref:Nr,class:"ch-logo",viewBox:"0 0 32 22",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-label":"Kimi Code",onClick:jn,onPointerdown:Wi,onPointerup:rs,onPointercancel:rs},[...Ue[58]||(Ue[58]=[$c('<defs data-v-e9b3eef9><mask id="kimiEyes" maskUnits="userSpaceOnUse" data-v-e9b3eef9><rect x="0" y="0" width="32" height="22" fill="#fff" data-v-e9b3eef9></rect><g class="ch-eyes" fill="#000" data-v-e9b3eef9><rect class="ch-eye" x="11.8" y="7" width="2.8" height="8" rx="1.4" data-v-e9b3eef9></rect><rect class="ch-eye" x="17.4" y="7" width="2.8" height="8" rx="1.4" data-v-e9b3eef9></rect></g></mask></defs><rect x="1" y="1" width="30" height="20" rx="6" fill="var(--logo)" mask="url(#kimiEyes)" data-v-e9b3eef9></rect>',2)])],544)),Ue[59]||(Ue[59]=C("span",{class:"ch-name"},"Kimi Code",-1))],64))]),C("div",gge,[f(pc)?X("",!0):(v(),ce(f(Jt),{key:0,class:"ch-collapse",size:"sm",label:f(i)("sidebar.collapseSidebar"),tooltip:f(i)("sidebar.collapseSidebar"),onClick:Ue[0]||(Ue[0]=wt(yt=>s("collapse"),["stop"]))},{default:de(()=>[U(f(ve),{name:"panel-collapse"})]),_:1},8,["label","tooltip"]))])]),U(M$),C("div",{class:Fe(["sidebar-actions",{"sidebar-actions--has-workspace-action":Yge}])},[C("button",{class:"btn-new-chat",type:"button",onClick:Ue[1]||(Ue[1]=wt(yt=>s("create"),["stop"]))},[U(f(ve),{name:"chat-new"}),C("span",null,D(f(i)("sidebar.newChat")),1),U(f(ku),{keys:f(a)},null,8,["keys"])]),X("",!0),C("button",{class:"search",type:"button",onClick:u},[U(f(ve),{class:"search-icon",name:"search"}),C("span",mge,D(f(i)("sidebar.search")),1),U(f(ku),{keys:f(l)},null,8,["keys"])])],2),f(re)?(v(),E("div",vge,[U(f(Vs),{class:"status-seg",size:"sm","model-value":se.value,options:ge.value,"onUpdate:modelValue":ke},null,8,["model-value","options"])])):X("",!0),C("div",{class:Fe(["sessions-head",{"sessions-head--scrolled":p.value}])},[e.pinnedSessions.length>0&&se.value==="open"?(v(),ce(fge,{key:0,ref_key:"pinnedListRef",ref:_o,sessions:e.pinnedSessions,"active-id":e.activeId,"pending-by-session":e.pendingBySession,"unread-by-session":e.unreadBySession,"state-tag":"open","flash-session-id":zn.value,onSelectSession:bn,onRenameSession:Ue[3]||(Ue[3]=(yt,xt)=>s("rename",yt,xt)),onGenerateSessionTitle:Ue[4]||(Ue[4]=(yt,xt)=>s("generateTitle",yt,xt)),onArchiveSession:Ue[5]||(Ue[5]=yt=>s("archive",yt)),onForkSession:Ue[6]||(Ue[6]=yt=>s("fork",yt)),onExportSession:Ue[7]||(Ue[7]=yt=>s("export",yt)),onPinSession:ms,onDropPin:Er,onSessionDragStart:te,onSessionDragEnd:be},null,8,["sessions","active-id","pending-by-session","unread-by-session","flash-session-id"])):X("",!0),C("div",yge,[C("span",kge,D(se.value==="workspaces"?f(i)("sidebar.tabWorkspaces"):se.value==="done"?f(i)("sidebar.tabDone"):f(i)("sidebar.sessionsHeader")),1),C("div",bge,[se.value==="workspaces"?(v(),ce(f(gn),{key:0,text:f(i)("sidebar.newWorkspace")},{default:de(()=>[U(f(Jt),{class:"side-section-toggle",size:"sm",label:f(i)("sidebar.newWorkspace"),onClick:Ue[8]||(Ue[8]=wt(yt=>s("addWorkspace"),["stop"]))},{default:de(()=>[U(f(ve),{name:"folder-plus"})]),_:1},8,["label"])]),_:1},8,["text"])):X("",!0),se.value!=="workspaces"&&ue.value==="grouped"?(v(),ce(f(Jt),{key:1,class:"side-section-toggle",size:"sm",label:$.value?f(i)("sidebar.expandAll"):f(i)("sidebar.collapseAll"),tooltip:$.value?f(i)("sidebar.expandAll"):f(i)("sidebar.collapseAll"),onClick:Ue[9]||(Ue[9]=wt(yt=>$.value?j():R(),["stop"]))},{default:de(()=>[$.value?(v(),ce(f(ve),{key:0,name:"expand"})):(v(),ce(f(ve),{key:1,name:"collapse"}))]),_:1},8,["label","tooltip"])):X("",!0),se.value!=="workspaces"?(v(),ce(f(gn),{key:2,text:f(i)("sidebar.viewSwitcher")},{default:de(()=>[U(f(Jt),{class:"side-section-toggle side-section-view",size:"sm",label:f(i)("sidebar.viewSwitcher"),onClick:wt(_t,["stop"])},{default:de(()=>[U(f(ve),{name:"list-settings"})]),_:1},8,["label"])]),_:1},8,["text"])):X("",!0)])])],2),C("div",{ref_key:"sessionsEl",ref:h,class:Fe(["sessions",{scrolling:f(w),"pinned-drag-active":ze.value&&Ne.value!==null,"flat-pinned-drop-hover":Ye.value}]),onScroll:M,onDragover:Tt,onDrop:on,onDragleave:jt,onMouseenter:Ue[39]||(Ue[39]=(...yt)=>f(T)&&f(T)(...yt)),onMouseleave:Ue[40]||(Ue[40]=(...yt)=>f(S)&&f(S)(...yt))},[se.value==="open"?(v(),E(Ee,{key:0},[ue.value==="flat"?(v(),E(Ee,{key:0},[(v(!0),E(Ee,null,pt(e.flatSessions,yt=>(v(),ce(Pp,{key:yt.id,session:yt,active:yt.id===e.activeId,"approval-count":e.pendingBySession[yt.id]?.approvals??0,"question-count":e.pendingBySession[yt.id]?.questions??0,unread:e.unreadBySession[yt.id]??!1,"state-tag":"open",draggable:gt.value!==yt.id,onDragstart:xt=>Le(yt.id,xt),onRenameStateChange:xt=>gt.value=xt?yt.id:null,onSelect:bn,onRename:Ue[10]||(Ue[10]=(xt,rn)=>s("rename",xt,rn)),onGenerateTitle:Ue[11]||(Ue[11]=(xt,rn)=>s("generateTitle",xt,rn)),onArchive:Ue[12]||(Ue[12]=xt=>s("archive",xt)),onFork:Ue[13]||(Ue[13]=xt=>s("fork",xt)),onExport:Ue[14]||(Ue[14]=xt=>s("export",xt)),onPin:ms},null,8,["session","active","approval-count","question-count","unread","draggable","onDragstart","onRenameStateChange"]))),128)),e.flatSessions.length===0&&!e.flatHasMore&&e.pinnedSessions.length===0?(v(),E("div",Age,D(f(i)("sidebar.noSessions")),1)):X("",!0),e.flatHasMore?(v(),E("div",Cge,[C("button",{class:"show-more",disabled:e.flatLoadingMore,onClick:Ue[15]||(Ue[15]=wt(yt=>s("loadMoreFlatSessions"),["stop"]))},[C("span",xge,D(e.flatLoadingMore?f(i)("sidebar.loadingMore"):f(i)("sidebar.loadMore")),1),U(f(ve),{name:"chevron-down",size:"sm"})],8,wge)])):X("",!0)],64)):(v(),E(Ee,{key:1},[e.groups.length===0?(v(),E("div",Sge,D(f(i)("workspace.noWorkspace")),1)):Ie.value.length===0&&e.pinnedSessions.length===0?(v(),E("div",_ge,D(f(i)("sidebar.noOpenSessions")),1)):(v(!0),E(Ee,{key:2},pt(Ie.value,yt=>(v(),E("div",{key:yt.workspace.id,class:Fe(["ws-drop-target",{"drop-before":Y.value?.id===yt.workspace.id&&Y.value.position==="before","drop-after":Y.value?.id===yt.workspace.id&&Y.value.position==="after","ws-locate-flash":So.value===yt.workspace.id}]),"data-ws-id":yt.workspace.id,onDragover:xt=>ie(xt,yt.workspace.id),onDrop:xt=>pe(yt.workspace.id)},[U(rge,{group:yt,"active-workspace-id":e.activeWorkspaceId,"active-id":e.activeId,"renaming-id":Un.value,"rename-value":Kn.value,"rename-input-ref":Ki(),"pending-by-session":e.pendingBySession,"unread-by-session":e.unreadBySession,"ws-menu-open-id":yi.value,dragging:V.value===yt.workspace.id,sortable:e.workspaceSortMode==="manual","is-collapsed":H,"visible-limit":P,"flash-session-id":zn.value,"pinned-drag-session":Ne.value,"state-tag":"open",onGroupClick:kn,onGroupContextmenu:Cn,onToggleWsMenu:As,onCreateInWorkspace:Ue[16]||(Ue[16]=xt=>s("createInWorkspace",xt)),onSelectSession:bn,onRenameSession:Ue[17]||(Ue[17]=(xt,rn)=>s("rename",xt,rn)),onGenerateSessionTitle:Ue[18]||(Ue[18]=(xt,rn)=>s("generateTitle",xt,rn)),onArchiveSession:Ue[19]||(Ue[19]=xt=>s("archive",xt)),onForkSession:Ue[20]||(Ue[20]=xt=>s("fork",xt)),onExportSession:Ue[21]||(Ue[21]=xt=>s("export",xt)),onPinSession:ms,onDropPinnedSession:Q,onExpand:Z,onCollapse:ae,onConfirmRename:Qs,onCancelRename:Li,onUpdateRenameValue:an,onWsDragstart:oe,onWsDragend:q},null,8,["group","active-workspace-id","active-id","renaming-id","rename-value","rename-input-ref","pending-by-session","unread-by-session","ws-menu-open-id","dragging","sortable","flash-session-id","pinned-drag-session"])],42,Mge))),128))],64))],64)):se.value==="done"?(v(),E(Ee,{key:1},[ue.value==="flat"?(v(!0),E(Ee,{key:0},pt(e.doneSessions,yt=>(v(),ce(Pp,{key:yt.id,session:yt,active:yt.id===e.activeId,"approval-count":e.pendingBySession[yt.id]?.approvals??0,"question-count":e.pendingBySession[yt.id]?.questions??0,unread:e.unreadBySession[yt.id]??!1,"state-tag":"done",onSelect:bn,onRename:Ue[22]||(Ue[22]=(xt,rn)=>s("rename",xt,rn)),onGenerateTitle:Ue[23]||(Ue[23]=(xt,rn)=>s("generateTitle",xt,rn)),onRestore:Ue[24]||(Ue[24]=xt=>s("restore",xt)),onFork:Ue[25]||(Ue[25]=xt=>s("fork",xt)),onExport:Ue[26]||(Ue[26]=xt=>s("export",xt))},null,8,["session","active","approval-count","question-count","unread"]))),128)):(v(!0),E(Ee,{key:1},pt(Oe.value,yt=>(v(),E("div",{key:yt.workspace.id,class:"done-group"},[C("div",{class:"done-gh",onClick:xt=>O(yt.workspace.id),onContextmenu:xt=>Cn(yt.workspace,xt)},[H(yt.workspace.id)?(v(),ce(f(ve),{key:0,class:"done-gh-folder",name:"folder-closed"})):(v(),ce(f(ve),{key:1,class:"done-gh-folder",name:"folder"})),C("span",Ege,D(yt.workspace.name),1),C("span",Tge,D(yt.sessions.length),1),C("span",Lge,[U(f(Jt),{class:Fe(["gh-more",{open:yi.value===yt.workspace.id}]),size:"sm",label:f(i)("sidebar.options"),tooltip:f(i)("sidebar.options"),"aria-haspopup":"menu","aria-expanded":yi.value===yt.workspace.id,onClick:wt(xt=>As(yt.workspace,xt),["stop"])},{default:de(()=>[U(f(ve),{name:"dots-horizontal"})]),_:1},8,["class","label","tooltip","aria-expanded","onClick"])])],40,Ige),H(yt.workspace.id)?X("",!0):(v(),E("div",Nge,[(v(!0),E(Ee,null,pt(yt.sessions,xt=>(v(),ce(Pp,{key:xt.id,session:xt,active:xt.id===e.activeId,"approval-count":e.pendingBySession[xt.id]?.approvals??0,"question-count":e.pendingBySession[xt.id]?.questions??0,unread:e.unreadBySession[xt.id]??!1,"state-tag":"done",onSelect:bn,onRename:Ue[27]||(Ue[27]=(rn,Zi)=>s("rename",rn,Zi)),onGenerateTitle:Ue[28]||(Ue[28]=(rn,Zi)=>s("generateTitle",rn,Zi)),onRestore:Ue[29]||(Ue[29]=rn=>s("restore",rn)),onFork:Ue[30]||(Ue[30]=rn=>s("fork",rn)),onExport:Ue[31]||(Ue[31]=rn=>s("export",rn))},null,8,["session","active","approval-count","question-count","unread"]))),128))]))]))),128)),e.doneSessions.length===0&&!e.doneHasMore?(v(),E("div",Fge,D(f(i)("sidebar.noDoneSessions")),1)):X("",!0),e.doneHasMore?(v(),E("div",Dge,[C("button",{class:"show-more",disabled:e.doneLoadingMore,onClick:Ue[32]||(Ue[32]=wt(yt=>s("loadMoreDoneSessions"),["stop"]))},[C("span",$ge,D(e.doneLoadingMore?f(i)("sidebar.loadingMore"):f(i)("sidebar.loadMore")),1),U(f(ve),{name:"chevron-down",size:"sm"})],8,Bge)])):X("",!0)],64)):(v(),E(Ee,{key:2},[(v(!0),E(Ee,null,pt(e.groups,yt=>(v(),E("div",{key:yt.workspace.id,class:Fe(["ws-dir",{on:yt.workspace.id===e.activeWorkspaceId}]),onClick:xt=>s("createInWorkspace",yt.workspace.id),onContextmenu:xt=>Cn(yt.workspace,xt)},[C("div",zge,[U(f(ve),{class:"ws-dir-icon",name:"folder-closed"}),Un.value===yt.workspace.id?Wn((v(),E("input",{key:0,ref_for:!0,ref:xt=>Io.value=xt,"onUpdate:modelValue":Ue[33]||(Ue[33]=xt=>Kn.value=xt),class:"ws-dir-rename",type:"text",onKeydown:[Ho(wt(Mn,["stop"]),["enter"]),Ue[34]||(Ue[34]=Ho(wt(xt=>Li(),["stop"]),["esc"]))],onCompositionstart:Ue[35]||(Ue[35]=(...xt)=>f(to)&&f(to)(...xt)),onCompositionend:Ue[36]||(Ue[36]=(...xt)=>f(Jn)&&f(Jn)(...xt)),onBlur:Ue[37]||(Ue[37]=xt=>Li()),onClick:Ue[38]||(Ue[38]=wt(()=>{},["stop"]))},null,40,Oge)),[[Bs,Kn.value]]):(v(),E("span",Pge,D(yt.workspace.name),1)),C("span",jge,[Un.value!==yt.workspace.id?(v(),ce(f(Jt),{key:0,class:Fe(["gh-more",{open:yi.value===yt.workspace.id}]),size:"sm",label:f(i)("sidebar.options"),tooltip:f(i)("sidebar.options"),"aria-haspopup":"menu","aria-expanded":yi.value===yt.workspace.id,onClick:wt(xt=>As(yt.workspace,xt),["stop"])},{default:de(()=>[U(f(ve),{name:"dots-horizontal"})]),_:1},8,["class","label","tooltip","aria-expanded","onClick"])):X("",!0)])]),C("div",Hge,D(yt.workspace.root),1)],42,Rge))),128)),e.groups.length===0?(v(),E("div",Wge,D(f(i)("workspace.noWorkspace")),1)):X("",!0)],64))],34),f(m)?(v(),E("div",{key:1,class:Fe(["sessions-thumb",{visible:f(k)}]),style:Kt({top:`${f(m).top}px`,height:`${f(m).height}px`}),"aria-hidden":"true",onPointerdown:Ue[41]||(Ue[41]=(...yt)=>f(A)&&f(A)(...yt)),onMouseenter:Ue[42]||(Ue[42]=(...yt)=>f(x)&&f(x)(...yt)),onMouseleave:Ue[43]||(Ue[43]=(...yt)=>f(_)&&f(_)(...yt))},null,38)):X("",!0),C("div",{class:Fe(["side-footer",{"side-footer--shadowed":g.value}])},[U(y0e,{onLogin:Ue[44]||(Ue[44]=yt=>s("login")),onOpenSettings:Ue[45]||(Ue[45]=yt=>s("openSettings"))})],2),C("div",{class:Fe(["folder-drop-overlay",{show:mo.value}]),"aria-hidden":"true"},[C("div",qge,[U(f(ve),{name:"folder",size:"lg"}),C("span",null,D(f(i)("sidebar.dropToAddWorkspace")),1)])],2)],36),U(fo,{name:"menu-pop"},{default:de(()=>[Ni.value?(v(),ce(f(Zs),{key:0,ref_key:"ghMenuRef",ref:$s,class:"gh-menu",style:Kt($o.value),onClick:Ue[46]||(Ue[46]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{onClick:qo},{default:de(()=>[U(f(ve),{name:"copy",size:"sm"}),$e(" "+D(f(i)("sidebar.copyPath")),1)]),_:1}),U(f(Ut),{class:"workspace-rename-item",onClick:ar},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(i)("sidebar.rename")),1)]),_:1}),U(f(Ut),{danger:"",onClick:ks},{default:de(()=>[U(f(ve),{name:"close",size:"sm"}),$e(" "+D(f(i)("sidebar.removeWorkspace")),1)]),_:1})]),_:1},8,["style"])):X("",!0)]),_:1}),U(fo,{name:"menu-pop"},{default:de(()=>[yi.value!==null&&Vn.value?(v(),ce(f(Zs),{key:0,ref_key:"wsMenuRef",ref:Fi,class:"ws-menu",style:Kt(ji.value),onClick:Ue[50]||(Ue[50]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{onClick:Ue[47]||(Ue[47]=yt=>Tr(Vn.value))},{default:de(()=>[U(f(ve),{name:"copy",size:"sm"}),$e(" "+D(f(i)("sidebar.copyPath")),1)]),_:1}),U(f(Ut),{class:"workspace-rename-item",onClick:Ue[48]||(Ue[48]=yt=>Lr(Vn.value))},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(i)("sidebar.rename")),1)]),_:1}),U(f(Ut),{danger:"",onClick:Ue[49]||(Ue[49]=yt=>jl(Vn.value))},{default:de(()=>[U(f(ve),{name:"close",size:"sm"}),$e(" "+D(f(i)("sidebar.removeWorkspace")),1)]),_:1})]),_:1},8,["style"])):X("",!0)]),_:1}),U(fo,{name:"menu-pop"},{default:de(()=>[we.value?(v(),ce(f(Zs),{key:0,ref_key:"viewMenuRef",ref:tt,class:"view-menu",style:Kt(Be.value),onClick:Ue[55]||(Ue[55]=wt(()=>{},["stop"]))},{default:de(()=>[C("div",Uge,D(f(i)("sidebar.viewGroup")),1),U(f(Ut),{onClick:Ue[51]||(Ue[51]=yt=>$t("flat"))},{default:de(()=>[U(f(ve),{name:"list",size:"sm"}),$e(" "+D(f(i)("sidebar.viewFlat"))+" ",1),C("span",Kge,[ue.value==="flat"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])]),_:1}),U(f(Ut),{onClick:Ue[52]||(Ue[52]=yt=>$t("grouped"))},{default:de(()=>[U(f(ve),{name:"tree-view",size:"sm"}),$e(" "+D(f(i)("sidebar.viewGrouped"))+" ",1),C("span",Vge,[ue.value==="grouped"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])]),_:1}),ue.value==="grouped"?(v(),E(Ee,{key:0},[C("div",Zge,D(f(i)("sidebar.sortGroup")),1),U(f(Ut),{onClick:Ue[53]||(Ue[53]=yt=>Vt("manual"))},{default:de(()=>[U(f(ve),{name:"grip",size:"sm"}),$e(" "+D(f(i)("sidebar.sortManual"))+" ",1),C("span",Gge,[e.workspaceSortMode==="manual"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])]),_:1}),U(f(Ut),{onClick:Ue[54]||(Ue[54]=yt=>Vt("recent"))},{default:de(()=>[U(f(ve),{name:"clock",size:"sm"}),$e(" "+D(f(i)("sidebar.sortRecent"))+" ",1),C("span",Qge,[e.workspaceSortMode==="recent"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])]),_:1})],64)):X("",!0),f(re)?(v(),E(Ee,{key:1},[U(f(Ut),{separator:""}),U(f(Ut),{onClick:nn},{default:de(()=>[U(f(ve),{name:"session-admin",size:"sm"}),$e(" "+D(f(i)("sidebar.sessionAdmin")),1)]),_:1})],64)):X("",!0)]),_:1},8,["style"])):X("",!0)]),_:1}),r.value?(v(),ce(bde,{key:0,sessions:e.sessions,workspaces:st.value,"active-id":e.activeId,onSelect:mn,onSelectWorkspace:Ir,onClose:Ue[56]||(Ue[56]=yt=>r.value=!1)},null,8,["sessions","workspaces","active-id"])):X("",!0),(v(),ce(Ds,{to:"body"},[Uo.value?(v(),ce(f(Cs),{key:0,onClose:Ue[57]||(Ue[57]=yt=>Uo.value=!1)})):X("",!0)]))],6))}}),eme=kt(Xge,[["__scopeId","data-v-e9b3eef9"]]),tme=["aria-label"],nme=Xe({__name:"ResizeHandle",props:{storageKey:{},defaultWidth:{},min:{},max:{},reverse:{type:Boolean},ariaLabel:{},applyLive:{}},emits:["update:width","update:dragging"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),{width:s,dragging:r,cursor:l,onPointerDown:a}=w$({storageKey:n.storageKey,defaultWidth:n.defaultWidth,min:n.min,max:()=>n.max,reverse:n.reverse,applyLive:n.applyLive});return i("update:width",s.value),Pe(s,u=>i("update:width",u)),Pe(r,u=>i("update:dragging",u)),(u,c)=>(v(),E("div",{class:Fe(["rh",{dragging:f(r)}]),style:Kt({cursor:f(l)}),role:"separator","aria-orientation":"vertical","aria-label":e.ariaLabel??f(o)("layout.resizeHandleAria"),onPointerdown:c[0]||(c[0]=(...d)=>f(a)&&f(a)(...d))},[...c[1]||(c[1]=[C("span",{class:"rh-bar","aria-hidden":"true"},null,-1)])],46,tme))}}),K_=kt(nme,[["__scopeId","data-v-1c6dfdc5"]]),ime={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function ome(e,t){return v(),E("svg",ime,[...t[0]||(t[0]=[C("path",{d:"M12.0684 2.03418C12.5654 2.03421 12.9687 2.43755 12.9688 2.93457V11.0996H21.0654C21.5625 11.0996 21.9658 11.503 21.9658 12C21.9658 12.497 21.5625 12.9004 21.0654 12.9004H12.9688V21.0654C12.9687 21.5624 12.5654 21.9658 12.0684 21.9658C11.5713 21.9658 11.168 21.5625 11.168 21.0654V12.9004H2.93457C2.43751 12.9004 2.03418 12.4971 2.03418 12C2.03418 11.5029 2.43751 11.0996 2.93457 11.0996H11.168V2.93457C11.168 2.43753 11.5713 2.03418 12.0684 2.03418Z",fill:"currentColor"},null,-1)])])}const sme=St({name:"kimi-add",render:ome}),rme={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function lme(e,t){return v(),E("svg",rme,[...t[0]||(t[0]=[C("path",{id:"p0",d:"M 0 -9.9 C -5.468 -9.9 -9.9 -5.468 -9.9 0 C -9.9 1.923 -9.351 3.719 -8.402 5.239 C -8.402 5.239 -9.483 7.821 -9.483 7.821 C -9.896 8.809 -9.171 9.9 -8.099 9.9 C -8.099 9.9 0 9.9 0 9.9 C 5.468 9.9 9.9 5.468 9.9 0 C 9.9 -5.468 5.468 -9.9 0 -9.9 Z M -8.1 0 C -8.1 -4.474 -4.474 -8.1 0 -8.1 C 4.473 -8.1 8.1 -4.474 8.1 0 C 8.1 4.473 4.473 8.1 -0.001 8.1 C -0.001 8.1 -7.648 8.1 -7.648 8.1 L -6.365 5.035 C -6.365 5.035 -6.648 4.629 -6.648 4.629 C -7.563 3.317 -8.1 1.723 -8.1 0 Z",transform:"matrix(1 0 0 1 12 12)",fill:"currentColor","fill-rule":"evenodd"},null,-1),C("path",{id:"p1",d:"M 3.6 0.5 L -2.6 0.5 M 0.5 -2.573 L 0.5 3.573",transform:"translate(11.5 11.5)",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round"},null,-1)])])}const ame=St({name:"kimi-add-conversation",render:lme}),ume={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function cme(e,t){return v(),E("svg",ume,[...t[0]||(t[0]=[C("path",{d:"M15.0996 12C15.5967 12 16 12.4033 16 12.9004C15.9998 13.3973 15.5965 13.7998 15.0996 13.7998H8.90039C8.40346 13.7998 8.00021 13.3973 8 12.9004C8 12.4033 8.40333 12 8.90039 12H15.0996Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M19 3.2002C20.5464 3.2002 21.7998 4.4536 21.7998 6V7C21.7998 8.03565 21.2363 8.93754 20.4004 9.42188V17C20.4004 19.1539 18.6539 20.9004 16.5 20.9004H7.5C5.34609 20.9004 3.59961 19.1539 3.59961 17V9.42188C2.76374 8.93754 2.2002 8.03565 2.2002 7V6C2.2002 4.4536 3.4536 3.2002 5 3.2002H19ZM5.40039 17C5.40039 18.1598 6.3402 19.0996 7.5 19.0996H16.5C17.6598 19.0996 18.5996 18.1598 18.5996 17V9.7998H5.40039V17ZM4.89746 5.00488C4.39333 5.05621 4 5.48232 4 6V7L4.00488 7.10254C4.05278 7.57297 4.42703 7.94722 4.89746 7.99512L5 8H19C19.5523 8 20 7.55228 20 7V6C20 5.44772 19.5523 5 19 5H5L4.89746 5.00488Z",fill:"currentColor"},null,-1)])])}const dme=St({name:"kimi-archive",render:cme}),fme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function hme(e,t){return v(),E("svg",fme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.386 21.6387C11.7378 21.988 12.3059 21.987 12.6565 21.6364L18.1949 16.098C18.5464 15.7465 18.5464 15.1766 18.1949 14.8252C17.8434 14.4737 17.2736 14.4737 16.9221 14.8252L12.9201 18.8272V3.00002C12.9201 2.50297 12.5171 2.10003 12.0201 2.10003C11.523 2.10003 11.1201 2.50297 11.1201 3.00002V18.8383L7.07554 14.8229C6.7228 14.4727 6.15295 14.4747 5.80275 14.8275C5.45255 15.1802 5.45461 15.7501 5.80735 16.1003L11.386 21.6387Z",fill:"currentColor"},null,-1)])])}const pme=St({name:"kimi-arrow-down",render:hme}),gme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function mme(e,t){return v(),E("svg",gme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.16127 12.814C1.81197 12.4622 1.81299 11.8941 2.16357 11.5435L7.70203 6.00506C8.0535 5.65359 8.62335 5.65359 8.97482 6.00506C9.32629 6.35653 9.32629 6.92638 8.97482 7.27785L4.97276 11.2799H20.8C21.297 11.2799 21.7 11.6829 21.7 12.1799C21.7 12.677 21.297 13.0799 20.8 13.0799H4.96171L8.97712 17.1244C9.32732 17.4772 9.32526 18.047 8.97252 18.3972C8.61978 18.7474 8.04993 18.7454 7.69973 18.3926L2.16127 12.814Z",fill:"currentColor"},null,-1)])])}const vme=St({name:"kimi-arrow-left",render:mme}),yme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function kme(e,t){return v(),E("svg",yme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M21.4387 12.814C21.788 12.4622 21.787 11.8941 21.4364 11.5436L15.8979 6.0051C15.5464 5.65363 14.9766 5.65363 14.6251 6.0051C14.2737 6.35657 14.2737 6.92642 14.6251 7.27789L18.6272 11.28H2.79998C2.30293 11.28 1.89998 11.6829 1.89998 12.18C1.89998 12.677 2.30293 13.08 2.79998 13.08H18.6382L14.6228 17.1245C14.2726 17.4772 14.2747 18.0471 14.6274 18.3973C14.9802 18.7475 15.55 18.7454 15.9002 18.3927L21.4387 12.814Z",fill:"currentColor"},null,-1)])])}const bme=St({name:"kimi-arrow-right",render:kme}),Ame={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Cme(e,t){return v(),E("svg",Ame,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.386 2.36129C11.7378 2.01198 12.3059 2.013 12.6565 2.36358L18.1949 7.90204C18.5464 8.25351 18.5464 8.82336 18.1949 9.17483C17.8434 9.52631 17.2736 9.52631 16.9221 9.17483L12.9201 5.17277V21C12.9201 21.497 12.5171 21.9 12.0201 21.9C11.523 21.9 11.1201 21.497 11.1201 21V5.16172L7.07554 9.17713C6.7228 9.52733 6.15295 9.52527 5.80275 9.17253C5.45255 8.81979 5.45461 8.24995 5.80735 7.89975L11.386 2.36129Z",fill:"currentColor"},null,-1)])])}const wme=St({name:"kimi-arrow-up",render:Cme}),xme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Sme(e,t){return v(),E("svg",xme,[...t[0]||(t[0]=[C("path",{d:"M19.3027 5.9053C19.6542 5.55397 20.2247 5.55388 20.5761 5.9053C20.9273 6.25675 20.9273 6.82734 20.5761 7.17874L9.65911 18.0948C9.30773 18.4461 8.73814 18.446 8.38665 18.0948L3.42376 13.1328C3.0726 12.7814 3.07263 12.2118 3.42376 11.8604C3.77524 11.509 4.34575 11.5089 4.6972 11.8604L9.02239 16.1856L19.3027 5.9053Z",fill:"currentColor"},null,-1)])])}const _me=St({name:"kimi-check",render:Sme}),Mme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Ime(e,t){return v(),E("svg",Mme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.3912 16.7134C11.743 17.0627 12.3111 17.0617 12.6617 16.7111L19.6364 9.73641C19.9878 9.38494 19.9878 8.81509 19.6364 8.46362C19.2849 8.11215 18.7151 8.11215 18.3636 8.46362L12.023 14.8042L5.63407 8.46132C5.28133 8.11112 4.71149 8.11318 4.36129 8.46592C4.01109 8.81866 4.01314 9.3885 4.36588 9.73871L11.3912 16.7134Z",fill:"currentColor"},null,-1)])])}const Eme=St({name:"kimi-chevron-down",render:Ime}),Tme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Lme(e,t){return v(),E("svg",Tme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M16.1261 12.6088C16.4754 12.257 16.4743 11.6889 16.1238 11.3383L9.14904 4.36363C8.79757 4.01216 8.22772 4.01216 7.87625 4.36363C7.52477 4.7151 7.52477 5.28495 7.87625 5.63642L14.2169 11.977L7.87395 18.3659C7.52375 18.7187 7.52581 19.2885 7.87855 19.6387C8.23129 19.9889 8.80113 19.9869 9.15133 19.6341L16.1261 12.6088Z",fill:"currentColor"},null,-1)])])}const Nme=St({name:"kimi-chevron-right",render:Lme}),Fme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Dme(e,t){return v(),E("svg",Fme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.3912 8.46132C11.743 8.11202 12.3111 8.11304 12.6617 8.46362L19.6364 15.4383C19.9878 15.7898 19.9878 16.3597 19.6364 16.7111C19.2849 17.0626 18.7151 17.0626 18.3636 16.7111L12.023 10.3705L5.63407 16.7134C5.28133 17.0636 4.71149 17.0616 4.36129 16.7088C4.01109 16.3561 4.01314 15.7862 4.36588 15.436L11.3912 8.46132Z",fill:"currentColor"},null,-1)])])}const Bme=St({name:"kimi-chevron-up",render:Dme}),$me={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Rme(e,t){return v(),E("svg",$me,[...t[0]||(t[0]=[C("circle",{cx:"12",cy:"12",r:"10.875",stroke:"currentColor","stroke-width":"2.25"},null,-1),C("path",{d:"M7.125 12.6L10.65 16.125L17.025 8.85",stroke:"currentColor","stroke-width":"2.25","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const zme=St({name:"kimi-circle-check",render:Rme}),Ome={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Pme(e,t){return v(),E("svg",Ome,[...t[0]||(t[0]=[C("path",{d:"M11.8999 6.79965C12.397 6.79965 12.7997 7.20235 12.7997 7.69941V11.7266L14.7359 13.6629C15.0873 14.0143 15.0879 14.584 14.7366 14.9355C14.3852 15.287 13.8148 15.287 13.4633 14.9355L11.2632 12.7355C11.0947 12.5668 11.0002 12.338 11.0001 12.0995V7.69941C11.0001 7.20238 11.4029 6.7997 11.8999 6.79965Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 1.89893C17.4677 1.89893 21.9001 6.33147 21.9002 11.7991C21.9002 17.2669 17.4678 21.6993 12 21.6993C6.53228 21.6993 2.09985 17.2669 2.09985 11.7991C2.09998 6.33147 6.53236 1.89893 12 1.89893ZM20.1 11.7998C20.1 7.32616 16.4737 3.69984 12 3.69984C7.5264 3.69984 3.90008 7.32616 3.90008 11.7998C3.90032 16.2732 7.52655 19.8998 12 19.8998C16.4735 19.8998 20.0998 16.2732 20.1 11.7998Z",fill:"currentColor"},null,-1)])])}const jme=St({name:"kimi-clock",render:Pme}),Hme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Wme(e,t){return v(),E("svg",Hme,[...t[0]||(t[0]=[C("path",{d:"M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z",fill:"currentColor"},null,-1)])])}const qme=St({name:"kimi-close",render:Wme}),Ume={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Kme(e,t){return v(),E("svg",Ume,[...t[0]||(t[0]=[C("path",{d:"M9.85815 11.957C10.9074 11.957 11.7583 12.8083 11.7585 13.8574V19.8574C11.7585 20.3545 11.3552 20.7578 10.8582 20.7578C10.3611 20.7578 9.95776 20.3545 9.95776 19.8574V13.8574C9.95755 13.8024 9.91325 13.7578 9.85815 13.7578H3.85815C3.3611 13.7578 2.95776 13.3545 2.95776 12.8574C2.95798 12.3605 3.36123 11.957 3.85815 11.957H9.85815Z",fill:"currentColor"},null,-1),C("path",{d:"M12.8582 2.95703C13.3551 2.95703 13.7583 3.36054 13.7585 3.85742V9.85742C13.7585 9.91265 13.8029 9.95703 13.8582 9.95703H19.8582C20.3551 9.95703 20.7583 10.3605 20.7585 10.8574C20.7585 11.3545 20.3552 11.7578 19.8582 11.7578H13.8582C12.8088 11.7578 11.9578 10.9068 11.9578 9.85742V3.85742C11.958 3.36054 12.3612 2.95703 12.8582 2.95703Z",fill:"currentColor"},null,-1)])])}const Vme=St({name:"kimi-collapse",render:Kme}),Zme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Gme(e,t){return v(),E("svg",Zme,[...t[0]||(t[0]=[C("path",{d:"M11.9004 2.19995C17.3678 2.20016 21.7998 6.63285 21.7998 12.1003C21.7996 17.5677 17.3677 21.9995 11.9004 21.9998H3.80078C2.72946 21.9996 2.00334 20.9089 2.41699 19.9207L3.49805 17.3386C2.54871 15.8189 2.00007 14.0226 2 12.1003C2 6.63272 6.43277 2.19995 11.9004 2.19995ZM11.9004 3.99976C7.42688 3.99976 3.7998 7.62684 3.7998 12.1003C3.79989 13.8228 4.33669 15.4175 5.25195 16.7292L5.53516 17.1345L4.25195 20.2H11.8994C16.3727 20.1999 19.9998 16.5736 20 12.1003C20 7.62697 16.3737 3.99997 11.9004 3.99976ZM8.9541 10.8005C9.75473 10.8006 10.4041 11.4491 10.4043 12.2498C10.4043 13.0505 9.75482 13.6998 8.9541 13.7C8.15329 13.7 7.50391 13.0506 7.50391 12.2498C7.50406 11.4491 8.15339 10.8005 8.9541 10.8005ZM15.1533 10.8005C15.9539 10.8006 16.6034 11.4491 16.6035 12.2498C16.6035 13.0505 15.954 13.6998 15.1533 13.7C14.3525 13.7 13.7031 13.0506 13.7031 12.2498C13.7033 11.4491 14.3526 10.8005 15.1533 10.8005Z",fill:"currentColor"},null,-1)])])}const Qme=St({name:"kimi-comment",render:Gme}),Yme={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Jme(e,t){return v(),E("svg",Yme,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17 7.09961C19.1539 7.09961 20.9004 8.84609 20.9004 11V17C20.9004 19.1539 19.1539 20.9004 17 20.9004H11C8.84609 20.9004 7.09961 19.1539 7.09961 17V11C7.09961 8.84609 8.84609 7.09961 11 7.09961H17ZM11 8.90039C9.8402 8.90039 8.90039 9.8402 8.90039 11V17C8.90039 18.1598 9.8402 19.0996 11 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V11C19.0996 9.8402 18.1598 8.90039 17 8.90039H11Z",fill:"currentColor"},null,-1),C("path",{d:"M13 3.09961C14.4447 3.09961 15.705 3.88644 16.3779 5.0498C16.6265 5.47999 16.4789 6.03049 16.0488 6.2793C15.6186 6.52781 15.0681 6.38029 14.8193 5.9502C14.4548 5.32041 13.776 4.90039 13 4.90039H7C5.8402 4.90039 4.90039 5.8402 4.90039 7V13C4.90039 13.776 5.32041 14.4548 5.9502 14.8193C6.38029 15.0681 6.52781 15.6186 6.2793 16.0488C6.03049 16.4789 5.47999 16.6265 5.0498 16.3779C3.88644 15.705 3.09961 14.4447 3.09961 13V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H13Z",fill:"currentColor"},null,-1)])])}const Xme=St({name:"kimi-copy",render:Jme}),eve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function tve(e,t){return v(),E("svg",eve,[...t[0]||(t[0]=[C("path",{d:"M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 10.2797 2.43414 8.66074 3.19922 7.24707C3.20172 7.24246 3.20453 7.23801 3.20703 7.2334C3.33385 6.99995 3.47181 6.77351 3.61621 6.55176C3.73214 6.37355 3.85079 6.19744 3.97754 6.02734C5.35905 4.17471 7.36856 2.81959 9.68945 2.27051C9.69952 2.26813 9.70965 2.26602 9.71973 2.26367C9.85224 2.23276 9.98563 2.2043 10.1201 2.17871C10.1542 2.17221 10.1884 2.16631 10.2227 2.16016C10.3466 2.13791 10.4712 2.11724 10.5967 2.09961C10.6301 2.09489 10.6637 2.0913 10.6973 2.08691C10.8216 2.07073 10.9465 2.05552 11.0723 2.04395C11.1125 2.04022 11.153 2.0384 11.1934 2.03516C11.4595 2.0139 11.7284 2 12 2ZM11.9941 3.7998C11.9968 3.86623 12 3.93292 12 4C12 6.76142 9.76142 9 7 9C6.14209 9 5.33517 8.78324 4.62988 8.40234C4.09862 9.48861 3.7998 10.7093 3.7998 12C3.7998 12.4438 3.83644 12.8791 3.9043 13.3037C4.52807 12.5673 5.45945 12.0996 6.5 12.0996C8.37777 12.0996 9.90039 13.6222 9.90039 15.5C9.90039 17.0702 8.83532 18.3903 7.38867 18.7812C8.70267 19.6765 10.2901 20.2002 12 20.2002C12.468 20.2002 12.9264 20.1583 13.373 20.083C13.1323 19.4342 13 18.7327 13 18C13 14.6863 15.6863 12 19 12C19.4098 12 19.8098 12.0416 20.1963 12.1201C20.1969 12.0801 20.2002 12.0401 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998H11.9941ZM19 13.7998C16.6804 13.7998 14.7998 15.6804 14.7998 18C14.7998 18.5617 14.9112 19.0972 15.1113 19.5869C17.5225 18.597 19.3558 16.4929 19.9727 13.9141C19.6605 13.8399 19.3349 13.7998 19 13.7998ZM6.5 13.9004C5.61634 13.9004 4.90039 14.6163 4.90039 15.5C4.90039 16.3837 5.61634 17.0996 6.5 17.0996C7.38366 17.0996 8.09961 16.3837 8.09961 15.5C8.09961 14.6163 7.38366 13.9004 6.5 13.9004ZM15.5 6.09961C16.8255 6.09961 17.9004 7.17452 17.9004 8.5C17.9004 9.82548 16.8255 10.9004 15.5 10.9004C14.1745 10.9004 13.0996 9.82548 13.0996 8.5C13.0996 7.17452 14.1745 6.09961 15.5 6.09961ZM15.5 7.90039C15.1686 7.90039 14.9004 8.16863 14.9004 8.5C14.9004 8.83137 15.1686 9.09961 15.5 9.09961C15.8314 9.09961 16.0996 8.83137 16.0996 8.5C16.0996 8.16863 15.8314 7.90039 15.5 7.90039ZM10.1992 4C8.35326 4.41375 6.74333 5.44923 5.59961 6.87598C6.02235 7.08306 6.49716 7.2002 7 7.2002C8.76731 7.2002 10.1992 5.76731 10.1992 4Z",fill:"currentColor"},null,-1)])])}const nve=St({name:"kimi-dark-mode",render:tve}),ive={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function ove(e,t){return v(),E("svg",ive,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2.90002C12.4971 2.90002 12.9 3.30297 12.9 3.80002V12.2939L15.8081 9.38585C16.1595 9.03438 16.7294 9.03438 17.0808 9.38585C17.4323 9.73732 17.4323 10.3072 17.0808 10.6586L12.6364 15.1031C12.4676 15.2719 12.2387 15.3667 12 15.3667C11.7613 15.3667 11.5324 15.2719 11.3636 15.1031L6.91917 10.6586C6.5677 10.3072 6.5677 9.73732 6.91917 9.38585C7.27064 9.03438 7.84049 9.03438 8.19196 9.38585L11.1 12.2939V3.80002C11.1 3.30297 11.503 2.90002 12 2.90002ZM4.00001 13.5874C4.49706 13.5874 4.90001 13.9903 4.90001 14.4874V18.043C4.90001 18.2758 4.99249 18.499 5.1571 18.6636C5.32172 18.8282 5.54498 18.9207 5.77778 18.9207H18.2222C18.455 18.9207 18.6783 18.8283 18.8429 18.6636C19.0075 18.499 19.1 18.2758 19.1 18.043V14.4874C19.1 13.9903 19.5029 13.5874 20 13.5874C20.4971 13.5874 20.9 13.9903 20.9 14.4874V18.043C20.9 18.7531 20.6179 19.4342 20.1157 19.9364C19.6135 20.4386 18.9324 20.7207 18.2222 20.7207H5.77778C5.06759 20.7207 4.38649 20.4386 3.88431 19.9364C3.38213 19.4342 3.10001 18.7531 3.10001 18.043V14.4874C3.10001 13.9903 3.50295 13.5874 4.00001 13.5874Z",fill:"currentColor"},null,-1)])])}const sve=St({name:"kimi-download",render:ove}),rve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function lve(e,t){return v(),E("svg",rve,[...t[0]||(t[0]=[C("path",{d:"M18.0179 3.09998C18.3963 3.10003 18.7709 3.17491 19.1205 3.31971C19.4701 3.46454 19.7884 3.67614 20.056 3.94373C20.3237 4.21144 20.5362 4.52965 20.681 4.87928C20.8258 5.22887 20.8997 5.60423 20.8997 5.9828C20.8997 6.36118 20.8257 6.73591 20.681 7.08533C20.5362 7.43497 20.3237 7.75317 20.056 8.02088L17.639 10.4379L9.15756 18.9183C8.5296 19.5463 7.74274 19.992 6.8812 20.2074L4.21811 20.8734C3.91148 20.95 3.5871 20.8596 3.36362 20.6361C3.14017 20.4126 3.05063 20.0883 3.12729 19.7816L3.79233 17.1185C4.00771 16.257 4.45344 15.4701 5.08139 14.8422L15.9798 3.94373C16.5203 3.40346 17.2536 3.09998 18.0179 3.09998ZM19.0003 19.1C19.4972 19.1002 19.8997 19.5034 19.8997 20.0004C19.8995 20.4971 19.4971 20.8996 19.0003 20.8998H12.0003C11.5034 20.8998 11.1001 20.4973 11.0999 20.0004C11.0999 19.5033 11.5033 19.1 12.0003 19.1H19.0003ZM18.0179 4.89979C17.7309 4.89979 17.4553 5.01417 17.2523 5.21717L6.35385 16.1146C5.95661 16.5119 5.67469 17.01 5.53842 17.5551L5.23666 18.7631L6.44467 18.4613C6.98971 18.3251 7.48782 18.0431 7.8851 17.6459L18.7826 6.74744C18.883 6.64702 18.9635 6.52821 19.0179 6.39686C19.0723 6.26558 19.0999 6.1247 19.0999 5.9828C19.0999 5.84075 19.0723 5.69916 19.0179 5.56776C18.9635 5.43645 18.883 5.31757 18.7826 5.21717C18.6821 5.11678 18.5631 5.03716 18.432 4.9828C18.3008 4.92845 18.16 4.89983 18.0179 4.89979Z",fill:"currentColor"},null,-1)])])}const ave=St({name:"kimi-edit",render:lve}),uve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function cve(e,t){return v(),E("svg",uve,[...t[0]||(t[0]=[C("path",{d:"M5 11.0996C5.49693 11.0996 5.90018 11.5031 5.90039 12V18C5.90039 18.0552 5.94477 18.0996 6 18.0996H12C12.4969 18.0996 12.9002 18.5031 12.9004 19C12.9004 19.4971 12.4971 19.9004 12 19.9004H6C4.95066 19.9004 4.09961 19.0493 4.09961 18V12C4.09982 11.5031 4.50307 11.0996 5 11.0996ZM18 4.09961C19.0492 4.09961 19.9002 4.95084 19.9004 6V12C19.9004 12.4971 19.4971 12.9004 19 12.9004C18.5029 12.9004 18.0996 12.4971 18.0996 12V6C18.0994 5.94495 18.0551 5.90039 18 5.90039H12C11.5029 5.90039 11.0996 5.49706 11.0996 5C11.0998 4.50312 11.5031 4.09961 12 4.09961H18Z",fill:"currentColor"},null,-1)])])}const dve=St({name:"kimi-expand",render:cve}),fve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function hve(e,t){return v(),E("svg",fve,[...t[0]||(t[0]=[C("g",null,[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M13.1723 2.1001C13.9413 2.10018 14.6793 2.40592 15.2231 2.94971L19.0512 6.77783C19.595 7.32162 19.9007 8.0596 19.9008 8.82861V18.0005C19.9008 20.1544 18.1543 21.9009 16.0004 21.9009H8.0004C5.84649 21.9009 4.10001 20.1544 4.10001 18.0005V6.00049C4.10001 3.84658 5.84649 2.1001 8.0004 2.1001H13.1723ZM8.0004 3.90088C6.8406 3.90088 5.90079 4.84069 5.90079 6.00049V18.0005C5.90079 19.1603 6.8406 20.1001 8.0004 20.1001H16.0004C17.1602 20.1001 18.1 19.1603 18.1 18.0005V9.90088H15.0004C13.3988 9.90088 12.1 8.60211 12.1 7.00049V3.90088H8.0004ZM13.9008 7.00049C13.9008 7.608 14.3929 8.1001 15.0004 8.1001H17.8217C17.8072 8.08375 17.7933 8.06681 17.7777 8.05127L13.9496 4.22314C13.9339 4.20745 13.9173 4.19286 13.9008 4.17822V7.00049Z",fill:"currentColor"})],-1)])])}const V_=St({name:"kimi-file",render:hve}),pve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function gve(e,t){return v(),E("svg",pve,[...t[0]||(t[0]=[C("path",{d:"M15.4795 15.4971C15.9765 15.4971 16.3799 15.9004 16.3799 16.3975C16.3799 16.8945 15.9765 17.2978 15.4795 17.2979H8.52051C8.02345 17.2979 7.62012 16.8945 7.62012 16.3975C7.62012 15.9004 8.02345 15.4971 8.52051 15.4971H15.4795Z",fill:"currentColor"},null,-1),C("path",{d:"M12.3359 11.0996C12.8329 11.0997 13.2354 11.503 13.2354 12C13.2354 12.497 12.8329 12.9003 12.3359 12.9004H8.52051C8.02345 12.9004 7.62012 12.4971 7.62012 12C7.62012 11.5029 8.02345 11.0996 8.52051 11.0996H12.3359Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M13.1719 2.09961C13.9408 2.09969 14.6789 2.40555 15.2227 2.94922L19.0508 6.77734C19.5946 7.32113 19.9003 8.05911 19.9004 8.82812V18C19.9004 20.1539 18.1539 21.9004 16 21.9004H8C5.84626 21.9002 4.09961 20.1538 4.09961 18V6C4.09961 3.84621 5.84626 2.09981 8 2.09961H13.1719ZM8 3.90039C6.84037 3.90059 5.90039 4.84032 5.90039 6V18C5.90039 19.1597 6.84037 20.0994 8 20.0996H16C17.1598 20.0996 18.0996 19.1598 18.0996 18V9.90039H15C13.3985 9.90019 12.0996 8.6015 12.0996 7V3.90039H8ZM13.9004 7C13.9004 7.60739 14.3927 8.09941 15 8.09961H17.8213C17.8068 8.08333 17.7928 8.06626 17.7773 8.05078L13.9492 4.22266C13.9335 4.20696 13.9169 4.19237 13.9004 4.17773V7Z",fill:"currentColor"},null,-1)])])}const mve=St({name:"kimi-file-text",render:gve}),vve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function yve(e,t){return v(),E("svg",vve,[...t[0]||(t[0]=[C("path",{d:"M9.2373 3.7002C10.4169 3.7002 11.5297 4.24779 12.249 5.18262L12.4424 5.43359H18C20.0987 5.43359 21.7998 7.13472 21.7998 9.2334V16.5C21.7998 18.5987 20.0987 20.2998 18 20.2998H6C3.90132 20.2998 2.2002 18.5987 2.2002 16.5V7.5C2.2002 5.40132 3.90132 3.7002 6 3.7002H9.2373ZM6 5.5C4.89543 5.5 4 6.39543 4 7.5V16.5C4 17.6046 4.89543 18.5 6 18.5H18C19.0357 18.5 19.887 17.7128 19.9893 16.7041L20 16.5V9.2334C20 8.19775 19.2128 7.34641 18.2041 7.24414L18 7.2334H12.0479L11.9326 7.22656C11.666 7.19561 11.4205 7.05812 11.2549 6.84277L10.8223 6.28027C10.4437 5.78834 9.85808 5.5 9.2373 5.5H6ZM16 9.59961C16.4971 9.59961 16.9004 10.0029 16.9004 10.5C16.9004 10.9971 16.4971 11.4004 16 11.4004H8C7.50294 11.4004 7.09961 10.9971 7.09961 10.5C7.09961 10.0029 7.50294 9.59961 8 9.59961H16Z",fill:"currentColor"},null,-1)])])}const kve=St({name:"kimi-folder",render:yve}),bve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Ave(e,t){return v(),E("svg",bve,[...t[0]||(t[0]=[C("g",null,[C("path",{d:"M18.3623 9.99976L18.209 8.48999C18.2031 8.43161 18.2004 8.37289 18.2002 8.31421C18.1988 8.31196 18.1956 8.30842 18.1904 8.30347C18.1718 8.28559 18.1302 8.26245 18.0713 8.26245H11C10.261 8.26245 9.59753 7.81016 9.32617 7.1228L8.9082 6.06421C8.88101 5.9953 8.85737 5.92501 8.83887 5.85327C8.83778 5.85099 8.833 5.84268 8.81836 5.83179C8.79454 5.81475 8.7549 5.79939 8.70605 5.80054H3.92871C3.86986 5.80054 3.82825 5.82368 3.80957 5.84155C3.80816 5.8429 3.80675 5.84428 3.80566 5.84546L4.47559 14.0955L3.62109 17.5154L5.12109 11.5154C5.34367 10.6251 6.1438 9.99977 7.06152 9.99976H18.3623ZM7.06152 11.7996C6.96976 11.7996 6.88944 11.8629 6.86719 11.9519L5.36719 17.9519C5.33598 18.078 5.43158 18.1999 5.56152 18.2H19.4385C19.5302 18.1999 19.6106 18.1376 19.6328 18.0486L21.1328 12.0486C21.1644 11.9224 21.0686 11.7996 20.9385 11.7996H7.06152ZM20.9385 9.99976C22.2396 9.99977 23.1945 11.2228 22.8789 12.4851L21.3789 18.4851C21.1563 19.3754 20.3562 19.9997 19.4385 19.9998H4.92871C4.41722 19.9998 3.92613 19.8059 3.56445 19.4597C3.20281 19.1135 3.00004 18.6436 3 18.1541L2 5.84644C2.00006 5.35711 2.20311 4.88786 2.56445 4.54175C2.92613 4.19554 3.41722 4.00073 3.92871 4.00073H8.66406C9.10133 3.99051 9.5296 4.1225 9.87793 4.37573C10.2285 4.63118 10.4767 4.99457 10.582 5.40405L11 6.46167H18.0713C18.5828 6.46167 19.0739 6.65648 19.4355 7.00269C19.7971 7.34888 20 7.81883 20 8.30835L20.1719 9.99976H20.9385Z",fill:"currentColor"})],-1)])])}const Cve=St({name:"kimi-folder-open",render:Ave}),wve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function xve(e,t){return v(),E("svg",wve,[...t[0]||(t[0]=[C("path",{d:"M9.5 3Q10.8 8.2 16 9.5Q10.8 10.8 9.5 16Q8.2 10.8 3 9.5Q8.2 8.2 9.5 3Z",fill:"currentColor"},null,-1),C("path",{d:"M17.25 13.5Q18 16.5 21 17.25Q18 18 17.25 21Q16.5 18 13.5 17.25Q16.5 16.5 17.25 13.5Z",fill:"currentColor"},null,-1)])])}const Sve=St({name:"kimi-gen-title",render:xve}),_ve={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function Mve(e,t){return v(),E("svg",_ve,[...t[0]||(t[0]=[C("path",{id:"af-p0",d:"M -2.619 -8.3 C -1.815 -8.3 -1.048 -7.97 -0.499 -7.39 C -0.499 -7.39 0.141 -6.712 0.141 -6.712 C 0.141 -6.712 5.75 -6.712 5.75 -6.712 C 7.904 -6.712 9.65 -4.986 9.65 -2.858 C 9.65 -2.858 9.65 -1.71 9.65 -1.71 C 9.65 -1.219 9.247 -0.821 8.75 -0.821 C 8.253 -0.821 7.85 -1.219 7.85 -1.71 C 7.85 -1.71 7.85 -2.858 7.85 -2.858 C 7.849 -4.004 6.91 -4.934 5.75 -4.934 C 5.75 -4.934 -0.207 -4.934 -0.207 -4.934 C -0.484 -4.934 -0.749 -5.047 -0.938 -5.247 C -0.938 -5.247 -1.815 -6.177 -1.815 -6.177 C -2.023 -6.397 -2.315 -6.521 -2.619 -6.521 C -2.619 -6.521 -6.25 -6.521 -6.25 -6.521 C -7.41 -6.521 -8.35 -5.592 -8.35 -4.446 C -8.35 -4.446 -8.35 4.446 -8.35 4.446 C -8.35 5.592 -7.41 6.521 -6.25 6.521 C -6.25 6.521 1.25 6.521 1.25 6.521 C 1.747 6.521 2.15 6.919 2.15 7.41 C 2.15 7.901 1.747 8.3 1.25 8.3 C 1.25 8.3 -6.25 8.3 -6.25 8.3 C -8.404 8.3 -10.15 6.574 -10.15 4.446 C -10.15 4.446 -10.15 -4.446 -10.15 -4.446 C -10.15 -6.574 -8.404 -8.3 -6.25 -8.3 C -6.25 -8.3 -2.619 -8.3 -2.619 -8.3 Z M 3.75 -2.5 C 4.247 -2.5 4.65 -2.097 4.65 -1.6 C 4.65 -1.103 4.247 -0.699 3.75 -0.699 C 3.75 -0.699 -4.25 -0.699 -4.25 -0.699 C -4.747 -0.699 -5.15 -1.103 -5.15 -1.6 C -5.15 -2.097 -4.747 -2.5 -4.25 -2.5 C -4.25 -2.5 3.75 -2.5 3.75 -2.5 Z",transform:"matrix(1 0 0 1 11.75 12)",fill:"currentColor"},null,-1),C("g",{id:"af-p1"},[C("path",{d:"M 2.635 0 L -2.635 0 M 0 -2.635 L 0 2.635",transform:"matrix(1 0 0 1 18.4 16.3)",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round"})],-1)])])}const Ive=St({name:"kimi-folder-plus",render:Mve}),Eve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Tve(e,t){return v(),E("svg",Eve,[...t[0]||(t[0]=[C("path",{d:"M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3ZM12 19.2002C15.9764 19.2002 19.2002 15.9764 19.2002 12C19.2002 8.02355 15.9764 4.7998 12 4.7998V19.2002Z",fill:"currentColor"},null,-1)])])}const Lve=St({name:"kimi-follow-system",render:Tve}),Nve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Fve(e,t){return v(),E("svg",Nve,[...t[0]||(t[0]=[C("path",{d:"M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7ZM12 15.6992C12.4968 15.6992 12.8994 16.1028 12.8994 16.5996C12.8994 17.0964 12.4968 17.5 12 17.5C11.5024 17.5 11.0996 17.0964 11.0996 16.5996C11.0996 16.1028 11.5024 15.6992 12 15.6992ZM12 6.49902C12.4969 6.49922 12.8994 6.86908 12.8994 7.3252V13.6729C12.8994 14.129 12.4969 14.4988 12 14.499C11.5029 14.499 11.0996 14.1291 11.0996 13.6729V7.3252C11.0996 6.86896 11.5029 6.49902 12 6.49902Z",fill:"currentColor"},null,-1)])])}const Dve=St({name:"kimi-full-access",render:Fve}),Bve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function $ve(e,t){return v(),E("svg",Bve,[...t[0]||(t[0]=[C("path",{d:"M12.5092 2.11279C17.7402 2.37781 21.8998 6.70364 21.8998 12.0005C21.8996 17.4153 17.5524 21.8108 12.1576 21.895C12.1056 21.898 12.0532 21.8999 12.0004 21.8999C11.948 21.8999 11.8954 21.8968 11.8432 21.896L11.8422 21.895C6.44751 21.8107 2.10022 17.4152 2.10001 12.0005C2.10001 6.53287 6.53278 2.1001 12.0004 2.1001L12.5092 2.11279ZM8.92715 13.0005C9.02896 14.9787 9.42581 16.721 9.99356 17.9985C10.3249 18.7441 10.6971 19.292 11.0639 19.6411C11.4259 19.9855 11.741 20.1001 12.0004 20.1001C12.2598 20.1 12.5749 19.9856 12.9369 19.6411C13.3037 19.292 13.6749 18.7441 14.0063 17.9985C14.574 16.721 14.9718 14.9788 15.0736 13.0005H8.92715ZM3.96329 13.0005C4.31462 15.8522 6.14714 18.2427 8.66837 19.3823C8.55544 19.1733 8.44916 18.9552 8.34903 18.73C7.66574 17.1926 7.22657 15.1926 7.12344 13.0005H3.96329ZM16.8764 13.0005C16.7732 15.1926 16.3341 17.1926 15.6508 18.73C15.5506 18.9554 15.4435 19.1732 15.3305 19.3823C17.8522 18.2429 19.6851 15.8525 20.0365 13.0005H16.8764ZM8.66934 4.6167C6.08869 5.78266 4.22826 8.25964 3.93985 11.1997H7.11661C7.20176 8.92954 7.64512 6.85497 8.34903 5.271C8.4494 5.04516 8.5561 4.82619 8.66934 4.6167ZM12.0004 3.8999C11.7411 3.8999 11.4259 4.01454 11.0639 4.35889C10.6971 4.70797 10.3249 5.25587 9.99356 6.00146C9.40671 7.32188 9.00186 9.13885 8.91739 11.1997H15.0834C14.9989 9.13884 14.5931 7.32189 14.0063 6.00146C13.6749 5.2559 13.3037 4.70796 12.9369 4.35889C12.5749 4.0144 12.2598 3.90002 12.0004 3.8999ZM15.3295 4.61572C15.443 4.82559 15.5502 5.04471 15.6508 5.271C16.3547 6.85498 16.799 8.92949 16.8842 11.1997H20.06C19.7715 8.25914 17.9108 5.78143 15.3295 4.61572Z",fill:"currentColor"},null,-1)])])}const Rve=St({name:"kimi-globe",render:$ve}),zve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Ove(e,t){return v(),E("svg",zve,[...t[0]||(t[0]=[C("path",{d:"M8 17C8.82834 17 9.5 17.6717 9.5 18.5C9.5 19.3283 8.82834 20 8 20C7.17166 20 6.5 19.3283 6.5 18.5C6.5 17.6717 7.17166 17 8 17ZM16 17C16.8283 17 17.5 17.6717 17.5 18.5C17.5 19.3283 16.8283 20 16 20C15.1717 20 14.5 19.3283 14.5 18.5C14.5 17.6717 15.1717 17 16 17ZM8 10.5C8.82834 10.5 9.5 11.1717 9.5 12C9.5 12.8283 8.82834 13.5 8 13.5C7.17166 13.5 6.5 12.8283 6.5 12C6.5 11.1717 7.17166 10.5 8 10.5ZM16 10.5C16.8283 10.5 17.5 11.1717 17.5 12C17.5 12.8283 16.8283 13.5 16 13.5C15.1717 13.5 14.5 12.8283 14.5 12C14.5 11.1717 15.1717 10.5 16 10.5ZM8 4C8.82834 4 9.5 4.67166 9.5 5.5C9.5 6.32834 8.82834 7 8 7C7.17166 7 6.5 6.32834 6.5 5.5C6.5 4.67166 7.17166 4 8 4ZM16 4C16.8283 4 17.5 4.67166 17.5 5.5C17.5 6.32834 16.8283 7 16 7C15.1717 7 14.5 6.32834 14.5 5.5C14.5 4.67166 15.1717 4 16 4Z",fill:"currentColor"},null,-1)])])}const Pve=St({name:"kimi-grip",render:Ove}),jve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Hve(e,t){return v(),E("svg",jve,[...t[0]||(t[0]=[C("path",{d:"M7.22264 6.10352C7.22264 5.5078 7.48259 4.95449 7.91405 4.56055C8.34271 4.16918 8.90831 3.96198 9.48241 3.96191C9.64155 3.96191 9.80001 3.97936 9.95507 4.01074C10.0127 3.5042 10.2586 3.04178 10.6338 2.69922C11.0625 2.30778 11.6279 2.09961 12.2021 2.09961C12.7763 2.09966 13.3418 2.30783 13.7705 2.69922C13.9947 2.90401 14.1709 3.15244 14.29 3.42676C14.4947 3.37044 14.7071 3.34182 14.9209 3.3418C15.4951 3.3418 16.0605 3.549 16.4892 3.94043C16.8644 4.28293 17.1093 4.74548 17.167 5.25195C17.3223 5.22045 17.4812 5.20312 17.6406 5.20312C18.2147 5.20318 18.7803 5.41135 19.209 5.80273C19.6402 6.19663 19.9004 6.74922 19.9004 7.34473V14.6543C19.9004 17.413 19.2914 19.0434 18.0137 20.21C16.82 21.2998 15.2175 21.9004 13.5615 21.9004C11.7538 21.9004 10.2315 21.5696 8.95702 20.8535C7.67664 20.1341 6.71683 19.0652 5.97362 17.708L3.3496 12.916C3.18848 12.6213 3.10112 12.2914 3.0996 11.9531C3.09812 11.6147 3.18309 11.2835 3.34179 10.9873C3.5001 10.692 3.72639 10.4416 3.99706 10.251C4.26771 10.0604 4.57776 9.93235 4.90136 9.87305C5.56617 9.75102 6.25934 9.84517 6.86425 10.1445C6.9942 10.2088 7.11461 10.2788 7.22264 10.3477V6.10352ZM9.02343 12.7969C9.02336 13.1912 8.76624 13.5395 8.38964 13.6562C8.0129 13.773 7.60387 13.6309 7.38085 13.3057L6.53514 12.0723C6.51218 12.0529 6.48411 12.0282 6.45018 12.002C6.34595 11.9213 6.20986 11.8289 6.06639 11.7578C5.81525 11.6335 5.51637 11.5904 5.22655 11.6436H5.22557C5.15055 11.6573 5.08558 11.6865 5.03417 11.7227C4.98289 11.7588 4.94815 11.7998 4.92772 11.8379C4.90762 11.8755 4.90023 11.9122 4.90038 11.9453C4.90057 11.9782 4.9084 12.0144 4.9287 12.0518L7.55272 16.8438C8.16912 17.9693 8.90989 18.7622 9.83886 19.2842C10.7737 19.8094 11.9704 20.0996 13.5615 20.0996C14.7902 20.0996 15.9536 19.6533 16.7998 18.8809C17.5619 18.185 18.0996 17.1383 18.0996 14.6543V7.34473C18.0996 7.28204 18.0734 7.20342 17.9951 7.13184C17.9139 7.05771 17.7875 7.00396 17.6406 7.00391C17.4937 7.00391 17.3674 7.05771 17.2861 7.13184C17.2077 7.20347 17.1807 7.28199 17.1807 7.34473V11.0693C17.1805 11.5661 16.778 11.9685 16.2812 11.9688C15.7843 11.9688 15.381 11.5662 15.3808 11.0693V5.48242C15.3808 5.41973 15.3537 5.34107 15.2754 5.26953C15.1941 5.19547 15.0677 5.1416 14.9209 5.1416C14.774 5.14166 14.6476 5.19541 14.5664 5.26953C14.4881 5.34105 14.462 5.41974 14.4619 5.48242V11.0693C14.4617 11.5662 14.0584 11.9688 13.5615 11.9688C13.0646 11.9687 12.6613 11.5662 12.6611 11.0693V4.24121C12.6611 4.17852 12.635 4.09989 12.5566 4.02832C12.4754 3.95419 12.349 3.90045 12.2021 3.90039C12.0552 3.90039 11.9289 3.95421 11.8476 4.02832C11.7692 4.09992 11.7422 4.17849 11.7422 4.24121V11.0693C11.742 11.5661 11.3395 11.9685 10.8428 11.9688C10.3458 11.9688 9.94257 11.5662 9.94237 11.0693V6.10352L9.93651 6.05371C9.92534 6.00177 9.89573 5.94433 9.8369 5.89062C9.75567 5.81647 9.62938 5.76172 9.48241 5.76172C9.33554 5.76179 9.2091 5.81651 9.12792 5.89062C9.04964 5.96222 9.02343 6.04084 9.02343 6.10352V12.7969Z",fill:"currentColor"},null,-1)])])}const Wve=St({name:"kimi-hand",render:Hve}),qve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Uve(e,t){return v(),E("svg",qve,[...t[0]||(t[0]=[C("path",{d:"M4 3.33203C4.55224 3.33203 4.99993 3.7798 5 4.33203V18.0908H20.0674C20.6195 18.0908 21.0671 18.5388 21.0674 19.0908C21.0674 19.6431 20.6197 20.0908 20.0674 20.0908H5C3.89543 20.0908 3 19.1954 3 18.0908V4.33203C3.00007 3.7798 3.44776 3.33203 4 3.33203ZM8.19922 9.28418C8.7515 9.28418 9.19922 9.73189 9.19922 10.2842V15.6045C9.19908 16.1567 8.75142 16.6045 8.19922 16.6045C7.64719 16.6043 7.19936 16.1565 7.19922 15.6045V10.2842C7.19922 9.73202 7.6471 9.28438 8.19922 9.28418ZM17.2227 6.85645C17.7748 6.85658 18.2226 7.3043 18.2227 7.85645V15.6045C18.2225 16.1566 17.7747 16.6044 17.2227 16.6045C16.6705 16.6045 16.2228 16.1566 16.2227 15.6045V7.85645C16.2227 7.30422 16.6704 6.85645 17.2227 6.85645ZM12.7109 3.96387C13.2631 3.96387 13.7107 4.41175 13.7109 4.96387V15.6035C13.7109 16.1558 13.2632 16.6035 12.7109 16.6035C12.1587 16.6035 11.7109 16.1558 11.7109 15.6035V4.96387C11.7111 4.41175 12.1588 3.96387 12.7109 3.96387Z",fill:"currentColor"},null,-1)])])}const Kve=St({name:"kimi-histogram",render:Uve}),Vve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Zve(e,t){return v(),E("svg",Vve,[...t[0]||(t[0]=[C("path",{d:"M8.00916 7.50488C8.47326 7.50488 8.91828 7.68943 9.24646 8.01758C9.57465 8.34577 9.75916 8.79075 9.75916 9.25488C9.75916 9.71901 9.57465 10.164 9.24646 10.4922C8.91828 10.8203 8.47326 11.0049 8.00916 11.0049C7.54507 11.0049 7.10001 10.8203 6.77185 10.4922C6.4437 10.164 6.25916 9.71898 6.25916 9.25488C6.25916 8.79078 6.4437 8.34576 6.77185 8.01758C7.10001 7.68942 7.54507 7.50492 8.00916 7.50488Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17.8998 4.09961C20.0537 4.09961 21.8002 5.84609 21.8002 8V16C21.8002 18.1539 20.0537 19.9004 17.8998 19.9004H5.89978C3.74598 19.9003 1.99939 18.1538 1.99939 16V8C1.99939 5.84617 3.74598 4.09974 5.89978 4.09961H17.8998ZM15.4867 12.2539C15.448 12.2184 15.3885 12.2192 15.351 12.2559L11.7338 15.8027C11.0146 16.5079 9.87305 16.5222 9.13708 15.835L6.98669 13.8262C6.95049 13.7924 6.89516 13.791 6.85681 13.8223L3.82361 16.2988C3.96873 17.3168 4.84165 18.0995 5.89978 18.0996H17.8998C18.9375 18.0996 19.7964 17.3466 19.9662 16.3574L15.4867 12.2539ZM5.89978 5.90039C4.74009 5.90052 3.80017 6.84028 3.80017 8V14.002L5.73181 12.4238C6.46046 11.8286 7.51253 11.8634 8.20056 12.5059L10.351 14.5146C10.3897 14.5508 10.4498 14.5497 10.4877 14.5127L14.1049 10.9658C14.819 10.2656 15.9506 10.2466 16.6879 10.9219L19.9994 13.9551V8C19.9994 6.8402 19.0596 5.90039 17.8998 5.90039H5.89978Z",fill:"currentColor"},null,-1)])])}const Gve=St({name:"kimi-image",render:Zve}),Qve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Yve(e,t){return v(),E("svg",Qve,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M5.09375 2.81174C5.4825 2.50796 6.04376 2.56488 6.34766 2.93869L20.1855 19.9602C20.4895 20.3341 20.421 20.8836 20.0322 21.1877C19.6435 21.4917 19.0823 21.4355 18.7783 21.0617L17.9971 20.1008H5.99609C3.84224 20.1008 2.0958 18.3552 2.0957 16.2014V8.13889C2.09589 6.26755 3.41429 4.70428 5.17285 4.32639L4.93945 4.03928C4.63577 3.66536 4.7051 3.11573 5.09375 2.81174ZM7.13184 14.1096C7.09416 14.0738 7.03659 14.0713 6.99609 14.1037L3.92871 16.5569C4.09761 17.5472 4.95753 18.301 5.99609 18.301H16.5342L13.373 14.4133L11.9072 15.9455C11.1531 16.7324 9.92202 16.7621 9.13281 16.0119L7.13184 14.1096ZM5.99609 6.03928C4.83643 6.03928 3.89669 6.97927 3.89648 8.13889V14.1408L5.83496 12.5901C6.60469 11.9742 7.69929 12.022 8.41504 12.7024L10.416 14.6037C10.4575 14.6431 10.5218 14.642 10.5615 14.6008L12.1641 12.926L9.78906 10.0051C9.70282 10.2646 9.55682 10.5038 9.35645 10.7004C9.02202 11.0285 8.56767 11.2131 8.09473 11.2131C7.62195 11.213 7.1683 11.0284 6.83398 10.7004C6.49961 10.3724 6.31152 9.92701 6.31152 9.46311C6.3116 8.99941 6.49981 8.55474 6.83398 8.22678C7.12986 7.93654 7.51931 7.75901 7.93262 7.7219L6.56543 6.03928H5.99609Z",fill:"currentColor"},null,-1),C("path",{d:"M18.0049 4.31272C20.1587 4.31288 21.9043 6.0593 21.9043 8.21311V13.718C21.9039 15.4743 19.7248 16.2906 18.5713 14.966L14.9141 10.7658C14.5882 10.3912 14.6278 9.82271 15.002 9.49631C15.3768 9.16994 15.9451 9.20948 16.2715 9.5842L19.9287 13.7844C19.9528 13.812 19.9696 13.8167 19.9775 13.8186C19.9908 13.8216 20.0141 13.8213 20.04 13.8117C20.0655 13.8021 20.0826 13.7875 20.0908 13.7766C20.0955 13.7702 20.1044 13.7552 20.1045 13.718V8.21311C20.1045 7.05341 19.1645 6.11366 18.0049 6.1135H10.6328C10.1361 6.11327 9.73267 5.70981 9.73242 5.21311C9.73242 4.71619 10.136 4.31295 10.6328 4.31272H18.0049Z",fill:"currentColor"},null,-1)])])}const Jve=St({name:"kimi-image-failed",render:Yve}),Xve={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function e2e(e,t){return v(),E("svg",Xve,[...t[0]||(t[0]=[C("path",{d:"M12 2.1001C17.4676 2.10031 21.8994 6.53286 21.8994 12.0005C21.8992 17.4679 17.4674 21.8997 12 21.8999C6.53237 21.8999 2.09982 17.4681 2.09961 12.0005C2.09961 6.53273 6.53224 2.1001 12 2.1001ZM12 3.8999C7.52636 3.8999 3.89941 7.52684 3.89941 12.0005C3.89963 16.474 7.52649 20.1001 12 20.1001C16.4733 20.0999 20.0994 16.4738 20.0996 12.0005C20.0996 7.52697 16.4735 3.90011 12 3.8999ZM12 9.50049C12.4969 9.50068 12.8994 9.87055 12.8994 10.3267V16.6743C12.8992 17.1303 12.4968 17.5003 12 17.5005C11.503 17.5005 11.0998 17.1304 11.0996 16.6743V10.3267C11.0996 9.87043 11.5029 9.50049 12 9.50049ZM12 6.49951C12.4968 6.49951 12.8994 6.90313 12.8994 7.3999C12.8992 7.8965 12.4966 8.30029 12 8.30029C11.5025 8.30028 11.0998 7.8965 11.0996 7.3999C11.0996 6.90313 11.5024 6.49952 12 6.49951Z",fill:"currentColor"},null,-1)])])}const t2e=St({name:"kimi-info",render:e2e}),n2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function i2e(e,t){return v(),E("svg",n2e,[...t[0]||(t[0]=[$c('<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.09998C6.53222 2.09998 2.09998 6.53222 2.09998 12C2.09998 17.4677 6.53222 21.9 12 21.9C17.4677 21.9 21.9 17.4677 21.9 12C21.9 6.53222 17.4677 2.09998 12 2.09998ZM3.89998 12C3.89998 7.52633 7.52633 3.89998 12 3.89998C16.4736 3.89998 20.1 7.52633 20.1 12C20.1 16.4736 16.4736 20.1 12 20.1C7.52633 20.1 3.89998 16.4736 3.89998 12Z" fill="currentColor"></path><path d="M9.4286 9.47153C9.4286 8.97448 9.83154 8.57153 10.3286 8.57153H11.1C11.5971 8.57153 12 8.97448 12 9.47153C12 9.96859 11.5971 10.3715 11.1 10.3715H10.3286C9.83154 10.3715 9.4286 9.96859 9.4286 9.47153Z" fill="currentColor"></path><path d="M5.14289 9.47155C5.14289 8.97449 5.54583 8.57155 6.04289 8.57155H7.67146C8.16851 8.57155 8.57146 8.97449 8.57146 9.47155C8.57146 9.9686 8.16851 10.3715 7.67146 10.3715H6.04289C5.54583 10.3715 5.14289 9.9686 5.14289 9.47155Z" fill="currentColor"></path><path d="M8.57146 16.3287C8.57146 15.8316 8.9744 15.4287 9.47145 15.4287H14.5286C15.0257 15.4287 15.4286 15.8316 15.4286 16.3287C15.4286 16.8257 15.0257 17.2287 14.5286 17.2287H9.47145C8.9744 17.2287 8.57146 16.8257 8.57146 16.3287Z" fill="currentColor"></path><path d="M6.04288 12.0001C5.54583 12.0001 5.14288 12.403 5.14288 12.9001C5.14288 13.3972 5.54583 13.8001 6.04288 13.8001H6.81431C7.31137 13.8001 7.71431 13.3972 7.71431 12.9001C7.71431 12.403 7.31137 12.0001 6.81431 12.0001H6.04288Z" fill="currentColor"></path><path d="M9.47145 12.0001C8.9744 12.0001 8.57146 12.403 8.57146 12.9001C8.57146 13.3972 8.9744 13.8001 9.47146 13.8001H10.2429C10.7399 13.8001 11.1429 13.3972 11.1429 12.9001C11.1429 12.403 10.7399 12.0001 10.2429 12.0001H9.47145Z" fill="currentColor"></path><path d="M12.8572 9.47153C12.8572 8.97448 13.2601 8.57153 13.7572 8.57153H14.5286C15.0257 8.57153 15.4286 8.97448 15.4286 9.47153C15.4286 9.96859 15.0257 10.3715 14.5286 10.3715H13.7572C13.2601 10.3715 12.8572 9.96859 12.8572 9.47153Z" fill="currentColor"></path><path d="M12.9 12.0001C12.403 12.0001 12 12.403 12 12.9001C12 13.3972 12.403 13.8001 12.9 13.8001H13.6715C14.1685 13.8001 14.5715 13.3972 14.5715 12.9001C14.5715 12.403 14.1685 12.0001 13.6715 12.0001H12.9Z" fill="currentColor"></path><path d="M16.2857 9.47153C16.2857 8.97448 16.6887 8.57153 17.1857 8.57153H17.9572C18.4542 8.57153 18.8572 8.97448 18.8572 9.47153C18.8572 9.96859 18.4542 10.3715 17.9572 10.3715H17.1857C16.6887 10.3715 16.2857 9.96859 16.2857 9.47153Z" fill="currentColor"></path><path d="M16.3286 12.0001C15.8315 12.0001 15.4286 12.403 15.4286 12.9001C15.4286 13.3972 15.8315 13.8001 16.3286 13.8001H17.9572C18.4542 13.8001 18.8572 13.3972 18.8572 12.9001C18.8572 12.403 18.4542 12.0001 17.9572 12.0001H16.3286Z" fill="currentColor"></path>',10)])])}const o2e=St({name:"kimi-keyboard",render:i2e}),s2e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function r2e(e,t){return v(),E("svg",s2e,[...t[0]||(t[0]=[C("path",{id:"bar-divider",d:"M 9.3 18.951 L 9.3 4.3",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1),C("path",{id:"bar-box",d:"M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"butt","stroke-linejoin":"miter",transform:"matrix(1 0 0 1 11.8 11.8)"},null,-1),C("path",{id:"bar-arrow",d:"M -1.25 -2.5 L 1.25 0 L -1.25 2.5",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const l2e=St({name:"kimi-left-panel",render:r2e}),a2e={xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24"};function u2e(e,t){return v(),E("svg",a2e,[...t[0]||(t[0]=[C("path",{id:"bar-divider",d:"M 9.3 18.951 L 9.3 4.3",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1),C("path",{id:"bar-box",d:"M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"butt","stroke-linejoin":"miter",transform:"matrix(1 0 0 1 11.8 11.8)"},null,-1),C("path",{id:"bar-arrow-expand",d:"M -1.25 -2.5 L 1.25 0 L -1.25 2.5",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const c2e=St({name:"kimi-left-panel-expand",render:u2e}),d2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function f2e(e,t){return v(),E("svg",d2e,[...t[0]||(t[0]=[$c('<g><path d="M12.9 1.7999C12.9 1.30285 12.4971 0.899902 12 0.899902C11.5029 0.899902 11.1 1.30285 11.1 1.7999V2.7999C11.1 3.29696 11.5029 3.6999 12 3.6999C12.4971 3.6999 12.9 3.29696 12.9 2.7999V1.7999Z" fill="currentColor"></path><path fill-rule="evenodd" clip-rule="evenodd" d="M6.1 11.9999C6.1 8.7414 8.74152 6.09988 12 6.09988C15.2585 6.09988 17.9 8.7414 17.9 11.9999C17.9 15.2584 15.2585 17.8999 12 17.8999C8.74152 17.8999 6.1 15.2584 6.1 11.9999ZM12 7.89988C9.73563 7.89988 7.9 9.73551 7.9 11.9999C7.9 14.2642 9.73563 16.0999 12 16.0999C14.2644 16.0999 16.1 14.2642 16.1 11.9999C16.1 9.73551 14.2644 7.89988 12 7.89988Z" fill="currentColor"></path><path d="M0.899994 11.9999C0.899994 11.5028 1.30294 11.0999 1.79999 11.0999H2.79999C3.29705 11.0999 3.69999 11.5028 3.69999 11.9999C3.69999 12.4969 3.29705 12.8999 2.79999 12.8999H1.79999C1.30294 12.8999 0.899994 12.4969 0.899994 11.9999Z" fill="currentColor"></path><path d="M12 20.2991C12.4971 20.2991 12.9 20.702 12.9 21.1991V22.1991C12.9 22.6961 12.4971 23.0991 12 23.0991C11.5029 23.0991 11.1 22.6961 11.1 22.1991V21.1991C11.1 20.702 11.5029 20.2991 12 20.2991Z" fill="currentColor"></path><path d="M21.2016 11.0999C20.7045 11.0999 20.3016 11.5028 20.3016 11.9999C20.3016 12.4969 20.7045 12.8999 21.2016 12.8999H22.2016C22.6986 12.8999 23.1016 12.4969 23.1016 11.9999C23.1016 11.5028 22.6986 11.0999 22.2016 11.0999H21.2016Z" fill="currentColor"></path><path d="M20.1995 3.79903C20.551 4.1505 20.551 4.72035 20.1995 5.07182L19.4924 5.77893C19.141 6.1304 18.5711 6.1304 18.2196 5.77893C17.8682 5.42746 17.8682 4.85761 18.2196 4.50614L18.9268 3.79903C19.2782 3.44756 19.8481 3.44756 20.1995 3.79903Z" fill="currentColor"></path><path d="M19.4942 18.2215C19.1427 17.87 18.5729 17.87 18.2214 18.2215C17.87 18.573 17.87 19.1428 18.2214 19.4943L18.9285 20.2014C19.28 20.5529 19.8498 20.5529 20.2013 20.2014C20.5528 19.8499 20.5528 19.2801 20.2013 18.9286L19.4942 18.2215Z" fill="currentColor"></path><path d="M5.78079 18.2213C6.13227 18.5727 6.13227 19.1426 5.78079 19.4941L5.07369 20.2012C4.72222 20.5526 4.15237 20.5526 3.8009 20.2012C3.44942 19.8497 3.44942 19.2798 3.8009 18.9284L4.508 18.2213C4.85947 17.8698 5.42932 17.8698 5.78079 18.2213Z" fill="currentColor"></path><path d="M5.07077 3.79912C4.7193 3.44764 4.14945 3.44764 3.79798 3.79912C3.4465 4.15059 3.4465 4.72044 3.79798 5.07191L4.50508 5.77901C4.85655 6.13049 5.4264 6.13049 5.77787 5.77902C6.12935 5.42754 6.12935 4.85769 5.77787 4.50622L5.07077 3.79912Z" fill="currentColor"></path></g>',1)])])}const h2e=St({name:"kimi-light-mode",render:f2e}),p2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function g2e(e,t){return v(),E("svg",p2e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M3.97427 8.06961C4.99348 7.33581 6.18946 7.1 7.00001 7.1H9.00001C9.49706 7.1 9.90001 7.50294 9.90001 8C9.90001 8.49706 9.49706 8.9 9.00001 8.9H7.00001C6.47755 8.9 5.67353 9.06419 5.02599 9.53039C4.42434 9.96356 3.90001 10.6934 3.90001 12C3.90001 13.3066 4.42434 14.0364 5.02599 14.4696C5.67353 14.9358 6.47755 15.1 7.00001 15.1H9.00001C9.49706 15.1 9.90001 15.5029 9.90001 16C9.90001 16.4971 9.49706 16.9 9.00001 16.9H7.00001C6.18946 16.9 4.99348 16.6642 3.97427 15.9304C2.90917 15.1636 2.10001 13.8934 2.10001 12C2.10001 10.1066 2.90917 8.83644 3.97427 8.06961ZM14.1 8C14.1 7.50294 14.5029 7.1 15 7.1H17C17.8105 7.1 19.0065 7.33581 20.0257 8.06961C21.0908 8.83644 21.9 10.1066 21.9 12C21.9 13.8934 21.0908 15.1636 20.0257 15.9304C19.0065 16.6642 17.8105 16.9 17 16.9H15C14.5029 16.9 14.1 16.4971 14.1 16C14.1 15.5029 14.5029 15.1 15 15.1H17C17.5225 15.1 18.3265 14.9358 18.974 14.4696C19.5757 14.0364 20.1 13.3066 20.1 12C20.1 10.6934 19.5757 9.96356 18.974 9.53039C18.3265 9.06419 17.5225 8.9 17 8.9H15C14.5029 8.9 14.1 8.49706 14.1 8ZM7.10001 12C7.10001 11.5029 7.50295 11.1 8.00001 11.1H16C16.4971 11.1 16.9 11.5029 16.9 12C16.9 12.4971 16.4971 12.9 16 12.9H8.00001C7.50295 12.9 7.10001 12.4971 7.10001 12Z",fill:"currentColor"},null,-1)])])}const m2e=St({name:"kimi-link",render:g2e}),v2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function y2e(e,t){return v(),E("svg",v2e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M4.10001 5.99998C4.10001 5.50292 4.50295 5.09998 5.00001 5.09998H19C19.4971 5.09998 19.9 5.50292 19.9 5.99998C19.9 6.49703 19.4971 6.89998 19 6.89998H5.00001C4.50295 6.89998 4.10001 6.49703 4.10001 5.99998ZM4.10001 12C4.10001 11.5029 4.50295 11.1 5.00001 11.1H19C19.4971 11.1 19.9 11.5029 19.9 12C19.9 12.497 19.4971 12.9 19 12.9H5.00001C4.50295 12.9 4.10001 12.497 4.10001 12ZM4.10001 18C4.10001 17.5029 4.50295 17.1 5.00001 17.1H19C19.4971 17.1 19.9 17.5029 19.9 18C19.9 18.497 19.4971 18.9 19 18.9H5.00001C4.50295 18.9 4.10001 18.497 4.10001 18Z",fill:"currentColor"},null,-1)])])}const k2e=St({name:"kimi-list",render:y2e}),b2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function A2e(e,t){return v(),E("svg",b2e,[...t[0]||(t[0]=[C("g",null,[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18 4.09961C20.1539 4.09961 21.9004 5.84609 21.9004 8V16C21.9004 18.1539 20.1539 19.9004 18 19.9004H6C3.84609 19.9004 2.09961 18.1539 2.09961 16V8C2.09961 5.84609 3.84609 4.09961 6 4.09961H18ZM3.90039 16C3.90039 17.1598 4.8402 18.0996 6 18.0996H18C19.1598 18.0996 20.0996 17.1598 20.0996 16V9.49805L13.5361 13.5361C12.5955 14.1147 11.4075 14.1084 10.4727 13.5205L3.90039 9.38672V16ZM6 5.90039C5.0746 5.90039 4.29039 6.49909 4.01074 7.33008L11.4316 11.9971C11.7861 12.2199 12.2361 12.2222 12.5928 12.0029L20.0195 7.43457C19.7725 6.54993 18.9636 5.90039 18 5.90039H6Z",fill:"currentColor"})],-1)])])}const C2e=St({name:"kimi-mail",render:A2e}),w2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function x2e(e,t){return v(),E("svg",w2e,[...t[0]||(t[0]=[C("path",{d:"M17 11.0996C17.4971 11.0996 17.9004 11.5029 17.9004 12C17.9004 12.4971 17.4971 12.9004 17 12.9004H7C6.50294 12.9004 6.09961 12.4971 6.09961 12C6.09961 11.5029 6.50294 11.0996 7 11.0996H17Z",fill:"currentColor"},null,-1)])])}const S2e=St({name:"kimi-minus",render:x2e}),_2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function M2e(e,t){return v(),E("svg",_2e,[...t[0]||(t[0]=[C("path",{d:"M15.182 3.32802C15.9304 2.72235 17.0309 2.76978 17.724 3.46767L18.5424 4.29189L18.6722 4.43642C19.2377 5.13495 19.234 6.1404 18.6635 6.83486L18.5326 6.97841L18.0248 7.48232C17.9549 7.55172 17.8793 7.61254 17.8021 7.66884C17.9794 8.18027 17.9316 8.7498 17.6595 9.22841C17.6847 9.24522 17.7091 9.2635 17.7328 9.2831L17.8002 9.3456L17.9847 9.53798C19.8515 11.5442 20.4549 14.0022 19.6224 16.2196C19.1921 17.3657 18.4025 18.3827 17.2992 19.203H19.0873L19.1801 19.2079C19.6337 19.2542 19.9877 19.6375 19.9877 20.1034C19.9876 20.5692 19.6337 20.9527 19.1801 20.9989L19.0873 21.0028H13.0385C13.0244 21.0033 13.0104 21.0031 12.9965 21.0028H4.9115C4.41448 21.0028 4.01117 20.6004 4.01111 20.1034C4.01111 19.6064 4.41444 19.203 4.9115 19.203H12.9047C15.7614 18.5471 17.3679 17.1023 17.9369 15.5868C18.4678 14.1726 18.179 12.4782 16.807 10.9188L16.5189 10.6093L16.4574 10.5399C16.4549 10.5368 16.453 10.5333 16.4506 10.5302L12.3011 14.6522C11.6031 15.3454 10.5023 15.3845 9.75818 14.7733L9.61365 14.6425L7.31091 12.3231C6.5717 11.5786 6.57617 10.376 7.32068 9.63662L12.3676 4.62392L12.5121 4.49404C13.0358 4.06988 13.7318 3.96755 14.3402 4.18251C14.3969 4.10597 14.4591 4.03197 14.5287 3.96279L15.0365 3.45791L15.182 3.32802ZM4.83044 12.9335C5.16112 12.6052 5.68305 12.5863 6.03552 12.8759L6.10291 12.9384L9.07361 15.9286L9.13513 15.997C9.42218 16.3514 9.3992 16.8727 9.06873 17.2011C8.7381 17.5294 8.21712 17.5482 7.86462 17.2587L7.79626 17.1972L4.82654 14.2069L4.76501 14.1376C4.47792 13.7831 4.49979 13.2619 4.83044 12.9335ZM13.6693 5.87978L13.6361 5.90126L8.58826 10.914C8.54935 10.9529 8.54943 11.0165 8.58826 11.0556L10.891 13.3739L10.9242 13.3964C10.9602 13.4111 11.0032 13.404 11.0326 13.3749L16.0795 8.3622L16.1019 8.329C16.1117 8.3049 16.1117 8.2779 16.1019 8.2538L16.0804 8.2206L13.7777 5.90224C13.7486 5.87289 13.7054 5.86535 13.6693 5.87978ZM16.3383 4.71376L16.3051 4.73525L15.7972 5.24013C15.7584 5.27904 15.7585 5.34166 15.7972 5.38076L16.6146 6.20498L16.6478 6.22744C16.6838 6.24221 16.7268 6.23487 16.7562 6.20595L17.264 5.70107L17.2865 5.66787C17.2962 5.64382 17.2963 5.61672 17.2865 5.59267L17.265 5.55947L16.4467 4.73623C16.4174 4.70681 16.3744 4.6992 16.3383 4.71376Z",fill:"currentColor"},null,-1)])])}const I2e=St({name:"kimi-microscope",render:M2e}),E2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function T2e(e,t){return v(),E("svg",E2e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.669 7.94435C11.6812 7.94435 11.6912 7.9546 11.6914 7.96681C11.6914 7.96922 11.6926 7.97233 11.6934 7.97462L14.0908 15.1924C14.1283 15.3052 14.0437 15.4219 13.9248 15.4219H12.709C12.6327 15.4217 12.5655 15.3718 12.543 15.2988L11.9639 13.418C11.9526 13.3814 11.9181 13.3565 11.8799 13.3565H9.1504C9.11222 13.3565 9.07868 13.3815 9.06739 13.418L8.48829 15.2988C8.46577 15.3719 8.39778 15.4219 8.3213 15.4219H7.10548C6.98659 15.4219 6.90296 15.3052 6.94044 15.1924L9.30762 8.06446C9.3313 7.99321 9.39855 7.94435 9.47364 7.94435H11.669ZM9.4961 12.041C9.47878 12.0971 9.52043 12.1543 9.57911 12.1543H11.4512C11.5098 12.1543 11.5525 12.0971 11.5352 12.041L10.6113 9.05177H10.4199L9.4961 12.041Z",fill:"currentColor"},null,-1),C("path",{d:"M16.0576 7.94435C16.1539 7.94435 16.2324 8.02289 16.2324 8.11915V15.2481C16.2322 15.3441 16.1537 15.4219 16.0576 15.4219H15.0645C14.9683 15.4219 14.8899 15.3441 14.8897 15.2481V8.11915C14.8897 8.02289 14.9682 7.94435 15.0645 7.94435H16.0576Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12.0534 2.091C12.5082 2.091 12.8766 2.45946 12.8766 2.91425L12.874 3.90821H14.3076L14.3102 2.92499C14.3103 2.47035 14.6788 2.10186 15.1334 2.10175C15.5882 2.10175 15.9566 2.47028 15.9567 2.92499L15.9541 3.90821H17.0293C18.4439 3.90854 19.5908 5.05504 19.5908 6.46974V7.90821L21.0852 7.93105C21.54 7.93105 21.9085 8.29951 21.9085 8.7543C21.9084 9.20899 21.54 9.57754 21.0852 9.57754L19.6074 9.5547C19.6019 9.5547 19.5964 9.55383 19.5908 9.55372V11.0215L21.0852 11.0443C21.54 11.0443 21.9084 11.4129 21.9085 11.8676C21.9085 12.3224 21.54 12.6908 21.0852 12.6908L19.6074 12.668C19.6019 12.668 19.5964 12.6671 19.5908 12.667V14.1016L21.0852 14.1244C21.54 14.1244 21.9084 14.4929 21.9085 14.9477C21.9085 15.4024 21.54 15.7709 21.0852 15.7709L19.6074 15.7481C19.6019 15.7481 19.5964 15.7472 19.5908 15.7471V16.8975C19.5907 18.312 18.4438 19.4587 17.0293 19.459H15.9453L15.9875 21.0863C15.9875 21.5409 15.6189 21.9094 15.1643 21.9095C14.7095 21.9095 14.3411 21.541 14.341 21.0863L14.2988 19.459H12.8311L12.8733 21.0863C12.8732 21.541 12.5048 21.9095 12.05 21.9095C11.5955 21.9093 11.2269 21.5409 11.2268 21.0863L11.1846 19.459H9.75098L9.79319 21.0687C9.79319 21.5235 9.42474 21.8919 8.96995 21.8919C8.51536 21.8917 8.14671 21.5233 8.14671 21.0687L8.1045 19.459H6.75489C5.34008 19.459 4.19352 18.3122 4.19337 16.8975V15.7031L2.90033 15.7353C2.4456 15.7353 2.07709 15.3668 2.07709 14.9121C2.0771 14.4574 2.44561 14.0889 2.90033 14.0889L4.19337 14.0567V12.5899L2.91595 12.6221C2.46128 12.6221 2.09289 12.2535 2.09271 11.7988C2.09271 11.344 2.46116 10.9756 2.91595 10.9756L4.19337 10.9434V9.50978L2.91595 9.54198C2.46126 9.54198 2.09287 9.1734 2.09271 8.71874C2.09271 8.26395 2.46116 7.8955 2.91595 7.8955L4.19337 7.86329V6.46974C4.19337 5.05483 5.33999 3.90821 6.75489 3.90821H8.11427L8.11684 2.91425C8.11684 2.45946 8.48529 2.091 8.94008 2.091C9.39483 2.09105 9.76332 2.45949 9.76332 2.91425L9.76075 3.90821H11.2275L11.2301 2.91425C11.2301 2.45955 11.5987 2.09115 12.0534 2.091ZM6.66114 5.55958C6.19983 5.6065 5.83985 5.99605 5.83985 6.46974V16.8975L5.84473 16.9912C5.88868 17.4216 6.23075 17.7639 6.66114 17.8076L6.75489 17.8125H17.0293L17.1221 17.8076C17.5526 17.764 17.8955 17.4217 17.9395 16.9912L17.9434 16.8975V6.46974C17.9434 5.99595 17.5835 5.60637 17.1221 5.55958L17.0293 5.5547H6.75489L6.66114 5.55958Z",fill:"currentColor"},null,-1)])])}const L2e=St({name:"kimi-model",render:T2e}),N2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function F2e(e,t){return v(),E("svg",N2e,[...t[0]||(t[0]=[C("path",{d:"M6 12C6 12.8283 5.32834 13.5 4.5 13.5C3.67166 13.5 3 12.8283 3 12C3 11.1717 3.67166 10.5 4.5 10.5C5.32834 10.5 6 11.1717 6 12Z",fill:"currentColor"},null,-1),C("path",{d:"M13.5 12C13.5 12.8283 12.8283 13.5 12 13.5C11.1717 13.5 10.5 12.8283 10.5 12C10.5 11.1717 11.1717 10.5 12 10.5C12.8283 10.5 13.5 11.1717 13.5 12Z",fill:"currentColor"},null,-1),C("path",{d:"M19.5002 13.5C20.3287 13.5 21 12.8287 21 12.0002C21 11.1718 20.3287 10.5 19.5002 10.5C18.6718 10.5 18 11.1718 18 12.0002C18 12.8287 18.6718 13.5 19.5002 13.5Z",fill:"currentColor"},null,-1)])])}const D2e=St({name:"kimi-more",render:F2e}),B2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function $2e(e,t){return v(),E("svg",B2e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M8 12.0993C8.49691 12.0993 8.90016 12.5028 8.90039 12.9997V17.9997C8.90039 19.6013 7.60163 20.9001 6 20.9001C4.39837 20.9001 3.09961 19.6013 3.09961 17.9997C3.09984 16.3982 4.39852 15.0993 6 15.0993C6.38939 15.0993 6.76033 15.1778 7.09961 15.317V12.9997C7.09984 12.5028 7.50309 12.0993 8 12.0993ZM6 16.9001C5.39263 16.9001 4.90062 17.3923 4.90039 17.9997C4.90039 18.6072 5.39249 19.0993 6 19.0993C6.60751 19.0993 7.09961 18.6072 7.09961 17.9997C7.09938 17.3923 6.60737 16.9001 6 16.9001Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.627 3.35611C19.8025 3.12106 20.9001 4.02068 20.9004 5.21939V15.9997C20.9004 17.6013 19.6016 18.9001 18 18.9001C16.3984 18.9001 15.0996 17.6013 15.0996 15.9997C15.0998 14.3982 16.3985 13.0993 18 13.0993C18.3894 13.0993 18.7603 13.1778 19.0996 13.317V9.21939C19.0993 9.15657 19.0421 9.10946 18.9805 9.12173L12.6768 10.3825C12.1894 10.4799 11.7148 10.1637 11.6172 9.67642C11.52 9.18922 11.8361 8.71439 12.3232 8.61685L18.627 7.35611C18.7868 7.32415 18.9452 7.31502 19.0996 7.32291V5.21939C19.0993 5.15657 19.0421 5.10946 18.9805 5.12173L12.6768 6.38248C12.1894 6.47994 11.7148 6.16372 11.6172 5.67642C11.52 5.18922 11.8361 4.71439 12.3232 4.61685L18.627 3.35611ZM18 14.9001C17.3926 14.9001 16.9006 15.3923 16.9004 15.9997C16.9004 16.6072 17.3925 17.0993 18 17.0993C18.6075 17.0993 19.0996 16.6072 19.0996 15.9997C19.0994 15.3923 18.6074 14.9001 18 14.9001Z",fill:"currentColor"},null,-1),C("path",{d:"M7.32422 5.38931C7.61669 4.87032 8.38346 4.87015 8.67578 5.38931L8.73047 5.50845L8.89551 5.95376L8.97949 6.1481C9.19937 6.58817 9.57968 6.93145 10.0459 7.10415L10.4912 7.26919C11.127 7.50461 11.1666 8.36217 10.6104 8.67544L10.4912 8.73013L10.0459 8.89517C9.5799 9.06783 9.19939 9.41141 8.97949 9.85123L8.89551 10.0456L8.73047 10.4909C8.49495 11.1267 7.63737 11.1665 7.32422 10.61L7.26953 10.4909L7.10449 10.0456C6.93172 9.57931 6.58767 9.19898 6.14746 8.97916L5.9541 8.89517L5.50879 8.73013C4.83054 8.47903 4.83061 7.52037 5.50879 7.26919L5.9541 7.10415L6.14746 7.02017C6.58757 6.80032 6.93176 6.41995 7.10449 5.95376L7.26953 5.50845L7.32422 5.38931Z",fill:"currentColor"},null,-1)])])}const R2e=St({name:"kimi-music",render:$2e}),z2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function O2e(e,t){return v(),E("svg",z2e,[...t[0]||(t[0]=[C("path",{d:"M17.9551 6.32648C17.955 5.82951 17.5517 5.42706 17.0547 5.42706H15.4844C14.9875 5.42717 14.5851 5.82958 14.585 6.32648V17.6732C14.585 18.1701 14.9874 18.5734 15.4844 18.5735H17.0547C17.5518 18.5735 17.9551 18.1702 17.9551 17.6732V6.32648ZM19.7549 17.6732C19.7549 19.1643 18.5459 20.3734 17.0547 20.3734H15.4844C13.9933 20.3732 12.7842 19.1643 12.7842 17.6732V6.32648C12.7843 4.83546 13.9934 3.62639 15.4844 3.62628H17.0547C18.5458 3.62628 19.7548 4.8354 19.7549 6.32648V17.6732Z",fill:"currentColor"},null,-1),C("path",{d:"M9.41571 6.32648C9.41561 5.82951 9.01231 5.42706 8.51532 5.42706H6.94501C6.44811 5.42717 6.0457 5.82958 6.04559 6.32648V17.6732C6.04559 18.1701 6.44804 18.5734 6.94501 18.5735H8.51532C9.01238 18.5735 9.41571 18.1702 9.41571 17.6732V6.32648ZM11.2155 17.6732C11.2155 19.1643 10.0065 20.3734 8.51532 20.3734H6.94501C5.45393 20.3732 4.24481 19.1643 4.24481 17.6732V6.32648C4.24492 4.83546 5.45399 3.62639 6.94501 3.62628H8.51532C10.0064 3.62628 11.2154 4.8354 11.2155 6.32648V17.6732Z",fill:"currentColor"},null,-1)])])}const P2e=St({name:"kimi-pause",render:O2e}),j2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function H2e(e,t){return v(),E("svg",j2e,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.0176 4.89998C17.7305 4.89998 17.4552 5.014 17.2522 5.217L6.35429 16.1149C5.957 16.5122 5.67517 17.01 5.53889 17.5551L5.23691 18.763L6.44486 18.4611C6.98994 18.3248 7.48773 18.0429 7.88502 17.6456L18.783 6.74773C18.8834 6.64728 18.9631 6.52797 19.0176 6.39658C19.072 6.26517 19.1 6.12441 19.1 5.98236C19.1 5.84031 19.072 5.69956 19.0176 5.56815C18.9631 5.43676 18.8834 5.31745 18.783 5.217C18.6825 5.11649 18.5631 5.03676 18.4318 4.98237C18.3005 4.92798 18.1597 4.89998 18.0176 4.89998ZM15.9794 3.94421C16.52 3.40366 17.2531 3.09998 18.0176 3.09998C18.3961 3.09998 18.7709 3.17452 19.1207 3.31938C19.4704 3.46424 19.7881 3.67656 20.0558 3.94421C20.3235 4.21192 20.5357 4.52969 20.6805 4.87932C20.8254 5.22895 20.9 5.60375 20.9 5.98236C20.9 6.36098 20.8254 6.73578 20.6805 7.08541C20.5357 7.43504 20.3235 7.75281 20.0558 8.02052L17.6385 10.4378L9.15781 18.9184C8.52984 19.5464 7.74301 19.9919 6.88142 20.2073L4.21828 20.8731C3.91158 20.9498 3.58714 20.8599 3.3636 20.6364C3.14006 20.4128 3.05019 20.0884 3.12686 19.7817L3.79264 17.1185C4.00803 16.257 4.45351 15.4701 5.0815 14.8421L15.9794 3.94421Z",fill:"currentColor"},null,-1)])])}const W2e=St({name:"kimi-pencil",render:H2e}),q2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function U2e(e,t){return v(),E("svg",q2e,[...t[0]||(t[0]=[C("path",{d:"M7.76251 3.10547C8.25776 3.10552 8.74422 3.23849 9.17072 3.49023L19.533 9.60742C20.8536 10.3869 21.2922 12.0901 20.5174 13.4121C20.2785 13.8195 19.9398 14.1604 19.533 14.4004L9.16974 20.5156C7.84721 21.2958 6.14595 20.8511 5.36993 19.5273C5.1196 19.1003 4.98719 18.6142 4.98712 18.1191V5.88672C4.98716 4.3537 6.2273 3.10547 7.76251 3.10547ZM6.7879 18.1191C6.78797 18.2945 6.8343 18.4664 6.92267 18.6172C7.19638 19.0841 7.79336 19.2377 8.25568 18.9648L18.618 12.8496C18.7607 12.7654 18.8803 12.6458 18.9647 12.502C19.2393 12.0334 19.082 11.4311 18.618 11.1572L8.25568 5.04102C8.1061 4.95273 7.93562 4.9063 7.76251 4.90625C7.22703 4.90625 6.78794 5.34218 6.7879 5.88672V18.1191Z",fill:"currentColor"},null,-1)])])}const K2e=St({name:"kimi-play",render:U2e}),V2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Z2e(e,t){return v(),E("svg",V2e,[...t[0]||(t[0]=[C("path",{d:"M18.36 6.64a9 9 0 1 1-12.73 0",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,-1),C("path",{d:"M12 2v10",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])}const G2e=St({name:"kimi-power",render:Z2e}),Q2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Y2e(e,t){return v(),E("svg",Q2e,[...t[0]||(t[0]=[C("path",{d:"M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z",fill:"currentColor"},null,-1),C("path",{d:"M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 3.7998C7.47126 3.7998 3.7998 7.47126 3.7998 12C3.7998 16.5287 7.47126 20.2002 12 20.2002C16.5287 20.2002 20.2002 16.5287 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998Z",fill:"currentColor"},null,-1)])])}const J2e=St({name:"kimi-question",render:Y2e}),X2e={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function eye(e,t){return v(),E("svg",X2e,[...t[0]||(t[0]=[C("path",{d:"M12 2C13.1046 2 14 2.89543 14 4C14 4.78019 13.552 5.45353 12.9004 5.7832V7H16.5C18.1569 7 19.5 8.34315 19.5 10V17C19.5 18.6051 18.2394 19.9158 16.6543 19.9961L16.5 20H7.5L7.3457 19.9961C5.81166 19.9184 4.58163 18.6883 4.50391 17.1543L4.5 17V10C4.5 8.34315 5.84315 7 7.5 7H11.0996V5.7832C10.448 5.45353 10 4.78019 10 4C10 2.89543 10.8954 2 12 2ZM7.5 8.7998C6.83726 8.7998 6.2998 9.33726 6.2998 10V17C6.2998 17.6627 6.83726 18.2002 7.5 18.2002H16.5C17.1627 18.2002 17.7002 17.6627 17.7002 17V10C17.7002 9.33726 17.1627 8.7998 16.5 8.7998H7.5ZM3 10.7666C3.49706 10.7666 3.90039 11.1699 3.90039 11.667V15C3.90039 15.4971 3.49706 15.9004 3 15.9004C2.50294 15.9004 2.09961 15.4971 2.09961 15V11.667C2.09961 11.1699 2.50294 10.7666 3 10.7666ZM21 10.7666C21.4971 10.7666 21.9004 11.1699 21.9004 11.667V15C21.9004 15.4971 21.4971 15.9004 21 15.9004C20.5029 15.9004 20.0996 15.4971 20.0996 15V11.667C20.0996 11.1699 20.5029 10.7666 21 10.7666ZM9.5 11.0996C9.99706 11.0996 10.4004 11.5029 10.4004 12V14.5C10.4004 14.9971 9.99706 15.4004 9.5 15.4004C9.00294 15.4004 8.59961 14.9971 8.59961 14.5V12C8.59961 11.5029 9.00294 11.0996 9.5 11.0996ZM14.5 11.0996C14.9971 11.0996 15.4004 11.5029 15.4004 12V14.5C15.4004 14.9971 14.9971 15.4004 14.5 15.4004C14.0029 15.4004 13.5996 14.9971 13.5996 14.5V12C13.5996 11.5029 14.0029 11.0996 14.5 11.0996ZM12 3.5C11.7239 3.5 11.5 3.72386 11.5 4C11.5 4.27614 11.7239 4.5 12 4.5C12.2761 4.5 12.5 4.27614 12.5 4C12.5 3.72386 12.2761 3.5 12 3.5Z",fill:"currentColor"},null,-1)])])}const tye=St({name:"kimi-robot",render:eye}),nye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function iye(e,t){return v(),E("svg",nye,[...t[0]||(t[0]=[C("path",{d:"M11.5 3C16.1944 3 20 6.80558 20 11.5C20 13.523 19.2933 15.381 18.1132 16.8404L21.1364 19.8636C21.4879 20.2151 21.4879 20.7849 21.1364 21.1364C20.7849 21.4879 20.2151 21.4879 19.8636 21.1364L16.8404 18.1132C15.381 19.2933 13.523 20 11.5 20C6.80558 20 3 16.1944 3 11.5C3 6.80558 6.80558 3 11.5 3ZM11.5 18.2C15.2003 18.2 18.2 15.2003 18.2 11.5C18.2 7.79969 15.2003 4.8 11.5 4.8C7.79969 4.8 4.8 7.79969 4.8 11.5C4.8 15.2003 7.79969 18.2 11.5 18.2Z",fill:"currentColor"},null,-1)])])}const oye=St({name:"kimi-search",render:iye}),sye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function rye(e,t){return v(),E("svg",sye,[...t[0]||(t[0]=[C("path",{d:"M16.5364 10.1636C16.8879 10.5151 16.8879 11.0849 16.5364 11.4364C16.1849 11.7879 15.6151 11.7879 15.2636 11.4364L12.9 9.07281V17.1C12.9 17.597 12.4971 18 12 18C11.503 18 11.1 17.597 11.1 17.1V9.07281L8.73641 11.4364C8.38494 11.7879 7.81509 11.7879 7.46362 11.4364C7.11214 11.0849 7.11214 10.5151 7.46362 10.1636L11.3636 6.2636C11.7151 5.91211 12.2849 5.91211 12.6364 6.2636L16.5364 10.1636Z",fill:"currentColor"},null,-1)])])}const lye=St({name:"kimi-send",render:rye}),aye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function uye(e,t){return v(),E("svg",aye,[...t[0]||(t[0]=[C("path",{d:"M16.0404 12C16.0404 9.76874 14.2313 7.9596 12.0001 7.9596C9.76883 7.9596 7.95972 9.76874 7.95972 12C7.95972 14.2313 9.76883 16.0404 12.0001 16.0404C14.2313 16.0404 16.0404 14.2313 16.0404 12ZM14.2222 12C14.2222 13.2271 13.2271 14.2222 12 14.2222C10.7729 14.2222 9.77783 13.2271 9.77783 12C9.77783 10.7729 10.7729 9.77778 12 9.77778C13.2271 9.77778 14.2222 10.7729 14.2222 12Z",fill:"currentColor"},null,-1),C("path",{d:"M9.91145 21.8009C9.29001 21.6797 8.76914 21.2612 8.50632 20.6922L8.07372 19.7556C7.88838 19.3544 7.43553 19.1048 6.95371 19.1549L5.89572 19.2647C5.2733 19.3293 4.64823 19.114 4.22298 18.6611C3.74343 18.1504 3.32454 17.6037 2.97033 17.0181C2.61571 16.4318 2.32839 15.8106 2.10407 15.1566C1.89769 14.5549 2.02148 13.8954 2.4089 13.3902L3.0376 12.5704C3.30043 12.2277 3.30042 11.7722 3.03758 11.4295L2.40413 10.6035C2.01474 10.0958 1.891 9.43198 2.10208 8.82826C2.55037 7.54612 3.27017 6.35997 4.22 5.34259C4.64518 4.8872 5.27275 4.67067 5.89701 4.73544L6.95383 4.84514C7.43561 4.89515 7.88844 4.6456 8.07377 4.24441L8.50266 3.31593C8.76494 2.74818 9.28448 2.33019 9.90423 2.20761C11.2916 1.9332 12.7148 1.93127 14.0885 2.19913C14.7099 2.32029 15.2308 2.73881 15.4937 3.3078L15.9263 4.24441C16.1116 4.6456 16.5644 4.89514 17.0462 4.84514L18.1043 4.73532C18.7267 4.67072 19.3518 4.88603 19.777 5.33886C20.2566 5.84953 20.6755 6.3963 21.0297 6.98193C21.3843 7.56823 21.6716 8.18942 21.8959 8.84339C22.1023 9.44509 21.9785 10.1046 21.5911 10.6098L20.9624 11.4295C20.6996 11.7722 20.6996 12.2278 20.9624 12.5705L21.5959 13.3964C21.9853 13.9042 22.109 14.568 21.8979 15.1717C21.4497 16.4538 20.7299 17.6399 19.7801 18.6573C19.3549 19.1128 18.7273 19.3294 18.103 19.2646L17.0462 19.1549C16.5645 19.1049 16.1116 19.3544 15.9263 19.7556L15.4974 20.6841C15.2351 21.2518 14.7156 21.6698 14.0958 21.7924C12.7083 22.0668 11.2852 22.0687 9.91145 21.8009ZM13.7432 20.0088C13.7844 20.0006 13.8259 19.9673 13.847 19.9216L14.2758 18.9931C14.7915 17.8768 15.9886 17.2171 17.2341 17.3464L18.2909 17.4561C18.3649 17.4638 18.4272 17.4423 18.4512 17.4166C19.2296 16.5828 19.8171 15.6146 20.1817 14.5716C20.1845 14.5636 20.1796 14.5373 20.1532 14.5029L19.5198 13.677C18.7564 12.6815 18.7564 11.3185 19.5198 10.323L20.1485 9.5033C20.1746 9.46927 20.1795 9.4429 20.1762 9.43327C19.9932 8.89965 19.7603 8.39623 19.4741 7.92293C19.1873 7.4489 18.846 7.00333 18.4517 6.58351C18.4272 6.55739 18.3656 6.53616 18.2921 6.54378L17.234 6.65361C15.9886 6.78287 14.7915 6.12317 14.2758 5.00689L13.8432 4.07027C13.822 4.02448 13.7811 3.9916 13.7406 3.98371C12.5983 3.76097 11.4132 3.76258 10.2571 3.99124C10.2158 3.99941 10.1744 4.03271 10.1533 4.07842L9.72441 5.00689C9.20875 6.12317 8.01164 6.7829 6.76619 6.6536L5.70942 6.54391C5.63535 6.53623 5.573 6.55774 5.54905 6.5834C4.77067 7.41713 4.18312 8.38534 3.81845 9.42835C3.81564 9.43637 3.82054 9.46265 3.84693 9.49706L4.48038 10.323C5.24381 11.3185 5.24383 12.6815 4.48041 13.6769L3.85171 14.4967C3.82561 14.5307 3.82066 14.5571 3.82396 14.5667C4.00701 15.1004 4.23986 15.6038 4.52613 16.0771C4.81284 16.5511 5.15421 16.9967 5.54845 17.4165C5.57298 17.4426 5.63461 17.4638 5.70811 17.4562L6.76608 17.3464C8.01157 17.2171 9.20871 17.8768 9.72438 18.9932L10.157 19.9297C10.1781 19.9755 10.2191 20.0084 10.2595 20.0163C11.4018 20.239 12.587 20.2374 13.7432 20.0088Z",fill:"currentColor"},null,-1)])])}const cye=St({name:"kimi-setting",render:uye}),dye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function fye(e,t){return v(),E("svg",dye,[...t[0]||(t[0]=[C("path",{d:"M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7Z",fill:"currentColor"},null,-1),C("path",{d:"M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z",fill:"currentColor"},null,-1),C("path",{d:"M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z",fill:"currentColor"},null,-1)])])}const hye=St({name:"kimi-shield-question",render:fye}),pye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function gye(e,t){return v(),E("svg",pye,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.90005 12C2.90005 11.503 3.303 11.1 3.80005 11.1H12.2939L9.38588 8.19197C9.03441 7.8405 9.03441 7.27065 9.38588 6.91918C9.73735 6.56771 10.3072 6.56771 10.6587 6.91918L15.1031 11.3636C15.2719 11.5324 15.3667 11.7613 15.3667 12C15.3667 12.2387 15.2719 12.4676 15.1031 12.6364L10.6587 17.0809C10.3072 17.4323 9.73735 17.4323 9.38588 17.0809C9.03441 16.7294 9.03441 16.1595 9.38588 15.8081L12.2939 12.9H3.80005C3.303 12.9 2.90005 12.4971 2.90005 12ZM13.5874 20C13.5874 19.503 13.9904 19.1 14.4874 19.1H18.043C18.2758 19.1 18.4991 19.0075 18.6637 18.8429C18.8283 18.6783 18.9208 18.455 18.9208 18.2222V5.7778C18.9208 5.545 18.8283 5.32174 18.6637 5.15712C18.499 4.9925 18.2758 4.90002 18.043 4.90002H14.4874C13.9904 4.90002 13.5874 4.49708 13.5874 4.00002C13.5874 3.50297 13.9904 3.10003 14.4874 3.10003H18.043C18.7532 3.10003 19.4343 3.38215 19.9365 3.88433C20.4386 4.38651 20.7208 5.06761 20.7208 5.7778V18.2222C20.7208 18.9324 20.4386 19.6135 19.9365 20.1157C19.4343 20.6179 18.7532 20.9 18.043 20.9H14.4874C13.9904 20.9 13.5874 20.4971 13.5874 20Z",fill:"currentColor"},null,-1)])])}const mye=St({name:"kimi-sign-in",render:gye}),vye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function yye(e,t){return v(),E("svg",vye,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M20.6364 11.3636C20.9879 11.7151 20.9879 12.2849 20.6364 12.6364L16.1919 17.0808C15.8405 17.4323 15.2706 17.4323 14.9192 17.0808C14.5677 16.7293 14.5677 16.1595 14.9192 15.808L17.8272 12.9H9.33333C8.83627 12.9 8.43333 12.497 8.43333 12C8.43333 11.5029 8.83627 11.1 9.33333 11.1H17.8272L14.9192 8.19193C14.5677 7.84046 14.5677 7.27061 14.9192 6.91914C15.2706 6.56766 15.8405 6.56766 16.1919 6.91914L20.6364 11.3636ZM10.2333 3.99998C10.2333 4.49703 9.83038 4.89998 9.33333 4.89998H5.77777C5.54497 4.89998 5.3217 4.99246 5.15709 5.15707C4.99247 5.32169 4.89999 5.54495 4.89999 5.77775V18.2222C4.89999 18.455 4.99247 18.6783 5.15709 18.8429C5.32171 19.0075 5.54497 19.1 5.77777 19.1H9.33333C9.83038 19.1 10.2333 19.5029 10.2333 20C10.2333 20.497 9.83038 20.9 9.33333 20.9H5.77777C5.06758 20.9 4.38648 20.6179 3.8843 20.1157C3.38212 19.6135 3.09999 18.9324 3.09999 18.2222V5.77775C3.09999 5.06756 3.38212 4.38646 3.8843 3.88428C4.38648 3.3821 5.06758 3.09998 5.77777 3.09998H9.33333C9.83038 3.09998 10.2333 3.50292 10.2333 3.99998Z",fill:"currentColor"},null,-1)])])}const kye=St({name:"kimi-sign-out",render:yye}),bye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Aye(e,t){return v(),E("svg",bye,[...t[0]||(t[0]=[$c('<path d="M4 6H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M18.0 6H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="16" cy="6" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M4 12H6.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M10.5 12H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="8.5" cy="12" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle><path d="M4 18H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><path d="M18.0 18H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"></path><circle cx="16" cy="18" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"></circle>',9)])])}const Cye=St({name:"kimi-sliders",render:Aye}),wye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function xye(e,t){return v(),E("svg",wye,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M7.78027 8.90405C7.5 9.45411 7.5 10.1742 7.5 11.6144V12.3856C7.5 13.8258 7.5 14.5459 7.78027 15.096C8.02681 15.5798 8.42019 15.9732 8.90405 16.2197C9.45411 16.5 10.1742 16.5 11.6144 16.5H12.3856C13.8258 16.5 14.5459 16.5 15.096 16.2197C15.5798 15.9732 15.9732 15.5798 16.2197 15.096C16.5 14.5459 16.5 13.8258 16.5 12.3856V11.6144C16.5 10.1742 16.5 9.45411 16.2197 8.90405C15.9732 8.42019 15.5798 8.02681 15.096 7.78027C14.5459 7.5 13.8258 7.5 12.3856 7.5H11.6144C10.1742 7.5 9.45411 7.5 8.90405 7.78027C8.42019 8.02681 8.02681 8.42019 7.78027 8.90405Z",fill:"currentColor"},null,-1)])])}const Sye=St({name:"kimi-stop",render:xye}),_ye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Mye(e,t){return v(),E("svg",_ye,[...t[0]||(t[0]=[C("path",{d:"M7.01562 3.41459C7.4446 3.16449 7.9954 3.30924 8.24609 3.73784C8.49645 4.167 8.35189 4.71868 7.92285 4.96928C5.51497 6.37506 3.90054 8.98498 3.90039 11.9703C3.90076 16.4435 7.52672 20.0699 12 20.0699C16.4733 20.0699 20.0992 16.4435 20.0996 11.9703C20.0996 11.2291 20 10.5116 19.8145 9.83159C19.6838 9.35222 19.967 8.85702 20.4463 8.72612C20.9256 8.59541 21.4207 8.87778 21.5518 9.35698C21.7792 10.1901 21.9004 11.0674 21.9004 11.9703C21.9 17.4376 17.4674 21.8697 12 21.8697C6.53261 21.8697 2.09998 17.4376 2.09961 11.9703C2.09976 8.31904 4.07782 5.12972 7.01562 3.41459ZM8.39258 8.24077C8.75015 7.89591 9.3199 7.90591 9.66504 8.26323C10.01 8.62076 9.99985 9.19051 9.64258 9.53569C9.00203 10.1541 8.60558 11.02 8.60547 11.979C8.60584 13.8536 10.1253 15.3736 12 15.3736C13.8746 15.3735 15.3942 13.8536 15.3945 11.979C15.3945 11.6847 15.3577 11.3989 15.2881 11.1285C15.1646 10.6474 15.4536 10.1568 15.9346 10.0328C16.4158 9.9089 16.9071 10.1991 17.0312 10.6802C17.1383 11.096 17.1943 11.5321 17.1943 11.979C17.194 14.8477 14.8688 17.1733 12 17.1734C9.1312 17.1734 6.80506 14.8478 6.80469 11.979C6.8048 10.5117 7.41519 9.18431 8.39258 8.24077ZM11.5459 1.12651C11.8216 0.965605 12.1631 0.963306 12.4414 1.11967L19.1953 4.91752C19.4859 5.08108 19.662 5.39277 19.6533 5.72612C19.6443 6.05972 19.4515 6.36154 19.1523 6.50932L12.9004 9.5933V12.2583C12.9004 12.7554 12.4971 13.1587 12 13.1587C11.5029 13.1587 11.0996 12.7554 11.0996 12.2583V1.90385C11.0999 1.58444 11.2702 1.2878 11.5459 1.12651ZM12.9004 7.58549L16.8252 5.64897L12.9004 3.44194V7.58549Z",fill:"currentColor"},null,-1)])])}const Iye=St({name:"kimi-target",render:Mye}),Eye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Tye(e,t){return v(),E("svg",Eye,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M18.9893 6.60743C20.5897 6.60757 21.8877 7.8926 21.8877 9.47736C21.8877 10.7416 21.0607 11.8129 19.9141 12.1955V14.257C19.914 15.8428 18.6152 17.1288 17.0137 17.1289H12.8438V20.1381C12.8437 20.6301 12.4412 21.0293 11.9443 21.0296C11.4473 21.0296 11.044 20.6302 11.0439 20.1381V16.4356C11.0441 15.8343 11.5363 15.3461 12.1436 15.3458H17.0137C17.6211 15.3457 18.1133 14.8585 18.1133 14.257V12.2129C16.9408 11.8451 16.0909 10.7598 16.0908 9.47736C16.0908 7.89251 17.3887 6.60743 18.9893 6.60743ZM18.9893 8.38953C18.3828 8.38953 17.8906 8.87684 17.8906 9.47736C17.8907 10.0778 18.3828 10.5642 18.9893 10.5642C19.5956 10.5641 20.0869 10.0777 20.0869 9.47736C20.0869 8.87693 19.5956 8.38967 18.9893 8.38953Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M4.89844 6.60743C6.49899 6.60747 7.79688 7.89254 7.79688 9.47736C7.79684 10.7388 6.97371 11.8078 5.83105 12.1926V14.4021C5.83105 15.0036 6.32315 15.4918 6.93066 15.4918H8.37109C8.86789 15.492 9.27038 15.8905 9.27051 16.3824C9.27051 16.8744 8.86797 17.2737 8.37109 17.2739H6.93066C5.32904 17.2739 4.03027 15.9879 4.03027 14.4021V12.2158C2.85382 11.8504 2.00004 10.7627 2 9.47736C2 7.89251 3.29784 6.60743 4.89844 6.60743ZM4.89844 8.38953C4.29196 8.38953 3.7998 8.87684 3.7998 9.47736C3.79985 10.0778 4.29198 10.5642 4.89844 10.5642C5.50485 10.5642 5.99605 10.0778 5.99609 9.47736C5.99609 8.87687 5.50488 8.38958 4.89844 8.38953Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M11.9434 2.9707C13.5439 2.97075 14.8418 4.25581 14.8418 5.84063C14.8418 7.11413 14.0035 8.1923 12.8438 8.56745V13.0135C12.8436 13.5056 12.4403 13.9041 11.9434 13.9041C11.4466 13.9039 11.0431 13.5055 11.043 13.0135V8.56745C9.8836 8.19209 9.04496 7.11387 9.04492 5.84063C9.04492 4.25592 10.343 2.97093 11.9434 2.9707ZM11.9434 4.75281C11.3371 4.75303 10.8447 5.24026 10.8447 5.84063C10.8448 6.44097 11.3371 6.92726 11.9434 6.92749C12.5498 6.92745 13.041 6.44108 13.041 5.84063C13.041 5.24014 12.5498 4.75285 11.9434 4.75281Z",fill:"currentColor"},null,-1)])])}const Lye=St({name:"kimi-task",render:Tye}),Nye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Fye(e,t){return v(),E("svg",Nye,[...t[0]||(t[0]=[C("path",{d:"M16.5293 15.0596C16.9496 15.1021 17.2772 15.4572 17.2773 15.8887C17.2773 16.3202 16.9497 16.6753 16.5293 16.7178L16.4443 16.7217H12C11.5399 16.7216 11.167 16.3488 11.167 15.8887C11.1671 15.4286 11.54 15.0558 12 15.0557H16.4443L16.5293 15.0596Z",fill:"currentColor"},null,-1),C("path",{d:"M6.96582 7.52246C7.27077 7.21751 7.75375 7.1983 8.08105 7.46484L8.14453 7.52246L10.8232 10.2002C11.5102 10.8872 11.5102 12.0014 10.8232 12.6885L8.14453 15.3672L8.08105 15.4248C7.75377 15.6913 7.27075 15.6721 6.96582 15.3672C6.66114 15.0621 6.64234 14.5791 6.90918 14.252L6.96582 14.1885L9.64453 11.5098C9.68057 11.4736 9.68062 11.415 9.64453 11.3789L6.96582 8.7002C6.64116 8.37488 6.6411 7.84774 6.96582 7.52246Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M17 3.09961C19.1539 3.09966 20.9004 4.84612 20.9004 7V17C20.9004 19.1539 19.1539 20.9003 17 20.9004H7C4.84609 20.9004 3.09961 19.1539 3.09961 17V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H17ZM7 4.90039C5.8402 4.90039 4.90039 5.8402 4.90039 7V17C4.90039 18.1598 5.8402 19.0996 7 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V7C19.0996 5.84024 18.1598 4.90044 17 4.90039H7Z",fill:"currentColor"},null,-1)])])}const Dye=St({name:"kimi-terminal",render:Fye}),Bye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function $ye(e,t){return v(),E("svg",Bye,[...t[0]||(t[0]=[C("path",{d:"M16.9971 3.90597C15.9799 2.99725 14.7342 2.38312 13.394 2.12966C12.0538 1.8762 10.6699 1.99301 9.39111 2.46751C8.11236 2.94202 6.98721 3.75626 6.13676 4.82261C5.2863 5.88896 4.74274 7.16703 4.56457 8.5193C4.40455 9.70501 4.53253 10.9118 4.93767 12.0376C5.34281 13.1634 6.01318 14.175 6.89207 14.9868C7.43557 15.4634 7.87413 16.0477 8.17997 16.7027C8.48581 17.3577 8.65224 18.0691 8.66873 18.7918V18.926C8.66962 19.7412 8.99387 20.5229 9.57035 21.0993C10.1468 21.6758 10.9285 22.0001 11.7437 22.001H12.2604C13.0757 22.0001 13.8573 21.6758 14.4338 21.0993C15.0103 20.5229 15.3345 19.7412 15.3354 18.926V18.4685C15.3479 17.8297 15.4982 17.2011 15.7761 16.6258C16.0539 16.0505 16.4528 15.542 16.9454 15.1351C17.7442 14.4355 18.3853 13.5741 18.826 12.608C19.2668 11.642 19.4973 10.5932 19.5022 9.53136C19.5071 8.46948 19.2863 7.41869 18.8544 6.4486C18.4225 5.4785 17.7894 4.61125 16.9971 3.9043V3.90597ZM12.2604 20.3343H11.7437C11.3704 20.3339 11.0124 20.1853 10.7484 19.9213C10.4844 19.6573 10.3358 19.2993 10.3354 18.926C10.3354 18.926 10.3296 18.7093 10.3287 18.6676H13.6687V18.926C13.6683 19.2993 13.5198 19.6573 13.2558 19.9213C12.9917 20.1853 12.6338 20.3339 12.2604 20.3343ZM15.8437 13.8835C14.8949 14.7064 14.2097 15.7908 13.8737 17.001H12.8354V11.0143C13.3212 10.8426 13.742 10.5249 14.0403 10.1049C14.3387 9.68482 14.4999 9.18285 14.5021 8.66763C14.5021 8.44662 14.4143 8.23466 14.258 8.07838C14.1017 7.9221 13.8897 7.8343 13.6687 7.8343C13.4477 7.8343 13.2358 7.9221 13.0795 8.07838C12.9232 8.23466 12.8354 8.44662 12.8354 8.66763C12.8354 8.88865 12.7476 9.10061 12.5913 9.25689C12.435 9.41317 12.2231 9.50097 12.0021 9.50097C11.7811 9.50097 11.5691 9.41317 11.4128 9.25689C11.2565 9.10061 11.1687 8.88865 11.1687 8.66763C11.1687 8.44662 11.0809 8.23466 10.9247 8.07838C10.7684 7.9221 10.5564 7.8343 10.3354 7.8343C10.1144 7.8343 9.90242 7.9221 9.74614 8.07838C9.58986 8.23466 9.50207 8.44662 9.50207 8.66763C9.5042 9.18285 9.66547 9.68482 9.96381 10.1049C10.2621 10.5249 10.683 10.8426 11.1687 11.0143V17.001H10.0671C9.69123 15.7586 8.98633 14.6411 8.02707 13.7668C7.21286 13.0081 6.63267 12.0324 6.35496 10.9547C6.07725 9.87703 6.1136 8.7424 6.45974 7.68471C6.80588 6.62702 7.44735 5.69042 8.30846 4.98543C9.16956 4.28045 10.2144 3.83649 11.3196 3.70597C11.5487 3.68039 11.779 3.66759 12.0096 3.66763C13.4409 3.66338 14.8226 4.19149 15.8862 5.1493C16.5026 5.69896 16.9952 6.37337 17.3312 7.12782C17.6672 7.88227 17.839 8.69952 17.8352 9.5254C17.8314 10.3513 17.6522 11.1669 17.3092 11.9183C16.9663 12.6696 16.4677 13.3395 15.8462 13.8835H15.8437Z",fill:"currentColor"},null,-1)])])}const Rye=St({name:"kimi-thinking",render:$ye}),zye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Oye(e,t){return v(),E("svg",zye,[...t[0]||(t[0]=[$c('<path d="M9.28994 4.92561C9.6436 4.57634 9.64716 4.0065 9.29789 3.65284C8.94862 3.29918 8.37878 3.29563 8.02512 3.6449L5.91339 5.73041L5.16642 4.95888C4.82067 4.60177 4.2509 4.59256 3.89379 4.9383C3.53668 5.28404 3.52747 5.85382 3.87321 6.21093L5.25245 7.63551C5.41956 7.80811 5.64874 7.90674 5.88897 7.90943C6.1292 7.91213 6.36053 7.81866 6.53146 7.64985L9.28994 4.92561Z" fill="currentColor"></path><path d="M12 5.10022C11.503 5.10022 11.1 5.50316 11.1 6.00022C11.1 6.49728 11.503 6.90022 12 6.90022L19.9965 6.90022C20.4935 6.90022 20.8965 6.49728 20.8965 6.00022C20.8965 5.50316 20.4935 5.10022 19.9965 5.10022L12 5.10022Z" fill="currentColor"></path><path d="M12 11.1002C11.503 11.1002 11.1 11.5032 11.1 12.0002C11.1 12.4973 11.503 12.9002 12 12.9002H19.9965C20.4935 12.9002 20.8965 12.4973 20.8965 12.0002C20.8965 11.5032 20.4935 11.1002 19.9965 11.1002L12 11.1002Z" fill="currentColor"></path><path d="M11.1 18.0002C11.1 17.5032 11.503 17.1002 12 17.1002L19.9965 17.1002C20.4935 17.1002 20.8965 17.5032 20.8965 18.0002C20.8965 18.4973 20.4935 18.9002 19.9965 18.9002H12C11.503 18.9002 11.1 18.4973 11.1 18.0002Z" fill="currentColor"></path><path d="M9.29789 9.77064C9.64716 10.1243 9.6436 10.6941 9.28994 11.0434L6.53146 13.7676C6.36053 13.9365 6.1292 14.0299 5.88897 14.0272C5.64874 14.0245 5.41956 13.9259 5.25245 13.7533L3.87321 12.3287C3.52747 11.9716 3.53668 11.4018 3.89379 11.0561C4.2509 10.7104 4.82067 10.7196 5.16642 11.0767L5.91339 11.8482L8.02512 9.76269C8.37878 9.41342 8.94862 9.41698 9.29789 9.77064Z" fill="currentColor"></path><path d="M9.29789 15.7436C9.64716 16.0973 9.6436 16.6671 9.28994 17.0164L6.53146 19.7406C6.36053 19.9094 6.1292 20.0029 5.88897 20.0002C5.64874 19.9975 5.41956 19.8989 5.25245 19.7263L3.87321 18.3017C3.52747 17.9446 3.53668 17.3748 3.89379 17.0291C4.2509 16.6833 4.82067 16.6926 5.16642 17.0497L5.91339 17.8212L8.02512 15.7357C8.37878 15.3864 8.94862 15.39 9.29789 15.7436Z" fill="currentColor"></path>',6)])])}const Pye=St({name:"kimi-todo",render:Oye}),jye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Hye(e,t){return v(),E("svg",jye,[...t[0]||(t[0]=[C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M8.09752 2.19507C8.5421 1.97278 9.08271 2.15298 9.305 2.59756L10.0562 4.10005H13.5C13.9971 4.10005 14.4 4.50299 14.4 5.00005C14.4 5.49711 13.9971 5.90005 13.5 5.90005H12.3106C12.2556 6.2319 12.1667 6.64073 12.0226 7.0987C11.7254 8.04355 11.191 9.20402 10.2334 10.3239C11.4166 11.196 12.5606 11.7524 13.4512 12.0987C13.978 12.3036 14.4136 12.434 14.7124 12.5122L14.7348 12.5181L15.695 10.5976C15.8475 10.2927 16.1591 10.1 16.5 10.1C16.8409 10.1 17.1525 10.2927 17.305 10.5976L20.7969 17.5814L20.8044 17.5959L20.8137 17.615L21.805 19.5976C22.0273 20.0421 21.8471 20.5827 21.4025 20.805C20.9579 21.0273 20.4173 20.8471 20.195 20.4025L19.4438 18.9H13.5562L12.805 20.4025C12.5827 20.8471 12.0421 21.0273 11.5975 20.805C11.1529 20.5827 10.9727 20.0421 11.195 19.5976L12.1863 17.615C12.1917 17.6036 12.1973 17.5924 12.2031 17.5814L13.9146 14.1583C13.6034 14.0667 13.2256 13.9423 12.7988 13.7764C11.7294 13.3605 10.3442 12.6802 8.92538 11.5924C7.79753 12.5167 6.69473 13.0764 5.83285 13.4112C5.33899 13.603 4.92286 13.7216 4.62401 13.7931C4.47449 13.8288 4.35399 13.8529 4.26741 13.8684C4.2241 13.8762 4.18924 13.8818 4.16343 13.8858L4.13156 13.8904L4.12084 13.8919L4.11682 13.8924L4.11514 13.8927C4.11514 13.8927 4.11368 13.8928 4.00001 13L4.11368 13.8928C3.62061 13.9556 3.17 13.6068 3.10722 13.1137C3.0446 12.6219 3.39148 12.1723 3.88256 12.1077L3.94947 12.0967C4.00428 12.0869 4.09114 12.0698 4.20543 12.0424C4.43422 11.9877 4.77156 11.8924 5.18106 11.7334C5.84103 11.477 6.68484 11.0564 7.56458 10.3753C7.15054 9.93496 6.78945 9.48388 6.50421 9.10102C6.26672 8.78224 6.07517 8.50172 5.94227 8.29973C5.87571 8.19858 5.82359 8.11671 5.78748 8.05909C5.76942 8.03027 5.75535 8.00749 5.74545 7.99135L5.73377 7.9722L5.73032 7.96651L5.72864 7.96371C5.71133 7.9349 5.69582 7.9055 5.68208 7.87566C5.49265 7.46416 5.6393 6.96717 6.03659 6.72853C6.09037 6.69623 6.14617 6.6702 6.20315 6.65023C6.59739 6.51205 7.04758 6.66421 7.27129 7.03623L7.27266 7.0385L7.28001 7.05054C7.28695 7.06186 7.29793 7.07964 7.31274 7.10328C7.34239 7.15059 7.38731 7.2212 7.44595 7.31032C7.56343 7.48886 7.73484 7.73997 7.94765 8.02562C8.21085 8.37889 8.52772 8.77187 8.8756 9.14201C9.64226 8.24147 10.0681 7.3133 10.3056 6.55854C10.381 6.3186 10.4372 6.09683 10.4791 5.90005H9.51951C9.50696 5.90031 9.49442 5.90031 9.48191 5.90005H4.00001C3.50296 5.90005 3.10001 5.49711 3.10001 5.00005C3.10001 4.50299 3.50296 4.10005 4.00001 4.10005H8.04378L7.69503 3.40254C7.67314 3.35877 7.65516 3.31407 7.64094 3.26883C7.51078 2.8546 7.69671 2.39547 8.09752 2.19507ZM16.5 13.0125L18.5438 17.1H14.4562L16.5 13.0125Z",fill:"currentColor"},null,-1),C("path",{d:"M15.1 4.00007C15.1 3.50301 15.5029 3.10007 16 3.10007H18C19.6016 3.10007 20.9 4.39844 20.9 6.00007V8.00007C20.9 8.49712 20.497 8.90007 20 8.90007C19.5029 8.90007 19.1 8.49712 19.1 8.00007V6.00007C19.1 5.39255 18.6075 4.90007 18 4.90007H16C15.5029 4.90007 15.1 4.49712 15.1 4.00007Z",fill:"currentColor"},null,-1),C("path",{d:"M3.99998 15.1001C4.49703 15.1001 4.89998 15.503 4.89998 16.0001V18.0001C4.89998 18.6076 5.39246 19.1001 5.99998 19.1001H7.99998C8.49703 19.1001 8.89998 19.503 8.89998 20.0001C8.89998 20.4971 8.49703 20.9001 7.99998 20.9001H5.99998C4.39835 20.9001 3.09998 19.6017 3.09998 18.0001V16.0001C3.09998 15.503 3.50292 15.1001 3.99998 15.1001Z",fill:"currentColor"},null,-1)])])}const Wye=St({name:"kimi-translate",render:Hye}),qye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Uye(e,t){return v(),E("svg",qye,[...t[0]||(t[0]=[C("path",{d:"M8.10001 3C8.10001 2.50294 8.50295 2.1 9.00001 2.1H15C15.4971 2.1 15.9 2.50294 15.9 3C15.9 3.49706 15.4971 3.9 15 3.9H9.00001C8.50295 3.9 8.10001 3.49706 8.10001 3Z",fill:"currentColor"},null,-1),C("path",{d:"M10 15.9C9.50295 15.9 9.10001 15.4971 9.10001 15L9.10001 10C9.10001 9.50294 9.50295 9.1 10 9.1C10.4971 9.1 10.9 9.50294 10.9 10L10.9 15C10.9 15.4971 10.4971 15.9 10 15.9Z",fill:"currentColor"},null,-1),C("path",{d:"M13.1 15C13.1 15.4971 13.5029 15.9 14 15.9C14.4971 15.9 14.9 15.4971 14.9 15L14.9 10C14.9 9.50294 14.4971 9.1 14 9.1C13.5029 9.1 13.1 9.50294 13.1 10V15Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M2.10001 6C2.10001 5.50294 2.50295 5.1 3.00001 5.1H4.99152C4.99785 5.09993 5.00417 5.09993 5.01048 5.1H18.9895C18.9958 5.09993 19.0021 5.09993 19.0085 5.1H21C21.4971 5.1 21.9 5.50294 21.9 6C21.9 6.49706 21.4971 6.9 21 6.9H19.8281L18.8448 18.6993C18.7412 19.9432 17.7013 20.9 16.4531 20.9H7.54686C6.29865 20.9 5.25881 19.9432 5.15515 18.6993L4.17188 6.9H3.00001C2.50295 6.9 2.10001 6.49706 2.10001 6ZM5.97811 6.9L18.0219 6.9L17.0511 18.5498C17.0251 18.8608 16.7652 19.1 16.4531 19.1H7.54686C7.23481 19.1 6.97485 18.8608 6.94893 18.5498L5.97811 6.9Z",fill:"currentColor"},null,-1)])])}const Kye=St({name:"kimi-trash",render:Uye}),Vye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Zye(e,t){return v(),E("svg",Vye,[...t[0]||(t[0]=[C("path",{d:"M7.36336 3.3634C7.71483 3.01192 8.28533 3.01192 8.6368 3.3634C8.98817 3.71488 8.98824 4.2854 8.6368 4.63683L6.17391 7.09972H15.0001C18.2585 7.09977 20.9005 9.74166 20.9005 13.0001C20.9004 16.2585 18.2585 18.9005 15.0001 18.9005H7.00008C6.50307 18.9005 6.09976 18.4971 6.09969 18.0001C6.09969 17.5031 6.50302 17.0997 7.00008 17.0997H15.0001C17.2644 17.0997 19.0996 15.2644 19.0997 13.0001C19.0997 10.7358 17.2644 8.90055 15.0001 8.90051H6.17391L8.6368 11.3634L8.69832 11.4318C8.98668 11.7853 8.96632 12.3073 8.6368 12.6368C8.30728 12.9663 7.78521 12.9867 7.43172 12.6984L7.36336 12.6368L3.36336 8.63683C3.33098 8.60445 3.30286 8.56908 3.27645 8.53332C3.25597 8.50559 3.23607 8.47741 3.21883 8.44738C3.20492 8.42311 3.19221 8.39837 3.18074 8.37316C3.1764 8.36365 3.17109 8.35453 3.16707 8.34484C3.1627 8.33427 3.1593 8.32331 3.15535 8.31261C3.12946 8.24274 3.11237 8.16872 3.10457 8.09191C3.09258 7.97426 3.10262 7.85446 3.1368 7.74035C3.14281 7.72035 3.15094 7.70114 3.15828 7.68176C3.16165 7.67283 3.16341 7.66325 3.16707 7.65441C3.17216 7.64216 3.17806 7.63025 3.18367 7.61828C3.19055 7.60356 3.19744 7.58874 3.20516 7.57433C3.24709 7.49624 3.3012 7.42556 3.36336 7.3634L7.36336 3.3634Z",fill:"currentColor"},null,-1)])])}const Gye=St({name:"kimi-undo",render:Zye}),Qye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function Yye(e,t){return v(),E("svg",Qye,[...t[0]||(t[0]=[C("path",{d:"M11.9997 12.8779C16.0197 12.878 19.4393 15.3848 20.7048 18.8828C21.0812 19.9234 20.2782 20.8962 19.2038 21.0137L18.9861 21.0264H5.0134L4.79562 21.0137C3.7213 20.8961 2.91743 19.9233 3.29367 18.8828C4.55905 15.3847 7.9797 12.8781 11.9997 12.8779ZM11.9997 14.6777C8.84467 14.6779 6.17462 16.5794 5.09152 19.2256H18.9079C17.8248 16.5793 15.1549 14.6778 11.9997 14.6777ZM12.2312 3.00586C14.6088 3.1264 16.4997 5.09239 16.4997 7.5L16.4939 7.73145C16.3734 10.1091 14.4073 11.9999 11.9997 12C9.59225 11.9998 7.62604 10.109 7.50558 7.73145L7.49973 7.5C7.49973 5.01485 9.51462 3.00021 11.9997 3L12.2312 3.00586ZM11.9997 4.7998C10.5087 4.80001 9.29953 6.00896 9.29953 7.5C9.29953 8.99104 10.5087 10.2 11.9997 10.2002C13.4908 10.2001 14.6999 8.99112 14.6999 7.5C14.6999 6.00888 13.4908 4.79989 11.9997 4.7998Z",fill:"currentColor"},null,-1)])])}const Jye=St({name:"kimi-user",render:Yye}),Xye={width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg"};function e9e(e,t){return v(),E("svg",Xye,[...t[0]||(t[0]=[C("path",{d:"M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z",fill:"currentColor"},null,-1),C("path",{d:"M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z",fill:"currentColor"},null,-1),C("path",{"fill-rule":"evenodd","clip-rule":"evenodd",d:"M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z",fill:"currentColor"},null,-1)])])}const t9e=St({name:"kimi-warning",render:e9e}),n9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function i9e(e,t){return v(),E("svg",n9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 6h8m4 0h4M6 12a2 2 0 1 0 4 0a2 2 0 1 0-4 0m-2 0h2m4 0h10m-5 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 18h11m4 0h1"},null,-1)])])}const o9e=St({name:"tabler-adjustments-horizontal",render:i9e}),s9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function r9e(e,t){return v(),E("svg",s9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m15 6l-6 6l6 6"},null,-1)])])}const l9e=St({name:"tabler-chevron-left",render:r9e}),a9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function u9e(e,t){return v(),E("svg",a9e,[...t[0]||(t[0]=[C("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[C("path",{d:"M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0"}),C("path",{d:"m9 12l2 2l4-4"})],-1)])])}const c9e=St({name:"tabler-circle-check",render:u9e}),d9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function f9e(e,t){return v(),E("svg",d9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M8.56 3.69a9 9 0 0 0-2.92 1.95M3.69 8.56A9 9 0 0 0 3 12m.69 3.44a9 9 0 0 0 1.95 2.92m2.92 1.95A9 9 0 0 0 12 21m3.44-.69a9 9 0 0 0 2.92-1.95m1.95-2.92A9 9 0 0 0 21 12m-.69-3.44a9 9 0 0 0-1.95-2.92m-2.92-1.95A9 9 0 0 0 12 3"},null,-1)])])}const h9e=St({name:"tabler-circle-dashed",render:f9e}),p9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function g9e(e,t){return v(),E("svg",p9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M3 5a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zm4 15h10m-8-4v4m6-4v4"},null,-1)])])}const m9e=St({name:"tabler-device-desktop",render:g9e}),v9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function y9e(e,t){return v(),E("svg",v9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M9 3h6m-5 6h4m-4-6v6L6 20a.7.7 0 0 0 .5 1h11a.7.7 0 0 0 .5-1L14 9V3"},null,-1)])])}const k9e=St({name:"tabler-flask",render:y9e}),b9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function A9e(e,t){return v(),E("svg",b9e,[...t[0]||(t[0]=[C("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[C("path",{d:"M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm11-2v16"}),C("path",{d:"m9 10l2 2l-2 2"})],-1)])])}const C9e=St({name:"tabler-layout-sidebar-right-collapse",render:A9e}),w9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function x9e(e,t){return v(),E("svg",w9e,[...t[0]||(t[0]=[C("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3L18 10a3 3 0 0 0-6-6l-6.5 6.5a4.5 4.5 0 0 0 9 9L21 13"},null,-1)])])}const S9e=St({name:"tabler-paperclip",render:x9e}),_9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function M9e(e,t){return v(),E("svg",_9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12A2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3m16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5"},null,-1)])])}const I9e=St({name:"ri-braces-line",render:M9e}),E9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function T9e(e,t){return v(),E("svg",E9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M9 3V1H7v2H3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4V1h-2v2zm-5 7h16v9H4zm0-5h3v1h2V5h6v1h2V5h3v3H4zm5.879 5.964L12 13.086l2.121-2.122l1.415 1.415l-2.122 2.121l2.121 2.121l-1.414 1.414L12 15.915l-2.121 2.12l-1.415-1.414l2.122-2.12l-2.122-2.122z"},null,-1)])])}const L9e=St({name:"ri-calendar-close-line",render:T9e}),N9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function F9e(e,t){return v(),E("svg",N9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M7 3V1h2v2h6V1h2v2h4a1 1 0 0 1 1 1v5h-2V5h-3v2h-2V5H9v2H7V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm10 9a4 4 0 1 0 0 8a4 4 0 0 0 0-8m-6 4a6 6 0 1 1 12 0a6 6 0 0 1-12 0m5-3v3.414l2.293 2.293l1.414-1.414L18 15.586V13z"},null,-1)])])}const D9e=St({name:"ri-calendar-schedule-line",render:F9e}),B9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function $9e(e,t){return v(),E("svg",B9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1zm11 10H4v8h16zM8 14v2H6v-2zm10 0v2h-8v-2zM7 5H4v4h16V5h-3v2h-2V5H9v2H7z"},null,-1)])])}const R9e=St({name:"ri-calendar-todo-line",render:$9e}),z9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function O9e(e,t){return v(),E("svg",z9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414z"},null,-1)])])}const P9e=St({name:"ri-code-line",render:O9e}),j9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function H9e(e,t){return v(),E("svg",j9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-4-7h8a4 4 0 0 1-8 0m0-2a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m8 0a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3"},null,-1)])])}const W9e=St({name:"ri-emotion-line",render:H9e}),q9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function U9e(e,t){return v(),E("svg",q9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"},null,-1)])])}const K9e=St({name:"ri-external-link-line",render:U9e}),V9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Z9e(e,t){return v(),E("svg",V9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12 3c5.392 0 9.878 3.88 10.819 9c-.94 5.12-5.427 9-10.819 9s-9.878-3.88-10.818-9C2.122 6.88 6.608 3 12 3m0 16a9.005 9.005 0 0 0 8.778-7a9.005 9.005 0 0 0-17.555 0A9.005 9.005 0 0 0 12 19m0-2.5a4.5 4.5 0 1 1 0-9a4.5 4.5 0 0 1 0 9m0-2a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5"},null,-1)])])}const G9e=St({name:"ri-eye-line",render:Z9e}),Q9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function Y9e(e,t){return v(),E("svg",Q9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M17.883 19.297A10.95 10.95 0 0 1 12 21c-5.392 0-9.878-3.88-10.818-9A11 11 0 0 1 4.52 5.935L1.394 2.808l1.414-1.414l19.799 19.798l-1.414 1.415zM5.936 7.35A8.97 8.97 0 0 0 3.223 12a9.005 9.005 0 0 0 13.201 5.838l-2.028-2.028A4.5 4.5 0 0 1 8.19 9.604zm6.978 6.978l-3.242-3.241a2.5 2.5 0 0 0 3.241 3.241m7.893 2.265l-1.431-1.431A8.9 8.9 0 0 0 20.778 12A9.005 9.005 0 0 0 9.552 5.338L7.974 3.76C9.221 3.27 10.58 3 12 3c5.392 0 9.878 3.88 10.819 9a10.95 10.95 0 0 1-2.012 4.593m-9.084-9.084Q11.86 7.5 12 7.5a4.5 4.5 0 0 1 4.492 4.778z"},null,-1)])])}const J9e=St({name:"ri-eye-off-line",render:Y9e}),X9e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function e4e(e,t){return v(),E("svg",X9e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M15 4H5v16h14V8h-4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008zM11 11V8h2v3h3v2h-3v3h-2v-3H8v-2z"},null,-1)])])}const t4e=St({name:"ri-file-add-line",render:e4e}),n4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function i4e(e,t){return v(),E("svg",n4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M13 9h8L11 24v-9H4l9-15zm-2 2V7.22L7.532 13H13v4.394L17.263 11z"},null,-1)])])}const o4e=St({name:"ri-flashlight-line",render:i4e}),s4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function r4e(e,t){return v(),E("svg",s4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M14 4.438A2.437 2.437 0 0 0 16.438 2h1.125A2.437 2.437 0 0 0 20 4.438v1.125A2.437 2.437 0 0 0 17.563 8h-1.125A2.437 2.437 0 0 0 14 5.563zM1 11a6 6 0 0 0 6-6h2a6 6 0 0 0 6 6v2a6 6 0 0 0-6 6H7a6 6 0 0 0-6-6zm3.876 1A8.04 8.04 0 0 1 8 15.124A8.04 8.04 0 0 1 11.124 12A8.04 8.04 0 0 1 8 8.876A8.04 8.04 0 0 1 4.876 12m12.374 2A3.25 3.25 0 0 1 14 17.25v1.5A3.25 3.25 0 0 1 17.25 22h1.5A3.25 3.25 0 0 1 22 18.75v-1.5A3.25 3.25 0 0 1 18.75 14z"},null,-1)])])}const l4e=St({name:"ri-sparkling-line",render:r4e}),a4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function u4e(e,t){return v(),E("svg",a4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"},null,-1)])])}const c4e=St({name:"ri-folder-fill",render:u4e}),d4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function f4e(e,t){return v(),E("svg",d4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M6 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2M3 6a3 3 0 1 1 4 2.83V9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-.17a3.001 3.001 0 1 1 2 0V9a4 4 0 0 1-4 4h-2v2.17a3.001 3.001 0 1 1-2 0V13H9a4 4 0 0 1-4-4v-.17A3 3 0 0 1 3 6m15-1a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-6 12a1 1 0 1 0 0 2a1 1 0 0 0 0-2"},null,-1)])])}const h4e=St({name:"ri-git-fork-line",render:f4e}),p4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function g4e(e,t){return v(),E("svg",p4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M15 5h2a2 2 0 0 1 2 2v8.17a3.001 3.001 0 1 1-2 0V7h-2v3l-4.5-4L15 2zM5 8.83a3.001 3.001 0 1 1 2 0v6.34a3.001 3.001 0 1 1-2 0zM6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m0 12a1 1 0 1 0 0-2a1 1 0 0 0 0 2m12 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2"},null,-1)])])}const m4e=St({name:"ri-git-pull-request-line",render:g4e}),v4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function y4e(e,t){return v(),E("svg",v4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M2 18h7v2H2zm0-7h9v2H2zm0-7h20v2H2zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4 4 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391a4 4 0 0 1-1.435.83L19 21h-2l-.24-1.196a4 4 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4 4 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196a4 4 0 0 1 1.434.83M18 18a2 2 0 1 0 0-4a2 2 0 0 0 0 4"},null,-1)])])}const k4e=St({name:"ri-list-settings-line",render:y4e}),b4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function A4e(e,t){return v(),E("svg",b4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M10 2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H8v2h5V9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H8v6h5v-1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H7a1 1 0 0 1-1-1V8H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm9 16h-4v2h4zm0-8h-4v2h4zM9 4H5v2h4z"},null,-1)])])}const C4e=St({name:"ri-node-tree",render:A4e}),w4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function x4e(e,t){return v(),E("svg",w4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m13.827 1.69l8.486 8.485l-1.415 1.414l-.707-.707l-4.242 4.243l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243l1.414-1.414l3.536-.707l4.242-4.243l-.707-.707zm.707 3.536l-4.67 4.67l-2.822.565l6.5 6.5l.564-2.822l4.671-4.67z"},null,-1)])])}const S4e=St({name:"ri-pushpin-line",render:x4e}),_4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function M4e(e,t){return v(),E("svg",_4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M20 4v12h3l-4 5l-4-5h3V4zm-8 14v2H3v-2zm2-7v2H3v-2zm0-7v2H3V4z"},null,-1)])])}const I4e=St({name:"ri-sort-desc",render:M4e}),E4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function T4e(e,t){return v(),E("svg",E4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928z"},null,-1)])])}const L4e=St({name:"ri-star-fill",render:T4e}),N4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function F4e(e,t){return v(),E("svg",N4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928zm0-2.292l4.247 2.377l-.948-4.773l3.573-3.305l-4.833-.573l-2.038-4.419l-2.039 4.42l-4.833.572l3.573 3.305l-.948 4.773z"},null,-1)])])}const D4e=St({name:"ri-star-line",render:F4e}),B4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function $4e(e,t){return v(),E("svg",B4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"M5.33 3.272a3.5 3.5 0 0 1 4.254 4.962l10.709 10.71l-1.414 1.414l-10.71-10.71a3.502 3.502 0 0 1-4.962-4.255L5.444 7.63a1.5 1.5 0 0 0 2.121-2.121zm10.367 1.883l3.182-1.768l1.414 1.415l-1.768 3.182l-1.768.353l-2.12 2.121l-1.415-1.414l2.121-2.121zm-6.718 8.132l1.415 1.414l-5.304 5.303a1 1 0 0 1-1.492-1.327l.078-.087z"},null,-1)])])}const R4e=St({name:"ri-tools-line",render:$4e}),z4e={viewBox:"0 0 24 24",width:"1.2em",height:"1.2em"};function O4e(e,t){return v(),E("svg",z4e,[...t[0]||(t[0]=[C("path",{fill:"currentColor",d:"m20.97 17.172l-1.414 1.414l-3.535-3.535l-.073.074l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243L5.34 8.761l3.536-.707l.073-.074l-3.536-3.536L6.828 3.03zM10.365 9.394l-.502.502l-2.822.565l6.5 6.5l.564-2.822l.502-.502zm8.411.074l-1.34 1.34l1.414 1.415l1.34-1.34l.707.707l1.415-1.415l-8.486-8.485l-1.414 1.414l.707.707l-1.34 1.34l1.414 1.415l1.34-1.34z"},null,-1)])])}const P4e=St({name:"ri-unpin-line",render:O4e}),j4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12.0684 2.03418C12.5654 2.03421 12.9687 2.43755 12.9688 2.93457V11.0996H21.0654C21.5625 11.0996 21.9658 11.503 21.9658 12C21.9658 12.497 21.5625 12.9004 21.0654 12.9004H12.9688V21.0654C12.9687 21.5624 12.5654 21.9658 12.0684 21.9658C11.5713 21.9658 11.168 21.5625 11.168 21.0654V12.9004H2.93457C2.43751 12.9004 2.03418 12.4971 2.03418 12C2.03418 11.5029 2.43751 11.0996 2.93457 11.0996H11.168V2.93457C11.168 2.43753 11.5713 2.03418 12.0684 2.03418Z" fill="currentColor"/> -</svg> -`,H4e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path id="p0" d="M 0 -9.9 C -5.468 -9.9 -9.9 -5.468 -9.9 0 C -9.9 1.923 -9.351 3.719 -8.402 5.239 C -8.402 5.239 -9.483 7.821 -9.483 7.821 C -9.896 8.809 -9.171 9.9 -8.099 9.9 C -8.099 9.9 0 9.9 0 9.9 C 5.468 9.9 9.9 5.468 9.9 0 C 9.9 -5.468 5.468 -9.9 0 -9.9 Z M -8.1 0 C -8.1 -4.474 -4.474 -8.1 0 -8.1 C 4.473 -8.1 8.1 -4.474 8.1 0 C 8.1 4.473 4.473 8.1 -0.001 8.1 C -0.001 8.1 -7.648 8.1 -7.648 8.1 L -6.365 5.035 C -6.365 5.035 -6.648 4.629 -6.648 4.629 C -7.563 3.317 -8.1 1.723 -8.1 0 Z" transform="matrix(1 0 0 1 12 12)" fill="currentColor" fill-rule="evenodd"/> - <path id="p1" d="M 3.6 0.5 L -2.6 0.5 M 0.5 -2.573 L 0.5 3.573" transform="translate(11.5 11.5)" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/> -</svg> -`,W4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M15.0996 12C15.5967 12 16 12.4033 16 12.9004C15.9998 13.3973 15.5965 13.7998 15.0996 13.7998H8.90039C8.40346 13.7998 8.00021 13.3973 8 12.9004C8 12.4033 8.40333 12 8.90039 12H15.0996Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M19 3.2002C20.5464 3.2002 21.7998 4.4536 21.7998 6V7C21.7998 8.03565 21.2363 8.93754 20.4004 9.42188V17C20.4004 19.1539 18.6539 20.9004 16.5 20.9004H7.5C5.34609 20.9004 3.59961 19.1539 3.59961 17V9.42188C2.76374 8.93754 2.2002 8.03565 2.2002 7V6C2.2002 4.4536 3.4536 3.2002 5 3.2002H19ZM5.40039 17C5.40039 18.1598 6.3402 19.0996 7.5 19.0996H16.5C17.6598 19.0996 18.5996 18.1598 18.5996 17V9.7998H5.40039V17ZM4.89746 5.00488C4.39333 5.05621 4 5.48232 4 6V7L4.00488 7.10254C4.05278 7.57297 4.42703 7.94722 4.89746 7.99512L5 8H19C19.5523 8 20 7.55228 20 7V6C20 5.44772 19.5523 5 19 5H5L4.89746 5.00488Z" fill="currentColor"/> -</svg> -`,q4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.386 21.6387C11.7378 21.988 12.3059 21.987 12.6565 21.6364L18.1949 16.098C18.5464 15.7465 18.5464 15.1766 18.1949 14.8252C17.8434 14.4737 17.2736 14.4737 16.9221 14.8252L12.9201 18.8272V3.00002C12.9201 2.50297 12.5171 2.10003 12.0201 2.10003C11.523 2.10003 11.1201 2.50297 11.1201 3.00002V18.8383L7.07554 14.8229C6.7228 14.4727 6.15295 14.4747 5.80275 14.8275C5.45255 15.1802 5.45461 15.7501 5.80735 16.1003L11.386 21.6387Z" fill="currentColor"/> -</svg> -`,U4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M2.16127 12.814C1.81197 12.4622 1.81299 11.8941 2.16357 11.5435L7.70203 6.00506C8.0535 5.65359 8.62335 5.65359 8.97482 6.00506C9.32629 6.35653 9.32629 6.92638 8.97482 7.27785L4.97276 11.2799H20.8C21.297 11.2799 21.7 11.6829 21.7 12.1799C21.7 12.677 21.297 13.0799 20.8 13.0799H4.96171L8.97712 17.1244C9.32732 17.4772 9.32526 18.047 8.97252 18.3972C8.61978 18.7474 8.04993 18.7454 7.69973 18.3926L2.16127 12.814Z" fill="currentColor"/> -</svg> -`,K4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M21.4387 12.814C21.788 12.4622 21.787 11.8941 21.4364 11.5436L15.8979 6.0051C15.5464 5.65363 14.9766 5.65363 14.6251 6.0051C14.2737 6.35657 14.2737 6.92642 14.6251 7.27789L18.6272 11.28H2.79998C2.30293 11.28 1.89998 11.6829 1.89998 12.18C1.89998 12.677 2.30293 13.08 2.79998 13.08H18.6382L14.6228 17.1245C14.2726 17.4772 14.2747 18.0471 14.6274 18.3973C14.9802 18.7475 15.55 18.7454 15.9002 18.3927L21.4387 12.814Z" fill="currentColor"/> -</svg> -`,V4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.386 2.36129C11.7378 2.01198 12.3059 2.013 12.6565 2.36358L18.1949 7.90204C18.5464 8.25351 18.5464 8.82336 18.1949 9.17483C17.8434 9.52631 17.2736 9.52631 16.9221 9.17483L12.9201 5.17277V21C12.9201 21.497 12.5171 21.9 12.0201 21.9C11.523 21.9 11.1201 21.497 11.1201 21V5.16172L7.07554 9.17713C6.7228 9.52733 6.15295 9.52527 5.80275 9.17253C5.45255 8.81979 5.45461 8.24995 5.80735 7.89975L11.386 2.36129Z" fill="currentColor"/> -</svg> -`,gR=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M19.3027 5.9053C19.6542 5.55397 20.2247 5.55388 20.5761 5.9053C20.9273 6.25675 20.9273 6.82734 20.5761 7.17874L9.65911 18.0948C9.30773 18.4461 8.73814 18.446 8.38665 18.0948L3.42376 13.1328C3.0726 12.7814 3.07263 12.2118 3.42376 11.8604C3.77524 11.509 4.34575 11.5089 4.6972 11.8604L9.02239 16.1856L19.3027 5.9053Z" fill="currentColor"/> -</svg> -`,Z4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3912 16.7134C11.743 17.0627 12.3111 17.0617 12.6617 16.7111L19.6364 9.73641C19.9878 9.38494 19.9878 8.81509 19.6364 8.46362C19.2849 8.11215 18.7151 8.11215 18.3636 8.46362L12.023 14.8042L5.63407 8.46132C5.28133 8.11112 4.71149 8.11318 4.36129 8.46592C4.01109 8.81866 4.01314 9.3885 4.36588 9.73871L11.3912 16.7134Z" fill="currentColor"/> -</svg> -`,G4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M16.1261 12.6088C16.4754 12.257 16.4743 11.6889 16.1238 11.3383L9.14904 4.36363C8.79757 4.01216 8.22772 4.01216 7.87625 4.36363C7.52477 4.7151 7.52477 5.28495 7.87625 5.63642L14.2169 11.977L7.87395 18.3659C7.52375 18.7187 7.52581 19.2885 7.87855 19.6387C8.23129 19.9889 8.80113 19.9869 9.15133 19.6341L16.1261 12.6088Z" fill="currentColor"/> -</svg> -`,Q4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.3912 8.46132C11.743 8.11202 12.3111 8.11304 12.6617 8.46362L19.6364 15.4383C19.9878 15.7898 19.9878 16.3597 19.6364 16.7111C19.2849 17.0626 18.7151 17.0626 18.3636 16.7111L12.023 10.3705L5.63407 16.7134C5.28133 17.0636 4.71149 17.0616 4.36129 16.7088C4.01109 16.3561 4.01314 15.7862 4.36588 15.436L11.3912 8.46132Z" fill="currentColor"/> -</svg> -`,Y4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<circle cx="12" cy="12" r="10.875" stroke="currentColor" stroke-width="2.25"/> -<path d="M7.125 12.6L10.65 16.125L17.025 8.85" stroke="currentColor" stroke-width="2.25" stroke-linecap="round" stroke-linejoin="round"/> -</svg> -`,J4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.8999 6.79965C12.397 6.79965 12.7997 7.20235 12.7997 7.69941V11.7266L14.7359 13.6629C15.0873 14.0143 15.0879 14.584 14.7366 14.9355C14.3852 15.287 13.8148 15.287 13.4633 14.9355L11.2632 12.7355C11.0947 12.5668 11.0002 12.338 11.0001 12.0995V7.69941C11.0001 7.20238 11.4029 6.7997 11.8999 6.79965Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M12 1.89893C17.4677 1.89893 21.9001 6.33147 21.9002 11.7991C21.9002 17.2669 17.4678 21.6993 12 21.6993C6.53228 21.6993 2.09985 17.2669 2.09985 11.7991C2.09998 6.33147 6.53236 1.89893 12 1.89893ZM20.1 11.7998C20.1 7.32616 16.4737 3.69984 12 3.69984C7.5264 3.69984 3.90008 7.32616 3.90008 11.7998C3.90032 16.2732 7.52655 19.8998 12 19.8998C16.4735 19.8998 20.0998 16.2732 20.1 11.7998Z" fill="currentColor"/> -</svg> -`,X4e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M17.9542 4.77253C18.3056 4.42106 18.8761 4.42106 19.2276 4.77253C19.579 5.12401 19.579 5.69452 19.2276 6.04597L13.2735 12.0001L19.2276 17.9542C19.5791 18.3056 19.5791 18.8761 19.2276 19.2276C18.8761 19.5791 18.3056 19.5791 17.9542 19.2276L12.0001 13.2735L6.04595 19.2276C5.69451 19.5791 5.12399 19.579 4.77252 19.2276C4.42104 18.8761 4.42104 18.3056 4.77252 17.9542L10.7266 12.0001L4.77252 6.04597C4.42104 5.6945 4.42104 5.124 4.77252 4.77253C5.12399 4.42107 5.69448 4.42106 6.04595 4.77253L12.0001 10.7266L17.9542 4.77253Z" fill="currentColor"/> -</svg> -`,e3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M9.85815 11.957C10.9074 11.957 11.7583 12.8083 11.7585 13.8574V19.8574C11.7585 20.3545 11.3552 20.7578 10.8582 20.7578C10.3611 20.7578 9.95776 20.3545 9.95776 19.8574V13.8574C9.95755 13.8024 9.91325 13.7578 9.85815 13.7578H3.85815C3.3611 13.7578 2.95776 13.3545 2.95776 12.8574C2.95798 12.3605 3.36123 11.957 3.85815 11.957H9.85815Z" fill="currentColor"/> -<path d="M12.8582 2.95703C13.3551 2.95703 13.7583 3.36054 13.7585 3.85742V9.85742C13.7585 9.91265 13.8029 9.95703 13.8582 9.95703H19.8582C20.3551 9.95703 20.7583 10.3605 20.7585 10.8574C20.7585 11.3545 20.3552 11.7578 19.8582 11.7578H13.8582C12.8088 11.7578 11.9578 10.9068 11.9578 9.85742V3.85742C11.958 3.36054 12.3612 2.95703 12.8582 2.95703Z" fill="currentColor"/> -</svg> -`,t3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.9004 2.19995C17.3678 2.20016 21.7998 6.63285 21.7998 12.1003C21.7996 17.5677 17.3677 21.9995 11.9004 21.9998H3.80078C2.72946 21.9996 2.00334 20.9089 2.41699 19.9207L3.49805 17.3386C2.54871 15.8189 2.00007 14.0226 2 12.1003C2 6.63272 6.43277 2.19995 11.9004 2.19995ZM11.9004 3.99976C7.42688 3.99976 3.7998 7.62684 3.7998 12.1003C3.79989 13.8228 4.33669 15.4175 5.25195 16.7292L5.53516 17.1345L4.25195 20.2H11.8994C16.3727 20.1999 19.9998 16.5736 20 12.1003C20 7.62697 16.3737 3.99997 11.9004 3.99976ZM8.9541 10.8005C9.75473 10.8006 10.4041 11.4491 10.4043 12.2498C10.4043 13.0505 9.75482 13.6998 8.9541 13.7C8.15329 13.7 7.50391 13.0506 7.50391 12.2498C7.50406 11.4491 8.15339 10.8005 8.9541 10.8005ZM15.1533 10.8005C15.9539 10.8006 16.6034 11.4491 16.6035 12.2498C16.6035 13.0505 15.954 13.6998 15.1533 13.7C14.3525 13.7 13.7031 13.0506 13.7031 12.2498C13.7033 11.4491 14.3526 10.8005 15.1533 10.8005Z" fill="currentColor"/> -</svg> -`,mR=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M17 7.09961C19.1539 7.09961 20.9004 8.84609 20.9004 11V17C20.9004 19.1539 19.1539 20.9004 17 20.9004H11C8.84609 20.9004 7.09961 19.1539 7.09961 17V11C7.09961 8.84609 8.84609 7.09961 11 7.09961H17ZM11 8.90039C9.8402 8.90039 8.90039 9.8402 8.90039 11V17C8.90039 18.1598 9.8402 19.0996 11 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V11C19.0996 9.8402 18.1598 8.90039 17 8.90039H11Z" fill="currentColor"/> -<path d="M13 3.09961C14.4447 3.09961 15.705 3.88644 16.3779 5.0498C16.6265 5.47999 16.4789 6.03049 16.0488 6.2793C15.6186 6.52781 15.0681 6.38029 14.8193 5.9502C14.4548 5.32041 13.776 4.90039 13 4.90039H7C5.8402 4.90039 4.90039 5.8402 4.90039 7V13C4.90039 13.776 5.32041 14.4548 5.9502 14.8193C6.38029 15.0681 6.52781 15.6186 6.2793 16.0488C6.03049 16.4789 5.47999 16.6265 5.0498 16.3779C3.88644 15.705 3.09961 14.4447 3.09961 13V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H13Z" fill="currentColor"/> -</svg> -`,n3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 10.2797 2.43414 8.66074 3.19922 7.24707C3.20172 7.24246 3.20453 7.23801 3.20703 7.2334C3.33385 6.99995 3.47181 6.77351 3.61621 6.55176C3.73214 6.37355 3.85079 6.19744 3.97754 6.02734C5.35905 4.17471 7.36856 2.81959 9.68945 2.27051C9.69952 2.26813 9.70965 2.26602 9.71973 2.26367C9.85224 2.23276 9.98563 2.2043 10.1201 2.17871C10.1542 2.17221 10.1884 2.16631 10.2227 2.16016C10.3466 2.13791 10.4712 2.11724 10.5967 2.09961C10.6301 2.09489 10.6637 2.0913 10.6973 2.08691C10.8216 2.07073 10.9465 2.05552 11.0723 2.04395C11.1125 2.04022 11.153 2.0384 11.1934 2.03516C11.4595 2.0139 11.7284 2 12 2ZM11.9941 3.7998C11.9968 3.86623 12 3.93292 12 4C12 6.76142 9.76142 9 7 9C6.14209 9 5.33517 8.78324 4.62988 8.40234C4.09862 9.48861 3.7998 10.7093 3.7998 12C3.7998 12.4438 3.83644 12.8791 3.9043 13.3037C4.52807 12.5673 5.45945 12.0996 6.5 12.0996C8.37777 12.0996 9.90039 13.6222 9.90039 15.5C9.90039 17.0702 8.83532 18.3903 7.38867 18.7812C8.70267 19.6765 10.2901 20.2002 12 20.2002C12.468 20.2002 12.9264 20.1583 13.373 20.083C13.1323 19.4342 13 18.7327 13 18C13 14.6863 15.6863 12 19 12C19.4098 12 19.8098 12.0416 20.1963 12.1201C20.1969 12.0801 20.2002 12.0401 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998H11.9941ZM19 13.7998C16.6804 13.7998 14.7998 15.6804 14.7998 18C14.7998 18.5617 14.9112 19.0972 15.1113 19.5869C17.5225 18.597 19.3558 16.4929 19.9727 13.9141C19.6605 13.8399 19.3349 13.7998 19 13.7998ZM6.5 13.9004C5.61634 13.9004 4.90039 14.6163 4.90039 15.5C4.90039 16.3837 5.61634 17.0996 6.5 17.0996C7.38366 17.0996 8.09961 16.3837 8.09961 15.5C8.09961 14.6163 7.38366 13.9004 6.5 13.9004ZM15.5 6.09961C16.8255 6.09961 17.9004 7.17452 17.9004 8.5C17.9004 9.82548 16.8255 10.9004 15.5 10.9004C14.1745 10.9004 13.0996 9.82548 13.0996 8.5C13.0996 7.17452 14.1745 6.09961 15.5 6.09961ZM15.5 7.90039C15.1686 7.90039 14.9004 8.16863 14.9004 8.5C14.9004 8.83137 15.1686 9.09961 15.5 9.09961C15.8314 9.09961 16.0996 8.83137 16.0996 8.5C16.0996 8.16863 15.8314 7.90039 15.5 7.90039ZM10.1992 4C8.35326 4.41375 6.74333 5.44923 5.59961 6.87598C6.02235 7.08306 6.49716 7.2002 7 7.2002C8.76731 7.2002 10.1992 5.76731 10.1992 4Z" fill="currentColor"/> -</svg> -`,i3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.90002C12.4971 2.90002 12.9 3.30297 12.9 3.80002V12.2939L15.8081 9.38585C16.1595 9.03438 16.7294 9.03438 17.0808 9.38585C17.4323 9.73732 17.4323 10.3072 17.0808 10.6586L12.6364 15.1031C12.4676 15.2719 12.2387 15.3667 12 15.3667C11.7613 15.3667 11.5324 15.2719 11.3636 15.1031L6.91917 10.6586C6.5677 10.3072 6.5677 9.73732 6.91917 9.38585C7.27064 9.03438 7.84049 9.03438 8.19196 9.38585L11.1 12.2939V3.80002C11.1 3.30297 11.503 2.90002 12 2.90002ZM4.00001 13.5874C4.49706 13.5874 4.90001 13.9903 4.90001 14.4874V18.043C4.90001 18.2758 4.99249 18.499 5.1571 18.6636C5.32172 18.8282 5.54498 18.9207 5.77778 18.9207H18.2222C18.455 18.9207 18.6783 18.8283 18.8429 18.6636C19.0075 18.499 19.1 18.2758 19.1 18.043V14.4874C19.1 13.9903 19.5029 13.5874 20 13.5874C20.4971 13.5874 20.9 13.9903 20.9 14.4874V18.043C20.9 18.7531 20.6179 19.4342 20.1157 19.9364C19.6135 20.4386 18.9324 20.7207 18.2222 20.7207H5.77778C5.06759 20.7207 4.38649 20.4386 3.88431 19.9364C3.38213 19.4342 3.10001 18.7531 3.10001 18.043V14.4874C3.10001 13.9903 3.50295 13.5874 4.00001 13.5874Z" fill="currentColor"/> -</svg> -`,o3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M18.0179 3.09998C18.3963 3.10003 18.7709 3.17491 19.1205 3.31971C19.4701 3.46454 19.7884 3.67614 20.056 3.94373C20.3237 4.21144 20.5362 4.52965 20.681 4.87928C20.8258 5.22887 20.8997 5.60423 20.8997 5.9828C20.8997 6.36118 20.8257 6.73591 20.681 7.08533C20.5362 7.43497 20.3237 7.75317 20.056 8.02088L17.639 10.4379L9.15756 18.9183C8.5296 19.5463 7.74274 19.992 6.8812 20.2074L4.21811 20.8734C3.91148 20.95 3.5871 20.8596 3.36362 20.6361C3.14017 20.4126 3.05063 20.0883 3.12729 19.7816L3.79233 17.1185C4.00771 16.257 4.45344 15.4701 5.08139 14.8422L15.9798 3.94373C16.5203 3.40346 17.2536 3.09998 18.0179 3.09998ZM19.0003 19.1C19.4972 19.1002 19.8997 19.5034 19.8997 20.0004C19.8995 20.4971 19.4971 20.8996 19.0003 20.8998H12.0003C11.5034 20.8998 11.1001 20.4973 11.0999 20.0004C11.0999 19.5033 11.5033 19.1 12.0003 19.1H19.0003ZM18.0179 4.89979C17.7309 4.89979 17.4553 5.01417 17.2523 5.21717L6.35385 16.1146C5.95661 16.5119 5.67469 17.01 5.53842 17.5551L5.23666 18.7631L6.44467 18.4613C6.98971 18.3251 7.48782 18.0431 7.8851 17.6459L18.7826 6.74744C18.883 6.64702 18.9635 6.52821 19.0179 6.39686C19.0723 6.26558 19.0999 6.1247 19.0999 5.9828C19.0999 5.84075 19.0723 5.69916 19.0179 5.56776C18.9635 5.43645 18.883 5.31757 18.7826 5.21717C18.6821 5.11678 18.5631 5.03716 18.432 4.9828C18.3008 4.92845 18.16 4.89983 18.0179 4.89979Z" fill="currentColor"/> -</svg> -`,s3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M5 11.0996C5.49693 11.0996 5.90018 11.5031 5.90039 12V18C5.90039 18.0552 5.94477 18.0996 6 18.0996H12C12.4969 18.0996 12.9002 18.5031 12.9004 19C12.9004 19.4971 12.4971 19.9004 12 19.9004H6C4.95066 19.9004 4.09961 19.0493 4.09961 18V12C4.09982 11.5031 4.50307 11.0996 5 11.0996ZM18 4.09961C19.0492 4.09961 19.9002 4.95084 19.9004 6V12C19.9004 12.4971 19.4971 12.9004 19 12.9004C18.5029 12.9004 18.0996 12.4971 18.0996 12V6C18.0994 5.94495 18.0551 5.90039 18 5.90039H12C11.5029 5.90039 11.0996 5.49706 11.0996 5C11.0998 4.50312 11.5031 4.09961 12 4.09961H18Z" fill="currentColor"/> -</svg> -`,w8=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<g> -<path fill-rule="evenodd" clip-rule="evenodd" d="M13.1723 2.1001C13.9413 2.10018 14.6793 2.40592 15.2231 2.94971L19.0512 6.77783C19.595 7.32162 19.9007 8.0596 19.9008 8.82861V18.0005C19.9008 20.1544 18.1543 21.9009 16.0004 21.9009H8.0004C5.84649 21.9009 4.10001 20.1544 4.10001 18.0005V6.00049C4.10001 3.84658 5.84649 2.1001 8.0004 2.1001H13.1723ZM8.0004 3.90088C6.8406 3.90088 5.90079 4.84069 5.90079 6.00049V18.0005C5.90079 19.1603 6.8406 20.1001 8.0004 20.1001H16.0004C17.1602 20.1001 18.1 19.1603 18.1 18.0005V9.90088H15.0004C13.3988 9.90088 12.1 8.60211 12.1 7.00049V3.90088H8.0004ZM13.9008 7.00049C13.9008 7.608 14.3929 8.1001 15.0004 8.1001H17.8217C17.8072 8.08375 17.7933 8.06681 17.7777 8.05127L13.9496 4.22314C13.9339 4.20745 13.9173 4.19286 13.9008 4.17822V7.00049Z" fill="currentColor"/> -</g> -</svg> -`,r3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M15.4795 15.4971C15.9765 15.4971 16.3799 15.9004 16.3799 16.3975C16.3799 16.8945 15.9765 17.2978 15.4795 17.2979H8.52051C8.02345 17.2979 7.62012 16.8945 7.62012 16.3975C7.62012 15.9004 8.02345 15.4971 8.52051 15.4971H15.4795Z" fill="currentColor"/> -<path d="M12.3359 11.0996C12.8329 11.0997 13.2354 11.503 13.2354 12C13.2354 12.497 12.8329 12.9003 12.3359 12.9004H8.52051C8.02345 12.9004 7.62012 12.4971 7.62012 12C7.62012 11.5029 8.02345 11.0996 8.52051 11.0996H12.3359Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M13.1719 2.09961C13.9408 2.09969 14.6789 2.40555 15.2227 2.94922L19.0508 6.77734C19.5946 7.32113 19.9003 8.05911 19.9004 8.82812V18C19.9004 20.1539 18.1539 21.9004 16 21.9004H8C5.84626 21.9002 4.09961 20.1538 4.09961 18V6C4.09961 3.84621 5.84626 2.09981 8 2.09961H13.1719ZM8 3.90039C6.84037 3.90059 5.90039 4.84032 5.90039 6V18C5.90039 19.1597 6.84037 20.0994 8 20.0996H16C17.1598 20.0996 18.0996 19.1598 18.0996 18V9.90039H15C13.3985 9.90019 12.0996 8.6015 12.0996 7V3.90039H8ZM13.9004 7C13.9004 7.60739 14.3927 8.09941 15 8.09961H17.8213C17.8068 8.08333 17.7928 8.06626 17.7773 8.05078L13.9492 4.22266C13.9335 4.20696 13.9169 4.19237 13.9004 4.17773V7Z" fill="currentColor"/> -</svg> -`,l3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M9.2373 3.7002C10.4169 3.7002 11.5297 4.24779 12.249 5.18262L12.4424 5.43359H18C20.0987 5.43359 21.7998 7.13472 21.7998 9.2334V16.5C21.7998 18.5987 20.0987 20.2998 18 20.2998H6C3.90132 20.2998 2.2002 18.5987 2.2002 16.5V7.5C2.2002 5.40132 3.90132 3.7002 6 3.7002H9.2373ZM6 5.5C4.89543 5.5 4 6.39543 4 7.5V16.5C4 17.6046 4.89543 18.5 6 18.5H18C19.0357 18.5 19.887 17.7128 19.9893 16.7041L20 16.5V9.2334C20 8.19775 19.2128 7.34641 18.2041 7.24414L18 7.2334H12.0479L11.9326 7.22656C11.666 7.19561 11.4205 7.05812 11.2549 6.84277L10.8223 6.28027C10.4437 5.78834 9.85808 5.5 9.2373 5.5H6ZM16 9.59961C16.4971 9.59961 16.9004 10.0029 16.9004 10.5C16.9004 10.9971 16.4971 11.4004 16 11.4004H8C7.50294 11.4004 7.09961 10.9971 7.09961 10.5C7.09961 10.0029 7.50294 9.59961 8 9.59961H16Z" fill="currentColor"/> -</svg> -`,vR=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<g> -<path d="M18.3623 9.99976L18.209 8.48999C18.2031 8.43161 18.2004 8.37289 18.2002 8.31421C18.1988 8.31196 18.1956 8.30842 18.1904 8.30347C18.1718 8.28559 18.1302 8.26245 18.0713 8.26245H11C10.261 8.26245 9.59753 7.81016 9.32617 7.1228L8.9082 6.06421C8.88101 5.9953 8.85737 5.92501 8.83887 5.85327C8.83778 5.85099 8.833 5.84268 8.81836 5.83179C8.79454 5.81475 8.7549 5.79939 8.70605 5.80054H3.92871C3.86986 5.80054 3.82825 5.82368 3.80957 5.84155C3.80816 5.8429 3.80675 5.84428 3.80566 5.84546L4.47559 14.0955L3.62109 17.5154L5.12109 11.5154C5.34367 10.6251 6.1438 9.99977 7.06152 9.99976H18.3623ZM7.06152 11.7996C6.96976 11.7996 6.88944 11.8629 6.86719 11.9519L5.36719 17.9519C5.33598 18.078 5.43158 18.1999 5.56152 18.2H19.4385C19.5302 18.1999 19.6106 18.1376 19.6328 18.0486L21.1328 12.0486C21.1644 11.9224 21.0686 11.7996 20.9385 11.7996H7.06152ZM20.9385 9.99976C22.2396 9.99977 23.1945 11.2228 22.8789 12.4851L21.3789 18.4851C21.1563 19.3754 20.3562 19.9997 19.4385 19.9998H4.92871C4.41722 19.9998 3.92613 19.8059 3.56445 19.4597C3.20281 19.1135 3.00004 18.6436 3 18.1541L2 5.84644C2.00006 5.35711 2.20311 4.88786 2.56445 4.54175C2.92613 4.19554 3.41722 4.00073 3.92871 4.00073H8.66406C9.10133 3.99051 9.5296 4.1225 9.87793 4.37573C10.2285 4.63118 10.4767 4.99457 10.582 5.40405L11 6.46167H18.0713C18.5828 6.46167 19.0739 6.65648 19.4355 7.00269C19.7971 7.34888 20 7.81883 20 8.30835L20.1719 9.99976H20.9385Z" fill="currentColor"/> -</g> -</svg> -`,a3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M9.5 3Q10.8 8.2 16 9.5Q10.8 10.8 9.5 16Q8.2 10.8 3 9.5Q8.2 8.2 9.5 3Z" fill="currentColor"/> -<path d="M17.25 13.5Q18 16.5 21 17.25Q18 18 17.25 21Q16.5 18 13.5 17.25Q16.5 16.5 17.25 13.5Z" fill="currentColor"/> -</svg> -`,u3e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path id="af-p0" d="M -2.619 -8.3 C -1.815 -8.3 -1.048 -7.97 -0.499 -7.39 C -0.499 -7.39 0.141 -6.712 0.141 -6.712 C 0.141 -6.712 5.75 -6.712 5.75 -6.712 C 7.904 -6.712 9.65 -4.986 9.65 -2.858 C 9.65 -2.858 9.65 -1.71 9.65 -1.71 C 9.65 -1.219 9.247 -0.821 8.75 -0.821 C 8.253 -0.821 7.85 -1.219 7.85 -1.71 C 7.85 -1.71 7.85 -2.858 7.85 -2.858 C 7.849 -4.004 6.91 -4.934 5.75 -4.934 C 5.75 -4.934 -0.207 -4.934 -0.207 -4.934 C -0.484 -4.934 -0.749 -5.047 -0.938 -5.247 C -0.938 -5.247 -1.815 -6.177 -1.815 -6.177 C -2.023 -6.397 -2.315 -6.521 -2.619 -6.521 C -2.619 -6.521 -6.25 -6.521 -6.25 -6.521 C -7.41 -6.521 -8.35 -5.592 -8.35 -4.446 C -8.35 -4.446 -8.35 4.446 -8.35 4.446 C -8.35 5.592 -7.41 6.521 -6.25 6.521 C -6.25 6.521 1.25 6.521 1.25 6.521 C 1.747 6.521 2.15 6.919 2.15 7.41 C 2.15 7.901 1.747 8.3 1.25 8.3 C 1.25 8.3 -6.25 8.3 -6.25 8.3 C -8.404 8.3 -10.15 6.574 -10.15 4.446 C -10.15 4.446 -10.15 -4.446 -10.15 -4.446 C -10.15 -6.574 -8.404 -8.3 -6.25 -8.3 C -6.25 -8.3 -2.619 -8.3 -2.619 -8.3 Z M 3.75 -2.5 C 4.247 -2.5 4.65 -2.097 4.65 -1.6 C 4.65 -1.103 4.247 -0.699 3.75 -0.699 C 3.75 -0.699 -4.25 -0.699 -4.25 -0.699 C -4.747 -0.699 -5.15 -1.103 -5.15 -1.6 C -5.15 -2.097 -4.747 -2.5 -4.25 -2.5 C -4.25 -2.5 3.75 -2.5 3.75 -2.5 Z" transform="matrix(1 0 0 1 11.75 12)" fill="currentColor"/> - <g id="af-p1"> - <path d="M 2.635 0 L -2.635 0 M 0 -2.635 L 0 2.635" transform="matrix(1 0 0 1 18.4 16.3)" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/> - </g> -</svg> -`,c3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 3C16.9706 3 21 7.02944 21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3ZM12 19.2002C15.9764 19.2002 19.2002 15.9764 19.2002 12C19.2002 8.02355 15.9764 4.7998 12 4.7998V19.2002Z" fill="currentColor"/> -</svg> -`,d3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7ZM12 15.6992C12.4968 15.6992 12.8994 16.1028 12.8994 16.5996C12.8994 17.0964 12.4968 17.5 12 17.5C11.5024 17.5 11.0996 17.0964 11.0996 16.5996C11.0996 16.1028 11.5024 15.6992 12 15.6992ZM12 6.49902C12.4969 6.49922 12.8994 6.86908 12.8994 7.3252V13.6729C12.8994 14.129 12.4969 14.4988 12 14.499C11.5029 14.499 11.0996 14.1291 11.0996 13.6729V7.3252C11.0996 6.86896 11.5029 6.49902 12 6.49902Z" fill="currentColor"/> -</svg> -`,f3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12.5092 2.11279C17.7402 2.37781 21.8998 6.70364 21.8998 12.0005C21.8996 17.4153 17.5524 21.8108 12.1576 21.895C12.1056 21.898 12.0532 21.8999 12.0004 21.8999C11.948 21.8999 11.8954 21.8968 11.8432 21.896L11.8422 21.895C6.44751 21.8107 2.10022 17.4152 2.10001 12.0005C2.10001 6.53287 6.53278 2.1001 12.0004 2.1001L12.5092 2.11279ZM8.92715 13.0005C9.02896 14.9787 9.42581 16.721 9.99356 17.9985C10.3249 18.7441 10.6971 19.292 11.0639 19.6411C11.4259 19.9855 11.741 20.1001 12.0004 20.1001C12.2598 20.1 12.5749 19.9856 12.9369 19.6411C13.3037 19.292 13.6749 18.7441 14.0063 17.9985C14.574 16.721 14.9718 14.9788 15.0736 13.0005H8.92715ZM3.96329 13.0005C4.31462 15.8522 6.14714 18.2427 8.66837 19.3823C8.55544 19.1733 8.44916 18.9552 8.34903 18.73C7.66574 17.1926 7.22657 15.1926 7.12344 13.0005H3.96329ZM16.8764 13.0005C16.7732 15.1926 16.3341 17.1926 15.6508 18.73C15.5506 18.9554 15.4435 19.1732 15.3305 19.3823C17.8522 18.2429 19.6851 15.8525 20.0365 13.0005H16.8764ZM8.66934 4.6167C6.08869 5.78266 4.22826 8.25964 3.93985 11.1997H7.11661C7.20176 8.92954 7.64512 6.85497 8.34903 5.271C8.4494 5.04516 8.5561 4.82619 8.66934 4.6167ZM12.0004 3.8999C11.7411 3.8999 11.4259 4.01454 11.0639 4.35889C10.6971 4.70797 10.3249 5.25587 9.99356 6.00146C9.40671 7.32188 9.00186 9.13885 8.91739 11.1997H15.0834C14.9989 9.13884 14.5931 7.32189 14.0063 6.00146C13.6749 5.2559 13.3037 4.70796 12.9369 4.35889C12.5749 4.0144 12.2598 3.90002 12.0004 3.8999ZM15.3295 4.61572C15.443 4.82559 15.5502 5.04471 15.6508 5.271C16.3547 6.85498 16.799 8.92949 16.8842 11.1997H20.06C19.7715 8.25914 17.9108 5.78143 15.3295 4.61572Z" fill="currentColor"/> -</svg> -`,h3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M8 17C8.82834 17 9.5 17.6717 9.5 18.5C9.5 19.3283 8.82834 20 8 20C7.17166 20 6.5 19.3283 6.5 18.5C6.5 17.6717 7.17166 17 8 17ZM16 17C16.8283 17 17.5 17.6717 17.5 18.5C17.5 19.3283 16.8283 20 16 20C15.1717 20 14.5 19.3283 14.5 18.5C14.5 17.6717 15.1717 17 16 17ZM8 10.5C8.82834 10.5 9.5 11.1717 9.5 12C9.5 12.8283 8.82834 13.5 8 13.5C7.17166 13.5 6.5 12.8283 6.5 12C6.5 11.1717 7.17166 10.5 8 10.5ZM16 10.5C16.8283 10.5 17.5 11.1717 17.5 12C17.5 12.8283 16.8283 13.5 16 13.5C15.1717 13.5 14.5 12.8283 14.5 12C14.5 11.1717 15.1717 10.5 16 10.5ZM8 4C8.82834 4 9.5 4.67166 9.5 5.5C9.5 6.32834 8.82834 7 8 7C7.17166 7 6.5 6.32834 6.5 5.5C6.5 4.67166 7.17166 4 8 4ZM16 4C16.8283 4 17.5 4.67166 17.5 5.5C17.5 6.32834 16.8283 7 16 7C15.1717 7 14.5 6.32834 14.5 5.5C14.5 4.67166 15.1717 4 16 4Z" fill="currentColor"/> -</svg> -`,p3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M7.22264 6.10352C7.22264 5.5078 7.48259 4.95449 7.91405 4.56055C8.34271 4.16918 8.90831 3.96198 9.48241 3.96191C9.64155 3.96191 9.80001 3.97936 9.95507 4.01074C10.0127 3.5042 10.2586 3.04178 10.6338 2.69922C11.0625 2.30778 11.6279 2.09961 12.2021 2.09961C12.7763 2.09966 13.3418 2.30783 13.7705 2.69922C13.9947 2.90401 14.1709 3.15244 14.29 3.42676C14.4947 3.37044 14.7071 3.34182 14.9209 3.3418C15.4951 3.3418 16.0605 3.549 16.4892 3.94043C16.8644 4.28293 17.1093 4.74548 17.167 5.25195C17.3223 5.22045 17.4812 5.20312 17.6406 5.20312C18.2147 5.20318 18.7803 5.41135 19.209 5.80273C19.6402 6.19663 19.9004 6.74922 19.9004 7.34473V14.6543C19.9004 17.413 19.2914 19.0434 18.0137 20.21C16.82 21.2998 15.2175 21.9004 13.5615 21.9004C11.7538 21.9004 10.2315 21.5696 8.95702 20.8535C7.67664 20.1341 6.71683 19.0652 5.97362 17.708L3.3496 12.916C3.18848 12.6213 3.10112 12.2914 3.0996 11.9531C3.09812 11.6147 3.18309 11.2835 3.34179 10.9873C3.5001 10.692 3.72639 10.4416 3.99706 10.251C4.26771 10.0604 4.57776 9.93235 4.90136 9.87305C5.56617 9.75102 6.25934 9.84517 6.86425 10.1445C6.9942 10.2088 7.11461 10.2788 7.22264 10.3477V6.10352ZM9.02343 12.7969C9.02336 13.1912 8.76624 13.5395 8.38964 13.6562C8.0129 13.773 7.60387 13.6309 7.38085 13.3057L6.53514 12.0723C6.51218 12.0529 6.48411 12.0282 6.45018 12.002C6.34595 11.9213 6.20986 11.8289 6.06639 11.7578C5.81525 11.6335 5.51637 11.5904 5.22655 11.6436H5.22557C5.15055 11.6573 5.08558 11.6865 5.03417 11.7227C4.98289 11.7588 4.94815 11.7998 4.92772 11.8379C4.90762 11.8755 4.90023 11.9122 4.90038 11.9453C4.90057 11.9782 4.9084 12.0144 4.9287 12.0518L7.55272 16.8438C8.16912 17.9693 8.90989 18.7622 9.83886 19.2842C10.7737 19.8094 11.9704 20.0996 13.5615 20.0996C14.7902 20.0996 15.9536 19.6533 16.7998 18.8809C17.5619 18.185 18.0996 17.1383 18.0996 14.6543V7.34473C18.0996 7.28204 18.0734 7.20342 17.9951 7.13184C17.9139 7.05771 17.7875 7.00396 17.6406 7.00391C17.4937 7.00391 17.3674 7.05771 17.2861 7.13184C17.2077 7.20347 17.1807 7.28199 17.1807 7.34473V11.0693C17.1805 11.5661 16.778 11.9685 16.2812 11.9688C15.7843 11.9688 15.381 11.5662 15.3808 11.0693V5.48242C15.3808 5.41973 15.3537 5.34107 15.2754 5.26953C15.1941 5.19547 15.0677 5.1416 14.9209 5.1416C14.774 5.14166 14.6476 5.19541 14.5664 5.26953C14.4881 5.34105 14.462 5.41974 14.4619 5.48242V11.0693C14.4617 11.5662 14.0584 11.9688 13.5615 11.9688C13.0646 11.9687 12.6613 11.5662 12.6611 11.0693V4.24121C12.6611 4.17852 12.635 4.09989 12.5566 4.02832C12.4754 3.95419 12.349 3.90045 12.2021 3.90039C12.0552 3.90039 11.9289 3.95421 11.8476 4.02832C11.7692 4.09992 11.7422 4.17849 11.7422 4.24121V11.0693C11.742 11.5661 11.3395 11.9685 10.8428 11.9688C10.3458 11.9688 9.94257 11.5662 9.94237 11.0693V6.10352L9.93651 6.05371C9.92534 6.00177 9.89573 5.94433 9.8369 5.89062C9.75567 5.81647 9.62938 5.76172 9.48241 5.76172C9.33554 5.76179 9.2091 5.81651 9.12792 5.89062C9.04964 5.96222 9.02343 6.04084 9.02343 6.10352V12.7969Z" fill="currentColor"/> -</svg> -`,g3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M4 3.33203C4.55224 3.33203 4.99993 3.7798 5 4.33203V18.0908H20.0674C20.6195 18.0908 21.0671 18.5388 21.0674 19.0908C21.0674 19.6431 20.6197 20.0908 20.0674 20.0908H5C3.89543 20.0908 3 19.1954 3 18.0908V4.33203C3.00007 3.7798 3.44776 3.33203 4 3.33203ZM8.19922 9.28418C8.7515 9.28418 9.19922 9.73189 9.19922 10.2842V15.6045C9.19908 16.1567 8.75142 16.6045 8.19922 16.6045C7.64719 16.6043 7.19936 16.1565 7.19922 15.6045V10.2842C7.19922 9.73202 7.6471 9.28438 8.19922 9.28418ZM17.2227 6.85645C17.7748 6.85658 18.2226 7.3043 18.2227 7.85645V15.6045C18.2225 16.1566 17.7747 16.6044 17.2227 16.6045C16.6705 16.6045 16.2228 16.1566 16.2227 15.6045V7.85645C16.2227 7.30422 16.6704 6.85645 17.2227 6.85645ZM12.7109 3.96387C13.2631 3.96387 13.7107 4.41175 13.7109 4.96387V15.6035C13.7109 16.1558 13.2632 16.6035 12.7109 16.6035C12.1587 16.6035 11.7109 16.1558 11.7109 15.6035V4.96387C11.7111 4.41175 12.1588 3.96387 12.7109 3.96387Z" fill="currentColor"/> -</svg> -`,m3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M8.00916 7.50488C8.47326 7.50488 8.91828 7.68943 9.24646 8.01758C9.57465 8.34577 9.75916 8.79075 9.75916 9.25488C9.75916 9.71901 9.57465 10.164 9.24646 10.4922C8.91828 10.8203 8.47326 11.0049 8.00916 11.0049C7.54507 11.0049 7.10001 10.8203 6.77185 10.4922C6.4437 10.164 6.25916 9.71898 6.25916 9.25488C6.25916 8.79078 6.4437 8.34576 6.77185 8.01758C7.10001 7.68942 7.54507 7.50492 8.00916 7.50488Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M17.8998 4.09961C20.0537 4.09961 21.8002 5.84609 21.8002 8V16C21.8002 18.1539 20.0537 19.9004 17.8998 19.9004H5.89978C3.74598 19.9003 1.99939 18.1538 1.99939 16V8C1.99939 5.84617 3.74598 4.09974 5.89978 4.09961H17.8998ZM15.4867 12.2539C15.448 12.2184 15.3885 12.2192 15.351 12.2559L11.7338 15.8027C11.0146 16.5079 9.87305 16.5222 9.13708 15.835L6.98669 13.8262C6.95049 13.7924 6.89516 13.791 6.85681 13.8223L3.82361 16.2988C3.96873 17.3168 4.84165 18.0995 5.89978 18.0996H17.8998C18.9375 18.0996 19.7964 17.3466 19.9662 16.3574L15.4867 12.2539ZM5.89978 5.90039C4.74009 5.90052 3.80017 6.84028 3.80017 8V14.002L5.73181 12.4238C6.46046 11.8286 7.51253 11.8634 8.20056 12.5059L10.351 14.5146C10.3897 14.5508 10.4498 14.5497 10.4877 14.5127L14.1049 10.9658C14.819 10.2656 15.9506 10.2466 16.6879 10.9219L19.9994 13.9551V8C19.9994 6.8402 19.0596 5.90039 17.8998 5.90039H5.89978Z" fill="currentColor"/> -</svg> -`,v3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M5.09375 2.81174C5.4825 2.50796 6.04376 2.56488 6.34766 2.93869L20.1855 19.9602C20.4895 20.3341 20.421 20.8836 20.0322 21.1877C19.6435 21.4917 19.0823 21.4355 18.7783 21.0617L17.9971 20.1008H5.99609C3.84224 20.1008 2.0958 18.3552 2.0957 16.2014V8.13889C2.09589 6.26755 3.41429 4.70428 5.17285 4.32639L4.93945 4.03928C4.63577 3.66536 4.7051 3.11573 5.09375 2.81174ZM7.13184 14.1096C7.09416 14.0738 7.03659 14.0713 6.99609 14.1037L3.92871 16.5569C4.09761 17.5472 4.95753 18.301 5.99609 18.301H16.5342L13.373 14.4133L11.9072 15.9455C11.1531 16.7324 9.92202 16.7621 9.13281 16.0119L7.13184 14.1096ZM5.99609 6.03928C4.83643 6.03928 3.89669 6.97927 3.89648 8.13889V14.1408L5.83496 12.5901C6.60469 11.9742 7.69929 12.022 8.41504 12.7024L10.416 14.6037C10.4575 14.6431 10.5218 14.642 10.5615 14.6008L12.1641 12.926L9.78906 10.0051C9.70282 10.2646 9.55682 10.5038 9.35645 10.7004C9.02202 11.0285 8.56767 11.2131 8.09473 11.2131C7.62195 11.213 7.1683 11.0284 6.83398 10.7004C6.49961 10.3724 6.31152 9.92701 6.31152 9.46311C6.3116 8.99941 6.49981 8.55474 6.83398 8.22678C7.12986 7.93654 7.51931 7.75901 7.93262 7.7219L6.56543 6.03928H5.99609Z" fill="currentColor"/> -<path d="M18.0049 4.31272C20.1587 4.31288 21.9043 6.0593 21.9043 8.21311V13.718C21.9039 15.4743 19.7248 16.2906 18.5713 14.966L14.9141 10.7658C14.5882 10.3912 14.6278 9.82271 15.002 9.49631C15.3768 9.16994 15.9451 9.20948 16.2715 9.5842L19.9287 13.7844C19.9528 13.812 19.9696 13.8167 19.9775 13.8186C19.9908 13.8216 20.0141 13.8213 20.04 13.8117C20.0655 13.8021 20.0826 13.7875 20.0908 13.7766C20.0955 13.7702 20.1044 13.7552 20.1045 13.718V8.21311C20.1045 7.05341 19.1645 6.11366 18.0049 6.1135H10.6328C10.1361 6.11327 9.73267 5.70981 9.73242 5.21311C9.73242 4.71619 10.136 4.31295 10.6328 4.31272H18.0049Z" fill="currentColor"/> -</svg> -`,y3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 2.1001C17.4676 2.10031 21.8994 6.53286 21.8994 12.0005C21.8992 17.4679 17.4674 21.8997 12 21.8999C6.53237 21.8999 2.09982 17.4681 2.09961 12.0005C2.09961 6.53273 6.53224 2.1001 12 2.1001ZM12 3.8999C7.52636 3.8999 3.89941 7.52684 3.89941 12.0005C3.89963 16.474 7.52649 20.1001 12 20.1001C16.4733 20.0999 20.0994 16.4738 20.0996 12.0005C20.0996 7.52697 16.4735 3.90011 12 3.8999ZM12 9.50049C12.4969 9.50068 12.8994 9.87055 12.8994 10.3267V16.6743C12.8992 17.1303 12.4968 17.5003 12 17.5005C11.503 17.5005 11.0998 17.1304 11.0996 16.6743V10.3267C11.0996 9.87043 11.5029 9.50049 12 9.50049ZM12 6.49951C12.4968 6.49951 12.8994 6.90313 12.8994 7.3999C12.8992 7.8965 12.4966 8.30029 12 8.30029C11.5025 8.30028 11.0998 7.8965 11.0996 7.3999C11.0996 6.90313 11.5024 6.49952 12 6.49951Z" fill="currentColor"/> -</svg> -`,k3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2.09998C6.53222 2.09998 2.09998 6.53222 2.09998 12C2.09998 17.4677 6.53222 21.9 12 21.9C17.4677 21.9 21.9 17.4677 21.9 12C21.9 6.53222 17.4677 2.09998 12 2.09998ZM3.89998 12C3.89998 7.52633 7.52633 3.89998 12 3.89998C16.4736 3.89998 20.1 7.52633 20.1 12C20.1 16.4736 16.4736 20.1 12 20.1C7.52633 20.1 3.89998 16.4736 3.89998 12Z" fill="currentColor"/> -<path d="M9.4286 9.47153C9.4286 8.97448 9.83154 8.57153 10.3286 8.57153H11.1C11.5971 8.57153 12 8.97448 12 9.47153C12 9.96859 11.5971 10.3715 11.1 10.3715H10.3286C9.83154 10.3715 9.4286 9.96859 9.4286 9.47153Z" fill="currentColor"/> -<path d="M5.14289 9.47155C5.14289 8.97449 5.54583 8.57155 6.04289 8.57155H7.67146C8.16851 8.57155 8.57146 8.97449 8.57146 9.47155C8.57146 9.9686 8.16851 10.3715 7.67146 10.3715H6.04289C5.54583 10.3715 5.14289 9.9686 5.14289 9.47155Z" fill="currentColor"/> -<path d="M8.57146 16.3287C8.57146 15.8316 8.9744 15.4287 9.47145 15.4287H14.5286C15.0257 15.4287 15.4286 15.8316 15.4286 16.3287C15.4286 16.8257 15.0257 17.2287 14.5286 17.2287H9.47145C8.9744 17.2287 8.57146 16.8257 8.57146 16.3287Z" fill="currentColor"/> -<path d="M6.04288 12.0001C5.54583 12.0001 5.14288 12.403 5.14288 12.9001C5.14288 13.3972 5.54583 13.8001 6.04288 13.8001H6.81431C7.31137 13.8001 7.71431 13.3972 7.71431 12.9001C7.71431 12.403 7.31137 12.0001 6.81431 12.0001H6.04288Z" fill="currentColor"/> -<path d="M9.47145 12.0001C8.9744 12.0001 8.57146 12.403 8.57146 12.9001C8.57146 13.3972 8.9744 13.8001 9.47146 13.8001H10.2429C10.7399 13.8001 11.1429 13.3972 11.1429 12.9001C11.1429 12.403 10.7399 12.0001 10.2429 12.0001H9.47145Z" fill="currentColor"/> -<path d="M12.8572 9.47153C12.8572 8.97448 13.2601 8.57153 13.7572 8.57153H14.5286C15.0257 8.57153 15.4286 8.97448 15.4286 9.47153C15.4286 9.96859 15.0257 10.3715 14.5286 10.3715H13.7572C13.2601 10.3715 12.8572 9.96859 12.8572 9.47153Z" fill="currentColor"/> -<path d="M12.9 12.0001C12.403 12.0001 12 12.403 12 12.9001C12 13.3972 12.403 13.8001 12.9 13.8001H13.6715C14.1685 13.8001 14.5715 13.3972 14.5715 12.9001C14.5715 12.403 14.1685 12.0001 13.6715 12.0001H12.9Z" fill="currentColor"/> -<path d="M16.2857 9.47153C16.2857 8.97448 16.6887 8.57153 17.1857 8.57153H17.9572C18.4542 8.57153 18.8572 8.97448 18.8572 9.47153C18.8572 9.96859 18.4542 10.3715 17.9572 10.3715H17.1857C16.6887 10.3715 16.2857 9.96859 16.2857 9.47153Z" fill="currentColor"/> -<path d="M16.3286 12.0001C15.8315 12.0001 15.4286 12.403 15.4286 12.9001C15.4286 13.3972 15.8315 13.8001 16.3286 13.8001H17.9572C18.4542 13.8001 18.8572 13.3972 18.8572 12.9001C18.8572 12.403 18.4542 12.0001 17.9572 12.0001H16.3286Z" fill="currentColor"/> -</svg> -`,b3e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path id="bar-divider" d="M 9.3 18.951 L 9.3 4.3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> - <path id="bar-box" d="M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="butt" stroke-linejoin="miter" transform="matrix(1 0 0 1 11.8 11.8)"/> - <path id="bar-arrow" d="M -1.25 -2.5 L 1.25 0 L -1.25 2.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> -</svg> -`,A3e=`<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path id="bar-divider" d="M 9.3 18.951 L 9.3 4.3" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> - <path id="bar-box" d="M -7.9 -4.8 C -7.9 -6.512 -6.512 -7.9 -4.8 -7.9 L 4.8 -7.9 C 6.512 -7.9 7.9 -6.512 7.9 -4.8 L 7.9 4.8 C 7.9 6.512 6.512 7.9 4.8 7.9 L -4.8 7.9 C -6.512 7.9 -7.9 6.512 -7.9 4.8 L -7.9 -4.8 Z" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="butt" stroke-linejoin="miter" transform="matrix(1 0 0 1 11.8 11.8)"/> - <path id="bar-arrow-expand" d="M -1.25 -2.5 L 1.25 0 L -1.25 2.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/> -</svg> -`,C3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<g> -<path d="M12.9 1.7999C12.9 1.30285 12.4971 0.899902 12 0.899902C11.5029 0.899902 11.1 1.30285 11.1 1.7999V2.7999C11.1 3.29696 11.5029 3.6999 12 3.6999C12.4971 3.6999 12.9 3.29696 12.9 2.7999V1.7999Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M6.1 11.9999C6.1 8.7414 8.74152 6.09988 12 6.09988C15.2585 6.09988 17.9 8.7414 17.9 11.9999C17.9 15.2584 15.2585 17.8999 12 17.8999C8.74152 17.8999 6.1 15.2584 6.1 11.9999ZM12 7.89988C9.73563 7.89988 7.9 9.73551 7.9 11.9999C7.9 14.2642 9.73563 16.0999 12 16.0999C14.2644 16.0999 16.1 14.2642 16.1 11.9999C16.1 9.73551 14.2644 7.89988 12 7.89988Z" fill="currentColor"/> -<path d="M0.899994 11.9999C0.899994 11.5028 1.30294 11.0999 1.79999 11.0999H2.79999C3.29705 11.0999 3.69999 11.5028 3.69999 11.9999C3.69999 12.4969 3.29705 12.8999 2.79999 12.8999H1.79999C1.30294 12.8999 0.899994 12.4969 0.899994 11.9999Z" fill="currentColor"/> -<path d="M12 20.2991C12.4971 20.2991 12.9 20.702 12.9 21.1991V22.1991C12.9 22.6961 12.4971 23.0991 12 23.0991C11.5029 23.0991 11.1 22.6961 11.1 22.1991V21.1991C11.1 20.702 11.5029 20.2991 12 20.2991Z" fill="currentColor"/> -<path d="M21.2016 11.0999C20.7045 11.0999 20.3016 11.5028 20.3016 11.9999C20.3016 12.4969 20.7045 12.8999 21.2016 12.8999H22.2016C22.6986 12.8999 23.1016 12.4969 23.1016 11.9999C23.1016 11.5028 22.6986 11.0999 22.2016 11.0999H21.2016Z" fill="currentColor"/> -<path d="M20.1995 3.79903C20.551 4.1505 20.551 4.72035 20.1995 5.07182L19.4924 5.77893C19.141 6.1304 18.5711 6.1304 18.2196 5.77893C17.8682 5.42746 17.8682 4.85761 18.2196 4.50614L18.9268 3.79903C19.2782 3.44756 19.8481 3.44756 20.1995 3.79903Z" fill="currentColor"/> -<path d="M19.4942 18.2215C19.1427 17.87 18.5729 17.87 18.2214 18.2215C17.87 18.573 17.87 19.1428 18.2214 19.4943L18.9285 20.2014C19.28 20.5529 19.8498 20.5529 20.2013 20.2014C20.5528 19.8499 20.5528 19.2801 20.2013 18.9286L19.4942 18.2215Z" fill="currentColor"/> -<path d="M5.78079 18.2213C6.13227 18.5727 6.13227 19.1426 5.78079 19.4941L5.07369 20.2012C4.72222 20.5526 4.15237 20.5526 3.8009 20.2012C3.44942 19.8497 3.44942 19.2798 3.8009 18.9284L4.508 18.2213C4.85947 17.8698 5.42932 17.8698 5.78079 18.2213Z" fill="currentColor"/> -<path d="M5.07077 3.79912C4.7193 3.44764 4.14945 3.44764 3.79798 3.79912C3.4465 4.15059 3.4465 4.72044 3.79798 5.07191L4.50508 5.77901C4.85655 6.13049 5.4264 6.13049 5.77787 5.77902C6.12935 5.42754 6.12935 4.85769 5.77787 4.50622L5.07077 3.79912Z" fill="currentColor"/> -</g> -</svg> -`,w3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M3.97427 8.06961C4.99348 7.33581 6.18946 7.1 7.00001 7.1H9.00001C9.49706 7.1 9.90001 7.50294 9.90001 8C9.90001 8.49706 9.49706 8.9 9.00001 8.9H7.00001C6.47755 8.9 5.67353 9.06419 5.02599 9.53039C4.42434 9.96356 3.90001 10.6934 3.90001 12C3.90001 13.3066 4.42434 14.0364 5.02599 14.4696C5.67353 14.9358 6.47755 15.1 7.00001 15.1H9.00001C9.49706 15.1 9.90001 15.5029 9.90001 16C9.90001 16.4971 9.49706 16.9 9.00001 16.9H7.00001C6.18946 16.9 4.99348 16.6642 3.97427 15.9304C2.90917 15.1636 2.10001 13.8934 2.10001 12C2.10001 10.1066 2.90917 8.83644 3.97427 8.06961ZM14.1 8C14.1 7.50294 14.5029 7.1 15 7.1H17C17.8105 7.1 19.0065 7.33581 20.0257 8.06961C21.0908 8.83644 21.9 10.1066 21.9 12C21.9 13.8934 21.0908 15.1636 20.0257 15.9304C19.0065 16.6642 17.8105 16.9 17 16.9H15C14.5029 16.9 14.1 16.4971 14.1 16C14.1 15.5029 14.5029 15.1 15 15.1H17C17.5225 15.1 18.3265 14.9358 18.974 14.4696C19.5757 14.0364 20.1 13.3066 20.1 12C20.1 10.6934 19.5757 9.96356 18.974 9.53039C18.3265 9.06419 17.5225 8.9 17 8.9H15C14.5029 8.9 14.1 8.49706 14.1 8ZM7.10001 12C7.10001 11.5029 7.50295 11.1 8.00001 11.1H16C16.4971 11.1 16.9 11.5029 16.9 12C16.9 12.4971 16.4971 12.9 16 12.9H8.00001C7.50295 12.9 7.10001 12.4971 7.10001 12Z" fill="currentColor"/> -</svg> -`,x3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M4.10001 5.99998C4.10001 5.50292 4.50295 5.09998 5.00001 5.09998H19C19.4971 5.09998 19.9 5.50292 19.9 5.99998C19.9 6.49703 19.4971 6.89998 19 6.89998H5.00001C4.50295 6.89998 4.10001 6.49703 4.10001 5.99998ZM4.10001 12C4.10001 11.5029 4.50295 11.1 5.00001 11.1H19C19.4971 11.1 19.9 11.5029 19.9 12C19.9 12.497 19.4971 12.9 19 12.9H5.00001C4.50295 12.9 4.10001 12.497 4.10001 12ZM4.10001 18C4.10001 17.5029 4.50295 17.1 5.00001 17.1H19C19.4971 17.1 19.9 17.5029 19.9 18C19.9 18.497 19.4971 18.9 19 18.9H5.00001C4.50295 18.9 4.10001 18.497 4.10001 18Z" fill="currentColor"/> -</svg> -`,S3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<g> -<path fill-rule="evenodd" clip-rule="evenodd" d="M18 4.09961C20.1539 4.09961 21.9004 5.84609 21.9004 8V16C21.9004 18.1539 20.1539 19.9004 18 19.9004H6C3.84609 19.9004 2.09961 18.1539 2.09961 16V8C2.09961 5.84609 3.84609 4.09961 6 4.09961H18ZM3.90039 16C3.90039 17.1598 4.8402 18.0996 6 18.0996H18C19.1598 18.0996 20.0996 17.1598 20.0996 16V9.49805L13.5361 13.5361C12.5955 14.1147 11.4075 14.1084 10.4727 13.5205L3.90039 9.38672V16ZM6 5.90039C5.0746 5.90039 4.29039 6.49909 4.01074 7.33008L11.4316 11.9971C11.7861 12.2199 12.2361 12.2222 12.5928 12.0029L20.0195 7.43457C19.7725 6.54993 18.9636 5.90039 18 5.90039H6Z" fill="currentColor"/> -</g> -</svg> -`,_3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M17 11.0996C17.4971 11.0996 17.9004 11.5029 17.9004 12C17.9004 12.4971 17.4971 12.9004 17 12.9004H7C6.50294 12.9004 6.09961 12.4971 6.09961 12C6.09961 11.5029 6.50294 11.0996 7 11.0996H17Z" fill="currentColor"/> -</svg> -`,M3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M15.182 3.32802C15.9304 2.72235 17.0309 2.76978 17.724 3.46767L18.5424 4.29189L18.6722 4.43642C19.2377 5.13495 19.234 6.1404 18.6635 6.83486L18.5326 6.97841L18.0248 7.48232C17.9549 7.55172 17.8793 7.61254 17.8021 7.66884C17.9794 8.18027 17.9316 8.7498 17.6595 9.22841C17.6847 9.24522 17.7091 9.2635 17.7328 9.2831L17.8002 9.3456L17.9847 9.53798C19.8515 11.5442 20.4549 14.0022 19.6224 16.2196C19.1921 17.3657 18.4025 18.3827 17.2992 19.203H19.0873L19.1801 19.2079C19.6337 19.2542 19.9877 19.6375 19.9877 20.1034C19.9876 20.5692 19.6337 20.9527 19.1801 20.9989L19.0873 21.0028H13.0385C13.0244 21.0033 13.0104 21.0031 12.9965 21.0028H4.9115C4.41448 21.0028 4.01117 20.6004 4.01111 20.1034C4.01111 19.6064 4.41444 19.203 4.9115 19.203H12.9047C15.7614 18.5471 17.3679 17.1023 17.9369 15.5868C18.4678 14.1726 18.179 12.4782 16.807 10.9188L16.5189 10.6093L16.4574 10.5399C16.4549 10.5368 16.453 10.5333 16.4506 10.5302L12.3011 14.6522C11.6031 15.3454 10.5023 15.3845 9.75818 14.7733L9.61365 14.6425L7.31091 12.3231C6.5717 11.5786 6.57617 10.376 7.32068 9.63662L12.3676 4.62392L12.5121 4.49404C13.0358 4.06988 13.7318 3.96755 14.3402 4.18251C14.3969 4.10597 14.4591 4.03197 14.5287 3.96279L15.0365 3.45791L15.182 3.32802ZM4.83044 12.9335C5.16112 12.6052 5.68305 12.5863 6.03552 12.8759L6.10291 12.9384L9.07361 15.9286L9.13513 15.997C9.42218 16.3514 9.3992 16.8727 9.06873 17.2011C8.7381 17.5294 8.21712 17.5482 7.86462 17.2587L7.79626 17.1972L4.82654 14.2069L4.76501 14.1376C4.47792 13.7831 4.49979 13.2619 4.83044 12.9335ZM13.6693 5.87978L13.6361 5.90126L8.58826 10.914C8.54935 10.9529 8.54943 11.0165 8.58826 11.0556L10.891 13.3739L10.9242 13.3964C10.9602 13.4111 11.0032 13.404 11.0326 13.3749L16.0795 8.3622L16.1019 8.329C16.1117 8.3049 16.1117 8.2779 16.1019 8.2538L16.0804 8.2206L13.7777 5.90224C13.7486 5.87289 13.7054 5.86535 13.6693 5.87978ZM16.3383 4.71376L16.3051 4.73525L15.7972 5.24013C15.7584 5.27904 15.7585 5.34166 15.7972 5.38076L16.6146 6.20498L16.6478 6.22744C16.6838 6.24221 16.7268 6.23487 16.7562 6.20595L17.264 5.70107L17.2865 5.66787C17.2962 5.64382 17.2963 5.61672 17.2865 5.59267L17.265 5.55947L16.4467 4.73623C16.4174 4.70681 16.3744 4.6992 16.3383 4.71376Z" fill="currentColor"/> -</svg> -`,I3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.669 7.94435C11.6812 7.94435 11.6912 7.9546 11.6914 7.96681C11.6914 7.96922 11.6926 7.97233 11.6934 7.97462L14.0908 15.1924C14.1283 15.3052 14.0437 15.4219 13.9248 15.4219H12.709C12.6327 15.4217 12.5655 15.3718 12.543 15.2988L11.9639 13.418C11.9526 13.3814 11.9181 13.3565 11.8799 13.3565H9.1504C9.11222 13.3565 9.07868 13.3815 9.06739 13.418L8.48829 15.2988C8.46577 15.3719 8.39778 15.4219 8.3213 15.4219H7.10548C6.98659 15.4219 6.90296 15.3052 6.94044 15.1924L9.30762 8.06446C9.3313 7.99321 9.39855 7.94435 9.47364 7.94435H11.669ZM9.4961 12.041C9.47878 12.0971 9.52043 12.1543 9.57911 12.1543H11.4512C11.5098 12.1543 11.5525 12.0971 11.5352 12.041L10.6113 9.05177H10.4199L9.4961 12.041Z" fill="currentColor"/> -<path d="M16.0576 7.94435C16.1539 7.94435 16.2324 8.02289 16.2324 8.11915V15.2481C16.2322 15.3441 16.1537 15.4219 16.0576 15.4219H15.0645C14.9683 15.4219 14.8899 15.3441 14.8897 15.2481V8.11915C14.8897 8.02289 14.9682 7.94435 15.0645 7.94435H16.0576Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M12.0534 2.091C12.5082 2.091 12.8766 2.45946 12.8766 2.91425L12.874 3.90821H14.3076L14.3102 2.92499C14.3103 2.47035 14.6788 2.10186 15.1334 2.10175C15.5882 2.10175 15.9566 2.47028 15.9567 2.92499L15.9541 3.90821H17.0293C18.4439 3.90854 19.5908 5.05504 19.5908 6.46974V7.90821L21.0852 7.93105C21.54 7.93105 21.9085 8.29951 21.9085 8.7543C21.9084 9.20899 21.54 9.57754 21.0852 9.57754L19.6074 9.5547C19.6019 9.5547 19.5964 9.55383 19.5908 9.55372V11.0215L21.0852 11.0443C21.54 11.0443 21.9084 11.4129 21.9085 11.8676C21.9085 12.3224 21.54 12.6908 21.0852 12.6908L19.6074 12.668C19.6019 12.668 19.5964 12.6671 19.5908 12.667V14.1016L21.0852 14.1244C21.54 14.1244 21.9084 14.4929 21.9085 14.9477C21.9085 15.4024 21.54 15.7709 21.0852 15.7709L19.6074 15.7481C19.6019 15.7481 19.5964 15.7472 19.5908 15.7471V16.8975C19.5907 18.312 18.4438 19.4587 17.0293 19.459H15.9453L15.9875 21.0863C15.9875 21.5409 15.6189 21.9094 15.1643 21.9095C14.7095 21.9095 14.3411 21.541 14.341 21.0863L14.2988 19.459H12.8311L12.8733 21.0863C12.8732 21.541 12.5048 21.9095 12.05 21.9095C11.5955 21.9093 11.2269 21.5409 11.2268 21.0863L11.1846 19.459H9.75098L9.79319 21.0687C9.79319 21.5235 9.42474 21.8919 8.96995 21.8919C8.51536 21.8917 8.14671 21.5233 8.14671 21.0687L8.1045 19.459H6.75489C5.34008 19.459 4.19352 18.3122 4.19337 16.8975V15.7031L2.90033 15.7353C2.4456 15.7353 2.07709 15.3668 2.07709 14.9121C2.0771 14.4574 2.44561 14.0889 2.90033 14.0889L4.19337 14.0567V12.5899L2.91595 12.6221C2.46128 12.6221 2.09289 12.2535 2.09271 11.7988C2.09271 11.344 2.46116 10.9756 2.91595 10.9756L4.19337 10.9434V9.50978L2.91595 9.54198C2.46126 9.54198 2.09287 9.1734 2.09271 8.71874C2.09271 8.26395 2.46116 7.8955 2.91595 7.8955L4.19337 7.86329V6.46974C4.19337 5.05483 5.33999 3.90821 6.75489 3.90821H8.11427L8.11684 2.91425C8.11684 2.45946 8.48529 2.091 8.94008 2.091C9.39483 2.09105 9.76332 2.45949 9.76332 2.91425L9.76075 3.90821H11.2275L11.2301 2.91425C11.2301 2.45955 11.5987 2.09115 12.0534 2.091ZM6.66114 5.55958C6.19983 5.6065 5.83985 5.99605 5.83985 6.46974V16.8975L5.84473 16.9912C5.88868 17.4216 6.23075 17.7639 6.66114 17.8076L6.75489 17.8125H17.0293L17.1221 17.8076C17.5526 17.764 17.8955 17.4217 17.9395 16.9912L17.9434 16.8975V6.46974C17.9434 5.99595 17.5835 5.60637 17.1221 5.55958L17.0293 5.5547H6.75489L6.66114 5.55958Z" fill="currentColor"/> -</svg> -`,E3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M6 12C6 12.8283 5.32834 13.5 4.5 13.5C3.67166 13.5 3 12.8283 3 12C3 11.1717 3.67166 10.5 4.5 10.5C5.32834 10.5 6 11.1717 6 12Z" fill="currentColor"/> -<path d="M13.5 12C13.5 12.8283 12.8283 13.5 12 13.5C11.1717 13.5 10.5 12.8283 10.5 12C10.5 11.1717 11.1717 10.5 12 10.5C12.8283 10.5 13.5 11.1717 13.5 12Z" fill="currentColor"/> -<path d="M19.5002 13.5C20.3287 13.5 21 12.8287 21 12.0002C21 11.1718 20.3287 10.5 19.5002 10.5C18.6718 10.5 18 11.1718 18 12.0002C18 12.8287 18.6718 13.5 19.5002 13.5Z" fill="currentColor"/> -</svg> -`,T3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M8 12.0993C8.49691 12.0993 8.90016 12.5028 8.90039 12.9997V17.9997C8.90039 19.6013 7.60163 20.9001 6 20.9001C4.39837 20.9001 3.09961 19.6013 3.09961 17.9997C3.09984 16.3982 4.39852 15.0993 6 15.0993C6.38939 15.0993 6.76033 15.1778 7.09961 15.317V12.9997C7.09984 12.5028 7.50309 12.0993 8 12.0993ZM6 16.9001C5.39263 16.9001 4.90062 17.3923 4.90039 17.9997C4.90039 18.6072 5.39249 19.0993 6 19.0993C6.60751 19.0993 7.09961 18.6072 7.09961 17.9997C7.09938 17.3923 6.60737 16.9001 6 16.9001Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M18.627 3.35611C19.8025 3.12106 20.9001 4.02068 20.9004 5.21939V15.9997C20.9004 17.6013 19.6016 18.9001 18 18.9001C16.3984 18.9001 15.0996 17.6013 15.0996 15.9997C15.0998 14.3982 16.3985 13.0993 18 13.0993C18.3894 13.0993 18.7603 13.1778 19.0996 13.317V9.21939C19.0993 9.15657 19.0421 9.10946 18.9805 9.12173L12.6768 10.3825C12.1894 10.4799 11.7148 10.1637 11.6172 9.67642C11.52 9.18922 11.8361 8.71439 12.3232 8.61685L18.627 7.35611C18.7868 7.32415 18.9452 7.31502 19.0996 7.32291V5.21939C19.0993 5.15657 19.0421 5.10946 18.9805 5.12173L12.6768 6.38248C12.1894 6.47994 11.7148 6.16372 11.6172 5.67642C11.52 5.18922 11.8361 4.71439 12.3232 4.61685L18.627 3.35611ZM18 14.9001C17.3926 14.9001 16.9006 15.3923 16.9004 15.9997C16.9004 16.6072 17.3925 17.0993 18 17.0993C18.6075 17.0993 19.0996 16.6072 19.0996 15.9997C19.0994 15.3923 18.6074 14.9001 18 14.9001Z" fill="currentColor"/> -<path d="M7.32422 5.38931C7.61669 4.87032 8.38346 4.87015 8.67578 5.38931L8.73047 5.50845L8.89551 5.95376L8.97949 6.1481C9.19937 6.58817 9.57968 6.93145 10.0459 7.10415L10.4912 7.26919C11.127 7.50461 11.1666 8.36217 10.6104 8.67544L10.4912 8.73013L10.0459 8.89517C9.5799 9.06783 9.19939 9.41141 8.97949 9.85123L8.89551 10.0456L8.73047 10.4909C8.49495 11.1267 7.63737 11.1665 7.32422 10.61L7.26953 10.4909L7.10449 10.0456C6.93172 9.57931 6.58767 9.19898 6.14746 8.97916L5.9541 8.89517L5.50879 8.73013C4.83054 8.47903 4.83061 7.52037 5.50879 7.26919L5.9541 7.10415L6.14746 7.02017C6.58757 6.80032 6.93176 6.41995 7.10449 5.95376L7.26953 5.50845L7.32422 5.38931Z" fill="currentColor"/> -</svg> -`,L3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M17.9551 6.32648C17.955 5.82951 17.5517 5.42706 17.0547 5.42706H15.4844C14.9875 5.42717 14.5851 5.82958 14.585 6.32648V17.6732C14.585 18.1701 14.9874 18.5734 15.4844 18.5735H17.0547C17.5518 18.5735 17.9551 18.1702 17.9551 17.6732V6.32648ZM19.7549 17.6732C19.7549 19.1643 18.5459 20.3734 17.0547 20.3734H15.4844C13.9933 20.3732 12.7842 19.1643 12.7842 17.6732V6.32648C12.7843 4.83546 13.9934 3.62639 15.4844 3.62628H17.0547C18.5458 3.62628 19.7548 4.8354 19.7549 6.32648V17.6732Z" fill="currentColor"/> -<path d="M9.41571 6.32648C9.41561 5.82951 9.01231 5.42706 8.51532 5.42706H6.94501C6.44811 5.42717 6.0457 5.82958 6.04559 6.32648V17.6732C6.04559 18.1701 6.44804 18.5734 6.94501 18.5735H8.51532C9.01238 18.5735 9.41571 18.1702 9.41571 17.6732V6.32648ZM11.2155 17.6732C11.2155 19.1643 10.0065 20.3734 8.51532 20.3734H6.94501C5.45393 20.3732 4.24481 19.1643 4.24481 17.6732V6.32648C4.24492 4.83546 5.45399 3.62639 6.94501 3.62628H8.51532C10.0064 3.62628 11.2154 4.8354 11.2155 6.32648V17.6732Z" fill="currentColor"/> -</svg> -`,N3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M18.0176 4.89998C17.7305 4.89998 17.4552 5.014 17.2522 5.217L6.35429 16.1149C5.957 16.5122 5.67517 17.01 5.53889 17.5551L5.23691 18.763L6.44486 18.4611C6.98994 18.3248 7.48773 18.0429 7.88502 17.6456L18.783 6.74773C18.8834 6.64728 18.9631 6.52797 19.0176 6.39658C19.072 6.26517 19.1 6.12441 19.1 5.98236C19.1 5.84031 19.072 5.69956 19.0176 5.56815C18.9631 5.43676 18.8834 5.31745 18.783 5.217C18.6825 5.11649 18.5631 5.03676 18.4318 4.98237C18.3005 4.92798 18.1597 4.89998 18.0176 4.89998ZM15.9794 3.94421C16.52 3.40366 17.2531 3.09998 18.0176 3.09998C18.3961 3.09998 18.7709 3.17452 19.1207 3.31938C19.4704 3.46424 19.7881 3.67656 20.0558 3.94421C20.3235 4.21192 20.5357 4.52969 20.6805 4.87932C20.8254 5.22895 20.9 5.60375 20.9 5.98236C20.9 6.36098 20.8254 6.73578 20.6805 7.08541C20.5357 7.43504 20.3235 7.75281 20.0558 8.02052L17.6385 10.4378L9.15781 18.9184C8.52984 19.5464 7.74301 19.9919 6.88142 20.2073L4.21828 20.8731C3.91158 20.9498 3.58714 20.8599 3.3636 20.6364C3.14006 20.4128 3.05019 20.0884 3.12686 19.7817L3.79264 17.1185C4.00803 16.257 4.45351 15.4701 5.0815 14.8421L15.9794 3.94421Z" fill="currentColor"/> -</svg> -`,F3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M7.76251 3.10547C8.25776 3.10552 8.74422 3.23849 9.17072 3.49023L19.533 9.60742C20.8536 10.3869 21.2922 12.0901 20.5174 13.4121C20.2785 13.8195 19.9398 14.1604 19.533 14.4004L9.16974 20.5156C7.84721 21.2958 6.14595 20.8511 5.36993 19.5273C5.1196 19.1003 4.98719 18.6142 4.98712 18.1191V5.88672C4.98716 4.3537 6.2273 3.10547 7.76251 3.10547ZM6.7879 18.1191C6.78797 18.2945 6.8343 18.4664 6.92267 18.6172C7.19638 19.0841 7.79336 19.2377 8.25568 18.9648L18.618 12.8496C18.7607 12.7654 18.8803 12.6458 18.9647 12.502C19.2393 12.0334 19.082 11.4311 18.618 11.1572L8.25568 5.04102C8.1061 4.95273 7.93562 4.9063 7.76251 4.90625C7.22703 4.90625 6.78794 5.34218 6.7879 5.88672V18.1191Z" fill="currentColor"/> -</svg> -`,D3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M18.36 6.64a9 9 0 1 1-12.73 0" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> -<path d="M12 2v10" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> -</svg> -`,B3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z" fill="currentColor"/> -<path d="M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2ZM12 3.7998C7.47126 3.7998 3.7998 7.47126 3.7998 12C3.7998 16.5287 7.47126 20.2002 12 20.2002C16.5287 20.2002 20.2002 16.5287 20.2002 12C20.2002 7.47126 16.5287 3.7998 12 3.7998Z" fill="currentColor"/> -</svg> -`,$3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 2C13.1046 2 14 2.89543 14 4C14 4.78019 13.552 5.45353 12.9004 5.7832V7H16.5C18.1569 7 19.5 8.34315 19.5 10V17C19.5 18.6051 18.2394 19.9158 16.6543 19.9961L16.5 20H7.5L7.3457 19.9961C5.81166 19.9184 4.58163 18.6883 4.50391 17.1543L4.5 17V10C4.5 8.34315 5.84315 7 7.5 7H11.0996V5.7832C10.448 5.45353 10 4.78019 10 4C10 2.89543 10.8954 2 12 2ZM7.5 8.7998C6.83726 8.7998 6.2998 9.33726 6.2998 10V17C6.2998 17.6627 6.83726 18.2002 7.5 18.2002H16.5C17.1627 18.2002 17.7002 17.6627 17.7002 17V10C17.7002 9.33726 17.1627 8.7998 16.5 8.7998H7.5ZM3 10.7666C3.49706 10.7666 3.90039 11.1699 3.90039 11.667V15C3.90039 15.4971 3.49706 15.9004 3 15.9004C2.50294 15.9004 2.09961 15.4971 2.09961 15V11.667C2.09961 11.1699 2.50294 10.7666 3 10.7666ZM21 10.7666C21.4971 10.7666 21.9004 11.1699 21.9004 11.667V15C21.9004 15.4971 21.4971 15.9004 21 15.9004C20.5029 15.9004 20.0996 15.4971 20.0996 15V11.667C20.0996 11.1699 20.5029 10.7666 21 10.7666ZM9.5 11.0996C9.99706 11.0996 10.4004 11.5029 10.4004 12V14.5C10.4004 14.9971 9.99706 15.4004 9.5 15.4004C9.00294 15.4004 8.59961 14.9971 8.59961 14.5V12C8.59961 11.5029 9.00294 11.0996 9.5 11.0996ZM14.5 11.0996C14.9971 11.0996 15.4004 11.5029 15.4004 12V14.5C15.4004 14.9971 14.9971 15.4004 14.5 15.4004C14.0029 15.4004 13.5996 14.9971 13.5996 14.5V12C13.5996 11.5029 14.0029 11.0996 14.5 11.0996ZM12 3.5C11.7239 3.5 11.5 3.72386 11.5 4C11.5 4.27614 11.7239 4.5 12 4.5C12.2761 4.5 12.5 4.27614 12.5 4C12.5 3.72386 12.2761 3.5 12 3.5Z" fill="currentColor"/> -</svg> -`,R3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.5 3C16.1944 3 20 6.80558 20 11.5C20 13.523 19.2933 15.381 18.1132 16.8404L21.1364 19.8636C21.4879 20.2151 21.4879 20.7849 21.1364 21.1364C20.7849 21.4879 20.2151 21.4879 19.8636 21.1364L16.8404 18.1132C15.381 19.2933 13.523 20 11.5 20C6.80558 20 3 16.1944 3 11.5C3 6.80558 6.80558 3 11.5 3ZM11.5 18.2C15.2003 18.2 18.2 15.2003 18.2 11.5C18.2 7.79969 15.2003 4.8 11.5 4.8C7.79969 4.8 4.8 7.79969 4.8 11.5C4.8 15.2003 7.79969 18.2 11.5 18.2Z" fill="currentColor"/> -</svg> -`,z3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M16.5364 10.1636C16.8879 10.5151 16.8879 11.0849 16.5364 11.4364C16.1849 11.7879 15.6151 11.7879 15.2636 11.4364L12.9 9.07281V17.1C12.9 17.597 12.4971 18 12 18C11.503 18 11.1 17.597 11.1 17.1V9.07281L8.73641 11.4364C8.38494 11.7879 7.81509 11.7879 7.46362 11.4364C7.11214 11.0849 7.11214 10.5151 7.46362 10.1636L11.3636 6.2636C11.7151 5.91211 12.2849 5.91211 12.6364 6.2636L16.5364 10.1636Z" fill="currentColor"/> -</svg> -`,O3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M16.0404 12C16.0404 9.76874 14.2313 7.9596 12.0001 7.9596C9.76883 7.9596 7.95972 9.76874 7.95972 12C7.95972 14.2313 9.76883 16.0404 12.0001 16.0404C14.2313 16.0404 16.0404 14.2313 16.0404 12ZM14.2222 12C14.2222 13.2271 13.2271 14.2222 12 14.2222C10.7729 14.2222 9.77783 13.2271 9.77783 12C9.77783 10.7729 10.7729 9.77778 12 9.77778C13.2271 9.77778 14.2222 10.7729 14.2222 12Z" fill="currentColor"/> -<path d="M9.91145 21.8009C9.29001 21.6797 8.76914 21.2612 8.50632 20.6922L8.07372 19.7556C7.88838 19.3544 7.43553 19.1048 6.95371 19.1549L5.89572 19.2647C5.2733 19.3293 4.64823 19.114 4.22298 18.6611C3.74343 18.1504 3.32454 17.6037 2.97033 17.0181C2.61571 16.4318 2.32839 15.8106 2.10407 15.1566C1.89769 14.5549 2.02148 13.8954 2.4089 13.3902L3.0376 12.5704C3.30043 12.2277 3.30042 11.7722 3.03758 11.4295L2.40413 10.6035C2.01474 10.0958 1.891 9.43198 2.10208 8.82826C2.55037 7.54612 3.27017 6.35997 4.22 5.34259C4.64518 4.8872 5.27275 4.67067 5.89701 4.73544L6.95383 4.84514C7.43561 4.89515 7.88844 4.6456 8.07377 4.24441L8.50266 3.31593C8.76494 2.74818 9.28448 2.33019 9.90423 2.20761C11.2916 1.9332 12.7148 1.93127 14.0885 2.19913C14.7099 2.32029 15.2308 2.73881 15.4937 3.3078L15.9263 4.24441C16.1116 4.6456 16.5644 4.89514 17.0462 4.84514L18.1043 4.73532C18.7267 4.67072 19.3518 4.88603 19.777 5.33886C20.2566 5.84953 20.6755 6.3963 21.0297 6.98193C21.3843 7.56823 21.6716 8.18942 21.8959 8.84339C22.1023 9.44509 21.9785 10.1046 21.5911 10.6098L20.9624 11.4295C20.6996 11.7722 20.6996 12.2278 20.9624 12.5705L21.5959 13.3964C21.9853 13.9042 22.109 14.568 21.8979 15.1717C21.4497 16.4538 20.7299 17.6399 19.7801 18.6573C19.3549 19.1128 18.7273 19.3294 18.103 19.2646L17.0462 19.1549C16.5645 19.1049 16.1116 19.3544 15.9263 19.7556L15.4974 20.6841C15.2351 21.2518 14.7156 21.6698 14.0958 21.7924C12.7083 22.0668 11.2852 22.0687 9.91145 21.8009ZM13.7432 20.0088C13.7844 20.0006 13.8259 19.9673 13.847 19.9216L14.2758 18.9931C14.7915 17.8768 15.9886 17.2171 17.2341 17.3464L18.2909 17.4561C18.3649 17.4638 18.4272 17.4423 18.4512 17.4166C19.2296 16.5828 19.8171 15.6146 20.1817 14.5716C20.1845 14.5636 20.1796 14.5373 20.1532 14.5029L19.5198 13.677C18.7564 12.6815 18.7564 11.3185 19.5198 10.323L20.1485 9.5033C20.1746 9.46927 20.1795 9.4429 20.1762 9.43327C19.9932 8.89965 19.7603 8.39623 19.4741 7.92293C19.1873 7.4489 18.846 7.00333 18.4517 6.58351C18.4272 6.55739 18.3656 6.53616 18.2921 6.54378L17.234 6.65361C15.9886 6.78287 14.7915 6.12317 14.2758 5.00689L13.8432 4.07027C13.822 4.02448 13.7811 3.9916 13.7406 3.98371C12.5983 3.76097 11.4132 3.76258 10.2571 3.99124C10.2158 3.99941 10.1744 4.03271 10.1533 4.07842L9.72441 5.00689C9.20875 6.12317 8.01164 6.7829 6.76619 6.6536L5.70942 6.54391C5.63535 6.53623 5.573 6.55774 5.54905 6.5834C4.77067 7.41713 4.18312 8.38534 3.81845 9.42835C3.81564 9.43637 3.82054 9.46265 3.84693 9.49706L4.48038 10.323C5.24381 11.3185 5.24383 12.6815 4.48041 13.6769L3.85171 14.4967C3.82561 14.5307 3.82066 14.5571 3.82396 14.5667C4.00701 15.1004 4.23986 15.6038 4.52613 16.0771C4.81284 16.5511 5.15421 16.9967 5.54845 17.4165C5.57298 17.4426 5.63461 17.4638 5.70811 17.4562L6.76608 17.3464C8.01157 17.2171 9.20871 17.8768 9.72438 18.9932L10.157 19.9297C10.1781 19.9755 10.2191 20.0084 10.2595 20.0163C11.4018 20.239 12.587 20.2374 13.7432 20.0088Z" fill="currentColor"/> -</svg> -`,P3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M17 2C19.2091 2 21 3.79086 21 6V15.7646C21 17.2361 20.192 18.5884 18.8965 19.2861L13.8965 21.9785C12.7126 22.616 11.2874 22.616 10.1035 21.9785L5.10352 19.2861C3.80802 18.5884 3 17.2361 3 15.7646V6C3 3.79086 4.79086 2 7 2H17ZM7 3.7998C5.78498 3.7998 4.79981 4.78497 4.7998 6V15.7646C4.7998 16.574 5.24443 17.3184 5.95703 17.7021L10.957 20.3936C11.6082 20.7442 12.3918 20.7442 13.043 20.3936L18.043 17.7021C18.7556 17.3184 19.2002 16.574 19.2002 15.7646V6C19.2002 4.78497 18.215 3.7998 17 3.7998H7Z" fill="currentColor"/> -<path d="M10.1611 7.37109C10.9017 6.79576 11.8605 6.60385 12.7881 6.8457C13.808 7.10861 14.6385 7.93756 14.9014 8.95898C15.2694 10.3845 14.5793 11.8629 13.2598 12.4736C13.0803 12.557 12.75 12.9552 12.75 13.3525V13.502C12.75 13.9172 12.4142 14.2527 11.999 14.2529C11.5837 14.2529 11.248 13.9173 11.248 13.502V13.3525C11.248 12.313 11.9587 11.4215 12.6279 11.1113C13.1777 10.8567 13.6681 10.192 13.4473 9.33496C13.3195 8.84253 12.9038 8.42684 12.4121 8.2998C11.9292 8.17289 11.4573 8.26727 11.0811 8.55859C10.71 8.84626 10.4971 9.28012 10.4971 9.74805C10.4968 10.1632 10.1613 10.499 9.74609 10.499C9.33092 10.499 8.99536 10.1632 8.99512 9.74805C8.99512 8.81152 9.41918 7.94493 10.1611 7.37109Z" fill="currentColor"/> -<path d="M11.999 15.0049C12.6208 15.0049 13.1259 15.5091 13.126 16.1309C13.126 16.7528 12.6209 17.2578 11.999 17.2578C11.3773 17.2576 10.873 16.7526 10.873 16.1309C10.8732 15.5092 11.3774 15.0051 11.999 15.0049Z" fill="currentColor"/> -</svg> -`,j3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M2.90005 12C2.90005 11.503 3.303 11.1 3.80005 11.1H12.2939L9.38588 8.19197C9.03441 7.8405 9.03441 7.27065 9.38588 6.91918C9.73735 6.56771 10.3072 6.56771 10.6587 6.91918L15.1031 11.3636C15.2719 11.5324 15.3667 11.7613 15.3667 12C15.3667 12.2387 15.2719 12.4676 15.1031 12.6364L10.6587 17.0809C10.3072 17.4323 9.73735 17.4323 9.38588 17.0809C9.03441 16.7294 9.03441 16.1595 9.38588 15.8081L12.2939 12.9H3.80005C3.303 12.9 2.90005 12.4971 2.90005 12ZM13.5874 20C13.5874 19.503 13.9904 19.1 14.4874 19.1H18.043C18.2758 19.1 18.4991 19.0075 18.6637 18.8429C18.8283 18.6783 18.9208 18.455 18.9208 18.2222V5.7778C18.9208 5.545 18.8283 5.32174 18.6637 5.15712C18.499 4.9925 18.2758 4.90002 18.043 4.90002H14.4874C13.9904 4.90002 13.5874 4.49708 13.5874 4.00002C13.5874 3.50297 13.9904 3.10003 14.4874 3.10003H18.043C18.7532 3.10003 19.4343 3.38215 19.9365 3.88433C20.4386 4.38651 20.7208 5.06761 20.7208 5.7778V18.2222C20.7208 18.9324 20.4386 19.6135 19.9365 20.1157C19.4343 20.6179 18.7532 20.9 18.043 20.9H14.4874C13.9904 20.9 13.5874 20.4971 13.5874 20Z" fill="currentColor"/> -</svg> -`,H3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M20.6364 11.3636C20.9879 11.7151 20.9879 12.2849 20.6364 12.6364L16.1919 17.0808C15.8405 17.4323 15.2706 17.4323 14.9192 17.0808C14.5677 16.7293 14.5677 16.1595 14.9192 15.808L17.8272 12.9H9.33333C8.83627 12.9 8.43333 12.497 8.43333 12C8.43333 11.5029 8.83627 11.1 9.33333 11.1H17.8272L14.9192 8.19193C14.5677 7.84046 14.5677 7.27061 14.9192 6.91914C15.2706 6.56766 15.8405 6.56766 16.1919 6.91914L20.6364 11.3636ZM10.2333 3.99998C10.2333 4.49703 9.83038 4.89998 9.33333 4.89998H5.77777C5.54497 4.89998 5.3217 4.99246 5.15709 5.15707C4.99247 5.32169 4.89999 5.54495 4.89999 5.77775V18.2222C4.89999 18.455 4.99247 18.6783 5.15709 18.8429C5.32171 19.0075 5.54497 19.1 5.77777 19.1H9.33333C9.83038 19.1 10.2333 19.5029 10.2333 20C10.2333 20.497 9.83038 20.9 9.33333 20.9H5.77777C5.06758 20.9 4.38648 20.6179 3.8843 20.1157C3.38212 19.6135 3.09999 18.9324 3.09999 18.2222V5.77775C3.09999 5.06756 3.38212 4.38646 3.8843 3.88428C4.38648 3.3821 5.06758 3.09998 5.77777 3.09998H9.33333C9.83038 3.09998 10.2333 3.50292 10.2333 3.99998Z" fill="currentColor"/> -</svg> -`,W3e='<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4 6H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M18.0 6H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="6" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 12H6.5" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M10.5 12H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="8.5" cy="12" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/><path d="M4 18H14.0" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><path d="M18.0 18H20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round"/><circle cx="16" cy="18" r="2.0" fill="none" stroke="currentColor" stroke-width="1.8"/></svg>',q3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M7.78027 8.90405C7.5 9.45411 7.5 10.1742 7.5 11.6144V12.3856C7.5 13.8258 7.5 14.5459 7.78027 15.096C8.02681 15.5798 8.42019 15.9732 8.90405 16.2197C9.45411 16.5 10.1742 16.5 11.6144 16.5H12.3856C13.8258 16.5 14.5459 16.5 15.096 16.2197C15.5798 15.9732 15.9732 15.5798 16.2197 15.096C16.5 14.5459 16.5 13.8258 16.5 12.3856V11.6144C16.5 10.1742 16.5 9.45411 16.2197 8.90405C15.9732 8.42019 15.5798 8.02681 15.096 7.78027C14.5459 7.5 13.8258 7.5 12.3856 7.5H11.6144C10.1742 7.5 9.45411 7.5 8.90405 7.78027C8.42019 8.02681 8.02681 8.42019 7.78027 8.90405Z" fill="currentColor"/> -</svg> -`,U3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M7.01562 3.41459C7.4446 3.16449 7.9954 3.30924 8.24609 3.73784C8.49645 4.167 8.35189 4.71868 7.92285 4.96928C5.51497 6.37506 3.90054 8.98498 3.90039 11.9703C3.90076 16.4435 7.52672 20.0699 12 20.0699C16.4733 20.0699 20.0992 16.4435 20.0996 11.9703C20.0996 11.2291 20 10.5116 19.8145 9.83159C19.6838 9.35222 19.967 8.85702 20.4463 8.72612C20.9256 8.59541 21.4207 8.87778 21.5518 9.35698C21.7792 10.1901 21.9004 11.0674 21.9004 11.9703C21.9 17.4376 17.4674 21.8697 12 21.8697C6.53261 21.8697 2.09998 17.4376 2.09961 11.9703C2.09976 8.31904 4.07782 5.12972 7.01562 3.41459ZM8.39258 8.24077C8.75015 7.89591 9.3199 7.90591 9.66504 8.26323C10.01 8.62076 9.99985 9.19051 9.64258 9.53569C9.00203 10.1541 8.60558 11.02 8.60547 11.979C8.60584 13.8536 10.1253 15.3736 12 15.3736C13.8746 15.3735 15.3942 13.8536 15.3945 11.979C15.3945 11.6847 15.3577 11.3989 15.2881 11.1285C15.1646 10.6474 15.4536 10.1568 15.9346 10.0328C16.4158 9.9089 16.9071 10.1991 17.0312 10.6802C17.1383 11.096 17.1943 11.5321 17.1943 11.979C17.194 14.8477 14.8688 17.1733 12 17.1734C9.1312 17.1734 6.80506 14.8478 6.80469 11.979C6.8048 10.5117 7.41519 9.18431 8.39258 8.24077ZM11.5459 1.12651C11.8216 0.965605 12.1631 0.963306 12.4414 1.11967L19.1953 4.91752C19.4859 5.08108 19.662 5.39277 19.6533 5.72612C19.6443 6.05972 19.4515 6.36154 19.1523 6.50932L12.9004 9.5933V12.2583C12.9004 12.7554 12.4971 13.1587 12 13.1587C11.5029 13.1587 11.0996 12.7554 11.0996 12.2583V1.90385C11.0999 1.58444 11.2702 1.2878 11.5459 1.12651ZM12.9004 7.58549L16.8252 5.64897L12.9004 3.44194V7.58549Z" fill="currentColor"/> -</svg> -`,K3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M18.9893 6.60743C20.5897 6.60757 21.8877 7.8926 21.8877 9.47736C21.8877 10.7416 21.0607 11.8129 19.9141 12.1955V14.257C19.914 15.8428 18.6152 17.1288 17.0137 17.1289H12.8438V20.1381C12.8437 20.6301 12.4412 21.0293 11.9443 21.0296C11.4473 21.0296 11.044 20.6302 11.0439 20.1381V16.4356C11.0441 15.8343 11.5363 15.3461 12.1436 15.3458H17.0137C17.6211 15.3457 18.1133 14.8585 18.1133 14.257V12.2129C16.9408 11.8451 16.0909 10.7598 16.0908 9.47736C16.0908 7.89251 17.3887 6.60743 18.9893 6.60743ZM18.9893 8.38953C18.3828 8.38953 17.8906 8.87684 17.8906 9.47736C17.8907 10.0778 18.3828 10.5642 18.9893 10.5642C19.5956 10.5641 20.0869 10.0777 20.0869 9.47736C20.0869 8.87693 19.5956 8.38967 18.9893 8.38953Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M4.89844 6.60743C6.49899 6.60747 7.79688 7.89254 7.79688 9.47736C7.79684 10.7388 6.97371 11.8078 5.83105 12.1926V14.4021C5.83105 15.0036 6.32315 15.4918 6.93066 15.4918H8.37109C8.86789 15.492 9.27038 15.8905 9.27051 16.3824C9.27051 16.8744 8.86797 17.2737 8.37109 17.2739H6.93066C5.32904 17.2739 4.03027 15.9879 4.03027 14.4021V12.2158C2.85382 11.8504 2.00004 10.7627 2 9.47736C2 7.89251 3.29784 6.60743 4.89844 6.60743ZM4.89844 8.38953C4.29196 8.38953 3.7998 8.87684 3.7998 9.47736C3.79985 10.0778 4.29198 10.5642 4.89844 10.5642C5.50485 10.5642 5.99605 10.0778 5.99609 9.47736C5.99609 8.87687 5.50488 8.38958 4.89844 8.38953Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M11.9434 2.9707C13.5439 2.97075 14.8418 4.25581 14.8418 5.84063C14.8418 7.11413 14.0035 8.1923 12.8438 8.56745V13.0135C12.8436 13.5056 12.4403 13.9041 11.9434 13.9041C11.4466 13.9039 11.0431 13.5055 11.043 13.0135V8.56745C9.8836 8.19209 9.04496 7.11387 9.04492 5.84063C9.04492 4.25592 10.343 2.97093 11.9434 2.9707ZM11.9434 4.75281C11.3371 4.75303 10.8447 5.24026 10.8447 5.84063C10.8448 6.44097 11.3371 6.92726 11.9434 6.92749C12.5498 6.92745 13.041 6.44108 13.041 5.84063C13.041 5.24014 12.5498 4.75285 11.9434 4.75281Z" fill="currentColor"/> -</svg> -`,V3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M16.5293 15.0596C16.9496 15.1021 17.2772 15.4572 17.2773 15.8887C17.2773 16.3202 16.9497 16.6753 16.5293 16.7178L16.4443 16.7217H12C11.5399 16.7216 11.167 16.3488 11.167 15.8887C11.1671 15.4286 11.54 15.0558 12 15.0557H16.4443L16.5293 15.0596Z" fill="currentColor"/> -<path d="M6.96582 7.52246C7.27077 7.21751 7.75375 7.1983 8.08105 7.46484L8.14453 7.52246L10.8232 10.2002C11.5102 10.8872 11.5102 12.0014 10.8232 12.6885L8.14453 15.3672L8.08105 15.4248C7.75377 15.6913 7.27075 15.6721 6.96582 15.3672C6.66114 15.0621 6.64234 14.5791 6.90918 14.252L6.96582 14.1885L9.64453 11.5098C9.68057 11.4736 9.68062 11.415 9.64453 11.3789L6.96582 8.7002C6.64116 8.37488 6.6411 7.84774 6.96582 7.52246Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M17 3.09961C19.1539 3.09966 20.9004 4.84612 20.9004 7V17C20.9004 19.1539 19.1539 20.9003 17 20.9004H7C4.84609 20.9004 3.09961 19.1539 3.09961 17V7C3.09961 4.84609 4.84609 3.09961 7 3.09961H17ZM7 4.90039C5.8402 4.90039 4.90039 5.8402 4.90039 7V17C4.90039 18.1598 5.8402 19.0996 7 19.0996H17C18.1598 19.0996 19.0996 18.1598 19.0996 17V7C19.0996 5.84024 18.1598 4.90044 17 4.90039H7Z" fill="currentColor"/> -</svg> -`,Z3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M16.9971 3.90597C15.9799 2.99725 14.7342 2.38312 13.394 2.12966C12.0538 1.8762 10.6699 1.99301 9.39111 2.46751C8.11236 2.94202 6.98721 3.75626 6.13676 4.82261C5.2863 5.88896 4.74274 7.16703 4.56457 8.5193C4.40455 9.70501 4.53253 10.9118 4.93767 12.0376C5.34281 13.1634 6.01318 14.175 6.89207 14.9868C7.43557 15.4634 7.87413 16.0477 8.17997 16.7027C8.48581 17.3577 8.65224 18.0691 8.66873 18.7918V18.926C8.66962 19.7412 8.99387 20.5229 9.57035 21.0993C10.1468 21.6758 10.9285 22.0001 11.7437 22.001H12.2604C13.0757 22.0001 13.8573 21.6758 14.4338 21.0993C15.0103 20.5229 15.3345 19.7412 15.3354 18.926V18.4685C15.3479 17.8297 15.4982 17.2011 15.7761 16.6258C16.0539 16.0505 16.4528 15.542 16.9454 15.1351C17.7442 14.4355 18.3853 13.5741 18.826 12.608C19.2668 11.642 19.4973 10.5932 19.5022 9.53136C19.5071 8.46948 19.2863 7.41869 18.8544 6.4486C18.4225 5.4785 17.7894 4.61125 16.9971 3.9043V3.90597ZM12.2604 20.3343H11.7437C11.3704 20.3339 11.0124 20.1853 10.7484 19.9213C10.4844 19.6573 10.3358 19.2993 10.3354 18.926C10.3354 18.926 10.3296 18.7093 10.3287 18.6676H13.6687V18.926C13.6683 19.2993 13.5198 19.6573 13.2558 19.9213C12.9917 20.1853 12.6338 20.3339 12.2604 20.3343ZM15.8437 13.8835C14.8949 14.7064 14.2097 15.7908 13.8737 17.001H12.8354V11.0143C13.3212 10.8426 13.742 10.5249 14.0403 10.1049C14.3387 9.68482 14.4999 9.18285 14.5021 8.66763C14.5021 8.44662 14.4143 8.23466 14.258 8.07838C14.1017 7.9221 13.8897 7.8343 13.6687 7.8343C13.4477 7.8343 13.2358 7.9221 13.0795 8.07838C12.9232 8.23466 12.8354 8.44662 12.8354 8.66763C12.8354 8.88865 12.7476 9.10061 12.5913 9.25689C12.435 9.41317 12.2231 9.50097 12.0021 9.50097C11.7811 9.50097 11.5691 9.41317 11.4128 9.25689C11.2565 9.10061 11.1687 8.88865 11.1687 8.66763C11.1687 8.44662 11.0809 8.23466 10.9247 8.07838C10.7684 7.9221 10.5564 7.8343 10.3354 7.8343C10.1144 7.8343 9.90242 7.9221 9.74614 8.07838C9.58986 8.23466 9.50207 8.44662 9.50207 8.66763C9.5042 9.18285 9.66547 9.68482 9.96381 10.1049C10.2621 10.5249 10.683 10.8426 11.1687 11.0143V17.001H10.0671C9.69123 15.7586 8.98633 14.6411 8.02707 13.7668C7.21286 13.0081 6.63267 12.0324 6.35496 10.9547C6.07725 9.87703 6.1136 8.7424 6.45974 7.68471C6.80588 6.62702 7.44735 5.69042 8.30846 4.98543C9.16956 4.28045 10.2144 3.83649 11.3196 3.70597C11.5487 3.68039 11.779 3.66759 12.0096 3.66763C13.4409 3.66338 14.8226 4.19149 15.8862 5.1493C16.5026 5.69896 16.9952 6.37337 17.3312 7.12782C17.6672 7.88227 17.839 8.69952 17.8352 9.5254C17.8314 10.3513 17.6522 11.1669 17.3092 11.9183C16.9663 12.6696 16.4677 13.3395 15.8462 13.8835H15.8437Z" fill="currentColor"/> -</svg> -`,G3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M9.28994 4.92561C9.6436 4.57634 9.64716 4.0065 9.29789 3.65284C8.94862 3.29918 8.37878 3.29563 8.02512 3.6449L5.91339 5.73041L5.16642 4.95888C4.82067 4.60177 4.2509 4.59256 3.89379 4.9383C3.53668 5.28404 3.52747 5.85382 3.87321 6.21093L5.25245 7.63551C5.41956 7.80811 5.64874 7.90674 5.88897 7.90943C6.1292 7.91213 6.36053 7.81866 6.53146 7.64985L9.28994 4.92561Z" fill="currentColor"/> -<path d="M12 5.10022C11.503 5.10022 11.1 5.50316 11.1 6.00022C11.1 6.49728 11.503 6.90022 12 6.90022L19.9965 6.90022C20.4935 6.90022 20.8965 6.49728 20.8965 6.00022C20.8965 5.50316 20.4935 5.10022 19.9965 5.10022L12 5.10022Z" fill="currentColor"/> -<path d="M12 11.1002C11.503 11.1002 11.1 11.5032 11.1 12.0002C11.1 12.4973 11.503 12.9002 12 12.9002H19.9965C20.4935 12.9002 20.8965 12.4973 20.8965 12.0002C20.8965 11.5032 20.4935 11.1002 19.9965 11.1002L12 11.1002Z" fill="currentColor"/> -<path d="M11.1 18.0002C11.1 17.5032 11.503 17.1002 12 17.1002L19.9965 17.1002C20.4935 17.1002 20.8965 17.5032 20.8965 18.0002C20.8965 18.4973 20.4935 18.9002 19.9965 18.9002H12C11.503 18.9002 11.1 18.4973 11.1 18.0002Z" fill="currentColor"/> -<path d="M9.29789 9.77064C9.64716 10.1243 9.6436 10.6941 9.28994 11.0434L6.53146 13.7676C6.36053 13.9365 6.1292 14.0299 5.88897 14.0272C5.64874 14.0245 5.41956 13.9259 5.25245 13.7533L3.87321 12.3287C3.52747 11.9716 3.53668 11.4018 3.89379 11.0561C4.2509 10.7104 4.82067 10.7196 5.16642 11.0767L5.91339 11.8482L8.02512 9.76269C8.37878 9.41342 8.94862 9.41698 9.29789 9.77064Z" fill="currentColor"/> -<path d="M9.29789 15.7436C9.64716 16.0973 9.6436 16.6671 9.28994 17.0164L6.53146 19.7406C6.36053 19.9094 6.1292 20.0029 5.88897 20.0002C5.64874 19.9975 5.41956 19.8989 5.25245 19.7263L3.87321 18.3017C3.52747 17.9446 3.53668 17.3748 3.89379 17.0291C4.2509 16.6833 4.82067 16.6926 5.16642 17.0497L5.91339 17.8212L8.02512 15.7357C8.37878 15.3864 8.94862 15.39 9.29789 15.7436Z" fill="currentColor"/> -</svg> -`,Q3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path fill-rule="evenodd" clip-rule="evenodd" d="M8.09752 2.19507C8.5421 1.97278 9.08271 2.15298 9.305 2.59756L10.0562 4.10005H13.5C13.9971 4.10005 14.4 4.50299 14.4 5.00005C14.4 5.49711 13.9971 5.90005 13.5 5.90005H12.3106C12.2556 6.2319 12.1667 6.64073 12.0226 7.0987C11.7254 8.04355 11.191 9.20402 10.2334 10.3239C11.4166 11.196 12.5606 11.7524 13.4512 12.0987C13.978 12.3036 14.4136 12.434 14.7124 12.5122L14.7348 12.5181L15.695 10.5976C15.8475 10.2927 16.1591 10.1 16.5 10.1C16.8409 10.1 17.1525 10.2927 17.305 10.5976L20.7969 17.5814L20.8044 17.5959L20.8137 17.615L21.805 19.5976C22.0273 20.0421 21.8471 20.5827 21.4025 20.805C20.9579 21.0273 20.4173 20.8471 20.195 20.4025L19.4438 18.9H13.5562L12.805 20.4025C12.5827 20.8471 12.0421 21.0273 11.5975 20.805C11.1529 20.5827 10.9727 20.0421 11.195 19.5976L12.1863 17.615C12.1917 17.6036 12.1973 17.5924 12.2031 17.5814L13.9146 14.1583C13.6034 14.0667 13.2256 13.9423 12.7988 13.7764C11.7294 13.3605 10.3442 12.6802 8.92538 11.5924C7.79753 12.5167 6.69473 13.0764 5.83285 13.4112C5.33899 13.603 4.92286 13.7216 4.62401 13.7931C4.47449 13.8288 4.35399 13.8529 4.26741 13.8684C4.2241 13.8762 4.18924 13.8818 4.16343 13.8858L4.13156 13.8904L4.12084 13.8919L4.11682 13.8924L4.11514 13.8927C4.11514 13.8927 4.11368 13.8928 4.00001 13L4.11368 13.8928C3.62061 13.9556 3.17 13.6068 3.10722 13.1137C3.0446 12.6219 3.39148 12.1723 3.88256 12.1077L3.94947 12.0967C4.00428 12.0869 4.09114 12.0698 4.20543 12.0424C4.43422 11.9877 4.77156 11.8924 5.18106 11.7334C5.84103 11.477 6.68484 11.0564 7.56458 10.3753C7.15054 9.93496 6.78945 9.48388 6.50421 9.10102C6.26672 8.78224 6.07517 8.50172 5.94227 8.29973C5.87571 8.19858 5.82359 8.11671 5.78748 8.05909C5.76942 8.03027 5.75535 8.00749 5.74545 7.99135L5.73377 7.9722L5.73032 7.96651L5.72864 7.96371C5.71133 7.9349 5.69582 7.9055 5.68208 7.87566C5.49265 7.46416 5.6393 6.96717 6.03659 6.72853C6.09037 6.69623 6.14617 6.6702 6.20315 6.65023C6.59739 6.51205 7.04758 6.66421 7.27129 7.03623L7.27266 7.0385L7.28001 7.05054C7.28695 7.06186 7.29793 7.07964 7.31274 7.10328C7.34239 7.15059 7.38731 7.2212 7.44595 7.31032C7.56343 7.48886 7.73484 7.73997 7.94765 8.02562C8.21085 8.37889 8.52772 8.77187 8.8756 9.14201C9.64226 8.24147 10.0681 7.3133 10.3056 6.55854C10.381 6.3186 10.4372 6.09683 10.4791 5.90005H9.51951C9.50696 5.90031 9.49442 5.90031 9.48191 5.90005H4.00001C3.50296 5.90005 3.10001 5.49711 3.10001 5.00005C3.10001 4.50299 3.50296 4.10005 4.00001 4.10005H8.04378L7.69503 3.40254C7.67314 3.35877 7.65516 3.31407 7.64094 3.26883C7.51078 2.8546 7.69671 2.39547 8.09752 2.19507ZM16.5 13.0125L18.5438 17.1H14.4562L16.5 13.0125Z" fill="currentColor"/> -<path d="M15.1 4.00007C15.1 3.50301 15.5029 3.10007 16 3.10007H18C19.6016 3.10007 20.9 4.39844 20.9 6.00007V8.00007C20.9 8.49712 20.497 8.90007 20 8.90007C19.5029 8.90007 19.1 8.49712 19.1 8.00007V6.00007C19.1 5.39255 18.6075 4.90007 18 4.90007H16C15.5029 4.90007 15.1 4.49712 15.1 4.00007Z" fill="currentColor"/> -<path d="M3.99998 15.1001C4.49703 15.1001 4.89998 15.503 4.89998 16.0001V18.0001C4.89998 18.6076 5.39246 19.1001 5.99998 19.1001H7.99998C8.49703 19.1001 8.89998 19.503 8.89998 20.0001C8.89998 20.4971 8.49703 20.9001 7.99998 20.9001H5.99998C4.39835 20.9001 3.09998 19.6017 3.09998 18.0001V16.0001C3.09998 15.503 3.50292 15.1001 3.99998 15.1001Z" fill="currentColor"/> -</svg> -`,Y3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M8.10001 3C8.10001 2.50294 8.50295 2.1 9.00001 2.1H15C15.4971 2.1 15.9 2.50294 15.9 3C15.9 3.49706 15.4971 3.9 15 3.9H9.00001C8.50295 3.9 8.10001 3.49706 8.10001 3Z" fill="currentColor"/> -<path d="M10 15.9C9.50295 15.9 9.10001 15.4971 9.10001 15L9.10001 10C9.10001 9.50294 9.50295 9.1 10 9.1C10.4971 9.1 10.9 9.50294 10.9 10L10.9 15C10.9 15.4971 10.4971 15.9 10 15.9Z" fill="currentColor"/> -<path d="M13.1 15C13.1 15.4971 13.5029 15.9 14 15.9C14.4971 15.9 14.9 15.4971 14.9 15L14.9 10C14.9 9.50294 14.4971 9.1 14 9.1C13.5029 9.1 13.1 9.50294 13.1 10V15Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M2.10001 6C2.10001 5.50294 2.50295 5.1 3.00001 5.1H4.99152C4.99785 5.09993 5.00417 5.09993 5.01048 5.1H18.9895C18.9958 5.09993 19.0021 5.09993 19.0085 5.1H21C21.4971 5.1 21.9 5.50294 21.9 6C21.9 6.49706 21.4971 6.9 21 6.9H19.8281L18.8448 18.6993C18.7412 19.9432 17.7013 20.9 16.4531 20.9H7.54686C6.29865 20.9 5.25881 19.9432 5.15515 18.6993L4.17188 6.9H3.00001C2.50295 6.9 2.10001 6.49706 2.10001 6ZM5.97811 6.9L18.0219 6.9L17.0511 18.5498C17.0251 18.8608 16.7652 19.1 16.4531 19.1H7.54686C7.23481 19.1 6.97485 18.8608 6.94893 18.5498L5.97811 6.9Z" fill="currentColor"/> -</svg> -`,J3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M7.36336 3.3634C7.71483 3.01192 8.28533 3.01192 8.6368 3.3634C8.98817 3.71488 8.98824 4.2854 8.6368 4.63683L6.17391 7.09972H15.0001C18.2585 7.09977 20.9005 9.74166 20.9005 13.0001C20.9004 16.2585 18.2585 18.9005 15.0001 18.9005H7.00008C6.50307 18.9005 6.09976 18.4971 6.09969 18.0001C6.09969 17.5031 6.50302 17.0997 7.00008 17.0997H15.0001C17.2644 17.0997 19.0996 15.2644 19.0997 13.0001C19.0997 10.7358 17.2644 8.90055 15.0001 8.90051H6.17391L8.6368 11.3634L8.69832 11.4318C8.98668 11.7853 8.96632 12.3073 8.6368 12.6368C8.30728 12.9663 7.78521 12.9867 7.43172 12.6984L7.36336 12.6368L3.36336 8.63683C3.33098 8.60445 3.30286 8.56908 3.27645 8.53332C3.25597 8.50559 3.23607 8.47741 3.21883 8.44738C3.20492 8.42311 3.19221 8.39837 3.18074 8.37316C3.1764 8.36365 3.17109 8.35453 3.16707 8.34484C3.1627 8.33427 3.1593 8.32331 3.15535 8.31261C3.12946 8.24274 3.11237 8.16872 3.10457 8.09191C3.09258 7.97426 3.10262 7.85446 3.1368 7.74035C3.14281 7.72035 3.15094 7.70114 3.15828 7.68176C3.16165 7.67283 3.16341 7.66325 3.16707 7.65441C3.17216 7.64216 3.17806 7.63025 3.18367 7.61828C3.19055 7.60356 3.19744 7.58874 3.20516 7.57433C3.24709 7.49624 3.3012 7.42556 3.36336 7.3634L7.36336 3.3634Z" fill="currentColor"/> -</svg> -`,X3e=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.9997 12.8779C16.0197 12.878 19.4393 15.3848 20.7048 18.8828C21.0812 19.9234 20.2782 20.8962 19.2038 21.0137L18.9861 21.0264H5.0134L4.79562 21.0137C3.7213 20.8961 2.91743 19.9233 3.29367 18.8828C4.55905 15.3847 7.9797 12.8781 11.9997 12.8779ZM11.9997 14.6777C8.84467 14.6779 6.17462 16.5794 5.09152 19.2256H18.9079C17.8248 16.5793 15.1549 14.6778 11.9997 14.6777ZM12.2312 3.00586C14.6088 3.1264 16.4997 5.09239 16.4997 7.5L16.4939 7.73145C16.3734 10.1091 14.4073 11.9999 11.9997 12C9.59225 11.9998 7.62604 10.109 7.50558 7.73145L7.49973 7.5C7.49973 5.01485 9.51462 3.00021 11.9997 3L12.2312 3.00586ZM11.9997 4.7998C10.5087 4.80001 9.29953 6.00896 9.29953 7.5C9.29953 8.99104 10.5087 10.2 11.9997 10.2002C13.4908 10.2001 14.6999 8.99112 14.6999 7.5C14.6999 6.00888 13.4908 4.79989 11.9997 4.7998Z" fill="currentColor"/> -</svg> -`,eke=`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M11.9996 7C11.5026 7 11.0996 7.36985 11.0996 7.82609V14.1739C11.0996 14.6301 11.5026 15 11.9996 15C12.4967 15 12.8996 14.6301 12.8996 14.1739V7.82609C12.8996 7.36985 12.4967 7 11.9996 7Z" fill="currentColor"/> -<path d="M12.8996 17.1006C12.8996 17.5974 12.4968 18.001 11.9992 18.001C11.5024 18.001 11.0996 17.5974 11.0996 17.1006C11.0996 16.6038 11.5024 16.2002 11.9992 16.2002C12.4968 16.2002 12.8996 16.6038 12.8996 17.1006Z" fill="currentColor"/> -<path fill-rule="evenodd" clip-rule="evenodd" d="M14.5108 3.5501C13.3946 1.61676 10.6041 1.61676 9.48786 3.5501L1.69363 17.0501C0.577423 18.9834 1.97269 21.4001 4.20511 21.4001H19.7936C22.026 21.4001 23.4212 18.9834 22.305 17.0501L14.5108 3.5501ZM11.0467 4.4501C11.4701 3.71676 12.5286 3.71676 12.952 4.4501L20.7462 17.9501C21.1696 18.6834 20.6403 19.6001 19.7936 19.6001H4.20511C3.35833 19.6001 2.82909 18.6834 3.25248 17.9501L11.0467 4.4501Z" fill="currentColor"/> -</svg> -`,tke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 6h8m4 0h4M6 12a2 2 0 1 0 4 0a2 2 0 1 0-4 0m-2 0h2m4 0h10m-5 6a2 2 0 1 0 4 0a2 2 0 1 0-4 0M4 18h11m4 0h1"/></svg>',nke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 6l-6 6l6 6"/></svg>',ike='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M3 12a9 9 0 1 0 18 0a9 9 0 1 0-18 0"/><path d="m9 12l2 2l4-4"/></g></svg>',oke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8.56 3.69a9 9 0 0 0-2.92 1.95M3.69 8.56A9 9 0 0 0 3 12m.69 3.44a9 9 0 0 0 1.95 2.92m2.92 1.95A9 9 0 0 0 12 21m3.44-.69a9 9 0 0 0 2.92-1.95m1.95-2.92A9 9 0 0 0 21 12m-.69-3.44a9 9 0 0 0-1.95-2.92m-2.92-1.95A9 9 0 0 0 12 3"/></svg>',ske='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 5a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1zm4 15h10m-8-4v4m6-4v4"/></svg>',rke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 3h6m-5 6h4m-4-6v6L6 20a.7.7 0 0 0 .5 1h11a.7.7 0 0 0 .5-1L14 9V3"/></svg>',lke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M4 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2zm11-2v16"/><path d="m9 10l2 2l-2 2"/></g></svg>',ake='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m15 7l-6.5 6.5a1.5 1.5 0 0 0 3 3L18 10a3 3 0 0 0-6-6l-6.5 6.5a4.5 4.5 0 0 0 9 9L21 13"/></svg>',uke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M4 18v-3.7a1.5 1.5 0 0 0-1.5-1.5H2v-1.6h.5A1.5 1.5 0 0 0 4 9.7V6a3 3 0 0 1 3-3h1v2H7a1 1 0 0 0-1 1v4.1A2 2 0 0 1 4.626 12A2 2 0 0 1 6 13.9V18a1 1 0 0 0 1 1h1v2H7a3 3 0 0 1-3-3m16-3.7V18a3 3 0 0 1-3 3h-1v-2h1a1 1 0 0 0 1-1v-4.1a2 2 0 0 1 1.374-1.9A2 2 0 0 1 18 10.1V6a1 1 0 0 0-1-1h-1V3h1a3 3 0 0 1 3 3v3.7a1.5 1.5 0 0 0 1.5 1.5h.5v1.6h-.5a1.5 1.5 0 0 0-1.5 1.5"/></svg>',cke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M9 3V1H7v2H3a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h18a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1h-4V1h-2v2zm-5 7h16v9H4zm0-5h3v1h2V5h6v1h2V5h3v3H4zm5.879 5.964L12 13.086l2.121-2.122l1.415 1.415l-2.122 2.121l2.121 2.121l-1.414 1.414L12 15.915l-2.121 2.12l-1.415-1.414l2.122-2.12l-2.122-2.122z"/></svg>',dke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M7 3V1h2v2h6V1h2v2h4a1 1 0 0 1 1 1v5h-2V5h-3v2h-2V5H9v2H7V5H4v14h6v2H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1zm10 9a4 4 0 1 0 0 8a4 4 0 0 0 0-8m-6 4a6 6 0 1 1 12 0a6 6 0 0 1-12 0m5-3v3.414l2.293 2.293l1.414-1.414L18 15.586V13z"/></svg>',fke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1zm11 10H4v8h16zM8 14v2H6v-2zm10 0v2h-8v-2zM7 5H4v4h16V5h-3v2h-2V5H9v2H7z"/></svg>',hke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m23 12l-7.071 7.071l-1.414-1.414L20.172 12l-5.657-5.657l1.414-1.414zM3.828 12l5.657 5.657l-1.414 1.414L1 12l7.071-7.071l1.414 1.414z"/></svg>',pke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10s-4.477 10-10 10m0-2a8 8 0 1 0 0-16a8 8 0 0 0 0 16m-4-7h8a4 4 0 0 1-8 0m0-2a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3m8 0a1.5 1.5 0 1 1 0-3a1.5 1.5 0 0 1 0 3"/></svg>',yR='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M10 6v2H5v11h11v-5h2v6a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1zm11-3v8h-2V6.413l-7.793 7.794l-1.414-1.414L17.585 5H13V3z"/></svg>',gke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12 3c5.392 0 9.878 3.88 10.819 9c-.94 5.12-5.427 9-10.819 9s-9.878-3.88-10.818-9C2.122 6.88 6.608 3 12 3m0 16a9.005 9.005 0 0 0 8.778-7a9.005 9.005 0 0 0-17.555 0A9.005 9.005 0 0 0 12 19m0-2.5a4.5 4.5 0 1 1 0-9a4.5 4.5 0 0 1 0 9m0-2a2.5 2.5 0 1 0 0-5a2.5 2.5 0 0 0 0 5"/></svg>',mke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M17.883 19.297A10.95 10.95 0 0 1 12 21c-5.392 0-9.878-3.88-10.818-9A11 11 0 0 1 4.52 5.935L1.394 2.808l1.414-1.414l19.799 19.798l-1.414 1.415zM5.936 7.35A8.97 8.97 0 0 0 3.223 12a9.005 9.005 0 0 0 13.201 5.838l-2.028-2.028A4.5 4.5 0 0 1 8.19 9.604zm6.978 6.978l-3.242-3.241a2.5 2.5 0 0 0 3.241 3.241m7.893 2.265l-1.431-1.431A8.9 8.9 0 0 0 20.778 12A9.005 9.005 0 0 0 9.552 5.338L7.974 3.76C9.221 3.27 10.58 3 12 3c5.392 0 9.878 3.88 10.819 9a10.95 10.95 0 0 1-2.012 4.593m-9.084-9.084Q11.86 7.5 12 7.5a4.5 4.5 0 0 1 4.492 4.778z"/></svg>',vke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M15 4H5v16h14V8h-4zM3 2.992C3 2.444 3.447 2 3.999 2H16l5 5v13.993A1 1 0 0 1 20.007 22H3.993A1 1 0 0 1 3 21.008zM11 11V8h2v3h3v2h-3v3h-2v-3H8v-2z"/></svg>',yke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M13 9h8L11 24v-9H4l9-15zm-2 2V7.22L7.532 13H13v4.394L17.263 11z"/></svg>',kR='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M14 4.438A2.437 2.437 0 0 0 16.438 2h1.125A2.437 2.437 0 0 0 20 4.438v1.125A2.437 2.437 0 0 0 17.563 8h-1.125A2.437 2.437 0 0 0 14 5.563zM1 11a6 6 0 0 0 6-6h2a6 6 0 0 0 6 6v2a6 6 0 0 0-6 6H7a6 6 0 0 0-6-6zm3.876 1A8.04 8.04 0 0 1 8 15.124A8.04 8.04 0 0 1 11.124 12A8.04 8.04 0 0 1 8 8.876A8.04 8.04 0 0 1 4.876 12m12.374 2A3.25 3.25 0 0 1 14 17.25v1.5A3.25 3.25 0 0 1 17.25 22h1.5A3.25 3.25 0 0 1 22 18.75v-1.5A3.25 3.25 0 0 1 18.75 14z"/></svg>',kke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M12.414 5H21a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h7.414z"/></svg>',bke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M6 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2M3 6a3 3 0 1 1 4 2.83V9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2v-.17a3.001 3.001 0 1 1 2 0V9a4 4 0 0 1-4 4h-2v2.17a3.001 3.001 0 1 1-2 0V13H9a4 4 0 0 1-4-4v-.17A3 3 0 0 1 3 6m15-1a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-6 12a1 1 0 1 0 0 2a1 1 0 0 0 0-2"/></svg>',Ake='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M15 5h2a2 2 0 0 1 2 2v8.17a3.001 3.001 0 1 1-2 0V7h-2v3l-4.5-4L15 2zM5 8.83a3.001 3.001 0 1 1 2 0v6.34a3.001 3.001 0 1 1-2 0zM6 7a1 1 0 1 0 0-2a1 1 0 0 0 0 2m0 12a1 1 0 1 0 0-2a1 1 0 0 0 0 2m12 0a1 1 0 1 0 0-2a1 1 0 0 0 0 2"/></svg>',Cke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M2 18h7v2H2zm0-7h9v2H2zm0-7h20v2H2zm18.674 9.025l1.156-.391l1 1.732l-.916.805a4 4 0 0 1 0 1.658l.916.805l-1 1.732l-1.156-.391a4 4 0 0 1-1.435.83L19 21h-2l-.24-1.196a4 4 0 0 1-1.434-.83l-1.156.392l-1-1.732l.916-.805a4 4 0 0 1 0-1.658l-.916-.805l1-1.732l1.156.391c.41-.37.898-.655 1.435-.83L17 11h2l.24 1.196a4 4 0 0 1 1.434.83M18 18a2 2 0 1 0 0-4a2 2 0 0 0 0 4"/></svg>',wke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M10 2a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1H8v2h5V9a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H8v6h5v-1a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-6a1 1 0 0 1-1-1v-1H7a1 1 0 0 1-1-1V8H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1zm9 16h-4v2h4zm0-8h-4v2h4zM9 4H5v2h4z"/></svg>',xke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m13.827 1.69l8.486 8.485l-1.415 1.414l-.707-.707l-4.242 4.243l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243l1.414-1.414l3.536-.707l4.242-4.243l-.707-.707zm.707 3.536l-4.67 4.67l-2.822.565l6.5 6.5l.564-2.822l4.671-4.67z"/></svg>',Ske='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M20 4v12h3l-4 5l-4-5h3V4zm-8 14v2H3v-2zm2-7v2H3v-2zm0-7v2H3V4z"/></svg>',_ke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928z"/></svg>',Mke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m12 18.26l-7.053 3.948l1.575-7.928L.588 8.792l8.027-.952L12 .5l3.385 7.34l8.027.952l-5.934 5.488l1.575 7.928zm0-2.292l4.247 2.377l-.948-4.773l3.573-3.305l-4.833-.573l-2.038-4.419l-2.039 4.42l-4.833.572l3.573 3.305l-.948 4.773z"/></svg>',Ike='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="M5.33 3.272a3.5 3.5 0 0 1 4.254 4.962l10.709 10.71l-1.414 1.414l-10.71-10.71a3.502 3.502 0 0 1-4.962-4.255L5.444 7.63a1.5 1.5 0 0 0 2.121-2.121zm10.367 1.883l3.182-1.768l1.414 1.415l-1.768 3.182l-1.768.353l-2.12 2.121l-1.415-1.414l2.121-2.121zm-6.718 8.132l1.415 1.414l-5.304 5.303a1 1 0 0 1-1.492-1.327l.078-.087z"/></svg>',Eke='<svg viewBox="0 0 24 24" width="1.2em" height="1.2em" ><path fill="currentColor" d="m20.97 17.172l-1.414 1.414l-3.535-3.535l-.073.074l-.707 3.536l-1.415 1.414l-4.242-4.243l-4.95 4.95l-1.414-1.414l4.95-4.95l-4.243-4.243L5.34 8.761l3.536-.707l.073-.074l-3.536-3.536L6.828 3.03zM10.365 9.394l-.502.502l-2.822.565l6.5 6.5l.564-2.822l.502-.502zm8.411.074l-1.34 1.34l1.414 1.415l1.34-1.34l.707.707l1.415-1.415l-8.486-8.485l-1.414 1.414l.707.707l-1.34 1.34l1.414 1.415l1.34-1.34z"/></svg>',Tke={sm:14,md:16,lg:20};function Et(e,t){return{component:e,svg:t}}const bR={plus:Et(sme,j4e),"chat-new":Et(ame,H4e),"calendar-close":Et(L9e,cke),"calendar-schedule":Et(D9e,dke),"calendar-todo":Et(R9e,fke),close:Et(qme,X4e),check:Et(_me,gR),"circle-check":Et(zme,Y4e),"state-open":Et(h9e,oke),"state-done":Et(c9e,ike),archive:Et(dme,W4e),search:Et(oye,R3e),copy:Et(Xme,mR),link:Et(m2e,w3e),"external-link":Et(K9e,yR),download:Et(sve,i3e),undo:Et(Gye,J3e),send:Et(lye,z3e),image:Et(Gve,m3e),settings:Et(cye,O3e),sliders:Et(Cye,W3e),"light-mode":Et(h2e,C3e),"dark-mode":Et(nve,n3e),"follow-system":Et(Lve,c3e),"log-in":Et(mye,j3e),"log-out":Et(kye,H3e),hand:Et(Wve,p3e),"full-access":Et(Dve,d3e),"shield-question":Et(hye,P3e),"chevron-down":Et(Eme,Z4e),"chevron-right":Et(Nme,G4e),"chevron-left":Et(l9e,nke),"chevron-up":Et(Bme,Q4e),"arrow-up":Et(wme,V4e),"arrow-down":Et(pme,q4e),"arrow-right":Et(bme,K4e),"arrow-left":Et(vme,U4e),minus:Et(S2e,_3e),microscope:Et(I2e,M3e),flask:Et(k9e,rke),"panel-collapse":Et(l2e,b3e),"panel-collapse-right":Et(C9e,lke),"panel-expand":Et(c2e,A3e),expand:Et(dve,s3e),collapse:Et(Vme,e3e),list:Et(k2e,x3e),"list-settings":Et(k4e,Cke),"tree-view":Et(C4e,wke),sort:Et(I4e,Ske),grip:Et(Pve,h3e),"session-admin":Et(o9e,tke),folder:Et(Cve,vR),"folder-closed":Et(kve,l3e),"folder-plus":Et(Ive,u3e),"folder-solid":Et(c4e,kke),file:Et(V_,w8),"file-text":Et(mve,r3e),"file-edit":Et(ave,o3e),"file-plus":Et(t4e,vke),"file-off":Et(V_,w8),attachment:Et(S9e,ake),"image-off":Et(Jve,v3e),eye:Et(G9e,gke),"eye-off":Et(J9e,mke),code:Et(P9e,hke),terminal:Et(Dye,V3e),"device-desktop":Et(m9e,ske),pencil:Et(W2e,N3e),tool:Et(R4e,Ike),glob:Et(I9e,uke),globe:Et(Rve,f3e),translate:Et(Wye,Q3e),"check-list":Et(Pye,G3e),bolt:Et(o4e,yke),sparkling:Et(l4e,kR),keyboard:Et(o2e,k3e),trash:Et(Kye,Y3e),"git-fork":Et(h4e,bke),"git-pull-request":Et(m4e,Ake),message:Et(Qme,t3e),mail:Et(C2e,S3e),user:Et(Jye,X3e),info:Et(t2e,y3e),"help-circle":Et(J2e,B3e),"alert-triangle":Et(t9e,eke),clock:Et(jme,J4e),robot:Et(tye,$3e),sparkles:Et(Lye,K3e),"gen-title":Et(Sve,a3e),histogram:Et(Kve,g3e),music:Et(R2e,T3e),emoji:Et(W9e,pke),target:Et(Iye,U3e),pause:Et(P2e,L3e),play:Et(K2e,F3e),power:Et(G2e,D3e),pin:Et(S4e,xke),stop:Et(Sye,q3e),star:Et(L4e,_ke),"star-outline":Et(D4e,Mke),unpin:Et(P4e,Eke),"dots-horizontal":Et(D2e,E3e),model:Et(L2e,I3e),thinking:Et(Rye,Z3e)};function Lke(e){return bR[e]}function Nke(e,t){return e.replace(/<svg\b[^>]*>/,n=>n.replace(/\s(?:width|height)="[^"]*"/g,"")).replace(/^<svg\b/,`<svg class="kw-icon" width="${t}" height="${t}" aria-hidden="true"`)}function Fke(e,t="md"){const n=bR[e];return n?Nke(n.svg,Tke[t]):""}const pct=[["Actions",["plus","attachment","chat-new","close","check","search","copy","link","external-link","download","undo","send","image","settings","sliders","log-in","log-out","eye","eye-off"]],["Navigation & layout",["chevron-down","chevron-right","chevron-up","arrow-up","arrow-down","arrow-right","arrow-left","minus","panel-collapse","panel-collapse-right","panel-expand","expand","collapse","list","list-settings","tree-view","sort","grip"]],["Files & tools",["folder","folder-closed","folder-plus","folder-solid","file","file-text","file-edit","file-plus","file-off","image-off","code","terminal","device-desktop","pencil","tool","glob","globe","check-list","bolt","git-fork","git-pull-request","archive","pin","unpin","target","calendar-schedule","calendar-todo","calendar-close","keyboard","trash","microscope","flask"]],["Communication",["message","mail","user","robot","emoji","translate"]],["Status & media",["info","help-circle","alert-triangle","hand","full-access","shield-question","clock","histogram","music","sparkles","sparkling","gen-title","pause","play","stop","star","star-outline","dots-horizontal","model","thinking","light-mode","dark-mode","follow-system"]]],i7=(e,t)=>t===void 0?da.global.t(e):da.global.t(e,t);function Cf(e){return nB(i7,e)}function Z_(e,t,n=!1){return w6(i7,e,t,n)}function Dke(e){return uoe(i7,e)}const Bke={read:"file-text",bash:"terminal",edit:"pencil",multi_edit:"pencil",write:"file-plus",grep:"search",search:"search",glob:"glob",ls:"folder",web_fetch:"globe",todo:"check-list",task:"sparkles",agentswarm:"sparkles",askuserquestion:"help-circle",exitplanmode:"file-text",creategoal:"target",getgoal:"target",setgoalbudget:"target",updategoal:"target",waitfor:"clock",croncreate:"calendar-schedule",cronlist:"calendar-todo",crondelete:"calendar-close"};function AR(e){const t=Gs(e);let n=Bke[t];return!n&&(e??"").trim().toLowerCase().includes("skill")&&(n="bolt"),n||(n="tool"),n}function CR(e){return Fke(AR(e),"sm")}const $ke={class:"op"},Rke={key:0,class:"op-empty"},zke=Xe({__name:"OutputPanel",props:{lines:{default:void 0},emptyText:{default:""}},setup(e){const t=e,n=F(()=>t.lines??[]);return(i,o)=>(v(),E("div",$ke,[n.value.length===0&&e.emptyText?(v(),E("div",Rke,D(e.emptyText),1)):X("",!0),(v(!0),E(Ee,null,pt(n.value,(s,r)=>(v(),E("div",{key:r},D(s),1))),128))]))}}),Xr=kt(zke,[["__scopeId","data-v-ab413c67"]]),Oke=["disabled","aria-label","aria-expanded"],Pke={class:"lead","aria-hidden":"true"},jke={class:"main"},Hke={class:"task"},Wke={key:0,class:"type"},qke={class:"tail"},Uke=["aria-label"],Kke=["aria-expanded"],Vke=Xe({__name:"AgentTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openAgent"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t;function s(A){if(!A)return{};try{const T=JSON.parse(A);return{description:typeof T.description=="string"?T.description:void 0,subagentType:typeof T.subagent_type=="string"?T.subagent_type:void 0,runInBackground:T.run_in_background===!0}}catch{return{}}}const r=F(()=>s(i.tool.arg)),l=F(()=>i.tool.status),a=F(()=>r.value.description||r.value.subagentType||Cf(i.tool.name)),u=F(()=>r.value.description?r.value.subagentType:""),c=hn("resolveAgentTaskId"),d=hn("resolveAgentModel"),h=F(()=>i.tool.agentId??c?.(i.tool.id)),p=F(()=>h.value!==void 0),g=F(()=>d?.(i.tool.id,h.value)),m=F(()=>[r.value.runInBackground?n("tools.agent.background"):n("tools.agent.foreground"),u.value,g.value?.display,g.value?.effort].filter(A=>A).join(" · ")),k=F(()=>!!i.tool.output&&i.tool.output.length>0),w=F(()=>p.value||k.value),y=K(!1);function b(){if(h.value!==void 0){o("openAgent",h.value);return}k.value&&(y.value=!y.value)}return(A,T)=>(v(),E("div",{class:Fe(["agent-card",{err:l.value==="error"}])},[C("button",{class:"head",type:"button",disabled:!w.value,"aria-label":p.value?f(n)("tasks.openDetail"):void 0,"aria-expanded":p.value?void 0:y.value,onClick:b},[C("span",Pke,[U(f(ve),{name:"robot",size:"sm"})]),C("span",jke,[C("span",Hke,D(a.value),1),m.value?(v(),E("span",Wke,D(m.value),1)):X("",!0)]),C("span",qke,[C("span",{class:Fe(["st",l.value]),role:"status","aria-label":l.value},[l.value==="ok"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):l.value==="error"?(v(),ce(f(ve),{key:1,name:"close",size:"sm"})):(v(),ce(f(ml),{key:2,status:"running"}))],10,Uke),p.value?(v(),ce(f(ve),{key:0,class:"go",name:"arrow-right",size:"sm","aria-hidden":"true"})):k.value?(v(),ce(f(ve),{key:1,class:Fe(["go car",{open:y.value}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"])):X("",!0)])],8,Oke),p.value&&k.value?(v(),E("button",{key:0,class:"saved-result",type:"button","aria-expanded":y.value,onClick:T[0]||(T[0]=S=>y.value=!y.value)},[U(f(ve),{class:Fe(["saved-result__chevron",{open:y.value}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"]),C("span",null,D(f(n)("tools.output.saved")),1)],8,Kke)):X("",!0),k.value&&y.value?(v(),E("div",{key:1,class:Fe(["result",{"result--legacy":!p.value}])},[U(Xr,{lines:e.tool.output},null,8,["lines"])],2)):X("",!0)],2))}}),Zke=kt(Vke,[["__scopeId","data-v-ab8f0011"]]);function Gke(e){if(!e)return[];try{const n=JSON.parse(e).questions;if(!Array.isArray(n))return[];const i=[];for(const o of n){if(!o||typeof o!="object")continue;const s=o,r=Array.isArray(s.options)?s.options.map(l=>{const a=l&&typeof l=="object"?l:{};return{label:typeof a.label=="string"?a.label:"",description:typeof a.description=="string"?a.description:""}}):[];i.push({question:typeof s.question=="string"?s.question:"",header:typeof s.header=="string"?s.header:"",options:r,multiSelect:s.multi_select===!0})}return i}catch{return[]}}const Rm={recognized:!1,answers:{},note:""};function Qke(e){const t=e?.[0];if(!t)return Rm;let n;try{n=JSON.parse(t)}catch{return Rm}if(!n||typeof n!="object"||Array.isArray(n))return Rm;const i=n.answers;if(!i||typeof i!="object"||Array.isArray(i))return Rm;const o={};for(const[s,r]of Object.entries(i))typeof r=="string"?o[s]=r:r===!0&&(o[s]=!0);return{recognized:!0,answers:o,note:typeof n.note=="string"?n.note:""}}function Yke(e,t,n){return e[t]??e[`q_${n}`]}const Jke=/^opt_\d+_(\d+)$/;function Xke(e,t=[]){if(e===void 0)return{selected:new Set,otherText:"",indeterminate:!1};if(e===!0)return{selected:new Set,otherText:"",indeterminate:!0};const n=new Map;t.forEach((r,l)=>{r.label.length>0&&!n.has(r.label)&&n.set(r.label,l)});const i=n.get(e);if(i!==void 0)return{selected:new Set([i]),otherText:"",indeterminate:!1};const o=new Set,s=[];for(const r of e.split(",")){const l=r.trim(),a=n.get(l);if(a!==void 0){o.add(a);continue}const u=Jke.exec(l);u?o.add(Number(u[1])):l.length>0&&s.push(l)}return{selected:o,otherText:s.join(", "),indeterminate:!1}}const ebe={class:"tl-ic","aria-hidden":"true"},tbe={class:"tl-main"},nbe=["aria-expanded","aria-label"],ibe={class:"tl-tail"},obe=["aria-label"],sbe=["inert"],rbe={class:"tl-body-inner"},lbe=Xe({__name:"ToolDisclosure",props:{status:{},open:{type:Boolean,default:!1},expandable:{type:Boolean,default:!1}},emits:["toggle"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=hn("pinScroll",()=>{}),r=K(null);function l(){if(!n.expandable)return;i("toggle");const u=r.value;u&&dt(()=>s(u))}const a=F(()=>n.open?o("tools.disclosure.collapse"):o("tools.disclosure.expand"));return(u,c)=>(v(),E("div",{class:Fe(["tool-line",{open:e.open,expandable:e.expandable,err:e.status==="error"}])},[C("div",{ref_key:"headEl",ref:r,class:Fe(["tl-head",{clickable:e.expandable}]),onClick:l},[C("span",ebe,[Rn(u.$slots,"leading")]),C("span",tbe,[Rn(u.$slots,"default"),U(f(gn),{text:a.value},{default:de(()=>[e.expandable?(v(),E("button",{key:0,class:"tl-car",type:"button","aria-expanded":e.open,"aria-label":a.value,onClick:wt(l,["stop"])},[U(f(ve),{class:"tl-car-ic",name:"chevron-right",size:"sm","aria-hidden":"true"})],8,nbe)):X("",!0)]),_:1},8,["text"])]),C("span",ibe,[Rn(u.$slots,"trailing"),C("span",{class:Fe(["tl-status",e.status]),role:"status","aria-label":e.status},[e.status==="ok"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):e.status==="error"?(v(),ce(f(ve),{key:1,name:"close",size:"sm"})):e.status==="suspended"?(v(),ce(f(ml),{key:2,status:"suspended"})):(v(),ce(f(ml),{key:3,status:"running"}))],10,obe)])],2),e.expandable?(v(),E("div",{key:0,class:Fe(["tl-body",{open:e.open}]),inert:!e.open},[C("div",rbe,[Rn(u.$slots,"body")])],10,sbe)):X("",!0)],2))}}),Pl=kt(lbe,[["__scopeId","data-v-6e9ab5f9"]]),abe={key:0,class:"rc-flat"},ube={class:"rc-head"},cbe={class:"rc-st"},dbe={class:"rc-qtext"},fbe={class:"rc-lb"},hbe={key:0,class:"rc-opt"},pbe={class:"rc-lb"},gbe={class:"rc-ds"},mbe={key:1,class:"rc-opt"},vbe={class:"rc-lb"},ybe={key:2,class:"rc-qskip"},kbe={class:"tl-name"},bbe={key:0,class:"tl-dim"},Abe={key:0,class:"tl-chip"},Cbe=80,wbe=Xe({__name:"AskUserTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile"],setup(e){const t=e,{t:n}=zt();function i(x,_=Cbe){const L=x.trim();return L.length>_?L.slice(0,_-1)+"…":L}const o=F(()=>Gke(t.tool.arg)),s=F(()=>Qke(t.tool.output)),r=F(()=>s.value.recognized),l=F(()=>r.value&&Object.keys(s.value.answers).length===0&&s.value.note.length>0),a=F(()=>o.value.map((x,_)=>Xke(Yke(s.value.answers,x.question,_),x.options))),u=F(()=>Object.keys(s.value.answers).length);function c(x,_){return a.value[x]?.selected.has(_)??!1}function d(x){return a.value[x]?.otherText??""}function h(x){return a.value[x]?.indeterminate??!1}const p=F(()=>t.tool.status),g=F(()=>o.value.map((x,_)=>({q:x,selected:x.options.map((L,M)=>({o:L,oi:M})).filter(({oi:L})=>c(_,L))}))),m=F(()=>o.value.length===1?n("tools.ask.question",{count:1}):n("tools.ask.questions",{count:o.value.length})),k=F(()=>{const x=o.value[0]?.question??"",_=n("tools.ask.unanswered");return x?`${x} —— ${_}`:_}),w=F(()=>{if(!r.value)return i(t.tool.output?.[0]??"");if(l.value)return n("tools.ask.dismissed");const x=o.value[0]?.question??"",_=i(x);return o.value.length<=1?_:`${_} ${n("tools.ask.more",{count:o.value.length-1})}`}),y=F(()=>r.value?l.value?n("tools.ask.dismissed"):u.value===0?"":u.value===1?n("tools.ask.answer",{count:1}):n("tools.ask.answers",{count:u.value}):""),b=F(()=>!!t.tool.output&&t.tool.output.length>0),A=F(()=>r.value&&(o.value.length>0||l.value)||b.value),T=K(t.tool.defaultExpanded===!0&&A.value),S=F(()=>Cf(t.tool.name));return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&A.value&&(T.value=!0)}),(x,_)=>r.value&&p.value==="ok"?(v(),E("div",{key:0,class:Fe(["ask-receipt",{flat:l.value||u.value===0}])},[l.value||u.value===0?(v(),E("span",abe,D(k.value),1)):(v(),E(Ee,{key:1},[C("div",ube,[C("span",null,D(f(n)("tools.ask.collected"))+" · "+D(m.value),1),C("span",cbe,[U(f(ve),{name:"check",size:"sm"})])]),(v(!0),E(Ee,null,pt(g.value,(L,M)=>(v(),E("div",{key:M,class:"rc-q"},[C("div",dbe,[C("span",null,D(L.q.question),1)]),(v(!0),E(Ee,null,pt(L.selected,N=>(v(),E("div",{key:N.oi,class:"rc-opt"},[C("span",{class:Fe(["rc-g on",L.q.multiSelect?"chk":"rad"])},null,2),C("span",fbe,D(N.o.label),1)]))),128)),d(M)?(v(),E("div",hbe,[C("span",{class:Fe(["rc-g on",L.q.multiSelect?"chk":"rad"])},null,2),C("span",pbe,D(d(M)),1),C("span",gbe,D(f(n)("tools.ask.freeInput")),1)])):X("",!0),h(M)?(v(),E("div",mbe,[_[1]||(_[1]=C("span",{class:"rc-g rad on"},null,-1)),C("span",vbe,D(f(n)("tools.ask.answered")),1)])):X("",!0),L.selected.length===0&&!d(M)&&!h(M)?(v(),E("div",ybe,D(f(n)("tools.ask.unanswered")),1)):X("",!0)]))),128))],64))],2)):(v(),ce(Pl,{key:1,status:p.value,open:T.value,expandable:A.value,onToggle:_[0]||(_[0]=L=>T.value=!T.value)},{leading:de(()=>[U(f(ve),{name:"help-circle",size:"sm"})]),trailing:de(()=>[y.value?(v(),E("span",Abe,D(y.value),1)):X("",!0)]),body:de(()=>[U(Xr,{lines:e.tool.output},null,8,["lines"])]),default:de(()=>[C("span",kbe,D(S.value),1),w.value?(v(),E("span",bbe,D(w.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),xbe=kt(wbe,[["__scopeId","data-v-f29eda04"]]);function Nu(e){const t=(e??"").trim();if(!t.startsWith("{"))return null;try{const n=JSON.parse(t);return n&&typeof n=="object"&&!Array.isArray(n)?n:null}catch{return null}}function ri(e){return typeof e=="string"&&e.length>0?e:void 0}function Xu(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function wR(e){if(e)return ri(e.path)??ri(e.file_path)??ri(e.filePath)??ri(e.filename)}function xR(e){return/^(.*)[\\/][^\\/]+[\\/]?$/.exec(e)?.[1]??""}function Sbe(e){try{const t=new URL(e),n=t.pathname.split("/").filter(Boolean)[0];return n?`${t.host}/${n}`:t.host}catch{return e.replace(/^https?:\/\//,"")}}const _be={class:"tl-name"},Mbe={class:"tl-mono"},Ibe={key:0,class:"tl-chip"},Ebe={class:"cmd-echo"},Tbe=Xe({__name:"BashTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.tool.status),o=F(()=>{const u=Nu(t.tool.arg);return(ri(u?.command)??ri(u?.cmd)??ri(u?.script)??t.tool.arg.replace(/^·\s*/,"")).trim()}),s=F(()=>t.tool.status==="running"),r=F(()=>!!t.tool.output&&t.tool.output.length>0),l=F(()=>r.value||s.value||o.value.length>0),a=K(t.tool.defaultExpanded===!0&&l.value);return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&l.value&&(a.value=!0)}),(u,c)=>(v(),ce(Pl,{status:i.value,open:a.value,expandable:l.value,onToggle:c[0]||(c[0]=d=>a.value=!a.value)},{leading:de(()=>[U(f(ve),{name:"terminal",size:"sm"})]),trailing:de(()=>[e.tool.timing?(v(),E("span",Ibe,D(e.tool.timing),1)):X("",!0)]),body:de(()=>[C("div",Ebe,D(o.value),1),U(Xr,{lines:e.tool.output,"empty-text":s.value?f(n)("tools.output.waiting"):f(n)("tools.output.empty")},null,8,["lines","empty-text"])]),default:de(()=>[C("span",_be,D(f(n)("tools.label.bash")),1),C("span",Mbe,D(o.value),1)]),_:1},8,["status","open","expandable"]))}}),Lbe=kt(Tbe,[["__scopeId","data-v-8869dd42"]]),Nbe={class:"hl-body"},Fbe={key:0,class:"hl-gutter"},Dbe={key:1,class:"hl-gutter new"},Bbe={class:"hl-sign"},$be={class:"hl-text"},Rbe=["data-line"],zbe={key:0,class:"hl-gutter"},Obe={class:"hl-text"},Pbe=200,jbe=Xe({__name:"HighlightedCode",props:{code:{default:void 0},lines:{default:void 0},path:{default:void 0},lineNumbers:{type:[Boolean,Array],default:!1},framed:{type:Boolean,default:!0},fullTexts:{default:null},lineClass:{type:Function,default:void 0}},setup(e){const t=e,n=a9(),i=F(()=>Tre(t.path)),o=F(()=>t.lines!==void 0),s=F(()=>t.lineNumbers===!0&&o.value),r=F(()=>(t.lines??[]).some(z=>z.oldNo!==void 0)),l=F(()=>(t.lines??[]).some(z=>z.newNo!==void 0)),a=F(()=>Array.isArray(t.lineNumbers)?t.lineNumbers:null),u=F(()=>Array.isArray(t.code)?t.code:Ha(t.code??"")),c=F(()=>{const z=t.lines;return z?t.fullTexts?t.fullTexts:{before:z.filter(H=>H.oldNo!==void 0).map(H=>H.text).join(` -`),after:z.filter(H=>H.newNo!==void 0).map(H=>H.text).join(` -`)}:null}),d=K(null),h=K(null),p=K(null);function g(){d.value=null,h.value=null,p.value=null}let m=null,k=0,w=0;async function y(){const z=++w;k=Date.now();const H=i.value;if(!H){z===w&&g();return}try{const{codeToTokens:O}=await Fo(async()=>{const{codeToTokens:$}=await import("./index-O6aQX5k9.js").then(W=>W.i);return{codeToTokens:$}},[]),R=n.value?"github-dark":"github-light",j=c.value;if(j){const[$,W]=await Promise.all([j.before?O(j.before,{lang:H,theme:R}):Promise.resolve(null),j.after?O(j.after,{lang:H,theme:R}):Promise.resolve(null)]);if(z!==w)return;h.value=$?.tokens??null,p.value=W?.tokens??null}else{const $=u.value.length>0?await O(u.value.join(` -`),{lang:H,theme:R}):null;if(z!==w)return;d.value=$?.tokens??null}}catch{z===w&&g()}}function b(){if(m!==null)return;const z=Math.max(0,Pbe-(Date.now()-k));m=setTimeout(()=>{m=null,y()},z)}const A=F(()=>u.value.join(` -`)),T=F(()=>c.value?.before??null),S=F(()=>c.value?.after??null);Pe([A,T,S],b),Pe([i,n,()=>t.fullTexts],()=>{w++,g(),b()}),cn(y),_n(()=>{w++,m!==null&&clearTimeout(m),m=null});const x=F(()=>{let z=0;if(Array.isArray(t.lineNumbers))for(const H of t.lineNumbers)H>z&&(z=H);else for(const H of t.lines??[])H.oldNo!==void 0&&H.oldNo>z&&(z=H.oldNo),H.newNo!==void 0&&H.newNo>z&&(z=H.newNo);return Math.max(4,String(z).length)});function _(z){if(z.type==="del"){if(z.oldNo===void 0)return null;const O=t.fullTexts?z.oldNo-1:L.value.get(z.oldNo);return O===void 0?null:h.value?.[O]??null}if(z.newNo===void 0)return null;const H=t.fullTexts?z.newNo-1:M.value.get(z.newNo);return H===void 0?null:p.value?.[H]??null}const L=F(()=>{const z=new Map;let H=0;for(const O of t.lines??[])O.oldNo!==void 0&&z.set(O.oldNo,H++);return z}),M=F(()=>{const z=new Map;let H=0;for(const O of t.lines??[])O.newNo!==void 0&&z.set(O.newNo,H++);return z});function N(z){const H={};z.color&&(H.color=z.color);const O=z.fontStyle??0;return O&1&&(H.fontStyle="italic"),O&2&&(H.fontWeight="var(--weight-semibold)"),O&4&&(H.textDecoration="underline"),H}function I(z){return z.type==="add"?"+":z.type==="del"?"-":" "}return(z,H)=>(v(),E("div",{class:Fe(["hl-code",{gutter:s.value,"plain-pad":!o.value&&!a.value,framed:e.framed}]),style:Kt({"--gutter-ch":`${x.value}ch`})},[C("div",Nbe,[o.value?(v(!0),E(Ee,{key:0},pt(e.lines??[],(O,R)=>(v(),E("div",{key:R,class:Fe(["hl-row",`row-${O.type}`])},[s.value?(v(),E(Ee,{key:0},[r.value?(v(),E("span",Fbe,D(O.oldNo??""),1)):X("",!0),l.value?(v(),E("span",Dbe,D(O.newNo??""),1)):X("",!0)],64)):X("",!0),C("span",Bbe,D(I(O)),1),C("span",$be,[_(O)?(v(!0),E(Ee,{key:0},pt(_(O)??[],(j,$)=>(v(),E("span",{key:$,style:Kt(N(j))},D(j.content),5))),128)):(v(),E(Ee,{key:1},[$e(D(O.text),1)],64))])],2))),128)):(v(!0),E(Ee,{key:1},pt(u.value,(O,R)=>(v(),E("div",{key:R,class:Fe(["hl-row",e.lineClass?.(a.value?.[R]??-1)]),"data-line":a.value?.[R]},[a.value?(v(),E("span",zbe,D(a.value[R]??""),1)):X("",!0),C("span",Obe,[d.value?.[R]?(v(!0),E(Ee,{key:0},pt(d.value[R]??[],(j,$)=>(v(),E("span",{key:$,style:Kt(N(j))},D(j.content),5))),128)):(v(),E(Ee,{key:1},[$e(D(O),1)],64))])],10,Rbe))),128))])],6))}}),oa=kt(jbe,[["__scopeId","data-v-6735e4da"]]),Hbe={class:"tl-name"},Wbe={key:1,class:"tl-dim"},qbe={key:2,class:"tl-faint"},Ube={key:0,class:"tl-add"},Kbe={key:1,class:"tl-del"},Vbe={class:"diffbar","aria-hidden":"true"},Zbe={key:1,class:"tl-chip"},Gbe=Xe({__name:"EditTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.tool.status),r=F(()=>Gs(n.tool.name)==="write"),l=F(()=>wR(Nu(n.tool.arg))??""),a=F(()=>l.value?Tu(l.value):""),u=F(()=>l.value?xR(l.value):""),c=F(()=>fB(n.tool)),d=F(()=>rre(n.tool)),h=F(()=>{const T=c.value;return!T||n.tool.status==="error"?{added:0,removed:0}:rB(T)}),p=F(()=>h.value.added>0||h.value.removed>0),g=F(()=>!!n.tool.output&&n.tool.output.length>0),m=F(()=>c.value!==null&&n.tool.status!=="error"),k=F(()=>d.value!==null&&n.tool.status!=="error"),w=F(()=>m.value||k.value||g.value),y=K(!1),b=K(y.value);Pe(y,T=>{T&&(b.value=!0)});function A(){l.value&&i("openFile",{path:l.value})}return(T,S)=>(v(),ce(Pl,{status:s.value,open:y.value,expandable:w.value,onToggle:S[0]||(S[0]=x=>y.value=!y.value)},{leading:de(()=>[U(f(ve),{name:r.value?"file-plus":"pencil",size:"sm"},null,8,["name"])]),trailing:de(()=>[p.value?(v(),E(Ee,{key:0},[h.value.added>0?(v(),E("span",Ube,"+"+D(h.value.added),1)):X("",!0),h.value.removed>0?(v(),E("span",Kbe,"−"+D(h.value.removed),1)):X("",!0),C("span",Vbe,[C("span",{class:"seg-add",style:Kt({flexGrow:h.value.added})},null,4),C("span",{class:"seg-del",style:Kt({flexGrow:h.value.removed})},null,4)])],64)):r.value&&s.value==="ok"?(v(),E("span",Zbe,D(f(o)("tools.chip.created")),1)):X("",!0)]),body:de(()=>[m.value&&b.value?(v(),ce(oa,{key:0,lines:c.value??[],path:l.value},null,8,["lines","path"])):k.value&&b.value?(v(),ce(oa,{key:1,code:d.value?.content??"",path:d.value?.path},null,8,["code","path"])):(v(),ce(Xr,{key:2,lines:e.tool.output,"empty-text":f(o)("tools.output.waiting")},null,8,["lines","empty-text"]))]),default:de(()=>[C("span",Hbe,D(r.value?f(o)("tools.label.write"):f(o)("tools.label.edit")),1),a.value?(v(),E("button",{key:0,class:"tl-file",type:"button",onClick:wt(A,["stop"])},D(a.value),1)):(v(),E("span",Wbe,D(l.value||e.tool.arg),1)),u.value?(v(),E("span",qbe,D(u.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),Qbe=kt(Gbe,[["__scopeId","data-v-bbf61950"]]),Ybe=["innerHTML"],Jbe={class:"tl-name"},Xbe={key:0,class:"tl-dim"},e8e={key:0,class:"tl-chip"},t8e={key:1,class:"tl-chip"},n8e={key:0,class:"arg-full"},i8e=Xe({__name:"GenericTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile"],setup(e){const t=e,{t:n}=zt(),i=F(()=>t.tool.status),o=F(()=>Cf(t.tool.name)),s=F(()=>CR(t.tool.name)),r=F(()=>Z_(t.tool.name,t.tool.arg)),l=F(()=>Z_(t.tool.name,t.tool.arg,!0)),a=F(()=>Dke({name:t.tool.name,arg:t.tool.arg,output:t.tool.output,timing:t.tool.timing,status:t.tool.status})),u=F(()=>!!t.tool.output&&t.tool.output.length>0),c=F(()=>u.value||!!l.value&&l.value!==r.value),d=K(t.tool.defaultExpanded===!0&&c.value);return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status,t.tool.name],()=>{t.tool.defaultExpanded===!0&&c.value&&(d.value=!0)}),(h,p)=>(v(),ce(Pl,{status:i.value,open:d.value,expandable:c.value,onToggle:p[0]||(p[0]=g=>d.value=!d.value)},{leading:de(()=>[C("span",{class:"gl",innerHTML:s.value},null,8,Ybe)]),trailing:de(()=>[a.value?(v(),E("span",e8e,D(a.value),1)):e.tool.timing?(v(),E("span",t8e,D(e.tool.timing),1)):X("",!0)]),body:de(()=>[l.value&&l.value!==r.value?(v(),E("div",n8e,D(l.value),1)):X("",!0),U(Xr,{lines:e.tool.output,"empty-text":i.value==="running"?f(n)("tools.output.waiting"):f(n)("tools.output.empty")},null,8,["lines","empty-text"])]),default:de(()=>[C("span",Jbe,D(o.value),1),r.value?(v(),E("span",Xbe,D(r.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),o8e=kt(i8e,[["__scopeId","data-v-b12a8498"]]),s8e={class:"tl-name"},r8e={key:0,class:"tl-mono"},l8e={key:1,class:"tl-mono"},a8e={key:2,class:"tl-dim"},u8e={key:3,class:"tl-faint"},c8e={key:0,class:"tl-chip"},d8e={key:0,class:"file-list"},f8e=["onClick"],h8e=Xe({__name:"GlobTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.tool.status),r=F(()=>Gs(n.tool.name)==="glob"),l=F(()=>Nu(n.tool.arg)),a=F(()=>{const m=l.value;return ri(m?.pattern)??ri(m?.glob)??ri(m?.query)??""}),u=F(()=>{const m=l.value;return ri(m?.path)??ri(m?.dir)??ri(m?.directory)??ri(m?.cwd)??""}),c=F(()=>(n.tool.output??[]).filter(m=>m.trim().length>0)),d=F(()=>c.value.length>0),h=F(()=>d.value),p=K(n.tool.defaultExpanded===!0&&h.value);Pe(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&h.value&&(p.value=!0)});function g(m){const k=m.trim();k&&i("openFile",{path:k})}return(m,k)=>(v(),ce(Pl,{status:s.value,open:p.value,expandable:h.value,onToggle:k[0]||(k[0]=w=>p.value=!p.value)},{leading:de(()=>[U(f(ve),{name:r.value?"tree-view":"list",size:"sm"},null,8,["name"])]),trailing:de(()=>[r.value&&c.value.length>0?(v(),E("span",c8e,D(f(o)("tools.chip.files",{count:c.value.length})),1)):X("",!0)]),body:de(()=>[r.value?(v(),E("div",d8e,[(v(!0),E(Ee,null,pt(c.value,(w,y)=>(v(),E("button",{key:y,class:"file-row",type:"button",onClick:b=>g(w)},D(w),9,f8e))),128))])):(v(),ce(Xr,{key:1,lines:e.tool.output},null,8,["lines"]))]),default:de(()=>[C("span",s8e,D(f(o)(r.value?"tools.label.glob":"tools.label.ls")),1),r.value&&a.value?(v(),E("span",r8e,D(a.value),1)):!r.value&&u.value?(v(),E("span",l8e,D(u.value),1)):(v(),E("span",a8e,D(e.tool.arg),1)),r.value&&u.value?(v(),E("span",u8e,D(u.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),p8e=kt(h8e,[["__scopeId","data-v-3936099e"]]),g8e={class:"tl-name"},m8e={key:0,class:"tl-dim"},v8e={key:1,class:"tl-pill pill-active"},y8e={key:0,class:"goal-block"},k8e={class:"goal-text"},b8e={key:0,class:"goal-criterion"},A8e=Xe({__name:"GoalTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.tool.status),o=F(()=>Gs(t.tool.name)),s=F(()=>Nu(t.tool.arg)),r=F(()=>ri(s.value?.objective)??""),l=F(()=>ri(s.value?.completionCriterion)??ri(s.value?.completion_criterion)??""),a={active:"status.goalStatusActive",blocked:"status.goalStatusBlocked",complete:"status.goalStatusComplete"},u=F(()=>ri(s.value?.status)??""),c=F(()=>{const y=a[u.value];return y?n(y):u.value}),d=F(()=>{switch(u.value){case"complete":return"pill-done";case"blocked":return"pill-blocked";default:return"pill-active"}}),h=F(()=>{const y=Xu(s.value?.value),b=ri(s.value?.unit);return y===void 0||!b?"":["turns","tokens","milliseconds","seconds","minutes","hours"].includes(b)?n(`tools.goal.${b}`,{value:y}):n("tools.goal.budget",{value:y,unit:b})}),p=F(()=>{switch(o.value){case"creategoal":return r.value;case"updategoal":return c.value;case"setgoalbudget":return h.value;default:return""}}),g=F(()=>!!t.tool.output&&t.tool.output.length>0),m=F(()=>!!l.value||o.value==="creategoal"&&g.value),k=F(()=>m.value||g.value),w=K(t.tool.defaultExpanded===!0&&k.value);return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&k.value&&(w.value=!0)}),(y,b)=>(v(),ce(Pl,{status:i.value,open:w.value,expandable:k.value,onToggle:b[0]||(b[0]=A=>w.value=!w.value)},{leading:de(()=>[U(f(ve),{name:"target",size:"sm"})]),trailing:de(()=>[o.value==="updategoal"&&c.value?(v(),E("span",{key:0,class:Fe(["tl-pill",d.value])},D(c.value),3)):o.value==="creategoal"?(v(),E("span",v8e,D(f(n)("status.goalStatusActive")),1)):X("",!0)]),body:de(()=>[r.value?(v(),E("div",y8e,[C("div",k8e,D(r.value),1),l.value?(v(),E("div",b8e,D(l.value),1)):X("",!0)])):X("",!0),g.value?(v(),ce(Xr,{key:1,lines:e.tool.output},null,8,["lines"])):X("",!0)]),default:de(()=>[C("span",g8e,D(f(Cf)(e.tool.name)),1),p.value?(v(),E("span",m8e,D(p.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),C8e=kt(A8e,[["__scopeId","data-v-862274de"]]),w8e={class:"tl-name"},x8e={key:0,class:"tl-mono"},S8e={key:1,class:"tl-dim"},_8e={key:2,class:"tl-faint"},M8e={key:0,class:"tl-chip"},I8e={key:0,class:"match-list"},E8e=["onClick"],T8e={key:0,class:"mref"},L8e={class:"mtext"},N8e=Xe({__name:"GrepTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.tool.status),r=F(()=>Gs(n.tool.name)==="grep"),l=F(()=>Nu(n.tool.arg)),a=F(()=>{const k=l.value;return ri(k?.pattern)??ri(k?.query)??ri(k?.regex)??""}),u=F(()=>{const k=l.value;return ri(k?.path)??ri(k?.glob)??ri(k?.include)??""}),c=F(()=>(n.tool.output??[]).filter(k=>k.trim().length>0).map(k=>{const w=/^(.+?):(\d+)[:-](.*)$/.exec(k);return w?{path:w[1],line:Number(w[2]),text:(w[3]??"").trim()}:{text:k}})),d=F(()=>c.value.length),h=F(()=>d.value>0),p=F(()=>h.value),g=K(n.tool.defaultExpanded===!0&&p.value);Pe(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&p.value&&(g.value=!0)});function m(k){k.path&&i("openFile",{path:k.path,line:k.line})}return(k,w)=>(v(),ce(Pl,{status:s.value,open:g.value,expandable:p.value,onToggle:w[0]||(w[0]=y=>g.value=!g.value)},{leading:de(()=>[U(f(ve),{name:"search",size:"sm"})]),trailing:de(()=>[d.value>0?(v(),E("span",M8e,D(f(o)("tools.chip.results",{count:d.value})),1)):X("",!0)]),body:de(()=>[r.value?(v(),E("div",I8e,[(v(!0),E(Ee,null,pt(c.value,(y,b)=>(v(),E("button",{key:b,class:Fe(["match-row",{link:y.path}]),type:"button",onClick:A=>m(y)},[y.path?(v(),E("span",T8e,D(y.path)+":"+D(y.line),1)):X("",!0),C("span",L8e,D(y.text),1)],10,E8e))),128))])):(v(),ce(Xr,{key:1,lines:e.tool.output},null,8,["lines"]))]),default:de(()=>[C("span",w8e,D(f(o)(r.value?"tools.label.grep":"tools.label.search")),1),a.value?(v(),E("span",x8e,D(a.value),1)):(v(),E("span",S8e,D(e.tool.arg),1)),u.value?(v(),E("span",_8e,D(u.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),F8e=kt(N8e,[["__scopeId","data-v-899c1a48"]]),D8e=["app:load:start","app:load:complete","export:start","export:accepted","export:failed","prompt:start","prompt:accepted","prompt:failed","session:snapshot:start","session:snapshot:accepted","session:snapshot:failed","operation:failed","window:error","window:unhandled-rejection","ws:connection","ws:error","ws:resync","ws:stale-reconnect"],SR=500,W2=256*1024,G_=200,M3=16384,I3=500,E3=50,T3=50,B8e=6,$8e=/api[_-]?key|authorization|token|secret|password|cookie|credential|email|phone|nickname|avatar/i,R8e=/^[A-Za-z0-9+/=_-]{200,}$/;let L3=null;function ga(){if(L3!==null)return L3;let e=!1;try{if(typeof location<"u"){const t=new URLSearchParams(location.search).get("debug");(t==="1"||t==="true")&&(e=!0)}}catch{}return e||(e=gs(un.debug)==="1"),L3=e,e}const gc=[],mh=[];let kp=0;const Ld=[];let bp=0,z8e=1;const q2=new TextEncoder,O8e=new Set(D8e),o7=K(0),Ap=ha(!1);function P8e(){return gc}function j8e(){gc.length=0,mh.length=0,kp=0,Ld.length=0,bp=0,o7.value++}function Fu(e){if(!Ap.value){try{const t={id:z8e++,ts:Date.now(),source:e.source,kind:String(Dh(e.kind)),label:String(Dh(e.label)),sessionId:e.sessionId===void 0?void 0:String(Dh(e.sessionId)),method:e.method,path:e.path,eventType:e.eventType,seq:e.seq,offset:e.offset,status:e.status,code:e.code,requestId:e.requestId,durationMs:e.durationMs,detail:Zc(e.detail)},n=JSON.stringify(t),i=q2.encode(n).byteLength;if(i>W2)return;for(gc.push(t),mh.push(n),kp+=i+(mh.length>1?1:0);gc.length>SR||kp>W2;){const o=mh.shift();gc.shift(),o!==void 0&&(kp-=q2.encode(o).byteLength,mh.length>0&&(kp-=1))}}catch{return}o7.value++}}function gd(e){if(typeof e=="string")return e.length<=G_?e:e.slice(0,G_)}function Sl(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function H8e(e,t){if(O8e.has(e))try{const n={ts:Date.now(),event:e,sessionId:gd(t?.sessionId),status:gd(t?.status),operation:gd(t?.operation),seq:Sl(t?.seq),durationMs:Sl(t?.durationMs),messageCount:Sl(t?.messageCount),contentCount:Sl(t?.contentCount),mediaCount:Sl(t?.mediaCount),sessionCount:Sl(t?.sessionCount),workspaceCount:Sl(t?.workspaceCount),promptId:gd(t?.promptId),zipBytes:Sl(t?.zipBytes),errorName:gd(t?.errorName),errorCode:Sl(t?.errorCode),requestId:gd(t?.requestId),phase:gd(t?.phase),httpStatus:Sl(t?.httpStatus),fatal:typeof t?.fatal=="boolean"?t.fatal:void 0,line:Sl(t?.line),col:Sl(t?.col)},i=JSON.stringify(n),o=q2.encode(i).byteLength;if(o>W2)return;for(Ld.push(i),bp+=o+(Ld.length>1?1:0);Ld.length>SR||bp>W2;){const s=Ld.shift();s!==void 0&&(bp-=q2.encode(s).byteLength,Ld.length>0&&(bp-=1))}}catch{return}}function Dh(e,t=0){if(e==null)return e;const n=typeof e;if(n==="number"||n==="boolean")return e;if(n==="string"){const s=e;return R8e.test(s)?`[base64-like, ${s.length} chars omitted]`:s.length>I3?`${s.slice(0,I3)}… [+${s.length-I3} chars]`:s}if(n!=="object")return String(e);if(t>=B8e)return"[max depth]";if(Array.isArray(e)){const s=e.slice(0,E3).map(r=>Dh(r,t+1));return e.length>E3&&s.push(`[+${e.length-E3} more items]`),s}const i={},o=Object.entries(e);for(const[s,r]of o.slice(0,T3))i[s]=$8e.test(s)?"[redacted]":Dh(r,t+1);return o.length>T3&&(i._truncatedKeys=o.length-T3),i}function Zc(e){if(e===void 0)return;const t=Dh(e);try{const n=JSON.stringify(t);if(n!==void 0&&n.length>M3)return{_truncated:`detail JSON was ${n.length} chars; first ${M3} kept`,preview:n.slice(0,M3)}}catch{return"[unserializable detail]"}return t}function W8e(e){ga()&&Fu({source:"rest",kind:"rest:request",label:`→ ${e.method} ${e.path}`,method:e.method,path:e.path,requestId:e.requestId,detail:{url:e.url,body:Zc(e.body)}})}function q8e(e){if(!ga())return;const t=e.code!==0;Fu({source:"rest",kind:t?"rest:error":"rest:response",label:`← ${e.method} ${e.path} ${e.status} code=${e.code}${t?` "${e.msg}"`:""} ${Math.round(e.durationMs)}ms`,method:e.method,path:e.path,requestId:e.requestId,status:e.status,code:e.code,durationMs:e.durationMs,detail:{envelope:{code:e.code,msg:e.msg,request_id:e.envelopeRequestId},data:Zc(e.data)}})}function U8e(e){ga()&&Fu({source:"rest",kind:"rest:error",label:`✕ ${e.method} ${e.path} ${e.phase} error${e.status!==void 0?` (HTTP ${e.status})`:""} ${Math.round(e.durationMs)}ms`,method:e.method,path:e.path,requestId:e.requestId,status:e.status,durationMs:e.durationMs,detail:{phase:e.phase,error:String(e.error)}})}function K8e(e,t){ga()&&Fu({source:"ws",kind:"ws:lifecycle",eventType:e,label:`ws ${e}`,detail:Zc(t)})}function V8e(e){if(!ga())return;const t=e??{},n=typeof t.type=="string"?t.type:"(unknown)",i=t.payload,o=typeof i?.session_id=="string"?i.session_id:void 0;Fu({source:"ws",kind:"ws:out",eventType:n,sessionId:o,label:`→ ${n}`,detail:Zc(e)})}function Z8e(e){if(!ga())return;const t=e??{},n=typeof t.type=="string"?t.type:"(unknown)",i=typeof t.session_id=="string"?t.session_id:typeof t.payload?.session_id=="string"?t.payload.session_id:void 0,o=typeof t.seq=="number"?t.seq:void 0,s=typeof t.offset=="number"?t.offset:void 0,r=[i,o!==void 0?`seq=${o}`:void 0,s!==void 0?`offset=${s}`:void 0,t.volatile===!0?"volatile":void 0].filter(Boolean);Fu({source:"ws",kind:"ws:in",eventType:n,sessionId:i,seq:o,offset:s,label:`← ${n}${r.length>0?` (${r.join(" ")})`:""}`,detail:Zc(t.payload)})}const G8e={error:"✕",warn:"⚠",info:"ℹ",debug:"·",log:"·"};function Q8e(e,t,n){ga()&&Fu({source:"client",kind:`client:${e}`,label:`${G8e[e]} ${t}`,detail:Zc(n)})}function Y8e(e,t){ga()&&Fu({source:"client",kind:"client:event",label:`· ${e}`,detail:Zc(t)})}function U2(e,t){H8e(e,t),Fu({source:"client",kind:"client:key",label:e,sessionId:typeof t?.sessionId=="string"?t.sessionId:void 0,seq:typeof t?.seq=="number"?t.seq:void 0,durationMs:typeof t?.durationMs=="number"?t.durationMs:void 0,detail:t})}let N3=!1,zm=null;function J8e(){if(N3)return()=>zm?.();N3=!0;const e=[];try{if(typeof window<"u"){const n=o=>{U2("window:error",{status:"failed",errorName:o.error instanceof Error?o.error.name:"Error",line:o.lineno,col:o.colno}),fu(`[kimi-web] window error: ${o.message}`,o.error instanceof Error?o.error.stack:void 0)},i=o=>{const s=o.reason;U2("window:unhandled-rejection",{status:"failed",errorName:s instanceof Error?s.name:typeof s}),fu(`[kimi-web] unhandled rejection: ${e5e(s)}`,s instanceof Error?s.stack:void 0)};window.addEventListener("error",n),window.addEventListener("unhandledrejection",i),e.push(()=>{window.removeEventListener("error",n)}),e.push(()=>{window.removeEventListener("unhandledrejection",i)})}}catch{}if(ga())for(const n of["error","warn","log","info","debug"]){const i=console[n];if(typeof i!="function")continue;const o=(...s)=>{try{Q8e(n,s.map(X8e).join(" "),s.length>1?s:s[0])}catch{}i.apply(console,s)};console[n]=o,e.push(()=>{console[n]===o&&(console[n]=i)})}const t=()=>{if(zm===t){for(const n of e.toReversed())n();zm=null,N3=!1}};return zm=t,t}function X8e(e){if(typeof e=="string")return e;if(e instanceof Error)return`${e.name}: ${e.message}`;try{return JSON.stringify(e)}catch{return String(e)}}function e5e(e){if(e instanceof Error)return e.message;try{return String(e)}catch{return"[unstringifiable reason]"}}function _R(e=gc){if(typeof document>"u")return;const t=new Blob([t5e(e)],{type:"application/x-ndjson"}),n=URL.createObjectURL(t);let i;try{i=document.createElement("a"),i.href=n,i.download=`kimi-web-log-${new Date().toISOString().replaceAll(/[:.]/g,"-")}.jsonl`,document.body.append(i),i.click()}finally{i?.remove(),setTimeout(()=>{try{URL.revokeObjectURL(n)}catch{}},0)}}function t5e(e=gc){return e===gc?mh.join(` -`):e.map(t=>JSON.stringify(t)).join(` -`)}function n5e(){return Ld.join(` -`)}const Q_=un.clientId,i5e="kimi-code-web",o5e="web";function s5e(){return{serverHttpUrl:l5e(),clientId:u5e(),clientName:i5e,clientVersion:c5e(),clientUiMode:o5e}}function r5e(){return typeof window<"u"&&window.location?.origin?window.location.origin:"http://127.0.0.1:58627"}function l5e(){const e=MR();return x8(e||void 0)}const Y_="kimi-desktop-server-origin";function MR(){if(typeof window>"u")return;const e=new URLSearchParams(window.location.search).get("kimi_origin");try{return e?(window.sessionStorage.setItem(Y_,e),e):window.sessionStorage.getItem(Y_)??void 0}catch{return e??void 0}}function x8(e){const t=e&&e.trim()?e:r5e(),n=new URL(t);return n.pathname=n.pathname.replace(/\/v1\/?$/,"").replace(/\/$/,""),n.search="",n.hash="",n.toString().replace(/\/$/,"")}function J_(e){return e.replace(/^https?:\/\//,"").replace(/\/$/,"")}function a5e(){if(typeof window<"u"){const t=MR();if(t)return J_(x8(t))}const e=typeof window<"u"&&window.location?.origin?window.location.origin:"";return J_(e)}function u5e(){const e=gs(Q_);if(e)return e;const t=`web_${globalThis.crypto?.randomUUID?.()||Math.random().toString(36).slice(2)}`;return is(Q_,t),t}function c5e(){return"0.38.0".trim()?"0.38.0":"0.0.0-dev"}const d5e={restRequest:e=>W8e(e),restResponse:e=>q8e(e),restFailure:e=>U8e(e),wsEvent:e=>{switch(e.kind){case"lifecycle":K8e(e.event,e.detail);break;case"in":Z8e(e.frame);break;case"out":V8e(e.frame);break}},traceKeyEvent:(e,t)=>U2(e,t)},f5e={getToken:tae,markAuthRequired:sae},h5e=(e,t)=>t===void 0?da.global.t(e):da.global.t(e,t);function p5e(){const e=s5e();return Soe({origin:e.serverHttpUrl,identity:{clientId:e.clientId,clientName:e.clientName,clientVersion:e.clientVersion,clientUiMode:e.clientUiMode},tracer:d5e,credentialStore:f5e,t:h5e})}const g5e=p5e();function Ic(){return g5e}const m5e=["src","controls","muted"],v5e=["src","alt"],y5e=Xe({__name:"AuthMedia",props:{url:{},kind:{},alt:{},fileId:{},sessionId:{},mediaClass:{default:"u-img"},controls:{type:Boolean,default:!0},muted:{type:Boolean,default:!1}},setup(e){const t=e,n=K(t.fileId?"":t.url),i=K(null),o=K(!t.fileId);let s=null,r=0,l=!1,a=null;function u(){s!==null&&(URL.revokeObjectURL(s),s=null)}async function c(){const d=++r;if(u(),!t.fileId){n.value=t.url;return}if(o.value)try{const h=t.sessionId?await Ic().getSessionMediaBlob(t.sessionId,t.fileId):await Ic().getFileBlob(t.fileId),p=URL.createObjectURL(h);if(l||d!==r){URL.revokeObjectURL(p);return}s=p,n.value=s}catch{if(l||d!==r)return;n.value=t.url}}return Pe(()=>[t.fileId,t.sessionId,t.url,o.value],c,{immediate:!0}),cn(()=>{typeof IntersectionObserver=="function"&&i.value?(a=new IntersectionObserver(d=>{d[0]?.isIntersecting&&(o.value=!0,a?.disconnect(),a=null)},{rootMargin:"200px"}),a.observe(i.value)):o.value=!0}),Hn(()=>{l=!0,a?.disconnect(),a=null,u()}),(d,h)=>e.kind==="video"?(v(),E("video",{key:0,ref_key:"mediaEl",ref:i,class:Fe(e.mediaClass),src:n.value||void 0,controls:e.controls,muted:e.muted,playsinline:"",preload:"metadata"},null,10,m5e)):(v(),E("img",{key:1,ref_key:"mediaEl",ref:i,class:Fe([e.mediaClass,{"is-resolving":!n.value}]),src:n.value||void 0,alt:e.alt||"",loading:"lazy"},null,10,v5e))}}),hg=kt(y5e,[["__scopeId","data-v-23acd4fa"]]),k5e={class:"media-title"},b5e=["src","alt"],A5e=["aria-label"],C5e={key:0,class:"media-video-tile","aria-hidden":"true"},w5e={class:"media-play-badge","aria-hidden":"true"},x5e=["src"],S5e=Xe({__name:"MediaTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia"],setup(e,{emit:t}){const n=e,i=t,o=F(()=>n.tool.status==="ok"?n.tool.media:void 0);function s(d){return d.split(/[\\/]+/).pop()||d}function r(d){return d<1024?`${d} B`:d<1024*1024?`${(d/1024).toFixed(1)} KB`:`${(d/1024/1024).toFixed(1)} MB`}const l=F(()=>{const d=o.value;if(!d)return"";const h=[d.path?s(d.path):n.tool.name];return d.mimeType&&h.push(d.mimeType),d.bytes!==void 0&&h.push(r(d.bytes)),d.dimensions&&h.push(d.dimensions),h.join(" · ")}),a=F(()=>o.value?.url.startsWith("blob:")??!1),u=F(()=>{const d=o.value;return d?.kind==="video"&&d.fileId!==void 0&&!a.value});function c(d){const h=o.value;if(h?.kind!=="image"&&h?.kind!=="video")return;const p=h.kind==="image"?d.currentTarget.querySelector("img"):null;i("openMedia",{media:h,originImg:p})}return(d,h)=>o.value?(v(),E("div",{key:0,class:Fe(["media-tool",{mob:e.mobile}])},[U(f(gn),{text:o.value.path||l.value},{default:de(()=>[C("div",k5e,D(l.value),1)]),_:1},8,["text"]),o.value.kind==="image"?(v(),ce(f(gn),{key:0,text:o.value.path||l.value},{default:de(()=>[C("button",{type:"button",class:"media-image-button",onClick:c},[C("img",{class:"media-image",src:o.value.url,alt:o.value.path?s(o.value.path):l.value,loading:"lazy"},null,8,b5e)])]),_:1},8,["text"])):o.value.kind==="video"?(v(),ce(f(gn),{key:1,text:o.value.path||l.value},{default:de(()=>[C("button",{type:"button",class:"media-image-button media-video-button","aria-label":o.value.path?s(o.value.path):l.value,onClick:c},[u.value?(v(),E("span",C5e)):(v(),ce(hg,{key:1,url:o.value.url,kind:"video","file-id":a.value?void 0:o.value.fileId,"media-class":"media-video",controls:!1,muted:""},null,8,["url","file-id"])),C("span",w5e,[U(f(ve),{name:"play",size:"sm"})])],8,A5e)]),_:1},8,["text"])):(v(),E("audio",{key:2,class:"media-audio",src:o.value.url,controls:""},null,8,x5e))],2)):X("",!0)}}),_5e=kt(S5e,[["__scopeId","data-v-3bc3ee1a"]]);var M5e=Object.create,s7=Object.defineProperty,I5e=Object.getOwnPropertyDescriptor,IR=Object.getOwnPropertyNames,E5e=Object.getPrototypeOf,T5e=Object.prototype.hasOwnProperty,ER=(e,t)=>function(){return t||(0,e[IR(e)[0]])((t={exports:{}}).exports,t),t.exports},L5e=e=>{let t={};for(var n in e)s7(t,n,{get:e[n],enumerable:!0});return t},N5e=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(var o=IR(t),s=0,r=o.length,l;s<r;s++)l=o[s],!T5e.call(e,l)&&l!==n&&s7(e,l,{get:(a=>t[a]).bind(null,l),enumerable:!(i=I5e(t,l))||i.enumerable});return e},TR=(e,t,n)=>(n=e!=null?M5e(E5e(e)):{},N5e(s7(n,"default",{value:e,enumerable:!0}),e));function F5e(e,t,n,i){const o=Number(e[t].meta.id+1).toString();let s="";return typeof i.docId=="string"&&(s=`-${i.docId}-`),s+o}function D5e(e,t){let n=Number(e[t].meta.id+1).toString();return e[t].meta.subId>0&&(n+=`:${e[t].meta.subId}`),`[${n}]`}function B5e(e,t,n,i,o){const s=o.rules.footnote_anchor_name(e,t,n,i,o),r=o.rules.footnote_caption(e,t,n,i,o);let l=s;return e[t].meta.subId>0&&(l+=`:${e[t].meta.subId}`),`<sup class="footnote-ref"><a href="#fn${s}" id="fnref${l}">${r}</a></sup>`}function $5e(e,t,n){return(n.xhtmlOut?`<hr class="footnotes-sep" /> -`:`<hr class="footnotes-sep"> -`)+`<section class="footnotes"> -<ol class="footnotes-list"> -`}function R5e(){return`</ol> -</section> -`}function z5e(e,t,n,i,o){let s=o.rules.footnote_anchor_name(e,t,n,i,o);return e[t].meta.subId>0&&(s+=`:${e[t].meta.subId}`),`<li id="fn${s}" class="footnote-item">`}function O5e(){return`</li> -`}function P5e(e,t,n,i,o){let s=o.rules.footnote_anchor_name(e,t,n,i,o);return e[t].meta.subId>0&&(s+=`:${e[t].meta.subId}`),` <a href="#fnref${s}" class="footnote-backref">↩︎</a>`}function j5e(e){const t=e.helpers.parseLinkLabel,n=e.utils.isSpace;e.renderer.rules.footnote_ref=B5e,e.renderer.rules.footnote_block_open=$5e,e.renderer.rules.footnote_block_close=R5e,e.renderer.rules.footnote_open=z5e,e.renderer.rules.footnote_close=O5e,e.renderer.rules.footnote_anchor=P5e,e.renderer.rules.footnote_caption=D5e,e.renderer.rules.footnote_anchor_name=F5e;function i(l,a,u,c){const d=l.bMarks[a]+l.tShift[a],h=l.eMarks[a];if(d+4>h||l.src.charCodeAt(d)!==91||l.src.charCodeAt(d+1)!==94)return!1;let p;for(p=d+2;p<h;p++){if(l.src.charCodeAt(p)===32)return!1;if(l.src.charCodeAt(p)===93)break}if(p===d+2||p+1>=h||l.src.charCodeAt(++p)!==58)return!1;if(c)return!0;p++,l.env.footnotes||(l.env.footnotes={}),l.env.footnotes.refs||(l.env.footnotes.refs={});const g=l.src.slice(d+2,p-2);l.env.footnotes.refs[`:${g}`]=-1;const m=new l.Token("footnote_reference_open","",1);m.meta={label:g},m.level=l.level++,l.tokens.push(m);const k=l.bMarks[a],w=l.tShift[a],y=l.sCount[a],b=l.parentType,A=p,T=l.sCount[a]+p-(l.bMarks[a]+l.tShift[a]);let S=T;for(;p<h;){const _=l.src.charCodeAt(p);if(n(_))_===9?S+=4-S%4:S++;else break;p++}l.tShift[a]=p-A,l.sCount[a]=S-T,l.bMarks[a]=A,l.blkIndent+=4,l.parentType="footnote",l.sCount[a]<l.blkIndent&&(l.sCount[a]+=l.blkIndent),l.md.block.tokenize(l,a,u,!0),l.parentType=b,l.blkIndent-=4,l.tShift[a]=w,l.sCount[a]=y,l.bMarks[a]=k;const x=new l.Token("footnote_reference_close","",-1);return x.level=--l.level,l.tokens.push(x),!0}function o(l,a){const u=l.posMax,c=l.pos;if(c+2>=u||l.src.charCodeAt(c)!==94||l.src.charCodeAt(c+1)!==91)return!1;const d=c+2,h=t(l,c+1);if(h<0)return!1;if(!a){l.env.footnotes||(l.env.footnotes={}),l.env.footnotes.list||(l.env.footnotes.list=[]);const p=l.env.footnotes.list.length,g=[];l.md.inline.parse(l.src.slice(d,h),l.md,l.env,g);const m=l.push("footnote_ref","",0);m.meta={id:p},l.env.footnotes.list[p]={content:l.src.slice(d,h),tokens:g}}return l.pos=h+1,l.posMax=u,!0}function s(l,a){const u=l.posMax,c=l.pos;if(c+3>u||!l.env.footnotes||!l.env.footnotes.refs||l.src.charCodeAt(c)!==91||l.src.charCodeAt(c+1)!==94)return!1;let d;for(d=c+2;d<u;d++){if(l.src.charCodeAt(d)===32||l.src.charCodeAt(d)===10)return!1;if(l.src.charCodeAt(d)===93)break}if(d===c+2||d>=u)return!1;d++;const h=l.src.slice(c+2,d-1);if(typeof l.env.footnotes.refs[`:${h}`]>"u")return!1;if(!a){l.env.footnotes.list||(l.env.footnotes.list=[]);let p;l.env.footnotes.refs[`:${h}`]<0?(p=l.env.footnotes.list.length,l.env.footnotes.list[p]={label:h,count:0},l.env.footnotes.refs[`:${h}`]=p):p=l.env.footnotes.refs[`:${h}`];const g=l.env.footnotes.list[p].count;l.env.footnotes.list[p].count++;const m=l.push("footnote_ref","",0);m.meta={id:p,subId:g,label:h}}return l.pos=d,l.posMax=u,!0}function r(l){let a,u,c,d=!1;const h={};if(!l.env.footnotes||(l.tokens=l.tokens.filter(function(g){return g.type==="footnote_reference_open"?(d=!0,u=[],c=g.meta.label,!1):g.type==="footnote_reference_close"?(d=!1,h[":"+c]=u,!1):(d&&u.push(g),!d)}),!l.env.footnotes.list))return;const p=l.env.footnotes.list;l.tokens.push(new l.Token("footnote_block_open","",1));for(let g=0,m=p.length;g<m;g++){const k=new l.Token("footnote_open","",1);if(k.meta={id:g,label:p[g].label},l.tokens.push(k),p[g].tokens){a=[];const b=new l.Token("paragraph_open","p",1);b.block=!0,a.push(b);const A=new l.Token("inline","",0);A.children=p[g].tokens,A.content=p[g].content,a.push(A);const T=new l.Token("paragraph_close","p",-1);T.block=!0,a.push(T)}else p[g].label&&(a=h[`:${p[g].label}`]);a&&(l.tokens=l.tokens.concat(a));let w;l.tokens[l.tokens.length-1].type==="paragraph_close"?w=l.tokens.pop():w=null;const y=p[g].count>0?p[g].count:1;for(let b=0;b<y;b++){const A=new l.Token("footnote_anchor","",0);A.meta={id:g,subId:b,label:p[g].label},l.tokens.push(A)}w&&l.tokens.push(w),l.tokens.push(new l.Token("footnote_close","",-1))}l.tokens.push(new l.Token("footnote_block_close","",-1))}e.block.ruler.before("reference","footnote_def",i,{alt:["paragraph","reference"]}),e.inline.ruler.after("image","footnote_inline",o),e.inline.ruler.after("footnote_inline","footnote_ref",s),e.core.ruler.after("inline","footnote_tail",r)}function H5e(e){function t(i,o){const s=i.pos,r=i.src.charCodeAt(s);if(o||r!==43)return!1;const l=i.scanDelims(i.pos,!0);let a=l.length;const u=String.fromCharCode(r);if(a<2)return!1;if(a%2){const c=i.push("text","",0);c.content=u,a--}for(let c=0;c<a;c+=2){const d=i.push("text","",0);d.content=u+u,!(!l.can_open&&!l.can_close)&&i.delimiters.push({marker:r,length:0,jump:c/2,token:i.tokens.length-1,end:-1,open:l.can_open,close:l.can_close})}return i.pos+=l.length,!0}function n(i,o){let s;const r=[],l=o.length;for(let a=0;a<l;a++){const u=o[a];if(u.marker!==43||u.end===-1)continue;const c=o[u.end];s=i.tokens[u.token],s.type="ins_open",s.tag="ins",s.nesting=1,s.markup="++",s.content="",s=i.tokens[c.token],s.type="ins_close",s.tag="ins",s.nesting=-1,s.markup="++",s.content="",i.tokens[c.token-1].type==="text"&&i.tokens[c.token-1].content==="+"&&r.push(c.token-1)}for(;r.length;){const a=r.pop();let u=a+1;for(;u<i.tokens.length&&i.tokens[u].type==="ins_close";)u++;u--,a!==u&&(s=i.tokens[u],i.tokens[u]=i.tokens[a],i.tokens[a]=s)}}e.inline.ruler.before("emphasis","ins",t),e.inline.ruler2.before("emphasis","ins",function(i){const o=i.tokens_meta,s=(i.tokens_meta||[]).length;n(i,i.delimiters);for(let r=0;r<s;r++)o[r]&&o[r].delimiters&&n(i,o[r].delimiters)})}function W5e(e){function t(i,o){const s=i.pos,r=i.src.charCodeAt(s);if(o||r!==61)return!1;const l=i.scanDelims(i.pos,!0);let a=l.length;const u=String.fromCharCode(r);if(a<2)return!1;if(a%2){const c=i.push("text","",0);c.content=u,a--}for(let c=0;c<a;c+=2){const d=i.push("text","",0);d.content=u+u,!(!l.can_open&&!l.can_close)&&i.delimiters.push({marker:r,length:0,jump:c/2,token:i.tokens.length-1,end:-1,open:l.can_open,close:l.can_close})}return i.pos+=l.length,!0}function n(i,o){const s=[],r=o.length;for(let l=0;l<r;l++){const a=o[l];if(a.marker!==61||a.end===-1)continue;const u=o[a.end],c=i.tokens[a.token];c.type="mark_open",c.tag="mark",c.nesting=1,c.markup="==",c.content="";const d=i.tokens[u.token];d.type="mark_close",d.tag="mark",d.nesting=-1,d.markup="==",d.content="",i.tokens[u.token-1].type==="text"&&i.tokens[u.token-1].content==="="&&s.push(u.token-1)}for(;s.length;){const l=s.pop();let a=l+1;for(;a<i.tokens.length&&i.tokens[a].type==="mark_close";)a++;if(a--,l!==a){const u=i.tokens[a];i.tokens[a]=i.tokens[l],i.tokens[l]=u}}}e.inline.ruler.before("emphasis","mark",t),e.inline.ruler2.before("emphasis","mark",function(i){let o;const s=i.tokens_meta,r=(i.tokens_meta||[]).length;for(n(i,i.delimiters),o=0;o<r;o++)s[o]&&s[o].delimiters&&n(i,s[o].delimiters)})}const q5e=/\\([ \\!"#$%&'()*+,./:;<=>?@[\]^_`{|}~-])/g;function U5e(e,t){const n=e.posMax,i=e.pos;if(e.src.charCodeAt(i)!==94||t||i+2>=n)return!1;e.pos=i+1;let o=!1;for(;e.pos<n;){if(e.src.charCodeAt(e.pos)===94){o=!0;break}e.md.inline.skipToken(e)}if(!o||i+1===e.pos)return e.pos=i,!1;const s=e.src.slice(i+1,e.pos);if(s.match(/(^|[^\\])(\\\\)*\s/))return e.pos=i,!1;e.posMax=e.pos,e.pos=i+1;const r=e.push("sup_open","sup",1);r.markup="^";const l=e.push("text","",0);l.content=s.replace(q5e,"$1");const a=e.push("sup_close","sup",-1);return a.markup="^",e.pos=e.posMax+1,e.posMax=n,!0}function K5e(e){e.inline.ruler.after("emphasis","sup",U5e)}var V5e=ER({"../../node_modules/.pnpm/markdown-it-task-checkbox@1.0.6/node_modules/markdown-it-task-checkbox/index.js":((e,t)=>{t.exports=function(m,k){k=Object.assign({},{disabled:!0,divWrap:!1,divClass:"checkbox",idPrefix:"cbx_",ulClass:"task-list",liClass:"task-list-item"},k),m.core.ruler.after("inline","github-task-lists",function(w){for(var y=w.tokens,b=0,A=2;A<y.length;A++)o(y,A)&&(s(y[A],b,k,w.Token),b+=1,n(y[A-2],"class",k.liClass),n(y[i(y,A-2)],"class",k.ulClass))})};function n(m,k,w){var y=m.attrIndex(k),b=[k,w];y<0?m.attrPush(b):m.attrs[y]=b}function i(m,k){for(var w=m[k].level-1,y=k-1;y>=0;y--)if(m[y].level===w)return y;return-1}function o(m,k){return d(m[k])&&h(m[k-1])&&p(m[k-2])&&g(m[k])}function s(m,k,w,y){var b=w.idPrefix+k;m.children[0].content=m.children[0].content.slice(3),m.children.unshift(l(b,y)),m.children.push(a(y)),m.children.unshift(r(m,b,w,y)),w.divWrap&&(m.children.unshift(u(w,y)),m.children.push(c(y)))}function r(m,k,w,y){var b=new y("checkbox_input","input",0);return b.attrs=[["type","checkbox"],["id",k]],/^\[[xX]\][ \u00A0]/.test(m.content)===!0&&b.attrs.push(["checked","true"]),w.disabled===!0&&b.attrs.push(["disabled","true"]),b}function l(m,k){var w=new k("label_open","label",1);return w.attrs=[["for",m]],w}function a(m){return new m("label_close","label",-1)}function u(m,k){var w=new k("checkbox_open","div",0);return w.attrs=[["class",m.divClass]],w}function c(m){return new m("checkbox_close","div",-1)}function d(m){return m.type==="inline"}function h(m){return m.type==="paragraph_open"}function p(m){return m.type==="list_item_open"}function g(m){return/^\[[xX \u00A0]\][ \u00A0]/.test(m.content)}})});const Z5e=new Map([[0,65533],[128,8364],[130,8218],[131,402],[132,8222],[133,8230],[134,8224],[135,8225],[136,710],[137,8240],[138,352],[139,8249],[140,338],[142,381],[145,8216],[146,8217],[147,8220],[148,8221],[149,8226],[150,8211],[151,8212],[152,732],[153,8482],[154,353],[155,8250],[156,339],[158,382],[159,376]]);function G5e(e){return e>=55296&&e<=57343||e>1114111?65533:Z5e.get(e)??e}function Q5e(e){const t=atob(e),n=t.length&-2,i=new Uint16Array(n/2);for(let o=0,s=0;o<n;o+=2){const r=t.charCodeAt(o),l=t.charCodeAt(o+1);i[s++]=r|l<<8}return i}const Y5e=Q5e("QR08ALkAAgH6AYsDNQR2BO0EPgXZBQEGLAbdBxMISQrvCmQLfQurDKQNLw4fD4YPpA+6D/IPAAAAAAAAAAAAAAAAKhBMEY8TmxUWF2EYLBkxGuAa3RsJHDscWR8YIC8jSCSIJcMl6ie3Ku8rEC0CLjoupS7kLgAIRU1hYmNmZ2xtbm9wcnN0dVQAWgBeAGUAaQBzAHcAfgCBAIQAhwCSAJoAoACsALMAbABpAGcAO4DGAMZAUAA7gCYAJkBjAHUAdABlADuAwQDBQHIiZXZlAAJhAAFpeW0AcgByAGMAO4DCAMJAEGRyAADgNdgE3XIAYQB2AGUAO4DAAMBA8CFoYZFj4SFjcgBhZAAAoFMqAAFncIsAjgBvAG4ABGFmAADgNdg43fAlbHlGdW5jdGlvbgCgYSBpAG4AZwA7gMUAxUAAAWNzpACoAHIAAOA12Jzc6SFnbgCgVCJpAGwAZABlADuAwwDDQG0AbAA7gMQAxEAABGFjZWZvcnN1xQDYANoA7QDxAPYA+QD8AAABY3LJAM8AayNzbGFzaAAAoBYidgHTANUAAKDnKmUAZAAAoAYjeQARZIABY3J0AOAA5QDrAGEidXNlAACgNSLuI291bGxpcwCgLCFhAJJjcgAA4DXYBd1wAGYAAOA12Dnd5SF2ZdhiYwDyAOoAbSJwZXEAAKBOIgAHSE9hY2RlZmhpbG9yc3UXARoBHwE6AVIBVQFiAWQBZgGCAakB6QHtAfIBYwB5ACdkUABZADuAqQCpQIABY3B5ACUBKAE1AfUhdGUGYWmg0iJ0KGFsRGlmZmVyZW50aWFsRAAAoEUhbCJleXMAAKAtIQACYWVpb0EBRAFKAU0B8iFvbgxhZABpAGwAO4DHAMdAcgBjAAhhbiJpbnQAAKAwIm8AdAAKYQABZG5ZAV0BaSJsbGEAuGB0I2VyRG90ALdg8gA5AWkAp2NyImNsZQAAAkRNUFRwAXQBeQF9AW8AdAAAoJkiaSJudXMAAKCWIuwhdXMAoJUiaSJtZXMAAKCXIm8AAAFjc4cBlAFrKndpc2VDb250b3VySW50ZWdyYWwAAKAyImUjQ3VybHkAAAFEUZwBpAFvJXVibGVRdW90ZQAAoB0gdSJvdGUAAKAZIAACbG5wdbABtgHNAdgBbwBuAGWgNyIAoHQqgAFnaXQAvAHBAcUB8iJ1ZW50AKBhIm4AdAAAoC8i7yV1ckludGVncmFsAKAuIgABZnLRAdMBAKACIe8iZHVjdACgECJuLnRlckNsb2Nrd2lzZUNvbnRvdXJJbnRlZ3JhbAAAoDMi7yFzcwCgLypjAHIAAOA12J7ccABDoNMiYQBwAACgTSKABURKU1phY2VmaW9zAAsCEgIVAhgCGwIsAjQCOQI9AnMCfwNvoEUh9CJyYWhkAKARKWMAeQACZGMAeQAFZGMAeQAPZIABZ3JzACECJQIoAuchZXIAoCEgcgAAoKEhaAB2AACg5CoAAWF5MAIzAvIhb24OYRRkbAB0oAciYQCUY3IAAOA12AfdAAFhZkECawIAAWNtRQJnAvIjaXRpY2FsAAJBREdUUAJUAl8CYwJjInV0ZQC0YG8AdAFZAloC2WJiJGxlQWN1dGUA3WJyImF2ZQBgYGkibGRlANxi7yFuZACgxCJmJWVyZW50aWFsRAAAoEYhcAR9AgAAAAAAAIECjgIAABoDZgAA4DXYO91EoagAhQKJAm8AdAAAoNwgcSJ1YWwAAKBQIuIhbGUAA0NETFJVVpkCqAK1Au8C/wIRA28AbgB0AG8AdQByAEkAbgB0AGUAZwByAGEA7ADEAW8AdAKvAgAAAACwAqhgbiNBcnJvdwAAoNMhAAFlb7kC0AJmAHQAgAFBUlQAwQLGAs0CciJyb3cAAKDQIekkZ2h0QXJyb3cAoNQhZQDlACsCbgBnAAABTFLWAugC5SFmdAABQVLcAuECciJyb3cAAKD4J+kkZ2h0QXJyb3cAoPon6SRnaHRBcnJvdwCg+SdpImdodAAAAUFU9gL7AnIicm93AACg0iFlAGUAAKCoInAAQQIGAwAAAAALA3Iicm93AACg0SFvJHduQXJyb3cAAKDVIWUlcnRpY2FsQmFyAACgJSJuAAADQUJMUlRhJAM2AzoDWgNxA3oDciJyb3cAAKGTIUJVLAMwA2EAcgAAoBMpcCNBcnJvdwAAoPUhciJldmUAEWPlIWZ00gJDAwAASwMAAFIDaSVnaHRWZWN0b3IAAKBQKWUkZVZlY3RvcgAAoF4p5SJjdG9yQqC9IWEAcgAAoFYpaSJnaHQA1AFiAwAAaQNlJGVWZWN0b3IAAKBfKeUiY3RvckKgwSFhAHIAAKBXKWUAZQBBoKQiciJyb3cAAKCnIXIAcgBvAPcAtAIAAWN0gwOHA3IAAOA12J/c8iFvaxBhAAhOVGFjZGZnbG1vcHFzdHV4owOlA6kDsAO/A8IDxgPNA9ID8gP9AwEEFAQeBCAEJQRHAEphSAA7gNAA0EBjAHUAdABlADuAyQDJQIABYWl5ALYDuQO+A/Ihb24aYXIAYwA7gMoAykAtZG8AdAAWYXIAAOA12AjdcgBhAHYAZQA7gMgAyEDlIm1lbnQAoAgiAAFhcNYD2QNjAHIAEmF0AHkAUwLhAwAAAADpA20lYWxsU3F1YXJlAACg+yVlJ3J5U21hbGxTcXVhcmUAAKCrJQABZ3D2A/kDbwBuABhhZgAA4DXYPN3zImlsb26VY3UAAAFhaQYEDgRsAFSgdSppImxkZQAAoEIi7CNpYnJpdW0AoMwhAAFjaRgEGwRyAACgMCFtAACgcyphAJdjbQBsADuAywDLQAABaXApBC0E8yF0cwCgAyLvJG5lbnRpYWxFAKBHIYACY2Zpb3MAPQQ/BEMEXQRyBHkAJGRyAADgNdgJ3WwibGVkAFMCTAQAAAAAVARtJWFsbFNxdWFyZQAAoPwlZSdyeVNtYWxsU3F1YXJlAACgqiVwA2UEAABpBAAAAABtBGYAAOA12D3dwSFsbACgACLyI2llcnRyZgCgMSFjAPIAcQQABkpUYWJjZGZnb3JzdIgEiwSOBJMElwSkBKcEqwStBLIE5QTqBGMAeQADZDuAPgA+QO0hbWFkoJMD3GNyImV2ZQAeYYABZWl5AJ0EoASjBOQhaWwiYXIAYwAcYRNkbwB0ACBhcgAA4DXYCt0AoNkicABmAADgNdg+3eUiYXRlcgADRUZHTFNUvwTIBM8E1QTZBOAEcSJ1YWwATKBlIuUhc3MAoNsidSRsbEVxdWFsAACgZyJyI2VhdGVyAACgoirlIXNzAKB3IuwkYW50RXF1YWwAoH4qaSJsZGUAAKBzImMAcgAA4DXYotwAoGsiAARBYWNmaW9zdfkE/QQFBQgFCwUTBSIFKwVSIkRjeQAqZAABY3QBBQQFZQBrAMdiXmDpIXJjJGFyAACgDCFsJWJlcnRTcGFjZQAAoAsh8AEYBQAAGwVmAACgDSHpJXpvbnRhbExpbmUAoAAlAAFjdCYFKAXyABIF8iFvayZhbQBwAEQBMQU5BW8AdwBuAEgAdQBtAPAAAAFxInVhbAAAoE8iAAdFSk9hY2RmZ21ub3N0dVMFVgVZBVwFYwVtBXAFcwV6BZAFtgXFBckFzQVjAHkAFWTsIWlnMmFjAHkAAWRjAHUAdABlADuAzQDNQAABaXlnBWwFcgBjADuAzgDOQBhkbwB0ADBhcgAAoBEhcgBhAHYAZQA7gMwAzEAAoREhYXB/BYsFAAFjZ4MFhQVyACphaSNuYXJ5SQAAoEghbABpAGUA8wD6AvQBlQUAAKUFZaAsIgABZ3KaBZ4F8iFhbACgKyLzI2VjdGlvbgCgwiJpI3NpYmxlAAABQ1SsBbEFbyJtbWEAAKBjIGkibWVzAACgYiCAAWdwdAC8Bb8FwwVvAG4ALmFmAADgNdhA3WEAmWNjAHIAAKAQIWkibGRlAChh6wHSBQAA1QVjAHkABmRsADuAzwDPQIACY2Zvc3UA4QXpBe0F8gX9BQABaXnlBegFcgBjADRhGWRyAADgNdgN3XAAZgAA4DXYQd3jAfcFAAD7BXIAAOA12KXc8iFjeQhk6yFjeQRkgANISmFjZm9zAAwGDwYSBhUGHQYhBiYGYwB5ACVkYwB5AAxk8CFwYZpjAAFleRkGHAbkIWlsNmEaZHIAAOA12A7dcABmAADgNdhC3WMAcgAA4DXYptyABUpUYWNlZmxtb3N0AD0GQAZDBl4GawZkB2gHcAd0B80H2gdjAHkACWQ7gDwAPECAAmNtbnByAEwGTwZSBlUGWwb1IXRlOWHiIWRhm2NnAACg6ifsI2FjZXRyZgCgEiFyAACgniGAAWFleQBkBmcGagbyIW9uPWHkIWlsO2EbZAABZnNvBjQHdAAABUFDREZSVFVWYXKABp4GpAbGBssG3AYDByEHwQIqBwABbnKEBowGZyVsZUJyYWNrZXQAAKDoJ/Ihb3cAoZAhQlKTBpcGYQByAACg5CHpJGdodEFycm93AKDGIWUjaWxpbmcAAKAII28A9QGqBgAAsgZiJWxlQnJhY2tldAAAoOYnbgDUAbcGAAC+BmUkZVZlY3RvcgAAoGEp5SJjdG9yQqDDIWEAcgAAoFkpbCJvb3IAAKAKI2kiZ2h0AAABQVbSBtcGciJyb3cAAKCUIeUiY3RvcgCgTikAAWVy4AbwBmUAAKGjIkFW5gbrBnIicm93AACgpCHlImN0b3IAoFopaSNhbmdsZQBCorIi+wYAAAAA/wZhAHIAAKDPKXEidWFsAACgtCJwAIABRFRWAAoHEQcYB+8kd25WZWN0b3IAoFEpZSRlVmVjdG9yAACgYCnlImN0b3JCoL8hYQByAACgWCnlImN0b3JCoLwhYQByAACgUilpAGcAaAB0AGEAcgByAG8A9wDMAnMAAANFRkdMU1Q/B0cHTgdUB1gHXwfxJXVhbEdyZWF0ZXIAoNoidSRsbEVxdWFsAACgZiJyI2VhdGVyAACgdiLlIXNzAKChKuwkYW50RXF1YWwAoH0qaSJsZGUAAKByInIAAOA12A/dZaDYIuYjdGFycm93AKDaIWkiZG90AD9hgAFucHcAege1B7kHZwAAAkxSbHKCB5QHmwerB+UhZnQAAUFSiAeNB3Iicm93AACg9SfpJGdodEFycm93AKD3J+kkZ2h0QXJyb3cAoPYn5SFmdAABYXLcAqEHaQBnAGgAdABhAHIAcgBvAPcA5wJpAGcAaAB0AGEAcgByAG8A9wDuAmYAAOA12EPdZQByAAABTFK/B8YHZSRmdEFycm93AACgmSHpJGdodEFycm93AKCYIYABY2h0ANMH1QfXB/IAWgYAoLAh8iFva0FhAKBqIgAEYWNlZmlvc3XpB+wH7gf/BwMICQgOCBEIcAAAoAUpeQAcZAABZGzyB/kHaSR1bVNwYWNlAACgXyBsI2ludHJmAACgMyFyAADgNdgQ3e4jdXNQbHVzAKATInAAZgAA4DXYRN1jAPIA/gecY4AESmFjZWZvc3R1ACEIJAgoCDUIgQiFCDsKQApHCmMAeQAKZGMidXRlAENhgAFhZXkALggxCDQI8iFvbkdh5CFpbEVhHWSAAWdzdwA7CGEIfQjhInRpdmWAAU1UVgBECEwIWQhlJWRpdW1TcGFjZQAAoAsgaABpAAABY25SCFMIawBTAHAAYQBjAOUASwhlAHIAeQBUAGgAaQDuAFQI9CFlZAABR0xnCHUIcgBlAGEAdABlAHIARwByAGUAYQB0AGUA8gDrBGUAcwBzAEwAZQBzAPMA2wdMImluZQAKYHIAAOA12BHdAAJCbnB0jAiRCJkInAhyImVhawAAoGAgwiZyZWFraW5nU3BhY2WgYGYAAKAVIUOq7CqzCMIIzQgAAOcIGwkAAAAAAAAtCQAAbwkAAIcJAACdCcAJGQoAADQKAAFvdbYIvAjuI2dydWVudACgYiJwIkNhcAAAoG0ibyh1YmxlVmVydGljYWxCYXIAAKAmIoABbHF4ANII1wjhCOUibWVudACgCSL1IWFsVKBgImkibGRlAADgQiI4A2kic3RzAACgBCJyI2VhdGVyAACjbyJFRkdMU1T1CPoIAgkJCQ0JFQlxInVhbAAAoHEidSRsbEVxdWFsAADgZyI4A3IjZWF0ZXIAAOBrIjgD5SFzcwCgeSLsJGFudEVxdWFsAOB+KjgDaSJsZGUAAKB1IvUhbXBEASAJJwnvI3duSHVtcADgTiI4A3EidWFsAADgTyI4A2UAAAFmczEJRgn0JFRyaWFuZ2xlQqLqIj0JAAAAAEIJYQByAADgzyk4A3EidWFsAACg7CJzAICibiJFR0xTVABRCVYJXAlhCWkJcSJ1YWwAAKBwInIjZWF0ZXIAAKB4IuUhc3MA4GoiOAPsJGFudEVxdWFsAOB9KjgDaSJsZGUAAKB0IuUic3RlZAABR0x1CX8J8iZlYXRlckdyZWF0ZXIA4KIqOAPlI3NzTGVzcwDgoSo4A/IjZWNlZGVzAKGAIkVTjwmVCXEidWFsAADgryo4A+wkYW50RXF1YWwAoOAiAAFlaaAJqQl2JmVyc2VFbGVtZW50AACgDCLnJWh0VHJpYW5nbGVCousitgkAAAAAuwlhAHIAAODQKTgDcSJ1YWwAAKDtIgABcXXDCeAJdSNhcmVTdQAAAWJwywnVCfMhZXRF4I8iOANxInVhbAAAoOIi5SJyc2V0ReCQIjgDcSJ1YWwAAKDjIoABYmNwAOYJ8AkNCvMhZXRF4IIi0iBxInVhbAAAoIgi4yJlZWRzgKGBIkVTVAD6CQAKBwpxInVhbAAA4LAqOAPsJGFudEVxdWFsAKDhImkibGRlAADgfyI4A+UicnNldEXggyLSIHEidWFsAACgiSJpImxkZQCAoUEiRUZUACIKJwouCnEidWFsAACgRCJ1JGxsRXF1YWwAAKBHImkibGRlAACgSSJlJXJ0aWNhbEJhcgAAoCQiYwByAADgNdip3GkAbABkAGUAO4DRANFAnWMAB0VhY2RmZ21vcHJzdHV2XgphCmgKcgp2CnoKgQqRCpYKqwqtCrsKyArNCuwhaWdSYWMAdQB0AGUAO4DTANNAAAFpeWwKcQpyAGMAO4DUANRAHmRiImxhYwBQYXIAAOA12BLdcgBhAHYAZQA7gNIA0kCAAWFlaQCHCooKjQpjAHIATGFnAGEAqWNjInJvbgCfY3AAZgAA4DXYRt3lI25DdXJseQABRFGeCqYKbyV1YmxlUXVvdGUAAKAcIHUib3RlAACgGCAAoFQqAAFjbLEKtQpyAADgNdiq3GEAcwBoADuA2ADYQGkAbAHACsUKZABlADuA1QDVQGUAcwAAoDcqbQBsADuA1gDWQGUAcgAAAUJQ0wrmCgABYXLXCtoKcgAAoD4gYQBjAAABZWvgCuIKAKDeI2UAdAAAoLQjYSVyZW50aGVzaXMAAKDcI4AEYWNmaGlsb3JzAP0KAwsFCwkLCwsMCxELIwtaC3IjdGlhbEQAAKACInkAH2RyAADgNdgT3WkApmOgY/Ujc01pbnVzsWAAAWlwFQsgC24AYwBhAHIAZQBwAGwAYQBuAOUACgVmAACgGSGAobsqZWlvACoLRQtJC+MiZWRlc4CheiJFU1QANAs5C0ALcSJ1YWwAAKCvKuwkYW50RXF1YWwAoHwiaSJsZGUAAKB+Im0AZQAAoDMgAAFkcE0LUQv1IWN0AKAPIm8jcnRpb24AYaA3ImwAAKAdIgABY2leC2ILcgAA4DXYq9yoYwACVWZvc2oLbwtzC3cLTwBUADuAIgAiQHIAAOA12BTdcABmAACgGiFjAHIAAOA12KzcAAZCRWFjZWZoaW9yc3WPC5MLlwupC7YL2AvbC90LhQyTDJoMowzhIXJyAKAQKUcAO4CuAK5AgAFjbnIAnQugC6ML9SF0ZVRhZwAAoOsncgB0oKAhbAAAoBYpgAFhZXkArwuyC7UL8iFvblhh5CFpbFZhIGR2oBwhZSJyc2UAAAFFVb8LzwsAAWxxwwvIC+UibWVudACgCyL1JGlsaWJyaXVtAKDLIXAmRXF1aWxpYnJpdW0AAKBvKXIAAKAcIW8AoWPnIWh0AARBQ0RGVFVWYewLCgwQDDIMNwxeDHwM9gIAAW5y8Av4C2clbGVCcmFja2V0AACg6SfyIW93AKGSIUJM/wsDDGEAcgAAoOUhZSRmdEFycm93AACgxCFlI2lsaW5nAACgCSNvAPUBFgwAAB4MYiVsZUJyYWNrZXQAAKDnJ24A1AEjDAAAKgxlJGVWZWN0b3IAAKBdKeUiY3RvckKgwiFhAHIAAKBVKWwib29yAACgCyMAAWVyOwxLDGUAAKGiIkFWQQxGDHIicm93AACgpiHlImN0b3IAoFspaSNhbmdsZQBCorMiVgwAAAAAWgxhAHIAAKDQKXEidWFsAACgtSJwAIABRFRWAGUMbAxzDO8kd25WZWN0b3IAoE8pZSRlVmVjdG9yAACgXCnlImN0b3JCoL4hYQByAACgVCnlImN0b3JCoMAhYQByAACgUykAAXB1iQyMDGYAAKAdIe4kZEltcGxpZXMAoHAp6SRnaHRhcnJvdwCg2yEAAWNongyhDHIAAKAbIQCgsSHsJGVEZWxheWVkAKD0KYAGSE9hY2ZoaW1vcXN0dQC/DMgMzAzQDOIM5gwKDQ0NFA0ZDU8NVA1YDQABQ2PDDMYMyCFjeSlkeQAoZEYiVGN5ACxkYyJ1dGUAWmEAorwqYWVpedgM2wzeDOEM8iFvbmBh5CFpbF5hcgBjAFxhIWRyAADgNdgW3e8hcnQAAkRMUlXvDPYM/QwEDW8kd25BcnJvdwAAoJMhZSRmdEFycm93AACgkCHpJGdodEFycm93AKCSIXAjQXJyb3cAAKCRIechbWGjY+EkbGxDaXJjbGUAoBgicABmAADgNdhK3XICHw0AAAAAIg10AACgGiLhIXJlgKGhJUlTVQAqDTINSg3uJXRlcnNlY3Rpb24AoJMidQAAAWJwNw1ADfMhZXRFoI8icSJ1YWwAAKCRIuUicnNldEWgkCJxInVhbAAAoJIibiJpb24AAKCUImMAcgAA4DXYrtxhAHIAAKDGIgACYmNtcF8Nag2ODZANc6DQImUAdABFoNAicSJ1YWwAAKCGIgABY2huDYkNZSJlZHMAgKF7IkVTVAB4DX0NhA1xInVhbAAAoLAq7CRhbnRFcXVhbACgfSJpImxkZQAAoH8iVABoAGEA9ADHCwCgESIAodEiZXOVDZ8NciJzZXQARaCDInEidWFsAACghyJlAHQAAKDRIoAFSFJTYWNmaGlvcnMAtQ27Db8NyA3ODdsN3w3+DRgOHQ4jDk8AUgBOADuA3gDeQMEhREUAoCIhAAFIY8MNxg1jAHkAC2R5ACZkAAFidcwNzQ0JYKRjgAFhZXkA1A3XDdoN8iFvbmRh5CFpbGJhImRyAADgNdgX3QABZWnjDe4N8gHoDQAA7Q3lImZvcmUAoDQiYQCYYwABY27yDfkNayNTcGFjZQAA4F8gCiDTInBhY2UAoAkg7CFkZYChPCJFRlQABw4MDhMOcSJ1YWwAAKBDInUkbGxFcXVhbAAAoEUiaSJsZGUAAKBIInAAZgAA4DXYS93pI3BsZURvdACg2yAAAWN0Jw4rDnIAAOA12K/c8iFva2Zh4QpFDlYOYA5qDgAAbg5yDgAAAAAAAAAAAAB5DnwOqA6zDgAADg8RDxYPGg8AAWNySA5ODnUAdABlADuA2gDaQHIAb6CfIeMhaXIAoEkpcgDjAVsOAABdDnkADmR2AGUAbGEAAWl5Yw5oDnIAYwA7gNsA20AjZGIibGFjAHBhcgAA4DXYGN1yAGEAdgBlADuA2QDZQOEhY3JqYQABZGl/Dp8OZQByAAABQlCFDpcOAAFhcokOiw5yAF9gYQBjAAABZWuRDpMOAKDfI2UAdAAAoLUjYSVyZW50aGVzaXMAAKDdI28AbgBQoMMi7CF1cwCgjiIAAWdwqw6uDm8AbgByYWYAAOA12EzdAARBREVUYWRwc78O0g7ZDuEOBQPqDvMOBw9yInJvdwDCoZEhyA4AAMwOYQByAACgEilvJHduQXJyb3cAAKDFIW8kd25BcnJvdwAAoJUhcSV1aWxpYnJpdW0AAKBuKWUAZQBBoKUiciJyb3cAAKClIW8AdwBuAGEAcgByAG8A9wAQA2UAcgAAAUxS+Q4AD2UkZnRBcnJvdwAAoJYh6SRnaHRBcnJvdwCglyFpAGyg0gNvAG4ApWPpIW5nbmFjAHIAAOA12LDcaSJsZGUAaGFtAGwAO4DcANxAgAREYmNkZWZvc3YALQ8xDzUPNw89D3IPdg97D4AP4SFzaACgqyJhAHIAAKDrKnkAEmThIXNobKCpIgCg5ioAAWVyQQ9DDwCgwSKAAWJ0eQBJD00Paw9hAHIAAKAWIGmgFiDjIWFsAAJCTFNUWA9cD18PZg9hAHIAAKAjIukhbmV8YGUkcGFyYXRvcgAAoFgnaSJsZGUAAKBAItQkaGluU3BhY2UAoAogcgAA4DXYGd1wAGYAAOA12E3dYwByAADgNdix3GQiYXNoAACgqiKAAmNlZm9zAI4PkQ+VD5kPng/pIXJjdGHkIWdlAKDAInIAAOA12BrdcABmAADgNdhO3WMAcgAA4DXYstwAAmZpb3OqD64Prw+0D3IAAOA12BvdnmNwAGYAAOA12E/dYwByAADgNdiz3IAEQUlVYWNmb3N1AMgPyw/OD9EP2A/gD+QP6Q/uD2MAeQAvZGMAeQAHZGMAeQAuZGMAdQB0AGUAO4DdAN1AAAFpedwP3w9yAGMAdmErZHIAAOA12BzdcABmAADgNdhQ3WMAcgAA4DXYtNxtAGwAeGEABEhhY2RlZm9z/g8BEAUQDRAQEB0QIBAkEGMAeQAWZGMidXRlAHlhAAFheQkQDBDyIW9ufWEXZG8AdAB7YfIBFRAAABwQbwBXAGkAZAB0AOgAVAhhAJZjcgAAoCghcABmAACgJCFjAHIAAOA12LXc4QtCEEkQTRAAAGcQbRByEAAAAAAAAAAAeRCKEJcQ8hD9EAAAGxEhETIROREAAD4RYwB1AHQAZQA7gOEA4UByImV2ZQADYYCiPiJFZGl1eQBWEFkQWxBgEGUQAOA+IjMDAKA/InIAYwA7gOIA4kB0AGUAO4C0ALRAMGRsAGkAZwA7gOYA5kByoGEgAOA12B7dcgBhAHYAZQA7gOAA4EAAAWVwfBCGEAABZnCAEIQQ8yF5bQCgNSHoAIMQaABhALFjAAFhcI0QWwAAAWNskRCTEHIAAWFnAACgPypkApwQAAAAALEQAKInImFkc3ajEKcQqRCuEG4AZAAAoFUqAKBcKmwib3BlAACgWCoAoFoqAKMgImVsbXJzersQvRDAEN0Q5RDtEACgpCllAACgICJzAGQAYaAhImEEzhDQENIQ1BDWENgQ2hDcEACgqCkAoKkpAKCqKQCgqykAoKwpAKCtKQCgrikAoK8pdAB2oB8iYgBkoL4iAKCdKQABcHTpEOwQaAAAoCIixWDhIXJyAKB8IwABZ3D1EPgQbwBuAAVhZgAA4DXYUt0Ao0giRWFlaW9wBxEJEQ0RDxESERQRAKBwKuMhaXIAoG8qAKBKImQAAKBLInMAJ2DyIW94ZaBIIvEADhFpAG4AZwA7gOUA5UCAAWN0eQAmESoRKxFyAADgNdi23CpgbQBwAGWgSCLxAPgBaQBsAGQAZQA7gOMA40BtAGwAO4DkAORAAAFjaUERRxFvAG4AaQBuAPQA6AFuAHQAAKARKgAITmFiY2RlZmlrbG5vcHJzdWQRaBGXEZ8RpxGrEdIR1hErEjASexKKEn0RThNbE3oTbwB0AACg7SoAAWNybBGJEWsAAAJjZXBzdBF4EX0RghHvIW5nAKBMInAjc2lsb24A9mNyImltZQAAoDUgaQBtAGWgPSJxAACgzSJ2AY0RkRFlAGUAAKC9ImUAZABnoAUjZQAAoAUjcgBrAHSgtSPiIXJrAKC2IwABb3mjEaYRbgDnAHcRMWTxIXVvAKAeIIACY21wcnQAtBG5Eb4RwRHFEeEhdXPloDUi5ABwInR5dgAAoLApcwDpAH0RbgBvAPUA6gCAAWFodwDLEcwRzhGyYwCgNiHlIWVuAKBsInIAAOA12B/dZwCAA2Nvc3R1dncA4xHyEQUSEhIhEiYSKRKAAWFpdQDpEesR7xHwAKMFcgBjAACg7yVwAACgwyKAAWRwdAD4EfwRABJvAHQAAKAAKuwhdXMAoAEqaSJtZXMAAKACKnECCxIAAAAADxLjIXVwAKAGKmEAcgAAoAUm8iNpYW5nbGUAAWR1GhIeEu8hd24AoL0lcAAAoLMlcCJsdXMAAKAEKmUA5QBCD+UAkg9hInJvdwAAoA0pgAFha28ANhJoEncSAAFjbjoSZRJrAIABbHN0AEESRxJNEm8jemVuZ2UAAKDrKXEAdQBhAHIA5QBcBPIjaWFuZ2xlgKG0JWRscgBYElwSYBLvIXduAKC+JeUhZnQAoMIlaSJnaHQAAKC4JWsAAKAjJLEBbRIAAHUSsgFxEgAAcxIAoJIlAKCRJTQAAKCTJWMAawAAoIglAAFlb38ShxJx4D0A5SD1IWl2AOBhIuUgdAAAoBAjAAJwdHd4kRKVEpsSnxJmAADgNdhT3XSgpSJvAG0AAKClIvQhaWUAoMgiAAZESFVWYmRobXB0dXayEsES0RLgEvcS+xIKExoTHxMjEygTNxMAAkxSbHK5ErsSvRK/EgCgVyUAoFQlAKBWJQCgUyUAolAlRFVkdckSyxLNEs8SAKBmJQCgaSUAoGQlAKBnJQACTFJsctgS2hLcEt4SAKBdJQCgWiUAoFwlAKBZJQCjUSVITFJobHLrEu0S7xLxEvMS9RIAoGwlAKBjJQCgYCUAoGslAKBiJQCgXyVvAHgAAKDJKQACTFJscgITBBMGEwgTAKBVJQCgUiUAoBAlAKAMJQCiACVEVWR1EhMUExYTGBMAoGUlAKBoJQCgLCUAoDQlaSJudXMAAKCfIuwhdXMAoJ4iaSJtZXMAAKCgIgACTFJsci8TMRMzEzUTAKBbJQCgWCUAoBglAKAUJQCjAiVITFJobHJCE0QTRhNIE0oTTBMAoGolAKBhJQCgXiUAoDwlAKAkJQCgHCUAAWV2UhNVE3YA5QD5AGIAYQByADuApgCmQAACY2Vpb2ITZhNqE24TcgAA4DXYt9xtAGkAAKBPIG0A5aA9IogRbAAAoVwAYmh0E3YTAKDFKfMhdWIAoMgnbAF+E4QTbABloCIgdAAAoCIgcAAAoU4iRWWJE4sTAKCuKvGgTyI8BeEMqRMAAN8TABQDFB8UAAAjFDQUAAAAAIUUAAAAAI0UAAAAANcU4xT3FPsUAACIFQAAlhWAAWNwcgCuE7ET1RP1IXRlB2GAoikiYWJjZHMAuxO/E8QTzhPSE24AZAAAoEQqciJjdXAAAKBJKgABYXXIE8sTcAAAoEsqcAAAoEcqbwB0AACgQCoA4CkiAP4AAWVv2RPcE3QAAKBBIO4ABAUAAmFlaXXlE+8T9RP4E/AB6hMAAO0TcwAAoE0qbwBuAA1hZABpAGwAO4DnAOdAcgBjAAlhcABzAHOgTCptAACgUCpvAHQAC2GAAWRtbgAIFA0UEhRpAGwAO4C4ALhAcCJ0eXYAAKCyKXQAAIGiADtlGBQZFKJAcgBkAG8A9ABiAXIAAOA12CDdgAFjZWkAKBQqFDIUeQBHZGMAawBtoBMn4SFyawCgEyfHY3IAAKPLJUVjZWZtcz8UQRRHFHcUfBSAFACgwykAocYCZWxGFEkUcQAAoFciZQBhAlAUAAAAAGAUciJyb3cAAAFsclYUWhTlIWZ0AKC6IWkiZ2h0AACguyGAAlJTYWNkAGgUaRRrFG8UcxSuYACgyCRzAHQAAKCbIukhcmMAoJoi4SFzaACgnSJuImludAAAoBAqaQBkAACg7yrjIWlyAKDCKfUhYnN1oGMmaQB0AACgYybsApMUmhS2FAAAwxRvAG4AZaA6APGgVCKrAG0CnxQAAAAAoxRhAHSgLABAYAChASJmbKcUqRTuABMNZQAAAW14rhSyFOUhbnQAoAEiZQDzANIB5wG6FAAAwBRkoEUibwB0AACgbSpuAPQAzAGAAWZyeQDIFMsUzhQA4DXYVN1vAOQA1wEAgakAO3MeAdMUcgAAoBchAAFhb9oU3hRyAHIAAKC1IXMAcwAAoBcnAAFjdeYU6hRyAADgNdi43AABYnDuFPIUZaDPKgCg0SploNAqAKDSKuQhb3QAoO8igANkZWxwcnZ3AAYVEBUbFSEVRBVlFYQV4SFycgABbHIMFQ4VAKA4KQCgNSlwAhYVAAAAABkVcgAAoN4iYwAAoN8i4SFycnCgtiEAoD0pgKIqImJjZG9zACsVMBU6FT4VQRVyImNhcAAAoEgqAAFhdTQVNxVwAACgRipwAACgSipvAHQAAKCNInIAAKBFKgDgKiIA/gACYWxydksVURVuFXMVcgByAG2gtyEAoDwpeQCAAWV2dwBYFWUVaRVxAHACXxUAAAAAYxVyAGUA4wAXFXUA4wAZFWUAZQAAoM4iZSJkZ2UAAKDPImUAbgA7gKQApEBlI2Fycm93AAABbHJ7FX8V5SFmdACgtiFpImdodAAAoLchZQDkAG0VAAFjaYsVkRVvAG4AaQBuAPQAkwFuAHQAAKAxImwiY3R5AACgLSOACUFIYWJjZGVmaGlqbG9yc3R1d3oAuBW7Fb8V1RXgFegV+RUKFhUWHxZUFlcWZRbFFtsW7xb7FgUXChdyAPIAtAJhAHIAAKBlKQACZ2xyc8YVyhXOFdAV5yFlcgCgICDlIXRoAKA4IfIA9QxoAHagECAAoKMiawHZFd4VYSJyb3cAAKAPKWEA4wBfAgABYXnkFecV8iFvbg9hNGQAoUYhYW/tFfQVAAFnciEC8RVyAACgyiF0InNlcQAAoHcqgAFnbG0A/xUCFgUWO4CwALBAdABhALRjcCJ0eXYAAKCxKQABaXIOFhIW8yFodACgfykA4DXYId1hAHIAAAFschsWHRYAoMMhAKDCIYACYWVnc3YAKBauAjYWOhY+Fm0AAKHEIm9zLhY0Fm4AZABzoMQi9SFpdACgZiZhIm1tYQDdY2kAbgAAoPIiAKH3AGlvQxZRFmQAZQAAgfcAO29KFksW90BuI3RpbWVzAACgxyJuAPgAUBZjAHkAUmRjAG8CXhYAAAAAYhZyAG4AAKAeI28AcAAAoA0jgAJscHR1dwBuFnEWdRaSFp4W7CFhciRgZgAA4DXYVd0AotkCZW1wc30WhBaJFo0WcQBkoFAibwB0AACgUSJpIm51cwAAoDgi7CF1cwCgFCLxInVhcmUAoKEiYgBsAGUAYgBhAHIAdwBlAGQAZwDlANcAbgCAAWFkaAClFqoWtBZyAHIAbwD3APUMbwB3AG4AYQByAHIAbwB3APMA8xVhI3Jwb29uAAABbHK8FsAWZQBmAPQAHBZpAGcAaAD0AB4WYgHJFs8WawBhAHIAbwD3AJILbwLUFgAAAADYFnIAbgAAoB8jbwBwAACgDCOAAWNvdADhFukW7BYAAXJ55RboFgDgNdi53FVkbAAAoPYp8iFvaxFhAAFkcvMW9xZvAHQAAKDxImkA5qC/JVsSAAFhaP8WAhdyAPIANQNhAPIA1wvhIm5nbGUAoKYpAAFjaQ4XEBd5AF9k5yJyYXJyAKD/JwAJRGFjZGVmZ2xtbm9wcXJzdHV4MRc4F0YXWxcyBF4XaRd5F40XrBe0F78X2RcVGCEYLRg1GEAYAAFEbzUXgRZvAPQA+BUAAWNzPBdCF3UAdABlADuA6QDpQPQhZXIAoG4qAAJhaW95TRdQF1YXWhfyIW9uG2FyAGOgViI7gOoA6kDsIW9uAKBVIk1kbwB0ABdhAAFEcmIXZhdvAHQAAKBSIgDgNdgi3XKhmipuF3QXYQB2AGUAO4DoAOhAZKCWKm8AdAAAoJgqgKGZKmlscwCAF4UXhxfuInRlcnMAoOcjAKATIWSglSpvAHQAAKCXKoABYXBzAJMXlheiF2MAcgATYXQAeQBzogUinxcAAAAAoRdlAHQAAKAFInAAMaADIDMBqRerFwCgBCAAoAUgAAFnc7AXsRdLYXAAAKACIAABZ3C4F7sXbwBuABlhZgAA4DXYVt2AAWFscwDFF8sXzxdyAHOg1SJsAACg4yl1AHMAAKBxKmkAAKG1A2x21RfYF28AbgC1Y/VjAAJjc3V24BfoF/0XEBgAAWlv5BdWF3IAYwAAoFYiaQLuFwAAAADwF+0ADQThIW50AAFnbPUX+Rd0AHIAAKCWKuUhc3MAoJUqgAFhZWkAAxgGGAoYbABzAD1gcwB0AACgXyJ2AESgYSJEAACgeCrwImFyc2wAoOUpAAFEYRkYHRhvAHQAAKBTInIAcgAAoHEpgAFjZGkAJxgqGO0XcgAAoC8hbwD0AIwCAAFhaDEYMhi3YzuA8ADwQAABbXI5GD0YbAA7gOsA60BvAACgrCCAAWNpcABGGEgYSxhsACFgcwD0ACwEAAFlb08YVxhjAHQAYQB0AGkAbwDuABoEbgBlAG4AdABpAGEAbADlADME4Ql1GAAAgRgAAIMYiBgAAAAAoRilGAAAqhgAALsYvhjRGAAA1xgnGWwAbABpAG4AZwBkAG8AdABzAGUA8QBlF3kARGRtImFsZQAAoEAmgAFpbHIAjRiRGJ0Y7CFpZwCgA/tpApcYAAAAAJoYZwAAoAD7aQBnAACgBPsA4DXYI93sIWlnAKAB++whaWcA4GYAagCAAWFsdACvGLIYthh0AACgbSZpAGcAAKAC+24AcwAAoLElbwBmAJJh8AHCGAAAxhhmAADgNdhX3QABYWvJGMwYbADsAGsEdqDUIgCg2SphI3J0aW50AACgDSoAAWFv2hgiGQABY3PeGB8ZsQPnGP0YBRkSGRUZAAAdGbID7xjyGPQY9xj5GAAA+xg7gL0AvUAAoFMhO4C8ALxAAKBVIQCgWSEAoFshswEBGQAAAxkAoFQhAKBWIbQCCxkOGQAAAAAQGTuAvgC+QACgVyEAoFwhNQAAoFghtgEZGQAAGxkAoFohAKBdITgAAKBeIWwAAKBEIHcAbgAAoCIjYwByAADgNdi73IAIRWFiY2RlZmdpamxub3JzdHYARhlKGVoZXhlmGWkZkhmWGZkZnRmgGa0ZxhnLGc8Z4BkjGmygZyIAoIwqgAFjbXAAUBlTGVgZ9SF0ZfVhbQBhAOSgswM6FgCghipyImV2ZQAfYQABaXliGWUZcgBjAB1hM2RvAHQAIWGAoWUibHFzAMYEcBl6GfGhZSLOBAAAdhlsAGEAbgD0AN8EgKF+KmNkbACBGYQZjBljAACgqSpvAHQAb6CAKmyggioAoIQqZeDbIgD+cwAAoJQqcgAA4DXYJN3noGsirATtIWVsAKA3IWMAeQBTZIChdyJFYWoApxmpGasZAKCSKgCgpSoAoKQqAAJFYWVztBm2Gb0ZwhkAoGkicABwoIoq8iFveACgiipxoIgq8aCIKrUZaQBtAACg5yJwAGYAAOA12FjdYQB2AOUAYwIAAWNp0xnWGXIAAKAKIW0AAKFzImVs3BneGQCgjioAoJAqAIM+ADtjZGxxco0E6xn0GfgZ/BkBGgABY2nvGfEZAKCnKnIAAKB6Km8AdAAAoNci0CFhcgCglSl1ImVzdAAAoHwqgAJhZGVscwAKGvQZFhrVBCAa8AEPGgAAFBpwAHIAbwD4AFkZcgAAoHgpcQAAAWxxxAQbGmwAZQBzAPMASRlpAO0A5AQAAWVuJxouGnIjdG5lcXEAAOBpIgD+xQAsGgAFQWFiY2Vma29zeUAaQxpmGmoabRqDGocalhrCGtMacgDyAMwCAAJpbG1yShpOGlAaVBpyAHMA8ABxD2YAvWBpAGwA9AASBQABZHJYGlsaYwB5AEpkAKGUIWN3YBpkGmkAcgAAoEgpAKCtIWEAcgAAoA8h6SFyYyVhgAFhbHIAcxp7Gn8a8iF0c3WgZSZpAHQAAKBlJuwhaXAAoCYg4yFvbgCguSJyAADgNdgl3XMAAAFld4wakRphInJvdwAAoCUpYSJyb3cAAKAmKYACYW1vcHIAnxqjGqcauhq+GnIAcgAAoP8h9CFodACgOyJrAAABbHKsGrMaZSRmdGFycm93AACgqSHpJGdodGFycm93AKCqIWYAAOA12Fnd4iFhcgCgFSCAAWNsdADIGswa0BpyAADgNdi93GEAcwDoAGka8iFvaydhAAFicNca2xr1IWxsAKBDIOghZW4AoBAg4Qr2GgAA/RoAAAgbExsaGwAAIRs7GwAAAAA+G2IbmRuVG6sbAACyG80b0htjAHUAdABlADuA7QDtQAChYyBpeQEbBhtyAGMAO4DuAO5AOGQAAWN4CxsNG3kANWRjAGwAO4ChAKFAAAFmcssCFhsA4DXYJt1yAGEAdgBlADuA7ADsQIChSCFpbm8AJxsyGzYbAAFpbisbLxtuAHQAAKAMKnQAAKAtIuYhaW4AoNwpdABhAACgKSHsIWlnM2GAAWFvcABDG1sbXhuAAWNndABJG0sbWRtyACthgAFlbHAAcQVRG1UbaQBuAOUAyAVhAHIA9AByBWgAMWFmAACgtyJlAGQAtWEAoggiY2ZvdGkbbRt1G3kb4SFyZQCgBSFpAG4AdKAeImkAZQAAoN0pZABvAPQAWxsAoisiY2VscIEbhRuPG5QbYQBsAACguiIAAWdyiRuNG2UAcgDzACMQ4wCCG2EicmhrAACgFyryIW9kAKA8KgACY2dwdJ8boRukG6gbeQBRZG8AbgAvYWYAAOA12FrdYQC5Y3UAZQBzAHQAO4C/AL9AAAFjabUbuRtyAADgNdi+3G4AAKIIIkVkc3bCG8QbyBvQAwCg+SJvAHQAAKD1Inag9CIAoPMiaaBiIOwhZGUpYesB1hsAANkbYwB5AFZkbAA7gO8A70AAA2NmbW9zdeYb7hvyG/Ub+hsFHAABaXnqG+0bcgBjADVhOWRyAADgNdgn3eEhdGg3YnAAZgAA4DXYW93jAf8bAAADHHIAAOA12L/c8iFjeVhk6yFjeVRkAARhY2ZnaGpvcxUcGhwiHCYcKhwtHDAcNRzwIXBhdqC6A/BjAAFleR4cIRzkIWlsN2E6ZHIAAOA12CjdciJlZW4AOGFjAHkARWRjAHkAXGRwAGYAAOA12FzdYwByAADgNdjA3IALQUJFSGFiY2RlZmdoamxtbm9wcnN0dXYAXhxtHHEcdRx5HN8cBx0dHTwd3B3tHfEdAR4EHh0eLB5FHrwewx7hHgkfPR9LH4ABYXJ0AGQcZxxpHHIA8gBvB/IAxQLhIWlsAKAbKeEhcnIAoA4pZ6BmIgCgiyphAHIAAKBiKWMJjRwAAJAcAACVHAAAAAAAAAAAAACZHJwcAACmHKgcrRwAANIc9SF0ZTph7SJwdHl2AKC0KXIAYQDuAFoG4iFkYbtjZwAAoegnZGyhHKMcAKCRKeUAiwYAoIUqdQBvADuAqwCrQHIAgKOQIWJmaGxwc3QAuhy/HMIcxBzHHMoczhxmoOQhcwAAoB8pcwAAoB0p6wCyGnAAAKCrIWwAAKA5KWkAbQAAoHMpbAAAoKIhAKGrKmFl1hzaHGkAbAAAoBkpc6CtKgDgrSoA/oABYWJyAOUc6RztHHIAcgAAoAwpcgBrAACgcicAAWFr8Rz4HGMAAAFla/Yc9xx7YFtgAAFlc/wc/hwAoIspbAAAAWR1Ax0FHQCgjykAoI0pAAJhZXV5Dh0RHRodHB3yIW9uPmEAAWRpFR0YHWkAbAA8YewAowbiAPccO2QAAmNxcnMkHScdLB05HWEAAKA2KXUAbwDyoBwgqhEAAWR1MB00HeghYXIAoGcpcyJoYXIAAKBLKWgAAKCyIQCiZCJmZ3FzRB1FB5Qdnh10AIACYWhscnQATh1WHWUdbB2NHXIicm93AHSgkCFhAOkAzxxhI3Jwb29uAAABZHVeHWId7yF3bgCgvSFwAACgvCHlJGZ0YXJyb3dzAKDHIWkiZ2h0AIABYWhzAHUdex2DHXIicm93APOglCGdBmEAcgBwAG8AbwBuAPMAzgtxAHUAaQBnAGEAcgByAG8A9wBlGugkcmVldGltZXMAoMsi8aFkIk0HAACaHWwAYQBuAPQAXgcAon0qY2Rnc6YdqR2xHbcdYwAAoKgqbwB0AG+gfypyoIEqAKCDKmXg2iIA/nMAAKCTKoACYWRlZ3MAwB3GHcod1h3ZHXAAcAByAG8A+ACmHG8AdAAAoNYicQAAAWdxzx3SHXQA8gBGB2cAdADyAHQcdADyAFMHaQDtAGMHgAFpbHIA4h3mHeod8yFodACgfClvAG8A8gDKBgDgNdgp3UWgdiIAoJEqYQH1Hf4dcgAAAWR1YB35HWygvCEAoGopbABrAACghCVjAHkAWWQAomoiYWNodAweDx4VHhkecgDyAGsdbwByAG4AZQDyAGAW4SFyZACgaylyAGkAAKD6JQABaW8hHiQe5CFvdEBh9SFzdGGgsCPjIWhlAKCwIwACRWFlczMeNR48HkEeAKBoInAAcKCJKvIhb3gAoIkqcaCHKvGghyo0HmkAbQAAoOYiAARhYm5vcHR3elIeXB5fHoUelh6mHqsetB4AAW5yVh5ZHmcAAKDsJ3IAAKD9IXIA6wCwBmcAgAFsbXIAZh52Hnse5SFmdAABYXKIB2weaQBnAGgAdABhAHIAcgBvAPcAkwfhInBzdG8AoPwnaQBnAGgAdABhAHIAcgBvAPcAmgdwI2Fycm93AAABbHKNHpEeZQBmAPQAxhxpImdodAAAoKwhgAFhZmwAnB6fHqIecgAAoIUpAOA12F3ddQBzAACgLSppIm1lcwAAoDQqYQGvHrMecwB0AACgFyLhAIoOZaHKJbkeRhLuIWdlAKDKJWEAcgBsoCgAdAAAoJMpgAJhY2htdADMHs8e1R7bHt0ecgDyAJ0GbwByAG4AZQDyANYWYQByAGSgyyEAoG0pAKAOIHIAaQAAoL8iAANhY2hpcXTrHu8e1QfzHv0eBh/xIXVvAKA5IHIAAOA12MHcbQDloXIi+h4AAPweAKCNKgCgjyoAAWJ19xwBH28AcqAYIACgGiDyIW9rQmEAhDwAO2NkaGlscXJCBhcfxh0gHyQfKB8sHzEfAAFjaRsfHR8AoKYqcgAAoHkqcgBlAOUAkx3tIWVzAKDJIuEhcnIAoHYpdSJlc3QAAKB7KgABUGk1HzkfYQByAACglillocMlAgdfEnIAAAFkdUIfRx9zImhhcgAAoEop6CFhcgCgZikAAWVuTx9WH3IjdG5lcXEAAOBoIgD+xQBUHwAHRGFjZGVmaGlsbm9wc3VuH3Ifoh+rH68ftx+7H74f5h/uH/MfBwj/HwsgxCFvdACgOiIAAmNscHJ5H30fiR+eH3IAO4CvAK9AAAFldIEfgx8AoEImZaAgJ3MAZQAAoCAnc6CmIXQAbwCAoaYhZGx1AJQfmB+cH28AdwDuAHkDZQBmAPQA6gbwAOkO6yFlcgCgriUAAW95ph+qH+0hbWEAoCkqPGThIXNoAKAUIOElc3VyZWRhbmdsZQCgISJyAADgNdgq3W8AAKAnIYABY2RuAMQfyR/bH3IAbwA7gLUAtUBhoiMi0B8AANMf1x9zAPQAKxFpAHIAAKDwKm8AdAA7gLcAt0B1AHMA4qESIh4TAADjH3WgOCIAoCoqYwHqH+0fcAAAoNsq8gB+GnAAbAB1APMACAgAAWRw9x/7H+UhbHMAoKciZgAA4DXYXt0AAWN0AyAHIHIAAOA12MLc8CFvcwCgPiJsobwDECAVIPQiaW1hcACguCJhAPAAEyAADEdMUlZhYmNkZWZnaGlqbG1vcHJzdHV2dzwgRyBmIG0geSCqILgg2iDeIBEhFSEyIUMhTSFQIZwhnyHSIQAiIyKLIrEivyIUIwABZ3RAIEMgAODZIjgD9uBrItIgBwmAAWVsdABNIF8gYiBmAHQAAAFhclMgWCByInJvdwAAoM0h6SRnaHRhcnJvdwCgziEA4NgiOAP24Goi0iBfCekkZ2h0YXJyb3cAoM8hAAFEZHEgdSDhIXNoAKCvIuEhc2gAoK4igAJiY25wdACCIIYgiSCNIKIgbABhAACgByL1IXRlRGFnAADgICLSIACiSSJFaW9wlSCYIJwgniAA4HAqOANkAADgSyI4A3MASWFyAG8A+AAyCnUAcgBhoG4mbADzoG4mmwjzAa8gAACzIHAAO4CgAKBAbQBwAOXgTiI4AyoJgAJhZW91eQDBIMogzSDWINkg8AHGIAAAyCAAoEMqbwBuAEhh5CFpbEZhbgBnAGSgRyJvAHQAAOBtKjgDcAAAoEIqPWThIXNoAKATIACjYCJBYWRxc3jpIO0g+SD+IAIhDCFyAHIAAKDXIXIAAAFocvIg9SBrAACgJClvoJch9wAGD28AdAAA4FAiOAN1AGkA9gC7CAABZWkGIQohYQByAACgKCntAN8I6SFzdPOgBCLlCHIAAOA12CvdAAJFZXN0/wgcISshLiHxoXEiIiEAABMJ8aFxIgAJAAAnIWwAYQBuAPQAEwlpAO0AGQlyoG8iAKBvIoABQWFwADghOyE/IXIA8gBeIHIAcgAAoK4hYQByAACg8ipzogsiSiEAAAAAxwtkoPwiAKD6ImMAeQBaZIADQUVhZGVzdABcIV8hYiFmIWkhkyGWIXIA8gBXIADgZiI4A3IAcgAAoJohcgAAoCUggKFwImZxcwBwIYQhjiF0AAABYXJ1IXohcgByAG8A9wBlIWkAZwBoAHQAYQByAHIAbwD3AD4h8aFwImAhAACKIWwAYQBuAPQAZwlz4H0qOAMAoG4iaQDtAG0JcqBuImkA5aDqIkUJaQDkADoKAAFwdKMhpyFmAADgNdhf3YCBrAA7aW4AriGvIcchrEBuAIChCSJFZHYAtyG6Ib8hAOD5IjgDbwB0AADg9SI4A+EB1gjEIcYhAKD3IgCg9iJpAHagDCLhAagJzyHRIQCg/iIAoP0igAFhb3IA2CHsIfEhcgCAoSYiYXN0AOAh5SHpIWwAbABlAOwAywhsAADg/SrlIADgAiI4A2wiaW50AACgFCrjoYAi9yEAAPohdQDlAJsJY+CvKjgDZaCAIvEAkwkAAkFhaXQHIgoiFyIeInIA8gBsIHIAcgAAoZshY3cRIhQiAOAzKTgDAOCdITgDZyRodGFycm93AACgmyFyAGkA5aDrIr4JgANjaGltcHF1AC8iPCJHIpwhTSJQIloigKGBImNlcgA2Iv0JOSJ1AOUABgoA4DXYw9zvIXJ0bQKdIQAAAABEImEAcgDhAOEhbQBloEEi8aBEIiYKYQDyAMsIcwB1AAABYnBWIlgi5QDUCeUA3wmAAWJjcABgInMieCKAoYQiRWVzAGci7glqIgDgxSo4A2UAdABl4IIi0iBxAPGgiCJoImMAZaCBIvEA/gmAoYUiRWVzAH8iFgqCIgDgxio4A2UAdABl4IMi0iBxAPGgiSKAIgACZ2lscpIilCKaIpwi7AAMCWwAZABlADuA8QDxQOcAWwlpI2FuZ2xlAAABbHKkIqoi5SFmdGWg6iLxAEUJaSJnaHQAZaDrIvEAvgltoL0DAKEjAGVzuCK8InIAbwAAoBYhcAAAoAcggARESGFkZ2lscnMAziLSItYi2iLeIugi7SICIw8j4SFzaACgrSLhIXJyAKAEKXAAAOBNItIg4SFzaACgrCIAAWV04iLlIgDgZSLSIADgPgDSIG4iZmluAACg3imAAUFldADzIvci+iJyAHIAAKACKQDgZCLSIHLgPADSIGkAZQAA4LQi0iAAAUF0BiMKI3IAcgAAoAMp8iFpZQDgtSLSIGkAbQAA4Dwi0iCAAUFhbgAaIx4jKiNyAHIAAKDWIXIAAAFociMjJiNrAACgIylvoJYh9wD/DuUhYXIAoCcpUxJqFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVCMAAF4jaSN/I4IjjSOeI8AUAAAAAKYjwCMAANoj3yMAAO8jHiQvJD8kRCQAAWNzVyNsFHUAdABlADuA8wDzQAABaXlhI2cjcgBjoJoiO4D0APRAPmSAAmFiaW9zAHEjdCN3I3EBeiNzAOgAdhTsIWFjUWF2AACgOCrvIWxkAKC8KewhaWdTYQABY3KFI4kjaQByAACgvykA4DXYLN1vA5QjAAAAAJYjAACcI24A22JhAHYAZQA7gPIA8kAAoMEpAAFibaEjjAphAHIAAKC1KQACYWNpdKwjryO6I70jcgDyAFkUAAFpcrMjtiNyAACgvinvIXNzAKC7KW4A5QDZCgCgwCmAAWFlaQDFI8gjyyNjAHIATWFnAGEAyWOAAWNkbgDRI9Qj1iPyIW9uv2MAoLYpdQDzAHgBcABmAADgNdhg3YABYWVsAOQj5yPrI3IAAKC3KXIAcAAAoLkpdQDzAHwBAKMoImFkaW9zdvkj/CMPJBMkFiQbJHIA8gBeFIChXSplZm0AAyQJJAwkcgBvoDQhZgAAoDQhO4CqAKpAO4C6ALpA5yFvZgCgtiJyAACgVipsIm9wZQAAoFcqAKBbKoABY2xvACMkJSQrJPIACCRhAHMAaAA7gPgA+EBsAACgmCJpAGwBMyQ4JGQAZQA7gPUA9UBlAHMAYaCXInMAAKA2Km0AbAA7gPYA9kDiIWFyAKA9I+EKXiQAAHokAAB8JJQkAACYJKkkAAAAALUkEQsAAPAkAAAAAAQleiUAAIMlcgCAoSUiYXN0AGUkbyQBCwCBtgA7bGokayS2QGwAZQDsABgDaQJ1JAAAAAB4JG0AAKDzKgCg/Sp5AD9kcgCAAmNpbXB0AIUkiCSLJJkSjyRuAHQAJWBvAGQALmBpAGwAAKAwIOUhbmsAoDEgcgAA4DXYLd2AAWltbwCdJKAkpCR2oMYD1WNtAGEA9AD+B24AZQAAoA4m9KHAA64kAAC0JGMjaGZvcmsAAKDUItZjAAFhdbgkxCRuAAABY2u9JMIkawBooA8hAKAOIfYAaRpzAACkKwBhYmNkZW1zdNMkIRPXJNsk4STjJOck6yTjIWlyAKAjKmkAcgAAoCIqAAFvdYsW3yQAoCUqAKByKm4AO4CxALFAaQBtAACgJip3AG8AAKAnKoABaXB1APUk+iT+JO4idGludACgFSpmAADgNdhh3W4AZAA7gKMAo0CApHoiRWFjZWlub3N1ABMlFSUYJRslTCVRJVklSSV1JQCgsypwAACgtyp1AOUAPwtjoK8qgKJ6ImFjZW5zACclLSU0JTYlSSVwAHAAcgBvAPgAFyV1AHIAbAB5AGUA8QA/C/EAOAuAAWFlcwA8JUElRSXwInByb3gAoLkqcQBxAACgtSppAG0AAKDoImkA7QBEC20AZQDzoDIgIguAAUVhcwBDJVclRSXwAEAlgAFkZnAATwtfJXElgAFhbHMAZSVpJW0l7CFhcgCgLiPpIW5lAKASI/UhcmYAoBMjdKAdIu8AWQvyIWVsAKCwIgABY2l9JYElcgAA4DXYxdzIY24iY3NwAACgCCAAA2Zpb3BzdZElKxuVJZolnyWkJXIAAOA12C7dcABmAADgNdhi3XIiaW1lAACgVyBjAHIAAOA12MbcgAFhZW8AqiW6JcAldAAAAWVpryW2JXIAbgBpAG8AbgDzABkFbgB0AACgFipzAHQAZaA/APEACRj0AG0LgApBQkhhYmNkZWZoaWxtbm9wcnN0dXgA4yXyJfYl+iVpJpAmpia9JtUm5ib4JlonaCdxJ3UnnietJ7EnyCfiJ+cngAFhcnQA6SXsJe4lcgDyAJkM8gD6AuEhaWwAoBwpYQByAPIA3BVhAHIAAKBkKYADY2RlbnFydAAGJhAmEyYYJiYmKyZaJgABZXUKJg0mAOA9IjEDdABlAFVhaQDjACAN7SJwdHl2AKCzKWcAgKHpJ2RlbAAgJiImJCYAoJIpAKClKeUA9wt1AG8AO4C7ALtAcgAApZIhYWJjZmhscHN0dz0mQCZFJkcmSiZMJk4mUSZVJlgmcAAAoHUpZqDlIXMAAKAgKQCgMylzAACgHinrALka8ACVHmwAAKBFKWkAbQAAoHQpbAAAoKMhAKCdIQABYWleJmImaQBsAACgGilvAG6gNiJhAGwA8wB2C4ABYWJyAG8mciZ2JnIA8gAvEnIAawAAoHMnAAFha3omgSZjAAABZWt/JoAmfWBdYAABZXOFJocmAKCMKWwAAAFkdYwmjiYAoI4pAKCQKQACYWV1eZcmmiajJqUm8iFvbllhAAFkaZ4moSZpAGwAV2HsAA8M4gCAJkBkAAJjbHFzrSawJrUmuiZhAACgNylkImhhcgAAoGkpdQBvAPKgHSCjAWgAAKCzIYABYWNnAMMm0iaUC2wAgKEcIWlwcwDLJs4migxuAOUAoAxhAHIA9ADaC3QAAKCtJYABaWxyANsm3ybjJvMhaHQAoH0pbwBvAPIANgwA4DXYL90AAWFv6ib1JnIAAAFkde8m8SYAoMEhbKDAIQCgbCl2oMED8WOAAWducwD+Jk4nUCdoAHQAAANhaGxyc3QKJxInISc1Jz0nRydyInJvdwB0oJIhYQDpAFYmYSNycG9vbgAAAWR1GiceJ28AdwDuAPAmcAAAoMAh5SFmdAABYWgnJy0ncgByAG8AdwDzAAkMYQByAHAAbwBvAG4A8wATBGklZ2h0YXJyb3dzAACgySFxAHUAaQBnAGEAcgByAG8A9wBZJugkcmVldGltZXMAoMwiZwDaYmkAbgBnAGQAbwB0AHMAZQDxABwYgAFhaG0AYCdjJ2YncgDyAAkMYQDyABMEAKAPIG8idXN0AGGgsSPjIWhlAKCxI+0haWQAoO4qAAJhYnB0fCeGJ4knmScAAW5ygCeDJ2cAAKDtJ3IAAKD+IXIA6wAcDIABYWZsAI8nkieVJ3IAAKCGKQDgNdhj3XUAcwAAoC4qaSJtZXMAAKA1KgABYXCiJ6gncgBnoCkAdAAAoJQp7yJsaW50AKASKmEAcgDyADwnAAJhY2hxuCe8J6EMwCfxIXVvAKA6IHIAAOA12MfcAAFidYAmxCdvAPKgGSCoAYABaGlyAM4n0ifWJ3IAZQDlAE0n7SFlcwCgyiJpAIChuSVlZmwAXAxjEt4n9CFyaQCgzinsInVoYXIAoGgpAKAeIWENBSgJKA0oSyhVKIYoAACLKLAoAAAAAOMo5ygAABApJCkxKW0pcSmHKaYpAACYKgAAAACxKmMidXRlAFthcQB1AO8ABR+ApHsiRWFjZWlucHN5ABwoHignKCooLygyKEEoRihJKACgtCrwASMoAAAlKACguCpvAG4AYWF1AOUAgw1koLAqaQBsAF9hcgBjAF1hgAFFYXMAOCg6KD0oAKC2KnAAAKC6KmkAbQAAoOki7yJsaW50AKATKmkA7QCIDUFkbwB0AGKixSKRFgAAAABTKACgZiqAA0FhY21zdHgAYChkKG8ocyh1KHkogihyAHIAAKDYIXIAAAFocmkoayjrAJAab6CYIfcAzAd0ADuApwCnQGkAO2D3IWFyAKApKW0AAAFpbn4ozQBuAHUA8wDOAHQAAKA2J3IA7+A12DDdIxkAAmFjb3mRKJUonSisKHIAcAAAoG8mAAFoeZkonChjAHkASWRIZHIAdABtAqUoAAAAAKgoaQDkAFsPYQByAGEA7ABsJDuArQCtQAABZ22zKLsobQBhAAChwwNmdroouijCY4CjPCJkZWdsbnByAMgozCjPKNMo1yjaKN4obwB0AACgairxoEMiCw5FoJ4qAKCgKkWgnSoAoJ8qZQAAoEYi7CF1cwCgJCrhIXJyAKByKWEAcgDyAPwMAAJhZWl07Sj8KAEpCCkAAWxz8Sj4KGwAcwBlAHQAbQDpAH8oaABwAACgMyrwImFyc2wAoOQpAAFkbFoPBSllAACgIyNloKoqc6CsKgDgrCoA/oABZmxwABUpGCkfKfQhY3lMZGKgLwBhoMQpcgAAoD8jZgAA4DXYZN1hAAABZHIoKRcDZQBzAHWgYCZpAHQAAKBgJoABY3N1ADYpRilhKQABYXU6KUApcABzoJMiAOCTIgD+cABzoJQiAOCUIgD+dQAAAWJwSylWKQChjyJlcz4NUCllAHQAZaCPIvEAPw0AoZAiZXNIDVspZQB0AGWgkCLxAEkNAKGhJWFmZilbBHIAZQFrKVwEAKChJWEAcgDyAAMNAAJjZW10dyl7KX8pgilyAADgNdjI3HQAbQDuAM4AaQDsAAYpYQByAOYAVw0AAWFyiimOKXIA5qAGJhESAAFhbpIpoylpImdodAAAAWVwmSmgKXAAcwBpAGwAbwDuANkXaADpAKAkcwCvYIACYmNtbnAArin8KY4NJSooKgCkgiJFZGVtbnByc7wpvinCKcgpzCnUKdgp3CkAoMUqbwB0AACgvSpkoIYibwB0AACgwyr1IWx0AKDBKgABRWXQKdIpAKDLKgCgiiLsIXVzAKC/KuEhcnIAoHkpgAFlaXUA4inxKfQpdAAAoYIiZW7oKewpcQDxoIYivSllAHEA8aCKItEpbQAAoMcqAAFicPgp+ikAoNUqAKDTKmMAgKJ7ImFjZW5zAAcqDSoUKhYqRihwAHAAcgBvAPgAIyh1AHIAbAB5AGUA8QCDDfEAfA2AAWFlcwAcKiIqPShwAHAAcgBvAPgAPChxAPEAOShnAACgaiYApoMiMTIzRWRlaGxtbnBzPCo/KkIqRSpHKlIqWCpjKmcqaypzKncqO4C5ALlAO4CyALJAO4CzALNAAKDGKgABb3NLKk4qdAAAoL4qdQBiAACg2CpkoIcibwB0AACgxCpzAAABb3VdKmAqbAAAoMknYgAAoNcq4SFycgCgeyn1IWx0AKDCKgABRWVvKnEqAKDMKgCgiyLsIXVzAKDAKoABZWl1AH0qjCqPKnQAAKGDImVugyqHKnEA8aCHIkYqZQBxAPGgiyJwKm0AAKDIKgABYnCTKpUqAKDUKgCg1iqAAUFhbgCdKqEqrCpyAHIAAKDZIXIAAAFocqYqqCrrAJUab6CZIfcAxQf3IWFyAKAqKWwAaQBnADuA3wDfQOELzyrZKtwq6SrsKvEqAAD1KjQrAAAAAAAAAAAAAEwrbCsAAHErvSsAAAAAAADRK3IC1CoAAAAA2CrnIWV0AKAWI8RjcgDrAOUKgAFhZXkA4SrkKucq8iFvbmVh5CFpbGNhQmRvAPQAIg5sInJlYwAAoBUjcgAA4DXYMd0AAmVpa2/7KhIrKCsuK/IBACsAAAkrZQAAATRm6g0EK28AcgDlAOsNYQBzorgDECsAAAAAEit5AG0A0WMAAWNuFislK2sAAAFhcxsrIStwAHAAcgBvAPgAFw5pAG0AAKA8InMA8AD9DQABYXMsKyEr8AAXDnIAbgA7gP4A/kDsATgrOyswG2QA5QBnAmUAcwCAgdcAO2JkAEMrRCtJK9dAYaCgInIAAKAxKgCgMCqAAWVwcwBRK1MraSvhAAkh4qKkIlsrXysAAAAAYytvAHQAAKA2I2kAcgAAoPEqb+A12GXdcgBrAACg2irhAHgociJpbWUAAKA0IIABYWlwAHYreSu3K2QA5QC+DYADYWRlbXBzdACFK6MrmiunK6wrsCuzK24iZ2xlAACitSVkbHFykCuUK5ornCvvIXduAKC/JeUhZnRloMMl8QACBwCgXCJpImdodABloLkl8QBdDG8AdAAAoOwlaSJudXMAAKA6KuwhdXMAoDkqYgAAoM0p6SFtZQCgOyrlInppdW0AoOIjgAFjaHQAwivKK80rAAFyecYrySsA4DXYydxGZGMAeQBbZPIhb2tnYQABaW/UK9creAD0ANERaCJlYWQAAAFsct4r5ytlAGYAdABhAHIAcgBvAPcAXQbpJGdodGFycm93AKCgIQAJQUhhYmNkZmdobG1vcHJzdHV3CiwNLBEsHSwnLDEsQCxLLFIsYix6LIQsjyzLLOgs7Sz/LAotcgDyAAkDYQByAACgYykAAWNyFSwbLHUAdABlADuA+gD6QPIACQ1yAOMBIywAACUseQBeZHYAZQBtYQABaXkrLDAscgBjADuA+wD7QENkgAFhYmgANyw6LD0scgDyANEO7CFhY3FhYQDyAOAOAAFpckQsSCzzIWh0AKB+KQDgNdgy3XIAYQB2AGUAO4D5APlAYQFWLF8scgAAAWxyWixcLACgvyEAoL4hbABrAACggCUAAWN0Zix2LG8CbCwAAAAAcyxyAG4AZaAcI3IAAKAcI28AcAAAoA8jcgBpAACg+CUAAWFsfiyBLGMAcgBrYTuAqACoQAABZ3CILIssbwBuAHNhZgAA4DXYZt0AA2FkaGxzdZksniynLLgsuyzFLHIAcgBvAPcACQ1vAHcAbgBhAHIAcgBvAPcA2A5hI3Jwb29uAAABbHKvLLMsZQBmAPQAWyxpAGcAaAD0AF0sdQDzAKYOaQAAocUDaGzBLMIs0mNvAG4AxWPwI2Fycm93cwCgyCGAAWNpdADRLOEs5CxvAtcsAAAAAN4scgBuAGWgHSNyAACgHSNvAHAAAKAOI24AZwBvYXIAaQAAoPklYwByAADgNdjK3IABZGlyAPMs9yz6LG8AdAAAoPAi7CFkZWlhaQBmoLUlAKC0JQABYW0DLQYtcgDyAMosbAA7gPwA/EDhIm5nbGUAoKcpgAdBQkRhY2RlZmxub3Byc3oAJy0qLTAtNC2bLZ0toS2/LcMtxy3TLdgt3C3gLfwtcgDyABADYQByAHag6CoAoOkqYQBzAOgA/gIAAW5yOC08LechcnQAoJwpgANla25wcnN0AJkpSC1NLVQtXi1iLYItYQBwAHAA4QAaHG8AdABoAGkAbgDnAKEXgAFoaXIAoSmzJFotbwBwAPQAdCVooJUh7wD4JgABaXVmLWotZwBtAOEAuygAAWJwbi14LXMjZXRuZXEAceCKIgD+AODLKgD+cyNldG5lcQBx4IsiAP4A4MwqAP4AAWhyhi2KLWUAdADhABIraSNhbmdsZQAAAWxyki2WLeUhZnQAoLIiaSJnaHQAAKCzInkAMmThIXNoAKCiIoABZWxyAKcttC24LWKiKCKuLQAAAACyLWEAcgAAoLsicQAAoFoi7CFpcACg7iIAAWJ0vC1eD2EA8gBfD3IAAOA12DPddAByAOkAlS1zAHUAAAFicM0t0C0A4IIi0iAA4IMi0iBwAGYAAOA12GfdcgBvAPAAWQt0AHIA6QCaLQABY3XkLegtcgAA4DXYy9wAAWJw7C30LW4AAAFFZXUt8S0A4IoiAP5uAAABRWV/LfktAOCLIgD+6SJnemFnAKCaKYADY2Vmb3BycwANLhAuJS4pLiMuLi40LukhcmN1YQABZGkULiEuAAFiZxguHC5hAHIAAKBfKmUAcaAnIgCgWSLlIXJwAKAYIXIAAOA12DTdcABmAADgNdho3WWgQCJhAHQA6ABqD2MAcgAA4DXYzNzjCuQRUC4AAFQuAABYLmIuAAAAAGMubS5wLnQuAAAAAIguki4AAJouJxIqEnQAcgDpAB0ScgAA4DXYNd0AAUFhWy5eLnIA8gDnAnIA8gCTB75jAAFBYWYuaS5yAPIA4AJyAPIAjAdhAPAAeh5pAHMAAKD7IoABZHB0APgReS6DLgABZmx9LoAuAOA12GnddQDzAP8RaQBtAOUABBIAAUFhiy6OLnIA8gDuAnIA8gCaBwABY3GVLgoScgAA4DXYzdwAAXB0nS6hLmwAdQDzACUScgDpACASAARhY2VmaW9zdbEuvC7ELsguzC7PLtQu2S5jAAABdXm2LrsudABlADuA/QD9QE9kAAFpecAuwy5yAGMAd2FLZG4AO4ClAKVAcgAA4DXYNt1jAHkAV2RwAGYAAOA12GrdYwByAADgNdjO3AABY23dLt8ueQBOZGwAO4D/AP9AAAVhY2RlZmhpb3N38y73Lv8uAi8MLxAvEy8YLx0vIi9jInV0ZQB6YQABYXn7Lv4u8iFvbn5hN2RvAHQAfGEAAWV0Bi8KL3QAcgDmAB8QYQC2Y3IAAOA12DfdYwB5ADZk5yJyYXJyAKDdIXAAZgAA4DXYa91jAHIAAOA12M/cAAFqbiYvKC8AoA0gagAAoAwg");var hr;(function(e){e[e.VALUE_LENGTH=49152]="VALUE_LENGTH",e[e.FLAG13=8192]="FLAG13",e[e.BRANCH_LENGTH=8064]="BRANCH_LENGTH",e[e.JUMP_TABLE=127]="JUMP_TABLE"})(hr||(hr={}));var bo;(function(e){e[e.NUM=35]="NUM",e[e.SEMI=59]="SEMI",e[e.EQUALS=61]="EQUALS",e[e.ZERO=48]="ZERO",e[e.NINE=57]="NINE",e[e.LOWER_A=97]="LOWER_A",e[e.LOWER_F=102]="LOWER_F",e[e.LOWER_X=120]="LOWER_X",e[e.LOWER_Z=122]="LOWER_Z",e[e.UPPER_A=65]="UPPER_A",e[e.UPPER_F=70]="UPPER_F",e[e.UPPER_Z=90]="UPPER_Z"})(bo||(bo={}));const X_=32;function S8(e){return e>=bo.ZERO&&e<=bo.NINE}function J5e(e){return e>=bo.UPPER_A&&e<=bo.UPPER_F||e>=bo.LOWER_A&&e<=bo.LOWER_F}function X5e(e){return e>=bo.UPPER_A&&e<=bo.UPPER_Z||e>=bo.LOWER_A&&e<=bo.LOWER_Z||S8(e)}function e6e(e){return e===bo.EQUALS||X5e(e)}var Is;(function(e){e[e.EntityStart=0]="EntityStart",e[e.NumericStart=1]="NumericStart",e[e.NumericDecimal=2]="NumericDecimal",e[e.NumericHex=3]="NumericHex",e[e.NamedEntity=4]="NamedEntity"})(Is||(Is={}));var lc;(function(e){e[e.Legacy=0]="Legacy",e[e.Strict=1]="Strict",e[e.Attribute=2]="Attribute"})(lc||(lc={}));var t6e=class{decodeTree;emitCodePoint;errors;constructor(e,t,n){this.decodeTree=e,this.emitCodePoint=t,this.errors=n}state=Is.EntityStart;consumed=1;result=0;treeIndex=0;excess=1;decodeMode=lc.Strict;runConsumed=0;startEntity(e){this.decodeMode=e,this.state=Is.EntityStart,this.result=0,this.treeIndex=0,this.excess=1,this.consumed=1,this.runConsumed=0}write(e,t){switch(this.state){case Is.EntityStart:return e.charCodeAt(t)===bo.NUM?(this.state=Is.NumericStart,this.consumed+=1,this.stateNumericStart(e,t+1)):(this.state=Is.NamedEntity,this.stateNamedEntity(e,t));case Is.NumericStart:return this.stateNumericStart(e,t);case Is.NumericDecimal:return this.stateNumericDecimal(e,t);case Is.NumericHex:return this.stateNumericHex(e,t);case Is.NamedEntity:return this.stateNamedEntity(e,t)}}stateNumericStart(e,t){return t>=e.length?-1:(e.charCodeAt(t)|X_)===bo.LOWER_X?(this.state=Is.NumericHex,this.consumed+=1,this.stateNumericHex(e,t+1)):(this.state=Is.NumericDecimal,this.stateNumericDecimal(e,t))}stateNumericHex(e,t){for(;t<e.length;){const n=e.charCodeAt(t);if(S8(n)||J5e(n)){const i=n<=bo.NINE?n-bo.ZERO:(n|X_)-bo.LOWER_A+10;this.result=this.result*16+i,this.consumed++,t++}else return this.emitNumericEntity(n,3)}return-1}stateNumericDecimal(e,t){for(;t<e.length;){const n=e.charCodeAt(t);if(S8(n))this.result=this.result*10+(n-bo.ZERO),this.consumed++,t++;else return this.emitNumericEntity(n,2)}return-1}emitNumericEntity(e,t){if(this.consumed<=t)return this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed),0;if(e===bo.SEMI)this.consumed+=1;else if(this.decodeMode===lc.Strict)return 0;return this.emitCodePoint(G5e(this.result),this.consumed),this.errors&&(e!==bo.SEMI&&this.errors.missingSemicolonAfterCharacterReference(),this.errors.validateNumericCharacterReference(this.result)),this.consumed}stateNamedEntity(e,t){const{decodeTree:n}=this;let i=n[this.treeIndex],o=(i&hr.VALUE_LENGTH)>>14;for(;t<e.length;){if(o===0&&(i&hr.FLAG13)!==0){const r=(i&hr.BRANCH_LENGTH)>>7;if(this.runConsumed===0){const l=i&hr.JUMP_TABLE;if(e.charCodeAt(t)!==l)return this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}for(;this.runConsumed<r;){if(t>=e.length)return-1;const l=this.runConsumed-1,a=n[this.treeIndex+1+(l>>1)],u=l%2===0?a&255:a>>8&255;if(e.charCodeAt(t)!==u)return this.runConsumed=0,this.result===0?0:this.emitNotTerminatedNamedEntity();t++,this.excess++,this.runConsumed++}this.runConsumed=0,this.treeIndex+=1+(r>>1),i=n[this.treeIndex],o=(i&hr.VALUE_LENGTH)>>14}if(t>=e.length)break;const s=e.charCodeAt(t);if(s===bo.SEMI&&o!==0&&(i&hr.FLAG13)!==0)return this.emitNamedEntityData(this.treeIndex,o,this.consumed+this.excess);if(this.treeIndex=i6e(n,i,this.treeIndex+Math.max(1,o),s),this.treeIndex<0)return this.result===0||this.decodeMode===lc.Attribute&&(o===0||e6e(s))?0:this.emitNotTerminatedNamedEntity();if(i=n[this.treeIndex],o=(i&hr.VALUE_LENGTH)>>14,o!==0){if(s===bo.SEMI)return this.emitNamedEntityData(this.treeIndex,o,this.consumed+this.excess);this.decodeMode!==lc.Strict&&(i&hr.FLAG13)===0&&(this.result=this.treeIndex,this.consumed+=this.excess,this.excess=0)}t++,this.excess++}return-1}emitNotTerminatedNamedEntity(){const{result:e,decodeTree:t}=this,n=(t[e]&hr.VALUE_LENGTH)>>14;return this.emitNamedEntityData(e,n,this.consumed),this.errors?.missingSemicolonAfterCharacterReference(),this.consumed}emitNamedEntityData(e,t,n){const{decodeTree:i}=this;return this.emitCodePoint(t===1?i[e]&~(hr.VALUE_LENGTH|hr.FLAG13):i[e+1],n),t===3&&this.emitCodePoint(i[e+2],n),n}end(){switch(this.state){case Is.NamedEntity:return this.result!==0&&(this.decodeMode!==lc.Attribute||this.result===this.treeIndex)?this.emitNotTerminatedNamedEntity():0;case Is.NumericDecimal:return this.emitNumericEntity(0,2);case Is.NumericHex:return this.emitNumericEntity(0,3);case Is.NumericStart:return this.errors?.absenceOfDigitsInNumericCharacterReference(this.consumed),0;case Is.EntityStart:return 0}}};function n6e(e){let t="";const n=new t6e(e,i=>t+=String.fromCodePoint(i));return function(o,s){let r=0,l=0;for(;(l=o.indexOf("&",l))>=0;){t+=o.slice(r,l),n.startEntity(s);const u=n.write(o,l+1);if(u<0){r=l+n.end();break}r=l+u,l=u===0?r+1:r}const a=t+o.slice(r);return t="",a}}function i6e(e,t,n,i){const o=(t&hr.BRANCH_LENGTH)>>7,s=t&hr.JUMP_TABLE;if(o===0)return s!==0&&i===s?n:-1;if(s){const u=i-s;return u<0||u>=o?-1:e[n+u]-1}const r=o+1>>1;let l=0,a=o-1;for(;l<=a;){const u=l+a>>>1,c=e[n+(u>>1)]>>(u&1)*8&255;if(c<i)l=u+1;else if(c>i)a=u-1;else return e[n+r+u]}return-1}const o6e=n6e(Y5e);function r7(e,t=lc.Legacy){return o6e(e,t)}var s6e=TR(V5e());const eM={};function r6e(e){let t=eM[e];if(t)return t;t=eM[e]=[];for(let n=0;n<128;n++){const i=String.fromCharCode(n);t.push(i)}for(let n=0;n<e.length;n++){const i=e.charCodeAt(n);t[i]="%"+("0"+i.toString(16).toUpperCase()).slice(-2)}return t}function b9(e,t){typeof t!="string"&&(t=b9.defaultChars);const n=r6e(t);return e.replace(/(%[a-f0-9]{2})+/gi,function(i){let o="";for(let s=0,r=i.length;s<r;s+=3){const l=parseInt(i.slice(s+1,s+3),16);if(l<128){o+=n[l];continue}if((l&224)===192&&s+3<r){const a=parseInt(i.slice(s+4,s+6),16);if((a&192)===128){const u=l<<6&1984|a&63;u<128?o+="��":o+=String.fromCharCode(u),s+=3;continue}}if((l&240)===224&&s+6<r){const a=parseInt(i.slice(s+4,s+6),16),u=parseInt(i.slice(s+7,s+9),16);if((a&192)===128&&(u&192)===128){const c=l<<12&61440|a<<6&4032|u&63;c<2048||c>=55296&&c<=57343?o+="���":o+=String.fromCharCode(c),s+=6;continue}}if((l&248)===240&&s+9<r){const a=parseInt(i.slice(s+4,s+6),16),u=parseInt(i.slice(s+7,s+9),16),c=parseInt(i.slice(s+10,s+12),16);if((a&192)===128&&(u&192)===128&&(c&192)===128){let d=l<<18&1835008|a<<12&258048|u<<6&4032|c&63;d<65536||d>1114111?o+="����":(d-=65536,o+=String.fromCharCode(55296+(d>>10),56320+(d&1023))),s+=9;continue}}o+="�"}return o})}b9.defaultChars=";/?:@&=+$,#";b9.componentChars="";var _8=b9;const tM={};function l6e(e){let t=tM[e];if(t)return t;t=tM[e]=[];for(let n=0;n<128;n++){const i=String.fromCharCode(n);/^[0-9a-z]$/i.test(i)?t.push(i):t.push("%"+("0"+n.toString(16).toUpperCase()).slice(-2))}for(let n=0;n<e.length;n++)t[e.charCodeAt(n)]=e[n];return t}function A9(e,t,n){typeof t!="string"&&(n=t,t=A9.defaultChars),typeof n>"u"&&(n=!0);const i=l6e(t);let o="";for(let s=0,r=e.length;s<r;s++){const l=e.charCodeAt(s);if(n&&l===37&&s+2<r&&/^[0-9a-f]{2}$/i.test(e.slice(s+1,s+3))){o+=e.slice(s,s+3),s+=2;continue}if(l<128){o+=i[l];continue}if(l>=55296&&l<=57343){if(l>=55296&&l<=56319&&s+1<r){const a=e.charCodeAt(s+1);if(a>=56320&&a<=57343){o+=encodeURIComponent(e[s]+e[s+1]),s++;continue}}o+="%EF%BF%BD";continue}o+=encodeURIComponent(e[s])}return o}A9.defaultChars=";/?:@&=+$,-_.!~*'()#";A9.componentChars="-_.!~*'()";var LR=A9;function l7(e){let t="";return t+=e.protocol||"",t+=e.slashes?"//":"",t+=e.auth?e.auth+"@":"",e.hostname&&e.hostname.indexOf(":")!==-1?t+="["+e.hostname+"]":t+=e.hostname||"",t+=e.port?":"+e.port:"",t+=e.pathname||"",t+=e.search||"",t+=e.hash||"",t}function K2(){this.protocol=null,this.slashes=null,this.auth=null,this.port=null,this.hostname=null,this.hash=null,this.search=null,this.pathname=null}const a6e=/^([a-z0-9.+-]+:)/i,u6e=/:[0-9]*$/,c6e=/^(\/\/?(?!\/)[^\?\s]*)(\?[^\s]*)?$/,d6e=["{","}","|","\\","^","`"].concat(["<",">",'"',"`"," ","\r",` -`," "]),f6e=["'"].concat(d6e),nM=["%","/","?",";","#"].concat(f6e),iM=["/","?","#"],h6e=255,oM=/^[+a-z0-9A-Z_-]{0,63}$/,p6e=/^([+a-z0-9A-Z_-]{0,63})(.*)$/,sM={javascript:!0,"javascript:":!0},rM={http:!0,https:!0,ftp:!0,gopher:!0,file:!0,"http:":!0,"https:":!0,"ftp:":!0,"gopher:":!0,"file:":!0};function g6e(e,t){if(e&&e instanceof K2)return e;const n=new K2;return n.parse(e,t),n}K2.prototype.parse=function(e,t){let n,i,o,s=e;if(s=s.trim(),!t&&e.split("#").length===1){const u=c6e.exec(s);if(u)return this.pathname=u[1],u[2]&&(this.search=u[2]),this}let r=a6e.exec(s);if(r&&(r=r[0],n=r.toLowerCase(),this.protocol=r,s=s.substr(r.length)),(t||r||s.match(/^\/\/[^@\/]+@[^@\/]+/))&&(o=s.substr(0,2)==="//",o&&!(r&&sM[r])&&(s=s.substr(2),this.slashes=!0)),!sM[r]&&(o||r&&!rM[r])){let u=-1;for(let g=0;g<iM.length;g++)i=s.indexOf(iM[g]),i!==-1&&(u===-1||i<u)&&(u=i);let c,d;u===-1?d=s.lastIndexOf("@"):d=s.lastIndexOf("@",u),d!==-1&&(c=s.slice(0,d),s=s.slice(d+1),this.auth=c),u=-1;for(let g=0;g<nM.length;g++)i=s.indexOf(nM[g]),i!==-1&&(u===-1||i<u)&&(u=i);u===-1&&(u=s.length),s[u-1]===":"&&u--;const h=s.slice(0,u);s=s.slice(u),this.parseHost(h),this.hostname=this.hostname||"";const p=this.hostname[0]==="["&&this.hostname[this.hostname.length-1]==="]";if(!p){const g=this.hostname.split(/\./);for(let m=0,k=g.length;m<k;m++){const w=g[m];if(w&&!w.match(oM)){let y="";for(let b=0,A=w.length;b<A;b++)w.charCodeAt(b)>127?y+="x":y+=w[b];if(!y.match(oM)){const b=g.slice(0,m),A=g.slice(m+1),T=w.match(p6e);T&&(b.push(T[1]),A.unshift(T[2])),A.length&&(s=A.join(".")+s),this.hostname=b.join(".");break}}}}this.hostname.length>h6e&&(this.hostname=""),p&&(this.hostname=this.hostname.substr(1,this.hostname.length-2))}const l=s.indexOf("#");l!==-1&&(this.hash=s.substr(l),s=s.slice(0,l));const a=s.indexOf("?");return a!==-1&&(this.search=s.substr(a),s=s.slice(0,a)),s&&(this.pathname=s),rM[n]&&this.hostname&&!this.pathname&&(this.pathname=""),this};K2.prototype.parseHost=function(e){let t=u6e.exec(e);t&&(t=t[0],t!==":"&&(this.port=t.substr(1)),e=e.substr(0,e.length-t.length)),e&&(this.hostname=e)};var a7=g6e,NR=L5e({decode:()=>_8,encode:()=>LR,format:()=>l7,parse:()=>a7}),m6e=Object.defineProperty,FR=e=>{let t={};for(var n in e)m6e(t,n,{get:e[n],enumerable:!0});return t},hs=class{type;tag;attrs;map;nesting;level;children;content;markup;info;meta;block;hidden;constructor(e,t,n){this.type=e,this.tag=t,this.attrs=null,this.map=null,this.nesting=n,this.level=0,this.children=null,this.content="",this.markup="",this.info="",this.meta=null,this.block=!1,this.hidden=!1}attrIndex(e){if(!this.attrs)return-1;const t=this.attrs;for(let n=0,i=t.length;n<i;n++)if(t[n][0]===e)return n;return-1}attrPush(e){this.attrs?this.attrs.push(e):this.attrs=[e]}attrSet(e,t){const n=this.attrIndex(e),i=[e,t];n<0?this.attrPush(i):this.attrs[n]=i}attrGet(e){const t=this.attrIndex(e);let n=null;return t>=0&&(n=this.attrs[t][1]),n}attrJoin(e,t){const n=this.attrIndex(e);n<0?this.attrPush([e,t]):this.attrs[n][1]=`${this.attrs[n][1]} ${t}`}},v6e=FR({arrayReplaceAt:()=>x6e,assign:()=>C6e,countLines:()=>To,escapeHtml:()=>F6e,escapeRE:()=>B6e,fromCodePoint:()=>N0,has:()=>A6e,isMdAsciiPunct:()=>G2,isPunctChar:()=>Z2,isPunctCode:()=>M8,isSpace:()=>w6e,isString:()=>k6e,isValidEntityCode:()=>w9,isWhiteSpace:()=>L0,lib:()=>$6e,mdurl:()=>NR,normalizeReference:()=>C9,ucmicro:()=>V2,unescapeAll:()=>F0,unescapeMd:()=>I6e});const V2={Any:/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,Cc:/[\0-\x1F\x7F-\x9F]/,Cf:/[\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB]|\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC3F]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]/,P:/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]/,S:/[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFF\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u31EF\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC2\uFD40-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDC-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF76\uDF7B-\uDFD9\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE7C\uDE80-\uDE88\uDE90-\uDEBD\uDEBF-\uDEC5\uDECE-\uDEDB\uDEE0-\uDEE8\uDEF0-\uDEF8\uDF00-\uDF92\uDF94-\uDFCA]/,Z:/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/};function y6e(e){return Object.prototype.toString.call(e)}function k6e(e){return y6e(e)==="[object String]"}const b6e=Object.prototype.hasOwnProperty;function A6e(e,t){return b6e.call(e,t)}function C6e(e,...t){return t.forEach(n=>{if(n){if(typeof n!="object")throw new TypeError(`${String(n)}must be object`);Object.keys(n).forEach(i=>{e[i]=n[i]})}}),e}function w6e(e){return e===9||e===32}function L0(e){if(e>=8192&&e<=8202)return!0;switch(e){case 9:case 10:case 11:case 12:case 13:case 32:case 160:case 5760:case 8239:case 8287:case 12288:return!0}return!1}function Z2(e){return V2.P.test(e)||V2.S.test(e)}const lM=new Map;function M8(e){if(G2(e))return!0;if(e>=0&&e<128)return!1;const t=lM.get(e);if(t!==void 0)return t;const n=Z2(String.fromCharCode(e));return lM.set(e,n),n}function G2(e){switch(e){case 33:case 34:case 35:case 36:case 37:case 38:case 39:case 40:case 41:case 42:case 43:case 44:case 45:case 46:case 47:case 58:case 59:case 60:case 61:case 62:case 63:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 124:case 125:case 126:return!0;default:return!1}}function C9(e){return e=e.trim().replace(/\s+/g," "),"ẞ".toLowerCase()==="Ṿ"&&(e=e.replace(/ẞ/g,"ß")),e.toLowerCase().toUpperCase()}function x6e(e,t,n){return[...e.slice(0,t),...n,...e.slice(t+1)]}function w9(e){return!(e>=55296&&e<=57343||e>=64976&&e<=65007||(e&65535)===65535||(e&65535)===65534||e>=0&&e<=8||e===11||e>=14&&e<=31||e>=127&&e<=159||e>1114111)}function N0(e){if(e>65535){e-=65536;const t=55296+(e>>10),n=56320+(e&1023);return String.fromCharCode(t,n)}return String.fromCharCode(e)}const DR=/\\([!"#$%&'()*+,\-\./:;<=>?@[\\\]^_`{|}~])/g,S6e=new RegExp(`${DR.source}|${/&([a-z#][a-z0-9]{1,31});/gi.source}`,"gi"),_6e=/^#((?:x[a-f0-9]{1,8}|[0-9]{1,8}))$/i;function M6e(e,t){if(t.charCodeAt(0)===35&&_6e.test(t)){const i=t[1].toLowerCase()==="x"?Number.parseInt(t.slice(2),16):Number.parseInt(t.slice(1),10);return w9(i)?N0(i):e}const n=r7(e);return n!==e?n:e}function I6e(e){return e.includes("\\")?e.replace(DR,"$1"):e}function F0(e){return!e.includes("\\")&&!e.includes("&")?e:e.replace(S6e,(t,n,i)=>n||M6e(t,i))}const E6e=/[&<>"]/,T6e=/[&<>"]/g,L6e={"&":"&","<":"<",">":">",'"':"""};function N6e(e){return L6e[e]}function F6e(e){return E6e.test(e)?e.replace(T6e,N6e):e}const D6e=/[.?*+^$[\]\\(){}|-]/g;function B6e(e){return e.replace(D6e,"\\$&")}const $6e={mdurl:NR,ucmicro:V2};function To(e){if(e.length===0)return 0;let t=0,n=-1;for(;(n=e.indexOf(` -`,n+1))!==-1;)t++;return t}const R6e=/(?:^|\n)[ \t]{0,3}\[\^[^\]\n]+\]:/m,z6e=/(?:^|\n)[ \t]{0,3}\*\[[^\]\n]+\]:/m,O6e=/(?:^|\n)[ \t]{0,3}\[(?!\^)(?:\\[\s\S]|[^\]\\[])+\][ \t]*:/m,u7=["references","footnotes","abbreviations","abbr","abbrs"],c7=Symbol.for("markdown-it-ts.global-state"),d7=Object.prototype.hasOwnProperty;function aM(e){return e==="reference-definition"||e==="footnote-definition"||e==="abbreviation-definition"}function sa(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function mc(e){if(Array.isArray(e))return e.map(t=>mc(t));if(sa(e)){const t={};for(const n of Object.keys(e))t[n]=mc(e[n]);return t}return e}function Q2(e){return Array.isArray(e)?e.map((t,n)=>String(n)):sa(e)?Object.keys(e):[]}function I8(e,t){if(Array.isArray(e)||Array.isArray(t)){if(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!I8(e[n],t[n]))return!1;return!0}if(sa(e)||sa(t)){if(!sa(e)||!sa(t))return!1;const n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(const o of n)if(!d7.call(t,o)||!I8(e[o],t[o]))return!1;return!0}return Object.is(e,t)}function BR(e,t){if(Array.isArray(e))return e[Number(t)];if(sa(e))return e[t]}function P6e(e,t){if(Array.isArray(e)&&Array.isArray(t)){e.length=t.length;for(let n=0;n<t.length;n++)e[n]=mc(t[n]);return e}if(sa(e)&&sa(t)){for(const n of Object.keys(e))d7.call(t,n)||delete e[n];for(const n of Object.keys(t))e[n]=mc(t[n]);return e}return mc(t)}function j6e(e,t,n){const i=n.ownedKeys??[],o=e[t];if(sa(o)||Array.isArray(o)){const s=new Set(Q2(n.value));for(const r of i)n.existed&&s.has(r)?o[r]=mc(BR(n.value,r)):delete o[r];!n.existed&&Q2(o).length===0&&delete e[t];return}n.existed?e[t]=mc(n.value):delete e[t]}function f7(e){const t=e[c7];return aM(t)?{reason:t,snapshot:{}}:t&&typeof t=="object"&&aM(t.reason)&&t.snapshot&&typeof t.snapshot=="object"?t:null}function H6e(e,t){Object.defineProperty(e,c7,{value:t,enumerable:!1,configurable:!0,writable:!0})}function Pr(e){return!e||!e.includes("]:")&&!e.includes("*[")?null:R6e.test(e)?"footnote-definition":z6e.test(e)?"abbreviation-definition":O6e.test(e)?"reference-definition":null}function pg(e){return f7(e)?.reason??null}function Bh(e,t,n){if(pg(e)&&Mu(e),!t)return n();h7(e,t);try{const i=n();return p7(e),i}catch(i){throw Mu(e),i}}function h7(e,t){try{Mu(e);const n={};for(const i of u7)n[i]=d7.call(e,i)?{existed:!0,value:mc(e[i])}:{existed:!1};H6e(e,{reason:t,snapshot:n})}catch{}}function p7(e){const t=f7(e);if(t)for(const n of u7){const i=t.snapshot[n];if(!i)continue;i.ownedKeys=[];const o=e[n];if(!sa(o)&&!Array.isArray(o))continue;const s=new Set(Q2(i.existed?i.value:void 0));i.ownedKeys=Q2(o).filter(r=>s.has(r)?!I8(o[r],BR(i.value,r)):!0)}}function Mu(e){const t=f7(e);if(t){for(const n of u7){const i=t.snapshot[n];if(!i){delete e[n];continue}if(i.ownedKeys){j6e(e,n,i);continue}i.existed?e[n]=P6e(e[n],i.value):delete e[n]}delete e[c7]}}function F3(e){return{area:e,attempted:!0,matched:!1,attemptMs:0,blocks:0,headings:0,paragraphs:0,lists:0,fences:0,paragraphCacheHits:0,paragraphCacheMisses:0,paragraphCacheBypasses:0,listCacheHits:0,listCacheMisses:0,fenceCacheHits:0,fenceCacheMisses:0}}const E8=Symbol.for("markdown-it-ts.diagnostics");function gg(e,t){if(e)try{const n=e[E8];if(n&&typeof n=="object")return n;if(!t)return;const i={};return e[E8]=i,i}catch{return}}function lu(e){return gg(e,!1)}function W6e(e){if(e)try{const t=e[E8];t&&typeof t=="object"&&(delete t.strategy,delete t.chunk,delete t.unbounded,delete t.editable,delete t.stockFast)}catch{}}function gr(e){W6e(e)}function V1(e,t){const n=gg(e,!0);n&&(n.stockFast=t)}function Go(e,t){const n=gg(e,!0);n&&(n.strategy=t)}function D3(e,t){const n=gg(e,!0);n&&(n.chunk=t)}function $R(e,t){const n=gg(e,!0);n&&(n.unbounded=t)}const q6e=/[\0-\uD7FF\uE000-\uFFFF]|[\uD800-\uDBFF][\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?:[^\uD800-\uDBFF]|^)[\uDC00-\uDFFF]/,U6e=/[\0-\x1F\x7F-\x9F]/,K6e=/[!-#%-\*,-\/:;\?@\[-\]_\{\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B4E\u1B4F\u1B5A-\u1B60\u1B7D-\u1B7F\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65]|\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDD6E\uDEAD\uDED0\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9\uDFD4\uDFD5\uDFD7\uDFD8]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2\uDF00-\uDF09\uDFE1]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDF43-\uDF4F\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDD6D-\uDD6F\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD839\uDDFF|\uD83A[\uDD5E\uDD5F]/,V6e=/[ \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000]/;var Z6e=class{src_Any=q6e.source;src_Cc=U6e.source;src_Z=V6e.source;src_P=K6e.source;src_ZPCc=[this.src_Z,this.src_P,this.src_Cc].join("|");src_ZCc=[this.src_Z,this.src_Cc].join("|");cache={};opts={maxLength:1e4,urlAuth:!1,schema_names:[]};constructor(e={}){this.opts={...this.opts,...e}}set(e={}){return this.opts={...this.opts,...e},this.cache={},this}escapeRE(e){return e.replace(/[.?*+^$[\]\\(){}|-]/g,"\\$&")}nestedPairRE(e,t,n=4){const i=this.escapeRE(e),o=this.escapeRE(t),s=`(?:(?!${this.src_ZCc}|${i}|${o}).)`;let r=`${i}${s}{0,1000}${o}`;for(let l=2;l<=n;l++)r=`${i}(?:${s}|${r}){0,1000}${o}`;return r}get_text_separators(){return this.cache.text_separators??=/[><\uff5c]/}get_pseudo_letter(){return this.cache.src_pseudo_letter??=new RegExp(`(?:(?!${this.get_text_separators().source}|${this.src_ZPCc})${this.src_Any})`)}get_ipv4_addr(){return this.cache.src_ip4??=new RegExp("(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])[.]){3}(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])")}get_ipv6_addr(){const e="[0-9A-Fa-f]{1,4}",t=`(?:(?:${e}:${e})|${this.get_ipv4_addr().source})`;return this.cache.src_ip6_addr??=new RegExp(`(?:(?:${e}:){6}${t}|::(?:${e}:){5}${t}|(?:${e})?::(?:${e}:){4}${t}|(?:(?:${e}:){0,1}${e})?::(?:${e}:){3}${t}|(?:(?:${e}:){0,2}${e})?::(?:${e}:){2}${t}|(?:(?:${e}:){0,3}${e})?::${e}:${t}|(?:(?:${e}:){0,4}${e})?::${t}|(?:(?:${e}:){0,5}${e})?::${e}|(?:(?:${e}:){0,6}${e})?::)`)}get_ipv6_url_host(){return this.cache.src_ip6_host??=new RegExp(`\\[${this.get_ipv6_addr().source}\\]`)}get_ipv6_mail_host(){return this.cache.src_ipv6_mail_host??=new RegExp(`\\[IPv6:${this.get_ipv6_addr().source}\\]`)}get_auth(){return this.cache.src_auth??=new RegExp(`(?:(?:(?!${this.src_ZCc}|[@/\\[\\]()]).){1,50}@)?`)}get_port(){return this.cache.src_port??=new RegExp("(?::(?:6(?:[0-4]\\d{3}|5(?:[0-4]\\d{2}|5(?:[0-2]\\d|3[0-5])))|[1-5]?\\d{1,4}))?")}get_host_terminator(){return this.cache.src_host_terminator??=new RegExp(`(?=$|${this.get_text_separators().source}|${this.src_ZPCc})(?!${this.opts["---"]?"-(?!--)|":"-|"}_|:\\d|\\.-|\\.(?!$|${this.src_ZPCc}))`)}get_path_terminator(){return this.cache.src_path_terminator??=new RegExp(`${this.src_ZPCc}|${this.get_text_separators().source}`)}get_path(){return this.cache.src_path??=new RegExp(`(?:[/?#](?:${this.nestedPairRE("[","]")}|${this.nestedPairRE("(",")")}|${this.nestedPairRE("{","}")}|\\"(?:(?!${this.src_ZCc}|["]).){1,100}\\"|\\'(?:(?!${this.src_ZCc}|[']).){1,100}\\'|\\'(?=${this.get_pseudo_letter().source}|[-])|\\.{2,20}[:]?[a-zA-Z0-9%/&]|\\.(?!${this.src_ZCc}|[.]|$)|`+(this.opts["---"]?"\\-(?!--(?:[^-]|$))(?:-{0,19})|":"\\-{1,20}|")+`,(?!${this.src_ZCc}|$)|;(?!${this.src_ZCc}|$)|\\!{1,20}(?!${this.src_ZCc}|[!]|$)|\\?(?!${this.src_ZCc}|[?]|$)|`+this.get_path_extra().source+`[\\\\/:%@#&=_~*]|(?!${this.get_path_terminator().source}).){1,${this.opts.maxLength}}|\\/)?`)}get_mail_name(){return this.cache.src_mail_name??=new RegExp("[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9](?:[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9]|[.](?=[-!#$%&'*+/=?^_`{|}~a-zA-Z0-9])){0,63}")}get_xn(){return this.cache.src_xn??=new RegExp("xn--[a-z0-9\\-]{1,59}")}get_tld(){if(this.cache.tld)return this.cache.tld;const e=[...new Set(this.opts.tlds||[])].sort().reverse().join("|");return this.cache.tld=new RegExp(`${e||"$#none#$"}|${this.get_xn().source}`),this.cache.tld}get_domain_root(){return this.cache.src_domain_root??=new RegExp("(?:"+this.get_xn().source+`|${this.get_pseudo_letter().source}{1,63})`)}get_domain(){return this.cache.src_domain??=new RegExp("(?:"+this.get_xn().source+`|(?:${this.get_pseudo_letter().source})|(?:${this.get_pseudo_letter().source}(?:-|${this.get_pseudo_letter().source}){0,61}${this.get_pseudo_letter().source}))`)}get_url_host_port(){return this.cache.url_host_port??=new RegExp("(?:"+this.get_ipv6_url_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,10}${this.get_domain().source}))`+this.get_port().source+this.get_host_terminator().source)}get_fuzzy_url_host_port(){return this.cache.fuzzy_url_host_port??=new RegExp("(?:"+(this.opts.fuzzyIP?this.get_ipv4_addr().source+"|":"")+`(?:(?:(?:${this.get_domain().source})\\.){1,10}(?:${this.get_tld().source})))`+this.get_host_terminator().source)}get_mail_host(){return this.cache.src_mail_host??=new RegExp("(?:"+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})\\.){0,4}${this.get_domain().source}))`+this.get_host_terminator().source)}get_fuzzy_mail_host(){return this.cache.src_fuzzy_mail_host??=new RegExp("(?:"+this.get_ipv6_mail_host().source+`|(?:(?:(?:${this.get_domain().source})[.]){1,4}${this.get_domain_root().source}))`+this.get_host_terminator().source)}get_path_extra(){return this.cache.src_path_extra??=new RegExp("")}get_fuzzy_mail_host_search(){return this.cache.mail_fuzzy_host_search??=new RegExp(`@${this.get_fuzzy_mail_host().source}`,"ig")}get_fuzzy_link_search(){return this.cache.link_fuzzy_search??=new RegExp(`(^|(?![.:/\\-_@])(?:[$+<=>^\`||]|${this.src_ZPCc}))(?:(?![$+<=>^\`||])${this.get_fuzzy_url_host_port().source}${this.get_path().source})`,"ig")}get_http_validator(){return this.cache.http_validator??=new RegExp("\\/\\/"+(this.opts.urlAuth?this.get_auth().source:"")+this.get_url_host_port().source+this.get_path().source,"iy")}get_relative_proto_validator(){return this.cache.relative_proto_validator??=new RegExp((this.opts.urlAuth?this.get_auth().source:"")+`(?:localhost|${this.get_ipv6_url_host().source}|(?:(?:${this.get_domain().source})[.]){1,10}${this.get_domain_root().source})`+this.get_port().source+this.get_host_terminator().source+this.get_path().source,"iy")}get_mail_name_validator(){return this.cache.mail_name_validator??=new RegExp(`(?:^|${this.get_text_separators().source}|"|\\(|${this.src_ZCc})(${this.get_mail_name().source})$`)}get_mailto_validator(){return this.cache.mailto_validator??=new RegExp(`${this.get_mail_name().source}@${this.get_mail_host().source}`,"iy")}get_schema_names(){return this.cache.schema_names??=new RegExp((this.opts.schema_names||[]).map(e=>this.escapeRE(e)).join("|"))}get_schema_search(){return this.cache.schema_search??=new RegExp(`(^|(?!_)(?:[><|]|${this.src_ZPCc}))(${this.get_schema_names().source})`,"ig")}get_schema_at_start(){return this.cache.schema_at_start??=new RegExp(`^${this.get_schema_search().source}`,"i")}},B3={validate:(e,t,n)=>{const i=n.re.get_http_validator();i.lastIndex=t;const o=i.exec(e);return o?o[0].length:0},normalize:(e,t)=>t.normalize(e)},G6e={"http:":B3,"https:":B3,"ftp:":B3,"//":{validate:function(e,t,n){const i=n.re.get_relative_proto_validator();i.lastIndex=t;const o=i.exec(e);return o?t>=3&&e[t-3]===":"||t>=3&&e[t-3]==="/"?0:o[0].length:0},normalize:(e,t)=>t.normalize(e)},"mailto:":{validate:function(e,t,n){const i=n.re.get_mailto_validator();i.lastIndex=t;const o=i.exec(e);return o?o[0].length:0},normalize:(e,t)=>t.normalize(e)}},Q6e="a:cdefgilmnoqrstuwxz|b:abdefghijmnorstvwyz|c:acdfghiklmnoruvwxyz|d:ejkmoz|e:cegrstu|f:ijkmor|g:abdefghilmnpqrstuwy|h:kmnrtu|i:delmnoqrst|j:emop|k:eghimnprwyz|l:abcikrstuvy|m:acdeghklmnopqrstuvwxyz|n:acefgilopruz|o:m|p:aefghklmnrstwy|q:a|r:eosuw|s:abcdeghijklmnortuvxyz|t:cdfghjklmnortvwz|u:agksyz|v:aceginu|w:fs|y:et|z:amw",Y6e="biz|com|edu|gov|net|org|pro|web|xxx|aero|asia|coop|info|museum|name|shop|рф";function J6e(){const e=Y6e.split("|");return Q6e.split("|").forEach(t=>{const n=t.indexOf(":"),i=t.slice(0,n);for(const o of t.slice(n+1))e.push(i+o)}),e}var X6e={fuzzyLink:!1,fuzzyEmail:!0,fuzzyIP:!1,"---":!1,tlds:J6e(),urlAuth:!1,maxLength:1e4},uM=class{schema;index;lastIndex;raw;text;url;constructor(e,t,n,i){const o=e.slice(n,i);this.schema=t.toLowerCase(),this.index=n,this.lastIndex=i,this.raw=o,this.text=o,this.url=o}},RR=class{__opts__;__schemas__;re;constructor(e={}){const{rebuilder:t,...n}=e;this.__opts__={...X6e,...n},this.__schemas__={...G6e},this.re=t||new Z6e,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)})}add(e,t=null){if(!t)delete this.__schemas__[e];else{const n={normalize:(i,o)=>o.normalize(i),...t};this.__schemas__[e]=n}return this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}set(e={}){return this.__opts__={...this.__opts__,...e},this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}test(e){if(!e.length)return!1;let t,n;for(n=this.re.get_schema_search(),n.lastIndex=0;(t=n.exec(e))!==null;)if(this.testSchemaAt(e,t[2],n.lastIndex))return!0;if(this.__opts__.fuzzyLink&&this.__schemas__["http:"]&&(n=this.re.get_fuzzy_link_search(),n.lastIndex=0,n.exec(e)!==null))return!0;if(this.__opts__.fuzzyEmail&&this.__schemas__["mailto:"]&&e.indexOf("@")>=0){const i=this.re.get_fuzzy_mail_host_search(),o=this.re.get_mail_name_validator();for(i.lastIndex=0;(t=i.exec(e))!==null;){const s=e.slice(Math.max(0,t.index-65),t.index);if(o.test(s))return!0}}return!1}testSchemaAt(e,t,n){return this.__schemas__[t.toLowerCase()]?this.__schemas__[t.toLowerCase()].validate(e.slice(0,n+this.__opts__.maxLength),n,this):0}match(e){const t=[],n=this.re.get_schema_search();let i,o,s,r,l,a,u=!1,c=!1,d=!1,h=0;if(!e.length)return null;for(n.lastIndex=0,this.__opts__.fuzzyLink&&this.__schemas__["http:"]&&(i=this.re.get_fuzzy_link_search(),i.lastIndex=0),this.__opts__.fuzzyEmail&&this.__schemas__["mailto:"]&&(o=this.re.get_fuzzy_mail_host_search(),o.lastIndex=0,s=this.re.get_mail_name_validator());;){const p=Math.max(h-1,0);if(o&&s&&!d&&(!l||l.index<h))for(o.lastIndex<p&&(o.lastIndex=p);;){const y=o.exec(e);if(!y){d=!0,l=void 0;break}const b=s.exec(e.slice(Math.max(0,y.index-65),y.index));if(b){if(l={schema:"mailto:",index:y.index-b[1].length,lastIndex:y.index+y[0].length},l.index>=h)break;o.lastIndex<p&&(o.lastIndex=p)}}if(i&&!c&&(!r||r.index<h))for(i.lastIndex<p&&(i.lastIndex=p);;){const y=i.exec(e);if(!y){c=!0,r=void 0;break}if(r={schema:"",index:y.index+y[1].length,lastIndex:y.index+y[0].length},r.index>=h)break;i.lastIndex<p&&(i.lastIndex=p)}let g=l;(!g||r&&(r.index<g.index||r.index===g.index&&r.lastIndex>g.lastIndex))&&(g=r);let m;if(!u)for(;;){if(!a){n.lastIndex<p&&(n.lastIndex=p);const A=n.exec(e);if(!A){u=!0;break}a={schema:A[2],index:A.index+A[1].length,lastIndex:A.index+A[0].length}}if(a.index<h){a=void 0;continue}if(g&&a.index>g.index)break;const y=a;a=void 0;const b=this.testSchemaAt(e,y.schema,y.lastIndex);if(b){m={schema:y.schema,index:y.index,lastIndex:y.lastIndex+b};break}}let k=m;if((!k||l&&(l.index<k.index||l.index===k.index&&l.lastIndex>k.lastIndex))&&(k=l),(!k||r&&(r.index<k.index||r.index===k.index&&r.lastIndex>k.lastIndex))&&(k=r),!k)break;k===l?l=void 0:k===r&&(r=void 0);const w=new uM(e,k.schema,k.index,k.lastIndex);w.schema?this.__schemas__[w.schema].normalize(w,this):this.normalize(w),t.push(w),h=k.lastIndex}return t.length?t:null}matchAtStart(e){if(!e.length)return null;const t=this.re.get_schema_at_start().exec(e);if(!t)return null;const n=this.testSchemaAt(e,t[2],t[0].length);if(!n)return null;const i=new uM(e,t[2],t.index+t[1].length,t.index+t[0].length+n);return this.__schemas__[i.schema].normalize(i,this),i}tlds(e,t=!1){return e=Array.isArray(e)?e:[e],t?this.__opts__.tlds=this.__opts__.tlds.concat(e):this.__opts__.tlds=e,this.re.set({...this.__opts__,schema_names:Object.keys(this.__schemas__)}),this}normalize(e){e.schema||(e.url=`http://${e.url}`),e.schema==="mailto:"&&!/^mailto:/i.test(e.url)&&(e.url=`mailto:${e.url}`)}},e7e=ER({"../../node_modules/.pnpm/punycode.js@2.3.1/node_modules/punycode.js/punycode.js":((e,t)=>{const d=/^xn--/,h=/[^\0-\x7F]/,p=/[\x2E\u3002\uFF0E\uFF61]/g,g={overflow:"Overflow: input needs wider integers to process","not-basic":"Illegal input >= 0x80 (not a basic code point)","invalid-input":"Invalid input"},m=35,k=Math.floor,w=String.fromCharCode;function y(O){throw new RangeError(g[O])}function b(O,R){const j=[];let $=O.length;for(;$--;)j[$]=R(O[$]);return j}function A(O,R){const j=O.split("@");let $="";j.length>1&&($=j[0]+"@",O=j[1]),O=O.replace(p,".");const W=b(O.split("."),R).join(".");return $+W}function T(O){const R=[];let j=0;const $=O.length;for(;j<$;){const W=O.charCodeAt(j++);if(W>=55296&&W<=56319&&j<$){const P=O.charCodeAt(j++);(P&64512)==56320?R.push(((W&1023)<<10)+(P&1023)+65536):(R.push(W),j--)}else R.push(W)}return R}const S=O=>String.fromCodePoint(...O),x=function(O){return O>=48&&O<58?26+(O-48):O>=65&&O<91?O-65:O>=97&&O<123?O-97:36},_=function(O,R){return O+22+75*(O<26)-((R!=0)<<5)},L=function(O,R,j){let $=0;for(O=j?k(O/700):O>>1,O+=k(O/R);O>m*26>>1;$+=36)O=k(O/m);return k($+(m+1)*O/(O+38))},M=function(O){const R=[],j=O.length;let $=0,W=128,P=72,Z=O.lastIndexOf("-");Z<0&&(Z=0);for(let ae=0;ae<Z;++ae)O.charCodeAt(ae)>=128&&y("not-basic"),R.push(O.charCodeAt(ae));for(let ae=Z>0?Z+1:0;ae<j;){const V=$;for(let oe=1,q=36;;q+=36){ae>=j&&y("invalid-input");const ne=x(O.charCodeAt(ae++));ne>=36&&y("invalid-input"),ne>k((2147483647-$)/oe)&&y("overflow"),$+=ne*oe;const ie=q<=P?1:q>=P+26?26:q-P;if(ne<ie)break;const pe=36-ie;oe>k(2147483647/pe)&&y("overflow"),oe*=pe}const Y=R.length+1;P=L($-V,Y,V==0),k($/Y)>2147483647-W&&y("overflow"),W+=k($/Y),$%=Y,R.splice($++,0,W)}return String.fromCodePoint(...R)},N=function(O){const R=[];O=T(O);const j=O.length;let $=128,W=0,P=72;for(const V of O)V<128&&R.push(w(V));const Z=R.length;let ae=Z;for(Z&&R.push("-");ae<j;){let V=2147483647;for(const oe of O)oe>=$&&oe<V&&(V=oe);const Y=ae+1;V-$>k((2147483647-W)/Y)&&y("overflow"),W+=(V-$)*Y,$=V;for(const oe of O)if(oe<$&&++W>2147483647&&y("overflow"),oe===$){let q=W;for(let ne=36;;ne+=36){const ie=ne<=P?1:ne>=P+26?26:ne-P;if(q<ie)break;const pe=q-ie,Ne=36-ie;R.push(w(_(ie+pe%Ne,0))),q=k(pe/Ne)}R.push(w(_(q,0))),P=L(W,Y,ae===Z),W=0,++ae}++W,++$}return R.join("")},H={version:"2.3.1",ucs2:{decode:T,encode:S},decode:M,encode:N,toASCII:function(O){return A(O,function(R){return h.test(R)?"xn--"+N(R):R})},toUnicode:function(O){return A(O,function(R){return d.test(R)?M(R.slice(4).toLowerCase()):R})}};t.exports=H})}),zR=TR(e7e());function g7(e,t,n){let i,o=t;const s={ok:!1,pos:0,str:""};if(e.charCodeAt(o)===60){for(o++;o<n;){if(i=e.charCodeAt(o),i===10||i===60)return s;if(i===62)return s.pos=o+1,s.str=F0(e.slice(t+1,o)),s.ok=!0,s;if(i===92&&o+1<n){o+=2;continue}o++}return s}let r=0;for(;o<n&&(i=e.charCodeAt(o),!(i===32||i<32||i===127));){if(i===92&&o+1<n){if(e.charCodeAt(o+1)===32)break;o+=2;continue}if(i===40&&(r++,r>32))return s;if(i===41){if(r===0)break;r--}o++}return t===o||r!==0||(s.str=F0(e.slice(t,o)),s.pos=o,s.ok=!0),s}var OR=g7;const _v=-2;function t7e(e,t,n,i){let o=1,s=t+1;for(;s<n;){const r=e.charCodeAt(s);if(r===93){if(o--,o===0)return s;if(i){const l=s+1<n?e.charCodeAt(s+1):0;if(l===40||l===91)return _v}s++;continue}if(r===92){s+=2;continue}if(r===96||r===60||r===33&&s+1<n&&e.charCodeAt(s+1)===91)return _v;if(r===91){o++,s++;continue}s++}return-1}function m7(e,t,n){let i=1,o=!1,s,r;const l=e.src,a=e.posMax,u=e.pos,c=e.linkLabelNoCloseFrom;if(c>=0&&t+1>=c)return-1;const d=l.indexOf("]",t+1);if(d<0||d>=a)return e.linkLabelNoCloseFrom=t+1,-1;const h=t7e(l,t,a,n);if(h!==_v)return h;for(e.pos=t+1;e.pos<a;){if(s=l.charCodeAt(e.pos),s===93&&(i--,i===0)){o=!0;break}if(r=e.pos,e.md.inline.skipToken(e),s===91){if(r===e.pos-1)i++;else if(n)return e.pos=u,-1}}let p=-1;return o&&(p=e.pos),e.pos=u,p}var Y2=m7;function v7(e,t,n,i){let o,s=t;const r={ok:!1,can_continue:!1,pos:0,str:"",marker:0};if(i)r.str=i.str,r.marker=i.marker;else{if(s>=n)return r;let l=e.charCodeAt(s);if(l!==34&&l!==39&&l!==40)return r;t++,s++,l===40&&(l=41),r.marker=l}for(;s<n;){if(o=e.charCodeAt(s),o===r.marker)return r.pos=s+1,r.str+=F0(e.slice(t,s)),r.ok=!0,r;if(o===40&&r.marker===41)return r;o===92&&s+1<n&&s++,s++}return r.can_continue=!0,r.str+=F0(e.slice(t,s)),r}var PR=v7;function x9(e,t){if(!e.attrs)return-1;for(let n=0;n<e.attrs.length;n++)if(e.attrs[n][0]===t)return n;return-1}function y7(e,t){e.attrs||(e.attrs=[]),e.attrs.push(t)}function n7e(e,t,n){const i=x9(e,t),o=[t,n];i<0?y7(e,o):e.attrs[i]=o}function i7e(e,t){const n=x9(e,t);return n>=0?e.attrs[n][1]:null}function o7e(e,t,n){const i=x9(e,t);i<0?y7(e,[t,n]):e.attrs[i][1]=`${e.attrs[i][1]} ${n}`}var s7e=FR({attrGet:()=>i7e,attrIndex:()=>x9,attrJoin:()=>o7e,attrPush:()=>y7,attrSet:()=>n7e,parseLinkDestination:()=>g7,parseLinkLabel:()=>m7,parseLinkTitle:()=>v7});function r7e(e){return e.includes("\r")||e.includes("\0")}function jR(e){return typeof e=="string"?e:e.toString()}function l7e(e){if(e.inlineMode){const t=new hs("inline","",0);t.content=jR(e.src),t.map=[0,1],t.children=[],t.level=0,e.tokens.push(t)}else e.md&&e.md.block&&e.md.block.parse(e.src,e.md,e.env,e.tokens)}const a7e=/^([a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)$/,u7e=/^([a-zA-Z][a-zA-Z0-9+.-]{1,31}):([^<>\x00-\x20]*)$/;function c7e(e,t){let n=e.pos;const i=e.src;if(i.charCodeAt(n)!==60)return!1;const o=n,s=e.posMax;for(;;){if(++n>=s)return!1;const l=i.charCodeAt(n);if(l===60)return!1;if(l===62)break}const r=i.slice(o+1,n);if(u7e.test(r)){const l=e.md.normalizeLink(r);if(!e.md.validateLink(l))return!1;if(!t){const a=e.push("link_open","a",1);a.attrs=[["href",l]],a.markup="autolink",a.info="auto";const u=e.push("text","",0);u.content=e.md.normalizeLinkText(r);const c=e.push("link_close","a",-1);c.markup="autolink",c.info="auto"}return e.pos+=r.length+2,!0}if(a7e.test(r)){const l=e.md.normalizeLink(`mailto:${r}`);if(!e.md.validateLink(l))return!1;if(!t){const a=e.push("link_open","a",1);a.attrs=[["href",l]],a.markup="autolink",a.info="auto";const u=e.push("text","",0);u.content=e.md.normalizeLinkText(r);const c=e.push("link_close","a",-1);c.markup="autolink",c.info="auto"}return e.pos+=r.length+2,!0}return!1}var HR=c7e;function d7e(e,t){const n=e.src;let i=e.pos;if(n.charCodeAt(i)!==96)return!1;const o=i;i++;const s=e.posMax;for(;i<s&&n.charCodeAt(i)===96;)i++;const r=n.slice(o,i),l=r.length;if(e.backticksScanned&&(e.backticks[l]||0)<=o)return t||(e.pending+=r),e.pos+=l,!0;let a=i,u;for(;(u=n.indexOf("`",a))!==-1;){for(a=u+1;a<s&&n.charCodeAt(a)===96;)a++;const c=a-u;if(c===l){if(!t){const d=e.push("code_inline","code",0);d.markup=r;let h=n.slice(i,u);h.includes(` -`)&&(h=h.replace(/\n/g," ")),h.length>2&&h.charCodeAt(0)===32&&h.charCodeAt(h.length-1)===32&&(h=h.slice(1,-1)),d.content=h}return e.pos=a,!0}e.backticks[c]=u}return e.backticksScanned=!0,t||(e.pending+=r),e.pos+=l,!0}var WR=d7e;function cM(e){const t={},n=e.length;if(!n)return;let i=0,o=-2;const s=[];for(let r=0;r<n;r++){const l=e[r];if(s.push(0),(e[i].marker!==l.marker||o!==l.token-1)&&(i=r),o=l.token,l.length=l.length||0,!l.close)continue;Object.prototype.hasOwnProperty.call(t,l.marker)||(t[l.marker]=[-1,-1,-1,-1,-1,-1]);const a=t[l.marker][(l.open?3:0)+l.length%3];let u=i-s[i]-1,c=u;for(;u>a;u-=s[u]+1){const d=e[u];if(d.marker===l.marker&&d.open&&d.end<0){let h=!1;if((d.close||l.open)&&(d.length+l.length)%3===0&&(d.length%3!==0||l.length%3!==0)&&(h=!0),!h){const p=u>0&&!e[u-1].open?s[u-1]+1:0;s[r]=r-u+p,s[u]=p,l.open=!1,d.end=r,d.close=!1,c=-1,o=-2;break}}}c!==-1&&(t[l.marker][(l.open?3:0)+(l.length||0)%3]=c)}}function f7e(e){const t=e.tokens_meta,n=e.tokens_meta.length;cM(e.delimiters);for(let i=0;i<n;i++)t[i]&&t[i].delimiters&&cM(t[i].delimiters)}var h7e=f7e;const qR="*",UR="_";function p7e(e,t){if(t)return!1;const n=e.src.charCodeAt(e.pos);if(n!==95&&n!==42)return!1;const i=e.scanDelims(e.pos,n===42);if(!i||i.length===0)return!1;const o=n===42?qR:UR,s=i.length,r=i.can_open,l=i.can_close,a=e.tokens,u=e.delimiters;for(let c=0;c<s;c++){const d=e.push("text","",0);d.content=o,u.push({marker:n,length:s,token:a.length-1,end:-1,open:r,close:l})}return e.pos+=s,!0}function dM(e,t){const n=t.length,i=e.tokens;for(let o=n-1;o>=0;o--){const s=t[o],r=s.marker;if(r!==95&&r!==42||s.end===-1)continue;const l=t[s.end],a=s.token,u=l.token,c=o>0&&t[o-1].end===s.end+1&&t[o-1].marker===r&&t[o-1].token===a-1&&t[s.end+1].token===u+1,d=r===42?qR:UR,h=i[a];c?(h.type="strong_open",h.tag="strong",h.nesting=1,h.markup=d+d,h.content=""):(h.type="em_open",h.tag="em",h.nesting=1,h.markup=d,h.content="");const p=i[u];c?(p.type="strong_close",p.tag="strong",p.nesting=-1,p.markup=d+d,p.content=""):(p.type="em_close",p.tag="em",p.nesting=-1,p.markup=d,p.content=""),c&&(i[t[o-1].token].content="",i[t[s.end+1].token].content="",o--)}}function g7e(e){const t=e.tokens_meta,n=e.tokens_meta.length;dM(e,e.delimiters);for(let i=0;i<n;i++)t[i]&&t[i].delimiters&&dM(e,t[i].delimiters)}const T8={tokenize:p7e,postProcess:g7e};function KR(e){return r7(e)}function k7(e){return e>=48&&e<=57}function m7e(e){const t=e|32;return k7(e)||t>=97&&t<=102}function VR(e){const t=e|32;return t>=97&&t<=122}function v7e(e){return VR(e)||k7(e)}function y7e(e,t,n){let i=t+2;if(i>=n)return null;let o=!1,s=7,r=i;for((e.charCodeAt(i)|32)===120&&(o=!0,s=6,i++,r=i);i<n&&i-r<s;){const l=e.charCodeAt(i);if(!(o?m7e(l):k7(l)))break;i++}return i===r||i>=n||e.charCodeAt(i)!==59?null:e.slice(t,i+1)}function k7e(e,t,n){let i=t+1;if(i>=n||!VR(e.charCodeAt(i)))return null;for(i++;i<n&&i-t-1<32&&v7e(e.charCodeAt(i));)i++;if(i-t-1<2||i>=n||e.charCodeAt(i)!==59)return null;const o=e.slice(t,i+1);return KR(o)!==o?o:null}function b7e(e,t){const n=e.pos,i=e.posMax;if(e.src.charCodeAt(n)!==38||n+1>=i)return!1;if(e.src.charCodeAt(n+1)===35){const o=y7e(e.src,n,i);if(o){if(!t){const s=(o.charCodeAt(2)|32)===120?Number.parseInt(o.slice(3,-1),16):Number.parseInt(o.slice(2,-1),10),r=e.push("text_special","",0);r.content=w9(s)?N0(s):N0(65533),r.markup=o,r.info="entity"}return e.pos+=o.length,!0}}else{const o=k7e(e.src,n,i);if(o){const s=KR(o);if(!t){const r=e.push("text_special","",0);r.content=s,r.markup=o,r.info="entity"}return e.pos+=o.length,!0}}return!1}var ZR=b7e;const GR=(()=>{const e=new Array(256).fill(0),t="\\!\"#$%&'()*+,./:;<=>?@[]^_`{|}~-";for(let n=0;n<32;n++)e[t.charCodeAt(n)]=1;return e})(),L8=new Array(128),QR=new Array(128);for(let e=0;e<128;e++){const t=String.fromCharCode(e);L8[e]=`\\${t}`,QR[e]=GR[e]?t:L8[e]}function fM(e,t,n){e.pending&&e.pushPending();const i=new hs("text_special","",0);i.level=e.level,i.content=t,i.markup=n,i.info="escape",e.pendingLevel=e.level,e.tokens.push(i),e.tokens_meta.push(null)}function A7e(e,t){let n=e.pos;const i=e.posMax,o=e.src;if(o.charCodeAt(n)!==92||(n++,n>=i))return!1;let s=o.charCodeAt(n);if(s===10){for(t||e.push("hardbreak","br",0),n++;n<i&&(s=o.charCodeAt(n),!(s!==9&&s!==32));)n++;return e.pos=n,!0}if(s<128)return t?(e.pos=n+1,!0):(fM(e,QR[s],L8[s]),e.pos=n+1,!0);if(t){if(s>=55296&&s<=56319&&n+1<i){const a=o.charCodeAt(n+1);a>=56320&&a<=57343&&n++}return e.pos=n+1,!0}let r=o.charAt(n);if(s>=55296&&s<=56319&&n+1<i){const a=o.charCodeAt(n+1);a>=56320&&a<=57343&&(r+=o.charAt(n+1),n++)}const l=`\\${r}`;return fM(e,s<256&&GR[s]?r:l,l),e.pos=n+1,!0}var YR=A7e;function C7e(e){let t,n,i=0;const o=e.tokens,s=e.tokens.length;for(t=n=0;t<s;t++){const r=o[t];r&&(r.nesting&&r.nesting<0&&i--,r.level=i,r.nesting&&r.nesting>0&&i++,r.type==="text"&&t+1<s&&o[t+1]?.type==="text"?o[t+1].content=r.content+o[t+1].content:(t!==n&&(o[n]=r),n++))}t!==n&&(o.length=n)}var w7e=C7e;const JR=`<[A-Za-z][A-Za-z0-9\\-]*(?:\\s+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:\\s*=\\s*(?:[^"'=<>\`\\x00-\\x20]+|'[^']*'|"[^"]*"))?)*\\s*\\/?>`,XR="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",x7e=new RegExp(`^(?:${JR}|${XR}|<!---?>|<!--(?:[^-]|-[^-]|--[^>])*-->|<\\?[\\s\\S]*?\\?>|<![A-Za-z][^>]*>|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>)`),S7e=new RegExp(`^(?:${JR}|${XR})`);function ez(e){return e===32||e===9||e===10||e===12||e===13}function _7e(e){if(e.length<3||e.charCodeAt(0)!==60||(e.charCodeAt(1)|32)!==97)return!1;const t=e.charCodeAt(2);return t===62||ez(t)}function M7e(e){if(e.length<4||e.charCodeAt(0)!==60||e.charCodeAt(1)!==47||(e.charCodeAt(2)|32)!==97)return!1;for(let t=3;t<e.length;t++){const n=e.charCodeAt(t);if(n===62)return!0;if(!ez(n))return!1}return!1}function I7e(e){const t=e|32;return t>=97&&t<=122}function E7e(e,t){if(!e.md.options.html)return!1;const n=e.posMax,i=e.pos,o=e.src;if(o.charCodeAt(i)!==60||i+2>=n)return!1;const s=o.charCodeAt(i+1);if(s!==33&&s!==63&&s!==47&&!I7e(s))return!1;const r=o.slice(i).match(x7e);if(!r)return!1;const l=r[0];if(!t){const a=e.pushSimple("html_inline","");a.content=l,_7e(l)&&e.linkLevel++,M7e(l)&&e.linkLevel--}return e.pos+=l.length,!0}var tz=E7e;function T7e(e,t){let n,i,o,s,r,l,a,u,c="";const d=e.pos,h=e.posMax;if(e.src.charCodeAt(e.pos)!==33||e.src.charCodeAt(e.pos+1)!==91)return!1;const p=e.pos+2,g=Y2(e,e.pos+1,!1);if(g<0)return!1;if(s=g+1,s<h&&e.src.charCodeAt(s)===40){for(s++;s<h&&(n=e.src.charCodeAt(s),!(n!==32&&n!==10));s++);if(s>=h)return!1;if(l=OR(e.src,s,e.posMax),l.ok){for(c=e.md.normalizeLink(l.str),e.md.validateLink(c)?s=l.pos:c="",u=s;s<h&&(n=e.src.charCodeAt(s),!(n!==32&&n!==10));s++);if(l=PR(e.src,s,e.posMax),s<h&&u!==s&&l.ok)for(a=l.str,s=l.pos;s<h&&(n=e.src.charCodeAt(s),!(n!==32&&n!==10));s++);else a=""}if(s>=h||e.src.charCodeAt(s)!==41)return e.pos=d,!1;s++}else{if(typeof e.env.references>"u")return!1;if(s<h&&e.src.charCodeAt(s)===91?(u=s+1,s=Y2(e,s),s>=0?o=e.src.slice(u,s++):s=g+1):s=g+1,o||(o=e.src.slice(p,g)),r=e.env.references[C9(o)],!r)return e.pos=d,!1;c=r.href,a=r.title}if(!t){i=e.src.slice(p,g);const m=[];e.md.inline.parse(i,e.md,e.env,m);const k=e.push("image","img",0);k.attrs=[["src",c],["alt",""]],k.children=m,k.content=i,a&&k.attrs.push(["title",a])}return e.pos=s,e.posMax=h,!0}var nz=T7e;function $3(e,t,n){for(;t<n;){const i=e.charCodeAt(t);if(i!==32&&i!==10)break;t++}return t}function L7e(e,t){if(e.src.charCodeAt(e.pos)!==91)return!1;const n=e.src,i=e.pos,o=e.posMax,s=e.pos+1,r=Y2(e,e.pos,!0);if(r<0)return!1;let l=r+1,a="",u="",c=!0;if(l<o&&n.charCodeAt(l)===40){l=$3(n,l+1,o);const d=OR(n,l,o);if(d.ok){const h=e.md.normalizeLink(d.str);e.md.validateLink(h)&&(a=h,l=d.pos,c=!1)}else l<o&&n.charCodeAt(l)===41&&(a="",c=!1);if(!c){if(l=$3(n,l,o),l<o&&n.charCodeAt(l)!==41){const h=PR(n,l,o);h.ok&&(u=h.str,l=$3(n,h.pos,o))}l<o&&n.charCodeAt(l)===41?l++:c=!0}}if(c){if(typeof e.env.references>"u")return!1;let d;if(l=r+1,l<o&&n.charCodeAt(l)===91){const p=l+1,g=Y2(e,l);g>=0?(d=n.slice(p,g),d||(d=n.slice(s,r)),l=g+1):d=n.slice(s,r)}else d=n.slice(s,r);const h=e.env.references[C9(d)];if(!h)return e.pos=i,!1;a=h.href,u=h.title}if(!t){e.pos=s,e.posMax=r;const d=e.push("link_open","a",1);d.attrs=u?[["href",a],["title",u]]:[["href",a]],e.linkLevel++,e.md.inline.tokenize(e),e.linkLevel--,e.push("link_close","a",-1)}return e.pos=l,e.posMax=o,!0}var iz=L7e;function oz(e){const t=e|32;return t>=97&&t<=122}function N7e(e){return e>=48&&e<=57}function F7e(e){return oz(e)||N7e(e)||e===43||e===45||e===46}function D7e(e){if(e.length===0)return null;let t=e.length-1;for(;t>=0&&F7e(e.charCodeAt(t));)t--;return t++,t>=e.length||!oz(e.charCodeAt(t))?null:e.slice(t)}function B7e(e,t,n){let i=t;for(;i<n;){const o=e.charCodeAt(i);if(o<=32||o===127||o===60)break;i++}return e.slice(t,i)}function sz(e,t){if(!e.md.options.linkify||e.linkLevel>0)return!1;const n=e.pos,i=e.posMax;if(n+3>i||e.src.charCodeAt(n)!==58||e.src.charCodeAt(n+1)!==47||e.src.charCodeAt(n+2)!==47)return!1;const o=D7e(e.pending);if(!o)return!1;const s=B7e(e.src,n-o.length,i),r=e.md.linkify.matchAtStart(s);if(!r)return!1;let l=r.url;if(l.length<=o.length)return!1;let a=l.length;for(;a>0&&l.charCodeAt(a-1)===42;)a--;a!==l.length&&(l=l.slice(0,a));const u=e.md.normalizeLink(l);if(!e.md.validateLink(u))return!1;if(!t){e.pending=e.pending.slice(0,-o.length);const c=e.push("link_open","a",1);c.attrs=[["href",u]],c.markup="linkify",c.info="auto";const d=e.push("text","",0);d.content=e.md.normalizeLinkText(l);const h=e.push("link_close","a",-1);h.markup="linkify",h.info="auto"}return e.pos+=l.length-o.length,!0}function $7e(e,t){let n=e.pos;if(e.src.charCodeAt(n)!==10)return!1;const i=e.pending.length-1,o=e.posMax;if(!t)if(i>=0&&e.pending.charCodeAt(i)===32)if(i>=1&&e.pending.charCodeAt(i-1)===32){let s=i-1;for(;s>=1&&e.pending.charCodeAt(s-1)===32;)s--;e.pending=e.pending.slice(0,s),e.pushSimple("hardbreak","br")}else e.pending=e.pending.slice(0,-1),e.pushSimple("softbreak","br");else e.pushSimple("softbreak","br");for(n++;n<o;){const s=e.src.charCodeAt(n);if(s!==9&&s!==32)break;n++}return e.pos=n,!0}var rz=$7e;function R7e(e,t){const n=e.pos,i=e.src.charCodeAt(n);if(t||i!==126)return!1;const o=e.scanDelims(e.pos,!0);if(!o)return!1;let s=o.length;const r=String.fromCharCode(i);if(s<2)return!1;let l;s%2&&(l=e.push("text","",0),l.content=r,s--);for(let a=0;a<s;a+=2)l=e.push("text","",0),l.content=r+r,e.delimiters.push({marker:i,length:0,token:e.tokens.length-1,end:-1,open:o.can_open,close:o.can_close});return e.pos+=o.length,!0}function hM(e,t){let n;const i=[],o=t.length;for(let s=0;s<o;s++){const r=t[s];if(r.marker!==126||r.end===-1)continue;const l=t[r.end];n=e.tokens[r.token],n.type="s_open",n.tag="s",n.nesting=1,n.markup="~~",n.content="",n=e.tokens[l.token],n.type="s_close",n.tag="s",n.nesting=-1,n.markup="~~",n.content="",e.tokens[l.token-1].type==="text"&&e.tokens[l.token-1].content==="~"&&i.push(l.token-1)}for(;i.length;){const s=i.pop();let r=s+1;for(;r<e.tokens.length&&e.tokens[r].type==="s_close";)r++;r--,s!==r&&(n=e.tokens[r],e.tokens[r]=e.tokens[s],e.tokens[s]=n)}}function z7e(e){const t=e.delimiters;hM(e,t);const n=e.tokens_meta;if(n)for(let i=0;i<n.length;i++)n[i]&&n[i].delimiters&&hM(e,n[i].delimiters)}const N8={tokenize:R7e,postProcess:z7e};function pM(e){switch(e){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!0;default:return!1}}function O7e(e,t){const n=e.src,i=e.pos,o=e.posMax;if(i>=o||pM(n.charCodeAt(i)))return!1;let s=i+1;for(;s<o&&!pM(n.charCodeAt(s));)s++;return t||(e.pending+=s===i+1?n.charAt(i):n.slice(i,s)),e.pos=s,!0}var lz=O7e;function b7(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function P7e(e){if(e.length===0)return 0;const t=e.slice().sort((i,o)=>i-o),n=Math.floor(t.length/2);return t.length%2===0?(t[n-1]+t[n])/2:t[n]}function j7e(e,t){return{chain:e,name:t,calls:0,hits:0,inclusiveMs:0,medianMs:0,maxMs:0,normalCalls:0,normalHits:0,silentCalls:0,silentHits:0,samples:[]}}function az(e){const t=e;if(!t)return null;if(t.__mdtsRuleProfile)return t.__mdtsRuleProfile;if(!t.__mdtsProfileRules)return null;const n=t.__mdtsProfileRules===!0?{}:t.__mdtsProfileRules,i={enabled:!0,fixture:n.fixture,mode:n.mode,startedAt:b7(),records:Object.create(null)};return t.__mdtsRuleProfile=i,i}function $h(e,t,n,i,o,s){const r=az(e);if(!r)return;const l=`${t}:${n}`,a=r.records[l]??(r.records[l]=j7e(t,n));a.calls++,a.inclusiveMs+=i,i>a.maxMs&&(a.maxMs=i),a.samples.push(i),s?(a.silentCalls++,o&&a.silentHits++):(a.normalCalls++,o&&a.normalHits++),o&&a.hits++,r.completedAt=b7()}function H7e(e){const t=az(e);if(!t)return null;const n=Object.keys(t.records);for(let i=0;i<n.length;i++){const o=t.records[n[i]];o.medianMs=P7e(o.samples)}return t.completedAt=b7(),t}var gM=class{rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t,n){const i=this.rules.findIndex(o=>o.name===e);i>=0&&this.rules.splice(i,1),this.rules.push({name:e,fn:t,alt:n?.alt||[],enabled:!0}),this.invalidateCache()}at(e,t,n){const i=this.rules.findIndex(o=>o.name===e);if(t===void 0){if(i<0)return;const o=this.rules[i];return Object.freeze({name:o.name,fn:o.fn,alt:o.alt?Object.freeze(o.alt.slice()):void 0,enabled:o.enabled})}if(i<0)throw new Error(`Parser rule not found: ${e}`);this.rules[i].fn=t,n?.alt!==void 0&&(this.rules[i].alt=n.alt),this.invalidateCache()}before(e,t,n,i){const o=this.rules.findIndex(r=>r.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this.rules.findIndex(r=>r.name===t);s>=0&&this.rules.splice(s,1),this.rules.splice(o,0,{name:t,fn:n,alt:i?.alt||[],enabled:!0}),this.invalidateCache()}after(e,t,n,i){const o=this.rules.findIndex(r=>r.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this.rules.findIndex(r=>r.name===t);s>=0&&this.rules.splice(s,1),this.rules.splice(o+1,0,{name:t,fn:n,alt:i?.alt||[],enabled:!0}),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;for(const s of n){const r=this.rules.findIndex(l=>l.name===s);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${s}`);continue}i.push(s),this.rules[r].enabled||(this.rules[r].enabled=!0,o=!0)}return o&&this.invalidateCache(),i}disable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;for(const s of n){const r=this.rules.findIndex(l=>l.name===s);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${s}`);continue}i.push(s),this.rules[r].enabled&&(this.rules[r].enabled=!1,o=!0)}return o&&this.invalidateCache(),i}enableOnly(e){const t=new Set(e);let n=!1;for(const i of this.rules){const o=t.has(i.name);i.enabled!==o&&(i.enabled=o,n=!0)}n&&this.invalidateCache()}getRules(e){const t=e||"";return this.cache||this.compileCache(),this.cache.get(t)??[]}getNamedRules(e){const t=e||"";return this.namedCache||this.compileCache(),this.namedCache.get(t)??[]}compileCache(){const e=new Set([""]);for(const i of this.rules)if(i.enabled&&i.alt)for(const o of i.alt)e.add(o);const t=new Map,n=new Map;for(const i of e){const o=[],s=[];for(const r of this.rules)r.enabled&&(i!==""&&!r.alt?.includes(i)||(o.push(r.fn),s.push({name:r.name,fn:r.fn})));t.set(i,o),n.set(i,s)}this.cache=t,this.namedCache=n}},uz=class{src;md;env;tokens;tokens_meta;pos;posMax;level;pending;pendingLevel;cache;delimiters;_prev_delimiters;backticks;backticksScanned;linkLevel;linkLabelNoCloseFrom;maxNesting;constructor(e,t,n,i){this.src=e,this.md=t,this.env=n,this.tokens=i,this.tokens_meta=new Array(i.length),this.pos=0,this.posMax=e.length,this.level=0,this.pending="",this.pendingLevel=0,this.cache=[],this.delimiters=[],this._prev_delimiters=[],this.backticks={},this.backticksScanned=!1,this.linkLevel=0,this.linkLabelNoCloseFrom=-1,this.maxNesting=t.options.maxNesting}pushPending(){const e=new hs("text","",0);return e.content=this.pending,e.level=this.pendingLevel,this.tokens.push(e),this.pending="",e}pushSimple(e,t){this.pending&&this.pushPending();const n=new hs(e,t,0);return n.level=this.level,this.pendingLevel=this.level,this.tokens.push(n),this.tokens_meta.push(null),n}push(e,t,n){if(this.pending&&this.pushPending(),n===0)return this.pushSimple(e,t);const i=new hs(e,t,n);let o=null;return n<0&&(this.level--,this.delimiters=this._prev_delimiters.pop()),i.level=this.level,n>0&&(this.level++,this._prev_delimiters.push(this.delimiters),this.delimiters=[],o={delimiters:this.delimiters}),this.pendingLevel=this.level,this.tokens.push(i),this.tokens_meta.push(o),i}scanDelims(e,t){const{src:n,posMax:i}=this,o=n.charCodeAt(e);let s=e;for(;s<i&&n.charCodeAt(s)===o;)s++;const r=s-e,l=e>0?n.charCodeAt(e-1):32,a=s<i?n.charCodeAt(s):32,u=L0(l),c=L0(a),d=M8(l),h=M8(a),p=!c&&(!h||u||d),g=!u&&(!d||c||h);return{can_open:p&&(t||!g||d),can_close:g&&(t||!p||h),length:r}}};uz.prototype.Token=hs;const W7e=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/;function mM(e,t){switch(e.src.charCodeAt(e.pos)){case 10:return rz(e,t);case 33:return nz(e,t);case 38:return ZR(e,t);case 42:case 95:return T8.tokenize(e,t);case 58:return e.md.options.linkify&&sz(e,t);case 60:return HR(e,t)||tz(e,t);case 91:return iz(e,t);case 92:return YR(e,t);case 96:return WR(e,t);case 126:return N8.tokenize(e,t);default:return lz(e,t)}}function cz(e){return!W7e.test(e)}var q7e=class{ruler;ruler2;cachedRulesVersion=-1;cachedRules=[];cachedRules2Version=-1;cachedRules2=[];defaultRulerVersion;defaultRuler2Version;constructor(){this.ruler=new gM,this.ruler2=new gM,this.ruler.push("text",lz),this.ruler.push("linkify",sz),this.ruler.push("newline",rz),this.ruler.push("escape",YR),this.ruler.push("backticks",WR),this.ruler.push("strikethrough",N8.tokenize),this.ruler.push("emphasis",T8.tokenize),this.ruler.push("link",iz),this.ruler.push("image",nz),this.ruler.push("autolink",HR),this.ruler.push("html_inline",tz),this.ruler.push("entity",ZR),this.ruler2.push("balance_pairs",h7e),this.ruler2.push("strikethrough",N8.postProcess),this.ruler2.push("emphasis",T8.postProcess),this.ruler2.push("fragments_join",w7e),this.defaultRulerVersion=this.ruler.version,this.defaultRuler2Version=this.ruler2.version}skipToken(e){const t=e.pos,n=this.getRules(),i=n.length,o=e.cache,s=o[t],r=!!e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules"));if(s!==void 0){e.pos=s;return}let l=!1;if(e.level<e.maxNesting){if(r){const a=this.ruler.getNamedRules("");for(let u=0;u<i;u++){e.level++;const c=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();l=a[u].fn(e,!0);const d=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if($h(e.env,"inline",a[u].name,d-c,!!l,!0),e.level--,l){if(t>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}}else if(this.isDefaultRuleset()){if(e.level++,l=mM(e,!0),e.level--,l&&t>=e.pos)throw new Error("inline rule didn't increment state.pos")}else for(let a=0;a<i;a++)if(e.level++,l=n[a](e,!0),e.level--,l){if(t>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}else e.pos=e.posMax;l||e.pos++,o[t]=e.pos}tokenize(e){const t=this.getRules(),n=t.length,i=e.posMax;if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){const s=this.isDefaultRuleset();for(;e.pos<i;){const r=e.pos;let l=!1;if(e.level<e.maxNesting){if(s)l=mM(e,!1);else for(let a=0;a<n&&(l=t[a](e,!1),!l);a++);if(l&&r>=e.pos)throw new Error("inline rule didn't increment state.pos")}if(l){if(e.pos>=i)break;continue}e.pending+=e.src.charAt(e.pos++)}e.pending&&e.pushPending();return}const o=this.ruler.getNamedRules("");for(;e.pos<i;){const s=e.pos;let r=!1;if(e.level<e.maxNesting)for(let l=0;l<n;l++){const a=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();r=o[l].fn(e,!1);const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if($h(e.env,"inline",o[l].name,u-a,!!r,!1),r){if(s>=e.pos)throw new Error("inline rule didn't increment state.pos");break}}if(r){if(e.pos>=i)break;continue}e.pending+=e.src.charAt(e.pos++)}e.pending&&e.pushPending()}isDefaultRuleset(){return this.ruler.version===this.defaultRulerVersion&&this.ruler2.version===this.defaultRuler2Version}parseSource(e,t,n,i){if(typeof e=="string"&&e.length>0&&this.isDefaultRuleset()&&cz(e)){const a=new hs("text","",0);a.content=e,i.push(a);return}const o=new uz(e,t,n,i);this.tokenize(o);const s=this.getRules2(),r=s.length;if(!(o.env&&(Object.prototype.hasOwnProperty.call(o.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(o.env,"__mdtsProfileRules")))){for(let a=0;a<r;a++)s[a](o,!1);return}const l=this.ruler2.getNamedRules("");for(let a=0;a<r;a++){const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();l[a].fn(o,!1);const c=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();$h(o.env,"inline2",l[a].name,c-u,!0,!1)}}parse(e,t,n,i){this.parseSource(e,t,n,i)}getRules(){return this.cachedRulesVersion!==this.ruler.version&&(this.cachedRules=this.ruler.getRules(""),this.cachedRulesVersion=this.ruler.version),this.cachedRules}getRules2(){return this.cachedRules2Version!==this.ruler2.version&&(this.cachedRules2=this.ruler2.getRules(""),this.cachedRules2Version=this.ruler2.version),this.cachedRules2}};function U7e(e){const t=e.tokens,n=!!e.md?.inline?.isDefaultRuleset?.();for(let i=0,o=t.length;i<o;i++){const s=t[i];if(s.type==="inline"&&e.md){if(s.children||(s.children=[]),n&&s.content.length>0&&cz(s.content)){const r=new hs("text","",0);r.content=s.content,s.children.push(r);continue}e.md.inline.parse(s.content,e.md,e.env,s.children)}}}const K7e=/[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}]/u,V7e=/[0-9a-z]/i;function Z7e(e){return/^<a[>\s]/i.test(e)}function G7e(e){return/^<\/a\s*>/i.test(e)}function Q7e(e,t){if(t.schema||t.index!==0||!t.raw)return t;for(let n=1;n<t.raw.length;n++){const i=t.raw[n-1],o=t.raw[n];if(!K7e.test(i)||!V7e.test(o))continue;const s=t.raw.slice(n),r=e.match(s)?.[0];if(!(!r||r.index!==0||r.lastIndex!==s.length))return{...r,index:t.index+n,lastIndex:t.index+n+r.lastIndex}}return t}function Y7e(e){const t=e.tokens;if(e.md?.options?.linkify)for(let n=0;n<t.length;n++){const i=t[n];if(i.type!=="inline"||!e.md.linkify.test(i.content))continue;let o=i.children;o||(o=[],i.children=o);let s=0;for(let r=o.length-1;r>=0;r--){const l=o[r];if(l.type==="link_close"){for(r--;r>=0&&o[r].level!==l.level&&o[r].type!=="link_open";)r--;continue}if(l.type==="html_inline"&&(Z7e(l.content)&&s>0&&s--,G7e(l.content)&&s++),s>0||l.type!=="text"||!e.md.linkify.test(l.content))continue;const a=l.content;let u=(e.md.linkify.match(a)||[]).map(p=>Q7e(e.md.linkify,p));if(u.length===0)continue;const c=[];let d=l.level,h=0;u.length>0&&u[0].index===0&&r>0&&o[r-1].type==="text_special"&&(u=u.slice(1));for(let p=0;p<u.length;p++){const g=u[p],m=e.md.normalizeLink(g.url);if(!e.md.validateLink(m))continue;let k=g.text;g.schema?g.schema==="mailto:"&&!/^mailto:/i.test(k)?k=e.md.normalizeLinkText(`mailto:${k}`).replace(/^mailto:/,""):k=e.md.normalizeLinkText(k):k=e.md.normalizeLinkText(`http://${k}`).replace(/^http:\/\//,"");const w=g.index;if(w>h){const T=new hs("text","",0);T.content=a.slice(h,w),T.level=d,c.push(T)}const y=new hs("link_open","a",1);y.attrs=[["href",m]],y.level=d++,y.markup="linkify",y.info="auto",c.push(y);const b=new hs("text","",0);b.content=k,b.level=d,c.push(b);const A=new hs("link_close","a",-1);A.level=--d,A.markup="linkify",A.info="auto",c.push(A),h=g.lastIndex}if(h!==0){if(h<a.length){const p=new hs("text","",0);p.content=a.slice(h),p.level=d,c.push(p)}o.splice(r,1,...c)}}}}const J7e=/\r\n?|\n/g,X7e=/\0/g;function eAe(e){if(!e||typeof e.src!="string")return;const t=e.src,n=t.includes("\r"),i=t.includes("\0");if(!n&&!i)return;let o=t;n&&(o=o.replace(J7e,` -`)),i&&(o=o.replace(X7e,"�")),e.src=o}const dz=/\+-|\.\.|\?\?\?\?|!!!!|,,|--/,tAe=/\((?:c|tm|r)\)/i,nAe=/\((c|tm|r)\)/gi,iAe={c:"©",r:"®",tm:"™"};function oAe(e,t){return iAe[t.toLowerCase()]}function sAe(e){let t=0;for(let n=e.length-1;n>=0;n--){const i=e[n];i.type==="text"&&!t&&(i.content=i.content.replace(nAe,oAe)),i.type==="link_open"&&i.info==="auto"&&t--,i.type==="link_close"&&i.info==="auto"&&t++}}function rAe(e){let t=0;for(let n=e.length-1;n>=0;n--){const i=e[n];i.type==="text"&&!t&&dz.test(i.content)&&(i.content=i.content.replace(/\+-/g,"±").replace(/\.{2,}/g,"…").replace(/([?!])…/g,"$1..").replace(/([?!]){4,}/g,"$1$1$1").replace(/,{2,}/g,",").replace(/(^|[^-])---(?=[^-]|$)/gm,"$1—").replace(/(^|\s)--(?=\s|$)/gm,"$1–").replace(/(^|[^-\s])--(?=[^-\s]|$)/gm,"$1–")),i.type==="link_open"&&i.info==="auto"&&t--,i.type==="link_close"&&i.info==="auto"&&t++}}function lAe(e){if(e.md?.options?.typographer)for(let t=e.tokens.length-1;t>=0;t--){const n=e.tokens[t];if(n.type!=="inline")continue;const i=n.content||(Array.isArray(n.children)?n.children.map(o=>o.type==="text"?o.content:"").join(""):"");tAe.test(i)&&sAe(n.children||[]),dz.test(i)&&rAe(n.children||[])}}var aAe=class{rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t){const n=this.rules.findIndex(i=>i.name===e);n>=0&&this.rules.splice(n,1),this.rules.push({name:e,fn:t,enabled:!0}),this.invalidateCache()}at(e,t){const n=this.rules.findIndex(i=>i.name===e);if(n<0)throw new Error(`Parser rule not found: ${e}`);this.rules[n].fn=t,this.invalidateCache()}before(e,t,n){const i=this.rules.findIndex(s=>s.name===e);if(i<0)throw new Error(`Parser rule not found: ${e}`);const o=this.rules.findIndex(s=>s.name===t);o>=0&&this.rules.splice(o,1),this.rules.splice(i,0,{name:t,fn:n,enabled:!0}),this.invalidateCache()}after(e,t,n){const i=this.rules.findIndex(s=>s.name===e);if(i<0)throw new Error(`Parser rule not found: ${e}`);const o=this.rules.findIndex(s=>s.name===t);o>=0&&this.rules.splice(o,1),this.rules.splice(i+1,0,{name:t,fn:n,enabled:!0}),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;for(const s of n){const r=this.rules.findIndex(l=>l.name===s);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${s}`);continue}i.push(s),this.rules[r].enabled||(this.rules[r].enabled=!0,o=!0)}return o&&this.invalidateCache(),i}disable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;for(const s of n){const r=this.rules.findIndex(l=>l.name===s);if(r<0){if(!t)throw new Error(`Rules manager: invalid rule name ${s}`);continue}i.push(s),this.rules[r].enabled&&(this.rules[r].enabled=!1,o=!0)}return o&&this.invalidateCache(),i}enableOnly(e){const t=new Set(e);let n=!1;for(const i of this.rules){const o=t.has(i.name);i.enabled!==o&&(i.enabled=o,n=!0)}n&&this.invalidateCache()}compileCache(){this.cache=this.rules.filter(e=>e.enabled).map(e=>e.fn),this.namedCache=this.rules.filter(e=>e.enabled).map(e=>({name:e.name,fn:e.fn}))}getRules(e=""){return this.cache||this.compileCache(),this.cache}getNamedRules(e=""){return this.namedCache||this.compileCache(),this.namedCache}};const uAe=/['"]/,vM=/['"]/g,yM="’";function Om(e,t,n){return e.slice(0,t)+n+e.slice(t+1)}function cAe(e,t){let n;const i=[],o=t.md&&t.md.options&&t.md.options.quotes||"“”‘’";for(let s=0;s<e.length;s++){const r=e[s],l=e[s].level;for(n=i.length-1;n>=0&&!(i[n].level<=l);n--);if(i.length=n+1,r.type!=="text")continue;let a=r.content,u=0,c=a.length;e:for(;u<c;){vM.lastIndex=u;const d=vM.exec(a);if(!d)break;let h=!0,p=!0;u=d.index+1;const g=d[0]==="'";let m=32;if(d.index-1>=0)m=a.charCodeAt(d.index-1);else for(n=s-1;n>=0&&!(e[n].type==="softbreak"||e[n].type==="hardbreak");n--)if(e[n].content){m=e[n].content.charCodeAt(e[n].content.length-1);break}let k=32;if(u<c)k=a.charCodeAt(u);else for(n=s+1;n<e.length&&!(e[n].type==="softbreak"||e[n].type==="hardbreak");n++)if(e[n].content){k=e[n].content.charCodeAt(0);break}const w=G2(m)||Z2(String.fromCharCode(m)),y=G2(k)||Z2(String.fromCharCode(k)),b=L0(m),A=L0(k);if(A?h=!1:y&&(b||w||(h=!1)),b?p=!1:w&&(A||y||(p=!1)),k===34&&d[0]==='"'&&m>=48&&m<=57&&(p=h=!1),h&&p&&(h=w,p=y),!h&&!p){g&&(r.content=Om(r.content,d.index,yM));continue}if(p)for(n=i.length-1;n>=0;n--){let T=i[n];if(i[n].level<l)break;if(T.single===g&&i[n].level===l){T=i[n];let S,x;g?(S=o[2]||"‘",x=o[3]||"’"):(S=o[0]||"“",x=o[1]||"”"),r.content=Om(r.content,d.index,x),e[T.token].content=Om(e[T.token].content,T.pos,S),u+=x.length-1,T.token===s&&(u+=S.length-1),a=r.content,c=a.length,i.length=n;continue e}}h?i.push({token:s,pos:d.index,single:g,level:l}):p&&g&&(r.content=Om(r.content,d.index,yM))}}}function dAe(e){if(e.md.options.typographer)for(let t=e.tokens.length-1;t>=0;t--){const n=e.tokens[t];if(n.type!=="inline")continue;const i=typeof n.content=="string"?n.content:(n.children||[]).map(o=>o.content||"").join("");!uAe.test(i)||!n.children||cAe(n.children,e)}}function fAe(e){const t=e.tokens||[],n=t.length;for(let i=0;i<n;i++){const o=t[i];if(o.type!=="inline"||!Array.isArray(o.children))continue;const s=o.children,r=s.length;for(let u=0;u<r;u++)s[u].type==="text_special"&&(s[u].type="text");let l=0,a=0;for(;a<r;a++)s[a].type==="text"&&a+1<r&&s[a+1].type==="text"?s[a+1].content=s[a].content+s[a+1].content:(a!==l&&(s[l]=s[a]),l++);a!==l&&(s.length=l)}}const hAe=/^(?:vbscript|javascript|file|data):/,pAe=/^data:image\/(?:gif|png|jpeg|webp);/,fz=["http:","https:","mailto:"];function hz(e){const t=e.trim().toLowerCase();return hAe.test(t)?pAe.test(t):!0}function pz(e){const t=a7(e,!0);if(t.hostname&&(!t.protocol||fz.includes(t.protocol)))try{t.hostname=zR.default.toASCII(t.hostname)}catch{}return LR(l7(t))}function gz(e){const t=a7(e,!0);if(t.hostname&&(!t.protocol||fz.includes(t.protocol)))try{t.hostname=zR.default.toUnicode(t.hostname)}catch{}return _8(l7(t),`${_8.defaultChars}%`)}function gAe(e){switch(e){case 9:case 32:return!0}return!1}function mAe(e,t,n,i){const o=e.src,s=e.bMarks,r=e.eMarks,l=e.tShift,a=e.sCount,u=e.bsCount;let c=s[t]+l[t],d=r[t];const h=e.lineMax;if(a[t]-e.blkIndent>=4||o.charCodeAt(c)!==62)return!1;if(i)return!0;const p=[],g=[],m=[],k=[],w=e.md.block.ruler.getRulesForState(e,"blockquote"),y=e.parentType;e.parentType="blockquote";let b=!1,A;for(A=t;A<n;A++){const L=a[A]<e.blkIndent;if(c=s[A]+l[A],d=r[A],c>=d)break;if(o.charCodeAt(c++)===62&&!L){let N=a[A]+1,I,z;o.charCodeAt(c)===32?(c++,N++,z=!1,I=!0):o.charCodeAt(c)===9?(I=!0,(u[A]+N)%4===3?(c++,N++,z=!1):z=!0):I=!1;let H=N;for(p.push(s[A]),s[A]=c;c<d;){const O=o.charCodeAt(c);if(gAe(O))O===9?H+=4-(H+u[A]+(z?1:0))%4:H++;else break;c++}b=c>=d,g.push(u[A]),u[A]=a[A]+1+(I?1:0),m.push(a[A]),a[A]=H-N,k.push(l[A]),l[A]=c-s[A];continue}if(b)break;let M=!1;for(let N=0,I=w.length;N<I;N++)if(w[N](e,A,n,!0)){M=!0;break}if(M){e.lineMax=A,e.blkIndent!==0&&(p.push(s[A]),g.push(u[A]),k.push(l[A]),m.push(a[A]),a[A]-=e.blkIndent);break}p.push(s[A]),g.push(u[A]),k.push(l[A]),m.push(a[A]),a[A]=-1}const T=e.blkIndent;e.blkIndent=0;const S=e.push("blockquote_open","blockquote",1);S.markup=">";const x=[t,0];S.map=x,e.md.block.tokenize(e,t,A);const _=e.push("blockquote_close","blockquote",-1);_.markup=">",e.lineMax=h,e.parentType=y,x[1]=e.line;for(let L=0;L<k.length;L++)s[L+t]=p[L],l[L+t]=k[L],a[L+t]=m[L],u[L+t]=g[L];return e.blkIndent=T,!0}function vAe(e,t,n){if(e.sCount[t]-e.blkIndent<4)return!1;let i=t+1,o=i;for(;i<n;){if(e.isEmpty(i)){i++;continue}if(e.sCount[i]-e.blkIndent>=4){i++,o=i;continue}break}e.line=o;const s=e.push("code_block","code",0);return s.content=`${e.getLines(t,o,4+e.blkIndent,!1)} -`,s.map=[t,e.line],!0}function yAe(e,t,n,i){let o=e.bMarks[t]+e.tShift[t],s=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||o+3>s)return!1;const r=e.src.charCodeAt(o);if(r!==126&&r!==96)return!1;let l=o;o=e.skipChars(o,r);let a=o-l;if(a<3)return!1;const u=e.src.slice(l,o),c=e.src.slice(o,s);if(r===96&&c.includes(String.fromCharCode(r)))return!1;if(i)return!0;let d=t,h=!1;for(;d++,!(d>=n||(o=l=e.bMarks[d]+e.tShift[d],s=e.eMarks[d],o<s&&e.sCount[d]<e.blkIndent));)if(e.src.charCodeAt(o)===r&&!(e.sCount[d]-e.blkIndent>=4)&&(o=e.skipChars(o,r),!(o-l<a)&&(o=e.skipSpaces(o),!(o<s)))){h=!0;break}a=e.sCount[t],e.line=d+(h?1:0);const p=e.push("fence","code",0);return p.info=c,p.content=e.getLines(t+1,d,a,!0),p.markup=u,p.map=[t,e.line],!0}const kM=["","h1","h2","h3","h4","h5","h6"],bM=["","#","##","###","####","#####","######"];function AM(e){switch(e){case 9:case 32:return!0}return!1}function kAe(e,t,n,i){const o=e.src,s=e.bMarks,r=e.tShift,l=e.eMarks;let a=s[t]+r[t],u=l[t];if(e.sCount[t]-e.blkIndent>=4)return!1;let c=o.charCodeAt(a);if(c!==35||a>=u)return!1;let d=1;for(c=o.charCodeAt(++a);c===35&&a<u&&d<=6;)d++,c=o.charCodeAt(++a);if(d>6||a<u&&!AM(c))return!1;if(i)return!0;u=e.skipSpacesBack(u,a);const h=e.skipCharsBack(u,35,a);h>a&&AM(o.charCodeAt(h-1))&&(u=h),e.line=t+1;const p=e.push("heading_open",kM[d],1);p.markup=bM[d],p.map=[t,e.line];const g=e.push("inline","",0);g.content=o.slice(a,u).trim(),g.map=[t,e.line],g.children=[];const m=e.push("heading_close",kM[d],-1);return m.markup=bM[d],!0}function bAe(e){switch(e){case 9:case 32:return!0}return!1}function AAe(e,t,n,i){const o=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4)return!1;let s=e.bMarks[t]+e.tShift[t];const r=e.src.charCodeAt(s++);if(r!==42&&r!==45&&r!==95)return!1;let l=1;for(;s<o;){const u=e.src.charCodeAt(s++);if(u!==r&&!bAe(u))return!1;u===r&&l++}if(l<3)return!1;if(i)return!0;e.line=t+1;const a=e.push("hr","hr",0);return a.map=[t,e.line],a.markup=new Array(l+1).join(String.fromCharCode(r)),!0}const Vf=[[/^<(script|pre|style|textarea)(?=(\s|>|$))/i,/<\/(script|pre|style|textarea)>/i,!0],[/^<!--/,/-->/,!0],[/^<\?/,/\?>/,!0],[/^<![A-Z]/,/>/,!0],[/^<!\[CDATA\[/,/\]\]>/,!0],[new RegExp(`^</?(${["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"].join("|")})(?=(\\s|/?>|$))`,"i"),/^$/,!0],[new RegExp(`${S7e.source}\\s*$`),/^$/,!1]];function CAe(e,t,n,i){let o=e.bMarks[t]+e.tShift[t],s=e.eMarks[t];if(e.sCount[t]-e.blkIndent>=4||!e.md.options.html||e.src.charCodeAt(o)!==60)return!1;let r=e.src.slice(o,s),l=0;for(;l<Vf.length&&!Vf[l][0].test(r);l++);if(l===Vf.length)return!1;if(i)return Vf[l][2];let a=t+1;if(!Vf[l][1].test(r)){for(;a<n&&!(e.sCount[a]<e.blkIndent);a++)if(o=e.bMarks[a]+e.tShift[a],s=e.eMarks[a],r=e.src.slice(o,s),Vf[l][1].test(r)){r.length!==0&&a++;break}}e.line=a;const u=e.push("html_block","",0);return u.map=[t,a],u.content=e.getLines(t,a,e.blkIndent,!0),!0}function CM(e){switch(e){case 9:case 32:return!0}return!1}const jp={Pipe:1,ParagraphTerminator:2};function wAe(e){switch(e){case 35:case 42:case 43:case 45:case 60:case 62:case 95:case 96:case 124:case 126:return!0}return e>=48&&e<=57}var mz=class{src;md;env;tokens;bMarks=[];eMarks=[];tShift=[];sCount=[];bsCount=[];lineFlags=[];blkIndent=0;line=0;lineMax=0;tight=!1;ddIndent=-1;listIndent=-1;parentType="root";level=0;constructor(e,t,n,i){this.src=e,this.md=t,this.env=n,this.tokens=i;const o=this.src;let s=0,r=0,l=0,a=!1,u=0;for(let c=0,d=o.length;c<d;c++){const h=o.charCodeAt(c);if(h===124&&(u|=jp.Pipe|jp.ParagraphTerminator),!a)if(CM(h)){s++,h===9?r+=4-r%4:r++;continue}else a=!0,wAe(h)&&(u|=jp.ParagraphTerminator);(h===10||c===d-1)&&(h!==10&&c++,this.bMarks.push(l),this.eMarks.push(c),this.tShift.push(s),this.sCount.push(r),this.bsCount.push(0),this.lineFlags.push(u),a=!1,s=0,r=0,u=0,l=c+1)}this.bMarks.push(o.length),this.eMarks.push(o.length),this.tShift.push(0),this.sCount.push(0),this.bsCount.push(0),this.lineFlags.push(0),this.lineMax=this.bMarks.length-1}push(e,t,n){if(n===0){const o=new hs(e,t,0);return o.block=!0,o.level=this.level,this.tokens.push(o),o}const i=new hs(e,t,n);return i.block=!0,n<0&&this.level--,i.level=this.level,n>0&&this.level++,this.tokens.push(i),i}isEmpty(e){return this.bMarks[e]+this.tShift[e]>=this.eMarks[e]}skipEmptyLines(e){const t=this.bMarks,n=this.tShift,i=this.eMarks;for(let o=this.lineMax;e<o&&!(t[e]+n[e]<i[e]);e++);return e}skipSpaces(e){const t=this.src;for(let n=t.length;e<n;e++){const i=t.charCodeAt(e);if(i!==9&&i!==32)break}return e}skipSpacesBack(e,t){if(e<=t)return e;const n=this.src;for(;e>t;){const i=n.charCodeAt(--e);if(i!==9&&i!==32)return e+1}return e}skipChars(e,t){const n=this.src;for(let i=n.length;e<i&&n.charCodeAt(e)===t;e++);return e}skipCharsBack(e,t,n){if(e<=n)return e;const i=this.src;for(;e>n;)if(t!==i.charCodeAt(--e))return e+1;return e}getLines(e,t,n,i){if(e>=t)return"";if(e+1===t){const c=e,d=this.bMarks[c];let h=d;const p=i?this.eMarks[c]+1:this.eMarks[c];let g=0;const m=this.src,k=this.bsCount,w=this.tShift;for(;h<p&&g<n;){const y=m.charCodeAt(h);if(y===9||y===32)y===9?g+=4-(g+k[c])%4:g++;else if(h-d<w[c])g++;else break;h++}return g>n?new Array(g-n+1).join(" ")+m.slice(h,p):m.slice(h,p)}const o=new Array(t-e),s=this.src,r=this.bMarks,l=this.eMarks,a=this.bsCount,u=this.tShift;for(let c=0,d=e;d<t;d++,c++){let h=0;const p=r[d];let g=p,m;for(d+1<t||i?m=l[d]+1:m=l[d];g<m&&h<n;){const k=s.charCodeAt(g);if(CM(k))k===9?h+=4-(h+a[d])%4:h++;else if(g-p<u[d])h++;else break;g++}h>n?o[c]=new Array(h-n+1).join(" ")+s.slice(g,m):o[c]=s.slice(g,m)}return o.join("")}};mz.prototype.Token=hs;function xAe(e,t,n){for(let i=t;i<n;i++)if(e.charCodeAt(i)===124)return!0;return!1}function vz(e){const t=e?.md?.block?.ruler;return t?t.version===t.__mdtsDefaultVersion:!1}function yz(e,t,n,i,o){if(e.lineFlags&&(e.lineFlags[t]&jp.ParagraphTerminator)===0||i>=o)return!1;const s=n.charCodeAt(i);switch(s){case 35:case 42:case 43:case 45:case 60:case 62:case 95:case 96:case 126:return!0}return s>=48&&s<=57?!0:xAe(n,i,o)}const wM=["","h1","h2"];function SAe(e,t,n){const i=e.md.block.ruler.getRulesForState(e,"paragraph"),o=e.src,s=e.bMarks,r=e.tShift,l=e.eMarks,a=e.sCount,u=e.blkIndent,c=vz(e);if(a[t]-u>=4)return!1;const d=e.parentType;e.parentType="paragraph";let h=0,p,g=t+1;for(;g<n;g++){const A=s[g]+r[g],T=l[g];if(A>=T)break;if(a[g]-u>3)continue;if(a[g]>=u&&(p=o.charCodeAt(A),p===45||p===61)){let x=A+1,_=x;for(;x<T&&o.charCodeAt(x)===p;)x++;for(_=x;x<T;){const L=o.charCodeAt(x);if(L!==9&&L!==32)break;x++}if(x>=T){h=p===61?1:2;break}if(_-A>1)continue}if(a[g]<0||c&&!yz(e,g,o,A,T))continue;let S=!1;for(let x=0,_=i.length;x<_;x++)if(i[x](e,g,n,!0)){S=!0;break}if(S)break}if(!h)return!1;let m;if(g===t+1){const A=s[t]+r[t];let T=l[t];for(;T>A;){const S=o.charCodeAt(T-1);if(S!==9&&S!==32)break;T--}m=o.slice(A,T)}else m=e.getLines(t,g,u,!1).trim();e.line=g+1;const k=p===61?"=":"-",w=e.push("heading_open",wM[h],1);w.markup=k,w.map=[t,e.line];const y=e.push("inline","",0);y.content=m,y.map=[t,e.line-1],y.children=[];const b=e.push("heading_close",wM[h],-1);return b.markup=k,e.parentType=d,!0}function kz(e){switch(e){case 9:case 32:return!0}return!1}function xM(e,t){const n=e.eMarks,i=e.bMarks,o=e.tShift,s=e.src,r=n[t];let l=i[t]+o[t];const a=s.charCodeAt(l++);return a!==42&&a!==45&&a!==43||l<r&&!kz(s.charCodeAt(l))?-1:l}function SM(e,t){const n=e.bMarks,i=e.tShift,o=e.eMarks,s=e.src,r=n[t]+i[t],l=o[t];let a=r;if(a+1>=l)return-1;let u=s.charCodeAt(a++);if(u<48||u>57)return-1;for(;;){if(a>=l)return-1;if(u=s.charCodeAt(a++),u>=48&&u<=57){if(a-r>=10)return-1;continue}if(u===41||u===46)break;return-1}return a<l&&(u=s.charCodeAt(a),!kz(u))?-1:a}function _Ae(e,t,n){const i=e.bMarks,o=e.tShift,s=e.src,r=i[t]+o[t];let l=0;for(let a=r;a<n-1;a++)l=l*10+s.charCodeAt(a)-48;return l}const MAe=["0","1","2","3","4","5","6","7","8","9"];function IAe(e,t){const n=e.level+2,i=e.tokens;for(let o=t+2,s=i.length-2;o<s;o++){const r=i[o];if(r.level===n){if(r.type==="paragraph_open"){r.hidden=!0,i[o+2].hidden=!0,o+=2;continue}if(r.nesting===1){let l=1;for(;l>0&&++o<s;)l+=i[o].nesting}}}}function EAe(e,t,n,i){let o,s,r=0,l=t,a=!0;if(e.sCount[l]-e.blkIndent>=4||e.listIndent>=0&&e.sCount[l]-e.listIndent>=4&&e.sCount[l]<e.blkIndent)return!1;let u=!1;i&&e.parentType==="paragraph"&&e.sCount[l]>=e.blkIndent&&(u=!0);let c,d,h;const p=e.src,g=e.bMarks,m=e.tShift,k=e.eMarks,w=e.sCount,y=e.bsCount,b=g[l]+m[l];if(b>=k[l])return!1;const A=p.charCodeAt(b);if(A>=48&&A<=57){if(h=SM(e,l),h<0||(c=!0,r=b,d=_Ae(e,l,h),u&&d!==1))return!1}else if(A===42||A===45||A===43){if(h=xM(e,l),h<0)return!1;c=!1}else return!1;if(u&&e.skipSpaces(h)>=k[l])return!1;if(i)return!0;const T=p.charCodeAt(h-1),S=String.fromCharCode(T);if(c){const I=e.push("ordered_list_open","ol",1);d!==void 0&&d!==1&&(I.attrs=[["start",String(d)]])}else e.push("bullet_list_open","ul",1);const x=[l,0];e.tokens[e.tokens.length-1].map=x,e.tokens[e.tokens.length-1].markup=S;let _=!1;const L=e.tokens.length-1,M=e.md.block.ruler.getRulesForState(e,"list"),N=e.parentType;for(e.parentType="list";l<n;){s=h,o=k[l];const I=w[l]+h-(g[l]+m[l]);let z=I;for(;s<o;){const Y=p.charCodeAt(s);if(Y===9)z+=4-(z+y[l])%4;else if(Y===32)z++;else break;s++}const H=s;let O;H>=o?O=1:O=z-I,O>4&&(O=1);const R=I+O,j=e.push("list_item_open","li",1);j.markup=S;const $=[l,0];j.map=$,c&&(j.info=h-r-1===1?MAe[p.charCodeAt(r)-48]:p.slice(r,h-1));const W=e.tight,P=e.tShift[l],Z=e.sCount[l],ae=e.listIndent;if(e.listIndent=e.blkIndent,e.blkIndent=R,e.tight=!0,e.tShift[l]=H-g[l],e.sCount[l]=z,H>=o&&e.isEmpty(l+1)?e.line=Math.min(e.line+2,n):e.md.block.tokenize(e,l,n,!0),(!e.tight||_)&&(a=!1),_=e.line-l>1&&e.isEmpty(e.line-1),e.blkIndent=e.listIndent,e.listIndent=ae,e.tShift[l]=P,e.sCount[l]=Z,e.tight=W,e.push("list_item_close","li",-1).markup=S,l=e.line,$[1]=l,l>=n||e.sCount[l]<e.blkIndent||e.sCount[l]-e.blkIndent>=4)break;let V=!1;for(let Y=0,oe=M.length;Y<oe;Y++)if(M[Y](e,l,n,!0)){V=!0;break}if(V)break;if(c){if(h=SM(e,l),h<0)break;r=g[l]+m[l]}else if(h=xM(e,l),h<0)break;if(T!==p.charCodeAt(h-1))break}return c?e.push("ordered_list_close","ol",-1).markup=S:e.push("bullet_list_close","ul",-1).markup=S,x[1]=l,e.line=l,e.parentType=N,a&&IAe(e,L),!0}function _M(e){return e===9||e===32}function TAe(e,t,n){const i=e.md.block.ruler.getRulesForState(e,"paragraph"),o=e.parentType,s=e.src,r=e.bMarks,l=e.tShift,a=e.eMarks,u=e.sCount,c=e.blkIndent,d=vz(e);let h=t+1;for(e.parentType="paragraph";h<n&&!e.isEmpty(h);h++){if(u[h]-c>3||u[h]<0)continue;if(o==="list"&&u[h]>=c){const b=r[h]+l[h],A=a[h];if(b<A){const T=s.charCodeAt(b);if(T===42||T===45||T===43){if(b+1>=A||_M(s.charCodeAt(b+1)))break}else if(T>=48&&T<=57&&b+1<A){let S=b+1;for(;;){if(S>=A){S=-1;break}const x=s.charCodeAt(S++);if(x>=48&&x<=57){if(S-b>=10){S=-1;break}continue}if((x===41||x===46)&&(S>=A||_M(s.charCodeAt(S))))break;S=-1;break}if(S>=0)break}}}const k=r[h]+l[h],w=a[h];if(d&&!yz(e,h,s,k,w))continue;let y=!1;for(let b=0,A=i.length;b<A;b++)if(i[b](e,h,n,!0)){y=!0;break}if(y)break}const p=e.getLines(t,h,c,!1).trim();e.line=h;const g=e.push("paragraph_open","p",1);g.map=[t,e.line];const m=e.push("inline","",0);return m.content=p,m.map=[t,e.line],m.children=[],e.push("paragraph_close","p",-1),e.parentType=o,!0}function Pm(e){switch(e){case 9:case 32:return!0}return!1}function LAe(e,t,n,i){let o=e.bMarks[t]+e.tShift[t],s=e.eMarks[t],r=t+1;const l=e.md.block.ruler.getRulesForState(e,"reference");if(e.sCount[t]-e.blkIndent>=4||e.src.charCodeAt(o)!==91)return!1;function a(b){const A=e.lineMax;if(b>=A||e.isEmpty(b))return null;let T=!1;if(e.sCount[b]-e.blkIndent>3&&(T=!0),e.sCount[b]<0&&(T=!0),!T){const _=e.parentType;e.parentType="reference";let L=!1;for(let M=0,N=l.length;M<N;M++)if(l[M](e,b,A,!0)){L=!0;break}if(e.parentType=_,L)return null}const S=e.bMarks[b]+e.tShift[b],x=e.eMarks[b];return e.src.slice(S,x+1)}let u=e.src.slice(o,s+1);s=u.length;let c=-1;for(o=1;o<s;o++){const b=u.charCodeAt(o);if(b===91)return!1;if(b===93){c=o;break}else if(b===10){const A=a(r);A!==null&&(u+=A,s=u.length,r++)}else if(b===92&&(o++,o<s&&u.charCodeAt(o)===10)){const A=a(r);A!==null&&(u+=A,s=u.length,r++)}}if(c<0||u.charCodeAt(c+1)!==58)return!1;for(o=c+2;o<s;o++){const b=u.charCodeAt(o);if(b===10){const A=a(r);A!==null&&(u+=A,s=u.length,r++)}else if(!Pm(b))break}const d=e.md.helpers.parseLinkDestination(u,o,s);if(!d.ok)return!1;const h=e.md.normalizeLink(d.str);if(!e.md.validateLink(h))return!1;o=d.pos;const p=o,g=r,m=o;for(;o<s;o++){const b=u.charCodeAt(o);if(b===10){const A=a(r);A!==null&&(u+=A,s=u.length,r++)}else if(!Pm(b))break}let k=e.md.helpers.parseLinkTitle(u,o,s);for(;k.can_continue;){const b=a(r);if(b===null)break;u+=b,o=s,s=u.length,r++,k=e.md.helpers.parseLinkTitle(u,o,s,k)}let w;for(o<s&&m!==o&&k.ok?(w=k.str,o=k.pos):(w="",o=p,r=g);o<s&&Pm(u.charCodeAt(o));)o++;if(o<s&&u.charCodeAt(o)!==10&&w)for(w="",o=p,r=g;o<s&&Pm(u.charCodeAt(o));)o++;if(o<s&&u.charCodeAt(o)!==10)return!1;const y=C9(u.slice(1,c));return y?(i||(typeof e.env.references>"u"&&(e.env.references={}),typeof e.env.references[y]>"u"&&(e.env.references[y]={title:w,href:h}),e.line=r),!0):!1}function R3(e){switch(e){case 9:case 32:return!0}return!1}const NAe=65536;function z3(e,t){const n=e.bMarks[t]+e.tShift[t],i=e.eMarks[t];return e.src.slice(n,i)}function FAe(e,t){if(e.lineFlags)return(e.lineFlags[t]&jp.Pipe)!==0;for(let n=e.bMarks[t]+e.tShift[t],i=e.eMarks[t];n<i;n++)if(e.src.charCodeAt(n)===124)return!0;return!1}function MM(e){const t=[],n=e.length;let i=0,o=e.charCodeAt(i),s=!1,r=0,l="";for(;i<n;)o===124&&(s?(l+=e.substring(r,i-1),r=i):(t.push(l+e.substring(r,i)),l="",r=i+1)),s=o===92,i++,o=e.charCodeAt(i);return t.push(l+e.substring(r)),t}function DAe(e,t,n,i){if(t+2>n)return!1;let o=t+1;if(e.sCount[o]<e.blkIndent||e.sCount[o]-e.blkIndent>=4)return!1;let s=e.bMarks[o]+e.tShift[o];if(s>=e.eMarks[o])return!1;const r=e.src.charCodeAt(s++);if(r!==124&&r!==45&&r!==58||s>=e.eMarks[o])return!1;const l=e.src.charCodeAt(s++);if(l!==124&&l!==45&&l!==58&&!R3(l)||r===45&&R3(l)||!FAe(e,t))return!1;for(;s<e.eMarks[o];){const A=e.src.charCodeAt(s);if(A!==124&&A!==45&&A!==58&&!R3(A))return!1;s++}let a=z3(e,t+1),u=a.split("|");const c=[];for(let A=0;A<u.length;A++){const T=u[A].trim();if(!T){if(A===0||A===u.length-1)continue;return!1}if(!/^:?-+:?$/.test(T))return!1;T.charCodeAt(T.length-1)===58?c.push(T.charCodeAt(0)===58?"center":"right"):T.charCodeAt(0)===58?c.push("left"):c.push("")}if(a=z3(e,t).trim(),e.sCount[t]-e.blkIndent>=4)return!1;u=MM(a),u.length&&u[0]===""&&u.shift(),u.length&&u[u.length-1]===""&&u.pop();const d=u.length;if(d===0||d!==c.length)return!1;if(i)return!0;const h=e.parentType;e.parentType="table";const p=e.md.block.ruler.getRulesForState(e,"blockquote"),g=e.push("table_open","table",1),m=[t,0];g.map=m;const k=e.push("thead_open","thead",1);k.map=[t,t+1];const w=e.push("tr_open","tr",1);w.map=[t,t+1];for(let A=0;A<u.length;A++){const T=e.push("th_open","th",1);c[A]&&(T.attrs=[["style",`text-align:${c[A]}`]]);const S=e.push("inline","",0);S.content=u[A].trim(),S.children=[],e.push("th_close","th",-1)}e.push("tr_close","tr",-1),e.push("thead_close","thead",-1);let y,b=0;for(o=t+2;o<n&&!(e.sCount[o]<e.blkIndent);o++){let A=!1;for(let S=0,x=p.length;S<x;S++)if(p[S](e,o,n,!0)){A=!0;break}if(A||(a=z3(e,o).trim(),!a)||e.sCount[o]-e.blkIndent>=4||(u=MM(a),u.length&&u[0]===""&&u.shift(),u.length&&u[u.length-1]===""&&u.pop(),b+=d-u.length,b>NAe))break;if(o===t+2){const S=e.push("tbody_open","tbody",1);S.map=y=[t+2,0]}const T=e.push("tr_open","tr",1);T.map=[o,o+1];for(let S=0;S<d;S++){const x=e.push("td_open","td",1);c[S]&&(x.attrs=[["style",`text-align:${c[S]}`]]);const _=e.push("inline","",0);_.content=u[S]?u[S].trim():"",_.children=[],e.push("td_close","td",-1)}e.push("tr_close","tr",-1)}return y&&(e.push("tbody_close","tbody",-1),y[1]=o),e.push("table_close","table",-1),m[1]=o,e.parentType=h,e.line=o,!0}var BAe=class{_rules=[];cache=null;namedCache=null;version=0;invalidateCache(){this.cache=null,this.namedCache=null,this.version++}push(e,t,n){this._rules.push({name:e,enabled:!0,fn:t,alt:n?.alt||[]}),this.invalidateCache()}before(e,t,n,i){const o=this._rules.findIndex(r=>r.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this._rules.findIndex(r=>r.name===t);s>=0&&this._rules.splice(s,1),this._rules.splice(o,0,{name:t,enabled:!0,fn:n,alt:i?.alt||[]}),this.invalidateCache()}after(e,t,n,i){const o=this._rules.findIndex(r=>r.name===e);if(o<0)throw new Error(`Parser rule not found: ${e}`);const s=this._rules.findIndex(r=>r.name===t);s>=0&&this._rules.splice(s,1),this._rules.splice(o+1,0,{name:t,enabled:!0,fn:n,alt:i?.alt||[]}),this.invalidateCache()}getRules(e){const t=e||"";return this.cache||this.compileCache(),this.cache[t]??[]}getNamedRules(e){const t=e||"";return this.namedCache||this.compileCache(),this.namedCache[t]??[]}getRulesForState(e,t){const n=e?.env;return n&&(Object.prototype.hasOwnProperty.call(n,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(n,"__mdtsProfileRules"))?this.getNamedRules(t).map(({name:i,fn:o})=>(s,r,l,a)=>{const u=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now(),c=o(s,r,l,a),d=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();return $h(s?.env,"block",i,d-u,c,!!a),c}):this.getRules(t)}at(e,t,n){const i=this._rules.findIndex(o=>o.name===e);if(i===-1)throw new Error(`Parser rule not found: ${e}`);this._rules[i].fn=t,n?.alt&&(this._rules[i].alt=n.alt),this.invalidateCache()}enable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;return n.forEach(s=>{const r=this._rules.findIndex(l=>l.name===s);if(r===-1){if(t)return;throw new Error(`Rules manager: invalid rule name ${s}`)}i.push(s),this._rules[r].enabled||(this._rules[r].enabled=!0,o=!0)}),o&&this.invalidateCache(),i}disable(e,t){const n=Array.isArray(e)?e:[e],i=[];let o=!1;return n.forEach(s=>{const r=this._rules.findIndex(l=>l.name===s);if(r===-1){if(t)return;throw new Error(`Rules manager: invalid rule name ${s}`)}i.push(s),this._rules[r].enabled&&(this._rules[r].enabled=!1,o=!0)}),o&&this.invalidateCache(),i}enableOnly(e){const t=new Set(e);let n=!1;for(const i of this._rules){const o=t.has(i.name);i.enabled!==o&&(i.enabled=o,n=!0)}n&&this.invalidateCache()}compileCache(){const e=new Set([""]);for(const i of this._rules)if(i.enabled)for(const o of i.alt)e.add(o);const t=Object.create(null),n=Object.create(null);for(const i of e){const o=[],s=[];for(const r of this._rules)r.enabled&&(i!==""&&!r.alt.includes(i)||(o.push(r.fn),s.push({name:r.name,fn:r.fn})));t[i]=o,n[i]=s}this.cache=t,this.namedCache=n}};const jm=[["table",DAe,["paragraph","reference"]],["code",vAe],["fence",yAe,["paragraph","reference","blockquote","list"]],["blockquote",mAe,["paragraph","reference","blockquote","list"]],["hr",AAe,["paragraph","reference","blockquote","list"]],["list",EAe,["paragraph","reference","blockquote"]],["reference",LAe],["html_block",CAe,["paragraph","reference","blockquote"]],["heading",kAe,["paragraph","reference","blockquote"]],["lheading",SAe],["paragraph",TAe]];var $Ae=class{ruler;cachedRulesVersion=-1;cachedRules=[];constructor(){this.ruler=new BAe;for(let e=0;e<jm.length;e++)this.ruler.push(jm[e][0],jm[e][1],{alt:(jm[e][2]||[]).slice()});this.ruler.__mdtsDefaultVersion=this.ruler.version}tokenize(e,t,n){const i=this.getRules(),o=i.length,s=e.md.options.maxNesting,r=e.bMarks,l=e.tShift,a=e.eMarks,u=e.sCount;let c=t,d=!1;if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){for(;c<n;){for(;c<n&&r[c]+l[c]>=a[c];)c++;if(e.line=c,c>=n||u[c]<e.blkIndent)break;if(e.level>=s){e.line=n;break}const p=e.line;let g=!1;for(let m=0;m<o;m++)if(g=i[m](e,c,n,!1),g){if(p>=e.line)throw new Error("block rule didn't increment state.line");break}if(!g)throw new Error("none of the block rules matched");e.tight=!d,r[e.line-1]+l[e.line-1]>=a[e.line-1]&&(d=!0),c=e.line,c<n&&r[c]+l[c]>=a[c]&&(d=!0,c++,e.line=c)}return}const h=this.ruler.getNamedRules("");for(;c<n;){for(;c<n&&r[c]+l[c]>=a[c];)c++;if(e.line=c,c>=n||u[c]<e.blkIndent)break;if(e.level>=s){e.line=n;break}const p=e.line;let g=!1;for(let m=0;m<o;m++){const k=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();g=h[m].fn(e,c,n,!1);const w=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();if($h(e.env,"block",h[m].name,w-k,g,!1),g){if(p>=e.line)throw new Error("block rule didn't increment state.line");break}}if(!g)throw new Error("none of the block rules matched");e.tight=!d,r[e.line-1]+l[e.line-1]>=a[e.line-1]&&(d=!0),c=e.line,c<n&&r[c]+l[c]>=a[c]&&(d=!0,c++,e.line=c)}}parse(e,t,n,i){if(!e||e.length===0)return;const o=new mz(e,t,n,i);this.tokenize(o,o.line,o.lineMax)}getRules(){return this.cachedRulesVersion!==this.ruler.version&&(this.cachedRules=this.ruler.getRules(""),this.cachedRulesVersion=this.ruler.version),this.cachedRules}},bz=class{src;env;tokens;inlineMode;md;constructor(e,t,n={}){this.src=typeof e=="string"?e||"":e,this.env=n,this.tokens=[],this.inlineMode=!1,this.md=t}};bz.prototype.Token=hs;const IM=[["normalize",eAe],["block",l7e],["inline",U7e],["linkify",Y7e],["replacements",lAe],["smartquotes",dAe],["text_join",fAe]],RAe={html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",maxNesting:100},zAe={parseLinkLabel:m7,parseLinkDestination:g7,parseLinkTitle:v7};function OAe(){return{...RAe}}function PAe(){return{...zAe}}var jAe=class{fallbackParser;lastState=null;block;inline;ruler;linkifyInstance=null;cachedCoreRulesVersion=-1;cachedCoreRules=[];cachedCoreNamedRulesVersion=-1;cachedCoreNamedRules=[];constructor(){this.block=new $Ae,this.inline=new q7e,this.ruler=new aAe;for(let e=0;e<IM.length;e++){const[t,n]=IM[e];this.ruler.push(t,n)}this.fallbackParser={block:this.block,inline:this.inline,core:this,options:OAe(),helpers:PAe(),normalizeLink:pz,normalizeLinkText:gz,validateLink:hz,linkify:null}}resolveParser(e){return e||(this.linkifyInstance||(this.linkifyInstance=new RR({fuzzyLink:!0})),this.fallbackParser.block!==this.block&&(this.fallbackParser.block=this.block),this.fallbackParser.inline!==this.inline&&(this.fallbackParser.inline=this.inline),this.fallbackParser.core=this,this.fallbackParser.linkify=this.linkifyInstance,this.fallbackParser)}createState(e,t={},n){return new bz(e,this.resolveParser(n),t)}getCoreRules(){return this.cachedCoreRulesVersion!==this.ruler.version&&(this.cachedCoreRules=this.ruler.getRules(""),this.cachedCoreRulesVersion=this.ruler.version),this.cachedCoreRules}getCoreNamedRules(){return this.cachedCoreNamedRulesVersion!==this.ruler.version&&(this.cachedCoreNamedRules=this.ruler.getNamedRules(""),this.cachedCoreNamedRulesVersion=this.ruler.version),this.cachedCoreNamedRules}process(e){if(!(e.env&&(Object.prototype.hasOwnProperty.call(e.env,"__mdtsRuleProfile")||Object.prototype.hasOwnProperty.call(e.env,"__mdtsProfileRules")))){const n=this.getCoreRules();for(let i=0;i<n.length;i++)n[i](e);return}const t=this.getCoreNamedRules();for(let n=0;n<t.length;n++){const i=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();t[n].fn(e);const o=typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now();$h(e.env,"core",t[n].name,o-i,!0,!1)}H7e(e.env)}parseSource(e,t={},n){if(typeof e!="string"&&r7e(e))return this.parse(jR(e),t,n);const i=this.createState(e,t,n);return this.process(i),this.lastState=i,i}parse(e,t={},n){if(typeof e!="string")throw new TypeError("Input data should be a String");return this.parseSource(e,t,n)}getTokens(){return this.lastState?this.lastState.tokens:[]}};const HAe=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/;function J2(e){return!HAe.test(e)}function Cp(e,t){const n=e.indexOf(` -`,t);return n===-1?e.length:n}function Mv(e,t,n){for(let i=t;i<n;i++){const o=e.charCodeAt(i);if(o!==32&&o!==9)return!1}return!0}function EM(e,t,n){return t+2<n&&e.charCodeAt(t)===96&&e.charCodeAt(t+1)===96&&e.charCodeAt(t+2)===96}function O3(e,t,n){return t+1<n&&e.charCodeAt(t)===45&&e.charCodeAt(t+1)===32}function WAe(e){if(e.length>3)return J2(e);for(let t=0;t<e.length;t++)switch(e.charCodeAt(t)){case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return!1}return!0}const qAe=["","h1","h2","h3","h4","h5","h6"],UAe=["","#","##","###","####","#####","######"],TM=0,P3=1,j3=2;function Dl(e,t,n,i){const o=new hs(e,t,n);return o.level=i,o.block=!0,o}function A7(e,t,n){const i=Dl("inline","",0,n);i.map=[t,t+1],i.content=e;const o=new hs("text","",0);return o.content=e,i.children=[o],i}function KAe(e,t,n,i,o){let s=0,r=n;for(;r<i&&t.charCodeAt(r)===35&&s<6;)r++,s++;if(s===0||r>=i||t.charCodeAt(r)!==32)return!1;let l=r+1;for(;l<i&&t.charCodeAt(l)===32;)l++;let a=i;for(;a>l&&t.charCodeAt(a-1)===32;)a--;let u=a;for(;u>l&&t.charCodeAt(u-1)===35;)u--;if(u>l&&t.charCodeAt(u-1)===32)for(a=u-1;a>l&&t.charCodeAt(a-1)===32;)a--;const c=t.slice(l,a);if(!J2(c))return!1;const d=qAe[s],h=UAe[s],p=Dl("heading_open",d,1,0);p.map=[o,o+1],p.markup=h,e.push(p),e.push(A7(c,o,1));const g=Dl("heading_close",d,-1,0);return g.markup=h,e.push(g),!0}function VAe(e,t,n){const i=Dl("paragraph_open","p",1,0);i.map=[n,n+1],e.push(i),e.push(A7(t,n,1)),e.push(Dl("paragraph_close","p",-1,0))}function ZAe(e,t,n){const i=e.charCodeAt(n-1);return i===32||i===9?e.slice(t,n).trim():e.slice(t,n)}function H3(e,t){for(;t<e.length&&e.charCodeAt(t)===10;)t++;return t}function GAe(e,t){const n=Dl("bullet_list_open","ul",1,0);return n.map=[t,t],n.markup="-",e.push(n),n}function QAe(e,t,n){const i=Dl("list_item_open","li",1,1);i.map=[n,n+1],i.markup="-",e.push(i);const o=Dl("paragraph_open","p",1,2);o.map=[n,n+1],o.hidden=!0,e.push(o),e.push(A7(t,n,3));const s=Dl("paragraph_close","p",-1,2);s.hidden=!0,e.push(s);const r=Dl("list_item_close","li",-1,1);return r.markup="-",e.push(r),i}function YAe(e){const t=Dl("bullet_list_close","ul",-1,0);t.markup="-",e.push(t)}function JAe(e,t,n,i){if(!EM(e,t,n))return null;const o=e.slice(t+3,n);if(o.includes("`"))return null;const s=n<e.length?n+1:n;let r=s,l=s,a=i+1;for(;l<e.length;){const u=Cp(e,l);if(EM(e,l,u)&&Mv(e,l+3,u)){const c=Dl("fence","code",0,0);return c.map=[i,a+1],c.markup="```",c.info=o,c.content=e.slice(s,r),{token:c,nextPos:u<e.length?u+1:u,nextLine:a+1}}l=u<e.length?u+1:u,r=l,a++}return null}function XAe(e,t){if(e.length===0)return t&&(t.matched=!0),[];if(e.includes("\r")||e.includes("\0"))return null;const n=[];let i=e.length>=1e5?TM:j3,o="",s=!1,r=!1,l=0,a=0;for(;l<e.length;){const u=Cp(e,l);if(l===u){l=u<e.length?u+1:u,a++;continue}const c=e.charCodeAt(l);if(c===32||c===9){if(!Mv(e,l,u))return null;l=u<e.length?u+1:u,a++;continue}if(c===35){if(!KAe(n,e,l,u,a))return null;t&&(t.blocks++,t.headings++);const g=u<e.length?u+1:u;l=H3(e,g),a+=1+l-g;continue}if(c===45){if(!O3(e,l,u))return null;const g=a;let m=l,k=a,w=null,y=null;for(;m<e.length;){const T=Cp(e,m);if(!O3(e,m,T))break;const S=m+2,x=T===S+1?e[S]:e.slice(S,T);if(!WAe(x))return null;w===null&&(w=GAe(n,g)),y=QAe(n,x,k),m=T<e.length?T+1:T,k++}if(w===null||y===null)return null;let b=m,A=k;for(;b<e.length;){if(e.charCodeAt(b)===10){b++,A++;continue}const T=Cp(e,b);if(!Mv(e,b,T)){if(O3(e,b,T))return null;break}b=T<e.length?T+1:T,A++}w.map[1]=A,y.map[1]=A,YAe(n),t&&(t.blocks++,t.lists++),l=b,a=A;continue}if(c===96){const g=JAe(e,l,u,a);if(!g)return null;n.push(g.token),t&&(t.blocks++,t.fences++),l=H3(e,g.nextPos),a=g.nextLine+l-g.nextPos;continue}const d=ZAe(e,l,u);let h;if(i===j3?(t&&t.paragraphCacheBypasses++,h=J2(d)):i===P3&&d===o?(t&&t.paragraphCacheHits++,h=s):(t&&t.paragraphCacheMisses++,h=J2(d),i===TM?(r&&(i=d===o?P3:j3),o=d,s=h,r=!0):i===P3&&(o=d,s=h)),!h)return null;const p=u<e.length?u+1:u;if(p<e.length&&e.charCodeAt(p)!==10&&!Mv(e,p,Cp(e,p)))return null;VAe(n,d,a),t&&(t.blocks++,t.paragraphs++),l=H3(e,p),a+=1+l-p}return t&&(t.matched=!0),n}const eCe=/[&<>"]/,LM=/[&<>"]/g,tCe=/&/g,nCe=/[<>"]/g,iCe={"&":"&","<":"<",">":">",'"':"""};function W3(e){return iCe[e]||e}function Ii(e){if(e.length===0)return"";if(e.length<32)return eCe.test(e)?e.replace(LM,W3):e;const t=e.includes("&"),n=e.includes("<"),i=e.includes(">"),o=e.includes('"');return!t&&!n&&!i&&!o?e:t&&!n&&!i&&!o?e.replace(tCe,"&"):t?e.replace(LM,W3):e.replace(nCe,W3)}const oCe=new RegExp(`${/\\([!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~])/g.source}|${/&([a-z#][a-z0-9]{1,31});/gi.source}`,"gi"),sCe=/^#(?:x[a-f0-9]{1,8}|\d{1,8})$/i;function Az(e){return!e.includes("\\")&&!e.includes("&")?e:e.replace(oCe,(t,n,i)=>{if(n)return n;if(sCe.test(i)){const s=i[1].toLowerCase()==="x"?Number.parseInt(i.slice(2),16):Number.parseInt(i.slice(1),10);return w9(s)?N0(s):"�"}const o=r7(t);return o!==t?o:t})}const rCe=/[\n!#$%&*+\-:<=>@[\]\\^_`{}~]/,lCe=/[\n!"#$%&*+\-:<=>@[\]\\^_`{}~]/,aCe=/"/g;function vh(e,t){const n=e.indexOf(` -`,t);return n===-1?e.length:n}function X2(e,t,n){for(let i=t;i<n;i++){const o=e.charCodeAt(i);if(o!==32&&o!==9)return!1}return!0}function Hm(e,t){for(;t<e.length&&e.charCodeAt(t)===10;)t++;return t}function uCe(e,t){return t>=e.length||e.charCodeAt(t)===10?!1:!X2(e,t,vh(e,t))}function NM(e,t,n){return t+2<n&&e.charCodeAt(t)===96&&e.charCodeAt(t+1)===96&&e.charCodeAt(t+2)===96}function cCe(e,t,n){const i=e.charCodeAt(n-1);return i===32||i===9?e.slice(t,n).trim():e.slice(t,n)}function C7(e){return lCe.test(e)?rCe.test(e)?null:e.replace(aCe,"""):e}function dCe(e,t,n){let i=0,o=t;for(;o<n&&e.charCodeAt(o)===35&&i<6;)o++,i++;if(i===0||o>=n||e.charCodeAt(o)!==32)return null;let s=o+1;for(;s<n&&e.charCodeAt(s)===32;)s++;let r=n;for(;r>s&&e.charCodeAt(r-1)===32;)r--;let l=r;for(;l>s&&e.charCodeAt(l-1)===35;)l--;if(l>s&&e.charCodeAt(l-1)===32)for(r=l-1;r>s&&e.charCodeAt(r-1)===32;)r--;const a=C7(e.slice(s,r));return a===null?null:`<h${i}>${a}</h${i}> -`}function FM(e,t,n){return t+1<n&&e.charCodeAt(t)===45&&e.charCodeAt(t+1)===32}function fCe(e,t){switch(e.charCodeAt(t)){case 34:return`<li>"</li> -`;case 10:case 33:case 35:case 36:case 37:case 38:case 42:case 43:case 45:case 58:case 60:case 61:case 62:case 64:case 91:case 92:case 93:case 94:case 95:case 96:case 123:case 125:case 126:return null}return`<li>${e[t]}</li> -`}function hCe(e,t,n){const i=t+2;if(n===i+1)return fCe(e,i);const o=C7(e.slice(t+2,n));return o===null?null:`<li>${o}</li> -`}function pCe(e,t,n){for(;t<n;){const o=e.charCodeAt(t);if(o!==32&&o!==9)break;t++}for(;n>t;){const o=e.charCodeAt(n-1);if(o!==32&&o!==9)break;n--}let i=n;for(let o=t;o<n;o++){const s=e.charCodeAt(o);if(s===96)return null;if(s===32||s===9){i=o;break}}return e.slice(t,i)}function gCe(e,t,n,i,o){if(!NM(e,t,n))return null;const s=pCe(e,t+3,n);if(s===null)return null;const r=n<e.length?n+1:n;let l=r,a=r;for(;a<e.length;){const u=vh(e,a);if(NM(e,a,u)&&X2(e,a+3,u)){const c=e.slice(r,l);let d;return s===i.lang?(o&&o.fenceCacheHits++,d=i.open):(o&&o.fenceCacheMisses++,d=s?`<pre><code class="language-${Ii(s)}">`:"<pre><code>",i.lang=s,i.open=d),{html:`${d}${Ii(c)}</code></pre> -`,nextPos:u<e.length?u+1:u}}a=u<e.length?u+1:u,l=a}return null}function Cz(e,t){if(e.length===0)return t&&(t.matched=!0),"";if(e.includes("\r")||e.includes("\0"))return null;let n=0,i="";const o=e.length>=25e4,s=[],r={lang:null,open:""};let l="",a="",u="",c="";for(;n<e.length;){const d=vh(e,n);if(n===d){n=d<e.length?d+1:d;continue}const h=e.charCodeAt(n);if(h===32||h===9){if(!X2(e,n,d))return null;n=d<e.length?d+1:d;continue}if(h===35){const k=dCe(e,n,d);if(k===null)return null;t&&(t.blocks++,t.headings++),o?s.push(k):i+=k,n=Hm(e,d<e.length?d+1:d);continue}if(h===45){let k=n;for(;k<e.length;){const A=vh(e,k);if(!FM(e,k,A))break;k=A<e.length?A+1:A}if(k===n)return null;const w=e.slice(n,k);let y;if(w===l)t&&t.listCacheHits++,y=a;else{t&&t.listCacheMisses++;let A=n;for(y=`<ul> -`;A<k;){const T=vh(e,A),S=hCe(e,A,T);if(S===null)return null;y+=S,A=T<e.length?T+1:T}y+=`</ul> -`,l=w,a=y}let b=Hm(e,k);for(;b<e.length;){if(e.charCodeAt(b)===10){b++;continue}const A=vh(e,b);if(!X2(e,b,A)){if(FM(e,b,A))return null;break}b=A<e.length?A+1:A}t&&(t.blocks++,t.lists++),o?s.push(y):i+=y,n=b;continue}if(h===96){const k=gCe(e,n,d,r,t);if(!k)return null;t&&(t.blocks++,t.fences++),o?s.push(k.html):i+=k.html,n=Hm(e,k.nextPos);continue}const p=cCe(e,n,d);let g;if(p===u)t&&t.paragraphCacheHits++,g=c;else{t&&t.paragraphCacheMisses++;const k=C7(p);if(k===null)return null;g=`<p>${k}</p> -`,u=p,c=g}const m=d<e.length?d+1:d;if(m<e.length&&e.charCodeAt(m)!==10&&uCe(e,m))return null;t&&(t.blocks++,t.paragraphs++),o?s.push(g):i+=g,n=Hm(e,m)}return t&&(t.matched=!0),o?s.join(""):i}function DM(e){return Cz(e)}function BM(e,t){return Cz(e,t)}const mCe={maxChunkChars:1e4,maxChunkLines:200,fenceAware:!0,maxChunks:void 0,fallbackOnGlobalState:!0};function ey(e,t,n={},i){gr(n);const o={...mCe,...i||{}},s=Pr(t);if(o.fallbackOnGlobalState!==!1&&s)return D3(n,{count:1,fallback:!0,fallbackReason:s,globalStateDetected:s,maxChunkChars:o.maxChunkChars,maxChunkLines:o.maxChunkLines}),Bh(n,s,()=>e.core.parse(t,n,e).tokens);let r=Iv(t,o);if(o.maxChunks&&r.length>o.maxChunks&&(r=bCe(r,o.maxChunks)),Ev(t,r))return D3(n,{count:1,fallback:!0,fallbackReason:"unsafe-chunk-boundary",maxChunkChars:o.maxChunkChars,maxChunkLines:o.maxChunkLines}),Bh(n,s,()=>e.core.parse(t,n,e).tokens);let l=0;const a=[];return D3(n,{count:r.length,maxChunkChars:o.maxChunkChars,maxChunkLines:o.maxChunkLines,globalStateDetected:s||void 0,globalStateFallbackDisabled:o.fallbackOnGlobalState===!1&&!!s}),Bh(n,s,()=>{for(let u=0;u<r.length;u++){const c=r[u],d=t.slice(c.start,c.end),h=e.core.parse(d,n,e).tokens;l!==0&&h.length&&yCe(h,l),kCe(a,h),l+=c.lineCount}return a})}function Iv(e,t,n=!0){const i=[];let o=0,s=0,r=0,l=0,a=0,u=0,c=null;function d(h){h<=r||(i.push({start:r,end:h,lineCount:l}),r=h,o=0,s=0,l=0)}for(let h=0;h<e.length;){let p=e.indexOf(` -`,h),g=p;p===-1?(p=e.length,g=e.length):g=p+1;const m=ACe(e,h,p);if(t.fenceAware){let y=h;for(;y<p;){const A=e.charCodeAt(y);if(A===32||A===9)y++;else break}const b=e[y];if(b==="`"||b==="~"){let A=y;for(;A<p&&e[A]===b;)A++;const T=A-y;T>=3&&(c?c.marker===b&&T>=c.length&&(c=null):c={marker:b,length:T})}}const k=g-h;o+=k,s+=1,l+=1,m?(a=0,u=0):(a+=1,u+=k);const w=m;if((o>=t.maxChunkChars||s>=t.maxChunkLines)&&!c)if(w)d(g);else{const y=Math.max(10,Math.floor(t.maxChunkLines*.5)),b=Math.max(t.maxChunkChars,8e3);(a>=y||u>=b)&&d(g)}h=g}return n&&d(e.length),i}function Ev(e,t,n={rangesCoverWholeSource:!0}){const i=n.rangesCoverWholeSource?t.length-1:t.length;for(let o=0;o<i;o++)if(!vCe(e,t[o].end))return!0;return!1}function vCe(e,t){if(t<=0||t>e.length||e.charCodeAt(t-1)!==10)return!1;let n=t-2;for(;n>=0&&e.charCodeAt(n)!==10;)n--;for(let i=n+1;i<t-1;i++){const o=e.charCodeAt(i);if(o!==32&&o!==9&&o!==13)return!1}return!0}function yCe(e,t){if(t===0)return;const n=[];for(let i=e.length-1;i>=0;i--)n.push(e[i]);for(;n.length;){const i=n.pop();if(i.map&&(i.map[0]+=t,i.map[1]+=t),i.children)for(let o=i.children.length-1;o>=0;o--)n.push(i.children[o])}}function kCe(e,t){for(let n=0;n<t.length;n++)e.push(t[n])}function bCe(e,t){if(e.length<=t)return e;const n=[];let i=0;for(let o=0;o<t;o++){const s=t-o,r=e.length-i,l=Math.ceil(r/s),a=e.slice(i,i+l);let u=0;for(let c=0;c<a.length;c++)u+=a[c].lineCount;n.push({start:a[0].start,end:a[a.length-1].end,lineCount:u}),i+=l}return n}function ACe(e,t,n){for(let i=t;i<n;i++){const o=e.charCodeAt(i);if(o!==32&&o!==9&&o!==13)return!1}return!0}const wz=4e6,xz=8e4,CCe=1e4,wCe=200,xCe=1e4,SCe=200;function Sz(e,t){for(let n=0;n<t.length;n++)e.push(t[n])}function _Ce(e,t){if(t===0)return;const n=[];for(let i=e.length-1;i>=0;i--)n.push(e[i]);for(;n.length;){const i=n.pop();if(i.map&&(i.map[0]+=t,i.map[1]+=t),i.children)for(let o=i.children.length-1;o>=0;o--)n.push(i.children[o])}}function Uu(e){return e.length===0?0:To(e)+(e.charCodeAt(e.length-1)===10?0:1)}function MCe(e,t,n){for(let i=t;i<n;i++){const o=e.charCodeAt(i);if(o!==32&&o!==9&&o!==13)return!1}return!0}function ICe(e,t){if(!t||e.length===0)return!1;let n=null;for(let i=0;i<e.length;){let o=e.indexOf(` -`,i);o===-1&&(o=e.length);let s=i;for(;s<o;){const l=e.charCodeAt(s);if(l===32||l===9)s++;else break}const r=e[s];if(r==="`"||r==="~"){let l=s;for(;l<o&&e[l]===r;)l++;const a=l-s;a>=3&&(n?n.marker===r&&a>=n.length&&(n=null):n={marker:r,length:a})}i=o===e.length?e.length:o+1}return n!==null}function ECe(e,t){if(e.length===0||e.charCodeAt(e.length-1)!==10)return!1;let n=e.length-2;for(;n>=0&&e.charCodeAt(n)!==10;)n--;return MCe(e,n+1,e.length-1)?!ICe(e,t):!1}function TCe(e,t,n,i={}){const o=i.mode??"full",s=i.fenceAware??(o==="stream"?e.options.streamChunkFenceAware??!0:e.options.fullChunkFenceAware??!0);if(i.maxChunkChars!==void 0||i.maxChunkLines!==void 0||i.autoTune===!1){const r=i.maxChunkChars??(o==="stream"?e.options.streamChunkSizeChars??xCe:e.options.fullChunkSizeChars??CCe),l=i.maxChunkLines??(o==="stream"?e.options.streamChunkSizeLines??SCe:e.options.fullChunkSizeLines??wCe);return{maxChunkChars:r,maxChunkLines:l,holdBelowChars:r,holdBelowLines:l,fenceAware:s}}return o==="stream"?t<=5e3?{maxChunkChars:16e3,maxChunkLines:250,holdBelowChars:16e3,holdBelowLines:250,fenceAware:s}:t<=2e4?{maxChunkChars:16e3,maxChunkLines:200,holdBelowChars:16e3,holdBelowLines:200,fenceAware:s}:t<=5e4?{maxChunkChars:16e3,maxChunkLines:250,holdBelowChars:16e3,holdBelowLines:250,fenceAware:s}:t<=5e5?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:32e3,holdBelowLines:350,fenceAware:s}:{maxChunkChars:64e3,maxChunkLines:700,holdBelowChars:64e3,holdBelowLines:700,fenceAware:s}:t<=1e5&&n<=2500?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:1e5,holdBelowLines:2500,fenceAware:s}:t<=2e5?{maxChunkChars:2e4,maxChunkLines:150,holdBelowChars:2e4,holdBelowLines:150,fenceAware:s}:t<=5e5?{maxChunkChars:32e3,maxChunkLines:350,holdBelowChars:32e3,holdBelowLines:350,fenceAware:s}:{maxChunkChars:64e3,maxChunkLines:700,holdBelowChars:64e3,holdBelowLines:700,fenceAware:s}}var mg=class{md;options;pending="";tokens=[];committedChars=0;committedLines=0;fedChunks=0;parsedChunks=0;globalStateEnv=null;markedGlobalStateReason=null;constructor(e,t={}){if(this.md=e,this.options={mode:"full",autoTune:!0,retainTokens:!0,...t},this.options.retainTokens===!1&&!this.options.onChunkTokens)throw new Error("UnboundedBuffer with retainTokens=false requires onChunkTokens")}feed(e){e&&(this.pending+=e,this.fedChunks+=1)}flushAvailable(e={}){if(!this.pending)return null;const t=this.resolveWindow(),n=Uu(this.pending);if(this.pending.length<t.holdBelowChars&&n<t.holdBelowLines)return this.updateEnvDiagnostics(e,t,n),null;const i=Iv(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!1);if(!i.length)return this.updateEnvDiagnostics(e,t,n),null;if(Ev(this.pending,i,{rangesCoverWholeSource:!1}))return this.updateEnvDiagnostics(e,t,n),null;const o=this.commitRanges(i,e);return this.pending=this.pending.slice(o),this.updateEnvDiagnostics(e,t,Uu(this.pending)),this.tokens}flushIfBoundary(e={}){if(!this.pending)return null;const t=this.resolveWindow();if(!ECe(this.pending,t.fenceAware))return this.updateEnvDiagnostics(e,t,Uu(this.pending)),null;const n=Iv(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!0);if(!n.length)return this.updateEnvDiagnostics(e,t,Uu(this.pending)),null;const i=Ev(this.pending,n,{rangesCoverWholeSource:!0})?[{start:0,end:this.pending.length,lineCount:Uu(this.pending)}]:n;return this.commitRanges(i,e),this.pending="",this.updateEnvDiagnostics(e,t,0),this.tokens}flushForce(e={}){if(!this.pending){this.prepareGlobalStateEnv(e,"");const i=this.resolveWindow();return this.updateEnvDiagnostics(e,i,0),this.tokens}const t=this.resolveWindow(),n=Iv(this.pending,{maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,fenceAware:t.fenceAware},!0);if(n.length){const i=Ev(this.pending,n,{rangesCoverWholeSource:!0})?[{start:0,end:this.pending.length,lineCount:Uu(this.pending)}]:n;this.commitRanges(i,e),this.pending=""}return this.updateEnvDiagnostics(e,t,0),this.tokens}reset(){this.pending="",this.tokens=[],this.committedChars=0,this.committedLines=0,this.fedChunks=0,this.parsedChunks=0,this.globalStateEnv=null,this.markedGlobalStateReason=null}peek(){return this.tokens}pendingText(){return this.pending}stats(){return{mode:this.options.mode??"full",fedChunks:this.fedChunks,parsedChunks:this.parsedChunks,committedChars:this.committedChars,committedLines:this.committedLines,pendingChars:this.pending.length,pendingLines:Uu(this.pending),retainedTokens:this.options.retainTokens!==!1}}resolveWindow(){const e=this.committedChars+this.pending.length,t=this.committedLines+Uu(this.pending);return TCe(this.md,e,t,this.options)}prepareGlobalStateEnv(e,t){if(this.globalStateEnv!==e&&(pg(e)&&Mu(e),this.globalStateEnv=e,this.markedGlobalStateReason=null),this.markedGlobalStateReason)return;const n=Pr(t);n&&(h7(e,n),this.markedGlobalStateReason=n)}commitRanges(e,t){if(!e.length)return 0;this.prepareGlobalStateEnv(t,this.pending);let n=0;try{for(let i=0;i<e.length;i++){const o=e[i],s=this.pending.slice(o.start,o.end),r=this.md.core.parse(s,t,this.md).tokens,l=this.committedChars,a=this.committedLines;a!==0&&r.length&&_Ce(r,a),this.options.retainTokens!==!1&&Sz(this.tokens,r),this.committedChars+=s.length,this.committedLines+=o.lineCount,this.parsedChunks+=1,this.options.onChunkTokens&&this.options.onChunkTokens(r,{chunkIndex:this.parsedChunks,chunkChars:s.length,chunkLines:o.lineCount,tokenCount:r.length,startOffset:l,endOffset:this.committedChars,startLine:a,endLine:this.committedLines}),n=o.end}return this.markedGlobalStateReason&&p7(t),n}catch(i){throw this.markedGlobalStateReason&&(Mu(t),this.globalStateEnv=null,this.markedGlobalStateReason=null),i}}updateEnvDiagnostics(e,t,n){$R(e,{mode:this.options.mode??"full",maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,committedChars:this.committedChars,committedLines:this.committedLines,pendingChars:this.pending.length,pendingLines:n,fedChunks:this.fedChunks,parsedChunks:this.parsedChunks,globalStateDetected:this.markedGlobalStateReason||void 0})}};function LCe(e,t,n={},i={}){gr(n);const o=new mg(e,{mode:"full",...i});for(const s of t)o.feed(s),o.flushAvailable(n);return o.flushForce(n)}async function NCe(e,t,n={},i={}){gr(n);const o=new mg(e,{mode:"full",...i});for await(const s of t)o.feed(s),o.flushAvailable(n);return o.flushForce(n)}function FCe(e,t,n,i={},o={}){gr(i);const s=new mg(e,{mode:"full",...o,retainTokens:!1,onChunkTokens:n});for(const r of t)s.feed(r),s.flushAvailable(i);return s.flushForce(i),s.stats()}async function DCe(e,t,n,i={},o={}){gr(i);const s=new mg(e,{mode:"full",...o,retainTokens:!1,onChunkTokens:n});for await(const r of t)s.feed(r),s.flushAvailable(i);return s.flushForce(i),s.stats()}function _z(e,t,n){if(e.options.autoUnbounded===!1)return!1;const i=e.options.autoUnboundedThresholdChars??wz,o=e.options.autoUnboundedThresholdLines??xz;return t>=i||n>=o}function Mz(e,t,n){if(e.options.autoUnbounded===!1)return"no";if(t>=(e.options.autoUnboundedThresholdChars??wz))return"yes";const i=e.options.autoUnboundedThresholdLines??xz;return n!==void 0?n>=i?"yes":"no":t+1<i?"no":"need-lines"}function Hp(e,t,n={},i={}){gr(n);const o=Pr(t);if(pg(n)&&Mu(n),i.fallbackOnGlobalState!==!1&&o)return $R(n,{mode:"full",fallback:!0,fallbackReason:o,committedChars:t.length,committedLines:To(t),pendingChars:0,pendingLines:0,fedChunks:1,parsedChunks:1,globalStateDetected:o}),Bh(n,o,()=>e.core.parse(t,n,e).tokens);const s=[],r=new mg(e,{mode:"full",...i,retainTokens:!1,onChunkTokens(l){Sz(s,l)}});if(o&&h7(n,o),r.feed(t),r.flushForce(n),o&&(p7(n),i.fallbackOnGlobalState===!1)){const l=lu(n)?.unbounded;l&&(l.globalStateDetected=o,l.globalStateFallbackDisabled=!0)}return s}const Rh=(e,t,n)=>e<t?t:e>n?n:e;function Iz(e){return e.experimental?{...e,...e.experimental}:e}const $M=[{max:5e3,strategy:"discrete",maxChunkChars:32e3,maxChunkLines:150,maxChunks:8,notes:"<=5k"},{max:2e4,strategy:"discrete",maxChunkChars:24e3,maxChunkLines:200,maxChunks:12,notes:"<=20k"},{max:1e5,strategy:"plain",notes:"<=100k plain"},{max:2e5,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:150,maxChunks:12,notes:"<=200k"},{max:5e5,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:16,notes:"<=500k"},{max:5e6,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:16,notes:"<=5M"}],RM=[{max:5e3,strategy:"discrete",maxChunkChars:16e3,maxChunkLines:250,maxChunks:8,notes:"<=5k"},{max:2e4,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:200,maxChunks:24,notes:"<=20k"},{max:1e5,strategy:"discrete",maxChunkChars:2e4,maxChunkLines:200,maxChunks:24,notes:"<=100k"},{max:5e5,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:32,notes:"<=500k"},{max:5e6,strategy:"discrete",maxChunkChars:64e3,maxChunkLines:700,maxChunks:32,notes:"<=5M"}];function Ez(e,t){return{strategy:t.strategy,maxChunkChars:t.maxChunkChars,maxChunkLines:t.maxChunkLines,maxChunks:t.maxChunks,fenceAware:e,notes:t.notes}}function BCe(e,t=Math.max(0,e/40|0),n={}){const i=Iz(n),o=i.fullChunkFenceAware??!0,s=i.fullChunkTargetChunks??8,r=i.fullChunkAdaptive!==!1;for(let l=0;l<$M.length;l++){const a=$M[l];if(e<=a.max){if(a.strategy!=="adaptive")return Ez(o,a);break}}return e>5e6?{strategy:"plain",fenceAware:o,notes:">5M plain"}:r?{strategy:"adaptive",maxChunkChars:Rh(Math.ceil(e/s),8e3,64e3),maxChunkLines:Rh(Math.ceil(t/s),150,700),maxChunks:Rh(Math.ceil(e/64e3),s,16),fenceAware:o,notes:"adaptive fallback"}:{strategy:"discrete",maxChunkChars:i.fullChunkSizeChars??1e4,maxChunkLines:i.fullChunkSizeLines??200,fenceAware:o,maxChunks:i.fullChunkMaxChunks}}function zM(e,t=Math.max(0,e/40|0),n={}){const i=Iz(n),o=i.streamChunkFenceAware??!0,s=i.streamChunkTargetChunks??8,r=i.streamChunkAdaptive!==!1;for(let l=0;l<RM.length;l++){const a=RM[l];if(e<=a.max){if(a.strategy!=="adaptive")return Ez(o,a);break}}return e>5e6?{strategy:"plain",fenceAware:o,notes:">5M plain"}:r?{strategy:"adaptive",maxChunkChars:Rh(Math.ceil(e/s),8e3,64e3),maxChunkLines:Rh(Math.ceil(t/s),150,700),maxChunks:Rh(Math.ceil(e/64e3),s,32),fenceAware:o,notes:"adaptive fallback"}:{strategy:"discrete",maxChunkChars:i.streamChunkSizeChars??1e4,maxChunkLines:i.streamChunkSizeLines??200,maxChunks:i.streamChunkMaxChunks,fenceAware:o}}var $Ce={options:{html:!0,xhtmlOut:!0,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["blockquote","code","fence","heading","hr","html_block","lheading","list","reference","paragraph"]},inline:{rules:["autolink","backticks","emphasis","entity","escape","html_inline","image","link","newline","text"]},inline2:{rules:["balance_pairs","emphasis","fragments_join"]}}},RCe={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:100},components:{core:{},block:{},inline:{}}},zCe={options:{html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",maxNesting:20},components:{core:{rules:["normalize","block","inline","text_join"]},block:{rules:["paragraph"]},inline:{rules:["text"]},inline2:{rules:["balance_pairs","fragments_join"]}}};function S9(e){return!!e&&(typeof e=="object"||typeof e=="function")&&typeof e.then=="function"}function Tv(e,t){if(S9(e))throw new TypeError(`Renderer rule "${t}" returned a Promise. Use renderAsync() instead.`);return e}const OM=e=>S9(e)?e:Promise.resolve(e);function Wp(e){switch(e){case"alt":case"class":case"href":case"id":case"lang":case"rel":case"src":case"start":case"style":case"target":case"title":return e;default:return Ii(e)}}function Ec(e){if(!e||e.length===0)return"";const t=e[0];let n=` ${Wp(t[0])}="${Ii(t[1])}"`;for(let i=1;i<e.length;i++){const o=e[i];n+=` ${Wp(o[0])}="${Ii(o[1])}"`}return n}function Tz(e){if(!e)return{langName:"",langAttrs:""};let t=0;for(;t<e.length;){const i=e.charCodeAt(t);if(i===32||i===9||i===10)break;t++}if(t>=e.length)return{langName:e,langAttrs:""};let n=t;for(;n<e.length;){const i=e.charCodeAt(n);if(i!==32&&i!==9&&i!==10)break;n++}return{langName:e.slice(0,t),langAttrs:n<e.length?e.slice(n):""}}function qp(e,t,n,i,o){if(t.indexOf("<pre")===0)return`${t} -`;if(n){if(!e.attrs||e.attrs.length===0)return`<pre><code class="${Ii(`${o.langPrefix??"language-"}${i}`)}">${t}</code></pre> -`;const s=e.attrIndex("class"),r=e.attrs?e.attrs.slice():[],l=`${o.langPrefix??"language-"}${i}`;return s<0?r.push(["class",l]):(r[s]=r[s].slice(),r[s][1]+=` ${l}`),`<pre><code${Ec(r)}>${t}</code></pre> -`}return`<pre><code${Ec(e.attrs)}>${t}</code></pre> -`}function D0(e){return!e.attrs||e.attrs.length===0?`<code>${Ii(e.content)}</code>`:`<code${Ec(e.attrs)}>${Ii(e.content)}</code>`}function F8(e){const t=Ii(e.content);return e.attrs?`<pre${Ec(e.attrs)}><code>${t}</code></pre> -`:`<pre><code>${t}</code></pre> -`}function OCe(e,t){const n=e.attrs;if(!n||n.length===0)switch(e.type){case"paragraph_open":return`${t}<p>`;case"heading_open":return`<${e.tag}>`;case"td_open":return`${t}<td>`;case"th_open":return`${t}<th>`;default:return null}if(n.length===1&&n[0][0]==="style"){if(e.type==="td_open")return`${t}<td style="${Ii(n[0][1])}">`;if(e.type==="th_open")return`${t}<th style="${Ii(n[0][1])}">`}return null}function PM(e){const t=e.attrs;return!t||t.length===0?"<a>":t.length===1?`<a ${Wp(t[0][0])}="${Ii(t[0][1])}">`:t.length===2?`<a ${Wp(t[0][0])}="${Ii(t[0][1])}" ${Wp(t[1][0])}="${Ii(t[1][1])}">`:`<a${Ec(t)}>`}function PCe(e){switch(e.type){case"text":case"text_special":case"softbreak":case"hardbreak":case"html_inline":case"code_inline":case"image":return!0;default:return!1}}function jM(e){switch(e.type){case"text":case"text_special":case"softbreak":case"hardbreak":case"html_inline":case"code_inline":return!0;default:return!1}}function ty(e,t){if(e.hidden)return"";const n=e.attrs,i=e.nesting,o=e.tag;if(!n||n.length===0)return i===0?t?`<${o} />`:`<${o}>`:i===-1?`</${o}>`:`<${o}>`;let s=(i===-1?"</":"<")+o+Ec(n);return i===0&&t&&(s+=" /"),`${s}>`}const jCe={langPrefix:"language-",xhtmlOut:!1,breaks:!1},Wm=Object.prototype.hasOwnProperty,ci={code_inline(e,t){return D0(e[t])},code_block(e,t){return F8(e[t])},fence(e,t,n,i,o){const s=e[t],r=s.info?Az(s.info).trim():"",{langName:l,langAttrs:a}=Tz(r),u=n.highlight,c=Ii(s.content);if(!u)return qp(s,c,r,l,n);const d=u(s.content,l,a);return S9(d)?d.then(h=>qp(s,h||c,r,l,n)):qp(s,d||c,r,l,n)},image(e,t,n,i,o){const s=e[t],r=o.renderInlineAsText(s.children||[],n,i),l=s.attrIndex("alt");return l>=0&&s.attrs?s.attrs[l][1]=r:s.attrs?s.attrs.push(["alt",r]):s.attrs=[["alt",r]],ty(s,n.xhtmlOut===!0)},hardbreak(e,t,n){return n.xhtmlOut?`<br /> -`:`<br> -`},softbreak(e,t,n){return n.breaks?n.xhtmlOut?`<br /> -`:`<br> -`:` -`},text(e,t){return Ii(e[t].content)},text_special(e,t){return Ii(e[t].content)},html_block(e,t){return e[t].content},html_inline(e,t){return e[t].content}};function HM(e,t,n){const i=e.info?Az(e.info).trim():"",{langName:o,langAttrs:s}=Tz(i),r=t.highlight,l=Ii(e.content);if(!r)return qp(e,l,i,o,t);const a=r(e.content,o,s);if(S9(a))throw new TypeError('Renderer rule "fence" returned a Promise. Use renderAsync() instead.');return qp(e,a||l,i,o,t)}function q3(e,t,n,i){switch(e.type){case"text":return t.text===ci.text?e.content.length===0?"":Ii(e.content):null;case"text_special":return t.text_special===ci.text_special?e.content.length===0?"":Ii(e.content):null;case"softbreak":return t.softbreak===ci.softbreak?i:null;case"hardbreak":return t.hardbreak===ci.hardbreak?n:null;case"html_inline":return t.html_inline===ci.html_inline?e.content:null;case"code_inline":return t.code_inline===ci.code_inline?D0(e):null;default:return null}}function HCe(e,t,n,i,o){const s=e[0];switch(s.type){case"text":if(o.text===ci.text)return s.content.length===0?"":Ii(s.content);break;case"text_special":if(o.text_special===ci.text_special)return s.content.length===0?"":Ii(s.content);break;case"softbreak":if(o.softbreak===ci.softbreak)return t.breaks?t.xhtmlOut?`<br /> -`:`<br> -`:` -`;break;case"hardbreak":if(o.hardbreak===ci.hardbreak)return t.xhtmlOut?`<br /> -`:`<br> -`;break;case"html_inline":if(o.html_inline===ci.html_inline)return s.content;break;case"code_inline":if(o.code_inline===ci.code_inline)return D0(s);break}const r=o[s.type];if(!r)return ty(s,t.xhtmlOut===!0);const l=r(e,0,t,n,i);return typeof l=="string"?l:Tv(l,s.type)}var WCe=class{rules;baseOptions;normalizedBase;constructor(e={}){this.baseOptions={...e},this.normalizedBase=this.buildNormalizedBase(),this.rules={...ci}}set(e){return this.baseOptions={...this.baseOptions,...e},this.normalizedBase=this.buildNormalizedBase(),this}render(e,t,n){if(!Array.isArray(e))throw new TypeError("render expects token array as first argument");if(e.length===1)return this.renderSingleToken(e,e[0],t,n);const i=this.mergeOptions(t),o=n??{},s=this.rules,r=i.xhtmlOut===!0;let l,a,u,c,d,h,p="",g="",m=!1,k="";for(let w=0;w<e.length;w++){const y=e[w],b=y.type,A=w>0&&e[w-1].hidden?` -`:"";if(b==="list_item_open"&&(!y.attrs||y.attrs.length===0)&&w+3<e.length){const x=e[w+1],_=e[w+2],L=e[w+3];if(x.type==="paragraph_open"&&x.hidden&&_.type==="inline"&&L.type==="paragraph_close"&&L.hidden){k+=`${A}<li>${this.renderInlineTokens(_.children||[],i,o)}`,w+=3;continue}}if(w+2<e.length){const x=e[w+1],_=e[w+2];if(x.type==="inline"&&_.nesting===-1&&_.tag===y.tag&&!_.hidden){const L=OCe(y,A);if(L!==null){k+=`${L+this.renderInlineTokens(x.children||[],i,o)}</${y.tag}> -`,w+=2;continue}}}if(b==="inline"){const x=y.children||[];if(x.length===1){m||(l=s.text,a=s.text_special,u=s.softbreak,c=s.hardbreak,d=s.html_inline,h=s.code_inline,p=i.xhtmlOut?`<br /> -`:`<br> -`,g=i.breaks?p:` -`,m=!0);const _=x[0];switch(_.type){case"text":if(l===ci.text){k+=Ii(_.content);continue}break;case"text_special":if(a===ci.text_special){k+=Ii(_.content);continue}break;case"softbreak":if(u===ci.softbreak){k+=g;continue}break;case"hardbreak":if(c===ci.hardbreak){k+=p;continue}break;case"html_inline":if(d===ci.html_inline){k+=_.content;continue}break;case"code_inline":if(h===ci.code_inline){k+=D0(_);continue}break}}k+=this.renderInlineTokens(x,i,o);continue}const T=s[b];if(!T){const x=y.attrs;if(!y.hidden){if(!x||x.length===0)switch(b){case"hr":k+=r?`<hr /> -`:`<hr> -`;continue;case"heading_open":k+=`<${y.tag}>`;continue;case"heading_close":k+=`</${y.tag}> -`;continue;case"paragraph_open":k+=`${A}<p>`;continue;case"paragraph_close":k+=`</p> -`;continue;case"list_item_open":{const _=e[w+1];k+=A+(_&&(_.type==="inline"||_.hidden||_.nesting===-1&&_.tag==="li")?"<li>":`<li> -`);continue}case"list_item_close":k+=`</li> -`;continue;case"bullet_list_open":k+=`${A}<ul> -`;continue;case"bullet_list_close":k+=`</ul> -`;continue;case"blockquote_open":k+=A+(e[w+1]&&e[w+1].nesting===-1&&e[w+1].tag==="blockquote"?"<blockquote>":`<blockquote> -`);continue;case"blockquote_close":k+=`</blockquote> -`;continue;case"ordered_list_open":k+=`${A}<ol> -`;continue;case"ordered_list_close":k+=`</ol> -`;continue;case"table_open":k+=`${A}<table> -`;continue;case"table_close":k+=`</table> -`;continue;case"thead_open":k+=`${A}<thead> -`;continue;case"thead_close":k+=`</thead> -`;continue;case"tbody_open":k+=`${A}<tbody> -`;continue;case"tbody_close":k+=`</tbody> -`;continue;case"tr_open":k+=`${A}<tr> -`;continue;case"tr_close":k+=`</tr> -`;continue;case"td_open":k+=`${A}<td>`;continue;case"td_close":k+=`</td> -`;continue;case"th_open":k+=`${A}<th>`;continue;case"th_close":k+=`</th> -`;continue}else if(x.length===1){const _=x[0];if(b==="ordered_list_open"&&_[0]==="start"){k+=`${A}<ol start="${Ii(_[1])}"> -`;continue}if(b==="td_open"&&_[0]==="style"){k+=`${A}<td style="${Ii(_[1])}">`;continue}if(b==="th_open"&&_[0]==="style"){k+=`${A}<th style="${Ii(_[1])}">`;continue}}}k+=this.renderToken(e,w,i);continue}if(b==="code_block"&&T===ci.code_block){k+=F8(y);continue}if(b==="fence"&&T===ci.fence){k+=HM(y,i);continue}if(b==="html_block"&&T===ci.html_block){k+=y.content;continue}const S=T(e,w,i,o,this);typeof S=="string"?k+=S:k+=Tv(S,y.type)}return k}async renderAsync(e,t,n){if(!Array.isArray(e))throw new TypeError("render expects token array as first argument");const i=this.mergeOptions(t),o=n??{},s=this.rules;let r="";for(let l=0;l<e.length;l++){const a=e[l];if(a.type==="inline"){r+=await this.renderInlineTokensAsync(a.children||[],i,o);continue}const u=s[a.type];u?r+=await OM(u(e,l,i,o,this)):r+=this.renderToken(e,l,i)}return r}renderInline(e,t,n){const i=this.mergeOptions(t),o=n??{};return this.renderInlineTokens(e,i,o)}async renderInlineAsync(e,t,n){const i=this.mergeOptions(t),o=n??{};return this.renderInlineTokensAsync(e,i,o)}renderInlineAsText(e,t,n){const i=this.mergeOptions(t),o=n??{};return this.renderInlineAsTextInternal(e,i,o)}renderAttrs(e){return Ec(e.attrs)}renderToken(e,t,n){const i=e[t];if(i.hidden)return"";const o=i.block,s=i.nesting,r=i.tag,l=i.attrs;let a=!1;if(o&&(a=!0,s===1&&t+1<e.length)){const h=e[t+1];(h.type==="inline"||h.hidden||h.nesting===-1&&h.tag===r)&&(a=!1)}const u=o&&s!==-1&&t>0&&e[t-1].hidden?` -`:"",c=a?`> -`:">";if(!l||l.length===0)return s===0?n.xhtmlOut?`${u}<${r} /${c}`:`${u}<${r}${c}`:s===-1?`${u}</${r}${c}`:`${u}<${r}${c}`;let d=u+(s===-1?"</":"<")+r+Ec(l);return s===0&&n.xhtmlOut&&(d+=" /"),d+c}mergeOptions(e){const t=this.normalizedBase;if(!e||e.highlight===t.highlight&&e.langPrefix===t.langPrefix&&e.xhtmlOut===t.xhtmlOut&&e.breaks===t.breaks)return t;let n=null;const i=()=>(n||(n={...t}),n);if(Wm.call(e,"highlight")&&e.highlight!==t.highlight&&(i().highlight=e.highlight),Wm.call(e,"langPrefix")){const o=e.langPrefix;o!==t.langPrefix&&(i().langPrefix=o)}if(Wm.call(e,"xhtmlOut")){const o=e.xhtmlOut;o!==t.xhtmlOut&&(i().xhtmlOut=o)}if(Wm.call(e,"breaks")){const o=e.breaks;o!==t.breaks&&(i().breaks=o)}return n||t}buildNormalizedBase(){return Object.freeze({...jCe,...this.baseOptions})}renderSingleToken(e,t,n,i){const o=this.rules,s=t.type;if(s==="code_block"&&o.code_block===ci.code_block)return F8(t);if(s==="html_block"&&o.html_block===ci.html_block)return t.content;const r=this.mergeOptions(n),l=i??{};if(s==="inline")return this.renderInlineTokens(t.children||[],r,l);const a=o[s];if(!a)return t.block?this.renderToken(e,0,r):ty(t,r.xhtmlOut===!0);if(s==="fence"&&a===ci.fence)return HM(t,r);const u=a(e,0,r,l,this);return typeof u=="string"?u:Tv(u,s)}renderInlineTokens(e,t,n){if(!e||e.length===0)return"";const i=this.rules;if(e.length===1)return HCe(e,t,n,this,i);const o=t.xhtmlOut===!0,s=o?`<br /> -`:`<br> -`,r=t.breaks?s:` -`,l=i.text,a=i.text_special,u=i.softbreak,c=i.hardbreak,d=i.html_inline,h=i.code_inline,p=i.link_open,g=i.link_close,m=i.em_open,k=i.em_close,w=i.strong_open,y=i.strong_close;let b="";for(let A=0;A<e.length;A++){const T=e[A];if(T.type==="link_open"&&!p&&!g&&A+2<e.length){const _=e[A+1];if(e[A+2].type==="link_close"&&PCe(_)){const L=q3(_,i,s,r);if(L!==null){const M=`${PM(T)+L}</a>`;if(u===ci.softbreak&&A+3<e.length&&e[A+3].type==="softbreak"){b+=M+r,A+=3;continue}b+=M,A+=2;continue}}}if(T.type==="link_open"&&!p&&!g&&A+1<e.length&&e[A+1].type==="link_close"){b+=`${PM(T)}</a>`,A+=1;continue}if(T.type==="em_open"&&!m&&!k&&A+2<e.length){const _=e[A+1];if(e[A+2].type==="em_close"&&jM(_)){const L=q3(_,i,s,r);if(L!==null){b+=`<em>${L}</em>`,A+=2;continue}}}if(T.type==="strong_open"&&!w&&!y&&A+2<e.length){const _=e[A+1];if(e[A+2].type==="strong_close"&&jM(_)){const L=q3(_,i,s,r);if(L!==null){b+=`<strong>${L}</strong>`,A+=2;continue}}}switch(T.type){case"text":if(l===ci.text){const _=T.content.length===0?"":Ii(T.content);if(d===ci.html_inline&&A+1<e.length&&e[A+1].type==="html_inline"){for(b+=_+e[++A].content;A+1<e.length&&e[A+1].type==="html_inline";)b+=e[++A].content;continue}b+=_;continue}break;case"text_special":if(a===ci.text_special){T.content.length!==0&&(b+=Ii(T.content));continue}break;case"softbreak":if(u===ci.softbreak){b+=r;continue}break;case"hardbreak":if(c===ci.hardbreak){b+=s;continue}break;case"html_inline":if(d===ci.html_inline){for(b+=T.content;A+1<e.length&&e[A+1].type==="html_inline";)b+=e[++A].content;continue}break;case"code_inline":if(h===ci.code_inline){b+=D0(T);continue}break}const S=i[T.type];if(!S){b+=T.block?this.renderToken(e,A,t):ty(T,o);continue}const x=S(e,A,t,n,this);typeof x=="string"?b+=x:b+=Tv(x,T.type)}return b}async renderInlineTokensAsync(e,t,n){if(!e||e.length===0)return"";const i=this.rules;let o="";for(let s=0;s<e.length;s++){const r=i[e[s].type];r?o+=await OM(r(e,s,t,n,this)):o+=this.renderToken(e,s,t)}return o}renderInlineAsTextInternal(e,t,n){if(!e||e.length===0)return"";let i="";for(let o=0;o<e.length;o++){const s=e[o];switch(s.type){case"text":case"text_special":i+=s.content;break;case"image":i+=this.renderInlineAsTextInternal(s.children||[],t,n);break;case"html_inline":case"html_block":i+=s.content;break;case"softbreak":case"hardbreak":i+=` -`;break}}return i}},qCe=WCe;const UCe=[],U3=4096;function KCe(e){const t=e.length;let n=0;for(;n<=t;){let i=e.indexOf(` -`,n);i===-1&&(i=t);const o=i<t;let s=n,r=0;for(;s<i;){const l=e.charCodeAt(s);if(l===32){if(r++,s++,r>=4)return!0;continue}if(l===9){if(r+=4-r%4,s++,r>=4)return!0;continue}break}if(s<i){const l=e.charCodeAt(s);switch(l){case 35:{let a=s;for(;a<i&&e.charCodeAt(a)===35;)a++;const u=a-s;if(u>0&&u<=6){if(a<i){const c=e.charCodeAt(a);if(c===32||c===9||c===13)return!0}else if(a===i&&o)return!0}break}case 62:{const a=s+1;if(a<i){const u=e.charCodeAt(a);if(u===32||u===9||u===13)return!0}else if(a===i&&o)return!0;break}case 45:case 42:case 43:{const a=s+1;if(a<i){const u=e.charCodeAt(a);if(u===32||u===9||u===13)return!0}else if(a===i&&o)return!0;break}case 96:case 126:{let a=s;for(;a<i&&e.charCodeAt(a)===l;)a++;if(a-s>=3)return!0;break}default:if(l>=48&&l<=57){let a=s+1;for(;a<i;){const u=e.charCodeAt(a);if(u<48||u>57)break;a++}if(a<i&&e.charCodeAt(a)===46){const u=a+1;if(u<i){const c=e.charCodeAt(u);if(c===32||c===9||c===13)return!0}else if(u===i&&o)return!0}}break}}if(i===t)break;n=i+1}return!1}function VCe(e,t){if(!e&&!t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n][0]!==t[n][0]||e[n][1]!==t[n][1])return!1;return!0}function ZCe(e,t){if(!e&&!t)return!0;if(!e||!t||e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(!Lz(e[n],t[n]))return!1;return!0}function Lz(e,t){if(!e||!t||e.type!==t.type)return!1;const n=e.map,i=t.map;return!!n!=!!i||n&&i&&(n[0]!==i[0]||n[1]!==i[1])||e.tag!==t.tag||e.nesting!==t.nesting||e.markup!==t.markup||e.info!==t.info||e.block!==t.block||e.hidden!==t.hidden||!VCe(e.attrs,t.attrs)||!ZCe(e.children,t.children)?!1:(e.content||"")===(t.content||"")}function WM(){return{total:0,cacheHits:0,appendHits:0,unboundedAppendHits:0,tailHits:0,fullParses:0,resets:0,chunkedParses:0,lastMode:"idle"}}var GCe=class{core;cache=null;stats=WM();MIN_SIZE_FOR_OPTIMIZATION=1e3;DEFAULT_SKIP_CACHE_CHARS=1e6;DEFAULT_SKIP_CACHE_LINES=1e5;IMPLICIT_STREAM_CHUNK_MIN_CHARS=16e4;MIN_LIST_LINES_FOR_MERGE=80;MIN_LIST_CHARS_FOR_MERGE=800;MIN_TABLE_LINES_FOR_MERGE=48;MIN_TABLE_CHARS_FOR_MERGE=1200;MIN_UNBOUNDED_APPEND_TOTAL_CHARS=5e5;MIN_UNBOUNDED_APPEND_CHARS=64e3;MIN_UNBOUNDED_APPEND_LINES=700;constructor(e){this.core=e}reset(){this.cache=null,this.stats.resets+=1,this.stats.lastMode="reset"}resetStats(){const{resets:e}=this.stats;this.stats=WM(),this.stats.resets=e}parse(e,t,n){const i=t,o=this.cache;if(gr(i??o?.env),!o||i&&i!==o.env){const z=i??{},H=!!n.__explicitStreamChunkFallbackSetting,O=typeof n.__canUseImplicitLargeInputStrategy=="function"?n.__canUseImplicitLargeInputStrategy():!0,R=!!n.options?.streamChunkedFallback,j=!H&&O,$=R||j,W=n.options?.streamChunkAdaptive!==!1,P=n.options?.streamChunkTargetChunks??8,Z=n.options?.streamChunkSizeChars,ae=n.options?.streamChunkSizeLines,V=n.options?.streamChunkMaxChunks,Y=!!n.__explicitStreamChunkConfig,oe=n.options?.autoTuneChunks!==!1,q=n.options?.streamChunkFenceAware??!0,ne=n.options?.streamLargeCachePolicy??"retain",ie=n.options?.streamSkipCacheAboveChars??this.DEFAULT_SKIP_CACHE_CHARS,pe=n.options?.streamSkipCacheAboveLines??this.DEFAULT_SKIP_CACHE_LINES;let Ne,te=!1;if(ne==="skip"&&(te=e.length>=ie,!te&&pe!==void 0&&(Ne=To(e),te=Ne>=pe)),te){const Q=this.parseFullDocument(e,z,n,Ne,!1);return this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",Go(z,{area:"stream",path:"stream-full",reason:"skip-cache-large-one-shot",unbounded:!!lu(z)?.unbounded}),Q.tokens}else if($){const Q=(ge,ke,Ie)=>ge<ke?ke:ge>Ie?Ie:ge;Ne===void 0&&(Ne=To(e));const ue=oe&&!Y?zM(e.length,Ne,n.options):null,Ae=ue?.maxChunkChars??(W?Q(Math.ceil(e.length/P),8e3,64e3):Z??1e4),se=ue?.maxChunkLines??(W?Q(Math.ceil(Ne/P),150,700):ae??200),re=ue?.maxChunks??(W?Q(Math.ceil(e.length/64e3),P,32):V),G=e.length>0&&e.charCodeAt(e.length-1)===10,le=j&&e.length>=this.IMPLICIT_STREAM_CHUNK_MIN_CHARS&&ue?.strategy!=="plain";if((R||le)&&(e.length>=Ae*2||Ne>=se*2)&&G){const ge=ey(n,e,z,{maxChunkChars:Ae,maxChunkLines:se,fenceAware:ue?.fenceAware??q,maxChunks:re});return this.cache={src:e,tokens:ge,env:z,lineCount:Ne,lastSegment:void 0,globalStateReason:Pr(e)},this.updateCacheLineCount(this.cache,Ne),this.recordChunkedParseResult(z,R?"explicit-initial-large-doc":"default-initial-large-doc"),ge}}const be=this.parseFullDocument(e,z,n,Ne);return Ne=be.lineCount,this.cache={src:e,tokens:be.tokens,env:z,lineCount:Ne,lastSegment:void 0,globalStateReason:Pr(e)},this.updateCacheLineCount(this.cache,Ne),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",Go(z,{area:"stream",path:"stream-full",reason:"initial-parse",unbounded:!!lu(z)?.unbounded}),be.tokens}if(e===o.src)return this.stats.total+=1,this.stats.cacheHits+=1,this.stats.lastMode="cache",Go(o.env,{area:"stream",path:"stream-cache",reason:"same-source"}),o.tokens;const s=e.startsWith(o.src)?e.slice(o.src.length):null;let r=o.globalStateReason;r===void 0&&(r=Pr(o.src),o.globalStateReason=r);const l=r?null:s!==null?this.detectGlobalStateForAppend(o,s):Pr(e),a=r||l;if(a){const z=i??o.env;Mu(z);const H=Pr(e),O=this.parseFullDocument(e,z,n),R=O.tokens,j=O.lineCount;return this.cache={src:e,tokens:R,env:z,lineCount:j,lastSegment:void 0,globalStateReason:H},this.updateCacheLineCount(this.cache,j),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",Go(z,{area:"stream",path:"stream-full",reason:`global-state:${a}`,unbounded:!!lu(z)?.unbounded}),R}const u=n.options?.streamOptimizationMinSize??this.MIN_SIZE_FOR_OPTIMIZATION;if(o.src.length<u&&e.length<u*1.5&&!e.startsWith(o.src)){const z=i??o.env,H=this.parseFullDocument(e,z,n),O=H.tokens,R=H.lineCount;return this.cache={src:e,tokens:O,env:z,lineCount:R,lastSegment:void 0,globalStateReason:Pr(e)},this.updateCacheLineCount(this.cache,R),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",Go(z,{area:"stream",path:"stream-full",reason:"small-non-append",unbounded:!!lu(z)?.unbounded}),O}const c=this.getAppendedSegment(o.src,e,s);if(c&&!this.shouldPreferTailReparseForAppend(o)){const z=o.lineCount??To(o.src);let H=3;c.length>5e3?H=8:c.length>1e3?H=6:c.length>200&&(H=4),H=Math.min(H,z);let O=null;const R=n.options?.streamContextParseStrategy??"chars",j=n.options?.streamContextParseMinChars??200,$=n.options?.streamContextParseMinLines??2;let W;const P=()=>(W===void 0&&(W=To(c)),W),Z=this.canDirectlyParseAppend(o),ae=Z&&this.shouldUseUnboundedAppend(e,o,c);let V=!1;if(!Z)switch(R){case"lines":V=P()>=$;break;case"constructs":if(c.length>=j){V=!0;break}if(KCe(c)){V=!0;break}V=P()>=$;break;case"chars":default:V=c.length>=j}if(H>0&&V){const q=this.getTailLines(o.src,H)+c;try{const ne=this.core.parse(q,o.env,n).tokens,ie=ne.findIndex(pe=>pe.map&&typeof pe.map[1]=="number"&&pe.map[1]>H);if(ie!==-1){const pe=ne.slice(ie),Ne=z-H;Ne!==0&&this.shiftTokenLines(pe,Ne),O={tokens:pe}}}catch{O=null}}else O=null;if(!O){const q=z;if(ae)O={tokens:Hp(n,c,o.env,{mode:"stream"})},q>0&&this.shiftTokenLines(O.tokens,q);else{const ne=this.core.parse(c,o.env,n);q>0&&this.shiftTokenLines(ne.tokens,q),O=ne}}let Y=0;if(o.tokens.length>0&&O.tokens.length>0){const q=o.tokens[o.tokens.length-1],ne=O.tokens[0];try{q.type==="inline"&&ne.type==="inline"&&(ne.children&&ne.children.length>0&&(q.children||(q.children=[]),this.appendTokens(q.children,ne.children)),q.content=(q.content||"")+(ne.content||""),Y=1)}catch{Y=0}}const oe=o.tokens.length;if(O.tokens.length>Y){const q=o.tokens,ne=O.tokens,ie=Math.min(q.length,ne.length-Y);let pe=0;for(let Ne=ie;Ne>0;Ne--){let te=!0;for(let be=0;be<Ne;be++){const Q=q[q.length-Ne+be],ue=ne[Y+be];if(!Lz(Q,ue)){te=!1;break}}if(te){pe=Ne;break}}pe>0&&(Y+=pe),ne.length>Y&&this.appendTokens(o.tokens,ne,Y)}if(o.src=e,o.globalStateReason=null,o.lineCount=z+(W??P()),o.tokens.length>oe){const q=this.getLastSegment(o.tokens,e,oe,o.tokens.length,e.length-c.length,z);q?o.lastSegment=q:o.lastSegment=void 0}else o.lastSegment=void 0;return this.stats.total+=1,this.stats.appendHits+=1,ae&&(this.stats.unboundedAppendHits=(this.stats.unboundedAppendHits||0)+1),this.stats.lastMode="append",Go(o.env,{area:"stream",path:ae?"stream-unbounded-append":"stream-append",reason:ae?"large-delta":"safe-append",unbounded:ae}),o.tokens}const d=i??o.env,h=this.tryTailSegmentReparse(e,o,d,n);if(h)return this.stats.total+=1,this.stats.tailHits+=1,this.stats.lastMode="tail",Go(d,{area:"stream",path:"stream-tail",reason:"tail-reparse"}),h;const p=!!n.__explicitStreamChunkFallbackSetting,g=typeof n.__canUseImplicitLargeInputStrategy=="function"?n.__canUseImplicitLargeInputStrategy():!0,m=!!n.options?.streamChunkedFallback,k=!p&&!c&&g,w=m||k,y=n.options?.streamChunkAdaptive!==!1,b=n.options?.streamChunkTargetChunks??8,A=n.options?.streamChunkSizeChars,T=n.options?.streamChunkSizeLines,S=n.options?.streamChunkMaxChunks,x=!!n.__explicitStreamChunkConfig,_=n.options?.autoTuneChunks!==!1,L=n.options?.streamChunkFenceAware??!0;let M=c&&o.lineCount!==void 0?o.lineCount+To(c):void 0;if(w){M===void 0&&(M=To(e));const z=(P,Z,ae)=>P<Z?Z:P>ae?ae:P,H=_&&!x?zM(e.length,M,n.options):null,O=H?.maxChunkChars??(y?z(Math.ceil(e.length/b),8e3,64e3):A??1e4),R=H?.maxChunkLines??(y?z(Math.ceil(M/b),150,700):T??200),j=H?.maxChunks??(y?z(Math.ceil(e.length/64e3),b,32):S),$=e.length>0&&e.charCodeAt(e.length-1)===10,W=k&&e.length>=this.IMPLICIT_STREAM_CHUNK_MIN_CHARS&&H?.strategy!=="plain";if((m||W)&&(e.length>=O*2||M>=R*2)&&$){const P=ey(n,e,d,{maxChunkChars:O,maxChunkLines:R,fenceAware:H?.fenceAware??L,maxChunks:j});return this.cache={src:e,tokens:P,env:d,lineCount:M,lastSegment:void 0,globalStateReason:Pr(e)},this.updateCacheLineCount(this.cache,M),this.recordChunkedParseResult(d,m?"explicit-fallback-large-doc":"default-fallback-large-doc"),P}}const N=this.parseFullDocument(e,d,n,M),I=N.tokens;return M=N.lineCount,this.cache={src:e,tokens:I,env:d,lineCount:M,lastSegment:void 0,globalStateReason:Pr(e)},this.updateCacheLineCount(this.cache,M),this.stats.total+=1,this.stats.fullParses+=1,this.stats.lastMode="full",Go(d,{area:"stream",path:"stream-full",reason:"fallback-full",unbounded:!!lu(d)?.unbounded}),I}recordChunkedParseResult(e,t){const n=lu(e)?.chunk,i=n?.fallback?String(n.fallbackReason||"global-state"):null;if(this.stats.total+=1,i){this.stats.fullParses+=1,this.stats.lastMode="full",Go(e,{area:"stream",path:"stream-full",reason:`global-state:${i}`,unbounded:!!lu(e)?.unbounded});return}this.stats.chunkedParses=(this.stats.chunkedParses||0)+1,this.stats.lastMode="chunked",Go(e,{area:"stream",path:"stream-chunked",chunked:!0,reason:t})}parseFullDocument(e,t,n,i,o=!0){const s=Pr(e);pg(t)&&Mu(t);const r=typeof n.__canUseImplicitLargeInputStrategy!="function"||n.__canUseImplicitLargeInputStrategy()?Mz(n,e.length,i):"no";if(r==="yes"){const a=Hp(n,e,t);return Go(t,{area:"stream",path:"stream-full",reason:"auto-unbounded-char-threshold",unbounded:!0}),{tokens:a,lineCount:i??(o?To(e):0)}}let l=i;if(r==="need-lines"&&(l=To(e),_z(n,e.length,l))){const a=Hp(n,e,t);return Go(t,{area:"stream",path:"stream-full",reason:"auto-unbounded-line-threshold",unbounded:!0}),{tokens:a,lineCount:l}}return l===void 0&&(l=o?To(e):0),{tokens:Bh(t,s,()=>this.core.parse(e,t,n).tokens),lineCount:l}}shouldUseUnboundedAppend(e,t,n){return!n||e.length<this.MIN_UNBOUNDED_APPEND_TOTAL_CHARS&&n.length<this.MIN_UNBOUNDED_APPEND_CHARS?!1:n.length>=this.MIN_UNBOUNDED_APPEND_CHARS?!0:To(n)>=this.MIN_UNBOUNDED_APPEND_LINES}getAppendedSegment(e,t,n){if(n===null||n===void 0&&!t.startsWith(e)||!e.endsWith(` -`))return null;const i=n??t.slice(e.length);if(!i)return null;const o=i.length;if(i.charCodeAt(o-1)!==10)return null;let s=0,r=-1;for(let a=0;a<o&&!(i.charCodeAt(a)===10&&(r===-1&&(r=a),s++,s>=2));a++);if(s<2)return null;const l=(r===-1?i:i.slice(0,r)).trim();if(l.length===0)return null;if(/^[-=]+$/.test(l)){const a=e.slice(0,-1),u=a.lastIndexOf(` -`);if(a.slice(u+1).trim().length>0)return null}return this.endsInsideOpenFence(e)||this.mayContainReferenceDefinition(i)?null:i}tryTailSegmentReparse(e,t,n,i){const o=this.ensureLastSegment(t);if(!o||o.srcOffset<=0&&o.tokenStart<=0)return null;const s=t.src.slice(0,o.srcOffset);if(!e.startsWith(s))return null;const r=t.src.slice(o.srcOffset),l=e.slice(o.srcOffset);if(l===r)return null;const a=e.startsWith(t.src)?e.slice(t.src.length):null;if(a){const u=this.tryContainerTailAppendMerge(e,t,n,i,o,a);if(u)return u}if(this.mayContainReferenceDefinition(r)||this.mayContainReferenceDefinition(l))return null;try{const u=this.core.parse(l,n,i),c=this.getLastSegment(u.tokens,l);return o.lineStart>0&&this.shiftTokenLines(u.tokens,o.lineStart),t.src=e,t.env=n,t.globalStateReason=null,t.globalStateCarry=void 0,t.tokens.length=o.tokenStart,this.appendTokens(t.tokens,u.tokens),t.lineCount=o.lineStart+To(l),c?t.lastSegment={tokenStart:o.tokenStart+c.tokenStart,tokenEnd:o.tokenStart+c.tokenEnd,lineStart:o.lineStart+c.lineStart,lineEnd:o.lineStart+c.lineEnd,srcOffset:o.srcOffset+c.srcOffset}:t.lastSegment=null,t.tokens}catch{return null}}getTailLines(e,t){if(t<=0)return"";let n=t;for(let i=e.length-1;i>=0;i--)if(e.charCodeAt(i)===10&&(n--,n===0))return e.slice(i+1);return e}endsInsideOpenFence(e){const n=e.length>4e3?e.length-4e3:0,i=e.slice(n),o=i.length;let s=null,r=0;for(;r<=o;){let l=i.indexOf(` -`,r);l===-1&&(l=o);let a=r;for(;a<l;){const u=i.charCodeAt(a);if(u===32||u===9)a++;else break}if(a<l){const u=i.charCodeAt(a);if(u===96||u===126){let c=a;for(;c<l&&i.charCodeAt(c)===u;)c++;const d=c-a;d>=3&&(s?s.marker===u&&d>=s.length&&(s=null):s={marker:u,length:d})}}if(l===o)break;r=l+1}return s!==null}peek(){return this.cache?.tokens??UCe}getStats(){return{...this.stats}}appendTokens(e,t,n=0,i=t.length){for(let o=n;o<i;o++)e.push(t[o])}updateCacheLineCount(e,t){e.lineCount=t??To(e.src),e.lastSegment=void 0,e.globalStateCarry=void 0}detectGlobalStateForAppend(e,t){if(e.globalStateReason)return e.globalStateReason;const n=(e.globalStateCarry??e.src.slice(-U3))+t,i=Pr(n);return e.globalStateCarry=n.length>U3?n.slice(n.length-U3):n,i&&(e.globalStateReason=i),i}ensureLastSegment(e){return e.lastSegment!==void 0||(e.lastSegment=this.getLastSegment(e.tokens,e.src)),e.lastSegment}getLastSegment(e,t,n=0,i=e.length,o,s){if(i<=n)return null;let r=Number.POSITIVE_INFINITY,l=-1,a=0;for(let u=i-1;u>=n;u--){const c=e[u];if(c.map&&(c.map[0]<r&&(r=c.map[0]),c.map[1]>l&&(l=c.map[1])),c.nesting<0){a+=-c.nesting;continue}if(c.nesting>0){if(a-=c.nesting,c.level===0&&a<=0){const d=Number.isFinite(r)?r:c.map?.[0]??0,h=l>=d?l:c.map?.[1]??d;return{tokenStart:u,tokenEnd:i,lineStart:d,lineEnd:h,srcOffset:this.getLineStartOffset(t,d,o,s)}}continue}if(c.level===0&&a===0){const d=Number.isFinite(r)?r:c.map?.[0]??0,h=l>=d?l:c.map?.[1]??d;return{tokenStart:u,tokenEnd:i,lineStart:d,lineEnd:h,srcOffset:this.getLineStartOffset(t,d,o,s)}}}return null}getLineStartOffset(e,t,n,i){if(n!==void 0&&i!==void 0&&t>=i)return this.getLineStartOffsetFrom(e,n,t-i);if(t<=0)return 0;let o=t,s=-1;for(;o>0;){if(s=e.indexOf(` -`,s+1),s===-1)return e.length;o--}return s+1}getLineStartOffsetFrom(e,t,n){if(n<=0)return t;let i=n,o=t-1;for(;i>0;){if(o=e.indexOf(` -`,o+1),o===-1)return e.length;i--}return o+1}mayContainReferenceDefinition(e){return e.includes("]:")?/(?:^|\n)[ \t]{0,3}\[[^\]\n]+\]:/.test(e):!1}canDirectlyParseAppend(e){if(!this.endsWithBlankLine(e.src))return!1;const t=this.ensureLastSegment(e);if(!t)return!1;switch(e.tokens[t.tokenStart]?.type){case"paragraph_open":case"heading_open":case"fence":case"code_block":case"html_block":case"hr":case"table_open":return!0;default:return!1}}tryContainerTailAppendMerge(e,t,n,i,o,s){if(!s||this.mayContainReferenceDefinition(s))return null;const r=t.tokens[o.tokenStart];switch(r?.type){case"bullet_list_open":case"ordered_list_open":return this.tryListTailAppendMerge(e,t,n,i,o,s,r);case"table_open":return this.tryTableTailAppendMerge(e,t,n,i,o,s,r);default:return null}}tryListTailAppendMerge(e,t,n,i,o,s,r){if(t.src.length===0||t.src.charCodeAt(t.src.length-1)!==10)return null;const l=o.lineEnd-o.lineStart,a=t.src.length-o.srcOffset;if(l<this.MIN_LIST_LINES_FOR_MERGE&&a<this.MIN_LIST_CHARS_FOR_MERGE)return null;const u=r.type==="bullet_list_open"?"bullet_list_close":"ordered_list_close";let c;try{c=this.core.parse(s,n,i).tokens}catch{return null}if(!this.isSingleTopLevelContainer(c,r.type,u,r.markup))return null;const d=c.slice(1,-1);if(d.length===0)return null;const h=t.lineCount??To(t.src);h>0&&this.shiftTokenLines(d,h);const p=this.getListParagraphMode(t.tokens,o.tokenStart,t.tokens.length,r.level),g=this.getListParagraphMode(c,0,c.length,0);(p==="loose"||g==="loose"||this.endsWithBlankLine(t.src)||(c[0]?.map?.[0]??0)>0)&&(this.setListParagraphVisibility(t.tokens,o.tokenStart,t.tokens.length,r.level,!1),this.setListParagraphVisibility(d,0,d.length,r.level,!1)),t.tokens.splice(t.tokens.length-1,0,...d),t.src=e,t.env=n,t.globalStateReason=null;const m=h+To(s);t.lineCount=m;const k=this.getDocLineCount(e,m);return r.map&&(r.map[1]=k),t.lastSegment={tokenStart:o.tokenStart,tokenEnd:t.tokens.length,lineStart:o.lineStart,lineEnd:k,srcOffset:o.srcOffset},t.tokens}tryTableTailAppendMerge(e,t,n,i,o,s,r){if(t.src.length===0||t.src.charCodeAt(t.src.length-1)!==10||/(?:^|\n)[ \t]*\n/.test(s))return null;const l=o.lineEnd-o.lineStart,a=t.src.length-o.srcOffset;if(l<this.MIN_TABLE_LINES_FOR_MERGE&&a<this.MIN_TABLE_CHARS_FOR_MERGE)return null;const u=this.getTableHeaderContext(t.src.slice(o.srcOffset));if(!u)return null;const c=`${u}${s}`;let d;try{d=this.core.parse(c,n,i).tokens}catch{return null}if(!this.isSingleTopLevelContainer(d,"table_open","table_close")||(d[0]?.map?.[1]??-1)!==this.getDocLineCount(c))return null;const h=this.getTableBodySection(d,0,d.length,0),p=this.getTableBodySection(t.tokens,o.tokenStart,t.tokens.length,r.level);if(!h||!p||h.tbodyOpenIndex<0||h.tbodyCloseIndex<0)return null;const g=p.tbodyOpenIndex>=0?d.slice(h.tbodyOpenIndex+1,h.tbodyCloseIndex):d.slice(h.tbodyOpenIndex,h.tbodyCloseIndex+1);if(g.length===0)return null;const m=o.lineEnd-2;m!==0&&this.shiftTokenLines(g,m);const k=p.tbodyCloseIndex>=0?p.tbodyCloseIndex:p.tableCloseIndex,w=t.lineCount??To(t.src);t.tokens.splice(k,0,...g),t.src=e,t.env=n,t.globalStateReason=null;const y=w+To(s);t.lineCount=y;const b=this.getDocLineCount(e,y);if(r.map&&(r.map[1]=b),p.tbodyOpenIndex>=0){const A=t.tokens[p.tbodyOpenIndex];A?.map&&(A.map[1]=b)}return t.lastSegment={tokenStart:o.tokenStart,tokenEnd:t.tokens.length,lineStart:o.lineStart,lineEnd:b,srcOffset:o.srcOffset},t.tokens}getTableHeaderContext(e){const t=e.indexOf(` -`);if(t<0)return null;const n=e.indexOf(` -`,t+1);return n<0?null:e.slice(0,n+1)}getTableBodySection(e,t,n,i){if(t<0||t>=n||e[t]?.type!=="table_open")return null;let o=-1;for(let l=n-1;l>t;l--){const a=e[l];if(a.type==="table_close"&&a.level===i){o=l;break}}if(o<0)return null;let s=-1,r=-1;for(let l=t+1;l<o;l++){const a=e[l];if(a.type==="tbody_open"&&a.level===i+1){s=l;break}}if(s>=0){for(let l=o-1;l>s;l--){const a=e[l];if(a.type==="tbody_close"&&a.level===i+1){r=l;break}}if(r<0)return null}return{tableCloseIndex:o,tbodyOpenIndex:s,tbodyCloseIndex:r}}isSingleTopLevelContainer(e,t,n,i){if(e.length<2)return!1;const o=e[0],s=e[e.length-1];if(o.type!==t||s.type!==n||o.level!==0||s.level!==0||i!==void 0&&o.markup!==i)return!1;let r=0;for(let l=0;l<e.length;l++){const a=e[l];if(a.level===0&&l>0&&l<e.length-1&&r===0)return!1;(a.nesting>0||a.nesting<0)&&(r+=a.nesting)}return r===0}getListParagraphMode(e,t,n,i){let o=!1,s=!1;const r=i+2;for(let l=t;l<n;l++){const a=e[l];if(!(a.type!=="paragraph_open"||a.level!==r)&&(a.hidden?o=!0:s=!0,o&&s))return"loose"}return s?"loose":o?"tight":"none"}setListParagraphVisibility(e,t,n,i,o){const s=i+2;for(let r=t;r<n;r++){const l=e[r];(l.type==="paragraph_open"||l.type==="paragraph_close")&&l.level===s&&(l.hidden=o)}}shouldPreferTailReparseForAppend(e){const t=this.ensureLastSegment(e);if(!t)return!1;switch(e.tokens[t.tokenStart]?.type){case"bullet_list_open":case"ordered_list_open":case"blockquote_open":case"table_open":return!0;case"paragraph_open":case"code_block":case"html_block":return!this.endsWithBlankLine(e.src);default:return!1}}endsWithBlankLine(e){const t=e.length;if(t<2||e.charCodeAt(t-1)!==10)return!1;let n=t-2;for(;n>=0;){const i=e.charCodeAt(n);if(i===32||i===9){n--;continue}return i===10}return!0}getDocLineCount(e,t=To(e)){return e.length===0?0:e.charCodeAt(e.length-1)===10?t:t+1}shiftTokenLines(e,t){if(t===0)return;let n=null;for(let i=0;i<e.length;i++){const o=e[i];if(o.map&&(o.map[0]+=t,o.map[1]+=t),o.children){n??=[];for(let s=o.children.length-1;s>=0;s--)n.push(o.children[s]);for(;n.length>0;){const s=n.pop();if(s.map&&(s.map[0]+=t,s.map[1]+=t),s.children)for(let r=s.children.length-1;r>=0;r--)n.push(s.children[r])}}}}};const qM={default:RCe,zero:zCe,commonmark:$Ce};function QCe(e){return{core:e.core.ruler.version,block:e.block.ruler.version,inline:e.inline.ruler.version,inline2:e.inline.ruler2.version}}function YCe(e,t){return e.core.ruler.version!==t.core||e.block.ruler.version!==t.block||e.inline.ruler.version!==t.inline||e.inline.ruler2.version!==t.inline2}function UM(e){return e.experimental?{...e,...e.experimental}:e}function Ml(e,t){if(!e)return!1;if(Object.prototype.hasOwnProperty.call(e,t)&&e[t]!==void 0)return!0;const n=e.experimental;return!!n&&Object.prototype.hasOwnProperty.call(n,t)&&n[t]!==void 0}function KM(e,t,n){for(let i=0;i<n.length;i++){const o=n[i];if(Ml(t,o)||Ml(e,o))return!0}return!1}function VM(e,t,n){return Ml(t,n)||Ml(e,n)}function ZM(e,t){const n=lu(e)?.chunk;if(n?.fallback){Go(e,{area:"parse",path:"plain",reason:`global-state:${n.fallbackReason||"unknown"}`});return}Go(e,{area:"parse",path:"full-chunk",chunked:!0,reason:t})}function Zf(){return typeof performance<"u"?performance.now():Date.now()}function JCe(e,t){let n={html:!1,xhtmlOut:!1,breaks:!1,langPrefix:"language-",linkify:!1,typographer:!1,quotes:"“”‘’",highlight:null,maxNesting:100,stream:!1,streamOptimizationMinSize:1e3,streamChunkedFallback:!1,streamChunkSizeChars:1e4,streamChunkSizeLines:200,streamChunkFenceAware:!0,streamChunkAdaptive:!0,streamChunkTargetChunks:8,streamChunkMaxChunks:void 0,streamLargeCachePolicy:"retain",streamSkipCacheAboveChars:1e6,streamSkipCacheAboveLines:1e5,fullChunkedFallback:!1,fullChunkThresholdChars:2e4,fullChunkThresholdLines:400,fullChunkSizeChars:1e4,fullChunkSizeLines:200,fullChunkFenceAware:!0,fullChunkAdaptive:!0,fullChunkTargetChunks:8,fullChunkMaxChunks:void 0,autoTuneChunks:!0,autoUnbounded:!0,autoUnboundedThresholdChars:4e6,autoUnboundedThresholdLines:8e4},i="default",o;!t&&typeof e!="string"?(o=e,i="default"):typeof e=="string"&&(i=e,o=t);const s=qM[i];if(!s)throw new Error(`Wrong \`markdown-it\` preset "${i}", check name`);if(s?.options&&(n={...n,...s.options}),o&&(n={...n,...o}),n=UM(n),typeof n.quotes=="string"){const _=n.quotes;_.length>=4?n.quotes=[_[0],_[1],_[2],_[3]]:n.quotes=["“","”","‘","’"]}let r=KM(s?.options,o,["fullChunkSizeChars","fullChunkSizeLines","fullChunkMaxChunks"]),l=KM(s?.options,o,["streamChunkSizeChars","streamChunkSizeLines","streamChunkMaxChunks"]),a=VM(s?.options,o,"fullChunkedFallback"),u=VM(s?.options,o,"streamChunkedFallback"),c=!1,d=null,h=null;const p=new jAe;let g=null;const m=()=>(g||(g=new qCe(n)),g);let k=null;const w=()=>(k||(k=new GCe(p)),k);let y=null;const b=()=>(y||(y=new RR({fuzzyLink:!0})),y),A=_=>!c&&!!d&&!YCe(_,d),T=(_,L)=>i==="default"&&!c&&g===null&&h!==null&&_.parse===h&&A(_)&&!_.stream.enabled&&L<(_.options.autoUnboundedThresholdChars??4e6)&&_.options.html===!1&&_.options.xhtmlOut===!1&&_.options.breaks===!1&&_.options.langPrefix==="language-"&&_.options.linkify===!1&&_.options.typographer===!1&&_.options.highlight===null,S=(_,L)=>i==="default"&&!c&&A(_)&&!_.stream.enabled&&!_.options.fullChunkedFallback&&L<(_.options.autoUnboundedThresholdChars??4e6)&&_.options.html===!1&&_.options.linkify===!1&&_.options.typographer===!1,x={core:p,block:p.block,inline:p.inline,get linkify(){const _=b();return Object.defineProperty(this,"linkify",{value:_,writable:!0,configurable:!0}),_},get renderer(){const _=m();return Object.defineProperty(this,"renderer",{value:_,writable:!0,configurable:!0}),_},options:n,__explicitFullChunkConfig:r,__explicitStreamChunkConfig:l,__explicitFullChunkFallbackSetting:a,__explicitStreamChunkFallbackSetting:u,__canUseImplicitLargeInputStrategy(){return A(this)},set(_){const L=UM(_);return this.options={...this.options,...L},(Ml(_,"fullChunkSizeChars")||Ml(_,"fullChunkSizeLines")||Ml(_,"fullChunkMaxChunks"))&&(r=!0,this.__explicitFullChunkConfig=!0),(Ml(_,"streamChunkSizeChars")||Ml(_,"streamChunkSizeLines")||Ml(_,"streamChunkMaxChunks"))&&(l=!0,this.__explicitStreamChunkConfig=!0),Ml(_,"fullChunkedFallback")&&(a=!0,this.__explicitFullChunkFallbackSetting=!0),Ml(_,"streamChunkedFallback")&&(u=!0,this.__explicitStreamChunkFallbackSetting=!0),g&&g.set(L),typeof L.stream=="boolean"&&(this.stream.enabled=L.stream,k&&(k.reset(),k.resetStats())),this},configure(_){const L=typeof _=="string"?qM[_]:_;if(!L)throw new Error("Wrong `markdown-it` preset, can't be empty");if(L.options&&this.set(L.options),L.components){const M=L.components;M.core?.rules&&this.core.ruler.enableOnly(M.core.rules),M.block?.rules&&this.block.ruler.enableOnly(M.block.rules),M.inline?.rules&&this.inline.ruler.enableOnly(M.inline.rules),M.inline2?.rules&&this.inline.ruler2.enableOnly(M.inline2.rules)}return this},enable(_,L){const M=Array.isArray(_)?_:[_],N=[this.core?.ruler,this.block?.ruler,this.inline?.ruler,this.inline?.ruler2],I=new Set;for(const z of N){if(!z)continue;const H=z.enable(M,!0);for(let O=0;O<H.length;O++)I.add(H[O])}if(!L){const z=M.filter(H=>!I.has(H));if(z.length)throw new Error(`Rules manager: invalid rule name ${z.join(", ")}`)}return this},disable(_,L){const M=Array.isArray(_)?_:[_],N=[this.core?.ruler,this.block?.ruler,this.inline?.ruler,this.inline?.ruler2],I=new Set;for(const z of N){if(!z)continue;const H=z.disable(M,!0);for(let O=0;O<H.length;O++)I.add(H[O])}if(!L){const z=M.filter(H=>!I.has(H));if(z.length)throw new Error(`Rules manager: invalid rule name ${z.join(", ")}`)}return this},use(_,...L){const M=typeof _=="function"?_:_&&typeof _.default=="function"?_.default:void 0;if(!M)throw new TypeError("MarkdownIt.use: plugin must be a function");const N=[this,...L],I=_;return c=!0,M.apply(I,N),this},render(_,L){let M;if(T(this,_.length)){L!==void 0&&(gr(L),M=F3("render"));const z=M?Zf():0,H=M?BM(_,M):DM(_);if(M&&(M.attemptMs=Zf()-z,H===null&&(M.fallbackReason="unsupported-stock-subset"),V1(L,M)),H!==null)return L!==void 0&&Go(L,{area:"render",path:"stock-fast",reason:"stock-subset"}),H}const N=L??{},I=this.parse(_,N);return M&&V1(N,M),m().render(I,this.options,N)},async renderAsync(_,L){let M;if(T(this,_.length)){L!==void 0&&(gr(L),M=F3("render"));const z=M?Zf():0,H=M?BM(_,M):DM(_);if(M&&(M.attemptMs=Zf()-z,H===null&&(M.fallbackReason="unsupported-stock-subset"),V1(L,M)),H!==null)return L!==void 0&&Go(L,{area:"render",path:"stock-fast",reason:"stock-subset"}),H}const N=L??{},I=this.parse(_,N);return M&&V1(N,M),m().renderAsync(I,this.options,N)},renderIterable(_,L={}){const M=this.parseIterable(_,L);return m().render(M,this.options,L)},async renderAsyncIterable(_,L={}){const M=await this.parseAsyncIterable(_,L);return m().renderAsync(M,this.options,L)},renderInline(_,L={}){const M=this.parseInline(_,L);return m().render(M,this.options,L)},validateLink:hz,normalizeLink:pz,normalizeLinkText:gz,utils:v6e,helpers:{...s7e},parse(_,L){if(typeof _!="string")throw new TypeError("Input data should be a String");if(L!==void 0&&gr(L),S(this,_.length)){const z=L===void 0?void 0:F3("parse"),H=z?Zf():0,O=XAe(_,z);if(z&&(z.attemptMs=Zf()-H,O===null&&(z.fallbackReason="unsupported-stock-subset"),V1(L,z)),O!==null)return L!==void 0&&Go(L,{area:"parse",path:"stock-fast",reason:"stock-subset"}),O}const M=L??{};let N;if(!this.stream.enabled&&!this.options.fullChunkedFallback&&A(this)){const z=Mz(this,_.length);if(z==="yes"){const H=Hp(this,_,M);return Go(L,{area:"parse",path:"auto-unbounded",unbounded:!0,reason:"char-threshold"}),H}z==="need-lines"&&(N=To(_))}if(!this.stream.enabled){const z=_.length,H=this.options.autoTuneChunks!==!1,O=r,R=!a&&A(this),j=!!this.options.fullChunkedFallback,$=R&&z>=2e5;let W;(j||$||N!==void 0)&&(W=N??To(_));const P=(j||$)&&H&&!O?BCe(z,W,this.options):null;if(j||$){const Z=W??0;if(j?z>=(this.options.fullChunkThresholdChars??2e4)||Z>=(this.options.fullChunkThresholdLines??400):$){if(P&&P.strategy!=="plain"){const ae=ey(this,_,M,{maxChunkChars:P.maxChunkChars,maxChunkLines:P.maxChunkLines,fenceAware:P.fenceAware,maxChunks:P.maxChunks});return L&&ZM(L,j?"explicit-full-chunk":"default-large-string"),ae}if(j){const ae=(te,be,Q)=>te<be?be:te>Q?Q:te,V=this.options.fullChunkAdaptive!==!1,Y=this.options.fullChunkTargetChunks??8,oe=ae(Math.ceil(z/Y),8e3,64e3),q=ae(Math.ceil(Z/Y),150,700),ne=V?oe:this.options.fullChunkSizeChars??1e4,ie=V?q:this.options.fullChunkSizeLines??200,pe=V?ae(Math.ceil(z/64e3),Y,32):this.options.fullChunkMaxChunks,Ne=ey(this,_,M,{maxChunkChars:ne,maxChunkLines:ie,fenceAware:this.options.fullChunkFenceAware??!0,maxChunks:pe});return L&&ZM(L,"explicit-full-chunk"),Ne}}}if(N!==void 0&&A(this)&&_z(this,z,W??N)){const Z=Hp(this,_,M);return Go(L,{area:"parse",path:"auto-unbounded",unbounded:!0,reason:"line-threshold"}),Z}}const I=Pr(_);return Go(L,{area:"parse",path:"plain",reason:"default-plain"}),Bh(M,I,()=>p.parse(_,M,this).tokens)},parseIterable(_,L={}){return gr(L),LCe(this,_,L)},parseAsyncIterable(_,L={}){return gr(L),NCe(this,_,L)},parseIterableToSink(_,L,M={}){return gr(M),FCe(this,_,L,M)},parseAsyncIterableToSink(_,L,M={}){return gr(M),DCe(this,_,L,M)},parseInline(_,L={}){if(typeof _!="string")throw new TypeError("Input data should be a String");gr(L),pg(L)&&Mu(L);const M=p.createState(_,L,this);return M.inlineMode=!0,p.process(M),M.tokens}};if(x.stream={enabled:!!n.stream,parse(_,L){return x.stream.enabled?w().parse(_,L,x):x.parse(_,L??{})},reset(){w().reset()},peek(){return k?k.peek():[]},stats(){return k?k.getStats():{total:0,cacheHits:0,appendHits:0,unboundedAppendHits:0,tailHits:0,fullParses:0,resets:0,chunkedParses:0,lastMode:"idle"}},resetStats(){k&&k.resetStats()}},s?.components){const _=s.components;_.core?.rules&&x.core.ruler.enableOnly(_.core.rules),_.block?.rules&&x.block.ruler.enableOnly(_.block.rules),_.inline?.rules&&x.inline.ruler.enableOnly(_.inline.rules),_.inline2?.rules&&x.inline.ruler2.enableOnly(_.inline2.rules)}return d=QCe(x),h=x.parse,x}var XCe=JCe;const Nz=["area","base","br","col","embed","hr","img","input","link","meta","param","source","track","wbr"],ewe=["a","abbr","b","bdi","bdo","button","cite","code","data","del","dfn","em","font","i","ins","kbd","label","mark","q","s","samp","small","span","strong","sub","sup","time","u","var"],Fz=["article","aside","blockquote","details","div","figcaption","figure","footer","header","h1","h2","h3","h4","h5","h6","li","main","nav","ol","p","pre","section","summary","table","tbody","td","th","thead","tr","ul"],twe=["svg","g","path"],nwe=["address","audio","body","canvas","caption","colgroup","datalist","dd","dialog","dl","dt","fieldset","form","head","hgroup","html","iframe","legend","map","menu","meter","noscript","object","optgroup","option","output","picture","progress","rp","rt","ruby","script","select","style","template","textarea","tfoot","title","video"],iwe=["onclick","onerror","onload","onmouseover","onmouseout","onmousedown","onmouseup","onkeydown","onkeyup","onfocus","onblur","onsubmit","onreset","onchange","onselect","ondblclick","ontouchstart","ontouchend","ontouchmove","ontouchcancel","onwheel","onscroll","oncopy","oncut","onpaste","oninput","oninvalid","onsearch","innerhtml","outerhtml","textcontent","innertext","srcdoc","ping"],owe=["action","data","href","src","srcset","poster","xlink:href","formaction"],swe=["script"],rwe=["pre","iframe","picture","script","style","table","tbody","td","tfoot","th","thead","textarea","tr","title","video"],Tc=new Set(Nz),Dz=new Set(Fz),B0=new Set([...Nz,...ewe,...Fz,...twe]),Bz=new Set([...B0,...nwe]),lwe=new Set(iwe),awe=new Set(owe),vg=new Set(swe),$z=new Set(rwe);function Rz(e){let t="";for(const n of e){const i=n.charCodeAt(0);i<=31||i>=127&&i<=159||/\s/u.test(n)||(t+=n)}return t}const uwe={amp:"&",bsol:"\\",colon:":",newline:` -`,sol:"/",tab:" "};function zz(e){return e.replace(/&(?:#(\d+)|#x([0-9a-f]+)|([a-z][a-z0-9]+));?/gi,(t,n,i,o)=>{const s=n??i;if(s){const r=Number.parseInt(s,n?10:16);try{return Number.isFinite(r)?String.fromCodePoint(r):""}catch{return""}}return uwe[String(o??"").toLowerCase()]??t})}const qm=new Set(["http","https","mailto","tel"]),cwe=new Set(["javascript","vbscript","data","file","ftp","blob","filesystem","intent","chrome","chrome-extension","moz-extension","ms-browser-extension","view-source"]),md=new Set(["http","https"]);function Oz(e){return e.match(/^([a-z][a-z0-9+.-]*):/i)?.[1]?.toLowerCase()??""}const dwe=/^https?:\/\//i;function fwe(e){if(!dwe.test(e))return!1;for(const t of e){const n=t.charCodeAt(0);if(t==="&"||n<=32||n>=127&&n<=159||n>127&&/\s/u.test(t))return!1}return!0}function hwe(e,t,n){if(!Up(t,n)||!e.startsWith("file:///"))return!1;const i=e.charAt(8);return i!=="/"&&i!=="\\"}function Up(e,t){return e?(e==="a"||e==="area")&&(!t||t==="href"||t==="xlink:href"):!t||t==="href"}function pwe(e,t){return t==="href"||t==="xlink:href"?Up(e,t)?qm:md:t==="src"||t==="srcset"||t==="poster"||t==="action"||t==="formaction"||t==="data"?md:(Up(e,t),qm)}function Gd(e,t={}){if(fwe(e))return!1;const n=Rz(zz(e)).toLowerCase(),i=String(t.tagName??"").toLowerCase(),o=String(t.attrName??"").toLowerCase();if(!n)return!1;if(n.startsWith("data:")){const r=/^data:image\/(?:png|gif|jpe?g|webp|avif|bmp);/i.test(n);return i==="img"&&o==="src"?!r:!0}if(/^[\\/]{2}/.test(n))return!0;if(n.startsWith("/")||n.startsWith("./")||n.startsWith("../")||n.startsWith("#")||n.startsWith("?"))return!1;const s=Oz(n);return s?s==="file"?!hwe(n,i,o):Up(i,o)?cwe.has(s):!pwe(i,o).has(s):!1}function gwe(e){const t=zz(String(e??"")).trim();if(!t||t.startsWith("#")||t.startsWith("/")||t.startsWith("./")||t.startsWith("../")||t.startsWith("?"))return!1;const n=Oz(Rz(t).toLowerCase());return n==="http"||n==="https"}function mwe(e,t={}){const n=String(e??"").trim();return n?Gd(n,t)?"":n:""}function GM(e){return mwe(e,{tagName:"img",attrName:"src"})}function vwe(e,t,n){function i(h){return h.trim().split(" ",2)[0]===t}function o(h,p,g,m,k){return h[p].nesting===1&&h[p].attrJoin("class",t),k.renderToken(h,p,g,m,k)}n=n||{};const s=3,r=n.marker||":",l=r.charCodeAt(0),a=r.length,u=n.validate||i,c=n.render||o;function d(h,p,g,m){let k,w=!1,y=h.bMarks[p]+h.tShift[p],b=h.eMarks[p];if(l!==h.src.charCodeAt(y))return!1;for(k=y+1;k<=b&&r[(k-y)%a]===h.src[k];k++);const A=Math.floor((k-y)/a);if(A<s)return!1;k-=(k-y)%a;const T=h.src.slice(y,k),S=h.src.slice(k,b);if(!u(S,T))return!1;if(m)return!0;let x=p;for(;x++,!(x>=g||(y=h.bMarks[x]+h.tShift[x],b=h.eMarks[x],y<b&&h.sCount[x]<h.blkIndent));)if(l===h.src.charCodeAt(y)&&!(h.sCount[x]-h.blkIndent>=4)){for(k=y+1;k<=b&&r[(k-y)%a]===h.src[k];k++);if(!(Math.floor((k-y)/a)<A)&&(k-=(k-y)%a,k=h.skipSpaces(k),!(k<b))){w=!0;break}}const _=h.parentType,L=h.lineMax;h.parentType="container",h.lineMax=x;const M=h.push("container_"+t+"_open","div",1);M.markup=T,M.block=!0,M.info=S,M.map=[p,x],h.md.block.tokenize(h,p+1,x);const N=h.push("container_"+t+"_close","div",-1);return N.markup=h.src.slice(y,k),N.block=!0,h.parentType=_,h.lineMax=L,h.line=x+(w?1:0),!0}e.block.ruler.before("fence","container_"+t,d,{alt:["paragraph","reference","blockquote","list"]}),e.renderer.rules["container_"+t+"_open"]=c,e.renderer.rules["container_"+t+"_close"]=c}function ywe(e){const t=String(e??"").trim();if(!t.startsWith("{")||!t.endsWith("}"))return null;const n=t.slice(1,-1).trim();if(!n)return{};if(n.includes("{")||n.includes("[")||n.includes("]"))return null;const i=[];let o="",s=!1,r=!1;for(let a=0;a<n.length;a++){const u=n[a];if(u==="\\"){o+=u,a+1<n.length&&(o+=n[a+1],a++);continue}if(!r&&u==="'"){s=!s,o+=u;continue}if(!s&&u==='"'){r=!r,o+=u;continue}if(!s&&!r&&u===","){i.push(o.trim()),o="";continue}o+=u}o.trim()&&i.push(o.trim());const l={};for(const a of i){if(!a)continue;let u=!1,c=!1,d=-1;for(let k=0;k<a.length;k++){const w=a[k];if(w==="\\"){k++;continue}if(!c&&w==="'"){u=!u;continue}if(!u&&w==='"'){c=!c;continue}if(!u&&!c&&w===":"){d=k;break}}if(d===-1)return null;const h=a.slice(0,d).trim(),p=a.slice(d+1).trim();if(!h)return null;let g=h;if(g.startsWith('"')&&g.endsWith('"')||g.startsWith("'")&&g.endsWith("'"))try{g=JSON.parse(g.replace(/^'/,'"').replace(/'$/,'"'))}catch{return null}if(!/^[_$A-Z][\w$-]*$/i.test(g))return null;let m;if(!p)m="";else if(p.startsWith('"')&&p.endsWith('"')||p.startsWith("'")&&p.endsWith("'"))try{m=JSON.parse(p.replace(/^'/,'"').replace(/'$/,'"'))}catch{m=p}else/^-?\d+(?:\.\d+)?$/.test(p)?m=Number(p):p==="true"||p==="false"?m=p==="true":p==="null"?m=null:m=p;l[g]=m}return l}function Pz(e,t,n){for(const i of e){const o=i,s=o.map;if(Array.isArray(s)&&s.length>=2){const r=Number(s[0]),l=Number(s[1]);Number.isFinite(r)&&Number.isFinite(l)&&(o.map=[r+t,Math.min(l+t,n)])}Array.isArray(o.children)&&Pz(o.children,t,n)}}function kwe(e){["admonition","info","warning","error","tip","danger","note","caution"].forEach(t=>{e.use(vwe,t,{render(n,i){return n[i].nesting===1?`<div class="vmr-container vmr-container-${t}">`:`</div> -`}})}),e.block.ruler.before("fence","vmr_container_fallback",(t,n,i,o)=>{const s=t,r=s.bMarks[n]+s.tShift[n],l=s.eMarks[n],a=s.src.slice(r,l),u=a.match(/^:::\s*([^\s{]+)/);if(!u)return!1;const c=u[1];if(!c.trim())return!1;const d=a.slice(u[0].length).trim();let h,p;const g=d.indexOf("{"),m=g>=0?d.slice(g).trimStart():void 0;if(g===-1)h=d||void 0;else{if(h=d.slice(0,g).trim()||void 0,m?.startsWith("{")){let S=0,x=-1;for(let _=0;_<m.length;_++)if(m[_]==="{"?S++:m[_]==="}"&&S--,S===0){x=_+1;break}x>0&&(p=m.slice(0,x))}p||(h=d||void 0)}if(o)return!0;const k=!!s.env.__markstreamFinal;let w=n+1,y=!1;for(;w<=i;){const S=s.bMarks[w]+s.tShift[w],x=s.eMarks[w];if(s.src.slice(S,x).trim()===":::"){y=!0;break}w++}y||(w=i);const b=s.push("vmr_container_open","div",1);if(b.attrSet("class",`vmr-container vmr-container-${c}`),b.map=[n,y?w:i],b.meta={...b.meta??{},unclosed:!y&&!k},h&&b.attrSet("data-args",h),p)try{const S=JSON.parse(p);for(const[x,_]of Object.entries(S)){const L=_!=null&&typeof _=="object";b.attrSet(`data-${x}`,L?JSON.stringify(_):String(_))}}catch{const S=ywe(p);if(S)for(const[x,_]of Object.entries(S)){const L=_!=null&&typeof _=="object";b.attrSet(`data-${x}`,L?JSON.stringify(_):String(_))}else b.attrSet("data-attrs",p)}const A=[];for(let S=n+1;S<w;S++){const x=s.bMarks[S]+s.tShift[S],_=s.eMarks[S];A.push(s.src.slice(x,_))}if(A.some(S=>S.trim().length>0)){let S=A.join(` -`);S.endsWith(` -`)||(S+=` -`),S.endsWith(` - -`)||(S+=` -`);const x=s.tokens[s.tokens.length-1];x&&(x.raw=S);const _=[];s.md.block.parse(S,s.md,s.env,_),Pz(_,n+1,n+1+A.length),s.tokens.push(..._)}const T=s.push("vmr_container_close","div",-1);return y||(T.hidden=!0,T.map=[i,i]),s.line=y?w+1:w,!0},{alt:["paragraph","reference","blockquote","list"]})}function fa(e){return e.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}function Do(e){let t=!1,n=!1;for(let i=0;i<e.length;i++){const o=e[i];if(o==="\\"){i++;continue}if(!n&&o==="'"){t=!t;continue}if(!t&&o==='"'){n=!n;continue}if(!t&&!n&&o===">")return i}return-1}function _9(e){const t=[],n=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let i;for(;(i=n.exec(e))!==null;){const o=i[1];if(!o)continue;const s=i[2]||i[3]||i[4]||"";t.push([o,s])}return t}const bwe=/^[a-z][a-z0-9_-]*$/;function QM(e){return bwe.test(String(e??"").trim().toLowerCase())}function zl(e){const t=String(e??"").trim();if(!t)return"";if(!t.startsWith("<"))return QM(t)?t.toLowerCase():"";let n=1;for(;n<t.length&&/\s/.test(t[n]);)n++;if(t[n]==="/")for(n++;n<t.length&&/\s/.test(t[n]);)n++;const i=n;for(;n<t.length&&/[\w-]/.test(t[n]);)n++;const o=t.slice(i,n).toLowerCase(),s=t[n]??"";return s&&!/[\s/>]/.test(s)?"":QM(o)?o:""}function wf(e){if(!e||e.length===0)return[];const t=new Set,n=[];for(const i of e){const o=zl(i);!o||t.has(o)||(t.add(o),n.push(o))}return n}function Awe(...e){const t=new Set,n=[];for(const i of e)for(const o of wf(i))t.has(o)||(t.add(o),n.push(o));return n}function Cwe(e){const t=wf(e);return{key:t.join(","),tags:t}}function jz(e){return zl(e)}function wwe(e,t){const n=String(e??""),i=zl(t);if(!i)return!1;const o=fa(i),s=n.match(new RegExp(String.raw`^\s*<\s*${o}(?:\s[^>]*)?(\s*\/)?>`,"i"));return s?s[1]?!0:new RegExp(String.raw`<\s*\/\s*${o}\s*>`,"i").test(n):!1}function Hz(e,t){const n=zl(t);return!!n&&!B0.has(n)&&!wwe(e,n)}function xwe(e,t){const n=String(e??""),i=zl(t);if(!i)return n;const o=fa(i),s=new RegExp(String.raw`^\s*<\s*${o}(?:\s[^>]*)?>\s*`,"i"),r=new RegExp(String.raw`\s*<\s*\/\s*${o}\s*>\s*$`,"i");return n.replace(s,"").replace(r,"")}const Wz=Tc,Swe=B0,qz=new Set(Dz);qz.delete("details");const _we=/<([A-Z][\w-]*)(?=[\s/>]|$)/gi,Mwe=/<\/\s*([A-Z][\w-]*)(?=[\s/>]|$)/gi,D8=/^<\s*(?:\/\s*)?([A-Z][\w-]*)/i,Iwe=/^<\s*([A-Z][\w:-]*)(?=[\s/>]|$)/i;function ny(e){return(e.match(D8)?.[1]??"").toLowerCase()}function w7(e){return/^\s*<\s*\//.test(e)}function x7(e,t){return Wz.has(t)||/\/\s*>\s*$/.test(e)}function Ewe(e,t){let n=0;for(let i=0;i<e.length;i++){const o=e[i];if(!o||o.type!=="html_inline")continue;const s=String(o.content??""),r=ny(s);if(r===t){if(w7(s)){if(n===0)return i;n--;continue}x7(s,r)||n++}}return-1}function Twe(e,t){let n=0;for(const i of e){if(!i||i.type!=="html_inline")continue;const o=String(i.content??""),s=ny(o);if(s===t){if(w7(o)){n>0&&n--;continue}x7(o,s)||n++}}return n}function YM(e,t,n=0){const i=new RegExp(String.raw`<\s*(\/?)\s*${fa(t)}(?=[\s>/])[^>]*>`,"gi");i.lastIndex=Math.max(0,n);let o=0,s;for(;(s=i.exec(e))!==null;){const r=s[0]??"",l=!!s[1],a=!l&&/\/\s*>$/.test(r);if(l){if(o===0)return{start:s.index,end:s.index+r.length};o--;continue}a||o++}return null}function Lwe(e,t){const n=new RegExp(String.raw`<\s*(\/?)\s*${fa(t)}(?=[\s>/])[^>]*>`,"gi");let i=0,o;for(;(o=n.exec(e))!==null;){const s=o[0]??"",r=!!o[1],l=!r&&/\/\s*>$/.test(s);if(r){i>0&&i--;continue}l||i++}return i}function iy(e){const t=e;return String(t.raw??t.content??t.markup??"")}function Nwe(e){const t=e;return t.meta||(t.meta={}),t.meta}function K3(e,t,n){const i=Nwe(e);i.markstreamCustomHtmlRaw=t,i.markstreamCustomHtmlInner=n}function Fwe(e,t){if(!t.size)return;const n=Array.from(t,p=>new RegExp(String.raw`<\s*${fa(p)}(?=[\s>/])`,"i")),i=[];let o=!1;const s=p=>p?n.some(g=>g.test(p)):!1,r=p=>{if(!(!p||!i.length))for(const g of i)g.raw+=p,g.inner+=p},l=()=>{!i.length||!o||(r(` -`),o=!1)},a=p=>{r(p)},u=p=>{for(let m=0;m<i.length;m++)i[m].raw+=p,m<i.length-1&&(i[m].inner+=p);const g=i.pop();K3(g.token,g.raw,g.inner)},c=p=>{const g=i[i.length-1]?.tag;if(!g)return null;const m=new RegExp(String.raw`^\s*<\s*\/\s*${fa(g)}\s*>`,"i");return p.match(m)?.[0]??null},d=p=>!!c(p),h=(p,g,m)=>{const k=m??(p.type==="html_inline"?ny(g):"");if(!(k&&t.has(k))){r(g);return}const w=w7(g),y=!w&&x7(g,k);if(w){if(!i.length||i[i.length-1].tag!==k){r(g);return}u(g);return}if(r(g),y){K3(p,g,"");return}i.push({tag:k,token:p,raw:g,inner:""})};for(const p of e){if(p.type==="inline"&&Array.isArray(p.children)){const g=String(p.content??"");if(d(g)?o=!1:l(),!i.length&&!s(g)){o=!1;continue}let m=0,k=!0;for(const w of p.children){const y=iy(w),b=w.type==="html_inline"?ny(y):"",A=b&&t.has(b);let T=y;if(k&&g&&y&&(i.length||A)){const S=g.indexOf(y,m);if(S!==-1)a(g.slice(m,S)),T=g.slice(S,S+y.length),m=S+y.length;else{if(i.length&&!A)continue;k=!1}}h(w,T,b)}k&&g&&m<g.length&&i.length&&a(g.slice(m)),o=i.length>0;continue}if(i.length&&typeof p.content=="string"){const g=iy(p),m=p.type==="html_block"?c(g):null;if(m){u(`${o?` -`:""}${m}`),o=i.length>0;continue}if(!p.content)continue;l(),r(p.content),o=!0}}for(const p of i)K3(p.token,p.raw,p.inner)}function Dwe(e){return/^\s*<\s*[!?]/.test(e)}function Bwe(e){const t=new Set(Swe);if(e&&Array.isArray(e))for(const n of e){const i=String(n??"").trim();if(!i)continue;const o=i.match(/^[<\s/]*([A-Z][\w-]*)/i);o&&t.add(o[1].toLowerCase())}return t}function JM(e,t){if(t.has(e))return!0;for(const n of t)if(n.startsWith(e))return!0;return!1}function $we(e,t){let n=null;for(const s of e.matchAll(_we)){const r=s.index??-1;if(r<0)continue;const l=(s[1]??"").toLowerCase();JM(l,t)&&Do(e.slice(r))===-1&&(!n||r<n.index)&&(n={index:r,tag:l,closing:!1})}for(const s of e.matchAll(Mwe)){const r=s.index??-1;if(r<0)continue;const l=(s[1]??"").toLowerCase();JM(l,t)&&Do(e.slice(r))===-1&&(!n||r<n.index)&&(n={index:r,tag:l,closing:!0})}const i=/<\/\s*$/.exec(e);if(i&&typeof i.index=="number"){const s=i.index;!e.slice(s).includes(">")&&(!n||s<n.index)&&(n={index:s,tag:"",closing:!0})}const o=/<\s*$/.exec(e);if(o&&typeof o.index=="number"){const s=o.index,r=e.slice(s);!r.startsWith("</")&&!r.includes(">")&&(!n||s<n.index)&&(n={index:s,tag:"",closing:!1})}return n}function Rwe(e,t){const n=e;return Object.assign(Object.create(Object.getPrototypeOf(n)),n,{type:"text",content:t,raw:t})}function zwe(e,t){if(!e.length)return{children:e};const n=[];let i=null,o=null;function s(a,u){a&&(u?n.push(Rwe(u,a)):n.push({type:"text",content:a,raw:a}))}function r(a,u){let c=0;for(;c<a.length;){const d=a.indexOf("<",c);if(d===-1){s(a.slice(c),u);break}s(a.slice(c,d),u);const h=a.slice(d),p=h.match(D8);if(!p){s("<",u),c=d+1;continue}const g=Do(h);if(g===-1){s("<",u),c=d+1;continue}const m=h.slice(0,g+1),k=(p[1]??"").toLowerCase();t.has(k)?n.push({type:"html_inline",tag:"",content:m,raw:m}):s(m,u),c=d+m.length}}function l(a,u){if(!a)return;const c=$we(a,t);if(!c){r(a,u);return}const d=a.slice(0,c.index);d&&r(d,u),i={tag:c.tag,buffer:a.slice(c.index),closing:c.closing},o=i.buffer}for(const a of e){if(i){i.buffer+=iy(a),o=i.buffer;const u=Do(i.buffer);if(u===-1)continue;const c=i.buffer.slice(0,u+1),d=i.buffer.slice(u+1);n.push({type:"html_inline",tag:"",content:c,raw:c}),i=null,o=null,d&&l(d);continue}if(a.type==="html_inline"){const u=iy(a),c=(u.match(D8)?.[1]??"").toLowerCase();if(c&&t.has(c)&&Do(u)===-1){i={tag:c,buffer:u,closing:/^<\s*\//.test(u)},o=i.buffer;continue}}if(a.type==="text"){const u=String(a.content??"");if(!u.includes("<")){n.push(a);continue}l(u,a);continue}n.push(a)}return{children:n,pendingBuffer:o??void 0}}const Owe=["a","span","strong","em","b","i","u"];function Pwe(e,t={}){const n=new Set;if(t.customHtmlTags?.length)for(const h of t.customHtmlTags){const p=zl(h);p&&n.add(p)}const i=h=>{const p=h,g=new Set(n),m=Array.isArray(p.env?.__markstreamCustomHtmlTags)?p.env.__markstreamCustomHtmlTags:[];for(const b of m){const A=zl(String(b??""));A&&g.add(A)}const k=Bwe(Array.from(g)),w=new Set(Owe);for(const b of g)w.add(b);return{autoCloseInlineTagSet:w,commonHtmlTags:k,customTagSet:g,shouldMergeHtmlBlockTag:b=>g.has(b)||!k.has(b)||qz.has(b)}},o=h=>{if(h.type==="html_block")return String(h.content??"");if(h.type!=="inline"||!Array.isArray(h.children)||h.children.length!==1)return"";const p=h.children[0];return p?.type!=="html_block"?"":String(h.content??p.content??"")},s=(h,p)=>{h.type="html_block",h.content=p,h.raw=p,h.children=[]},r=h=>h.replace(/^(?:\r?\n)+/,""),l=h=>/^(?: {4}|\t)/.test(h),a=h=>h.replace(/^(?: {4}|\t)/gm,""),u=(h,p)=>{const g=r(h);if(!/\S/.test(g))return[];if(l(g))return[{type:"code_block",content:a(g),raw:g}];const m=g.replace(/^[\t ]+/,"");if(!m)return[];if(m.startsWith("<"))return[{type:"html_block",content:m}];const k={type:"inline",tag:"",nesting:0,content:m,children:[{type:"text",content:m,raw:m}]};return p==="paragraph"?[{type:"paragraph_open",tag:"p",nesting:1},k,{type:"paragraph_close",tag:"p",nesting:-1}]:p==="text"?[{type:"text",content:m,raw:m}]:[k]},c=(h,p,g)=>h[p-1]?.type==="paragraph_open"&&h[p+1]?.type==="paragraph_close"?"inline":g,d=(h,p)=>{const g=r(p);return!/\S/.test(g)||h.type!=="inline"||!Array.isArray(h.children)?!1:(h.content=`${String(h.content??"")}${g}`,h.children.push({type:"text",content:g,raw:g}),!0)};e.core.ruler.after("inline","fix_html_inline_streaming",h=>{const p=h.tokens??[],{commonHtmlTags:g,customTagSet:m}=i(h);for(const k of p){const w=k;if(w.type!=="inline"||!Array.isArray(w.children))continue;const y=String(w.content??""),b=w.children.length?w.children:y.includes("<")?[{type:"text",content:y,raw:y}]:null;if(b)try{const A=zwe(b,g);if(w.children=A.children,A.pendingBuffer){const T=y.lastIndexOf(A.pendingBuffer);if(T!==-1){const S=y.slice(0,T);w.content=S,typeof w.raw=="string"&&(w.raw=S)}}}catch(A){console.error("[applyFixHtmlInlineTokens] failed to fix streaming html inline",A)}}Fwe(p,m)}),e.core.ruler.push("fix_html_inline_tokens",h=>{const p=h.tokens??[],{autoCloseInlineTagSet:g,customTagSet:m,shouldMergeHtmlBlockTag:k}=i(h),w=[];for(let y=0;y<p.length;y++){const b=p[y];if(w.length>0){const[T,S]=w[w.length-1];if(y!==S){if(b.type==="paragraph_open"||b.type==="paragraph_close"){p.splice(y,1),y--;continue}const x=String(b.content??b.raw??"");if(x){const _=p[S],L=`${String(_.content||"")} -${x}`,M=Do(L),N=M===-1?null:YM(L,T,M+1);if(N){const I=L.slice(0,N.end),z=L.slice(N.end);_.content=I,_.loading=!1,p.splice(y,1),w.pop();const H=d(_,z)?[]:u(z,c(p,y,"paragraph"));H.length&&p.splice(y,0,...H),y--;continue}_.content=L,_.loading!==!1&&(_.loading=!0)}p.splice(y,1),y--;continue}}const A=o(b);if(A){if(Dwe(A))continue;const T=(A.match(/<\s*(?:\/\s*)?([^\s>/]+)/)?.[1]??"").toLowerCase(),S=/^\s*<\s*\//.test(A);if(!T||!k(T))continue;if(s(b,A),!S)T&&!new RegExp(`^\\s*<\\s*${T}\\b[^>]*\\/\\s*>`,"i").test(A)&&Lwe(A,T)>0&&w.push([T,y]);else if(w.length>0&&T&&w[w.length-1][0]===T){const[,x]=w[w.length-1],_=p[x];_.content=`${String(_.content||"")} -${A}`,_.loading=!1,w.pop(),p.splice(y,1),y--}continue}else if(w.length>0){if(b.type==="paragraph_open"||b.type==="paragraph_close"){p.splice(y,1),y--;continue}const T=b.content||"",S=new RegExp(`<\\s*\\/\\s*${w[w.length-1][0]}\\s*>`,"i").test(T);if(T){const[,x]=w[w.length-1],_=p[x];_.content=`${_.content||""} -${T}`,_.loading!==!1&&(_.loading=!S)}S&&w.pop(),p.splice(y,1),y--}else continue}if(m.size>0){const y=new Map,b=new Map,A=x=>{let _=y.get(x);return _||(_=new RegExp(`<\\s*${x}\\b`,"i"),y.set(x,_)),_},T=x=>{let _=b.get(x);return _||(_=new RegExp(`<\\s*\\/\\s*${x}\\s*>`,"i"),b.set(x,_)),_},S=[];for(let x=0;x<p.length;x++){const _=p[x],L=String(_.content??"");if(S.length>0){const N=S[S.length-1],I=p[N.index],z=_.type==="html_block"?T(N.tag).exec(L):null;if(z){const R=z.index+z[0].length,j=L.slice(0,R),$=L.slice(R);I.content=`${String(I.content??"")} -${j}`,Array.isArray(I.children)&&I.children.push({type:"html_inline",content:`</${N.tag}>`,raw:`</${N.tag}>`}),S.pop();const W=d(I,$)?[]:u($,c(p,x,"paragraph"));W.length?p.splice(x,1,...W):(p.splice(x,1),x--);continue}if(_.type!=="inline")continue;const H=Array.isArray(_.children)?_.children:[],O=Ewe(H,N.tag);if(O!==-1){const R=H.slice(0,O+1),j=H.slice(O+1),$=R.map(W=>String(W?.content??W?.raw??"")).join("");if(I.content=`${String(I.content??"")} -${$}`,Array.isArray(I.children)&&I.children.push(...R),j.length){const W=j.map(P=>String(P.content??P.raw??"")).join("");if(W.trim()){const P=W.replace(/^\s+/,"");if(d(I,W))p.splice(x,1),x--;else if(P.startsWith("<"))p.splice(x,1,{type:"html_block",content:P});else{const Z=u(W,c(p,x,"paragraph"));p.splice(x,1,...Z)}}else p.splice(x,1),x--}else p.splice(x,1),x--;S.pop();continue}I.content=`${String(I.content??"")} -${L}`,Array.isArray(I.children)&&I.children.push(...H),p.splice(x,1),x--;continue}if(_.type!=="inline")continue;const M=Array.isArray(_.children)?_.children:[];for(const N of m)if((M.length?Twe(M,N):A(N).test(L)&&!T(N).test(L)?1:0)>0){S.push({tag:N,index:x});break}}}{let y=0;for(let b=0;b<p.length;b++){const A=p[b];if(A.type==="paragraph_open"){y++;continue}A.type==="paragraph_close"&&(y>0?y--:(p.splice(b,1),b--))}}for(let y=0;y<p.length;y++){const b=p[y];if(b.type==="html_block"){const _=(b.content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase();if(_.startsWith("!")||_.startsWith("?")){b.loading=!1;continue}if(m.has(_)){const O=String(b.content??""),R=Do(O),j=R===-1?null:YM(O,_,R+1);b.loading=j?!1:b.loading!==void 0?b.loading:!0;const $=j?.start??-1,W=j?j.end-j.start:0;if($!==-1){const P=O.slice(0,$+W);let Z="";R!==-1&&R<$&&(Z=O.slice(R+1,$)),b.children=[{type:_,content:Z,raw:P,attrs:[],tag:_,loading:!1}],b.content=P,b.raw=P;const ae=u(O.slice($+W)||"","text");ae.length&&p.splice(y+1,0,...ae)}else b.children=[{type:_,content:"",raw:O,attrs:[],tag:_,loading:!0}];continue}if(["br","hr","img","input","link","meta","div","p","ul","li"].includes(_))continue;b.type="inline";const L=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let M;for(;(M=L.exec(b.content||""))!==null;)M[1],M[2]||M[3]||M[4];const N=String(b.content??""),I=new RegExp(`<\\/\\s*${_}\\s*>`,"i").exec(N),z=I?I.index:-1,H=I?I[0].length:0;if(z!==-1){const O=N.slice(0,z+H),R=(N.slice(z+H)||"").replace(/^\s+/,"");b.children=[{type:"html_block",content:O,tag:_,loading:!1}],b.content=O,b.raw=O,R&&p.splice(y+1,0,R.startsWith("<")?{type:"html_block",content:R}:{type:"text",content:R,raw:R})}else b.children=[{type:"html_block",content:b.content,tag:_,loading:!0}];continue}if(!b||b.type!=="inline")continue;if(b.children.length===2&&b.children[0].type==="html_inline"){const _=(b.children[0].content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase(),L=b.children[1],M=String(L?.content??"").match(/^<\s*\/\s*([^\s>]+)/)?.[1]?.toLowerCase()??"";if(L?.type==="html_inline"&&M===_)continue;g.has(_)?(b.children[0].loading=!0,b.children[0].tag=_,b.children.push({type:"html_inline",tag:_,loading:!0,content:`</${_}>`})):b.children=[{type:"html_block",loading:!0,tag:_,content:String(b.children[0]?.content??"")+String(b.children[1]?.content??"")}];continue}else if(b.children.length===3&&b.children[0].type==="html_inline"&&b.children[2].type==="html_inline"){const _=(b.children[0].content?.match(/<([^\s>/]+)/)?.[1]??"").toLowerCase();if(g.has(_))continue;b.children=[{type:"html_block",loading:!1,tag:_,content:b.children.map(L=>L.content).join("")}];continue}if(!b.content?.startsWith("<")||b.children?.length!==1)continue;const A=String(b.content),T=b,S=T.children[0];if(S?.type!=="html_inline"){/^<\s*(?:\/\s*)?[A-Z][\w:-]*\s*$/i.test(A)&&(T.children.length=0);continue}const x=String(S.content??A).match(Iwe)?.[1]?.toLowerCase()??"";if(x){if(/\/\s*>\s*$/.test(A)||Wz.has(x)){T.children=[{type:"html_inline",content:A}];continue}T.children.length=0}}})}function jwe(e){const t=e.trim();return!t||/^&[a-z0-9#]+;/i.test(t)?!1:!!(/^(?:const|let|var|function|class|import|export|if|for|while|return|await|async|yield|try|catch|throw|new|typeof|instanceof|switch|case|break|continue|def|ruby|perl|print|echo|true|false|null|undefined|NaN|Infinity|this)\b/.test(t)||/[a-z_$][\w$]*(?:\.[a-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[\d+\])*\s*\(/i.test(t)||/[a-z_$][\w$]*(?:\.[a-z_$][\w$]*|\['[^']*'\]|\["[^"]*"\]|\[[\d+\]])+/i.test(t)||/\w+\s*(?:===?|!==?|<=?|>=?|\+\+|--|&&|\|\||\?\.)/.test(t)||/^(?:!!|\+\+|--)\s*\w/.test(t)||/[\w$]+\s*(?:\+=|-=|\*=|\/=|%=|\*\*=|=)/.test(t)||/^(?:https?:\/\/|ftp:\/\/|file:\/\/|\/\/|www\.)/i.test(t)||/`[^`]*\$\{[^}]*\}[^`]*`/.test(t)||/<\/?[A-Z][a-zA-Z0-9]*/.test(t)||/<[a-z][a-z0-9]*\s[^>]+>/.test(t)||/^(["'`]).*\1\s*[;,]?$/.test(t)||/^\[[\s\S]*\]$/.test(t)||/^\{[\s\S]*\}$/.test(t)||/^\(\s*\)$/.test(t)||/[\w$]+(?:\s*[+\-*/%<>=!&|^~:]+\s*[\w$]+|\s*\.\s*[\w$]+)/.test(t)||/=>|->|::/.test(t)||/^@[\w.$]+$/.test(t)||/^(?:0x[0-9a-fA-F]+|0b[01]+|0o[0-7]+|\d+(?:\.\d*)?(?:px|em|rem|%|vh|vw|deg|s|ms)?)$/.test(t)||/^\$[\w$]+\s*[=:]/.test(t)||/\|\s*\w+|\w+\s*\|/.test(t)||/^(?:git|npm|yarn|pnpm|bun|pip|cargo|go|rust|python|node|java|mvn|gradle|docker|kubectl)\s+/.test(t)||/(?:console|window|document|Math|JSON|Date|Array|Object|String|Number|Boolean)\.[a-zA-Z]/.test(t)||/^(?:\/\/|#|\/\*|\*\/|<!--|-->)/.test(t)||/^(?:<<<|<<\s*['"]?\w+['"]?)/.test(t))}function Hwe(e,t={}){t.enabled!==!1&&e.core.ruler.after("inline","fix_indented_code_block",n=>{const i=n.tokens??[];for(let o=0;o<i.length;o++){const s=i[o];if(s.type!=="code_block")continue;const r=String(s.content??"").trim();if(!r)continue;const l=r.split(/\r?\n/).filter(a=>a.trim().length>0);if(l.length===1&&!jwe(l[0]??"")){const a=l[0]??"",u=s.level??0;i.splice(o,1,{type:"paragraph_open",tag:"p",nesting:1,level:u},{type:"inline",tag:"",nesting:0,level:u,content:a,children:[{type:"text",content:a,level:u+1,raw:a}],block:!0},{type:"paragraph_close",tag:"p",nesting:-1,level:u}),o+=2}}})}const Uz=/\.([a-z0-9]{1,15})$/i,Wwe=/[_()[\]{}<>]/u,qwe=/^(?:https?:\/\/|ftp:\/\/|mailto:|www\.)/i,Uwe=/[?#@]/u,Kwe=/[\\/]/u,Vwe=/^[\p{L}\p{N}./\\-]+$/u,Zwe=/^[A-Za-z0-9-]{1,63}$/u,Gwe=/^xn--[a-z0-9-]{2,59}$/i,Qwe=/^(?:[A-Z]{1,6}|\d{1,8})$/u,Ywe=/^(?=.{1,12}$)[A-Z0-9]+(?:[-.][A-Z0-9]+)*$/iu,Jwe=/文件名\s*[::]?|附件\s*[::]?|路径\s*[::]?|路徑\s*[::]?|文件列表\s*[::]?|文档列表\s*[::]?|文檔列表\s*[::]?|\bfile\s*names?\b\s*[::]?|\battachments?\b\s*[::]?|\bpaths?\b\s*[::]?|\bfile\s+lists?\b\s*[::]?|\bdocument\s+lists?\b\s*[::]?/iu,Xwe=/文件名\s*[::]?|文件\s*[::]?|附件\s*[::]?|档案\s*[::]?|檔案\s*[::]?|文档\s*[::]?|文檔\s*[::]?|资料\s*[::]?|資料\s*[::]?|路径\s*[::]?|路徑\s*[::]?|\bfile\s*name\b\s*[::]?|\battachments?\b\s*[::]?|\bfiles?\b\s*[::]?|\bdocuments?\b\s*[::]?|\bdocs?\b\s*[::]?|\bpaths?\b\s*[::]?/iu,exe=/股票代码|股票代碼|证券代码|證券代碼|(?:代码|代碼|交易所|后缀|後綴|市场|市場)(?=$|[\s::/|,,、()()])|\btickers?\b|\bsymbols?\b|\bexchanges?\b/iu,txe=2e3,nxe=512,ixe={},oxe=new Set(["ai","md","py","rs","sh","zip"]),Kz=new Set(["as","bj","de","hk","l","ln","ny","pa","sh","ss","sz","t","us"]),sxe=new Set([...Kz,"at","ax","cn","co","it","jp","ks","mc","mx","nz","pl","sa","si","to","tw"]),rxe=new Set(["com","dev","io","page","site"]),lxe=new Set(["app","apk","dmg","exe","ipa","lock","log","markdown","webmanifest"]),axe=new Set(["7z","ai","astro","avi","bash","bz2","c","cjs","cpp","cs","csv","doc","docx","fish","flac","gif","go","gz","h","hpp","html","java","jpeg","jpg","js","json","jsx","kt","md","mdx","mjs","mov","mp3","mp4","pdf","php","png","ppt","pptx","ps1","py","rar","rb","rs","sh","sql","svg","swift","svelte","tar","tgz","toml","ts","tsx","txt","vue","wav","webp","xls","xlsx","xml","yaml","yml","zip","zsh"]),Rd=new Map;function XM(e,t){if(!e||e.length>nxe)return t;for(Rd.set(e,t);Rd.size>txe;){const n=Rd.keys().next().value;if(!n)break;Rd.delete(n)}return t}function $0(e){return e?.filename===!0||e?.explicitFilename===!0||e?.marketTicker===!0}function V3(e,t){const n={filename:e?.filename||t?.filename,explicitFilename:e?.explicitFilename||t?.explicitFilename,marketTicker:e?.marketTicker||t?.marketTicker};return $0(n)?n:void 0}function eI(e,t){if(!$0(t))return e;const n=e?.__linkifyDemotionContext;return{...e,__linkifyDemotionContext:{filename:n?.filename||t?.filename,explicitFilename:n?.explicitFilename||t?.explicitFilename,marketTicker:n?.marketTicker||t?.marketTicker}}}function tI(e){const t=yg(e);return $0(t)?t:void 0}function uxe(e){return e.replace(/^[\s>*_`[\]((【《"'“‘]+/u,"").replace(/[\s<*_`\]))】》"'.。;;,,、::!?!?]+$/u,"")}function nI(e,t){if(!$0(t))return;const n=String(e??"").trim().split(/\s+/u).map(uxe).filter(Boolean);if(n.length===0)return;const i={};return t?.filename&&n.every(o=>oy(o,{filename:!0,explicitFilename:t.explicitFilename}))&&(i.filename=!0),t?.explicitFilename&&i.filename&&(i.explicitFilename=!0),t?.marketTicker&&n.every(o=>oy(o,{marketTicker:!0}))&&(i.marketTicker=!0),$0(i)?i:void 0}function Gc(e,t=!1){let n;return{options(i){return t||i==null?eI(e,n):eI(e,V3(tI(i),nI(i,n)))},remember(i){const o=tI(i);n=t?V3(n,o):V3(o,nI(i,n))},reset(){n=void 0}}}function iI(e){return Zwe.test(e)&&!e.startsWith("-")&&!e.endsWith("-")}function cxe(e){const t=e.split(".");if(t.length<2)return!1;const n=t[t.length-1]?.toLowerCase()??"";return iI(n)||Gwe.test(n)?t.every(iI):!1}function Vz(e){return Array.from(e).some(t=>t.charCodeAt(0)>127)}function dxe(e){return e.replace(/^[a-z][a-z0-9+.-]*:\/\//i,"").split(/[/?#]/,1)[0]??""}function fxe(e){return e.split(".").some(t=>t.toLowerCase().startsWith("xn--"))}function Zz(e,t,n){const i=dxe(t);return Vz(e)&&fxe(i)&&String(n??"").toLowerCase().includes(i.toLowerCase())}function hxe(e){if(!e)return!1;if(e.includes("文件")||e.includes("附件")||e.includes("路径")||e.includes("路徑")||e.includes("文档")||e.includes("文檔")||e.includes("档案")||e.includes("檔案")||e.includes("资料")||e.includes("資料")||e.includes("股票")||e.includes("证券")||e.includes("證券")||e.includes("代码")||e.includes("代碼")||e.includes("交易所")||e.includes("后缀")||e.includes("後綴")||e.includes("市场")||e.includes("市場"))return!0;const t=e.toLowerCase();return t.includes("file")||t.includes("attachment")||t.includes("document")||t.includes("doc")||t.includes("path")||t.includes("ticker")||t.includes("symbol")||t.includes("exchange")}function yg(e){const t=String(e??""),n=Rd.get(t);return n?(Rd.delete(t),Rd.set(t,n),n):hxe(t)?XM(t,{explicitFilename:Jwe.test(t),filename:Xwe.test(t),marketTicker:exe.test(t)}):XM(t,ixe)}function pxe(e){return cxe(e.split(/[\\/]/)[0]??"")}function gxe(e){const t=e.replace(/[^a-z]/gi,"");return t.length>=2&&t===t.toUpperCase()}function mxe(e){if(Wwe.test(e)||!Vwe.test(e))return!0;if(Kwe.test(e))return!pxe(e);const t=e.replace(Uz,"");return Vz(t)?!0:t.split(".").filter(Boolean).some(gxe)}function vxe(e,t,n){if(!(n?sxe:Kz).has(t))return!1;const i=e.slice(0,-(t.length+1));return i===""?e.startsWith("."):(n?Ywe:Qwe).test(i)}function oy(e,t={}){if(!e||qwe.test(e)||Uwe.test(e))return!1;const n=e.match(Uz);if(!n)return!1;const i=String(n[1]??"").toLowerCase();return vxe(e,i,t.marketTicker===!0)?!0:axe.has(i)?!oxe.has(i)||t.filename?!0:mxe(e):!!(t.explicitFilename&&rxe.has(i)||t.filename&&lxe.has(i))}const Gz=new WeakMap,Qz=new WeakSet;function B8(e,t){return Gz.set(e,t),e}function yxe(e){return Gz.get(e)}function kxe(e){Qz.add(e)}function bxe(e){return e===void 0||Qz.has(e)}const oI=["!"];function sI(e){return e==="linkify"||e==="autolink"?e:"recovery"}function $r(e){return{type:"text",content:e,raw:e}}function vd(e,t){t===1?e.push({type:"em_open",tag:"em",nesting:1}):t===2?e.push({type:"strong_open",tag:"strong",nesting:1}):t===3&&(e.push({type:"strong_open",tag:"strong",nesting:1}),e.push({type:"em_open",tag:"em",nesting:1}))}function yd(e,t){t===1?e.push({type:"em_close",tag:"em",nesting:-1}):t===2?e.push({type:"strong_close",tag:"strong",nesting:-1}):t===3&&(e.push({type:"em_close",tag:"em",nesting:-1}),e.push({type:"strong_close",tag:"strong",nesting:-1}))}function Ku(e,t,n,i="recovery"){let o="";if(t.includes('"')){const s=t.split('"');t=s[0].trim(),o=s[1].trim()}return B8({type:"link",loading:n,href:t,title:o,text:e,children:[{type:"text",content:e,raw:e}],raw:`[${e}](${t})`},i)}function Axe(e,t){if(!(!e||!t)&&(e.href=String(e.href??"")+t,e.text=String(e.text??"")+t,e.raw=`[${e.text}](${e.href})`,Array.isArray(e.children)&&e.children.length)){const n=e.children[e.children.length-1];n?.type==="text"?(n.content=String(n.content??"")+t,n.raw=String(n.raw??"")+t):e.children.push($r(t))}}function rI(e,t){let n=-1;for(const i of t){const o=e.indexOf(i);o!==-1&&(n===-1||o<n)&&(n=o)}return n}function Cxe(e){const t=e.attrs?.find(n=>n?.[0]==="href")?.[1];return typeof t=="string"?t:""}function wxe(e,t){if(!e)return;e.attrs=Array.isArray(e.attrs)?e.attrs:[];const n=e.attrs.findIndex(i=>i?.[0]==="href");n>=0?e.attrs[n][1]=t:e.attrs.push(["href",t])}function lI(e,t,n){let i="";for(let o=t+1;o<n;o++){const s=e[o];if(s?.type!=="text"||typeof s.content!="string")return null;i+=s.content}return i||null}function aI(e){let t=0;for(let n=0;n<e.length;n++){const i=e[n];if(i==="(")t++;else if(i===")"){if(t===0)return n;t--}}return-1}function xxe(e){e.core.ruler.after("inline","fix_link_tokens",t=>{const n=t.tokens??[];for(let i=0;i<n.length;i++){const o=n[i];if(o&&o.type==="inline"&&Array.isArray(o.children))try{o.children=Sxe(o.children,typeof o.content=="string"?o.content:void 0)}catch(s){console.error("[applyFixLinkTokens] failed to fix inline children",s)}}})}function Sxe(e,t){if(e.length<3)return e;const n=e.some(r=>r.type==="code_inline"),i=new Map;let o=0;for(let r=0;r<e.length;r++){const l=e[r];if(l.type==="link_open"){let a=-1;for(let u=r+1;u<e.length;u++)if(e[u]?.type==="link_close"){a=u;break}if(a!==-1&&l.markup==="linkify"){i.set(l,o);const u=lI(e,r,a),c=o>0&&u?aI(u):-1;if(c!==-1&&u)for(const d of u.slice(c))d==="("?o++:d===")"&&o>0&&o--}a!==-1&&(r=a);continue}if(!(l.type!=="text"||typeof l.content!="string"))for(const a of l.content)a==="("?o++:a===")"&&o>0&&o--}const s=yg(t);for(let r=0;r<=e.length-1;r++){r<0&&(r=0);const l=e[r];if(!l)break;if(l.type==="link_open"&&(l.markup==="linkify"||l.markup==="autolink")){let a=-1;for(let u=r+1;u<e.length;u++)if(e[u]?.type==="link_close"){a=u;break}if(a!==-1){const u=lI(e,r,a),c=Cxe(l);if(!n&&l.markup==="linkify"&&u&&!Zz(u,c,t)&&oy(u,s)){e.splice(r,a-r+1,$r(u));continue}let d=rI(u??"",oI);if(l.markup==="linkify"&&u?.includes(")")&&(i.get(l)??0)>0){const g=aI(u);g!==-1&&(d===-1||g<d)&&(d=g)}const h=rI(c,oI);let p=d;for(let g=r+1;g<a;g++){const m=e[g];if(m?.type!=="text"||typeof m.content!="string")continue;if(p>=m.content.length){p-=m.content.length;continue}if(p<0)break;const k=m.content[p],w=m.content.slice(0,p);let y=m.content.slice(p);for(let T=g+1;T<a;T++){const S=e[T];S?.type==="text"&&typeof S.content=="string"&&(y+=S.content)}m.content=w,m.raw=w;const b=a-(g+1);b>0&&(e.splice(g+1,b),a=g+1);let A=c;if(k==="!"&&h!==-1)A=c.slice(0,h);else if(y){const T=encodeURI(y);if(T&&c.endsWith(T))A=c.slice(0,c.length-T.length);else{const S=k?encodeURI(k):"",x=S?c.indexOf(S):-1;x!==-1&&(A=c.slice(0,x))}}A!==c&&wxe(l,A),y&&e.splice(a+1,0,$r(y));break}}}if(!n){if(l?.type==="em_open"&&e[r-1]?.type==="text"&&e[r-1].content?.endsWith("*")){const a=e[r-1].content?.replace(/(\*+)$/,"")||"";e[r-1].content=a,l.type="strong_open",l.tag="strong",l.markup="**";for(let u=r+1;u<e.length;u++)if(e[u]?.type==="em_close"){e[u].type="strong_close",e[u].tag="strong",e[u].markup="**";break}}else if(l?.type==="text"&&l.content?.endsWith("(")&&e[r+1]?.type==="link_open"){const a=l.content.match(/\[([^\]]+)\]/);if(a){let u=l.content.slice(0,a.index);const c=u.match(/(\*+)$/),d=sI(e[r+1]?.markup),h=[];if(c){u=u.slice(0,c.index),u&&h.push($r(u));const p=a[1],g=c[1].length;vd(h,g);let m=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(m+=e[r+4]?.content||"",e[r+4].content=""),h.push(Ku(p,m,!e[r+4]?.content?.startsWith(")"),d)),yd(h,g),e[r+4]?.type==="text"){const k=e[r+4].content?.replace(/^\)\**/,"");k&&h.push($r(k)),e.splice(r,5,...h)}else e.splice(r,4,...h)}else{u&&h.push($r(u));let p=a[1];const g=p.match(/^\*+/);if(g){const k=g[0].length;p=p.replace(/^\*+/,"").replace(/\*+$/,"");let w=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(w+=e[r+4]?.content||"",e[r+4].content=""),vd(h,k),h.push(Ku(p,w,!e[r+4]?.content?.startsWith(")"),d)),yd(h,k),e[r+4]?.type==="text"){const y=e[r+4].content?.replace(/^\)/,"");y&&h.push($r(y)),e.splice(r,5,...h)}else e.splice(r,4,...h);r===0?r=h.length-1:r-=h.length+1;continue}let m=e[r+2]?.content||"";if(e[r+4]?.type==="text"&&!e[r+4].content?.startsWith(")")&&(m+=e[r+4]?.content||"",e[r+4].content=""),h.push(Ku(p,m,!e[r+4]?.content?.startsWith(")"),d)),e[r+4]?.type==="text"){const k=e[r+4].content?.replace(/^\)/,"");k&&h.push($r(k)),e.splice(r,5,...h)}else e.splice(r,4,...h)}r-=h.length+1;continue}}else if(l.type==="link_open"&&l.markup==="linkify"&&e[r-1]?.type==="text"&&e[r-1].content?.endsWith("(")){if(e[r-2]?.type==="link_close"){const a=[],u=e[r-3].content||"";let c=l.attrs?.find(d=>d[0]==="href")?.[1]||"";if(e[r+3]?.type==="text"){const d=(e[r+3]?.content??"").indexOf(")"),h=d===-1;d===-1&&(c+=e[r+3]?.content?.slice(0,d)||"",e[r+3].content=""),a.push(Ku(u,c,h,"linkify"));const p=e[r+3].content?.replace(/^\)\**/,"");p&&a.push($r(p)),e.splice(r-4,8,...a)}else a.push(B8({type:"link",loading:!0,href:c,title:"",text:u,children:[{type:"text",content:c,raw:c}],raw:`[${u}](${c})`},"linkify")),e.splice(r-4,7,...a);continue}else if(e[r-1].content==="]("&&e[r-3]?.type==="text"&&e[r-3].content?.endsWith(")"))if(e[r-2]?.type==="strong_open"){const[a,u]=e[r-3].content?.split("[**")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}else if(e[r-2]?.type==="em_open"){const[a,u]=e[r-3].content?.split("[*")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}else{const[a,u]=e[r-3].content?.split("[")||[];e[r+1].content=u||"",e[r-3].content=a||"",e[r-1].content=""}}if(l.type==="link_close"&&l.nesting===-1&&e[r-2]?.type==="link_open"&&e[r+1]?.type==="text"&&e[r-1]?.type==="text"){const a=e[r-1].content||"",u=e[r-2].attrs||[],c=u.find(w=>w[0]==="href")?.[1]||"",d=u.find(w=>w[0]==="title")?.[1]||"";let h=3,p=2;const g=(e[r-3]?.content||"").match(/^(\*+)$/),m=[];if(g){p+=1;const w=g[1].length;vd(m,w)}if(l.markup!=="linkify"&&e[r+1].type==="text"&&e[r+1]?.content?.startsWith("](")){h+=1;for(let w=r+1;w<e.length;w++){const y=g?g[1].length:e[r-3].markup.length,b=e[w];if(y===1&&b.type==="em_close")break;if(y===2&&b.type==="strong_close")break;if(y===3&&(b.type==="em_close"||b.type==="strong_close"))break;h+=1}}const k=B8({type:"link",loading:!1,href:c,title:d,text:a,children:[{type:"text",content:a,raw:a}],raw:`[${a}](${c})`},l.markup?sI(l.markup):"explicit");if(m.push(k),g){const w=g[1].length;yd(m,w)}e.splice(r-p,h,...m),r-=m.length+1;continue}else if(l.content?.startsWith("](")&&e[r-1].markup?.includes("*")&&e[r-4]?.type==="text"&&e[r-4].content?.endsWith("[")){const a=e[r-1].markup.length,u=[],c=e[r-4].content.slice(0,e[r-4].content.length-a);c&&u.push($r(c)),vd(u,a);const d=e[r-2].content||"";let h=l.content.slice(2),p=!0;if(e[r+1]?.type==="text"){const g=(e[r+1]?.content??"").indexOf(")");p=g===-1,g===-1&&(h+=e[r+1]?.content?.slice(0,g)||"",e[r+1].content="")}if(u.push(Ku(d,h,p)),yd(u,a),e[r+1]?.type==="text"){const g=e[r+1].content?.replace(/^\)\**/,"");g&&u.push($r(g)),e.splice(r-4,8,...u)}else e[r+1]?.type==="link_open"?e.splice(r-4,10,...u):e.splice(r-4,7,...u);r-=u.length+1;continue}else if(l.content?.startsWith("](")&&e[r-1].type==="strong_close"&&e[r-4]?.type==="text"&&e[r-4]?.content?.includes("**[")){const a=[],u=e[r-4].content.split("**[")[0];u&&a.push($r(u)),vd(a,2);const c=e[r-2].content||"";let d=l.content.slice(2),h=!0;if(e[r+1]?.type==="text"){const p=(e[r+1]?.content??"").indexOf(")");h=p===-1,p===-1&&(d+=e[r+1]?.content?.slice(0,p)||"",e[r+1].content="")}if(a.push(Ku(c,d,h)),yd(a,2),e[r+1]?.type==="text"){const p=e[r+1].content?.replace(/^\)\**/,"");p&&a.push($r(p)),e.splice(r-4,8,...a)}else e[r+1]?.type==="link_open"?e.splice(r-4,10,...a):e.splice(r-4,7,...a);r-=a.length+1;continue}else if(l.type==="strong_close"&&e[r+1]?.type==="text"&&e[r+1].content?.includes("](")&&e[r-1].type==="text"&&/\[.*$/.test(e[r-1].content||"")){const a=[],[u,c]=e[r-1].content?.split("[")||["",""];u&&a.push($r(u)),vd(a,2);let[d,h]=e[r+1].content.split("](");d=c+d;let p=4;if(e[r+2]?.type==="link_open"){const m=e[r+2].attrs?.find(k=>k[0]==="href")?.[1];e[r+5]?.type==="text"&&e[r+5].content==="."?(h=(m||h)+e[r+5].content,e[r+5].content=""):h=m||h,p+=3}let g=!0;if(l.nesting===-1&&(d=d.replace(/\*+$/,"")),e[r+2]?.type==="text"){const m=(e[r+2]?.content??"").indexOf(")");g=m===-1,m===-1&&(h+=e[r+2]?.content?.slice(0,m)||"",e[r+2].content="")}a.push(Ku(d,h,g)),yd(a,2),e.splice(r-2,p,...a)}if(l.type==="text"&&/\*+\[[^\]]*$/.test(l.content||"")&&e[r+1]?.type==="strong_open"&&e[r+2]?.type==="text"&&e[r+2].content==="]("&&e[r+3]?.type==="link_open"&&e[r+5]?.type==="link_close"&&e[r+6]?.type==="text"&&e[r+6].content===")"&&e[r+7]?.type==="strong_close"){const a=(l.content||"").match(/^(\*+)\[(.*)$/);if(a){const u=(a[2]||"")+a[1];let c=e[r+3]?.attrs?.find(h=>h[0]==="href")?.[1]||"";!c&&e[r+4]?.type==="text"&&(c=e[r+4].content||"");const d=[];vd(d,2),d.push(Ku(u,c,!1)),yd(d,2),e.splice(r,9,...d),r-=d.length-1;continue}}}}if(n)return e;for(let r=0;r<e.length-1;r++){const l=e[r],a=e[r+1];if(l?.type!=="link"||a?.type!=="text"||typeof a.content!="string"||!a.content.startsWith("!"))continue;const u=String(l.href??"");if(String(l.text??"")!==u||!u.endsWith("=")&&!u.endsWith("#"))continue;Axe(l,"!");const c=a.content.slice(1);c?(a.content=c,a.raw=c):e.splice(r+1,1)}return e}function _xe(e){e.core.ruler.after("inline","fix_list_item_tokens",t=>{const n=t.tokens??[];for(let i=0;i<n.length;i++){const o=n[i];if(o&&o.type==="inline"&&Array.isArray(o.children))try{o.children=Mxe(o.children)}catch(s){console.error("[applyFixListItem] failed to fix inline children",s)}}})}function Mxe(e){const t=e[e.length-1],n=String(t?.content??"");return t?.type==="text"&&/^\s*\d+\.\s*$/.test(n)&&e[e.length-2]?.tag==="br"&&e.splice(e.length-1,1),e}function Ixe(e){e.core.ruler.after("inline","fix_strong_tokens",t=>{const n=t.tokens??[];for(let i=0;i<n.length;i++){const o=n[i];if(o&&o.type==="inline"&&Array.isArray(o.children))try{o.children=Exe(o.children)}catch(s){console.error("[applyFixStrongTokens] failed to fix inline children",s)}}})}function Exe(e){let t=0;const n=new Set,i=new Set;let o=0;for(let c=0;c<e.length;c++){const d=e[c],h=d.type;if(h==="strong_open"){t++;const p=String(d.markup??"");let g=c-1;for(;g>=0&&e[g].type==="text"&&e[g].content==="";)g--;const m=e[g];let k=c+1;for(;k<e.length&&e[k].type==="text"&&e[k].content==="";)k++;const w=e[k];p==="__"&&(m?.content?.endsWith("_")||w?.content?.startsWith("_")||w?.markup?.includes("_"))&&(d.type="text",d.tag="",d.content=p,d.raw=p,d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null,n.add(t))}else if(h==="strong_close")n.has(t)&&d.markup==="__"&&(d.type="text",d.content=d.markup,d.raw=String(d.markup??""),d.tag="",d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null),t--,t<0&&(t=0);else if(h==="em_open"){o++;const p=String(d.markup??"");let g=c-1;for(;g>=0&&e[g].type==="text"&&e[g].content==="";)g--;const m=e[g];let k=c+1;for(;k<e.length&&e[k].type==="text"&&e[k].content==="";)k++;const w=e[k];p==="_"&&(m?.content?.endsWith("_")||w?.content?.startsWith("_")||w?.markup?.includes("_"))&&(d.type="text",d.tag="",d.content=p,d.raw=p,d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null,i.add(o))}else h==="em_close"&&(i.has(o)&&d.markup==="_"&&(d.type="text",d.content=d.markup,d.raw=String(d.markup??""),d.tag="",d.markup="",d.attrs=null,d.map=null,d.info="",d.meta=null),o--,o<0&&(o=0))}if(e.length<5)return e;const s=e.length-4,r=e[s];let l=[...e];const a=e[s+1],u=String(r.content??"");if(r.type==="link_open"&&e[s-1]?.type==="em_open"&&e[s-2]?.type==="text"&&e[s-2].content?.endsWith("*")){const c=String(e[s-2].content??"").slice(0,-1),d=[{type:"strong_open",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""},e[s],e[s+1],e[s+2],{type:"strong_close",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""}];c&&d.unshift({type:"text",content:c,raw:c}),l.splice(s-2,6,...d)}else if(r.type==="text"&&u.endsWith("*")&&a.type==="em_open"){const c=e[s+2],d=c?.type==="text"?4:3,h=[{type:"strong_open",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""},{type:"text",content:c?.type==="text"?String(c.content??""):"",raw:c?.type==="text"?String(c.content??""):""},{type:"strong_close",tag:"strong",attrs:null,map:null,children:null,content:"",markup:"**",info:"",meta:null,raw:""}],p=u.slice(0,-1);p&&h.unshift({type:"text",content:p,raw:p}),l.splice(s,d,...h)}return l=Txe(l),l}function Txe(e){if(e.length<7)return e;const t=[];for(let n=0;n<e.length;n++){const i=e[n],o=e[n+1],s=e[n+2],r=e[n+3],l=e[n+4],a=e[n+5],u=e[n+6];if(i?.type==="strong_open"&&o?.type==="text"&&s?.type==="strong_close"&&r?.type==="strong_open"&&l?.type==="math_inline"&&a?.type==="strong_close"&&u?.type==="text"){const c=String(u.content??""),d=c.indexOf("**");if(d!==-1){const h=c.slice(0,d),p=c.slice(d+2);t.push(i),t.push(o),t.push(l),h&&t.push({...u,type:"text",content:h,raw:h}),t.push(a),p&&t.push({...u,type:"text",content:p,raw:p}),n+=6;continue}}if(i?.type==="strong_open"&&o?.type==="text"&&s?.type==="strong_close"&&r?.type==="strong_open"&&l?.type==="math_inline"&&a?.type==="strong_close"){const c=Lxe(e,n+6);if(c){t.push(i),t.push(o),t.push(l);for(let d=n+6;d<c.index;d++)t.push(e[d]);c.beforeClose&&t.push({...e[c.index],type:"text",content:c.beforeClose,raw:c.beforeClose}),t.push(a),c.afterClose&&t.push({...e[c.index],type:"text",content:c.afterClose,raw:c.afterClose}),n=c.index;continue}}t.push(i)}return t}function Lxe(e,t){for(let n=t;n<e.length;n++){const i=e[n];if(i?.type==="strong_open")return null;if(i?.type!=="text")continue;const o=String(i.content??""),s=o.indexOf("**");if(s!==-1)return{index:n,beforeClose:o.slice(0,s),afterClose:o.slice(s+2)}}return null}function Nxe(e){e.core.ruler.after("block","fix_table_tokens",t=>{const n=t;try{const i=zxe(n.tokens??[],!!n.env?.__markstreamFinal,n.src??"");Array.isArray(i)&&(n.tokens=i)}catch(i){console.error("[applyFixTableTokens] failed to fix table tokens",i)}})}function uI(){return[{type:"table_open",tag:"table",attrs:null,map:null,children:null,content:"",markup:"",info:"",level:0,loading:!0,meta:null},{type:"thead_open",tag:"thead",attrs:null,block:!0,level:1,children:null},{type:"tr_open",tag:"tr",attrs:null,block:!0,level:2,children:null}]}function cI(){return[{type:"tr_close",tag:"tr",attrs:null,block:!0,level:2,children:null},{type:"thead_close",tag:"thead",attrs:null,block:!0,level:1,children:null},{type:"table_close",tag:"table",attrs:null,map:null,children:null,content:"",markup:"",info:"",level:0,meta:null}]}function dI(e){return[{type:"th_open",tag:"th",attrs:null,block:!0,level:3,children:null},{type:"inline",tag:"",children:null,content:e,level:4,attrs:null,block:!0},{type:"th_close",tag:"th",attrs:null,block:!0,level:3,children:null}]}function Yz(e,t){if(!e.startsWith("|")||e.includes(` -`)||!e.endsWith("|"))return null;const n=e.slice(1).split("|");return n.at(-1)===""&&n.pop(),n.length>0&&n.every(i=>i.trim().length>0)?n:null}function Z3(e){return Yz(e)!==null}function Jz(e){return/^:?-+:?$/.test(e.trim())}function Fxe(e){if(!e.startsWith("|"))return!1;const t=e.slice(1).split("|");return t.at(-1)===""&&t.pop(),t.length>0&&t.every(Jz)}function Dxe(e){return/^(?:[::]-*|:?-+:?)?$/.test(e.trim())}function Bxe(e){if(e==="")return!0;if(!e.startsWith("|"))return!1;const t=e.slice(1).split("|"),n=t.at(-1)??"";return t.slice(0,-1).every(Jz)&&Dxe(n)}function $xe(e){return e==="|"||e==="|:"}function Rxe(e){const t=Yz(e);return t!==null&&t.every(n=>!n.includes(":"))}function zxe(e,t=!1,n=""){const i=[...e];if(e.length<3)return i;const o=e.length-2,s=e[o];if(s.type==="inline"){const r=String(s.content??""),l=r.split(` -`)[0]??"",[a="",u="",...c]=r.split(` -`),d=!t&&!r.includes(` -`)&&/\r?\n$/.test(n)&&Z3(r);if(!t&&(r.includes(` -`)&&c.length===0&&Z3(a)&&Bxe(u)||d)){const h=l.slice(1,-1).split("|").map(g=>g.trim()).flatMap(g=>dI(g)),p=[...uI(),...h,...cI()];i.splice(o-1,3,...p)}else if(r.includes(` -`)&&c.length===0&&Z3(a)&&Fxe(u)){const h=l.slice(1,-1).split("|").map(g=>g.trim()).flatMap(g=>dI(g)),p=[...uI(),...h,...cI()];i.splice(o-1,3,...p)}else r.includes(` -`)&&c.length===0&&Rxe(a)&&$xe(u)&&(s.content=r.slice(0,-2),s.children.splice(2,1))}return i}function Oxe(e,t,n,i){const o=e.length;if(n==="$$"&&i==="$$"){let u=t;for(;u<o-1;){if(e[u]==="$"&&e[u+1]==="$"){let c=u-1,d=0;for(;c>=0&&e[c]==="\\";)d++,c--;if(d%2===0)return u}u++}return-1}const s=n[n.length-1],r=i;let l=0,a=t;for(;a<o;){if(e.slice(a,a+r.length)===r){let c=a-1,d=0;for(;c>=0&&e[c]==="\\";)d++,c--;if(d%2===0){if(l===0)return a;l--,a+=r.length;continue}}const u=e[a];if(u==="\\"){a+=2;continue}u===s?l++:u===r[r.length-1]&&l>0&&l--,a++}return-1}var Pxe=Oxe;const jxe=["boldsymbol","mathbb","mathcal","mathfrak","mathrm","mathit","mathsf","vec","hat","bar","tilde","overline","underline","mathscr","mathnormal","operatorname","mathbf*"],sy=jxe.map(e=>e.replace(/[.*+?^${}()|[\\]"\]/g,"\\$&")).join("|"),Hxe=/\\[a-z]+/i,Xz="(?:\\\\|\\u0008)",Wxe=new RegExp(String.raw`${Xz}(?:${sy})\s*\{[^}]+\}`,"i"),qxe=new RegExp(String.raw`(?:${Xz})?(?:${sy})\s*\{`,"i"),Uxe=/\\(?:text|frac|left|right|times)/,Kxe=/(?:^|[^+])\+(?!\+)|[=\-*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/,Vxe=/\b[A-Z]{2,}-[A-Z]{2,}\b/i,Zxe=/[A-Z]+\s*\([^)]+\)/i,Gxe=/^\(\s*[a-z](?:\s*,\s*[a-z])+\s*\)$/i,Qxe=/\b(?:sin|cos|tan|log|ln|exp|sqrt|frac|sum|lim|int|prod)\b/,Yxe=/\b\d{4}\/\d{1,2}\/\d{1,2}(?:[ T]\d{1,2}:\d{2}(?::\d{2})?)?\b/,Jxe={"\b":"\\b","\v":"\\v","\f":"\\f"};function Xxe(e){let t="";for(const n of e)t+=Jxe[n]??n;return t}function ac(e){if(!e)return!1;const t=Xxe(e),n=t.trim();if(Yxe.test(n)||n.includes("**"))return!1;if(n.length>2e3)return!0;const i=Hxe.test(t),o=Wxe.test(t),s=qxe.test(t),r=Uxe.test(t),l=/(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)_(?:\{[^}]+\}|[A-Z0-9\\])/i.test(t)||/(?:^|[^\w\\])(?:[A-Z]|\\[A-Z]+)\^(?:\{[^}]+\}|[A-Z0-9\\])/i.test(t),a=Kxe.test(t)&&!Vxe.test(t),u=Zxe.test(t),c=Gxe.test(n),d=Qxe.test(t),h=/^\([a-z]\)$/i.test(n)||/^(?:[a-z]|pi)$/i.test(n),p=/^(?:[A-Z][a-z]?(?:_\{?\d+\}?|\^\{?\d+\}?)?)+$/.test(n);return i||o||s||r||l||a||u||c||d||h||p}const eO="__markstreamMathPluginApplied",$8=80,tO=2e4,fI=tO+4096;function S7(e){return!!e[eO]}function eSe(e){e[eO]=!0}const nO=["ldots","cdots","quad","in","displaystyle","int_","lim","lim_","ce","pu","end","infty","perp","mid","operatorname","to","rightarrow","leftarrow","math","mathrm","mathit","mathbb","mathcal","mathfrak","implies","alpha","beta","gamma","delta","epsilon","lambda","sum","sum_","prod","sqrt","fbox","boxed","color","rule","edef","fcolorbox","hline","hdashline","cdot","times","pm","le","ge","neq","sin","cos","tan","log","ln","exp","frac","text","left","right"],tSe=["cdot","mathbf{","partial","mu_{"],iO=nO.slice().sort((e,t)=>t.length-e.length).map(e=>e.replace(/[.*+?^${}()|[\\]\\\]/g,"\\$&")).join("|"),oO="[ \r\b\f\v]",nSe=new RegExp(`([^\\\\])(${tSe.map(e=>e).join("|")})+`,"g"),iSe=/span\{([^}]+)\}/,oSe=/\\operatorname\{span\}\{((?:[^{}]|\{[^}]*\})+)\}/,sSe=/(^|[^\\])\\\r?\n/g,rSe=/(^|[^\\])\\$/g,lSe=/[\p{L}\p{M}\p{N}\p{Pe}\p{Pf}'′″‴|‖]/u,aSe=new RegExp(`(${oO})|(${iO})\\b`,"g"),hI=new Map,pI=new Map;function uSe(e){if(!e)return aSe;const t=[...e];t.sort((r,l)=>l.length-r.length);const n=t.join(""),i=hI.get(n);if(i)return i;const o=`(?:${t.map(r=>r.replace(/[.*+?^${}()|[\\]\\"\]/g,"\\$&")).join("|")})`,s=new RegExp(`(${oO})|(${o})\\b`,"g");return hI.set(n,s),s}function cSe(e,t){const n=e?[]:[...t??[]];e||n.sort((l,a)=>a.length-l.length);const i=e?"__default__":n.join(""),o=pI.get(i);if(o)return o;const s=e?[sy,iO].filter(Boolean).join("|"):[n.map(l=>l.replace(/[.*+?^${}()|[\\]\\\]/g,"\\$&")).join("|"),sy].filter(Boolean).join("|"),r=new RegExp(`(^|[^\\\\\\w])(${s})\\s*\\{`,"g");return pI.set(i,r),r}const gI={" ":"t","\r":"r","\b":"b","\f":"f","\v":"v"};function mI(e){const t=/(^|[^\\])(__|\*\*)/g;let n=0;for(;t.exec(e)!==null;)n++;return n}function dSe(e){return e.replace(/(^|[^\\])!+/gu,(t,n)=>{if(n&&lSe.test(n))return t;const i=n?t.slice(n.length):t;return`${n}${"\\!".repeat(i.length)}`})}function vI(e){const t=/(^|[^\\])(__|\*\*)/g;let n,i=null;for(;(n=t.exec(e))!==null;)i={marker:n[2],index:n.index+(n[1]?.length??0)};return i}function Vu(e,t){const n=t?.commands??nO,i=t?.escapeExclamation??!0,o=t?.commands==null,s=uSe(o?void 0:n);let r=e.replace(s,(u,c,d,h,p)=>{if(c!==void 0&&gI[c]!==void 0)return`\\${gI[c]}`;if(d&&n.includes(d)){const g=p&&typeof h=="number"?p[h-1]:void 0;return g==="\\"||g&&/\w/.test(g)?u:`\\${d}`}return u});i&&(r=dSe(r));let l=r;const a=cSe(o,o?void 0:n);return l=l.replace(a,(u,c,d)=>`${c}\\${d}{`),l=l.replace(iSe,"span\\{$1\\}").replace(oSe,"\\operatorname{span}\\{$1\\}"),l=l.replace(sSe,`$1\\\\ -`),l=l.replace(rSe,"$1\\\\"),l=l.replace(nSe,"$1\\$2"),l}function yI(e){const t=e.trim();return!(!ac(t)||/"[^"\n]{1,80}"\s*:\s*/.test(t)||!(/\\[a-z]+/i.test(t)||/[=+*/^<>]|\\times|\\pm|\\cdot|\\le|\\ge|\\neq/.test(t)||/[_^]/.test(t))&&/\s-\s/.test(t))}function sO(e){const t=[];let n=0;for(;n<e.length;){if(e[n]!=="`"){n++;continue}const i=n;let o=1;for(;i+o<e.length&&e[i+o]==="`";)o++;let s=i+o,r=-1;for(;s<e.length;){if(e[s]!=="`"){s++;continue}let l=1;for(;s+l<e.length&&e[s+l]==="`";)l++;if(l===o){r=s;break}s+=l}if(r!==-1){t.push([i,r+o]),n=r+o;continue}n=i+o}return t}function ry(e,t){for(const n of e)if(t>=n[0]&&t<n[1])return n;return null}function fSe(e,t=!1){const n=[];let i=0;for(;i<e.length-1;){if(e[i]==="!"&&e[i+1]==="["){const o=i;let s=i+2,r=1;for(;s<e.length&&r>0;){if(e[s]==="\\"&&s+1<e.length){s+=2;continue}e[s]==="["?r++:e[s]==="]"&&r--,s++}if(r===0&&s<e.length&&e[s]==="("){let l=s+1,a=1;for(;l<e.length&&a>0;){if(e[l]==="\\"&&l+1<e.length){l+=2;continue}e[l]==="("?a++:e[l]===")"&&a--,l++}if(a===0){n.push([o,l]),i=l;continue}if(t){n.push([o,e.length]),i=e.length;continue}}}i++}return n}function kg(e,t){let n=t-1,i=0;for(;n>=0&&e[n]==="\\";)i++,n--;return i%2===1}function R8(e,t){let n=t;for(;n<e.length;){const i=e.indexOf("$",n);if(i===-1)return-1;if(kg(e,i)){n=i+1;continue}return i}return-1}function G3(e,t){let n=t;for(;n<e.length;){const i=R8(e,n);if(i===-1)return-1;if(i>0&&e[i-1]==="$"||i+1<e.length&&e[i+1]==="$"){n=i+1;continue}return i}return-1}function lh(e,t,n=0){let i=Math.max(0,n);for(;i<e.length;){const o=e.indexOf(t,i);if(o===-1)return-1;if(!kg(e,o))return o;i=o+Math.max(1,t.length)}return-1}function kI(e,t,n=0,i=e.length,o=[]){let s=0,r=Math.max(0,n);const l=Math.min(e.length,Math.max(0,i));for(;r<l;){const a=e.indexOf(t,r);if(a===-1||a>=l)break;const u=ry(o,a);if(u){r=Math.max(a+Math.max(1,t.length),u[1]);continue}kg(e,a)||s++,r=a+Math.max(1,t.length)}return s}function _7(e,t,n){const i=z0(String(e??""));if(!i.endsWith(t))return-1;const o=i.length-t.length;if(o<=0||!z0(i.slice(0,o)).trim()||kg(i,o))return-1;const s=sO(i);if(ry(s,o))return-1;const r=kI(i,t,0,o,s);if(t==="$$"){if(r%2===1)return-1}else if(r>kI(i,n,0,o,s))return-1;return o}function R0(e){return e===" "||e===" "}function z0(e){let t=e.length;for(;t>0&&R0(e[t-1]);)t--;return e.slice(0,t)}function bI(e){let t=0;for(let n=0;n<e.length;n++)e[n]===` -`&&t++;return t}function AI(e){if(!e)return!1;const t=e.charCodeAt(0);return t>=48&&t<=57}function hSe(e){if(e.length<3)return!1;const t=e[0];if(t!=="-"&&t!=="*"&&t!=="_"&&t!=="=")return!1;let n=0;for(let i=0;i<e.length;i++){const o=e[i];if(o===t){n++;continue}if(!R0(o))return!1}return n>=3}function pSe(e){const t=e.trim();if(!t)return!1;let n=0;t[n]===":"&&n++;let i=0;for(;t[n]==="-";)i++,n++;return i<3?!1:(t[n]===":"&&n++,n===t.length)}function gSe(e){if(!e.includes("|"))return!1;const t=e[0]==="|"?e.slice(1):e;return(t.endsWith("|")?t.slice(0,-1):t).split("|").every(pSe)}function mSe(e){let t=0;if(!AI(e[t]))return!1;for(;AI(e[t]);)t++;return e[t]!=="."&&e[t]!==")"?!1:R0(e[t+1])}function rO(e){const t=e.trimStart();if(!t||t.startsWith("```")||t.startsWith("~~~")||t.startsWith(":::")||t[0]===">"||t[0]==="<")return!0;if(t[0]==="#"){let n=0;for(;t[n]==="#";)n++;if(n>=1&&n<=6&&R0(t[n]))return!0}return!!((t[0]==="-"||t[0]==="+"||t[0]==="*")&&R0(t[1])||mSe(t)||hSe(t)||gSe(t))}function CI(e,t){return e?t?`${e} -${t}`:e:t}function z8(e){const t=String(e??"").trim();return t?ac(t):!1}function wI(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)|0;return t.toString(36)}function lO(e){if(e.length<=fI)return{source:e,lineOffset:0};let t=e.length-fI;const n=e.indexOf(` -`,t);return n===-1?{source:"",lineOffset:bI(e)}:(t=n+1,{source:e.slice(t),lineOffset:bI(e.slice(0,t))})}function aO(e){const t=String(e??"");if(!t||!t.includes("$$")&&!t.includes("\\["))return!1;const{source:n}=lO(t);if(!n)return!1;const i=n.split(/\r?\n/),o=Math.max(0,i.length-$8-2),s=[["$$","$$"],["\\[","\\]"]];for(let r=o;r<i.length;r++){const l=z0(i[r]);if(l&&!rO(l)){for(const[a,u]of s)if(_7(l,a,u)!==-1)return!0}}return!1}function vSe(e){const t=String(e??"");if(!t||!t.includes("$$")&&!t.includes("\\["))return null;const{source:n,lineOffset:i}=lO(t);if(!n)return null;const o=n.split(/\r?\n/),s=Math.max(0,o.length-$8-2),r=[["$$","$$"],["\\[","\\]"]];for(let l=s;l<o.length-1;l++){const a=z0(o[l]);for(const[u,c]of r){const d=_7(a,u,c);if(d===-1)continue;let h="",p=!1;for(let g=l+1;g<o.length;g++){if(g-l>$8){p=!0;break}const m=o[g],k=lh(m,c);if(k!==-1){const w=CI(h,m.slice(0,k));if(!z8(w)){p=!0;break}const y=m.slice(k+c.length),b=y.trim()?`suffix:${wI(y)}`:"nosuffix";return["closed",u,i+l,d,i+g,k,wI(w),b].join(":")}if(rO(m)){p=!0;break}if(h=CI(h,m),h.length>tO){p=!0;break}}if(!p&&z8(h))return["pending",u,i+l,d].join(":")}}return null}function Q3(e,t){const n=String(e??"").trim();return!n||!/^\d[\d,.]*\s*[~~-]\s*$/.test(n)?!1:/\d/.test(String(t??""))}function ySe(e){const t=String(e??"").trimStart(),n=t.match(/^\d+(?:,\d{3})*(?:\.\d+)?/);if(!n)return!1;const i=t.slice(n[0].length);return/^\s*(?:[+\-*/^_=<>]|\\[a-z]+)/i.test(i)?!1:i===""||/^[)\s,.!?;:]/.test(i)}function Y3(e){const t=String(e??"").trim();return t?/^(?:\.{3,}|…+)$/.test(t):!1}function kSe(e,t){eSe(e);const n=(r,l,a)=>{const u=String(l??"").replace(/^[\t ]+/,"").replace(/[\t ]+$/,"");if(!u)return;const c=r.push("paragraph_open","p",1);c.map=[a,a+1];const d=r.push("inline","",0);d.content=u,d.map=[a,a+1],d.children=[],r.push("paragraph_close","p",-1)},i=(r,l)=>{const a=r,u=!!t?.strictDelimiters,c=!a?.env?.__markstreamFinal,d=(y,b)=>{let A=b;for(;A<y.length&&(y[A]===" "||y[A]===" ");)A++;if(A===b||!(y[A]===` -`||y[A]==="\r"&&y[A+1]===` -`))return b;const T=y.slice(b,A),S=a.push("text","",0);return S.content=T,A};if(/^\*[^*]+/.test(a.src))return!1;if(a.src[a.pos]==="$"){let y=a.pos+1;for(;a.src[y]==="$";)y++;const b=y-a.pos,A=a.src[y];if(b>=3&&(!A||/\s/.test(A))){const T=a.push("text","",0);return T.content=a.src.slice(a.pos,y),a.pos=y,!0}}const h=[["$$","$$"],["$","$"],["\\(","\\)"]],p=String(a.pending??""),g=Math.max(0,a.pos-p.length);let m=g,k=g;const w=g;for(const[y,b]of h){const A=a.src,T=sO(A),S=fSe(A,c);let x=!1;y==="$$"&&m!==w&&(m=w);let _=-1,L=-1,M=0;const N=I=>{if((I==="undefined"||I==null)&&(I=""),I==="\\"){a.pos=a.pos+I.length,m=a.pos;return}if(I==="\\)"||I==="\\("){const O=a.push("text_special","",0);O.content=I==="\\)"?")":"(",O.markup=I,a.pos=a.pos+I.length,m=a.pos;return}if(!I)return;if(y==="$$"&&I.includes("$")){let O=0;for(;O<I.length;){const R=R8(I,O);if(R===-1){const q=I.slice(O);if(q){const ne=a.push("text","",0);ne.content=q,a.pos=a.pos+q.length,m=a.pos}break}if(R>0&&I[R-1]==="$"||R+1<I.length&&I[R+1]==="$"){const q=I.slice(O,R+1);if(q){const ne=a.push("text","",0);ne.content=q,a.pos=a.pos+q.length,m=a.pos}O=R+1;continue}const j=I.slice(O,R);if(j){const q=a.push("text","",0);q.content=j,a.pos=a.pos+j.length,m=a.pos}const $=G3(I,R+1);if($===-1){const q=I.slice(R),ne=a.push("text","",0);ne.content=q,a.pos=a.pos+q.length,m=a.pos;break}const W=I.slice(R+1,$),P=W.includes("`"),Z=!W||!W.trim(),ae=I[$+1],V=Q3(W,ae),Y=Y3(W);if(!P&&!Z&&!V&&!Y){const q=a.push("math_inline","math",0);q.content=Vu(W,t),q.markup="$",q.raw=`$${W}$`,q.loading=!1,a.pos=a.pos+($-R+1),m=a.pos,O=$+1;continue}const oe=a.push("text","",0);oe.content="$",a.pos=a.pos+1,m=a.pos,O=R+1}return}const z=I.indexOf("![");if(z!==-1){if(z>0){const j=I.slice(0,z),$=a.push("text","",0);$.content=j,a.pos=a.pos+j.length,m=a.pos}const O=I.slice(z).match(/^!\[([^\]]*)\]\(([^)]+)\)/);if(O){const[,j,$]=O,W=$.match(/^(\S+)(?:\s+"([^"]+)")?\s*$/),P=W?W[1]:$,Z=W&&W[2]?W[2]:null,ae=a.push("image","img",0);ae.attrs=[["src",P],["alt",j]],Z&&ae.attrs.push(["title",Z]),ae.content=j,ae.children=[{type:"text",content:j,tag:""}],a.pos=a.pos+O[0].length,m=a.pos;const V=I.slice(z+O[0].length);V&&N(V);return}const R=a.push("text","",0);R.content=I,a.pos=a.pos+I.length,m=a.pos;return}const H=a.push("text","",0);H.content=I,a.pos=a.pos+I.length,m=a.pos};for(;!(m>=A.length);){const I=A.indexOf(y,m);if(I===-1)break;if(kg(A,I)){m=I+Math.max(1,y.length);continue}const z=ry(T,I);if(z){m=z[1];continue}const H=ry(S,I);if(H){m=H[1];continue}if(I===_&&m===L){if(M++,M>2){m=I+Math.max(1,y.length);continue}}else M=0,_=I,L=m;if(y==="("&&I>0){let V=I-1;for(;V>=0&&A[V]===" ";)V--;if(V>=0&&A[V]==="]"){m=I+y.length;continue}}if(y==="$"&&I>0&&A[I-1]==="$"){m=I+1;continue}if(y==="$"&&I<A.length-1&&A[I+1]==="$"){m=I+2;continue}const O=y==="$"?G3(A,I+y.length):Pxe(A,I+y.length,y,b);if(O===-1){const V=A.slice(I+y.length);if(V.includes(y)){m=A.indexOf(y,I+y.length);continue}if(O===-1){const Y=y==="$"&&ySe(V);if(c&&!u&&!Y&&ac(V)&&!V.includes("`")){if(m=I+y.length,x=!0,!l){a.pending="";const oe=k?A.slice(k,m):A.slice(0,m),q=mI(oe)%2===1;if(k)N(A.slice(k,m));else{let ne=A.slice(0,m);ne.endsWith(y)&&(ne=ne.slice(0,ne.length-y.length)),N(ne)}if(q){const ne=vI(oe)?.marker??"**",ie=a.push("strong_open","",0);ie.markup=ne;const pe=a.push("math_inline","math",0);pe.content=Vu(V,t),pe.markup=y==="$$"?"$$":y==="\\("?"\\(\\)":y==="$"?"$":"()",pe.raw=`${y}${V}${b}`,pe.loading=!0,ie.content=V,a.push("strong_close","",0)}else{const ne=a.push("math_inline","math",0);ne.content=Vu(V,t),ne.markup=y==="$$"?"$$":y==="\\("?"\\(\\)":y==="$"?"$":"()",ne.raw=`${y}${V}${b}`,ne.loading=!0}a.pos=A.length}m=A.length,k=m}break}}const R=A.slice(I+y.length,O),j=R.includes("`"),$=!R||!R.trim(),W=y==="$",P=A[O+b.length],Z=W&&Q3(R,P),ae=W&&Y3(R);if(u?j||$||Z||ae:j||$||Z||ae||!W&&!ac(R)){m=O+b.length;const V=A.slice(a.pos,m);a.pending||(N(V),k=m);continue}if(x=!0,!l){const V=A.slice(a.pos-(a.pending??"").length,I);let Y=A.slice(0,m)?A.slice(k,I):V;const oe=mI(Y)%2===1;I!==a.pos&&oe&&(Y=a.pending+A.slice(a.pos,I));const q=oe?vI(Y):null,ne=q?.marker??"**";if(a.pending!==Y)if(a.pending="",oe)if(q){const ie=Y.slice(q.index+ne.length);N(Y.slice(0,q.index));const pe=a.push("strong_open","",0);pe.markup=ne;const Ne=a.push("text","",0);Ne.content=ie,a.push("strong_close","",0)}else N(Y);else N(Y);if(oe){const ie=a.push("strong_open","",0);ie.markup=ne;const pe=a.push("math_inline","math",0);pe.content=Vu(R,t),pe.markup=y==="$$"?"$$":y==="\\("?"\\(\\)":y==="$"?"$":"()",pe.raw=`${y}${R}${b}`,pe.loading=!1;const Ne=A.slice(O+b.length).startsWith(ne);return Ne&&a.push("strong_close","",0),a.pos=d(A,O+b.length),m=a.pos,k=m,Ne||a.push("strong_close","",0),!0}else{const ie=a.push("math_inline","math",0);ie.content=Vu(R,t),ie.markup=y==="$$"?"$$":y==="\\("?"\\(\\)":y==="$"?"$":"()",ie.raw=`${y}${R}${b}`,ie.loading=!1}}return m=d(A,O+b.length),k=m,a.pos=m,!0}if(x){if(l)a.pos=m;else{if(y==="$$"&&m<A.length&&A.slice(m).includes("$")){let I=m;for(;!(I>=A.length);){const z=R8(A,I);if(z===-1)break;if(z+1<A.length&&A[z+1]==="$"){I=z+2;continue}if(z>0&&A[z-1]==="$"){I=z+1;continue}const H=G3(A,z+1);if(H===-1)break;const O=A.slice(z+1,H),R=O.includes("`"),j=!O||!O.trim(),$=A[H+1],W=Q3(O,$),P=Y3(O);if(!R&&!j&&!W&&!P){const Z=A.slice(m,z);Z&&N(Z);const ae=a.push("math_inline","math",0);ae.content=Vu(O,t),ae.markup="$",ae.raw=`$${O}$`,ae.loading=!1,m=H+1,I=H+1}else N("$"),I=z+1}I<A.length&&N(A.slice(I))}else m<A.length&&N(A.slice(m));a.pos=A.length}return!0}}return!1},o=(r,l,a,u)=>{const c=r,d=!c?.env?.__markstreamFinal,h=t?.strictDelimiters,p=h?[["\\[","\\]"],["$$","$$"]]:[["\\[","\\]"],["[","]"],["$$","$$"]],g=c.bMarks[l]+c.tShift[l];let m=c.src.slice(g,c.eMarks[l]).trim(),k=!1,w="",y="",b=!1,A="",T=!1;for(const[Z,ae]of p)if(m.startsWith(Z))if(Z.includes("[")){const V=Z==="\\["?m.slice(Z.length):"";if(Z==="\\["&&lh(V,ae)===-1&&!/^\s*!\[/.test(V)&&!V.includes("`")&&ac(V)){k=!0,w=Z,y=ae;break}if(t?.strictDelimiters){if(m.replace("\\","")==="["){if(l+1<a){k=!0,w=Z,y=ae;break}continue}}else if(m.replace("\\","")==="["){if(l+1<a){k=!0,w=Z,y=ae;break}continue}else{const Y=c.tokens[c.tokens.length-1];if(Y&&Y.type==="list_item_open"&&Y.mark==="-"&&m.slice(Z.length,m.indexOf("]")).trim()==="x")continue;if(m.replace("\\","").startsWith("[")&&!m.includes("](")){const oe=m.indexOf("]");if(m.slice(oe).trim()!=="]")continue;const q=m.slice(Z.length,oe);if(Z==="["?yI(q):ac(q)){k=!0,w=Z,y=ae;break}continue}}}else{k=!0,w=Z,y=ae;break}else if((Z==="$$"||Z==="\\[")&&m.endsWith(Z)&&l+1<a){const V=_7(m,Z,ae);if(V===-1)continue;A=z0(m.slice(0,V)),T=!0;const Y=c.bMarks[l+1]+c.tShift[l+1];m=c.src.slice(Y,c.eMarks[l+1]).trim(),b=!0,k=!0,w=Z,y=ae;break}if(!k)return!1;if(u&&!T)return!0;const S=m.indexOf(w),x=S+w.length,_=!h&&w==="["?m.indexOf("\\]",x):-1,L=_>=0?"\\]":y,M=_>=0?_:lh(m,y,x);if(!b&&M>w.length){const Z=m.slice(S+w.length,M),ae=c.push("math_block","math",0);ae.content=Vu(Z),ae.markup=w==="$$"?"$$":w==="["?"[]":"\\[\\]",ae.map=[l,l+1],ae.raw=`${w}${Z}${L}`,ae.block=!0,ae.loading=!1,c.line=l+1;const V=m.slice(M+L.length);return V.trim()&&n(c,V,l),!0}let N=l,I="",z=!1,H="",O=l;const R=b?m:m===w?"":m.slice(w.length),j=!h&&w==="\\["?"]":"",$=lh(R,y);if($!==-1){const Z=$;I=R.slice(0,Z),H=R.slice(Z+y.length),O=b?l+1:l,z=!0,N=O}else for(R&&!b&&(I=R),N=l+1;N<a;N++){const Z=c.bMarks[N]+c.tShift[N],ae=c.eMarks[N],V=c.src.slice(Z,ae),Y=V.trim();if(!h&&w==="["&&Y==="\\]"){y="\\]",z=!0;break}if(j&&V.trim()===j){y=j,z=!0;break}if(Y===y){z=!0;break}else if(!h&&w==="["&&V.includes("\\]")){z=!0;const oe=V.indexOf("\\]");y="\\]";const q=V.slice(0,oe);q&&(I+=(I?` -`:"")+q),H=V.slice(oe+y.length),O=N;break}else if(lh(V,y)!==-1){z=!0;const oe=lh(V,y),q=V.slice(0,oe);q&&(I+=(I?` -`:"")+q),H=V.slice(oe+y.length),O=N;break}I+=(I?` -`:"")+V}if((!d||h)&&!z)return!1;const W=/^\s*!\[/.test(I);if(!(T?!W&&z8(I):w==="$$"?!W:w==="["?yI(I):ac(I)))return!1;if(u)return!0;A&&n(c,A,l);const P=c.push("math_block","math",0);return P.content=Vu(I),P.markup=w==="$$"?"$$":w==="["?"[]":"\\[\\]",P.raw=`${w}${I}${I.startsWith(` -`)?` -`:""}${y}`,P.map=[l,N+1],P.block=!0,P.loading=!z,c.line=N+1,H.trim()&&n(c,H,O),!0},s=(r,l,a,u)=>{const c=r,d=c.bMarks[l]+c.tShift[l],h=c.src.slice(d,c.eMarks[l]).trim();return!h.startsWith("$$")&&!h.startsWith("\\[")?!1:o(r,l,a,u)};e.inline.ruler.before("escape","math",i),e.block.ruler.before("lheading","explicit_math_block",s,{alt:["paragraph","reference","blockquote","list"]}),e.block.ruler.before("paragraph","math_block",o,{alt:["paragraph","reference","blockquote","list"]})}function bSe(e){const t=e.renderer.rules.image||function(n,i,o,s,r){const l=n,a=r;return a.renderToken?a.renderToken(l,i,o):""};e.renderer.rules.image=(n,i,o,s,r)=>{const l=n;return l[i].attrSet?.("loading","lazy"),t(l,i,o,s,r)},e.renderer.rules.fence=e.renderer.rules.fence||((n,i)=>{const o=n[i],s=String(o.info??"").trim();return`<pre class="${s?`language-${e.utils.escapeHtml(s.split(/\s+/g)[0])}`:""}"><code>${e.utils.escapeHtml(String(o.content??""))}</code></pre>`})}const ASe=/^<a[>\s]/i,CSe=/^<\/a\s*>/i;function wSe(e,t){if(e?.type!=="inline")return!1;const n=e.children;if(!Array.isArray(n)||n.length===0)return t.test(String(e.content??""));let i=0;for(let o=n.length-1;o>=0;o--){const s=n[o];if(s?.type==="link_close"){for(o--;o>=0&&n[o]?.level!==s.level&&n[o]?.type!=="link_open";)o--;continue}if(s?.type==="html_inline"){const r=String(s.content??"");ASe.test(r)&&i>0&&i--,CSe.test(r)&&i++}if(!(i>0)&&s?.type==="text"&&t.test(String(s.content??"")))return!0}return!1}function xSe(e){const t=e.core?.ruler,n=t.getNamedRules?.().find(i=>i.name==="linkify")?.fn;typeof n=="function"&&t.at("linkify",i=>{if(!i.md?.options?.linkify)return;const o=Array.isArray(i.tokens)?i.tokens:[],s=i.md.linkify;if(!s)return;const r=o.filter(l=>wSe(l,s));if(r.length)return n(Object.assign(Object.create(Object.getPrototypeOf(i)),i,{tokens:r}))})}function SSe(e){const t=e.inline.ruler,n=t.getNamedRules?.(),i=n?.find(l=>l.name==="link")?.fn,o=n?.find(l=>l.name==="image")?.fn;if(typeof i!="function"||typeof o!="function")return;const s=e.validateLink,r=e;r.__markstreamOriginalValidateLink=s,t.at("link",(...l)=>{const a=l[0].md,u=a?.validateLink===s?a.options?.validateLink:a?.validateLink;if(!a||typeof u!="function")return i(...l);const c=a.validateLink;a.validateLink=u;try{return i(...l)}finally{a.validateLink=c}}),t.at("image",(...l)=>{const a=l[0].md;if(!a)return o(...l);const u=a.validateLink;a.validateLink=s;try{return o(...l)}finally{a.validateLink=u}})}function _Se(e={}){const t=e.markdownItOptions??{},n=typeof t.experimental=="object"&&t.experimental!==null?t.experimental:{},i=Object.prototype.hasOwnProperty.call(t,"stream")?!!t.stream:!0,o=Object.prototype.hasOwnProperty.call(t,"validateLink"),s=new XCe({html:!0,linkify:!0,typographer:!0,...t,experimental:{stream:i,...n}});if(!o){const r=l=>!Gd(l,{tagName:"a",attrName:"href"});kxe(r),s.set({validateLink:r})}return SSe(s),xSe(s),(e.enableMath??!0)&&kSe(s,{...e.mathOptions??{}}),(e.enableContainers??!0)&&kwe(s),e.enableFixIndentedCodeBlock!==!1&&Hwe(s),xxe(s),Ixe(s),_xe(s),Nxe(s),bSe(s),Pwe(s,{customHtmlTags:e.customHtmlTags}),s}function Qd(e){const t=Object.assign(Object.create(Object.getPrototypeOf(e)),e);return Array.isArray(e.attrs)&&(t.attrs=e.attrs.map(n=>[...n])),Array.isArray(e.map)&&(t.map=[...e.map]),Array.isArray(e.children)&&(t.children=e.children.map(n=>Qd(n))),t}function MSe(e){const t=e.meta??{};return{type:"checkbox",checked:t.checked===!0,raw:t.checked?"[x]":"[ ]"}}function ISe(e){const t=e,n=t.attrGet?t.attrGet("checked"):void 0,i=n===""||n==="true";return{type:"checkbox_input",checked:i,raw:i?"[x]":"[ ]"}}function ESe(e){const t=String(e.content??"");return{type:"emoji",name:t,markup:String(e.markup??""),raw:`:${t}:`}}function Um(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="em_close";){const l=e[s];o+=String(e[s].content??l.text??""),r.push(e[s]),s++}return i.push(...Ao(r,void 0,void 0,n)),{node:{type:"emphasis",children:i,raw:`*${o}*`},nextIndex:s<e.length?s+1:e.length}}function TSe(e,t){return new RegExp(`\r? -[ \\t]*${e}{${t},}[ \\t]*$`)}const uO=["diff ","index ","--- ","+++ ","@@ "],LSe=/\r?\n/;function NSe(e){const t=String(e??"");return t?uO.some(n=>n.startsWith(t)||t.startsWith(n)):!1}function xI(e,t,n,i){n.length>0&&e.push(...n),i.length>0&&t.push(...i),n.length=0,i.length=0}function SI(e,t){return!t&&e.startsWith(" ")&&!e.startsWith(" ")?` ${e}`:e}function FSe(e,t){const n=[],i=[],o=[],s=[],r=e.split(LSe),l=/\r?\n$/.test(e),a=r.some(p=>p.startsWith("diff ")||p.startsWith("--- ")||p.startsWith("+++ ")||p.startsWith("@@ ")),u=p=>{const g=p;if(!uO.some(m=>g.startsWith(m)))if(g.startsWith("-")){const m=g.slice(1);o.push(SI(m,a))}else if(g.startsWith("+")){const m=g.slice(1);s.push(SI(m,a))}else{xI(n,i,o,s);const m=a&&g.startsWith(" ")?g.slice(1):g;n.push(m),i.push(m)}},c=l?Math.max(0,r.length-1):r.length;for(let p=0;p<c;p++){const g=r[p]??"";!t&&!l&&p===c-1&&NSe(g)||u(g)}(t||o.length>0||s.length>0)&&xI(n,i,o,s);const d=n.join(` -`),h=i.join(` -`);return{original:t&&l&&d?`${d} -`:d,updated:t&&l&&h?`${h} -`:h}}function M7(e){const t=Array.isArray(e.map)&&e.map.length===2,n=e.meta??{},i=typeof n.closed=="boolean"?n.closed:void 0,o=i===!0||i!==!1&&t,s=String(e.info??""),r=s.startsWith("diff"),l=r?(()=>{const u=s,c=u.indexOf(" ");return c===-1?"":String(u.slice(c+1)??"")})():s;let a=String(e.content??"");if(!o&&e.markup){const u=e.markup[0],c=e.markup.length,d=TSe(u,c);d.test(a)&&(a=a.replace(d,""))}if(r){const{original:u,updated:c}=FSe(a,o===!0);return{type:"code_block",language:l,code:String(c??""),raw:String(a??""),diff:r,loading:i===!0?!1:i===!1?!0:!t,originalCode:u,updatedCode:c}}return{type:"code_block",language:l,code:String(a??""),raw:String(a??""),diff:r,loading:i===!0?!1:i===!1?!0:!t}}function DSe(e){const t=e.meta??{};return{type:"footnote_reference",id:String(t.label??""),raw:`[^${String(t.label??"")}]`}}function BSe(){return{type:"hardbreak",raw:`\\ -`}}function $Se(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="mark_close";)o+=String(e[s].content??""),r.push(e[s]),s++;return i.push(...Ao(r,void 0,void 0,n)),{node:{type:"highlight",children:i,raw:`==${o}==`},nextIndex:s<e.length?s+1:e.length}}let J3=null;const X3=new WeakMap;function _I(){return J3||(J3={customTagSet:null,allowedTagSet:T9()}),J3}function cO(e){const t=e.match(/^<\s*(?:\/\s*)?([\w-]+)/);return t?t[1].toLowerCase():""}function dO(e){return/^<\s*\//.test(e)}function fO(e,t){return/\/\s*>\s*$/.test(t)||Tc.has(e)}function RSe(e){if(!e||e.length===0)return _I();const t=X3.get(e);if(t)return t;const n=e.map(zl).filter(Boolean);if(!n.length){const o=_I();return X3.set(e,o),o}const i={customTagSet:new Set(n),allowedTagSet:T9({customHtmlTags:e})};return X3.set(e,i),i}function hO(e){const t=e,n=t.raw??t.content??t.markup??"";return String(n??"")}function zSe(e){const t=e.meta,n=t?.markstreamCustomHtmlRaw,i=t?.markstreamCustomHtmlInner;return typeof n=="string"&&typeof i=="string"?{raw:n,inner:i}:null}function ly(e,t){const n=t.toLowerCase();for(let i=e.length-1;i>=0;i--){const[o,s]=e[i];if(String(o).toLowerCase()===n)return s}}function OSe(e,t,n){const i=e.slice();return ly(i,"href")||i.push(["href",t]),n!=null&&!ly(i,"title")&&i.push(["title",n]),i}function O8(e){return e.map(hO).join("")}function Lv(e){const t=[],n=i=>{const o=String(i??"");if(!o)return;const s=t[t.length-1];if(s?.type==="text"){s.content=`${s.content}${o}`,s.raw=`${s.raw}${o}`;return}t.push({type:"text",content:o,raw:o})};for(const i of e)if(i){if(i.type==="reference"||i.type==="footnote_reference"){n(String(i.raw??""));continue}if("children"in i&&Array.isArray(i.children)){t.push({...i,children:Lv(i.children)});continue}t.push(i)}return t}function PSe(e,t,n){let i=0;for(let o=t;o<e.length;o++){const s=e[o];if(s.type!=="html_inline")continue;const r=String(s.content??""),l=cO(r),a=dO(r),u=fO(l,r);if(!a&&!u&&l===n){i++;continue}if(a&&l===n){if(i===0)return o;i--}}return-1}function ek(e,t,n){const i=[e[t]];let o=[],s=t+1,r=!1;const l=n?PSe(e,t+1,n):-1;return l!==-1?(o=e.slice(t+1,l),i.push(...o,e[l]),s=l+1,r=!0):(o=e.slice(t+1),o.length&&i.push(...o),s=e.length),{closed:r,html:O8(i),innerTokens:o,nextIndex:s}}function jSe(e,t,n,i,o,s,r){const l=String(e.content??""),a=cO(l),{customTagSet:u,allowedTagSet:c}=RSe(r?.customHtmlTags);if(!a)return[{type:"inline_code",code:l,raw:l},n+1];if(!c.has(a)&&!ek(t,n,a).closed){const T=hO(e);return[{type:"text",content:T,raw:T},n+1]}if(a==="br")return[{type:"hardbreak",raw:l},n+1];const d=dO(l),h=fO(a,l);if(d)return[{type:"html_inline",tag:a,content:l,children:[],raw:l,loading:!1},n+1];if(a==="a"){const T=ek(t,n,a),S=_9(l),x=T.innerTokens,_=String(ly(S,"href")??""),L=ly(S,"title"),M=L==null?null:String(L),N=OSe(S,_,M),I=Lv(x.length?i(x,o,s,r):[]),z=x.length?O8(x):_||"";return!I.length&&z&&I.push({type:"text",content:z,raw:z}),[{type:"link",href:_,title:M,text:z,attrs:N,children:I,loading:!T.closed,raw:T.html||l},T.nextIndex]}if(h)return[{type:u?.has(a)?a:"html_inline",tag:a,content:l,children:[],raw:l,loading:!1},n+1];const p=ek(t,n,a);if(a==="p"||a==="div")return[{type:"paragraph",children:Lv(p.innerTokens.length?i(p.innerTokens,o,s,r):[]),raw:p.html},p.nextIndex];const g=Lv(p.innerTokens.length?i(p.innerTokens,o,s,r):[]);let m=p.html||l,k=!p.closed,w=!1;if(!p.closed){const T=`</${a}>`;m.toLowerCase().includes(T.toLowerCase())||(m+=T),w=!0,k=!0}const y=[],b=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let A;for(;(A=b.exec(l))!==null;){const T=A[1],S=A[2]||A[3]||A[4]||"";y.push([T,S])}if(u?.has(a)){const T=zSe(e);return[{type:a,tag:a,attrs:y,content:T?T.inner:p.innerTokens.length?O8(p.innerTokens):"",children:p.innerTokens.length?i(p.innerTokens,o,s,r):[],raw:T?.raw??m,loading:e.loading||k,autoClosed:w},p.nextIndex]}return[{type:"html_inline",tag:a,attrs:y,content:m,children:g,raw:m,loading:k,autoClosed:w},p.nextIndex]}function pO(e){if(e.type==="math_inline"){if(e.raw)return String(e.raw);const t=e.markup==="$$"?"$$":"$";return`${t}${String(e.content??"")}${t}`}return Array.isArray(e.children)&&e.children.length>0?e.children.map(t=>pO(t)).join(""):String(e.content??"")}function HSe(e){return!e||!Array.isArray(e.children)||e.children.length===0?"":e.children.map(t=>pO(t)).join("")}function MI(e,t=!1){let n=e.attrs??[],i=null;if((!n||n.length===0)&&Array.isArray(e.children))for(const d of e.children){const h=d.attrs;if(Array.isArray(h)&&h.length>0){n=h,i=d;break}}const o=String(n.find(d=>d[0]==="src")?.[1]??""),s=n.find(d=>d[0]==="alt")?.[1],r=HSe(i??e);let l="";r?l=r:s!=null&&String(s).length>0?l=String(s):i?.content!=null&&String(i.content).length>0?l=String(i.content):Array.isArray(i?.children)&&i.children[0]?.content?l=String(i.children[0].content):Array.isArray(e.children)&&e.children[0]?.content?l=String(e.children[0].content):e.content!=null&&String(e.content).length>0&&(l=String(e.content));const a=n.find(d=>d[0]==="title")?.[1]??null,u=a===null?null:String(a),c=String(e.content??"");return{type:"image",src:o,alt:l,title:u,raw:c,loading:t}}function WSe(e){const t=String(e.content??"");return{type:"inline_code",code:t,raw:t}}function qSe(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="ins_close";)o+=String(e[s].content??""),r.push(e[s]),s++;return i.push(...Ao(r,void 0,void 0,n)),{node:{type:"insert",children:i,raw:`++${String(o)}++`},nextIndex:s<e.length?s+1:e.length}}function USe(e){const t=[];if(!Array.isArray(e))return t;for(const n of e){const i=n?.[0];i&&t.push([String(i),String(n?.[1]??"")])}return t}function ay(e,t){const n=t.toLowerCase();for(let i=e.length-1;i>=0;i--){const[o,s]=e[i];if(String(o).toLowerCase()===n)return s}}function KSe(e,t,n){const i=e.slice();return ay(i,"href")||i.push(["href",t]),n!=null&&!ay(i,"title")&&i.push(["title",n]),i}function Km(e,t,n){const i=e[t],o=USe(i.attrs),s=String(ay(o,"href")??""),r=ay(o,"title"),l=r==null?null:String(r),a=KSe(o,s,l);let u=t+1;const c=[];let d=!0;for(;u<e.length&&e[u].type!=="link_close";)c.push(e[u]),u++;e[u]?.type==="link_close"&&(d=!1);let h=c;const p=c[c.length-1];if(n?.__insideStrong&&p?.type==="text"&&String(p.content??"").endsWith("**")&&!c.some(k=>k.type==="strong_open")){const k=String(p.content??""),w=String(p.raw??k),y=Qd(p);y.content=k.slice(0,-2),y.raw=w.replace(/\*\*$/,""),h=c.slice(),h[h.length-1]=y}const g=Ao(h,void 0,void 0,n),m=g.map(k=>{const w=k;return"content"in k?String(w.content??""):String(w.raw??"")}).join("");return{node:{type:"link",href:s,title:l,text:m,children:g,raw:`[${m}](${s}${l?` "${l}"`:""})`,loading:d,attrs:a},nextIndex:u<e.length?u+1:e.length}}function II(e){const t=e.content??"",n=e.raw==="$$"?`$${t}$`:e.raw||"";return{type:"math_inline",content:t,loading:!!e.loading,raw:n,markup:e.markup}}function VSe(e){return{type:"reference",id:String(e.content??""),raw:String(e.markup??`[${e.content??""}]`)}}function EI(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="s_close";)o+=String(e[s].content??""),r.push(e[s]),s++;return i.push(...Ao(r,void 0,void 0,n)),{node:{type:"strikethrough",children:i,raw:`~~${o}~~`},nextIndex:s<e.length?s+1:e.length}}const ZSe=/\\([\\()[\]`$|*_\-!])/g;function GSe(e,t){if(!e)return;const n=String(e);if(n&&(n===t||n.replace(ZSe,"$1")===t))return n}function Z1(e,t,n,i){const o=[];let s="",r=t+1;const l=[];let a=1;for(;r<e.length;){if(e[r].type==="strong_close"){if(a===1)break;a--}e[r].type==="strong_open"&&a++,s+=String(e[r].content??""),l.push(e[r]),r++}const u={...i,__insideStrong:!0};return o.push(...Ao(l,GSe(n,s),void 0,u)),{node:{type:"strong",children:o,raw:`**${String(s)}**`},nextIndex:r<e.length?r+1:e.length}}function QSe(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="sub_close";)o+=String(e[s].content??""),r.push(e[s]),s++;i.push(...Ao(r,void 0,void 0,n));const l=String(e[t].content??""),a=o||l;return{node:{type:"subscript",children:i.length>0?i:[{type:"text",content:a,raw:a}],raw:`~${a}~`},nextIndex:s<e.length?s+1:e.length}}function YSe(e,t,n){const i=[];let o="",s=t+1;const r=[];for(;s<e.length&&e[s].type!=="sup_close";)o+=String(e[s].content??""),r.push(e[s]),s++;return i.push(...Ao(r,void 0,void 0,n)),{node:{type:"superscript",children:i.length>0?i:[{type:"text",content:o||String(e[t].content??""),raw:o||String(e[t].content??"")}],raw:`^${o||String(e[t].content??"")}^`},nextIndex:s<e.length?s+1:e.length}}function JSe(e){const t=String(e.content??"");return{type:"text",content:t,raw:t}}const XSe=/[^~]*~{2,}[^~]+/,e_e=/\*\*/,t_e=/[[_*^~]/,n_e=/\\([\\()[\]`$|*_\-!])/g,I7=new Set(["\\","(",")","[","]","`","$","|","*","_","-","!"]),i_e=/\s/u,o_e=/[!"#$%&'()*+,\-./:;<=>?@[\\\]^_`{|}~]/,s_e=/\p{P}/u,r_e=/^[\x22\x27《「『【〔〖〘〚〈([{“‘﹁﹃﹙﹛﹝]$/u,l_e=/^[\x22\x27》」』】〕〗〙〛〉)]}”’﹂﹄﹚﹜﹞]$/u,a_e=/^(?:https?:\/\/|mailto:|ftp:\/\/)/i,u_e=/:\/\//,P8=1,gO=2,c_e=4,d_e=8,mO=16,ec=32,Nv=64,wp=128,vO=256,f_e=512,xp=1024,h_e=1982;function Vm(e){let t=0;for(let n=0;n<e.length;n++)switch(e.charCodeAt(n)){case 33:t|=wp;break;case 36:t|=vO;break;case 40:t|=xp;break;case 42:t|=gO;break;case 91:t|=ec;break;case 92:t|=P8;break;case 93:t|=Nv;break;case 95:t|=c_e;break;case 96:t|=mO;break;case 124:t|=f_e;break;case 126:t|=d_e;break}return t}function p_e(e){let t=0,n=0;for(;n<e.length;){if(e[n]==="\\"&&n+1<e.length&&e[n+1]==="*"){n+=2;continue}e[n]==="*"&&t++,n++}return t}function yO(e,t=0){if(!e)return-1;let n=0;for(let i=0;i<e.length;i++){const o=e[i],s=e[i+1];if(o==="\\"&&s&&I7.has(s)){if(s==="*"&&n>=t){n++,i++;continue}n++,i++;continue}if(o==="*"&&n>=t)return n;n++}return-1}function Lc(e){return!!e&&i_e.test(e)}function Nc(e){return!!e&&(o_e.test(e)||s_e.test(e))}function kO(e,t){return!!e&&!!t&&/^\p{Script=Han}$/u.test(t)&&r_e.test(e)}function bO(e,t){return!!e&&!!t&&/^[\p{L}\p{N}]$/u.test(t)&&l_e.test(e)}function g_e(e,t){const n=t>0?e[t-1]:void 0,i=e[t+1];return!i||Lc(i)?!1:!(Nc(i)&&!kO(i,n)&&n&&!Lc(n)&&!Nc(n))}function m_e(e,t){const n=t>0?e[t-1]:void 0,i=e[t+1];return!n||Lc(n)?!1:!(Nc(n)&&!bO(n,i)&&i&&!Lc(i)&&!Nc(i))}function v_e(e,t,n=0){let i=n,o=!1;for(;i<t.length;){const s=e?yO(e,i):t.indexOf("*",i);if(s===-1)break;if(m_e(t,s))return{index:s,sawInvalidClose:o};o=!0,i=s+1}return{index:-1,sawInvalidClose:o}}function y_e(e,t){const n=t>0?e[t-1]:void 0,i=e[t+2];return!i||Lc(i)?!1:!(Nc(i)&&!kO(i,n)&&n&&!Lc(n)&&!Nc(n))}function k_e(e,t){const n=t>0?e[t-1]:void 0,i=e[t+2];return!n||Lc(n)?!1:!(Nc(n)&&!bO(n,i)&&i&&!Lc(i)&&!Nc(i))}function b_e(e,t=0){let n=t,i=!1;for(;n<e.length;){const o=e.indexOf("**",n);if(o===-1)break;if(k_e(e,o))return{index:o,sawInvalidClose:i};i=!0,n=o+2}return{index:-1,sawInvalidClose:i}}function A_e(e){let t="",n=0;for(;n<e.length;){if(e[n]!=="\\"){t+=e[n],n++;continue}let i=0;for(;n+i<e.length&&e[n+i]==="\\";)i++;const o=e[n+i];if(t+="\\".repeat(Math.floor(i/2)),i%2===1){if(o&&I7.has(o)){t+=o,n+=i+1;continue}t+="\\"}n+=i}return t}function C_e(e,t){let n=0;for(let i=0;i<e.length;i++){const o=e[i],s=e[i+1];if(o==="\\"&&s&&I7.has(s)){if(n===t)return i+1;n++,i++;continue}if(n===t)return i;n++}return-1}function w_e(e,t,n){const i=C_e(e,t);if(i===-1||e[i]!==n)return!1;let o=0;for(let s=i-1;s>=0&&e[s]==="\\";s--)o++;return o%2===1}const x_e=/[\p{L}\p{N}]/u,S_e=/^[\p{L}\p{N}]+$/u;function j8(e){return e?x_e.test(e):!1}function AO(e){return e?S_e.test(e):!1}function Kp(e,t){let n=t;for(;n<e.length&&e[n]==="*";)n++;const i=t>0?e[t-1]:void 0,o=n<e.length?e[n]:void 0;return{len:n-t,prev:i,next:o,intraword:j8(i)&&j8(o)}}function __e(e){const t=[];for(let n=0;n<e.length;){if(e[n]!=="*"){n++;continue}const i=Kp(e,n),o=n+i.len;i.len>=2&&i.intraword&&t.push({start:n,end:o}),n=o}for(let n=0;n<t.length-1;n++){const i=t[n],o=t[n+1];if(!AO(e.slice(i.end,o.start)))return o.end}return-1}function M_e(e){return!!e&&e.trim()===e&&/^[\p{L}\p{N}\s]+$/u.test(e)}function I_e(e,t){let n=t;for(;n<e.length;){const i=e.indexOf("***",n);if(i===-1)return-1;const o=Kp(e,i);if(o.len>=3)return i;n=i+o.len}return-1}function E_e(e){return e?a_e.test(e)||u_e.test(e):!1}function T_e(e,t){if(!e||!t)return null;const n=e.match(/\[([^\]\n]+)\]\(([^)]*)$/);return n&&n[2]===t?n[1]:null}function Ao(e,t,n,i){if(!e||e.length===0)return[];const o=i?.__linkifyDemotionContext,s=yg(t),r={filename:o?.filename||s.filename,explicitFilename:o?.explicitFilename||s.explicitFilename,marketTicker:o?.marketTicker||s.marketTicker};(r.filename||r.explicitFilename||r.marketTicker)&&(i={...i,__linkifyDemotionContext:r});const l=i,a=[];let u=null,c=0;const d=i?.requireClosingStrong,h=e;function p(){return e===h&&(e=e.slice()),e}function g(){u=null}function m(te,be){const Q=e.length===1?t:String(be.content??""),ue=[],Ae=__e(te);if(Ae!==-1){T(te.slice(0,Ae),te.slice(0,Ae));const re=te.slice(Ae);return re&&(N({type:"text",content:re,raw:re}),c--),c++,!0}if(XSe.test(te)){const re=te.indexOf("~~");re!==-1&&ue.push({type:"strikethrough",index:re})}if(e_e.test(te)){const re=te.indexOf("**");re!==-1&&ue.push({type:"strong",index:re})}if(/[^*]*\*[^*]+/.test(te)){const re=Q?yO(Q,0):te.indexOf("*");if(Q&&re===-1)return!1;re!==-1&&ue.push({type:"emphasis",index:re})}ue.sort((re,G)=>re.index!==G.index?re.index-G.index:re.type===G.type?0:re.type==="strong"?-1:G.type==="strong"?1:0);const se=ue[0];if(!se)return!1;if(se.type==="strikethrough"){const re=se.index,G=re>-1?te.slice(0,re):"";if(G&&T(G,G),re===-1)return c++,!0;const le=te.indexOf("~~",re+2),ge=le===-1?te.slice(re+2):te.slice(re+2,le),ke=le===-1?"":te.slice(le+2),{node:Ie}=EI([{type:"s_open",tag:"s",content:"",markup:"~~",info:"",meta:null},{type:"text",tag:"",content:ge,markup:"",info:"",meta:null},{type:"s_close",tag:"s",content:"",markup:"~~",info:"",meta:null}],0,i);return g(),A(Ie),ke&&(N({type:"text",content:ke,raw:ke}),c--),c++,!0}if(se.type==="strong"){const re=se.index,G=re>-1?te.slice(0,re):"";if(G&&T(G,G),re===-1)return c++,!0;if(t&&re===0){let we=!1,Be=0;for(;Be<te.length&&te[Be]==="*";)Be++;if(t.startsWith("\\*")&&(we=!0),we){let tt=0,ut=0;for(;ut<t.length&&tt<Be;)if(t[ut]==="\\"&&ut+1<t.length&&t[ut+1]==="*")tt+=1,ut+=2;else{if(t[ut]==="*")break;ut++}if(tt>=2)return T(te,te),c++,!0}}if(t&&(te.match(/\*/g)||[]).length>p_e(t))return T(te.slice(G.length),te.slice(G.length)),c++,!0;const le=Kp(te,re);if(le.len>=3){const we=I_e(te,re+le.len);if(we!==-1){const Be=te.slice(re+le.len,we);if(M_e(Be)){const{node:tt}=Z1([{type:"strong_open",tag:"strong",content:"",markup:"**",info:"",meta:null},{type:"em_open",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"text",tag:"",content:Be,markup:"",info:"",meta:null},{type:"em_close",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"strong_close",tag:"strong",content:"",markup:"**",info:"",meta:null}],0,t,i);g(),A(tt);const ut=te.slice(we+3);return ut&&(N({type:"text",content:ut,raw:ut}),c--),c++,!0}}}if(!y_e(te,re)){const we=te.slice(re,re+le.len);T(we,we);const Be=te.slice(re+le.len);return Be&&(N({type:"text",content:Be,raw:Be}),c--),c++,!0}const ge=b_e(te,re+2);let ke="",Ie="";if(ge.index!==-1){ke=te.slice(re+2,ge.index),Ie=te.slice(ge.index+2);const we=ge.index,Be=Kp(te,we);if(le.intraword&&Be.intraword&&!AO(ke)||!ke&&le.len>=4&&le.intraword)return T(te.slice(G.length),te.slice(G.length)),c++,!0}else{if(d||ge.sawInvalidClose||le.intraword)return T(te.slice(G.length),te.slice(G.length)),c++,!0;ke=te.slice(re+2),Ie=""}if(!ke&&/^\*+$/.test(Ie))return T(te,te),c++,!0;const{node:Oe}=Z1([{type:"strong_open",tag:"strong",content:"",markup:"**",info:"",meta:null},{type:"text",tag:"",content:ke,markup:"",info:"",meta:null},{type:"strong_close",tag:"strong",content:"",markup:"**",info:"",meta:null}],0,t,i);return g(),A(Oe),Ie&&(N({type:"text",content:Ie,raw:Ie}),c--),c++,!0}if(se.type==="emphasis"){let re=se.index;re===-1&&(re=0);const G=te.slice(0,re);if(G&&T(G,G),!g_e(te,re)){T(te[re],te[re]);const we=te.slice(re+1);return we&&(N({type:"text",content:we,raw:we}),c--),c++,!0}const le=Kp(te,re),ge=v_e(Q,te,re+1),ke=ge.index,Ie=e[c+1];if(i?.final&&Ie?.type==="em_open"&&ke!==-1&&te.slice(re+1,ke).trim()!==te.slice(re+1,ke)||ke===-1&&(ge.sawInvalidClose||i?.final||le.intraword||!j8(te[re+1])))return T(te.slice(re),te.slice(re)),c++,!0;const{node:Oe}=Um([{type:"em_open",tag:"em",content:"",markup:"*",info:"",meta:null},{type:"text",tag:"",content:ke>-1?te.slice(re+1,ke):te.slice(re+1),markup:"",info:"",meta:null},{type:"em_close",tag:"em",content:"",markup:"*",info:"",meta:null}],0,i);if(g(),A(Oe),ke!==-1&&ke<te.length-1){const we=te.slice(ke+1);we&&(N({type:"text",content:we,raw:we}),c--)}return c++,!0}return!1}function k(te,be){if(!te.includes("`"))return!1;const ue=(Ie=>{for(let Oe=0;Oe<Ie.length;Oe++){if(Ie[Oe]!=="`")continue;let we=0;for(let Be=Oe-1;Be>=0&&Ie[Be]==="\\";Be--)we++;if(we%2===0)return Oe}return-1})(te);if(ue===-1)return!1;let Ae=1;for(let Ie=ue+1;Ie<te.length&&te[Ie]==="`";Ie++)Ae++;const se="`".repeat(Ae),re=ue+Ae,G=te.indexOf(se,re);if(G===-1){if(Ae===1){const Oe=te.slice(0,ue),we=te.slice(ue+1);return Oe&&(m(Oe,be)?c--:T(Oe,Oe)),y({type:"inline_code",code:we,raw:String(we)}),c++,!0}let Ie=te;for(let Oe=c+1;Oe<e.length;Oe++)Ie+=String((e[Oe].content??"")+(e[Oe].markup??""));return c=e.length-1,T(Ie,Ie),c++,!0}g();const le=te.slice(0,ue),ge=te.slice(ue+Ae,G),ke=te.slice(G+Ae);return le&&(m(le,be)?c--:T(le,le)),y({type:"inline_code",code:ge,raw:String(ge??"")}),ke&&(N({type:"text",content:ke,raw:ke}),c--),c++,!0}function w(te){const be=l?.__markdownIt;if(!be||e.length<=1||!e.some(se=>se?.type==="math_inline")||!t_e.test(te))return null;const Q=be.parseInline(te,{__markstreamFinal:!!i?.final});if(!Array.isArray(Q)||Q.length===0)return null;const ue=(Q.find(se=>se?.type==="inline")?.children??[]).filter(se=>!(se?.type==="text"&&String(se.content??"")===""));if(!ue.length||!ue.some(se=>se?.type!=="text")||ue.length===1&&ue[0]?.type==="text"&&String(ue[0].content??"")===te)return null;const Ae=Ao(ue,te,n,i);return Ae.length?Ae:null}function y(te){g(),a.push(te)}function b(te){g();const be=Qd(te);a.push(be)}function A(te){y(te)}function T(te,be){u?(u.content+=te,u.raw+=be??te):(u={type:"text",content:String(te??""),raw:String(be??te??"")},a.push(u))}function S(te,be){if(!te)return;const Q=Ao([{...be,type:"text",content:te,raw:te}],te,n,i);if(Q.length===1&&Q[0]?.type==="text"){const ue=Q[0];T(String(ue.content??""),String(ue.raw??ue.content??""));return}for(const ue of Q)A(ue)}function x(te,be){return String(te.markup??"").startsWith(be)}function _(te){if(!u||te.loading!==!0||te.markup!=="\\(\\)")return;const be=e[c-1];!be||be.type!=="text"||!x(be,"\\(")||u.content.endsWith("(")&&(u.content=u.content.slice(0,-1),u.raw.endsWith("(")&&(u.raw=u.raw.slice(0,-1)),!u.content&&a[a.length-1]===u&&(a.pop(),u=null))}function L(te){return te.endsWith("](")?e[c+1]?.type==="link_open"&&e[c+1]?.markup==="linkify"&&e[c+2]?.type==="text"&&e[c+3]?.type==="link_close"&&e[c+4]?.type==="text"&&String(e[c+4]?.content??"").startsWith(")"):!1}function M(te,be,Q=Vm(te)){let ue=te;const Ae=String(be.content??"");return(Q&P8)!==0&&ue.endsWith("\\")&&!x(be,"\\\\")&&!Ae.endsWith("\\\\")&&(ue=ue.slice(0,-1)),(Q&xp)!==0&&ue.endsWith("(")&&!x(be,"\\(")&&!Ae.endsWith("\\(")&&(ue=ue.slice(0,-1)),(Q&gO)!==0&&/\*+$/.test(ue)&&!x(be,"\\*")&&!Ae.endsWith("\\*")&&(ue=ue.replace(/\*+$/,"")),ue}for(;c<e.length;){const te=e[c];N(te)}function N(te){switch(te.type){case"text":z(te);break;case"softbreak":u?(u.content+=` -`,u.raw+=` -`):(u={type:"text",content:` -`,raw:` -`},a.push(u)),c++;break;case"code_inline":A(WSe(te)),c++;break;case"html_inline":{const[be,Q]=jSe(te,e,c,Ao,t,n,i);A(be),c=Q;break}case"link_open":H(te);break;case"image":Y(te)||(g(),A(MI(te)),c++);break;case"strong_open":{g();const{node:be,nextIndex:Q}=Z1(e,c,te.content,i);A(be),c=Q;break}case"em_open":{g();const{node:be,nextIndex:Q}=Um(e,c,i);A(be),c=Q;break}case"s_open":{g();const{node:be,nextIndex:Q}=EI(e,c,i);A(be),c=Q;break}case"mark_open":{g();const{node:be,nextIndex:Q}=$Se(e,c,i);A(be),c=Q;break}case"ins_open":{g();const{node:be,nextIndex:Q}=qSe(e,c,i);A(be),c=Q;break}case"sub_open":{g();const{node:be,nextIndex:Q}=QSe(e,c,i);A(be),c=Q;break}case"sup_open":{g();const{node:be,nextIndex:Q}=YSe(e,c,i);A(be),c=Q;break}case"sub":g(),A({type:"subscript",children:[{type:"text",content:String(te.content??""),raw:String(te.content??"")}],raw:`~${String(te.content??"")}~`}),c++;break;case"sup":g(),A({type:"superscript",children:[{type:"text",content:String(te.content??""),raw:String(te.content??"")}],raw:`^${String(te.content??"")}^`}),c++;break;case"emoji":{g();const be=e[c-1];be?.type==="text"&&/\|:-+/.test(String(be.content??""))?T("",""):A(ESe(te)),c++;break}case"checkbox":g(),A(MSe(te)),c++;break;case"checkbox_input":g(),A(ISe(te)),c++;break;case"footnote_ref":g(),A(DSe(te)),c++;break;case"footnote_anchor":{g();const be=te.meta??{};y({type:"footnote_anchor",id:String(be.label??te.content??""),raw:String(te.content??"")}),c++;break}case"hardbreak":g(),A(BSe()),c++;break;case"fence":g(),A(M7(e[c])),c++;break;case"math_inline":_(te),g(),!te.content&&te.markup==="$"&&e[c+1]?.type==="text"&&e[c+2]?.type==="math_inline"?(A(II({...te,content:e[c+1].content})),c+=2):A(II(te)),c++;break;case"reference":R(te);break;case"text_special":T(String(te.content??""),String(te.content??"")),c++;break;default:{const be=te;if(te.type==="link"&&be.href!=null&&i?.validateLink&&!i.validateLink(String(be.href))){g();const Q=String(be.text??"");T(Q,Q),c++}else oe(te)||$(te)||P(te)||j(te)||b(te),c++;break}}}function I(te,be,Q,ue,Ae=Vm(te)){const se=JSe({...be,content:te});if(u){u.content+=i?.final?se.content:M(se.content,be,Ae),u.raw+=se.raw;return}const re=Q?.tag==="br"&&e[c-2]?.content==="[";ue||(se.content=i?.final?se.content:M(se.content,be,Ae)),u=se,u.center=re,a.push(u)}function z(te){const be=String(te.content??""),Q=Vm(be),ue=(Q&P8)!==0,Ae=e.length===1&&ue&&typeof t=="string"?String(t):"";let se=Ae?A_e(Ae):ue?be.replace(n_e,"$1"):be;const re=se===be?Q:Vm(se);if(te.content==="<"||se==="1"&&e[c-1]?.tag==="br"){c++;return}const G=(re&vO)!==0?se.indexOf("$"):-1;G!==-1&&G===se.lastIndexOf("$")&&se.endsWith("$")&&(se=se.slice(0,-1)),se.endsWith("undefined")&&!t?.endsWith("undefined")&&(se=se.slice(0,-9));let le=a.length,ge="";for(let we=a.length-1;we>=0;we--){const Be=a[we];if(Be.type!=="text")break;le=we,ge=String(Be.content??"")+ge}le<a.length&&(se.startsWith(ge)?(u=null,a.length=le):u=a[a.length-1]);const ke=e[c+1];if((se==="`"||se==="|"||se==="$")&&!x(te,`\\${se}`)||/^\*+$/.test(se)&&!x(te,"\\*")){c++;return}if(!ke&&i?.final!==!0&&(re&xp)!==0&&/[^\]]\s*\(\s*$/.test(se)&&(se=se.replace(/\(\s*$/,"")),!se){c++;return}if((re&(ec|wp))===(ec|wp)&&V(se)||(re&(Nv|xp))===(Nv|xp)&&q(se))return;if((re&h_e)===0){I(se,te,e[c-1],ke,re),c++;return}if((re&ec)!==0&&Ne(se))return;const Ie=e[c-1];if((re&ec)!==0&&se==="["&&!ke?.markup?.includes("*")&&!x(te,"\\[")||(re&Nv)!==0&&se==="]"&&!Ie?.markup?.includes("*")&&!x(te,"\\]")){c++;return}if((re&mO)!==0&&k(be,te)||(re&(wp|ec))===(wp|ec)&&pe(se)||(re&ec)!==0&&(e[c+1]?.type!=="link_open"||L(se))&&ie(se,te))return;const Oe=w(be);if(Oe){g();for(const we of Oe)A(we);c++;return}m(se,te)||(I(se,te,Ie,ke,re),c++)}function H(te){if(O(te))return;if(ne()){const{node:le,nextIndex:ge}=Km(e,c,i),ke=String(le.text||le.href||"");T(ke,ke),c=ge;return}g();const be=c,{node:Q,nextIndex:ue}=Km(e,c,i);c=ue;const Ae=Q.text||Q.href||"";if(te.markup==="linkify"&&!Zz(Ae,Q.href,t)&&oy(Ae,l?.__linkifyDemotionContext)){T(Ae,Ae);return}const se=Q.children.length===1&&Q.children[0]?.type==="text";if(Q.loading&&t&&Q.text===Q.href&&se){const le=T_e(t,Q.href);le&&(Q.text=le,Q.children=[{type:"text",content:le,raw:le}],Q.raw=`[${le}](${Q.href}${Q.title?` "${Q.title}"`:""})`)}if(i?.validateLink&&!i.validateLink(Q.href)){T(Q.text,Q.text);return}const re=te.attrs?.find(([le])=>le==="href")?.[1],G=String(re??"");if(t&&G){const le=t.indexOf("](");if(le!==-1){const ge=t.indexOf(")",le+2);ge===-1?Q.loading=!0:Q.loading&&t.slice(le+2,ge).includes(G)&&(Q.loading=!1)}}/^file:\/\/\/[a-z]:\//i.test(Q.href)&&P(Q,be-1)||j(Q)||y(Q)}function O(te){if(te.markup!=="linkify")return!1;const{node:be,nextIndex:Q}=Km(e,c,i);return W(be,Q)?(c=Q,!0):!1}function R(te){g(),A(VSe(te)),c++}function j(te){if(te.type!=="link")return!1;const be=a[a.length-1];if(!be||be.type!=="text")return!1;const Q=String(be.content??"").match(/^([^[]*)\[([^\]\n]+)\]\($/);if(!Q)return!1;const ue=te,Ae=String(ue.href??""),se=String(ue.text??""),re=String(Q[2]??""),G=Ae.replace(/^(?:https?:\/\/|mailto:|ftp:\/\/)/i,"");if(!Ae||!(se===Ae||se===G||E_e(se)))return!1;const le=String(Q[1]??"");return le?(be.content=le,be.raw=le):a.pop(),y({...te,text:re,children:[{type:"text",content:re,raw:re}],raw:`[${re}](${Ae}${ue.title?` "${ue.title}"`:""})`}),!0}function $(te){if(te.type!=="link")return!1;const be=te,Q=String(be.href??"");return Q?W({href:Q,title:be.title==null||be.title===""?null:String(be.title),loading:!!be.loading},c+1):!1}function W(te,be){const Q=a[a.length-1];if(Q?.type!=="image"||Q.src||!Q.loading||!String(Q.raw??"").endsWith("]("))return!1;const ue=e[be],Ae=String(ue?.content??"");if(ue?.type!=="text"||!Ae.startsWith(")"))return!1;a.pop(),u=null;const se=String(Q.alt??"");y({type:"image",src:te.href,alt:se,title:te.title,raw:`![${se}](${te.href}${te.title?` "${te.title}"`:""})`,loading:!!te.loading});const re=Ae.slice(1),G=Qd(ue);return G.content=re,G.raw=re,p()[be]=G,!0}function P(te,be=c-1){if(te.type!=="link")return!1;const Q=a[a.length-1],ue=e[be];if(!Q||Q.type!=="text"||ue?.type!=="text")return!1;const Ae=String(Q.content??""),se=String(ue.content??"");if(!Ae.endsWith("!")||!se.endsWith("!")||x(ue,"\\!"))return!1;const re=Ae.slice(0,-1);re?(Q.content=re,Q.raw=re,u=Q):(a.pop(),u=null);const G=te,le=String(G.text??G.children?.map(Ie=>String(Ie?.content??Ie?.raw??"")).join("")??""),ge=String(G.href??""),ke=G.title==null||G.title===""?null:String(G.title);return y({type:"image",src:ge,alt:le,title:ke,raw:`![${le}](${ge}${ke?` "${ke}"`:""})`,loading:!!G.loading}),!0}function Z(te,be="",Q=null){const ue=String(te.alt??te.raw??"");return{type:"link",href:be,title:Q,text:ue,children:[te],raw:`[${ue}](${be}${Q?` "${Q}"`:""})`,loading:!0}}function ae(te){const be=te.startsWith("![")?te:`![${te}`,Q=be.slice(2),ue=Q.indexOf("](");return{type:"image",src:"",alt:ue===-1?Q.replace(/\]$/,""):Q.slice(0,ue),title:null,raw:be,loading:!0}}function V(te){const be=te.indexOf("[![");if(be===-1||typeof t=="string"&&e.length===1&&w_e(t,be,"["))return!1;const Q=te.slice(0,be);return Q&&T(Q,Q),y(Z(ae(te.slice(be+1)))),c++,!0}function Y(te){if(i?.final)return!1;const be=e[c-1];if(be?.type!=="text"||!String(be.content??"").endsWith("[")||x(be,"\\["))return!1;const Q=a[a.length-1];if(Q?.type==="text"&&Q.content.endsWith("[")){const ue=Q.content.slice(0,-1);ue?(Q.content=ue,Q.raw=ue,u=Q):(a.pop(),u=null)}return y(Z(MI(te))),c++,!0}function oe(te){if(te.type!=="link")return!1;const be=te,Q=String(be.raw??""),ue=String(be.text??"");if(!Q.startsWith("[![")&&!ue.startsWith("!["))return!1;const Ae=be.title==null||be.title===""?null:String(be.title);return y(Z({type:"image",src:String(be.href??""),alt:ue.replace(/^!\[/,"").replace(/\]$/,""),title:Ae,raw:Q.startsWith("[![")?Q.slice(1):Q,loading:!0})),!0}function q(te){if(!te.startsWith("]("))return!1;const be=e[c-2];if(be?.type==="text"&&String(be.content??"").endsWith("[")&&x(be,"\\["))return!1;const Q=a[a.length-1];if(Q?.type!=="image"&&Q?.type!=="link")return!1;const ue=Q,Ae=Q?.type==="link"&&Array.isArray(ue.children)&&ue.children.length===1&&ue.children[0]?.type==="image"?a.pop():null,se=Ae?Ae.children[0]:a.pop();if(!se||se.type!=="image")return!1;const re=e[c+1];let G=String(Ae?.href??""),le=Ae?.title==null?null:String(Ae.title),ge=!0;if(re?.type==="link_open"){const{node:Ie,nextIndex:Oe}=Km(e,c+1,i);G=Ie.href,le=Ie.title,ge=!0,c=Oe}else{if(G=te.slice(2),G.includes('"')){const Ie=G.split('"');G=String(Ie[0]??"").trim(),le=Ie[1]==null?null:String(Ie[1]).trim()}c++}const ke=Z(se,G,le);return ke.loading=ge,y(ke),!0}function ne(){const te=e[c-3];return e[c-2]?.type==="image"&&e[c-1]?.type==="text"&&String(e[c-1].content??"")==="]("&&te?.type==="text"&&String(te.content??"").endsWith("[")&&x(te,"\\[")}function ie(te,be){const Q=te.indexOf("[");if(Q===-1)return!1;let ue=te.slice(0,Q);const Ae=te.indexOf("](",Q);if(Ae!==-1){const se=e[c+2];let re=te.slice(Q+1,Ae);if(re.includes("[")){const we=re.indexOf("[");ue+=te.slice(0,Q+we+1);const Be=Q+we+1;re=te.slice(Be+1,Ae)}const G=e[c+1];if(te.endsWith("](")&&G?.type==="link_open"&&se){const we=e[c+4];let Be=4,tt=!0;if(we?.type==="text"){const _t=String(we.content??"");if(_t.startsWith(")")){tt=!1;const Ct=_t.slice(1);if(Ct){const $t=Qd(we);$t.content=Ct,$t.raw=Ct,p()[c+4]=$t}else Be++}else _t==="."&&Be++}S(ue,be);const ut=String(se.content??"");return i?.validateLink&&!i.validateLink(ut)?T(re,re):y({type:"link",href:ut,title:null,text:re,children:[{type:"text",content:re,raw:re}],loading:tt}),c+=Be,!0}const le=te.indexOf(")",Ae),ge=le!==-1?te.slice(Ae+2,le):"",ke=le===-1;let Ie=ue.match(/\*+$/);if(Ie&&(ue=ue.replace(/\*+$/,"")),S(ue,be),Ie||(Ie=re.match(/^\*+/)),!d&&Ie){const we=Ie[0].length;re=re.replace(/^\*+/,"").replace(/\*+$/,"");const Be=[];if(we===1?Be.push({type:"em_open",tag:"em",nesting:1}):we===2?Be.push({type:"strong_open",tag:"strong",nesting:1}):we===3&&(Be.push({type:"strong_open",tag:"strong",nesting:1}),Be.push({type:"em_open",tag:"em",nesting:1})),Be.push({type:"link",href:ge,title:null,text:re,children:[{type:"text",content:re,raw:re}],loading:ke}),we===1){Be.push({type:"em_close",tag:"em",nesting:-1});const{node:tt}=Um(Be,0,i);A(tt)}else if(we===2){Be.push({type:"strong_close",tag:"strong",nesting:-1});const{node:tt}=Z1(Be,0,void 0,i);A(tt)}else if(we===3){Be.push({type:"em_close",tag:"em",nesting:-1}),Be.push({type:"strong_close",tag:"strong",nesting:-1});const{node:tt}=Z1(Be,0,void 0,i);A(tt)}else{const{node:tt}=Um(Be,0,i);A(tt)}}else i?.validateLink&&!i.validateLink(ge)?T(re,re):y({type:"link",href:ge,title:null,text:re,children:[{type:"text",content:re,raw:re}],loading:ke});const Oe=le!==-1?te.slice(le+1):"";return Oe&&(N({type:"text",content:Oe,raw:Oe}),c--),c++,!0}return!1}function pe(te){const be=te.indexOf("![");if(be===-1)return!1;const Q=te.slice(0,be);return Q&&!u?u={type:"text",content:Q,raw:Q}:Q&&u&&(u.content+=Q),u&&(a.push(u),u=null),y(ae(te.slice(be))),c++,!0}function Ne(te){if(!(te?.startsWith("[")&&n?.type==="list_item_open"))return!1;const be=te.slice(1).match(/[^\s\]]/);if(be===null)return c++,!0;if(be&&/x/i.test(be[0])){const Q=be[0]==="x"||be[0]==="X";return y({type:"checkbox_input",checked:Q,raw:Q?"[x]":"[ ]"}),c++,!0}return!1}return a}function E7(e,t,n){const i=n?.__sourceLineMapper;if(!i)return{startLine:e,endLine:t};const o=i(e),s=t>e?i(t-1).endLine:i(t).startLine;return{startLine:o.startLine,endLine:Math.max(o.startLine,s)}}function TI(e,t){const n=Math.max(0,Math.min(e.length,Math.trunc(t)));let i=0;for(let o=0;o<n;o++)e[o]===` -`&&i++;return i}function L_e(e,t,n){const i=Math.max(0,Math.min(e.length,Math.trunc(t))),o=Math.max(i,Math.min(e.length,Math.trunc(n))),s=TI(e,i);let r=TI(e,o);return o>i&&e[o-1]!==` -`&&r++,{startLine:s,endLine:r}}function O0(e,t,n,i){const o=L_e(e,t,n);return E7(o.startLine,o.endLine,i)}function N_e(e,t){const n=e?.map;if(!Array.isArray(n)||n.length<2)return null;const i=Number(n[0]),o=Number(n[1]);return!Number.isFinite(i)||!Number.isFinite(o)?null:E7(i,o,t)}function di(e,t,n){if(!n?.includeSourceMap)return e;const i=N_e(t,n);if(!i)return e;if(e.sourceMap=i,e.type==="code_block"){const o=e;o.startLine=i.startLine,o.endLine=i.endLine}return e}function F_e(e,t,n,i){if(!i?.includeSourceMap)return e;const o=t?.map;if(!Array.isArray(o)||o.length<2)return e;const s=Number(o[0]),r=Number(o[1]),l=Number(n);return!Number.isFinite(s)||!Number.isFinite(r)||!Number.isFinite(l)||(e.sourceMap=E7(s,Math.max(r,l),i)),e}function D_e(e){const t=String(e.content??""),n=t.replace(/[ \t\r\n]+$/g,"");if(n===t)return;e.content=n;const i=e.children;if(!(!Array.isArray(i)||i.length===0))for(;i.length;){const o=i[i.length-1];if(!o){i.pop();continue}if(o.type==="softbreak"||o.type==="hardbreak"){i.pop();continue}if(o.type==="text"){const s=String(o.content??""),r=s.replace(/[ \t\r\n]+$/g,"");if(r===s)break;if(r){o.content=r;break}i.pop();continue}break}}function B_e(e){const t=String(e.content??""),n=t.match(/\r?\n\s*\d+[.)]?\s*$/);if(!n||typeof n.index!="number")return;e.content=t.slice(0,n.index);const i=e.children;if(!(!Array.isArray(i)||i.length===0))for(;i.length;){const o=i[i.length-1];if(!o){i.pop();continue}if(o.type==="softbreak"||o.type==="hardbreak"){i.pop();continue}if(o.type==="text"){const s=String(o.content??"");if(/^[ \t\r\n\d.)]*$/.test(s)){i.pop();continue}const r=s.replace(/[ \t\r\n\d.)]+$/g,"");r!==s&&(r?o.content=r:i.pop())}break}}function $_e(e){const t=String(e.content??"");return/[ \t\r\n]+$/.test(t)||/\r?\n\s*\d+[.)]?\s*$/.test(t)}function p1(e,t,n){const i=e[t],o=[],s=Gc(n,!0);let r=t+1;for(;r<e.length&&e[r].type!=="bullet_list_close"&&e[r].type!=="ordered_list_close";)if(e[r].type==="list_item_open"){const a=[];let u=r+1;for(;u<e.length&&e[u].type!=="list_item_close";)if(e[u].type==="paragraph_open"){const d=e[u+1],h=$_e(d)?Qd(d):d,p=e[u-1];h!==d&&(B_e(h),D_e(h));const g=String(h.content??""),m={type:"paragraph",children:Ao(h.children||[],g,p,s.options()),raw:g};n?.includeSourceMap&&di(m,e[u],n),a.push(m),s.remember(g),u+=3}else if(e[u].type==="blockquote_open"){const[d,h]=g1(e,u,s.options());a.push(d),s.remember(d.raw),u=h}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[d,h]=p1(e,u,s.options());a.push(d),s.remember(d.raw),u=h}else{const d=L7(e,u,s.options(),T7);d?(a.push(d[0]),s.remember(d[0].raw),u=d[1]):u+=1}const c={type:"list_item",children:a,raw:a.map(d=>d.raw).join("")};n?.includeSourceMap&&di(c,e[r],n),o.push(c),r=u+1}else r+=1;const l={type:"list",ordered:i.type==="ordered_list_open",start:(()=>{if(i.attrs&&i.attrs.length){const a=i.attrs.find(u=>u[0]==="start");if(a){const u=Number(a[1]);return Number.isFinite(u)&&u!==0?u:1}}})(),items:o,raw:o.map(a=>a.raw).join(` -`)};return n?.includeSourceMap&&di(l,i,n),[l,r+1]}function R_e(e,t,n,i){const o=String(n[1]??"note"),s=String(n[2]??o.charAt(0).toUpperCase()+o.slice(1)),r=[],l=Gc(i,!0);let a=t+1;for(;a<e.length&&e[a].type!=="container_close";)if(e[a].type==="paragraph_open"){const u=e[a+1];if(u){const c={type:"paragraph",children:Ao(u.children||[],String(u.content??""),void 0,l.options()),raw:String(u.content??"")};i?.includeSourceMap&&di(c,e[a],i),r.push(c),l.remember(c.raw)}a+=3}else if(e[a].type==="bullet_list_open"||e[a].type==="ordered_list_open"){const[u,c]=p1(e,a,l.options());i?.includeSourceMap&&di(u,e[a],i),r.push(u),l.remember(u.raw),a=c}else if(e[a].type==="blockquote_open"){const[u,c]=g1(e,a,l.options());i?.includeSourceMap&&di(u,e[a],i),r.push(u),l.remember(u.raw),a=c}else{const u=M9(e,a,l.options());u?(r.push(u[0]),l.remember(u[0].raw),a=u[1]):a++}return[{type:"admonition",kind:o,title:s,children:r,raw:`:::${o} ${s} -${r.map(u=>u.raw).join(` -`)} -:::`},a+1]}const z_e=new Set(["warning","info","note","tip","danger","caution"]);function O_e(e){let t=0;for(;t<e.length&&t<3&&e[t]===":";)t++;if(t===0||e[t]===":")return null;const n=e.slice(t).trimStart();if(!n)return null;const i=n.search(/\s/),o=(i===-1?n:n.slice(0,i)).toLowerCase();return z_e.has(o)?{kind:o,title:i===-1?"":n.slice(i).trim()}:null}function P_e(e,t,n){const i=e[t];let o="note",s="";const r=i.type.match(/^container_(\w+)_open$/);if(r){o=r[1];const d=String(i.info??"").trim();if(d&&!d.startsWith(":::")&&d.toLowerCase().startsWith(o)){const h=d.slice(o.length).trim();h&&(s=h)}}else{const d=O_e(String(i.info??"").trim());d&&(o=d.kind,s=d.title)}s||(s=o.charAt(0).toUpperCase()+o.slice(1));const l=[],a=Gc(n,!0);let u=t+1;const c=new RegExp(`^container_${o}_close$`);for(;u<e.length&&e[u].type!=="container_close"&&!c.test(e[u].type);)if(e[u].type==="paragraph_open"){const d=e[u+1];if(d){const h=d.children||[];let p=-1;for(let m=h.length-1;m>=0;m--){const k=h[m];if(k.type==="text"&&/:+/.test(k.content)){p=m;break}}const g={type:"paragraph",children:Ao((p!==-1?h.slice(0,p):h)||[],void 0,void 0,a.options()),raw:String(d.content??"").replace(/\n:+$/,"").replace(/\n\s*:::\s*$/,"")};n?.includeSourceMap&&di(g,e[u],n),l.push(g),a.remember(g.raw)}u+=3}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[d,h]=p1(e,u,a.options());n?.includeSourceMap&&di(d,e[u],n),l.push(d),a.remember(d.raw),u=h}else if(e[u].type==="blockquote_open"){const[d,h]=g1(e,u,a.options());n?.includeSourceMap&&di(d,e[u],n),l.push(d),a.remember(d.raw),u=h}else{const d=M9(e,u,a.options());d?(l.push(d[0]),a.remember(d[0].raw),u=d[1]):u++}return[{type:"admonition",kind:o,title:s,children:l,raw:`:::${o} ${s} -${l.map(d=>d.raw).join(` -`)} -:::`},u+1]}const j_e=/^::: ?(warning|info|note|tip|danger|caution|error) ?(.*)$/;function H_e(e,t,n){const i=e[t];if(i.type!=="container_open")return null;const o=j_e.exec(String(i.info??""));return o?R_e(e,t,o,n):null}const T7={parseContainer:(e,t,n)=>P_e(e,t,n),matchAdmonition:H_e};function g1(e,t,n){const i=[],o=Gc(n,!0);let s=t+1;for(;s<e.length&&e[s].type!=="blockquote_close";){const l=e[s];switch(l.type){case"paragraph_open":{const a=e[s+1],u={type:"paragraph",children:Ao(a.children||[],String(a.content??""),void 0,o.options()),raw:String(a.content??"")};n?.includeSourceMap&&di(u,l,n),i.push(u),o.remember(u.raw),s+=3;break}case"bullet_list_open":case"ordered_list_open":{const[a,u]=p1(e,s,o.options());i.push(a),o.remember(a.raw),s=u;break}case"blockquote_open":{const[a,u]=g1(e,s,o.options());i.push(a),o.remember(a.raw),s=u;break}default:{const a=L7(e,s,o.options(),T7);a?(i.push(a[0]),o.remember(a[0].raw),s=a[1]):s++;break}}}const r={type:"blockquote",children:i,raw:i.map(l=>l.raw).join(` -`)};return n?.includeSourceMap&&di(r,e[t],n),[r,s+1]}function W_e(e){if(e.info?.startsWith("diff"))return M7(e);const t=String(e.content??""),n=t.match(/ type="application\/vnd\.ant\.([^"]+)"/);let i=t;n?.[1]&&(i=t.replace(/<antArtifact[^>]*>/g,"").replace(/<\/antArtifact>/g,""));const o=Array.isArray(e.map)&&e.map.length===2;return{type:"code_block",language:n?n[1]:String(e.info??""),code:i,raw:i,loading:!o}}function q_e(e,t,n){const i=[];let o=t+1,s=[],r=[];const l=Gc(n,!0);for(;o<e.length&&e[o].type!=="dl_close";)if(e[o].type==="dt_open"){const a=e[o+1];s=Ao(a.children||[],void 0,void 0,l.options()),l.remember(s.map(u=>u.raw).join("")),o+=3}else if(e[o].type==="dd_open"){let a=o+1;for(r=[];a<e.length&&e[a].type!=="dd_close";)if(e[a].type==="paragraph_open"){const u=e[a+1];r.push({type:"paragraph",children:Ao(u.children||[],String(u.content??""),void 0,l.options()),raw:String(u.content??"")}),l.remember(String(u.content??"")),a+=3}else a++;s.length>0&&(i.push({type:"definition_item",term:s,definition:r,raw:`${s.map(u=>u.raw).join("")}: ${r.map(u=>u.raw).join(` -`)}`}),s=[]),o=a+1}else o++;return[{type:"definition_list",items:i,raw:i.map(a=>a.raw).join(` -`)},o+1]}function U_e(e,t,n){const i=e[t].meta??{},o=String(i?.label??"0"),s=[],r=Gc(n,!0);let l=t+1;for(;l<e.length&&e[l].type!=="footnote_close";)if(e[l].type==="paragraph_open"){const a=e[l+1],u=a.children?[...a.children]:[];e[l+2].type==="footnote_anchor"&&u.push(e[l+2]);const c={type:"paragraph",children:Ao(u,String(a.content??""),void 0,r.options()),raw:String(a.content??"")};s.push(c),r.remember(c.raw),l+=3}else l++;return[{type:"footnote",id:o,children:s,raw:`[^${o}]: ${s.map(a=>a.raw).join(` -`)}`},l+1]}function K_e(e,t,n){const i=e[t],o=i.attrs,s=Array.isArray(o)&&o.length?Object.fromEntries(o.filter(c=>Array.isArray(c)&&c.length>=1&&c[0]).map(([c,d])=>[String(c),d==null||d===""?!0:String(d)])):void 0,r=String(i.tag?.substring(1)??"1"),l=Number.parseInt(r,10),a=e[t+1],u=String(a.content??"");return{type:"heading",level:l,text:u,...s?{attrs:s}:{},children:Ao(a.children||[],u,void 0,n),raw:u}}function V_e(e,t,n){const i=t.toLowerCase(),o=new RegExp(String.raw`^<\s*${i}(?=\s|>|/)`,"i"),s=new RegExp(String.raw`^<\s*\/\s*${i}(?=\s|>)`,"i");let r=0,l=Math.max(0,n);for(;l<e.length;){const a=e.indexOf("<",l);if(a===-1)return-1;const u=e.slice(a);if(s.test(u)){const c=Do(u);if(c===-1)return-1;if(r===0)return a+c+1;r--,l=a+c+1;continue}if(o.test(u)){const c=Do(u);if(c===-1)return-1;const d=u.slice(0,c+1);/\/\s*>$/.test(d)||r++,l=a+c+1;continue}l=a+1}return-1}function CO(e){const t=String(e.content??"");if(/^\s*<!--/.test(t)||/^\s*<!/.test(t)||/^\s*<\?/.test(t))return{type:"html_block",content:t,raw:t,tag:"",loading:!1};const n=(t.match(/^\s*<([A-Z][\w:-]*)/i)?.[1]||"").toLowerCase();if(!n)return{type:"html_block",content:t,raw:t,tag:"",loading:!1};const i=Do(t),o=i===-1?t:t.slice(0,i+1),s=i!==-1&&/\/\s*>$/.test(o),r=Tc.has(n),l=_9(o),a=(i===-1?-1:V_e(t,n,i+1))!==-1,u=!(r||s||a);return{type:"html_block",content:u?`${t.replace(/<[^>]*$/,"")} -</${n}>`:t,raw:t,tag:n,attrs:l.length?l:void 0,loading:u}}function Z_e(e){const t=String(e.content??""),n=e.raw==="$$"?`$$${t}$$`:String(e.raw??"");return{type:"math_block",content:t,loading:!!e.loading,raw:n,markup:e.markup}}function G_e(e){if(!e)return"left";for(const t of e){if(!t)continue;const[n,i]=t;if(!i)continue;const o=String(i).trim().toLowerCase();if(n==="style"){const s=/text-align\s*:\s*(left|right|center)/i.exec(o);if(s)return s[1].toLowerCase()}}return"left"}function wO(e){return e?.filename===!0||e?.explicitFilename===!0||e?.marketTicker===!0}function xO(e,t){const n={filename:e?.filename||t?.filename,explicitFilename:e?.explicitFilename||t?.explicitFilename,marketTicker:e?.marketTicker||t?.marketTicker};return wO(n)?n:void 0}function Q_e(e,t,n){const i=xO(yg(t),n);if(!wO(i))return e;const o=e?.__linkifyDemotionContext;return{...e,__linkifyDemotionContext:{filename:o?.filename||i?.filename,explicitFilename:o?.explicitFilename||i?.explicitFilename,marketTicker:o?.marketTicker||i?.marketTicker}}}function Y_e(e,t,n){let i=t+1,o=null;const s=[];let r=!1;for(;i<e.length&&e[i].type!=="table_close";)if(e[i].type==="thead_open")r=!0,i++;else if(e[i].type==="thead_close")r=!1,i++;else if(e[i].type==="tbody_open"||e[i].type==="tbody_close")i++;else if(e[i].type==="tr_open"){const a=[];let u=i+1,c;for(;u<e.length&&e[u].type!=="tr_close";)if(e[u].type==="th_open"||e[u].type==="td_open"){const h=e[u].type==="th_open",p=e[u+1],g=String(p.content??""),m=G_e(e[u].attrs),k=a.length,w=!h&&!r,y=w?o?.cells[k]?.raw:void 0;a.push({type:"table_cell",header:h||r,children:Ao(p.children||[],g,void 0,Q_e(n,y,w?c:void 0)),raw:g,align:m}),w&&(c=xO(c,yg(g))),u+=3}else u++;const d={type:"table_row",cells:a,raw:a.map(h=>h.raw).join("|")};r?o=d:s.push(d),i=u+1}else i++;o||(o={type:"table_row",cells:[],raw:""});const l=e[t].loading===!0;return[{type:"table",header:o,rows:s,loading:l&&!n?.final&&s.length===0,raw:[o,...s].map(a=>a.raw).join(` -`)},i+1]}function J_e(){return{type:"thematic_break",raw:"---"}}let tk=null;const nk=new WeakMap;function LI(){return tk||(tk={allowedTagSet:T9(),customTagSet:null}),tk}function X_e(e){if(!e||e.length===0)return LI();const t=nk.get(e);if(t)return t;const n=e.map(zl).filter(Boolean);if(!n.length){const o=LI();return nk.set(e,o),o}const i={allowedTagSet:T9({customHtmlTags:e}),customTagSet:new Set(n)};return nk.set(e,i),i}function eMe(e,t,n){const i=e[t],o=i.attrs;let s="";const r={};if(o){for(const[p,g]of o)if(p==="class"){const m=g.match(/(?:\s|^)vmr-container-(\S+)/);m&&(s=m[1])}else if(p.startsWith("data-")){const m=p.slice(5);try{r[m]=JSON.parse(g)}catch{r[m]=g}}}const l=[],a=Gc(n,!0);let u=t+1;for(;u<e.length&&e[u].type!=="vmr_container_close";)if(e[u].type==="paragraph_open"){const p=e[u+1];if(p){const g={type:"paragraph",children:Ao(p.children||[],void 0,void 0,a.options()),raw:String(p.content??"")};n?.includeSourceMap&&di(g,e[u],n),l.push(g),a.remember(g.raw)}u+=3}else if(e[u].type==="bullet_list_open"||e[u].type==="ordered_list_open"){const[p,g]=p1(e,u,a.options());n?.includeSourceMap&&di(p,e[u],n),l.push(p),a.remember(p.raw),u=g}else if(e[u].type==="blockquote_open"){const[p,g]=g1(e,u,a.options());n?.includeSourceMap&&di(p,e[u],n),l.push(p),a.remember(p.raw),u=g}else{const p=M9(e,u,a.options());p?(l.push(p[0]),a.remember(p[0].raw),u=p[1]):u++}const c=u<e.length&&e[u].type==="vmr_container_close",d=c&&i.meta?.unclosed!==!0||!!n?.final;let h=`::: ${s}`;return Object.keys(r).length>0&&(h+=` ${JSON.stringify(r)}`),h+=` -`,l.length>0&&(h+=i.raw??l.map(p=>p.raw).join(` -`),h+=` -`),h+=":::",[{type:"vmr_container",name:s,loading:!d,attrs:Object.keys(r).length>0?r:void 0,children:l,raw:h},c?u+1:u]}function ik(e,t,n,i){if(n?.type.endsWith("_close")){let o=Array.isArray(n.map)?Number(n.map[1]):NaN;return Number.isFinite(o)||(o=Array.isArray(t.map)?Number(t.map[1])+1:NaN),F_e(e,t,o,i)}return di(e,t,i)}function tMe(e){return e.replace(/^\r?\n/,"").replace(/\r?\n$/,"")}function nMe(e,t){if(!e||!t)return e;const n=new RegExp(String.raw`[\t ]*<\s*\/\s*${t}[^>]*$`,"i");return e.replace(n,"")}function iMe(e,t,n){if(!e||!t)return null;const i=t.toLowerCase(),o=new RegExp(String.raw`^<\s*${fa(i)}(?=\s|>|/)`,"i"),s=new RegExp(String.raw`^<\s*\/\s*${fa(i)}(?=\s|>)`,"i");let r=0,l=Math.max(0,n);for(;l<e.length;){const a=e.indexOf("<",l);if(a===-1)break;const u=e.slice(a);if(s.test(u)){const c=Do(u);if(c===-1)return null;if(r===0)return{start:a,end:a+c+1};r--,l=a+c+1;continue}if(o.test(u)){const c=Do(u);if(c===-1)return null;const d=u.slice(0,c+1);/\/\s*>$/.test(d)||r++,l=a+c+1;continue}l=a+1}return null}function oMe(e,t,n){if(!e||!t)return null;const i=t.toLowerCase(),o=new RegExp(String.raw`<\s*${i}(?=\s|>|/)`,"gi");o.lastIndex=Math.max(0,n||0);const s=o.exec(e);if(!s||s.index==null)return null;const r=s.index,l=e.slice(r),a=Do(l);if(a===-1)return null;const u=r+a;if(/\/\s*>\s*$/.test(l.slice(0,a+1))){const g=u+1;return{raw:e.slice(r,g),start:r,end:g}}let c=1,d=u+1;const h=g=>{const m=e.slice(g);return new RegExp(String.raw`^<\s*${i}(?=\s|>|/)`,"i").test(m)},p=g=>{const m=e.slice(g);return new RegExp(String.raw`^<\s*\/\s*${i}(?=\s|>)`,"i").test(m)};for(;d<e.length;){const g=e.indexOf("<",d);if(g===-1)return{raw:e.slice(r),start:r,end:e.length};if(p(g)){const m=e.indexOf(">",g);if(m===-1)return null;if(c--,c===0){const k=m+1;return{raw:e.slice(r,k),start:r,end:k}}d=m+1;continue}if(h(g)){const m=Do(e.slice(g));if(m===-1)return null;c++,d=g+m+1;continue}d=g+1}return{raw:e.slice(r),start:r,end:e.length}}function H8(e){return Number.isFinite(e)&&e>0?e:0}function sMe(e,t){const n=H8(t);if(!e||n<=0)return 0;let i=0;for(let o=0;o<e.length;o++)if(e[o]===` -`&&(i++,i===n))return o+1;return e.length}function M9(e,t,n){const i=e[t],o=n?.includeSourceMap===!0;switch(i.type){case"heading_open":{const s=K_e(e,t,n);return o&&di(s,i,n),[s,t+3]}case"code_block":{const s=W_e(i);return o&&di(s,i,n),[s,t+1]}case"fence":{const s=M7(i);return o&&di(s,i,n),[s,t+1]}case"math_block":{const s=Z_e(i);return o&&di(s,i,n),[s,t+1]}case"html_block":{const s=CO(i),r=s.tag?X_e(n?.customHtmlTags):null;if(s.tag&&s.loading&&r&&!r.allowedTagSet.has(s.tag)){const l=String(i.content??"").replace(/\n+$/,""),a={type:"paragraph",children:l?[{type:"text",content:l,raw:l}]:[],raw:l};return o&&di(a,i,n),[a,t+1]}if(s.tag&&r?.customTagSet?.has(s.tag)){const l=s.tag,a=String(n?.__sourceMarkdown??""),u=Number(n?.__customHtmlBlockCursor??0),c=Array.isArray(i.map)?sMe(a,Number(i.map?.[0]??0)):0,d=oMe(a,l,Math.max(H8(u),H8(c)));d&&n&&(n.__customHtmlBlockCursor=d.end);const h=String(d?.raw??s.raw??""),p=Do(h),g=p!==-1?h.slice(0,p+1):h,m=p!==-1&&/\/\s*>\s*$/.test(g),k=p===-1?null:iMe(h,l,p+1),w=k?.start??-1;let y="";p!==-1&&(w!==-1&&p<w?y=h.slice(p+1,w):y=h.slice(p+1)),w===-1&&(y=nMe(y,l));const b=[],A=/\s([\w:-]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'>]+)))?/g;let T;for(;(T=A.exec(g))!==null;){const _=T[1];if(!_||_.toLowerCase()===l)continue;const L=T[2]||T[3]||T[4]||"";b.push([_,L])}const S=!n?.final&&!m&&k==null,x={type:l,tag:l,content:tMe(y),raw:String(d?.raw??s.raw??h),loading:S,attrs:b.length?b:void 0};return o&&(d?x.sourceMap=O0(a,d.start,d.end,n):di(x,i,n)),[x,t+1]}return o&&di(s,i,n),[s,t+1]}case"table_open":{const[s,r]=Y_e(e,t,n);return o&&di(s,i,n),[s,r]}case"dl_open":{const[s,r]=q_e(e,t,n);return o&&di(s,i,n),[s,r]}case"footnote_open":{const[s,r]=U_e(e,t,n);return o&&di(s,i,n),[s,r]}case"hr":{const s=J_e();return o&&di(s,i,n),[s,t+1]}}return null}function L7(e,t,n,i){const o=M9(e,t,n);if(o)return o;const s=e[t],r=n?.includeSourceMap===!0;switch(s.type){case"container_warning_open":case"container_info_open":case"container_note_open":case"container_tip_open":case"container_danger_open":case"container_caution_open":case"container_error_open":if(i?.parseContainer){const l=i.parseContainer(e,t,n);return r&&ik(l[0],s,e[l[1]-1],n),l}break;case"container_open":if(i?.matchAdmonition){const l=i.matchAdmonition(e,t,n);if(l)return r&&ik(l[0],s,e[l[1]-1],n),l}break;case"vmr_container_open":{const l=eMe(e,t,n);return r&&ik(l[0],s,e[l[1]-1],n),l}}return null}function rMe(){return{type:"hardbreak",raw:`\\ -`}}function lMe(e,t,n){const i=e[t+1],o=String(i.content??"");return{type:"paragraph",children:Ao(i.children||[],o,void 0,n),raw:o}}const NI=new WeakMap,SO=new WeakMap,FI=new WeakMap,DI=new WeakMap;function xa(e,t,n){const i=t?.map,o=n?.__sourceMarkdown;if(!Array.isArray(i)||i.length<2||typeof o!="string"||!n)return;const s=Number(i[0]),r=Number(i[1]);if(!Number.isFinite(s)||!Number.isFinite(r))return;let l=FI.get(n);if(!l){l=[0];for(let a=0;a<o.length;a++)o[a]===` -`&&l.push(a+1);FI.set(n,l)}SO.set(e,{start:l[Math.max(0,Math.trunc(s))]??o.length,end:l[Math.max(0,Math.trunc(r))]??o.length})}const I9=new WeakMap,BI=new WeakMap,aMe=["$","\\["],uMe=/(^|\r?\n)[\t ]*:::[\t ]*(?:warning|info|note|tip|danger|caution|error)(?=[\t ]|\r?\n|$)[^\r\n]*(?:\r?\n[\t ]*)*$/,cMe=1024,dMe=16,W8=new WeakMap,Vp=new WeakMap,Sp=new WeakMap,fMe=new Set(["code_inline","em_close","em_open","emoji","hardbreak","html_block","html_inline","image","ins_close","ins_open","link","link_close","link_open","mark_close","mark_open","math_inline","s_close","s_open","softbreak","strong_close","strong_open","sub","sup","text"]),hMe=new Map([["paragraph_open","paragraph_close"],["heading_open","heading_close"],["bullet_list_open","bullet_list_close"],["ordered_list_open","ordered_list_close"],["blockquote_open","blockquote_close"],["table_open","table_close"]]),pMe=new Set(["code_block","fence","hr","inline","math_block"]);function Jl(){return typeof performance<"u"?performance.now():Date.now()}function vc(e,t,n){e&&(e[t]=(e[t]??0)+n)}function _O(e){return e.__timing}function MO(e,t,n){return t&&vc(t,"parseMarkdownToStructureTotalMs",Jl()-n),e}function IO(e,t){const n=t.postTransformNodes;if(typeof n!="function")return e;const i=n(e);return Array.isArray(i)?i:e}function $I(e,t,n,i){return MO(IO(e,t),n,i)}function ah(e,t,n){if(!n)return GI(e,t);vc(n,"processTokensInputTokens",e.length);const i=Jl(),o=GI(e,t);return vc(n,"processTokensMs",Jl()-i),o}function EO(e,t){return e.every(n=>{if(!fMe.has(n.type)||(n.type==="link"||n.type==="link_open"||n.type==="link_close")&&!bxe(t))return!1;if(n.type==="link"){const o=yxe(n);if(o!=="explicit"&&o!=="linkify"&&o!=="autolink")return!1}if(n.type==="link_open"||n.type==="link_close"){const o=n.markup??"";if(o!==""&&o!=="linkify"&&o!=="autolink")return!1}const i=n.children;return!Array.isArray(i)||EO(i,t)})}function gMe(e){const t=hMe.get(e);if(t)return t;const n=/^container_(.+)_open$/.exec(e);return n?`container_${n[1]}_close`:void 0}function mMe(e,t){const n=[];let i=!1,o=0;for(;o<e.length;){const s=e[o];if(!s||s.level!==0)return null;const r=gMe(s.type);let l=o+1;if(r){if(s.nesting!==1)return null;for(;l<e.length;){const a=e[l];if(a.level===0){if(a.type!==r||a.nesting!==-1)return null;l++;break}l++}if(e[l-1]?.type!==r)return null;if(s.type==="paragraph_open"||s.type==="heading_open"){if(l!==o+3||e[o+1]?.type!=="inline")return null}else i=!0}else if(pMe.has(s.type)){if(s.nesting!==0)return null;i=!0}else return null;for(let a=o;a<l;a++){const u=e[a];if(u.type!=="inline")continue;const c=u.children;if(!Array.isArray(c)||!EO(c,t))return null}n.push(o),o=l}return{mixed:i,starts:n}}function vMe(e){return/\r?\n[\t ]*\r?\n[\t ]*$/.test(e)}function yMe(e){return e.__reuseStableTopLevelNodes===!0&&e.final!==!0&&!e.preTransformTokens&&!e.postTransformTokens&&!e.postTransformNodes&&!e.customHtmlTags?.length&&e.includeSourceMap!==!0}function RI(e,t,n,i,o,s){const r=i.starts;if(r.length===0||o.length!==r.length){Vp.delete(e);return}const l=r.map((a,u)=>{const c=r[u+1]??n.length;return{firstToken:n[a],lastToken:n[c-1],tokenCount:c-a}});Vp.set(e,{groupBoundaries:l,source:t,nodes:o,stableGroupCount:i.mixed?Math.max(0,r.length-1):vMe(t)?r.length:Math.max(0,r.length-1),requireClosingStrong:s.requireClosingStrong,validateLink:s.validateLink})}function kMe(e,t,n,i){const o=n.length-1;for(let s=0;s<i;s++){const r=n[s],l=n[s+1]??t.length,a=e.groupBoundaries[s];if(!a||a.tokenCount!==l-r)return!1;if(!(a.firstToken===t[r]&&a.lastToken===t[l-1])&&(s>=o||!PI(a.firstToken,t[r])||!PI(a.lastToken,t[l-1])))return!1}return!0}function bMe(e,t,n,i,o){const s=e,r=i.__disableStructuredReuse===!0;if(!(N7(e,i)&&yMe(i)))return r||Vp.delete(s),ah(n,i,o);if(r)return ah(n,i,o);const l=mMe(n,i.validateLink);if(!l)return Vp.delete(s),ah(n,i,o);const a=l.starts,u=Vp.get(s),c=Sp.get(s),d=u&&l.mixed?Math.min(u.stableGroupCount,Math.max(0,u.groupBoundaries.length-1)):u?.stableGroupCount??0;if(u&&d>0&&u.requireClosingStrong===i.requireClosingStrong&&u.validateLink===i.validateLink&&t.startsWith(u.source)&&a.length>=d&&(c==="append"||c==="tail")&&kMe(u,n,a,d)){const p=a[d]??n.length,g=ah(n.slice(p),{...i,__linkifyDemotionSeed:u.nodes.slice(0,d).map(k=>String(k.raw??""))},o),m=a.length-d;if(g.length===m){const k=u.nodes.slice(0,d).concat(g);return vc(o,"processTokensReusedTopLevelNodes",d),RI(e,t,n,l,k,i),k}}const h=ah(n,i,o);return RI(e,t,n,l,h,i),h}function AMe(e){const t=e?.customHtmlTags;if(!Array.isArray(t)||t.length===0)return null;const n=wf(t);return n.length?new Set(n):null}function CMe(e,t){const n=e;let i=NI.get(n);i||(i=new Map,NI.set(n,i));const o=t.__markstreamFinal===!0?"final":"streaming";let s=i.get(o);s||(s={},i.set(o,s));for(const r of Object.keys(s))Object.prototype.hasOwnProperty.call(t,r)||delete s[r];return Object.assign(s,t),s}function wMe(e){if(!e||typeof e!="object")return!1;const t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function Zm(e,t,n){for(const i of Reflect.ownKeys(e)){const o=Object.getOwnPropertyDescriptor(e,i);if(!o||!("value"in o))continue;const s=Object.getOwnPropertyDescriptor(t,i);s&&(!("value"in s)||s.writable===!1)||(t[i]=Nd(o.value,n))}}function Nd(e,t=new WeakMap){if(!e||typeof e!="object")return e;const n=e,i=t.get(n);if(i)return i;if(Array.isArray(e)){const r=[];t.set(n,r);for(const l of e)r.push(Nd(l,t));return r}if(e instanceof Map){const r=new Map;t.set(n,r);for(const[l,a]of e)r.set(Nd(l,t),Nd(a,t));return r}if(e instanceof Set){const r=new Set;t.set(n,r);for(const l of e)r.add(Nd(l,t));return r}if(e instanceof Date){const r=new Date(e.getTime());return t.set(n,r),r}if(e instanceof RegExp){const r=new RegExp(e.source,e.flags);return r.lastIndex=e.lastIndex,t.set(n,r),r}if(typeof URL<"u"&&e instanceof URL){const r=new URL(e.href);return t.set(n,r),Zm(n,r,t),r}if(typeof URLSearchParams<"u"&&e instanceof URLSearchParams){const r=new URLSearchParams(e.toString());return t.set(n,r),Zm(n,r,t),r}if(e instanceof Error){let r;const l=e.constructor;try{r=new l(e.message)}catch{r=new Error(e.message)}return Object.setPrototypeOf(r,Object.getPrototypeOf(e)),t.set(n,r),Zm(n,r,t),r}if(typeof Promise<"u"&&e instanceof Promise||typeof Node<"u"&&e instanceof Node)return t.set(n,e),e;if(!wMe(e)){const r=Object.create(Object.getPrototypeOf(e));return t.set(n,r),Zm(n,r,t),r}const o={};t.set(n,o);const s=e;for(const r of Object.keys(s))o[r]=Nd(s[r],t);return o}function TO(e,t=!0){if(!t)return Qd(e);const n=Object.create(Object.getPrototypeOf(e)),i=new WeakMap;for(const o of Reflect.ownKeys(e)){const s=Object.getOwnPropertyDescriptor(e,o);if(!s)continue;if(!("value"in s)){Object.defineProperty(n,o,s);continue}const r=s.value;let l=r;o==="attrs"&&Array.isArray(r)?l=r.map(a=>[...a]):o==="map"&&Array.isArray(r)?l=[...r]:o==="children"&&Array.isArray(r)?l=r.map(a=>TO(a,t)):t&&r&&typeof r=="object"&&(l=Nd(r,i)),Object.defineProperty(n,o,{...s,value:l})}return n}function zI(e,t=!0){return e.map(n=>TO(n,t))}function N7(e,t){const n=t,i=e.stream,o=t.streamParse??"auto";return n.__disableStreamParse!==!0&&e.__markstreamHasCustomParserExtensions!==!0&&(o===!0||o==="auto"&&t.final!==!0)&&i?.enabled===!0&&typeof i.parse=="function"}function xMe(e,t){const n=t,i=t.streamParse??"auto",o=e.stream;return t.final===!0&&i==="auto"&&n.__disableStreamParse!==!0&&e.__markstreamHasCustomParserExtensions!==!0&&o?.enabled===!0&&typeof o.reset=="function"}function SMe(e){I9.delete(e)}function _Me(){return{fenceChar:"",fenceInBlockquote:!1,fenceInList:!1,fenceLen:0,fenceListIndent:0,inDollarMath:!1,inFence:!1,inMath:!1,listContentIndent:null,dollarMathOpenOffset:null,mathOpenOffset:null}}function Zp(e){return{...e}}function MMe(e,t,n,i=E9(t).state){I9.set(e,{explicitBracketMath:i,source:t,key:n,pendingCandidate:n===null&&aO(t)})}function IMe(e){return e.endsWith("$")||e.endsWith("\\")}function EMe(e){const t=Math.max(e.lastIndexOf(` -`)+1,0),n=e.slice(t).replace(/[\t ]+$/,"");return aMe.some(i=>n.endsWith(i))}function TMe(e,t){return t?!!(t.includes("$$")||t.includes("\\[")||e.endsWith("$")&&t[0]==="$"||e.endsWith("\\")&&t[0]==="["||EMe(e)&&/[\r\n]/.test(t)):!1}function Na(e,t){let n=t-1,i=0;for(;n>=0&&e[n]==="\\";)i++,n--;return i%2===1}function q8(e){return e===" "||e===" "}function LO(e,t){return t===" "?e+1:e+4-e%4}function F7(e){let t=0,n=0;for(;t<e.length&&q8(e[t]);)n=LO(n,e[t]),t++;return{index:t,column:n}}function m1(e){const t=F7(e);return t.column>3?null:t}function ok(e){const t=m1(e);if(!t)return null;const n=t.index,i=e[n];if(i!=="`"&&i!=="~")return null;let o=n;for(;o<e.length&&e[o]===i;)o++;const s=o-n;if(s<3)return null;const r=e.slice(o);return i==="`"&&r.includes("`")?null:{markerChar:i,markerLen:s,rest:r}}function D7(e){const t=m1(e);if(!t)return null;const n=e.slice(t.index),i=/^(?:[-+*]|\d{1,9}[.)])(?=[\t ]|$)/.exec(n)?.[0];if(!i)return null;let o=t.index+i.length,s=t.column+i.length;if(!q8(e[o]))return null;for(;o<e.length&&q8(e[o]);)s=LO(s,e[o]),o++;return{content:e.slice(o),contentIndent:s}}function B7(e){let t=e,n=!1;for(;;){const i=m1(t);if(!i)return n?t:null;let o=i.index;if(t[o]!==">")return n?t:null;n=!0,o++,(t[o]===" "||t[o]===" ")&&o++,t=t.slice(o)}}function $7(e){const t=ok(e);if(t)return{...t,inBlockquote:!1,inList:!1,listIndent:0};const n=B7(e),i=n==null?null:ok(n);if(i)return{...i,inBlockquote:!0,inList:!1,listIndent:0};const o=D7(e);if(!o)return null;const s=ok(o.content);return s==null?null:{...s,inBlockquote:!1,inList:!0,listIndent:o.contentIndent}}function NO(e,t){let n=!1,i="",o=0,s=!1,r=!1,l=0,a=null,u=0;for(;u<t;){const c=e.indexOf(` -`,u),d=c===-1||c>=t?t:c,h=e.slice(u,d),p=h.endsWith("\r")?h.slice(0,-1):h,g=F7(p),m=D7(p);n&&s&&p.trim()&&B7(p)==null&&(n=!1,i="",o=0,s=!1,r=!1,l=0),n&&r&&p.trim()&&g.column<l&&!m&&(n=!1,i="",o=0,s=!1,r=!1,l=0),m?a=m.contentIndent:p.trim()&&a!=null&&g.column<a&&!n&&(a=null);const k=$7(p);if(k&&(n?k.markerChar===i&&k.markerLen>=o&&/^\s*$/.test(k.rest)&&(n=!1,i="",o=0,s=!1,r=!1,l=0):(n=!0,i=k.markerChar,o=k.markerLen,s=k.inBlockquote,r=k.inList||a!=null&&!k.inBlockquote&&g.column>=a,l=k.listIndent||a||0)),c===-1||c>=t)break;u=c+1}return n}function LMe(e,t){const n=d=>d===" "||d===" ",i=d=>{const h=d.charCodeAt(0);return h>=65&&h<=90||h>=97&&h<=122||h>=48&&h<=57||d==="_"||d==="-"||d===":"},o=d=>{if(d[0]!=="<")return null;let h=1;for(;h<d.length&&n(d[h]);)h++;const p=d[h]==="/";if(p)for(h++;h<d.length&&n(d[h]);)h++;const g=h;for(;h<d.length&&i(d[h]);)h++;if(h===g)return null;const m=d.slice(g,h).toLowerCase();if(!Dz.has(m))return null;const k=d[h];if(k&&k!==" "&&k!==" "&&k!==">"&&k!=="/")return null;const w=Do(d);if(w===-1)return null;let y=w-1;for(;y>=0&&n(d[y]);)y--;return{closing:p,tag:m,selfClosing:!p&&d[y]==="/",after:d.slice(w+1)}},s=(d,h)=>{const p=d.toLowerCase();let g=0;for(;g<p.length;){const m=p.indexOf("</",g);if(m===-1)return!1;for(g=m+2;g<p.length&&n(p[g]);)g++;if(p.startsWith(h,g)){const k=p[g+h.length];if(!k||k===" "||k===" "||k===">")return!0}}return!1},r=[];let l=!1,a=!1,u=!1,c=0;for(;c<t;){const d=e.indexOf(` -`,c),h=d===-1||d>=t?t:d,p=e.slice(c,h),g=p.endsWith("\r")?p.slice(0,-1):p,m=m1(g);if(m){const k=g.slice(m.index);if(l)l=!k.includes("-->");else if(a)a=!k.includes(">");else if(u)u=!k.includes("?>");else if(k.startsWith("<!--"))l=!k.includes("-->");else if(k.startsWith("<?"))u=!k.includes("?>");else if(k.startsWith("<!"))a=!k.includes(">");else{const w=o(k);if(w)if(w.closing){for(let y=r.length-1;y>=0;y--)if(r[y]===w.tag){r.length=y;break}}else w.selfClosing||s(w.after,w.tag)||r.push(w.tag)}}if(d===-1||d>=t)break;c=d+1}return l||a||u||r.length>0}function NMe(e,t,n){if(!n?.length)return!1;const i=new Set(wf(n));if(!i.size)return!1;const o=c=>{const d=c.charCodeAt(0);return d>=65&&d<=90||d>=97&&d<=122||d>=48&&d<=57||c==="_"||c==="-"||c===":"},s=c=>c===" "||c===" ",r=c=>{if(c[0]!=="<")return null;let d=1;for(;d<c.length&&s(c[d]);)d++;const h=c[d]==="/";if(h)for(d++;d<c.length&&s(c[d]);)d++;const p=d;for(;d<c.length&&o(c[d]);)d++;if(d===p)return null;const g=c.slice(p,d).toLowerCase();if(!i.has(g))return null;const m=c[d];if(m&&m!==" "&&m!==" "&&m!==">"&&m!=="/")return null;const k=c.indexOf(">",d);if(k===-1)return null;let w=k-1;for(;w>=0&&s(c[w]);)w--;return{closing:h,tag:g,selfClosing:!h&&c[w]==="/",after:c.slice(k+1)}},l=(c,d)=>{const h=c.toLowerCase();let p=0;for(;p<h.length;){const g=h.indexOf("</",p);if(g===-1)return!1;for(p=g+2;p<h.length&&s(h[p]);)p++;if(h.startsWith(d,p)){const m=h[p+d.length];if(!m||m===" "||m===" "||m===">")return!0}}return!1},a=[];let u=0;for(;u<t;){const c=e.indexOf(` -`,u),d=c===-1||c>=t?t:c,h=e.slice(u,d),p=h.endsWith("\r")?h.slice(0,-1):h,g=m1(p);if(g){const m=r(p.slice(g.index));if(m)if(m.closing){for(let k=a.length-1;k>=0;k--)if(a[k]===m.tag){a.length=k;break}}else m.selfClosing||l(m.after,m.tag)||a.push(m.tag)}if(c===-1||c>=t)break;u=c+1}return a.length>0}function FMe(e,t){const n=uMe.exec(e);if(!n)return null;const i=n[1]??"",o=n.index+i.length,s=e.indexOf(` -`,o),r=e.slice(o,s===-1?e.length:s);return!m1(r.endsWith("\r")?r.slice(0,-1):r)||NO(e,o)||LMe(e,o)||NMe(e,o,t)?null:`${e.slice(0,n.index)}${i}`}function R7(e,t,n){let i=t;for(;i<e.length&&e[i]===n;)i++;return i-t}function FO(e,t,n){let i=t;for(;i<e.length;){const o=e.indexOf("`",i);if(o===-1)return-1;const s=R7(e,o,"`");if(s===n)return o;i=o+s}return-1}function sk(e){e.inFence=!1,e.fenceChar="",e.fenceLen=0,e.fenceInBlockquote=!1,e.fenceInList=!1,e.fenceListIndent=0}function OI(e,t,n,i,o){let s=0,r=!1;for(;s<e.length;){const l=s;if(t.inMath){if(e.startsWith("\\]",s)&&!Na(e,l)){i!=null&&o&&n+s+2>i&&(r=!0),t.inMath=!1,t.mathOpenOffset=null,s+=2;continue}s++;continue}if(t.inDollarMath){if(e.startsWith("$$",s)&&!Na(e,l)){i!=null&&o&&n+s+2>i&&(r=!0),t.inDollarMath=!1,t.dollarMathOpenOffset=null,s+=2;continue}s++;continue}if(e[s]==="`"&&!Na(e,l)){const a=R7(e,s,"`"),u=FO(e,s+a,a);if(u===-1)break;s=u+a;continue}if(e.startsWith("\\[",s)&&!Na(e,l)){t.inMath=!0,t.mathOpenOffset=n+s,s+=2;continue}if(e.startsWith("$$",s)&&!Na(e,l)){t.inDollarMath=!0,t.dollarMathOpenOffset=n+s,s+=2;continue}s++}return r}function DMe(e,t){if(!S7(t))return e;const n=t,i=BI.get(n),o=i?.source===e?i.state:i&&e.startsWith(i.source)?DO(i.state,e.slice(i.source.length),i.source.length-i.state.lineBuffer.length).state:E9(e).state;BI.set(n,{source:e,state:o});const{context:s}=o,r=s.inMath?s.mathOpenOffset:s.inDollarMath?s.dollarMathOpenOffset:null;if(r==null)return e;const l=e.slice(r+2),a=e.lastIndexOf(` -`,r-1)+1;if(e.slice(a,r).trim()!==""&&!/^\r?\n/.test(l)||/^\s*!\[/.test(l))return e;const u=l.trim(),c=/^(?:[a-z]|pi)$/i.test(u);return ac(l)&&!c?e:e.slice(0,r)}function BMe(e,t,n,i,o){const s=F7(e),r=D7(e);if(t.inFence&&t.fenceInBlockquote&&e.trim()&&B7(e)==null&&sk(t),t.inFence&&t.fenceInList&&e.trim()&&s.column<t.fenceListIndent&&!r&&sk(t),r?t.listContentIndent=r.contentIndent:e.trim()&&t.listContentIndent!=null&&s.column<t.listContentIndent&&!t.inFence&&(t.listContentIndent=null),!t.inMath&&!t.inDollarMath){const l=$7(e);if(l)t.inFence?l.markerChar===t.fenceChar&&l.markerLen>=t.fenceLen&&/^\s*$/.test(l.rest)&&sk(t):(t.inFence=!0,t.fenceChar=l.markerChar,t.fenceLen=l.markerLen,t.fenceInBlockquote=l.inBlockquote,t.fenceInList=l.inList||t.listContentIndent!=null&&!l.inBlockquote&&s.column>=t.listContentIndent,t.fenceListIndent=l.listIndent||t.listContentIndent||0);else if(!t.inFence)return OI(e,t,n,i,o)}else return OI(e,t,n,i,o);return!1}function E9(e,t=_Me(),n=null,i=!1,o=0){const s=Zp(t);let r=Zp(t),l="",a=!1,u=0;for(;u<e.length;){const c=e.indexOf(` -`,u),d=c!==-1,h=d&&c>u&&e[c-1]==="\r"?c-1:d?c:e.length,p=e.slice(u,h);BMe(p,s,o+u,n,i)&&(a=!0),d?(r=Zp(s),l=""):l=p,u=d?c+1:e.length}return{closedOpenMath:a,state:{committedContext:r,context:s,lineBuffer:l}}}function DO(e,t,n=0){return t&&!e.context.inMath&&!e.context.inDollarMath&&!e.context.inFence&&!e.committedContext.inFence&&!/[\\$`~\r\n]/.test(t)&&!(e.lineBuffer.endsWith("\\")&&(t[0]==="["||t[0]==="]"))?{closedOpenMath:!1,state:{committedContext:Zp(e.committedContext),context:Zp(e.context),lineBuffer:e.lineBuffer+t}}:E9(e.lineBuffer+t,e.committedContext,n+e.lineBuffer.length,e.context.inMath||e.context.inDollarMath,n)}function $Me(e,t){if(!S7(e))return;const n=e.stream;if(typeof n?.reset!="function")return;const i=e,o=I9.get(i);if(o?.source===t)return;const s=o?t.startsWith(o.source):!1,r=s&&o?t.slice(o.source.length):"",l=s&&o?DO(o.explicitBracketMath,r,o.source.length-o.explicitBracketMath.lineBuffer.length):E9(t),a=l.state,u=s&&o?l.closedOpenMath:!1;if(o&&s&&o.key===null&&o.pendingCandidate===!1&&!u&&!TMe(o.source,r)&&!IMe(t)){o.source=t,o.explicitBracketMath=a;return}const c=vSe(t);(o&&(o&&!s||o.key!==c||u)||!o&&c)&&n.reset(),MMe(e,t,c,a)}function RMe(e){return typeof e.preTransformTokens=="function"||typeof e.postTransformTokens=="function"}function BO(e,t){const n=e?.map,i=t?.map;return n===i?!0:!Array.isArray(n)||!Array.isArray(i)?!1:n.length===i.length&&n.every((o,s)=>o===i[s])}function zMe(e,t){const n=e?.attrs,i=t?.attrs;if(n===i)return!0;if(!Array.isArray(n)||!Array.isArray(i)||n.length!==i.length)return!1;for(let o=0;o<n.length;o++){const s=n[o],r=i[o];if(s[0]!==r[0]||s[1]!==r[1])return!1}return!0}function PI(e,t){return!!e&&!!t&&e.type===t.type&&e.tag===t.tag&&e.nesting===t.nesting&&e.level===t.level&&e.markup===t.markup&&e.content===t.content&&e.info===t.info&&BO(e,t)&&zMe(e,t)}function rk(e,t){return!!e&&!!t&&e.type===t.type&&e.tag===t.tag&&e.nesting===t.nesting&&e.markup===t.markup&&e.content===t.content&&BO(e,t)}function jI(e,t){return e[t]?.type==="paragraph_open"&&e[t+1]?.type==="inline"&&e[t+2]?.type==="paragraph_close"}function OMe(e){for(let t=0;t+5<e.length;t++)if(jI(e,t)&&jI(e,t+3)&&rk(e[t],e[t+3])&&rk(e[t+1],e[t+4])&&rk(e[t+2],e[t+5]))return!0;return!1}function PMe(e,t,n){return S7(e)&&aO(t)&&OMe(n)}function jMe(e){const t=I9.get(e);return typeof t?.key=="string"&&t.key.startsWith("pending:")}function HI(e,t,n,i){const o=e;if(i.customHtmlTags?.length&&(n.__markstreamCustomHtmlTags=i.customHtmlTags),!N7(e,i)||($Me(e,t),jMe(e)))return Sp.set(o,"sync"),e.parse(t,n);const s=e.stream.parse(t,CMe(e,n));if(PMe(e,t,s))return e.stream?.reset?.(),Sp.set(o,"sync"),e.parse(t,n);const r=e.stream?.stats?.();if(Sp.set(o,r?.lastMode??"stream"),!RMe(i))return s;const l=_O(i);if(!l)return zI(s,!0);const a=Jl(),u=zI(s,!0);return vc(l,"tokenCloneMs",Jl()-a),u}function T9(e){const t=e?.customHtmlTags;if(!Array.isArray(t)||t.length===0)return B0;const n=new Set(B0);for(const i of wf(t))i&&n.add(i);return n}function HMe(e){const t=e.raw;if(typeof t=="string")return t;const n=e.content;return typeof n=="string"?n:e.type==="hardbreak"?"<br>":""}function WI(e){return{type:"paragraph",children:e,raw:e.map(HMe).join("")}}function qI(e,t){if(t.sourceMap)for(const n of e)n.sourceMap||(n.sourceMap=t.sourceMap)}function UI(e,t){if(e.type!=="paragraph")return null;const n=e.children,i=Array.isArray(n)?n:[];if(i.length===0)return null;const o=AMe(t);if(!o?.size)return null;let s=-1;for(let c=0;c<i.length;c++){const d=i[c];if(!o.has(String(d?.type??"").toLowerCase()))continue;const h=i.slice(0,c);if(String(d.content??"").trim()&&h.some(p=>p?.type==="hardbreak")){s=c;break}}if(s===-1)return null;const r=i.slice(0,s),l=i[s];if(!l)return null;const a=[];r.length&&a.push(WI(r)),a.push(l);const u=i.slice(s+1);return u.length&&a.push(WI(u)),a}function WMe(e){const t=e.trim();if(!t)return null;const n=/^(?:<!doctype\s+html[^>]*>\s*)?<html(?:\s[^>]*)?>/i.test(t),i=/<\/html>\s*$/i.test(t);return!n||!i?null:[{type:"html_block",tag:"html",raw:e,content:e,loading:!1}]}function Gp(e){const t=e.raw;if(typeof t=="string")return t;const n=e.content;return typeof n=="string"?n:""}function qMe(e,t){if(e.type!=="html_block"||!t)return!1;const n=String(e.raw??e.content??"");return new RegExp(String.raw`^\s*<\s*\/\s*${fa(t)}\s*>\s*$`,"i").test(n)}const lk=new Set(["iframe","script","style","textarea","title"]);function bg(e,t,n){if(!e||!t)return null;const i=t.toLowerCase(),o=h=>{if(e.startsWith("<!--",h)){const b=e.indexOf("-->",h+4);return{closing:!1,end:b===-1?e.length:b+3,selfClosing:!1,tag:""}}if(e.startsWith("<![CDATA[",h)){const b=e.indexOf("]]>",h+9);return{closing:!1,end:b===-1?e.length:b+3,selfClosing:!1,tag:""}}const p=Do(e.slice(h));if(p===-1)return null;const g=h+p+1,m=e.slice(h,g);if(/^<\s*[!?]/.test(m))return{closing:!1,end:g,selfClosing:!1,tag:""};let k=m.slice(1).trimStart();const w=k.startsWith("/");w&&(k=k.slice(1).trimStart());const y=k.match(/^([A-Z][\w:-]*)/i);return y?.[1]?{closing:w,end:g,selfClosing:/\/\s*>$/.test(m),tag:y[1].toLowerCase()}:{closing:!1,end:h+1,selfClosing:!1,tag:""}},s=(h,p)=>{const g=new RegExp(String.raw`<\s*\/\s*${fa(h)}(?=\s|>)`,"gi");g.lastIndex=p;const m=g.exec(e);if(!m||m.index==null)return null;const k=o(m.index);return k?{start:m.index,end:k.end}:null};let r=-1,l=-1,a=Math.max(0,n);for(;a<e.length;){const h=e.indexOf("<",a);if(h===-1)return null;const p=o(h);if(!p)return null;if(!p.closing&&p.tag===i){r=h,l=p.end-1;break}if(!p.closing&&lk.has(p.tag)){a=s(p.tag,p.end)?.end??e.length;continue}a=p.end}if(r===-1||l===-1)return null;const u=e.slice(r,l+1);if(Tc.has(i)||/\/\s*>$/.test(u))return{raw:u,start:r,end:l+1,closed:!0};if(lk.has(i)){const h=s(i,l+1);return h?{raw:e.slice(r,h.end),start:r,end:h.end,closeStart:h.start,closed:!0}:{raw:e.slice(r),start:r,end:e.length,closed:!1}}let c=1,d=l+1;for(;d<e.length;){const h=e.indexOf("<",d);if(h===-1)return{raw:e.slice(r),start:r,end:e.length,closed:!1};const p=o(h);if(!p)return null;if(p.closing&&p.tag===i){c--;const g=p.end;if(c===0)return{raw:e.slice(r,g),start:r,end:g,closeStart:h,closed:!0};d=g;continue}if(!p.closing&&p.tag===i){!p.selfClosing&&!Tc.has(p.tag)&&c++,d=p.end;continue}if(!p.closing&&lk.has(p.tag)){d=s(p.tag,p.end)?.end??e.length;continue}d=p.end}return{raw:e.slice(r),start:r,end:e.length,closed:!1}}function UMe(e,t){if(!t)return 0;let n=0,i=0;for(;n<e.length&&i<t.length;){if(e[n]===t[i]){n++,i++;continue}if(e[n]==="\r"||e[n]===` -`){n++;continue}return-1}return i===t.length?n:-1}function KMe(e,t,n){return n?e:`${e.replace(/<[^>]*$/,"")} -</${t}>`}function KI(e){return e.replace(/\r\n/g,` -`).replace(/(^|\n)[ \t]{1,4}/g,"$1")}function VMe(e,t,n){return n?e.includes(n,t)?!0:KI(e.slice(Math.max(0,t))).includes(KI(n)):!1}function ZMe(e,t){let n=Math.max(0,t);for(;n<e.length&&(e[n]===" "||e[n]===" ");)n++;return e[n]==="\r"?(n++,e[n]===` -`&&n++,n):e[n]===` -`?n+1:t}function VI(e){if(e.type!=="html_block"||String(e.tag??"").toLowerCase()!=="details")return!1;const t=String(e.raw??e.content??"");return/^\s*<details\b/i.test(t)}function GMe(e){if(e.type!=="html_block")return!1;const t=String(e.raw??e.content??"");return/^\s*<\/details\b/i.test(t)}function $O(e,t){const n=new RegExp(String.raw`<\s*\/\s*${fa(t)}(?=\s|>)`,"gi");let i=-1,o;for(;(o=n.exec(e))!==null;)i=o.index;return i}function RO(e,t){return{final:t,__disableStreamParse:!0,requireClosingStrong:e.requireClosingStrong,customHtmlTags:e.customHtmlTags,validateLink:e.validateLink}}const QMe=new Set(["admonition","blockquote","code_block","definition_list","footnote","heading","list","math_block","table","thematic_break"]),YMe=/(?:^|\n)\s{0,3}(?:#{1,6}\s+\S|[-+*]\s+\S|\d+[.)]\s+\S|>\s*\S|`{3,}|~{3,}|(?:\*{3,}|-{3,}|_{3,})(?:\s|$)|\|.*\|)/m;function JMe(e){return/\n\s*\n/.test(e)||YMe.test(e)}function XMe(e,t){if(!e.trim()||t.length===0)return!1;if(t.some(i=>QMe.has(String(i?.type??"").toLowerCase()))||t.some(i=>{if(i?.type!=="html_block")return!1;const o=i;return Array.isArray(o.children)&&o.children.length>0}))return!0;if(!JMe(e))return!1;if(t.length>1)return!0;const[n]=t;return!!(n&&n.type==="paragraph")}function eIe(e){const t=[];let n=0;for(;n<e.length;){for(;/\s/.test(e[n]??"");)n++;if(n>=e.length)break;const i=e.slice(n).match(/^<([A-Z][\w:-]*)/i);if(!i?.[1])return null;const o=bg(e,i[1],n);if(!o||o.start!==n)return null;t.push(o.raw),n=o.end}return t.length>1?t:null}function tIe(e,t,n,i){const o=n.customHtmlTags?.join("\0")??"",s=t,r=DI.get(s),l=r&&r.final===i&&r.customHtmlTags===o&&r.requireClosingStrong===n.requireClosingStrong&&r.validateLink===n.validateLink,a=e.map((u,c)=>l&&r.blocks[c]===u?r.children[c]:zh(u,t,n));return DI.set(s,{blocks:e,children:a,customHtmlTags:o,final:i,requireClosingStrong:n.requireClosingStrong,validateLink:n.validateLink}),a.flat()}function nIe(e,t,n,i){return e.map(o=>{if(o?.type!=="html_block")return o;const s=o,r=String(s.tag??"").toLowerCase();if(!r||r==="details"||$z.has(r)||Array.isArray(s.children))return o;const l=String(o.raw??s.content??"");if(!l)return o;const a=Do(l);if(a===-1)return o;const u=bg(l,r,0),c=u?.closeStart??-1,d=u?.closed===!0&&c>=a+1,h=d?l.slice(a+1,c):l.slice(a+1);if(!h.trim())return o;const p=RO(n,i),g=d?null:eIe(h),m=g?tIe(g,t,p,i):zh(h,t,p);return XMe(h,m)?{...o,children:m}:o})}function iIe(e){for(const t of e)if(t?.type==="html_block")return!0;return!1}function zh(e,t,n){return e.trim()?OO(e,t,{...n,__disableStreamParse:!0,__disableStructuredReuse:!0}):[]}function oIe(e,t,n){const i=zh(e,t,n),o=i[0];return i.length===1&&o?.type==="paragraph"&&Array.isArray(o.children)?o.children:i}function sIe(e,t,n){const i=CO({content:e}),o=Do(e),s=$O(e,"summary");if(o!==-1&&s!==-1&&s>=o+1){const r=oIe(e.slice(o+1,s),t,n);r.length>0&&(i.children=r)}return i.raw=e,i}function rIe(e,t,n){const i=Do(e);if(i===-1)return[];const o=e.slice(i+1);if(!o.trim())return[];const s=bg(o,"summary",0);if(!s)return zh(o,t,n);const r=o.slice(0,s.start),l=o.slice(s.end);return[...zh(r,t,n),sIe(s.raw,t,n),...zh(l,t,n)]}function zO(e,t,n,i,o,s=0){const r=[];let l=s;for(let a=0;a<e.length;a++){const u=e[a],c=Gp(u);let d=-1;if(c&&(d=t.indexOf(c,l),d!==-1&&(l=d+c.length)),!VI(u)){r.push(u);continue}const h=String(u.raw??Gp(u)??""),p=d!==-1?d:t.indexOf(h,Math.max(0,l-h.length));if(p===-1){r.push(u);continue}let g=1,m=-1;for(let P=a+1;P<e.length;P++){const Z=e[P];if(VI(Z)){g++;continue}if(GMe(Z)&&(g--,g===0)){m=P;break}}const k=bg(t,"details",p),w=m===-1&&k?.closed===!0,y=w?(()=>{const P=$O(h,"details");return P!==-1?h.slice(0,P):h})():h,[b]=zO(w?[]:m===-1?e.slice(a+1):e.slice(a+1,m),t,n,i,o,p+h.length),A=rIe(y,n,RO(i,o)),T=m===-1?"</details>":String(e[m].raw??Gp(e[m])??"</details>"),S=w||m!==-1&&k?.closed===!0,x=T.replace(/[\t\r\n ]+$/,""),_=S?(()=>{const P=(k?.raw??"").lastIndexOf(x);return P===-1?t.length:p+P})():t.length,L=Do(h),M=w&&L!==-1?p+L+1:p+h.length,N=t.slice(M,_===-1?t.length:_),I=n.parse(N,{__markstreamFinal:o}),z=n.renderer.render(I,n.options,{__markstreamFinal:o}),H=_+x.length,O=S?Math.max(_+T.length,ZMe(t,H)):t.length,R=S?t.slice(_,O):T,j=S?t.slice(p,O):t.slice(p),$=w&&L!==-1?h.slice(0,L+1):h,W={...u,tag:"details",attrs:_9(h.slice(0,L+1)),raw:j,content:`${$}${z}${R}`,children:[...A,...b],loading:!o&&!S};if(i.includeSourceMap&&(W.sourceMap=O0(t,p,S?O:t.length,i)),r.push(W),l=S?O:t.length,m===-1&&!w)break;m!==-1&&(a=m)}return[r,l]}function lIe(e,t,n,i){if(!n)return e;const o=e.slice();let s=0;for(let r=0;r<o.length;r++){const l=o[r],a=Gp(l),u=a?n.indexOf(a,s):-1;if(l?.type!=="html_block"){u!==-1&&(s=u+a.length);continue}const c=String(l.tag??"").toLowerCase();if(!c)continue;if(c==="details"){u!==-1&&(s=u+a.length);continue}const d=bg(n,c,u!==-1?u:s);if(!d)continue;s=d.end;const h=String(l.content??a),p=String(l.raw??h),g=u+p.length;if(u!==-1&&d.end<g&&n.slice(u,g)===p){s=g,i?.includeSourceMap&&(l.sourceMap=O0(n,u,g,i));continue}const m=KMe(d.raw,c,d.closed),k=!t&&!d.closed,w=h!==m||p!==d.raw||!!l.loading!==k,y=Do(d.raw),b=y===-1?"":d.raw.slice(0,y+1),A=b?_9(b):[];if(l.content=m,l.raw=d.raw,l.loading=k,l.attrs=A.length?A:void 0,i?.includeSourceMap&&(l.sourceMap=O0(n,d.start,d.end,i)),!w)continue;let T=UMe(d.raw,p);T===-1&&(T=0);const S=r+1;for(;S<o.length;){if(d.closed&&qMe(o[S],c)){o.splice(S,1);continue}const x=Gp(o[S]);if(!x)break;const _=d.raw.indexOf(x,T);if(_===-1){if(VMe(n,d.end,x))break;const L=SO.get(o[S]);if(!L)break;if(L.start>=d.start&&L.end<=d.end){o.splice(S,1);continue}break}T=_+x.length,o.splice(S,1)}}return o}function aIe(e){const t=l=>l===" "||l===" "||l===` -`||l==="\r",n=l=>{if(!l||l[0]!=="<"||l.includes(">"))return!1;let a=1;if(a<l.length&&t(l[a])||l.startsWith("<!--")||l.startsWith("<?")||l.startsWith("<!")||l[a]==="/"&&(a++,a<l.length&&t(l[a])))return!1;const u=m=>{const k=m.charCodeAt(0);return k>=65&&k<=90||k>=97&&k<=122},c=m=>{const k=m.charCodeAt(0);return k>=48&&k<=57},d=m=>m==="!"||u(m),h=m=>u(m)||c(m)||m===":"||m==="-",p=m=>u(m)||c(m)||m==="_"||m==="."||m===":"||m==="-",g=p;if(a>=l.length||!d(l[a]))return!1;for(a++;a<l.length&&h(l[a]);)a++;for(;a<l.length;){for(;a<l.length&&t(l[a]);)a++;if(a>=l.length)return!0;if(l[a]==="/"){for(a++;a<l.length&&t(l[a]);)a++;return a>=l.length}if(!p(l[a]))return!1;for(a++;a<l.length&&g(l[a]);)a++;for(;a<l.length&&t(l[a]);)a++;if(a<l.length&&l[a]==="="){for(a++;a<l.length&&t(l[a]);)a++;if(a>=l.length)return!0;const m=l[a];if(m==='"'||m==="'"){for(a++;a<l.length&&l[a]!==m;)a++;if(a>=l.length)return!0;a++}else{for(;a<l.length;){const k=l[a];if(t(k)||k==="<"||k===">"||k==='"'||k==="'"||k==="`")break;a++}if(a>=l.length)return!0}}}return!0},i=(l,a)=>NO(l,a),o=String(e??""),s=o.lastIndexOf("<");if(s===-1||i(o,s))return o;if(s>0){const l=o[s-1],a=l===" "||l===" "||l===` -`||l==="\r",u=o[s-2];if(!a&&!((l==="n"||l==="r")&&u==="\\"))return o}const r=o.slice(s);return r.includes(">")||r.length>1&&(r[1]===" "||r[1]===" "||r[1]===` -`||r[1]==="\r")||!n(r)?o:o.slice(0,s)}function ZI(e,t){if(e===t)return;const n=e.split(/\r?\n/),i=t.split(/\r?\n/),o=[];let s=0;for(let r=0;r<i.length;r++){const l=i[r]??"";if(n[s]===l){o[r]={startLine:s,endLine:s+1},s++;continue}const a=n[s]??"";if(l!==""&&a!==l&&a.startsWith(l)){let p=l,g=-1;for(let m=r+1;m<i.length;m++){if(p+=i[m]??"",p===a){g=m;break}if(!a.startsWith(p))break}if(g!==-1){for(let m=r;m<=g;m++)o[m]={startLine:s,endLine:s+1};s++,r=g;continue}o[r]={startLine:s,endLine:s+1};continue}let u=n[s]??"",c=-1;for(let p=s+1;p<n.length;p++){if(u+=`\\n${n[p]??""}`,u===l){c=p+1;break}if(!l.startsWith(u))break}if(c!==-1){o[r]={startLine:s,endLine:c},s=c;continue}let d=-1;if(l!==""){const p=Math.min(n.length,s+80);for(let g=s;g<p;g++)if(n[g]===l){d=g;break}}if(d!==-1){o[r]={startLine:d,endLine:d+1},s=d+1;continue}const h=Math.min(Math.max(0,n.length-1),Math.max(0,s-1));o[r]={startLine:h,endLine:h+1}}return r=>{const l=Number.isFinite(r)?Math.max(0,Math.trunc(r)):0;if(l<o.length)return o[l]??{startLine:0,endLine:0};const a=o[o.length-1]??{startLine:Math.max(0,n.length-1),endLine:n.length},u=Math.min(n.length,a.endLine+l-o.length);return{startLine:u,endLine:Math.min(n.length,u+1)}}}function uIe(e,t){if(!e||!t.length)return e;const n=new Set(t.map(g=>String(g??"").toLowerCase()).filter(Boolean));if(!n.size)return e;const i=g=>g===" "||g===" ",o=g=>{const m=g.charCodeAt(0);return m>=65&&m<=90||m>=97&&m<=122||m>=48&&m<=57||g==="_"||g==="-"||g===":"},s=g=>{if(!g)return!1;if(g[0]===" ")return!0;let m=0;for(let k=0;k<g.length;k++){const w=g[k];if(w===" "){if(m++,m>=4)return!0;continue}if(w===" ")return!0;break}return!1},r=g=>{let m=!1,k=!1;for(let w=0;w<g.length;w++){const y=g[w];if(y==="\\"){w++;continue}if(!k&&y==="'"){m=!m;continue}if(!m&&y==='"'){k=!k;continue}if(!m&&!k&&y===">")return w}return-1},l=g=>{let m=0;for(;m<g.length&&i(g[m]);)m++;const k=g[m];if(k!=="`"&&k!=="~")return null;let w=m;for(;w<g.length&&g[w]===k;)w++;const y=w-m;return y<3?null:{markerChar:k,markerLen:y,rest:g.slice(w)}},a=(g,m)=>{if(s(g))return-1;const k=g.replace(/^[ \t]+/,"");if(!k||k.startsWith(">")||k.startsWith("|")||/^(?:[*+-]|\d+[.)])[\t ]+/.test(k))return-1;let w=!1,y=0;for(;y<g.length;){const b=g[y];if(b!=="<"){i(b)||(w=!0),y++;continue}const A=r(g.slice(y));if(A===-1){w=!0,y++;continue}const T=g.slice(y,y+A+1);let S=1;for(;S<T.length&&i(T[S]);)S++;if(S>=T.length){w=!0,y++;continue}const x=T[S];if(x==="!"||x==="?"){w=!0,y+=A+1;continue}if(x==="/"){w=!0,y+=A+1;continue}const _=S;for(;S<T.length&&o(T[S]);)S++;if(S===_){w=!0,y++;continue}const L=T.slice(_,S).toLowerCase(),M=T[S];if(M&&M!==" "&&M!==" "&&M!==">"&&M!=="/"){w=!0,y++;continue}const N=new RegExp(String.raw`<\s*\/\s*${L}\s*>`,"i"),I=/\/\s*>$/.test(T),z=N.test(g.slice(y+A+1)),H=N.test(e.slice(m+y+A+1)),O=/[\r\n]/.test(e.slice(m+y+A+1));if(w&&n.has(L)&&!I&&!z&&(H||O))return y;w=!0,y+=A+1}return-1};let u=!1,c="",d=0,h="",p=0;for(;p<e.length;){const g=e.indexOf(` -`,p),m=g!==-1,k=m&&g>p&&e[g-1]==="\r",w=m?k?g-1:g:e.length,y=e.slice(p,w),b=m?k?`\r -`:` -`:"",A=l(y);let T=y;if(!u&&!A){const S=a(y,p);if(S!==-1){const x=b||` -`;T=`${y.slice(0,S).replace(/[ \t]+$/,"")}${x}${x}${y.slice(S).replace(/^[ \t]+/,"")}`}}h+=T,h+=b,A&&(u?A.markerChar===c&&A.markerLen>=d&&/^\s*$/.test(A.rest)&&(u=!1,c="",d=0):(u=!0,c=A.markerChar,d=A.markerLen)),p=m?g+1:e.length}return h}function cIe(e,t){if(!e||!t.length)return e;const n=new Set(t.map(d=>String(d??"").toLowerCase()));if(!n.size)return e;const i=d=>d===" "||d===" ",o=d=>{const h=d.charCodeAt(0);return h>=65&&h<=90||h>=97&&h<=122||h>=48&&h<=57||d==="_"||d==="-"},s=d=>{let h=0;for(;h<d.length&&i(d[h]);)h++;return d.slice(h)},r=d=>{let h=!1,p=!1;for(let g=0;g<d.length;g++){const m=d[g];if(m==="\\"){g++;continue}if(!p&&m==="'"){h=!h;continue}if(!h&&m==='"'){p=!p;continue}if(!h&&!p&&m===">")return g}return-1},l=(d,h,p)=>{const g=p.toLowerCase();let m=d.indexOf("<",h);for(;m!==-1;){let k=m+1;for(;k<d.length&&i(d[k]);)k++;if(k>=d.length||d[k]!=="/"){m=d.indexOf("<",m+1);continue}for(k++;k<d.length&&i(d[k]);)k++;if(k+g.length>d.length){m=d.indexOf("<",m+1);continue}let w=!0;for(let b=0;b<g.length;b++){const A=d[k+b];if((A>="A"&&A<="Z"?String.fromCharCode(A.charCodeAt(0)+32):A)!==g[b]){w=!1;break}}if(!w){m=d.indexOf("<",m+1);continue}let y=k+g.length;if(y<d.length&&o(d[y])){m=d.indexOf("<",m+1);continue}for(;y<d.length&&i(d[y]);)y++;if(y<d.length&&d[y]===">")return!0;m=d.indexOf("<",m+1)}return!1},a=d=>{let h=0;for(;h<d.length&&i(d[h]);)h++;if(h>=d.length||d[h]!=="<")return d;for(h++;h<d.length&&i(d[h]);)h++;if(h>=d.length||d[h]==="/")return d;const p=h;for(;h<d.length&&o(d[h]);)h++;if(h===p)return d;const g=d.slice(p,h).toLowerCase();if(!n.has(g))return d;const m=r(d.slice(h));if(m===-1)return d;const k=h+m;if(l(d,k+1,g))return d;const w=s(d.slice(k+1));return w?`${d.slice(0,k+1)} -${w}`:d};let u="",c=0;for(;c<e.length;){const d=e.indexOf(` -`,c);if(d===-1){u+=a(e.slice(c));break}const h=d>c&&e[d-1]==="\r",p=h?d-1:d,g=e.slice(c,p);u+=a(g),u+=h?`\r -`:` -`,c=d+1}return u}function dIe(e,t){if(!e||!t.length)return e;const n=new Set(t.map(h=>String(h??"").toLowerCase()));if(!n.size)return e;const i=h=>h===" "||h===" ",o=h=>{let p=0,g=!1,m=0;for(;p<h.length;){for(;p<h.length&&i(h[p]);)p++;if(p>=h.length||h[p]!==">")break;for(g=!0,p++;p<h.length&&i(h[p]);)p++;m=p}return g?{prefix:h.slice(0,m),content:h.slice(m)}:null},s=h=>{let p=0;for(;p<h.length&&i(h[p]);)p++;const g=h[p];if(g!=="`"&&g!=="~")return null;let m=p;for(;m<h.length&&h[m]===g;)m++;const k=m-p;return k<3?null:{markerChar:g,markerLen:k,rest:h.slice(m)}},r=Array.from(n).map(h=>new RegExp(String.raw`(<\s*\/\s*${h}\s*>)${"(?=[\\t ]*(?:#{1,6}[\\t ]+|>|(?:[*+-]|\\d+[.)])[\\t ]+|(?:`{3,}|~{3,})|\\||\\$\\$|:{3,}|\\[\\^[^\\]]+\\]:|(?:-{3,}|\\*{3,}|_{3,})))"}`,"gi"));let l=!1,a="",u=0,c="",d=0;for(;d<e.length;){const h=e.indexOf(` -`,d),p=h!==-1,g=p&&h>d&&e[h-1]==="\r",m=p?g?h-1:h:e.length,k=e.slice(d,m),w=p?g?`\r -`:` -`:"",y=o(k),b=y?.prefix??"",A=y?.content??k,T=s(A);T&&(l?T.markerChar===a&&T.markerLen>=u&&/^\s*$/.test(T.rest)&&(l=!1,a="",u=0):(l=!0,a=T.markerChar,u=T.markerLen));let S=A;if(!l&&S.includes("</"))for(const x of r)S=S.replace(x,(_,L,M,N)=>{if(N.replace(/^[\t ]+/,"").startsWith("|"))return _;const I=N.slice(0,M).replace(/^[\t ]+/,"");if(I.length>0){const z=L.match(/^<\s*\/\s*([A-Z][\w:-]*)/i)?.[1]?.toLowerCase()??"",H=I.match(/^<\s*([A-Z][\w:-]*)/i)?.[1]?.toLowerCase()??"";if(!z||!H||z!==H)return _}return`${L} - -`});if(b){const x=b+S.split(` -`).join(` -${b}`);c+=x}else c+=S;c+=w,d=p?h+1:e.length}return c}function fIe(e,t){if(!e||!t.length)return e;const n=new Set(t.map(I=>String(I??"").toLowerCase()));if(!n.size)return e;const i=I=>I===" "||I===" ",o=I=>{if(!I)return!1;if(I[0]===" ")return!0;let z=0;for(let H=0;H<I.length;H++){const O=I[H];if(O===" "){if(z++,z>=4)return!0;continue}if(O===" ")return!0;break}return!1},s=I=>{const z=I.charCodeAt(0);return z>=65&&z<=90||z>=97&&z<=122||z>=48&&z<=57||I==="_"||I==="-"||I===":"},r=I=>{let z=0;for(;z<I.length&&i(I[z]);)z++;return I.slice(z)},l=I=>{let z=0,H=!1,O=0;for(;z<I.length;){for(;z<I.length&&i(I[z]);)z++;if(z>=I.length||I[z]!==">")break;for(H=!0,z++;z<I.length&&i(I[z]);)z++;O=z}if(!H)return null;const R=I.slice(0,O);return{prefix:R,key:R.replace(/[ \t]+$/,""),content:I.slice(O)}},a=I=>r(I).startsWith("<"),u=I=>{for(let z=0;z<I.length;z++){const H=I[z];if(H!==" "&&H!==" ")return!1}return!0},c=I=>{if(o(I))return"";const z=r(I);if(!z.startsWith("<"))return"";let H=1;for(;H<z.length&&i(z[H]);)H++;if(H>=z.length||z[H]==="/"||z[H]==="!"||z[H]==="?")return"";const O=H;for(;H<z.length&&s(z[H]);)H++;if(H===O)return"";const R=z.slice(O,H).toLowerCase();if(!n.has(R))return"";const j=z[H];return j&&j!==" "&&j!==" "&&j!==">"&&j!=="/"?"":R},d=I=>{if(o(I))return null;const z=r(I);if(!z.startsWith("<"))return null;let H=1;for(;H<z.length&&i(z[H]);)H++;if(H>=z.length)return null;const O=z[H]==="/";if(O)for(H++;H<z.length&&i(z[H]);)H++;const R=z[H];if(!R||R==="!"||R==="?")return null;const j=H;for(;H<z.length&&s(z[H]);)H++;if(H===j)return null;const $=z.slice(j,H).toLowerCase();if(!n.has($))return null;const W=z[H];if(W&&W!==" "&&W!==" "&&W!==">"&&W!=="/")return null;if(O)return{type:"close",name:$};if(/\/\s*>\s*$/.test(z))return{type:"open",name:$,complete:!0};const P=z.indexOf(">",H);if(P!==-1){const Z=z.slice(P+1);if(new RegExp(`<\\s*\\/\\s*${$}\\s*>`,"i").test(Z))return{type:"open",name:$,complete:!0}}return{type:"open",name:$,complete:!1}},h=I=>{if(o(I))return null;const z=r(I).replace(/[ \t]+$/,"");if(!z.startsWith("<")||/^<\s*(?:!--|!doctype\b|\?)/i.test(z))return null;const H=z.match(/^<\s*([A-Z][\w:-]*)\b[^>]*\/\s*>\s*$/i);if(H?.[1])return H[1].toLowerCase();const O=z.match(/^<\s*([A-Z][\w:-]*)\b[^>]*>[\s\S]*<\s*\/\s*([A-Z][\w:-]*)\s*>\s*$/i);if(!O?.[1]||!O[2])return null;const R=O[1].toLowerCase();return R===O[2].toLowerCase()?R:null};let p=!1,g="",m=0;const k=I=>{let z=0;for(;z<I.length&&i(I[z]);)z++;const H=I[z];if(H!=="`"&&H!=="~")return null;let O=z;for(;O<I.length&&I[O]===H;)O++;const R=O-z;return R<3?null:{markerChar:H,markerLen:R,rest:I.slice(O)}},w=I=>k(I),y=I=>{const z=r(I);return z?o(I)?!0:/^(?:#{1,6}[ \t]+|>|[*+-][ \t]+|\d+[.)][ \t]+|`{3,}|~{3,}|\||\$\$|:{3,}|\[\^[^\]]+\]:|-{3,}|\*{3,}|_{3,})/.test(z):!1},b=(I,z,H)=>{let O=I,R=0;for(;O<e.length;){const j=e.indexOf(` -`,O),$=j!==-1,W=$&&j>O&&e[j-1]==="\r",P=$?W?j-1:j:e.length,Z=e.slice(O,P),ae=l(Z),V=ae?.key??"";if(R>0&&z&&V!==z)break;const Y=ae?.content??Z,oe=d(Y);if(oe?.name===H){if(oe.type==="open")oe.complete||R++;else if(R>0&&(R--,R===0))return!1}else if(R>0&&(u(Y)||y(Y)))return!0;if($)O=j+1;else break}return!1};let A="",T=0,S=!0,x=!1,_=!1,L=` -`;const M=[];let N="";for(;T<e.length;){const I=e.indexOf(` -`,T),z=I!==-1,H=z&&I>T&&e[I-1]==="\r",O=z?H?I-1:I:e.length,R=e.slice(T,O),j=z?H?`\r -`:` -`:"",$=l(R),W=$?.key??"",P=$?.content??R,Z=w(P);Z&&(p?Z.markerChar===g&&Z.markerLen>=m&&/^\s*$/.test(Z.rest)&&(p=!1,g="",m=0):(p=!0,g=Z.markerChar,m=Z.markerLen));const ae=M.length>0;if(!p&&!ae){const Y=c(P),oe=!!Y&&!S&&x&&_&&b(T,W,Y);Y&&!S&&(!x||oe)&&(W&&N&&W===N?A+=`${W}${L}`:W||(A+=L))}if(A+=R,A+=j,j&&(L=j),!p){const Y=d(P);if(Y){if(Y.type==="open")Y.complete||M.push(Y.name);else for(let oe=M.length-1;oe>=0;oe--)if(M[oe]===Y.name){M.length=oe;break}}}const V=u(P);S=V,x=!V&&a(P),_=!V&&!!h(P),N=W,T=z?I+1:e.length}return A}function hIe(e){let t=!1,n="",i=0,o=!1,s=!1,r=!1,l=0;const a=(c,d)=>{const h=$7(c);if(h){t?h.markerChar===n&&h.markerLen>=i&&/^\s*$/.test(h.rest)&&(t=!1,n="",i=0):(t=!0,n=h.markerChar,i=h.markerLen);return}if(t)return;let p=0;for(;p<c.length;){if(o){c.startsWith("$$",p)&&!Na(c,p)?(o=!1,p+=2):p++;continue}if(s){c.startsWith("\\]",p)&&!Na(c,p)?(s=!1,p+=2):p++;continue}const g=c[p];if(g==="`"){const m=R7(c,p,"`"),k=FO(c,p+m,m);if(k===-1)break;p=k+m;continue}if(g==="\\"){const m=c[p+1];m==="["&&!Na(c,p)?(s=!0,p+=2):(m==="]"&&Na(c,p),p+=2);continue}if(g==="$"){if(c[p+1]==="$"&&!Na(c,p)){o=!0,r=!1,p+=2;continue}if(r){r=!1,p++;continue}const m=c[p+1];(m===void 0||m!==" "&&m!==" "&&!/\d/.test(m))&&(r=!0),p++;continue}p++}};return{scanTo:c=>{for(;l<c;){const d=e.indexOf(` -`,l),h=d===-1||d>=c?c:d,p=h>l&&e[h-1]==="\r"?h-1:h;if(a(e.slice(l,p)),d===-1||d>=c){l=c;break}r=!1,l=d+1}},inMath:()=>o||s||r}}function ak(e,t,n,i){let o=e.replace(/([^\\])\r(ight|ho)/g,"$1\\r$2");const s=hIe(o);if(o=o.replace(/([^\\])\r?\n(abla|eq|ot|exists)/g,(r,l,a,u)=>{s.scanTo(u+1);const c=s.inMath();return s.scanTo(u+r.length),c?`${l}\\n${a}`:r}),t||(o.endsWith("- *")&&(o=o.replace(/- \*$/,"- \\*")),/(?:^|\n)\s*-\s*$/.test(o)?o=o.replace(/(?:^|\n)\s*-\s*$/,r=>r.startsWith(` -`)?` -`:""):/(?:^|\n)\s*--\s*$/.test(o)?o=o.replace(/(?:^|\n)\s*--\s*$/,r=>r.startsWith(` -`)?` -`:""):/(?:^|\n)\s*>\s*$/.test(o)?o=o.replace(/(?:^|\n)\s*>\s*$/,r=>r.startsWith(` -`)?` -`:""):/\n\s*[*+]\s*$/.test(o)?o=o.replace(/\n\s*[*+]\s*$/,` -`):/(?:^|\n)\s*\d+\s*$/.test(o)?/^\d+$/.test(o.trim())||(o=o.replace(/(?:^|\n)\s*\d+\s*$/,r=>r.startsWith(` -`)?` -`:"")):/(?:^|\n)\s*\d+[.)]\s+\*{1,3}\s*$/.test(o)?o=o.replace(/((?:^|\n)\s*\d+[.)]\s+)(\*{1,3})\s*$/,(r,l,a)=>`${l}${a.split("").map(()=>"\\*").join("")}`):/(?:^|\n)\s*\d+[.)]\s*$/.test(o)?o=o.replace(/(?:^|\n)\s*\d+[.)]\s*$/,r=>r.startsWith(` -`)?` -`:""):/\n[[(]\n*$/.test(o)&&(o=o.replace(/(\n\[|\n\()+\n*$/g,` -`)),o=FMe(o,i.customHtmlTags)??o),i.customHtmlTags?.length&&o.includes("<")){const r=wf(i.customHtmlTags);if(r.length&&(o=uIe(o,r),o=cIe(o,r),o=fIe(o,r),o=dIe(o,r),o.includes("</")))for(const l of r){const a=new RegExp(String.raw`(^[\t ]*<\s*\/\s*${l}\s*>[\t ]*)(\r?\n)(?![\t ]*\r?\n|$)`,"gim");o=o.replace(a,"$1$2$2")}}return t||(o=aIe(o)),o}function pIe(e,t,n,i){const o=e,s=`${n?"final":"stream"}:${(i.customHtmlTags??[]).join(",")}`,r=W8.get(o);let l;if(!n&&!i.customHtmlTags?.length&&r&&r.mode===s&&t.length>=r.source.length&&t.startsWith(r.source)){const a=Math.max(0,r.source.length-cMe-dMe),u=ak(t.slice(a),n,e,i),c=r.source.length-a;l=u.length>=c&&u.slice(0,c)===r.safeMarkdown.slice(-c)?r.safeMarkdown.slice(0,r.safeMarkdown.length-c)+u:ak(t,n,e,i)}else l=ak(t,n,e,i);return n||(l=DMe(l,e)),W8.set(o,{source:t,safeMarkdown:l,mode:s}),l}function OO(e,t,n={}){const i=_O(n),o=i?Jl():0,s=!!n.final,r=(e??"").toString();xMe(t,n)&&(t.stream.reset(),SMe(t),W8.delete(t));const l=pIe(t,r,s,n);i&&vc(i,"safeMarkdownMs",Jl()-o);const a=WMe(l);if(a){if(n.includeSourceMap){const T={...n,__sourceLineMapper:ZI(r,l)};a[0].sourceMap=O0(l,0,l.length,T)}const b=n.preTransformTokens,A=n.postTransformTokens;if(N7(t,n)||typeof b=="function"||typeof A=="function"){const T=HI(t,l,{__markstreamFinal:s},n),S=typeof b=="function"&&b(T)||T;typeof A=="function"&&A(S)}return $I(a,n,i,o)}const u=i?Jl():0,c=HI(t,l,{__markstreamFinal:s},n);if(i&&vc(i,"tokenizeMs",Jl()-u),!c||!Array.isArray(c))return $I([],n,i,o);const d=n.preTransformTokens,h=n.postTransformTokens;let p=c;d&&typeof d=="function"&&(p=d(p)||p);const g=t,m=typeof g.validateLink=="function"&&g.__markstreamOriginalValidateLink&&g.validateLink!==g.__markstreamOriginalValidateLink?g.validateLink:void 0,k=n.validateLink??m??g.options?.validateLink??(typeof g.validateLink=="function"?g.validateLink:void 0),w={...n,validateLink:k,__markdownIt:t,__sourceLineMapper:n.includeSourceMap===!0?ZI(r,l):void 0,__sourceMarkdown:l,__customHtmlBlockCursor:0};let y=bMe(t,l,p,w,i);if(h&&typeof h=="function"){const b=h(p);if(Array.isArray(b)){const A=b[0],T=A?.type;A&&typeof T=="string"?y=ah(b,{...w,__customHtmlBlockCursor:0},i):y=b}}if(iIe(y)){const b=i?Jl():0;y=lIe(y,s,l,w),y=zO(y,l,t,w,s)[0],y=nIe(y,t,w,s),i&&vc(i,"htmlBlockPassesMs",Jl()-b)}if(s){const b=new WeakSet,A=T=>{if(!T||typeof T!="object"||b.has(T))return;if(b.add(T),Array.isArray(T)){for(const x of T)A(x);return}const S=T;S.type==="html_block"&&S.loading===!0&&(S.loading=!1);for(const x of Object.values(S))A(x)};A(y)}return y=IO(y,n),n.debug&&console.log("Parsed Markdown Tree Structure:",y),MO(y,i,o)}function GI(e,t){if(!e||!Array.isArray(e))return[];const n=[],i=Gc(t),o=t?.__linkifyDemotionSeed;if(Array.isArray(o)&&o.length)for(const l of o)i.remember(String(l??""));const s=t?.includeSourceMap===!0;let r=0;for(;r<e.length;){const l=L7(e,r,i.options(),T7);if(l){xa(l[0],e[r],t),n.push(l[0]),i.remember(l[0].raw),r=l[1];continue}const a=e[r];switch(a.type){case"paragraph_open":{const u=String(e[r+1]?.content??""),c=lMe(e,r,i.options(u));s&&di(c,a,t);const d=UI(c,t);if(d){s&&qI(d,c);for(const h of d)xa(h,a,t);n.push(...d)}else xa(c,a,t),n.push(c);i.remember(c.raw),r+=3;break}case"bullet_list_open":case"ordered_list_open":{const[u,c]=p1(e,r,i.options());s&&di(u,a,t),xa(u,a,t),n.push(u),i.remember(u.raw),r=c;break}case"blockquote_open":{const[u,c]=g1(e,r,i.options());s&&di(u,a,t),xa(u,a,t),n.push(u),i.remember(u.raw),r=c;break}case"footnote_anchor":{const u=a.meta??{},c={type:"footnote_anchor",id:String(u.label??a.content??""),raw:String(a.content??"")};s&&di(c,a,t),xa(c,a,t),n.push(c),i.remember(String(a.content??"")),r++;break}case"hardbreak":n.push(rMe()),i.reset(),r++;break;case"text":{const u=String(a.content??""),c={type:"paragraph",raw:u,children:u?[{type:"text",content:u,raw:u}]:[]};s&&di(c,a,t),xa(c,a,t),n.push(c),i.remember(u),r++;break}case"inline":{const u=String(a.content??""),c=Ao(a.children||[],u,void 0,i.options(u));if(c.length!==0)if(c.every(d=>d.type==="html_block")){if(s)for(const d of c)di(d,a,t);for(const d of c)xa(d,a,t);n.push(...c)}else{const d={type:"paragraph",raw:u,children:c};s&&di(d,a,t);const h=UI(d,t);if(h){s&&qI(h,d);for(const p of h)xa(p,a,t);n.push(...h)}else xa(d,a,t),n.push(d)}i.remember(u)}r+=1;break;default:r+=1;break}}return n}const gIe=/\\([ \\!"#$%&'()*+,./:;<=>?@[\]^_`{|}~-])/g,Qp=/\d/u,mIe=/[,.!?;:,。;、!?:]/u,vIe=/\d\p{Script=Han}{1,3}$/u;function yIe(e){return e.pos>0&&e.pos+1<e.posMax&&Qp.test(e.src[e.pos-1])&&Qp.test(e.src[e.pos+1])}function kIe(e,t,n,i,o,s={}){const r=e.charCodeAt(0);return(l,a)=>{const u=l,c=u.posMax,d=u.pos;if(u.src.charCodeAt(d)!==r||a||s.refuseDigitRange&&yIe(u))return!1;u.pos=d+1;let h=!1;for(;u.pos<c;){if(u.src.charCodeAt(u.pos)===r){h=!0;break}u.md.inline.skipToken(u)}if(!h||d+1===u.pos)return u.pos=d,!1;const p=u.src.slice(d+1,u.pos);if(!p||p.match(/(^|[^\\])(\\\\)*\s/))return u.pos=d,!1;const g=u.src[u.pos+1],m=Qp.test(p[0]),k=g!==void 0&&Qp.test(g);if(m&&k&&(vIe.test(u.src.slice(0,d))||mIe.test(p)||Qp.test(p[p.length-1])))return u.pos=d,!1;const w=u.push(n,o,1);w.markup=t;const y=u.push("text","",0);y.content=p.replace(gIe,"$1");const b=u.push(i,o,-1);return b.markup=t,u.pos=u.pos+1,!0}}function bIe(e){const t=kIe("~","~","sub_open","sub_close","sub",{refuseDigitRange:!0});e.inline.ruler.after("emphasis","sub",t)}const AIe=/^([a-z][\w-]*)(?=[\t\n\f\r />]|$)/i,CIe=new Set([...vg,"base","button","datalist","dialog","embed","fieldset","form","iframe","input","legend","link","meta","object","optgroup","option","output","param","select","style","template","textarea","title"]),wIe=new Set(["a","abbr","b","blockquote","br","caption","code","col","colgroup","dd","details","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","i","img","ins","kbd","li","mark","ol","p","picture","pre","s","small","source","span","strong","sub","summary","sup","table","tbody","td","tfoot","th","thead","tr","ul"]);function QI(e,t){return Object.prototype.hasOwnProperty.call(e,t)}function xIe(e){return typeof e=="string"?e:e==null?"":String(e)}function PO(e){return/^[^\s"'<>`=]+$/.test(e)&&!/^on/i.test(e)}function uc(e){return xIe(e).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function jO(e){return uc(e).replace(/`/g,"`")}function L9(e){return String(e??"").trim().toLowerCase()}function z7(e,t="safe"){const n=L9(e);return n?t==="escape"?!0:t==="trusted"?vg.has(n):!wIe.has(n):!1}function HO(e,t="safe"){const n=L9(e);return n?t==="escape"?!0:t==="trusted"?vg.has(n):CIe.has(n):!1}function YI(e){const t=Object.entries(e);return t.length===0?"":t.map(([n,i])=>i===""?` ${n}`:` ${n}="${jO(i)}"`).join("")}function WO(e){const t=e.startsWith("/"),n=t?e.slice(1):e,i=n.match(AIe);return i?{attrsStr:t?"":n.slice(i[0].length).trimStart(),isClosing:t,isSelfClosing:!t&&e.trimEnd().endsWith("/"),tagName:i[1]}:null}function SIe(e,t){const n=e.split(",").map(i=>i.trim()).filter(Boolean);return n.length===0?!1:n.some(i=>{const o=i.split(/\s+/,1)[0]??"";return!o||Gd(o,{tagName:t,attrName:"srcset"})})}function qO(e,t,n,i){return lwe.has(e)||n==="safe"&&e==="style"?!0:e==="srcset"?SIe(t,i):!!(awe.has(e)&&t&&Gd(t,{tagName:i,attrName:e}))}function Fd(e,t){const n=t.toLowerCase();return Object.keys(e).find(i=>i.toLowerCase()===n)}function UO(e,t,n,i=!1){if(t!=="safe"||L9(n)!=="a")return e;const o=Fd(e,"href");if(i&&(!o||!e[o])){const a=Fd(e,"target"),u=Fd(e,"rel");return a&&delete e[a],u&&delete e[u],e}const s=Fd(e,"target");if((s?String(e[s]).trim():"").toLowerCase()!=="_blank")return e;const r=Fd(e,"rel"),l=new Set(String(r?e[r]:"").split(/\s+/).map(a=>a.trim()).filter(Boolean).filter(a=>a.toLowerCase()!=="opener"));return l.add("noopener"),l.add("noreferrer"),r&&r!=="rel"&&delete e[r],e.rel=Array.from(l).join(" "),e}function JI(e,t="safe",n){const i={};for(const[o,s]of Object.entries(e)){const r=o.trim(),l=r.toLowerCase();!r||!PO(r)||qO(l,s,t,n)||(i[r]=s)}return UO(i,t,n,!!Fd(e,"href"))}function KO(e,t){const n=e.toLowerCase();return Bz.has(n)?!1:QI(t,n)||QI(t,e)}function O7(e,t="safe",n){const i={};for(const[o,s]of Object.entries(e)){const r=o.trim(),l=r.toLowerCase();!r||!PO(r)||qO(l,s,t,n)||(i[r]=s)}return UO(i,t,n,!!Fd(e,"href"))}function Yp(e){const t={};if(!Array.isArray(e)||e.length===0)return t;for(const[n,i]of e)n&&(t[String(n)]=i==null?"":String(i));return t}function Fv(e,t="safe",n){const i=O7(Yp(e),t,n),o=Object.entries(i).map(([s,r])=>[s,r]);return o.length>0?o:void 0}function _Ie(e,t){const n=t.toLowerCase();if(["checked","disabled","readonly","required","autofocus","multiple","hidden"].includes(n))return e==="true"||e===""||e===t;if(["value","min","max","step","width","height","size","maxlength"].includes(n)){const i=Number(e);if(e!==""&&!Number.isNaN(i))return i}return e}function MIe(e){const t={};for(const[n,i]of Object.entries(e))t[n]=_Ie(i,n);return t}function uk(e){return e.trim().length>0}function VO(e){const t=[];let n=0;for(;n<e.length;){if(e.startsWith("<!--",n)){const r=e.indexOf("-->",n);if(r!==-1){n=r+3;continue}break}const i=e.indexOf("<",n);if(i===-1){if(n<e.length){const r=e.slice(n);uk(r)&&t.push({type:"text",content:r})}break}if(i>n){const r=e.slice(n,i);uk(r)&&t.push({type:"text",content:r})}if(e.startsWith("![CDATA[",i+1)){const r=e.indexOf("]]>",i);if(r!==-1){t.push({type:"text",content:e.slice(i,r+3)}),n=r+3;continue}break}if(e.startsWith("!",i+1)){const r=e.indexOf(">",i);if(r!==-1){n=r+1;continue}break}const o=e.indexOf(">",i);if(o===-1)break;const s=WO(e.slice(i+1,o));if(!s){const r=e.slice(i,o+1);uk(r)&&t.push({type:"text",content:r}),n=o+1;continue}if(s.isClosing)t.push({type:"tag_close",tagName:s.tagName});else{const r={};if(s.attrsStr){const l=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|(\S*)))?/g;let a;for(;(a=l.exec(s.attrsStr))!==null;){const u=a[1],c=a[2]??a[3]??a[4]??"";u&&!u.endsWith("/")&&(r[u]=c)}}t.push({type:s.isSelfClosing||Tc.has(s.tagName.toLowerCase())?"self_closing":"tag_open",tagName:s.tagName,attrs:r})}n=o+1}return t}function IIe(e){const t=[];let n=0;for(;n<e.length;){if(e.startsWith("<!--",n)){const l=e.indexOf("-->",n);if(l!==-1){n=l+3;continue}break}const i=e.indexOf("<",n);if(i===-1){n<e.length&&t.push({type:"text",content:e.slice(n)});break}if(i>n&&t.push({type:"text",content:e.slice(n,i)}),e.startsWith("![CDATA[",i+1)){const l=e.indexOf("]]>",i);if(l!==-1){t.push({type:"text",content:e.slice(i,l+3)}),n=l+3;continue}break}if(e.startsWith("!",i+1)){const l=e.indexOf(">",i);if(l!==-1){n=l+1;continue}break}const o=e.indexOf(">",i);if(o===-1)break;const s=WO(e.slice(i+1,o));if(!s){t.push({type:"text",content:e.slice(i,o+1)}),n=o+1;continue}if(s.isClosing){t.push({type:"tag_close",tagName:s.tagName}),n=o+1;continue}const r={};if(s.attrsStr){const l=/([^\s=]+)(?:=(?:"([^"]*)"|'([^']*)'|(\S*)))?/g;let a;for(;(a=l.exec(s.attrsStr))!==null;){const u=a[1],c=a[2]??a[3]??a[4]??"";u&&!u.endsWith("/")&&(r[u]=c)}}t.push({type:s.isSelfClosing||Tc.has(s.tagName.toLowerCase())?"self_closing":"tag_open",tagName:s.tagName,attrs:r}),n=o+1}return t}function EIe(e){const t=String(e.tagName??"").trim();if(!t)return"";if(e.type==="tag_close")return`</${uc(t)}>`;const n=Object.entries(e.attrs??{}).map(([i,o])=>o===""?` ${uc(i)}`:` ${uc(i)}="${jO(o)}"`).join("");return e.type==="self_closing"?`<${uc(t)}${n} />`:`<${uc(t)}${n}>`}function TIe(e,t){if(!e||!e.includes("<")||!t||Object.keys(t).length===0)return!1;for(const n of VO(e))if((n.type==="tag_open"||n.type==="self_closing")&&KO(n.tagName??"",t))return!0;return!1}function Oh(e,t="safe"){if(!e)return"";if(t==="escape")return uc(e);const n=IIe(e),i=[],o=[],s=[];for(const r of n){if(r.type==="text"){s.length===0&&o.push(uc(r.content??""));continue}const l=L9(r.tagName);if(!l)continue;if(HO(l,t)){r.type==="tag_open"?s.push(l):r.type==="tag_close"&&s[s.length-1]===l&&s.pop();continue}if(s.length>0)continue;if(t==="safe"&&z7(l,t)){o.push(EIe(r));continue}if(r.type==="self_closing"){o.push(`<${l}${YI(JI(r.attrs??{},t,l))}>`);continue}if(r.type==="tag_open"){o.push(`<${l}${YI(JI(r.attrs??{},t,l))}>`),Tc.has(l)||i.push(l);continue}const a=i.lastIndexOf(l);if(a===-1)continue;for(;i.length>a+1;){const c=i.pop();c&&o.push(`</${c}>`)}const u=i.pop();u&&o.push(`</${u}>`)}for(;i.length>0;){const r=i.pop();r&&o.push(`</${r}>`)}return o.join("")}const LIe=[/javascript:/i,/vbscript:/i,/data:text\/html/i,/expression\s*\(/i,/@import/i],XI="http://www.w3.org/2000/svg",NIe=new Set(["script","style","iframe","object","embed","link","meta"]),FIe=new Set(["svg","style","g","a","defs","marker","path","rect","circle","ellipse","line","polyline","polygon","text","tspan","title","desc","use","image","lineargradient","radialgradient","stop","clippath","mask","pattern"]),DIe=new Set(["href","xlink:href","src","srcdoc","action","data","formaction","poster"]),BIe=new Set(["clip-path","fill","filter","marker-end","marker-mid","marker-start","mask","stroke"]),$Ie=new Set(["circle","ellipse","image","line","path","polygon","polyline","rect","text","tspan","use"]);function RIe(e){return(e.getAttribute("href")||e.getAttribute("xlink:href"))?.startsWith("#")===!0}function zIe(e){return!!(e.getAttribute("href")||e.getAttribute("xlink:href")||e.getAttribute("src"))}function OIe(e){const t=e.nodeName.toLowerCase();return t==="use"?RIe(e):t==="image"?zIe(e):t==="text"||t==="tspan"?!!e.textContent?.trim():$Ie.has(t)}function PIe(e){return e.replace(/(["'])\s*javascript:/gi,"$1#").replace(/\bjavascript:/gi,"#").replace(/(["'])\s*vbscript:/gi,"$1#").replace(/\bvbscript:/gi,"#").replace(/\bdata:text\/html/gi,"#")}function jIe(e,t,n){const i=e.toLowerCase(),o=t.toLowerCase(),s=String(n??"").trim();return s?(i==="use"||i==="marker"||i==="clippath"||i==="mask")&&(o==="href"||o==="xlink:href")?s.startsWith("#")?s:"":i==="a"&&(o==="href"||o==="xlink:href")?Gd(s,{tagName:"a",attrName:"href"})?"":s:i==="image"&&(o==="href"||o==="xlink:href"||o==="src")?Gd(s,{tagName:"img",attrName:"src"})?"":s:o==="href"||o==="xlink:href"?s.startsWith("#")?s:"":Gd(s,{tagName:i,attrName:o})?"":s:""}function HIe(e,t){let n=t+4;for(;n<e.length&&/\s/.test(e[n]??"");)n++;const i=e[n];if(i==='"'||i==="'"){const s=n+1,r=e.indexOf(i,s);if(r===-1)return{next:e.length,url:""};for(n=r+1;n<e.length&&/\s/.test(e[n]??"");)n++;return{next:n<e.length&&e[n]===")"?n+1:n,url:e.slice(s,r)}}const o=n;for(;n<e.length&&e[n]!==")";)n++;return{next:n<e.length?n+1:n,url:e.slice(o,n)}}function ZO(e){return e.replace(/\\([0-9a-f]{1,6}\s?|.)/gi,(t,n)=>{const i=n.trim();if(/^[0-9a-f]+$/i.test(i)){const o=Number.parseInt(i,16);try{return Number.isFinite(o)?String.fromCodePoint(o):""}catch{return""}}return String(n).trim()})}function GO(e){const t=ZO(e),n=t.toLowerCase();let i=0;for(;i<n.length;){const o=n.indexOf("url(",i);if(o===-1)return!1;const s=HIe(t,o);if(i=Math.max(s.next,o+4),!s.url.trim().startsWith("#"))return!0}return!1}function eE(e){const t=ZO(e);return LIe.some(n=>n.test(t))||GO(t)}function WIe(e){if(e.tagName.toLowerCase()!=="a"||e.getAttribute("target")?.trim().toLowerCase()!=="_blank")return;const t=new Set(String(e.getAttribute("rel")??"").split(/\s+/).map(n=>n.trim()).filter(Boolean).filter(n=>n.toLowerCase()!=="opener"));t.add("noopener"),t.add("noreferrer"),e.setAttribute("rel",Array.from(t).join(" "))}function Gm(e){const t=Number.parseFloat(String(e??""));return Number.isFinite(t)?t:0}function QO(e,t){if(e.nodeType===Node.TEXT_NODE){const o=e.textContent??"";o&&t.push(o);return}if(e.nodeType!==Node.ELEMENT_NODE)return;const n=e,i=n.tagName.toLowerCase();if(!NIe.has(i)){if(i==="br"){t.push(` -`);return}for(const o of Array.from(n.childNodes))QO(o,t)}}function qIe(e){for(const t of Array.from(e.querySelectorAll("foreignObject"))){const n=[];QO(t,n);const i=n.join("").split(/\r?\n/).map(c=>c.trim()).filter(Boolean);if(!i.length){t.remove();continue}const o=Gm(t.getAttribute("width")),s=Gm(t.getAttribute("height")),r=Gm(t.getAttribute("x")),l=Gm(t.getAttribute("y")),a=e.ownerDocument.createElementNS(XI,"text");a.setAttribute("x",String(r+o/2)),a.setAttribute("y",String(l+s/2)),a.setAttribute("text-anchor","middle"),a.setAttribute("dominant-baseline","central");const u=t.querySelector(".nodeLabel");if(u?.getAttribute("class")&&a.setAttribute("class",u.getAttribute("class")),i.length===1)a.textContent=i[0];else{const c=-.6*(i.length-1);for(const[d,h]of i.entries()){const p=e.ownerDocument.createElementNS(XI,"tspan");p.setAttribute("x",String(r+o/2)),p.setAttribute("dy",d===0?`${c}em`:"1.2em"),p.textContent=h,a.appendChild(p)}}t.parentNode?.replaceChild(a,t)}}function UIe(e){qIe(e);const t=[e,...Array.from(e.querySelectorAll("*"))];for(const n of t){const i=n.tagName.toLowerCase();if(!FIe.has(i)){n.remove();continue}if(i==="style"&&eE(n.textContent??"")){n.remove();continue}const o=Array.from(n.attributes);for(const s of o){const r=s.name.toLowerCase();if(/^on/i.test(r)){n.removeAttribute(s.name);continue}if(r==="style"&&s.value&&eE(s.value)){n.removeAttribute(s.name);continue}if(r==="srcdoc"){n.removeAttribute(s.name);continue}if(DIe.has(r)&&s.value){const l=jIe(i,r,s.value);if(!l){n.removeAttribute(s.name);continue}l!==s.value&&n.setAttribute(s.name,l);continue}if(BIe.has(r)&&s.value&&GO(s.value)){n.removeAttribute(s.name);continue}if(s.value){const l=PIe(s.value);l!==s.value&&n.setAttribute(s.name,l)}}WIe(n)}}function gct(e){if(typeof DOMParser>"u"||!e)return null;try{const t=new DOMParser().parseFromString(e,"image/svg+xml").documentElement;if(!t||t.nodeName.toLowerCase()!=="svg")return null;const n=t;return UIe(n),KIe(n)?null:n}catch{return null}}function KIe(e){const t=e.getAttribute("viewBox");if(t){const o=t.trim().split(/[\s,]+/);if(o.length===4){const s=Number.parseFloat(o[2]||""),r=Number.parseFloat(o[3]||"");if(!Number.isFinite(s)||!Number.isFinite(r)||s<=0||r<=0)return!0}}const n=[e,...Array.from(e.querySelectorAll("*"))];let i=!1;for(const o of n){OIe(o)&&(i=!0);for(const s of Array.from(o.attributes))if(/\bNaN\b/i.test(s.value)||s.name==="style"&&/max-width:\s*0(?:px)?/i.test(s.value))return!0}return!i}const Qm=[];function ck(e){return String(e??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}function VIe(e){return(String(e||"text").trim().split(/\s+/)[0]||"text").replace(/[^\w+.#:-]/g,"-").replace(/-+/g,"-")||"text"}function ZIe(e){return e.replace(/[^\w:.+-]/g,"-").replace(/-+/g,"-")}function tE(e=`editor-${Date.now()}`,t={}){const n=_Se(t),i=n;i.__markstreamRegisteredPluginCount=Qm.length,i.__markstreamHasCustomParserExtensions=!!(t.plugin?.length||t.apply?.length||Qm.length);const o={"common.copy":"Copy"};let s;if(typeof t.i18n=="function")s=t.i18n;else if(t.i18n&&typeof t.i18n=="object"){const p=t.i18n;s=g=>p[g]??o[g]??g}else s=p=>o[p]??p;if(Array.isArray(t.plugin))for(const p of t.plugin){const g=p;if(Array.isArray(g)){const[m,...k]=g;typeof m=="function"&&n.use(m,...k)}else typeof g=="function"&&n.use(g)}if(Array.isArray(t.apply))for(const p of t.apply)try{p(n)}catch(g){console.error("[getMarkdown] apply function threw an error",g)}if(Qm.length)for(const p of Qm)if(Array.isArray(p)){const[g,...m]=p;typeof g=="function"&&n.use(g,...m)}else typeof p=="function"&&n.use(p);n.use(bIe),n.use(K5e),n.use(W5e);const r=s6e,l=r.default??r;n.use(l),n.use(H5e),n.use(j5e),n.core.ruler.after("block","mark_fence_closed",p=>{const g=p,m=g.src,k=!!g.env?.__markstreamFinal,w=m.split(/\r?\n/);for(const y of g.tokens){if(y.type!=="fence"||!y.map||!y.markup)continue;const b=y.map[0],A=y.map[1],T=y.markup,S=T[0],x=T.length,_=w[Math.max(0,A-1)]??"";let L=0;for(;L<_.length&&(_[L]===" "||_[L]===" ");)L++;let M=0;for(;L+M<_.length&&_[L+M]===S;)M++;let N=L+M;for(;N<_.length&&(_[N]===" "||_[N]===" ");)N++;const I=k?!0:A>b+1&&M>=x&&N===_.length,z=y;z.meta=z.meta??{},z.meta.unclosed=!I,z.meta.closed=!!I}}),n.renderer.rules.fence=(p,g)=>{const m=p[g],k=String(m.info??"").trim(),w=String(m.content??""),y=btoa(unescape(encodeURIComponent(w))),b=VIe(k),A=ck(b),T=ZIe(`editor-${e}-${g}-${b}`),S=ck(s("common.copy"));return`<div class="code-block" data-code="${y}" data-lang="${A}" id="${T}"> - <div class="code-header"> - <span class="code-lang">${ck(b.toUpperCase())}</span> - <button class="copy-button" data-code="${y}">${S}</button> - </div> - <div class="code-editor"></div> - </div>`};const a=/^\[(\d+)\]/,u=/^\[([^\]\n]+)\]/,c=p=>{if(!p.startsWith("["))return!1;const g=u.exec(p);if(!g)return p!=="["&&!/^\[\d+$/.test(p);const m=String(g[1]??"");return p.slice(g[0].length).startsWith("(")?!1:!/^\d+$/.test(m)},d=(p,g)=>{const m=p;if(m.src[m.pos]!=="[")return!1;const k=a.exec(m.src.slice(m.pos));if(!k)return!1;const w=m.src.slice(Math.max(0,m.pos-120),m.pos);if(/"[^"\n]{1,80}"\s*:\s*$/.test(w))return!1;const y=m.src.slice(m.pos+k[0].length);if(y.startsWith("](")||y.startsWith("(")||c(y))return!1;if(!g){const b=k[1],A=m.push("reference","span",0);A.content=b,A.markup=k[0],A.raw=k[0]}return m.pos+=k[0].length,!0};n.inline.ruler.before("escape","reference",d),n.renderer.rules.reference=(p,g)=>{const k=String(p[g].content??"");return`<span class="reference-link" data-reference-id="${k}" role="button" tabindex="0" title="Click to view reference">${k}</span>`};const h=n.use.bind(n);return n.use=((...p)=>(i.__markstreamHasCustomParserExtensions=!0,h(...p))),n}function GIe({nextContent:e,previousContent:t,typewriterEnabled:n}){return n?e===t?{settledContent:e,streamedDelta:"",appended:!1}:t&&e.startsWith(t)&&e.length>t.length?{settledContent:t,streamedDelta:e.slice(t.length),appended:!0}:{settledContent:e,streamedDelta:"",appended:!1}:{settledContent:e,streamedDelta:"",appended:!1}}function YO({nextContent:e,persistedContent:t,currentState:n,typewriterEnabled:i,streamRenderVersionChanged:o=!1}){const s=`${n.settledContent}${n.streamedDelta}`;return i?n.streamedDelta&&s===e?o?{settledContent:s,streamedDelta:"",appended:!1}:{settledContent:n.settledContent,streamedDelta:n.streamedDelta,appended:!1}:GIe({nextContent:e,previousContent:t??s,typewriterEnabled:i}):{settledContent:e,streamedDelta:"",appended:!1}}const QIe={plain:"plaintext",text:"plaintext",txt:"plaintext",js:"javascript",mjs:"javascript",cjs:"javascript",ts:"typescript",mts:"typescript",cts:"typescript",golang:"go",py:"python",rb:"ruby",rs:"rust",kt:"kotlin",kts:"kotlin",md:"markdown",yml:"yaml",sh:"shellscript",bash:"shellscript",zsh:"shellscript",shell:"shellscript",shellscript:"shellscript",ps:"powershell",ps1:"powershell",pwsh:"powershell","c++":"cpp","c#":"csharp",cs:"csharp",objc:"objective-c",objectivec:"objective-c","objective-c":"objective-c",objectivecpp:"objective-cpp","objective-c++":"objective-cpp","objective-cpp":"objective-cpp"};function YIe(e){const t=String(e??"").trim();if(!t)return"";const[n=""]=t.split(/\s+/);return n.split(":")[0]?.trim().toLowerCase()??""}function JO(e){const t=YIe(e);return QIe[t]??t}function JIe(e){if(!Array.isArray(e))return;const t=e.filter(i=>typeof i=="string").map(i=>JO(i)).filter(Boolean),n=Array.from(new Set(t)).sort();return n.length>0?n:void 0}function XIe(e){if(!Array.isArray(e))return;const t=[],n=new Set;for(const i of e){if(typeof i!="string")continue;const o=i.trim();!o||n.has(o)||(n.add(o),t.push(o))}return t.length>0?t:void 0}function eEe(e){return XIe(e)?.join("\0")??""}function tEe(e,t){return`${eEe(e)}\0\0${JIe(t)?.join("\0")??""}`}function Gf(e,t,n=1){const i=Number(e);return Number.isFinite(i)?Math.max(n,i):t}function nE(e,t){const n=Number(e);return Number.isFinite(n)?Math.max(0,n):t}var nEe=class{constructor(e={},t){this.source="",this.visible="",this.done=!1,this.paused=!1,this.listeners=new Set,this.rafId=0,this.startedAt=0,this.lastTick=0,this.charBudget=0,this.hasStarted=!1,this.destroyed=!1,this.getSnapshot=()=>({source:this.source,visible:this.visible,done:this.done,paused:this.paused,pendingChars:this.pendingChars,caughtUp:this.caughtUp,final:this.final}),this.subscribe=d=>this.destroyed?()=>{}:(this.listeners.add(d),()=>{this.listeners.delete(d)}),this.enqueue=d=>{if(this.destroyed||!d)return;this.done&&(this.done=!1);const h=this.source.length>0,p=this.pendingChars<=0;if(this.source+=d,p){const g=iE();this.startedAt=h&&this.hasStarted?g-this.normalizedStartDelayMs:g,this.lastTick=g,this.charBudget=0}this.hasStarted=!0,this.emit(),this.ensureLoop()},this.finish=(d={})=>{if(!this.destroyed){if(this.done=!0,d.flush??this.flushOnFinish){this.visible=this.source,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.cancelLoop(),this.emit();return}this.emit(),this.ensureLoop()}},this.flush=()=>{this.destroyed||(this.visible=this.source,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.cancelLoop(),this.emit())},this.reset=(d="")=>{this.destroyed||(this.cancelLoop(),this.source=d,this.visible=d,this.done=!1,this.paused=!1,this.hasStarted=!1,this.startedAt=0,this.lastTick=0,this.charBudget=0,this.currentCps=this.minCharsPerSecond,this.emit())},this.pause=()=>{this.destroyed||this.paused||(this.paused=!0,this.cancelLoop(),this.emit())},this.resume=()=>{if(this.destroyed||!this.paused)return;this.paused=!1;const d=iE();this.lastTick=d,this.startedAt||=d,this.emit(),this.ensureLoop()},this.destroy=()=>{this.destroyed||(this.destroyed=!0,this.cancelLoop(),this.listeners.clear())},this.dispose=()=>{this.destroy()},this.tick=d=>{if(this.rafId=0,this.destroyed||this.paused)return;if(this.pendingChars<=0){this.startedAt=0,this.lastTick=0,this.charBudget=0,this.currentCps=this.minCharsPerSecond;return}if(d-this.startedAt<this.normalizedStartDelayMs){this.rafId=requestAnimationFrame(this.tick);return}const h=1e3/Math.max(1,this.maxCommitFps),p=Math.min(100,Math.max(0,d-this.lastTick));if(p<h){this.rafId=requestAnimationFrame(this.tick);return}this.lastTick=d;const g=this.pendingChars,m=g>this.normalizedCatchUpThreshold?this.normalizedCatchUpLatencyMs:this.normalizedTargetLatencyMs,k=rEe(g/Math.max(.001,m/1e3),this.minCharsPerSecond,this.maxCharsPerSecond);if(this.currentCps+=(k-this.currentCps)*.2,this.charBudget+=this.currentCps*(p/1e3),this.charBudget<1){this.ensureLoop();return}const w=Math.min(Math.floor(this.charBudget),this.maxCharsPerCommit),y=sEe(this.source.slice(this.visible.length),w,this.segmenter);y.text&&(this.visible+=y.text,this.charBudget=Math.max(0,this.charBudget-y.graphemeCount),this.emit()),this.ensureLoop()};const{minCharsPerSecond:n=40,maxCharsPerSecond:i=1e3,targetLatencyMs:o=900,catchUpLatencyMs:s=350,catchUpThreshold:r=600,maxCommitFps:l=30,startDelayMs:a=80,maxCharsPerCommit:u=80,flushOnFinish:c=!1}=e;this.minCharsPerSecond=Gf(n,40,1),this.maxCharsPerSecond=Math.max(this.minCharsPerSecond,Gf(i,1e3,1)),this.normalizedTargetLatencyMs=Gf(o,900,1),this.normalizedCatchUpLatencyMs=Gf(s,350,1),this.normalizedCatchUpThreshold=nE(r,600),this.normalizedStartDelayMs=nE(a,80),this.maxCommitFps=Math.trunc(Gf(l,30,1)),this.maxCharsPerCommit=Math.trunc(Gf(u,80,1)),this.flushOnFinish=c,this.segmenter=oEe(),t&&this.listeners.add(t),this.currentCps=this.minCharsPerSecond}get pendingChars(){return Math.max(0,this.source.length-this.visible.length)}get caughtUp(){return this.pendingChars===0}get final(){return this.done&&this.caughtUp}ensureLoop(){if(!(this.destroyed||this.rafId||this.paused||this.pendingChars<=0)){if(typeof requestAnimationFrame!="function"){this.flush();return}this.rafId=requestAnimationFrame(this.tick)}}cancelLoop(){this.rafId&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.rafId),this.rafId=0)}emit(){if(!this.destroyed)for(const e of this.listeners)e()}};function iEe(e={},t){const n=new nEe(e,t);return{getSnapshot:n.getSnapshot,subscribe:n.subscribe,enqueue:n.enqueue,finish:n.finish,flush:n.flush,reset:n.reset,pause:n.pause,resume:n.resume,destroy:n.destroy,dispose:n.dispose}}function oEe(){if(typeof Intl>"u")return null;const e=Intl.Segmenter;return e?new e(void 0,{granularity:"grapheme"}):null}function sEe(e,t,n){if(!e||t<=0)return{text:"",graphemeCount:0};if(!n){const s=Array.from(e).slice(0,t);return{text:s.join(""),graphemeCount:s.length}}let i="",o=0;for(const s of n.segment(e)){if(o>=t)break;i+=s.segment,o++}return{text:i,graphemeCount:o}}function iE(){return typeof performance<"u"?performance.now():Date.now()}function rEe(e,t,n){return Math.min(n,Math.max(t,e))}var lEe=(e,t,n)=>new Promise((i,o)=>{var s=a=>{try{l(n.next(a))}catch(u){o(u)}},r=a=>{try{l(n.throw(a))}catch(u){o(u)}},l=a=>a.done?i(a.value):Promise.resolve(a.value).then(s,r);l((n=n.apply(e,t)).next())});const U8=Symbol.for("markstream-vue:node-lifecycle");function mct(){}const P7=new Map;let XO="material";const yh=new Map,oE=new Map;let K8=null;function aEe(e){P7.set(e.id,e)}function uEe(e){const t=P7.get(XO);if(!t)return;const n=t.core[e];if(n)return n;const i=yh.get(t.id);if(i){const o=i[e];if(o)return o}t.loadExtended&&!yh.has(t.id)&&dEe(t)}function cEe(){var e,t;return(t=(e=P7.get(XO))==null?void 0:e.fallback)!=null?t:""}function dEe(e){return lEe(this,null,function*(){var t,n,i;if(yh.has(e.id))return(t=yh.get(e.id))!=null?t:null;let o=oE.get(e.id);return o||(o=((i=(n=e.loadExtended)==null?void 0:n.call(e))!=null?i:Promise.resolve(null)).then(s=>(yh.set(e.id,s),K8?.(),s)).catch(()=>(yh.set(e.id,null),null)),oE.set(e.id,o)),o})}const sE='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M30 14v-2h-2V8h-2v4h-2V8h-2v4h-2v2h2v2h-2v2h2v4h2v-4h2v4h2v-4h2v-2h-2v-2Zm-4 2h-2v-2h2Zm-12.437 6A5.57 5.57 0 0 1 8 16.437v-2.873A5.57 5.57 0 0 1 13.563 8H18V2h-4.437A11.563 11.563 0 0 0 2 13.563v2.873A11.564 11.564 0 0 0 13.563 28H18v-6Z"/></svg>',rE='<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/><path fill="#42a5f5" d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"/></svg>',fEe={id:"material",core:{"":rE,plain:'<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path d="M0 0h24v24H0z"/><path fill="#42a5f5" d="M8 16h8v2H8zm0-4h8v2H8zm6-10H6c-1.1 0-2 .9-2 2v16c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8zm4 18H6V4h7v5h5z"/></svg>',text:rE,javascript:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ffca28" d="M2 2v12h12V2zm6 6h1v4a1.003 1.003 0 0 1-1 1H7a1.003 1.003 0 0 1-1-1v-1h1v1h1zm3 0h2v1h-2v1h1a1.003 1.003 0 0 1 1 1v1a1.003 1.003 0 0 1-1 1h-2v-1h2v-1h-1a1.003 1.003 0 0 1-1-1V9a1.003 1.003 0 0 1 1-1"/></svg>',typescript:'<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" viewBox="0 0 16 16"><path fill="#0288d1" d="M2 2v12h12V2zm4 6h3v1H8v4H7V9H6zm5 0h2v1h-2v1h1a1.003 1.003 0 0 1 1 1v1a1.003 1.003 0 0 1-1 1h-2v-1h2v-1h-1a1.003 1.003 0 0 1-1-1V9a1.003 1.003 0 0 1 1-1"/></svg>',jsx:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#00bcd4" d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4-12-2.59-12-4 4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6 14-2.686 14-6-6.268-6-14-6"/><path fill="#00bcd4" d="M16 14a2 2 0 1 0 2 2 2 2 0 0 0-2-2"/><path fill="#00bcd4" d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493 3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124-3.284-5.69-7.72-9.493-10.74-9.493Z"/><path fill="#00bcd4" d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"/></svg>',tsx:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M16 12c7.444 0 12 2.59 12 4s-4.556 4-12 4-12-2.59-12-4 4.556-4 12-4m0-2c-7.732 0-14 2.686-14 6s6.268 6 14 6 14-2.686 14-6-6.268-6-14-6"/><path fill="#0288d1" d="M16 14a2 2 0 1 0 2 2 2 2 0 0 0-2-2"/><path fill="#0288d1" d="M10.458 5.507c2.017 0 5.937 3.177 9.006 8.493 3.722 6.447 3.757 11.687 2.536 12.392a.9.9 0 0 1-.457.1c-2.017 0-5.938-3.176-9.007-8.492C8.814 11.553 8.779 6.313 10 5.608a.9.9 0 0 1 .458-.1m-.001-2A2.87 2.87 0 0 0 9 3.875C6.13 5.532 6.938 12.304 10.804 19c3.284 5.69 7.72 9.493 10.74 9.493A2.87 2.87 0 0 0 23 28.124c2.87-1.656 2.062-8.428-1.804-15.124-3.284-5.69-7.72-9.493-10.74-9.493Z"/><path fill="#0288d1" d="M21.543 5.507a.9.9 0 0 1 .457.1c1.221.706 1.186 5.946-2.536 12.393-3.07 5.316-6.99 8.493-9.007 8.493a.9.9 0 0 1-.457-.1C8.779 25.686 8.814 20.446 12.536 14c3.07-5.316 6.99-8.493 9.007-8.493m0-2c-3.02 0-7.455 3.804-10.74 9.493C6.939 19.696 6.13 26.468 9 28.124a2.87 2.87 0 0 0 1.457.369c3.02 0 7.455-3.804 10.74-9.493C25.061 12.304 25.87 5.532 23 3.876a2.87 2.87 0 0 0-1.457-.369"/></svg>',html:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#e65100" d="m4 4 2 22 10 2 10-2 2-22Zm19.72 7H11.28l.29 3h11.86l-.802 9.335L15.99 25l-6.635-1.646L8.93 19h3.02l.19 2 3.86.77 3.84-.77.29-4H8.84L8 8h16Z"/></svg>',css:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#7e57c2" d="M20 18h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 20 22h2v2h2v-2c0-.388-.562-.851-1.254-1.034C20.356 20.34 20 18.84 20 18m-3.254 2.966C14.356 20.34 14 18.84 14 18h-2v-2h-2v8h2v-2h4v2h2v-2c0-.388-.562-.851-1.254-1.034"/><path fill="#7e57c2" d="M24 4H4v20a4 4 0 0 0 4 4h16.16A3.84 3.84 0 0 0 28 24.16V8a4 4 0 0 0-4-4m2 14h-2v-2h-2v2c0 .193 0 .703 1.254 1.033A3.345 3.345 0 0 1 26 22v2a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2 2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2 2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2 2 2 0 0 1 2-2h2a2 2 0 0 1 2 2 2 2 0 0 1 2-2h2a2 2 0 0 1 2 2Z"/></svg>',scss:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ec407a" d="M27.837 5.673a4.33 4.33 0 0 0-2.293-2.701c-2.362-1.261-6.11-1.298-9.548-.092a26.3 26.3 0 0 0-8.76 4.966c-2.752 2.542-3.438 4.925-3.189 6.194.523 2.668 3.274 4.539 5.485 6.042.418.284.822.559 1.175.816-1.429.76-4.261 2.444-5.088 4.248a3.88 3.88 0 0 0-.118 3.332A2.37 2.37 0 0 0 6.869 29.8a5.6 5.6 0 0 0 1.49.2 6.35 6.35 0 0 0 5.19-2.856 6.74 6.74 0 0 0 .864-5.382 7.3 7.3 0 0 1 2.044-.03 3.92 3.92 0 0 1 2.816 1.311 1.82 1.82 0 0 1 .423 1.262 1.55 1.55 0 0 1-.772 1.05c-.234.14-.586.355-.504.803.036.194.198.633.894.512a2.93 2.93 0 0 0 2.145-2.651 4 4 0 0 0-1.197-2.904 5.94 5.94 0 0 0-4.396-1.626 10.6 10.6 0 0 0-2.672.304 20 20 0 0 0-2.203-1.846c-1.712-1.3-3.33-2.529-3.235-4.26.125-2.263 2.468-4.532 6.964-6.744 4.016-1.976 7.254-2.037 8.944-1.438a2 2 0 0 1 1.204.883 2.77 2.77 0 0 1-.36 2.47 9.71 9.71 0 0 1-7.425 4.304 3.86 3.86 0 0 1-3.238-.757c-.278-.302-.593-.645-1.074-.383q-.565.31-.225 1.189a3.9 3.9 0 0 0 2.407 1.92 11.7 11.7 0 0 0 7.128-.671c3.527-1.35 6.681-5.202 5.756-8.787M11.895 24.475a4 4 0 0 1-.192.468 4.5 4.5 0 0 1-.753 1.081 2.83 2.83 0 0 1-2.533 1.107c-.056-.032-.078-.146-.085-.193a3.28 3.28 0 0 1 1.076-2.284 11.3 11.3 0 0 1 2.644-1.933 3.85 3.85 0 0 1-.157 1.754"/></svg>',json:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="#f9a825" d="M560-160v-80h120q17 0 28.5-11.5T720-280v-80q0-38 22-69t58-44v-14q-36-13-58-44t-22-69v-80q0-17-11.5-28.5T680-720H560v-80h120q50 0 85 35t35 85v80q0 17 11.5 28.5T840-560h40v160h-40q-17 0-28.5 11.5T800-360v80q0 50-35 85t-85 35zm-280 0q-50 0-85-35t-35-85v-80q0-17-11.5-28.5T120-400H80v-160h40q17 0 28.5-11.5T160-600v-80q0-50 35-85t85-35h120v80H280q-17 0-28.5 11.5T240-680v80q0 38-22 69t-58 44v14q36 13 58 44t22 69v80q0 17 11.5 28.5T280-240h120v80z"/></svg>',python:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#0288d1" d="M9.86 2A2.86 2.86 0 0 0 7 4.86v1.68h4.29c.39 0 .71.57.71.96H4.86A2.86 2.86 0 0 0 2 10.36v3.781a2.86 2.86 0 0 0 2.86 2.86h1.18v-2.68a2.85 2.85 0 0 1 2.85-2.86h5.25c1.58 0 2.86-1.271 2.86-2.851V4.86A2.86 2.86 0 0 0 14.14 2zm-.72 1.61c.4 0 .72.12.72.71s-.32.891-.72.891c-.39 0-.71-.3-.71-.89s.32-.711.71-.711"/><path fill="#fdd835" d="M17.959 7v2.68a2.85 2.85 0 0 1-2.85 2.859H9.86A2.85 2.85 0 0 0 7 15.389v3.75a2.86 2.86 0 0 0 2.86 2.86h4.28A2.86 2.86 0 0 0 17 19.14v-1.68h-4.291c-.39 0-.709-.57-.709-.96h7.14A2.86 2.86 0 0 0 22 13.64V9.86A2.86 2.86 0 0 0 19.14 7zM8.32 11.513l-.004.004.038-.004zm6.54 7.276c.39 0 .71.3.71.89a.71.71 0 0 1-.71.71c-.4 0-.72-.12-.72-.71s.32-.89.72-.89"/></svg>',ruby:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#f44336" d="M18.041 3.177c2.24.382 2.879 1.919 2.843 3.527V6.67l-1.013 13.266-13.132.897h.008c-1.093-.044-3.518-.151-3.634-3.545l1.217-2.222 2.462 5.74 2.097-6.77-.045.009.018-.018 6.85 2.186L13.945 9.3l6.53-.409-5.144-4.212 2.71-1.51v.009M3.113 17.252v.017zM6.916 6.874c2.63-2.622 6.033-4.168 7.34-2.844 1.297 1.306-.072 4.523-2.702 7.135-2.666 2.613-6.015 4.248-7.322 2.933-1.306-1.324.036-4.612 2.675-7.224z"/></svg>',go:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#00acc1" d="M2 12h4v2H2zm-2 4h6v2H0zm4 4h2v2H4zm16.954-5H14v3h3.239a4.42 4.42 0 0 1-3.531 2 2.65 2.65 0 0 1-2.053-.858 2.86 2.86 0 0 1-.628-2.28A4.515 4.515 0 0 1 15.292 13a2.73 2.73 0 0 1 1.749.584l2.962-1.185A5.6 5.6 0 0 0 15.292 10a7.526 7.526 0 0 0-7.243 6.5 5.614 5.614 0 0 0 5.659 6.5 7.526 7.526 0 0 0 7.243-6.5 6.4 6.4 0 0 0 .003-1.5"/><path fill="#00acc1" d="M26.292 10a7.526 7.526 0 0 0-7.243 6.5 5.614 5.614 0 0 0 5.659 6.5 7.526 7.526 0 0 0 7.243-6.5 5.614 5.614 0 0 0-5.659-6.5m2.681 6.137A4.515 4.515 0 0 1 24.708 20a2.65 2.65 0 0 1-2.053-.858 2.86 2.86 0 0 1-.628-2.28A4.515 4.515 0 0 1 26.292 13a2.65 2.65 0 0 1 2.053.858 2.86 2.86 0 0 1 .628 2.28Z"/></svg>',java:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#f44336" d="M4 26h24v2H4zM28 4H7a1 1 0 0 0-1 1v13a4 4 0 0 0 4 4h10a4 4 0 0 0 4-4v-4h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2m0 8h-4V6h4Z"/></svg>',kotlin:'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24"><defs><linearGradient id="a" x1="1.725" x2="22.185" y1="22.67" y2="1.982" gradientTransform="translate(1.306 1.129)scale(.89324)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#7c4dff"/><stop offset=".5" stop-color="#d500f9"/><stop offset="1" stop-color="#ef5350"/></linearGradient></defs><path fill="url(#a)" d="M2.975 2.976v18.048h18.05v-.03l-4.478-4.511-4.48-4.515 4.48-4.515 4.443-4.477z"/></svg>',c:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M19.563 22A5.57 5.57 0 0 1 14 16.437v-2.873A5.57 5.57 0 0 1 19.563 8H24V2h-4.437A11.563 11.563 0 0 0 8 13.563v2.873A11.564 11.564 0 0 0 19.563 28H24v-6Z"/></svg>',cpp:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#0288d1" d="M28 14v-4h-2v4h-6v-4h-2v4h-4v2h4v4h2v-4h6v4h2v-4h4v-2z"/><path fill="#0288d1" d="M13.563 22A5.57 5.57 0 0 1 8 16.437v-2.873A5.57 5.57 0 0 1 13.563 8H18V2h-4.437A11.563 11.563 0 0 0 2 13.563v2.873A11.564 11.564 0 0 0 13.563 28H18v-6Z"/></svg>',cs:sE,csharp:sE,php:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#1e88e5" d="M12 18.08c-6.63 0-12-2.72-12-6.08s5.37-6.08 12-6.08S24 8.64 24 12s-5.37 6.08-12 6.08m-5.19-7.95c.54 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.58 1.09q-.42.33-1.29.33h-.87l.53-2.76zm-3.5 5.55h1.44l.34-1.75h1.23c.54 0 .98-.06 1.33-.17.35-.12.67-.31.96-.58.24-.22.43-.46.58-.73.15-.26.26-.56.31-.88.16-.78.05-1.39-.33-1.82-.39-.44-.99-.65-1.82-.65H4.59zm7.25-8.33-1.28 6.58h1.42l.74-3.77h1.14c.36 0 .6.06.71.18s.13.34.07.66l-.57 2.93h1.45l.59-3.07c.13-.62.03-1.07-.27-1.36-.3-.27-.85-.4-1.65-.4h-1.27L12 7.35zM18 10.13c.55 0 .91.1 1.09.31.18.2.22.56.13 1.03-.1.53-.29.87-.57 1.09-.29.22-.72.33-1.3.33h-.85l.5-2.76zm-3.5 5.55h1.44l.34-1.75h1.22c.55 0 1-.06 1.35-.17.35-.12.65-.31.95-.58.24-.22.44-.46.58-.73.15-.26.26-.56.32-.88.15-.78.04-1.39-.34-1.82-.36-.44-.99-.65-1.82-.65h-2.75z"/></svg>',shell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ff7043" d="M2 2a1 1 0 0 0-1 1v10c0 .554.446 1 1 1h12c.554 0 1-.446 1-1V3a1 1 0 0 0-1-1zm0 3h12v8H2zm1 2 2 2-2 2 1 1 3-3-3-3zm5 3.5V12h5v-1.5z"/></svg>',powershell:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#03a9f4" d="M29.07 6H7.677A1.535 1.535 0 0 0 6.24 7.113l-4.2 17.774A.852.852 0 0 0 2.93 26h21.393a1.535 1.535 0 0 0 1.436-1.113L29.96 7.112A.852.852 0 0 0 29.07 6M8.626 23.797a1.4 1.4 0 0 1-1.814-.31l-.007-.009a1.075 1.075 0 0 1 .315-1.599l9.6-6.061-6.102-5.852-.01-.01a1.068 1.068 0 0 1 .084-1.625l.037-.03a1.38 1.38 0 0 1 1.8.07l7.233 6.957a1.1 1.1 0 0 1 .236.739 1.08 1.08 0 0 1-.412.79c-.074.04-.146.119-10.951 6.935ZM24 22.94A1.135 1.135 0 0 1 22.803 24h-5.634a1.061 1.061 0 1 1 .001-2.112h5.633A1.134 1.134 0 0 1 24 22.938Z"/></svg>',sql:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ffca28" d="M16 24c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-8c-5.525 0-10-.9-10-2v4c0 1.1 4.475 2 10 2s10-.9 10-2v-4c0 1.1-4.475 2-10 2m0-12C10.477 4 6 4.895 6 6v4c0 1.1 4.475 2 10 2s10-.9 10-2V6c0-1.105-4.477-2-10-2"/></svg>',yaml:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#ff5252" d="M13 9h5.5L13 3.5zM6 2h8l6 6v12c0 1.1-.9 2-2 2H6c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2m12 16v-2H9v2zm-4-4v-2H6v2z"/></svg>',markdown:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#42a5f5" d="m14 10-4 3.5L6 10H4v12h4v-6l2 2 2-2v6h4V10zm12 6v-6h-4v6h-4l6 8 6-8z"/></svg>',xml:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#8bc34a" d="M13 9h5.5L13 3.5zM6 2h8l6 6v12a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4c0-1.11.89-2 2-2m.12 13.5 3.74 3.74 1.42-1.41-2.33-2.33 2.33-2.33-1.42-1.41zm11.16 0-3.74-3.74-1.42 1.41 2.33 2.33-2.33 2.33 1.42 1.41z"/></svg>',rust:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#ff7043" d="m30 12-4-2V6h-4l-2-4-4 2-4-2-2 4H6v4l-4 2 2 4-2 4 4 2v4h4l2 4 4-2 4 2 2-4h4v-4l4-2-2-4ZM6 16a9.9 9.9 0 0 1 .842-4H10v8H6.842A9.9 9.9 0 0 1 6 16m10 10a9.98 9.98 0 0 1-7.978-4H16v-2h-2v-2h4c.819.819.297 2.308 1.179 3.37a1.89 1.89 0 0 0 1.46.63h3.34A9.98 9.98 0 0 1 16 26m-2-12v-2h4a1 1 0 0 1 0 2Zm11.158 6H24a2.006 2.006 0 0 1-2-2 2 2 0 0 0-2-2 3 3 0 0 0 3-3q0-.08-.004-.161A3.115 3.115 0 0 0 19.83 10H8.022a9.986 9.986 0 0 1 17.136 10"/></svg>',vue:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="#41b883" d="M1.791 3.851 12 21.471 22.209 3.936V3.85H18.24l-6.18 10.616L5.906 3.851z"/><path fill="#35495e" d="m5.907 3.851 6.152 10.617L18.24 3.851h-3.723L12.084 8.03 9.66 3.85z"/></svg>',mermaid:'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32"><path fill="#42a5f5" d="m14 10-4 3.5L6 10H4v12h4v-6l2 2 2-2v6h4V10zm12 6v-6h-4v6h-4l6 8 6-8z"/></svg>'},fallback:'<svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#ff7043" d="M2 2a1 1 0 0 0-1 1v10c0 .554.446 1 1 1h12c.554 0 1-.446 1-1V3a1 1 0 0 0-1-1zm0 3h12v8H2zm1 2 2 2-2 2 1 1 3-3-3-3zm5 3.5V12h5v-1.5z"/></svg>',loadExtended:()=>Fo(()=>import("./extended-p72mFE2C.js"),[]).then(e=>e.materialExtendedMap)},hEe=ha(0);K8=()=>{hEe.value++},aEe(fEe);const pEe={"":"",javascript:"javascript",js:"javascript",mjs:"javascript",cjs:"javascript",typescript:"typescript",ts:"typescript",jsx:"jsx",tsx:"tsx",golang:"go",py:"python",rb:"ruby",sh:"shell",bash:"shell",zsh:"shell",shellscript:"shell",bat:"shell",batch:"shell",ps1:"powershell",plaintext:"plain",text:"plain",txt:"plain","c++":"cpp","c#":"csharp",cs:"csharp","objective-c":"objectivec","objective-c++":"objectivecpp",yml:"yaml",md:"markdown",rs:"rust",kt:"kotlin"};function N9(e){var t;const n=(function(i){if(!i)return"";const o=i.trim();if(!o)return"";const[s]=o.split(/\s+/),[r]=s.split(":");return r.toLowerCase()})(e);return(t=pEe[n])!=null?t:n}function vct(e){const t=N9(e);if(!t)return"plaintext";switch(t){case"plain":return"plaintext";case"jsx":return"javascript";case"tsx":return"typescript";case"objectivec":return"objective-c";case"objectivecpp":return"objective-cpp";default:return t}}function yct(e){return uEe(N9(e))||cEe()}const lE={js:"JavaScript",javascript:"JavaScript",ts:"TypeScript",jsx:"JSX",tsx:"TSX",html:"HTML",css:"CSS",scss:"SCSS",json:"JSON",py:"Python",python:"Python",rb:"Ruby",go:"Go",java:"Java",c:"C",cpp:"C++",cs:"C#",csharp:"C#",php:"PHP",sh:"Shell",bash:"Bash",sql:"SQL",yaml:"YAML",md:"Markdown",d2:"D2",d2lang:"D2","":"Plain Text",plain:"Plain Text"};var F9=(e,t,n)=>new Promise((i,o)=>{var s=a=>{try{l(n.next(a))}catch(u){o(u)}},r=a=>{try{l(n.throw(a))}catch(u){o(u)}},l=a=>a.done?i(a.value):Promise.resolve(a.value).then(s,r);l((n=n.apply(e,t)).next())});let yr=null,zd=!1,Od=null,D9=H7;function Ag(e){var t;const n=(t=e?.default)!=null?t:e;return n&&typeof n.renderToString=="function"?n:null}function j7(){try{const e=globalThis;return Ag(e?.katex)}catch{return null}}function H7(){return F9(null,null,function*(){const e=j7();if(e)return e;const t=yield Fo(()=>import("./katex-DnlPpQZa.js"),[]);try{yield Fo(()=>import("./mhchem-DtR62fUK.js"),__vite__mapDeps([2,3]))}catch{}return Ag(t)})}function eP(e){const t=Promise.resolve(e).then(n=>{var i;return Od===t&&n?(yr=(i=Ag(n))!=null?i:n,yr):null}).catch(()=>null).finally(()=>{Od===t&&(Od=null)});return Od=t,zd=!0,t}function gEe(e){D9=e,yr=null,zd=!1,Od=null}function mEe(e){gEe(H7)}function tP(){return typeof D9=="function"}function kct(){var e;const t=D9;if(!t||t===H7)return null;if(yr)return yr;const n=j7();if(n)return yr=n,yr;if(zd)return null;try{const i=t();return i?typeof i?.then=="function"?(eP(i),null):(yr=(e=Ag(i))!=null?e:i,yr):null}catch{return null}}function nP(){return F9(this,null,function*(){var e;const t=j7();if(t)return yr=t,yr;if(yr)return yr;if(Od)return Od;if(zd)return null;const n=D9;if(!n)return zd=!0,null;try{const i=n();if(typeof i?.then=="function")return eP(i);if(i)return yr=(e=Ag(i))!=null?e:i,zd=!0,yr}catch{}return zd=!0,null})}function iP(e){return e?e.replace(/·/g,"⋅").replace(/℃/g,"°C"):""}let Dv=null,Sd=null;const mr=new Map,gu=new Map;let P0=5;const Yd=new Set;function Jp(){if(mr.size<P0&&Yd.size){let e=P0-mr.size;for(const t of Array.from(Yd)){if(e<=0)break;Yd.delete(t),e--;try{t()}catch{}}}}function vEe(){for(const e of Array.from(Yd)){Yd.delete(e);try{e()}catch{}}}function yEe(e){Dv=e,Sd=null,Dv.onmessage=t=>{const{id:n,html:i,error:o}=t.data,s=mr.get(n);if(s)if(mr.delete(n),clearTimeout(s.timeoutId),s.cleanup(),Jp(),o)s.aborted||s.reject(new Error(o));else{const{content:r,displayMode:l}=t.data;if(r){const a=`${l?"d":"i"}:${r}`;if(gu.set(a,i),gu.size>200){const u=gu.keys().next().value;gu.delete(u)}}s.aborted||s.resolve(i)}},Dv.onerror=t=>{console.error("[katexWorkerClient] Worker error:",t);for(const[n,i]of mr.entries())clearTimeout(i.timeoutId),i.cleanup(),i.aborted||i.reject(new Error(`Worker error: ${t.message}`));mr.clear(),vEe()}}function kEe(e,t=!0,n=2e3,i){return F9(this,null,function*(){performance.now();const o=iP(e);if(!tP()){const a=new Error("KaTeX rendering disabled");return a.name="KaTeXDisabled",a.code="KATEX_DISABLED",Promise.reject(a)}if(Sd)return Promise.reject(Sd);const s=`${t?"d":"i"}:${o}`,r=gu.get(s);if(r)return Jp(),Promise.resolve(r);const l=Dv||(Sd=new Error("[katexWorkerClient] No worker instance set. Please inject a Worker via setKaTeXWorker()."),Sd.name="WorkerInitError",Sd.code="WORKER_INIT_ERROR",null);if(!l)return Promise.reject(Sd);if(mr.size>=P0){const a=new Error("Worker busy");return a.name="WorkerBusy",a.code="WORKER_BUSY",a.busy=!0,a.inFlight=mr.size,a.max=P0,Promise.reject(a)}return new Promise((a,u)=>{if(i?.aborted){const m=new Error("Aborted");return m.name="AbortError",void u(m)}const c=Math.random().toString(36).slice(2);let d=null;const h=globalThis.setTimeout(()=>{const m=mr.get(c);if(!m)return;mr.delete(c),m.cleanup();const k=new Error("Worker render timed out");k.name="WorkerTimeout",k.code="WORKER_TIMEOUT",m.aborted||m.reject(k),Jp()},n);d=()=>{const m=mr.get(c);if(!m||m.aborted)return;m.aborted=!0,m.cleanup();const k=new Error("Aborted");k.name="AbortError",u(k)},i&&i.addEventListener("abort",d,{once:!0});const p=a,g=u;mr.set(c,{resolve:m=>{p(m)},reject:m=>{g(m)},timeoutId:h,aborted:!1,cleanup:()=>{i&&d&&i.removeEventListener("abort",d),d=null}});try{l.postMessage({id:c,content:o,displayMode:t})}catch(m){const k=mr.get(c);mr.delete(c),clearTimeout(h),k?.cleanup(),k?.reject(m),Jp()}})})}function bct(e,t=!0,n){const i=`${t?"d":"i"}:${iP(e)}`;if(gu.set(i,n),gu.size>200){const o=gu.keys().next().value;gu.delete(o)}}const bEe="WORKER_BUSY";function AEe(e=2e3,t){return mr.size<P0?Promise.resolve():new Promise((n,i)=>{let o,s=!1,r=null,l=()=>{};const a=()=>{o&&globalThis.clearTimeout(o),Yd.delete(l),t&&r&&t.removeEventListener("abort",r),r=null};l=()=>{s||(s=!0,a(),n())},Yd.add(l),o=globalThis.setTimeout(()=>{if(s)return;s=!0,a();const u=new Error("Wait for worker slot timed out");u.name="WorkerBusyTimeout",u.code="WORKER_BUSY_TIMEOUT",i(u)},e),queueMicrotask(()=>Jp()),t&&(r=()=>{if(s)return;s=!0,a();const u=new Error("Aborted");u.name="AbortError",i(u)},t.aborted?r():t.addEventListener("abort",r,{once:!0}))})}const G1={timeout:2e3,waitTimeout:1500,backoffMs:30,maxRetries:1};function Act(e){return F9(this,arguments,function*(t,n=!0,i={}){var o,s,r,l;if(!tP()){const m=new Error("KaTeX rendering disabled");throw m.name="KaTeXDisabled",m.code="KATEX_DISABLED",m}const a=(o=i.timeout)!=null?o:G1.timeout,u=(s=i.waitTimeout)!=null?s:G1.waitTimeout,c=(r=i.backoffMs)!=null?r:G1.backoffMs,d=(l=i.maxRetries)!=null?l:G1.maxRetries,h=Number.isFinite(d)?Math.max(0,Math.min(Math.floor(d),8)):G1.maxRetries,p=i.signal;let g=0;for(;;){if(p?.aborted){const m=new Error("Aborted");throw m.name="AbortError",m}try{return yield kEe(t,n,a,p)}catch(m){if(m?.code!==bEe||g>=h)throw m;if(g++,yield AEe(u,p).catch(()=>{}),p?.aborted){const k=new Error("Aborted");throw k.name="AbortError",k}c>0&&(yield new Promise(k=>globalThis.setTimeout(k,c*g)))}}})}function kh(e){const t=typeof e=="number"?e:Number.parseFloat(String(e??""));return Number.isFinite(t)&&t>0?t:null}function CEe(e){var t;for(const n of e.split(/\r?\n/)){const i=n.trim();if(!i||i.startsWith("%%"))continue;const o=i.match(/^([A-Z][\w-]*)\b/i);return((t=o?.[1])==null?void 0:t.toLowerCase())||""}return""}function uy(e){const t=e.split(/\r?\n/).map(o=>o.trim()).filter(o=>o&&!o.startsWith("%%")),n=Math.max(1,t.length),i=CEe(e);return i==="gantt"?220+28*n:i==="sequencediagram"?180+26*n:i==="classdiagram"||i==="statediagram"||i==="erdiagram"?180+24*n:i==="flowchart"||i==="graph"?170+28*n:200+22*n}function cy(e){const t=e.split(/\r?\n/).filter(n=>/^\s*-\s+/.test(n)).length;return t>=3?500:t>0?280+60*t:360}function oP(e,t=360,n=500){return n==null?Math.max(t,e):Math.min(Math.max(t,e),n)}function dy(e,t=360,n=500){return oP(e,t,n)}function fy(e,t=360,n=500){return oP(e,t,n)}var wEe=Object.defineProperty,xEe=Object.defineProperties,SEe=Object.getOwnPropertyDescriptors,aE=Object.getOwnPropertySymbols,_Ee=Object.prototype.hasOwnProperty,MEe=Object.prototype.propertyIsEnumerable,uE=(e,t,n)=>t in e?wEe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,sP=(e,t)=>{for(var n in t||(t={}))_Ee.call(t,n)&&uE(e,n,t[n]);if(aE)for(var n of aE(t))MEe.call(t,n)&&uE(e,n,t[n]);return e},cE=(e,t,n)=>new Promise((i,o)=>{var s=a=>{try{l(n.next(a))}catch(u){o(u)}},r=a=>{try{l(n.throw(a))}catch(u){o(u)}},l=a=>a.done?i(a.value):Promise.resolve(a.value).then(s,r);l((n=n.apply(e,t)).next())});const hy=()=>Fo(()=>import("./mermaid.core-DaDTfY6S.js").then(e=>e.bp),__vite__mapDeps([4,5]));let ou=null,bh=hy,_p=null,V8=!1,Z8=!1,Mp=0;function IEe(e){bh=e,Mp++,ou=null,_p=null,V8=!1,Z8=!1}function EEe(e){IEe(hy)}function dE(){return typeof bh=="function"}function fE(e){if(!e)return e;const t=e&&e.default?e.default:e;if(t&&(typeof t.render=="function"||typeof t.parse=="function"||typeof t.initialize=="function"))return t;if(t&&t.mermaidAPI&&(typeof t.mermaidAPI.render=="function"||typeof t.mermaidAPI.parse=="function")){const o=t.mermaidAPI;return n=sP({},t),i={render:o.render.bind(o),parse:o.parse?o.parse.bind(o):void 0,initialize:s=>typeof t.initialize=="function"?t.initialize(s):o.initialize?o.initialize(s):void 0},xEe(n,SEe(i))}var n,i;return e.mermaid&&typeof e.mermaid.render=="function"?e.mermaid:t}function hE(e){if(e)try{const t=e?.initialize;e.initialize=n=>{const i=sP({suppressErrorRendering:!0},n||{});return typeof t=="function"?t.call(e,i):e?.mermaidAPI&&typeof e.mermaidAPI.initialize=="function"?e.mermaidAPI.initialize(i):void 0}}catch{}}function Cct(){return cE(this,null,function*(){if(ou)return ou;const e=(function(){try{const i=globalThis;return fE(i?.mermaid)}catch{return null}})();if(e)return ou=e,hE(ou),ou;const t=bh,n=Mp;return t?t===hy&&V8?null:_p||(_p=cE(null,null,function*(){let i;try{i=yield t()}catch(o){if(t===hy)return n===Mp&&t===bh&&(V8=!0,(function(s){Z8||(Z8=!0,console.warn('[markstream-vue] Optional dependency "mermaid" is not installed. Mermaid blocks will render as source.',s))})(o)),null;throw o}finally{n===Mp&&t===bh&&(_p=null)}return n!==Mp||t!==bh?null:i?(ou=fE(i),hE(ou),ou):null}),_p):null})}let Ma=null,_d=null;const Xl=new Map,Md=new Map;function dk(e){for(const t of Xl.values())t.reject(e);Xl.clear(),Md.clear()}let pE=5,gE=!1;const TEe="WORKER_BUSY",mE="MERMAID_DISABLED";function LEe(e){if(Ma&&Ma!==e){const n=new Error("Worker replaced");n.code="WORKER_REPLACED",dk(n)}Ma=e,_d=null;const t=e;Ma.onmessage=n=>{if(Ma!==t)return;const{id:i,ok:o,result:s,error:r}=n.data,l=Xl.get(i);l&&(o===!1||r?l.reject(new Error(r||"Unknown error")):l.resolve(s))},Ma.onerror=n=>{var i,o;if(Ma===t)if(Xl.size!==0){try{gE?console.error("[mermaidWorkerClient] Worker error:",n?.message||n):(o=console.debug)==null||o.call(console,"[mermaidWorkerClient] Worker error:",n?.message||n)}catch{}dk(new Error(`Worker error: ${n.message}`))}else(i=console.debug)==null||i.call(console,"[mermaidWorkerClient] Worker error (no pending):",n?.message||n)},Ma.onmessageerror=n=>{var i,o;if(Ma===t)if(Xl.size!==0){try{gE?console.error("[mermaidWorkerClient] Worker messageerror:",n):(o=console.debug)==null||o.call(console,"[mermaidWorkerClient] Worker messageerror:",n)}catch{}dk(new Error("Worker messageerror"))}else(i=console.debug)==null||i.call(console,"[mermaidWorkerClient] Worker messageerror (no pending):",n)}}function rP(e,t,n,i){if(!dE()){const r=new Error("Mermaid rendering disabled");return r.name="MermaidDisabled",r.code=mE,Promise.reject(r)}const o=`${e}\0${t.theme}\0${n}\0${t.code}`;let s=Md.get(o);return s||(s=(function(r,l,a=1400){if(!dE()){const c=new Error("Mermaid rendering disabled");return c.name="MermaidDisabled",c.code=mE,Promise.reject(c)}if(_d)return Promise.reject(_d);const u=Ma||(_d=new Error("[mermaidWorkerClient] No worker instance set. Please inject a Worker via setMermaidWorker()."),_d.name="WorkerInitError",_d.code="WORKER_INIT_ERROR",null);if(!u)return Promise.reject(_d);if(Xl.size>=pE){const c=new Error("Worker busy");return c.name="WorkerBusy",c.code=TEe,c.inFlight=Xl.size,c.max=pE,Promise.reject(c)}return new Promise((c,d)=>{const h=Math.random().toString(36).slice(2);let p,g=!1;const m=()=>{g||(g=!0,p!=null&&globalThis.clearTimeout(p),Xl.delete(h))},k={resolve:w=>{m(),c(w)},reject:w=>{m(),d(w)}};Xl.set(h,k);try{u.postMessage({id:h,action:r,payload:l})}catch(w){return Xl.delete(h),void d(w)}p=globalThis.setTimeout(()=>{const w=new Error("Worker call timed out");w.name="WorkerTimeout",w.code="WORKER_TIMEOUT";const y=Xl.get(h);y&&y.reject(w)},a)})})(e,t,n),Md.set(o,s),s.then(()=>{Md.get(o)===s&&Md.delete(o)},()=>{Md.get(o)===s&&Md.delete(o)})),(function(r,l){if(!l)return r;if(l.aborted){const a=new Error("Aborted");return a.name="AbortError",Promise.reject(a)}return new Promise((a,u)=>{let c=()=>{};const d=()=>l.removeEventListener("abort",c);c=()=>{d();const h=new Error("Aborted");h.name="AbortError",u(h)},l.addEventListener("abort",c,{once:!0}),r.then(h=>{d(),a(h)},h=>{d(),u(h)})})})(s,i)}function wct(e,t,n=1400,i){return rP("canParse",{code:e,theme:t},n,i)}function xct(e,t,n=1400,i){return rP("findPrefix",{code:e,theme:t},n,i)}var NEe=Object.defineProperty,FEe=Object.defineProperties,DEe=Object.getOwnPropertyDescriptors,vE=Object.getOwnPropertySymbols,BEe=Object.prototype.hasOwnProperty,$Ee=Object.prototype.propertyIsEnumerable,yE=(e,t,n)=>t in e?NEe(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Mt=(e,t)=>{for(var n in t||(t={}))BEe.call(t,n)&&yE(e,n,t[n]);if(vE)for(var n of vE(t))$Ee.call(t,n)&&yE(e,n,t[n]);return e},An=(e,t)=>FEe(e,DEe(t)),Ji=(e,t,n)=>new Promise((i,o)=>{var s=a=>{try{l(n.next(a))}catch(u){o(u)}},r=a=>{try{l(n.throw(a))}catch(u){o(u)}},l=a=>a.done?i(a.value):Promise.resolve(a.value).then(s,r);l((n=n.apply(e,t)).next())});const REe="__global__",fk="__MARKSTREAM_VUE_CUSTOM_COMPONENTS_STORE__",G8=(()=>{const e=globalThis;if(e[fk])return e[fk];const t={scopedCustomComponents:{},revision:ha(0)};return e[fk]=t,t})(),kE=G8.revision,zEe=Symbol("markstreamCustomComponents"),OEe=new Set(["text","paragraph","heading","code_block","list","list_item","blockquote","table","table_row","table_cell","definition_list","definition_item","footnote","footnote_reference","footnote_anchor","admonition","hardbreak","link","image","thematic_break","math_inline","math_block","strong","emphasis","strikethrough","highlight","insert","subscript","superscript","emoji","checkbox","checkbox_input","inline_code","html_inline","html_block","reference","mermaid","infographic","d2","vmr_container"]);function Cg(e){return OEe.has(String(e).trim().toLowerCase())}function PEe(e){return e.trim().replace(/([a-z0-9])([A-Z])/g,"$1-$2").replace(/[_\s]+/g,"-").toLowerCase()}function hk(e={}){const t={};for(const[n,i]of Object.entries(e))if(i!=null){t[n]=i;for(const o of new Set([zl(n),zl(PEe(n))]))!o||Cg(o)||Object.prototype.hasOwnProperty.call(t,o)||(t[o]=i)}return t}function ss(e){const t=hn(zEe,null);return F(()=>{var n;return kE.value,(function(i,o={}){return kE.value,Mt(Mt(Mt({},hk(G8.scopedCustomComponents[REe]||{})),hk(o)),hk((function(s){return s&&G8.scopedCustomComponents[s]||{}})(i)))})(e?.(),(n=t?.value)!=null?n:{})})}const jEe=["aria-label"],HEe={key:0,xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",class:"checkbox-icon checkbox-unchecked"},WEe={key:1,xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24",fill:"none",class:"checkbox-icon checkbox-checked"},Ci=(e,t)=>{const n=e.__vccOpts||e;for(const[i,o]of t)n[i]=o;return n},dl=Ci(Xe({__name:"CheckboxNode",props:{node:{}},setup:e=>(t,n)=>(v(),E("span",{class:"checkbox-node",role:"img","aria-label":e.node.checked?"checked":"unchecked"},[e.node.checked?(v(),E("svg",WEe,[...n[1]||(n[1]=[C("rect",{x:"3",y:"3",width:"18",height:"18",rx:"4",fill:"currentColor"},null,-1),C("path",{d:"M9 12l2 2 4-4",stroke:"hsl(var(--ms-background))","stroke-width":"2.5","stroke-linecap":"round","stroke-linejoin":"round"},null,-1)])])):(v(),E("svg",HEe,[...n[0]||(n[0]=[C("rect",{x:"3",y:"3",width:"18",height:"18",rx:"4",stroke:"currentColor","stroke-width":"2"},null,-1)])]))],8,jEe))}),[["__scopeId","data-v-be21ab83"]]);dl.install=e=>{e.component(dl.__name,dl)};const qEe={class:"emoji-node"},Ur=Ci(Xe({__name:"EmojiNode",props:{node:{}},setup:e=>(t,n)=>(v(),E("span",qEe,D(e.node.name),1))}),[["__scopeId","data-v-de55dc97"]]);Ur.install=e=>{e.component(Ur.__name,Ur)};const UEe=["id"],KEe=["title"],fl=Ci(Xe({__name:"FootnoteReferenceNode",props:{node:{}},setup(e){const t=`#fnref--${e.node.id}`;function n(){if(typeof document>"u")return;const i=document.querySelector(t);i?i.scrollIntoView({behavior:"smooth"}):console.warn(`Element with href: ${t} not found`)}return(i,o)=>(v(),E("sup",{id:`fnref-${e.node.id}`,class:"footnote-reference",onClick:n},[C("span",{href:t,title:`查看脚注 ${e.node.id}`,class:"footnote-link cursor-pointer"},"["+D(e.node.id)+"]",9,KEe)],8,UEe))}}),[["__scopeId","data-v-c1463a29"]]);fl.install=e=>{e.component(fl.__name,fl)};const lP=(()=>{try{return!1}catch{}return!1})();function pk(e){lP&&console.warn(e)}function bE(e,t="safe",n){return O7(e,t,n)}function aP(e){return MIe(e)}function gk(e){return e===!0?"":e===!1?"false":e==null?null:String(e)}function W7(e,t="safe"){const n=String(e.tag||e.type||"").trim(),i=Fv((o=e.attrs)?Array.isArray(o)?o.every(Array.isArray)?o.map(([r,l])=>[String(r),gk(l)]):o.filter(r=>r&&typeof r=="object"&&!Array.isArray(r)&&"name"in r).map(r=>[String(r.name),gk(r.value)]):Object.entries(o).map(([r,l])=>[r,gk(l)]):null,t,n);var o;if(!i)return;const s=aP(Yp(i));return Object.keys(s).length>0?s:void 0}function AE(e,t,n=!1){const i=Object.entries(t??{}),o=i.length>0?i.map(([s,r])=>r===""?` ${s}`:` ${s}="${r}"`).join(""):"";return n?`<${e}${o} />`:`<${e}${o}>`}function Q1(e,t){Array.isArray(t)?e.push(...t):t!=null&&e.push(t)}function mk(e,t,n,i,o,s,r=!1){const l=(function(d,h){return KO(d,h)})(e,i);if(vg.has(e.toLowerCase())||!l&&HO(e,s))return null;if(!l&&z7(e,s))return r?[AE(e,t,!0)]:[AE(e,t),...n,`</${e}>`];const a=O7(t,s,e),u=a.key,c=u!=null&&u!==""?u:o;if(l){const d=i[e]||i[e.toLowerCase()],h=aP(a);return yn(d,An(Mt({},h),{key:c}),n.length>0?n:void 0)}return yn(e,An(Mt({},a),{innerHTML:void 0,key:c}),n.length>0?n:void 0)}function uP(e,t){return TIe(e,t)}function py(e,t,n="safe"){if(!e)return[];try{return(function(s,r,l="safe"){let a=0;const u=[],c=[];for(const d of s)if(d.type==="text")(u.length>0?u[u.length-1].children:c).push(d.content);else if(d.type==="self_closing"){const h=mk(d.tagName,d.attrs||{},[],r,"ms-html-"+a++,l,!0);Q1(u.length>0?u[u.length-1].children:c,h)}else if(d.type==="tag_open")u.push({tagName:d.tagName,children:[],attrs:d.attrs,autoKey:"ms-html-"+a++});else if(d.type==="tag_close"){const h=d.tagName.toLowerCase();let p=-1;for(let g=u.length-1;g>=0;g--)if(u[g].tagName.toLowerCase()===h){p=g;break}if(p!==-1)for(;u.length>p;){const g=u.pop(),m=mk(g.tagName,g.attrs||{},g.children,r,g.autoKey,l);u.length>0?Q1(u[u.length-1].children,m):Q1(c,m),g.tagName.toLowerCase()!==h&&u.length>p&&pk(`Auto-closing unclosed tag: <${g.tagName}>`)}else pk(`Ignoring closing tag with no matching opening tag: </${d.tagName}>`)}for(;u.length>0;){const d=u.pop(),h=mk(d.tagName,d.attrs||{},d.children,r,d.autoKey,l);u.length>0?Q1(u[u.length-1].children,h):Q1(c,h),pk(`Auto-closing unclosed tag: <${d.tagName}>`)}return c})(VO(e),t,n)}catch(o){return i=o,lP&&console.error("Failed to parse HTML to VNodes:",i),null}var i}const VEe=["innerHTML"],hl=Ci(Xe({__name:"HtmlInlineNode",props:{node:{},customId:{},htmlPolicy:{}},setup(e){const t=e,n=hn("markstreamHtmlPolicy",void 0),i=F(()=>{var l,a;return(a=(l=t.htmlPolicy)!=null?l:n?.value)!=null?a:"safe"}),o=ss(()=>t.customId),s=Xe({name:"DynamicRenderer",props:{nodes:{type:Array,required:!0}},render(){return this.nodes}}),r=F(()=>{const l=t.node.content;if(!l)return{mode:"html",content:""};if(i.value==="escape")return{mode:"html",content:Oh(l,i.value)};if(t.node.loading&&!t.node.autoClosed)return{mode:"text",content:l};if(t.node.loading&&t.node.autoClosed){const u=py(l,o.value,i.value);if(u!==null)return{mode:"dynamic",nodes:u}}if(!uP(l,o.value))return{mode:"html",content:Oh(l,i.value)};const a=py(l,o.value,i.value);return a===null?{mode:"html",content:Oh(l,i.value)}:{mode:"dynamic",nodes:a}});return(l,a)=>r.value.mode==="dynamic"?(v(),E("span",{key:0,class:Fe(["html-inline-node",{"html-inline-node--loading":t.node.loading}])},[U(f(s),{nodes:r.value.nodes},null,8,["nodes"])],2)):r.value.mode==="text"?(v(),E("span",{key:1,class:Fe(["html-inline-node",{"html-inline-node--loading":t.node.loading}])},D(r.value.content),3)):(v(),E("span",{key:2,class:Fe(["html-inline-node",{"html-inline-node--loading":t.node.loading}]),innerHTML:r.value.content},null,10,VEe))}}),[["__scopeId","data-v-d17f12b0"]]);hl.install=e=>{e.component(hl.__name,hl)};const ZEe={class:"inline-code"},GEe={key:0},rr=Ci(Xe({__name:"InlineCodeNode",props:{node:{}},setup(e){const t=e,n=r1(),i=hn("markstreamFade",void 0),o=hn("markstreamTextStreamState",void 0),s=hn("markstreamStreamVersion",void 0),r=F(()=>{const y=n.fade;return y===""||y===!0||y==="true"||y!==!1&&y!=="false"&&void 0}),l=F(()=>typeof r.value=="boolean"?r.value:typeof i?.value!="boolean"||i.value),a=F(()=>{var y;return String((y=t.node.code)!=null?y:"")}),u=F(()=>!l.value),c=F(()=>{var y;const b=(y=n["index-key"])!=null?y:n.indexKey;return b==null||b===""?"":String(b)}),d=K(t.node.code),h=K(""),p=K(0);let g;function m(){g?.(),g=void 0}function k(){m(),h.value&&(d.value=d.value+h.value,h.value="")}Pe([()=>t.node.code,c,l],([y])=>{const b=String(y??""),A=c.value,T=YO({nextContent:b,persistedContent:A?o?.get(A):void 0,currentState:{settledContent:d.value,streamedDelta:h.value},typewriterEnabled:l.value});d.value=T.settledContent,h.value=T.streamedDelta,T.appended?(p.value+=1,(function(){if(!h.value||g||!s)return;const S=s.value;g=Pe(()=>s.value,x=>{x!==S&&k()},{flush:"sync"})})()):h.value||m(),A&&o?.set(A,b)},{immediate:!0}),Bc(m);const w=F(()=>p.value%2==0?"inline-code-stream-delta--a":"inline-code-stream-delta--b");return(y,b)=>(v(),E("code",ZEe,[u.value?(v(),E(Ee,{key:0},[$e(D(a.value),1)],64)):(v(),E(Ee,{key:1},[d.value?(v(),E("span",GEe,D(d.value),1)):X("",!0),h.value?(v(),E("span",{key:1,class:Fe(["inline-code-stream-delta",[w.value]]),onAnimationend:k},D(h.value),35)):X("",!0)],64))]))}}),[["__scopeId","data-v-4e331c97"]]);rr.install=e=>{e.component(rr.__name,rr)};const Q8=K(!1),CE=K(""),wE=K("top"),Xp=K(null),e0=K(null),Y8=K(null),J8=K(null),xE=K(null);let Bv=null,$v=null,X8=0;function cP(){Bv&&(clearTimeout(Bv),Bv=null),$v&&(clearTimeout($v),$v=null)}let Ym=!1,Jm=null,SE=!1;function QEe(e,t,n="top",i=!1,o,s){if(!e)return;const r=++X8;cP();const l=()=>Ji(null,null,function*(){var a,u;if(yield(function(){return Ji(this,null,function*(){if(!Ym&&!SE&&typeof document<"u"){Jm!=null||(Jm=Ji(null,null,function*(){const[{createApp:c,h:d},{default:h}]=yield Promise.all([Fo(()=>import("./vue.runtime.esm-bundler-DL_Wfh3f.js"),[]),Fo(()=>import("./Tooltip-06BtTYE8.js"),[])]),p=document.createElement("div");p.setAttribute("data-singleton-tooltip","1"),document.body.appendChild(p),c({setup:()=>()=>{var g;return d(h,{visible:Q8.value,"anchor-el":Xp.value,content:CE.value,placement:wE.value,id:e0.value,originX:Y8.value,originY:J8.value,isDark:(g=xE.value)!=null?g:void 0})}}).mount(p),Ym=!0}));try{yield Jm}catch(c){Ym=!1,Jm=null,SE=!0,console.warn("[markstream-vue] Failed to mount Tooltip component. Tooltips will be disabled.",c)}}})})(),Ym&&r===X8){e0.value=`tooltip-${Date.now()}-${Math.floor(1e3*Math.random())}`,Xp.value=e,CE.value=t,wE.value=n,Y8.value=(a=o?.x)!=null?a:null,J8.value=(u=o?.y)!=null?u:null,xE.value=typeof s=="boolean"?s:null,Q8.value=!0;try{e.setAttribute("aria-describedby",e0.value)}catch{}}});i?l():Bv=setTimeout(l,80)}function YEe(e=!1){X8+=1,cP();const t=()=>{if(Xp.value&&e0.value)try{Xp.value.removeAttribute("aria-describedby")}catch{}Q8.value=!1,Xp.value=null,e0.value=null,Y8.value=null,J8.value=null};e?t():$v=setTimeout(t,120)}const JEe={"common.copy":"Copy","common.copied":"Copied","common.decrease":"Decrease","common.reset":"Reset","common.increase":"Increase","common.expand":"Expand","common.collapse":"Collapse","common.preview":"Preview","common.source":"Source","common.export":"Export","common.open":"Open","common.minimize":"Minimize","common.zoomIn":"Zoom in","common.zoomOut":"Zoom out","common.resetZoom":"Reset zoom","image.loadError":"Image failed to load","image.loading":"Loading image..."},XEe=Symbol("markstreamI18nFallback");function dP(e,t){var n;return(n=t?.[e])!=null?n:JEe[e]}const e5=(e,t)=>{var n;return(n=dP(e,t))!=null?n:(function(i){return(i.split(".").pop()||i).replace(/[_-]/g," ").replace(/([A-Z])/g," $1").replace(/\s+/g," ").replace(/\b\w/g,o=>o.toUpperCase()).trim()})(e)};function _E(e,t){return{t(n){const i=dP(n,t);if(e.te&&i!=null&&!e.te(n))return e5(n,t);const o=e.t(n);return o===n&&i!=null?e5(n,t):o}}}function eTe(){const e=(function(){var n,i,o;try{const s=os(),r=XEe,l=s?.provides,a=(n=s?.appContext)==null?void 0:n.provides;return(o=(i=l?.[r])!=null?i:a?.[r])!=null?o:null}catch{}return null})(),t=(function(){var n,i;try{const o=os(),s=o?.proxy,r=s?.$t;if(typeof r=="function"){const u=s?.$te;return{t:r.bind(s),te:typeof u=="function"?u.bind(s):void 0}}const l=(i=(n=o?.appContext)==null?void 0:n.config)==null?void 0:i.globalProperties,a=l?.$t;if(typeof a=="function"){const u=l?.$te;return{t:a.bind(l),te:typeof u=="function"?u.bind(l):void 0}}}catch{}return null})();if(t)return _E(t,e);try{const n=globalThis.$vueI18nUse||null;if(n&&typeof n=="function")try{const i=n();if(i&&typeof i.t=="function")return _E({t:i.t.bind(i),te:typeof i.te=="function"?i.te.bind(i):void 0},e)}catch{}}catch{}return{t:n=>e5(n,e)}}const fP=Symbol("ViewportPriority"),hP=Symbol("ViewportPriorityOptions"),pP=Symbol("OffscreenHeavyNodeDeferral"),tTe=F(()=>!1),ff="400px";function q7(){return hn(hP,void 0)}function U7(){return hn(pP,tTe)}function nTe(e,t){var n,i;const o=typeof window<"u"&&typeof document<"u",s=typeof t=="boolean"?K(t):t,r=o?(n=window.requestIdleCallback)!=null?n:x=>window.setTimeout(()=>x({didTimeout:!0,timeRemaining:()=>0}),16):null,l=o?(i=window.cancelIdleCallback)!=null?i:x=>window.clearTimeout(x):null,a=new WeakMap;let u=1;const c=new Map,d=new Map,h=new Set;let p=null,g=null;function m(x){if(!x)return"viewport";let _=a.get(x);return _||(_=u++,a.set(x,_)),String(_)}function k(){if(p!=null){try{l?.(p)}catch{}p=null}}function w(x){if(x){const _=c.get(x);if(_&&!_.targets.size){try{_.io.disconnect()}catch{}c.delete(x)}}d.size||h.size||k()}function y(x){const _=d.get(x);if(!_)return;const L=c.get(_.bucketKey);if(!_.visible.value){_.visible.value=!0;try{_.resolve()}catch{}}try{L?.io.unobserve(x)}catch{}L?.targets.delete(x),d.delete(x),h.delete(x),w(_.bucketKey)}function b(){window.__MARKSTREAM_DISABLE_VIEWPORT_PRIORITY_IDLE_DRAIN__!==!0&&r&&p==null&&h.size&&(p=r(()=>{p=null;const x=h.values().next().value;x&&(h.delete(x),y(x),h.size&&b())},{timeout:1200}))}function A(x,_){if(!o||typeof IntersectionObserver>"u")return null;const L=(function(O,R){var j,$,W;return{root:(j=e?.(O??null))!=null?j:null,rootMargin:($=R?.rootMargin)!=null?$:ff,threshold:(W=R?.threshold)!=null?W:0}})(x,_),M=[m((N=L).root),N.rootMargin,N.threshold].join("\0");var N;const I=c.get(M);if(I)return{key:M,bucket:I};let z;try{z=new IntersectionObserver(O=>{for(const R of O)(R.isIntersecting||R.intersectionRatio>0)&&y(R.target)},{root:L.root,rootMargin:L.rootMargin,threshold:L.threshold})}catch{return null}const H={io:z,targets:new Map};return c.set(M,H),{key:M,bucket:H}}function T(){if(o&&s.value)for(const[x,_]of Array.from(d.entries())){const L=A(x,_.opts);if(!L){y(x);continue}if(L.key===_.bucketKey)continue;const M=_.bucketKey,N=c.get(M);try{N?.io.unobserve(x)}catch{}N?.targets.delete(x),_.bucketKey=L.key,L.bucket.targets.set(x,_),L.bucket.io.observe(x),w(M)}}Pe(s,x=>{if(!x){for(const _ of Array.from(d.keys()))y(_);k()}},{flush:"sync"});const S=(x,_)=>{const L=K(!1);let M,N=!1;const I=new Promise(R=>{M=()=>{N||(N=!0,R())}}),z=()=>{const R=d.get(x);if(!R)return h.delete(x),void w();const j=c.get(R.bucketKey);try{j?.io.unobserve(x)}catch{}j?.targets.delete(x),d.delete(x),h.delete(x),w(R.bucketKey)};if(!o||!s.value)return L.value=!0,M(),{isVisible:L,whenVisible:I,destroy:z};const H=A(x,_);if(!H)return L.value=!0,M(),{isVisible:L,whenVisible:I,destroy:z};const O={resolve:M,visible:L,bucketKey:H.key,opts:_};return d.set(x,O),H.bucket.targets.set(x,O),H.bucket.io.observe(x),o&&g==null&&(g=window.requestAnimationFrame(()=>{g=null,T()})),_?.allowIdle!==!1&&(h.add(x),b()),{isVisible:L,whenVisible:I,destroy:z}};return S.refresh=T,oi(fP,S),S}function K7(){var e,t;const n=hn(fP,void 0);if(n)return n;const i=new WeakMap,o=new Map,s=new Set;let r=null;const l=typeof window<"u"?(e=window.requestIdleCallback)!=null?e:p=>window.setTimeout(()=>p({didTimeout:!0,timeRemaining:()=>0}),16):null,a=typeof window<"u"?(t=window.cancelIdleCallback)!=null?t:p=>window.clearTimeout(p):null,u=()=>{if(r!=null){try{a?.(r)}catch{}r=null}},c=p=>{if(!p)return;const g=o.get(p);if(g&&!g.targets.size){try{g.io.disconnect()}catch{}o.delete(p)}},d=p=>{const g=i.get(p);if(!g)return;const m=o.get(g.bucketKey);if(!g.visible.value){g.visible.value=!0;try{g.resolve()}catch{}}try{m?.io.unobserve(p)}catch{}i.delete(p),m?.targets.delete(p),s.delete(p),c(g.bucketKey),s.size||u()},h=()=>{window.__MARKSTREAM_DISABLE_VIEWPORT_PRIORITY_IDLE_DRAIN__!==!0&&l&&r==null&&s.size&&(r=l(()=>{r=null;const p=s.values().next().value;p&&(s.delete(p),d(p),s.size&&h())},{timeout:1200}))};return(p,g)=>{const m=K(!1);let k,w=!1;const y=new Promise(T=>{k=()=>{w||(w=!0,T())}}),b=()=>{const T=i.get(p);if(!T)return s.delete(p),void(s.size||u());const S=o.get(T.bucketKey);try{S?.io.unobserve(p)}catch{}i.delete(p),S?.targets.delete(p),s.delete(p),c(T.bucketKey),s.size||u()},A=(T=>{var S,x;if(typeof window>"u"||typeof IntersectionObserver>"u")return null;const _=(z=>{var H,O;return[(H=z?.rootMargin)!=null?H:ff,(O=z?.threshold)!=null?O:0].join("\0")})(T),L=o.get(_);if(L)return{key:_,bucket:L};const M=(S=T?.rootMargin)!=null?S:ff;let N;try{N=new IntersectionObserver(z=>{for(const H of z)(H.isIntersecting||H.intersectionRatio>0)&&d(H.target)},{root:null,rootMargin:M,threshold:(x=T?.threshold)!=null?x:0})}catch{return null}const I={io:N,targets:new Set};return o.set(_,I),{key:_,bucket:I}})(g);return A?(i.set(p,{resolve:k,visible:m,bucketKey:A.key}),A.bucket.targets.add(p),A.bucket.io.observe(p),g?.allowIdle!==!1&&(s.add(p),h()),{isVisible:m,whenVisible:y,destroy:b}):(m.value=!0,k(),{isVisible:m,whenVisible:y,destroy:b})}}function iTe(e,t){var n,i;const o=(i=(n=e.indexKey)!=null?n:t["index-key"])!=null?i:t.indexKey;return o==null||o===""?"":String(o)}const oTe=["data-markstream-viewport-pending"],sTe=["src","alt","title","loading","fetchpriority","decoding","tabindex","aria-label"],rTe={key:1,class:"image-placeholder"},lTe={key:1,class:"image-node__raw-text"},aTe={key:2,class:"image-shimmer-overlay"},uTe={key:1,class:"image-node__raw-text"},cTe={key:3,class:"image-error"},yc=Ci(Xe({__name:"ImageNode",props:{node:{},fallbackSrc:{default:""},lazy:{type:Boolean,default:!1},usePlaceholder:{type:Boolean,default:!0}},emits:["load","error","click"],setup(e,{emit:t}){var n,i,o;const s=e,r=t,l=K(!1),a=K(!1),u=K(""),c=K("primary"),d=K(null),h=r1(),p=hn(U8,null),g=K7(),m=q7(),k=U7(),w=F(()=>GM(s.node.src)),y=F(()=>GM(s.fallbackSrc)),b=(o=(i=(n=os())==null?void 0:n.vnode.el)==null?void 0:i.querySelector)==null?void 0:o.call(i,"img"),A=typeof window<"u"&&b?.getAttribute("src")===(w.value||y.value),T=K(typeof window>"u"||A||!k.value),S=ha(null);let x="",_=null;const L=F(()=>u.value),M=F(()=>!s.lazy),N=F(()=>typeof window<"u"&&k.value&&!A),I=F(()=>!N.value||T.value),z=F(()=>I.value?L.value:""),H=F(()=>{var ie,pe;return(pe=(ie=m?.value.heavyBlockMargin)!=null?ie:m?.value.rootMargin)!=null?pe:ff}),O=F(()=>!s.node.loading&&c.value!=="failed"&&u.value.length>0),R=F(()=>c.value==="failed"),j=F(()=>(!M.value||N.value&&!T.value)&&!l.value&&!a.value&&c.value!=="failed"&&u.value.length>0),$=F(()=>iTe(s,h));function W(ie=$.value){ie&&d.value&&p?.reportHeight(ie,d.value.offsetHeight)}function P(ie=$.value){ie&&dt(()=>{W(ie)})}function Z(){_&&(clearTimeout(_),_=null)}function ae(){const ie=$.value;ie&&x!==ie&&(x&&p?.markSettled(x),Z(),x=ie,p?.markPending(ie),typeof window<"u"&&(_=window.setTimeout(()=>{x===ie&&(P(ie),V())},8e3)))}function V(){return Ji(this,null,function*(){const ie=x;ie&&(Z(),x="",yield dt(),W(ie),p?.markSettled(ie))})}function Y(){if(c.value==="primary"&&y.value&&y.value!==u.value)return c.value="fallback",u.value=y.value,l.value=!1,a.value=!1,void P();c.value="failed",a.value=!0,r("error",u.value),P()}function oe(){l.value=!0,a.value=!1,r("load",L.value),P()}function q(ie){ie.preventDefault(),l.value&&!a.value&&r("click",[ie,L.value])}const{t:ne}=eTe();return Pe([w,y,()=>s.node.loading],()=>(l.value=!1,a.value=!1,s.node.loading||w.value?(u.value=w.value,void(c.value="primary")):y.value?(u.value=y.value,void(c.value="fallback")):(u.value="",c.value="failed",void(a.value=!0))),{immediate:!0}),typeof window<"u"&&Pe([d,N],([ie,pe],Ne,te)=>{var be;if((be=S.value)==null||be.destroy(),S.value=null,!pe||T.value)return void(T.value=!0);if(!ie)return void(T.value=!1);let Q=!0;const ue=g(ie,{rootMargin:H.value,allowIdle:!1});S.value=ue,T.value=ue.isVisible.value,ue.whenVisible.then(()=>{Q&&S.value===ue&&(T.value=!0)}),te(()=>{Q=!1,ue.destroy(),S.value===ue&&(S.value=null)})},{immediate:!0}),Pe([O,l,a,L,()=>s.lazy,I],([ie,pe,Ne,te,be,Q])=>ie&&te&&!Ne&&Q?pe?(V(),void P()):be?(ae(),void P()):void(pe||Ne||ae()):(V(),void P()),{flush:"post",immediate:!0}),Hn(()=>{var ie;(ie=S.value)==null||ie.destroy(),S.value=null,(function(){const pe=x;pe&&(Z(),x="",p?.markSettled(pe))})()}),(ie,pe)=>{var Ne,te,be,Q,ue;return v(),E("span",{ref_key:"rootRef",ref:d,class:"image-node-container","data-markstream-viewport-pending":N.value&&!T.value?"true":void 0},[O.value?(v(),E("img",{key:0,src:z.value||void 0,alt:String((te=(Ne=s.node.alt)!=null?Ne:s.node.title)!=null?te:""),title:String((Q=(be=s.node.title)!=null?be:s.node.alt)!=null?Q:""),class:Fe(["image-node__img",{"is-loading":!M.value&&!l.value,"is-loaded":M.value||l.value,"has-natural-size":l.value,"cursor-pointer":l.value}]),loading:s.lazy?"lazy":void 0,fetchpriority:M.value?"high":void 0,decoding:M.value?"sync":"async",tabindex:l.value?0:-1,"aria-label":(ue=s.node.alt)!=null?ue:f(ne)("image.preview"),onError:Y,onLoad:oe,onClick:q},null,42,sTe)):X("",!0),e.node.loading&&!a.value?(v(),E("span",rTe,[s.usePlaceholder?Rn(ie.$slots,"placeholder",{key:0,node:s.node,displaySrc:L.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:s.fallbackSrc,lazy:s.lazy},()=>[pe[0]||(pe[0]=C("span",{class:"image-shimmer"},null,-1))],!0):(v(),E("span",lTe,D(e.node.raw),1))])):X("",!0),j.value&&!e.node.loading?(v(),E("span",aTe,[s.usePlaceholder?Rn(ie.$slots,"placeholder",{key:0,node:s.node,displaySrc:L.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:s.fallbackSrc,lazy:s.lazy},()=>[pe[1]||(pe[1]=C("span",{class:"image-shimmer"},null,-1))],!0):(v(),E("span",uTe,D(e.node.raw),1))])):X("",!0),R.value?(v(),E("span",cTe,[Rn(ie.$slots,"error",{node:s.node,displaySrc:L.value,imageLoaded:l.value,hasError:a.value,fallbackSrc:s.fallbackSrc,lazy:s.lazy},()=>[pe[2]||(pe[2]=C("svg",{xmlns:"http://www.w3.org/2000/svg",width:"16",height:"16",viewBox:"0 0 24 24"},[C("path",{fill:"currentColor",d:"M2 2h20v10h-2V4H4v9.586l5-5L14.414 14L13 15.414l-4-4l-5 5V20h8v2H2zm13.547 5a1 1 0 1 0 0 2a1 1 0 0 0 0-2m-3 1a3 3 0 1 1 6 0a3 3 0 0 1-6 0m3.625 6.757L19 17.586l2.828-2.829l1.415 1.415L20.414 19l2.829 2.828l-1.415 1.415L19 20.414l-2.828 2.829l-1.415-1.415L17.586 19l-2.829-2.828z"})],-1)),C("span",null,D(f(ne)("image.loadError")),1)],!0)])):X("",!0)],8,oTe)}}}),[["__scopeId","data-v-046e82ac"]]);yc.install=e=>{e.component(yc.__name,yc)};const dTe={key:2},Va=Xe({__name:"NodeChildRenderer",props:{node:{},components:{},customId:{},indexKey:{},fallbackToText:{type:Boolean,default:!1}},setup(e){const t=e,n=ss(()=>t.customId),i=hn("markstreamHtmlPolicy",void 0),o=hn("markstreamNestedRendererProps",void 0),s=F(()=>{var g;return(g=i?.value)!=null?g:"safe"}),r=F(()=>{var g,m;const k=(g=o?.value)!=null?g:{};return An(Mt({},k),{customId:(m=t.customId)!=null?m:k.customId,htmlPolicy:s.value})}),l=ia({loader:()=>Promise.resolve().then(()=>iA),suspensible:!1}),a=F(()=>t.components[String(t.node.type)]),u=F(()=>!!(a.value&&n.value[t.node.type]&&!Cg(String(t.node.type)))),c=F(()=>u.value?W7(t.node,s.value):void 0),d=F(()=>Array.isArray(t.node.children)&&t.node.children.length>0),h=F(()=>{var g;return String((g=t.node.content)!=null?g:"")}),p=F(()=>{var g,m;return String((m=(g=t.node.content)!=null?g:t.node.raw)!=null?m:"")});return(g,m)=>a.value&&u.value?(v(),ce(Oo(a.value),ni({key:0},c.value,{node:e.node,loading:e.node.loading,"index-key":e.indexKey,"custom-id":e.customId,"is-dark":r.value.isDark}),{default:de(()=>[d.value?(v(),ce(f(l),ni({key:0},r.value,{nodes:e.node.children,"index-key":e.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):h.value?(v(),ce(f(l),ni({key:1},r.value,{content:h.value,final:!e.node.loading,"index-key":`${e.indexKey||"child"}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):X("",!0)]),_:1},16,["node","loading","index-key","custom-id","is-dark"])):a.value?(v(),ce(Oo(a.value),{key:1,node:e.node,"custom-id":e.customId,"index-key":e.indexKey},null,8,["node","custom-id","index-key"])):e.fallbackToText?(v(),E("span",dTe,D(p.value),1)):X("",!0)}}),ME=Object.freeze({enabled:!0,contextLineCount:2,minimumLineCount:4,revealLineCount:5});function fTe(e){var t;if(typeof e=="boolean")return e;if(e&&typeof e=="object"){const n=e;return An(Mt(Mt({},ME),n),{enabled:(t=n.enabled)==null||t})}return Mt({},ME)}function V7(e,t){if(e.renderSideBySide===!1)return!0;if(e.useInlineViewWhenSpaceIsLimited!==!0)return!1;const n=e.renderSideBySideInlineBreakpoint,i=typeof n=="number"&&Number.isFinite(n)?n:900;return t>0&&t<=i}function gP(e){var t,n;const i=(n=(t=String(e??"").split(/\r?\n/,1)[0])==null?void 0:t.trim())!=null?n:"";if(i.length<3)return"";const o=i[0];if(o!=="`"&&o!=="~"||i[1]!==o||i[2]!==o)return"";let s=3;for(;i[s]===o;)s+=1;return i.slice(s).trim()}function IE(e){var t;return((t=String(e??"").trim().split(/\s+/,1)[0])!=null?t:"")==="diff"}function hTe(e){var t;return e.diff===!0||IE(e.language)||IE(gP(String((t=e.raw)!=null?t:"")))}function pTe(e,t,n){const i=(function(o){const s=gP(o);if(!s)return"";const r=s.split(/\s+/).filter(Boolean);if(!r.length)return"";const l=r[0]==="diff"?r.slice(1):r;for(const a of l){const u=a.includes(":")?a.slice(a.indexOf(":")+1):a;if(u&&/[./\\-]/.test(u))return u}return""})(e);return{title:i||t,caption:i?n?`Diff / ${t}`:t:""}}const gTe=["aria-busy","aria-label","data-language","data-markstream-line-numbers"],mTe={key:0,translate:"no",class:"markstream-pre__diff-code"},vTe={class:"markstream-pre__diff-pane-content"},yTe={class:"markstream-pre__diff-number","aria-hidden":"true"},kTe={class:"markstream-pre__diff-content"},bTe={class:"markstream-pre__diff-content-inner"},ATe={key:0,class:"markstream-pre__line-numbers","aria-hidden":"true"},CTe=["textContent"],wTe=["textContent"],jr=Xe({__name:"PreCodeNode",props:{node:{},loading:{type:Boolean},showLineNumbers:{type:Boolean},diffInline:{type:Boolean},diffHideUnchangedRegions:{type:[Boolean,Object]},reservedHeightPx:{}},setup(e){const t=e;function n(q,ne){const ie=String(q??"");return ne?ie:ie.replace(/\r\n$|\n$|\r$/,"")}const i=F(()=>{var q,ne,ie;const pe=String((ne=(q=t.node)==null?void 0:q.language)!=null?ne:"");return String((ie=String(pe).split(/\s+/g)[0])!=null?ie:"").toLowerCase().replace(/[^\w-]/g,"")||"plaintext"}),o=F(()=>`language-${i.value}`),s=F(()=>{var q;return t.loading===!0||((q=t.node)==null?void 0:q.loading)===!0}),r=F(()=>{var q;return n((q=t.node)==null?void 0:q.code,s.value)});let l="",a=1;const u=F(()=>(function(q){let ne=0,ie=1;q.startsWith(l)&&(ne=l.length,ie=a,ne>0&&q[ne-1]==="\r"&&q[ne]===` -`&&ne++);for(let pe=ne;pe<q.length;pe++)q[pe]===` -`?ie++:q[pe]==="\r"&&(ie++,q[pe+1]===` -`&&pe++);return l=q,a=ie,ie})(r.value)),c=F(()=>r.value.split(/\r\n|\n|\r/));let d=0,h="";const p=F(()=>{const q=u.value;q<d&&(d=0,h="");for(let ne=d+1;ne<=q;ne++)h+=`${h?` -`:""}${ne}`;return d=q,h}),g=F(()=>{var q;return t.showLineNumbers===!0&&((q=t.node)==null?void 0:q.diff)===!0}),m=F(()=>g.value&&t.diffInline===!0),k=F(()=>{const q=Number(t.reservedHeightPx);if(!Number.isFinite(q)||q<=0)return;const ne=`${Math.ceil(q)}px`;return s.value?{maxHeight:ne,overflow:"auto"}:{height:ne,minHeight:ne,maxHeight:ne,overflow:"auto"}}),w=["diff ","index ","--- ","+++ ","@@ "];function y(q){return String(q??"").trim().length===0}function b(q,ne="context",ie={}){const pe=y(q);return{code:q,kind:pe&&ne!=="hunk"&&ne!=="spacer"&&!ie.preserveBlankKind?"context":ne,empty:pe}}function A(q){const ne=n(q,s.value);return ne?ne.split(/\r\n|\n|\r/):[]}function T(q,ne){return!y(q[ne])||ne<q.length-1}function S(q){return q.startsWith("-")&&!q.startsWith("---")}function x(q){return q.startsWith("+")&&!q.startsWith("+++")}function _(q){return q.some(ne=>w.some(ie=>ne.startsWith(ie)))}function L(q,ne){return ne||!q.startsWith(" ")||q.startsWith(" ")?q:` ${q}`}function M(q,ne){const ie=q.length,pe=ne.length,Ne=[];let te=0;for(;te<ie&&te<pe&&q[te]===ne[te];)Ne.push({originalIndex:te,modifiedIndex:te}),te++;const be=[];let Q=ie-1,ue=pe-1;for(;Q>=te&&ue>=te&&q[Q]===ne[ue];)be.unshift({originalIndex:Q,modifiedIndex:ue}),Q--,ue--;const Ae=Q-te+1,se=ue-te+1;if(Ae<=0||se<=0||s.value||(Ae+1)*(se+1)>15e5)return Ne.concat(be);const re=se+1,G=new Uint32Array((Ae+1)*(se+1));for(let Ie=Ae-1;Ie>=0;Ie--)for(let Oe=se-1;Oe>=0;Oe--){const we=Ie*re+Oe;if(q[te+Ie]===ne[te+Oe])G[we]=G[(Ie+1)*re+Oe+1]+1;else{const Be=G[(Ie+1)*re+Oe],tt=G[Ie*re+Oe+1];G[we]=Be>=tt?Be:tt}}const le=[];let ge=0,ke=0;for(;ge<Ae&&ke<se;)q[te+ge]===ne[te+ke]?(le.push({originalIndex:te+ge,modifiedIndex:te+ke}),ge++,ke++):G[(ge+1)*re+ke]>=G[ge*re+ke+1]?ge++:ke++;return Ne.concat(le,be)}function N(q){var ne;const ie=(function(){var ue,Ae;const se=t.diffHideUnchangedRegions;if(se==null||se===!1)return null;const re=se===!0?{}:se;return re.enabled===!1?null:{contextLineCount:Math.max(0,Math.floor((ue=re.contextLineCount)!=null?ue:2)),minimumLineCount:Math.max(1,Math.floor((Ae=re.minimumLineCount)!=null?Ae:4))}})();if(!ie||q.length<1||q.length>2||q.length===2&&q[0].lines.length!==q[1].lines.length)return q;const pe=q[0].lines,Ne=(ne=q[1])==null?void 0:ne.lines,te=ue=>pe[ue].kind==="context"&&(Ne===void 0||Ne[ue].kind==="context"&&pe[ue].code===Ne[ue].code),be=[];let Q=0;for(;Q<pe.length;){const ue=Q;for(;Q<pe.length&&te(Q);)Q++;const Ae=Q;if(Ae-ue>=ie.minimumLineCount){const se=ue+(ue===0?0:ie.contextLineCount),re=Ae-(Ae===pe.length?0:ie.contextLineCount);re-se>=ie.minimumLineCount&&be.push({start:se,end:re})}Q===ue&&Q++}return be.length?q.map((ue,Ae)=>{const se=[];let re=0;for(const G of be)se.push(...ue.lines.slice(re,G.start)),se.push({code:Ae===0?"Unmodified lines":"",kind:"collapsed",empty:!1,key:`${ue.key}-collapsed-${G.start}-${G.end}`,number:""}),re=G.end;return se.push(...ue.lines.slice(re)),An(Mt({},ue),{lines:se})}):q}const I=F(()=>{var q,ne,ie,pe;if(!g.value)return[];const Ne=(function(Ae){const se=Ae.some(G=>S(G)),re=Ae.some(G=>x(G));return se&&re||(function(){var G,le,ge,ke;if(i.value==="diff")return!0;const Ie=(ke=(ge=String((le=(G=t.node)==null?void 0:G.raw)!=null?le:"").split(/\r?\n/,1)[0])==null?void 0:ge.trim())!=null?ke:"";return/^`{3,}\s*diff(?:\s|$)|^~{3,}\s*diff(?:\s|$)/.test(Ie)})()&&(se||re)})(c.value),te=(function(){var Ae,se;return((Ae=t.node)==null?void 0:Ae.originalCode)!=null||((se=t.node)==null?void 0:se.updatedCode)!=null})();if(m.value){const Ae=te?(function(se,re){const G=A(se),le=A(re),ge=M(G,le);if(ge.length>0){const tt=[];let ut=0,_t=0;for(const Ct of ge){for(;ut<Ct.originalIndex;)tt.push(An(Mt({},b(G[ut],"removed",{preserveBlankKind:T(G,ut)})),{key:`inline-removed-source-${ut}`,number:ut+1})),ut++;for(;_t<Ct.modifiedIndex;)tt.push(An(Mt({},b(le[_t],"added",{preserveBlankKind:T(le,_t)})),{key:`inline-added-source-${_t}`,number:_t+1})),_t++;tt.push(An(Mt({},b(le[Ct.modifiedIndex])),{key:`inline-context-source-${Ct.originalIndex}-${Ct.modifiedIndex}`,number:Ct.modifiedIndex+1})),ut=Ct.originalIndex+1,_t=Ct.modifiedIndex+1}for(;ut<G.length;)tt.push(An(Mt({},b(G[ut],"removed",{preserveBlankKind:T(G,ut)})),{key:`inline-removed-source-${ut}`,number:ut+1})),ut++;for(;_t<le.length;)tt.push(An(Mt({},b(le[_t],"added",{preserveBlankKind:T(le,_t)})),{key:`inline-added-source-${_t}`,number:_t+1})),_t++;return tt}const ke=[];let Ie=0,Oe=G.length-1,we=le.length-1;for(;Ie<=Oe&&Ie<=we&&G[Ie]===le[Ie];)ke.push(An(Mt({},b(le[Ie])),{key:`inline-prefix-${Ie}`,number:Ie+1})),Ie++;const Be=[];for(;Oe>=Ie&&we>=Ie&&G[Oe]===le[we];)Be.unshift(An(Mt({},b(le[we])),{key:`inline-suffix-${we}`,number:we+1})),Oe--,we--;for(let tt=Ie;tt<=Oe;tt++)ke.push(An(Mt({},b(G[tt],"removed",{preserveBlankKind:T(G,tt)})),{key:`inline-removed-source-${tt}`,number:tt+1}));for(let tt=Ie;tt<=we;tt++)ke.push(An(Mt({},b(le[tt],"added",{preserveBlankKind:T(le,tt)})),{key:`inline-added-source-${tt}`,number:tt+1}));return ke.concat(Be)})((q=t.node)==null?void 0:q.originalCode,(ne=t.node)==null?void 0:ne.updatedCode):(function(se){const re=[];let G=1,le=1;const ge=_(se);for(const[ke,Ie]of se.entries())if(Ie.startsWith("@@")){const Oe=Ie.match(/^@@\s+-(\d+)(?:,\d+)?\s+\+(\d+)(?:,\d+)?\s+@@/);Oe&&(G=Number(Oe[1]),le=Number(Oe[2])),re.push(An(Mt({},b(Ie,"hunk")),{key:`inline-hunk-${ke}`,number:""}))}else if(S(Ie))re.push(An(Mt({},b(L(Ie.slice(1),ge),"removed",{preserveBlankKind:!0})),{key:`inline-removed-${ke}`,number:G++}));else if(x(Ie))re.push(An(Mt({},b(L(Ie.slice(1),ge),"added",{preserveBlankKind:!0})),{key:`inline-added-${ke}`,number:le++}));else{const Oe=ge&&Ie.startsWith(" ")?Ie.slice(1):Ie;re.push(An(Mt({},b(Oe)),{key:`inline-context-${ke}`,number:le})),G++,le++}return re})(c.value);return N([{key:"inline",className:"markstream-pre__diff-pane--inline",lines:Ae}])}if(!Ne&&te)return(function(Ae,se){const re=A(Ae),G=A(se),le=M(re,G),ge=[],ke=[];let Ie=0,Oe=0,we=0;const Be=(tt,ut)=>{const _t=Math.max(tt-Ie,ut-Oe);for(let Ct=0;Ct<_t;Ct++){const $t=Ie+Ct,Vt=Oe+Ct;ge.push($t<tt?An(Mt({},b(re[$t],"removed",{preserveBlankKind:T(re,$t)})),{key:`original-changed-${we}-${$t}`,number:$t+1}):An(Mt({},b("","spacer")),{key:`original-spacer-${we}-${Ct}`,number:""})),ke.push(Vt<ut?An(Mt({},b(G[Vt],"added",{preserveBlankKind:T(G,Vt)})),{key:`modified-changed-${we}-${Vt}`,number:Vt+1}):An(Mt({},b("","spacer")),{key:`modified-spacer-${we}-${Ct}`,number:""}))}Ie=tt,Oe=ut,we++};for(const tt of le)Be(tt.originalIndex,tt.modifiedIndex),ge.push(An(Mt({},b(re[tt.originalIndex])),{key:`original-context-${tt.originalIndex}-${tt.modifiedIndex}`,number:tt.originalIndex+1})),ke.push(An(Mt({},b(G[tt.modifiedIndex])),{key:`modified-context-${tt.originalIndex}-${tt.modifiedIndex}`,number:tt.modifiedIndex+1})),Ie=tt.originalIndex+1,Oe=tt.modifiedIndex+1;return Be(re.length,G.length),N([{key:"original",className:"markstream-pre__diff-pane--original",lines:ge},{key:"modified",className:"markstream-pre__diff-pane--modified",lines:ke}])})((ie=t.node)==null?void 0:ie.originalCode,(pe=t.node)==null?void 0:pe.updatedCode);const be=[],Q=[],ue=_(c.value);for(const Ae of c.value)if(Ae.startsWith("@@"))be.push(b(Ae,"hunk")),Q.push(b(Ae,"hunk"));else if(Ae.startsWith("-")&&!Ae.startsWith("---"))be.push(b(L(Ae.slice(1),ue),"removed",{preserveBlankKind:!0}));else if(Ae.startsWith("+")&&!Ae.startsWith("+++"))Q.push(b(L(Ae.slice(1),ue),"added",{preserveBlankKind:!0}));else{const se=ue&&Ae.startsWith(" ")?Ae.slice(1):Ae;be.push(b(se)),Q.push(b(se))}return N([{key:"original",className:"markstream-pre__diff-pane--original",lines:be.map((Ae,se)=>An(Mt({},Ae),{key:`original-${se}`,number:se+1}))},{key:"modified",className:"markstream-pre__diff-pane--modified",lines:Q.map((Ae,se)=>An(Mt({},Ae),{key:`modified-${se}`,number:se+1}))}])}),z=F(()=>{var q,ne;if(t.showLineNumbers!==!0)return;let ie=g.value?1:u.value;if(g.value){ie=Math.max(ie,A((q=t.node)==null?void 0:q.originalCode).length,A((ne=t.node)==null?void 0:ne.updatedCode).length);for(const Ne of I.value)for(const te of Ne.lines)typeof te.number=="number"&&(ie=Math.max(ie,te.number))}const pe=`${Math.max(2,String(ie).length)}ch`;return{"--markstream-pre-line-number-width":pe,"--markstream-pre-diff-line-number-width":pe,"--markstream-code-padding-left":"calc(var(--markstream-pre-line-number-padding-left, 2ch) + var(--markstream-pre-line-number-width, 2ch) + var(--markstream-pre-line-number-padding-right, 1ch) + var(--markstream-pre-line-number-separator-width, 2px) + var(--markstream-pre-line-number-gap-to-code, 1ch))"}}),H=F(()=>I.value.some(q=>q.lines.some(ne=>ne.kind==="collapsed"))),O=F(()=>{const q=i.value;return q?`Code block: ${q}`:"Code block"}),R=K(null),j=K([]);let $=null,W=!1,P=null;function Z(q){const ne=Number.parseFloat(String(q??""));return Number.isFinite(ne)&&ne>0?ne:0}function ae(q,ne){var ie;if(!q)return ne;if(q.classList.contains("markstream-pre__diff-line--collapsed"))return 32;const pe=q.querySelector(".markstream-pre__diff-content"),Ne=pe?.getBoundingClientRect(),te=(ie=Ne?.height)!=null?ie:0;return Math.max(ne,Math.ceil(te))}function V(){W||typeof window>"u"||($!=null&&window.cancelAnimationFrame($),$=window.requestAnimationFrame(()=>{$=null,W||(function(){var q,ne;$=null;const ie=R.value;if(!ie||!g.value||m.value||!ie.classList.contains("is-wrap"))return void(j.value.length&&(j.value=[]));const pe=(function(se){const re=window.getComputedStyle(se),G=Z(re.getPropertyValue("--markstream-pre-diff-line-height"));if(G>0)return G;const le=Z(re.lineHeight);return le>0?le:18})(ie),Ne=Array.from(ie.querySelectorAll(".markstream-pre__diff-pane--original .markstream-pre__diff-line")),te=Array.from(ie.querySelectorAll(".markstream-pre__diff-pane--modified .markstream-pre__diff-line")),be=Math.max(Ne.length,te.length),Q=[];for(let se=0;se<be;se++){const re=ae((q=Ne[se])!=null?q:null,pe),G=ae((ne=te[se])!=null?ne:null,pe),le=Math.max(pe,re,G);Q.push({rowHeight:le,originalHeight:re,modifiedHeight:G})}var ue,Ae;ue=j.value,Ae=Q,ue.length===Ae.length&&ue.every((se,re)=>{const G=Ae[re];return G&&Math.abs(se.rowHeight-G.rowHeight)<=.5&&Math.abs(se.originalHeight-G.originalHeight)<=.5&&Math.abs(se.modifiedHeight-G.modifiedHeight)<=.5})||(j.value=Q)})()}))}function Y(q){P?.disconnect(),P=null,q&&g.value&&!m.value&&typeof ResizeObserver<"u"&&(P=new ResizeObserver(()=>{V()}),P.observe(q))}function oe(q,ne){const ie=j.value[q];if(!ie)return;const pe=ne==="original"?ie.originalHeight:ie.modifiedHeight;return{"--markstream-pre-diff-synced-row-height":`${Math.ceil(ie.rowHeight)}px`,"--markstream-pre-diff-content-height":`${Math.ceil(pe)}px`}}return Pe(R,q=>{Y(q),dt(()=>V())},{flush:"post"}),Pe([g,m,I],()=>{Y(R.value),dt(()=>V())},{flush:"post",immediate:!0}),Hn(()=>{W=!0,$!=null&&(window.cancelAnimationFrame($),$=null),P?.disconnect(),P=null}),(q,ne)=>(v(),E("pre",{ref_key:"preRef",ref:R,style:Kt([k.value,z.value]),class:Fe([o.value,{"markstream-pre--line-numbers":t.showLineNumbers,"markstream-pre--diff-preview":g.value,"markstream-pre--diff-inline":m.value,"markstream-pre--diff-collapsed":H.value}]),"aria-busy":s.value,"aria-label":O.value,"data-language":i.value,"data-markstream-line-numbers":t.showLineNumbers?"1":void 0,"data-markstream-pre":"1",tabindex:"0"},[g.value?(v(),E("code",mTe,[(v(!0),E(Ee,null,pt(I.value,ie=>(v(),E("span",{key:ie.key,class:Fe(["markstream-pre__diff-pane",ie.className])},[C("span",vTe,[(v(!0),E(Ee,null,pt(ie.lines,(pe,Ne)=>(v(),E("span",{key:pe.key,class:Fe(["markstream-pre__diff-line",[`markstream-pre__diff-line--${pe.kind}`,{"markstream-pre__diff-line--empty":pe.empty}]]),style:Kt(oe(Ne,ie.key))},[ne[0]||(ne[0]=C("span",{class:"markstream-pre__diff-rail","aria-hidden":"true"},null,-1)),C("span",yTe,D(pe.number),1),C("span",kTe,[C("span",bTe,D(pe.code),1)])],6))),128))])],2))),128))])):(v(),E(Ee,{key:1},[t.showLineNumbers?(v(),E("span",ATe,[C("span",{class:"markstream-pre__line-numbers-text",textContent:D(p.value)},null,8,CTe)])):X("",!0),C("code",{translate:"no",class:"markstream-pre__code",textContent:D(r.value)},null,8,wTe)],64))],14,gTe))}});jr.install=e=>{e.component(jr.__name,jr)};const Bo=Ci(Xe({__name:"TextNode",props:{node:{}},emits:["copy"],setup(e){const t=e,n=r1(),i=hn("markstreamFade",void 0),o=hn("markstreamTextStreamState",void 0),s=hn("markstreamStreamVersion",void 0),r=F(()=>{const T=n.fade;return T===""||T===!0||T==="true"||T!==!1&&T!=="false"&&void 0}),l=F(()=>typeof r.value=="boolean"?r.value:typeof i?.value!="boolean"||i.value),a=F(()=>{var T;const S=(T=n["index-key"])!=null?T:n.indexKey;return S==null||S===""?"":String(S)}),u=K(t.node.content),c=K(""),d=K(0),h=K(t.node.content);let p;const g=K(null),m=K(null);let k="",w=null;function y(){p?.(),p=void 0}function b(){y(),c.value&&(u.value=u.value+c.value,c.value="")}Pe([u,g,m],function(){var T,S;const x=g.value;if(!x)return;const _=String((T=u.value)!=null?T:""),L=m.value;return w||(w=x.firstChild,k=(S=w?.data)!=null?S:""),_.startsWith(k)?!w&&_?(x.textContent=_,w=x.firstChild,void(k=_)):void(_.length>k.length&&L&&(L.appendChild(document.createTextNode(_.slice(k.length))),k=_)):(x.textContent=_,w=x.firstChild,L&&(L.textContent=""),void(k=_))},{immediate:!0}),Pe([()=>t.node.content,a,l],([T])=>{const S=String(T??""),x=a.value,_=YO({nextContent:S,persistedContent:x?o?.get(x):void 0,currentState:{settledContent:u.value,streamedDelta:c.value},typewriterEnabled:l.value});u.value=_.settledContent,c.value=_.streamedDelta,_.appended?(d.value+=1,(function(){if(!c.value||p||!s)return;const L=s.value;p=Pe(()=>s.value,M=>{M!==L&&b()},{flush:"sync"})})()):c.value||y(),x&&o?.set(x,S)},{immediate:!0}),Bc(y);const A=F(()=>d.value%2==0?"text-node-stream-delta--a":"text-node-stream-delta--b");return(T,S)=>(v(),E("span",{class:Fe([[e.node.center?"text-node-center":""],"text-node"])},[Wn(C("span",{ref_key:"settledTextEl",ref:g},D(h.value),513),[[Po,u.value!==""]]),Wn(C("span",{ref_key:"settledAppendsEl",ref:m},null,512),[[Po,u.value!==""]]),c.value?(v(),E("span",{key:0,class:Fe(["text-node-stream-delta",[A.value]]),onAnimationend:b},D(c.value),35)):X("",!0)],2))}}),[["__scopeId","data-v-fd79037c"]]);function Ip(e,t,n){return Xe({name:e,inheritAttrs:!1,setup(i,{attrs:o,slots:s}){var r,l;const a=K7(),u=q7(),c=U7(),d=typeof window<"u"&&((l=(r=os())==null?void 0:r.vnode.el)==null?void 0:l.nodeType)===1,h=K(typeof window>"u"||d||!c.value),p=ha(null);let g=null;function m(k){const w=k&&"$el"in k?k.$el:k;p.value=w instanceof HTMLElement?w:null}return typeof window<"u"&&Pe([p,c],([k,w],y,b)=>{if(g?.destroy(),g=null,!w||h.value)return void(h.value=!0);if(!k)return;let A=!0;const T=a(k,{rootMargin:u?.value.heavyBlockMargin,allowIdle:!1});g=T,h.value=T.isVisible.value,T.whenVisible.then(()=>{A&&g===T&&(h.value=!0)}),b(()=>{A=!1,T.destroy(),g===T&&(g=null)})},{immediate:!0}),Hn(()=>{g?.destroy(),g=null}),()=>yn(h.value?t:n,An(Mt({},o),{ref:m}),s)}})}Bo.install=e=>{e.component(Bo.__name,Bo)};const gy=Xe({name:"CodeBlockNodeLoading",inheritAttrs:!1,props:["node","isDark","loading","stream","theme","darkTheme","lightTheme","isShowPreview","monacoOptions","enableFontSizeControl","minWidth","maxWidth","themes","showHeader","showCopyButton","showExpandButton","showPreviewButton","showCollapseButton","showFontSizeButtons","showTooltips","htmlPreviewAllowScripts","htmlPreviewSandbox","customId","estimatedHeightPx","estimatedContentHeightPx","estimatedDiffInline"],emits:["previewCode","copy"],setup(e,{attrs:t}){const n=e;return()=>{var i,o,s,r,l,a,u;const c=N9(String((o=(i=n.node)==null?void 0:i.language)!=null?o:"")),d=lE[c]||(c?c.charAt(0).toUpperCase()+c.slice(1):lE[""]),h=hTe(n.node),p=pTe(String((r=(s=n.node)==null?void 0:s.raw)!=null?r:""),d,h),g=n.monacoOptions,m=h&&((l=n.estimatedDiffInline)!=null?l:V7(g??{},typeof window>"u"?0:window.innerWidth)),k=g?.diffAppearance,w=k==="dark"||k!=="light"&&n.isDark===!0,y=typeof g?.fontSize=="number"&&Number.isFinite(g.fontSize)&&g.fontSize>0?g.fontSize:12,b=typeof g?.lineHeight=="number"&&Number.isFinite(g.lineHeight)&&g.lineHeight>0?g.lineHeight:y===12?18:Math.max(12,Math.round(1.5*y)),A=typeof g?.tabSize=="number"&&Number.isFinite(g.tabSize)&&g.tabSize>0?g.tabSize:4,T=h?0:8,S=typeof((a=g?.padding)==null?void 0:a.top)=="number"&&Number.isFinite(g.padding.top)&&g.padding.top>=0?g.padding.top:T,x=typeof((u=g?.padding)==null?void 0:u.bottom)=="number"&&Number.isFinite(g.padding.bottom)&&g.padding.bottom>=0?g.padding.bottom:T,_=typeof g?.fontFamily=="string"?g.fontFamily.trim():"",L=Mt(Mt({fontSize:`${y}px`,lineHeight:`${b}px`,tabSize:A,paddingTop:`${S}px`,paddingBottom:`${x}px`,"--markstream-pre-line-number-top":`${S}px`},h?{"--markstream-pre-diff-line-height":`${b}px`}:{}),_?{"--markstream-code-font-family":_}:{}),M=()=>yn("button",{class:"code-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded leading-none shrink-0","aria-hidden":"true",disabled:!0,tabindex:-1,type:"button"},[yn("svg",{class:"action-icon",width:"14",height:"14"})]),N=n.isShowPreview!==!1&&(c==="html"||c==="svg"),I=n.showFontSizeButtons!==!1&&n.enableFontSizeControl!==!1||n.showExpandButton!==!1||N&&n.showPreviewButton!==!1,z=O=>{if(O!=null)return typeof O=="number"?`${O}px`:String(O)},H=Mt(Mt(Mt({"--markstream-code-layout-character-width":"1ch"},z(n.minWidth)?{minWidth:z(n.minWidth)}:{}),z(n.maxWidth)?{maxWidth:z(n.maxWidth)}:{}),h?{}:{color:"var(--vscode-editor-foreground, var(--markstream-code-fallback-fg, var(--code-fg)))",backgroundColor:"var(--markstream-code-fallback-bg, var(--code-bg, #fff))",borderColor:"var(--markstream-code-border-color, var(--code-border))"});return yn("div",An(Mt({},t),{class:["code-block-container","rounded-lg","border",{dark:n.isDark===!0,"is-rendering":n.loading!==!1,"is-dark":w,"is-diff":h,"is-plain-text":c===""||c==="plaintext"||c==="text"},t.class],style:[H,t.style],"data-markstream-code-block":"1","data-markstream-enhanced":"false","data-markstream-code-block-state":n.loading?"streaming":"settled","data-markstream-code-loading":"1"}),[n.showHeader===!1?null:yn("div",{class:"code-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)] border-[var(--code-border)] bg-[var(--code-header-bg)] text-[var(--code-fg)]"},[yn("div",{class:"code-header-main",style:{minWidth:0,flex:"1 1 auto",display:"flex",alignItems:"center",gap:"var(--ms-gap-header-main, 0.625rem)",overflow:"hidden"}},[yn("span",{class:"icon-slot h-4 w-4 flex-shrink-0","aria-hidden":"true",style:{display:"inline-flex",width:"1rem",height:"1rem",flex:"0 0 auto"}}),yn("div",{class:"code-header-copy",style:{minWidth:0,display:"grid",gap:"2px"}},[yn("div",{class:"code-header-title",style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"var(--ms-text-label, 0.75rem)",fontWeight:"500",color:"var(--code-action-fg)"}},p.title),p.caption?yn("div",{class:"code-header-caption",style:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap",fontSize:"0.75rem",color:"var(--code-line-number)"}},p.caption):null])]),yn("div",{class:"flex items-center gap-0.5",style:{visibility:"hidden"}},[h?yn("div",{class:"code-diff-stats","aria-hidden":"true"},[yn("span",{class:"code-diff-stat removed"},"-0"),yn("span",{class:"code-diff-stat added"},"+0")]):null,n.showCopyButton===!1?null:M(),n.showCollapseButton===!1?null:M(),I?yn("div",{class:"relative"},[M()]):null])]),yn("div",{class:"code-block-shell-content",style:n.stream!==!1||n.loading===!1?void 0:{display:"none"}},[yn(jr,{node:n.node,loading:n.loading,showLineNumbers:!0,reservedHeightPx:h?void 0:n.estimatedContentHeightPx,diffInline:m,diffHideUnchangedRegions:h?fTe(g?.diffHideUnchangedRegions):void 0,class:"code-pre-fallback",style:L,"data-markstream-code-loading":"1"})]),yn("div",{class:"code-loading-placeholder",style:n.stream===!1&&n.loading!==!1?void 0:{display:"none"}},[yn("div",{class:"loading-skeleton"},[yn("div",{class:"skeleton-line"}),yn("div",{class:"skeleton-line"}),yn("div",{class:"skeleton-line short"})])]),yn("span",{class:"sr-only","aria-live":"polite",role:"status"})])}}}),vk=Ip("ViewportDeferredCodeBlockNode",ia({loader:()=>Ji(null,null,function*(){try{return(yield Fo(()=>import("./CodeBlockNode-CJGhujJE.js"),__vite__mapDeps([6,7]))).default}catch(e){return console.warn('[markstream-vue] Failed to load the enhanced CodeBlockNode chunk; falling back to preformatted code rendering. Enhanced code blocks require the optional "stream-diffs" peer (or "stream-monaco" as a fallback).',e),jr}}),loadingComponent:gy,delay:0,suspensible:!1}),gy),ma=ia(()=>Ji(null,null,function*(){var e;if(((e=(function(){const t=Reflect.get(globalThis,"process");return t?.env})())==null?void 0:e.NODE_ENV)==="test"&&typeof window<"u")return t=>{var n,i,o,s;return yn(Bo,An(Mt({},t),{node:{type:"text",content:(i=t.node.raw)!=null?i:`$${(n=t.node.content)!=null?n:""}$`,raw:(s=t.node.raw)!=null?s:`$${(o=t.node.content)!=null?o:""}$`}}))};try{return yield nP(),(yield Fo(()=>import("./index7-DnGHoBRb.js"),[])).default}catch(t){console.warn('[markstream-vue] Optional peer dependencies for MathInlineNode are missing. Falling back to text rendering. To enable full math rendering features, please install "katex".',t)}return t=>{var n,i,o,s;return yn(Bo,An(Mt({},t),{node:{type:"text",content:(i=t.node.raw)!=null?i:`$${(n=t.node.content)!=null?n:""}$`,raw:(s=t.node.raw)!=null?s:`$${(o=t.node.content)!=null?o:""}$`}}))}})),mP=ia(()=>Ji(null,null,function*(){try{return yield nP(),(yield Fo(()=>import("./index6-CBDuyf4L.js"),[])).default}catch(e){console.warn('[markstream-vue] Optional peer dependencies for MathBlockNode are missing. Falling back to text rendering. To enable full math rendering features, please install "katex".',e)}return e=>{var t,n,i,o;return yn(Bo,An(Mt({},e),{node:{type:"text",content:(n=e.node.raw)!=null?n:`$$${(t=e.node.content)!=null?t:""}$$`,raw:(o=e.node.raw)!=null?o:`$$${(i=e.node.content)!=null?i:""}$$`}}))}})),Ar=Ci(Xe({__name:"ReferenceNode",props:{node:{},messageId:{},threadId:{}},emits:["click","mouseEnter","mouseLeave"],setup:e=>(t,n)=>(v(),E("span",{class:"reference-node cursor-pointer text-xs rounded-md px-1.5 mx-0.5",role:"button",tabindex:"0",onClick:n[0]||(n[0]=i=>t.$emit("click",i,e.node.id,e.messageId,e.threadId)),onMouseenter:n[1]||(n[1]=i=>t.$emit("mouseEnter",i,e.node.id,e.messageId,e.threadId)),onMouseleave:n[2]||(n[2]=i=>t.$emit("mouseLeave",i,e.node.id,e.messageId,e.threadId))},D(e.node.id),33))}),[["__scopeId","data-v-775c65e4"]]);Ar.install=e=>{e.component(Ar.__name,Ar)};const xTe={class:"superscript-node"},Kr=Ci(Xe({__name:"SuperscriptNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,emphasis:Sr,footnote_reference:fl,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,emoji:Ur,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("sup",xTe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"superscript"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"superscript"}-${l}`,"fallback-to-text":""},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-24160b22"]]);Kr.install=e=>{e.component(Kr.__name,Kr)};const STe={class:"subscript-node"},Vr=Ci(Xe({__name:"SubscriptNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,emphasis:Sr,footnote_reference:fl,strikethrough:wr,highlight:pl,insert:Zr,superscript:Kr,emoji:Ur,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("sub",STe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"subscript"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"subscript"}-${l}`,"fallback-to-text":""},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-197fa13b"]]);Vr.install=e=>{e.component(Vr.__name,Vr)};const _Te={class:"strong-node"},Cr=Ci(Xe({__name:"StrongNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,emphasis:Sr,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,footnote_reference:fl,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("strong",_Te,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"strong"}-${l}`,components:i.value,node:r,"index-key":`${e.indexKey||"strong"}-${l}`,"custom-id":t.customId},null,8,["components","node","index-key","custom-id"]))),128))]))}}),[["__scopeId","data-v-a8647104"]]);Cr.install=e=>{e.component(Cr.__name,Cr)};const MTe={class:"strikethrough-node"},wr=Ci(Xe({__name:"StrikethroughNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,emphasis:Sr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,footnote_reference:fl,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("del",MTe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"strikethrough"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"strikethrough"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-b7a531fa"]]);wr.install=e=>{e.component(wr.__name,wr)};const ITe=["href","title","aria-label","aria-hidden","target","rel"],ETe=["aria-hidden"],TTe={class:"link-text-wrapper relative inline-flex"},LTe={class:"leading-[normal] link-text"},xr=Ci(Xe({__name:"LinkNode",props:{node:{},indexKey:{},customId:{},showTooltip:{type:Boolean,default:!0},color:{},underlineHeight:{},underlineBottom:{},animationDuration:{},animationOpacity:{},animationTiming:{},animationIteration:{}},setup(e){const t=e,n=hn("markstreamShowTooltips",void 0),i=F(()=>{const w=n?.value;return typeof w=="boolean"?w:t.showTooltip}),o=F(()=>{var w,y,b,A,T;const S=t.underlineBottom!==void 0?typeof t.underlineBottom=="number"?`${t.underlineBottom}px`:String(t.underlineBottom):"-3px",x=(w=t.animationOpacity)!=null?w:.35,_=Math.max(.12,Math.min(.5*x,x)),L={"--underline-height":`${(y=t.underlineHeight)!=null?y:2}px`,"--underline-bottom":S,"--underline-opacity":String(x),"--underline-rest-opacity":String(_),"--underline-duration":`${(b=t.animationDuration)!=null?b:1.6}s`,"--underline-timing":(A=t.animationTiming)!=null?A:"ease-in-out","--underline-iteration":typeof t.animationIteration=="number"?String(t.animationIteration):(T=t.animationIteration)!=null?T:"infinite"};return t.color&&(L["--link-color"]=t.color),L}),s=ss(()=>t.customId),r=F(()=>Mt({text:Bo,strong:Cr,strikethrough:wr,emphasis:Sr,image:yc,html_inline:hl,inline_code:rr},s.value)),l=r1(),a=F(()=>{var w,y;const b=(w=t.node)==null?void 0:w.attrs;if(!b||typeof b!="object")return{};const A={};if(Array.isArray(b))for(const T of b)Array.isArray(T)&&T[0]&&(A[String(T[0])]=String((y=T[1])!=null?y:""));else for(const[T,S]of Object.entries(b))T&&S!=null&&S!==!1&&(A[T]=S===!0?"":String(S));return bE(A,"safe","a")}),u=F(()=>Mt(Mt({},l),a.value)),c=F(()=>{var w,y;return bE({href:String((y=(w=t.node)==null?void 0:w.href)!=null?y:"")},"safe","a").href}),d=F(()=>{if(!c.value)return;const w=u.value.target;return(typeof w=="string"?w.trim():String(w??"").trim())||(gwe(c.value)?"_blank":void 0)}),h=F(()=>{var w;return String((w=d.value)!=null?w:"").trim().toLowerCase()==="_blank"}),p=F(()=>{if(!c.value)return;const w=u.value.rel,y=new Set((typeof w=="string"?w:String(w??"")).split(/\s+/).filter(Boolean)),b=new Set(Array.from(y).filter(A=>A.toLowerCase()!=="opener"));return h.value&&(b.add("noopener"),b.add("noreferrer")),b.size>0?Array.from(b).join(" "):void 0}),g=F(()=>{const w=Mt({},u.value);return delete w.title,delete w.href,delete w.target,delete w.rel,w});function m(){i.value&&YEe()}const k=F(()=>{var w,y;const b=(w=t.node)==null?void 0:w.title;return typeof b=="string"&&b.trim().length>0?b:String((y=c.value)!=null?y:"")});return(w,y)=>{var b,A;return e.node.loading?(v(),E("span",ni({key:1,class:"link-loading inline-flex items-baseline gap-1.5","aria-hidden":e.node.loading?"false":"true"},f(l),{style:o.value}),[C("span",TTe,[C("span",LTe,[U(f(Bo),{class:"leading-[normal] link-text",node:{type:"text",content:String((b=e.node.text)!=null?b:""),raw:String((A=e.node.text)!=null?A:"")},"index-key":`${e.indexKey||"link-text"}-loading`},null,8,["node","index-key"])]),y[1]||(y[1]=C("span",{class:"link-loading-indicator","aria-hidden":"true"},null,-1))])],16,ETe)):(v(),E("a",ni({key:0,class:"link-node",href:c.value,title:i.value?"":k.value,"aria-label":`Link: ${k.value}`,"aria-hidden":e.node.loading?"true":"false",target:d.value,rel:p.value},g.value,{style:o.value,onMouseenter:y[0]||(y[0]=T=>(function(S){var x,_,L,M;if(!i.value)return;const N=S,I=N?.clientX!=null&&N?.clientY!=null?{x:N.clientX,y:N.clientY}:void 0,z=((x=t.node)==null?void 0:x.title)||((_=c.value)!=null&&_.includes("xn--")&&((M=(L=t.node)==null?void 0:L.text)!=null&&M.includes("://"))?t.node.text:c.value)||"";QEe(S.currentTarget,z,"top",!1,I)})(T)),onMouseleave:m}),[(v(!0),E(Ee,null,pt(e.node.children,(T,S)=>(v(),ce(f(Va),{key:`${e.indexKey||"emphasis"}-${S}`,components:r.value,node:T,"custom-id":t.customId,"index-key":`${e.indexKey||"link-text"}-${S}`},null,8,["components","node","custom-id","index-key"]))),128))],16,ITe))}}}),[["__scopeId","data-v-367e6ca4"]]);xr.install=e=>{e.component(xr.__name,xr)};const NTe={class:"insert-node"},Zr=Ci(Xe({__name:"InsertNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,emphasis:Sr,strikethrough:wr,highlight:pl,subscript:Vr,superscript:Kr,emoji:Ur,footnote_reference:fl,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("ins",NTe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"insert"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"insert"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-1e2c29d4"]]);Zr.install=e=>{e.component(Zr.__name,Zr)};const FTe={class:"highlight-node"},pl=Ci(Xe({__name:"HighlightNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,emphasis:Sr,strikethrough:wr,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,footnote_reference:fl,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("mark",FTe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"highlight"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"highlight"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-7a62982a"]]);pl.install=e=>{e.component(pl.__name,pl)};const DTe={class:"emphasis-node"},Sr=Ci(Xe({__name:"EmphasisNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>Mt({text:Bo,inline_code:rr,link:xr,html_inline:hl,strong:Cr,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,footnote_reference:fl,math_inline:ma,reference:Ar},n.value));return(o,s)=>(v(),E("em",DTe,[(v(!0),E(Ee,null,pt(e.node.children,(r,l)=>(v(),ce(f(Va),{key:`${e.indexKey||"emphasis"}-${l}`,components:i.value,node:r,"custom-id":t.customId,"index-key":`${e.indexKey||"emphasis"}-${l}`},null,8,["components","node","custom-id","index-key"]))),128))]))}}),[["__scopeId","data-v-2a5aafbf"]]);Sr.install=e=>{e.component(Sr.__name,Sr)};const BTe={class:"hard-break"},kc=Ci(Xe({__name:"HardBreakNode",props:{node:{}},setup:e=>(t,n)=>(v(),E("br",BTe))}),[["__scopeId","data-v-50c58f70"]]);kc.install=e=>{e.component(kc.__name,kc)};const j0=Xe({__name:"SimpleInlineRenderer",props:{nodes:{},customId:{},indexKey:{}},setup(e){const t=e,n=St({checkbox:dl,checkbox_input:dl,emoji:Ur,emphasis:Sr,hardbreak:kc,highlight:pl,inline_code:rr,insert:Zr,link:xr,reference:Ar,strikethrough:wr,strong:Cr,subscript:Vr,superscript:Kr,text:Bo}),i=ss(()=>t.customId),o=F(()=>{const s=i.value;return Object.keys(s).length>0?Mt(Mt({},n),s):n});return(s,r)=>(v(!0),E(Ee,null,pt(e.nodes,(l,a)=>(v(),ce(f(Va),{key:a,components:o.value,node:l,"custom-id":t.customId,"index-key":`${e.indexKey||"inline"}-${a}`},null,8,["components","node","custom-id","index-key"]))),128))}});function t5(e){if(!e||typeof e!="object")return!1;const t=`|${e.type}|`;if(!"|checkbox|checkbox_input|emoji|emphasis|hardbreak|highlight|inline_code|insert|link|reference|strikethrough|strong|subscript|superscript|text|".includes(t))return!1;if(!"|emphasis|highlight|insert|link|strikethrough|strong|subscript|superscript|".includes(t))return!0;const n=e.children;return Array.isArray(n)&&n.every(t5)}function my(e,t=!0,n=!1){if(!e||!n&&e.length===0)return null;if(e.every(t5))return e;if(!t||e.length!==1)return null;const i=e[0];if(i?.type!=="paragraph"||!Array.isArray(i.children))return null;const o=i.children;return(n||o.length>0)&&o.every(t5)?o:null}function hf(e){var t,n;if(!e?.length)return null;let i="";for(const o of e){if(o?.type!=="text"||o.center===!0)return null;i+=String((n=(t=o.content)!=null?t:o.raw)!=null?n:"")}return i}const $Te=["cite"],RTe={key:0,dir:"auto",class:"paragraph-node"},zTe=["custom-id"],Rv=Ci(Xe({__name:"BlockquoteNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{},showTooltips:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=ss(()=>t.customId),i=F(()=>!!n.value.paragraph),o=F(()=>!!n.value.text),s=F(()=>my(t.node.children,!i.value)),r=F(()=>t.fade!==!1||o.value?null:hf(s.value));return oi("markstreamShowTooltips",F(()=>t.showTooltips)),oi("markstreamFade",F(()=>t.fade)),(l,a)=>(v(),E("blockquote",{class:"blockquote blockquote-node",dir:"auto",cite:e.node.cite},[s.value?(v(),E("p",RTe,[r.value!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(r.value),9,zTe)):(v(),ce(f(j0),{key:1,nodes:s.value,"custom-id":t.customId,"index-key":`blockquote-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))])):(v(),ce(f(Gr),{key:1,"show-tooltips":t.showTooltips,"index-key":`blockquote-${t.indexKey}`,nodes:t.node.children||[],"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:a[0]||(a[0]=u=>l.$emit("copy",u))},null,8,["show-tooltips","index-key","nodes","custom-id","typewriter","fade"]))],8,$Te))}}),[["__scopeId","data-v-abfecebc"]]);Rv.install=e=>{e.component(Rv.__name,Rv)};const OTe={class:"definition-list"},PTe={class:"definition-term"},jTe={class:"definition-desc"},zv=Ci(Xe({__name:"DefinitionListNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e){const t=e;return(n,i)=>(v(),E("dl",OTe,[(v(!0),E(Ee,null,pt(t.node.items,(o,s)=>(v(),E(Ee,{key:s},[C("dt",PTe,[U(f(Gr),{"index-key":`definition-term-${t.indexKey}-${s}`,nodes:o.term,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:i[0]||(i[0]=r=>n.$emit("copy",r))},null,8,["index-key","nodes","custom-id","typewriter","fade"])]),C("dd",jTe,[U(f(Gr),{"index-key":`definition-desc-${t.indexKey}-${s}`,nodes:o.definition,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:i[1]||(i[1]=r=>n.$emit("copy",r))},null,8,["index-key","nodes","custom-id","typewriter","fade"])])],64))),128))]))}}),[["__scopeId","data-v-4e103b30"]]);zv.install=e=>{e.component(zv.__name,zv)};const HTe=["href","title"],t0=Ci(Xe({__name:"FootnoteAnchorNode",props:{node:{}},setup(e){const t=e;function n(i){var o;if(i.preventDefault(),typeof document>"u")return;const s=`fnref-${String((o=t.node.id)!=null?o:"")}`,r=document.getElementById(s);r&&r.scrollIntoView({behavior:"smooth",block:"center"})}return(i,o)=>(v(),E("a",{class:"footnote-anchor text-sm hover:underline cursor-pointer",href:`#fnref-${e.node.id}`,title:`返回引用 ${e.node.id}`,onClick:n}," ↩︎ ",8,HTe))}}),[["__scopeId","data-v-e1eb37b6"]]);t0.install=e=>{e.component(t0.__name,t0)};const WTe=["id"],qTe={class:"flex-1"},Ov=Xe({__name:"FootnoteNode",props:{node:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e){const t=e;return(n,i)=>(v(),E("div",{id:`fnref--${e.node.id}`,class:"footnote-node flex text-sm leading-relaxed border-t border-[var(--footnote-border)] pt-2"},[C("div",qTe,[U(f(Gr),{"index-key":`footnote-${t.indexKey}`,nodes:t.node.children,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,onCopy:i[0]||(i[0]=o=>n.$emit("copy",o))},null,8,["index-key","nodes","custom-id","typewriter","fade"])])],8,WTe))}});Ov.install=e=>{e.component(Ov.__name,Ov)};const UTe=["custom-id"],n5=Ci(Xe({__name:"HeadingNode",props:{node:{},customId:{},indexKey:{}},setup(e){const t=e,n=ss(()=>t.customId),i=hn("markstreamFade",void 0),o=F(()=>i?.value!==!1||n.value.text?null:hf(t.node.children)),s=F(()=>Mt({text:Bo,inline_code:rr,link:xr,image:yc,strong:Cr,emphasis:Sr,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,checkbox:dl,checkbox_input:dl,footnote_reference:fl,hardbreak:kc,math_inline:ma,reference:Ar},n.value));return(r,l)=>(v(),ce(Oo(`h${e.node.level}`),ni({class:["heading-node",[`heading-${e.node.level}`]],dir:"auto"},e.node.attrs),{default:de(()=>[o.value!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(o.value),9,UTe)):(v(!0),E(Ee,{key:1},pt(e.node.children,(a,u)=>(v(),ce(f(Va),{key:u,components:s.value,"custom-id":t.customId,node:a,"index-key":`${e.indexKey||"heading"}-${u}`},null,8,["components","custom-id","node","index-key"]))),128))]),_:1},16,["class"]))}}),[["__scopeId","data-v-7122dbe1"]]),B9=n5;B9.install=e=>{e.component(n5.__name,n5)};const KTe={key:0,dir:"auto",class:"paragraph-node"},VTe=["custom-id"],ZTe={dir:"auto",class:"paragraph-node"},GTe=["custom-id"],Ph=Ci(Xe({__name:"ListItemNode",props:{node:{},item:{},indexKey:{},customId:{},typewriter:{type:Boolean},fade:{type:Boolean},showTooltips:{type:Boolean},value:{},isDark:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=F(()=>{var p;return(p=t.node)!=null?p:t.item}),i=ss(()=>t.customId),o=F(()=>!!i.value.paragraph),s=F(()=>!!i.value.text),r=F(()=>{var p;return my((p=n.value)==null?void 0:p.children,!o.value)}),l=F(()=>{var p;if(o.value)return null;const g=(p=n.value)==null?void 0:p.children;if(!Array.isArray(g)||g.length<2)return null;const m=g[0];if(m?.type!=="paragraph"||!Array.isArray(m.children))return null;const k=g.slice(1);if(!k.every(y=>y?.type==="list"))return null;const w=my([m]);return w?{paragraphChildren:w,nestedLists:k}:null});function a(){return t.fade===!1&&!s.value}const u=F(()=>a()?hf(r.value):null),c=F(()=>{var p;return a()?hf((p=l.value)==null?void 0:p.paragraphChildren):null}),d=Object.freeze({}),h=F(()=>{const{value:p}=t;return typeof p=="number"&&Number.isFinite(p)?{value:p}:d});return oi("markstreamShowTooltips",F(()=>t.showTooltips)),oi("markstreamFade",F(()=>t.fade)),(p,g)=>{var m,k;return v(),E("li",ni({class:"list-item",dir:"auto"},h.value),[r.value?(v(),E("p",KTe,[u.value!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(u.value),9,VTe)):(v(),ce(f(j0),{key:1,nodes:r.value,"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))])):l.value?(v(),E(Ee,{key:1},[C("p",ZTe,[c.value!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(c.value),9,GTe)):(v(),ce(f(j0),{key:1,nodes:l.value.paragraphChildren,"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-paragraph`},null,8,["nodes","custom-id","index-key"]))]),(v(!0),E(Ee,null,pt(l.value.nestedLists,(w,y)=>(v(),ce(f(Gr),{key:y,nodes:[w],"custom-id":t.customId,"index-key":`list-item-${t.indexKey}-nested-${y}`,"show-tooltips":t.showTooltips,typewriter:t.typewriter,fade:t.fade,"is-dark":t.isDark,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0,onCopy:g[0]||(g[0]=b=>p.$emit("copy",b))},null,8,["nodes","custom-id","index-key","show-tooltips","typewriter","fade","is-dark"]))),128))],64)):(v(),ce(f(Gr),{key:2,"show-tooltips":t.showTooltips,"index-key":`list-item-${t.indexKey}`,nodes:(k=(m=n.value)==null?void 0:m.children)!=null?k:[],"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"is-dark":t.isDark,"batch-rendering":!1,onCopy:g[1]||(g[1]=w=>p.$emit("copy",w))},null,8,["show-tooltips","index-key","nodes","custom-id","typewriter","fade","is-dark"]))],16)}}}),[["__scopeId","data-v-617214f9"]]);Ph.install=e=>{e.component(Ph.__name,Ph)};const jh=Ci(Xe({__name:"ListNode",props:{node:{},customId:{},indexKey:{},typewriter:{type:Boolean},fade:{type:Boolean},showTooltips:{type:Boolean},isDark:{type:Boolean}},emits:["copy"],setup(e){const t=ss(()=>e.customId),n=F(()=>t.value.list_item||Ph);return(i,o)=>(v(),ce(Oo(e.node.ordered?"ol":"ul"),{class:Fe(["list-node",{"list-decimal":e.node.ordered,"list-disc":!e.node.ordered}])},{default:de(()=>[(v(!0),E(Ee,null,pt(e.node.items,(s,r)=>{var l;return v(),ce(Oo(n.value),ni({key:`${e.indexKey||"list"}-${r}`},{ref_for:!0},{showTooltips:e.showTooltips},{node:s,"custom-id":e.customId,"index-key":`${e.indexKey||"list"}-${r}`,typewriter:e.typewriter,fade:e.fade,"is-dark":e.isDark,value:e.node.ordered?((l=e.node.start)!=null?l:1)+r:void 0,onCopy:o[0]||(o[0]=a=>i.$emit("copy",a))}),null,16,["node","custom-id","index-key","typewriter","fade","is-dark","value"])}),128))]),_:1},8,["class"]))}}),[["__scopeId","data-v-99cb95e0"]]);jh.install=e=>{e.component(jh.__name,jh)};const QTe={key:2,class:"html-block-node__raw"},YTe=["innerHTML"],JTe={key:1,class:"html-block-node__placeholder"},n0=Ci(Xe({__name:"HtmlBlockNode",props:{node:{},customId:{},htmlPolicy:{}},setup(e){const t=e,n=hn("markstreamHtmlPolicy",void 0),i=hn("markstreamNestedRendererProps",void 0),o=F(()=>{var I,z;return(z=(I=t.htmlPolicy)!=null?I:n?.value)!=null?z:"safe"}),s=F(()=>{var I,z;const H=(I=i?.value)!=null?I:{};return An(Mt({},H),{customId:(z=t.customId)!=null?z:H.customId,htmlPolicy:o.value})}),r=ia({loader:()=>Promise.resolve().then(()=>iA),suspensible:!1}),l=F(()=>{const I=Fv(t.node.attrs,o.value);if(!I)return;const z=Yp(I);return Object.keys(z).length>0?z:void 0}),a=F(()=>{const I=String(t.node.tag||"").trim(),z=Fv(t.node.attrs,o.value,I);if(!z)return;const H=Yp(z);return Object.keys(H).length>0?H:void 0}),u=ss(()=>t.customId),c=Xe({name:"DynamicRenderer",props:{nodes:{type:Array,required:!0}},render(){return this.nodes}}),d=K(null),h=K(typeof window>"u"),p=K(t.node.content),g=F(()=>Array.isArray(t.node.children)?t.node.children:[]),m=F(()=>String(t.node.tag||"div")),k=F(()=>{var I;if(m.value.trim().toLowerCase()!=="details"||(I=t.node.attrs)!=null&&I.some(([H])=>String(H).toLowerCase()==="open"))return null;const z=g.value[0];return z?.type==="html_block"&&String(z.tag||"").toLowerCase()==="summary"?z:null}),w=F(()=>{var I;return hf((I=k.value)==null?void 0:I.children)}),y=F(()=>{const I=k.value;if(!I)return;const z=Fv(I.attrs,o.value,"summary");if(!z)return;const H=Yp(z);return Object.keys(H).length>0?H:void 0}),b=F(()=>w.value==null?g.value:g.value.slice(1)),A=F(()=>{const I=m.value.trim().toLowerCase();return $z.has(I)||z7(I,o.value)}),T=F(()=>g.value.length>0&&!!t.node.tag&&!A.value),S=F(()=>{var I,z,H;if(T.value)return{mode:"structured"};if(!h.value)return{mode:"html",content:(I=p.value)!=null?I:""};const O=(z=p.value)!=null?z:t.node.content;if(!O)return{mode:"html",content:""};if(o.value==="escape")return{mode:"html",content:Oh(O,o.value)};if(t.node.loading){const j=py(O,u.value,o.value);return j===null?{mode:"text",content:(H=t.node.raw)!=null?H:O}:{mode:"dynamic",nodes:j}}if(!uP(O,u.value))return{mode:"html",content:Oh(O,o.value)};const R=py(O,u.value,o.value);return R===null?{mode:"html",content:Oh(O,o.value)}:{mode:"dynamic",nodes:R}}),x=K7(),_=q7(),L=U7(),M=ha(null),N=!!t.node.loading;return typeof window<"u"?(Pe([()=>d.value,()=>_?.value.heavyBlockMargin,()=>_?.value.rootMargin],([I],z,H)=>{var O,R,j,$;if((R=(O=M.value)==null?void 0:O.destroy)==null||R.call(O),M.value=null,!N)return h.value=!0,void(p.value=t.node.content);if(!I)return void(h.value=!1);let W=!0;const P=($=(j=_?.value.heavyBlockMargin)!=null?j:_?.value.rootMargin)!=null?$:ff,Z=x(I,{rootMargin:P,allowIdle:!L.value});M.value=Z,h.value=h.value||Z.isVisible.value,Z.whenVisible.then(()=>{W&&M.value===Z&&(h.value=!0)}),H(()=>{W=!1,Z.destroy(),M.value===Z&&(M.value=null)})},{immediate:!0}),Pe(()=>t.node.content,I=>{N&&!h.value||(p.value=I)})):h.value=!0,Hn(()=>{var I,z;(z=(I=M.value)==null?void 0:I.destroy)==null||z.call(I),M.value=null}),(I,z)=>(v(),ce(Oo(T.value?m.value:"div"),ni({ref_key:"htmlRef",ref:d,class:"html-block-node","data-markstream-viewport-pending":f(L)&&!h.value?"true":void 0},T.value?a.value:void 0),{default:de(()=>[h.value?(v(),E(Ee,{key:0},[S.value.mode==="structured"?(v(),E(Ee,{key:0},[w.value!==null?(v(),E(Ee,{key:0},[C("summary",RW(eF(y.value)),D(w.value),17),b.value.length?(v(),ce(f(r),ni({key:0},s.value,{nodes:b.value,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes"])):X("",!0)],64)):(v(),ce(f(r),ni({key:1},s.value,{nodes:g.value,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes"]))],64)):S.value.mode==="dynamic"?(v(),ce(f(c),{key:1,nodes:S.value.nodes},null,8,["nodes"])):S.value.mode==="text"?(v(),E("pre",QTe,D(S.value.content),1)):(v(),E("div",ni({key:3},l.value,{innerHTML:S.value.content}),null,16,YTe))],64)):(v(),E("div",JTe,[Rn(I.$slots,"placeholder",{node:e.node},()=>[z[0]||(z[0]=C("span",{class:"html-block-node__placeholder-bar"},null,-1)),z[1]||(z[1]=C("span",{class:"html-block-node__placeholder-bar w-4/5"},null,-1)),z[2]||(z[2]=C("span",{class:"html-block-node__placeholder-bar w-2/3"},null,-1))],!0)]))]),_:3},16,["data-markstream-viewport-pending"]))}}),[["__scopeId","data-v-e140a874"]]);n0.install=e=>{e.component(n0.__name,n0)};const XTe={dir:"auto",class:"paragraph-node"},eLe=["custom-id"],Jd=Ci(Xe({__name:"ParagraphNode",props:{node:{},customId:{},indexKey:{},customHtmlTags:{},parseOptions:{},customMarkdownIt:{type:Function}},setup(e){const t=e,n=ss(()=>t.customId),i=hn("markstreamHtmlPolicy",void 0),o=hn("markstreamFade",void 0),s=hn("markstreamParseOptions",void 0),r=hn("markstreamCustomMarkdownIt",void 0),l=hn("markstreamNestedRendererProps",void 0),a=F(()=>{var _;return(_=i?.value)!=null?_:"safe"}),u=F(()=>{var _;return(_=t.parseOptions)!=null?_:s?.value}),c=F(()=>{var _;return(_=t.customMarkdownIt)!=null?_:r?.value}),d=F(()=>{var _,L;return(L=t.customHtmlTags)!=null?L:(_=l?.value)==null?void 0:_.customHtmlTags}),h=F(()=>{var _,L;const M=(_=l?.value)!=null?_:{};return An(Mt({},M),{customId:(L=t.customId)!=null?L:M.customId,customHtmlTags:d.value,parseOptions:u.value,customMarkdownIt:c.value,htmlPolicy:a.value})}),p=ia({loader:()=>Promise.resolve().then(()=>iA),suspensible:!1});function g(_){var L;return _.type==="text"&&String((L=_.content)!=null?L:"").trim()===""}const m=F(()=>t.node.children.filter(_=>!g(_))),k=F(()=>m.value.length>0&&m.value.every(_=>_.type==="image"||(function(L){var M;const N=(function(I){return I.type==="link"&&Array.isArray(I.children)?I.children.filter(z=>!g(z)):[]})(L);return N.length===1&&((M=N[0])==null?void 0:M.type)==="image"})(_))),w=F(()=>new Set(wf(d.value))),y=F(()=>{if(!k.value||m.value.length<=1)return t.node.children;const _=[];for(let L=0;L<t.node.children.length;L++){const M=t.node.children[L];if(!g(M)){_.push(M);continue}const N=_.length>0,I=t.node.children.slice(L+1).some(z=>!g(z));N&&I&&_.push(An(Mt({},M),{content:" ",raw:" "}))}return _}),b=F(()=>o?.value===!1&&!n.value.text),A=F(()=>b.value?hf(y.value):null);function T(_,L){return{node:_,"index-key":`${t.indexKey}-${L}`,"custom-id":t.customId,"custom-html-tags":d.value}}const S=F(()=>Mt({inline_code:rr,image:yc,link:xr,hardbreak:kc,emphasis:Sr,strong:Cr,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,html_inline:hl,html_block:n0,emoji:Ur,checkbox:dl,math_inline:ma,checkbox_input:dl,reference:Ar,footnote_anchor:t0,footnote_reference:fl,text:Bo},n.value)),x=F(()=>y.value.map((_,L)=>{var M;const N=(function(I){var z,H,O,R;if(I.type==="html_block"||I.type==="html_inline"){const j=String((z=I.tag)!=null?z:"").trim().toLowerCase()||jz(I.content);if(j&&!w.value.has(j)&&Hz((H=I.content)!=null?H:I.raw,j)){const $=String((R=(O=I.content)!=null?O:I.raw)!=null?R:"");return{child:{type:"text",content:$,raw:$},component:Bo,isCustomComponent:!1}}}return{child:I,component:S.value[I.type],isCustomComponent:!!(n.value[I.type]&&!Cg(String(I.type)))}})(_);return An(Mt({},N),{index:L,key:`${t.indexKey||"paragraph"}-${L}`,customAttrs:N.isCustomComponent?W7(N.child,a.value):void 0,hasSlotChildren:Array.isArray(N.child.children)&&N.child.children.length>0,slotContent:String((M=N.child.content)!=null?M:""),originalChild:_})}));return(_,L)=>(v(),E("p",XTe,[A.value!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(A.value),9,eLe)):(v(!0),E(Ee,{key:1},pt(x.value,M=>{return v(),E(Ee,{key:M.key},[k.value&&g(M.originalChild)?(v(),E(Ee,{key:0},[$e(D((N=M.originalChild,String((I=N.content)!=null?I:""))),1)],64)):M.isCustomComponent?(v(),ce(Oo(M.component),ni({key:1,ref_for:!0},M.customAttrs,{node:M.child,loading:M.child.loading,"index-key":M.key,"custom-id":t.customId,"custom-html-tags":d.value,"is-dark":h.value.isDark}),{default:de(()=>[M.hasSlotChildren?(v(),ce(f(p),ni({key:0,ref_for:!0},h.value,{nodes:M.child.children,"index-key":M.key,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):M.slotContent?(v(),ce(f(p),ni({key:1,ref_for:!0},h.value,{content:M.slotContent,final:!M.child.loading,"index-key":`${M.key}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):X("",!0)]),_:2},1040,["node","loading","index-key","custom-id","custom-html-tags","is-dark"])):(v(),ce(Oo(M.component),ni({key:2,ref_for:!0},T(M.child,M.index)),null,16))],64);var N,I}),128))]))}}),[["__scopeId","data-v-c59ff506"]]);Jd.install=e=>{e.component(Jd.__name,Jd)};const tLe={class:"table-node-wrapper"},nLe=["aria-busy"],iLe={key:0},oLe=["custom-id"],sLe=["aria-label","onPointerdown"],rLe=["custom-id"],lLe={key:0,class:"table-node__loading",role:"status","aria-live":"polite"},i0=Ci(Xe({__name:"TableNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{},showTooltips:{type:Boolean}},emits:["copy"],setup(e){const t=e,n=F(()=>{var w;return(w=t.node.loading)!=null&&w}),i=F(()=>{var w;return(w=t.node.rows)!=null?w:[]}),o=K(null),s=K([]);let r=null;const l=F(()=>t.node.header.cells.length),a=F(()=>s.value.some(w=>Number.isFinite(w)&&w>0)),u=F(()=>a.value?s.value.map(w=>w>0?{width:`${w}px`}:void 0):[]);oi("markstreamShowTooltips",F(()=>t.showTooltips)),oi("markstreamFade",F(()=>t.fade));const c=ss(()=>t.customId),d=F(()=>!!c.value.text),h=F(()=>!!c.value.paragraph),p=new WeakMap;function g(w){const y=t.fade===!1&&!d.value,b=!h.value,A=p.get(w);if(A?.children===w.children&&A.textFastPath===y&&A.paragraphFastPath===b)return A.info;const T=my(w.children,b,!0),S={simpleChildren:T,plainText:T&&y?hf(T):null};return p.set(w,{children:w.children,textFastPath:y,paragraphFastPath:b,info:S}),S}function m(w){if(!r)return;w.preventDefault();const y=r.startWidth+r.nextStartWidth,b=Math.min(48,Math.floor(y/2)),A=Math.max(b,Math.min(y-b,Math.round(r.startWidth+w.clientX-r.startX))),T=[...r.widths];T[r.index]=A,T[r.index+1]=y-A,s.value=T}function k(){r&&(window.removeEventListener("pointermove",m),window.removeEventListener("pointerup",k),window.removeEventListener("pointercancel",k),r=null)}return Pe(l,()=>{k(),s.value=[]}),Hn(k),(w,y)=>(v(),E("div",tLe,[C("table",{ref_key:"tableRef",ref:o,class:Fe(["table-node",{"table-node--loading":n.value}]),"aria-busy":n.value},[a.value?(v(),E("colgroup",iLe,[(v(!0),E(Ee,null,pt(e.node.header.cells,(b,A)=>(v(),E("col",{key:A,style:Kt(u.value[A])},null,4))),128))])):X("",!0),C("thead",null,[C("tr",null,[(v(!0),E(Ee,null,pt(e.node.header.cells,(b,A)=>(v(),E("th",{key:A,dir:"auto",class:Fe([b.align==="right"?"text-right":b.align==="center"?"text-center":"text-left"])},[g(b).plainText!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(g(b).plainText),9,oLe)):g(b).simpleChildren?(v(),ce(f(j0),{key:1,nodes:g(b).simpleChildren,"custom-id":t.customId,"index-key":`table-th-${t.indexKey}-${A}`},null,8,["nodes","custom-id","index-key"])):(v(),ce(f(Gr),{key:2,nodes:b.children,"index-key":`table-th-${t.indexKey}`,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"show-tooltips":t.showTooltips,onCopy:y[0]||(y[0]=T=>w.$emit("copy",T))},null,8,["nodes","index-key","custom-id","typewriter","fade","show-tooltips"])),A<e.node.header.cells.length-1?(v(),E("button",{key:3,type:"button",class:"table-node__resize-handle","aria-label":`Resize columns ${A+1} and ${A+2}`,onPointerdown:T=>(function(S,x){if(x.button!==0)return;const _=(function(){var N;const I=(N=o.value)==null?void 0:N.querySelectorAll("thead th");return Array.from(I??[],z=>Math.round(z.getBoundingClientRect().width))})(),L=_[S],M=_[S+1];L&&M&&(x.preventDefault(),r={index:S,startX:x.clientX,startWidth:L,nextStartWidth:M,widths:_},s.value=_,window.addEventListener("pointermove",m),window.addEventListener("pointerup",k),window.addEventListener("pointercancel",k))})(A,T)},null,40,sLe)):X("",!0)],2))),128))])]),C("tbody",null,[(v(!0),E(Ee,null,pt(i.value,(b,A)=>(v(),E("tr",{key:A},[(v(!0),E(Ee,null,pt(b.cells,(T,S)=>(v(),E("td",{key:S,class:Fe([T.align==="right"?"text-right":T.align==="center"?"text-center":"text-left"]),dir:"auto"},[g(T).plainText!==null?(v(),E("span",{key:0,class:"text-node","custom-id":t.customId},D(g(T).plainText),9,rLe)):g(T).simpleChildren?(v(),ce(f(j0),{key:1,nodes:g(T).simpleChildren,"custom-id":t.customId,"index-key":`table-td-${t.indexKey}-${A}-${S}`},null,8,["nodes","custom-id","index-key"])):(v(),ce(f(Gr),{key:2,nodes:T.children,"index-key":`table-td-${t.indexKey}`,"custom-id":t.customId,typewriter:t.typewriter,fade:t.fade,"show-tooltips":t.showTooltips,onCopy:y[1]||(y[1]=x=>w.$emit("copy",x))},null,8,["nodes","index-key","custom-id","typewriter","fade","show-tooltips"]))],2))),128))]))),128))])],10,nLe),U(fo,{name:"table-node-fade"},{default:de(()=>[n.value?(v(),E("div",lLe,[Rn(w.$slots,"loading",{isLoading:n.value},()=>[y[2]||(y[2]=C("span",{class:"table-node__spinner animate-spin","aria-hidden":"true"},null,-1)),y[3]||(y[3]=C("span",{class:"sr-only"},"Loading",-1))],!0)])):X("",!0)]),_:3})]))}}),[["__scopeId","data-v-39f87b5d"]]);i0.install=e=>{e.component(i0.__name,i0)};const aLe={class:"hr-node"},Pv=Ci({},[["render",function(e,t){return v(),E("hr",aLe)}],["__scopeId","data-v-39b2349c"]]);Pv.install=e=>{e.component(Pv.__name,Pv)};const uLe={class:"unknown-node"},i5=Xe({__name:"FallbackComponent",props:{node:{}},setup:e=>(t,n)=>(v(),E("div",uLe,D(e.node.raw),1))}),jv=Ci(Xe({__name:"VmrContainerNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},setup(e){const t=e,n=F(()=>`vmr-container vmr-container-${t.node.name}`),i=ss(()=>t.customId),o=F(()=>Mt({text:Bo,paragraph:Jd,heading:B9,inline_code:rr,link:xr,image:yc,strong:Cr,emphasis:Sr,strikethrough:wr,insert:Zr,subscript:Vr,superscript:Kr,checkbox:dl,checkbox_input:dl,hardbreak:kc,math_inline:ma,reference:Ar,list:jh,math_block:mP,table:i0},i.value));return(s,r)=>(v(),E("div",ni({class:n.value},e.node.attrs),[(v(!0),E(Ee,null,pt(e.node.children,(l,a)=>{return v(),ce(Oo((u=l.type,o.value[u]||i5)),{key:`${e.indexKey||"vmr-container"}-${a}`,"custom-id":t.customId,node:l,"index-key":`${e.indexKey||"vmr-container"}-${a}`,typewriter:t.typewriter,fade:t.fade},null,8,["custom-id","node","index-key","typewriter","fade"]);var u}),128))],16))}}),[["__scopeId","data-v-911e41c4"]]);jv.install=e=>{e.component(jv.__name,jv)};const cLe=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],EE=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function dLe(e){if(e<=255)return cLe[e];let t=0,n=EE.length-1;for(;t<=n;){const i=t+n>>1,o=EE[i];if(e<o[0])n=i-1;else{if(!(e>o[1]))return o[2];t=i+1}}return"L"}const fLe=/[ \t\n\r\f]+/g,hLe=/[\t\n\r\f]| {2,}|^ | $/;let yk=null;const pLe=new RegExp("\\p{Script=Arabic}","u"),Fc=new RegExp("\\p{M}","u"),Z7=new RegExp("\\p{Nd}","u");function TE(e){return pLe.test(e)}function LE(e){return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=183984&&e<=191471||e>=191472&&e<=192093||e>=194560&&e<=195103||e>=196608&&e<=201551||e>=201552&&e<=205743||e>=205744&&e<=210041||e>=63744&&e<=64255||e>=12288&&e<=12351||e>=12352&&e<=12447||e>=12448&&e<=12543||e>=12592&&e<=12687||e>=44032&&e<=55215||e>=65280&&e<=65519}function Ba(e){for(let t=0;t<e.length;t++){const n=e.charCodeAt(t);if(!(n<12288)){if(n>=55296&&n<=56319&&t+1<e.length){const i=e.charCodeAt(t+1);if(i>=56320&&i<=57343){if(LE(i-56320+(n-55296<<10)+65536))return!0;t++;continue}}if(LE(n))return!0}}return!1}const gLe=new Set([" "," ","⁠","\uFEFF"]),mLe=new Set(["-","‐","–","—"]);function vP(e,t){return!((function(n){const i=o0(n);return i!==null&&gLe.has(i)})(e)||t&&((function(n){const i=o0(n);return i!==null&&(G7.has(i)||pf.has(i))})(e)||(function(n){const i=o0(n);return i!==null&&mLe.has(i)})(e)))}const G7=new Set([",",".","!",":",";","?","、","。","・",")","〕","〉","》","」","』","】","〗","〙","〛","ー","々","〻","ゝ","ゞ","ヽ","ヾ"]),$9=new Set(['"',"(","[","{","¡","¿","“","‘","‚","„","«","‹","⸘","(","〔","〈","《","「","『","【","〖","〘","〚"]),Q7=new Set(["'","’"]),pf=new Set([".",",","!","?",":",";","،","؛","؟","।","॥","၊","။","၌","၍","၏",")","]","}","%",'"',"”","’","»","›","…"]),vLe=new Set([":",".","،","؛"]),yLe=new Set(["၏"]),kLe=new Set(["”","’","»","›","」","』","】","》","〉","〕",")"]);function bLe(e){if(Y7(e))return!0;let t=!1;for(const n of e)if(pf.has(n)||yy(n))t=!0;else if(!t||!Fc.test(n))return!1;return t}function ALe(e){for(const t of e)if(!G7.has(t)&&!pf.has(t))return!1;return e.length>0}function CLe(e){if(Y7(e))return!0;for(const t of e)if(!($9.has(t)||Q7.has(t)||Fc.test(t)||yy(t)))return!1;return e.length>0}function Y7(e){let t=!1;for(const n of e)if(n!=="\\"&&!Fc.test(n)){if(!($9.has(n)||pf.has(n)||Q7.has(n)))return!1;t=!0}return t}function vy(e,t){const n=t-1;if(n<=0)return Math.max(n,0);const i=e.charCodeAt(n);if(i<56320||i>57343)return n;const o=n-1;if(o<0)return n;const s=e.charCodeAt(o);return s>=55296&&s<=56319?o:n}function o0(e){if(e.length===0)return null;const t=vy(e,e.length);return e.slice(t)}const wLe=[36,37,43,43,92,92,162,165,176,177,1423,1423,1545,1547,1642,1642,2046,2047,2546,2547,2553,2555,2801,2801,3065,3065,3449,3449,3647,3647,6107,6107,8240,8247,8279,8279,8352,8399,8451,8451,8457,8457,8470,8470,8722,8723,43064,43064,65020,65020,65129,65130,65284,65285,65504,65505,65509,65510,73693,73696,123647,123647,126124,126124,126128,126128];function yy(e){const t=e.codePointAt(0);return t!==void 0&&(function(n,i){for(let o=0;o<i.length;o+=2)if(n>=i[o]&&n<=i[o+1])return!0;return!1})(t,wLe)}function xLe(e){const t=(function(n){for(const i of n)if(!Fc.test(i))return i;return null})(e);return t!==null&&Z7.test(t)}function SLe(e){const t=Array.from(e);let n=t.length;for(;n>0;){const i=t[n-1];if(Fc.test(i))n--;else{if(!$9.has(i)&&!Q7.has(i))break;n--}}return n<=0||n===t.length?null:{head:t.slice(0,n).join(""),tail:t.slice(n).join("")}}function _Le(e,t,n){return n!=="text"||t||e.length!==1||e==="-"||e==="—"?null:e}function NE(e,t,n,i){const o=t[i],s=e[i];if(o==null)return s;const r=n[i];if(s.length===r)return s;const l=o.repeat(r);return e[i]=l,l}function FE(e,t){return e&&t!==null&&vLe.has(t)}function MLe(e){const t=o0(e);return t!==null&&yLe.has(t)}function ILe(e){if(e.length<2||e[0]!==" ")return null;const t=e.slice(1);return new RegExp("^\\p{M}+$","u").test(t)?{space:" ",marks:t}:null}function o5(e){let t=e.length;for(;t>0;){const n=vy(e,t),i=e.slice(n,t);if(kLe.has(i))return!0;if(!pf.has(i))return!1;t=n}return!1}function ELe(e,t){if(t.preserveOrdinarySpaces||t.preserveHardBreaks){if(e===" ")return"preserved-space";if(e===" ")return"tab";if(t.preserveHardBreaks&&e===` -`)return"hard-break"}return e===" "?"space":e===" "||e===" "||e==="⁠"||e==="\uFEFF"?"glue":e==="​"?"zero-width-break":e==="­"?"soft-hyphen":"text"}const TLe=/[\x20\t\n\xA0\xAD\u200B\u202F\u2060\uFEFF]/;function Gl(e){return e.length===1?e[0]:e.join("")}function LLe(e,t){const n=[];for(let i=e.length-1;i>=0;i--)n.push(e[i]);return n.push(t),Gl(n)}function NLe(e,t,n,i){if(!TLe.test(e))return[{text:e,isWordLike:t,kind:"text",start:n}];const o=[];let s=null,r=[],l=n,a=!1,u=0;for(const c of e){const d=ELe(c,i),h=d==="text"&&t;s===null||d!==s||h!==a?(s!==null&&o.push({text:Gl(r),isWordLike:a,kind:s,start:l}),s=d,r=[c],l=n+u,a=h,u+=c.length):(r.push(c),u+=c.length)}return s!==null&&o.push({text:Gl(r),isWordLike:a,kind:s,start:l}),o}function kk(e){return e==="space"||e==="preserved-space"||e==="zero-width-break"||e==="hard-break"}const FLe=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function DLe(e,t){const n=e.texts[t];return!!n.startsWith("www.")||FLe.test(n)&&t+1<e.len&&e.kinds[t+1]==="text"&&e.texts[t+1]==="//"}function BLe(e){return e.includes("?")&&(e.includes("://")||e.startsWith("www."))}const $Le=new Set([":","-","/","×",",",".","+","–","—"]),RLe=/[\p{P}\p{S}\p{Co}]/u,zLe=new RegExp("\\p{Emoji_Presentation}","u"),OLe=new Set(["?","֊","-","‐","‒","–","—","…","‼","‽","⁉"]);function yP(e){const t=e.charCodeAt(0);return t<128?(function(n){return n>=33&&n<=47&&n!==45||n>=58&&n<=64&&n!==63||n>=91&&n<=96||n>=123&&n<=126})(t):!OLe.has(e)&&!zLe.test(e)&&RLe.test(e)}function DE(e){let t=!1;for(const n of e)if(!Fc.test(n)){if(!yP(n))return!1;t=!0}return t}function PLe(e,t,n,i){const o=!t&&DE(e),s=!i&&DE(n),r=(function(a){const u=(function(c){for(let d=c.length;d>0;){const h=vy(c,d),p=c.slice(h,d);if(!Fc.test(p))return p;d=h}return null})(a);return u!==null&&yy(u)})(e),l=(t||r)&&(function(a){for(let u=a.length;u>0;){const c=vy(a,u),d=a.slice(c,u);if(!Fc.test(d))return yP(d)||yy(d);u=c}return!1})(e);return!!(o||s||l)&&!Ba(e)&&!Ba(n)&&(t||o||r)&&(i||s)}function BE(e){for(const t of e)if(Z7.test(t))return!0;return!1}function Hv(e){if(e.length===0)return!1;for(const t of e)if(!Z7.test(t)&&!$Le.has(t))return!1;return!0}function jLe(e,t){if(e.len===0)return[];if(!t.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}];const n=[];let i=0;for(let o=0;o<e.len;o++)e.kinds[o]==="hard-break"&&(n.push({startSegmentIndex:i,endSegmentIndex:o,consumedEndSegmentIndex:o+1}),i=o+1);return i<e.len&&n.push({startSegmentIndex:i,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}),n}function HLe(e,t,n="normal",i="normal"){const o=(function(a){const u=a??"normal";return u==="pre-wrap"?{mode:u,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:u,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}})(n),s=o.mode==="pre-wrap"?(function(a){return/[\r\f]/.test(a)?a.replace(/\r\n/g,` -`).replace(/[\r\f]/g,` -`):a})(e):(function(a){if(!hLe.test(a))return a;let u=a.replace(fLe," ");return u.charCodeAt(0)===32&&(u=u.slice(1)),u.length>0&&u.charCodeAt(u.length-1)===32&&(u=u.slice(0,-1)),u})(e);if(s.length===0)return{normalized:s,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};const r=(function(a,u,c){var d,h,p;const g=(yk===null&&(yk=new Intl.Segmenter(void 0,{granularity:"word"})),yk);let m=0;const k=[],w=[],y=[],b=[],A=[],T=[],S=[],x=[],_=[],L=[],M=[],N=[];for(const R of g.segment(a))for(const j of NLe(R.segment,(d=R.isWordLike)!=null&&d,R.index,c)){let $=function(){T[q]!==null&&(w[q]=[NE(k,T,S,q)],T[q]=null),w[q].push(j.text),y[q]=y[q]||j.isWordLike,x[q]=x[q]||Z,_[q]=_[q]||ae,L[q]=Y,M[q]=oe,N[q]=FE(_[q],V)};const W=j.kind==="text",P=_Le(j.text,j.isWordLike,j.kind),Z=Ba(j.text),ae=TE(j.text),V=o0(j.text),Y=o5(j.text),oe=MLe(j.text),q=m-1;u.carryCJKAfterClosingQuote&&W&&m>0&&b[q]==="text"&&Z&&x[q]&&L[q]||W&&m>0&&b[q]==="text"&&ALe(j.text)&&x[q]||W&&m>0&&b[q]==="text"&&M[q]?$():W&&m>0&&b[q]==="text"&&j.isWordLike&&ae&&N[q]?($(),y[q]=!0):P!==null&&m>0&&b[q]==="text"&&T[q]===P?S[q]=((h=S[q])!=null?h:1)+1:W&&!j.isWordLike&&m>0&&b[q]==="text"&&!x[q]&&(bLe(j.text)||j.text==="-"&&y[q])?$():(k[m]=j.text,w[m]=[j.text],y[m]=j.isWordLike,b[m]=j.kind,A[m]=j.start,T[m]=P,S[m]=P===null?0:1,x[m]=Z,_[m]=ae,L[m]=Y,M[m]=oe,N[m]=FE(ae,V),m++)}for(let R=0;R<m;R++)T[R]===null?k[R]=Gl(w[R]):k[R]=NE(k,T,S,R);for(let R=1;R<m;R++)b[R]!=="text"||y[R]||!Y7(k[R])||b[R-1]!=="text"||x[R-1]||(k[R-1]+=k[R],y[R-1]=y[R-1]||y[R],k[R]="");const I=Array.from({length:m},()=>null);let z=-1;for(let R=m-1;R>=0;R--){const j=k[R];if(j.length!==0){if(b[R]==="text"&&!y[R]&&z>=0&&b[z]==="text"&&(CLe(j)||j==="-"&&xLe(k[z]))){const $=(p=I[z])!=null?p:[];$.push(j),I[z]=$,A[z]=A[R],k[R]="";continue}z=R}}for(let R=0;R<m;R++){const j=I[R];j!=null&&(k[R]=LLe(j,k[R]))}let H=0;for(let R=0;R<m;R++){const j=k[R];j.length!==0&&(H!==R&&(k[H]=j,y[H]=y[R],b[H]=b[R],A[H]=A[R]),H++)}k.length=H,y.length=H,b.length=H,A.length=H;const O=(function(R){const j=R.texts.slice(),$=R.isWordLike.slice(),W=R.kinds.slice(),P=R.starts.slice();for(let Z=0;Z<j.length-1;Z++){if(W[Z]!=="text"||W[Z+1]!=="text"||!Ba(j[Z])||!Ba(j[Z+1]))continue;const ae=SLe(j[Z]);ae!==null&&(j[Z]=ae.head,j[Z+1]=ae.tail+j[Z+1],P[Z+1]=P[Z]+ae.head.length)}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=[],$=[],W=[],P=[];let Z=0;for(;Z<R.len;){const ae=R.texts[Z],V=R.kinds[Z],Y=R.isWordLike[Z];if(V==="text"){const oe=[ae];let q=Z+1,ne=Y;for(;q<R.len&&R.kinds[q]==="text"&&PLe(R.texts[q-1],R.isWordLike[q-1],R.texts[q],R.isWordLike[q]);){const ie=R.texts[q];oe.push(ie),ne=ne||R.isWordLike[q],q++}if(q>Z+1){j.push(Gl(oe)),$.push(ne),W.push("text"),P.push(R.starts[Z]),Z=q;continue}}j.push(ae),$.push(Y),W.push(V),P.push(R.starts[Z]),Z++}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=[],$=[],W=[],P=[];for(let Z=0;Z<R.len;Z++){const ae=R.texts[Z];if(R.kinds[Z]==="text"&&ae.includes("-")){const V=ae.split("-");let Y=V.length>1;for(let oe=0;oe<V.length;oe++){const q=V[oe];if(!Y)break;q.length!==0&&BE(q)&&Hv(q)||(Y=!1)}if(Y){let oe=0;for(let q=0;q<V.length;q++){const ne=V[q],ie=q<V.length-1?`${ne}-`:ne;j.push(ie),$.push(!0),W.push("text"),P.push(R.starts[Z]+oe),oe+=ie.length}continue}}j.push(ae),$.push(R.isWordLike[Z]),W.push(R.kinds[Z]),P.push(R.starts[Z])}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=[],$=[],W=[],P=[];for(let Z=0;Z<R.len;Z++){const ae=R.texts[Z],V=R.kinds[Z];if(V==="text"&&Hv(ae)&&BE(ae)){const Y=[ae];let oe=Z+1;for(;oe<R.len&&R.kinds[oe]==="text"&&Hv(R.texts[oe]);)Y.push(R.texts[oe]),oe++;j.push(Gl(Y)),$.push(!0),W.push("text"),P.push(R.starts[Z]),Z=oe-1;continue}j.push(ae),$.push(R.isWordLike[Z]),W.push(V),P.push(R.starts[Z])}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=[],$=[],W=[],P=[];for(let Z=0;Z<R.len;Z++){const ae=R.texts[Z];if(j.push(ae),$.push(R.isWordLike[Z]),W.push(R.kinds[Z]),P.push(R.starts[Z]),!BLe(ae))continue;const V=Z+1;if(V>=R.len||kk(R.kinds[V]))continue;const Y=[],oe=R.starts[V];let q=V;for(;q<R.len&&!kk(R.kinds[q]);)Y.push(R.texts[q]),q++;Y.length>0&&(j.push(Gl(Y)),$.push(!0),W.push("text"),P.push(oe),Z=q-1)}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=R.texts.slice(),$=R.isWordLike.slice(),W=R.kinds.slice(),P=R.starts.slice();for(let ae=0;ae<R.len;ae++){if(W[ae]!=="text"||!DLe(R,ae))continue;const V=[j[ae]];let Y=ae+1;for(;Y<R.len&&!kk(W[Y]);){V.push(j[Y]),$[ae]=!0;const oe=j[Y].includes("?");if(W[Y]="text",j[Y]="",Y++,oe)break}j[ae]=Gl(V)}let Z=0;for(let ae=0;ae<j.length;ae++){const V=j[ae];V.length!==0&&(Z!==ae&&(j[Z]=V,$[Z]=$[ae],W[Z]=W[ae],P[Z]=P[ae]),Z++)}return j.length=Z,$.length=Z,W.length=Z,P.length=Z,{len:Z,texts:j,isWordLike:$,kinds:W,starts:P}})((function(R){const j=[],$=[],W=[],P=[];let Z=0;for(;Z<R.len;){const ae=[R.texts[Z]];let V=R.isWordLike[Z],Y=R.kinds[Z],oe=R.starts[Z];if(Y==="glue"){const q=[ae[0]],ne=oe;for(Z++;Z<R.len&&R.kinds[Z]==="glue";)q.push(R.texts[Z]),Z++;const ie=Gl(q);if(!(Z<R.len&&R.kinds[Z]==="text")){j.push(ie),$.push(!1),W.push("glue"),P.push(ne);continue}ae[0]=ie,ae.push(R.texts[Z]),V=R.isWordLike[Z],Y="text",oe=ne,Z++}else Z++;if(Y==="text")for(;Z<R.len&&R.kinds[Z]==="glue";){const q=[];for(;Z<R.len&&R.kinds[Z]==="glue";)q.push(R.texts[Z]),Z++;const ne=Gl(q);Z<R.len&&R.kinds[Z]==="text"?(ae.push(ne,R.texts[Z]),V=V||R.isWordLike[Z],Z++):ae.push(ne)}j.push(Gl(ae)),$.push(V),W.push(Y),P.push(oe)}return{len:j.length,texts:j,isWordLike:$,kinds:W,starts:P}})({len:H,texts:k,isWordLike:y,kinds:b,starts:A})))))));for(let R=0;R<O.len-1;R++){const j=ILe(O.texts[R]);j!==null&&(O.kinds[R]!=="space"&&O.kinds[R]!=="preserved-space"||O.kinds[R+1]!=="text"||!TE(O.texts[R+1])||(O.texts[R]=j.space,O.isWordLike[R]=!1,O.kinds[R]=O.kinds[R]==="preserved-space"?"preserved-space":"space",O.texts[R+1]=j.marks+O.texts[R+1],O.starts[R+1]=O.starts[R]+j.space.length))}return O})(s,t,o),l=i==="keep-all"?(function(a,u,c){if(u.len<=1)return u;const d=[],h=[],p=[],g=[];let m=-1,k=!1;function w(b){d.push(u.texts[b]),h.push(u.isWordLike[b]),p.push("text"),g.push(u.starts[b])}function y(b){if(!(m<0)){if(k)m+1===b?w(m):(function(A,T){let S=!1;for(let L=A;L<T;L++)S=S||u.isWordLike[L];const x=u.starts[A],_=T<u.len?u.starts[T]:a.length;d.push(a.slice(x,_)),h.push(S),p.push("text"),g.push(x)})(m,b);else for(let A=m;A<b;A++)w(A);m=-1,k=!1}}for(let b=0;b<u.len;b++){const A=u.texts[b],T=u.kinds[b];T!=="text"?(y(b),d.push(A),h.push(u.isWordLike[b]),p.push(T),g.push(u.starts[b])):(m>=0&&!vP(u.texts[b-1],c)&&y(b),m<0&&(m=b),k=k||Ba(A))}return y(u.len),{len:d.length,texts:d,isWordLike:h,kinds:p,starts:g}})(s,r,t.breakKeepAllAfterPunctuation):r;return Mt({normalized:s,chunks:jLe(l,o)},l)}let Qf=null;const $E=new Map;let Yf=null;const WLe=new RegExp("\\p{Emoji_Presentation}","u"),qLe=/[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}\uFE0F\u20E3]/u;let bk=null;const RE=new Map;function s5(){if(Qf!==null)return Qf;if(typeof OffscreenCanvas<"u")return Qf=new OffscreenCanvas(1,1).getContext("2d"),Qf;if(typeof document<"u")return Qf=document.createElement("canvas").getContext("2d"),Qf;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function Zu(e,t){let n=t.get(e);return n===void 0&&(n={width:s5().measureText(e).width,containsCJK:Ba(e)},t.set(e,n)),n}function ky(){if(Yf!==null)return Yf;if(typeof navigator>"u")return Yf={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,breakKeepAllAfterPunctuation:!0,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},Yf;const e=navigator.userAgent,t=navigator.vendor==="Apple Computer, Inc."&&e.includes("Safari/")&&!e.includes("Chrome/")&&!e.includes("Chromium/")&&!e.includes("CriOS/")&&!e.includes("FxiOS/")&&!e.includes("EdgiOS/"),n=e.includes("Chrome/")||e.includes("Chromium/")||e.includes("CriOS/")||e.includes("Edg/");return Yf={lineFitEpsilon:t?1/64:.005,carryCJKAfterClosingQuote:n,breakKeepAllAfterPunctuation:!t,preferPrefixWidthsForBreakableRuns:t,preferEarlySoftHyphenBreak:t},Yf}function kP(){return bk===null&&(bk=new Intl.Segmenter(void 0,{granularity:"grapheme"})),bk}function ULe(e){return WLe.test(e)||e.includes("️")}function kd(e,t,n){return n===0?t.width:t.width-(function(i,o){return o.emojiCount===void 0&&(o.emojiCount=(function(s){let r=0;const l=kP();for(const a of l.segment(s))ULe(a.segment)&&r++;return r})(i)),o.emojiCount})(e,t)*n}function KLe(e){return e==="space"||e==="zero-width-break"||e==="soft-hyphen"}function zE(e){return e==="space"||e==="preserved-space"||e==="tab"||e==="zero-width-break"||e==="soft-hyphen"}function OE(e,t,n=e.widths.length){for(;t<n&&KLe(e.kinds[t]);)t++;return t}function VLe(e,t){if(t<=0)return 0;const n=e%t;return Math.abs(n)<=1e-6?t:t-n}function ZLe(e,t,n){return e.letterSpacing!==0&&t&&e.spacingGraphemeCounts[n]>0?e.letterSpacing:0}function J7(e,t){return t===0?0:e+t}function GLe(e,t,n,i,o){return J7(i,t==="tab"?o+(function(s,r){return s.letterSpacing!==0&&s.spacingGraphemeCounts[r]>0?s.letterSpacing:0})(e,n):e.lineEndFitAdvances[n])}function PE(e,t,n,i){return J7(i,t==="tab"?0:e.lineEndFitAdvances[n])}function jE(e,t,n,i,o){return J7(i,t==="tab"?o:e.lineEndPaintAdvances[n])}function QLe(e,t,n){return e.letterSpacing!==0&&t?n+e.letterSpacing:n}function YLe(e,t){return e.letterSpacing===0?t:t+e.letterSpacing}function Xm(e,t,n){let i=t;for(;i<e.length&&e[i]<n;)i++;return i}function JLe(e,t){return(function(n,i){if(n.simpleLineWalkFastPath)return(function(I,z){const{widths:H,kinds:O,breakableFitAdvances:R,breakablePreferredBreaks:j}=I;if(H.length===0)return 0;const $=z+ky().lineFitEpsilon;let W=0,P=0,Z=!1,ae=0,V=0,Y=-1,oe=0;function q(be=ae,Q=V,ue=P){W++,P=0,Z=!1,Y=-1,oe=0}function ne(be,Q){Z=!0,ae=be+1,V=0,P=Q}function ie(be,Q,ue){Z=!0,ae=be,V=Q+1,P=ue}function pe(be,Q){Z?(P+=Q,ae=be+1,V=0):ne(be,Q)}function Ne(be,Q){var ue;const Ae=R[be],se=(ue=j[be])!=null?ue:null;let re=se===null?-1:Xm(se,0,Q+1),G=-1,le=0,ge=Q;for(;ge<Ae.length;){const ke=Ae[ge];if(Z)if(P+ke>$){if(se!==null&&G>Q){q(be,G,le),ge=G,re=Xm(se,re,ge+1),G=-1,le=0;continue}q(),ie(be,ge,ke)}else P+=ke,ae=be,V=ge+1;else ie(be,ge,ke);const Ie=ge+1;se!==null&&se[re]===Ie&&(G=Ie,le=P,re++),ge++}Z&&ae===be&&V===Ae.length&&(ae=be+1,V=0)}let te=0;for(;te<H.length&&(Z||(te=OE(I,te),!(te>=H.length)));){const be=H[te],Q=zE(O[te]);if(Z)if(P+be>$){if(Q){pe(te,be),q(te+1,0,P-be),te++;continue}if(Y>=0){if(ae>Y||ae===Y&&V>0){q();continue}q(Y,0,oe);continue}if(be>$&&R[te]!==null){q(),Ne(te,0),te++;continue}q()}else pe(te,be),Q&&(Y=te+1,oe=P-be),te++;else be>$&&R[te]!==null?Ne(te,0):ne(te,be),Q&&(Y=te+1,oe=P-be),te++}return Z&&q(),W})(n,i);const{widths:o,kinds:s,breakableFitAdvances:r,breakablePreferredBreaks:l,discretionaryHyphenWidth:a,chunks:u}=n;if(o.length===0||u.length===0)return 0;const c=ky(),d=i+c.lineFitEpsilon;let h=0,p=0,g=!1,m=0,k=0,w=-1,y=0,b=null;function A(){w=-1,y=0,b=null}function T(I=m,z=k,H){h++,p=0,g=!1,A()}function S(I,z){g=!0,m=I+1,k=0,p=z}function x(I,z,H){g=!0,m=I,k=z+1,p=H}function _(I,z){g?(p+=z,m=I+1,k=0):S(I,z)}function L(I,z,H,O,R,j){if(!z)return;const $=PE(n,I,H,R);jE(n,I,H,R,O),w=H+1,y=p-j+$,b=I}function M(I,z){var H;const O=r[I],R=(H=l[I])!=null?H:null;let j=R===null?-1:Xm(R,0,z+1),$=-1,W=z;for(;W<O.length;){const P=O[W];if(g){const ae=QLe(n,!0,P),V=p+ae;if(YLe(n,V)>d){if(R!==null&&$>z){T(I,$),W=$,j=Xm(R,j,W+1),$=-1;continue}T(),x(I,W,P)}else p=V,m=I,k=W+1}else x(I,W,P);const Z=W+1;R!==null&&R[j]===Z&&($=Z,j++),W++}g&&m===I&&k===O.length&&(m=I+1,k=0)}function N(I){h++,A()}for(let I=0;I<u.length;I++){const z=u[I];if(z.startSegmentIndex===z.endSegmentIndex){N();continue}g=!1,p=0,z.startSegmentIndex,m=z.startSegmentIndex,k=0,A();let H=z.startSegmentIndex;for(;H<z.endSegmentIndex&&(g||(H=OE(n,H,z.endSegmentIndex),!(H>=z.endSegmentIndex)));){const O=s[H],R=zE(O),j=ZLe(n,g,H),$=O==="tab"?VLe(p+j,n.tabStopAdvance):o[H],W=j+$,P=GLe(n,O,H,j,$);if(O!=="soft-hyphen")if(g){if(p+P>d){const Z=p+PE(n,O,H,j);if(jE(n,O,H,j,$),b==="soft-hyphen"&&c.preferEarlySoftHyphenBreak&&y<=d){T(w,0);continue}if(R&&Z<=d){_(H,W),T(H+1,0),H++;continue}if(w>=0&&y<=d){if(m>w||m===w&&k>0){T();continue}const ae=w;T(ae,0),H=ae;continue}if(P>d&&r[H]!==null){T(),M(H,0),H++;continue}T();continue}_(H,W),L(O,R,H,$,j,W),H++}else P>d&&r[H]!==null?M(H,0):S(H,$),L(O,R,H,$,j,W),H++;else g&&(m=H+1,k=0,w=H+1,y=p+a,b=O),H++}g&&(z.consumedEndSegmentIndex,T(z.consumedEndSegmentIndex,0))}return h})(e,t)}let Ak=null;function X7(){return Ak===null&&(Ak=new Intl.Segmenter(void 0,{granularity:"grapheme"})),Ak}function XLe(e,t){const n=[];let i=[],o=0,s=!1,r=!1,l=!1;function a(){i.length!==0&&(n.push({text:i.length===1?i[0]:i.join(""),start:o}),i=[],s=!1,r=!1,l=!1)}function u(d,h,p){i=[d],o=h,s=p,r=o5(d),l=$9.has(d)}function c(d,h){i.push(d),s=s||h;const p=o5(d);r=d.length===1&&pf.has(d)&&r||p,l=!1}for(const d of X7().segment(e)){const h=d.segment,p=Ba(h);i.length!==0?l||G7.has(h)||pf.has(h)||t.carryCJKAfterClosingQuote&&p&&r?c(h,p):s||p?(a(),u(h,d.index,p)):c(h,p):u(h,d.index,p)}return a(),n}function eNe(e,t,n){if(t.length<=1)return t;const i=[];let o=-1,s=!1;function r(l){if(!(o<0)){if(s)o+1===l?i.push(t[o]):(function(a,u){const c=t[a].start,d=u<t.length?t[u].start:e.length;i.push({text:e.slice(c,d),start:c})})(o,l);else for(let a=o;a<l;a++)i.push(t[a]);o=-1,s=!1}}for(let l=0;l<t.length;l++){const a=t[l];o>=0&&!vP(t[l-1].text,n)&&r(l),o<0&&(o=l),s=s||Ba(a.text)}return r(t.length),i}function HE(e,t){if(t==="zero-width-break"||t==="soft-hyphen"||t==="hard-break")return 0;if(t==="tab")return 1;let n=0;const i=X7();for(const o of i.segment(e))n++;return n}function tNe(e){return e==="-"||e==="֊"||e==="‐"||e==="‒"||e==="–"||e==="—"}function nNe(e,t,n,i,o){const s=ky(),{cache:r,emojiCorrection:l}=(function(N,I){s5().font=N;const z=(function(R){let j=$E.get(R);return j||(j=new Map,$E.set(R,j)),j})(N),H=(function(R){const j=R.match(/(\d+(?:\.\d+)?)\s*px/);return j?parseFloat(j[1]):16})(N),O=I?(function(R,j){let $=RE.get(R);if($!==void 0)return $;const W=s5();W.font=R;const P=W.measureText("😀").width;if($=0,P>j+.5&&typeof document<"u"&&document.body!==null){const Z=document.createElement("span");Z.style.font=R,Z.style.display="inline-block",Z.style.visibility="hidden",Z.style.position="absolute",Z.textContent="😀",document.body.appendChild(Z);const ae=Z.getBoundingClientRect().width;document.body.removeChild(Z),P-ae>.5&&($=P-ae)}return RE.set(R,$),$})(N,H):0;return{cache:z,fontSize:H,emojiCorrection:O}})(t,(a=e.normalized,qLe.test(a)));var a;const u=kd("-",Zu("-",r),l)+(o===0?0:2*o),c=8*kd(" ",Zu(" ",r),l),d=o!==0;if(e.len===0)return{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],breakablePreferredBreaks:[],letterSpacing:0,spacingGraphemeCounts:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[]};const h=[],p=[],g=[],m=[];let k=e.chunks.length<=1&&!d;const w=null,y=[],b=[],A=[],T=null,S=Array.from({length:e.len});function x(N,I,z,H,O,R,j,$,W){O!=="text"&&O!=="space"&&O!=="zero-width-break"&&(k=!1),h.push(I),p.push(z),g.push(H),m.push(O),y.push(j),b.push($),d&&A.push(W)}function _(N,I,z,H,O){const R=Zu(N,r),j=d?HE(N,I):0,$=(function(ae,V,Y){return V>1?ae+(V-1)*Y:ae})(kd(N,R,l),j,o),W=I==="space"||I==="preserved-space"||I==="zero-width-break"?0:$,P=W===0?0:W+(j>0?o:0),Z=I==="space"||I==="zero-width-break"?0:$;if(O&&H&&N.length>1){let ae="sum-graphemes";o!==0?ae="segment-prefixes":Hv(N)?ae="pair-context":s.preferPrefixWidthsForBreakableRuns&&(ae="segment-prefixes");const V=(function(oe,q,ne,ie,pe){if(q.breakableFitAdvances!==void 0&&q.breakableFitMode===pe)return q.breakableFitAdvances;q.breakableFitMode=pe;const Ne=kP(),te=[];for(const Ae of Ne.segment(oe))te.push(Ae.segment);if(te.length<=1)return q.breakableFitAdvances=null,q.breakableFitAdvances;if(pe==="sum-graphemes"){const Ae=[];for(const se of te){const re=Zu(se,ne);Ae.push(kd(se,re,ie))}return q.breakableFitAdvances=Ae,q.breakableFitAdvances}if(pe==="pair-context"||te.length>96){const Ae=[];let se=null,re=0;for(const G of te){const le=kd(G,Zu(G,ne),ie);if(se===null)Ae.push(le);else{const ge=se+G,ke=Zu(ge,ne);Ae.push(kd(ge,ke,ie)-re)}se=G,re=le}return q.breakableFitAdvances=Ae,q.breakableFitAdvances}const be=[];let Q="",ue=0;for(const Ae of te){Q+=Ae;const se=kd(Q,Zu(Q,ne),ie);be.push(se-ue),ue=se}return q.breakableFitAdvances=be,q.breakableFitAdvances})(N,R,r,l,ae),Y=V===null||i==="keep-all"?null:(function(oe){if(!/[-\u058A\u2010\u2012\u2013\u2014]/u.test(oe))return null;const q=[];let ne=0;for(const ie of X7().segment(oe))ne++,tNe(ie.segment)&&q.push(ne);return q.length===0?null:q})(N);return void x(N,$,P,Z,I,z,V,Y,j)}x(N,$,P,Z,I,z,null,null,j)}for(let N=0;N<e.len;N++){S[N]=h.length;const I=e.texts[N],z=e.isWordLike[N],H=e.kinds[N],O=e.starts[N];if(H==="soft-hyphen"){x(I,0,u,u,H,O,null,null,0);continue}if(H==="hard-break"){x(I,0,0,0,H,O,null,null,0);continue}if(H==="tab"){x(I,0,0,0,H,O,null,null,d?HE(I,H):0);continue}const R=Zu(I,r);if(H==="text"&&R.containsCJK){const j=XLe(I,s),$=i==="keep-all"?eNe(I,j,s.breakKeepAllAfterPunctuation):j;for(let W=0;W<$.length;W++){const P=$[W];_(P.text,"text",O+P.start,z,i==="keep-all"||!Ba(P.text))}continue}_(I,H,O,z,!0)}const L=(function(N,I,z){const H=[];for(let O=0;O<N.length;O++){const R=N[O],j=R.startSegmentIndex<I.length?I[R.startSegmentIndex]:z,$=R.endSegmentIndex<I.length?I[R.endSegmentIndex]:z,W=R.consumedEndSegmentIndex<I.length?I[R.consumedEndSegmentIndex]:z;H.push({startSegmentIndex:j,endSegmentIndex:$,consumedEndSegmentIndex:W})}return H})(e.chunks,S,h.length),M=w===null?null:(function(N,I){const z=(function(O){const R=O.length;if(R===0)return null;const j=new Array(R);let $=!1;for(let Y=0;Y<R;){const oe=O.charCodeAt(Y);let q=oe,ne=1;if(oe>=55296&&oe<=56319&&Y+1<R){const pe=O.charCodeAt(Y+1);pe>=56320&&pe<=57343&&(q=pe-56320+(oe-55296<<10)+65536,ne=2)}const ie=dLe(q);ie!=="R"&&ie!=="AL"&&ie!=="AN"||($=!0);for(let pe=0;pe<ne;pe++)j[Y+pe]=ie;Y+=ne}if(!$)return null;let W=0;for(let Y=0;Y<R;Y++){const oe=j[Y];if(oe==="L"){W=0;break}if(oe==="R"||oe==="AL"){W=1;break}}const P=new Int8Array(R);for(let Y=0;Y<R;Y++)P[Y]=W;const Z=1&W?"R":"L",ae=Z;let V=ae;for(let Y=0;Y<R;Y++)j[Y]==="NSM"?j[Y]=V:V=j[Y];V=ae;for(let Y=0;Y<R;Y++){const oe=j[Y];oe==="EN"?j[Y]=V==="AL"?"AN":"EN":oe!=="R"&&oe!=="L"&&oe!=="AL"||(V=oe)}for(let Y=0;Y<R;Y++)j[Y]==="AL"&&(j[Y]="R");for(let Y=1;Y<R-1;Y++)j[Y]==="ES"&&j[Y-1]==="EN"&&j[Y+1]==="EN"&&(j[Y]="EN"),j[Y]!=="CS"||j[Y-1]!=="EN"&&j[Y-1]!=="AN"||j[Y+1]!==j[Y-1]||(j[Y]=j[Y-1]);for(let Y=0;Y<R;Y++){if(j[Y]!=="EN")continue;let oe;for(oe=Y-1;oe>=0&&j[oe]==="ET";oe--)j[oe]="EN";for(oe=Y+1;oe<R&&j[oe]==="ET";oe++)j[oe]="EN"}for(let Y=0;Y<R;Y++){const oe=j[Y];oe!=="WS"&&oe!=="ES"&&oe!=="ET"&&oe!=="CS"||(j[Y]="ON")}V=ae;for(let Y=0;Y<R;Y++){const oe=j[Y];oe==="EN"?j[Y]=V==="L"?"L":"EN":oe!=="R"&&oe!=="L"||(V=oe)}for(let Y=0;Y<R;Y++){if(j[Y]!=="ON")continue;let oe=Y+1;for(;oe<R&&j[oe]==="ON";)oe++;const q=(Y>0?j[Y-1]:ae)!=="L"?"R":"L";if(q===((oe<R?j[oe]:ae)!=="L"?"R":"L"))for(let ne=Y;ne<oe;ne++)j[ne]=q;Y=oe-1}for(let Y=0;Y<R;Y++)j[Y]==="ON"&&(j[Y]=Z);for(let Y=0;Y<R;Y++){const oe=j[Y];1&P[Y]?oe!=="L"&&oe!=="AN"&&oe!=="EN"||P[Y]++:oe==="R"?P[Y]++:oe!=="AN"&&oe!=="EN"||(P[Y]+=2)}return P})(N);if(z===null)return null;const H=new Int8Array(I.length);for(let O=0;O<I.length;O++)H[O]=z[I[O]];return H})(e.normalized,w);return T!==null?{widths:h,lineEndFitAdvances:p,lineEndPaintAdvances:g,kinds:m,simpleLineWalkFastPath:k,segLevels:M,breakableFitAdvances:y,breakablePreferredBreaks:b,letterSpacing:o,spacingGraphemeCounts:A,discretionaryHyphenWidth:u,tabStopAdvance:c,chunks:L,segments:T}:{widths:h,lineEndFitAdvances:p,lineEndPaintAdvances:g,kinds:m,simpleLineWalkFastPath:k,segLevels:M,breakableFitAdvances:y,breakablePreferredBreaks:b,letterSpacing:o,spacingGraphemeCounts:A,discretionaryHyphenWidth:u,tabStopAdvance:c,chunks:L}}const Ck="__MARKSTREAM_VUE_HEIGHT_ESTIMATION_EXPERIMENT__",iNe=["diff ","index ","--- ","+++ ","@@ "],cs=(()=>{const e=globalThis;if(e[Ck])return e[Ck];const t={configs:{},controllers:{},revision:ha(0),preparedCache:new Map,blockEstimateCache:new Map};return e[Ck]=t,t})();let Y1=null;const wk=cs.revision;function WE(e){var t;return e&&(t=cs.configs[e])!=null?t:null}function qE(e,t){const n=Number.parseFloat(String(e??""));return Number.isFinite(n)&&n>0?n:t}function oNe(e){return e?.type==="text"||e?.type==="emoji"||e?.type==="hardbreak"}function xk(e){var t,n,i;if(!Array.isArray(e)||e.length===0)return null;let o="";for(const s of e){if(!oNe(s))return null;s.type==="text"?o+=String((t=s.content)!=null?t:""):s.type==="emoji"?o+=String((i=(n=s.name)!=null?n:s.raw)!=null?i:""):s.type==="hardbreak"&&(o+=` -`)}return o.length>0?o:null}function Sk(e,t,n){var i,o;if(!e||!Number.isFinite(t)||t<=0||!(function(){var s;if(Y1!=null)return Y1;if(typeof document>"u")return!1;try{const r=document.createElement("canvas");return Y1=!!((s=r.getContext)!=null&&s.call(r,"2d")),Y1}catch{return Y1=!1,!1}})())return null;try{const s=Math.round(100*t)/100,r=[(i=n.whiteSpace)!=null?i:"pre-wrap",n.font,n.lineHeight,n.wrapperOverhead,n.widthAdjustment,s,e].join("\0"),l=cs.blockEstimateCache.get(r);if(l)return cs.blockEstimateCache.delete(r),cs.blockEstimateCache.set(r,l),{kind:"simple-text",height:l.height,contentHeight:l.contentHeight};const a=(o=n.whiteSpace)!=null?o:"pre-wrap",u=(function(p,g,m){const k=`${m}\0${g}\0${p}`,w=cs.preparedCache.get(k);if(w)return cs.preparedCache.delete(k),cs.preparedCache.set(k,w),w.prepared;const y=(function(b,A,T){return(function(S,x,_,L){var M,N;const I=(M=L?.wordBreak)!=null?M:"normal",z=(N=L?.letterSpacing)!=null?N:0;return nNe(HLe(S,ky(),L?.whiteSpace,I),x,!1,I,z)})(b,A,0,T)})(p,g,{whiteSpace:m});for(cs.preparedCache.set(k,{prepared:y});cs.preparedCache.size>240;){const b=cs.preparedCache.keys().next().value;if(!b)break;cs.preparedCache.delete(b)}return y})(e,n.font,a),c=(function(p,g,m){const k=JLe(p,g);return{lineCount:k,height:k*m}})(u,Math.max(24,s-n.widthAdjustment),n.lineHeight),d=Math.max(n.lineHeight,c.height),h=Math.max(n.lineHeight,Math.round(d+n.wrapperOverhead));for(cs.blockEstimateCache.set(r,{height:h,contentHeight:Math.round(d)});cs.blockEstimateCache.size>4e3;){const p=cs.blockEstimateCache.keys().next().value;if(!p)break;cs.blockEstimateCache.delete(p)}return{kind:"simple-text",height:h,contentHeight:Math.round(d)}}catch{return null}}function bP(e,t,n){var i,o;if(!n||!e||!Number.isFinite(t)||t<=0)return null;if(e.type==="paragraph"){const s=xk(e.children);return s&&n.paragraph?Sk(s,t,n.paragraph):null}if(e.type==="heading"){const s=Number(e.level||0),r=xk(e.children),l=n.headings[s];return r&&l?Sk(r,t,l):null}if(e.type==="list_item"){const s=Array.isArray(e.children)?e.children:[];if(s.length!==1||((i=s[0])==null?void 0:i.type)!=="paragraph"||!n.listItem)return null;const r=xk((o=s[0])==null?void 0:o.children);return r?Sk(r,t,n.listItem):null}if(e.type==="list"){const s=Array.isArray(e.items)?e.items:[];if(!s.length)return null;let r=Math.max(0,n.listWrapperOverhead);for(const l of s){const a=bP(l,t,n);if(!a)return null;r+=a.height}return{kind:"simple-text",height:Math.max(1,Math.round(r)),contentHeight:Math.max(1,Math.round(r))}}return null}function J1(e){if(!e)return 1;const t=String(e).split(/\r?\n/);return Math.max(1,t.length)}function bd(e,t){const n=String(e??"");return t?n:n.replace(/\r\n$|\n$|\r$/,"")}function _k(e,t,n=0){return e.diff?V7(t??{},n)?(function(i){const o=bd(i.raw);if(o){const s=o.split(/\r?\n/);return i.originalCode!=null||i.updatedCode!=null?Math.max(1,s.filter(r=>!iNe.some(l=>r.startsWith(l))).length):Math.max(1,s.length)}return J1(bd(i.originalCode))+J1(bd(i.updatedCode))})(e):(function(i){const o=i.originalCode,s=i.updatedCode;if(o!=null||s!=null)return Math.max(J1(bd(o)),J1(bd(s)));const r=bd(i.code).split(/\r?\n/);let l=0,a=0;for(const u of r)u.startsWith("+")&&!u.startsWith("+++")?a++:u.startsWith("-")&&!u.startsWith("---")?l++:(l++,a++);return Math.max(1,l,a)})(e):J1(bd(e.code,e.loading===!0))}function sNe(e){return e?`${e.fontStyle||"normal"} ${e.fontWeight||"400"} ${e.fontSize||"16px"} ${e.fontFamily||"sans-serif"}`:""}function Mk(e,t,n="pre-wrap"){if(!e||!t||typeof window>"u")return null;const i=window.getComputedStyle(t),o=e.offsetHeight,s=qE(i.lineHeight,1.5*qE(i.fontSize,16)),r=e.getBoundingClientRect().width,l=t.getBoundingClientRect().width;return{font:sNe(i),lineHeight:s,wrapperOverhead:Math.max(0,o-s),widthAdjustment:Math.max(0,r-l),whiteSpace:n}}const rNe=new Set(["node","key","ref","ctx","renderNode","indexKey","__proto__","prototype","constructor"]);function UE(e,t={}){var n;const i={},o=new Set((n=t.omit)!=null?n:[]);if(!e||typeof e!="object")return i;const s=Object.getOwnPropertyDescriptors(e);for(const[r,l]of Object.entries(s))rNe.has(r)||o.has(r)||l.enumerable&&"value"in l&&(i[r]=l.value);return i}function KE(e,t,n,i){var o;const s=(function(h){return Math.max(0,Math.ceil(h.scrollHeight||0)-Math.ceil(h.clientHeight||0))})(e),r=(function(h,p){return Number.isFinite(h)?Math.min(Math.max(0,h),p):0})(n,s);if(!i.isReverseFlexScrollRoot(e))return void(e.scrollTop=r);const l=Math.max(0,s-r),a=[-l,l];let u=a[0],c=Number.POSITIVE_INFINITY;for(const h of a){e.scrollTop=h;const p=i.getNormalizedScrollTop(e,t,!1),g=Math.abs(p-r);g<c&&(c=g,u=h)}e.scrollTop=u;const d=(o=i.epsilonPx)!=null?o:2;Math.abs(i.getNormalizedScrollTop(e,t,!1)-r)>d&&(e.scrollTop=u)}function VE(e,t){let n=0,i=null,o=null;const s=()=>{const r=o;o=null,i=null,r&&(n=Date.now(),e(...r))};return function(...r){const l=Date.now(),a=t-(l-n);o=r,a<=0?(i&&(clearTimeout(i),i=null),n=l,o=null,e(...r)):i||(i=setTimeout(s,a))}}function ZE(e){return e==="simple"?"simple":e===!0||e==="true"||e==="precise"?"precise":"off"}const AP=Symbol("MarkstreamMathBlockMinHeightCache");function Sct(){return hn(AP,null)}const lNe=new Set(["text","inline_code","emoji","footnote_reference"]),aNe=new Set(["strong","emphasis","strikethrough","highlight","insert","subscript","superscript","link"]);function X1(e){const t=Number(e);return!Number.isFinite(t)||t<=0?-1:Math.round(t/32)}function Ad(e,t,n,i=22){const o=String(e??"");if(!o)return n;const s=Math.max(18,Math.floor(Math.max(320,t)/8)),r=o.split(/\r?\n/).length,l=Math.ceil(o.length/s),a=Math.max(1,r,l);return Math.max(n,Math.ceil(a*i+12))}function CP(e){var t;if(!e||typeof e!="object")return!1;const n=e,i=String((t=n.type)!=null?t:"");if(lNe.has(i))return!0;if(!aNe.has(i))return!1;const o=n.children;return!Array.isArray(o)||!o.length||o.every(CP)}function r5(e){var t,n,i,o,s,r,l,a;if(!e||typeof e!="object")return"";const u=e,c=String((t=u.type)!=null?t:"");if(c==="text")return String((i=(n=u.content)!=null?n:u.raw)!=null?i:"");if(c==="inline_code")return String((r=(s=(o=u.code)!=null?o:u.content)!=null?s:u.raw)!=null?r:"");if(c==="emoji")return String((a=(l=u.name)!=null?l:u.raw)!=null?a:"");if(typeof u.text=="string")return u.text;const d=[];for(const h of["children","items","cells","rows"]){const p=u[h];if(Array.isArray(p)){const g=p.map(r5).filter(Boolean).join(" ");g&&d.push(g)}}return d.join(" ").replace(/\s+/g," ").trim()}function wP(e){if(!e||typeof e!="object")return!1;const t=e;return t.type==="inline_code"||["children","items","cells","rows"].some(n=>{const i=t[n];return Array.isArray(i)&&i.some(wP)})}function uNe(e,t){if(!e)return 30;const n=Math.max(18,Math.floor(Math.max(320,t)/8)),i=e.split(/\r?\n/).length,o=Math.ceil(e.length/n),s=Math.max(1,i,o);return 30+26*Math.max(0,s-1)}function cNe(e,t){var n,i,o,s,r,l,a,u,c,d,h,p,g,m;if(!e||typeof e!="object")return 32;const k=e,w=String((n=k.type)!=null?n:""),y=Number.isFinite(t)&&t>0?t:640;switch(w){case"heading":return(function(b){var A;const T=Number((A=b.level)!=null?A:b.depth);return T>=4?20:T===3?30:T===2?32:44})(k);case"paragraph":return(function(b,A){const T=String(b??"");if(!T)return 28;const S=Math.max(18,Math.floor(Math.max(320,A)/8)),x=T.split(/\r?\n/).length,_=Math.ceil(T.length/S);return Math.max(1,x,_)<=1?28:Ad(T,A,34)})(String((o=(i=k.raw)!=null?i:k.content)!=null?o:""),y);case"list":return(function(b,A){var T;const S=Array.isArray(b.items)?b.items:[];if(!S.length)return 48;const x=Math.max(48,30*S.length+12);let _=12;for(const N of S)_+=uNe(r5(N)||String((T=N.raw)!=null?T:""),A);const L=Math.max(0,_-x);if(S.length>20){const N=Math.round(2.4*S.length);return Math.round(x+Math.max(N,Math.min(L,3*S.length)))}if(L<=0)return x;const M=S.length>8?8*S.length:L;return Math.round(x+Math.min(L,M))})(k,y);case"list_item":return Ad(String((r=(s=k.raw)!=null?s:k.content)!=null?r:""),y,34);case"blockquote":return Ad(String((a=(l=k.raw)!=null?l:k.content)!=null?a:""),y,56);case"table":return(function(b,A){const T=[...b.header?[b.header]:[],...Array.isArray(b.rows)?b.rows:[]];if(!T.length){const S=Array.isArray(b.children)?b.children.length:3;return Math.max(120,38*S+48)}return Math.max(120,Math.round(4+T.reduce((S,x)=>S+(function(_,L){const M=Math.max(1,_.length),N=Math.max(80,(L-32)/M),I=Math.max(10,Math.floor(N/8)),z=Math.max(1,..._.map(H=>{var O;const R=r5(H)||String((O=H?.raw)!=null?O:"");return Math.ceil(R.length/I)||1}));return 54+34*Math.max(0,z-1)+(M<=3&&_.some(wP)?14:0)})((function(_){var L;return Array.isArray(_?.cells)&&(L=_.cells)!=null?L:[]})(x),A),0)))})(k,y);case"code_block":{const b=String((u=k.language)!=null?u:"").trim().toLowerCase(),A=String((d=(c=k.code)!=null?c:k.raw)!=null?d:"");return b==="mermaid"?dy(uy(A)):b==="infographic"?fy(cy(A)):Ad(A,y,96,20)}case"math_block":return 72;case"image":return 220;case"admonition":case"vmr_container":case"html_block":return(function(b,A){var T,S,x;const _=b.match(/^\s*<details\b([^>]*)>/i);return _&&!/(?:^|\s)open(?:\s|=|$)/i.test((T=_[1])!=null?T:"")?Ad(((x=(S=b.match(/<summary\b[^>]*>([\s\S]*?)<\/summary>/i))==null?void 0:S[1])==null?void 0:x.replace(/<[^>]*>/g,"").trim())||"Details",A,28,28):Ad(b,A,96)})(String((p=(h=k.raw)!=null?h:k.content)!=null?p:""),y);case"thematic_break":return 24;default:return Ad(String((m=(g=k.raw)!=null?g:k.content)!=null?m:""),y,40)}}function GE(e,t,n){return Math.min(Math.max(e,t),n)}const dNe=["total","cacheHits","appendHits","tailHits","fullParses","chunkedParses"],fNe=["tokenCloneMs","processTokensInputTokens","processTokensReusedTopLevelNodes","processTokensMs","safeMarkdownMs","tokenizeMs","htmlBlockPassesMs","parseMarkdownToStructureTotalMs"],hNe=new Set(["attrs","data","items","header","payload","props","rows","cells","term","definition","sourceMap"]),xP=["raw","content","code","originalCode","updatedCode"],QE=new WeakMap,YE=new WeakMap;let pNe=1;function Zl(){return typeof performance<"u"?performance.now():Date.now()}function JE(e){const t=e.stream;return t&&typeof t.stats=="function"?t.stats():null}function rl(e){if(typeof e!="object"&&typeof e!="function"||e===null)return"";const t=e;let n=QE.get(t);return n||(n=pNe++,QE.set(t,n)),String(n)}function XE(e,t,n,i={}){var o,s;const r=i.includeFinal!==!1,l={md:rl(t),customMarkdownIt:rl(n),requireClosingStrong:e.requireClosingStrong===!0,customHtmlTags:(o=e.customHtmlTags)!=null?o:[],includeSourceMap:e.includeSourceMap===!0,streamParse:(s=e.streamParse)!=null?s:"auto",validateLink:rl(e.validateLink),preTransformTokens:rl(e.preTransformTokens),postTransformTokens:rl(e.postTransformTokens),postTransformNodes:rl(e.postTransformNodes)};return r&&(l.final=e.final===!0),JSON.stringify(l)}function eT(e){let t=e.length;for(;t>0&&e.charCodeAt(t-1)===10;)t-=1;const n=e.lastIndexOf(` -`,t-1)+1;return e.slice(n,t).trim()}function tT(e){const t=SP(e);return t.length>=2&&t.every(n=>{const i=n.trim();return i.length>=1&&i.replace(/^:/,"").replace(/:$/,"").split("").every(o=>o==="-")})}function SP(e){return e.includes("|")?e.replace(/^\|/,"").replace(/\|$/,"").split("|"):[]}function _P(e){let t=2166136261;for(let n=0;n<e.length;n++)t^=e.charCodeAt(n),t=Math.imul(t,16777619);return(t>>>0).toString(36)}function eA(e){const t=String(e??"");return`${t.length}:${_P(t)}`}function l5(e,t=new WeakMap,n=0){if(e==null||typeof e=="number"||typeof e=="boolean")return String(e);if(typeof e=="string")return`s:${(function(r){return r.length<=8192?eA(r):`${r.length}:${_P(r.slice(0,8192))}:truncated`})(e)}`;if(typeof e=="function")return`fn:${rl(e)}`;if(typeof e!="object")return typeof e;const i=e,o=t.get(i);if(o)return`cycle:${o}`;if(n>=6)return`object:${rl(i)}`;const s=rl(i);if(t.set(i,s),Array.isArray(e)){const r=e.slice(0,200);return`a:${e.length}:${r.map(l=>l5(l,t,n+1)).join(",")}`}if(typeof e=="object"){const r=e,l=Object.keys(r).sort(),a=l.slice(0,80);return`o:${l.length}:${a.sort().map(u=>`${u}:${l5(r[u],t,n+1)}`).join(";")}`}return typeof e}function by(e){return typeof e=="object"&&e!==null&&typeof e.type=="string"&&typeof e.raw=="string"}function MP(e,t=new WeakMap,n=0){return Array.isArray(e)?`a:${e.length}:${e.slice(0,200).map(i=>by(i)?Dc(i,t,n+1):MP(i,t,n+1)).join(",")}`:by(e)?Dc(e,t,n):l5(e,t,n)}function gNe(e,t,n){return Object.keys(e).sort().filter(i=>i!=="children"&&!xP.includes(i)).map(i=>{const o=e[i];return typeof o=="string"?`${i}=s:${eA(o)}`:typeof o=="number"||typeof o=="boolean"||o==null?`${i}=${String(o)}`:typeof o=="function"?`${i}=fn:${rl(o)}`:hNe.has(i)&&(Array.isArray(o)||typeof o=="object")?`${i}=${MP(o,t,n+1)}`:o&&typeof o=="object"?`${i}=object:${rl(o)}`:""}).filter(Boolean).join(";")}function mNe(e){return xP.map(t=>{const n=e[t];return typeof n=="string"?`${t}=s:${eA(n)}`:""}).filter(Boolean).join(";")}function Dc(e,t=new WeakMap,n=0){const i=YE.get(e);if(i)return i;const o=e,s=t.get(o);if(s)return`node-cycle:${s}`;if(n>=6)return`node:${e.type}:${rl(o)}`;const r=rl(o);t.set(o,r);const l=(function(a,u,c){const d=a,h=Array.isArray(d.children)?d.children:[],p=h.length?h.slice(0,200).map(g=>Dc(g,u,c+1)).join("|"):"";return[a.type,mNe(d),gNe(d,u,c),h.length,p].join(":")})(e,t,n);return YE.set(o,l),l}function IP(e,t){return Dc(e)===Dc(t)}function tA(e,t,n){const i=Zl(),o=t==="stabilizeSignatureMs"?"stabilizeSignatureCallCount":"primeSignatureCallCount";try{return n()}finally{e[t]+=Zl()-i,e[o]+=1,e.signatureMs=e.stabilizeSignatureMs+e.primeSignatureMs,e.signatureCallCount=e.stabilizeSignatureCallCount+e.primeSignatureCallCount}}function nT(e,t,n){return tA(t,n,()=>Dc(e))}function EP(e,t,n){return nT(e,n,"stabilizeSignatureMs")===nT(t,n,"stabilizeSignatureMs")}function ev(e){return{reusedNodeCount:0,dirtyStartIndex:e>0?0:-1,stablePrefixNodeCount:0,dirtyTailNodeCount:e}}function iT(e,t,n){return e<0?0:Math.max(t.length,n.length)-e}function oT(e){return e.__markstreamHasCustomParserExtensions===!0||(function(t){var n;return Number((n=t.__markstreamRegisteredPluginCount)!=null?n:0)>0})(e)}function vNe(e,t){return e.length===t.length&&e===t}function nA(e,t,n=0){if(n>=4)return null;if(e.type!==t.type)return!1;const i=e,o=t,s=Object.keys(i).filter(c=>c!=="type"&&c!=="children").sort(),r=Object.keys(o).filter(c=>c!=="type"&&c!=="children").sort();if(s.length!==r.length)return!1;for(let c=0;c<s.length;c++){const d=s[c];if(d!==r[c])return!1;const h=i[d],p=o[d];if(typeof h!=typeof p)return!1;if(typeof h!="string"){if(typeof h!="number"&&typeof h!="boolean"&&h!=null)return null;if(!Object.is(h,p))return!1}else if(typeof p!="string"||!vNe(h,p))return!1}const l=Object.prototype.hasOwnProperty.call(i,"children");if(l!==Object.prototype.hasOwnProperty.call(o,"children"))return!1;if(!l)return!0;const a=i.children,u=o.children;if(!Array.isArray(a)||!Array.isArray(u))return null;if(a.length!==u.length)return!1;for(let c=0;c<a.length;c++){const d=a[c],h=u[c];if(!by(d)||!by(h))return null;const p=nA(d,h,n+1);if(p==null)return null;if(!p)return!1}return!0}function yNe(e,t){if(!e||!t)return!1;if(e===t)return!0;if(e.type!==t.type)return!1;const n=nA(e,t);return n??IP(e,t)}function kNe(e,t,n){if(!e||!t)return!1;if(e===t)return!0;if(e.type!==t.type)return!1;let i=null;return tA(n,"stabilizeSignatureMs",()=>{i=nA(e,t)}),i??EP(e,t,n)}function bNe(e,t){const n={};for(const i of dNe){const o=e[i],s=t?.[i];typeof o=="number"&&(n[i]=o-(typeof s=="number"?s:0))}return n}function ANe(e,t){var n;const i=tE(t.instanceMsgId),o=new Map,s=(n=t.smoothStreamingEnabled)!=null?n:F(()=>!1),r=K(t.renderContent.value);let l=[],a="",u="",c="",d=!1;const h=(function(){let H="",O=0,R=!1,j=!1,$=!1,W=!1;function P(){H="",O=0,R=!1,j=!1,$=!1,W=!1}function Z(ae){let V=!1;for(let Y=0;Y<ae.length;Y++){const oe=ae.charCodeAt(Y);if(oe===10||oe===13){const ne=oe===10&&W;W=oe===13,R=!1,ne||($||(j=!1,O=0),$=!1);continue}W=!1;const q=oe===9||oe===32;if(q||($=!0,j&&(V=!0)),O)if(O!==1)q||(oe!==58?O=oe===91?1:0:(V=!0,j=!0));else{if(R){R=!1;continue}if(oe===92){R=!0;continue}oe===93&&(O=2)}else oe===91&&(O=1)}return V}return(ae,V)=>{if(!ae||!V.startsWith(ae)||V.length<=ae.length)return P(),[!0,0];let Y=0;H!==ae&&(P(),Z(ae),Y=ae.length);const oe=V.slice(ae.length),q=Z(oe);return H=V,[q,Y+oe.length]}})();let p,g=0,m=0,k=Zl(),w=-1,y=0;function b(H){w=Number.isInteger(H)?H:0,y+=1}function A(){p&&(clearTimeout(p),p=void 0)}function T(){A();const H=t.renderContent.value;r.value!==H&&(r.value=H),k=Zl()}Pe([t.renderContent,t.effectiveFinal,s],([H,O,R])=>{r.value!==H&&(!R||O||(function(j,$){if(!j&&$||$.length<=80||$.length<j.length||!$.startsWith(j))return!0;const W=$.slice(j.length);return!!W&&(!!tT(eT($))||!(!W.includes(` - -`)&&!/(?:^|\n)(?:#{1,6}\s|[-+*]\s+|\d+[.)]\s+|>\s*|`{3,}|~{3,})/.test(W))||W.endsWith(` -`)&&!(function(P){const Z=eT(P);if(tT(Z))return!1;const ae=SP(Z);return ae.length>=2&&ae.some(V=>V.trim())})($))})(r.value,H)?T():(function(){if(m+=1,p)return;const j=Math.max(0,(function($){const W=$.parseCoalesceMs;return typeof W=="number"&&Number.isFinite(W)&&W>=0?W:80})(e)-(Zl()-k));j<=0?T():p=setTimeout(T,j)})())},{flush:"sync",immediate:!0}),Bc(A);const S=F(()=>{var H,O,R,j;return Awe(e.customHtmlTags,(H=e.parseOptions)==null?void 0:H.customHtmlTags,(j=(R=(O=t.customComponentsMap)==null?void 0:O.value)!=null?R:{},Object.entries(j).map(([$,W])=>{const P=zl($);return W==null||!P||Cg(P)||Bz.has(P)||vg.has(P)?"":P}).filter(Boolean)))}),x=F(()=>{const{key:H,tags:O}=Cwe(S.value);if(!H)return i;const R=o.get(H);if(R)return R;const j=tE(t.instanceMsgId,{customHtmlTags:O});return o.set(H,j),j}),_=F(()=>{const H=x.value;if(!e.customMarkdownIt)return H;const O=e.customMarkdownIt(H);return H.__markstreamHasCustomParserExtensions=!0,O.__markstreamHasCustomParserExtensions=!0,O}),L=F(()=>{var H,O;const R=(H=e.parseOptions)!=null?H:{},j=t.effectiveFinal.value,$=S.value,W=j!=null,P=$.length>0;return W||P||R.streamParse==null?Mt(Mt(An(Mt({},R),{streamParse:(O=R.streamParse)==null||O}),W?{final:j}:{}),P?{customHtmlTags:$}:{}):R}),M=F(()=>{var H;return new Set(((H=L.value.customHtmlTags)!=null?H:[]).map(O=>String(O).trim().toLowerCase()).filter(Boolean))}),N=F(()=>XE(L.value,_.value,e.customMarkdownIt,{includeFinal:!0})),I=F(()=>XE(L.value,_.value,e.customMarkdownIt,{includeFinal:!1}));Pe([N,I],([H,O],[R,j])=>{R&&(H===R&&O===j||(T(),O!==j&&(l=[],c="")))},{flush:"sync"});const z=F(()=>{var H,O,R,j,$,W,P,Z,ae,V,Y;if((H=e.nodes)!=null&&H.length)return l=[],c="",b(0),St(e.nodes.slice());const oe=r.value;if(!oe)return l=[],c="",b(-1),[];const q=t.debugPerformanceEnabled.value,ne=q?Zl():0,ie=_.value,pe=N.value,Ne=I.value;a&&pe!==a&&(function(ut){var _t,Ct;(Ct=(_t=ut.stream)==null?void 0:_t.reset)==null||Ct.call(_t)})(ie),u&&Ne!==u&&(l=[],c="");const te=Object.keys((R=(O=t.customComponentsMap)==null?void 0:O.value)!=null?R:{}).length>0||typeof L.value.postTransformNodes=="function";te!==d&&(l=[],c="");const be=!te&&l.length>0&&oe.startsWith(c)&&Ne===u,Q=q?JE(ie):null,ue=q?{}:void 0,Ae=oT(ie),se=!Ae&&!te,re=Mt(Mt(An(Mt({},L.value),{__reuseStableTopLevelNodes:se}),Ae?{__disableStreamParse:!0}:{}),ue?{__timing:ue}:{}),G=OO(oe,ie,re),le=q?Zl():0,ge=q?{signatureMs:0,stabilizeSignatureMs:0,primeSignatureMs:0,signatureCallCount:0,stabilizeSignatureCallCount:0,primeSignatureCallCount:0}:void 0;let ke,Ie=q?ev(G.length):void 0,Oe=0,we=0,Be=0;if(be){const ut=q?Zl():0,[_t,Ct]=(function(Vt){var nn,gt;const[Le,ze]=Vt.scanGlobalReferenceAppend(Vt.previousContent,Vt.content),Ye=Vt.parseOptions;return[Vt.previousDirtyStartIndex>0&&Ye.final!==!0&&!Vt.customMarkdownIt&&!oT(Vt.md)&&!Le&&typeof Ye.preTransformTokens!="function"&&typeof Ye.postTransformTokens!="function"&&typeof Ye.postTransformNodes!="function"&&((gt=(nn=Ye.customHtmlTags)==null?void 0:nn.length)!=null?gt:0)===0?Vt.previousDirtyStartIndex:0,ze]})({content:oe,previousContent:c,previousDirtyStartIndex:w,parseOptions:L.value,customMarkdownIt:e.customMarkdownIt,md:ie,scanGlobalReferenceAppend:h});Be=Ct;const $t=_t<=0;if(ge){const Vt=(function(nn,gt,Le,ze={}){var Ye;if(!gt.length)return{nodes:nn,metrics:ev(nn.length)};const Tt=(Ye=ze.scanStartIndex)!=null?Ye:0,on=ze.reuseDirtyTail!==!1,jt=(function(mn,zn,He,st=0){const et=Math.min(mn.length,zn.length);for(let Nt=Math.min(et,Math.max(0,st));Nt<et;Nt++)if(!kNe(zn[Nt],mn[Nt],He))return Nt;return mn.length===zn.length?-1:et})(nn,gt,Le,Tt);if(jt<0)return{nodes:gt,metrics:{reusedNodeCount:nn.length,dirtyStartIndex:jt,stablePrefixNodeCount:nn.length,dirtyTailNodeCount:0}};const kn=nn.slice();let bn=jt;for(let mn=0;mn<jt;mn++)kn[mn]=gt[mn];if(on)for(let mn=jt;mn<nn.length;mn++){const zn=gt[mn],He=nn[mn];zn&&EP(zn,He,Le)&&(kn[mn]=zn,bn+=1)}return{nodes:kn,metrics:{reusedNodeCount:bn,dirtyStartIndex:jt,stablePrefixNodeCount:jt,dirtyTailNodeCount:iT(jt,nn,gt)}}})(G,l,ge,{reuseDirtyTail:$t,scanStartIndex:_t});ke=Vt.nodes,Ie=Vt.metrics}else{const Vt=(function(nn,gt,Le={}){var ze;if(!gt.length)return{nodes:nn,metrics:ev(nn.length)};const Ye=(ze=Le.scanStartIndex)!=null?ze:0,Tt=Le.reuseDirtyTail!==!1,on=(function(bn,mn,zn=0){const He=Math.min(bn.length,mn.length);for(let st=Math.min(He,Math.max(0,zn));st<He;st++)if(!yNe(mn[st],bn[st]))return st;return bn.length===mn.length?-1:He})(nn,gt,Ye);if(on<0)return{nodes:gt,metrics:{reusedNodeCount:nn.length,dirtyStartIndex:on,stablePrefixNodeCount:nn.length,dirtyTailNodeCount:0}};const jt=nn.slice();let kn=on;for(let bn=0;bn<on;bn++)jt[bn]=gt[bn];if(Tt)for(let bn=on;bn<nn.length;bn++){const mn=gt[bn],zn=nn[bn];mn&&IP(mn,zn)&&(jt[bn]=mn,kn+=1)}return{nodes:jt,metrics:{reusedNodeCount:kn,dirtyStartIndex:on,stablePrefixNodeCount:on,dirtyTailNodeCount:iT(on,nn,gt)}}})(G,l,{reuseDirtyTail:$t,scanStartIndex:_t});ke=Vt.nodes,Ie=Vt.metrics}Oe=q?Zl()-ut:0,we=$t?Ie?.dirtyStartIndex==null||Ie.dirtyStartIndex<0?ke.length:Ie.dirtyStartIndex:ke.length}else ke=G,Ie=ev(ke.length);t.effectiveFinal.value!==!0&&(ge?(function(ut,_t,Ct=0){for(let $t=Math.max(0,Ct);$t<ut.length;$t++)tA(_t,"primeSignatureMs",()=>Dc(ut[$t]))})(ke,ge,we):(function(ut,_t=0){for(let Ct=Math.max(0,_t);Ct<ut.length;Ct++)Dc(ut[Ct])})(ke,we));const tt=q?Zl()-le:0;if(g+=1,c=oe,a=pe,u=Ne,d=te,l=ke,b((j=Ie?.dirtyStartIndex)!=null?j:0),q){const ut=JE(ie),_t=typeof ut?.total=="number"&&ut.total>(($=Q?.total)!=null?$:0);t.logPerf(_t?"parse(stream)":"parse(sync)",Mt(Mt(Mt({rendererId:t.instanceMsgId,ms:Math.round(Zl()-ne),nodes:ke.length,contentLength:oe.length,parseCommitCount:g,parseCoalescedCount:m,nodeReuseMs:tt,referenceDefinitionScanChars:Be,signatureMs:(W=ge?.signatureMs)!=null?W:0,stabilizeSignatureMs:(P=ge?.stabilizeSignatureMs)!=null?P:0,primeSignatureMs:(Z=ge?.primeSignatureMs)!=null?Z:0,signatureCallCount:(ae=ge?.signatureCallCount)!=null?ae:0,stabilizeSignatureCallCount:(V=ge?.stabilizeSignatureCallCount)!=null?V:0,primeSignatureCallCount:(Y=ge?.primeSignatureCallCount)!=null?Y:0,stabilizeMs:Oe},Ie??{}),ue?Object.fromEntries(fNe.map(Ct=>{var $t;return[Ct,($t=ue[Ct])!=null?$t:0]})):{}),ut?{streamMode:ut.lastMode,streamDelta:bNe(ut,Q),streamStats:ut}:{}))}return St(ke)});return{effectiveCustomHtmlTags:S,effectiveCustomHtmlTagsSet:M,mdBase:x,mdInstance:_,mergedParseOptions:L,getParsedNodesDirtyStartIndex:()=>w,getParsedNodesRevision:()=>y,parsedNodes:z}}function CNe(e){const{isClient:t}=e,n=K(new Set),i=new Map,o=new Map,s=new Map;function r(u){if(!t)return;const c=s.get(u);c!=null&&(window.clearTimeout(c),s.delete(u))}function l(){if(t)for(const u of s.values())window.clearTimeout(u);s.clear()}function a(){n.value=new Set}return{visibleNodeIndices:n,nodeVisibilityHandles:i,nodeVisibilityWatchStops:o,nodeVisibilityFallbackTimers:s,clearVisibilityFallback:r,clearAllVisibilityFallbacks:l,markNodeVisible:function(u,c=!0){var d;c&&r(u),(function(h,p){if((m=(g=e.shouldTrackVisibleNodeIndices)==null?void 0:g.call(e))!=null&&!m)return;var g,m;const k=n.value,w=k.has(h);if(p){if(w)return;const b=new Set(k);return b.add(h),void(n.value=b)}if(!w)return;const y=new Set(k);y.delete(h),n.value=y})(u,c),c&&((d=e.onNodeMarkedVisible)==null||d.call(e,u))},resetNodeVisibleState:a,cleanupNodeVisibility:function(u){var c;if(e.shouldCleanupNodeVisibility&&!e.shouldCleanupNodeVisibility())return;for(const[h,p]of o.entries())h<u||(p(),o.delete(h));for(const[h,p]of i.entries())h<u||(p.destroy(),i.delete(h),r(h),(c=e.onNodeVisibilityCleaned)==null||c.call(e,h));for(const h of Array.from(s.keys()))h<u||r(h);if(!n.value.size)return;const d=new Set;for(const h of n.value)h<u&&d.add(h);n.value=d},destroyNodeVisibilityState:function(){a();for(const u of o.values())u();o.clear();for(const u of i.values())u.destroy();i.clear(),l()}}}function wNe(e={}){const t=K(""),n=K(""),i=K(!1),o=iEe(e),s=()=>{const c=o.getSnapshot();t.value=c.source,n.value=c.visible,i.value=c.done},r=o.subscribe(s);s();const l=F(()=>Math.max(0,t.value.length-n.value.length)),a=F(()=>l.value===0),u=F(()=>i.value&&a.value);return Y0()&&Bc(()=>{r(),o.destroy()}),{source:t,visible:n,done:i,final:u,caughtUp:a,pendingChars:l,enqueue:c=>o.enqueue(c),finish:c=>o.finish(c),flush:()=>o.flush(),reset:c=>o.reset(c),pause:()=>o.pause(),resume:()=>o.resume()}}const xNe={maxCharsPerSecond:3e3,maxCommitFps:20,maxCharsPerCommit:160,catchUpLatencyMs:220,catchUpThreshold:400},sT=/auto|scroll|overlay/i;function SNe(e){if(!e)return!1;const t=(e.overflowY||"").toLowerCase(),n=(e.overflow||"").toLowerCase();return sT.test(t)||sT.test(n)}function _Ne(e){const t=Math.ceil(e.scrollHeight)>Math.ceil(e.clientHeight)+1,n=Math.ceil(e.scrollWidth)>Math.ceil(e.clientWidth)+1;return t||n}const MNe={class:"m-0 p-0"},INe=["data-probe"],ENe=Ci(Xe(An(Mt({},{name:"HeightEstimationProbes"}),{__name:"HeightEstimationProbes",props:{width:{},flowRoot:{type:Boolean},paragraphNode:{},listItemNode:{},listNode:{},headingNodes:{},setParagraphWrapper:{type:Function},setListItemWrapper:{type:Function},setListWrapper:{type:Function},setHeadingWrapper:{type:Function}},setup(e){const t=e;function n(i){var o,s;return(s=(o=t.headingNodes)==null?void 0:o[i])!=null?s:null}return(i,o)=>(v(),E("div",{class:"height-estimation-probes",style:Kt({width:`${e.width}px`}),"aria-hidden":"true"},[C("div",{ref:s=>e.setParagraphWrapper(s),class:Fe(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"paragraph"},[U(f(Jd),{node:e.paragraphNode,"index-key":"probe-paragraph"},null,8,["node"])],2),C("div",{ref:s=>e.setListItemWrapper(s),class:Fe(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"list-item"},[C("ul",MNe,[U(f(Ph),{node:e.listItemNode,"index-key":"probe-list-item"},null,8,["node"])])],2),C("div",{ref:s=>e.setListWrapper(s),class:Fe(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":"list"},[U(f(jh),{node:e.listNode,"index-key":"probe-list"},null,8,["node"])],2),(v(),E(Ee,null,pt(6,s=>C("div",{key:`probe-heading-${s}`,ref_for:!0,ref:r=>e.setHeadingWrapper(s,r),class:Fe(["node-content",{"node-content-flow-root":e.flowRoot}]),"data-probe":`heading-${s}`},[U(f(B9),{node:n(s),"index-key":`probe-heading-${s}`},null,8,["node","index-key"])],10,INe)),64))],4))}})),[["__scopeId","data-v-3e0766e2"]]),rT=Xe({name:"InfographicBlockNodeLoading",props:{node:{type:Object,required:!0},showHeader:{type:Boolean,default:!0},estimatedPreviewHeightPx:{type:Number,default:void 0}},setup(e){const t=F(()=>{var n,i;return fy((i=kh(e.estimatedPreviewHeightPx))!=null?i:cy(String((n=e.node.code)!=null?n:"")))});return()=>{var n;return yn("div",{class:"infographic-block-container rounded-lg border overflow-hidden",style:{margin:"var(--ms-flow-diagram-y) 0",background:"var(--diagram-bg)",borderColor:"var(--diagram-border)",color:"hsl(var(--ms-foreground))"},"data-markstream-infographic":"1","data-markstream-mode":"pending"},[e.showHeader?yn("div",{class:"infographic-block-header flex justify-between items-center border-b",style:{padding:"var(--ms-inset-panel-y) var(--ms-inset-panel-x)",background:"var(--diagram-header-bg)",borderColor:"var(--diagram-border)",minHeight:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding) + var(--ms-inset-panel-y) + var(--ms-inset-panel-y) + 1px)"}},[yn("div",{class:"flex items-center gap-x-2 overflow-hidden"},[yn("span",{class:"icon-slot action-icon shrink-0",style:{display:"inline-flex",width:"var(--ms-action-btn-icon)",height:"var(--ms-action-btn-icon)"}}),yn("span",{class:"infographic-label font-medium font-mono truncate",style:{fontSize:"var(--ms-text-label)",color:"hsl(var(--ms-muted-foreground))"}},"Infographic")]),yn("div",{class:"infographic-header-actions flex items-center opacity-0 pointer-events-none",style:{gap:"var(--ms-gap-header-actions)"},"aria-hidden":"true"},Array.from({length:4},()=>yn("span",{class:"infographic-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded",style:{width:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding))",height:"calc(var(--ms-action-btn-icon) + var(--ms-action-btn-padding) + var(--ms-action-btn-padding))"}})))]):null,yn("div",{class:"infographic-preview relative overflow-hidden block",style:{height:`${t.value}px`,minHeight:"var(--ms-size-diagram-min-height)",background:"var(--diagram-bg)"}},[yn("pre",{class:"infographic-pending-source text-sm font-mono whitespace-pre-wrap",style:{position:"absolute",inset:"0",zIndex:"1",margin:"0",padding:"var(--ms-inset-panel-body)",overflow:"auto",textAlign:"left"}},String((n=e.node.code)!=null?n:"")),yn("div",{class:"absolute inset-0"},[yn("div",{class:"w-full text-center flex items-center justify-center min-h-full"})])])])}}}),lT=Xe({name:"MermaidBlockNodeLoading",props:{node:{type:Object,required:!0},showHeader:{type:Boolean,default:!0},estimatedPreviewHeightPx:{type:Number,default:void 0}},setup(e){const t=F(()=>{var n,i;return dy((i=kh(e.estimatedPreviewHeightPx))!=null?i:uy(String((n=e.node.code)!=null?n:"")))});return()=>{var n;return yn("div",{class:"mermaid-block-container rounded-lg border overflow-hidden",style:{margin:"var(--ms-flow-diagram-y) 0",borderColor:"var(--diagram-border)"},"data-markstream-mermaid":"1","data-markstream-mode":"pending"},[e.showHeader?yn("div",{class:"mermaid-block-header flex justify-between items-center border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)]",style:{background:"var(--diagram-header-bg)",borderColor:"var(--diagram-border)"}},[yn("div",{class:"flex items-center gap-x-2 overflow-hidden"},[yn("span",{class:"mermaid-label-text text-[length:var(--ms-text-label)] font-medium font-mono truncate",style:{color:"var(--code-action-fg)"}},"Mermaid")]),yn("div",{class:"mermaid-header-actions flex items-center gap-[var(--ms-gap-header-actions)] opacity-0 pointer-events-none","aria-hidden":"true"},Array.from({length:4},()=>yn("span",{class:"mermaid-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded"},[yn("span",{class:"action-icon block"})])))]):null,yn("div",{class:"mermaid-preview-area relative overflow-hidden block",style:{height:`${t.value}px`,minHeight:"var(--ms-size-diagram-min-height)",background:"var(--diagram-bg)"}},[yn("pre",{class:"mermaid-source-code text-sm font-mono whitespace-pre-wrap",style:{position:"absolute",inset:"0",margin:"0",padding:"var(--ms-inset-panel-body)",overflow:"auto",textAlign:"left"}},String((n=e.node.code)!=null?n:"")),yn("div",{class:"_mermaid w-full text-center flex items-center justify-center min-h-full",style:{fontFamily:"inherit",contentVisibility:"auto",contain:"content",containIntrinsicSize:"var(--ms-size-diagram-min-height) 240px"}})])])}}}),TNe={docs:{showTooltips:!0,fade:!0,batchRendering:!0,initialRenderBatchSize:40,renderBatchSize:80,renderBatchDelay:16,renderBatchBudgetMs:6,renderBatchIdleTimeoutMs:120,deferNodesUntilVisible:!0,maxLiveNodes:220,liveNodeBuffer:60,nodeVirtual:"auto"},chat:{showTooltips:!1,fade:!1,batchRendering:!0,initialRenderBatchSize:32,renderBatchSize:48,renderBatchDelay:6,renderBatchBudgetMs:8,renderBatchIdleTimeoutMs:60,deferNodesUntilVisible:!0,maxLiveNodes:0,liveNodeBuffer:0,nodeVirtual:"auto"},minimal:{showTooltips:!1,fade:!1,batchRendering:!0,initialRenderBatchSize:32,renderBatchSize:48,renderBatchDelay:6,renderBatchBudgetMs:8,renderBatchIdleTimeoutMs:60,deferNodesUntilVisible:!0,maxLiveNodes:0,liveNodeBuffer:0,nodeVirtual:"auto"}};function Ms(e){if(e==null)return"";if(typeof e=="string"||typeof e=="number"||typeof e=="boolean")return String(e);try{return JSON.stringify(e)}catch{return String(e)}}const LNe=["data-custom-id"],NNe=["data-node-index","data-node-type"],aT="typewriter-simple-cursor-target",TP=Ci(Xe(An(Mt({},{name:"NodeRenderer"}),{__name:"NodeRenderer",props:{content:{},nodes:{},final:{type:Boolean},parseOptions:{},customMarkdownIt:{},debugPerformance:{type:Boolean,default:!1},customHtmlTags:{},mode:{},domMode:{},htmlPolicy:{},viewportPriority:{type:Boolean,default:void 0},viewportPriorityOptions:{},codeBlockStream:{type:Boolean,default:!0},codeBlockDarkTheme:{},codeBlockLightTheme:{},codeBlockMonacoOptions:{},codeRenderer:{},renderCodeBlocksAsPre:{type:Boolean,default:void 0},codeBlockMinWidth:{},codeBlockMaxWidth:{},codeBlockProps:{},mermaidProps:{},d2Props:{},infographicProps:{},showTooltips:{type:Boolean,default:void 0},themes:{},langs:{},isDark:{type:Boolean},customId:{},indexKey:{},typewriter:{type:[Boolean,String],default:!1},smoothStreaming:{type:[Boolean,String],default:"auto"},smoothStreamingOptions:{},parseCoalesceMs:{},fade:{type:Boolean,default:void 0},batchRendering:{type:Boolean,default:void 0},initialRenderBatchSize:{},renderBatchSize:{},renderBatchDelay:{},renderBatchBudgetMs:{},renderBatchIdleTimeoutMs:{},deferNodesUntilVisible:{type:Boolean,default:void 0},maxLiveNodes:{},liveNodeBuffer:{},nodeVirtual:{type:[Boolean,String],default:void 0},virtualScroll:{},renderAsFragment:{type:Boolean}},emits:["copy","copy-code","handleArtifactClick","click","mouseover","mouseout","virtual-state-change","height-change","render-settled","render-final","anchor-change"],setup(e,{expose:t,emit:n}){const i=e,o=n;function s(B){if(!(typeof Event<"u"&&B instanceof Event))return typeof B=="string"&&o("copy-code",B),void o("copy",B)}const r=os(),l=hn("markstreamNestedRendererProps",void 0);function a(B){const J=r?.vnode.props;return!!J&&(Object.prototype.hasOwnProperty.call(J,B)||Object.prototype.hasOwnProperty.call(J,String(B).replace(/[A-Z]/g,fe=>`-${fe.toLowerCase()}`)))}function u(B){var J,fe;const he=i[B];return a(B)?he:(fe=(J=l?.value)==null?void 0:J[B])!=null?fe:he}const c=F(()=>{return(B=u("mode"))==="chat"||B==="minimal"||B==="docs"?B:"docs";var B}),d=F(()=>ZE(u("typewriter"))),h=F(()=>d.value!=="off"),p=F(()=>u("domMode")==="minimal"?"minimal":"full"),g=F(()=>{return(B={mode:c.value,codeRenderer:u("codeRenderer"),renderCodeBlocksAsPre:u("renderCodeBlocksAsPre")}).renderCodeBlocksAsPre===!0?"pre":B.codeRenderer==="pre"||B.codeRenderer==="shiki"||B.codeRenderer==="monaco"?B.codeRenderer:B.renderCodeBlocksAsPre===!1||B.mode==="docs"?"monaco":"pre";var B}),m=F(()=>TNe[c.value]),k=F(()=>{var B;return(B=u("showTooltips"))!=null?B:m.value.showTooltips}),w=F(()=>{var B;return(B=u("fade"))!=null?B:m.value.fade}),y=F(()=>{var B;return(B=u("batchRendering"))!=null?B:m.value.batchRendering}),b=F(()=>{var B;return(B=u("initialRenderBatchSize"))!=null?B:m.value.initialRenderBatchSize}),A=F(()=>{var B;return(B=u("renderBatchSize"))!=null?B:m.value.renderBatchSize}),T=F(()=>{var B;return(B=u("renderBatchDelay"))!=null?B:m.value.renderBatchDelay}),S=F(()=>{var B;return(B=u("renderBatchBudgetMs"))!=null?B:m.value.renderBatchBudgetMs}),x=F(()=>{var B;return(B=u("renderBatchIdleTimeoutMs"))!=null?B:m.value.renderBatchIdleTimeoutMs}),_=F(()=>{var B;return(B=u("deferNodesUntilVisible"))!=null?B:m.value.deferNodesUntilVisible}),L=F(()=>{var B;return(B=u("maxLiveNodes"))!=null?B:m.value.maxLiveNodes}),M=F(()=>{var B;return(B=u("liveNodeBuffer"))!=null?B:m.value.liveNodeBuffer}),N=F(()=>{var B;return(B=u("nodeVirtual"))!=null?B:m.value.nodeVirtual}),I={get content(){return i.content},get nodes(){return i.nodes},get final(){return i.final},get parseOptions(){return u("parseOptions")},get customMarkdownIt(){return u("customMarkdownIt")},get debugPerformance(){return i.debugPerformance},get customHtmlTags(){return u("customHtmlTags")},get mode(){return u("mode")},get domMode(){return p.value},get htmlPolicy(){return u("htmlPolicy")},get viewportPriority(){return u("viewportPriority")},get viewportPriorityOptions(){return u("viewportPriorityOptions")},get codeBlockStream(){return u("codeBlockStream")},get codeBlockDarkTheme(){return u("codeBlockDarkTheme")},get codeBlockLightTheme(){return u("codeBlockLightTheme")},get codeBlockMonacoOptions(){return u("codeBlockMonacoOptions")},get codeRenderer(){return u("codeRenderer")},get renderCodeBlocksAsPre(){return u("renderCodeBlocksAsPre")},get codeBlockMinWidth(){return u("codeBlockMinWidth")},get codeBlockMaxWidth(){return u("codeBlockMaxWidth")},get codeBlockProps(){return u("codeBlockProps")},get mermaidProps(){return u("mermaidProps")},get d2Props(){return u("d2Props")},get infographicProps(){return u("infographicProps")},get showTooltips(){return k.value},get themes(){return u("themes")},get langs(){return u("langs")},get isDark(){return u("isDark")},get customId(){return u("customId")},get indexKey(){return i.indexKey},get typewriter(){return u("typewriter")},get smoothStreaming(){return i.smoothStreaming},get smoothStreamingOptions(){return u("smoothStreamingOptions")},get parseCoalesceMs(){return u("parseCoalesceMs")},get fade(){return w.value},get batchRendering(){return y.value},get initialRenderBatchSize(){return b.value},get renderBatchSize(){return A.value},get renderBatchDelay(){return T.value},get renderBatchBudgetMs(){return S.value},get renderBatchIdleTimeoutMs(){return x.value},get deferNodesUntilVisible(){return _.value},get maxLiveNodes(){return L.value},get liveNodeBuffer(){return M.value},get nodeVirtual(){return N.value},get virtualScroll(){return i.virtualScroll},get renderAsFragment(){return i.renderAsFragment}};function z(B){o("height-change",B)}function H(B){o("virtual-state-change",B)}function O(B){o("anchor-change",B)}const R=K(),j=K(null),$=K(null),W=K(null),P=jo({1:null,2:null,3:null,4:null,5:null,6:null}),Z=K(!1),ae=new Map,V=K(0),Y=K(0),oe=K({paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}});function q(B,J){return typeof B!="string"?J:B.trim()||J}function ne(B){const J=Number(B);return Number.isFinite(J)&&J>0?Math.max(1,Math.trunc(J)):640}const ie=F(()=>{var B;const J=(B=I.viewportPriorityOptions)!=null?B:{},fe=q(J.rootMargin,ff);return{rootMargin:fe,heavyBlockMargin:q(J.heavyBlockMargin,fe),maxTargets:ne(J.maxTargets)}}),pe=F(()=>{var B;return(B=ie.value.rootMargin)!=null?B:ff}),Ne=F(()=>{var B;return(B=ie.value.maxTargets)!=null?B:640});function te(){var B,J;if(((B=i.virtualScroll)==null?void 0:B.enabled)!==!0)return null;const fe=(J=i.virtualScroll)==null?void 0:J.scrollRoot;return be(typeof fe=="function"?fe():fe)}function be(B){return B?typeof HTMLElement<"u"&&B instanceof HTMLElement?B:typeof B=="object"&&"value"in B?be(B.value):typeof B=="object"&&"$el"in B?be(B.$el):null:null}oi(hP,ie);const{isClient:Q,renderAsFragment:ue,debugPerformanceEnabled:Ae,resolvedShowTooltips:se,resolvedHtmlPolicy:re,inheritedSmoothStreaming:G,ownsTypewriterCursor:le}=(function(B){const J=typeof window<"u",fe=r1(),he=hn("markstreamHtmlPolicy",void 0),Ce=hn("markstreamTypewriterCursor",void 0),De=hn("markstreamSmoothStreaming",void 0),We=F(()=>B.renderAsFragment===!0),Ze=F(()=>!!(B.debugPerformance&&J&&typeof console<"u")),lt=F(()=>{var rt;if(typeof B.showTooltips=="boolean")return B.showTooltips;const qe=(rt=fe.showTooltips)!=null?rt:fe["show-tooltips"];return qe===""||qe===!0||qe==="true"||qe!==!1&&qe!=="false"&&void 0}),Ge=F(()=>{var rt,qe;return(qe=(rt=B.htmlPolicy)!=null?rt:he?.value)!=null?qe:"safe"}),nt=F(()=>Ce?.value!==!0);return{isClient:J,renderAsFragment:We,debugPerformanceEnabled:Ze,resolvedShowTooltips:lt,resolvedHtmlPolicy:Ge,inheritedSmoothStreaming:De,inheritedTypewriterCursor:Ce,ownsTypewriterCursor:nt}})(I),{resolveViewportRoot:ge,resolveScrollContainer:ke,isReverseFlexScrollRoot:Ie,getNormalizedScrollTop:Oe,getOffsetTopWithinRoot:we}=(function(B,J){function fe(){var Ze,lt;return(lt=(Ze=J.scrollRoot)==null?void 0:Ze.call(J))!=null?lt:null}function he(Ze){if(typeof window>"u")return null;const lt=fe();if(lt)return lt;const Ge=Ze??B.value;if(!Ge)return null;const nt=Ge.ownerDocument||document,rt=nt.scrollingElement||nt.documentElement;let qe=Ge;for(;qe&&qe!==nt.body&&qe!==rt;){if(SNe(window.getComputedStyle(qe))&&_Ne(qe))return qe;qe=qe.parentElement}return null}function Ce(Ze){if(!J.isClient)return!1;try{const lt=window.getComputedStyle(Ze);return!!(lt.display||"").toLowerCase().includes("flex")&&(lt.flexDirection||"").toLowerCase().endsWith("reverse")}catch{return!1}}function De(Ze,lt,Ge){var nt,rt;if(Ge)return We(lt);const qe=Ze.scrollTop;if(!Ce(Ze))return qe;const it=qe<0?-qe:qe;return Math.max(0,((nt=Ze.scrollHeight)!=null?nt:0)-((rt=Ze.clientHeight)!=null?rt:0))-it}function We(Ze){var lt,Ge,nt,rt,qe;const it=Number((lt=Ze.scrollingElement)==null?void 0:lt.scrollTop),mt=Number((nt=(Ge=Ze.documentElement)==null?void 0:Ge.scrollTop)!=null?nt:0),ht=Number((qe=(rt=Ze.body)==null?void 0:rt.scrollTop)!=null?qe:0);return Math.max(0,Number.isFinite(it)?it:0,Number.isFinite(mt)?mt:0,Number.isFinite(ht)?ht:0)}return{resolveViewportRoot:he,resolveScrollContainer:function(Ze){var lt,Ge,nt,rt;const qe=fe();if(qe)return qe;const it=he((lt=Ze??B.value)!=null?lt:null);if(it)return it;const mt=(rt=(nt=Ze?.ownerDocument)!=null?nt:(Ge=B.value)==null?void 0:Ge.ownerDocument)!=null?rt:typeof document<"u"?document:null;return mt?.scrollingElement||mt?.documentElement||null},isReverseFlexScrollRoot:Ce,getNormalizedScrollTop:De,getOffsetTopWithinRoot:function(Ze,lt){const Ge=lt.ownerDocument||Ze.ownerDocument||document;if((function(it,mt){return it===mt.documentElement||it===mt.body||it===mt.scrollingElement})(lt,Ge))return Ze.getBoundingClientRect().top+We(Ge);const nt=lt.getBoundingClientRect(),rt=Ze.getBoundingClientRect(),qe=De(lt,Ge,!1);return rt.top-nt.top+qe}}})(R,{isClient:Q,scrollRoot:te});oi("markstreamShowTooltips",se),oi("markstreamHtmlPolicy",re),oi("markstreamTypewriter",h),oi("markstreamFade",F(()=>I.fade!==!1)),oi("markstreamTypewriterCursor",F(()=>!0)),oi("markstreamTextStreamState",ae),oi("markstreamStreamVersion",V),oi("markstreamParseOptions",F(()=>I.parseOptions)),oi("markstreamCustomMarkdownIt",F(()=>I.customMarkdownIt));const{smoothStreamingEnabled:Be,renderContent:tt,requestedFinal:ut,effectiveFinal:_t}=(function(B,J){const fe=wNe(Mt(Mt({},xNe),B.smoothStreamingOptions)),he=F(()=>{var qe,it,mt;return B.smoothStreaming!==!1&&!((qe=B.nodes)!=null&&qe.length)&&(B.smoothStreaming===!0||!((it=J.inheritedSmoothStreaming)!=null&&it.value))&&(B.smoothStreaming===!0||ZE(B.typewriter)!=="off"||((mt=B.maxLiveNodes)!=null?mt:0)<=0)}),Ce=K(!J.isClient||B.smoothStreaming===!0);cn(()=>{Ce.value=!0});const De=F(()=>Ce.value&&he.value),We=F(()=>{var qe;return De.value?fe.visible.value:(qe=B.content)!=null?qe:""}),Ze=F(()=>{var qe,it;const mt=(qe=B.parseOptions)!=null?qe:{};return(it=B.final)!=null?it:mt.final}),lt=F(()=>{const qe=Ze.value;return De.value&&qe!=null?!!qe&&fe.caughtUp.value:qe});let Ge=0,nt=!1;function rt(){Ge=0,nt=!1}return Pe([()=>B.content,()=>B.nodes,De,Ze],([qe,it,mt,ht])=>{if(it?.length)return rt(),void fe.reset("");const Dt=qe??"";if(!mt)return rt(),fe.reset(Dt),void(ht&&fe.finish({flush:!0}));const At=fe.source.value;if(Dt){if(Dt!==At)if(Dt.startsWith(At)){const qt=Dt.slice(At.length),Zt=fe.pendingChars.value;qt.length<=8?(Ge++,nt||Ge>=2&&Zt<=8?(nt=!0,fe.reset(Dt)):fe.enqueue(qt)):(rt(),fe.enqueue(qt))}else rt(),fe.reset(Dt)}else rt(),fe.reset("");ht&&fe.finish()},{immediate:!0}),{smoothStream:fe,smoothStreamingEligible:he,smoothStreamingEnabled:De,renderContent:We,requestedFinal:Ze,effectiveFinal:lt}})(I,{isClient:Q,inheritedSmoothStreaming:G}),Ct=ut.value===!0;oi("markstreamSmoothStreaming",Be);const $t=K(!1),Vt=K(!1),nn=K(!1);let gt="",Le=!1,ze=null;function Ye(){Q&&ze!=null&&(window.clearTimeout(ze),ze=null)}function Tt(){$t.value=!1,Ye()}function on(B,J){if(!Ae.value)return;const fe=(function(){if(!Ae.value)return null;const he=zn(jt),Ce=zn(kn),De=Math.max(mn,Ce);if(he<=0&&De<=0)return null;const We={total:he,maxPerFrame:De,byLabel:(Ze=jt,Object.fromEntries(Array.from(Ze.entries()).sort((lt,Ge)=>Ge[1]-lt[1]||lt[0].localeCompare(Ge[0]))))};var Ze;return jt.clear(),kn.clear(),mn=0,We})();console.info(`[markstream-vue][perf] ${B}`,fe?An(Mt({},J),{layoutReads:fe}):J)}Pe([()=>I.indexKey,()=>I.customId],()=>{var B,J;Tt(),Vt.value=!1,nn.value=!((B=i.nodes)!=null&&B.length)&&ut.value!==!0&&!!i.content,gt=(J=tt.value)!=null?J:"",Le=gt.length>0},{flush:"sync"}),Pe([()=>i.content,()=>i.nodes,ut],([B,J,fe])=>{!J?.length&&fe!==!0&&B&&(nn.value=!0)},{flush:"sync",immediate:!0}),Pe([tt,()=>i.nodes,ut],([B,J,fe])=>{const he=B??"";return J?.length||fe===!0?(Tt(),Vt.value=!1,gt=he,void(Le=!0)):(he.length>0&&(nn.value=!0),Le?(gt&&he.length>gt.length&&he.startsWith(gt)?($t.value=!0,Vt.value=!0,Q&&(Ye(),ze=window.setTimeout(()=>{var Ce;ze=null,_t.value===!0||(Ce=i.nodes)!=null&&Ce.length||($f(),$t.value=!1,Qa())},1200))):(he.length<gt.length||!he.startsWith(gt))&&(Tt(),Vt.value=!1),void(gt=he)):(gt=he,void(Le=!0)))},{flush:"sync",immediate:!0});const jt=new Map,kn=new Map;let bn=!1,mn=0;function zn(B){let J=0;for(const fe of B.values())J+=fe;return J}function He(){mn=Math.max(mn,zn(kn)),kn.clear(),bn=!1}function st(B){B.maxPerFrame=Math.max(Number(B.maxPerFrame||0),Number(B.currentFrameTotal||0)),B.currentFrameTotal=0,B.frameScheduled=!1}function et(B){var J,fe;Ae.value&&(jt.set(B,((J=jt.get(B))!=null?J:0)+1),kn.set(B,((fe=kn.get(B))!=null?fe:0)+1),(function(he){const Ce=(function(){if(!Q||typeof window>"u")return null;const De=window;if(De.__markstreamLayoutReadPerformance)return De.__markstreamLayoutReadPerformance;const We={total:0,maxPerFrame:0,byLabel:{}};return De.__markstreamLayoutReadPerformance=We,We})();Ce&&(Ce.total=Number(Ce.total||0)+1,Ce.byLabel[he]=Number(Ce.byLabel[he]||0)+1,Ce.currentFrameTotal=Number(Ce.currentFrameTotal||0)+1,Ce.frameScheduled||(Ce.frameScheduled=!0,typeof window.requestAnimationFrame!="function"?typeof queueMicrotask!="function"?setTimeout(()=>st(Ce),0):queueMicrotask(()=>st(Ce)):window.requestAnimationFrame(()=>st(Ce))))})(B),bn||(bn=!0,Q&&typeof window<"u"&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(He):typeof queueMicrotask!="function"?setTimeout(He,0):queueMicrotask(He)))}function Nt(B,J){return et(B),J()}const Lt=I.customId?`renderer-${I.customId}`:`renderer-${Date.now()}-${Math.random().toString(36).slice(2)}`,qn=(function(B){const J=new Map;return{scope:B,cache:J,clear:()=>J.clear()}})(Lt),So=Lt;oi(AP,qn);const Yn=ss(()=>I.customId),{effectiveCustomHtmlTagsSet:Ir,mergedParseOptions:_o,parsedNodes:It,getParsedNodesDirtyStartIndex:ms,getParsedNodesRevision:Er}=ANe(I,{instanceMsgId:Lt,renderContent:tt,effectiveFinal:_t,smoothStreamingEnabled:Be,debugPerformanceEnabled:Ae,customComponentsMap:Yn,logPerf:on});Pe(It,()=>{$t.value||qn.clear(),V.value+=1},{immediate:!0});const go=F(()=>({customId:I.customId,customHtmlTags:_o.value.customHtmlTags,parseOptions:I.parseOptions,customMarkdownIt:I.customMarkdownIt,htmlPolicy:re.value,viewportPriority:I.viewportPriority,viewportPriorityOptions:ie.value,mode:c.value,domMode:I.domMode,codeRenderer:g.value,codeBlockStream:I.codeBlockStream,codeBlockDarkTheme:I.codeBlockDarkTheme,codeBlockLightTheme:I.codeBlockLightTheme,codeBlockMonacoOptions:I.codeBlockMonacoOptions,renderCodeBlocksAsPre:I.renderCodeBlocksAsPre,codeBlockMinWidth:I.codeBlockMinWidth,codeBlockMaxWidth:I.codeBlockMaxWidth,codeBlockProps:I.codeBlockProps,mermaidProps:I.mermaidProps,d2Props:I.d2Props,infographicProps:I.infographicProps,showTooltips:se.value,themes:I.themes,langs:I.langs,isDark:I.isDark,typewriter:h.value,smoothStreamingOptions:I.smoothStreamingOptions,parseCoalesceMs:I.parseCoalesceMs,fade:I.fade}));oi("markstreamNestedRendererProps",go);const mo=F(()=>It.value),vs=F(()=>It.value.length),_i=K(null),Mo=K(null),ys=K(null),Tn=K(null),Un=i.indexKey!=null&&String(i.indexKey).startsWith("list-item-"),Kn=!Un&&I.customId?WE(I.customId):null,Pi=F(()=>Kn?(wk.value,WE(I.customId)):null),Io=F(()=>{var B;return!!(!ue.value&&I.customId&&!Un&&((B=Pi.value)!=null&&B.enabled))}),Ki=F(()=>!!(Q&&Io.value)),Ti=F(()=>{var B;return!!(!ue.value&&((B=i.virtualScroll)!=null&&B.enabled))}),Qs=F(()=>Ti.value),Li=K(!1);cn(()=>{Li.value=!0});const an=F(()=>!!(Q&&Ti.value));oi("markstreamHostScrollManaged",an);const to=F(()=>!!(Li.value&&an.value)),Jn=F(()=>Ki.value||an.value),Wo=F(()=>Ki.value||to.value),Mn=F(()=>{var B;return Jn.value&&((B=Pi.value)==null?void 0:B.textEstimation)!==!1});function Ni(){const B=Y.value||Nt("getMeasuredContainerWidth.clientWidth",()=>{var J;return((J=R.value)==null?void 0:J.clientWidth)||0});return Number.isFinite(B)&&B>0?B:0}const wi=F(()=>{const B=Ni();return B>0?Math.max(1,Math.round(B)):640}),$o=F(()=>{var B,J;return!(_t.value!==!0||Ti.value||c.value!=="chat"&&c.value!=="minimal"||a("maxLiveNodes")||a("liveNodeBuffer")||(B=i.nodes)!=null&&B.length||nn.value||!(((J=I.maxLiveNodes)!=null?J:0)<=0))}),$s=F(()=>{var B;return $o.value?50:Math.max(1,(B=I.maxLiveNodes)!=null?B:320)}),Vi=F(()=>{var B;return $o.value?16:Math.max(0,(B=I.liveNodeBuffer)!=null?B:60)}),Cn=F(()=>{var B;return!ue.value&&I.nodeVirtual!==!1&&!(((B=I.maxLiveNodes)!=null?B:0)<=0&&!$o.value)&&(I.nodeVirtual===!0?It.value.length>0:It.value.length>$s.value)}),Rs=F(()=>Cn.value||Ki.value||an.value),qo=F(()=>I.viewportPriority!==!1),ar=F(()=>!!qo.value&&!Z.value);var ks;ks=F(()=>qo.value),oi(pP,ks);const yi=F(()=>{var B;return!(ue.value||I.deferNodesUntilVisible===!1||((B=I.maxLiveNodes)!=null?B:0)<=0||Cn.value||It.value.length>900||I.viewportPriority===!1)}),Vn=nTe(B=>{var J;return ge((J=B??R.value)!=null?J:null)},qo),{requestFrame:ji,cancelFrame:Fi,hasIdleCallback:bs,isTestEnv:As}=(function(B){const J=B.isClient&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame.bind(window):null,fe=B.isClient&&typeof window.cancelAnimationFrame=="function"?window.cancelAnimationFrame.bind(window):null,he=B.isClient&&typeof window.requestIdleCallback=="function",Ce=(function(){var De;if(typeof globalThis>"u"||!("process"in globalThis))return;const We=(De=Object.getOwnPropertyDescriptor(globalThis,"process"))==null?void 0:De.value;return We?.env})();return{requestFrame:J,cancelFrame:fe,hasIdleCallback:he,isTestEnv:Ce?.NODE_ENV==="test"}})({isClient:Q}),Eo=F(()=>_t.value===!0&&!Ti.value),{resolvedBatchSize:Tr,resolvedInitialBatch:Lr,batchingEnabled:jl,incrementalRenderingActive:Nr,renderedCount:Di,previousRenderContext:Xn,adaptiveBatchSize:Cs,previousBatchConfig:Uo}=(function(B,J){var fe;const he=F(()=>{var rt;const qe=Math.trunc((rt=B.renderBatchSize)!=null?rt:80);return Number.isFinite(qe)?Math.max(0,qe):0}),Ce=F(()=>{var rt;const qe=Math.trunc((rt=B.initialRenderBatchSize)!=null?rt:he.value);return Number.isFinite(qe)?Math.max(0,qe):he.value}),De=F(()=>!J.renderAsFragment.value&&B.batchRendering!==!1&&he.value>0&&J.isClient&&!J.isTestEnv),We=K(0),Ze=K({key:B.indexKey,total:0}),lt=K(Math.max(1,he.value||1)),Ge=F(()=>{var rt,qe,it;return De.value&&!((rt=J.continuousStreaming)!=null&&rt.value)&&!((qe=J.forceFullRenderFinalContent)!=null&&qe.value)&&((it=B.maxLiveNodes)!=null?it:0)<=0}),nt=K({batchSize:he.value,initial:Ce.value,delay:(fe=B.renderBatchDelay)!=null?fe:16,enabled:Ge.value});return{resolvedBatchSize:he,resolvedInitialBatch:Ce,batchingEnabled:De,incrementalRenderingActive:Ge,renderedCount:We,previousRenderContext:Ze,adaptiveBatchSize:lt,previousBatchConfig:nt}})(I,{isClient:Q,isTestEnv:As,renderAsFragment:ue,forceFullRenderFinalContent:Eo,continuousStreaming:F(()=>Vt.value&&_t.value!==!0)}),On=F(()=>{var B;return!ue.value&&I.batchRendering!==!1&&Tr.value>0&&!As&&((B=I.maxLiveNodes)!=null?B:0)<=0&&!Eo.value}),Hi=F(()=>On.value),Wi=F(()=>Jn.value||Hi.value),rs=F(()=>{var B;return Wi.value&&((B=Pi.value)==null?void 0:B.codeBlockEstimation)!==!1}),jn=new Map,Ke=new Map,Ue=new WeakMap;let yt=null;const xt=new WeakMap,rn=new Map,Zi=[];let Gi=[],oo=[],qi=-1;const vo=ha(Zi),so=new Set,Ro=K(0);let ot=0;const xe=K(0),je=F(()=>(xe.value,Array.from(jn.entries()).sort((B,J)=>B[0]-J[0]))),Dn=K(null),vn=K(null);let ii,ws=null,xs=0,ro=null;function ai(){ii.markFallbackHeightPrefixDirty()}function Ys(B){return ii.getFallbackNodeHeight(B)}function Ss(B,J){return ii.estimateHeightRange(B,J)}function el(B){return ii.estimateIndexForOffset(B)}const{activeRestoreAnchor:ur,getRelativeScrollTopWithinContainer:tl,setRelativeScrollTopWithinContainer:ee,resolveAnchorOffset:me,clearRestoreReconcile:Me,scheduleRestoreReconcile:Re,captureRestoreAnchor:Qe,restoreAnchor:Je,getAnchorDrift:ft}=(function(B){const{isClient:J,containerRef:fe,parsedNodeCount:he,requestFrame:Ce,cancelFrame:De,resolveScrollContainer:We,getNormalizedScrollTop:Ze,getOffsetTopWithinRoot:lt,isReverseFlexScrollRoot:Ge,estimateIndexForOffset:nt,estimateHeightRange:rt,getFallbackNodeHeight:qe,clamp:it}=B,mt=K(null);let ht=null,Dt=[];function At(){const ln=We(),Fn=fe.value;if(!ln||!Fn)return null;const Pn=ln.ownerDocument||Fn.ownerDocument||document;if(ln===Pn.documentElement||ln===Pn.body||ln===Pn.scrollingElement){const Mi=Fn.getBoundingClientRect();return Math.max(0,-Mi.top)}return Math.max(0,Ze(ln,Pn,!1)-lt(Fn,ln))}function qt(ln){var Fn;const Pn=We(),Mi=fe.value;if(!Pn||!Mi)return;const Os=Math.max(0,ln),_s=Pn.ownerDocument||Mi.ownerDocument||document,Ul=_s.defaultView||(typeof window<"u"?window:null);if(Pn===_s.documentElement||Pn===_s.body||Pn===_s.scrollingElement){const ba=Ze(Pn,_s,!0)+Mi.getBoundingClientRect().top;return void((Fn=Ul?.scrollTo)==null||Fn.call(Ul,0,Math.max(0,ba+Os)))}KE(Pn,_s,lt(Mi,Pn)+Os,{isReverseFlexScrollRoot:ba=>{var R1;return(R1=Ge?.(ba))!=null&&R1},getNormalizedScrollTop:Ze})}function Zt(ln){const Fn=he.value,Pn=it(ln.nodeIndex,0,Math.max(0,Fn-1));return rt(0,Pn)+Math.max(0,ln.offsetWithinNodePx)}function sn(){if(ht!=null&&(De?.(ht),ht=null),J)for(const ln of Dt)window.clearTimeout(ln);Dt=[]}function Xt(ln){const Fn=Zt(ln),Pn=At();Pn!=null&&Math.abs(Pn-Fn)<=.5||qt(Fn)}return{activeRestoreAnchor:mt,getRelativeScrollTopWithinContainer:At,setRelativeScrollTopWithinContainer:qt,resolveAnchorOffset:Zt,clearRestoreReconcile:sn,applyRestoreAnchor:Xt,scheduleRestoreReconcile:function(){mt.value&&J&&ht==null&&(ht=Ce?Ce(()=>{ht=null,mt.value&&Xt(mt.value)}):null,ht==null&&mt.value&&Xt(mt.value))},captureRestoreAnchor:function(){const ln=At(),Fn=he.value;if(ln==null||Fn<=0)return null;const Pn=it(nt(ln+1),0,Fn-1),Mi=rt(0,Pn),Os=qe(Pn);return{nodeIndex:Pn,offsetWithinNodePx:it(ln-Mi,0,Math.max(0,Os-1))}},restoreAnchor:function(ln){const Fn=he.value;if(mt.value={nodeIndex:it(ln.nodeIndex,0,Math.max(0,Fn-1)),offsetWithinNodePx:Math.max(0,ln.offsetWithinNodePx)},sn(),Xt(mt.value),J)for(const Pn of[0,120,280,480])Dt.push(window.setTimeout(()=>{mt.value&&Xt(mt.value)},Pn))},getAnchorDrift:function(ln){const Fn=At();return Fn==null?null:Fn-Zt(ln)}}})({isClient:Q,containerRef:R,parsedNodeCount:vs,requestFrame:ji,cancelFrame:Fi,resolveScrollContainer:()=>Dn.value||ke(),getNormalizedScrollTop:Oe,getOffsetTopWithinRoot:we,isReverseFlexScrollRoot:Ie,estimateIndexForOffset:el,estimateHeightRange:Ss,getFallbackNodeHeight:Ys,clamp:zs}),{nodeHeights:vt,heightStats:Pt,heightTreeSize:fn,heightSumTree:dn,heightKnownTree:ui,averageNodeHeight:Ln,resetHeightMeasurements:Sn,pruneHeightMeasurements:fi,rebuildHeightTrees:Ui,recordNodeHeight:Fr,removeNodeHeights:ya,exportHeightCache:ka,importHeightCache:Du,fenwickRangeSum:v1}=(function(B={}){const J=jo({}),fe=jo({total:0,count:0}),he=K(0),Ce=K([]),De=K([]);function We(){for(const qe of Object.keys(J))delete J[Number(qe)];fe.total=0,fe.count=0,he.value=0,Ce.value=[],De.value=[]}function Ze(qe,it,mt){for(let ht=it+1;ht<qe.length;ht+=ht&-ht)qe[ht]+=mt}function lt(qe,it){let mt=0;for(let ht=it+1;ht>0;ht-=ht&-ht)mt+=qe[ht];return mt}function Ge(qe){he.value=qe;const it=new Array(qe+1).fill(0),mt=new Array(qe+1).fill(0);for(const[ht,Dt]of Object.entries(J)){const At=Number(ht),qt=Number(Dt);!Number.isFinite(At)||At<0||At>=qe||!Number.isFinite(qt)||qt<=0||(Ze(it,At,qt),Ze(mt,At,1))}Ce.value=it,De.value=mt}function nt(qe){if(!Number.isInteger(qe)||qe<0)return!1;const it=J[qe];if(!Number.isFinite(it)||it<=0)return!1;if(delete J[qe],fe.total=Math.max(0,fe.total-it),fe.count=Math.max(0,fe.count-1),he.value>qe){const mt=Ce.value,ht=De.value;mt.length&&ht.length&&(Ze(mt,qe,-it),Ze(ht,qe,-1))}return!0}const rt=F(()=>fe.count>0?Math.max(12,fe.total/fe.count):32);return{nodeHeights:J,heightStats:fe,heightTreeSize:he,heightSumTree:Ce,heightKnownTree:De,averageNodeHeight:rt,resetHeightMeasurements:We,pruneHeightMeasurements:function(qe){if(qe<=0)return void We();let it=0,mt=0;for(const[ht,Dt]of Object.entries(J)){const At=Number(ht),qt=Number(Dt);!Number.isFinite(At)||At<0||At>=qe||!Number.isFinite(qt)||qt<=0?delete J[At]:(it+=qt,mt++)}fe.total=it,fe.count=mt},rebuildHeightTrees:Ge,recordNodeHeight:function(qe,it,mt={}){(function(ht,Dt,At={}){var qt;if(!Number.isFinite(Dt)||Dt<=0)return!1;const Zt=J[ht];if(Zt&&(At.allowShrink===!1&&Dt<Zt||Math.abs(Dt-Zt)<=1))return!1;if(J[ht]=Dt,Zt?fe.total+=Dt-Zt:(fe.total+=Dt,fe.count++),he.value>ht){const sn=Ce.value,Xt=De.value;if(sn.length&&Xt.length)if(Zt){const ln=Dt-Zt;ln!==0&&Ze(sn,ht,ln)}else Ze(sn,ht,Dt),Ze(Xt,ht,1)}At.notify!==!1&&((qt=B.onHeightRecorded)==null||qt.call(B))})(qe,it,An(Mt({},mt),{notify:!0}))},removeNodeHeight:function(qe,it={}){var mt;const ht=nt(qe);return ht&&it.notify!==!1&&((mt=B.onHeightRecorded)==null||mt.call(B)),ht},removeNodeHeights:function(qe,it={}){var mt;let ht=0;for(const Dt of qe)nt(Number(Dt))&&ht++;return ht>0&&it.notify!==!1&&((mt=B.onHeightRecorded)==null||mt.call(B)),ht},exportHeightCache:function(){return Object.entries(J).map(([qe,it])=>({index:Number(qe),height:Number(it)})).filter(qe=>Number.isFinite(qe.index)&&qe.index>=0&&Number.isFinite(qe.height)&&qe.height>0).sort((qe,it)=>qe.index-it.index)},importHeightCache:function(qe,it={}){var mt;if(!Array.isArray(qe))return;const ht=he.value;let Dt=!1;if(it.mode!=="merge"){const At=Object.keys(J);if(At.length>0){for(const qt of At)delete J[Number(qt)];Dt=!0}}for(const At of qe){const qt=Number(At.index),Zt=Number(At.height);if(!Number.isInteger(qt)||qt<0||ht>0&&qt>=ht||!Number.isFinite(Zt)||Zt<=0)continue;const sn=J[qt];sn&&Math.abs(sn-Zt)<=1||(J[qt]=Zt,Dt=!0)}Dt&&((function(){let At=0,qt=0;const Zt=he.value;for(const[sn,Xt]of Object.entries(J)){const ln=Number(sn),Fn=Number(Xt);!Number.isFinite(ln)||ln<0||Zt>0&&ln>=Zt||!Number.isFinite(Fn)||Fn<=0?delete J[ln]:(At+=Fn,qt++)}fe.total=At,fe.count=qt})(),ht>0&&Ge(ht),(mt=B.onHeightRecorded)==null||mt.call(B))},fenwickRangeSum:function(qe,it,mt){if(mt<=it)return 0;const ht=lt(qe,mt-1);return it<=0?ht:ht-lt(qe,it-1)}}})({onHeightRecorded:()=>{ai(),an.value&&L1(),ur.value&&Re(),vn.value&&Ff(),Qi("node-resize")}});function ye(B){Number.isInteger(B)&&B>=0&&so.add(B)}function Se(B){for(const J of B)ye(Number(J))}function Ve(B){ot++;let J=!0;try{const fe=B();return J=fe!==!1,fe}finally{ot--,ot===0&&J&&Ro.value++}}function Rt(){Gi=[],oo=[],qi=-1,so.clear(),vo.value=Zi}function Yt(){Rt(),Ve(()=>Sn()),rn.clear()}function wn(B){!Number.isInteger(B)||B<0||B>=It.value.length||rn.set(B,b1(B))}function ei(B,J,fe={}){const he=vt[B];ye(B),Fr(B,J,fe);const Ce=vt[B];return Object.is(he,Ce)?(so.delete(B),!1):(Ce&&Ce>0?wn(B):he&&rn.delete(B),!0)}function Bi(B,J){const fe=Nt("getNodeLayoutHeight.slot.offsetHeight",()=>{var he,Ce;return(Ce=(he=jn.get(B))==null?void 0:he.offsetHeight)!=null?Ce:0});return fe>0?fe:Nt("getNodeLayoutHeight.content.offsetHeight",()=>J.offsetHeight)}function Ko(B,J={}){J.mode!=="merge"?Rt():Se(B.map(fe=>fe.index)),Ve(()=>Du(B,J)),b4()}const ls=F(()=>yi.value&&ar.value),Hl=F(()=>{var B;return!ue.value&&I.batchRendering!==!1&&Tr.value>0&&((B=I.maxLiveNodes)!=null?B:0)<=0}),V9=F(()=>!ue.value&&Ct&&_t.value===!0&&!Cn.value&&!Ti.value&&!Io.value&&!ls.value&&!Hl.value),Za=F(()=>!!Vn&&ls.value),Ng=F(()=>Cn.value||an.value),{focusIndex:Al,liveRange:as,updateLiveRange:Bu}=(function(B,J){const{parsedNodeCount:fe,virtualizationEnabled:he,maxLiveNodesResolved:Ce,liveNodeBufferResolved:De,clamp:We}=J,Ze=De??F(()=>{var nt;return Math.max(0,(nt=B.liveNodeBuffer)!=null?nt:60)}),lt=K(0),Ge=jo({start:0,end:0});return{liveNodeBufferResolved:Ze,focusIndex:lt,liveRange:Ge,updateLiveRange:function(){const nt=fe.value;if(!he.value||nt===0)return Ge.start=0,void(Ge.end=nt);const rt=Math.min(Ce.value,nt),qe=Ze.value,it=We(lt.value-qe,0,Math.max(0,nt-rt));Ge.start=it,Ge.end=Math.min(nt,it+rt)}}})(I,{parsedNodeCount:vs,virtualizationEnabled:Cn,maxLiveNodesResolved:$s,liveNodeBufferResolved:Vi,clamp:zs}),Te=new Map,ct=new Map,at=new Map,Ht=[],Nn=new Map,no=new Set,Js=K(0);let zo=!1;const Wl=F(()=>(Js.value,no.size)),us=new Map,cr=new Map,zA=K(0),Z9=F(()=>{zA.value;let B=0;for(const J of us.values())B+=Math.max(0,J);return B});let nl=null;const Fg=F(()=>{if(!Cn.value)return It.value.length;const B=Vi.value,J=Math.max(as.end+B,Lr.value),fe=Math.min(It.value.length,J);return Math.max(Di.value,fe)});function Dg(){zo||(zo=!0,queueMicrotask(()=>{zo=!1,Js.value+=1}))}function OA(B,J,fe="node-resize"){if(!Q||typeof window>"u")return null;const he=window.setTimeout(()=>{no.delete(he)&&Dg();try{J()}finally{Qi(fe)}},Math.max(0,B));return no.add(he),Dg(),he}function Bg(B){Q&&B!=null&&(no.delete(B)&&Dg(),window.clearTimeout(B))}function PA(){if(Q&&typeof window<"u")for(const B of no)window.clearTimeout(B);no.size&&(no.clear(),Dg()),Ht.length=0,at.clear()}function RH(B){j.value=B}function zH(B){$.value=B}function OH(B){W.value=B}const{cancelScheduledFocusSync:G9,scheduleFocusSync:ql}=(function(B){const{isClient:J,containerRef:fe,virtualizationEnabled:he,requestFrame:Ce,cancelFrame:De,syncFocusToScroll:We}=B;let Ze=null;function lt(){var nt,rt,qe;return(qe=(rt=(nt=fe.value)==null?void 0:nt.ownerDocument)==null?void 0:rt.defaultView)!=null?qe:typeof window<"u"?window:null}function Ge(){if(!Ze)return;const nt=lt();Ze.viaTimeout?nt?nt.clearTimeout(Ze.id):clearTimeout(Ze.id):De?.(Ze.id),Ze=null}return{cancelScheduledFocusSync:Ge,scheduleFocusSync:function(nt={}){if(!he.value)return;if(!J)return void We(!0);if(nt.immediate)return Ge(),void We(!0);if(Ze)return;const rt=()=>{Ze=null,We()};if(Ce)return void(Ze={id:Ce(rt),viaTimeout:!1});const qe=lt();Ze={id:qe?qe.setTimeout(rt,16):setTimeout(rt,16),viaTimeout:!0}}}})({isClient:Q,containerRef:R,virtualizationEnabled:Cn,requestFrame:ji,cancelFrame:Fi,syncFocusToScroll:function(B=!1){var J;if(!Cn.value)return;const fe=Dn.value||ke();if(!fe)return;const he=fe.ownerDocument||((J=R.value)==null?void 0:J.ownerDocument)||document,Ce=he?.defaultView||(typeof window<"u"?window:null),De=fe===he?.documentElement||fe===he?.body,We=It.value.length;if(We<=0)return;if(!De&&We>0&&Ie(fe)){const ht=Nt("syncFocusToScroll.clientHeight",()=>fe.clientHeight||0),Dt=Nt("syncFocusToScroll.scrollTop",()=>fe.scrollTop),At=Dt<0?-Dt:Dt;return void zg(zs((Ze=Math.max(0,At)+.5*Math.max(0,ht),ii.estimateIndexForOffsetFromEnd(Ze)),0,Math.max(0,We-1)),B)}var Ze;const lt=(function(ht,Dt,At,qt){const Zt=R.value;if(!Zt)return null;const sn=qt?0:Nt("syncFocusToScroll.model.root.getBoundingClientRect",()=>ht.getBoundingClientRect().top),Xt=Nt("syncFocusToScroll.model.container.getBoundingClientRect",()=>Zt.getBoundingClientRect().top),ln=Math.max(0,sn-Xt),Fn=qt?Nt("syncFocusToScroll.model.viewport.clientHeight",()=>{var Pn,Mi,Os,_s;return(_s=(Os=(Mi=At?.innerHeight)!=null?Mi:(Pn=Dt.documentElement)==null?void 0:Pn.clientHeight)!=null?Os:ht.clientHeight)!=null?_s:0}):Nt("syncFocusToScroll.model.root.clientHeight",()=>ht.clientHeight);return zs(el(ln+.5*Math.max(0,Fn)),0,Math.max(0,It.value.length-1))})(fe,he,Ce,De);if(lt!=null)return void zg(lt,B);const Ge=De?null:Nt("syncFocusToScroll.root.getBoundingClientRect",()=>fe.getBoundingClientRect()),nt=De?0:Ge.top,rt=De?Nt("syncFocusToScroll.viewport.clientHeight",()=>{var ht,Dt;return(Dt=(ht=Ce?.innerHeight)!=null?ht:fe.clientHeight)!=null?Dt:0}):Ge.bottom,qe=je.value;let it=null,mt=null;for(const[ht,Dt]of qe){if(!Dt)continue;const At=Nt("syncFocusToScroll.slot.getBoundingClientRect",()=>Dt.getBoundingClientRect());At.bottom<=nt||At.top>=rt||(it==null&&(it=ht),mt=ht)}if(it==null||mt==null){const ht=R.value;if(!ht)return;const Dt=De?{top:0}:Nt("syncFocusToScroll.fallback.root.getBoundingClientRect",()=>fe.getBoundingClientRect()),At=Nt("syncFocusToScroll.fallback.scrollTop",()=>Oe(fe,he,De)),qt=De?(()=>{const sn=Nt("syncFocusToScroll.fallback.container.getBoundingClientRect",()=>ht.getBoundingClientRect()),Xt=(De?0:Dt.top)-sn.top;return Math.max(0,Xt)})():(()=>{const sn=we(ht,fe);return Math.max(0,At-sn)})(),Zt=De?Nt("syncFocusToScroll.fallback.viewport.clientHeight",()=>{var sn,Xt,ln,Fn;return(Fn=(ln=(Xt=Ce?.innerHeight)!=null?Xt:(sn=he?.documentElement)==null?void 0:sn.clientHeight)!=null?ln:fe.clientHeight)!=null?Fn:0}):Nt("syncFocusToScroll.fallback.root.clientHeight",()=>fe.clientHeight);return void zg(zs(el(qt+.5*Math.max(0,Zt)),0,Math.max(0,It.value.length-1)),!0)}zg(Math.round((it+mt)/2),B)}}),{visibleNodeIndices:Q9,nodeVisibilityHandles:_f,nodeVisibilityWatchStops:$g,nodeVisibilityFallbackTimers:jA,clearVisibilityFallback:Rg,markNodeVisible:$u,cleanupNodeVisibility:PH,destroyNodeVisibilityState:Y9}=CNe({isClient:Q,shouldTrackVisibleNodeIndices:()=>ls.value,shouldCleanupNodeVisibility:()=>Cn.value,onNodeMarkedVisible:B=>{Cn.value?ql():Al.value=zs(B,0,Math.max(0,It.value.length-1))},onNodeVisibilityCleaned:B=>{jn.delete(B)&&gC()}}),{cleanupScrollListener:HA,setupScrollListener:jH}=(function(B){const{isClient:J,virtualizationEnabled:fe,listenerEnabled:he,scrollRootElement:Ce,resolveScrollContainer:De,scheduleFocusSync:We,onScroll:Ze}=B;let lt=null,Ge=null;function nt(){lt&&(lt(),lt=null),Ge=null,Ce.value=null}function rt(qe){const it=B.getScrollTop?B.getScrollTop(qe):qe.scrollTop;return Math.max(0,Number.isFinite(it)?Math.abs(it):0)}return{cleanupScrollListener:nt,setupScrollListener:function(){if(!J)return;if(!((qe=he?.value)!=null?qe:fe.value))return void nt();var qe;const it=De();if(!it)return void nt();if(Ce.value===it&<)return;nt(),Ge=rt(it);const mt=()=>{if(Ze?.(),fe.value){const ht=(function(Dt){const At=rt(Dt),qt=Ge;Ge=At;const Zt=Math.max(480,.75*(Dt.clientHeight||0));return qt==null?At>Zt?{immediate:!0}:void 0:Math.abs(At-qt)>Zt?{immediate:!0}:void 0})(it);ht?We(ht):We()}};it.addEventListener("scroll",mt,{passive:!0}),Ce.value=it,lt=()=>{it.removeEventListener("scroll",mt)}}}})({isClient:Q,virtualizationEnabled:Cn,listenerEnabled:Ng,scrollRootElement:Dn,resolveScrollContainer:ke,scheduleFocusSync:ql,onScroll:function(){const B=vn.value;if(!B)return;const J=k1();if(!J||(function(he){if(S1()>=xs)return ro=null,!1;const Ce=ro;if(Ce==null)return!0;const De=Math.abs(he.scrollTop-Ce)<=2;return De||(ro=null),De})(J))return;const fe=iC(J);fe!=null?(fe<-32||Math.abs(Math.max(0,fe)-Math.max(0,B.distanceFromBottomPx))>32)&&Nf("restore"):Nf("restore")},getScrollTop:B=>{var J;const fe=B.ownerDocument||((J=R.value)==null?void 0:J.ownerDocument)||document,he=B===fe.documentElement||B===fe.body||B===fe.scrollingElement;return Nt("scrollListener.getScrollTop",()=>Oe(B,fe,he))}});function zg(B,J=!1){const fe=zs(B,0,Math.max(0,It.value.length-1));!J&&Math.abs(fe-Al.value)<=1||(Al.value=fe,Bu())}function zs(B,J,fe){return Math.min(Math.max(B,J),fe)}function J9(B=It.value.length){const J=ms();return!Number.isInteger(J)||J<0?B:zs(J,0,B)}function X9(B){return B?.firstElementChild}function WA(B,J){var fe;return B?(fe=B.matches)!=null&&fe.call(B,J)?B:B.querySelector(J):null}function HH(B,J){B<1||B>6||(P[B]=J)}function qA(){if(!Jn.value)return void(Y.value=0);const B=Nt("updateExperimentContainerWidth.clientWidth",()=>{var J,fe;return(fe=(J=R.value)==null?void 0:J.clientWidth)!=null?fe:0});Y.value=B>0?B:0}let y1=null;function e4(){y1?.disconnect(),y1=null}const UA=Ip("ViewportDeferredMarkdownCodeBlockNode",ia({loader:()=>Ji(null,null,function*(){return(yield Fo(()=>import("./index5-L7WSqVk4.js"),__vite__mapDeps([8,6,7]))).default}),loadingComponent:gy,delay:0,suspensible:!1}),gy);function KA(B){return B===UA}const VA=F(()=>g.value==="pre"?jr:g.value==="shiki"?UA:vk);function ZA(){var B;return((B=I.codeBlockProps)==null?void 0:B.showHeader)!==!1}function GA(B,J,fe){const he=vt[J],Ce=typeof he=="number"&&he>0;if(Mn.value&&!Ce&&!(function(De){return!!Yn.value.paragraph&&(De.type==="paragraph"||De.type==="list_item"||De.type==="list")})(B)){const De=bP(B,fe,oe.value);if(De)return De}if(rs.value&&B.type==="code_block"){const De=(function(We){if(We.type!=="code_block")return null;const Ze=MC(We,Zg(We));return KA(Ze)?"markdown":Ze===jr?"pre":Ze===VA.value||Ze===vk?"monaco":null})(B);if(De==="monaco"||De==="markdown"||De==="pre")return(function(We,Ze){var lt,Ge,nt;if(!We||We.type!=="code_block")return null;const rt=Ze.rendererKind,qe=rt!=="pre"&&Ze.showHeader!==!1,it=!!We.diff;let mt=0,ht=500;if(rt==="monaco"){const At=(lt=Ze.monacoOptions)!=null?lt:{},qt=_k(We,At,Ze.width),Zt=(function(Xt){const ln=typeof Xt?.fontSize=="number"&&Xt.fontSize>0?Xt.fontSize:12;return typeof Xt?.lineHeight=="number"&&Xt.lineHeight>0?Xt.lineHeight:Math.round(1.5*ln)})(At),sn=(function(Xt,ln){var Fn,Pn;const Mi=typeof((Fn=Xt?.padding)==null?void 0:Fn.top)=="number"?Xt.padding.top:ln?0:8,Os=typeof((Pn=Xt?.padding)==null?void 0:Pn.bottom)=="number"?Xt.padding.bottom:ln?0:8;return Math.max(0,Mi)+Math.max(0,Os)})(At,it);ht=typeof At.MAX_HEIGHT=="number"&&At.MAX_HEIGHT>0?At.MAX_HEIGHT:500,mt=Math.round(qt*Zt+sn)}else if(rt==="markdown"){const At=_k(We);mt=Math.round(21*At+32)}else{const At=_k(We);mt=Math.round(28*At),ht=Number.POSITIVE_INFINITY}const Dt=Math.max(1,Math.min(mt,ht));return Mt({kind:"code-block",height:Math.round(Dt+(qe?40:0)),contentHeight:Dt,rendererKind:rt},it&&rt==="monaco"?{diffInline:V7((Ge=Ze.monacoOptions)!=null?Ge:{},(nt=Ze.width)!=null?nt:0)}:{})})(B,{rendererKind:De,monacoOptions:I.codeBlockMonacoOptions,showHeader:ZA(),width:fe})}return null}Zk(()=>{if(Ro.value,ot>0)return;const B=It.value,J=Er();if(!B.length||!Wi.value)return Gi=[],oo=[],qi=-1,so.clear(),void(vo.value=Zi);const fe=Y.value||Nt("estimatedNodeHeights.clientWidth",()=>{var Ge;return((Ge=R.value)==null?void 0:Ge.clientWidth)||0});if(!Number.isFinite(fe)||fe<=0)return Gi=[],oo=[],qi=-1,so.clear(),void(vo.value=Zi);const he=(function(Ge){return[Math.round(Ge),Mn.value,rs.value,oe.value,I.codeBlockMonacoOptions,ZA(),g.value,Yn.value,wk.value]})(fe),Ce=Gi.length<=B.length&&(We=he,(De=oo).length===We.length&&De.every((Ge,nt)=>Object.is(Ge,We[nt])));var De,We;const Ze=Ce&&qi===J?B.length:Ce?J9(B.length):0,lt=Ce?Array.from(so):[];Gi.length=B.length;for(let Ge=Ze;Ge<B.length;Ge++)Gi[Ge]=GA(B[Ge],Ge,fe);for(const Ge of lt)Ge>=0&&Ge<B.length&&Ge<Ze&&(Gi[Ge]=GA(B[Ge],Ge,fe));so.clear(),oo=he,qi=J,vo.value=Gi,lq(vo)},{flush:"sync"});const Mf=F(()=>vo.value);ii=(function(B){let J=!0,fe=[0],he="";function Ce(nt){var rt;const qe=B.nodeHeights[nt];if(Number.isFinite(qe)&&qe>0)return qe;const it=B.parsedNodes.value[nt],mt=it?.type,ht=!!((rt=B.hasCustomParagraphComponent)!=null&&rt.call(B)),Dt=B.estimatedNodeHeights.value[nt],At=Dt?.height;if(!(function(Zt,sn,Xt){return!!(Xt&&sn?.kind==="simple-text"&&(Zt==="paragraph"||Zt==="list_item"||Zt==="list"))})(mt,Dt,ht)&&Number.isFinite(At)&&At>0)return At;const qt=cNe(it,B.getContainerWidth()||640);return mt==="heading"||mt==="paragraph"&&qt<=28&&(function(Zt,sn){if(sn)return!1;const Xt=Zt.children;return!Array.isArray(Xt)||!Xt.length||Xt.every(CP)})(it,ht)?qt:Math.max(B.averageNodeHeight.value,qt)}function De(){var nt;const rt=B.parsedNodes.value.length,qe=B.getPrefixCacheKeyParts().join(":");if(!J&&he===qe)return fe;const it=new Array(rt+1);it[0]=0;for(let mt=0;mt<rt;mt++)it[mt+1]=it[mt]+(B.heightEstimationActive.value?Ce(mt):(nt=B.nodeHeights[mt])!=null?nt:B.averageNodeHeight.value);return fe=it,he=qe,J=!1,it}function We(nt){var rt,qe;const it=B.parsedNodes.value.length;if(it<=0||nt<=0)return 0;const mt=De();if(nt>=((rt=mt[it])!=null?rt:0))return it-1;let ht=0,Dt=it-1,At=it-1;for(;ht<=Dt;){const qt=ht+Dt>>1;((qe=mt[qt+1])!=null?qe:0)>=nt?(At=qt,Dt=qt-1):ht=qt+1}return At}function Ze(nt,rt){var qe,it;if(nt>=rt)return 0;if(B.heightEstimationActive.value)return(function(Dt,At){var qt,Zt;const sn=B.parsedNodes.value.length,Xt=GE(Math.trunc(Dt),0,sn),ln=GE(Math.trunc(At),Xt,sn);if(Xt>=ln)return 0;const Fn=De();return((qt=Fn[ln])!=null?qt:0)-((Zt=Fn[Xt])!=null?Zt:0)})(nt,rt);if(B.heightTreeSize.value!==B.parsedNodes.value.length){let Dt=0;for(let At=nt;At<rt;At++)Dt+=(qe=B.nodeHeights[At])!=null?qe:B.averageNodeHeight.value;return Dt}const mt=B.heightSumTree.value,ht=B.heightKnownTree.value;if(!mt.length||!ht.length){let Dt=0;for(let At=nt;At<rt;At++)Dt+=(it=B.nodeHeights[At])!=null?it:B.averageNodeHeight.value;return Dt}return B.fenwickRangeSum(mt,nt,rt)+(rt-nt-B.fenwickRangeSum(ht,nt,rt))*B.averageNodeHeight.value}function lt(nt){var rt;if(nt<=0)return 0;const qe=B.parsedNodes.value;if(B.heightEstimationActive.value)return We(nt);if(B.heightTreeSize.value===qe.length&&B.heightSumTree.value.length&&B.heightKnownTree.value.length){const mt=B.averageNodeHeight.value,ht=B.heightSumTree.value,Dt=B.heightKnownTree.value,At=Xt=>Xt<=0?0:B.fenwickRangeSum(ht,0,Xt)+(Xt-B.fenwickRangeSum(Dt,0,Xt))*mt;let qt=0,Zt=qe.length-1,sn=qe.length-1;for(;qt<=Zt;){const Xt=qt+Zt>>1;At(Xt+1)>=nt?(sn=Xt,Zt=Xt-1):qt=Xt+1}return sn}let it=nt;for(let mt=0;mt<qe.length;mt++){const ht=(rt=B.nodeHeights[mt])!=null?rt:B.averageNodeHeight.value;if(it<=ht)return mt;it-=ht}return Math.max(0,qe.length-1)}function Ge(){if(!B.heightEstimationActive.value)return 0;let nt=0;const rt=B.estimatedNodeHeights.value;for(let qe=0;qe<rt.length;qe++){if(!rt[qe])continue;const it=B.nodeHeights[qe];Number.isFinite(it)&&it>0||nt++}return nt}return{markFallbackHeightPrefixDirty:function(){J=!0},getFallbackNodeHeight:Ce,estimateHeightRange:Ze,estimateIndexForOffset:lt,estimateIndexForOffsetFromEnd:function(nt){var rt,qe;const it=B.parsedNodes.value;if(!it.length)return 0;if(nt<=0)return Math.max(0,it.length-1);if(B.heightEstimationActive.value){const ht=(rt=De()[it.length])!=null?rt:0;return We(Math.max(0,ht-nt))}if(B.heightTreeSize.value===it.length){const ht=Ze(0,it.length);return lt(Math.max(0,ht-nt))}let mt=nt;for(let ht=it.length-1;ht>=0;ht--){const Dt=(qe=B.nodeHeights[ht])!=null?qe:B.averageNodeHeight.value;if(mt<=Dt)return ht;mt-=Dt}return 0},getEstimatedNodeHeightCount:Ge,buildVirtualHeightSummary:function(nt){var rt;const qe=B.parsedNodes.value.length;return{totalNodes:qe,measuredCount:B.heightStats.count,estimatedCount:Ge(),averageNodeHeight:B.averageNodeHeight.value,topSpacerHeight:nt.topSpacerHeight,bottomSpacerHeight:nt.bottomSpacerHeight,estimatedTotalHeight:Ze(0,qe),width:(rt=nt.width)!=null?rt:B.getContainerWidth()}}}})({parsedNodes:It,nodeHeights:vt,heightStats:Pt,heightTreeSize:fn,heightSumTree:dn,heightKnownTree:ui,averageNodeHeight:Ln,heightEstimationActive:Jn,estimatedNodeHeights:Mf,getContainerWidth:Ni,hasCustomParagraphComponent:()=>!!Yn.value.paragraph,getPrefixCacheKeyParts:()=>{var B;const J=X1(Y.value||Nt("getFallbackHeightPrefix.clientWidth",()=>{var he;return((he=R.value)==null?void 0:he.clientWidth)||0})),fe=((B=i.virtualScroll)==null?void 0:B.measurementKey)==null?"":String(i.virtualScroll.measurementKey);return[It.value.length,Pt.count,Math.round(Pt.total),Math.round(100*Ln.value),fe,J,Jn.value?1:0,wk.value,V.value,Yn.value.paragraph?1:0]},fenwickRangeSum:v1}),Pe(()=>It.value.length,B=>{var J;ai(),B<=0?Yt():(B<fn.value&&(J=B,Rt(),Ve(()=>fi(J))),B!==fn.value&&Ui(B))},{immediate:!0});const WH=F(()=>{if(!Cn.value)return It.value.map((he,Ce)=>({node:he,index:Ce}));const B=It.value.length,J=zs(as.start,0,B),fe=zs(as.end,J,B);return It.value.slice(J,fe).map((he,Ce)=>({node:he,index:J+Ce}))}),t4=F(()=>Cn.value?Ss(0,Math.min(as.start,It.value.length)):0),n4=F(()=>{if(!Cn.value)return 0;const B=It.value.length;return Ss(Math.min(as.end,B),B)});function QA(){return ii.buildVirtualHeightSummary({topSpacerHeight:t4.value,bottomSpacerHeight:n4.value,width:ed()})}function qH(){const B=It.value,J=QA();return An(Mt({},J),{probe:{paragraphReady:!!oe.value.paragraph,listItemReady:!!oe.value.listItem,listWrapperOverhead:oe.value.listWrapperOverhead,headingReadyLevels:Object.entries(oe.value.headings).filter(([,fe])=>!!fe).map(([fe])=>Number(fe))},nodes:B.map((fe,he)=>{var Ce,De,We,Ze,lt,Ge,nt,rt,qe;return{index:he,type:fe.type,estimateKind:(De=(Ce=Mf.value[he])==null?void 0:Ce.kind)!=null?De:null,rendererKind:(Ze=(We=Mf.value[he])==null?void 0:We.rendererKind)!=null?Ze:null,estimatedHeight:(Ge=(lt=Mf.value[he])==null?void 0:lt.height)!=null?Ge:null,estimatedContentHeight:(rt=(nt=Mf.value[he])==null?void 0:nt.contentHeight)!=null?rt:null,measuredHeight:(qe=vt[he])!=null?qe:null}})})}function i4(){return i.indexKey!=null?String(i.indexKey):Ti.value?`virtual-${lo()}`:"markdown-renderer"}function YA(B){const J=String(B),fe=`${i4()}-`;if(!J.startsWith(fe))return null;const he=J.slice(fe.length).match(/^(\d+)(?:$|-)/);if(!he)return null;const Ce=Number(he[1]);return!Number.isInteger(Ce)||Ce<0||Ce>=It.value.length?null:Ce}function lo(){var B,J,fe;const he=(B=i.virtualScroll)==null?void 0:B.sessionKey;return String(he!=null&&he!==""?he:(fe=(J=i.indexKey)!=null?J:I.customId)!=null?fe:Lt)}function Vo(){var B;const J=(B=i.virtualScroll)==null?void 0:B.threadKey;return J==null||J===""?void 0:String(J)}const UH=F(()=>{var B,J,fe;return(fe=Vo())!=null?fe:String((J=(B=i.indexKey)!=null?B:I.customId)!=null?J:Lt)});function o4(B){var J;return(B??"")===((J=Vo())!=null?J:"")}function Ga(){var B,J,fe;return J=(B=i.virtualScroll)==null?void 0:B.measurementKey,fe=(function(){const he=g.value;return(function(Ce){var De,We;const Ze=Ce.renderer,lt=Ze==="monaco"?Ce.codeBlockMonacoOptions:void 0,Ge=Ce.codeBlockProps,nt=Ze==="shiki";return[Ce.isDark?"dark":"light",Ze==="monaco"?"code-rich":Ze==="pre"?"code-pre":"code-shiki",Ce.codeBlockStream===!1?"code-static":"code-stream",Ms(Ce.codeBlockMinWidth),Ms(Ce.codeBlockMaxWidth),...nt?[tEe((De=Ge?.themes)!=null?De:Ce.themes,(We=Ge?.langs)!=null?We:Ce.langs)]:[],Ms(lt?.fontSize),Ms(lt?.lineHeight),Ms(lt?.fontFamily),Ms(lt?.tabSize),Ms(lt?.MAX_HEIGHT),Ms(lt?.wordWrap),Ms(lt?.wrappingIndent),Ms(lt?.padding),Ms(Ge?.showHeader),Ms(Ge?.showCopyButton),Ms(Ge?.showExpandButton),Ms(Ge?.showPreviewButton),Ms(Ge?.showCollapseButton),Ms(Ge?.showFontSizeButtons)].join("\0")})({renderer:he,isDark:I.isDark,codeBlockStream:I.codeBlockStream,codeBlockMinWidth:I.codeBlockMinWidth,codeBlockMaxWidth:I.codeBlockMaxWidth,codeBlockMonacoOptions:he==="monaco"?I.codeBlockMonacoOptions:void 0,codeBlockProps:I.codeBlockProps,themes:he==="shiki"?I.themes:void 0,langs:he==="shiki"?I.langs:void 0})})(),[J==null?"":String(J),fe].join("\0")}function ed(){return Ni()}const Og=F(()=>X1(ed())),il=F(()=>[Ga(),Og.value].join("\0")),KH=F(()=>{var B;return Ti.value?["virtual",(B=Vo())!=null?B:"",lo(),il.value].join("\0"):i.indexKey});function If(){zA.value+=1}function s4(B){return!(!B||!Number.isInteger(B.index)||B.index<0||B.index>=It.value.length||B.sessionKey!==lo()||B.threadKey!==Vo()||B.layoutEpochKey!==il.value)}function JA(B){const J=String(B),fe=cr.get(J);return fe?s4(fe)?fe.index:null:YA(J)}function XA(B="async-node"){(us.size||cr.size)&&(us.clear(),cr.clear(),If(),Qi(B))}const Ef=hn(U8,null),r4={reportHeight(B,J){if(!an.value)return;const fe=JA(B);if(fe==null)return;const he=Te.get(fe);if(!he)return;const Ce=Number(J),De=Bi(fe,he);(function(We,Ze,lt={}){Ve(()=>ei(We,Ze,lt))})(fe,Number.isFinite(Ce)&&Ce>0?Math.max(Ce,De||0):De)},markPending(B){if(!an.value)return;const J=YA(B);J!=null&&(function(fe,he){var Ce;const De=cr.get(fe);if(De&&s4(De))return us.set(fe,Math.max(0,(Ce=us.get(fe))!=null?Ce:0)+1),If(),void Qi("async-node");us.set(fe,1),cr.set(fe,(function(We){return{index:We,sessionKey:lo(),threadKey:Vo(),layoutEpochKey:il.value}})(he)),If(),Qi("async-node")})(String(B),J)},markSettled(B){if(!an.value)return;const J=String(B),fe=JA(B);(fe!=null||(function(he){return us.has(String(he))})(J))&&(function(he){var Ce;const De=(Ce=us.get(he))!=null?Ce:0;return!(De<=0||(De<=1?(us.delete(he),cr.delete(he)):us.set(he,De-1),If(),De===1&&Qi("async-node"),0))})(J)&&fe!=null&&Qa()}};function VH(){let B=0;for(const J of Te.values())B+=Nt("getVisibleDomHeight.offsetHeight",()=>{var fe;return(fe=J?.offsetHeight)!=null?fe:0});return Math.ceil(Math.max(0,B))}oi(U8,{reportHeight(B,J){r4.reportHeight(B,J),Ef?.reportHeight(B,J)},markPending(B){r4.markPending(B),Ef?.markPending(B)},markSettled(B){r4.markSettled(B),Ef?.markSettled(B)}});let l4,a4=null,Tf=null;function Pg(B){return B!==!1&&B!=null&&B!==""}function eC(){return Cn.value?(function(){if(!Cn.value)return!0;const B=It.value.length,J=zs(as.start,0,B),fe=zs(as.end,J,B);if(J>=fe)return!0;for(let he=J;he<fe;he++)if(!jn.has(he)||qg(he)&&!Te.has(he))return!1;return!0})():Di.value>=Fg.value}function u4(){return _t.value===!0&&!$t.value&&Z9.value===0&&no.size===0&&Nn.size===0&&nl==null&&eC()}function tC(){var B,J;if(((B=i.virtualScroll)==null?void 0:B.settleMode)!=="manual"||a4===lo()&&l4===Vo())return!0;const fe=(J=i.virtualScroll)==null?void 0:J.settledToken;return!!Pg(fe)&&Tf===N1(fe)}function c4(){return u4()&&tC()}function ZH(B,J){return J.totalNodes<=0?B==="final"?"final":"estimate":J.measuredCount>=J.totalNodes?B==="final"?"final":"measured":J.measuredCount>0||J.estimatedCount>0?"mixed":"estimate"}function td(B="manual",J){const fe=QA(),he=(function(Ce){return Ce||(_t.value!==!0?It.value.length>0?"streaming":"estimating":!eC()||Nn.size>0||nl!=null?"measuring":c4()?"settled":"settling")})(J);return{sessionKey:lo(),threadKey:Vo(),phase:he,nodeCount:fe.totalNodes,liveRange:{start:as.start,end:as.end},renderedCount:Di.value,measuredCount:fe.measuredCount,estimatedCount:fe.estimatedCount,averageNodeHeight:fe.averageNodeHeight,topSpacerHeight:fe.topSpacerHeight,bottomSpacerHeight:fe.bottomSpacerHeight,visibleDomHeight:VH(),totalHeight:nC(),width:fe.width,final:_t.value===!0,stable:c4(),confidence:ZH(he,fe),reason:B}}function k1(){const B=Dn.value||ke(),J=R.value;if(!B||!J)return null;const fe=B.ownerDocument||J.ownerDocument||document,he=B===fe.documentElement||B===fe.body||B===fe.scrollingElement,Ce=Nt("getScrollBox.scrollTop",()=>Oe(B,fe,he)),De=Nt("getScrollBox.scrollHeight",()=>{var Ze,lt,Ge,nt,rt;return he?Math.max((lt=(Ze=fe.documentElement)==null?void 0:Ze.scrollHeight)!=null?lt:0,(nt=(Ge=fe.body)==null?void 0:Ge.scrollHeight)!=null?nt:0,(rt=B.scrollHeight)!=null?rt:0):B.scrollHeight}),We=Nt("getScrollBox.clientHeight",()=>{var Ze;return he?((Ze=fe.documentElement)==null?void 0:Ze.clientHeight)||B.clientHeight||0:B.clientHeight});return{root:B,doc:fe,isViewportRoot:he,scrollTop:Ce,scrollHeight:De,clientHeight:We}}function nC(){const B=It.value.length,J=Math.max(0,Ss(0,B)),fe=Nt("getRendererLogicalHeight.offsetHeight",()=>{var Ce,De;return(De=(Ce=R.value)==null?void 0:Ce.offsetHeight)!=null?De:0}),he=Math.max(0,fe>0?fe:Nt("getRendererLogicalHeight.scrollHeight",()=>{var Ce,De;return(De=(Ce=R.value)==null?void 0:Ce.scrollHeight)!=null?De:0}));return B<=0?Math.ceil(fe):Cn.value?J>0?Math.max(1,Math.ceil(J),(function(){let Ce=t4.value+n4.value;for(const De of jn.values())De&&(Ce+=Math.max(0,Nt("getVirtualizedDomLogicalHeight.offsetHeight",()=>De.offsetHeight||0)));return Math.ceil(Math.max(0,Ce))})(),(function(Ce,De){return Ce<=0||De<=0?0:De<=Ce+Math.max(512,.05*Ce)?Math.ceil(De):0})(J,he)):Math.max(1,Math.ceil(he)):an.value?J>0||Pt.count>0||ii.getEstimatedNodeHeightCount()>0?(Nr.value&&Di.value,Math.max(1,Math.ceil(he),Math.ceil(J))):Math.ceil(he):Math.max(1,Math.ceil(he),Math.ceil(J))}function iC(B){const J=R.value;if(!J)return null;const fe=Nt("getRendererBottomDistanceFromViewport.getBoundingClientRect",()=>J.getBoundingClientRect());return(function(Ce){return Ce.isViewportRoot?Ce.clientHeight:Nt("getViewportBottomInRoot.getBoundingClientRect",()=>Ce.root.getBoundingClientRect().bottom)})(B)-fe.bottom}function GH(B={}){const J=B.requireViewport!==!1,fe=(function(De=64){const We=k1(),Ze=R.value;if(!We||!Ze)return!1;const lt=(function(nt){if(nt.isViewportRoot)return{top:0,bottom:nt.clientHeight};const rt=Nt("getVirtualViewportRect.getBoundingClientRect",()=>nt.root.getBoundingClientRect());return{top:rt.top,bottom:rt.bottom}})(We),Ge=Nt("isRendererNearVirtualViewport.getBoundingClientRect",()=>Ze.getBoundingClientRect());return Ge.bottom>=lt.top-De&&Ge.top<=lt.bottom+De})();if(J&&!fe)return null;const he=(function(){const De=k1(),We=R.value;if(!De||!We||Math.max(0,De.scrollHeight-De.scrollTop-De.clientHeight)>64)return null;const Ze=iC(De);return Ze==null?null:Ze>=-8&&Ze<=160?{type:"bottom",distanceFromBottomPx:Math.max(0,Ze)}:null})();if(he)return{anchor:he,captured:!0};const Ce=Qe();if(Ce)return{anchor:{type:"node",nodeIndex:Ce.nodeIndex,offsetWithinNodePx:Ce.offsetWithinNodePx},captured:fe};if(B.allowFallback===!0){const De=(function(){const We=It.value.length;return We<=0?null:{type:"node",nodeIndex:zs(Al.value,0,Math.max(0,We-1)),offsetWithinNodePx:0}})();return De?{anchor:De,captured:!1}:null}return null}function d4(B){let J=2166136261;for(let fe=0;fe<B.length;fe++)J^=B.charCodeAt(fe),J=Math.imul(J,16777619);return(J>>>0).toString(36)}function QH(B,J){let fe=B;for(let he=0;he<J.length;he++)fe^=J.charCodeAt(he),fe=Math.imul(fe,16777619);return fe^=31,fe=Math.imul(fe,16777619),fe}const YH=new Set(["children","items","header","rows","cells","attrs","data","term","definition"]);function jg(B,J=new WeakSet,fe=0){if(B==null||typeof B=="number"||typeof B=="boolean")return String(B);if(typeof B=="string")return`s:${(function(he){const Ce=he.length>8192?`${he.slice(0,8192)}...${he.length}`:he;return`${he.length}:${d4(Ce)}`})(B)}`;if(typeof B=="function")return"fn";if(typeof B!="object")return typeof B;if(J.has(B))return"cycle";if(fe>=6)return"max-depth";J.add(B);try{if(Array.isArray(B)){if(B.length<=160){const Ge=[];for(let nt=0;nt<B.length;nt++)Ge.push(jg(B[nt],J,fe+1));return`a:${B.length}:${Ge.join(",")}`}const De=[],We=[],Ze=Math.max(0,B.length-32);let lt=2166136261;for(let Ge=0;Ge<B.length;Ge++){const nt=jg(B[Ge],J,fe+1);lt=QH(lt,nt),Ge<32&&De.push(nt),Ge>=Ze&&We.push(nt)}return[`a:${B.length}`,`h=${De.join(",")}`,`t=${We.join(",")}`,`all=${(lt>>>0).toString(36)}`].join(":")}const he=B,Ce=Object.keys(he).filter(De=>{const We=he[De];return De!=="parent"&&De!=="el"&&De!=="component"&&(We==null||typeof We=="string"||typeof We=="number"||typeof We=="boolean"||YH.has(De))}).sort();return`o:${Ce.length}:${Ce.map(De=>`${De}=${jg(he[De],J,fe+1)}`).join(";")}`}finally{J.delete(B)}}let f4=-1,h4="",nd=[2166136261];function b1(B){const J=It.value[B];return J?d4(jg(J)):""}function JH(B,J){let fe=B;for(let he=0;he<J.length;he++)fe^=J.charCodeAt(he),fe=Math.imul(fe,16777619);return fe>>>0}function p4(){var B,J;const fe=V.value;if(f4===fe)return h4;const he=It.value.length;let Ce=J9(he);(f4!==fe-1||Ce>he||nd.length<Ce+1)&&(Ce=0),Ce===0?nd=[2166136261]:nd.length=Ce+1;for(let De=Ce;De<he;De++){const We=b1(De);nd[De+1]=JH((B=nd[De])!=null?B:2166136261,We)}return nd.length=he+1,h4=(((J=nd[he])!=null?J:2166136261)>>>0).toString(36),f4=fe,h4}function Lf(B,J={}){var fe;const he=J.includeHeightCache===!0,Ce=(fe=J.includeContentHash)!=null?fe:he,De=he?(function(Ze){const lt=(function(){var ht,Dt;const At=Number((Dt=(ht=i.virtualScroll)==null?void 0:ht.heightCacheLimit)!=null?Dt:5e3);return!Number.isFinite(At)||At<=0?Number.POSITIVE_INFINITY:Math.max(1,Math.trunc(At))})();if(!Number.isFinite(lt)||Ze.length<=lt)return Ze;const Ge=new Map,nt=ht=>{!ht||Ge.size>=lt||Ge.set(ht.index,ht)},rt=It.value.length,qe=zs(as.start-2*Vi.value,0,rt),it=zs(as.end+2*Vi.value,qe,rt);for(const ht of Ze)ht.index>=qe&&ht.index<it&&nt(ht);const mt=Math.max(1,Math.ceil(Ze.length/lt));for(let ht=0;ht<Ze.length&&Ge.size<lt;ht+=mt)nt(Ze[ht]);for(let ht=Ze.length-1;ht>=0&&Ge.size<lt;ht-=mt)nt(Ze[ht]);return Array.from(Ge.values()).sort((ht,Dt)=>ht.index-Dt.index).slice(0,lt)})(ka().map(Ze=>{var lt;const Ge=It.value[Ze.index];return Ge?An(Mt({},Ze),{nodeType:String((lt=Ge.type)!=null?lt:""),signature:b1(Ze.index)}):null}).filter(Ze=>!!Ze)):[],We=GH({allowFallback:J.allowAnchorFallback===!0,requireViewport:J.requireViewport});return We||De.length||J.includeEmptyState===!0?An(Mt({sessionKey:B.sessionKey,threadKey:B.threadKey},We?{anchor:We.anchor,anchorCaptured:We.captured}:{anchorCaptured:!1}),{metrics:B,width:B.width,contentHash:Ce?p4():void 0,measurementKey:Ga()||void 0,heightCache:De.length?De:void 0}):null}function g4(B){var J,fe;const he=k1();if(!he)return;const Ce=(function(Ze){const lt=R.value;if(!lt)return null;const Ge=we(lt,Ze.root),nt=It.value.length,rt=Nt("getRendererBottomOffsetWithinRoot.offsetHeight",()=>lt.offsetHeight||0),qe=Math.max(0,rt>0?rt:nt>0?Nt("getRendererBottomOffsetWithinRoot.scrollHeight",()=>lt.scrollHeight||0):0),it=nC();return Ge+Math.max(qe,it)})(he);if(Ce==null)return;const De=Math.max(0,B.distanceFromBottomPx),We=Math.max(0,Ce-he.clientHeight-De);(function(Ze){xs=S1()+120,ro=Ze})(We),he.isViewportRoot?(fe=(J=he.doc.defaultView)==null?void 0:J.scrollTo)==null||fe.call(J,0,We):KE(he.root,he.doc,We,{isReverseFlexScrollRoot:Ie,getNormalizedScrollTop:Oe})}const m4=[];function oC(){if(Q)for(ws!=null&&(Fi?.(ws),ws=null);m4.length;){const B=m4.pop();B!=null&&window.clearTimeout(B)}}function Nf(B){const J=!!vn.value;vn.value=null,xs=0,ro=null,oC(),J&&B&&Qi(B)}function Ff(){if(!vn.value||!Q||ws!=null)return;const B=()=>{ws=null;const J=vn.value;J&&g4(J)};ws=ji?ji(B):null,ws==null&&B()}function sC(B,J={}){const fe=It.value.length;return fe<=0?[]:B.filter(he=>!(!Number.isInteger(he.index)||he.index<0||he.index>=fe)&&!(!Number.isFinite(he.height)||he.height<=0)&&!(J.requireSignature&&!he.signature)&&!(J.requireCompatibilityMetadata&&!he.nodeType&&!he.signature)&&(function(Ce){var De;const We=It.value[Ce.index];return!(!We||Ce.nodeType&&Ce.nodeType!==String((De=We.type)!=null?De:"")||Ce.signature&&Ce.signature!==b1(Ce.index))})(he))}function rC(B){const J=X1(ed()),fe=X1(B);return J!==-1&&fe!==-1&&J===fe}function v4(B){var J;const fe=Number(B?.width);if(Number.isFinite(fe)&&fe>0)return fe;const he=Number((J=B?.metrics)==null?void 0:J.width);return Number.isFinite(he)&&he>0?he:null}function lC(B){var J;return B.sessionKey===lo()&&!!o4(B.threadKey)&&((J=B.measurementKey)!=null?J:"")===Ga()&&!!rC(v4(B))&&!!(function(fe){const he=fe.heightCache;return!!he?.length&&(aC(fe)?he.some(Ce=>!!(Ce.nodeType||Ce.signature)):he.some(Ce=>!!Ce.signature))})(B)}function aC(B){return!!(B.contentHash&&B.contentHash===p4())}function XH(B){return!aC(B)}let id=null,od=null,Hg=null,A1=null,C1=null;function y4(B){var J;const fe=B.map(Ce=>{var De,We;return[Ce.index,Math.round(10*Ce.height),(De=Ce.nodeType)!=null?De:"",(We=Ce.signature)!=null?We:""].join("")}).join(""),he=X1(ed());return[(J=Vo())!=null?J:"",lo(),Ga(),It.value.length,he,B.length,d4(fe)].join(":")}function uC(B=(J=>(J=i.virtualScroll)==null?void 0:J.heightCache)()){if(!an.value||!B?.length||It.value.length<=0||!rC((J=i.virtualScroll)==null?void 0:J.heightCacheWidth))return!1;var J;const fe=sC(B,{requireSignature:!0});if(!fe.length)return!1;const he=y4(fe);return he===id?(od="standalone",!0):(Ko(fe,{mode:"merge"}),ai(),id=he,od="standalone",M1(),Qi("restore"),!0)}function k4(B,J={}){var fe,he,Ce;if(!an.value||!B||B.sessionKey!==lo()||!o4(B.threadKey)||It.value.length<=0)return!1;const De=!!((fe=B.heightCache)!=null&&fe.length)&&!Wg(),We=!B.anchor||B.anchorCaptured===!1&&J.allowUncapturedAnchor!==!0?null:B.anchor,Ze=J.restoreAnchor===!0&&!!We&&!Wg()&&Number(v4(B))>0;let lt=!1;if((he=B.heightCache)!=null&&he.length&&lC(B)){const nt=sC(B.heightCache,{requireCompatibilityMetadata:!B.contentHash,requireSignature:XH(B)});nt.length&&(Ko(nt,{mode:"merge"}),ai(),id=y4(nt),od="restore",M1(),lt=!0)}if(De||Ze)return!1;if(!J.restoreAnchor||!We)return lt&&Qi("restore"),!0;const Ge=(function(nt,rt){var qe;const it=nt.anchor,mt=it?it.type==="bottom"?`bottom:${Math.round(it.distanceFromBottomPx)}`:`node:${it.nodeIndex}:${Math.round(it.offsetWithinNodePx)}`:"none";return[(qe=Vo())!=null?qe:"",lo(),Ga(),Og.value,rt,mt].join(":")})(B,(Ce=J.restoreToken)!=null?Ce:"imperative");return Hg===Ge?(lt&&Qi("restore"),!0):(Hg=Ge,(function(nt){const rt=()=>{if(nt.type==="node")return Nf(),void Je({nodeIndex:nt.nodeIndex,offsetWithinNodePx:nt.offsetWithinNodePx});if(Me(),ur.value=null,vn.value=nt,oC(),g4(nt),Q)for(const qe of[0,120,280,480])m4.push(window.setTimeout(()=>{const it=vn.value;it&&g4(it)},qe))};(function(qe){if(!Cn.value)return!1;const it=It.value.length;return!(it<=0||(Al.value=qe.type==="node"?zs(qe.nodeIndex,0,it-1):it-1,Bu(),0))})(nt)?dt(rt):rt()})(We),Qi("restore"),!0)}function Wg(){const B=ed();return Number.isFinite(B)&&B>0}function cC(B){var J;return B.sessionKey===lo()&&!!o4(B.threadKey)&&(It.value.length<=0||!(!((J=B.heightCache)!=null&&J.length)||Wg())||!(!(B.anchor&&Number(v4(B))>0)||Wg()))}function b4(){rn.clear();for(const B of Object.keys(vt)){const J=Number(B);Number.isInteger(J)&&J>=0&&J<It.value.length&&wn(J)}}function w1(){nl!=null&&(Fi?.(nl),nl=null),E4()}function dC(){return!Q||As?Promise.resolve():new Promise(B=>{let J=!1,fe=null;const he=()=>{J||(J=!0,fe!=null&&window.clearTimeout(fe),B())};if(ji)return ji(he),void(fe=window.setTimeout(he,50));fe=window.setTimeout(he,0)})}function A4(B,J=Vo(),fe=il.value){return lo()===B&&Vo()===J&&il.value===fe}function C4(){return Ji(this,arguments,function*(B={}){var J,fe,he,Ce,De;const We=lo(),Ze=Vo(),lt=il.value,Ge=(J=B.frames)!=null?J:2,nt=(fe=B.timeoutMs)!=null?fe:120,rt=(he=B.reason)!=null?he:"manual",qe=B.expectedSettledTokenKey,it=B.flushPendingTimers===!0,mt=td(rt),ht=()=>An(Mt({},mt),{phase:mt.final?"settling":mt.phase,stable:!1,confidence:mt.confidence==="final"?"mixed":mt.confidence,reason:rt}),Dt=()=>A4(We,Ze,lt)&&(qe==null||_1()===qe);for(let sn=0;sn<Ge;sn++){if(yield dt(),!Dt()||(yield dC(),!Dt()))return ht();Qa(),w1()}if(yield(function(sn){return!Q||sn<=0?Promise.resolve():new Promise(Xt=>window.setTimeout(Xt,sn))})(nt),!Dt()||(it&&PA(),Qa(),w1(),!Dt()))return ht();const At=u4();At&&(a4=We,l4=Ze,((Ce=i.virtualScroll)==null?void 0:Ce.settleMode)==="manual"&&qe!=null&&Pg((De=i.virtualScroll)==null?void 0:De.settledToken)&&_1()===qe&&(Tf=N1(i.virtualScroll.settledToken)));const qt=Dt()&&At&&tC(),Zt=td(rt,qt?"final":void 0);return M4(Zt,!0),Zt})}let w4="content",sd=null,rd=null,x4=0,x1=null,Df=null,S4=null,_4=null;function S1(){return typeof performance<"u"&&typeof performance.now=="function"?performance.now():Date.now()}function fC(B){var J,fe;const he=x1;if(!he)return!0;const Ce=(fe=(J=i.virtualScroll)==null?void 0:J.heightDiffThresholdPx)!=null?fe:1;return Math.abs(B.totalHeight-he.totalHeight)>Ce||B.sessionKey!==he.sessionKey||B.phase!==he.phase||B.stable!==he.stable||B.final!==he.final||B.threadKey!==he.threadKey||B.nodeCount!==he.nodeCount||B.measuredCount!==he.measuredCount||B.width!==he.width}function _1(B=(J=>(J=i.virtualScroll)==null?void 0:J.settledToken)()){return Ms(B)}function hC(B,J){var fe,he;return[B,J.sessionKey,(fe=J.threadKey)!=null?fe:"",Ga(),p4(),Ms((he=i.virtualScroll)==null?void 0:he.settledToken),Math.round(J.totalHeight),Math.round(J.width)].join("\0")}function M1(){S4=null,_4=null,Df=null}function eW(B){const J=B.heightCache;return J?.length?y4(J):""}function I1(B){var J,fe,he;const Ce=B.metrics,De=B.anchor?(We=B.anchor).type==="bottom"?`bottom:${Math.round(We.distanceFromBottomPx)}`:`node:${We.nodeIndex}:${Math.round(We.offsetWithinNodePx)}`:"none";var We;return[B.sessionKey,(J=B.threadKey)!=null?J:"",(fe=B.measurementKey)!=null?fe:Ga(),(he=B.contentHash)!=null?he:"",eW(B),De,B.anchorCaptured?1:0,Ce.liveRange.start,Ce.liveRange.end,Ce.renderedCount,Ce.nodeCount,Math.round(Ce.totalHeight),Math.round(Ce.width),Ce.phase,Ce.stable?1:0].join("\0")}function M4(B,J=!1){if(!an.value||(function(We=!1){return!We&&Ti.value&&!to.value})(J))return;const fe=J||fC(B),he=(function(We,Ze=!1){return Ze||We.stable||We.phase==="final"?{state:Lf(We,{includeHeightCache:!0})}:{state:Lf(We)}})(B,J),Ce=he.state,De=!!(Ce&&(fe||(function(We,Ze=!1){return!!Ze||I1(We)!==Df})(Ce,J)));if(fe&&(z(B),x1=B,x4=S1()),Ce&&De&&(H(Ce),Ce.anchor&&O(Ce.anchor),Df=I1(Ce)),B.stable){const We=hC("settled",B);if(We!==S4){S4=We;const Ze=Lf(B,{includeHeightCache:!0});Ze&&(H(Ze),Df=I1(Ze)),(function(lt){o("render-settled",lt)})(B)}}if(B.phase==="final"){const We=hC("final",B);if(We!==_4){_4=We;const Ze=Lf(B,{includeHeightCache:!0});Ze&&(H(Ze),Df=I1(Ze)),(function(lt){o("render-final",lt)})(B)}}}function I4(){sd!=null&&(Fi?.(sd),sd=null),rd!=null&&Q&&(window.clearTimeout(rd),rd=null)}function pC(){sd=null,rd=null,(function(B){if(Nn.size>0||nl!=null)return!0;switch(B){case"node-resize":case"async-node":case"resize":case"restore":case"final":case"manual":return!0;default:return!1}})(w4)&&(Qa(),w1()),M4(td(w4))}function Qi(B){var J,fe;if(!an.value||(w4=B,sd!=null||rd!=null))return;const he=Math.max(0,(fe=(J=i.virtualScroll)==null?void 0:J.emitIntervalMs)!=null?fe:32),Ce=Math.max(0,he-(S1()-x4)),De=()=>{rd=null,sd=ji?ji(pC):null,sd==null&&pC()};Q&&Ce>0?rd=window.setTimeout(De,Ce):De()}function gC(){xe.value+=1}function qg(B){if(Nr.value&&B>=Di.value){const J=It.value[B],fe=ut.value===!0&&_t.value!==!0&&B>=It.value.length-2,he=J?.type==="code_block"||J?.type==="image"||J?.type==="mermaid"||J?.type==="infographic";if(!fe||he)return!1}return!ls.value||B<Lr.value||Q9.value.has(B)}function Bf(B){const J=$g.get(B);J&&(J(),$g.delete(B));const fe=_f.get(B);fe&&(fe.destroy(),_f.delete(B)),Rg(B)}function Ug(B,J){let fe=!1;if(J){const De=jn.get(B);jn.set(B,J),De!==J&&(fe=!0)}else jn.delete(B)&&(fe=!0);if(fe&&gC(),J||Rg(B),!Za.value||!Vn)return Bf(B),void(J&&ls.value&&$u(B,!0));if(!Cn.value&&ls.value&&!Z.value&&_f.size>=Ne.value&&(Z.value||(Z.value=!0,Y9()),!Za.value||!Vn))return Bf(B),void(J&&$u(B,!0));if(B<Lr.value&&!Cn.value||Q9.value.has(B))return Bf(B),void $u(B,!0);if(!J)return void Bf(B);Bf(B);const he=Vn(J,{rootMargin:pe.value});if(!he)return;_f.set(B,he),$u(B,he.isVisible.value),ls.value&&(function(De){if(!Q||!ls.value)return;Rg(De);const We=De%17*23,Ze=window.setTimeout(()=>{if(jA.delete(De),!ls.value||Q9.value.has(De))return;const lt=jn.get(De);if(!lt)return;const Ge=ke(lt),nt=lt.ownerDocument||document,rt=nt.defaultView||window,qe=!Ge||Ge===nt.documentElement||Ge===nt.body,it=!qe&&Ge?Nt("nodeVisibilityFallback.root.getBoundingClientRect",()=>Ge.getBoundingClientRect()):null,mt=qe?0:it.top,ht=qe?Nt("nodeVisibilityFallback.clientHeight",()=>{var At,qt;return(qt=(At=rt.innerHeight)!=null?At:Ge?.clientHeight)!=null?qt:0}):it.bottom,Dt=Nt("nodeVisibilityFallback.node.getBoundingClientRect",()=>lt.getBoundingClientRect());Dt.bottom>=mt-500&&Dt.top<=ht+500&&$u(De,!0)},1800+We);jA.set(De,Ze)})(B);let Ce=null;Ce=Pe(()=>he.isVisible.value,De=>{if(De){Rg(B),$u(B,!0),Ce?.(),$g.delete(B),_f.get(B)===he&&_f.delete(B);try{he.destroy()}catch{}}},{immediate:!0}),$g.set(B,Ce),Cn.value&&ql()}function E4(){nl=null,Ve(()=>{let B=!1;for(const[J,fe]of Nn)Nn.delete(J),Te.get(J)===fe.el&&ct.get(J)===fe.version&&(B=ei(J,fe.height,{allowShrink:fe.allowShrink})||B);return B})}function $f(){nl!=null&&(Fi?.(nl),nl=null),Nn.clear()}function Kg(B,J){(function(fe,he,Ce){var De;if(!Number.isFinite(Ce)||Ce<=0||Te.get(fe)!==he)return;const We=ct.get(fe);if(We==null)return;const Ze=It.value[fe],lt=$t.value&&_t.value!==!0&&!((De=i.nodes)!=null&&De.length)&&fe>=It.value.length-2,Ge=!(Ze?.loading===!0||lt),nt=Nn.get(fe),rt=nt?nt.allowShrink&&Ge:Ge,qe=nt&&!rt?Math.max(nt.height,Ce):Ce;Nn.set(fe,{height:qe,allowShrink:rt,version:We,el:he}),nl==null&&(nl=ji?ji(E4):null,nl==null&&E4())})(B,J,Bi(B,J))}function Qa(){for(const[B,J]of Te)J&&Kg(B,J)}function mC(){yt?.disconnect(),yt=null,Ke.clear()}function T4(){for(;Ht.length;)Bg(Ht.pop())}Pe(to,B=>{B&&Qi("content")},{flush:"post"}),t({getVirtualMetrics:td,captureVirtualState:function(B={}){var J;return Lf(td("manual"),{includeHeightCache:!0,includeContentHash:!0,allowAnchorFallback:B.allowFallbackAnchor===!0,requireViewport:B.requireViewport===!0,includeEmptyState:(J=B.includeEmptyState)==null||J})},restoreVirtualState:function(B,J={}){const fe=J.restoreAnchor===!0,he=J.restoreToken==null?"imperative":String(J.restoreToken);A1=B,C1={restoreAnchor:fe,restoreToken:he,allowUncapturedAnchor:J.allowUncapturedAnchor===!0},!k4(B,{restoreAnchor:fe,restoreToken:he,allowUncapturedAnchor:J.allowUncapturedAnchor===!0})&&cC(B)||(A1=null,C1=null)},forceMeasure:function(B="manual"){return Ji(this,null,function*(){yield dt(),yield dC(),Qa(),w1(),yield dt();const J=td(B);return M4(J,!0),J})},settle:C4,scrollToNode:function(B,J="start"){Nf(),Me();const fe=It.value.length;if(fe<=0)return;const he=zs(B,0,fe-1),Ce=()=>{var De;const We=me({nodeIndex:he,offsetWithinNodePx:0}),Ze=Ys(he),lt=k1(),Ge=(De=lt?.clientHeight)!=null?De:0,nt=tl();let rt=We;if(J==="center")rt=We-Ge/2+Ze/2;else if(J==="end")rt=We-Ge+Ze;else if(J==="nearest"&&nt!=null){if(We>=nt&&We+Ze<=nt+Ge)return;rt=We<nt?We:We-Ge+Ze}ee(Math.max(0,rt)),ql({immediate:!0}),Cn.value&&(Al.value=he,Bu())};if(Cn.value)return Al.value=he,Bu(),void dt(Ce);Ce()}}),Pe(()=>Rs.value,B=>{if(!B){mC();for(const J of at.values())for(const fe of J)Bg(fe);at.clear(),ct.clear(),T4(),$f()}},{immediate:!0}),Pe(_t,B=>{B&&(function(){if(Q&&_t.value&&Te.size){T4();for(const J of[80,240,640]){const fe=OA(J,()=>{for(const[he,Ce]of Te)Ce&&Kg(he,Ce)},"final");fe!=null&&Ht.push(fe)}}})(),Qi(B?"final":"content")});const tW=VE(()=>Qi("content"),16),nW=VE(()=>Qi("batch"),16);Pe([()=>It.value.length,()=>Di.value],()=>{vn.value&&Ff(),tW()},{flush:"post",immediate:!0}),Pe([()=>as.start,()=>as.end],()=>{nW()},{flush:"post"});const{cleanupBatchScheduler:iW}=(function(B){const{props:J,isClient:fe,isTestEnv:he,parsedNodesIdentity:Ce,parsedNodeCount:De,desiredRenderedCount:We,datasetKey:Ze,batchingEnabled:lt,incrementalRenderingActive:Ge,resolvedBatchSize:nt,resolvedInitialBatch:rt,renderedCount:qe,adaptiveBatchSize:it,previousRenderContext:mt,previousBatchConfig:ht,requestFrame:Dt,cancelFrame:At,hasIdleCallback:qt,cleanupNodeVisibility:Zt,onDatasetKeyChanged:sn,onDatasetChanged:Xt}=B;let ln=null,Fn="raf",Pn=null,Mi=0,Os=!1,_s=!1;const Ul=new Set,ba=new Set;function R1(){if(fe){ln!=null&&(Fn==="raf"&&At?At(ln):Fn==="idle"&&typeof window.cancelIdleCallback=="function"?window.cancelIdleCallback(ln):Fn==="timeout"&&window.clearTimeout(ln),ln=null),Mi+=1;for(const Xs of Ul)At&&At(Xs);for(const Xs of ba)window.clearTimeout(Xs);Ul.clear(),ba.clear(),Pn=null,Os=!1,_s=!1}}function tm(){return typeof performance<"u"?performance.now():Date.now()}function DC(Xs){(function(Ya){var zu;if(!Ge.value)return;const Ja=Math.max(2,(zu=J.renderBatchBudgetMs)!=null?zu:6),Xa=Math.max(1,nt.value||1),Kl=Math.max(1,Math.floor(Xa/4));Ya>1.5*Ja?it.value=Math.max(Kl,Math.floor(.8*it.value)):Ya<.6*Ja&&it.value<Xa&&(it.value=Math.min(Xa,Math.ceil(1.2*it.value)))})(Xs),Os=!1;const Br=_s||qe.value<We.value;_s=!1,Br&&RC()}function BC(Xs,Br={}){var Ya,zu;if(!Ge.value)return;const Ja=We.value;if(qe.value>=Ja)return;const Xa=Math.max(1,Xs),Kl=()=>{const Of=tm();ln=null;const z1=Pn??Xa;Pn=null;const Pf=tm();qe.value=Math.min(Ja,qe.value+z1),Zt(qe.value),(function(R4,nm){if(!fe)return void DC(nm);Os=!0;const zC=++Mi;dt().then(()=>{var OC;if(zC!==Mi)return;const xW=tm(),SW=Math.max(nm,xW-R4),PC=()=>{zC===Mi&&DC(SW)};if(Dt){let ad=null,jf=null,HC=!1;const WC=()=>{HC||(HC=!0,ad!==null&&(Ul.delete(ad),ad=null),jf!==null&&(ba.delete(jf),window.clearTimeout(jf),jf=null),PC())};return ad=Dt(()=>{WC()}),Ul.add(ad),jf=window.setTimeout(()=>{ad!==null&&At&&At(ad),WC()},Math.max(32,(OC=J.renderBatchIdleTimeoutMs)!=null?OC:120)),void ba.add(jf)}const jC=window.setTimeout(()=>{ba.delete(jC),PC()},0);ba.add(jC)})})(Of,tm()-Pf)};if(!fe||Br.immediate)return void Kl();const Ou=Math.max(0,(Ya=J.renderBatchDelay)!=null?Ya:16);if(Pn=Pn!=null?Math.max(Pn,Xa):Xa,ln==null){if(!he&&qt&&window.requestIdleCallback){const Of=Math.max(0,(zu=J.renderBatchIdleTimeoutMs)!=null?zu:120);return Fn="idle",void(ln=window.requestIdleCallback(()=>Kl(),{timeout:Of}))}if(Dt&&!he)return Fn="raf",void(ln=Dt(()=>{Ou===0?Kl():(Fn="timeout",ln=window.setTimeout(()=>Kl(),Ou))}));Fn="timeout",ln=window.setTimeout(()=>Kl(),Ou)}}function $C(Xs,Br={}){Os?_s=!0:Xs==null?RC():BC(Xs,Br)}function RC(){Ge.value&&BC(lt.value?Math.max(1,Math.round(it.value)):Math.max(1,nt.value))}return Pe([Ce,De,Ze,Ge,nt,rt,()=>J.renderBatchDelay],()=>{var Xs;const Br=De.value,Ya=mt.value,zu=Ze.value,Ja=!Object.is(zu,Ya.key),Xa=Br!==Ya.total,Kl=Ja||Xa;mt.value={key:zu,total:Br};const Ou=ht.value,Of=(Xs=J.renderBatchDelay)!=null?Xs:16,z1=Ou.batchSize!==nt.value||Ou.initial!==rt.value||Ou.delay!==Of||Ou.enabled!==Ge.value;ht.value={batchSize:nt.value,initial:rt.value,delay:Of,enabled:Ge.value},Ja&&sn(Br),(Kl||z1||!Ge.value)&&R1(),(Kl||z1)&&(it.value=Math.max(1,nt.value||1)),Kl&&Xt();const Pf=We.value;if(!Br)return qe.value=0,void Zt(0);if(!Ge.value)return qe.value=Pf,void Zt(qe.value);const R4=Ja||Ya.total===0;qe.value=R4||z1?Math.min(Pf,rt.value):Math.min(qe.value,Pf);const nm=Math.max(1,rt.value||nt.value||Br);qe.value<Pf?$C(nm,{immediate:!fe}):Zt(qe.value)},{immediate:!0}),Pe(We,(Xs,Br)=>{Ge.value&&(typeof Br=="number"&&Xs<=Br||Xs>qe.value&&$C())}),{cleanupBatchScheduler:R1}})({props:I,isClient:Q,isTestEnv:As,parsedNodesIdentity:mo,parsedNodeCount:vs,desiredRenderedCount:Fg,datasetKey:KH,batchingEnabled:jl,incrementalRenderingActive:Nr,resolvedBatchSize:Tr,resolvedInitialBatch:Lr,renderedCount:Di,adaptiveBatchSize:Cs,previousRenderContext:Xn,previousBatchConfig:Uo,requestFrame:ji,cancelFrame:Fi,hasIdleCallback:bs,cleanupNodeVisibility:PH,onDatasetKeyChanged:B=>{$f(),Yt(),ai(),M1(),B>0&&Ui(B)},onDatasetChanged:()=>{Cn.value&&ql({immediate:!0})}});Pe([Ng,Cn,()=>R.value,()=>te()],([B,J])=>{if(!B)return HA(),void G9();jH(),J?ql({immediate:!0}):G9()},{flush:"post",immediate:!0}),Pe([()=>It.value.length,()=>Cn.value],B=>Ji(null,[B],function*([J,fe]){fe&&J&&Q&&(yield dt(),ql({immediate:!0}))}),{flush:"post"}),Pe(Jn,B=>{B&&(function(){var J;if(_i.value&&Mo.value&&ys.value&&((J=Tn.value)!=null&&J[1]))return;const fe=St({type:"paragraph",children:[{type:"text",content:"Probe paragraph text",raw:"Probe paragraph text"}],raw:"Probe paragraph text"}),he=St({type:"list_item",children:[fe],raw:"- Probe paragraph text"}),Ce=St({type:"list",ordered:!1,items:[he],raw:"- Probe paragraph text"});_i.value=fe,Mo.value=he,ys.value=Ce;const De={1:null,2:null,3:null,4:null,5:null,6:null};for(let We=1;We<=6;We++)De[We]=St({type:"heading",level:We,text:"Probe heading",children:[{type:"text",content:"Probe heading",raw:"Probe heading"}],raw:`${"#".repeat(We)} Probe heading`});Tn.value=De})()},{immediate:!0}),Pe([()=>R.value,Jn],()=>{if(!Jn.value)return e4(),void(Y.value=0);qA(),e4(),Jn.value&&R.value&&typeof ResizeObserver<"u"&&(y1=new ResizeObserver(()=>{qA(),ur.value&&Re(),vn.value&&Ff(),Qi("resize")}),y1.observe(R.value))},{immediate:!0}),Pe([Jn,wi,il],()=>Ji(null,null,function*(){if(!Jn.value)return oe.value={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},void ai();yield dt(),(function(){if(!Jn.value||typeof window>"u")return oe.value={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},void ai();const B={paragraph:null,listItem:null,listWrapperOverhead:0,headings:{1:null,2:null,3:null,4:null,5:null,6:null}},J=WA(X9(j.value),".paragraph-node");B.paragraph=Mk(j.value,J,"pre-wrap");const fe=X9($.value),he=fe?.querySelector(".paragraph-node");B.listItem=Mk($.value,he,"pre-wrap");const Ce=Nt("readSimpleTextProbeProfile.list.offsetHeight",()=>{var We,Ze;return(Ze=(We=W.value)==null?void 0:We.offsetHeight)!=null?Ze:0}),De=Nt("readSimpleTextProbeProfile.listItem.offsetHeight",()=>{var We,Ze;return(Ze=(We=$.value)==null?void 0:We.offsetHeight)!=null?Ze:0});B.listWrapperOverhead=Math.max(0,Ce-De);for(let We=1;We<=6;We++){const Ze=WA(X9(P[We]),`h${We}`);B.headings[We]=Mk(P[We],Ze,"pre-wrap")}oe.value=B,ai()})()}),{flush:"post",immediate:!0}),Pe(()=>It.value.length,()=>{Cn.value&&ql({immediate:!0})}),Pe([Jn,Y],()=>{ai(),Cn.value&&ql({immediate:!0}),ur.value&&Re(),vn.value&&Ff(),Qi("resize")},{immediate:!1}),Pe(()=>ls.value,B=>{if(B)for(const[J,fe]of jn)Ug(J,fe);else if(Y9(),Cn.value)ql({immediate:!0});else for(const[J,fe]of jn)fe&&$u(J,!0)},{immediate:!1}),Pe([pe,Ne,()=>te()],()=>{var B;(B=Vn.refresh)==null||B.call(Vn);for(const[J,fe]of jn)Ug(J,fe)},{immediate:!1}),Pe([()=>I.viewportPriority,()=>It.value.length,Ne],([B,J,fe])=>{if(B!==!1){if(Z.value&&(J<=200||J<=fe)){Z.value=!1;for(const[he,Ce]of jn)Ug(he,Ce)}}else Z.value=!1}),Pe(()=>Di.value,()=>{Cn.value&&ql({immediate:!0})}),Pe([Al,$s,Vi,()=>It.value.length,Cn],()=>{Bu()},{immediate:!0});let E1=null,T1=!1,Rf=null;function L1(){E1=null,a4=null,l4=void 0,Tf=null,M1()}function L4(){$f(),Yt(),ai(),rn.clear();const B=It.value.length;B>0&&Ui(B),b4()}function N4(){I4(),PA(),x1=null,id=null,od=null,Hg=null,A1=null,C1=null,T1=!1,L1(),XA("restore"),Me(),Nf()}function N1(B){var J;return[(J=Vo())!=null?J:"",lo(),Ga(),Og.value,_1(B),It.value.length,Math.round(Ss(0,It.value.length)),Math.round(ed()),Pt.count,Math.round(Pt.total)].join(":")}function vC(){return Ji(this,null,function*(){var B,J,fe,he;const Ce=(B=i.virtualScroll)==null?void 0:B.settledToken,De=_1(Ce),We=lo(),Ze=Vo(),lt=il.value;if(an.value&&((J=i.virtualScroll)==null?void 0:J.settleMode)==="manual"&&Pg(Ce))if(u4()){if(N1(Ce)!==Tf&&!T1){T1=!0;try{const Ge=yield C4({reason:"manual",expectedSettledTokenKey:De}),nt=_1()===De;A4(We,Ze,lt)&&Ge.sessionKey===We&&Ge.threadKey===Ze&&nt&&Ge.stable&&Ge.phase==="final"&&(Tf=N1((fe=i.virtualScroll)==null?void 0:fe.settledToken))}finally{T1=!1,yield dt();const Ge=(he=i.virtualScroll)==null?void 0:he.settledToken,nt=Pg(Ge)?N1(Ge):"";A4(We,Ze,lt)&&nt&&Tf!==nt&&vC()}}}else Qi("manual")})}Pe(an,(B,J)=>{if(B!==J){if(!B)return N4(),void I4();N4(),L4(),Rf=il.value,Qi("content")}},{flush:"post"}),Pe([an,il],([B,J])=>{B?Rf!=null?Rf!==J&&(Rf=J,(function(fe="resize"){$f(),Yt(),ai(),rn.clear();const he=It.value.length;he>0&&Ui(he),b4(),id=null,od=null,Hg=null,x1=null,T1=!1,L1(),uC(),dt(()=>{Qa(),ur.value&&Re(),vn.value&&Ff(),Qi(fe)})})("resize")):Rf=J:Rf=null},{flush:"post",immediate:!0}),Pe([an,()=>lo(),()=>Vo()],([B])=>{B&&(N4(),L4(),XA("content"),Qi("content"))}),Pe([an,()=>lo(),()=>Vo(),il,()=>It.value.length],([B])=>{B&&(function(J="async-node"){let fe=!1;for(const[he,Ce]of Array.from(cr.entries()))s4(Ce)||(cr.delete(he),us.delete(he),fe=!0);fe&&(If(),Qi(J))})("async-node")},{flush:"post"}),Pe([an,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.sessionKey},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.measurementKey},()=>i.indexKey,()=>V.value],([B])=>{B&&(M1(),(function(J="content"){if(!an.value)return;const fe=[],he=It.value.length,Ce=J9(he);for(const De of Array.from(rn.keys())){if(De>=he){fe.push(De);continue}if(De<Ce)continue;const We=b1(De),Ze=rn.get(De);Ze!=null&&Ze!==We&&fe.push(De),rn.set(De,We)}for(const De of Array.from(rn.keys()))De>=he&&rn.delete(De);fe.length&&((function(De,We={}){const Ze=Array.from(De,Number);Se(Ze);let lt=0;if(Ve(()=>(lt=ya(Ze,We),lt>0)),lt>0)(function(Ge){for(const nt of Ge)rn.delete(nt)})(Ze);else for(const Ge of Ze)so.delete(Ge)})(fe,{notify:!1}),ai(),L1(),ur.value&&Re(),vn.value&&Ff(),Qi(J))})("content"))},{flush:"post",immediate:!0}),Pe([an,()=>It.value.length,()=>lo(),()=>Vo()],([B,J,fe,he],[Ce,De,We,Ze])=>{B&&Ce&&fe===We&&he===Ze&&J!==De&&L1()},{flush:"post"}),Pe([an,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.heightCache},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.heightCacheWidth},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.restoreState},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.measurementKey},()=>It.value.length,()=>lo(),Y],()=>{uC()},{flush:"post",immediate:!0}),Pe([an,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.restoreState},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.restoreAnchor},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.measurementKey},()=>It.value.length,()=>lo(),Y],B=>Ji(null,[B],function*([J,fe]){if(!J||!fe)return;yield dt();const he=(function(){var Ce;const De=(Ce=i.virtualScroll)==null?void 0:Ce.restoreAnchor;return De==null||De===!1?null:De===!0?"true":String(De)})();k4(fe,{restoreAnchor:he!=null,restoreToken:he??void 0})}),{flush:"post",immediate:!0}),Pe([an,Y,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.restoreState},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.measurementKey}],([B])=>{var J;if(!B)return;const fe=(J=i.virtualScroll)==null?void 0:J.restoreState;fe&&id&&od==="restore"&&(lC(fe)||(L4(),id=null,od=null,Qi("resize")))},{flush:"post"}),Pe([an,()=>It.value.length,()=>lo(),Y],B=>Ji(null,[B],function*([J]){var fe;const he=A1,Ce=C1;J&&he&&(yield dt(),!k4(he,{restoreAnchor:Ce?.restoreAnchor===!0,restoreToken:(fe=Ce?.restoreToken)!=null?fe:"imperative",allowUncapturedAnchor:Ce?.allowUncapturedAnchor===!0})&&cC(he)||(A1=null,C1=null))}),{flush:"post",immediate:!0}),Pe([an,_t,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.settleMode},()=>lo(),()=>Vo(),il,Z9,Wl,()=>Di.value,Fg,()=>Pt.count,()=>Pt.total],([B,J,fe])=>{if(!B||J!==!0||fe==="manual"||!c4())return;const he=(function(){var Ce;const De=It.value.length;return[(Ce=Vo())!=null?Ce:"",lo(),Ga(),Og.value,De,Math.round(Ss(0,De)),Math.round(ed()),Pt.count,Math.round(Pt.total)].join(":")})();E1!==he&&(E1=he,C4({reason:"final"}).then(Ce=>{Ce.stable||E1!==he||(E1=null)}))},{flush:"post",immediate:!0}),Pe([an,_t,()=>{var B;return(B=i.virtualScroll)==null?void 0:B.settleMode},()=>{var B;return(B=i.virtualScroll)==null?void 0:B.settledToken},()=>lo(),()=>Vo(),il,Z9,Wl,()=>Di.value,Fg,()=>It.value.length,()=>Pt.count,()=>Pt.total],()=>{vC()},{flush:"post",immediate:!0}),Pe([()=>It.value.length,Cn,$s,Vi,()=>as.start,()=>as.end],([B,J,fe,he,Ce,De])=>{Ae.value&&on("virtualization",{nodes:B,virtualization:J,maxLiveNodes:fe,buffer:he,focusIndex:Al.value,scroll:J?(()=>{const We=Dn.value||ke();return We?{reverse:Ie(We),scrollTop:Math.round(We.scrollTop),scrollTopAbs:Math.round(Math.abs(We.scrollTop)),scrollHeight:Math.round(We.scrollHeight),clientHeight:Math.round(We.clientHeight)}:null})():null,liveRange:{start:Ce,end:De},rendered:Di.value})}),Pe([()=>I.customId],([B],J,fe)=>{if(!B||Un)return;const he=(function(Ce,De){return Ce?(cs.controllers[Ce]=De,()=>{cs.controllers[Ce]===De&&delete cs.controllers[Ce]}):()=>{}})(B,{captureRestoreAnchor:Qe,restoreAnchor:Je,getAnchorDrift:ft,getReport:qH});fe(()=>{he()})},{immediate:!0}),Hn(()=>{(function(){if(an.value)try{Qa(),w1();const B=td("manual");fC(B)&&(z(B),x1=B,x4=S1());const J=Lf(B,{includeHeightCache:!0,includeContentHash:!0,allowAnchorFallback:!1,requireViewport:!0,includeEmptyState:!0});J&&(H(J),J.anchor&&O(J.anchor),Df=I1(J))}catch{}})(),iW(),Y9(),Ye(),mC();for(const B of at.values())for(const J of B)Bg(J);at.clear(),ct.clear(),rn.clear(),T4(),$f(),e4(),Me(),Nf(),I4(),HA(),G9()});const oW=Ip("ViewportDeferredMermaidBlockNode",ia({loader:()=>Ji(null,null,function*(){try{return(yield Fo(()=>import("./index11-DwTakJcU.js"),__vite__mapDeps([9,7]))).default}catch(B){return console.warn('[markstream-vue] Optional peer dependencies for MermaidBlockNode are missing. Falling back to preformatted code rendering. To enable Mermaid rendering, please install "mermaid".',B),jr}}),loadingComponent:lT,delay:0}),lT),sW=Ip("ViewportDeferredInfographicBlockNode",ia({loader:()=>Ji(null,null,function*(){try{return(yield Fo(()=>import("./index10-BqVmm7xb.js"),[])).default}catch(B){return console.warn('[markstream-vue] Failed to load InfographicBlockNode. Falling back to preformatted code rendering. To enable Infographic rendering, install "@antv/infographic" and configure setInfographicLoader with a dynamic loader.',B),jr}}),loadingComponent:rT,delay:0}),rT),rW=Ip("ViewportDeferredD2BlockNode",ia(()=>Ji(null,null,function*(){try{return(yield Fo(()=>import("./index8-Dz0AkV3W.js"),[])).default}catch(B){return console.warn('[markstream-vue] Optional peer dependencies for D2BlockNode are missing. Falling back to preformatted code rendering. To enable D2 rendering, please install "@terrastruct/d2".',B),jr}})),jr),yC={text:Bo,paragraph:Jd,heading:B9,code_block:vk,list:jh,list_item:Ph,blockquote:Rv,table:i0,definition_list:zv,footnote:Ov,footnote_reference:fl,footnote_anchor:t0,admonition:Wv,vmr_container:jv,hardbreak:kc,link:xr,image:yc,thematic_break:Pv,math_inline:ma,math_block:mP,strong:Cr,emphasis:Sr,strikethrough:wr,highlight:pl,insert:Zr,subscript:Vr,superscript:Kr,emoji:Ur,checkbox:dl,checkbox_input:dl,inline_code:rr,html_inline:hl,reference:Ar,html_block:n0},lW=F(()=>i4()),kC=F(()=>UE(I.codeBlockProps)),aW=F(()=>UE(I.codeBlockProps,{omit:["langs"]})),bC=F(()=>Mt(Mt({stream:I.codeBlockStream,darkTheme:I.codeBlockDarkTheme,lightTheme:I.codeBlockLightTheme,monacoOptions:I.codeBlockMonacoOptions,themes:I.themes,langs:g.value==="shiki"?I.langs:void 0,minWidth:I.codeBlockMinWidth,maxWidth:I.codeBlockMaxWidth},typeof se.value=="boolean"?{showTooltips:se.value}:{}),aW.value)),AC=F(()=>Mt(An(Mt({},bC.value),{langs:I.langs}),kC.value));function CC(B){return typeof B=="boolean"?B:void 0}const uW=F(()=>{const B=I.codeBlockProps||{},J={},fe=CC(B.showLineNumbers);fe!==void 0&&(J.showLineNumbers=fe);const he=CC(B.diffInline);he!==void 0&&(J.diffInline=he);const Ce=(function(De){const We=Number(De);return Number.isFinite(We)&&We>0?We:void 0})(B.reservedHeightPx);return Ce!==void 0&&(J.reservedHeightPx=Ce),J}),cW=F(()=>Mt(Mt({stream:I.codeBlockStream,darkTheme:I.codeBlockDarkTheme,lightTheme:I.codeBlockLightTheme,themes:I.themes,langs:I.langs,minWidth:I.codeBlockMinWidth,maxWidth:I.codeBlockMaxWidth},typeof se.value=="boolean"?{showTooltips:se.value}:{}),kC.value)),dW=F(()=>Mt({},I.mermaidProps||{})),wC=F(()=>Mt({},I.d2Props||{})),fW=F(()=>Mt({},I.infographicProps||{})),F1=F(()=>({typewriter:h.value,fade:I.fade,customHtmlTags:_o.value.customHtmlTags})),hW=F(()=>Mt(Mt({},F1.value),typeof se.value=="boolean"?{showTooltip:se.value}:{})),pW=F(()=>Mt(Mt({},F1.value),typeof se.value=="boolean"?{showTooltips:se.value}:{})),gW=F(()=>Mt(Mt({},F1.value),typeof se.value=="boolean"?{showTooltips:se.value}:{})),mW=F(()=>Mt(Mt({},F1.value),typeof se.value=="boolean"?{showTooltips:se.value}:{}));function vW(B){return Array.isArray(B.children)&&B.children.length>0}const Vg=F(()=>WH.value.map(B=>{var J,fe,he,Ce,De,We,Ze,lt;let Ge=(function(At){var qt,Zt,sn,Xt,ln,Fn,Pn;if(At.type!=="code_block")return At;const Mi=At,Os=[String((qt=Mi.language)!=null?qt:""),String((Zt=Mi.loading)!=null?Zt:""),String((sn=Mi.diff)!=null?sn:""),String((Xt=Mi.code)!=null?Xt:""),String((ln=Mi.originalCode)!=null?ln:""),String((Fn=Mi.updatedCode)!=null?Fn:""),String((Pn=Mi.raw)!=null?Pn:"")].join("\0"),_s=xt.get(Mi);if(_s&&_s.signature===Os)return _s.node;const Ul=Mt({},Mi);return xt.set(Mi,{signature:Os,node:Ul}),Ul})(B.node);const nt=Zg(Ge);let rt=MC(Ge,nt);if((Ge.type==="html_block"||Ge.type==="html_inline")&&rt===yC[Ge.type]){const At=Ge,qt=String((J=At.tag)!=null?J:"").trim().toLowerCase()||jz(At.content);if(qt){const Zt=Yn.value[qt];if(Ir.value.has(qt)&&Zt)rt=Zt,Ge=An(Mt({},At),{type:qt,tag:qt,content:xwe(At.content,qt)});else if(Hz((fe=At.content)!=null?fe:At.raw,qt)){const sn=String((Ce=(he=At.content)!=null?he:At.raw)!=null?Ce:"");Ge.type==="html_inline"?(rt=Bo,Ge={type:"text",content:sn,raw:sn}):(rt=Jd,Ge={type:"paragraph",children:[{type:"text",content:sn,raw:sn}],raw:sn})}}}const qe=Ge.type==="code_block"&&g.value==="pre"&&rt===jr&&!F4(Yn.value,nt);let it=Mt({},(function(At,qt,Zt){const sn=qt??Zg(At);if(At.type==="code_block"){const Xt=sn?F4(Yn.value,sn):void 0;if(Zt&&g.value==="pre"&&!Xt&&Zt===jr)return uW.value;if(Zt&&sn&&Zt===Xt)return sn==="mermaid"?SC(At):sn==="infographic"?_C(At):sn==="d2"||sn==="d2lang"?wC.value:AC.value;if(Zt&&Zt===Yn.value.code_block)return AC.value;if(KA(Zt))return cW.value}return sn==="mermaid"?SC(At):sn==="infographic"?_C(At):sn==="d2"||sn==="d2lang"?wC.value:At.type==="link"?hW.value:At.type==="list"?pW.value:At.type==="blockquote"?gW.value:At.type==="table"?mW.value:At.type==="code_block"?bC.value:F1.value})(Ge,nt,rt));const mt=Jn.value?Mf.value[B.index]:null;Ge.type==="code_block"&&mt?.kind==="code-block"&&(it=An(Mt({},it),qe?{reservedHeightPx:(De=mt.height)!=null?De:mt.contentHeight}:{estimatedHeightPx:mt.height,estimatedContentHeightPx:mt.contentHeight,estimatedDiffInline:mt.diffInline})),qe||Ge.type!=="code_block"||nt!=="mermaid"||kh(it.estimatedPreviewHeightPx)!=null||(it=An(Mt({},it),{estimatedPreviewHeightPx:dy(uy(String((We=Ge.code)!=null?We:"")))})),qe||Ge.type!=="code_block"||nt!=="infographic"||kh(it.estimatedPreviewHeightPx)!=null||(it=An(Mt({},it),{estimatedPreviewHeightPx:fy(cy(String((Ze=Ge.code)!=null?Ze:"")))})),Ge.type==="math_block"&&(it=An(Mt({},it),{cacheScope:So}));const ht=(function(At,qt){const Zt=String(At.type);return!Cg(Zt)&&Yn.value[Zt]===qt})(Ge,rt),Dt=ht?W7(Ge,re.value):void 0;return An(Mt({},B),{node:Ge,component:rt,bindings:it,customBindings:Mt(Mt({},Dt??{}),it),rendersCustomNode:ht,hasSlotChildren:vW(Ge),slotContent:String((lt=Ge.content)!=null?lt:""),isCodeBlock:Ge.type==="code_block",indexKey:`${lW.value}-${B.index}`,vnodeKey:`${UH.value}\0${B.index}\0${Ge.type}`})}));function Zg(B){var J;return B?.type==="code_block"?String((J=B.language)!=null?J:"").trim().toLowerCase():""}function F4(B,J){const fe=J.trim().toLowerCase();if(fe)for(const he of[fe,N9(fe),JO(fe)]){const Ce=he&&B[he];if(Ce)return Ce}}function xC(B,J,fe,he){var Ce,De;const We=Mt({},B.value);return kh(We.estimatedPreviewHeightPx)==null&&(We.estimatedPreviewHeightPx=he(fe(String((Ce=J?.code)!=null?Ce:"")),void 0,We.maxHeight==="none"?null:(De=kh(We.maxHeight))!=null?De:void 0)),We}function SC(B){return xC(dW,B,uy,dy)}function _C(B){return xC(fW,B,cy,fy)}function MC(B,J){if(!B)return i5;const fe=Yn.value,he=fe[String(B.type)];if(B.type==="code_block"){const Ce=J??Zg(B),De=Ce?F4(fe,Ce):void 0;return De||(g.value==="pre"?fe.code_block||jr:Ce==="mermaid"?fe.mermaid||oW:Ce==="infographic"?fe.infographic||sW:Ce==="d2"||Ce==="d2lang"?fe.d2||rW:he||fe.code_block||VA.value)}return he||yC[String(B.type)]||i5}function D4(B){o("click",B)}function yW(B){var J;(J=B.target)!=null&&J.closest("[data-node-index]")&&o("mouseover",B)}function kW(B){var J;(J=B.target)!=null&&J.closest("[data-node-index]")&&o("mouseout",B)}function IC(B){o("mouseover",B)}function EC(B){o("mouseout",B)}const ld=K(null),Dr=K(!1),D1=K(null),bW=F(()=>!(I.domMode!=="minimal"||ue.value||I.fade!==!1||h.value||Dr.value||On.value||Cn.value||Qs.value||Io.value||yi.value||Object.keys(Yn.value).length!==0));let B1,zf=null,B4=0,Gg=0,Qg=0;const TC=["code_block","admonition","table","math_block","html_block","image","thematic_break"],AW=new Set(TC),LC=[".typewriter-cursor",".height-estimation-probes",...TC.map(B=>`[data-node-type="${B}"]`),"script","style"].join(",");function NC(B){if(!B||typeof B!="object")return!1;const J=B.type;return typeof J=="string"&&AW.has(J)}function Yg(B){var J,fe;if(!B||typeof B!="object")return 0;const he=B,Ce=(fe=(J=he.raw)!=null?J:he.content)!=null?fe:he.code;if(typeof Ce=="string")return Ce.length;const De=he.children;if(Array.isArray(De))return De.reduce((Ze,lt)=>Ze+Yg(lt),0);const We=he.items;return Array.isArray(We)?We.reduce((Ze,lt)=>Ze+Yg(lt),0):0}function Jg(){B1&&(clearTimeout(B1),B1=void 0)}function $4(){B4+=1,zf!=null&&(Fi?.(zf),zf=null)}function $1(){$4(),Ru(),ld.value&&(ld.value.style.visibility="hidden")}function CW(B){var J;if(B.nodeType!==Node.TEXT_NODE||!((J=B.textContent)!=null?J:"").trim())return!1;const fe=B.parentElement;return!!fe&&!fe.closest(LC)}function wW(B){let J=B.lastChild;for(;J;){if(CW(J))return J;if(J.nodeType===Node.ELEMENT_NODE){const fe=J;if(!fe.matches(LC)&&fe.lastChild){J=fe.lastChild;continue}}for(;J&&J!==B&&!J.previousSibling;)J=J.parentNode;if(!J||J===B)break;J=J.previousSibling}return null}function FC(){const B=Vg.value;for(let J=B.length-1;J>=0;J--){const fe=B[J];if(!fe||NC(fe.node)||!qg(fe.index))continue;const he=jn.get(fe.index);if(!he)continue;const Ce=wW(he);if(Ce)return Ce}return null}function Ru(){D1.value&&(D1.value.classList.remove(aT),D1.value=null)}function Xg(){if(d.value!=="simple"||!Q||!Dr.value||!R.value)return void Ru();const B=FC(),J=B?(function(fe){var he;const Ce=(he=fe.parentElement)==null?void 0:he.closest(".text-node");return Ce instanceof HTMLElement?Ce:fe.parentElement})(B):null;J!==D1.value&&(Ru(),J&&(J.classList.add(aT),D1.value=J))}function em(){if(d.value!=="precise"||!Q||!Dr.value||zf!=null)return;const B=B4,J=()=>{zf=null,B===B4&&(function(){var fe,he;if(d.value!=="precise"||!(Q&&Dr.value&&R.value&&ld.value))return;const Ce=R.value,De=ld.value;De.style.visibility="hidden";const We=FC();if(!We)return;let Ze=0,lt=0,Ge=20,nt=!1;if(We?.textContent){const rt=We.textContent.length,qe=document.createRange();qe.setStart(We,Math.max(0,rt-1)),qe.setEnd(We,rt);const it=typeof qe.getClientRects=="function"?qe.getClientRects():void 0,mt=(he=it?.[it.length-1])!=null?he:(fe=We.parentElement)==null?void 0:fe.getBoundingClientRect();if(mt){const ht=Nt("typewriterCursor.root.getBoundingClientRect",()=>Ce.getBoundingClientRect());Ze=mt.right-ht.left+Ce.scrollLeft,lt=mt.top-ht.top+Ce.scrollTop,Ge=mt.height||Ge,nt=!0}qe.detach()}nt&&(De.style.transform=`translate(${Math.max(0,Ze)}px, ${Math.max(0,lt)}px)`,De.style.height=`${Ge}px`,De.style.visibility="visible")})()};ji?zf=ji(J):J()}return Pe([tt,()=>i.content,()=>i.nodes,()=>I.typewriter,_t],()=>Ji(null,null,function*(){var B,J;if(!Q||ue.value||!le.value)return;if(_t.value)return Dr.value=!1,Jg(),void $1();if((B=i.nodes)!=null&&B.length)return Dr.value=!1,Jg(),$1(),Gg=((J=i.content)!=null?J:"").length,void(Qg=tt.value.length);const fe=(function(){var Ze,lt;return(Ze=i.nodes)!=null&&Ze.length?i.nodes.reduce((Ge,nt)=>Ge+Yg(nt),0):((lt=i.content)!=null?lt:"").length})(),he=(function(){var Ze;return(Ze=i.nodes)!=null&&Ze.length?i.nodes.reduce((lt,Ge)=>lt+Yg(Ge),0):tt.value.length})(),Ce=!NC(It.value[It.value.length-1]),De=fe>Gg,We=he>Qg;if(!h.value||!Ce||!De&&!We)return h.value&&Ce||(Dr.value=!1,$1()),Gg=fe,void(Qg=he);Gg=fe,Qg=he,Dr.value=!0,d.value==="precise"&&ld.value&&(ld.value.style.visibility="hidden"),Jg(),yield dt(),d.value==="simple"?Xg():(Ru(),em()),B1=setTimeout(()=>{B1=void 0,Dr.value=!1},3e3)}),{flush:"post",immediate:!0}),Pe(Dr,B=>Ji(null,null,function*(){B?(yield dt(),d.value!=="simple"?(Ru(),d.value==="precise"&&em()):Xg()):$1()}),{flush:"post"}),Pe(d,()=>Ji(null,null,function*(){if(Q&&!ue.value&&le.value&&Dr.value){if(yield dt(),d.value==="simple")return $4(),void Xg();Ru(),d.value!=="precise"?$1():em()}}),{flush:"post"}),Pe([()=>Di.value,()=>as.start,()=>as.end],()=>Ji(null,null,function*(){Q&&!ue.value&&le.value&&Dr.value&&(yield dt(),d.value!=="simple"?(Ru(),d.value==="precise"&&em()):Xg())}),{flush:"post"}),Hn(()=>{Jg(),$4(),Ru(),qn.clear()}),(B,J)=>{const fe=tU("NodeRenderer",!0);return f(ue)?(v(!0),E(Ee,{key:0},pt(Vg.value,he=>(v(),E(Ee,{key:he.vnodeKey},[he.rendersCustomNode?(v(),ce(Oo(he.component),ni({key:0,ref_for:!0},he.customBindings,{node:he.node,loading:he.node.loading,"index-key":he.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onClick:D4,onMouseover:IC,onMouseout:EC,onCopy:J[0]||(J[0]=Ce=>s(Ce)),onHandleArtifactClick:J[1]||(J[1]=Ce=>o("handleArtifactClick",Ce))}),{default:de(()=>[he.hasSlotChildren?(v(),ce(fe,ni({key:0,ref_for:!0},go.value,{nodes:he.node.children,"index-key":he.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):he.slotContent?(v(),ce(fe,ni({key:1,ref_for:!0},go.value,{content:he.slotContent,final:!he.node.loading,"index-key":`${he.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):X("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(v(),ce(Oo(he.component),ni({key:1,node:he.node,loading:he.node.loading,"index-key":he.indexKey},{ref_for:!0},he.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onClick:D4,onMouseover:IC,onMouseout:EC,onCopy:J[2]||(J[2]=Ce=>s(Ce)),onHandleArtifactClick:J[3]||(J[3]=Ce=>o("handleArtifactClick",Ce))}),null,16,["node","loading","index-key","custom-id","is-dark"]))],64))),128)):(v(),E("div",{key:1,ref_key:"containerRef",ref:R,class:Fe(["markstream-vue markdown-renderer",[{dark:I.isDark},{virtualized:Cn.value},{"virtual-scroll-coordinated":to.value},{"stable-layout":V9.value},{"typewriter-simple-cursor":Dr.value&&d.value==="simple"}]]),"data-custom-id":I.customId,onClick:D4,onMouseover:yW,onMouseout:kW},[Wo.value||Cn.value?(v(),E(Ee,{key:0},[Wo.value?(v(),ce(ENe,{key:0,width:wi.value,"flow-root":Cn.value||to.value,"paragraph-node":_i.value,"list-item-node":Mo.value,"list-node":ys.value,"heading-nodes":Tn.value,"set-paragraph-wrapper":RH,"set-list-item-wrapper":zH,"set-list-wrapper":OH,"set-heading-wrapper":HH},null,8,["width","flow-root","paragraph-node","list-item-node","list-node","heading-nodes"])):X("",!0),Cn.value?(v(),E("div",{key:1,class:"node-spacer",style:Kt({height:`${t4.value}px`}),"aria-hidden":"true"},null,4)):X("",!0)],64)):X("",!0),bW.value?(v(!0),E(Ee,{key:1},pt(Vg.value,he=>(v(),E(Ee,{key:he.vnodeKey},[qg(he.index)?(v(),ce(Oo(he.component),ni({key:0,node:he.node,loading:he.node.loading,"index-key":he.indexKey},{ref_for:!0},he.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onMouseover:J[4]||(J[4]=Ce=>o("mouseover",Ce)),onMouseout:J[5]||(J[5]=Ce=>o("mouseout",Ce)),onCopy:J[6]||(J[6]=Ce=>s(Ce)),onHandleArtifactClick:J[7]||(J[7]=Ce=>o("handleArtifactClick",Ce))}),null,16,["node","loading","index-key","custom-id","is-dark"])):X("",!0)],64))),128)):(v(!0),E(Ee,{key:2},pt(Vg.value,he=>(v(),E("div",{key:he.vnodeKey,ref_for:!0,ref:Ce=>Ug(he.index,Ce),class:"node-slot","data-node-index":he.index,"data-node-type":he.node.type},[qg(he.index)?(v(),E("div",{key:0,ref_for:!0,ref:Ce=>(function(De,We){var Ze;We||(function(rt){const qe=`${i4()}-${rt}`;let it=!1;for(const mt of Array.from(us.keys())){const ht=cr.get(mt);(ht?.index===rt||mt===qe||mt.startsWith(`${qe}-`))&&(us.delete(mt),cr.delete(mt),it=!0)}it&&(If(),Qi("async-node"))})(De),Nn.delete(De),(function(rt){var qe;const it=((qe=ct.get(rt))!=null?qe:0)+1;ct.set(rt,it)})(De);const lt=at.get(De);if(lt){for(const rt of lt)Bg(rt);at.delete(De)}if((function(rt){const qe=Ke.get(rt);qe&&(yt?.unobserve(qe),Ue.delete(qe),Ke.delete(rt))})(De),!We||!Rs.value)return Te.delete(De),void ct.delete(De);Te.set(De,We);const Ge=()=>{Kg(De,We)};queueMicrotask(Ge);const nt=(yt||typeof ResizeObserver>"u"||(yt=new ResizeObserver(rt=>{if(rt.length)for(const qe of rt){const it=Ue.get(qe.target),mt=Ke.get(it??-1);it!=null&&mt&&Kg(it,mt)}else Qa()})),yt);if(nt&&(Ke.set(De,We),Ue.set(We,De),nt.observe(We)),typeof window<"u"){const rt=((Ze=It.value[De])==null?void 0:Ze.type)==="code_block"?[16,80,240,800]:_t.value?[80]:[];if(rt.length){const qe=rt.map(it=>OA(it,Ge,"node-resize")).filter(it=>it!=null);qe.length&&at.set(De,qe)}}})(he.index,Ce),class:"node-content"},[he.isCodeBlock?he.rendersCustomNode?(v(),ce(Oo(he.component),ni({key:1,ref_for:!0},he.customBindings,{node:he.node,loading:he.node.loading,"index-key":he.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onCopy:J[12]||(J[12]=Ce=>s(Ce)),onHandleArtifactClick:J[13]||(J[13]=Ce=>o("handleArtifactClick",Ce))}),{default:de(()=>[he.hasSlotChildren?(v(),ce(fe,ni({key:0,ref_for:!0},go.value,{nodes:he.node.children,"index-key":he.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):he.slotContent?(v(),ce(fe,ni({key:1,ref_for:!0},go.value,{content:he.slotContent,final:!he.node.loading,"index-key":`${he.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):X("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(v(),ce(Oo(he.component),ni({key:2,node:he.node,loading:he.node.loading,"index-key":he.indexKey},{ref_for:!0},he.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onCopy:J[14]||(J[14]=Ce=>s(Ce)),onHandleArtifactClick:J[15]||(J[15]=Ce=>o("handleArtifactClick",Ce))}),null,16,["node","loading","index-key","custom-id","is-dark"])):(v(),ce(fo,{key:0,name:"fade",css:I.fade!==!1,appear:I.fade!==!1},{default:de(()=>[he.rendersCustomNode?(v(),ce(Oo(he.component),ni({key:0,ref_for:!0},he.customBindings,{node:he.node,loading:he.node.loading,"index-key":he.indexKey,"custom-id":I.customId,"is-dark":I.isDark,onCopy:J[8]||(J[8]=Ce=>s(Ce)),onHandleArtifactClick:J[9]||(J[9]=Ce=>o("handleArtifactClick",Ce))}),{default:de(()=>[he.hasSlotChildren?(v(),ce(fe,ni({key:0,ref_for:!0},go.value,{nodes:he.node.children,"index-key":he.indexKey,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["nodes","index-key"])):he.slotContent?(v(),ce(fe,ni({key:1,ref_for:!0},go.value,{content:he.slotContent,final:!he.node.loading,"index-key":`${he.indexKey}-content`,"smooth-streaming":!1,"batch-rendering":!1,"defer-nodes-until-visible":!1,"render-as-fragment":!0}),null,16,["content","final","index-key"])):X("",!0)]),_:2},1040,["node","loading","index-key","custom-id","is-dark"])):(v(),ce(Oo(he.component),ni({key:1,node:he.node,loading:he.node.loading,"index-key":he.indexKey},{ref_for:!0},he.bindings,{"custom-id":I.customId,"is-dark":I.isDark,onCopy:J[10]||(J[10]=Ce=>s(Ce)),onHandleArtifactClick:J[11]||(J[11]=Ce=>o("handleArtifactClick",Ce))}),null,16,["node","loading","index-key","custom-id","is-dark"]))]),_:2},1032,["css","appear"]))],512)):(v(),E("div",{key:1,class:"node-placeholder",style:Kt({height:`${Ys(he.index)}px`})},null,4))],8,NNe))),128)),Dr.value&&d.value==="precise"?(v(),E("span",{key:3,ref_key:"typewriterCursorRef",ref:ld,class:"typewriter-cursor","aria-hidden":"true"},null,512)):X("",!0),Cn.value?(v(),E("div",{key:4,class:"node-spacer",style:Kt({height:`${n4.value}px`}),"aria-hidden":"true"},null,4)):X("",!0)],42,LNe))}}})),[["__scopeId","data-v-a9489508"]]),Gr=TP;Gr.install=e=>{const t=new Set(["MarkdownRender","NodeRenderer",Gr.__name,Gr.name].filter(n=>!!n));for(const n of t)e.component(n,TP)};const iA=Object.freeze(Object.defineProperty({__proto__:null,default:Gr},Symbol.toStringTag,{value:"Module"})),FNe={key:0,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},DNe={key:1,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},BNe={key:2,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},$Ne={key:3,xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round",class:"admonition-icon"},RNe={class:"admonition-title"},zNe=["aria-expanded","aria-controls"],ONe=["id"],Wv=Ci(Xe({__name:"AdmonitionNode",props:{node:{},indexKey:{},isDark:{type:Boolean},typewriter:{type:Boolean},fade:{type:Boolean},customId:{}},emits:["copy"],setup(e,{emit:t}){var n;const i=e,o=t,s=F(()=>{if(i.node.title&&i.node.title.trim().length)return i.node.title;const u=i.node.kind||"note";return u.charAt(0).toUpperCase()+u.slice(1)}),r=K(!!i.node.collapsible&&!((n=i.node.open)==null||n));function l(){i.node.collapsible&&(r.value=!r.value)}const a=`admonition-${Math.random().toString(36).slice(2,9)}`;return(u,c)=>(v(),E("div",{class:Fe(["admonition",[`admonition-${i.node.kind}`]])},[C("div",{id:a,class:"admonition-legend"},[i.node.kind==="note"||i.node.kind==="info"?(v(),E("svg",FNe,[...c[1]||(c[1]=[C("circle",{cx:"12",cy:"12",r:"10"},null,-1),C("path",{d:"M12 16v-4"},null,-1),C("path",{d:"M12 8h.01"},null,-1)])])):i.node.kind==="tip"?(v(),E("svg",DNe,[...c[2]||(c[2]=[C("path",{d:"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"},null,-1),C("path",{d:"M9 18h6"},null,-1),C("path",{d:"M10 22h4"},null,-1)])])):i.node.kind==="warning"||i.node.kind==="caution"?(v(),E("svg",BNe,[...c[3]||(c[3]=[C("path",{d:"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"},null,-1),C("path",{d:"M12 9v4"},null,-1),C("path",{d:"M12 17h.01"},null,-1)])])):i.node.kind==="danger"||i.node.kind==="error"?(v(),E("svg",$Ne,[...c[4]||(c[4]=[C("polygon",{points:"7.86 2 16.14 2 22 7.86 22 16.14 16.14 22 7.86 22 2 16.14 2 7.86 7.86 2"},null,-1),C("path",{d:"M12 8v4"},null,-1),C("path",{d:"M12 16h.01"},null,-1)])])):X("",!0),C("span",RNe,D(s.value),1),i.node.collapsible?(v(),E("button",{key:4,class:"admonition-toggle","aria-expanded":!r.value,"aria-controls":`${a}-content`,onClick:l},[(v(),E("svg",{style:Kt({rotate:r.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"},[...c[5]||(c[5]=[C("path",{d:"m9 18 6-6-6-6"},null,-1)])],4))],8,zNe)):X("",!0)]),Wn(C("div",{id:`${a}-content`,class:"admonition-content","aria-labelledby":a},[U(f(Gr),{"index-key":`admonition-${e.indexKey}`,nodes:i.node.children,"custom-id":i.customId,typewriter:i.typewriter,fade:i.fade,onCopy:c[0]||(c[0]=d=>o("copy",d))},null,8,["index-key","nodes","custom-id","typewriter","fade"])],8,ONe),[[Po,!r.value]])],2))}}),[["__scopeId","data-v-a83480e1"]]);Wv.install=e=>{e.component(Wv.__name,Wv)};const a5=()=>Fo(()=>import("./d2_markstream-vue-yoD6TSFD.js"),[]);let tv=null,nv=a5,iv=null,uT=!1,cT=!1;function _ct(){return Ji(this,null,function*(){if(tv)return tv;const e=nv;return e?e===a5&&uT?null:iv||(iv=Ji(null,null,function*(){let t;try{t=yield e()}catch(n){if(e===a5)return e===nv&&(uT=!0,(function(i){cT||(cT=!0,console.warn('[markstream-vue] Optional dependency "@terrastruct/d2" is not installed. D2 blocks will render as source.',i))})(n)),null;throw n}finally{e===nv&&(iv=null)}return e!==nv?null:t?(tv=(function(n){var i;if(!n)return n;if(n.D2&&typeof n.D2=="function")return n.D2;if(n.default&&n.default.D2&&typeof n.default.D2=="function")return n.default.D2;const o=(i=n.default)!=null?i:n;return typeof o=="function"?o:o?.D2&&typeof o.D2=="function"?o.D2:o})(t),tv):null}),iv):null})}let ov=null,LP=null,sv=null;function Mct(){return typeof LP=="function"}function Ict(){return Ji(this,null,function*(){if(ov)return ov;const e=LP;return e?sv||(sv=Ji(null,null,function*(){const t=yield e(),n=(function(i){var o,s,r;if(!i)return null;const l=(o=i.default)!=null?o:i,a=typeof l=="function"&&typeof((s=l.prototype)==null?void 0:s.render)=="function"?l:(r=i.Infographic)!=null?r:l?.Infographic;return typeof a=="function"?a:null})(t);return n?(ov=n,ov):null}).finally(()=>{sv=null}),sv):null})}const Ect=Symbol("markstreamLanguageIconResolver");function PNe(e){return new Worker("/assets/katexRenderer.worker-CO_gEm4q.js",{type:"module",name:e?.name})}function jNe(e){return new Worker("/assets/mermaidParser.worker-BFSlSHEW.js",{type:"module",name:e?.name})}let dT=!1;function NP(){dT||typeof Worker>"u"||(dT=!0,yEe(new PNe),LEe(new jNe))}NP();const fT=document.createElement("i");function HNe(e){const t="&"+e+";";fT.innerHTML=t;const n=fT.textContent;return n.charCodeAt(n.length-1)===59&&e!=="semi"||n===t?!1:n}function qa(e,t,n,i){const o=e.length;let s=0,r;if(t<0?t=-t>o?0:o+t:t=t>o?o:t,n=n>0?n:0,i.length<1e4)r=Array.from(i),r.unshift(t,n),e.splice(...r);else for(n&&e.splice(t,n);s<i.length;)r=i.slice(s,s+1e4),r.unshift(t,0),e.splice(...r),s+=1e4,t+=1e4}function Nl(e,t){return e.length>0?(qa(e,e.length,0,t),e):t}const hT={}.hasOwnProperty;function WNe(e){const t={};let n=-1;for(;++n<e.length;)qNe(t,e[n]);return t}function qNe(e,t){let n;for(n in t){const o=(hT.call(e,n)?e[n]:void 0)||(e[n]={}),s=t[n];let r;if(s)for(r in s){hT.call(o,r)||(o[r]=[]);const l=s[r];UNe(o[r],Array.isArray(l)?l:l?[l]:[])}}}function UNe(e,t){let n=-1;const i=[];for(;++n<t.length;)(t[n].add==="after"?e:i).push(t[n]);qa(e,0,0,i)}function oA(e){return e.replace(/[\t\n\r ]+/g," ").replace(/^ | $/g,"").toLowerCase().toUpperCase()}const Fa=Qc(/[A-Za-z]/),ra=Qc(/[\dA-Za-z]/),KNe=Qc(/[#-'*+\--9=?A-Z^-~]/);function u5(e){return e!==null&&(e<32||e===127)}const c5=Qc(/\d/),VNe=Qc(/[\dA-Fa-f]/),ZNe=Qc(/[!-/:-@[-`{-~]/);function En(e){return e!==null&&e<-2}function Qr(e){return e!==null&&(e<0||e===32)}function bi(e){return e===-2||e===-1||e===32}const GNe=Qc(/\p{P}|\p{S}/u),QNe=Qc(/\s/);function Qc(e){return t;function t(n){return n!==null&&n>-1&&e.test(String.fromCharCode(n))}}function Xi(e,t,n,i){const o=i?i-1:Number.POSITIVE_INFINITY;let s=0;return r;function r(a){return bi(a)?(e.enter(n),l(a)):t(a)}function l(a){return bi(a)&&s++<o?(e.consume(a),l):(e.exit(n),t(a))}}const YNe={tokenize:JNe};function JNe(e){const t=e.attempt(this.parser.constructs.contentInitial,i,o);let n;return t;function i(l){if(l===null){e.consume(l);return}return e.enter("lineEnding"),e.consume(l),e.exit("lineEnding"),Xi(e,t,"linePrefix")}function o(l){return e.enter("paragraph"),s(l)}function s(l){const a=e.enter("chunkText",{contentType:"text",previous:n});return n&&(n.next=a),n=a,r(l)}function r(l){if(l===null){e.exit("chunkText"),e.exit("paragraph"),e.consume(l);return}return En(l)?(e.consume(l),e.exit("chunkText"),s):(e.consume(l),r)}}const XNe={tokenize:eFe},pT={tokenize:tFe};function eFe(e){const t=this,n=[];let i=0,o,s,r;return l;function l(b){if(i<n.length){const A=n[i];return t.containerState=A[1],e.attempt(A[0].continuation,a,u)(b)}return u(b)}function a(b){if(i++,t.containerState._closeFlow){t.containerState._closeFlow=void 0,o&&y();const A=t.events.length;let T=A,S;for(;T--;)if(t.events[T][0]==="exit"&&t.events[T][1].type==="chunkFlow"){S=t.events[T][1].end;break}w(i);let x=A;for(;x<t.events.length;)t.events[x][1].end={...S},x++;return qa(t.events,T+1,0,t.events.slice(A)),t.events.length=x,u(b)}return l(b)}function u(b){if(i===n.length){if(!o)return h(b);if(o.currentConstruct&&o.currentConstruct.concrete)return g(b);t.interrupt=!!(o.currentConstruct&&!o._gfmTableDynamicInterruptHack)}return t.containerState={},e.check(pT,c,d)(b)}function c(b){return o&&y(),w(i),h(b)}function d(b){return t.parser.lazy[t.now().line]=i!==n.length,r=t.now().offset,g(b)}function h(b){return t.containerState={},e.attempt(pT,p,g)(b)}function p(b){return i++,n.push([t.currentConstruct,t.containerState]),h(b)}function g(b){if(b===null){o&&y(),w(0),e.consume(b);return}return o=o||t.parser.flow(t.now()),e.enter("chunkFlow",{_tokenizer:o,contentType:"flow",previous:s}),m(b)}function m(b){if(b===null){k(e.exit("chunkFlow"),!0),w(0),e.consume(b);return}return En(b)?(e.consume(b),k(e.exit("chunkFlow")),i=0,t.interrupt=void 0,l):(e.consume(b),m)}function k(b,A){const T=t.sliceStream(b);if(A&&T.push(null),b.previous=s,s&&(s.next=b),s=b,o.defineSkip(b.start),o.write(T),t.parser.lazy[b.start.line]){let S=o.events.length;for(;S--;)if(o.events[S][1].start.offset<r&&(!o.events[S][1].end||o.events[S][1].end.offset>r))return;const x=t.events.length;let _=x,L,M;for(;_--;)if(t.events[_][0]==="exit"&&t.events[_][1].type==="chunkFlow"){if(L){M=t.events[_][1].end;break}L=!0}for(w(i),S=x;S<t.events.length;)t.events[S][1].end={...M},S++;qa(t.events,_+1,0,t.events.slice(x)),t.events.length=S}}function w(b){let A=n.length;for(;A-- >b;){const T=n[A];t.containerState=T[1],T[0].exit.call(t,e)}n.length=b}function y(){o.write([null]),s=void 0,o=void 0,t.containerState._closeFlow=void 0}}function tFe(e,t,n){return Xi(e,e.attempt(this.parser.constructs.document,t,n),"linePrefix",this.parser.constructs.disable.null.includes("codeIndented")?void 0:4)}function gT(e){if(e===null||Qr(e)||QNe(e))return 1;if(GNe(e))return 2}function sA(e,t,n){const i=[];let o=-1;for(;++o<e.length;){const s=e[o].resolveAll;s&&!i.includes(s)&&(t=s(t,n),i.push(s))}return t}const d5={name:"attention",resolveAll:nFe,tokenize:iFe};function nFe(e,t){let n=-1,i,o,s,r,l,a,u,c;for(;++n<e.length;)if(e[n][0]==="enter"&&e[n][1].type==="attentionSequence"&&e[n][1]._close){for(i=n;i--;)if(e[i][0]==="exit"&&e[i][1].type==="attentionSequence"&&e[i][1]._open&&t.sliceSerialize(e[i][1]).charCodeAt(0)===t.sliceSerialize(e[n][1]).charCodeAt(0)){if((e[i][1]._close||e[n][1]._open)&&(e[n][1].end.offset-e[n][1].start.offset)%3&&!((e[i][1].end.offset-e[i][1].start.offset+e[n][1].end.offset-e[n][1].start.offset)%3))continue;a=e[i][1].end.offset-e[i][1].start.offset>1&&e[n][1].end.offset-e[n][1].start.offset>1?2:1;const d={...e[i][1].end},h={...e[n][1].start};mT(d,-a),mT(h,a),r={type:a>1?"strongSequence":"emphasisSequence",start:d,end:{...e[i][1].end}},l={type:a>1?"strongSequence":"emphasisSequence",start:{...e[n][1].start},end:h},s={type:a>1?"strongText":"emphasisText",start:{...e[i][1].end},end:{...e[n][1].start}},o={type:a>1?"strong":"emphasis",start:{...r.start},end:{...l.end}},e[i][1].end={...r.start},e[n][1].start={...l.end},u=[],e[i][1].end.offset-e[i][1].start.offset&&(u=Nl(u,[["enter",e[i][1],t],["exit",e[i][1],t]])),u=Nl(u,[["enter",o,t],["enter",r,t],["exit",r,t],["enter",s,t]]),u=Nl(u,sA(t.parser.constructs.insideSpan.null,e.slice(i+1,n),t)),u=Nl(u,[["exit",s,t],["enter",l,t],["exit",l,t],["exit",o,t]]),e[n][1].end.offset-e[n][1].start.offset?(c=2,u=Nl(u,[["enter",e[n][1],t],["exit",e[n][1],t]])):c=0,qa(e,i-1,n-i+3,u),n=i+u.length-c-2;break}}for(n=-1;++n<e.length;)e[n][1].type==="attentionSequence"&&(e[n][1].type="data");return e}function iFe(e,t){const n=this.parser.constructs.attentionMarkers.null,i=this.previous,o=gT(i);let s;return r;function r(a){return s=a,e.enter("attentionSequence"),l(a)}function l(a){if(a===s)return e.consume(a),l;const u=e.exit("attentionSequence"),c=gT(a),d=!c||c===2&&o||n.includes(a),h=!o||o===2&&c||n.includes(i);return u._open=!!(s===42?d:d&&(o||!h)),u._close=!!(s===42?h:h&&(c||!d)),t(a)}}function mT(e,t){e.column+=t,e.offset+=t,e._bufferIndex+=t}const oFe={name:"autolink",tokenize:sFe};function sFe(e,t,n){let i=0;return o;function o(p){return e.enter("autolink"),e.enter("autolinkMarker"),e.consume(p),e.exit("autolinkMarker"),e.enter("autolinkProtocol"),s}function s(p){return Fa(p)?(e.consume(p),r):p===64?n(p):u(p)}function r(p){return p===43||p===45||p===46||ra(p)?(i=1,l(p)):u(p)}function l(p){return p===58?(e.consume(p),i=0,a):(p===43||p===45||p===46||ra(p))&&i++<32?(e.consume(p),l):(i=0,u(p))}function a(p){return p===62?(e.exit("autolinkProtocol"),e.enter("autolinkMarker"),e.consume(p),e.exit("autolinkMarker"),e.exit("autolink"),t):p===null||p===32||p===60||u5(p)?n(p):(e.consume(p),a)}function u(p){return p===64?(e.consume(p),c):KNe(p)?(e.consume(p),u):n(p)}function c(p){return ra(p)?d(p):n(p)}function d(p){return p===46?(e.consume(p),i=0,c):p===62?(e.exit("autolinkProtocol").type="autolinkEmail",e.enter("autolinkMarker"),e.consume(p),e.exit("autolinkMarker"),e.exit("autolink"),t):h(p)}function h(p){if((p===45||ra(p))&&i++<63){const g=p===45?h:d;return e.consume(p),g}return n(p)}}const R9={partial:!0,tokenize:rFe};function rFe(e,t,n){return i;function i(s){return bi(s)?Xi(e,o,"linePrefix")(s):o(s)}function o(s){return s===null||En(s)?t(s):n(s)}}const FP={continuation:{tokenize:aFe},exit:uFe,name:"blockQuote",tokenize:lFe};function lFe(e,t,n){const i=this;return o;function o(r){if(r===62){const l=i.containerState;return l.open||(e.enter("blockQuote",{_container:!0}),l.open=!0),e.enter("blockQuotePrefix"),e.enter("blockQuoteMarker"),e.consume(r),e.exit("blockQuoteMarker"),s}return n(r)}function s(r){return bi(r)?(e.enter("blockQuotePrefixWhitespace"),e.consume(r),e.exit("blockQuotePrefixWhitespace"),e.exit("blockQuotePrefix"),t):(e.exit("blockQuotePrefix"),t(r))}}function aFe(e,t,n){const i=this;return o;function o(r){return bi(r)?Xi(e,s,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(r):s(r)}function s(r){return e.attempt(FP,t,n)(r)}}function uFe(e){e.exit("blockQuote")}const DP={name:"characterEscape",tokenize:cFe};function cFe(e,t,n){return i;function i(s){return e.enter("characterEscape"),e.enter("escapeMarker"),e.consume(s),e.exit("escapeMarker"),o}function o(s){return ZNe(s)?(e.enter("characterEscapeValue"),e.consume(s),e.exit("characterEscapeValue"),e.exit("characterEscape"),t):n(s)}}const BP={name:"characterReference",tokenize:dFe};function dFe(e,t,n){const i=this;let o=0,s,r;return l;function l(d){return e.enter("characterReference"),e.enter("characterReferenceMarker"),e.consume(d),e.exit("characterReferenceMarker"),a}function a(d){return d===35?(e.enter("characterReferenceMarkerNumeric"),e.consume(d),e.exit("characterReferenceMarkerNumeric"),u):(e.enter("characterReferenceValue"),s=31,r=ra,c(d))}function u(d){return d===88||d===120?(e.enter("characterReferenceMarkerHexadecimal"),e.consume(d),e.exit("characterReferenceMarkerHexadecimal"),e.enter("characterReferenceValue"),s=6,r=VNe,c):(e.enter("characterReferenceValue"),s=7,r=c5,c(d))}function c(d){if(d===59&&o){const h=e.exit("characterReferenceValue");return r===ra&&!HNe(i.sliceSerialize(h))?n(d):(e.enter("characterReferenceMarker"),e.consume(d),e.exit("characterReferenceMarker"),e.exit("characterReference"),t)}return r(d)&&o++<s?(e.consume(d),c):n(d)}}const vT={partial:!0,tokenize:hFe},yT={concrete:!0,name:"codeFenced",tokenize:fFe};function fFe(e,t,n){const i=this,o={partial:!0,tokenize:T};let s=0,r=0,l;return a;function a(S){return u(S)}function u(S){const x=i.events[i.events.length-1];return s=x&&x[1].type==="linePrefix"?x[2].sliceSerialize(x[1],!0).length:0,l=S,e.enter("codeFenced"),e.enter("codeFencedFence"),e.enter("codeFencedFenceSequence"),c(S)}function c(S){return S===l?(r++,e.consume(S),c):r<3?n(S):(e.exit("codeFencedFenceSequence"),bi(S)?Xi(e,d,"whitespace")(S):d(S))}function d(S){return S===null||En(S)?(e.exit("codeFencedFence"),i.interrupt?t(S):e.check(vT,m,A)(S)):(e.enter("codeFencedFenceInfo"),e.enter("chunkString",{contentType:"string"}),h(S))}function h(S){return S===null||En(S)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),d(S)):bi(S)?(e.exit("chunkString"),e.exit("codeFencedFenceInfo"),Xi(e,p,"whitespace")(S)):S===96&&S===l?n(S):(e.consume(S),h)}function p(S){return S===null||En(S)?d(S):(e.enter("codeFencedFenceMeta"),e.enter("chunkString",{contentType:"string"}),g(S))}function g(S){return S===null||En(S)?(e.exit("chunkString"),e.exit("codeFencedFenceMeta"),d(S)):S===96&&S===l?n(S):(e.consume(S),g)}function m(S){return e.attempt(o,A,k)(S)}function k(S){return e.enter("lineEnding"),e.consume(S),e.exit("lineEnding"),w}function w(S){return s>0&&bi(S)?Xi(e,y,"linePrefix",s+1)(S):y(S)}function y(S){return S===null||En(S)?e.check(vT,m,A)(S):(e.enter("codeFlowValue"),b(S))}function b(S){return S===null||En(S)?(e.exit("codeFlowValue"),y(S)):(e.consume(S),b)}function A(S){return e.exit("codeFenced"),t(S)}function T(S,x,_){let L=0;return M;function M(O){return S.enter("lineEnding"),S.consume(O),S.exit("lineEnding"),N}function N(O){return S.enter("codeFencedFence"),bi(O)?Xi(S,I,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(O):I(O)}function I(O){return O===l?(S.enter("codeFencedFenceSequence"),z(O)):_(O)}function z(O){return O===l?(L++,S.consume(O),z):L>=r?(S.exit("codeFencedFenceSequence"),bi(O)?Xi(S,H,"whitespace")(O):H(O)):_(O)}function H(O){return O===null||En(O)?(S.exit("codeFencedFence"),x(O)):_(O)}}}function hFe(e,t,n){const i=this;return o;function o(r){return r===null?n(r):(e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),s)}function s(r){return i.parser.lazy[i.now().line]?n(r):t(r)}}const Ik={name:"codeIndented",tokenize:gFe},pFe={partial:!0,tokenize:mFe};function gFe(e,t,n){const i=this;return o;function o(u){return e.enter("codeIndented"),Xi(e,s,"linePrefix",5)(u)}function s(u){const c=i.events[i.events.length-1];return c&&c[1].type==="linePrefix"&&c[2].sliceSerialize(c[1],!0).length>=4?r(u):n(u)}function r(u){return u===null?a(u):En(u)?e.attempt(pFe,r,a)(u):(e.enter("codeFlowValue"),l(u))}function l(u){return u===null||En(u)?(e.exit("codeFlowValue"),r(u)):(e.consume(u),l)}function a(u){return e.exit("codeIndented"),t(u)}}function mFe(e,t,n){const i=this;return o;function o(r){return i.parser.lazy[i.now().line]?n(r):En(r)?(e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),o):Xi(e,s,"linePrefix",5)(r)}function s(r){const l=i.events[i.events.length-1];return l&&l[1].type==="linePrefix"&&l[2].sliceSerialize(l[1],!0).length>=4?t(r):En(r)?o(r):n(r)}}const vFe={name:"codeText",previous:kFe,resolve:yFe,tokenize:bFe};function yFe(e){let t=e.length-4,n=3,i,o;if((e[n][1].type==="lineEnding"||e[n][1].type==="space")&&(e[t][1].type==="lineEnding"||e[t][1].type==="space")){for(i=n;++i<t;)if(e[i][1].type==="codeTextData"){e[n][1].type="codeTextPadding",e[t][1].type="codeTextPadding",n+=2,t-=2;break}}for(i=n-1,t++;++i<=t;)o===void 0?i!==t&&e[i][1].type!=="lineEnding"&&(o=i):(i===t||e[i][1].type==="lineEnding")&&(e[o][1].type="codeTextData",i!==o+2&&(e[o][1].end=e[i-1][1].end,e.splice(o+2,i-o-2),t-=i-o-2,i=o+2),o=void 0);return e}function kFe(e){return e!==96||this.events[this.events.length-1][1].type==="characterEscape"}function bFe(e,t,n){let i=0,o,s;return r;function r(d){return e.enter("codeText"),e.enter("codeTextSequence"),l(d)}function l(d){return d===96?(e.consume(d),i++,l):(e.exit("codeTextSequence"),a(d))}function a(d){return d===null?n(d):d===32?(e.enter("space"),e.consume(d),e.exit("space"),a):d===96?(s=e.enter("codeTextSequence"),o=0,c(d)):En(d)?(e.enter("lineEnding"),e.consume(d),e.exit("lineEnding"),a):(e.enter("codeTextData"),u(d))}function u(d){return d===null||d===32||d===96||En(d)?(e.exit("codeTextData"),a(d)):(e.consume(d),u)}function c(d){return d===96?(e.consume(d),o++,c):o===i?(e.exit("codeTextSequence"),e.exit("codeText"),t(d)):(s.type="codeTextData",u(d))}}class AFe{constructor(t){this.left=t?[...t]:[],this.right=[]}get(t){if(t<0||t>=this.left.length+this.right.length)throw new RangeError("Cannot access index `"+t+"` in a splice buffer of size `"+(this.left.length+this.right.length)+"`");return t<this.left.length?this.left[t]:this.right[this.right.length-t+this.left.length-1]}get length(){return this.left.length+this.right.length}shift(){return this.setCursor(0),this.right.pop()}slice(t,n){const i=n??Number.POSITIVE_INFINITY;return i<this.left.length?this.left.slice(t,i):t>this.left.length?this.right.slice(this.right.length-i+this.left.length,this.right.length-t+this.left.length).reverse():this.left.slice(t).concat(this.right.slice(this.right.length-i+this.left.length).reverse())}splice(t,n,i){const o=n||0;this.setCursor(Math.trunc(t));const s=this.right.splice(this.right.length-o,Number.POSITIVE_INFINITY);return i&&ep(this.left,i),s.reverse()}pop(){return this.setCursor(Number.POSITIVE_INFINITY),this.left.pop()}push(t){this.setCursor(Number.POSITIVE_INFINITY),this.left.push(t)}pushMany(t){this.setCursor(Number.POSITIVE_INFINITY),ep(this.left,t)}unshift(t){this.setCursor(0),this.right.push(t)}unshiftMany(t){this.setCursor(0),ep(this.right,t.reverse())}setCursor(t){if(!(t===this.left.length||t>this.left.length&&this.right.length===0||t<0&&this.left.length===0))if(t<this.left.length){const n=this.left.splice(t,Number.POSITIVE_INFINITY);ep(this.right,n.reverse())}else{const n=this.right.splice(this.left.length+this.right.length-t,Number.POSITIVE_INFINITY);ep(this.left,n.reverse())}}}function ep(e,t){let n=0;if(t.length<1e4)e.push(...t);else for(;n<t.length;)e.push(...t.slice(n,n+1e4)),n+=1e4}function $P(e){const t={};let n=-1,i,o,s,r,l,a,u;const c=new AFe(e);for(;++n<c.length;){for(;n in t;)n=t[n];if(i=c.get(n),n&&i[1].type==="chunkFlow"&&c.get(n-1)[1].type==="listItemPrefix"&&(a=i[1]._tokenizer.events,s=0,s<a.length&&a[s][1].type==="lineEndingBlank"&&(s+=2),s<a.length&&a[s][1].type==="content"))for(;++s<a.length&&a[s][1].type!=="content";)a[s][1].type==="chunkText"&&(a[s][1]._isInFirstContentOfListItem=!0,s++);if(i[0]==="enter")i[1].contentType&&(Object.assign(t,CFe(c,n)),n=t[n],u=!0);else if(i[1]._container){for(s=n,o=void 0;s--;)if(r=c.get(s),r[1].type==="lineEnding"||r[1].type==="lineEndingBlank")r[0]==="enter"&&(o&&(c.get(o)[1].type="lineEndingBlank"),r[1].type="lineEnding",o=s);else if(!(r[1].type==="linePrefix"||r[1].type==="listItemIndent"))break;o&&(i[1].end={...c.get(o)[1].start},l=c.slice(o,n),l.unshift(i),c.splice(o,n-o+1,l))}}return qa(e,0,Number.POSITIVE_INFINITY,c.slice(0)),!u}function CFe(e,t){const n=e.get(t)[1],i=e.get(t)[2];let o=t-1;const s=[];let r=n._tokenizer;r||(r=i.parser[n.contentType](n.start),n._contentTypeTextTrailing&&(r._contentTypeTextTrailing=!0));const l=r.events,a=[],u={};let c,d,h=-1,p=n,g=0,m=0;const k=[m];for(;p;){for(;e.get(++o)[1]!==p;);s.push(o),p._tokenizer||(c=i.sliceStream(p),p.next||c.push(null),d&&r.defineSkip(p.start),p._isInFirstContentOfListItem&&(r._gfmTasklistFirstContentOfListItem=!0),r.write(c),p._isInFirstContentOfListItem&&(r._gfmTasklistFirstContentOfListItem=void 0)),d=p,p=p.next}for(p=n;++h<l.length;)l[h][0]==="exit"&&l[h-1][0]==="enter"&&l[h][1].type===l[h-1][1].type&&l[h][1].start.line!==l[h][1].end.line&&(m=h+1,k.push(m),p._tokenizer=void 0,p.previous=void 0,p=p.next);for(r.events=[],p?(p._tokenizer=void 0,p.previous=void 0):k.pop(),h=k.length;h--;){const w=l.slice(k[h],k[h+1]),y=s.pop();a.push([y,y+w.length-1]),e.splice(y,2,w)}for(a.reverse(),h=-1;++h<a.length;)u[g+a[h][0]]=g+a[h][1],g+=a[h][1]-a[h][0]-1;return u}const wFe={resolve:SFe,tokenize:_Fe},xFe={partial:!0,tokenize:MFe};function SFe(e){return $P(e),e}function _Fe(e,t){let n;return i;function i(l){return e.enter("content"),n=e.enter("chunkContent",{contentType:"content"}),o(l)}function o(l){return l===null?s(l):En(l)?e.check(xFe,r,s)(l):(e.consume(l),o)}function s(l){return e.exit("chunkContent"),e.exit("content"),t(l)}function r(l){return e.consume(l),e.exit("chunkContent"),n.next=e.enter("chunkContent",{contentType:"content",previous:n}),n=n.next,o}}function MFe(e,t,n){const i=this;return o;function o(r){return e.exit("chunkContent"),e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),Xi(e,s,"linePrefix")}function s(r){if(r===null||En(r))return n(r);const l=i.events[i.events.length-1];return!i.parser.constructs.disable.null.includes("codeIndented")&&l&&l[1].type==="linePrefix"&&l[2].sliceSerialize(l[1],!0).length>=4?t(r):e.interrupt(i.parser.constructs.flow,n,t)(r)}}function RP(e,t,n,i,o,s,r,l,a){const u=a||Number.POSITIVE_INFINITY;let c=0;return d;function d(w){return w===60?(e.enter(i),e.enter(o),e.enter(s),e.consume(w),e.exit(s),h):w===null||w===32||w===41||u5(w)?n(w):(e.enter(i),e.enter(r),e.enter(l),e.enter("chunkString",{contentType:"string"}),m(w))}function h(w){return w===62?(e.enter(s),e.consume(w),e.exit(s),e.exit(o),e.exit(i),t):(e.enter(l),e.enter("chunkString",{contentType:"string"}),p(w))}function p(w){return w===62?(e.exit("chunkString"),e.exit(l),h(w)):w===null||w===60||En(w)?n(w):(e.consume(w),w===92?g:p)}function g(w){return w===60||w===62||w===92?(e.consume(w),p):p(w)}function m(w){return!c&&(w===null||w===41||Qr(w))?(e.exit("chunkString"),e.exit(l),e.exit(r),e.exit(i),t(w)):c<u&&w===40?(e.consume(w),c++,m):w===41?(e.consume(w),c--,m):w===null||w===32||w===40||u5(w)?n(w):(e.consume(w),w===92?k:m)}function k(w){return w===40||w===41||w===92?(e.consume(w),m):m(w)}}function zP(e,t,n,i,o,s){const r=this;let l=0,a;return u;function u(p){return e.enter(i),e.enter(o),e.consume(p),e.exit(o),e.enter(s),c}function c(p){return l>999||p===null||p===91||p===93&&!a||p===94&&!l&&"_hiddenFootnoteSupport"in r.parser.constructs?n(p):p===93?(e.exit(s),e.enter(o),e.consume(p),e.exit(o),e.exit(i),t):En(p)?(e.enter("lineEnding"),e.consume(p),e.exit("lineEnding"),c):(e.enter("chunkString",{contentType:"string"}),d(p))}function d(p){return p===null||p===91||p===93||En(p)||l++>999?(e.exit("chunkString"),c(p)):(e.consume(p),a||(a=!bi(p)),p===92?h:d)}function h(p){return p===91||p===92||p===93?(e.consume(p),l++,d):d(p)}}function OP(e,t,n,i,o,s){let r;return l;function l(h){return h===34||h===39||h===40?(e.enter(i),e.enter(o),e.consume(h),e.exit(o),r=h===40?41:h,a):n(h)}function a(h){return h===r?(e.enter(o),e.consume(h),e.exit(o),e.exit(i),t):(e.enter(s),u(h))}function u(h){return h===r?(e.exit(s),a(r)):h===null?n(h):En(h)?(e.enter("lineEnding"),e.consume(h),e.exit("lineEnding"),Xi(e,u,"linePrefix")):(e.enter("chunkString",{contentType:"string"}),c(h))}function c(h){return h===r||h===null||En(h)?(e.exit("chunkString"),u(h)):(e.consume(h),h===92?d:c)}function d(h){return h===r||h===92?(e.consume(h),c):c(h)}}function s0(e,t){let n;return i;function i(o){return En(o)?(e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),n=!0,i):bi(o)?Xi(e,i,n?"linePrefix":"lineSuffix")(o):t(o)}}const IFe={name:"definition",tokenize:TFe},EFe={partial:!0,tokenize:LFe};function TFe(e,t,n){const i=this;let o;return s;function s(p){return e.enter("definition"),r(p)}function r(p){return zP.call(i,e,l,n,"definitionLabel","definitionLabelMarker","definitionLabelString")(p)}function l(p){return o=oA(i.sliceSerialize(i.events[i.events.length-1][1]).slice(1,-1)),p===58?(e.enter("definitionMarker"),e.consume(p),e.exit("definitionMarker"),a):n(p)}function a(p){return Qr(p)?s0(e,u)(p):u(p)}function u(p){return RP(e,c,n,"definitionDestination","definitionDestinationLiteral","definitionDestinationLiteralMarker","definitionDestinationRaw","definitionDestinationString")(p)}function c(p){return e.attempt(EFe,d,d)(p)}function d(p){return bi(p)?Xi(e,h,"whitespace")(p):h(p)}function h(p){return p===null||En(p)?(e.exit("definition"),i.parser.defined.push(o),t(p)):n(p)}}function LFe(e,t,n){return i;function i(l){return Qr(l)?s0(e,o)(l):n(l)}function o(l){return OP(e,s,n,"definitionTitle","definitionTitleMarker","definitionTitleString")(l)}function s(l){return bi(l)?Xi(e,r,"whitespace")(l):r(l)}function r(l){return l===null||En(l)?t(l):n(l)}}const NFe={name:"hardBreakEscape",tokenize:FFe};function FFe(e,t,n){return i;function i(s){return e.enter("hardBreakEscape"),e.consume(s),o}function o(s){return En(s)?(e.exit("hardBreakEscape"),t(s)):n(s)}}const DFe={name:"headingAtx",resolve:BFe,tokenize:$Fe};function BFe(e,t){let n=e.length-2,i=3,o,s;return e[i][1].type==="whitespace"&&(i+=2),n-2>i&&e[n][1].type==="whitespace"&&(n-=2),e[n][1].type==="atxHeadingSequence"&&(i===n-1||n-4>i&&e[n-2][1].type==="whitespace")&&(n-=i+1===n?2:4),n>i&&(o={type:"atxHeadingText",start:e[i][1].start,end:e[n][1].end},s={type:"chunkText",start:e[i][1].start,end:e[n][1].end,contentType:"text"},qa(e,i,n-i+1,[["enter",o,t],["enter",s,t],["exit",s,t],["exit",o,t]])),e}function $Fe(e,t,n){let i=0;return o;function o(c){return e.enter("atxHeading"),s(c)}function s(c){return e.enter("atxHeadingSequence"),r(c)}function r(c){return c===35&&i++<6?(e.consume(c),r):c===null||Qr(c)?(e.exit("atxHeadingSequence"),l(c)):n(c)}function l(c){return c===35?(e.enter("atxHeadingSequence"),a(c)):c===null||En(c)?(e.exit("atxHeading"),t(c)):bi(c)?Xi(e,l,"whitespace")(c):(e.enter("atxHeadingText"),u(c))}function a(c){return c===35?(e.consume(c),a):(e.exit("atxHeadingSequence"),l(c))}function u(c){return c===null||c===35||Qr(c)?(e.exit("atxHeadingText"),l(c)):(e.consume(c),u)}}const RFe=["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hr","html","iframe","legend","li","link","main","menu","menuitem","nav","noframes","ol","optgroup","option","p","param","search","section","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"],kT=["pre","script","style","textarea"],zFe={concrete:!0,name:"htmlFlow",resolveTo:jFe,tokenize:HFe},OFe={partial:!0,tokenize:qFe},PFe={partial:!0,tokenize:WFe};function jFe(e){let t=e.length;for(;t--&&!(e[t][0]==="enter"&&e[t][1].type==="htmlFlow"););return t>1&&e[t-2][1].type==="linePrefix"&&(e[t][1].start=e[t-2][1].start,e[t+1][1].start=e[t-2][1].start,e.splice(t-2,2)),e}function HFe(e,t,n){const i=this;let o,s,r,l,a;return u;function u(V){return c(V)}function c(V){return e.enter("htmlFlow"),e.enter("htmlFlowData"),e.consume(V),d}function d(V){return V===33?(e.consume(V),h):V===47?(e.consume(V),s=!0,m):V===63?(e.consume(V),o=3,i.interrupt?t:P):Fa(V)?(e.consume(V),r=String.fromCharCode(V),k):n(V)}function h(V){return V===45?(e.consume(V),o=2,p):V===91?(e.consume(V),o=5,l=0,g):Fa(V)?(e.consume(V),o=4,i.interrupt?t:P):n(V)}function p(V){return V===45?(e.consume(V),i.interrupt?t:P):n(V)}function g(V){const Y="CDATA[";return V===Y.charCodeAt(l++)?(e.consume(V),l===Y.length?i.interrupt?t:I:g):n(V)}function m(V){return Fa(V)?(e.consume(V),r=String.fromCharCode(V),k):n(V)}function k(V){if(V===null||V===47||V===62||Qr(V)){const Y=V===47,oe=r.toLowerCase();return!Y&&!s&&kT.includes(oe)?(o=1,i.interrupt?t(V):I(V)):RFe.includes(r.toLowerCase())?(o=6,Y?(e.consume(V),w):i.interrupt?t(V):I(V)):(o=7,i.interrupt&&!i.parser.lazy[i.now().line]?n(V):s?y(V):b(V))}return V===45||ra(V)?(e.consume(V),r+=String.fromCharCode(V),k):n(V)}function w(V){return V===62?(e.consume(V),i.interrupt?t:I):n(V)}function y(V){return bi(V)?(e.consume(V),y):M(V)}function b(V){return V===47?(e.consume(V),M):V===58||V===95||Fa(V)?(e.consume(V),A):bi(V)?(e.consume(V),b):M(V)}function A(V){return V===45||V===46||V===58||V===95||ra(V)?(e.consume(V),A):T(V)}function T(V){return V===61?(e.consume(V),S):bi(V)?(e.consume(V),T):b(V)}function S(V){return V===null||V===60||V===61||V===62||V===96?n(V):V===34||V===39?(e.consume(V),a=V,x):bi(V)?(e.consume(V),S):_(V)}function x(V){return V===a?(e.consume(V),a=null,L):V===null||En(V)?n(V):(e.consume(V),x)}function _(V){return V===null||V===34||V===39||V===47||V===60||V===61||V===62||V===96||Qr(V)?T(V):(e.consume(V),_)}function L(V){return V===47||V===62||bi(V)?b(V):n(V)}function M(V){return V===62?(e.consume(V),N):n(V)}function N(V){return V===null||En(V)?I(V):bi(V)?(e.consume(V),N):n(V)}function I(V){return V===45&&o===2?(e.consume(V),R):V===60&&o===1?(e.consume(V),j):V===62&&o===4?(e.consume(V),Z):V===63&&o===3?(e.consume(V),P):V===93&&o===5?(e.consume(V),W):En(V)&&(o===6||o===7)?(e.exit("htmlFlowData"),e.check(OFe,ae,z)(V)):V===null||En(V)?(e.exit("htmlFlowData"),z(V)):(e.consume(V),I)}function z(V){return e.check(PFe,H,ae)(V)}function H(V){return e.enter("lineEnding"),e.consume(V),e.exit("lineEnding"),O}function O(V){return V===null||En(V)?z(V):(e.enter("htmlFlowData"),I(V))}function R(V){return V===45?(e.consume(V),P):I(V)}function j(V){return V===47?(e.consume(V),r="",$):I(V)}function $(V){if(V===62){const Y=r.toLowerCase();return kT.includes(Y)?(e.consume(V),Z):I(V)}return Fa(V)&&r.length<8?(e.consume(V),r+=String.fromCharCode(V),$):I(V)}function W(V){return V===93?(e.consume(V),P):I(V)}function P(V){return V===62?(e.consume(V),Z):V===45&&o===2?(e.consume(V),P):I(V)}function Z(V){return V===null||En(V)?(e.exit("htmlFlowData"),ae(V)):(e.consume(V),Z)}function ae(V){return e.exit("htmlFlow"),t(V)}}function WFe(e,t,n){const i=this;return o;function o(r){return En(r)?(e.enter("lineEnding"),e.consume(r),e.exit("lineEnding"),s):n(r)}function s(r){return i.parser.lazy[i.now().line]?n(r):t(r)}}function qFe(e,t,n){return i;function i(o){return e.enter("lineEnding"),e.consume(o),e.exit("lineEnding"),e.attempt(R9,t,n)}}const UFe={name:"htmlText",tokenize:KFe};function KFe(e,t,n){const i=this;let o,s,r;return l;function l(P){return e.enter("htmlText"),e.enter("htmlTextData"),e.consume(P),a}function a(P){return P===33?(e.consume(P),u):P===47?(e.consume(P),T):P===63?(e.consume(P),b):Fa(P)?(e.consume(P),_):n(P)}function u(P){return P===45?(e.consume(P),c):P===91?(e.consume(P),s=0,g):Fa(P)?(e.consume(P),y):n(P)}function c(P){return P===45?(e.consume(P),p):n(P)}function d(P){return P===null?n(P):P===45?(e.consume(P),h):En(P)?(r=d,j(P)):(e.consume(P),d)}function h(P){return P===45?(e.consume(P),p):d(P)}function p(P){return P===62?R(P):P===45?h(P):d(P)}function g(P){const Z="CDATA[";return P===Z.charCodeAt(s++)?(e.consume(P),s===Z.length?m:g):n(P)}function m(P){return P===null?n(P):P===93?(e.consume(P),k):En(P)?(r=m,j(P)):(e.consume(P),m)}function k(P){return P===93?(e.consume(P),w):m(P)}function w(P){return P===62?R(P):P===93?(e.consume(P),w):m(P)}function y(P){return P===null||P===62?R(P):En(P)?(r=y,j(P)):(e.consume(P),y)}function b(P){return P===null?n(P):P===63?(e.consume(P),A):En(P)?(r=b,j(P)):(e.consume(P),b)}function A(P){return P===62?R(P):b(P)}function T(P){return Fa(P)?(e.consume(P),S):n(P)}function S(P){return P===45||ra(P)?(e.consume(P),S):x(P)}function x(P){return En(P)?(r=x,j(P)):bi(P)?(e.consume(P),x):R(P)}function _(P){return P===45||ra(P)?(e.consume(P),_):P===47||P===62||Qr(P)?L(P):n(P)}function L(P){return P===47?(e.consume(P),R):P===58||P===95||Fa(P)?(e.consume(P),M):En(P)?(r=L,j(P)):bi(P)?(e.consume(P),L):R(P)}function M(P){return P===45||P===46||P===58||P===95||ra(P)?(e.consume(P),M):N(P)}function N(P){return P===61?(e.consume(P),I):En(P)?(r=N,j(P)):bi(P)?(e.consume(P),N):L(P)}function I(P){return P===null||P===60||P===61||P===62||P===96?n(P):P===34||P===39?(e.consume(P),o=P,z):En(P)?(r=I,j(P)):bi(P)?(e.consume(P),I):(e.consume(P),H)}function z(P){return P===o?(e.consume(P),o=void 0,O):P===null?n(P):En(P)?(r=z,j(P)):(e.consume(P),z)}function H(P){return P===null||P===34||P===39||P===60||P===61||P===96?n(P):P===47||P===62||Qr(P)?L(P):(e.consume(P),H)}function O(P){return P===47||P===62||Qr(P)?L(P):n(P)}function R(P){return P===62?(e.consume(P),e.exit("htmlTextData"),e.exit("htmlText"),t):n(P)}function j(P){return e.exit("htmlTextData"),e.enter("lineEnding"),e.consume(P),e.exit("lineEnding"),$}function $(P){return bi(P)?Xi(e,W,"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(P):W(P)}function W(P){return e.enter("htmlTextData"),r(P)}}const rA={name:"labelEnd",resolveAll:QFe,resolveTo:YFe,tokenize:JFe},VFe={tokenize:XFe},ZFe={tokenize:eDe},GFe={tokenize:tDe};function QFe(e){let t=-1;const n=[];for(;++t<e.length;){const i=e[t][1];if(n.push(e[t]),i.type==="labelImage"||i.type==="labelLink"||i.type==="labelEnd"){const o=i.type==="labelImage"?4:2;i.type="data",t+=o}}return e.length!==n.length&&qa(e,0,e.length,n),e}function YFe(e,t){let n=e.length,i=0,o,s,r,l;for(;n--;)if(o=e[n][1],s){if(o.type==="link"||o.type==="labelLink"&&o._inactive)break;e[n][0]==="enter"&&o.type==="labelLink"&&(o._inactive=!0)}else if(r){if(e[n][0]==="enter"&&(o.type==="labelImage"||o.type==="labelLink")&&!o._balanced&&(s=n,o.type!=="labelLink")){i=2;break}}else o.type==="labelEnd"&&(r=n);const a={type:e[s][1].type==="labelLink"?"link":"image",start:{...e[s][1].start},end:{...e[e.length-1][1].end}},u={type:"label",start:{...e[s][1].start},end:{...e[r][1].end}},c={type:"labelText",start:{...e[s+i+2][1].end},end:{...e[r-2][1].start}};return l=[["enter",a,t],["enter",u,t]],l=Nl(l,e.slice(s+1,s+i+3)),l=Nl(l,[["enter",c,t]]),l=Nl(l,sA(t.parser.constructs.insideSpan.null,e.slice(s+i+4,r-3),t)),l=Nl(l,[["exit",c,t],e[r-2],e[r-1],["exit",u,t]]),l=Nl(l,e.slice(r+1)),l=Nl(l,[["exit",a,t]]),qa(e,s,e.length,l),e}function JFe(e,t,n){const i=this;let o=i.events.length,s,r;for(;o--;)if((i.events[o][1].type==="labelImage"||i.events[o][1].type==="labelLink")&&!i.events[o][1]._balanced){s=i.events[o][1];break}return l;function l(h){return s?s._inactive?d(h):(r=i.parser.defined.includes(oA(i.sliceSerialize({start:s.end,end:i.now()}))),e.enter("labelEnd"),e.enter("labelMarker"),e.consume(h),e.exit("labelMarker"),e.exit("labelEnd"),a):n(h)}function a(h){return h===40?e.attempt(VFe,c,r?c:d)(h):h===91?e.attempt(ZFe,c,r?u:d)(h):r?c(h):d(h)}function u(h){return e.attempt(GFe,c,d)(h)}function c(h){return t(h)}function d(h){return s._balanced=!0,n(h)}}function XFe(e,t,n){return i;function i(d){return e.enter("resource"),e.enter("resourceMarker"),e.consume(d),e.exit("resourceMarker"),o}function o(d){return Qr(d)?s0(e,s)(d):s(d)}function s(d){return d===41?c(d):RP(e,r,l,"resourceDestination","resourceDestinationLiteral","resourceDestinationLiteralMarker","resourceDestinationRaw","resourceDestinationString",32)(d)}function r(d){return Qr(d)?s0(e,a)(d):c(d)}function l(d){return n(d)}function a(d){return d===34||d===39||d===40?OP(e,u,n,"resourceTitle","resourceTitleMarker","resourceTitleString")(d):c(d)}function u(d){return Qr(d)?s0(e,c)(d):c(d)}function c(d){return d===41?(e.enter("resourceMarker"),e.consume(d),e.exit("resourceMarker"),e.exit("resource"),t):n(d)}}function eDe(e,t,n){const i=this;return o;function o(l){return zP.call(i,e,s,r,"reference","referenceMarker","referenceString")(l)}function s(l){return i.parser.defined.includes(oA(i.sliceSerialize(i.events[i.events.length-1][1]).slice(1,-1)))?t(l):n(l)}function r(l){return n(l)}}function tDe(e,t,n){return i;function i(s){return e.enter("reference"),e.enter("referenceMarker"),e.consume(s),e.exit("referenceMarker"),o}function o(s){return s===93?(e.enter("referenceMarker"),e.consume(s),e.exit("referenceMarker"),e.exit("reference"),t):n(s)}}const nDe={name:"labelStartImage",resolveAll:rA.resolveAll,tokenize:iDe};function iDe(e,t,n){const i=this;return o;function o(l){return e.enter("labelImage"),e.enter("labelImageMarker"),e.consume(l),e.exit("labelImageMarker"),s}function s(l){return l===91?(e.enter("labelMarker"),e.consume(l),e.exit("labelMarker"),e.exit("labelImage"),r):n(l)}function r(l){return l===94&&"_hiddenFootnoteSupport"in i.parser.constructs?n(l):t(l)}}const oDe={name:"labelStartLink",resolveAll:rA.resolveAll,tokenize:sDe};function sDe(e,t,n){const i=this;return o;function o(r){return e.enter("labelLink"),e.enter("labelMarker"),e.consume(r),e.exit("labelMarker"),e.exit("labelLink"),s}function s(r){return r===94&&"_hiddenFootnoteSupport"in i.parser.constructs?n(r):t(r)}}const Ek={name:"lineEnding",tokenize:rDe};function rDe(e,t){return n;function n(i){return e.enter("lineEnding"),e.consume(i),e.exit("lineEnding"),Xi(e,t,"linePrefix")}}const qv={name:"thematicBreak",tokenize:lDe};function lDe(e,t,n){let i=0,o;return s;function s(u){return e.enter("thematicBreak"),r(u)}function r(u){return o=u,l(u)}function l(u){return u===o?(e.enter("thematicBreakSequence"),a(u)):i>=3&&(u===null||En(u))?(e.exit("thematicBreak"),t(u)):n(u)}function a(u){return u===o?(e.consume(u),i++,a):(e.exit("thematicBreakSequence"),bi(u)?Xi(e,l,"whitespace")(u):l(u))}}const Rr={continuation:{tokenize:dDe},exit:hDe,name:"list",tokenize:cDe},aDe={partial:!0,tokenize:pDe},uDe={partial:!0,tokenize:fDe};function cDe(e,t,n){const i=this,o=i.events[i.events.length-1];let s=o&&o[1].type==="linePrefix"?o[2].sliceSerialize(o[1],!0).length:0,r=0;return l;function l(p){const g=i.containerState.type||(p===42||p===43||p===45?"listUnordered":"listOrdered");if(g==="listUnordered"?!i.containerState.marker||p===i.containerState.marker:c5(p)){if(i.containerState.type||(i.containerState.type=g,e.enter(g,{_container:!0})),g==="listUnordered")return e.enter("listItemPrefix"),p===42||p===45?e.check(qv,n,u)(p):u(p);if(!i.interrupt||p===49)return e.enter("listItemPrefix"),e.enter("listItemValue"),a(p)}return n(p)}function a(p){return c5(p)&&++r<10?(e.consume(p),a):(!i.interrupt||r<2)&&(i.containerState.marker?p===i.containerState.marker:p===41||p===46)?(e.exit("listItemValue"),u(p)):n(p)}function u(p){return e.enter("listItemMarker"),e.consume(p),e.exit("listItemMarker"),i.containerState.marker=i.containerState.marker||p,e.check(R9,i.interrupt?n:c,e.attempt(aDe,h,d))}function c(p){return i.containerState.initialBlankLine=!0,s++,h(p)}function d(p){return bi(p)?(e.enter("listItemPrefixWhitespace"),e.consume(p),e.exit("listItemPrefixWhitespace"),h):n(p)}function h(p){return i.containerState.size=s+i.sliceSerialize(e.exit("listItemPrefix"),!0).length,t(p)}}function dDe(e,t,n){const i=this;return i.containerState._closeFlow=void 0,e.check(R9,o,s);function o(l){return i.containerState.furtherBlankLines=i.containerState.furtherBlankLines||i.containerState.initialBlankLine,Xi(e,t,"listItemIndent",i.containerState.size+1)(l)}function s(l){return i.containerState.furtherBlankLines||!bi(l)?(i.containerState.furtherBlankLines=void 0,i.containerState.initialBlankLine=void 0,r(l)):(i.containerState.furtherBlankLines=void 0,i.containerState.initialBlankLine=void 0,e.attempt(uDe,t,r)(l))}function r(l){return i.containerState._closeFlow=!0,i.interrupt=void 0,Xi(e,e.attempt(Rr,t,n),"linePrefix",i.parser.constructs.disable.null.includes("codeIndented")?void 0:4)(l)}}function fDe(e,t,n){const i=this;return Xi(e,o,"listItemIndent",i.containerState.size+1);function o(s){const r=i.events[i.events.length-1];return r&&r[1].type==="listItemIndent"&&r[2].sliceSerialize(r[1],!0).length===i.containerState.size?t(s):n(s)}}function hDe(e){e.exit(this.containerState.type)}function pDe(e,t,n){const i=this;return Xi(e,o,"listItemPrefixWhitespace",i.parser.constructs.disable.null.includes("codeIndented")?void 0:5);function o(s){const r=i.events[i.events.length-1];return!bi(s)&&r&&r[1].type==="listItemPrefixWhitespace"?t(s):n(s)}}const bT={name:"setextUnderline",resolveTo:gDe,tokenize:mDe};function gDe(e,t){let n=e.length,i,o,s;for(;n--;)if(e[n][0]==="enter"){if(e[n][1].type==="content"){i=n;break}e[n][1].type==="paragraph"&&(o=n)}else e[n][1].type==="content"&&e.splice(n,1),!s&&e[n][1].type==="definition"&&(s=n);const r={type:"setextHeading",start:{...e[i][1].start},end:{...e[e.length-1][1].end}};return e[o][1].type="setextHeadingText",s?(e.splice(o,0,["enter",r,t]),e.splice(s+1,0,["exit",e[i][1],t]),e[i][1].end={...e[s][1].end}):e[i][1]=r,e.push(["exit",r,t]),e}function mDe(e,t,n){const i=this;let o;return s;function s(u){let c=i.events.length,d;for(;c--;)if(i.events[c][1].type!=="lineEnding"&&i.events[c][1].type!=="linePrefix"&&i.events[c][1].type!=="content"){d=i.events[c][1].type==="paragraph";break}return!i.parser.lazy[i.now().line]&&(i.interrupt||d)?(e.enter("setextHeadingLine"),o=u,r(u)):n(u)}function r(u){return e.enter("setextHeadingLineSequence"),l(u)}function l(u){return u===o?(e.consume(u),l):(e.exit("setextHeadingLineSequence"),bi(u)?Xi(e,a,"lineSuffix")(u):a(u))}function a(u){return u===null||En(u)?(e.exit("setextHeadingLine"),t(u)):n(u)}}const vDe={tokenize:yDe};function yDe(e){const t=this,n=e.attempt(R9,i,e.attempt(this.parser.constructs.flowInitial,o,Xi(e,e.attempt(this.parser.constructs.flow,o,e.attempt(wFe,o)),"linePrefix")));return n;function i(s){if(s===null){e.consume(s);return}return e.enter("lineEndingBlank"),e.consume(s),e.exit("lineEndingBlank"),t.currentConstruct=void 0,n}function o(s){if(s===null){e.consume(s);return}return e.enter("lineEnding"),e.consume(s),e.exit("lineEnding"),t.currentConstruct=void 0,n}}const kDe={resolveAll:jP()},bDe=PP("string"),ADe=PP("text");function PP(e){return{resolveAll:jP(e==="text"?CDe:void 0),tokenize:t};function t(n){const i=this,o=this.parser.constructs[e],s=n.attempt(o,r,l);return r;function r(c){return u(c)?s(c):l(c)}function l(c){if(c===null){n.consume(c);return}return n.enter("data"),n.consume(c),a}function a(c){return u(c)?(n.exit("data"),s(c)):(n.consume(c),a)}function u(c){if(c===null)return!0;const d=o[c];let h=-1;if(d)for(;++h<d.length;){const p=d[h];if(!p.previous||p.previous.call(i,i.previous))return!0}return!1}}}function jP(e){return t;function t(n,i){let o=-1,s;for(;++o<=n.length;)s===void 0?n[o]&&n[o][1].type==="data"&&(s=o,o++):(!n[o]||n[o][1].type!=="data")&&(o!==s+2&&(n[s][1].end=n[o-1][1].end,n.splice(s+2,o-s-2),o=s+2),s=void 0);return e?e(n,i):n}}function CDe(e,t){let n=0;for(;++n<=e.length;)if((n===e.length||e[n][1].type==="lineEnding")&&e[n-1][1].type==="data"){const i=e[n-1][1],o=t.sliceStream(i);let s=o.length,r=-1,l=0,a;for(;s--;){const u=o[s];if(typeof u=="string"){for(r=u.length;u.charCodeAt(r-1)===32;)l++,r--;if(r)break;r=-1}else if(u===-2)a=!0,l++;else if(u!==-1){s++;break}}if(t._contentTypeTextTrailing&&n===e.length&&(l=0),l){const u={type:n===e.length||a||l<2?"lineSuffix":"hardBreakTrailing",start:{_bufferIndex:s?r:i.start._bufferIndex+r,_index:i.start._index+s,line:i.end.line,column:i.end.column-l,offset:i.end.offset-l},end:{...i.end}};i.end={...u.start},i.start.offset===i.end.offset?Object.assign(i,u):(e.splice(n,0,["enter",u,t],["exit",u,t]),n+=2)}n++}return e}const wDe={42:Rr,43:Rr,45:Rr,48:Rr,49:Rr,50:Rr,51:Rr,52:Rr,53:Rr,54:Rr,55:Rr,56:Rr,57:Rr,62:FP},xDe={91:IFe},SDe={[-2]:Ik,[-1]:Ik,32:Ik},_De={35:DFe,42:qv,45:[bT,qv],60:zFe,61:bT,95:qv,96:yT,126:yT},MDe={38:BP,92:DP},IDe={[-5]:Ek,[-4]:Ek,[-3]:Ek,33:nDe,38:BP,42:d5,60:[oFe,UFe],91:oDe,92:[NFe,DP],93:rA,95:d5,96:vFe},EDe={null:[d5,kDe]},TDe={null:[42,95]},LDe={null:[]},NDe=Object.freeze(Object.defineProperty({__proto__:null,attentionMarkers:TDe,contentInitial:xDe,disable:LDe,document:wDe,flow:_De,flowInitial:SDe,insideSpan:EDe,string:MDe,text:IDe},Symbol.toStringTag,{value:"Module"}));function FDe(e,t,n){let i={_bufferIndex:-1,_index:0,line:n&&n.line||1,column:n&&n.column||1,offset:n&&n.offset||0};const o={},s=[];let r=[],l=[];const a={attempt:x(T),check:x(S),consume:y,enter:b,exit:A,interrupt:x(S,{interrupt:!0})},u={code:null,containerState:{},defineSkip:m,events:[],now:g,parser:e,previous:null,sliceSerialize:h,sliceStream:p,write:d};let c=t.tokenize.call(u,a);return t.resolveAll&&s.push(t),u;function d(N){return r=Nl(r,N),k(),r[r.length-1]!==null?[]:(_(t,0),u.events=sA(s,u.events,u),u.events)}function h(N,I){return BDe(p(N),I)}function p(N){return DDe(r,N)}function g(){const{_bufferIndex:N,_index:I,line:z,column:H,offset:O}=i;return{_bufferIndex:N,_index:I,line:z,column:H,offset:O}}function m(N){o[N.line]=N.column,M()}function k(){let N;for(;i._index<r.length;){const I=r[i._index];if(typeof I=="string")for(N=i._index,i._bufferIndex<0&&(i._bufferIndex=0);i._index===N&&i._bufferIndex<I.length;)w(I.charCodeAt(i._bufferIndex));else w(I)}}function w(N){c=c(N)}function y(N){En(N)?(i.line++,i.column=1,i.offset+=N===-3?2:1,M()):N!==-1&&(i.column++,i.offset++),i._bufferIndex<0?i._index++:(i._bufferIndex++,i._bufferIndex===r[i._index].length&&(i._bufferIndex=-1,i._index++)),u.previous=N}function b(N,I){const z=I||{};return z.type=N,z.start=g(),u.events.push(["enter",z,u]),l.push(z),z}function A(N){const I=l.pop();return I.end=g(),u.events.push(["exit",I,u]),I}function T(N,I){_(N,I.from)}function S(N,I){I.restore()}function x(N,I){return z;function z(H,O,R){let j,$,W,P;return Array.isArray(H)?ae(H):"tokenize"in H?ae([H]):Z(H);function Z(q){return ne;function ne(ie){const pe=ie!==null&&q[ie],Ne=ie!==null&&q.null,te=[...Array.isArray(pe)?pe:pe?[pe]:[],...Array.isArray(Ne)?Ne:Ne?[Ne]:[]];return ae(te)(ie)}}function ae(q){return j=q,$=0,q.length===0?R:V(q[$])}function V(q){return ne;function ne(ie){return P=L(),W=q,q.partial||(u.currentConstruct=q),q.name&&u.parser.constructs.disable.null.includes(q.name)?oe():q.tokenize.call(I?Object.assign(Object.create(u),I):u,a,Y,oe)(ie)}}function Y(q){return N(W,P),O}function oe(q){return P.restore(),++$<j.length?V(j[$]):R}}}function _(N,I){N.resolveAll&&!s.includes(N)&&s.push(N),N.resolve&&qa(u.events,I,u.events.length-I,N.resolve(u.events.slice(I),u)),N.resolveTo&&(u.events=N.resolveTo(u.events,u))}function L(){const N=g(),I=u.previous,z=u.currentConstruct,H=u.events.length,O=Array.from(l);return{from:H,restore:R};function R(){i=N,u.previous=I,u.currentConstruct=z,u.events.length=H,l=O,M()}}function M(){i.line in o&&i.column<2&&(i.column=o[i.line],i.offset+=o[i.line]-1)}}function DDe(e,t){const n=t.start._index,i=t.start._bufferIndex,o=t.end._index,s=t.end._bufferIndex;let r;if(n===o)r=[e[n].slice(i,s)];else{if(r=e.slice(n,o),i>-1){const l=r[0];typeof l=="string"?r[0]=l.slice(i):r.shift()}s>0&&r.push(e[o].slice(0,s))}return r}function BDe(e,t){let n=-1;const i=[];let o;for(;++n<e.length;){const s=e[n];let r;if(typeof s=="string")r=s;else switch(s){case-5:{r="\r";break}case-4:{r=` -`;break}case-3:{r=`\r -`;break}case-2:{r=t?" ":" ";break}case-1:{if(!t&&o)continue;r=" ";break}default:r=String.fromCharCode(s)}o=s===-2,i.push(r)}return i.join("")}function $De(e){const i={constructs:WNe([NDe,...(e||{}).extensions||[]]),content:o(YNe),defined:[],document:o(XNe),flow:o(vDe),lazy:{},string:o(bDe),text:o(ADe)};return i;function o(s){return r;function r(l){return FDe(i,s,l)}}}function RDe(e){for(;!$P(e););return e}const AT=/[\0\t\n\r]/g;function zDe(){let e=1,t="",n=!0,i;return o;function o(s,r,l){const a=[];let u,c,d,h,p;for(s=t+(typeof s=="string"?s.toString():new TextDecoder(r||void 0).decode(s)),d=0,t="",n&&(s.charCodeAt(0)===65279&&d++,n=void 0);d<s.length;){if(AT.lastIndex=d,u=AT.exec(s),h=u&&u.index!==void 0?u.index:s.length,p=s.charCodeAt(h),!u){t=s.slice(d);break}if(p===10&&d===h&&i)a.push(-3),i=void 0;else switch(i&&(a.push(-5),i=void 0),d<h&&(a.push(s.slice(d,h)),e+=h-d),p){case 0:{a.push(65533),e++;break}case 9:{for(c=Math.ceil(e/4)*4,a.push(-2);e++<c;)a.push(-1);break}case 10:{a.push(-4),e=1;break}default:i=!0,e=1}d=h+1}return l&&(i&&a.push(-5),t&&a.push(t),a.push(null)),a}}function Ps(e){this.content=e}Ps.prototype={constructor:Ps,find:function(e){for(var t=0;t<this.content.length;t+=2)if(this.content[t]===e)return t;return-1},get:function(e){var t=this.find(e);return t==-1?void 0:this.content[t+1]},update:function(e,t,n){var i=n&&n!=e?this.remove(n):this,o=i.find(e),s=i.content.slice();return o==-1?s.push(n||e,t):(s[o+1]=t,n&&(s[o]=n)),new Ps(s)},remove:function(e){var t=this.find(e);if(t==-1)return this;var n=this.content.slice();return n.splice(t,2),new Ps(n)},addToStart:function(e,t){return new Ps([e,t].concat(this.remove(e).content))},addToEnd:function(e,t){var n=this.remove(e).content.slice();return n.push(e,t),new Ps(n)},addBefore:function(e,t,n){var i=this.remove(t),o=i.content.slice(),s=i.find(e);return o.splice(s==-1?o.length:s,0,t,n),new Ps(o)},forEach:function(e){for(var t=0;t<this.content.length;t+=2)e(this.content[t],this.content[t+1])},prepend:function(e){return e=Ps.from(e),e.size?new Ps(e.content.concat(this.subtract(e).content)):this},append:function(e){return e=Ps.from(e),e.size?new Ps(this.subtract(e).content.concat(e.content)):this},subtract:function(e){var t=this;e=Ps.from(e);for(var n=0;n<e.content.length;n+=2)t=t.remove(e.content[n]);return t},toObject:function(){var e={};return this.forEach(function(t,n){e[t]=n}),e},get size(){return this.content.length>>1}};Ps.from=function(e){if(e instanceof Ps)return e;var t=[];if(e)for(var n in e)t.push(n,e[n]);return new Ps(t)};function HP(e,t,n){for(let i=0;;i++){if(i==e.childCount||i==t.childCount)return e.childCount==t.childCount?null:n;let o=e.child(i),s=t.child(i);if(o==s){n+=o.nodeSize;continue}if(!o.sameMarkup(s))return n;if(o.isText&&o.text!=s.text){let r=o.text,l=s.text,a=0;for(;r[a]==l[a];a++)n++;return a&&a<r.length&&a<l.length&&UP(r.charCodeAt(a-1))&&qP(r.charCodeAt(a))&&n--,n}if(o.content.size||s.content.size){let r=HP(o.content,s.content,n+1);if(r!=null)return r}n+=o.nodeSize}}function WP(e,t,n,i){for(let o=e.childCount,s=t.childCount;;){if(o==0||s==0)return o==s?null:{a:n,b:i};let r=e.child(--o),l=t.child(--s),a=r.nodeSize;if(r==l){n-=a,i-=a;continue}if(!r.sameMarkup(l))return{a:n,b:i};if(r.isText&&r.text!=l.text){let u=r.text,c=l.text,d=u.length,h=c.length;for(;d>0&&h>0&&u[d-1]==c[h-1];)d--,h--,n--,i--;return d&&h&&d<u.length&&UP(u.charCodeAt(d-1))&&qP(u.charCodeAt(d))&&(n++,i++),{a:n,b:i}}if(r.content.size||l.content.size){let u=WP(r.content,l.content,n-1,i-1);if(u)return u}n-=a,i-=a}}function qP(e){return e>=56320&&e<57344}function UP(e){return e>=55296&&e<56320}class Bn{constructor(t,n){if(this.content=t,this.size=n||0,n==null)for(let i=0;i<t.length;i++)this.size+=t[i].nodeSize}nodesBetween(t,n,i,o=0,s){for(let r=0,l=0;l<n;r++){let a=this.content[r],u=l+a.nodeSize;if(u>t&&i(a,o+l,s||null,r)!==!1&&a.content.size){let c=l+1;a.nodesBetween(Math.max(0,t-c),Math.min(a.content.size,n-c),i,o+c)}l=u}}descendants(t){this.nodesBetween(0,this.size,t)}textBetween(t,n,i,o){let s="",r=!0;return this.nodesBetween(t,n,(l,a)=>{let u=l.isText?l.text.slice(Math.max(t,a)-a,n-a):l.isLeaf?o?typeof o=="function"?o(l):o:l.type.spec.leafText?l.type.spec.leafText(l):"":"";l.isBlock&&(l.isLeaf&&u||l.isTextblock)&&i&&(r?r=!1:s+=i),s+=u},0),s}append(t){if(!t.size)return this;if(!this.size)return t;let n=this.lastChild,i=t.firstChild,o=this.content.slice(),s=0;for(n.isText&&n.sameMarkup(i)&&(o[o.length-1]=n.withText(n.text+i.text),s=1);s<t.content.length;s++)o.push(t.content[s]);return new Bn(o,this.size+t.size)}cut(t,n=this.size){if(t==0&&n==this.size)return this;let i=[],o=0;if(n>t)for(let s=0,r=0;r<n;s++){let l=this.content[s],a=r+l.nodeSize;a>t&&((r<t||a>n)&&(l.isText?l=l.cut(Math.max(0,t-r),Math.min(l.text.length,n-r)):l=l.cut(Math.max(0,t-r-1),Math.min(l.content.size,n-r-1))),i.push(l),o+=l.nodeSize),r=a}return new Bn(i,o)}cutByIndex(t,n){return t==n?Bn.empty:t==0&&n==this.content.length?this:new Bn(this.content.slice(t,n))}replaceChild(t,n){let i=this.content[t];if(i==n)return this;let o=this.content.slice(),s=this.size+n.nodeSize-i.nodeSize;return o[t]=n,new Bn(o,s)}addToStart(t){return new Bn([t].concat(this.content),this.size+t.nodeSize)}addToEnd(t){return new Bn(this.content.concat(t),this.size+t.nodeSize)}eq(t){if(this.content.length!=t.content.length)return!1;for(let n=0;n<this.content.length;n++)if(!this.content[n].eq(t.content[n]))return!1;return!0}get firstChild(){return this.content.length?this.content[0]:null}get lastChild(){return this.content.length?this.content[this.content.length-1]:null}get childCount(){return this.content.length}child(t){let n=this.content[t];if(!n)throw new RangeError("Index "+t+" out of range for "+this);return n}maybeChild(t){return this.content[t]||null}forEach(t){for(let n=0,i=0;n<this.content.length;n++){let o=this.content[n];t(o,i,n),i+=o.nodeSize}}findDiffStart(t,n=0){return HP(this,t,n)}findDiffEnd(t,n=this.size,i=t.size){return WP(this,t,n,i)}findIndex(t){if(t==0)return rv(0,t);if(t==this.size)return rv(this.content.length,t);if(t>this.size||t<0)throw new RangeError(`Position ${t} outside of fragment (${this})`);for(let n=0,i=0;;n++){let o=this.child(n),s=i+o.nodeSize;if(s>=t)return s==t?rv(n+1,s):rv(n,i);i=s}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map(t=>t.toJSON()):null}static fromJSON(t,n){if(!n)return Bn.empty;if(!Array.isArray(n))throw new RangeError("Invalid input for Fragment.fromJSON");return Bn.fromArray(n.map(t.nodeFromJSON))}static fromArray(t){if(!t.length)return Bn.empty;let n,i=0;for(let o=0;o<t.length;o++){let s=t[o];i+=s.nodeSize,o&&s.isText&&t[o-1].sameMarkup(s)?(n||(n=t.slice(0,o)),n[n.length-1]=s.withText(n[n.length-1].text+s.text)):n&&n.push(s)}return new Bn(n||t,i)}static from(t){if(!t)return Bn.empty;if(t instanceof Bn)return t;if(Array.isArray(t))return this.fromArray(t);if(t.attrs)return new Bn([t],t.nodeSize);throw new RangeError("Can not convert "+t+" to a Fragment"+(t.nodesBetween?" (looks like multiple versions of prosemirror-model were loaded)":""))}}Bn.empty=new Bn([],0);const Tk={index:0,offset:0};function rv(e,t){return Tk.index=e,Tk.offset=t,Tk}function Ay(e,t){if(e===t)return!0;if(!(e&&typeof e=="object")||!(t&&typeof t=="object"))return!1;let n=Array.isArray(e);if(Array.isArray(t)!=n)return!1;if(n){if(e.length!=t.length)return!1;for(let i=0;i<e.length;i++)if(!Ay(e[i],t[i]))return!1}else{for(let i in e)if(!(i in t)||!Ay(e[i],t[i]))return!1;for(let i in t)if(!(i in e))return!1}return!0}class eo{constructor(t,n){this.type=t,this.attrs=n}addToSet(t){let n,i=!1;for(let o=0;o<t.length;o++){let s=t[o];if(this.eq(s))return t;if(this.type.excludes(s.type))n||(n=t.slice(0,o));else{if(s.type.excludes(this.type))return t;!i&&s.type.rank>this.type.rank&&(n||(n=t.slice(0,o)),n.push(this),i=!0),n&&n.push(s)}}return n||(n=t.slice()),i||n.push(this),n}removeFromSet(t){for(let n=0;n<t.length;n++)if(this.eq(t[n]))return t.slice(0,n).concat(t.slice(n+1));return t}isInSet(t){for(let n=0;n<t.length;n++)if(this.eq(t[n]))return!0;return!1}eq(t){return this==t||this.type==t.type&&Ay(this.attrs,t.attrs)}toJSON(){let t={type:this.type.name};for(let n in this.attrs){t.attrs=this.attrs;break}return t}static fromJSON(t,n){if(!n)throw new RangeError("Invalid input for Mark.fromJSON");let i=t.marks[n.type];if(!i)throw new RangeError(`There is no mark type ${n.type} in this schema`);let o=i.create(n.attrs);return i.checkAttrs(o.attrs),o}static sameSet(t,n){if(t==n)return!0;if(t.length!=n.length)return!1;for(let i=0;i<t.length;i++)if(!t[i].eq(n[i]))return!1;return!0}static setFrom(t){if(!t||Array.isArray(t)&&t.length==0)return eo.none;if(t instanceof eo)return[t];let n=t.slice();return n.sort((i,o)=>i.type.rank-o.type.rank),n}}eo.none=[];class H0 extends Error{}class Qn{constructor(t,n,i){this.content=t,this.openStart=n,this.openEnd=i}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(t,n){let i=VP(this.content,t+this.openStart,n,this.openStart+1,this.openEnd+1);return i&&new Qn(i,this.openStart,this.openEnd)}removeBetween(t,n){return new Qn(KP(this.content,t+this.openStart,n+this.openStart),this.openStart,this.openEnd)}eq(t){return this.content.eq(t.content)&&this.openStart==t.openStart&&this.openEnd==t.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let t={content:this.content.toJSON()};return this.openStart>0&&(t.openStart=this.openStart),this.openEnd>0&&(t.openEnd=this.openEnd),t}static fromJSON(t,n){if(!n)return Qn.empty;let i=n.openStart||0,o=n.openEnd||0;if(typeof i!="number"||typeof o!="number")throw new RangeError("Invalid input for Slice.fromJSON");return new Qn(Bn.fromJSON(t,n.content),i,o)}static maxOpen(t,n=!0){let i=0,o=0;for(let s=t.firstChild;s&&!s.isLeaf&&(n||!s.type.spec.isolating);s=s.firstChild)i++;for(let s=t.lastChild;s&&!s.isLeaf&&(n||!s.type.spec.isolating);s=s.lastChild)o++;return new Qn(t,i,o)}}Qn.empty=new Qn(Bn.empty,0,0);function KP(e,t,n){let{index:i,offset:o}=e.findIndex(t),s=e.maybeChild(i),{index:r,offset:l}=e.findIndex(n);if(o==t||s.isText){if(l!=n&&!e.child(r).isText)throw new RangeError("Removing non-flat range");return e.cut(0,t).append(e.cut(n))}if(i!=r)throw new RangeError("Removing non-flat range");return e.replaceChild(i,s.copy(KP(s.content,t-o-1,n-o-1)))}function VP(e,t,n,i,o,s){let{index:r,offset:l}=e.findIndex(t),a=e.maybeChild(r);if(l==t||a.isText)return s&&i<=0&&o<=0&&!s.canReplace(r,r,n)?null:e.cut(0,t).append(n).append(e.cut(t));let u=VP(a.content,t-l-1,n,r==0?i-1:0,r==e.childCount-1?o-1:0,a);return u&&e.replaceChild(r,a.copy(u))}function ODe(e,t,n){if(n.openStart>e.depth)throw new H0("Inserted content deeper than insertion position");if(e.depth-n.openStart!=t.depth-n.openEnd)throw new H0("Inconsistent open depths");return ZP(e,t,n,0)}function ZP(e,t,n,i){let o=e.index(i),s=e.node(i);if(o==t.index(i)&&i<e.depth-n.openStart){let r=ZP(e,t,n,i+1);return s.copy(s.content.replaceChild(o,r))}else if(n.content.size)if(!n.openStart&&!n.openEnd&&e.depth==i&&t.depth==i){let r=e.parent,l=r.content;return ef(r,l.cut(0,e.parentOffset).append(n.content).append(l.cut(t.parentOffset)))}else{let{start:r,end:l}=PDe(n,e);return ef(s,QP(e,r,l,t,i))}else return ef(s,Cy(e,t,i))}function GP(e,t){if(!t.type.compatibleContent(e.type))throw new H0("Cannot join "+t.type.name+" onto "+e.type.name)}function f5(e,t,n){let i=e.node(n);return GP(i,t.node(n)),i}function Xd(e,t){let n=t.length-1;n>=0&&e.isText&&e.sameMarkup(t[n])?t[n]=e.withText(t[n].text+e.text):t.push(e)}function r0(e,t,n,i){let o=(t||e).node(n),s=0,r=t?t.index(n):o.childCount;e&&(s=e.index(n),e.depth>n?s++:e.textOffset&&(Xd(e.nodeAfter,i),s++));for(let l=s;l<r;l++)Xd(o.child(l),i);t&&t.depth==n&&t.textOffset&&Xd(t.nodeBefore,i)}function ef(e,t){if(!e.type.validContent(t))throw new H0("Invalid content for node "+e.type.name);return e.copy(t)}function QP(e,t,n,i,o){let s=e.depth>o&&f5(e,t,o+1),r=i.depth>o&&f5(n,i,o+1),l=[];return r0(null,e,o,l),s&&r&&t.index(o)==n.index(o)?(GP(s,r),Xd(ef(s,QP(e,t,n,i,o+1)),l)):(s&&Xd(ef(s,Cy(e,t,o+1)),l),r0(t,n,o,l),r&&Xd(ef(r,Cy(n,i,o+1)),l)),r0(i,null,o,l),new Bn(l)}function Cy(e,t,n){let i=[];if(r0(null,e,n,i),e.depth>n){let o=f5(e,t,n+1);Xd(ef(o,Cy(e,t,n+1)),i)}return r0(t,null,n,i),new Bn(i)}function PDe(e,t){let n=t.depth-e.openStart,o=t.node(n).copy(e.content);for(let s=n-1;s>=0;s--)o=t.node(s).copy(Bn.from(o));return{start:o.resolveNoCache(e.openStart+n),end:o.resolveNoCache(o.content.size-e.openEnd-n)}}class W0{constructor(t,n,i){this.pos=t,this.path=n,this.parentOffset=i,this.depth=n.length/3-1}resolveDepth(t){return t==null?this.depth:t<0?this.depth+t:t}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(t){return this.path[this.resolveDepth(t)*3]}index(t){return this.path[this.resolveDepth(t)*3+1]}indexAfter(t){return t=this.resolveDepth(t),this.index(t)+(t==this.depth&&!this.textOffset?0:1)}start(t){return t=this.resolveDepth(t),t==0?0:this.path[t*3-1]+1}end(t){return t=this.resolveDepth(t),this.start(t)+this.node(t).content.size}before(t){if(t=this.resolveDepth(t),!t)throw new RangeError("There is no position before the top-level node");return t==this.depth+1?this.pos:this.path[t*3-1]}after(t){if(t=this.resolveDepth(t),!t)throw new RangeError("There is no position after the top-level node");return t==this.depth+1?this.pos:this.path[t*3-1]+this.path[t*3].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let t=this.parent,n=this.index(this.depth);if(n==t.childCount)return null;let i=this.pos-this.path[this.path.length-1],o=t.child(n);return i?t.child(n).cut(i):o}get nodeBefore(){let t=this.index(this.depth),n=this.pos-this.path[this.path.length-1];return n?this.parent.child(t).cut(0,n):t==0?null:this.parent.child(t-1)}posAtIndex(t,n){n=this.resolveDepth(n);let i=this.path[n*3],o=n==0?0:this.path[n*3-1]+1;for(let s=0;s<t;s++)o+=i.child(s).nodeSize;return o}marks(){let t=this.parent,n=this.index();if(t.content.size==0)return eo.none;if(this.textOffset)return t.child(n).marks;let i=t.maybeChild(n-1),o=t.maybeChild(n);if(!i){let l=i;i=o,o=l}let s=i.marks;for(var r=0;r<s.length;r++)s[r].type.spec.inclusive===!1&&(!o||!s[r].isInSet(o.marks))&&(s=s[r--].removeFromSet(s));return s}marksAcross(t){let n=this.parent.maybeChild(this.index());if(!n||!n.isInline)return null;let i=n.marks,o=t.parent.maybeChild(t.index());for(var s=0;s<i.length;s++)i[s].type.spec.inclusive===!1&&(!o||!i[s].isInSet(o.marks))&&(i=i[s--].removeFromSet(i));return i}sharedDepth(t){for(let n=this.depth;n>0;n--)if(this.start(n)<=t&&this.end(n)>=t)return n;return 0}blockRange(t=this,n){if(t.pos<this.pos)return t.blockRange(this);for(let i=this.depth-(this.parent.inlineContent||this.pos==t.pos?1:0);i>=0;i--)if(t.pos<=this.end(i)&&(!n||n(this.node(i))))return new WDe(this,t,i);return null}sameParent(t){return this.pos-this.parentOffset==t.pos-t.parentOffset}max(t){return t.pos>this.pos?t:this}min(t){return t.pos<this.pos?t:this}toString(){let t="";for(let n=1;n<=this.depth;n++)t+=(t?"/":"")+this.node(n).type.name+"_"+this.index(n-1);return t+":"+this.parentOffset}static resolve(t,n){if(!(n>=0&&n<=t.content.size))throw new RangeError("Position "+n+" out of range");let i=[],o=0,s=n;for(let r=t;;){let{index:l,offset:a}=r.content.findIndex(s),u=s-a;if(i.push(r,l,o+a),!u||(r=r.child(l),r.isText))break;s=u-1,o+=a+1}return new W0(n,i,s)}static resolveCached(t,n){let i=CT.get(t);if(i)for(let s=0;s<i.elts.length;s++){let r=i.elts[s];if(r.pos==n)return r}else CT.set(t,i=new jDe);let o=i.elts[i.i]=W0.resolve(t,n);return i.i=(i.i+1)%HDe,o}}class jDe{constructor(){this.elts=[],this.i=0}}const HDe=12,CT=new WeakMap;class WDe{constructor(t,n,i){this.$from=t,this.$to=n,this.depth=i}get start(){return this.$from.before(this.depth+1)}get end(){return this.$to.after(this.depth+1)}get parent(){return this.$from.node(this.depth)}get startIndex(){return this.$from.index(this.depth)}get endIndex(){return this.$to.indexAfter(this.depth)}}const qDe=Object.create(null);let Hh=class h5{constructor(t,n,i,o=eo.none){this.type=t,this.attrs=n,this.marks=o,this.content=i||Bn.empty}get children(){return this.content.content}get nodeSize(){return this.isLeaf?1:2+this.content.size}get childCount(){return this.content.childCount}child(t){return this.content.child(t)}maybeChild(t){return this.content.maybeChild(t)}forEach(t){this.content.forEach(t)}nodesBetween(t,n,i,o=0){this.content.nodesBetween(t,n,i,o,this)}descendants(t){this.nodesBetween(0,this.content.size,t)}get textContent(){return this.isLeaf&&this.type.spec.leafText?this.type.spec.leafText(this):this.textBetween(0,this.content.size,"")}textBetween(t,n,i,o){return this.content.textBetween(t,n,i,o)}get firstChild(){return this.content.firstChild}get lastChild(){return this.content.lastChild}eq(t){return this==t||this.sameMarkup(t)&&this.content.eq(t.content)}sameMarkup(t){return this.hasMarkup(t.type,t.attrs,t.marks)}hasMarkup(t,n,i){return this.type==t&&Ay(this.attrs,n||t.defaultAttrs||qDe)&&eo.sameSet(this.marks,i||eo.none)}copy(t=null){return t==this.content?this:new h5(this.type,this.attrs,t,this.marks)}mark(t){return t==this.marks?this:new h5(this.type,this.attrs,this.content,t)}cut(t,n=this.content.size){return t==0&&n==this.content.size?this:this.copy(this.content.cut(t,n))}slice(t,n=this.content.size,i=!1){if(t==n)return Qn.empty;let o=this.resolve(t),s=this.resolve(n),r=i?0:o.sharedDepth(n),l=o.start(r),u=o.node(r).content.cut(o.pos-l,s.pos-l);return new Qn(u,o.depth-r,s.depth-r)}replace(t,n,i){return ODe(this.resolve(t),this.resolve(n),i)}nodeAt(t){for(let n=this;;){let{index:i,offset:o}=n.content.findIndex(t);if(n=n.maybeChild(i),!n)return null;if(o==t||n.isText)return n;t-=o+1}}childAfter(t){let{index:n,offset:i}=this.content.findIndex(t);return{node:this.content.maybeChild(n),index:n,offset:i}}childBefore(t){if(t==0)return{node:null,index:0,offset:0};let{index:n,offset:i}=this.content.findIndex(t);if(i<t)return{node:this.content.child(n),index:n,offset:i};let o=this.content.child(n-1);return{node:o,index:n-1,offset:i-o.nodeSize}}resolve(t){return W0.resolveCached(this,t)}resolveNoCache(t){return W0.resolve(this,t)}rangeHasMark(t,n,i){let o=!1;return n>t&&this.nodesBetween(t,n,s=>(i.isInSet(s.marks)&&(o=!0),!o)),o}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let t=this.type.name;return this.content.size&&(t+="("+this.content.toStringInner()+")"),YP(this.marks,t)}contentMatchAt(t){let n=this.type.contentMatch.matchFragment(this.content,0,t);if(!n)throw new Error("Called contentMatchAt on a node with invalid content");return n}canReplace(t,n,i=Bn.empty,o=0,s=i.childCount){let r=this.contentMatchAt(t).matchFragment(i,o,s),l=r&&r.matchFragment(this.content,n);if(!l||!l.validEnd)return!1;for(let a=o;a<s;a++)if(!this.type.allowsMarks(i.child(a).marks))return!1;return!0}canReplaceWith(t,n,i,o){if(o&&!this.type.allowsMarks(o))return!1;let s=this.contentMatchAt(t).matchType(i),r=s&&s.matchFragment(this.content,n);return r?r.validEnd:!1}canAppend(t){return t.content.size?this.canReplace(this.childCount,this.childCount,t.content):this.type.compatibleContent(t.type)}check(){this.type.checkContent(this.content),this.type.checkAttrs(this.attrs);let t=eo.none;for(let n=0;n<this.marks.length;n++){let i=this.marks[n];i.type.checkAttrs(i.attrs),t=i.addToSet(t)}if(!eo.sameSet(t,this.marks))throw new RangeError(`Invalid collection of marks for node ${this.type.name}: ${this.marks.map(n=>n.type.name)}`);this.content.forEach(n=>n.check())}toJSON(){let t={type:this.type.name};for(let n in this.attrs){t.attrs=this.attrs;break}return this.content.size&&(t.content=this.content.toJSON()),this.marks.length&&(t.marks=this.marks.map(n=>n.toJSON())),t}static fromJSON(t,n){if(!n)throw new RangeError("Invalid input for Node.fromJSON");let i;if(n.marks){if(!Array.isArray(n.marks))throw new RangeError("Invalid mark data for Node.fromJSON");i=n.marks.map(t.markFromJSON)}if(n.type=="text"){if(typeof n.text!="string")throw new RangeError("Invalid text node in JSON");return t.text(n.text,i)}let o=Bn.fromJSON(t,n.content),s=t.nodeType(n.type).create(n.attrs,o,i);return s.type.checkAttrs(s.attrs),s}};Hh.prototype.text=void 0;class wy extends Hh{constructor(t,n,i,o){if(super(t,n,null,o),!i)throw new RangeError("Empty text nodes are not allowed");this.text=i}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):YP(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(t,n){return this.text.slice(t,n)}get nodeSize(){return this.text.length}mark(t){return t==this.marks?this:new wy(this.type,this.attrs,this.text,t)}withText(t){return t==this.text?this:new wy(this.type,this.attrs,t,this.marks)}cut(t=0,n=this.text.length){return t==0&&n==this.text.length?this:this.withText(this.text.slice(t,n))}eq(t){return this.sameMarkup(t)&&this.text==t.text}toJSON(){let t=super.toJSON();return t.text=this.text,t}}function YP(e,t){for(let n=e.length-1;n>=0;n--)t=e[n].type.name+"("+t+")";return t}class gf{constructor(t){this.validEnd=t,this.next=[],this.wrapCache=[]}static parse(t,n){let i=new UDe(t,n);if(i.next==null)return gf.empty;let o=JP(i);i.next&&i.err("Unexpected trailing text");let s=JDe(YDe(o));return XDe(s,i),s}matchType(t){for(let n=0;n<this.next.length;n++)if(this.next[n].type==t)return this.next[n].next;return null}matchFragment(t,n=0,i=t.childCount){let o=this;for(let s=n;o&&s<i;s++)o=o.matchType(t.child(s).type);return o}get inlineContent(){return this.next.length!=0&&this.next[0].type.isInline}get defaultType(){for(let t=0;t<this.next.length;t++){let{type:n}=this.next[t];if(!(n.isText||n.hasRequiredAttrs()))return n}return null}compatible(t){for(let n=0;n<this.next.length;n++)for(let i=0;i<t.next.length;i++)if(this.next[n].type==t.next[i].type)return!0;return!1}fillBefore(t,n=!1,i=0){let o=[this];function s(r,l){let a=r.matchFragment(t,i);if(a&&(!n||a.validEnd))return Bn.from(l.map(u=>u.createAndFill()));for(let u=0;u<r.next.length;u++){let{type:c,next:d}=r.next[u];if(!(c.isText||c.hasRequiredAttrs())&&o.indexOf(d)==-1){o.push(d);let h=s(d,l.concat(c));if(h)return h}}return null}return s(this,[])}findWrapping(t){for(let i=0;i<this.wrapCache.length;i+=2)if(this.wrapCache[i]==t)return this.wrapCache[i+1];let n=this.computeWrapping(t);return this.wrapCache.push(t,n),n}computeWrapping(t){let n=Object.create(null),i=[{match:this,type:null,via:null}];for(;i.length;){let o=i.shift(),s=o.match;if(s.matchType(t)){let r=[];for(let l=o;l.type;l=l.via)r.push(l.type);return r.reverse()}for(let r=0;r<s.next.length;r++){let{type:l,next:a}=s.next[r];!l.isLeaf&&!l.hasRequiredAttrs()&&!(l.name in n)&&(!o.type||a.validEnd)&&(i.push({match:l.contentMatch,type:l,via:o}),n[l.name]=!0)}}return null}get edgeCount(){return this.next.length}edge(t){if(t>=this.next.length)throw new RangeError(`There's no ${t}th edge in this content match`);return this.next[t]}toString(){let t=[];function n(i){t.push(i);for(let o=0;o<i.next.length;o++)t.indexOf(i.next[o].next)==-1&&n(i.next[o].next)}return n(this),t.map((i,o)=>{let s=o+(i.validEnd?"*":" ")+" ";for(let r=0;r<i.next.length;r++)s+=(r?", ":"")+i.next[r].type.name+"->"+t.indexOf(i.next[r].next);return s}).join(` -`)}}gf.empty=new gf(!0);class UDe{constructor(t,n){this.string=t,this.nodeTypes=n,this.inline=null,this.pos=0,this.tokens=t.split(/\s*(?=\b|\W|$)/),this.tokens[this.tokens.length-1]==""&&this.tokens.pop(),this.tokens[0]==""&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(t){return this.next==t&&(this.pos++||!0)}err(t){throw new SyntaxError(t+" (in content expression '"+this.string+"')")}}function JP(e){let t=[];do t.push(KDe(e));while(e.eat("|"));return t.length==1?t[0]:{type:"choice",exprs:t}}function KDe(e){let t=[];do t.push(VDe(e));while(e.next&&e.next!=")"&&e.next!="|");return t.length==1?t[0]:{type:"seq",exprs:t}}function VDe(e){let t=QDe(e);for(;;)if(e.eat("+"))t={type:"plus",expr:t};else if(e.eat("*"))t={type:"star",expr:t};else if(e.eat("?"))t={type:"opt",expr:t};else if(e.eat("{"))t=ZDe(e,t);else break;return t}function wT(e){/\D/.test(e.next)&&e.err("Expected number, got '"+e.next+"'");let t=Number(e.next);return e.pos++,t}function ZDe(e,t){let n=wT(e),i=n;return e.eat(",")&&(e.next!="}"?i=wT(e):i=-1),e.eat("}")||e.err("Unclosed braced range"),{type:"range",min:n,max:i,expr:t}}function GDe(e,t){let n=e.nodeTypes,i=n[t];if(i)return[i];let o=[];for(let s in n){let r=n[s];r.isInGroup(t)&&o.push(r)}return o.length==0&&e.err("No node type or group '"+t+"' found"),o}function QDe(e){if(e.eat("(")){let t=JP(e);return e.eat(")")||e.err("Missing closing paren"),t}else if(/\W/.test(e.next))e.err("Unexpected token '"+e.next+"'");else{let t=GDe(e,e.next).map(n=>(e.inline==null?e.inline=n.isInline:e.inline!=n.isInline&&e.err("Mixing inline and block content"),{type:"name",value:n}));return e.pos++,t.length==1?t[0]:{type:"choice",exprs:t}}}function YDe(e){let t=[[]];return o(s(e,0),n()),t;function n(){return t.push([])-1}function i(r,l,a){let u={term:a,to:l};return t[r].push(u),u}function o(r,l){r.forEach(a=>a.to=l)}function s(r,l){if(r.type=="choice")return r.exprs.reduce((a,u)=>a.concat(s(u,l)),[]);if(r.type=="seq")for(let a=0;;a++){let u=s(r.exprs[a],l);if(a==r.exprs.length-1)return u;o(u,l=n())}else if(r.type=="star"){let a=n();return i(l,a),o(s(r.expr,a),a),[i(a)]}else if(r.type=="plus"){let a=n();return o(s(r.expr,l),a),o(s(r.expr,a),a),[i(a)]}else{if(r.type=="opt")return[i(l)].concat(s(r.expr,l));if(r.type=="range"){let a=l;for(let u=0;u<r.min;u++){let c=n();o(s(r.expr,a),c),a=c}if(r.max==-1)o(s(r.expr,a),a);else for(let u=r.min;u<r.max;u++){let c=n();i(a,c),o(s(r.expr,a),c),a=c}return[i(a)]}else{if(r.type=="name")return[i(l,void 0,r.value)];throw new Error("Unknown expr type")}}}}function XP(e,t){return t-e}function xT(e,t){let n=[];return i(t),n.sort(XP);function i(o){let s=e[o];if(s.length==1&&!s[0].term)return i(s[0].to);n.push(o);for(let r=0;r<s.length;r++){let{term:l,to:a}=s[r];!l&&n.indexOf(a)==-1&&i(a)}}}function JDe(e){let t=Object.create(null);return n(xT(e,0));function n(i){let o=[];i.forEach(r=>{e[r].forEach(({term:l,to:a})=>{if(!l)return;let u;for(let c=0;c<o.length;c++)o[c][0]==l&&(u=o[c][1]);xT(e,a).forEach(c=>{u||o.push([l,u=[]]),u.indexOf(c)==-1&&u.push(c)})})});let s=t[i.join(",")]=new gf(i.indexOf(e.length-1)>-1);for(let r=0;r<o.length;r++){let l=o[r][1].sort(XP);s.next.push({type:o[r][0],next:t[l.join(",")]||n(l)})}return s}}function XDe(e,t){for(let n=0,i=[e];n<i.length;n++){let o=i[n],s=!o.validEnd,r=[];for(let l=0;l<o.next.length;l++){let{type:a,next:u}=o.next[l];r.push(a.name),s&&!(a.isText||a.hasRequiredAttrs())&&(s=!1),i.indexOf(u)==-1&&i.push(u)}s&&t.err("Only non-generatable nodes ("+r.join(", ")+") in a required position (see https://prosemirror.net/docs/guide/#generatable)")}}function ej(e){let t=Object.create(null);for(let n in e){let i=e[n];if(!i.hasDefault)return null;t[n]=i.default}return t}function tj(e,t){let n=Object.create(null);for(let i in e){let o=t&&t[i];if(o===void 0){let s=e[i];if(s.hasDefault)o=s.default;else throw new RangeError("No value supplied for attribute "+i)}n[i]=o}return n}function nj(e,t,n,i){for(let o in t)if(!(o in e))throw new RangeError(`Unsupported attribute ${o} for ${n} of type ${i}`);for(let o in e)e[o].validate&&e[o].validate(t[o])}function ij(e,t){let n=Object.create(null);if(t)for(let i in t)n[i]=new tBe(e,i,t[i]);return n}let ST=class oj{constructor(t,n,i){this.name=t,this.schema=n,this.spec=i,this.markSet=null,this.groups=i.group?i.group.split(" "):[],this.attrs=ij(t,i.attrs),this.defaultAttrs=ej(this.attrs),this.contentMatch=null,this.inlineContent=null,this.isBlock=!(i.inline||t=="text"),this.isText=t=="text"}get isInline(){return!this.isBlock}get isTextblock(){return this.isBlock&&this.inlineContent}get isLeaf(){return this.contentMatch==gf.empty}get isAtom(){return this.isLeaf||!!this.spec.atom}isInGroup(t){return this.groups.indexOf(t)>-1}get whitespace(){return this.spec.whitespace||(this.spec.code?"pre":"normal")}hasRequiredAttrs(){for(let t in this.attrs)if(this.attrs[t].isRequired)return!0;return!1}compatibleContent(t){return this==t||this.contentMatch.compatible(t.contentMatch)}computeAttrs(t){return!t&&this.defaultAttrs?this.defaultAttrs:tj(this.attrs,t)}create(t=null,n,i){if(this.isText)throw new Error("NodeType.create can't construct text nodes");return new Hh(this,this.computeAttrs(t),Bn.from(n),eo.setFrom(i))}createChecked(t=null,n,i){return n=Bn.from(n),this.checkContent(n),new Hh(this,this.computeAttrs(t),n,eo.setFrom(i))}createAndFill(t=null,n,i){if(t=this.computeAttrs(t),n=Bn.from(n),n.size){let r=this.contentMatch.fillBefore(n);if(!r)return null;n=r.append(n)}let o=this.contentMatch.matchFragment(n),s=o&&o.fillBefore(Bn.empty,!0);return s?new Hh(this,t,n.append(s),eo.setFrom(i)):null}validContent(t){let n=this.contentMatch.matchFragment(t);if(!n||!n.validEnd)return!1;for(let i=0;i<t.childCount;i++)if(!this.allowsMarks(t.child(i).marks))return!1;return!0}checkContent(t){if(!this.validContent(t))throw new RangeError(`Invalid content for node ${this.name}: ${t.toString().slice(0,50)}`)}checkAttrs(t){nj(this.attrs,t,"node",this.name)}allowsMarkType(t){return this.markSet==null||this.markSet.indexOf(t)>-1}allowsMarks(t){if(this.markSet==null)return!0;for(let n=0;n<t.length;n++)if(!this.allowsMarkType(t[n].type))return!1;return!0}allowedMarks(t){if(this.markSet==null)return t;let n;for(let i=0;i<t.length;i++)this.allowsMarkType(t[i].type)?n&&n.push(t[i]):n||(n=t.slice(0,i));return n?n.length?n:eo.none:t}static compile(t,n){let i=Object.create(null);t.forEach((s,r)=>i[s]=new oj(s,n,r));let o=n.spec.topNode||"doc";if(!i[o])throw new RangeError("Schema is missing its top node type ('"+o+"')");if(!i.text)throw new RangeError("Every schema needs a 'text' type");for(let s in i.text.attrs)throw new RangeError("The text node type should not have attributes");return i}};function eBe(e,t,n){let i=n.split("|");return o=>{let s=o===null?"null":typeof o;if(i.indexOf(s)<0)throw new RangeError(`Expected value of type ${i} for attribute ${t} on type ${e}, got ${s}`)}}class tBe{constructor(t,n,i){this.hasDefault=Object.prototype.hasOwnProperty.call(i,"default"),this.default=i.default,this.validate=typeof i.validate=="string"?eBe(t,n,i.validate):i.validate}get isRequired(){return!this.hasDefault}}class lA{constructor(t,n,i,o){this.name=t,this.rank=n,this.schema=i,this.spec=o,this.attrs=ij(t,o.attrs),this.excluded=null;let s=ej(this.attrs);this.instance=s?new eo(this,s):null}create(t=null){return!t&&this.instance?this.instance:new eo(this,tj(this.attrs,t))}static compile(t,n){let i=Object.create(null),o=0;return t.forEach((s,r)=>i[s]=new lA(s,o++,n,r)),i}removeFromSet(t){for(var n=0;n<t.length;n++)t[n].type==this&&(t=t.slice(0,n).concat(t.slice(n+1)),n--);return t}isInSet(t){for(let n=0;n<t.length;n++)if(t[n].type==this)return t[n]}checkAttrs(t){nj(this.attrs,t,"mark",this.name)}excludes(t){return this.excluded.indexOf(t)>-1}}class nBe{constructor(t){this.linebreakReplacement=null,this.cached=Object.create(null);let n=this.spec={};for(let o in t)n[o]=t[o];n.nodes=Ps.from(t.nodes),n.marks=Ps.from(t.marks||{}),this.nodes=ST.compile(this.spec.nodes,this),this.marks=lA.compile(this.spec.marks,this);let i=Object.create(null);for(let o in this.nodes){if(o in this.marks)throw new RangeError(o+" can not be both a node and a mark");let s=this.nodes[o],r=s.spec.content||"",l=s.spec.marks;if(s.contentMatch=i[r]||(i[r]=gf.parse(r,this.nodes)),s.inlineContent=s.contentMatch.inlineContent,s.spec.linebreakReplacement){if(this.linebreakReplacement)throw new RangeError("Multiple linebreak nodes defined");if(!s.isInline||!s.isLeaf)throw new RangeError("Linebreak replacement nodes must be inline leaf nodes");this.linebreakReplacement=s}s.markSet=l=="_"?null:l?_T(this,l.split(" ")):l==""||!s.inlineContent?[]:null}for(let o in this.marks){let s=this.marks[o],r=s.spec.excludes;s.excluded=r==null?[s]:r==""?[]:_T(this,r.split(" "))}this.nodeFromJSON=o=>Hh.fromJSON(this,o),this.markFromJSON=o=>eo.fromJSON(this,o),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(t,n=null,i,o){if(typeof t=="string")t=this.nodeType(t);else if(t instanceof ST){if(t.schema!=this)throw new RangeError("Node type from different schema used ("+t.name+")")}else throw new RangeError("Invalid node type: "+t);return t.createChecked(n,i,o)}text(t,n){let i=this.nodes.text;return new wy(i,i.defaultAttrs,t,eo.setFrom(n))}mark(t,n){return typeof t=="string"&&(t=this.marks[t]),t.create(n)}nodeType(t){let n=this.nodes[t];if(!n)throw new RangeError("Unknown node type: "+t);return n}}function _T(e,t){let n=[];for(let i=0;i<t.length;i++){let o=t[i],s=e.marks[o],r=s;if(s)n.push(s);else for(let l in e.marks){let a=e.marks[l];(o=="_"||a.spec.group&&a.spec.group.split(" ").indexOf(o)>-1)&&n.push(r=a)}if(!r)throw new SyntaxError("Unknown mark type: '"+t[i]+"'")}return n}function iBe(e){return e.tag!=null}function oBe(e){return e.style!=null}let sBe=class p5{constructor(t,n){this.schema=t,this.rules=n,this.tags=[],this.styles=[];let i=this.matchedStyles=[];n.forEach(o=>{if(iBe(o))this.tags.push(o);else if(oBe(o)){let s=/[^=]*/.exec(o.style)[0];i.indexOf(s)<0&&i.push(s),this.styles.push(o)}}),this.normalizeLists=!this.tags.some(o=>{if(!/^(ul|ol)\b/.test(o.tag)||!o.node)return!1;let s=t.nodes[o.node];return s.contentMatch.matchType(s)})}parse(t,n={}){let i=new IT(this,n,!1);return i.addAll(t,eo.none,n.from,n.to),i.finish()}parseSlice(t,n={}){let i=new IT(this,n,!0);return i.addAll(t,eo.none,n.from,n.to),Qn.maxOpen(i.finish())}matchTag(t,n,i){for(let o=i?this.tags.indexOf(i)+1:0;o<this.tags.length;o++){let s=this.tags[o];if(aBe(t,s.tag)&&(s.namespace===void 0||t.namespaceURI==s.namespace)&&(!s.context||n.matchesContext(s.context))){if(s.getAttrs){let r=s.getAttrs(t);if(r===!1)continue;s.attrs=r||void 0}return s}}}matchStyle(t,n,i,o){for(let s=o?this.styles.indexOf(o)+1:0;s<this.styles.length;s++){let r=this.styles[s],l=r.style;if(!(l.indexOf(t)!=0||r.context&&!i.matchesContext(r.context)||l.length>t.length&&(l.charCodeAt(t.length)!=61||l.slice(t.length+1)!=n))){if(r.getAttrs){let a=r.getAttrs(n);if(a===!1)continue;r.attrs=a||void 0}return r}}}static schemaRules(t){let n=[];function i(o){let s=o.priority==null?50:o.priority,r=0;for(;r<n.length;r++){let l=n[r];if((l.priority==null?50:l.priority)<s)break}n.splice(r,0,o)}for(let o in t.marks){let s=t.marks[o].spec.parseDOM;s&&s.forEach(r=>{i(r=ET(r)),r.mark||r.ignore||r.clearMark||(r.mark=o)})}for(let o in t.nodes){let s=t.nodes[o].spec.parseDOM;s&&s.forEach(r=>{i(r=ET(r)),r.node||r.ignore||r.mark||(r.node=o)})}return n}static fromSchema(t){return t.cached.domParser||(t.cached.domParser=new p5(t,p5.schemaRules(t)))}};const sj={address:!0,article:!0,aside:!0,blockquote:!0,body:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},rBe={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},rj={ol:!0,ul:!0},q0=1,g5=2,l0=4;function MT(e,t,n){return t!=null?(t?q0:0)|(t==="full"?g5:0):e&&e.whitespace=="pre"?q0|g5:n&~l0}class lv{constructor(t,n,i,o,s,r){this.type=t,this.attrs=n,this.marks=i,this.solid=o,this.options=r,this.content=[],this.activeMarks=eo.none,this.match=s||(r&l0?null:t.contentMatch)}findWrapping(t){if(!this.match){if(!this.type)return[];let n=this.type.contentMatch.fillBefore(Bn.from(t));if(n)this.match=this.type.contentMatch.matchFragment(n);else{let i=this.type.contentMatch,o;return(o=i.findWrapping(t.type))?(this.match=i,o):null}}return this.match.findWrapping(t.type)}finish(t){if(!(this.options&q0)){let i=this.content[this.content.length-1],o;if(i&&i.isText&&(o=/[ \t\r\n\u000c]+$/.exec(i.text))){let s=i;i.text.length==o[0].length?this.content.pop():this.content[this.content.length-1]=s.withText(s.text.slice(0,s.text.length-o[0].length))}}let n=Bn.from(this.content);return!t&&this.match&&(n=n.append(this.match.fillBefore(Bn.empty,!0))),this.type?this.type.create(this.attrs,n,this.marks):n}inlineContext(t){return this.type?this.type.inlineContent:this.content.length?this.content[0].isInline:t.parentNode&&!sj.hasOwnProperty(t.parentNode.nodeName.toLowerCase())}}class IT{constructor(t,n,i){this.parser=t,this.options=n,this.isOpen=i,this.open=0,this.localPreserveWS=!1;let o=n.topNode,s,r=MT(null,n.preserveWhitespace,0)|(i?l0:0);o?s=new lv(o.type,o.attrs,eo.none,!0,n.topMatch||o.type.contentMatch,r):i?s=new lv(null,null,eo.none,!0,null,r):s=new lv(t.schema.topNodeType,null,eo.none,!0,null,r),this.nodes=[s],this.find=n.findPositions,this.needsBlock=!1}get top(){return this.nodes[this.open]}addDOM(t,n){t.nodeType==3?this.addTextNode(t,n):t.nodeType==1&&this.addElement(t,n)}addTextNode(t,n){let i=t.nodeValue,o=this.top,s=o.options&g5?"full":this.localPreserveWS||(o.options&q0)>0,{schema:r}=this.parser;if(s==="full"||o.inlineContext(t)||/[^ \t\r\n\u000c]/.test(i)){if(s)if(s==="full")i=i.replace(/\r\n?/g,` -`);else if(r.linebreakReplacement&&/[\r\n]/.test(i)&&this.top.findWrapping(r.linebreakReplacement.create())){let l=i.split(/\r?\n|\r/);for(let a=0;a<l.length;a++)a&&this.insertNode(r.linebreakReplacement.create(),n,!0),l[a]&&this.insertNode(r.text(l[a]),n,!/\S/.test(l[a]));i=""}else i=i.replace(/\r?\n|\r/g," ");else if(i=i.replace(/[ \t\r\n\u000c]+/g," "),/^[ \t\r\n\u000c]/.test(i)&&this.open==this.nodes.length-1){let l=o.content[o.content.length-1],a=t.previousSibling;(!l||a&&a.nodeName=="BR"||l.isText&&/[ \t\r\n\u000c]$/.test(l.text))&&(i=i.slice(1))}i&&this.insertNode(r.text(i),n,!/\S/.test(i)),this.findInText(t)}else this.findInside(t)}addElement(t,n,i){let o=this.localPreserveWS,s=this.top;(t.tagName=="PRE"||/pre/.test(t.style&&t.style.whiteSpace))&&(this.localPreserveWS=!0);let r=t.nodeName.toLowerCase(),l;rj.hasOwnProperty(r)&&this.parser.normalizeLists&&lBe(t);let a=this.options.ruleFromNode&&this.options.ruleFromNode(t)||(l=this.parser.matchTag(t,this,i));e:if(a?a.ignore:rBe.hasOwnProperty(r))this.findInside(t),this.ignoreFallback(t,n);else if(!a||a.skip||a.closeParent){a&&a.closeParent?this.open=Math.max(0,this.open-1):a&&a.skip.nodeType&&(t=a.skip);let u,c=this.needsBlock;if(sj.hasOwnProperty(r))s.content.length&&s.content[0].isInline&&this.open&&(this.open--,s=this.top),u=!0,s.type||(this.needsBlock=!0);else if(!t.firstChild){this.leafFallback(t,n);break e}let d=a&&a.skip?n:this.readStyles(t,n);d&&this.addAll(t,d),u&&this.sync(s),this.needsBlock=c}else{let u=this.readStyles(t,n);u&&this.addElementByRule(t,a,u,a.consuming===!1?l:void 0)}this.localPreserveWS=o}leafFallback(t,n){t.nodeName=="BR"&&this.top.type&&this.top.type.inlineContent&&this.addTextNode(t.ownerDocument.createTextNode(` -`),n)}ignoreFallback(t,n){t.nodeName=="BR"&&(!this.top.type||!this.top.type.inlineContent)&&this.findPlace(this.parser.schema.text("-"),n,!0)}readStyles(t,n){let i=t.style;if(i&&i.length)for(let o=0;o<this.parser.matchedStyles.length;o++){let s=this.parser.matchedStyles[o],r=i.getPropertyValue(s);if(r)for(let l=void 0;;){let a=this.parser.matchStyle(s,r,this,l);if(!a)break;if(a.ignore)return null;if(a.clearMark?n=n.filter(u=>!a.clearMark(u)):n=n.concat(this.parser.schema.marks[a.mark].create(a.attrs)),a.consuming===!1)l=a;else break}}return n}addElementByRule(t,n,i,o){let s,r;if(n.node)if(r=this.parser.schema.nodes[n.node],r.isLeaf)this.insertNode(r.create(n.attrs),i,t.nodeName=="BR")||this.leafFallback(t,i);else{let a=this.enter(r,n.attrs||null,i,n.preserveWhitespace);a&&(s=!0,i=a)}else{let a=this.parser.schema.marks[n.mark];i=i.concat(a.create(n.attrs))}let l=this.top;if(r&&r.isLeaf)this.findInside(t);else if(o)this.addElement(t,i,o);else if(n.getContent)this.findInside(t),n.getContent(t,this.parser.schema).forEach(a=>this.insertNode(a,i,!1));else{let a=t;typeof n.contentElement=="string"?a=t.querySelector(n.contentElement):typeof n.contentElement=="function"?a=n.contentElement(t):n.contentElement&&(a=n.contentElement),this.findAround(t,a,!0),this.addAll(a,i),this.findAround(t,a,!1)}s&&this.sync(l)&&this.open--}addAll(t,n,i,o){let s=i||0;for(let r=i?t.childNodes[i]:t.firstChild,l=o==null?null:t.childNodes[o];r!=l;r=r.nextSibling,++s)this.findAtPoint(t,s),this.addDOM(r,n);this.findAtPoint(t,s)}findPlace(t,n,i){let o,s;for(let r=this.open,l=0;r>=0;r--){let a=this.nodes[r],u=a.findWrapping(t);if(u&&(!o||o.length>u.length+l)&&(o=u,s=a,!u.length))break;if(a.solid){if(i)break;l+=2}}if(!o)return null;this.sync(s);for(let r=0;r<o.length;r++)n=this.enterInner(o[r],null,n,!1);return n}insertNode(t,n,i){if(t.isInline&&this.needsBlock&&!this.top.type){let s=this.textblockFromContext();s&&(n=this.enterInner(s,null,n))}let o=this.findPlace(t,n,i);if(o){this.closeExtra();let s=this.top;s.match&&(s.match=s.match.matchType(t.type));let r=eo.none;for(let l of o.concat(t.marks))(s.type?s.type.allowsMarkType(l.type):TT(l.type,t.type))&&(r=l.addToSet(r));return s.content.push(t.mark(r)),!0}return!1}enter(t,n,i,o){let s=this.findPlace(t.create(n),i,!1);return s&&(s=this.enterInner(t,n,i,!0,o)),s}enterInner(t,n,i,o=!1,s){this.closeExtra();let r=this.top;r.match=r.match&&r.match.matchType(t);let l=MT(t,s,r.options);r.options&l0&&r.content.length==0&&(l|=l0);let a=eo.none;return i=i.filter(u=>(r.type?r.type.allowsMarkType(u.type):TT(u.type,t))?(a=u.addToSet(a),!1):!0),this.nodes.push(new lv(t,n,a,o,null,l)),this.open++,i}closeExtra(t=!1){let n=this.nodes.length-1;if(n>this.open){for(;n>this.open;n--)this.nodes[n-1].content.push(this.nodes[n].finish(t));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(!!(this.isOpen||this.options.topOpen))}sync(t){for(let n=this.open;n>=0;n--){if(this.nodes[n]==t)return this.open=n,!0;this.localPreserveWS&&(this.nodes[n].options|=q0)}return!1}get currentPos(){this.closeExtra();let t=0;for(let n=this.open;n>=0;n--){let i=this.nodes[n].content;for(let o=i.length-1;o>=0;o--)t+=i[o].nodeSize;n&&t++}return t}findAtPoint(t,n){if(this.find)for(let i=0;i<this.find.length;i++)this.find[i].node==t&&this.find[i].offset==n&&(this.find[i].pos=this.currentPos)}findInside(t){if(this.find)for(let n=0;n<this.find.length;n++)this.find[n].pos==null&&t.nodeType==1&&t.contains(this.find[n].node)&&(this.find[n].pos=this.currentPos)}findAround(t,n,i){if(t!=n&&this.find)for(let o=0;o<this.find.length;o++)this.find[o].pos==null&&t.nodeType==1&&t.contains(this.find[o].node)&&n.compareDocumentPosition(this.find[o].node)&(i?2:4)&&(this.find[o].pos=this.currentPos)}findInText(t){if(this.find)for(let n=0;n<this.find.length;n++)this.find[n].node==t&&(this.find[n].pos=this.currentPos-(t.nodeValue.length-this.find[n].offset))}matchesContext(t){if(t.indexOf("|")>-1)return t.split(/\s*\|\s*/).some(this.matchesContext,this);let n=t.split("/"),i=this.options.context,o=!this.isOpen&&(!i||i.parent.type==this.nodes[0].type),s=-(i?i.depth+1:0)+(o?0:1),r=(l,a)=>{for(;l>=0;l--){let u=n[l];if(u==""){if(l==n.length-1||l==0)continue;for(;a>=s;a--)if(r(l-1,a))return!0;return!1}else{let c=a>0||a==0&&o?this.nodes[a].type:i&&a>=s?i.node(a-s).type:null;if(!c||c.name!=u&&!c.isInGroup(u))return!1;a--}}return!0};return r(n.length-1,this.open)}textblockFromContext(){let t=this.options.context;if(t)for(let n=t.depth;n>=0;n--){let i=t.node(n).contentMatchAt(t.indexAfter(n)).defaultType;if(i&&i.isTextblock&&i.defaultAttrs)return i}for(let n in this.parser.schema.nodes){let i=this.parser.schema.nodes[n];if(i.isTextblock&&i.defaultAttrs)return i}}}function lBe(e){for(let t=e.firstChild,n=null;t;t=t.nextSibling){let i=t.nodeType==1?t.nodeName.toLowerCase():null;i&&rj.hasOwnProperty(i)&&n?(n.appendChild(t),t=n):i=="li"?n=t:i&&(n=null)}}function aBe(e,t){return(e.matches||e.msMatchesSelector||e.webkitMatchesSelector||e.mozMatchesSelector).call(e,t)}function ET(e){let t={};for(let n in e)t[n]=e[n];return t}function TT(e,t){let n=t.schema.nodes;for(let i in n){let o=n[i];if(!o.allowsMarkType(e))continue;let s=[],r=l=>{s.push(l);for(let a=0;a<l.edgeCount;a++){let{type:u,next:c}=l.edge(a);if(u==t||s.indexOf(c)<0&&r(c))return!0}};if(r(o.contentMatch))return!0}}class z9{constructor(t,n){this.nodes=t,this.marks=n}serializeFragment(t,n={},i){i||(i=av(n).createDocumentFragment());let o=i,s=[];return t.forEach(r=>{if(s.length||r.marks.length){let l=0,a=0;for(;l<s.length&&a<r.marks.length;){let u=r.marks[a];if(!this.marks[u.type.name]){a++;continue}if(!u.eq(s[l][0])||u.type.spec.spanning===!1)break;l++,a++}for(;l<s.length;)o=s.pop()[1];for(;a<r.marks.length;){let u=r.marks[a++],c=this.serializeMark(u,r.isInline,n);c&&(s.push([u,o]),o.appendChild(c.dom),o=c.contentDOM||c.dom)}}o.appendChild(this.serializeNodeInner(r,n))}),i}serializeNodeInner(t,n){if(t.isText)return av(n).createTextNode(t.text);let{dom:i,contentDOM:o}=Uv(av(n),this.nodes[t.type.name](t),null,t.attrs);if(o){if(t.isLeaf)throw new RangeError("Content hole not allowed in a leaf node spec");this.serializeFragment(t.content,n,o)}return i}serializeNode(t,n={}){let i=this.serializeNodeInner(t,n);for(let o=t.marks.length-1;o>=0;o--){let s=this.serializeMark(t.marks[o],t.isInline,n);s&&((s.contentDOM||s.dom).appendChild(i),i=s.dom)}return i}serializeMark(t,n,i={}){let o=this.marks[t.type.name];return o&&Uv(av(i),o(t,n),null,t.attrs)}static renderSpec(t,n,i=null,o){return typeof n=="string"?{dom:t.createTextNode(n)}:Uv(t,n,i,o)}static fromSchema(t){return t.cached.domSerializer||(t.cached.domSerializer=new z9(this.nodesFromSchema(t),this.marksFromSchema(t)))}static nodesFromSchema(t){let n=LT(t.nodes);return n.text||(n.text=i=>i.text),n}static marksFromSchema(t){return LT(t.marks)}}function LT(e){let t={};for(let n in e){let i=e[n].spec.toDOM;i&&(t[n]=i)}return t}function av(e){return e.document||window.document}const NT=new WeakMap;function uBe(e){let t=NT.get(e);return t===void 0&&NT.set(e,t=cBe(e)),t}function cBe(e){let t=null;function n(i){if(i&&typeof i=="object")if(Array.isArray(i))if(typeof i[0]=="string")t||(t=[]),t.push(i);else for(let o=0;o<i.length;o++)n(i[o]);else for(let o in i)n(i[o])}return n(e),t}function Uv(e,t,n,i){if(t.nodeType==1)return{dom:t};if(t.dom&&t.dom.nodeType==1)return t;let o=t[0],s;if(typeof o!="string")throw new RangeError("Invalid array passed to renderSpec");if(i&&(s=uBe(i))&&s.indexOf(t)>-1)throw new RangeError("Using an array from an attribute object as a DOM spec. This may be an attempted cross site scripting attack.");let r=o.indexOf(" ");r>0&&(n=o.slice(0,r),o=o.slice(r+1));let l,a=n?e.createElementNS(n,o):e.createElement(o),u=t[1],c=1;if(u&&typeof u=="object"&&u.nodeType==null&&!Array.isArray(u)){c=2;for(let d in u)if(u[d]!=null){let h=d.indexOf(" ");h>0?a.setAttributeNS(d.slice(0,h),d.slice(h+1),u[d]):d=="style"&&a.style?a.style.cssText=u[d]:a.setAttribute(d,u[d])}}for(let d=c;d<t.length;d++){let h=t[d];if(h===0){if(d<t.length-1||d>c)throw new RangeError("Content hole must be the only child of its parent node");return{dom:a,contentDOM:a}}else if(typeof h=="string")a.appendChild(e.createTextNode(h));else{let{dom:p,contentDOM:g}=Uv(e,h,n,i);if(a.appendChild(p),g){if(l)throw new RangeError("Multiple content holes");l=g}}}return{dom:a,contentDOM:l}}const lj=65535,aj=Math.pow(2,16);function dBe(e,t){return e+t*aj}function FT(e){return e&lj}function fBe(e){return(e-(e&lj))/aj}const uj=1,cj=2,Kv=4,dj=8;class DT{constructor(t,n,i){this.pos=t,this.delInfo=n,this.recover=i}get deleted(){return(this.delInfo&dj)>0}get deletedBefore(){return(this.delInfo&(uj|Kv))>0}get deletedAfter(){return(this.delInfo&(cj|Kv))>0}get deletedAcross(){return(this.delInfo&Kv)>0}}class ll{constructor(t,n=!1){if(this.ranges=t,this.inverted=n,!t.length&&ll.empty)return ll.empty}recover(t){let n=0,i=FT(t);if(!this.inverted)for(let o=0;o<i;o++)n+=this.ranges[o*3+2]-this.ranges[o*3+1];return this.ranges[i*3]+n+fBe(t)}mapResult(t,n=1){return this._map(t,n,!1)}map(t,n=1){return this._map(t,n,!0)}_map(t,n,i){let o=0,s=this.inverted?2:1,r=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let a=this.ranges[l]-(this.inverted?o:0);if(a>t)break;let u=this.ranges[l+s],c=this.ranges[l+r],d=a+u;if(t<=d){let h=u?t==a?-1:t==d?1:n:n,p=a+o+(h<0?0:c);if(i)return p;let g=t==(n<0?a:d)?null:dBe(l/3,t-a),m=t==a?cj:t==d?uj:Kv;return(n<0?t!=a:t!=d)&&(m|=dj),new DT(p,m,g)}o+=c-u}return i?t+o:new DT(t+o,0,null)}touches(t,n){let i=0,o=FT(n),s=this.inverted?2:1,r=this.inverted?1:2;for(let l=0;l<this.ranges.length;l+=3){let a=this.ranges[l]-(this.inverted?i:0);if(a>t)break;let u=this.ranges[l+s],c=a+u;if(t<=c&&l==o*3)return!0;i+=this.ranges[l+r]-u}return!1}forEach(t){let n=this.inverted?2:1,i=this.inverted?1:2;for(let o=0,s=0;o<this.ranges.length;o+=3){let r=this.ranges[o],l=r-(this.inverted?s:0),a=r+(this.inverted?0:s),u=this.ranges[o+n],c=this.ranges[o+i];t(l,l+u,a,a+c),s+=c-u}}invert(){return new ll(this.ranges,!this.inverted)}toString(){return(this.inverted?"-":"")+JSON.stringify(this.ranges)}static offset(t){return t==0?ll.empty:new ll(t<0?[0,-t,0]:[0,0,t])}}ll.empty=new ll([]);const Lk=Object.create(null);class lr{getMap(){return ll.empty}merge(t){return null}static fromJSON(t,n){if(!n||!n.stepType)throw new RangeError("Invalid input for Step.fromJSON");let i=Lk[n.stepType];if(!i)throw new RangeError(`No step type ${n.stepType} defined`);return i.fromJSON(t,n)}static jsonID(t,n){if(t in Lk)throw new RangeError("Duplicate use of step JSON ID "+t);return Lk[t]=n,n.prototype.jsonID=t,n}}class es{constructor(t,n){this.doc=t,this.failed=n}static ok(t){return new es(t,null)}static fail(t){return new es(null,t)}static fromReplace(t,n,i,o){try{return es.ok(t.replace(n,i,o))}catch(s){if(s instanceof H0)return es.fail(s.message);throw s}}}function aA(e,t,n){let i=[];for(let o=0;o<e.childCount;o++){let s=e.child(o);s.content.size&&(s=s.copy(aA(s.content,t,s))),s.isInline&&(s=t(s,n,o)),i.push(s)}return Bn.fromArray(i)}class Pd extends lr{constructor(t,n,i){super(),this.from=t,this.to=n,this.mark=i}apply(t){let n=t.slice(this.from,this.to),i=t.resolve(this.from),o=i.node(i.sharedDepth(this.to)),s=new Qn(aA(n.content,(r,l)=>!r.isAtom||!l.type.allowsMarkType(this.mark.type)?r:r.mark(this.mark.addToSet(r.marks)),o),n.openStart,n.openEnd);return es.fromReplace(t,this.from,this.to,s)}invert(){return new jd(this.from,this.to,this.mark)}map(t){let n=t.mapResult(this.from,1),i=t.mapResult(this.to,-1);return n.deleted&&i.deleted||n.pos>=i.pos?null:new Pd(n.pos,i.pos,this.mark)}merge(t){return t instanceof Pd&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new Pd(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,n){if(typeof n.from!="number"||typeof n.to!="number")throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new Pd(n.from,n.to,t.markFromJSON(n.mark))}}lr.jsonID("addMark",Pd);class jd extends lr{constructor(t,n,i){super(),this.from=t,this.to=n,this.mark=i}apply(t){let n=t.slice(this.from,this.to),i=new Qn(aA(n.content,o=>o.mark(this.mark.removeFromSet(o.marks)),t),n.openStart,n.openEnd);return es.fromReplace(t,this.from,this.to,i)}invert(){return new Pd(this.from,this.to,this.mark)}map(t){let n=t.mapResult(this.from,1),i=t.mapResult(this.to,-1);return n.deleted&&i.deleted||n.pos>=i.pos?null:new jd(n.pos,i.pos,this.mark)}merge(t){return t instanceof jd&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new jd(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,n){if(typeof n.from!="number"||typeof n.to!="number")throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new jd(n.from,n.to,t.markFromJSON(n.mark))}}lr.jsonID("removeMark",jd);class Hd extends lr{constructor(t,n){super(),this.pos=t,this.mark=n}apply(t){let n=t.nodeAt(this.pos);if(!n)return es.fail("No node at mark step's position");let i=n.type.create(n.attrs,null,this.mark.addToSet(n.marks));return es.fromReplace(t,this.pos,this.pos+1,new Qn(Bn.from(i),0,n.isLeaf?0:1))}invert(t){let n=t.nodeAt(this.pos);if(n){let i=this.mark.addToSet(n.marks);if(i.length==n.marks.length){for(let o=0;o<n.marks.length;o++)if(!n.marks[o].isInSet(i))return new Hd(this.pos,n.marks[o]);return new Hd(this.pos,this.mark)}}return new U0(this.pos,this.mark)}map(t){let n=t.mapResult(this.pos,1);return n.deletedAfter?null:new Hd(n.pos,this.mark)}toJSON(){return{stepType:"addNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(t,n){if(typeof n.pos!="number")throw new RangeError("Invalid input for AddNodeMarkStep.fromJSON");return new Hd(n.pos,t.markFromJSON(n.mark))}}lr.jsonID("addNodeMark",Hd);class U0 extends lr{constructor(t,n){super(),this.pos=t,this.mark=n}apply(t){let n=t.nodeAt(this.pos);if(!n)return es.fail("No node at mark step's position");let i=n.type.create(n.attrs,null,this.mark.removeFromSet(n.marks));return es.fromReplace(t,this.pos,this.pos+1,new Qn(Bn.from(i),0,n.isLeaf?0:1))}invert(t){let n=t.nodeAt(this.pos);return!n||!this.mark.isInSet(n.marks)?this:new Hd(this.pos,this.mark)}map(t){let n=t.mapResult(this.pos,1);return n.deletedAfter?null:new U0(n.pos,this.mark)}toJSON(){return{stepType:"removeNodeMark",pos:this.pos,mark:this.mark.toJSON()}}static fromJSON(t,n){if(typeof n.pos!="number")throw new RangeError("Invalid input for RemoveNodeMarkStep.fromJSON");return new U0(n.pos,t.markFromJSON(n.mark))}}lr.jsonID("removeNodeMark",U0);class Ql extends lr{constructor(t,n,i,o=!1){super(),this.from=t,this.to=n,this.slice=i,this.structure=o}apply(t){return this.structure&&m5(t,this.from,this.to)?es.fail("Structure replace would overwrite content"):es.fromReplace(t,this.from,this.to,this.slice)}getMap(){return new ll([this.from,this.to-this.from,this.slice.size])}invert(t){return new Ql(this.from,this.from+this.slice.size,t.slice(this.from,this.to))}map(t){let n=t.mapResult(this.to,-1),i=this.from==this.to&&Ql.MAP_BIAS<0?n:t.mapResult(this.from,1);return i.deletedAcross&&n.deletedAcross?null:new Ql(i.pos,Math.max(i.pos,n.pos),this.slice,this.structure)}merge(t){if(!(t instanceof Ql)||t.structure||this.structure)return null;if(this.from+this.slice.size==t.from&&!this.slice.openEnd&&!t.slice.openStart){let n=this.slice.size+t.slice.size==0?Qn.empty:new Qn(this.slice.content.append(t.slice.content),this.slice.openStart,t.slice.openEnd);return new Ql(this.from,this.to+(t.to-t.from),n,this.structure)}else if(t.to==this.from&&!this.slice.openStart&&!t.slice.openEnd){let n=this.slice.size+t.slice.size==0?Qn.empty:new Qn(t.slice.content.append(this.slice.content),t.slice.openStart,this.slice.openEnd);return new Ql(t.from,this.to,n,this.structure)}else return null}toJSON(){let t={stepType:"replace",from:this.from,to:this.to};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,n){if(typeof n.from!="number"||typeof n.to!="number")throw new RangeError("Invalid input for ReplaceStep.fromJSON");return new Ql(n.from,n.to,Qn.fromJSON(t,n.slice),!!n.structure)}}Ql.MAP_BIAS=1;lr.jsonID("replace",Ql);class Wh extends lr{constructor(t,n,i,o,s,r,l=!1){super(),this.from=t,this.to=n,this.gapFrom=i,this.gapTo=o,this.slice=s,this.insert=r,this.structure=l}apply(t){if(this.structure&&(m5(t,this.from,this.gapFrom)||m5(t,this.gapTo,this.to)))return es.fail("Structure gap-replace would overwrite content");let n=t.slice(this.gapFrom,this.gapTo);if(n.openStart||n.openEnd)return es.fail("Gap is not a flat range");let i=this.slice.insertAt(this.insert,n.content);return i?es.fromReplace(t,this.from,this.to,i):es.fail("Content does not fit in gap")}getMap(){return new ll([this.from,this.gapFrom-this.from,this.insert,this.gapTo,this.to-this.gapTo,this.slice.size-this.insert])}invert(t){let n=this.gapTo-this.gapFrom;return new Wh(this.from,this.from+this.slice.size+n,this.from+this.insert,this.from+this.insert+n,t.slice(this.from,this.to).removeBetween(this.gapFrom-this.from,this.gapTo-this.from),this.gapFrom-this.from,this.structure)}map(t){let n=t.mapResult(this.from,1),i=t.mapResult(this.to,-1),o=this.from==this.gapFrom?n.pos:t.map(this.gapFrom,-1),s=this.to==this.gapTo?i.pos:t.map(this.gapTo,1);return n.deletedAcross&&i.deletedAcross||o<n.pos||s>i.pos?null:new Wh(n.pos,i.pos,o,s,this.slice,this.insert,this.structure)}toJSON(){let t={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,n){if(typeof n.from!="number"||typeof n.to!="number"||typeof n.gapFrom!="number"||typeof n.gapTo!="number"||typeof n.insert!="number")throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new Wh(n.from,n.to,n.gapFrom,n.gapTo,Qn.fromJSON(t,n.slice),n.insert,!!n.structure)}}lr.jsonID("replaceAround",Wh);function m5(e,t,n){let i=e.resolve(t),o=n-t,s=i.depth;for(;o>0&&s>0&&i.indexAfter(s)==i.node(s).childCount;)s--,o--;if(o>0){let r=i.node(s).maybeChild(i.indexAfter(s));for(;o>0;){if(!r||r.isLeaf)return!0;r=r.firstChild,o--}}return!1}function hBe(e,t,n){let i=e.resolve(t);if(!n.content.size)return t;let o=n.content;for(let s=0;s<n.openStart;s++)o=o.firstChild.content;for(let s=1;s<=(n.openStart==0&&n.size?2:1);s++)for(let r=i.depth;r>=0;r--){let l=r==i.depth?0:i.pos<=(i.start(r+1)+i.end(r+1))/2?-1:1,a=i.index(r)+(l>0?1:0),u=i.node(r),c=!1;if(s==1)c=u.canReplace(a,a,o);else{let d=u.contentMatchAt(a).findWrapping(o.firstChild.type);c=d&&u.canReplaceWith(a,a,d[0])}if(c)return l==0?i.pos:l<0?i.before(r+1):i.after(r+1)}return null}class a0 extends lr{constructor(t,n,i){super(),this.pos=t,this.attr=n,this.value=i}apply(t){let n=t.nodeAt(this.pos);if(!n)return es.fail("No node at attribute step's position");let i=Object.create(null);for(let s in n.attrs)i[s]=n.attrs[s];i[this.attr]=this.value;let o=n.type.create(i,null,n.marks);return es.fromReplace(t,this.pos,this.pos+1,new Qn(Bn.from(o),0,n.isLeaf?0:1))}getMap(){return ll.empty}invert(t){return new a0(this.pos,this.attr,t.nodeAt(this.pos).attrs[this.attr])}map(t){let n=t.mapResult(this.pos,1);return n.deletedAfter?null:new a0(n.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(t,n){if(typeof n.pos!="number"||typeof n.attr!="string")throw new RangeError("Invalid input for AttrStep.fromJSON");return new a0(n.pos,n.attr,n.value)}}lr.jsonID("attr",a0);class xy extends lr{constructor(t,n){super(),this.attr=t,this.value=n}apply(t){let n=Object.create(null);for(let o in t.attrs)n[o]=t.attrs[o];n[this.attr]=this.value;let i=t.type.create(n,t.content,t.marks);return es.ok(i)}getMap(){return ll.empty}invert(t){return new xy(this.attr,t.attrs[this.attr])}map(t){return this}toJSON(){return{stepType:"docAttr",attr:this.attr,value:this.value}}static fromJSON(t,n){if(typeof n.attr!="string")throw new RangeError("Invalid input for DocAttrStep.fromJSON");return new xy(n.attr,n.value)}}lr.jsonID("docAttr",xy);let K0=class extends Error{};K0=function e(t){let n=Error.call(this,t);return n.__proto__=e.prototype,n};K0.prototype=Object.create(Error.prototype);K0.prototype.constructor=K0;K0.prototype.name="TransformError";const Nk=Object.create(null);class Lo{constructor(t,n,i){this.$anchor=t,this.$head=n,this.ranges=i||[new pBe(t.min(n),t.max(n))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let t=this.ranges;for(let n=0;n<t.length;n++)if(t[n].$from.pos!=t[n].$to.pos)return!1;return!0}content(){return this.$from.doc.slice(this.from,this.to,!0)}replace(t,n=Qn.empty){let i=n.content.lastChild,o=null;for(let l=0;l<n.openEnd;l++)o=i,i=i.lastChild;let s=t.steps.length,r=this.ranges;for(let l=0;l<r.length;l++){let{$from:a,$to:u}=r[l],c=t.mapping.slice(s);t.replaceRange(c.map(a.pos),c.map(u.pos),l?Qn.empty:n),l==0&&RT(t,s,(i?i.isInline:o&&o.isTextblock)?-1:1)}}replaceWith(t,n){let i=t.steps.length,o=this.ranges;for(let s=0;s<o.length;s++){let{$from:r,$to:l}=o[s],a=t.mapping.slice(i),u=a.map(r.pos),c=a.map(l.pos);s?t.deleteRange(u,c):(t.replaceRangeWith(u,c,n),RT(t,i,n.isInline?-1:1))}}static findFrom(t,n,i=!1){let o=t.parent.inlineContent?new co(t):uh(t.node(0),t.parent,t.pos,t.index(),n,i);if(o)return o;for(let s=t.depth-1;s>=0;s--){let r=n<0?uh(t.node(0),t.node(s),t.before(s+1),t.index(s),n,i):uh(t.node(0),t.node(s),t.after(s+1),t.index(s)+1,n,i);if(r)return r}return null}static near(t,n=1){return this.findFrom(t,n)||this.findFrom(t,-n)||new Oa(t.node(0))}static atStart(t){return uh(t,t,0,0,1)||new Oa(t)}static atEnd(t){return uh(t,t,t.content.size,t.childCount,-1)||new Oa(t)}static fromJSON(t,n){if(!n||!n.type)throw new RangeError("Invalid input for Selection.fromJSON");let i=Nk[n.type];if(!i)throw new RangeError(`No selection type ${n.type} defined`);return i.fromJSON(t,n)}static jsonID(t,n){if(t in Nk)throw new RangeError("Duplicate use of selection JSON ID "+t);return Nk[t]=n,n.prototype.jsonID=t,n}getBookmark(){return co.between(this.$anchor,this.$head).getBookmark()}}Lo.prototype.visible=!0;class pBe{constructor(t,n){this.$from=t,this.$to=n}}let BT=!1;function $T(e){!BT&&!e.parent.inlineContent&&(BT=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+e.parent.type.name+")"))}class co extends Lo{constructor(t,n=t){$T(t),$T(n),super(t,n)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(t,n){let i=t.resolve(n.map(this.head));if(!i.parent.inlineContent)return Lo.near(i);let o=t.resolve(n.map(this.anchor));return new co(o.parent.inlineContent?o:i,i)}replace(t,n=Qn.empty){if(super.replace(t,n),n==Qn.empty){let i=this.$from.marksAcross(this.$to);i&&t.ensureMarks(i)}}eq(t){return t instanceof co&&t.anchor==this.anchor&&t.head==this.head}getBookmark(){return new O9(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(t,n){if(typeof n.anchor!="number"||typeof n.head!="number")throw new RangeError("Invalid input for TextSelection.fromJSON");return new co(t.resolve(n.anchor),t.resolve(n.head))}static create(t,n,i=n){let o=t.resolve(n);return new this(o,i==n?o:t.resolve(i))}static between(t,n,i){let o=t.pos-n.pos;if((!i||o)&&(i=o>=0?1:-1),!n.parent.inlineContent){let s=Lo.findFrom(n,i,!0)||Lo.findFrom(n,-i,!0);if(s)n=s.$head;else return Lo.near(n,i)}return t.parent.inlineContent||(o==0?t=n:(t=(Lo.findFrom(t,-i,!0)||Lo.findFrom(t,i,!0)).$anchor,t.pos<n.pos!=o<0&&(t=n))),new co(t,n)}}Lo.jsonID("text",co);class O9{constructor(t,n){this.anchor=t,this.head=n}map(t){return new O9(t.map(this.anchor),t.map(this.head))}resolve(t){return co.between(t.resolve(this.anchor),t.resolve(this.head))}}class vi extends Lo{constructor(t){let n=t.nodeAfter,i=t.node(0).resolve(t.pos+n.nodeSize);super(t,i),this.node=n}map(t,n){let{deleted:i,pos:o}=n.mapResult(this.anchor),s=t.resolve(o);return i?Lo.near(s):new vi(s)}content(){return new Qn(Bn.from(this.node),0,0)}eq(t){return t instanceof vi&&t.anchor==this.anchor}toJSON(){return{type:"node",anchor:this.anchor}}getBookmark(){return new uA(this.anchor)}static fromJSON(t,n){if(typeof n.anchor!="number")throw new RangeError("Invalid input for NodeSelection.fromJSON");return new vi(t.resolve(n.anchor))}static create(t,n){return new vi(t.resolve(n))}static isSelectable(t){return!t.isText&&t.type.spec.selectable!==!1}}vi.prototype.visible=!1;Lo.jsonID("node",vi);class uA{constructor(t){this.anchor=t}map(t){let{deleted:n,pos:i}=t.mapResult(this.anchor);return n?new O9(i,i):new uA(i)}resolve(t){let n=t.resolve(this.anchor),i=n.nodeAfter;return i&&vi.isSelectable(i)?new vi(n):Lo.near(n)}}class Oa extends Lo{constructor(t){super(t.resolve(0),t.resolve(t.content.size))}replace(t,n=Qn.empty){if(n==Qn.empty){t.delete(0,t.doc.content.size);let i=Lo.atStart(t.doc);i.eq(t.selection)||t.setSelection(i)}else super.replace(t,n)}toJSON(){return{type:"all"}}static fromJSON(t){return new Oa(t)}map(t){return new Oa(t)}eq(t){return t instanceof Oa}getBookmark(){return gBe}}Lo.jsonID("all",Oa);const gBe={map(){return this},resolve(e){return new Oa(e)}};function uh(e,t,n,i,o,s=!1){if(t.inlineContent)return co.create(e,n);for(let r=i-(o>0?0:1);o>0?r<t.childCount:r>=0;r+=o){let l=t.child(r);if(l.isAtom){if(!s&&vi.isSelectable(l))return vi.create(e,n-(o<0?l.nodeSize:0))}else{let a=uh(e,l,n+o,o<0?l.childCount:0,o,s);if(a)return a}n+=l.nodeSize*o}return null}function RT(e,t,n){let i=e.steps.length-1;if(i<t)return;let o=e.steps[i];if(!(o instanceof Ql||o instanceof Wh))return;let s=e.mapping.maps[i],r;s.forEach((l,a,u,c)=>{r==null&&(r=c)}),e.setSelection(Lo.near(e.doc.resolve(r),n))}function zT(e,t){return!t||!e?e:e.bind(t)}class uv{constructor(t,n,i){this.name=t,this.init=zT(n.init,i),this.apply=zT(n.apply,i)}}new uv("doc",{init(e){return e.doc||e.schema.topNodeType.createAndFill()},apply(e){return e.doc}}),new uv("selection",{init(e,t){return e.selection||Lo.atStart(t.doc)},apply(e){return e.selection}}),new uv("storedMarks",{init(e){return e.storedMarks||null},apply(e,t,n,i){return i.selection.$cursor?e.storedMarks:null}}),new uv("scrollToSelection",{init(){return 0},apply(e,t){return e.scrolledIntoView?t+1:t}});function fj(e,t,n){for(let i in e){let o=e[i];o instanceof Function?o=o.bind(t):i=="handleDOMEvents"&&(o=fj(o,t,{})),n[i]=o}return n}class mBe{constructor(t){this.spec=t,this.props={},t.props&&fj(t.props,this,this.props),this.key=t.key?t.key.key:vBe("plugin")}getState(t){return t[this.key]}}const Fk=Object.create(null);function vBe(e){return e in Fk?e+"$"+ ++Fk[e]:(Fk[e]=0,e+"$")}const Sy="kimi-code://skill/";function hj(e){return e?e.startsWith(Sy)&&e.length>Sy.length?"skill":e.startsWith("#")||e.startsWith("?")||e.startsWith("//")||/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(e)&&!/^[a-zA-Z]:(?:[\\/]|%5c)/i.test(e)?null:e.endsWith("/")||e.endsWith("\\")||/%5c$/i.test(e)?"folder":"file":null}function Ep(e){const t=e.search(/[#?]/);return t>0?e.slice(0,t):e}function pj(e){let t="";for(const n of e)n.codePointAt(0)>127||/[A-Za-z0-9\-._~]/.test(n)?t+=n:t+=`%${n.charCodeAt(0).toString(16).toUpperCase().padStart(2,"0")}`;return t}function yBe(e){const t=e.split("/").map(pj).join("/");return t.startsWith("//")?`/%2F${t.slice(2)}`:t}function kBe(e){return e.replace(/%/g,"%25").replace(/&/g,"%26").replace(/</g,"%3C").replace(/>/g,"%3E").replace(/([\\[\]])/g,"\\$1").replace(/\n/g,"%0A").replace(/\r/g,"%0D")}function bBe(e){return e.replace(/\\([\\[\]])/g,"$1").replace(/%0A/g,` -`).replace(/%0D/g,"\r").replace(/%26/g,"&").replace(/%3C/g,"<").replace(/%3E/g,">").replace(/%25/g,"%")}function ABe(e){return e.replace(/%0A/g,` -`).replace(/%0D/g,"\r").replace(/%26/g,"&").replace(/%3C/g,"<").replace(/%3E/g,">").replace(/%25/g,"%")}function CBe(e,t){const n=t?e.replace(/\\([\\<>])/g,"$1"):e.replace(/\\([\\()])/g,"$1");try{return decodeURIComponent(n)}catch{return n}}function gj(e){const t=e.slice(Sy.length);try{return decodeURIComponent(t)}catch{return t}}function cA(e){const t=kBe(e.name);if(e.kind==="skill")return`[${t}](${Sy}${pj(e.name)})`;const n=e.kind==="folder"&&!e.path.endsWith("/")&&!e.path.endsWith("\\")?`${e.path}/`:e.path;return`[${t}](${yBe(n)})`}const wBe=new nBe({nodes:{doc:{content:"block+"},paragraph:{group:"block",content:"inline*",toDOM:()=>["p",0],parseDOM:[{tag:"p"}]},text:{group:"inline"},mention:{group:"inline",inline:!0,atom:!0,selectable:!0,attrs:{kind:{},name:{},path:{default:""}},leafText:e=>cA(e.attrs),toDOM:e=>{const t=e.attrs;return["span",{class:`mention-pill mention-${t.kind}`,"data-mention-path":t.path},t.name]}}}}),xBe={extensions:[{disable:{null:["attention","autolink","blockQuote","characterReference","codeFenced","codeIndented","codeText","definition","hardBreakEscape","headingAtx","htmlFlow","htmlText","list","setextUnderline","thematicBreak"]}}]};function dA(e){if(e.includes(` -`)){const a=[];let u=0;for(const c of e.split(` -`)){for(const d of dA(c))a.push({...d,start:d.start+u,end:d.end+u});u+=c.length+1}return a}const t=RDe($De(xBe).document().write(zDe()(e,void 0,!0))),n=[];let i=null,o=!1,s=!1,r=null,l=0;for(const[a,u]of t){if(u.type==="image"){l+=a==="enter"?1:-1;continue}if(l>0)continue;if(a==="enter"){u.type==="label"?i={start:u.start.offset,end:u.end.offset}:u.type==="resource"&&i!==null&&u.start.offset===i.end?(o=!0,s=!1,r=null):u.type==="resourceTitle"&&o?s=!0:u.type==="resourceDestination"&&o&&(r={start:u.start.offset,end:u.end.offset});continue}if(u.type!=="resource"||!o||i===null)continue;o=!1;const{start:c,end:d}=i;i=null;const h=u.end.offset;if(s||e[c]!=="["||r===null)continue;const p=e.slice(c+1,d-1);let g=e.slice(r.start,r.end),m=!1;if(g.startsWith("<")&&(m=!0,g=g.slice(1,-1)),!p||!g)continue;const k=hj(g);if(k!==null)if(k==="skill")n.push({start:c,end:h,attrs:{kind:k,name:gj(g),path:""},rawDest:g});else{const w=CBe(g,m);n.push({start:c,end:h,attrs:{kind:k,name:bBe(p),path:w},rawDest:g})}}return n}function SBe(e){const t=dA(e);if(t.length===0)return[{type:"text",value:e}];const n=[];let i=0;for(const o of t)o.start>i&&n.push({type:"text",value:e.slice(i,o.start)}),n.push({type:"mention",attrs:o.attrs,rawDest:o.rawDest}),i=o.end;return i<e.length&&n.push({type:"text",value:e.slice(i)}),n}function ch(e){try{return decodeURIComponent(e)}catch{return e}}function mj(e){const t=dA(e.args??"").filter(n=>n.attrs.kind==="skill");return t.length===1&&t[0].attrs.name===e.name}function fA(e,t){if(mj(e))return t.revivePill?e.args??"":null;if(e.name.includes(" "))return null;const n=e.args??"";return`/skill:${e.name}${n.length>0?` ${n}`:""}`}function vj(e,t){return fA(e,t)!==null}const xf=function(e){for(var t=0;;t++)if(e=e.previousSibling,!e)return t},yj=function(e,t,n,i){return n&&(OT(e,t,n,i,-1)||OT(e,t,n,i,1))},_Be=/^(img|br|input|textarea|hr)$/i;function OT(e,t,n,i,o){for(var s;;){if(e==n&&t==i)return!0;if(t==(o<0?0:_y(e))){let r=e.parentNode;if(!r||r.nodeType!=1||hA(e)||_Be.test(e.nodeName)||e.contentEditable=="false")return!1;t=xf(e)+(o<0?0:1),e=r}else if(e.nodeType==1){let r=e.childNodes[t+(o<0?-1:0)];if(r.nodeType==1&&r.contentEditable=="false")if(!((s=r.pmViewDesc)===null||s===void 0)&&s.ignoreForSelection)t+=o;else return!1;else e=r,t=o<0?_y(e):0}else return!1}}function _y(e){return e.nodeType==3?e.nodeValue.length:e.childNodes.length}function MBe(e,t,n){for(let i=t==0,o=t==_y(e);i||o;){if(e==n)return!0;let s=xf(e);if(e=e.parentNode,!e)return!1;i=i&&s==0,o=o&&s==_y(e)}}function hA(e){let t;for(let n=e;n&&!(t=n.pmViewDesc);n=n.parentNode);return t&&t.node&&t.node.isBlock&&(t.dom==e||t.contentDOM==e)}const kj=function(e){return e.focusNode&&yj(e.focusNode,e.focusOffset,e.anchorNode,e.anchorOffset)};function bj(e,t){let n=document.createEvent("Event");return n.initEvent("keydown",!0,!0),n.keyCode=e,n.key=n.code=t,n}const Ua=typeof navigator<"u"?navigator:null,PT=typeof document<"u"?document:null,Yc=Ua&&Ua.userAgent||"",v5=/Edge\/(\d+)/.exec(Yc),Aj=/MSIE \d/.exec(Yc),y5=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(Yc),wg=!!(Aj||y5||v5),Cj=Aj?document.documentMode:y5?+y5[1]:v5?+v5[1]:0,P9=!wg&&/gecko\/(\d+)/i.test(Yc);P9&&+(/Firefox\/(\d+)/.exec(Yc)||[0,0])[1];const k5=!wg&&/Chrome\/(\d+)/.exec(Yc),Jc=!!k5,wj=k5?+k5[1]:0,Sf=!wg&&!!Ua&&/Apple Computer/.test(Ua.vendor),pA=Sf&&(/Mobile\/\w+/.test(Yc)||!!Ua&&Ua.maxTouchPoints>2),El=pA||(Ua?/Mac/.test(Ua.platform):!1),xj=Ua?/Win/.test(Ua.platform):!1,xg=/Android \d/.test(Yc),gA=!!PT&&"webkitFontSmoothing"in PT.documentElement.style,IBe=gA?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function EBe(e,t=null){let n=e.domSelectionRange(),i=e.state.doc;if(!n.focusNode)return null;let o=e.docView.nearestDesc(n.focusNode),s=o&&o.size==0,r=e.docView.posFromDOM(n.focusNode,n.focusOffset,1);if(r<0)return null;let l=i.resolve(r),a,u;if(kj(n)){for(a=r;o&&!o.node;)o=o.parent;let d=o.node;if(o&&d.isAtom&&vi.isSelectable(d)&&o.parent&&!(d.isInline&&MBe(n.focusNode,n.focusOffset,o.dom))){let h=o.posBefore;u=new vi(r==h?l:i.resolve(h))}}else{if(n instanceof e.dom.ownerDocument.defaultView.Selection&&n.rangeCount>1){let d=r,h=r;for(let p=0;p<n.rangeCount;p++){let g=n.getRangeAt(p);d=Math.min(d,e.docView.posFromDOM(g.startContainer,g.startOffset,1)),h=Math.max(h,e.docView.posFromDOM(g.endContainer,g.endOffset,-1))}if(d<0)return null;[a,r]=h==e.state.selection.anchor?[h,d]:[d,h],l=i.resolve(r)}else a=e.docView.posFromDOM(n.anchorNode,n.anchorOffset,1);if(a<0)return null}let c=i.resolve(a);if(!u){let d=t=="pointer"||e.state.selection.head<l.pos&&!s?1:-1;u=_j(e,c,l,d)}return u}function Sj(e){return e.editable?e.hasFocus():FBe(e)&&document.activeElement&&document.activeElement.contains(e.dom)}function mA(e,t=!1){let n=e.state.selection;if(NBe(e,n),!Sj(e))return;let i=e.input.mouseDown;if(!t&&Jc&&i){let o=e.domSelectionRange(),s=e.domObserver.currentSelection;if(o.anchorNode&&s.anchorNode&&yj(o.anchorNode,o.anchorOffset,s.anchorNode,s.anchorOffset)&&i.delaySelUpdate()){e.domObserver.setCurSelection();return}}if(e.domObserver.disconnectSelection(),e.cursorWrapper)LBe(e);else{let{anchor:o,head:s}=n,r,l;jT&&!(n instanceof co)&&(n.$from.parent.inlineContent||(r=HT(e,n.from)),!n.empty&&!n.$from.parent.inlineContent&&(l=HT(e,n.to))),e.docView.setSelection(o,s,e,t),jT&&(r&&WT(r),l&&WT(l)),n.visible?e.dom.classList.remove("ProseMirror-hideselection"):(e.dom.classList.add("ProseMirror-hideselection"),"onselectionchange"in document&&TBe(e))}e.domObserver.setCurSelection(),e.domObserver.connectSelection()}const jT=Sf||Jc&&wj<63;function HT(e,t){let{node:n,offset:i}=e.docView.domFromPos(t,0),o=i<n.childNodes.length?n.childNodes[i]:null,s=i?n.childNodes[i-1]:null;if(Sf&&o&&o.contentEditable=="false")return Dk(o);if((!o||o.contentEditable=="false")&&(!s||s.contentEditable=="false")){if(o)return Dk(o);if(s)return Dk(s)}}function Dk(e){return e.contentEditable="true",Sf&&e.draggable&&(e.draggable=!1,e.wasDraggable=!0),e}function WT(e){e.contentEditable="false",e.wasDraggable&&(e.draggable=!0,e.wasDraggable=null)}function TBe(e){let t=e.dom.ownerDocument;t.removeEventListener("selectionchange",e.input.hideSelectionGuard);let n=e.domSelectionRange(),i=n.anchorNode,o=n.anchorOffset;t.addEventListener("selectionchange",e.input.hideSelectionGuard=()=>{(n.anchorNode!=i||n.anchorOffset!=o)&&(t.removeEventListener("selectionchange",e.input.hideSelectionGuard),setTimeout(()=>{(!Sj(e)||e.state.selection.visible)&&e.dom.classList.remove("ProseMirror-hideselection")},20))})}function LBe(e){let t=e.domSelection();if(!t)return;let n=e.cursorWrapper.dom,i=n.nodeName=="IMG";i?t.collapse(n.parentNode,xf(n)+1):t.collapse(n,0),!i&&!e.state.selection.visible&&wg&&Cj<=11&&(n.disabled=!0,n.disabled=!1)}function NBe(e,t){if(t instanceof vi){let n=e.docView.descAt(t.from);n!=e.lastSelectedViewDesc&&(qT(e),n&&n.selectNode(),e.lastSelectedViewDesc=n)}else qT(e)}function qT(e){e.lastSelectedViewDesc&&(e.lastSelectedViewDesc.parent&&e.lastSelectedViewDesc.deselectNode(),e.lastSelectedViewDesc=void 0)}function _j(e,t,n,i){return e.someProp("createSelectionBetween",o=>o(e,t,n))||co.between(t,n,i)}function FBe(e){let t=e.domSelectionRange();if(!t.anchorNode)return!1;try{return e.dom.contains(t.anchorNode.nodeType==3?t.anchorNode.parentNode:t.anchorNode)&&(e.editable||e.dom.contains(t.focusNode.nodeType==3?t.focusNode.parentNode:t.focusNode))}catch{return!1}}function b5(e,t){let{$anchor:n,$head:i}=e.selection,o=t>0?n.max(i):n.min(i),s=o.parent.inlineContent?o.depth?e.doc.resolve(t>0?o.after():o.before()):null:o;return s&&Lo.findFrom(s,t)}function oc(e,t){return e.dispatch(e.state.tr.setSelection(t).scrollIntoView()),!0}function UT(e,t,n){let i=e.state.selection;if(i instanceof co)if(n.indexOf("s")>-1){let{$head:o}=i,s=o.textOffset?null:t<0?o.nodeBefore:o.nodeAfter;if(!s||s.isText||!s.isLeaf)return!1;let r=e.state.doc.resolve(o.pos+s.nodeSize*(t<0?-1:1));return oc(e,new co(i.$anchor,r))}else if(i.empty){if(e.endOfTextblock(t>0?"forward":"backward")){let o=b5(e.state,t);return o&&o instanceof vi?oc(e,o):!1}else if(!(El&&n.indexOf("m")>-1)){let o=i.$head,s=o.textOffset?null:t<0?o.nodeBefore:o.nodeAfter,r;if(!s||s.isText)return!1;let l=t<0?o.pos-s.nodeSize:o.pos;return s.isAtom||(r=e.docView.descAt(l))&&!r.contentDOM?vi.isSelectable(s)?oc(e,new vi(t<0?e.state.doc.resolve(o.pos-s.nodeSize):o)):gA?oc(e,new co(e.state.doc.resolve(t<0?l:l+s.nodeSize))):!1:!1}}else return!1;else{if(i instanceof vi&&i.node.isInline)return oc(e,new co(t>0?i.$to:i.$from));{let o=b5(e.state,t);return o?oc(e,o):!1}}}function My(e){return e.nodeType==3?e.nodeValue.length:e.childNodes.length}function u0(e,t){let n=e.pmViewDesc;return n&&n.size==0&&(t<0||e.nextSibling||e.nodeName!="BR")}function Jf(e,t){return t<0?DBe(e):BBe(e)}function DBe(e){let t=e.domSelectionRange(),n=t.focusNode,i=t.focusOffset;if(!n)return;let o,s,r=!1;for(P9&&n.nodeType==1&&i<My(n)&&u0(n.childNodes[i],-1)&&(r=!0);;)if(i>0){if(n.nodeType!=1)break;{let l=n.childNodes[i-1];if(u0(l,-1))o=n,s=--i;else if(l.nodeType==3)n=l,i=n.nodeValue.length;else break}}else{if(Mj(n))break;{let l=n.previousSibling;for(;l&&u0(l,-1);)o=n.parentNode,s=xf(l),l=l.previousSibling;if(l)n=l,i=My(n);else{if(n=n.parentNode,n==e.dom)break;i=0}}}r?A5(e,n,i):o&&A5(e,o,s)}function BBe(e){let t=e.domSelectionRange(),n=t.focusNode,i=t.focusOffset;if(!n)return;let o=My(n),s,r;for(;;)if(i<o){if(n.nodeType!=1)break;let l=n.childNodes[i];if(u0(l,1))s=n,r=++i;else break}else{if(Mj(n))break;{let l=n.nextSibling;for(;l&&u0(l,1);)s=l.parentNode,r=xf(l)+1,l=l.nextSibling;if(l)n=l,i=0,o=My(n);else{if(n=n.parentNode,n==e.dom)break;i=o=0}}}s&&A5(e,s,r)}function Mj(e){let t=e.pmViewDesc;return t&&t.node&&t.node.isBlock}function $Be(e,t){for(;e&&t==e.childNodes.length&&!hA(e);)t=xf(e)+1,e=e.parentNode;for(;e&&t<e.childNodes.length;){let n=e.childNodes[t];if(n.nodeType==3)return n;if(n.nodeType==1&&n.contentEditable=="false")break;e=n,t=0}}function RBe(e,t){for(;e&&!t&&!hA(e);)t=xf(e),e=e.parentNode;for(;e&&t;){let n=e.childNodes[t-1];if(n.nodeType==3)return n;if(n.nodeType==1&&n.contentEditable=="false")break;e=n,t=e.childNodes.length}}function A5(e,t,n){if(t.nodeType!=3){let s,r;(r=$Be(t,n))?(t=r,n=0):(s=RBe(t,n))&&(t=s,n=s.nodeValue.length)}let i=e.domSelection();if(!i)return;if(kj(i)){let s=document.createRange();s.setEnd(t,n),s.setStart(t,n),i.removeAllRanges(),i.addRange(s)}else i.extend&&i.extend(t,n);e.domObserver.setCurSelection();let{state:o}=e;setTimeout(()=>{e.state==o&&mA(e)},50)}function KT(e,t){let n=e.state.doc.resolve(t);if(!(Jc||xj)&&n.parent.inlineContent){let o=e.coordsAtPos(t);if(t>n.start()){let s=e.coordsAtPos(t-1),r=(s.top+s.bottom)/2;if(r>o.top&&r<o.bottom&&Math.abs(s.left-o.left)>1)return s.left<o.left?"ltr":"rtl"}if(t<n.end()){let s=e.coordsAtPos(t+1),r=(s.top+s.bottom)/2;if(r>o.top&&r<o.bottom&&Math.abs(s.left-o.left)>1)return s.left>o.left?"ltr":"rtl"}}return getComputedStyle(e.dom).direction=="rtl"?"rtl":"ltr"}function VT(e,t,n){let i=e.state.selection;if(i instanceof co&&!i.empty||n.indexOf("s")>-1||El&&n.indexOf("m")>-1)return!1;let{$from:o,$to:s}=i;if(!o.parent.inlineContent||e.endOfTextblock(t<0?"up":"down")){let r=b5(e.state,t);if(r&&r instanceof vi)return oc(e,r)}if(!o.parent.inlineContent){let r=t<0?o:s,l=i instanceof Oa?Lo.near(r,t):Lo.findFrom(r,t);return l?oc(e,l):!1}return!1}function ZT(e,t){if(!(e.state.selection instanceof co))return!0;let{$head:n,$anchor:i,empty:o}=e.state.selection;if(!n.sameParent(i))return!0;if(!o)return!1;if(e.endOfTextblock(t>0?"forward":"backward"))return!0;let s=!n.textOffset&&(t<0?n.nodeBefore:n.nodeAfter);if(s&&!s.isText){let r=e.state.tr;return t<0?r.delete(n.pos-s.nodeSize,n.pos):r.delete(n.pos,n.pos+s.nodeSize),e.dispatch(r),!0}return!1}function GT(e,t,n){e.domObserver.stop(),t.contentEditable=n,e.domObserver.start()}function zBe(e){if(!Sf||e.state.selection.$head.parentOffset>0)return!1;let{focusNode:t,focusOffset:n}=e.domSelectionRange();if(t&&t.nodeType==1&&n==0&&t.firstChild&&t.firstChild.contentEditable=="false"){let i=t.firstChild;GT(e,i,"true"),setTimeout(()=>GT(e,i,"false"),20)}return!1}function OBe(e){let t="";return e.ctrlKey&&(t+="c"),e.metaKey&&(t+="m"),e.altKey&&(t+="a"),e.shiftKey&&(t+="s"),t}function PBe(e,t){let n=t.keyCode,i=OBe(t);if(n==8||El&&n==72&&i=="c")return ZT(e,-1)||Jf(e,-1);if(n==46&&!t.shiftKey||El&&n==68&&i=="c")return ZT(e,1)||Jf(e,1);if(n==13||n==27)return!0;if(n==37||El&&n==66&&i=="c"){let o=n==37?KT(e,e.state.selection.from)=="ltr"?-1:1:-1;return UT(e,o,i)||Jf(e,o)}else if(n==39||El&&n==70&&i=="c"){let o=n==39?KT(e,e.state.selection.from)=="ltr"?1:-1:1;return UT(e,o,i)||Jf(e,o)}else{if(n==38||El&&n==80&&i=="c")return VT(e,-1,i)||Jf(e,-1);if(n==40||El&&n==78&&i=="c")return zBe(e)||VT(e,1,i)||Jf(e,1);if(i==(El?"m":"c")&&(n==66||n==73||n==89||n==90))return!0}return!1}function Ij(e,t){e.someProp("transformCopied",p=>{t=p(t,e)});let n=[],{content:i,openStart:o,openEnd:s}=t;for(;o>1&&s>1&&i.childCount==1&&i.firstChild.childCount==1;){o--,s--;let p=i.firstChild;n.push(p.type.name,p.attrs!=p.type.defaultAttrs?p.attrs:null),i=p.content}let r=e.someProp("clipboardSerializer")||z9.fromSchema(e.state.schema),l=Dj(),a=l.createElement("div");a.appendChild(r.serializeFragment(i,{document:l}));let u=a.firstChild,c,d=0;for(;u&&u.nodeType==1&&(c=Fj[u.nodeName.toLowerCase()]);){for(let p=c.length-1;p>=0;p--){let g=l.createElement(c[p]);for(;a.firstChild;)g.appendChild(a.firstChild);a.appendChild(g),d++}u=a.firstChild}u&&u.nodeType==1&&u.setAttribute("data-pm-slice",`${o} ${s}${d?` -${d}`:""} ${JSON.stringify(n)}`);let h=e.someProp("clipboardTextSerializer",p=>p(t,e))||t.content.textBetween(0,t.content.size,` - -`);return{dom:a,text:h,slice:t}}function Ej(e,t,n,i,o){let s=o.parent.type.spec.code,r,l;if(!n&&!t)return null;let a=!!t&&(i||s||!n);if(a){if(e.someProp("transformPastedText",h=>{t=h(t,s||i,e)}),s)return l=new Qn(Bn.from(e.state.schema.text(t.replace(/\r\n?/g,` -`))),0,0),e.someProp("transformPasted",h=>{l=h(l,e,!0)}),l;let d=e.someProp("clipboardTextParser",h=>h(t,o,i,e));if(d)l=d;else{let h=o.marks(),{schema:p}=e.state,g=z9.fromSchema(p);r=document.createElement("div"),t.split(/(?:\r\n?|\n)+/).forEach(m=>{let k=r.appendChild(document.createElement("p"));m&&k.appendChild(g.serializeNode(p.text(m,h)))})}}else e.someProp("transformPastedHTML",d=>{n=d(n,e)}),r=qBe(n),gA&&UBe(r);let u=r&&r.querySelector("[data-pm-slice]"),c=u&&/^(\d+) (\d+)(?: -(\d+))? (.*)/.exec(u.getAttribute("data-pm-slice")||"");if(c&&c[3])for(let d=+c[3];d>0;d--){let h=r.firstChild;for(;h&&h.nodeType!=1;)h=h.nextSibling;if(!h)break;r=h}if(l||(l=(e.someProp("clipboardParser")||e.someProp("domParser")||sBe.fromSchema(e.state.schema)).parseSlice(r,{preserveWhitespace:!!(a||c),context:o,ruleFromNode(h){return h.nodeName=="BR"&&!h.nextSibling&&h.parentNode&&!jBe.test(h.parentNode.nodeName)?{ignore:!0}:null}})),c)l=KBe(QT(l,+c[1],+c[2]),c[4]);else if(l=Qn.maxOpen(HBe(l.content,o),!0),l.openStart||l.openEnd){let d=0,h=0;for(let p=l.content.firstChild;d<l.openStart&&!p.type.spec.isolating;d++,p=p.firstChild);for(let p=l.content.lastChild;h<l.openEnd&&!p.type.spec.isolating;h++,p=p.lastChild);l=QT(l,d,h)}return e.someProp("transformPasted",d=>{l=d(l,e,a)}),l}const jBe=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function HBe(e,t){if(e.childCount<2)return e;for(let n=t.depth;n>=0;n--){let o=t.node(n).contentMatchAt(t.index(n)),s,r=[];if(e.forEach(l=>{if(!r)return;let a=o.findWrapping(l.type),u;if(!a)return r=null;if(u=r.length&&s.length&&Lj(a,s,l,r[r.length-1],0))r[r.length-1]=u;else{r.length&&(r[r.length-1]=Nj(r[r.length-1],s.length));let c=Tj(l,a);r.push(c),o=o.matchType(c.type),s=a}}),r)return Bn.from(r)}return e}function Tj(e,t,n=0){for(let i=t.length-1;i>=n;i--)e=t[i].create(null,Bn.from(e));return e}function Lj(e,t,n,i,o){if(o<e.length&&o<t.length&&e[o]==t[o]){let s=Lj(e,t,n,i.lastChild,o+1);if(s)return i.copy(i.content.replaceChild(i.childCount-1,s));if(i.contentMatchAt(i.childCount).matchType(o==e.length-1?n.type:e[o+1]))return i.copy(i.content.append(Bn.from(Tj(n,e,o+1))))}}function Nj(e,t){if(t==0)return e;let n=e.content.replaceChild(e.childCount-1,Nj(e.lastChild,t-1)),i=e.contentMatchAt(e.childCount).fillBefore(Bn.empty,!0);return e.copy(n.append(i))}function C5(e,t,n,i,o,s){let r=t<0?e.firstChild:e.lastChild,l=r.content;return e.childCount>1&&(s=0),o<i-1&&(l=C5(l,t,n,i,o+1,s)),o>=n&&(l=t<0?r.contentMatchAt(0).fillBefore(l,s<=o).append(l):l.append(r.contentMatchAt(r.childCount).fillBefore(Bn.empty,!0))),e.replaceChild(t<0?0:e.childCount-1,r.copy(l))}function QT(e,t,n){return t<e.openStart&&(e=new Qn(C5(e.content,-1,t,e.openStart,0,e.openEnd),t,e.openEnd)),n<e.openEnd&&(e=new Qn(C5(e.content,1,n,e.openEnd,0,0),e.openStart,n)),e}const Fj={thead:["table"],tbody:["table"],tfoot:["table"],caption:["table"],colgroup:["table"],col:["table","colgroup"],tr:["table","tbody"],td:["table","tbody","tr"],th:["table","tbody","tr"]};function Dj(){return document.implementation.createHTMLDocument("title")}let Bk=null;function WBe(e){let t=window.trustedTypes;return t?(Bk||(Bk=t.defaultPolicy||t.createPolicy("ProseMirrorClipboard",{createHTML:n=>n})),Bk.createHTML(e)):e}function qBe(e){let t=/^(\s*<meta [^>]*>)*/.exec(e);t&&(e=e.slice(t[0].length));let n=Dj(),i=n.body,o=/<([a-z][^>\s]+)/i.exec(e),s;if((s=o&&Fj[o[1].toLowerCase()])&&(e=s.map(r=>"<"+r+">").join("")+e+s.map(r=>"</"+r+">").reverse().join("")),i.innerHTML=WBe(e),s)for(let r=0;r<s.length;r++)i=i.querySelector(s[r])||i;for(let r=0;r<n.styleSheets.length;r++){let l=n.styleSheets[r];for(let a=0;a<l.rules.length;a++){let u=l.rules[a];if(u instanceof CSSStyleRule){let c=i.querySelectorAll(u.selectorText);for(let d=0;d<c.length;d++)c[d].style.cssText+=u.style.cssText}}}return i}function UBe(e){let t=e.querySelectorAll(Jc?"span:not([class]):not([style])":"span.Apple-converted-space");for(let n=0;n<t.length;n++){let i=t[n];i.childNodes.length==1&&i.textContent==" "&&i.parentNode&&i.parentNode.replaceChild(e.ownerDocument.createTextNode(" "),i)}}function KBe(e,t){if(!e.size)return e;let n=e.content.firstChild.type.schema,i;try{i=JSON.parse(t)}catch{return e}let{content:o,openStart:s,openEnd:r}=e;for(let l=i.length-2;l>=0;l-=2){let a=n.nodes[i[l]];if(!a||a.hasRequiredAttrs())break;o=Bn.from(a.create(i[l+1],o)),s++,r++}return new Qn(o,s,r)}const va={},kl={};function mu(e,t){e.input.lastSelectionOrigin=t,e.input.lastSelectionTime=Date.now()}kl.keydown=(e,t)=>{let n=t;if(e.input.shiftKey=n.keyCode==16||n.shiftKey,!zj(e)&&(e.input.lastKeyCode=n.keyCode,e.input.lastKeyCodeTime=Date.now(),!(xg&&Jc&&n.keyCode==13)))if(n.keyCode!=229&&e.domObserver.forceFlush(),pA&&n.keyCode==13&&!n.ctrlKey&&!n.altKey&&!n.metaKey){let i=Date.now();e.input.lastIOSEnter=i,e.input.lastIOSEnterFallbackTimeout=setTimeout(()=>{e.input.lastIOSEnter==i&&(e.someProp("handleKeyDown",o=>o(e,bj(13,"Enter"))),e.input.lastIOSEnter=0)},200)}else e.someProp("handleKeyDown",i=>i(e,n))||PBe(e,n)?n.preventDefault():mu(e,"key")};kl.keyup=(e,t)=>{t.keyCode==16&&(e.input.shiftKey=!1)};kl.keypress=(e,t)=>{let n=t;if(zj(e)||!n.charCode||n.ctrlKey&&!n.altKey||El&&n.metaKey)return;if(e.someProp("handleKeyPress",o=>o(e,n))){n.preventDefault();return}let i=e.state.selection;if(!(i instanceof co)||!i.$from.sameParent(i.$to)){let o=String.fromCharCode(n.charCode),s=()=>e.state.tr.insertText(o).scrollIntoView();!/[\r\n]/.test(o)&&!e.someProp("handleTextInput",r=>r(e,i.$from.pos,i.$to.pos,o,s))&&e.dispatch(s()),n.preventDefault()}};function Sg(e){return{left:e.clientX,top:e.clientY}}function VBe(e,t){let n=t.x-e.clientX,i=t.y-e.clientY;return n*n+i*i<100}function vA(e,t,n,i,o){if(i==-1)return!1;let s=e.state.doc.resolve(i);for(let r=s.depth+1;r>0;r--)if(e.someProp(t,l=>r>s.depth?l(e,n,s.nodeAfter,s.before(r),o,!0):l(e,n,s.node(r),s.before(r),o,!1)))return!0;return!1}function _g(e,t,n){if(e.focused||e.focus(),e.state.selection.eq(t))return;let i=e.state.tr.setSelection(t);i.setMeta("pointer",!0),e.dispatch(i)}function ZBe(e,t){if(t==-1)return!1;let n=e.state.doc.resolve(t),i=n.nodeAfter;return i&&i.isAtom&&vi.isSelectable(i)?(_g(e,new vi(n)),!0):!1}function GBe(e,t){if(t==-1)return!1;let n=e.state.selection,i,o;n instanceof vi&&(i=n.node);let s=e.state.doc.resolve(t);for(let r=s.depth+1;r>0;r--){let l=r>s.depth?s.nodeAfter:s.node(r);if(vi.isSelectable(l)){i&&n.$from.depth>0&&r>=n.$from.depth&&s.before(n.$from.depth+1)==n.$from.pos?o=s.before(n.$from.depth):o=s.before(r);break}}return o!=null?(_g(e,vi.create(e.state.doc,o)),!0):!1}function QBe(e,t,n,i,o){return vA(e,"handleClickOn",t,n,i)||e.someProp("handleClick",s=>s(e,t,i))||(o?GBe(e,n):ZBe(e,n))}function YBe(e,t,n,i){return vA(e,"handleDoubleClickOn",t,n,i)||e.someProp("handleDoubleClick",o=>o(e,t,i))}function JBe(e,t,n,i){return vA(e,"handleTripleClickOn",t,n,i)||e.someProp("handleTripleClick",o=>o(e,t,i))||XBe(e,n,i)}function XBe(e,t,n){if(n.button!=0)return!1;let i=Bj(e,t,!0),o=e.state.doc;return i?(_g(e,i),i instanceof co&&o.eq(e.state.doc)&&(e.input.mouseDown=new t$e(e,i)),!0):!1}function Bj(e,t,n){let i=e.state.doc;if(t==-1)return i.inlineContent?co.create(i,0,i.content.size):null;let o=i.resolve(t);for(let s=o.depth+1;s>0;s--){let r=s>o.depth?o.nodeAfter:o.node(s),l=o.before(s);if(r.inlineContent)return co.create(i,l+1,l+1+r.content.size);if(n&&vi.isSelectable(r))return vi.create(i,l)}return null}function yA(e){return Iy(e)}const $j=El?"metaKey":"ctrlKey";va.mousedown=(e,t)=>{let n=t;e.input.shiftKey=n.shiftKey;let i=yA(e),o=Date.now(),s="singleClick";o-e.input.lastClick.time<500&&VBe(n,e.input.lastClick)&&!n[$j]&&e.input.lastClick.button==n.button&&(e.input.lastClick.type=="singleClick"?s="doubleClick":e.input.lastClick.type=="doubleClick"&&(s="tripleClick")),e.input.lastClick={time:o,x:n.clientX,y:n.clientY,type:s,button:n.button},e.input.mouseDown&&e.input.mouseDown.done();let r=e.posAtCoords(Sg(n));r&&(s=="singleClick"?e.input.mouseDown=new e$e(e,r,n,!!i):(s=="doubleClick"?YBe:JBe)(e,r.pos,r.inside,n)?n.preventDefault():mu(e,"pointer"))};class Rj{constructor(t){this.view=t,this.mightDrag=null,t.root.addEventListener("mouseup",this.up=this.up.bind(this)),t.root.addEventListener("mousemove",this.move=this.move.bind(this))}up(t){this.done()}move(t){t.buttons==0&&this.done()}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.view.input.mouseDown==this&&(this.view.input.mouseDown=null)}delaySelUpdate(){return!1}}class e$e extends Rj{constructor(t,n,i,o){super(t),this.pos=n,this.event=i,this.flushed=o,this.delayedSelectionSync=!1,this.startDoc=t.state.doc,this.selectNode=!!i[$j],this.allowDefault=i.shiftKey;let s,r;if(n.inside>-1)s=t.state.doc.nodeAt(n.inside),r=n.inside;else{let c=t.state.doc.resolve(n.pos);s=c.parent,r=c.depth?c.before():0}const l=o?null:i.target,a=l?t.docView.nearestDesc(l,!0):null;this.target=a&&a.nodeDOM.nodeType==1?a.nodeDOM:null;let{selection:u}=t.state;i.button==0&&(s.type.spec.draggable&&s.type.spec.selectable!==!1||u instanceof vi&&u.from<=r&&u.to>r)&&(this.mightDrag={node:s,pos:r,addAttr:!!(this.target&&!this.target.draggable),setUneditable:!!(this.target&&P9&&!this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout(()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")},20),this.view.domObserver.start()),mu(t,"pointer")}done(){super.done(),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout(()=>{this.view.isDestroyed||mA(this.view)})}up(t){if(this.done(),!this.view.dom.contains(t.target))return;let n=this.pos;this.view.state.doc!=this.startDoc&&(n=this.view.posAtCoords(Sg(t))),this.updateAllowDefault(t),this.allowDefault||!n?mu(this.view,"pointer"):QBe(this.view,n.pos,n.inside,t,this.selectNode)?t.preventDefault():t.button==0&&(this.flushed||Sf&&this.mightDrag&&!this.mightDrag.node.isAtom||Jc&&!this.view.state.selection.visible&&Math.min(Math.abs(n.pos-this.view.state.selection.from),Math.abs(n.pos-this.view.state.selection.to))<=2)?(_g(this.view,Lo.near(this.view.state.doc.resolve(n.pos))),t.preventDefault()):mu(this.view,"pointer")}move(t){this.updateAllowDefault(t),mu(this.view,"pointer"),super.move(t)}updateAllowDefault(t){!this.allowDefault&&(Math.abs(this.event.x-t.clientX)>4||Math.abs(this.event.y-t.clientY)>4)&&(this.allowDefault=!0)}delaySelUpdate(){return this.allowDefault?(this.delayedSelectionSync=!0,!0):!1}}class t$e extends Rj{constructor(t,n){super(t),this.startSelection=n,this.startDoc=t.state.doc}move(t){if(t.buttons==0||this.view.isDestroyed||!this.view.state.doc.eq(this.startDoc)){this.done();return}t.preventDefault(),mu(this.view,"pointer");let n=this.view.posAtCoords(Sg(t)),i=n&&Bj(this.view,n.inside,!1);if(!i)return;let{doc:o}=this.view.state,s=this.startSelection,[r,l]=i.from<s.from?[s.to,i.from]:[s.from,i.to];_g(this.view,co.create(o,r,l))}}va.touchstart=e=>{e.input.lastTouch=Date.now(),yA(e),mu(e,"pointer")};va.touchmove=e=>{e.input.lastTouch=Date.now(),mu(e,"pointer")};va.contextmenu=e=>yA(e);function zj(e,t){return e.composing?!0:Sf&&Math.abs(Date.now()-e.input.compositionEndedAt)<500?(e.input.compositionEndedAt=-2e8,!0):!1}const n$e=xg?5e3:-1;kl.compositionstart=kl.compositionupdate=e=>{if(!e.composing){e.domObserver.flush();let{state:t}=e,n=t.selection.$to;if(t.selection instanceof co&&(t.storedMarks||!n.textOffset&&n.parentOffset&&n.nodeBefore.marks.some(i=>i.type.spec.inclusive===!1)||Jc&&xj&&i$e(e)))e.markCursor=e.state.storedMarks||n.marks(),Iy(e,!0),e.markCursor=null;else if(Iy(e,!t.selection.empty),P9&&t.selection.empty&&n.parentOffset&&!n.textOffset&&n.nodeBefore.marks.length){let i=e.domSelectionRange();for(let o=i.focusNode,s=i.focusOffset;o&&o.nodeType==1&&s!=0;){let r=s<0?o.lastChild:o.childNodes[s-1];if(!r)break;if(r.nodeType==3){let l=e.domSelection();l&&l.collapse(r,r.nodeValue.length);break}else o=r,s=-1}}e.input.composing=!0}Oj(e,n$e)};function i$e(e){let{focusNode:t,focusOffset:n}=e.domSelectionRange();if(!t||t.nodeType!=1||n>=t.childNodes.length)return!1;let i=t.childNodes[n];return i.nodeType==1&&i.contentEditable=="false"}kl.compositionend=(e,t)=>{e.composing&&(e.input.composing=!1,e.input.compositionEndedAt=Date.now(),e.input.compositionPendingChanges=e.domObserver.pendingRecords().length?e.input.compositionID:0,e.input.compositionNode=null,e.input.badSafariComposition?e.domObserver.forceFlush():e.input.compositionPendingChanges&&Promise.resolve().then(()=>e.domObserver.flush()),e.input.compositionID++,Oj(e,20))};function Oj(e,t){clearTimeout(e.input.composingTimeout),t>-1&&(e.input.composingTimeout=setTimeout(()=>Iy(e),t))}function o$e(e){for(e.composing&&(e.input.composing=!1,e.input.compositionEndedAt=Date.now());e.input.compositionNodes.length>0;)e.input.compositionNodes.pop().markParentsDirty()}function Iy(e,t=!1){if(!(xg&&e.domObserver.flushingSoon>=0)){if(e.domObserver.forceFlush(),o$e(e),t||e.docView&&e.docView.dirty){let n=EBe(e),i=e.state.selection;return n&&!n.eq(i)?e.dispatch(e.state.tr.setSelection(n)):(e.markCursor||t)&&!i.$from.node(i.$from.sharedDepth(i.to)).inlineContent?e.dispatch(e.state.tr.deleteSelection()):e.updateState(e.state),!0}return!1}}function s$e(e,t){if(!e.dom.parentNode)return;let n=e.dom.parentNode.appendChild(document.createElement("div"));n.appendChild(t),n.style.cssText="position: fixed; left: -10000px; top: 10px";let i=getSelection(),o=document.createRange();o.selectNodeContents(t),e.dom.blur(),i.removeAllRanges(),i.addRange(o),setTimeout(()=>{n.parentNode&&n.parentNode.removeChild(n),e.focus()},50)}const V0=wg&&Cj<15||pA&&IBe<604;va.copy=kl.cut=(e,t)=>{let n=t,i=e.state.selection,o=n.type=="cut";if(i.empty)return;let s=V0?null:n.clipboardData,r=i.content(),{dom:l,text:a}=Ij(e,r);s?(n.preventDefault(),s.clearData(),s.setData("text/html",l.innerHTML),s.setData("text/plain",a)):s$e(e,l),o&&e.dispatch(e.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))};function r$e(e){return e.openStart==0&&e.openEnd==0&&e.content.childCount==1?e.content.firstChild:null}function l$e(e,t){if(!e.dom.parentNode)return;let n=e.input.shiftKey||e.state.selection.$from.parent.type.spec.code,i=e.dom.parentNode.appendChild(document.createElement(n?"textarea":"div"));n||(i.contentEditable="true"),i.style.cssText="position: fixed; left: -10000px; top: 10px",i.focus();let o=e.input.shiftKey&&e.input.lastKeyCode!=45;setTimeout(()=>{e.focus(),i.parentNode&&i.parentNode.removeChild(i),n?w5(e,i.value,null,o,t):w5(e,i.textContent,i.innerHTML,o,t)},50)}function w5(e,t,n,i,o){let s=Ej(e,t,n,i,e.state.selection.$from);if(e.someProp("handlePaste",a=>a(e,o,s||Qn.empty)))return!0;if(!s)return!1;let r=r$e(s),l=r?e.state.tr.replaceSelectionWith(r,i):e.state.tr.replaceSelection(s);return e.dispatch(l.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}function Pj(e){let t=e.getData("text/plain")||e.getData("Text");if(t)return t;let n=e.getData("text/uri-list");return n?n.replace(/\r?\n/g," "):""}kl.paste=(e,t)=>{let n=t;if(e.composing&&!xg)return;let i=V0?null:n.clipboardData,o=e.input.shiftKey&&e.input.lastKeyCode!=45;i&&w5(e,Pj(i),i.getData("text/html"),o,n)?n.preventDefault():l$e(e,n)};class a$e{constructor(t,n,i){this.slice=t,this.move=n,this.node=i}}const u$e=El?"altKey":"ctrlKey";function jj(e,t){let n;return e.someProp("dragCopies",i=>{n=n||i(t)}),n!=null?!n:!t[u$e]}va.dragstart=(e,t)=>{let n=t,i=e.input.mouseDown;if(i&&i.done(),!n.dataTransfer)return;let o=e.state.selection,s=o.empty?null:e.posAtCoords(Sg(n)),r;if(!(s&&s.pos>=o.from&&s.pos<=(o instanceof vi?o.to-1:o.to))){if(i&&i.mightDrag)r=vi.create(e.state.doc,i.mightDrag.pos);else if(n.target&&n.target.nodeType==1){let d=e.docView.nearestDesc(n.target,!0);d&&d.node.type.spec.draggable&&d!=e.docView&&(r=vi.create(e.state.doc,d.posBefore))}}let l=(r||e.state.selection).content(),{dom:a,text:u,slice:c}=Ij(e,l);(!n.dataTransfer.files.length||!Jc||wj>120)&&n.dataTransfer.clearData(),n.dataTransfer.setData(V0?"Text":"text/html",a.innerHTML),n.dataTransfer.effectAllowed="copyMove",V0||n.dataTransfer.setData("text/plain",u),e.dragging=new a$e(c,jj(e,n),r)};va.dragend=e=>{let t=e.dragging;window.setTimeout(()=>{e.dragging==t&&(e.dragging=null)},50)};kl.dragover=kl.dragenter=(e,t)=>t.preventDefault();kl.drop=(e,t)=>{try{c$e(e,t,e.dragging)}finally{e.dragging=null}};function c$e(e,t,n){if(!t.dataTransfer)return;let i=e.posAtCoords(Sg(t));if(!i)return;let o=e.state.doc.resolve(i.pos),s=n&&n.slice;s?e.someProp("transformPasted",p=>{s=p(s,e,!1)}):s=Ej(e,Pj(t.dataTransfer),V0?null:t.dataTransfer.getData("text/html"),!1,o);let r=!!(n&&jj(e,t));if(e.someProp("handleDrop",p=>p(e,t,s||Qn.empty,r))){t.preventDefault();return}if(!s)return;t.preventDefault();let l=s?hBe(e.state.doc,o.pos,s):o.pos;l==null&&(l=o.pos);let a=e.state.tr;if(r){let{node:p}=n;p?p.replace(a):a.deleteSelection()}let u=a.mapping.map(l),c=s.openStart==0&&s.openEnd==0&&s.content.childCount==1,d=a.doc;if(c?a.replaceRangeWith(u,u,s.content.firstChild):a.replaceRange(u,u,s),a.doc.eq(d))return;let h=a.doc.resolve(u);if(c&&vi.isSelectable(s.content.firstChild)&&h.nodeAfter&&h.nodeAfter.sameMarkup(s.content.firstChild))a.setSelection(new vi(h));else{let p=a.mapping.map(l);a.mapping.maps[a.mapping.maps.length-1].forEach((g,m,k,w)=>p=w),a.setSelection(_j(e,h,a.doc.resolve(p)))}e.focus(),e.dispatch(a.setMeta("uiEvent","drop"))}va.focus=e=>{e.input.lastFocus=Date.now(),e.focused||(e.domObserver.stop(),e.dom.classList.add("ProseMirror-focused"),e.domObserver.start(),e.focused=!0,setTimeout(()=>{e.docView&&e.hasFocus()&&!e.domObserver.currentSelection.eq(e.domSelectionRange())&&mA(e)},20))};va.blur=(e,t)=>{let n=t;e.focused&&(e.domObserver.stop(),e.dom.classList.remove("ProseMirror-focused"),e.domObserver.start(),n.relatedTarget&&e.dom.contains(n.relatedTarget)&&e.domObserver.currentSelection.clear(),e.focused=!1)};va.beforeinput=(e,t)=>{if(xg&&t.inputType=="deleteContentBackward"){e.domObserver.flushSoon();let{domChangeCount:i}=e.input;setTimeout(()=>{if(e.input.domChangeCount!=i||(e.dom.blur(),e.focus(),e.someProp("handleKeyDown",s=>s(e,bj(8,"Backspace")))))return;let{$cursor:o}=e.state.selection;o&&o.pos>0&&e.dispatch(e.state.tr.delete(o.pos-1,o.pos).scrollIntoView())},50)}};for(let e in kl)va[e]=kl[e];function Z0(e,t){if(e==t)return!0;for(let n in e)if(e[n]!==t[n])return!1;for(let n in t)if(!(n in e))return!1;return!0}class Ey{constructor(t,n){this.toDOM=t,this.spec=n||tf,this.side=this.spec.side||0}map(t,n,i,o){let{pos:s,deleted:r}=t.mapResult(n.from+o,this.side<0?-1:1);return r?null:new $a(s-i,s-i,this)}valid(){return!0}eq(t){return this==t||t instanceof Ey&&(this.spec.key&&this.spec.key==t.spec.key||this.toDOM==t.toDOM&&Z0(this.spec,t.spec))}destroy(t){this.spec.destroy&&this.spec.destroy(t)}}class bc{constructor(t,n){this.attrs=t,this.spec=n||tf}map(t,n,i,o){let s=t.map(n.from+o,this.spec.inclusiveStart?-1:1)-i,r=t.map(n.to+o,this.spec.inclusiveEnd?1:-1)-i;return s>=r?null:new $a(s,r,this)}valid(t,n){return n.from<n.to}eq(t){return this==t||t instanceof bc&&Z0(this.attrs,t.attrs)&&Z0(this.spec,t.spec)}static is(t){return t.type instanceof bc}destroy(){}}class kA{constructor(t,n){this.attrs=t,this.spec=n||tf}map(t,n,i,o){let s=t.mapResult(n.from+o,1);if(s.deleted)return null;let r=t.mapResult(n.to+o,-1);return r.deleted||r.pos<=s.pos?null:new $a(s.pos-i,r.pos-i,this)}valid(t,n){let{index:i,offset:o}=t.content.findIndex(n.from),s;return o==n.from&&!(s=t.child(i)).isText&&o+s.nodeSize==n.to}eq(t){return this==t||t instanceof kA&&Z0(this.attrs,t.attrs)&&Z0(this.spec,t.spec)}destroy(){}}class $a{constructor(t,n,i){this.from=t,this.to=n,this.type=i}copy(t,n){return new $a(t,n,this.type)}eq(t,n=0){return this.type.eq(t.type)&&this.from+n==t.from&&this.to+n==t.to}map(t,n,i){return this.type.map(t,this,n,i)}static widget(t,n,i){return new $a(t,t,new Ey(n,i))}static inline(t,n,i,o){return new $a(t,n,new bc(i,o))}static node(t,n,i,o){return new $a(t,n,new kA(i,o))}get spec(){return this.type.spec}get inline(){return this.type instanceof bc}get widget(){return this.type instanceof Ey}}const dh=[],tf={};class Ls{constructor(t,n){this.local=t.length?t:dh,this.children=n.length?n:dh}static create(t,n){return n.length?Ty(n,t,0,tf):pr}find(t,n,i){let o=[];return this.findInner(t??0,n??1e9,o,0,i),o}findInner(t,n,i,o,s){for(let r=0;r<this.local.length;r++){let l=this.local[r];l.from<=n&&l.to>=t&&(!s||s(l.spec))&&i.push(l.copy(l.from+o,l.to+o))}for(let r=0;r<this.children.length;r+=3)if(this.children[r]<n&&this.children[r+1]>t){let l=this.children[r]+1;this.children[r+2].findInner(t-l,n-l,i,o+l,s)}}map(t,n,i){return this==pr||t.maps.length==0?this:this.mapInner(t,n,0,0,i||tf)}mapInner(t,n,i,o,s){let r;for(let l=0;l<this.local.length;l++){let a=this.local[l].map(t,i,o);a&&a.type.valid(n,a)?(r||(r=[])).push(a):s.onRemove&&s.onRemove(this.local[l].spec)}return this.children.length?d$e(this.children,r||[],t,n,i,o,s):r?new Ls(r.sort(nf),dh):pr}add(t,n){return n.length?this==pr?Ls.create(t,n):this.addInner(t,n,0):this}addInner(t,n,i){let o,s=0;t.forEach((l,a)=>{let u=a+i,c;if(c=Wj(n,l,u)){for(o||(o=this.children.slice());s<o.length&&o[s]<a;)s+=3;o[s]==a?o[s+2]=o[s+2].addInner(l,c,u+1):o.splice(s,0,a,a+l.nodeSize,Ty(c,l,u+1,tf)),s+=3}});let r=Hj(s?qj(n):n,-i);for(let l=0;l<r.length;l++)r[l].type.valid(t,r[l])||r.splice(l--,1);return new Ls(r.length?this.local.concat(r).sort(nf):this.local,o||this.children)}remove(t){return t.length==0||this==pr?this:this.removeInner(t,0)}removeInner(t,n){let i=this.children,o=this.local;for(let s=0;s<i.length;s+=3){let r,l=i[s]+n,a=i[s+1]+n;for(let c=0,d;c<t.length;c++)(d=t[c])&&d.from>l&&d.to<a&&(t[c]=null,(r||(r=[])).push(d));if(!r)continue;i==this.children&&(i=this.children.slice());let u=i[s+2].removeInner(r,l+1);u!=pr?i[s+2]=u:(i.splice(s,3),s-=3)}if(o.length){for(let s=0,r;s<t.length;s++)if(r=t[s])for(let l=0;l<o.length;l++)o[l].eq(r,n)&&(o==this.local&&(o=this.local.slice()),o.splice(l--,1))}return i==this.children&&o==this.local?this:o.length||i.length?new Ls(o,i):pr}forChild(t,n){if(this==pr)return this;if(n.isLeaf)return Ls.empty;let i,o;for(let l=0;l<this.children.length;l+=3)if(this.children[l]>=t){this.children[l]==t&&(i=this.children[l+2]);break}let s=t+1,r=s+n.content.size;for(let l=0;l<this.local.length;l++){let a=this.local[l];if(a.from<r&&a.to>s&&a.type instanceof bc){let u=Math.max(s,a.from)-s,c=Math.min(r,a.to)-s;u<c&&(o||(o=[])).push(a.copy(u,c))}}if(o){let l=new Ls(o.sort(nf),dh);return i?new Dd([l,i]):l}return i||pr}eq(t){if(this==t)return!0;if(!(t instanceof Ls)||this.local.length!=t.local.length||this.children.length!=t.children.length)return!1;for(let n=0;n<this.local.length;n++)if(!this.local[n].eq(t.local[n]))return!1;for(let n=0;n<this.children.length;n+=3)if(this.children[n]!=t.children[n]||this.children[n+1]!=t.children[n+1]||!this.children[n+2].eq(t.children[n+2]))return!1;return!0}locals(t){return bA(this.localsInner(t))}localsInner(t){if(this==pr)return dh;if(t.inlineContent||!this.local.some(bc.is))return this.local;let n=[];for(let i=0;i<this.local.length;i++)this.local[i].type instanceof bc||n.push(this.local[i]);return n}forEachSet(t){t(this)}}Ls.empty=new Ls([],[]);Ls.removeOverlap=bA;const pr=Ls.empty;class Dd{constructor(t){this.members=t}map(t,n){const i=this.members.map(o=>o.map(t,n,tf));return Dd.from(i)}forChild(t,n){if(n.isLeaf)return Ls.empty;let i=[];for(let o=0;o<this.members.length;o++){let s=this.members[o].forChild(t,n);s!=pr&&(s instanceof Dd?i=i.concat(s.members):i.push(s))}return Dd.from(i)}eq(t){if(!(t instanceof Dd)||t.members.length!=this.members.length)return!1;for(let n=0;n<this.members.length;n++)if(!this.members[n].eq(t.members[n]))return!1;return!0}locals(t){let n,i=!0;for(let o=0;o<this.members.length;o++){let s=this.members[o].localsInner(t);if(s.length)if(!n)n=s;else{i&&(n=n.slice(),i=!1);for(let r=0;r<s.length;r++)n.push(s[r])}}return n?bA(i?n:n.sort(nf)):dh}static from(t){switch(t.length){case 0:return pr;case 1:return t[0];default:return new Dd(t.every(n=>n instanceof Ls)?t:t.reduce((n,i)=>n.concat(i instanceof Ls?i:i.members),[]))}}forEachSet(t){for(let n=0;n<this.members.length;n++)this.members[n].forEachSet(t)}}function d$e(e,t,n,i,o,s,r){let l=e.slice();for(let u=0,c=s;u<n.maps.length;u++){let d=0;n.maps[u].forEach((h,p,g,m)=>{let k=m-g-(p-h);for(let w=0;w<l.length;w+=3){let y=l[w+1];if(y<0||h>y+c-d)continue;let b=l[w]+c-d;p>=b?l[w+1]=h<=b?-2:-1:h>=c&&k&&(l[w]+=k,l[w+1]+=k)}d+=k}),c=n.maps[u].map(c,-1)}let a=!1;for(let u=0;u<l.length;u+=3)if(l[u+1]<0){if(l[u+1]==-2){a=!0,l[u+1]=-1;continue}let c=n.map(e[u]+s),d=c-o;if(d<0||d>=i.content.size){a=!0;continue}let h=n.map(e[u+1]+s,-1),p=h-o,{index:g,offset:m}=i.content.findIndex(d),k=i.maybeChild(g);if(k&&m==d&&m+k.nodeSize==p){let w=l[u+2].mapInner(n,k,c+1,e[u]+s+1,r);w!=pr?(l[u]=d,l[u+1]=p,l[u+2]=w):(l[u+1]=-2,a=!0)}else a=!0}if(a){let u=f$e(l,e,t,n,o,s,r),c=Ty(u,i,0,r);t=c.local;for(let d=0;d<l.length;d+=3)l[d+1]<0&&(l.splice(d,3),d-=3);for(let d=0,h=0;d<c.children.length;d+=3){let p=c.children[d];for(;h<l.length&&l[h]<p;)h+=3;l.splice(h,0,c.children[d],c.children[d+1],c.children[d+2])}}return new Ls(t.sort(nf),l)}function Hj(e,t){if(!t||!e.length)return e;let n=[];for(let i=0;i<e.length;i++){let o=e[i];n.push(new $a(o.from+t,o.to+t,o.type))}return n}function f$e(e,t,n,i,o,s,r){function l(a,u){for(let c=0;c<a.local.length;c++){let d=a.local[c].map(i,o,u);d?n.push(d):r.onRemove&&r.onRemove(a.local[c].spec)}for(let c=0;c<a.children.length;c+=3)l(a.children[c+2],a.children[c]+u+1)}for(let a=0;a<e.length;a+=3)e[a+1]==-1&&l(e[a+2],t[a]+s+1);return n}function Wj(e,t,n){if(t.isLeaf)return null;let i=n+t.nodeSize,o=null;for(let s=0,r;s<e.length;s++)(r=e[s])&&r.from>n&&r.to<i&&((o||(o=[])).push(r),e[s]=null);return o}function qj(e){let t=[];for(let n=0;n<e.length;n++)e[n]!=null&&t.push(e[n]);return t}function Ty(e,t,n,i){let o=[],s=!1;t.forEach((l,a)=>{let u=Wj(e,l,a+n);if(u){s=!0;let c=Ty(u,l,n+a+1,i);c!=pr&&o.push(a,a+l.nodeSize,c)}});let r=Hj(s?qj(e):e,-n).sort(nf);for(let l=0;l<r.length;l++)r[l].type.valid(t,r[l])||(i.onRemove&&i.onRemove(r[l].spec),r.splice(l--,1));return r.length||o.length?new Ls(r,o):pr}function nf(e,t){return e.from-t.from||e.to-t.to}function bA(e){let t=e;for(let n=0;n<t.length-1;n++){let i=t[n];if(i.from!=i.to)for(let o=n+1;o<t.length;o++){let s=t[o];if(s.from==i.from){s.to!=i.to&&(t==e&&(t=e.slice()),t[o]=s.copy(s.from,i.to),YT(t,o+1,s.copy(i.to,s.to)));continue}else{s.from<i.to&&(t==e&&(t=e.slice()),t[n]=i.copy(i.from,s.from),YT(t,o,i.copy(s.from,i.to)));break}}}return t}function YT(e,t,n){for(;t<e.length&&nf(n,e[t])>0;)t++;e.splice(t,0,n)}const h$e={sm:14,md:16,lg:20},p$e={file:w8,folder:vR,skill:kR,copy:mR,check:gR,"external-link":yR};function e1(e,t="md"){const n=h$e[t];return p$e[e].replace(/<svg\b[^>]*>/,i=>i.replace(/\s(?:width|height)="[^"]*"/g,"")).replace(/^<svg\b/,`<svg class="kw-icon" width="${n}" height="${n}" aria-hidden="true"`)}const g$e=e1("folder","sm"),m$e=e1("file","sm"),v$e=e1("skill","sm");function AA(e,t,n){return n||e.endsWith("/")?g$e:m$e}function CA(e,t,n){return e==="skill"?v$e:AA(t,n,e==="folder")}const $k=32;let JT;function XT(e){return JT??=new Intl.Segmenter("und",{granularity:"grapheme"}),[...JT.segment(e)].map(t=>t.segment)}function Uj(e){const t=XT(e);if(t.length<=$k)return e;const n=e.lastIndexOf("."),o=(n>0?XT(e.slice(n)):[]).length+4,s=$k-1-o;return s<8?`${t.slice(0,$k-1).join("")}…`:`${t.slice(0,s).join("")}…${t.slice(t.length-o).join("")}`}new mBe({props:{decorations(e){const t=[];return e.doc.forEach((n,i)=>{const o=n.lastChild;if(o&&o.type===wBe.nodes.mention){const s=i+n.nodeSize-1;t.push($a.widget(s,()=>{const r=document.createElement("span");return r.className="mention-caret-anchor",r.textContent="​",r},{side:1,key:`mention-caret-anchor-${s}`}))}}),Ls.create(e.doc,t)}}});function Rk(e,t,n){if(t===void 0||t.length===0||e.length===0)return[{text:e,hit:!1}];const i=new Set;for(const l of t){const a=l-n;a>=0&&a<e.length&&i.add(a)}if(i.size===0)return[{text:e,hit:!1}];const o=[];let s=0,r=i.has(0);for(let l=1;l<e.length;l++){const a=i.has(l);a!==r&&(o.push({text:e.slice(s,l),hit:r}),s=l,r=a)}return o.push({text:e.slice(s),hit:r}),o}function y$e(e){let t=new Set;const n=()=>{const i=e();if(!i)return;const o=i.ownerDocument?.getSelection?.()??document.getSelection(),s=o&&o.rangeCount>0&&!o.isCollapsed?o.getRangeAt(0):null;let r=!1;if(s&&i instanceof Node)try{r=s.intersectsNode(i)}catch{r=!1}if(!s||!r){for(const a of t)a.classList.remove("pill-in-selection");t=new Set;return}const l=new Set;for(const a of i.querySelectorAll(".mention-pill"))try{s.intersectsNode(a)&&l.add(a)}catch{}for(const a of l)t.has(a)||a.classList.add("pill-in-selection");for(const a of t)l.has(a)||a.classList.remove("pill-in-selection");t=l};return document.addEventListener("selectionchange",n),()=>document.removeEventListener("selectionchange",n)}function Mg(e,t){let n;return()=>{if(n===void 0){const i=getComputedStyle(document.documentElement).getPropertyValue(e).trim(),o=parseFloat(i);n=Number.isFinite(o)?o:t}return n}}const k$e=Mg("--space-1-5",6),b$e=Mg("--p-mention-tip-vmargin",12),A$e=Mg("--duration-tooltip",150),C$e=Mg("--duration-fast",120),w$e=Mg("--duration-flash",1e3),x$e=3e4;function S$e(e,t={}){const n=document.createElement("div");n.className="mention-tip-path";const i=document.createElement("div");i.className="mention-tip-path-text";const o=e.split(/([/\\])/);let s=o.length-1;for(;s>0&&(o[s]===""||o[s]==="/"||o[s]==="\\");)s--;for(let a=0;a<o.length;a++){const u=o[a]??"";if(u==="")continue;const c=document.createElement("span");if(u==="/"||u==="\\"){c.className="mention-tip-sep",c.textContent=u,i.append(c,document.createElement("wbr"));continue}a===s&&(c.className="mention-tip-base"),c.textContent=u,i.append(c)}n.append(i);const r=document.createElement("button");r.type="button",r.className="mention-tip-copy",r.setAttribute("aria-label",t.copyLabel??"Copy path");const l=e1("copy","sm");return r.innerHTML=l,r.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),(async()=>await Xo(e)&&(r.innerHTML=e1("check","sm"),window.setTimeout(()=>{r.innerHTML=l},w$e())))()}),n.append(r),n}function _$e(e,t={}){const n=document.createElement("div");n.className="mention-tip-skill";const i=document.createElement("div");i.className="mention-tip-head";const o=document.createElement("span");if(o.className="mention-tip-name",o.textContent=e.name,i.append(o),e.path&&t.onOpen){const s=document.createElement("button");s.type="button",s.className="mention-tip-open",s.setAttribute("aria-label",t.openLabel??"Open skill file"),s.innerHTML=e1("external-link","sm");const r=e.path,l=t.onOpen;s.addEventListener("click",a=>{a.preventDefault(),a.stopPropagation(),l(r)}),i.append(s)}if(n.append(i),e.description){const s=document.createElement("div");s.className="mention-tip-desc",s.textContent=e.description,n.append(s)}return n}function cv(e){const t=e.dataset.mentionKind??(e.classList.contains("mention-skill")?"skill":e.classList.contains("mention-folder")?"folder":"file"),n=e.dataset.mentionName??e.querySelector(".mention-pill-name")?.textContent??"";return{kind:t,name:n,path:e.dataset.mentionPath??""}}function M$e(e){let t=null,n=null,i=null,o=null,s,r,l;const a=new Map,u=new Map;function c(H){const O=a.get(H);return O!==void 0&&Date.now()-O<x$e}function d(H,O){for(const R of document.querySelectorAll(".mention-pill"))(R.dataset.mentionActionPath??R.dataset.mentionPath??"")===H&&R.classList.toggle("mention-missing",O)}function h(H,O,R){if(!e.probePath||H==="")return;const j=e.probeScope?.()??"",$=R??H,W=`${j}|${$}`;if(c(W))return;o=W;let P=u.get(W);P===void 0&&(P=(async()=>{try{const Z=await e.probePath?.($,O);return(e.probeScope?.()??"")!==j?!1:(Z===!1?d($,!0):(a.set(W,Date.now()),d($,!1)),!0)}finally{u.delete(W)}})(),u.set(W,P)),P.then(Z=>{Z&&o===W&&t?.querySelector(".mention-tip-spinner")?.remove()})}function p(H){e.skillsLoaded?.()!==!1&&(H.tabIndex=-1,H.removeAttribute("role"),H.hasAttribute("href")&&(H.dataset.mentionHref=H.getAttribute("href")??"",H.removeAttribute("href"))),H.classList.add("mention-inert")}function g(H){const O=cv(H);if(O.kind==="skill"){const R=e.resolveSkill?.(O.name);return!R?.path||!e.openPath?p(H):H.classList.contains("mention-inert")&&!H.closest(".q-body")&&(H.tabIndex=0,H.setAttribute("role","button"),H.dataset.mentionHref!==void 0&&(H.setAttribute("href",H.dataset.mentionHref),delete H.dataset.mentionHref),H.classList.remove("mention-inert")),_$e(R??{name:O.name,description:""},{openLabel:e.openSkillLabel?.(),onOpen:R?.path&&e.openPath?j=>{w(),e.openPath?.({path:j})}:void 0})}return S$e(O.path!==""?O.path:O.name,{copyLabel:e.copyPathLabel?.()})}function m(H){if(!t)return;const O=H.getBoundingClientRect(),R=t.offsetWidth,j=t.offsetHeight,$=k$e(),W=b$e();let P=O.top-$-j;P<W&&(P=O.bottom+$),P=Math.min(Math.max(P,W),Math.max(W,window.innerHeight-W-j));const Z=Math.min(Math.max(O.left+O.width/2-R/2,W),Math.max(W,window.innerWidth-W-R));t.style.top=`${Math.round(P)}px`,t.style.left=`${Math.round(Z)}px`}function k(H){t||(t=document.createElement("div"),t.className="mention-tip",t.id="mention-tip",t.setAttribute("role","tooltip"),t.addEventListener("mouseenter",()=>window.clearTimeout(r)),t.addEventListener("mouseleave",()=>b()),t.addEventListener("focusin",()=>window.clearTimeout(r)),t.addEventListener("focusout",R=>{const j=R.relatedTarget;j instanceof Node&&(t?.contains(j)||n?.contains(j))||w()}),document.body.append(t)),n?.removeAttribute("aria-describedby"),n=H,n.setAttribute("aria-describedby",t.id);const O=cv(H);if(i=O.kind!=="skill"&&O.path!==""?O.path:null,o=null,t.replaceChildren(g(H)),t.classList.remove("positioned"),m(H),t.classList.add("positioned"),t.removeAttribute("inert"),i!==null&&e.probePath){const R=H.dataset.mentionActionPath??i,j=`${e.probeScope?.()??""}|${R}`;if(!c(j)){const $=document.createElement("span");$.className="mention-tip-spinner",$.setAttribute("aria-hidden","true"),(t.querySelector(".mention-tip-path-text")??t).append($),h(i,O.kind==="folder"?"folder":"file",H.dataset.mentionActionPath)}}l??=new MutationObserver(()=>{n&&!n.isConnected&&w()}),l.disconnect(),l.observe(document.body,{childList:!0,subtree:!0})}function w(){window.clearTimeout(s),window.clearTimeout(r),n?.removeAttribute("aria-describedby"),n=null,i=null,o=null,l?.disconnect(),t?.classList.remove("positioned"),t?.setAttribute("inert","")}function y(H){window.clearTimeout(s),window.clearTimeout(r);const O=t?.classList.contains("positioned")?0:A$e();s=window.setTimeout(()=>{H.isConnected&&k(H)},O)}function b(){window.clearTimeout(s),window.clearTimeout(r),r=window.setTimeout(w,C$e())}function A(H){return H instanceof Element?H.closest(".mention-pill"):null}function T(H){const O=A(H.target);if(!O)return;if(O===n){window.clearTimeout(r);return}const R=H.relatedTarget;R instanceof Element&&O.contains(R)||y(O)}function S(H){const O=A(H.target);if(!O)return;const R=H.relatedTarget;R instanceof Element&&(O.contains(R)||t?.contains(R))||b()}function x(H){if(H.key==="Enter"||H.key===" "){const O=A(H.target);if(O&&M(O,H))return}if(H.key==="Escape"){t?.classList.contains("positioned")&&(n&&H.target instanceof Node&&t.contains(H.target)&&n.focus(),w(),H.preventDefault(),H.stopImmediatePropagation());return}if(H.key==="Tab"){if(t?.classList.contains("positioned")&&H.target instanceof Node&&t.contains(H.target)){const R=[...t.querySelectorAll("button")],j=R[0],$=R[R.length-1];(!H.shiftKey&&H.target===$||H.shiftKey&&H.target===j)&&(H.preventDefault(),n?.focus(),w());return}if(H.shiftKey)return;if(A(H.target)===n&&t?.classList.contains("positioned")){const R=t.querySelector("button");R&&(H.preventDefault(),R.focus())}return}t&&H.target instanceof Node&&t.contains(H.target)||t?.contains(document.activeElement)||w()}function _(){w()}function L(H){t&&H.target instanceof Node&&t.contains(H.target)||w()}function M(H,O){if(H.closest(".ProseMirror")||H.closest(".q-body")||cv(H).kind!=="skill")return!1;const R=e.resolveSkill?.(cv(H).name);return!R?.path||!e.openPath?(p(H),!1):(O.preventDefault(),O.stopPropagation(),w(),e.openPath({path:R.path}),!0)}function N(H){const O=A(H.target);if(O){if(O===n){window.clearTimeout(r);return}y(O)}}function I(H){if(!A(H.target))return;const R=H.relatedTarget;R instanceof Node&&t?.contains(R)||b()}function z(H){const O=A(H.target);O&&M(O,H)}return document.addEventListener("mouseover",T),document.addEventListener("mouseout",S),document.addEventListener("focusin",N),document.addEventListener("focusout",I),document.addEventListener("keydown",x,!0),document.addEventListener("scroll",_,!0),document.addEventListener("pointerdown",L),document.addEventListener("click",z,!0),window.addEventListener("resize",_),()=>{w(),t?.remove(),t=null,document.removeEventListener("mouseover",T),document.removeEventListener("mouseout",S),document.removeEventListener("focusin",N),document.removeEventListener("focusout",I),document.removeEventListener("keydown",x,!0),document.removeEventListener("scroll",_,!0),document.removeEventListener("pointerdown",L),document.removeEventListener("click",z,!0),window.removeEventListener("resize",_)}}const I$e=["data-mention-kind","data-mention-name","data-mention-path","data-mention-action-path","onClick","onKeydown"],E$e=["innerHTML"],T$e={class:"mention-pill-name"},eL=Xe({__name:"ComposerText",props:{text:{},interactive:{type:Boolean,default:!0},openFile:{type:Function,default:void 0}},setup(e){const t=e,n=F(()=>SBe(t.text));function i(a){return!t.interactive||a.kind==="folder"?{}:a.kind==="skill"?{tabindex:0,role:"button"}:t.openFile?{tabindex:0,role:"button"}:{}}function o(a){if(a.type!=="mention"||a.attrs.kind==="skill")return;const u=ch(Ep(a.rawDest));return u!==a.attrs.path?u:void 0}function s(a,u){a.type!=="mention"||!t.interactive||a.attrs.kind!=="file"||!t.openFile||(u.preventDefault(),u.stopPropagation(),t.openFile({path:o(a)??a.attrs.path}))}function r(a,u){u.key!=="Enter"&&u.key!==" "||s(a,u)}function l(a){const u=window.getSelection(),c=a.currentTarget;if(!u||u.isCollapsed||u.rangeCount===0||!c)return;const d=u.getRangeAt(0);if(!c.contains(d.commonAncestorContainer))return;const h=d.cloneContents();for(const p of h.querySelectorAll(".mention-pill")){const g=p.getAttribute("data-mention-kind");if(g!=="file"&&g!=="folder"&&g!=="skill")continue;const m=p.getAttribute("data-mention-name")??"",k=p.getAttribute("data-mention-path")??"";p.replaceWith(document.createTextNode(cA({kind:g,name:m,path:k})))}a.clipboardData?.setData("text/plain",h.textContent??""),a.preventDefault()}return(a,u)=>(v(),E("span",{class:"composer-text",onCopy:l},[(v(!0),E(Ee,null,pt(n.value,(c,d)=>(v(),E(Ee,{key:d},[c.type==="mention"?(v(),E("span",ni({key:0,class:`mention-pill mention-${c.attrs.kind}`,"data-mention-kind":c.attrs.kind,"data-mention-name":c.attrs.name,"data-mention-path":c.attrs.path||void 0,"data-mention-action-path":o(c)},{ref_for:!0},i(c.attrs),{onClick:h=>s(c,h),onKeydown:h=>r(c,h)}),[C("span",{class:"mention-pill-icon","aria-hidden":"true",innerHTML:f(CA)(c.attrs.kind,c.attrs.path,c.attrs.name)},null,8,E$e),C("span",T$e,D(f(Uj)(c.attrs.name)),1)],16,I$e)):(v(),E(Ee,{key:1},[$e(D(c.value),1)],64))],64))),128))],32))}}),Kj=["cjs","css","csv","gif","htm","html","jpeg","jpg","js","json","jsx","log","md","mjs","pdf","png","scss","svg","ts","tsx","txt","vue","webp","xml","yaml","yml"],L$e=new Set(["AGENTS.md","CHANGELOG.md","Dockerfile","LICENSE","Makefile","README.md","package.json","pnpm-lock.yaml","pnpm-workspace.yaml","tsconfig.json","vite.config.ts"]),x5=[...Kj].sort((e,t)=>t.length-e.length).join("|"),zk=new RegExp([String.raw`(?:^|[\s([{"'`+"`"+String.raw`])`,String.raw`(`,String.raw`(?:~|\.{1,2}|/)?(?:[A-Za-z0-9_.@+()[\]-]+/)+[A-Za-z0-9_.@+()[\]-]+(?:\.(?:${x5}))?`,String.raw`|`,String.raw`[A-Za-z0-9_.@+()[\]-]+\.(?:${x5})`,String.raw`)`,String.raw`(?:#L?(\d+)|:(\d+))?`,String.raw`(?=$|[\s)"'\]}>.,;!?,。;!?)])`].join(""),"gi"),Vj=/[),.;!?,。;!?)]+$/;function N$e(e){const t=e.toLowerCase();return Kj.some(n=>t.endsWith(`.${n}`))}function F$e(e){const t=new Map,n=new RegExp(String.raw`\b(?:path|src)=["'](\/[^"']+\.(?:${x5}))["']`,"gi");let i;for(;(i=n.exec(e))!==null;){const o=i[1];if(!o)continue;const s=o.split("/").pop();s&&t.set(s,o)}return t}function D$e(e,t={}){const n=e.trim();if(!n||/^[a-z][a-z0-9+.-]*:\/\//i.test(n))return null;const i=n.match(/^(.*?)(?:#L?(\d+)|:(\d+))?$/i);if(!i)return null;let o=(i[1]??"").replace(Vj,"");if(!o)return null;const s=o.split("/").pop()??o,r=o.includes("/"),l=L$e.has(s),a=N$e(s);if(r&&!l&&!a)return null;if(!r&&!l){const d=t.aliases?.get(s);if(!d)return null;o=d}const u=i[2]??i[3],c=u?Number(u):void 0;return{path:o,line:c!==void 0&&Number.isFinite(c)&&c>0?c:void 0}}function B$e(e,t={}){const n=[];zk.lastIndex=0;let i;for(;(i=zk.exec(e))!==null;){const o=i[0]??"",s=i[1]??"",r=o.indexOf(s);if(r<0)continue;const l=i[2]??i[3];let a=s+(l?o.slice(r+s.length):"");const u=a.replace(Vj,""),c=a.length-u.length;a=u;const d=D$e(a,t);if(!d)continue;const h=i.index+r,p=h+a.length;n.push({...d,start:h,end:p,text:a}),c>0&&(zk.lastIndex-=c)}return n}const $$e=/^---[ \t]*$/,R$e=/^---[ \t]*(?:\r\n|\n)/;function z$e(e){const t=R$e.exec(e);if(t===null)return{frontmatter:null,body:e};let n=t[0].length;const i=n;for(;n<=e.length;){let o=e.indexOf(` -`,n);o===-1&&(o=e.length);let s=e.slice(n,o);if(s.endsWith("\r")&&(s=s.slice(0,-1)),$$e.test(s)){const r=e.slice(i,n);if(r==="")return{frontmatter:null,body:e};const l=o<e.length?e.slice(o+1):"";return{frontmatter:r,body:l}}if(o===e.length)break;n=o+1}return{frontmatter:null,body:e}}function dv(e,t){let n=0,i=t-1;for(;i>=0&&e[i]==="\\";)n++,i--;return n%2===1}const O$e=/\s/,P$e=/\p{Nd}/u;function mf(e,t){const n=e.codePointAt(t);return n===void 0?void 0:String.fromCodePoint(n)}function j$e(e,t){if(t<=0)return;const n=e.charCodeAt(t-1),i=n>=56320&&n<=57343&&t>1?t-2:t-1,o=e.codePointAt(i);return o===void 0?void 0:String.fromCodePoint(o)}function tL(e){return e!==void 0&&O$e.test(e)}function t1(e){return e!==void 0&&P$e.test(e)}function H$e(e,t){const n=e[t+1];return t1(mf(e,t+1))?!0:(n==="-"||n==="+"||n==="."||n==="−"||n==="+"||n==="-")&&t1(mf(e,t+2))}function Ly(e){return e!==void 0&&e>="A"&&e<="Z"}const Zj=new RegExp(String.raw`^(?:AED|AFN|ALL|AMD|ANG|AOA|ARS|AUD|AWG|AZN|BAM|BBD|BDT|BGN|BHD|BIF|BMD|BND|BOB|BRL|BSD|BTN|BWP|BYN|BZD|CAD|CDF|CHF|CLF|CLP|CNY|COP|CRC|CUC|CUP|CVE|CZK|DJF|DKK|DOP|DZD|EGP|ERN|ETB|EUR|FJD|FKP|GBP|GEL|GHS|GIP|GMD|GNF|GTQ|GYD|HKD|HNL|HRK|HTG|HUF|IDR|ILS|INR|IQD|IRR|ISK|JMD|JOD|JPY|KES|KGS|KHR|KMF|KPW|KRW|KWD|KYD|KZT|LAK|LBP|LKR|LRD|LSL|LYD|MAD|MDL|MGA|MKD|MMK|MNT|MOP|MRU|MUR|MVR|MWK|MXN|MYR|MZN|NAD|NGN|NIO|NOK|NPR|NZD|OMR|PAB|PEN|PGK|PHP|PKR|PLN|PYG|QAR|RON|RSD|RUB|RWF|SAR|SBD|SCR|SDG|SEK|SGD|SHP|SLE|SLL|SOS|SRD|SSP|STN|SVC|SYP|SZL|THB|TJS|TMT|TND|TOP|TRY|TTD|TWD|TZS|UAH|UGX|USD|UYU|UZS|VED|VES|VND|VUV|WST|XAF|XCD|XOF|XPF|YER|ZAR|ZMW|ZWL|HK|US|SG|AU|CA|NZ|NT|TW|RMB|MEX|TT|BZ|EU|UK)$`);function W$e(e,t){if(!Ly(e[t-1]))return!1;let n=t-1;for(;n>0&&Ly(e[n-1]);)n--;return Zj.test(e.slice(n,t))||t1(mf(e,t+1))?!0:t-n<=2&&!/[\p{L}\p{Nd}]/u.test(e[n-1]??"")&&!/\p{L}/u.test(mf(e,t+1)??"")}function q$e(e,t){if(!Ly(e[t-1]))return!1;let n=t-1;for(;n>0&&Ly(e[n-1]);)n--;return Zj.test(e.slice(n,t))?!0:t-n<=2&&!/[\p{L}\p{Nd}]/u.test(e[n-1]??"")}const U$e=/^[-–—,,、;;::~~(([【//]$/;function K$e(e,t){const n=e[t+1];if(n!=="-"&&n!=="+"&&n!=="."||!t1(mf(e,t+2)))return!1;const i=e[t-1];return i!==void 0&&U$e.test(i)}function V$e(e){const t=String.raw`[、,,;;::~~\-–—至到//\s()()=*×=]|和|跟|与|及|或|and|or`;let n=e.replace(new RegExp(String.raw`^(?:${t})+`,"u"),"");for(;;){const o=n.replace(new RegExp(String.raw`^\p{L}+(?:${t})+`,"u"),"").replace(/^[\p{L}][\p{L} ]*(?=\p{Nd})/u,"");if(o===n)break;n=o}if(!/\p{Nd}/u.test(n))return!1;const i=String.raw`[-+]?[\p{Nd}][\p{Nd},.'’]*`;return new RegExp(String.raw`^${i}(?:\p{L}+)?(?:(?:${t})+${i}(?:\p{L}+)?)*$`,"u").test(n)}const Sa=-1,nL=1,iL=2,oL=3;function Z$e(e){const t=e.length,n=new Uint8Array(t),i=new Int32Array(t+1).fill(Sa),o=new Int32Array(t+1),s=new Int32Array(t+1),r=[],l=[];{const $=[];for(let ae=0;ae<t;ae++)if(e[ae]==="`"){if(dv(e,ae))continue;let V=ae+1;for(;V<t&&e[V]==="`";)V++;$.push([ae,V]),ae=V-1}const W=new Map;for(let ae=0;ae<$.length;ae++){const V=$[ae][1]-$[ae][0],Y=W.get(V);Y?Y.push(ae):W.set(V,[ae])}const P=new Map;let Z=0;for(;Z<$.length;){const[ae,V]=$[Z],Y=V-ae,oe=W.get(Y);let q=P.get(Y)??0;for(;q<oe.length&&oe[q]<=Z;)q++;P.set(Y,q),q<oe.length?(l.push([ae,$[oe[q]][1]]),Z=oe[q]+1):Z++}}let a=0;const u=$=>{for(;a<l.length&&$>=(l[a]?.[1]??0);)a++;const W=l[a];return W!==void 0&&$>=W[0]},c=new Set(' \n\r)。,、;:!?"<>`「」『』【】〔〕()*—–“”‘’'),d=[];for(const $ of e.matchAll(/\b(?:https?:\/\/|ftp:\/\/|mailto:|www\.)/gi))d.push($.index);for(const $ of e.matchAll(/\b(?:localhost|(?:\d{1,3}\.){3}\d{1,3}|[\w-]+(?:\.[\w-]+)*\.[a-zA-Z]{2,})(?=(?:\/|\?|:\d))/gi))d.push($.index);for(const $ of e.matchAll(/(?:\.{1,2})?\/[\p{L}\p{Nd}._-]+(?:\/[\p{L}\p{Nd}._-]*)*\?/gu))($.index===0||!/[\w~/.-]/.test(e[$.index-1]))&&d.push($.index);d.sort(($,W)=>$-W);let h=-1;for(const $ of d){if($<h)continue;let W=$,P=0,Z=0,ae=0;for(;W<t;){const V=e[W];if(V==="(")P++;else if(V===")"){if(P===0)break;P--}else if(V==="[")Z++;else if(V==="]"){if(Z===0)break;Z--}else if(V==="{")ae++;else if(V==="}"){if(ae===0)break;ae--}else{if(c.has(V))break;if((V===","||V===";"||V==="!"||V==="?")&&!/[A-Za-z0-9$]/.test(e[W+1]??""))break;if(V===":"&&Z===0&&W>$+7&&!/[\w/?#@~.+&=%-]/.test(e[W+1]??""))break}W++}r.push([$,W]),h=W}const p=[];for(let $=0;$<t;$++){if(e[$]!=="<"||e[$+1]===void 0||!/[a-zA-Z/]/.test(e[$+1]))continue;let W=$+1;const P=e[W]==="/";P&&W++;const Z=/^[a-zA-Z][a-zA-Z0-9-]*/.exec(e.slice(W));if(!Z)continue;W+=Z[0].length;const ae=e[W];if(ae===void 0||!/[\s/>]/.test(ae))continue;let V=W,Y=Sa,oe=Sa;for(;V<t;){const q=e[V];if(q===">"){oe=V;break}if(!P&&q==="/"&&e[V+1]===">"){oe=V+1;break}if(!/\s/.test(q)){Y=V;break}for(;V<t&&/\s/.test(e[V]);)V++;const ne=e[V];if(ne===void 0)break;if(ne===">"){oe=V;break}if(P){Y=V;break}if(ne==="/"&&e[V+1]===">"){oe=V+1;break}const ie=/^[a-zA-Z_:][\w:.-]*/.exec(e.slice(V));if(!ie){Y=V;break}V+=ie[0].length;let pe=V;for(;pe<t&&/\s/.test(e[pe]);)pe++;if(e[pe]==="="){for(pe++;pe<t&&/\s/.test(e[pe]);)pe++;const Ne=e[pe];if(Ne==='"'||Ne==="'"){const te=e.indexOf(Ne,pe+1);if(te===-1){Y=pe;break}V=te+1}else{const te=/^[^\s"'=<>`]+/.exec(e.slice(pe));if(!te){Y=pe;break}V=pe+te[0].length}}}if(oe!==Sa)p.push([$,oe+1]),$=oe;else if(Y!==Sa){const q=e.indexOf("<",$+1);$=(q!==-1&&q<Y?q:Y)-1}else break}let g=!0,m=!0,k=!0,w=!0;for(let $=0;$<t;$++){if(e[$]!=="<")continue;const W=e[$+1];let P=!1;if(W==="?"&&m){const Y=e.indexOf("?>",$+2);Y===-1?m=!1:(p.push([$,Y+2]),$=Y+1,P=!0)}else if(W==="!"){if(e[$+2]==="-"&&e[$+3]==="-"){if(g){const Y=e.indexOf("-->",$+4);Y===-1?g=!1:(p.push([$,Y+3]),$=Y+2,P=!0)}}else if(e.startsWith("[CDATA[",$+2)){if(k){const Y=e.indexOf("]]>",$+9);Y===-1?k=!1:(p.push([$,Y+3]),$=Y+2,P=!0)}}else if(w&&/[A-Z]/.test(e[$+2]??"")){const Y=e.indexOf(">",$+3);Y===-1?w=!1:(p.push([$,Y+1]),$=Y,P=!0)}}if(P)continue;if(W!==void 0&&/[a-zA-Z]/.test(W)){const Y=/^[a-zA-Z][a-zA-Z0-9+.-]{1,31}:/.exec(e.slice($+1));if(Y){let oe=$+1+Y[0].length;for(;oe<t&&e[oe]!==">"&&e[oe]!=="<"&&!/\s/.test(e[oe]);)oe++;if(e[oe]===">"){p.push([$,oe+1]),$=oe;continue}}}if(W===void 0||!/[\w.!#$%&'*+/=?^`{|}~-]/.test(W))continue;let Z=$+1;for(;Z<t&&/[\w.!#$%&'*+/=?^`{|}~-]/.test(e[Z]);)Z++;if(e[Z]!=="@")continue;Z++;const ae=/^[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?/;let V=ae.exec(e.slice(Z));if(V){for(Z+=V[0].length;e[Z]==="."&&(V=ae.exec(e.slice(Z+1)),!!V);)Z+=1+V[0].length;e[Z]===">"&&(p.push([$,Z+1]),$=Z)}}p.sort(($,W)=>$[0]-W[0]);const y=[];for(const[$,W]of p){const P=y[y.length-1];P&&$<=P[1]?P[1]=Math.max(P[1],W):y.push([$,W])}r.push(...y);let b=0;const A=$=>{for(;b<y.length&&$>=(y[b]?.[1]??0);)b++;const W=y[b];return W!==void 0&&$>=W[0]},T=[];let S=null,x=0,_=!1;for(let $=0;$<t;$++)if(e[$]==="\\")$++;else if(_)e[$]===">"&&(_=!1);else if(!(u($)||A($))){if(S!==null)e[$]===S&&(S=null);else if(T.length>0&&(e[$]==='"'||e[$]==="'")&&$>0&&/\s/.test(e[$-1]))S=e[$];else if(e[$]==="[")x++;else if(e[$]==="]")x>0&&e[$+1]==="("&&(T.push($),_=e[$+2]==="<",$++),x=Math.max(0,x-1);else if(e[$]==="("&&T.length>0)T.push(-1);else if(e[$]===")"&&T.length>0){const W=T.pop();if(W!==void 0&&W>=0){const P=e.slice(W+2,$);(/\s/.exec(P)===null||P.startsWith("<")&&/^<(?:\\[<>]|[^<>])*>$/.test(P)||/^[^\s]*\s+("([^"\\]|\\.)*"|'([^'\\]|\\.)*'|\(([^()\\]|\\.)*\))$/.test(P))&&r.push([W,$+1])}}}r.sort(($,W)=>$[0]-W[0]);const L=[];for(const[$,W]of r){const P=L[L.length-1];P&&$<=P[1]?P[1]=Math.max(P[1],W):L.push([$,W])}const M=$=>{let W=0,P=L.length-1;for(;W<=P;){const Z=W+P>>1,ae=L[Z];if(ae===void 0)return!1;if($<ae[0])P=Z-1;else if($>=ae[1])W=Z+1;else return!0}return!1},N=new Uint8Array(t);{let $=-1,W=!1,P=!1,Z=0;for(let ae=0;ae<=t;ae++){const V=ae<t&&e[ae]==="`";if(ae===t||V){if(V&&$!==-1&&P&&!W&&Z===0)for(let oe=$+1;oe<ae;oe++)N[oe]=1;$=ae,W=!1,P=!1,Z=0;continue}if($===-1)continue;const Y=e[ae];Y==="$"?dv(e,ae)||(e[ae+1]==="{"?(P=!0,Z++,ae++):Z===0&&(W=!0)):Z>0&&(Y==="{"?Z++:Y==="}"&&Z--)}}for(let $=0;$<t;$++)s[$+1]=(s[$]??0)+(e[$]==="`"&&!dv(e,$)?1:0),e[$]==="$"&&(dv(e,$)||M($)||N[$]===1?n[$]=nL:tL(e[$-1])||t1(mf(e,$+1))||K$e(e,$)?n[$]=iL:n[$]=oL),o[$+1]=(o[$]??0)+(n[$]===iL?1:0);let I=Sa;for(let $=t-1;$>=0;$--)n[$]===oL&&(I=$),i[$]=I;const z=/^[\p{L}\p{Nd}\\|{([+.¬°-±×÷′-″←-⇿∀-⋿^_<>=-]$/u,H=/[^\p{L}\p{Nd}\s]$/u,O=/[^\s\u0020-\u007E\u0370-\u03FF\u{1D400}-\u{1D7FF}\p{Nd}¬°-±×÷′-″←-⇿∀-⋿]/u,R=/(?:^|\s)[a-z]{2,}/,j=($,W)=>{const P=mf(e,$+1);if(P===void 0||!z.test(P))return!1;const Z=i[$+1]??Sa;if(Z!==Sa){const ae=e.slice($+1,Z);return!(ae.length===((ae.codePointAt(0)??0)>65535?2:1))&&O.test(ae)||/[,;:!?]$/.test(ae)||/^[a-z]{2,}$/.test(ae)?!1:(o[Z]??0)-(o[$+1]??0)===0&&(s[Z]??0)-(s[$+1]??0)===0}return H.test(W)||O.test(W)||R.test(W)};return($,W=-1)=>{if(e[$]!=="$"||n[$]===nL||e[$+1]==="$"||e[$-1]==="$"&&W!==$||W$e(e,$)||$+1>=t||tL(e[$+1]))return null;const P=i[$+1]??Sa;if(P===Sa||(o[P]??0)-(o[$+1]??0)>0||(s[P]??0)-(s[$+1]??0)>0)return null;const Z=e.slice($+1,P);return/^\{[A-Z_][A-Z0-9_]*(?:\}$|[:-])/.test(Z)||e[P+1]==="{"&&/^\{[A-Za-z_][A-Za-z0-9_]*(?:[:-][^{}]*)?\}$/.test(Z)||t1(j$e(e,$))&&V$e(Z)||H$e(e,$)&&(j(P,Z)||q$e(e,P)||/\s/.test(Z)&&/\p{Nd}$/u.test(Z)&&!/[+\-*/^=_<>|\\¬°-±×÷′-″←-⇿∀-⋿]/.test(Z)||e[P+1]==="$"&&!/\p{L}/u.test(Z)&&/[^\p{L}\p{Nd}\s]$/u.test(Z))?null:{content:Z,end:P+1}}}const sL=new WeakMap;function G$e(e,t){if(e.src[e.pos]!=="$")return!1;let n=sL.get(e);(!n||n.src!==e.src)&&(n={src:e.src,match:Z$e(e.src),lastEnd:-1},sL.set(e,n));const i=n.match(e.pos,n.lastEnd);if(!i||i.end>e.posMax)return!1;if(n.lastEnd=i.end,t)return e.pos=i.end,!0;const o=e.push("math_inline","math",0);return o.content=i.content,o.markup="$",o.raw=e.src.slice(e.pos,i.end),o.loading=!1,e.pos=i.end,!0}function Q$e(e){return e.set({typographer:!1}),e.inline.ruler.disable("math"),e.inline.ruler.before("escape","math",G$e),e}const Y$e=12e4,J$e=6e4,X$e=32,eRe=3e4,rL=/(^|\n)(`{3,}|~{3,})[^\n]*\n([\s\S]*?)(?:\n)?\2(?=\n|$)/g;function tRe(e){let t=0,n=0,i=0;rL.lastIndex=0;let o;for(;(o=rL.exec(e))!==null;){const r=o[3]??"";t+=1,n+=r.length,i=Math.max(i,r.length)}return{codeRenderer:e.length>=Y$e||n>=J$e||t>=X$e||i>=eRe?"pre":"shiki",codeFenceCount:t,codeChars:n}}async function Gj(e){const t=typeof navigator<"u"?navigator.clipboard:void 0;if(t&&typeof t.writeText=="function")try{return await t.writeText(e),!0}catch{}return iRe(e)}function nRe(e){if(typeof e!="string")return;const t=typeof navigator<"u"?navigator.clipboard:void 0;t&&typeof t.writeText=="function"||Gj(e)}function iRe(e){if(typeof document>"u"||typeof document.execCommand!="function")return!1;const t=document.createElement("textarea");t.value=e,t.setAttribute("readonly",""),t.style.position="fixed",t.style.top="-9999px",t.style.left="-9999px",t.style.opacity="0",document.body.appendChild(t);let n=!1;try{t.focus(),t.select(),n=document.execCommand("copy")}catch{n=!1}finally{document.body.removeChild(t)}return n}const Qj="md-table-wide",Yj="md-table-toggle",Jj="md-table-fade",lL="md-table-toggle--show",oRe="md-table-at-end",sRe="kimi-table-layout",Xj='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="15 3 21 3 21 9"/><polyline points="9 21 3 21 3 15"/><line x1="21" y1="3" x2="14" y2="10"/><line x1="3" y1="21" x2="10" y2="14"/></svg>',rRe='<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polyline points="4 14 10 14 10 20"/><polyline points="20 10 14 10 14 4"/><line x1="14" y1="10" x2="21" y2="3"/><line x1="3" y1="21" x2="10" y2="14"/></svg>';function Ig(e){return e.querySelector(`button.${Yj}`)}function eH(e){return e.querySelector(`.${Jj}`)}const lRe=26;function aRe(e){const t=Ig(e);if(!t)return;const n=e.querySelector("thead tr")??e.querySelector("tr");if(!n)return;const i=n.getBoundingClientRect(),o=e.getBoundingClientRect().top,s=Math.max(2,Math.round(i.top-o+(i.height-lRe)/2));t.style.top=`${s}px`,t.style.right=`${s}px`}function uRe(e){return e.closest(".a-msg .msg")!==null}function cRe(e){const t=e.querySelector("table");return t!==null&&t.scrollWidth>e.clientWidth+1}function tH(e){const t=`translateX(${e.scrollLeft}px)`,n=eH(e);n&&(n.style.transform=t);const i=Ig(e);i&&(i.style.transform=t);const o=e.scrollLeft+e.clientWidth>=e.scrollWidth-2;e.classList.toggle(oRe,o)}function dRe(e,t){const n=Ig(e);if(n)return n;if(!uRe(e))return null;const i=document.createElement("div");i.className=Jj,i.setAttribute("aria-hidden","true");const o=document.createElement("button");return o.type="button",o.className=Yj,o.innerHTML=Xj,o.setAttribute("aria-label",t.widen),o.title=t.widen,o.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation(),fRe(e,t)}),e.appendChild(i),e.appendChild(o),e.addEventListener("scroll",()=>tH(e),{passive:!0}),wA(e),o}function fRe(e,t){const n=e.classList.toggle(Qj),i=Ig(e);if(i){i.innerHTML=n?rRe:Xj;const o=n?t.restore:t.widen;i.setAttribute("aria-label",o),i.title=o}wA(e),e.dispatchEvent(new CustomEvent(sRe,{bubbles:!0}))}function wA(e){const t=Ig(e);if(!t)return;const n=cRe(e),i=e.classList.contains(Qj);t.classList.toggle(lL,n||i);const o=eH(e);o&&o.classList.toggle(lL,n),aRe(e),tH(e)}const hRe={key:0,class:"md-frontmatter"},pRe={key:1,class:"diff-wrap"},gRe={class:"diff-bar"},mRe=["aria-label","onClick"],vRe={class:"diff-pre"},yRe={key:0,class:"diff-sign"},kRe={class:"diff-text"},bRe="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7",aL="github-light",uL="github-dark",ARe=Xe({__name:"Markdown",props:{text:{},openFile:{},resolveMentionPath:{},streaming:{type:Boolean,default:!1}},setup(e){mEe(),EEe(),NP();const{t}=a1(),n=hn("resolveImage"),i=K(null),o=e,s=F(()=>!o.streaming),r=F(()=>z$e(o.text??"")),l=F(()=>r.value.frontmatter),a=F(()=>r.value.body),u=F(()=>F$e(a.value)),c=F(()=>o.streaming?{codeRenderer:"shiki",codeFenceCount:0,codeChars:0}:tRe(a.value)),d=a9(),h=F(()=>!o.streaming),p=jo(new Map),g=new Set,m=/(!\[[^\]]*\]\()\s*([^)\s]+)([^)]*\))/g,k=/(<img\b[^>]*?\bsrc=")([^"]+)(")/gi;function w($){return!/^(https?:|data:|blob:)/i.test($)}function y($){if(!n)return;const W=[];for(const P of[m,k]){P.lastIndex=0;let Z;for(;(Z=P.exec($))!==null;)W.push(Z[2]??"")}for(const P of W)!P||!w(P)||p.has(P)||g.has(P)||(g.add(P),n(P).then(Z=>{p.set(P,Z!==P?Z:"")}).catch(()=>{p.set(P,"")}).finally(()=>{g.delete(P)}))}function b($){if(!n)return $;const W=P=>{if(!w(P))return null;const Z=p.get(P);return Z===void 0?bRe:Z===""?null:Z};return $.replace(m,(P,Z,ae,V)=>{const Y=W(ae);return Y===null?P:`${Z}${Y}${V}`}).replace(k,(P,Z,ae,V)=>{const Y=W(ae);return Y===null?P:`${Z}${Y}${V}`})}Pe(a,$=>y($),{immediate:!0});function A(){if(!i.value||!o.openFile||o.streaming)return;const $=document.createTreeWalker(i.value,NodeFilter.SHOW_TEXT),W=[];let P=$.nextNode();for(;P;){const Z=P,ae=Z.parentElement;ae&&!ae.closest("a, pre, .md-file-link, svg")&&Z.data.trim().length>0&&W.push(Z),P=$.nextNode()}for(const Z of W){const ae=B$e(Z.data,{aliases:u.value});if(ae.length===0||!Z.parentNode)continue;const V=document.createDocumentFragment();let Y=0;for(const oe of ae){oe.start>Y&&V.append(document.createTextNode(Z.data.slice(Y,oe.start)));const q=document.createElement("button");q.type="button",q.className="md-file-link",q.textContent=oe.text,q.title=oe.line?`${oe.path}:${oe.line}`:oe.path,q.addEventListener("click",ne=>{ne.preventDefault(),ne.stopPropagation(),o.openFile?.({path:oe.path,line:oe.line})}),V.append(q),Y=oe.end}Y<Z.data.length&&V.append(document.createTextNode(Z.data.slice(Y))),Z.parentNode.replaceChild(V,Z)}}function T(){if(!i.value||o.streaming)return;const $=i.value.querySelectorAll("a[href]");for(const W of $){if(W.dataset.mdLinkHandled==="true"||W.closest("svg"))continue;const P=W.getAttribute("href")??"",Z=hj(P);if(Z===null||W.querySelector("img"))continue;W.dataset.mdLinkHandled="true",W.removeAttribute("title");const ae=Z==="skill"?P:ch(P),V=ABe(W.textContent??"");if(W.classList.add("mention-pill",`mention-${Z}`),W.dataset.mentionKind=Z,W.dataset.mentionName=Z==="skill"?gj(P):V,W.dataset.mentionPath=Z==="skill"?ae:o.resolveMentionPath?.(ae)??ae,Z!=="skill"){const q=o.resolveMentionPath?.(ch(Ep(P)))??ch(Ep(P));q!==W.dataset.mentionPath&&(W.dataset.mentionActionPath=q)}(Z==="skill"||o.openFile)&&W.removeAttribute("href"),(Z==="skill"||Z==="file"&&o.openFile)&&(W.tabIndex=0,W.setAttribute("role","button"));const Y=Uj(V),oe=document.createElement("span");if(oe.className="mention-pill-name",oe.textContent=Y,W.replaceChildren(oe),!W.querySelector(".mention-pill-icon")){const q=document.createElement("span");q.className="mention-pill-icon",q.setAttribute("aria-hidden","true"),q.innerHTML=Z==="skill"?CA("skill","",V):AA(ae,V,Z==="folder"),W.prepend(q)}W.addEventListener("click",q=>{Z!=="skill"&&!o.openFile||(q.preventDefault(),q.stopPropagation(),Z==="file"&&o.openFile?.({path:ch(Ep(P))}))}),Z==="file"&&o.openFile&&W.addEventListener("keydown",q=>{q.key!=="Enter"&&q.key!==" "||(q.preventDefault(),q.stopPropagation(),o.openFile?.({path:ch(Ep(P))}))})}}function S(){return{widen:t("conversation.widenTable"),restore:t("conversation.restoreTableWidth")}}function x(){if(!i.value||o.streaming)return;const $=S();for(const W of i.value.querySelectorAll(".table-node-wrapper"))dRe(W,$)}function _(){if(!(!i.value||o.streaming))for(const $ of i.value.querySelectorAll(".table-node-wrapper"))wA($)}function L(){dt().then(()=>{A(),T(),x()})}Pe(()=>o.text,L),Pe(()=>o.streaming,L);let M=null,N=null;cn(()=>{L(),i.value&&(M=new MutationObserver(L),M.observe(i.value,{childList:!0,subtree:!0}),N=new ResizeObserver(_),N.observe(i.value))}),_n(()=>{M?.disconnect(),N?.disconnect()});const I={showHeader:!0,showCopyButton:!0,showExpandButton:!1,showPreviewButton:!1,showCollapseButton:!1,showFontSizeButtons:!1,loading:!1,monacoOptions:{lineNumbers:!1,fontSize:13,fontFamily:"var(--font-mono)",padding:{top:12,bottom:12}}},z=/(^|\n)(?:```|~~~)diff\b[^\n]*\n([\s\S]*?)(?:\n)?(?:```|~~~)(?=\n|$)/g,H=F(()=>{const $=b(a.value),W=[];let P=0;z.lastIndex=0;let Z;for(;(Z=z.exec($))!==null;){const V=Z[1]??"",Y=$.slice(P,Z.index)+(V||"");Y.trim()&&W.push({kind:"md",text:Y}),W.push({kind:"diff",code:Z[2]??""}),P=z.lastIndex}const ae=$.slice(P);return(ae.trim()||W.length===0)&&W.push({kind:"md",text:ae}),W});function O($){return $.split(` -`).map(W=>W.startsWith("@@")?{type:"hunk",sign:"",text:W}:/^\+(?!\+\+)/.test(W)?{type:"add",sign:"+",text:W.slice(1)}:/^-(?!--)/.test(W)?{type:"del",sign:"-",text:W.slice(1)}:W.startsWith(" ")?{type:"ctx",sign:"",text:W.slice(1)}:{type:"ctx",sign:"",text:W})}const R=K(null);function j($,W){Gj($).then(P=>{P&&(R.value=W,setTimeout(()=>{R.value=null},1400))})}return($,W)=>(v(),E("div",{ref_key:"mdRef",ref:i,class:"md"},[l.value!==null?(v(),E("pre",hRe,D(l.value),1)):X("",!0),(v(!0),E(Ee,null,pt(H.value,(P,Z)=>(v(),E(Ee,{key:Z},[P.kind==="md"?(v(),ce(f(Gr),{key:0,content:P.text,"custom-markdown-it":f(Q$e),mode:"chat","code-renderer":c.value.codeRenderer,"is-dark":f(d),"code-block-light-theme":aL,"code-block-dark-theme":uL,themes:[aL,uL],"code-block-props":I,final:s.value,"smooth-streaming":e.streaming,"batch-rendering":h.value,"defer-nodes-until-visible":!1,onCopy:f(nRe)},null,8,["content","custom-markdown-it","code-renderer","is-dark","themes","final","smooth-streaming","batch-rendering","onCopy"])):(v(),E("div",pRe,[C("div",gRe,[W[0]||(W[0]=C("span",{class:"diff-lang"},"diff",-1)),U(f(gn),{text:f(t)("filePreview.copyCode")},{default:de(()=>[C("button",{class:"diff-copy","aria-label":f(t)("filePreview.copyCode"),onClick:ae=>j(P.code,Z)},[U(f(ve),{name:R.value===Z?"check":"copy",size:"sm"},null,8,["name"])],8,mRe)]),_:2},1032,["text"])]),C("pre",vRe,[C("code",null,[(v(!0),E(Ee,null,pt(O(P.code),(ae,V)=>(v(),E("span",{key:V,class:Fe(["diff-line",`diff-${ae.type}`])},[ae.type!=="hunk"?(v(),E("span",yRe,D(ae.sign),1)):X("",!0),C("span",kRe,D(ae.text),1)],2))),128))])])]))],64))),128))],512))}}),Iu=kt(ARe,[["__scopeId","data-v-4a3beed4"]]),CRe=["innerHTML"],wRe={class:"tl-name"},xRe={key:0,class:"tl-faint"},SRe={key:0,class:"tl-chip"},_Re=["title"],MRe={key:1,class:"plan-content"},IRe={key:2,class:"plan-review"},ERe={key:0},TRe={class:"review-label"},LRe={key:1},NRe={class:"review-label"},FRe={class:"review-feedback"},DRe=Xe({__name:"PlanTool",props:{tool:{},mobile:{type:Boolean}},emits:["openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=K(n.tool.defaultExpanded===!0),r=F(()=>n.tool.plan),l=F(()=>r.value?.path??n.tool.planPath),a=F(()=>r.value!==void 0||l.value!==void 0||(n.tool.output?.length??0)>0),u=F(()=>{const d=r.value?.review?.state;return d?o(`tools.plan.review.${d}`):void 0});function c(){l.value&&i("openFile",{path:l.value,content:r.value?.plan})}return(d,h)=>(v(),ce(Pl,{status:e.tool.status,open:s.value,expandable:a.value,onToggle:h[0]||(h[0]=p=>s.value=!s.value)},{leading:de(()=>[C("span",{class:"plan-glyph",innerHTML:f(CR)(e.tool.name)},null,8,CRe)]),trailing:de(()=>[e.tool.timing?(v(),E("span",SRe,D(e.tool.timing),1)):X("",!0)]),body:de(()=>[l.value?(v(),E("button",{key:0,type:"button",class:"plan-path",title:l.value,onClick:c},D(l.value),9,_Re)):X("",!0),r.value?(v(),E("div",MRe,[U(f(Iu),{text:r.value.plan,"open-file":p=>i("openFile",p)},null,8,["text","open-file"])])):X("",!0),r.value?.review?.selectedOption||r.value?.review?.feedback?(v(),E("div",IRe,[r.value.review.selectedOption?(v(),E("div",ERe,[C("span",TRe,D(f(o)("tools.plan.selectedOption")),1),C("span",null,D(r.value.review.selectedOption),1)])):X("",!0),r.value.review.feedback?(v(),E("div",LRe,[C("span",NRe,D(f(o)("tools.plan.feedback")),1),C("span",FRe,D(r.value.review.feedback),1)])):X("",!0)])):X("",!0),r.value?X("",!0):(v(),ce(Xr,{key:3,lines:e.tool.output,"empty-text":f(o)("tools.output.empty")},null,8,["lines","empty-text"]))]),default:de(()=>[C("span",wRe,D(f(Cf)(e.tool.name)),1),u.value?(v(),E("span",xRe,D(u.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),BRe=kt(DRe,[["__scopeId","data-v-8dff80a1"]]),$Re={class:"tl-name"},RRe={key:1,class:"tl-faint"},zRe={key:2,class:"tl-faint"},ORe={key:3,class:"tl-dim"},PRe={key:0,class:"tl-chip"},jRe=Xe({__name:"ReadTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.tool.status),r=F(()=>Nu(n.tool.arg)),l=F(()=>wR(r.value)??""),a=F(()=>l.value?Tu(l.value):""),u=F(()=>l.value?xR(l.value):""),c=F(()=>{const S=r.value;if(S)return Xu(S.offset)??Xu(S.line_start)??Xu(S.start_line)}),d=F(()=>{const S=r.value;if(!S)return;const x=Xu(S.limit)??Xu(S.length);return Xu(S.line_end)??Xu(S.end_line)??(c.value!==void 0&&x!==void 0?c.value+x:void 0)}),h=F(()=>c.value!==void 0&&d.value!==void 0?`:${c.value}-${d.value}`:c.value!==void 0?`:${c.value}`:""),p=F(()=>n.tool.status==="ok"?qle(n.tool.output??[]):null),g=F(()=>p.value?.contents??[]),m=F(()=>p.value?.lineNumbers),k=F(()=>p.value?.contents.length??n.tool.output?.length??0),w=F(()=>!!n.tool.output&&n.tool.output.length>0),y=F(()=>p.value!==null||w.value),b=K(n.tool.defaultExpanded===!0&&y.value),A=K(b.value);Pe(b,S=>{S&&(A.value=!0)}),Pe(()=>[n.tool.defaultExpanded,n.tool.output?.length,n.tool.status],()=>{n.tool.defaultExpanded===!0&&y.value&&(b.value=!0)});function T(){l.value&&i("openFile",{path:l.value,line:c.value})}return(S,x)=>(v(),ce(Pl,{status:s.value,open:b.value,expandable:y.value,onToggle:x[0]||(x[0]=_=>b.value=!b.value)},{leading:de(()=>[U(f(ve),{name:"file-text",size:"sm"})]),trailing:de(()=>[k.value>0?(v(),E("span",PRe,D(f(o)("tools.chip.lines",{count:k.value})),1)):X("",!0)]),body:de(()=>[l.value?(v(),E("button",{key:0,class:"path-link",type:"button",onClick:T},D(l.value),1)):X("",!0),p.value&&A.value?(v(),ce(oa,{key:1,code:g.value,path:l.value,"line-numbers":m.value},null,8,["code","path","line-numbers"])):(v(),ce(Xr,{key:2,lines:e.tool.output,"empty-text":f(o)("tools.output.waiting")},null,8,["lines","empty-text"]))]),default:de(()=>[C("span",$Re,D(f(o)("tools.label.read")),1),a.value?(v(),E("button",{key:0,class:"tl-file",type:"button",onClick:wt(T,["stop"])},D(a.value),1)):X("",!0),u.value?(v(),E("span",RRe,D(u.value),1)):X("",!0),h.value?(v(),E("span",zRe,D(h.value),1)):X("",!0),a.value?X("",!0):(v(),E("span",ORe,D(l.value||e.tool.arg),1))]),_:1},8,["status","open","expandable"]))}}),HRe=kt(jRe,[["__scopeId","data-v-0edbdd82"]]),WRe=["aria-expanded"],qRe={class:"title"},URe={key:0,class:"meta"},KRe={key:1,class:"sum-txt"},VRe={class:"rt"},ZRe={class:"status"},GRe={key:0,class:"chip"},QRe={key:1,class:"tm"},YRe={class:"body"},JRe={class:"overview"},XRe={class:"overview-line"},eze={class:"big"},tze={key:0,class:"lbl"},nze={key:1,class:"lbl"},ize={key:2,class:"lbl"},oze={key:3,class:"lbl"},sze={key:0,class:"seg","aria-hidden":"true"},rze={key:1,class:"legend"},lze=["disabled","aria-label","aria-expanded","onClick"],aze={class:"mname"},uze={class:"mact"},cze={class:"mphase"},dze=["aria-expanded","onClick"],fze={key:1,class:"fallback-output"},hze={key:2,class:"waiting"},pze=Xe({__name:"SwarmTool",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t;function s($){if(!$)return{};try{const W=JSON.parse($),P=Array.isArray(W.items)?W.items:void 0;return{description:typeof W.description=="string"?W.description:void 0,itemCount:P?.length}}catch{return{}}}const r=hn("resolveSwarmMembers"),l=F(()=>s(i.tool.arg)),a=F(()=>Cf(i.tool.name)),u=F(()=>l.value.description??""),c=F(()=>r?.(i.tool.id)??[]),d=F(()=>rle(i.tool.output)),h=hn("modelDisplay"),p=hn("subagentEffort"),g=F(()=>{let $;for(const W of c.value){const P=h?.(W.model),Z=p?.(W.thinkingEffort),ae=[P,Z].filter(Y=>Y!==void 0);if(ae.length===0)continue;const V=ae.join(" · ");if($===void 0)$=V;else if($!==V)return}return $}),m=F(()=>i.tool.status),k=F(()=>m.value==="running"?"running":m.value==="error"||(d.value?.failed??0)>0?"error":"ok"),w=F(()=>Xse(c.value,d.value)),y=F(()=>{const $={completed:0,working:0,suspended:0,queued:0,failed:0,cancelled:0};for(const W of w.value)$[W.phase]++;return $}),b=F(()=>w.value.length||l.value.itemCount||0),A=F(()=>y.value.completed+y.value.failed+y.value.cancelled),T=F(()=>{const $=d.value;if(!$)return"";const W=$.aborted??0;return W>0?n("tools.swarm.doneSubWithCancelled",{completed:$.completed,failed:$.failed,cancelled:W}):n("tools.swarm.doneSub",{completed:$.completed,failed:$.failed})}),S=F(()=>y.value.working+y.value.suspended+y.value.queued),x=[{phase:"completed",cls:"s-ok"},{phase:"working",cls:"s-run"},{phase:"suspended",cls:"s-warn"},{phase:"failed",cls:"s-fail"},{phase:"cancelled",cls:"s-queue"},{phase:"queued",cls:"s-queue"}],_=F(()=>x.map(({phase:$,cls:W})=>({phase:$,count:y.value[$],cls:W})).filter($=>$.count>0)),L=K(m.value==="running"||S.value>0);function M(){L.value=!L.value}const N=F(()=>w.value.length>0||d.value||m.value==="running"?"":(i.tool.output??[]).join(` -`).trim()),I=K(new Set);function z($){return I.value.has($)}function H($){const W=new Set(I.value);W.has($)?W.delete($):W.add($),I.value=W}function O($){if($.agentId){o("openAgent",$.agentId);return}$.body&&H($.id)}function R($){return $.agentId!==void 0&&$.body.length>0&&($.phase==="completed"||$.phase==="failed"||$.phase==="cancelled")}function j($){return n(`tools.swarm.phase${$[0].toUpperCase()}${$.slice(1)}`)}return($,W)=>(v(),E("div",{class:Fe(["swarm-card",{open:L.value,err:k.value==="error"}])},[C("button",{class:"head",type:"button","aria-expanded":L.value,onClick:M},[U(f(ve),{class:"ic",name:"sparkles",size:"sm"}),C("span",qRe,D(a.value),1),u.value?(v(),E("span",URe,"·")):X("",!0),u.value?(v(),E("span",KRe,D(u.value),1)):X("",!0),C("span",VRe,[C("span",ZRe,[k.value==="ok"?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):k.value==="error"?(v(),ce(f(ve),{key:1,name:"close",size:"sm"})):(v(),ce(f(ml),{key:2,status:"running"}))]),A.value>0||b.value>0?(v(),E("span",GRe,D(A.value)+" / "+D(b.value),1)):X("",!0),e.tool.timing?(v(),E("span",QRe,D(e.tool.timing),1)):X("",!0)]),U(f(ve),{class:"car",name:"chevron-right",size:"sm"})],8,WRe),Wn(C("div",YRe,[C("div",JRe,[C("div",XRe,[C("span",eze,D(f(n)("tools.swarm.progress",{done:A.value,total:b.value})),1),g.value?(v(),E("span",tze,D(g.value),1)):X("",!0),k.value==="running"&&b.value>0?(v(),E("span",nze,D(f(n)("tools.swarm.runningSub",{count:S.value})),1)):d.value?(v(),E("span",ize,D(T.value),1)):(v(),E("span",oze,D(f(n)("tools.swarm.waiting")),1))]),b.value>0&&_.value.length>0?(v(),E("div",sze,[(v(!0),E(Ee,null,pt(_.value,P=>(v(),E("span",{key:P.phase,class:Fe(P.cls),style:Kt({flex:P.count})},null,6))),128))])):X("",!0),_.value.length>1?(v(),E("div",rze,[(v(!0),E(Ee,null,pt(_.value,P=>(v(),E("span",{key:P.phase},[C("i",{class:Fe(["lg-dot",P.cls])},null,2),$e(D(j(P.phase))+" "+D(P.count),1)]))),128))])):X("",!0)]),w.value.length>0?(v(!0),E(Ee,{key:0},pt(w.value,P=>(v(),E("div",{key:P.id,class:Fe(["member",[`phase-${P.phase}`,{open:!P.agentId&&z(P.id)}]])},[C("button",{class:"member-head",type:"button",disabled:!P.agentId&&!P.body,"aria-label":P.agentId?f(n)("tasks.openDetail"):void 0,"aria-expanded":!P.agentId&&P.body?z(P.id):void 0,onClick:Z=>O(P)},[U(f(ml),{class:"row-dot",status:P.phase},null,8,["status"]),U(f(gn),{text:P.name},{default:de(()=>[C("span",aze,D(P.name),1)]),_:2},1032,["text"]),P.activity?(v(),ce(f(gn),{key:0,text:P.activity},{default:de(()=>[C("span",uze,D(P.activity),1)]),_:2},1032,["text"])):X("",!0),C("span",cze,D(j(P.phase)),1),P.agentId?(v(),ce(f(ve),{key:1,class:"mcar",name:"arrow-right",size:"sm"})):P.body?(v(),ce(f(ve),{key:2,class:"mcar",name:"chevron-right",size:"sm"})):X("",!0)],8,lze),R(P)?(v(),E("button",{key:0,class:"member-saved",type:"button","aria-expanded":z(P.id),onClick:Z=>H(P.id)},[U(f(ve),{class:Fe(["member-saved-car",{open:z(P.id)}]),name:"chevron-right",size:"sm","aria-hidden":"true"},null,8,["class"]),C("span",null,D(f(n)("tools.output.saved")),1)],8,dze)):X("",!0),P.body&&(!P.agentId||R(P))?Wn((v(),E("div",{key:1,class:"member-body"},D(P.body),513)),[[Po,z(P.id)]]):X("",!0)],2))),128)):N.value?(v(),E("div",fze,D(N.value),1)):(v(),E("div",hze,D(f(n)("tools.swarm.waiting")),1))],512),[[Po,L.value]])],2))}}),gze=kt(pze,[["__scopeId","data-v-f7b643ea"]]),mze=Xe({__name:"StatusGlyph",props:{status:{}},setup(e){const t=e;return(n,i)=>(v(),E("span",{class:Fe(["status-glyph",`s-${t.status}`]),"aria-hidden":"true"},[t.status==="run"?(v(),ce(f(ml),{key:0,status:"running"})):t.status==="pending"?(v(),ce(f(ml),{key:1,status:"idle"})):t.status==="done"?(v(),ce(f(ve),{key:2,name:"check",size:"sm"})):(v(),ce(f(ve),{key:3,name:"close",size:"sm"}))],2))}}),vze=kt(mze,[["__scopeId","data-v-f1aedfd0"]]),yze={class:"tl-name"},kze={key:0,class:"tl-dim"},bze={key:0,class:"tl-chip"},Aze={key:1,class:"todo-bar","aria-hidden":"true"},Cze={key:0,class:"todo-list"},wze={class:"todo-title"},xze=Xe({__name:"TodoTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=zt();function i(g){const m=Nu(g),k=m&&Array.isArray(m.todos)?m.todos:m&&Array.isArray(m.items)?m.items:void 0;if(!k)return[];const w=[];for(const y of k){if(!y||typeof y!="object")continue;const b=y,A=ri(b.title)??ri(b.content)??ri(b.activeForm)??ri(b.text);if(!A)continue;const T=ri(b.status)??"pending";w.push({title:A,status:T==="in_progress"?"in_progress":T==="done"||T==="completed"?"done":"pending"})}return w}const o=F(()=>t.tool.status),s=F(()=>i(t.tool.arg)),r=F(()=>s.value.filter(g=>g.status==="done").length),l=F(()=>s.value.length),a=F(()=>s.value.find(g=>g.status==="in_progress")),u=F(()=>l.value>0?r.value/l.value:0),c=F(()=>!!t.tool.output&&t.tool.output.length>0),d=F(()=>l.value>0||c.value),h=K(t.tool.defaultExpanded===!0&&d.value);Pe(()=>[t.tool.defaultExpanded,t.tool.status],()=>{t.tool.defaultExpanded===!0&&d.value&&(h.value=!0)});function p(g){return g.status==="in_progress"?"run":g.status}return(g,m)=>(v(),ce(Pl,{status:o.value,open:h.value,expandable:d.value,onToggle:m[0]||(m[0]=k=>h.value=!h.value)},{leading:de(()=>[U(f(ve),{name:"check-list",size:"sm"})]),trailing:de(()=>[l.value>0?(v(),E("span",bze,D(r.value)+"/"+D(l.value),1)):X("",!0),l.value>0?(v(),E("span",Aze,[C("span",{class:"todo-fill",style:Kt({width:`${u.value*100}%`})},null,4)])):X("",!0)]),body:de(()=>[l.value>0?(v(),E("div",Cze,[(v(!0),E(Ee,null,pt(s.value,(k,w)=>(v(),E("div",{key:w,class:Fe(["todo-row",`s-${k.status}`])},[U(vze,{status:p(k)},null,8,["status"]),C("span",wze,D(k.title),1)],2))),128))])):c.value?(v(),ce(Xr,{key:1,lines:e.tool.output},null,8,["lines"])):X("",!0)]),default:de(()=>[C("span",yze,D(f(n)("tools.label.todo")),1),a.value?(v(),E("span",kze,D(a.value.title),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),Sze=kt(xze,[["__scopeId","data-v-1b7f51f3"]]),_ze={class:"tl-name"},Mze={key:0,class:"tl-dim"},Ize={key:2,class:"tl-chip"},Eze={key:0,class:"wf-glance"},Tze={class:"wf-main"},Lze=Xe({__name:"WaitForTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.tool.status),o=F(()=>Nu(t.tool.arg)),s=F(()=>ri(o.value?.task_id)??ri(o.value?.taskId)),r=F(()=>i.value==="error"?null:hle(t.tool.output)),l={completed:"conversation.notification.status.completed",failed:"conversation.notification.status.failed",timed_out:"conversation.notification.status.timed_out",killed:"conversation.notification.status.killed",lost:"conversation.notification.status.lost"},a=F(()=>{const b=r.value?.finishedStatus;if(!b)return"";const A=l[b];return A?n(A):b}),u=F(()=>{switch(r.value?.finishedStatus){case"completed":return"success";case"failed":case"lost":return"danger";case"timed_out":case"killed":return"warning";default:return"neutral"}}),c=F(()=>t.tool.output?.find(b=>b.trim().length>0)??""),d=F(()=>{if(i.value==="running")return s.value?n("tools.waitfor.waitingTask",{id:s.value}):n("tools.waitfor.waitingAny");if(i.value==="error")return c.value;const b=r.value;if(!b)return s.value??c.value;switch(b.status){case"completed":return b.finishedDescription??b.taskId??"";case"timed_out":return b.runningCount>0?n("tools.waitfor.stillRunning",{count:b.runningCount}):n("tools.waitfor.timedOut");case"no_tasks":return n("tools.waitfor.noTasks")}}),h=F(()=>{const b=r.value;return!b||b.status==="no_tasks"?"":Wa(b.waitedMs)}),p=F(()=>h.value||t.tool.timing||"");function g(b){if(b.runningSamples.length===0)return null;const A=[...b.runningSamples],T=b.runningCount-b.runningSamples.length;return T>0&&A.push(n("tools.waitfor.moreRunning",{count:T})),A.join(", ")}const m=F(()=>{const b=r.value;if(!b)return null;if(b.status==="completed"){const A=[b.taskId,a.value].filter(_=>_).join(" · "),T=[];b.finishedDescription&&T.push(b.finishedDescription);const S=[];b.extraCount>0&&S.push(n("tools.waitfor.moreFinished",{count:b.extraCount})),b.runningCount>0&&S.push(n("tools.waitfor.stillRunning",{count:b.runningCount})),S.length>0&&T.push(S.join(" · "));const x=g(b);return x!==null&&T.push(x),{main:A,subs:T}}if(b.status==="timed_out"){if(b.runningCount===0&&b.extraCount===0)return null;const A=b.runningCount>0?n("tools.waitfor.stillRunning",{count:b.runningCount}):n("tools.waitfor.moreFinished",{count:b.extraCount}),T=[];b.runningCount>0&&b.extraCount>0&&T.push(n("tools.waitfor.moreFinished",{count:b.extraCount}));const S=g(b);return S!==null&&T.push(S),{main:A,subs:T}}return null}),k=F(()=>!!t.tool.output&&t.tool.output.length>0),w=F(()=>m.value!==null||k.value),y=K(t.tool.defaultExpanded===!0&&w.value);return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&w.value&&(y.value=!0)}),(b,A)=>(v(),ce(Pl,{status:i.value,open:y.value,expandable:w.value,onToggle:A[0]||(A[0]=T=>y.value=!y.value)},{leading:de(()=>[U(f(ve),{name:"clock",size:"sm"})]),trailing:de(()=>[r.value?.status==="timed_out"?(v(),ce(f(br),{key:0,variant:"warning",size:"sm"},{default:de(()=>[$e(D(f(n)("tools.waitfor.timedOut")),1)]),_:1})):r.value?.status==="completed"&&a.value?(v(),ce(f(br),{key:1,variant:u.value,size:"sm"},{default:de(()=>[$e(D(a.value),1)]),_:1},8,["variant"])):X("",!0),p.value?(v(),E("span",Ize,D(p.value),1)):X("",!0)]),body:de(()=>[m.value?(v(),E("div",Eze,[C("div",Tze,D(m.value.main),1),(v(!0),E(Ee,null,pt(m.value.subs,(T,S)=>(v(),E("div",{key:S,class:"wf-sub"},D(T),1))),128))])):X("",!0),k.value?(v(),ce(Xr,{key:1,lines:e.tool.output,"empty-text":i.value==="running"?f(n)("tools.output.waiting"):f(n)("tools.output.empty")},null,8,["lines","empty-text"])):X("",!0)]),default:de(()=>[C("span",_ze,D(f(Cf)(e.tool.name)),1),d.value?(v(),E("span",Mze,D(d.value),1)):X("",!0)]),_:1},8,["status","open","expandable"]))}}),Nze=kt(Lze,[["__scopeId","data-v-256015f8"]]),Fze={class:"tl-name"},Dze={key:0},Bze={key:1,class:"tl-dim"},$ze={key:0,class:"fetch-url"},Rze=Xe({__name:"WebFetchTool",props:{tool:{},mobile:{type:Boolean,default:!1}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.tool.status),o=F(()=>{const u=Nu(t.tool.arg);return ri(u?.url)??ri(u?.uri)??""}),s=F(()=>o.value?Sbe(o.value):""),r=F(()=>!!t.tool.output&&t.tool.output.length>0),l=F(()=>r.value),a=K(t.tool.defaultExpanded===!0&&l.value);return Pe(()=>[t.tool.defaultExpanded,t.tool.output?.length,t.tool.status],()=>{t.tool.defaultExpanded===!0&&l.value&&(a.value=!0)}),(u,c)=>(v(),ce(Pl,{status:i.value,open:a.value,expandable:l.value,onToggle:c[0]||(c[0]=d=>a.value=!a.value)},{leading:de(()=>[U(f(ve),{name:"globe",size:"sm"})]),body:de(()=>[o.value?(v(),E("div",$ze,D(o.value),1)):X("",!0),U(Xr,{lines:e.tool.output,"empty-text":f(n)("tools.output.waiting")},null,8,["lines","empty-text"])]),default:de(()=>[C("span",Fze,D(f(n)("tools.label.web_fetch")),1),s.value?(v(),E("span",Dze,D(s.value),1)):(v(),E("span",Bze,D(e.tool.arg),1))]),_:1},8,["status","open","expandable"]))}}),zze=kt(Rze,[["__scopeId","data-v-8c248fcc"]]);function Oze(e){if(e.media&&e.status==="ok")return _5e;switch(Gs(e.name)){case"bash":return Lbe;case"read":return HRe;case"edit":case"write":case"multi_edit":return Qbe;case"grep":case"search":return F8e;case"glob":case"ls":return p8e;case"web_fetch":return zze;case"todo":return Sze;case"task":return Zke;case"agentswarm":return gze;case"askuserquestion":return xbe;case"exitplanmode":return BRe;case"creategoal":case"getgoal":case"setgoalbudget":case"updategoal":return C8e;case"waitfor":return Nze;default:return o8e}}const xA=Xe({__name:"ToolCall",props:{tool:{},mobile:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,i=t,o=F(()=>Oze(n.tool));return(s,r)=>(v(),ce(Oo(o.value),{tool:e.tool,mobile:e.mobile,onOpenMedia:r[0]||(r[0]=l=>i("openMedia",l)),onOpenFile:r[1]||(r[1]=l=>i("openFile",l)),onOpenAgent:r[2]||(r[2]=l=>i("openAgent",l))},null,40,["tool","mobile"]))}});function vu(e){if(e.blocks)return e.blocks;const t=[];e.thinking&&t.push({kind:"thinking",thinking:e.thinking}),e.text&&t.push({kind:"text",text:e.text});for(const n of e.tools??[])t.push({kind:"tool",tool:n});return t}function S5(e){return vu(e).some(t=>t.kind==="thinking"&&t.thinking.trim().length>0||t.kind==="text"&&t.text.trim().length>0||t.kind==="tool"||t.kind==="notification")}function nH(e){return!(e.tool.status==="ok"&&e.tool.media)}function Pze(e){const t=vu(e),n=[];let i=[],o=null;const s=()=>{const[l]=i;i.length===1&&l?n.push(l):i.length>1&&n.push({kind:"activity-run",items:i}),i=[]},r=()=>{o&&n.push({kind:"notification",items:o.items,sourceIndex:o.sourceIndex}),o=null};return t.forEach((l,a)=>{if(l.kind==="notification"){o?o.items.push(l.notification):o={items:[l.notification],sourceIndex:a};return}if(i.length===0&&r(),l.kind==="thinking"){i.push({kind:"thinking",thinking:l.thinking,startedAt:l.startedAt,durationMs:l.durationMs,sourceIndex:a});return}if(l.kind==="tool"&&nH(l)){i.push({kind:"tool",tool:l.tool,sourceIndex:a});return}s(),r(),l.kind==="text"?n.push({kind:"text",text:l.text,sourceIndex:a}):l.kind==="tool"&&n.push({kind:"tool",tool:l.tool,sourceIndex:a})}),s(),r(),n}const cL=new WeakMap;function iH(e){const t=cL.get(e);if(t!==void 0)return t;const n=jze(e);return cL.set(e,n),n}function jze(e){const t=Pze(e);let n=-1;for(let r=t.length-1;r>=0;r--){const l=t[r];if(l?.kind==="text"&&l.text.trim().length>0){n=r;break}}if(n===-1){for(let r=0;r<t.length;r++){const l=t[r];if(l?.kind==="tool"&&!nH(l)){n=r;break}if(l?.kind==="notification"){n=r;break}}if(n===-1)return{folded:t,visible:[]}}const i=t.slice(0,n),o=t.slice(n),s=i.filter(r=>r.kind==="notification");return s.length>0?{folded:i.filter(r=>r.kind!=="notification"),visible:[...s,...o]}:{folded:i,visible:o}}function Hze(e){const t=n=>n.kind==="activity-run"?n.items[0]?.sourceIndex??-1:n.sourceIndex;return[...e.folded,...e.visible].sort((n,i)=>t(n)-t(i))}function Wze(e){let t;for(const n of e){if(n.kind!=="thinking"||n.startedAt===void 0)continue;const i=Date.parse(n.startedAt);Number.isNaN(i)||(t===void 0||i<t)&&(t=i)}return t}function dL(e){if(e===void 0)return;const t=Date.parse(e);return Number.isNaN(t)?void 0:t}function qze(e){if(e.state.phase==="settled")return e.durationMs!==void 0?Math.max(0,e.durationMs):e.startMs===void 0||e.endedMs===void 0?void 0:Math.max(0,e.endedMs-e.startMs);if(e.startMs!==void 0)return Math.max(0,e.state.nowMs-e.startMs)}function Uze(e){return iH(e).visible.flatMap(t=>t.kind==="text"&&t.text?[t.text]:[]).join(` - -`)}function Kze(e){const t=[];for(const n of vu(e))if(n.kind==="thinking"&&n.thinking)t.push(`> **Thinking** -> ${n.thinking.split(` -`).join(` -> `)}`);else if(n.kind==="text"&&n.text)t.push(n.text);else if(n.kind==="tool"&&n.tool.output&&n.tool.output.length>0){const i=n.tool.output.join(` -`);t.push(`\`\`\` -[${n.tool.name}] -${i} -\`\`\``)}else if(n.kind==="notification"){const i=n.notification,o=[i.title,i.type,...i.body.split(` -`)].filter(u=>u!==""),s=o.length>0?`> **Notification** -> ${o.join(` -> `)}`:"",r=i.outputPreview?.text??"",l=r!==""?`\`\`\` -[output-preview] -${r} -\`\`\``:"",a=[s,l].filter(u=>u!=="").join(` - -`);a!==""&&t.push(a)}return t.join(` - -`)}function oH(e){return e.tool.id||`tool-${e.sourceIndex}`}function sH(e,t){return e.kind==="activity-run"?`activity-run-${e.items[0]?.sourceIndex??t}`:e.kind==="tool"?oH({tool:e.tool,sourceIndex:e.sourceIndex}):`${e.kind}-${e.sourceIndex}`}function Vze(e){const t=new Map;for(const n of vu(e)){if(n.kind!=="tool"||n.tool.status==="error")continue;const i=n.tool,o=Gs(i.name);if(o!=="edit"&&o!=="multi_edit"&&o!=="write")continue;let s,r=0,l=0,a=!1,u=!1,c=null;if(o==="write")s=mS(i),a=!0,u=!0;else if(c=fB(i),s=mS(i),c){const p=rB(c);r=p.added,l=p.removed}else u=!0;if(!s)continue;const d=Zze(s),h=t.get(d);if(h)if(h.added+=r,h.removed+=l,h.hasWrite||=a,h.statsIncomplete||=u,h.diff!==null&&c!==null){let p=0,g=0;for(const k of h.diff)k.oldNo!==void 0&&k.oldNo>p&&(p=k.oldNo),k.newNo!==void 0&&k.newNo>g&&(g=k.newNo);const m=c.map(k=>({...k,oldNo:k.oldNo!==void 0?k.oldNo+p:void 0,newNo:k.newNo!==void 0?k.newNo+g:void 0}));h.diff=[...h.diff,{type:"hunk",text:"···"},...m]}else h.diff=null;else t.set(d,{path:s,added:r,removed:l,hasWrite:a,statsIncomplete:u,diff:c})}return[...t.values()]}function Zze(e){const t=e.replace(/\\/g,"/");let n="",i=t,o=!1;const s=/^\/\/([^/]+\/[^/]+)(\/|$)/.exec(t);s?(n=`//${s[1].toLowerCase()}/`,i=t.slice(s[0].length-(s[0].endsWith("/")?1:0)),o=!0):/^[a-zA-Z]:\//.test(t)?(n=`${t[0].toLowerCase()}:/`,i=t.slice(3),o=!0):t.startsWith("/")&&(n="/",i=t.slice(1));const r=n!=="",l=[];for(const c of i.split("/"))if(!(!c||c===".")){if(c===".."){l.length>0&&l[l.length-1]!==".."?l.pop():r||l.push(c);continue}l.push(c)}const a=l.join("/"),u=n+a;return o?u.toLowerCase():u}const Gze=2e3,tp=new Map;function Qze(e){const t=[];for(const n of vu(e)){if(n.kind!=="tool")continue;const i=n.tool,o=Gs(i.name);o!=="edit"&&o!=="multi_edit"&&o!=="write"||t.push(`${i.id}:${i.status}:${i.arg.length}`)}return t.join("|")}function Yze(e){const t=Qze(e),n=tp.get(e.id);if(n&&n.key===t)return n.changes;const i=Vze(e);if(tp.set(e.id,{key:t,changes:i}),tp.size>Gze){const o=tp.keys().next().value;o!==void 0&&tp.delete(o)}return i}const Jze=["aria-expanded"],Xze={class:"think-title"},eOe={key:0,class:"think-time"},tOe=["inert"],nOe={class:"think-text"},iOe=Xe({__name:"ThinkingBlock",props:{text:{},mobile:{type:Boolean,default:!1},streaming:{type:Boolean,default:!1},startedAt:{default:void 0},durationMs:{default:void 0},instantReveal:{type:Boolean,default:!1}},setup(e){const t=e,n=K(!1),{t:i}=zt();Pe(()=>t.streaming,(d,h)=>{h&&!d&&(n.value=!1)});const o=K(Date.now());Pe(()=>[t.streaming,t.startedAt],([d,h],p,g)=>{if(!d||!h)return;o.value=Date.now();const m=setInterval(()=>{o.value=Date.now()},1e3);g(()=>clearInterval(m))},{immediate:!0});const s=F(()=>{if(t.streaming&&t.startedAt){const d=Date.parse(t.startedAt);return Number.isFinite(d)?Wa(o.value-d):""}if(t.durationMs!==void 0){const d=Wa(t.durationMs);return d?`· ${d}`:""}return""}),r=hn("pinScroll",()=>{}),l=K(null),a=K(null),u=K(!1);function c(){if(!n.value){const h=(a.value?.scrollHeight??0)>(typeof window<"u"?window.innerHeight:0);u.value=t.instantReveal||t.streaming&&h}if(n.value=!n.value,t.streaming)return;const d=l.value;d&&dt(()=>r(d))}return(d,h)=>(v(),E("div",{class:Fe(["think",{mob:e.mobile,open:n.value,streaming:e.streaming}])},[C("button",{ref_key:"headEl",ref:l,class:"think-head",type:"button","aria-expanded":n.value,onClick:c},[U(f(ve),{class:"think-bulb",name:"thinking",size:"sm"}),C("span",Xze,D(e.streaming?f(i)("thinking.streaming"):f(i)("thinking.panelTitle")),1),s.value?(v(),E("span",eOe,D(s.value),1)):X("",!0),U(f(ve),{class:"think-car",name:"chevron-right",size:"sm"})],8,Jze),C("div",{class:Fe(["think-body",{open:n.value,instant:u.value}]),inert:!n.value},[C("div",{ref_key:"bodyInnerEl",ref:a,class:"think-body-inner"},[C("pre",nOe,D(e.text),1)],512)],10,tOe)],2))}}),SA=kt(iOe,[["__scopeId","data-v-980ffe0e"]]),rH=(e,t)=>t===void 0?da.global.t(e):da.global.t(e,t);function oOe(e,t={}){return xre(rH,e,t)}function sOe(e,t){return _re(rH,e,t)}const rOe=["aria-label"],lOe=["title"],aOe={key:0,class:"ar-sep"},uOe=["inert"],cOe={class:"ar-body-inner"},dOe=Xe({__name:"ActivityRun",props:{items:{},mobile:{type:Boolean,default:!1},streaming:{type:Boolean,default:!1},forceOpen:{type:Boolean,default:!1}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,i=t,o=F(()=>n.items.at(-1)),s=F(()=>{const L=o.value;if(n.streaming&&L?.kind==="thinking")return L;for(let M=n.items.length-1;M>=0;M--){const N=n.items[M];if(N?.kind==="tool"&&N.tool.status==="running")return N}return null}),r=F(()=>{if(n.streaming)return"running";for(const L of n.items)if(L.kind==="tool"&&L.tool.status==="running")return"running";for(const L of n.items)if(L.kind==="tool"&&L.tool.status==="error")return"error";return"done"}),l=K(r.value==="running"),a=F(()=>n.forceOpen||l.value),u=hn("pinScroll",()=>{}),c=K(null),d=K(null),h=K(void 0),p=K(Date.now()),g=F(()=>{let L=null;for(const M of n.items)if(M.kind==="thinking"&&M.startedAt!==void 0){const N=Date.parse(M.startedAt);Number.isFinite(N)&&(L===null||N<L)&&(L=N)}return L});Pe(r,(L,M,N)=>{if(L==="running"){M!==void 0&&M!=="running"&&(l.value=!0),d.value===null&&(d.value=g.value??Date.now()),h.value=void 0,p.value=Date.now();const I=setInterval(()=>{p.value=Date.now()},1e3);N(()=>clearInterval(I));return}M==="running"&&(l.value=!1,d.value!==null&&(h.value=Date.now()-d.value),d.value=null)},{immediate:!0});function m(){if(n.forceOpen||(l.value=!l.value,n.streaming))return;const L=c.value;L&&dt(()=>u(L))}const k=F(()=>{if(r.value==="done")return"check";if(r.value==="error")return"close";const L=s.value??o.value;return L?L.kind==="thinking"?"thinking":AR(L.tool.name):"tool"}),w=F(()=>sOe(n.items,s.value)),y=F(()=>oOe(n.items,{durationMs:h.value})),b=F(()=>r.value!=="running"||d.value===null?"":Wa(p.value-d.value)),A=F(()=>{if(r.value!=="running")return y.value.clauses;const L=[];return w.value.current&&L.push(w.value.current),L.push(...w.value.done),b.value&&L.push({fragments:[{text:b.value,tone:"faint"}]}),L}),T=F(()=>r.value!=="running"?y.value.plain:[w.value.plain,b.value].filter(Boolean).join(" · "));function S(L){if(L==="danger")return"ar-danger";if(L==="faint")return"ar-faint"}function x(L){return L.kind==="tool"?oH(L):`thinking-${L.sourceIndex}`}function _(L){return n.streaming&&L.kind==="thinking"&&L.durationMs===void 0&&L.sourceIndex===o.value?.sourceIndex}return(L,M)=>(v(),E("div",{class:Fe(["activity-run",{open:a.value}])},[(v(),ce(Oo(e.forceOpen?"div":"button"),ni({ref_key:"headEl",ref:c,class:["ar-head",{"is-static":e.forceOpen}]},e.forceOpen?{}:{type:"button","aria-expanded":a.value},{onClick:m}),{default:de(()=>[C("span",{class:Fe(["ar-glyph",{run:r.value==="running",err:r.value==="error",ok:r.value==="done"}]),role:"status","aria-label":r.value},[U(f(ve),{name:k.value,size:"sm","aria-hidden":"true"},null,8,["name"])],10,rOe),C("span",{class:"ar-sum",title:T.value},[(v(!0),E(Ee,null,pt(A.value,(N,I)=>(v(),E(Ee,{key:I},[I>0?(v(),E("span",aOe," · ")):X("",!0),(v(!0),E(Ee,null,pt(N.fragments,(z,H)=>(v(),E("span",{key:H,class:Fe(S(z.tone))},D(z.text),3))),128))],64))),128))],8,lOe),e.forceOpen?X("",!0):(v(),ce(f(ve),{key:0,class:"ar-car",name:"chevron-right",size:"sm","aria-hidden":"true"}))]),_:1},16,["class"])),C("div",{class:Fe(["ar-body",{open:a.value}]),inert:!a.value},[C("div",cOe,[(v(!0),E(Ee,null,pt(e.items,N=>(v(),E(Ee,{key:x(N)},[N.kind==="thinking"?(v(),ce(SA,{key:0,text:N.thinking,mobile:e.mobile,streaming:_(N),"started-at":N.startedAt,"duration-ms":N.durationMs,"instant-reveal":e.forceOpen},null,8,["text","mobile","streaming","started-at","duration-ms","instant-reveal"])):(v(),ce(xA,{key:1,tool:N.tool,mobile:e.mobile,onOpenMedia:M[0]||(M[0]=I=>i("openMedia",I)),onOpenFile:M[1]||(M[1]=I=>i("openFile",I)),onOpenAgent:M[2]||(M[2]=I=>i("openAgent",I))},null,8,["tool","mobile"]))],64))),128))])],10,uOe)],2))}}),lH=kt(dOe,[["__scopeId","data-v-45842de9"]]),fOe={class:"msg-time"},hOe=Xe({__name:"MessageTime",props:{time:{}},setup(e){const t=e,{t:n}=zt(),i=F(()=>_B(t.time,n("conversation.yesterday")));return(o,s)=>(v(),E("span",fOe,D(i.value),1))}}),_A=kt(hOe,[["__scopeId","data-v-9153170e"]]),pOe={class:"ntf-list"},gOe={class:"ntn-head"},mOe={class:"ntn-head-text"},vOe={class:"ntn-bubble"},yOe={key:0,class:"ntn-line"},kOe={key:1,class:"ntn-line ntn-body"},bOe={key:2,class:"ntn-line ntn-out"},AOe=["title"],COe={key:0,class:"ntn-out-size"},wOe=["onClick"],xOe={key:3,class:"ntn-line ntn-preview"},SOe={key:0,class:"ntn-preview-cap"},_Oe={key:1,class:"ntn-preview-text"},MOe={class:"ntn-line ntn-raw"},IOe={class:"ntn-raw-in"},EOe={class:"ntn-raw-fields"},TOe={class:"k"},LOe={class:"v"},NOe={class:"k"},FOe={class:"v"},DOe={class:"k"},BOe={class:"v"},$Oe={class:"ntn-raw-pre"},ROe={class:"ntn-meta"},zOe=Xe({__name:"NotificationCard",props:{items:{}},setup(e){const{t}=zt(),n={completed:"check",failed:"alert-triangle",timed_out:"clock",killed:"stop",lost:"alert-triangle",info:"info"};function i(k,w){return k.id!==""?`${k.id}#${w}`:`ntf-${w}`}function o(k){const w=Tb(k);return w==="info"&&k.sourceKind==="subagent"?"robot":n[w]}function s(k){return k.sourceKind==="subagent"?t("conversation.notification.kindSubagent"):t("conversation.notification.kindTask")}function r(k){return t(`conversation.notification.title.${Tb(k)}`,{kind:s(k)})}function l(k){return Qoe(k)}function a(k){return k.sourceKind==="subagent"&&k.agentId!==void 0&&k.agentId!==""?k.agentId:k.sourceId}function u(k){const w=a(k);return w===""?r(k):`${r(k)} · ${w}`}function c(k){return k<1024?`${k} B`:k<1024*1024?`${(k/1024).toFixed(1)} KB`:`${(k/1024/1024).toFixed(1)} MB`}function d(k){const w=k.outputPreview;if(!w)return"";const y=[];return w.truncated===!0&&y.push(t("conversation.notification.outputTruncated")),w.bytes!==void 0&&y.push(w.totalBytes!==void 0&&w.totalBytes!==w.bytes?`${c(w.bytes)} / ${c(w.totalBytes)}`:c(w.bytes)),y.join(" · ")}function h(k){return k.outputPreview!==void 0&&(k.outputPreview.text!==""||d(k)!=="")}const p=K(null);let g=null;async function m(k,w){await Xo(k)&&(p.value=w,g!==null&&clearTimeout(g),g=setTimeout(()=>{g=null,p.value=null},1200))}return(k,w)=>(v(),E("div",pOe,[(v(!0),E(Ee,null,pt(e.items,(y,b)=>(v(),E("div",{key:i(y,b),class:Fe(["ntn",l(y)]),role:"status"},[C("div",gOe,[U(f(ve),{name:o(y),size:"sm",class:"ntn-ico","aria-hidden":"true"},null,8,["name"]),C("span",mOe,D(u(y)),1)]),C("div",vOe,[y.title?(v(),E("div",yOe,D(y.title),1)):X("",!0),y.body?(v(),E("div",kOe,D(y.body),1)):X("",!0),y.outputFile?(v(),E("div",bOe,[U(f(ve),{class:"ntn-out-ic",name:"file-text",size:"sm","aria-hidden":"true"}),C("span",{class:"ntn-out-path",title:y.outputFile.path},D(y.outputFile.path),9,AOe),y.outputFile.bytes!==void 0?(v(),E("span",COe,D(c(y.outputFile.bytes)),1)):X("",!0),C("button",{class:"ntn-out-copy",type:"button",onClick:A=>m(y.outputFile.path,i(y,b))},D(p.value===i(y,b)?f(t)("conversation.notification.copied"):f(t)("conversation.notification.copyPath")),9,wOe)])):X("",!0),h(y)?(v(),E("div",xOe,[d(y)!==""?(v(),E("div",SOe,D(d(y)),1)):X("",!0),y.outputPreview?.text?(v(),E("pre",_Oe,D(y.outputPreview.text),1)):X("",!0)])):X("",!0),C("details",MOe,[C("summary",null,[U(f(ve),{class:"ntn-raw-car",name:"chevron-right",size:"sm","aria-hidden":"true"}),C("span",null,D(f(t)("conversation.notification.rawPayload")),1)]),C("div",IOe,[C("div",EOe,[C("span",TOe,D(f(t)("conversation.notification.fields.type")),1),C("span",LOe,D(y.type),1),C("span",NOe,D(f(t)("conversation.notification.fields.source")),1),C("span",FOe,D(y.sourceKind)+" · "+D(y.sourceId),1),C("span",DOe,D(f(t)("conversation.notification.fields.severity")),1),C("span",BOe,D(y.severity||"—"),1)]),C("pre",$Oe,D(y.raw),1)])])]),C("div",ROe,[y.createdAt?(v(),ce(_A,{key:0,time:y.createdAt},null,8,["time"])):X("",!0)])],2))),128))]))}}),aH=kt(zOe,[["__scopeId","data-v-010c7307"]]),OOe=["aria-expanded"],POe=["title"],jOe=["inert"],HOe={class:"tf-body-inner"},WOe={key:1,class:"msg"},qOe=Xe({__name:"TurnFold",props:{items:{},mobile:{type:Boolean,default:!1},streamingTailIndex:{default:null},live:{type:Boolean,default:!1},parked:{type:Boolean,default:!1},seedMs:{default:void 0},createdMs:{default:void 0},endedMs:{default:void 0},durationMs:{default:void 0}},emits:["openMedia","openFile","openAgent"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.streamingTailIndex!==null),r=F(()=>n.live?n.parked?"parked":"live":"settled"),l=K(!1),a=F(()=>s.value||l.value),u=K(a.value),c=K(a.value);let d=null;Pe(a,x=>{if(x){if(d!==null&&(clearTimeout(d),d=null),u.value){c.value=!0;return}u.value=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{c.value=!0})});return}c.value=!1,d=setTimeout(()=>{d=null,u.value=!1},200)});const h=hn("pinScroll",()=>{}),p=K(null),g=K(Date.now());let m=null;function k(){m!==null&&(clearInterval(m),m=null)}_n(()=>{k(),d!==null&&clearTimeout(d)}),Pe(r,(x,_)=>{x!=="settled"?(g.value=Date.now(),m===null&&(m=setInterval(()=>{g.value=Date.now()},1e3))):k(),_==="live"&&x!=="live"&&(l.value=!1)},{immediate:!0});const w=F(()=>n.seedMs===void 0?n.createdMs:n.createdMs===void 0?n.seedMs:Math.min(n.seedMs,n.createdMs)),y=F(()=>qze({startMs:w.value,endedMs:n.endedMs,durationMs:n.durationMs,state:r.value==="settled"?{phase:"settled"}:{phase:"live",nowMs:g.value}}));function b(){l.value=!l.value,dt(()=>{const x=p.value;x&&h(x)})}const A=F(()=>{const x=y.value===void 0?"":Wa(y.value);return x?o("conversation.fold.worked",{duration:x}):o("conversation.fold.workedUnknown")});function T(x){return n.streamingTailIndex===null||x.kind==="thinking"&&x.durationMs!==void 0?!1:x.sourceIndex===n.streamingTailIndex}function S(x){if(n.streamingTailIndex===null)return!1;const _=x.items.at(-1);return _?.kind==="thinking"&&_.durationMs!==void 0?!1:_!==void 0&&_.sourceIndex===n.streamingTailIndex}return(x,_)=>e.items.length>0?(v(),E("div",{key:0,class:Fe(["turn-fold",{open:a.value,streaming:s.value}])},[s.value?X("",!0):(v(),E("button",{key:0,ref_key:"headEl",ref:p,class:"tf-head",type:"button","aria-expanded":l.value,onClick:b},[C("span",{class:"tf-sum",title:A.value},D(A.value),9,POe),U(f(ve),{class:"tf-car",name:"chevron-right",size:"sm","aria-hidden":"true"})],8,OOe)),u.value?(v(),E("div",{key:1,class:Fe(["tf-body",{open:c.value}]),inert:!a.value},[C("div",HOe,[(v(!0),E(Ee,null,pt(e.items,(L,M)=>(v(),E(Ee,{key:f(sH)(L,M)},[L.kind==="thinking"?(v(),ce(SA,{key:0,text:L.thinking,mobile:e.mobile,streaming:T(L),"started-at":L.startedAt,"duration-ms":L.durationMs},null,8,["text","mobile","streaming","started-at","duration-ms"])):L.kind==="text"&&L.text?(v(),E("div",WOe,[U(f(Iu),{text:L.text,streaming:T(L),"open-file":N=>i("openFile",N)},null,8,["text","streaming","open-file"])])):L.kind==="activity-run"?(v(),ce(lH,{key:2,items:L.items,mobile:e.mobile,streaming:S(L),onOpenMedia:_[0]||(_[0]=N=>i("openMedia",N)),onOpenFile:_[1]||(_[1]=N=>i("openFile",N)),onOpenAgent:_[2]||(_[2]=N=>i("openAgent",N))},null,8,["items","mobile","streaming"])):L.kind==="tool"?(v(),ce(xA,{key:3,tool:L.tool,mobile:e.mobile,onOpenMedia:_[3]||(_[3]=N=>i("openMedia",N)),onOpenFile:_[4]||(_[4]=N=>i("openFile",N)),onOpenAgent:_[5]||(_[5]=N=>i("openAgent",N))},null,8,["tool","mobile"])):L.kind==="notification"?(v(),ce(aH,{key:4,items:L.items},null,8,["items"])):X("",!0)],64))),128))])],10,jOe)):X("",!0)],2)):X("",!0)}}),UOe=kt(qOe,[["__scopeId","data-v-ce1eb651"]]),KOe={class:"turn-files"},VOe={class:"tf-ic","aria-hidden":"true"},ZOe={class:"tf-title"},GOe={key:0,class:"tf-stats"},QOe={key:0,class:"tf-add"},YOe={key:1,class:"tf-del"},JOe={class:"diffbar","aria-hidden":"true"},XOe={class:"tf-list"},ePe={key:0,class:"tf-dir"},tPe={class:"tf-base"},nPe={key:0,class:"tf-stats"},iPe={key:0,class:"tf-add"},oPe={key:1,class:"tf-del"},Ok=3,sPe=Xe({__name:"TurnFilesSummary",props:{changes:{},cwd:{},interactive:{type:Boolean,default:!0}},emits:["openDiff","openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.interactive!==!1),r=F(()=>{const A=n.changes.length;return o(A===1?"conversation.turnFiles.titleOne":"conversation.turnFiles.titleOther",{number:A})}),l=F(()=>n.changes.some(A=>A.statsIncomplete)),a=F(()=>{let A=0,T=0;for(const S of n.changes)A+=S.added,T+=S.removed;return{added:A,removed:T}}),u=F(()=>!l.value&&(a.value.added>0||a.value.removed>0)),c=K(!1),d=F(()=>c.value?n.changes:n.changes.slice(0,Ok)),h=F(()=>Math.max(0,n.changes.length-Ok)),p=F(()=>n.changes.length>Ok),g=F(()=>c.value?o("conversation.turnFiles.showLess"):h.value===1?o("conversation.turnFiles.moreOne"):o("conversation.turnFiles.more",{number:h.value}));function m(A){const T=n.cwd?d9(A,n.cwd):null;return T!==null?T||Tu(A):A}function k(A){const T=m(A),S=Math.max(T.lastIndexOf("/"),T.lastIndexOf("\\"));return S>0?T.slice(0,S+1):""}function w(A){const T=m(A),S=Math.max(T.lastIndexOf("/"),T.lastIndexOf("\\"));return S>=0?T.slice(S+1):T}function y(A){return A.statsIncomplete||A.added===0&&A.removed===0?null:{added:A.added,removed:A.removed}}function b(A){A.hasWrite?i("openFile",{path:A.path}):i("openDiff",A)}return(A,T)=>(v(),E("div",KOe,[U(f(xQ),null,TN({head:de(()=>[C("span",VOe,[U(f(ve),{name:"pencil",size:"sm"})]),C("span",ZOe,D(r.value),1),u.value?(v(),E("span",GOe,[a.value.added>0?(v(),E("span",QOe,"+"+D(a.value.added),1)):X("",!0),a.value.removed>0?(v(),E("span",YOe,"−"+D(a.value.removed),1)):X("",!0),C("span",JOe,[C("span",{class:"seg-add",style:Kt({flexGrow:a.value.added})},null,4),C("span",{class:"seg-del",style:Kt({flexGrow:a.value.removed})},null,4)])])):X("",!0)]),default:de(()=>[C("ul",XOe,[(v(!0),E(Ee,null,pt(d.value,S=>(v(),E("li",{key:S.path,class:"tf-row"},[(v(),ce(Oo(s.value?"button":"span"),{class:"tf-file",type:s.value?"button":void 0,onClick:x=>s.value&&b(S)},{default:de(()=>[k(S.path)?(v(),E("span",ePe,D(k(S.path)),1)):X("",!0),C("span",tPe,D(w(S.path)),1)]),_:2},1032,["type","onClick"])),y(S)?(v(),E("span",nPe,[y(S).added>0?(v(),E("span",iPe,"+"+D(y(S).added),1)):X("",!0),y(S).removed>0?(v(),E("span",oPe,"−"+D(y(S).removed),1)):X("",!0)])):X("",!0)]))),128))])]),_:2},[p.value?{name:"foot",fn:de(()=>[U(f(Qt),{variant:"ghost",size:"sm",class:"tf-more","aria-expanded":c.value,onClick:T[0]||(T[0]=S=>c.value=!c.value)},{default:de(()=>[$e(D(g.value)+" ",1),U(f(ve),{class:Fe(["tf-more-car",{open:c.value}]),name:"chevron-down",size:"sm","aria-hidden":"true"},null,8,["class"])]),_:1},8,["aria-expanded"])]),key:"0"}:void 0]),1024)]))}}),rPe=kt(sPe,[["__scopeId","data-v-f37da416"]]),lPe={class:"activity-notice",role:"status"},aPe={"aria-hidden":"true"},uPe={class:"an-label"},cPe=Xe({__name:"ActivityNotice",props:{label:{}},setup(e){return(t,n)=>(v(),E("div",lPe,[C("span",aPe,[U(f(Oi),{size:"sm"})]),C("span",uPe,D(e.label),1)]))}}),dPe=kt(cPe,[["__scopeId","data-v-cc29061f"]]),fPe=["data-turn-id"],hPe=["title"],pPe={class:"cn-head-text"},gPe={key:0,class:"cn-bubble"},mPe={class:"cn-prompt"},vPe={key:1,class:"cn-meta"},yPe=Xe({__name:"CronNotice",props:{text:{},cron:{},turnId:{},createdAt:{}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.cron),o=F(()=>i.value?.missedCount!==void 0),s=F(()=>o.value?n("conversation.cron.missed"):n("conversation.cron.fired")),r=F(()=>{const h=i.value;return!h?.cron||h.recurring===!1?"":h.cron}),l=F(()=>o.value?"error":"ok"),a=F(()=>{const h=i.value;if(!h)return"";const p=[];return h.recurring===!1&&p.push(n("conversation.cron.oneShot")),typeof h.coalescedCount=="number"&&h.coalescedCount>1&&p.push(n("conversation.cron.coalesced",{n:h.coalescedCount})),h.missedCount!==void 0&&p.push(n("conversation.cron.missedCount",{n:h.missedCount})),h.stale===!0&&p.push(n("conversation.cron.finalDelivery")),p.join(" · ")}),u=F(()=>{const h=[s.value];return r.value&&h.push(r.value),a.value&&h.push(a.value),h.join(" · ")}),c=F(()=>{const h=i.value?.jobId;return h?n("conversation.cron.job",{id:h}):void 0}),d=F(()=>t.text??"");return(h,p)=>(v(),E("div",{class:Fe(["cn cron-notice",{"turn-anchor":!!e.turnId}]),"data-turn-id":e.turnId,role:"status"},[C("div",{class:Fe(["cn-head",l.value]),title:c.value},[U(f(ve),{name:"clock",size:"sm",class:"cn-head-ico","aria-hidden":"true"}),C("span",pPe,D(u.value),1)],10,hPe),d.value?(v(),E("div",gPe,[C("span",mPe,D(d.value),1)])):X("",!0),e.createdAt?(v(),E("div",vPe,[U(_A,{time:e.createdAt},null,8,["time"])])):X("",!0)],10,fPe))}}),kPe=kt(yPe,[["__scopeId","data-v-9f79345d"]]);let j9=!1,H9=0,fL=!1;const bPe=100;function APe(){j9=!0,H9=0}function CPe(){j9=!1,H9=Date.now()}function hL(){j9=!1,H9=0}function uH(){fL||typeof document>"u"||(fL=!0,document.addEventListener("compositionstart",APe,!0),document.addEventListener("compositionend",CPe,!0),document.addEventListener("focusin",hL,!0),document.addEventListener("focusout",hL,!0))}function cH(e){return j9||e.isComposing||e.keyCode===229||Date.now()-H9<bPe}const wPe=/^(application\/pdf|image\/(png|jpe?g|gif|webp|avif|bmp|x-icon|vnd\.microsoft\.icon)|video\/[\w.+-]+|audio\/[\w.+-]+)$/i,xPe=/^(txt|md|markdown|log|json|ya?ml|csv|tsv|ts|mts|tsx|jsx|css|py|go|rs|java|c|h|cc|cpp|hpp|sh|zsh|sql|toml|ini|cfg|conf|vue)$/i,SPe=/^(png|jpe?g|gif|webp|avif|bmp|ico)$/i,pL="text/plain;charset=utf-8";function _Pe(e,t){const n=(t??"").toLowerCase();if(wPe.test(n))return n;if(n.startsWith("text/"))return n==="text/html"?null:pL;const i=e?.match(/\.([A-Za-z0-9]{1,8})$/)?.[1]?.toLowerCase();return i===void 0?null:xPe.test(i)?pL:SPe.test(i)?`image/${i==="jpg"?"jpeg":i==="ico"?"x-icon":i}`:i==="pdf"?"application/pdf":null}async function dH(e,t,n,i){const o=_Pe(n,i);if(o===null)return"unsupported";const s=window.open("","_blank");s!==null&&(s.opener=null);const r=await e.getFileBlob(t).catch(()=>null);if(r===null)return s?.close(),"failed";const l=URL.createObjectURL(new Blob([r],{type:o}));if(s!==null)s.location.href=l;else{const a=document.createElement("a");a.href=l,a.download=n??t,a.click()}return setTimeout(()=>{URL.revokeObjectURL(l)},6e4),"previewed"}/*! - * PhotoSwipe 5.4.4 - https://photoswipe.com - * (c) 2024 Dmytro Semenov - */function al(e,t,n){const i=document.createElement(t);return e&&(i.className=e),n&&n.appendChild(i),i}function Qo(e,t){return e.x=t.x,e.y=t.y,t.id!==void 0&&(e.id=t.id),e}function fH(e){e.x=Math.round(e.x),e.y=Math.round(e.y)}function _5(e,t){const n=Math.abs(e.x-t.x),i=Math.abs(e.y-t.y);return Math.sqrt(n*n+i*i)}function c0(e,t){return e.x===t.x&&e.y===t.y}function Eg(e,t,n){return Math.min(Math.max(e,t),n)}function G0(e,t,n){let i=`translate3d(${e}px,${t||0}px,0)`;return n!==void 0&&(i+=` scale3d(${n},${n},1)`),i}function Wd(e,t,n,i){e.style.transform=G0(t,n,i)}const MPe="cubic-bezier(.4,0,.22,1)";function hH(e,t,n,i){e.style.transition=t?`${t} ${n}ms ${i||MPe}`:"none"}function M5(e,t,n){e.style.width=typeof t=="number"?`${t}px`:t,e.style.height=typeof n=="number"?`${n}px`:n}function IPe(e){hH(e)}function EPe(e){return"decode"in e?e.decode().catch(()=>{}):e.complete?Promise.resolve(e):new Promise((t,n)=>{e.onload=()=>t(e),e.onerror=n})}const _l={IDLE:"idle",LOADING:"loading",LOADED:"loaded",ERROR:"error"};function TPe(e){return"button"in e&&e.button===1||e.ctrlKey||e.metaKey||e.altKey||e.shiftKey}function LPe(e,t,n=document){let i=[];if(e instanceof Element)i=[e];else if(e instanceof NodeList||Array.isArray(e))i=Array.from(e);else{const o=typeof e=="string"?e:t;o&&(i=Array.from(n.querySelectorAll(o)))}return i}function gL(){return!!(navigator.vendor&&navigator.vendor.match(/apple/i))}let pH=!1;try{window.addEventListener("test",null,Object.defineProperty({},"passive",{get:()=>{pH=!0}}))}catch{}class NPe{constructor(){this._pool=[]}add(t,n,i,o){this._toggleListener(t,n,i,o)}remove(t,n,i,o){this._toggleListener(t,n,i,o,!0)}removeAll(){this._pool.forEach(t=>{this._toggleListener(t.target,t.type,t.listener,t.passive,!0,!0)}),this._pool=[]}_toggleListener(t,n,i,o,s,r){if(!t)return;const l=s?"removeEventListener":"addEventListener";n.split(" ").forEach(u=>{if(u){r||(s?this._pool=this._pool.filter(d=>d.type!==u||d.listener!==i||d.target!==t):this._pool.push({target:t,type:u,listener:i,passive:o}));const c=pH?{passive:o||!1}:!1;t[l](u,i,c)}})}}function gH(e,t){if(e.getViewportSizeFn){const n=e.getViewportSizeFn(e,t);if(n)return n}return{x:document.documentElement.clientWidth,y:window.innerHeight}}function Tp(e,t,n,i,o){let s=0;if(t.paddingFn)s=t.paddingFn(n,i,o)[e];else if(t.padding)s=t.padding[e];else{const r="padding"+e[0].toUpperCase()+e.slice(1);t[r]&&(s=t[r])}return Number(s)||0}function mH(e,t,n,i){return{x:t.x-Tp("left",e,t,n,i)-Tp("right",e,t,n,i),y:t.y-Tp("top",e,t,n,i)-Tp("bottom",e,t,n,i)}}class FPe{constructor(t){this.slide=t,this.currZoomLevel=1,this.center={x:0,y:0},this.max={x:0,y:0},this.min={x:0,y:0}}update(t){this.currZoomLevel=t,this.slide.width?(this._updateAxis("x"),this._updateAxis("y"),this.slide.pswp.dispatch("calcBounds",{slide:this.slide})):this.reset()}_updateAxis(t){const{pswp:n}=this.slide,i=this.slide[t==="x"?"width":"height"]*this.currZoomLevel,s=Tp(t==="x"?"left":"top",n.options,n.viewportSize,this.slide.data,this.slide.index),r=this.slide.panAreaSize[t];this.center[t]=Math.round((r-i)/2)+s,this.max[t]=i>r?Math.round(r-i)+s:this.center[t],this.min[t]=i>r?s:this.center[t]}reset(){this.center.x=0,this.center.y=0,this.max.x=0,this.max.y=0,this.min.x=0,this.min.y=0}correctPan(t,n){return Eg(n,this.max[t],this.min[t])}}const mL=4e3;class vH{constructor(t,n,i,o){this.pswp=o,this.options=t,this.itemData=n,this.index=i,this.panAreaSize=null,this.elementSize=null,this.fit=1,this.fill=1,this.vFill=1,this.initial=1,this.secondary=1,this.max=1,this.min=1}update(t,n,i){const o={x:t,y:n};this.elementSize=o,this.panAreaSize=i;const s=i.x/o.x,r=i.y/o.y;this.fit=Math.min(1,s<r?s:r),this.fill=Math.min(1,s>r?s:r),this.vFill=Math.min(1,r),this.initial=this._getInitial(),this.secondary=this._getSecondary(),this.max=Math.max(this.initial,this.secondary,this._getMax()),this.min=Math.min(this.fit,this.initial,this.secondary),this.pswp&&this.pswp.dispatch("zoomLevelsUpdate",{zoomLevels:this,slideData:this.itemData})}_parseZoomLevelOption(t){const n=t+"ZoomLevel",i=this.options[n];if(i)return typeof i=="function"?i(this):i==="fill"?this.fill:i==="fit"?this.fit:Number(i)}_getSecondary(){let t=this._parseZoomLevelOption("secondary");return t||(t=Math.min(1,this.fit*3),this.elementSize&&t*this.elementSize.x>mL&&(t=mL/this.elementSize.x),t)}_getInitial(){return this._parseZoomLevelOption("initial")||this.fit}_getMax(){return this._parseZoomLevelOption("max")||Math.max(1,this.fit*4)}}class DPe{constructor(t,n,i){this.data=t,this.index=n,this.pswp=i,this.isActive=n===i.currIndex,this.currentResolution=0,this.panAreaSize={x:0,y:0},this.pan={x:0,y:0},this.isFirstSlide=this.isActive&&!i.opener.isOpen,this.zoomLevels=new vH(i.options,t,n,i),this.pswp.dispatch("gettingData",{slide:this,data:this.data,index:n}),this.content=this.pswp.contentLoader.getContentBySlide(this),this.container=al("pswp__zoom-wrap","div"),this.holderElement=null,this.currZoomLevel=1,this.width=this.content.width,this.height=this.content.height,this.heavyAppended=!1,this.bounds=new FPe(this),this.prevDisplayedWidth=-1,this.prevDisplayedHeight=-1,this.pswp.dispatch("slideInit",{slide:this})}setIsActive(t){t&&!this.isActive?this.activate():!t&&this.isActive&&this.deactivate()}append(t){this.holderElement=t,this.container.style.transformOrigin="0 0",this.data&&(this.calculateSize(),this.load(),this.updateContentSize(),this.appendHeavy(),this.holderElement.appendChild(this.container),this.zoomAndPanToInitial(),this.pswp.dispatch("firstZoomPan",{slide:this}),this.applyCurrentZoomPan(),this.pswp.dispatch("afterSetContent",{slide:this}),this.isActive&&this.activate())}load(){this.content.load(!1),this.pswp.dispatch("slideLoad",{slide:this})}appendHeavy(){const{pswp:t}=this;this.heavyAppended||!t.opener.isOpen||t.mainScroll.isShifted()||!this.isActive&&!1||this.pswp.dispatch("appendHeavy",{slide:this}).defaultPrevented||(this.heavyAppended=!0,this.content.append(),this.pswp.dispatch("appendHeavyContent",{slide:this}))}activate(){this.isActive=!0,this.appendHeavy(),this.content.activate(),this.pswp.dispatch("slideActivate",{slide:this})}deactivate(){this.isActive=!1,this.content.deactivate(),this.currZoomLevel!==this.zoomLevels.initial&&this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize(),this.pswp.dispatch("slideDeactivate",{slide:this})}destroy(){this.content.hasSlide=!1,this.content.remove(),this.container.remove(),this.pswp.dispatch("slideDestroy",{slide:this})}resize(){this.currZoomLevel===this.zoomLevels.initial||!this.isActive?(this.calculateSize(),this.currentResolution=0,this.zoomAndPanToInitial(),this.applyCurrentZoomPan(),this.updateContentSize()):(this.calculateSize(),this.bounds.update(this.currZoomLevel),this.panTo(this.pan.x,this.pan.y))}updateContentSize(t){const n=this.currentResolution||this.zoomLevels.initial;if(!n)return;const i=Math.round(this.width*n)||this.pswp.viewportSize.x,o=Math.round(this.height*n)||this.pswp.viewportSize.y;!this.sizeChanged(i,o)&&!t||this.content.setDisplayedSize(i,o)}sizeChanged(t,n){return t!==this.prevDisplayedWidth||n!==this.prevDisplayedHeight?(this.prevDisplayedWidth=t,this.prevDisplayedHeight=n,!0):!1}getPlaceholderElement(){var t;return(t=this.content.placeholder)===null||t===void 0?void 0:t.element}zoomTo(t,n,i,o){const{pswp:s}=this;if(!this.isZoomable()||s.mainScroll.isShifted())return;s.dispatch("beforeZoomTo",{destZoomLevel:t,centerPoint:n,transitionDuration:i}),s.animations.stopAllPan();const r=this.currZoomLevel;o||(t=Eg(t,this.zoomLevels.min,this.zoomLevels.max)),this.setZoomLevel(t),this.pan.x=this.calculateZoomToPanOffset("x",n,r),this.pan.y=this.calculateZoomToPanOffset("y",n,r),fH(this.pan);const l=()=>{this._setResolution(t),this.applyCurrentZoomPan()};i?s.animations.startTransition({isPan:!0,name:"zoomTo",target:this.container,transform:this.getCurrentTransform(),onComplete:l,duration:i,easing:s.options.easing}):l()}toggleZoom(t){this.zoomTo(this.currZoomLevel===this.zoomLevels.initial?this.zoomLevels.secondary:this.zoomLevels.initial,t,this.pswp.options.zoomAnimationDuration)}setZoomLevel(t){this.currZoomLevel=t,this.bounds.update(this.currZoomLevel)}calculateZoomToPanOffset(t,n,i){if(this.bounds.max[t]-this.bounds.min[t]===0)return this.bounds.center[t];n||(n=this.pswp.getViewportCenterPoint()),i||(i=this.zoomLevels.initial);const s=this.currZoomLevel/i;return this.bounds.correctPan(t,(this.pan[t]-n[t])*s+n[t])}panTo(t,n){this.pan.x=this.bounds.correctPan("x",t),this.pan.y=this.bounds.correctPan("y",n),this.applyCurrentZoomPan()}isPannable(){return!!this.width&&this.currZoomLevel>this.zoomLevels.fit}isZoomable(){return!!this.width&&this.content.isZoomable()}applyCurrentZoomPan(){this._applyZoomTransform(this.pan.x,this.pan.y,this.currZoomLevel),this===this.pswp.currSlide&&this.pswp.dispatch("zoomPanUpdate",{slide:this})}zoomAndPanToInitial(){this.currZoomLevel=this.zoomLevels.initial,this.bounds.update(this.currZoomLevel),Qo(this.pan,this.bounds.center),this.pswp.dispatch("initialZoomPan",{slide:this})}_applyZoomTransform(t,n,i){i/=this.currentResolution||this.zoomLevels.initial,Wd(this.container,t,n,i)}calculateSize(){const{pswp:t}=this;Qo(this.panAreaSize,mH(t.options,t.viewportSize,this.data,this.index)),this.zoomLevels.update(this.width,this.height,this.panAreaSize),t.dispatch("calcSlideSize",{slide:this})}getCurrentTransform(){const t=this.currZoomLevel/(this.currentResolution||this.zoomLevels.initial);return G0(this.pan.x,this.pan.y,t)}_setResolution(t){t!==this.currentResolution&&(this.currentResolution=t,this.updateContentSize(),this.pswp.dispatch("resolutionChanged"))}}const BPe=.35,$Pe=.6,vL=.4,yL=.5;function RPe(e,t){return e*t/(1-t)}class zPe{constructor(t){this.gestures=t,this.pswp=t.pswp,this.startPan={x:0,y:0}}start(){this.pswp.currSlide&&Qo(this.startPan,this.pswp.currSlide.pan),this.pswp.animations.stopAll()}change(){const{p1:t,prevP1:n,dragAxis:i}=this.gestures,{currSlide:o}=this.pswp;if(i==="y"&&this.pswp.options.closeOnVerticalDrag&&o&&o.currZoomLevel<=o.zoomLevels.fit&&!this.gestures.isMultitouch){const s=o.pan.y+(t.y-n.y);if(!this.pswp.dispatch("verticalDrag",{panY:s}).defaultPrevented){this._setPanWithFriction("y",s,$Pe);const r=1-Math.abs(this._getVerticalDragRatio(o.pan.y));this.pswp.applyBgOpacity(r),o.applyCurrentZoomPan()}}else this._panOrMoveMainScroll("x")||(this._panOrMoveMainScroll("y"),o&&(fH(o.pan),o.applyCurrentZoomPan()))}end(){const{velocity:t}=this.gestures,{mainScroll:n,currSlide:i}=this.pswp;let o=0;if(this.pswp.animations.stopAll(),n.isShifted()){const r=(n.x-n.getCurrSlideX())/this.pswp.viewportSize.x;t.x<-yL&&r<0||t.x<.1&&r<-.5?(o=1,t.x=Math.min(t.x,0)):(t.x>yL&&r>0||t.x>-.1&&r>.5)&&(o=-1,t.x=Math.max(t.x,0)),n.moveIndexBy(o,!0,t.x)}i&&i.currZoomLevel>i.zoomLevels.max||this.gestures.isMultitouch?this.gestures.zoomLevels.correctZoomPan(!0):(this._finishPanGestureForAxis("x"),this._finishPanGestureForAxis("y"))}_finishPanGestureForAxis(t){const{velocity:n}=this.gestures,{currSlide:i}=this.pswp;if(!i)return;const{pan:o,bounds:s}=i,r=o[t],l=this.pswp.bgOpacity<1&&t==="y",u=r+RPe(n[t],.995);if(l){const g=this._getVerticalDragRatio(r),m=this._getVerticalDragRatio(u);if(g<0&&m<-vL||g>0&&m>vL){this.pswp.close();return}}const c=s.correctPan(t,u);if(r===c)return;const d=c===u?1:.82,h=this.pswp.bgOpacity,p=c-r;this.pswp.animations.startSpring({name:"panGesture"+t,isPan:!0,start:r,end:c,velocity:n[t],dampingRatio:d,onUpdate:g=>{if(l&&this.pswp.bgOpacity<1){const m=1-(c-g)/p;this.pswp.applyBgOpacity(Eg(h+(1-h)*m,0,1))}o[t]=Math.floor(g),i.applyCurrentZoomPan()}})}_panOrMoveMainScroll(t){const{p1:n,dragAxis:i,prevP1:o,isMultitouch:s}=this.gestures,{currSlide:r,mainScroll:l}=this.pswp,a=n[t]-o[t],u=l.x+a;if(!a||!r)return!1;if(t==="x"&&!r.isPannable()&&!s)return l.moveTo(u,!0),!0;const{bounds:c}=r,d=r.pan[t]+a;if(this.pswp.options.allowPanToNext&&i==="x"&&t==="x"&&!s){const h=l.getCurrSlideX(),p=l.x-h,g=a>0,m=!g;if(d>c.min[t]&&g){if(c.min[t]<=this.startPan[t])return l.moveTo(u,!0),!0;this._setPanWithFriction(t,d)}else if(d<c.max[t]&&m){if(this.startPan[t]<=c.max[t])return l.moveTo(u,!0),!0;this._setPanWithFriction(t,d)}else if(p!==0){if(p>0)return l.moveTo(Math.max(u,h),!0),!0;if(p<0)return l.moveTo(Math.min(u,h),!0),!0}else this._setPanWithFriction(t,d)}else t==="y"?!l.isShifted()&&c.min.y!==c.max.y&&this._setPanWithFriction(t,d):this._setPanWithFriction(t,d);return!1}_getVerticalDragRatio(t){var n,i;return(t-((n=(i=this.pswp.currSlide)===null||i===void 0?void 0:i.bounds.center.y)!==null&&n!==void 0?n:0))/(this.pswp.viewportSize.y/3)}_setPanWithFriction(t,n,i){const{currSlide:o}=this.pswp;if(!o)return;const{pan:s,bounds:r}=o;if(r.correctPan(t,n)!==n||i){const a=Math.round(n-s[t]);s[t]+=a*(i||BPe)}else s[t]=n}}const OPe=.05,PPe=.15;function kL(e,t,n){return e.x=(t.x+n.x)/2,e.y=(t.y+n.y)/2,e}class jPe{constructor(t){this.gestures=t,this._startPan={x:0,y:0},this._startZoomPoint={x:0,y:0},this._zoomPoint={x:0,y:0},this._wasOverFitZoomLevel=!1,this._startZoomLevel=1}start(){const{currSlide:t}=this.gestures.pswp;t&&(this._startZoomLevel=t.currZoomLevel,Qo(this._startPan,t.pan)),this.gestures.pswp.animations.stopAllPan(),this._wasOverFitZoomLevel=!1}change(){const{p1:t,startP1:n,p2:i,startP2:o,pswp:s}=this.gestures,{currSlide:r}=s;if(!r)return;const l=r.zoomLevels.min,a=r.zoomLevels.max;if(!r.isZoomable()||s.mainScroll.isShifted())return;kL(this._startZoomPoint,n,o),kL(this._zoomPoint,t,i);let u=1/_5(n,o)*_5(t,i)*this._startZoomLevel;if(u>r.zoomLevels.initial+r.zoomLevels.initial/15&&(this._wasOverFitZoomLevel=!0),u<l)if(s.options.pinchToClose&&!this._wasOverFitZoomLevel&&this._startZoomLevel<=r.zoomLevels.initial){const c=1-(l-u)/(l/1.2);s.dispatch("pinchClose",{bgOpacity:c}).defaultPrevented||s.applyBgOpacity(c)}else u=l-(l-u)*PPe;else u>a&&(u=a+(u-a)*OPe);r.pan.x=this._calculatePanForZoomLevel("x",u),r.pan.y=this._calculatePanForZoomLevel("y",u),r.setZoomLevel(u),r.applyCurrentZoomPan()}end(){const{pswp:t}=this.gestures,{currSlide:n}=t;(!n||n.currZoomLevel<n.zoomLevels.initial)&&!this._wasOverFitZoomLevel&&t.options.pinchToClose?t.close():this.correctZoomPan()}_calculatePanForZoomLevel(t,n){const i=n/this._startZoomLevel;return this._zoomPoint[t]-(this._startZoomPoint[t]-this._startPan[t])*i}correctZoomPan(t){const{pswp:n}=this.gestures,{currSlide:i}=n;if(!(i!=null&&i.isZoomable()))return;this._zoomPoint.x===0&&(t=!0);const o=i.currZoomLevel;let s,r=!0;o<i.zoomLevels.initial?s=i.zoomLevels.initial:o>i.zoomLevels.max?s=i.zoomLevels.max:(r=!1,s=o);const l=n.bgOpacity,a=n.bgOpacity<1,u=Qo({x:0,y:0},i.pan);let c=Qo({x:0,y:0},u);t&&(this._zoomPoint.x=0,this._zoomPoint.y=0,this._startZoomPoint.x=0,this._startZoomPoint.y=0,this._startZoomLevel=o,Qo(this._startPan,u)),r&&(c={x:this._calculatePanForZoomLevel("x",s),y:this._calculatePanForZoomLevel("y",s)}),i.setZoomLevel(s),c={x:i.bounds.correctPan("x",c.x),y:i.bounds.correctPan("y",c.y)},i.setZoomLevel(o);const d=!c0(c,u);if(!d&&!r&&!a){i._setResolution(s),i.applyCurrentZoomPan();return}n.animations.stopAllPan(),n.animations.startSpring({isPan:!0,start:0,end:1e3,velocity:0,dampingRatio:1,naturalFrequency:40,onUpdate:h=>{if(h/=1e3,d||r){if(d&&(i.pan.x=u.x+(c.x-u.x)*h,i.pan.y=u.y+(c.y-u.y)*h),r){const p=o+(s-o)*h;i.setZoomLevel(p)}i.applyCurrentZoomPan()}a&&n.bgOpacity<1&&n.applyBgOpacity(Eg(l+(1-l)*h,0,1))},onComplete:()=>{i._setResolution(s),i.applyCurrentZoomPan()}})}}function bL(e){return!!e.target.closest(".pswp__container")}class HPe{constructor(t){this.gestures=t}click(t,n){const i=n.target.classList,o=i.contains("pswp__img"),s=i.contains("pswp__item")||i.contains("pswp__zoom-wrap");o?this._doClickOrTapAction("imageClick",t,n):s&&this._doClickOrTapAction("bgClick",t,n)}tap(t,n){bL(n)&&this._doClickOrTapAction("tap",t,n)}doubleTap(t,n){bL(n)&&this._doClickOrTapAction("doubleTap",t,n)}_doClickOrTapAction(t,n,i){var o;const{pswp:s}=this.gestures,{currSlide:r}=s,l=t+"Action",a=s.options[l];if(!s.dispatch(l,{point:n,originalEvent:i}).defaultPrevented){if(typeof a=="function"){a.call(s,n,i);return}switch(a){case"close":case"next":s[a]();break;case"zoom":r?.toggleZoom(n);break;case"zoom-or-close":r!=null&&r.isZoomable()&&r.zoomLevels.secondary!==r.zoomLevels.initial?r.toggleZoom(n):s.options.clickToCloseNonZoomable&&s.close();break;case"toggle-controls":(o=this.gestures.pswp.element)===null||o===void 0||o.classList.toggle("pswp--ui-visible");break}}}}const WPe=10,qPe=300,UPe=25;class KPe{constructor(t){this.pswp=t,this.dragAxis=null,this.p1={x:0,y:0},this.p2={x:0,y:0},this.prevP1={x:0,y:0},this.prevP2={x:0,y:0},this.startP1={x:0,y:0},this.startP2={x:0,y:0},this.velocity={x:0,y:0},this._lastStartP1={x:0,y:0},this._intervalP1={x:0,y:0},this._numActivePoints=0,this._ongoingPointers=[],this._touchEventEnabled="ontouchstart"in window,this._pointerEventEnabled=!!window.PointerEvent,this.supportsTouch=this._touchEventEnabled||this._pointerEventEnabled&&navigator.maxTouchPoints>1,this._numActivePoints=0,this._intervalTime=0,this._velocityCalculated=!1,this.isMultitouch=!1,this.isDragging=!1,this.isZooming=!1,this.raf=null,this._tapTimer=null,this.supportsTouch||(t.options.allowPanToNext=!1),this.drag=new zPe(this),this.zoomLevels=new jPe(this),this.tapHandler=new HPe(this),t.on("bindEvents",()=>{t.events.add(t.scrollWrap,"click",this._onClick.bind(this)),this._pointerEventEnabled?this._bindEvents("pointer","down","up","cancel"):this._touchEventEnabled?(this._bindEvents("touch","start","end","cancel"),t.scrollWrap&&(t.scrollWrap.ontouchmove=()=>{},t.scrollWrap.ontouchend=()=>{})):this._bindEvents("mouse","down","up")})}_bindEvents(t,n,i,o){const{pswp:s}=this,{events:r}=s,l=o?t+o:"";r.add(s.scrollWrap,t+n,this.onPointerDown.bind(this)),r.add(window,t+"move",this.onPointerMove.bind(this)),r.add(window,t+i,this.onPointerUp.bind(this)),l&&r.add(s.scrollWrap,l,this.onPointerUp.bind(this))}onPointerDown(t){const n=t.type==="mousedown"||t.pointerType==="mouse";if(n&&t.button>0)return;const{pswp:i}=this;if(!i.opener.isOpen){t.preventDefault();return}i.dispatch("pointerDown",{originalEvent:t}).defaultPrevented||(n&&(i.mouseDetected(),this._preventPointerEventBehaviour(t,"down")),i.animations.stopAll(),this._updatePoints(t,"down"),this._numActivePoints===1&&(this.dragAxis=null,Qo(this.startP1,this.p1)),this._numActivePoints>1?(this._clearTapTimer(),this.isMultitouch=!0):this.isMultitouch=!1)}onPointerMove(t){this._preventPointerEventBehaviour(t,"move"),this._numActivePoints&&(this._updatePoints(t,"move"),!this.pswp.dispatch("pointerMove",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===1&&!this.isDragging?(this.dragAxis||this._calculateDragDirection(),this.dragAxis&&!this.isDragging&&(this.isZooming&&(this.isZooming=!1,this.zoomLevels.end()),this.isDragging=!0,this._clearTapTimer(),this._updateStartPoints(),this._intervalTime=Date.now(),this._velocityCalculated=!1,Qo(this._intervalP1,this.p1),this.velocity.x=0,this.velocity.y=0,this.drag.start(),this._rafStopLoop(),this._rafRenderLoop())):this._numActivePoints>1&&!this.isZooming&&(this._finishDrag(),this.isZooming=!0,this._updateStartPoints(),this.zoomLevels.start(),this._rafStopLoop(),this._rafRenderLoop())))}_finishDrag(){this.isDragging&&(this.isDragging=!1,this._velocityCalculated||this._updateVelocity(!0),this.drag.end(),this.dragAxis=null)}onPointerUp(t){this._numActivePoints&&(this._updatePoints(t,"up"),!this.pswp.dispatch("pointerUp",{originalEvent:t}).defaultPrevented&&(this._numActivePoints===0&&(this._rafStopLoop(),this.isDragging?this._finishDrag():!this.isZooming&&!this.isMultitouch&&this._finishTap(t)),this._numActivePoints<2&&this.isZooming&&(this.isZooming=!1,this.zoomLevels.end(),this._numActivePoints===1&&(this.dragAxis=null,this._updateStartPoints()))))}_rafRenderLoop(){(this.isDragging||this.isZooming)&&(this._updateVelocity(),this.isDragging?c0(this.p1,this.prevP1)||this.drag.change():(!c0(this.p1,this.prevP1)||!c0(this.p2,this.prevP2))&&this.zoomLevels.change(),this._updatePrevPoints(),this.raf=requestAnimationFrame(this._rafRenderLoop.bind(this)))}_updateVelocity(t){const n=Date.now(),i=n-this._intervalTime;i<50&&!t||(this.velocity.x=this._getVelocity("x",i),this.velocity.y=this._getVelocity("y",i),this._intervalTime=n,Qo(this._intervalP1,this.p1),this._velocityCalculated=!0)}_finishTap(t){const{mainScroll:n}=this.pswp;if(n.isShifted()){n.moveIndexBy(0,!0);return}if(t.type.indexOf("cancel")>0)return;if(t.type==="mouseup"||t.pointerType==="mouse"){this.tapHandler.click(this.startP1,t);return}const i=this.pswp.options.doubleTapAction?qPe:0;this._tapTimer?(this._clearTapTimer(),_5(this._lastStartP1,this.startP1)<UPe&&this.tapHandler.doubleTap(this.startP1,t)):(Qo(this._lastStartP1,this.startP1),this._tapTimer=setTimeout(()=>{this.tapHandler.tap(this.startP1,t),this._clearTapTimer()},i))}_clearTapTimer(){this._tapTimer&&(clearTimeout(this._tapTimer),this._tapTimer=null)}_getVelocity(t,n){const i=this.p1[t]-this._intervalP1[t];return Math.abs(i)>1&&n>5?i/n:0}_rafStopLoop(){this.raf&&(cancelAnimationFrame(this.raf),this.raf=null)}_preventPointerEventBehaviour(t,n){this.pswp.applyFilters("preventPointerEvent",!0,t,n)&&t.preventDefault()}_updatePoints(t,n){if(this._pointerEventEnabled){const i=t,o=this._ongoingPointers.findIndex(s=>s.id===i.pointerId);n==="up"&&o>-1?this._ongoingPointers.splice(o,1):n==="down"&&o===-1?this._ongoingPointers.push(this._convertEventPosToPoint(i,{x:0,y:0})):o>-1&&this._convertEventPosToPoint(i,this._ongoingPointers[o]),this._numActivePoints=this._ongoingPointers.length,this._numActivePoints>0&&Qo(this.p1,this._ongoingPointers[0]),this._numActivePoints>1&&Qo(this.p2,this._ongoingPointers[1])}else{const i=t;this._numActivePoints=0,i.type.indexOf("touch")>-1?i.touches&&i.touches.length>0&&(this._convertEventPosToPoint(i.touches[0],this.p1),this._numActivePoints++,i.touches.length>1&&(this._convertEventPosToPoint(i.touches[1],this.p2),this._numActivePoints++)):(this._convertEventPosToPoint(t,this.p1),n==="up"?this._numActivePoints=0:this._numActivePoints++)}}_updatePrevPoints(){Qo(this.prevP1,this.p1),Qo(this.prevP2,this.p2)}_updateStartPoints(){Qo(this.startP1,this.p1),Qo(this.startP2,this.p2),this._updatePrevPoints()}_calculateDragDirection(){if(this.pswp.mainScroll.isShifted())this.dragAxis="x";else{const t=Math.abs(this.p1.x-this.startP1.x)-Math.abs(this.p1.y-this.startP1.y);if(t!==0){const n=t>0?"x":"y";Math.abs(this.p1[n]-this.startP1[n])>=WPe&&(this.dragAxis=n)}}}_convertEventPosToPoint(t,n){return n.x=t.pageX-this.pswp.offset.x,n.y=t.pageY-this.pswp.offset.y,"pointerId"in t?n.id=t.pointerId:t.identifier!==void 0&&(n.id=t.identifier),n}_onClick(t){this.pswp.mainScroll.isShifted()&&(t.preventDefault(),t.stopPropagation())}}const VPe=.35;class ZPe{constructor(t){this.pswp=t,this.x=0,this.slideWidth=0,this._currPositionIndex=0,this._prevPositionIndex=0,this._containerShiftIndex=-1,this.itemHolders=[]}resize(t){const{pswp:n}=this,i=Math.round(n.viewportSize.x+n.viewportSize.x*n.options.spacing),o=i!==this.slideWidth;o&&(this.slideWidth=i,this.moveTo(this.getCurrSlideX())),this.itemHolders.forEach((s,r)=>{o&&Wd(s.el,(r+this._containerShiftIndex)*this.slideWidth),t&&s.slide&&s.slide.resize()})}resetPosition(){this._currPositionIndex=0,this._prevPositionIndex=0,this.slideWidth=0,this._containerShiftIndex=-1}appendHolders(){this.itemHolders=[];for(let t=0;t<3;t++){const n=al("pswp__item","div",this.pswp.container);n.setAttribute("role","group"),n.setAttribute("aria-roledescription","slide"),n.setAttribute("aria-hidden","true"),n.style.display=t===1?"block":"none",this.itemHolders.push({el:n})}}canBeSwiped(){return this.pswp.getNumItems()>1}moveIndexBy(t,n,i){const{pswp:o}=this;let s=o.potentialIndex+t;const r=o.getNumItems();if(o.canLoop()){s=o.getLoopedIndex(s);const a=(t+r)%r;a<=r/2?t=a:t=a-r}else s<0?s=0:s>=r&&(s=r-1),t=s-o.potentialIndex;o.potentialIndex=s,this._currPositionIndex-=t,o.animations.stopMainScroll();const l=this.getCurrSlideX();if(!n)this.moveTo(l),this.updateCurrItem();else{o.animations.startSpring({isMainScroll:!0,start:this.x,end:l,velocity:i||0,naturalFrequency:30,dampingRatio:1,onUpdate:u=>{this.moveTo(u)},onComplete:()=>{this.updateCurrItem(),o.appendHeavy()}});let a=o.potentialIndex-o.currIndex;if(o.canLoop()){const u=(a+r)%r;u<=r/2?a=u:a=u-r}Math.abs(a)>1&&this.updateCurrItem()}return!!t}getCurrSlideX(){return this.slideWidth*this._currPositionIndex}isShifted(){return this.x!==this.getCurrSlideX()}updateCurrItem(){var t;const{pswp:n}=this,i=this._prevPositionIndex-this._currPositionIndex;if(!i)return;this._prevPositionIndex=this._currPositionIndex,n.currIndex=n.potentialIndex;let o=Math.abs(i),s;o>=3&&(this._containerShiftIndex+=i+(i>0?-3:3),o=3,this.itemHolders.forEach(r=>{var l;(l=r.slide)===null||l===void 0||l.destroy(),r.slide=void 0}));for(let r=0;r<o;r++)i>0?(s=this.itemHolders.shift(),s&&(this.itemHolders[2]=s,this._containerShiftIndex++,Wd(s.el,(this._containerShiftIndex+2)*this.slideWidth),n.setContent(s,n.currIndex-o+r+2))):(s=this.itemHolders.pop(),s&&(this.itemHolders.unshift(s),this._containerShiftIndex--,Wd(s.el,this._containerShiftIndex*this.slideWidth),n.setContent(s,n.currIndex+o-r-2)));Math.abs(this._containerShiftIndex)>50&&!this.isShifted()&&(this.resetPosition(),this.resize()),n.animations.stopAllPan(),this.itemHolders.forEach((r,l)=>{r.slide&&r.slide.setIsActive(l===1)}),n.currSlide=(t=this.itemHolders[1])===null||t===void 0?void 0:t.slide,n.contentLoader.updateLazy(i),n.currSlide&&n.currSlide.applyCurrentZoomPan(),n.dispatch("change")}moveTo(t,n){if(!this.pswp.canLoop()&&n){let i=(this.slideWidth*this._currPositionIndex-t)/this.slideWidth;i+=this.pswp.currIndex;const o=Math.round(t-this.x);(i<0&&o>0||i>=this.pswp.getNumItems()-1&&o<0)&&(t=this.x+o*VPe)}this.x=t,this.pswp.container&&Wd(this.pswp.container,t),this.pswp.dispatch("moveMainScroll",{x:t,dragging:n??!1})}}const GPe={Escape:27,z:90,ArrowLeft:37,ArrowUp:38,ArrowRight:39,ArrowDown:40,Tab:9},Cd=(e,t)=>t?e:GPe[e];class QPe{constructor(t){this.pswp=t,this._wasFocused=!1,t.on("bindEvents",()=>{t.options.trapFocus&&(t.options.initialPointerPos||this._focusRoot(),t.events.add(document,"focusin",this._onFocusIn.bind(this))),t.events.add(document,"keydown",this._onKeyDown.bind(this))});const n=document.activeElement;t.on("destroy",()=>{t.options.returnFocus&&n&&this._wasFocused&&n.focus()})}_focusRoot(){!this._wasFocused&&this.pswp.element&&(this.pswp.element.focus(),this._wasFocused=!0)}_onKeyDown(t){const{pswp:n}=this;if(n.dispatch("keydown",{originalEvent:t}).defaultPrevented||TPe(t))return;let i,o,s=!1;const r="key"in t;switch(r?t.key:t.keyCode){case Cd("Escape",r):n.options.escKey&&(i="close");break;case Cd("z",r):i="toggleZoom";break;case Cd("ArrowLeft",r):o="x";break;case Cd("ArrowUp",r):o="y";break;case Cd("ArrowRight",r):o="x",s=!0;break;case Cd("ArrowDown",r):s=!0,o="y";break;case Cd("Tab",r):this._focusRoot();break}if(o){t.preventDefault();const{currSlide:l}=n;n.options.arrowKeys&&o==="x"&&n.getNumItems()>1?i=s?"next":"prev":l&&l.currZoomLevel>l.zoomLevels.fit&&(l.pan[o]+=s?-80:80,l.panTo(l.pan.x,l.pan.y))}i&&(t.preventDefault(),n[i]())}_onFocusIn(t){const{template:n}=this.pswp;n&&document!==t.target&&n!==t.target&&!n.contains(t.target)&&n.focus()}}const YPe="cubic-bezier(.4,0,.22,1)";class JPe{constructor(t){var n;this.props=t;const{target:i,onComplete:o,transform:s,onFinish:r=()=>{},duration:l=333,easing:a=YPe}=t;this.onFinish=r;const u=s?"transform":"opacity",c=(n=t[u])!==null&&n!==void 0?n:"";this._target=i,this._onComplete=o,this._finished=!1,this._onTransitionEnd=this._onTransitionEnd.bind(this),this._helperTimeout=setTimeout(()=>{hH(i,u,l,a),this._helperTimeout=setTimeout(()=>{i.addEventListener("transitionend",this._onTransitionEnd,!1),i.addEventListener("transitioncancel",this._onTransitionEnd,!1),this._helperTimeout=setTimeout(()=>{this._finalizeAnimation()},l+500),i.style[u]=c},30)},0)}_onTransitionEnd(t){t.target===this._target&&this._finalizeAnimation()}_finalizeAnimation(){this._finished||(this._finished=!0,this.onFinish(),this._onComplete&&this._onComplete())}destroy(){this._helperTimeout&&clearTimeout(this._helperTimeout),IPe(this._target),this._target.removeEventListener("transitionend",this._onTransitionEnd,!1),this._target.removeEventListener("transitioncancel",this._onTransitionEnd,!1),this._finished||this._finalizeAnimation()}}const XPe=12,eje=.75;class tje{constructor(t,n,i){this.velocity=t*1e3,this._dampingRatio=n||eje,this._naturalFrequency=i||XPe,this._dampedFrequency=this._naturalFrequency,this._dampingRatio<1&&(this._dampedFrequency*=Math.sqrt(1-this._dampingRatio*this._dampingRatio))}easeFrame(t,n){let i=0,o;n/=1e3;const s=Math.E**(-this._dampingRatio*this._naturalFrequency*n);if(this._dampingRatio===1)o=this.velocity+this._naturalFrequency*t,i=(t+o*n)*s,this.velocity=i*-this._naturalFrequency+o*s;else if(this._dampingRatio<1){o=1/this._dampedFrequency*(this._dampingRatio*this._naturalFrequency*t+this.velocity);const r=Math.cos(this._dampedFrequency*n),l=Math.sin(this._dampedFrequency*n);i=s*(t*r+o*l),this.velocity=i*-this._naturalFrequency*this._dampingRatio+s*(-this._dampedFrequency*t*l+this._dampedFrequency*o*r)}return i}}class nje{constructor(t){this.props=t,this._raf=0;const{start:n,end:i,velocity:o,onUpdate:s,onComplete:r,onFinish:l=()=>{},dampingRatio:a,naturalFrequency:u}=t;this.onFinish=l;const c=new tje(o,a,u);let d=Date.now(),h=n-i;const p=()=>{this._raf&&(h=c.easeFrame(h,Date.now()-d),Math.abs(h)<1&&Math.abs(c.velocity)<50?(s(i),r&&r(),this.onFinish()):(d=Date.now(),s(h+i),this._raf=requestAnimationFrame(p)))};this._raf=requestAnimationFrame(p)}destroy(){this._raf>=0&&cancelAnimationFrame(this._raf),this._raf=0}}class ije{constructor(){this.activeAnimations=[]}startSpring(t){this._start(t,!0)}startTransition(t){this._start(t)}_start(t,n){const i=n?new nje(t):new JPe(t);return this.activeAnimations.push(i),i.onFinish=()=>this.stop(i),i}stop(t){t.destroy();const n=this.activeAnimations.indexOf(t);n>-1&&this.activeAnimations.splice(n,1)}stopAll(){this.activeAnimations.forEach(t=>{t.destroy()}),this.activeAnimations=[]}stopAllPan(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isPan?(t.destroy(),!1):!0)}stopMainScroll(){this.activeAnimations=this.activeAnimations.filter(t=>t.props.isMainScroll?(t.destroy(),!1):!0)}isPanRunning(){return this.activeAnimations.some(t=>t.props.isPan)}}class oje{constructor(t){this.pswp=t,t.events.add(t.element,"wheel",this._onWheel.bind(this))}_onWheel(t){t.preventDefault();const{currSlide:n}=this.pswp;let{deltaX:i,deltaY:o}=t;if(n&&!this.pswp.dispatch("wheel",{originalEvent:t}).defaultPrevented)if(t.ctrlKey||this.pswp.options.wheelToZoom){if(n.isZoomable()){let s=-o;t.deltaMode===1?s*=.05:s*=t.deltaMode?1:.002,s=2**s;const r=n.currZoomLevel*s;n.zoomTo(r,{x:t.clientX,y:t.clientY})}}else n.isPannable()&&(t.deltaMode===1&&(i*=18,o*=18),n.panTo(n.pan.x-i,n.pan.y-o))}}function sje(e){if(typeof e=="string")return e;if(!e||!e.isCustomSVG)return"";const t=e;let n='<svg aria-hidden="true" class="pswp__icn" viewBox="0 0 %d %d" width="%d" height="%d">';return n=n.split("%d").join(t.size||32),t.outlineID&&(n+='<use class="pswp__icn-shadow" xlink:href="#'+t.outlineID+'"/>'),n+=t.inner,n+="</svg>",n}class rje{constructor(t,n){var i;const o=n.name||n.className;let s=n.html;if(t.options[o]===!1)return;typeof t.options[o+"SVG"]=="string"&&(s=t.options[o+"SVG"]),t.dispatch("uiElementCreate",{data:n});let r="";n.isButton?(r+="pswp__button ",r+=n.className||`pswp__button--${n.name}`):r+=n.className||`pswp__${n.name}`;let l=n.isButton?n.tagName||"button":n.tagName||"div";l=l.toLowerCase();const a=al(r,l);if(n.isButton){l==="button"&&(a.type="button");let{title:d}=n;const{ariaLabel:h}=n;typeof t.options[o+"Title"]=="string"&&(d=t.options[o+"Title"]),d&&(a.title=d);const p=h||d;p&&a.setAttribute("aria-label",p)}a.innerHTML=sje(s),n.onInit&&n.onInit(a,t),n.onClick&&(a.onclick=d=>{typeof n.onClick=="string"?t[n.onClick]():typeof n.onClick=="function"&&n.onClick(d,a,t)});const u=n.appendTo||"bar";let c=t.element;u==="bar"?(t.topBar||(t.topBar=al("pswp__top-bar pswp__hide-on-close","div",t.scrollWrap)),c=t.topBar):(a.classList.add("pswp__hide-on-close"),u==="wrapper"&&(c=t.scrollWrap)),(i=c)===null||i===void 0||i.appendChild(t.applyFilters("uiElement",a,n))}}function yH(e,t,n){e.classList.add("pswp__button--arrow"),e.setAttribute("aria-controls","pswp__items"),t.on("change",()=>{t.options.loop||(n?e.disabled=!(t.currIndex<t.getNumItems()-1):e.disabled=!(t.currIndex>0))})}const lje={name:"arrowPrev",className:"pswp__button--arrow--prev",title:"Previous",order:10,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'<path d="M29 43l-3 3-16-16 16-16 3 3-13 13 13 13z" id="pswp__icn-arrow"/>',outlineID:"pswp__icn-arrow"},onClick:"prev",onInit:yH},aje={name:"arrowNext",className:"pswp__button--arrow--next",title:"Next",order:11,isButton:!0,appendTo:"wrapper",html:{isCustomSVG:!0,size:60,inner:'<use xlink:href="#pswp__icn-arrow"/>',outlineID:"pswp__icn-arrow"},onClick:"next",onInit:(e,t)=>{yH(e,t,!0)}},uje={name:"close",title:"Close",order:20,isButton:!0,html:{isCustomSVG:!0,inner:'<path d="M24 10l-2-2-6 6-6-6-2 2 6 6-6 6 2 2 6-6 6 6 2-2-6-6z" id="pswp__icn-close"/>',outlineID:"pswp__icn-close"},onClick:"close"},cje={name:"zoom",title:"Zoom",order:10,isButton:!0,html:{isCustomSVG:!0,inner:'<path d="M17.426 19.926a6 6 0 1 1 1.5-1.5L23 22.5 21.5 24l-4.074-4.074z" id="pswp__icn-zoom"/><path fill="currentColor" class="pswp__zoom-icn-bar-h" d="M11 16v-2h6v2z"/><path fill="currentColor" class="pswp__zoom-icn-bar-v" d="M13 12h2v6h-2z"/>',outlineID:"pswp__icn-zoom"},onClick:"toggleZoom"},dje={name:"preloader",appendTo:"bar",order:7,html:{isCustomSVG:!0,inner:'<path fill-rule="evenodd" clip-rule="evenodd" d="M21.2 16a5.2 5.2 0 1 1-5.2-5.2V8a8 8 0 1 0 8 8h-2.8Z" id="pswp__icn-loading"/>',outlineID:"pswp__icn-loading"},onInit:(e,t)=>{let n,i=null;const o=(l,a)=>{e.classList.toggle("pswp__preloader--"+l,a)},s=l=>{n!==l&&(n=l,o("active",l))},r=()=>{var l;if(!((l=t.currSlide)!==null&&l!==void 0&&l.content.isLoading())){s(!1),i&&(clearTimeout(i),i=null);return}i||(i=setTimeout(()=>{var a;s(!!(!((a=t.currSlide)===null||a===void 0)&&a.content.isLoading())),i=null},t.options.preloaderDelay))};t.on("change",r),t.on("loadComplete",l=>{t.currSlide===l.slide&&r()}),t.ui&&(t.ui.updatePreloaderVisibility=r)}},fje={name:"counter",order:5,onInit:(e,t)=>{t.on("change",()=>{e.innerText=t.currIndex+1+t.options.indexIndicatorSep+t.getNumItems()})}};function AL(e,t){e.classList.toggle("pswp--zoomed-in",t)}class hje{constructor(t){this.pswp=t,this.isRegistered=!1,this.uiElementsData=[],this.items=[],this.updatePreloaderVisibility=()=>{},this._lastUpdatedZoomLevel=void 0}init(){const{pswp:t}=this;this.isRegistered=!1,this.uiElementsData=[uje,lje,aje,cje,dje,fje],t.dispatch("uiRegister"),this.uiElementsData.sort((n,i)=>(n.order||0)-(i.order||0)),this.items=[],this.isRegistered=!0,this.uiElementsData.forEach(n=>{this.registerElement(n)}),t.on("change",()=>{var n;(n=t.element)===null||n===void 0||n.classList.toggle("pswp--one-slide",t.getNumItems()===1)}),t.on("zoomPanUpdate",()=>this._onZoomPanUpdate())}registerElement(t){this.isRegistered?this.items.push(new rje(this.pswp,t)):this.uiElementsData.push(t)}_onZoomPanUpdate(){const{template:t,currSlide:n,options:i}=this.pswp;if(this.pswp.opener.isClosing||!t||!n)return;let{currZoomLevel:o}=n;if(this.pswp.opener.isOpen||(o=n.zoomLevels.initial),o===this._lastUpdatedZoomLevel)return;this._lastUpdatedZoomLevel=o;const s=n.zoomLevels.initial-n.zoomLevels.secondary;if(Math.abs(s)<.01||!n.isZoomable()){AL(t,!1),t.classList.remove("pswp--zoom-allowed");return}t.classList.add("pswp--zoom-allowed");const r=o===n.zoomLevels.initial?n.zoomLevels.secondary:n.zoomLevels.initial;AL(t,r<=o),(i.imageClickAction==="zoom"||i.imageClickAction==="zoom-or-close")&&t.classList.add("pswp--click-to-zoom")}}function pje(e){const t=e.getBoundingClientRect();return{x:t.left,y:t.top,w:t.width}}function gje(e,t,n){const i=e.getBoundingClientRect(),o=i.width/t,s=i.height/n,r=o>s?o:s,l=(i.width-t*r)/2,a=(i.height-n*r)/2,u={x:i.left+l,y:i.top+a,w:t*r};return u.innerRect={w:i.width,h:i.height,x:l,y:a},u}function mje(e,t,n){const i=n.dispatch("thumbBounds",{index:e,itemData:t,instance:n});if(i.thumbBounds)return i.thumbBounds;const{element:o}=t;let s,r;if(o&&n.options.thumbSelector!==!1){const l=n.options.thumbSelector||"img";r=o.matches(l)?o:o.querySelector(l)}return r=n.applyFilters("thumbEl",r,t,e),r&&(t.thumbCropped?s=gje(r,t.width||t.w||0,t.height||t.h||0):s=pje(r)),n.applyFilters("thumbBounds",s,t,e)}class vje{constructor(t,n){this.type=t,this.defaultPrevented=!1,n&&Object.assign(this,n)}preventDefault(){this.defaultPrevented=!0}}class yje{constructor(){this._listeners={},this._filters={},this.pswp=void 0,this.options=void 0}addFilter(t,n,i=100){var o,s,r;this._filters[t]||(this._filters[t]=[]),(o=this._filters[t])===null||o===void 0||o.push({fn:n,priority:i}),(s=this._filters[t])===null||s===void 0||s.sort((l,a)=>l.priority-a.priority),(r=this.pswp)===null||r===void 0||r.addFilter(t,n,i)}removeFilter(t,n){this._filters[t]&&(this._filters[t]=this._filters[t].filter(i=>i.fn!==n)),this.pswp&&this.pswp.removeFilter(t,n)}applyFilters(t,...n){var i;return(i=this._filters[t])===null||i===void 0||i.forEach(o=>{n[0]=o.fn.apply(this,n)}),n[0]}on(t,n){var i,o;this._listeners[t]||(this._listeners[t]=[]),(i=this._listeners[t])===null||i===void 0||i.push(n),(o=this.pswp)===null||o===void 0||o.on(t,n)}off(t,n){var i;this._listeners[t]&&(this._listeners[t]=this._listeners[t].filter(o=>n!==o)),(i=this.pswp)===null||i===void 0||i.off(t,n)}dispatch(t,n){var i;if(this.pswp)return this.pswp.dispatch(t,n);const o=new vje(t,n);return(i=this._listeners[t])===null||i===void 0||i.forEach(s=>{s.call(this,o)}),o}}class kje{constructor(t,n){if(this.element=al("pswp__img pswp__img--placeholder",t?"img":"div",n),t){const i=this.element;i.decoding="async",i.alt="",i.src=t,i.setAttribute("role","presentation")}this.element.setAttribute("aria-hidden","true")}setDisplayedSize(t,n){this.element&&(this.element.tagName==="IMG"?(M5(this.element,250,"auto"),this.element.style.transformOrigin="0 0",this.element.style.transform=G0(0,0,t/250)):M5(this.element,t,n))}destroy(){var t;(t=this.element)!==null&&t!==void 0&&t.parentNode&&this.element.remove(),this.element=null}}class bje{constructor(t,n,i){this.instance=n,this.data=t,this.index=i,this.element=void 0,this.placeholder=void 0,this.slide=void 0,this.displayedImageWidth=0,this.displayedImageHeight=0,this.width=Number(this.data.w)||Number(this.data.width)||0,this.height=Number(this.data.h)||Number(this.data.height)||0,this.isAttached=!1,this.hasSlide=!1,this.isDecoding=!1,this.state=_l.IDLE,this.data.type?this.type=this.data.type:this.data.src?this.type="image":this.type="html",this.instance.dispatch("contentInit",{content:this})}removePlaceholder(){this.placeholder&&!this.keepPlaceholder()&&setTimeout(()=>{this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0)},1e3)}load(t,n){if(this.slide&&this.usePlaceholder())if(this.placeholder){const i=this.placeholder.element;i&&!i.parentElement&&this.slide.container.prepend(i)}else{const i=this.instance.applyFilters("placeholderSrc",this.data.msrc&&this.slide.isFirstSlide?this.data.msrc:!1,this);this.placeholder=new kje(i,this.slide.container)}this.element&&!n||this.instance.dispatch("contentLoad",{content:this,isLazy:t}).defaultPrevented||(this.isImageContent()?(this.element=al("pswp__img","img"),this.displayedImageWidth&&this.loadImage(t)):(this.element=al("pswp__content","div"),this.element.innerHTML=this.data.html||""),n&&this.slide&&this.slide.updateContentSize(!0))}loadImage(t){var n,i;if(!this.isImageContent()||!this.element||this.instance.dispatch("contentLoadImage",{content:this,isLazy:t}).defaultPrevented)return;const o=this.element;this.updateSrcsetSizes(),this.data.srcset&&(o.srcset=this.data.srcset),o.src=(n=this.data.src)!==null&&n!==void 0?n:"",o.alt=(i=this.data.alt)!==null&&i!==void 0?i:"",this.state=_l.LOADING,o.complete?this.onLoaded():(o.onload=()=>{this.onLoaded()},o.onerror=()=>{this.onError()})}setSlide(t){this.slide=t,this.hasSlide=!0,this.instance=t.pswp}onLoaded(){this.state=_l.LOADED,this.slide&&this.element&&(this.instance.dispatch("loadComplete",{slide:this.slide,content:this}),this.slide.isActive&&this.slide.heavyAppended&&!this.element.parentNode&&(this.append(),this.slide.updateContentSize(!0)),(this.state===_l.LOADED||this.state===_l.ERROR)&&this.removePlaceholder())}onError(){this.state=_l.ERROR,this.slide&&(this.displayError(),this.instance.dispatch("loadComplete",{slide:this.slide,isError:!0,content:this}),this.instance.dispatch("loadError",{slide:this.slide,content:this}))}isLoading(){return this.instance.applyFilters("isContentLoading",this.state===_l.LOADING,this)}isError(){return this.state===_l.ERROR}isImageContent(){return this.type==="image"}setDisplayedSize(t,n){if(this.element&&(this.placeholder&&this.placeholder.setDisplayedSize(t,n),!this.instance.dispatch("contentResize",{content:this,width:t,height:n}).defaultPrevented&&(M5(this.element,t,n),this.isImageContent()&&!this.isError()))){const i=!this.displayedImageWidth&&t;this.displayedImageWidth=t,this.displayedImageHeight=n,i?this.loadImage(!1):this.updateSrcsetSizes(),this.slide&&this.instance.dispatch("imageSizeChange",{slide:this.slide,width:t,height:n,content:this})}}isZoomable(){return this.instance.applyFilters("isContentZoomable",this.isImageContent()&&this.state!==_l.ERROR,this)}updateSrcsetSizes(){if(!this.isImageContent()||!this.element||!this.data.srcset)return;const t=this.element,n=this.instance.applyFilters("srcsetSizesWidth",this.displayedImageWidth,this);(!t.dataset.largestUsedSize||n>parseInt(t.dataset.largestUsedSize,10))&&(t.sizes=n+"px",t.dataset.largestUsedSize=String(n))}usePlaceholder(){return this.instance.applyFilters("useContentPlaceholder",this.isImageContent(),this)}lazyLoad(){this.instance.dispatch("contentLazyLoad",{content:this}).defaultPrevented||this.load(!0)}keepPlaceholder(){return this.instance.applyFilters("isKeepingPlaceholder",this.isLoading(),this)}destroy(){this.hasSlide=!1,this.slide=void 0,!this.instance.dispatch("contentDestroy",{content:this}).defaultPrevented&&(this.remove(),this.placeholder&&(this.placeholder.destroy(),this.placeholder=void 0),this.isImageContent()&&this.element&&(this.element.onload=null,this.element.onerror=null,this.element=void 0))}displayError(){if(this.slide){var t,n;let i=al("pswp__error-msg","div");i.innerText=(t=(n=this.instance.options)===null||n===void 0?void 0:n.errorMsg)!==null&&t!==void 0?t:"",i=this.instance.applyFilters("contentErrorElement",i,this),this.element=al("pswp__content pswp__error-msg-container","div"),this.element.appendChild(i),this.slide.container.innerText="",this.slide.container.appendChild(this.element),this.slide.updateContentSize(!0),this.removePlaceholder()}}append(){if(this.isAttached||!this.element)return;if(this.isAttached=!0,this.state===_l.ERROR){this.displayError();return}if(this.instance.dispatch("contentAppend",{content:this}).defaultPrevented)return;const t="decode"in this.element;this.isImageContent()?t&&this.slide&&(!this.slide.isActive||gL())?(this.isDecoding=!0,this.element.decode().catch(()=>{}).finally(()=>{this.isDecoding=!1,this.appendImage()})):this.appendImage():this.slide&&!this.element.parentNode&&this.slide.container.appendChild(this.element)}activate(){this.instance.dispatch("contentActivate",{content:this}).defaultPrevented||!this.slide||(this.isImageContent()&&this.isDecoding&&!gL()?this.appendImage():this.isError()&&this.load(!1,!0),this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","false"))}deactivate(){this.instance.dispatch("contentDeactivate",{content:this}),this.slide&&this.slide.holderElement&&this.slide.holderElement.setAttribute("aria-hidden","true")}remove(){this.isAttached=!1,!this.instance.dispatch("contentRemove",{content:this}).defaultPrevented&&(this.element&&this.element.parentNode&&this.element.remove(),this.placeholder&&this.placeholder.element&&this.placeholder.element.remove())}appendImage(){this.isAttached&&(this.instance.dispatch("contentAppendImage",{content:this}).defaultPrevented||(this.slide&&this.element&&!this.element.parentNode&&this.slide.container.appendChild(this.element),(this.state===_l.LOADED||this.state===_l.ERROR)&&this.removePlaceholder()))}}const Aje=5;function kH(e,t,n){const i=t.createContentFromData(e,n);let o;const{options:s}=t;if(s){o=new vH(s,e,-1);let r;t.pswp?r=t.pswp.viewportSize:r=gH(s,t);const l=mH(s,r,e,n);o.update(i.width,i.height,l)}return i.lazyLoad(),o&&i.setDisplayedSize(Math.ceil(i.width*o.initial),Math.ceil(i.height*o.initial)),i}function Cje(e,t){const n=t.getItemData(e);if(!t.dispatch("lazyLoadSlide",{index:e,itemData:n}).defaultPrevented)return kH(n,t,e)}class wje{constructor(t){this.pswp=t,this.limit=Math.max(t.options.preload[0]+t.options.preload[1]+1,Aje),this._cachedItems=[]}updateLazy(t){const{pswp:n}=this;if(n.dispatch("lazyLoad").defaultPrevented)return;const{preload:i}=n.options,o=t===void 0?!0:t>=0;let s;for(s=0;s<=i[1];s++)this.loadSlideByIndex(n.currIndex+(o?s:-s));for(s=1;s<=i[0];s++)this.loadSlideByIndex(n.currIndex+(o?-s:s))}loadSlideByIndex(t){const n=this.pswp.getLoopedIndex(t);let i=this.getContentByIndex(n);i||(i=Cje(n,this.pswp),i&&this.addToCache(i))}getContentBySlide(t){let n=this.getContentByIndex(t.index);return n||(n=this.pswp.createContentFromData(t.data,t.index),this.addToCache(n)),n.setSlide(t),n}addToCache(t){if(this.removeByIndex(t.index),this._cachedItems.push(t),this._cachedItems.length>this.limit){const n=this._cachedItems.findIndex(i=>!i.isAttached&&!i.hasSlide);n!==-1&&this._cachedItems.splice(n,1)[0].destroy()}}removeByIndex(t){const n=this._cachedItems.findIndex(i=>i.index===t);n!==-1&&this._cachedItems.splice(n,1)}getContentByIndex(t){return this._cachedItems.find(n=>n.index===t)}destroy(){this._cachedItems.forEach(t=>t.destroy()),this._cachedItems=[]}}class xje extends yje{getNumItems(){var t;let n=0;const i=(t=this.options)===null||t===void 0?void 0:t.dataSource;i&&"length"in i?n=i.length:i&&"gallery"in i&&(i.items||(i.items=this._getGalleryDOMElements(i.gallery)),i.items&&(n=i.items.length));const o=this.dispatch("numItems",{dataSource:i,numItems:n});return this.applyFilters("numItems",o.numItems,i)}createContentFromData(t,n){return new bje(t,this,n)}getItemData(t){var n;const i=(n=this.options)===null||n===void 0?void 0:n.dataSource;let o={};Array.isArray(i)?o=i[t]:i&&"gallery"in i&&(i.items||(i.items=this._getGalleryDOMElements(i.gallery)),o=i.items[t]);let s=o;s instanceof Element&&(s=this._domElementToItemData(s));const r=this.dispatch("itemData",{itemData:s||{},index:t});return this.applyFilters("itemData",r.itemData,t)}_getGalleryDOMElements(t){var n,i;return(n=this.options)!==null&&n!==void 0&&n.children||(i=this.options)!==null&&i!==void 0&&i.childSelector?LPe(this.options.children,this.options.childSelector,t)||[]:[t]}_domElementToItemData(t){const n={element:t},i=t.tagName==="A"?t:t.querySelector("a");if(i){n.src=i.dataset.pswpSrc||i.href,i.dataset.pswpSrcset&&(n.srcset=i.dataset.pswpSrcset),n.width=i.dataset.pswpWidth?parseInt(i.dataset.pswpWidth,10):0,n.height=i.dataset.pswpHeight?parseInt(i.dataset.pswpHeight,10):0,n.w=n.width,n.h=n.height,i.dataset.pswpType&&(n.type=i.dataset.pswpType);const s=t.querySelector("img");if(s){var o;n.msrc=s.currentSrc||s.src,n.alt=(o=s.getAttribute("alt"))!==null&&o!==void 0?o:""}(i.dataset.pswpCropped||i.dataset.cropped)&&(n.thumbCropped=!0)}return this.applyFilters("domItemData",n,t,i)}lazyLoadData(t,n){return kH(t,this,n)}}const np=.003;class Sje{constructor(t){this.pswp=t,this.isClosed=!0,this.isOpen=!1,this.isClosing=!1,this.isOpening=!1,this._duration=void 0,this._useAnimation=!1,this._croppedZoom=!1,this._animateRootOpacity=!1,this._animateBgOpacity=!1,this._placeholder=void 0,this._opacityElement=void 0,this._cropContainer1=void 0,this._cropContainer2=void 0,this._thumbBounds=void 0,this._prepareOpen=this._prepareOpen.bind(this),t.on("firstZoomPan",this._prepareOpen)}open(){this._prepareOpen(),this._start()}close(){if(this.isClosed||this.isClosing||this.isOpening)return;const t=this.pswp.currSlide;this.isOpen=!1,this.isOpening=!1,this.isClosing=!0,this._duration=this.pswp.options.hideAnimationDuration,t&&t.currZoomLevel*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps(),setTimeout(()=>{this._start()},this._croppedZoom?30:0)}_prepareOpen(){if(this.pswp.off("firstZoomPan",this._prepareOpen),!this.isOpening){const t=this.pswp.currSlide;this.isOpening=!0,this.isClosing=!1,this._duration=this.pswp.options.showAnimationDuration,t&&t.zoomLevels.initial*t.width>=this.pswp.options.maxWidthToAnimate&&(this._duration=0),this._applyStartProps()}}_applyStartProps(){const{pswp:t}=this,n=this.pswp.currSlide,{options:i}=t;if(i.showHideAnimationType==="fade"?(i.showHideOpacity=!0,this._thumbBounds=void 0):i.showHideAnimationType==="none"?(i.showHideOpacity=!1,this._duration=0,this._thumbBounds=void 0):this.isOpening&&t._initialThumbBounds?this._thumbBounds=t._initialThumbBounds:this._thumbBounds=this.pswp.getThumbBounds(),this._placeholder=n?.getPlaceholderElement(),t.animations.stopAll(),this._useAnimation=!!(this._duration&&this._duration>50),this._animateZoom=!!this._thumbBounds&&n?.content.usePlaceholder()&&(!this.isClosing||!t.mainScroll.isShifted()),!this._animateZoom)this._animateRootOpacity=!0,this.isOpening&&n&&(n.zoomAndPanToInitial(),n.applyCurrentZoomPan());else{var o;this._animateRootOpacity=(o=i.showHideOpacity)!==null&&o!==void 0?o:!1}if(this._animateBgOpacity=!this._animateRootOpacity&&this.pswp.options.bgOpacity>np,this._opacityElement=this._animateRootOpacity?t.element:t.bg,!this._useAnimation){this._duration=0,this._animateZoom=!1,this._animateBgOpacity=!1,this._animateRootOpacity=!0,this.isOpening&&(t.element&&(t.element.style.opacity=String(np)),t.applyBgOpacity(1));return}if(this._animateZoom&&this._thumbBounds&&this._thumbBounds.innerRect){var s;this._croppedZoom=!0,this._cropContainer1=this.pswp.container,this._cropContainer2=(s=this.pswp.currSlide)===null||s===void 0?void 0:s.holderElement,t.container&&(t.container.style.overflow="hidden",t.container.style.width=t.viewportSize.x+"px")}else this._croppedZoom=!1;this.isOpening?(this._animateRootOpacity?(t.element&&(t.element.style.opacity=String(np)),t.applyBgOpacity(1)):(this._animateBgOpacity&&t.bg&&(t.bg.style.opacity=String(np)),t.element&&(t.element.style.opacity="1")),this._animateZoom&&(this._setClosedStateZoomPan(),this._placeholder&&(this._placeholder.style.willChange="transform",this._placeholder.style.opacity=String(np)))):this.isClosing&&(t.mainScroll.itemHolders[0]&&(t.mainScroll.itemHolders[0].el.style.display="none"),t.mainScroll.itemHolders[2]&&(t.mainScroll.itemHolders[2].el.style.display="none"),this._croppedZoom&&t.mainScroll.x!==0&&(t.mainScroll.resetPosition(),t.mainScroll.resize()))}_start(){this.isOpening&&this._useAnimation&&this._placeholder&&this._placeholder.tagName==="IMG"?new Promise(t=>{let n=!1,i=!0;EPe(this._placeholder).finally(()=>{n=!0,i||t(!0)}),setTimeout(()=>{i=!1,n&&t(!0)},50),setTimeout(t,250)}).finally(()=>this._initiate()):this._initiate()}_initiate(){var t,n;(t=this.pswp.element)===null||t===void 0||t.style.setProperty("--pswp-transition-duration",this._duration+"ms"),this.pswp.dispatch(this.isOpening?"openingAnimationStart":"closingAnimationStart"),this.pswp.dispatch("initialZoom"+(this.isOpening?"In":"Out")),(n=this.pswp.element)===null||n===void 0||n.classList.toggle("pswp--ui-visible",this.isOpening),this.isOpening?(this._placeholder&&(this._placeholder.style.opacity="1"),this._animateToOpenState()):this.isClosing&&this._animateToClosedState(),this._useAnimation||this._onAnimationComplete()}_onAnimationComplete(){const{pswp:t}=this;if(this.isOpen=this.isOpening,this.isClosed=this.isClosing,this.isOpening=!1,this.isClosing=!1,t.dispatch(this.isOpen?"openingAnimationEnd":"closingAnimationEnd"),t.dispatch("initialZoom"+(this.isOpen?"InEnd":"OutEnd")),this.isClosed)t.destroy();else if(this.isOpen){var n;this._animateZoom&&t.container&&(t.container.style.overflow="visible",t.container.style.width="100%"),(n=t.currSlide)===null||n===void 0||n.applyCurrentZoomPan()}}_animateToOpenState(){const{pswp:t}=this;this._animateZoom&&(this._croppedZoom&&this._cropContainer1&&this._cropContainer2&&(this._animateTo(this._cropContainer1,"transform","translate3d(0,0,0)"),this._animateTo(this._cropContainer2,"transform","none")),t.currSlide&&(t.currSlide.zoomAndPanToInitial(),this._animateTo(t.currSlide.container,"transform",t.currSlide.getCurrentTransform()))),this._animateBgOpacity&&t.bg&&this._animateTo(t.bg,"opacity",String(t.options.bgOpacity)),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","1")}_animateToClosedState(){const{pswp:t}=this;this._animateZoom&&this._setClosedStateZoomPan(!0),this._animateBgOpacity&&t.bgOpacity>.01&&t.bg&&this._animateTo(t.bg,"opacity","0"),this._animateRootOpacity&&t.element&&this._animateTo(t.element,"opacity","0")}_setClosedStateZoomPan(t){if(!this._thumbBounds)return;const{pswp:n}=this,{innerRect:i}=this._thumbBounds,{currSlide:o,viewportSize:s}=n;if(this._croppedZoom&&i&&this._cropContainer1&&this._cropContainer2){const r=-s.x+(this._thumbBounds.x-i.x)+i.w,l=-s.y+(this._thumbBounds.y-i.y)+i.h,a=s.x-i.w,u=s.y-i.h;t?(this._animateTo(this._cropContainer1,"transform",G0(r,l)),this._animateTo(this._cropContainer2,"transform",G0(a,u))):(Wd(this._cropContainer1,r,l),Wd(this._cropContainer2,a,u))}o&&(Qo(o.pan,i||this._thumbBounds),o.currZoomLevel=this._thumbBounds.w/o.width,t?this._animateTo(o.container,"transform",o.getCurrentTransform()):o.applyCurrentZoomPan())}_animateTo(t,n,i){if(!this._duration){t.style[n]=i;return}const{animations:o}=this.pswp,s={duration:this._duration,easing:this.pswp.options.easing,onComplete:()=>{o.activeAnimations.length||this._onAnimationComplete()},target:t};s[n]=i,o.startTransition(s)}}const _je={allowPanToNext:!0,spacing:.1,loop:!0,pinchToClose:!0,closeOnVerticalDrag:!0,hideAnimationDuration:333,showAnimationDuration:333,zoomAnimationDuration:333,escKey:!0,arrowKeys:!0,trapFocus:!0,returnFocus:!0,maxWidthToAnimate:4e3,clickToCloseNonZoomable:!0,imageClickAction:"zoom-or-close",bgClickAction:"close",tapAction:"toggle-controls",doubleTapAction:"zoom",indexIndicatorSep:" / ",preloaderDelay:2e3,bgOpacity:.8,index:0,errorMsg:"The image cannot be loaded",preload:[1,2],easing:"cubic-bezier(.4,0,.22,1)"};class Mje extends xje{constructor(t){super(),this.options=this._prepareOptions(t||{}),this.offset={x:0,y:0},this._prevViewportSize={x:0,y:0},this.viewportSize={x:0,y:0},this.bgOpacity=1,this.currIndex=0,this.potentialIndex=0,this.isOpen=!1,this.isDestroying=!1,this.hasMouse=!1,this._initialItemData={},this._initialThumbBounds=void 0,this.topBar=void 0,this.element=void 0,this.template=void 0,this.container=void 0,this.scrollWrap=void 0,this.currSlide=void 0,this.events=new NPe,this.animations=new ije,this.mainScroll=new ZPe(this),this.gestures=new KPe(this),this.opener=new Sje(this),this.keyboard=new QPe(this),this.contentLoader=new wje(this)}init(){if(this.isOpen||this.isDestroying)return!1;this.isOpen=!0,this.dispatch("init"),this.dispatch("beforeOpen"),this._createMainStructure();let t="pswp--open";return this.gestures.supportsTouch&&(t+=" pswp--touch"),this.options.mainClass&&(t+=" "+this.options.mainClass),this.element&&(this.element.className+=" "+t),this.currIndex=this.options.index||0,this.potentialIndex=this.currIndex,this.dispatch("firstUpdate"),this.scrollWheel=new oje(this),(Number.isNaN(this.currIndex)||this.currIndex<0||this.currIndex>=this.getNumItems())&&(this.currIndex=0),this.gestures.supportsTouch||this.mouseDetected(),this.updateSize(),this.offset.y=window.pageYOffset,this._initialItemData=this.getItemData(this.currIndex),this.dispatch("gettingData",{index:this.currIndex,data:this._initialItemData,slide:void 0}),this._initialThumbBounds=this.getThumbBounds(),this.dispatch("initialLayout"),this.on("openingAnimationEnd",()=>{const{itemHolders:n}=this.mainScroll;n[0]&&(n[0].el.style.display="block",this.setContent(n[0],this.currIndex-1)),n[2]&&(n[2].el.style.display="block",this.setContent(n[2],this.currIndex+1)),this.appendHeavy(),this.contentLoader.updateLazy(),this.events.add(window,"resize",this._handlePageResize.bind(this)),this.events.add(window,"scroll",this._updatePageScrollOffset.bind(this)),this.dispatch("bindEvents")}),this.mainScroll.itemHolders[1]&&this.setContent(this.mainScroll.itemHolders[1],this.currIndex),this.dispatch("change"),this.opener.open(),this.dispatch("afterInit"),!0}getLoopedIndex(t){const n=this.getNumItems();return this.options.loop&&(t>n-1&&(t-=n),t<0&&(t+=n)),Eg(t,0,n-1)}appendHeavy(){this.mainScroll.itemHolders.forEach(t=>{var n;(n=t.slide)===null||n===void 0||n.appendHeavy()})}goTo(t){this.mainScroll.moveIndexBy(this.getLoopedIndex(t)-this.potentialIndex)}next(){this.goTo(this.potentialIndex+1)}prev(){this.goTo(this.potentialIndex-1)}zoomTo(...t){var n;(n=this.currSlide)===null||n===void 0||n.zoomTo(...t)}toggleZoom(){var t;(t=this.currSlide)===null||t===void 0||t.toggleZoom()}close(){!this.opener.isOpen||this.isDestroying||(this.isDestroying=!0,this.dispatch("close"),this.events.removeAll(),this.opener.close())}destroy(){var t;if(!this.isDestroying){this.options.showHideAnimationType="none",this.close();return}this.dispatch("destroy"),this._listeners={},this.scrollWrap&&(this.scrollWrap.ontouchmove=null,this.scrollWrap.ontouchend=null),(t=this.element)===null||t===void 0||t.remove(),this.mainScroll.itemHolders.forEach(n=>{var i;(i=n.slide)===null||i===void 0||i.destroy()}),this.contentLoader.destroy(),this.events.removeAll()}refreshSlideContent(t){this.contentLoader.removeByIndex(t),this.mainScroll.itemHolders.forEach((n,i)=>{var o,s;let r=((o=(s=this.currSlide)===null||s===void 0?void 0:s.index)!==null&&o!==void 0?o:0)-1+i;if(this.canLoop()&&(r=this.getLoopedIndex(r)),r===t&&(this.setContent(n,t,!0),i===1)){var l;this.currSlide=n.slide,(l=n.slide)===null||l===void 0||l.setIsActive(!0)}}),this.dispatch("change")}setContent(t,n,i){if(this.canLoop()&&(n=this.getLoopedIndex(n)),t.slide){if(t.slide.index===n&&!i)return;t.slide.destroy(),t.slide=void 0}if(!this.canLoop()&&(n<0||n>=this.getNumItems()))return;const o=this.getItemData(n);t.slide=new DPe(o,n,this),n===this.currIndex&&(this.currSlide=t.slide),t.slide.append(t.el)}getViewportCenterPoint(){return{x:this.viewportSize.x/2,y:this.viewportSize.y/2}}updateSize(t){if(this.isDestroying)return;const n=gH(this.options,this);!t&&c0(n,this._prevViewportSize)||(Qo(this._prevViewportSize,n),this.dispatch("beforeResize"),Qo(this.viewportSize,this._prevViewportSize),this._updatePageScrollOffset(),this.dispatch("viewportSize"),this.mainScroll.resize(this.opener.isOpen),!this.hasMouse&&window.matchMedia("(any-hover: hover)").matches&&this.mouseDetected(),this.dispatch("resize"))}applyBgOpacity(t){this.bgOpacity=Math.max(t,0),this.bg&&(this.bg.style.opacity=String(this.bgOpacity*this.options.bgOpacity))}mouseDetected(){if(!this.hasMouse){var t;this.hasMouse=!0,(t=this.element)===null||t===void 0||t.classList.add("pswp--has_mouse")}}_handlePageResize(){this.updateSize(),/iPhone|iPad|iPod/i.test(window.navigator.userAgent)&&setTimeout(()=>{this.updateSize()},500)}_updatePageScrollOffset(){this.setScrollOffset(0,window.pageYOffset)}setScrollOffset(t,n){this.offset.x=t,this.offset.y=n,this.dispatch("updateScrollOffset")}_createMainStructure(){this.element=al("pswp","div"),this.element.setAttribute("tabindex","-1"),this.element.setAttribute("role","dialog"),this.template=this.element,this.bg=al("pswp__bg","div",this.element),this.scrollWrap=al("pswp__scroll-wrap","section",this.element),this.container=al("pswp__container","div",this.scrollWrap),this.scrollWrap.setAttribute("aria-roledescription","carousel"),this.container.setAttribute("aria-live","off"),this.container.setAttribute("id","pswp__items"),this.mainScroll.appendHolders(),this.ui=new hje(this),this.ui.init(),(this.options.appendToEl||document.body).appendChild(this.element)}getThumbBounds(){return mje(this.currIndex,this.currSlide?this.currSlide.data:this._initialItemData,this)}canLoop(){return this.options.loop&&this.getNumItems()>2}_prepareOptions(t){return window.matchMedia("(prefers-reduced-motion), (update: slow)").matches&&(t.showHideAnimationType="none",t.zoomAnimationDuration=0),{..._je,...t}}}function Ije(e){return new Promise(t=>{const n=new Image;n.onload=()=>t(n.naturalWidth>0?{w:n.naturalWidth,h:n.naturalHeight}:null),n.onerror=()=>t(null),n.src=e})}async function Eje(e,t,n){if(n?.currentSrc&&n.naturalWidth>0)return{src:n.currentSrc,w:n.naturalWidth,h:n.naturalHeight,objectUrl:null};let i=t.url,o=null;if(t.fileId)try{const r=t.sessionId?await e.getSessionMediaBlob(t.sessionId,t.fileId):await e.getFileBlob(t.fileId);o=URL.createObjectURL(r),i=o}catch{}const s=await Ije(i);return s?{src:i,...s,objectUrl:o}:(o&&URL.revokeObjectURL(o),null)}function Tje(e){const t=(o,s)=>{const r=parseFloat(e(o));return Number.isFinite(r)&&r>0?r:s},n=t("--space-6",24),i=t("--space-8",32)+n;return{top:i,bottom:i,left:n,right:n}}function Lje(e){let t=!1,n=!1,i=null;return(async()=>{const o=await Eje(e.api,e.media,e.thumbImg);if(t){o?.objectUrl&&URL.revokeObjectURL(o.objectUrl);return}if(!o){e.onClose();return}const s=e.thumbImg?.currentSrc===o.src?e.thumbImg:null;i=new Mje({dataSource:[{src:o.src,w:o.w,h:o.h,thumbCropped:!0,...s?{msrc:s.currentSrc,element:s}:{}}],index:0,showHideAnimationType:s?"zoom":"fade",arrowPrev:!1,arrowNext:!1,counter:!1,close:!1,zoom:!1,wheelToZoom:!0,escKey:!0,trapFocus:!1,bgOpacity:1,padding:Tje(l=>getComputedStyle(document.documentElement).getPropertyValue(l))}),i.addFilter("thumbEl",l=>l?.isConnected?l:null);const r=e.media.path;i.on("uiRegister",()=>{const l=i?.ui;!l||!r||l.registerElement({name:"caption",className:"media-preview-caption",isButton:!1,appendTo:"root",onInit:a=>{a.textContent=r}})}),i.on("openingAnimationStart",()=>{Fs.value+=1,e.onOpen?.()}),i.on("destroy",()=>{n=!0,Fs.value=Math.max(0,Fs.value-1),o.objectUrl&&URL.revokeObjectURL(o.objectUrl),e.onClose()}),i.init()})(),()=>{t=!0,i&&!n&&i.close()}}function MA(e){try{const t=new URL(e).protocol;return t==="http:"||t==="https:"}catch{return!1}}function Nje(){const e=window.open("","_blank");if(!e)return null;try{e.opener=null}catch{}return{get closed(){return e.closed},navigate(t){e.location.href=t},focus(){e.focus()},close(){e.close()}}}function bH(e=Nje){let t=null,n=null;function i(){if(t)try{t.close()}catch{}t=null,n=null}return{onGesture(){i(),t=e()},openUrl(o,s){if(!MA(o))return i(),!1;if(!t||t.closed)return t=null,n=null,!1;if(n===o){try{t.focus()}catch{}return!0}try{t.navigate(o)}catch{return i(),!1}return n=o,!0},settle(o,s){if(n!==null&&(o||s?.keepNavigated===!0)){t=null,n=null;return}i()}}}function AH(){return{subscribe(e){const t=()=>{document.visibilityState==="visible"&&e()};return window.addEventListener("focus",e),document.addEventListener("visibilitychange",t),()=>{window.removeEventListener("focus",e),document.removeEventListener("visibilitychange",t)}}}}const Fje=["aria-label"],Dje=["aria-label"],Bje={class:"media-lightbox-card"},$je={class:"media-lightbox-frame"},Rje={key:0,class:"media-lightbox-name"},zje=["aria-label"],Oje='button:not([disabled]), video[controls], [tabindex]:not([tabindex="-1"])',Pje=Xe({__name:"MediaLightbox",props:{media:{},originImg:{}},emits:["close"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>n.media.kind==="image"),r=F(()=>n.media.path??null),l=F(()=>r.value??(n.media.kind==="video"?o("composer.attachmentVideo"):o("composer.attachmentImage"))),a=K(null),u=K(null),c=K(!1);let d=null,h=null;function p(g){if(g.key==="Escape"){g.preventDefault(),i("close");return}if(g.key!=="Tab"||!a.value)return;const m=a.value.querySelectorAll(Oje),k=m[0],w=m[m.length-1];!k||!w||(a.value.contains(document.activeElement)?g.shiftKey&&document.activeElement===k?(g.preventDefault(),w.focus()):!g.shiftKey&&document.activeElement===w&&(g.preventDefault(),k.focus()):(g.preventDefault(),(g.shiftKey?w:k).focus()))}return cn(()=>{if(s.value){h=Lje({api:Ic(),media:n.media,thumbImg:n.originImg??null,onOpen:()=>{c.value=!0},onClose:()=>i("close")});return}Fs.value+=1,d=document.activeElement instanceof HTMLElement?document.activeElement:null,window.addEventListener("keydown",p),u.value?.focus()}),Hn(()=>{if(h){h(),h=null;return}Fs.value=Math.max(0,Fs.value-1),window.removeEventListener("keydown",p),d?.focus()}),(g,m)=>(v(),ce(Ds,{to:"body"},[s.value?c.value?(v(),ce(f(gn),{key:1,text:f(o)("model.close")},{default:de(()=>[C("button",{type:"button",class:"media-lightbox-close","aria-label":f(o)("model.close"),onClick:m[2]||(m[2]=k=>i("close"))},[U(f(ve),{name:"close",size:"sm"})],8,zje)]),_:1},8,["text"])):X("",!0):(v(),E("div",{key:0,ref_key:"overlayRef",ref:a,class:"media-lightbox",role:"dialog","aria-modal":"true","aria-label":l.value,onMousedown:m[1]||(m[1]=wt(k=>i("close"),["self"]))},[U(f(gn),{text:f(o)("model.close")},{default:de(()=>[C("button",{ref_key:"closeRef",ref:u,type:"button",class:"media-lightbox-close","aria-label":f(o)("model.close"),onClick:m[0]||(m[0]=k=>i("close"))},[U(f(ve),{name:"close",size:"sm"})],8,Dje)]),_:1},8,["text"]),C("div",Bje,[C("div",$je,[U(hg,{url:e.media.url,kind:e.media.kind==="video"?"video":"image","file-id":e.media.fileId,"session-id":e.media.sessionId,"media-class":"media-lightbox-media",controls:e.media.kind==="video"},null,8,["url","kind","file-id","session-id","controls"])]),r.value?(v(),E("div",Rje,D(r.value),1)):X("",!0)])],40,Fje))]))}}),IA=kt(Pje,[["__scopeId","data-v-c59e1983"]]),jje=["title","aria-label"],Hje={key:1,class:"media-thumb-media media-thumb-tile","aria-hidden":"true"},Wje={key:2,class:"media-thumb-badge","aria-hidden":"true"},qje={key:3,class:"media-thumb-badge is-error","aria-hidden":"true"},Uje={key:4,class:"media-thumb-badge","aria-hidden":"true"},Kje=["aria-label"],Vje=Xe({__name:"MediaThumb",props:{kind:{},name:{},url:{},fileId:{},sessionId:{},uploading:{type:Boolean,default:!1},error:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},removeLabel:{}},emits:["activate","remove"],setup(e,{emit:t}){const n=e,i=t;function o(u){i("activate",u.currentTarget.querySelector("img"))}const{t:s}=zt(),r=F(()=>n.name?n.name:n.kind==="video"?s("composer.attachmentVideo"):s("composer.attachmentImage")),l=F(()=>n.url?.startsWith("blob:")??!1),a=F(()=>!n.url||n.kind==="video"&&n.fileId!==void 0&&!l.value);return(u,c)=>(v(),E("span",{class:Fe(["media-thumb",{"is-error":e.error,uploading:e.uploading}])},[C("button",{type:"button",class:"media-thumb-btn",title:r.value,"aria-label":r.value,onClick:o},[a.value?(v(),E("span",Hje)):(v(),ce(hg,{key:0,url:e.url,kind:e.kind,"file-id":l.value?void 0:e.fileId,"session-id":l.value?void 0:e.sessionId,"media-class":"media-thumb-media",controls:!1,muted:""},null,8,["url","kind","file-id","session-id"])),e.uploading?(v(),E("span",Wje,[U(f(Oi),{size:"sm",label:f(s)("composer.uploading")},null,8,["label"])])):e.error?(v(),E("span",qje,[U(f(ve),{name:"info",size:"sm"})])):e.kind==="video"?(v(),E("span",Uje,[U(f(ve),{name:"play",size:"sm"})])):X("",!0)],8,jje),e.removable?(v(),ce(f(gn),{key:0,text:e.removeLabel??f(s)("composer.remove")},{default:de(()=>[C("button",{type:"button",class:"media-thumb-rm","aria-label":e.removeLabel??f(s)("composer.remove"),onClick:c[0]||(c[0]=d=>i("remove"))},[U(f(ve),{name:"close",size:"sm"})],8,Kje)]),_:1},8,["text"])):X("",!0)],2))}}),CH=kt(Vje,[["__scopeId","data-v-16b8c78d"]]),Zje=["title","data-kind"],Gje=["aria-label"],Qje={class:"att-tile"},Yje={class:"att-name"},Jje={key:1,class:"att-err"},Xje=["aria-label"],eHe=Xe({__name:"AttachmentChip",props:{kind:{},name:{},url:{},fileId:{},sessionId:{},mediaType:{},size:{},uploading:{type:Boolean,default:!1},error:{type:Boolean,default:!1},removable:{type:Boolean,default:!1},removeLabel:{}},emits:["activate","remove"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>{const d=n.name?.match(/\.([A-Za-z0-9]{1,8})$/)?.[1]??n.mediaType?.split("/")[1]?.split("+")[0];return d?d.toUpperCase():void 0}),r=F(()=>{const c=s.value??"";return/^(txt|md|doc|docx|rtf|log)$/i.test(c)?"file-text":"file"}),l=F(()=>n.name?n.name:n.kind==="image"?o("composer.attachmentImage"):n.kind==="video"?o("composer.attachmentVideo"):o("composer.attachmentFile"));function a(c){return c<1024?`${c} B`:c<1024*1024?`${Math.round(c/1024)} KB`:`${(c/(1024*1024)).toFixed(1)} MB`}const u=F(()=>{const c=[l.value];return n.size!==void 0&&c.push(a(n.size)),c.join(" · ")});return(c,d)=>(v(),E("span",{class:Fe(["att-chip",{"is-error":e.error,uploading:e.uploading}]),title:u.value,"data-kind":e.kind},[C("button",{type:"button",class:"att-activate","aria-label":u.value,onClick:d[0]||(d[0]=h=>i("activate"))},[C("span",Qje,[e.kind==="image"&&e.url?(v(),ce(hg,{key:0,url:e.url,kind:"image",alt:e.name,"file-id":e.fileId,"session-id":e.sessionId,"media-class":"att-thumb"},null,8,["url","alt","file-id","session-id"])):e.kind==="video"?(v(),ce(f(ve),{key:1,name:"play",size:"sm"})):e.kind==="image"?(v(),ce(f(ve),{key:2,name:"image",size:"sm"})):(v(),ce(f(ve),{key:3,name:r.value,size:"sm"},null,8,["name"]))]),C("span",Yje,D(l.value),1),e.uploading?(v(),ce(f(Oi),{key:0,size:"sm",label:f(o)("composer.uploading")},null,8,["label"])):e.error?(v(),E("span",Jje,[U(f(ve),{name:"info",size:"sm"})])):X("",!0)],8,Gje),e.removable?(v(),ce(f(gn),{key:0,text:e.removeLabel??f(o)("composer.remove")},{default:de(()=>[C("button",{type:"button",class:"att-rm","aria-label":e.removeLabel??f(o)("composer.remove"),onClick:d[1]||(d[1]=h=>i("remove"))},[U(f(ve),{name:"close",size:"sm"})],8,Xje)]),_:1},8,["text"])):X("",!0)],10,Zje))}}),wH=kt(eHe,[["__scopeId","data-v-37de1632"]]),tHe="/assets/kimi_avatar_default-srYjF2HV.riv",nHe={key:0,class:"mascot-fallback",viewBox:"5 0 240.776 240.776","aria-hidden":"true"},iHe="light/dark",oHe="click_avator",sHe="hoverspace",rHe=Xe({__name:"KimiMascot",setup(e){const t=K(!1),n=K(null),i=a9();let o=null,s=null,r=null;function l(){o!==null&&NS(o,iHe,i.value?1:0)}cn(async()=>{if(!window.matchMedia("(prefers-reduced-motion: reduce)").matches)try{const[{Rive:c,RuntimeLoader:d},h,p]=await Promise.all([Fo(()=>import("./rive-CeXCFBdn.js").then(y=>y.r),__vite__mapDeps([10,5])),Fo(()=>import("./rive-BxcgqsjB.js"),[]).then(y=>y.default),Fo(()=>import("./rive_fallback-ByshBW-N.js"),[]).then(y=>y.default)]),g=n.value;if(!g)return;d.setWasmUrl(h),d.setWasmFallbackUrl(p);const m=new c({canvas:g,src:tHe,autoplay:!0,onLoad(){const y=m.stateMachineNames[0];y!==void 0&&m.play(y),requestAnimationFrame(()=>{n.value&&(l(),m.resizeDrawingSurfaceToCanvas(),r=qB(m,g),t.value=!0)})}});o=m;const k=Pe(i,l),w=()=>m.resizeDrawingSurfaceToCanvas();window.addEventListener("resize",w),s=()=>{r?.(),r=null,k(),window.removeEventListener("resize",w),m.cleanup(),o=null}}catch{}}),Hn(()=>{s?.(),s=null});function a(c){o!==null&&NS(o,sHe,c)}function u(){o!==null&&Ule(o,oHe)}return(c,d)=>(v(),E("div",{class:"mascot-host",role:"img","aria-label":"Kimi mascot",onPointerenter:d[0]||(d[0]=h=>a(!0)),onPointerleave:d[1]||(d[1]=h=>a(!1)),onClick:u},[t.value?X("",!0):(v(),E("svg",nHe,[...d[2]||(d[2]=[$c('<defs data-v-27600ac7><radialGradient id="mascot-body-gradient" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(125.388 105.735) scale(121.866)" data-v-27600ac7><stop stop-color="#117DFB" data-v-27600ac7></stop><stop stop-color="#449BFF" offset="0.759254" data-v-27600ac7></stop><stop stop-color="#77B6FF" offset="1" data-v-27600ac7></stop></radialGradient></defs><g data-v-27600ac7><path d="M125.388 0C191.877 0 245.776 53.8995 245.776 120.388C245.776 186.877 191.877 240.776 125.388 240.776C58.8996 240.776 5 186.877 5 120.388C5 53.8995 58.8996 0 125.388 0Z" fill="#2389FF" data-v-27600ac7></path><path d="M125.388 0C191.877 0 245.776 53.8995 245.776 120.388C245.776 186.877 191.877 240.776 125.388 240.776C58.8996 240.776 5 186.877 5 120.388C5 53.8995 58.8996 0 125.388 0Z" fill="url(#mascot-body-gradient)" data-v-27600ac7></path></g><g transform="translate(-33.4 0)" data-v-27600ac7><g transform="rotate(7.8 127.94 83.94)" data-v-27600ac7><path d="M111.089 73.2179C109.935 64.8166 115.756 57.078 124.091 55.9333C132.426 54.7886 140.117 60.6713 141.271 69.0726L144.785 94.6564C145.939 103.058 140.118 110.796 131.783 111.941C123.449 113.086 115.757 107.203 114.603 98.8018L111.089 73.2179Z" fill="#FFFFFF" data-v-27600ac7></path></g><g transform="translate(0 8.5) rotate(7.8 189.67 75.44)" data-v-27600ac7><path d="M174.422 65.1492C173.326 57.1679 178.518 49.8626 186.019 48.8324C193.52 47.8021 200.489 53.4371 201.586 61.4184L204.924 85.723C206.02 93.7042 200.828 101.01 193.327 102.04C185.825 103.07 178.856 97.435 177.76 89.4538L174.422 65.1492Z" fill="#FFFFFF" data-v-27600ac7></path></g></g>',3)])])),C("canvas",{ref_key:"canvasRef",ref:n,class:Fe(["mascot-canvas",{ready:t.value}])},null,2)],32))}}),lHe=kt(rHe,[["__scopeId","data-v-27600ac7"]]),aHe={class:"working-indicator",role:"status"},uHe={class:"wi-mascot","aria-hidden":"true"},cHe={class:"wi-label"},dHe=Xe({__name:"WorkingIndicator",props:{label:{}},setup(e){return(t,n)=>(v(),E("div",aHe,[C("span",uHe,[U(lHe)]),C("span",cHe,D(e.label),1)]))}}),xH=kt(dHe,[["__scopeId","data-v-8abb44ef"]]),fHe={key:0,class:"chat-loading"},hHe={class:"chat-loading-text"},pHe={key:1,class:"chat-empty"},gHe={key:1,class:"top-sentinel-text"},mHe={key:0,class:"u-turn"},vHe=["data-turn-id"],yHe={key:0,class:"u-media"},kHe={key:1,class:"u-atts"},bHe={key:2,class:"skill-act"},AHe={class:"skill-act-head"},CHe=["aria-expanded","onClick"],wHe={key:0,class:"u-meta"},xHe=["aria-label","onClick"],SHe={class:"u-edit-hint"},_He=["aria-label","onClick"],MHe=["aria-label","onClick"],IHe=["data-turn-id"],EHe=["onClick"],THe={class:"cd-view"},LHe={key:1,class:"cd-label"},NHe=["data-turn-id"],FHe={key:0,class:"goal-prov"},DHe={key:1,class:"msg"},BHe={key:3,class:"a-msg-ft"},$He={key:0,class:"a-time"},RHe=["aria-label","onClick"],zHe={key:4,class:"compact-divider",role:"separator"},OHe={class:"cd-label",role:"status"},PHe={key:3,class:"turn-failed",role:"alert"},jHe={class:"tf-chip","aria-hidden":"true"},HHe={class:"tf-main"},WHe={class:"tf-title"},qHe=["title"],UHe=["title"],KHe={key:5,class:"sending-placeholder"},VHe={key:6,class:"q-stack"},ZHe={class:"q-head"},GHe={class:"q-title"},QHe=["onDragover","onDrop"],YHe=["aria-label","onClick"],JHe={class:"u-bub q-bub"},XHe=["title","onDragstart"],eWe=["title","onClick"],tWe={key:0,class:"u-text q-text"},nWe={key:1,class:"q-text q-text-placeholder"},iWe=["aria-expanded","onClick"],oWe={key:0,class:"q-imgs"},sWe={key:0,class:"q-file"},rWe=["aria-label","onClick"],lWe=["aria-label","onClick"],aWe={key:0,class:"open-unsupported",role:"status"},uWe=2500,cWe=10,dWe=3,fWe=Xe({__name:"ChatPane",props:{turns:{},cwd:{},turnFilesInteractive:{type:Boolean,default:!0},approvals:{default:()=>[]},questions:{default:()=>[]},turnActive:{type:Boolean,default:!1},working:{type:Boolean,default:!1},sessionLoading:{type:Boolean},compaction:{default:null},hasMoreMessages:{type:Boolean,default:!1},loadingMore:{type:Boolean,default:!1},loadingMoreError:{type:Boolean,default:!1},isFollowing:{type:Boolean,default:!1},readOnly:{type:Boolean,default:!1},inspector:{type:Boolean,default:!1},queued:{default:()=>[]},undoHintTurnId:{default:null},interruptedTurnId:{default:null},turnFailed:{type:Boolean,default:!1},turnError:{default:null},turnRetry:{default:null}},emits:["openFile","openMedia","openTurnDiff","copyConversationCopied","openCompaction","openAgent","editMessage","armedUndo","loadOlderMessages","unqueue","editQueued","reorderQueue","steerQueued","resumeTurn"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),{confirm:o}=Vc();_n(()=>{Q!==null&&(clearTimeout(Q),Q=null),oe!==null&&(clearTimeout(oe),oe=null),Z!==null&&(clearTimeout(Z),Z=null),Le!==null&&(clearTimeout(Le),Le=null)});const s=e,r=K(null);let l=null;function a(){!r.value||typeof IntersectionObserver>"u"||(l?.disconnect(),l=new IntersectionObserver(He=>{He[0]?.isIntersecting&&s.hasMoreMessages&&!s.loadingMore&&!s.loadingMoreError&&!s.sessionLoading&&!s.isFollowing&&w("loadOlderMessages")},{root:null,rootMargin:"200px 0px 0px 0px",threshold:0}),l.observe(r.value))}cn(a),_n(()=>{l?.disconnect(),l=null});const u=K(null);let c=null;cn(()=>{c=y$e(()=>u.value)}),_n(()=>{c?.(),c=null}),Pe(()=>[s.hasMoreMessages,s.loadingMore,s.loadingMoreError],()=>{dt().then(a)});const d=F(()=>{if(!s.turnActive||s.turns.length===0)return null;const He=s.turns.at(-1);return He.role==="assistant"?He.id:null}),h=F(()=>{const He=new Map;for(const st of s.turns){if(st.role!=="assistant"||st.id===d.value)continue;const et=Yze(st);et.length>0&&He.set(st.id,et)}return He}),p=F(()=>s.working),g=F(()=>{const He=s.turnRetry;if(He!=null)return i("conversation.workingRetry",{n:He.nextAttempt,max:He.maxAttempts});const st=s.turns.at(-1),et=st?.role==="assistant"&&(st.text.trim().length>0||(st.thinking?.trim().length??0)>0||(st.tools?.length??0)>0);return i(et?"conversation.working":"conversation.requesting")}),m=F(()=>s.turnError?.code==="loop.max_steps_exceeded"?i("conversation.turnFailedMaxSteps"):i("conversation.turnFailed")),k=F(()=>{const He=s.turnError;if(!He)return"";const st=[];return He.code!==void 0&&He.code.length>0&&st.push(He.code),He.statusCode!==void 0&&st.push(`HTTP ${He.statusCode}`),He.requestId!==void 0&&He.requestId.length>0&&st.push(He.requestId),st.join(" · ")}),w=n,y=He=>w("openFile",He),b=He=>w("openMedia",He),A=He=>w("openAgent",He),T=He=>w("openTurnDiff",He),S=K(null),x=K(null);function _(He){return(He.attachments?.length??0)>0}function L(He){w("editQueued",He)}function M(He){typeof window<"u"&&window.matchMedia("(hover: none)").matches||L(He)}function N(He,st){if(S.value=He,!st.dataTransfer)return;st.dataTransfer.effectAllowed="move",st.dataTransfer.setData("text/plain",String(He));const et=st.currentTarget?.closest(".q-turn");et&&st.dataTransfer.setDragImage(et,24,24)}function I(He,st){if(S.value===null)return;st.preventDefault(),st.dataTransfer&&(st.dataTransfer.dropEffect="move");const et=st.currentTarget.getBoundingClientRect(),Nt=st.clientY<et.top+et.height/2?"before":"after";x.value={index:He,position:Nt}}function z(He,st){st.preventDefault();const et=S.value,Nt=x.value?.position??"before";if(S.value=null,x.value=null,et===null)return;let Lt=Nt==="before"?He:He+1;et<Lt&&(Lt-=1),et!==Lt&&w("reorderQueue",{from:et,to:Lt})}function H(){S.value=null,x.value=null}const O=F(()=>{for(let He=s.turns.length-1;He>=0;He--){const st=s.turns[He];if(st.goalContinuation)return null;if(st.role==="user")return st.id}return null});function R(He){return!s.readOnly&&He.role==="user"&&He.id===O.value&&!s.working&&!He.pluginCommand&&!(He.skillActivation&&!vj(He.skillActivation,{revivePill:!1}))}function j(He){const st=He.compaction,et=st?.trigger==="auto"?i("conversation.compactedAuto"):i("conversation.compactedPlain");return typeof st?.tokensBefore=="number"&&typeof st?.tokensAfter=="number"?et+i("conversation.compactedTokens",{before:_u(st.tokensBefore),after:_u(st.tokensAfter)}):et}const $=K(null);function W(He){const st=He.createdAt===void 0?NaN:Date.parse(He.createdAt),et=He.endedAt??(Number.isFinite(st)&&He.durationMs!==void 0?new Date(st+He.durationMs).toISOString():He.createdAt);return et===void 0?"":_B(et,i("conversation.yesterday"))}const P=K(null);let Z=null;async function ae(He){await o({title:i("conversation.undo"),message:i("conversation.undoConfirm"),variant:"primary"})&&V(He)}function V(He){if(P.value!==null)return;P.value=He.id;const st=He.skillActivation?fA(He.skillActivation,{revivePill:!1})??He.text:He.text;w("editMessage",{text:st,attachments:He.attachments}),Z=setTimeout(()=>{Z=null,P.value=null},uWe)}Pe(()=>s.turns,He=>{P.value!==null&&(He.some(st=>st.id===P.value)||(P.value=null,Z!==null&&(clearTimeout(Z),Z=null)))},{flush:"post"});const Y=K(!1);let oe=null;function q(){if(s.turns.length===0)return;const He=[];for(const et of s.turns){if(et.role==="compaction"||et.role==="cron")continue;const Nt=et.role==="user"?"User":"Assistant",Lt=Kze(et);Lt.trim()&&He.push(`**${Nt}** - -${Lt}`)}const st=He.join(` - ---- - -`);Xo(st).then(et=>{et&&(Y.value=!0,w("copyConversationCopied"),oe!==null&&clearTimeout(oe),oe=setTimeout(()=>{oe=null,Y.value=!1},2e3))}).catch(()=>{})}function ne(He){const st=[];for(let et=He;et>=0;et--){const Nt=s.turns[et];if(!Nt||Nt.role!=="assistant")break;st.unshift(Nt)}return st}function ie(He){return ne(He).map(st=>Uze(st)).filter(Boolean).join(` - -`)}function pe(He){return ne(He).some(S5)}function Ne(){for(let He=s.turns.length-1;He>=0;He-=1)if(s.turns[He]?.role==="assistant")return ie(He);return""}function te(){const He=Ne();He.trim()&&Xo(He).then(st=>{st&&(Y.value=!0,w("copyConversationCopied"),oe!==null&&clearTimeout(oe),oe=setTimeout(()=>{oe=null,Y.value=!1},2e3))}).catch(()=>{})}t({copyConversation:q,copyFinalSummary:te});function be(He){const st=s.turns[He];if(!st||st.role!=="assistant")return!1;const et=s.turns[He+1];return!et||et.role!=="assistant"}let Q=null;function ue(He){const st=s.turns[He];if(!st)return;const et=ie(He);et.trim()&&Xo(et).then(Nt=>{Nt&&($.value=st.id,Q!==null&&clearTimeout(Q),Q=setTimeout(()=>{Q=null,$.value=null},1400))}).catch(()=>{})}function Ae(He){const st=He.text;st.trim()&&Xo(st).then(et=>{et&&($.value=He.id,Q!==null&&clearTimeout(Q),Q=setTimeout(()=>{Q=null,$.value=null},1400))}).catch(()=>{})}const se=jo(new Set),re=jo(new Set),G=new Map,le=new WeakMap,ge=hn("pinScroll",()=>{}),ke=new ResizeObserver(He=>{for(const st of He){const et=st.target,Nt=le.get(et);Nt!==void 0&&Ie(Nt,et)}});_n(()=>ke.disconnect());function Ie(He,st){const et=parseFloat(getComputedStyle(st).lineHeight);if(!Number.isFinite(et)||et<=0)return;const Lt=(st.textContent??"").match(/\n+$/)?.[0].length??0,qn=st.scrollHeight-Math.max(0,Lt-1)*et,So=He.startsWith("queue:")?dWe:cWe;qn>et*So+1?se.add(He):se.delete(He)}function Oe(He,st){if(!(st instanceof HTMLElement)||G.get(He)===st)return;const et=G.get(He);et!==void 0&&ke.unobserve(et),G.set(He,st),le.set(st,He),ke.observe(st),Ie(He,st)}function we(He){return`queue:${He.id}`}Pe([()=>s.turns,()=>s.queued],()=>{const He=new Set(s.turns.map(st=>st.id));for(const st of s.queued)He.add(we(st));for(const[st,et]of G)He.has(st)||(ke.unobserve(et),G.delete(st),se.delete(st),re.delete(st))});function Be(He){if(He.skillActivation){const st=He.skillActivation;if(mj(st))return st.args??null;const et=cA({kind:"skill",name:st.name,path:""});return st.args?`${et} ${st.args}`:et}return He.pluginCommand?He.pluginCommand.args||null:He.text||null}function tt(He){return He.pluginCommand!==void 0}function ut(He){return se.has(He)&&!re.has(He)}function _t(He,st){const et=re.has(He);et&&st.currentTarget instanceof HTMLElement&&ge(st.currentTarget),et?re.delete(He):re.add(He)}function Ct(He){return He.kind==="image"||He.kind==="video"}function $t(He){return(He.attachments??[]).filter(Ct)}function Vt(He){return(He.attachments??[]).filter(st=>!Ct(st))}function nn(He){return{kind:He.kind==="video"?"video":"image",url:He.url,path:He.name,fileId:He.fileId,sessionId:He.sessionId}}const gt=K(null);let Le=null;const ze=K(null),Ye=K(null);function Tt(He,st){if(He.kind==="image"||He.kind==="video"){Ye.value=st??null,ze.value=nn(He);return}He.fileId!==void 0&&dH(Ic(),He.fileId,He.name,He.mediaType).then(et=>{et==="unsupported"&&(gt.value=He.name??He.fileId??"",Le!==null&&clearTimeout(Le),Le=setTimeout(()=>{Le=null,gt.value=null},2400))})}function on(He,st){return He.id!==d.value||st.kind==="thinking"&&st.durationMs!==void 0?!1:st.sourceIndex===vu(He).length-1}function jt(He,st){if(He.id!==d.value)return!1;const et=st.items.at(-1);return et?.kind==="thinking"&&et.durationMs!==void 0?!1:et!==void 0&&et.sourceIndex===vu(He).length-1}const kn={folded:[],visible:[]};function bn(He){return He.role!=="assistant"?kn:iH(He)}function mn(He){const st=bn(He);return s.inspector?Hze(st):st.visible}function zn(He){if(He.id!==d.value)return null;const st=vu(He),et=st.at(-1);if(et?.kind==="thinking"&&et.durationMs!==void 0)return null;if(et?.kind==="tool"&&et.tool.status==="running"){const Nt=et.tool.id;if(s.approvals?.some(Lt=>Lt.toolCallId===Nt)||s.questions?.some(Lt=>Lt.toolCallId===Nt))return null}return st.length-1}return(He,st)=>(v(),E(Ee,null,[C("div",{class:"chat",ref_key:"chatRootRef",ref:u},[e.sessionLoading?(v(),E("div",fHe,[U(f(Oi),{size:"sm"}),C("span",hHe,D(f(i)("conversation.loading")),1)])):e.turns.length===0&&(!e.approvals||e.approvals.length===0)?(v(),E("div",pHe)):X("",!0),e.hasMoreMessages||e.loadingMore?(v(),E("div",{key:2,ref_key:"topSentinelRef",ref:r,class:Fe(["top-sentinel",{"top-sentinel-loading":e.loadingMore}])},[e.loadingMore?(v(),E("span",gHe,[U(f(Oi),{size:"sm"}),$e(" "+D(f(i)("conversation.loadingOlder")),1)])):(v(),E("button",{key:0,type:"button",class:"top-sentinel-btn",onClick:st[0]||(st[0]=et=>w("loadOlderMessages"))},D(f(i)("conversation.loadOlder")),1))],2)):X("",!0),(v(!0),E(Ee,null,pt(e.turns,(et,Nt)=>(v(),E(Ee,{key:et.id},[et.role==="user"?(v(),E("div",mHe,[C("div",{class:Fe(["u-bub turn-anchor",{undoing:P.value===et.id}]),"data-turn-id":et.id},[$t(et).length>0?(v(),E("div",yHe,[(v(!0),E(Ee,null,pt($t(et),(Lt,qn)=>(v(),ce(CH,{key:qn,kind:Lt.kind,name:Lt.name,url:Lt.url,"file-id":Lt.fileId,"session-id":Lt.sessionId,onActivate:So=>Tt(Lt,So)},null,8,["kind","name","url","file-id","session-id","onActivate"]))),128))])):X("",!0),Vt(et).length>0?(v(),E("div",kHe,[(v(!0),E(Ee,null,pt(Vt(et),(Lt,qn)=>(v(),ce(wH,{key:qn,kind:Lt.kind,name:Lt.name,url:Lt.url,"file-id":Lt.fileId,"media-type":Lt.mediaType,size:Lt.size,onActivate:So=>Tt(Lt)},null,8,["kind","name","url","file-id","media-type","size","onActivate"]))),128))])):X("",!0),et.pluginCommand?(v(),E("div",bHe,[C("div",AHe,[st[3]||(st[3]=C("span",{class:"skill-act-arrow"},"▶",-1)),C("span",null,"/"+D(et.pluginCommand.pluginId)+":"+D(et.pluginCommand.commandName),1)])])):X("",!0),Be(et)!==null?(v(),E("div",{key:3,class:Fe(["u-text-wrap",{"is-clamped":ut(et.id),"u-text-wrap-args":tt(et)}])},[C("div",{class:Fe(tt(et)?"skill-act-args":"u-text"),ref_for:!0,ref:Lt=>Oe(et.id,Lt)},[U(f(eL),{text:Be(et)??"","open-file":y},null,8,["text"])],2),se.has(et.id)?(v(),E("button",{key:0,type:"button",class:"u-text-toggle","aria-expanded":!ut(et.id),onClick:Lt=>_t(et.id,Lt)},[C("span",null,D(ut(et.id)?f(i)("conversation.userMessage.expand"):f(i)("conversation.userMessage.collapse")),1),U(f(ve),{class:"u-text-toggle-car",name:"chevron-down",size:"sm","aria-hidden":"true"})],8,CHe)):X("",!0)],2)):X("",!0)],10,vHe),et.createdAt||R(et)||!e.readOnly&&e.undoHintTurnId===et.id?(v(),E("div",wHe,[R(et)||!e.readOnly&&e.undoHintTurnId===et.id?(v(),E("div",{key:0,class:Fe(["u-edit-wrap",{undoing:P.value===et.id}])},[e.undoHintTurnId===et.id?(v(),ce(f(gn),{key:0,text:f(i)("conversation.undoTooltip")},{default:de(()=>[C("button",{type:"button",class:"u-edit u-edit-armed","aria-label":f(i)("conversation.undoTooltip"),onClick:Lt=>w("armedUndo",et.id)},[U(f(ve),{name:"undo",size:"sm"}),C("span",SHe,[$e(D(f(i)("conversation.escUndoHintPre")),1),U(f(ku),{keys:["Esc"]}),$e(D(f(i)("conversation.escUndoHintPost")),1)])],8,xHe)]),_:2},1032,["text"])):(v(),ce(f(gn),{key:1,text:f(i)("conversation.undoTooltip")},{default:de(()=>[C("button",{type:"button",class:"u-edit","aria-label":f(i)("conversation.undoTooltip"),onClick:Lt=>ae(et)},[U(f(ve),{name:"undo",size:"sm"})],8,_He)]),_:2},1032,["text"]))],2)):X("",!0),U(f(gn),{text:f(i)("filePreview.copy")},{default:de(()=>[et.text.trim().length>0?(v(),E("button",{key:0,type:"button",class:"u-copy","aria-label":f(i)("filePreview.copy"),onClick:wt(Lt=>Ae(et),["stop"])},[$.value!==et.id?(v(),ce(f(ve),{key:0,name:"copy",size:"sm"})):(v(),ce(f(ve),{key:1,name:"check",size:"sm"}))],8,MHe)):X("",!0)]),_:2},1032,["text"]),et.createdAt?(v(),ce(_A,{key:1,time:et.createdAt},null,8,["time"])):X("",!0)])):X("",!0)])):et.role==="compaction"?(v(),E("div",{key:1,class:"compact-divider turn-anchor","data-turn-id":et.id,role:"separator"},[st[4]||(st[4]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1)),et.text?(v(),E("button",{key:0,type:"button",class:"cd-label cd-btn",onClick:Lt=>w("openCompaction",{turnId:et.id})},[C("span",null,D(j(et)),1),C("span",THe,D(f(i)("conversation.viewSummary")),1)],8,EHe)):(v(),E("span",LHe,D(j(et)),1)),st[5]||(st[5]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1))],8,IHe)):et.role==="cron"?(v(),ce(kPe,{key:2,text:et.text,cron:et.cron,"turn-id":et.id,"created-at":et.createdAt},null,8,["text","cron","turn-id","created-at"])):(v(),E("div",{key:3,class:"a-msg turn-anchor","data-turn-id":et.id},[et.goalContinuation?(v(),E("div",FHe,[U(f(ve),{name:"target",size:"sm","aria-hidden":"true"}),C("span",null,D(f(i)("conversation.goal.continuation")),1)])):X("",!0),!e.inspector&&bn(et).folded.length>0?(v(),ce(UOe,{key:1,items:bn(et).folded,mobile:"","streaming-tail-index":zn(et),live:et.id===d.value,parked:et.id===d.value&&zn(et)===null,"seed-ms":f(Wze)(f(vu)(et)),"created-ms":f(dL)(et.createdAt),"ended-ms":f(dL)(et.endedAt),"duration-ms":et.durationMs,onOpenMedia:b,onOpenFile:y,onOpenAgent:A},null,8,["items","streaming-tail-index","live","parked","seed-ms","created-ms","ended-ms","duration-ms"])):X("",!0),(v(!0),E(Ee,null,pt(mn(et),(Lt,qn)=>(v(),E(Ee,{key:f(sH)(Lt,qn)},[Lt.kind==="thinking"?(v(),ce(SA,{key:0,text:Lt.thinking,mobile:"",streaming:on(et,Lt),"started-at":Lt.startedAt,"duration-ms":Lt.durationMs,"instant-reveal":e.inspector},null,8,["text","streaming","started-at","duration-ms","instant-reveal"])):Lt.kind==="text"&&Lt.text?(v(),E("div",DHe,[U(f(Iu),{text:Lt.text,streaming:on(et,Lt),"open-file":y},null,8,["text","streaming"])])):Lt.kind==="activity-run"?(v(),ce(lH,{key:2,items:Lt.items,mobile:"",streaming:jt(et,Lt),"force-open":e.inspector,onOpenMedia:b,onOpenFile:y,onOpenAgent:A},null,8,["items","streaming","force-open"])):Lt.kind==="tool"?(v(),ce(xA,{key:3,tool:Lt.tool,mobile:"",onOpenMedia:b,onOpenFile:y,onOpenAgent:A},null,8,["tool"])):Lt.kind==="notification"?(v(),ce(aH,{key:4,items:Lt.items},null,8,["items"])):X("",!0)],64))),128)),h.value.get(et.id)?(v(),ce(rPe,{key:2,changes:h.value.get(et.id),cwd:s.cwd,interactive:e.turnFilesInteractive,onOpenDiff:T,onOpenFile:y},null,8,["changes","cwd","interactive"])):X("",!0),!e.inspector&&et.id!==d.value&&be(Nt)&&pe(Nt)&&(ie(Nt).trim().length>0||W(et))?(v(),E("div",BHe,[W(et)?(v(),E("span",$He,D(W(et)),1)):X("",!0),U(f(gn),{text:f(i)("filePreview.copy")},{default:de(()=>[ie(Nt).trim().length>0?(v(),E("button",{key:0,class:"a-cpbtn","aria-label":f(i)("filePreview.copy"),onClick:Lt=>ue(Nt)},[$.value!==et.id?(v(),ce(f(ve),{key:0,name:"copy",size:"sm"})):(v(),ce(f(ve),{key:1,name:"check",size:"sm"}))],8,RHe)):X("",!0)]),_:2},1032,["text"])])):X("",!0)],8,NHe)),et.role==="assistant"&&et.id===e.interruptedTurnId?(v(),E("div",zHe,[st[6]||(st[6]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1)),C("span",OHe,D(f(i)("conversation.turnInterrupted")),1),st[7]||(st[7]=C("span",{class:"cd-line","aria-hidden":"true"},null,-1))])):X("",!0)],64))),128)),e.turnFailed?(v(),E("div",PHe,[C("span",jHe,[U(f(ve),{name:"alert-triangle",size:"sm"})]),C("div",HHe,[C("span",WHe,D(m.value),1),e.turnError?.message?(v(),E("span",{key:0,class:"tf-sub",title:e.turnError.message},D(e.turnError.message),9,qHe)):X("",!0),k.value?(v(),E("span",{key:1,class:"tf-meta",title:k.value},D(k.value),9,UHe)):X("",!0)]),e.readOnly?X("",!0):(v(),ce(f(Qt),{key:0,variant:"secondary",size:"sm",onClick:st[1]||(st[1]=et=>w("resumeTurn"))},{default:de(()=>[$e(D(f(i)("conversation.turnFailedResume")),1)]),_:1}))])):X("",!0),e.compaction?(v(),ce(dPe,{key:4,label:f(i)("conversation.compacting")},null,8,["label"])):X("",!0),p.value?(v(),E("div",KHe,[U(xH,{label:g.value},null,8,["label"])])):X("",!0),e.queued.length>0?(v(),E("div",VHe,[C("div",ZHe,[C("span",GHe,[U(f(ve),{name:"mail",size:"sm"}),$e(" "+D(f(i)("composer.queueLabel"))+" · ",1),C("b",null,D(f(i)("composer.queuePending",{n:e.queued.length})),1)])]),(v(!0),E(Ee,null,pt(e.queued,(et,Nt)=>(v(),E("div",{key:et.id,class:Fe(["u-turn q-turn",{"q-dragging":S.value===Nt,"drop-before":x.value?.index===Nt&&x.value.position==="before","drop-after":x.value?.index===Nt&&x.value.position==="after"}]),onDragover:Lt=>I(Nt,Lt),onDrop:Lt=>z(Nt,Lt)},[Nt===0?(v(),ce(f(gn),{key:0,text:f(i)("composer.queueSteer")},{default:de(()=>[C("button",{type:"button",class:"q-send","aria-label":f(i)("composer.queueSteer"),onClick:wt(Lt=>w("steerQueued",Nt),["stop"])},[U(f(ve),{name:"send",size:"lg"})],8,YHe)]),_:2},1032,["text"])):X("",!0),C("div",JHe,[C("span",{class:"q-grip",title:f(i)("composer.queueDragTitle"),draggable:"true",onDragstart:Lt=>N(Nt,Lt),onDragend:H},[U(f(ve),{name:"grip",size:"sm"})],40,XHe),C("div",{class:Fe(["q-clamp u-text-wrap",{"is-clamped":ut(we(et))}])},[C("button",{type:"button",class:"q-body",title:f(i)("composer.editQueued"),ref_for:!0,ref:Lt=>Oe(we(et),Lt),onClick:Lt=>M(Nt)},[et.text?(v(),E("span",tWe,[U(f(eL),{text:et.text,interactive:!1},null,8,["text"])])):(v(),E("span",nWe,[U(f(ve),{name:"file",size:"sm"}),$e(" "+D(f(i)("composer.queuedAttachments",{n:et.attachments?.length??0})),1)]))],8,eWe),se.has(we(et))?(v(),E("button",{key:0,type:"button",class:"u-text-toggle","aria-expanded":!ut(we(et)),onClick:Lt=>_t(we(et),Lt)},[C("span",null,D(ut(we(et))?f(i)("conversation.userMessage.expand"):f(i)("conversation.userMessage.collapse")),1),U(f(ve),{class:"u-text-toggle-car",name:"chevron-down",size:"sm","aria-hidden":"true"})],8,iWe)):X("",!0)],2),_(et)?(v(),E("div",oWe,[(v(!0),E(Ee,null,pt(et.attachments,(Lt,qn)=>(v(),E(Ee,{key:qn},[Lt.kind==="file"?(v(),E("span",sWe,[U(f(ve),{name:"file",size:"sm"}),$e(" "+D(Lt.name??Lt.fileId),1)])):(v(),ce(hg,{key:1,url:Lt.url,kind:Lt.kind,"file-id":Lt.fileId,"session-id":Lt.sessionId,"media-class":"q-img",controls:!1,muted:""},null,8,["url","kind","file-id","session-id"]))],64))),128))])):X("",!0),C("button",{type:"button",class:"q-edit","aria-label":f(i)("composer.editQueued"),onClick:wt(Lt=>L(Nt),["stop"])},[U(f(ve),{name:"pencil",size:"sm"})],8,rWe),U(f(gn),{text:f(i)("composer.remove")},{default:de(()=>[C("button",{type:"button",class:"q-rm","aria-label":f(i)("composer.remove"),onClick:wt(Lt=>w("unqueue",Nt),["stop"])},[U(f(ve),{name:"close",size:"sm"})],8,lWe)]),_:2},1032,["text"])])],42,QHe))),128))])):X("",!0)],512),gt.value!==null?(v(),E("div",aWe,D(f(i)("composer.attachmentOpenUnsupported",{name:gt.value})),1)):X("",!0),ze.value?(v(),ce(IA,{key:1,media:ze.value,"origin-img":Ye.value,onClose:st[2]||(st[2]=et=>{ze.value=null,Ye.value=null})},null,8,["media","origin-img"])):X("",!0)],64))}}),EA=kt(fWe,[["__scopeId","data-v-765caf09"]]),hWe={class:"ch-id"},pWe=["title"],gWe={key:1,class:"ch-ws"},mWe={key:2,class:"ch-sep"},vWe=["onKeydown"],yWe={class:"ch-ses"},kWe={key:0,class:"ch-pill ch-sync-pill"},bWe={key:0,class:"ch-ahead"},AWe={key:1,class:"ch-behind"},CWe={key:1,class:"ch-pill ch-diff-pill"},wWe={key:0,class:"ch-add"},xWe={key:1,class:"ch-del"},SWe={class:"ch-pill ch-pr pr-merged ch-done-pill"},_We=Xe({__name:"ChatHeader",props:{sessionId:{},workspaceName:{},workspaceRoot:{},sessionTitle:{},branch:{},ahead:{},behind:{},changesCount:{},gitDiffStats:{},isGitRepo:{type:Boolean},pr:{},copied:{type:Boolean},archived:{type:Boolean},pinned:{type:Boolean}},emits:["copyAll","copyFinalSummary","openChanges","openPr","renameSession","forkSession","togglePin","archiveSession","restoreSession","exportSession"],setup(e,{emit:t}){const{t:n}=zt(),{sidebarTabs:i}=d1(),o=e,s=t,r=F(()=>o.ahead??0),l=F(()=>o.behind??0),a=F(()=>o.gitDiffStats?.totalAdditions??0),u=F(()=>o.gitDiffStats?.totalDeletions??0),c=F(()=>a.value>0||u.value>0),d={open:"header.prStatusOpen",closed:"header.prStatusClosed",merged:"header.prStatusMerged",draft:"header.prStatusDraft"};function h(ne){return ne.trim().toLowerCase().replaceAll("_","-")}function p(ne){const ie=h(ne);return d[ie]?`pr-${ie}`:"pr-unknown"}function g(ne){return n(d[h(ne)]??"header.prStatusUnknown")}const m=K(!1),k=K(null),w=K(null),y=K({});function b(ne){const ie=ne.target;w.value?.el?.contains(ie)||k.value?.el?.contains(ie)||S()}function A(){S()}async function T(ne){if(ne.stopPropagation(),m.value){S();return}m.value=!0,document.addEventListener("mousedown",b),window.addEventListener("resize",A),await dt();const ie=k.value?.el,pe=w.value?.el;if(!ie||!pe)return;const Ne=ie.getBoundingClientRect(),te=4,be=8,Q=pe.offsetWidth,ue=pe.offsetHeight;let Ae=Ne.bottom+te,se=!1;Ae+ue>window.innerHeight-be&&(Ae=Math.max(be,Ne.top-ue-te),se=!0);let re=Ne.left,G=!1;re+Q>window.innerWidth-be&&(re=Math.max(be,Ne.right-Q),G=!0),y.value={top:`${Math.round(Ae)}px`,left:`${Math.round(re)}px`,transformOrigin:`${se?"bottom":"top"} ${G?"right":"left"}`,"--menu-pop-shift":se?"2px":"-2px"}}function S(){m.value=!1,document.removeEventListener("mousedown",b),window.removeEventListener("resize",A)}_n(()=>{document.removeEventListener("mousedown",b),window.removeEventListener("resize",A)});function x(){s("copyAll"),S()}function _(){s("copyFinalSummary"),S()}const L=K(!1);function M(){o.sessionId&&Xo(o.sessionId).then(ne=>{ne&&(L.value=!0,setTimeout(()=>{L.value=!1},1200))})}const N=K(!1),I=K(""),z=K(null),{handleCompositionStart:H,handleCompositionEnd:O,isComposingKeyEvent:R}=bl();async function j(){if(S(),!!o.sessionId){N.value=!0,I.value=o.sessionTitle??"",await dt();try{z.value?.focus(),z.value?.select()}catch{}}}function $(){const ne=I.value.trim();ne&&o.sessionId&&ne!==(o.sessionTitle??"").trim()&&s("renameSession",o.sessionId,ne),N.value=!1}function W(ne){R(ne)||$()}function P(){N.value=!1}function Z(){o.sessionId&&(S(),s("togglePin",o.sessionId))}function ae(){o.sessionId&&(S(),s("forkSession",o.sessionId))}function V(){o.sessionId&&(S(),s("exportSession",o.sessionId))}function Y(){o.sessionId&&(S(),s("archiveSession",o.sessionId))}function oe(){o.sessionId&&(S(),s("restoreSession",o.sessionId))}const q=!1;return(ne,ie)=>(v(),E("header",{class:Fe(["chat-header",{"macos-desktop":f(pc)}])},[C("div",hWe,[f(q)?(v(),E("span",{key:0,class:"ch-dev",title:f(n)("header.devBadge")},"DEV",8,pWe)):X("",!0),e.workspaceName?(v(),E("span",gWe,D(e.workspaceName),1)):X("",!0),e.workspaceName&&e.sessionTitle?(v(),E("span",mWe,"/")):X("",!0),N.value?Wn((v(),E("input",{key:3,ref_key:"renameInputRef",ref:z,"onUpdate:modelValue":ie[0]||(ie[0]=pe=>I.value=pe),class:"ch-rename",type:"text",onKeydown:[Ho(wt(W,["stop"]),["enter"]),Ho(wt(P,["stop"]),["esc"])],onCompositionstart:ie[1]||(ie[1]=(...pe)=>f(H)&&f(H)(...pe)),onCompositionend:ie[2]||(ie[2]=(...pe)=>f(O)&&f(O)(...pe)),onBlur:$,onClick:ie[3]||(ie[3]=wt(()=>{},["stop"]))},null,40,vWe)),[[Bs,I.value]]):e.sessionTitle?(v(),ce(f(gn),{key:4,text:e.sessionTitle},{default:de(()=>[C("span",yWe,D(e.sessionTitle),1)]),_:1},8,["text"])):X("",!0)]),U(f(Jt),{ref_key:"kebabRef",ref:k,class:Fe(["ch-act-more",{open:m.value}]),label:f(n)("header.options"),tooltip:f(n)("header.options"),"aria-expanded":m.value,"aria-haspopup":"menu",onClick:ie[4]||(ie[4]=wt(pe=>T(pe),["stop"]))},{default:de(()=>[U(f(ve),{name:"dots-horizontal",size:"sm"})]),_:1},8,["class","label","tooltip","aria-expanded"]),U(fo,{name:"menu-pop"},{default:de(()=>[m.value?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:w,class:"ch-menu",style:Kt(y.value),onClick:ie[5]||(ie[5]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{onClick:x},{default:de(()=>[U(f(ve),{name:e.copied?"check":"copy",size:"sm"},null,8,["name"]),$e(" "+D(e.copied?f(n)("header.copied"):f(n)("header.copyAll")),1)]),_:1}),U(f(Ut),{onClick:_},{default:de(()=>[U(f(ve),{name:"file-text",size:"sm"}),$e(" "+D(f(n)("header.copyFinalSummary")),1)]),_:1}),e.sessionId?(v(),E(Ee,{key:0},[U(f(Ut),{separator:""}),U(f(Ut),{onClick:M},{default:de(()=>[U(f(ve),{name:L.value?"check":"copy",size:"sm"},null,8,["name"]),$e(" "+D(L.value?f(n)("header.copied"):f(n)("header.copySessionId")),1)]),_:1}),e.archived?X("",!0):(v(),ce(f(Ut),{key:0,onClick:Z},{default:de(()=>[U(f(ve),{name:e.pinned?"unpin":"pin",size:"sm"},null,8,["name"]),$e(" "+D(e.pinned?f(n)("header.unpinSession"):f(n)("header.pinSession")),1)]),_:1})),U(f(Ut),{onClick:j},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(n)("header.renameSession")),1)]),_:1}),U(f(Ut),{onClick:ae},{default:de(()=>[U(f(ve),{name:"git-fork",size:"sm"}),$e(" "+D(f(n)("header.forkSession")),1)]),_:1}),U(f(Ut),{onClick:V},{default:de(()=>[U(f(ve),{name:"download",size:"sm"}),$e(" "+D(f(n)("header.exportSession")),1)]),_:1}),e.archived&&f(i)?(v(),ce(f(Ut),{key:1,onClick:oe},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),$e(" "+D(f(n)("header.reopenSession")),1)]),_:1})):X("",!0),e.archived?X("",!0):(v(),ce(f(Ut),{key:2,onClick:Y},{default:de(()=>[U(f(ve),{name:f(i)?"state-done":"archive",size:"sm"},null,8,["name"]),$e(" "+D(f(i)?f(n)("header.markSessionDone"):f(n)("header.archiveSession")),1)]),_:1}))],64)):X("",!0)]),_:1},8,["style"])):X("",!0)]),_:1}),ie[8]||(ie[8]=C("div",{class:"ch-spacer"},null,-1)),e.isGitRepo?(v(),E("button",{key:0,type:"button",class:"ch-git",onClick:ie[6]||(ie[6]=pe=>s("openChanges"))},[U(f(ve),{class:"ch-branch-icon",name:"git-fork",size:"sm"}),C("span",{class:Fe(["ch-branch",{"ch-detached":!e.branch}])},D(e.branch||f(n)("header.detached")),3),r.value>0||l.value>0?(v(),E("span",kWe,[r.value>0?(v(),E("span",bWe,"↑"+D(r.value),1)):X("",!0),l.value>0?(v(),E("span",AWe,"↓"+D(l.value),1)):X("",!0)])):X("",!0),c.value?(v(),E("span",CWe,[a.value>0?(v(),E("span",wWe,"+"+D(a.value),1)):X("",!0),u.value>0?(v(),E("span",xWe,"-"+D(u.value),1)):X("",!0)])):X("",!0)])):X("",!0),e.pr?(v(),E("button",{key:1,type:"button",class:Fe(["ch-pill ch-pr",p(e.pr.state)]),onClick:ie[7]||(ie[7]=pe=>e.pr&&s("openPr",e.pr.url))},[U(f(ve),{name:"git-pull-request",size:"sm"}),C("span",null,"PR #"+D(e.pr.number)+" · "+D(g(e.pr.state)),1)],2)):X("",!0),e.sessionId&&e.archived&&f(i)?(v(),E(Ee,{key:2},[C("span",SWe,[U(f(ve),{name:"state-done",size:"sm"}),C("span",null,D(f(n)("header.sessionDone")),1)]),U(f(Qt),{variant:"secondary",size:"sm",onClick:oe},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),$e(" "+D(f(n)("header.reopenSession")),1)]),_:1})],64)):X("",!0)],2))}}),MWe=kt(_We,[["__scopeId","data-v-2fde3f1e"]]),IWe=["BN","BN","BN","BN","BN","BN","BN","BN","BN","S","B","S","WS","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","B","B","B","S","WS","ON","ON","ET","ET","ET","ON","ON","ON","ON","ON","ES","CS","ES","CS","CS","EN","EN","EN","EN","EN","EN","EN","EN","EN","EN","CS","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","ON","ON","ON","BN","BN","BN","BN","BN","BN","B","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","BN","CS","ON","ET","ET","ET","ET","ON","ON","ON","ON","L","ON","ON","BN","ON","ON","ET","ET","EN","EN","ON","L","ON","ON","ON","EN","L","ON","ON","ON","ON","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","L","ON","L","L","L","L","L","L","L","L"],CL=[[697,698,"ON"],[706,719,"ON"],[722,735,"ON"],[741,749,"ON"],[751,767,"ON"],[768,879,"NSM"],[884,885,"ON"],[894,894,"ON"],[900,901,"ON"],[903,903,"ON"],[1014,1014,"ON"],[1155,1161,"NSM"],[1418,1418,"ON"],[1421,1422,"ON"],[1423,1423,"ET"],[1424,1424,"R"],[1425,1469,"NSM"],[1470,1470,"R"],[1471,1471,"NSM"],[1472,1472,"R"],[1473,1474,"NSM"],[1475,1475,"R"],[1476,1477,"NSM"],[1478,1478,"R"],[1479,1479,"NSM"],[1480,1535,"R"],[1536,1541,"AN"],[1542,1543,"ON"],[1544,1544,"AL"],[1545,1546,"ET"],[1547,1547,"AL"],[1548,1548,"CS"],[1549,1549,"AL"],[1550,1551,"ON"],[1552,1562,"NSM"],[1563,1610,"AL"],[1611,1631,"NSM"],[1632,1641,"AN"],[1642,1642,"ET"],[1643,1644,"AN"],[1645,1647,"AL"],[1648,1648,"NSM"],[1649,1749,"AL"],[1750,1756,"NSM"],[1757,1757,"AN"],[1758,1758,"ON"],[1759,1764,"NSM"],[1765,1766,"AL"],[1767,1768,"NSM"],[1769,1769,"ON"],[1770,1773,"NSM"],[1774,1775,"AL"],[1776,1785,"EN"],[1786,1808,"AL"],[1809,1809,"NSM"],[1810,1839,"AL"],[1840,1866,"NSM"],[1867,1957,"AL"],[1958,1968,"NSM"],[1969,1983,"AL"],[1984,2026,"R"],[2027,2035,"NSM"],[2036,2037,"R"],[2038,2041,"ON"],[2042,2044,"R"],[2045,2045,"NSM"],[2046,2069,"R"],[2070,2073,"NSM"],[2074,2074,"R"],[2075,2083,"NSM"],[2084,2084,"R"],[2085,2087,"NSM"],[2088,2088,"R"],[2089,2093,"NSM"],[2094,2136,"R"],[2137,2139,"NSM"],[2140,2143,"R"],[2144,2191,"AL"],[2192,2193,"AN"],[2194,2198,"AL"],[2199,2207,"NSM"],[2208,2249,"AL"],[2250,2273,"NSM"],[2274,2274,"AN"],[2275,2306,"NSM"],[2362,2362,"NSM"],[2364,2364,"NSM"],[2369,2376,"NSM"],[2381,2381,"NSM"],[2385,2391,"NSM"],[2402,2403,"NSM"],[2433,2433,"NSM"],[2492,2492,"NSM"],[2497,2500,"NSM"],[2509,2509,"NSM"],[2530,2531,"NSM"],[2546,2547,"ET"],[2555,2555,"ET"],[2558,2558,"NSM"],[2561,2562,"NSM"],[2620,2620,"NSM"],[2625,2626,"NSM"],[2631,2632,"NSM"],[2635,2637,"NSM"],[2641,2641,"NSM"],[2672,2673,"NSM"],[2677,2677,"NSM"],[2689,2690,"NSM"],[2748,2748,"NSM"],[2753,2757,"NSM"],[2759,2760,"NSM"],[2765,2765,"NSM"],[2786,2787,"NSM"],[2801,2801,"ET"],[2810,2815,"NSM"],[2817,2817,"NSM"],[2876,2876,"NSM"],[2879,2879,"NSM"],[2881,2884,"NSM"],[2893,2893,"NSM"],[2901,2902,"NSM"],[2914,2915,"NSM"],[2946,2946,"NSM"],[3008,3008,"NSM"],[3021,3021,"NSM"],[3059,3064,"ON"],[3065,3065,"ET"],[3066,3066,"ON"],[3072,3072,"NSM"],[3076,3076,"NSM"],[3132,3132,"NSM"],[3134,3136,"NSM"],[3142,3144,"NSM"],[3146,3149,"NSM"],[3157,3158,"NSM"],[3170,3171,"NSM"],[3192,3198,"ON"],[3201,3201,"NSM"],[3260,3260,"NSM"],[3276,3277,"NSM"],[3298,3299,"NSM"],[3328,3329,"NSM"],[3387,3388,"NSM"],[3393,3396,"NSM"],[3405,3405,"NSM"],[3426,3427,"NSM"],[3457,3457,"NSM"],[3530,3530,"NSM"],[3538,3540,"NSM"],[3542,3542,"NSM"],[3633,3633,"NSM"],[3636,3642,"NSM"],[3647,3647,"ET"],[3655,3662,"NSM"],[3761,3761,"NSM"],[3764,3772,"NSM"],[3784,3790,"NSM"],[3864,3865,"NSM"],[3893,3893,"NSM"],[3895,3895,"NSM"],[3897,3897,"NSM"],[3898,3901,"ON"],[3953,3966,"NSM"],[3968,3972,"NSM"],[3974,3975,"NSM"],[3981,3991,"NSM"],[3993,4028,"NSM"],[4038,4038,"NSM"],[4141,4144,"NSM"],[4146,4151,"NSM"],[4153,4154,"NSM"],[4157,4158,"NSM"],[4184,4185,"NSM"],[4190,4192,"NSM"],[4209,4212,"NSM"],[4226,4226,"NSM"],[4229,4230,"NSM"],[4237,4237,"NSM"],[4253,4253,"NSM"],[4957,4959,"NSM"],[5008,5017,"ON"],[5120,5120,"ON"],[5760,5760,"WS"],[5787,5788,"ON"],[5906,5908,"NSM"],[5938,5939,"NSM"],[5970,5971,"NSM"],[6002,6003,"NSM"],[6068,6069,"NSM"],[6071,6077,"NSM"],[6086,6086,"NSM"],[6089,6099,"NSM"],[6107,6107,"ET"],[6109,6109,"NSM"],[6128,6137,"ON"],[6144,6154,"ON"],[6155,6157,"NSM"],[6158,6158,"BN"],[6159,6159,"NSM"],[6277,6278,"NSM"],[6313,6313,"NSM"],[6432,6434,"NSM"],[6439,6440,"NSM"],[6450,6450,"NSM"],[6457,6459,"NSM"],[6464,6464,"ON"],[6468,6469,"ON"],[6622,6655,"ON"],[6679,6680,"NSM"],[6683,6683,"NSM"],[6742,6742,"NSM"],[6744,6750,"NSM"],[6752,6752,"NSM"],[6754,6754,"NSM"],[6757,6764,"NSM"],[6771,6780,"NSM"],[6783,6783,"NSM"],[6832,6877,"NSM"],[6880,6891,"NSM"],[6912,6915,"NSM"],[6964,6964,"NSM"],[6966,6970,"NSM"],[6972,6972,"NSM"],[6978,6978,"NSM"],[7019,7027,"NSM"],[7040,7041,"NSM"],[7074,7077,"NSM"],[7080,7081,"NSM"],[7083,7085,"NSM"],[7142,7142,"NSM"],[7144,7145,"NSM"],[7149,7149,"NSM"],[7151,7153,"NSM"],[7212,7219,"NSM"],[7222,7223,"NSM"],[7376,7378,"NSM"],[7380,7392,"NSM"],[7394,7400,"NSM"],[7405,7405,"NSM"],[7412,7412,"NSM"],[7416,7417,"NSM"],[7616,7679,"NSM"],[8125,8125,"ON"],[8127,8129,"ON"],[8141,8143,"ON"],[8157,8159,"ON"],[8173,8175,"ON"],[8189,8190,"ON"],[8192,8202,"WS"],[8203,8205,"BN"],[8207,8207,"R"],[8208,8231,"ON"],[8232,8232,"WS"],[8233,8233,"B"],[8234,8238,"BN"],[8239,8239,"CS"],[8240,8244,"ET"],[8245,8259,"ON"],[8260,8260,"CS"],[8261,8286,"ON"],[8287,8287,"WS"],[8288,8303,"BN"],[8304,8304,"EN"],[8308,8313,"EN"],[8314,8315,"ES"],[8316,8318,"ON"],[8320,8329,"EN"],[8330,8331,"ES"],[8332,8334,"ON"],[8352,8399,"ET"],[8400,8432,"NSM"],[8448,8449,"ON"],[8451,8454,"ON"],[8456,8457,"ON"],[8468,8468,"ON"],[8470,8472,"ON"],[8478,8483,"ON"],[8485,8485,"ON"],[8487,8487,"ON"],[8489,8489,"ON"],[8494,8494,"ET"],[8506,8507,"ON"],[8512,8516,"ON"],[8522,8525,"ON"],[8528,8543,"ON"],[8585,8587,"ON"],[8592,8721,"ON"],[8722,8722,"ES"],[8723,8723,"ET"],[8724,9013,"ON"],[9083,9108,"ON"],[9110,9257,"ON"],[9280,9290,"ON"],[9312,9351,"ON"],[9352,9371,"EN"],[9450,9899,"ON"],[9901,10239,"ON"],[10496,11123,"ON"],[11126,11263,"ON"],[11493,11498,"ON"],[11503,11505,"NSM"],[11513,11519,"ON"],[11647,11647,"NSM"],[11744,11775,"NSM"],[11776,11869,"ON"],[11904,11929,"ON"],[11931,12019,"ON"],[12032,12245,"ON"],[12272,12287,"ON"],[12288,12288,"WS"],[12289,12292,"ON"],[12296,12320,"ON"],[12330,12333,"NSM"],[12336,12336,"ON"],[12342,12343,"ON"],[12349,12351,"ON"],[12441,12442,"NSM"],[12443,12444,"ON"],[12448,12448,"ON"],[12539,12539,"ON"],[12736,12773,"ON"],[12783,12783,"ON"],[12829,12830,"ON"],[12880,12895,"ON"],[12924,12926,"ON"],[12977,12991,"ON"],[13004,13007,"ON"],[13175,13178,"ON"],[13278,13279,"ON"],[13311,13311,"ON"],[19904,19967,"ON"],[42128,42182,"ON"],[42509,42511,"ON"],[42607,42610,"NSM"],[42611,42611,"ON"],[42612,42621,"NSM"],[42622,42623,"ON"],[42654,42655,"NSM"],[42736,42737,"NSM"],[42752,42785,"ON"],[42888,42888,"ON"],[43010,43010,"NSM"],[43014,43014,"NSM"],[43019,43019,"NSM"],[43045,43046,"NSM"],[43048,43051,"ON"],[43052,43052,"NSM"],[43064,43065,"ET"],[43124,43127,"ON"],[43204,43205,"NSM"],[43232,43249,"NSM"],[43263,43263,"NSM"],[43302,43309,"NSM"],[43335,43345,"NSM"],[43392,43394,"NSM"],[43443,43443,"NSM"],[43446,43449,"NSM"],[43452,43453,"NSM"],[43493,43493,"NSM"],[43561,43566,"NSM"],[43569,43570,"NSM"],[43573,43574,"NSM"],[43587,43587,"NSM"],[43596,43596,"NSM"],[43644,43644,"NSM"],[43696,43696,"NSM"],[43698,43700,"NSM"],[43703,43704,"NSM"],[43710,43711,"NSM"],[43713,43713,"NSM"],[43756,43757,"NSM"],[43766,43766,"NSM"],[43882,43883,"ON"],[44005,44005,"NSM"],[44008,44008,"NSM"],[44013,44013,"NSM"],[64285,64285,"R"],[64286,64286,"NSM"],[64287,64296,"R"],[64297,64297,"ES"],[64298,64335,"R"],[64336,64450,"AL"],[64451,64466,"ON"],[64467,64829,"AL"],[64830,64847,"ON"],[64848,64911,"AL"],[64912,64913,"ON"],[64914,64967,"AL"],[64968,64975,"ON"],[64976,65007,"BN"],[65008,65020,"AL"],[65021,65023,"ON"],[65024,65039,"NSM"],[65040,65049,"ON"],[65056,65071,"NSM"],[65072,65103,"ON"],[65104,65104,"CS"],[65105,65105,"ON"],[65106,65106,"CS"],[65108,65108,"ON"],[65109,65109,"CS"],[65110,65118,"ON"],[65119,65119,"ET"],[65120,65121,"ON"],[65122,65123,"ES"],[65124,65126,"ON"],[65128,65128,"ON"],[65129,65130,"ET"],[65131,65131,"ON"],[65136,65278,"AL"],[65279,65279,"BN"],[65281,65282,"ON"],[65283,65285,"ET"],[65286,65290,"ON"],[65291,65291,"ES"],[65292,65292,"CS"],[65293,65293,"ES"],[65294,65295,"CS"],[65296,65305,"EN"],[65306,65306,"CS"],[65307,65312,"ON"],[65339,65344,"ON"],[65371,65381,"ON"],[65504,65505,"ET"],[65506,65508,"ON"],[65509,65510,"ET"],[65512,65518,"ON"],[65520,65528,"BN"],[65529,65533,"ON"],[65534,65535,"BN"],[65793,65793,"ON"],[65856,65932,"ON"],[65936,65948,"ON"],[65952,65952,"ON"],[66045,66045,"NSM"],[66272,66272,"NSM"],[66273,66299,"EN"],[66422,66426,"NSM"],[67584,67870,"R"],[67871,67871,"ON"],[67872,68096,"R"],[68097,68099,"NSM"],[68100,68100,"R"],[68101,68102,"NSM"],[68103,68107,"R"],[68108,68111,"NSM"],[68112,68151,"R"],[68152,68154,"NSM"],[68155,68158,"R"],[68159,68159,"NSM"],[68160,68324,"R"],[68325,68326,"NSM"],[68327,68408,"R"],[68409,68415,"ON"],[68416,68863,"R"],[68864,68899,"AL"],[68900,68903,"NSM"],[68904,68911,"AL"],[68912,68921,"AN"],[68922,68927,"AL"],[68928,68937,"AN"],[68938,68968,"R"],[68969,68973,"NSM"],[68974,68974,"ON"],[68975,69215,"R"],[69216,69246,"AN"],[69247,69290,"R"],[69291,69292,"NSM"],[69293,69311,"R"],[69312,69327,"AL"],[69328,69336,"ON"],[69337,69369,"AL"],[69370,69375,"NSM"],[69376,69423,"R"],[69424,69445,"AL"],[69446,69456,"NSM"],[69457,69487,"AL"],[69488,69505,"R"],[69506,69509,"NSM"],[69510,69631,"R"],[69633,69633,"NSM"],[69688,69702,"NSM"],[69714,69733,"ON"],[69744,69744,"NSM"],[69747,69748,"NSM"],[69759,69761,"NSM"],[69811,69814,"NSM"],[69817,69818,"NSM"],[69826,69826,"NSM"],[69888,69890,"NSM"],[69927,69931,"NSM"],[69933,69940,"NSM"],[70003,70003,"NSM"],[70016,70017,"NSM"],[70070,70078,"NSM"],[70089,70092,"NSM"],[70095,70095,"NSM"],[70191,70193,"NSM"],[70196,70196,"NSM"],[70198,70199,"NSM"],[70206,70206,"NSM"],[70209,70209,"NSM"],[70367,70367,"NSM"],[70371,70378,"NSM"],[70400,70401,"NSM"],[70459,70460,"NSM"],[70464,70464,"NSM"],[70502,70508,"NSM"],[70512,70516,"NSM"],[70587,70592,"NSM"],[70606,70606,"NSM"],[70608,70608,"NSM"],[70610,70610,"NSM"],[70625,70626,"NSM"],[70712,70719,"NSM"],[70722,70724,"NSM"],[70726,70726,"NSM"],[70750,70750,"NSM"],[70835,70840,"NSM"],[70842,70842,"NSM"],[70847,70848,"NSM"],[70850,70851,"NSM"],[71090,71093,"NSM"],[71100,71101,"NSM"],[71103,71104,"NSM"],[71132,71133,"NSM"],[71219,71226,"NSM"],[71229,71229,"NSM"],[71231,71232,"NSM"],[71264,71276,"ON"],[71339,71339,"NSM"],[71341,71341,"NSM"],[71344,71349,"NSM"],[71351,71351,"NSM"],[71453,71453,"NSM"],[71455,71455,"NSM"],[71458,71461,"NSM"],[71463,71467,"NSM"],[71727,71735,"NSM"],[71737,71738,"NSM"],[71995,71996,"NSM"],[71998,71998,"NSM"],[72003,72003,"NSM"],[72148,72151,"NSM"],[72154,72155,"NSM"],[72160,72160,"NSM"],[72193,72198,"NSM"],[72201,72202,"NSM"],[72243,72248,"NSM"],[72251,72254,"NSM"],[72263,72263,"NSM"],[72273,72278,"NSM"],[72281,72283,"NSM"],[72330,72342,"NSM"],[72344,72345,"NSM"],[72544,72544,"NSM"],[72546,72548,"NSM"],[72550,72550,"NSM"],[72752,72758,"NSM"],[72760,72765,"NSM"],[72850,72871,"NSM"],[72874,72880,"NSM"],[72882,72883,"NSM"],[72885,72886,"NSM"],[73009,73014,"NSM"],[73018,73018,"NSM"],[73020,73021,"NSM"],[73023,73029,"NSM"],[73031,73031,"NSM"],[73104,73105,"NSM"],[73109,73109,"NSM"],[73111,73111,"NSM"],[73459,73460,"NSM"],[73472,73473,"NSM"],[73526,73530,"NSM"],[73536,73536,"NSM"],[73538,73538,"NSM"],[73562,73562,"NSM"],[73685,73692,"ON"],[73693,73696,"ET"],[73697,73713,"ON"],[78912,78912,"NSM"],[78919,78933,"NSM"],[90398,90409,"NSM"],[90413,90415,"NSM"],[92912,92916,"NSM"],[92976,92982,"NSM"],[94031,94031,"NSM"],[94095,94098,"NSM"],[94178,94178,"ON"],[94180,94180,"NSM"],[113821,113822,"NSM"],[113824,113827,"BN"],[117760,117973,"ON"],[118e3,118009,"EN"],[118010,118012,"ON"],[118016,118451,"ON"],[118458,118480,"ON"],[118496,118512,"ON"],[118528,118573,"NSM"],[118576,118598,"NSM"],[119143,119145,"NSM"],[119155,119162,"BN"],[119163,119170,"NSM"],[119173,119179,"NSM"],[119210,119213,"NSM"],[119273,119274,"ON"],[119296,119361,"ON"],[119362,119364,"NSM"],[119365,119365,"ON"],[119552,119638,"ON"],[120513,120513,"ON"],[120539,120539,"ON"],[120571,120571,"ON"],[120597,120597,"ON"],[120629,120629,"ON"],[120655,120655,"ON"],[120687,120687,"ON"],[120713,120713,"ON"],[120745,120745,"ON"],[120771,120771,"ON"],[120782,120831,"EN"],[121344,121398,"NSM"],[121403,121452,"NSM"],[121461,121461,"NSM"],[121476,121476,"NSM"],[121499,121503,"NSM"],[121505,121519,"NSM"],[122880,122886,"NSM"],[122888,122904,"NSM"],[122907,122913,"NSM"],[122915,122916,"NSM"],[122918,122922,"NSM"],[123023,123023,"NSM"],[123184,123190,"NSM"],[123566,123566,"NSM"],[123628,123631,"NSM"],[123647,123647,"ET"],[124140,124143,"NSM"],[124398,124399,"NSM"],[124643,124643,"NSM"],[124646,124646,"NSM"],[124654,124655,"NSM"],[124661,124661,"NSM"],[124928,125135,"R"],[125136,125142,"NSM"],[125143,125251,"R"],[125252,125258,"NSM"],[125259,126063,"R"],[126064,126143,"AL"],[126144,126207,"R"],[126208,126287,"AL"],[126288,126463,"R"],[126464,126703,"AL"],[126704,126705,"ON"],[126706,126719,"AL"],[126720,126975,"R"],[126976,127019,"ON"],[127024,127123,"ON"],[127136,127150,"ON"],[127153,127167,"ON"],[127169,127183,"ON"],[127185,127221,"ON"],[127232,127242,"EN"],[127243,127247,"ON"],[127279,127279,"ON"],[127338,127343,"ON"],[127405,127405,"ON"],[127584,127589,"ON"],[127744,128728,"ON"],[128732,128748,"ON"],[128752,128764,"ON"],[128768,128985,"ON"],[128992,129003,"ON"],[129008,129008,"ON"],[129024,129035,"ON"],[129040,129095,"ON"],[129104,129113,"ON"],[129120,129159,"ON"],[129168,129197,"ON"],[129200,129211,"ON"],[129216,129217,"ON"],[129232,129240,"ON"],[129280,129623,"ON"],[129632,129645,"ON"],[129648,129660,"ON"],[129664,129674,"ON"],[129678,129734,"ON"],[129736,129736,"ON"],[129741,129756,"ON"],[129759,129770,"ON"],[129775,129784,"ON"],[129792,129938,"ON"],[129940,130031,"ON"],[130032,130041,"EN"],[130042,130042,"ON"],[131070,131071,"BN"],[196606,196607,"BN"],[262142,262143,"BN"],[327678,327679,"BN"],[393214,393215,"BN"],[458750,458751,"BN"],[524286,524287,"BN"],[589822,589823,"BN"],[655358,655359,"BN"],[720894,720895,"BN"],[786430,786431,"BN"],[851966,851967,"BN"],[917502,917759,"BN"],[917760,917999,"NSM"],[918e3,921599,"BN"],[983038,983039,"BN"],[1048574,1048575,"BN"],[1114110,1114111,"BN"]];function EWe(e){if(e<=255)return IWe[e];let t=0,n=CL.length-1;for(;t<=n;){const i=t+n>>1,o=CL[i];if(e<o[0]){n=i-1;continue}if(e>o[1]){t=i+1;continue}return o[2]}return"L"}function TWe(e){const t=e.length;if(t===0)return null;const n=new Array(t);let i=!1;for(let u=0;u<t;){const c=e.charCodeAt(u);let d=c,h=1;if(c>=55296&&c<=56319&&u+1<t){const g=e.charCodeAt(u+1);g>=56320&&g<=57343&&(d=(c-55296<<10)+(g-56320)+65536,h=2)}const p=EWe(d);(p==="R"||p==="AL"||p==="AN")&&(i=!0);for(let g=0;g<h;g++)n[u+g]=p;u+=h}if(!i)return null;let o=0;for(let u=0;u<t;u++){const c=n[u];if(c==="L"){o=0;break}if(c==="R"||c==="AL"){o=1;break}}const s=new Int8Array(t);for(let u=0;u<t;u++)s[u]=o;const r=o&1?"R":"L",l=r;let a=l;for(let u=0;u<t;u++)n[u]==="NSM"?n[u]=a:a=n[u];a=l;for(let u=0;u<t;u++){const c=n[u];c==="EN"?n[u]=a==="AL"?"AN":"EN":(c==="R"||c==="L"||c==="AL")&&(a=c)}for(let u=0;u<t;u++)n[u]==="AL"&&(n[u]="R");for(let u=1;u<t-1;u++)n[u]==="ES"&&n[u-1]==="EN"&&n[u+1]==="EN"&&(n[u]="EN"),n[u]==="CS"&&(n[u-1]==="EN"||n[u-1]==="AN")&&n[u+1]===n[u-1]&&(n[u]=n[u-1]);for(let u=0;u<t;u++){if(n[u]!=="EN")continue;let c;for(c=u-1;c>=0&&n[c]==="ET";c--)n[c]="EN";for(c=u+1;c<t&&n[c]==="ET";c++)n[c]="EN"}for(let u=0;u<t;u++){const c=n[u];(c==="WS"||c==="ES"||c==="ET"||c==="CS")&&(n[u]="ON")}a=l;for(let u=0;u<t;u++){const c=n[u];c==="EN"?n[u]=a==="L"?"L":"EN":(c==="R"||c==="L")&&(a=c)}for(let u=0;u<t;u++){if(n[u]!=="ON")continue;let c=u+1;for(;c<t&&n[c]==="ON";)c++;const d=u>0?n[u-1]:l,h=c<t?n[c]:l,p=d!=="L"?"R":"L";if(p===(h!=="L"?"R":"L"))for(let m=u;m<c;m++)n[m]=p;u=c-1}for(let u=0;u<t;u++)n[u]==="ON"&&(n[u]=r);for(let u=0;u<t;u++){const c=n[u];(s[u]&1)===0?c==="R"?s[u]++:(c==="AN"||c==="EN")&&(s[u]+=2):(c==="L"||c==="AN"||c==="EN")&&s[u]++}return s}function LWe(e,t){const n=TWe(e);if(n===null)return null;const i=new Int8Array(t.length);for(let o=0;o<t.length;o++)i[o]=n[t[o]];return i}const NWe=/[ \t\n\r\f]+/g,FWe=/[\t\n\r\f]| {2,}|^ | $/;function DWe(e){const t=e??"normal";return t==="pre-wrap"?{mode:t,preserveOrdinarySpaces:!0,preserveHardBreaks:!0}:{mode:t,preserveOrdinarySpaces:!1,preserveHardBreaks:!1}}function BWe(e){if(!FWe.test(e))return e;let t=e.replace(NWe," ");return t.charCodeAt(0)===32&&(t=t.slice(1)),t.length>0&&t.charCodeAt(t.length-1)===32&&(t=t.slice(0,-1)),t}function $We(e){return/[\r\f]/.test(e)?e.replace(/\r\n/g,` -`).replace(/[\r\f]/g,` -`):e}let Pk=null,RWe;function zWe(){return Pk===null&&(Pk=new Intl.Segmenter(RWe,{granularity:"word"})),Pk}const OWe=/\p{Script=Arabic}/u,Xc=/\p{M}/u,TA=/\p{Nd}/u;function wL(e){return OWe.test(e)}function xL(e){return e>=19968&&e<=40959||e>=13312&&e<=19903||e>=131072&&e<=173791||e>=173824&&e<=177983||e>=177984&&e<=178207||e>=178208&&e<=183983||e>=183984&&e<=191471||e>=191472&&e<=192093||e>=194560&&e<=195103||e>=196608&&e<=201551||e>=201552&&e<=205743||e>=205744&&e<=210041||e>=63744&&e<=64255||e>=12288&&e<=12351||e>=12352&&e<=12447||e>=12448&&e<=12543||e>=12592&&e<=12687||e>=44032&&e<=55215||e>=65280&&e<=65519}function Ka(e){for(let t=0;t<e.length;t++){const n=e.charCodeAt(t);if(!(n<12288)){if(n>=55296&&n<=56319&&t+1<e.length){const i=e.charCodeAt(t+1);if(i>=56320&&i<=57343){const o=(n-55296<<10)+(i-56320)+65536;if(xL(o))return!0;t++;continue}}if(xL(n))return!0}}return!1}function PWe(e){const t=Tg(e);return t!==null&&(LA.has(t)||vf.has(t))}const jWe=new Set([" "," ","⁠","\uFEFF"]),HWe=new Set(["-","‐","–","—"]);function WWe(e){const t=Tg(e);return t!==null&&jWe.has(t)}function qWe(e){const t=Tg(e);return t!==null&&HWe.has(t)}function SH(e,t){return WWe(e)?!1:t?!(PWe(e)||qWe(e)):!0}const LA=new Set([",",".","!",":",";","?","、","。","・",")","〕","〉","》","」","』","】","〗","〙","〛","ー","々","〻","ゝ","ゞ","ヽ","ヾ"]),W9=new Set(['"',"(","[","{","¡","¿","“","‘","‚","„","«","‹","⸘","(","〔","〈","《","「","『","【","〖","〘","〚"]),NA=new Set(["'","’"]),vf=new Set([".",",","!","?",":",";","،","؛","؟","।","॥","၊","။","၌","၍","၏",")","]","}","%",'"',"”","’","»","›","…"]),UWe=new Set([":",".","،","؛"]),KWe=new Set(["၏"]),VWe=new Set(["”","’","»","›","」","』","】","》","〉","〕",")"]);function ZWe(e){if(FA(e))return!0;let t=!1;for(const n of e){if(vf.has(n)||U9(n)){t=!0;continue}if(!(t&&Xc.test(n)))return!1}return t}function GWe(e){for(const t of e)if(!LA.has(t)&&!vf.has(t))return!1;return e.length>0}function QWe(e){if(FA(e))return!0;for(const t of e)if(!W9.has(t)&&!NA.has(t)&&!Xc.test(t)&&!U9(t))return!1;return e.length>0}function FA(e){let t=!1;for(const n of e)if(!(n==="\\"||Xc.test(n))){if(W9.has(n)||vf.has(n)||NA.has(n)){t=!0;continue}return!1}return t}function q9(e,t){const n=t-1;if(n<=0)return Math.max(n,0);const i=e.charCodeAt(n);if(i<56320||i>57343)return n;const o=n-1;if(o<0)return n;const s=e.charCodeAt(o);return s>=55296&&s<=56319?o:n}function Tg(e){if(e.length===0)return null;const t=q9(e,e.length);return e.slice(t)}function YWe(e){for(const t of e)if(!Xc.test(t))return t;return null}function JWe(e){for(let t=e.length;t>0;){const n=q9(e,t),i=e.slice(n,t);if(!Xc.test(i))return i;t=n}return null}const XWe=[36,37,43,43,92,92,162,165,176,177,1423,1423,1545,1547,1642,1642,2046,2047,2546,2547,2553,2555,2801,2801,3065,3065,3449,3449,3647,3647,6107,6107,8240,8247,8279,8279,8352,8399,8451,8451,8457,8457,8470,8470,8722,8723,43064,43064,65020,65020,65129,65130,65284,65285,65504,65505,65509,65510,73693,73696,123647,123647,126124,126124,126128,126128];function eqe(e,t){for(let n=0;n<t.length;n+=2)if(e>=t[n]&&e<=t[n+1])return!0;return!1}function U9(e){const t=e.codePointAt(0);return t!==void 0&&eqe(t,XWe)}function tqe(e){const t=JWe(e);return t!==null&&U9(t)}function nqe(e){const t=YWe(e);return t!==null&&TA.test(t)}function iqe(e){const t=Array.from(e);let n=t.length;for(;n>0;){const i=t[n-1];if(Xc.test(i)){n--;continue}if(W9.has(i)||NA.has(i)){n--;continue}break}return n<=0||n===t.length?null:{head:t.slice(0,n).join(""),tail:t.slice(n).join("")}}function oqe(e,t,n){return n==="text"&&!t&&e.length===1&&e!=="-"&&e!=="—"?e:null}function SL(e,t,n,i){const o=t[i],s=e[i];if(o==null)return s;const r=n[i];if(s.length===r)return s;const l=o.repeat(r);return e[i]=l,l}function _L(e,t){return e&&t!==null&&UWe.has(t)}function sqe(e){const t=Tg(e);return t!==null&&KWe.has(t)}function rqe(e){if(e.length<2||e[0]!==" ")return null;const t=e.slice(1);return/^\p{M}+$/u.test(t)?{space:" ",marks:t}:null}function I5(e){let t=e.length;for(;t>0;){const n=q9(e,t),i=e.slice(n,t);if(VWe.has(i))return!0;if(!vf.has(i))return!1;t=n}return!1}function lqe(e,t){if(t.preserveOrdinarySpaces||t.preserveHardBreaks){if(e===" ")return"preserved-space";if(e===" ")return"tab";if(t.preserveHardBreaks&&e===` -`)return"hard-break"}return e===" "?"space":e===" "||e===" "||e==="⁠"||e==="\uFEFF"?"glue":e==="​"?"zero-width-break":e==="­"?"soft-hyphen":"text"}const aqe=/[\x20\t\n\xA0\xAD\u200B\u202F\u2060\uFEFF]/;function aa(e){return e.length===1?e[0]:e.join("")}function uqe(e,t){const n=[];for(let i=e.length-1;i>=0;i--)n.push(e[i]);return n.push(t),aa(n)}function cqe(e,t,n,i){if(!aqe.test(e))return[{text:e,isWordLike:t,kind:"text",start:n}];const o=[];let s=null,r=[],l=n,a=!1,u=0;for(const c of e){const d=lqe(c,i),h=d==="text"&&t;if(s!==null&&d===s&&h===a){r.push(c),u+=c.length;continue}s!==null&&o.push({text:aa(r),isWordLike:a,kind:s,start:l}),s=d,r=[c],l=n+u,a=h,u+=c.length}return s!==null&&o.push({text:aa(r),isWordLike:a,kind:s,start:l}),o}function E5(e){return e==="space"||e==="preserved-space"||e==="zero-width-break"||e==="hard-break"}const dqe=/^[A-Za-z][A-Za-z0-9+.-]*:$/;function fqe(e,t){const n=e.texts[t];return n.startsWith("www.")?!0:dqe.test(n)&&t+1<e.len&&e.kinds[t+1]==="text"&&e.texts[t+1]==="//"}function hqe(e){return e.includes("?")&&(e.includes("://")||e.startsWith("www."))}function pqe(e){const t=e.texts.slice(),n=e.isWordLike.slice(),i=e.kinds.slice(),o=e.starts.slice();for(let r=0;r<e.len;r++){if(i[r]!=="text"||!fqe(e,r))continue;const l=[t[r]];let a=r+1;for(;a<e.len&&!E5(i[a]);){l.push(t[a]),n[r]=!0;const u=t[a].includes("?");if(i[a]="text",t[a]="",a++,u)break}t[r]=aa(l)}let s=0;for(let r=0;r<t.length;r++){const l=t[r];l.length!==0&&(s!==r&&(t[s]=l,n[s]=n[r],i[s]=i[r],o[s]=o[r]),s++)}return t.length=s,n.length=s,i.length=s,o.length=s,{len:s,texts:t,isWordLike:n,kinds:i,starts:o}}function gqe(e){const t=[],n=[],i=[],o=[];for(let s=0;s<e.len;s++){const r=e.texts[s];if(t.push(r),n.push(e.isWordLike[s]),i.push(e.kinds[s]),o.push(e.starts[s]),!hqe(r))continue;const l=s+1;if(l>=e.len||E5(e.kinds[l]))continue;const a=[],u=e.starts[l];let c=l;for(;c<e.len&&!E5(e.kinds[c]);)a.push(e.texts[c]),c++;a.length>0&&(t.push(aa(a)),n.push(!0),i.push("text"),o.push(u),s=c-1)}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}const mqe=new Set([":","-","/","×",",",".","+","–","—"]),vqe=/[\p{P}\p{S}\p{Co}]/u,yqe=/\p{Emoji_Presentation}/u,kqe=new Set(["?","֊","-","‐","‒","–","—","…","‼","‽","⁉"]);function bqe(e){return e>=33&&e<=47&&e!==45||e>=58&&e<=64&&e!==63||e>=91&&e<=96||e>=123&&e<=126}function _H(e){const t=e.charCodeAt(0);return t<128?bqe(t):!kqe.has(e)&&!yqe.test(e)&&vqe.test(e)}function ML(e){let t=!1;for(const n of e)if(!Xc.test(n)){if(!_H(n))return!1;t=!0}return t}function Aqe(e){for(let t=e.length;t>0;){const n=q9(e,t),i=e.slice(n,t);if(Xc.test(i)){t=n;continue}return _H(i)||U9(i)}return!1}function Cqe(e,t,n,i){const o=!t&&ML(e),s=!i&&ML(n),r=tqe(e),l=(t||r)&&Aqe(e);return!o&&!s&&!l||Ka(e)||Ka(n)?!1:(t||o||r)&&(i||s)}function MH(e){for(const t of e)if(TA.test(t))return!0;return!1}function Ny(e){if(e.length===0)return!1;for(const t of e)if(!(TA.test(t)||mqe.has(t)))return!1;return!0}function wqe(e){const t=[],n=[],i=[],o=[];for(let s=0;s<e.len;s++){const r=e.texts[s],l=e.kinds[s];if(l==="text"&&Ny(r)&&MH(r)){const a=[r];let u=s+1;for(;u<e.len&&e.kinds[u]==="text"&&Ny(e.texts[u]);)a.push(e.texts[u]),u++;t.push(aa(a)),n.push(!0),i.push("text"),o.push(e.starts[s]),s=u-1;continue}t.push(r),n.push(e.isWordLike[s]),i.push(l),o.push(e.starts[s])}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}function xqe(e){const t=[],n=[],i=[],o=[];let s=0;for(;s<e.len;){const r=e.texts[s],l=e.kinds[s],a=e.isWordLike[s];if(l==="text"){const u=[r];let c=s+1,d=a;for(;c<e.len&&e.kinds[c]==="text"&&Cqe(e.texts[c-1],e.isWordLike[c-1],e.texts[c],e.isWordLike[c]);){const h=e.texts[c];u.push(h),d=d||e.isWordLike[c],c++}if(c>s+1){t.push(aa(u)),n.push(d),i.push("text"),o.push(e.starts[s]),s=c;continue}}t.push(r),n.push(a),i.push(l),o.push(e.starts[s]),s++}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}function Sqe(e){const t=[],n=[],i=[],o=[];for(let s=0;s<e.len;s++){const r=e.texts[s];if(e.kinds[s]==="text"&&r.includes("-")){const l=r.split("-");let a=l.length>1;for(let u=0;u<l.length;u++){const c=l[u];if(!a)break;(c.length===0||!MH(c)||!Ny(c))&&(a=!1)}if(a){let u=0;for(let c=0;c<l.length;c++){const d=l[c],h=c<l.length-1?`${d}-`:d;t.push(h),n.push(!0),i.push("text"),o.push(e.starts[s]+u),u+=h.length}continue}}t.push(r),n.push(e.isWordLike[s]),i.push(e.kinds[s]),o.push(e.starts[s])}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}function _qe(e){const t=[],n=[],i=[],o=[];let s=0;for(;s<e.len;){const r=[e.texts[s]];let l=e.isWordLike[s],a=e.kinds[s],u=e.starts[s];if(a==="glue"){const c=[r[0]],d=u;for(s++;s<e.len&&e.kinds[s]==="glue";)c.push(e.texts[s]),s++;const h=aa(c);if(s<e.len&&e.kinds[s]==="text")r[0]=h,r.push(e.texts[s]),l=e.isWordLike[s],a="text",u=d,s++;else{t.push(h),n.push(!1),i.push("glue"),o.push(d);continue}}else s++;if(a==="text")for(;s<e.len&&e.kinds[s]==="glue";){const c=[];for(;s<e.len&&e.kinds[s]==="glue";)c.push(e.texts[s]),s++;const d=aa(c);if(s<e.len&&e.kinds[s]==="text"){r.push(d,e.texts[s]),l=l||e.isWordLike[s],s++;continue}r.push(d)}t.push(aa(r)),n.push(l),i.push(a),o.push(u)}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}function Mqe(e){const t=e.texts.slice(),n=e.isWordLike.slice(),i=e.kinds.slice(),o=e.starts.slice();for(let s=0;s<t.length-1;s++){if(i[s]!=="text"||i[s+1]!=="text"||!Ka(t[s])||!Ka(t[s+1]))continue;const r=iqe(t[s]);r!==null&&(t[s]=r.head,t[s+1]=r.tail+t[s+1],o[s+1]=o[s]+r.head.length)}return{len:t.length,texts:t,isWordLike:n,kinds:i,starts:o}}function Iqe(e,t,n){const i=zWe();let o=0;const s=[],r=[],l=[],a=[],u=[],c=[],d=[],h=[],p=[],g=[],m=[],k=[];for(const S of i.segment(e))for(const x of cqe(S.segment,S.isWordLike??!1,S.index,n)){let R=function(){c[O]!==null&&(r[O]=[SL(s,c,d,O)],c[O]=null),r[O].push(x.text),l[O]=l[O]||x.isWordLike,h[O]=h[O]||M,p[O]=p[O]||N,g[O]=z,m[O]=H,k[O]=_L(p[O],I)};const _=x.kind==="text",L=oqe(x.text,x.isWordLike,x.kind),M=Ka(x.text),N=wL(x.text),I=Tg(x.text),z=I5(x.text),H=sqe(x.text),O=o-1;t.carryCJKAfterClosingQuote&&_&&o>0&&a[O]==="text"&&M&&h[O]&&g[O]||_&&o>0&&a[O]==="text"&&GWe(x.text)&&h[O]||_&&o>0&&a[O]==="text"&&m[O]?R():_&&o>0&&a[O]==="text"&&x.isWordLike&&N&&k[O]?(R(),l[O]=!0):L!==null&&o>0&&a[O]==="text"&&c[O]===L?d[O]=(d[O]??1)+1:_&&!x.isWordLike&&o>0&&a[O]==="text"&&!h[O]&&(ZWe(x.text)||x.text==="-"&&l[O])?R():(s[o]=x.text,r[o]=[x.text],l[o]=x.isWordLike,a[o]=x.kind,u[o]=x.start,c[o]=L,d[o]=L===null?0:1,h[o]=M,p[o]=N,g[o]=z,m[o]=H,k[o]=_L(N,I),o++)}for(let S=0;S<o;S++){if(c[S]!==null){s[S]=SL(s,c,d,S);continue}s[S]=aa(r[S])}for(let S=1;S<o;S++)a[S]==="text"&&!l[S]&&FA(s[S])&&a[S-1]==="text"&&!h[S-1]&&(s[S-1]+=s[S],l[S-1]=l[S-1]||l[S],s[S]="");const w=Array.from({length:o},()=>null);let y=-1;for(let S=o-1;S>=0;S--){const x=s[S];if(x.length!==0){if(a[S]==="text"&&!l[S]&&y>=0&&a[y]==="text"&&(QWe(x)||x==="-"&&nqe(s[y]))){const _=w[y]??[];_.push(x),w[y]=_,u[y]=u[S],s[S]="";continue}y=S}}for(let S=0;S<o;S++){const x=w[S];x!=null&&(s[S]=uqe(x,s[S]))}let b=0;for(let S=0;S<o;S++){const x=s[S];x.length!==0&&(b!==S&&(s[b]=x,l[b]=l[S],a[b]=a[S],u[b]=u[S]),b++)}s.length=b,l.length=b,a.length=b,u.length=b;const A=_qe({len:b,texts:s,isWordLike:l,kinds:a,starts:u}),T=Mqe(xqe(Sqe(wqe(gqe(pqe(A))))));for(let S=0;S<T.len-1;S++){const x=rqe(T.texts[S]);x!==null&&(T.kinds[S]!=="space"&&T.kinds[S]!=="preserved-space"||T.kinds[S+1]!=="text"||!wL(T.texts[S+1])||(T.texts[S]=x.space,T.isWordLike[S]=!1,T.kinds[S]=T.kinds[S]==="preserved-space"?"preserved-space":"space",T.texts[S+1]=x.marks+T.texts[S+1],T.starts[S+1]=T.starts[S]+x.space.length))}return T}function Eqe(e,t){if(e.len===0)return[];if(!t.preserveHardBreaks)return[{startSegmentIndex:0,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}];const n=[];let i=0;for(let o=0;o<e.len;o++)e.kinds[o]==="hard-break"&&(n.push({startSegmentIndex:i,endSegmentIndex:o,consumedEndSegmentIndex:o+1}),i=o+1);return i<e.len&&n.push({startSegmentIndex:i,endSegmentIndex:e.len,consumedEndSegmentIndex:e.len}),n}function Tqe(e,t,n){if(t.len<=1)return t;const i=[],o=[],s=[],r=[];let l=-1,a=!1;function u(h){i.push(t.texts[h]),o.push(t.isWordLike[h]),s.push("text"),r.push(t.starts[h])}function c(h,p){let g=!1;for(let w=h;w<p;w++)g=g||t.isWordLike[w];const m=t.starts[h],k=p<t.len?t.starts[p]:e.length;i.push(e.slice(m,k)),o.push(g),s.push("text"),r.push(m)}function d(h){if(!(l<0)){if(a)l+1===h?u(l):c(l,h);else for(let p=l;p<h;p++)u(p);l=-1,a=!1}}for(let h=0;h<t.len;h++){const p=t.texts[h],g=t.kinds[h];if(g==="text"){l>=0&&!SH(t.texts[h-1],n)&&d(h),l<0&&(l=h),a=a||Ka(p);continue}d(h),i.push(p),o.push(t.isWordLike[h]),s.push(g),r.push(t.starts[h])}return d(t.len),{len:i.length,texts:i,isWordLike:o,kinds:s,starts:r}}function Lqe(e,t,n="normal",i="normal"){const o=DWe(n),s=o.mode==="pre-wrap"?$We(e):BWe(e);if(s.length===0)return{normalized:s,chunks:[],len:0,texts:[],isWordLike:[],kinds:[],starts:[]};const r=Iqe(s,t,o),l=i==="keep-all"?Tqe(s,r,t.breakKeepAllAfterPunctuation):r;return{normalized:s,chunks:Eqe(l,o),...l}}let Xf=null;const IL=new Map;let eh=null;const Nqe=96,Fqe=/\p{Emoji_Presentation}/u,Dqe=/[\p{Emoji_Presentation}\p{Extended_Pictographic}\p{Regional_Indicator}\uFE0F\u20E3]/u;let jk=null;const EL=new Map;function DA(){if(Xf!==null)return Xf;if(typeof OffscreenCanvas<"u")return Xf=new OffscreenCanvas(1,1).getContext("2d"),Xf;if(typeof document<"u")return Xf=document.createElement("canvas").getContext("2d"),Xf;throw new Error("Text measurement requires OffscreenCanvas or a DOM canvas context.")}function Bqe(e){let t=IL.get(e);return t||(t=new Map,IL.set(e,t)),t}function fc(e,t){let n=t.get(e);return n===void 0&&(n={width:DA().measureText(e).width,containsCJK:Ka(e)},t.set(e,n)),n}function K9(){if(eh!==null)return eh;if(typeof navigator>"u")return eh={lineFitEpsilon:.005,carryCJKAfterClosingQuote:!1,breakKeepAllAfterPunctuation:!0,preferPrefixWidthsForBreakableRuns:!1,preferEarlySoftHyphenBreak:!1},eh;const e=navigator.userAgent,n=navigator.vendor==="Apple Computer, Inc."&&e.includes("Safari/")&&!e.includes("Chrome/")&&!e.includes("Chromium/")&&!e.includes("CriOS/")&&!e.includes("FxiOS/")&&!e.includes("EdgiOS/"),i=e.includes("Chrome/")||e.includes("Chromium/")||e.includes("CriOS/")||e.includes("Edg/");return eh={lineFitEpsilon:n?1/64:.005,carryCJKAfterClosingQuote:i,breakKeepAllAfterPunctuation:!n,preferPrefixWidthsForBreakableRuns:n,preferEarlySoftHyphenBreak:n},eh}function $qe(e){const t=e.match(/(\d+(?:\.\d+)?)\s*px/);return t?parseFloat(t[1]):16}function IH(){return jk===null&&(jk=new Intl.Segmenter(void 0,{granularity:"grapheme"})),jk}function Rqe(e){return Fqe.test(e)||e.includes("️")}function zqe(e){return Dqe.test(e)}function Oqe(e,t){let n=EL.get(e);if(n!==void 0)return n;const i=DA();i.font=e;const o=i.measureText("😀").width;if(n=0,o>t+.5&&typeof document<"u"&&document.body!==null){const s=document.createElement("span");s.style.font=e,s.style.display="inline-block",s.style.visibility="hidden",s.style.position="absolute",s.textContent="😀",document.body.appendChild(s);const r=s.getBoundingClientRect().width;document.body.removeChild(s),o-r>.5&&(n=o-r)}return EL.set(e,n),n}function Pqe(e){let t=0;const n=IH();for(const i of n.segment(e))Rqe(i.segment)&&t++;return t}function jqe(e,t){return t.emojiCount===void 0&&(t.emojiCount=Pqe(e)),t.emojiCount}function qd(e,t,n){return n===0?t.width:t.width-jqe(e,t)*n}function Hqe(e,t,n,i,o){if(t.breakableFitAdvances!==void 0&&t.breakableFitMode===o)return t.breakableFitAdvances;t.breakableFitMode=o;const s=IH(),r=[];for(const c of s.segment(e))r.push(c.segment);if(r.length<=1)return t.breakableFitAdvances=null,t.breakableFitAdvances;if(o==="sum-graphemes"){const c=[];for(const d of r){const h=fc(d,n);c.push(qd(d,h,i))}return t.breakableFitAdvances=c,t.breakableFitAdvances}if(o==="pair-context"||r.length>Nqe){const c=[];let d=null,h=0;for(const p of r){const g=fc(p,n),m=qd(p,g,i);if(d===null)c.push(m);else{const k=d+p,w=fc(k,n);c.push(qd(k,w,i)-h)}d=p,h=m}return t.breakableFitAdvances=c,t.breakableFitAdvances}const l=[];let a="",u=0;for(const c of r){a+=c;const d=fc(a,n),h=qd(a,d,i);l.push(h-u),u=h}return t.breakableFitAdvances=l,t.breakableFitAdvances}function Wqe(e,t){const n=DA();n.font=e;const i=Bqe(e),o=$qe(e),s=t?Oqe(e,o):0;return{cache:i,fontSize:o,emojiCorrection:s}}function qqe(e){return e==="space"||e==="zero-width-break"||e==="soft-hyphen"}function EH(e){return e==="space"||e==="preserved-space"||e==="tab"||e==="zero-width-break"||e==="soft-hyphen"}function TH(e,t,n=e.widths.length){for(;t<n;){const i=e.kinds[t];if(!qqe(i))break;t++}return t}function Uqe(e,t){if(t<=0)return 0;const n=e%t;return Math.abs(n)<=1e-6?t:t-n}function Kqe(e,t,n){return e.letterSpacing!==0&&t&&e.spacingGraphemeCounts[n]>0?e.letterSpacing:0}function BA(e,t){return t===0?0:e+t}function Vqe(e,t){return e.letterSpacing!==0&&e.spacingGraphemeCounts[t]>0?e.letterSpacing:0}function Zqe(e,t,n,i,o){const s=t==="tab"?o+Vqe(e,n):e.lineEndFitAdvances[n];return BA(i,s)}function TL(e,t,n,i){const o=t==="tab"?0:e.lineEndFitAdvances[n];return BA(i,o)}function LL(e,t,n,i,o){const s=t==="tab"?o:e.lineEndPaintAdvances[n];return BA(i,s)}function Gqe(e,t,n){return e.letterSpacing!==0&&t?n+e.letterSpacing:n}function Qqe(e,t){return e.letterSpacing===0?t:t+e.letterSpacing}function Fy(e,t,n){let i=t;for(;i<e.length&&e[i]<n;)i++;return i}function Yqe(e,t,n,i,o){if(e.letterSpacing===0)return 0;if(o>0)return e.spacingGraphemeCounts[i]>0?e.letterSpacing:0;for(let s=i-1;s>=t;s--){const r=e.kinds[s];if(!(r==="space"||r==="zero-width-break"||r==="hard-break")){if(r==="soft-hyphen"){if(s===i-1)return 0;continue}return s===t&&n>0||e.spacingGraphemeCounts[s]>0?e.letterSpacing:0}}return 0}function Jqe(e,t,n,i,o,s){return t+Yqe(e,n,i,o,s)}function Xqe(e,t,n){const{widths:i,kinds:o,breakableFitAdvances:s,breakablePreferredBreaks:r}=e;if(i.length===0)return 0;const a=K9().lineFitEpsilon,u=t+a;let c=0,d=0,h=!1,p=0,g=0,m=0,k=0,w=-1,y=0;function b(){w=-1,y=0}function A(M=m,N=k,I=d){c++,n?.(I,p,g,M,N),d=0,h=!1,b()}function T(M,N){h=!0,p=M,g=0,m=M+1,k=0,d=N}function S(M,N,I){h=!0,p=M,g=N,m=M,k=N+1,d=I}function x(M,N){if(!h){T(M,N);return}d+=N,m=M+1,k=0}function _(M,N){const I=s[M],z=r[M]??null;let H=z===null?-1:Fy(z,0,N+1),O=-1,R=0,j=N;for(;j<I.length;){const $=I[j];if(!h)S(M,j,$);else if(d+$>u){if(z!==null&&O>N){A(M,O,R),j=O,H=Fy(z,H,j+1),O=-1,R=0;continue}A(),S(M,j,$)}else d+=$,m=M,k=j+1;const W=j+1;z!==null&&z[H]===W&&(O=W,R=d,H++),j++}h&&m===M&&k===I.length&&(m=M+1,k=0)}let L=0;for(;L<i.length&&!(!h&&(L=TH(e,L),L>=i.length));){const M=i[L],N=o[L],I=EH(N);if(!h){M>u&&s[L]!==null?_(L,0):T(L,M),I&&(w=L+1,y=d-M),L++;continue}if(d+M>u){if(I){x(L,M),A(L+1,0,d-M),L++;continue}if(w>=0){if(m>w||m===w&&k>0){A();continue}A(w,0,y);continue}if(M>u&&s[L]!==null){A(),_(L,0),L++;continue}A();continue}x(L,M),I&&(w=L+1,y=d-M),L++}return h&&A(),c}function eUe(e,t,n){if(e.simpleLineWalkFastPath)return Xqe(e,t,n);const{widths:i,kinds:o,breakableFitAdvances:s,breakablePreferredBreaks:r,discretionaryHyphenWidth:l,chunks:a}=e;if(i.length===0||a.length===0)return 0;const u=K9(),c=u.lineFitEpsilon,d=t+c;let h=0,p=0,g=!1,m=0,k=0,w=0,y=0,b=-1,A=0,T=0,S=null;function x(){b=-1,A=0,T=0,S=null}function _(){return S==="soft-hyphen"&&b===w&&y===0?T:p}function L(R=w,j=y,$){h++,n!==void 0&&n(Jqe(e,$??_(),m,k,R,j),m,k,R,j),p=0,g=!1,x()}function M(R,j){g=!0,m=R,k=0,w=R+1,y=0,p=j}function N(R,j,$){g=!0,m=R,k=j,w=R,y=j+1,p=$}function I(R,j){if(!g){M(R,j);return}p+=j,w=R+1,y=0}function z(R,j,$,W,P,Z){if(!j)return;const ae=TL(e,R,$,P),V=LL(e,R,$,P,W);b=$+1,A=p-Z+ae,T=p-Z+V,S=R}function H(R,j){const $=s[R],W=r[R]??null;let P=W===null?-1:Fy(W,0,j+1),Z=-1,ae=0,V=j;for(;V<$.length;){const Y=$[V];if(!g)N(R,V,Y);else{const q=Gqe(e,!0,Y),ne=p+q;if(Qqe(e,ne)>d){if(W!==null&&Z>j){L(R,Z,ae),V=Z,P=Fy(W,P,V+1),Z=-1,ae=0;continue}L(),N(R,V,Y)}else p=ne,w=R,y=V+1}const oe=V+1;W!==null&&W[P]===oe&&(Z=oe,ae=p,P++),V++}g&&w===R&&y===$.length&&(w=R+1,y=0)}function O(R){h++,n?.(0,R.startSegmentIndex,0,R.consumedEndSegmentIndex,0),x()}for(let R=0;R<a.length;R++){const j=a[R];if(j.startSegmentIndex===j.endSegmentIndex){O(j);continue}g=!1,p=0,m=j.startSegmentIndex,k=0,w=j.startSegmentIndex,y=0,x();let $=j.startSegmentIndex;for(;$<j.endSegmentIndex&&!(!g&&($=TH(e,$,j.endSegmentIndex),$>=j.endSegmentIndex));){const W=o[$],P=EH(W),Z=Kqe(e,g,$),ae=W==="tab"?Uqe(p+Z,e.tabStopAdvance):i[$],V=Z+ae,Y=Zqe(e,W,$,Z,ae);if(W==="soft-hyphen"){g&&(w=$+1,y=0,b=$+1,A=p+l,T=p+l,S=W),$++;continue}if(!g){Y>d&&s[$]!==null?H($,0):M($,ae),z(W,P,$,ae,Z,V),$++;continue}if(p+Y>d){const q=p+TL(e,W,$,Z),ne=p+LL(e,W,$,Z,ae);if(S==="soft-hyphen"&&u.preferEarlySoftHyphenBreak&&A<=d){L(b,0,T);continue}if(P&&q<=d){I($,V),L($+1,0,ne),$++;continue}if(b>=0&&A<=d){if(w>b||w===b&&y>0){L();continue}const ie=b;L(ie,0,T),$=ie;continue}if(Y>d&&s[$]!==null){L(),H($,0),$++;continue}L();continue}I($,V),z(W,P,$,ae,Z,V),$++}if(g){const W=b===j.consumedEndSegmentIndex?T:p;L(j.consumedEndSegmentIndex,0,W)}}return h}let Hk=null;function $A(){return Hk===null&&(Hk=new Intl.Segmenter(void 0,{granularity:"grapheme"})),Hk}function tUe(e){return{widths:[],lineEndFitAdvances:[],lineEndPaintAdvances:[],kinds:[],simpleLineWalkFastPath:!0,segLevels:null,breakableFitAdvances:[],breakablePreferredBreaks:[],letterSpacing:0,spacingGraphemeCounts:[],discretionaryHyphenWidth:0,tabStopAdvance:0,chunks:[],segments:[]}}function nUe(e,t){const n=[];let i=[],o=0,s=!1,r=!1,l=!1;function a(){i.length!==0&&(n.push({text:i.length===1?i[0]:i.join(""),start:o}),i=[],s=!1,r=!1,l=!1)}function u(d,h,p){i=[d],o=h,s=p,r=I5(d),l=W9.has(d)}function c(d,h){i.push(d),s=s||h;const p=I5(d);d.length===1&&vf.has(d)?r=r||p:r=p,l=!1}for(const d of $A().segment(e)){const h=d.segment,p=Ka(h);if(i.length===0){u(h,d.index,p);continue}if(l||LA.has(h)||vf.has(h)||t.carryCJKAfterClosingQuote&&p&&r){c(h,p);continue}if(!s&&!p){c(h,p);continue}a(),u(h,d.index,p)}return a(),n}function iUe(e,t,n){if(t.length<=1)return t;const i=[];let o=-1,s=!1;function r(a,u){const c=t[a].start,d=u<t.length?t[u].start:e.length;i.push({text:e.slice(c,d),start:c})}function l(a){if(!(o<0)){if(s)o+1===a?i.push(t[o]):r(o,a);else for(let u=o;u<a;u++)i.push(t[u]);o=-1,s=!1}}for(let a=0;a<t.length;a++){const u=t[a];o>=0&&!SH(t[a-1].text,n)&&l(a),o<0&&(o=a),s=s||Ka(u.text)}return l(t.length),i}function NL(e,t){if(t==="zero-width-break"||t==="soft-hyphen"||t==="hard-break")return 0;if(t==="tab")return 1;let n=0;const i=$A();for(const o of i.segment(e))n++;return n}function oUe(e){return e==="-"||e==="֊"||e==="‐"||e==="‒"||e==="–"||e==="—"}function sUe(e){if(!/[-\u058A\u2010\u2012\u2013\u2014]/u.test(e))return null;const t=[];let n=0;for(const i of $A().segment(e))n++,oUe(i.segment)&&t.push(n);return t.length===0?null:t}function rUe(e,t,n){return t>1?e+(t-1)*n:e}function lUe(e,t,n,i,o){const s=K9(),{cache:r,emojiCorrection:l}=Wqe(t,zqe(e.normalized)),a=qd("-",fc("-",r),l)+(o===0?0:o*2),c=qd(" ",fc(" ",r),l)*8,d=o!==0;if(e.len===0)return tUe();const h=[],p=[],g=[],m=[];let k=e.chunks.length<=1&&!d;const w=n?[]:null,y=[],b=[],A=[],T=n?[]:null,S=Array.from({length:e.len});function x(N,I,z,H,O,R,j,$,W){O!=="text"&&O!=="space"&&O!=="zero-width-break"&&(k=!1),h.push(I),p.push(z),g.push(H),m.push(O),w?.push(R),y.push(j),b.push($),d&&A.push(W),T!==null&&T.push(N)}function _(N,I,z,H,O){const R=fc(N,r),j=d?NL(N,I):0,$=rUe(qd(N,R,l),j,o),W=I==="space"||I==="preserved-space"||I==="zero-width-break"?0:$,P=W===0?0:W+(j>0?o:0),Z=I==="space"||I==="zero-width-break"?0:$;if(O&&H&&N.length>1){let ae="sum-graphemes";o!==0?ae="segment-prefixes":Ny(N)?ae="pair-context":s.preferPrefixWidthsForBreakableRuns&&(ae="segment-prefixes");const V=Hqe(N,R,r,l,ae),Y=V===null||i==="keep-all"?null:sUe(N);x(N,$,P,Z,I,z,V,Y,j);return}x(N,$,P,Z,I,z,null,null,j)}for(let N=0;N<e.len;N++){S[N]=h.length;const I=e.texts[N],z=e.isWordLike[N],H=e.kinds[N],O=e.starts[N];if(H==="soft-hyphen"){x(I,0,a,a,H,O,null,null,0);continue}if(H==="hard-break"){x(I,0,0,0,H,O,null,null,0);continue}if(H==="tab"){x(I,0,0,0,H,O,null,null,d?NL(I,H):0);continue}const R=fc(I,r);if(H==="text"&&R.containsCJK){const j=nUe(I,s),$=i==="keep-all"?iUe(I,j,s.breakKeepAllAfterPunctuation):j;for(let W=0;W<$.length;W++){const P=$[W];_(P.text,"text",O+P.start,z,i==="keep-all"||!Ka(P.text))}continue}_(I,H,O,z,!0)}const L=aUe(e.chunks,S,h.length),M=w===null?null:LWe(e.normalized,w);return T!==null?{widths:h,lineEndFitAdvances:p,lineEndPaintAdvances:g,kinds:m,simpleLineWalkFastPath:k,segLevels:M,breakableFitAdvances:y,breakablePreferredBreaks:b,letterSpacing:o,spacingGraphemeCounts:A,discretionaryHyphenWidth:a,tabStopAdvance:c,chunks:L,segments:T}:{widths:h,lineEndFitAdvances:p,lineEndPaintAdvances:g,kinds:m,simpleLineWalkFastPath:k,segLevels:M,breakableFitAdvances:y,breakablePreferredBreaks:b,letterSpacing:o,spacingGraphemeCounts:A,discretionaryHyphenWidth:a,tabStopAdvance:c,chunks:L}}function aUe(e,t,n){const i=[];for(let o=0;o<e.length;o++){const s=e[o],r=s.startSegmentIndex<t.length?t[s.startSegmentIndex]:n,l=s.endSegmentIndex<t.length?t[s.endSegmentIndex]:n,a=s.consumedEndSegmentIndex<t.length?t[s.consumedEndSegmentIndex]:n;i.push({startSegmentIndex:r,endSegmentIndex:l,consumedEndSegmentIndex:a})}return i}function uUe(e,t,n,i){const o=i?.wordBreak??"normal",s=i?.letterSpacing??0,r=Lqe(e,K9(),i?.whiteSpace,o);return lUe(r,t,n,o,s)}function cUe(e,t,n){return uUe(e,t,!0,n)}function dUe(e){let t=0;return eUe(e,Number.POSITIVE_INFINITY,n=>{n>t&&(t=n)}),t}const fUe={key:0,class:"slash-empty",role:"status"},hUe=["id","aria-selected","onMouseenter","onMousedown"],pUe={class:"slash-name"},gUe={key:0,class:"slash-match"},mUe={class:"slash-desc"},vUe={key:0,class:"slash-desc-match"},yUe=Xe({__name:"SlashMenu",props:{items:{},activeIndex:{},query:{default:""},ranges:{},layout:{default:"popup"}},emits:["select","hover"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),o=e,s=n;function r(x,_){if(!_||_.length===0)return[{text:x,hit:!1}];const L=[];let M=0;for(const[N,I]of[..._].sort((z,H)=>z[0]-H[0]))N>M&&L.push({text:x.slice(M,N),hit:!1}),L.push({text:x.slice(N,I),hit:!0}),M=I;return M<x.length&&L.push({text:x.slice(M),hit:!1}),L}function l(x){return x.isSkill?x.desc:i(x.desc)}const a=F(()=>o.items.map((x,_)=>{const L=l(x),M=o.ranges?.[_]??oce(o.query,x.name,L);return{item:x,namePieces:r(x.name,M.name),desc:L,descPieces:r(L,M.desc)}})),u=K(null),c=K(null);t({el:c});const d=K(!1),h=K(!1);let p=null;const g=K(null);function m(){const x=u.value;if(!x)return;d.value=x.scrollTop>0,h.value=x.scrollTop+x.clientHeight<x.scrollHeight-1;const{scrollTop:_,scrollHeight:L,clientHeight:M}=x;if(L<=M+1){g.value=null;return}const N=getComputedStyle(x),I=parseFloat(N.getPropertyValue("--menu-scrollbar-track-inset"))||0,z=parseFloat(N.getPropertyValue("--menu-scrollbar-thumb-min"))||24,H=M-I*2,O=Math.max(z,M/L*H),R=L-M,j=x.offsetTop+I+_/R*(H-O);g.value={top:j,height:O}}function k(){m()}let w=null;function y(x){const _=u.value,L=g.value;if(!_||!L)return;x.preventDefault(),w?.();const M=x.pointerId;x.target.setPointerCapture?.(x.pointerId);const N=getComputedStyle(_),I=parseFloat(N.getPropertyValue("--menu-scrollbar-track-inset"))||0,z=_.clientHeight-I*2-L.height,H=_.scrollHeight-_.clientHeight,O=x.clientY,R=_.scrollTop,j=P=>{P.pointerId!==M||z<=0||(_.scrollTop=R+(P.clientY-O)/z*H)},$=P=>{P.pointerId===M&&W()},W=()=>{window.removeEventListener("pointerup",$),window.removeEventListener("pointermove",j),window.removeEventListener("pointercancel",$),w===W&&(w=null)};w=W,window.addEventListener("pointermove",j),window.addEventListener("pointerup",$),window.addEventListener("pointercancel",$)}const b=F(()=>{const x=d.value,_=h.value,L="var(--menu-scroll-fade)";if(x&&_)return`linear-gradient(to bottom, transparent 0, black ${L}, black calc(100% - ${L}), transparent 100%)`;if(x)return`linear-gradient(to bottom, transparent, black ${L})`;if(_)return`linear-gradient(to top, transparent, black ${L})`}),A=K("");function T(){const x=c.value,_=u.value,L=x?.offsetParent;if(!x||!_||!L)return;const M=getComputedStyle(x),N=parseFloat(M.getPropertyValue("--space-2"))||8,I=parseFloat(M.getPropertyValue("--space-2"))||8,z=(parseFloat(M.paddingTop)||0)+(parseFloat(M.paddingBottom)||0),H=parseFloat(getComputedStyle(_).getPropertyValue("--p-slash-menu-h"))||Number.POSITIVE_INFINITY,O=window.visualViewport?.offsetTop??0,R=L.getBoundingClientRect().top-O-N-I-z;A.value=`${Math.max(Math.floor(Math.min(H,R)),0)}px`,dt(()=>{m(),S()})}cn(()=>{if(o.layout==="sheet"){m(),typeof ResizeObserver=="function"&&u.value&&(p=new ResizeObserver(()=>m()),p.observe(u.value));return}if(T(),m(),typeof ResizeObserver=="function"&&u.value){p=new ResizeObserver(_=>{for(const L of _)L.target===u.value?m():T()}),p.observe(u.value);const x=c.value?.offsetParent;x&&p.observe(x)}window.addEventListener("resize",T),window.visualViewport?.addEventListener("resize",T),window.visualViewport?.addEventListener("scroll",T)}),_n(()=>{p?.disconnect(),p=null,w?.(),window.removeEventListener("resize",T),window.visualViewport?.removeEventListener("resize",T),window.visualViewport?.removeEventListener("scroll",T)});function S(){const x=u.value;if(!x)return;const _=x.querySelectorAll('[role="option"]')[o.activeIndex];if(!_)return;const L=x.getBoundingClientRect(),M=_.getBoundingClientRect(),N=M.top-L.top+x.scrollTop,I=N+M.height;N<x.scrollTop?x.scrollTop=N:I>x.scrollTop+x.clientHeight&&(x.scrollTop=I-x.clientHeight)}return Pe(()=>o.activeIndex,()=>{dt(S)}),Pe(()=>o.items,()=>{dt(()=>{m(),S()})}),(x,_)=>(v(),E("div",{ref_key:"menuEl",ref:c,class:Fe(["slash-menu",{"is-sheet":e.layout==="sheet"}]),"data-menu-frame":""},[e.items.length===0?(v(),E("div",fUe,D(f(i)("composer.noCommands")),1)):X("",!0),Wn(C("div",{id:"composer-slash-menu",ref_key:"scrollEl",ref:u,class:"slash-scroll",role:"listbox",style:Kt({maskImage:b.value,maxHeight:A.value}),onScroll:k},[(v(!0),E(Ee,null,pt(a.value,(L,M)=>(v(),E("div",{key:`${L.item.name}-${M}`,id:`composer-slash-option-${M}`,class:Fe(["slash-item",{active:M===o.activeIndex}]),role:"option","aria-selected":M===o.activeIndex,onMouseenter:N=>s("hover",M),onMousedown:wt(N=>s("select",L.item),["prevent"])},[C("span",pUe,[(v(!0),E(Ee,null,pt(L.namePieces,(N,I)=>(v(),E(Ee,{key:I},[N.hit?(v(),E("span",gUe,D(N.text),1)):(v(),E(Ee,{key:1},[$e(D(N.text),1)],64))],64))),128))]),C("span",mUe,[(v(!0),E(Ee,null,pt(L.descPieces,(N,I)=>(v(),E(Ee,{key:I},[N.hit?(v(),E("span",vUe,D(N.text),1)):(v(),E(Ee,{key:1},[$e(D(N.text),1)],64))],64))),128))])],42,hUe))),128))],36),[[Po,e.items.length>0]]),g.value&&e.items.length>0?(v(),E("div",{key:1,class:"scroll-thumb",onPointerdown:y,style:Kt({top:`${g.value.top}px`,height:`${g.value.height}px`})},null,36)):X("",!0)],2))}}),FL=kt(yUe,[["__scopeId","data-v-ac34fe29"]]),kUe={key:0,class:"mention-state dim",role:"status"},bUe={key:1,class:"mention-state dim",role:"status"},AUe=["id","aria-selected","onMouseenter","onMousedown"],CUe=["innerHTML"],wUe={class:"mention-name"},xUe={key:0,class:"mention-hit"},SUe={class:"mention-meta"},_Ue={class:"mention-name"},MUe={key:0,class:"mention-hit"},IUe={key:0,class:"mention-meta"},EUe={key:0,class:"mention-hit"},TUe=Xe({__name:"MentionMenu",props:{items:{},activeIndex:{},loading:{type:Boolean},stale:{type:Boolean,default:!1},layout:{default:"popup"}},emits:["select","hover"],setup(e,{expose:t,emit:n}){const i=e,o=n,{t:s}=zt();function r(M){return M.kind==="skill"?`skill:${M.skill.name}`:M.file.path}function l(M){return M.kind==="skill"?CA("skill","",M.skill.name):AA(M.file.path,M.file.name,M.kind==="folder")}function a(M){const N=M.endsWith("/")?M.slice(0,-1):M,I=N.lastIndexOf("/");return I===-1?"":N.slice(0,I)}function u(M){return Rk(M.skill.name,M.matchPositions,0)}function c(M){const N=M.path.endsWith("/")?M.path.slice(0,-1):M.path;return Rk(M.name,M.matchPositions,Math.max(0,N.length-M.name.length))}function d(M){return Rk(a(M.path),M.matchPositions,0)}const h=K(null),p=K(null);t({el:p});const g=K(!1),m=K(!1);let k=null;const w=K(null);function y(){const M=h.value;if(!M)return;g.value=M.scrollTop>0,m.value=M.scrollTop+M.clientHeight<M.scrollHeight-1;const{scrollTop:N,scrollHeight:I,clientHeight:z}=M;if(I<=z+1){w.value=null;return}const H=getComputedStyle(M),O=parseFloat(H.getPropertyValue("--menu-scrollbar-track-inset"))||0,R=parseFloat(H.getPropertyValue("--menu-scrollbar-thumb-min"))||24,j=z-O*2,$=Math.max(R,z/I*j),W=I-z,P=M.offsetTop+O+N/W*(j-$);w.value={top:P,height:$}}function b(){y()}let A=null;function T(M){const N=h.value,I=w.value;if(!N||!I)return;M.preventDefault(),A?.();const z=M.pointerId;M.target.setPointerCapture?.(M.pointerId);const H=getComputedStyle(N),O=parseFloat(H.getPropertyValue("--menu-scrollbar-track-inset"))||0,R=N.clientHeight-O*2-I.height,j=N.scrollHeight-N.clientHeight,$=M.clientY,W=N.scrollTop,P=V=>{V.pointerId!==z||R<=0||(N.scrollTop=W+(V.clientY-$)/R*j)},Z=V=>{V.pointerId===z&&ae()},ae=()=>{window.removeEventListener("pointerup",Z),window.removeEventListener("pointermove",P),window.removeEventListener("pointercancel",Z),A===ae&&(A=null)};A=ae,window.addEventListener("pointermove",P),window.addEventListener("pointerup",Z),window.addEventListener("pointercancel",Z)}const S=F(()=>{const M=g.value,N=m.value,I="var(--menu-scroll-fade)";if(M&&N)return`linear-gradient(to bottom, transparent 0, black ${I}, black calc(100% - ${I}), transparent 100%)`;if(M)return`linear-gradient(to bottom, transparent, black ${I})`;if(N)return`linear-gradient(to top, transparent, black ${I})`}),x=K("");function _(){const M=p.value,N=h.value,I=M?.offsetParent;if(!M||!N||!I)return;const z=getComputedStyle(M),H=parseFloat(z.getPropertyValue("--space-2"))||8,O=parseFloat(z.getPropertyValue("--space-2"))||8,R=(parseFloat(z.paddingTop)||0)+(parseFloat(z.paddingBottom)||0),j=parseFloat(getComputedStyle(N).getPropertyValue("--p-mention-menu-h"))||Number.POSITIVE_INFINITY,$=window.visualViewport?.offsetTop??0,W=I.getBoundingClientRect().top-$-H-O-R;x.value=`${Math.max(Math.floor(Math.min(j,W)),0)}px`,dt(()=>{y(),L()})}cn(()=>{if(i.layout==="sheet"){y(),typeof ResizeObserver=="function"&&h.value&&(k=new ResizeObserver(()=>y()),k.observe(h.value));return}if(_(),y(),typeof ResizeObserver=="function"&&h.value){k=new ResizeObserver(N=>{for(const I of N)I.target===h.value?y():_()}),k.observe(h.value);const M=p.value?.offsetParent;M&&k.observe(M)}window.addEventListener("resize",_),window.visualViewport?.addEventListener("resize",_),window.visualViewport?.addEventListener("scroll",_)}),_n(()=>{k?.disconnect(),k=null,A?.(),window.removeEventListener("resize",_),window.visualViewport?.removeEventListener("resize",_),window.visualViewport?.removeEventListener("scroll",_)});function L(){const M=h.value;if(!M)return;const N=M.querySelectorAll('[role="option"]')[i.activeIndex];if(!N)return;const I=M.getBoundingClientRect(),z=N.getBoundingClientRect(),H=z.top-I.top+M.scrollTop,O=H+z.height;H<M.scrollTop?M.scrollTop=H:O>M.scrollTop+M.clientHeight&&(M.scrollTop=O-M.clientHeight)}return Pe(()=>i.activeIndex,()=>{dt(L)}),Pe(()=>i.items,()=>{dt(()=>{y(),L()})}),(M,N)=>(v(),E("div",{ref_key:"menuEl",ref:p,class:Fe(["mention-menu",{"is-sheet":e.layout==="sheet"}]),"data-menu-frame":""},[i.loading&&i.items.length===0?(v(),E("div",kUe,D(f(s)("mention.searching")),1)):i.items.length===0?(v(),E("div",bUe,D(f(s)("mention.noMatch")),1)):X("",!0),i.loading&&i.items.length>0?(v(),ce(f(Oi),{key:2,class:"mention-spin",size:"xs"})):X("",!0),Wn(C("div",{id:"composer-mention-menu",ref_key:"scrollEl",ref:h,class:"mention-scroll",role:"listbox",style:Kt({maskImage:S.value,maxHeight:x.value}),onScroll:b},[(v(!0),E(Ee,null,pt(i.items,(I,z)=>(v(),E("div",{key:r(I),id:`composer-mention-option-${z}`,class:Fe(["mention-item",{active:z===i.activeIndex,stale:i.stale&&I.kind!=="skill"}]),role:"option","aria-selected":z===i.activeIndex,onMouseenter:H=>o("hover",z),onMousedown:wt(H=>o("select",I),["prevent"])},[C("span",{class:"mention-icon",innerHTML:l(I),"aria-hidden":"true"},null,8,CUe),I.kind==="skill"?(v(),E(Ee,{key:0},[C("span",wUe,[(v(!0),E(Ee,null,pt(u(I),(H,O)=>(v(),E(Ee,{key:O},[H.hit?(v(),E("span",xUe,D(H.text),1)):(v(),E(Ee,{key:1},[$e(D(H.text),1)],64))],64))),128))]),C("span",SUe,D(I.skill.description),1)],64)):(v(),E(Ee,{key:1},[C("span",_Ue,[(v(!0),E(Ee,null,pt(c(I.file),(H,O)=>(v(),E(Ee,{key:O},[H.hit?(v(),E("span",MUe,D(H.text),1)):(v(),E(Ee,{key:1},[$e(D(H.text),1)],64))],64))),128))]),a(I.file.path)?(v(),E("span",IUe,[(v(!0),E(Ee,null,pt(d(I.file),(H,O)=>(v(),E(Ee,{key:O},[H.hit?(v(),E("span",EUe,D(H.text),1)):(v(),E(Ee,{key:1},[$e(D(H.text),1)],64))],64))),128))])):X("",!0)],64))],42,AUe))),128))],36),[[Po,i.items.length>0]]),w.value&&i.items.length>0?(v(),E("div",{key:3,class:"scroll-thumb",onPointerdown:T,style:Kt({top:`${w.value.top}px`,height:`${w.value.height}px`})},null,36)):X("",!0)],2))}}),DL=kt(TUe,[["__scopeId","data-v-8b392586"]]),LUe={key:0,class:"sheet-root"},NUe=["aria-label"],FUe=["aria-label"],DUe={key:0,class:"sheet-head"},BUe={class:"sheet-title"},$Ue={class:"sheet-body"},RUe=Xe({__name:"BottomSheet",props:{modelValue:{type:Boolean},title:{default:""},closeOnEsc:{type:Boolean,default:!0}},emits:["update:modelValue","close"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t;function s(){o("update:modelValue",!1),o("close")}function r(l){l.key==="Escape"&&i.closeOnEsc&&s()}return Pe(()=>i.modelValue,l=>{l?oh.value+=1:oh.value=Math.max(0,oh.value-1),!(typeof document>"u")&&(l?document.addEventListener("keydown",r):document.removeEventListener("keydown",r))},{immediate:!0}),_n(()=>{i.modelValue&&(oh.value=Math.max(0,oh.value-1)),typeof document<"u"&&document.removeEventListener("keydown",r)}),(l,a)=>(v(),ce(fo,{name:"sheet"},{default:de(()=>[e.modelValue?(v(),E("div",LUe,[C("div",{class:"sheet-scrim",onClick:s}),C("div",{class:"sheet-panel",role:"dialog","aria-label":e.title||f(n)("mobile.sheetLabel")},[C("button",{type:"button",class:"sheet-grab","aria-label":f(n)("mobile.closeSheet"),onClick:s},null,8,FUe),e.title?(v(),E("div",DUe,[C("span",BUe,D(e.title),1)])):X("",!0),C("div",$Ue,[Rn(l.$slots,"default",{},void 0,!0)])],8,NUe)])):X("",!0)]),_:3}))}}),qh=kt(RUe,[["__scopeId","data-v-d719a5d1"]]),zUe={key:0,class:"att-strip"},OUe={key:1,class:"att-row"},PUe={key:0,class:"att-more"},jUe={class:"cin-wrap"},HUe=["onClick"],WUe={class:"am-icon"},qUe={class:"am-name"},UUe={key:0,class:"am-desc"},KUe={class:"input-row"},VUe=["placeholder","disabled","aria-expanded","aria-controls","aria-activedescendant"],ZUe=["aria-label"],GUe={class:"toolbar-left"},QUe=["aria-label","onKeydown"],YUe={class:"perm-pill-label"},JUe=["onClick"],XUe={class:"pd-info"},eKe={class:"pd-desc"},tKe={class:"pd-check"},nKe={key:1,class:"swarm-chip"},iKe={class:"swarm-label"},oKe={class:"toolbar-right"},sKe=["aria-label"],rKe=["aria-expanded","aria-label"],lKe={key:0,class:"think-suffix"},aKe={class:"mp-name"},uKe={class:"mp-name"},cKe=["aria-label"],dKe=["aria-label","disabled"],fKe={class:"md-list"},hKe={key:0,class:"md-section"},pKe=["onClick"],gKe={class:"md-check"},mKe={class:"md-name"},vKe={class:"md-provider"},yKe={key:1,class:"md-divider"},kKe={key:2,class:"md-section"},bKe=["onClick"],AKe={class:"md-check"},CKe={class:"md-name"},wKe={key:0,class:"md-divider"},xKe={class:"md-thinking"},SKe={class:"md-name"},_Ke={key:0,class:"md-note"},MKe={key:2,class:"md-note"},IKe={class:"md-cache-note"},EKe={class:"md-check md-more-icon"},TKe={class:"md-name"},LKe={key:1,class:"composer-footer"},NKe={class:"drop-card"},FKe={class:"msheet-search"},DKe={class:"msheet-search"},BKe=["onClick"],$Ke={class:"am-icon"},RKe={class:"am-name"},zKe={key:0,class:"am-desc"},BL=36,OKe=Xe({__name:"Composer",props:{running:{type:Boolean,default:!1},working:{type:Boolean,default:!1},starting:{type:Boolean,default:!1},sessionId:{},queued:{default:()=>[]},searchFiles:{type:Function,default:void 0},uploadImage:{type:Function,default:void 0},status:{},thinking:{},planMode:{type:Boolean},planArmed:{type:Boolean},swarmMode:{type:Boolean},goalMode:{type:Boolean},goal:{},activationBadges:{},models:{default:()=>[]},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{default:()=>[]},skills:{default:()=>[]},hideContext:{type:Boolean}},emits:["submit","steer","command","interrupt","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","createGoal","controlGoal","focusGoal","compact","pickModel","selectModel","login"],setup(e,{expose:t,emit:n}){const i=e,o=rg(),s=F(()=>i.starting?l("composer.starting"):i.running?l(o.value?"composer.placeholderRunningMobile":"composer.placeholderRunning"):i.goalMode?l("status.goalPlaceholder"):i.planArmed||i.planMode?l("status.planPlaceholder"):l("composer.placeholder")),r=n,{t:l,locale:a}=zt(),{text:u,editorRef:c,loadForEdit:d,clearDraft:h}=Dde({sessionId:()=>i.sessionId}),p=c;function g(){const Te=p.value;Te&&(Te.style.height="auto",Te.style.height=`${Te.scrollHeight}px`)}Pe(u,()=>void dt(g));const m=K(!1);function k(){m.value=!m.value,dt(()=>{g(),A(),p.value?.focus()})}function w(){m.value&&(m.value=!1,dt(g))}function y(Te){if(typeof getComputedStyle>"u")return BL;const ct=Number.parseFloat(getComputedStyle(Te).minHeight);return Number.isFinite(ct)&&ct>0?ct:BL}const b=K(!1);function A(){const Te=p.value;b.value=!!Te&&Te.scrollHeight>y(Te)}Pe(u,()=>{dt(A)});const T=zde({text:u,editorRef:p,sessionId:()=>i.sessionId});function S(){oo.value||(i.goalMode&&r("toggleGoal"),r("togglePlan"))}function x(){if(so.value){r("focusGoal");return}i.goalMode||(oo.value&&r("togglePlan"),r("toggleGoal"))}const{open:_,items:L,ranges:M,active:N,update:I,select:z}=Ode({text:u,editorRef:p,skills:()=>i.skills,emitCommand:Te=>{if(Te==="/plan"){S();return}if(Te==="/goal"){x();return}if(Te==="/swarm"){qi.value||r("toggleSwarm");return}r("command",{cmd:Te,attachments:[]})},historyPush:Te=>T.push(Te),clearDraft:h,resolveDesc:Te=>Te.isSkill?Te.desc:l(Te.desc)}),H=F(()=>u.value.startsWith("/")&&!u.value.includes(" ")?u.value.slice(1):""),O=F(()=>{if(_.value)return"composer-slash-menu";if(j.value)return"composer-mention-menu"}),R=F(()=>{if(_.value&&L.value.length>0)return`composer-slash-option-${N.value}`;if(j.value&&$.value.length>0)return`composer-mention-option-${W.value}`}),{open:j,items:$,active:W,loading:P,fileStale:Z,update:ae,close:V,select:Y,navigate:oe,getToken:q}=Wde({text:u,editorRef:p,searchFiles:()=>i.searchFiles}),ne=F({get:()=>H.value,set:Te=>{u.value=`/${Te}`,I()}}),ie=K(null),pe=K("");Pe(pe,Te=>{const ct=ie.value;if(ct==null||!j.value)return;const at=u.value,Nn=at.slice(ct+1).search(/\s/),no=Nn===-1?at.length:ct+1+Nn;u.value=`${at.slice(0,ct)}@${Te}${at.slice(no)}`,dt(()=>{const Js=p.value,zo=ct+1+Te.length;Js&&Js.setSelectionRange(zo,zo),ae()})});const Ne=K(null),te=K(null);Pe(_,Te=>{Te&&o.value&&dt(()=>Ne.value?.focus())}),Pe(j,Te=>{if(Te&&o.value){const ct=q();ie.value=ct?.start??null,pe.value=ct?.token??"",dt(()=>te.value?.focus())}else ie.value=null});function be(){_.value=!1}function Q(){V()}function ue(){Vn()}const Ae=K(null),se=K(null),re=F(()=>Ae.value?.el??null),G=F(()=>se.value?.el??null);sc(_,re),sc(j,G),Pe(()=>i.sessionId,()=>{m.value=!1,_.value=!1,V()});function le(){o.value||(_.value=!1,V())}function ge(){T.resetBrowsing(),I(),ae(),(_.value||j.value||Kn.value)&&Vn()}function ke(Te){const ct=Te.map(zo=>/\s/.test(zo)?`"${zo}"`:zo).join(" "),at=p.value,Ht=u.value,Nn=at&&document.activeElement===at?at.selectionStart:Ht.length,no=Nn>0&&!/\s/.test(Ht[Nn-1])?" ":"",Js=Nn<Ht.length&&!/\s/.test(Ht[Nn])?" ":"";T.resetBrowsing(),u.value=Ht.slice(0,Nn)+no+ct+Js+Ht.slice(Nn),dt(()=>{const zo=p.value;if(!zo)return;const Wl=Nn+no.length+ct.length;zo.setSelectionRange(Wl,Wl),zo.focus(),g()})}const{attachments:Ie,previewAttachment:Oe,fileInputRef:we,isDragOver:Be,removeAttachment:tt,openAttachmentPreview:ut,closeAttachmentPreview:_t,openFilePicker:Ct,handleFileInputChange:$t,handleDragOver:Vt,handleDragLeave:nn,handleDrop:gt,clearAfterSubmit:Le,clearAttachments:ze,loadAttachments:Ye}=rfe({api:Ic(),uploadImage:()=>i.uploadImage,sessionId:()=>i.sessionId,insertFolderPaths:ke}),Tt=Te=>Te.kind==="image"||Te.kind==="video",on=F(()=>Ie.value.filter(Tt)),jt=F(()=>Ie.value.filter(Te=>!Tt(Te))),kn=K(null),bn=K(null),mn=K(!1);function zn(){const Te=kn.value,ct=bn.value;mn.value=Te!==null&&ct!==null&&ct.scrollHeight>Te.clientHeight+1}let He=null;Pe(kn,Te=>{if(He?.disconnect(),He=null,Te){const ct=new ResizeObserver(zn);ct.observe(Te),He=ct}zn()},{immediate:!0}),Pe(Ie,()=>void dt(zn),{deep:!0}),_n(()=>He?.disconnect());const st=K(null);Pe(()=>[on.value.length,jt.value.length],([Te,ct],[at,Ht])=>{Te<=at&&ct<=Ht||dt(()=>{const Nn=kn.value;Nn&&(Te>at&&st.value?Nn.scrollTop=st.value.offsetHeight-Nn.clientHeight:Nn.scrollTop=Nn.scrollHeight)})}),cn(()=>{u.value&&dt(()=>{g(),A()})}),_n(()=>{Er()});function et(){p.value?.focus({preventScroll:!0})}function Nt(Te){Ye(Te)}const Lt=K(null);function qn(Te,ct){if(Te.kind==="file"){Te.fileId!==void 0&&dH(Ic(),Te.fileId,Te.name,Te.mediaType);return}Lt.value=ct??null,ut(Te)}const So=F(()=>{const Te=Oe.value;return!Te||!Te.previewUrl?null:{kind:Te.kind==="video"?"video":"image",url:Te.previewUrl,path:Te.name,fileId:Te.previewUrl.startsWith("blob:")?void 0:Te.fileId,sessionId:Te.previewUrl.startsWith("blob:")?void 0:Te.sessionId}}),Yn=F(()=>!Ie.value.some(Te=>Te.uploading)&&(u.value.trim()!==""||Ie.value.some(Te=>!Te.error&&Te.fileId)));function Ir(){const Te=u.value.trim();if(Ie.value.some(Ht=>Ht.uploading))return;const ct=Ie.value.filter(Ht=>!Ht.uploading&&!Ht.error&&Ht.fileId);if(!Te&&ct.length===0)return;if(T.push(Te),Te==="/plan"){u.value="",h(),_.value=!1,w(),S();return}if(Te==="/goal"){u.value="",h(),_.value=!1,w(),x();return}if(Te==="/swarm"){u.value="",h(),_.value=!1,w(),qi.value||r("toggleSwarm");return}if(Te){const Ht=Yue(Te),Nn=Ht?Jue(c$(i.skills),Ht.cmd):void 0;if(Ht&&Nn){const no=Ht.arg?`${Ht.cmd} ${Ht.arg}`:Ht.cmd,Js=Nn.isSkill===!0;u.value="",h(),_.value=!1,w(),Js?(Oe.value=null,Lt.value=null,Le(),V(),r("command",{cmd:no,attachments:ct.map(zo=>Nm(zo))})):r("command",{cmd:no,attachments:[]});return}if(Ht&&!Nn&&Ht.cmd.startsWith(`/${Zd}`)){const no=Ht.arg?`${Ht.cmd} ${Ht.arg}`:Ht.cmd;u.value="",h(),_.value=!1,w(),Oe.value=null,Lt.value=null,Le(),V(),r("command",{cmd:no,attachments:ct.map(Js=>Nm(Js))});return}}const at={text:Te,attachments:ct.map(Ht=>Nm(Ht))};Oe.value=null,Lt.value=null,Le(),u.value="",h(),_.value=!1,V(),w(),r("submit",at)}function _o(){if(!i.running||Ie.value.some(Ht=>Ht.uploading))return;const Te=u.value.trim(),ct=Ie.value.filter(Ht=>!Ht.uploading&&!Ht.error&&Ht.fileId);if(!Te&&ct.length===0&&i.queued.length===0)return;const at={text:Te,attachments:ct.map(Ht=>Nm(Ht))};Le(),T.push(Te),u.value="",h(),_.value=!1,V(),w(),r("steer",at)}let It=!1,ms=null;function Er(){ms!==null&&(clearTimeout(ms),ms=null)}function go(){Er(),It=!0}function mo(){Er(),ms=setTimeout(()=>{ms=null,It=!1},0)}function vs(Te){return It||Te.isComposing||Te.keyCode===229}function _i(Te){if(vs(Te))return;if(Ro.value&&Te.key==="Backspace"&&!Te.shiftKey&&!Te.altKey&&!Te.metaKey&&!Te.ctrlKey){const at=p.value;if(at&&at.selectionStart===0&&at.selectionEnd===0){Te.preventDefault(),ot();return}}if(Te.key==="Escape"){if(Kn.value){Te.preventDefault(),Vn();return}if(Tn.value){Te.preventDefault(),qo();return}if(Un.value){Te.preventDefault(),ks();return}}if(_.value){if(Te.key==="Escape"){Te.preventDefault(),_.value=!1;return}if(Te.key==="Tab"&&L.value.length===0){_.value=!1;return}}if(_.value&&L.value.length>0){if(Te.key==="ArrowDown"){Te.preventDefault(),N.value=(N.value+1)%L.value.length;return}if(Te.key==="ArrowUp"){Te.preventDefault(),N.value=(N.value-1+L.value.length)%L.value.length;return}if(Te.key==="Enter"||Te.key==="Tab"){Te.preventDefault();const at=L.value[N.value];at&&z(at);return}}if(j.value){if(Te.key==="Escape"){Te.preventDefault(),V();return}if(Te.key==="Tab"&&$.value.length===0){V();return}if($.value.length>0){if(Te.key==="ArrowDown"){Te.preventDefault(),oe((W.value+1)%$.value.length);return}if(Te.key==="ArrowUp"){Te.preventDefault(),oe((W.value-1+$.value.length)%$.value.length);return}if(Te.key==="Enter"||Te.key==="Tab"){Te.preventDefault();const at=$.value[W.value];at&&Y(at);return}}}if(Te.key==="s"&&(Te.ctrlKey||Te.metaKey)&&!Te.shiftKey&&!Te.altKey){i.running&&(Te.preventDefault(),_o());return}const ct=_.value&&L.value.length>0;if(!m.value&&!ct&&!j.value&&!Te.shiftKey&&!Te.altKey&&!Te.metaKey&&!Te.ctrlKey){const at=T.isBrowsing();if(Te.key==="ArrowUp"&&T.hasHistory()&&(at||T.caretAtTextStart())){Te.preventDefault(),T.recallOlder(),_.value=!1;return}if(Te.key==="ArrowDown"&&at){Te.preventDefault(),T.recallNewer(),_.value=!1;return}}if(Te.key==="Enter"&&!Te.shiftKey){if(m.value&&!(Te.metaKey||Te.ctrlKey))return;Te.preventDefault(),Ir()}}const Mo=F(()=>l("composer.send")),ys=F(()=>!!i.uploadImage),Tn=K(!1),Un=K(!1),Kn=K(!1),Pi=K(null),Io=K(null),Ki=K(null),Ti=K(null),Qs=K(null),Li=K(null);sc(Kn,Io),sc(Un,Qs);const an=K(null),to=K(null);let Jn=null;function Wo(){const Te=an.value;if(!Te)return;const{scrollTop:ct,scrollHeight:at,clientHeight:Ht}=Te;if(at<=Ht+1){to.value=null;return}const Nn=getComputedStyle(Te),no=parseFloat(Nn.getPropertyValue("--menu-scrollbar-track-inset"))||0,Js=parseFloat(Nn.getPropertyValue("--menu-scrollbar-thumb-min"))||24,zo=Ht-no*2,Wl=Math.max(Js,Ht/at*zo),us=at-Ht,cr=Te.offsetTop+no+ct/us*(zo-Wl);to.value={top:cr,height:Wl}}function Mn(){Wo()}Pe(Kn,async Te=>{Jn?.disconnect(),Jn=null,to.value=null,Te&&(await dt(),Wo(),typeof ResizeObserver=="function"&&an.value&&(Jn=new ResizeObserver(Wo),Jn.observe(an.value)))}),_n(()=>{Jn?.disconnect(),Jn=null});const Ni=K(""),wi=K(""),$o=K(!1),$s=F(()=>{const Te={};return Ni.value&&(Te.right=Ni.value),wi.value&&(Te.maxHeight=wi.value),Te}),Vi=F(()=>Tn.value||Un.value||Kn.value||_.value||j.value);t({loadForEdit:d,loadAttachmentsForEdit:Nt,focus:et,anyPopupOpen:Vi,isEmpty:()=>u.value.trim().length===0&&Ie.value.length===0});function Rs(){Tn.value=!Tn.value,Tn.value?(ur(),Un.value=!1,Kn.value=!1,document.addEventListener("click",Xn,!0)):document.removeEventListener("click",Xn,!0)}function qo(){Tn.value=!1,!Un.value&&!Kn.value&&document.removeEventListener("click",Xn,!0)}function ar(){Un.value=!Un.value,Un.value?(el(),Tn.value=!1,Kn.value=!1,document.addEventListener("click",Xn,!0)):document.removeEventListener("click",Xn,!0)}function ks(){Un.value=!1,!Tn.value&&!Kn.value&&document.removeEventListener("click",Xn,!0)}function yi(){Kn.value=!Kn.value,Kn.value?(Tn.value=!1,Un.value=!1,_.value=!1,V(),document.addEventListener("click",Xn,!0),dt(()=>{(o.value?Ki.value:Io.value)?.querySelector(".am-row")?.focus()})):document.removeEventListener("click",Xn,!0)}function Vn(){Kn.value=!1,!Tn.value&&!Un.value&&document.removeEventListener("click",Xn,!0)}const ji=F(()=>{const Te=[];return ys.value&&Te.push({id:"files",icon:"attachment",nameKey:"composer.addFiles",descKey:"composer.addFilesDesc",action:As}),o.value&&(Te.push({id:"slash",icon:"terminal",nameKey:"composer.addSlash",descKey:"composer.addSlashDesc",action:Tr}),Te.push({id:"mention",icon:"link",nameKey:"composer.addMention",descKey:"composer.addMentionDesc",action:Lr})),Te.push({id:"goal",icon:"target",nameKey:"status.goalLabel",descKey:"composer.addGoalDesc",action:jl}),Te.push({id:"plan",icon:"file-edit",nameKey:"status.planLabel",descKey:"composer.addPlanDesc",action:Nr}),Te.push({id:"swarm",icon:"sparkles",nameKey:"status.swarmLabel",descKey:"composer.addSwarmDesc",action:Di}),Te});function Fi(Te){Te.action(),!(o.value&&Te.id==="files")&&p.value?.focus()}function bs(Te){if(Te.key==="Escape"){Te.preventDefault(),Vn(),p.value?.focus();return}if(Te.key==="Tab"){Vn();return}if(Te.key!=="ArrowDown"&&Te.key!=="ArrowUp")return;Te.preventDefault();const ct=o.value?Ki.value:Io.value,at=Array.from(ct?.querySelectorAll(".am-row")??[]);if(at.length===0)return;const Ht=at.indexOf(document.activeElement),Nn=Te.key==="ArrowDown"?(Ht+1)%at.length:(Ht-1+at.length)%at.length;at[Nn]?.focus()}function As(){Vn(),Ct()}function Eo(Te){Vn(),u.value=Te,dt(()=>{const ct=p.value;ct&&ct.setSelectionRange(ct.value.length,ct.value.length),Te==="/"?I():ae()})}function Tr(){Eo("/")}function Lr(){Eo("@")}function jl(){Vn(),i.goalMode||x()}function Nr(){Vn(),oo.value||S()}function Di(){Vn(),qi.value||r("toggleSwarm")}function Xn(Te){const ct=Te.target,at=Pi.value?.contains(ct)??!1,Ht=Io.value?.contains(ct)??!1;!at&&!Ht&&(qo(),ks(),Vn())}_n(()=>{document.removeEventListener("click",Xn,!0)});const Cs=F(()=>{const Te=i.status?.ctxMax??0;return Te<=0?0:Math.min(100,Math.max(0,Math.ceil((i.status?.ctxUsed??0)/Te*100)))}),Uo=F(()=>{const Te=_u(i.status?.ctxUsed??0),ct=_u(i.status?.ctxMax??0);return l("status.ctxTooltip",{used:Te,max:ct,pct:Cs.value})}),On=F(()=>Cs.value>=80),Hi=F(()=>i.models?.find(Te=>Te.id===i.status?.modelId)),Wi=F(()=>u9(Hi.value)),rs=F(()=>c9(Hi.value)),jn=F(()=>E6(Hi.value,i.thinking)),Ke=F(()=>rs.value.includes(jn.value)?jn.value:""),Ue=F(()=>qre(jn.value)),yt=F(()=>Wi.value==="unsupported"||rs.value.length<=1),xt=F(()=>{if(!Ue.value)return"";const Te=(Hi.value?.supportEfforts?.length??0)>0,ct=jn.value;return Te&&ct!=="on"?l("composer.thinkingSuffixEffort",{level:ct}):l("composer.thinkingSuffix")});function rn(Te){yt.value||r("setThinking",IB(Hi.value,Te))}function Zi(Te){return Te==="on"?l("status.thinkingOn"):Te==="off"?l("status.thinkingOff"):zb(Te)}const Gi=F(()=>rs.value.map(Te=>({value:Te,label:Zi(Te)}))),oo=F(()=>i.planArmed===!0||i.planMode===!0),qi=F(()=>i.swarmMode===!0),vo=F(()=>i.goal?.status??i.activationBadges?.goal?.status??null),so=F(()=>vo.value!==null&&vo.value!=="complete"),Ro=F(()=>i.goalMode?"goal":i.planArmed?"plan":null);function ot(){Ro.value==="goal"?r("toggleGoal"):Ro.value==="plan"&&r("togglePlan")}const xe=K(null),je=K(""),Dn=F(()=>je.value?{textIndent:je.value}:void 0);let vn=null;function ii(){const Te=xe.value;je.value=Te?`calc(${Te.offsetWidth}px + var(--space-1-5) - var(--space-05))`:""}Pe(Ro,async Te=>{if(vn?.disconnect(),vn=null,!Te){je.value="";return}await dt(),ii(),typeof ResizeObserver=="function"&&xe.value&&(vn=new ResizeObserver(ii),vn.observe(xe.value))},{immediate:!0}),_n(()=>{vn?.disconnect(),vn=null});const ws=[{mode:"manual",icon:"hand",color:"var(--color-text)",labelKey:"status.permissionManual",descKey:"status.permissionManualDesc"},{mode:"yolo",icon:"shield-question",color:"var(--color-warning)",labelKey:"status.permissionYolo",descKey:"status.permissionYoloDesc"},{mode:"auto",icon:"full-access",color:"var(--color-danger)",labelKey:"status.permissionAuto",descKey:"status.permissionAutoDesc"}],xs=K(null),ro=K(""),ai=K("");function Ys(Te){const ct={};return Te&&(ct["--composer-menu-desc-width"]=Te),ct}const Ss=F(()=>({...Ys(ro.value),...ai.value?{left:ai.value}:{}}));function el(){const Te=Ti.value,ct=Pi.value;if(!Te||!ct){ai.value="";return}ai.value=`${Math.round(Te.getBoundingClientRect().left-ct.getBoundingClientRect().left)}px`}function ur(){const Te=Li.value,ct=Pi.value;if(!Te||!ct){Ni.value="";return}Ni.value=`${Math.round(ct.getBoundingClientRect().right-Te.getBoundingClientRect().right)}px`}let tl=null;function ee(Te){const ct=Number.parseFloat(Te);return Number.isFinite(ct)?ct:0}function me(Te){return`${Te.fontStyle||"normal"} ${Te.fontWeight||"400"} ${Te.fontSize} ${Te.fontFamily}`}function Me(Te){return Te.letterSpacing==="normal"?0:ee(Te.letterSpacing)}function Re(Te,ct){if(!Te)return 0;const at=cUe(Te,me(ct),{letterSpacing:Me(ct)});return dUe(at)}function Qe(){const Te=xs.value?.querySelector(".pd-desc");if(!Te)return;const ct=getComputedStyle(Te),at=Math.max(0,...ws.map(Ht=>Re(l(Ht.descKey),ct)));ro.value=at>0?`${Math.ceil(at)}px`:""}function Je(){typeof window>"u"||(tl!==null&&window.cancelAnimationFrame(tl),dt(()=>{tl=window.requestAnimationFrame(()=>{tl=null,Qe()})}))}Pe(a,()=>{Je(),_.value&&I()},{immediate:!0}),cn(()=>{Je(),document.fonts?.ready.then(Je)}),_n(()=>{tl!==null&&(window.cancelAnimationFrame(tl),tl=null)});function ft(Te){r("setPermission",Te),ks()}const vt=F(()=>ws.find(Te=>Te.mode===i.status?.permission)),Pt=F(()=>vt.value?l(vt.value.labelKey):""),fn=F(()=>vt.value?.icon??"hand"),dn=K(!1),ui=K(!1),Ln=K(null);let Sn=0,fi=0;function Ui(){const Te=Pi.value?getComputedStyle(Pi.value):null;return{valveFloor:Te?Fr(Te,"--composer-valve-floor",56):56,expandMargin:Te?Fr(Te,"--composer-valve-expand-margin",48):48}}function Fr(Te,ct,at){const Ht=Te.getPropertyValue(ct).trim(),Nn=parseFloat(Ht);return Number.isFinite(Nn)?Ht.endsWith("em")?Nn*parseFloat(Te.fontSize):Nn:at}function ya(Te){return Te.scrollWidth>Te.clientWidth+1||Te.clientWidth===0&&(Te.textContent?.length??0)>0}function ka(){const Te=Pi.value;if(!Te)return;const{valveFloor:ct,expandMargin:at}=Ui(),Ht=Te.getBoundingClientRect().width;if(ui.value){Ht>fi+at&&(ui.value=!1,dt(ka));return}if(dn.value&&Ht>Sn+at){dn.value=!1,dt(ka);return}const Nn=Ln.value;Nn!==null&&ya(Nn)&&Nn.getBoundingClientRect().width<ct&&(dn.value?(fi=Ht,ui.value=!0):(Sn=Ht,dn.value=!0),dt(ka))}let Du=null;cn(()=>{typeof ResizeObserver>"u"||!Pi.value||(Du=new ResizeObserver(ka),Du.observe(Pi.value))}),_n(()=>{Du?.disconnect(),Du=null});const{fontScale:v1}=c1();Pe([Pt,qi,On,xt,()=>i.status?.model,()=>i.working,()=>i.authReady,()=>i.managedSignedIn,()=>i.managedMembership,()=>i.models?.length,v1,a],()=>{dn.value&&(dn.value=!1),ui.value&&(ui.value=!1),dt(ka)}),cn(()=>{document.fonts?.ready.then(ka)});const ye=F(()=>`${i.status?.model??""}${xt.value}`),Se=F(()=>Hi.value?.provider??""),Ve=F(()=>!Se.value||!i.models?.length?[]:i.models.filter(Te=>Te.provider===Se.value)),Rt=F(()=>(i.models?.length??0)>0),Yt=F(()=>i.authReady===!1&&!Rt.value),wn=F(()=>Yt.value&&!(i.managedSignedIn??!1)),ei=F(()=>Yt.value&&(i.managedSignedIn??!1)&&i.managedMembership==="free"),Bi=F(()=>new Set(i.starredIds??[]));function Ko(Te){return Bi.value.has(Te)}const ls=F(()=>i.models?.length?i.models.filter(Te=>Ko(Te.id)&&Te.provider!==Se.value):[]),Hl=K(null);sc(Tn,Hl);function V9(){const Te=Hl.value,ct=Pi.value;if(!Te||!ct)return;const at=getComputedStyle(Te),Ht=ee(at.getPropertyValue("--space-1"))||4,Nn=ee(at.getPropertyValue("--space-2"))||8,no=window.visualViewport,Js=no?.offsetTop??0,zo=Js+(no?.height??window.innerHeight),Wl=ct.getBoundingClientRect(),us=Wl.top-Js-Ht-Nn,cr=zo-Wl.bottom-Ht-Nn;Te.offsetHeight>us&&cr>us?($o.value=!0,wi.value=`${Math.max(Math.floor(cr),0)}px`):($o.value=!1,wi.value=`${Math.max(Math.floor(us),0)}px`)}function Za(){qo()}function Ng(){window.addEventListener("resize",Za),window.visualViewport?.addEventListener("resize",Za),window.visualViewport?.addEventListener("scroll",Za)}function Al(){window.removeEventListener("resize",Za),window.visualViewport?.removeEventListener("resize",Za),window.visualViewport?.removeEventListener("scroll",Za)}Pe(Tn,async Te=>{if(!Te){Al();return}Ng(),$o.value=!1,wi.value="",await dt(),V9(),(Hl.value?.querySelector(".md-row.is-current")??Hl.value?.querySelector(".md-row"))?.focus()}),_n(()=>{Al()});function as(Te){if(Te.key!=="ArrowDown"&&Te.key!=="ArrowUp")return;const ct=Array.from(Hl.value?.querySelectorAll(".md-row:not(:disabled)")??[]);if(!ct.length)return;Te.preventDefault();const at=ct.indexOf(document.activeElement),Ht=Te.key==="ArrowDown"?(at+1)%ct.length:(at-1+ct.length)%ct.length;ct[Ht]?.focus()}function Bu(Te){r("selectModel",Te),qo()}return(Te,ct)=>(v(),E("div",{class:Fe(["composer",{"drag-over":f(Be),expanded:m.value}]),onDragover:ct[21]||(ct[21]=(...at)=>f(Vt)&&f(Vt)(...at)),onDragleave:ct[22]||(ct[22]=(...at)=>f(nn)&&f(nn)(...at)),onDrop:ct[23]||(ct[23]=(...at)=>f(gt)&&f(gt)(...at))},[So.value?(v(),ce(IA,{key:0,media:So.value,"origin-img":Lt.value,onClose:ct[0]||(ct[0]=at=>{Lt.value=null,f(_t)()})},null,8,["media","origin-img"])):X("",!0),C("div",{class:Fe(["composer-card",{"labels-collapsed":dn.value}])},[f(Ie).length>0?(v(),E("div",zUe,[C("div",{ref_key:"attScrollRef",ref:kn,class:Fe(["att-scroll",{"is-overflowing":mn.value}])},[C("div",{ref_key:"attScrollContentRef",ref:bn,class:"att-scroll-content"},[on.value.length>0?(v(),E("div",{key:0,ref_key:"attMediaRowRef",ref:st,class:"att-row att-row-media"},[(v(!0),E(Ee,null,pt(on.value,at=>(v(),ce(CH,{key:at.localId,kind:at.kind,name:at.name,url:at.previewUrl,"file-id":at.fileId,"session-id":at.sessionId,uploading:at.uploading,error:at.error,removable:"","remove-label":f(l)("composer.removeNamed",{name:at.name}),onActivate:Ht=>qn(at,Ht),onRemove:Ht=>f(tt)(at.localId)},null,8,["kind","name","url","file-id","session-id","uploading","error","remove-label","onActivate","onRemove"]))),128))],512)):X("",!0),jt.value.length>0?(v(),E("div",OUe,[(v(!0),E(Ee,null,pt(jt.value,at=>(v(),ce(wH,{key:at.localId,kind:"file",name:at.name,"media-type":at.mediaType,size:at.size,uploading:at.uploading,error:at.error,removable:"","remove-label":f(l)("composer.removeNamed",{name:at.name}),onActivate:Ht=>qn(at),onRemove:Ht=>f(tt)(at.localId)},null,8,["name","media-type","size","uploading","error","remove-label","onActivate","onRemove"]))),128))])):X("",!0)],512)],2),mn.value?(v(),E("span",PUe,D(f(l)("composer.attachmentCount",{n:f(Ie).length})),1)):X("",!0),f(Ie).length>=2?(v(),ce(f(gn),{key:1,text:f(l)("composer.clearAll")},{default:de(()=>[U(f(Jt),{class:"att-clear",size:"sm",label:f(l)("composer.clearAll"),onClick:f(ze)},{default:de(()=>[U(f(ve),{name:"trash"})]),_:1},8,["label","onClick"])]),_:1},8,["text"])):X("",!0)])):X("",!0),C("div",jUe,[f(_)&&!f(o)?(v(),ce(FL,{key:0,ref_key:"slashMenuRef",ref:Ae,items:f(L),ranges:f(M),"active-index":f(N),query:H.value,onSelect:f(z),onHover:ct[1]||(ct[1]=at=>N.value=at)},null,8,["items","ranges","active-index","query","onSelect"])):X("",!0),f(j)&&!f(o)?(v(),ce(DL,{key:1,ref_key:"mentionMenuRef",ref:se,items:f($),"active-index":f(W),loading:f(P),stale:f(Z),onSelect:f(Y),onHover:f(oe)},null,8,["items","active-index","loading","stale","onSelect","onHover"])):X("",!0),U(fo,{name:"composer-menu-pop"},{default:de(()=>[Kn.value&&!f(o)?(v(),E("div",{key:0,ref_key:"addMenuRef",ref:Io,class:"add-menu",onClick:ct[3]||(ct[3]=wt(()=>{},["stop"])),onKeydown:bs},[C("div",{ref_key:"addScrollRef",ref:an,class:"am-scroll",role:"menu",onScroll:Mn},[(v(!0),E(Ee,null,pt(ji.value,at=>(v(),E("button",{key:at.id,type:"button",class:"am-row",role:"menuitem",onMousedown:ct[2]||(ct[2]=wt(()=>{},["prevent"])),onClick:Ht=>Fi(at)},[C("span",WUe,[U(f(ve),{name:at.icon,size:"sm"},null,8,["name"])]),C("span",qUe,D(f(l)(at.nameKey)),1),at.descKey?(v(),E("span",UUe,D(f(l)(at.descKey)),1)):X("",!0)],40,HUe))),128))],544),to.value?(v(),E("div",{key:0,class:"scroll-thumb",style:Kt({top:`${to.value.top}px`,height:`${to.value.height}px`})},null,4)):X("",!0)],544)):X("",!0)]),_:1}),C("div",KUe,[Ro.value?(v(),E("span",{key:0,ref_key:"wmPillRef",ref:xe,class:"wm-pill"},[U(f(ve),{name:Ro.value==="goal"?"target":"file-edit",size:"sm"},null,8,["name"]),C("span",null,D(Ro.value==="goal"?f(l)("status.goalLabel"):f(l)("status.planLabel")),1),U(f(Jt),{class:"wm-x",size:"sm",label:f(l)("status.workModeDismiss"),tooltip:f(l)("status.workModeDismiss"),onMousedown:ct[4]||(ct[4]=wt(()=>{},["prevent"])),onClick:ot},{default:de(()=>[U(f(ve),{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])],512)):X("",!0),Wn(C("textarea",{ref_key:"textareaRef",ref:p,"onUpdate:modelValue":ct[5]||(ct[5]=at=>io(u)?u.value=at:null),class:"ph",style:Kt(Dn.value),placeholder:s.value,disabled:e.starting,autocomplete:"off",spellcheck:"false",rows:"1",role:"combobox","aria-autocomplete":"list","aria-haspopup":"listbox","aria-expanded":!!O.value,"aria-controls":O.value,"aria-activedescendant":R.value,onKeydown:_i,onCompositionstart:go,onCompositionend:mo,onInput:ge,onBlur:le},null,44,VUe),[[Bs,f(u)]]),U(f(gn),{text:m.value?f(l)("composer.collapseTitle"):f(l)("composer.expandTitle")},{default:de(()=>[m.value||b.value?(v(),E("button",{key:0,class:"expand-btn",type:"button","aria-label":m.value?f(l)("composer.collapseTitle"):f(l)("composer.expandTitle"),onClick:k},[m.value?(v(),ce(f(ve),{key:0,name:"collapse",size:"sm"})):(v(),ce(f(ve),{key:1,name:"expand",size:"sm"}))],8,ZUe)):X("",!0)]),_:1},8,["text"])])]),ys.value?(v(),E("input",{key:1,ref_key:"fileInputRef",ref:we,type:"file",multiple:"",class:"file-input-hidden",onChange:ct[6]||(ct[6]=(...at)=>f($t)&&f($t)(...at))},null,544)):X("",!0),C("div",{ref_key:"toolbarRef",ref:Pi,class:"toolbar"},[C("div",{ref_key:"menuMeasureRef",ref:xs,class:"menu-measure","aria-hidden":"true"},[...ct[24]||(ct[24]=[C("span",{class:"pd-desc"},null,-1)])],512),C("div",GUe,[U(f(Jt),{class:"composer-attach",size:"md",label:f(l)("composer.addMenu"),tooltip:f(l)("composer.addMenu"),"aria-haspopup":"menu","aria-expanded":Kn.value,onMousedown:ct[7]||(ct[7]=wt(()=>{},["prevent"])),onClick:wt(yi,["stop"])},{default:de(()=>[U(f(ve),{name:"plus"})]),_:1},8,["label","tooltip","aria-expanded"]),e.status?(v(),ce(f(gn),{key:0,text:dn.value?Pt.value:null},{default:de(()=>[C("span",{ref_key:"permPillRef",ref:Ti,class:Fe(["perm-pill",["perm-"+e.status.permission,{open:Un.value}]]),role:"button",tabindex:"0","aria-label":Pt.value,onClick:wt(ar,["stop"]),onKeydown:[Ho(ar,["enter"]),Ho(wt(ar,["prevent"]),["space"])]},[U(f(ve),{class:"perm-pill-icon",name:fn.value,size:"md"},null,8,["name"]),C("span",YUe,D(Pt.value),1)],42,QUe)]),_:1},8,["text"])):X("",!0),U(fo,{name:"composer-menu-pop"},{default:de(()=>[Un.value&&e.status?(v(),E("div",{key:0,ref_key:"permDropdownRef",ref:Qs,class:"perm-dropdown",style:Kt(Ss.value),role:"menu",onClick:ct[8]||(ct[8]=wt(()=>{},["stop"]))},[(v(),E(Ee,null,pt(ws,at=>C("button",{key:at.mode,class:Fe(["pd-row",{"is-current":at.mode===e.status.permission}]),role:"menuitem",onClick:Ht=>ft(at.mode)},[C("span",{class:"pd-icon",style:Kt({color:at.color})},[U(f(ve),{name:at.icon,size:"md"},null,8,["name"])],4),C("span",XUe,[C("span",{class:"pd-name",style:Kt({color:at.color})},D(f(l)(at.labelKey)),5),C("span",eKe,D(f(l)(at.descKey)),1)]),C("span",tKe,[at.mode===e.status.permission?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)])],10,JUe)),64))],4)):X("",!0)]),_:1}),qi.value?(v(),E("span",nKe,[U(f(ve),{class:"swarm-ic",name:"sparkles",size:"md"}),C("span",iKe,D(f(l)("status.swarmLabel")),1),U(f(Jt),{class:"swarm-x",size:"sm",label:f(l)("status.swarmDismiss"),tooltip:f(l)("status.swarmDismiss"),onMousedown:ct[9]||(ct[9]=wt(()=>{},["prevent"])),onClick:ct[10]||(ct[10]=wt(at=>r("toggleSwarm"),["stop"]))},{default:de(()=>[U(f(ve),{name:"close",size:"sm"})]),_:1},8,["label","tooltip"])])):X("",!0)]),C("div",oKe,[On.value?(v(),E("button",{key:0,class:"compact-chip",onClick:ct[11]||(ct[11]=wt(at=>r("compact"),["stop"]))},"/compact")):X("",!0),U(f(gn),{text:Uo.value},{default:de(()=>[e.status&&!e.hideContext?(v(),E("span",{key:0,class:"ctx-group",role:"img",tabindex:"0","aria-label":Uo.value},[U(f(IQ),{pct:Cs.value},null,8,["pct"])],8,sKe)):X("",!0)]),_:1},8,["text"]),e.status&&!wn.value&&!ei.value?(v(),ce(f(gn),{key:1,text:ui.value?ye.value:null},{default:de(()=>[C("button",{ref_key:"modelPillRef",ref:Li,type:"button",class:Fe(["model-pill",{open:Tn.value,"icon-only":ui.value}]),"aria-haspopup":"menu","aria-expanded":Tn.value,"aria-label":ui.value?ye.value:void 0,onClick:wt(Rs,["stop"])},[ui.value?(v(),ce(f(ve),{key:0,name:"model",size:"md"})):(v(),E(Ee,{key:1},[C("span",{ref_key:"mpNameRef",ref:Ln,class:"mp-name"},D(e.status.model),513),xt.value?(v(),E("span",lKe,D(xt.value),1)):X("",!0),U(f(ve),{class:"cv",name:"chevron-down",size:"sm"})],64))],10,rKe)]),_:1},8,["text"])):e.status&&ei.value?(v(),E("button",{key:2,type:"button",class:"model-pill login-pill",onClick:ct[12]||(ct[12]=wt(at=>f(sg)(),["stop"]))},[U(f(ve),{name:"music",size:"sm"}),C("span",aKe,D(f(l)("sidebar.upgrade")),1)])):e.status&&wn.value?(v(),E("button",{key:3,type:"button",class:"model-pill login-pill",onClick:ct[13]||(ct[13]=wt(at=>r("login"),["stop"]))},[U(f(ve),{name:"log-in",size:"sm"}),C("span",uKe,D(f(l)("login.action")),1)])):X("",!0),e.working?(v(),ce(f(gn),{key:4,text:f(l)("composer.interruptTitle")},{default:de(()=>[C("button",{class:"stop","aria-label":f(l)("composer.interrupt"),onClick:ct[14]||(ct[14]=at=>r("interrupt"))},[U(f(ve),{name:"stop",size:"sm"})],8,cKe)]),_:1},8,["text"])):X("",!0),U(f(gn),{text:Mo.value},{default:de(()=>[C("button",{class:Fe(["send",{"is-starting":e.starting}]),"aria-label":Mo.value,disabled:e.starting||!Yn.value,onClick:ct[15]||(ct[15]=at=>Ir())},[e.starting?(v(),ce(f(Oi),{key:0,size:"sm"})):(v(),ce(f(ve),{key:1,name:"send",size:"sm"}))],10,dKe)]),_:1},8,["text"])]),U(fo,{name:"composer-menu-pop"},{default:de(()=>[Tn.value&&e.status?(v(),E("div",{key:0,ref_key:"modelDropdownRef",ref:Hl,class:Fe(["model-dropdown",{"flip-down":$o.value}]),style:Kt($s.value),role:"menu",onClick:ct[17]||(ct[17]=wt(()=>{},["stop"])),onKeydown:as},[C("div",fKe,[ls.value.length>0?(v(),E("div",hKe,D(f(l)("status.starredModels")),1)):X("",!0),(v(!0),E(Ee,null,pt(ls.value,at=>(v(),E("button",{key:at.id,class:Fe(["md-row",{"is-current":at.id===e.status.modelId}]),role:"menuitem",onClick:Ht=>Bu(at.id)},[C("span",gKe,[at.id===e.status.modelId?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)]),C("span",mKe,D(at.displayName??at.model),1),C("span",vKe,D(at.provider),1),U(f(ve),{class:"md-star",name:"star",size:"sm"})],10,pKe))),128)),ls.value.length>0?(v(),E("div",yKe)):X("",!0),Ve.value.length>0?(v(),E("div",kKe,D(Se.value),1)):X("",!0),(v(!0),E(Ee,null,pt(Ve.value,at=>(v(),E("button",{key:at.id,class:Fe(["md-row",{"is-current":at.id===e.status.modelId}]),role:"menuitem",onClick:Ht=>Bu(at.id)},[C("span",AKe,[at.id===e.status.modelId?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)]),C("span",CKe,D(at.displayName??at.model),1),Ko(at.id)?(v(),ce(f(ve),{key:0,class:"md-star",name:"star",size:"sm"})):X("",!0)],10,bKe))),128))]),Ve.value.length>0?(v(),E("div",wKe)):X("",!0),C("div",xKe,[C("span",SKe,D(f(l)("status.thinkingLabel")),1),Wi.value==="unsupported"?(v(),E("span",_Ke,D(f(l)("status.modeNotSupported")),1)):rs.value.length>1?(v(),ce(f(Vs),{key:1,"model-value":Ke.value,options:Gi.value,size:"xs","onUpdate:modelValue":rn},null,8,["model-value","options"])):(v(),E("span",MKe,D(Zi(rs.value[0]??jn.value)),1))]),ct[25]||(ct[25]=C("div",{class:"md-divider"},null,-1)),C("div",IKe,D(f(l)("status.cacheNote")),1),ct[26]||(ct[26]=C("div",{class:"md-divider"},null,-1)),C("button",{class:"md-row md-row-more",role:"menuitem",onClick:ct[16]||(ct[16]=at=>{qo(),r("pickModel")})},[C("span",EKe,[U(f(ve),{name:"list",size:"sm"})]),C("span",TKe,D(f(l)("status.moreModels")),1),U(f(ve),{class:"md-more-arrow",name:"chevron-right",size:"sm"})])],38)):X("",!0)]),_:1})],512)],2),Te.$slots.footer?(v(),E("div",LKe,[Rn(Te.$slots,"footer",{},void 0,!0)])):X("",!0),C("div",{class:Fe(["drop-overlay",{show:f(Be)}]),"aria-hidden":"true"},[C("div",NKe,[U(f(ve),{name:"file-plus",size:"lg"}),C("span",null,D(f(l)("composer.dropToAttach")),1)])],2),(v(),ce(Ds,{to:"body"},[U(qh,{"model-value":f(o)&&f(_),title:f(l)("composer.slashSheetTitle"),"onUpdate:modelValue":be},{default:de(()=>[C("div",FKe,[U(f(Ns),{ref_key:"slashSearchRef",ref:Ne,modelValue:ne.value,"onUpdate:modelValue":ct[18]||(ct[18]=at=>ne.value=at),placeholder:f(l)("composer.slashSearchPlaceholder"),autocomplete:"off",spellcheck:"false",role:"combobox","aria-autocomplete":"list","aria-haspopup":"listbox","aria-expanded":!!O.value,"aria-controls":O.value,"aria-activedescendant":R.value,onKeydown:_i,onCompositionstart:go,onCompositionend:mo},null,8,["modelValue","placeholder","aria-expanded","aria-controls","aria-activedescendant"])]),U(FL,{layout:"sheet",items:f(L),ranges:f(M),"active-index":f(N),query:ne.value,onSelect:f(z),onHover:ct[19]||(ct[19]=at=>N.value=at)},null,8,["items","ranges","active-index","query","onSelect"])]),_:1},8,["model-value","title"])])),(v(),ce(Ds,{to:"body"},[U(qh,{"model-value":f(o)&&f(j),title:f(l)("composer.mentionSheetTitle"),"onUpdate:modelValue":Q},{default:de(()=>[C("div",DKe,[U(f(Ns),{ref_key:"mentionSearchRef",ref:te,modelValue:pe.value,"onUpdate:modelValue":ct[20]||(ct[20]=at=>pe.value=at),placeholder:f(l)("composer.mentionSearchPlaceholder"),autocomplete:"off",spellcheck:"false",role:"combobox","aria-autocomplete":"list","aria-haspopup":"listbox","aria-expanded":!!O.value,"aria-controls":O.value,"aria-activedescendant":R.value,onKeydown:_i,onCompositionstart:go,onCompositionend:mo},null,8,["modelValue","placeholder","aria-expanded","aria-controls","aria-activedescendant"])]),U(DL,{layout:"sheet",items:f($),"active-index":f(W),loading:f(P),stale:f(Z),onSelect:f(Y),onHover:f(oe)},null,8,["items","active-index","loading","stale","onSelect","onHover"])]),_:1},8,["model-value","title"])])),(v(),ce(Ds,{to:"body"},[U(qh,{"model-value":f(o)&&Kn.value,"onUpdate:modelValue":ue},{default:de(()=>[C("div",{ref_key:"addSheetRef",ref:Ki,class:"msheet-add",role:"menu",onKeydown:bs},[(v(!0),E(Ee,null,pt(ji.value,at=>(v(),E("button",{key:at.id,type:"button",class:"am-row",role:"menuitem",onClick:Ht=>Fi(at)},[C("span",$Ke,[U(f(ve),{name:at.icon,size:"sm"},null,8,["name"])]),C("span",RKe,D(f(l)(at.nameKey)),1),at.descKey?(v(),E("span",zKe,D(f(l)(at.descKey)),1)):X("",!0)],8,BKe))),128))],544)]),_:1},8,["model-value"])]))],34))}}),LH=kt(OKe,[["__scopeId","data-v-5a96480c"]]),PKe={class:"goal-panel"},jKe={key:0,class:"goal-criterion"},HKe={class:"goal-criterion-label"},WKe=Xe({__name:"GoalPanel",props:{goal:{},openFile:{type:Function}},setup(e){const{t}=zt();return(n,i)=>(v(),E("div",PKe,[U(f(Iu),{text:e.goal.objective,"open-file":e.openFile},null,8,["text","open-file"]),e.goal.completionCriterion?(v(),E("div",jKe,[C("span",HKe,[U(f(ve),{name:"check-list",size:"sm"}),$e(" "+D(f(t)("status.goalDoneWhen")),1)]),U(f(Iu),{text:e.goal.completionCriterion,"open-file":e.openFile},null,8,["text","open-file"])])):X("",!0)]))}}),qKe=kt(WKe,[["__scopeId","data-v-cdb3e8b0"]]),UKe={class:"plan-panel"},KKe={key:0,class:"plan-review-row"},VKe={class:"plan-review-label"},ZKe={key:1,class:"plan-review-row"},GKe={class:"plan-review-label"},QKe={class:"plan-review-feedback"},YKe={key:3,class:"plan-path-only"},JKe={class:"plan-path-hint"},XKe={key:1,class:"plan-empty"},eVe=Xe({__name:"PlanPanel",props:{plan:{},planModeOn:{type:Boolean},openFile:{type:Function}},setup(e){const t=e,{t:n}=zt(),i=F(()=>t.plan&&!t.plan.plan&&t.plan.path?t.plan.path:void 0);function o(){i.value&&t.openFile?.({path:i.value})}return(s,r)=>(v(),E("div",UKe,[e.plan?(v(),E(Ee,{key:0},[e.plan.review?.selectedOption?(v(),E("div",KKe,[C("span",VKe,D(f(n)("tools.plan.selectedOption")),1),C("span",null,D(e.plan.review.selectedOption),1)])):X("",!0),e.plan.review?.feedback?(v(),E("div",ZKe,[C("span",GKe,D(f(n)("tools.plan.feedback")),1),C("span",QKe,D(e.plan.review.feedback),1)])):X("",!0),e.plan.plan?(v(),ce(f(Iu),{key:2,text:e.plan.plan,"open-file":e.openFile},null,8,["text","open-file"])):X("",!0),i.value?(v(),E("div",YKe,[C("span",JKe,D(f(n)("tools.plan.pathOnlyHint")),1),U(f(Qt),{variant:"ghost",size:"sm",class:"plan-path",onClick:o},{default:de(()=>[$e(D(i.value),1)]),_:1})])):X("",!0)],64)):(v(),E("div",XKe,[U(f(ve),{name:"file-edit",size:"lg",class:"plan-empty-ico"}),C("span",null,D(e.planModeOn?f(n)("status.planEmptyArmed"):f(n)("status.planEmptyIdle")),1)]))]))}}),tVe=kt(eVe,[["__scopeId","data-v-dea23306"]]),nVe={key:0,class:"qh-chip"},iVe={class:"qtitle"},oVe={class:"qbody"},sVe={class:"qopts"},rVe=["onClick"],lVe={class:"qopt-key"},aVe={class:"qopt-text"},uVe={class:"qopt-label"},cVe={key:0,class:"qopt-desc"},dVe={class:"qopt-label"},fVe=["placeholder"],hVe={class:"qfoot"},pVe={class:"qbtns"},gVe={class:"qhint"},mVe=Xe({__name:"QuestionCard",props:{question:{},busyKind:{}},emits:["answer","dismiss"],setup(e,{emit:t}){const n=e,{t:i}=zt(),o=t,s=K(0),r=K(!1);function l(){r.value&&(r.value=!1)}const a=F(()=>n.question.questions[s.value]),u=F(()=>n.question.questions.length);function c(){s.value>0&&s.value--}function d(){s.value<u.value-1&&s.value++}function h(Y){const oe=g.value[Y];return oe?oe.kind==="multi"?oe.optionIds.length>0:oe.kind==="multiWithOther"?oe.optionIds.length>0||oe.otherText.trim().length>0:oe.kind==="other"?oe.text.trim().length>0:!0:!1}function p(){return h(a.value.id)}const g=K({});function m(Y){return Y.recommended===!0?!0:/\b(?:recommended|recommend)\b|推荐/.test(`${Y.label} ${Y.description??""}`.toLowerCase())}function k(){const Y={...g.value};let oe=!1;for(const q of n.question.questions){if(Y[q.id])continue;const ne=q.options.filter(m);ne.length!==0&&(Y[q.id]=q.multiSelect?{kind:"multi",optionIds:ne.map(ie=>ie.id)}:{kind:"single",optionId:ne[0].id},oe=!0)}oe&&(g.value=Y)}Pe(()=>n.question.questionId,()=>{s.value=0,r.value=!1,g.value={},b.value={}}),Pe(()=>n.question,()=>{s.value>=n.question.questions.length&&(s.value=0),k()},{immediate:!0,deep:!0});function w(Y,oe){const q=g.value[Y];if(q&&q.kind==="single"&&q.optionId===oe){const ne={...g.value};delete ne[Y],g.value=ne}else g.value={...g.value,[Y]:{kind:"single",optionId:oe}}}function y(Y,oe){const q=g.value[Y],ne=q&&(q.kind==="multi"||q.kind==="multiWithOther")?q.kind==="multi"?[...q.optionIds]:[...q.optionIds]:[],ie=ne.indexOf(oe);ie>=0?ne.splice(ie,1):ne.push(oe);const pe=g.value[Y],Ne=pe&&pe.kind==="multiWithOther"?pe.otherText:"";Ne?g.value={...g.value,[Y]:{kind:"multiWithOther",optionIds:ne,otherText:Ne}}:g.value={...g.value,[Y]:{kind:"multi",optionIds:ne}}}const b=K({}),A=K(null);function T(Y){const oe=n.question.questions.find(ne=>ne.id===Y),q=b.value[Y]??"";if(oe.multiSelect){const ne=g.value[Y],ie=ne&&(ne.kind==="multi"||ne.kind==="multiWithOther")?ne.kind==="multi"?[...ne.optionIds]:[...ne.optionIds]:[];g.value={...g.value,[Y]:{kind:"multiWithOther",optionIds:ie,otherText:q}}}else g.value={...g.value,[Y]:{kind:"other",text:q}}}function S(Y){T(Y),dt(()=>A.value?.focus())}function x(Y,oe){const q=g.value[Y];return q?q.kind==="single"?q.optionId===oe:q.kind==="multi"||q.kind==="multiWithOther"?q.optionIds.includes(oe):!1:!1}function _(Y){const oe=g.value[Y];return!!(oe&&(oe.kind==="other"||oe.kind==="multiWithOther"))}function L(){return n.question.questions.every(Y=>h(Y.id))}const M=F(()=>n.busyKind==="answer"),N=F(()=>n.busyKind==="dismiss"),I=F(()=>!!n.busyKind);function z(){if(I.value||!L())return;const Y={answers:g.value,method:"click"};o("answer",n.question.questionId,Y)}function H(){I.value||o("dismiss",n.question.questionId)}const O=K(0);let R=!1;Pe([s,()=>n.question.questionId],()=>{O.value!==0&&(R=!0),O.value=0});const j=K(null);function $(Y,oe){const q=Y.getBoundingClientRect(),ne=oe.getBoundingClientRect(),ie=ne.top-q.top+Y.scrollTop,pe=ie+ne.height;ne.height>=Y.clientHeight||ie<Y.scrollTop?Y.scrollTop=ie:pe>Y.scrollTop+Y.clientHeight&&(Y.scrollTop=pe-Y.clientHeight)}function W(){const Y=j.value,oe=Y?.querySelector(".qbody");if(!Y||!oe)return;const q=oe.querySelectorAll(".qopt")[O.value];q&&($(oe,q),$(Y,q))}Pe(O,()=>{if(R){R=!1;return}dt(W)}),Pe(s,()=>{dt(()=>{const Y=j.value?.querySelector(".qbody");Y&&(Y.scrollTop=0),j.value&&(j.value.scrollTop=0)})});const{handleCompositionStart:P,handleCompositionEnd:Z,isComposingKeyEvent:ae}=bl();function V(Y){const oe=(document.activeElement?.tagName??"").toLowerCase(),q=oe==="input"||oe==="textarea";if(Y.metaKey||Y.ctrlKey||Y.altKey||I.value||ae(Y)||Fs.value>0)return;if(Y.key==="Enter"){if(Y.preventDefault(),r.value)return;s.value<u.value-1&&p()?d():L()&&z();return}if(q)return;if(Y.key==="Escape"){if(Fs.value>0||Y.defaultPrevented)return;Y.preventDefault(),H();return}if(r.value)return;if(Y.key==="ArrowDown"||Y.key==="ArrowUp"){const ie=a.value,pe=ie.options.length+(ie.allowOther?1:0);if(pe===0)return;Y.preventDefault();const Ne=Y.key==="ArrowDown"?1:-1,te=Math.min(pe-1,Math.max(0,O.value+Ne));if(te===O.value){dt(W);return}O.value=te;const be=ie.options[O.value];be?ie.multiSelect||w(ie.id,be.id):ie.allowOther&&!ie.multiSelect&&T(ie.id);return}if(Y.key===" "&&a.value.multiSelect){Y.preventDefault();const ie=a.value,pe=ie.options[O.value];pe?(y(ie.id,pe.id),dt(W)):ie.allowOther&&(T(ie.id),dt(W));return}const ne=parseInt(Y.key,10);if(!isNaN(ne)&&ne>=1&&ne<=9){Y.preventDefault();const ie=a.value,pe=ne-1,Ne=ie.options[pe];Ne&&(O.value=pe,ie.multiSelect?y(ie.id,Ne.id):w(ie.id,Ne.id),dt(W))}}return cn(()=>document.addEventListener("keydown",V)),_n(()=>document.removeEventListener("keydown",V)),(Y,oe)=>(v(),E("div",{ref_key:"cardEl",ref:j,class:Fe(["qcard",{minimized:r.value}])},[C("div",{class:Fe(["qh",{clickable:r.value}]),onClick:l},[u.value>1?(v(),E("span",nVe,D(s.value+1),1)):X("",!0),C("span",iVe,D(a.value.question),1),U(f(Jt),{class:"qmin",size:"sm",label:r.value?f(i)("question.expand"):f(i)("question.minimize"),tooltip:r.value?f(i)("question.expand"):f(i)("question.minimize"),onClick:oe[0]||(oe[0]=wt(q=>r.value=!r.value,["stop"]))},{default:de(()=>[r.value?(v(),ce(f(ve),{key:0,name:"chevron-up",size:"md"})):(v(),ce(f(ve),{key:1,name:"minus",size:"md"}))]),_:1},8,["label","tooltip"]),U(f(Jt),{class:"qclose",size:"sm",label:f(i)("question.dismiss"),tooltip:f(i)("question.dismiss"),disabled:I.value,onClick:wt(H,["stop"])},{default:de(()=>[U(f(ve),{name:"close",size:"md"})]),_:1},8,["label","tooltip","disabled"])],2),r.value?X("",!0):(v(),E(Ee,{key:0},[C("div",oVe,[a.value.body?(v(),ce(f(Iu),{key:0,text:a.value.body,class:"qmdbody"},null,8,["text"])):X("",!0),C("div",sVe,[(v(!0),E(Ee,null,pt(a.value.options,(q,ne)=>(v(),E("label",{key:q.id,class:Fe(["qopt",{selected:x(a.value.id,q.id),highlighted:a.value.multiSelect&&ne===O.value}]),onClick:wt(ie=>{O.value=ne,a.value.multiSelect?y(a.value.id,q.id):w(a.value.id,q.id)},["prevent"])},[C("span",lVe,D(ne+1),1),C("span",{class:Fe(["qopt-glyph",a.value.multiSelect?"chk":"rad"])},null,2),C("span",aVe,[C("span",uVe,D(q.label),1),q.description?(v(),E("span",cVe,D(q.description),1)):X("",!0)])],10,rVe))),128)),a.value.allowOther?(v(),E("label",{key:0,class:Fe(["qopt",{selected:_(a.value.id),highlighted:a.value.multiSelect&&O.value===a.value.options.length}]),onClick:oe[6]||(oe[6]=wt(q=>{O.value=a.value.options.length,S(a.value.id)},["prevent"]))},[oe[7]||(oe[7]=C("span",{class:"qopt-key"},null,-1)),C("span",{class:Fe(["qopt-glyph",a.value.multiSelect?"chk":"rad"])},null,2),C("span",dVe,D(a.value.otherLabel??f(i)("question.otherDefault")),1),Wn(C("input",{ref_key:"otherInputEl",ref:A,"onUpdate:modelValue":oe[1]||(oe[1]=q=>b.value[a.value.id]=q),class:"other-input",type:"text",placeholder:a.value.otherLabel??f(i)("question.otherDefault"),onInput:oe[2]||(oe[2]=q=>T(a.value.id)),onFocus:oe[3]||(oe[3]=q=>T(a.value.id)),onCompositionstart:oe[4]||(oe[4]=(...q)=>f(P)&&f(P)(...q)),onCompositionend:oe[5]||(oe[5]=(...q)=>f(Z)&&f(Z)(...q))},null,40,fVe),[[Bs,b.value[a.value.id]]])],2)):X("",!0)])]),C("div",hVe,[C("div",pVe,[s.value<u.value-1?(v(),ce(f(Qt),{key:0,class:"qmain",size:"md",variant:"primary",disabled:!p(),onClick:d},{default:de(()=>[$e(D(f(i)("question.nextQuestion")),1)]),_:1},8,["disabled"])):(v(),ce(f(Qt),{key:1,class:"qmain",size:"md",variant:"primary",disabled:!L(),loading:M.value,onClick:z},{default:de(()=>[$e(D(f(i)("question.submit")),1)]),_:1},8,["disabled","loading"])),u.value>1?(v(),ce(f(Qt),{key:2,size:"md",variant:"ghost",disabled:s.value===0||I.value,onClick:c},{default:de(()=>[$e(D(f(i)("question.back")),1)]),_:1},8,["disabled"])):X("",!0),U(f(Qt),{size:"md",variant:"ghost",loading:N.value,disabled:I.value,onClick:H},{default:de(()=>[$e(D(f(i)("question.dismiss")),1)]),_:1},8,["loading","disabled"])]),C("span",gVe,D(f(i)("question.hint")),1)])],64))],2))}}),vVe=kt(mVe,[["__scopeId","data-v-8e7280dd"]]),yVe={class:"akind"},kVe={key:1,class:"apeek"},bVe={class:"ab"},AVe=["title"],CVe={class:"code-path"},wVe={key:2,class:"body-shell"},xVe={class:"shell-cmd"},SVe={key:0,class:"shell-cwd"},_Ve={key:1,class:"shell-danger"},MVe={class:"code-path"},IVe={key:4,class:"body-chip"},EVe={class:"chip-label"},TVe={class:"chip-value"},LVe={key:0,class:"chip-detail"},NVe={key:5,class:"body-chip"},FVe={key:0,class:"chip-label"},DVe={class:"chip-value"},BVe={key:6,class:"body-chip"},$Ve={class:"chip-label"},RVe={class:"chip-value"},zVe={key:0,class:"chip-detail"},OVe={key:7,class:"body-chip"},PVe={class:"chip-label"},jVe={class:"chip-value"},HVe={key:0,class:"chip-detail"},WVe={key:8,class:"body-todo"},qVe={class:"todo-glyph"},UVe={key:0,class:"plan-opts"},KVe=["disabled","onClick"],VVe={class:"popt-key"},ZVe={class:"popt-text"},GVe={class:"popt-label"},QVe={key:0,class:"popt-desc"},YVe={key:10,class:"body-generic"},JVe={class:"gen-text"},XVe={key:11,class:"feedback-wrap"},eZe={class:"feedback-hint"},tZe={class:"af"},nZe={class:"abtns"},iZe={key:0,class:"knum"},oZe={key:0,class:"knum"},sZe=.4,rZe=Xe({__name:"ApprovalCard",props:{block:{},agentName:{},busy:{type:Boolean},openFile:{type:Function}},emits:["decide"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>{const pe=n.block;return pe.kind!=="plan_review"?null:{plan:pe.plan,path:pe.path,options:pe.options??[]}}),r=K(!1),l=K(null),a=K(null),u=K(null),c=K(!1),d=K(!1);function h(){c.value=(a.value?.scrollTop??0)>0||(u.value?.scrollTop??0)>0,d.value=(l.value?.scrollTop??0)>0}function p(){h()}const g=K(!1),m=F(()=>{const pe=n.block.kind;return pe==="plan_review"||pe==="diff"||pe==="file"});function k(){r.value&&(r.value=!1)}const w=["shell","diff","file","fileop","url","search","invocation","todo","plan_review","generic"];function y(){return w.includes(n.block.kind)?n.block.kind:"generic"}function b(){return o(`approval.title.${y()}`)}const A=F(()=>{const pe=n.block;switch(pe.kind){case"diff":case"file":case"fileop":return pe.path;case"shell":return pe.command;case"url":return pe.url;case"search":return pe.query;case"invocation":return pe.name;case"generic":return pe.summary;default:return""}}),T=K(!1),S=K(""),x=K(null);function _(){const pe=x.value?.el;if(!pe)return;pe.style.height="auto";const te=(window.visualViewport?.height??window.innerHeight)*sZe;pe.style.height=`${Math.min(pe.scrollHeight,te)}px`,pe.style.overflowY=pe.scrollHeight>te?"auto":"hidden"}Pe(S,()=>void dt(_)),Pe(r,pe=>{pe||dt(_)});const{fontScale:L}=c1();Pe(L,()=>void dt(_));let M=null,N=0;cn(()=>{window.addEventListener("resize",_),window.visualViewport?.addEventListener("resize",_),M=new ResizeObserver(pe=>{const Ne=pe[0]?.contentRect.width??0;Ne!==N&&(N=Ne,_())}),l.value&&M.observe(l.value)}),_n(()=>{window.removeEventListener("resize",_),window.visualViewport?.removeEventListener("resize",_),M?.disconnect()});function I(){n.busy||(T.value=!0,S.value="",setTimeout(()=>x.value?.el?.focus(),0))}function z(){if(n.busy)return;const pe=S.value.trim();s.value?P("feedback",{decision:"rejected",selectedLabel:"Revise",feedback:pe||void 0}):P("feedback",{decision:"rejected",feedback:pe||void 0}),T.value=!1,S.value=""}function H(){n.busy||(T.value=!1,S.value="")}const{handleCompositionStart:O,handleCompositionEnd:R,isComposingKeyEvent:j}=bl();function $(pe){j(pe)||(pe.key==="Enter"&&!pe.shiftKey?(pe.preventDefault(),z()):pe.key==="Escape"&&(pe.preventDefault(),H()))}const W=K(null);Pe(()=>n.busy,pe=>{pe||(W.value=null)});function P(pe,Ne){n.busy||(W.value=pe,i("decide",Ne))}function Z(){P("approve",{decision:"approved"})}function ae(){P("approveSession",{decision:"approved",scope:"session"})}function V(){P("reject",{decision:"rejected"})}function Y(){P("approvePlan",{decision:"approved"})}function oe(pe){P(`option:${pe}`,{decision:"approved",selectedLabel:pe})}function q(){n.busy||I()}function ne(){P("rejectAndExit",{decision:"rejected",selectedLabel:"Reject and Exit"})}function ie(pe){const Ne=(document.activeElement?.tagName??"").toLowerCase();if(Ne==="input"||Ne==="textarea"||pe.metaKey||pe.ctrlKey||pe.altKey||Fs.value>0||pe.defaultPrevented)return;if(T.value){pe.key==="Escape"&&(pe.preventDefault(),H());return}if(n.busy||r.value)return;const te=s.value;if(te){if(te.options.length===0){pe.key==="1"?(pe.preventDefault(),Y()):pe.key==="2"?(pe.preventDefault(),q()):pe.key==="3"&&(pe.preventDefault(),ne());return}pe.key==="1"&&te.options[0]?(pe.preventDefault(),oe(te.options[0].label)):pe.key==="2"&&te.options[1]?(pe.preventDefault(),oe(te.options[1].label)):pe.key==="3"&&te.options[2]&&(pe.preventDefault(),oe(te.options[2].label));return}pe.key==="1"?(pe.preventDefault(),Z()):pe.key==="2"?(pe.preventDefault(),ae()):pe.key==="3"?(pe.preventDefault(),V()):pe.key==="4"&&(pe.preventDefault(),I())}return cn(()=>document.addEventListener("keydown",ie)),_n(()=>document.removeEventListener("keydown",ie)),s1(h),(pe,Ne)=>(v(),E("div",{ref_key:"cardRef",ref:l,class:Fe(["appr",{minimized:r.value,scrolled:d.value}]),onScroll:h},[C("div",{class:Fe(["ah",{clickable:r.value}]),onClick:k},[C("span",yVe,D(b()),1),e.agentName&&!r.value?(v(),ce(f(br),{key:0,variant:"neutral",size:"sm"},{default:de(()=>[$e(D(f(o)("approval.subagentBadge",{name:e.agentName})),1)]),_:1})):X("",!0),r.value&&A.value?(v(),E("span",kVe,D(A.value),1)):X("",!0),m.value&&!r.value?(v(),ce(f(Jt),{key:2,class:"aexpand",size:"sm",label:g.value?f(o)("approval.collapsePlan"):f(o)("approval.expandPlan"),tooltip:g.value?f(o)("approval.collapsePlan"):f(o)("approval.expandPlan"),onClick:Ne[0]||(Ne[0]=te=>g.value=!g.value)},{default:de(()=>[U(f(ve),{name:g.value?"collapse":"expand",size:"md"},null,8,["name"])]),_:1},8,["label","tooltip"])):X("",!0),U(f(Jt),{class:"amin",size:"sm",label:r.value?f(o)("question.expand"):f(o)("question.minimize"),tooltip:r.value?f(o)("question.expand"):f(o)("question.minimize"),onClick:Ne[1]||(Ne[1]=wt(te=>r.value=!r.value,["stop"]))},{default:de(()=>[r.value?(v(),ce(f(ve),{key:0,name:"chevron-up",size:"md"})):(v(),ce(f(ve),{key:1,name:"minus",size:"md"}))]),_:1},8,["label","tooltip"])],2),r.value?X("",!0):(v(),E(Ee,{key:0},[C("div",bVe,[e.block.kind==="plan_review"&&e.block.path?(v(),E("button",{key:0,type:"button",class:"plan-path",title:e.block.path,onClick:Ne[2]||(Ne[2]=te=>n.openFile?.({path:e.block.path,content:e.block.plan}))},D(e.block.path),9,AVe)):X("",!0),e.block.kind==="diff"?(v(),E("div",{key:1,class:Fe(["body-code",{expanded:g.value}])},[C("div",CVe,D(e.block.path),1),e.block.diff.length>0?(v(),ce(oa,{key:0,lines:e.block.diff,path:e.block.path},null,8,["lines","path"])):X("",!0)],2)):e.block.kind==="shell"?(v(),E("div",wVe,[C("div",xVe,[Ne[4]||(Ne[4]=C("span",{class:"shell-dollar"},"$",-1)),$e(" "+D(e.block.command),1)]),e.block.cwd?(v(),E("div",SVe,"cwd: "+D(e.block.cwd),1)):X("",!0),e.block.danger?(v(),E("div",_Ve,[U(f(ve),{name:"alert-triangle",size:"sm",class:"shell-danger-ic"}),C("span",null,D(f(o)("approval.danger",{detail:e.block.danger})),1)])):X("",!0)])):e.block.kind==="file"?(v(),E("div",{key:3,class:Fe(["body-code",{expanded:g.value}])},[C("div",MVe,D(e.block.path),1),U(oa,{code:e.block.content,path:e.block.path},null,8,["code","path"])],2)):e.block.kind==="fileop"?(v(),E("div",IVe,[C("span",EVe,D(e.block.op),1),C("span",TVe,D(e.block.path),1),e.block.detail?(v(),E("span",LVe,D(e.block.detail),1)):X("",!0)])):e.block.kind==="url"?(v(),E("div",NVe,[e.block.method?(v(),E("span",FVe,D(e.block.method),1)):X("",!0),C("span",DVe,D(e.block.url),1)])):e.block.kind==="search"?(v(),E("div",BVe,[C("span",$Ve,D(f(o)("approval.searchQueryLabel")),1),C("span",RVe,D(e.block.query),1),e.block.scope?(v(),E("span",zVe,D(f(o)("approval.searchScope",{scope:e.block.scope})),1)):X("",!0)])):e.block.kind==="invocation"?(v(),E("div",OVe,[C("span",PVe,D(e.block.kind2),1),C("span",jVe,D(e.block.name),1),e.block.description?(v(),E("span",HVe,D(e.block.description),1)):X("",!0)])):e.block.kind==="todo"?(v(),E("div",WVe,[(v(!0),E(Ee,null,pt(e.block.items,(te,be)=>(v(),E("div",{key:be,class:"todo-item"},[C("span",qVe,D(te.status==="done"||te.status==="completed"?"✓":"○"),1),C("span",{class:Fe(["todo-title",{"todo-done":te.status==="done"||te.status==="completed"}])},D(te.title),3)]))),128))])):e.block.kind==="plan_review"?(v(),E("div",{key:9,ref_key:"planWrapEl",ref:a,class:Fe(["body-plan-wrap",{scrolled:c.value}]),onScroll:p},[C("div",{ref_key:"planBodyEl",ref:u,class:Fe(["body-plan",{expanded:g.value}]),onScroll:p},[U(f(Iu),{text:e.block.plan,"open-file":n.openFile},null,8,["text","open-file"])],34),s.value&&s.value.options.length>0?(v(),E("div",UVe,[(v(!0),E(Ee,null,pt(s.value.options,(te,be)=>(v(),E("button",{key:be,type:"button",class:"popt",disabled:e.busy,onClick:Q=>oe(te.label)},[C("span",VVe,D(be+1),1),C("span",ZVe,[C("span",GVe,D(te.label),1),te.description?(v(),E("span",QVe,D(te.description),1)):X("",!0)]),W.value===`option:${te.label}`?(v(),ce(f(Oi),{key:0,size:"sm",class:"popt-spin"})):X("",!0)],8,KVe))),128))])):X("",!0)],34)):(v(),E("div",YVe,[C("span",JVe,D(e.block.summary),1)])),T.value?(v(),E("div",XVe,[U(f(MY),{ref_key:"feedbackRef",ref:x,modelValue:S.value,"onUpdate:modelValue":Ne[3]||(Ne[3]=te=>S.value=te),placeholder:f(o)("approval.feedbackPlaceholder"),rows:3,resize:!1,onKeydown:$,onCompositionstart:f(O),onCompositionend:f(R)},null,8,["modelValue","placeholder","onCompositionstart","onCompositionend"]),C("div",eZe,D(f(o)("approval.feedbackHint")),1)])):X("",!0)]),C("div",tZe,[C("div",nZe,[T.value?(v(),E(Ee,{key:0},[U(f(Qt),{size:"md",variant:"danger-soft",loading:W.value==="feedback",disabled:e.busy,onClick:z},{default:de(()=>[$e(D(f(o)("approval.feedbackSubmit")),1)]),_:1},8,["loading","disabled"]),U(f(Qt),{size:"md",variant:"ghost",disabled:e.busy,onClick:H},{default:de(()=>[$e(D(f(o)("approval.feedbackCancel")),1)]),_:1},8,["disabled"])],64)):s.value?(v(),E(Ee,{key:1},[s.value.options.length===0?(v(),ce(f(Qt),{key:0,class:"amain",size:"md",variant:"primary",loading:W.value==="approvePlan",disabled:e.busy,onClick:Y},{default:de(()=>[Ne[5]||(Ne[5]=C("span",{class:"knum"},"1",-1)),$e(D(f(o)("approval.approvePlan")),1)]),_:1},8,["loading","disabled"])):X("",!0),U(f(Qt),{size:"md",variant:"ghost",disabled:e.busy,onClick:q},{default:de(()=>[s.value.options.length===0?(v(),E("span",iZe,"2")):X("",!0),$e(D(f(o)("approval.revise")),1)]),_:1},8,["disabled"]),U(f(Qt),{size:"md",variant:"ghost",loading:W.value==="rejectAndExit",disabled:e.busy,onClick:ne},{default:de(()=>[s.value.options.length===0?(v(),E("span",oZe,"3")):X("",!0),$e(D(f(o)("approval.rejectAndExit")),1)]),_:1},8,["loading","disabled"])],64)):(v(),E(Ee,{key:2},[U(f(Qt),{class:"amain",size:"md",variant:"primary",loading:W.value==="approve",disabled:e.busy,onClick:Z},{default:de(()=>[Ne[6]||(Ne[6]=C("span",{class:"knum"},"1",-1)),$e(D(f(o)("approval.approve")),1)]),_:1},8,["loading","disabled"]),U(f(Qt),{size:"md",variant:"ghost",loading:W.value==="approveSession",disabled:e.busy,onClick:ae},{default:de(()=>[Ne[7]||(Ne[7]=C("span",{class:"knum"},"2",-1)),$e(D(f(o)("approval.approveSession")),1)]),_:1},8,["loading","disabled"]),U(f(Qt),{size:"md",variant:"ghost",loading:W.value==="reject",disabled:e.busy,onClick:V},{default:de(()=>[Ne[8]||(Ne[8]=C("span",{class:"knum"},"3",-1)),$e(D(f(o)("approval.reject")),1)]),_:1},8,["loading","disabled"]),U(f(Qt),{size:"md",variant:"ghost",disabled:e.busy,onClick:I},{default:de(()=>[Ne[9]||(Ne[9]=C("span",{class:"knum"},"4",-1)),$e(D(f(o)("approval.feedback")),1)]),_:1},8,["disabled"])],64))])])],64))],34))}}),lZe=kt(rZe,[["__scopeId","data-v-690f6ed6"]]),aZe={class:"taskspane"},uZe={class:"tp-list"},cZe={key:0,class:"tp-empty"},dZe={class:"tp-main"},fZe=["aria-label","onClick"],hZe=["aria-label"],pZe={class:"tp-name"},gZe={key:1,class:"tp-meta"},mZe={key:2,class:"tp-model"},vZe={key:3,class:"tp-model"},yZe={key:4,class:"tp-time"},kZe=Xe({__name:"TasksPane",props:{tasks:{},filter:{}},emits:["cancel","open"],setup(e,{emit:t}){const n=e,i={active:"tasks.emptyRecent",running:"tasks.emptyRunning",done:"tasks.emptyDone",all:"tasks.emptyTasks"},o=F(()=>i[n.filter??"all"]),s=t,{t:r}=zt();function l(k){return!!(k.output&&k.output.length>0||k.meta)}function a(k){u(k)&&s("open",k.agentId??k.id)}function u(k){return k.kind==="subagent"||l(k)}function c(k){return typeof k.durationMs!="number"?"":Wa(k.durationMs,{h:r("status.timeUnitHour"),m:r("status.timeUnitMinute"),s:r("status.timeUnitSecond")})}function d(k){return k.state==="done"?r("tasks.stateDone"):k.state==="fail"?r("tasks.stateFail"):k.state==="cancelled"?r("tasks.stateCancelled"):r("tasks.running")}const h=hn("modelDisplay"),p=hn("subagentEffort");function g(k){if(k.kind==="subagent")return h?.(k.model)}function m(k){if(k.kind==="subagent")return p?.(k.thinkingEffort)}return(k,w)=>(v(),E("div",aZe,[C("div",uZe,[e.tasks.length===0?(v(),E("div",cZe,D(f(r)(o.value)),1)):(v(!0),E(Ee,{key:1},pt(e.tasks,y=>(v(),E("div",{key:y.id,class:Fe(["tp-row",{fail:y.state==="fail",expandable:u(y)}])},[C("div",dZe,[u(y)?(v(),E("button",{key:0,type:"button",class:"tp-open","aria-label":y.name,onClick:b=>a(y)},null,8,fZe)):X("",!0),C("span",{class:"tp-glyph",role:"img","aria-label":d(y)},[y.state==="run"?(v(),ce(f(ml),{key:0,status:"running"})):y.state==="done"?(v(),ce(f(ve),{key:1,class:"tp-done",name:"circle-check",size:"sm"})):y.state==="cancelled"?(v(),ce(f(ve),{key:2,class:"tp-cancelled",name:"close",size:"sm"})):(v(),ce(f(ve),{key:3,class:"tp-fail",name:"close",size:"sm"}))],8,hZe),C("span",pZe,D(y.name),1),y.meta?(v(),E("span",gZe,D(y.meta),1)):X("",!0),g(y)?(v(),E("span",mZe,D(g(y)),1)):X("",!0),m(y)?(v(),E("span",vZe,D(m(y)),1)):X("",!0),c(y)?(v(),E("span",yZe,D(c(y)),1)):X("",!0),y.state==="run"?(v(),ce(f(Jt),{key:5,class:"tp-stop",size:"sm",label:f(r)("tasks.stop"),tooltip:f(r)("tasks.stop"),onClick:wt(b=>s("cancel",y.id),["stop"])},{default:de(()=>[U(f(ve),{name:"close",size:"sm"})]),_:1},8,["label","tooltip","onClick"])):X("",!0),u(y)?(v(),ce(f(ve),{key:6,class:"tp-chevron",name:"chevron-right",size:"sm"})):X("",!0)])],2))),128))])]))}}),bZe=kt(kZe,[["__scopeId","data-v-22fc9dfb"]]),AZe={key:0,class:"sg-empty"},CZe={key:1,class:"sg-grid"},wZe=["aria-label","onClick"],xZe={class:"sg-top"},SZe={class:"sg-num"},_Ze={class:"sg-name"},MZe={key:1,class:"sg-desc"},IZe={class:"sg-foot"},EZe={key:0,class:"sg-model"},TZe={class:"sg-status"},LZe={class:"sg-state"},NZe={key:0,class:"sg-time"},FZe=Xe({__name:"SubagentGrid",props:{tasks:{},filter:{}},emits:["open","cancel"],setup(e,{emit:t}){const n=e,i={active:"tasks.emptyRecent",running:"tasks.emptyRunning",done:"tasks.emptyDone",all:"tasks.emptyTasks"},o=F(()=>i[n.filter??"all"]),s=t,{t:r}=zt(),l=hn("modelDisplay"),a=hn("subagentEffort");function u(g){const m=[l?.(g.model),a?.(g.thinkingEffort)].filter(k=>k!==void 0);return m.length>0?m.join(" · "):void 0}function c(g){return r(g==="done"?"tasks.stateDone":g==="fail"?"tasks.stateFail":g==="cancelled"?"tasks.stateCancelled":"tasks.running")}function d(g){return typeof g.durationMs!="number"?"":Wa(g.durationMs,{h:r("status.timeUnitHour"),m:r("status.timeUnitMinute"),s:r("status.timeUnitSecond")})}function h(g,m){return String((g.swarmIndex??m)+1).padStart(2,"0")}function p(g){return!!g.agentId||!!(g.output&&g.output.length>0)}return(g,m)=>e.tasks.length===0?(v(),E("div",AZe,D(f(r)(o.value)),1)):(v(),E("div",CZe,[(v(!0),E(Ee,null,pt(e.tasks,(k,w)=>(v(),E("div",{key:k.id,class:Fe(["sg-card",[`s-${k.state}`,{openable:p(k)}]])},[p(k)?(v(),E("button",{key:0,type:"button",class:"sg-open","aria-label":k.name,onClick:y=>s("open",k.agentId??k.id)},null,8,wZe)):X("",!0),C("div",xZe,[C("span",SZe,D(h(k,w)),1),C("span",_Ze,D(k.name),1)]),k.meta?(v(),E("div",MZe,D(k.meta),1)):X("",!0),C("div",IZe,[u(k)?(v(),E("div",EZe,[U(f(ve),{name:"robot",size:"sm"}),C("span",null,D(u(k)),1)])):X("",!0),C("div",TZe,[C("span",LZe,[k.state==="run"?(v(),ce(f(ml),{key:0,status:"running"})):k.state==="done"?(v(),ce(f(ve),{key:1,class:"sg-ic-done",name:"circle-check",size:"sm"})):(v(),ce(f(ve),{key:2,name:"close",size:"sm"})),$e(" "+D(c(k.state)),1)]),d(k)?(v(),E("span",NZe,[U(f(ve),{name:"clock",size:"sm"}),$e(D(d(k)),1)])):X("",!0)])]),k.state==="run"?(v(),ce(f(Jt),{key:2,class:"sg-cancel",size:"sm",label:f(r)("tasks.stop"),tooltip:f(r)("tasks.stop"),onClick:wt(y=>s("cancel",k.id),["stop"])},{default:de(()=>[U(f(ve),{name:"close",size:"sm"})]),_:1},8,["label","tooltip","onClick"])):X("",!0)],2))),128))]))}}),DZe=kt(FZe,[["__scopeId","data-v-f7e4b600"]]),BZe={class:"todo-card"},$Ze={key:0,class:"tc-empty"},RZe={class:"tc-name"},zZe=Xe({__name:"TodoCard",props:{todos:{}},setup(e){const t=e,{t:n}=zt();return(i,o)=>(v(),E("div",BZe,[t.todos.length===0?(v(),E("div",$Ze,[U(f(ve),{name:"check-list",size:"lg",class:"tc-empty-ico"}),C("span",null,D(f(n)("tasks.emptyTodo")),1)])):X("",!0),(v(!0),E(Ee,null,pt(t.todos,(s,r)=>(v(),E("div",{key:r,class:Fe(["tc-row",`s-${s.status}`])},[C("span",{class:Fe(["tc-glyph",`g-${s.status}`]),"aria-hidden":"true"},[s.status==="in_progress"?(v(),ce(f(Oi),{key:0,size:"xs",class:"tc-spin"})):s.status==="done"?(v(),ce(f(ve),{key:1,name:"circle-check",size:"md"})):X("",!0)],2),C("span",RZe,D(s.title),1)],2))),128))]))}}),OZe=kt(zZe,[["__scopeId","data-v-f090f678"]]),ip=Xe({__name:"WorkPill",props:{icon:{},active:{type:Boolean},label:{}},emits:["click"],setup(e,{emit:t}){const n=t;return(i,o)=>(v(),ce(f(tD),{active:e.active,"aria-pressed":e.active,"aria-label":e.label,onClick:o[0]||(o[0]=s=>n("click",s))},{default:de(()=>[U(f(ve),{name:e.icon,size:"md"},null,8,["name"]),C("span",null,[Rn(i.$slots,"default")]),Rn(i.$slots,"meta")]),_:3},8,["active","aria-pressed","aria-label"]))}}),PZe={class:"wp-head-tab"},jZe={key:0,class:"wp-head-meta"},HZe={key:0,class:"wp-head-actions"},WZe=Xe({__name:"WorkPanelHead",props:{icon:{},title:{},meta:{}},setup(e){return(t,n)=>(v(),E(Ee,null,[C("span",PZe,[U(f(ve),{name:e.icon,size:"md"},null,8,["name"]),C("span",null,D(e.title),1),e.meta?(v(),E("span",jZe,D(e.meta),1)):X("",!0)]),t.$slots.actions?(v(),E("span",HZe,[Rn(t.$slots,"actions",{},void 0,!0)])):X("",!0)],64))}}),op=kt(WZe,[["__scopeId","data-v-82048a74"]]),qZe={class:"fc-label"},UZe=Xe({__name:"FilterControl",props:{modelValue:{},options:{}},emits:["update:modelValue"],setup(e,{emit:t}){const n=e,i=t,o=F(()=>n.options.find(M=>M.value===n.modelValue)),s=typeof window<"u"&&window.matchMedia?.("(hover: none)").matches?"lg":"md",r=K(null),l=K(!1);let a=0,u=null;async function c(){const M=r.value?.closest(".dock-work-head");if(!M)return;const N=M.querySelector(".wp-head-tab"),I=getComputedStyle(M),z=(parseFloat(I.columnGap)||0)*2,H=M.clientWidth-parseFloat(I.paddingLeft)-parseFloat(I.paddingRight)-z,O=N?.scrollWidth??0;if(!l.value){const j=r.value?.querySelector(".ui-seg");j!==null&&j.offsetWidth>0&&(a=j.offsetWidth)}const R=O+a>H;if(l.value=R,!R){await dt();const j=r.value?.querySelector(".ui-seg");j!==null&&j.offsetWidth>0&&(a=j.offsetWidth),l.value=O+a>H}}cn(()=>{const M=r.value?.closest(".dock-work-head");!M||typeof ResizeObserver!="function"||(u=new ResizeObserver(c),u.observe(M),c())}),Pe(l,M=>{!M&&d.value&&w()}),Pe(Fs,M=>{M>0&&d.value&&w()}),Pe(()=>n.options,async()=>{a=0,await dt(),c()},{flush:"post"});const d=K(!1),h=K(null);function p(){return h.value?.$el??null}const g=K(null),m=K({left:"0px",top:"0px"});async function k(){if(d.value){w();return}d.value=!0,await dt(),y(),b(),window.addEventListener("mousedown",S,!0),window.addEventListener("keydown",x,!0),window.addEventListener("resize",y),window.addEventListener("scroll",y,!0)}function w(M){d.value=!1,window.removeEventListener("mousedown",S,!0),window.removeEventListener("keydown",x,!0),window.removeEventListener("resize",y),window.removeEventListener("scroll",y,!0),M?.refocus&&p()?.focus()}function y(){const M=p();if(!M)return;const N=M.getBoundingClientRect(),I=g.value?.offsetHeight??0,z=getComputedStyle(document.documentElement),H=Number.parseFloat(z.getPropertyValue("--space-2"))||0,O=Number.parseFloat(z.getPropertyValue("--space-1"))||0,R=g.value?.offsetWidth??0,j=Math.min(N.left,Math.max(H,window.innerWidth-R-H));N.bottom+O+I<=window.innerHeight-H?m.value={left:`${j}px`,top:`${N.bottom+O}px`}:m.value={left:`${j}px`,bottom:`${window.innerHeight-N.top+O}px`}}function b(){const M=g.value;if(!M)return;(M.querySelector(".ui-menu-item.is-active")??M.querySelector(".ui-menu-item"))?.focus()}function A(){d.value||k()}function T(M){const N=M.relatedTarget;N&&(g.value?.contains(N)||p()?.contains(N))||w()}function S(M){const N=M.target;if(N){if(g.value?.contains(N)){M.stopImmediatePropagation();return}p()?.contains(N)||w()}}function x(M){M.key==="Escape"&&(M.preventDefault(),M.stopImmediatePropagation(),w({refocus:!0}))}function _(M){if(M.key!=="ArrowDown"&&M.key!=="ArrowUp")return;M.preventDefault();const N=Array.from(g.value?.querySelectorAll(".ui-menu-item")??[]);if(N.length===0)return;const I=N.indexOf(document.activeElement),z=M.key==="ArrowDown"?(I+1)%N.length:(I-1+N.length)%N.length;N[z]?.focus()}function L(M){i("update:modelValue",M),w({refocus:!0})}return Hn(()=>{u?.disconnect(),d.value&&w()}),(M,N)=>(v(),E("span",{ref_key:"root",ref:r,class:"filter-control"},[l.value?(v(),E(Ee,{key:0},[U(f(tD),{ref_key:"triggerRef",ref:h,class:"fc-trigger","aria-haspopup":"menu","aria-expanded":d.value,onClick:k,onKeydown:[Ho(wt(A,["prevent"]),["down"]),Ho(wt(A,["prevent"]),["up"])],onFocusout:T},{default:de(()=>[o.value?.icon?(v(),ce(f(ve),{key:0,name:o.value.icon,size:"sm"},null,8,["name"])):X("",!0),C("span",null,D(o.value?.label),1),U(f(ve),{class:"fc-chevron",name:"chevron-down",size:"sm"})]),_:1},8,["aria-expanded","onKeydown"]),(v(),ce(Ds,{to:"body"},[d.value?(v(),E("div",{key:0,ref_key:"menuBoxRef",ref:g,class:"fc-menu",style:Kt(m.value),onKeydown:_,onFocusout:T},[U(f(Zs),null,{default:de(()=>[(v(!0),E(Ee,null,pt(e.options,I=>(v(),ce(f(Ut),{key:I.value,role:"menuitemradio",active:I.value===e.modelValue,"aria-checked":I.value===e.modelValue,size:f(s),onClick:z=>L(I.value)},{default:de(()=>[I.icon?(v(),ce(f(ve),{key:0,name:I.icon,size:"sm","data-icon":I.icon},null,8,["name","data-icon"])):X("",!0),C("span",qZe,D(I.label),1),I.value===e.modelValue?(v(),ce(f(ve),{key:1,class:"fc-check",name:"check",size:"sm"})):X("",!0)]),_:2},1032,["active","aria-checked","size","onClick"]))),128))]),_:1})],36)):X("",!0)]))],64)):(v(),ce(f(Vs),{key:1,"model-value":e.modelValue,options:e.options,size:"md","onUpdate:modelValue":N[0]||(N[0]=I=>i("update:modelValue",I))},null,8,["model-value","options"]))],512))}}),$L=kt(UZe,[["__scopeId","data-v-153e0d9c"]]),KZe={class:"dock-work-head"},VZe={key:0,class:"dock-workbar"},ZZe={key:0,class:"dw-running"},GZe={key:0,class:"dw-running"},QZe={class:"dw-count"},YZe=Xe({__name:"ChatDock",props:{sessionId:{},running:{type:Boolean},working:{type:Boolean},starting:{type:Boolean},queued:{},searchFiles:{type:Function},uploadImage:{type:Function},status:{},thinking:{},planMode:{type:Boolean},planArmed:{type:Boolean},swarmMode:{type:Boolean},goalMode:{type:Boolean},activationBadges:{},models:{},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{},skills:{},goal:{},dockPanel:{},overlayOpen:{type:Boolean},sessionPlans:{},bashTasks:{},subagentTasks:{},bashRunning:{},subagentRunning:{},todoDoneCount:{},hasDockWork:{type:Boolean},todos:{},pendingQuestion:{},questionBusyKind:{},pendingApproval:{},approvalBusy:{type:Boolean},openFile:{type:Function},mobile:{type:Boolean}},emits:["submit","steer","command","interrupt","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","createGoal","controlGoal","focusGoal","compact","pickModel","selectModel","login","answer","dismiss","approval","cancelTask","toggle-dock-panel","close-dock-panel","openAgent"],setup(e,{expose:t,emit:n}){const i=e,o=n,{t:s}=zt(),{confirm:r,isConfirmOpen:l}=Vc(),a=F(()=>{switch(i.goal?.status){case"active":return s("status.goalStatusActive");case"paused":return s("status.goalStatusPaused");case"blocked":return s("status.goalStatusBlocked");case"complete":return s("status.goalStatusComplete");default:return""}}),u=F(()=>i.goal?Wa(i.goal.wallClockMs,{h:s("status.timeUnitHour"),m:s("status.timeUnitMinute"),s:s("status.timeUnitSecond")}):"");async function c(){await r({title:s("status.goalCancel"),message:s("status.goalCancelConfirm"),confirmLabel:s("status.goalCancelConfirmYes"),cancelLabel:s("status.goalCancelConfirmNo"),variant:"danger"})&&o("controlGoal","cancel")}const d=[{id:"active",labelKey:"tasks.filterRecent",icon:"clock"},{id:"running",labelKey:"tasks.filterRunning",icon:"play"},{id:"done",labelKey:"tasks.filterDone",icon:"circle-check"},{id:"all",labelKey:"tasks.filterAll",icon:"list"}];function h(se,re){return(re.completedAt??re.createdAt??"").localeCompare(se.completedAt??se.createdAt??"")||(re.createdAt??"").localeCompare(se.createdAt??"")}function p(se,re){if(re==="all")return se;if(re==="running")return se.filter(le=>le.state==="run");if(re==="done")return se.filter(le=>le.state!=="run");const G=[];for(const le of se){if(le.state==="run")continue;let ge=G.length;for(;ge>0&&h(G[ge-1],le)>0;)ge--;G.splice(ge,0,le),G.length>5&&(G.length=5)}return[...se.filter(le=>le.state==="run"),...G]}const g=K("active"),m=K("active"),k=F(()=>p(i.bashTasks,g.value)),w=F(()=>p(i.subagentTasks,m.value)),y=F(()=>d.map(se=>({value:se.id,label:s(se.labelKey),icon:se.icon}))),b=F({get:()=>g.value,set:se=>{g.value=se}}),A=F({get:()=>m.value,set:se=>{m.value=se}}),T=F(()=>(i.todos?.length??0)>0&&i.todoDoneCount===(i.todos?.length??0)),S=F(()=>i.bashTasks.some(se=>se.kind==="tool")),x=F(()=>S.value?"tasks.dockTasks":"tasks.dockBash"),_=F(()=>`${s("status.goalLabel")} ${a.value}`.trim()),L=F(()=>i.bashRunning>0?`${s(x.value)} ${i.bashRunning} ${s("tasks.running")}`:s(x.value)),M=F(()=>i.subagentRunning>0?`${s("tasks.dockSubagent")} ${i.subagentRunning} ${s("tasks.running")}`:s("tasks.dockSubagent")),N=F(()=>`${s("tasks.todoProgressTitle")} ${i.todoDoneCount}/${i.todos?.length??0}`),I=F(()=>Object.values(i.sessionPlans??{}).at(-1)),z=F(()=>{const se=I.value?.review?.state;return se?s(`tools.plan.review.${se}`):""});function H(){const se=I.value;se?.path&&i.openFile?.(se.plan?{path:se.path,content:se.plan}:{path:se.path})}const O=K(null),R=F(()=>O.value?.anyPopupOpen===!0),j=F(()=>R.value||i.dockPanel!=null),$=K(null),W=K(null),P=K(!1),Z=K("50%");function ae(se,re){if(i.pendingQuestion)return;const G=re.currentTarget;if(G&&W.value){const le=G.getBoundingClientRect(),ge=W.value.getBoundingClientRect();Z.value=`${le.left+le.width/2-ge.left}px`}o("toggle-dock-panel",se)}function V(se){return O.value?(O.value.loadForEdit(se),!0):!1}function Y(se){O.value?.loadAttachmentsForEdit(se)}function oe(){O.value?.focus()}const q=()=>O.value?.isEmpty?.()??!1;function ne(se){if(!i.dockPanel)return;const re=se.target;re&&($.value?.contains(re)||re instanceof Element&&re.closest(".ui-pill")||o("close-dock-panel"))}function ie(se){se.key!=="Escape"||se.repeat||cH(se)||se.defaultPrevented||R.value||l.value||i.overlayOpen||(se.preventDefault(),se.stopImmediatePropagation(),o("close-dock-panel"))}const pe=K(null),Ne=K(!1);function te(){const se=pe.value;Ne.value=se?se.scrollTop>0:!1}function be(se){Ne.value=se.target.scrollTop>0}let Q=null;Pe(()=>i.dockPanel,async se=>{typeof document<"u"&&(document.removeEventListener("mousedown",ne,!0),document.removeEventListener("keydown",ie,!0),se&&(document.addEventListener("mousedown",ne,!0),document.addEventListener("keydown",ie,!0))),Q?.disconnect(),Q=null,se?(await dt(),te(),typeof ResizeObserver=="function"&&pe.value&&(Q=new ResizeObserver(te),Q.observe(pe.value))):Ne.value=!1},{immediate:!0}),Pe(()=>i.pendingQuestion,se=>{se&&i.dockPanel&&o("close-dock-panel")});let ue=null;function Ae(){const se=W.value?.offsetHeight??0;document.documentElement.style.setProperty("--dock-h",`${se}px`);const re=Number.parseFloat(getComputedStyle(document.documentElement).getPropertyValue("--p-bp-sm"));P.value=(W.value?.offsetWidth??0)<(Number.isFinite(re)?re:640)}return cn(()=>{uH(),!(typeof ResizeObserver!="function"||!W.value)&&(ue=new ResizeObserver(Ae),ue.observe(W.value),Ae())}),_n(()=>{typeof document<"u"&&(document.removeEventListener("mousedown",ne,!0),document.removeEventListener("keydown",ie,!0)),ue?.disconnect(),ue=null,Q?.disconnect(),Q=null}),t({loadForEdit:V,loadAttachmentsForEdit:Y,focus:oe,anyPopupOpen:R,isEmpty:q}),(se,re)=>(v(),E("div",{ref_key:"dockRef",ref:W,class:Fe(["chat-dock",[e.mobile?"align-mobile":"align-center",{"has-popup":j.value,"has-approval":!!e.pendingApproval&&!e.pendingQuestion,"has-question":!!e.pendingQuestion,"pills-compact":P.value}]]),onClick:re[36]||(re[36]=wt(()=>{},["stop"]))},[U(fo,{name:"dock-panel"},{default:de(()=>[e.dockPanel?(v(),E("div",{ref_key:"workPanelRef",ref:$,key:e.dockPanel,class:Fe(["dock-work-panel",[`panel-${e.dockPanel}`,{"body-scrolled-up":Ne.value}]]),style:Kt({transformOrigin:`${Z.value} 100%`}),onClick:re[11]||(re[11]=wt(()=>{},["stop"]))},[C("div",KZe,[e.dockPanel==="bash"?(v(),ce(op,{key:0,icon:"terminal",title:f(s)(x.value),meta:`${e.bashRunning} ${f(s)("tasks.running")}`},{actions:de(()=>[U($L,{modelValue:b.value,"onUpdate:modelValue":re[0]||(re[0]=G=>b.value=G),options:y.value},null,8,["modelValue","options"])]),_:1},8,["title","meta"])):e.dockPanel==="subagent"?(v(),ce(op,{key:1,icon:"sparkles",title:f(s)("tasks.dockSubagent"),meta:`${e.subagentRunning} ${f(s)("tasks.running")}`},{actions:de(()=>[U($L,{modelValue:A.value,"onUpdate:modelValue":re[1]||(re[1]=G=>A.value=G),options:y.value},null,8,["modelValue","options"])]),_:1},8,["title","meta"])):e.dockPanel==="todos"?(v(),ce(op,{key:2,icon:T.value?"check-list":"list",title:f(s)("tasks.todoProgressTitle"),meta:`${e.todoDoneCount}/${e.todos?.length??0}`},null,8,["icon","title","meta"])):e.dockPanel==="goal"?(v(),ce(op,{key:3,icon:"target",title:f(s)("status.goalLabel"),meta:u.value},{actions:de(()=>[e.goal?(v(),E(Ee,{key:0},[e.goal.status==="active"?(v(),ce(f(Jt),{key:0,size:"sm",label:f(s)("status.goalPause"),tooltip:f(s)("status.goalPause"),onClick:re[2]||(re[2]=wt(G=>o("controlGoal","pause"),["stop"]))},{default:de(()=>[U(f(ve),{name:"pause",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),e.goal.status==="paused"||e.goal.status==="blocked"?(v(),ce(f(Jt),{key:1,size:"sm",label:f(s)("status.goalResume"),tooltip:f(s)("status.goalResume"),onClick:re[3]||(re[3]=wt(G=>o("controlGoal","resume"),["stop"]))},{default:de(()=>[U(f(ve),{name:"play",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),U(f(Jt),{size:"sm",label:f(s)("status.goalCancel"),tooltip:f(s)("status.goalCancel"),onClick:wt(c,["stop"])},{default:de(()=>[U(f(ve),{name:"power",size:"md"})]),_:1},8,["label","tooltip"]),U(f(Jt),{size:"sm",label:f(s)("tasks.closePanel"),tooltip:f(s)("tasks.closePanel"),onClick:re[4]||(re[4]=wt(G=>o("close-dock-panel"),["stop"]))},{default:de(()=>[U(f(ve),{name:"close",size:"md"})]),_:1},8,["label","tooltip"])],64)):X("",!0)]),_:1},8,["title","meta"])):e.dockPanel==="plan"?(v(),ce(op,{key:4,icon:"file-edit",title:f(s)("status.planLabel"),meta:z.value},{actions:de(()=>[I.value?.path?(v(),ce(f(Jt),{key:0,size:"sm",label:f(s)("tasks.openPanel"),tooltip:f(s)("tasks.openPanel"),onClick:wt(H,["stop"])},{default:de(()=>[U(f(ve),{name:"external-link",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),e.planArmed||e.planMode?(v(),ce(f(Jt),{key:1,size:"sm",label:f(s)("status.workModeDismiss"),tooltip:f(s)("status.workModeDismiss"),onClick:re[5]||(re[5]=wt(G=>o("togglePlan"),["stop"]))},{default:de(()=>[U(f(ve),{name:"power",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),U(f(Jt),{size:"sm",label:f(s)("tasks.closePanel"),tooltip:f(s)("tasks.closePanel"),onClick:re[6]||(re[6]=wt(G=>o("close-dock-panel"),["stop"]))},{default:de(()=>[U(f(ve),{name:"close",size:"md"})]),_:1},8,["label","tooltip"])]),_:1},8,["title","meta"])):X("",!0)]),C("div",{ref_key:"workBodyRef",ref:pe,class:"dock-work-body",onScroll:be},[e.dockPanel==="bash"?(v(),ce(bZe,{key:0,tasks:k.value,filter:g.value,onCancel:re[7]||(re[7]=G=>o("cancelTask",G)),onOpen:re[8]||(re[8]=G=>o("openAgent",G))},null,8,["tasks","filter"])):e.dockPanel==="subagent"?(v(),ce(DZe,{key:1,tasks:w.value,filter:m.value,onCancel:re[9]||(re[9]=G=>o("cancelTask",G)),onOpen:re[10]||(re[10]=G=>o("openAgent",G))},null,8,["tasks","filter"])):e.dockPanel==="todos"?(v(),ce(OZe,{key:2,todos:e.todos??[]},null,8,["todos"])):e.dockPanel==="goal"&&e.goal?(v(),ce(qKe,{key:3,goal:e.goal,"open-file":e.openFile},null,8,["goal","open-file"])):e.dockPanel==="plan"?(v(),ce(tVe,{key:4,plan:I.value,"plan-mode-on":e.planMode,"open-file":e.openFile},null,8,["plan","plan-mode-on","open-file"])):X("",!0)],544)],6)):X("",!0)]),_:1}),e.hasDockWork||e.planMode||I.value?(v(),E("div",VZe,[e.goal?(v(),ce(ip,{key:0,icon:"target",label:_.value,active:e.dockPanel==="goal",onClick:re[12]||(re[12]=G=>ae("goal",G))},{meta:de(()=>[C("span",{class:Fe(["dw-goal-status",`dw-goal-status--${e.goal.status}`])},D(a.value),3)]),default:de(()=>[$e(D(f(s)("status.goalLabel"))+" ",1)]),_:1},8,["label","active"])):X("",!0),e.planMode||I.value?(v(),ce(ip,{key:1,icon:"file-edit",label:f(s)("status.planLabel"),active:e.dockPanel==="plan",onClick:re[13]||(re[13]=G=>ae("plan",G))},{default:de(()=>[$e(D(f(s)("status.planLabel")),1)]),_:1},8,["label","active"])):X("",!0),e.bashTasks.length>0?(v(),ce(ip,{key:2,icon:"terminal",label:L.value,active:e.dockPanel==="bash",onClick:re[14]||(re[14]=G=>ae("bash",G))},{meta:de(()=>[e.bashRunning>0?(v(),E("span",ZZe,[U(f(ml),{status:"running"}),$e(D(e.bashRunning),1)])):X("",!0)]),default:de(()=>[$e(D(f(s)(x.value))+" ",1)]),_:1},8,["label","active"])):X("",!0),e.subagentTasks.length>0?(v(),ce(ip,{key:3,icon:"sparkles",label:M.value,active:e.dockPanel==="subagent",onClick:re[15]||(re[15]=G=>ae("subagent",G))},{meta:de(()=>[e.subagentRunning>0?(v(),E("span",GZe,[U(f(ml),{status:"running"}),$e(D(e.subagentRunning),1)])):X("",!0)]),default:de(()=>[$e(D(f(s)("tasks.dockSubagent"))+" ",1)]),_:1},8,["label","active"])):X("",!0),(e.todos?.length??0)>0?(v(),ce(ip,{key:4,icon:T.value?"check-list":"list",label:N.value,active:e.dockPanel==="todos",onClick:re[16]||(re[16]=G=>ae("todos",G))},{meta:de(()=>[C("span",QZe,D(e.todoDoneCount)+"/"+D(e.todos?.length??0),1)]),default:de(()=>[$e(D(f(s)("tasks.todoProgressTitle"))+" ",1)]),_:1},8,["icon","label","active"])):X("",!0)])):X("",!0),e.pendingQuestion?(v(),ce(vVe,{key:e.pendingQuestion.questionId,class:"dock-question",question:e.pendingQuestion,"busy-kind":e.questionBusyKind,onAnswer:re[17]||(re[17]=(G,le)=>o("answer",G,le)),onDismiss:re[18]||(re[18]=G=>o("dismiss",G))},null,8,["question","busy-kind"])):e.pendingApproval?(v(),ce(lZe,{key:e.pendingApproval.approvalId,class:"dock-approval",block:e.pendingApproval.block,"agent-name":e.pendingApproval.agentName,busy:e.approvalBusy,"open-file":e.openFile,onDecide:re[19]||(re[19]=G=>o("approval",e.pendingApproval.approvalId,G))},null,8,["block","agent-name","busy","open-file"])):(v(),ce(LH,{key:3,ref_key:"composerRef",ref:O,"session-id":e.sessionId,running:e.running,working:e.working,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"plan-armed":e.planArmed,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,goal:e.goal,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,starting:e.starting,onSubmit:re[20]||(re[20]=G=>o("submit",G)),onSteer:re[21]||(re[21]=G=>o("steer",G)),onCommand:re[22]||(re[22]=G=>o("command",G)),onInterrupt:re[23]||(re[23]=G=>o("interrupt")),onSetPermission:re[24]||(re[24]=G=>o("setPermission",G)),onSetThinking:re[25]||(re[25]=G=>o("setThinking",G)),onTogglePlan:re[26]||(re[26]=G=>o("togglePlan")),onToggleSwarm:re[27]||(re[27]=G=>o("toggleSwarm")),onToggleGoal:re[28]||(re[28]=G=>o("toggleGoal")),onCreateGoal:re[29]||(re[29]=G=>o("createGoal",G)),onControlGoal:re[30]||(re[30]=G=>o("controlGoal",G)),onFocusGoal:re[31]||(re[31]=G=>o("focusGoal")),onCompact:re[32]||(re[32]=G=>o("compact")),onPickModel:re[33]||(re[33]=G=>o("pickModel")),onSelectModel:re[34]||(re[34]=G=>o("selectModel",G)),onLogin:re[35]||(re[35]=G=>o("login"))},null,8,["session-id","running","working","queued","search-files","upload-image","status","thinking","plan-mode","plan-armed","swarm-mode","goal-mode","goal","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","starting"]))],2))}}),JZe=kt(YZe,[["__scopeId","data-v-8cd7cb40"]]),XZe={class:"ws-home"},eGe={class:"ws-home-title"},tGe={class:"ws-home-name"},nGe={key:0,class:"ws-home-path"},iGe=Xe({__name:"WorkspaceHome",props:{workspaceName:{},workspaceRoot:{}},setup(e){return(t,n)=>(v(),E("div",XZe,[C("div",eGe,[U(f(ve),{class:"ws-home-folder",name:"folder-closed"}),C("span",tGe,D(e.workspaceName),1)]),e.workspaceRoot?(v(),E("div",nGe,D(e.workspaceRoot),1)):X("",!0)]))}}),oGe=kt(iGe,[["__scopeId","data-v-cf7957ea"]]),sGe={class:"wrs"},rGe={class:"wrs-caption"},lGe=["onClick"],aGe={class:"wrs-title"},uGe={class:"wrs-time"},cGe={class:"wrs-foot"},dGe=Xe({__name:"WorkspaceRecentSessions",props:{sessions:{}},emits:["selectSession","openSessionAdmin"],setup(e,{emit:t}){const n=t,{t:i}=zt();return(o,s)=>(v(),E("div",sGe,[C("div",rGe,D(f(i)("conversation.recentSessions")),1),(v(!0),E(Ee,null,pt(e.sessions,r=>(v(),E("button",{key:r.id,type:"button",class:"wrs-row",onClick:l=>n("selectSession",r.id)},[C("span",{class:Fe(["wrs-ico",r.archived?"wrs-ico--done":"wrs-ico--open"])},[U(f(ve),{name:r.archived?"state-done":"state-open",size:"sm"},null,8,["name"])],2),C("span",aGe,D(r.title),1),C("span",uGe,D(r.time),1)],8,lGe))),128)),C("div",cGe,[U(f(gn),{text:f(i)("conversation.sessionAdminTooltip")},{default:de(()=>[C("button",{type:"button",class:"wrs-more",onClick:s[0]||(s[0]=r=>n("openSessionAdmin"))},[$e(D(f(i)("conversation.viewMoreSessions"))+" ",1),U(f(ve),{name:"chevron-down",size:"sm"})])]),_:1},8,["text"])])]))}}),fGe=kt(dGe,[["__scopeId","data-v-f463cc7b"]]),hGe=["aria-label","aria-hidden"],pGe={class:"toc-scroll"},gGe=["onClick"],mGe={class:"toc-label"},vGe=240,yGe=Xe({__name:"ConversationToc",props:{items:{},activeTurnId:{},mobile:{type:Boolean},sessionLoading:{type:Boolean},occluded:{type:Boolean}},emits:["select"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=K(null),r=K(!0);let l=null;function a(){const c=s.value,d=c?.offsetParent;if(!c||!d)return;const h=c.getBoundingClientRect().left,p=d.getBoundingClientRect().right;r.value=p-h>=vGe}const u=F(()=>!n.mobile&&!n.sessionLoading&&n.items.length>1);return Pe(u,c=>{l?.disconnect(),l=null,c&&dt(()=>{const d=s.value,h=d?.offsetParent;!d||!h||(typeof ResizeObserver<"u"&&(l=new ResizeObserver(a),l.observe(h)),a())})},{immediate:!0}),Hn(()=>{l?.disconnect(),l=null}),(c,d)=>u.value?(v(),E("nav",{key:0,ref_key:"navRef",ref:s,class:Fe(["conversation-toc",{"toc-clipped":!r.value||e.occluded}]),"aria-label":f(o)("conversation.toc"),"aria-hidden":r.value&&!e.occluded?void 0:!0},[C("div",pGe,[(v(!0),E(Ee,null,pt(e.items,h=>(v(),E("button",{key:h.id,type:"button",class:Fe(["toc-row",{active:e.activeTurnId===h.id}]),onClick:p=>i("select",h.id)},[d[0]||(d[0]=C("span",{class:"toc-bar"},null,-1)),C("span",mGe,D(h.title),1)],10,gGe))),128))])],10,hGe)):X("",!0)}}),kGe=kt(yGe,[["__scopeId","data-v-b8ba267a"]]),bGe={class:"tsearch-main"},AGe=["placeholder"],CGe={key:0,class:"tsearch-spin"},wGe=["inert"],xGe={class:"tsearch-foot"},SGe={class:"tsearch-count",role:"status"},_Ge={class:"tsearch-rings","aria-hidden":"true"},MGe=800,IGe=400,EGe=1500,TGe=Xe({__name:"TranscriptSearch",props:{pane:{},reveal:{},mobile:{type:Boolean,default:!1}},emits:["close"],setup(e,{expose:t,emit:n}){const i=e,o=n,{t:s}=zt(),{handleCompositionStart:r,handleCompositionEnd:l,isComposingKeyEvent:a}=bl(),u=K(""),c=K(!1),d=K([]),h=K(0),p=K(null),g=F(()=>d.value.length),m=F(()=>u.value.trim()!==""&&!c.value),k=K(!1),w=F(()=>{if(g.value===0)return s("conversation.search.noResults");const ae={current:h.value+1,total:g.value};return k.value?s("conversation.search.resultsCapped",ae):s("conversation.search.results",ae)});let y=null,b=null,A=null,T=null,S=null,x=0;const _=K([]);function L(){const ae=i.pane,V=d.value[h.value];if(!ae||V===void 0){_.value=[];return}const Y=ae.getBoundingClientRect(),oe=[];for(const q of V.getClientRects())oe.push({top:`${q.top-Y.top+ae.scrollTop}px`,left:`${q.left-Y.left}px`,width:`${q.width}px`,height:`${q.height}px`});_.value=oe}function M(ae,V){return ae.type==="attributes"&&ae.target===V?!0:N(ae)}function N(ae){const V=Y=>Y instanceof Element&&(Y.classList.contains("tsearch-rings")||Y.closest(".tsearch-rings")!==null);if(V(ae.target))return!0;if(ae.type==="childList"){const Y=[...ae.addedNodes,...ae.removedNodes];if(Y.length>0&&Y.every(V))return!0}return!1}function I(){_.value.length!==0&&(S!==null&&clearTimeout(S),S=setTimeout(()=>{S=null,L()},120))}function z(){return i.pane?.querySelector(".chat")??null}function H(){if(y!==null&&(clearTimeout(y),y=null),u.value.trim()===""){c.value=!1,O();return}c.value=!0,y=setTimeout(O,MGe)}function O(ae="first"){y!==null&&(clearTimeout(y),y=null),c.value=!1;const V=z();if(u.value.trim()===""||V===null){d.value=[],k.value=!1,h.value=0,a8(),L();return}const Y=d.value[h.value],oe=Y?.startContainer??null,q=Y?.startOffset??0,ne=$ce(V,u.value.trim()),ie=ne.ranges;if(k.value=ne.truncated,d.value=ie,ie.length===0){h.value=0,k3([],0),L();return}if(ae!==!1){const Ne=R(ie);h.value=ae==="backward"?(Ne-1+ie.length)%ie.length:Ne,j();return}const pe=oe!==null?ie.findIndex(Ne=>Ne.startContainer===oe&&Ne.startOffset===q):-1;h.value=pe>=0?pe:R(ie),k3(ie,h.value),L()}function R(ae){const V=i.pane?.getBoundingClientRect().top??0,Y=ae.findIndex(oe=>{const q=oe.getClientRects(),ne=q[q.length-1];return ne!==void 0&&ne.bottom>=V});return Y===-1?0:Y}function j(){const ae=d.value[h.value];k3(d.value,h.value),ae!==void 0&&i.reveal(ae),L()}function $(ae){g.value!==0&&(h.value=(h.value+ae+g.value)%g.value,j())}function W(ae){if(ae.key==="Enter"&&!a(ae)){if(ae.preventDefault(),y!==null){O(ae.shiftKey?"backward":"first");return}$(ae.shiftKey?-1:1)}}function P(ae){ae.key==="Escape"&&(a(ae)||(ae.preventDefault(),ae.stopPropagation(),o("close")))}function Z(){const ae=p.value;ae&&(ae.focus(),ae.select())}return t({focusInput:Z}),cn(()=>{dt(()=>p.value?.focus()),i.pane&&typeof MutationObserver=="function"&&(A=new MutationObserver(V=>{if(u.value.trim()!==""&&!V.every(Y=>M(Y,i.pane))&&y===null){if(Date.now()-x>=EGe){x=Date.now(),b!==null&&(clearTimeout(b),b=null),O(!1);return}b!==null&&clearTimeout(b),b=setTimeout(()=>{b=null,y===null&&(x=Date.now(),O(!1))},IGe)}}),A.observe(i.pane,{subtree:!0,childList:!0,characterData:!0,attributes:!0,attributeFilter:["inert","style","class"]})),i.pane?.addEventListener("scroll",I,{passive:!0});const ae=[i.pane,i.pane?.querySelector(".content-wrap")??null];if(typeof ResizeObserver=="function"){T=new ResizeObserver(()=>L());for(const V of ae)V&&T.observe(V)}}),_n(()=>{y!==null&&clearTimeout(y),b!==null&&clearTimeout(b),S!==null&&clearTimeout(S),A?.disconnect(),A=null,T?.disconnect(),T=null,i.pane?.removeEventListener("scroll",I),a8()}),(ae,V)=>(v(),E("div",{class:Fe(["tsearch",{mobile:e.mobile}]),role:"search",onKeydown:P},[C("div",bGe,[U(f(ve),{class:"tsearch-icon",name:"search",size:"sm","aria-hidden":"true"}),Wn(C("input",{ref_key:"inputRef",ref:p,"onUpdate:modelValue":V[0]||(V[0]=Y=>u.value=Y),type:"text",class:"tsearch-input",placeholder:f(s)("conversation.search.placeholder"),autocapitalize:"off",autocomplete:"off",spellcheck:"false",onInput:H,onKeydown:W,onCompositionstart:V[1]||(V[1]=(...Y)=>f(r)&&f(r)(...Y)),onCompositionend:V[2]||(V[2]=(...Y)=>f(l)&&f(l)(...Y))},null,40,AGe),[[Bs,u.value]]),c.value?(v(),E("span",CGe,[U(f(Oi),{size:"sm",label:f(s)("conversation.search.searching")},null,8,["label"])])):X("",!0),V[6]||(V[6]=C("span",{class:"tsearch-sep","aria-hidden":"true"},null,-1)),U(f(Jt),{class:"tsearch-close",size:"sm",label:f(s)("conversation.search.close"),tooltip:f(s)("conversation.search.close"),onClick:V[3]||(V[3]=Y=>o("close"))},{default:de(()=>[U(f(ve),{name:"close"})]),_:1},8,["label","tooltip"])]),C("div",{class:Fe(["tsearch-foot-wrap",{open:m.value}]),inert:!m.value},[C("div",xGe,[U(f(Jt),{size:"sm",label:f(s)("conversation.search.previous"),tooltip:f(s)("conversation.search.previous"),disabled:g.value===0,onClick:V[4]||(V[4]=Y=>$(-1))},{default:de(()=>[U(f(ve),{name:"arrow-up"})]),_:1},8,["label","tooltip","disabled"]),U(f(Jt),{size:"sm",label:f(s)("conversation.search.next"),tooltip:f(s)("conversation.search.next"),disabled:g.value===0,onClick:V[5]||(V[5]=Y=>$(1))},{default:de(()=>[U(f(ve),{name:"arrow-down"})]),_:1},8,["label","tooltip","disabled"]),C("span",SGe,D(w.value),1)])],10,wGe),e.pane?(v(),ce(Ds,{key:0,to:e.pane},[C("div",_Ge,[(v(!0),E(Ee,null,pt(_.value,(Y,oe)=>(v(),E("div",{key:oe,class:"tsearch-ring",style:Kt(Y)},null,4))),128))])],8,["to"])):X("",!0)],34))}}),LGe=kt(TGe,[["__scopeId","data-v-26f3fed5"]]),NGe="/assets/k3_doodle1-27EZ2HSw.riv",FGe={class:"doodle-host"},DGe={key:0,class:"doodle-fallback"},BGe=Xe({__name:"KimiDoodle",setup(e){const t=K(!1),n=K(null),i=a9();let o=null,s=null;return cn(async()=>{if(!window.matchMedia("(prefers-reduced-motion: reduce)").matches)try{let r=function(){const m=h.stateMachineNames[0];if(!m)return;const k=(h.stateMachineInputs(m)??[]).find(w=>w.name==="light/dark");k&&(k.value=i.value?1:0)};const[{Rive:l,RuntimeLoader:a},u,c]=await Promise.all([Fo(()=>import("./rive-CeXCFBdn.js").then(m=>m.r),__vite__mapDeps([10,5])),Fo(()=>import("./rive-BxcgqsjB.js"),[]).then(m=>m.default),Fo(()=>import("./rive_fallback-ByshBW-N.js"),[]).then(m=>m.default)]),d=n.value;if(!d)return;a.setWasmUrl(u),a.setWasmFallbackUrl(c);const h=new l({canvas:d,src:NGe,autoplay:!0,onLoad(){const m=h.stateMachineNames[0];m&&h.play(m),requestAnimationFrame(()=>{n.value&&(r(),h.resizeDrawingSurfaceToCanvas(),s=qB(h,d),t.value=!0)})}}),p=Pe(i,r),g=()=>h.resizeDrawingSurfaceToCanvas();window.addEventListener("resize",g),o=()=>{s?.(),s=null,p(),window.removeEventListener("resize",g),h.cleanup()}}catch{}}),Hn(()=>{o?.(),o=null}),(r,l)=>(v(),E("div",FGe,[t.value?X("",!0):(v(),E("div",DGe,[Rn(r.$slots,"fallback",{},void 0,!0)])),C("canvas",{ref_key:"canvasRef",ref:n,class:Fe(["doodle-canvas",{ready:t.value}]),role:"img","aria-label":"Kimi"},null,2)]))}}),$Ge=kt(BGe,[["__scopeId","data-v-694a2ad0"]]),RGe={key:1,class:"empty-hint"},zGe={class:"empty-hint-title"},OGe={key:1,class:"empty-hint-title is-starting"},PGe={key:2,class:"empty-hint-text"},jGe={key:2,class:"upgrade-banner"},HGe={class:"upgrade-banner-text"},WGe={class:"ws-bar"},qGe={key:0,class:"ws-anchor"},UGe=["aria-expanded"],KGe={class:"ws-chip-name"},VGe={class:"ws-caption"},ZGe=["onClick"],GGe={class:"ws-info"},QGe={class:"ws-name"},YGe={class:"ws-path"},JGe={class:"empty-spacer empty-tail"},XGe=["aria-label"],eQe={key:0,class:"undo-toast",role:"status","aria-live":"polite"},tQe={class:"undo-toast-text"},nQe=48,sp=80,RL=1e3,iQe=420,oQe=3e3,sQe=5e3,rQe=1e4,lQe=2500,aQe=Xe({__name:"ConversationPane",props:{turns:{},sessionId:{},approvals:{},gitInfo:{},tasks:{},todos:{},goal:{},activationBadges:{},status:{},thinking:{},planMode:{type:Boolean},planArmed:{type:Boolean},sessionPlans:{},swarmMode:{type:Boolean},goalMode:{type:Boolean},questions:{},pendingQuestionActions:{},pendingApprovalActions:{},running:{type:Boolean},turnActive:{type:Boolean},queued:{},searchFiles:{type:Function},uploadImage:{type:Function},changes:{},fileReloadKey:{},working:{type:Boolean},lastTurnReason:{},turnError:{},turnRetry:{},overlayOpen:{type:Boolean},starting:{type:Boolean},mobile:{type:Boolean},sessionLoading:{type:Boolean},compaction:{},hasMoreMessages:{type:Boolean},loadingMore:{type:Boolean},loadingMoreError:{type:Boolean},loadOlderMessages:{type:Function},models:{},authReady:{type:Boolean},managedSignedIn:{type:Boolean},managedMembership:{},starredIds:{},skills:{},workspaceName:{},workspaceRoot:{},gitDiffStats:{},workspaces:{},activeWorkspaceId:{},recentSessions:{},draftEntry:{},sessionTitle:{},sessionArchived:{type:Boolean},sessionPinned:{type:Boolean},pr:{}},emits:["submit","steer","approval","cancelTask","answer","dismiss","command","interrupt","unqueue","editQueued","reorderQueue","steerQueued","setPermission","setThinking","togglePlan","toggleSwarm","toggleGoal","createGoal","controlGoal","compact","pickModel","selectModel","login","openFile","openMedia","openTurnDiff","openCompaction","openAgent","openChanges","refreshGitStatus","editMessage","selectWorkspace","addWorkspace","selectSession","openPr","renameSession","forkSession","togglePin","archiveSession","restoreSession","exportSession","openSessionAdmin"],setup(e,{expose:t,emit:n}){const{t:i}=zt(),o=e,s=n,r=K(!1),l=K(null);sc(r,l);const a=K(!1),u=K(null),c=F(()=>o.workspaces?.find(Se=>Se.id===o.activeWorkspaceId)?.name??o.workspaceName??""),{sidebarTabs:d}=d1(),h=F(()=>!o.mobile&&!o.starting&&o.draftEntry==="workspace"&&d.value),p=F(()=>(o.workspaces?.length??0)>0),g=F(()=>o.authReady===!1&&(o.models?.length??0)===0&&o.managedSignedIn===!0&&o.managedMembership==="free"),m=F(()=>Qce(o.workspaces??[],o.activeWorkspaceId));function k(ye){if(r.value){r.value=!1;return}const Se=ye.currentTarget?.closest(".ws-anchor"),Ve=Se?.closest(".panes");if(Se instanceof HTMLElement&&Ve instanceof HTMLElement){const Rt=Se.getBoundingClientRect(),Yt=Ve.getBoundingClientRect(),wn=Yt.bottom-Rt.bottom-4,ei=Rt.top-Yt.top-4;a.value=ei>wn;const Bi=Math.max(0,Math.floor(a.value?ei:wn));u.value=`min(calc(var(--space-8) * 10), ${Bi}px)`}else a.value=!1,u.value=null;r.value=!0}function w(ye){r.value=!1,ye!==o.activeWorkspaceId&&s("selectWorkspace",ye)}_r(un.contentAlign);const y=K(null),b=K(null),A=K(null),T=K(!1);let S=null;function x(ye,Se){const Ve=A.value??b.value;return!Ve||Ve.loadForEdit(ye)===!1?!1:(Ve.loadAttachmentsForEdit(Se??[]),!0)}function _(){const ye=A.value??b.value;return ye?ye.isEmpty?.()??!0:!0}function L(){T.value=!0,S!==null&&clearTimeout(S),S=setTimeout(()=>{S=null,T.value=!1},2e3)}const M=F(()=>o.tasks.filter(ye=>ye.kind==="bash"||ye.kind==="tool"&&!ye.id.startsWith("question-"))),N=F(()=>o.tasks.filter(ye=>ye.kind==="subagent"&&ye.runInBackground)),I=F(()=>M.value.filter(ye=>ye.state==="run").length),z=F(()=>N.value.filter(ye=>ye.state==="run").length);function H(ye){const Se=o.tasks,Ve=Se.find(Yt=>Yt.id===ye)??Se.find(Yt=>Yt.parentToolCallId===ye);if(Ve?.agentId)return Ve.agentId;const Rt=Se.filter(Yt=>Yt.kind==="subagent"&&!Yt.parentToolCallId&&Yt.agentId);if(Rt.length===1)return Rt[0].agentId}oi("resolveAgentTaskId",H);const O=hn("modelDisplay"),R=hn("subagentEffort");function j(ye,Se){const Ve=Se??H(ye);if(Ve===void 0)return;const Rt=o.tasks.find(ei=>ei.agentId===Ve||ei.id===Ve),Yt=O?.(Rt?.model),wn=R?.(Rt?.thinkingEffort);if(!(Yt===void 0&&wn===void 0))return{display:Yt,effort:wn}}oi("resolveAgentModel",j),oi("pinScroll",$o);const $=F(()=>(o.todos??[]).filter(ye=>ye.status==="done").length),W=F(()=>o.goal!=null||M.value.length>0||N.value.length>0||(o.todos?.length??0)>0),P=K(null),Z=F(()=>o.gitInfo?o.changes?.length??0:0);function ae(ye){le.value||(P.value=P.value===ye?null:ye)}function V(){P.value=null}function Y(){o.goal&&!le.value&&(P.value="goal")}Pe(()=>[o.goal,M.value.length,N.value.length,o.todos?.length,o.planMode,o.sessionPlans],()=>{const ye=P.value;if(ye===null)return;ye==="goal"&&o.goal!=null||ye==="bash"&&M.value.length>0||ye==="subagent"&&N.value.length>0||ye==="todos"&&(o.todos?.length??0)>0||ye==="plan"&&(o.planMode===!0||Object.keys(o.sessionPlans??{}).length>0)||V()});function oe(ye){if(ye.role==="compaction")return i("conversation.compactedPlain");if(ye.role==="user"){if(ye.skillActivation)return`/${ye.skillActivation.name}`;if(ye.pluginCommand)return`/${ye.pluginCommand.pluginId}:${ye.pluginCommand.commandName}`;const Ve=ye.text.trim().replaceAll(/\s+/g," ");return Ve.length>0?Ve:"user"}const Se=(ye.text||ye.thinking||"").trim().replaceAll(/\s+/g," ");return Se.length>0?Se:(ye.tools?.length??0)>0?`${ye.tools.length} tools`:"kimi"}const q=F(()=>o.turns.filter(ye=>ye.role==="user").map((ye,Se)=>({id:ye.id,role:ye.role,no:Se+1,title:oe(ye)}))),ne=K(null);function ie(){const ye=Oe.value;if(!ye)return;const Se=q.value;if(Se.length===0)return;if(zn()<=sp){ne.value=Se[Se.length-1].id;return}if(Ne||pe===null){const wn=ye.scrollTop,ei=ye.getBoundingClientRect().top,Bi=[];for(const Ko of ye.querySelectorAll(".turn-anchor[data-turn-id]")){const ls=Ko.dataset.turnId;ls&&Bi.push({id:ls,top:Ko.getBoundingClientRect().top-ei+wn})}pe=Bi,Ne=!1}const Ve=new Set(Se.map(wn=>wn.id)),Rt=ye.scrollTop+ye.clientHeight/2;let Yt=null;for(const wn of pe)Ve.has(wn.id)&&wn.top<=Rt&&(Yt=wn.id);ne.value=Yt??Se[0].id}let pe=null,Ne=!0;function te(){Ne=!0}let be=0;function Q(){be||(be=Li(()=>{be=0,ie()}))}const ue=K(!1);let Ae=0;function se(){Ae||(Ae=Li(()=>{Ae=0,G()}))}function re(){se(),te()}function G(){const ye=Oe.value,Se=!o.mobile&&ye?ye.closest(".con")?.querySelector(".conversation-toc"):null,Ve=Se?.querySelector(".toc-bar");let Rt=!1;if(ye&&Se&&Ve){const Yt=Ve.getBoundingClientRect(),wn=Se.getBoundingClientRect(),ei=Yt.left+Yt.width/2;Rt=Array.from(ye.querySelectorAll(".table-node-wrapper")).some(Bi=>{const Ko=Bi.getBoundingClientRect();return Ko.left<=ei&&ei<=Ko.right&&Ko.top<wn.bottom&&Ko.bottom>wn.top})}ue.value!==Rt&&(ue.value=Rt)}const le=F(()=>o.questions&&o.questions.length>0?o.questions[0]:void 0),ge=F(()=>{const ye=le.value;if(ye)return o.pendingQuestionActions?.[ye.questionId]}),ke=F(()=>o.approvals&&o.approvals.length>0?o.approvals[0]:void 0),Ie=F(()=>{const ye=ke.value;return ye?!!o.pendingApprovalActions?.[ye.approvalId]:!1}),Oe=K(null),we=K(null),Be=K(0),tt=K(0),ut=K(!1),_t=K(null);let Ct=null;function $t(){if(o.turns.length!==0){if(ut.value){_t.value?.focusInput();return}Ct=document.activeElement,ut.value=!0}}function Vt(){ut.value=!1,dt(()=>{Ct instanceof HTMLElement&&Ct.isConnected&&Ct.focus(),Ct=null})}Pe(()=>o.turns.length===0&&!o.sessionLoading,ye=>{ye&&ut.value&&Vt()});const nn=F(()=>({"--panes-scrollbar-width":`${Be.value}px`})),gt=F(()=>({"--chat-dock-height":`${tt.value+nQe}px`}));function Le(ye){return ye instanceof HTMLElement?ye:ye&&"$el"in ye&&ye.$el instanceof HTMLElement?ye.$el:null}let ze=0;function Ye(){ze||(ze=Li(()=>{ze=0;const ye=Oe.value,Se=ye?Math.max(0,ye.offsetWidth-ye.clientWidth):0;Se!==Be.value&&(Be.value=Se);const Ve=we.value?.offsetHeight??0;Ve!==tt.value&&(tt.value=Ve)}))}function Tt(ye){const Se=Le(ye);Se!==Oe.value&&(Oe.value=Se,Se&&xe())}function on(ye){const Se=Le(ye);Se!==we.value&&(we.value=Se??null,ye&&"loadForEdit"in ye&&typeof ye.loadForEdit=="function"&&"focus"in ye&&typeof ye.focus=="function"?A.value={loadForEdit:ye.loadForEdit.bind(ye),loadAttachmentsForEdit:"loadAttachmentsForEdit"in ye&&typeof ye.loadAttachmentsForEdit=="function"?ye.loadAttachmentsForEdit.bind(ye):()=>{},focus:ye.focus.bind(ye),get anyPopupOpen(){return"anyPopupOpen"in ye&&ye.anyPopupOpen===!0},isEmpty:"isEmpty"in ye&&typeof ye.isEmpty=="function"?ye.isEmpty.bind(ye):void 0}:A.value=null,ot())}const jt=K(!0),kn=K(!1),bn=K(!1);let mn=null;function zn(){const ye=Oe.value;return ye?On-ye.scrollTop-Hi:0}let He=0,st=0,et=0,Nt=0,Lt=0,qn=0,So=0;function Yn(){return Date.now()<st}function Ir(){se(),bn.value=!0,mn&&clearTimeout(mn),mn=setTimeout(()=>{bn.value=!1,mn=null},900);const ye=Oe.value;if(!ye)return;const Se=ye.scrollTop;if(wi()){He=Se;return}if(performance.now()-et<100){He=Se;return}const Ve=zn();if(Yn()){jt.value=!0,kn.value=!1,He=Se;return}Se<He-1&&Ve>1?ye.scrollHeight-Se-ye.clientHeight>1&&(jt.value=!1,kn.value=!0):Ve<=sp&&Se>He+1&&Date.now()>=Nt&&(jt.value=!0,kn.value=!1),He=Se,Q()}function _o(ye=!1){const Se=Oe.value;jt.value=!0,kn.value=!1,Un(),Se&&(!ye&&performance.now()<Lt||(ye?ms():Se.scrollTop=Math.max(Se.scrollTop,On),He=Se.scrollTop))}let It=0;function ms(ye=320){const Se=Oe.value;if(!Se)return;if(It&&(an(It),It=0),typeof window<"u"&&window.matchMedia("(prefers-reduced-motion: reduce)").matches){Se.scrollTop=Se.scrollHeight,He=Se.scrollTop;return}const Ve=Se.scrollTop,Rt=performance.now();et=Rt,Lt=Rt+ye+iQe;const Yt=()=>{It=0;const wn=Math.min(1,(performance.now()-Rt)/ye),ei=1-Math.pow(1-wn,3);Se.scrollTop=Ve+(Se.scrollHeight-Ve)*ei,He=Se.scrollTop,wn<1?It=Li(Yt):Lt=0};It=Li(Yt)}function Er(ye,Se){return(Se.closest("[inert]")?.closest(".tool-group, .activity-run, .turn-fold")??Se).getBoundingClientRect().top-ye.getBoundingClientRect().top+ye.scrollTop}function go(ye,Se){const Ve=Array.from(ye.querySelectorAll(".turn-anchor[data-turn-id], [data-scroll-anchor-id]")).map(wn=>({node:wn,top:Er(ye,wn)})),Rt=Ve.findIndex(wn=>wn.top>=Se),Yt=Rt<0?Math.max(0,Ve.length-1):Rt;return Ve.slice(Yt,Yt+2).flatMap(wn=>{const ei=wn.node.dataset.scrollAnchorId,Bi=ei??wn.node.dataset.turnId;return Bi?[{kind:ei?"tool":"turn",id:Bi,top:wn.top}]:[]})}const mo=new Map;function vs(ye,Se){for(const Ve of Se.anchors){const Rt=Ve.kind==="tool"?"data-scroll-anchor-id":"data-turn-id",Yt=ye.querySelector(`[${Rt}="${ys(Ve.id)}"]`);if(Yt)return Er(ye,Yt)-Ve.top}return ye.scrollHeight-Se.oldHeight}function _i(ye,Se,Ve=ye.scrollTop){return ye.scrollTop=Ve+vs(ye,Se),He=ye.scrollTop,ye.scrollTop}async function Mo(){if(!o.sessionId||!o.loadOlderMessages||o.loadingMore||jn.value||!o.hasMoreMessages)return;const ye=o.sessionId,Se=Oe.value,Ve=Se?.scrollTop??0,Rt={anchors:Se?go(Se,Ve):[],oldHeight:Se?.scrollHeight??0};Ke(ye,!0),yt();try{if(await dt(),await o.loadOlderMessages(ye),await dt(),o.sessionId!==ye){mo.set(ye,Rt);return}const Yt=Oe.value;if(!Yt)return;_i(Yt,Rt),mo.delete(ye)}finally{Ke(ye,!1)}}function ys(ye){return typeof CSS<"u"&&typeof CSS.escape=="function"?CSS.escape(ye):ye.replaceAll(/["\\]/g,"\\$&")}let Tn=null;function Un(){Tn!==null&&(clearTimeout(Tn),Tn=null)}function Kn(ye){xt(),jt.value=!1,kn.value=zn()>sp,ye.scrollIntoView({behavior:"smooth",block:"center"}),Un(),Tn=setTimeout(()=>{Tn=null;const Se=Oe.value;if(!Se||!ye.isConnected)return;const Ve=ye.getBoundingClientRect().top+ye.offsetHeight/2-(Se.getBoundingClientRect().top+Se.clientHeight/2);Math.abs(Ve)>48&&(Se.scrollTop+=Ve)},480)}function Pi(ye){const Se=Oe.value;if(!Se)return;const Ve=Se.querySelector(`.turn-anchor[data-turn-id="${ys(ye)}"]`);Ve&&Kn(Ve)}function Io(ye,Se){const Ve=ye.startContainer.parentElement;if(Ve!==null)for(let Rt=Ve;Rt!==null&&Rt!==Se;Rt=Rt.parentElement){const Yt=getComputedStyle(Rt),wn=/(auto|scroll)/.test(Yt.overflowY)&&Rt.scrollHeight>Rt.clientHeight,ei=/(auto|scroll)/.test(Yt.overflowX)&&Rt.scrollWidth>Rt.clientWidth;if(!wn&&!ei)continue;const Bi=ye.getClientRects()[0];if(!Bi)return;const Ko=Rt.getBoundingClientRect();wn&&(Rt.scrollTop+=Bi.top+Bi.height/2-(Ko.top+Rt.clientHeight/2)),ei&&(Rt.scrollLeft+=Bi.left+Bi.width/2-(Ko.left+Rt.clientWidth/2))}}function Ki(ye){const Se=Oe.value;if(!Se)return;const Ve=ye.startContainer.parentElement;xt(),jt.value=!1,kn.value=zn()>sp,Nt=Date.now()+700;const Rt=Ve?.closest(".u-text-wrap.is-clamped");if(Rt){Rt.querySelector(".u-text-toggle")?.click(),dt(()=>Ti(ye,Se));return}Ti(ye,Se)}function Ti(ye,Se){const Ve=ye.startContainer.parentElement;Io(ye,Se);const Rt=ye.getClientRects()[0];if(!Rt){Ve instanceof HTMLElement&&Kn(Ve);return}const Yt=Se.getBoundingClientRect(),wn=Rt.top+Rt.height/2-(Yt.top+Se.clientHeight/2),ei=typeof window>"u"||!window.matchMedia("(prefers-reduced-motion: reduce)").matches;Se.scrollTo({top:Se.scrollTop+wn,behavior:ei?"smooth":"auto"}),Un(),Tn=setTimeout(()=>{Tn=null;const Bi=Oe.value,Ko=ye.getClientRects()[0];if(!Bi||!Ko)return;const ls=Bi.getBoundingClientRect(),Hl=Ko.top+Ko.height/2-(ls.top+Bi.clientHeight/2);Math.abs(Hl)>48&&(Bi.scrollTop+=Hl)},480)}function Qs(){const ye=Oe.value;if(!ye)return"none";const Se=ye.firstElementChild,Ve=Se instanceof HTMLElement?Se.offsetHeight:0,Rt=we.value?.offsetHeight??0;return`${ye.scrollHeight}:${ye.clientHeight}:${Ve}:${Rt}`}function Li(ye){return typeof requestAnimationFrame=="function"?requestAnimationFrame(ye):setTimeout(ye,16)}function an(ye){typeof cancelAnimationFrame=="function"?cancelAnimationFrame(ye):clearTimeout(ye)}let to=0,Jn=0,Wo=null,Mn=0;const Ni=K(!1);function wi(){return performance.now()<to}function $o(ye,Se=200){const Ve=Oe.value;if(!Ve||jn.value||(xt(),jt.value=!1,Wo=ye,Mn=ye.getBoundingClientRect().top,to=performance.now()+Se,Ni.value=!0,Jn))return;const Rt=()=>{if(Jn=0,!Wo)return;if(jt.value){Wo=null,Ni.value=!1;return}if(performance.now()>=to){Wo=null,Ni.value=!1,$s();return}const Yt=Wo.getBoundingClientRect().top-Mn;Yt&&(Ve.scrollTop+=Yt),Jn=Li(Rt)};Jn=Li(Rt)}function $s(){zn()<=sp?(jt.value=!0,kn.value=!1):(jt.value=!1,kn.value=!0)}function Vi(ye=36,Se){if(!jt.value&&!Yn()){Se?.();return}const Ve=++So;let Rt="",Yt=0,wn=0;qn&&(an(qn),qn=0);const ei=()=>{if(qn=0,Ve!==So)return;if(!jt.value&&!Yn()){Se?.();return}_o(!1);const Bi=Qs();Yt=Bi===Rt?Yt+1:0,Rt=Bi,wn++,Yt<3&&wn<ye?qn=Li(ei):Se?.()};qn=Li(ei)}function Cn(ye,Se){return ye!==void 0&&ye.length>0&&Se.length>=ye.length&&ye.firstId!==Se.firstId&&ye.lastId===Se.lastId&&ye.lastTextLen===Se.lastTextLen&&ye.lastThinkingLen===Se.lastThinkingLen&&ye.lastToolsLen===Se.lastToolsLen&&ye.approvalIds===Se.approvalIds}const Rs=F(()=>{const ye=(o.approvals??[]).map(wn=>wn.approvalId).join(","),Se=o.turns,Ve=Se.at(-1),Rt=Ve?.thinking?.length??0,Yt=Ve?.tools?.reduce((wn,ei)=>wn+ei.name.length+(ei.arg?.length??0)+(ei.output?.join("").length??0),0)??0;return{length:Se.length,firstId:Se[0]?.id??"",lastId:Ve?.id??"",lastTextLen:Ve?.text.length??0,lastThinkingLen:Rt,lastToolsLen:Yt,approvalIds:ye}});let qo=o.fileReloadKey;Pe(Rs,async(ye,Se)=>{const Ve=o.fileReloadKey,Rt=Ve!==qo;if(qo=Ve,jn.value&&Cn(Se,ye)){Q();return}if(Rt){Q();return}await dt(),jt.value||Yn()?_o(ye.length<Se.length):kn.value=!0,Q()}),Pe(we,()=>{ot()}),Pe(()=>o.mobile,async()=>{await dt(),Ye()});const ar=new Map,ks=K(!1);let yi=0,Vn=null;function ji(){ks.value=!0,yi&&(an(yi),yi=0),Vn&&clearTimeout(Vn),Vn=setTimeout(()=>{ks.value=!1,Vn=null},1200)}function Fi(){if(!ks.value)return;let ye=2;const Se=()=>{if(yi=0,ye--,ye>0){yi=Li(Se);return}ks.value=!1,Vn&&(clearTimeout(Vn),Vn=null)};yi&&an(yi),yi=Li(Se)}Pe(()=>o.fileReloadKey,async(ye,Se)=>{const Ve=Oe.value;Se&&Ve&&ar.set(String(Se),{top:Ve.scrollTop,following:jt.value}),xt(),ji(),await dt();const Rt=Oe.value,Yt=ye?ar.get(String(ye)):void 0;if(Yt&&Rt){const wn=mo.get(String(ye)),ei=wn?_i(Rt,wn,Yt.top):Yt.top;wn&&mo.delete(String(ye)),jt.value=Yt.following,Rt.scrollTop=ei,He=Rt.scrollTop,kn.value=!Yt.following&&zn()>1,Yt.following?Vi(36,Fi):Fi()}else jt.value=!0,He=0,_o(!1),Vi(36,Fi);te(),ie()}),Pe(()=>o.sessionLoading,async(ye,Se)=>{ye||!Se||(jt.value=!0,await dt(),Vi(36,Fi),Q())}),Pe(()=>o.turnActive,async(ye,Se)=>{ye||!Se||!jt.value&&!Yn()||(await dt(),Vi(48),Q())});function bs(){jt.value=!0,kn.value=!1,st=Date.now()+RL,dt(()=>{_o(!0),Vi(16)})}function As(ye){bs(),s("submit",ye)}function Eo(ye){jt.value=!0,kn.value=!1,st=Date.now()+RL,s("editMessage",ye)}function Tr(ye){const Se=o.queued?.[ye],Ve=Se?.text??"";x(Ve,Se?.attachments)&&s("editQueued",ye)}function Lr(ye){s("reorderQueue",ye)}function jl(ye,Se){bs(),s("answer",ye,Se)}function Nr(ye,Se){!ye||!Se||s("approval",ye,Se)}let Di=null,Xn=null,Cs=null,Uo=null,On=0,Hi=0,Wi=0;const rs=K(new Set),jn=F(()=>!!o.sessionId&&rs.value.has(o.sessionId));function Ke(ye,Se){const Ve=new Set(rs.value);Se?Ve.add(ye):Ve.delete(ye),rs.value=Ve}function Ue(){jn.value||Wi||(Wi=Li(()=>{Wi=0,!jn.value&&(wi()||(jt.value||Yn())&&_o(!1))}))}function yt(){So++,qn&&(an(qn),qn=0),Wi&&(an(Wi),Wi=0)}function xt(){const ye=Oe.value;if(st=0,Nt=0,yt(),to=0,Wo=null,Ni.value=!1,It&&(an(It),It=0),Un(),ye){const Se=ye.scrollTop;typeof ye.scrollTo=="function"?ye.scrollTo({top:Se,behavior:"auto"}):ye.scrollTop=Se}Lt=0,et=Number.NEGATIVE_INFINITY,ye&&(He=ye.scrollTop)}function rn(){const ye=Oe.value;!ye||ye.scrollHeight-ye.clientHeight<=1&&!o.hasMoreMessages||(jt.value=!1,xt(),ye.scrollHeight-ye.clientHeight>1&&(kn.value=!0))}function Zi(ye){const Se=Oe.value;if(!Se)return!1;for(const Ve of ye.composedPath()){if(Ve===Se)return!1;if(Ve instanceof HTMLElement&&Ve.scrollHeight>Ve.clientHeight+1&&Ve.scrollTop>1)return!0}return!1}function Gi(ye){ye.defaultPrevented||ye.ctrlKey||ye.shiftKey||(Un(),!(ye.deltaY>=0||Zi(ye))&&rn())}function oo(ye){const Se=Oe.value;if(!Se||ye.defaultPrevented||ye.button!==0||ye.pointerType==="touch")return;const Ve=Se.getBoundingClientRect(),Rt=Se.offsetWidth-Se.clientWidth,Yt=Rt>0?Rt:12;ye.target===Se&&ye.clientX>=Ve.right-Yt&&rn()}let qi=null;function vo(ye){qi=ye.touches.length===1?ye.touches[0].clientY:null}function so(ye){const Se=ye.touches.length===1?ye.touches[0].clientY:null;Un(),Se!==null&&qi!==null&&Se>qi+2&&!Zi(ye)&&rn(),qi=Se}function Ro(){if(!Xn)return;const ye=Oe.value?.firstElementChild??null;ye!==Cs&&(Cs&&Xn.unobserve(Cs),Cs=ye,ye&&Xn.observe(ye))}function ot(){if(!Xn)return;const ye=we.value;ye!==Uo&&(Uo&&Xn.unobserve(Uo),Uo=ye,ye&&Xn.observe(ye))}function xe(){const ye=Oe.value;Ye(),Di&&(Di.disconnect(),ye&&Di.observe(ye,{childList:!0,subtree:!0,characterData:!0})),Xn&&(Xn.disconnect(),Cs=null,Uo=null,ye&&Xn.observe(ye),Ro(),ot()),On=ye?.scrollHeight??0,Hi=ye?.clientHeight??0,se(),te()}function je(){Ro(),Ue(),se(),te()}function Dn(){typeof document>"u"||document.visibilityState==="visible"&&jt.value&&Vi()}const vn=K(!1);let ii=null;function ws(){vn.value=!0,ii!==null&&clearTimeout(ii),ii=setTimeout(()=>{vn.value=!1},oQe)}const xs=K(null);let ro=null;const ai=K(null);let Ys=null,Ss=!1;function el(){xs.value=null,ai.value=null,Ss=!1,ro!==null&&(clearTimeout(ro),ro=null),Ys!==null&&(clearTimeout(Ys),Ys=null)}function ur(){for(let ye=o.turns.length-1;ye>=0;ye--){const Se=o.turns[ye];if(Se.goalContinuation)return null;if(Se.role==="user")return Se}return null}function tl(){if(xs.value!==null||ai.value!==null||!o.working||(o.queued?.length??0)>0)return;const ye=ur();if(ye===null||ye.pluginCommand!==void 0||ye.skillActivation!==void 0&&!vj(ye.skillActivation,{revivePill:!1}))return;o.turns.slice(o.turns.indexOf(ye)+1).every(Ve=>Ve.role==="assistant"&&!S5(Ve))?(ai.value=ye.id,Ss=!1,Ys=setTimeout(()=>{ai.value=null},rQe)):xs.value=ye.id}let ee=!1,me=null;function Me(ye){if(ee)return;el();const Se=o.turns.find(Yt=>Yt.id===ye);if(Se===void 0||Se.role!=="user"||ur()?.id!==Se.id||(A.value??b.value)?.isEmpty?.()===!1)return;ee=!0,me=setTimeout(()=>{ee=!1,me=null},lQe);const Rt=Se.skillActivation?fA(Se.skillActivation,{revivePill:!1})??Se.text:Se.text;Eo({text:Rt,attachments:Se.attachments})}function Re(){ai.value===null||o.working||!Ss||Me(ai.value)}Pe(()=>o.working,(ye,Se)=>{if(!(Se!==!0||ye)){if(ai.value!==null){Re();return}xs.value!==null&&ro===null&&(ro=setTimeout(()=>{xs.value=null,ro=null},sQe))}}),Pe(()=>ur()?.id??null,(ye,Se)=>{ye!==Se&&el()}),Pe(()=>o.sessionId,el),Pe(()=>o.queued?.length,ye=>{(ye??0)>0&&el()});const Qe=F(()=>{if(o.lastTurnReason!=="cancelled"||o.working||o.turnActive)return null;const ye=o.turns[o.turns.length-1];return ye?.role==="assistant"&&S5(ye)?ye.id:null}),Je=F(()=>o.lastTurnReason==="failed"&&!o.working&&!o.turnActive&&o.turns.length>0);function ft(){bs(),s("submit",{text:i("conversation.turnFailedResumeText"),attachments:[]})}const vt=F(()=>o.working?null:xs.value);function Pt(){s("interrupt")}function fn(){return(A.value?.anyPopupOpen??b.value?.anyPopupOpen)===!0}const{handleCompositionStart:dn,handleCompositionEnd:ui,isComposingKeyEvent:Ln}=bl();let Sn=null;function fi(ye){Sn=ye.target}function Ui(ye){const Se=ye instanceof Element&&ye!==document.body?ye:Sn,Ve=mae(Se,".global-preview");if(Ve){OS(Ve);return}const Rt=Oe.value?.querySelector(".chat");Rt&&OS(Rt)}function Fr(ye){if(!(ye.target instanceof Element&&ye.target.closest(".terminal-host")!==null)){if(ye.key==="Escape"&&!o.overlayOpen&&!fn()&&!ye.defaultPrevented&&!ye.repeat&&!Ln(ye)){vt.value!==null?(ye.preventDefault(),Me(vt.value)):o.working&&(ye.preventDefault(),tl(),Pt());return}if(xce(ye)&&!o.overlayOpen&&o.turns.length>0){ye.preventDefault(),$t();return}pae(ye)&&!o.overlayOpen&&!gae(ye.target)&&(ye.preventDefault(),Ui(ye.target))}}function ya(){jt.value&&Ue()}cn(()=>{dt(()=>{typeof MutationObserver=="function"&&(Di=new MutationObserver(je)),typeof ResizeObserver=="function"&&(Xn=new ResizeObserver(()=>{se(),te(),Ye();const ye=Oe.value;if(!ye)return;const{scrollHeight:Se,clientHeight:Ve}=ye,Rt=Se>On+1,Yt=Ve<Hi-1;On=Se,Hi=Ve,!wi()&&(Rt||Yt)&&Ue()})),xe(),Vi(48),ie(),Oe.value?.addEventListener("kimi-table-layout",re),typeof document<"u"&&(document.addEventListener("visibilitychange",Dn),document.addEventListener("keydown",Fr),document.addEventListener("pointerdown",fi,!0),document.addEventListener("compositionstart",dn),document.addEventListener("compositionend",ui)),window.visualViewport?.addEventListener("resize",ya)})}),_n(()=>{Oe.value?.removeEventListener("kimi-table-layout",re),Di&&Di.disconnect(),Xn&&Xn.disconnect(),Wi&&an(Wi),qn&&an(qn),Jn&&an(Jn),It&&an(It),Ae&&an(Ae),be&&an(be),Tn!==null&&clearTimeout(Tn),mn&&clearTimeout(mn),ii!==null&&clearTimeout(ii),ro!==null&&clearTimeout(ro),Ys!==null&&clearTimeout(Ys),me!==null&&clearTimeout(me),S!==null&&(clearTimeout(S),S=null),typeof document<"u"&&(document.removeEventListener("visibilitychange",Dn),document.removeEventListener("keydown",Fr),document.removeEventListener("pointerdown",fi,!0),document.removeEventListener("compositionstart",dn),document.removeEventListener("compositionend",ui)),window.visualViewport?.removeEventListener("resize",ya)});function ka(){(A.value??b.value)?.focus()}$de({sessionId:()=>o.sessionId,mobile:()=>o.mobile===!0,starting:()=>o.starting===!0,dockedComposer:A,emptyComposer:b});function Du(){ws()}function v1(ye){if(ai.value!==null){if(!ye){Ss||el();return}Ss=!0,Re()}}return t({loadComposerForEdit:x,isComposerEmpty:_,focusComposer:ka,notifyUndone:Du,onAbortOutcome:v1,selectAllRegion:Ui,focusGoal:Y}),(ye,Se)=>(v(),E("section",{class:Fe(["con",{mobile:e.mobile}])},[!e.mobile&&!(e.turns.length===0&&!e.sessionLoading)?(v(),ce(MWe,{key:0,"session-id":e.sessionId,"workspace-name":e.workspaceName,"workspace-root":e.workspaceRoot,"session-title":e.sessionTitle,branch:e.gitInfo?.branch,ahead:e.gitInfo?.ahead,behind:e.gitInfo?.behind,"changes-count":Z.value,"git-diff-stats":e.gitDiffStats,"is-git-repo":!!e.gitInfo,pr:e.pr,copied:T.value,archived:e.sessionArchived,pinned:e.sessionPinned,onOpenChanges:Se[0]||(Se[0]=Ve=>s("openChanges")),onCopyAll:Se[1]||(Se[1]=Ve=>y.value?.copyConversation()),onCopyFinalSummary:Se[2]||(Se[2]=Ve=>y.value?.copyFinalSummary()),onOpenPr:Se[3]||(Se[3]=Ve=>e.pr&&s("openPr",e.pr.url)),onRenameSession:Se[4]||(Se[4]=(Ve,Rt)=>s("renameSession",Ve,Rt)),onForkSession:Se[5]||(Se[5]=Ve=>s("forkSession",Ve)),onTogglePin:Se[6]||(Se[6]=Ve=>s("togglePin",Ve)),onArchiveSession:Se[7]||(Se[7]=Ve=>s("archiveSession",Ve)),onRestoreSession:Se[8]||(Se[8]=Ve=>s("restoreSession",Ve)),onExportSession:Se[9]||(Se[9]=Ve=>s("exportSession",Ve))},null,8,["session-id","workspace-name","workspace-root","session-title","branch","ahead","behind","changes-count","git-diff-stats","is-git-repo","pr","copied","archived","pinned"])):e.mobile?X("",!0):(v(),E("div",{key:1,class:Fe(["empty-drag",{"macos-desktop":f(pc)}])},null,2)),U(kGe,{items:q.value,"active-turn-id":ne.value,mobile:e.mobile,"session-loading":e.sessionLoading,occluded:ue.value,onSelect:Pi},null,8,["items","active-turn-id","mobile","session-loading","occluded"]),C("div",{class:"chat-layout",style:Kt(gt.value)},[C("div",{ref:Tt,class:Fe(["panes chat-scroll",{"is-following":jt.value,"history-prepending":jn.value,"is-pinned":Ni.value,scrolling:bn.value,"session-settling":ks.value}]),onScrollPassive:Ir,onWheelPassive:Gi,onPointerdownPassive:oo,onTouchstartPassive:vo,onTouchmovePassive:so},[C("div",{class:Fe(["content-wrap",[e.mobile?"align-mobile":"align-center"]])},[e.turns.length===0&&!e.sessionLoading?(v(),E(Ee,{key:0},[Se[60]||(Se[60]=C("div",{class:"empty-spacer"},null,-1)),h.value?(v(),ce(oGe,{key:0,"workspace-name":c.value,"workspace-root":e.workspaceRoot},null,8,["workspace-name","workspace-root"])):(v(),E("div",RGe,[e.starting?(v(),E("span",OGe,[U(f(Oi),{size:"sm"}),C("span",null,D(f(i)("conversation.starting")),1)])):(v(),ce($Ge,{key:0,class:"empty-doodle"},{fallback:de(()=>[C("span",zGe,D(f(i)("composer.emptyConversationTitle")),1)]),_:1})),e.starting?X("",!0):(v(),E("span",PGe,D(f(i)("composer.emptyConversation")),1))])),g.value?(v(),E("div",jGe,[U(f(ve),{class:"upgrade-banner-icon",name:"music",size:"sm"}),C("span",HGe,D(f(i)("composer.upgradeBanner")),1),C("button",{type:"button",class:"upgrade-banner-cta",onClick:Se[10]||(Se[10]=Ve=>f(sg)())},D(f(i)("sidebar.upgrade")),1)])):X("",!0),U(LH,{ref_key:"emptyComposerRef",ref:b,class:"empty-composer","session-id":e.sessionId,running:e.running,working:e.working,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"plan-armed":e.planArmed,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,goal:e.goal,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,starting:e.starting,"hide-context":"",onSubmit:As,onSteer:Se[13]||(Se[13]=Ve=>s("steer",Ve)),onCommand:Se[14]||(Se[14]=Ve=>s("command",Ve)),onInterrupt:Pt,onUnqueue:Se[15]||(Se[15]=Ve=>s("unqueue",Ve)),onEditQueued:Se[16]||(Se[16]=Ve=>s("editQueued",Ve)),onSetPermission:Se[17]||(Se[17]=Ve=>s("setPermission",Ve)),onSetThinking:Se[18]||(Se[18]=Ve=>s("setThinking",Ve)),onTogglePlan:Se[19]||(Se[19]=Ve=>s("togglePlan")),onToggleSwarm:Se[20]||(Se[20]=Ve=>s("toggleSwarm")),onToggleGoal:Se[21]||(Se[21]=Ve=>s("toggleGoal")),onOpenBtw:Se[22]||(Se[22]=Ve=>s("command",{cmd:"/btw",attachments:[]})),onCreateGoal:Se[23]||(Se[23]=Ve=>s("createGoal",Ve)),onControlGoal:Se[24]||(Se[24]=Ve=>s("controlGoal",Ve)),onFocusGoal:Y,onCompact:Se[25]||(Se[25]=Ve=>s("compact")),onPickModel:Se[26]||(Se[26]=Ve=>s("pickModel")),onSelectModel:Se[27]||(Se[27]=Ve=>s("selectModel",Ve)),onLogin:Se[28]||(Se[28]=Ve=>s("login"))},TN({_:2},[e.starting?void 0:{name:"footer",fn:de(()=>[C("div",WGe,[p.value?(v(),E("div",qGe,[U(f(gn),{text:f(i)("conversation.switchWorkspace")},{default:de(()=>[C("button",{type:"button",class:Fe(["ws-chip",{open:r.value}]),"aria-expanded":r.value,onClick:wt(k,["stop"])},[U(f(ve),{name:"folder"}),C("span",KGe,D(c.value),1),U(f(ve),{class:"ws-chip-chev",name:"chevron-down",size:"sm"})],10,UGe)]),_:1},8,["text"]),r.value?(v(),E("div",{key:0,ref_key:"wsPanelRef",ref:l,class:Fe(["ws-panel",{up:a.value}]),style:Kt(u.value?{maxHeight:u.value}:void 0),role:"menu"},[C("div",VGe,D(f(i)("workspace.recentLabel")),1),(v(!0),E(Ee,null,pt(m.value,Ve=>(v(),E("button",{key:Ve.id,type:"button",class:Fe(["ws-row",{on:Ve.id===e.activeWorkspaceId}]),role:"menuitem",onClick:wt(Rt=>w(Ve.id),["stop"])},[U(f(ve),{name:"folder"}),C("span",GGe,[C("span",QGe,D(Ve.name),1),C("span",YGe,D(Ve.shortPath),1)]),Ve.id===e.activeWorkspaceId?(v(),ce(f(ve),{key:0,class:"ws-check",name:"check",size:"sm"})):X("",!0)],10,ZGe))),128)),Se[59]||(Se[59]=C("div",{class:"ws-divider"},null,-1)),C("button",{type:"button",class:"ws-action",role:"menuitem",onClick:Se[11]||(Se[11]=wt(Ve=>{r.value=!1,s("addWorkspace")},["stop"]))},[U(f(ve),{name:"folder-plus"}),C("span",null,D(f(i)("conversation.pickFolder")),1)])],6)):X("",!0)])):(v(),E("button",{key:1,type:"button",class:"ws-chip ws-ghost",onClick:Se[12]||(Se[12]=Ve=>s("addWorkspace"))},[U(f(ve),{name:"folder-plus"}),C("span",null,D(f(i)("conversation.pickFolder")),1)]))])]),key:"0"}]),1032,["session-id","running","working","queued","search-files","upload-image","status","thinking","plan-mode","plan-armed","swarm-mode","goal-mode","goal","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","starting"]),r.value?(v(),E("div",{key:3,class:"ws-backdrop",onClick:Se[29]||(Se[29]=Ve=>r.value=!1)})):X("",!0),C("div",JGe,[h.value&&(e.recentSessions?.length??0)>0?(v(),ce(fGe,{key:0,sessions:e.recentSessions??[],onSelectSession:Se[30]||(Se[30]=Ve=>s("selectSession",Ve)),onOpenSessionAdmin:Se[31]||(Se[31]=Ve=>s("openSessionAdmin",e.activeWorkspaceId??void 0))},null,8,["sessions"])):X("",!0)])],64)):(v(),ce(EA,{ref_key:"chatPaneRef",ref:y,key:e.fileReloadKey??"no-session",turns:e.turns,cwd:e.status.cwd,approvals:e.approvals,questions:e.questions,"turn-active":e.turnActive,working:e.working,"session-loading":e.sessionLoading,compaction:e.compaction,"has-more-messages":e.hasMoreMessages,"loading-more":e.loadingMore,"loading-more-error":e.loadingMoreError,"is-following":jt.value,queued:e.queued,"undo-hint-turn-id":vt.value,"interrupted-turn-id":Qe.value,"turn-failed":Je.value,"turn-error":e.turnError??null,"turn-retry":e.turnRetry??null,onResumeTurn:ft,onOpenFile:Se[32]||(Se[32]=Ve=>s("openFile",Ve)),onOpenMedia:Se[33]||(Se[33]=Ve=>s("openMedia",Ve)),onOpenTurnDiff:Se[34]||(Se[34]=Ve=>s("openTurnDiff",Ve)),onCopyConversationCopied:L,onOpenCompaction:Se[35]||(Se[35]=Ve=>s("openCompaction",Ve)),onOpenAgent:Se[36]||(Se[36]=Ve=>s("openAgent",Ve)),onEditMessage:Eo,onArmedUndo:Me,onLoadOlderMessages:Mo,onUnqueue:Se[37]||(Se[37]=Ve=>s("unqueue",Ve)),onEditQueued:Tr,onReorderQueue:Lr,onSteerQueued:Se[38]||(Se[38]=Ve=>s("steerQueued",Ve))},null,8,["turns","cwd","approvals","questions","turn-active","working","session-loading","compaction","has-more-messages","loading-more","loading-more-error","is-following","queued","undo-hint-turn-id","interrupted-turn-id","turn-failed","turn-error","turn-retry"]))],2)],34),e.turns.length===0&&!e.sessionLoading?X("",!0):(v(),ce(JZe,{key:0,ref:on,style:Kt(nn.value),"session-id":e.sessionId,running:e.running,working:e.working,starting:e.starting,queued:e.queued,"search-files":e.searchFiles,"upload-image":e.uploadImage,status:e.status,thinking:e.thinking,"plan-mode":e.planMode,"plan-armed":e.planArmed,"swarm-mode":e.swarmMode,"goal-mode":e.goalMode,"activation-badges":e.activationBadges,models:e.models,"auth-ready":e.authReady,"managed-signed-in":e.managedSignedIn,"managed-membership":e.managedMembership,"starred-ids":e.starredIds,skills:e.skills,goal:e.goal,"session-plans":e.sessionPlans,"dock-panel":P.value,"overlay-open":e.overlayOpen,"bash-tasks":M.value,"subagent-tasks":N.value,"bash-running":I.value,"subagent-running":z.value,"todo-done-count":$.value,"has-dock-work":W.value,todos:e.todos,"pending-question":le.value,"question-busy-kind":ge.value,"pending-approval":ke.value,"approval-busy":Ie.value,mobile:e.mobile,onToggleDockPanel:Se[39]||(Se[39]=Ve=>ae(Ve)),onCloseDockPanel:Se[40]||(Se[40]=Ve=>V()),onOpenAgent:Se[41]||(Se[41]=Ve=>s("openAgent",Ve)),"open-file":Ve=>s("openFile",Ve),onAnswer:jl,onDismiss:Se[42]||(Se[42]=Ve=>s("dismiss",Ve)),onApproval:Nr,onCancelTask:Se[43]||(Se[43]=Ve=>s("cancelTask",Ve)),onControlGoal:Se[44]||(Se[44]=Ve=>s("controlGoal",Ve)),onSubmit:As,onSteer:Se[45]||(Se[45]=Ve=>s("steer",Ve)),onCommand:Se[46]||(Se[46]=Ve=>s("command",Ve)),onInterrupt:Pt,onSetPermission:Se[47]||(Se[47]=Ve=>s("setPermission",Ve)),onSetThinking:Se[48]||(Se[48]=Ve=>s("setThinking",Ve)),onTogglePlan:Se[49]||(Se[49]=Ve=>s("togglePlan")),onToggleSwarm:Se[50]||(Se[50]=Ve=>s("toggleSwarm")),onToggleGoal:Se[51]||(Se[51]=Ve=>s("toggleGoal")),onOpenBtw:Se[52]||(Se[52]=Ve=>s("command",{cmd:"/btw",attachments:[]})),onCreateGoal:Se[53]||(Se[53]=Ve=>s("createGoal",Ve)),onFocusGoal:Y,onCompact:Se[54]||(Se[54]=Ve=>s("compact")),onPickModel:Se[55]||(Se[55]=Ve=>s("pickModel")),onSelectModel:Se[56]||(Se[56]=Ve=>s("selectModel",Ve)),onLogin:Se[57]||(Se[57]=Ve=>s("login"))},null,8,["style","session-id","running","working","starting","queued","search-files","upload-image","status","thinking","plan-mode","plan-armed","swarm-mode","goal-mode","activation-badges","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","goal","session-plans","dock-panel","overlay-open","bash-tasks","subagent-tasks","bash-running","subagent-running","todo-done-count","has-dock-work","todos","pending-question","question-busy-kind","pending-approval","approval-busy","mobile","open-file"]))],4),ut.value?(v(),ce(LGe,{key:2,ref_key:"transcriptSearchRef",ref:_t,pane:Oe.value,mobile:e.mobile,reveal:Ki,onClose:Vt},null,8,["pane","mobile"])):X("",!0),U(fo,{name:"pill"},{default:de(()=>[kn.value&&e.turns.length>0?(v(),E("button",{key:0,class:"newmsg-pill",style:Kt({bottom:`${tt.value+12}px`}),"aria-label":f(i)("conversation.jumpToLatestAria"),onClick:Se[58]||(Se[58]=Ve=>_o(!0))},[U(f(ve),{class:"pill-chevron",name:"arrow-down",size:"sm"}),$e(" "+D(f(i)("conversation.newMessages")),1)],12,XGe)):X("",!0)]),_:1}),U(fo,{name:"undo-toast"},{default:de(()=>[vn.value?(v(),E("div",eQe,[C("span",tQe,D(f(i)("conversation.undone")),1)])):X("",!0)]),_:1})],2))}}),uQe=kt(aQe,[["__scopeId","data-v-031838d6"]]),fv=4,rp=8;function RA(e){const t=K(!1),n=K({});let i=null;function o(){document.removeEventListener("mousedown",l),document.removeEventListener("keydown",a),window.removeEventListener("resize",r),window.removeEventListener("scroll",u,!0)}function s(){document.addEventListener("mousedown",l),document.addEventListener("keydown",a),window.addEventListener("resize",r),window.addEventListener("scroll",u,!0)}function r(){t.value&&(t.value=!1,i=null,o())}function l(g){const m=g.target;m.closest(".sa-menu")||i!==null&&i.contains(m)||r()}function a(g){g.key==="Escape"&&r()}function u(g){g.target instanceof Element&&g.target.closest(".sa-menu")||r()}async function c(g,m,k){t.value||(t.value=!0,s()),await dt();const w=e.value?.el,y=w?.offsetHeight??0,b=w?.offsetWidth??0;let A=m,T=!1;A+y>window.innerHeight-rp&&(A=Math.max(rp,m-y-(k?.flipAboveGap??0)),T=!0);let S=k?.alignRightTo!==void 0?k.alignRightTo-b:g;S+b>window.innerWidth-rp&&(S=Math.max(rp,window.innerWidth-b-rp)),n.value={top:`${Math.round(A)}px`,left:`${Math.round(S)}px`,transformOrigin:T?"bottom left":"top left","--menu-pop-shift":T?"2px":"-2px"}}async function d(g){if(t.value){r();return}i=g.currentTarget;const m=i.getBoundingClientRect();await c(m.left,m.bottom+fv,{flipAboveGap:m.height+fv*2})}async function h(g,m){if(t.value){r();return}i=g.currentTarget;const k=i.getBoundingClientRect();await c(k.left,k.bottom+fv,{flipAboveGap:k.height+fv*2,alignRightTo:m==="right"?k.right:void 0})}async function p(g,m){i=null,await c(g,m)}return Hn(o),{open:t,menuStyle:n,toggle:d,toggleAnchored:h,openAt:p,close:r}}const cQe=["aria-label"],dQe={class:"sa-select-label"},fQe={class:"sa-check"},hQe=Xe({__name:"FilterSelect",props:{modelValue:{},options:{},ariaLabel:{}},emits:["update:modelValue"],setup(e,{expose:t,emit:n}){const i=e,o=n,s=K(null),{open:r,menuStyle:l,toggle:a,close:u}=RA(s);t({open:r});const c=F(()=>i.options.find(h=>h.value===i.modelValue)?.label??"");function d(h){h!==i.modelValue&&o("update:modelValue",h),u()}return(h,p)=>(v(),E(Ee,null,[C("button",{class:Fe(["sa-select",{"is-open":f(r)}]),type:"button","aria-label":e.ariaLabel,onClick:p[0]||(p[0]=(...g)=>f(a)&&f(a)(...g))},[C("span",dQe,D(c.value),1),U(f(ve),{class:"sa-select-chev",name:"chevron-down",size:"sm"})],10,cQe),U(fo,{name:"menu-pop"},{default:de(()=>[f(r)?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:s,class:"sa-menu",style:Kt(f(l)),onClick:p[1]||(p[1]=wt(()=>{},["stop"]))},{default:de(()=>[(v(!0),E(Ee,null,pt(e.options,g=>(v(),ce(f(Ut),{key:g.value,onClick:m=>d(g.value)},{default:de(()=>[C("span",fQe,[g.value===e.modelValue?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)]),g.dot?(v(),E("span",{key:0,class:Fe(["sa-dot",`sa-dot--${g.dot}`])},null,2)):X("",!0),$e(" "+D(g.label),1)]),_:2},1032,["onClick"]))),128))]),_:1},8,["style"])):X("",!0)]),_:1})],64))}}),T5=kt(hQe,[["__scopeId","data-v-559b928b"]]),pQe=["aria-label","onKeydown"],gQe={class:"sa-tag-name"},mQe=["aria-label","onClick"],vQe={key:0,class:"sa-tag-more"},yQe={key:1,class:"sa-select-label"},kQe={class:"sa-search"},bQe=["placeholder","aria-label"],AQe={class:"sa-opts"},CQe={class:"sa-ws-name"},wQe={key:0,class:"sa-menu-empty"},xQe=Xe({__name:"MultiSelectMenu",props:{options:{},modelValue:{},ariaLabel:{}},emits:["update:modelValue"],setup(e,{expose:t,emit:n}){const i=e,o=n,{t:s}=zt(),r=K(null),{open:l,menuStyle:a,toggle:u}=RA(r);t({open:l});const c=F(()=>new Set(i.modelValue)),d=F(()=>i.options.length>0&&c.value.size===i.options.length),h=F(()=>i.options.filter(x=>c.value.has(x.id))),p=F(()=>h.value.slice(0,2)),g=F(()=>h.value.length-p.value.length),m=K(""),k=K(null),w=F(()=>{const x=m.value.trim().toLowerCase();return x===""?i.options:i.options.filter(_=>_.name.toLowerCase().includes(x))});Pe(l,x=>{x?dt(()=>k.value?.focus()):m.value=""});function y(x){o("update:modelValue",i.options.filter(_=>x.has(_.id)).map(_=>_.id))}function b(x){const _=new Set(c.value);_.has(x)?_.delete(x):_.add(x),y(_)}function A(x){const _=new Set(c.value);_.delete(x),y(_)}function T(){y(d.value?new Set:new Set(i.options.map(x=>x.id)))}function S(x){u(x)}return(x,_)=>(v(),E(Ee,null,[C("div",{class:Fe(["sa-select",{"is-open":f(l)}]),role:"button",tabindex:"0","aria-label":e.ariaLabel,onClick:_[2]||(_[2]=(...L)=>f(u)&&f(u)(...L)),onKeydown:[Ho(wt(S,["prevent"]),["enter"]),Ho(wt(S,["prevent"]),["space"])]},[h.value.length>0?(v(),E(Ee,{key:0},[(v(!0),E(Ee,null,pt(p.value,L=>(v(),E("span",{key:L.id,class:"sa-tag"},[C("span",gQe,D(L.name),1),C("button",{class:"sa-tag-x",type:"button","aria-label":f(s)("admin.removeTag",{name:L.name}),onClick:wt(M=>A(L.id),["stop"]),onKeydown:[_[0]||(_[0]=Ho(wt(()=>{},["stop"]),["enter"])),_[1]||(_[1]=Ho(wt(()=>{},["stop"]),["space"]))]},[U(f(ve),{name:"close",size:"sm"})],40,mQe)]))),128)),g.value>0?(v(),E("span",vQe,"+"+D(g.value),1)):X("",!0)],64)):(v(),E("span",yQe,D(f(s)("admin.allWorkspaces")),1)),U(f(ve),{class:"sa-select-chev",name:"chevron-down",size:"sm"})],42,pQe),U(fo,{name:"menu-pop"},{default:de(()=>[f(l)?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:r,class:"sa-menu",style:Kt(f(a)),role:"dialog",onClick:_[4]||(_[4]=wt(()=>{},["stop"]))},{default:de(()=>[C("div",kQe,[U(f(ve),{name:"search",size:"sm"}),Wn(C("input",{ref_key:"searchRef",ref:k,"onUpdate:modelValue":_[3]||(_[3]=L=>m.value=L),class:"sa-search-input",type:"text",placeholder:f(s)("admin.searchWorkspace"),"aria-label":f(s)("admin.searchWorkspace")},null,8,bQe),[[Bs,m.value]])]),U(f(Ut),{role:"button",active:d.value,onClick:T},{default:de(()=>[$e(D(f(s)("admin.selectAll")),1)]),_:1},8,["active"]),U(f(Ut),{separator:""}),C("div",AQe,[(v(!0),E(Ee,null,pt(w.value,L=>(v(),ce(f(Ut),{key:L.id,role:"button",active:c.value.has(L.id),onClick:M=>b(L.id)},{default:de(()=>[C("span",CQe,D(L.name),1)]),_:2},1032,["active","onClick"]))),128)),w.value.length===0?(v(),E("div",wQe,D(f(s)("admin.noWorkspaceMatch")),1)):X("",!0)])]),_:1},8,["style"])):X("",!0)]),_:1})],64))}}),SQe=kt(xQe,[["__scopeId","data-v-08fc2991"]]);function zL(e){const t=new Date(e),n=i=>String(i).padStart(2,"0");return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}function OL(e){const t=new Date(e),n=i=>String(i).padStart(2,"0");return`${n(t.getMonth()+1)}-${n(t.getDate())} ${n(t.getHours())}:${n(t.getMinutes())}`}const _Qe={class:"sa-menu-head"},MQe=Xe({__name:"SessionAdminMenu",props:{mode:{},targetArchived:{type:Boolean},counts:{}},emits:["action"],setup(e,{expose:t,emit:n}){const i=n,{t:o}=zt(),s=K(null),{open:r,menuStyle:l,toggleAnchored:a,openAt:u,close:c}=RA(s);function d(h){c(),i("action",h)}return t({openAt:u,toggleAnchored:a,close:c}),(h,p)=>(v(),ce(fo,{name:"menu-pop"},{default:de(()=>[f(r)?(v(),ce(f(Zs),{key:0,ref_key:"menuRef",ref:s,class:"sa-menu",style:Kt(f(l)),onClick:p[11]||(p[11]=wt(()=>{},["stop"]))},{default:de(()=>[e.mode==="single"?(v(),E(Ee,{key:0},[U(f(Ut),{onClick:p[0]||(p[0]=g=>d("open"))},{default:de(()=>[U(f(ve),{name:"external-link",size:"sm"}),$e(" "+D(f(o)("admin.open")),1)]),_:1}),U(f(Ut),{onClick:p[1]||(p[1]=g=>d("rename"))},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(o)("admin.rename")),1)]),_:1}),U(f(Ut),{onClick:p[2]||(p[2]=g=>d("fork"))},{default:de(()=>[U(f(ve),{name:"git-fork",size:"sm"}),$e(" "+D(f(o)("admin.fork")),1)]),_:1}),U(f(Ut),{onClick:p[3]||(p[3]=g=>d("export"))},{default:de(()=>[U(f(ve),{name:"download",size:"sm"}),$e(" "+D(f(o)("admin.export")),1)]),_:1}),U(f(Ut),{separator:""}),e.targetArchived?(v(),ce(f(Ut),{key:0,onClick:p[4]||(p[4]=g=>d("restore"))},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),$e(" "+D(f(o)("admin.reopen")),1)]),_:1})):(v(),ce(f(Ut),{key:1,onClick:p[5]||(p[5]=g=>d("archive"))},{default:de(()=>[U(f(ve),{name:"state-done",size:"sm"}),$e(" "+D(f(o)("admin.markDone")),1)]),_:1}))],64)):e.mode==="rowActions"?(v(),E(Ee,{key:1},[U(f(Ut),{onClick:p[6]||(p[6]=g=>d("rename"))},{default:de(()=>[U(f(ve),{name:"pencil",size:"sm"}),$e(" "+D(f(o)("admin.rename")),1)]),_:1}),U(f(Ut),{onClick:p[7]||(p[7]=g=>d("fork"))},{default:de(()=>[U(f(ve),{name:"git-fork",size:"sm"}),$e(" "+D(f(o)("admin.fork")),1)]),_:1}),U(f(Ut),{onClick:p[8]||(p[8]=g=>d("export"))},{default:de(()=>[U(f(ve),{name:"download",size:"sm"}),$e(" "+D(f(o)("admin.export")),1)]),_:1})],64)):(v(),E(Ee,{key:2},[C("div",_Qe,D(f(o)("admin.batchSelected",{n:e.counts?.total??0})),1),U(f(Ut),{disabled:(e.counts?.open??0)===0,onClick:p[9]||(p[9]=g=>d("archive"))},{default:de(()=>[U(f(ve),{name:"state-done",size:"sm"}),$e(" "+D(f(o)("admin.markDoneCount",{n:e.counts?.open??0})),1)]),_:1},8,["disabled"]),U(f(Ut),{disabled:(e.counts?.done??0)===0,onClick:p[10]||(p[10]=g=>d("restore"))},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),$e(" "+D(f(o)("admin.reopenCount",{n:e.counts?.done??0})),1)]),_:1},8,["disabled"])],64))]),_:1},8,["style"])):X("",!0)]),_:1}))}}),IQe=kt(MQe,[["__scopeId","data-v-770e2854"]]),EQe={key:0},TQe={class:"sa-col-cb"},LQe=["aria-label"],NQe={key:0,colspan:"7",class:"sa-batch"},FQe={class:"sa-batch-inner"},DQe={class:"sa-batch-count"},BQe=["disabled"],$Qe=["disabled"],RQe=["disabled"],zQe={class:"sa-c-time"},OQe={class:"sa-c-time"},PQe=["onContextmenu"],jQe={class:"sa-col-cb"},HQe=["aria-label","onClick"],WQe=["onKeydown","onBlur"],qQe=["title"],UQe={class:"sa-ws"},KQe=["title"],VQe={class:"sa-c-time"},ZQe={class:"sa-time sa-time--full"},GQe={class:"sa-time sa-time--compact"},QQe={class:"sa-c-time"},YQe={class:"sa-time sa-time--full"},JQe={class:"sa-time sa-time--compact"},XQe={key:1,class:"sa-time sa-none"},eYe={class:"sa-act"},tYe={key:1,class:"sa-state"},nYe={key:2,class:"sa-state"},iYe={class:"sa-empty"},oYe=Xe({__name:"SessionAdminTable",props:{items:{},total:{},loading:{type:Boolean},workspaces:{},batchRunning:{}},emits:["archiveSessions","restoreSessions"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=pa(),r=F(()=>new Map(n.workspaces.map(W=>[W.id,W.name])));function l(W){return W.meta.title??W.meta.last_prompt??W.id.slice(0,12)}function a(W){const P=r.value.get(W.workspace.id);return P!==void 0?P:W.workspace.cwd!==null?Tu(W.workspace.cwd):"—"}function u(W){return W.meta.archived?zL(W.meta.archived_at??W.meta.updated_at):null}function c(W){return W.meta.archived?OL(W.meta.archived_at??W.meta.updated_at):null}const d=F(()=>s.sessionAdminSelectedIds.value),h=F(()=>s.sessionAdminSelectedCount.value),p=F(()=>s.sessionAdminOpenSelectedIds.value),g=F(()=>s.sessionAdminDoneSelectedIds.value),m=F(()=>s.sessionAdminAllMatching.value),k=F(()=>s.sessionAdminMaterializingAll.value),w=F(()=>({total:h.value,open:p.value.length,done:g.value.length})),y=F(()=>n.items.map(W=>({id:W.id,archived:W.meta.archived}))),b=F(()=>y.value.length>0&&y.value.every(W=>d.value.has(W.id))),A=F(()=>!b.value&&y.value.some(W=>d.value.has(W.id)));function T(){s.toggleSessionAdminPageSelection(y.value)}const S=K(null),x=K(""),_=K(null);function L(W){S.value=W.id,x.value=l(W),dt(()=>{_.value?.focus(),_.value?.select()})}async function M(W){if(S.value!==W.id)return;const P=x.value.trim();S.value=null,!(P===""||P===l(W))&&(await s.renameSession(W.id,P),await s.refreshSessionAdminSessions())}function N(W,P){W.stopPropagation(),W.key==="Enter"?M(P):W.key==="Escape"&&(S.value=null)}const I=K("single"),z=K(null),H=K(null);function O(W,P){P.preventDefault(),d.value.has(W.id)&&d.value.size>1?(I.value="multi",z.value=null):(s.setSessionAdminSelection([{id:W.id,archived:W.meta.archived}]),I.value="single",z.value=W),H.value?.openAt(P.clientX,P.clientY)}function R(W,P){I.value="rowActions",z.value=W,H.value?.toggleAnchored(P,"right")}function j(W){W.meta.archived?i("restoreSessions",[W.id]):i("archiveSessions",[W.id])}function $(W){if(I.value==="multi"){W==="archive"?i("archiveSessions",[...p.value]):W==="restore"&&i("restoreSessions",[...g.value]);return}const P=z.value;if(P!==null)switch(W){case"open":s.selectSession(P.id);break;case"rename":L(P);break;case"fork":s.forkSession(P.id);break;case"export":s.exportSession(P.id);break;case"archive":i("archiveSessions",[P.id]);break;case"restore":i("restoreSessions",[P.id]);break}}return(W,P)=>(v(),E(Ee,null,[C("div",{class:Fe(["sa-table-card",{"is-loading":e.loading&&e.items.length>0}])},[e.items.length>0?(v(),E("table",EQe,[P[5]||(P[5]=C("colgroup",null,[C("col",{class:"sa-col-cb"}),C("col",{class:"sa-col-title"}),C("col",{class:"sa-col-ws"}),C("col",{class:"sa-col-status"}),C("col"),C("col",{class:"sa-col-time"}),C("col",{class:"sa-col-time"}),C("col",{class:"sa-col-act"})],-1)),C("thead",null,[C("tr",null,[C("th",TQe,[C("button",{class:Fe(["sa-cb",{on:b.value,ind:A.value}]),type:"button","aria-label":f(o)("admin.selectPageAll"),onClick:T},[b.value?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):A.value?(v(),ce(f(ve),{key:1,name:"minus",size:"sm"})):X("",!0)],10,LQe)]),h.value>0?(v(),E("th",NQe,[C("div",FQe,[C("span",DQe,D(m.value?f(o)("admin.allMatchingSelected",{n:h.value}):f(o)("admin.batchSelected",{n:h.value})),1),m.value?(v(),E("button",{key:0,class:"sa-batch-link",type:"button",onClick:P[0]||(P[0]=Z=>f(s).clearSessionAdminSelection())},D(f(o)("admin.clearSelection")),1)):b.value&&e.total>h.value?(v(),E("button",{key:1,class:"sa-batch-link",type:"button",disabled:k.value,onClick:P[1]||(P[1]=Z=>f(s).selectSessionAdminAllMatching())},D(k.value?f(o)("admin.materializingAll"):f(o)("admin.selectAllMatching",{total:e.total})),9,BQe)):X("",!0),C("button",{class:"sa-btn-q sa-btn-q--primary",type:"button",disabled:w.value.open===0||e.batchRunning!==null,onClick:P[2]||(P[2]=Z=>i("archiveSessions",[...p.value]))},[e.batchRunning==="archive"?(v(),ce(f(Oi),{key:0,size:"sm"})):(v(),ce(f(ve),{key:1,name:"state-done",size:"sm"})),$e(" "+D(f(o)("admin.markDone")),1)],8,$Qe),C("button",{class:"sa-btn-q",type:"button",disabled:w.value.done===0||e.batchRunning!==null,onClick:P[3]||(P[3]=Z=>i("restoreSessions",[...g.value]))},[e.batchRunning==="restore"?(v(),ce(f(Oi),{key:0,size:"sm"})):(v(),ce(f(ve),{key:1,name:"undo",size:"sm"})),$e(" "+D(f(o)("admin.reopen")),1)],8,RQe)])])):(v(),E(Ee,{key:1},[C("th",null,D(f(o)("admin.colTitle")),1),C("th",null,D(f(o)("admin.colWorkspace")),1),C("th",null,D(f(o)("admin.colStatus")),1),C("th",null,D(f(o)("admin.colPrompt")),1),C("th",zQe,D(f(o)("admin.colUpdated")),1),C("th",OQe,D(f(o)("admin.colCompleted")),1),C("th",null,D(f(o)("admin.colActions")),1)],64))])]),C("tbody",null,[(v(!0),E(Ee,null,pt(e.items,Z=>(v(),E("tr",{key:Z.id,onContextmenu:ae=>O(Z,ae)},[C("td",jQe,[C("button",{class:Fe(["sa-cb",{on:d.value.has(Z.id)}]),type:"button","aria-label":Z.id,onClick:ae=>f(s).toggleSessionAdminSelection(Z.id,Z.meta.archived)},[d.value.has(Z.id)?(v(),ce(f(ve),{key:0,name:"check",size:"sm"})):X("",!0)],10,HQe)]),C("td",null,[S.value===Z.id?Wn((v(),E("input",{key:0,ref_for:!0,ref_key:"renameInputRef",ref:_,"onUpdate:modelValue":P[4]||(P[4]=ae=>x.value=ae),class:"sa-rename",type:"text",onKeydown:ae=>N(ae,Z),onBlur:ae=>void M(Z)},null,40,WQe)),[[Bs,x.value]]):(v(),E("span",{key:1,class:"sa-title",title:l(Z)},D(l(Z)),9,qQe))]),C("td",null,[C("span",UQe,[C("span",null,D(a(Z)),1)])]),C("td",null,[C("span",{class:Fe(["sa-st",Z.meta.archived?"sa-st--done":"sa-st--open"])},[U(f(ve),{name:Z.meta.archived?"state-done":"state-open",size:"sm"},null,8,["name"]),$e(" "+D(Z.meta.archived?f(o)("admin.statusDone"):f(o)("admin.statusOpen")),1)],2)]),C("td",{class:"sa-prompt",title:Z.meta.last_prompt??void 0},[C("span",{class:Fe({"sa-none":Z.meta.last_prompt===null})},D(Z.meta.last_prompt??"—"),3)],8,KQe),C("td",VQe,[C("span",ZQe,D(f(zL)(Z.meta.updated_at)),1),C("span",GQe,D(f(OL)(Z.meta.updated_at)),1)]),C("td",QQe,[u(Z)!==null?(v(),E(Ee,{key:0},[C("span",YQe,D(u(Z)),1),C("span",JQe,D(c(Z)),1)],64)):(v(),E("span",XQe,"—"))]),C("td",null,[C("div",eYe,[U(f(Jt),{size:"sm",label:Z.meta.archived?f(o)("admin.reopen"):f(o)("admin.markDone"),tooltip:Z.meta.archived?f(o)("admin.reopen"):f(o)("admin.markDone"),onClick:ae=>j(Z)},{default:de(()=>[U(f(ve),{name:Z.meta.archived?"undo":"state-done"},null,8,["name"])]),_:2},1032,["label","tooltip","onClick"]),U(f(Jt),{size:"sm",label:f(o)("admin.moreActions"),tooltip:f(o)("admin.moreActions"),onClick:ae=>R(Z,ae)},{default:de(()=>[U(f(ve),{name:"dots-horizontal"})]),_:1},8,["label","tooltip","onClick"])])])],40,PQe))),128))])])):e.loading?(v(),E("div",tYe,[U(f(Oi),{size:"lg",label:f(o)("admin.loading")},null,8,["label"])])):(v(),E("div",nYe,[C("p",iYe,D(f(o)("admin.empty")),1)]))],2),U(IQe,{ref_key:"adminMenuRef",ref:H,mode:I.value,"target-archived":z.value?.meta.archived,counts:w.value,onAction:$},null,8,["mode","target-archived","counts"])],64))}}),sYe=kt(oYe,[["__scopeId","data-v-9b9dc9c2"]]);function rYe(e,t){return t<=7?Array.from({length:t},(n,i)=>i+1):e<=4?[1,2,3,4,5,"…",t]:e>=t-3?[1,"…",t-4,t-3,t-2,t-1,t]:[1,"…",e-1,e,e+1,"…",t]}const lYe={class:"sa-pager"},aYe={class:"sa-total"},uYe={class:"sa-pager-right"},cYe={key:0,class:"sa-pages"},dYe=["disabled","title","aria-label"],fYe={key:0,class:"sa-ellipsis"},hYe=["onClick"],pYe=["disabled","title","aria-label"],gYe=Xe({__name:"SessionAdminPagination",props:{page:{},pageSize:{},total:{}},emits:["update:page","update:pageSize"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=[10,20,50,100],r=F(()=>Math.max(1,Math.ceil(n.total/n.pageSize))),l=F(()=>rYe(n.page,r.value)),a=F(()=>s.map(c=>({value:String(c),label:o("admin.pageSize",{n:c})}))),u=F({get:()=>String(n.pageSize),set:c=>i("update:pageSize",Number(c))});return(c,d)=>(v(),E("div",lYe,[C("span",aYe,D(f(o)("admin.total",{n:e.total})),1),C("div",uYe,[U(T5,{modelValue:u.value,"onUpdate:modelValue":d[0]||(d[0]=h=>u.value=h),options:a.value,"aria-label":f(o)("admin.pageSize",{n:e.pageSize})},null,8,["modelValue","options","aria-label"]),e.total>0?(v(),E("div",cYe,[C("button",{class:"sa-pg",type:"button",disabled:e.page===1,title:f(o)("admin.prevPage"),"aria-label":f(o)("admin.prevPage"),onClick:d[1]||(d[1]=h=>i("update:page",e.page-1))},[U(f(ve),{name:"chevron-left",size:"sm"})],8,dYe),(v(!0),E(Ee,null,pt(l.value,(h,p)=>(v(),E(Ee,{key:p},[h==="…"?(v(),E("span",fYe,"…")):(v(),E("button",{key:1,class:Fe(["sa-pg",{cur:h===e.page}]),type:"button",onClick:g=>i("update:page",h)},D(h),11,hYe))],64))),128)),C("button",{class:"sa-pg",type:"button",disabled:e.page===r.value,title:f(o)("admin.nextPage"),"aria-label":f(o)("admin.nextPage"),onClick:d[2]||(d[2]=h=>i("update:page",e.page+1))},[U(f(ve),{name:"chevron-right",size:"sm"})],8,pYe)])):X("",!0)])]))}}),mYe=kt(gYe,[["__scopeId","data-v-a27fa76f"]]),vYe={class:"sa-head"},yYe={class:"sa-title"},kYe={class:"sa-scroll"},bYe={class:"sa-page"},AYe={class:"sa-subtitle"},CYe={class:"sa-f-label"},wYe={class:"sa-f-label"},xYe={class:"sa-f-label"},SYe={class:"sa-f-actions"},_Ye=Xe({__name:"SessionAdminView",props:{batchRunning:{}},emits:["archiveSessions","restoreSessions"],setup(e,{emit:t}){const{t:n}=zt(),i=pa(),o=t,s=F(()=>i.sessionAdminItems.value),r=F(()=>i.sessionAdminTotal.value),l=F(()=>i.sessionAdminLoading.value),a=F(()=>i.sessionAdminPage.value),u=F(()=>i.sessionAdminPageSize.value),c=F(()=>i.workspacesView.value.map(N=>({id:N.id,name:N.name}))),d={"3d":3,"7d":7,"30d":30};function h(N){if(N==="all")return"";const I=new Date;I.setDate(I.getDate()-d[N]);const z=H=>String(H).padStart(2,"0");return`${I.getFullYear()}-${z(I.getMonth()+1)}-${z(I.getDate())}`}function p(N){for(const I of["3d","7d","30d"])if(h(I)===N)return I;return"all"}const g=K([]),m=K("all"),k=K("all");function w(){const N=i.sessionAdminFilters.value;g.value=[...N.workspaceIds],m.value=N.status,k.value=N.updatedFrom===""?p(N.updatedTo):"all"}w(),Pe(()=>i.mainView.value,N=>{N==="sessionAdmin"&&w()});function y(){i.applySessionAdminFilters({workspaceIds:[...g.value],status:m.value,updatedFrom:"",updatedTo:h(k.value)})}function b(){g.value=[],m.value="all",k.value="all",i.applySessionAdminFilters({workspaceIds:[],status:"all",updatedFrom:"",updatedTo:""})}const A=K(null),T=K(null),S=K(null),x=F(()=>A.value?.open===!0||T.value?.open===!0||S.value?.open===!0);function _(){x.value||y()}const L=F(()=>[{value:"all",label:n("admin.statusAll")},{value:"open",label:n("admin.statusOpen"),dot:"open"},{value:"done",label:n("admin.statusDone"),dot:"done"}]),M=F(()=>[{value:"all",label:n("admin.timeAll")},{value:"3d",label:n("admin.timeDaysAgo",{n:3})},{value:"7d",label:n("admin.timeDaysAgo",{n:7})},{value:"30d",label:n("admin.timeDaysAgo",{n:30})}]);return(N,I)=>(v(),E("section",{class:Fe(["con session-admin",{"macos-desktop":f(pc)}])},[C("header",vYe,[U(f(gn),{text:f(n)("admin.back")},{default:de(()=>[U(f(Jt),{size:"sm",label:f(n)("admin.back"),onClick:I[0]||(I[0]=z=>f(i).closeSessionAdmin())},{default:de(()=>[U(f(ve),{name:"chevron-left"})]),_:1},8,["label"])]),_:1},8,["text"]),C("h1",yYe,D(f(n)("admin.title")),1)]),C("div",kYe,[C("div",bYe,[C("p",AYe,D(f(n)("admin.subtitle")),1),C("div",{class:"sa-filters",onKeydown:Ho(_,["enter"])},[C("span",CYe,D(f(n)("admin.filterWorkspace")),1),U(SQe,{ref_key:"wsMenuRef",ref:A,modelValue:g.value,"onUpdate:modelValue":I[1]||(I[1]=z=>g.value=z),options:c.value,"aria-label":f(n)("admin.filterWorkspace")},null,8,["modelValue","options","aria-label"]),C("span",wYe,D(f(n)("admin.filterStatus")),1),U(T5,{ref_key:"statusSelectRef",ref:T,modelValue:m.value,"onUpdate:modelValue":I[2]||(I[2]=z=>m.value=z),options:L.value,"aria-label":f(n)("admin.filterStatus")},null,8,["modelValue","options","aria-label"]),C("span",xYe,D(f(n)("admin.filterTime")),1),U(T5,{ref_key:"timeSelectRef",ref:S,modelValue:k.value,"onUpdate:modelValue":I[3]||(I[3]=z=>k.value=z),options:M.value,"aria-label":f(n)("admin.filterTime")},null,8,["modelValue","options","aria-label"]),C("div",SYe,[U(f(Qt),{variant:"primary",size:"sm",onClick:y},{default:de(()=>[$e(D(f(n)("admin.query")),1)]),_:1}),U(f(Qt),{variant:"ghost",size:"sm",onClick:b},{default:de(()=>[$e(D(f(n)("admin.reset")),1)]),_:1})])],32),U(sYe,{items:s.value,total:r.value,loading:l.value,workspaces:f(i).workspacesView.value,"batch-running":e.batchRunning,onArchiveSessions:I[4]||(I[4]=z=>o("archiveSessions",z)),onRestoreSessions:I[5]||(I[5]=z=>o("restoreSessions",z))},null,8,["items","total","loading","workspaces","batch-running"]),U(mYe,{page:a.value,"page-size":u.value,total:r.value,"onUpdate:page":I[6]||(I[6]=z=>f(i).setSessionAdminPage(z)),"onUpdate:pageSize":I[7]||(I[7]=z=>f(i).setSessionAdminPageSize(z))},null,8,["page","page-size","total"])])])],2))}}),MYe=kt(_Ye,[["__scopeId","data-v-01565f3a"]]);function PL(e,t){return t.succeeded===0?null:{direction:e,ids:t.okIds,succeeded:t.succeeded,failed:t.failed}}function IYe(e){return e==="archive"?"restore":"archive"}const EYe={key:0,class:"fp-empty fp-error"},TYe={key:1,class:"fp-empty"},LYe={key:2,class:"fp-loading"},NYe={class:"fp-path"},FYe={class:"fp-meta"},DYe={key:0,class:"fp-lines"},BYe={class:"fp-size"},$Ye={key:3,class:"fp-search"},RYe=["placeholder"],zYe={key:0,class:"fp-search-count"},OYe=["href","aria-label"],PYe={key:1,class:"fp-code"},jYe={key:1,class:"fp-body fp-code"},HYe={key:2,class:"fp-body"},WYe=["srcdoc","title"],qYe={key:1,class:"fp-code"},UYe={key:3,class:"fp-body fp-pdf-wrap"},KYe=["src","title"],VYe={key:1,class:"fp-binary-card"},ZYe={class:"fp-binary-label"},GYe={key:4,class:"fp-body fp-table-wrap"},QYe={class:"fp-table"},YYe=["data-line"],JYe={key:5,class:"fp-body fp-image-wrap"},XYe=["src","alt"],eJe={key:1,class:"fp-binary-card"},tJe={class:"fp-binary-icon"},nJe={class:"fp-binary-label"},iJe={key:6,class:"fp-body fp-code"},oJe={key:7,class:"fp-body fp-binary-wrap"},sJe={class:"fp-binary-card"},rJe={class:"fp-binary-icon"},lJe={class:"fp-binary-label"},aJe=Xe({__name:"FilePreview",props:{file:{},loading:{type:Boolean},error:{},line:{},downloadUrl:{},closable:{type:Boolean},externalActions:{type:Boolean},openFile:{type:Function}},emits:["close","openExternal","reveal"],setup(e,{emit:t}){const{t:n}=zt(),i=hn("resolveImage",async ie=>ie),o=F(()=>ple(u.file?.path??""));function s(ie){if(/^(https?:|data:|blob:)/i.test(ie)||ie.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(ie)||ie.startsWith("\\\\"))return ie;const pe=o.value;return pe?LS(ie,pe):ie}async function r(ie){const pe=s(ie);return i?i(pe):pe}oi("resolveImage",r);function l(ie){return ie.startsWith("/")||/^[a-zA-Z]:[\\/]/.test(ie)||ie.startsWith("\\\\")?ie:LS(ie,o.value)}function a(ie){const pe=l(ie.path);return pe===ie.path?ie:{...ie,path:pe}}const u=e,c=t;function d(ie){u.openFile?.(a(ie))}const h=K(null),p=F(()=>{const ie=u.file;if(!ie)return"binary";const pe=ie.mime??"",Ne=ie.languageId??"",te=ie.path.toLowerCase();return pe==="text/markdown"||Ne==="markdown"||Ne==="md"||te.endsWith(".mdx")?"markdown":pe==="application/json"||Ne==="json"?"json":pe==="text/html"||Ne==="html"||te.endsWith(".html")||te.endsWith(".htm")?"html":pe==="application/pdf"||te.endsWith(".pdf")?"pdf":pe==="text/csv"||Ne==="csv"||te.endsWith(".csv")?"csv":pe.startsWith("image/")?"image":ie.isBinary?"binary":pe.startsWith("text/")||Ne!==""?"text":"binary"});function g(ie){const pe=atob(ie),Ne=Uint8Array.from(pe,te=>te.charCodeAt(0));return new TextDecoder().decode(Ne)}const m=F(()=>{const ie=u.file;if(!ie)return"";if(ie.encoding==="base64")try{return g(ie.content)}catch{return ie.content}return ie.content}),k=F(()=>{if(p.value!=="json"||!u.file)return"";try{return JSON.stringify(JSON.parse(m.value),null,2)}catch{return m.value}}),w=F(()=>u.file?(p.value==="json"?k.value:m.value).split(` -`):[]),y=F(()=>u.file?p.value==="json"?k.value:m.value:""),b=F(()=>w.value.map((ie,pe)=>pe+1)),A=F(()=>u.file&&y.value.length<=Nb?u.file.path:void 0),T=K(""),S=K(0),x=F(()=>{const ie=T.value.trim().toLowerCase();if(!ie)return[];const pe=[];return w.value.forEach((Ne,te)=>{Ne.toLowerCase().includes(ie)&&pe.push(te+1)}),pe});Pe(T,()=>{S.value=0});function _(ie,pe=!1){ie&&dt(()=>{const Ne=h.value?.querySelector(".fp-body"),te=Ne?.querySelector(`[data-line="${ie}"]`);if(!Ne||!te)return;pe&&(Ne.scrollTop=0);const be=Ne.getBoundingClientRect(),Q=te.getBoundingClientRect(),ue=Q.top-be.top+Ne.scrollTop;Ne.scrollTop=ue-Ne.clientHeight/2+Q.height/2})}Pe(()=>[u.file?.path,u.line],()=>_(u.line,!0),{immediate:!0});function L(ie){const pe=x.value;pe.length!==0&&(S.value=(S.value+ie+pe.length)%pe.length,_(pe[S.value]))}function M(ie){const pe=x.value;return{target:u.line===ie,hit:pe.includes(ie),active:pe[S.value]===ie}}function N(ie){return ie<1024?`${ie} B`:ie<1024*1024?`${(ie/1024).toFixed(1)} KB`:`${(ie/(1024*1024)).toFixed(1)} MB`}const I=K(!1),z=K(!1);function H(){u.file&&Xo(y.value).then(ie=>{ie&&(I.value=!0,setTimeout(()=>{I.value=!1},1400))})}function O(){u.file&&Xo(u.file.path).then(ie=>{ie&&(z.value=!0,setTimeout(()=>{z.value=!1},1400))})}const R=K("preview"),j=K("preview"),$=K("fit");function W(ie){R.value=ie}function P(ie){j.value=ie}function Z(ie){$.value=ie}Pe(p,ie=>{R.value=ie==="html"?"preview":"source",j.value="preview",$.value="fit"});const ae=F(()=>{const ie=u.file;return!ie||p.value!=="image"?null:ie.encoding==="base64"?`data:${ie.mime};base64,${ie.content}`:ie.mime==="image/svg+xml"?`data:${ie.mime};charset=utf-8,${encodeURIComponent(ie.content)}`:null}),V=F(()=>{const ie=u.file;return!ie||p.value!=="pdf"?null:u.downloadUrl?u.downloadUrl:ie.encoding==="base64"?`data:${ie.mime};base64,${ie.content}`:null}),Y=F(()=>u.file?["<!doctype html>",'<meta charset="utf-8">',`<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data: blob:; style-src 'unsafe-inline'; font-src data:;">`,m.value].join(""):"");function oe(ie){const pe=[];let Ne="",te=!1;for(let be=0;be<ie.length;be++){const Q=ie[be];Q==='"'&&ie[be+1]==='"'?(Ne+='"',be++):Q==='"'?te=!te:Q===","&&!te?(pe.push(Ne),Ne=""):Ne+=Q}return pe.push(Ne),pe}const q=F(()=>w.value.slice(0,200).map(oe));function ne(ie,pe=55){return!ie||ie.length<=pe?ie:"…"+ie.slice(ie.length-pe+1)}return(ie,pe)=>(v(),E("div",{ref_key:"rootRef",ref:h,class:"file-preview"},[e.error&&!e.loading?(v(),E("div",EYe,[C("span",null,D(e.error),1),e.closable?(v(),ce(f(Qt),{key:0,variant:"secondary",size:"sm",onClick:pe[0]||(pe[0]=Ne=>c("close"))},{default:de(()=>[$e(D(f(n)("filePreview.close")),1)]),_:1})):X("",!0)])):!e.file&&!e.loading?(v(),E("div",TYe,D(f(n)("filePreview.empty")),1)):e.loading?(v(),E("div",LYe,[pe[7]||(pe[7]=C("span",{class:"spinner"},null,-1)),C("span",null,D(f(n)("filePreview.loading")),1)])):e.file?(v(),E(Ee,{key:3},[U(f(rf),{wrap:"",title:f(n)("common.preview"),closable:e.closable,"close-label":f(n)("filePreview.close"),onClose:pe[6]||(pe[6]=Ne=>c("close"))},{default:de(()=>[U(f(gn),{text:e.file.path},{default:de(()=>[C("span",NYe,D(ne(e.file.path)),1)]),_:1},8,["text"]),C("span",FYe,[e.file.lineCount?(v(),E("span",DYe,D(f(n)("filePreview.lineCount",{count:e.file.lineCount})),1)):X("",!0),C("span",BYe,D(N(e.file.size)),1)]),p.value==="html"?(v(),ce(f(Vs),{key:0,"model-value":R.value,size:"sm",options:[{value:"preview",label:f(n)("filePreview.preview")},{value:"source",label:f(n)("filePreview.source")}],"onUpdate:modelValue":W},null,8,["model-value","options"])):X("",!0),p.value==="markdown"?(v(),ce(f(Vs),{key:1,"model-value":j.value,size:"sm",options:[{value:"preview",label:f(n)("filePreview.preview")},{value:"source",label:f(n)("filePreview.source")}],"onUpdate:modelValue":P},null,8,["model-value","options"])):X("",!0),p.value==="image"?(v(),ce(f(Vs),{key:2,"model-value":$.value,size:"sm",options:[{value:"fit",label:f(n)("filePreview.fit")},{value:"actual",label:f(n)("filePreview.actual")}],"onUpdate:modelValue":Z},null,8,["model-value","options"])):X("",!0),p.value==="text"||p.value==="json"||p.value==="html"||p.value==="csv"?(v(),E("div",$Ye,[Wn(C("input",{"onUpdate:modelValue":pe[1]||(pe[1]=Ne=>T.value=Ne),class:"fp-search-input",type:"search",placeholder:f(n)("filePreview.search")},null,8,RYe),[[Bs,T.value]]),T.value.trim()?(v(),E("span",zYe,D(x.value.length),1)):X("",!0),U(f(Jt),{size:"sm",disabled:x.value.length===0,label:f(n)("filePreview.prevMatch"),tooltip:f(n)("filePreview.prevMatch"),onClick:pe[2]||(pe[2]=Ne=>L(-1))},{default:de(()=>[U(f(ve),{name:"arrow-up",size:"md"})]),_:1},8,["disabled","label","tooltip"]),U(f(Jt),{size:"sm",disabled:x.value.length===0,label:f(n)("filePreview.nextMatch"),tooltip:f(n)("filePreview.nextMatch"),onClick:pe[3]||(pe[3]=Ne=>L(1))},{default:de(()=>[U(f(ve),{name:"arrow-down",size:"md"})]),_:1},8,["disabled","label","tooltip"])])):X("",!0),U(f(Jt),{size:"sm",class:Fe({copied:z.value}),label:z.value?f(n)("filePreview.copied"):f(n)("filePreview.copyPath"),tooltip:z.value?f(n)("filePreview.copied"):f(n)("filePreview.copyPath"),onClick:O},{default:de(()=>[z.value?(v(),ce(f(ve),{key:1,class:"fp-check",name:"check",size:"md"})):(v(),ce(f(ve),{key:0,name:"link",size:"md"}))]),_:1},8,["class","label","tooltip"]),e.externalActions?(v(),ce(f(Jt),{key:4,size:"sm",label:f(n)("filePreview.openInEditor"),tooltip:f(n)("filePreview.openInEditor"),onClick:pe[4]||(pe[4]=Ne=>c("openExternal"))},{default:de(()=>[U(f(ve),{name:"external-link",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),e.externalActions?(v(),ce(f(Jt),{key:5,size:"sm",label:f(n)("filePreview.reveal"),tooltip:f(n)("filePreview.reveal"),onClick:pe[5]||(pe[5]=Ne=>c("reveal"))},{default:de(()=>[U(f(ve),{name:"folder",size:"md"})]),_:1},8,["label","tooltip"])):X("",!0),e.downloadUrl?(v(),ce(f(gn),{key:6,text:f(n)("filePreview.download")},{default:de(()=>[C("a",{class:"fp-download",href:e.downloadUrl,target:"_blank",rel:"noreferrer",download:"","aria-label":f(n)("filePreview.download")},[U(f(ve),{name:"download",size:"md"})],8,OYe)]),_:1},8,["text"])):X("",!0),!e.file.isBinary&&p.value!=="image"?(v(),ce(f(Jt),{key:7,size:"sm",class:Fe({copied:I.value}),label:I.value?f(n)("filePreview.copied"):f(n)("filePreview.copy"),tooltip:I.value?f(n)("filePreview.copied"):f(n)("filePreview.copy"),onClick:H},{default:de(()=>[I.value?(v(),ce(f(ve),{key:1,class:"fp-check",name:"check",size:"md"})):(v(),ce(f(ve),{key:0,name:"copy",size:"md"}))]),_:1},8,["class","label","tooltip"])):X("",!0)]),_:1},8,["title","closable","close-label"]),p.value==="markdown"?(v(),E("div",{key:0,class:Fe(["fp-body",{"fp-markdown":j.value==="preview"}])},[j.value==="preview"?(v(),ce(f(Iu),{key:e.file?.path,text:m.value,"open-file":u.openFile?d:void 0,"resolve-mention-path":l},null,8,["text","open-file"])):(v(),E("div",PYe,[U(oa,{code:w.value,path:A.value,"line-numbers":b.value,framed:!1,"line-class":M},null,8,["code","path","line-numbers"])]))],2)):p.value==="json"?(v(),E("div",jYe,[U(oa,{code:w.value,path:A.value,"line-numbers":b.value,framed:!1,"line-class":M},null,8,["code","path","line-numbers"])])):p.value==="html"?(v(),E("div",HYe,[R.value==="preview"?(v(),E("iframe",{key:0,class:"fp-html-frame",sandbox:"",srcdoc:Y.value,title:e.file.path},null,8,WYe)):(v(),E("div",qYe,[U(oa,{code:w.value,path:A.value,"line-numbers":b.value,framed:!1,"line-class":M},null,8,["code","path","line-numbers"])]))])):p.value==="pdf"?(v(),E("div",UYe,[V.value?(v(),E("iframe",{key:0,class:"fp-pdf-frame",src:V.value,title:e.file.path},null,8,KYe)):(v(),E("div",VYe,[C("span",ZYe,D(f(n)("filePreview.pdfNoPreview")),1)]))])):p.value==="csv"?(v(),E("div",GYe,[C("table",QYe,[C("tbody",null,[(v(!0),E(Ee,null,pt(q.value,(Ne,te)=>(v(),E("tr",{key:te,class:Fe(M(te+1)),"data-line":te+1},[C("th",null,D(te+1),1),(v(!0),E(Ee,null,pt(Ne,(be,Q)=>(v(),E("td",{key:Q},D(be),1))),128))],10,YYe))),128))])])])):p.value==="image"?(v(),E("div",JYe,[ae.value?(v(),E("img",{key:0,src:ae.value,alt:e.file.path,class:Fe(["fp-image",{actual:$.value==="actual"}])},null,10,XYe)):(v(),E("div",eJe,[C("span",tJe,[U(f(ve),{name:"image-off",size:"lg"})]),C("span",nJe,D(f(n)("filePreview.imageNoPreview",{mime:e.file.mime,size:N(e.file.size)})),1)]))])):p.value==="text"?(v(),E("div",iJe,[U(oa,{code:w.value,path:A.value,"line-numbers":b.value,framed:!1,"line-class":M},null,8,["code","path","line-numbers"])])):(v(),E("div",oJe,[C("div",sJe,[C("span",rJe,[U(f(ve),{name:"file-off",size:"lg"})]),C("span",lJe,D(f(n)("filePreview.binaryNoPreview",{mime:e.file.mime||f(n)("filePreview.unknownType"),size:N(e.file.size)})),1)])]))],64)):X("",!0)],512))}}),uJe=kt(aJe,[["__scopeId","data-v-9a4f39c9"]]),cJe={class:"tp"},dJe=Xe({__name:"ThinkingPanel",props:{text:{},subtitle:{}},emits:["close"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=K(null);return Pe(()=>n.text,()=>{const r=s.value;!r||!(r.scrollHeight-r.scrollTop-r.clientHeight<24)||dt(()=>{s.value&&(s.value.scrollTop=s.value.scrollHeight)})},{immediate:!0}),(r,l)=>(v(),E("div",cJe,[U(f(rf),{title:f(o)("common.preview"),subtitle:e.subtitle??f(o)("thinking.panelTitle"),"close-label":f(o)("thinking.close"),onClose:l[0]||(l[0]=a=>i("close"))},null,8,["title","subtitle","close-label"]),C("pre",{ref_key:"bodyEl",ref:s,class:"tp-body"},D(e.text),513)]))}}),fJe=kt(dJe,[["__scopeId","data-v-afb1f46f"]]),hJe={class:"agent-panel"},pJe={key:0,class:"agent-fallback"},gJe={key:0,class:"agent-error"},mJe=Xe({__name:"AgentDetailPanel",props:{member:{},turns:{},running:{type:Boolean},loading:{type:Boolean},loadError:{type:Boolean},hasMore:{type:Boolean},loadingMore:{type:Boolean},loadMoreError:{type:Boolean}},emits:["close","loadOlderMessages","openAgent","openFile","openMedia","openTurnDiff"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=K(null),r=F(()=>{const q=n.member.prompt?.trim(),ne=q?`$ ${q}`:null;return Z.value.filter(ie=>ie!==q&&ie!==ne).join(` -`)});let l=null,a=0;function u(q){const ne=q==="command"?n.member.prompt:q==="output"?r.value:[n.member.prompt?.trim(),r.value].filter(Boolean).join(` - -`);if(!ne)return;const ie=a;Xo(ne).then(pe=>{!pe||ie!==a||(l!==null&&clearTimeout(l),s.value=q,l=setTimeout(()=>{l=null,s.value=null},1400))})}const c=typeof window<"u"&&window.matchMedia?.("(hover: none)").matches,d=c?"lg":"md",h=c?"lg":"sm",p=K(!1),g=K(null),m=K(null),k=K({left:"0px",top:"0px"});function w(){return g.value?.$el??null}async function y(){if(p.value){b();return}p.value=!0,await dt(),_(),A(),window.addEventListener("mousedown",L,!0),window.addEventListener("keydown",M,!0),window.addEventListener("resize",_),window.addEventListener("scroll",_,!0)}function b(q){p.value=!1,window.removeEventListener("mousedown",L,!0),window.removeEventListener("keydown",M,!0),window.removeEventListener("resize",_),window.removeEventListener("scroll",_,!0),q?.refocus&&w()?.focus()}function A(){const q=m.value;q&&q.querySelector(".ui-menu-item:not(:disabled)")?.focus()}function T(q){const ne=q.relatedTarget;ne&&(m.value?.contains(ne)||w()?.contains(ne))||b()}function S(){p.value||y()}function x(q){if(q.key!=="ArrowDown"&&q.key!=="ArrowUp")return;q.preventDefault();const ne=Array.from(m.value?.querySelectorAll(".ui-menu-item:not(:disabled)")??[]);if(ne.length===0)return;const ie=ne.indexOf(document.activeElement),pe=q.key==="ArrowDown"?(ie+1)%ne.length:(ie-1+ne.length)%ne.length;ne[pe]?.focus()}function _(){const q=w();if(!q)return;const ne=q.getBoundingClientRect(),ie=getComputedStyle(document.documentElement),pe=Number.parseFloat(ie.getPropertyValue("--space-2"))||0,Ne=Number.parseFloat(ie.getPropertyValue("--space-1"))||0,te=m.value?.offsetWidth??0,be=Math.max(pe,Math.min(ne.right-te,window.innerWidth-te-pe)),Q=m.value?.offsetHeight??0;ne.bottom+Ne+Q<=window.innerHeight-pe?k.value={left:`${be}px`,top:`${ne.bottom+Ne}px`}:k.value={left:`${be}px`,bottom:`${window.innerHeight-ne.top+Ne}px`}}function L(q){const ne=q.target;if(ne){if(m.value?.contains(ne)){q.stopImmediatePropagation();return}w()?.contains(ne)||b()}}function M(q){q.key==="Escape"&&(q.preventDefault(),q.stopImmediatePropagation(),b({refocus:!0}))}function N(q){u(q),b({refocus:!0})}Pe(Fs,q=>{q>0&&p.value&&b()});const I=F(()=>n.member.id),{scroller:z,following:H,onScroll:O,pinScroll:R}=_de(I);Pe(I,()=>{b(),a++,l!==null&&clearTimeout(l),l=null,s.value=null});const j=K(!1);let $=null,W=null;function P(){$!==null&&typeof cancelAnimationFrame=="function"&&cancelAnimationFrame($),W!==null&&clearTimeout(W),$=null,W=null}Pe(I,()=>{j.value=!1,P();const q=()=>{P(),j.value=!0};typeof requestAnimationFrame=="function"?$=requestAnimationFrame(()=>{$=requestAnimationFrame(q)}):W=setTimeout(q,32)},{immediate:!0}),Hn(()=>{P(),p.value&&b()});const Z=F(()=>{const q=new Set,ne=[],ie=n.member.prompt?.trim(),pe=ie?`$ ${ie}`:null;for(const Ne of[n.member.prompt,n.member.suspendedReason,n.member.text,n.member.outputLines?.join(` -`),n.member.summary]){const te=Ne?.trim();!te||q.has(te)||pe!==null&&te===pe||(q.add(te),ne.push(te))}return ne});oi("pinScroll",()=>{z.value&&R()});function ae(q){switch(q){case"queued":return o("tools.swarm.phaseQueued");case"working":return o("tools.swarm.phaseWorking");case"suspended":return o("tools.swarm.phaseSuspended");case"completed":return o("tools.swarm.phaseCompleted");case"failed":return o("tools.swarm.phaseFailed");case"cancelled":return o("tools.swarm.phaseCancelled")}}const V=hn("modelDisplay"),Y=hn("subagentEffort"),oe=F(()=>{const q=[n.member.subagentType,V?.(n.member.model),Y?.(n.member.thinkingEffort)].filter(ne=>!!ne);return q.length>0?q.join(" · "):void 0});return(q,ne)=>(v(),E("div",hJe,[U(f(rf),{title:e.member.name,subtitle:oe.value,"close-label":f(o)("thinking.close"),onClose:ne[3]||(ne[3]=ie=>i("close"))},{default:de(()=>[U(f(br),{variant:"neutral",size:"sm"},{default:de(()=>[$e(D(ae(e.member.phase)),1)]),_:1}),e.member.prompt||r.value?(v(),E(Ee,{key:0},[U(f(Jt),{ref_key:"copyTriggerRef",ref:g,size:f(h),class:Fe({"copy-menu-open":p.value}),label:f(o)("tasks.copy"),tooltip:f(o)("tasks.copy"),"aria-haspopup":"menu","aria-expanded":p.value,onClick:y,onKeydown:[Ho(wt(S,["prevent"]),["down"]),Ho(wt(S,["prevent"]),["up"])],onFocusout:T},{default:de(()=>[U(f(ve),{name:s.value?"check":"copy",size:"sm"},null,8,["name"])]),_:1},8,["size","class","label","tooltip","aria-expanded","onKeydown"]),(v(),ce(Ds,{to:"body"},[p.value?(v(),E("div",{key:0,ref_key:"copyMenuBoxRef",ref:m,class:"copy-menu",style:Kt(k.value),onKeydown:x,onFocusout:T},[U(f(Zs),null,{default:de(()=>[e.member.prompt?(v(),ce(f(Ut),{key:0,size:f(d),onClick:ne[0]||(ne[0]=ie=>N("command"))},{default:de(()=>[U(f(ve),{name:"terminal",size:"sm"}),C("span",null,D(f(o)("tasks.copyCommand")),1)]),_:1},8,["size"])):X("",!0),U(f(Ut),{disabled:!r.value,size:f(d),onClick:ne[1]||(ne[1]=ie=>N("output"))},{default:de(()=>[U(f(ve),{name:"file-text",size:"sm"}),C("span",null,D(f(o)("tasks.copyOutput")),1)]),_:1},8,["disabled","size"]),U(f(Ut),{separator:""}),U(f(Ut),{size:f(d),onClick:ne[2]||(ne[2]=ie=>N("all"))},{default:de(()=>[U(f(ve),{name:"copy",size:"sm"}),C("span",null,D(f(o)("tasks.copyAll")),1)]),_:1},8,["size"])]),_:1})],36)):X("",!0)]))],64)):X("",!0)]),_:1},8,["title","subtitle","close-label"]),C("div",{ref_key:"scroller",ref:z,class:"agent-transcript",onScrollPassive:ne[9]||(ne[9]=(...ie)=>f(O)&&f(O)(...ie))},[j.value?(v(),E(Ee,{key:0},[e.turns.length===0&&!e.loading&&(e.loadError||Z.value.length>0)?(v(),E("div",pJe,[e.loadError?(v(),E("div",gJe,D(f(o)("tasks.transcriptLoadError")),1)):X("",!0),Z.value.length>0?(v(),ce(Xr,{key:1,lines:Z.value},null,8,["lines"])):X("",!0)])):(v(),ce(EA,{key:1,turns:e.turns,"turn-active":e.running,"session-loading":e.loading&&e.turns.length===0,"has-more-messages":e.hasMore,"loading-more":e.loadingMore,"loading-more-error":e.loadMoreError,"is-following":f(H),"read-only":"",inspector:"",onLoadOlderMessages:ne[4]||(ne[4]=ie=>i("loadOlderMessages")),onOpenAgent:ne[5]||(ne[5]=ie=>i("openAgent",ie)),onOpenFile:ne[6]||(ne[6]=ie=>i("openFile",ie)),onOpenMedia:ne[7]||(ne[7]=ie=>i("openMedia",ie)),onOpenTurnDiff:ne[8]||(ne[8]=ie=>i("openTurnDiff",ie))},null,8,["turns","turn-active","session-loading","has-more-messages","loading-more","loading-more-error","is-following"]))],64)):X("",!0)],544)]))}}),vJe=kt(mJe,[["__scopeId","data-v-87af6ca2"]]),yJe={class:"sc"},kJe={key:0,class:"sc-empty"},bJe={key:2,class:"sc-loading"},AJe={class:"sc-composer"},CJe=["placeholder"],wJe=["disabled"],xJe=Xe({__name:"SideChatPanel",props:{turns:{},running:{type:Boolean},sending:{type:Boolean},title:{},subtitle:{},onSend:{type:Function}},emits:["close","openMedia"],setup(e,{expose:t,emit:n}){const i=e,o=n,{t:s}=zt(),r=F(()=>i.turns.find(_=>_.role==="user")?.text?.trim()??""),l=F(()=>i.title?.trim()||s("sideChat.title")),a=F(()=>i.subtitle?.trim()?i.subtitle.trim():r.value||s("sideChat.subtitle")),u=K(""),c=K(null),d=K(null),h=K(!1);async function p(){const x=u.value,_=x.trim();if(!(!_||h.value)){h.value=!0;try{if(!await i.onSend(_)||u.value!==x)return;u.value="",dt(()=>{c.value&&(c.value.style.height="auto"),g()})}finally{h.value=!1}}}function g(){const x=d.value;x&&(x.scrollTop=x.scrollHeight)}oi("pinScroll",x=>{const _=d.value;if(!_)return;const L=x.getBoundingClientRect().top;requestAnimationFrame(()=>{_.scrollTop+=x.getBoundingClientRect().top-L})});const m=F(()=>{const x=i.turns;if(x.length===0)return"0";const _=x.at(-1),L=_.thinking?.length??0,M=_.tools?.reduce((N,I)=>N+I.name.length+(I.arg?.length??0)+(I.output?.join("").length??0),0)??0;return`${x.length}:${_.text.length}:${L}:${M}`});Pe(m,async()=>{!i.running&&!i.sending||(await dt(),g())});const k=F(()=>i.sending?i.turns.at(-1)?.role==="user":!1),{handleCompositionStart:w,handleCompositionEnd:y,isComposingKeyEvent:b}=bl();function A(x){x.key==="Enter"&&!x.shiftKey&&!b(x)&&(x.preventDefault(),p())}function T(){const x=c.value;x&&(x.style.height="auto",x.style.height=`${Math.min(x.scrollHeight,160)}px`)}function S(){c.value?.focus()}return t({focusInput:S}),(x,_)=>(v(),E("div",yJe,[U(f(rf),{title:l.value,subtitle:a.value,"close-label":f(s)("thinking.close"),onClose:_[0]||(_[0]=L=>o("close"))},null,8,["title","subtitle","close-label"]),C("div",{ref_key:"bodyRef",ref:d,class:"sc-body"},[e.turns.length===0?(v(),E("div",kJe,D(f(s)("sideChat.empty")),1)):(v(),ce(EA,{key:1,turns:e.turns,approvals:[],"turn-active":e.running,working:e.sending||e.running,"turn-files-interactive":!1,onOpenMedia:_[1]||(_[1]=L=>o("openMedia",L))},null,8,["turns","turn-active","working"])),k.value?(v(),E("div",bJe,[U(xH,{label:f(s)("conversation.requesting")},null,8,["label"])])):X("",!0)],512),C("div",AJe,[Wn(C("textarea",{ref_key:"inputRef",ref:c,"onUpdate:modelValue":_[2]||(_[2]=L=>u.value=L),class:"sc-input",rows:"1",placeholder:f(s)("sideChat.placeholder"),onInput:T,onKeydown:A,onCompositionstart:_[3]||(_[3]=(...L)=>f(w)&&f(w)(...L)),onCompositionend:_[4]||(_[4]=(...L)=>f(y)&&f(y)(...L))},null,40,CJe),[[Bs,u.value]]),U(f(gn),{text:f(s)("sideChat.send")},{default:de(()=>[C("button",{type:"button",class:"sc-send",disabled:!u.value.trim(),onClick:p},[U(f(ve),{name:"arrow-right",size:"sm"})],8,wJe)]),_:1},8,["text"])])]))}}),SJe=kt(xJe,[["__scopeId","data-v-ce2b775d"]]),_Je={class:"changes-pane"},MJe={class:"dv-path"},IJe={class:"diff-head"},EJe={class:"back-label"},TJe={key:"loading",class:"empty-state diff-loading"},LJe={key:"lines",class:"dv-lines-wrap"},NJe={key:"empty",class:"empty-state"},FJe={class:"dv-change-count"},DJe={class:"ch-head"},BJe={class:"br-heading"},$Je={class:"br-label"},RJe={class:"br-name"},zJe={key:0,class:"sync-info"},OJe={key:0,class:"ahead"},PJe={key:0,class:"behind"},jJe={key:1,class:"empty-head"},HJe={class:"ch-list-content"},WJe=["onClick"],qJe={class:"fpath"},UJe=["onClick"],KJe={class:"tree-name"},VJe=["onClick"],ZJe={class:"tree-name"},GJe={key:2,class:"empty-state"},QJe={class:"empty-state-icon","aria-hidden":"true"},YJe={key:3,class:"empty-state"},JJe=Xe({__name:"DiffView",props:{changes:{},gitInfo:{},fileDiff:{},fullTexts:{},emptyFile:{type:Boolean},selectedDiffPath:{},fileDiffLoading:{type:Boolean},mode:{default:"full"},hideBack:{type:Boolean,default:!1},closable:{type:Boolean,default:!0}},emits:["open","back","close"],setup(e,{emit:t}){const{t:n}=zt();function i(z){return n(z===1?"diff.fileCountOne":"diff.fileCountOther",{number:z})}const o=e,s=t;function r(z){const H=z.toLowerCase();return H==="modified"?"modified":H==="added"?"added":H==="deleted"?"deleted":H==="renamed"?"renamed":H==="untracked"?"untracked":H==="conflicted"?"conflicted":H==="ignored"?"ignored":H==="clean"?"clean":"unknown"}const l={modified:"M",added:"+",deleted:"−",renamed:"→",untracked:"+",conflicted:"C",ignored:"I",clean:"·",unknown:"?"};function a(z){return l[r(z)]??"?"}function u(z,H=60){return z.length<=H?z:"…"+z.slice(z.length-H+1)}const c=F(()=>o.gitInfo!==null),d=F(()=>o.changes.length>0),h=F(()=>(o.selectedDiffPath??null)!==null),p=F(()=>o.mode==="detail"||o.mode==="full"&&h.value),g=F(()=>o.fileDiff??[]),m=F(()=>o.fileDiffLoading===!0);function k(z){s("open",z)}function w(){s("back")}function y(){s("close")}const b=K("list");function A(z){b.value=z}function T(z){const H={children:[]},O=[...z].sort((R,j)=>R.path.localeCompare(j.path));for(const R of O){const j=R.path.endsWith("/"),$=R.path.split("/").filter(Boolean);if($.length===0)continue;let W=H;for(let P=0;P<$.length;P++){const Z=$[P],ae=P===$.length-1&&!j,V=$.slice(0,P+1).join("/");let Y=W.children.find(oe=>oe.name===Z&&oe.kind===(ae?"file":"folder"));Y||(Y={name:Z,path:V,kind:ae?"file":"folder",status:ae?R.status:void 0,children:[]},W.children.push(Y)),W=Y}}return H.children}const S=F(()=>T(o.changes)),x=K(new Set);function _(z){return!x.value.has(z)}const L=F(()=>{const z=[];function H(O,R){for(const j of O)z.push({node:j,depth:R}),j.kind==="folder"&&_(j.path)&&H(j.children,R+1)}return H(S.value,0),z});function M(z){const H=new Set(x.value);H.has(z.path)?H.delete(z.path):H.add(z.path),x.value=H}function N(z){return`calc(var(--tree-base-indent) + ${z} * var(--tree-indent-step))`}function I(z){return{paddingLeft:N(z),"--tree-depth":String(z)}}return(z,H)=>(v(),E("div",_Je,[p.value?(v(),E(Ee,{key:0},[U(f(rf),{title:f(n)("diff.title"),closable:e.closable,"close-label":f(n)("diff.close"),onClose:y},{default:de(()=>[U(f(gn),{text:e.selectedDiffPath??""},{default:de(()=>[C("span",MJe,D(u(e.selectedDiffPath??"",50)),1)]),_:1},8,["text"])]),_:1},8,["title","closable","close-label"]),C("div",IJe,[e.hideBack?X("",!0):(v(),ce(f(Qt),{key:0,variant:"ghost",size:"sm",onClick:w},{default:de(()=>[U(f(ve),{name:"arrow-left",size:"sm"}),C("span",EJe,D(f(n)("diff.back")),1)]),_:1}))]),U(fo,{name:"diff-content",mode:"out-in"},{default:de(()=>[m.value?(v(),E("div",TJe,[U(f(Oi),{size:"md"}),C("span",null,D(f(n)("diff.loading")),1)])):g.value.length>0?(v(),E("div",LJe,[U(oa,{lines:g.value,path:e.selectedDiffPath??void 0,"line-numbers":"",framed:!1,"full-texts":e.fullTexts??null},null,8,["lines","path","full-texts"])])):(v(),E("div",NJe,D(e.emptyFile?f(n)("diff.emptyFile"):f(n)("diff.noDiff")),1))]),_:1})],64)):(v(),E(Ee,{key:1},[U(f(rf),{title:f(n)("diff.title"),closable:e.closable,"close-label":f(n)("diff.close"),onClose:y},{default:de(()=>[C("span",FJe,D(i(e.changes.length)),1),U(f(Vs),{"model-value":b.value,size:"sm",options:[{value:"list",label:f(n)("diff.list"),icon:"list"},{value:"tree",label:f(n)("diff.tree"),icon:"tree-view"}],"onUpdate:modelValue":A},null,8,["model-value","options"])]),_:1},8,["title","closable","close-label"]),C("div",DJe,[c.value?(v(),E(Ee,{key:0},[C("span",BJe,[U(f(ve),{class:"br-icon",name:"git-fork",size:"sm"}),C("span",$Je,D(f(n)("diff.branch")),1)]),C("span",RJe,D(e.gitInfo.branch),1),e.gitInfo.ahead>0||e.gitInfo.behind>0?(v(),E("span",zJe,[U(f(gn),{text:f(n)("diff.aheadTitle")},{default:de(()=>[e.gitInfo.ahead>0?(v(),E("span",OJe,"↑"+D(e.gitInfo.ahead),1)):X("",!0)]),_:1},8,["text"]),U(f(gn),{text:f(n)("diff.behindTitle")},{default:de(()=>[e.gitInfo.behind>0?(v(),E("span",PJe,"↓"+D(e.gitInfo.behind),1)):X("",!0)]),_:1},8,["text"])])):X("",!0)],64)):(v(),E("span",jJe,D(f(n)("diff.empty")),1))]),d.value&&b.value==="list"?(v(),ce(f(cx),{key:0,class:"ch-list"},{default:de(()=>[C("div",HJe,[(v(!0),E(Ee,null,pt(e.changes,O=>(v(),ce(f(gn),{key:O.path,text:O.path},{default:de(()=>[C("button",{type:"button",class:"ch-row",onClick:R=>k(O.path)},[C("span",{class:Fe(["badge",r(O.status)])},D(a(O.status)),3),C("span",qJe,D(u(O.path)),1)],8,WJe)]),_:2},1032,["text"]))),128))])]),_:1})):d.value&&b.value==="tree"?(v(),ce(f(cx),{key:1,class:"ch-list ch-tree"},{default:de(()=>[U(pF,{name:"tree-collapse",tag:"ul",class:"tree-list ch-list-content"},{default:de(()=>[(v(!0),E(Ee,null,pt(L.value,({node:O,depth:R})=>(v(),E("li",{key:O.path,class:"tree-node"},[O.kind==="folder"?(v(),E("button",{key:0,type:"button",class:"tree-row tree-folder",style:Kt(I(R)),onClick:j=>M(O)},[U(f(ve),{class:"tree-icon",name:"folder-solid",size:"sm"}),C("span",KJe,D(O.name),1)],12,UJe)):(v(),ce(f(gn),{key:1,text:O.path},{default:de(()=>[C("button",{type:"button",class:"tree-row tree-file",style:Kt(I(R)),onClick:j=>k(O.path)},[C("span",{class:Fe(["badge",r(O.status)])},D(a(O.status)),3),C("span",ZJe,D(O.name),1)],12,VJe)]),_:2},1032,["text"]))]))),128))]),_:1})]),_:1})):c.value?(v(),E("div",GJe,[C("span",QJe,[U(f(ve),{name:"check",size:"lg"})]),$e(" "+D(f(n)("diff.clean")),1)])):(v(),E("div",YJe,D(f(n)("diff.empty")),1))],64))]))}}),XJe=kt(JJe,[["__scopeId","data-v-7d5ab9c7"]]),eXe={class:"td"},tXe={class:"td-path"},nXe={class:"td-body"},iXe={key:1,class:"td-empty"},oXe=Xe({__name:"TurnDiffPanel",props:{change:{},cwd:{},closable:{type:Boolean}},emits:["close","openFile"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=F(()=>{const a=n.cwd?d9(n.change.path,n.cwd):null;return r(a??n.change.path)});function r(a,u=48){return!a||a.length<=u?a:"…"+a.slice(a.length-u+1)}const l=F(()=>n.change.diff!==null&&n.change.diff.length>0);return(a,u)=>(v(),E("div",eXe,[U(f(rf),{title:f(o)("conversation.turnFiles.diffTitle"),closable:e.closable,"close-label":f(o)("filePreview.close"),onClose:u[1]||(u[1]=c=>i("close"))},{default:de(()=>[U(f(gn),{text:e.change.path},{default:de(()=>[C("span",tXe,D(s.value),1)]),_:1},8,["text"]),U(f(Jt),{size:"sm",label:f(o)("conversation.turnFiles.openFile"),tooltip:f(o)("conversation.turnFiles.openFile"),onClick:u[0]||(u[0]=c=>i("openFile",e.change.path))},{default:de(()=>[U(f(ve),{name:"external-link",size:"md"})]),_:1},8,["label","tooltip"])]),_:1},8,["title","closable","close-label"]),C("div",nXe,[l.value?(v(),ce(oa,{key:0,lines:e.change.diff,path:e.change.path,framed:!1},null,8,["lines","path"])):(v(),E("div",iXe,[C("p",null,D(f(o)("conversation.turnFiles.diffUnavailable")),1),U(f(Qt),{variant:"ghost",size:"sm",onClick:u[2]||(u[2]=c=>i("openFile",e.change.path))},{default:de(()=>[$e(D(f(o)("conversation.turnFiles.openFile")),1)]),_:1})]))])]))}}),sXe=kt(oXe,[["__scopeId","data-v-fdd0bc05"]]);function NH(e,t){let n=null;cn(()=>{n=typeof document<"u"&&document.activeElement instanceof HTMLElement?document.activeElement:null,dt(()=>{const i=t?.value??e.value;try{i?.focus()}catch{}})}),Hn(()=>{const i=n;if(n=null,!(!i||typeof document>"u"||!document.contains(i)))try{i.focus()}catch{}})}const rXe={class:"search-wrap"},lXe=["aria-label"],aXe=["aria-label"],uXe=["aria-pressed","onClick"],cXe={key:1,class:"state-row"},dXe={key:2,class:"state-row unavail"},fXe=["aria-label"],hXe=["aria-selected","onClick","onMouseenter"],pXe={class:"model-main"},gXe={class:"model-name"},mXe={class:"model-meta"},vXe={class:"model-side"},yXe={key:0,class:"empty"},kXe={class:"footer-hint","aria-hidden":"true"},bXe=Xe({__name:"ModelPicker",props:{models:{},current:{},starredIds:{},loading:{type:Boolean},unavailable:{type:Boolean}},emits:["select","toggle-star","close"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=F(()=>new Set(i.starredIds??[]));function r(O){return s.value.has(O)}const l=K(""),a=K(null),u=K(null),c=K(null),d=K("all"),h={image_in:"model.capabilityImageInput",video_in:"model.capabilityVideoInput",tool_use:"model.capabilityToolUse",thinking:"model.capabilityThinking",always_thinking:"model.capabilityAlwaysThinking"};function p(O){const R=h[O];return R?n(R):O.replaceAll("_"," ")}function g(O){const R=[O.provider,n("model.contextSuffix",{size:_u(O.maxContextSize)})];for(const j of O.capabilities??[])R.push(p(j));return R.join(" · ")}const m=typeof window<"u"&&window.matchMedia("(hover: none)").matches;NH(u,m?void 0:a);const k=rg(),w=F(()=>k.value?qh:Pc),y=F(()=>k.value?{modelValue:!0,title:n("model.title"),closeOnEsc:!1}:{open:!0,closeOnEsc:!1,title:n("model.title"),size:"lg",height:"fixed",padded:!1,focusOnOpen:!m}),b=F(()=>{const O=new Set,R=[{id:"all",label:n("model.allTab")}];for(const j of i.models)O.has(j.provider)||(O.add(j.provider),R.push({id:j.provider,label:j.provider}));return R}),A=F(()=>{const O=l.value.toLowerCase().trim(),R=i.models.filter(j=>{if(d.value!=="all"&&j.provider!==d.value)return!1;const $=(j.displayName??j.model).toLowerCase().includes(O),W=j.provider.toLowerCase().includes(O),P=j.id.toLowerCase().includes(O);return!O||$||W||P});return d.value!=="all"?R:R.sort((j,$)=>{const W=r(j.id)?1:0;return(r($.id)?1:0)-W})}),T=F(()=>A.value),S=K(0);Pe([l,d],()=>{S.value=0}),Pe(b,O=>{O.some(R=>R.id===d.value)||(d.value="all")}),Pe(T,O=>{S.value=Math.min(S.value,Math.max(O.length-1,0))}),Pe(S,async()=>{await dt(),c.value?.querySelector(".model-row.is-selected")?.scrollIntoView({block:"nearest"})});const{handleCompositionStart:x,handleCompositionEnd:_,isComposingKeyEvent:L}=bl();function M(O){if(!L(O)){if(O.key==="Escape"){o("close");return}if(O.key==="ArrowDown")O.preventDefault(),S.value=Math.min(S.value+1,T.value.length-1);else if(O.key==="ArrowUp")O.preventDefault(),S.value=Math.max(S.value-1,0);else if(O.key==="Enter"){const R=T.value[S.value];R&&o("select",R.id)}}}cn(()=>{document.addEventListener("keydown",M)}),_n(()=>{document.removeEventListener("keydown",M)});function N(O){o("select",O)}function I(){l.value="",a.value?.focus()}function z(O){return T.value.indexOf(O)}function H(O){d.value=O}return(O,R)=>(v(),ce(Oo(w.value),ni(y.value,{onClose:R[1]||(R[1]=j=>o("close"))}),{default:de(()=>[C("div",{ref_key:"dialogRef",ref:u,class:Fe(["mp",{"mp--sheet":f(k)}])},[C("div",rXe,[U(f(Ns),{ref_key:"searchRef",ref:a,modelValue:l.value,"onUpdate:modelValue":R[0]||(R[0]=j=>l.value=j),placeholder:f(n)("model.searchPlaceholder"),autocomplete:"off",spellcheck:"false",autofocus:!f(m),onCompositionstart:f(x),onCompositionend:f(_)},null,8,["modelValue","placeholder","autofocus","onCompositionstart","onCompositionend"]),U(f(gn),{text:f(n)("model.clearSearch")},{default:de(()=>[C("button",{type:"button",class:Fe(["search-clear",{"is-on":l.value.length>0}]),tabindex:"-1","aria-label":f(n)("model.clearSearch"),onClick:I},[U(f(ve),{name:"close",size:"sm"})],10,lXe)]),_:1},8,["text"])]),b.value.length>1?(v(),E("div",{key:0,class:"chip-strip","aria-label":f(n)("model.providerTabs")},[(v(!0),E(Ee,null,pt(b.value,j=>(v(),E("button",{key:j.id,type:"button",class:Fe(["chip",{"is-active":j.id===d.value}]),"aria-pressed":j.id===d.value,onClick:$=>H(j.id)},D(j.label),11,uXe))),128))],8,aXe)):X("",!0),e.loading?(v(),E("div",cXe,[U(f(Oi),{size:"sm"}),C("span",null,D(f(n)("model.loading")),1)])):e.unavailable?(v(),E("div",dXe,[U(f(ve),{name:"alert-triangle",size:"lg"}),C("span",null,D(f(n)("model.unavailable")),1)])):(v(),E("div",{key:3,ref_key:"listRef",ref:c,class:"model-list",role:"listbox","aria-label":f(n)("model.title")},[(v(!0),E(Ee,null,pt(T.value,j=>(v(),E("div",{key:j.id,class:Fe(["model-row",{"is-current":j.id===e.current,"is-selected":z(j)===S.value}]),role:"option","aria-selected":j.id===e.current,onClick:$=>N(j.id),onMouseenter:$=>S.value=z(j)},[C("span",pXe,[C("span",gXe,D(j.displayName??j.model),1),C("span",mXe,D(g(j)),1)]),C("span",vXe,[j.id===e.current?(v(),ce(f(ve),{key:0,class:"model-check",name:"check",size:"sm"})):X("",!0),U(f(Jt),{class:Fe(["model-star",{"is-starred":r(j.id)}]),size:"sm",label:r(j.id)?f(n)("model.unstarTitle"):f(n)("model.starTitle"),tooltip:r(j.id)?f(n)("model.unstarTitle"):f(n)("model.starTitle"),onClick:wt($=>o("toggle-star",j.id),["stop"])},{default:de(()=>[r(j.id)?(v(),ce(f(ve),{key:0,name:"star",size:"md"})):(v(),ce(f(ve),{key:1,name:"star-outline",size:"md"}))]),_:2},1032,["class","label","tooltip","onClick"])])],42,hXe))),128)),T.value.length===0?(v(),E("div",yXe,D(i.models.length===0?f(n)("model.emptyNoModels"):f(n)("model.emptyNoMatch")),1)):X("",!0)],8,fXe)),C("div",kXe,[U(f(ku),{keys:["↑","↓"]}),C("span",null,D(f(n)("model.hintNavigate")),1),R[2]||(R[2]=C("span",{class:"hint-dot"},"·",-1)),U(f(ku),{keys:["Enter"]}),C("span",null,D(f(n)("model.hintSelect")),1),R[3]||(R[3]=C("span",{class:"hint-dot"},"·",-1)),U(f(ku),{keys:["Esc"]}),C("span",null,D(f(n)("model.hintClose")),1)])],2)]),_:1},16))}}),AXe=kt(bXe,[["__scopeId","data-v-87452cd9"]]),CXe=["mask"],wXe=Xe({__name:"BrandLogo",props:{size:{default:64}},setup(e){const t=`bl-eyes-${Fq()}`,n=K(null);let i;function o(){const s=n.value;s&&(s.classList.remove("blink-now"),s.getBoundingClientRect(),s.classList.add("blink-now"),clearTimeout(i),i=setTimeout(()=>s.classList.remove("blink-now"),300))}return Hn(()=>clearTimeout(i)),(s,r)=>(v(),E("svg",{ref_key:"logoRef",ref:n,class:"brand-logo",style:Kt({width:`${e.size}px`,height:`${e.size*22/32}px`}),viewBox:"0 0 32 22",fill:"none",xmlns:"http://www.w3.org/2000/svg",role:"img","aria-label":"Kimi Code",onClick:o},[C("defs",null,[C("mask",{id:t,maskUnits:"userSpaceOnUse"},[...r[0]||(r[0]=[C("rect",{x:"0",y:"0",width:"32",height:"22",fill:"#fff"},null,-1),C("g",{class:"ch-eyes",fill:"#000"},[C("rect",{class:"ch-eye",x:"11.8",y:"7",width:"2.8",height:"8",rx:"1.4"}),C("rect",{class:"ch-eye",x:"17.4",y:"7",width:"2.8",height:"8",rx:"1.4"})],-1)])])]),C("rect",{x:"1",y:"1",width:"30",height:"20",rx:"6",fill:"var(--logo)",mask:`url(#${t})`},null,8,CXe)],4))}}),n1=kt(wXe,[["__scopeId","data-v-f04205a8"]]),xXe={key:0,class:"nb-cards"},SXe={key:1,class:"center-body"},_Xe={class:"center-text"},MXe={key:2,class:"nb"},IXe={class:"nb-hero"},EXe={class:"nb-hero-icon"},TXe={key:0,class:"nb-hero-title"},LXe={class:"nb-hero-hint"},NXe={class:"nb-manual"},FXe={class:"nb-manual-label"},DXe={key:3,class:"center-body"},BXe={class:"center-text success-text"},$Xe={class:"center-hint"},RXe={class:"center-body"},zXe={class:"center-text err-text"},OXe={class:"center-hint"},PXe={class:"actions"},jXe={class:"center-body"},HXe={class:"center-text warn-text"},WXe={class:"center-hint"},qXe={class:"actions"},UXe=Xe({__name:"LoginDialog",props:{onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function},onGetOAuthRegion:{type:Function}},emits:["success","close"],setup(e,{emit:t}){const{t:n}=zt(),i=K(!0),o=t,s=e,{step:r,pollError:l,flow:a,secondsLeft:u,autoOpenBlocked:c,startFlow:d,cancelFlow:h}=_$({onStartOAuthLogin:s.onStartOAuthLogin,onPollOAuthLogin:s.onPollOAuthLogin,onCancelOAuthLogin:s.onCancelOAuthLogin,onSuccess:()=>{o("success"),o("close")},autoOpen:bH(),authWake:AH()}),p=K(!1),g=K("choice"),m=[{region:"mainland-cn",titleKey:"login.regionCnTitle",hintKey:"login.regionCnHint"},{region:"global",titleKey:"login.regionOverseasTitle",hintKey:"login.regionOverseasHint"}],k={titleKey:"login.oauthTitle",hintKey:"login.oauthHint"},w=K("pending"),y=F(()=>LB(w.value,m,k)),b=F(()=>a.value?.verificationUriComplete??"");cn(()=>{s.onGetOAuthRegion?.().then(L=>{w.value=L===null?"unsupported":"supported"})});function A(L){g.value="flow",d(L)}async function T(){!a.value||!await Xo(b.value)||(p.value=!0,setTimeout(()=>{p.value=!1},2e3))}function S(){MA(b.value)&&window.open(b.value,"_blank","noopener,noreferrer")}async function x(){h(),o("close")}function _(L){const M=Math.floor(L/60),N=L%60;return`${M}:${String(N).padStart(2,"0")}`}return(L,M)=>(v(),ce(f(Pc),{open:i.value,"onUpdate:open":M[2]||(M[2]=N=>i.value=N),size:g.value==="choice"?"md":"sm",title:f(n)("login.title"),"close-on-overlay":!1,onClose:x},{default:de(()=>[g.value==="choice"?(v(),E("div",xXe,[(v(!0),E(Ee,null,pt(y.value,N=>(v(),ce(f(cb),{key:N.region??"oauth",disabled:N.disabled,onSelect:I=>A(N.region)},{leading:de(()=>[U(n1,{size:40})]),hint:de(()=>[$e(D(f(n)(N.hintKey)),1)]),default:de(()=>[$e(" "+D(f(n)(N.titleKey))+" ",1)]),_:2},1032,["disabled","onSelect"]))),128))])):f(r)==="starting"?(v(),E("div",SXe,[U(f(Oi),{size:"md"}),C("span",_Xe,D(f(n)("login.starting")),1)])):f(r)==="device-code"&&f(a)?(v(),E("div",MXe,[C("div",IXe,[C("span",EXe,[U(n1,{size:48})]),f(c)?(v(),E("div",TXe,D(f(n)("login.blockedTitle")),1)):X("",!0),C("div",LXe,D(f(c)?f(n)("login.blockedHint"):f(n)("login.openedHint",{time:_(f(u))})),1)]),f(c)?(v(),ce(f(Qt),{key:0,variant:"primary",onClick:S},{default:de(()=>[$e(D(f(n)("login.authorizeInBrowser"))+" ",1),U(f(ve),{name:"external-link",size:"sm"})]),_:1})):X("",!0),C("div",NXe,[C("span",FXe,[$e(D(f(n)("login.notOpened"))+" ",1),U(f(Qt),{variant:"text",class:Fe(["nb-copy-text",{"is-copied":p.value}]),onClick:T},{default:de(()=>[$e(D(p.value?f(n)("login.copied"):f(n)("login.copyLink")),1)]),_:1},8,["class"])])])])):f(r)==="success"?(v(),E("div",DXe,[U(f(Eh),{kind:"success"}),C("span",BXe,D(f(n)("login.success")),1),C("span",$Xe,D(f(n)("login.successHint")),1)])):f(r)==="expired"?(v(),E(Ee,{key:4},[C("div",RXe,[U(f(Eh),{kind:"expired"}),C("span",zXe,D(f(n)("login.expiredTitle")),1),C("span",OXe,D(f(n)("login.expiredHint")),1)]),C("div",PXe,[U(f(Qt),{variant:"primary",onClick:M[0]||(M[0]=N=>f(d)())},{default:de(()=>[$e(D(f(n)("login.retry")),1)]),_:1}),U(f(Qt),{variant:"secondary",onClick:x},{default:de(()=>[$e(D(f(n)("login.closeBtn")),1)]),_:1})])],64)):f(r)==="error"?(v(),E(Ee,{key:5},[C("div",jXe,[U(f(Eh),{kind:"error"}),C("span",HXe,D(f(l)?f(n)("login.pollErrorTitle"):f(n)("login.errorTitle")),1),C("span",WXe,D(f(l)?f(n)("login.pollErrorHint"):f(n)("login.errorHint")),1)]),C("div",qXe,[U(f(Qt),{variant:"primary",onClick:M[1]||(M[1]=N=>f(d)())},{default:de(()=>[$e(D(f(n)("login.retry")),1)]),_:1}),U(f(Qt),{variant:"secondary",onClick:x},{default:de(()=>[$e(D(f(n)("login.closeBtn")),1)]),_:1})])],64)):X("",!0)]),_:1},8,["open","size","title"]))}}),KXe=kt(UXe,[["__scopeId","data-v-99a1a98a"]]),FH=Xe({__name:"LanguageSwitcher",props:{size:{default:"md"}},setup(e){const{locale:t}=zt(),n=H2.map(o=>({value:o.code,label:o.label}));function i(o){t.value!==o&&n7(o)}return(o,s)=>(v(),ce(f(Vs),{"model-value":f(t),options:f(n),size:e.size,"onUpdate:modelValue":i},null,8,["model-value","options","size"]))}}),VXe={class:"msg"},ZXe={class:"pf-field"},GXe={class:"pf-field-label"},QXe={class:"pf-field"},YXe={class:"pf-field-label"},JXe={class:"pf-field"},XXe={class:"pf-field-label"},eet={class:"pf-key-wrap"},tet={class:"pf-field"},net={class:"pf-field-label"},iet={class:"pf-field"},oet={class:"pf-field-label"},set={class:"pf-models"},ret={key:0,class:"pf-models-empty"},aet={class:"pf-model-grid pf-model-head"},uet={key:1},cet={key:0},det={class:"pf-foot"},fet={key:0,class:"pf-managed-note"},het={class:"pf-confirm-msg"},pet=Xe({__name:"ProviderForm",props:{mode:{},provider:{},guard:{type:Boolean}},emits:["dirtyChange","guardStay","guardDiscard","added","saved","deleting","deleted","cancel"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=pa(),r=jo({id:"",type:"openai",apiKey:"",baseUrl:"",models:[_m()]}),l=K(""),a=K(!1),u=K(!1),c=K(!1),d=F(()=>n.mode==="add"),h=F(()=>n.provider!==void 0&&OB(n.provider)),p=F(()=>{const z=n.provider;return z===void 0?0:Wb(z,s.config.value?.models).length}),g=F(()=>h.value&&p.value===0),m=F(()=>Fle.map(z=>({value:z,label:o(`providers.types.${z}`)}))),k=F(()=>h.value?o("providers.apiKeyManaged"):!d.value&&n.provider?.hasApiKey===!0?o("providers.apiKeySet"):"sk-…");function w(){l.value="",u.value=!1;const z=n.provider;if(d.value||z===void 0){r.id="",r.type="openai",r.apiKey="",r.baseUrl="",r.models=[_m()];return}r.id=z.id,r.type=z.type,r.apiKey="",r.baseUrl=z.baseUrl??"";const H=Wb(z,s.config.value?.models);r.models=H.length>0?H:[_m()]}cn(()=>{w(),A()});const y=K(!1),b=K(!1);async function A(){const z=n.provider;if(!(d.value||z===void 0||h.value||z.hasApiKey!==!0))try{const H=await s.getProvider(z.id);if(b.value)return;H.apiKey!==void 0&&H.apiKey!==""&&(r.apiKey=H.apiKey,y.value=!0)}catch{}}function T(){i("dirtyChange",!0)}const S=K(!1),x=K();function _(z){l.value=z,dt(()=>x.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}async function L(){if(a.value)return;const z=Dle(r,{requireApiKey:d.value,requireBaseUrl:d.value});if(z!==null){_(o(`providers.error.${z}`));return}l.value="",a.value=!0;try{if(d.value){const H=await s.addProvider(Ble(r));if(H!==null){_(H);return}i("dirtyChange",!1),s.notify({severity:"success",title:o("providers.added")}),i("added",r.id.trim())}else{const H=n.provider;if(H===void 0)return;const O=s.config.value?.providers?.[H.id]?.defaultModel,R=await s.updateProvider(H.id,$le(r,H,{includeBlankApiKey:y.value,existingDefaultModel:O}));if(R!==null){_(R);return}await s.checkAuth(),s.notify({severity:"success",title:o("providers.saved")}),i("dirtyChange",!1),i("saved",r.id.trim())}}finally{a.value=!1}}async function M(){const z=n.provider;if(!(z===void 0||c.value)){c.value=!0,i("deleting"),await new Promise(H=>setTimeout(H,300));try{if(await s.deleteProvider(z.id)===null){u.value=!1;return}i("dirtyChange",!1),i("deleted",z.id)}finally{c.value=!1}}}function N(){r.models.push(_m()),T()}function I(z){r.models.length<=1||(r.models.splice(z,1),T())}return(z,H)=>(v(),E("div",{class:"pf-form",onInput:T},[e.guard?(v(),ce(f(Ed),{key:0,variant:"warning",class:"pf-guard"},{default:de(()=>[C("span",VXe,D(f(o)("providers.unsavedGuard")),1),U(f(Qt),{variant:"secondary",size:"sm",onClick:H[0]||(H[0]=O=>i("guardStay"))},{default:de(()=>[$e(D(f(o)("providers.guardStay")),1)]),_:1}),U(f(Qt),{variant:"danger",size:"sm",onClick:H[1]||(H[1]=O=>i("guardDiscard"))},{default:de(()=>[$e(D(f(o)("providers.guardDiscard")),1)]),_:1})]),_:1})):X("",!0),l.value?(v(),E("div",{key:1,ref_key:"errorBox",ref:x},[U(f(Ed),{variant:"danger"},{default:de(()=>[$e(D(l.value),1)]),_:1})],512)):X("",!0),C("div",ZXe,[C("label",GXe,[$e(D(f(o)("providers.fieldId")),1),H[11]||(H[11]=C("span",{class:"req"}," *",-1))]),U(f(Ns),{modelValue:r.id,"onUpdate:modelValue":H[2]||(H[2]=O=>r.id=O),placeholder:"my-openai",disabled:h.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","disabled"])]),C("div",QXe,[C("label",YXe,[$e(D(f(o)("providers.fieldType")),1),H[12]||(H[12]=C("span",{class:"req"}," *",-1))]),U(f(wb),{"model-value":r.type,options:m.value,disabled:h.value,"onUpdate:modelValue":H[3]||(H[3]=O=>{r.type=O,T()})},null,8,["model-value","options","disabled"])]),C("div",JXe,[C("label",XXe,[$e(D(f(o)("providers.fieldApiKey")),1),H[13]||(H[13]=C("span",{class:"req"}," *",-1))]),C("div",eet,[U(f(Ns),{modelValue:r.apiKey,"onUpdate:modelValue":H[4]||(H[4]=O=>r.apiKey=O),type:S.value?"text":"password",placeholder:k.value,disabled:h.value,autocomplete:"off",spellcheck:"false",onInput:H[5]||(H[5]=O=>b.value=!0)},null,8,["modelValue","type","placeholder","disabled"]),h.value?X("",!0):(v(),ce(f(Jt),{key:0,class:"pf-key-eye",size:"sm",label:f(o)(S.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:f(o)(S.value?"providers.hideApiKey":"providers.showApiKey"),onClick:H[6]||(H[6]=O=>S.value=!S.value)},{default:de(()=>[U(f(ve),{name:S.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"]))])]),C("div",tet,[C("label",net,[$e(D(f(o)("providers.fieldBaseUrl")),1),H[14]||(H[14]=C("span",{class:"req"}," *",-1))]),U(f(Ns),{modelValue:r.baseUrl,"onUpdate:modelValue":H[7]||(H[7]=O=>r.baseUrl=O),placeholder:f(o)("providers.baseUrlPlaceholder"),disabled:h.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder","disabled"])]),C("div",iet,[C("label",oet,[$e(D(f(o)("providers.fieldModels")),1),H[15]||(H[15]=C("span",{class:"req"}," *",-1))]),C("div",set,[g.value?(v(),E("div",ret,D(f(o)("providers.noModels")),1)):(v(),E(Ee,{key:1},[C("div",aet,[C("span",null,[$e(D(f(o)("providers.colModelId")),1),H[16]||(H[16]=C("span",{class:"req"}," *",-1))]),C("span",null,[$e(D(f(o)("providers.colContext")),1),H[17]||(H[17]=C("span",{class:"req"}," *",-1))]),C("span",null,D(f(o)("providers.colDisplayName")),1),H[18]||(H[18]=C("span",null,null,-1))]),(v(!0),E(Ee,null,pt(r.models,(O,R)=>(v(),E("div",{key:R,class:"pf-model-grid"},[U(f(Ns),{modelValue:O.model,"onUpdate:modelValue":j=>O.model=j,placeholder:f(o)("providers.modelIdPlaceholder"),disabled:h.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),U(f(Ns),{modelValue:O.maxContextSize,"onUpdate:modelValue":j=>O.maxContextSize=j,inputmode:"numeric",placeholder:f(o)("providers.modelContextPlaceholder"),disabled:h.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),U(f(Ns),{modelValue:O.displayName,"onUpdate:modelValue":j=>O.displayName=j,placeholder:f(o)("providers.modelNamePlaceholder"),disabled:h.value,autocomplete:"off",spellcheck:"false"},null,8,["modelValue","onUpdate:modelValue","placeholder","disabled"]),h.value?(v(),E("span",uet)):(v(),ce(f(Jt),{key:0,size:"sm",label:f(o)("providers.removeModel"),tooltip:f(o)("providers.removeModel"),disabled:r.models.length<=1,onClick:j=>I(R)},{default:de(()=>[U(f(ve),{name:"trash",size:"sm"})]),_:1},8,["label","tooltip","disabled","onClick"]))]))),128)),h.value?X("",!0):(v(),E("div",cet,[U(f(Qt),{variant:"ghost",size:"sm",onClick:N},{default:de(()=>[U(f(ve),{name:"plus",size:"sm"}),$e(" "+D(f(o)("providers.addModel")),1)]),_:1})]))],64))])]),C("div",det,[h.value?(v(),E("span",fet,D(f(o)("providers.managedHint")),1)):d.value?(v(),E(Ee,{key:1},[U(f(Qt),{variant:"secondary",size:"sm",onClick:H[8]||(H[8]=O=>i("cancel"))},{default:de(()=>[$e(D(f(o)("common.cancel")),1)]),_:1}),U(f(Qt),{variant:"primary",size:"sm",disabled:a.value,onClick:L},{default:de(()=>[$e(D(f(o)("providers.addProvider")),1)]),_:1},8,["disabled"])],64)):u.value&&n.provider!==void 0?(v(),E(Ee,{key:2},[C("span",het,D(f(o)("providers.deleteConfirm",{id:n.provider.id,count:p.value})),1),H[19]||(H[19]=C("span",{class:"spacer"},null,-1)),U(f(Qt),{variant:"secondary",size:"sm",disabled:c.value,onClick:H[9]||(H[9]=O=>u.value=!1)},{default:de(()=>[$e(D(f(o)("common.cancel")),1)]),_:1},8,["disabled"]),U(f(Qt),{variant:"danger",size:"sm",disabled:c.value,onClick:M},{default:de(()=>[$e(D(f(o)("providers.deleteConfirmYes")),1)]),_:1},8,["disabled"])],64)):(v(),E(Ee,{key:3},[U(f(Qt),{variant:"danger-soft",size:"sm",onClick:H[10]||(H[10]=O=>u.value=!0)},{default:de(()=>[$e(D(f(o)("providers.deleteProvider")),1)]),_:1}),H[20]||(H[20]=C("span",{class:"spacer"},null,-1)),U(f(Qt),{variant:"primary",size:"sm",disabled:a.value,onClick:L},{default:de(()=>[$e(D(f(o)("providers.save")),1)]),_:1},8,["disabled"])],64))])],32))}}),DH=kt(pet,[["__scopeId","data-v-3164ed08"]]),get={class:"af"},met={class:"msg"},vet={key:2,class:"af-catalog"},yet={key:0,class:"af-center"},ket={key:1,class:"af-error"},bet={class:"af-list"},Aet=["disabled","onClick"],Cet={class:"af-entry-name"},wet={key:1,class:"af-entry-reason"},xet={key:2,class:"af-entry-count"},_et={key:0,class:"af-empty"},Met={class:"af-field"},Iet={class:"af-label"},Eet={class:"af-field"},Tet={class:"af-label"},Let={class:"af-key-wrap"},Net={key:0,class:"af-field"},Fet={class:"af-label"},Det={class:"af-note"},Bet={class:"af-foot"},$et={class:"af-hint"},Ret={class:"af-field"},zet={class:"af-label"},Oet={class:"af-field"},Pet={class:"af-label"},jet={class:"af-key-wrap"},Het={class:"af-foot"},Wet={class:"af-manual"},qet=Xe({__name:"AddProviderFlow",props:{guard:{type:Boolean}},emits:["dirtyChange","guardStay","guardDiscard","added","cancel"],setup(e,{emit:t}){const n=t,{t:i,te:o}=zt(),s=pa(),r=K("catalog"),l=F(()=>[{value:"catalog",label:i("providers.catalog.sourceCatalog")},{value:"registry",label:i("providers.catalog.sourceRegistry")},{value:"manual",label:i("providers.catalog.sourceManual")}]),a=K("loading"),u=K([]);async function c(){a.value="loading";const $=await s.loadCatalogProviders();$.kind==="ok"?(u.value=$.items,a.value="ready"):$.kind==="unsupported"?(a.value="unsupported",r.value==="catalog"&&(r.value="manual")):a.value="error"}cn(c);const d=K(""),h=F(()=>{const $=d.value.trim().toLowerCase();return $===""?u.value:u.value.filter(W=>W.name.toLowerCase().includes($)||W.id.toLowerCase().includes($))});function p($){const W=$.rejectReason;return W!==null&&o(`providers.catalog.rejectReason.${W}`)?i(`providers.catalog.rejectReason.${W}`):i("providers.catalog.rejected")}const g=K(null),m=K({id:"",apiKey:"",baseUrl:""}),k=K(!1),w=K(!1),y=K("");function b($){g.value=$,m.value={id:$.id,apiKey:"",baseUrl:""},y.value="",k.value=!1}function A(){g.value=null,y.value="",n("dirtyChange",!1)}function T(){n("dirtyChange",!0)}const S=F(()=>{if(g.value===null)return!1;const W=m.value.id.trim();return W!==""&&s.providers.value.some(P=>P.id===W)}),x=K();function _($){y.value=$,dt(()=>x.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}function L(){const $=m.value,W=$.id.trim();return W===""?i("providers.error.idRequired"):RB.test(W)?$.apiKey.trim()===""?i("providers.error.apiKeyRequired"):g.value?.needsBaseUrl===!0&&$.baseUrl.trim()===""?i("providers.error.baseUrlRequired"):null:i("providers.error.idInvalid")}async function M(){const $=g.value;if($===null||w.value)return;const W=L();if(W!==null){_(W);return}y.value="",w.value=!0;try{const P=m.value,Z=P.id.trim(),ae=P.baseUrl.trim(),V=await s.importCatalogProvider({catalogId:$.id,apiKey:P.apiKey.trim(),...ae===""?{}:{baseUrl:ae},...Z===$.id?{}:{id:Z}});if(V!==null){_(V);return}s.notify({severity:"success",title:i("providers.added")}),n("dirtyChange",!1),n("added",Z)}finally{w.value=!1}}const N=K({url:"",apiKey:""}),I=K(!1),z=K(!1),H=K(""),O=K();function R($){H.value=$,dt(()=>O.value?.scrollIntoView({block:"nearest",behavior:"smooth"}))}async function j(){if(z.value)return;const $=N.value.url.trim();if($===""){R(i("providers.error.registryUrlRequired"));return}H.value="",z.value=!0;try{const W=N.value.apiKey.trim(),P=await s.importCustomRegistry({url:$,...W===""?{}:{apiKey:W}});if(typeof P=="string"){R(P);return}s.notify({severity:"success",title:i("providers.catalog.registryImported",{count:P.providers.length})}),n("dirtyChange",!1);const Z=P.providers[0];Z!==void 0?n("added",Z.id):n("cancel")}finally{z.value=!1}}return($,W)=>(v(),E("div",get,[e.guard?(v(),ce(f(Ed),{key:0,variant:"warning",class:"af-guard"},{default:de(()=>[C("span",met,D(f(i)("providers.unsavedGuard")),1),U(f(Qt),{variant:"secondary",size:"sm",onClick:W[0]||(W[0]=P=>n("guardStay"))},{default:de(()=>[$e(D(f(i)("providers.guardStay")),1)]),_:1}),U(f(Qt),{variant:"danger",size:"sm",onClick:W[1]||(W[1]=P=>n("guardDiscard"))},{default:de(()=>[$e(D(f(i)("providers.guardDiscard")),1)]),_:1})]),_:1})):X("",!0),a.value!=="unsupported"?(v(),ce(f(Vs),{key:1,modelValue:r.value,"onUpdate:modelValue":W[2]||(W[2]=P=>r.value=P),size:"sm",options:l.value},null,8,["modelValue","options"])):X("",!0),a.value!=="unsupported"?Wn((v(),E("div",vet,[a.value==="loading"?(v(),E("div",yet,[U(f(Oi),{size:"sm"}),C("span",null,D(f(i)("providers.catalog.loading")),1)])):a.value==="error"?(v(),E("div",ket,[U(f(Ed),{variant:"danger"},{default:de(()=>[$e(D(f(i)("providers.catalog.loadError")),1)]),_:1}),C("div",null,[U(f(Qt),{variant:"secondary",size:"sm",onClick:c},{default:de(()=>[$e(D(f(i)("providers.catalog.retry")),1)]),_:1})])])):g.value===null?(v(),E(Ee,{key:2},[U(f(Ns),{modelValue:d.value,"onUpdate:modelValue":W[3]||(W[3]=P=>d.value=P),placeholder:f(i)("providers.catalog.searchPlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder"]),C("div",bet,[(v(!0),E(Ee,null,pt(h.value,P=>(v(),E("button",{key:P.id,type:"button",class:"af-entry",disabled:P.rejected,onClick:Z=>b(P)},[C("span",Cet,D(P.name),1),P.wireType!==null?(v(),ce(f(br),{key:0,variant:"neutral",size:"sm"},{default:de(()=>[$e(D(P.wireType),1)]),_:2},1024)):X("",!0),W[16]||(W[16]=C("span",{class:"grow"},null,-1)),P.rejected?(v(),E("span",wet,D(p(P)),1)):(v(),E("span",xet,D(f(i)("providers.modelCount",{count:P.models.length})),1))],8,Aet))),128)),h.value.length===0?(v(),E("div",_et,D(f(i)("providers.catalog.empty")),1)):X("",!0)])],64)):(v(),E("div",{key:3,class:"af-import",onInput:T},[C("button",{type:"button",class:"af-back",onClick:A},[U(f(ve),{name:"arrow-left",size:"sm"}),$e(" "+D(f(i)("providers.catalog.backToList")),1)]),C("div",Met,[C("label",Iet,[$e(D(f(i)("providers.fieldId")),1),W[17]||(W[17]=C("span",{class:"req"}," *",-1))]),U(f(Ns),{modelValue:m.value.id,"onUpdate:modelValue":W[4]||(W[4]=P=>m.value.id=P),autocomplete:"off",spellcheck:"false"},null,8,["modelValue"])]),C("div",Eet,[C("label",Tet,[$e(D(f(i)("providers.fieldApiKey")),1),W[18]||(W[18]=C("span",{class:"req"}," *",-1))]),C("div",Let,[U(f(Ns),{modelValue:m.value.apiKey,"onUpdate:modelValue":W[5]||(W[5]=P=>m.value.apiKey=P),type:k.value?"text":"password",placeholder:"sk-…",autocomplete:"off",spellcheck:"false"},null,8,["modelValue","type"]),U(f(Jt),{class:"af-key-eye",size:"sm",label:f(i)(k.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:f(i)(k.value?"providers.hideApiKey":"providers.showApiKey"),onClick:W[6]||(W[6]=P=>k.value=!k.value)},{default:de(()=>[U(f(ve),{name:k.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])])]),g.value.needsBaseUrl?(v(),E("div",Net,[C("label",Fet,[$e(D(f(i)("providers.fieldBaseUrl")),1),W[19]||(W[19]=C("span",{class:"req"}," *",-1))]),U(f(Ns),{modelValue:m.value.baseUrl,"onUpdate:modelValue":W[7]||(W[7]=P=>m.value.baseUrl=P),placeholder:f(i)("providers.baseUrlPlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","placeholder"])])):X("",!0),S.value?(v(),ce(f(Ed),{key:1,variant:"warning"},{default:de(()=>[$e(D(f(i)("providers.catalog.overwriteWarning")),1)]),_:1})):X("",!0),C("div",Det,D(f(i)("providers.catalog.willImport",{count:g.value.models.length})),1),y.value?(v(),E("div",{key:2,ref_key:"importErrorBox",ref:x},[U(f(Ed),{variant:"danger"},{default:de(()=>[$e(D(y.value),1)]),_:1})],512)):X("",!0),C("div",Bet,[U(f(Qt),{variant:"secondary",size:"sm",onClick:W[8]||(W[8]=P=>n("cancel"))},{default:de(()=>[$e(D(f(i)("common.cancel")),1)]),_:1}),U(f(Qt),{variant:"primary",size:"sm",disabled:w.value,onClick:M},{default:de(()=>[$e(D(f(i)("providers.catalog.importAction")),1)]),_:1},8,["disabled"])])],32))],512)),[[Po,r.value==="catalog"]]):X("",!0),Wn(C("div",{class:"af-registry",onInput:T},[C("div",$et,D(f(i)("providers.catalog.registryHint")),1),C("div",Ret,[C("label",zet,[$e(D(f(i)("providers.catalog.registryUrlLabel")),1),W[20]||(W[20]=C("span",{class:"req"}," *",-1))]),U(f(Ns),{modelValue:N.value.url,"onUpdate:modelValue":W[9]||(W[9]=P=>N.value.url=P),placeholder:"https://example.com/api.json",autocomplete:"off",spellcheck:"false"},null,8,["modelValue"])]),C("div",Oet,[C("label",Pet,D(f(i)("providers.fieldApiKey")),1),C("div",jet,[U(f(Ns),{modelValue:N.value.apiKey,"onUpdate:modelValue":W[10]||(W[10]=P=>N.value.apiKey=P),type:I.value?"text":"password",placeholder:f(i)("providers.modelNamePlaceholder"),autocomplete:"off",spellcheck:"false"},null,8,["modelValue","type","placeholder"]),U(f(Jt),{class:"af-key-eye",size:"sm",label:f(i)(I.value?"providers.hideApiKey":"providers.showApiKey"),tooltip:f(i)(I.value?"providers.hideApiKey":"providers.showApiKey"),onClick:W[11]||(W[11]=P=>I.value=!I.value)},{default:de(()=>[U(f(ve),{name:I.value?"eye-off":"eye",size:"sm"},null,8,["name"])]),_:1},8,["label","tooltip"])])]),H.value?(v(),E("div",{key:0,ref_key:"registryErrorBox",ref:O},[U(f(Ed),{variant:"danger"},{default:de(()=>[$e(D(H.value),1)]),_:1})],512)):X("",!0),C("div",Het,[U(f(Qt),{variant:"secondary",size:"sm",onClick:W[12]||(W[12]=P=>n("cancel"))},{default:de(()=>[$e(D(f(i)("common.cancel")),1)]),_:1}),U(f(Qt),{variant:"primary",size:"sm",disabled:z.value,onClick:j},{default:de(()=>[$e(D(f(i)("providers.catalog.importAction")),1)]),_:1},8,["disabled"])])],544),[[Po,r.value==="registry"]]),Wn(C("div",Wet,[U(DH,{mode:"add",guard:!1,onDirtyChange:W[13]||(W[13]=P=>n("dirtyChange",P)),onAdded:W[14]||(W[14]=P=>n("added",P)),onCancel:W[15]||(W[15]=P=>n("cancel"))})],512),[[Po,r.value==="manual"]])]))}}),Uet=kt(qet,[["__scopeId","data-v-9777a945"]]),Ket={class:"pp"},Vet={class:"pp-head"},Zet={class:"pp-title"},Get={key:0,class:"pp-loading"},Qet={key:1,class:"pp-group"},Yet={class:"pp-add-label"},Jet={class:"pp-chev"},Xet={class:"pp-acc"},ett={class:"pp-acc-in"},ttt={key:1,class:"pp-empty"},ntt=["onClick"],itt={class:"grow"},ott={class:"pp-id"},stt={class:"pp-count"},rtt={class:"pp-chev"},ltt={class:"pp-acc"},att={class:"pp-acc-in"},wd="$add",utt=Xe({__name:"ProvidersPanel",setup(e){const{t}=zt(),n=pa(),i=K(!0),o=K(null),s=K(null);let r=0;const l=K(!1),a=K(!1),u=K(null),c=K("");let d=0;const h=F(()=>[...n.providers.value].sort((S,x)=>S.id.localeCompare(x.id)));function p(S){return Wb(S,n.config.value?.models).length}Pe(o,(S,x)=>{x!==null&&x!==S&&(s.value=x,window.clearTimeout(r),r=window.setTimeout(()=>{s.value=null},300)),l.value=!1}),Pe(l,S=>{S||(a.value=!1,u.value=null)}),_n(()=>{window.clearTimeout(r),window.clearTimeout(d)});const g=K(!1);Pe(o,S=>{S===wd?(g.value=!1,dt(()=>requestAnimationFrame(()=>{g.value=!0}))):g.value=!1}),cn(async()=>{i.value=!0;try{await Promise.all([n.loadProviders(),n.loadModels(),n.loadConfig()])}finally{i.value=!1}});function m(S){const x=o.value===S?null:S;if(l.value){u.value=x,a.value=!0;return}o.value=x}function k(){a.value=!1,u.value=null}function w(){a.value=!1,o.value=u.value,u.value=null}function y(S){c.value=S,window.clearTimeout(d),d=window.setTimeout(()=>{c.value=""},1200)}function b(S){o.value=S}function A(S){o.value=S,y(S)}function T(){o.value=null}return(S,x)=>(v(),E("section",Ket,[C("div",Vet,[C("h3",Zet,D(f(t)("settings.tabs.providers")),1),U(f(Qt),{variant:"secondary",size:"sm",onClick:x[0]||(x[0]=_=>m(wd))},{default:de(()=>[U(f(ve),{name:"plus",size:"sm"}),$e(" "+D(f(t)("providers.addProvider")),1)]),_:1})]),i.value?(v(),E("div",Get,[U(f(Oi),{size:"sm"}),C("span",null,D(f(t)("providers.loading")),1)])):(v(),E("div",Qet,[o.value===wd||s.value===wd?(v(),E("div",{key:0,class:Fe(["pp-item pp-add-item",{open:o.value===wd&&g.value}])},[C("button",{type:"button",class:"pp-row pp-add-row",onClick:x[1]||(x[1]=_=>m(wd))},[C("span",Yet,D(f(t)("providers.addProvider")),1),x[6]||(x[6]=C("span",{class:"grow"},null,-1)),C("span",Jet,[U(f(ve),{name:"chevron-right",size:"sm"})])]),C("div",Xet,[C("div",ett,[U(Uet,{guard:a.value&&o.value===wd,onDirtyChange:x[2]||(x[2]=_=>l.value=_),onGuardStay:k,onGuardDiscard:w,onAdded:A,onCancel:x[3]||(x[3]=_=>o.value=null)},null,8,["guard"])])])],2)):X("",!0),h.value.length===0?(v(),E("div",ttt,D(f(t)("providers.empty")),1)):X("",!0),(v(!0),E(Ee,null,pt(h.value,_=>(v(),E("div",{key:_.id,class:Fe(["pp-item",{open:o.value===_.id,flash:c.value===_.id}])},[C("button",{type:"button",class:"pp-row",onClick:L=>m(_.id)},[C("div",itt,[C("span",ott,D(_.id),1),U(f(br),{variant:"neutral",size:"sm"},{default:de(()=>[$e(D(_.type),1)]),_:2},1024),f(OB)(_)?(v(),ce(f(br),{key:0,variant:"info",size:"sm"},{default:de(()=>[$e(D(f(t)("providers.managedBadge")),1)]),_:1})):X("",!0)]),C("span",stt,D(f(t)("providers.modelCount",{count:p(_)})),1),C("span",rtt,[U(f(ve),{name:"chevron-right",size:"sm"})])],8,ntt),C("div",ltt,[C("div",att,[o.value===_.id||s.value===_.id?(v(),ce(DH,{key:0,mode:"edit",provider:_,guard:a.value&&o.value===_.id,onDirtyChange:x[4]||(x[4]=L=>l.value=L),onGuardStay:k,onGuardDiscard:w,onSaved:b,onDeleting:x[5]||(x[5]=L=>o.value=null),onDeleted:T},null,8,["provider","guard"])):X("",!0)])])],2))),128))]))]))}}),ctt=kt(utt,[["__scopeId","data-v-193300c3"]]),dtt={class:"sec"},ftt={class:"sec-title"},htt={class:"pu-group"},ptt={class:"pu-row"},gtt={class:"pu-main"},mtt={class:"pu-label"},vtt={class:"pu-hint"},ytt=Xe({__name:"PlanUpgradeCard",setup(e){const{t}=zt();return(n,i)=>(v(),E("section",dtt,[C("h3",ftt,D(f(t)("settings.planUsage.title")),1),C("div",htt,[C("div",ptt,[C("span",gtt,[C("span",mtt,D(f(t)("settings.planUsage.freeTitle")),1),C("span",vtt,D(f(t)("settings.planUsage.freeHint")),1)]),U(f(Qt),{variant:"primary",size:"sm",onClick:i[0]||(i[0]=o=>f(sg)())},{default:de(()=>[$e(D(f(t)("sidebar.upgrade")),1)]),_:1})])])]))}}),BH=kt(ytt,[["__scopeId","data-v-5711dff8"]]),ktt={class:"sec"},btt={class:"sec-title"},Att={class:"pu-group"},Ctt={key:0,class:"pu-row pu-state"},wtt={key:1,class:"pu-row pu-state"},xtt={class:"pu-error-text"},Stt={key:2,class:"pu-row pu-state pu-empty"},_tt={class:"pu-main"},Mtt={class:"pu-label"},Itt={key:0,class:"pu-hint"},Ett={class:"pu-value"},Ttt=["aria-valuenow","aria-valuemax"],Ltt={key:0,class:"sec"},Ntt={class:"sec-title"},Ftt={class:"pu-group"},Dtt={class:"pu-row"},Btt={class:"pu-main"},$tt={class:"pu-label"},Rtt={class:"pu-value"},ztt={key:0,class:"pu-value-sub"},Ott={key:0,class:"pu-meter"},Ptt={class:"pu-row"},jtt={class:"pu-main"},Htt={class:"pu-label"},Wtt={class:"pu-value"},qtt={class:"pu-row"},Utt={class:"pu-main"},Ktt={class:"pu-label"},Vtt={class:"pu-value"},Ztt={class:"pu-value-sub"},Gtt=Xe({__name:"PlanUsageCard",props:{onFetchUsage:{type:Function}},setup(e){const t=e,{t:n}=zt(),i=K(!0),o=K(null);async function s(){i.value=!0;try{o.value=await t.onFetchUsage()}finally{i.value=!1}}cn(s);const r=F(()=>o.value?.kind==="ok"?o.value:null),l=F(()=>r.value?.extraUsage??null),a=F(()=>{const m=r.value;return m===null?[]:m.summary===null?m.limits:[m.summary,...m.limits]}),u=F(()=>a.value.length>0),c=F(()=>o.value?.kind==="error"?o.value.message:n("settings.planUsage.loadFailed")),d=F(()=>o.value?.kind==="error"&&(o.value.status===402||o.value.status===403)),h=F(()=>l.value!==null&&l.value.monthlyChargeLimitEnabled&&l.value.monthlyChargeLimitCents>0);function p(m,k){const w=Nle(m,k);return`${w.symbol}${w.number}`}function g(m){return m.resetAt===void 0?"":$B(m.resetAt,n)}return(m,k)=>d.value?(v(),ce(BH,{key:0})):(v(),E(Ee,{key:1},[C("section",ktt,[C("h3",btt,D(f(n)("settings.planUsage.title")),1),C("div",Att,[i.value?(v(),E("div",Ctt,[U(f(Oi),{size:"sm"})])):r.value===null?(v(),E("div",wtt,[C("span",xtt,D(c.value),1),U(f(Qt),{variant:"ghost",size:"sm",onClick:s},{default:de(()=>[$e(D(f(n)("settings.planUsage.retry")),1)]),_:1})])):u.value?(v(!0),E(Ee,{key:3},pt(a.value,(w,y)=>(v(),E("div",{key:y,class:"pu-row"},[C("span",_tt,[C("span",Mtt,D(f(BB)(w,f(n))),1),g(w)?(v(),E("span",Itt,D(g(w)),1)):X("",!0)]),C("span",Ett,D(f(n)("settings.planUsage.usedPct",{pct:f(bv)(w.used,w.limit)})),1),C("span",{class:"pu-meter",role:"progressbar","aria-valuenow":w.used,"aria-valuemax":w.limit},[C("i",{class:Fe(`sev-${f(Hb)(w.used,w.limit)}`),style:Kt({width:`${f(bv)(w.used,w.limit)}%`})},null,6)],8,Ttt)]))),128)):(v(),E("div",Stt,D(f(n)("settings.planUsage.empty")),1))])]),l.value!==null?(v(),E("section",Ltt,[C("h3",Ntt,D(f(n)("settings.planUsage.boosterTitle")),1),C("div",Ftt,[C("div",Dtt,[C("span",Btt,[C("span",$tt,D(f(n)("settings.planUsage.monthlyUsed")),1)]),C("span",Rtt,[$e(D(p(l.value.monthlyUsedCents,l.value.currency)),1),h.value?(v(),E("span",ztt," / "+D(p(l.value.monthlyChargeLimitCents,l.value.currency)),1)):X("",!0)]),h.value?(v(),E("span",Ott,[C("i",{class:Fe(`sev-${f(Hb)(l.value.monthlyUsedCents,l.value.monthlyChargeLimitCents)}`),style:Kt({width:`${f(bv)(l.value.monthlyUsedCents,l.value.monthlyChargeLimitCents)}%`})},null,6)])):X("",!0)]),C("div",Ptt,[C("span",jtt,[C("span",Htt,D(f(n)("settings.planUsage.monthlyLimit")),1)]),C("span",Wtt,[h.value?(v(),E(Ee,{key:0},[$e(D(p(l.value.monthlyChargeLimitCents,l.value.currency)),1)],64)):(v(),E(Ee,{key:1},[$e(D(f(n)("settings.planUsage.unlimited")),1)],64))])]),C("div",qtt,[C("span",Utt,[C("span",Ktt,D(f(n)("settings.planUsage.boosterBalance")),1)]),C("span",Vtt,[$e(D(p(l.value.balanceCents,l.value.currency)),1),C("span",Ztt," / "+D(p(l.value.totalCents,l.value.currency)),1)])])])])):X("",!0)],64))}}),$H=kt(Gtt,[["__scopeId","data-v-f39cdded"]]),Qtt=["aria-expanded","aria-label"],Ytt={class:"sm-picker__value-text"},Jtt=["aria-label"],Xtt=["aria-label"],ent={class:"sm-picker__group"},tnt=["aria-selected","onMouseenter","onClick"],nnt={class:"sm-picker__option-label"},int=["aria-label"],ont={class:"sm-picker__group"},snt=["aria-selected","onMouseenter","onClick"],rnt={class:"sm-picker__option-label"},lnt=188,ant=250,Wk=8,unt=Xe({__name:"SecondaryModelPicker",props:{modelValue:{},effort:{},groups:{},modelInfoById:{}},emits:["select"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt(),s=K(null),r=K(null),l=K(null),a=K(null),u=new Map,c=K(!1);sc(c,l);const d=K(!1),h=K({}),p=`sm-picker-${Math.random().toString(36).slice(2,9)}`,g=K(""),m=K(null),k=K("right"),w=K(0),y=K("models"),b=K(0),A=K(0);let T=null;const S=F(()=>n.groups.flatMap(te=>te.options)),x=F(()=>n.modelValue?S.value.find(te=>te.id===n.modelValue)?.label??n.modelValue:""),_=F(()=>n.modelValue?n.effort?`${x.value} · ${n.effort}`:x.value:o("settings.noSecondaryModel")),L=F(()=>{const te=m.value;if(te===null)return[];const be=c9(n.modelInfoById[te]),Q=n.effort===""?[null,...be]:[...be];return n.modelValue===te&&n.effort!==""&&!be.includes(n.effort)&&Q.push(n.effort),Q});function M(te){return n.modelValue!==m.value?!1:te===null?n.effort==="":n.effort===te}function N(){const te=L.value.findIndex(be=>M(be));return te>=0?te:0}function I(te,be){te instanceof HTMLElement?u.set(be,te):u.delete(be)}function z(){T!==null&&(clearTimeout(T),T=null)}function H(){z(),T=setTimeout(()=>{m.value=null,y.value==="efforts"&&(y.value="models")},ant)}function O(te){te!==g.value&&(g.value=te,b.value=Math.max(0,S.value.findIndex(be=>be.id===te)))}function R(){const te=r.value,be=l.value;if(!te||!be)return;const Q=te.getBoundingClientRect(),ue=be.offsetHeight,Ae=window.innerHeight-Q.bottom;d.value=Ae<ue+Wk&&Q.top>ue;const se=Math.max(Wk,window.innerWidth-Q.right);h.value=d.value?{right:`${se}px`,bottom:`${window.innerHeight-Q.top+4}px`,top:"auto"}:{right:`${se}px`,top:`${Q.bottom+4}px`,bottom:"auto"}}function j(){const te=l.value,be=m.value===null?void 0:u.get(m.value);if(!te||!be)return;const Q=te.getBoundingClientRect(),ue=be.getBoundingClientRect(),Ae=a.value?.offsetHeight??0,se=Math.max(0,window.innerHeight-Wk-Ae-Q.top);w.value=Math.max(0,Math.min(ue.top-Q.top-4,te.offsetHeight-40,se));const re=window.innerWidth-Q.right,G=Q.left;k.value=re>=lnt||re>=G?"right":"left"}function $(te,{moveFocus:be=!1}={}){O(te),z(),m.value=te,be&&(y.value="efforts",A.value=N()),dt(j)}function W(){m.value=null,y.value="models"}function P(){c.value||(c.value=!0,g.value=n.modelValue||(S.value[0]?.id??""),b.value=Math.max(0,S.value.findIndex(te=>te.id===g.value)),m.value=null,y.value="models",dt(R))}function Z({restoreFocus:te=!1}={}){c.value&&(z(),c.value=!1,m.value=null,te&&dt(()=>r.value?.focus()))}function ae(){c.value?Z():P()}function V(te){if(m.value===null)return;const be={model:m.value,effort:te??void 0};(be.model!==n.modelValue||(be.effort??"")!==n.effort)&&i("select",be),Z({restoreFocus:!0})}function Y(){dt(()=>{l.value?.querySelector(".sm-picker__option.is-kb-active")?.scrollIntoView({block:"nearest"})})}function oe(te){const be=S.value;if(be.length===0)return;const Q=(b.value+te+be.length)%be.length,ue=be[Q].id;O(ue),m.value!==null&&$(ue),Y()}function q(te){const be=L.value;be.length!==0&&(A.value=(A.value+te+be.length)%be.length,Y())}function ne(te){if(!c.value){(te.key==="Enter"||te.key===" "||te.key==="ArrowDown")&&(te.preventDefault(),P());return}if(te.key==="ArrowDown")te.preventDefault(),y.value==="models"?oe(1):q(1);else if(te.key==="ArrowUp")te.preventDefault(),y.value==="models"?oe(-1):q(-1);else if(te.key==="ArrowRight")te.preventDefault(),$(g.value,{moveFocus:!0});else if(te.key==="ArrowLeft")te.preventDefault(),m.value!==null&&W();else if(te.key==="Enter"||te.key===" ")te.preventDefault(),y.value==="models"?$(g.value,{moveFocus:!0}):V(L.value[A.value]??null);else if(te.key==="Home"||te.key==="End"){te.preventDefault();const be=te.key==="Home";if(y.value==="models"){const Q=S.value;if(Q.length===0)return;const ue=(be?Q[0]:Q.at(-1)).id;O(ue),m.value!==null&&$(ue)}else A.value=be?0:L.value.length-1;Y()}else te.key==="Escape"&&(te.preventDefault(),Z({restoreFocus:!0}))}function ie(te){const be=te.target;s.value?.contains(be)||l.value?.contains(be)||Z()}function pe(te){if(c.value){if(l.value?.contains(te.target)){j();return}R(),j()}}function Ne(){Z()}return cn(()=>{document.addEventListener("pointerdown",ie),document.addEventListener("scroll",pe,!0),window.addEventListener("resize",Ne)}),_n(()=>{document.removeEventListener("pointerdown",ie),document.removeEventListener("scroll",pe,!0),window.removeEventListener("resize",Ne),z()}),(te,be)=>(v(),E("div",{ref_key:"rootRef",ref:s,class:Fe(["sm-picker",{"is-open":c.value}])},[C("button",{ref_key:"triggerRef",ref:r,class:"sm-picker__trigger",type:"button",role:"combobox","aria-controls":p,"aria-expanded":c.value,"aria-haspopup":"dialog","aria-label":f(o)("settings.secondaryModel"),onClick:ae,onKeydown:ne},[C("span",{class:Fe(["sm-picker__value",{"is-placeholder":!e.modelValue}])},[C("span",Ytt,D(_.value),1)],2),U(f(ve),{class:"sm-picker__chevron",name:"chevron-down",size:"sm"})],40,Qtt),(v(),ce(Ds,{to:"body"},[c.value?(v(),E("div",{key:0,id:p,ref_key:"menuRef",ref:l,class:Fe(["sm-picker__menu",{"sm-picker__menu--up":d.value}]),style:Kt(h.value),role:"dialog","aria-label":f(o)("settings.secondaryModel")},[C("div",{class:"sm-picker__models",role:"listbox","aria-label":f(o)("settings.secondaryModel")},[(v(!0),E(Ee,null,pt(e.groups,Q=>(v(),E(Ee,{key:Q.provider},[C("div",ent,D(Q.provider),1),(v(!0),E(Ee,null,pt(Q.options,ue=>(v(),E("button",{key:ue.id,ref_for:!0,ref:Ae=>I(Ae,ue.id),class:Fe(["sm-picker__option",{"is-selected":ue.id===e.modelValue,"is-active":ue.id===g.value,"is-kb-active":y.value==="models"&&ue.id===g.value}]),type:"button",role:"option","aria-selected":ue.id===e.modelValue,onMouseenter:Ae=>$(ue.id),onMouseleave:H,onClick:Ae=>$(ue.id,{moveFocus:!0})},[U(f(ve),{class:"sm-picker__check",name:"check",size:"sm"}),C("span",nnt,D(ue.label),1),U(f(ve),{class:"sm-picker__flyout-caret",name:"chevron-right",size:"sm"})],42,tnt))),128))],64))),128))],8,Xtt),m.value!==null?(v(),E("div",{key:0,ref_key:"flyoutRef",ref:a,class:Fe(["sm-picker__flyout",`sm-picker__flyout--${k.value}`]),style:Kt({top:`${w.value}px`}),role:"listbox","aria-label":f(o)("settings.secondaryModelEffort"),onMouseenter:z,onMouseleave:H},[C("div",ont,D(f(o)("settings.secondaryModelEffort")),1),(v(!0),E(Ee,null,pt(L.value,(Q,ue)=>(v(),E("button",{key:Q??"__default__",class:Fe(["sm-picker__option",{"is-selected":M(Q),"is-active":y.value==="efforts"&&ue===A.value,"is-kb-active":y.value==="efforts"&&ue===A.value,"is-muted":Q===null}]),type:"button",role:"option","aria-selected":M(Q),onMouseenter:Ae=>{y.value="efforts",A.value=ue},onClick:Ae=>V(Q)},[U(f(ve),{class:"sm-picker__check",name:"check",size:"sm"}),C("span",rnt,D(Q??f(o)("settings.secondaryModelEffortAuto")),1)],42,snt))),128))],46,int)):X("",!0)],14,Jtt)):X("",!0)]))],2))}}),cnt=kt(unt,[["__scopeId","data-v-0cf7dc4b"]]),dnt=["aria-label"],fnt={class:"settings-tabs-header"},hnt={class:"settings-dialog-title"},pnt={class:"settings-tab-list"},gnt=["aria-selected","onClick"],mnt={class:"settings-region"},vnt={class:"settings-region-header"},ynt={class:"panel"},knt={class:"sec"},bnt={class:"sec-title"},Ant={class:"settings-group"},Cnt={class:"row"},wnt={class:"rlabel"},xnt={class:"hint"},Snt={class:"row language-row"},_nt={class:"rlabel"},Mnt={class:"hint"},Int={class:"row font-size-row"},Ent={class:"rlabel"},Tnt={class:"hint"},Lnt={class:"sec notification-settings"},Nnt={class:"sec-title"},Fnt={class:"settings-group"},Dnt={class:"row"},Bnt={class:"rlabel"},$nt={class:"hint"},Rnt={key:0,class:"hint"},znt={class:"row"},Ont={class:"rlabel"},Pnt={class:"hint"},jnt={class:"panel"},Hnt={class:"sec"},Wnt={class:"sec-title"},qnt={class:"settings-group"},Unt={class:"account-row"},Knt={class:"account-avatar","aria-hidden":"true"},Vnt=["src"],Znt={class:"account-meta"},Gnt={class:"account-name-row"},Qnt={class:"account-name"},Ynt={class:"account-sub"},Jnt={key:0,class:"panel"},Xnt={class:"panel"},eit={class:"sec"},tit={class:"sec-head"},nit={class:"sec-title"},iit={class:"settings-group"},oit={class:"row"},sit={class:"rlabel"},rit={class:"hint"},lit={key:0,class:"select-wrap"},ait={key:1,class:"rvalue mono"},uit={class:"row"},cit={class:"rlabel"},dit={class:"hint"},fit={class:"row"},hit={class:"rlabel"},pit={class:"hint"},git={class:"row"},mit={class:"rlabel"},vit={class:"hint"},yit={key:1,class:"empty-config"},kit={key:0,class:"sec"},bit={class:"sec-head"},Ait={class:"sec-title"},Cit={class:"settings-group"},wit={class:"row"},xit={class:"rlabel"},Sit={class:"hint"},_it={key:0,class:"select-wrap"},Mit={key:1,class:"rvalue mono"},Iit={class:"panel"},Eit={class:"sec"},Tit={class:"sec-title"},Lit={class:"settings-group"},Nit={class:"row"},Fit={class:"rlabel"},Dit={class:"hint"},Bit={class:"rvalue"},$it={class:"row"},Rit={class:"rlabel"},zit={class:"hint"},Oit={class:"rvalue-wrap"},Pit={class:"rvalue"},jit={class:"row"},Hit={class:"rlabel"},Wit={class:"hint"},qit={class:"rvalue-wrap"},Uit={class:"rvalue"},Kit={key:0,class:"row"},Vit={class:"rlabel"},Zit={key:0,class:"hint"},Git={key:1,class:"hint"},Qit={key:1,class:"row"},Yit={class:"rlabel"},Jit={class:"hint"},Xit={key:0,class:"sec"},eot={class:"sec-title"},tot={class:"settings-group"},not={class:"row"},iot={class:"rlabel"},oot={class:"hint"},sot={class:"hint"},rot={class:"sec"},lot={class:"sec-title"},aot={class:"settings-group"},uot={class:"row"},cot={class:"rlabel"},dot={class:"hint"},fot={key:0,class:"hint"},hot={class:"panel"},pot={class:"sec"},got={class:"sec-title"},mot={class:"settings-group"},vot={class:"row"},yot={class:"rlabel"},kot={class:"hint"},bot={class:"panel"},Aot={class:"panel-head"},Cot={class:"panel-title"},wot={class:"panel-desc"},xot={class:"archive-toolbar"},Sot={class:"archive-search"},_ot=["placeholder"],Mot={key:0,class:"archive-empty"},Iot={key:0,class:"archive-list"},Eot={class:"archive-workspace"},Tot={class:"path"},Lot={class:"count"},Not={class:"setting-card"},Fot={class:"archive-meta"},Dot={class:"archive-name"},Bot={class:"archive-time"},$ot={key:1,class:"archive-empty"},Rot=100,zot=Xe({__name:"SettingsDialog",props:{colorScheme:{},fontScale:{},initialTab:{},managedProviderStatus:{},managedUserInfo:{},onFetchUsage:{type:Function},notify:{type:Boolean},notifyPermission:{},notifySound:{type:Boolean},config:{},models:{},configSaving:{type:Boolean},serverVersion:{},experimentalFlags:{}},emits:["setColorScheme","setFontScale","setNotify","setNotifySound","login","logout","updateConfig","close"],setup(e,{emit:t}){const{t:n}=zt(),{sidebarTabs:i,setSidebarTabs:o}=d1();function s(Le){o(Le)}const r=e,l=t,a=F(()=>r.managedProviderStatus==="authenticated"),u=F(()=>a.value?r.managedUserInfo?.nickname||n("sidebar.defaultUserName"):n("sidebar.notSignedIn")),c=F(()=>r.managedUserInfo?.userLevelName?.trim()??""),d=K(!1);Pe(()=>r.managedUserInfo?.avatar,()=>{d.value=!1});const h=F(()=>!!r.managedUserInfo?.avatar&&!d.value),p=F(()=>a.value?n("settings.signedIn"):n("settings.signedOutHint")),g=K(r.initialTab??"general"),m=K(!1);let k=null;function w(){m.value=!0,k&&clearTimeout(k),k=setTimeout(()=>{m.value=!1,k=null},900)}const y=[{id:"general",labelKey:"settings.tabs.general",icon:"sliders"},{id:"agent",labelKey:"settings.tabs.agent",icon:"robot"},{id:"account",labelKey:"settings.tabs.account",icon:"user"},{id:"providers",labelKey:"settings.tabs.providers",icon:"bolt"},{id:"advanced",labelKey:"settings.tabs.advanced",icon:"microscope"},{id:"lab",labelKey:"settings.tabs.lab",icon:"flask"},{id:"archived",labelKey:"settings.tabs.archived",icon:"archive"}],b=a5e(),A=K(!1),T=K(!1);function S(){r.serverVersion&&Xo(r.serverVersion).then(Le=>{Le&&(A.value=!0,setTimeout(()=>{A.value=!1},1500))})}function x(){Xo(b).then(Le=>{Le&&(T.value=!0,setTimeout(()=>{T.value=!1},1500))})}const _=["manual","yolo","auto"],L={manual:"status.permissionManual",auto:"status.permissionAuto",yolo:"status.permissionYolo"},M=K(null);NH(M);const{isConfirmOpen:N}=Vc();function I(Le){Le.key==="Escape"&&!Le.defaultPrevented&&!N.value&&l("close")}cn(()=>document.addEventListener("keydown",I)),_n(()=>{document.removeEventListener("keydown",I),k&&clearTimeout(k)});function z(){_R()}const H=(()=>{const Le="0.38.0".trim()?"0.38.0":"";let ze="";if("2026-08-21T12:58:21.598Z".trim()){const Tt=new Date("2026-08-21T12:58:21.598Z");if(!Number.isNaN(Tt.getTime())){const on=jt=>String(jt).padStart(2,"0");ze=`${Tt.getFullYear()}-${on(Tt.getMonth()+1)}-${on(Tt.getDate())} ${on(Tt.getHours())}:${on(Tt.getMinutes())}`}}const Ye=ze===""?Le:`${Le} · ${ze}`;return Ye===""?"-":Ye})(),O=cfe(),R=K(!1),j=K(null);async function $(){if(!R.value){R.value=!0,j.value=null;try{j.value=await O.check()}finally{R.value=!1}}}const W=F(()=>{const Le=j.value;if(Le===null)return"";switch(Le.outcome){case"available":return O.status.value.state==="downloaded"?n("settings.updateCheckDownloaded",{version:Le.version??""}):O.autoDownload.value?n("settings.updateCheckAvailableAuto",{version:Le.version??""}):n("settings.updateCheckAvailable",{version:Le.version??""});case"latest":return n("settings.updateCheckLatest");case"unsupported":return n("settings.updateCheckUnsupported");case"error":return n("settings.updateCheckFailed")}}),P=F(()=>{const Le=new Map;for(const ze of r.models??[])Le.set(ze.id,{id:ze.id,label:ze.displayName??ze.model??ze.id,provider:ze.provider});for(const[ze,Ye]of Object.entries(r.config?.models??{})){if(Le.has(ze))continue;const Tt=Y(Ye);Le.set(ze,{id:ze,label:oe(ze,Ye,Tt),provider:Tt??ze})}return Array.from(Le.values())}),Z=F(()=>{const Le=new Map;for(const ze of P.value){const Ye=Le.get(ze.provider)??[];Ye.push(ze),Le.set(ze.provider,Ye)}for(const ze of Le.values())ze.sort((Ye,Tt)=>Ye.label.localeCompare(Tt.label));return Array.from(Le.entries()).toSorted(([ze],[Ye])=>ze.localeCompare(Ye)).map(([ze,Ye])=>({provider:ze,options:Ye}))}),ae=F(()=>{const Le=Z.value.flatMap(ze=>ze.options.map(Ye=>({value:Ye.id,label:Ye.label,group:ze.provider})));return r.config?.defaultModel||Le.unshift({value:"",label:n("settings.noDefaultModel"),group:"",disabled:!0}),Le}),V=F(()=>{const Le=r.config?.defaultPermissionMode;return Le==="auto"||Le==="yolo"||Le==="manual"?Le:"manual"});function Y(Le){if(!Le||typeof Le!="object")return;const ze=Le;return typeof ze.provider=="string"?ze.provider:void 0}function oe(Le,ze,Ye){if(!ze||typeof ze!="object")return Le;const Tt=ze,on=typeof Tt.model=="string"?Tt.model:void 0,jt=Ye??Y(ze);return on&&jt?`${Le} (${jt}/${on})`:on?`${Le} (${on})`:Le}function q(Le){return Le===!0}function ne(Le){!Le||Le===r.config?.defaultModel||l("updateConfig",{defaultModel:Le})}function ie(Le){Le!==V.value&&l("updateConfig",{defaultPermissionMode:Le})}const pe=F(()=>(r.experimentalFlags?.["secondary-model"]??r.config?.experimental?.["secondary-model"])===!0),Ne=F(()=>r.config?.secondaryModel?.model??""),te=F(()=>r.config?.secondaryModel?.defaultEffort??""),be=F(()=>Object.fromEntries((r.models??[]).map(Le=>[Le.id,Le])));function Q(Le){Le.model===Ne.value&&(Le.effort??"")===te.value||l("updateConfig",{secondaryModel:Le.effort?{model:Le.model,defaultEffort:Le.effort}:{model:Le.model}})}function ue(Le){const ze=r.config?.[Le];l("updateConfig",{[Le]:!q(ze)})}function Ae(){const Le=r.config?.thinking;return!Le||typeof Le!="object"?!0:Le.enabled!==!1}function se(){l("updateConfig",{thinking:{enabled:!Ae()}})}function re(){const Le=r.config?.telemetry!==!1;l("updateConfig",{telemetry:!Le})}function G(Le){g.value=Le}const le=pa(),ge=F(()=>a.value&&le.managedMembership.value==="free"),ke=K([]),Ie=K(!1),Oe=K(!1),we=K(""),Be=K("all"),tt=K("archived-desc");async function ut(){if(!(Ie.value||Oe.value)){Ie.value=!0;try{const Le=[];let ze;for(;;){const Ye=await le.loadArchivedSessions({beforeId:ze,pageSize:Rot});if(Le.push(...Ye.items),!Ye.hasMore||Ye.items.length===0)break;const Tt=Ye.items.at(-1)?.id;if(Tt===void 0)break;ze=Tt}ke.value=Le,Oe.value=!0}catch(Le){bu("loadAllArchived failed",Le)}finally{Ie.value=!1}}}Pe(g,Le=>{Le==="archived"&&!Oe.value&&ut()},{immediate:!0});const _t=F(()=>{const Le=new Set;for(const ze of ke.value)Le.add(ze.cwd);return Array.from(Le).sort((ze,Ye)=>ze.localeCompare(Ye))}),Ct=F(()=>[{value:"all",label:n("settings.archivedAllWorkspaces")},..._t.value.map(Le=>({value:Le,label:Le}))]),$t=F(()=>{const Le=we.value.trim().toLowerCase();let ze=ke.value.filter(Ye=>Ye.archived===!0);return Be.value!=="all"&&(ze=ze.filter(Ye=>Ye.cwd===Be.value)),Le&&(ze=ze.filter(Ye=>Ye.title.toLowerCase().includes(Le))),ze=ze.slice(),tt.value==="archived-desc"?ze.sort((Ye,Tt)=>(Tt.archivedAt??Tt.updatedAt).localeCompare(Ye.archivedAt??Ye.updatedAt)):tt.value==="created-desc"?ze.sort((Ye,Tt)=>Tt.createdAt.localeCompare(Ye.createdAt)):ze.sort((Ye,Tt)=>Ye.title.localeCompare(Tt.title,"zh")),ze}),Vt=F(()=>{const Le=new Map;for(const ze of $t.value){const Ye=Le.get(ze.cwd)??[];Ye.push(ze),Le.set(ze.cwd,Ye)}return Array.from(Le.entries()).map(([ze,Ye])=>({cwd:ze,items:Ye}))});async function nn(Le){await le.restoreSession(Le)&&(ke.value=ke.value.filter(Ye=>Ye.id!==Le))}function gt(Le){const ze=new Date(Le);if(Number.isNaN(ze.getTime()))return Le;const Ye=Tt=>String(Tt).padStart(2,"0");return`${ze.getFullYear()}-${Ye(ze.getMonth()+1)}-${Ye(ze.getDate())} ${Ye(ze.getHours())}:${Ye(ze.getMinutes())}`}return(Le,ze)=>(v(),ce(f(Pc),{open:!0,"close-on-esc":!1,"aria-label":f(n)("settings.title"),size:"xl",height:"fixed",padded:!1,level:"grouped",onClose:ze[16]||(ze[16]=Ye=>l("close"))},{default:de(()=>[C("div",{ref_key:"dialogRef",ref:M,class:"sd"},[C("nav",{class:"settings-tabs",role:"tablist","aria-label":f(n)("settings.title")},[C("header",fnt,[C("h2",hnt,D(f(n)("settings.title")),1)]),C("div",pnt,[(v(),E(Ee,null,pt(y,Ye=>C("button",{key:Ye.id,type:"button",class:Fe(["tab",{on:g.value===Ye.id}]),role:"tab","aria-selected":g.value===Ye.id,onClick:Tt=>G(Ye.id)},[U(f(ve),{name:Ye.icon,size:"md"},null,8,["name"]),C("span",null,D(f(n)(Ye.labelKey)),1)],10,gnt)),64))])],8,dnt),C("section",mnt,[C("header",vnt,[U(f(Jt),{size:"sm",label:f(n)("settings.close"),tooltip:f(n)("settings.close"),onClick:ze[0]||(ze[0]=Ye=>l("close"))},{default:de(()=>[U(f(ve),{name:"close",size:"md"})]),_:1},8,["label","tooltip"])]),C("div",{class:Fe(["body",{scrolling:m.value}]),onScroll:w},[Wn(C("section",ynt,[C("section",knt,[C("h3",bnt,D(f(n)("settings.appearance")),1),C("div",Ant,[C("div",Cnt,[C("span",wnt,[$e(D(f(n)("theme.colorSchemeLabel"))+" ",1),C("span",xnt,D(f(n)("settings.colorSchemeHint")),1)]),U(f(Vs),{"model-value":e.colorScheme,options:[{value:"light",label:f(n)("theme.light"),icon:"light-mode"},{value:"dark",label:f(n)("theme.dark"),icon:"dark-mode"},{value:"system",label:f(n)("theme.system")}],"onUpdate:modelValue":ze[1]||(ze[1]=Ye=>l("setColorScheme",Ye))},null,8,["model-value","options"])]),C("div",Snt,[C("span",_nt,[$e(D(f(n)("sidebar.language"))+" ",1),C("span",Mnt,D(f(n)("settings.languageHint")),1)]),U(FH)]),C("div",Int,[C("span",Ent,[$e(D(f(n)("settings.uiFontSize"))+" ",1),C("span",Tnt,D(f(n)("settings.uiFontSizeHint")),1)]),U(f(Vs),{"model-value":e.fontScale,options:[{value:"small",label:"S"},{value:"medium",label:"M"},{value:"large",label:"L"},{value:"xlarge",label:"XL"}],"aria-label":f(n)("settings.uiFontSize"),"onUpdate:modelValue":ze[2]||(ze[2]=Ye=>l("setFontScale",Ye))},null,8,["model-value","aria-label"])])])]),C("section",Lnt,[C("h3",Nnt,D(f(n)("settings.notifications")),1),C("div",Fnt,[C("div",Dnt,[C("span",Bnt,[$e(D(f(n)("settings.notifyEnabled"))+" ",1),C("span",$nt,D(f(n)("settings.notifyEnabledHint")),1),e.notifyPermission==="denied"?(v(),E("span",Rnt,D(f(n)("settings.notifyDenied")),1)):X("",!0)]),U(f(dd),{"model-value":e.notify,disabled:e.notifyPermission==="denied",label:f(n)("settings.notifyEnabled"),"onUpdate:modelValue":ze[3]||(ze[3]=Ye=>l("setNotify",Ye))},null,8,["model-value","disabled","label"])]),C("div",znt,[C("span",Ont,[$e(D(f(n)("settings.notifySound"))+" ",1),C("span",Pnt,D(f(n)("settings.notifySoundHint")),1)]),U(f(dd),{"model-value":e.notifySound,label:f(n)("settings.notifySound"),"onUpdate:modelValue":ze[4]||(ze[4]=Ye=>l("setNotifySound",Ye))},null,8,["model-value","label"])])])])],512),[[Po,g.value==="general"]]),Wn(C("section",jnt,[C("section",Hnt,[C("h3",Wnt,D(f(n)("settings.account")),1),C("div",qnt,[C("div",Unt,[C("span",Knt,[h.value?(v(),E("img",{key:0,src:r.managedUserInfo?.avatar,alt:"",onError:ze[5]||(ze[5]=Ye=>d.value=!0)},null,40,Vnt)):(v(),ce(f(ve),{key:1,name:"user",size:"md"}))]),C("span",Znt,[C("span",Gnt,[C("span",Qnt,D(u.value),1),c.value?(v(),ce(f(br),{key:0,class:"account-level",variant:"neutral",size:"sm"},{default:de(()=>[$e(D(c.value),1)]),_:1})):X("",!0)]),C("span",Ynt,D(p.value),1)]),a.value?(v(),ce(f(Qt),{key:0,variant:"danger-soft",size:"sm",onClick:ze[6]||(ze[6]=Ye=>l("logout"))},{default:de(()=>[$e(D(f(n)("sidebar.signOut")),1)]),_:1})):(v(),ce(f(Qt),{key:1,variant:"primary",size:"sm",onClick:ze[7]||(ze[7]=Ye=>l("login"))},{default:de(()=>[$e(D(f(n)("sidebar.signIn")),1)]),_:1}))])])]),ge.value?(v(),ce(BH,{key:0})):a.value?(v(),ce($H,{key:1,"on-fetch-usage":r.onFetchUsage},null,8,["on-fetch-usage"])):X("",!0)],512),[[Po,g.value==="account"]]),g.value==="providers"?(v(),E("section",Jnt,[U(ctt)])):X("",!0),Wn(C("section",Xnt,[C("section",eit,[C("div",tit,[C("h3",nit,D(f(n)("settings.agentDefaults")),1)]),C("div",iit,[e.config?(v(),E(Ee,{key:0},[C("div",oit,[C("span",sit,[$e(D(f(n)("settings.defaultModel"))+" ",1),C("span",rit,D(f(n)("settings.defaultModelHint")),1)]),Z.value.length>0?(v(),E("div",lit,[U(f(wb),{"model-value":e.config.defaultModel??"",options:ae.value,"aria-label":f(n)("settings.defaultModel"),"onUpdate:modelValue":ne},null,8,["model-value","options","aria-label"])])):(v(),E("span",ait,D(e.config.defaultModel??f(n)("settings.noDefaultModel")),1))]),C("div",uit,[C("span",cit,[$e(D(f(n)("settings.defaultPermission"))+" ",1),C("span",dit,D(f(n)("settings.defaultPermissionHint")),1)]),U(f(Vs),{"model-value":V.value,options:_.map(Ye=>({value:Ye,label:f(n)(L[Ye])})),"onUpdate:modelValue":ze[8]||(ze[8]=Ye=>ie(Ye))},null,8,["model-value","options"])]),C("div",fit,[C("span",hit,[$e(D(f(n)("settings.defaultThinking"))+" ",1),C("span",pit,D(f(n)("settings.defaultThinkingHint")),1)]),U(f(dd),{"model-value":Ae(),label:f(n)("settings.defaultThinking"),"onUpdate:modelValue":ze[9]||(ze[9]=Ye=>se())},null,8,["model-value","label"])]),C("div",git,[C("span",mit,[$e(D(f(n)("settings.defaultPlanMode"))+" ",1),C("span",vit,D(f(n)("settings.defaultPlanModeHint")),1)]),U(f(dd),{"model-value":q(e.config.defaultPlanMode),label:f(n)("settings.defaultPlanMode"),"onUpdate:modelValue":ze[10]||(ze[10]=Ye=>ue("defaultPlanMode"))},null,8,["model-value","label"])])],64)):(v(),E("div",yit,D(f(n)("settings.configUnavailable")),1))])]),e.config&&pe.value?(v(),E("section",kit,[C("div",bit,[C("h3",Ait,D(f(n)("settings.secondaryModelSection")),1)]),C("div",Cit,[C("div",wit,[C("span",xit,[$e(D(f(n)("settings.secondaryModel"))+" ",1),C("span",Sit,D(f(n)("settings.secondaryModelHint")),1)]),Z.value.length>0?(v(),E("div",_it,[U(cnt,{"model-value":Ne.value,effort:te.value,groups:Z.value,"model-info-by-id":be.value,onSelect:Q},null,8,["model-value","effort","groups","model-info-by-id"])])):(v(),E("span",Mit,D(Ne.value||f(n)("settings.noSecondaryModel")),1))])])])):X("",!0)],512),[[Po,g.value==="agent"]]),Wn(C("section",Iit,[C("section",Eit,[C("h3",Tit,D(f(n)("settings.versionAndUpdates")),1),C("div",Lit,[C("div",Nit,[C("span",Fit,[$e(D(f(n)("settings.appVersion"))+" ",1),C("span",Dit,D(f(n)("settings.appVersionHint")),1)]),C("span",Bit,D(f(H)),1)]),C("div",$it,[C("span",Rit,[$e(D(f(n)("settings.serverVersion"))+" ",1),C("span",zit,D(f(n)("settings.serverVersionHint")),1)]),C("span",Oit,[C("span",Pit,D(e.serverVersion||"-"),1),e.serverVersion?(v(),ce(f(Jt),{key:0,size:"sm",label:A.value?f(n)("settings.copied"):f(n)("settings.copyServerVersion"),tooltip:A.value?f(n)("settings.copied"):f(n)("settings.copyServerVersion"),onClick:S},{default:de(()=>[A.value?(v(),ce(f(ve),{key:1,class:"sd-check",name:"check",size:"md"})):(v(),ce(f(ve),{key:0,name:"copy",size:"md"}))]),_:1},8,["label","tooltip"])):X("",!0)])]),C("div",jit,[C("span",Hit,[$e(D(f(n)("settings.serverAddress"))+" ",1),C("span",Wit,D(f(n)("settings.serverAddressHint")),1)]),C("span",qit,[C("span",Uit,D(f(b)),1),U(f(Jt),{size:"sm",label:T.value?f(n)("settings.copied"):f(n)("settings.copyServerAddress"),tooltip:T.value?f(n)("settings.copied"):f(n)("settings.copyServerAddress"),onClick:x},{default:de(()=>[T.value?(v(),ce(f(ve),{key:1,class:"sd-check",name:"check",size:"md"})):(v(),ce(f(ve),{key:0,name:"copy",size:"md"}))]),_:1},8,["label","tooltip"])])]),f(O).canCheck?(v(),E("div",Kit,[C("span",Vit,[$e(D(f(n)("settings.checkUpdate"))+" ",1),W.value?(v(),E("span",Zit,D(W.value),1)):(v(),E("span",Git,D(f(n)("settings.checkUpdateHint")),1))]),U(f(Qt),{variant:"secondary",size:"sm",disabled:R.value,onClick:$},{default:de(()=>[$e(D(R.value?f(n)("settings.updateChecking"):f(n)("settings.checkUpdateBtn")),1)]),_:1},8,["disabled"])])):X("",!0),f(O).canToggleAutoDownload?(v(),E("div",Qit,[C("span",Yit,[$e(D(f(n)("settings.autoDownloadUpdate"))+" ",1),C("span",Jit,D(f(n)("settings.autoDownloadUpdateHint")),1)]),U(f(dd),{"model-value":f(O).autoDownload.value,label:f(n)("settings.autoDownloadUpdate"),"onUpdate:modelValue":ze[11]||(ze[11]=Ye=>f(O).setAutoDownload(Ye,"settings"))},null,8,["model-value","label"])])):X("",!0)])]),e.config?(v(),E("section",Xit,[C("h3",eot,D(f(n)("settings.privacy")),1),C("div",tot,[C("div",not,[C("span",iot,[$e(D(f(n)("settings.telemetry"))+" ",1),C("span",oot,D(f(n)("settings.telemetryHint")),1),C("span",sot,D(f(n)("settings.telemetryRestartHint")),1)]),U(f(dd),{"model-value":e.config.telemetry!==!1,disabled:e.configSaving,label:f(n)("settings.telemetry"),"onUpdate:modelValue":ze[12]||(ze[12]=Ye=>re())},null,8,["model-value","disabled","label"])])])])):X("",!0),C("section",rot,[C("h3",lot,D(f(n)("settings.diagnostics")),1),C("div",aot,[C("div",uot,[C("span",cot,[$e(D(f(n)("settings.exportLog"))+" ",1),C("span",dot,D(f(n)("settings.exportLogHint")),1),f(ga)()?X("",!0):(v(),E("span",fot,D(f(n)("settings.logHint")),1))]),U(f(Qt),{variant:"secondary",size:"sm",onClick:z},{default:de(()=>[$e(D(f(n)("settings.exportLogBtn")),1)]),_:1})])])])],512),[[Po,g.value==="advanced"]]),Wn(C("section",hot,[C("section",pot,[C("h3",got,D(f(n)("settings.tabs.lab")),1),C("div",mot,[C("div",vot,[C("span",yot,[$e(D(f(n)("settings.lab.sidebarTabs"))+" ",1),C("span",kot,D(f(n)("settings.lab.sidebarTabsHint")),1)]),U(f(dd),{"model-value":f(i),label:f(n)("settings.lab.sidebarTabs"),"onUpdate:modelValue":s},null,8,["model-value","label"])])])])],512),[[Po,g.value==="lab"]]),Wn(C("section",bot,[C("div",Aot,[C("h4",Cot,D(f(n)("settings.archivedTitle")),1),C("p",wot,D(f(n)("settings.archivedDesc")),1)]),C("div",xot,[C("label",Sot,[ze[17]||(ze[17]=C("svg",{viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.8","stroke-linecap":"round","stroke-linejoin":"round"},[C("circle",{cx:"11",cy:"11",r:"7"}),C("path",{d:"m21 21-4.3-4.3"})],-1)),Wn(C("input",{"onUpdate:modelValue":ze[13]||(ze[13]=Ye=>we.value=Ye),placeholder:f(n)("settings.archivedSearch")},null,8,_ot),[[Bs,we.value]])]),U(f(wb),{"model-value":Be.value,options:Ct.value,size:"sm","aria-label":f(n)("settings.archivedAllWorkspaces"),"onUpdate:modelValue":ze[14]||(ze[14]=Ye=>Be.value=Ye)},null,8,["model-value","options","aria-label"]),U(f(Vs),{size:"sm","model-value":tt.value,options:[{value:"archived-desc",label:f(n)("settings.archivedSortArchived"),icon:"clock"},{value:"created-desc",label:f(n)("settings.archivedSortCreated"),icon:"calendar-schedule"},{value:"name-asc",label:f(n)("settings.archivedSortName"),icon:"sort"}],"onUpdate:modelValue":ze[15]||(ze[15]=Ye=>tt.value=Ye)},null,8,["model-value","options"])]),Ie.value?(v(),E("div",Mot,D(f(n)("settings.archivedLoadingAll")),1)):(v(),E(Ee,{key:1},[Vt.value.length>0?(v(),E("div",Iot,[(v(!0),E(Ee,null,pt(Vt.value,Ye=>(v(),E("section",{key:Ye.cwd,class:"archive-card"},[C("div",Eot,[U(f(ve),{name:"folder-closed",size:"md"}),C("span",Tot,D(Ye.cwd),1),C("span",Lot,D(f(n)("settings.archivedSessionsCount",{count:Ye.items.length})),1)]),C("div",Not,[(v(!0),E(Ee,null,pt(Ye.items,Tt=>(v(),E("div",{key:Tt.id,class:"archive-row"},[C("div",Fot,[C("div",Dot,D(Tt.title),1),C("div",Bot,D(f(n)("settings.archivedAt",{time:gt(Tt.archivedAt??Tt.updatedAt)})),1)]),U(f(Qt),{variant:"secondary",size:"sm",onClick:on=>nn(Tt.id)},{default:de(()=>[U(f(ve),{name:"undo",size:"sm"}),C("span",null,D(f(n)("settings.archivedRestore")),1)]),_:1},8,["onClick"])]))),128))])]))),128))])):(v(),E("div",$ot,D(ke.value.length===0?f(n)("settings.archivedEmpty"):f(n)("settings.archivedNoMatch")),1))],64))],512),[[Po,g.value==="archived"]])],34)])],512)]),_:1},8,["aria-label"]))}}),Oot=kt(zot,[["__scopeId","data-v-955ddf4d"]]),Pot={class:"aw"},jot={class:"crumbbar"},Hot={class:"crumbs"},Wot={key:0,class:"crumb-sep"},qot=["onClick"],Uot={key:0,class:"filterbar"},Kot=["placeholder"],Vot={class:"folder-list"},Zot={key:0,class:"fl-loading"},Got=["onClick"],Qot={class:"folder-name search-rel"},Yot={key:0,class:"fl-empty"},Jot={key:1,class:"fl-loading"},Xot=["onClick"],est={class:"folder-name"},tst={key:0,class:"fl-empty"},nst={class:"paste-row"},ist={class:"paste-input-wrap"},ost={key:1,class:"add-error",role:"alert"},sst={class:"actions"},rst={class:"footer-hint"},lst=600,ast=6,jL=150,ust=Xe({__name:"AddWorkspaceDialog",props:{browseFs:{type:Function},getFsHome:{type:Function},defaultPath:{},error:{}},emits:["add","close"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=K(!0),r=K(!1),l=K(!1),a=K(""),u=K(null),c=K([]),d=K(""),h=K(!1),p=K([]),g=F(()=>d.value.trim().length>0);let m=0,k=null;function w($,W){const P=$.toLowerCase(),Z=W.toLowerCase();let ae=0;for(let V=0;V<Z.length&&ae<P.length;V++)Z[V]===P[ae]&&ae++;return ae===P.length}async function y($){const W=a.value,P=$.trim();if(!W||P===""){p.value=[],h.value=!1;return}const Z=++m;h.value=!0;const ae=[],V=[{path:W,depth:0}];let Y=0;for(;V.length>0&&Y<lst&&ae.length<jL;){if(Z!==m)return;const oe=V.shift();Y++;let q;try{q=await i.browseFs(oe.path)}catch{continue}if(Z!==m)return;for(const ne of q.entries){if(!ne.isDir)continue;const ie=ne.path.startsWith(W)?ne.path.slice(W.length).replace(/^\/+/,""):ne.path;if(w(P,ie||ne.name)&&(ae.push({path:ne.path,name:ne.name,rel:ie||ne.name}),ae.length>=jL))break;oe.depth+1<ast&&V.push({path:ne.path,depth:oe.depth+1})}Z===m&&(p.value=[...ae])}Z===m&&(h.value=!1)}Pe(d,$=>{if(k&&clearTimeout(k),$.trim()===""){m++,p.value=[],h.value=!1;return}k=setTimeout(()=>void y($),220)});const b=K(!1),A=K(""),T=F(()=>A.value.trim()),S=F(()=>{const $=a.value;if(!$)return[];const W=$.split("/").filter(Boolean),P=[{label:"/",path:"/"}];let Z="";for(const ae of W)Z+=`/${ae}`,P.push({label:ae,path:Z});return P}),x=F(()=>a.value.length>0);async function _($){r.value=!0;try{const W=await i.browseFs($);if(!W.path){l.value=!0;return}a.value=W.path,u.value=W.parent,c.value=W.entries,d.value="",l.value=!1}catch{l.value=!0}finally{r.value=!1}}function L($){$.isDir&&_($.path)}function M(){u.value&&_(u.value)}function N(){x.value&&o("add",a.value)}function I(){T.value.length!==0&&o("add",T.value)}const{handleCompositionStart:z,handleCompositionEnd:H,isComposingKeyEvent:O}=bl();function R($){O($)||I()}function j($){$.key==="Escape"&&O($)&&$.stopPropagation()}return cn(async()=>{r.value=!0;try{if(i.defaultPath&&(await _(i.defaultPath),!l.value))return;const $=await i.getFsHome();$.home?await _($.home):l.value=!0}catch{l.value=!0}finally{r.value=!1}}),_n(()=>{k&&clearTimeout(k)}),($,W)=>(v(),ce(f(Pc),{open:s.value,"onUpdate:open":W[5]||(W[5]=P=>s.value=P),title:f(n)("workspace.addTitle"),size:"lg",height:"fixed",padded:!1,onClose:W[6]||(W[6]=P=>o("close"))},{default:de(()=>[C("div",Pot,[l.value?X("",!0):(v(),E(Ee,{key:0},[C("div",jot,[U(f(Jt),{size:"sm",disabled:!u.value,label:f(n)("workspace.up"),tooltip:f(n)("workspace.up"),onClick:M},{default:de(()=>[U(f(ve),{name:"arrow-up",size:"md"})]),_:1},8,["disabled","label","tooltip"]),C("div",Hot,[(v(!0),E(Ee,null,pt(S.value,(P,Z)=>(v(),E(Ee,{key:P.path},[Z>1?(v(),E("span",Wot,"/")):X("",!0),C("button",{class:Fe(["crumb",{last:Z===S.value.length-1}]),onClick:ae=>_(P.path)},D(P.label),11,qot)],64))),128))])]),r.value?X("",!0):(v(),E("div",Uot,[U(f(ve),{class:"filter-icon",name:"search",size:"md"}),Wn(C("input",{"onUpdate:modelValue":W[0]||(W[0]=P=>d.value=P),class:"filter-input",type:"text",placeholder:f(n)("workspace.searchPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:W[1]||(W[1]=wt(()=>{},["stop"]))},null,40,Kot),[[Bs,d.value]]),h.value?(v(),ce(f(Oi),{key:0,size:"sm"})):X("",!0)])),C("div",Vot,[r.value?(v(),E("div",Zot,D(f(n)("workspace.browsing")),1)):g.value?(v(),E(Ee,{key:1},[(v(!0),E(Ee,null,pt(p.value,P=>(v(),E("button",{key:P.path,class:"folder-row",onClick:Z=>_(P.path)},[U(f(ve),{class:"dir-icon",name:"folder-closed",size:"sm"}),C("span",Qot,D(P.rel),1)],8,Got))),128)),!h.value&&p.value.length===0?(v(),E("div",Yot,D(f(n)("workspace.noFilterMatch",{q:d.value.trim()})),1)):h.value&&p.value.length===0?(v(),E("div",Jot,D(f(n)("workspace.searching")),1)):X("",!0)],64)):(v(),E(Ee,{key:2},[(v(!0),E(Ee,null,pt(c.value,P=>(v(),E("button",{key:P.path,class:"folder-row",onClick:Z=>L(P)},[U(f(ve),{class:"dir-icon",name:"folder-closed",size:"sm"}),C("span",est,D(P.name),1)],8,Xot))),128)),c.value.length===0?(v(),E("div",tst,D(f(n)("workspace.noSubfolders")),1)):X("",!0)],64))])],64)),C("div",{class:Fe(["paste-section",{"paste-only":l.value}])},[!l.value&&!b.value?(v(),ce(f(Qt),{key:0,variant:"ghost",size:"sm",onClick:W[2]||(W[2]=P=>b.value=!0)},{default:de(()=>[$e(D(f(n)("workspace.pasteToggle")),1)]),_:1})):(v(),ce(f(ZQ),{key:1,label:f(n)("workspace.pathLabel")},{default:de(()=>[C("div",nst,[C("div",ist,[U(f(Ns),{modelValue:A.value,"onUpdate:modelValue":W[3]||(W[3]=P=>A.value=P),placeholder:f(n)("workspace.pathPlaceholder"),autocomplete:"off",spellcheck:"false",onKeydown:[Ho(wt(R,["stop"]),["enter"]),j],onCompositionstart:f(z),onCompositionend:f(H)},null,8,["modelValue","placeholder","onKeydown","onCompositionstart","onCompositionend"])]),U(f(Jt),{disabled:T.value.length===0,label:f(n)("workspace.add"),tooltip:f(n)("workspace.add"),onClick:I},{default:de(()=>[U(f(ve),{name:"plus",size:"md"})]),_:1},8,["disabled","label","tooltip"])])]),_:1},8,["label"]))],2),e.error?(v(),E("div",ost,D(e.error),1)):X("",!0),C("div",sst,[U(f(gn),{text:a.value},{default:de(()=>[l.value?X("",!0):(v(),ce(f(Qt),{key:0,variant:"primary",disabled:!x.value,onClick:N},{default:de(()=>[$e(D(f(n)("workspace.openThisFolder")),1)]),_:1},8,["disabled"]))]),_:1},8,["text"]),U(f(Qt),{variant:"secondary",onClick:W[4]||(W[4]=P=>o("close"))},{default:de(()=>[$e(D(f(n)("workspace.cancel")),1)]),_:1})]),C("div",rst,D(f(n)("workspace.browseHint")),1)])]),_:1},8,["open","title"]))}}),cst=kt(ust,[["__scopeId","data-v-fea98be5"]]),dst={key:0,class:"confirm-dialog__message"},fst=Xe({__name:"ConfirmDialog",props:{open:{type:Boolean},title:{},message:{},confirmLabel:{},cancelLabel:{},variant:{default:"danger"},loading:{type:Boolean}},emits:["update:open","confirm","cancel"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt();function s(){n.loading||(i("update:open",!1),i("cancel"))}function r(l){if(l.key!=="Enter"||!n.open||n.loading)return;const a=l.target;a instanceof HTMLButtonElement||a instanceof HTMLAnchorElement||a instanceof HTMLTextAreaElement||a instanceof HTMLSelectElement||a instanceof HTMLInputElement||(l.preventDefault(),i("confirm"))}return typeof window<"u"&&window.addEventListener("keydown",r),Hn(()=>{typeof window<"u"&&window.removeEventListener("keydown",r)}),(l,a)=>(v(),ce(f(Pc),{open:e.open,title:e.title,height:"auto","initial-focus":".confirm-dialog__confirm","close-on-esc":!e.loading,"close-on-overlay":!e.loading,"onUpdate:open":a[1]||(a[1]=u=>i("update:open",u)),onClose:s},{foot:de(()=>[U(f(Qt),{variant:"secondary",disabled:e.loading,onClick:s},{default:de(()=>[$e(D(e.cancelLabel??f(o)("common.cancel")),1)]),_:1},8,["disabled"]),U(f(Qt),{class:"confirm-dialog__confirm",variant:e.variant,loading:e.loading,onClick:a[0]||(a[0]=u=>i("confirm"))},{default:de(()=>[$e(D(e.confirmLabel??f(o)("common.confirm")),1)]),_:1},8,["variant","loading"])]),default:de(()=>[e.message?(v(),E("p",dst,D(e.message),1)):X("",!0)]),_:1},8,["open","title","close-on-esc","close-on-overlay"]))}}),hst=kt(fst,[["__scopeId","data-v-aa5422da"]]),pst=Xe({__name:"ConfirmDialogHost",setup(e){const{current:t,busy:n,settle:i,runAction:o}=Vc();function s(){o()}return(r,l)=>f(t)!==null?(v(),ce(hst,{key:0,open:!0,title:f(t).title,message:f(t).message,"confirm-label":f(t).confirmLabel,"cancel-label":f(t).cancelLabel,variant:f(t).variant,loading:f(n),onConfirm:s,onCancel:l[0]||(l[0]=a=>f(i)(!1))},null,8,["title","message","confirm-label","cancel-label","variant","loading"])):X("",!0)}}),gst={class:"rows"},mst={class:"row"},vst={class:"row"},yst={class:"row"},kst={class:"row"},bst={class:"row"},Ast={class:"row"},Cst={class:"ctx-text"},wst={key:0,class:"bar"},xst={class:"row"},Sst=Xe({__name:"StatusPanel",props:{status:{},thinking:{},planMode:{type:Boolean},swarmMode:{type:Boolean},costUsd:{}},emits:["close"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=K(!0),r=F(()=>i.status.ctxMax<=0?0:Math.min(100,Math.max(0,Math.ceil(i.status.ctxUsed/i.status.ctxMax*100)))),l=F(()=>i.status.ctxMax>0?n("status.statusContextValue",{used:_u(i.status.ctxUsed),max:_u(i.status.ctxMax),pct:r.value}):n("status.statusNone"));function a(g){return n(g==="yolo"?"status.permissionYolo":g==="auto"?"status.permissionAuto":"status.permissionManual")}const u=F(()=>{const g=i.status.permission;return g==="auto"?"var(--color-danger)":g==="yolo"?"var(--color-warning)":"var(--color-text)"}),c=F(()=>i.planMode?n("status.planOn"):n("status.planOff")),d=F(()=>i.swarmMode?n("status.swarmOn"):n("status.swarmOff")),h=F(()=>typeof i.costUsd=="number"&&i.costUsd>0),p=F(()=>h.value?`$${i.costUsd.toFixed(4)}`:n("status.statusNone"));return(g,m)=>(v(),ce(f(Pc),{open:s.value,"onUpdate:open":m[0]||(m[0]=k=>s.value=k),title:f(n)("status.statusPanelTitle"),onClose:m[1]||(m[1]=k=>o("close"))},{default:de(()=>[C("dl",gst,[C("div",mst,[C("dt",null,D(f(n)("status.statusModel")),1),C("dd",null,D(e.status.model),1)]),C("div",vst,[C("dt",null,D(f(n)("status.statusThinking")),1),C("dd",null,D(e.thinking),1)]),C("div",yst,[C("dt",null,D(f(n)("status.statusPermission")),1),C("dd",{style:Kt({color:u.value})},D(a(e.status.permission)),5)]),C("div",kst,[C("dt",null,D(f(n)("status.statusPlanMode")),1),C("dd",{class:Fe({"plan-on":e.planMode})},D(c.value),3)]),C("div",bst,[C("dt",null,D(f(n)("status.statusSwarmMode")),1),C("dd",{class:Fe({"swarm-on":e.swarmMode})},D(d.value),3)]),C("div",Ast,[C("dt",null,D(f(n)("status.statusContext")),1),C("dd",null,[C("span",Cst,D(l.value),1),e.status.ctxMax>0?(v(),E("span",wst,[C("i",{style:Kt({width:r.value+"%"})},null,4)])):X("",!0)])]),C("div",xst,[C("dt",null,D(f(n)("status.statusCost")),1),C("dd",null,D(p.value),1)])])]),_:1},8,["open","title"]))}}),_st=kt(Sst,[["__scopeId","data-v-340d1b31"]]),Mst={key:0,class:"actions"},Ist=["onClick"],Est=["onClick"],Tst={key:1,class:"details"},Lst=Xe({__name:"WarningToasts",props:{warnings:{}},emits:["dismiss"],setup(e,{emit:t}){const n=e,i=t,{t:o}=zt();function s(M){return typeof M=="object"&&M!==null}function r(M){return s(M)?M.title:M}function l(M){return s(M)?M.message??"":""}function a(M){return s(M)?M.details:void 0}function u(M){return s(M)?M.severity==="error":M.startsWith(`${o("warnings.errorLabel")}:`)||/\b4\d\d\b|error|失败|failed/i.test(M)}function c(M){return s(M)?M.severity==="error"?"danger":M.severity==="success"?"success":M.severity==="info"?"info":"warning":u(M)?"danger":"warning"}function d(M){return s(M)?`notice:${M.severity}:${M.title}:${M.message??""}:${JSON.stringify(M.details??[])}`:`text:${M}`}function h(M){if(!s(M))return M;const N=[M.title];M.message&&N.push(M.message);const I=M.details??[];if(I.length>0){N.push("",`${o("warnings.diagnostics")}:`);for(const z of I)N.push(`${z.label}: ${z.value}`)}return N.join(` -`)}let p=1;const g=K([]),m=new Map,k=new Map;function w(M){const N=u(M)?12e3:6e3;return typeof window<"u"&&window.matchMedia?.("(hover: none)").matches===!0?N+5e3:N}function y(M,N){const I=m.get(M)??{handle:null,deadline:0,remaining:0};I.handle=setTimeout(()=>L(M),N),I.deadline=Date.now()+N,m.set(M,I)}function b(M){const N=m.get(M);N&&N.handle!==null&&clearTimeout(N.handle),m.delete(M)}function A(M){const N=m.get(M);!N||N.handle===null||(clearTimeout(N.handle),N.handle=null,N.remaining=Math.max(0,N.deadline-Date.now()))}function T(M){if(g.value.find(z=>z.id===M)?.detailsOpen)return;const I=m.get(M);!I||I.handle!==null||y(M,I.remaining)}const S=F(()=>Fs.value+oh.value>0);Pe(S,M=>{for(const N of g.value)M?A(N.id):T(N.id)});function x(M){M.detailsOpen=!M.detailsOpen,M.detailsOpen?A(M.id):T(M.id)}async function _(M){if(!await Xo(h(M.warning)))return;M.copied=!0;const I=k.get(M.id);I&&clearTimeout(I),k.set(M.id,setTimeout(()=>{M.copied=!1,k.delete(M.id)},1400))}function L(M){b(M);const N=k.get(M);N&&clearTimeout(N),k.delete(M);const I=g.value.findIndex(z=>z.id===M);I!==-1&&(g.value=g.value.filter(z=>z.id!==M),i("dismiss",I))}return Pe(()=>n.warnings,M=>{const N=[...g.value];g.value=M.map(I=>{const z=d(I),H=N.findIndex(j=>j.key===z),O=H===-1?void 0:N.splice(H,1)[0];if(O)return O.warning=I,O;const R={id:p++,key:z,warning:I,detailsOpen:!1,copied:!1};return y(R.id,w(I)),S.value&&A(R.id),R});for(const I of N){b(I.id);const z=k.get(I.id);z&&clearTimeout(z),k.delete(I.id)}},{immediate:!0,flush:"post"}),_n(()=>{m.forEach(M=>{M.handle!==null&&clearTimeout(M.handle)}),m.clear(),k.forEach(M=>clearTimeout(M)),k.clear()}),(M,N)=>(v(),ce(pF,{name:"toast",tag:"div",class:Fe(["toasts",{"below-overlay":S.value}]),role:"status","aria-live":"polite"},{default:de(()=>[(v(!0),E(Ee,null,pt(g.value,I=>(v(),ce(f(FY),{key:I.id,variant:c(I.warning),title:r(I.warning),message:l(I.warning),"dismiss-label":f(o)("warnings.dismiss"),onDismiss:z=>L(I.id),onPointerenter:z=>A(I.id),onPointerleave:z=>T(I.id)},{default:de(()=>[a(I.warning)?.length?(v(),E("div",Mst,[C("button",{class:"link",type:"button",onClick:z=>x(I)},D(I.detailsOpen?f(o)("warnings.hideDetails"):f(o)("warnings.showDetails")),9,Ist),C("button",{class:"link",type:"button",onClick:z=>_(I)},D(I.copied?f(o)("warnings.copied"):f(o)("warnings.copyDetails")),9,Est)])):X("",!0),I.detailsOpen&&a(I.warning)?.length?(v(),E("dl",Tst,[(v(!0),E(Ee,null,pt(a(I.warning),z=>(v(),E("div",{key:`${z.label}:${z.value}`,class:"detail-row"},[C("dt",null,D(z.label),1),C("dd",null,D(z.value),1)]))),128))])):X("",!0)]),_:2},1032,["variant","title","message","dismiss-label","onDismiss","onPointerenter","onPointerleave"]))),128))]),_:1},8,["class"]))}}),Nst=kt(Lst,[["__scopeId","data-v-c225aa7a"]]),Fst={class:"topbar"},Dst=["aria-label"],Bst={key:0,class:"st","aria-hidden":"true"},$st={key:4,class:"unread-dot"},Rst={class:"tb-line"},zst={class:"tt"},Ost=Xe({__name:"MobileTopBar",props:{workspace:{default:null},sessionTitle:{default:""},status:{default:"idle"}},emits:["openSwitcher","openSettings"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t,s=F(()=>i.workspace?.name??n("workspace.noWorkspace"));return(r,l)=>(v(),E("div",Fst,[C("button",{type:"button",class:"tb-main","aria-label":f(n)("mobile.openSwitcher"),onClick:l[0]||(l[0]=a=>o("openSwitcher"))},[e.status!=="idle"?(v(),E("span",Bst,[e.status==="awaiting-approval"?(v(),ce(f(br),{key:0,variant:"warning",size:"sm"},{default:de(()=>[$e(D(f(n)("workspace.awaitingPermission")),1)]),_:1})):e.status==="awaiting-question"?(v(),ce(f(br),{key:1,variant:"info",size:"sm"},{default:de(()=>[$e(D(f(n)("workspace.awaitingAnswer")),1)]),_:1})):e.status==="running"?(v(),ce(f(Oi),{key:2,size:"sm"})):e.status==="aborted"?(v(),ce(f(br),{key:3,variant:"danger",size:"sm"},{default:de(()=>[$e(D(f(n)("workspace.aborted")),1)]),_:1})):e.status==="unread"?(v(),E("span",$st)):X("",!0)])):X("",!0),C("span",Rst,[C("span",{class:Fe(["dir",{solo:!e.sessionTitle}])},D(s.value),3),e.sessionTitle?(v(),E(Ee,{key:0},[l[2]||(l[2]=C("span",{class:"sl"},"/",-1)),C("span",zst,D(e.sessionTitle),1)],64)):X("",!0),U(f(ve),{class:"cv",name:"chevron-down",size:"sm"})])],8,Dst),U(f(Jt),{size:"lg",label:f(n)("mobile.openSettings"),onClick:l[1]||(l[1]=a=>o("openSettings"))},{default:de(()=>[U(f(ve),{name:"sliders",size:"lg"})]),_:1},8,["label"])]))}}),Pst=kt(Ost,[["__scopeId","data-v-58cf4cd3"]]),jst={class:"actions"},Hst={class:"view-tabs"},Wst={key:0,class:"mlist"},qst={key:0,class:"mempty"},Ust=["onClick"],Kst={class:"mgh-name"},Vst={class:"mgh-path"},Zst={key:2,class:"att"},Gst={key:0,class:"mempty small"},Qst=["onClick"],Yst={key:0,class:"att"},Jst={class:"time"},Xst={key:1,class:"mshow-more-row"},ert=["disabled","onClick"],trt={key:1,class:"mshow-more-sep","aria-hidden":"true"},nrt=["onClick"],irt={key:1,class:"mlist"},ort={key:0,class:"mempty"},srt=["onClick"],rrt={class:"srow-main"},lrt={class:"srow-sub"},art={key:0,class:"att"},urt={class:"time"},crt={key:1,class:"mshow-more-row"},drt=["disabled"],frt=Xe({__name:"MobileSwitcherSheet",props:{modelValue:{type:Boolean},groups:{},flatSessions:{},pinnedSessions:{},flatHasMore:{type:Boolean,default:!1},flatLoadingMore:{type:Boolean,default:!1},activeWorkspaceId:{default:null},activeId:{},attentionBySession:{default:()=>({})},attentionByWorkspace:{default:()=>({})}},emits:["update:modelValue","select","create","createInWorkspace","addWorkspace","rename","archive","deleteWorkspace","loadMore","ensureFlatSessions","loadMoreFlatSessions"],setup(e,{emit:t}){const{t:n}=zt(),i=e,o=t;function s(){o("update:modelValue",!1)}function r(j){o("select",j),s()}function l(j){o("createInWorkspace",j),s()}function a(){o("create"),s()}function u(){o("addWorkspace"),s()}const c=K(gce()),d=F(()=>[{value:"flat",label:n("mobile.viewFlat")},{value:"grouped",label:n("mobile.viewGrouped")}]);Pe(c,j=>mce(j)),Pe(()=>[i.modelValue,c.value],([j,$])=>{j&&$==="flat"&&o("ensureFlatSessions")},{immediate:!0});const h=F(()=>{const j=new Set,$=[];for(const W of[...i.flatSessions,...i.pinnedSessions])j.has(W.id)||(j.add(W.id),$.push(W));return $.sort((W,P)=>new Date(P.updatedAt??0).getTime()-new Date(W.updatedAt??0).getTime())}),p=F(()=>{const j=$=>$.sessions.length>0?new Date($.sessions[0].updatedAt??0).getTime():0;return i.groups.map(($,W)=>({g:$,index:W,ms:j($)})).sort(($,W)=>W.ms-$.ms||$.index-W.index).map($=>$.g)}),g=K(new Set);function m(j){return g.value.has(j)}function k(j){const $=new Set(g.value);$.has(j)?$.delete(j):$.add(j),g.value=$,L.value=null,z.value=null}const w=K(new Map);function y(j){return w.value.get(j.workspace.id)??j.initialCount}function b(j){const $=j.sessions.slice(0,y(j));if(i.activeId&&!$.some(W=>W.id===i.activeId)){const W=j.sessions.find(P=>P.id===i.activeId);if(W)return[...$,W]}return $}function A(j){return j.sessions.length>y(j)||j.hasMore||j.loadingMore}function T(j){return y(j)>j.initialCount}function S(j){const $=i.groups.find(Z=>Z.workspace.id===j);if(!$)return;const W=y($)+j6,P=new Map(w.value);P.set(j,W),w.value=P,$.sessions.length<W&&$.hasMore&&o("loadMore",j)}function x(j){if(!w.value.has(j))return;const $=new Map(w.value);$.delete(j),w.value=$}function _(j){return i.attentionByWorkspace[j]??0}const L=K(null);function M(j){L.value=L.value===j?null:j,z.value=null}function N(j){L.value=null;const W=(typeof window<"u"?window.prompt(n("sidebar.rename"),j.title):null)?.trim();W&&o("rename",j.id,W)}function I(j){L.value=null,o("archive",j)}const z=K(null);function H(j){z.value=z.value===j?null:j,L.value=null}function O(j){Xo(j.root),z.value=null}function R(j){z.value=null,o("deleteWorkspace",j.id)}return(j,$)=>(v(),ce(qh,{"model-value":e.modelValue,"onUpdate:modelValue":$[5]||($[5]=W=>o("update:modelValue",W))},{default:de(()=>[U(M$),C("div",jst,[C("button",{type:"button",class:"newrow",onClick:a},[U(f(ve),{name:"chat-new",size:"sm"}),$e(" "+D(f(n)("sidebar.newChat")),1)]),C("button",{type:"button",class:"newrow",onClick:u},[U(f(ve),{name:"folder",size:"sm"}),$e(" "+D(f(n)("sidebar.newWorkspace")),1)])]),C("div",Hst,[U(f(Vs),{modelValue:c.value,"onUpdate:modelValue":$[0]||($[0]=W=>c.value=W),options:d.value,size:"sm"},null,8,["modelValue","options"])]),c.value==="grouped"?(v(),E("div",Wst,[p.value.length===0?(v(),E("div",qst,D(f(n)("workspace.noWorkspace")),1)):X("",!0),(v(!0),E(Ee,null,pt(p.value,W=>(v(),E("div",{key:W.workspace.id,class:"mgroup"},[C("div",{class:Fe(["mgh",{on:W.workspace.id===e.activeWorkspaceId}]),onClick:P=>k(W.workspace.id)},[m(W.workspace.id)?(v(),ce(f(ve),{key:0,class:"mgh-folder",name:"folder-closed",size:"sm"})):(v(),ce(f(ve),{key:1,class:"mgh-folder",name:"folder",size:"sm"})),C("span",Kst,D(W.workspace.name),1),U(f(gn),{text:W.workspace.root},{default:de(()=>[C("span",Vst,D(W.workspace.shortPath),1)]),_:2},1032,["text"]),m(W.workspace.id)&&_(W.workspace.id)>0?(v(),E("span",Zst,D(_(W.workspace.id)),1)):X("",!0),U(f(Jt),{size:"lg",class:"mgh-more",label:f(n)("sidebar.options"),onClick:wt(P=>H(W.workspace.id),["stop"])},{default:de(()=>[U(f(ve),{name:"dots-horizontal",size:"md"})]),_:1},8,["label","onClick"]),U(f(Jt),{size:"lg",class:"mgh-add",label:f(n)("workspace.newInGroup"),onClick:wt(P=>l(W.workspace.id),["stop"])},{default:de(()=>[U(f(ve),{name:"chat-new",size:"md"})]),_:1},8,["label","onClick"]),z.value===W.workspace.id?(v(),ce(f(Zs),{key:3,class:"kmenu wsmenu",onClick:$[1]||($[1]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{size:"lg",onClick:P=>O(W.workspace)},{default:de(()=>[$e(D(f(n)("sidebar.copyPath")),1)]),_:1},8,["onClick"]),U(f(Ut),{size:"lg",danger:"",onClick:P=>R(W.workspace)},{default:de(()=>[$e(D(f(n)("sidebar.delete")),1)]),_:1},8,["onClick"])]),_:2},1024)):X("",!0)],10,Ust),Wn(C("div",null,[W.sessions.length===0?(v(),E("div",Gst,D(f(n)("sidebar.noSessions")),1)):X("",!0),(v(!0),E(Ee,null,pt(b(W),P=>(v(),E("div",{key:P.id,class:Fe(["srow",{cur:P.id===e.activeId}]),onClick:Z=>r(P.id)},[C("span",{class:Fe(["t",{run:P.busy,aborted:!P.busy&&(e.attentionBySession[P.id]??0)===0&&P.lastTurnReason==="failed"}])},D(P.title),3),(e.attentionBySession[P.id]??0)>0?(v(),E("span",Yst,D(e.attentionBySession[P.id]),1)):X("",!0),C("span",Jst,D(P.time),1),U(f(Jt),{size:"lg",class:"kb",label:f(n)("sidebar.options"),onClick:wt(Z=>M(P.id),["stop"])},{default:de(()=>[U(f(ve),{name:"dots-horizontal",size:"md"})]),_:1},8,["label","onClick"]),L.value===P.id?(v(),ce(f(Zs),{key:1,class:"kmenu",onClick:$[2]||($[2]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{size:"lg",onClick:Z=>N(P)},{default:de(()=>[$e(D(f(n)("sidebar.rename")),1)]),_:1},8,["onClick"]),U(f(Ut),{size:"lg",onClick:Z=>I(P.id)},{default:de(()=>[$e(D(f(n)("sidebar.archive")),1)]),_:1},8,["onClick"])]),_:2},1024)):X("",!0)],10,Qst))),128)),A(W)||T(W)?(v(),E("div",Xst,[A(W)?(v(),E("button",{key:0,type:"button",class:"mshow-more",disabled:W.loadingMore,onClick:wt(P=>S(W.workspace.id),["stop"])},[U(f(ve),{name:"chevron-down",size:"sm"}),$e(" "+D(W.loadingMore?f(n)("sidebar.loadingMore"):f(n)("sidebar.showMore")),1)],8,ert)):X("",!0),A(W)&&T(W)?(v(),E("span",trt,"·")):X("",!0),T(W)?(v(),E("button",{key:2,type:"button",class:"mshow-more",onClick:wt(P=>x(W.workspace.id),["stop"])},[U(f(ve),{name:"chevron-up",size:"sm"}),$e(" "+D(f(n)("sidebar.showLess")),1)],8,nrt)):X("",!0)])):X("",!0)],512),[[Po,!m(W.workspace.id)]])]))),128))])):(v(),E("div",irt,[h.value.length===0?(v(),E("div",ort,D(f(n)("sidebar.noSessions")),1)):X("",!0),(v(!0),E(Ee,null,pt(h.value,W=>(v(),E("div",{key:W.id,class:Fe(["srow srow-flat",{cur:W.id===e.activeId}]),onClick:P=>r(W.id)},[C("span",rrt,[C("span",{class:Fe(["t",{run:W.busy,aborted:!W.busy&&(e.attentionBySession[W.id]??0)===0&&W.lastTurnReason==="failed"}])},D(W.title),3),C("span",lrt,D(W.cwdLabel??"-"),1)]),(e.attentionBySession[W.id]??0)>0?(v(),E("span",art,D(e.attentionBySession[W.id]),1)):X("",!0),C("span",urt,D(W.time),1),U(f(Jt),{size:"lg",class:"kb",label:f(n)("sidebar.options"),onClick:wt(P=>M(W.id),["stop"])},{default:de(()=>[U(f(ve),{name:"dots-horizontal",size:"md"})]),_:1},8,["label","onClick"]),L.value===W.id?(v(),ce(f(Zs),{key:1,class:"kmenu",onClick:$[3]||($[3]=wt(()=>{},["stop"]))},{default:de(()=>[U(f(Ut),{size:"lg",onClick:P=>N(W)},{default:de(()=>[$e(D(f(n)("sidebar.rename")),1)]),_:1},8,["onClick"]),U(f(Ut),{size:"lg",onClick:P=>I(W.id)},{default:de(()=>[$e(D(f(n)("sidebar.archive")),1)]),_:1},8,["onClick"])]),_:2},1024)):X("",!0)],10,srt))),128)),e.flatHasMore?(v(),E("div",crt,[C("button",{type:"button",class:"mshow-more",disabled:e.flatLoadingMore,onClick:$[4]||($[4]=wt(W=>o("loadMoreFlatSessions"),["stop"]))},[U(f(ve),{name:"chevron-down",size:"sm"}),$e(" "+D(e.flatLoadingMore?f(n)("sidebar.loadingMore"):f(n)("sidebar.showMore")),1)],8,drt)])):X("",!0)]))]),_:1},8,["model-value"]))}}),hrt=kt(frt,[["__scopeId","data-v-38e26691"]]),prt={class:"group-title"},grt={class:"card"},mrt={class:"srow-main"},vrt={class:"srow-label"},yrt={class:"srow-sub"},krt={class:"srow read-only"},brt={class:"srow-main"},Art={class:"srow-label"},Crt={key:0,class:"srow-sub"},wrt=["aria-checked"],xrt={class:"srow-main"},Srt={class:"srow-label"},_rt={class:"srow-sub"},Mrt=["aria-checked"],Irt={class:"srow-main"},Ert={class:"srow-label"},Trt={class:"srow-sub"},Lrt={class:"srow-main"},Nrt={class:"srow-label"},Frt={class:"srow-sub"},Drt=["aria-checked"],Brt={class:"srow-main"},$rt={class:"srow-label"},Rrt={class:"srow-sub"},zrt={class:"srow-main"},Ort={class:"srow-label"},Prt={class:"srow read-only"},jrt={class:"srow-main"},Hrt={class:"srow-label"},Wrt={class:"srow-sub"},qrt=["aria-label"],Urt={class:"cache-note"},Krt={class:"group-title"},Vrt={class:"card"},Zrt={class:"srow read-only pref"},Grt={class:"srow-main"},Qrt={class:"srow-label"},Yrt={class:"srow read-only pref"},Jrt={class:"srow-main"},Xrt={class:"srow-label"},elt={class:"srow read-only pref"},tlt={class:"srow-main"},nlt={class:"srow-label"},ilt={key:0,class:"srow read-only"},olt={class:"srow-main"},slt={class:"srow-label"},rlt={class:"srow-val dim"},llt={class:"group-title"},alt={class:"card"},ult={class:"srow read-only acct-profile"},clt={class:"acct-avatar","aria-hidden":"true"},dlt=["src"],flt={class:"srow-main"},hlt={class:"acct-name-row"},plt={class:"srow-label"},glt={class:"srow-sub"},mlt={class:"srow-main"},vlt={class:"srow-label"},ylt={class:"srow-main"},klt={class:"srow-label"},blt={key:0,class:"usage"},Alt=Xe({__name:"MobileSettingsSheet",props:{modelValue:{type:Boolean},status:{},thinking:{},planMode:{type:Boolean},goalMode:{type:Boolean},goalActive:{type:Boolean},swarmMode:{type:Boolean},colorScheme:{default:"system"},fontScale:{default:"medium"},managedProviderStatus:{default:null},managedUserInfo:{default:null},serverVersion:{default:""},models:{default:()=>[]}},emits:["update:modelValue","pickModel","setThinking","togglePlan","toggleGoal","focusGoal","toggleSwarm","setPermission","setColorScheme","setFontScale","login","logout"],setup(e,{emit:t}){const{t:n}=zt(),{isConfirmOpen:i}=Vc(),o=pa(),s=e,r=t;function l(j){r("setColorScheme",j)}const a=["manual","yolo","auto"],u=F(()=>s.models?.find(j=>j.id===s.status?.modelId)),c=F(()=>u9(u.value)),d=F(()=>c9(u.value)),h=F(()=>E6(u.value,s.thinking)),p=F(()=>d.value.includes(h.value)?h.value:""),g=F(()=>d.value.map(j=>({value:j,label:zb(j)}))),m=F(()=>s.planMode===!0),k=F(()=>s.goalMode===!0);function w(){if(s.goalActive){r("focusGoal");return}!k.value&&m.value&&r("togglePlan"),r("toggleGoal")}function y(){!m.value&&k.value&&r("toggleGoal"),r("togglePlan")}const b=F(()=>s.swarmMode===!0),A=K(!1);Pe(()=>s.managedUserInfo?.avatar,()=>{A.value=!1});const T=F(()=>!!s.managedUserInfo?.avatar&&!A.value),S=F(()=>s.managedUserInfo?.userLevelName?.trim()??""),x=F(()=>s.managedProviderStatus==="authenticated"),_=F(()=>{const j=s.status.permission;return j==="auto"?"var(--color-danger)":j==="yolo"?"var(--color-warning)":"var(--color-text-muted)"}),L=F(()=>{const j=s.status.permission,$=n(j==="yolo"?"mobile.permYoloSub":j==="auto"?"mobile.permAutoSub":"mobile.permManualSub");return`${j} · ${$}`}),M=F(()=>s.status.ctxMax>0?Math.min(100,Math.max(0,Math.ceil(s.status.ctxUsed/s.status.ctxMax*100))):0),N=F(()=>s.status.ctxMax>0?`${_u(s.status.ctxUsed)}/${_u(s.status.ctxMax)}`:n("status.statusNone"));function I(j){r("setThinking",IB(u.value,j))}function z(){const j=a.indexOf(s.status.permission),$=a[(j+1)%a.length];r("setPermission",$)}function H(){r("pickModel"),r("update:modelValue",!1)}function O(){r("login"),r("update:modelValue",!1)}function R(){r("logout"),r("update:modelValue",!1)}return(j,$)=>(v(),ce(qh,{"model-value":e.modelValue,title:f(n)("mobile.settingsTitle"),"close-on-esc":!f(i),"onUpdate:modelValue":$[3]||($[3]=W=>r("update:modelValue",W))},{default:de(()=>[C("div",prt,D(f(n)("mobile.groupSession")),1),C("div",grt,[C("button",{type:"button",class:"srow",onClick:H},[C("span",mrt,[C("span",vrt,D(f(n)("status.statusModel")),1),C("span",yrt,D(e.status.model),1)]),$[4]||($[4]=C("span",{class:"chev"},"›",-1))]),C("div",krt,[C("span",brt,[C("span",Art,D(f(n)("status.statusThinking")),1),c.value==="unsupported"?(v(),E("span",Crt,D(f(n)("status.modeNotSupported")),1)):X("",!0)]),d.value.length>1?(v(),ce(f(Vs),{key:0,"model-value":p.value,options:g.value,size:"sm","onUpdate:modelValue":I},null,8,["model-value","options"])):(v(),E("span",{key:1,class:Fe(["srow-val",{dim:h.value==="off"}])},D(h.value==="off"?f(n)("status.planOff"):f(zb)(h.value)),3))]),C("button",{type:"button",class:"srow",role:"switch","aria-checked":m.value,onClick:y},[C("span",xrt,[C("span",Srt,D(f(n)("status.statusPlanMode")),1),C("span",_rt,D(f(n)("mobile.planModeSub")),1)]),C("span",{class:Fe(["toggle",{on:m.value}]),"aria-hidden":"true"},null,2)],8,wrt),e.goalActive?(v(),E("button",{key:1,type:"button",class:"srow",onClick:w},[C("span",Lrt,[C("span",Nrt,D(f(n)("status.goalLabel")),1),C("span",Frt,D(f(n)("mobile.goalModeSub")),1)]),U(f(ve),{class:"srow-chevron",name:"chevron-right",size:"sm","aria-hidden":"true"})])):(v(),E("button",{key:0,type:"button",class:"srow",role:"switch","aria-checked":k.value,onClick:w},[C("span",Irt,[C("span",Ert,D(f(n)("status.goalLabel")),1),C("span",Trt,D(f(n)("mobile.goalModeSub")),1)]),C("span",{class:Fe(["toggle",{on:k.value}]),"aria-hidden":"true"},null,2)],8,Mrt)),C("button",{type:"button",class:"srow",role:"switch","aria-checked":b.value,onClick:$[0]||($[0]=W=>r("toggleSwarm"))},[C("span",Brt,[C("span",$rt,D(f(n)("status.statusSwarmMode")),1),C("span",Rrt,D(f(n)("mobile.swarmModeSub")),1)]),C("span",{class:Fe(["toggle",{on:b.value}]),"aria-hidden":"true"},null,2)],8,Drt),C("button",{type:"button",class:"srow",onClick:z},[C("span",zrt,[C("span",Ort,D(f(n)("status.statusPermission")),1),C("span",{class:"srow-sub",style:Kt({color:_.value})},D(L.value),5)]),$[5]||($[5]=C("span",{class:"chev"},"›",-1))]),C("div",Prt,[C("span",jrt,[C("span",Hrt,D(f(n)("status.statusContext")),1),C("span",Wrt,D(N.value),1)]),C("span",{class:"ctx-meter","aria-label":N.value},[C("i",{style:Kt({width:M.value+"%"})},null,4)],8,qrt)])]),C("div",Urt,D(f(n)("status.cacheNote")),1),C("div",Krt,D(f(n)("mobile.groupApp")),1),C("div",Vrt,[C("div",Zrt,[C("span",Grt,[C("span",Qrt,D(f(n)("theme.colorSchemeLabel")),1)]),U(f(Vs),{"model-value":e.colorScheme??"system",options:[{value:"light",label:f(n)("theme.light"),icon:"light-mode"},{value:"dark",label:f(n)("theme.dark"),icon:"dark-mode"},{value:"system",label:f(n)("theme.system")}],"onUpdate:modelValue":l},null,8,["model-value","options"])]),C("div",Yrt,[C("span",Jrt,[C("span",Xrt,D(f(n)("sidebar.language")),1)]),U(FH)]),C("div",elt,[C("span",tlt,[C("span",nlt,D(f(n)("settings.uiFontSize")),1)]),U(f(Vs),{"model-value":e.fontScale,options:[{value:"small",label:"S"},{value:"medium",label:"M"},{value:"large",label:"L"},{value:"xlarge",label:"XL"}],"aria-label":f(n)("settings.uiFontSize"),"onUpdate:modelValue":$[1]||($[1]=W=>r("setFontScale",W))},null,8,["model-value","aria-label"])]),e.serverVersion?(v(),E("div",ilt,[C("span",olt,[C("span",slt,D(f(n)("settings.serverVersion")),1)]),C("span",rlt,D(e.serverVersion),1)])):X("",!0)]),C("div",llt,D(f(n)("mobile.groupAccount")),1),C("div",alt,[x.value?(v(),E(Ee,{key:0},[C("div",ult,[C("span",clt,[T.value?(v(),E("img",{key:0,src:e.managedUserInfo?.avatar,alt:"",onError:$[2]||($[2]=W=>A.value=!0)},null,40,dlt)):(v(),ce(f(ve),{key:1,name:"user",size:"md"}))]),C("span",flt,[C("span",hlt,[C("span",plt,D(e.managedUserInfo?.nickname||f(n)("sidebar.defaultUserName")),1),S.value?(v(),ce(f(br),{key:0,class:"acct-level",variant:"neutral",size:"sm"},{default:de(()=>[$e(D(S.value),1)]),_:1})):X("",!0)]),C("span",glt,D(f(n)("settings.signedIn")),1)])]),C("button",{type:"button",class:"srow acct out",onClick:R},[C("span",mlt,[C("span",vlt,D(f(n)("sidebar.signOut")),1)])])],64)):(v(),E("button",{key:1,type:"button",class:"srow acct in",onClick:O},[C("span",ylt,[C("span",klt,D(f(n)("sidebar.signIn")),1)])]))]),x.value&&e.modelValue?(v(),E("div",blt,[U($H,{"on-fetch-usage":f(o).getUsage},null,8,["on-fetch-usage"])])):X("",!0)]),_:1},8,["model-value","title","close-on-esc"]))}}),Clt=kt(Alt,[["__scopeId","data-v-65e9ffc0"]]),wlt={key:0,class:"ls-done-card"},xlt={class:"ls-done-badge"},Slt={class:"ls-card-text"},_lt={class:"ls-card-title"},Mlt={class:"ls-card-hint"},Ilt={key:1,class:"ls-cards"},Elt={class:"ls-card-icon"},Tlt={key:2,class:"ls-flow"},Llt={key:0,class:"ls-center"},Nlt={class:"ls-center-text"},Flt={key:1,class:"ls-device"},Dlt={class:"ls-hero"},Blt={class:"ls-hero-icon"},$lt={key:0,class:"ls-hero-title"},Rlt={class:"ls-hero-hint"},zlt={class:"ls-manual"},Olt={class:"ls-manual-label"},Plt={key:2,class:"ls-center"},jlt={class:"ls-center-text ls-success-text"},Hlt={class:"ls-center-hint"},Wlt={class:"ls-center"},qlt={class:"ls-center-text ls-err-text"},Ult={class:"ls-center-hint"},Klt={class:"ls-actions"},Vlt={class:"ls-center"},Zlt={class:"ls-center-text ls-warn-text"},Glt={class:"ls-center-hint"},Qlt={class:"ls-actions"},Ylt=Xe({__name:"OnboardingLoginStep",props:{authReady:{type:Boolean},onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function},onGetOAuthRegion:{type:Function}},emits:["success","addProvider"],setup(e,{emit:t}){const{t:n}=zt(),i=rg(),o=e,s=t,r=K("choice"),{step:l,pollError:a,flow:u,secondsLeft:c,autoOpenBlocked:d,startFlow:h,cancelFlow:p}=_$({onStartOAuthLogin:o.onStartOAuthLogin,onPollOAuthLogin:o.onPollOAuthLogin,onCancelOAuthLogin:o.onCancelOAuthLogin,onSuccess:()=>s("success"),autoOpen:bH(),authWake:AH()}),g=K(!1),m=[{region:"mainland-cn",titleKey:"onboarding.login.kimiCnTitle",hintKey:"onboarding.login.kimiCnHint"},{region:"global",titleKey:"onboarding.login.kimiOverseasTitle",hintKey:"onboarding.login.kimiOverseasHint"}],k={titleKey:"onboarding.login.kimiTitle",hintKey:"onboarding.login.kimiHint"},w=K("pending"),y=F(()=>LB(w.value,m,k));cn(()=>{o.onGetOAuthRegion?.().then(L=>{w.value=L===null?"unsupported":"supported"})});const b=F(()=>u.value?.verificationUriComplete??"");function A(L){r.value="flow",h(L)}function T(){p(),r.value="choice"}async function S(){!u.value||!await Xo(b.value)||(g.value=!0,setTimeout(()=>{g.value=!1},2e3))}function x(){MA(b.value)&&window.open(b.value,"_blank","noopener,noreferrer")}function _(L){const M=Math.floor(L/60),N=L%60;return`${M}:${String(N).padStart(2,"0")}`}return(L,M)=>e.authReady?(v(),E("div",wlt,[C("span",xlt,[U(f(ve),{name:"check",size:"sm"})]),C("div",Slt,[C("div",_lt,D(f(n)("onboarding.login.loggedInTitle")),1),C("div",Mlt,D(f(n)("onboarding.login.loggedInHint")),1)])])):r.value==="choice"?(v(),E("div",Ilt,[(v(!0),E(Ee,null,pt(y.value,N=>(v(),ce(f(cb),{key:N.region??"oauth",disabled:N.disabled,onSelect:I=>A(N.region)},{leading:de(()=>[U(n1,{size:40})]),hint:de(()=>[$e(D(f(n)(N.hintKey)),1)]),default:de(()=>[$e(" "+D(f(n)(N.titleKey))+" ",1)]),_:2},1032,["disabled","onSelect"]))),128)),f(i)?X("",!0):(v(),ce(f(cb),{key:0,onSelect:M[0]||(M[0]=N=>s("addProvider"))},{leading:de(()=>[C("span",Elt,[U(f(ve),{name:"bolt",size:"lg"})])]),hint:de(()=>[$e(D(f(n)("onboarding.login.customProviderHint")),1)]),default:de(()=>[$e(" "+D(f(n)("onboarding.login.customProviderTitle"))+" ",1)]),_:1}))])):(v(),E("div",Tlt,[f(l)==="starting"?(v(),E("div",Llt,[U(f(Oi),{size:"md"}),C("span",Nlt,D(f(n)("login.starting")),1)])):f(l)==="device-code"&&f(u)?(v(),E("div",Flt,[C("div",Dlt,[C("span",Blt,[U(n1,{size:48})]),f(d)?(v(),E("div",$lt,D(f(n)("login.blockedTitle")),1)):X("",!0),C("div",Rlt,D(f(d)?f(n)("login.blockedHint"):f(n)("login.openedHint",{time:_(f(c))})),1)]),f(d)?(v(),ce(f(Qt),{key:0,variant:"primary",onClick:x},{default:de(()=>[$e(D(f(n)("login.authorizeInBrowser"))+" ",1),U(f(ve),{name:"external-link",size:"sm"})]),_:1})):X("",!0),C("div",zlt,[C("span",Olt,[$e(D(f(n)("login.notOpened"))+" ",1),U(f(Qt),{variant:"text",class:Fe(["ls-copy-text",{"is-copied":g.value}]),onClick:S},{default:de(()=>[$e(D(g.value?f(n)("login.copied"):f(n)("login.copyLink")),1)]),_:1},8,["class"])])])])):f(l)==="success"?(v(),E("div",Plt,[U(f(Eh),{kind:"success"}),C("span",jlt,D(f(n)("login.success")),1),C("span",Hlt,D(f(n)("login.successHint")),1)])):f(l)==="expired"?(v(),E(Ee,{key:3},[C("div",Wlt,[U(f(Eh),{kind:"expired"}),C("span",qlt,D(f(n)("login.expiredTitle")),1),C("span",Ult,D(f(n)("login.expiredHint")),1)]),C("div",Klt,[U(f(Qt),{variant:"secondary",onClick:T},{default:de(()=>[$e(D(f(n)("onboarding.back")),1)]),_:1}),U(f(Qt),{variant:"primary",onClick:M[1]||(M[1]=N=>f(h)())},{default:de(()=>[$e(D(f(n)("login.retry")),1)]),_:1})])],64)):f(l)==="error"?(v(),E(Ee,{key:4},[C("div",Vlt,[U(f(Eh),{kind:"error"}),C("span",Zlt,D(f(a)?f(n)("login.pollErrorTitle"):f(n)("login.errorTitle")),1),C("span",Glt,D(f(a)?f(n)("login.pollErrorHint"):f(n)("login.errorHint")),1)]),C("div",Qlt,[U(f(Qt),{variant:"secondary",onClick:T},{default:de(()=>[$e(D(f(n)("onboarding.back")),1)]),_:1}),U(f(Qt),{variant:"primary",onClick:M[2]||(M[2]=N=>f(h)())},{default:de(()=>[$e(D(f(n)("login.retry")),1)]),_:1})])],64)):X("",!0)]))}}),Jlt=kt(Ylt,[["__scopeId","data-v-3875193b"]]),Xlt=["aria-label"],eat={class:"wiz-body"},tat={key:0,class:"wiz-step"},nat={class:"wiz-title"},iat={class:"wiz-sub"},oat={class:"pref-group"},sat={class:"pref-label"},rat={class:"lang-cards"},lat=["onClick"],aat={class:"opt-label"},uat={class:"pref-group"},cat={class:"pref-label"},dat={class:"theme-cards"},fat=["onClick"],hat={class:"opt-label"},pat={key:1,class:"wiz-step"},gat={class:"wiz-title"},mat={class:"wiz-sub"},vat={class:"wiz-step-fill"},yat={class:"wiz-foot"},kat={class:"wiz-foot-ghost"},bat=Xe({__name:"OnboardingWizard",props:{authReady:{type:Boolean},onStartOAuthLogin:{type:Function},onPollOAuthLogin:{type:Function},onCancelOAuthLogin:{type:Function},onGetOAuthRegion:{type:Function}},emits:["complete","loginSuccess","addProvider"],setup(e,{emit:t}){const{t:n,locale:i}=zt(),o=e,s=t;function r(){s("addProvider")}const l=["preferences","login"],a=K(0),u=F(()=>l[a.value]??"preferences");function c(){a.value<l.length-1&&a.value++}function d(){a.value>0&&a.value--}function h(w){i.value!==w&&n7(w)}const{colorScheme:p,setColorScheme:g}=c1(),m=[{value:"system",labelKey:"theme.system"},{value:"light",labelKey:"theme.light"},{value:"dark",labelKey:"theme.dark"}];function k(){s("loginSuccess")}return(w,y)=>(v(),E("div",{class:"wizard",role:"dialog","aria-modal":"true","aria-label":f(n)("onboarding.welcome.title")},[C("div",eat,[u.value==="preferences"?(v(),E("section",tat,[U(n1,{size:72}),C("h1",nat,D(f(n)("onboarding.welcome.title")),1),C("p",iat,D(f(n)("onboarding.welcome.subtitle")),1),C("div",oat,[C("div",sat,D(f(n)("onboarding.welcome.languageLabel")),1),C("div",rat,[(v(!0),E(Ee,null,pt(f(H2),b=>(v(),E("button",{key:b.code,class:Fe(["opt-card lang-card",{selected:f(i)===b.code}]),type:"button",onClick:A=>h(b.code)},[C("span",{class:Fe(["opt-radio",{on:f(i)===b.code}])},null,2),C("span",aat,D(b.label),1)],10,lat))),128))])]),C("div",uat,[C("div",cat,D(f(n)("onboarding.welcome.themeLabel")),1),C("div",dat,[(v(),E(Ee,null,pt(m,b=>C("button",{key:b.value,class:Fe(["opt-card theme-card",{selected:f(p)===b.value}]),type:"button",onClick:A=>f(g)(b.value)},[C("span",{class:Fe(["tp",`tp-${b.value}`]),"aria-hidden":"true"},[b.value==="system"?(v(),E(Ee,{key:0},[y[2]||(y[2]=$c('<span class="tp-half tp-half-light" data-v-0535eac0><span class="tp-side" data-v-0535eac0></span><span class="tp-lines" data-v-0535eac0><span data-v-0535eac0></span><span data-v-0535eac0></span><span data-v-0535eac0></span></span></span><span class="tp-half tp-half-dark" data-v-0535eac0><span class="tp-side" data-v-0535eac0></span><span class="tp-lines" data-v-0535eac0><span data-v-0535eac0></span><span data-v-0535eac0></span><span data-v-0535eac0></span></span></span>',2))],64)):(v(),E(Ee,{key:1},[y[3]||(y[3]=C("span",{class:"tp-side"},null,-1)),y[4]||(y[4]=C("span",{class:"tp-lines"},[C("span"),C("span"),C("span")],-1))],64))],2),C("span",hat,D(f(n)(b.labelKey)),1)],10,fat)),64))])])])):(v(),E("section",pat,[U(n1,{size:72}),C("h1",gat,D(f(n)("onboarding.login.title")),1),C("p",mat,D(f(n)("onboarding.login.subtitle")),1),C("div",vat,[U(Jlt,{"auth-ready":o.authReady,"on-start-o-auth-login":o.onStartOAuthLogin,"on-poll-o-auth-login":o.onPollOAuthLogin,"on-cancel-o-auth-login":o.onCancelOAuthLogin,"on-get-o-auth-region":o.onGetOAuthRegion,onSuccess:k,onAddProvider:r},null,8,["auth-ready","on-start-o-auth-login","on-poll-o-auth-login","on-cancel-o-auth-login","on-get-o-auth-region"])])])),C("div",yat,[u.value==="preferences"?(v(),ce(f(Qt),{key:0,variant:"primary",size:"lg",class:"wiz-primary",onClick:c},{default:de(()=>[$e(D(f(n)("onboarding.continue")),1)]),_:1})):u.value==="login"&&o.authReady?(v(),ce(f(Qt),{key:1,variant:"primary",size:"lg",class:"wiz-primary",onClick:y[0]||(y[0]=b=>s("complete"))},{default:de(()=>[$e(D(f(n)("onboarding.login.finish")),1)]),_:1})):X("",!0),C("div",kat,[a.value>0?(v(),ce(f(Qt),{key:0,variant:"ghost",onClick:d},{default:de(()=>[$e(D(f(n)("onboarding.back")),1)]),_:1})):X("",!0),u.value==="login"&&o.authReady?X("",!0):(v(),ce(f(Qt),{key:1,variant:"ghost",onClick:y[1]||(y[1]=b=>s("complete"))},{default:de(()=>[$e(D(u.value==="login"?f(n)("onboarding.login.skip"):f(n)("onboarding.skip")),1)]),_:1}))])])])],8,Xlt))}}),Aat=kt(bat,[["__scopeId","data-v-0535eac0"]]),Cat=["aria-label"],wat={class:"gload-box"},xat={class:"gload-text"},Sat=Xe({__name:"GlobalLoading",setup(e){const{t}=zt();return(n,i)=>(v(),E("div",{class:"gload",role:"status","aria-label":f(t)("app.connecting")},[C("div",wat,[i[0]||(i[0]=$c('<svg class="gload-logo" viewBox="0 0 96 32" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" data-v-ab85ede1><path fill="currentColor" d="M35.767 31.329c0 .37.3.671.67.671h4.305c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.672-.671h-4.304c-.37 0-.671.3-.671.671z" data-v-ab85ede1></path><path fill="currentColor" d="M90.353 31.329c0 .37.3.671.67.671h4.305c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.672-.671h-4.304a.67.67 0 0 0-.671.671z" data-v-ab85ede1></path><path fill="currentColor" d="M73.256 0a.67.67 0 0 0-.652.512l-6.366 26.1c-.106.428-.607.428-.71 0L59.159.512A.67.67 0 0 0 58.511 0H47.725c-.37 0-.668.3-.668.671V31.33c0 .37.3.671.67.671h4.781c.37 0 .671-.292.671-.662V5.554c0-.515.604-.622.726-.127l6.358 26.06a.67.67 0 0 0 .653.513h9.931c.31 0 .58-.212.653-.512L77.855 5.43c.122-.495.726-.388.726.127v25.772c0 .37.3.671.671.671h4.78c.371 0 .672-.3.672-.671V.67c0-.37-.3-.671-.671-.671z" data-v-ab85ede1></path><path fill="currentColor" d="M15.279 14.837 28.264 1.133A.671.671 0 0 0 27.777 0h-6.043a.67.67 0 0 0-.477.199L6.374 15.223c-.231.234-.573.025-.573-.35V.672c0-.37-.3-.671-.671-.671H.67a.67.67 0 0 0-.67.67V31.33c0 .37.3.671.671.671H5.13c.37 0 .671-.3.671-.671v-6.114a.5.5 0 0 1 .13-.35l4.594-4.69a.293.293 0 0 1 .386-.045l12.286 9.305c1.796 1.245 4.083 2.06 6.178 2.401a.645.645 0 0 0 .743-.648v-5.537a.7.7 0 0 0-.562-.677c-1.215-.262-2.565-.758-3.59-1.468L15.332 15.58c-.22-.152-.248-.544-.052-.744" data-v-ab85ede1></path></svg>',1)),U(f(Oi),{size:"md",label:f(t)("app.connecting")},null,8,["label"]),C("div",xat,D(f(t)("app.connecting")),1)])],8,Cat))}}),_at=kt(Sat,[["__scopeId","data-v-ab85ede1"]]),Mat={class:"kap-root"},Iat={class:"kap-head"},Eat={class:"kap-count"},Tat={class:"kap-head-actions"},Lat={class:"kap-filters"},Nat=["value"],Fat={class:"kap-check"},Dat={class:"kap-check"},Bat={class:"kap-view-toggle",role:"group"},$at={key:0,class:"kap-empty"},Rat=["onClick"],zat={class:"kap-ts"},Oat={class:"kap-label"},Pat={key:0,class:"kap-detail"},jat={class:"kap-detail-actions"},Hat=["onClick"],Wat={key:1,class:"kap-agg"},qat={class:"mono"},Uat={class:"mono"},Kat={class:"num"},Vat={class:"num"},Zat={key:0},Gat={class:"mono"},Qat={class:"num"},Yat={class:"num"},Jat={key:0},Xat=Xe({__name:"KapDebugView",emits:["close"],setup(e,{emit:t}){const n=t,i=K("all"),o=K(""),s=K(""),r=K(!1),l=K("timeline"),a=F(()=>(o7.value,[...P8e()])),u=F(()=>{const L=new Set;for(const M of a.value)M.sessionId&&L.add(M.sessionId);return[...L].sort()});function c(L){return L.kind==="rest:error"||L.code!==void 0&&L.code!==0||L.eventType==="error"||L.eventType==="parse-error"}const d=F(()=>{const L=o.value.trim().toLowerCase();return a.value.filter(M=>!(i.value!=="all"&&M.source!==i.value||s.value&&M.sessionId!==s.value||r.value&&!c(M)||L&&!`${M.label} ${M.kind} ${M.eventType??""} ${M.sessionId??""} ${M.requestId??""}`.toLowerCase().includes(L)))}),h=F(()=>{const L=new Map;for(const M of d.value){if(M.kind!=="ws:in"&&M.kind!=="ws:out")continue;const N=M.kind==="ws:in"?"←":"→",I=`${N} ${M.eventType??"?"} @ ${M.sessionId??"-"}`,z=L.get(I)??{key:I,sessionId:M.sessionId??"-",eventType:M.eventType??"?",dir:N,count:0};z.count++,M.seq!==void 0&&(z.lastSeq=M.seq),L.set(I,z)}return[...L.values()].sort((M,N)=>N.count-M.count)}),p=F(()=>{const L=new Map;for(const M of d.value){if(M.source!=="rest"||M.kind==="rest:request")continue;const N=`${M.method??"?"} ${M.path??"?"}`,I=L.get(N)??{count:0,errors:0,totalMs:0,timed:0};I.count++,c(M)&&I.errors++,M.durationMs!==void 0&&(I.totalMs+=M.durationMs,I.timed++),L.set(N,I)}return[...L.entries()].map(([M,N])=>({key:M,count:N.count,errors:N.errors,avgMs:N.timed>0?Math.round(N.totalMs/N.timed):0})).sort((M,N)=>N.count-M.count)}),g=K(null),m=K(!0),k=K(null),w=K(null);Pe(()=>d.value.length,async()=>{if(!m.value||l.value!=="timeline")return;await dt();const L=k.value;L&&(L.scrollTop=L.scrollHeight)});function y(L){g.value=g.value===L?null:L}function b(L){const M=new Date(L),N=(I,z=2)=>String(I).padStart(z,"0");return`${N(M.getHours())}:${N(M.getMinutes())}:${N(M.getSeconds())}.${N(M.getMilliseconds(),3)}`}function A(L){return JSON.stringify(L,null,2)}async function T(L){await Xo(A(L))&&(w.value=L.id,setTimeout(()=>{w.value===L.id&&(w.value=null)},1500))}function S(){_R(d.value)}function x(L){return c(L)||L.source==="client"?"b-err":L.source==="rest"?"b-rest":L.kind==="ws:lifecycle"?"b-life":L.kind==="ws:out"?"b-out":"b-in"}function _(L){return L.source==="rest"?"REST":L.source==="client"?"APP":"WS"}return(L,M)=>(v(),E("section",Mat,[C("header",Iat,[M[11]||(M[11]=C("strong",null,"KAP debug",-1)),C("span",Eat,D(d.value.length)+"/"+D(a.value.length),1),C("div",Tat,[C("button",{type:"button",class:Fe({on:f(Ap)}),onClick:M[0]||(M[0]=N=>Ap.value=!f(Ap))},D(f(Ap)?"resume":"pause"),3),C("button",{type:"button",onClick:M[1]||(M[1]=N=>f(j8e)())},"clear"),C("button",{type:"button",onClick:M[2]||(M[2]=N=>S())},"export jsonl"),U(f(gn),{text:"Close window"},{default:de(()=>[C("button",{type:"button",onClick:M[3]||(M[3]=N=>n("close"))},"✕")]),_:1})])]),C("div",Lat,[Wn(C("select",{"onUpdate:modelValue":M[4]||(M[4]=N=>i.value=N),"aria-label":"Source filter"},[...M[12]||(M[12]=[C("option",{value:"all"},"rest + ws + app",-1),C("option",{value:"rest"},"rest",-1),C("option",{value:"ws"},"ws",-1),C("option",{value:"client"},"app errors",-1)])],512),[[ub,i.value]]),Wn(C("select",{"onUpdate:modelValue":M[5]||(M[5]=N=>s.value=N),"aria-label":"Session filter"},[M[13]||(M[13]=C("option",{value:""},"all sessions",-1)),(v(!0),E(Ee,null,pt(u.value,N=>(v(),E("option",{key:N,value:N},D(N),9,Nat))),128))],512),[[ub,s.value]]),Wn(C("input",{"onUpdate:modelValue":M[6]||(M[6]=N=>o.value=N),type:"text",placeholder:"filter (type / path / id)","aria-label":"Text filter"},null,512),[[Bs,o.value]]),C("label",Fat,[Wn(C("input",{"onUpdate:modelValue":M[7]||(M[7]=N=>r.value=N),type:"checkbox"},null,512),[[f2,r.value]]),M[14]||(M[14]=$e(" errors",-1))]),C("label",Dat,[Wn(C("input",{"onUpdate:modelValue":M[8]||(M[8]=N=>m.value=N),type:"checkbox"},null,512),[[f2,m.value]]),M[15]||(M[15]=$e(" follow",-1))]),C("div",Bat,[C("button",{type:"button",class:Fe({on:l.value==="timeline"}),onClick:M[9]||(M[9]=N=>l.value="timeline")},"timeline",2),C("button",{type:"button",class:Fe({on:l.value==="aggregate"}),onClick:M[10]||(M[10]=N=>l.value="aggregate")},"aggregate",2)])]),l.value==="timeline"?(v(),E("div",{key:0,ref_key:"listRef",ref:k,class:"kap-list"},[d.value.length===0?(v(),E("div",$at," No trace entries yet. REST calls and WS frames will appear here. ")):X("",!0),(v(!0),E(Ee,null,pt(d.value,N=>(v(),E("div",{key:N.id,class:"kap-row-wrap"},[C("button",{type:"button",class:Fe(["kap-row",{expanded:g.value===N.id}]),onClick:I=>y(N.id)},[C("span",zat,D(b(N.ts)),1),C("span",{class:Fe(["kap-badge",x(N)])},D(_(N)),3),C("span",Oat,D(N.label),1)],10,Rat),g.value===N.id?(v(),E("div",Pat,[C("div",jat,[C("button",{type:"button",onClick:I=>T(N)},D(w.value===N.id?"copied ✓":"copy json"),9,Hat)]),C("pre",null,D(A(N)),1)])):X("",!0)]))),128))],512)):(v(),E("div",Wat,[M[20]||(M[20]=C("h4",null,"WS frames by session / type",-1)),C("table",null,[M[17]||(M[17]=C("thead",null,[C("tr",null,[C("th",null,"dir"),C("th",null,"type"),C("th",null,"session"),C("th",null,"count"),C("th",null,"last seq")])],-1)),C("tbody",null,[(v(!0),E(Ee,null,pt(h.value,N=>(v(),E("tr",{key:N.key},[C("td",null,D(N.dir),1),C("td",qat,D(N.eventType),1),C("td",Uat,D(N.sessionId),1),C("td",Kat,D(N.count),1),C("td",Vat,D(N.lastSeq??"—"),1)]))),128)),h.value.length===0?(v(),E("tr",Zat,[...M[16]||(M[16]=[C("td",{colspan:"5",class:"kap-empty"},"no ws frames",-1)])])):X("",!0)])]),M[21]||(M[21]=C("h4",null,"REST by endpoint",-1)),C("table",null,[M[19]||(M[19]=C("thead",null,[C("tr",null,[C("th",null,"endpoint"),C("th",null,"count"),C("th",null,"errors"),C("th",null,"avg ms")])],-1)),C("tbody",null,[(v(!0),E(Ee,null,pt(p.value,N=>(v(),E("tr",{key:N.key},[C("td",Gat,D(N.key),1),C("td",Qat,D(N.count),1),C("td",{class:Fe(["num",{err:N.errors>0}])},D(N.errors),3),C("td",Yat,D(N.avgMs),1)]))),128)),p.value.length===0?(v(),E("tr",Jat,[...M[18]||(M[18]=[C("td",{colspan:"4",class:"kap-empty"},"no rest calls",-1)])])):X("",!0)])])]))]))}}),eut=kt(Xat,[["__scopeId","data-v-2b13888e"]]),tut=Xe({__name:"DebugPanel",setup(e){const t=K(!1);let n=null,i=null,o=null;const s=["data-color-scheme"];function r(c){const d=document.documentElement,h=c.documentElement;for(const p of s){const g=d.getAttribute(p);g!==null?h.setAttribute(p,g):h.removeAttribute(p)}}function l(c){const d=c.document;d.title="KAP debug";const h=d.createElement("base");h.href=location.href,d.head.appendChild(h);for(const g of Array.from(document.querySelectorAll('style, link[rel="stylesheet"]')))d.head.appendChild(g.cloneNode(!0));r(d),d.body.style.margin="0";const p=d.createElement("div");return p.style.height="100vh",d.body.appendChild(p),p}function a(){o?.disconnect(),o=null;try{i?.unmount()}catch{}i=null,n=null,t.value=!1}function u(){if(n&&!n.closed){n.focus();return}const c=window.open("","kap-debug","popup=yes,width=1040,height=760");if(!c)return;n=c;const d=l(c),h=h2(eut,{onClose:()=>c.close()});h.mount(d),i=h,t.value=!0,o=new MutationObserver(()=>{n&&!n.closed&&r(n.document)}),o.observe(document.documentElement,{attributes:!0,attributeFilter:[...s]}),c.addEventListener("pagehide",a),c.addEventListener("beforeunload",a)}return cn(()=>{u()}),Hn(()=>{n&&!n.closed&&n.close(),a()}),(c,d)=>(v(),ce(f(gn),{text:t.value?"Focus KAP debug window":"Open KAP debug window"},{default:de(()=>[C("button",{class:"kap-fab",type:"button",onClick:u}," KAP ")]),_:1},8,["text"]))}}),nut=kt(tut,[["__scopeId","data-v-21de79fc"]]),iut=Xe({__name:"ServerAuthDialog",setup(e){const t=K(""),n=K(null),i=K(!1);cn(()=>{dt(()=>n.value?.focus())});function o(){const r=t.value;!r||i.value||(i.value=!0,UB(r),window.location.reload())}function s(r){r.key==="Enter"&&(r.preventDefault(),o())}return(r,l)=>(v(),ce(f(Pc),{open:!0,title:"Server token required","hide-close":!0,"close-on-overlay":!1,"close-on-esc":!1},{foot:de(()=>[U(f(Qt),{variant:"primary",disabled:!t.value||i.value,loading:i.value,onClick:o},{default:de(()=>[$e(D(i.value?"Connecting…":"Connect"),1)]),_:1},8,["disabled","loading"])]),default:de(()=>[l[1]||(l[1]=C("p",{class:"server-auth-hint"},[$e(" This server is protected. Enter the bearer token printed when the server started (or the password set via "),C("code",null,"KIMI_CODE_PASSWORD"),$e("). ")],-1)),U(f(Ns),{ref_key:"inputRef",ref:n,modelValue:t.value,"onUpdate:modelValue":l[0]||(l[0]=a=>t.value=a),type:"password",autocomplete:"current-password",placeholder:"Token",disabled:i.value,onKeydown:s},null,8,["modelValue","disabled"])]),_:1}))}}),out=kt(iut,[["__scopeId","data-v-331563ff"]]),sut=["aria-label"],rut=Xe({__name:"InternalBuildBanner",setup(e){const{t}=zt(),n=bf;return(i,o)=>f(n)?(v(),E("span",{key:0,class:"internal-build-tag",role:"note","aria-label":f(t)("app.internalBuildBanner")},[o[0]||(o[0]=C("svg",{viewBox:"0 0 16 16",width:"11",height:"11",fill:"none",stroke:"currentColor","stroke-width":"1.7","stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true"},[C("path",{d:"M8 2 14 13H2L8 2Z"}),C("path",{d:"M8 6v3.5"}),C("path",{d:"M8 11.5h.01"})],-1)),C("span",null,D(f(t)("app.internalBuildBanner")),1)],8,sut)):X("",!0)}}),lut=kt(rut,[["__scopeId","data-v-14c3d0e0"]]),aut={class:"app-shell"},uut=["inert"],cut=["aria-label","aria-hidden"],dut=Xe({__name:"App",setup(e){eae();const t=K(!1);let n=null;const i=pa(),o=F(()=>!i.dangerousBypassAuth.value&&t.value);oi("resolveImage",i.resolveImageUrl),oi("resolveSwarmMembers",ot=>i.swarmMembersByToolCallId.value.get(ot)??[]),oi("modelDisplay",ot=>jre(ot,i.models.value));const{t:s}=zt();oi("subagentEffort",ot=>Hre(ot));const{confirm:r}=Vc(),l=ga(),a=rg(),u=K(!1),c=K(!1),d=F(()=>{const ot=i.activeSessionId.value;return i.sessions.value.find(xe=>xe.id===ot)?.title??""}),h=F(()=>{const ot=i.activeSessionId.value;return!!ot&&i.pinnedSessionIds.value.includes(ot)}),p=K(null);function g(ot){i.pinnedSessionIds.value.includes(ot)||p.value?.revealPinnedSection(),i.togglePinSession(ot)}const m=F(()=>{const ot=i.activeSessionId.value;return i.sessions.value.find(xe=>xe.id===ot)?.lastTurnReason??null}),k=F(()=>i.activity.value!=="idle"),w=F(()=>{const ot=i.activeSessionId.value,xe=i.sessions.value.find(je=>je.id===ot);return og({busy:xe?.busy??!1,unread:i.unreadBySession.value[ot??""]??!1,questionCount:i.questions.value.length,approvalCount:i.pendingApprovals.value.length,pendingInteraction:xe?.pendingInteraction,lastTurnReason:m.value??void 0})});tfe({running:k,title:i.documentBaseTitle});const y=F(()=>{const ot=i.models.value.find(xe=>xe.id===i.status.value.modelId);return E6(ot,i.thinking.value)}),b=K(!i.onboarded.value);function A(){i.setOnboarded(!0),b.value=!1}function T(){A(),yi.value="providers",Tn.value=!0}function S(){yi.value="archived",Tn.value=!0}let x=0;function _(){const ot=window.visualViewport,xe=document.documentElement.style;xe.setProperty("--app-height",`${ot?.height??window.innerHeight}px`),xe.setProperty("--app-top",`${ot?.offsetTop??0}px`)}function L(){x||(x=requestAnimationFrame(()=>{x=0,_()}))}zce(()=>i.getOAuthRegion());function M(){u8(()=>i.getOAuthRegion())}cn(()=>{n=oae(()=>{t.value=!0,i.clearDangerousBypassAuth()}),i.load(),M(),Ae(),_(),window.visualViewport?.addEventListener("resize",L),window.visualViewport?.addEventListener("scroll",L),window.addEventListener("resize",L),document.addEventListener("keydown",N,!0),uH()}),_n(()=>{document.removeEventListener("keydown",N,!0),window.visualViewport?.removeEventListener("resize",L),window.visualViewport?.removeEventListener("scroll",L),window.removeEventListener("resize",L),x&&(cancelAnimationFrame(x),x=0),document.documentElement.style.removeProperty("--app-height"),document.documentElement.style.removeProperty("--app-top"),n!==null&&(n(),n=null)});function N(ot){ot.key==="Escape"&&(cH(ot)||Io.value||ot.defaultPrevented||Yn()&&(ot.stopImmediatePropagation(),ot.preventDefault()))}const I=K(null),{previewTarget:z,previewFile:H,previewLoading:O,previewError:R,previewDownloadUrl:j,previewExternalActions:$,openFilePreview:W,closeFilePreview:P,openPreviewInEditor:Z,revealPreviewFile:ae}=Yde({client:i,detailTarget:I,t:(ot,xe)=>xe===void 0?s(ot):s(ot,xe)}),V=F(()=>I.value!==null);cn(()=>{const ot=M$e({resolveSkill:xe=>i.skills.value.find(je=>je.name===xe)??null,openPath:xe=>void W(xe),openSkillLabel:()=>s("mention.openSkill"),copyPathLabel:()=>s("mention.copyPath"),probePath:(xe,je)=>i.probeWorkspacePath(xe,je),skillsLoaded:()=>i.skillsLoaded.value,probeScope:()=>i.activeSessionId.value||i.activeWorkspaceId.value});_n(ot)});const Y=K(null),oe=K(null);function q(ot){oe.value=ot.originImg??null,Y.value=ot.media}const{SIDEBAR_WIDTH_KEY:ne,SIDEBAR_DEFAULT:ie,SIDEBAR_MIN:pe,sidebarMax:Ne,sessionColWidth:te,sidebarCollapsed:be,sidebarDragging:Q,sideWidth:ue,loadSidebarCollapsed:Ae,toggleSidebarCollapse:se}=Gde({previewOpen:V}),{PREVIEW_WIDTH_KEY:re,PREVIEW_MIN:G,previewDefaultWidth:le,previewMax:ge,previewWidth:ke,previewPanelWidth:Ie,compactionPanelText:Oe,compactionPanelVisible:we,openCompactionPanel:Be,closeCompactionPanel:tt,agentPanelMember:ut,agentPanelTurns:_t,agentPanelLoading:Ct,agentPanelLoadError:$t,agentPanelLoadingMore:Vt,agentPanelLoadMoreError:nn,agentPanelHasMore:gt,agentPanelRunning:Le,openAgentPanel:ze,closeAgentPanel:Ye,loadOlderAgentMessages:Tt,detailDiffMode:on,detailDiffPath:jt,openDiffDetail:kn,closeDiffDetail:bn,selectDiffFile:mn,turnDiffChange:zn,openTurnDiff:He,closeTurnDiff:st,btwVisible:et,openSideChatTab:Nt,closeSideChat:Lt,sidePanelVisible:qn,panelDragging:So,closeOpenSidePanel:Yn}=Ude({client:i,sideWidth:ue,detailTarget:I,closeFilePreview:P}),Ir=K(null);function _o(ot){Ir.value?.style.setProperty("--preview-w",`${ot}px`)}Pe([Ir,Ie],([ot,xe])=>ot?.style.setProperty("--preview-w",`${xe}px`),{immediate:!0});const It=K(null),ms=K(null);function Er(){let ot=!1;const xe=je=>{je instanceof KeyboardEvent&&je.repeat||(ot=!0)};return document.addEventListener("pointerdown",xe,!0),document.addEventListener("keydown",xe,!0),window.addEventListener("blur",xe),document.addEventListener("visibilitychange",xe),()=>{dt(()=>{document.removeEventListener("pointerdown",xe,!0),document.removeEventListener("keydown",xe,!0),window.removeEventListener("blur",xe),document.removeEventListener("visibilitychange",xe),!ot&&document.hasFocus()&&(a.value||Io.value||ms.value?.focusInput())})}}const go=F(()=>{const ot=i.goal.value?.status;return ot==="active"||ot==="paused"||ot==="blocked"});function mo(){c.value=!1,It.value?.focusGoal()}const vs=K(!1),_i=K(!1),Mo=K(!1),ys=K(!1),Tn=K(!1);let Un;cn(()=>{Un=window.kimiDesktop?.onMenuAction?.(ot=>{ot==="open-settings"?Tn.value=!0:ot==="new-chat"&&oo()})}),_n(()=>{Un?.()});const Kn=K(null),Pi=K(null),Io=F(()=>Fs.value>0||vs.value||_i.value||Mo.value||ys.value||Tn.value||b.value||u.value||c.value),Ki=K(!1),Ti=K(!1),Qs=K(!1);async function Li(){Ki.value=!0,Ti.value=!1,vs.value=!0;try{await i.refreshAllProviders()}catch{Ti.value=!0}finally{Ki.value=!1}}function an(){_i.value=!0}async function to(){await r({title:s("sidebar.logoutConfirmTitle"),message:s("sidebar.logoutConfirmMessage"),variant:"danger",action:async()=>{await i.logout(),M()}})}async function Jn(ot){vs.value=!1,await Wo(ot)}async function Wo(ot){await i.setModel(ot)&&ot!==i.defaultModel.value&&i.updateConfig({defaultModel:ot})}const Mn=K(null);let Ni=0;const wi=K(null);async function $o(ot,xe){if(!(xe.length===0||wi.value!==null)){wi.value=ot;try{const je=ot==="archive"?await i.archiveSessions(xe):await i.restoreSessions(xe),Dn=PL(ot,je);if(Dn===null){i.notify({severity:"error",title:s(ot==="archive"?"admin.batchDoneFailedNotice":"admin.batchReopenFailedNotice",{n:je.failed})});return}Mn.value={kind:"adminBatch",plan:Dn,key:++Ni}}finally{wi.value=null}}}async function $s(){const ot=Mn.value;if(!ot||ot.kind!=="adminBatch")return;const xe=IYe(ot.plan.direction),je=xe==="archive"?await i.archiveSessions(ot.plan.ids):await i.restoreSessions(ot.plan.ids),Dn=PL(xe,je);Dn!==null&&Mn.value?.key===ot.key&&(Mn.value={kind:"adminBatch",plan:Dn,key:++Ni})}async function Vi(ot){await i.archiveSession(ot),!i.sessionsForView.value.some(xe=>xe.id===ot)&&(Mn.value={kind:"archive",id:ot,key:++Ni})}async function Cn(ot){await i.restoreSession(ot)&&(Mn.value={kind:"archive",id:ot,reopen:!0,key:++Ni})}let Rs=!1;async function qo(ot){if(Rs)return;Rs=!0;const xe=++Ni,je=setTimeout(()=>{(Mn.value===null||Mn.value.key<=xe)&&(Mn.value={kind:"export",state:"running",key:xe})},400);try{await i.exportSession(ot)&&!bf?(Mn.value===null||Mn.value.key<=xe)&&(Mn.value={kind:"export",state:"done",key:++Ni}):Mn.value?.kind==="export"&&Mn.value.key===xe&&(Mn.value=null)}finally{clearTimeout(je),Rs=!1}}async function ar(){const ot=Mn.value;if(!(!ot||ot.kind!=="archive")){if(ot.reopen){if(await i.archiveSession(ot.id),i.sessionsForView.value.some(xe=>xe.id===ot.id)||Mn.value?.key!==ot.key)return;Mn.value={kind:"archive",id:ot.id,key:++Ni};return}await i.restoreSession(ot.id)&&Mn.value?.key===ot.key&&(Mn.value=null)}}function ks(ot){ot!==void 0&&Mn.value?.key===ot&&(Mn.value=null)}const yi=K(void 0),{sidebarTabs:Vn}=d1();async function ji(ot){const xe=i.workspacesView.value.find(je=>je.id===ot)?.name??ot;await r({title:s("sidebar.removeWorkspace"),message:s("workspace.removeWorkspaceConfirm",{name:xe}),variant:"danger",action:()=>i.deleteWorkspace(ot)})}async function Fi(ot){Qs.value=!0;try{await i.updateConfig(ot)&&await i.checkAuth()}finally{Qs.value=!1}}async function bs(ot){return i.startOAuthLogin(ot)}async function As(){return i.pollOAuthLogin()}async function Eo(){return i.cancelOAuthLogin()}async function Tr(){return i.getOAuthRegion()}async function Lr(){_i.value=!1,await i.checkAuth(),await i.load(),M()}async function jl(){A(),await i.checkAuth(),await i.load(),M()}async function Nr(ot){const xe=i.activeSessionId.value;await i.undo(1)!==null&&(xe&&(i.invalidateSessionPlans(xe),i.refreshSessionPlans(xe)),await dt(),It.value?.loadComposerForEdit(ot.text,ot.attachments),It.value?.notifyUndone())}async function Di(){const ot=await i.abortCurrentPrompt();It.value?.onAbortOutcome(ot)}function Xn(ot){const xe=Ic();return ot.map(je=>P6(xe,je))}async function Cs(ot,xe,je){if(i.authReady.value)return!0;const Dn=i.managedProviderStatus.value==="authenticated";Dn&&i.managedMembership.value===null&&await i.probeManagedMembership();const vn=Dn&&i.managedMembership.value==="free",ii=await r(vn?{title:s("login.upgradeRequiredTitle"),message:s("login.upgradeRequiredMessage"),confirmLabel:s("sidebar.upgrade"),variant:"primary"}:{title:s("login.requiredTitle"),message:s("login.requiredMessage"),confirmLabel:s("login.goToLogin"),variant:"primary"});return It.value?.loadComposerForEdit(je??ot,Xn(xe)),ii&&(vn?sg():an()),!1}async function Uo(ot,xe=[],je){if(i.activeSessionId.value||i.activeWorkspaceId.value)return!0;const Dn=await r({title:s("workspace.requiredTitle"),message:s("workspace.requiredMessage"),confirmLabel:s("conversation.pickFolder"),variant:"primary"});return It.value?.loadComposerForEdit(je??ot,Xn(xe)),Dn&&(Mo.value=!0),!1}async function On(ot,xe=[],je){return await Cs(ot,xe,je)?Uo(ot,xe,je):!1}let Hi=0;async function Wi(ot){const{cmd:xe,attachments:je,restoreText:Dn}=ot;if(xe==="/compact"||xe.startsWith("/compact ")){if(!await On(xe))return;i.compact(xe.slice(8).trim()||void 0);return}if(xe==="/swarm"||xe.startsWith("/swarm ")){const vn=xe.slice(6).trim();if(vn==="on")i.setSwarmMode(!0);else if(vn==="off")i.setSwarmMode(!1);else if(vn){if(!await On(xe))return;i.setSwarmMode(!0),i.sendPrompt(vn)}else i.toggleSwarmMode();return}if(xe==="/goal"||xe.startsWith("/goal ")){const vn=xe.slice(5).trim();if(vn==="pause"||vn==="resume"||vn==="cancel")i.controlGoal(vn);else if(vn){if(!await On(xe))return;i.createGoal(vn)}else i.toggleGoalMode();return}if(xe==="/btw"||xe.startsWith("/btw ")){const vn=xe.slice(4).trim();if(!vn&&i.sideChatVisible.value)Lt();else{const ii=Er();if(vn&&!await On(xe)){ii();return}Nt(vn||void 0).then(()=>ii(),()=>ii())}return}switch(xe){case"/new":case"/clear":oo();break;case"/fork":i.forkSession();break;case"/export":qo();break;case"/undo":{const vn=i.activeSessionId.value;i.undo().then(ii=>{ii&&vn&&(i.invalidateSessionPlans(vn),i.refreshSessionPlans(vn))});break}case"/status":ys.value=!0;break;case"/login":an();break;default:{const vn=xe.indexOf(" "),ii=u$((vn===-1?xe:xe.slice(0,vn)).slice(1)),ws=vn===-1?void 0:xe.slice(vn+1).trim()||void 0;if(!ii)break;const xs=++Hi;if(!await On(xe,je,Dn))return;if(!i.activeSessionId.value&&i.activeWorkspaceId.value){const ro=i.activeWorkspaceId.value,{sessionId:ai,activated:Ys}=await i.startSessionAndActivateSkill(ro,ii,ws,je);!Ys&&xs===Hi&&It.value?.isComposerEmpty()&&(ai===null?i.activeWorkspaceId.value===ro:i.activeSessionId.value===ai)&&It.value.loadComposerForEdit(Dn??xe,Xn(je))}else{const ro=i.activeSessionId.value;i.activateSkill(ii,ws,je).then(ai=>{ai||i.activeSessionId.value===ro&&xs===Hi&&It.value?.isComposerEmpty()&&It.value.loadComposerForEdit(Dn??xe,Xn(je))})}break}}}function rs(ot){i.unqueue(ot)}function jn(ot){i.unqueue(ot)}function Ke(ot){i.reorderQueue(ot.from,ot.to)}function Ue(ot){Hi++,i.steerQueued(ot)}async function yt(ot){if(!await Cs(ot.text,ot.attachments))return;Hi++;const xe=i.activeWorkspaceId.value;if(!i.activeSessionId.value&&xe){await i.startSessionAndSendPrompt(xe,ot.text,ot.attachments);return}if(!i.activeSessionId.value&&!xe){Kn.value=ot,await r({title:s("workspace.requiredTitle"),message:s("workspace.requiredMessage"),confirmLabel:s("conversation.pickFolder"),variant:"primary"})?Mo.value=!0:xt();return}i.sendPrompt(ot.text,ot.attachments)}function xt(){const ot=Kn.value;Kn.value=null,ot&&It.value?.loadComposerForEdit(ot.text,Xn(ot.attachments))}async function rn(ot){if(Pi.value=null,!await i.addWorkspaceByPath(ot)){Pi.value=s("workspace.addFailed");return}Mo.value=!1;const je=Kn.value;Kn.value=null;const Dn=i.activeWorkspaceId.value;je&&Dn&&await i.startSessionAndSendPrompt(Dn,je.text,je.attachments)}function Zi(){xt(),Pi.value=null,Mo.value=!1}function Gi(){dt(()=>{It.value?.focusComposer()})}function oo(){const ot=i.activeWorkspaceId.value;ot?i.openWorkspaceDraft(ot,{entry:"newChat"}):i.clearActiveSession(),Gi()}function qi(ot){i.openWorkspaceDraft(ot,{entry:"workspace"}),Gi()}function vo(ot){i.openWorkspaceDraft(ot),Gi()}const so=F(()=>i.recentSessionsForWorkspace(i.activeWorkspaceId.value));function Ro(ot){ot&&window.open(ot,"_blank","noopener")}return(ot,xe)=>(v(),E("div",aut,[o.value?(v(),ce(out,{key:0})):X("",!0),C("div",{class:Fe(["app",{mobile:f(a),"sidebar-collapsed":f(be)&&!f(a),"macos-desktop":f(pc)}]),inert:b.value},[f(a)?(v(),ce(Pst,{key:1,workspace:f(i).visibleWorkspace.value,"session-title":d.value,status:w.value,onOpenSwitcher:xe[27]||(xe[27]=je=>u.value=!0),onOpenSettings:xe[28]||(xe[28]=je=>c.value=!0)},null,8,["workspace","session-title","status"])):(v(),E(Ee,{key:0},[U(eme,{ref_key:"sidebarRef",ref:p,collapsed:f(be),dragging:f(Q),"col-width":f(ue),"active-workspace":f(i).visibleWorkspace.value,"active-workspace-id":f(i).activeWorkspaceId.value,sessions:f(i).sessionsForView.value,groups:f(i).workspaceGroups.value,"workspace-sort-mode":f(i).workspaceSortMode.value,"pinned-sessions":f(i).pinnedSessions.value,"flat-sessions":f(i).flatSessions.value,"flat-has-more":f(i).flatSessionsHasMore.value,"flat-loading-more":f(i).flatSessionsLoadingMore.value,"done-sessions":f(i).doneSessions.value,"done-has-more":f(i).doneSessionsHasMore.value,"done-loading-more":f(i).doneSessionsLoadingMore.value,initialized:f(i).initialized.value,"active-id":f(i).activeSessionId.value,"attention-by-session":f(i).attentionBySession.value,"pending-by-session":f(i).pendingBySession.value,"unread-by-session":f(i).unreadBySession.value,onSelect:xe[0]||(xe[0]=je=>f(i).selectSession(je)),onCreate:oo,onCreateInWorkspace:xe[1]||(xe[1]=je=>qi(je)),onSelectWorkspace:xe[2]||(xe[2]=je=>f(i).openWorkspace(je)),onAddWorkspace:xe[3]||(xe[3]=je=>Mo.value=!0),onRename:xe[4]||(xe[4]=(je,Dn)=>f(i).renameSession(je,Dn)),onGenerateTitle:xe[5]||(xe[5]=(je,Dn)=>void f(i).regenerateSessionTitle(je).then(Dn)),onArchive:xe[6]||(xe[6]=je=>Vi(je)),onRestore:xe[7]||(xe[7]=je=>Cn(je)),onFork:xe[8]||(xe[8]=je=>f(i).forkSession(je)),onExport:xe[9]||(xe[9]=je=>void qo(je)),onPin:xe[10]||(xe[10]=je=>f(i).togglePinSession(je)),onUnpin:xe[11]||(xe[11]=je=>f(i).unpinSession(je)),onDropPin:xe[12]||(xe[12]=je=>f(i).pinSession(je)),onRenameWorkspace:xe[13]||(xe[13]=(je,Dn)=>f(i).renameWorkspace(je,Dn)),onDeleteWorkspace:xe[14]||(xe[14]=je=>ji(je)),onReorderWorkspaces:xe[15]||(xe[15]=je=>f(i).reorderWorkspaces(je)),onSetWorkspaceSortMode:xe[16]||(xe[16]=je=>f(i).setWorkspaceSortMode(je)),onLoadMoreSessions:xe[17]||(xe[17]=je=>void f(i).loadMoreSessions(je)),onLoadAllSessions:xe[18]||(xe[18]=je=>void f(i).loadAllSessions()),onEnsureFlatSessions:xe[19]||(xe[19]=je=>void f(i).ensureFlatSessions()),onLoadMoreFlatSessions:xe[20]||(xe[20]=je=>void f(i).loadMoreFlatSessions()),onEnsureDoneSessions:xe[21]||(xe[21]=je=>void f(i).ensureDoneSessions()),onLoadMoreDoneSessions:xe[22]||(xe[22]=je=>void f(i).loadMoreDoneSessions()),onOpenSessionAdmin:xe[23]||(xe[23]=je=>f(i).openSessionAdmin()),onOpenSettings:xe[24]||(xe[24]=je=>Tn.value=!0),onLogin:an,onCollapse:f(se)},null,8,["collapsed","dragging","col-width","active-workspace","active-workspace-id","sessions","groups","workspace-sort-mode","pinned-sessions","flat-sessions","flat-has-more","flat-loading-more","done-sessions","done-has-more","done-loading-more","initialized","active-id","attention-by-session","pending-by-session","unread-by-session","onCollapse"]),Wn(U(K_,{class:"side-handle","storage-key":f(ne),"default-width":f(ie),min:f(pe),max:f(Ne),"onUpdate:width":xe[25]||(xe[25]=je=>te.value=je),"onUpdate:dragging":xe[26]||(xe[26]=je=>Q.value=je)},null,8,["storage-key","default-width","min","max"]),[[Po,!f(be)]])],64)),Wn(U(uQe,{ref_key:"conversationPaneRef",ref:It,mobile:f(a),turns:f(i).turns.value,"session-id":f(i).activeSessionId.value,approvals:f(i).pendingApprovals.value,changes:f(i).changes.value,"git-info":f(i).gitInfo.value,tasks:f(i).tasks.value,todos:f(i).todos.value,goal:f(i).goal.value,"session-plans":f(i).sessionPlans.value,"activation-badges":f(i).activationBadges.value,status:f(i).status.value,thinking:f(i).thinking.value,"plan-mode":f(i).planMode.value,"plan-armed":f(i).planArmed.value,"swarm-mode":f(i).swarmMode.value,"goal-mode":f(i).goalMode.value,models:f(i).models.value,"auth-ready":f(i).authReady.value,"managed-signed-in":f(i).managedProviderStatus.value==="authenticated","managed-membership":f(i).managedMembership.value,"starred-ids":f(i).starredModelIds.value,skills:f(i).skills.value,questions:f(i).questions.value,"pending-question-actions":f(i).pendingQuestionActions,"pending-approval-actions":f(i).pendingApprovalActions,running:k.value,"overlay-open":Io.value,"turn-active":f(i).turnActive.value,queued:f(i).queued.value,"search-files":f(i).searchFiles,"upload-image":f(i).uploadImage,working:f(i).working.value,"last-turn-reason":m.value,"turn-error":f(i).activeTurnError.value??null,"turn-retry":f(i).activeTurnRetry.value??null,starting:f(i).isStartingFirstPrompt.value,"file-reload-key":f(i).activeSessionId.value,"session-loading":f(i).sessionLoading.value,compaction:f(i).compaction.value,"has-more-messages":f(i).hasMoreMessages.value,"loading-more":f(i).loadingMoreMessages.value,"loading-more-error":f(i).loadMoreMessagesError.value,"load-older-messages":f(i).loadOlderMessages,"workspace-name":f(i).visibleWorkspace.value?.name,"workspace-root":f(i).visibleWorkspace.value?.root??f(i).status.value.cwd,"git-diff-stats":f(i).gitDiffStats.value,workspaces:f(i).workspacesView.value,"active-workspace-id":f(i).activeWorkspaceId.value,"recent-sessions":so.value,"draft-entry":f(i).draftEntry.value,"session-title":d.value,"session-archived":f(i).activeSessionArchived.value,"session-pinned":h.value,pr:f(i).activePullRequest.value,onOpenChanges:xe[29]||(xe[29]=je=>f(kn)()),onSelectWorkspace:xe[30]||(xe[30]=je=>vo(je)),onSelectSession:xe[31]||(xe[31]=je=>f(i).selectSession(je)),onAddWorkspace:xe[32]||(xe[32]=je=>Mo.value=!0),onOpenPr:Ro,onOpenSessionAdmin:xe[33]||(xe[33]=je=>f(i).openSessionAdmin(je)),onSubmit:xe[34]||(xe[34]=je=>yt(je)),onLogin:xe[35]||(xe[35]=je=>an()),onSteer:xe[36]||(xe[36]=je=>f(i).steerPrompt(je.text,je.attachments)),onApproval:xe[37]||(xe[37]=(je,Dn)=>f(i).respondApproval(je,Dn)),onCancelTask:xe[38]||(xe[38]=je=>f(i).cancelTask(je)),onAnswer:xe[39]||(xe[39]=(je,Dn)=>f(i).respondQuestion(je,Dn)),onDismiss:xe[40]||(xe[40]=je=>f(i).dismissQuestion(je)),onCommand:Wi,onInterrupt:Di,onUnqueue:rs,onEditQueued:jn,onReorderQueue:Ke,onSteerQueued:Ue,onSetPermission:xe[41]||(xe[41]=je=>f(i).setPermission(je)),onSetThinking:xe[42]||(xe[42]=je=>f(i).setThinking(je)),onTogglePlan:xe[43]||(xe[43]=je=>f(i).togglePlanMode()),onToggleSwarm:xe[44]||(xe[44]=je=>f(i).toggleSwarmMode()),onToggleGoal:xe[45]||(xe[45]=je=>f(i).toggleGoalMode()),onCreateGoal:xe[46]||(xe[46]=je=>f(i).createGoal(je)),onControlGoal:xe[47]||(xe[47]=je=>f(i).controlGoal(je)),onRefreshGitStatus:xe[48]||(xe[48]=je=>f(i).activeSessionId.value&&f(i).loadGitStatus(f(i).activeSessionId.value)),onRenameSession:xe[49]||(xe[49]=(je,Dn)=>f(i).renameSession(je,Dn)),onForkSession:xe[50]||(xe[50]=je=>f(i).forkSession(je)),onTogglePin:g,onArchiveSession:xe[51]||(xe[51]=je=>Vi(je)),onRestoreSession:xe[52]||(xe[52]=je=>Cn(je)),onExportSession:xe[53]||(xe[53]=je=>void qo(je)),onCompact:xe[54]||(xe[54]=je=>f(i).compact()),onPickModel:xe[55]||(xe[55]=je=>Li()),onSelectModel:xe[56]||(xe[56]=je=>Wo(je)),onOpenFile:xe[57]||(xe[57]=je=>f(W)(je)),onOpenMedia:q,onOpenTurnDiff:xe[58]||(xe[58]=je=>f(He)(je)),onOpenCompaction:xe[59]||(xe[59]=je=>f(Be)(je)),onOpenAgent:xe[60]||(xe[60]=je=>f(ze)(je)),onEditMessage:Nr},null,8,["mobile","turns","session-id","approvals","changes","git-info","tasks","todos","goal","session-plans","activation-badges","status","thinking","plan-mode","plan-armed","swarm-mode","goal-mode","models","auth-ready","managed-signed-in","managed-membership","starred-ids","skills","questions","pending-question-actions","pending-approval-actions","running","overlay-open","turn-active","queued","search-files","upload-image","working","last-turn-reason","turn-error","turn-retry","starting","file-reload-key","session-loading","compaction","has-more-messages","loading-more","loading-more-error","load-older-messages","workspace-name","workspace-root","git-diff-stats","workspaces","active-workspace-id","recent-sessions","draft-entry","session-title","session-archived","session-pinned","pr"]),[[Po,f(i).mainView.value==="chat"]]),Wn(U(MYe,{"batch-running":wi.value,onArchiveSessions:xe[61]||(xe[61]=je=>void $o("archive",je)),onRestoreSessions:xe[62]||(xe[62]=je=>void $o("restore",je))},null,8,["batch-running"]),[[Po,f(i).mainView.value==="sessionAdmin"]]),!f(a)&&(f(pc)||f(be))?(v(),ce(f(Jt),{key:2,class:"sidebar-toggle-btn",size:"sm",label:f(be)?f(s)("sidebar.expandSidebar"):f(s)("sidebar.collapseSidebar"),tooltip:f(be)?f(s)("sidebar.expandSidebar"):f(s)("sidebar.collapseSidebar"),onClick:f(se)},{default:de(()=>[U(f(ve),{name:f(be)?"panel-expand":"panel-collapse"},null,8,["name"])]),_:1},8,["label","tooltip","onClick"])):X("",!0),!f(a)&&f(be)?(v(),ce(f(Jt),{key:3,class:"new-chat-btn",size:"sm",label:f(s)("sidebar.newChat"),tooltip:f(s)("sidebar.newChat"),onClick:oo},{default:de(()=>[U(f(ve),{name:"chat-new"})]),_:1},8,["label","tooltip"])):X("",!0),f(qn)&&!f(a)?(v(),ce(K_,{key:4,class:"preview-handle","storage-key":f(re),"default-width":f(le),min:f(G),max:f(ge),reverse:"","aria-label":f(s)("layout.resizePreviewAria"),"apply-live":_o,"onUpdate:width":xe[63]||(xe[63]=je=>ke.value=je),"onUpdate:dragging":xe[64]||(xe[64]=je=>So.value=je)},null,8,["storage-key","default-width","min","max","aria-label"])):X("",!0),!f(a)||f(qn)?(v(),E("aside",{key:5,ref_key:"previewPanelEl",ref:Ir,class:Fe(["global-preview",{open:f(qn),mobile:f(a)}]),role:"complementary","aria-label":f(s)("layout.detailPanelAria"),"aria-hidden":!f(qn)},[I.value==="compaction"&&f(we)?(v(),ce(fJe,{key:0,text:f(Oe)??"",subtitle:f(s)("conversation.summaryTitle"),onClose:f(tt)},null,8,["text","subtitle","onClose"])):I.value==="agent"&&f(ut)?(v(),ce(vJe,{key:1,member:f(ut),turns:f(_t),running:f(Le),loading:f(Ct),"load-error":f($t),"has-more":f(gt),"loading-more":f(Vt),"load-more-error":f(nn),onClose:f(Ye),onLoadOlderMessages:f(Tt),onOpenAgent:f(ze),onOpenFile:f(W),onOpenMedia:q,onOpenTurnDiff:xe[65]||(xe[65]=je=>f(He)(je))},null,8,["member","turns","running","loading","load-error","has-more","loading-more","load-more-error","onClose","onLoadOlderMessages","onOpenAgent","onOpenFile"])):I.value==="btw"&&f(et)?(v(),ce(SJe,{key:2,ref_key:"sideChatPanelRef",ref:ms,turns:f(i).sideChatTurns.value,running:f(i).sideChatRunning.value,sending:f(i).sideChatSending.value,"on-send":f(i).sendSideChatPrompt,onClose:f(Lt),onOpenMedia:q},null,8,["turns","running","sending","on-send","onClose"])):I.value==="diff"?(v(),ce(XJe,{key:3,mode:f(on),changes:f(i).changes.value,"git-info":f(i).gitInfo.value,"file-diff":f(i).fileDiff.value,"full-texts":f(i).fileDiffTexts.value,"empty-file":f(i).fileDiffEmptyFile.value,"selected-diff-path":f(i).selectedDiffPath.value,"file-diff-loading":f(i).fileDiffLoading.value,closable:"",onOpen:f(mn),onBack:xe[66]||(xe[66]=je=>{on.value="list",jt.value=null,f(i).clearFileDiff()}),onClose:f(bn)},null,8,["mode","changes","git-info","file-diff","full-texts","empty-file","selected-diff-path","file-diff-loading","onOpen","onClose"])):I.value==="file"?(v(),ce(uJe,{key:4,file:f(H),loading:f(O),error:f(R),line:f(z)?.line,"download-url":f(j),closable:"","external-actions":f($),"open-file":f(W),onClose:f(P),onOpenExternal:f(Z),onReveal:f(ae)},null,8,["file","loading","error","line","download-url","external-actions","open-file","onClose","onOpenExternal","onReveal"])):I.value==="turn-diff"&&f(zn)?(v(),ce(sXe,{key:5,change:f(zn),cwd:f(i).status.value.cwd,closable:"",onClose:f(st),onOpenFile:xe[67]||(xe[67]=je=>f(W)({path:je}))},null,8,["change","cwd","onClose"])):X("",!0)],10,cut)):X("",!0),U(lut,{class:"internal-build-fab"}),vs.value?(v(),ce(AXe,{key:6,models:f(i).models.value,current:f(i).status.value.modelId,"starred-ids":f(i).starredModelIds.value,loading:Ki.value,unavailable:Ti.value,onSelect:xe[68]||(xe[68]=je=>Jn(je)),onToggleStar:xe[69]||(xe[69]=je=>f(i).toggleStarModel(je)),onClose:xe[70]||(xe[70]=je=>vs.value=!1)},null,8,["models","current","starred-ids","loading","unavailable"])):X("",!0),Tn.value?(v(),ce(Oot,{key:7,"color-scheme":f(i).colorScheme.value,"font-scale":f(i).fontScale.value,"managed-provider-status":f(i).managedProviderStatus.value,"managed-user-info":f(i).managedUserInfo.value,"on-fetch-usage":f(i).getUsage,notify:f(i).notifyEnabled.value,"notify-permission":f(i).notifyPermission.value,"notify-sound":f(i).notifySound.value,config:f(i).config.value,models:f(i).models.value,"config-saving":Qs.value,"server-version":f(i).serverVersion.value,backend:f(i).backend.value,"experimental-flags":f(i).experimentalFlags.value,"initial-tab":yi.value,onSetColorScheme:xe[71]||(xe[71]=je=>f(i).setColorScheme(je)),onSetFontScale:xe[72]||(xe[72]=je=>f(i).setFontScale(je)),onSetNotify:xe[73]||(xe[73]=je=>f(i).setNotifyEnabled(je)),onSetNotifySound:xe[74]||(xe[74]=je=>f(i).setNotifySound(je)),onUpdateConfig:xe[75]||(xe[75]=je=>Fi(je)),onLogin:xe[76]||(xe[76]=()=>{Tn.value=!1,an()}),onLogout:to,onClose:xe[77]||(xe[77]=je=>{Tn.value=!1,yi.value=void 0})},null,8,["color-scheme","font-scale","managed-provider-status","managed-user-info","on-fetch-usage","notify","notify-permission","notify-sound","config","models","config-saving","server-version","backend","experimental-flags","initial-tab"])):X("",!0),ys.value?(v(),ce(_st,{key:8,status:f(i).status.value,thinking:y.value,"plan-mode":f(i).planMode.value,"swarm-mode":f(i).swarmMode.value,"cost-usd":f(i).sessionCost.value,onClose:xe[78]||(xe[78]=je=>ys.value=!1)},null,8,["status","thinking","plan-mode","swarm-mode","cost-usd"])):X("",!0),Mo.value?(v(),ce(cst,{key:9,"browse-fs":f(i).browseFs,"get-fs-home":f(i).getFsHome,"default-path":f(i).visibleWorkspace.value?.root??f(i).status.value.cwd,error:Pi.value,onAdd:xe[79]||(xe[79]=je=>rn(je)),onClose:Zi},null,8,["browse-fs","get-fs-home","default-path","error"])):X("",!0),U(fo,{name:"gload-fade"},{default:de(()=>[f(i).initialized.value?X("",!0):(v(),ce(_at,{key:0,issue:f(i).connectIssue.value},null,8,["issue"]))]),_:1}),U(Nst,{warnings:f(i).warnings.value,onDismiss:f(i).dismissWarning},null,8,["warnings","onDismiss"]),(v(),ce(Ds,{to:"body"},[U(fo,{name:"action-toast"},{default:de(()=>[Mn.value?(v(),ce(f(rQ),{key:Mn.value.key,duration:Mn.value.kind==="export"?Mn.value.state==="running"?6e4:4e3:8e3,"dismiss-token":Mn.value.key,onDismiss:ks},{default:de(()=>[Mn.value.kind==="archive"?(v(),E(Ee,{key:0},[f(Vn)?(v(),E(Ee,{key:0},[$e(D(Mn.value.reopen?f(s)("sidebar.reopenToastLead"):f(s)("sidebar.completeToastLead"))+" ",1),C("button",{type:"button",onClick:ar},D(f(s)("sidebar.archiveToastUndo")),1)],64)):(v(),E(Ee,{key:1},[C("button",{type:"button",onClick:ar},D(f(s)("sidebar.archiveToastUndo")),1),f(a)?X("",!0):(v(),E(Ee,{key:0},[$e(D(f(s)("sidebar.archiveToastMid"))+" ",1),C("button",{type:"button",onClick:S},D(f(s)("sidebar.archiveToastSettings")),1),$e(" "+D(f(s)("sidebar.archiveToastTail")),1)],64))],64))],64)):Mn.value.kind==="adminBatch"?(v(),E(Ee,{key:1},[$e(D(Mn.value.plan.direction==="archive"?f(s)("admin.batchDoneToast",{n:Mn.value.plan.succeeded}):f(s)("admin.batchReopenedToast",{n:Mn.value.plan.succeeded})),1),Mn.value.plan.failed>0?(v(),E(Ee,{key:0},[$e(D(f(s)("admin.batchFailedSuffix",{n:Mn.value.plan.failed})),1)],64)):X("",!0),C("button",{type:"button",onClick:$s},D(f(s)("admin.undo")),1)],64)):(v(),E(Ee,{key:2},[$e(D(Mn.value.state==="running"?f(s)("commands.export.started"):f(s)("commands.export.done")),1)],64))]),_:1},8,["duration","dismiss-token"])):X("",!0)]),_:1})])),f(l)?(v(),ce(nut,{key:10})):X("",!0),U(pst),f(a)?(v(),ce(hrt,{key:11,modelValue:u.value,"onUpdate:modelValue":xe[80]||(xe[80]=je=>u.value=je),groups:f(i).mobileWorkspaceGroups.value,"flat-sessions":f(i).flatSessions.value,"pinned-sessions":f(i).pinnedSessions.value,"flat-has-more":f(i).flatSessionsHasMore.value,"flat-loading-more":f(i).flatSessionsLoadingMore.value,"active-workspace-id":f(i).activeWorkspaceId.value,"active-id":f(i).activeSessionId.value,"attention-by-session":f(i).attentionBySession.value,"attention-by-workspace":f(i).attentionByWorkspace.value,onSelect:xe[81]||(xe[81]=je=>f(i).selectSession(je)),onCreate:oo,onCreateInWorkspace:xe[82]||(xe[82]=je=>qi(je)),onAddWorkspace:xe[83]||(xe[83]=je=>Mo.value=!0),onRename:xe[84]||(xe[84]=(je,Dn)=>f(i).renameSession(je,Dn)),onArchive:xe[85]||(xe[85]=je=>Vi(je)),onDeleteWorkspace:xe[86]||(xe[86]=je=>ji(je)),onLoadMore:xe[87]||(xe[87]=je=>void f(i).loadMoreSessions(je)),onEnsureFlatSessions:xe[88]||(xe[88]=je=>void f(i).ensureFlatSessions()),onLoadMoreFlatSessions:xe[89]||(xe[89]=je=>void f(i).loadMoreFlatSessions())},null,8,["modelValue","groups","flat-sessions","pinned-sessions","flat-has-more","flat-loading-more","active-workspace-id","active-id","attention-by-session","attention-by-workspace"])):X("",!0),f(a)?(v(),ce(Clt,{key:12,modelValue:c.value,"onUpdate:modelValue":xe[90]||(xe[90]=je=>c.value=je),status:f(i).status.value,thinking:f(i).thinking.value,models:f(i).models.value,"plan-mode":f(i).planArmed.value||f(i).planMode.value,"goal-mode":f(i).goalMode.value,"goal-active":go.value,"swarm-mode":f(i).swarmMode.value,"color-scheme":f(i).colorScheme.value,"font-scale":f(i).fontScale.value,"managed-provider-status":f(i).managedProviderStatus.value,"managed-user-info":f(i).managedUserInfo.value,"server-version":f(i).serverVersion.value,onPickModel:xe[91]||(xe[91]=je=>Li()),onSetThinking:xe[92]||(xe[92]=je=>f(i).setThinking(je)),onTogglePlan:xe[93]||(xe[93]=je=>f(i).togglePlanMode()),onToggleGoal:xe[94]||(xe[94]=je=>f(i).toggleGoalMode()),onFocusGoal:mo,onToggleSwarm:xe[95]||(xe[95]=je=>f(i).toggleSwarmMode()),onSetPermission:xe[96]||(xe[96]=je=>f(i).setPermission(je)),onSetColorScheme:xe[97]||(xe[97]=je=>f(i).setColorScheme(je)),onSetFontScale:xe[98]||(xe[98]=je=>f(i).setFontScale(je)),onLogin:xe[99]||(xe[99]=()=>{c.value=!1,an()}),onLogout:to},null,8,["modelValue","status","thinking","models","plan-mode","goal-mode","goal-active","swarm-mode","color-scheme","font-scale","managed-provider-status","managed-user-info","server-version"])):X("",!0)],10,uut),f(i).initialized.value&&b.value?(v(),ce(Aat,{key:1,"auth-ready":f(i).managedProviderStatus.value==="authenticated","on-start-o-auth-login":bs,"on-poll-o-auth-login":As,"on-cancel-o-auth-login":Eo,"on-get-o-auth-region":Tr,onComplete:A,onLoginSuccess:jl,onAddProvider:T},null,8,["auth-ready"])):X("",!0),_i.value?(v(),ce(KXe,{key:2,"on-start-o-auth-login":bs,"on-poll-o-auth-login":As,"on-cancel-o-auth-login":Eo,"on-get-o-auth-region":Tr,onSuccess:Lr,onClose:xe[100]||(xe[100]=je=>_i.value=!1)})):X("",!0),Y.value?(v(),ce(IA,{key:3,media:Y.value,"origin-img":oe.value,onClose:xe[101]||(xe[101]=je=>{Y.value=null,oe.value=null})},null,8,["media","origin-img"])):X("",!0)]))}}),fut=kt(dut,[["__scopeId","data-v-d59cb496"]]);J8e();jfe({api:Ic,t:(e,t)=>t===void 0?da.global.t(e):da.global.t(e,t),traceClientEvent:Y8e,traceKeyEvent:(e,t)=>U2(e,t),sessionExportTraceToJsonl:n5e});const Lg=h2(fut).use(da);Lg.use(f1);const hut={t:(e,t)=>da.global.t(e,t)};Lg.provide(JF,hut);Lg.provide(xF,e=>Lke(e)?.component);Lg.provide(Are,pa());Lg.mount("#app");if(bf){const e=window.kimiDesktop;if(e){const t=()=>{const n=document.documentElement.dataset.colorScheme;e.setTheme(n==="light"||n==="dark"?n:"system")};new MutationObserver(t).observe(document.documentElement,{attributes:!0,attributeFilter:["data-color-scheme"]}),t()}}export{F5 as $,TN as A,Nq as B,Yo as C,lct as D,ZL as E,Ee as F,$c as G,$e as H,U as I,cq as J,Nut as K,ia as L,Xe as M,uK as N,$ut as O,Rut as P,Put as Q,Zv as R,Mh as S,Ds as T,zut as U,G5 as V,But as W,uct as X,Out as Y,nct as Z,put as _,wN as a,Oo as a$,os as a0,Y0 as a1,but as a2,z5 as a3,eF as a4,yn as a5,o1 as a6,wq as a7,fct as a8,Iut as a9,IN as aA,Vq as aB,Xq as aC,cn as aD,Jq as aE,Yq as aF,Bc as aG,Qq as aH,_n as aI,s1 as aJ,mq as aK,v as aL,rK as aM,xut as aN,oi as aO,fN as aP,wut as aQ,Jv as aR,jo as aS,Vk as aT,K as aU,Qut as aV,xK as aW,pt as aX,Rn as aY,tU as aZ,Fut as a_,Lut as aa,Tut as ab,Eut as ac,Jut as ad,hct as ae,hn as af,RU as ag,Vy as ah,Ra as ai,xu as aj,io as ak,Yut as al,ul as am,Cc as an,St as ao,Wut as ap,qut as aq,ni as ar,dt as as,HU as at,Fe as au,RW as av,Kt as aw,Kq as ax,Gq as ay,Hn as az,Cut as b,eTe as b$,sct as b0,g0 as b1,s2 as b2,ict as b3,Ac as b4,cN as b5,mut as b6,ha as b7,xq as b8,oct as b9,Bs as bA,Po as bB,zU as bC,ect as bD,Pe as bE,Zk as bF,_ut as bG,_q as bH,Kut as bI,de as bJ,jut as bK,Wn as bL,Ho as bM,Xut as bN,wt as bO,Sut as bP,Ci as bQ,Fo as bR,kct as bS,bct as bT,iP as bU,Act as bV,bEe as bW,nP as bX,U8 as bY,Sct as bZ,iTe as b_,gut as ba,D as bb,hv as bc,Dut as bd,si as be,vut as bf,dq as bg,Yl as bh,Gut as bi,lq as bj,f as bk,r1 as bl,dct as bm,act as bn,dK as bo,Fq as bp,Vut as bq,Sq as br,cct as bs,Hut as bt,Mut as bu,CN as bv,f2 as bw,kK as bx,mF as by,ub as bz,tct as c,K7 as c0,q7 as c1,U7 as c2,Mct as c3,fy as c4,kh as c5,cy as c6,QEe as c7,YEe as c8,Ict as c9,xH as cA,rPe as cB,ml as cC,Oi as cD,kt as cE,_ct as ca,mct as cb,Ect as cc,N9 as cd,jr as ce,hTe as cf,fTe as cg,hEe as ch,yct as ci,uEe as cj,cEe as ck,vct as cl,V7 as cm,pTe as cn,ME as co,lE as cp,CEe as cq,dy as cr,uy as cs,Cct as ct,xct as cu,gct as cv,wct as cw,ve as cx,pct as cy,cb as cz,Zut as d,hc as e,yut as f,fo as g,pF as h,kut as i,Aut as j,Rl as k,J0 as l,ps as m,Oy as n,Su as o,rct as p,F as q,h2 as r,ce as s,X as t,E as u,C as v,wU as w,Uut as x,CU as y,SK as z}; diff --git a/apps/kimi-code/dist-web/assets/index-DGHD7Bg9.css b/apps/kimi-code/dist-web/assets/index-DGHD7Bg9.css new file mode 100644 index 000000000..1b392427d --- /dev/null +++ b/apps/kimi-code/dist-web/assets/index-DGHD7Bg9.css @@ -0,0 +1 @@ +.ui-tip__bubble[data-v-93bacf6d]{position:fixed;z-index:var(--z-tooltip);display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:var(--tip-lines);max-width:280px;padding:4px 8px;border-radius:var(--radius-sm);background:var(--color-text);color:var(--color-bg);font-family:var(--font-ui);font-size:var(--text-xs);line-height:1.35;overflow:hidden;overflow-wrap:anywhere;pointer-events:none;opacity:0;transition:opacity var(--duration-fast) var(--ease-out)}.ui-tip__bubble.positioned[data-v-93bacf6d]{opacity:1}.ui-icon-button[data-v-2cbeca98]{display:inline-flex;align-items:center;justify-content:center;flex:none;padding:0;border:.5px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);cursor:pointer;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.ui-icon-button[data-v-2cbeca98]:hover:not(:disabled){background:var(--color-hover);color:var(--color-text)}.ui-icon-button[data-v-2cbeca98]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-icon-button[data-v-2cbeca98]:disabled{opacity:.5;cursor:not-allowed}.ui-icon-button--sm[data-v-2cbeca98]{width:var(--icon-button-sm);height:var(--icon-button-sm);border-radius:var(--radius-sm)}.ui-icon-button--md[data-v-2cbeca98]{width:32px;height:32px}.ui-icon-button--lg[data-v-2cbeca98]{width:44px;height:44px}.ui-icon-button[data-v-2cbeca98] svg{width:var(--p-ic-md);height:var(--p-ic-md)}.ui-icon-button--sm[data-v-2cbeca98] svg{width:var(--p-ic-md);height:var(--p-ic-md)}.ui-icon-button--lg[data-v-2cbeca98] svg{width:var(--p-ic-lg);height:var(--p-ic-lg)}.ui-action-toast-host[data-v-e84c8ca2]{position:fixed;top:calc(48px + var(--space-2));left:50%;translate:-50% 0;z-index:var(--z-toast);max-width:calc(100vw - 32px)}.ui-action-toast[data-v-e84c8ca2]{display:flex;align-items:center;gap:var(--space-2);padding:4px 6px 4px 14px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);font-family:var(--font-ui);font-size:var(--text-base);line-height:1.45;color:var(--color-text);white-space:nowrap}.ui-action-toast__body[data-v-e84c8ca2]{min-width:0}.ui-action-toast__body button[data-v-e84c8ca2-s]{border:0;padding:0;background:none;color:var(--color-accent);cursor:pointer;font:inherit}.ui-action-toast__body button[data-v-e84c8ca2-s]:hover{color:var(--color-accent-hover);text-decoration:underline}.ui-action-toast__body button[data-v-e84c8ca2-s]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:var(--radius-xs)}.ui-action-toast__close[data-v-e84c8ca2]{flex:none}.ui-badge[data-v-d879fe18]{display:inline-flex;align-items:center;gap:6px;border-radius:var(--radius-full);font-family:var(--font-ui);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;border:.5px solid transparent}.ui-badge--md[data-v-d879fe18]{height:22px;padding:0 9px;font-size:var(--text-xs)}.ui-badge--sm[data-v-d879fe18]{height:18px;padding:0 7px;font-size:11px}.ui-badge__dot[data-v-d879fe18]{width:6px;height:6px;border-radius:var(--radius-full);background:currentColor;flex:none}.ui-badge--neutral[data-v-d879fe18]{background:var(--color-surface-sunken);color:var(--color-text-muted);border-color:var(--color-line)}.ui-badge--info[data-v-d879fe18]{background:var(--color-accent-soft);color:var(--color-accent-hover);border-color:var(--color-accent-bd)}.ui-badge--success[data-v-d879fe18]{background:var(--color-success-soft);color:var(--color-success);border-color:var(--color-success-bd)}.ui-badge--warning[data-v-d879fe18]{background:var(--color-warning-soft);color:var(--color-warning);border-color:var(--color-warning-bd)}.ui-badge--danger[data-v-d879fe18]{background:var(--color-danger-soft);color:var(--color-danger);border-color:var(--color-danger-bd)}.ui-badge--solid[data-v-d879fe18]{background:var(--color-text);color:var(--color-bg)}.ui-banner[data-v-6d739c6d]{display:flex;align-items:center;gap:10px;padding:10px 14px;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);line-height:var(--leading-normal)}.ui-banner__icon[data-v-6d739c6d]{display:inline-flex;flex:none}.ui-banner__icon svg[data-v-6d739c6d]{width:18px;height:18px}.ui-banner--info[data-v-6d739c6d]{background:var(--color-accent-soft);border-color:var(--color-accent-bd)}.ui-banner--warning[data-v-6d739c6d]{background:var(--color-warning-soft);border-color:var(--color-warning-bd)}.ui-banner--danger[data-v-6d739c6d]{background:var(--color-danger-soft);border-color:var(--color-danger-bd)}.ui-banner--info .ui-banner__icon[data-v-6d739c6d]{color:var(--color-accent)}.ui-banner--warning .ui-banner__icon[data-v-6d739c6d]{color:var(--color-warning)}.ui-banner--danger .ui-banner__icon[data-v-6d739c6d]{color:var(--color-danger)}.ui-spinner[data-v-0b81b1b5]{display:inline-flex;flex:none;color:var(--color-accent)}.ui-spinner--sm[data-v-0b81b1b5]{width:14px;height:14px}.ui-spinner--md[data-v-0b81b1b5]{width:18px;height:18px}.ui-spinner--lg[data-v-0b81b1b5]{width:28px;height:28px}.ui-spinner__svg[data-v-0b81b1b5]{width:100%;height:100%}.ui-spinner__track[data-v-0b81b1b5]{fill:none;stroke:var(--color-line);stroke-width:2.2}.ui-spinner__arc[data-v-0b81b1b5]{fill:none;stroke:currentColor;stroke-width:2.2;stroke-linecap:round;stroke-dasharray:56 56;stroke-dashoffset:38}.ui-button[data-v-01b5ec22]{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);border:.5px solid transparent;border-radius:var(--radius-md);font-family:var(--font-ui);font-weight:var(--weight-medium);line-height:1;cursor:pointer;white-space:nowrap;transition:background var(--duration-base) var(--ease-out),border-color var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.ui-button[data-v-01b5ec22]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.ui-button[data-v-01b5ec22]:not(:disabled):active{transform:scale(.98)}.ui-button[data-v-01b5ec22]:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;transform:none}.ui-button--sm[data-v-01b5ec22]{height:30px;padding:0 var(--space-3);font-size:var(--text-sm);border-radius:var(--radius-sm)}.ui-button--md[data-v-01b5ec22]{height:36px;padding:0 var(--space-4);font-size:var(--text-base)}.ui-button--lg[data-v-01b5ec22]{height:42px;padding:0 var(--space-5);font-size:15px;border-radius:var(--radius-lg)}.ui-button__content[data-v-01b5ec22]{display:inline-flex;align-items:center;gap:var(--space-2)}.ui-button__content[data-v-01b5ec22] svg{flex:none}.ui-button__content[data-v-01b5ec22] svg:not([width]){width:1em;height:1em}.ui-button--primary[data-v-01b5ec22]{background:var(--color-accent);color:var(--color-text-on-accent);border-color:var(--color-accent);box-shadow:var(--shadow-xs)}.ui-button--primary[data-v-01b5ec22]:not(:disabled):hover{background:var(--color-accent-hover);border-color:var(--color-accent-hover)}.ui-button--secondary[data-v-01b5ec22]{background:var(--color-surface-raised);color:var(--color-text);border-color:var(--color-line-strong);box-shadow:var(--shadow-xs)}.ui-button--secondary[data-v-01b5ec22]:not(:disabled):hover{border-color:var(--color-line-strong);background:var(--color-hover)}.ui-button--ghost[data-v-01b5ec22]{background:transparent;color:var(--color-text-muted);border-color:transparent}.ui-button--ghost[data-v-01b5ec22]:not(:disabled):hover{background:var(--color-hover);color:var(--color-text-strong)}.ui-button--danger[data-v-01b5ec22]{background:var(--color-danger);color:var(--color-text-on-accent);border-color:var(--color-danger);box-shadow:var(--shadow-xs)}.ui-button--danger[data-v-01b5ec22]:not(:disabled):hover{filter:brightness(.96)}.ui-button--danger-soft[data-v-01b5ec22]{background:var(--color-danger-soft);color:var(--color-danger);border-color:var(--color-danger-bd)}.ui-button--danger-soft[data-v-01b5ec22]:not(:disabled):hover{background:var(--color-danger);color:var(--color-text-on-accent);border-color:var(--color-danger)}.ui-button.is-loading .ui-button__content[data-v-01b5ec22]{opacity:.7}.ui-button .ui-button__spinner[data-v-01b5ec22]{flex:none;color:inherit}.ui-button__spinner[data-v-01b5ec22] .ui-spinner__track{opacity:.35}.ui-card[data-v-fbd05138]{background:var(--color-surface);border:.5px solid var(--color-line);border-radius:var(--radius-md);overflow:hidden}.ui-card.is-elevated[data-v-fbd05138]{box-shadow:var(--shadow-md);border-color:transparent}.ui-card__head[data-v-fbd05138]{display:flex;align-items:center;gap:var(--space-2);padding:10px 14px;border-bottom:.5px solid var(--color-line);background:var(--color-surface);font-family:var(--font-mono);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text)}.ui-card__body[data-v-fbd05138]{padding:14px;color:var(--color-text-muted)}.ui-card__foot[data-v-fbd05138]{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding:10px 14px;border-top:.5px solid var(--color-line);background:var(--color-surface)}.ui-check[data-v-d4bf4026]{display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer}.ui-check.is-disabled[data-v-d4bf4026]{opacity:.5;cursor:not-allowed}.ui-check__input[data-v-d4bf4026]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}.ui-check__box[data-v-d4bf4026]{display:inline-flex;align-items:center;justify-content:center;width:17px;height:17px;flex:none;border:.5px solid var(--color-line-strong);border-radius:var(--radius-sm);background:var(--color-surface-raised);color:var(--color-text-on-accent);transition:background var(--duration-base) var(--ease-out),border-color var(--duration-base) var(--ease-out)}.ui-check.is-on .ui-check__box[data-v-d4bf4026]{background:var(--color-accent);border-color:var(--color-accent)}.ui-check__input:focus-visible+.ui-check__box[data-v-d4bf4026]{box-shadow:var(--p-focus-ring)}.ui-check__box svg[data-v-d4bf4026]{width:12px;height:12px}.ui-check__label[data-v-d4bf4026]{font-family:var(--font-ui);font-size:var(--text-base);color:var(--color-text)}.ctx-ring[data-v-de787cf2]{width:16px;height:16px;flex:none;transform:rotate(-90deg)}.ctx-ring-track[data-v-de787cf2]{stroke:var(--line)}.ctx-ring-fill[data-v-de787cf2]{stroke:var(--color-accent);transition:stroke-dashoffset .3s ease,stroke .3s ease}.ui-dialog__overlay[data-v-ebbc1a68]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-6);background:#0d111747;animation:kimi-dialog-overlay-in-ebbc1a68 var(--duration-base) var(--ease-out)}@keyframes kimi-dialog-overlay-in-ebbc1a68{0%{opacity:0}to{opacity:1}}.ui-dialog[data-v-ebbc1a68]{max-height:calc(100vh - var(--space-8) * 2);display:flex;flex-direction:column;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-xl);box-shadow:var(--shadow-xl);outline:none;overflow:hidden;animation:kimi-card-in var(--duration-slow) var(--ease-out)}.ui-dialog--md[data-v-ebbc1a68]{width:min(440px,100%)}.ui-dialog--lg[data-v-ebbc1a68]{width:min(640px,100%)}.ui-dialog--xl[data-v-ebbc1a68]{width:min(var(--p-content-max),100%)}.ui-dialog--fixed-height[data-v-ebbc1a68]{height:min(680px,calc(100vh - var(--space-8) * 2))}.ui-dialog--grouped[data-v-ebbc1a68]{background:var(--color-bg)}.ui-dialog--flush .ui-dialog__body[data-v-ebbc1a68]{padding:0}.ui-dialog__head[data-v-ebbc1a68]{display:flex;align-items:flex-start;gap:var(--space-3);padding:20px 22px 14px}.ui-dialog__titles[data-v-ebbc1a68]{flex:1;min-width:0}.ui-dialog__title[data-v-ebbc1a68]{font-size:var(--text-lg);font-weight:500;color:var(--color-text);line-height:var(--leading-tight)}.ui-dialog__desc[data-v-ebbc1a68]{margin-top:4px;font-size:var(--text-base);color:var(--color-text-muted)}.ui-dialog__close[data-v-ebbc1a68]{flex:none;margin-top:-2px}.ui-dialog__body[data-v-ebbc1a68]{flex:1;min-height:0;padding:4px 22px 18px;color:var(--color-text);overflow:auto}.ui-dialog__foot[data-v-ebbc1a68]{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:14px 22px 20px}.ui-empty[data-v-6da80932]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-8) var(--space-4);text-align:center;color:var(--color-text-muted)}.ui-empty__icon[data-v-6da80932]{color:var(--color-text-faint)}.ui-empty__icon[data-v-6da80932] svg{width:48px;height:48px}.ui-empty__title[data-v-6da80932]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text-muted)}.ui-empty__hint[data-v-6da80932]{font-size:var(--text-sm);color:var(--color-text-muted)}.ui-field[data-v-a8de5f7f]{display:flex;flex-direction:column;gap:6px}.ui-field__label[data-v-a8de5f7f]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.ui-field__hint[data-v-a8de5f7f]{font-size:var(--text-xs);color:var(--color-text-faint)}.ui-field__error[data-v-a8de5f7f]{font-size:var(--text-xs);color:var(--color-danger)}.ui-input[data-v-f1cdf732]{width:100%;border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-surface-overlay);box-shadow:var(--shadow-xs);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);line-height:var(--leading-normal);padding:0 var(--space-3);transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.ui-input--md[data-v-f1cdf732]{height:38px}.ui-input--sm[data-v-f1cdf732]{height:32px;font-size:var(--text-sm);border-radius:var(--radius-sm)}.ui-input[data-v-f1cdf732]::placeholder{color:var(--color-text-faint)}.ui-input[data-v-f1cdf732]:hover:not(:disabled):not(:focus){border-color:var(--color-line-strong)}.ui-input[data-v-f1cdf732]:focus{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.ui-input[data-v-f1cdf732]:disabled{opacity:.5;cursor:not-allowed}.ui-input[readonly][data-v-f1cdf732]{background:var(--color-surface-sunken)}.ui-input.has-error[data-v-f1cdf732]{border-color:var(--color-danger)}.ui-input.has-error[data-v-f1cdf732]:focus{box-shadow:0 0 0 3px var(--color-danger-soft)}.ui-kbd[data-v-04b30ce2]{display:inline-flex;align-items:center;gap:3px;flex:none}.ui-kbd__key[data-v-04b30ce2]{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;border:.5px solid var(--color-line);border-radius:var(--radius-xs);background:transparent;color:inherit;font-family:var(--font-kbd);font-size:11px;line-height:1}.ui-menu[data-v-9be2c64a]{min-width:180px;padding:3.5px;background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);display:flex;flex-direction:column}.ui-menu-item[data-v-3866cadb]{display:flex;align-items:center;gap:7px;width:100%;padding:5px 9px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-option-label);line-height:var(--leading-tight);text-align:left;cursor:pointer;transition:background var(--duration-base),color var(--duration-base)}.ui-menu-item[data-v-3866cadb]:hover:not(:disabled):not(.is-active):not(.is-danger){background:var(--color-hover);color:var(--color-text-strong)}.ui-menu-item[data-v-3866cadb]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-menu-item[data-v-3866cadb]:disabled{opacity:.5;cursor:not-allowed}.ui-menu-item.is-active[data-v-3866cadb]{background:var(--color-hover);color:var(--color-text)}.ui-menu-item.is-danger[data-v-3866cadb]{color:var(--color-danger)}.ui-menu-item.is-danger[data-v-3866cadb]:hover:not(:disabled){background:var(--color-danger-soft)}.ui-menu-item[data-v-3866cadb] svg{display:block;width:16px;height:16px;flex:none;color:var(--muted);transition:color var(--duration-base)}.ui-menu-item[data-v-3866cadb]:hover:not(:disabled):not(.is-active):not(.is-danger) svg{color:var(--color-text-strong)}.ui-menu-item.is-active[data-v-3866cadb] svg{color:var(--color-text)}.ui-menu-item.is-danger[data-v-3866cadb] svg{color:var(--color-danger)}.ui-menu-item--lg[data-v-3866cadb]{min-height:44px;padding:12px 14px;font-size:var(--text-sm)}.ui-menu-sep[data-v-3866cadb]{height:1px;margin:4px 0;background:var(--color-line)}.ui-tip[data-v-414bd903]{display:contents}.ui-panel-header[data-v-eb14b05d]{flex:none;display:flex;align-items:center;gap:var(--space-2);height:var(--panel-head-h, 48px);padding:0 var(--panel-head-inset, 11px) 0 var(--space-3);box-sizing:border-box;min-width:0;border-bottom:.5px solid var(--color-line);background:var(--color-surface-deep)}.ui-panel-header__title[data-v-eb14b05d]{flex:none;font:var(--weight-semibold) var(--ui-b2) var(--font-ui);color:var(--color-text)}.ui-panel-header__sub[data-v-eb14b05d]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--ui-c1) var(--font-mono);color:var(--color-text-muted)}.ui-panel-header__close[data-v-eb14b05d]{flex:none;margin-left:auto}.ui-panel-header.wrap[data-v-eb14b05d]{flex-wrap:wrap;height:auto;min-height:var(--panel-head-h, 48px);padding-top:3px;padding-bottom:3px;gap:4px 6px}.ui-panel-header.wrap .ui-panel-header__close[data-v-eb14b05d]{margin-left:0}.ui-pill[data-v-fe6a2873]{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;border:.5px solid transparent;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;cursor:default;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}button.ui-pill[data-v-fe6a2873]{cursor:pointer}button.ui-pill[data-v-fe6a2873]:hover:not(:disabled){background:var(--color-hover);color:var(--color-text-strong)}button.ui-pill[data-v-fe6a2873]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}button.ui-pill[data-v-fe6a2873]:disabled{opacity:.5;cursor:not-allowed}.ui-pill.is-active[data-v-fe6a2873]{background:var(--color-accent-soft);color:var(--color-accent)}.ui-pill[data-v-fe6a2873] svg{width:var(--p-ic-sm);height:var(--p-ic-sm);flex:none;color:var(--color-text-faint)}.ui-scroll-area[data-v-9c504ebc]{position:relative;min-width:0;min-height:0;overflow:hidden}.ui-scroll-area__viewport[data-v-9c504ebc]{width:100%;height:100%;overscroll-behavior:contain;scrollbar-width:none}.ui-scroll-area__viewport[data-v-9c504ebc]::-webkit-scrollbar{display:none}.ui-scroll-area__viewport[data-v-9c504ebc]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.ui-scroll-area__bar[data-v-9c504ebc]{position:absolute;z-index:3;opacity:0;pointer-events:none;touch-action:none;transition:opacity var(--duration-base) var(--ease-out)}.ui-scroll-area__bar.is-visible[data-v-9c504ebc]{opacity:1;pointer-events:auto}.ui-scroll-area__bar--vertical[data-v-9c504ebc]{inset:2px 2px 2px auto;width:10px}.ui-scroll-area__bar--horizontal[data-v-9c504ebc]{inset:auto 2px 2px;height:10px}.ui-scroll-area__thumb[data-v-9c504ebc]{position:absolute;display:block;border-radius:999px;background:color-mix(in srgb,var(--color-text-muted) 62%,transparent);transition:background var(--duration-fast) var(--ease-out),width var(--duration-fast) var(--ease-out),height var(--duration-fast) var(--ease-out)}.ui-scroll-area__bar--vertical .ui-scroll-area__thumb[data-v-9c504ebc]{right:1px;width:4px}.ui-scroll-area__bar--horizontal .ui-scroll-area__thumb[data-v-9c504ebc]{bottom:1px;height:4px}.ui-scroll-area__bar:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__thumb[data-v-9c504ebc]:active{background:color-mix(in srgb,var(--color-text-muted) 82%,transparent)}.ui-scroll-area__bar--vertical:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__bar--vertical .ui-scroll-area__thumb[data-v-9c504ebc]:active{width:6px}.ui-scroll-area__bar--horizontal:hover .ui-scroll-area__thumb[data-v-9c504ebc],.ui-scroll-area__bar--horizontal .ui-scroll-area__thumb[data-v-9c504ebc]:active{height:6px}.ui-seg[data-v-27f5a180]{position:relative;display:inline-flex;gap:2px;padding:2px;background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md)}.ui-seg__indicator[data-v-27f5a180]{position:absolute;top:0;left:0;z-index:0;border-radius:var(--radius-sm);background:var(--color-surface-raised);box-shadow:var(--shadow-sm);opacity:0;pointer-events:none;transition:transform var(--duration-base) var(--ease-out),width var(--duration-base) var(--ease-out),height var(--duration-base) var(--ease-out),opacity var(--duration-fast) var(--ease-out)}.ui-seg__indicator.is-ready[data-v-27f5a180]{opacity:1}.ui-seg__item[data-v-27f5a180]{position:relative;z-index:1;display:inline-flex;align-items:center;gap:var(--space-1);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-weight:var(--weight-medium);cursor:pointer;line-height:1;white-space:nowrap;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.ui-seg__swatch[data-v-27f5a180]{width:7px;height:7px;border:.5px solid color-mix(in srgb,currentColor 22%,transparent);border-radius:50%;flex:none}.ui-seg__icon[data-v-27f5a180]{flex:none}.ui-seg--md .ui-seg__item[data-v-27f5a180]{padding:5px var(--space-3);font-size:var(--text-sm)}.ui-seg--sm .ui-seg__item[data-v-27f5a180]{height:24px;padding:0 var(--space-2);font-size:var(--text-sm)}.ui-seg--xs .ui-seg__item[data-v-27f5a180]{height:20px;padding:0 var(--space-2);font-size:var(--text-xs)}.ui-seg__item[data-v-27f5a180]:hover:not(.is-on){color:var(--color-text)}.ui-seg__item.is-on[data-v-27f5a180]{color:var(--color-text)}.ui-seg__item[data-v-27f5a180]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-select[data-v-63f5dcbc]{position:relative;width:100%;font-family:var(--font-ui)}.ui-select.is-open[data-v-63f5dcbc]{z-index:var(--z-dropdown)}.ui-select__trigger[data-v-63f5dcbc]{display:flex;align-items:center;gap:var(--space-2);width:100%;height:100%;padding:0 var(--space-3);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:transparent;box-shadow:none;color:var(--color-text);font:inherit;font-size:var(--text-base);line-height:var(--leading-normal);text-align:left;cursor:pointer;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out)}.ui-select--md[data-v-63f5dcbc]{height:38px}.ui-select--sm[data-v-63f5dcbc]{height:32px}.ui-select--sm .ui-select__trigger[data-v-63f5dcbc]{font-size:var(--text-sm)}.ui-select__trigger[data-v-63f5dcbc]:hover:not(:disabled){border-color:var(--color-line-strong)}.ui-select__trigger[data-v-63f5dcbc]:focus-visible,.ui-select.is-open .ui-select__trigger[data-v-63f5dcbc]{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.ui-select.has-error .ui-select__trigger[data-v-63f5dcbc]{border-color:var(--color-danger)}.ui-select.has-error .ui-select__trigger[data-v-63f5dcbc]:focus-visible{box-shadow:0 0 0 3px var(--color-danger-soft)}.ui-select__value[data-v-63f5dcbc]{min-width:0;flex:1;display:flex;align-items:center;gap:var(--space-2);overflow:hidden;white-space:nowrap}.ui-select__value-text[data-v-63f5dcbc]{min-width:0;overflow:hidden;text-overflow:ellipsis}.ui-select__value.is-placeholder[data-v-63f5dcbc]{color:var(--color-text-faint)}.ui-select__icon[data-v-63f5dcbc]{flex:none;width:14px;height:14px;border-radius:3px}.ui-select__icon--option[data-v-63f5dcbc]{width:16px;height:16px;border-radius:4px}.ui-select__chevron[data-v-63f5dcbc]{flex:none;color:var(--color-text-muted);transition:transform var(--duration-base) var(--ease-out)}.ui-select.is-open .ui-select__chevron[data-v-63f5dcbc]{transform:rotate(180deg)}.ui-select.is-disabled[data-v-63f5dcbc]{opacity:.5}.ui-select.is-disabled .ui-select__trigger[data-v-63f5dcbc]{cursor:not-allowed}.ui-select__menu[data-v-63f5dcbc]{position:absolute;z-index:var(--z-dropdown);top:calc(100% + var(--space-1));left:0;width:100%;max-height:260px;overflow-y:auto;padding:var(--space-1);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.ui-select__group[data-v-63f5dcbc]{padding:var(--space-2) var(--space-2) var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium)}.ui-select__option[data-v-63f5dcbc]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:32px;padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font:inherit;font-size:var(--text-sm);text-align:left;cursor:pointer}.ui-select__option.is-active[data-v-63f5dcbc]{background:var(--color-hover);color:var(--color-text-strong)}.ui-select__option[data-v-63f5dcbc]:disabled{opacity:.45;cursor:not-allowed}.ui-select__check[data-v-63f5dcbc]{flex:none;color:transparent}.ui-select__option.is-selected .ui-select__check[data-v-63f5dcbc]{color:var(--color-accent)}.kw-dot[data-v-b282847b]{width:7px;height:7px;border-radius:var(--radius-full);background:var(--color-text-faint);flex:none}.kw-dot--ok[data-v-b282847b]{background:var(--color-success)}.kw-dot--error[data-v-b282847b]{background:var(--color-danger)}.kw-dot--suspended[data-v-b282847b]{background:var(--color-warning)}.kw-dot--running[data-v-b282847b]{background:var(--color-accent);animation:kw-dot-pulse-b282847b 1.4s var(--ease-out) infinite}@keyframes kw-dot-pulse-b282847b{0%{box-shadow:0 0 color-mix(in srgb,var(--color-accent) 40%,transparent)}to{box-shadow:0 0 0 6px transparent}}.ui-switch[data-v-2fc56545]{position:relative;width:36px;height:20px;flex:none;padding:0;border:.5px solid var(--color-line-strong);border-radius:var(--radius-full);background:var(--color-line-strong);cursor:pointer;transition:background var(--duration-base) var(--ease-out)}.ui-switch.is-on[data-v-2fc56545]{background:var(--color-accent)}.ui-switch[data-v-2fc56545]:disabled{opacity:.5;cursor:not-allowed}.ui-switch[data-v-2fc56545]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ui-switch__thumb[data-v-2fc56545]{position:absolute;top:1.5px;left:1.5px;width:16px;height:16px;border-radius:var(--radius-full);background:var(--color-text-on-accent);box-shadow:var(--shadow-xs);transform-origin:left center;transition:transform var(--duration-base) var(--ease-out)}.ui-switch:not(:disabled):hover .ui-switch__thumb[data-v-2fc56545]{transform:scaleX(1.125)}.ui-switch.is-on .ui-switch__thumb[data-v-2fc56545]{transform:translate(16px);transform-origin:right center}.ui-switch.is-on:not(:disabled):hover .ui-switch__thumb[data-v-2fc56545]{transform:translate(16px) scaleX(1.125)}.ui-toast[data-v-62bc76d1]{display:flex;align-items:flex-start;gap:11px;width:360px;max-width:100%;padding:13px 14px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);font-family:var(--font-ui);line-height:1.45}.ui-toast__icon[data-v-62bc76d1]{flex:none;width:20px;height:20px;margin-top:1px;border-radius:var(--radius-full);display:grid;place-items:center;background:var(--color-accent-soft);color:var(--color-accent)}.ui-toast__icon svg[data-v-62bc76d1]{width:12px;height:12px}.ui-toast--success .ui-toast__icon[data-v-62bc76d1]{background:var(--color-success-soft);color:var(--color-success)}.ui-toast--warning .ui-toast__icon[data-v-62bc76d1]{background:var(--color-warning-soft);color:var(--color-warning)}.ui-toast--danger .ui-toast__icon[data-v-62bc76d1]{background:var(--color-danger-soft);color:var(--color-danger)}.ui-toast--danger[data-v-62bc76d1]{border-color:color-mix(in srgb,var(--color-danger) 35%,transparent)}.ui-toast__body[data-v-62bc76d1]{flex:1;min-width:0}.ui-toast__title[data-v-62bc76d1]{font-size:var(--text-base);font-weight:500;color:var(--color-text);overflow-wrap:anywhere}.ui-toast__msg[data-v-62bc76d1]{margin-top:2px;font-size:var(--text-sm);color:var(--color-text-muted);overflow-wrap:anywhere}.ui-toast--danger .ui-toast__msg[data-v-62bc76d1]{color:var(--color-danger)}.ui-toast__close[data-v-62bc76d1]{flex:none;margin:-3px -4px 0 0}.sd-search[data-v-d69c7a8c]{position:relative;margin:0 22px;padding-bottom:var(--space-1)}.sd-search[data-v-d69c7a8c] .ui-input{padding-right:30px}.search-clear[data-v-d69c7a8c]{position:absolute;top:0;bottom:var(--space-1);right:var(--space-2);margin-block:auto;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:var(--radius-full);background:var(--color-hover);color:var(--color-text-faint);cursor:pointer;visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast),background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.search-clear.is-on[data-v-d69c7a8c]{visibility:visible;opacity:1}.search-clear[data-v-d69c7a8c]:hover{background:var(--color-selected);color:var(--color-text-muted)}.search-clear[data-v-d69c7a8c]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}@media(prefers-reduced-motion:reduce){.search-clear[data-v-d69c7a8c]{transition:none}}.sd-body[data-v-d69c7a8c]{height:100%;min-height:0;display:flex;flex-direction:column;gap:var(--space-2);padding-top:4px}.sd-list[data-v-d69c7a8c]{flex:1;min-height:0;overflow-y:auto;padding:var(--space-1) var(--space-2)}.sd-row[data-v-d69c7a8c]{display:flex;flex-direction:column;gap:2px;width:100%;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-md);background:none;cursor:pointer;text-align:left;font-family:var(--font-ui);color:var(--color-text)}.sd-row[data-v-d69c7a8c]:hover{background:var(--color-hover)}.sd-row.on[data-v-d69c7a8c]{background:var(--color-selected)}.sd-row.active .sd-title[data-v-d69c7a8c]{color:var(--color-accent-hover)}.sd-meta[data-v-d69c7a8c]{display:flex;align-items:center;gap:var(--space-1);min-width:0;font-size:var(--text-xs);color:var(--color-text-muted)}.sd-folder[data-v-d69c7a8c]{flex:none;color:var(--color-text-muted)}.sd-ws[data-v-d69c7a8c]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-time[data-v-d69c7a8c]{flex:none;font-family:var(--font-mono);color:var(--color-text-faint)}.sd-title[data-v-d69c7a8c]{min-width:0;font-size:var(--text-base);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-snippet[data-v-d69c7a8c]{min-width:0;font-size:var(--text-sm);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sd-title[data-v-d69c7a8c] mark{background:var(--color-accent-soft);color:inherit;font-weight:var(--weight-semibold);border-radius:var(--radius-xs);padding:0 1px}.sd-meta[data-v-d69c7a8c] mark,.sd-snippet[data-v-d69c7a8c] mark{background:var(--color-accent-soft);color:var(--color-text);font-weight:var(--weight-medium);border-radius:var(--radius-xs);padding:0 1px}.sd-empty[data-v-d69c7a8c]{height:100%;display:flex;align-items:center;justify-content:center}.sd-foot[data-v-d69c7a8c]{flex:none;display:flex;align-items:center;gap:var(--space-1);padding:var(--space-2) var(--space-4);border-top:.5px solid var(--color-line);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.sd-hint[data-v-d69c7a8c]{display:inline-flex;align-items:center;gap:var(--space-1)}.sd-dot[data-v-d69c7a8c]{margin:0 var(--space-1)}:where(.markstream-vue) button{appearance:none;-webkit-appearance:none;-moz-appearance:none;background:transparent;border:0;font:inherit;color:inherit}.markstream-vue li:has(.checkbox-node){list-style-type:none;margin-left:calc(-1 * var(--ms-flow-list-indent))}.markstream-vue .text-node{white-space:pre-wrap;overflow-wrap:break-word}.\!container{width:100%!important}.container{width:100%}@media(min-width:640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media(min-width:768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media(min-width:1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media(min-width:1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media(min-width:1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.markstream-vue .sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.markstream-vue .pointer-events-none{pointer-events:none}.markstream-vue .\!visible{visibility:visible!important}.markstream-vue .visible{visibility:visible}.markstream-vue .collapse{visibility:collapse}.markstream-vue .static{position:static}.markstream-vue .fixed{position:fixed}.markstream-vue .absolute{position:absolute}.markstream-vue .relative{position:relative}.markstream-vue .inset-0{inset:0}.markstream-vue .right-2{right:8px}.markstream-vue .right-6{right:24px}.markstream-vue .top-2{top:8px}.markstream-vue .top-6{top:24px}.markstream-vue .z-10{z-index:10}.markstream-vue .z-50{z-index:50}.markstream-vue .m-0{margin:0}.markstream-vue .mx-0\.5{margin-left:2px;margin-right:2px}.markstream-vue .mr-2{margin-right:8px}.markstream-vue .mt-2{margin-top:8px}.markstream-vue .block{display:block}.markstream-vue .inline{display:inline}.markstream-vue .flex{display:flex}.markstream-vue .inline-flex{display:inline-flex}.markstream-vue .table{display:table}.markstream-vue .flow-root{display:flow-root}.markstream-vue .grid{display:grid}.markstream-vue .contents{display:contents}.markstream-vue .list-item{display:list-item}.markstream-vue .hidden{display:none}.markstream-vue .h-4{height:16px}.markstream-vue .h-full{height:100%}.markstream-vue .max-h-full{max-height:100%}.markstream-vue .min-h-full{min-height:100%}.markstream-vue .w-2\/3{width:66.666667%}.markstream-vue .w-4{width:16px}.markstream-vue .w-4\/5{width:80%}.markstream-vue .w-full{width:100%}.markstream-vue .min-w-\[160px\]{min-width:160px}.markstream-vue .max-w-full{max-width:100%}.markstream-vue .flex-1{flex:1 1 0%}.markstream-vue .flex-shrink{flex-shrink:1}.markstream-vue .flex-shrink-0{flex-shrink:0}.markstream-vue .shrink{flex-shrink:1}.markstream-vue .shrink-0{flex-shrink:0}.markstream-vue .border-collapse{border-collapse:collapse}.markstream-vue .transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.markstream-vue .animate-spin{animation:spin 1s linear infinite}.markstream-vue .cursor-grab{cursor:grab}.markstream-vue .cursor-grabbing{cursor:grabbing}.markstream-vue .cursor-not-allowed{cursor:not-allowed}.markstream-vue .cursor-pointer{cursor:pointer}.markstream-vue .resize{resize:both}.markstream-vue .list-decimal{list-style-type:decimal}.markstream-vue .list-disc{list-style-type:disc}.markstream-vue .flex-wrap{flex-wrap:wrap}.markstream-vue .items-center{align-items:center}.markstream-vue .items-baseline{align-items:baseline}.markstream-vue .justify-center{justify-content:center}.markstream-vue .justify-between{justify-content:space-between}.markstream-vue .gap-0\.5{gap:2px}.markstream-vue .gap-1\.5{gap:6px}.markstream-vue .gap-2{gap:8px}.markstream-vue .gap-\[var\(--ms-gap-header-actions\)\]{gap:var(--ms-gap-header-actions)}.markstream-vue .gap-x-1{-moz-column-gap:4px;column-gap:4px}.markstream-vue .gap-x-2{-moz-column-gap:8px;column-gap:8px}.markstream-vue .overflow-hidden{overflow:hidden}.markstream-vue .overflow-x-auto{overflow-x:auto}.markstream-vue .truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.markstream-vue .whitespace-nowrap{white-space:nowrap}.markstream-vue .whitespace-pre-wrap{white-space:pre-wrap}.markstream-vue .rounded{border-radius:calc(var(--ms-radius) * .5)}.markstream-vue .rounded-lg{border-radius:var(--ms-radius)}.markstream-vue .rounded-md{border-radius:calc(var(--ms-radius) * .75)}.markstream-vue .border{border-width:1px}.markstream-vue .border-b{border-bottom-width:1px}.markstream-vue .border-t{border-top-width:1px}.markstream-vue .border-\[var\(--code-border\)\]{border-color:var(--code-border)}.markstream-vue .border-\[var\(--footnote-border\)\]{border-color:var(--footnote-border)}.markstream-vue .border-\[var\(--hr-border\)\]{border-color:var(--hr-border)}.markstream-vue .bg-\[hsl\(var\(--ms-popover\)\)\]{background-color:hsl(var(--ms-popover))}.markstream-vue .bg-\[var\(--code-header-bg\)\]{background-color:var(--code-header-bg)}.markstream-vue .p-0{padding:0}.markstream-vue .p-1{padding:4px}.markstream-vue .p-4{padding:16px}.markstream-vue .p-\[var\(--ms-action-btn-padding\)\]{padding:var(--ms-action-btn-padding)}.markstream-vue .px-1\.5{padding-left:6px;padding-right:6px}.markstream-vue .px-2{padding-left:8px;padding-right:8px}.markstream-vue .px-4{padding-left:16px;padding-right:16px}.markstream-vue .px-\[var\(--ms-inset-panel-x\)\]{padding-left:var(--ms-inset-panel-x);padding-right:var(--ms-inset-panel-x)}.markstream-vue .py-0\.5{padding-top:2px;padding-bottom:2px}.markstream-vue .py-1\.5{padding-top:6px;padding-bottom:6px}.markstream-vue .py-\[var\(--ms-inset-panel-y\)\]{padding-top:var(--ms-inset-panel-y);padding-bottom:var(--ms-inset-panel-y)}.markstream-vue .pb-3{padding-bottom:12px}.markstream-vue .pt-2{padding-top:8px}.markstream-vue .text-left{text-align:left}.markstream-vue .text-center{text-align:center}.markstream-vue .text-right{text-align:right}.markstream-vue .font-mono{font-family:var(--ms-font-mono)}.markstream-vue .text-\[length\:var\(--ms-text-label\)\]{font-size:var(--ms-text-label)}.markstream-vue .text-sm{font-size:14px;line-height:20px}.markstream-vue .text-xs{font-size:12px;line-height:16px}.markstream-vue .font-medium{font-weight:500}.markstream-vue .font-semibold{font-weight:600}.markstream-vue .uppercase{text-transform:uppercase}.markstream-vue .lowercase{text-transform:lowercase}.markstream-vue .italic{font-style:italic}.markstream-vue .leading-\[normal\]{line-height:normal}.markstream-vue .leading-none{line-height:1}.markstream-vue .leading-relaxed{line-height:1.625}.markstream-vue .text-\[\#0366d6\]{--tw-text-opacity: 1;color:rgb(3 102 214 / var(--tw-text-opacity, 1))}.markstream-vue .text-\[hsl\(var\(--ms-popover-foreground\)\)\]{color:hsl(var(--ms-popover-foreground))}.markstream-vue .text-\[var\(--code-action-fg\)\]{color:var(--code-action-fg)}.markstream-vue .text-\[var\(--code-fg\)\]{color:var(--code-fg)}.markstream-vue .underline{text-decoration-line:underline}.markstream-vue .antialiased{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.markstream-vue .opacity-0{opacity:0}.markstream-vue .opacity-50{opacity:.5}.markstream-vue .shadow-\[var\(--ms-shadow-popover\)\]{--tw-shadow-color: var(--ms-shadow-popover);--tw-shadow: var(--tw-shadow-colored)}.markstream-vue .outline{outline-style:solid}.markstream-vue .blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.markstream-vue .filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.markstream-vue .backdrop-blur{--tw-backdrop-blur: blur(8px);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.markstream-vue .backdrop-filter{backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.markstream-vue .transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-\[height\]{transition-property:height;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.markstream-vue .ease-in-out{transition-timing-function:cubic-bezier(.4,0,.2,1)}.markstream-vue .ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.markstream-vue{--ms-background: 0 0% 100%;--ms-foreground: 0 0% 10%;--ms-muted: 0 0% 96.5%;--ms-muted-foreground: 0 0% 43%;--ms-secondary: 0 0% 93.5%;--ms-secondary-foreground: 0 0% 10%;--ms-accent: 0 0% 91%;--ms-accent-foreground: 0 0% 10%;--ms-primary: 0 0% 10%;--ms-primary-foreground: 0 0% 100%;--ms-destructive: 0 62% 52%;--ms-destructive-foreground: 0 0% 100%;--ms-border: 0 0% 87%;--ms-ring: 0 0% 10%;--ms-popover: 0 0% 100%;--ms-popover-foreground: 0 0% 10%;--ms-radius: 8px;--ms-info: 215 60% 50%;--ms-info-foreground: 0 0% 100%;--ms-success: 152 56% 39%;--ms-success-foreground: 0 0% 100%;--ms-warning: 38 64% 46%;--ms-warning-foreground: 0 0% 9%;--ms-diff-added: 152 50% 36%;--ms-diff-removed: 0 58% 48%;--ms-highlight: 50 60% 72%;--ms-highlight-foreground: 0 0% 0%;--ms-font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji";--ms-font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace}.dark .markstream-vue,.markstream-vue.dark{--ms-background: 0 0% 7%;--ms-foreground: 0 0% 93%;--ms-muted: 0 0% 12%;--ms-muted-foreground: 0 0% 60%;--ms-secondary: 0 0% 16%;--ms-secondary-foreground: 0 0% 93%;--ms-accent: 0 0% 24%;--ms-accent-foreground: 0 0% 93%;--ms-primary: 0 0% 93%;--ms-primary-foreground: 0 0% 10%;--ms-destructive: 0 60% 50%;--ms-destructive-foreground: 0 0% 93%;--ms-border: 0 0% 20%;--ms-ring: 0 0% 80%;--ms-popover: 0 0% 9%;--ms-popover-foreground: 0 0% 93%;--ms-info: 215 55% 62%;--ms-info-foreground: 0 0% 100%;--ms-success: 152 48% 55%;--ms-success-foreground: 0 0% 100%;--ms-warning: 32 65% 58%;--ms-warning-foreground: 0 0% 9%;--ms-diff-added: 152 42% 60%;--ms-diff-removed: 0 58% 58%;--ms-highlight: 48 65% 50%;--ms-highlight-foreground: 0 0% 0%;--ms-shadow-subtle: 0 1px 3px 0 hsl(0 0% 0% / .25);--ms-shadow-popover: 0 4px 6px -1px hsl(0 0% 0% / .2), 0 2px 4px -2px hsl(0 0% 0% / .15);--ms-shadow-modal: 0 10px 15px -3px hsl(0 0% 0% / .5), 0 4px 6px -4px hsl(0 0% 0% / .4);--ms-shadow-preview: 0 10px 40px hsl(0 0% 0% / .6);--tooltip-bg: hsl(0 0% 12%);--tooltip-fg: hsl(0 0% 72%);--code-header-bg: hsl(var(--ms-muted));--admonition-note-header-bg: color-mix(in srgb, hsl(var(--ms-info)) 12%, transparent);--admonition-tip-header-bg: color-mix(in srgb, hsl(var(--ms-success)) 12%, transparent);--admonition-warn-header-bg: color-mix(in srgb, hsl(var(--ms-warning)) 12%, transparent);--admonition-danger-header-bg: color-mix(in srgb, hsl(var(--ms-destructive)) 12%, transparent)}.markstream-vue{font-family:var(--ms-font-sans);font-size:var(--ms-text-body);line-height:var(--ms-leading-body);--inline-code-bg: hsl(var(--ms-secondary));--inline-code-fg: hsl(var(--ms-foreground) / .75);--inline-code-border: hsl(var(--ms-border) / .9);--code-bg: hsl(var(--ms-muted));--code-fg: hsl(var(--ms-foreground));--code-border: hsl(var(--ms-border));--code-header-bg: hsl(var(--ms-secondary));--code-selection-bg: hsl(var(--ms-accent) / .3);--code-line-number: hsl(var(--ms-muted-foreground));--markstream-code-line-number-align: right;--code-action-fg: hsl(var(--ms-muted-foreground));--code-action-hover-bg: hsl(var(--ms-accent));--code-action-hover-fg: hsl(var(--ms-accent-foreground));--code-action-active-bg: hsl(var(--ms-primary));--code-action-active-fg: hsl(var(--ms-primary-foreground));--diff-added-fg: hsl(var(--ms-diff-added));--diff-removed-fg: hsl(var(--ms-diff-removed));--diff-added-bg: hsl(var(--ms-diff-added) / .1);--diff-added-inline-bg: hsl(var(--ms-diff-added) / .2);--diff-removed-bg: hsl(var(--ms-diff-removed) / .1);--diff-removed-inline-bg: hsl(var(--ms-diff-removed) / .2);--blockquote-border: hsl(var(--ms-muted-foreground) / .2);--admonition-bg: hsl(var(--ms-muted));--admonition-border: hsl(var(--ms-border));--admonition-fg: hsl(var(--ms-foreground));--admonition-muted: hsl(var(--ms-muted-foreground));--admonition-header-bg: hsl(var(--ms-muted) / .5);--admonition-note: hsl(var(--ms-info));--admonition-tip: hsl(var(--ms-success));--admonition-warning: hsl(var(--ms-warning));--admonition-danger: hsl(var(--ms-destructive));--admonition-note-header-bg: color-mix(in srgb, hsl(var(--ms-info)) 6%, transparent);--admonition-tip-header-bg: color-mix(in srgb, hsl(var(--ms-success)) 6%, transparent);--admonition-warn-header-bg: color-mix(in srgb, hsl(var(--ms-warning)) 6%, transparent);--admonition-danger-header-bg: color-mix(in srgb, hsl(var(--ms-destructive)) 6%, transparent);--table-border: hsl(var(--ms-border));--table-header-bg: hsl(var(--ms-muted));--link-color: hsl(var(--ms-info));--list-marker: hsl(var(--ms-muted-foreground) / .5);--list-counter-marker: hsl(var(--ms-muted-foreground));--hr-border: hsl(var(--ms-border));--highlight-bg: hsl(var(--ms-highlight));--footnote-border: hsl(var(--ms-border));--tooltip-bg: hsl(0 0% 18%);--tooltip-fg: hsl(0 0% 88%);--tooltip-border: hsl(var(--ms-border));--modal-overlay: hsl(0 0% 0% / .7);--modal-bg: hsl(var(--ms-popover));--modal-fg: hsl(var(--ms-popover-foreground));--diagram-bg: hsl(var(--ms-muted));--diagram-border: hsl(var(--ms-border));--diagram-header-bg: hsl(var(--ms-muted));--loading-spinner: hsl(var(--ms-muted-foreground));--loading-shimmer: hsl(var(--ms-muted) / .5);--image-placeholder-bg: hsl(var(--ms-muted));--focus-ring: hsl(var(--ms-ring));--ms-space-1: 4px;--ms-space-1_5: 6px;--ms-space-2: 8px;--ms-space-2_5: 10px;--ms-space-3: 12px;--ms-space-4: 16px;--ms-space-5: 20px;--ms-space-6: 24px;--ms-space-8: 32px;--ms-space-12: 48px;--ms-flow-paragraph-y: 1.5em;--ms-flow-list-y: 1em;--ms-flow-list-item-y: .25em;--ms-flow-list-indent: 1.625em ;--ms-flow-list-indent-mobile: calc(14 / 9 * 1em);--ms-flow-table-y: 2em;--ms-flow-table-cell: .5em .75em;--ms-flow-blockquote-y: 1.25em;--ms-flow-blockquote-indent: 1.25em;--ms-flow-admonition-y: 1.25em;--ms-flow-footnote-y: .5em;--ms-flow-hr-y: 2.5em;--ms-flow-diagram-y: 1.5em;--ms-flow-codeblock-y: 1.5em;--ms-flow-definition-term-mt: .75em;--ms-flow-definition-desc-ml: 1.25em;--ms-flow-definition-desc-mb: .5em;--ms-flow-heading-1-mt: 0;--ms-flow-heading-1-mb: 1em;--ms-flow-heading-2-mt: 2em;--ms-flow-heading-2-mb: .75em;--ms-flow-heading-3-mt: 1.5em;--ms-flow-heading-3-mb: .6em;--ms-flow-heading-4-mt: 1.25em;--ms-flow-heading-4-mb: .4em;--ms-flow-heading-5-mt: 1em;--ms-flow-heading-5-mb: .25em;--ms-flow-heading-6-mt: 1em;--ms-flow-heading-6-mb: .25em;--ms-text-body: 16px;--ms-leading-body: 1.75;--ms-text-h1: 36px;--ms-text-h2: 24px;--ms-text-h3: 20px;--ms-text-h4: 16px;--ms-text-h5: 16px;--ms-text-h6: 16px;--ms-leading-h1: 1.2;--ms-leading-h2: 1.35;--ms-leading-h3: 1.5;--ms-weight-h1: 700;--ms-weight-h2: 600;--ms-weight-h3: 600;--ms-weight-h4: 600;--ms-text-label: 12px;--ms-action-btn-padding: 6px;--ms-action-btn-icon: 14px;--ms-inset-panel-x: 10px;--ms-inset-panel-y: 6px;--ms-inset-panel-body-sm: 8px;--ms-inset-panel-body: 16px;--ms-inset-admonition-body-top: 8px;--ms-inset-admonition-body-bottom: 12px;--ms-gap-header: var(--ms-space-4);--ms-gap-header-main: var(--ms-space-2_5);--ms-gap-header-actions: var(--ms-space-2);--ms-shadow-subtle: 0 1px 3px 0 hsl(var(--ms-foreground) / .06);--ms-shadow-popover: 0 4px 6px -1px hsl(var(--ms-foreground) / .1), 0 2px 4px -2px hsl(var(--ms-foreground) / .1);--ms-shadow-modal: 0 10px 15px -3px hsl(var(--ms-foreground) / .1), 0 4px 6px -4px hsl(var(--ms-foreground) / .1);--ms-shadow-preview: 0 10px 40px hsl(var(--ms-foreground) / .25);--ms-duration-fast: .12s;--ms-duration-standard: .18s;--ms-duration-overlay: .2s;--ms-duration-emphasis: .22s;--ms-duration-slow: .3s;--ms-duration-stream: .28s;--ms-ease-linear: linear;--ms-ease-standard: ease;--ms-ease-out: ease-out;--ms-ease-in-out: ease-in-out;--ms-ease-spring: cubic-bezier(.16, 1, .3, 1);--ms-border-width: 1px;--ms-border-width-strong: 4px;--ms-focus-ring-width: 2px;--ms-focus-ring-offset: 2px;--ms-size-diagram-min-height: 360px;--ms-size-code-max-height: 500px;--ms-size-image-max-width: 384px;--ms-size-image-min-width: 128px;--ms-size-image-min-height: 1.5em;--ms-size-math-min-height: 40px;--ms-size-skeleton-min-height: 120px}body>div[id^=dmermaid-]{position:fixed;top:-10000px;left:0;width:100%;visibility:hidden;pointer-events:none}.markstream-vue .hover\:bg-\[var\(--code-action-hover-bg\)\]:hover{background-color:var(--code-action-hover-bg)}.markstream-vue .hover\:text-\[var\(--code-action-hover-fg\)\]:hover{color:var(--code-action-hover-fg)}.markstream-vue .hover\:underline:hover{text-decoration-line:underline}.markstream-vue .active\:scale-\[0\.96\]:active{--tw-scale-x: .96;--tw-scale-y: .96;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.markstream-vue .disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.markstream-vue .disabled\:opacity-40:disabled{opacity:.4}.checkbox-node[data-v-be21ab83]{display:inline-flex;align-items:center;margin-right:.5em;vertical-align:-.15em}.checkbox-icon[data-v-be21ab83]{flex-shrink:0}.checkbox-unchecked[data-v-be21ab83]{color:hsl(var(--ms-muted-foreground) / .5)}.checkbox-checked[data-v-be21ab83]{color:hsl(var(--ms-info))}.emoji-node[data-v-de55dc97]{display:inline-block}.footnote-reference[data-v-c1463a29]{font-size:.75em;line-height:0}.footnote-link[data-v-c1463a29]{color:var(--link-color);text-decoration:none}.footnote-link[data-v-c1463a29]:hover{text-decoration:underline}.html-inline-node[data-v-d17f12b0]{display:inline}.html-inline-node--loading[data-v-d17f12b0]{opacity:.85}.inline-code[data-v-4e331c97]{display:inline;font-family:var(--ms-font-mono);font-size:.8125em;line-height:inherit;color:var(--inline-code-fg);background-color:var(--inline-code-bg);padding:.15em .35em;border-radius:.25em;white-space:normal;word-break:break-word;max-width:100%;-webkit-box-decoration-break:clone;box-decoration-break:clone}.inline-code-stream-delta[data-v-4e331c97]{animation-duration:var(--stream-update-fade-duration, var(--fade-duration, .28s));animation-timing-function:var(--stream-update-fade-ease, var(--fade-ease, cubic-bezier(.33, 0, .67, 1)));animation-fill-mode:both}.inline-code-stream-delta--a[data-v-4e331c97]{animation-name:inline-code-stream-update-fade-a-4e331c97}.inline-code-stream-delta--b[data-v-4e331c97]{animation-name:inline-code-stream-update-fade-b-4e331c97}@keyframes inline-code-stream-update-fade-a-4e331c97{0%{opacity:0}to{opacity:1}}@keyframes inline-code-stream-update-fade-b-4e331c97{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.inline-code-stream-delta[data-v-4e331c97]{animation:none!important}}.image-node-container[data-v-046e82ac]{display:inline-block;position:relative;vertical-align:middle;max-width:var(--ms-size-image-max-width)}.image-node__img[data-v-046e82ac]{display:inline-block;max-width:100%;min-width:var(--ms-size-image-min-width);min-height:var(--ms-size-image-min-height);height:auto;vertical-align:middle;transition:opacity var(--ms-duration-emphasis) var(--ms-ease-standard)}.image-node__img.is-loading[data-v-046e82ac]{opacity:0}.image-node__img.is-loaded[data-v-046e82ac]{opacity:1}.image-node__img.has-natural-size[data-v-046e82ac]{min-width:0;min-height:0}.image-placeholder[data-v-046e82ac]{display:inline-flex;align-items:center;justify-content:center;width:100%;min-width:var(--ms-size-image-min-width);min-height:128px;max-width:var(--ms-size-image-max-width);background:hsl(var(--ms-muted));overflow:hidden;vertical-align:middle}.image-shimmer-overlay[data-v-046e82ac]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:hsl(var(--ms-muted));overflow:hidden}.image-shimmer-overlay .image-shimmer[data-v-046e82ac]{width:100%;height:100%}.image-shimmer[data-v-046e82ac]{display:block;width:100%;height:100%;min-height:128px;background:linear-gradient(90deg,hsl(var(--ms-muted)),hsl(var(--ms-muted-foreground) / .06),hsl(var(--ms-muted)));background-size:200% 100%;animation:image-shimmer-046e82ac 1.5s ease-in-out infinite}.image-node-container[data-markstream-viewport-pending=true] .image-shimmer[data-v-046e82ac]{animation:none}@keyframes image-shimmer-046e82ac{0%{background-position:100% 0}to{background-position:-100% 0}}.image-error[data-v-046e82ac]{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:16px 24px;min-height:64px;max-width:var(--ms-size-image-max-width);background:hsl(var(--ms-muted));color:hsl(var(--ms-muted-foreground));font-size:var(--ms-text-label);vertical-align:middle}.image-node__raw-text[data-v-046e82ac]{font-size:var(--ms-text-label);color:hsl(var(--ms-muted-foreground))}@media(prefers-reduced-motion:reduce){.image-shimmer[data-v-046e82ac]{animation:none!important}}.markstream-vue pre[class^=language-],.markstream-vue pre[class*=" language-"]{white-space:pre;overflow:auto;-moz-tab-size:2;-o-tab-size:2;tab-size:2;font-variant-ligatures:none;contain:content;backface-visibility:hidden;transform:translateZ(0);-webkit-font-smoothing:antialiased}.markstream-vue pre[class^=language-]>code,.markstream-vue pre[class*=" language-"]>code{display:block}.markstream-vue pre.markstream-pre--line-numbers{position:relative}.markstream-vue pre.code-pre-fallback[data-markstream-code-loading="1"]{--markstream-pre-line-number-top: var(--markstream-code-padding-y, 8px);--markstream-pre-line-number-left: 0px;--markstream-pre-line-number-width: 2ch;--markstream-pre-line-number-padding-left: 2ch;--markstream-pre-line-number-padding-right: 1ch;--markstream-pre-line-number-separator-width: 2px;--markstream-code-padding-left: calc(6ch + 2px) ;box-sizing:border-box;width:100%;margin:0;padding:var(--markstream-code-padding-y, 8px) var(--markstream-code-padding-x, 12px);padding-left:var(--markstream-code-padding-left);overflow:auto;border:0;border-radius:0;background:var(--code-bg);color:var(--code-fg);font-family:var( --markstream-code-font-family, Menlo, Monaco, Courier New, monospace );font-size:var(--vscode-editor-font-size, 12px);line-height:var(--vscode-editor-line-height, 18px)}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers{position:absolute;top:var(--markstream-pre-line-number-top, 0);left:var(--markstream-pre-line-number-left, 0);box-sizing:content-box;display:flex;flex-direction:column;align-items:flex-end;width:var(--markstream-pre-line-number-width, 2ch);min-width:var(--markstream-pre-line-number-width, 2ch);padding-left:var(--markstream-pre-line-number-padding-left, 2ch);padding-right:var(--markstream-pre-line-number-padding-right, 1ch);border-right:var(--markstream-pre-line-number-separator-width, 2px) solid var(--code-bg);color:var(--code-line-number);font:inherit;font-variant-numeric:tabular-nums;line-height:inherit;pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.markstream-vue pre.markstream-pre--line-numbers:not(.markstream-pre--diff-preview):not(.code-pre-fallback)>.markstream-pre__code{box-sizing:border-box;min-width:100%;padding-left:var(--markstream-code-padding-left, 52px);padding-right:var(--markstream-code-padding-x, 12px)}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers>.markstream-pre__line-number{display:block;min-height:1lh}.markstream-vue pre.markstream-pre--line-numbers>.markstream-pre__line-numbers>.markstream-pre__line-numbers-text{display:block;min-height:1lh;text-align:right;white-space:pre}.markstream-vue pre.markstream-pre--diff-preview{box-sizing:border-box;padding-left:0;padding-right:0;width:100%;--markstream-pre-diff-gutter-marker-width: var(--stream-monaco-gutter-marker-width, 4px);--markstream-pre-diff-gutter-gap: var(--stream-monaco-gutter-gap, 1ch);--markstream-pre-diff-code-gap: var(--stream-monaco-diff-code-gap, 1ch);--markstream-pre-diff-code-padding: var(--stream-monaco-diff-code-padding, 0px);--markstream-diff-added-fg: var(--diff-added-fg, #2f8f68);--markstream-diff-removed-fg: var(--diff-removed-fg, #c24141);--markstream-diff-added-line-fill: var(--diff-added-bg, rgb(47 143 104 / 12%));--markstream-diff-removed-line-fill: var(--diff-removed-bg, rgb(194 65 65 / 12%));--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--markstream-pre-diff-gutter-marker-width), transparent var(--markstream-pre-diff-gutter-marker-width) 100% );--markstream-diff-removed-gutter: linear-gradient( 90deg, var(--markstream-diff-removed-fg) 0 var(--markstream-pre-diff-gutter-marker-width), transparent var(--markstream-pre-diff-gutter-marker-width) 100% );--markstream-pre-diff-line-number-width: var( --stream-monaco-line-number-width, 2ch );--markstream-pre-diff-line-number-padding-left: var(--stream-monaco-line-number-padding-left, 2ch);--markstream-pre-diff-line-number-padding-right: var(--stream-monaco-line-number-padding-right, 1ch);--markstream-pre-diff-line-number-separator-width: var(--stream-monaco-line-number-separator-width, 2px);--markstream-pre-diff-line-number-box-width: calc( var(--markstream-pre-diff-line-number-padding-left) + var(--markstream-pre-diff-line-number-width) + var(--markstream-pre-diff-line-number-padding-right) + var(--markstream-pre-diff-line-number-separator-width) );--markstream-pre-diff-line-number-bg: var( --stream-monaco-line-number-bg, var(--markstream-diff-line-number-bg, transparent) );--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-original-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px );--markstream-pre-diff-line-number-align: var(--markstream-diff-line-number-align, right);--markstream-pre-diff-code-fill-left: calc( var(--markstream-pre-diff-line-number-left) + var(--markstream-pre-diff-line-number-box-width) );--markstream-pre-diff-code-left: calc( var(--markstream-pre-diff-code-fill-left) + var(--markstream-pre-diff-line-number-gap-to-code) + var(--markstream-pre-diff-code-padding) )}.markstream-vue pre.markstream-pre--diff-preview::-webkit-scrollbar{width:12px;height:12px}.markstream-vue pre.markstream-pre--diff-preview.is-wrap{white-space:pre-wrap;overflow-wrap:anywhere}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline{--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-modified-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px )}.markstream-vue pre.markstream-pre--diff-preview>.markstream-pre__diff-code{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);font:inherit;line-height:inherit;min-width:100%;width:100%}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline>.markstream-pre__diff-code{grid-template-columns:minmax(0,1fr)}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline:not(.is-wrap)>.markstream-pre__diff-code{grid-template-columns:minmax(100%,max-content);width:100%;min-width:-moz-max-content;min-width:max-content}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane{min-width:0;overflow:hidden}.markstream-vue pre.markstream-pre--diff-preview:not(.is-wrap):not(.markstream-pre--diff-inline) .markstream-pre__diff-pane{overflow-x:auto;overflow-y:hidden}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane-content{display:block;min-width:100%}.markstream-vue pre.markstream-pre--diff-preview:not(.is-wrap):not(.markstream-pre--diff-inline) .markstream-pre__diff-pane-content{width:-moz-max-content;width:max-content}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline:not(.is-wrap) .markstream-pre__diff-pane{min-width:-moz-max-content;min-width:max-content;width:100%;overflow:visible}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-pane--modified{--markstream-pre-diff-pane-divider-width: 1px;--markstream-pre-diff-line-number-gap-to-code: var( --stream-monaco-modified-line-number-gap-to-code, var(--stream-monaco-line-number-gap-to-code, var(--markstream-pre-diff-code-gap)) );--markstream-pre-diff-line-number-left: var( --stream-monaco-line-number-left, 0px );box-shadow:inset 1px 0 var(--markstream-diff-pane-divider, hsl(var(--ms-border)))}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified{--markstream-pre-diff-line-number-left: calc( var(--stream-monaco-line-number-left, 0px) + var(--markstream-pre-diff-pane-divider-width) )}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-rail{left:var(--markstream-pre-diff-pane-divider-width)}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-line{padding-left:calc(var(--markstream-pre-diff-code-left) + var(--markstream-pre-diff-pane-divider-width))}.markstream-vue pre.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane--modified .markstream-pre__diff-line:before{left:calc(var(--markstream-pre-diff-code-fill-left) + var(--markstream-pre-diff-pane-divider-width))}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-inline .markstream-pre__diff-pane--modified{box-shadow:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line{position:relative;display:block;box-sizing:border-box;width:100%;min-width:100%;min-height:var( --markstream-pre-diff-synced-row-height, var(--markstream-pre-diff-line-height, 18px) );padding-left:var(--markstream-pre-diff-code-left);line-height:var(--markstream-pre-diff-line-height, 18px)}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line:before{content:"";position:absolute;left:var(--markstream-pre-diff-code-fill-left);right:0;top:0;height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );z-index:0;pointer-events:none;border-radius:0;background:transparent}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line:after{content:"";position:absolute;left:var(--markstream-pre-diff-line-number-left);top:0;width:var(--markstream-pre-diff-line-number-box-width);height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );z-index:0;pointer-events:none;background:var(--markstream-pre-diff-line-number-bg);box-shadow:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-rail{position:absolute;z-index:2;top:0;left:0;height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );width:var(--markstream-pre-diff-gutter-marker-width, 4px);min-width:var(--markstream-pre-diff-gutter-marker-width, 4px)}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-number{position:absolute;z-index:1;top:0;left:var(--markstream-pre-diff-line-number-left);width:var(--markstream-pre-diff-line-number-width);min-width:var(--markstream-pre-diff-line-number-width);height:var( --markstream-pre-diff-content-height, var(--markstream-pre-diff-line-height, 18px) );box-sizing:content-box;background:var(--markstream-pre-diff-line-number-bg);box-shadow:none;padding-left:var(--markstream-pre-diff-line-number-padding-left, 2ch);padding-right:var(--markstream-pre-diff-line-number-padding-right, 1ch);border-right:var(--markstream-pre-diff-line-number-separator-width, 2px) solid var(--stream-monaco-editor-bg, var(--code-bg));color:var(--code-line-number);font-variant-numeric:tabular-nums;line-height:var(--markstream-pre-diff-line-height, 18px);text-align:var(--markstream-pre-diff-line-number-align, right);-webkit-user-select:none;-moz-user-select:none;user-select:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-number{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent));color:var(--stream-monaco-added-fg, var(--markstream-diff-added-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-number{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent));color:var(--stream-monaco-removed-fg, var(--markstream-diff-removed-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-content{position:relative;z-index:1;display:block;width:-moz-max-content;width:max-content;min-width:100%;line-height:var(--markstream-pre-diff-line-height, 18px);white-space:inherit;overflow-wrap:normal;word-break:normal;line-break:auto}.markstream-vue pre.markstream-pre--diff-preview.is-wrap .markstream-pre__diff-content{width:auto;min-width:0;overflow-wrap:inherit}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-content-inner{white-space:inherit;overflow-wrap:inherit;word-break:inherit;line-break:inherit;-webkit-box-decoration-break:clone;box-decoration-break:clone}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--hunk{color:var(--stream-monaco-unchanged-fg, var(--markstream-diff-unchanged-fg, var(--code-line-number)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--hunk:before{background:var(--stream-monaco-unchanged-bg, var(--markstream-diff-unchanged-bg, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer:before{background-image:linear-gradient(-45deg,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 12.5%,transparent 12.5%,transparent 50%,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 50%,color-mix(in srgb,var(--stream-monaco-editor-fg, currentColor) 20%,transparent) 62.5%,transparent 62.5%,transparent 100%);background-size:10px 10px;opacity:.38}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer:after,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-rail,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-number,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--spacer>.markstream-pre__diff-content{display:none}.markstream-vue pre.markstream-pre--diff-preview.markstream-pre--diff-collapsed:not(.code-pre-fallback){height:auto!important;min-height:0!important}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed{min-height:28px;padding-left:0;color:var(--stream-monaco-unchanged-fg, var(--markstream-diff-unchanged-fg, var(--code-line-number)));line-height:28px}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed:before{left:0;height:28px;background:var(--stream-monaco-unchanged-bg, var(--markstream-diff-unchanged-bg, rgb(0 0 0 / 4%)))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed:after,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-rail,.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-number{display:none}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--collapsed>.markstream-pre__diff-content{width:100%;min-width:0;padding-left:calc(var(--markstream-pre-diff-code-left) + 12px);line-height:28px}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added:before{background:linear-gradient(var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent)),var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))),var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed:before{background:linear-gradient(var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent)),var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))),var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added:after{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed:after{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-rail{background:var(--stream-monaco-added-gutter, var(--markstream-diff-added-gutter, currentColor))}.markstream-vue pre.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-rail{background:var(--stream-monaco-removed-gutter, var(--markstream-diff-removed-gutter, currentColor))}.markstream-vue pre[class^=language-]:focus,.markstream-vue pre[class*=" language-"]:focus{outline:var(--ms-focus-ring-width) solid var(--focus-ring);outline-offset:var(--ms-focus-ring-offset)}.text-node[data-v-a7e90764]{display:inline;font-weight:inherit;vertical-align:baseline}.text-node-center[data-v-a7e90764]{display:inline-flex;justify-content:center;width:100%}.text-node-stream-delta[data-v-a7e90764]{animation-duration:var(--stream-update-fade-duration, var(--fade-duration, .28s));animation-timing-function:var(--stream-update-fade-ease, var(--fade-ease, cubic-bezier(.33, 0, .67, 1)));animation-fill-mode:both;will-change:opacity}.text-node-stream-delta--a[data-v-a7e90764]{animation-name:text-node-stream-update-fade-a-a7e90764}.text-node-stream-delta--b[data-v-a7e90764]{animation-name:text-node-stream-update-fade-b-a7e90764}@keyframes text-node-stream-update-fade-a-a7e90764{0%{opacity:0}to{opacity:1}}@keyframes text-node-stream-update-fade-b-a7e90764{0%{opacity:0}to{opacity:1}}@media(prefers-reduced-motion:reduce){.text-node-stream-delta[data-v-a7e90764]{animation:none!important}}.reference-node[data-v-775c65e4]{background-color:hsl(var(--ms-muted));color:hsl(var(--ms-muted-foreground))}.reference-node[data-v-775c65e4]:hover{background-color:hsl(var(--ms-secondary))}.superscript-node[data-v-24160b22]{font-size:.8em;vertical-align:super}.subscript-node[data-v-197fa13b]{font-size:.8em;vertical-align:sub}.strong-node[data-v-a8647104]{font-weight:700}.strikethrough-node[data-v-b7a531fa]{text-decoration:line-through}.link-node[data-v-367e6ca4]{color:var(--link-color);text-decoration:none}.link-node[data-v-367e6ca4]:hover{text-decoration:underline;text-underline-offset:3.2px}.link-loading .link-text-wrapper[data-v-367e6ca4]{position:relative}.link-loading[data-v-367e6ca4]{color:var(--link-color)}.link-loading .link-text[data-v-367e6ca4]{position:relative;z-index:2}.link-loading-indicator[data-v-367e6ca4]{position:absolute;left:0;right:0;height:var(--underline-height, 2px);bottom:var(--underline-bottom, -3px);background:currentColor;border-radius:999px;will-change:opacity;opacity:var(--underline-rest-opacity, .18);animation:underlinePulse-367e6ca4 var(--underline-duration, 1.6s) var(--underline-timing, ease-in-out) var(--underline-iteration, infinite)}@keyframes underlinePulse-367e6ca4{0%,to{opacity:var(--underline-rest-opacity, .18)}50%{opacity:var(--underline-opacity, .35)}}@media(prefers-reduced-motion:reduce){.link-loading-indicator[data-v-367e6ca4]{animation:none;opacity:var(--underline-rest-opacity, .18)}}.insert-node[data-v-1e2c29d4]{text-decoration:underline}.highlight-node[data-v-7a62982a]{background-color:var(--highlight-bg);padding:0 3.2px;border-radius:.2em}.emphasis-node[data-v-2a5aafbf]{font-style:italic}.hard-break[data-v-50c58f70]{display:block}.blockquote[data-v-abfecebc]{font-weight:400;font-style:normal;color:var(--blockquote-fg, hsl(var(--ms-muted-foreground)));border-left:3px solid var(--blockquote-border);margin-top:var(--ms-flow-blockquote-y);margin-bottom:var(--ms-flow-blockquote-y);padding-left:var(--ms-flow-blockquote-indent)}.blockquote>.paragraph-node[data-v-abfecebc]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:var(--ms-flow-paragraph-y) 0}.blockquote>.paragraph-node[data-v-abfecebc]:first-child{margin-top:0}.blockquote>.paragraph-node[data-v-abfecebc]:last-child{margin-bottom:0}.blockquote[data-v-abfecebc] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.definition-list[data-v-4e103b30]{margin:0 0 16px}.definition-term[data-v-4e103b30]{font-weight:600;margin-top:var(--ms-flow-definition-term-mt)}.definition-desc[data-v-4e103b30]{margin-left:var(--ms-flow-definition-desc-ml);margin-bottom:var(--ms-flow-definition-desc-mb)}.definition-list[data-v-4e103b30] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.footnote-anchor[data-v-e1eb37b6]{margin-left:8px;color:var(--link-color)}.footnote-node{margin-top:var(--ms-flow-footnote-y);margin-bottom:var(--ms-flow-footnote-y)}.markstream-vue [class*=footnote-] .markdown-renderer,.markstream-vue .flex-1 .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.heading-node[data-v-7122dbe1]{font-weight:500;line-height:1.25}hr+.heading-node[data-v-7122dbe1]{margin-top:0}.heading-1[data-v-7122dbe1]{font-size:var(--ms-text-h1);line-height:var(--ms-leading-h1);font-weight:var(--ms-weight-h1);margin-top:var(--ms-flow-heading-1-mt);margin-bottom:var(--ms-flow-heading-1-mb)}.heading-2[data-v-7122dbe1]{font-size:var(--ms-text-h2);line-height:var(--ms-leading-h2);font-weight:var(--ms-weight-h2);margin-top:var(--ms-flow-heading-2-mt);margin-bottom:var(--ms-flow-heading-2-mb)}.heading-3[data-v-7122dbe1]{font-size:var(--ms-text-h3);line-height:var(--ms-leading-h3);font-weight:var(--ms-weight-h3);margin-top:var(--ms-flow-heading-3-mt);margin-bottom:var(--ms-flow-heading-3-mb)}.heading-4[data-v-7122dbe1]{font-size:var(--ms-text-h4);font-weight:var(--ms-weight-h4);margin-top:var(--ms-flow-heading-4-mt);margin-bottom:var(--ms-flow-heading-4-mb)}.heading-5[data-v-7122dbe1]{font-size:var(--ms-text-h5);margin-top:var(--ms-flow-heading-5-mt);margin-bottom:var(--ms-flow-heading-5-mb)}.heading-6[data-v-7122dbe1]{font-size:var(--ms-text-h6);margin-top:var(--ms-flow-heading-6-mt);margin-bottom:var(--ms-flow-heading-6-mb)}.list-item[data-v-617214f9]{margin:var(--ms-flow-list-item-y) 0;padding-left:var(--ms-space-1_5)}ol>.list-item[data-v-617214f9]::marker{color:var(--list-counter-marker);line-height:1.6}ul>.list-item[data-v-617214f9]::marker{color:var(--list-marker)}.list-item>.paragraph-node[data-v-617214f9]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:0}.list-item[data-v-617214f9] .markdown-renderer{content-visibility:visible;contain-intrinsic-size:0px 0px;contain:content}.list-node[data-v-99cb95e0]{margin-top:var(--ms-flow-list-y);margin-bottom:var(--ms-flow-list-y);padding-left:var(--ms-flow-list-indent)}.list-decimal[data-v-99cb95e0]{list-style-type:decimal}.list-disc[data-v-99cb95e0]{list-style-type:disc}@media(max-width:1023px){.list-disc[data-v-99cb95e0]{margin-top:calc(4/3*1em);margin-bottom:calc(4/3*1em);padding-left:var(--ms-flow-list-indent-mobile)}}.html-block-node__raw[data-v-e140a874]{white-space:pre-wrap;overflow-wrap:anywhere;opacity:.85}.html-block-node__placeholder[data-v-e140a874]{display:flex;flex-direction:column;gap:5.6px;padding:8px 0}.html-block-node__placeholder-bar[data-v-e140a874]{display:block;height:12.8px;border-radius:9999px;background-image:linear-gradient(90deg,var(--loading-shimmer),transparent,var(--loading-shimmer));background-size:200% 100%}.paragraph-node[data-v-c59ff506]{font-size:var(--ms-text-body);line-height:var(--ms-leading-body);margin:var(--ms-flow-paragraph-y) 0}li .paragraph-node[data-v-c59ff506]{margin:0}.table-node-wrapper[data-v-39f87b5d]{position:relative;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;overscroll-behavior-y:auto;scrollbar-gutter:stable}.table-node[data-v-39f87b5d]{width:100%;table-layout:fixed;border-collapse:separate;border-spacing:0;margin:var(--ms-flow-table-y) 0;font-size:inherit;border:1px solid var(--table-border);border-radius:var(--ms-radius);overflow:hidden;box-shadow:var(--ms-shadow-subtle)}.table-node[data-v-39f87b5d] th,.table-node[data-v-39f87b5d] td{border-bottom:1px solid var(--table-border);border-right:1px solid var(--table-border);padding:var(--ms-flow-table-cell);white-space:normal;overflow-wrap:break-word;word-break:normal}.table-node[data-v-39f87b5d] th:last-child,.table-node[data-v-39f87b5d] td:last-child{border-right:none}.table-node[data-v-39f87b5d] tbody tr:last-child td{border-bottom:none}.table-node[data-v-39f87b5d] thead th{position:relative;font-weight:600;background-color:var(--table-header-bg);border-bottom-width:2px}.table-node__resize-handle[data-v-39f87b5d]{position:absolute;top:0;right:-4px;bottom:0;z-index:1;width:8px;padding:0;border:0;background:transparent;cursor:col-resize;touch-action:none}.table-node__resize-handle[data-v-39f87b5d]:after{content:"";position:absolute;top:.35em;bottom:.35em;left:50%;width:2px;border-radius:9999px;background:color-mix(in srgb,var(--table-border) 45%,hsl(var(--ms-foreground)));opacity:0;transform:translate(-50%);transition:opacity var(--ms-duration-fast) var(--ms-ease-standard)}.table-node__resize-handle[data-v-39f87b5d]:hover:after,.table-node__resize-handle[data-v-39f87b5d]:focus-visible:after{opacity:1}.table-node[data-v-39f87b5d] tbody tr:nth-child(2n){background-color:hsl(var(--ms-muted) / .35)}.table-node[data-v-39f87b5d] tbody tr:hover{background-color:var(--code-action-hover-bg)}.table-node--loading tbody td[data-v-39f87b5d]{position:relative;overflow:hidden}.table-node--loading tbody td[data-v-39f87b5d]>*{visibility:hidden}.table-node--loading tbody td[data-v-39f87b5d]:after{content:"";position:absolute;inset:0;border-radius:calc(var(--ms-radius) * .5);background:linear-gradient(90deg,var(--loading-shimmer) 25%,var(--loading-shimmer) 50%,var(--loading-shimmer) 75%);background-size:200% 100%;animation:table-node-shimmer-39f87b5d 1.2s linear infinite;will-change:background-position}.table-node__loading[data-v-39f87b5d]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;pointer-events:none}.table-node__spinner[data-v-39f87b5d]{width:40px;height:40px;border-radius:9999px;border:2px solid color-mix(in srgb,var(--loading-spinner) 25%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);will-change:transform}.table-node-fade-enter-active[data-v-39f87b5d],.table-node-fade-leave-active[data-v-39f87b5d]{transition:opacity var(--ms-duration-standard) var(--ms-ease-standard)}.table-node-fade-enter-from[data-v-39f87b5d],.table-node-fade-leave-to[data-v-39f87b5d]{opacity:0}[data-v-39f87b5d] .table-node .markdown-renderer{display:contents;content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}[data-v-39f87b5d] .table-node .markdown-renderer .node-slot,[data-v-39f87b5d] .table-node .markdown-renderer .node-content,[data-v-39f87b5d] .table-node .markdown-renderer .node-space{display:contents}[data-v-39f87b5d] .table-node .text-node,[data-v-39f87b5d] .table-node code{white-space:inherit;overflow-wrap:inherit;word-break:inherit;max-width:none}@keyframes table-node-shimmer-39f87b5d{0%{background-position:0% 0%}50%{background-position:100% 0%}to{background-position:200% 0%}}.hr+.table-node-wrapper[data-v-39f87b5d]{margin-top:0}.hr+.table-node-wrapper .table-node[data-v-39f87b5d]{margin-top:0}.sr-only[data-v-39f87b5d]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.hr-node[data-v-39b2349c]{border-top-width:1px;border-color:var(--hr-border);margin:var(--ms-flow-hr-y) 0}.vmr-container[data-v-911e41c4]{margin-top:16px;margin-bottom:16px;border-radius:var(--ms-radius);border-width:1px;padding:16px;border-left-width:var(--ms-border-width-strong)}.height-estimation-probes[data-v-3e0766e2]{position:absolute;left:-100000px;top:0;visibility:hidden;pointer-events:none;overflow:hidden;z-index:-1}.node-content[data-v-3e0766e2]{width:100%}.node-content-flow-root[data-v-3e0766e2]{display:flow-root}.markdown-renderer[data-v-a9489508]{position:relative;contain:layout;content-visibility:auto;contain-intrinsic-size:800px 600px}.markdown-renderer.virtualized[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated[data-v-a9489508]{content-visibility:visible;contain-intrinsic-size:auto}.markdown-renderer.stable-layout[data-v-a9489508]{content-visibility:visible;contain-intrinsic-size:none}.node-slot[data-v-a9489508],.node-content[data-v-a9489508]{width:100%}.markdown-renderer.virtualized .node-slot[data-v-a9489508],.markdown-renderer.virtualized .node-content[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated .node-slot[data-v-a9489508],.markdown-renderer.virtual-scroll-coordinated .node-content[data-v-a9489508]{display:flow-root}.node-placeholder[data-v-a9489508]{width:100%;min-height:16px;margin:4px 0}.node-placeholder[data-v-a9489508]:first-child{margin-top:0}.node-spacer[data-v-a9489508]{width:100%}.unknown-node[data-v-a9489508]{color:hsl(var(--ms-muted-foreground));font-style:italic;margin:var(--ms-flow-paragraph-y) 0}.typewriter-cursor[data-v-a9489508]{position:absolute;left:0;top:0;display:inline-block;width:.55em;height:1em;margin-left:.08em;vertical-align:-.12em;border-right:2px solid currentColor;pointer-events:none;visibility:hidden;animation:typewriter-cursor-blink-a9489508 1s steps(1,end) infinite}@keyframes typewriter-cursor-blink-a9489508{0%,49%{opacity:1}50%,to{opacity:0}}.markstream-vue.typewriter-simple-cursor .typewriter-simple-cursor-target:after{content:"";display:inline-block;width:.55em;height:1em;margin-left:.08em;vertical-align:-.12em;border-right:2px solid currentColor;pointer-events:none;animation:typewriter-cursor-blink 1s steps(1,end) infinite}@media(prefers-reduced-motion:reduce){.markstream-vue.typewriter-simple-cursor .typewriter-simple-cursor-target:after{animation:none}}.markstream-vue .fade-enter-from{opacity:0}.markstream-vue .fade-enter-active{transition:opacity var(--fade-duration, .28s) var(--fade-ease, cubic-bezier(.33, 0, .67, 1));will-change:opacity}.markstream-vue .fade-enter-to{opacity:1}.admonition[data-v-a83480e1]{position:relative;margin:var(--ms-flow-admonition-y) 0;padding:.25em .75em .375em;border:1px solid var(--admonition-border);border-radius:var(--ms-radius);color:var(--admonition-fg)}.admonition-legend[data-v-a83480e1]{position:absolute;top:0;left:.75em;transform:translateY(-50%);display:inline-flex;align-items:center;gap:.35em;padding:0 .5em;background-color:hsl(var(--ms-background));font-size:13px;font-weight:600;line-height:1}.admonition-icon[data-v-a83480e1]{flex-shrink:0}.admonition-title[data-v-a83480e1]{white-space:nowrap}.admonition-content[data-v-a83480e1]{padding-top:.25em;color:var(--admonition-fg)}.admonition-note[data-v-a83480e1],.admonition-info[data-v-a83480e1]{border-color:hsl(var(--ms-info) / .3);background-color:hsl(var(--ms-info) / .04)}.admonition-note .admonition-legend[data-v-a83480e1],.admonition-info .admonition-legend[data-v-a83480e1]{color:var(--admonition-note)}.admonition-tip[data-v-a83480e1]{border-color:hsl(var(--ms-success) / .3);background-color:hsl(var(--ms-success) / .04)}.admonition-tip .admonition-legend[data-v-a83480e1]{color:var(--admonition-tip)}.admonition-warning[data-v-a83480e1],.admonition-caution[data-v-a83480e1]{border-color:hsl(var(--ms-warning) / .3);background-color:hsl(var(--ms-warning) / .04)}.admonition-warning .admonition-legend[data-v-a83480e1],.admonition-caution .admonition-legend[data-v-a83480e1]{color:var(--admonition-warning)}.admonition-danger[data-v-a83480e1],.admonition-error[data-v-a83480e1]{border-color:hsl(var(--ms-destructive) / .3);background-color:hsl(var(--ms-destructive) / .04)}.admonition-danger .admonition-legend[data-v-a83480e1],.admonition-error .admonition-legend[data-v-a83480e1]{color:var(--admonition-danger)}.admonition-toggle[data-v-a83480e1]{margin-left:.25em;background:transparent;border:none;color:inherit;cursor:pointer;padding:2px;border-radius:calc(var(--ms-radius) * .5);display:inline-flex;align-items:center;transition:background-color var(--ms-duration-fast) var(--ms-ease-standard)}.admonition-toggle[data-v-a83480e1]:hover{background-color:hsl(var(--ms-accent))}.admonition-toggle[data-v-a83480e1]:focus-visible{outline:var(--ms-focus-ring-width) solid var(--focus-ring);outline-offset:var(--ms-focus-ring-offset)}.admonition-content[data-v-a83480e1] .markdown-renderer{content-visibility:visible;contain:content;contain-intrinsic-size:0px 0px}.tooltip-element[data-v-c606ee4c]{z-index:9999;display:inline-block;max-width:320px;padding:4px 8px;border-radius:calc(var(--ms-radius) * .75);font-size:12px;line-height:1.4;white-space:normal;word-break:break-word;pointer-events:none;background-color:var(--tooltip-bg);color:var(--tooltip-fg);box-shadow:inset 0 1px #ffffff26,0 0 0 1px #0000001f,var(--ms-shadow-popover);transition:transform var(--ms-duration-emphasis) var(--ms-ease-spring),box-shadow var(--ms-duration-emphasis) var(--ms-ease-spring)}.tooltip-arrow[data-v-c606ee4c]{position:absolute;width:6px;height:6px;background:inherit;transform:rotate(45deg)}.tooltip-arrow[data-placement^=top][data-v-c606ee4c]{bottom:-3px}.tooltip-arrow[data-placement^=bottom][data-v-c606ee4c]{top:-3px}.tooltip-arrow[data-placement^=left][data-v-c606ee4c]{right:-3px}.tooltip-arrow[data-placement^=right][data-v-c606ee4c]{left:-3px}.tooltip-enter-active[data-v-c606ee4c]{transition:opacity .18s cubic-bezier(.16,1,.3,1),transform .18s cubic-bezier(.16,1,.3,1)}.tooltip-leave-active[data-v-c606ee4c]{transition:opacity .12s ease-in,transform .12s ease-in}.tooltip-enter-from[data-v-c606ee4c]{opacity:0;transform:scale(.96)}.tooltip-enter-to[data-v-c606ee4c],.tooltip-leave-from[data-v-c606ee4c]{opacity:1;transform:scale(1)}.tooltip-leave-to[data-v-c606ee4c]{opacity:0;transform:scale(.97)}.code-block-container{margin:var(--ms-flow-codeblock-y) 0;contain:layout style;container-type:inline-size;background:var(--code-bg);border-color:var(--code-border);color:var(--code-fg);box-shadow:var(--ms-shadow-subtle)}.code-block-header{position:relative;z-index:1;gap:var(--ms-gap-header);border-radius:var(--ms-radius) var(--ms-radius) 0 0;overflow:visible}.code-block-header .code-header-main{min-width:0;flex:1 1 auto;display:flex;align-items:center;gap:var(--ms-gap-header-main);overflow:hidden}.code-block-header .code-header-copy{min-width:0;display:grid;gap:2px}.code-block-header .code-header-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--ms-text-label);font-weight:500;color:var(--code-action-fg)}.code-block-header .code-header-caption{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;color:var(--code-line-number)}.code-block-header .code-header-actions{display:flex;align-items:center;justify-content:flex-end;gap:var(--ms-gap-header-actions);flex-wrap:wrap}.code-block-header .icon-slot{display:inline-flex;align-items:center;justify-content:center}.code-block-header .icon-slot svg,.code-block-header .icon-slot img{display:block;width:100%;height:100%}.code-diff-stats{display:inline-flex;align-items:center;gap:var(--ms-space-1_5);margin-right:var(--ms-space-1);font-size:var(--ms-text-label);font-weight:600;line-height:1;font-variant-numeric:tabular-nums}.code-diff-stat{display:inline-flex;align-items:center;padding:2px 6px;border-radius:var(--ms-radius);line-height:1}.code-diff-stat.removed{color:var(--diff-removed-fg);background:hsl(var(--ms-diff-removed) / .1)}.code-diff-stat.added{color:var(--diff-added-fg);background:hsl(var(--ms-diff-added) / .1)}.code-more-menu{position:absolute;top:100%;right:0;margin-top:4px;z-index:50;border-radius:var(--ms-radius)}.code-block-shell-content,.code-loading-placeholder{overflow:hidden;border-radius:0 0 var(--ms-radius) var(--ms-radius);contain:content}.code-block-shell-content--collapsed{height:0;min-height:0;visibility:hidden;pointer-events:none}.code-menu-enter-active,.code-menu-leave-active{transform-origin:top right}.code-menu-enter-active{transition:opacity .22s cubic-bezier(.16,1,.3,1),transform .22s cubic-bezier(.16,1,.3,1)}.code-menu-leave-active{transition:opacity .14s ease-in,transform .14s ease-in}.code-menu-enter-from{opacity:0;transform:scale(.9) translateY(-4px)}.code-menu-leave-to{opacity:0;transform:scale(.95) translateY(-2px)}.html-preview-frame__backdrop[data-v-24e66176]{position:fixed;inset:0;background-color:var(--modal-overlay);display:flex;align-items:center;justify-content:center;z-index:50}.html-preview-frame[data-v-24e66176]{width:80vw;max-width:960px;height:70vh;background-color:var(--modal-bg);color:var(--modal-fg);border-radius:calc(var(--ms-radius) * 2);overflow:hidden;box-shadow:var(--ms-shadow-preview);display:flex;flex-direction:column}.html-preview-frame__header[data-v-24e66176]{display:flex;justify-content:space-between;align-items:center;padding:6.4px 12px;border-bottom:1px solid var(--code-border)}.html-preview-frame__title[data-v-24e66176]{display:inline-flex;align-items:center;gap:6.4px;font-size:12px;font-weight:500;letter-spacing:.02em;text-transform:uppercase;opacity:.85}.html-preview-frame__dot[data-v-24e66176]{width:8px;height:8px;border-radius:999px;background-color:hsl(var(--ms-success))}.html-preview-frame__label[data-v-24e66176]{white-space:nowrap}.html-preview-frame__close[data-v-24e66176]{border:none;background:transparent;font-size:20px;line-height:1;cursor:pointer;color:var(--modal-fg)}.html-preview-frame__iframe[data-v-24e66176]{width:100%;height:100%;border:none;display:block}@media(max-width:640px){.html-preview-frame[data-v-24e66176]{width:100vw;height:80vh;border-radius:0}}.code-block-container[data-v-72200115]{--markstream-code-fallback-bg: var(--code-bg);--markstream-code-fallback-fg: var(--code-fg);--markstream-code-border-color: var(--code-border);--vscode-editor-selectionBackground: var(--markstream-code-fallback-selection-bg);--markstream-code-fallback-selection-bg: var(--code-selection-bg);--markstream-diff-frame-border: var(--code-border);--markstream-diff-frame-shadow: 0 16px 40px -32px hsl(var(--ms-foreground) / .18);--markstream-diff-shell-fg: hsl(var(--ms-foreground));--markstream-diff-shell-muted: hsl(var(--ms-muted-foreground));--markstream-diff-shell-border: var(--code-border);--markstream-diff-shell-shadow: var(--ms-shadow-subtle);--markstream-diff-shell-bg: var(--code-bg);--markstream-diff-header-border: hsl(var(--ms-border) / .92);--markstream-diff-editor-bg: hsl(var(--ms-background));--markstream-diff-editor-fg: hsl(var(--ms-foreground));--markstream-diff-unchanged-fg: hsl(var(--ms-foreground));--markstream-diff-unchanged-bg: hsl(var(--ms-muted));--markstream-diff-unchanged-divider: hsl(var(--ms-background) / .94);--markstream-diff-focus: var(--focus-ring);--markstream-diff-widget-shadow: hsl(var(--ms-foreground) / .26);--markstream-diff-action-hover: var(--code-action-hover-bg);--markstream-diff-panel-bg: linear-gradient(180deg, var(--code-bg) 0%, hsl(var(--ms-muted)) 100%);--markstream-diff-panel-bg-soft: var(--code-bg);--markstream-diff-panel-bg-strong: var(--code-bg);--markstream-diff-panel-border: hsl(var(--ms-border) / .3);--markstream-diff-pane-divider: hsl(var(--ms-border) / .42);--markstream-diff-gutter-bg: transparent;--markstream-diff-gutter-guide: hsl(var(--ms-border) / .72);--markstream-diff-gutter-gap: 8px;--markstream-diff-line-number-bg: hsl(var(--ms-muted) / .45);--markstream-diff-line-number: var(--code-line-number);--markstream-diff-line-number-active: var(--code-line-number);--markstream-diff-added-fg: var(--diff-added-fg);--markstream-diff-removed-fg: var(--diff-removed-fg);--markstream-diff-added-line: var(--diff-added-bg);--markstream-diff-removed-line: var(--diff-removed-bg);--markstream-diff-added-inline: var(--diff-added-inline-bg);--markstream-diff-removed-inline: var(--diff-removed-inline-bg);--markstream-diff-added-inline-border: transparent;--markstream-diff-removed-inline-border: transparent;--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--stream-monaco-gutter-marker-width, 4px), transparent var(--stream-monaco-gutter-marker-width, 4px) 100% );--markstream-diff-removed-gutter: repeating-linear-gradient( 180deg, var(--markstream-diff-removed-fg) 0 2px, transparent 2px 4px ) left / var(--stream-monaco-gutter-marker-width, 4px) 100% no-repeat;--markstream-diff-added-line-fill: var(--diff-added-bg);--markstream-diff-removed-line-fill: var(--diff-removed-bg)}.code-block-container.is-dark[data-v-72200115]{--markstream-code-fallback-bg: var(--code-bg);--markstream-code-fallback-fg: var(--code-fg);--markstream-code-border-color: var(--code-border);--markstream-code-fallback-selection-bg: var(--code-selection-bg);--markstream-diff-frame-border: var(--code-border);--markstream-diff-frame-shadow: 0 18px 40px -30px hsl(var(--ms-foreground) / .84);--markstream-diff-shell-fg: hsl(var(--ms-foreground));--markstream-diff-shell-muted: hsl(var(--ms-muted-foreground));--markstream-diff-shell-border: var(--code-border);--markstream-diff-shell-shadow: var(--ms-shadow-subtle);--markstream-diff-shell-bg: var(--code-bg);--markstream-diff-header-border: hsl(var(--ms-border) / .82);--markstream-diff-editor-bg: #121212;--markstream-diff-editor-fg: #e5e5e5;--markstream-diff-unchanged-fg: #d4d4d4;--markstream-diff-unchanged-bg: #262626;--markstream-diff-unchanged-divider: hsl(0 0% 100% / .08);--markstream-diff-focus: var(--focus-ring);--markstream-diff-widget-shadow: hsl(var(--ms-foreground) / .72);--markstream-diff-action-hover: var(--code-action-hover-bg);--markstream-diff-panel-bg: #121212;--markstream-diff-panel-bg-soft: #121212;--markstream-diff-panel-bg-strong: #121212;--markstream-diff-panel-border: hsl(var(--ms-border) / .3);--markstream-diff-pane-divider: hsl(var(--ms-border) / .34);--markstream-diff-gutter-bg: linear-gradient( 180deg, hsl(0 0% 7% / .94) 0%, hsl(0 0% 7% / .98) 100% );--markstream-diff-gutter-guide: hsl(var(--ms-muted-foreground) / .08);--markstream-diff-gutter-gap: 8px;--markstream-diff-line-number-bg: hsl(0 0% 7% / .98);--markstream-diff-line-number: var(--code-line-number);--markstream-diff-line-number-active: var(--code-line-number);--markstream-diff-added-fg: hsl(152 42% 60%);--markstream-diff-removed-fg: hsl(0 58% 58%);--markstream-diff-added-line: hsl(152 42% 60% / .18);--markstream-diff-removed-line: hsl(0 58% 58% / .18);--markstream-diff-added-inline: hsl(152 42% 60% / .28);--markstream-diff-removed-inline: hsl(0 58% 58% / .28);--markstream-diff-added-inline-border: transparent;--markstream-diff-removed-inline-border: transparent;--markstream-diff-added-gutter: linear-gradient( 90deg, var(--markstream-diff-added-fg) 0 var(--stream-monaco-gutter-marker-width, 4px), transparent var(--stream-monaco-gutter-marker-width, 4px) 100% );--markstream-diff-removed-gutter: repeating-linear-gradient( 180deg, var(--markstream-diff-removed-fg) 0 2px, transparent 2px 4px ) left / var(--stream-monaco-gutter-marker-width, 4px) 100% no-repeat;--markstream-diff-added-line-fill: hsl(152 42% 60% / .18);--markstream-diff-removed-line-fill: hsl(0 58% 58% / .18)}.code-editor-container[data-v-72200115]{transition:none;box-sizing:border-box;min-width:0;width:100%}.code-block-container.is-diff .code-editor-container[data-v-72200115]{transition:none}.code-editor-layer[data-v-72200115]{display:grid;min-width:0;position:relative}.code-editor-layer--collapsed[data-v-72200115]{height:0;min-height:0;overflow:hidden;visibility:hidden;pointer-events:none}.code-editor-layer>.code-editor-container[data-v-72200115]{grid-area:1 / 1;z-index:1}.code-editor-layer>pre.code-pre-fallback[data-v-72200115]{grid-area:1 / 1;position:relative;z-index:2}.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .monaco-editor-background,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .margin,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .lines-content{background:var(--vscode-editor-background, var(--markstream-code-fallback-bg))!important}.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .margin,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .view-lines,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .view-line,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .view-line span,.code-block-container.is-plain-text[data-v-72200115]:not(.is-diff) .monaco-editor .line-numbers{color:var(--vscode-editor-foreground, var(--markstream-code-fallback-fg))!important}.code-block-container.is-diff[data-v-72200115]{color:var(--markstream-diff-shell-fg);border-color:var(--markstream-diff-shell-border);background:var(--markstream-diff-shell-bg);box-shadow:var(--markstream-diff-shell-shadow);--vscode-editor-selectionBackground: var(--markstream-diff-action-hover);--code-fg: var(--markstream-diff-shell-fg);--code-header-bg: transparent;--code-border: var(--markstream-diff-header-border);--code-line-number: var(--markstream-diff-shell-muted);--code-action-fg: var(--markstream-diff-shell-muted)}.code-block-container.is-diff .code-editor-layer[data-v-72200115]{background:transparent;--vscode-editor-background: var(--markstream-diff-editor-bg);--vscode-editor-foreground: var(--markstream-diff-editor-fg);--vscode-diffEditor-unchangedRegionForeground: var(--markstream-diff-unchanged-fg);--vscode-diffEditor-unchangedRegionBackground: var(--markstream-diff-unchanged-bg);--vscode-focusBorder: var(--markstream-diff-focus);--vscode-widget-shadow: var(--markstream-diff-widget-shadow);--vscode-editor-selectionBackground: color-mix( in srgb, var(--markstream-diff-editor-bg) 90%, var(--markstream-diff-editor-fg) 10% );--stream-monaco-editor-bg: var(--markstream-diff-editor-bg);--stream-monaco-editor-fg: var(--markstream-diff-editor-fg);--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg);--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg);--stream-monaco-frame-radius: 0;--stream-monaco-fixed-editor-bg: var(--markstream-diff-editor-bg);--stream-monaco-frame-border: transparent;--stream-monaco-frame-shadow: none;--stream-monaco-panel-bg: var(--markstream-diff-editor-bg);--stream-monaco-panel-bg-soft: var(--markstream-diff-editor-bg);--stream-monaco-panel-bg-strong: var(--markstream-diff-editor-bg);--stream-monaco-panel-border: transparent;--stream-monaco-pane-divider: var(--markstream-diff-pane-divider);--stream-monaco-gutter-bg: var(--markstream-diff-gutter-bg);--stream-monaco-gutter-guide: var(--markstream-diff-gutter-guide);--stream-monaco-gutter-marker-width: 4px;--stream-monaco-gutter-gap: 1ch;--stream-monaco-line-number-bg: var(--markstream-diff-line-number-bg);--stream-monaco-line-number: var(--markstream-diff-line-number);--stream-monaco-line-number-active: var(--markstream-diff-line-number-active);--stream-monaco-line-number-left: 0px;--stream-monaco-line-number-width: 2ch;--stream-monaco-line-number-padding-left: 2ch;--stream-monaco-line-number-padding-right: 1ch;--stream-monaco-line-number-separator-width: 2px;--stream-monaco-layout-character-width: var(--markstream-code-layout-character-width, 1ch);--stream-monaco-line-number-box-width: calc( var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-layout-character-width) + var(--stream-monaco-line-number-separator-width) );--stream-monaco-diff-code-gap: 1ch;--stream-monaco-diff-code-padding: 0px;--stream-monaco-line-number-gap-to-code: var(--stream-monaco-diff-code-gap);--stream-monaco-line-number-align: var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) );--stream-monaco-original-margin-width: calc( var(--stream-monaco-line-number-left) + var(--stream-monaco-line-number-box-width) + var(--stream-monaco-line-number-gap-to-code) );--stream-monaco-original-scrollable-left: var(--stream-monaco-original-margin-width);--stream-monaco-original-scrollable-width: calc( 100% - var(--stream-monaco-original-margin-width) );--stream-monaco-modified-margin-width: calc( var(--stream-monaco-line-number-left) + var(--stream-monaco-line-number-box-width) + var(--stream-monaco-line-number-gap-to-code) );--stream-monaco-modified-scrollable-left: var(--stream-monaco-modified-margin-width);--stream-monaco-modified-scrollable-width: calc( 100% - var(--stream-monaco-modified-margin-width) );--stream-monaco-added-fg: var(--markstream-diff-added-fg);--stream-monaco-removed-fg: var(--markstream-diff-removed-fg);--stream-monaco-added-line: var(--markstream-diff-added-line);--stream-monaco-removed-line: var(--markstream-diff-removed-line);--stream-monaco-added-inline: var(--markstream-diff-added-inline);--stream-monaco-removed-inline: var(--markstream-diff-removed-inline);--stream-monaco-added-outline: transparent;--stream-monaco-removed-outline: transparent;--stream-monaco-added-inline-border: var(--markstream-diff-added-inline-border);--stream-monaco-removed-inline-border: var(--markstream-diff-removed-inline-border);--stream-monaco-added-line-shadow: none;--stream-monaco-removed-line-shadow: none;--stream-monaco-added-gutter: var(--markstream-diff-added-gutter);--stream-monaco-removed-gutter: var(--markstream-diff-removed-gutter);--stream-monaco-added-line-fill: var(--markstream-diff-added-line-fill);--stream-monaco-removed-line-fill: var(--markstream-diff-removed-line-fill);--stream-monaco-added-border: hsl(var(--ms-diff-added) / .25);--stream-monaco-removed-border: hsl(var(--ms-diff-removed) / .25);--stream-monaco-widget-shadow: var(--markstream-diff-widget-shadow)}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers{left:var(--stream-monaco-line-number-left)!important;width:var(--stream-monaco-line-number-width)!important;min-width:var(--stream-monaco-line-number-width)!important;box-sizing:content-box!important;background:var(--stream-monaco-line-number-bg, var(--markstream-diff-line-number-bg))!important;padding-left:var(--stream-monaco-line-number-padding-left, 2ch)!important;padding-right:var(--stream-monaco-line-number-padding-right, 1ch)!important;border-right:var(--stream-monaco-line-number-separator-width, 2px) solid var(--stream-monaco-editor-bg)!important;text-align:var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) )!important;font-variant-numeric:tabular-nums;box-shadow:none}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin-view-overlays .line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin-view-overlays .line-numbers *{text-align:var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) )!important;font-variant-numeric:tabular-nums}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.original .margin-view-overlays .line-delete.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.modified .margin-view-overlays .line-delete.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .line-delete.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers.stream-monaco-line-number-delete,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers.stream-monaco-line-number-delete,.code-block-container.is-diff[data-v-72200115] .monaco-editor .stream-monaco-fallback-line-number-delete,.code-block-container.is-diff[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-native-stale .monaco-diff-editor .line-delete.line-numbers{background:var(--stream-monaco-removed-line-fill)!important;color:var(--stream-monaco-removed-fg)!important;box-shadow:none!important}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.original .margin-view-overlays .line-insert.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.modified .margin-view-overlays .line-insert.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .line-insert.line-numbers,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.original .margin-view-overlays .line-numbers.stream-monaco-line-number-insert,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .editor.modified .margin-view-overlays .line-numbers.stream-monaco-line-number-insert,.code-block-container.is-diff[data-v-72200115] .monaco-editor .stream-monaco-fallback-line-number-insert,.code-block-container.is-diff[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-native-stale .monaco-diff-editor .line-insert.line-numbers{background:var(--stream-monaco-added-line-fill)!important;color:var(--stream-monaco-added-fg)!important;box-shadow:none!important}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .monaco-editor,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin,.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin-view-overlays{--stream-monaco-line-number-align: var( --markstream-diff-line-number-align, var(--markstream-code-line-number-align, right) ) !important}.code-block-container[data-v-72200115]:not(.is-diff){--markstream-code-line-number-box-width: calc( var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + var(--markstream-code-layout-character-width, 1ch) + 2px );--markstream-code-content-left: calc( var(--markstream-code-line-number-box-width) + var(--markstream-code-layout-character-width, 1ch) )}.code-block-container[data-v-72200115]:not(.is-diff) .monaco-editor .margin,.code-block-container[data-v-72200115]:not(.is-diff) .monaco-editor .margin-view-overlays{width:var(--markstream-code-content-left)!important}.code-block-container[data-v-72200115]:not(.is-diff) .monaco-editor .line-numbers{left:0!important;width:2ch!important;min-width:2ch!important;box-sizing:content-box!important;padding-left:2ch!important;padding-right:1ch!important;border-right:2px solid var(--vscode-editor-background)!important;text-align:var(--markstream-code-line-number-align, right)!important;font-variant-numeric:tabular-nums}.code-block-container[data-v-72200115]:not(.is-diff) .monaco-editor .monaco-scrollable-element.editor-scrollable{left:var(--markstream-code-content-left)!important;width:calc(100% - var(--markstream-code-content-left))!important}.code-block-container[data-v-72200115]:not(.is-diff) .monaco-editor .lines-content{left:0!important}.code-editor-container[data-markstream-host-hidden=true][data-v-72200115]{position:absolute;inset:0;width:100%;height:100%!important;min-height:0!important;max-height:none!important;overflow:hidden;visibility:hidden;pointer-events:none}pre.code-pre-fallback[data-v-72200115]{margin:0;box-sizing:border-box;width:100%;padding:var(--markstream-code-padding-y, 8px) var(--markstream-code-padding-x, 12px);padding-left:var(--markstream-code-padding-left, 52px);background:transparent;color:var(--vscode-editor-foreground, inherit);backface-visibility:visible;transform:none;-webkit-font-smoothing:auto;font-size:var(--vscode-editor-font-size, 12px);line-height:var(--vscode-editor-line-height, 18px);font-weight:400;font-family:var( --markstream-code-font-family, Menlo, Monaco, Courier New, monospace )}pre.code-pre-fallback[data-v-72200115] code{font-size:inherit;font-weight:inherit;line-height:inherit;font-family:inherit}pre.code-pre-fallback.is-wrap[data-v-72200115]{white-space:pre-wrap;overflow-wrap:anywhere}pre.code-pre-fallback.markstream-pre--diff-preview[data-v-72200115]{padding-left:0;padding-right:0}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview{background:var(--markstream-diff-editor-bg);transition:none}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-pane{box-sizing:border-box;padding-bottom:var(--markstream-pre-diff-pane-bottom-padding, 0px)}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview:not(.markstream-pre--diff-inline) .markstream-pre__diff-pane{padding-bottom:var(--markstream-pre-diff-pane-bottom-padding, 0px)}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added:after,.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-number{background:var(--stream-monaco-added-line-fill, var(--markstream-diff-added-line-fill, transparent))!important}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed:after,.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-number{background:var(--stream-monaco-removed-line-fill, var(--markstream-diff-removed-line-fill, transparent))!important}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--added>.markstream-pre__diff-rail{background:var(--stream-monaco-added-gutter, var(--markstream-diff-added-gutter, currentColor))!important}.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview .markstream-pre__diff-line--removed>.markstream-pre__diff-rail{background:var(--stream-monaco-removed-gutter, var(--markstream-diff-removed-gutter, currentColor))!important}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin-view-overlays>.gutter-insert>.cmdr.gutter-insert{background:linear-gradient(90deg,transparent 0 var(--stream-monaco-line-number-box-width),var(--stream-monaco-added-line-fill) var(--stream-monaco-line-number-box-width) 100%)!important}.code-block-container.is-diff[data-v-72200115] .monaco-diff-editor .margin-view-overlays>.gutter-delete>.cmdr.gutter-delete{background:linear-gradient(90deg,transparent 0 var(--stream-monaco-line-number-box-width),var(--stream-monaco-removed-line-fill) var(--stream-monaco-line-number-box-width) 100%)!important}@media(prefers-reduced-motion:reduce){.code-block-container.is-diff[data-v-72200115] pre.code-pre-fallback.markstream-pre--diff-preview{transition:none}}.code-block-container.is-rendering .code-height-placeholder[data-v-72200115]{background-size:400% 100%;animation:code-skeleton-shimmer-72200115 1.2s ease-in-out infinite;min-height:var(--ms-size-skeleton-min-height);background:linear-gradient(90deg,var(--loading-shimmer) 25%,hsl(var(--ms-muted) / .7) 37%,var(--loading-shimmer) 63%)}.code-loading-placeholder[data-v-72200115]{padding:16px;min-height:var(--ms-size-skeleton-min-height)}.loading-skeleton[data-v-72200115]{display:flex;flex-direction:column;gap:12px}.skeleton-line[data-v-72200115]{height:16px;background:linear-gradient(90deg,var(--loading-shimmer) 25%,hsl(var(--ms-muted) / .7) 37%,var(--loading-shimmer) 63%);background-size:400% 100%;animation:code-skeleton-shimmer-72200115 1.2s ease-in-out infinite;border-radius:calc(var(--ms-radius) * .5)}.skeleton-line.short[data-v-72200115]{width:60%}.code-block-container[data-markstream-viewport-pending=true] .code-height-placeholder[data-v-72200115],.code-block-container[data-markstream-viewport-pending=true] .skeleton-line[data-v-72200115]{animation:none}@keyframes code-skeleton-shimmer-72200115{0%{background-position:100% 0}to{background-position:0 0}}[data-v-72200115] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center{border-radius:var(--ms-radius)!important;background:transparent!important;border:1px solid transparent!important;box-shadow:none!important;min-height:28px!important;transition:background-color .14s ease,border-color .14s ease!important}[data-v-72200115] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:hover,[data-v-72200115] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center.stream-monaco-focus-within{background:color-mix(in srgb,var(--stream-monaco-editor-fg) 4%,transparent)!important;border-color:color-mix(in srgb,var(--stream-monaco-editor-fg) 10%,transparent)!important;box-shadow:none!important}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center{background:transparent!important;border-color:transparent!important;box-shadow:none!important}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center:hover,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-appearance-dark .monaco-editor .diff-hidden-lines .center.stream-monaco-focus-within{background:color-mix(in srgb,var(--stream-monaco-editor-fg) 6%,transparent)!important;border-color:color-mix(in srgb,var(--stream-monaco-editor-fg) 12%,transparent)!important;box-shadow:none!important}[data-v-72200115] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center .stream-monaco-unchanged-count:before{content:"";display:inline-block;width:14px;height:14px;margin-right:4px;flex-shrink:0;background:currentColor;mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5'/%3E%3Cpath d='m7 9 5-5 5 5'/%3E%3C/svg%3E");-webkit-mask-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m7 15 5 5 5-5'/%3E%3Cpath d='m7 9 5-5 5 5'/%3E%3C/svg%3E");mask-size:contain;-webkit-mask-size:contain;mask-repeat:no-repeat;-webkit-mask-repeat:no-repeat}[data-v-72200115] .monaco-diff-editor .diffOverview{background-color:var(--vscode-editor-background)}[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor .diffOverview,[data-v-72200115] .stream-monaco-diff-root .decorationsOverviewRuler{display:none!important;width:0!important;min-width:0!important;max-width:0!important;border:0!important;background:transparent!important;opacity:0!important;pointer-events:none!important;overflow:hidden!important}[data-v-72200115] .code-block-container .stream-monaco-diff-root .monaco-diff-editor{border:0!important;border-radius:0!important;box-shadow:none!important}[data-v-72200115] .code-block-container .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:not(.stream-monaco-clickable)>*:not(a){visibility:hidden!important}[data-v-72200115] .code-block-container .stream-monaco-diff-root .monaco-editor .diff-hidden-lines-compact .text{opacity:0!important}[data-v-72200115] .stream-monaco-diff-root{--stream-monaco-gutter-guide: var(--markstream-diff-gutter-guide) !important;--stream-monaco-gutter-gap: var(--markstream-diff-gutter-gap) !important;--stream-monaco-line-number: var(--markstream-diff-line-number) !important;--stream-monaco-line-number-active: var(--markstream-diff-line-number-active) !important;--stream-monaco-added-fg: var(--markstream-diff-added-fg) !important;--stream-monaco-removed-fg: var(--markstream-diff-removed-fg) !important;--stream-monaco-added-line: var(--markstream-diff-added-line) !important;--stream-monaco-removed-line: var(--markstream-diff-removed-line) !important;--stream-monaco-added-inline: var(--markstream-diff-added-inline) !important;--stream-monaco-removed-inline: var(--markstream-diff-removed-inline) !important;--stream-monaco-added-inline-border: var(--markstream-diff-added-inline-border) !important;--stream-monaco-removed-inline-border: var(--markstream-diff-removed-inline-border) !important;--stream-monaco-added-line-fill: var(--markstream-diff-added-line-fill) !important;--stream-monaco-removed-line-fill: var(--markstream-diff-removed-line-fill) !important;--stream-monaco-added-gutter: var(--markstream-diff-added-gutter) !important;--stream-monaco-removed-gutter: var(--markstream-diff-removed-gutter) !important;--stream-monaco-added-line-shadow: none !important;--stream-monaco-removed-line-shadow: none !important;--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg) !important;--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg) !important;box-sizing:border-box;min-width:0;width:100%}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .monaco-editor,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .overflow-guard,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side),[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .monaco-editor,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .overflow-guard{min-width:0!important;width:100%!important}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .editor.modified .monaco-scrollable-element.editor-scrollable,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .editor.modified .monaco-scrollable-element.editor-scrollable{left:var(--stream-monaco-modified-scrollable-left, var(--stream-monaco-modified-margin-width))!important;width:calc(100% - var(--stream-monaco-modified-scrollable-left, var(--stream-monaco-modified-margin-width)))!important}[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor .editor.modified .view-lines .view-line.stream-monaco-line-insert-fill,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor .editor.original .view-lines .view-line.stream-monaco-line-delete-fill{width:1000000px!important}.code-block-container.is-diff[data-v-72200115] .stream-monaco-fallback-inline-delete-line{box-sizing:border-box;padding-left:var(--stream-monaco-diff-code-padding, 0px)}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline .monaco-diff-editor .scrollbar.horizontal,[data-v-72200115] .stream-monaco-diff-root .monaco-diff-editor:not(.side-by-side) .scrollbar.horizontal{display:none!important;height:0!important}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .view-lines.line-delete{margin-left:0!important;width:100%!important;background:var(--stream-monaco-removed-line-fill)!important;box-shadow:var(--stream-monaco-removed-line-shadow)!important;display:block!important;height:-moz-max-content!important;height:max-content!important;min-height:18px!important;overflow:visible!important}[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .gutter-delete,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .inline-deleted-margin-view-zone,[data-v-72200115] .stream-monaco-diff-root.stream-monaco-diff-inline.stream-monaco-diff-inline-native-ready.stream-monaco-diff-native-stale .monaco-diff-editor .editor.modified .stream-monaco-fallback-inline-delete-margin{background:var(--stream-monaco-removed-gutter),var(--stream-monaco-removed-line-fill)!important;display:block!important;height:100%!important;min-height:18px!important;overflow:visible!important}[data-v-72200115] .stream-monaco-diff-root .monaco-editor .diff-hidden-lines .center:not(.stream-monaco-unchanged-bridge-source),[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge{--stream-monaco-unchanged-bg: var(--markstream-diff-unchanged-bg) !important;--stream-monaco-unchanged-fg: var(--markstream-diff-unchanged-fg) !important;background:var(--stream-monaco-unchanged-bg)!important;color:var(--stream-monaco-unchanged-fg)!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge{right:calc(var(--stream-monaco-gutter-marker-width) - var(--stream-monaco-unchanged-rail-width) / 2 + (var(--stream-monaco-gutter-gap) * 2))!important;width:auto!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary:hover,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary:focus-visible,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-summary.stream-monaco-focus-visible{background:var(--stream-monaco-unchanged-bg)!important;color:var(--markstream-diff-unchanged-fg)!important;padding-left:calc(var(--stream-monaco-gutter-marker-width) + (var(--stream-monaco-gutter-gap) * 2))!important;padding-right:calc(var(--stream-monaco-gutter-marker-width) + (var(--stream-monaco-gutter-gap) * 2))!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge.stream-monaco-diff-unchanged-bridge-line-info .stream-monaco-unchanged-rail,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:hover,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:focus-visible,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal.stream-monaco-focus-visible{background:var(--stream-monaco-unchanged-bg)!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail{border-right-color:var(--markstream-diff-unchanged-divider)!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal{border-bottom-color:transparent!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-both .stream-monaco-unchanged-reveal:first-child{border-bottom-color:var(--markstream-diff-unchanged-divider)!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-top-only .stream-monaco-unchanged-reveal,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-rail.stream-monaco-unchanged-rail-bottom-only .stream-monaco-unchanged-reveal{border-bottom:0!important}[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-meta,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-count,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-metadata-label,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:hover,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal:focus-visible,[data-v-72200115] .stream-monaco-diff-root .stream-monaco-diff-unchanged-bridge .stream-monaco-unchanged-reveal.stream-monaco-focus-visible{color:var(--markstream-diff-unchanged-fg)!important}[data-v-72200115] .monaco-diff-editor:not(.side-by-side) .editor.original .diff-hidden-lines .center{align-items:center;justify-content:center}[data-v-72200115] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center{align-items:center;justify-content:center!important;position:relative}[data-v-72200115] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center:not(.stream-monaco-clickable){opacity:0!important;pointer-events:none!important}[data-v-72200115] .monaco-diff-editor:not(.side-by-side) .editor.modified .diff-hidden-lines .center .stream-monaco-unchanged-meta{justify-content:center!important;padding:0 28px!important}[data-v-72200115] .monaco-diff-editor:not(.side-by-side) .editor.original .diff-hidden-lines .center>div:first-child{align-items:center;display:flex;justify-content:center!important;min-width:100%;width:100%!important}[data-v-72200115] .markstream-inline-fold-proxy{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:transparent;border:0;border-radius:calc(var(--ms-radius) * .5);box-shadow:none;cursor:pointer;inset:0;padding:0;pointer-events:auto;position:absolute;z-index:2}[data-v-72200115] .markstream-inline-fold-proxy:hover,[data-v-72200115] .markstream-inline-fold-proxy:focus-visible{background:transparent}[data-v-72200115] .markstream-inline-fold-proxy:focus-visible{outline:1px solid var(--vscode-focusBorder, currentColor);outline-offset:-1px}.math-inline-wrapper[data-v-6c556261]{position:relative;display:inline-block}.math-inline[data-v-6c556261]{display:inline-block;vertical-align:middle}.math-inline--fallback[data-v-6c556261]{white-space:pre-wrap}.math-inline__loading[data-v-6c556261]{display:inline-flex;align-items:center;justify-content:center;pointer-events:none}.math-inline__spinner[data-v-6c556261]{width:16px;height:16px;border-radius:9999px;border:2px solid color-mix(in srgb,var(--loading-spinner) 25%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);will-change:transform}.table-node-fade-enter-active[data-v-6c556261],.table-node-fade-leave-active[data-v-6c556261]{transition:opacity var(--ms-duration-standard) var(--ms-ease-standard)}.table-node-fade-enter-from[data-v-6c556261],.table-node-fade-leave-to[data-v-6c556261]{opacity:0}.sr-only[data-v-6c556261]{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.math-block[data-v-939191ad]{min-height:var(--ms-size-math-min-height);transition:min-height var(--ms-duration-overlay) var(--ms-ease-standard)}.math-loading-overlay[data-v-939191ad]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(2px);min-height:var(--ms-size-math-min-height)}.math-loading-spinner[data-v-939191ad]{width:20px;height:20px;border:2px solid color-mix(in srgb,var(--loading-spinner) 15%,transparent);border-top-color:color-mix(in srgb,var(--loading-spinner) 80%,transparent);border-radius:50%;animation:math-spin-939191ad .8s linear infinite}@keyframes math-spin-939191ad{to{transform:rotate(360deg)}}.math-rendering[data-v-939191ad]{opacity:.3;transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.math-block__fallback[data-v-939191ad]{white-space:pre-wrap;overflow-wrap:anywhere;margin:0}.math-fade-enter-active[data-v-939191ad],.math-fade-leave-active[data-v-939191ad]{transition:all var(--ms-duration-slow) var(--ms-ease-standard)}.math-fade-enter-from[data-v-939191ad],.math-fade-leave-to[data-v-939191ad]{opacity:0}.action-icon{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.icon-slot{display:inline-flex;align-items:center;justify-content:center}.icon-slot svg{display:block;width:100%;height:100%}.mermaid-block-container[data-v-0aff75e3]{margin:var(--ms-flow-diagram-y) 0;border-color:var(--diagram-border)}.mermaid-block-header[data-v-0aff75e3]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border)}.mermaid-label-text[data-v-0aff75e3]{color:var(--code-action-fg)}.mermaid-mode-toggle-group[data-v-0aff75e3]{background:transparent}.mermaid-mode-btn[data-v-0aff75e3]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6}.mermaid-mode-btn[data-v-0aff75e3]:hover{opacity:.9}.mermaid-mode-btn.is-active[data-v-0aff75e3]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.mermaid-header-actions[data-v-0aff75e3]{gap:var(--ms-gap-header-actions)}.mermaid-action-btn[data-v-0aff75e3]{font-family:inherit;font-size:var(--ms-text-label);color:var(--code-action-fg)}.mermaid-action-btn[data-v-0aff75e3]:hover{background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.mermaid-action-btn[data-v-0aff75e3]:active{transform:scale(.98)}.mermaid-source-panel[data-v-0aff75e3]{padding:var(--ms-inset-panel-body);background:var(--diagram-bg)}.mermaid-source-code[data-v-0aff75e3]{color:hsl(var(--ms-foreground))}.mermaid-preview-area[data-v-0aff75e3]{background:var(--diagram-bg);min-height:var(--ms-size-diagram-min-height);transition-duration:var(--ms-duration-standard)}.mermaid-modal-overlay[data-v-0aff75e3]{background:var(--modal-overlay)}.mermaid-modal-panel[data-v-0aff75e3]{background:var(--modal-bg);color:var(--modal-fg);box-shadow:var(--ms-shadow-modal)}._mermaid[data-v-0aff75e3]{position:relative;font-family:inherit;content-visibility:auto;contain:content;contain-intrinsic-size:var(--ms-size-diagram-min-height) 240px}._mermaid[data-v-0aff75e3] [data-mermaid-svg-layer]{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;width:100%;min-height:100%}._mermaid[data-v-0aff75e3] svg{width:100%;height:auto;display:block}.fullscreen[data-v-0aff75e3]{width:100%;max-height:100%!important;height:100%!important}.mermaid-dialog-enter-from[data-v-0aff75e3],.mermaid-dialog-leave-to[data-v-0aff75e3]{opacity:0}.mermaid-dialog-enter-active[data-v-0aff75e3],.mermaid-dialog-leave-active[data-v-0aff75e3]{transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.mermaid-dialog-enter-from .dialog-panel[data-v-0aff75e3],.mermaid-dialog-leave-to .dialog-panel[data-v-0aff75e3]{transform:translateY(8px) scale(.98);opacity:.98}.mermaid-dialog-enter-to .dialog-panel[data-v-0aff75e3],.mermaid-dialog-leave-from .dialog-panel[data-v-0aff75e3]{transform:translateY(0) scale(1);opacity:1}.mermaid-dialog-enter-active .dialog-panel[data-v-0aff75e3],.mermaid-dialog-leave-active .dialog-panel[data-v-0aff75e3]{transition:transform var(--ms-duration-overlay) var(--ms-ease-standard),opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.infographic-block-container[data-v-de34ec4b]{margin:var(--ms-flow-diagram-y) 0;background:var(--diagram-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground));box-shadow:var(--ms-shadow-subtle)}.infographic-block-header[data-v-de34ec4b]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground))}.infographic-label[data-v-de34ec4b]{font-size:var(--ms-text-label);color:hsl(var(--ms-muted-foreground))}.action-icon[data-v-de34ec4b]{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.icon-slot[data-v-de34ec4b]{display:inline-flex;align-items:center;justify-content:center}.icon-slot[data-v-de34ec4b] svg{display:block;width:100%;height:100%}.infographic-mode-toggle[data-v-de34ec4b]{background:transparent}.infographic-mode-btn[data-v-de34ec4b]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6;transition:color .15s,background-color .15s,opacity .15s}.infographic-mode-btn[data-v-de34ec4b]:hover{opacity:.9}.infographic-mode-btn.is-active[data-v-de34ec4b]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.infographic-header-actions[data-v-de34ec4b]{gap:var(--ms-gap-header-actions)}.infographic-action-btn[data-v-de34ec4b]{font-family:inherit;color:var(--code-action-fg);transition:background-color .15s,color .15s}.infographic-action-btn[data-v-de34ec4b]:hover{background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.infographic-action-btn[data-v-de34ec4b]:active{transform:scale(.98)}.infographic-source[data-v-de34ec4b]{padding:var(--ms-inset-panel-body);background:var(--diagram-bg)}.infographic-source-code[data-v-de34ec4b]{color:hsl(var(--ms-foreground))}.infographic-preview[data-v-de34ec4b]{background:var(--diagram-bg);min-height:var(--ms-size-diagram-min-height);transition-duration:var(--ms-duration-fast)}.infographic-pending-source[data-v-de34ec4b]{position:absolute;inset:0;z-index:1;margin:0;padding:var(--ms-inset-panel-body);overflow:auto;color:hsl(var(--ms-foreground));text-align:left;background:var(--diagram-bg)}.infographic-modal-overlay[data-v-de34ec4b]{background:var(--modal-overlay)}.infographic-modal-panel[data-v-de34ec4b]{background:var(--modal-bg);color:var(--modal-fg);box-shadow:var(--ms-shadow-modal)}.fullscreen[data-v-de34ec4b]{width:100%;max-height:100%!important;height:100%!important}.infographic-dialog-enter-from[data-v-de34ec4b],.infographic-dialog-leave-to[data-v-de34ec4b]{opacity:0}.infographic-dialog-enter-active[data-v-de34ec4b],.infographic-dialog-leave-active[data-v-de34ec4b]{transition:opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.infographic-dialog-enter-from .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-to .dialog-panel[data-v-de34ec4b]{transform:translateY(8px) scale(.98);opacity:.98}.infographic-dialog-enter-to .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-from .dialog-panel[data-v-de34ec4b]{transform:translateY(0) scale(1);opacity:1}.infographic-dialog-enter-active .dialog-panel[data-v-de34ec4b],.infographic-dialog-leave-active .dialog-panel[data-v-de34ec4b]{transition:transform var(--ms-duration-overlay) var(--ms-ease-standard),opacity var(--ms-duration-overlay) var(--ms-ease-standard)}.d2-block-container[data-v-3b434cf5]{margin:var(--ms-flow-diagram-y) 0;background:var(--diagram-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground));box-shadow:var(--ms-shadow-subtle)}.d2-block-header[data-v-3b434cf5]{padding:var(--ms-inset-panel-y) var(--ms-inset-panel-x);background:var(--diagram-header-bg);border-color:var(--diagram-border);color:hsl(var(--ms-foreground))}.d2-mode-toggle[data-v-3b434cf5]{background:transparent}.mode-btn[data-v-3b434cf5]{font-size:var(--ms-text-label);color:var(--code-action-fg);opacity:.6;transition:opacity .2s,color .2s,background-color .2s}.mode-btn[data-v-3b434cf5]:hover{opacity:.9}.mode-btn.is-active[data-v-3b434cf5]{background:hsl(var(--ms-foreground) / .08);color:var(--code-fg);opacity:1}.d2-header-actions[data-v-3b434cf5]{gap:var(--ms-gap-header-actions)}.d2-action-btn[data-v-3b434cf5]{color:var(--code-action-fg);opacity:.7;transition:opacity .2s,background-color .15s,color .15s}.d2-action-btn[data-v-3b434cf5]:hover{opacity:1;background:var(--code-action-hover-bg);color:var(--code-action-hover-fg)}.d2-action-btn[data-v-3b434cf5]:disabled{opacity:.3;cursor:not-allowed}.d2-block-body[data-v-3b434cf5]{position:relative}.d2-source[data-v-3b434cf5]{padding:var(--ms-inset-panel-body) var(--ms-inset-panel-x);font-family:var(--vscode-editor-font-family, "Fira Code", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace)}.d2-code[data-v-3b434cf5]{white-space:pre;font-size:14px;line-height:1.5}.d2-render[data-v-3b434cf5]{max-height:var(--ms-size-code-max-height);overflow:auto}.d2-svg[data-v-3b434cf5] svg.markstream-d2-root-svg{width:100%;max-width:100%;height:auto;display:block}.d2-label[data-v-3b434cf5]{font-size:var(--ms-text-label)}.action-icon[data-v-3b434cf5]{width:var(--ms-action-btn-icon);height:var(--ms-action-btn-icon)}.d2-error[data-v-3b434cf5]{color:hsl(var(--ms-destructive))}.markstream-virtual-timeline[data-v-1303f06e]{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;overflow:auto;overflow-anchor:none}.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__spacer[data-v-1303f06e],.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__item[data-v-1303f06e]{opacity:0;visibility:hidden;pointer-events:none}.markstream-virtual-timeline.is-restoring-thread>.markstream-virtual-timeline__item[data-v-1303f06e],.markstream-virtual-timeline__item.is-restored-height-floor[data-v-1303f06e]{height:var(--markstream-virtual-item-size);overflow:hidden}.markstream-virtual-timeline__restore-loading[data-v-1303f06e]{position:absolute;top:0;left:0;right:0;z-index:10;display:grid;place-items:center;pointer-events:none;overflow:hidden;background:Canvas;contain:strict}.markstream-virtual-timeline__restore-loading-card[data-v-1303f06e]{display:inline-flex;align-items:center;gap:10px;padding:10px 14px;border:1px solid rgb(148 163 184 / 32%);border-radius:999px;background:#ffffffeb;color:#334155;font-size:13px;box-shadow:0 8px 24px #0f172a14}.markstream-virtual-timeline__restore-spinner[data-v-1303f06e]{width:14px;height:14px;border:2px solid rgb(148 163 184 / 35%);border-top-color:#334155;border-radius:999px;animation:markstream-timeline-restore-spin-1303f06e .8s linear infinite}@keyframes markstream-timeline-restore-spin-1303f06e{to{transform:rotate(360deg)}}.markstream-virtual-timeline__spacer[data-v-1303f06e]{flex:0 0 auto;overflow-anchor:none}.markstream-virtual-timeline__item[data-v-1303f06e]{display:flow-root;flex:0 0 auto;overflow-anchor:none}.markstream-virtual-timeline__default-item[data-v-1303f06e]{margin:8px 0;padding:10px 12px;border:1px solid rgb(148 163 184 / 32%);border-radius:8px;background:#f8fafc;color:#0f172a;line-height:1.5;white-space:pre-wrap}.markstream-virtual-timeline__default-item--system-divider[data-v-1303f06e]{border:0;background:transparent;color:#64748b;font-size:12px;text-align:center}.markstream-virtual-timeline__default-item--error[data-v-1303f06e]{border-color:#f8717173;background:#fef2f2;color:#991b1b}.markstream-virtual-timeline__status[data-v-1303f06e]{display:inline-flex;margin-right:8px;color:#475569;font-size:12px;text-transform:uppercase}@font-face{font-display:block;font-family:KaTeX_AMS;font-style:normal;font-weight:400;src:url(/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2) format("woff2"),url(/assets/KaTeX_AMS-Regular-DMm9YOAa.woff) format("woff"),url(/assets/KaTeX_AMS-Regular-DRggAlZN.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Caligraphic;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2) format("woff2"),url(/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff) format("woff"),url(/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff) format("woff"),url(/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Fraktur;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2) format("woff2"),url(/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff) format("woff"),url(/assets/KaTeX_Fraktur-Regular-CB_wures.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:700;src:url(/assets/KaTeX_Main-Bold-Cx986IdX.woff2) format("woff2"),url(/assets/KaTeX_Main-Bold-Jm3AIy58.woff) format("woff"),url(/assets/KaTeX_Main-Bold-waoOVXN0.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2) format("woff2"),url(/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff) format("woff"),url(/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2) format("woff2"),url(/assets/KaTeX_Main-Italic-BMLOBm91.woff) format("woff"),url(/assets/KaTeX_Main-Italic-3WenGoN9.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Main;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Main-Regular-B22Nviop.woff2) format("woff2"),url(/assets/KaTeX_Main-Regular-Dr94JaBh.woff) format("woff"),url(/assets/KaTeX_Main-Regular-ypZvNtVU.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:700;src:url(/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2) format("woff2"),url(/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff) format("woff"),url(/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Math;font-style:italic;font-weight:400;src:url(/assets/KaTeX_Math-Italic-t53AETM-.woff2) format("woff2"),url(/assets/KaTeX_Math-Italic-DA0__PXp.woff) format("woff"),url(/assets/KaTeX_Math-Italic-flOr_0UB.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:700;src:url(/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff) format("woff"),url(/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:italic;font-weight:400;src:url(/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff) format("woff"),url(/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_SansSerif;font-style:normal;font-weight:400;src:url(/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2) format("woff2"),url(/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff) format("woff"),url(/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Script;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Script-Regular-D3wIWfF6.woff2) format("woff2"),url(/assets/KaTeX_Script-Regular-D5yQViql.woff) format("woff"),url(/assets/KaTeX_Script-Regular-C5JkGWo-.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size1;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2) format("woff2"),url(/assets/KaTeX_Size1-Regular-C195tn64.woff) format("woff"),url(/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size2;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2) format("woff2"),url(/assets/KaTeX_Size2-Regular-oD1tc_U0.woff) format("woff"),url(/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size3;font-style:normal;font-weight:400;src:url(data:font/woff2;base64,d09GMgABAAAAAA4oAA4AAAAAHbQAAA3TAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAAgRQIDgmcDBEICo1oijYBNgIkA14LMgAEIAWJAAeBHAyBHBvbGiMRdnO0IkRRkiYDgr9KsJ1NUAf2kILNxgUmgqIgq1P89vcbIcmsQbRps3vCcXdYOKSWEPEKgZgQkprQQsxIXUgq0DqpGKmIvrgkeVGtEQD9DzAO29fM9jYhxZEsL2FeURH2JN4MIcTdO049NCVdxQ/w9NrSYFEBKTDKpLKfNkCGDc1RwjZLQcm3vqJ2UW9Xfa3tgAHz6ivp6vgC2yD4/6352ndnN0X0TL7seypkjZlMsjmZnf0Mm5Q+JykRWQBKCVCVPbARPXWyQtb5VgLB6Biq7/Uixcj2WGqdI8tGSgkuRG+t910GKP2D7AQH0DB9FMDW/obJZ8giFI3Wg8Cvevz0M+5m0rTh7XDBlvo9Y4vm13EXmfttwI4mBo1EG15fxJhUiCLbiiyCf/ZA6MFAhg3pGIZGdGIVjtPn6UcMk9A/UUr9PhoNsCENw1APAq0gpH73e+M+0ueyHbabc3vkbcdtzcf/fiy+NxQEjf9ud/ELBHAXJ0nk4z+MXH2Ev/kWyV4k7SkvpPc9Qr38F6RPWnM9cN6DJ0AdD1BhtgABtmoRoFCvPsBAumNm6soZG2Gk5GyVTo2sJncSyp0jQTYoR6WDvTwaaEcHsxHfvuWhHA3a6bN7twRKtcGok6NsCi7jYRrM2jExsUFMxMQYuJbMhuWNOumEJy9hi29Dmg5zMp/A5+hhPG19j1vBrq8JTLr8ki5VLPmG/PynJHVul440bxg5xuymHUFPBshC+nA9I1FmwbRBTNHAcik3Oae0cxKoI3MOriM42UrPe51nsaGxJ+WfXubAsP84aabUlQSJ1IiE0iPETLUU4CATgfXSCSpuRFRmCGbO+wSpAnzaeaCYW1VNEysRtuXCEL1kUFUbbtMv3Tilt/1c11jt3Q5bbMa84cpWipp8Elw3MZhOHsOlwwVUQM3lAR35JiFQbaYCRnMF2lxAWoOg2gyoIV4PouX8HytNIfLhqpJtXB4vjiViUI8IJ7bkC4ikkQvKksnOTKICwnqWSZ9YS5f0WCxmpgjbIq7EJcM4aI2nmhLNY2JIUgOjXZFWBHb+x5oh6cwb0Tv1ackHdKi0I9OO2wE9aogIOn540CCCziyhN+IaejtgAONKznHlHyutPrHGwCx9S6B8kfS4Mfi4Eyv7OU730bT1SCBjt834cXsf43zVjPUqqJjgrjeGnBxSG4aYAKFuVbeCfkDIjAqMb6yLNIbCuvXhMH2/+k2vkNpkORhR59N1CkzoOENvneIosjYmuTxlhUzaGEJQ/iWqx4dmwpmKjrwTiTGTCVozNAYqk/zXOndWxuWSmJkQpJw3pK5KX6QrLt5LATMqpmPAQhkhK6PUjzHUn7E0gHE0kPE0iKkolgkUx9SZmVAdDgpffdyJKg3k7VmzYGCwVXGz/tXmkOIp+vcWs+EMuhhvN0h9uhfzWJziBQmCREGSIFmQIkgVpAnSBRmC//6hkLZwaVhwxlrJSOdqlFtOYxlau9F2QN5Y98xmIAsiM1HVp2VFX+DHHGg6Ecjh3vmqtidX3qHI2qycTk/iwxSt5UzTmEP92ZBnEWTk4Mx8Mpl78ZDokxg/KWb+Q0QkvdKVmq3TMW+RXEgrsziSAfNXFMhDc60N5N9jQzjfO0kBKpUZl0ZmwJ41j/B9Hz6wmRaJB84niNmQrzp9eSlQCDDzazGDdVi3P36VZQ+Jy4f9UBNp+3zTjqI4abaFAm+GShVaXlsGdF3FYzZcDI6cori4kMxUECl9IjJZpzkvitAoxKue+90pDMvcKRxLl53TmOKCmV/xRolNKSqqUxc6LStOETmFOiLZZptlZepcKiAzteG8PEdpnQpbOMNcMsR4RR2Bs0cKFEvSmIjAFcnarqwUL4lDhHmnVkwu1IwshbiCcgvOheZuYyOteufZZwlcTlLgnZ3o/WcYdzZHW/WGaqaVfmTZ1aWCceJjkbZqsfbkOtcFlUZM/jy+hXHDbaUobWqqXaeWobbLO99yG5N3U4wxco0rQGGcOLASFMXeJoham8M+/x6O2WywK2l4HGbq1CoUyC/IZikQhdq3SiuNrvAEj0AVu9x2x3lp/xWzahaxidezFVtdcb5uEnzyl0ZmYiuKI0exvCd4Xc9CV1KB0db00z92wDPde0kukbvZIWN6jUWFTmPIC/Y4UPCm8UfDTFZpZNon1qLFTkBhxzB+FjQRA2Q/YRJT8pQigslMaUpFyAG8TMlXigiqmAZX4xgijKjRlGpLE0GdplRfCaJo0JQaSxNBk6ZmMzcya0FmrcisDdn0Q3HI2sWSppYigmlM1XT/kLQZSNpMJG0WkjYbSZuDpM1F0uYhFc1HxU4m1QJjDK6iL0S5uSj5rgXc3RejEigtcRBtqYPQsiTskmO5vosV+q4VGIKbOkDg0jtRrq+Em1YloaTFar3EGr1EUC8R0kus1Uus00usL97ABr2BjXoDm/QGNhuWtMVBKOwg/i78lT7hBsAvDmwHc/ao3vmUbBmhjeYySZNWvGkfZAgISDSaDo1SVpzGDsAEkF8B+gEapViUoZgUWXcRIGFZNm6gWbAKk0bp0k1MHG9fLYtV4iS2SmLEQFARzRcnf9PUS0LVn05/J9MiRRBU3v2IrvW974v4N00L7ZMk0wXP1409CHo/an8zTRHD3eSJ6m8D4YMkZNl3M79sqeuAsr/m3f+8/yl7A50aiAEJgeBeMWzu7ui9UfUBCe2TIqZIoOd/3/udRBOQidQZUERzb2/VwZN1H/Sju82ew2H2Wfr6qvfVf3hqwDvAIpkQVFy4B9Pe9e4/XvPeceu7h3dvO56iJPf0+A6cqA2ip18ER+iFgggiuOkvj24bby0N9j2UHIkgqIt+sVgfodC4YghLSMjSZbH0VR/6dMDrYJeKHilKTemt6v6kvzvn3/RrdWtr0GoN/xL+Sex/cPYLUpepx9cz/D46UPU5KXgAQa+NDps1v6J3xP1i2HtaDB0M9aX2deA7SYff//+gUCovMmIK/qfsFcOk+4Y5ZN97XlG6zebqtMbKgeRFi51vnxTQYBUik2rS/Cn6PC8ADR8FGxsRPB82dzfND90gIcshOcYUkfjherBz53odpm6TP8txlwOZ71xmfHHOvq053qFF/MRlS3jP0ELudrf2OeN8DHvp6ZceLe8qKYvWz/7yp0u4dKPfli3CYq0O13Ih71mylJ80tOi10On8wi+F4+LWgDPeJ30msSQt9/vkmHq9/Lvo2b461mP801v3W4xTcs6CbvF9UDdrSt+A8OUbpSh55qAUFXWznBBfdeJ8a4d7ugT5tvxUza3h9m4H7ptTqiG4z0g5dc0X29OcGlhpGFMpQo9ytTS+NViZpNdvU4kWx+LKxNY10kQ1yqGXrhe4/1nvP7E+nd5A92TtaRplbHSqoIdOqtRWti+fkB5/n1+/VvCmz12pG1kpQWsfi1ftlBobm0bpngs16CHkbIwdLnParxtTV3QYRlfJ0KFskH7pdN/YDn+yRuSd7sNH3aO0DYPggk6uWuXrfOc+fa3VTxFVvKaNxHsiHmsXyCLIE5yuOeN3/Jdf8HBL/5M6shjyhxHx9BjB1O0+4NLOnjLLSxwO7ukN4jMbOIcD879KLSi6Pk61Oqm2377n8079PXEEQ7cy7OKEC9nbpet118fxweTafpt69x/Bt8UqGzNQt7aelpc44dn5cqhwf71+qKp/Zf/+a0zcizOUWpl/iBcSXip0pplkatCchoH5c5aUM8I7/dWxAej8WicPL1URFZ9BDJelUwEwTkGqUhgSlydVes95YdXvhh9Gfz/aeFWvgVb4tuLbcv4+wLdutVZv/cUonwBD/6eDlE0aSiKK/uoH3+J1wDE/jMVqY2ysGufN84oIXB0sPzy8ollX/LegY74DgJXJR57sn+VGza0x3DnuIgABFM15LmajjjsNlYj+JEZGbuRYcAMOWxFkPN2w6Wd46xo4gVWQR/X4lyI/R6K/YK0110GzudPRW7Y+UOBGTfNNzHeYT0fiH0taunBpq9HEW8OKSaBGj21L0MqenEmNRWBAWDWAk4CpNoEZJ2tTaPFgbQYj8HxtFilErs3BTRwT8uO1NXQaWfIotchmPkAF5mMBAliEmZiOGVgCG9LgRzpscMAOOwowlT3JhusdazXGSC/hxR3UlmWVwWHpOIKheqONvjyhSiTHIkVUco5bnji8m//zL7PKaT1Vl5I6UE609f+gkr6MZKVyKc7zJRmCahLsdlyA5fdQkRSan9LgnnLEyGSkaKJCJog0wAgvepWBt80+1yKln1bMVtCljfNWDueKLsWwaEbBSfSPTEmVRsUcYYMnEjcjeyCZzBXK9E9BYBXLKjOSpUDR+nEV3TFSUdQaz+ot98QxgXwx0GQ+EEUAKB2qZPkQQ0GqFD8UPFMqyaCHM24BZmSGic9EYMagKizOw9Hz50DMrDLrqqLkTAhplMictiCAx5S3BIUQdeJeLnBy2CNtMfz6cV4u8XKoFZQesbf9YZiIERiHjaNodDW6LgcirX/mPnJIkBGDUpTBhSa0EIr38D5hCIszhCM8URGBqImoWjpvpt1ebu/v3Gl3qJfMnNM+9V+kiRFyROTPHQWOcs1dNW94/ukKMPZBvDi55i5CttdeJz84DLngLqjcdwEZ87bFFR8CIG35OAkDVN6VRDZ7aq67NteYqZ2lpT8oYB2CytoBd6VuAx4WgiAsnuj3WohG+LugzXiQRDeM3XYXlULv4dp5VFYC) format("woff2"),url(/assets/KaTeX_Size3-Regular-CTq5MqoE.woff) format("woff"),url(/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Size4;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2) format("woff2"),url(/assets/KaTeX_Size4-Regular-BF-4gkZK.woff) format("woff"),url(/assets/KaTeX_Size4-Regular-DWFBv043.ttf) format("truetype")}@font-face{font-display:block;font-family:KaTeX_Typewriter;font-style:normal;font-weight:400;src:url(/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2) format("woff2"),url(/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff) format("woff"),url(/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf) format("truetype")}.katex{font: 1.21em KaTeX_Main,Times New Roman,serif;line-height:1.2;position:relative;text-indent:0;text-rendering:auto}.katex *{-ms-high-contrast-adjust:none!important;border-color:currentColor}.katex .katex-version:after{content:"0.17.0"}.katex .katex-mathml{border:0;-webkit-clip-path:inset(50%);clip-path:inset(50%);height:1px;overflow:hidden;padding:0;position:absolute;width:1px}.katex .katex-html>.newline{display:block}.katex .base{position:relative;white-space:nowrap;width:-webkit-min-content;width:-moz-min-content;width:min-content}.katex .base,.katex .strut{display:inline-block}.katex .textbf{font-weight:700}.katex .textit{font-style:italic}.katex .textrm{font-family:KaTeX_Main}.katex .textsf{font-family:KaTeX_SansSerif}.katex .texttt{font-family:KaTeX_Typewriter}.katex .mathnormal{font-family:KaTeX_Math;font-style:italic}.katex .mathit{font-family:KaTeX_Main;font-style:italic}.katex .mathrm{font-style:normal}.katex .mathbf{font-family:KaTeX_Main;font-weight:700}.katex .boldsymbol{font-family:KaTeX_Math;font-style:italic;font-weight:700}.katex .amsrm,.katex .mathbb,.katex .textbb{font-family:KaTeX_AMS}.katex .mathcal{font-family:KaTeX_Caligraphic}.katex .mathfrak,.katex .textfrak{font-family:KaTeX_Fraktur}.katex .mathboldfrak,.katex .textboldfrak{font-family:KaTeX_Fraktur;font-weight:700}.katex .mathtt{font-family:KaTeX_Typewriter}.katex .mathscr,.katex .textscr{font-family:KaTeX_Script}.katex .mathsf,.katex .textsf{font-family:KaTeX_SansSerif}.katex .mathboldsf,.katex .textboldsf{font-family:KaTeX_SansSerif;font-weight:700}.katex .mathitsf,.katex .mathsfit,.katex .textitsf{font-family:KaTeX_SansSerif;font-style:italic}.katex .mainrm{font-family:KaTeX_Main;font-style:normal}.katex .vlist-t{border-collapse:collapse;display:inline-table;table-layout:fixed}.katex .vlist-r{display:table-row}.katex .vlist{display:table-cell;position:relative;vertical-align:bottom}.katex .vlist>span{display:block;height:0;position:relative}.katex .vlist>span>span{display:inline-block}.katex .vlist>span>.pstrut{overflow:hidden;width:0}.katex .vlist-t2{margin-right:-2px}.katex .vlist-s{display:table-cell;font-size:1px;min-width:2px;vertical-align:bottom;width:2px}.katex .vbox{align-items:baseline;display:inline-flex;flex-direction:column}.katex .hbox{width:100%}.katex .hbox,.katex .thinbox{display:inline-flex;flex-direction:row}.katex .thinbox{max-width:0;width:0}.katex .msupsub{text-align:left}.katex .mfrac>span>span{text-align:center}.katex .mfrac .frac-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline,.katex .hline,.katex .mfrac .frac-line,.katex .overline .overline-line,.katex .rule,.katex .underline .underline-line{min-height:1px}.katex .mspace{display:inline-block}.katex .smash{display:inline;line-height:0}.katex .clap,.katex .llap,.katex .rlap{position:relative;width:0}.katex .clap>.inner,.katex .llap>.inner,.katex .rlap>.inner{position:absolute}.katex .clap>.fix,.katex .llap>.fix,.katex .rlap>.fix{display:inline-block}.katex .llap>.inner{right:0}.katex .clap>.inner,.katex .rlap>.inner{left:0}.katex .clap>.inner>span{margin-left:-50%;margin-right:50%}.katex .rule{border:0 solid;display:inline-block;position:relative}.katex .hline,.katex .overline .overline-line,.katex .underline .underline-line{border-bottom-style:solid;display:inline-block;width:100%}.katex .hdashline{border-bottom-style:dashed;display:inline-block;width:100%}.katex .sqrt>.root{margin-left:.2777777778em;margin-right:-.5555555556em}.katex .fontsize-ensurer.reset-size1.size1,.katex .sizing.reset-size1.size1{font-size:1em}.katex .fontsize-ensurer.reset-size1.size2,.katex .sizing.reset-size1.size2{font-size:1.2em}.katex .fontsize-ensurer.reset-size1.size3,.katex .sizing.reset-size1.size3{font-size:1.4em}.katex .fontsize-ensurer.reset-size1.size4,.katex .sizing.reset-size1.size4{font-size:1.6em}.katex .fontsize-ensurer.reset-size1.size5,.katex .sizing.reset-size1.size5{font-size:1.8em}.katex .fontsize-ensurer.reset-size1.size6,.katex .sizing.reset-size1.size6{font-size:2em}.katex .fontsize-ensurer.reset-size1.size7,.katex .sizing.reset-size1.size7{font-size:2.4em}.katex .fontsize-ensurer.reset-size1.size8,.katex .sizing.reset-size1.size8{font-size:2.88em}.katex .fontsize-ensurer.reset-size1.size9,.katex .sizing.reset-size1.size9{font-size:3.456em}.katex .fontsize-ensurer.reset-size1.size10,.katex .sizing.reset-size1.size10{font-size:4.148em}.katex .fontsize-ensurer.reset-size1.size11,.katex .sizing.reset-size1.size11{font-size:4.976em}.katex .fontsize-ensurer.reset-size2.size1,.katex .sizing.reset-size2.size1{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size2.size2,.katex .sizing.reset-size2.size2{font-size:1em}.katex .fontsize-ensurer.reset-size2.size3,.katex .sizing.reset-size2.size3{font-size:1.1666666667em}.katex .fontsize-ensurer.reset-size2.size4,.katex .sizing.reset-size2.size4{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size2.size5,.katex .sizing.reset-size2.size5{font-size:1.5em}.katex .fontsize-ensurer.reset-size2.size6,.katex .sizing.reset-size2.size6{font-size:1.6666666667em}.katex .fontsize-ensurer.reset-size2.size7,.katex .sizing.reset-size2.size7{font-size:2em}.katex .fontsize-ensurer.reset-size2.size8,.katex .sizing.reset-size2.size8{font-size:2.4em}.katex .fontsize-ensurer.reset-size2.size9,.katex .sizing.reset-size2.size9{font-size:2.88em}.katex .fontsize-ensurer.reset-size2.size10,.katex .sizing.reset-size2.size10{font-size:3.4566666667em}.katex .fontsize-ensurer.reset-size2.size11,.katex .sizing.reset-size2.size11{font-size:4.1466666667em}.katex .fontsize-ensurer.reset-size3.size1,.katex .sizing.reset-size3.size1{font-size:.7142857143em}.katex .fontsize-ensurer.reset-size3.size2,.katex .sizing.reset-size3.size2{font-size:.8571428571em}.katex .fontsize-ensurer.reset-size3.size3,.katex .sizing.reset-size3.size3{font-size:1em}.katex .fontsize-ensurer.reset-size3.size4,.katex .sizing.reset-size3.size4{font-size:1.1428571429em}.katex .fontsize-ensurer.reset-size3.size5,.katex .sizing.reset-size3.size5{font-size:1.2857142857em}.katex .fontsize-ensurer.reset-size3.size6,.katex .sizing.reset-size3.size6{font-size:1.4285714286em}.katex .fontsize-ensurer.reset-size3.size7,.katex .sizing.reset-size3.size7{font-size:1.7142857143em}.katex .fontsize-ensurer.reset-size3.size8,.katex .sizing.reset-size3.size8{font-size:2.0571428571em}.katex .fontsize-ensurer.reset-size3.size9,.katex .sizing.reset-size3.size9{font-size:2.4685714286em}.katex .fontsize-ensurer.reset-size3.size10,.katex .sizing.reset-size3.size10{font-size:2.9628571429em}.katex .fontsize-ensurer.reset-size3.size11,.katex .sizing.reset-size3.size11{font-size:3.5542857143em}.katex .fontsize-ensurer.reset-size4.size1,.katex .sizing.reset-size4.size1{font-size:.625em}.katex .fontsize-ensurer.reset-size4.size2,.katex .sizing.reset-size4.size2{font-size:.75em}.katex .fontsize-ensurer.reset-size4.size3,.katex .sizing.reset-size4.size3{font-size:.875em}.katex .fontsize-ensurer.reset-size4.size4,.katex .sizing.reset-size4.size4{font-size:1em}.katex .fontsize-ensurer.reset-size4.size5,.katex .sizing.reset-size4.size5{font-size:1.125em}.katex .fontsize-ensurer.reset-size4.size6,.katex .sizing.reset-size4.size6{font-size:1.25em}.katex .fontsize-ensurer.reset-size4.size7,.katex .sizing.reset-size4.size7{font-size:1.5em}.katex .fontsize-ensurer.reset-size4.size8,.katex .sizing.reset-size4.size8{font-size:1.8em}.katex .fontsize-ensurer.reset-size4.size9,.katex .sizing.reset-size4.size9{font-size:2.16em}.katex .fontsize-ensurer.reset-size4.size10,.katex .sizing.reset-size4.size10{font-size:2.5925em}.katex .fontsize-ensurer.reset-size4.size11,.katex .sizing.reset-size4.size11{font-size:3.11em}.katex .fontsize-ensurer.reset-size5.size1,.katex .sizing.reset-size5.size1{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size5.size2,.katex .sizing.reset-size5.size2{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size5.size3,.katex .sizing.reset-size5.size3{font-size:.7777777778em}.katex .fontsize-ensurer.reset-size5.size4,.katex .sizing.reset-size5.size4{font-size:.8888888889em}.katex .fontsize-ensurer.reset-size5.size5,.katex .sizing.reset-size5.size5{font-size:1em}.katex .fontsize-ensurer.reset-size5.size6,.katex .sizing.reset-size5.size6{font-size:1.1111111111em}.katex .fontsize-ensurer.reset-size5.size7,.katex .sizing.reset-size5.size7{font-size:1.3333333333em}.katex .fontsize-ensurer.reset-size5.size8,.katex .sizing.reset-size5.size8{font-size:1.6em}.katex .fontsize-ensurer.reset-size5.size9,.katex .sizing.reset-size5.size9{font-size:1.92em}.katex .fontsize-ensurer.reset-size5.size10,.katex .sizing.reset-size5.size10{font-size:2.3044444444em}.katex .fontsize-ensurer.reset-size5.size11,.katex .sizing.reset-size5.size11{font-size:2.7644444444em}.katex .fontsize-ensurer.reset-size6.size1,.katex .sizing.reset-size6.size1{font-size:.5em}.katex .fontsize-ensurer.reset-size6.size2,.katex .sizing.reset-size6.size2{font-size:.6em}.katex .fontsize-ensurer.reset-size6.size3,.katex .sizing.reset-size6.size3{font-size:.7em}.katex .fontsize-ensurer.reset-size6.size4,.katex .sizing.reset-size6.size4{font-size:.8em}.katex .fontsize-ensurer.reset-size6.size5,.katex .sizing.reset-size6.size5{font-size:.9em}.katex .fontsize-ensurer.reset-size6.size6,.katex .sizing.reset-size6.size6{font-size:1em}.katex .fontsize-ensurer.reset-size6.size7,.katex .sizing.reset-size6.size7{font-size:1.2em}.katex .fontsize-ensurer.reset-size6.size8,.katex .sizing.reset-size6.size8{font-size:1.44em}.katex .fontsize-ensurer.reset-size6.size9,.katex .sizing.reset-size6.size9{font-size:1.728em}.katex .fontsize-ensurer.reset-size6.size10,.katex .sizing.reset-size6.size10{font-size:2.074em}.katex .fontsize-ensurer.reset-size6.size11,.katex .sizing.reset-size6.size11{font-size:2.488em}.katex .fontsize-ensurer.reset-size7.size1,.katex .sizing.reset-size7.size1{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size7.size2,.katex .sizing.reset-size7.size2{font-size:.5em}.katex .fontsize-ensurer.reset-size7.size3,.katex .sizing.reset-size7.size3{font-size:.5833333333em}.katex .fontsize-ensurer.reset-size7.size4,.katex .sizing.reset-size7.size4{font-size:.6666666667em}.katex .fontsize-ensurer.reset-size7.size5,.katex .sizing.reset-size7.size5{font-size:.75em}.katex .fontsize-ensurer.reset-size7.size6,.katex .sizing.reset-size7.size6{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size7.size7,.katex .sizing.reset-size7.size7{font-size:1em}.katex .fontsize-ensurer.reset-size7.size8,.katex .sizing.reset-size7.size8{font-size:1.2em}.katex .fontsize-ensurer.reset-size7.size9,.katex .sizing.reset-size7.size9{font-size:1.44em}.katex .fontsize-ensurer.reset-size7.size10,.katex .sizing.reset-size7.size10{font-size:1.7283333333em}.katex .fontsize-ensurer.reset-size7.size11,.katex .sizing.reset-size7.size11{font-size:2.0733333333em}.katex .fontsize-ensurer.reset-size8.size1,.katex .sizing.reset-size8.size1{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size8.size2,.katex .sizing.reset-size8.size2{font-size:.4166666667em}.katex .fontsize-ensurer.reset-size8.size3,.katex .sizing.reset-size8.size3{font-size:.4861111111em}.katex .fontsize-ensurer.reset-size8.size4,.katex .sizing.reset-size8.size4{font-size:.5555555556em}.katex .fontsize-ensurer.reset-size8.size5,.katex .sizing.reset-size8.size5{font-size:.625em}.katex .fontsize-ensurer.reset-size8.size6,.katex .sizing.reset-size8.size6{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size8.size7,.katex .sizing.reset-size8.size7{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size8.size8,.katex .sizing.reset-size8.size8{font-size:1em}.katex .fontsize-ensurer.reset-size8.size9,.katex .sizing.reset-size8.size9{font-size:1.2em}.katex .fontsize-ensurer.reset-size8.size10,.katex .sizing.reset-size8.size10{font-size:1.4402777778em}.katex .fontsize-ensurer.reset-size8.size11,.katex .sizing.reset-size8.size11{font-size:1.7277777778em}.katex .fontsize-ensurer.reset-size9.size1,.katex .sizing.reset-size9.size1{font-size:.2893518519em}.katex .fontsize-ensurer.reset-size9.size2,.katex .sizing.reset-size9.size2{font-size:.3472222222em}.katex .fontsize-ensurer.reset-size9.size3,.katex .sizing.reset-size9.size3{font-size:.4050925926em}.katex .fontsize-ensurer.reset-size9.size4,.katex .sizing.reset-size9.size4{font-size:.462962963em}.katex .fontsize-ensurer.reset-size9.size5,.katex .sizing.reset-size9.size5{font-size:.5208333333em}.katex .fontsize-ensurer.reset-size9.size6,.katex .sizing.reset-size9.size6{font-size:.5787037037em}.katex .fontsize-ensurer.reset-size9.size7,.katex .sizing.reset-size9.size7{font-size:.6944444444em}.katex .fontsize-ensurer.reset-size9.size8,.katex .sizing.reset-size9.size8{font-size:.8333333333em}.katex .fontsize-ensurer.reset-size9.size9,.katex .sizing.reset-size9.size9{font-size:1em}.katex .fontsize-ensurer.reset-size9.size10,.katex .sizing.reset-size9.size10{font-size:1.2002314815em}.katex .fontsize-ensurer.reset-size9.size11,.katex .sizing.reset-size9.size11{font-size:1.4398148148em}.katex .fontsize-ensurer.reset-size10.size1,.katex .sizing.reset-size10.size1{font-size:.2410800386em}.katex .fontsize-ensurer.reset-size10.size2,.katex .sizing.reset-size10.size2{font-size:.2892960463em}.katex .fontsize-ensurer.reset-size10.size3,.katex .sizing.reset-size10.size3{font-size:.337512054em}.katex .fontsize-ensurer.reset-size10.size4,.katex .sizing.reset-size10.size4{font-size:.3857280617em}.katex .fontsize-ensurer.reset-size10.size5,.katex .sizing.reset-size10.size5{font-size:.4339440694em}.katex .fontsize-ensurer.reset-size10.size6,.katex .sizing.reset-size10.size6{font-size:.4821600771em}.katex .fontsize-ensurer.reset-size10.size7,.katex .sizing.reset-size10.size7{font-size:.5785920926em}.katex .fontsize-ensurer.reset-size10.size8,.katex .sizing.reset-size10.size8{font-size:.6943105111em}.katex .fontsize-ensurer.reset-size10.size9,.katex .sizing.reset-size10.size9{font-size:.8331726133em}.katex .fontsize-ensurer.reset-size10.size10,.katex .sizing.reset-size10.size10{font-size:1em}.katex .fontsize-ensurer.reset-size10.size11,.katex .sizing.reset-size10.size11{font-size:1.1996142719em}.katex .fontsize-ensurer.reset-size11.size1,.katex .sizing.reset-size11.size1{font-size:.2009646302em}.katex .fontsize-ensurer.reset-size11.size2,.katex .sizing.reset-size11.size2{font-size:.2411575563em}.katex .fontsize-ensurer.reset-size11.size3,.katex .sizing.reset-size11.size3{font-size:.2813504823em}.katex .fontsize-ensurer.reset-size11.size4,.katex .sizing.reset-size11.size4{font-size:.3215434084em}.katex .fontsize-ensurer.reset-size11.size5,.katex .sizing.reset-size11.size5{font-size:.3617363344em}.katex .fontsize-ensurer.reset-size11.size6,.katex .sizing.reset-size11.size6{font-size:.4019292605em}.katex .fontsize-ensurer.reset-size11.size7,.katex .sizing.reset-size11.size7{font-size:.4823151125em}.katex .fontsize-ensurer.reset-size11.size8,.katex .sizing.reset-size11.size8{font-size:.578778135em}.katex .fontsize-ensurer.reset-size11.size9,.katex .sizing.reset-size11.size9{font-size:.6945337621em}.katex .fontsize-ensurer.reset-size11.size10,.katex .sizing.reset-size11.size10{font-size:.8336012862em}.katex .fontsize-ensurer.reset-size11.size11,.katex .sizing.reset-size11.size11{font-size:1em}.katex .delimsizing.size1{font-family:KaTeX_Size1}.katex .delimsizing.size2{font-family:KaTeX_Size2}.katex .delimsizing.size3{font-family:KaTeX_Size3}.katex .delimsizing.size4{font-family:KaTeX_Size4}.katex .delimsizing.mult .delim-size1>span{font-family:KaTeX_Size1}.katex .delimsizing.mult .delim-size4>span{font-family:KaTeX_Size4}.katex .nulldelimiter{display:inline-block;width:.12em}.katex .delimcenter,.katex .op-symbol{position:relative}.katex .op-symbol.small-op{font-family:KaTeX_Size1}.katex .op-symbol.large-op{font-family:KaTeX_Size2}.katex .accent>.vlist-t,.katex .op-limits>.vlist-t{text-align:center}.katex .accent .accent-body{position:relative}.katex .accent .accent-body:not(.accent-full){width:0}.katex .overlay{display:block}.katex .mtable .vertical-separator{display:inline-block;min-width:1px}.katex .mtable .arraycolsep{display:inline-block}.katex .mtable .col-align-c>.vlist-t{text-align:center}.katex .mtable .col-align-l>.vlist-t{text-align:left}.katex .mtable .col-align-r>.vlist-t{text-align:right}.katex .svg-align{text-align:left}.katex svg{fill:currentColor;stroke:currentColor;display:block;height:inherit;position:absolute;width:100%}.katex svg path{stroke:none}.katex svg{fill-rule:nonzero;fill-opacity:1;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1}.katex img{border-style:none;max-height:none;max-width:none;min-height:0;min-width:0}.katex .stretchy{display:block;overflow:hidden;position:relative;width:100%}.katex .stretchy:after,.katex .stretchy:before{content:""}.katex .hide-tail{overflow:hidden;position:relative;width:100%}.katex .halfarrow-left{left:0;overflow:hidden;position:absolute;width:50.2%}.katex .halfarrow-right{overflow:hidden;position:absolute;right:0;width:50.2%}.katex .brace-left{left:0;overflow:hidden;position:absolute;width:25.1%}.katex .brace-center{left:25%;overflow:hidden;position:absolute;width:50%}.katex .brace-right{overflow:hidden;position:absolute;right:0;width:25.1%}.katex .x-arrow-pad{padding:0 .5em}.katex .cd-arrow-pad{padding:0 .55556em 0 .27778em}.katex .mover,.katex .munder,.katex .x-arrow{text-align:center}.katex .boxpad{padding:0 .3em}.katex .fbox,.katex .fcolorbox{border:.04em solid;box-sizing:border-box}.katex .cancel-pad{padding:0 .2em}.katex .cancel-lap{margin-left:-.2em;margin-right:-.2em}.katex .sout{border-bottom-style:solid;border-bottom-width:.08em}.katex .angl{border-right:.049em solid;border-top:.049em solid;box-sizing:border-box;margin-right:.03889em}.katex .anglpad{padding:0 .03889em}.katex .eqn-num:before{content:"(" counter(katexEqnNo) ")";counter-increment:katexEqnNo}.katex .mml-eqn-num:before{content:"(" counter(mmlEqnNo) ")";counter-increment:mmlEqnNo}.katex .mtr-glue{width:50%}.katex .cd-vert-arrow{display:inline-block;position:relative}.katex .cd-label-left{display:inline-block;position:absolute;right:calc(50% + .3em);text-align:left}.katex .cd-label-right{display:inline-block;left:calc(50% + .3em);position:absolute;text-align:right}.katex-display{display:block;margin:1em 0;text-align:center}.katex-display>.katex{display:block;text-align:center;white-space:nowrap}.katex-display>.katex>.katex-html{display:block;position:relative}.katex-display>.katex>.katex-html>.tag{position:absolute;right:0}.katex-display.leqno>.katex>.katex-html>.tag{left:0;right:auto}.katex-display.fleqn>.katex{padding-left:2em;text-align:left}body{counter-reset:katexEqnNo mmlEqnNo}.md[data-v-2a3e373d]{font:400 var(--content-font-size)/1.6 var(--font-ui);line-height:round(calc(var(--content-font-size) * 1.625),1px);color:var(--color-text);word-break:break-word}.md[data-v-2a3e373d] .markdown-renderer{font:400 var(--content-font-size)/1.6 var(--font-ui);line-height:round(calc(var(--content-font-size) * 1.625),1px);color:var(--color-text)}.md[data-v-2a3e373d] .markstream-vue,.md[data-v-2a3e373d] .markdown-renderer{--code-bg: var(--color-surface-sunken);--code-fg: var(--color-text);--code-border: var(--color-line);--code-header-bg: var(--color-surface);--code-action-fg: var(--color-text-muted);--code-action-hover-fg: var(--color-accent);--markstream-code-fallback-bg: var(--color-surface-sunken);--markstream-code-fallback-fg: var(--color-text);--markstream-code-border-color: var(--color-line);--inline-code-bg: var(--color-inline-code-bg);--inline-code-fg: var(--color-text);--inline-code-border: transparent}.md[data-v-2a3e373d] .md-file-link{appearance:none;display:inline;border:0;padding:0;background:transparent;color:var(--color-accent-hover);font:inherit;text-decoration:underline;text-decoration-thickness:1px;text-underline-offset:2px;cursor:pointer}.md[data-v-2a3e373d] .md-file-link:hover{color:var(--color-accent)}.md[data-v-2a3e373d] .inline-code .md-file-link{text-underline-offset:1.5px}.md[data-v-2a3e373d] .markdown-renderer p,.md[data-v-2a3e373d] .markdown-renderer li{font-size:var(--content-font-size);line-height:round(calc(var(--content-font-size) * 1.625),1px)}.md[data-v-2a3e373d] .markdown-renderer blockquote,.md[data-v-2a3e373d] .markdown-renderer td,.md[data-v-2a3e373d] .markdown-renderer th{font-size:var(--md-b2)}.md[data-v-2a3e373d] .markdown-renderer img{background:var(--media-alpha-canvas)}.md[data-v-2a3e373d] strong{color:color-mix(in srgb,var(--color-text) 86%,var(--color-text-muted));font-weight:var(--weight-semibold)}.md[data-v-2a3e373d] h1,.md[data-v-2a3e373d] h2,.md[data-v-2a3e373d] h3,.md[data-v-2a3e373d] h4{color:var(--color-text);font-optical-sizing:auto;font-weight:600;margin:.85em 0 .35em}.md[data-v-2a3e373d] h1{font-size:var(--md-h1);line-height:round(calc(var(--md-h1) * 1.63),1px);border-bottom:1px solid var(--color-line);padding-bottom:4px}.md[data-v-2a3e373d] h2{font-size:var(--md-h2);line-height:round(calc(var(--md-h2) * 1.6),1px)}.md[data-v-2a3e373d] h3{font-size:var(--md-h3);line-height:round(calc(var(--md-h3) * 1.56),1px)}.md[data-v-2a3e373d] h4{font-size:var(--md-b2);line-height:round(calc(var(--md-b2) * 1.6),1px);color:var(--color-text-muted)}.md[data-v-2a3e373d] p{margin:0}.md[data-v-2a3e373d] .node-slot+.node-slot{margin-top:var(--content-font-size)}.md[data-v-2a3e373d] .node-slot+.node-slot:has(h1),.md[data-v-2a3e373d] .node-slot+.node-slot:has(h2){margin-top:calc(var(--content-font-size) * 2)}.md[data-v-2a3e373d] .node-slot+.node-slot:has(h3),.md[data-v-2a3e373d] .node-slot+.node-slot:has(h4){margin-top:calc(var(--content-font-size) * 1.5)}.md[data-v-2a3e373d] ul,.md[data-v-2a3e373d] ol{--md-dot: round(calc(var(--content-font-size) * .375), 1px);list-style:none;margin:0;padding-left:calc(var(--content-font-size) * 2)}.md[data-v-2a3e373d] li{position:relative;margin:0;padding:0}.md[data-v-2a3e373d] li+li{margin-top:round(calc(var(--content-font-size) * .75),1px)}.md[data-v-2a3e373d] li>ul,.md[data-v-2a3e373d] li>ol{margin-top:round(calc(var(--content-font-size) * .75),1px);padding-left:calc(var(--content-font-size) * 1.5)}.md[data-v-2a3e373d] ul>li:before{content:"";position:absolute;left:calc((var(--md-dot) + var(--content-font-size) * 2) / -2);top:calc((round(calc(var(--content-font-size) * 1.625),1px) - var(--md-dot)) / 2);width:var(--md-dot);height:var(--md-dot);border-radius:50%;background:color-mix(in srgb,var(--color-text) 90%,transparent)}.md[data-v-2a3e373d] ul>li:has(>input[type=checkbox]):before,.md[data-v-2a3e373d] ul>li:has(>p>input[type=checkbox]):before{content:none}.md[data-v-2a3e373d] ul ul>li:before{background:transparent;border:1px solid color-mix(in srgb,var(--color-text) 90%,transparent);box-sizing:border-box}.md[data-v-2a3e373d] ol{counter-reset:md-ol}.md[data-v-2a3e373d] ol[start],.md[data-v-2a3e373d] ol:has(>li[value]){counter-reset:none;list-style:decimal}.md[data-v-2a3e373d] ol[start]>li,.md[data-v-2a3e373d] ol:has(>li[value])>li{counter-increment:none}.md[data-v-2a3e373d] ol[start]>li:before,.md[data-v-2a3e373d] ol:has(>li[value])>li:before{content:none}.md[data-v-2a3e373d] ol>li{counter-increment:md-ol}.md[data-v-2a3e373d] ol>li:before{content:counter(md-ol) ".";position:absolute;top:0;left:calc(var(--content-font-size) * -2);width:calc(var(--content-font-size) * 2);line-height:round(calc(var(--content-font-size) * 1.625),1px);text-align:center;color:var(--color-text)}.md[data-v-2a3e373d] :not(pre)>code,.md[data-v-2a3e373d] .inline-code{font:.9em var(--font-mono);background:var(--color-inline-code-bg);color:var(--color-text);border:0;padding:0 4px;border-radius:var(--radius-sm)}.md[data-v-2a3e373d] strong code,.md[data-v-2a3e373d] strong .inline-code,.md[data-v-2a3e373d] b code,.md[data-v-2a3e373d] b .inline-code{font-weight:var(--weight-semibold)}.md[data-v-2a3e373d] .code-block-container{margin:.6em 0;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);box-shadow:var(--shadow-xs);overflow:hidden;--vscode-editor-font-size: var(--text-sm);--vscode-editor-line-height: calc(var(--text-sm) * 1.65)}.md[data-v-2a3e373d] .code-block-header{background:var(--color-surface);border-bottom:.5px solid var(--color-line);padding:4px 6px 4px 12px;color:var(--color-text-muted);font:var(--text-xs) var(--font-ui)}.md[data-v-2a3e373d] .code-block-header *{color:var(--color-text-muted);font:var(--text-xs) var(--font-ui)}.md[data-v-2a3e373d] .code-block-header .code-header-main{font-family:var(--font-ui)}.md[data-v-2a3e373d] .code-block-header .code-action-btn{color:var(--color-text-muted);background:transparent;border:none;border-radius:var(--radius-sm);cursor:pointer;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.md[data-v-2a3e373d] .code-block-header .code-action-btn:hover{background:var(--color-surface-sunken);color:var(--color-text)}.md[data-v-2a3e373d] .code-block-header .code-action-btn:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md[data-v-2a3e373d] .code-block-header .code-action-btn *{pointer-events:none}.md[data-v-2a3e373d] .code-block-shell-content,.md[data-v-2a3e373d] .markstream-pre{background:var(--color-well)}.md[data-v-2a3e373d] .code-editor-container{line-height:1.65;--diffs-gap-block: var(--space-3)}.md[data-v-2a3e373d] .code-editor-container diffs-container{--diffs-line-height: 1.65em}.md[data-v-2a3e373d] .code-pre-fallback>.markstream-pre__line-numbers{display:none}.md[data-v-2a3e373d] .code-block-container .code-pre-fallback{padding-left:1ch;line-height:1.65!important}.md[data-v-2a3e373d] .code-block-container pre:not(.code-pre-fallback):not(.markstream-pre--line-numbers),.md[data-v-2a3e373d] .markstream-pre:not(.code-pre-fallback):not(.markstream-pre--line-numbers){margin:0;padding:12px 14px;overflow-x:auto;font:var(--text-sm)/1.65 var(--font-mono)}.md[data-v-2a3e373d] .code-block-container pre code{font:inherit;color:var(--color-text);background:none;border:none;padding:0;border-radius:0}.md[data-v-2a3e373d] .markstream-pre,.md[data-v-2a3e373d] .code-pre-fallback,.md[data-v-2a3e373d] .code-block-shell-content pre:not(.shiki),.md[data-v-2a3e373d] .code-block-shell-content pre:not(.shiki) code{color:var(--color-text)}.md[data-v-2a3e373d] a{color:var(--color-accent);text-decoration:none}.md[data-v-2a3e373d] a:hover{text-decoration:underline}.md[data-v-2a3e373d] .katex-display{overflow-x:auto;overflow-y:hidden;padding:2px 0 6px;margin:.6em 0}.md[data-v-2a3e373d] .math-inline{vertical-align:baseline}.md[data-v-2a3e373d] blockquote{position:relative;margin:0;padding:0 0 0 round(calc(var(--content-font-size) * 1.5),1px);border-left:none;color:var(--color-text)}.md[data-v-2a3e373d] blockquote:before{content:"";position:absolute;left:calc(round(calc(var(--content-font-size) * 1.5),1px)/2 - 1px);top:2px;bottom:2px;width:2px;border-radius:2px;background:var(--color-line)}.md[data-v-2a3e373d] .blockquote>.paragraph-node{margin:0}.md[data-v-2a3e373d] .blockquote>.paragraph-node+.paragraph-node{margin-top:var(--content-font-size)}.md[data-v-2a3e373d] hr{border:none;border-top:1px solid var(--color-line);margin:0}.md[data-v-2a3e373d] table:not(.table-node){border-collapse:collapse;font-size:var(--text-lg);margin:.5em 0}.md[data-v-2a3e373d] table:not(.table-node) th,.md[data-v-2a3e373d] table:not(.table-node) td{border:1px solid var(--color-line);padding:4px 10px;text-align:left}.md[data-v-2a3e373d] table:not(.table-node) th{background:var(--color-surface);color:var(--color-text);font-weight:var(--weight-medium)}.md[data-v-2a3e373d] .table-node-wrapper{width:100%;max-width:100%!important;min-width:0;overflow-x:auto!important;scrollbar-gutter:auto!important;position:relative;--table-cell-cap: var(--p-table-cell-max)}.md[data-v-2a3e373d] .table-node{--table-border: var(--color-line);--table-header-bg: var(--color-surface);font-size:var(--text-lg);margin:.5em 0;width:max-content!important;min-width:100%;max-width:none!important;table-layout:auto!important}.md[data-v-2a3e373d] .table-node th,.md[data-v-2a3e373d] .table-node td{text-align:left;vertical-align:top;max-width:var(--table-cell-cap)}.md[data-v-2a3e373d] .table-node .text-node{display:inline-block;max-width:var(--table-cell-cap);vertical-align:top}.md[data-v-2a3e373d] .md-table-fade{display:none;position:absolute;top:0;bottom:0;right:0;width:36px;z-index:1;background:linear-gradient(to right,transparent,color-mix(in srgb,var(--color-bg) 65%,transparent) 55%,var(--color-bg));pointer-events:none;transition:opacity var(--duration-base) var(--ease-out)}.md[data-v-2a3e373d] .md-table-at-end .md-table-fade{opacity:0}.md[data-v-2a3e373d] .md-table-toggle{display:none;position:absolute;top:6px;right:6px;z-index:2;align-items:center;justify-content:center;width:26px;height:26px;color:var(--color-text-muted);background:var(--color-surface);border:1px solid var(--color-line);border-radius:var(--radius-sm);box-shadow:var(--shadow-sm);cursor:pointer;opacity:0;transition:opacity var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}@container (min-width: 760px){.md[data-v-2a3e373d] .md-table-fade.md-table-toggle--show,.md[data-v-2a3e373d] .md-table-toggle.md-table-toggle--show{display:block}.md[data-v-2a3e373d] .md-table-toggle.md-table-toggle--show{display:inline-flex}}.md[data-v-2a3e373d] .table-node-wrapper:hover .md-table-toggle.md-table-toggle--show,.md[data-v-2a3e373d] .table-node-wrapper:focus-within .md-table-toggle.md-table-toggle--show,.md[data-v-2a3e373d] .table-node-wrapper.md-table-wide .md-table-toggle.md-table-toggle--show{opacity:1}.md[data-v-2a3e373d] .md-table-toggle:hover{background:var(--color-surface-sunken);color:var(--color-text)}.md[data-v-2a3e373d] .md-table-toggle:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md[data-v-2a3e373d] .md-table-toggle svg{display:block}.md[data-v-2a3e373d] .table-node tbody tr:hover{background-color:transparent!important}.diff-wrap[data-v-2a3e373d]{margin:.6em 0;border:1px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-surface-sunken);box-shadow:var(--shadow-xs);overflow:hidden}.diff-bar[data-v-2a3e373d]{display:flex;align-items:center;gap:6px;padding:4px 12px;background:var(--color-surface);border-bottom:1px solid var(--color-line);color:var(--color-text-muted);font:var(--text-xs) var(--font-mono)}.diff-lang[data-v-2a3e373d]{margin-right:auto}.diff-copy[data-v-2a3e373d]{display:inline-flex;align-items:center;justify-content:center;color:var(--color-text-muted);background:transparent;border:none;border-radius:var(--radius-sm);cursor:pointer;padding:2px 6px;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.diff-copy[data-v-2a3e373d]:hover{background:var(--color-surface-sunken);color:var(--color-text)}.diff-copy[data-v-2a3e373d]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.diff-pre[data-v-2a3e373d]{margin:0;padding:12px 0;overflow-x:auto;background:var(--color-surface-sunken)}.diff-pre code[data-v-2a3e373d]{display:block;width:max-content;min-width:100%;font:var(--text-sm)/1.65 var(--font-mono);color:var(--color-text)}.diff-line[data-v-2a3e373d]{display:block;width:100%;padding:0 14px}.diff-sign[data-v-2a3e373d]{display:inline-block;width:14px;text-align:center;color:var(--color-text-muted);user-select:none}.diff-text[data-v-2a3e373d]{color:var(--color-text)}.diff-add[data-v-2a3e373d]{background:var(--color-success-soft);box-shadow:inset 2px 0 color-mix(in srgb,var(--color-success) 55%,transparent)}.diff-add .diff-sign[data-v-2a3e373d]{color:var(--color-success)}.diff-del[data-v-2a3e373d]{background:var(--color-danger-soft);box-shadow:inset 2px 0 color-mix(in srgb,var(--color-danger) 55%,transparent)}.diff-del .diff-sign[data-v-2a3e373d]{color:var(--color-danger)}.diff-hunk[data-v-2a3e373d]{background:var(--color-surface)}.diff-hunk .diff-text[data-v-2a3e373d]{color:var(--color-text-muted)}.md[data-v-2a3e373d],.md .markdown-renderer[data-v-2a3e373d]{font-family:var(--sans)}.md .code-block-container[data-v-2a3e373d],.md .diff-wrap[data-v-2a3e373d]{border-radius:var(--radius-md)}.md :not(pre)>code[data-v-2a3e373d],.md .inline-code[data-v-2a3e373d]{border-radius:var(--radius-sm)}.upd[data-v-c0a4acce]{display:inline-flex;flex:none;-webkit-app-region:no-drag;animation:upd-in-c0a4acce var(--duration-base) var(--ease-out)}@keyframes upd-in-c0a4acce{0%{opacity:0;transform:scale(.85)}}.upd-pill[data-v-c0a4acce]{display:inline-flex;align-items:center;gap:var(--space-1);padding:0 var(--space-2);border:none;border-radius:var(--radius-full);background:var(--color-warning);color:var(--color-text-on-accent);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:var(--leading-normal);white-space:nowrap;cursor:pointer;transition:filter var(--duration-fast) var(--ease-out)}.upd-pill[data-v-c0a4acce]:hover{filter:brightness(1.1)}.upd-pill[data-v-c0a4acce]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.upd-pill-icon[data-v-c0a4acce]{flex:none;color:var(--color-text-on-accent)}.upd[data-state=downloading] .upd-pill-text[data-v-c0a4acce]{display:inline-block;min-width:4ch;text-align:left;font-variant-numeric:tabular-nums}@container sidebar-col (max-width: 250px){.upd-pill[data-v-c0a4acce]{padding:var(--space-1)}.upd-pill-text[data-v-c0a4acce]{display:none}}.upd-meta[data-v-c0a4acce]{margin:0;font-size:var(--text-xs);line-height:var(--leading-normal);color:var(--color-text-faint)}.upd-message[data-v-c0a4acce]{margin:0;font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted);word-break:break-all}.upd-notes[data-v-c0a4acce]{margin-top:var(--space-3);padding-top:var(--space-3);border-top:1px solid var(--color-line);max-height:min(360px,45vh);overflow-y:auto;font-size:var(--text-sm);line-height:var(--leading-normal);color:var(--color-text)}.upd-notes-title[data-v-c0a4acce]{margin:0 0 var(--space-2);font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--color-text-faint)}.upd-notes[data-v-c0a4acce] ul,.upd-notes[data-v-c0a4acce] p{margin:0}.upd-notes[data-v-c0a4acce] li+li{margin-top:var(--space-1)}.upd-notes[data-v-c0a4acce] h3{margin:var(--space-3) 0 var(--space-1);font-size:var(--text-sm);font-weight:var(--weight-medium);line-height:var(--leading-normal);color:var(--color-text)}.upd-notes[data-v-c0a4acce] h3:first-child{margin-top:0}.upd-notes[data-v-c0a4acce]:first-child{margin-top:0;padding-top:0;border-top:none}.upd-foot[data-v-c0a4acce]{display:flex;flex-direction:column;align-items:stretch;gap:var(--space-3);width:100%}.upd-foot-actions[data-v-c0a4acce]{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2)}.upd-auto[data-v-c0a4acce]{align-self:flex-end}.upd-progress[data-v-c0a4acce]{margin-top:var(--space-3);height:var(--space-1);border-radius:var(--radius-xs);background:var(--color-line);overflow:hidden}.upd-progress-fill[data-v-c0a4acce]{height:100%;border-radius:var(--radius-xs);background:var(--color-accent);transition:width var(--duration-base) var(--ease-out)}.user-menu-trigger[data-v-06f13413]{display:flex;align-items:center;gap:var(--sb-gap);width:100%;min-width:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);cursor:pointer;text-align:left}.user-menu-trigger[data-v-06f13413]:hover,.user-menu-trigger[aria-expanded=true][data-v-06f13413]{background:var(--sb-hover)}.user-menu-trigger[data-v-06f13413]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.user-menu-trigger svg[data-v-06f13413]{flex:none}.user-menu-avatar[data-v-06f13413]{display:flex;align-items:center;justify-content:center;width:24px;height:24px;flex:none;border-radius:var(--radius-full);background:var(--color-surface-sunken);color:var(--color-text-muted);overflow:hidden}.user-menu-avatar img[data-v-06f13413]{width:100%;height:100%;object-fit:cover}.user-menu-name[data-v-06f13413]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-menu[data-v-06f13413]{position:fixed;top:0;left:0;z-index:var(--z-dropdown);max-height:calc(100vh - 16px);overflow-y:auto;overflow-x:hidden}.user-submenu[data-v-06f13413]{position:fixed;top:0;left:0;z-index:var(--z-dropdown);width:max-content;max-height:calc(100vh - 16px);overflow-y:auto;overflow-x:hidden}.menu-pop-enter-active[data-v-06f13413]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-06f13413]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-06f13413],.menu-pop-leave-to[data-v-06f13413]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, 2px))}.user-menu-usage[data-v-06f13413]{display:flex;flex-direction:column;gap:3px;padding:5px 9px 7px}.user-menu-usage-state[data-v-06f13413]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-1) 0;color:var(--color-text-muted);font-size:var(--text-sm)}.user-menu-usage-error[data-v-06f13413]{flex:1;min-width:0}.user-menu-usage-empty[data-v-06f13413]{color:var(--color-text-faint)}.user-menu-usage-row[data-v-06f13413]{display:flex;align-items:flex-start;gap:var(--space-3)}.user-menu-usage-main[data-v-06f13413]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.user-menu-usage-label[data-v-06f13413]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-sm);color:var(--color-text)}.user-menu-usage-hint[data-v-06f13413]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);color:var(--color-text-faint)}.user-menu-usage-value[data-v-06f13413]{flex:none;font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);font-variant-numeric:tabular-nums;white-space:nowrap}.user-menu-usage-value.sev-warn[data-v-06f13413]{color:var(--color-warning)}.user-menu-usage-value.sev-danger[data-v-06f13413]{color:var(--color-danger)}.user-menu-item-label[data-v-06f13413]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.user-menu-login-label[data-v-06f13413]{color:var(--color-accent)}.user-menu-row-value[data-v-06f13413]{flex:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);color:var(--color-text-faint)}.emoji-picker[data-v-05e46bbb]{--ep-cell: 26px}.ep-search[data-v-05e46bbb]{display:flex;align-items:center;gap:var(--space-2);margin:var(--space-1);padding:0 var(--space-2);border-radius:var(--radius-sm);color:var(--color-text-faint)}.ep-search[data-v-05e46bbb]:hover,.ep-search[data-v-05e46bbb]:focus-within{background:var(--color-surface-sunken)}.ep-input[data-v-05e46bbb]{flex:1;min-width:0;height:calc(var(--ep-cell) + 2px);font-size:var(--text-sm);color:var(--color-text);background:transparent;border:none;outline:none}.ep-input[data-v-05e46bbb]::placeholder{color:var(--color-text-faint)}.ep-scroll[data-v-05e46bbb]{max-height:calc(var(--ep-cell) * 10 + var(--space-1));overflow-y:auto;padding:0 var(--space-1)}.ep-label[data-v-05e46bbb]{padding:var(--space-1) var(--space-2);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--color-text-faint);user-select:none}.ep-grid[data-v-05e46bbb]{display:grid;grid-template-columns:repeat(8,var(--ep-cell));gap:var(--space-1);padding-bottom:var(--space-1)}.ep-e[data-v-05e46bbb]{height:var(--ep-cell);display:grid;place-items:center;padding:0;font-size:var(--text-lg);background:transparent;border:none;border-radius:var(--radius-xs);cursor:pointer}.ep-e[data-v-05e46bbb]:hover{background:var(--color-hover)}.ep-e[data-v-05e46bbb]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ep-e.sel[data-v-05e46bbb]{background:var(--color-accent-soft)}.ep-empty[data-v-05e46bbb]{padding:var(--space-3) var(--space-2);font-size:var(--text-xs);color:var(--color-text-faint);text-align:center;user-select:none}.se[data-v-341acfa2]{--se-pad-x: var(--space-2);display:block;margin:0;padding:8px var(--se-pad-x);border-radius:var(--radius-sm);font-family:var(--font-ui);color:var(--color-text);cursor:pointer;position:relative}.se[data-v-341acfa2]:hover{background:var(--sb-hover, var(--color-hover));color:var(--color-text)}.se.on[data-v-341acfa2]{background:var(--sb-selected, var(--color-selected));color:var(--color-text)}.row[data-v-341acfa2]{display:flex;align-items:center;gap:var(--sb-gap, 6px);min-width:0}.left[data-v-341acfa2]{display:flex;align-items:center;flex:1;min-width:0}.lead[data-v-341acfa2]{width:var(--sb-gutter, 16px);flex:none;display:inline-flex;align-items:center;justify-content:center}.unread-dot[data-v-341acfa2]{width:7px;height:7px;border-radius:var(--radius-full);background:var(--color-accent)}.t[data-v-341acfa2]{--sb-fade: 0px;--sb-fade-len: 16px;color:inherit;font-size:var(--ui-font-size-sm);font-weight:450;line-height:var(--leading-tight);user-select:none;flex:1;min-width:0;overflow:hidden;text-overflow:clip;white-space:nowrap;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)));mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)))}.se:hover .t[data-v-341acfa2]{--sb-fade: 34px;--sb-fade-len: 26px}.se:has(.ui-badge):hover .t[data-v-341acfa2]{--sb-fade: 0px;--sb-fade-len: 16px}.t .emoji[data-v-341acfa2]{padding:0;background:transparent;border:none;cursor:pointer}.t .emoji[data-v-341acfa2]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.sub[data-v-341acfa2]{display:flex;align-items:center;gap:var(--space-1);margin:var(--space-1) 0 0;color:var(--color-text-faint);font-size:var(--text-xs);line-height:var(--leading-tight);user-select:none}.sub-icon[data-v-341acfa2]{flex:none;color:var(--color-text-muted)}.pr[data-v-341acfa2]{display:inline-flex;align-items:center;gap:var(--space-05);flex:none;padding:0;border:none;background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);cursor:pointer}.pr[data-v-341acfa2]:hover{color:var(--color-text-muted)}.pr[data-v-341acfa2]:focus-visible{outline:none;border-radius:var(--radius-xs);box-shadow:var(--p-focus-ring)}.pr--open[data-v-341acfa2],.pr--open[data-v-341acfa2]:hover{color:var(--color-success)}.pr--merged[data-v-341acfa2],.pr--merged[data-v-341acfa2]:hover{color:var(--color-done)}.sub-text[data-v-341acfa2]{flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent);mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - 16px),transparent)}.ts[data-v-341acfa2]{color:var(--color-text-faint);font-size:var(--text-xs);font-family:var(--font-ui);font-weight:475;line-height:var(--leading-tight);font-variant-numeric:tabular-nums;text-align:right}.act[data-v-341acfa2]{position:relative;flex:none;align-self:stretch;display:inline-flex;align-items:center;justify-content:flex-end;gap:var(--sb-gap, 6px);min-width:26px}.act .ha[data-v-341acfa2]{position:absolute;top:0;bottom:0;right:calc(3px - var(--se-pad-x));display:inline-flex;align-items:center;gap:2px;opacity:0;visibility:hidden;border-radius:var(--radius-sm);transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.se:hover .ha[data-v-341acfa2]{opacity:1;visibility:visible;transition:opacity var(--duration-fast) var(--ease-out)}.act .ts[data-v-341acfa2]{transition:opacity var(--duration-fast) var(--ease-out)}.se:hover .act .ts[data-v-341acfa2]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.act .st[data-v-341acfa2]{display:inline-flex;align-items:center;transition:opacity var(--duration-fast) var(--ease-out)}.se:hover .act .st[data-v-341acfa2]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.act .ui-badge[data-v-341acfa2]{transition:opacity var(--duration-fast) var(--ease-out)}.se.flat:hover .act .ui-badge[data-v-341acfa2]{opacity:0;visibility:hidden;transition:opacity var(--duration-fast) var(--ease-out),visibility 0s linear var(--duration-fast)}.menu[data-v-341acfa2],.picker[data-v-341acfa2]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.menu-pop-enter-active[data-v-341acfa2]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-341acfa2]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-341acfa2],.menu-pop-leave-to[data-v-341acfa2]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}.menu-time[data-v-341acfa2]{padding:6px 10px;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);cursor:default;user-select:text}.rename-input[data-v-341acfa2]{flex:1;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs);padding:1px 4px;outline:none;min-width:0}.sessions .se[data-v-341acfa2]{margin:0;border-radius:var(--radius-sm);--se-pad-x: calc(var(--sb-pad-x, 20px) - var(--sb-inset, 12px));padding:8px var(--se-pad-x)}.sessions .se.flat+.se.flat[data-v-341acfa2]{margin-top:var(--space-05)}.sessions .se .rename-input[data-v-341acfa2]{border-radius:var(--radius-sm);font-family:var(--sans)}.group.dragging[data-v-9586bfbe]{opacity:.45}.group.pinned-drag-active[data-v-9586bfbe],.group.pinned-drop-hover[data-v-9586bfbe]{border-radius:var(--radius-sm)}.group.pinned-drag-active[data-v-9586bfbe]{box-shadow:inset 0 0 0 1px var(--color-accent)}.group.pinned-drop-hover[data-v-9586bfbe]{box-shadow:inset 0 0 0 2px var(--color-accent)}.group.pinned-drop-blocked[data-v-9586bfbe],.group.pinned-drop-blocked[data-v-9586bfbe] *{cursor:no-drop}.group-sessions[data-v-9586bfbe]{height:auto;overflow:hidden;transition:height var(--duration-base) var(--ease-out)}.group-sessions.collapsed[data-v-9586bfbe]{height:0}.gh[data-v-9586bfbe]{display:flex;flex-direction:column;margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border-radius:var(--radius-sm);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text);user-select:none;position:relative;cursor:grab}.gh[data-v-9586bfbe]:active{cursor:grabbing}.gh[data-v-9586bfbe]:hover{background:var(--sb-hover, var(--color-hover))}.gh.on[data-v-9586bfbe]{background:var(--sb-selected, var(--color-selected))}.gh-top[data-v-9586bfbe]{position:relative;display:flex;align-items:center;gap:var(--sb-gap)}.gh-folder[data-v-9586bfbe]{flex:none;color:var(--color-text-muted)}.gh-name[data-v-9586bfbe]{font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);color:var(--color-text-muted);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.gh-actions[data-v-9586bfbe]{position:absolute;right:calc(3px - (var(--sb-pad-x) - var(--sb-inset)));top:50%;transform:translateY(-50%);display:flex;align-items:center;gap:var(--space-1);padding-left:var(--space-1);border-radius:var(--radius-sm);isolation:isolate;opacity:0;pointer-events:none}.gh-name[data-v-9586bfbe]{--sb-fade: 0px;--sb-fade-len: 16px;text-overflow:clip;-webkit-mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)));mask-image:linear-gradient(to right,var(--color-text-strong) calc(100% - var(--sb-fade) - var(--sb-fade-len)),transparent calc(100% - var(--sb-fade)))}.gh:hover .gh-name[data-v-9586bfbe],.gh:focus-within .gh-name[data-v-9586bfbe],.gh:has(.gh-actions.open) .gh-name[data-v-9586bfbe]{--sb-fade: 64px;--sb-fade-len: 26px}.gh-actions[data-v-9586bfbe]>*{position:relative;z-index:1}.gh:hover .gh-actions[data-v-9586bfbe],.gh:focus-within .gh-actions[data-v-9586bfbe],.gh-actions.open[data-v-9586bfbe]{opacity:1;pointer-events:auto}.gh-more.open[data-v-9586bfbe]{color:var(--color-text);background:var(--color-line)}.group-empty[data-v-9586bfbe]{padding:var(--space-1) var(--space-2) var(--space-1) calc(var(--sb-pad-x) - var(--sb-inset) + var(--sb-gutter) + var(--sb-gap));font-size:var(--text-xs);color:var(--color-text-faint);font-family:var(--font-ui);user-select:none}.show-more-row[data-v-9586bfbe]{display:flex;align-items:center;padding-left:calc(var(--sb-gutter) + var(--sb-gap))}.show-more[data-v-9586bfbe]{display:flex;align-items:center;gap:var(--sb-gap);margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));min-width:0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);text-align:left;cursor:pointer}.show-more[data-v-9586bfbe]:hover{background:var(--sb-hover, var(--color-hover))}.show-more[data-v-9586bfbe]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.show-more-sep[data-v-9586bfbe]{margin:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);user-select:none}.show-more-label[data-v-9586bfbe]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gh-rename[data-v-9586bfbe]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-regular);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs);padding:2px 5px;outline:none}.gh-rename[data-v-9586bfbe]{border-radius:var(--radius-sm);font-family:var(--sans)}.gh-add[data-v-9586bfbe]{color:var(--faint)}.gh-add[data-v-9586bfbe]:hover{color:var(--dim)}.pinned-label[data-v-aec340eb]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 var(--space-3) var(--space-1) var(--space-2);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--faint);user-select:none}.pinned-title[data-v-aec340eb]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pinned-toggle[data-v-aec340eb]{color:var(--faint);opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.pinned-label:hover .pinned-toggle[data-v-aec340eb],.pinned-label:focus-within .pinned-toggle[data-v-aec340eb],.pinned-toggle--on[data-v-aec340eb]{opacity:1}.pinned-toggle[data-v-aec340eb]:hover{color:var(--dim)}.pinned-toggle svg[data-v-aec340eb]{width:13px;height:13px}.pinned-rows[data-v-aec340eb]{max-height:40vh;overflow-y:auto}.pinned-rows[data-v-aec340eb]::-webkit-scrollbar{width:4px}.pinned-rows[data-v-aec340eb]::-webkit-scrollbar-track{background:transparent}.pinned-rows[data-v-aec340eb]::-webkit-scrollbar-thumb{background:transparent;border-radius:var(--radius-full);transition:background var(--duration-base) var(--ease-out)}.pinned-rows[data-v-aec340eb]:hover::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.pinned-rows[data-v-aec340eb]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.pin-drop-target.dragging[data-v-aec340eb]{opacity:.45}.pin-drop-target.drop-before[data-v-aec340eb]{box-shadow:inset 0 2px 0 var(--color-accent)}.pin-drop-target.drop-after[data-v-aec340eb]{box-shadow:inset 0 -2px 0 var(--color-accent)}.side[data-v-a80a4ba6]{background:var(--color-sidebar-bg);display:flex;flex-direction:row;justify-content:flex-end;overflow:hidden;min-width:0;height:100%;transition:width .28s cubic-bezier(.4,0,.2,1),visibility .28s;--sb-inset: var(--space-2);--sb-pad-x: var(--space-4);--sb-gutter: 16px;--sb-gap: var(--space-2);--sb-hover: var(--color-hover);--sb-selected: color-mix(in srgb, var(--color-selected) 75%, transparent)}.side.no-anim[data-v-a80a4ba6]{transition:none}.side.collapsed[data-v-a80a4ba6]{visibility:hidden}.col[data-v-a80a4ba6]{flex:none;min-width:0;display:flex;flex-direction:column;min-height:0;width:100%;box-sizing:border-box;border-right:.5px solid var(--line);container-type:inline-size;container-name:sidebar-col;position:relative}.ch[data-v-a80a4ba6]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:var(--space-3);min-height:calc(26px + 2 * var(--space-3));width:100%;box-sizing:border-box}.side.macos-desktop .ch[data-v-a80a4ba6]{padding-left:80px;-webkit-app-region:drag}.side.macos-desktop .ch-brand[data-v-a80a4ba6]{display:none}.ch-logo[data-v-a80a4ba6]{height:22px;width:32px;flex:none;display:block;cursor:pointer;user-select:none;touch-action:none;transition:transform .18s ease}.ch-logo[data-v-a80a4ba6]:hover{transform:scale(1.08)}.ch-brand[data-v-a80a4ba6]{display:flex;align-items:center;gap:8px;min-width:0;flex:1;user-select:none;touch-action:none}.ch-tail[data-v-a80a4ba6]{display:flex;align-items:center;gap:var(--space-2);flex:none;min-width:0;margin-left:auto}.ch-name[data-v-a80a4ba6]{font-size:var(--ui-font-size);font-weight:500;line-height:22px;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}@container sidebar-col (max-width: 250px){.ch-name[data-v-a80a4ba6]{display:none}}.sidebar-actions[data-v-a80a4ba6]{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:0 var(--space-2);padding:0 var(--sb-inset) var(--space-1);position:relative;z-index:1;background:var(--color-sidebar-bg)}.sessions-head[data-v-a80a4ba6]{position:relative;z-index:1;padding:var(--space-3) var(--sb-inset) 0;border-bottom:.5px solid transparent;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out)}.sessions-head[data-v-a80a4ba6]:after,.side-footer[data-v-a80a4ba6]:before{content:"";position:absolute;left:0;right:0;height:13px;pointer-events:none;opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.sessions-head[data-v-a80a4ba6]:after{top:100%;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) .75%,transparent),transparent);transition-duration:var(--duration-slow)}.sessions-head--scrolled[data-v-a80a4ba6]{border-bottom-color:var(--line)}.sessions-head--scrolled[data-v-a80a4ba6]:after{opacity:1}.btn-new-chat[data-v-a80a4ba6]{grid-column:1 / -1;display:flex;align-items:center;gap:var(--sb-gap);width:100%;min-width:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);cursor:pointer;text-align:left}.sidebar-actions--has-workspace-action .btn-new-chat[data-v-a80a4ba6]{grid-column:1}.btn-new-chat[data-v-a80a4ba6]:hover{background:var(--sb-hover)}.btn-new-chat[data-v-a80a4ba6]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.btn-new-chat svg[data-v-a80a4ba6]{flex:none}.btn-new-chat span[data-v-a80a4ba6]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.btn-new-chat[data-v-a80a4ba6] .ui-kbd{margin-left:auto}.btn-new-chat[data-v-a80a4ba6] .ui-kbd,.search[data-v-a80a4ba6] .ui-kbd{opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.btn-new-chat[data-v-a80a4ba6]:hover .ui-kbd,.btn-new-chat[data-v-a80a4ba6]:focus-visible .ui-kbd,.search[data-v-a80a4ba6]:hover .ui-kbd,.search[data-v-a80a4ba6]:focus-visible .ui-kbd{opacity:1}.search[data-v-a80a4ba6]{grid-column:1 / -1;display:flex;align-items:center;gap:var(--sb-gap);width:100%;margin:0;padding:8px calc(var(--sb-pad-x) - var(--sb-inset));border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font:inherit;text-align:left;cursor:pointer}.search[data-v-a80a4ba6]:hover{background:var(--sb-hover)}.search[data-v-a80a4ba6]:focus-visible{background:var(--sb-hover);color:var(--color-text);outline:2px solid var(--color-accent-bd);outline-offset:-2px}.search-icon[data-v-a80a4ba6]{flex:none;transform:translateY(-.5px)}.search-input[data-v-a80a4ba6]{flex:1;min-width:0;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sessions[data-v-a80a4ba6]{flex:1;overflow-y:auto;padding:0 var(--sb-inset) var(--space-3);min-height:0}.sessions[data-v-a80a4ba6]::-webkit-scrollbar{width:4px}.sessions[data-v-a80a4ba6]::-webkit-scrollbar-track{background:transparent}.sessions[data-v-a80a4ba6]::-webkit-scrollbar-thumb{background:transparent;border-radius:var(--radius-full);transition:background var(--duration-base) var(--ease-out)}.sessions.scrolling[data-v-a80a4ba6]::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.sessions.scrolling[data-v-a80a4ba6]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.side-footer[data-v-a80a4ba6]{flex:none;position:relative;z-index:1;padding:var(--space-2) var(--sb-inset);border-top:.5px solid var(--line);background:var(--color-sidebar-bg)}.side-footer[data-v-a80a4ba6]:before{bottom:100%;background:linear-gradient(to top,color-mix(in srgb,var(--color-text) 1.5%,transparent),transparent 35%),linear-gradient(to top,color-mix(in srgb,var(--color-text) 1%,transparent),transparent 65%),linear-gradient(to top,color-mix(in srgb,var(--color-text) .75%,transparent),transparent);transition-duration:var(--duration-slow)}.side-footer--shadowed[data-v-a80a4ba6]:before{opacity:1}.side-section-label[data-v-a80a4ba6]{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:0 var(--space-3) var(--space-1) var(--space-2);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-section-label);text-transform:uppercase;color:var(--faint);user-select:none}.side-section-title[data-v-a80a4ba6]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sessions-head .pinned+.side-section-label[data-v-a80a4ba6]{margin-top:var(--space-2)}.side-section-toggle[data-v-a80a4ba6]{color:var(--faint);opacity:0;transition:opacity var(--duration-base) var(--ease-out)}.side-section-label:hover .side-section-toggle[data-v-a80a4ba6],.side-section-label:focus-within .side-section-toggle[data-v-a80a4ba6]{opacity:1}.side-section-toggle[data-v-a80a4ba6]:hover{color:var(--dim)}.side-section-toggle svg[data-v-a80a4ba6]{width:13px;height:13px}.side-section-actions[data-v-a80a4ba6]{display:flex;align-items:center;gap:2px}.ws-drop-target.drop-before[data-v-a80a4ba6]{box-shadow:inset 0 2px 0 var(--color-accent)}.ws-drop-target.drop-after[data-v-a80a4ba6]{box-shadow:inset 0 -2px 0 var(--color-accent)}.sessions.pinned-drag-active[data-v-a80a4ba6]{box-shadow:inset 0 0 0 1px var(--color-accent)}.sessions.flat-pinned-drop-hover[data-v-a80a4ba6]{box-shadow:inset 0 0 0 2px var(--color-accent)}.show-more-row[data-v-a80a4ba6]{display:flex;align-items:center;justify-content:center}.show-more[data-v-a80a4ba6]{display:flex;align-items:center;justify-content:center;gap:var(--space-1);margin:0;padding:6px var(--space-3);min-width:0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);cursor:pointer}.show-more[data-v-a80a4ba6]:hover{background:var(--sb-hover, var(--color-hover))}.show-more[data-v-a80a4ba6]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.show-more-label[data-v-a80a4ba6]{flex:none;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.folder-drop-overlay[data-v-a80a4ba6]{position:absolute;inset:0;z-index:1;display:flex;align-items:center;justify-content:center;padding:var(--space-3);box-sizing:border-box;background:color-mix(in srgb,var(--color-sidebar-bg) 72%,transparent);pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--duration-base) ease,visibility var(--duration-base)}.folder-drop-overlay.show[data-v-a80a4ba6]{opacity:1;visibility:visible}.folder-drop-card[data-v-a80a4ba6]{display:flex;align-items:center;gap:var(--space-3);max-width:100%;box-sizing:border-box;padding:var(--space-4);border-radius:var(--radius-lg);border:.5px dashed var(--color-accent);background:var(--color-bg);color:var(--color-accent);font-size:var(--ui-font-size-lg);font-weight:var(--weight-medium);box-shadow:var(--shadow-md)}.folder-drop-card svg[data-v-a80a4ba6]{flex:none}.folder-drop-card span[data-v-a80a4ba6]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.empty[data-v-a80a4ba6]{padding:var(--space-6) var(--space-3);text-align:center;color:var(--faint);font-size:calc(var(--ui-font-size) - 3px);line-height:1.6}.ws-menu[data-v-a80a4ba6],.gh-menu[data-v-a80a4ba6],.view-menu[data-v-a80a4ba6]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.view-menu-label[data-v-a80a4ba6]{padding:var(--space-1) var(--space-2) var(--space-05);font-size:var(--text-xs);color:var(--faint);user-select:none}.view-menu-check[data-v-a80a4ba6]{margin-left:auto;display:inline-flex}.menu-pop-enter-active[data-v-a80a4ba6]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-a80a4ba6]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-a80a4ba6],.menu-pop-leave-to[data-v-a80a4ba6]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}[data-v-a80a4ba6] .workspace-rename-item{font-size:var(--text-xs);font-weight:var(--weight-option-label)}.section-menu-check[data-v-a80a4ba6]{display:inline-flex;flex:none;width:14px}.rh[data-v-1c6dfdc5]{width:4px;flex:none;position:relative;align-self:stretch;background:transparent;touch-action:none;margin:0 -2px;z-index:var(--z-dropdown)}.rh-bar[data-v-1c6dfdc5]{position:absolute;inset:0 1px;background:transparent;transition:background .12s}.rh:hover .rh-bar[data-v-1c6dfdc5]{background:var(--color-selected)}.rh.dragging .rh-bar[data-v-1c6dfdc5]{background:var(--color-line-strong)}.op[data-v-ab413c67]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);background:var(--color-well);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);white-space:pre-wrap;word-break:break-word;max-height:12lh;overflow-y:auto;overscroll-behavior:contain;scrollbar-gutter:stable}.op-empty[data-v-ab413c67]{color:var(--color-text-faint);font-style:italic}.agent-card[data-v-7cea5372]{margin:var(--space-1) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);overflow:hidden;transition:border-color var(--duration-base) var(--ease-out)}.agent-card[data-v-7cea5372]:hover{border-color:var(--color-line-strong)}.agent-card.err[data-v-7cea5372]{border-color:color-mix(in srgb,var(--color-danger) 45%,var(--bg))}.head[data-v-7cea5372]{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border:none;background:transparent;color:var(--color-text);font-family:var(--font-ui);text-align:left;cursor:pointer}.head[data-v-7cea5372]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.head[data-v-7cea5372]:disabled{cursor:default}.lead[data-v-7cea5372]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-md);background:var(--color-surface-sunken);color:var(--color-text-muted);flex:none}.main[data-v-7cea5372]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.task[data-v-7cea5372]{font-size:var(--ui-font-size);line-height:1.4;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.type[data-v-7cea5372]{font-size:var(--text-xs);line-height:1.4;color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tail[data-v-7cea5372]{display:flex;align-items:center;gap:var(--space-2);flex:none}.st[data-v-7cea5372]{display:inline-flex;align-items:center}.st.ok[data-v-7cea5372]{color:var(--color-success)}.st.error[data-v-7cea5372]{color:var(--color-danger)}.go[data-v-7cea5372]{color:var(--color-text-faint);transition:color var(--duration-base) var(--ease-out)}.agent-card:hover .head:not(:disabled) .go[data-v-7cea5372]{color:var(--color-text)}.go.car[data-v-7cea5372]{transition:color var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.go.car.open[data-v-7cea5372]{transform:rotate(90deg)}.saved-result[data-v-7cea5372]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) var(--space-3);border:none;border-top:.5px solid var(--color-line);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);text-align:left;cursor:pointer}.saved-result[data-v-7cea5372]:hover{color:var(--color-text-muted)}.saved-result[data-v-7cea5372]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.saved-result__chevron[data-v-7cea5372]{transition:transform var(--duration-base) var(--ease-out)}.saved-result__chevron.open[data-v-7cea5372]{transform:rotate(90deg)}.result[data-v-7cea5372]{padding:var(--space-2) var(--space-3)}.result--legacy[data-v-7cea5372]{border-top:.5px solid var(--color-line)}.tl-head[data-v-58658159]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) 0;border-radius:var(--radius-sm);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left}.tl-head.clickable[data-v-58658159]{cursor:pointer;user-select:none}.tl-ic[data-v-58658159]{display:inline-flex;align-items:center;justify-content:flex-start;flex:none;color:var(--color-text-faint)}.tl-main[data-v-58658159]{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-1)}.tl-tail[data-v-58658159]{margin-left:auto;display:flex;align-items:center;gap:var(--space-1);flex:none}.tl-status[data-v-58658159]{display:inline-flex;align-items:center;flex:none}.tl-status.ok[data-v-58658159]{color:var(--color-success)}.tl-status.error[data-v-58658159]{color:var(--color-danger)}.tl-car[data-v-58658159]{display:inline-flex;align-items:center;justify-content:center;align-self:center;width:16px;height:16px;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);cursor:pointer;flex:none}.tl-car[data-v-58658159]:hover{color:var(--color-text)}.tl-car[data-v-58658159]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-car-ic[data-v-58658159]{transition:transform var(--duration-base) var(--ease-out)}.tool-line.open .tl-car-ic[data-v-58658159]{transform:rotate(90deg)}.tl-body[data-v-58658159]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.tl-body.open[data-v-58658159]{grid-template-rows:minmax(0,1fr)}.tl-body-inner[data-v-58658159]{min-height:0;overflow:hidden;padding:2px var(--space-2) var(--space-1) 0}.tl-main .tl-name[data-v-58658159-s]{font-weight:var(--weight-regular);color:var(--color-text-muted);flex:none}.tl-main .tl-dim[data-v-58658159-s]{color:var(--color-text-muted);line-height:var(--leading-tight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-faint[data-v-58658159-s]{color:var(--color-text-faint);line-height:var(--leading-tight);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-mono[data-v-58658159-s]{font-family:var(--font-mono);font-size:var(--text-xs);font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);line-height:normal;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tl-main .tl-file[data-v-58658159-s]{font-weight:var(--weight-regular);color:var(--color-text);line-height:var(--leading-tight);flex:none;max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;border:none;border-radius:var(--radius-xs);background:transparent;padding:0 1px;font-family:inherit;font-size:inherit;cursor:pointer}.tl-main .tl-file[data-v-58658159-s]:hover{color:var(--color-accent);text-decoration:underline;text-underline-offset:3px}.tl-main .tl-file[data-v-58658159-s]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-tail .tl-pill[data-v-58658159-s]{font-size:var(--text-xs);line-height:1.5;padding:0 var(--space-2);border-radius:var(--radius-full);flex:none;white-space:nowrap}.tl-tail .tl-chip[data-v-58658159-s]{color:var(--color-text-faint);font-size:var(--text-xs);flex:none;white-space:nowrap}.tl-tail .tl-add[data-v-58658159-s]{color:var(--color-success);font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.tl-tail .tl-del[data-v-58658159-s]{color:var(--color-danger);font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.ask-receipt[data-v-f29eda04]{max-width:560px;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-xs);padding:var(--space-2) var(--space-3) 10px;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text)}.ask-receipt.flat[data-v-f29eda04]{color:var(--color-text-faint);font-style:italic;padding-top:6px;padding-bottom:6px}.rc-head[data-v-f29eda04]{display:flex;align-items:center;gap:var(--space-2);color:var(--color-text-faint);font-size:var(--text-xs);margin-bottom:6px}.rc-st[data-v-f29eda04]{margin-left:auto;color:var(--color-success);display:inline-flex}.rc-q+.rc-q[data-v-f29eda04]{margin-top:6px}.rc-qtext[data-v-f29eda04]{display:flex;align-items:baseline;gap:var(--space-2);margin-bottom:3px;font-weight:var(--weight-medium);color:var(--color-text)}.rc-opt[data-v-f29eda04]{display:flex;align-items:center;gap:var(--space-2);padding:1.5px 0;color:var(--color-text)}.rc-qskip[data-v-f29eda04]{padding:1.5px 0;color:var(--color-text-faint);font-style:italic}.rc-lb[data-v-f29eda04]{min-width:0}.rc-ds[data-v-f29eda04]{color:var(--color-text-faint);font-size:var(--text-xs)}.rc-g[data-v-f29eda04]{width:14px;height:14px;flex:none;border:.5px solid var(--color-line-strong);position:relative}.rc-g.chk[data-v-f29eda04]{border-radius:var(--radius-xs)}.rc-g.rad[data-v-f29eda04]{border-radius:50%}.rc-g.on[data-v-f29eda04]{border-color:var(--color-accent)}.rc-g.chk.on[data-v-f29eda04]{background:var(--color-accent)}.rc-g.chk.on[data-v-f29eda04]:after{content:"";position:absolute;left:3.5px;top:.5px;width:4px;height:8px;border-right:1.5px solid var(--color-text-on-accent);border-bottom:1.5px solid var(--color-text-on-accent);transform:rotate(45deg)}.rc-g.rad.on[data-v-f29eda04]:after{content:"";position:absolute;inset:2.5px;border-radius:50%;background:var(--color-accent)}.cmd-echo[data-v-8869dd42]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.hl-code[data-v-6735e4da]{border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);overflow:auto;max-height:calc(24 * 1.5 * var(--ui-font-size));overscroll-behavior:contain;font-family:var(--font-mono);font-size:var(--code-font-size);line-height:var(--leading-normal);font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none}.hl-code[data-v-6735e4da]:not(.framed){border:none;border-radius:0;background:transparent;max-height:none;overflow:visible}.hl-body[data-v-6735e4da]{width:max-content;min-width:100%;padding:var(--space-1) 0 var(--space-2)}.hl-code.plain-pad .hl-body[data-v-6735e4da]{padding-left:var(--space-3)}.hl-row[data-v-6735e4da]{display:flex;align-items:flex-start;min-height:calc(1em * var(--leading-normal));white-space:pre;width:100%}.hl-gutter[data-v-6735e4da]{flex:none;box-sizing:content-box;min-width:var(--gutter-ch, 4ch);padding:0 var(--space-2);text-align:right;color:var(--color-text-faint);user-select:none;border-right:.5px solid var(--color-line);font-variant-numeric:tabular-nums}.hl-sign[data-v-6735e4da]{flex:none;width:16px;text-align:center;color:var(--color-text-muted);user-select:none}.hl-text[data-v-6735e4da]{flex:none;padding-right:14px;white-space:pre;color:var(--color-text)}.hl-gutter+.hl-text[data-v-6735e4da]{padding-left:var(--space-2)}.row-add[data-v-6735e4da]{background:var(--color-diff-add-bg)}.row-add .hl-sign[data-v-6735e4da]{color:var(--color-success)}.row-del[data-v-6735e4da]{background:var(--color-diff-del-bg)}.row-del .hl-sign[data-v-6735e4da]{color:var(--color-danger)}.row-hunk[data-v-6735e4da]{background:var(--color-surface-sunken)}.row-hunk .hl-text[data-v-6735e4da]{color:var(--color-text-muted)}.hl-code.gutter .row-add[data-v-6735e4da]{box-shadow:inset 2px 0 color-mix(in srgb,var(--color-success) 55%,transparent)}.hl-code.gutter .row-del[data-v-6735e4da]{box-shadow:inset 2px 0 color-mix(in srgb,var(--color-danger) 55%,transparent)}.diffbar[data-v-bbf61950]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);overflow:hidden;gap:1px;flex:none}.seg-add[data-v-bbf61950]{background:var(--color-success)}.seg-del[data-v-bbf61950]{background:var(--color-danger)}.gl[data-v-b12a8498]{display:inline-flex;align-items:center}.arg-full[data-v-b12a8498]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.file-list[data-v-3936099e]{display:flex;flex-direction:column;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-1);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.file-row[data-v-3936099e]{width:100%;border:none;border-radius:var(--radius-sm);background:transparent;padding:2px var(--space-2);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.file-row[data-v-3936099e]:hover{background:var(--color-hover);color:var(--color-accent)}.file-row[data-v-3936099e]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tl-pill.pill-active[data-v-862274de]{color:var(--color-accent);background:var(--color-accent-soft)}.tl-pill.pill-done[data-v-862274de]{color:var(--color-success);background:var(--color-success-soft)}.tl-pill.pill-blocked[data-v-862274de]{color:var(--color-warning);background:var(--color-warning-soft)}.goal-block[data-v-862274de]{margin-bottom:var(--space-1)}.goal-text[data-v-862274de]{color:var(--color-text);font-size:calc(var(--content-font-size) - 1px);line-height:1.6;white-space:pre-wrap;word-break:break-word}.goal-criterion[data-v-862274de]{color:var(--color-text-muted);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;margin-top:2px;white-space:pre-wrap;word-break:break-word}.match-list[data-v-899c1a48]{display:flex;flex-direction:column;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-1);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.match-row[data-v-899c1a48]{display:flex;align-items:baseline;gap:var(--space-2);width:100%;border:none;border-radius:var(--radius-sm);background:transparent;padding:2px var(--space-2);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;font-feature-settings:"liga" 0,"calt" 0;font-variant-ligatures:none;color:var(--color-text);text-align:left;cursor:default}.match-row.link[data-v-899c1a48]{cursor:pointer}.match-row.link[data-v-899c1a48]:hover{background:var(--color-hover)}.match-row[data-v-899c1a48]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.mref[data-v-899c1a48]{flex:none;max-width:45%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-faint)}.match-row.link:hover .mref[data-v-899c1a48]{color:var(--color-accent)}.mtext[data-v-899c1a48]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.is-resolving[data-v-0826404b]{visibility:hidden}.media-tool[data-v-3bc3ee1a]{display:inline-flex;flex-direction:column;gap:6px;max-width:320px}.media-title[data-v-3bc3ee1a]{font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-image-button[data-v-3bc3ee1a]{padding:0;border:none;background:transparent;cursor:pointer;border-radius:var(--radius-md);overflow:hidden}.media-image[data-v-3bc3ee1a]{display:block;max-width:100%;border-radius:var(--radius-md);background:var(--media-alpha-canvas)}.media-video[data-v-3bc3ee1a],.media-audio[data-v-3bc3ee1a]{max-width:100%;border-radius:var(--radius-md)}.media-video[data-v-3bc3ee1a]{display:block}.media-video-button[data-v-3bc3ee1a]{position:relative}.media-video-tile[data-v-3bc3ee1a]{display:block;width:320px;max-width:100%;aspect-ratio:16 / 9;background:var(--color-well)}.media-play-badge[data-v-3bc3ee1a]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:var(--radius-full);background:var(--color-surface-raised);border:.5px solid var(--color-line);color:var(--color-text);box-shadow:var(--shadow-sm);pointer-events:none}.plan-glyph[data-v-8dff80a1]{display:inline-flex;align-items:center}.plan-path[data-v-8dff80a1]{display:block;max-width:100%;margin:0 0 var(--space-2);padding:0;overflow:hidden;border:none;background:transparent;color:var(--color-accent);font-family:var(--font-mono);font-size:var(--text-xs);text-align:left;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.plan-path[data-v-8dff80a1]:hover{text-decoration:underline}.plan-path[data-v-8dff80a1]:focus-visible{outline:none;border-radius:var(--radius-xs);box-shadow:var(--p-focus-ring)}.plan-content[data-v-8dff80a1]{padding:var(--space-3);border:1px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);color:var(--color-text)}.plan-review[data-v-8dff80a1]{display:flex;flex-direction:column;gap:var(--space-1);margin-top:var(--space-2);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);line-height:var(--leading-normal)}.plan-review>div[data-v-8dff80a1]{display:flex;align-items:baseline;gap:var(--space-2)}.review-label[data-v-8dff80a1]{flex:none;color:var(--color-text-faint)}.review-feedback[data-v-8dff80a1]{white-space:pre-wrap}.path-link[data-v-0edbdd82]{display:block;width:100%;border:none;border-radius:var(--radius-xs);background:transparent;padding:0 0 var(--space-1);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);color:var(--color-text-muted);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.path-link[data-v-0edbdd82]:hover{color:var(--color-accent);text-decoration:underline;text-underline-offset:3px}.path-link[data-v-0edbdd82]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.swarm-card[data-v-f360563e]{margin:0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);overflow:hidden;transition:border-color var(--duration-base) var(--ease-out)}.swarm-card.err[data-v-f360563e]{border-color:color-mix(in srgb,var(--color-danger) 45%,var(--bg))}.head[data-v-f360563e]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:34px;padding:0 var(--space-2) 0 var(--space-3);border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--ui-font-size);text-align:left;cursor:pointer;user-select:none}.head[data-v-f360563e]:hover{background:var(--color-hover);color:var(--color-text)}.head[data-v-f360563e]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.ic[data-v-f360563e]{color:var(--color-text-faint);flex:none}.title[data-v-f360563e]{font-weight:var(--weight-medium);color:var(--color-text);flex:none}.meta[data-v-f360563e]{color:var(--color-text-faint);flex:none}.sum-txt[data-v-f360563e]{color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}.rt[data-v-f360563e]{margin-left:auto;display:flex;align-items:center;gap:var(--space-2);flex:none;color:var(--color-text-muted);font-size:var(--text-xs)}.status[data-v-f360563e]{display:inline-flex;align-items:center;flex:none}.status[data-v-f360563e]:has(>svg){color:var(--color-success)}.err .status[data-v-f360563e]:has(>svg){color:var(--color-danger)}.chip[data-v-f360563e]{color:var(--color-text-muted);font-family:var(--font-mono)}.tm[data-v-f360563e]{color:var(--color-text-faint);font-family:var(--font-mono)}.car[data-v-f360563e]{margin-left:2px;color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.swarm-card.open .car[data-v-f360563e]{transform:rotate(90deg)}.body[data-v-f360563e]{border-top:.5px solid var(--color-line)}.overview[data-v-f360563e]{padding:10px var(--space-3) var(--space-2);border-bottom:.5px solid var(--color-line)}.overview-line[data-v-f360563e]{display:flex;align-items:baseline;gap:var(--space-2)}.big[data-v-f360563e]{font-family:var(--font-mono);font-weight:var(--weight-medium);color:var(--color-text);font-size:15px}.lbl[data-v-f360563e]{color:var(--color-text-muted);font-size:var(--text-xs)}.seg[data-v-f360563e]{display:flex;height:5px;border-radius:var(--radius-full);overflow:hidden;margin:var(--space-2) 0 var(--space-1);gap:2px}.seg>span[data-v-f360563e]{height:100%;border-radius:var(--radius-full);min-width:3px}.s-ok[data-v-f360563e]{background:var(--color-success)}.s-run[data-v-f360563e]{background:var(--color-accent)}.s-warn[data-v-f360563e]{background:var(--color-warning)}.s-fail[data-v-f360563e]{background:var(--color-danger)}.s-queue[data-v-f360563e]{background:var(--color-line)}.legend[data-v-f360563e]{display:flex;flex-wrap:wrap;gap:10px}.legend span[data-v-f360563e]{display:inline-flex;align-items:center;gap:5px;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted)}.lg-dot[data-v-f360563e]{width:6px;height:6px;border-radius:var(--radius-full)}.member[data-v-f360563e]{border-bottom:.5px solid var(--color-line)}.member[data-v-f360563e]:last-child{border-bottom:none}.member-head[data-v-f360563e]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:30px;padding:0 var(--space-2) 0 var(--space-3);border:none;background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size);text-align:left;cursor:pointer;user-select:none}.member-head[data-v-f360563e]:not(:disabled):hover{background:var(--color-hover)}.member-head[data-v-f360563e]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.member-head[data-v-f360563e]:disabled{cursor:default}.row-dot[data-v-f360563e]{flex:none}.mname[data-v-f360563e]{flex:none;min-width:0;max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-medium);color:var(--color-text)}.mact[data-v-f360563e]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted);font-size:var(--text-xs)}.mphase[data-v-f360563e]{flex:none;margin-left:auto;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint)}.phase-completed .mphase[data-v-f360563e]{color:var(--color-success)}.phase-failed .mphase[data-v-f360563e]{color:var(--color-danger)}.phase-working .mphase[data-v-f360563e]{color:var(--color-accent)}.phase-suspended .mphase[data-v-f360563e]{color:var(--color-warning)}.mcar[data-v-f360563e]{margin-left:var(--space-1);color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.member.open .mcar[data-v-f360563e]{transform:rotate(90deg)}.member-saved[data-v-f360563e]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) var(--space-3);border:none;border-top:.5px solid var(--color-line);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-xs);text-align:left;cursor:pointer}.member-saved[data-v-f360563e]:hover{color:var(--color-text-muted)}.member-saved[data-v-f360563e]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.member-saved-car[data-v-f360563e]{transition:transform var(--duration-base) var(--ease-out)}.member-saved-car.open[data-v-f360563e]{transform:rotate(90deg)}.member-body[data-v-f360563e]{padding:var(--space-1) var(--space-3) 10px 31px;color:var(--color-text-muted);font-size:calc(var(--content-font-size) - 2px);line-height:1.65;white-space:pre-wrap;word-break:break-word}.waiting[data-v-f360563e]{padding:6px var(--space-3) 10px;color:var(--color-text-muted);font-size:var(--text-xs)}.fallback-output[data-v-f360563e]{padding:10px var(--space-3);color:var(--color-text);font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;white-space:pre-wrap;word-break:break-word}.status-glyph[data-v-f1aedfd0]{flex:none;width:16px;display:inline-flex;align-items:center;justify-content:center;user-select:none}.status-glyph.s-run[data-v-f1aedfd0]{color:var(--color-accent)}.status-glyph.s-done[data-v-f1aedfd0]{color:var(--color-success)}.status-glyph.s-fail[data-v-f1aedfd0]{color:var(--color-danger)}.status-glyph.s-pending[data-v-f1aedfd0]{color:var(--color-text-faint)}.todo-bar[data-v-1b7f51f3]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden;flex:none}.todo-fill[data-v-1b7f51f3]{background:var(--color-success);border-radius:var(--radius-full);transition:width var(--duration-slow) var(--ease-out)}.todo-list[data-v-1b7f51f3]{display:flex;flex-direction:column;gap:1px;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);padding:var(--space-2) var(--space-3);max-height:calc(12 * 1.6 * var(--content-font-size));overflow-y:auto;overscroll-behavior:contain}.todo-row[data-v-1b7f51f3]{display:flex;align-items:center;gap:7px;padding:2px 0;font-size:calc(var(--content-font-size) - 1px);color:var(--color-text)}.todo-title[data-v-1b7f51f3]{flex:1;min-width:0;overflow-wrap:anywhere;line-height:1.4}.todo-row.s-in_progress .todo-title[data-v-1b7f51f3]{font-weight:var(--weight-medium)}.todo-row.s-done .todo-title[data-v-1b7f51f3]{color:var(--color-text-faint);text-decoration:line-through}.fetch-url[data-v-8c248fcc]{font-family:var(--font-mono);font-size:calc(var(--content-font-size) - 2px);line-height:1.6;color:var(--color-text-faint);white-space:pre-wrap;word-break:break-all;margin-bottom:var(--space-1)}.think[data-v-7d463c2a]{margin:0}.think-head[data-v-7d463c2a]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-1) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.think-head[data-v-7d463c2a]:hover{color:var(--color-text)}.think-head[data-v-7d463c2a]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.think-bulb[data-v-7d463c2a]{flex:none}.think-title[data-v-7d463c2a]{font-weight:var(--weight-medium)}.think-time[data-v-7d463c2a]{color:var(--color-text-faint);font-weight:400;flex:none}.think.streaming .think-title[data-v-7d463c2a]{animation:think-breathe-7d463c2a 1.6s var(--ease-in-out) infinite}@keyframes think-breathe-7d463c2a{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.think.streaming .think-title[data-v-7d463c2a]{animation:none}}.think-car[data-v-7d463c2a]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.think.open .think-car[data-v-7d463c2a]{transform:rotate(90deg)}.think-body[data-v-7d463c2a]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.think-body.instant[data-v-7d463c2a]{transition:none}.think-body.open[data-v-7d463c2a]{grid-template-rows:minmax(0,1fr)}.think-body-inner[data-v-7d463c2a]{min-height:0;overflow:hidden}.think-text[data-v-7d463c2a]{font:var(--text-base)/var(--leading-relaxed) var(--font-ui);font-weight:400;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-word;margin:0;padding:var(--space-1) 0 var(--space-2)}.mob .think-text[data-v-7d463c2a]{color:var(--color-text-faint);line-height:var(--leading-normal)}.activity-run[data-v-91eb361a]{display:flex;flex-direction:column;animation:kimi-card-in var(--duration-base) var(--ease-out)}.ar-head[data-v-91eb361a]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.ar-head[data-v-91eb361a]:hover{color:var(--color-text)}.ar-head[data-v-91eb361a]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.ar-glyph[data-v-91eb361a]{display:inline-flex;align-items:center;flex:none;color:var(--color-text-faint)}.ar-glyph.ok[data-v-91eb361a]{color:var(--color-success)}.ar-glyph.err[data-v-91eb361a]{color:var(--color-danger)}.ar-glyph.run[data-v-91eb361a]{color:var(--color-text-muted);animation:ar-breathe-91eb361a 1.6s var(--ease-in-out) infinite}@keyframes ar-breathe-91eb361a{0%,to{opacity:1}50%{opacity:.45}}@media(prefers-reduced-motion:reduce){.ar-glyph.run[data-v-91eb361a]{animation:none}}.ar-sum[data-v-91eb361a]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-regular)}.ar-danger[data-v-91eb361a]{color:var(--color-danger)}.ar-faint[data-v-91eb361a],.ar-sep[data-v-91eb361a]{color:var(--color-text-faint)}.ar-car[data-v-91eb361a]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.activity-run.open .ar-car[data-v-91eb361a]{transform:rotate(90deg)}.ar-body[data-v-91eb361a]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.ar-body.open[data-v-91eb361a]{grid-template-rows:minmax(0,1fr)}.ar-body-inner[data-v-91eb361a]{min-height:0;overflow:hidden;display:flex;flex-direction:column;gap:var(--space-2);padding-top:var(--space-1)}.msg-time[data-v-9153170e]{display:inline-flex;align-items:center;min-height:22px;box-sizing:border-box;padding:2px 5px;border-radius:var(--radius-sm);color:var(--muted);font-size:var(--text-xs);font-weight:var(--weight-medium);line-height:1;opacity:.7;white-space:nowrap}.ntf[data-v-69e0a1db],.ntf-group-card[data-v-69e0a1db]{margin:var(--space-2) 0;border:.5px solid var(--color-line);border-radius:var(--radius-lg);background:var(--color-surface);box-shadow:var(--shadow-xs);overflow:hidden;animation:kimi-card-in var(--duration-slow) var(--ease-out)}.ntf.ok[data-v-69e0a1db]{background:var(--color-success-soft);border-color:var(--color-success-bd)}.ntf.err[data-v-69e0a1db]{background:var(--color-danger-soft);border-color:var(--color-danger-bd)}.ntf.warn[data-v-69e0a1db]{background:var(--color-warning-soft);border-color:var(--color-warning-bd)}.ntf-head[data-v-69e0a1db]{display:flex;align-items:center;gap:var(--space-2);width:100%;padding:var(--space-2) var(--space-3);border:none;text-align:left;user-select:none}.ntf-chip[data-v-69e0a1db]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-md);background:var(--color-surface-raised);box-shadow:var(--shadow-xs);flex:none;color:var(--color-text-muted)}.ntf.ok .ntf-chip[data-v-69e0a1db]{color:var(--color-success)}.ntf.err .ntf-chip[data-v-69e0a1db]{color:var(--color-danger)}.ntf.warn .ntf-chip[data-v-69e0a1db]{color:var(--color-warning)}.ntf-main[data-v-69e0a1db]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.ntf-title[data-v-69e0a1db]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-normal)}.ntf-sub[data-v-69e0a1db]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ntf-side[data-v-69e0a1db]{flex:none;display:inline-flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);color:var(--color-text-faint)}.ntf-side .st[data-v-69e0a1db]{font-weight:var(--weight-medium)}.ntf.ok .st[data-v-69e0a1db],.ng-item.ok .st[data-v-69e0a1db]{color:var(--color-success)}.ntf.err .st[data-v-69e0a1db],.ng-item.err .st[data-v-69e0a1db]{color:var(--color-danger)}.ntf.warn .st[data-v-69e0a1db],.ng-item.warn .st[data-v-69e0a1db]{color:var(--color-warning)}.ntf-car[data-v-69e0a1db]{color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.ntf.open>.ntf-head .ntf-car[data-v-69e0a1db],.ntf-group-card.open>.ntf-head .ntf-car[data-v-69e0a1db],.ng-item.open>.ntf-head .ntf-car[data-v-69e0a1db]{transform:rotate(90deg)}.ntf-body-in[data-v-69e0a1db]{margin:0 var(--space-3) var(--space-3);padding-top:var(--space-3);border-top:.5px solid var(--color-line);display:flex;flex-direction:column;gap:var(--space-2)}.ntf.ok .ntf-body-in[data-v-69e0a1db],.ng-item.ok .ntf-body-in[data-v-69e0a1db]{border-top-color:var(--color-success-bd)}.ntf.err .ntf-body-in[data-v-69e0a1db],.ng-item.err .ntf-body-in[data-v-69e0a1db]{border-top-color:var(--color-danger-bd)}.ntf.warn .ntf-body-in[data-v-69e0a1db],.ng-item.warn .ntf-body-in[data-v-69e0a1db]{border-top-color:var(--color-warning-bd)}.nd-fields[data-v-69e0a1db]{display:grid;grid-template-columns:auto 1fr;gap:var(--space-1) var(--space-3)}.nd-fields .k[data-v-69e0a1db]{color:var(--color-text-faint);font-size:var(--text-xs)}.nd-fields .v[data-v-69e0a1db]{color:var(--color-text-muted);font-size:var(--text-xs);font-family:var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.nd-body[data-v-69e0a1db]{color:var(--color-text-muted);font-size:var(--text-sm);line-height:var(--leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.nd-out[data-v-69e0a1db]{display:flex;align-items:center;gap:var(--space-2);background:var(--color-surface-raised);border-radius:var(--radius-md);padding:var(--space-1) var(--space-2);box-shadow:var(--shadow-xs)}.nd-out-ic[data-v-69e0a1db]{color:var(--color-text-faint);flex:none}.nd-out .path[data-v-69e0a1db]{flex:1;min-width:0;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left}.nd-act[data-v-69e0a1db]{display:inline-flex;align-items:center;height:var(--space-6);padding:0 var(--space-2);border-radius:var(--radius-full);font-size:var(--text-xs);color:var(--color-text-muted);border:.5px solid var(--color-line-strong);background:var(--color-surface-raised);flex:none;transition:color var(--duration-fast) var(--ease-out)}.nd-act[data-v-69e0a1db]:hover{color:var(--color-text)}.nd-raw summary[data-v-69e0a1db]{list-style:none;display:flex;align-items:center;gap:var(--space-1);cursor:pointer;color:var(--color-text-faint);font-size:var(--text-xs);user-select:none}.nd-raw summary[data-v-69e0a1db]::-webkit-details-marker{display:none}.nd-raw summary[data-v-69e0a1db]:hover{color:var(--color-text)}.nd-raw-car[data-v-69e0a1db]{transition:transform var(--duration-base) var(--ease-out)}.nd-raw[open] .nd-raw-car[data-v-69e0a1db]{transform:rotate(90deg)}.nd-raw pre[data-v-69e0a1db]{margin:var(--space-2) 0 0;padding:var(--space-2) var(--space-3);background:var(--color-surface-raised);border-radius:var(--radius-sm);box-shadow:var(--shadow-xs);font-size:var(--text-xs);line-height:1.55;color:var(--color-text-muted);overflow-x:auto;white-space:pre}.ng-dots[data-v-69e0a1db]{display:inline-flex;gap:var(--space-1);margin-right:var(--space-1)}.dot[data-v-69e0a1db]{width:7px;height:7px;border-radius:50%;flex:none;background:var(--color-text-faint)}.dot.done[data-v-69e0a1db]{background:var(--color-success)}.dot.error[data-v-69e0a1db]{background:var(--color-danger)}.dot.warn[data-v-69e0a1db]{background:var(--color-warning)}.ng-list[data-v-69e0a1db]{display:flex;flex-direction:column}.ng-item[data-v-69e0a1db]{border-top:.5px solid var(--color-subtle)}.ng-item>.ntf-head[data-v-69e0a1db]{padding:var(--space-1) var(--space-3)}.ng-item .ntf-chip[data-v-69e0a1db]{width:22px;height:22px;border-radius:var(--radius-sm);box-shadow:none;background:transparent}.ng-item.ok .ntf-chip[data-v-69e0a1db]{color:var(--color-success)}.ng-item.err .ntf-chip[data-v-69e0a1db]{color:var(--color-danger)}.ng-item.warn .ntf-chip[data-v-69e0a1db]{color:var(--color-warning)}.ng-item .ntf-title[data-v-69e0a1db]{font-weight:var(--weight-regular);color:var(--color-text-muted)}.ng-item.open .ntf-title[data-v-69e0a1db]{color:var(--color-text)}.turn-fold[data-v-66797f5d]{display:flex;flex-direction:column}.tf-head[data-v-66797f5d]{display:flex;align-items:center;gap:var(--space-1);width:100%;padding:var(--space-2) 0;border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);line-height:1;text-align:left;cursor:pointer;user-select:none;transition:color var(--duration-base) var(--ease-out)}.tf-head[data-v-66797f5d]:hover{color:var(--color-text)}.tf-head[data-v-66797f5d]:focus-visible{outline:none;box-shadow:inset 0 0 0 2px var(--color-accent-soft)}.tf-sum[data-v-66797f5d]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-regular)}.tf-car[data-v-66797f5d]{color:var(--color-text-faint);flex:none;transition:transform var(--duration-base) var(--ease-out)}.turn-fold.open .tf-car[data-v-66797f5d]{transform:rotate(90deg)}.tf-body[data-v-66797f5d]{display:grid;grid-template-rows:minmax(0,0fr);overflow:hidden;transition:grid-template-rows var(--duration-base) var(--ease-out)}.tf-body.open[data-v-66797f5d]{grid-template-rows:minmax(0,1fr)}.tf-body-inner[data-v-66797f5d]{min-height:0;overflow:hidden;display:flex;flex-direction:column}.tf-body-inner>.msg[data-v-66797f5d],.tf-body-inner[data-v-66797f5d]>.think,.tf-body-inner[data-v-66797f5d]>.tool-group,.tf-body-inner[data-v-66797f5d]>.activity-run,.tf-body-inner[data-v-66797f5d]>.agent-card,.tf-body-inner[data-v-66797f5d]>.agent-group,.tf-body-inner[data-v-66797f5d]>.tool-line,.tf-body-inner[data-v-66797f5d]>.swarm-card,.tf-body-inner[data-v-66797f5d]>.media-tool,.tf-body-inner[data-v-66797f5d]>.ask-receipt{margin-top:var(--chat-block-gap)}.turn-fold.streaming .tf-body-inner>.msg[data-v-66797f5d]:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.think:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.tool-group:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.activity-run:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.agent-card:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.agent-group:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.tool-line:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.swarm-card:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.media-tool:first-child,.turn-fold.streaming .tf-body-inner[data-v-66797f5d]>.ask-receipt:first-child{margin-top:0}.tf-body-inner .msg[data-v-66797f5d]{font-size:var(--ui-font-size);line-height:var(--leading-prose);color:var(--color-text);font-weight:var(--weight-medium)}.tf-body-inner .msg[data-v-66797f5d] p{margin:0}.tf-body-inner .msg[data-v-66797f5d] p+p{margin-top:var(--space-2)}@container (min-width: 760px){.tf-body-inner .msg[data-v-66797f5d] .markstream-vue.markdown-renderer:has(.table-node-wrapper.md-table-wide){content-visibility:visible}.tf-body-inner .msg[data-v-66797f5d] .table-node-wrapper.md-table-wide{position:relative;left:50%;width:max-content;min-width:100%;max-width:min(var(--p-table-max),calc(100cqi - var(--space-5) - var(--space-5)))!important;transform:translate(-50%)}.tf-body-inner .msg[data-v-66797f5d] .table-node-wrapper:not(.md-table-wide){--table-cell-cap: min(var(--p-table-cell-max), 36cqi)}}@media(max-width:640px){.tf-body-inner .msg[data-v-66797f5d]{font-size:var(--ui-font-size-xl)}}.turn-files[data-v-f37da416]{margin-top:var(--chat-block-gap)}.turn-files[data-v-f37da416] .ui-card__head{font-family:var(--font-ui);font-weight:var(--weight-regular);padding:var(--space-2) var(--space-3)}.turn-files[data-v-f37da416] .ui-card__body{padding:var(--space-1) var(--space-3)}.turn-files[data-v-f37da416] .ui-card__foot{padding:0;justify-content:stretch}.tf-ic[data-v-f37da416]{display:inline-flex;align-items:center;color:var(--color-text-faint);flex:none}.tf-title[data-v-f37da416]{font-size:var(--text-sm);color:var(--color-text);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tf-stats[data-v-f37da416]{margin-left:auto;display:inline-flex;align-items:center;gap:var(--space-1);flex:none}.tf-add[data-v-f37da416],.tf-del[data-v-f37da416]{font-family:var(--font-mono);font-size:var(--text-xs);flex:none}.tf-add[data-v-f37da416]{color:var(--color-success)}.tf-del[data-v-f37da416]{color:var(--color-danger)}.tf-list[data-v-f37da416]{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.tf-row[data-v-f37da416]{display:flex;align-items:center;gap:var(--space-1);min-width:0;padding:var(--space-1) 0;font-size:var(--text-sm);line-height:var(--leading-tight)}.tf-file[data-v-f37da416]{display:flex;align-items:baseline;border:none;border-radius:var(--radius-xs);background:transparent;padding:0;font-family:inherit;font-size:inherit;color:var(--color-text);flex:1;min-width:0;overflow:hidden;white-space:nowrap;text-align:left}button.tf-file[data-v-f37da416]{cursor:pointer}button.tf-file[data-v-f37da416]:hover{text-decoration:underline;text-decoration-color:var(--color-text-faint);text-underline-offset:3px}.tf-file[data-v-f37da416]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.tf-dir[data-v-f37da416]{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;color:var(--color-text-faint)}.tf-base[data-v-f37da416]{flex:none;font-weight:var(--weight-medium);color:var(--color-text)}.tf-more[data-v-f37da416]{width:100%;justify-content:flex-start;border-radius:0}.turn-files .tf-more[data-v-f37da416]:not(:disabled):active{transform:none}.tf-more-car[data-v-f37da416]{color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.tf-more-car.open[data-v-f37da416]{transform:rotate(180deg)}.diffbar[data-v-f37da416]{display:inline-flex;width:36px;height:3px;border-radius:var(--radius-full);overflow:hidden;flex:none}.seg-add[data-v-f37da416]{background:var(--color-success)}.seg-del[data-v-f37da416]{background:var(--color-danger)}.activity-notice[data-v-cc29061f]{display:inline-flex;align-items:center;gap:9px;align-self:flex-start;margin:0;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text-muted)}.cn[data-v-9f79345d]{margin:0;align-self:flex-end;max-width:78%;display:flex;flex-direction:column;align-items:flex-end}.cn-head[data-v-9f79345d]{align-self:flex-end;display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal);overflow-wrap:anywhere}.cn-head-ico[data-v-9f79345d]{flex:none}.cn-head.error .cn-head-ico[data-v-9f79345d]{color:var(--color-danger)}.cn-bubble[data-v-9f79345d]{box-sizing:border-box;max-width:100%;padding:10px 12px;background:var(--color-user-bubble-bg);border-radius:var(--radius-lg);color:var(--color-text);font-size:var(--content-font-size);line-height:var(--leading-normal);white-space:pre-wrap;overflow-wrap:anywhere}.cn-meta[data-v-9f79345d]{margin-top:var(--space-1);padding:0 var(--space-1);color:var(--color-text-faint);font-size:var(--text-base);line-height:var(--leading-normal)}/*! PhotoSwipe main CSS by Dmytro Semenov | photoswipe.com */.pswp{--pswp-bg: #000;--pswp-placeholder-bg: #222;--pswp-root-z-index: 100000;--pswp-preloader-color: rgba(79, 79, 79, .4);--pswp-preloader-color-secondary: rgba(255, 255, 255, .9);--pswp-icon-color: #fff;--pswp-icon-color-secondary: #4f4f4f;--pswp-icon-stroke-color: #4f4f4f;--pswp-icon-stroke-width: 2px;--pswp-error-text-color: var(--pswp-icon-color)}.pswp{position:fixed;top:0;left:0;width:100%;height:100%;z-index:var(--pswp-root-z-index);display:none;touch-action:none;outline:0;opacity:.003;contain:layout style size;-webkit-tap-highlight-color:rgba(0,0,0,0)}.pswp:focus{outline:0}.pswp *{box-sizing:border-box}.pswp img{max-width:none}.pswp--open{display:block}.pswp,.pswp__bg{transform:translateZ(0);will-change:opacity}.pswp__bg{opacity:.005;background:var(--pswp-bg)}.pswp,.pswp__scroll-wrap{overflow:hidden}.pswp__scroll-wrap,.pswp__bg,.pswp__container,.pswp__item,.pswp__content,.pswp__img,.pswp__zoom-wrap{position:absolute;top:0;left:0;width:100%;height:100%}.pswp__img,.pswp__zoom-wrap{width:auto;height:auto}.pswp--click-to-zoom.pswp--zoom-allowed .pswp__img{cursor:-webkit-zoom-in;cursor:-moz-zoom-in;cursor:zoom-in}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab}.pswp--click-to-zoom.pswp--zoomed-in .pswp__img:active{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing}.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img,.pswp--no-mouse-drag.pswp--zoomed-in .pswp__img:active,.pswp__img{cursor:-webkit-zoom-out;cursor:-moz-zoom-out;cursor:zoom-out}.pswp__container,.pswp__img,.pswp__button,.pswp__counter{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.pswp__item{z-index:1;overflow:hidden}.pswp__hidden{display:none!important}.pswp__content{pointer-events:none}.pswp__content>*{pointer-events:auto}.pswp__error-msg-container{display:grid}.pswp__error-msg{margin:auto;font-size:1em;line-height:1;color:var(--pswp-error-text-color)}.pswp .pswp__hide-on-close{opacity:.005;will-change:opacity;transition:opacity var(--pswp-transition-duration) cubic-bezier(.4,0,.22,1);z-index:10;pointer-events:none}.pswp--ui-visible .pswp__hide-on-close{opacity:1;pointer-events:auto}.pswp__button{position:relative;display:block;width:50px;height:60px;padding:0;margin:0;overflow:hidden;cursor:pointer;background:none;border:0;box-shadow:none;opacity:.85;-webkit-appearance:none;-webkit-touch-callout:none}.pswp__button:hover,.pswp__button:active,.pswp__button:focus{transition:none;padding:0;background:none;border:0;box-shadow:none;opacity:1}.pswp__button:disabled{opacity:.3;cursor:auto}.pswp__icn{fill:var(--pswp-icon-color);color:var(--pswp-icon-color-secondary)}.pswp__icn{position:absolute;top:14px;left:9px;width:32px;height:32px;overflow:hidden;pointer-events:none}.pswp__icn-shadow{stroke:var(--pswp-icon-stroke-color);stroke-width:var(--pswp-icon-stroke-width);fill:none}.pswp__icn:focus{outline:0}div.pswp__img--placeholder,.pswp__img--with-bg{background:var(--pswp-placeholder-bg)}.pswp__top-bar{position:absolute;left:0;top:0;width:100%;height:60px;display:flex;flex-direction:row;justify-content:flex-end;z-index:10;pointer-events:none!important}.pswp__top-bar>*{pointer-events:auto;will-change:opacity}.pswp__button--close{margin-right:6px}.pswp__button--arrow{position:absolute;width:75px;height:100px;top:50%;margin-top:-50px}.pswp__button--arrow:disabled{display:none;cursor:default}.pswp__button--arrow .pswp__icn{top:50%;margin-top:-30px;width:60px;height:60px;background:none;border-radius:0}.pswp--one-slide .pswp__button--arrow{display:none}.pswp--touch .pswp__button--arrow{visibility:hidden}.pswp--has_mouse .pswp__button--arrow{visibility:visible}.pswp__button--arrow--prev{right:auto;left:0}.pswp__button--arrow--next{right:0}.pswp__button--arrow--next .pswp__icn{left:auto;right:14px;transform:scaleX(-1)}.pswp__button--zoom{display:none}.pswp--zoom-allowed .pswp__button--zoom{display:block}.pswp--zoomed-in .pswp__zoom-icn-bar-v{display:none}.pswp__preloader{position:relative;overflow:hidden;width:50px;height:60px;margin-right:auto}.pswp__preloader .pswp__icn{opacity:0;transition:opacity .2s linear;animation:pswp-clockwise .6s linear infinite}.pswp__preloader--active .pswp__icn{opacity:.85}@keyframes pswp-clockwise{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.pswp__counter{height:30px;margin-top:15px;margin-inline-start:20px;font-size:14px;line-height:30px;color:var(--pswp-icon-color);text-shadow:1px 1px 3px var(--pswp-icon-color-secondary);opacity:.85}.pswp--one-slide .pswp__counter{display:none}.pswp{--pswp-root-z-index: var(--z-modal);--pswp-bg: var(--color-scrim-strong)}.media-preview-caption{position:absolute;left:0;right:0;bottom:var(--space-4);padding:0 var(--space-6);color:var(--color-text-on-scrim);font-size:var(--ui-font-size-xs);text-align:center;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none}.media-lightbox[data-v-6c0c564d]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;padding:var(--space-6);background:var(--color-scrim-strong)}.media-lightbox-card[data-v-6c0c564d]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);max-width:min(960px,calc(100vw - var(--space-6) * 2));max-height:calc(100vh - var(--space-6) * 2)}.media-lightbox-frame[data-v-6c0c564d]{max-width:100%;border-radius:var(--radius-md);overflow:hidden;background:var(--color-bg);box-shadow:var(--shadow-xl)}.media-lightbox-media[data-v-6c0c564d]{display:block;max-width:100%;max-height:calc(100vh - var(--space-6) * 4);object-fit:contain}.media-lightbox-name[data-v-6c0c564d]{max-width:100%;color:var(--color-text-on-scrim);font-size:var(--ui-font-size-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.media-lightbox-close[data-v-6c0c564d]{position:fixed;top:var(--space-4);right:var(--space-6);display:flex;align-items:center;justify-content:center;width:36px;height:36px;padding:0;border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-surface-raised);color:var(--color-text);box-shadow:var(--shadow-sm);cursor:pointer;z-index:var(--z-modal-dropdown)}.media-lightbox-close[data-v-6c0c564d]:before{content:"";position:absolute;inset:-6px}.media-lightbox-close[data-v-6c0c564d]:hover{border-color:var(--color-line-strong);background:var(--color-surface-sunken)}.media-thumb[data-v-a7ab7e98]{position:relative;flex:none;display:inline-flex}.media-thumb-btn[data-v-a7ab7e98]{display:block;padding:0;border:.5px solid var(--color-line);border-radius:var(--radius-md);background:var(--color-well);overflow:hidden;cursor:pointer;transition:border-color var(--duration-fast) ease}.media-thumb-btn[data-v-a7ab7e98]:hover{border-color:var(--color-line-strong)}.media-thumb-btn[data-v-a7ab7e98]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.media-thumb-media[data-v-a7ab7e98]{display:block;width:64px;height:64px;object-fit:cover}.media-thumb-tile[data-v-a7ab7e98]{object-fit:none}.media-thumb-badge[data-v-a7ab7e98]{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:flex;align-items:center;justify-content:center;width:22px;height:22px;border-radius:var(--radius-full);background:var(--color-surface-raised);border:.5px solid var(--color-line);color:var(--color-text);box-shadow:var(--shadow-sm);pointer-events:none}.media-thumb-badge.is-error[data-v-a7ab7e98]{color:var(--color-danger);border-color:var(--color-danger-bd)}.media-thumb.is-error .media-thumb-btn[data-v-a7ab7e98]{border-color:var(--color-danger-bd)}.media-thumb-rm[data-v-a7ab7e98]{position:absolute;top:var(--space-1);right:var(--space-1);z-index:1;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:var(--color-scrim);color:var(--color-text-on-scrim);cursor:pointer}.media-thumb-rm[data-v-a7ab7e98]:hover{background:var(--color-text);color:var(--color-bg)}.media-thumb-rm[data-v-a7ab7e98]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.att-chip[data-v-9af3d603]{display:inline-flex;align-items:center;gap:6px;max-width:220px;padding:4px 9px 4px 5px;background:var(--color-well);border:.5px solid var(--color-line);border-radius:999px;font-size:var(--ui-font-size-sm);transition:border-color var(--duration-fast) ease}.att-chip[data-v-9af3d603]:hover{border-color:var(--color-line-strong)}.att-activate[data-v-9af3d603]{display:inline-flex;align-items:center;gap:6px;min-width:0;padding:0;border:none;background:transparent;color:inherit;font:inherit;cursor:pointer}.att-activate[data-v-9af3d603]:focus-visible{outline:none;box-shadow:var(--p-focus-ring);border-radius:999px}.att-tile[data-v-9af3d603]{width:20px;height:20px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;overflow:hidden;color:var(--color-text-muted);background:var(--color-surface-sunken)}.att-tile[data-v-9af3d603] .att-thumb{width:100%;height:100%;object-fit:cover;display:block}.att-name[data-v-9af3d603]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text);font-weight:var(--weight-medium)}.att-chip.is-error[data-v-9af3d603]{border-color:var(--color-danger-bd)}.att-chip.is-error .att-err[data-v-9af3d603]{flex:none;display:flex;align-items:center;color:var(--color-danger)}.att-rm[data-v-9af3d603]{flex:none;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:50%;background:transparent;color:var(--color-text-faint);cursor:pointer}.att-rm[data-v-9af3d603]:hover{background:var(--color-hover);color:var(--color-text)}.att-rm[data-v-9af3d603]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.mascot-host[data-v-75a5cb70]{position:relative;width:100%;aspect-ratio:72 / 100}.mascot-fallback[data-v-75a5cb70]{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);display:block;width:86.5%;height:auto}.mascot-canvas[data-v-75a5cb70]{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .25s ease}.mascot-canvas.ready[data-v-75a5cb70]{opacity:1}@media(prefers-reduced-motion:reduce){.mascot-canvas[data-v-75a5cb70]{transition:none}}.working-indicator[data-v-8abb44ef]{display:inline-flex;align-items:center;gap:var(--space-2);align-self:flex-start;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text-muted)}.wi-mascot[data-v-8abb44ef]{flex:none;width:40px}.wi-label[data-v-8abb44ef]{animation:wi-breathe-8abb44ef 1.6s var(--ease-in-out) infinite}@keyframes wi-breathe-8abb44ef{0%,to{opacity:1}50%{opacity:.45}}.chat-empty[data-v-7797947d]{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:24px 16px;color:var(--faint);text-align:center}.chat-empty-text[data-v-7797947d]{font-size:var(--ui-font-size-sm)}.chat-loading[data-v-7797947d]{flex:1;display:flex;align-items:center;justify-content:center;gap:8px;padding:24px 16px;color:var(--muted)}.chat-loading-text[data-v-7797947d]{font-size:var(--ui-font-size-sm)}.chat[data-v-7797947d]{--chat-turn-gap: 16px;--chat-block-gap: 10px;--chat-section-gap: 18px;display:flex;flex-direction:column;gap:0;padding:16px 14px 20px;flex:1;min-height:0;position:relative}.chat .chat-empty[data-v-7797947d]{align-self:stretch}.open-unsupported[data-v-7797947d]{position:absolute;bottom:16px;left:50%;transform:translate(-50%);max-width:min(90%,480px);padding:6px 12px;border-radius:var(--radius-md);border:.5px solid var(--color-line);background:var(--color-surface-raised);color:var(--color-text-muted);font-size:var(--ui-font-size-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;pointer-events:none;z-index:var(--z-sticky)}.chat>.u-turn[data-v-7797947d],.chat>.a-msg[data-v-7797947d],.chat>.compact-divider[data-v-7797947d],.chat>.cron-notice[data-v-7797947d],.chat>.sending-placeholder[data-v-7797947d],.chat[data-v-7797947d]>.activity-notice{margin-top:var(--chat-turn-gap)}.chat>.a-msg[data-v-7797947d]{margin-top:10px}.chat>.u-turn[data-v-7797947d]:first-child,.chat>.a-msg[data-v-7797947d]:first-child,.chat>.compact-divider[data-v-7797947d]:first-child,.chat>.cron-notice[data-v-7797947d]:first-child,.chat>.sending-placeholder[data-v-7797947d]:first-child,.chat[data-v-7797947d]>.activity-notice:first-child{margin-top:0}.u-turn[data-v-7797947d]{display:flex;flex-direction:column;align-items:flex-end;align-self:flex-start;width:100%}.u-bub[data-v-7797947d]{align-self:flex-end;max-width:78%;background:var(--color-user-bubble-bg);color:var(--color-text);border-radius:var(--radius-lg);padding:10px 12px;font-size:var(--content-font-size);line-height:var(--leading-normal)}.u-meta[data-v-7797947d]{align-self:flex-end;display:flex;justify-content:flex-end;align-items:center;max-width:78%;margin-top:var(--space-2);margin-right:4px}.u-meta .u-edit[data-v-7797947d]{min-height:22px;box-sizing:border-box}.u-text[data-v-7797947d]{white-space:pre-wrap;overflow-wrap:anywhere}.u-text-wrap[data-v-7797947d]{position:relative;display:flex;flex-direction:column}.u-text-wrap-args[data-v-7797947d]{margin-top:var(--space-1)}.u-text-wrap.is-clamped[data-v-7797947d]{min-width:120px}.u-text-wrap.is-clamped>.u-text[data-v-7797947d],.u-text-wrap.is-clamped>.skill-act-args[data-v-7797947d],.u-text-wrap.is-clamped>.q-body[data-v-7797947d]{max-height:10lh;overflow:hidden;mask-image:linear-gradient(to bottom,black calc(100% - 5lh),transparent calc(100% - 1lh));-webkit-mask-image:linear-gradient(to bottom,black calc(100% - 5lh),transparent calc(100% - 1lh))}.u-text-toggle[data-v-7797947d]{display:inline-flex;align-items:center;gap:var(--space-1);align-self:center;margin-top:var(--space-2);padding:var(--space-2) var(--space-4);border:none;border-radius:var(--radius-full);background:var(--color-surface-raised);box-shadow:var(--shadow-sm);color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size-sm);line-height:1;cursor:pointer;user-select:none;transition:box-shadow var(--duration-base) var(--ease-out)}.u-text-toggle[data-v-7797947d]:hover{box-shadow:var(--shadow-md)}.u-text-toggle[data-v-7797947d]:focus-visible{outline:2px solid var(--color-accent);outline-offset:1px}.u-text-wrap.is-clamped .u-text-toggle[data-v-7797947d]{position:absolute;bottom:0;left:50%;transform:translate(-50%);margin-top:0}.u-text-toggle-car[data-v-7797947d]{transition:transform var(--duration-base) var(--ease-out)}.u-text-toggle[aria-expanded=true] .u-text-toggle-car[data-v-7797947d]{transform:rotate(180deg)}.u-edit[data-v-7797947d]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s}.u-edit svg[data-v-7797947d]{display:block;flex:none}.u-edit[data-v-7797947d]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.u-edit-armed[data-v-7797947d]{--undo-hint-duration: 5s;gap:var(--space-1);opacity:1;color:var(--color-text);animation:u-edit-armed-blink-7797947d var(--undo-hint-duration) linear forwards}.u-edit-armed[data-v-7797947d]:hover{color:var(--color-accent);background:var(--hover)}.u-edit-hint[data-v-7797947d]{display:inline-flex;align-items:center;gap:var(--space-1);font-size:var(--text-xs);font-weight:var(--weight-medium);white-space:nowrap}@keyframes u-edit-armed-blink-7797947d{0%,55%{opacity:1}62%{opacity:.45}69%{opacity:1}75%{opacity:.4}81%{opacity:.95}86%{opacity:.35}91%{opacity:.85}95%{opacity:.3}to{opacity:0}}@media(prefers-reduced-motion:reduce){.u-edit-armed[data-v-7797947d]{animation:none}}.u-copy[data-v-7797947d]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s;min-height:22px;box-sizing:border-box}.u-copy svg[data-v-7797947d]{display:block;flex:none}.u-copy[data-v-7797947d]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.u-edit-wrap[data-v-7797947d]{display:flex;justify-content:flex-end}.chat>.u-edit-wrap[data-v-7797947d]{margin-top:4px}.chat>.u-edit-wrap+.a-msg[data-v-7797947d]{margin-top:8px}.compact-divider[data-v-7797947d]{display:flex;align-items:center;gap:10px;align-self:stretch;width:100%;margin:var(--chat-section-gap) 0 0}.chat>.compact-divider[data-v-7797947d]:first-child{margin-top:0}.cd-line[data-v-7797947d]{flex:1;height:1px;background:var(--line)}.cd-label[data-v-7797947d]{flex:none;display:inline-flex;align-items:center;gap:8px;max-width:80%;font-size:var(--text-base);color:var(--muted);white-space:nowrap}.cd-btn[data-v-7797947d]{background:none;border:none;padding:0;cursor:pointer;font:inherit;font-size:var(--text-base);color:var(--muted)}.cd-view[data-v-7797947d]{color:var(--color-accent)}.cd-btn:hover .cd-view[data-v-7797947d]{text-decoration:underline}.chat>.turn-failed[data-v-7797947d]{margin-top:var(--chat-turn-gap)}.chat>.turn-failed[data-v-7797947d]:first-child{margin-top:0}.turn-failed[data-v-7797947d]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border:var(--p-hairline) solid var(--color-danger-bd);border-radius:var(--radius-lg);background:var(--color-danger-soft);box-shadow:var(--shadow-xs);animation:kimi-card-in var(--duration-slow) var(--ease-out)}.tf-chip[data-v-7797947d]{display:inline-flex;align-items:center;justify-content:center;width:var(--space-6);height:var(--space-6);border-radius:var(--radius-md);background:var(--color-surface-raised);box-shadow:var(--shadow-xs);flex:none;color:var(--color-danger)}.tf-main[data-v-7797947d]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.tf-title[data-v-7797947d]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-normal)}.tf-sub[data-v-7797947d]{font-size:var(--text-xs);color:var(--color-text-muted);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tf-meta[data-v-7797947d]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint);line-height:var(--leading-normal);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.goal-prov[data-v-7797947d]{display:flex;align-items:center;gap:var(--space-1);margin-bottom:var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);line-height:var(--leading-normal);user-select:none}.a-msg[data-v-7797947d]{align-self:flex-start;max-width:94%;width:94%}.a-msg-ft[data-v-7797947d]{display:flex;justify-content:flex-start;align-items:center;gap:8px;height:auto;margin-top:var(--chat-block-gap);overflow:visible}.a-duration[data-v-7797947d]{display:inline-flex;align-items:center;font-size:var(--text-base);color:var(--muted);line-height:1}.a-cpbtn[data-v-7797947d]{display:inline-flex;align-items:center;justify-content:center;padding:2px 5px;background:none;border:none;border-radius:var(--radius-sm);color:var(--muted);font:inherit;font-size:var(--text-base);line-height:1;cursor:pointer;opacity:.7;transition:opacity .12s,color .12s,background-color .12s;min-height:22px;box-sizing:border-box}.a-cpbtn[data-v-7797947d]:hover{opacity:1;color:var(--color-accent);background:var(--hover)}.a-cpbtn svg[data-v-7797947d]{display:block;flex:none}@media(hover:none){.a-msg-ft[data-v-7797947d]{height:auto;margin-top:var(--chat-block-gap);opacity:1;pointer-events:auto}.a-cpbtn[data-v-7797947d]{font-size:var(--ui-font-size-sm);padding:8px 10px;margin:-4px -6px}}.a-msg .msg[data-v-7797947d]{font-size:var(--ui-font-size);line-height:var(--leading-prose);color:var(--color-text);font-weight:500}.a-msg .msg[data-v-7797947d] p{margin:0}.a-msg .msg[data-v-7797947d] p+p{margin-top:8px}.a-msg>.msg[data-v-7797947d],.a-msg[data-v-7797947d]>.think,.a-msg[data-v-7797947d]>.tool-group,.a-msg[data-v-7797947d]>.activity-run,.a-msg[data-v-7797947d]>.agent-card,.a-msg[data-v-7797947d]>.agent-group,.a-msg[data-v-7797947d]>.tool-line,.a-msg[data-v-7797947d]>.swarm-card,.a-msg[data-v-7797947d]>.media-tool,.a-msg[data-v-7797947d]>.ask-receipt{margin-top:var(--chat-block-gap)}.a-msg>.msg[data-v-7797947d]:first-child,.a-msg[data-v-7797947d]>.think:first-child,.a-msg[data-v-7797947d]>.tool-group:first-child,.a-msg[data-v-7797947d]>.activity-run:first-child,.a-msg[data-v-7797947d]>.agent-card:first-child,.a-msg[data-v-7797947d]>.agent-group:first-child,.a-msg[data-v-7797947d]>.tool-line:first-child,.a-msg[data-v-7797947d]>.swarm-card:first-child,.a-msg[data-v-7797947d]>.media-tool:first-child,.a-msg[data-v-7797947d]>.ask-receipt:first-child{margin-top:0}.a-msg>.goal-prov:first-child+.msg[data-v-7797947d],.a-msg>.goal-prov[data-v-7797947d]:first-child+.think,.a-msg>.goal-prov[data-v-7797947d]:first-child+.tool-group,.a-msg>.goal-prov[data-v-7797947d]:first-child+.activity-run,.a-msg>.goal-prov[data-v-7797947d]:first-child+.agent-card,.a-msg>.goal-prov[data-v-7797947d]:first-child+.agent-group,.a-msg>.goal-prov[data-v-7797947d]:first-child+.tool-line,.a-msg>.goal-prov[data-v-7797947d]:first-child+.swarm-card,.a-msg>.goal-prov[data-v-7797947d]:first-child+.media-tool,.a-msg>.goal-prov[data-v-7797947d]:first-child+.ask-receipt,.a-msg>.goal-prov[data-v-7797947d]:first-child+.turn-fold{margin-top:0}.a-msg[data-v-7797947d] :not(pre)>code{font:.9em var(--font-mono);background:var(--color-inline-code-bg);border:.5px solid var(--color-line);border-radius:var(--radius-sm);padding:1px 6px;color:var(--color-accent-hover)}@container (min-width: 760px){.a-msg .msg[data-v-7797947d] .markstream-vue.markdown-renderer:has(.table-node-wrapper.md-table-wide){content-visibility:visible}.a-msg .msg[data-v-7797947d] .table-node-wrapper.md-table-wide{position:relative;left:50%;width:max-content;min-width:100%;max-width:min(var(--p-table-max),calc(100cqi - var(--space-5) - var(--space-5)))!important;transform:translate(-50%)}.a-msg .msg[data-v-7797947d] .table-node-wrapper:not(.md-table-wide){--table-cell-cap: min(var(--p-table-cell-max), 36cqi)}}.u-media[data-v-7797947d]{display:flex;flex-wrap:wrap;gap:var(--space-2)}.u-media[data-v-7797947d]:not(:last-child){margin-bottom:var(--space-2)}.u-atts[data-v-7797947d]{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px}.sending-placeholder[data-v-7797947d]{align-self:flex-start;padding:10px 0}.skill-act[data-v-7797947d]{display:flex;flex-direction:column;gap:2px}.skill-act-head[data-v-7797947d]{font-size:var(--ui-font-size-sm);font-weight:500;color:var(--color-accent-hover);display:flex;align-items:center;gap:6px}.skill-act-arrow[data-v-7797947d]{color:var(--color-accent);font-size:var(--text-base)}.skill-act-args[data-v-7797947d]{font-size:var(--text-base);color:var(--muted);padding-left:17px;white-space:pre-wrap;overflow-wrap:anywhere}@media(max-width:640px){.chat[data-v-7797947d]{box-sizing:border-box;width:100%;padding:14px max(12px,var(--safe-right)) 18px max(12px,var(--safe-left))}.u-bub[data-v-7797947d]{max-width:min(88%,calc(100vw - 52px))}.a-msg[data-v-7797947d]{width:100%;max-width:100%}.u-bub .u-text[data-v-7797947d],.a-msg .msg[data-v-7797947d]{font-size:var(--ui-font-size-xl)}.a-msg[data-v-7797947d] .md,.a-msg[data-v-7797947d] .markdown-renderer,.a-msg[data-v-7797947d] .code-block-container,.a-msg[data-v-7797947d] .diff-wrap,.a-msg[data-v-7797947d] pre{max-width:100%}.a-msg[data-v-7797947d] .code-block-container pre,.a-msg[data-v-7797947d] .diff-pre{overflow-x:auto;-webkit-overflow-scrolling:touch}.a-msg[data-v-7797947d] .media-tool.mob{width:min(44vw,160px)}.cd-label[data-v-7797947d]{min-width:0;max-width:calc(100% - 48px);overflow:hidden;text-overflow:ellipsis}.u-edit-confirm[data-v-7797947d]{flex-wrap:wrap;justify-content:flex-end;max-width:calc(100vw - 28px)}.ts[data-v-7797947d]{font-size:var(--ui-font-size-sm)}.chat-empty-text[data-v-7797947d],.chat-loading-text[data-v-7797947d]{font-size:var(--ui-font-size-lg)}.cd-label[data-v-7797947d],.cd-btn[data-v-7797947d]{font-size:var(--ui-font-size)}}.top-sentinel[data-v-7797947d]{display:flex;align-items:center;justify-content:center;padding:12px 0;min-height:28px;user-select:none}.top-sentinel-loading[data-v-7797947d]{opacity:.8}.top-sentinel-btn[data-v-7797947d]{appearance:none;border:.5px solid var(--border);background:transparent;color:var(--muted);font-size:var(--ui-font-size-sm);padding:4px 12px;border-radius:999px;cursor:pointer;transition:color .15s ease,border-color .15s ease}.top-sentinel-btn[data-v-7797947d]:hover{color:var(--fg);border-color:var(--fg)}.top-sentinel-text[data-v-7797947d]{display:inline-flex;align-items:center;gap:8px;color:var(--muted);font-size:var(--ui-font-size-sm)}.chat[data-v-7797947d]{background:transparent}.chat[data-v-7797947d]{gap:0;padding:22px 20px 26px}.u-bub[data-v-7797947d]{background:var(--color-user-bubble-bg);border-radius:var(--radius-lg);padding:10px 12px}.a-msg[data-v-7797947d]{max-width:100%;width:100%}.chat>.q-stack[data-v-7797947d]{margin-top:var(--chat-turn-gap)}.chat>.q-stack[data-v-7797947d]:first-child{margin-top:0}.q-stack[data-v-7797947d]{align-self:flex-end;width:100%;display:flex;flex-direction:column;gap:8px}.q-head[data-v-7797947d]{display:flex;align-items:center;justify-content:flex-end;gap:8px;padding:0 6px;color:var(--color-text-faint);font-size:var(--ui-font-size-xs)}.q-title[data-v-7797947d]{display:inline-flex;align-items:center;gap:6px}.q-title b[data-v-7797947d]{color:var(--color-accent-hover);font-weight:var(--weight-medium)}.q-hint[data-v-7797947d]{color:var(--color-text-faint)}.q-turn[data-v-7797947d]{position:relative}.q-bub[data-v-7797947d]{display:flex;align-items:center;gap:8px;width:fit-content;background:var(--color-surface-raised);border:.5px dashed var(--color-accent-bd);padding:8px 8px 8px 6px;transition:border-color .12s ease,background .12s ease}.q-bub[data-v-7797947d]:hover{border-color:var(--color-accent);background:var(--color-accent-soft)}.q-grip[data-v-7797947d]{flex:none;display:inline-flex;align-items:center;padding:2px;color:var(--color-text-faint);cursor:grab;opacity:.7}.q-grip[data-v-7797947d]:hover{opacity:1}.q-grip[data-v-7797947d]:active{cursor:grabbing}.q-clamp[data-v-7797947d]{flex:1;min-width:0}.q-body[data-v-7797947d]{flex:1;min-width:0;background:none;border:none;padding:0;margin:0;font:inherit;color:var(--color-text);text-align:left;cursor:pointer;opacity:.82}.q-bub:hover .q-body[data-v-7797947d]{opacity:1}.q-body[data-v-7797947d]:disabled{cursor:default}.q-text[data-v-7797947d]{white-space:pre-wrap;overflow-wrap:anywhere}.q-text-placeholder[data-v-7797947d]{display:inline-flex;align-items:center;gap:4px;color:var(--color-text-muted)}.q-imgs[data-v-7797947d]{display:flex;gap:4px;flex:none}.q-img[data-v-7797947d]{width:28px;height:28px;object-fit:cover;border-radius:var(--radius-sm);border:.5px solid var(--color-line)}.q-file[data-v-7797947d]{display:inline-flex;align-items:center;gap:4px;height:28px;padding:0 6px;border-radius:var(--radius-sm);border:.5px solid var(--color-line);color:var(--color-text-muted);font-size:calc(var(--ui-font-size) - 3px);max-width:160px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.q-tag[data-v-7797947d]{flex:none;padding:1px 6px;border-radius:var(--radius-full);font-size:var(--ui-font-size-xs);font-weight:var(--weight-medium);line-height:1.4;white-space:nowrap}.q-tag-next[data-v-7797947d]{color:var(--color-accent-hover);background:var(--color-accent-soft);border:.5px solid var(--color-accent-bd)}.q-tag-idx[data-v-7797947d]{color:var(--color-text-faint);background:var(--color-surface-sunken);border:.5px solid var(--color-line)}.q-rm[data-v-7797947d]{flex:none;width:22px;height:22px;display:inline-flex;align-items:center;justify-content:center;background:none;border:none;border-radius:var(--radius-sm);color:var(--color-text-faint);cursor:pointer;opacity:0;transition:opacity .12s ease,background .12s ease,color .12s ease}.q-bub:hover .q-rm[data-v-7797947d],.q-bub:focus-within .q-rm[data-v-7797947d],.q-rm[data-v-7797947d]:focus-visible{opacity:1}.q-rm[data-v-7797947d]:hover{background:var(--color-danger-soft);color:var(--color-danger)}.q-turn.q-dragging .q-bub[data-v-7797947d]{opacity:.45}.q-turn.drop-before[data-v-7797947d]:before,.q-turn.drop-after[data-v-7797947d]:after{content:"";position:absolute;left:0;right:0;height:2px;background:var(--color-accent);border-radius:var(--radius-full);z-index:1}.q-turn.drop-before[data-v-7797947d]:before{top:-5px}.q-turn.drop-after[data-v-7797947d]:after{bottom:-5px}.chat-header[data-v-cac58d83]{flex:none;display:flex;align-items:center;gap:14px;height:var(--panel-head-h, 48px);padding:0 16px;border-bottom:.5px solid var(--color-line);background:var(--color-bg);font-family:var(--font-ui);min-width:0;user-select:none;container-type:inline-size}.chat-header.macos-desktop[data-v-cac58d83]{-webkit-app-region:drag}.chat-header.macos-desktop button[data-v-cac58d83],.chat-header.macos-desktop input[data-v-cac58d83]{-webkit-app-region:no-drag}.ch-id[data-v-cac58d83]{display:flex;align-items:center;gap:6px;min-width:0;flex:none;max-width:46%}.ch-ws[data-v-cac58d83]{color:var(--color-text-muted);font-size:var(--text-base);font-weight:var(--weight-medium);flex:none}.ch-sep[data-v-cac58d83]{color:var(--color-text-faint);flex:none}.ch-ses[data-v-cac58d83]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ch-rename[data-v-cac58d83]{flex:1;min-width:0;font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);background:var(--color-bg);border:.5px solid var(--color-accent);border-radius:var(--radius-xs);padding:2px 5px;outline:none;user-select:text}.ch-git[data-v-cac58d83]{display:flex;align-items:center;gap:4px;border:none;background:transparent;padding:0;color:var(--muted);font-family:var(--font-ui);font-size:calc(var(--ui-font-size) - 2px);flex:0 1 auto;max-width:none;min-width:0;cursor:pointer}.ch-git:hover .ch-branch[data-v-cac58d83]{color:var(--color-text)}.ch-branch-icon[data-v-cac58d83]{flex:none;color:var(--color-text-muted)}.ch-branch[data-v-cac58d83]{color:var(--dim);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-right:4px}.ch-detached[data-v-cac58d83]{color:var(--muted);font-style:italic}.ch-pill[data-v-cac58d83]{display:inline-flex;align-items:center;gap:3px;padding:1px 5px;border-radius:999px;background:var(--panel);border:.5px solid var(--line);font-size:calc(var(--ui-font-size) - 3px)}.ch-sync-pill[data-v-cac58d83]{border-color:var(--line)}.ch-diff-pill[data-v-cac58d83]{border-color:color-mix(in srgb,var(--color-success) 20%,var(--line));font-variant-numeric:tabular-nums}.ch-ahead[data-v-cac58d83]{color:var(--color-warning);flex:none}.ch-behind[data-v-cac58d83]{color:var(--color-accent-hover);flex:none}.ch-add[data-v-cac58d83]{color:var(--color-success);flex:none}.ch-del[data-v-cac58d83]{color:var(--color-danger);flex:none}.ch-spacer[data-v-cac58d83]{flex:1;min-width:0}@container (max-width: 720px){.ch-ws[data-v-cac58d83],.ch-sep[data-v-cac58d83]{display:none}.ch-id[data-v-cac58d83]{flex:1;max-width:none}.ch-spacer[data-v-cac58d83]{flex:0}}.chat-header .ch-act-more[data-v-cac58d83]{width:24px;height:24px;border-radius:var(--radius-sm)}.chat-header .ch-act-more[data-v-cac58d83] svg{width:14px;height:14px}.ch-act-more.open[data-v-cac58d83]{background:var(--color-well);color:var(--color-text)}.ch-dev[data-v-cac58d83]{display:inline-flex;align-items:center;height:22px;padding:0 9px;flex:none;border:.5px solid var(--color-warning-bd);border-radius:var(--radius-full);background:var(--color-warning-soft);color:var(--color-warning);font-size:var(--text-xs);font-weight:500}.ch-pr[data-v-cac58d83]{display:inline-flex;align-items:center;gap:4px;height:22px;padding:0 9px;flex:none;border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-well);color:var(--color-text-muted);font-size:var(--text-xs);font-weight:500;cursor:pointer}.ch-pr svg[data-v-cac58d83]{flex:none}.ch-pr.pr-open[data-v-cac58d83]{color:var(--color-success);border-color:var(--color-success-bd);background:var(--color-success-soft)}.ch-pr.pr-merged[data-v-cac58d83]{color:var(--color-done);border-color:var(--color-done-bd);background:var(--color-done-soft)}.ch-pr.pr-closed[data-v-cac58d83]{color:var(--color-danger);border-color:var(--color-danger-bd);background:var(--color-danger-soft)}.ch-pr.pr-draft[data-v-cac58d83],.ch-pr.pr-unknown[data-v-cac58d83]{color:var(--color-text-muted);border-color:var(--color-line-strong);background:var(--color-well)}.ch-pr[data-v-cac58d83]:hover{border-color:var(--color-line-strong)}.ch-menu[data-v-cac58d83]{position:fixed;top:0;left:0;z-index:var(--z-dropdown)}.menu-pop-enter-active[data-v-cac58d83]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.menu-pop-leave-active[data-v-cac58d83]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.menu-pop-enter-from[data-v-cac58d83],.menu-pop-leave-to[data-v-cac58d83]{opacity:0;transform:scale(.97) translateY(var(--menu-pop-shift, -2px))}@media(max-width:980px){.ch-act-label[data-v-cac58d83]{display:none}}@media(max-width:640px){.chat-header[data-v-cac58d83]{display:none}}.slash-menu[role=listbox][data-v-ca6fa882]{position:absolute;bottom:calc(100% + 4px);left:0;right:0;padding:var(--space-1);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);z-index:var(--z-dropdown);max-height:240px;overflow-y:auto}.slash-item[data-v-ca6fa882]{display:grid;grid-template-columns:minmax(90px,32%) minmax(0,1fr);align-items:start;gap:10px;padding:6px 10px;cursor:pointer;font-family:var(--font-ui);font-size:var(--ui-b2);border-radius:var(--radius-sm)}.slash-item[data-v-ca6fa882]:hover,.slash-item.active[data-v-ca6fa882]{background:var(--color-hover)}.slash-item.active .slash-name[data-v-ca6fa882]{color:var(--color-text)}.slash-name[data-v-ca6fa882]{color:var(--color-accent);font-weight:500;min-width:0;line-height:var(--leading-normal);overflow-wrap:anywhere}.slash-desc[data-v-ca6fa882]{color:var(--color-text-muted);font-size:var(--text-xs);min-width:0;line-height:var(--leading-normal);overflow-wrap:anywhere}@media(max-width:520px){.slash-item[data-v-ca6fa882]{grid-template-columns:minmax(0,1fr);gap:2px}}.slash-menu[data-v-ca6fa882]{border-radius:var(--radius-lg);box-shadow:var(--sh)}.slash-desc[data-v-ca6fa882]{font-family:var(--sans)}.mention-menu[role=listbox][data-v-181f2289]{position:absolute;bottom:calc(100% + 4px);left:0;right:0;padding:var(--space-1);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);z-index:var(--z-dropdown);max-height:220px;overflow-y:auto}.mention-state[data-v-181f2289]{padding:8px 12px;font-family:var(--font-ui);font-size:var(--ui-b2)}.dim[data-v-181f2289]{color:var(--color-text-muted)}.mention-item[data-v-181f2289]{display:flex;align-items:center;gap:8px;padding:6px 10px;cursor:pointer;font-family:var(--font-ui);font-size:var(--ui-b2);border-radius:var(--radius-sm)}.mention-icon[data-v-181f2289]{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;color:var(--muted);flex-shrink:0}.mention-icon[data-v-181f2289] svg{width:13px;height:13px;display:block}.mention-item:hover .mention-icon[data-v-181f2289],.mention-item.active .mention-icon[data-v-181f2289]{color:var(--color-text-strong)}.mention-item[data-v-181f2289]:hover{background:var(--color-hover)}.mention-item:hover .mention-name[data-v-181f2289],.mention-item.active .mention-name[data-v-181f2289]{color:var(--color-text-strong)}.mention-item.active[data-v-181f2289]{background:var(--color-hover)}.mention-name[data-v-181f2289]{color:var(--color-text);font-weight:500;min-width:80px;flex-shrink:0}.mention-path[data-v-181f2289]{color:var(--color-text-muted);font-size:var(--text-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mention-menu[data-v-181f2289]{border-radius:var(--radius-lg);box-shadow:var(--sh)}.mention-state[data-v-181f2289]{font-family:var(--sans)}.composer[data-v-81ce0c45]{padding:7px var(--dock-inline-right, 16px) 12px var(--dock-inline-left, 16px);background:transparent;transition:background .12s}.composer.drag-over[data-v-81ce0c45]{background:var(--color-accent-soft)}.drop-overlay[data-v-81ce0c45]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;align-items:center;justify-content:center;background:color-mix(in srgb,var(--color-bg) 72%,transparent);pointer-events:none;opacity:0;visibility:hidden;transition:opacity var(--duration-base) ease,visibility var(--duration-base)}.drop-overlay.show[data-v-81ce0c45]{opacity:1;visibility:visible}.drop-card[data-v-81ce0c45]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4) var(--space-6);border-radius:var(--radius-lg);border:.5px dashed var(--color-accent);background:var(--color-bg);color:var(--color-accent);font-size:var(--ui-font-size-lg);font-weight:var(--weight-medium);box-shadow:var(--shadow-md)}.composer-card[data-v-81ce0c45]{--composer-control-size: var(--space-8);--composer-send-size: var(--composer-control-size);--composer-control-inset: var(--space-2);position:relative;border:.5px solid var(--color-composer-line);border-radius:var(--radius-composer);corner-shape:var(--corner-shape-composer);background:var(--color-composer-bg);box-shadow:var(--shadow-input);user-select:none;container-type:inline-size}.composer-card[data-v-81ce0c45]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--color-composer-focus-line);border-radius:var(--radius-composer);corner-shape:var(--corner-shape-composer);opacity:0;pointer-events:none;transition:opacity var(--duration-slow) var(--ease-in-out)}.composer-card[data-v-81ce0c45]:focus-within:after{opacity:1}.att-strip[data-v-81ce0c45]{position:relative;padding:var(--space-3) var(--space-4) 0}.att-scroll[data-v-81ce0c45]{max-height:calc(128px + var(--space-2));overflow-y:auto;margin-right:calc(var(--icon-button-sm) + var(--space-1))}.att-scroll-content[data-v-81ce0c45]{display:flex;flex-direction:column;gap:var(--space-2);padding-right:var(--space-1)}.att-scroll.is-overflowing[data-v-81ce0c45]{padding-bottom:var(--space-6)}.att-more[data-v-81ce0c45]{position:absolute;left:var(--space-4);bottom:var(--space-1);z-index:1;display:inline-flex;align-items:center;height:18px;padding:0 var(--space-2);border:.5px solid var(--color-line);border-radius:var(--radius-full);background:var(--color-surface-raised);color:var(--color-text-muted);font-size:var(--text-xs);box-shadow:var(--shadow-sm);pointer-events:none}.att-row[data-v-81ce0c45]{display:flex;flex-wrap:wrap;gap:6px}.att-row-media[data-v-81ce0c45]{gap:var(--space-2)}.att-clear[data-v-81ce0c45]{position:absolute;top:var(--space-3);right:var(--space-4);z-index:1}.file-input-hidden[data-v-81ce0c45]{display:none}.cin-wrap[data-v-81ce0c45]{position:relative;padding:14px 16px 8px}.input-row[data-v-81ce0c45]{display:flex;align-items:flex-start;gap:var(--space-2)}.expand-btn[data-v-81ce0c45]{width:22px;height:22px;display:flex;align-items:center;justify-content:center;border:none;border-radius:6px;background:transparent;color:var(--dim);cursor:pointer;padding:0;transition:background .12s,color .12s}.expand-btn[data-v-81ce0c45]:hover{background:var(--panel2);color:var(--color-text)}.expand-btn[data-v-81ce0c45]:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}.ph[data-v-81ce0c45]{color:var(--faint);caret-color:var(--color-text);flex:1;border:none;outline:none;resize:none;font-family:var(--font-ui);font-size:var(--content-font-size);text-autospace:normal;background:transparent;min-height:36px;max-height:25vh;overflow-y:auto;scrollbar-width:none;line-height:1.5;margin-bottom:6px;user-select:text}.ph[data-v-81ce0c45]::-webkit-scrollbar{display:none}.ph[data-v-81ce0c45]::placeholder{color:var(--muted)}.ph[data-v-81ce0c45]:not(:placeholder-shown){color:var(--color-text)}.composer.expanded .ph[data-v-81ce0c45]{min-height:70vh;max-height:70vh}.compact-chip[data-v-81ce0c45]{height:var(--composer-control-size);padding:0 var(--space-2);border:.5px solid transparent;border-radius:var(--radius-full);background:transparent;color:var(--color-warning);font-family:var(--mono);font-size:var(--ui-font-size);cursor:pointer;line-height:1;flex:none;transition:background var(--duration-base) var(--ease-out)}.compact-chip[data-v-81ce0c45]:hover{background:var(--color-hover)}.composer-attach[data-v-81ce0c45]{width:var(--composer-control-size);height:var(--composer-control-size);border-radius:var(--radius-full)}.send[data-v-81ce0c45]{width:var(--composer-send-size);height:var(--composer-send-size);border-radius:var(--radius-full);background:var(--color-send-bg);color:var(--color-send-icon);border:none;box-shadow:var(--shadow-send);padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background var(--duration-slow) var(--ease-out),transform var(--duration-fast) var(--ease-out),box-shadow var(--duration-slow) var(--ease-out);position:relative}.send[data-v-81ce0c45]:hover:not(:disabled){background:var(--color-send-bg-hover);box-shadow:var(--shadow-send-hover)}.send[data-v-81ce0c45]:active{transform:scale(.92)}.send[data-v-81ce0c45]:disabled{cursor:not-allowed;background:var(--color-send-bg-disabled);color:var(--color-send-icon-disabled);opacity:var(--opacity-send-disabled)}.send[data-v-81ce0c45]:disabled:active{transform:none}.send.is-starting[data-v-81ce0c45]:disabled{background:var(--color-send-bg);color:var(--color-send-icon)}.send.is-starting[data-v-81ce0c45] .ui-spinner{color:var(--color-send-icon)}.send.is-starting[data-v-81ce0c45] .ui-spinner__track{stroke:color-mix(in srgb,var(--color-send-icon) 32%,transparent)}.send svg[data-v-81ce0c45]{flex:none;width:var(--composer-send-icon-size);height:var(--composer-send-icon-size)}.stop[data-v-81ce0c45]{width:var(--composer-send-size);height:var(--composer-send-size);border-radius:var(--radius-full);background:var(--color-subtle);color:var(--color-stop-glyph);border:none;box-shadow:var(--shadow-xs);padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;transition:background .16s ease,color .16s ease,transform .12s ease}.stop[data-v-81ce0c45]:hover{background:var(--color-danger);color:var(--color-text-on-accent)}.stop[data-v-81ce0c45]:active{transform:scale(.92)}.stop svg[data-v-81ce0c45]{flex:none;width:var(--composer-send-icon-size);height:var(--composer-send-icon-size)}.toolbar[data-v-81ce0c45]{display:flex;align-items:center;justify-content:space-between;padding:var(--space-1) var(--composer-control-inset) var(--composer-control-inset);position:relative}.menu-measure[data-v-81ce0c45]{position:absolute;width:max-content;height:0;overflow:hidden;visibility:hidden;pointer-events:none}.toolbar-left[data-v-81ce0c45],.toolbar-right[data-v-81ce0c45]{display:flex;align-items:center;gap:var(--space-1);min-width:0}.toolbar-left[data-v-81ce0c45]{flex:0 1 auto;overflow:hidden}.toolbar-right[data-v-81ce0c45]{flex:1 1 0;justify-content:flex-end}.perm-pill[data-v-81ce0c45],.mode-pill[data-v-81ce0c45],.model-pill[data-v-81ce0c45]{position:relative;display:inline-flex;align-items:center;gap:var(--space-1);height:var(--composer-control-size);padding:0 var(--space-3);border:.5px solid transparent;border-radius:var(--radius-full);background:transparent;color:var(--color-text);font-family:var(--font-ui);font-size:var(--ui-font-size);font-weight:var(--weight-medium);line-height:1;white-space:nowrap;cursor:pointer;user-select:none;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.perm-pill[data-v-81ce0c45],.mode-pill[data-v-81ce0c45]{font-size:var(--ui-font-size-sm)}.perm-pill[data-v-81ce0c45]:after,.mode-pill[data-v-81ce0c45]:after,.model-pill[data-v-81ce0c45]:after{content:"";position:absolute;inset:0;border-radius:var(--radius-full);background:var(--color-hover);opacity:0;transition:opacity var(--duration-base) var(--ease-out);pointer-events:none}.perm-pill[data-v-81ce0c45]:hover:after,.mode-pill[data-v-81ce0c45]:hover:after,.model-pill[data-v-81ce0c45]:hover:after{opacity:1}.perm-pill.open[data-v-81ce0c45],.mode-pill.open[data-v-81ce0c45],.mode-pill.on[data-v-81ce0c45],.model-pill.open[data-v-81ce0c45]{background:var(--color-accent-soft)}.perm-pill.perm-manual[data-v-81ce0c45]{color:var(--dim)}.perm-pill.perm-yolo[data-v-81ce0c45]{color:var(--color-warning)}.perm-pill.perm-auto[data-v-81ce0c45]{color:var(--color-danger)}.perm-pill-icon[data-v-81ce0c45]{flex:none}@container (max-width: 620px){.perm-pill[data-v-81ce0c45]{width:var(--composer-control-size);height:var(--composer-control-size);padding:0;justify-content:center;flex:none}.perm-pill-label[data-v-81ce0c45]{display:none}}.ctx-group[data-v-81ce0c45]{display:flex;align-items:center;gap:4px;flex-shrink:0;padding:2px 0;border-radius:var(--radius-xs)}.ctx-group[data-v-81ce0c45]:focus-visible{outline:2px solid var(--color-accent);outline-offset:2px}.model-pill[data-v-81ce0c45]{gap:var(--space-1);line-height:var(--leading-normal);overflow:hidden;flex:0 1 auto;min-width:0;max-width:320px;transition:background var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out),transform var(--duration-fast) var(--ease-out)}.model-pill[data-v-81ce0c45]:active{transform:scale(.97)}.model-pill[data-v-81ce0c45]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.model-pill .mp-name[data-v-81ce0c45]{flex:0 1 auto;font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}.model-pill .think-suffix[data-v-81ce0c45]{color:var(--color-accent);font-weight:var(--weight-medium);flex-shrink:0}.model-pill .cv[data-v-81ce0c45]{color:var(--faint);flex:none;transition:transform var(--duration-base) var(--ease-out),color var(--duration-base) var(--ease-out)}.model-pill:hover .cv[data-v-81ce0c45],.model-pill.open .cv[data-v-81ce0c45]{color:var(--dim)}.model-pill.open .cv[data-v-81ce0c45]{transform:rotate(180deg)}.model-pill.login-pill[data-v-81ce0c45]{flex:none;color:var(--color-accent)}.model-pill.login-pill .mp-name[data-v-81ce0c45]{color:var(--color-accent)}.model-dropdown[data-v-81ce0c45]{position:absolute;bottom:calc(100% + 4px);right:calc(var(--composer-control-inset) + var(--composer-send-size) + var(--space-1));z-index:var(--z-dropdown);min-width:200px;background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:var(--space-1);display:flex;flex-direction:column;gap:1px;font-family:var(--font-ui);transform-origin:bottom right}.composer-menu-pop-enter-active[data-v-81ce0c45]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.composer-menu-pop-leave-active[data-v-81ce0c45]{transition:opacity var(--duration-fast) var(--ease-out),transform var(--duration-fast) var(--ease-out);pointer-events:none}.composer-menu-pop-enter-from[data-v-81ce0c45],.composer-menu-pop-leave-to[data-v-81ce0c45]{opacity:0;transform:scale(.97) translateY(2px)}.md-list[data-v-81ce0c45]{display:flex;flex-direction:column;gap:1px;max-height:min(320px,40vh);overflow-y:auto;overscroll-behavior:contain}.md-section[data-v-81ce0c45]{padding:4px 9px 2px;font-size:var(--text-xs);color:var(--muted);text-transform:uppercase;letter-spacing:.04em;font-weight:var(--weight-semibold)}.md-row[data-v-81ce0c45]{display:flex;align-items:center;gap:7px;width:100%;background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text);padding:5px 9px;border-radius:6px;text-align:left;transition:background var(--duration-base) var(--ease-out)}.md-row[data-v-81ce0c45]:hover{background:var(--color-hover)}.md-row:hover .md-name[data-v-81ce0c45]{color:var(--color-text-strong)}.md-row[data-v-81ce0c45]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.md-row[data-v-81ce0c45]:disabled{cursor:default;opacity:.58}.md-row[data-v-81ce0c45]:disabled:hover{background:none}.md-row.is-current[data-v-81ce0c45]{background:var(--color-selected)}.md-note[data-v-81ce0c45]{margin-left:auto;color:var(--muted);font-size:var(--ui-font-size-xs)}.md-row-more .md-more-icon[data-v-81ce0c45]{color:var(--dim)}.md-row-more .md-more-arrow[data-v-81ce0c45]{color:var(--faint);flex:none;transition:color var(--duration-base) var(--ease-out)}.md-row-more:hover .md-more-arrow[data-v-81ce0c45]{color:var(--dim)}.md-check[data-v-81ce0c45]{width:14px;flex:none;color:var(--color-accent);font-weight:500;display:flex;justify-content:center}.md-name[data-v-81ce0c45]{flex:1;transition:color var(--duration-base) var(--ease-out)}.md-provider[data-v-81ce0c45]{color:var(--muted);font-size:var(--ui-font-size-xs);flex:none}.md-star[data-v-81ce0c45]{color:var(--star);flex:none;margin-left:auto}.md-divider[data-v-81ce0c45]{height:1px;background:var(--line);margin:3px 0}.md-thinking[data-v-81ce0c45]{display:flex;align-items:center;gap:8px;padding:6px 9px;border-radius:var(--radius-sm)}.md-thinking .md-name[data-v-81ce0c45]{font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text);flex:none}.md-thinking .md-note[data-v-81ce0c45],.md-thinking .ui-seg[data-v-81ce0c45]{margin-left:auto}.md-cache-note[data-v-81ce0c45]{width:0;min-width:100%;padding:2px 7px 4px;color:var(--muted);font-size:var(--ui-font-size-xs);line-height:1.4}.perm-dropdown[data-v-81ce0c45]{position:absolute;bottom:calc(100% + 4px);left:var(--composer-control-inset);z-index:var(--z-dropdown);min-width:220px;width:max-content;max-width:calc(100vw - var(--space-8));background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:5px;display:flex;flex-direction:column;gap:1px;transform-origin:bottom left}.pd-row[data-v-81ce0c45]{display:grid;grid-template-columns:var(--p-ic-sm) var(--composer-menu-desc-width, max-content) var(--p-ic-sm);column-gap:7px;row-gap:2px;align-items:start;width:100%;background:none;border:none;cursor:pointer;padding:6px 7px;border-radius:6px;text-align:left}.pd-row[data-v-81ce0c45]:hover,.pd-row.is-current[data-v-81ce0c45]{background:var(--color-hover)}.pd-icon[data-v-81ce0c45]{grid-column:1;grid-row:1;width:var(--p-ic-sm);min-height:1lh;display:flex;align-items:center;justify-content:center;line-height:var(--leading-tight)}.pd-check[data-v-81ce0c45]{grid-column:3;grid-row:1;width:var(--p-ic-sm);min-height:1lh;color:var(--color-accent);font-size:var(--ui-font-size);font-weight:var(--weight-medium);display:flex;align-items:center;justify-content:center;line-height:var(--leading-tight)}.pd-info[data-v-81ce0c45]{display:contents}.pd-name[data-v-81ce0c45]{grid-column:2;grid-row:1;font-family:var(--font-ui);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);line-height:var(--leading-tight)}.pd-desc[data-v-81ce0c45]{grid-column:2;grid-row:2;width:var(--composer-menu-desc-width, auto);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-caption);color:var(--muted);line-height:var(--leading-tight)}.modes[data-v-81ce0c45]{position:relative;display:inline-flex;z-index:var(--z-sticky)}.mode-pill.on[data-v-81ce0c45]{color:var(--color-accent-hover)}.mode-label[data-v-81ce0c45]{flex:none}.mode-tag[data-v-81ce0c45]{flex:none;font-family:var(--font-ui);font-size:calc(var(--ui-font-size) - 3px);color:var(--color-accent-hover);background:var(--bg);border:.5px solid var(--color-accent-bd);border-radius:999px;padding:0 6px;line-height:16px}.mode-dot[data-v-81ce0c45]{width:6px;height:6px;border-radius:50%;background:var(--color-accent);flex:none}.modes-menu[data-v-81ce0c45]{position:fixed;z-index:var(--z-dropdown);min-width:220px;width:max-content;max-width:calc(100vw - var(--space-8));background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);padding:5px;display:flex;flex-direction:column;gap:1px;transform-origin:bottom left}.mode-row[data-v-81ce0c45]{display:grid;grid-template-columns:14px var(--composer-menu-desc-width, max-content);column-gap:7px;row-gap:2px;align-items:start;width:100%;padding:6px 7px;border:none;background:none;border-radius:6px;cursor:pointer;font-family:var(--font-ui);text-align:left}.mode-row[data-v-81ce0c45]:hover:not(:disabled){background:var(--color-hover)}.mode-row:hover:not(:disabled) .mode-row-icon[data-v-81ce0c45],.mode-row:hover:not(:disabled) .mode-row-name[data-v-81ce0c45]{color:var(--color-text-strong)}.mode-row[data-v-81ce0c45]:disabled{cursor:not-allowed;opacity:.45}.mode-row-info[data-v-81ce0c45]{display:contents}.mode-row-icon[data-v-81ce0c45]{grid-column:1;grid-row:1;width:14px;min-height:1lh;display:flex;align-items:center;justify-content:center;color:var(--muted);transition:color var(--duration-base) var(--ease-out);font-size:var(--ui-font-size);line-height:var(--leading-tight)}.mode-row-name[data-v-81ce0c45]{grid-column:2;grid-row:1;transition:color var(--duration-base) var(--ease-out);font-size:var(--ui-font-size-sm);font-weight:var(--weight-medium);color:var(--color-text);line-height:var(--leading-tight)}.mode-row-desc[data-v-81ce0c45]{grid-column:2;grid-row:2;width:var(--composer-menu-desc-width, auto);font-size:var(--text-xs);font-weight:var(--weight-caption);color:var(--muted);line-height:var(--leading-tight)}.mode-row-not-supported[data-v-81ce0c45]{margin-left:auto;font-size:var(--ui-font-size-xs);color:var(--muted)}.mode-row.on[data-v-81ce0c45]{background:var(--color-hover)}.mode-row.on .mode-row-name[data-v-81ce0c45],.mode-row.on .mode-row-icon[data-v-81ce0c45]{color:var(--color-text)}.mode-row-meta[data-v-81ce0c45]{font-family:var(--mono);font-size:calc(var(--ui-font-size) - 3px);color:var(--muted)}.mode-row:disabled .mode-row-meta[data-v-81ce0c45]{color:var(--faint)}.mode-switch[data-v-81ce0c45]{grid-column:2;grid-row:1;justify-self:end;width:34px;height:19px;border-radius:999px;background:var(--color-line-strong);position:relative;transition:background .15s}.mode-switch.on[data-v-81ce0c45]{background:var(--color-accent)}.mode-knob[data-v-81ce0c45]{position:absolute;top:2px;left:2px;width:15px;height:15px;border-radius:50%;background:var(--color-text-on-accent);box-shadow:var(--shadow-xs);transition:transform .15s}.mode-switch.on .mode-knob[data-v-81ce0c45]{transform:translate(15px)}.mode-row-goal[data-v-81ce0c45]{--mode-row-icon-col: 14px;--mode-row-col-gap: 7px;--mode-row-pad-x: 7px;display:flex;flex-direction:column;align-items:stretch;cursor:default;padding:0;gap:0}.mode-row-goal[data-v-81ce0c45]:hover{background:transparent}.mode-row-goal.on[data-v-81ce0c45]{background:var(--color-hover)}.mode-row-main[data-v-81ce0c45]{display:grid;grid-template-columns:var(--mode-row-icon-col) var(--composer-menu-desc-width, max-content);column-gap:var(--mode-row-col-gap);row-gap:2px;align-items:start;width:100%;padding:6px var(--mode-row-pad-x);border:none;background:none;border-radius:6px;cursor:pointer;font-family:var(--font-ui);text-align:left}.mode-row-main[data-v-81ce0c45]:hover{background:var(--color-hover)}.mode-row-main:hover .mode-row-icon[data-v-81ce0c45],.mode-row-main:hover .mode-row-name[data-v-81ce0c45]{color:var(--color-text-strong)}.mode-row-goal.on .mode-row-main .mode-row-name[data-v-81ce0c45]{color:var(--color-text)}.mode-row-actions[data-v-81ce0c45]{display:flex;flex-wrap:wrap;gap:var(--space-2);justify-content:flex-start;padding:0 var(--mode-row-pad-x) var(--mode-row-pad-x) calc(var(--mode-row-pad-x) + var(--mode-row-icon-col) + var(--mode-row-col-gap))}.mode-row-action[data-v-81ce0c45]{flex:none}.mode-row-action[data-v-81ce0c45] .ui-button__content{gap:var(--space-1)}.mode-row-input[data-v-81ce0c45]{flex:1;min-width:0;padding:4px 8px;border-radius:var(--radius-sm);border:.5px solid var(--line);background:var(--bg);color:var(--color-text);font-size:var(--ui-font-size-xs)}@media(max-width:980px){.perm-pill[data-v-81ce0c45]{max-width:104px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}}@media(max-width:640px){.composer[data-v-81ce0c45]{padding:9px var(--dock-inline-right, max(12px, var(--safe-right))) max(24px,var(--safe-bottom)) var(--dock-inline-left, max(12px, var(--safe-left)))}.composer-card[data-v-81ce0c45]{--composer-control-size: 36px;max-width:100%}.input-row[data-v-81ce0c45]{gap:6px;min-width:0}.send[data-v-81ce0c45]{width:var(--composer-send-size);height:var(--composer-send-size);min-width:var(--composer-send-size);padding:0;border-radius:var(--radius-full);font-size:0;align-self:flex-end;position:relative}.send svg[data-v-81ce0c45]{display:none}.send[data-v-81ce0c45]:after{content:"↑";font-size:17px;line-height:1;color:var(--bg)}.stop[data-v-81ce0c45]{width:var(--composer-send-size);height:var(--composer-send-size);min-width:var(--composer-send-size);padding:0;border-radius:var(--radius-full);font-size:0;align-self:flex-end;position:relative}.stop svg[data-v-81ce0c45]{display:none}.stop[data-v-81ce0c45]:after{content:"■";font-size:17px;line-height:1}.perm-pill[data-v-81ce0c45],.modes[data-v-81ce0c45]{display:none}.model-dropdown[data-v-81ce0c45]{right:calc(var(--composer-control-inset) + var(--composer-send-size) + var(--space-1));left:auto;min-width:180px;max-width:calc(100vw - 24px)}.ph[data-v-81ce0c45]{font-size:16px}.model-pill[data-v-81ce0c45],.attach-btn[data-v-81ce0c45]{font-size:var(--ui-font-size)}.toolbar[data-v-81ce0c45]{gap:6px;min-width:0}.toolbar-left[data-v-81ce0c45],.toolbar-right[data-v-81ce0c45]{min-width:0}.model-pill[data-v-81ce0c45]{max-width:min(52vw,220px)}.model-pill .mp-name[data-v-81ce0c45]{max-width:min(40vw,170px)}.md-row[data-v-81ce0c45],.md-section[data-v-81ce0c45]{font-size:var(--ui-font-size)}.md-thinking[data-v-81ce0c45]{flex-wrap:wrap;row-gap:6px}.md-thinking .ui-seg[data-v-81ce0c45]{margin-left:0}.pd-name[data-v-81ce0c45]{font-size:var(--ui-font-size)}.pd-desc[data-v-81ce0c45]{font-size:var(--text-xs)}}.goal-panel[data-v-104a665c]{display:flex;flex-direction:column;gap:var(--space-2)}.goal-full[data-v-104a665c]{color:var(--color-text);font-size:var(--text-base);line-height:var(--leading-prose);white-space:pre-wrap;overflow-wrap:anywhere}.goal-criterion[data-v-104a665c]{padding-top:var(--space-2);border-top:.5px solid var(--color-line);color:var(--color-text-muted)}.goal-criterion-label[data-v-104a665c]{display:flex;align-items:center;gap:var(--space-1);color:var(--color-text);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-section-label);line-height:var(--leading-normal)}.goal-criterion p[data-v-104a665c]{margin:var(--space-1) 0 0;color:var(--color-text-muted);font:var(--text-base)/var(--leading-prose) var(--font-ui)}.qcard[data-v-ca95f2cd]{margin:var(--space-2) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);overflow:hidden;animation:kimi-card-in var(--duration-base) var(--ease-out)}.qcard.minimized[data-v-ca95f2cd]{transition:background var(--duration-fast) var(--ease-out)}.qcard.minimized[data-v-ca95f2cd]:hover{background:var(--color-hover)}.qh[data-v-ca95f2cd]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-3) var(--space-4) 0}.qcard.minimized .qh[data-v-ca95f2cd]{padding-bottom:var(--space-3);align-items:center}.qcard.minimized .qh.clickable[data-v-ca95f2cd]{cursor:pointer}.qh-chip[data-v-ca95f2cd]{width:var(--p-chip-num);height:var(--p-chip-num);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.qtitle[data-v-ca95f2cd]{flex:1;min-width:0;color:var(--color-text);font-size:var(--text-lg);font-weight:var(--weight-semibold);line-height:var(--leading-tight);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.qcard.minimized .qtitle[data-v-ca95f2cd]{display:block;white-space:nowrap;text-overflow:ellipsis}.qmin[data-v-ca95f2cd],.qclose[data-v-ca95f2cd]{flex:none;margin-top:calc((var(--text-lg) * var(--leading-tight) - var(--icon-button-sm)) / 2)}.qmin[data-v-ca95f2cd]{margin-left:auto}.qcard.minimized .qmin[data-v-ca95f2cd],.qcard.minimized .qclose[data-v-ca95f2cd]{margin-top:0}.qbody[data-v-ca95f2cd]{padding:var(--space-3) var(--space-4) 0;color:var(--color-text);font:var(--text-base)/var(--leading-normal) var(--font-ui)}.qmdbody[data-v-ca95f2cd]{margin-bottom:var(--space-2)}.qopts[data-v-ca95f2cd]{display:flex;flex-direction:column;gap:2px;margin-top:var(--space-2)}.qopt[data-v-ca95f2cd]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);cursor:pointer;font:var(--text-sm)/var(--leading-normal) var(--font-ui);color:var(--color-text);transition:background var(--duration-fast) var(--ease-out);user-select:none}.qopt[data-v-ca95f2cd]:hover,.qopt.highlighted[data-v-ca95f2cd]{background:var(--color-hover)}.qopt-key[data-v-ca95f2cd]{width:var(--p-chip-num);height:var(--p-chip-num);margin-top:calc((var(--text-base) * var(--leading-normal) - var(--p-chip-num)) / 2);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.qopt-key[data-v-ca95f2cd]:empty{background:transparent}.qopt-glyph[data-v-ca95f2cd]{width:16px;height:16px;margin-top:calc((var(--text-base) * var(--leading-normal) - 16px) / 2);flex:none;border:.5px solid var(--color-line-strong);position:relative;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.qopt-glyph.rad[data-v-ca95f2cd]{border-radius:50%}.qopt-glyph.chk[data-v-ca95f2cd]{border-radius:var(--radius-xs)}.qopt.selected .qopt-glyph[data-v-ca95f2cd]{border-color:var(--color-accent)}.qopt.selected .qopt-glyph.rad[data-v-ca95f2cd]:after{content:"";position:absolute;inset:3px;border-radius:50%;background:var(--color-accent)}.qopt.selected .qopt-glyph.chk[data-v-ca95f2cd]{background:var(--color-accent)}.qopt.selected .qopt-glyph.chk[data-v-ca95f2cd]:after{content:"";position:absolute;left:4.5px;top:1.5px;width:4px;height:8px;border-right:1.5px solid var(--color-text-on-accent);border-bottom:1.5px solid var(--color-text-on-accent);transform:rotate(45deg)}.qopt-text[data-v-ca95f2cd]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.qopt-label[data-v-ca95f2cd]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.qopt-desc[data-v-ca95f2cd]{color:var(--color-text-muted);font:var(--text-xs)/var(--leading-normal) var(--font-ui)}.other-input[data-v-ca95f2cd]{flex:1;font:var(--text-base) var(--font-ui);border:none;border-bottom:.5px solid var(--color-line);outline:none;padding:2px var(--space-1);color:var(--color-text);background:transparent;min-width:0}.other-input[data-v-ca95f2cd]:focus-visible{border-bottom-color:var(--color-accent);box-shadow:0 1px 0 0 var(--color-accent)}.qfoot[data-v-ca95f2cd]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.qbtns[data-v-ca95f2cd]{display:flex;align-items:center;gap:var(--space-1)}.qhint[data-v-ca95f2cd]{margin-left:auto;color:var(--color-text-faint);font:var(--text-xs) var(--font-ui);user-select:none}@media(max-width:640px){.qopt[data-v-ca95f2cd]{min-height:44px;padding:var(--space-3)}.other-input[data-v-ca95f2cd]{flex-basis:100%;min-height:28px}.qfoot[data-v-ca95f2cd]{flex-direction:column;align-items:stretch}.qhint[data-v-ca95f2cd]{display:none}.qbtns[data-v-ca95f2cd]{flex-direction:column;gap:var(--space-2)}.qbtns[data-v-ca95f2cd] .ui-button{width:100%;min-height:46px}}.appr[data-v-cd852243]{display:flex;flex-direction:column;max-height:calc(100dvh - 72px);margin:var(--space-2) 0;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-menu);overflow:hidden;animation:kimi-card-in var(--duration-base) var(--ease-out)}.appr>.ah[data-v-cd852243],.appr>.af[data-v-cd852243]{flex:none}.appr.minimized[data-v-cd852243]{transition:background var(--duration-fast) var(--ease-out)}.appr.minimized[data-v-cd852243]:hover{background:var(--color-hover)}.ah[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-3) var(--space-4) 0;flex-wrap:nowrap}.appr.minimized .ah[data-v-cd852243]{padding-bottom:var(--space-3)}.appr.minimized .ah.clickable[data-v-cd852243]{cursor:pointer}.akind[data-v-cd852243]{color:var(--color-text);font-size:var(--text-lg);font-weight:var(--weight-semibold);white-space:nowrap;flex:none}.apeek[data-v-cd852243]{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text-muted);font:var(--text-xs) var(--font-mono)}.amin[data-v-cd852243],.aexpand[data-v-cd852243]{margin-left:auto;flex:none}.aexpand+.amin[data-v-cd852243]{margin-left:0}.ab[data-v-cd852243]{display:flex;flex-direction:column;flex:1;min-height:0;padding:var(--space-3) var(--space-4) 0}.ab[data-v-cd852243]>*{flex:none}.ab>.body-plan-wrap[data-v-cd852243]{flex:1}.plan-path[data-v-cd852243]{display:block;width:100%;margin-bottom:var(--space-2);padding:0;border:none;background:transparent;color:var(--color-accent);font:var(--text-xs) var(--font-mono);text-align:left;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:pointer}.plan-path[data-v-cd852243]:hover{text-decoration:underline}.plan-path[data-v-cd852243]:focus-visible{outline:none;text-decoration:underline;border-radius:var(--radius-xs);box-shadow:var(--p-focus-ring)}.body-code[data-v-cd852243]{display:flex;flex-direction:column;min-height:0}.body-code.expanded[data-v-cd852243]{flex:1}.body-code.expanded[data-v-cd852243] .hl-code{max-height:none;flex:1}.code-path[data-v-cd852243]{flex:none;color:var(--color-text-muted);font:var(--text-xs) var(--font-mono);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.shell-cmd[data-v-cd852243]{font:var(--text-sm) var(--font-mono);background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3);white-space:pre-wrap;word-break:break-all;max-height:160px;overflow-y:auto;color:var(--color-text)}.shell-dollar[data-v-cd852243]{color:var(--color-accent-hover);font-weight:var(--weight-medium);margin-right:var(--space-2)}.shell-cwd[data-v-cd852243]{font:var(--text-xs) var(--font-mono);color:var(--color-text-muted);margin-top:var(--space-1)}.shell-danger[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);color:var(--color-danger);font:var(--text-sm)/var(--leading-normal) var(--font-ui);background:var(--color-danger-soft)}.shell-danger-ic[data-v-cd852243]{flex:none}.body-chip[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap;font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text)}.chip-label[data-v-cd852243]{background:var(--color-inline-code-bg);border-radius:var(--radius-sm);padding:2px var(--space-2);font:var(--weight-semibold) var(--text-xs) var(--font-mono);color:var(--color-text-muted);white-space:nowrap}.chip-value[data-v-cd852243]{font:var(--text-sm) var(--font-mono);color:var(--color-text);word-break:break-all}.chip-detail[data-v-cd852243]{font:var(--text-xs) var(--font-ui);color:var(--color-text-muted)}.todo-item[data-v-cd852243]{display:flex;align-items:flex-start;gap:var(--space-2);padding:var(--space-1) 0;font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text)}.todo-glyph[data-v-cd852243]{color:var(--color-accent);font-size:var(--text-sm);flex:none;width:14px}.todo-title[data-v-cd852243]{color:var(--color-text)}.todo-done[data-v-cd852243]{color:var(--color-text-muted);text-decoration:line-through}.body-generic[data-v-cd852243]{font:var(--text-base)/var(--leading-normal) var(--font-ui);color:var(--color-text);word-break:break-word}.body-plan-wrap[data-v-cd852243]{display:flex;flex-direction:column;min-height:0;position:relative}.body-plan-wrap[data-v-cd852243]:before{content:"";position:absolute;top:0;left:0;right:0;height:18px;z-index:1;pointer-events:none;opacity:0;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 2.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.75%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.25%,transparent),transparent);transition:opacity var(--duration-slow) var(--ease-out)}.body-plan-wrap.scrolled[data-v-cd852243]:before{opacity:1}.body-plan-wrap>.plan-opts[data-v-cd852243]{flex:none}.body-plan[data-v-cd852243]{max-height:50vh;overflow-y:auto;min-height:0}.body-plan.expanded[data-v-cd852243]{max-height:none;flex:1}.plan-opts[data-v-cd852243]{display:flex;flex-direction:column;gap:2px;margin-top:var(--space-3);padding-top:var(--space-3);border-top:.5px solid var(--color-line)}.popt[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-2) var(--space-3);border:none;border-radius:var(--radius-md);background:transparent;color:var(--color-text);font:var(--text-sm)/var(--leading-normal) var(--font-ui);text-align:left;cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.popt[data-v-cd852243]:hover:not(:disabled){background:var(--color-hover)}.popt[data-v-cd852243]:focus-visible{outline:none;background:var(--color-hover);box-shadow:var(--p-focus-ring)}.popt[data-v-cd852243]:disabled{cursor:default;opacity:.6}.popt-key[data-v-cd852243]{width:var(--p-chip-num);height:var(--p-chip-num);border-radius:var(--radius-sm);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/var(--p-chip-num) var(--font-ui);text-align:center;flex:none}.popt-text[data-v-cd852243]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.popt-label[data-v-cd852243]{color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.popt-desc[data-v-cd852243]{color:var(--color-text-muted);font:var(--text-xs)/var(--leading-normal) var(--font-ui)}.popt-spin[data-v-cd852243]{flex:none;color:var(--color-text-muted)}.feedback-wrap[data-v-cd852243]{margin-top:var(--space-3)}.feedback-ta[data-v-cd852243]{width:100%;box-sizing:border-box;font:var(--text-sm) var(--font-ui);padding:var(--space-2) var(--space-2);border:.5px solid var(--color-line);border-radius:var(--radius-md);resize:none;outline:none;color:var(--color-text);background:var(--color-surface)}.feedback-ta[data-v-cd852243]:focus-visible{border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.feedback-hint[data-v-cd852243]{font:var(--text-xs) var(--font-ui);color:var(--color-text-muted);margin-top:var(--space-1)}.af[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-2);margin-top:var(--space-3);padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.abtns[data-v-cd852243]{display:flex;align-items:center;gap:var(--space-1)}.knum[data-v-cd852243]{min-width:16px;height:16px;padding:0 3px;border-radius:var(--radius-xs);background:var(--color-inline-code-bg);color:var(--color-text);font:var(--weight-medium) var(--text-xs)/16px var(--font-ui);text-align:center}.abtns .ui-button--primary .knum[data-v-cd852243]{background:color-mix(in srgb,var(--color-text-on-accent) 28%,transparent);color:var(--color-text-on-accent)}@media(max-width:640px){.popt[data-v-cd852243]{min-height:44px;padding:var(--space-3)}.af[data-v-cd852243]{flex-direction:column;align-items:stretch}.abtns[data-v-cd852243]{flex-direction:column;margin-left:0;gap:var(--space-2)}.abtns[data-v-cd852243] .ui-button{width:100%;min-height:46px}.abtns .amain[data-v-cd852243]{order:-1}}.taskspane[data-v-e5e66edb]{padding:14px 18px 10px;flex:1;min-height:0;display:flex;flex-direction:column}.tp-head[data-v-e5e66edb]{border-top:.5px solid var(--line);padding-top:10px;margin-bottom:8px;display:flex;align-items:baseline;gap:8px}.tp-title[data-v-e5e66edb]{color:var(--color-accent-hover);font-weight:500;font-size:var(--text-base);text-transform:capitalize}.tp-count[data-v-e5e66edb]{color:var(--muted);font-size:var(--text-base)}.tp-list[data-v-e5e66edb]{flex:1;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.tp-row[data-v-e5e66edb]{padding:4px 0}.tp-row.done .tp-name[data-v-e5e66edb]{color:var(--muted);text-decoration:line-through}.tp-row.fail .tp-name[data-v-e5e66edb]{color:var(--color-danger)}.tp-main[data-v-e5e66edb]{display:flex;align-items:center;gap:7px;font-size:var(--text-base)}.tp-row.expandable>.tp-main[data-v-e5e66edb]{cursor:pointer;border-radius:4px}.tp-row.expandable>.tp-main[data-v-e5e66edb]:hover{background:var(--panel2)}.tp-chevron[data-v-e5e66edb]{flex:none;color:var(--muted);transition:transform .12s}.tp-chevron.open[data-v-e5e66edb]{transform:rotate(90deg)}.tp-name[data-v-e5e66edb]{color:var(--color-text);flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-time[data-v-e5e66edb]{flex:none;font-size:var(--text-base);color:var(--muted)}.tp-model[data-v-e5e66edb]{flex:0 1 auto;min-width:0;font-size:var(--text-base);color:var(--muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tp-stop[data-v-e5e66edb]{flex:none;background:none;border:.5px solid color-mix(in srgb,var(--color-danger) 22%,var(--bg));border-radius:var(--radius-xs);color:var(--color-danger);font-size:max(9px,calc(var(--ui-font-size) - 3.5px));padding:1px 8px;cursor:pointer;font-family:var(--mono)}.tp-stop[data-v-e5e66edb]:hover{background:var(--panel)}.tp-detail[data-v-e5e66edb]{margin:4px 0 0 23px;display:flex;flex-direction:column;gap:4px}.tp-codebox[data-v-e5e66edb]{position:relative;background:var(--panel);border:.5px solid var(--line);border-radius:var(--radius-xs)}.tp-copy[data-v-e5e66edb]{position:absolute;top:4px;right:6px;z-index:1;opacity:0;visibility:hidden;transition:opacity .12s ease,visibility .12s ease;background:var(--panel2);border:.5px solid var(--line);border-radius:var(--radius-xs);color:var(--dim);font-size:max(9px,calc(var(--ui-font-size) - 3.5px));padding:1px 7px;cursor:pointer;font-family:var(--sans)}.tp-codebox:hover .tp-copy[data-v-e5e66edb],.tp-copy[data-v-e5e66edb]:focus-visible{opacity:1;visibility:visible}.tp-copy[data-v-e5e66edb]:hover{background:var(--panel)}.tp-copy.copied[data-v-e5e66edb]{color:var(--color-success);border-color:color-mix(in srgb,var(--color-success) 30%,var(--line))}.tp-pre[data-v-e5e66edb]{margin:0;padding:6px 10px;max-height:320px;overflow:auto;contain:layout paint}.tp-pre code[data-v-e5e66edb]{display:block;font-family:var(--mono);font-size:var(--text-base);line-height:1.55;color:var(--dim);white-space:pre-wrap;word-break:break-word}.tp-cmd[data-v-e5e66edb]{display:block;color:var(--muted)}.tp-line[data-v-e5e66edb]{display:block}.tp-empty[data-v-e5e66edb]{padding:24px 0;text-align:center;color:var(--faint);font-size:var(--ui-font-size-sm)}@media(max-width:640px){.taskspane[data-v-e5e66edb]{padding:14px 14px 16px}.tp-main[data-v-e5e66edb]{flex-wrap:wrap;row-gap:4px}.tp-name[data-v-e5e66edb]{font-size:var(--ui-font-size-sm)}.tp-stop[data-v-e5e66edb]{min-height:32px;display:inline-flex;align-items:center;padding:4px 12px;border-radius:6px;font-size:var(--ui-font-size-xs)}.tp-detail[data-v-e5e66edb]{margin-left:0}.tp-pre[data-v-e5e66edb]{font-size:var(--ui-font-size-xs)}}.tp-stop[data-v-e5e66edb]{border-radius:var(--radius-md);font-family:var(--sans)}.todo-card[data-v-01c65735]{display:flex;flex-direction:column;gap:1px;font-size:var(--text-base)}.tc-row[data-v-01c65735]{display:flex;align-items:center;gap:7px;padding:4px 0;color:var(--color-text)}.tc-name[data-v-01c65735]{flex:1;min-width:0;overflow-wrap:anywhere;line-height:1.4}.tc-row.s-in_progress .tc-name[data-v-01c65735]{font-weight:var(--weight-medium)}.tc-row.s-done .tc-name[data-v-01c65735]{color:var(--color-text-faint);text-decoration:line-through}.tc-empty[data-v-01c65735]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);padding:var(--space-6) var(--space-4);color:var(--color-text-faint);font-size:var(--text-sm)}.tc-empty-ico[data-v-01c65735]{width:28px;height:28px;color:var(--color-line-strong)}@media(max-width:640px){.todo-card[data-v-01c65735]{font-size:var(--text-lg)}.tc-row[data-v-01c65735]{padding:var(--space-2) var(--space-3)}}.chat-dock[data-v-6f1ea685]{--dock-inline-left: 16px;--dock-inline-right: 16px;box-sizing:border-box;width:100%;max-width:calc(var(--read-max) + var(--panes-scrollbar-width, 0px));padding-right:var(--panes-scrollbar-width, 0px);flex:none;position:absolute;inset:auto 0 0;background:transparent;z-index:var(--z-sticky)}.chat-dock.has-popup[data-v-6f1ea685]{z-index:var(--z-dropdown)}.chat-dock.align-center[data-v-6f1ea685]{margin-left:auto;margin-right:auto}.chat-dock.align-left[data-v-6f1ea685]{margin-left:0;margin-right:auto}.chat-dock.align-mobile[data-v-6f1ea685]{max-width:none}.chat-dock[data-v-6f1ea685]:before{--fade: 48px;--veil: 72px;content:"";position:absolute;top:calc(-1 * var(--fade));right:0;bottom:0;left:0;z-index:0;pointer-events:none;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-bg) 0%,transparent),color-mix(in srgb,var(--color-bg) 30%,transparent) 21px,color-mix(in srgb,var(--color-bg) 70%,transparent) 45px,var(--color-bg) var(--veil))}.chat-dock[data-v-6f1ea685]>*{position:relative;z-index:1}.dock-work-panel[data-v-6f1ea685]{position:absolute;left:16px;right:calc(16px + var(--panes-scrollbar-width, 0px));bottom:100%;background:var(--color-surface);border:.5px solid var(--color-line-strong);border-radius:var(--radius-xl);box-shadow:var(--shadow-menu);margin-bottom:7px;max-height:min(360px,50vh);display:flex;flex-direction:column;overflow:hidden}.dock-work-head[data-v-6f1ea685]{display:flex;align-items:center;gap:8px;padding:var(--space-2) var(--space-3);border-bottom:.5px solid var(--color-line);position:relative;z-index:1}.dock-work-tab[data-v-6f1ea685]{font-size:var(--text-base);font-weight:500;color:var(--color-text);padding:3px 8px;border-radius:var(--radius-sm);background:var(--color-surface-sunken);border:.5px solid var(--color-line)}.dock-work-tab.static[data-v-6f1ea685]{background:transparent;border-color:transparent;padding-left:2px}.dock-work-body[data-v-6f1ea685]{padding:var(--space-2) var(--space-3);overflow-y:auto;min-height:0}.dock-work-head-actions[data-v-6f1ea685]{margin-left:auto;display:flex;align-items:center;gap:var(--space-2);flex:none}.dock-goal-action[data-v-6f1ea685] .ui-button__content{gap:var(--space-1)}.dock-work-foot[data-v-6f1ea685]{display:flex;flex-wrap:wrap;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-top:.5px solid var(--color-line);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-option-label);font-variant-numeric:tabular-nums;position:relative;z-index:1}.dock-work-head[data-v-6f1ea685]:after,.dock-work-foot[data-v-6f1ea685]:before{content:"";position:absolute;left:0;right:0;height:18px;pointer-events:none;opacity:0;transition:opacity var(--duration-slow) var(--ease-out)}.dock-work-head[data-v-6f1ea685]:after{top:100%;background:linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 2.5%,transparent),transparent 35%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.75%,transparent),transparent 65%),linear-gradient(to bottom,color-mix(in srgb,var(--color-text) 1.25%,transparent),transparent)}.dock-work-foot[data-v-6f1ea685]:before{bottom:100%;background:linear-gradient(to top,color-mix(in srgb,var(--color-text) 2.5%,transparent),transparent 35%),linear-gradient(to top,color-mix(in srgb,var(--color-text) 1.75%,transparent),transparent 65%),linear-gradient(to top,color-mix(in srgb,var(--color-text) 1.25%,transparent),transparent)}.dock-work-panel.body-scrolled-up .dock-work-head[data-v-6f1ea685]:after,.dock-work-panel.body-scrolled-down .dock-work-foot[data-v-6f1ea685]:before{opacity:1}.dock-work-body[data-v-6f1ea685] .taskspane{border:none;background:transparent;padding:0}.dock-work-body[data-v-6f1ea685] .taskspane .tp-head{display:none}.dock-workbar[data-v-6f1ea685]{display:flex;align-items:center;flex-wrap:wrap;gap:var(--space-1) 6px;padding:4px var(--dock-inline-right) 2px var(--dock-inline-left)}.dock-workbar[data-v-6f1ea685] .ui-pill{position:relative;height:var(--space-8);padding:0 var(--space-4);border:.5px solid var(--color-line-strong);border-radius:var(--radius-full);background:var(--color-surface);color:var(--color-text)}.dock-workbar[data-v-6f1ea685] .ui-pill:after{content:"";position:absolute;inset:0;border-radius:var(--radius-full);background:var(--color-hover);opacity:0;transition:opacity var(--duration-base) var(--ease-out);pointer-events:none}.dock-workbar[data-v-6f1ea685] .ui-pill:hover:not(:disabled):after{opacity:1}.dock-workbar[data-v-6f1ea685] .ui-pill.is-active{background:var(--color-accent-soft);color:var(--color-accent)}.dock-workbar .dw-count[data-v-6f1ea685]{margin-left:1px}.dock-workbar .dw-count b[data-v-6f1ea685]{font-weight:500}.dock-workbar .dw-goal-status[data-v-6f1ea685]{font-weight:var(--weight-medium)}.dock-workbar .dw-goal-status--active[data-v-6f1ea685]{color:var(--color-success)}.dock-workbar .dw-goal-status--paused[data-v-6f1ea685]{color:var(--color-warning)}.dock-workbar .dw-goal-status--blocked[data-v-6f1ea685]{color:var(--color-danger)}.dock-approval[data-v-6f1ea685]{margin-top:8px}.chat-dock.has-approval[data-v-6f1ea685]{display:flex;flex-direction:column;max-height:calc(100dvh - 72px)}.chat-dock.has-approval>.dock-workbar[data-v-6f1ea685]{flex:none}.chat-dock.has-approval>.dock-approval[data-v-6f1ea685]{min-height:0}@media(max-width:640px){.chat-dock[data-v-6f1ea685]{--dock-inline-left: max(12px, var(--safe-left));--dock-inline-right: max(12px, var(--safe-right))}.dock-work-panel[data-v-6f1ea685]{left:10px;right:calc(10px + var(--panes-scrollbar-width, 0px))}}.chat-dock[data-v-6f1ea685]:not(.align-mobile) .composer{padding-bottom:14px}.dock-panel-enter-active[data-v-6f1ea685],.dock-panel-leave-active[data-v-6f1ea685]{transition:opacity .16s ease,transform .16s ease}.dock-panel-enter-from[data-v-6f1ea685],.dock-panel-leave-to[data-v-6f1ea685]{opacity:0;transform:translateY(8px)}.conversation-toc[data-v-b8ba267a]{position:absolute;z-index:var(--z-sticky);top:50%;transform:translateY(-50%);--toc-content-max: min( var(--p-content-max), calc(100cqi - var(--space-5) - var(--space-5)) );left:calc(50% + (var(--toc-content-max) / 2) + 14px);max-height:calc(100% - 160px);display:flex;flex-direction:column;justify-content:center;opacity:.5;transition:opacity var(--duration-base) var(--ease-out)}.conversation-toc[data-v-b8ba267a]:before{content:"";position:absolute;inset:0 -48px 0 -14px;z-index:0}.conversation-toc[data-v-b8ba267a]:hover,.conversation-toc[data-v-b8ba267a]:focus-within{opacity:1}.conversation-toc[data-v-b8ba267a]:hover:not(:focus-within){transition-delay:var(--duration-hover-intent)}.toc-scroll[data-v-b8ba267a]{position:relative;z-index:1;display:flex;flex-direction:column;gap:7px;padding:8px 0;min-height:0;overflow-y:auto;scrollbar-width:none}.toc-scroll[data-v-b8ba267a]::-webkit-scrollbar{display:none}.toc-row[data-v-b8ba267a]{display:flex;align-items:center;gap:10px;height:18px;padding:0;border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);text-align:left;cursor:pointer;white-space:nowrap}.toc-row[data-v-b8ba267a]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.toc-bar[data-v-b8ba267a]{flex:none;width:3px;height:14px;border-radius:var(--radius-full);background:var(--color-accent);opacity:.3;transition:opacity var(--duration-fast) var(--ease-out),height var(--duration-fast) var(--ease-out)}.toc-label[data-v-b8ba267a]{display:block;max-width:0;overflow:hidden;opacity:0;text-overflow:ellipsis;transition:max-width .22s var(--ease-out),opacity var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.conversation-toc:hover .toc-bar[data-v-b8ba267a],.conversation-toc:focus-within .toc-bar[data-v-b8ba267a]{height:18px;opacity:.5}.conversation-toc:hover .toc-label[data-v-b8ba267a],.conversation-toc:focus-within .toc-label[data-v-b8ba267a]{max-width:220px;opacity:1}.conversation-toc:hover:not(:focus-within) .toc-bar[data-v-b8ba267a]{transition-delay:0ms,var(--duration-hover-intent)}.conversation-toc:hover:not(:focus-within) .toc-label[data-v-b8ba267a]{transition-delay:var(--duration-hover-intent),var(--duration-hover-intent),0ms}.toc-row.active .toc-bar[data-v-b8ba267a]{opacity:1;height:18px}.toc-row.active .toc-label[data-v-b8ba267a]{color:var(--color-accent);font-weight:var(--weight-medium)}.toc-row:hover .toc-bar[data-v-b8ba267a]{opacity:1}.toc-row:hover .toc-label[data-v-b8ba267a]{color:var(--color-text)}.conversation-toc.toc-clipped[data-v-b8ba267a]{visibility:hidden;pointer-events:none}.tsearch[data-v-26f3fed5]{position:absolute;top:calc(var(--panel-head-h, 48px) + var(--space-3));right:var(--space-3);z-index:var(--z-sticky);width:min(var(--p-findbar-w),calc(100% - var(--space-3) * 2));background:var(--color-surface-raised);border:var(--p-hairline) solid var(--color-line);border-radius:var(--radius-2xl);box-shadow:var(--shadow-menu);animation:kimi-card-in var(--duration-slow) var(--ease-out)}.tsearch.mobile[data-v-26f3fed5]{top:var(--space-3)}.tsearch[data-v-26f3fed5]:after{content:"";position:absolute;inset:0;border:inherit;border-color:var(--color-composer-focus-line);border-radius:var(--radius-2xl);opacity:0;pointer-events:none;transition:opacity var(--duration-slow) var(--ease-in-out)}.tsearch[data-v-26f3fed5]:focus-within:after{opacity:1}.tsearch-main[data-v-26f3fed5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-1) var(--space-2);min-height:calc(var(--space-8) + 2 * var(--space-1))}.tsearch-icon[data-v-26f3fed5]{flex:none;margin-left:var(--space-1);color:var(--color-text-muted)}.tsearch-input[data-v-26f3fed5]{flex:1;min-width:0;height:var(--space-8);padding:0;border:none;background:transparent;font-family:var(--font-ui);font-size:var(--ui-font-size);color:var(--color-text)}.tsearch-input[data-v-26f3fed5]:focus-visible{outline:none}.tsearch-input[data-v-26f3fed5]::placeholder{color:var(--color-text-muted)}.tsearch-spin[data-v-26f3fed5]{display:inline-flex;flex:none}.tsearch-sep[data-v-26f3fed5]{flex:none;width:var(--p-hairline);height:var(--space-4);background:var(--color-line)}.tsearch .tsearch-close[data-v-26f3fed5]{border-radius:var(--radius-full)}.tsearch-foot-wrap[data-v-26f3fed5]{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--duration-slow) var(--ease-out)}.tsearch-foot-wrap.open[data-v-26f3fed5]{grid-template-rows:1fr}.tsearch-foot[data-v-26f3fed5]{overflow:hidden;min-height:0;display:flex;align-items:center;gap:var(--space-1);padding:0 var(--space-2)}.tsearch-foot-wrap.open .tsearch-foot[data-v-26f3fed5]{padding:var(--space-1) var(--space-2);border-top:var(--p-hairline) solid var(--color-line)}.tsearch-count[data-v-26f3fed5]{margin-left:auto;padding-right:var(--space-1);font-size:var(--ui-font-size-sm);color:var(--color-text-muted);white-space:nowrap;user-select:none}.tsearch-rings[data-v-26f3fed5]{position:absolute;inset:0;pointer-events:none}.tsearch-ring[data-v-26f3fed5]{position:absolute;box-sizing:content-box;border:var(--p-findring-w) solid var(--color-warning);margin:calc(-1 * var(--p-findring-w));border-radius:var(--radius-xs);pointer-events:none}.doodle-host[data-v-b7d865dd]{position:relative;width:100%;aspect-ratio:338 / 152;display:flex;align-items:center;justify-content:center}.doodle-canvas[data-v-b7d865dd]{position:absolute;inset:0;width:100%;height:100%;display:block;opacity:0;transition:opacity .25s ease}.doodle-canvas.ready[data-v-b7d865dd]{opacity:1}@media(prefers-reduced-motion:reduce){.doodle-canvas[data-v-b7d865dd]{transition:none}}.con[data-v-2ddf1d39]{--read-max: 760px;display:flex;flex-direction:column;min-width:0;height:100%;position:relative;container-type:inline-size}.empty-drag[data-v-2ddf1d39]{position:absolute;top:0;left:0;right:0;height:var(--panel-head-h, 48px)}.empty-drag.macos-desktop[data-v-2ddf1d39]{-webkit-app-region:drag}.panes[data-v-2ddf1d39]{flex:1;min-height:0;overflow-y:auto;overflow-anchor:auto;scrollbar-gutter:stable}.panes[data-v-2ddf1d39]::-webkit-scrollbar{width:4px}.panes[data-v-2ddf1d39]::-webkit-scrollbar-thumb{background:transparent;transition:background var(--duration-base) var(--ease-out)}.panes.scrolling[data-v-2ddf1d39]::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.panes.scrolling[data-v-2ddf1d39]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.panes.session-settling .chat[data-v-2ddf1d39]>*:not(.chat-loading){visibility:hidden}.panes.is-following[data-v-2ddf1d39],.panes.history-prepending[data-v-2ddf1d39],.panes.is-pinned[data-v-2ddf1d39]{overflow-anchor:none}.chat-layout[data-v-2ddf1d39]{display:flex;flex-direction:column;height:100%;min-height:0;position:relative}.chat-scroll[data-v-2ddf1d39]{flex:1;min-height:0;position:relative}.content-wrap[data-v-2ddf1d39]{width:100%;max-width:var(--read-max);min-height:100%;box-sizing:border-box;padding-bottom:var(--chat-dock-height, 0px);display:flex;flex-direction:column;flex-shrink:0}.content-wrap.align-center[data-v-2ddf1d39]{margin-left:auto;margin-right:auto}.content-wrap.align-left[data-v-2ddf1d39]{margin-left:0;margin-right:auto}.content-wrap.align-mobile[data-v-2ddf1d39]{max-width:none}@media(max-width:640px){.con.mobile[data-v-2ddf1d39]{min-width:0;overflow:hidden}.con.mobile .panes[data-v-2ddf1d39]{scrollbar-gutter:auto;-webkit-overflow-scrolling:touch}.content-wrap.align-mobile[data-v-2ddf1d39]{width:100%;min-width:0}}.empty-spacer[data-v-2ddf1d39]{flex:1}.empty-hint[data-v-2ddf1d39]{flex:none;display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;padding:0 16px 16px;color:var(--color-text);font-family:var(--font-ui);user-select:none}.empty-hint-title[data-v-2ddf1d39]{font-size:calc(var(--ui-font-size) + 16px);font-optical-sizing:auto;font-weight:600}.empty-hint-title.is-starting[data-v-2ddf1d39]{display:inline-flex;align-items:center;gap:9px;color:var(--dim);font-weight:400}.empty-doodle[data-v-2ddf1d39]{width:min(340px,62vw)}.empty-hint-text[data-v-2ddf1d39]{display:inline-block;font-size:var(--text-base);color:var(--dim);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.upgrade-banner[data-v-2ddf1d39]{flex:none;display:flex;align-items:center;gap:var(--space-3);margin:0 var(--dock-inline-right, 16px) var(--space-2) var(--dock-inline-left, 16px);padding:var(--space-2) var(--space-3);border:.5px solid var(--color-accent-bd);border-radius:var(--radius-xl);background:var(--color-accent-soft)}.upgrade-banner-icon[data-v-2ddf1d39]{flex:none;color:var(--color-accent)}.upgrade-banner-text[data-v-2ddf1d39]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text)}.upgrade-banner-cta[data-v-2ddf1d39]{flex:none;display:inline-flex;align-items:center;gap:var(--space-1);padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-accent);cursor:pointer}.upgrade-banner-cta[data-v-2ddf1d39]:hover{color:var(--color-accent-hover)}.empty-composer[data-v-2ddf1d39] .composer-card{position:relative;z-index:var(--z-sticky)}.empty-composer[data-v-2ddf1d39]:not(.expanded) .ph{min-height:3lh}.ws-bar[data-v-2ddf1d39]{margin-top:calc(-1 * var(--space-4));padding:calc(var(--space-4) + var(--space-2)) var(--space-2) var(--space-2);background:color-mix(in srgb,var(--color-hover) 60%,transparent);border-radius:0 0 var(--radius-2xl) var(--radius-2xl);font-family:var(--font-ui)}.ws-anchor[data-v-2ddf1d39]{position:relative}.ws-chip[data-v-2ddf1d39]{display:inline-flex;align-items:center;gap:var(--space-2);max-width:100%;padding:var(--space-2) var(--space-3);background:none;border:none;border-radius:var(--radius-full);color:var(--color-text-muted);font-family:inherit;font-size:var(--ui-font-size-sm);cursor:pointer;transition:background var(--duration-base) var(--ease-out)}.ws-chip[data-v-2ddf1d39]:hover,.ws-chip.open[data-v-2ddf1d39]{background:var(--color-selected);color:var(--color-text)}.ws-chip[data-v-2ddf1d39]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ws-chip>.kw-icon[data-v-2ddf1d39]{flex:none}.ws-chip-name[data-v-2ddf1d39]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:var(--weight-option-label)}.ws-chip-chev[data-v-2ddf1d39]{flex:none;transition:transform var(--duration-base) var(--ease-out)}.ws-chip.open .ws-chip-chev[data-v-2ddf1d39]{transform:rotate(180deg)}.ws-chip.ws-ghost[data-v-2ddf1d39]{color:var(--color-text-muted)}.ws-chip.ws-ghost[data-v-2ddf1d39]:hover{color:var(--color-text)}.ws-backdrop[data-v-2ddf1d39]{position:fixed;inset:0;z-index:var(--z-sticky)}.ws-panel[data-v-2ddf1d39]{position:absolute;box-sizing:border-box;display:grid;grid-template-columns:minmax(0,1fr);left:0;top:calc(100% + var(--space-1));z-index:var(--z-dropdown);width:max-content;min-width:min(calc(var(--space-8) * 8),100%);max-width:100%;max-height:calc(var(--space-8) * 10);overflow:hidden auto;background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);border:.5px solid var(--color-line);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);padding:var(--space-1);animation:ws-pop-2ddf1d39 var(--duration-base) var(--ease-out)}.ws-panel.up[data-v-2ddf1d39]{top:auto;bottom:calc(100% + var(--space-1));animation-name:ws-pop-up-2ddf1d39}@keyframes ws-pop-2ddf1d39{0%{opacity:0;transform:translateY(calc(-1 * var(--space-1))) scale(.99)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes ws-pop-up-2ddf1d39{0%{opacity:0;transform:translateY(var(--space-1)) scale(.99)}to{opacity:1;transform:translateY(0) scale(1)}}.ws-caption[data-v-2ddf1d39]{padding:var(--space-1) var(--space-2);font-size:var(--text-xs);font-weight:var(--weight-medium);color:var(--color-text-faint);user-select:none}.ws-row[data-v-2ddf1d39]{display:flex;align-items:center;gap:var(--space-2);width:100%;text-align:left;background:none;border:none;border-radius:var(--radius-sm);padding:var(--space-1) var(--space-2);cursor:pointer;font-family:var(--font-ui)}.ws-row>.kw-icon[data-v-2ddf1d39]{flex:none;color:var(--muted)}.ws-row[data-v-2ddf1d39]:hover{background:var(--color-hover)}.ws-row.on[data-v-2ddf1d39]{background:var(--color-selected)}.ws-row[data-v-2ddf1d39]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.ws-info[data-v-2ddf1d39]{flex:1;min-width:0;display:flex;flex-direction:column}.ws-name[data-v-2ddf1d39]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);font-weight:var(--weight-option-label);color:var(--color-text);line-height:var(--leading-normal)}.ws-path[data-v-2ddf1d39]{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-xs);font-weight:var(--weight-option-label);color:var(--muted);line-height:var(--leading-normal)}.ws-check[data-v-2ddf1d39]{flex:none;margin-left:var(--space-3);color:var(--color-text)}.ws-divider[data-v-2ddf1d39]{height:1px;margin:var(--space-1) var(--space-2);background:var(--line)}.ws-action[data-v-2ddf1d39]{display:flex;align-items:center;gap:var(--space-2);width:100%;text-align:left;background:none;border:none;border-radius:var(--radius-sm);padding:var(--space-2);cursor:pointer;font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--dim)}.ws-action>.kw-icon[data-v-2ddf1d39]{flex:none;color:var(--muted)}.ws-action span[data-v-2ddf1d39]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ws-action[data-v-2ddf1d39]:hover{background:var(--color-hover);color:var(--color-text)}.ws-action:hover>.kw-icon[data-v-2ddf1d39]{color:var(--dim)}.ws-action[data-v-2ddf1d39]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.chat-scroll[data-v-2ddf1d39]{display:flex;flex-direction:column}.mobile .panes[data-v-2ddf1d39]:has(>.chat-layout){overflow:hidden;scrollbar-gutter:auto}.newmsg-pill[data-v-2ddf1d39]{position:absolute;left:50%;bottom:12px;transform:translate(-50%);display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:999px;border:.5px solid var(--line);background:var(--panel);color:var(--color-text);font-size:var(--text-xs);font-weight:var(--weight-ui-strong);cursor:pointer;box-shadow:var(--shadow-sm);z-index:var(--z-sticky)}.pill-chevron[data-v-2ddf1d39]{width:12px;height:12px}.pill-enter-active[data-v-2ddf1d39],.pill-leave-active[data-v-2ddf1d39]{transition:opacity .2s ease,transform .2s ease}.pill-enter-from[data-v-2ddf1d39],.pill-leave-to[data-v-2ddf1d39]{opacity:0;transform:translate(-50%) translateY(8px)}.undo-toast[data-v-2ddf1d39]{position:absolute;left:50%;top:60px;transform:translate(-50%);padding:8px 14px;border-radius:var(--radius-sm);background:var(--color-text);color:var(--bg);font-size:var(--ui-font-size-sm);z-index:var(--z-sticky);box-shadow:var(--shadow-sm)}.undo-toast-text[data-v-2ddf1d39]{display:flex;align-items:center;gap:8px}.undo-toast-enter-active[data-v-2ddf1d39],.undo-toast-leave-active[data-v-2ddf1d39]{transition:opacity .15s ease,transform .15s ease}.undo-toast-enter-from[data-v-2ddf1d39],.undo-toast-leave-to[data-v-2ddf1d39]{opacity:0;transform:translate(-50%) translateY(-6px)}.con[data-v-2ddf1d39]{background:var(--bg)}.newmsg-pill[data-v-2ddf1d39]{font-family:var(--sans)}.file-preview[data-v-4c55a361]{display:flex;flex-direction:column;height:100%;background:var(--bg);font-family:var(--mono);min-width:0;container-type:inline-size}.fp-empty[data-v-4c55a361],.fp-loading[data-v-4c55a361]{flex:1;display:flex;align-items:center;justify-content:center;gap:10px;color:var(--muted);font-size:var(--ui-font-size)}.fp-path[data-v-4c55a361]{flex:1 1 60px;min-width:40px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;direction:rtl;text-align:left;font-size:var(--ui-font-size-xs);color:var(--muted);font-weight:400}.fp-meta[data-v-4c55a361]{display:flex;align-items:center;gap:8px;flex:none}@container (max-width: 539px){.fp-meta[data-v-4c55a361]{display:none}}.fp-lines[data-v-4c55a361],.fp-size[data-v-4c55a361]{font-size:max(9px,calc(var(--ui-font-size) - 3.5px));color:var(--muted);white-space:nowrap}.fp-search[data-v-4c55a361]{display:flex;align-items:center;gap:4px;flex:1 1 110px;min-width:70px;max-width:200px}.fp-search-input[data-v-4c55a361]{flex:1;min-width:0;height:26px;border:.5px solid var(--color-line);border-radius:var(--radius-sm);padding:2px 7px;background:var(--color-surface-raised);color:var(--color-text);font:var(--text-xs) var(--font-mono)}.fp-search-count[data-v-4c55a361]{color:var(--muted);font-size:max(9px,calc(var(--ui-font-size) - 3.5px));min-width:18px;text-align:right}.fp-download[data-v-4c55a361]{display:inline-grid;place-items:center;width:26px;height:26px;flex:none;border-radius:var(--radius-sm);color:var(--color-text-muted)}.fp-download[data-v-4c55a361]:hover{background:var(--color-hover);color:var(--color-text)}.fp-download[data-v-4c55a361]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.fp-download svg[data-v-4c55a361]{width:var(--p-ic-sm);height:var(--p-ic-sm)}.fp-check[data-v-4c55a361]{color:var(--color-success)}.fp-body[data-v-4c55a361]{--fp-search-hit-bg: color-mix(in srgb, var(--star) 22%, var(--bg));--fp-search-active-bg: color-mix(in srgb, var(--star) 36%, var(--bg));flex:1;min-height:0;overflow:auto}.fp-markdown[data-v-4c55a361]{padding:16px 20px}.fp-code[data-v-4c55a361]{background:var(--bg)}.fp-code[data-v-4c55a361] .hl-row.hit,.fp-table tr.hit td[data-v-4c55a361]{background:var(--fp-search-hit-bg)}.fp-code[data-v-4c55a361] .hl-row.active,.fp-table tr.active td[data-v-4c55a361]{background:var(--fp-search-active-bg)}.fp-code[data-v-4c55a361] .hl-row.target,.fp-table tr.target th[data-v-4c55a361],.fp-table tr.target td[data-v-4c55a361]{background:var(--color-accent-soft)}.fp-html-frame[data-v-4c55a361],.fp-pdf-frame[data-v-4c55a361]{width:100%;height:100%;border:0;background:var(--color-surface-raised)}.fp-pdf-wrap[data-v-4c55a361]{background:var(--panel2)}.fp-table-wrap[data-v-4c55a361]{background:var(--bg)}.fp-table[data-v-4c55a361]{border-collapse:collapse;min-width:100%;font:var(--code-font-size)/var(--leading-normal) var(--mono)}.fp-table th[data-v-4c55a361]{position:sticky;left:0;z-index:1;width:44px;min-width:44px;padding:2px 8px;text-align:right;color:var(--faint);background:var(--panel);border-right:.5px solid var(--line2);user-select:none}.fp-table td[data-v-4c55a361]{padding:2px 10px;border-right:.5px solid var(--line2);border-bottom:.5px solid var(--line2);white-space:pre}.fp-image-wrap[data-v-4c55a361]{display:flex;align-items:center;justify-content:center;padding:24px;background:var(--panel2)}.fp-image[data-v-4c55a361]{max-width:100%;max-height:100%;object-fit:contain;border:.5px solid var(--line);border-radius:4px;background:var(--media-alpha-canvas)}.fp-image.actual[data-v-4c55a361]{max-width:none;max-height:none}.fp-binary-wrap[data-v-4c55a361]{display:flex;align-items:center;justify-content:center}.fp-binary-card[data-v-4c55a361]{display:flex;align-items:center;gap:12px;padding:20px 24px;border:.5px solid var(--line);border-radius:6px;background:var(--panel);color:var(--muted);font-size:var(--ui-font-size);margin:32px auto;max-width:480px}.fp-binary-icon[data-v-4c55a361]{color:var(--faint);flex:none}.fp-error[data-v-4c55a361]{flex-direction:column;padding:24px;text-align:center}@keyframes spin-4c55a361{to{transform:rotate(360deg)}}.spinner[data-v-4c55a361]{display:inline-block;width:14px;height:14px;border:.5px solid var(--line);border-top-color:var(--color-accent);border-radius:50%;animation:spin-4c55a361 .7s linear infinite}@media(max-width:640px){.fp-lines[data-v-4c55a361]{display:none}.fp-markdown[data-v-4c55a361]{padding:14px 16px}.fp-body.fp-code[data-v-4c55a361]{-webkit-overflow-scrolling:touch}}.fp-empty[data-v-4c55a361],.fp-loading[data-v-4c55a361]{font-family:var(--sans)}.fp-binary-card[data-v-4c55a361]{border:.5px solid var(--color-line);border-radius:var(--radius-md)}.fp-binary-label[data-v-4c55a361]{font-family:var(--sans)}.fp-image[data-v-4c55a361]{border-radius:var(--radius-md)}.seg-btn[data-v-4c55a361]{font-family:var(--sans)}.tp[data-v-afb1f46f]{height:100%;display:flex;flex-direction:column;min-height:0;background:var(--color-bg)}.tp-body[data-v-afb1f46f]{flex:1;min-height:0;overflow-y:auto;margin:0;padding:12px 14px;font:var(--text-base)/var(--leading-relaxed) var(--font-ui);font-weight:400;color:var(--color-text-muted);white-space:pre-wrap;word-break:break-word}.agent-panel[data-v-95fdb6f0]{height:100%;min-height:0;display:flex;flex-direction:column;background:var(--color-bg)}.agent-transcript[data-v-95fdb6f0]{flex:1;min-height:0;overflow-y:auto}.agent-transcript[data-v-95fdb6f0] .think-body,.agent-transcript[data-v-95fdb6f0] .ar-body,.agent-transcript[data-v-95fdb6f0] .tf-body,.agent-transcript[data-v-95fdb6f0] .bb,.agent-transcript[data-v-95fdb6f0] .tl-body{transition:none}.agent-error[data-v-95fdb6f0]{color:var(--color-danger);font:var(--text-sm)/var(--leading-normal) var(--font-ui)}.agent-fallback[data-v-95fdb6f0]{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4)}.sc[data-v-753d11f0]{height:100%;display:flex;flex-direction:column;min-height:0;background:var(--bg)}.sc-body[data-v-753d11f0]{flex:1;min-height:0;overflow-y:auto}.sc-empty[data-v-753d11f0]{padding:24px 16px;text-align:center;color:var(--muted);font-size:var(--ui-font-size)}.sc-composer[data-v-753d11f0]{flex:none;display:flex;align-items:flex-end;gap:6px;padding:8px 10px;border-top:.5px solid var(--color-line);background:var(--color-surface-raised)}.sc-input[data-v-753d11f0]{flex:1;min-width:0;resize:none;border:.5px solid var(--color-line);border-radius:var(--r-sm);padding:7px 9px;background:var(--bg);color:var(--color-text);font:var(--ui-font-size)/1.5 var(--sans);outline:none;max-height:160px}.sc-input[data-v-753d11f0]:focus{border-color:var(--color-accent-bd)}.sc-send[data-v-753d11f0]{flex:none;display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border:none;border-radius:var(--r-sm);background:var(--color-accent);color:var(--color-text-on-accent);cursor:pointer}.sc-send[data-v-753d11f0]:disabled{opacity:.4;cursor:default}.sc-send[data-v-753d11f0]:not(:disabled):hover{background:var(--color-accent-hover)}.sc-loading[data-v-753d11f0]{flex:none;padding:8px 12px 12px}.sc-body[data-v-753d11f0] .sending-placeholder,.sc-body[data-v-753d11f0] .sending-line{display:none}.changes-pane[data-v-7d5ab9c7]{display:flex;flex-direction:column;height:100%;background:var(--bg);font-family:var(--mono)}.dv-path[data-v-7d5ab9c7],.dv-change-count[data-v-7d5ab9c7]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-family:var(--mono);font-size:var(--ui-font-size-xs);color:var(--muted)}.dv-change-count[data-v-7d5ab9c7]{flex:1;align-self:stretch;display:inline-flex;align-items:center;font-family:var(--font-ui)}.dv-path[data-v-7d5ab9c7]{font-family:var(--font-ui)}.ch-head[data-v-7d5ab9c7]{display:flex;align-items:center;gap:8px;padding:8px var(--space-3);border-bottom:.5px solid var(--line);background:var(--panel);font-size:var(--text-base);color:var(--dim);flex:none;white-space:nowrap;overflow:hidden;font-family:var(--font-ui);user-select:none}.br-heading[data-v-7d5ab9c7]{display:inline-flex;align-items:center;gap:var(--space-1);flex:none}.br-icon[data-v-7d5ab9c7]{flex:none;color:var(--muted)}.br-label[data-v-7d5ab9c7]{color:var(--muted);font-size:var(--text-xs);font-weight:500}.br-name[data-v-7d5ab9c7]{color:var(--color-text);font-weight:500;font-size:var(--text-xs)}.sync-info[data-v-7d5ab9c7]{display:flex;align-items:center;gap:4px}.ahead[data-v-7d5ab9c7]{color:var(--color-accent);font-size:var(--text-xs)}.behind[data-v-7d5ab9c7]{color:var(--color-warning);font-size:var(--text-xs)}.empty-head[data-v-7d5ab9c7]{color:var(--muted);font-size:var(--text-base)}.ch-list[data-v-7d5ab9c7]{flex:1;min-height:0}.ch-list-content[data-v-7d5ab9c7]{min-height:100%;padding:4px 0}.ch-row[data-v-7d5ab9c7]{display:flex;align-items:center;gap:6px;padding:3px 8px;cursor:pointer;font-size:var(--text-xs);line-height:1.6;width:100%;background:none;border:none;text-align:left;font-family:var(--font-ui);color:inherit}.ch-row[data-v-7d5ab9c7]:hover{background:var(--panel2)}.ch-row[data-v-7d5ab9c7]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.ch-tree[data-v-7d5ab9c7]{--tree-base-indent: 14px;--tree-indent-step: 12px;font-family:var(--font-ui)}.tree-list[data-v-7d5ab9c7]{list-style:none;margin:0}.tree-node[data-v-7d5ab9c7]{overflow:hidden;interpolate-size:allow-keywords}.tree-collapse-enter-active[data-v-7d5ab9c7],.tree-collapse-leave-active[data-v-7d5ab9c7]{transition:block-size var(--duration-base) var(--ease-out),opacity var(--duration-fast) var(--ease-out),transform var(--duration-base) var(--ease-out)}.tree-collapse-enter-from[data-v-7d5ab9c7],.tree-collapse-leave-to[data-v-7d5ab9c7]{block-size:0;opacity:0;transform:translateY(-3px)}.tree-collapse-enter-to[data-v-7d5ab9c7],.tree-collapse-leave-from[data-v-7d5ab9c7]{block-size:auto;opacity:1;transform:translateY(0)}.tree-row[data-v-7d5ab9c7]{position:relative;display:flex;align-items:center;gap:6px;width:100%;margin-top:1px;padding:3px 8px;background:none;border:none;text-align:left;font-family:inherit;font-size:var(--text-xs);color:inherit;cursor:pointer}.tree-row[data-v-7d5ab9c7]:before{content:"";position:absolute;top:0;bottom:0;left:calc(var(--tree-base-indent) + 6px);width:calc(var(--tree-depth, 0) * var(--tree-indent-step));background:repeating-linear-gradient(to right,var(--color-line) 0 1px,transparent 1px var(--tree-indent-step));pointer-events:none}.tree-row[data-v-7d5ab9c7]:hover{background:var(--panel2)}.tree-row[data-v-7d5ab9c7]:focus-visible{outline:2px solid var(--color-accent);outline-offset:-2px}.tree-folder[data-v-7d5ab9c7]{color:var(--color-text);font-weight:500}.tree-file[data-v-7d5ab9c7]{color:var(--color-text);font-weight:450}.tree-icon[data-v-7d5ab9c7]{flex:none;color:var(--muted)}.tree-name[data-v-7d5ab9c7]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.badge[data-v-7d5ab9c7]{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:var(--radius-xs);font-size:max(9px,calc(var(--ui-font-size) - 4px));font-weight:500;flex:none;user-select:none}.badge.modified[data-v-7d5ab9c7]{background:var(--color-warning-soft);color:var(--color-warning)}.badge.added[data-v-7d5ab9c7]{background:var(--color-success-soft);color:var(--color-success)}.badge.deleted[data-v-7d5ab9c7]{background:var(--color-danger-soft);color:var(--color-danger)}.badge.renamed[data-v-7d5ab9c7]{background:var(--color-done-soft);color:var(--color-done)}.badge.untracked[data-v-7d5ab9c7]{background:var(--color-success-soft);color:var(--color-success)}.badge.conflicted[data-v-7d5ab9c7]{background:color-mix(in srgb,var(--color-danger) 10%,var(--bg));color:var(--color-danger);font-size:max(9px,calc(var(--ui-font-size) - 5px))}.badge.ignored[data-v-7d5ab9c7]{background:var(--color-well);color:var(--faint)}.badge.clean[data-v-7d5ab9c7]{background:transparent;color:var(--faint)}.badge.unknown[data-v-7d5ab9c7]{background:var(--color-well);color:var(--muted)}.fpath[data-v-7d5ab9c7]{color:var(--color-text);font-size:var(--text-xs);font-weight:450;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;direction:rtl;text-align:left;min-width:0}.fpath[data-v-7d5ab9c7]:before,.fpath[data-v-7d5ab9c7]:after{content:"‎"}.empty-state[data-v-7d5ab9c7]{flex:1;min-height:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-2);padding:32px 20px;color:var(--muted);font-size:var(--ui-font-size);text-align:center;user-select:none}.empty-state-icon[data-v-7d5ab9c7]{display:inline-flex;align-items:center;justify-content:center;width:32px;height:32px;border-radius:50%;background:var(--color-well);color:var(--color-text-muted)}.diff-head[data-v-7d5ab9c7]{display:flex;align-items:center;gap:10px;padding:6px 12px;border-bottom:.5px solid var(--line);background:var(--panel);flex:none;white-space:nowrap;overflow:hidden}.dv-lines-wrap[data-v-7d5ab9c7]{flex:1;min-height:0;overflow:auto}.diff-content-enter-active[data-v-7d5ab9c7],.diff-content-leave-active[data-v-7d5ab9c7]{transition:opacity var(--duration-base) var(--ease-out)}.diff-content-enter-from[data-v-7d5ab9c7],.diff-content-leave-to[data-v-7d5ab9c7]{opacity:0}@media(max-width:640px){.ch-head[data-v-7d5ab9c7]{padding:10px 14px}.ch-list[data-v-7d5ab9c7]{padding:2px 0 12px}.ch-row[data-v-7d5ab9c7]{min-height:44px;padding:8px 14px;gap:12px;font-size:var(--text-xs)}.ch-row[data-v-7d5ab9c7]:active{background:var(--panel2)}.badge[data-v-7d5ab9c7]{width:18px;height:18px}.fpath[data-v-7d5ab9c7]{font-size:var(--text-xs)}.tree-row[data-v-7d5ab9c7]{min-height:40px;padding:8px 14px}.diff-head[data-v-7d5ab9c7]{padding:8px 12px;gap:10px}.diff-path[data-v-7d5ab9c7]{font-size:var(--text-base)}}.changes-pane .empty-state[data-v-7d5ab9c7],.br-label[data-v-7d5ab9c7],.empty-head[data-v-7d5ab9c7]{font-family:var(--sans)}.ch-row[data-v-7d5ab9c7],.ct-row[data-v-7d5ab9c7]{margin:1px 6px;width:calc(100% - 12px);border-radius:var(--radius-md)}.changes-pane .badge[data-v-7d5ab9c7],.changed-tree .badge[data-v-7d5ab9c7]{border-radius:var(--radius-sm)}.change-count[data-v-7d5ab9c7]{font-family:var(--sans);border-radius:999px}.td[data-v-fdd0bc05]{display:flex;flex-direction:column;height:100%;min-height:0}.td-path[data-v-fdd0bc05]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:var(--ui-c1) var(--font-mono);color:var(--color-text-muted)}.td-body[data-v-fdd0bc05]{flex:1;min-height:0;overflow:auto}.td-empty[data-v-fdd0bc05]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);height:100%;padding:var(--space-6);color:var(--color-text-muted);font-size:var(--text-sm);text-align:center}.mp[data-v-3ba22330]{display:flex;flex-direction:column;gap:var(--space-2);height:100%;min-height:0;padding-top:4px}.search-wrap[data-v-3ba22330]{position:relative;margin:0 22px;padding-bottom:var(--space-1)}.search-wrap[data-v-3ba22330] .ui-input{padding-right:30px}.search-clear[data-v-3ba22330]{position:absolute;top:0;bottom:var(--space-1);right:var(--space-2);margin-block:auto;display:flex;align-items:center;justify-content:center;width:18px;height:18px;padding:0;border:none;border-radius:var(--radius-full);background:var(--color-hover);color:var(--color-text-faint);cursor:pointer;visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast),background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.search-clear.is-on[data-v-3ba22330]{visibility:visible;opacity:1}.search-clear[data-v-3ba22330]:hover{background:var(--color-selected);color:var(--color-text-muted)}.search-clear[data-v-3ba22330]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.chip-strip[data-v-3ba22330]{display:flex;gap:var(--space-1);margin:0 22px;overflow-x:auto;scrollbar-width:none}.chip-strip[data-v-3ba22330]::-webkit-scrollbar{display:none}.chip[data-v-3ba22330]{flex:none;height:28px;padding:0 var(--space-3);border:none;border-radius:var(--radius-full);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base);white-space:nowrap;cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.chip[data-v-3ba22330]:hover{background:var(--color-hover);color:var(--color-text)}.chip.is-active[data-v-3ba22330]{background:var(--color-selected);color:var(--color-text);font-weight:var(--weight-medium)}.chip[data-v-3ba22330]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.model-list[data-v-3ba22330]{display:flex;flex-direction:column;flex:1;min-height:0;overflow-y:auto;padding:var(--space-1) var(--space-2)}.model-row[data-v-3ba22330]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);cursor:pointer;color:var(--color-text);min-width:0;transition:background var(--duration-fast) var(--ease-out)}.model-row[data-v-3ba22330]:hover,.model-row.is-selected[data-v-3ba22330]{background:var(--color-hover)}.model-row.is-current[data-v-3ba22330]{background:var(--color-selected)}.model-main[data-v-3ba22330]{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}.model-name[data-v-3ba22330]{font-family:var(--font-ui);font-size:var(--text-base);line-height:20px;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.model-row.is-current .model-name[data-v-3ba22330]{font-weight:var(--weight-medium)}.model-meta[data-v-3ba22330]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:18px;color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.model-side[data-v-3ba22330]{display:flex;align-items:center;gap:var(--space-1);flex:none}.model-check[data-v-3ba22330]{color:var(--color-text)}.model-star[data-v-3ba22330]{color:var(--color-text-faint);visibility:hidden;opacity:0;transition:opacity var(--duration-fast) var(--ease-out),visibility var(--duration-fast)}.model-row:hover .model-star[data-v-3ba22330],.model-row.is-selected .model-star[data-v-3ba22330],.model-star.is-starred[data-v-3ba22330],.model-star[data-v-3ba22330]:focus-visible{visibility:visible;opacity:1}.model-star.is-starred[data-v-3ba22330]{color:var(--star)}@media(hover:none){.model-star[data-v-3ba22330]{visibility:visible;opacity:1}}.state-row[data-v-3ba22330]{flex:1;min-height:0;display:flex;align-items:center;justify-content:center;gap:var(--space-2);color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.state-row.unavail[data-v-3ba22330]{color:var(--color-warning)}.empty[data-v-3ba22330]{flex:1;display:flex;align-items:center;justify-content:center;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.footer-hint[data-v-3ba22330]{flex:none;display:flex;align-items:center;gap:var(--space-1);padding:var(--space-2) var(--space-4);border-top:.5px solid var(--color-line);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.hint-dot[data-v-3ba22330]{margin:0 var(--space-1)}@media(prefers-reduced-motion:reduce){.chip[data-v-3ba22330],.model-row[data-v-3ba22330],.model-star[data-v-3ba22330],.search-clear[data-v-3ba22330]{transition:none}}.center-body[data-v-c798a107]{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);padding:var(--space-8) 0 var(--space-4);text-align:center}.center-text[data-v-c798a107]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.success-text[data-v-c798a107]{color:var(--color-success)}.err-text[data-v-c798a107]{color:var(--color-danger)}.warn-text[data-v-c798a107]{color:var(--color-warning);font-size:var(--text-base)}.center-hint[data-v-c798a107]{font-size:var(--text-sm);color:var(--color-text-muted)}.nb[data-v-c798a107]{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-2) 0 var(--space-4)}.nb-lead[data-v-c798a107]{font-size:var(--text-base);color:var(--color-text);line-height:var(--leading-normal)}.nb-primary[data-v-c798a107]{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);width:100%;min-height:40px;padding:0 var(--space-4);background:var(--color-accent);color:var(--color-text-on-accent);border:.5px solid var(--color-accent);border-radius:var(--radius-md);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);cursor:pointer;text-decoration:none;transition:background var(--duration-fast) var(--ease-out),border-color var(--duration-fast) var(--ease-out)}.nb-primary[data-v-c798a107]:hover{background:var(--color-accent-hover);border-color:var(--color-accent-hover)}.nb-or[data-v-c798a107]{display:flex;align-items:center;gap:var(--space-3);color:var(--color-text-muted);font-size:var(--text-xs);letter-spacing:.06em}.nb-or[data-v-c798a107]:before,.nb-or[data-v-c798a107]:after{content:"";flex:1;height:1px;background:var(--color-line)}.nb-fallback[data-v-c798a107]{display:flex;flex-direction:column;gap:var(--space-2)}.nb-fb-text[data-v-c798a107]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.nb-fb-link[data-v-c798a107]{color:var(--color-accent);text-decoration:none;border-bottom:.5px solid var(--color-accent-bd)}.nb-fb-link[data-v-c798a107]:hover{border-bottom-color:var(--color-accent)}.nb-code-row[data-v-c798a107]{display:flex;align-items:center;gap:var(--space-3);background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3)}.nb-code[data-v-c798a107]{flex:1;font-family:var(--font-mono);font-size:var(--text-xl);font-weight:var(--weight-medium);color:var(--color-text);letter-spacing:.14em}.nb-link[data-v-c798a107]{flex:1;min-width:0;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:text}.nb-copy.is-copied[data-v-c798a107]{color:var(--color-success);border-color:var(--color-success-bd)}.nb-status[data-v-c798a107]{display:flex;align-items:center;gap:var(--space-2);padding-top:var(--space-3);border-top:.5px solid var(--color-line)}.nb-status-text[data-v-c798a107]{font-family:var(--font-mono);font-size:var(--text-sm);color:var(--color-text-muted);flex:1}.nb-countdown[data-v-c798a107]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums}.actions[data-v-c798a107]{display:flex;justify-content:flex-end;gap:var(--space-3);padding-top:var(--space-4)}@media(max-width:640px){.center-body[data-v-c798a107],.nb[data-v-c798a107]{overflow-y:auto;-webkit-overflow-scrolling:touch}.nb-code-row[data-v-c798a107],.nb-status[data-v-c798a107],.actions[data-v-c798a107]{flex-wrap:wrap}.nb-code[data-v-c798a107]{min-width:0;overflow-wrap:anywhere;letter-spacing:.08em}.nb-copy[data-v-c798a107]{min-height:34px}.nb-primary[data-v-c798a107]{min-height:44px}.nb-status-text[data-v-c798a107]{min-width:0}}.pf-form[data-v-ac0597e3]{display:flex;flex-direction:column;gap:var(--space-4);padding:var(--space-4) var(--space-4) var(--space-5);border-top:.5px solid var(--color-line)}.pf-guard[data-v-ac0597e3] .ui-banner__text{display:flex;align-items:center;gap:var(--space-2);width:100%}.pf-guard .msg[data-v-ac0597e3]{flex:1}.pf-field[data-v-ac0597e3]{display:flex;flex-direction:column;gap:6px}.pf-key-wrap[data-v-ac0597e3]{position:relative}.pf-key-wrap[data-v-ac0597e3] .ui-input{padding-right:calc(var(--icon-button-sm) + var(--space-2))}.pf-key-eye[data-v-ac0597e3]{position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%)}.pf-field-label[data-v-ac0597e3]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.req[data-v-ac0597e3]{color:var(--color-danger)}.pf-models[data-v-ac0597e3]{display:flex;flex-direction:column;gap:var(--space-2)}.pf-model-grid[data-v-ac0597e3]{display:grid;grid-template-columns:minmax(0,2fr) minmax(0,1fr) minmax(0,2fr) auto;gap:var(--space-2);align-items:center}.pf-model-head span[data-v-ac0597e3]{font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint)}.pf-models-empty[data-v-ac0597e3]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.pf-foot[data-v-ac0597e3]{display:flex;align-items:center;gap:var(--space-2);padding-top:var(--space-4);border-top:.5px solid var(--color-line)}.pf-foot .spacer[data-v-ac0597e3]{flex:1}.pf-confirm-msg[data-v-ac0597e3]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-danger)}.pf-managed-note[data-v-ac0597e3]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}@media(max-width:640px){.pf-model-grid[data-v-ac0597e3]{grid-template-columns:minmax(0,1fr) auto}}.af[data-v-9e5ec0a8]{display:flex;flex-direction:column;gap:var(--space-3);padding:var(--space-4) var(--space-4) var(--space-5);border-top:.5px solid var(--color-line)}.af-guard[data-v-9e5ec0a8] .ui-banner__text{display:flex;align-items:center;gap:var(--space-2);width:100%}.af-guard .msg[data-v-9e5ec0a8]{flex:1}.af-catalog[data-v-9e5ec0a8]{display:flex;flex-direction:column;gap:var(--space-3)}.af-center[data-v-9e5ec0a8]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4) 0;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.af-error[data-v-9e5ec0a8]{display:flex;flex-direction:column;align-items:flex-start;gap:var(--space-2)}.af-list[data-v-9e5ec0a8]{display:flex;flex-direction:column;max-height:320px;overflow-y:auto;border:.5px solid var(--color-line);border-radius:var(--radius-md)}.af-list[data-v-9e5ec0a8]>*+*{border-top:.5px solid var(--color-line)}.af-entry[data-v-9e5ec0a8]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:34px;padding:var(--space-1) var(--space-3);border:none;background:transparent;text-align:left;font-family:var(--font-ui);color:var(--color-text);cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.af-entry[data-v-9e5ec0a8]:hover:not(:disabled){background:var(--color-hover)}.af-entry[data-v-9e5ec0a8]:disabled{cursor:not-allowed;opacity:.55}.af-entry-name[data-v-9e5ec0a8]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--text-base);font-weight:var(--weight-medium)}.af-entry .grow[data-v-9e5ec0a8]{flex:1;min-width:0}.af-entry-count[data-v-9e5ec0a8],.af-entry-reason[data-v-9e5ec0a8]{flex:none;font-size:var(--text-xs);color:var(--color-text-faint);white-space:nowrap}.af-empty[data-v-9e5ec0a8]{padding:var(--space-4);text-align:center;color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm)}.af-import[data-v-9e5ec0a8],.af-registry[data-v-9e5ec0a8]{display:flex;flex-direction:column;gap:var(--space-4)}.af-hint[data-v-9e5ec0a8]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.af-back[data-v-9e5ec0a8]{display:inline-flex;align-items:center;gap:var(--space-1);align-self:flex-start;padding:0;border:none;background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);cursor:pointer;transition:color var(--duration-fast) var(--ease-out)}.af-back[data-v-9e5ec0a8]:hover{color:var(--color-text)}.af-field[data-v-9e5ec0a8]{display:flex;flex-direction:column;gap:6px}.af-label[data-v-9e5ec0a8]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted)}.req[data-v-9e5ec0a8]{color:var(--color-danger)}.af-key-wrap[data-v-9e5ec0a8]{position:relative}.af-key-wrap[data-v-9e5ec0a8] .ui-input{padding-right:calc(var(--icon-button-sm) + var(--space-2))}.af-key-eye[data-v-9e5ec0a8]{position:absolute;right:var(--space-1);top:50%;transform:translateY(-50%)}.af-note[data-v-9e5ec0a8]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.af-foot[data-v-9e5ec0a8]{display:flex;align-items:center;justify-content:flex-end;gap:var(--space-2);padding-top:var(--space-4);border-top:.5px solid var(--color-line)}.af-manual[data-v-9e5ec0a8] .pf-form{padding:0;border-top:none}.pp[data-v-9aa0e3a8]{display:flex;flex-direction:column}.pp-head[data-v-9aa0e3a8]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}.pp-title[data-v-9aa0e3a8]{margin:0;font-family:var(--font-ui);font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.pp-loading[data-v-9aa0e3a8]{display:flex;align-items:center;justify-content:center;gap:var(--space-2);padding:var(--space-4) 0;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-base)}.pp-group[data-v-9aa0e3a8]{overflow:hidden;border:.5px solid var(--color-line);border-radius:var(--radius-xl);background:var(--color-surface-raised)}.pp-group[data-v-9aa0e3a8]:has(.ui-select.is-open){position:relative;z-index:var(--z-dropdown);overflow:visible}.pp-group[data-v-9aa0e3a8]>*+*{border-top:.5px solid var(--color-line)}.pp-row[data-v-9aa0e3a8]{display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:40px;padding:var(--space-2) var(--space-4);border:none;background:transparent;text-align:left;font-family:var(--font-ui);color:var(--color-text);cursor:pointer;transition:background var(--duration-fast) var(--ease-out)}.pp-row[data-v-9aa0e3a8]:hover{background:var(--color-hover)}.pp-item.open>.pp-row[data-v-9aa0e3a8]{background:var(--color-surface-sunken)}.pp-row .grow[data-v-9aa0e3a8]{flex:1;min-width:0;display:flex;align-items:center;gap:var(--space-2)}.pp-id[data-v-9aa0e3a8]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.pp-count[data-v-9aa0e3a8]{flex:none;font-size:var(--text-xs);color:var(--color-text-faint);white-space:nowrap}.pp-chev[data-v-9aa0e3a8]{display:inline-flex;flex:none;color:var(--color-text-faint);transition:transform var(--duration-base) var(--ease-out)}.pp-item.open .pp-chev[data-v-9aa0e3a8]{transform:rotate(90deg)}.pp-add-row[data-v-9aa0e3a8]{gap:var(--space-2);color:var(--color-text);font-size:var(--text-base);font-weight:var(--weight-medium)}.pp-acc[data-v-9aa0e3a8]{display:grid;grid-template-rows:0fr;transition:grid-template-rows var(--duration-slow) var(--ease-out)}.pp-item.open>.pp-acc[data-v-9aa0e3a8]{grid-template-rows:1fr}.pp-acc-in[data-v-9aa0e3a8]{overflow:hidden;min-height:0}.pp-item.open .pp-acc-in[data-v-9aa0e3a8]{overflow:visible}.pp-item.flash>.pp-row[data-v-9aa0e3a8]{animation:pp-flash-9aa0e3a8 1.2s var(--ease-out)}@keyframes pp-flash-9aa0e3a8{0%{background:var(--color-accent-soft)}to{background:transparent}}.pp-empty[data-v-9aa0e3a8]{padding:var(--space-5) var(--space-4);color:var(--color-text-faint);font-family:var(--font-ui);font-size:var(--text-sm);text-align:center}.sec[data-v-5711dff8]{margin-bottom:var(--space-5)}.sec-title[data-v-5711dff8]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);margin:0 0 var(--space-3)}.pu-group[data-v-5711dff8]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.pu-row[data-v-5711dff8]{display:flex;align-items:center;gap:var(--space-3);min-height:52px;padding:var(--space-3) var(--space-4)}.pu-main[data-v-5711dff8]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.pu-label[data-v-5711dff8]{font-size:var(--text-sm);color:var(--color-text)}.pu-hint[data-v-5711dff8]{font-size:var(--text-xs);color:var(--color-text-faint)}.sec[data-v-f39cdded]{margin-bottom:var(--space-5)}.sec-title[data-v-f39cdded]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text);margin:0 0 var(--space-3)}.pu-group[data-v-f39cdded]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.pu-row[data-v-f39cdded]{display:flex;align-items:center;gap:var(--space-3);min-height:52px;padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.pu-row[data-v-f39cdded]:first-child{border-top:none}.pu-state[data-v-f39cdded]{color:var(--color-text-muted);font-size:var(--text-sm)}.pu-error-text[data-v-f39cdded]{flex:1;min-width:0}.pu-empty[data-v-f39cdded]{color:var(--color-text-faint)}.pu-main[data-v-f39cdded]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.pu-label[data-v-f39cdded]{font-size:var(--text-sm);color:var(--color-text)}.pu-hint[data-v-f39cdded]{font-size:var(--text-xs);color:var(--color-text-faint)}.pu-value[data-v-f39cdded]{flex:none;font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);font-variant-numeric:tabular-nums;white-space:nowrap}.pu-value-sub[data-v-f39cdded]{font-weight:var(--weight-regular);color:var(--color-text-faint)}.pu-meter[data-v-f39cdded]{flex:none;width:120px;height:5px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden}.pu-meter i[data-v-f39cdded]{display:block;height:100%;border-radius:var(--radius-full);background:var(--color-accent);transition:width var(--duration-base) var(--ease-out)}.pu-meter i.sev-warn[data-v-f39cdded]{background:var(--color-warning)}.pu-meter i.sev-danger[data-v-f39cdded]{background:var(--color-danger)}.sm-picker[data-v-f114c246]{position:relative;width:100%;font-family:var(--font-ui)}.sm-picker__trigger[data-v-f114c246]{display:flex;align-items:center;gap:var(--space-2);width:100%;height:38px;padding:0 var(--space-3);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:transparent;box-shadow:none;color:var(--color-text);font:inherit;font-size:var(--text-base);line-height:var(--leading-normal);text-align:left;cursor:pointer;transition:border-color var(--duration-base) var(--ease-out),box-shadow var(--duration-base) var(--ease-out),background var(--duration-base) var(--ease-out)}.sm-picker__trigger[data-v-f114c246]:focus-visible,.sm-picker.is-open .sm-picker__trigger[data-v-f114c246]{outline:none;border-color:var(--color-accent);box-shadow:var(--p-focus-ring)}.sm-picker__value[data-v-f114c246]{min-width:0;flex:1;display:flex;align-items:center;overflow:hidden;white-space:nowrap}.sm-picker__value-text[data-v-f114c246]{min-width:0;overflow:hidden;text-overflow:ellipsis}.sm-picker__value.is-placeholder[data-v-f114c246]{color:var(--color-text-faint)}.sm-picker__chevron[data-v-f114c246]{flex:none;color:var(--color-text-muted);transition:transform var(--duration-base) var(--ease-out)}.sm-picker.is-open .sm-picker__chevron[data-v-f114c246]{transform:rotate(180deg)}.sm-picker__menu[data-v-f114c246]{position:fixed;z-index:var(--z-modal-dropdown);width:252px;max-width:calc(100vw - 64px);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.sm-picker__models[data-v-f114c246]{max-height:280px;overflow-y:auto;padding:var(--space-1);border-radius:var(--radius-md)}.sm-picker__flyout[data-v-f114c246]{position:absolute;width:180px;max-height:280px;overflow-y:auto;padding:var(--space-1);border:.5px solid var(--color-line-strong);border-radius:var(--radius-md);background:var(--color-menu-bg);-webkit-backdrop-filter:var(--p-menu-backdrop);backdrop-filter:var(--p-menu-backdrop);box-shadow:var(--shadow-lg)}.sm-picker__flyout--right[data-v-f114c246]{left:calc(100% + var(--space-1))}.sm-picker__flyout--left[data-v-f114c246]{right:calc(100% + var(--space-1))}.sm-picker__group[data-v-f114c246]{padding:var(--space-2) var(--space-2) var(--space-1);color:var(--color-text-faint);font-size:var(--text-xs);font-weight:var(--weight-medium)}.sm-picker__option[data-v-f114c246]{display:flex;align-items:center;gap:var(--space-2);width:100%;min-height:32px;padding:var(--space-1) var(--space-2);border:none;border-radius:var(--radius-sm);background:transparent;color:var(--color-text);font:inherit;font-size:var(--text-sm);text-align:left;cursor:pointer}.sm-picker__option.is-active[data-v-f114c246]{background:var(--color-hover);color:var(--color-text-strong)}.sm-picker__option.is-muted[data-v-f114c246]{color:var(--color-text-muted)}.sm-picker__option-label[data-v-f114c246]{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-picker__check[data-v-f114c246]{flex:none;color:transparent}.sm-picker__option.is-selected .sm-picker__check[data-v-f114c246]{color:var(--color-accent)}.sm-picker__flyout-caret[data-v-f114c246]{flex:none;margin-left:auto;color:var(--color-text-faint)}.sd[data-v-146a8c47]{display:grid;grid-template-columns:148px 1fr;grid-template-areas:"tabs region";min-height:0;height:100%;user-select:none}.sd[data-v-146a8c47] :is(input,textarea,[contenteditable=true]){user-select:text}.settings-region[data-v-146a8c47]{display:flex;min-width:0;min-height:0;flex-direction:column;grid-area:region}.settings-region-header[data-v-146a8c47],.settings-tabs-header[data-v-146a8c47]{display:flex;align-items:center;height:calc(var(--space-4) + var(--icon-button-sm) + var(--space-2));box-sizing:border-box}.settings-region-header[data-v-146a8c47]{justify-content:flex-end;padding-right:var(--space-5)}.settings-tabs-header[data-v-146a8c47]{padding-inline:var(--space-3)}.settings-dialog-title[data-v-146a8c47]{margin:0;font-family:var(--font-ui);font-size:var(--text-lg);font-weight:var(--weight-medium);line-height:var(--leading-tight);color:var(--color-text)}.settings-tabs[data-v-146a8c47]{display:flex;flex-direction:column;width:148px;padding:0 var(--space-2) var(--space-2);gap:2px;overflow-y:auto;border-right:.5px solid var(--color-line);grid-area:tabs}.settings-tab-list[data-v-146a8c47]{display:flex;flex-direction:column;gap:2px}.tab[data-v-146a8c47]{display:flex;align-items:center;gap:var(--space-2);text-align:left;padding:8px 10px;border:none;border-radius:var(--radius-md);background:transparent;color:var(--color-text-muted);font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-ui-strong);cursor:pointer;transition:background var(--duration-fast) var(--ease-out),color var(--duration-fast) var(--ease-out)}.tab[data-v-146a8c47]:hover{background:var(--color-hover);color:var(--color-text-strong)}.tab.on[data-v-146a8c47]{background:var(--color-hover);color:var(--color-text)}.tab[data-v-146a8c47]:focus-visible{outline:none;box-shadow:var(--p-focus-ring)}.body[data-v-146a8c47]{display:flex;flex-direction:column;overflow-y:auto;padding:var(--space-2) 32px var(--space-5);flex:1;min-width:0}.body[data-v-146a8c47]::-webkit-scrollbar{width:4px}.body[data-v-146a8c47]::-webkit-scrollbar-track{background:transparent}.body[data-v-146a8c47]::-webkit-scrollbar-thumb{background:transparent;border-radius:var(--radius-full);transition:background var(--duration-base) var(--ease-out)}.body.scrolling[data-v-146a8c47]::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent)}.body.scrolling[data-v-146a8c47]::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}.panel[data-v-146a8c47]{display:block}.sec[data-v-146a8c47]{padding:var(--space-4) 0}.panel>.sec[data-v-146a8c47]:first-child{padding-top:0}.sec-head[data-v-146a8c47]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);margin-bottom:var(--space-3)}.sec-title[data-v-146a8c47]{margin:0 0 var(--space-3);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);letter-spacing:0;color:var(--color-text)}.notification-settings[data-v-146a8c47]{user-select:none}.sec-head .sec-title[data-v-146a8c47]{margin-bottom:0}.row[data-v-146a8c47]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);min-height:38px;padding:var(--space-1) 0}.settings-group[data-v-146a8c47]{overflow:hidden;border-radius:var(--radius-xl);background:var(--color-surface)}.settings-group[data-v-146a8c47]:has(.ui-select.is-open){position:relative;z-index:var(--z-dropdown);overflow:visible}.settings-group>.row[data-v-146a8c47]{min-height:52px;padding:var(--space-4);border-top:.5px solid var(--color-line)}.settings-group>.row[data-v-146a8c47]:first-child{border-top:none}.settings-group>.empty-config[data-v-146a8c47]{padding:var(--space-3)}.account-row[data-v-146a8c47]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4)}.account-avatar[data-v-146a8c47]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border-radius:50%;background:var(--color-surface-sunken);color:var(--color-text-muted)}.account-avatar img[data-v-146a8c47]{width:100%;height:100%;border-radius:50%;object-fit:cover}.account-name-row[data-v-146a8c47]{display:flex;align-items:center;gap:var(--space-2);min-width:0}.account-level[data-v-146a8c47]{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}.account-meta[data-v-146a8c47]{display:flex;flex:1;min-width:0;flex-direction:column;gap:2px}.account-name[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.account-sub[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rlabel[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text);font-weight:var(--weight-option-label);display:flex;flex-direction:column;gap:0}.rvalue[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-muted);max-width:60%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.rvalue.mono[data-v-146a8c47]{font-family:var(--font-mono);font-size:var(--text-xs)}.hint[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-tight);color:var(--color-text-faint)}.body[data-v-146a8c47] .ui-seg,.body[data-v-146a8c47] .ui-select__trigger,.body[data-v-146a8c47] .ui-button,.archive-search[data-v-146a8c47]{border-width:.5px}.select-wrap[data-v-146a8c47]{min-width:220px;max-width:min(320px,50vw);flex:none}.empty-config[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-muted);padding:var(--space-1) 0}@media(max-width:640px){.sd[data-v-146a8c47]{grid-template-columns:1fr;grid-template-rows:auto 1fr;grid-template-areas:"tabs" "region"}.settings-tabs[data-v-146a8c47]{width:auto;padding:0;overflow-x:visible;border-right:none;border-bottom:.5px solid var(--color-line)}.settings-tabs-header[data-v-146a8c47]{padding:var(--space-3)}.settings-tab-list[data-v-146a8c47]{flex-direction:row;gap:var(--space-1);overflow-x:auto;padding:0 var(--space-3) var(--space-2)}.settings-region-header[data-v-146a8c47]{padding:var(--space-3)}.body[data-v-146a8c47]{padding-inline:var(--space-3)}.tab[data-v-146a8c47]{white-space:nowrap;flex:none}.row[data-v-146a8c47]{align-items:flex-start;flex-direction:column}.settings-group[data-v-146a8c47]{margin-inline:0}.select-wrap[data-v-146a8c47]{width:100%;max-width:none}}.setting-card[data-v-146a8c47]{border-radius:var(--radius-xl);overflow:hidden;background:var(--color-surface)}.panel-head[data-v-146a8c47]{margin-bottom:var(--space-4)}.panel-title[data-v-146a8c47]{margin:0 0 var(--space-2);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);letter-spacing:0;color:var(--color-text)}.panel-desc[data-v-146a8c47]{margin:0;font-family:var(--font-ui);font-size:var(--text-xs);line-height:var(--leading-normal);color:var(--color-text-muted);max-width:560px}.archive-toolbar[data-v-146a8c47]{display:flex;align-items:center;gap:var(--space-3);margin-bottom:var(--space-4);flex-wrap:wrap}.archive-search[data-v-146a8c47]{flex:1;min-width:200px;height:36px;display:flex;align-items:center;gap:var(--space-2);padding:0 var(--space-3);border-radius:var(--radius-md);border:.5px solid var(--color-line);color:var(--color-text-faint);font-size:var(--text-xs);background:var(--color-surface-overlay);transition:border-color var(--duration-fast) var(--ease-out),box-shadow var(--duration-fast) var(--ease-out)}.archive-search[data-v-146a8c47]:focus-within{border-color:var(--color-accent);box-shadow:var(--p-focus-ring);color:var(--color-text-muted)}.archive-search svg[data-v-146a8c47]{width:15px;height:15px;flex:none}.archive-search input[data-v-146a8c47]{width:100%;border:none;outline:none;background:transparent;font:inherit;color:var(--color-text)}.archive-list[data-v-146a8c47]{display:flex;flex-direction:column;gap:var(--space-4)}.archive-card .setting-card[data-v-146a8c47]{margin-bottom:0}.archive-workspace[data-v-146a8c47]{display:flex;align-items:center;gap:var(--space-2);margin:0 2px var(--space-2);color:var(--color-text-muted);font-size:var(--text-xs);font-weight:var(--weight-medium)}.archive-workspace svg[data-v-146a8c47]{width:16px;height:16px;color:var(--color-text-faint);flex:none}.archive-workspace .path[data-v-146a8c47]{font-family:var(--font-ui);font-size:var(--text-xs);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archive-workspace .count[data-v-146a8c47]{margin-left:auto;color:var(--color-text-faint);font-weight:var(--weight-medium);font-size:var(--text-xs);flex:none}.archive-row[data-v-146a8c47]{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:var(--space-3);align-items:center;padding:var(--space-3) var(--space-4);border-top:.5px solid var(--color-line)}.archive-row[data-v-146a8c47]:first-child{border-top:none}.archive-row[data-v-146a8c47]:hover{background:var(--color-hover)}.archive-meta[data-v-146a8c47]{min-width:0}.archive-name[data-v-146a8c47]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.archive-time[data-v-146a8c47]{margin-top:2px;font-size:var(--text-xs);color:var(--color-text-faint);font-family:var(--font-ui)}.archive-draining[data-v-146a8c47]{margin-bottom:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);background:var(--color-accent-soft);color:var(--color-accent-hover);font-size:var(--text-xs)}.archive-empty[data-v-146a8c47]{padding:var(--space-6) var(--space-4);border-radius:var(--radius-xl);color:var(--color-text-faint);font-size:var(--text-xs);text-align:center;background:var(--color-surface)}@media(max-width:640px){.archive-toolbar[data-v-146a8c47]{flex-direction:column;align-items:stretch}.archive-search[data-v-146a8c47]{min-width:0}}[data-v-146a8c47] .ui-dialog{width:min(980px,96vw)}[data-v-146a8c47] .ui-dialog--fixed-height{height:min(780px,calc(100vh - var(--space-8) * 2))}.aw[data-v-fea98be5]{padding-top:4px}.crumbbar[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) 22px;border-bottom:.5px solid var(--color-line)}.crumbs[data-v-fea98be5]{display:flex;align-items:center;flex-wrap:wrap;gap:1px;min-width:0;font-size:var(--text-sm)}.crumb-sep[data-v-fea98be5]{color:var(--color-text-muted)}.crumb[data-v-fea98be5]{background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-muted);padding:1px var(--space-1);border-radius:var(--radius-xs)}.crumb[data-v-fea98be5]:hover{color:var(--color-text);background:var(--color-hover)}.crumb.last[data-v-fea98be5]{color:var(--color-text);font-weight:var(--weight-medium)}.filterbar[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) 22px;border-bottom:.5px solid var(--color-line)}.filter-icon[data-v-fea98be5]{flex:none;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--color-text-muted)}.filter-input[data-v-fea98be5]{flex:1;min-width:0;font-family:var(--font-ui);font-size:var(--text-base);padding:var(--space-1) 0;border:none;background:none;color:var(--color-text);outline:none}.filter-input[data-v-fea98be5]::placeholder{color:var(--color-text-muted)}.search-rel[data-v-fea98be5]{color:var(--color-text)}.folder-list[data-v-fea98be5]{height:300px;overflow-y:auto;padding:var(--space-1) var(--space-2)}.fl-loading[data-v-fea98be5],.fl-empty[data-v-fea98be5]{padding:var(--space-6) var(--space-4);text-align:center;color:var(--color-text-muted);font-size:var(--text-sm)}.folder-row[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2);width:100%;background:none;border:none;cursor:pointer;font-family:var(--font-ui);font-size:var(--text-base);color:var(--color-text);text-align:left;padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);transition:background var(--duration-fast) var(--ease-out)}.folder-row[data-v-fea98be5]:hover{background:var(--color-hover)}.dir-icon[data-v-fea98be5]{flex:none;width:var(--p-ic-sm);height:var(--p-ic-sm);color:var(--color-text-muted)}.folder-name[data-v-fea98be5]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--color-text)}.paste-section[data-v-fea98be5]{padding:var(--space-3) 22px;border-top:.5px solid var(--color-line)}.paste-section.paste-only[data-v-fea98be5]{border-top:none}.paste-row[data-v-fea98be5]{display:flex;align-items:center;gap:var(--space-2)}.paste-input-wrap[data-v-fea98be5]{flex:1;min-width:0}.add-error[data-v-fea98be5]{margin:0 22px var(--space-2);padding:var(--space-2) var(--space-3);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-danger);background:var(--color-danger-soft);border:.5px solid var(--color-danger-bd);border-radius:var(--radius-sm)}.actions[data-v-fea98be5]{display:flex;justify-content:flex-end;gap:var(--space-2);padding:var(--space-3) 22px}.footer-hint[data-v-fea98be5]{padding:var(--space-2) var(--space-4);font-family:var(--font-ui);font-size:var(--text-xs);color:var(--color-text-faint);border-top:.5px solid var(--color-line)}@media(max-width:640px){.folder-row[data-v-fea98be5]{min-height:44px}.crumbbar[data-v-fea98be5]{align-items:flex-start}.actions[data-v-fea98be5]{flex-wrap:wrap}}.confirm-dialog__message[data-v-aa5422da]{margin:0;font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted)}.rows[data-v-340d1b31]{margin:0;padding:0}.row[data-v-340d1b31]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0;font-size:var(--text-base)}.row dt[data-v-340d1b31]{width:96px;flex:none;color:var(--color-text-muted);text-transform:uppercase;letter-spacing:.04em;font-size:var(--text-xs)}.row dd[data-v-340d1b31]{margin:0;color:var(--color-text);font-weight:var(--weight-medium);display:flex;align-items:center;gap:var(--space-2);min-width:0}.row dd.plan-on[data-v-340d1b31],.row dd.swarm-on[data-v-340d1b31]{color:var(--color-accent)}.ctx-text[data-v-340d1b31]{flex:none}.bar[data-v-340d1b31]{width:80px;height:5px;border-radius:var(--radius-full);background:var(--color-line);overflow:hidden;flex:none}.bar i[data-v-340d1b31]{display:block;height:100%;background:var(--color-accent)}@media(max-width:640px){.rows[data-v-340d1b31]{overflow-y:auto;-webkit-overflow-scrolling:touch}.row[data-v-340d1b31]{align-items:flex-start;flex-direction:column;gap:var(--space-1);min-height:48px}.row dt[data-v-340d1b31]{width:auto}.row dd[data-v-340d1b31]{max-width:100%;flex-wrap:wrap}}.toasts[data-v-ac44e9ef]{position:fixed;right:16px;bottom:84px;display:flex;flex-direction:column;gap:var(--space-2);z-index:var(--z-toast);width:min(440px,calc(100vw - 32px));max-height:56vh;overflow-y:auto}.toast-enter-active[data-v-ac44e9ef],.toast-leave-active[data-v-ac44e9ef]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.toast-enter-from[data-v-ac44e9ef],.toast-leave-to[data-v-ac44e9ef]{opacity:0;transform:translate(16px)}.toast-move[data-v-ac44e9ef]{transition:transform var(--duration-base) var(--ease-out)}.actions[data-v-ac44e9ef]{display:flex;flex-wrap:wrap;gap:var(--space-2);margin-top:var(--space-2)}.link[data-v-ac44e9ef]{border:0;padding:0;background:none;color:var(--color-accent);cursor:pointer;font:inherit;font-size:var(--ui-font-size-xs)}.link[data-v-ac44e9ef]:hover{text-decoration:underline}.details[data-v-ac44e9ef]{display:grid;gap:5px;margin:8px 0 0;padding:8px;border:.5px solid var(--color-line);border-radius:var(--radius-sm);background:var(--color-surface-sunken)}.detail-row[data-v-ac44e9ef]{display:grid;grid-template-columns:minmax(88px,.34fr) minmax(0,1fr);gap:8px}.detail-row dt[data-v-ac44e9ef]{color:var(--color-text-muted)}.detail-row dd[data-v-ac44e9ef]{margin:0;color:var(--color-text);overflow-wrap:anywhere;white-space:pre-wrap}@media(max-width:640px){.toasts[data-v-ac44e9ef]{left:12px;right:12px;bottom:calc(var(--dock-h, 76px) + 8px);width:auto;max-height:50vh}.detail-row[data-v-ac44e9ef]{grid-template-columns:1fr;gap:2px}}.topbar[data-v-7f357087]{display:flex;align-items:center;gap:10px;height:calc(50px + var(--safe-top));flex:none;padding:var(--safe-top) max(12px,var(--safe-right)) 0 max(12px,var(--safe-left));border-bottom:.5px solid var(--color-line);background:var(--color-bg);font-family:var(--font-ui)}.wsq[data-v-7f357087]{flex:none;width:28px;height:28px;border-radius:var(--radius-md);background:var(--color-text);color:var(--color-bg);display:flex;align-items:center;justify-content:center;font-family:var(--font-mono);font-weight:var(--weight-medium);font-size:var(--ui-font-size-sm)}.tb-mid[data-v-7f357087]{flex:1;min-width:0;height:100%;display:flex;flex-direction:column;justify-content:center;gap:1px;background:none;border:none;padding:0;cursor:pointer;text-align:left}.tb-path[data-v-7f357087]{display:flex;align-items:center;gap:5px;font-size:var(--ui-font-size-sm);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tb-path .ws[data-v-7f357087]{color:var(--color-text)}.tb-path .sl[data-v-7f357087]{color:var(--color-text-faint)}.tb-path .se[data-v-7f357087]{color:var(--color-text);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tb-path .cv[data-v-7f357087]{color:var(--color-text-faint);flex:none}.tb-sub[data-v-7f357087]{display:flex;align-items:center;gap:5px;font-size:max(9px,calc(var(--ui-font-size) - 3.5px));color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tb-sub .rd[data-v-7f357087]{flex:none;width:6px;height:6px;border-radius:var(--radius-full);background:var(--color-text-faint)}.tb-sub .rd.on[data-v-7f357087]{background:var(--color-success)}.topbar .tb-path[data-v-7f357087]{font-family:var(--sans)}.sheet-root[data-v-c3d5dadc]{position:fixed;inset:0;z-index:var(--z-overlay);display:flex;flex-direction:column;justify-content:flex-end}.sheet-scrim[data-v-c3d5dadc]{position:absolute;inset:0;background:#0d111773}.sheet-panel[data-v-c3d5dadc]{position:relative;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-bottom:none;border-radius:var(--radius-xl) var(--radius-xl) 0 0;box-shadow:var(--shadow-xl);max-height:86vh;display:flex;flex-direction:column;min-height:0;font-family:var(--font-ui);color:var(--color-text)}.sheet-grab[data-v-c3d5dadc]{flex:none;align-self:center;width:56px;height:18px;padding:0;border:none;background:none;cursor:pointer;position:relative;margin-top:4px}.sheet-grab[data-v-c3d5dadc]:after{content:"";position:absolute;left:50%;top:7px;transform:translate(-50%);width:38px;height:5px;border-radius:var(--radius-full);background:var(--color-line)}.sheet-head[data-v-c3d5dadc]{flex:none;display:flex;align-items:center;justify-content:space-between;padding:6px 16px 10px}.sheet-title[data-v-c3d5dadc]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.sheet-body[data-v-c3d5dadc]{flex:1;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:max(16px,var(--safe-bottom))}.sheet-enter-active[data-v-c3d5dadc],.sheet-leave-active[data-v-c3d5dadc]{transition:opacity var(--duration-slow) var(--ease-out)}.sheet-enter-active .sheet-panel[data-v-c3d5dadc],.sheet-leave-active .sheet-panel[data-v-c3d5dadc]{transition:transform var(--duration-slow) var(--ease-out)}.sheet-enter-from[data-v-c3d5dadc],.sheet-leave-to[data-v-c3d5dadc]{opacity:0}.sheet-enter-from .sheet-panel[data-v-c3d5dadc],.sheet-leave-to .sheet-panel[data-v-c3d5dadc]{transform:translateY(102%)}.newrow[data-v-67278201]{display:flex;align-items:center;gap:10px;width:100%;padding:var(--space-3) var(--space-4);background:none;border:none;border-radius:var(--radius-md);color:var(--color-accent);font-weight:500;font-size:var(--text-base);cursor:pointer;text-align:left}.newrow[data-v-67278201]:hover{background:var(--color-hover)}.newrow[data-v-67278201]:active{background:var(--color-surface-sunken)}.newrow.secondary[data-v-67278201]{padding-top:var(--space-2);padding-bottom:var(--space-2);color:var(--color-text-muted);font-weight:400}.newrow.secondary[data-v-67278201]:hover{background:var(--color-hover)}.newrow.secondary[data-v-67278201]:active{background:var(--color-surface-sunken);color:var(--color-text)}.mlist[data-v-67278201]{--m-pad: 16px;--m-gutter: 15px;--m-gap: 8px;--m-indent: calc(var(--m-pad) + var(--m-gutter) + var(--m-gap));padding-bottom:var(--space-1)}.mempty[data-v-67278201]{padding:var(--space-6) var(--space-4);text-align:center;color:var(--color-text-faint);font-size:var(--ui-font-size)}.mempty.small[data-v-67278201]{padding:10px 16px 12px var(--m-indent);text-align:left;font-size:var(--ui-font-size-xs)}.mgroup[data-v-67278201]{padding-top:2px}.mgh[data-v-67278201]{display:flex;align-items:center;gap:var(--m-gap);padding:10px var(--m-pad) 6px;border-radius:var(--radius-md);cursor:pointer;user-select:none;position:relative}.mgh[data-v-67278201]:hover{background:var(--color-hover)}.mgh[data-v-67278201]:active{background:var(--color-surface-sunken)}.mgh-folder[data-v-67278201]{flex:none;color:var(--color-text-muted)}.mgh-main[data-v-67278201]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.mgh-name[data-v-67278201]{font-size:var(--ui-font-size-lg);font-weight:550;color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mgh-path[data-v-67278201]{font-size:var(--text-base);font-weight:425;color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mgh-add[data-v-67278201]{margin:-10px -12px -10px 0}.mgh-add[data-v-67278201]:active{color:var(--color-text);background:var(--color-hover)}.mgh-more[data-v-67278201]{margin:-10px -8px}.mgh-more[data-v-67278201]:active{color:var(--color-text);background:var(--color-hover)}.srow[data-v-67278201]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--m-pad) var(--space-3) var(--m-indent);border-radius:var(--radius-md);cursor:pointer;position:relative}.srow[data-v-67278201]:hover{background:var(--color-hover)}.srow[data-v-67278201]:active{background:var(--color-surface-sunken)}.srow.cur[data-v-67278201]{background:var(--color-accent-soft);box-shadow:inset 0 0 0 1px var(--color-accent-bd)}.srow .m[data-v-67278201]{flex:1;min-width:0}.srow .m .t[data-v-67278201]{font-size:var(--text-base);font-weight:450;line-height:var(--leading-tight);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.srow.cur .m .t[data-v-67278201]{color:var(--color-accent-hover)}.srow .m .t.run[data-v-67278201]{position:relative}.srow .m .t.run[data-v-67278201]:before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:var(--radius-full);background:var(--color-accent);animation:mRunPulse-67278201 1.4s ease-in-out infinite}@keyframes mRunPulse-67278201{0%,to{opacity:1}50%{opacity:.35}}.srow .m .t.aborted[data-v-67278201]{position:relative}.srow .m .t.aborted[data-v-67278201]:before{content:"";position:absolute;left:-14px;top:50%;transform:translateY(-50%);width:6px;height:6px;border-radius:var(--radius-full);background:var(--color-danger)}.srow .m .s[data-v-67278201]{font-size:var(--text-base);font-weight:475;font-variant-numeric:tabular-nums;color:var(--color-text-faint);margin-top:1px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.att[data-v-67278201]{flex:none;font-family:var(--font-mono);font-size:max(9px,calc(var(--ui-font-size) - 4px));color:var(--color-text-on-accent);background:var(--color-warning);border-radius:var(--radius-full);padding:1px 7px}.srow .kb[data-v-67278201]:active{color:var(--color-text);background:var(--color-hover)}.kmenu[data-v-67278201]{position:absolute;right:12px;top:44px;z-index:var(--z-dropdown);min-width:96px;overflow:hidden}.wsmenu[data-v-67278201]{top:calc(100% - 4px);right:var(--m-pad);min-width:132px}.mshow-more-row[data-v-67278201]{display:flex;align-items:center;padding-left:calc(var(--m-indent) - var(--space-3))}.mshow-more[data-v-67278201]{display:flex;align-items:center;gap:var(--space-2);min-height:44px;padding:var(--space-1) var(--space-3);background:none;border:none;border-radius:var(--radius-md);color:var(--color-text-muted);font-size:var(--text-base);cursor:pointer;text-align:left}.mshow-more[data-v-67278201]:active{color:var(--color-accent-hover);background:var(--color-hover)}.mshow-more-sep[data-v-67278201]{margin:0 var(--space-1);color:var(--color-text-faint);user-select:none}.newrow[data-v-67278201]{font-family:var(--sans)}.mlist .srow[data-v-67278201]{margin:1px 8px;border-radius:var(--radius-md);border-bottom:none;padding:12px calc(var(--m-pad, 16px) - 8px) 12px calc(var(--m-indent, 39px) - 8px)}.mlist .srow.cur[data-v-67278201]{box-shadow:inset 0 0 0 1px var(--color-accent-bd)}.group-title[data-v-41a9e678]{padding:var(--space-3) var(--space-3) var(--space-1);font-family:var(--font-ui);font-size:var(--text-xs);font-weight:var(--weight-medium);letter-spacing:.06em;text-transform:uppercase;color:var(--color-text-faint)}.srow[data-v-41a9e678]{display:flex;align-items:center;gap:var(--space-3);width:100%;min-height:52px;padding:var(--space-3);background:none;border:none;border-radius:var(--radius-md);cursor:pointer;text-align:left;color:var(--color-text)}.srow[data-v-41a9e678]:hover:not(.read-only){background:var(--color-hover)}.srow[data-v-41a9e678]:active:not(.read-only){background:var(--color-surface-sunken)}.srow.read-only[data-v-41a9e678]{cursor:default}.srow-main[data-v-41a9e678]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.srow-label[data-v-41a9e678]{font-size:var(--text-base);color:var(--color-text)}.srow-sub[data-v-41a9e678]{font-size:var(--text-base);color:var(--color-text-faint);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.srow-val[data-v-41a9e678]{flex:none;font-family:var(--font-mono);font-size:var(--ui-font-size);font-weight:500;color:var(--color-accent-hover)}.srow-val.dim[data-v-41a9e678]{font-weight:400;color:var(--color-text-muted)}.cache-note[data-v-41a9e678]{padding:0 var(--space-3) var(--space-2);font-size:var(--text-xs);color:var(--color-text-faint);line-height:1.4}.chev[data-v-41a9e678]{flex:none;color:var(--color-text-faint);font-size:17px;line-height:1}.toggle[data-v-41a9e678]{flex:none;width:44px;height:26px;border-radius:var(--radius-full);background:var(--color-line);position:relative;transition:background .18s}.toggle.on[data-v-41a9e678]{background:var(--color-accent)}.toggle[data-v-41a9e678]:after{content:"";position:absolute;top:3px;left:3px;width:20px;height:20px;border-radius:var(--radius-full);box-sizing:border-box;background:var(--color-bg);border:.5px solid var(--color-line);box-shadow:var(--shadow-xs);transition:left .18s}.toggle.on[data-v-41a9e678]:after{left:21px}.srow.pref[data-v-41a9e678]{cursor:default}.srow.acct.in .srow-label[data-v-41a9e678]{color:var(--color-accent-hover);font-weight:500}.srow.acct.out .srow-label[data-v-41a9e678]{color:var(--color-danger)}.acct-avatar[data-v-41a9e678]{display:flex;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border-radius:50%;background:var(--color-surface-sunken);color:var(--color-text-muted)}.acct-avatar img[data-v-41a9e678]{width:100%;height:100%;border-radius:50%;object-fit:cover}.acct-name-row[data-v-41a9e678]{display:flex;align-items:center;gap:var(--space-2);min-width:0}.acct-name-row .srow-label[data-v-41a9e678]{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.acct-level[data-v-41a9e678]{min-width:0;max-width:100%;overflow:hidden;text-overflow:ellipsis}.ctx-meter[data-v-41a9e678]{flex:none;width:96px;height:7px;border-radius:var(--radius-full);background:var(--color-surface-sunken);overflow:hidden}.ctx-meter i[data-v-41a9e678]{display:block;height:100%;background:var(--color-accent)}@media(max-width:640px){.srow[data-v-41a9e678]{align-items:flex-start;gap:10px;min-width:0;padding:14px max(14px,var(--safe-right)) 14px max(14px,var(--safe-left))}.group-title[data-v-41a9e678],.cache-note[data-v-41a9e678]{padding-left:max(14px,var(--safe-left));padding-right:max(14px,var(--safe-right))}.srow-main[data-v-41a9e678]{flex:1 1 auto}.srow-sub[data-v-41a9e678]{white-space:normal;overflow-wrap:anywhere}.srow.pref[data-v-41a9e678]{flex-wrap:wrap}.srow.pref .srow-main[data-v-41a9e678]{flex:1 0 100%}.srow-val[data-v-41a9e678],.chev[data-v-41a9e678],.toggle[data-v-41a9e678],.ctx-meter[data-v-41a9e678]{margin-top:2px}}.srow[data-v-41a9e678],.srow-sub[data-v-41a9e678],.srow-val[data-v-41a9e678],.cache-note[data-v-41a9e678]{font-family:var(--sans)}.arch-subhead[data-v-41a9e678]{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-3) var(--space-1)}.arch-back[data-v-41a9e678]{display:inline-flex;align-items:center;gap:2px;border:none;background:none;padding:var(--space-1) var(--space-2) var(--space-1) 0;font-family:var(--font-ui);font-size:var(--text-base);color:var(--color-accent-hover);cursor:pointer}.chev.back[data-v-41a9e678]{font-size:20px}.arch-count[data-v-41a9e678]{font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.arch-tools[data-v-41a9e678]{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);flex-wrap:wrap}.arch-search-input[data-v-41a9e678]{flex:1;min-width:160px}.arch-row[data-v-41a9e678]{display:flex;align-items:center;gap:var(--space-3);min-height:56px;padding:var(--space-2) var(--space-3);border-top:.5px solid var(--color-line)}.arch-row[data-v-41a9e678]:first-of-type{border-top:none}.arch-meta[data-v-41a9e678]{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}.arch-name[data-v-41a9e678]{font-family:var(--font-ui);font-size:var(--text-base);color:var(--color-text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.arch-time[data-v-41a9e678]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-faint)}.arch-empty[data-v-41a9e678]{padding:var(--space-6) var(--space-4);text-align:center;font-family:var(--font-ui);font-size:var(--text-sm);color:var(--color-text-faint)}.brand-logo[data-v-f04205a8]{display:block;flex:none;cursor:pointer;user-select:none;touch-action:manipulation}.ls-cards[data-v-0a67ec7e]{display:flex;flex-direction:column;gap:var(--space-3)}.ls-card[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-3);width:100%;padding:var(--space-4);background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);font-family:var(--font-ui);text-align:left;cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.ls-card[data-v-0a67ec7e]:hover{border-color:var(--color-line-strong);background:var(--color-surface)}.ls-card[data-v-0a67ec7e]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.ls-card-logo[data-v-0a67ec7e]{align-self:flex-start}.ls-card-icon[data-v-0a67ec7e]{display:inline-flex;align-items:center;justify-content:center;width:40px;height:40px;color:var(--color-text-muted)}.ls-card-text[data-v-0a67ec7e]{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--space-1)}.ls-card-title[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-lg);font-weight:var(--weight-medium);color:var(--color-text)}.ls-reco[data-v-0a67ec7e]{padding:2px var(--space-2);border-radius:var(--radius-full);background:var(--color-accent-soft);color:var(--color-accent);font-size:var(--text-xs);font-weight:var(--weight-medium)}.ls-card-hint[data-v-0a67ec7e]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.ls-card-chevron[data-v-0a67ec7e]{color:var(--color-text-faint);flex:none}.ls-done-card[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);background:var(--color-surface-raised);border:.5px solid var(--color-success-bd);border-radius:var(--radius-lg)}.ls-done-badge[data-v-0a67ec7e]{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border-radius:var(--radius-full);background:var(--color-success-soft);color:var(--color-success);flex:none}.ls-flow[data-v-0a67ec7e]{display:flex;flex-direction:column;gap:var(--space-4)}.ls-center[data-v-0a67ec7e]{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);padding:var(--space-6) 0 var(--space-2);text-align:center}.ls-center-text[data-v-0a67ec7e]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.ls-success-text[data-v-0a67ec7e]{color:var(--color-success)}.ls-err-text[data-v-0a67ec7e]{color:var(--color-danger)}.ls-warn-text[data-v-0a67ec7e]{color:var(--color-warning)}.ls-center-hint[data-v-0a67ec7e]{font-size:var(--text-sm);color:var(--color-text-muted)}.ls-device[data-v-0a67ec7e]{display:flex;flex-direction:column;gap:var(--space-4)}.ls-lead[data-v-0a67ec7e]{font-size:var(--text-base);color:var(--color-text);line-height:var(--leading-normal)}.ls-primary[data-v-0a67ec7e]{display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);width:100%;min-height:40px;padding:0 var(--space-4);background:var(--color-accent);color:var(--color-text-on-accent);border:.5px solid var(--color-accent);border-radius:var(--radius-md);font-family:var(--font-ui);font-size:var(--text-base);font-weight:var(--weight-medium);cursor:pointer;text-decoration:none;transition:background var(--duration-fast) var(--ease-out),border-color var(--duration-fast) var(--ease-out)}.ls-primary[data-v-0a67ec7e]:hover{background:var(--color-accent-hover);border-color:var(--color-accent-hover)}.ls-or[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-3);color:var(--color-text-muted);font-size:var(--text-xs);letter-spacing:.06em}.ls-or[data-v-0a67ec7e]:before,.ls-or[data-v-0a67ec7e]:after{content:"";flex:1;height:1px;background:var(--color-line)}.ls-fb-text[data-v-0a67ec7e]{font-size:var(--text-sm);color:var(--color-text-muted);line-height:var(--leading-normal)}.ls-fb-link[data-v-0a67ec7e]{color:var(--color-accent);text-decoration:none;border-bottom:.5px solid var(--color-accent-bd)}.ls-fb-link[data-v-0a67ec7e]:hover{border-bottom-color:var(--color-accent)}.ls-code-row[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-3);background:var(--color-surface-sunken);border:.5px solid var(--color-line);border-radius:var(--radius-md);padding:var(--space-2) var(--space-3)}.ls-code[data-v-0a67ec7e]{flex:1;font-family:var(--font-mono);font-size:var(--text-xl);font-weight:var(--weight-medium);color:var(--color-text);letter-spacing:.14em}.ls-link[data-v-0a67ec7e]{flex:1;min-width:0;font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;user-select:text}.ls-copy.is-copied[data-v-0a67ec7e]{color:var(--color-success);border-color:var(--color-success-bd)}.ls-status[data-v-0a67ec7e]{display:flex;align-items:center;gap:var(--space-2);padding-top:var(--space-3);border-top:.5px solid var(--color-line)}.ls-status-text[data-v-0a67ec7e]{font-family:var(--font-mono);font-size:var(--text-sm);color:var(--color-text-muted);flex:1}.ls-countdown[data-v-0a67ec7e]{font-family:var(--font-mono);font-size:var(--text-xs);color:var(--color-text-muted);font-variant-numeric:tabular-nums}.ls-actions[data-v-0a67ec7e]{display:flex;justify-content:flex-end;gap:var(--space-3)}@media(max-width:640px){.ls-code-row[data-v-0a67ec7e],.ls-status[data-v-0a67ec7e],.ls-actions[data-v-0a67ec7e]{flex-wrap:wrap}.ls-code[data-v-0a67ec7e]{min-width:0;overflow-wrap:anywhere;letter-spacing:.08em}.ls-status-text[data-v-0a67ec7e]{min-width:0}}.wizard[data-v-a665ca6b]{position:fixed;inset:0;z-index:var(--z-modal);display:flex;flex-direction:column;background:var(--color-bg);color:var(--color-text);overflow-y:auto;font-family:var(--font-ui)}.wiz-body[data-v-a665ca6b]{flex:1;display:flex;flex-direction:column;align-items:center;width:min(560px,100%);margin:0 auto;padding:max(var(--space-8),12vh) var(--space-5) var(--space-6)}.wiz-step[data-v-a665ca6b]{display:flex;flex-direction:column;align-items:center;width:100%;flex:1;min-height:0}.wiz-step-fill[data-v-a665ca6b]{flex:1;min-height:0;display:flex;flex-direction:column;justify-content:center;width:100%}.wiz-title[data-v-a665ca6b]{margin:var(--space-4) 0 0;font-size:var(--text-2xl);font-weight:var(--weight-semibold);line-height:var(--leading-tight);color:var(--color-text);text-align:center}.wiz-sub[data-v-a665ca6b]{margin:var(--space-2) 0 var(--space-6);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted);text-align:center;max-width:460px}.pref-group[data-v-a665ca6b]{width:100%;margin-bottom:var(--space-5)}.pref-label[data-v-a665ca6b]{font-size:var(--text-sm);font-weight:var(--weight-medium);color:var(--color-text-muted);margin-bottom:var(--space-2)}.opt-card[data-v-a665ca6b]{display:flex;align-items:center;background:var(--color-surface-raised);border:.5px solid var(--color-line);border-radius:var(--radius-lg);font-family:var(--font-ui);cursor:pointer;transition:border-color var(--duration-fast) var(--ease-out),background var(--duration-fast) var(--ease-out)}.opt-card[data-v-a665ca6b]:hover{border-color:var(--color-line-strong)}.opt-card[data-v-a665ca6b]:focus-visible{outline:none;box-shadow:var(--p-focus-ring-strong)}.opt-card.selected[data-v-a665ca6b]{border-color:var(--color-accent);background:var(--color-accent-soft)}.opt-label[data-v-a665ca6b]{font-size:var(--text-base);font-weight:var(--weight-medium);color:var(--color-text)}.lang-cards[data-v-a665ca6b]{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--space-3);width:100%}.lang-card[data-v-a665ca6b]{gap:var(--space-3);padding:var(--space-4)}.opt-radio[data-v-a665ca6b]{width:18px;height:18px;border-radius:var(--radius-full);border:.5px solid var(--color-line-strong);background:var(--color-surface-raised);flex:none;display:inline-flex;align-items:center;justify-content:center;transition:border-color var(--duration-fast) var(--ease-out)}.opt-radio[data-v-a665ca6b]:after{content:"";width:8px;height:8px;border-radius:var(--radius-full);background:transparent;transition:background var(--duration-fast) var(--ease-out)}.opt-radio.on[data-v-a665ca6b]{border-color:var(--color-accent)}.opt-radio.on[data-v-a665ca6b]:after{background:var(--color-accent)}.theme-cards[data-v-a665ca6b]{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-3);width:100%}.theme-card[data-v-a665ca6b]{flex-direction:column;gap:var(--space-3);padding:var(--space-3)}.tp[data-v-a665ca6b]{display:flex;width:100%;aspect-ratio:16 / 10;border:.5px solid var(--color-line);border-radius:var(--radius-md);overflow:hidden}.tp-light[data-v-a665ca6b]{background:#fff}.tp-dark[data-v-a665ca6b]{background:#0d1117}.tp-half[data-v-a665ca6b]{flex:1;display:flex;min-width:0}.tp-half-light[data-v-a665ca6b]{background:#fff}.tp-half-dark[data-v-a665ca6b]{background:#0d1117}.tp-side[data-v-a665ca6b]{width:30%;flex:none}.tp-light .tp-side[data-v-a665ca6b],.tp-half-light .tp-side[data-v-a665ca6b]{background:#0000000d}.tp-dark .tp-side[data-v-a665ca6b],.tp-half-dark .tp-side[data-v-a665ca6b]{background:#ffffff12}.tp-lines[data-v-a665ca6b]{flex:1;display:flex;flex-direction:column;gap:6px;padding:14% 12%}.tp-lines span[data-v-a665ca6b]{height:6px;border-radius:var(--radius-full)}.tp-lines span[data-v-a665ca6b]:nth-child(1){width:62%}.tp-lines span[data-v-a665ca6b]:nth-child(2){width:88%}.tp-lines span[data-v-a665ca6b]:nth-child(3){width:44%}.tp-light .tp-lines span[data-v-a665ca6b],.tp-half-light .tp-lines span[data-v-a665ca6b]{background:#00000024}.tp-dark .tp-lines span[data-v-a665ca6b],.tp-half-dark .tp-lines span[data-v-a665ca6b]{background:#ffffff38}.wiz-foot[data-v-a665ca6b]{display:flex;flex-direction:column;align-items:center;gap:var(--space-2);width:100%;margin-top:auto;padding:var(--space-8) 0 max(var(--space-8),8vh)}.wiz-foot-ghost[data-v-a665ca6b]{display:flex;gap:var(--space-3);min-height:32px;align-items:center}.wiz-foot-ghost[data-v-a665ca6b] .ui-button--ghost:not(:disabled):hover{background:transparent;color:var(--color-text)}.wiz-primary[data-v-a665ca6b]{min-width:140px}@media(max-width:640px){.theme-cards[data-v-a665ca6b]{grid-template-columns:1fr}}.gload[data-v-ab85ede1]{position:fixed;top:0;left:0;width:100vw;height:100vh;height:100dvh;min-width:100vw;min-height:100dvh;z-index:var(--z-toast);display:flex;align-items:center;justify-content:center;background:var(--bg)}.gload-box[data-v-ab85ede1]{display:flex;flex-direction:column;align-items:center;gap:22px;transform:translateY(-6%)}.gload-logo[data-v-ab85ede1]{width:128px;height:auto;color:var(--color-text);animation:gload-pop-ab85ede1 .55s cubic-bezier(.22,1,.36,1) both}.gload-text[data-v-ab85ede1]{font-family:var(--mono);font-size:var(--text-base);color:var(--muted);letter-spacing:.04em}@keyframes gload-pop-ab85ede1{0%{opacity:0;transform:translateY(6px) scale(.96)}to{opacity:1;transform:translateY(0) scale(1)}}@media(prefers-reduced-motion:reduce){.gload-logo[data-v-ab85ede1]{animation:none}}.gload-text[data-v-ab85ede1]{font-family:var(--sans)}.kap-root[data-v-2b13888e]{height:100vh;display:flex;flex-direction:column;background:var(--bg);font-family:var(--mono);font-size:calc(var(--ui-font-size) - 2.5px);color:var(--color-text)}.kap-head[data-v-2b13888e]{flex:none;display:flex;align-items:center;gap:8px;padding:10px 14px;border-bottom:.5px solid var(--line);background:var(--panel)}.kap-count[data-v-2b13888e]{color:var(--muted)}.kap-head-actions[data-v-2b13888e]{margin-left:auto;display:flex;gap:6px}.kap-head-actions button[data-v-2b13888e],.kap-view-toggle button[data-v-2b13888e]{padding:3px 8px;border:.5px solid var(--line);border-radius:6px;background:var(--bg);color:var(--muted);font:inherit;cursor:pointer}.kap-head-actions button[data-v-2b13888e]:hover,.kap-view-toggle button[data-v-2b13888e]:hover{color:var(--color-text)}.kap-head-actions button.on[data-v-2b13888e],.kap-view-toggle button.on[data-v-2b13888e]{color:var(--color-accent-hover);border-color:var(--color-accent-bd);background:var(--color-accent-soft)}.kap-filters[data-v-2b13888e]{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:6px;padding:7px 10px;border-bottom:.5px solid var(--line)}.kap-filters select[data-v-2b13888e],.kap-filters input[type=text][data-v-2b13888e]{padding:3px 6px;border:.5px solid var(--line);border-radius:6px;background:var(--bg);color:var(--color-text);font:inherit;min-width:0}.kap-filters input[type=text][data-v-2b13888e]{flex:1;min-width:120px}.kap-check[data-v-2b13888e]{display:inline-flex;align-items:center;gap:4px;color:var(--muted);white-space:nowrap}.kap-view-toggle[data-v-2b13888e]{display:flex;gap:0}.kap-view-toggle button[data-v-2b13888e]:first-child{border-radius:6px 0 0 6px;border-right:none}.kap-view-toggle button[data-v-2b13888e]:last-child{border-radius:0 6px 6px 0}.kap-list[data-v-2b13888e]{flex:1;min-height:0;overflow-y:auto}.kap-empty[data-v-2b13888e]{padding:18px 12px;color:var(--muted);text-align:center}.kap-row[data-v-2b13888e]{display:flex;align-items:baseline;gap:7px;width:100%;padding:3px 10px;border:none;border-bottom:.5px solid var(--line);background:transparent;color:var(--color-text);font:inherit;text-align:left;cursor:pointer}.kap-row[data-v-2b13888e]:hover{background:var(--panel2)}.kap-row.expanded[data-v-2b13888e]{background:var(--color-accent-soft)}.kap-ts[data-v-2b13888e]{flex:none;color:var(--muted)}.kap-badge[data-v-2b13888e]{flex:none;padding:0 5px;border-radius:var(--radius-sm);font-size:max(9px,calc(var(--ui-font-size) - 4.5px));font-weight:500;line-height:1.7}.b-rest[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-accent-hover)}.b-in[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-success)}.b-out[data-v-2b13888e]{background:var(--color-accent-soft);color:var(--color-warning)}.b-life[data-v-2b13888e]{background:var(--panel2);color:var(--muted)}.b-err[data-v-2b13888e]{background:var(--color-warning);color:var(--bg)}.kap-label[data-v-2b13888e]{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kap-detail[data-v-2b13888e]{border-bottom:.5px solid var(--line);background:var(--bg);padding:6px 10px 10px}.kap-detail-actions[data-v-2b13888e]{display:flex;justify-content:flex-end;margin-bottom:4px}.kap-detail-actions button[data-v-2b13888e]{padding:2px 8px;border:.5px solid var(--line);border-radius:6px;background:var(--panel);color:var(--muted);font:inherit;cursor:pointer}.kap-detail-actions button[data-v-2b13888e]:hover{color:var(--color-text)}.kap-detail pre[data-v-2b13888e]{margin:0;max-height:320px;overflow:auto;white-space:pre-wrap;word-break:break-word;font-size:calc(var(--ui-font-size) - 3px);line-height:1.45}.kap-agg[data-v-2b13888e]{flex:1;min-height:0;overflow-y:auto;padding:8px 10px}.kap-agg h4[data-v-2b13888e]{margin:8px 0 4px;font-size:calc(var(--ui-font-size) - 2.5px);color:var(--muted)}.kap-agg table[data-v-2b13888e]{width:100%;border-collapse:collapse}.kap-agg th[data-v-2b13888e],.kap-agg td[data-v-2b13888e]{padding:3px 6px;border-bottom:.5px solid var(--line);text-align:left;vertical-align:top}.kap-agg th[data-v-2b13888e]{color:var(--muted);font-weight:500}.kap-agg .num[data-v-2b13888e]{text-align:right}.kap-agg .err[data-v-2b13888e]{color:var(--color-warning);font-weight:500}.kap-agg .mono[data-v-2b13888e]{word-break:break-all}.kap-fab[data-v-21de79fc]{position:fixed;right:10px;bottom:10px;z-index:var(--z-overlay);padding:5px 9px;border:.5px solid var(--line);border-radius:8px;background:var(--panel);color:var(--muted);font-family:var(--mono);font-size:calc(var(--ui-font-size) - 3px);font-weight:500;letter-spacing:.04em;cursor:pointer;opacity:.75}.kap-fab[data-v-21de79fc]:hover{opacity:1;color:var(--color-accent)}.server-auth-hint[data-v-331563ff]{margin:0 0 var(--space-3);font-size:var(--text-base);line-height:var(--leading-normal);color:var(--color-text-muted)}.server-auth-hint code[data-v-331563ff]{padding:1px 5px;font-family:var(--font-mono);font-size:var(--text-xs);background:var(--color-surface-sunken);border-radius:var(--radius-xs)}.internal-build-tag[data-v-14c3d0e0]{flex:none;display:inline-flex;align-items:center;gap:4px;padding:2px 7px;border-radius:999px;background:#f5a623;color:#3a2a00;font-size:11px;font-weight:700;letter-spacing:.01em;line-height:1.4;white-space:nowrap;user-select:none}.gload-fade-leave-active[data-v-ac226647]{transition:opacity .28s ease}.gload-fade-leave-to[data-v-ac226647]{opacity:0}.action-toast-enter-active[data-v-ac226647],.action-toast-leave-active[data-v-ac226647]{transition:opacity var(--duration-base) var(--ease-out),transform var(--duration-base) var(--ease-out)}.action-toast-leave-active[data-v-ac226647]{transition-duration:var(--duration-fast)}.action-toast-enter-from[data-v-ac226647],.action-toast-leave-to[data-v-ac226647]{opacity:0;transform:translateY(-6px)}.app-shell[data-v-ac226647]{position:fixed;top:var(--app-top, 0px);left:0;right:0;height:100vh;height:100dvh;height:var(--app-height, 100dvh);display:flex;flex-direction:column;overflow:hidden;box-sizing:border-box}.app[data-v-ac226647]{flex:1;min-height:0;position:relative;display:grid;grid-template-columns:auto 0 minmax(0,1fr) 0 auto;background:var(--bg);color:var(--color-text);overflow:hidden;box-sizing:border-box}.app[data-v-ac226647]>*{min-height:0;min-width:0}.app>.side[data-v-ac226647]{grid-column:1}.side-handle[data-v-ac226647]{grid-column:2}.app:not(.mobile)>.con[data-v-ac226647]{grid-column:3}.preview-handle[data-v-ac226647]{grid-column:4}.sidebar-toggle-btn[data-v-ac226647]{position:absolute;top:11px;left:16px;z-index:var(--z-sticky);animation:sidebar-toggle-btn-in-ac226647 .18s var(--ease-out) .12s backwards;-webkit-app-region:no-drag}.app.macos-desktop .sidebar-toggle-btn[data-v-ac226647]{left:84px;animation:none}.new-chat-btn[data-v-ac226647]{position:absolute;top:11px;left:42px;z-index:var(--z-sticky);animation:sidebar-toggle-btn-in-ac226647 .18s var(--ease-out) .12s backwards;-webkit-app-region:no-drag}.app.macos-desktop .new-chat-btn[data-v-ac226647]{left:110px}@keyframes sidebar-toggle-btn-in-ac226647{0%{opacity:0}}.internal-build-fab[data-v-ac226647]{position:absolute;right:var(--space-3);bottom:var(--space-3);z-index:var(--z-sticky);pointer-events:none}.app.mobile[data-v-ac226647]{grid-template-columns:1fr;grid-template-rows:auto 1fr}.global-preview[data-v-ac226647]{--preview-w: 460px;grid-column:5;min-width:0;min-height:0;width:0;background:var(--bg);overflow:hidden}.global-preview.open[data-v-ac226647]{width:var(--preview-w)}.global-preview[data-v-ac226647]:not(.mobile)>*{width:var(--preview-w);height:100%;box-sizing:border-box;border-left:.5px solid var(--line)}.global-preview.mobile[data-v-ac226647]{position:fixed;inset:0;z-index:var(--z-sticky);width:auto;transition:none;border-top:.5px solid var(--color-text)}:root{--panel-head-h: 48px;--panel-head-inset: calc((var(--panel-head-h) - var(--icon-button-sm)) / 2)}.app:not(.mobile) .chat-header{transition:padding-left .28s cubic-bezier(.4,0,.2,1)}.app.sidebar-collapsed .chat-header{padding-left:78px}.app.sidebar-collapsed.macos-desktop .chat-header{padding-left:146px}.app.macos-desktop .global-preview .ui-panel-header{-webkit-app-region:drag}.app.macos-desktop .global-preview .ui-panel-header button,.app.macos-desktop .global-preview .ui-panel-header input{-webkit-app-region:no-drag}.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel) .chat-header,.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel) .side .ch,.app.macos-desktop:has(.ch-menu,.open-in-menu,.dock-work-panel) .global-preview .ui-panel-header{-webkit-app-region:no-drag}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA) format("woff2-variations");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2) format("woff2-variations");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2) format("woff2-variations");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2) format("woff2-variations");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2) format("woff2-variations");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2) format("woff2-variations");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Noto Sans SC Variable;font-style:normal;font-display:swap;font-weight:100 900;src:url(/assets/NotoSansSC_wght_-BkPpiACN.woff2) format("woff2-variations")}@font-face{font-family:Schibsted Grotesk Variable;font-style:normal;font-display:swap;font-weight:400 900;src:url(/assets/SchibstedGrotesk_wght_-DIzGrWVg.woff2) format("woff2-variations")}@font-face{font-family:Schibsted Grotesk Variable;font-style:italic;font-display:swap;font-weight:400 900;src:url(/assets/SchibstedGrotesk-Italic_wght_-DjkBGo1z.woff2) format("woff2-variations")}:root{--dim: rgba(0, 0, 0, .6);--muted: rgba(0, 0, 0, .45);--faint: rgba(0, 0, 0, .3);--line: var(--color-line);--line2: var(--color-subtle);--canvas: #f9fbfc;--sh: 0 1px 3px rgba(28, 40, 66, .05), 0 6px 18px rgba(28, 40, 66, .06);--shc: 0 1px 2px rgba(28, 40, 66, .05);--panel: #f5f5f5;--panel2: rgba(0, 0, 0, .05);--bg: #ffffff;--blue: #1783ff;--blue2: #167ff7;--soft: #e8f3ff;--bd: rgba(23, 131, 255, .25);--logo: #1783ff;--bluebg: #e8f3ff;--blueln: rgba(23, 131, 255, .25);--ok: #0e7a38;--warn: #a9610a;--star: #eab308;--err: #c0392b;--hover: var(--color-hover);--r-xs: var(--radius-sm);--r-sm: var(--radius-md);--r-md: var(--radius-lg);--r-lg: var(--radius-xl);--ui-font-size: var(--ui-b2);--ui-font-size-sm: calc(var(--ui-font-size) - 1px);--ui-font-size-xs: calc(var(--ui-font-size) - 2px);--ui-font-size-lg: calc(var(--ui-font-size) + 1px);--ui-font-size-xl: calc(var(--ui-font-size) + 2px);--content-font-size: var(--md-b1);--code-font-size: calc(var(--content-font-size) - 2px);--mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--sans: var(--font-ui);color-scheme:light dark}html[data-color-scheme=light]{color-scheme:light}html[data-color-scheme=system]{color-scheme:light dark}html[data-color-scheme=dark]{color-scheme:dark;--dim: rgba(255, 255, 255, .56);--muted: rgba(255, 255, 255, .42);--faint: rgba(255, 255, 255, .26);--panel: #1f1f1f;--panel2: #121212;--bg: #121212;--blue: #1a88ff;--blue2: #258eff;--soft: rgba(26, 136, 255, .1);--bd: rgba(26, 136, 255, .28);--logo: #1a88ff;--bluebg: #292929;--blueln: rgba(255, 255, 255, .05);--ok: #3fb950;--warn: #d29922;--star: #facc15;--err: #f85149;--hover: var(--color-hover);--canvas: #161717;--sh: 0 1px 3px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .4);--shc: 0 1px 2px rgba(0, 0, 0, .35)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--dim: rgba(255, 255, 255, .56);--muted: rgba(255, 255, 255, .42);--faint: rgba(255, 255, 255, .26);--panel: #1f1f1f;--panel2: #121212;--bg: #121212;--blue: #1a88ff;--blue2: #258eff;--soft: rgba(26, 136, 255, .1);--bd: rgba(26, 136, 255, .28);--logo: #1a88ff;--bluebg: #292929;--blueln: rgba(255, 255, 255, .05);--ok: #3fb950;--warn: #d29922;--star: #facc15;--err: #f85149;--hover: var(--color-hover);--canvas: #161717;--sh: 0 1px 3px rgba(0, 0, 0, .35), 0 6px 18px rgba(0, 0, 0, .4);--shc: 0 1px 2px rgba(0, 0, 0, .35)}}:root{--color-bg: #ffffff;--color-surface: #f5f5f5;--color-surface-raised: #ffffff;--color-surface-overlay: #ffffff;--color-surface-sunken: #f5f5f5;--color-inline-code-bg: rgba(0, 0, 0, .03);--color-well: #f5f5f5;--color-surface-deep: #f5f5f5;--color-media-alpha-bg-1: color-mix(in srgb, var(--color-bg) 52%, var(--color-text) 48%);--color-media-alpha-bg-2: color-mix(in srgb, var(--color-bg) 42%, var(--color-text) 58%);--media-alpha-canvas: conic-gradient( var(--color-media-alpha-bg-1) 25%, var(--color-media-alpha-bg-2) 0 50%, var(--color-media-alpha-bg-1) 0 75%, var(--color-media-alpha-bg-2) 0 ) 0 0 / 16px 16px;--color-text: rgba(0, 0, 0, .9);--color-text-strong: #000000;--color-text-muted: rgba(0, 0, 0, .6);--color-text-faint: rgba(0, 0, 0, .45);--color-text-on-accent: #ffffff;--color-line: rgba(0, 0, 0, .13);--color-subtle: rgba(0, 0, 0, .05);--color-line-strong: rgba(0, 0, 0, .15);--color-scrim: rgba(0, 0, 0, .4);--color-scrim-strong: rgba(0, 0, 0, .6);--color-text-on-scrim: #ffffff;--color-selected: rgba(0, 0, 0, .05);--color-hover: rgba(0, 0, 0, .03);--color-sidebar-bg: #f9fbfc;--color-user-bubble-bg: #f5f5f5;--color-accent: #1783ff;--color-accent-hover: #167ff7;--color-accent-soft: #e8f3ff;--color-accent-bd: rgba(23, 131, 255, .25);--color-success: #0e7a38;--color-success-soft: #e7f6ee;--color-success-bd: #bfe3cc;--color-warning: #a9610a;--color-warning-soft: #fbf1e0;--color-warning-bd: #f0d9b8;--color-danger: #c0392b;--color-danger-soft: #fbeaea;--color-danger-bd: #f0cccc;--color-diff-add-bg: rgba(22, 196, 86, .25);--color-diff-del-bg: rgba(255, 56, 73, .25);--color-done: #8250df;--color-done-soft: #f3e8ff;--color-done-bd: #e0ccff;--color-info: #1783ff;--color-term-magenta: #8250df;--color-term-cyan: #1b7c83;--color-term-black: #24292f;--space-05: 2px;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--radius-xs: 4px;--radius-sm: 6px;--radius-md: 8px;--radius-lg: 12px;--radius-xl: 16px;--radius-2xl: 20px;--radius-composer: 32px;--corner-shape-composer: superellipse(1.5);--radius-full: 999px;--z-base: 0;--z-sticky: 100;--z-dropdown: 200;--z-overlay: 300;--z-modal: 400;--z-modal-dropdown: 500;--z-toast: 600;--z-tooltip: 650;--z-max: 9999;--shadow-xs: 0 1px 2px rgba(16, 24, 40, .04);--shadow-sm: 0 1px 2px rgba(16, 24, 40, .05), 0 1px 3px rgba(16, 24, 40, .06);--shadow-menu: 0 6px 18px lch(0% 0 0 / .02), 0 3px 9px lch(0% 0 0 / .04), 0 1px 1px lch(0% 0 0 / .04);--color-menu-bg: rgba(255, 255, 255, .95);--p-menu-backdrop: blur(24px) saturate(1.8);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(16, 24, 40, .07), 0 2px 4px rgba(16, 24, 40, .05);--shadow-lg: 0 12px 32px rgba(16, 24, 40, .12), 0 4px 10px rgba(16, 24, 40, .08);--shadow-xl: 0 24px 64px rgba(16, 24, 40, .18), 0 8px 20px rgba(16, 24, 40, .1);--ease-out: cubic-bezier(.16, 1, .3, 1);--ease-in-out: cubic-bezier(.4, 0, .2, 1);--duration-fast: .12s;--duration-base: .16s;--duration-slow: .26s;--duration-hover-intent: .25s;--color-composer-bg: #ffffff;--color-composer-line: rgba(0, 0, 0, .13);--color-composer-focus-line: rgba(0, 0, 0, .25);--color-send-bg: rgba(0, 0, 0, .9);--color-send-bg-hover: #252525;--color-send-icon: #ffffff;--color-stop-glyph: var(--color-danger);--color-send-bg-disabled: rgba(0, 0, 0, .05);--color-send-icon-disabled: rgba(0, 0, 0, .27);--opacity-send-disabled: 1;--shadow-send: 0 7px 16px -13px rgba(0, 0, 0, .38), 0 1px 2px rgba(0, 0, 0, .07);--shadow-send-hover: 0 8px 18px -13px rgba(0, 0, 0, .42), 0 1px 3px rgba(0, 0, 0, .09);--composer-send-icon-size: 28px;--font-ui-latin: "Schibsted Grotesk Variable", "Helvetica Neue", Arial;--font-ui: var(--font-ui-latin), "Noto Sans SC Variable", "Noto Sans SC", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Source Han Sans SC", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Ubuntu, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-display: var(--font-ui);--font-kbd: "Schibsted Grotesk Variable", system-ui, sans-serif;--font-mono: "JetBrains Mono Variable", "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;--text-2xs: calc(var(--ui-c1) - 1px);--text-xs: var(--ui-c1);--text-sm: calc(var(--ui-b2) - 1px);--text-base: var(--ui-b2);--text-lg: var(--ui-t2);--text-xl: var(--ui-t1);--text-2xl: var(--ui-t0);--leading-tight: 1.25;--leading-normal: 1.5;--leading-prose: 1.6;--leading-relaxed: 1.7;--weight-regular: 400;--weight-caption: 450;--weight-option-label: 475;--weight-medium: 500;--weight-ui-strong: 525;--weight-section-label: 600;--weight-semibold: 700;--ui-shift: calc(var(--base-font, 14px) - 14px);--md-shift: var(--ui-shift);--ui-t0: min(calc(20px + var(--ui-shift)), 24px);--ui-t1: min(calc(18px + var(--ui-shift)), 22px);--ui-t2: calc(16px + var(--ui-shift));--ui-b1: calc(15px + var(--ui-shift));--ui-b2: calc(14px + var(--ui-shift));--ui-c1: calc(12px + var(--ui-shift));--ui-c2: calc(10px + var(--ui-shift));--md-h1: calc(22px + var(--md-shift));--md-h2: calc(20px + var(--md-shift));--md-h3: calc(18px + var(--md-shift));--md-b1: calc(14px + var(--md-shift));--md-b2: calc(13px + var(--md-shift));--md-b3: calc(13px + var(--md-shift));--p-focus-ring: 0 0 0 3px var(--color-accent-soft);--p-focus-ring-strong: 0 0 0 3px var(--color-accent-soft), 0 0 0 1px var(--color-accent);--p-selection: rgba(23, 131, 255, .2);--p-ic-sm: 14px;--p-ic-md: 16px;--p-ic-lg: 20px;--p-hairline: .5px;--p-findring-w: 2px;--icon-button-sm: 26px;--p-chip-num: 20px;--p-sidebar-w: 264px;--p-content-max: 760px;--p-content-wide: 920px;--p-table-max: 1040px;--p-table-cell-max: 700px;--p-findbar-w: 340px;--p-bp-sm: 640px;--p-bp-md: 980px}:root,html[data-font-scale=medium]{--base-font: 14px}html[data-font-scale=small]{--base-font: 12px}html[data-font-scale=large]{--base-font: 16px}html[data-font-scale=xlarge]{--base-font: 18px}.text-ui-t0{font-size:var(--ui-t0);line-height:round(calc(var(--ui-t0) * 1.4),1px)}.text-ui-t1{font-size:var(--ui-t1);line-height:round(calc(var(--ui-t1) * 1.44),1px)}.text-ui-t2{font-size:var(--ui-t2);line-height:round(calc(var(--ui-t2) * 1.5),1px)}.text-ui-b1{font-size:var(--ui-b1);line-height:round(calc(var(--ui-b1) * 1.47),1px)}.text-ui-b2{font-size:var(--ui-b2);line-height:round(calc(var(--ui-b2) * 1.42),1px)}.text-ui-c1{font-size:var(--ui-c1);line-height:round(calc(var(--ui-c1) * 1.5),1px)}.text-ui-c2{font-size:var(--ui-c2);line-height:round(calc(var(--ui-c2) * 1.4),1px)}.text-md-h1{font-size:var(--md-h1);line-height:round(calc(var(--md-h1) * 1.63),1px)}.text-md-h2{font-size:var(--md-h2);line-height:round(calc(var(--md-h2) * 1.6),1px)}.text-md-h3{font-size:var(--md-h3);line-height:round(calc(var(--md-h3) * 1.56),1px)}.text-md-b1{font-size:var(--md-b1);line-height:round(calc(var(--md-b1) * 1.625),1px)}.text-md-b2{font-size:var(--md-b2);line-height:round(calc(var(--md-b2) * 1.6),1px)}.text-md-b3{font-size:var(--md-b3);line-height:round(calc(var(--md-b3) * 1.57),1px)}html[data-color-scheme=dark]{--color-bg: #121212;--color-surface: #1f1f1f;--color-surface-raised: #292929;--color-surface-overlay: rgba(255, 255, 255, .1);--color-surface-sunken: #121212;--color-inline-code-bg: rgba(255, 255, 255, .1);--color-well: #1f1f1f;--color-surface-deep: #0d0d0d;--color-text: rgba(255, 255, 255, .84);--color-text-strong: #ffffff;--color-text-muted: rgba(255, 255, 255, .56);--color-text-faint: rgba(255, 255, 255, .42);--color-line: rgba(255, 255, 255, .12);--color-subtle: rgba(255, 255, 255, .05);--color-line-strong: rgba(255, 255, 255, .18);--color-scrim: rgba(0, 0, 0, .6);--color-scrim-strong: rgba(0, 0, 0, .75);--color-selected: rgba(255, 255, 255, .1);--color-hover: rgba(255, 255, 255, .05);--color-sidebar-bg: #0d0d0d;--color-user-bubble-bg: #292929;--color-accent: #1a88ff;--color-accent-hover: #258eff;--color-accent-soft: rgba(26, 136, 255, .1);--color-accent-bd: rgba(26, 136, 255, .28);--p-selection: rgba(26, 136, 255, .2);--color-success: #3fb950;--color-success-soft: rgba(63, 185, 80, .14);--color-success-bd: rgba(63, 185, 80, .28);--color-warning: #d29922;--color-warning-soft: rgba(210, 153, 34, .14);--color-warning-bd: rgba(210, 153, 34, .28);--color-danger: #f85149;--color-danger-soft: rgba(248, 81, 73, .14);--color-danger-bd: rgba(248, 81, 73, .28);--color-diff-add-bg: rgba(63, 185, 80, .14);--color-diff-del-bg: rgba(248, 81, 73, .14);--color-done: #a371f7;--color-done-soft: rgba(163, 113, 247, .14);--color-done-bd: rgba(163, 113, 247, .28);--color-info: #1a88ff;--color-term-magenta: #d2a8ff;--color-term-cyan: #76e3ea;--color-term-black: #484f58;--color-composer-bg: #1f1f1f;--color-composer-line: rgba(255, 255, 255, .12);--color-composer-focus-line: rgba(255, 255, 255, .25);--color-send-bg: rgba(255, 255, 255, .84);--color-send-bg-hover: rgba(255, 255, 255, .848);--color-send-icon: #1f1f1f;--color-stop-glyph: color-mix(in srgb, var(--color-danger) 72%, transparent);--color-send-bg-disabled: rgba(255, 255, 255, .1);--color-send-icon-disabled: rgba(255, 255, 255, .28);--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .22), 0 1px 3px rgba(0, 0, 0, .18);--shadow-menu: 0 6px 18px rgba(0, 0, 0, .2), 0 3px 9px rgba(0, 0, 0, .24), 0 1px 1px rgba(0, 0, 0, .24);--color-menu-bg: rgba(41, 41, 41, .95);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3), 0 2px 4px rgba(0, 0, 0, .24);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .34), 0 4px 10px rgba(0, 0, 0, .28);--shadow-xl: 0 24px 64px rgba(0, 0, 0, .42), 0 8px 20px rgba(0, 0, 0, .32)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-bg: #121212;--color-surface: #1f1f1f;--color-surface-raised: #292929;--color-surface-overlay: rgba(255, 255, 255, .1);--color-surface-sunken: #121212;--color-inline-code-bg: rgba(255, 255, 255, .1);--color-well: #1f1f1f;--color-surface-deep: #0d0d0d;--color-text: rgba(255, 255, 255, .84);--color-text-strong: #ffffff;--color-text-muted: rgba(255, 255, 255, .56);--color-text-faint: rgba(255, 255, 255, .42);--color-line: rgba(255, 255, 255, .12);--color-subtle: rgba(255, 255, 255, .05);--color-line-strong: rgba(255, 255, 255, .18);--color-scrim: rgba(0, 0, 0, .6);--color-scrim-strong: rgba(0, 0, 0, .75);--color-selected: rgba(255, 255, 255, .1);--color-hover: rgba(255, 255, 255, .05);--color-sidebar-bg: #0d0d0d;--color-user-bubble-bg: #292929;--color-accent: #1a88ff;--color-accent-hover: #258eff;--color-accent-soft: rgba(26, 136, 255, .1);--color-accent-bd: rgba(26, 136, 255, .28);--p-selection: rgba(26, 136, 255, .2);--color-success: #3fb950;--color-success-soft: rgba(63, 185, 80, .14);--color-success-bd: rgba(63, 185, 80, .28);--color-warning: #d29922;--color-warning-soft: rgba(210, 153, 34, .14);--color-warning-bd: rgba(210, 153, 34, .28);--color-danger: #f85149;--color-danger-soft: rgba(248, 81, 73, .14);--color-danger-bd: rgba(248, 81, 73, .28);--color-diff-add-bg: rgba(63, 185, 80, .14);--color-diff-del-bg: rgba(248, 81, 73, .14);--color-done: #a371f7;--color-done-soft: rgba(163, 113, 247, .14);--color-done-bd: rgba(163, 113, 247, .28);--color-term-magenta: #d2a8ff;--color-term-cyan: #76e3ea;--color-term-black: #484f58;--color-info: #1a88ff;--color-composer-bg: #1f1f1f;--color-composer-line: rgba(255, 255, 255, .12);--color-composer-focus-line: rgba(255, 255, 255, .25);--color-send-bg: rgba(255, 255, 255, .84);--color-send-bg-hover: rgba(255, 255, 255, .848);--color-send-icon: #1f1f1f;--color-stop-glyph: color-mix(in srgb, var(--color-danger) 72%, transparent);--color-send-bg-disabled: rgba(255, 255, 255, .1);--color-send-icon-disabled: rgba(255, 255, 255, .28);--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 1px 2px rgba(0, 0, 0, .22), 0 1px 3px rgba(0, 0, 0, .18);--shadow-menu: 0 6px 18px rgba(0, 0, 0, .2), 0 3px 9px rgba(0, 0, 0, .24), 0 1px 1px rgba(0, 0, 0, .24);--color-menu-bg: rgba(41, 41, 41, .95);--shadow-input: 0 5px 16px -4px rgba(0, 0, 0, .07);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3), 0 2px 4px rgba(0, 0, 0, .24);--shadow-lg: 0 12px 32px rgba(0, 0, 0, .34), 0 4px 10px rgba(0, 0, 0, .28);--shadow-xl: 0 24px 64px rgba(0, 0, 0, .42), 0 8px 20px rgba(0, 0, 0, .32)}}:root{--color-sidebar-tint: rgba(255, 255, 255, .4)}html[data-color-scheme=dark]{--color-sidebar-tint: rgba(0, 0, 0, .25)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-sidebar-tint: rgba(0, 0, 0, .25)}}:root{--color-search-match: #ffe066;--color-search-match-current: #ffc531}html[data-color-scheme=dark]{--color-search-match: rgba(255, 197, 49, .3);--color-search-match-current: rgba(255, 197, 49, .55)}@media(prefers-color-scheme:dark){html[data-color-scheme=system]{--color-search-match: rgba(255, 197, 49, .3);--color-search-match-current: rgba(255, 197, 49, .55)}}::highlight(kimi-transcript-search){background-color:var(--color-search-match)}::highlight(kimi-transcript-search-current){background-color:var(--color-search-match-current)}*,*:before,*:after{box-sizing:border-box}html{-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit;margin:0}p,blockquote,dl,dd,figure,pre{margin:0}ol,ul,menu{list-style:none;margin:0;padding:0}a{color:inherit;text-decoration:inherit}b,strong{font-weight:var(--weight-medium)}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}button,input,optgroup,select,textarea{margin:0;padding:0;font-family:inherit;font-size:100%;line-height:inherit;color:inherit}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background:transparent;background-image:none}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block}img,video{max-width:100%;height:auto}textarea{resize:vertical}input::placeholder,textarea::placeholder{opacity:1}table{border-collapse:collapse;border-color:inherit;text-indent:0}hr{height:0;color:inherit;border-top-width:1px}fieldset{margin:0;padding:0}legend{padding:0}dialog{padding:0}summary{display:list-item}[hidden]{display:none}@supports (interpolate-size: allow-keywords){:root{interpolate-size:allow-keywords}}:root{--safe-top: env(safe-area-inset-top, 0px);--safe-right: env(safe-area-inset-right, 0px);--safe-bottom: env(safe-area-inset-bottom, 0px);--safe-left: env(safe-area-inset-left, 0px)}.kw-icon{display:inline-block;flex:none;vertical-align:-.15em}code,pre,kbd,samp,tt{font-feature-settings:"liga" 0,"calt" 0,"ss01" 0;font-variant-ligatures:none}html,body,#app{height:100%;margin:0;background:var(--bg)}#app{position:fixed;inset:0}html,body{overflow:hidden}@supports not selector(::-webkit-scrollbar){*{scrollbar-width:thin;scrollbar-color:color-mix(in srgb,var(--color-text) 12%,transparent) transparent}}*::-webkit-scrollbar{width:6px;height:6px}*::-webkit-scrollbar-track{background:transparent}*::-webkit-scrollbar-thumb{background:color-mix(in srgb,var(--color-text) 12%,transparent);border-radius:999px}*::-webkit-scrollbar-thumb:hover{background:color-mix(in srgb,var(--color-text) 25%,transparent)}*::-webkit-scrollbar-corner{background:transparent}body{font-family:var(--sans);color:var(--color-text);background:var(--bg);font-size:var(--ui-font-size);font-weight:400;line-height:1.6;font-optical-sizing:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:auto;font-synthesis:none;text-size-adjust:100%;-webkit-hyphens:none;hyphens:none}@media(max-width:640px){.backdrop{align-items:flex-end;justify-content:stretch}.backdrop .dialog{width:100%;max-width:100%;max-height:88vh;border-radius:var(--radius-xl) var(--radius-xl) 0 0;border-left:none;border-right:none;border-bottom:none;border-top:.5px solid var(--line);box-shadow:0 -10px 30px #0000002e;animation:kimi-sheet-up .26s cubic-bezier(.4,0,.2,1)}}@keyframes kimi-sheet-up{0%{transform:translateY(101%)}to{transform:translateY(0)}}.backdrop,.ob-backdrop{min-width:100vw!important;min-height:100vh!important;min-height:100dvh!important}@keyframes kimi-card-in{0%{opacity:0;transform:translateY(8px) scale(.995)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes kimi-check-in{0%{opacity:0;transform:scale(.4)}60%{opacity:1;transform:scale(1.15)}to{opacity:1;transform:scale(1)}}@media(prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;animation-delay:0ms!important;transition-duration:.001ms!important}}.ch-eyes{animation:kimi-eye-look 16s ease-in-out infinite}.ch-eye{transform-box:fill-box;transform-origin:center;animation:kimi-eye-blink 11s ease-in-out infinite}@keyframes kimi-eye-look{0%,42%{transform:translate(0)}47%,53%{transform:translate(2px)}58%,80%{transform:translate(0)}84%,90%{transform:translate(-2px)}95%,to{transform:translate(0)}}@keyframes kimi-eye-blink{0%,94%,to{transform:scaleY(1)}96.5%,98%{transform:scaleY(.12)}}@media(prefers-reduced-motion:reduce){.ch-eyes,.ch-eye{animation:none}}.blink-now .ch-eye{animation:kimi-eye-blink-once .24s ease-in-out}@keyframes kimi-eye-blink-once{0%,to{transform:scaleY(1)}50%{transform:scaleY(.1)}}.md .markdown-renderer img{min-width:0;min-height:0}.app{font-size:var(--ui-font-size)}.md,.md .markdown-renderer,.md .markdown-renderer p,.md .markdown-renderer li,.u-bub,.u-bub .u-text,.a-msg .msg,.ph{font-size:var(--content-font-size)}.md .markdown-renderer blockquote,.md .markdown-renderer td,.md .markdown-renderer th{font-size:var(--md-b2)}.md,.u-bub .u-text,.a-msg .msg{text-autospace:normal}.md .code-block-container pre,.md .markstream-pre,.md .code-block-container pre code,.md .diff-pre code,.md .markdown-renderer :not(pre)>code,.md .markdown-renderer .inline-code,.a-msg code{font-size:var(--md-b3)}.md .markdown-renderer :is(h1,h2,h3,h4) :not(pre)>code,.md .markdown-renderer :is(h1,h2,h3,h4) .inline-code{font-size:.9em}.queue-item,.queue-text,.ctx-num,.model-pill,.perm-pill,.mode-pill,.compact-chip,.qcard,.qtext,.qopt,.qbtn,.srow,.srow-val{font-size:var(--ui-font-size)}.qopt-desc,.srow-label{font-size:var(--ui-font-size-sm)}.code-block-header,.code-block-header *,.diff-lang,.queue-label,.qopt-key,.qstep,.srow-sub{font-size:var(--ui-font-size-xs)}@media(max-width:640px){.u-bub .u-text,.a-msg .msg,.ph{font-size:max(16px,var(--ui-font-size-xl))}}:root{--anim-rive-spin: .4167s;--anim-leftbar: .5333s;--anim-leftbar-shrink: .2s}#bar-divider{transform-box:view-box;transform-origin:9.3px 12px;transition:transform var(--anim-leftbar-shrink) linear}svg:hover #bar-divider,button:hover #bar-divider{transform:translate(-1.5px) scaleY(.5)}#bar-arrow{transform-box:view-box;transform-origin:0 0;transform:translate(63.95833%,50.625%) scale(0)}svg:hover #bar-arrow,button:hover #bar-arrow{animation:leftbar-arrow var(--anim-leftbar) linear 1 forwards}@keyframes leftbar-arrow{0%{transform:translate(62.97083%,50.625%) scale(-.6);opacity:0}3.125%{transform:translate(62.97083%,50.625%) scale(-.6);opacity:1}15.625%{transform:translate(59.0125%,50.625%) scale(-1);opacity:1}37.5%{transform:translate(52.08333%,50.625%) scale(-1);opacity:1}to{transform:translate(52.08333%,50.625%) scale(-1);opacity:1}}#bar-arrow-expand{transform-box:view-box;transform-origin:0 0;transform:translate(52.08333%,50.625%) scale(0)}svg:hover #bar-arrow-expand,button:hover #bar-arrow-expand{animation:leftbar-arrow-expand var(--anim-leftbar) linear 1 forwards}@keyframes leftbar-arrow-expand{0%{transform:translate(37.02917%,50.625%) scale(.6);opacity:0}3.125%{transform:translate(37.02917%,50.625%) scale(.6);opacity:1}15.625%{transform:translate(40.9875%,50.625%) scale(1);opacity:1}37.5%{transform:translate(52.08333%,50.625%) scale(1);opacity:1}to{transform:translate(52.08333%,50.625%) scale(1);opacity:1}}#p1{transform-box:view-box;transform-origin:0 0}svg:hover #p1,button:hover #p1{animation:nc-plus-spin var(--anim-rive-spin) linear 1 forwards}@keyframes nc-plus-spin{0%{transform:translate(11.5px,11.5px)}8%{transform:translate(11.501px,11.48px) rotate(1.1795deg) scale(1.02022)}12%{transform:translate(11.511px,11.46px) rotate(2.8374deg) scale(1.03026)}20%{transform:translate(11.562px,11.401px) rotate(8.8167deg) scale(1.05041)}24%{transform:translate(11.608px,11.361px) rotate(13.4726deg) scale(1.06017)}32%{transform:translate(11.751px,11.278px) rotate(25.9719deg) scale(1.08008)}48%{transform:translate(12.149px,11.222px) rotate(55.8418deg) scale(1.12025)}52%{transform:translate(12.235px,11.236px) rotate(62.0737deg) scale(1.12953)}60%{transform:translate(12.371px,11.276px) rotate(72.1167deg) scale(1.14954)}68%{transform:translate(12.446px,11.346px) rotate(79.3018deg) scale(1.12048)}76%{transform:translate(12.488px,11.403px) rotate(84.2633deg) scale(1.09046)}88%{transform:translate(12.509px,11.464px) rotate(88.52deg) scale(1.04535)}to{transform:translate(12.5px,11.5px) rotate(90deg)}}#af-p1{transform-box:view-box;transform-origin:18.4px 16.3px}svg:hover #af-p1,button:hover #af-p1{animation:folder-plus-spin var(--anim-rive-spin) linear 1 forwards}@keyframes folder-plus-spin{0%{transform:none}8%{transform:rotate(1.1795deg) scale(1.02022)}12%{transform:rotate(2.8374deg) scale(1.03026)}20%{transform:rotate(8.8167deg) scale(1.05041)}24%{transform:rotate(13.4726deg) scale(1.06017)}32%{transform:rotate(25.9719deg) scale(1.08008)}48%{transform:rotate(55.8418deg) scale(1.12025)}52%{transform:rotate(62.0737deg) scale(1.12953)}60%{transform:rotate(72.1167deg) scale(1.14954)}68%{transform:rotate(79.3018deg) scale(1.12048)}76%{transform:rotate(84.2633deg) scale(1.09046)}88%{transform:rotate(88.52deg) scale(1.04535)}to{transform:rotate(90deg)}} diff --git a/apps/kimi-code/dist-web/assets/index-foxHOIBX.js b/apps/kimi-code/dist-web/assets/index-DzfhniX8.js similarity index 99% rename from apps/kimi-code/dist-web/assets/index-foxHOIBX.js rename to apps/kimi-code/dist-web/assets/index-DzfhniX8.js index a99313333..41ef0c27f 100644 --- a/apps/kimi-code/dist-web/assets/index-foxHOIBX.js +++ b/apps/kimi-code/dist-web/assets/index-DzfhniX8.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-DwG2KKf1.js","assets/index-O6aQX5k9.js","assets/index-D1h84VfZ.js","assets/index-BTY1et1y.css"])))=>i.map(i=>d[i]); -import{bR as Q}from"./index-D1h84VfZ.js";var Y=class{chunks=[];cached="";dirty=!1;length=0;append(e){e&&(this.chunks.push(e),this.length+=e.length,this.dirty=!0,this.chunks.length>256&&this.compact())}clear(e=""){this.chunks=e?[e]:[],this.cached=e,this.dirty=!1,this.length=e.length}toString(){return this.dirty&&(this.cached=this.chunks.join(""),this.dirty=!1),this.cached}compact(){this.chunks=[this.chunks.join("")]}};function $(e,i){e.replaceChildren();const t=document.createElement("div");t.className="stream-diffs-shell",t.style.overflow="auto",t.style.maxHeight=typeof i=="number"?`${i}px`:i??"none";const n=document.createElement("div");return n.className="stream-diffs-surface",t.appendChild(n),e.appendChild(t),{shell:t,surface:n}}function E(e,i,t){return{name:e,contents:i,lang:t}}var Z=class{input;container;surface;instance;diff;selectedLines=null;disposed=!1;renderListeners=new Set;visualRevision=0;visualReadyPromise=Promise.resolve(!1);resolveVisualReady;constructor(e){this.input=e}async mount(e){this.disposed=!1,this.container=e,this.surface=$(e).surface,await this.render()}async update(e){this.input=e,this.surface&&await this.render(!0)}updateFile(e,i){return this.update({kind:"file",file:e,annotations:i,options:this.input.kind==="file"?this.input.options:void 0,workerManager:this.input.kind==="file"?this.input.workerManager:void 0})}updateDiff(e,i,t){return this.update({kind:"diff",oldFile:e,newFile:i,annotations:t,options:z(this.input)?this.input.options:void 0,workerManager:z(this.input)?this.input.workerManager:void 0})}updateParsedDiff(e,i){return this.update({kind:"diff",fileDiff:e,annotations:i,options:z(this.input)?this.input.options:void 0,workerManager:z(this.input)?this.input.workerManager:void 0})}updatePatch(e,i=0,t,n=0){return this.update({kind:"patch",patch:e,patchIndex:n,fileIndex:i,annotations:t,options:this.input.kind==="patch"?this.input.options:void 0,workerManager:this.input.kind==="patch"?this.input.workerManager:void 0})}updateMergeConflict(e,i){return this.update({kind:"merge-conflict",file:e,annotations:i,options:this.input.kind==="merge-conflict"?this.input.options:void 0,workerManager:this.input.kind==="merge-conflict"?this.input.workerManager:void 0})}setSelectedLines(e){this.selectedLines=e,this.instance?.setSelectedLines(e)}setAnnotations(e){this.instance&&(this.input.kind==="file"?(this.input.annotations=e,this.instance.setLineAnnotations(this.input.annotations)):(this.input.annotations=e,this.instance.setLineAnnotations(this.input.annotations)),this.emitRender())}setThemeType(e){this.input.options?this.input.options={...this.input.options,themeType:e}:this.input.options={themeType:e},this.instance?.setThemeType(e)}async setTheme(e){this.input.options?this.input.options={...this.input.options,theme:e}:this.input.options={theme:e},this.surface&&await this.render(!1)}async setOptions(e){this.input.options=e,this.surface&&await this.render(!1)}acceptReject(e,i){if(!z(this.input)||!this.diff)throw new Error("acceptReject() requires a diff view");const{diffAcceptRejectHunk:t}=this.module;return this.diff=t(this.diff,e,i),this.instance.render({fileDiff:this.diff,containerWrapper:this.surface,lineAnnotations:this.input.annotations}),this.diff}resolveConflict(e,i){if(this.input.kind!=="merge-conflict")throw new Error("resolveConflict() requires a merge-conflict view");const t=this.instance.resolveConflict(e,i);return t&&(this.input.file=t.file,this.diff=t.fileDiff),t?.file}getResolvedFile(){if(!z(this.input)||!this.diff||this.diff.isPartial)return;const e="newFile"in this.input?this.input.newFile:void 0;return{name:e?.name??this.diff.name,contents:this.diff.additionLines.join(""),lang:e?.lang??this.diff.lang}}getDiff(){return this.diff}getInput(){return this.input}getNativeInstance(){return this.instance}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}async whenVisualReady(){let e=this.visualReadyPromise;for(;;){const i=await e;if(e===this.visualReadyPromise)return i;e=this.visualReadyPromise}}dispose(){this.disposed=!0,this.invalidateVisualReady(),this.instance?.cleanUp(),this.instance=void 0,this.surface=void 0,this.container?.replaceChildren(),this.container=void 0,this.renderListeners.clear()}module;async render(e=!0){const i=this.surface;if(!i||this.disposed)return;const t=this.beginVisualRender(),n=this.module??=await Q(()=>import("./index-DwG2KKf1.js"),__vite__mapDeps([0,1,2,3]));if(this.disposed||i!==this.surface)return;if(this.instance?.cleanUp(),i.replaceChildren(),this.input.kind==="file"){const o=new n.File(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);o.render({file:this.input.file,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=o,o.setSelectedLines(this.selectedLines),this.diff=void 0;return}if(z(this.input)){if(e||!this.diff)if(this.input.kind==="patch"){const a=n.parsePatchFiles(this.input.patch)[this.input.patchIndex??0];if(!a)throw new Error(`Patch does not contain patch index ${this.input.patchIndex??0}`);const d=a.files[this.input.fileIndex??0];if(!d)throw new Error(`Patch does not contain file index ${this.input.fileIndex??0}`);this.diff=d}else"fileDiff"in this.input?this.diff=this.input.fileDiff:this.diff=n.parseDiffFromFile(this.input.oldFile,this.input.newFile,this.input.options?.parseDiffOptions);const o=new n.FileDiff(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);o.render({fileDiff:this.diff,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=o,o.setSelectedLines(this.selectedLines);return}const r=new n.UnresolvedFile(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);r.render({file:this.input.file,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=r,r.setSelectedLines(this.selectedLines),this.diff=r.fileDiff}emitRender(){for(const e of this.renderListeners)e()}beginVisualRender(){this.resolveVisualReady?.(!1);const e=++this.visualRevision;return this.visualReadyPromise=new Promise(i=>{this.resolveVisualReady=i}),e}markVisualReady(e){this.disposed||e!==this.visualRevision||(this.resolveVisualReady?.(!0),this.resolveVisualReady=void 0,this.emitRender())}invalidateVisualReady(){this.visualRevision++,this.resolveVisualReady?.(!1),this.resolveVisualReady=void 0}};function x(e){return new Z(e)}function ee(e){return!e||e.useTokenTransformer===!0||!e.onTokenClick&&!e.onTokenEnter&&!e.onTokenLeave?e:{...e,useTokenTransformer:!0}}function b(e,i){const t=ee(e),n=t?.onPostRender;return{...t,onPostRender(...r){n?.(...r),i()}}}function z(e){return e.kind==="diff"||e.kind==="patch"}var K=class{options;state="idle";stats={characters:0,lines:0,writes:0,resets:0,renderMode:"plain-text",overflowed:!1};text=new Y;pending=[];scheduled;generation=0;container;shell;surface;finalizedSurface;plainText;finalizePromise;renderListeners=new Set;finalizedRenderSubscription;constructor(e={}){this.options=e}async mount(e){if(this.state==="disposed")throw new Error("Cannot mount a disposed code stream. Create a new controller instead.");++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.plainText=void 0,this.pending=[],this.setState("mounting"),this.container=e;const{shell:i,surface:t}=$(e,this.options.maxHeight);this.shell=i,this.surface=t,this.mountPlainText(t),this.stats.startedAt??=performance.now(),this.setState("streaming")}append(e){if(e){if(this.state==="finalized"||this.state==="finalizing"||this.state==="disposed")throw new Error(`Cannot append while stream is ${this.state}`);this.text.append(e),this.stats.characters=this.text.length,this.stats.lines+=ie(e)+(this.stats.lines===0?1:0),this.pending.push(e),this.scheduleFlush()}}updateSnapshot(e){const i=this.text.toString();if(e.startsWith(i)){this.append(e.slice(i.length));return}const t=this.options.nonAppendBehavior??"reset";if(t!=="ignore"){if(t==="throw")throw new Error("Snapshot violates the append-only stream contract");return this.reset(e)}}async consume(e){try{if(Symbol.asyncIterator in e)for await(const i of e)this.append(i);else{const i=e.getReader();try{for(;;){const{done:t,value:n}=await i.read();if(t)break;this.append(n)}}finally{i.releaseLock()}}}catch(i){throw this.fail(i),i}}async flush(){if(this.cancelScheduledFlush(),!this.pending.length)return;const e=this.shouldFollowViewport(),i=this.pending.join("");this.pending.length=0,this.plainText?.append(i),this.stats.writes++,this.followViewport(e),this.emitRender()}finalize(e={view:"stream"}){if(this.state==="finalized")return Promise.resolve();if(this.finalizePromise)return this.finalizePromise;const i=this.performFinalize(e).finally(()=>{this.finalizePromise===i&&(this.finalizePromise=void 0)});return this.finalizePromise=i,i}async performFinalize(e){if(this.state==="disposed")throw new Error("Cannot finalize a disposed code stream");const i=this.generation;if(this.setState("finalizing"),await this.flush(),i!==this.generation)return;if(this.stats.finalizedAt=performance.now(),!e.view||e.view==="stream"){this.setState("finalized");return}const t=this.surface;if(!t)throw new Error("Mount the stream before finalizing to a file or diff view");const n=this.options.fileName??`code.${this.options.language??"txt"}`,r=E(n,this.getText(),this.options.language);let o;if(e.view==="file"){const{annotations:c,workerManager:g,view:S,...T}=e;o=x({kind:"file",file:r,annotations:c,options:{theme:this.options.theme,themeType:this.options.themeType,...T},workerManager:g??this.options.workerManager})}else{const{annotations:c,original:g,workerManager:S,view:T,...L}=e;o=x({kind:"diff",oldFile:E(n,g,this.options.language),newFile:r,annotations:c,options:{theme:this.options.theme,themeType:this.options.themeType,...L},workerManager:S??this.options.workerManager})}const a=document.createElement("div");if(a.className="stream-diffs-finalized",await o.mount(a),i!==this.generation){o.dispose();return}const d=this.shell,p=d?.scrollTop??0,h=d?d.scrollHeight-d.scrollTop-d.clientHeight:0;t.replaceWith(a),this.surface=a,this.plainText=void 0,this.finalizedSurface=o,this.finalizedRenderSubscription=o.onDidRender(()=>this.emitRender()),d&&(this.options.autoScroll==="always"||this.options.autoScroll!=="never"&&h<=(this.options.autoScrollThresholdPx??32)?d.scrollTop=d.scrollHeight:d.scrollTop=p),this.setState("finalized"),this.emitRender()}async reset(e=""){const i=this.container;++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.plainText=void 0,this.pending=[],this.finalizePromise=void 0,this.text.clear(),this.stats.resets++,this.stats.characters=0,this.stats.lines=0,this.stats.renderMode="plain-text",this.stats.overflowed=!1,this.setState("idle"),e&&this.append(e),i&&await this.mount(i)}setThemeType(e){this.options.themeType=e,this.finalizedSurface?.setThemeType(e)}async setTheme(e){this.options.theme=e,this.finalizedSurface&&await this.finalizedSurface.setTheme(e)}async setLanguage(e){if(e===this.options.language||(this.options.language=e,!this.finalizedSurface))return;const i=this.finalizedSurface.getInput();i.kind==="file"?await this.finalizedSurface.updateFile({...i.file,lang:e},i.annotations):i.kind==="diff"&&"oldFile"in i&&await this.finalizedSurface.updateDiff({...i.oldFile,lang:e},{...i.newFile,lang:e},i.annotations)}getText(){return this.text.toString()}getState(){return this.state}getStats(){return{...this.stats}}getElement(){return this.shell}getFinalizedSurface(){return this.finalizedSurface}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}dispose(){++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.plainText=void 0,this.container=void 0,this.surface=void 0,this.shell=void 0,this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.finalizePromise=void 0,this.renderListeners.clear(),this.setState("disposed")}scheduleFlush(){if(this.scheduled!=null||!this.plainText)return;const e=this.options.flushStrategy??"raf";e==="raf"&&typeof requestAnimationFrame=="function"?this.scheduled=requestAnimationFrame(()=>void this.flush()):this.scheduled=globalThis.setTimeout(()=>void this.flush(),e==="raf"?0:e.intervalMs)}cancelScheduledFlush(){this.scheduled!=null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.scheduled),clearTimeout(this.scheduled),this.scheduled=void 0)}shouldFollowViewport(){const e=this.shell;return!e||this.options.autoScroll==="never"?!1:this.options.autoScroll==="always"?!0:e.scrollHeight-e.scrollTop-e.clientHeight<=(this.options.autoScrollThresholdPx??32)}followViewport(e=this.shouldFollowViewport()){this.shell&&e&&(this.shell.scrollTop=this.shell.scrollHeight)}mountPlainText(e){const i=document.createElement("pre");i.className="stream-diffs-plain-text",i.dataset.streamDiffsState="streaming",i.style.margin="0",i.style.whiteSpace=this.options.wrap?"pre-wrap":"pre",i.style.overflowWrap=this.options.wrap?"anywhere":"normal",i.textContent=this.getText(),e.replaceChildren(i),this.plainText=i}setState(e){this.state=e,this.options.onStateChange?.(e)}emitRender(){for(const e of this.renderListeners)e()}fail(e){this.state!=="disposed"&&(this.setState("error"),this.options.onError?.(e))}};function ie(e){let i=0;for(let t=0;t<e.length;t++)e.charCodeAt(t)===10&&i++;return i}function de(e){return new K(e)}var G=class{options;state="idle";generation=0;original="";modified="";container;shell;surface;finalizedSurface;finalizePromise;renderListeners=new Set;finalizedRenderSubscription;constructor(e={}){this.options=e}async mount(e,i=this.original,t=this.modified){if(this.state==="disposed")throw new Error("Cannot mount a disposed diff stream. Create a new controller instead.");++this.generation,this.original=i,this.modified=t,this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.setState("mounting"),this.container=e;const{shell:n,surface:r}=$(e,this.options.maxHeight);this.shell=n,this.surface=r,this.renderPre(),this.setState("streaming")}update(e,i){if(this.state==="disposed")throw new Error("Cannot update a disposed diff stream");return this.original=e,this.modified=i,this.finalizedSurface?this.finalizedSurface.updateDiff(this.asFile(e),this.asFile(i)):(this.renderPre(),this.emitRender(),Promise.resolve())}finalize(e){if(this.state==="finalized")return Promise.resolve(this.finalizedSurface);if(this.finalizePromise)return this.finalizePromise;const i=this.performFinalize(e).finally(()=>{this.finalizePromise===i&&(this.finalizePromise=void 0)});return this.finalizePromise=i,i}async performFinalize(e){if(this.state==="disposed")throw new Error("Cannot finalize a disposed diff stream");const i=this.surface;if(!i)throw new Error("Mount the diff stream before finalizing it");const t=this.generation;this.setState("finalizing");const n=x({kind:"diff",oldFile:this.asFile(this.original),newFile:this.asFile(this.modified),annotations:e,options:{...this.options,diffStyle:this.options.diffStyle??"unified"},workerManager:this.options.workerManager}),r=document.createElement("div");if(r.className="stream-diffs-finalized",await n.mount(r),t!==this.generation){n.dispose();return}const o=this.shell,a=o?.scrollTop??0;return i.replaceWith(r),this.surface=r,this.finalizedSurface=n,this.finalizedRenderSubscription=n.onDidRender(()=>this.emitRender()),o&&(o.scrollTop=a),this.setState("finalized"),this.emitRender(),n}setThemeType(e){this.options.themeType=e,this.finalizedSurface?.setThemeType(e)}async setTheme(e){this.options.theme=e,this.finalizedSurface&&await this.finalizedSurface.setTheme(e)}async setLanguage(e){if(e!==this.options.language){if(this.options.language=e,this.finalizedSurface){const i=this.finalizedSurface.getInput();i.kind==="diff"&&"oldFile"in i&&await this.finalizedSurface.updateDiff({...i.oldFile,lang:e},{...i.newFile,lang:e},i.annotations);return}this.renderPre()}}getOriginal(){return this.original}getModified(){return this.modified}getState(){return this.state}getElement(){return this.shell}getFinalizedSurface(){return this.finalizedSurface}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}dispose(){++this.generation,this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.container=void 0,this.shell=void 0,this.surface=void 0,this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.finalizePromise=void 0,this.renderListeners.clear(),this.setState("disposed")}renderPre(){const e=this.surface;if(!e||this.finalizedSurface)return;const i=document.createElement("div");i.className=`stream-diffs-diff-pre stream-diffs-diff-pre--${this.options.diffStyle??"unified"}`,i.dataset.streamDiffsState="streaming",i.style.minWidth="max-content",(this.options.diffStyle??"unified")==="split"?(i.style.display="grid",i.style.gridTemplateColumns="minmax(0, 1fr) minmax(0, 1fr)",i.append(this.createPre(this.original,"deletions"),this.createPre(this.modified,"additions"))):i.append(this.createPre(te(this.original,this.modified),"unified")),e.replaceChildren(i)}createPre(e,i){const t=document.createElement("pre");return t.className=`stream-diffs-diff-pre__pane stream-diffs-diff-pre__pane--${i}`,t.dataset.side=i,t.style.margin="0",t.style.whiteSpace=this.options.wrap?"pre-wrap":"pre",t.style.overflowWrap=this.options.wrap?"anywhere":"normal",t.textContent=e,t}asFile(e){return E(this.options.fileName??`code.${this.options.language??"txt"}`,e,this.options.language)}setState(e){this.state=e,this.options.onStateChange?.(e)}emitRender(){for(const e of this.renderListeners)e()}};function te(e,i){const t=e.split(` +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/index-ZmzTmhry.js","assets/index-BZFTzQ6y.js","assets/index-D-7nOosq.js","assets/index-DGHD7Bg9.css"])))=>i.map(i=>d[i]); +import{bR as Q}from"./index-D-7nOosq.js";var Y=class{chunks=[];cached="";dirty=!1;length=0;append(e){e&&(this.chunks.push(e),this.length+=e.length,this.dirty=!0,this.chunks.length>256&&this.compact())}clear(e=""){this.chunks=e?[e]:[],this.cached=e,this.dirty=!1,this.length=e.length}toString(){return this.dirty&&(this.cached=this.chunks.join(""),this.dirty=!1),this.cached}compact(){this.chunks=[this.chunks.join("")]}};function $(e,i){e.replaceChildren();const t=document.createElement("div");t.className="stream-diffs-shell",t.style.overflow="auto",t.style.maxHeight=typeof i=="number"?`${i}px`:i??"none";const n=document.createElement("div");return n.className="stream-diffs-surface",t.appendChild(n),e.appendChild(t),{shell:t,surface:n}}function E(e,i,t){return{name:e,contents:i,lang:t}}var Z=class{input;container;surface;instance;diff;selectedLines=null;disposed=!1;renderListeners=new Set;visualRevision=0;visualReadyPromise=Promise.resolve(!1);resolveVisualReady;constructor(e){this.input=e}async mount(e){this.disposed=!1,this.container=e,this.surface=$(e).surface,await this.render()}async update(e){this.input=e,this.surface&&await this.render(!0)}updateFile(e,i){return this.update({kind:"file",file:e,annotations:i,options:this.input.kind==="file"?this.input.options:void 0,workerManager:this.input.kind==="file"?this.input.workerManager:void 0})}updateDiff(e,i,t){return this.update({kind:"diff",oldFile:e,newFile:i,annotations:t,options:z(this.input)?this.input.options:void 0,workerManager:z(this.input)?this.input.workerManager:void 0})}updateParsedDiff(e,i){return this.update({kind:"diff",fileDiff:e,annotations:i,options:z(this.input)?this.input.options:void 0,workerManager:z(this.input)?this.input.workerManager:void 0})}updatePatch(e,i=0,t,n=0){return this.update({kind:"patch",patch:e,patchIndex:n,fileIndex:i,annotations:t,options:this.input.kind==="patch"?this.input.options:void 0,workerManager:this.input.kind==="patch"?this.input.workerManager:void 0})}updateMergeConflict(e,i){return this.update({kind:"merge-conflict",file:e,annotations:i,options:this.input.kind==="merge-conflict"?this.input.options:void 0,workerManager:this.input.kind==="merge-conflict"?this.input.workerManager:void 0})}setSelectedLines(e){this.selectedLines=e,this.instance?.setSelectedLines(e)}setAnnotations(e){this.instance&&(this.input.kind==="file"?(this.input.annotations=e,this.instance.setLineAnnotations(this.input.annotations)):(this.input.annotations=e,this.instance.setLineAnnotations(this.input.annotations)),this.emitRender())}setThemeType(e){this.input.options?this.input.options={...this.input.options,themeType:e}:this.input.options={themeType:e},this.instance?.setThemeType(e)}async setTheme(e){this.input.options?this.input.options={...this.input.options,theme:e}:this.input.options={theme:e},this.surface&&await this.render(!1)}async setOptions(e){this.input.options=e,this.surface&&await this.render(!1)}acceptReject(e,i){if(!z(this.input)||!this.diff)throw new Error("acceptReject() requires a diff view");const{diffAcceptRejectHunk:t}=this.module;return this.diff=t(this.diff,e,i),this.instance.render({fileDiff:this.diff,containerWrapper:this.surface,lineAnnotations:this.input.annotations}),this.diff}resolveConflict(e,i){if(this.input.kind!=="merge-conflict")throw new Error("resolveConflict() requires a merge-conflict view");const t=this.instance.resolveConflict(e,i);return t&&(this.input.file=t.file,this.diff=t.fileDiff),t?.file}getResolvedFile(){if(!z(this.input)||!this.diff||this.diff.isPartial)return;const e="newFile"in this.input?this.input.newFile:void 0;return{name:e?.name??this.diff.name,contents:this.diff.additionLines.join(""),lang:e?.lang??this.diff.lang}}getDiff(){return this.diff}getInput(){return this.input}getNativeInstance(){return this.instance}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}async whenVisualReady(){let e=this.visualReadyPromise;for(;;){const i=await e;if(e===this.visualReadyPromise)return i;e=this.visualReadyPromise}}dispose(){this.disposed=!0,this.invalidateVisualReady(),this.instance?.cleanUp(),this.instance=void 0,this.surface=void 0,this.container?.replaceChildren(),this.container=void 0,this.renderListeners.clear()}module;async render(e=!0){const i=this.surface;if(!i||this.disposed)return;const t=this.beginVisualRender(),n=this.module??=await Q(()=>import("./index-ZmzTmhry.js"),__vite__mapDeps([0,1,2,3]));if(this.disposed||i!==this.surface)return;if(this.instance?.cleanUp(),i.replaceChildren(),this.input.kind==="file"){const o=new n.File(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);o.render({file:this.input.file,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=o,o.setSelectedLines(this.selectedLines),this.diff=void 0;return}if(z(this.input)){if(e||!this.diff)if(this.input.kind==="patch"){const a=n.parsePatchFiles(this.input.patch)[this.input.patchIndex??0];if(!a)throw new Error(`Patch does not contain patch index ${this.input.patchIndex??0}`);const d=a.files[this.input.fileIndex??0];if(!d)throw new Error(`Patch does not contain file index ${this.input.fileIndex??0}`);this.diff=d}else"fileDiff"in this.input?this.diff=this.input.fileDiff:this.diff=n.parseDiffFromFile(this.input.oldFile,this.input.newFile,this.input.options?.parseDiffOptions);const o=new n.FileDiff(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);o.render({fileDiff:this.diff,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=o,o.setSelectedLines(this.selectedLines);return}const r=new n.UnresolvedFile(b(this.input.options,()=>this.markVisualReady(t)),this.input.workerManager);r.render({file:this.input.file,containerWrapper:i,lineAnnotations:this.input.annotations}),this.instance=r,r.setSelectedLines(this.selectedLines),this.diff=r.fileDiff}emitRender(){for(const e of this.renderListeners)e()}beginVisualRender(){this.resolveVisualReady?.(!1);const e=++this.visualRevision;return this.visualReadyPromise=new Promise(i=>{this.resolveVisualReady=i}),e}markVisualReady(e){this.disposed||e!==this.visualRevision||(this.resolveVisualReady?.(!0),this.resolveVisualReady=void 0,this.emitRender())}invalidateVisualReady(){this.visualRevision++,this.resolveVisualReady?.(!1),this.resolveVisualReady=void 0}};function x(e){return new Z(e)}function ee(e){return!e||e.useTokenTransformer===!0||!e.onTokenClick&&!e.onTokenEnter&&!e.onTokenLeave?e:{...e,useTokenTransformer:!0}}function b(e,i){const t=ee(e),n=t?.onPostRender;return{...t,onPostRender(...r){n?.(...r),i()}}}function z(e){return e.kind==="diff"||e.kind==="patch"}var K=class{options;state="idle";stats={characters:0,lines:0,writes:0,resets:0,renderMode:"plain-text",overflowed:!1};text=new Y;pending=[];scheduled;generation=0;container;shell;surface;finalizedSurface;plainText;finalizePromise;renderListeners=new Set;finalizedRenderSubscription;constructor(e={}){this.options=e}async mount(e){if(this.state==="disposed")throw new Error("Cannot mount a disposed code stream. Create a new controller instead.");++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.plainText=void 0,this.pending=[],this.setState("mounting"),this.container=e;const{shell:i,surface:t}=$(e,this.options.maxHeight);this.shell=i,this.surface=t,this.mountPlainText(t),this.stats.startedAt??=performance.now(),this.setState("streaming")}append(e){if(e){if(this.state==="finalized"||this.state==="finalizing"||this.state==="disposed")throw new Error(`Cannot append while stream is ${this.state}`);this.text.append(e),this.stats.characters=this.text.length,this.stats.lines+=ie(e)+(this.stats.lines===0?1:0),this.pending.push(e),this.scheduleFlush()}}updateSnapshot(e){const i=this.text.toString();if(e.startsWith(i)){this.append(e.slice(i.length));return}const t=this.options.nonAppendBehavior??"reset";if(t!=="ignore"){if(t==="throw")throw new Error("Snapshot violates the append-only stream contract");return this.reset(e)}}async consume(e){try{if(Symbol.asyncIterator in e)for await(const i of e)this.append(i);else{const i=e.getReader();try{for(;;){const{done:t,value:n}=await i.read();if(t)break;this.append(n)}}finally{i.releaseLock()}}}catch(i){throw this.fail(i),i}}async flush(){if(this.cancelScheduledFlush(),!this.pending.length)return;const e=this.shouldFollowViewport(),i=this.pending.join("");this.pending.length=0,this.plainText?.append(i),this.stats.writes++,this.followViewport(e),this.emitRender()}finalize(e={view:"stream"}){if(this.state==="finalized")return Promise.resolve();if(this.finalizePromise)return this.finalizePromise;const i=this.performFinalize(e).finally(()=>{this.finalizePromise===i&&(this.finalizePromise=void 0)});return this.finalizePromise=i,i}async performFinalize(e){if(this.state==="disposed")throw new Error("Cannot finalize a disposed code stream");const i=this.generation;if(this.setState("finalizing"),await this.flush(),i!==this.generation)return;if(this.stats.finalizedAt=performance.now(),!e.view||e.view==="stream"){this.setState("finalized");return}const t=this.surface;if(!t)throw new Error("Mount the stream before finalizing to a file or diff view");const n=this.options.fileName??`code.${this.options.language??"txt"}`,r=E(n,this.getText(),this.options.language);let o;if(e.view==="file"){const{annotations:c,workerManager:g,view:S,...T}=e;o=x({kind:"file",file:r,annotations:c,options:{theme:this.options.theme,themeType:this.options.themeType,...T},workerManager:g??this.options.workerManager})}else{const{annotations:c,original:g,workerManager:S,view:T,...L}=e;o=x({kind:"diff",oldFile:E(n,g,this.options.language),newFile:r,annotations:c,options:{theme:this.options.theme,themeType:this.options.themeType,...L},workerManager:S??this.options.workerManager})}const a=document.createElement("div");if(a.className="stream-diffs-finalized",await o.mount(a),i!==this.generation){o.dispose();return}const d=this.shell,p=d?.scrollTop??0,h=d?d.scrollHeight-d.scrollTop-d.clientHeight:0;t.replaceWith(a),this.surface=a,this.plainText=void 0,this.finalizedSurface=o,this.finalizedRenderSubscription=o.onDidRender(()=>this.emitRender()),d&&(this.options.autoScroll==="always"||this.options.autoScroll!=="never"&&h<=(this.options.autoScrollThresholdPx??32)?d.scrollTop=d.scrollHeight:d.scrollTop=p),this.setState("finalized"),this.emitRender()}async reset(e=""){const i=this.container;++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.plainText=void 0,this.pending=[],this.finalizePromise=void 0,this.text.clear(),this.stats.resets++,this.stats.characters=0,this.stats.lines=0,this.stats.renderMode="plain-text",this.stats.overflowed=!1,this.setState("idle"),e&&this.append(e),i&&await this.mount(i)}setThemeType(e){this.options.themeType=e,this.finalizedSurface?.setThemeType(e)}async setTheme(e){this.options.theme=e,this.finalizedSurface&&await this.finalizedSurface.setTheme(e)}async setLanguage(e){if(e===this.options.language||(this.options.language=e,!this.finalizedSurface))return;const i=this.finalizedSurface.getInput();i.kind==="file"?await this.finalizedSurface.updateFile({...i.file,lang:e},i.annotations):i.kind==="diff"&&"oldFile"in i&&await this.finalizedSurface.updateDiff({...i.oldFile,lang:e},{...i.newFile,lang:e},i.annotations)}getText(){return this.text.toString()}getState(){return this.state}getStats(){return{...this.stats}}getElement(){return this.shell}getFinalizedSurface(){return this.finalizedSurface}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}dispose(){++this.generation,this.cancelScheduledFlush(),this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.plainText=void 0,this.container=void 0,this.surface=void 0,this.shell=void 0,this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.finalizePromise=void 0,this.renderListeners.clear(),this.setState("disposed")}scheduleFlush(){if(this.scheduled!=null||!this.plainText)return;const e=this.options.flushStrategy??"raf";e==="raf"&&typeof requestAnimationFrame=="function"?this.scheduled=requestAnimationFrame(()=>void this.flush()):this.scheduled=globalThis.setTimeout(()=>void this.flush(),e==="raf"?0:e.intervalMs)}cancelScheduledFlush(){this.scheduled!=null&&(typeof cancelAnimationFrame=="function"&&cancelAnimationFrame(this.scheduled),clearTimeout(this.scheduled),this.scheduled=void 0)}shouldFollowViewport(){const e=this.shell;return!e||this.options.autoScroll==="never"?!1:this.options.autoScroll==="always"?!0:e.scrollHeight-e.scrollTop-e.clientHeight<=(this.options.autoScrollThresholdPx??32)}followViewport(e=this.shouldFollowViewport()){this.shell&&e&&(this.shell.scrollTop=this.shell.scrollHeight)}mountPlainText(e){const i=document.createElement("pre");i.className="stream-diffs-plain-text",i.dataset.streamDiffsState="streaming",i.style.margin="0",i.style.whiteSpace=this.options.wrap?"pre-wrap":"pre",i.style.overflowWrap=this.options.wrap?"anywhere":"normal",i.textContent=this.getText(),e.replaceChildren(i),this.plainText=i}setState(e){this.state=e,this.options.onStateChange?.(e)}emitRender(){for(const e of this.renderListeners)e()}fail(e){this.state!=="disposed"&&(this.setState("error"),this.options.onError?.(e))}};function ie(e){let i=0;for(let t=0;t<e.length;t++)e.charCodeAt(t)===10&&i++;return i}function de(e){return new K(e)}var G=class{options;state="idle";generation=0;original="";modified="";container;shell;surface;finalizedSurface;finalizePromise;renderListeners=new Set;finalizedRenderSubscription;constructor(e={}){this.options=e}async mount(e,i=this.original,t=this.modified){if(this.state==="disposed")throw new Error("Cannot mount a disposed diff stream. Create a new controller instead.");++this.generation,this.original=i,this.modified=t,this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.setState("mounting"),this.container=e;const{shell:n,surface:r}=$(e,this.options.maxHeight);this.shell=n,this.surface=r,this.renderPre(),this.setState("streaming")}update(e,i){if(this.state==="disposed")throw new Error("Cannot update a disposed diff stream");return this.original=e,this.modified=i,this.finalizedSurface?this.finalizedSurface.updateDiff(this.asFile(e),this.asFile(i)):(this.renderPre(),this.emitRender(),Promise.resolve())}finalize(e){if(this.state==="finalized")return Promise.resolve(this.finalizedSurface);if(this.finalizePromise)return this.finalizePromise;const i=this.performFinalize(e).finally(()=>{this.finalizePromise===i&&(this.finalizePromise=void 0)});return this.finalizePromise=i,i}async performFinalize(e){if(this.state==="disposed")throw new Error("Cannot finalize a disposed diff stream");const i=this.surface;if(!i)throw new Error("Mount the diff stream before finalizing it");const t=this.generation;this.setState("finalizing");const n=x({kind:"diff",oldFile:this.asFile(this.original),newFile:this.asFile(this.modified),annotations:e,options:{...this.options,diffStyle:this.options.diffStyle??"unified"},workerManager:this.options.workerManager}),r=document.createElement("div");if(r.className="stream-diffs-finalized",await n.mount(r),t!==this.generation){n.dispose();return}const o=this.shell,a=o?.scrollTop??0;return i.replaceWith(r),this.surface=r,this.finalizedSurface=n,this.finalizedRenderSubscription=n.onDidRender(()=>this.emitRender()),o&&(o.scrollTop=a),this.setState("finalized"),this.emitRender(),n}setThemeType(e){this.options.themeType=e,this.finalizedSurface?.setThemeType(e)}async setTheme(e){this.options.theme=e,this.finalizedSurface&&await this.finalizedSurface.setTheme(e)}async setLanguage(e){if(e!==this.options.language){if(this.options.language=e,this.finalizedSurface){const i=this.finalizedSurface.getInput();i.kind==="diff"&&"oldFile"in i&&await this.finalizedSurface.updateDiff({...i.oldFile,lang:e},{...i.newFile,lang:e},i.annotations);return}this.renderPre()}}getOriginal(){return this.original}getModified(){return this.modified}getState(){return this.state}getElement(){return this.shell}getFinalizedSurface(){return this.finalizedSurface}onDidRender(e){return this.renderListeners.add(e),{dispose:()=>this.renderListeners.delete(e)}}dispose(){++this.generation,this.finalizedSurface?.dispose(),this.finalizedRenderSubscription?.dispose(),this.container?.replaceChildren(),this.container=void 0,this.shell=void 0,this.surface=void 0,this.finalizedSurface=void 0,this.finalizedRenderSubscription=void 0,this.finalizePromise=void 0,this.renderListeners.clear(),this.setState("disposed")}renderPre(){const e=this.surface;if(!e||this.finalizedSurface)return;const i=document.createElement("div");i.className=`stream-diffs-diff-pre stream-diffs-diff-pre--${this.options.diffStyle??"unified"}`,i.dataset.streamDiffsState="streaming",i.style.minWidth="max-content",(this.options.diffStyle??"unified")==="split"?(i.style.display="grid",i.style.gridTemplateColumns="minmax(0, 1fr) minmax(0, 1fr)",i.append(this.createPre(this.original,"deletions"),this.createPre(this.modified,"additions"))):i.append(this.createPre(te(this.original,this.modified),"unified")),e.replaceChildren(i)}createPre(e,i){const t=document.createElement("pre");return t.className=`stream-diffs-diff-pre__pane stream-diffs-diff-pre__pane--${i}`,t.dataset.side=i,t.style.margin="0",t.style.whiteSpace=this.options.wrap?"pre-wrap":"pre",t.style.overflowWrap=this.options.wrap?"anywhere":"normal",t.textContent=e,t}asFile(e){return E(this.options.fileName??`code.${this.options.language??"txt"}`,e,this.options.language)}setState(e){this.state=e,this.options.onStateChange?.(e)}emitRender(){for(const e of this.renderListeners)e()}};function te(e,i){const t=e.split(` `),n=i.split(` `);let r=0;for(;r<t.length&&r<n.length&&t[r]===n[r];)r++;let o=0;for(;o<t.length-r&&o<n.length-r&&t[t.length-o-1]===n[n.length-o-1];)o++;return[...t.slice(0,r).map(a=>` ${a}`),...t.slice(r,t.length-o).map(a=>`- ${a}`),...n.slice(r,n.length-o).map(a=>`+ ${a}`),...t.slice(t.length-o).map(a=>` ${a}`)].join(` `)}function he(e){return new G(e)}function ue(e={}){let i,t,n,r,o,a="text",d="",p="",h,c=0,g="system",S=U(e),T=q(e);const L={disableLineNumbers:e.lineNumbers===!1,overflow:e.wordWrap==="on"?"wrap":"scroll",enableLineSelection:e.enableLineSelection},M=()=>({...L,theme:S,themeType:g});async function H(s,l,u){k();const w=c;if(N(s,e),h=s,a=R(u),_(l))return V(s,l,a);if(e.stream===!1)return O(s,l,a);const f=new K({...M(),...F(e),fileName:`code.${a}`,language:a,maxHeight:e.MAX_HEIGHT,autoScroll:e.autoScrollOnUpdate===!1?"never":"near-bottom",autoScrollThresholdPx:e.autoScrollThresholdPx,workerManager:e.workerManager});if(i=f,f.append(l),await f.mount(s),w!==c||i!==f||h!==s)throw f.dispose(),new Error("Editor creation was cancelled");return e.onController?.(f),r=C(()=>f.getText(),s,()=>f.getFinalizedSurface(),m=>f.onDidRender(m)),r}async function I(s,l,u,w){k();const f=c;N(s,e),h=s,a=R(w),d=l,p=u;let m,v;if(e.stream===!1){if(m=x({kind:"diff",oldFile:y(l),newFile:y(u),annotations:e.lineAnnotations,workerManager:e.workerManager,options:{...M(),diffStyle:e.diffStyle??(e.renderSideBySide===!1?"unified":"split"),...F(e)}}),n=m,await m.mount(s),f!==c||n!==m||h!==s)throw m.dispose(),new Error("Editor creation was cancelled");e.onController?.(m)}else{if(v=new G({...M(),...F(e),fileName:`code.${a}`,language:a,diffStyle:e.diffStyle??(e.renderSideBySide===!1?"unified":"split"),maxHeight:e.MAX_HEIGHT,wrap:e.wordWrap==="on",workerManager:e.workerManager}),t=v,await v.mount(s,l,u),f!==c||t!==v||h!==s)throw v.dispose(),new Error("Editor creation was cancelled");e.onController?.(v)}return o=oe(()=>d,()=>p,s,()=>m??v?.getFinalizedSurface()),o}async function X(s,l=a){const u=R(l);if(_(s)){n?.getInput().kind==="merge-conflict"?(a=u,await n.updateMergeConflict(y(s),e.lineAnnotations)):h&&await V(h,s,u);return}if(e.stream===!1){n?.getInput().kind==="file"?(a=u,await n.updateFile(y(s),e.lineAnnotations)):h&&await O(h,s,u);return}if(!i){h&&await H(h,s,u);return}if(i.getState()==="finalized"){s!==i.getText()&&await i.reset(s);return}if(u!==a){a=u,await i.setLanguage(u),s!==i.getText()&&await i.reset(s);return}const w=i.getText();s.startsWith(w)?i.append(s.slice(w.length)):await i.reset(s)}async function P(s,l,u=a){if(d=s,p=l,a=R(u),t){await t.update(s,l);return}if(!n){h&&await I(h,s,l,u);return}await n.updateDiff(y(s),y(l))}function k(){c++,i?.dispose(),t?.dispose(),t||n?.dispose(),i=void 0,t=void 0,n=void 0,r=void 0,o=void 0,h=void 0}async function O(s,l,u){k();const w=c;h=s,a=u;const f=x({kind:"file",file:y(l),annotations:e.lineAnnotations,workerManager:e.workerManager,options:{...M(),...F(e)}});if(n=f,await f.mount(s),w!==c||n!==f||h!==s)throw f.dispose(),new Error("Editor creation was cancelled");return e.onController?.(f),r=C(()=>B(f)??l,s,()=>f,m=>f.onDidRender(m)),r}async function V(s,l,u){k();const w=c;h=s,a=u;const f=x({kind:"merge-conflict",file:y(l),annotations:e.lineAnnotations,workerManager:e.workerManager,options:{...M(),...F(e)}});if(n=f,await f.mount(s),w!==c||n!==f||h!==s)throw f.dispose(),new Error("Editor creation was cancelled");return e.onController?.(f),r=C(()=>B(f)??l,s,()=>f,m=>f.onDidRender(m)),r}function _(s){return e.mergeConflict===!1?!1:/^<<<<<<< .+$/m.test(s)&&/^=======$/m.test(s)&&/^>>>>>>> .+$/m.test(s)}async function J(s){if(s){if(typeof s=="string"){const l=e.themes;if(l?.[0]===s){await W(),g="dark",i?.setThemeType("dark"),t?.setThemeType("dark"),n?.setThemeType("dark");return}if(l?.[1]===s){await W(),g="light",i?.setThemeType("light"),t?.setThemeType("light"),n?.setThemeType("light");return}}T=void 0,S=s,await j(s)}}async function W(){const s=q(e);!s||s===T||(T=s,S=U(e),await j(S))}async function j(s){await i?.setTheme(s),await t?.setTheme(s),await n?.setTheme(s)}function y(s){return E(`code.${a||"txt"}`,s,a)}return{runtimeKind:"stream-diffs",createEditor:H,createDiffEditor:I,updateCode:X,appendCode(s){i?.append(s)},async finalizeCode(){if(!i||i.getState()==="finalized")return i?.getFinalizedSurface();const s=F(e);return delete s.lineAnnotations,await i.finalize({view:"file",...s,theme:S,themeType:g,annotations:e.lineAnnotations,workerManager:e.workerManager}),i.getFinalizedSurface()},async finalizeDiff(){return t&&(n=await t.finalize(e.lineAnnotations)),n},updateDiff:P,updateOriginal(s,l=a){return P(s,p,l)},updateModified(s,l=a){return P(d,s,l)},appendOriginal(s,l=a){return P(d+s,p,l)},appendModified(s,l=a){return P(d,p+s,l)},cleanupEditor:k,safeClean:k,setTheme:J,async setLanguage(s){if(a=R(s),await i?.setLanguage(a),await t?.setLanguage(a),n&&!t){const l=n.getInput();l.kind==="file"||l.kind==="merge-conflict"?await n.update({...l,file:{...l.file,lang:a}}):l.kind==="diff"&&"oldFile"in l&&await n.update({...l,oldFile:{...l.oldFile,lang:a},newFile:{...l.newFile,lang:a}})}},getCurrentTheme:()=>S,getEditor:()=>le,getEditorView:()=>r??null,getDiffEditorView:()=>o??null,getDiffModels:()=>({original:D(()=>d),modified:D(()=>n?.getResolvedFile()?.contents??t?.getModified()??p)}),getCode:()=>{const s=n?.getInput();return s?.kind==="diff"||s?.kind==="patch"?{original:d,modified:n?.getResolvedFile()?.contents??p}:s?.kind==="file"||s?.kind==="merge-conflict"?s.file.contents:t?{original:t.getOriginal(),modified:t.getModified()}:i?.getText()??null},refreshDiffPresentation:()=>n?.update(n.getInput()),whenVisualReady:async()=>{const s=h,l=c,u=n??i?.getFinalizedSurface()??t?.getFinalizedSurface();return!u||!await u.whenVisualReady()?!1:ne(s,()=>l===c&&s===h&&u===(n??i?.getFinalizedSurface()??t?.getFinalizedSurface()),()=>se(n??i?.getFinalizedSurface()??t?.getFinalizedSurface()))}}}async function ne(e,i,t){if(!e||typeof window>"u")return!1;let n="",r,o=0;for(let a=0;a<120;a+=1){if(!i())return!1;const d=e.querySelector(".stream-diffs-shell"),p=d?.querySelector("diffs-container")?.shadowRoot?.querySelector("pre"),h=d?.getBoundingClientRect(),c=p?.textContent??"";if(h&&h.width>0&&h.height>0&&p&&t()){const g=`${Math.round(h.width)}:${Math.round(h.height)}:${p.scrollWidth}:${p.scrollHeight}:${c.length}`;if(o=p===r&&g===n?o+1:1,r=p,n=g,o>=2)return!0}else n="",r=void 0,o=0;await ae()}return!1}function se(e){if(!e)return!0;const i=e.getNativeInstance(),t=i?.fileRenderer??i?.hunksRenderer;if(!t)return!0;const n=t.renderCache;if(!n?.result)return!1;if(n.highlighted===!0)return!0;const r=e.getInput();if(R(r.kind==="file"||r.kind==="merge-conflict"?r.file.lang:"oldFile"in r?r.oldFile.lang??r.newFile.lang:e.getDiff()?.lang)==="text")return!0;const o=Number(t.getTokenizeMaxLength?.()??1e5);if(r.kind==="file"||r.kind==="merge-conflict")return re(r.file.contents)>o;const a=e.getDiff();return!!a&&Math.max(a.additionLines.length,a.deletionLines.length)>o}function R(e){return!e||/^(?:text|txt|plain|plaintext)$/i.test(e)?"text":e}function re(e){if(!e)return 0;let i=1;for(let t=0;t<e.length;t+=1)e.charCodeAt(t)===10&&(i+=1);return i}function ae(){return new Promise(e=>{let i=!1;const t=()=>{i||(i=!0,window.clearTimeout(r),window.cancelAnimationFrame(n),e())},n=window.requestAnimationFrame(t),r=window.setTimeout(t,50)})}function U(e){return e.themes?.length&&typeof e.themes[0]=="string"&&typeof e.themes[1]=="string"?{dark:e.themes[0],light:e.themes[1]}:e.theme??void 0}function q(e){if(!(typeof e.themes?.[0]!="string"||typeof e.themes?.[1]!="string"))return`${e.themes[0]} diff --git a/apps/kimi-code/dist-web/assets/index-DwG2KKf1.js b/apps/kimi-code/dist-web/assets/index-ZmzTmhry.js similarity index 99% rename from apps/kimi-code/dist-web/assets/index-DwG2KKf1.js rename to apps/kimi-code/dist-web/assets/index-ZmzTmhry.js index abd97bb1c..68d0a62c8 100644 --- a/apps/kimi-code/dist-web/assets/index-DwG2KKf1.js +++ b/apps/kimi-code/dist-web/assets/index-ZmzTmhry.js @@ -1,4 +1,4 @@ -import{t as pe,b as Ln,n as Or,c as Nr,a as Fr,d as zr,s as Ur,g as Vr,e as Br}from"./index-O6aQX5k9.js";import{f as Ld}from"./index-O6aQX5k9.js";import{bR as k}from"./index-D1h84VfZ.js";const Ei="diffs-container",$r=(()=>{try{return!1}catch{return!1}})(),Wr=/(?=^From [a-f0-9]+ .+$)/m,Ti=/(?=^diff --git)/gm,Ul=/(?=^---\s+\S)/gm,Vl=/(?=^@@ )/gm,Gr=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: (.*))?/m,jr=/(?<=\n)/,qr=/^(---|\+\+\+)\s+([^\t\r\n]+)/,Kr=/^(---|\+\+\+)\s+[ab]\/([^\t\r\n]+)/,Yr=/^diff --git (?:"a\/(.+?)"|a\/(.+?)) (?:"b\/(.+?)"|b\/(.+?))$/,Xr=/^index ([0-9a-f]+)\.\.([0-9a-f]+)(?: (\d+))?$/i,Bl=/^<{7,}(?:\s.*)?$/,$l=/^\|{7,}(?:\s.*)?$/,Wl=/^={7,}$/,Gl=/^>{7,}(?:\s.*)?$/,on="header-prefix",sn="header-metadata",an="header-custom",_={dark:"pierre-dark",light:"pierre-light"},Ii="data-theme-css",Ri="data-unsafe-css",Qr="data-core-css",Jr="data-diffs-scrollbar-measure",Ai="--diffs-scrollbar-gutter-measured",jl=1,Zr=1e5,ln={hunkLineCount:50,lineHeight:20,diffHeaderHeight:44,spacing:8},_e={...ln,hunkLineCount:1},eo={paddingTop:8,paddingBottom:8,gap:8},to={omega:.015,positionEpsilon:.5,velocityEpsilon:.05},no=Object.freeze({fromStart:0,fromEnd:0}),Ae={startingLine:0,totalLines:1/0,bufferBefore:0,bufferAfter:0},Hi={startingLine:0,totalLines:0,bufferBefore:0,bufferAfter:0},Ie=new Set;let Re=null;function Y(e){Ie.add(e),Re??=requestAnimationFrame(Mi)}function io(e){Ie.delete(e),Ie.size===0&&Re!=null&&(cancelAnimationFrame(Re),Re=null)}function Mi(e){const t=new Set(Ie);Ie.clear();for(const n of t)try{n(e)}catch(i){console.error(i)}Ie.size>0?Re=requestAnimationFrame(Mi):Re=null}function He(e,t,n){if(e===t||e==null||t==null)return e===t;const i=new Set(n),r=Object.keys(e),o=new Set(Object.keys(t));for(const s of r)if(o.delete(s),!i.has(s)&&(!(s in t)||e[s]!==t[s]))return!1;for(const s of Array.from(o))if(!i.has(s))return!1;return!0}function De(e,t){return e==null||t==null||typeof e=="string"||typeof t=="string"?e===t:e.dark===t.dark&&e.light===t.light}function dn(e,t){const n=e?.theme??_,i=t?.theme??_,r=kn(e),o=kn(t);return De(n,i)&&He(e,t,["theme","parseDiffOptions"])&&He(r,o)}function kn(e){if(e!=null&&"parseDiffOptions"in e)return e.parseDiffOptions}function Wt(e,t){return e?.start===t?.start&&e?.end===t?.end&&e?.side===t?.side&&e?.endSide===t?.endSide}function Gt({scrollTop:e,scrollHeight:t,height:n,fitPerfectly:i=!1,fitPerfectlyOverscroll:r=0,overscrollSize:o}){const s=n+o*2,l=i?n+r*2:s;if(t=Math.max(t,l),s>=t||i){const h=Math.max(e-r,0),c=Math.min(e+l,t);return{top:h,bottom:Math.max(c,h)}}let a=e+n/2-s/2,d=a+s;return a<0&&(a=0),d>t&&(d=t),a=Math.floor(Math.max(a,0)),{top:a,bottom:Math.ceil(Math.max(Math.min(d,t),a))}}function ro(){return typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function W(e){return{type:"text",value:e}}function A({tagName:e,children:t=[],properties:n={}}){return{type:"element",tagName:e,properties:n,children:t}}function pt({name:e,width:t=16,height:n=16,properties:i}){return A({tagName:"svg",properties:{width:t,height:n,viewBox:"0 0 16 16",...i},children:[A({tagName:"use",properties:{href:`#${e.replace(/^#/,"")}`}})]})}function oo(e){let t=e.children[0];for(;t!=null;){if(t.type==="element"&&t.tagName==="code")return t;"children"in t?t=t.children[0]:t=null}}function Ee(e){return A({tagName:"div",properties:{"data-gutter":""},children:e})}function Di(e,t,n,i={}){return A({tagName:"div",properties:{"data-line-type":e,"data-column-number":t,"data-line-index":n,...i},children:t!=null?[A({tagName:"span",properties:{"data-line-number-content":""},children:[W(`${t}`)]})]:void 0})}function j(e,t,n){return A({tagName:"div",properties:{"data-gutter-buffer":t,"data-buffer-size":n,"data-line-type":t==="annotation"?void 0:e,style:t==="annotation"?`grid-row: span ${n};`:`grid-row: span ${n};min-height:calc(${n} * 1lh);`}})}function so(){return A({tagName:"button",properties:{"data-utility-button":"",type:"button"},children:[pt({name:"diffs-icon-plus",properties:{"data-icon":""}})]})}function ao(e,t){return e.lineNumber===t.lineNumber&&e.side===t.side}var Pi=class{mode;options;hoveredLine;hoveredToken;pre;gutterUtilityLine;gutterUtilityContainer;gutterUtilityButton;gutterUtilitySlot;interactiveLinesAttr=!1;interactiveLineNumbersAttr=!1;hasPointerListeners=!1;hasDocumentPointerListeners=!1;selectedRange=null;proposedSelectedRange;renderedSelectionRange;selectionAnchor;queuedSelectionRender;pointerSession={mode:"idle"};constructor(e,t){this.mode=e,this.options=t}setOptions(e){this.options=e}cleanUp(){this.pre?.removeEventListener("click",this.handlePointerClick),this.pre?.removeEventListener("pointerdown",this.handlePointerDown),this.pre?.removeEventListener("pointermove",this.handlePointerMove),this.pre?.removeEventListener("pointerleave",this.handlePointerLeave),this.pre?.removeAttribute("data-interactive-lines"),this.pre?.removeAttribute("data-interactive-line-numbers"),this.pre=void 0,this.gutterUtilityContainer?.remove(),this.gutterUtilityLine=void 0,this.gutterUtilityContainer=void 0,this.gutterUtilityButton=void 0,this.gutterUtilitySlot=void 0,this.clearHoveredLine(),this.clearHoveredToken(),this.detachDocumentPointerListeners(),this.clearPointerSession(),this.queuedSelectionRender!=null&&(cancelAnimationFrame(this.queuedSelectionRender),this.queuedSelectionRender=void 0),this.interactiveLinesAttr=!1,this.interactiveLineNumbersAttr=!1,this.hasPointerListeners=!1}setup(e){this.setSelectionDirty();const{usesCustomGutterUtility:t=!1,enableGutterUtility:n=!1}=this.options;this.pre!==e&&(this.cleanUp(),this.pre=e),n?this.ensureGutterUtilityNode(t):this.gutterUtilityContainer!=null&&(this.gutterUtilityContainer.remove(),this.gutterUtilityLine=void 0,this.gutterUtilityContainer=void 0,this.gutterUtilityButton=void 0,this.gutterUtilitySlot=void 0,this.pointerSession.mode==="gutterSelecting"&&(this.clearPointerSession(),this.detachDocumentPointerListeners())),this.syncPointerListeners(e),this.updateInteractiveLineAttributes(),this.renderSelection(),this.placeUtility()}setSelectionDirty(){this.renderedSelectionRange=void 0}isSelectionDirty(){return this.renderedSelectionRange===null}setSelection(e,t){const n=!(e===this.selectedRange||Wt(e??void 0,this.selectedRange??void 0));!this.isSelectionDirty()&&!n||(this.proposedSelectedRange=void 0,this.selectedRange=e,this.renderSelection(),this.placeUtility(),n&&t?.notify!==!1&&this.notifySelectionCommitted())}getSelection(){return this.selectedRange}getHoveredLine=()=>{const e=this.gutterUtilityLine??this.hoveredLine;if(e!=null){if(this.mode==="diff"&&e.type==="diff-line")return{lineNumber:e.lineNumber,side:e.annotationSide};if(this.mode==="file"&&e.type==="line")return{lineNumber:e.lineNumber}}};handlePointerClick=e=>{const{onHunkExpand:t,onLineClick:n,onLineNumberClick:i,onTokenClick:r,onMergeConflictActionClick:o}=this.options;t==null&&n==null&&i==null&&o==null&&r==null||this.options.onGutterUtilityClick!=null&&et(e.composedPath())||(he(this.options.__debugPointerEvents,"click","FileDiff.DEBUG.handlePointerClick:",e),this.handlePointerEvent({eventType:"click",event:e}))};handlePointerMove=e=>{if(e.pointerType!=="mouse")return;const{lineHoverHighlight:t="disabled",onLineEnter:n,onLineLeave:i,onTokenEnter:r,onTokenLeave:o,enableGutterUtility:s=!1}=this.options;t==="disabled"&&!s&&n==null&&i==null&&r==null&&o==null||(he(this.options.__debugPointerEvents,"move","FileDiff.DEBUG.handlePointerMove:",e),this.handlePointerEvent({eventType:"move",event:e}))};handlePointerLeave=e=>{const{__debugPointerEvents:t}=this.options;if(he(t,"move","FileDiff.DEBUG.handlePointerLeave: no event"),this.hoveredLine==null&&this.hoveredToken==null){he(t,"move","FileDiff.DEBUG.handlePointerLeave: returned early, no hovered line or token");return}this.hoveredToken!=null&&(this.options.onTokenLeave?.(this.hoveredToken,e),this.clearHoveredToken()),this.hoveredLine!=null&&(this.options.onLineLeave?.({...this.hoveredLine,event:e}),this.clearHoveredLine()),this.placeUtility()};handlePointerEvent({eventType:e,event:t}){const{__debugPointerEvents:n}=this.options,i=t.composedPath();he(n,e,"FileDiff.DEBUG.handlePointerEvent:",{eventType:e,composedPath:i});const r=this.resolvePointerTarget(i);he(n,e,"FileDiff.DEBUG.handlePointerEvent: resolvePointerTarget result:",r);const{onLineClick:o,onLineNumberClick:s,onLineEnter:l,onLineLeave:a,onTokenClick:d,onTokenEnter:h,onTokenLeave:c,onHunkExpand:u,onMergeConflictActionClick:f}=this.options;switch(e){case"move":{const g=Tt(r)&&this.hoveredLine?.lineElement===r.lineElement;ut(r)&&this.hoveredToken?.tokenElement===r.tokenElement||(this.hoveredToken!=null&&(c?.(this.hoveredToken,t),this.clearHoveredToken()),ut(r)&&(this.setHoveredToken(this.toTokenEventBaseProps(r)),h?.(this.hoveredToken,t))),g||(this.hoveredLine!=null&&(a?.({...this.hoveredLine,event:t}),this.clearHoveredLine()),Tt(r)?(this.setHoveredLine(this.toEventBaseProps(r)),this.placeUtility(),l?.({...this.hoveredLine,event:t})):this.placeUtility());break}case"click":{if(r==null)break;if(co(r)&&f!=null){f(r);break}if(ho(r)&&u!=null){u(r.hunkIndex,r.all||t.shiftKey?"both":r.direction,r.all||t.shiftKey?Number.POSITIVE_INFINITY:void 0);break}if(!Tt(r))break;ut(r)&&d!=null&&d(this.toTokenEventBaseProps(r),t);const g=this.toEventBaseProps(r);s!=null&&r.numberColumn?s({...g,event:t}):o?.({...g,event:t});break}}}syncPointerListeners(e){const{__debugPointerEvents:t,lineHoverHighlight:n="disabled",onLineClick:i,onLineNumberClick:r,onLineEnter:o,onLineLeave:s,onTokenClick:l,onTokenEnter:a,onTokenLeave:d,onHunkExpand:h,onMergeConflictActionClick:c,enableGutterUtility:u=!1,enableLineSelection:f=!1,onGutterUtilityClick:g}=this.options,b=g!=null,y=n!=="disabled"||i!=null||r!=null||o!=null||s!=null||l!=null||a!=null||d!=null||h!=null||c!=null||u||f||b;y&&!this.hasPointerListeners?(e.addEventListener("click",this.handlePointerClick),e.addEventListener("pointerdown",this.handlePointerDown),e.addEventListener("pointermove",this.handlePointerMove),e.addEventListener("pointerleave",this.handlePointerLeave),this.hasPointerListeners=!0,he(t,"click","FileDiff.DEBUG.attachEventListeners: Attaching click events for:",(()=>{const C=[];return(t==="both"||t==="click")&&(i!=null&&C.push("onLineClick"),r!=null&&C.push("onLineNumberClick"),h!=null&&C.push("expandable hunk separators"),c!=null&&C.push("merge conflict actions")),C})()),he(t,"move","FileDiff.DEBUG.attachEventListeners: Attaching pointer move event"),he(t,"move","FileDiff.DEBUG.attachEventListeners: Attaching pointer leave event")):!y&&this.hasPointerListeners&&(e.removeEventListener("click",this.handlePointerClick),e.removeEventListener("pointerdown",this.handlePointerDown),e.removeEventListener("pointermove",this.handlePointerMove),e.removeEventListener("pointerleave",this.handlePointerLeave),this.hasPointerListeners=!1);const m=this.pointerSession.mode==="selecting"||this.pointerSession.mode==="pendingSingleLineUnselect",p=this.pointerSession.mode==="gutterSelecting";(!f&&m||!b&&p)&&(this.clearPointerSession(),this.detachDocumentPointerListeners(),this.selectionAnchor=void 0,this.clearPendingSingleLineState())}updateInteractiveLineAttributes(){if(this.pre==null)return;const{onLineClick:e,onLineNumberClick:t,enableLineSelection:n=!1}=this.options,i=e!=null,r=t!=null||n;i&&!this.interactiveLinesAttr?(this.pre.setAttribute("data-interactive-lines",""),this.interactiveLinesAttr=!0):!i&&this.interactiveLinesAttr&&(this.pre.removeAttribute("data-interactive-lines"),this.interactiveLinesAttr=!1),r&&!this.interactiveLineNumbersAttr?(this.pre.setAttribute("data-interactive-line-numbers",""),this.interactiveLineNumbersAttr=!0):!r&&this.interactiveLineNumbersAttr&&(this.pre.removeAttribute("data-interactive-line-numbers"),this.interactiveLineNumbersAttr=!1)}handlePointerDown=e=>{if(e.pointerType==="mouse"&&e.button!==0||this.pre==null||this.pointerSession.mode!=="idle")return;const t=e.composedPath();et(t)&&this.options.onGutterUtilityClick!=null?this.startGutterSelectionFromPointerDown(e):(e.pointerType!=="mouse"&&this.revealUtilityFromGutterPath(t),this.startLineSelectionFromPointerDown(e))};startLineSelectionFromPointerDown(e){const{enableLineSelection:t=!1}=this.options;if(!t)return;const n=this.resolveSelectionInfo(e,{source:"event-path",requireNumberColumn:!0});if(n==null)return;const{pre:i}=this;if(i==null)return;const{lineNumber:r,eventSide:o,lineIndex:s}=n;if(e.shiftKey&&this.selectedRange!=null){const l=this.getIndexesFromSelection(this.selectedRange,i.getAttribute("data-diff-type")==="split");if(l==null)return;const a=l.start<=l.end?s>=l.start:s<=l.end;this.selectionAnchor={lineNumber:a?this.selectedRange.start:this.selectedRange.end,side:a?this.selectedRange.side:this.selectedRange.endSide??this.selectedRange.side},this.updateSelection(r,o,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.pointerSession={mode:"selecting",pointerId:e.pointerId},this.attachDocumentPointerListeners();return}if(this.selectedRange?.start===r&&this.selectedRange?.end===r){const l={lineNumber:r,side:o};this.selectionAnchor=l,this.pointerSession={mode:"pendingSingleLineUnselect",pointerId:e.pointerId,anchor:l,pending:l},this.attachDocumentPointerListeners();return}this.options.controlledSelection===!0?this.proposedSelectedRange=null:this.selectedRange=null,this.placeUtility(),this.selectionAnchor={lineNumber:r,side:o},this.updateSelection(r,o,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.pointerSession={mode:"selecting",pointerId:e.pointerId},this.attachDocumentPointerListeners()}startGutterSelectionFromPointerDown(e){const{enableLineSelection:t=!1,onGutterUtilityClick:n}=this.options;if(n==null)return;const i=this.currentSelectionEnds(),r=i?.bottom??this.resolveSelectionPoint(e,{source:"event-path",excludeUtility:!1}),o=i?.top??r;r==null||o==null||(e.preventDefault(),e.stopPropagation(),this.pointerSession={mode:"gutterSelecting",pointerId:e.pointerId,anchor:o,current:r},t&&(this.selectionAnchor={lineNumber:o.lineNumber,side:o.side},this.updateSelection(r.lineNumber,r.side,!1),this.notifySelectionStart(this.getCurrentSelectionRange())),this.attachDocumentPointerListeners())}handleDocumentPointerMove=e=>{const{enableLineSelection:t=!1}=this.options;switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionPoint(e,{source:"coordinates-first"});if(n==null)return;this.pointerSession.current=n,t===!0&&this.updateSelection(n.lineNumber,n.side);return}case"selecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionInfo(e,{source:"coordinates-first",requireNumberColumn:!1});if(n==null||this.selectionAnchor==null)return;this.updateSelection(n.lineNumber,n.eventSide);return}case"pendingSingleLineUnselect":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionInfo(e,{source:"coordinates-first",requireNumberColumn:!1});if(n==null||this.selectionAnchor==null)return;const i={lineNumber:n.lineNumber,side:n.eventSide};if(ao(this.pointerSession.pending,i))return;this.updateSelection(n.lineNumber,n.eventSide,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.notifySelectionChangeDelta(),this.pointerSession={mode:"selecting",pointerId:e.pointerId};return}}};handleDocumentPointerUp=e=>{const{enableLineSelection:t=!1,onGutterUtilityClick:n}=this.options;switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const i=this.resolveSelectionPoint(e,{source:"coordinates-first"});i!=null&&(this.pointerSession.current=i,t&&this.updateSelection(i.lineNumber,i.side)),n?.(this.buildSelectedLineRange(this.pointerSession.anchor,this.pointerSession.current)),this.selectionAnchor=void 0,t&&(this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection()),this.clearPointerSession(),this.detachDocumentPointerListeners();return}case"pendingSingleLineUnselect":if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault(),this.updateSelection(null,void 0,!1),this.selectionAnchor=void 0,this.clearPendingSingleLineState(),this.detachDocumentPointerListeners(),this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection();return;case"selecting":if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault(),this.selectionAnchor=void 0,this.detachDocumentPointerListeners(),this.clearPointerSession(),this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection()}};handleDocumentPointerCancel=e=>{switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":case"selecting":case"pendingSingleLineUnselect":if("pointerId"in this.pointerSession&&e.pointerId!==this.pointerSession.pointerId)return;this.selectionAnchor=void 0,this.clearProposedSelection(),this.clearPendingSingleLineState(),this.clearPointerSession(),this.detachDocumentPointerListeners()}};clearHoveredLine(){this.hoveredLine!=null&&(this.hoveredLine.lineElement.removeAttribute("data-hovered"),this.hoveredLine.numberElement.removeAttribute("data-hovered"),this.hoveredLine=void 0)}setHoveredLine(e){const{lineHoverHighlight:t="disabled"}=this.options;this.hoveredLine!=null&&this.clearHoveredLine(),this.hoveredLine=e,t!=="disabled"&&((t==="both"||t==="line")&&this.hoveredLine.lineElement.setAttribute("data-hovered",""),(t==="both"||t==="number")&&this.hoveredLine.numberElement.setAttribute("data-hovered",""))}clearHoveredToken(){this.hoveredToken!=null&&(this.hoveredToken=void 0)}setHoveredToken(e){this.hoveredToken!=null&&this.clearHoveredToken(),this.hoveredToken=e}ensureGutterUtilityNode(e){if(this.gutterUtilityContainer==null&&(this.gutterUtilityContainer=document.createElement("div"),this.gutterUtilityContainer.setAttribute("data-gutter-utility-slot","")),e)this.gutterUtilityButton!=null&&(this.gutterUtilityButton.remove(),this.gutterUtilityButton=void 0),this.gutterUtilitySlot==null&&(this.gutterUtilitySlot=document.createElement("slot"),this.gutterUtilitySlot.name="gutter-utility-slot"),this.gutterUtilitySlot.parentNode!==this.gutterUtilityContainer&&this.gutterUtilityContainer.replaceChildren(this.gutterUtilitySlot);else{if(this.gutterUtilitySlot?.remove(),this.gutterUtilitySlot=void 0,this.gutterUtilityButton==null){const t=document.createElement("div");t.innerHTML=pe(so());const n=t.firstElementChild;if(!(n instanceof HTMLButtonElement))throw new Error("InteractionManager.ensureGutterUtilityNode: Node element should be a button");n.remove(),this.gutterUtilityButton=n}this.gutterUtilityButton.parentNode!==this.gutterUtilityContainer&&this.gutterUtilityContainer.replaceChildren(this.gutterUtilityButton)}}revealUtilityFromGutterPath(e){if(this.placeUtilityFromSelection())return;const t=this.resolvePointerTarget(e);Ve(t)&&t.numberColumn&&this.showUtilityOnLine(this.toEventBaseProps(t))}placeUtility(){if(!this.placeUtilityFromSelection()){if(this.hoveredLine!=null){this.showUtilityOnLine(this.hoveredLine);return}this.hideUtility()}}placeUtilityFromSelection(){const e=this.currentSelectionEnds();if(e==null)return!1;const t=this.targetForSelectionPoint(e.bottom);return t==null?this.hideUtility():this.showUtilityOnLine(this.toEventBaseProps(t)),!0}showUtilityOnLine(e){this.gutterUtilityContainer!=null&&(this.gutterUtilityLine=e,e.numberElement.appendChild(this.gutterUtilityContainer))}hideUtility(){this.gutterUtilityContainer?.remove(),this.gutterUtilityLine=void 0}currentSelectionEnds(){const e=this.getCurrentSelectionRange();return e==null?void 0:this.selectionEnds(e)}selectionEnds(e){const t={lineNumber:e.start,side:e.side},n={lineNumber:e.end,side:e.endSide??e.side},i=this.selectionPointRowIndex(t),r=this.selectionPointRowIndex(n);if(!(i==null||r==null))return i>r?{top:n,bottom:t}:{top:t,bottom:n}}selectionPointRowIndex(e){const t=this.getLineIndex(e.lineNumber,e.side);if(t!=null)return this.isSplitDiff()?t[1]:t[0]}targetForSelectionPoint(e){if(this.pre==null)return;const t=this.getLineIndex(e.lineNumber,e.side);if(t==null)return;const n=this.mode==="diff"?`${t[0]},${t[1]}`:`${t[0]}`,i=this.pre.querySelectorAll(`[data-column-number="${e.lineNumber}"][data-line-index="${n}"]`);for(const r of i){if(!(r instanceof HTMLElement))continue;const o=this.resolvePointerTarget(Ze(r));if(Ve(o)&&!(this.mode==="diff"&&e.side!=null&&o.side!==e.side))return o}}attachDocumentPointerListeners(){this.hasDocumentPointerListeners||(document.addEventListener("pointermove",this.handleDocumentPointerMove),document.addEventListener("pointerup",this.handleDocumentPointerUp),document.addEventListener("pointercancel",this.handleDocumentPointerCancel),this.hasDocumentPointerListeners=!0)}detachDocumentPointerListeners(){this.hasDocumentPointerListeners&&(document.removeEventListener("pointermove",this.handleDocumentPointerMove),document.removeEventListener("pointerup",this.handleDocumentPointerUp),document.removeEventListener("pointercancel",this.handleDocumentPointerCancel),this.hasDocumentPointerListeners=!1)}clearPointerSession(){this.pointerSession={mode:"idle"}}clearPendingSingleLineState(){this.pointerSession.mode==="pendingSingleLineUnselect"&&(this.pointerSession={mode:"idle"})}selectionInfoFromPath(e,t){const n=this.resolvePointerTarget(e);if(Ve(n)&&!(t&&!n.numberColumn)&&n.splitLineIndex!=null)return{lineIndex:n.splitLineIndex,lineNumber:n.lineNumber,eventSide:this.mode==="diff"?n.side:void 0}}resolveSelectionInfo(e,t){const n=this.resolveSelectionPath(e,t);return n!=null?this.selectionInfoFromPath(n,t.requireNumberColumn):void 0}selectionPointFromPath(e){const t=this.resolvePointerTarget(e);if(Ve(t))return{lineNumber:t.lineNumber,side:this.mode==="diff"?t.side:void 0}}resolveSelectionPoint(e,t){const n=this.resolveSelectionPath(e,t);return n!=null?this.selectionPointFromPath(n):void 0}resolveSelectionPath(e,t){const n=t.excludeUtility!==!1;switch(t.source){case"event-path":return this.pathFromEventPath(e.composedPath(),n);case"coordinates-first":{const i=this.pathFromCoordinates(e,n);return i!==void 0?i??void 0:this.pathFromEventPath(e.composedPath(),n)}}}pathFromCoordinates(e,t){const n=this.hitTest(e);if(n!==void 0)return n===null?null:this.pathFromElement(n,t)??null}pathFromEventPath(e,t){if(!(t&&et(e))){for(const n of e)if(n instanceof Element)return this.pathFromElement(n,t)}}pathFromElement(e,t){const n=Ze(e);if(t&&et(n))return;const i=fo(e);return i!=null?Ze(i):this.pathFromAnnotationSlot(e)}pathFromAnnotationSlot(e){const t=go(po(e));if(t==null)return;const n=this.targetForSelectionPoint(t);return n!=null?Ze(n.lineElement):void 0}hitTest(e){if(!Number.isFinite(e.clientX)||!Number.isFinite(e.clientY))return;const t=this.pre?.getRootNode(),n=En(t)?t:En(document)?document:void 0;if(n!=null)return n.elementFromPoint(e.clientX,e.clientY)}getLineIndex(e,t){const{getLineIndex:n}=this.options;return n!=null?n(e,t):[e-1,e-1]}getCurrentSelectionRange(){return this.proposedSelectedRange!==void 0?this.proposedSelectedRange:this.selectedRange}clearProposedSelection(){this.proposedSelectedRange=void 0}updateSelection(e,t,n=!0){const i=this.getCurrentSelectionRange();let r;if(e==null)r=null;else{const o=this.selectionAnchor?.side??t,s=this.selectionAnchor?.lineNumber??e;r=this.buildSelectionRange(s,e,o,t)}Wt(i??void 0,r??void 0)||(this.options.controlledSelection===!0?this.proposedSelectedRange=r:(this.selectedRange=r,this.queuedSelectionRender??=requestAnimationFrame(this.renderSelection)),this.placeUtility(),n&&this.notifySelectionChangeDelta())}getIndexesFromSelection(e,t){if(this.pre==null)return;const n=this.getLineIndex(e.start,e.side),i=this.getLineIndex(e.end,e.endSide??e.side);return n!=null&&i!=null?{start:t?n[1]:n[0],end:t?i[1]:i[0]}:void 0}renderSelection=()=>{if(this.queuedSelectionRender!=null&&(cancelAnimationFrame(this.queuedSelectionRender),this.queuedSelectionRender=void 0),this.pre==null||this.renderedSelectionRange===this.selectedRange)return;const e=this.pre.querySelectorAll("[data-selected-line]");for(const l of e)l.removeAttribute("data-selected-line");if(this.renderedSelectionRange=this.selectedRange,this.selectedRange==null)return;const{children:t}=this.pre;if(t.length===0)return;if(t.length>2)throw console.error(t),new Error("InteractionManager.renderSelection: Somehow there are more than 2 code elements...");const n=this.pre.getAttribute("data-diff-type")==="split",i=this.getIndexesFromSelection(this.selectedRange,n);if(i==null)throw console.error({rowRange:i,selectedRange:this.selectedRange}),new Error("InteractionManager.renderSelection: No valid rowRange");const r=i.start===i.end,o=Math.min(i.start,i.end),s=Math.max(i.start,i.end);for(const l of t){const[a,d]=l.children,h=d.children.length;if(h!==a.children.length)throw new Error("InteractionManager.renderSelection: gutter and content children dont match, something is wrong");for(let c=0;c<h;c++){const u=d.children[c],f=a.children[c];if(!(u instanceof HTMLElement)||!(f instanceof HTMLElement))continue;const g=this.parseLineIndex(u,n);if((g??0)>s)break;if(g==null||g<o)continue;let b=r?"single":g===o?"first":g===s?"last":"";u.setAttribute("data-selected-line",b),f.setAttribute("data-selected-line",b),f.nextSibling instanceof HTMLElement&&u.nextSibling instanceof HTMLElement&&(u.nextSibling.hasAttribute("data-line-annotation")||u.nextSibling.hasAttribute("data-merge-conflict-actions"))&&(r?(b="last",u.setAttribute("data-selected-line","first")):g===o?b="":g===s&&u.setAttribute("data-selected-line",""),u.nextSibling.setAttribute("data-selected-line",b),f.nextSibling.setAttribute("data-selected-line",b))}}};notifySelectionCommitted(){this.options.onLineSelected?.(this.getCurrentSelectionRange()??null)}notifySelectionChangeDelta(){this.options.onLineSelectionChange?.(this.getCurrentSelectionRange()??null)}notifySelectionStart(e){this.options.onLineSelectionStart?.(e)}notifySelectionEnd(e){this.options.onLineSelectionEnd?.(e)}toEventBaseProps(e){return this.mode==="file"?{type:"line",lineElement:e.lineElement,lineNumber:e.lineNumber,numberColumn:e.numberColumn,numberElement:e.numberElement}:{type:"diff-line",annotationSide:e.side,lineType:e.lineType,lineElement:e.lineElement,numberElement:e.numberElement,lineNumber:e.lineNumber,numberColumn:e.numberColumn}}toTokenEventBaseProps({lineCharEnd:e,lineCharStart:t,lineNumber:n,side:i,tokenElement:r,tokenText:o}){return this.mode==="file"?{type:"token",lineCharEnd:e,lineCharStart:t,lineNumber:n,tokenElement:r,tokenText:o}:{type:"token",lineCharEnd:e,lineCharStart:t,lineNumber:n,side:i,tokenElement:r,tokenText:o}}buildSelectedLineRange(e,t){return this.buildSelectionRange(e.lineNumber,t.lineNumber,e.side,t.side)}buildSelectionRange(e,t,n,i){return{start:e,end:t,...n!=null?{side:n}:{},...n!==i&&i!=null?{endSide:i}:{}}}resolvePointerTarget(e){let t=!1,n,i,r,o,s,l,a,d,h,c;for(const f of e){if(!(f instanceof HTMLElement))continue;if(c==null&&f.hasAttribute("data-merge-conflict-action")){const m=f.getAttribute("data-merge-conflict-action")??void 0,p=f.getAttribute("data-merge-conflict-conflict-index")??void 0,C=p!=null?Number.parseInt(p,10):NaN;uo(m)&&Number.isFinite(C)&&(c={kind:"merge-conflict-action",resolution:m,conflictIndex:C})}if(l==null&&f.hasAttribute("data-char")){l=f;const m=f.getAttribute("data-char");if(m!=null){const p=Number.parseInt(m,10);if(!Number.isNaN(p)){const C=f.textContent??"",v=p+C.length;(C.trim()!==""||this.options.enableTokenInteractionsOnWhitespace===!0)&&(a={tokenElement:l,lineCharStart:p,lineCharEnd:v,tokenText:C});continue}}}const g=s==null?f.getAttribute("data-column-number")??void 0:void 0;if(g!=null){s=f,h=Number.parseInt(g,10),t=!0,n=In(f),o=f.getAttribute("data-line-index")??void 0;continue}const b=r==null?f.getAttribute("data-line")??void 0:void 0;if(b!=null){r=f,h=Number.parseInt(b,10),n=In(f),o=f.getAttribute("data-line-index")??void 0;continue}if(d==null&&(f.hasAttribute("data-expand-button")||f.hasAttribute("data-unmodified-lines"))){d={hunkIndex:void 0,direction:f.hasAttribute("data-expand-up")?"up":f.hasAttribute("data-expand-down")?"down":"both",all:f.hasAttribute("data-expand-all-button")};continue}const y=d!=null?f.getAttribute("data-expand-index")??void 0:void 0;if(d!=null&&y!=null){const m=Number.parseInt(y,10);Number.isNaN(m)||(d.hunkIndex=m);continue}if(i==null&&f.hasAttribute("data-code")){i=f;break}}if(c!=null)return c;if(d?.hunkIndex!=null)return{type:"line-info",hunkIndex:d.hunkIndex,direction:d.direction,all:d.all};if(r??=o!=null?wn(i,`[data-line][data-line-index="${o}"]`):void 0,s??=o!=null?wn(i,`[data-column-number][data-line-index="${o}"]`):void 0,i==null||r==null||s==null||n==null||h==null||Number.isNaN(h))return;const u=this.parseLineIndex(r,this.isSplitDiff());return a!=null?this.mode==="file"?{kind:"token",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:void 0,splitLineIndex:u,...a}:{kind:"token",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:Tn(n,i),splitLineIndex:u,...a}:this.mode==="file"?{kind:"line",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:void 0,splitLineIndex:u}:{kind:"line",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:Tn(n,i),splitLineIndex:u}}isSplitDiff(){return this.pre?.getAttribute("data-diff-type")==="split"}parseLineIndex(e,t){const n=(e.getAttribute("data-line-index")??"").split(",").map(i=>Number.parseInt(i,10)).filter(i=>!Number.isNaN(i));if(t&&n.length===2)return n[1];if(!t)return n[0]}};function Ke({enableTokenInteractionsOnWhitespace:e,enableGutterUtility:t,lineHoverHighlight:n,onGutterUtilityClick:i,onLineClick:r,onLineEnter:o,onLineLeave:s,onLineNumberClick:l,onTokenClick:a,onTokenEnter:d,onTokenLeave:h,renderGutterUtility:c,__debugPointerEvents:u,enableLineSelection:f,controlledSelection:g,onLineSelected:b,onLineSelectionStart:y,onLineSelectionChange:m,onLineSelectionEnd:p},C,v,x){return{enableTokenInteractionsOnWhitespace:e,enableGutterUtility:lo({enableGutterUtility:t,renderGutterUtility:c,onGutterUtilityClick:i}),usesCustomGutterUtility:c!=null,lineHoverHighlight:n,onGutterUtilityClick:i,onHunkExpand:C,onMergeConflictActionClick:x,onLineClick:r,onLineEnter:o,onLineLeave:s,onLineNumberClick:l,onTokenClick:a,onTokenEnter:d,onTokenLeave:h,__debugPointerEvents:u,enableLineSelection:f,controlledSelection:g,onLineSelected:b,onLineSelectionStart:y,onLineSelectionChange:m,onLineSelectionEnd:p,getLineIndex:v}}function lo({enableGutterUtility:e,renderGutterUtility:t,onGutterUtilityClick:n}){if(n!=null&&t!=null)throw new Error("Cannot use both 'onGutterUtilityClick' and 'renderGutterUtility'. Use only one gutter utility API.");return e??!1}function Ve(e){return e!=null&&"kind"in e&&e.kind==="line"}function ut(e){return e!=null&&"kind"in e&&e.kind==="token"}function Tt(e){return Ve(e)||ut(e)}function ho(e){return"type"in e&&e.type==="line-info"}function co(e){return"kind"in e&&e.kind==="merge-conflict-action"}function uo(e){return e==="current"||e==="incoming"||e==="both"}function wn(e,t){const n=e?.querySelector(t);return n instanceof HTMLElement?n:void 0}function Ze(e){const t=[];let n=e;for(;n!=null;)t.push(n),n=n.parentNode;return t}function fo(e){const t=e.closest("[data-line], [data-column-number]");if(t instanceof HTMLElement)return t;const n=e.closest('[data-line-annotation], [data-gutter-buffer="annotation"]');if(!(n instanceof HTMLElement))return;const i=n.previousElementSibling;return i instanceof HTMLElement&&(i.hasAttribute("data-line")||i.hasAttribute("data-column-number"))?i:void 0}function po(e){const t=e.closest('[slot^="annotation-"]');if(t instanceof HTMLElement)return t.getAttribute("slot")??void 0;if(e instanceof HTMLElement){const n=e.getAttribute("name")??void 0;return n!=null&&n.startsWith("annotation-")?n:void 0}}function go(e){if(e==null)return;const t=/^annotation-(?:(additions|deletions)-)?(\d+)$/.exec(e);if(t==null)return;const n=Number.parseInt(t[2],10);if(!(!Number.isFinite(n)||n<=0))return{lineNumber:n,side:t[1]}}function En(e){return e!=null&&typeof e.elementFromPoint=="function"}function Tn(e,t){switch(e){case"change-deletion":return"deletions";case"change-addition":return"additions";default:return t.hasAttribute("data-deletions")?"deletions":"additions"}}function In(e){const t=e.getAttribute("data-line-type");if(t!=null)switch(t){case"change-deletion":case"change-addition":case"context":case"context-expanded":return t;default:return}}function et(e){for(const t of e)if(t instanceof HTMLElement&&(t.hasAttribute("data-utility-button")||t.hasAttribute("data-gutter-utility-slot")||t.getAttribute("slot")==="gutter-utility-slot"||t.getAttribute("name")==="gutter-utility-slot"))return!0;return!1}function he(e="none",t,...n){switch(e){case"none":return;case"both":break;case"click":if(t!=="click")return;break;case"move":if(t!=="move")return;break}console.log(...n)}var _i=class ue{static resizeObserver;static managersByElement=new Map;static getResizeObserver(){const t=ue.resizeObserver??new ResizeObserver(ue.handleSharedResizeEntries);return ue.resizeObserver=t,t}static handleSharedResizeEntries(t){const n=new Map;for(const i of t){const r=ue.managersByElement.get(i.target);if(r==null)continue;const o=n.get(r);o==null?n.set(r,[i]):o.push(i)}for(const[i,r]of n)i.handleResizeEntries(r)}observedNodes=new Map;setup(t,n){const i=new Set;let r=0;const o=new Map(this.observedNodes);this.observedNodes.clear();for(const s of t.children){if(r===2)break;const l=(()=>{if(s instanceof HTMLElement&&s.tagName==="CODE")return s})();if(l==null)continue;r++;let a=o.get(l);if(a!=null&&a.type!=="code")throw new Error("ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible");let d=l.firstElementChild;d instanceof HTMLElement||(d=null),a!=null?(this.observedNodes.set(l,a),o.delete(l),a.numberElement!==d?(a.numberElement!=null&&(this.unobserve(a.numberElement),o.delete(a.numberElement)),d!=null&&(this.observe(d),o.delete(d),this.observedNodes.set(d,a)),a.numberElement=d,a.numberWidth=0):a.numberElement!=null?(o.delete(a.numberElement),this.observedNodes.set(a.numberElement,a)):a.numberWidth=0):(a={type:"code",codeElement:l,numberElement:d,codeWidth:"auto",numberWidth:0},this.observedNodes.set(l,a),this.observe(l),d!=null&&(this.observedNodes.set(d,a),this.observe(d)))}if(r>1&&!n){const s=t.querySelectorAll('[data-line-annotation*=","]'),l=new Map;for(const a of s){if(!(a instanceof HTMLElement))continue;const d=a.getAttribute("data-line-annotation")??"";if(!/^-?\d+,-?\d+$/.test(d)){console.error("DiffFileRenderer.setupResizeObserver: Invalid element or annotation",{lineAnnotation:d,element:a});continue}let h=l.get(d);h==null&&(h=[],l.set(d,h)),h.push(a)}for(const[a,d]of l){if(d.length!==2){console.error("DiffFileRenderer.setupResizeObserver: Bad Pair",a,d);continue}const[h,c]=d,u=h.firstElementChild,f=c.firstElementChild;if(!(h instanceof HTMLElement)||!(c instanceof HTMLElement)||!(u instanceof HTMLElement)||!(f instanceof HTMLElement))continue;let g=o.get(u);if(g!=null){this.observedNodes.set(u,g),this.observedNodes.set(f,g),o.delete(u),o.delete(f);continue}const b=u.getBoundingClientRect().height,y=f.getBoundingClientRect().height;g={type:"annotations",column1:{container:h,child:u,childHeight:b},column2:{container:c,child:f,childHeight:y},currentHeight:"auto"},i.add({child1:u,child2:f,item:g,newHeight:Math.max(b,y)})}for(const a of i)this.applyNewHeight(a.item,a.newHeight),this.observedNodes.set(a.child1,a.item),this.observedNodes.set(a.child2,a.item),this.observe(a.child1),this.observe(a.child2);i.clear()}for(const[s,l]of o)this.unobserve(s),l.type==="code"?bo(l):Co(l);o.clear()}cleanUp(){for(const t of this.observedNodes.keys())this.unobserve(t);this.observedNodes.clear()}observe(t){const{managersByElement:n}=ue,i=n.get(t);if(i!==this){if(i!=null&&i!==this)throw new Error("ResizeManager.observe: element is already owned by another ResizeManager");n.set(t,this),ue.getResizeObserver().observe(t)}}unobserve(t){const{managersByElement:n,resizeObserver:i}=ue,r=n.get(t);if(r!=null){if(r!==this)throw new Error("ResizeManager.unobserve: element is owned by another ResizeManager");n.delete(t),i?.unobserve(t),i!=null&&n.size===0&&(i.disconnect(),ue.resizeObserver=void 0)}}handleResizeEntries(t){const n=new Map,i=new Set;for(const r of t){const{target:o,borderBoxSize:s,contentBoxSize:l}=r;if(!(o instanceof HTMLElement)){console.error("ResizeManager.handleResizeEntries: Invalid element for ResizeObserver",r);continue}const a=this.observedNodes.get(o);if(a==null){console.error("ResizeManager.handleResizeEntries: Not a valid observed node",r);continue}if(a.type==="annotations"){const d=(()=>{if(o===a.column1.child)return a.column1;if(o===a.column2.child)return a.column2})();if(d==null){console.error("ResizeManager.handleResizeEntries: Couldn't find a column for",{item:a,target:o});continue}d.childHeight=s[0].blockSize,i.add(a)}else if(a.type==="code"){const d=n.get(a)??{},h=l[0].inlineSize;o===a.codeElement?d.codeInlineSize=h:o===a.numberElement&&(d.numberInlineSize=h),n.set(a,d)}}this.applyAnnotationUpdates(i),i.clear(),this.applyColumnUpdates(n),n.clear()}applyAnnotationUpdates(t){for(const n of t)this.applyNewHeight(n,Math.max(n.column1.childHeight,n.column2.childHeight))}applyColumnUpdates=t=>{for(const[n,i]of t){const r=i.codeInlineSize!=null?mo(i.codeInlineSize):n.codeWidth,o=i.numberInlineSize!=null?vo(i.numberInlineSize):n.numberWidth,s=r!==n.codeWidth,l=o!==n.numberWidth;if(!(!s&&!l)&&(n.codeWidth=r,n.numberWidth=o,s&&n.codeElement.style.setProperty("--diffs-column-width",`${typeof r=="number"?`${r}px`:"auto"}`),l&&n.codeElement.style.setProperty("--diffs-column-number-width",`${o===0?"auto":`${o}px`}`),s||l&&r!=="auto")){const a=typeof r=="number"?Math.max(r-o,0):0;n.codeElement.style.setProperty("--diffs-column-content-width",`${a>0?`${a}px`:"auto"}`)}}};applyNewHeight(t,n){n!==t.currentHeight&&(t.currentHeight=Math.max(n,0),t.column1.container.style.setProperty("--diffs-annotation-min-height",`${t.currentHeight}px`),t.column2.container.style.setProperty("--diffs-annotation-min-height",`${t.currentHeight}px`))}};function mo(e){const t=Math.max(Math.floor(e),0);return t===0?"auto":t}function vo(e){return Math.max(Math.ceil(e),0)}function bo(e){e.codeElement.isConnected&&(e.codeElement.style.removeProperty("--diffs-column-content-width"),e.codeElement.style.removeProperty("--diffs-column-number-width"),e.codeElement.style.removeProperty("--diffs-column-width"))}function Co(e){e.column1.container.isConnected&&e.column1.container.style.removeProperty("--diffs-annotation-min-height"),e.column2.container.isConnected&&e.column2.container.style.removeProperty("--diffs-annotation-min-height")}const Se=new Map,It=new Map,jt=new Map,gt=new Set;function mt(e){for(const t of Array.isArray(e)?e:[e])if(!(t==="text"||t==="ansi")&&!gt.has(t))return!1;return!0}function Rn(e,t){e=Array.isArray(e)?e:[e];for(const n of e){if(gt.has(n.name))continue;let i=Se.get(n.name);i==null&&(i=n,Se.set(n.name,i)),gt.add(i.name),t.loadLanguageSync(i.data)}}function So(){Se.clear(),gt.clear()}function Oi(){return typeof WorkerGlobalScope<"u"&&typeof self<"u"&&self instanceof WorkerGlobalScope}async function Ni(e){if(Oi())throw new Error(`resolveLanguage("${e}") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);const t=It.get(e);if(t!=null)return t;try{let n=jt.get(e);if(n==null&&Object.prototype.hasOwnProperty.call(Ln,e)&&(n=Ln[e]),n==null)throw new Error(`resolveLanguage: "${e}" not found in bundled or custom languages`);const i=n().then(({default:r})=>{const o={name:e,data:r};return Se.has(e)||Se.set(e,o),o});return It.set(e,i),await i}finally{It.delete(e)}}function Fi(e){return Se.get(e)??Ni(e)}const vt=new Set;function Ye(e){const t=[],n=new Set;for(const c of yo(e.themes)){const u=zi(c)?c.getThemes():[c];for(const f of u){if(n.has(f.name))throw new Error(`Theme collection already contains theme "${f.name}"`);n.add(f.name),t.push(f)}}const i=Object.freeze([...t]),r=Object.freeze(i.filter(c=>c.colorScheme==="light")),o=Object.freeze(i.filter(c=>c.colorScheme==="dark")),s=new Map(i.map(c=>[c.name,c])),l=Object.freeze(i.map(c=>c.name)),a=Object.freeze(r.map(c=>c.name)),d=Object.freeze(o.map(c=>c.name));function h(c){if(c==null)return i;const{colorScheme:u,collection:f}=c;return f==null?u==="light"?r:u==="dark"?o:i:i.filter(g=>g.collection!==f?!1:u==null||g.colorScheme===u)}return{getTheme(c){return s.get(c)},getThemes(c){return h(c)},getThemeNames(c){return c?.collection==null?c?.colorScheme==="light"?a:c?.colorScheme==="dark"?d:l:h(c).map(u=>u.name)},hasTheme(c){return s.has(c)},orderBy(c){return Ye({themes:i.map((u,f)=>({descriptor:u,index:f})).sort((u,f)=>{const g=c(u.descriptor,f.descriptor);return g!==0?g:u.index-f.index}).map(u=>u.descriptor)})},pick(c){const u=[],f=new Set;for(const g of c){if(f.has(g))throw new Error(`Theme collection pick already includes theme "${g}"`);f.add(g);const b=s.get(g);if(b==null)throw new Error(`Theme collection does not contain theme "${g}"`);u.push(b)}return Ye({themes:u})},registerInto(c){for(const u of i)c.registerThemeIfAbsent(u.name,u.load)}}}function yo(e){return xo(e)?[e]:e}function xo(e){return zi(e)||Lo(e)}function Lo(e){return typeof e.name=="string"&&typeof e.load=="function"}function zi(e){return typeof e.getThemes=="function"}function Ui(e){return e!==null&&typeof e=="object"&&"default"in e?e.default:e}var Vi=class extends Error{constructor(e){super(`Theme "${e}" is already registered`),this.name="DuplicateThemeError"}},ko=class extends Error{constructor(e){super(`No loader registered for theme "${e}"`),this.name="UnregisteredThemeError"}},wo=class extends Error{constructor(e){super(`Theme "${e}" has not been resolved`),this.name="UnresolvedThemeError"}};function Eo(){const e=new Map,t=new Map,n=new Map;let i=0;function r(m,p){if(e.has(m))throw new Vi(m);e.set(m,p)}function o(m,p){return e.has(m)?!1:(e.set(m,p),!0)}function s(m){return e.has(m)}function l(m){const p=t.get(m);if(p!==void 0)return Promise.resolve(p);const C=n.get(m);if(C!==void 0)return C;const v=e.get(m);if(v===void 0)return Promise.reject(new ko(m));const x=i,S=v().then(L=>{const E=Ui(L);return x===i&&t.set(m,E),n.get(m)===S&&n.delete(m),E}).catch(L=>{throw n.get(m)===S&&n.delete(m),L});return n.set(m,S),S}function a(m){return Promise.all(m.map(p=>l(p)))}function d(m,p){t.set(m,p)}function h(m){for(const[p,C]of m)d(p,C)}function c(m){return t.get(m)}function u(m){const p=[];for(const C of m){const v=t.get(C);if(v===void 0)throw new wo(C);p.push(v)}return p}function f(m){return t.has(m)}function g(m){for(const p of m)if(!t.has(p))return!1;return!0}function b(m){const p=t.get(m);return p!==void 0?p:l(m)}function y(){i++,t.clear(),n.clear()}return{clearResolvedThemes:y,getResolvedOrResolveTheme:b,getResolvedTheme:c,getResolvedThemes:u,hasRegisteredTheme:s,hasResolvedTheme:f,hasResolvedThemes:g,registerTheme:r,registerThemeIfAbsent:o,resolveTheme:l,resolveThemes:a,seedResolvedTheme:d,seedResolvedThemes:h}}const X=Eo();function An(e,t){e=Array.isArray(e)?e:[e];for(let n of e){let i;if(typeof n=="string"){if(i=X.getResolvedTheme(n),i==null)throw new Error(`loadResolvedThemes: ${n} is not resolved, you must resolve it before calling loadResolvedThemes`)}else i=n,n=n.name,X.getResolvedTheme(n)==null&&X.seedResolvedTheme(n,i);vt.has(n)||(vt.add(n),t.loadThemeSync(i))}}function To(){X.clearResolvedThemes(),vt.clear()}function hn({name:e,load:t,colorScheme:n,collection:i,displayName:r}){return{name:e,colorScheme:n,collection:i,displayName:r,load:Io(t)}}function Io(e){return async()=>Or(Ui(await e()))}const Ro="pierre",Ao=["pierre-dark","pierre-dark-soft","pierre-dark-vibrant","pierre-dark-protanopia-deuteranopia","pierre-dark-tritanopia"],Bi=["pierre-light","pierre-light-soft","pierre-light-vibrant","pierre-light-protanopia-deuteranopia","pierre-light-tritanopia"],Ho=[...Bi,...Ao],Mo=new Set(Bi);function Do(e){return Mo.has(e)?"light":"dark"}const Po={"pierre-dark":"Pierre Dark","pierre-dark-soft":"Pierre Dark Soft","pierre-dark-vibrant":"Pierre Dark Vibrant","pierre-dark-protanopia-deuteranopia":"Pierre Dark Protanopia & Deuteranopia","pierre-dark-tritanopia":"Pierre Dark Tritanopia","pierre-light":"Pierre Light","pierre-light-soft":"Pierre Light Soft","pierre-light-vibrant":"Pierre Light Vibrant","pierre-light-protanopia-deuteranopia":"Pierre Light Protanopia & Deuteranopia","pierre-light-tritanopia":"Pierre Light Tritanopia"},_o={"pierre-dark":()=>k(()=>import("./pierre-dark-CyvmCCZW.js"),[]),"pierre-dark-soft":()=>k(()=>import("./pierre-dark-soft-BHGpRqa4.js"),[]),"pierre-dark-vibrant":()=>k(()=>import("./pierre-dark-vibrant-BWBVywrn.js"),[]),"pierre-dark-protanopia-deuteranopia":()=>k(()=>import("./pierre-dark-protanopia-deuteranopia-Rgc0TwpF.js"),[]),"pierre-dark-tritanopia":()=>k(()=>import("./pierre-dark-tritanopia-Beq2gCRQ.js"),[]),"pierre-light":()=>k(()=>import("./pierre-light-480U9XYS.js"),[]),"pierre-light-soft":()=>k(()=>import("./pierre-light-soft-CVdyfjmI.js"),[]),"pierre-light-vibrant":()=>k(()=>import("./pierre-light-vibrant-DdTDNdfJ.js"),[]),"pierre-light-protanopia-deuteranopia":()=>k(()=>import("./pierre-light-protanopia-deuteranopia-CaVOBURG.js"),[]),"pierre-light-tritanopia":()=>k(()=>import("./pierre-light-tritanopia-B4_gpKOM.js"),[])};function Oo(e){return hn({name:e,collection:Ro,colorScheme:Do(e),displayName:Po[e],load:_o[e]})}const $i=Ye({themes:Ho.map(e=>Oo(e))}),No="shiki",Wi=["ayu-light","catppuccin-latte","everforest-light","github-light","github-light-default","github-light-high-contrast","gruvbox-light-hard","gruvbox-light-medium","gruvbox-light-soft","horizon-bright","kanagawa-lotus","light-plus","material-theme-lighter","min-light","night-owl-light","one-light","rose-pine-dawn","slack-ochin","snazzy-light","solarized-light","vitesse-light"],Fo=["andromeeda","aurora-x","ayu-dark","ayu-mirage","catppuccin-frappe","catppuccin-macchiato","catppuccin-mocha","dark-plus","dracula","dracula-soft","everforest-dark","github-dark","github-dark-default","github-dark-dimmed","github-dark-high-contrast","gruvbox-dark-hard","gruvbox-dark-medium","gruvbox-dark-soft","horizon","houston","kanagawa-dragon","kanagawa-wave","laserwave","material-theme","material-theme-darker","material-theme-ocean","material-theme-palenight","min-dark","monokai","night-owl","nord","one-dark-pro","plastic","poimandres","red","rose-pine","rose-pine-moon","slack-dark","solarized-dark","synthwave-84","tokyo-night","vesper","vitesse-black","vitesse-dark"],zo=new Set(Wi);function Uo(e){return zo.has(e)?"light":"dark"}const Vo={andromeeda:()=>k(()=>import("./andromeeda-C4gqWexZ.js"),[]),"aurora-x":()=>k(()=>import("./aurora-x-D-2ljcwZ.js"),[]),"ayu-dark":()=>k(()=>import("./ayu-dark-DYE7WIF3.js"),[]),"ayu-light":()=>k(()=>import("./ayu-light-BA47KaF1.js"),[]),"ayu-mirage":()=>k(()=>import("./ayu-mirage-32ctXXKs.js"),[]),"catppuccin-frappe":()=>k(()=>import("./catppuccin-frappe-DFWUc33u.js"),[]),"catppuccin-latte":()=>k(()=>import("./catppuccin-latte-C9dUb6Cb.js"),[]),"catppuccin-macchiato":()=>k(()=>import("./catppuccin-macchiato-DQyhUUbL.js"),[]),"catppuccin-mocha":()=>k(()=>import("./catppuccin-mocha-D87Tk5Gz.js"),[]),"dark-plus":()=>k(()=>import("./dark-plus-C3mMm8J8.js"),[]),dracula:()=>k(()=>import("./dracula-BzJJZx-M.js"),[]),"dracula-soft":()=>k(()=>import("./dracula-soft-BXkSAIEj.js"),[]),"everforest-dark":()=>k(()=>import("./everforest-dark-BgDCqdQA.js"),[]),"everforest-light":()=>k(()=>import("./everforest-light-C8M2exoo.js"),[]),"github-dark":()=>k(()=>import("./github-dark-DHJKELXO.js"),[]),"github-dark-default":()=>k(()=>import("./github-dark-default-Cuk6v7N8.js"),[]),"github-dark-dimmed":()=>k(()=>import("./github-dark-dimmed-DH5Ifo-i.js"),[]),"github-dark-high-contrast":()=>k(()=>import("./github-dark-high-contrast-E3gJ1_iC.js"),[]),"github-light":()=>k(()=>import("./github-light-DAi9KRSo.js"),[]),"github-light-default":()=>k(()=>import("./github-light-default-D7oLnXFd.js"),[]),"github-light-high-contrast":()=>k(()=>import("./github-light-high-contrast-BfjtVDDH.js"),[]),"gruvbox-dark-hard":()=>k(()=>import("./gruvbox-dark-hard-CFHQjOhq.js"),[]),"gruvbox-dark-medium":()=>k(()=>import("./gruvbox-dark-medium-GsRaNv29.js"),[]),"gruvbox-dark-soft":()=>k(()=>import("./gruvbox-dark-soft-CVdnzihN.js"),[]),"gruvbox-light-hard":()=>k(()=>import("./gruvbox-light-hard-CH1njM8p.js"),[]),"gruvbox-light-medium":()=>k(()=>import("./gruvbox-light-medium-DRw_LuNl.js"),[]),"gruvbox-light-soft":()=>k(()=>import("./gruvbox-light-soft-hJgmCMqR.js"),[]),horizon:()=>k(()=>import("./horizon-BUw7H-hv.js"),[]),"horizon-bright":()=>k(()=>import("./horizon-bright-CUuTKBJd.js"),[]),houston:()=>k(()=>import("./houston-DnULxvSX.js"),[]),"kanagawa-dragon":()=>k(()=>import("./kanagawa-dragon-CkXjmgJE.js"),[]),"kanagawa-lotus":()=>k(()=>import("./kanagawa-lotus-CfQXZHmo.js"),[]),"kanagawa-wave":()=>k(()=>import("./kanagawa-wave-DWedfzmr.js"),[]),laserwave:()=>k(()=>import("./laserwave-DUszq2jm.js"),[]),"light-plus":()=>k(()=>import("./light-plus-B7mTdjB0.js"),[]),"material-theme":()=>k(()=>import("./material-theme-D5KoaKCx.js"),[]),"material-theme-darker":()=>k(()=>import("./material-theme-darker-BfHTSMKl.js"),[]),"material-theme-lighter":()=>k(()=>import("./material-theme-lighter-B0m2ddpp.js"),[]),"material-theme-ocean":()=>k(()=>import("./material-theme-ocean-CyktbL80.js"),[]),"material-theme-palenight":()=>k(()=>import("./material-theme-palenight-Csfq5Kiy.js"),[]),"min-dark":()=>k(()=>import("./min-dark-CafNBF8u.js"),[]),"min-light":()=>k(()=>import("./min-light-CTRr51gU.js"),[]),monokai:()=>k(()=>import("./monokai-D4h5O-jR.js"),[]),"night-owl":()=>k(()=>import("./night-owl-C39BiMTA.js"),[]),"night-owl-light":()=>k(()=>import("./night-owl-light-CMTm3GFP.js"),[]),nord:()=>k(()=>import("./nord-Ddv68eIx.js"),[]),"one-dark-pro":()=>k(()=>import("./one-dark-pro-DVMEJ2y_.js"),[]),"one-light":()=>k(()=>import("./one-light-C3Wv6jpd.js"),[]),plastic:()=>k(()=>import("./plastic-3e1v2bzS.js"),[]),poimandres:()=>k(()=>import("./poimandres-CS3Unz2-.js"),[]),red:()=>k(()=>import("./red-bN70gL4F.js"),[]),"rose-pine":()=>k(()=>import("./rose-pine-qdsjHGoJ.js"),[]),"rose-pine-dawn":()=>k(()=>import("./rose-pine-dawn-DHQR4-dF.js"),[]),"rose-pine-moon":()=>k(()=>import("./rose-pine-moon-D4_iv3hh.js"),[]),"slack-dark":()=>k(()=>import("./slack-dark-BthQWCQV.js"),[]),"slack-ochin":()=>k(()=>import("./slack-ochin-DqwNpetd.js"),[]),"snazzy-light":()=>k(()=>import("./snazzy-light-Bw305WKR.js"),[]),"solarized-dark":()=>k(()=>import("./solarized-dark-DXbdFlpD.js"),[]),"solarized-light":()=>k(()=>import("./solarized-light-L9t79GZl.js"),[]),"synthwave-84":()=>k(()=>import("./synthwave-84-CbfX1IO0.js"),[]),"tokyo-night":()=>k(()=>import("./tokyo-night-hegEt444.js"),[]),vesper:()=>k(()=>import("./vesper-DRje8inN.js"),[]),"vitesse-black":()=>k(()=>import("./vitesse-black-Bkuqu6BP.js"),[]),"vitesse-dark":()=>k(()=>import("./vitesse-dark-D0r3Knsf.js"),[]),"vitesse-light":()=>k(()=>import("./vitesse-light-CVO1_9PV.js"),[])};function Hn(e){return hn({name:e,collection:No,colorScheme:Uo(e),load:Vo[e]})}const Gi=Ye({themes:Object.freeze([...Wi.map(e=>Hn(e)),...Fo.map(e=>Hn(e))])});Ye({themes:[$i,Gi]});function ji(e){if(Oi())throw new Error(`Theme "${e}" cannot be resolved from a worker context. Themes must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);if(X.hasRegisteredTheme(e))return;const t=Gi.getTheme(e);if(t!=null){X.registerThemeIfAbsent(t.name,t.load);return}throw new Error(`No valid theme loader registered for "${e}"`)}function qi(e,t){if(t.name!==e)throw new Error(`resolvedTheme: themeName: ${e} does not match theme.name: ${t.name}`)}async function Bo(e){ji(e);const t=await X.resolveTheme(e);return qi(e,t),t}function $o(e){return X.getResolvedTheme(e)??Bo(e)}let $;async function xt({themes:e,langs:t,preferredHighlighter:n="shiki-js"}){$??=Nr({themes:[],langs:["text"],engine:n==="shiki-wasm"?Fr(k(()=>import("./wasm-CG6Dc4jp.js"),[])):zr()});const i=Wo($)?await $:$;$=i;const r=[];for(const s of t){if(s==="text"||s==="ansi")continue;const l=Fi(s);"then"in l?r.push(l):Rn(l,i)}const o=[];for(const s of e){const l=$o(s);"then"in l?o.push(l):An(l,$)}return(r.length>0||o.length>0)&&await Promise.all([Promise.all(r).then(s=>{Rn(s,i)}),Promise.all(o).then(s=>{An(s,i)})]),i}function ql(e=$){return e!=null&&!("then"in e)}function Ki(){if($!=null&&!("then"in $))return $}function Wo(e=$){return e!=null&&"then"in e}function Kl(e=$){return e==null}async function Yl(e){await xt(e)}async function Xl(){$!=null&&((await $).dispose(),So(),To(),$=void 0)}for(const e of $i.getThemes())X.registerThemeIfAbsent(e.name,e.load);function cn(e=_){const t=[];return typeof e=="string"?t.push(e):(t.push(e.dark),t.push(e.light)),t}function Ge(e){for(const t of cn(e))if(!vt.has(t))return!1;return!0}function Go(e){return X.hasResolvedThemes(e)}function Oe(e,t){return De(e.theme,t.theme)&&e.useTokenTransformer===t.useTokenTransformer&&e.tokenizeMaxLineLength===t.tokenizeMaxLineLength}function ae(e,t){return e?.cacheKey===t?.cacheKey&&e?.contents===t?.contents&&e?.name===t?.name&&e?.lang===t?.lang}function Lt(e,t){return e==null||t==null?e===t:e.startingLine===t.startingLine&&e.totalLines===t.totalLines&&e.bufferBefore===t.bufferBefore&&e.bufferAfter===t.bufferAfter}function qt(e){return A({tagName:"div",children:[A({tagName:"div",children:e.annotations?.map(t=>A({tagName:"slot",properties:{name:t}})),properties:{"data-annotation-content":""}})],properties:{"data-line-annotation":`${e.hunkIndex},${e.lineIndex}`}})}function jo(e){switch(e){case"file":return"diffs-icon-file-code";case"change":return"diffs-icon-symbol-modified";case"new":return"diffs-icon-symbol-added";case"deleted":return"diffs-icon-symbol-deleted";case"rename-pure":case"rename-changed":return"diffs-icon-symbol-moved"}}function Yi({fileOrDiff:e,mode:t,stickyHeader:n}){const i="type"in e?e:void 0,r={"data-diffs-header":t,"data-change-type":i?.type,"data-sticky":n?"":void 0};return A({tagName:"div",children:[t==="custom"?A({tagName:"slot",properties:{name:an}}):qo({name:e.name,prevName:"prevName"in e?e.prevName:void 0,iconType:i?.type??"file"}),...t==="custom"?[]:[Ko(i)]],properties:r})}function qo({name:e,prevName:t,iconType:n}){const i=[A({tagName:"slot",properties:{name:on}}),pt({name:jo(n),properties:{"data-change-icon":n}})];return t!=null&&(i.push(A({tagName:"div",children:[A({tagName:"bdi",children:[W(t)]})],properties:{"data-prev-name":""}})),i.push(pt({name:"diffs-icon-arrow-right-short",properties:{"data-rename-icon":""}}))),i.push(A({tagName:"div",children:[A({tagName:"bdi",children:[W(e)]})],properties:{"data-title":""}})),A({tagName:"div",children:i,properties:{"data-header-content":""}})}function Ko(e){const t=[];if(e!=null){let n=0,i=0;for(const r of e.hunks)n+=r.additionLines,i+=r.deletionLines;(i>0||n===0)&&t.push(A({tagName:"span",children:[W(`-${i}`)],properties:{"data-deletions-count":""}})),(n>0||i===0)&&t.push(A({tagName:"span",children:[W(`+${n}`)],properties:{"data-additions-count":""}}))}return t.push(A({tagName:"slot",properties:{name:sn}})),A({tagName:"div",children:t,properties:{"data-metadata":""}})}function Xi(e){return A({tagName:"pre",properties:Yo(e)})}function Yo({diffIndicators:e,disableBackground:t,disableLineNumbers:n,overflow:i,split:r,totalLines:o,type:s,customProperties:l}){return{...l,"data-diff":s==="diff"?"":void 0,"data-file":s==="file"?"":void 0,"data-diff-type":s==="diff"?r?"split":"single":void 0,"data-overflow":i,"data-disable-line-numbers":n?"":void 0,"data-background":t?void 0:"","data-indicators":e==="bars"||e==="classic"?e:void 0,style:`--diffs-min-number-column-width-default:${`${o}`.length}ch;`}}const Z=new Map;let bt=0;const Ne={"1c":"1c",abap:"abap",as:"actionscript-3",ada:"ada",adb:"ada",ads:"ada",adoc:"asciidoc",asciidoc:"asciidoc","component.html":"angular-html","component.ts":"angular-ts",conf:"nginx",htaccess:"apache",cls:"tex",trigger:"apex",apl:"apl",applescript:"applescript",scpt:"applescript",ara:"ara",asm:"asm",s:"riscv",astro:"astro",awk:"awk",bal:"ballerina",sh:"zsh",bash:"zsh",bat:"cmd",cmd:"cmd",be:"berry",beancount:"beancount",bib:"bibtex",bicep:"bicep","blade.php":"blade",bsl:"bsl",c:"c",h:"objective-cpp",cs:"csharp",cpp:"cpp",hpp:"cpp",cc:"cpp",cxx:"cpp",hh:"cpp",cdc:"cdc",cairo:"cairo",clar:"clarity",clj:"clojure",cljs:"clojure",cljc:"clojure",soy:"soy",cmake:"cmake","CMakeLists.txt":"cmake",cob:"cobol",cbl:"cobol",cobol:"cobol",CODEOWNERS:"codeowners",ql:"ql",coffee:"coffeescript",lisp:"lisp",cl:"lisp",lsp:"lisp",log:"log",v:"verilog",cql:"cql",cr:"crystal",css:"css",csv:"csv",cue:"cue",cypher:"cypher",cyp:"cypher",d:"d",dart:"dart",dax:"dax",desktop:"desktop",diff:"diff",patch:"diff",Dockerfile:"dockerfile",dockerfile:"dockerfile",env:"dotenv",dm:"dream-maker",edge:"edge",el:"emacs-lisp",ex:"elixir",exs:"elixir",elm:"elm",erb:"erb",erl:"erlang",hrl:"erlang",f:"fortran-fixed-form",for:"fortran-fixed-form",fs:"fsharp",fsi:"fsharp",fsx:"fsharp",f03:"f03",f08:"f08",f18:"f18",f77:"f77",f90:"fortran-free-form",f95:"fortran-free-form",fnl:"fennel",fish:"fish",ftl:"ftl",tres:"gdresource",res:"gdresource",gd:"gdscript",gdshader:"gdshader",gs:"genie",feature:"gherkin",COMMIT_EDITMSG:"git-commit","git-rebase-todo":"git-rebase",gjs:"glimmer-js",gleam:"gleam",gts:"glimmer-ts",glsl:"glsl",vert:"glsl",frag:"glsl",shader:"shaderlab",gp:"gnuplot",plt:"gnuplot",gnuplot:"gnuplot",go:"go",graphql:"graphql",gql:"graphql",groovy:"groovy",gvy:"groovy",hack:"hack",haml:"haml",hbs:"handlebars",handlebars:"handlebars",hs:"haskell",lhs:"haskell",hx:"haxe",hcl:"hcl",hjson:"hjson",hlsl:"hlsl",fx:"hlsl",html:"html",htm:"html",http:"http",rest:"http",hxml:"hxml",hy:"hy",imba:"imba",ini:"ini",cfg:"ini",jade:"pug",pug:"pug",java:"java",js:"javascript",mjs:"javascript",cjs:"javascript",jinja:"jinja",jinja2:"jinja",j2:"jinja",jison:"jison",jl:"julia",json:"json",json5:"json5",jsonc:"jsonc",jsonl:"jsonl",jsonnet:"jsonnet",libsonnet:"jsonnet",jssm:"jssm",jsx:"jsx",kt:"kotlin",kts:"kts",kql:"kusto",tex:"tex",ltx:"tex",lean:"lean4",less:"less",liquid:"liquid",lit:"lit",ll:"llvm",logo:"logo",lua:"lua",luau:"luau",Makefile:"makefile",mk:"makefile",makefile:"makefile",md:"markdown",markdown:"markdown",marko:"marko",m:"wolfram",mat:"matlab",mdc:"mdc",mdx:"mdx",wiki:"wikitext",mediawiki:"wikitext",mmd:"mermaid",mermaid:"mermaid",mips:"mipsasm",mojo:"mojo","🔥":"mojo",move:"move",nar:"narrat",nf:"nextflow",nim:"nim",nims:"nim",nimble:"nim",nix:"nix",nu:"nushell",mm:"objective-cpp",ml:"ocaml",mli:"ocaml",mll:"ocaml",mly:"ocaml",pas:"pascal",p:"pascal",pl:"prolog",pm:"perl",t:"perl",raku:"raku",p6:"raku",pl6:"raku",php:"php",phtml:"php",pls:"plsql",sql:"sql",po:"po",polar:"polar",pcss:"postcss",pot:"pot",potx:"potx",pq:"powerquery",pqm:"powerquery",ps1:"powershell",psm1:"powershell",psd1:"powershell",prisma:"prisma",pro:"prolog",P:"prolog",properties:"properties",proto:"protobuf",pp:"puppet",purs:"purescript",py:"python",pyw:"python",pyi:"python",qml:"qml",qmldir:"qmldir",qss:"qss",r:"r",R:"r",rkt:"racket",rktl:"racket",razor:"razor",cshtml:"razor",rb:"ruby",rbw:"ruby",reg:"reg",regex:"regexp",rel:"rel",rs:"rust",rst:"rst",rake:"ruby",gemspec:"ruby",jbuilder:"ruby",builder:"ruby",rabl:"ruby",arb:"ruby",ru:"ruby",podspec:"ruby",Gemfile:"ruby",Rakefile:"ruby",Guardfile:"ruby",Capfile:"ruby",Berksfile:"ruby",Brewfile:"ruby",Vagrantfile:"ruby",Thorfile:"ruby",Appraisals:"ruby",Dangerfile:"ruby",sas:"sas",sass:"sass",scala:"scala",sc:"scala",scm:"scheme",ss:"scheme",sld:"scheme",scss:"scss",sdbl:"sdbl",shadergraph:"shader",st:"smalltalk",sol:"solidity",sparql:"sparql",rq:"sparql",spl:"splunk",config:"ssh-config",do:"stata",ado:"stata",dta:"stata",styl:"stylus",stylus:"stylus",svelte:"svelte",swift:"swift",sv:"system-verilog",svh:"system-verilog",service:"systemd",socket:"systemd",device:"systemd",timer:"systemd",talon:"talonscript",tasl:"tasl",tcl:"tcl",templ:"templ",tf:"tf",tfvars:"tfvars",toml:"toml",ts:"typescript",tsp:"typespec",tsv:"tsv",tsx:"tsx",ttl:"turtle",twig:"twig",typ:"typst",vv:"v",vala:"vala",vapi:"vala",vb:"vb",vbs:"vb",bas:"vb",vh:"verilog",vhd:"vhdl",vhdl:"vhdl",vim:"vimscript",vue:"vue","vine.ts":"vue-vine",vy:"vyper",wasm:"wasm",wat:"wasm",wy:"文言",wgsl:"wgsl",wit:"wit",wl:"wolfram",nb:"wolfram",xml:"xml",xsl:"xsl",xslt:"xsl",yaml:"yaml",yml:"yml",zs:"zenscript",zig:"zig",zsh:"zsh",sty:"tex"};function Q(e){if(Z.has(e))return Z.get(e)??"text";if(Ne[e]!=null)return Ne[e];const t=e.match(/\.([^/\\]+\.[^/\\]+)$/);if(t!=null){if(Z.has(t[1]))return Z.get(t[1])??"text";if(Ne[t[1]]!=null)return Ne[t[1]]??"text"}const n=e.match(/\.([^.]+)$/)?.[1]??"";return Z.has(n)?Z.get(n)??"text":Ne[n]??"text"}function Ql(e,t){if(e<=bt)return!1;Z.clear();for(const n in t){const i=t[n];i!=null&&Z.set(n,i)}return bt=e,!0}function Jl(){return bt}function Xo(e,t){const n=Z.get(e);return n===t?!1:(n!=null&&console.warn(`setCustomExtension: overriding custom mapping for "${e}" from "${n}" to "${t}"`),Z.set(e,t),bt++,!0)}function Zl(){return Object.fromEntries(Z)}function un(e,{theme:t,preferredHighlighter:n="shiki-js"}){return{langs:[e??"text"],themes:cn(t),preferredHighlighter:n}}function ge(e){return`annotation-${"side"in e?`${e.side}-`:""}${e.lineNumber}`}function xe(e){return e.replace(/\n$|\r\n$/,"")}function Qo(e,t,n){const i=typeof n.lineInfo=="function"?n.lineInfo(t):n.lineInfo[t-1];if(i==null){const r=`processLine: line ${t}, contains no state.lineInfo`;throw console.error(r,{node:e,line:t,state:n}),new Error(r)}return e.tagName="div",e.properties["data-line"]=i.lineNumber,e.properties["data-alt-line"]=i.altLineNumber,e.properties["data-line-type"]=i.type,e.properties["data-line-index"]=i.lineIndex,e.children.length===0&&e.children.push(W(` +import{t as pe,b as Ln,n as Or,c as Nr,a as Fr,d as zr,s as Ur,g as Vr,e as Br}from"./index-BZFTzQ6y.js";import{f as Ld}from"./index-BZFTzQ6y.js";import{bR as k}from"./index-D-7nOosq.js";const Ei="diffs-container",$r=(()=>{try{return!1}catch{return!1}})(),Wr=/(?=^From [a-f0-9]+ .+$)/m,Ti=/(?=^diff --git)/gm,Ul=/(?=^---\s+\S)/gm,Vl=/(?=^@@ )/gm,Gr=/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(?: (.*))?/m,jr=/(?<=\n)/,qr=/^(---|\+\+\+)\s+([^\t\r\n]+)/,Kr=/^(---|\+\+\+)\s+[ab]\/([^\t\r\n]+)/,Yr=/^diff --git (?:"a\/(.+?)"|a\/(.+?)) (?:"b\/(.+?)"|b\/(.+?))$/,Xr=/^index ([0-9a-f]+)\.\.([0-9a-f]+)(?: (\d+))?$/i,Bl=/^<{7,}(?:\s.*)?$/,$l=/^\|{7,}(?:\s.*)?$/,Wl=/^={7,}$/,Gl=/^>{7,}(?:\s.*)?$/,on="header-prefix",sn="header-metadata",an="header-custom",_={dark:"pierre-dark",light:"pierre-light"},Ii="data-theme-css",Ri="data-unsafe-css",Qr="data-core-css",Jr="data-diffs-scrollbar-measure",Ai="--diffs-scrollbar-gutter-measured",jl=1,Zr=1e5,ln={hunkLineCount:50,lineHeight:20,diffHeaderHeight:44,spacing:8},_e={...ln,hunkLineCount:1},eo={paddingTop:8,paddingBottom:8,gap:8},to={omega:.015,positionEpsilon:.5,velocityEpsilon:.05},no=Object.freeze({fromStart:0,fromEnd:0}),Ae={startingLine:0,totalLines:1/0,bufferBefore:0,bufferAfter:0},Hi={startingLine:0,totalLines:0,bufferBefore:0,bufferAfter:0},Ie=new Set;let Re=null;function Y(e){Ie.add(e),Re??=requestAnimationFrame(Mi)}function io(e){Ie.delete(e),Ie.size===0&&Re!=null&&(cancelAnimationFrame(Re),Re=null)}function Mi(e){const t=new Set(Ie);Ie.clear();for(const n of t)try{n(e)}catch(i){console.error(i)}Ie.size>0?Re=requestAnimationFrame(Mi):Re=null}function He(e,t,n){if(e===t||e==null||t==null)return e===t;const i=new Set(n),r=Object.keys(e),o=new Set(Object.keys(t));for(const s of r)if(o.delete(s),!i.has(s)&&(!(s in t)||e[s]!==t[s]))return!1;for(const s of Array.from(o))if(!i.has(s))return!1;return!0}function De(e,t){return e==null||t==null||typeof e=="string"||typeof t=="string"?e===t:e.dark===t.dark&&e.light===t.light}function dn(e,t){const n=e?.theme??_,i=t?.theme??_,r=kn(e),o=kn(t);return De(n,i)&&He(e,t,["theme","parseDiffOptions"])&&He(r,o)}function kn(e){if(e!=null&&"parseDiffOptions"in e)return e.parseDiffOptions}function Wt(e,t){return e?.start===t?.start&&e?.end===t?.end&&e?.side===t?.side&&e?.endSide===t?.endSide}function Gt({scrollTop:e,scrollHeight:t,height:n,fitPerfectly:i=!1,fitPerfectlyOverscroll:r=0,overscrollSize:o}){const s=n+o*2,l=i?n+r*2:s;if(t=Math.max(t,l),s>=t||i){const h=Math.max(e-r,0),c=Math.min(e+l,t);return{top:h,bottom:Math.max(c,h)}}let a=e+n/2-s/2,d=a+s;return a<0&&(a=0),d>t&&(d=t),a=Math.floor(Math.max(a,0)),{top:a,bottom:Math.ceil(Math.max(Math.min(d,t),a))}}function ro(){return typeof window>"u"||typeof window.matchMedia!="function"?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function W(e){return{type:"text",value:e}}function A({tagName:e,children:t=[],properties:n={}}){return{type:"element",tagName:e,properties:n,children:t}}function pt({name:e,width:t=16,height:n=16,properties:i}){return A({tagName:"svg",properties:{width:t,height:n,viewBox:"0 0 16 16",...i},children:[A({tagName:"use",properties:{href:`#${e.replace(/^#/,"")}`}})]})}function oo(e){let t=e.children[0];for(;t!=null;){if(t.type==="element"&&t.tagName==="code")return t;"children"in t?t=t.children[0]:t=null}}function Ee(e){return A({tagName:"div",properties:{"data-gutter":""},children:e})}function Di(e,t,n,i={}){return A({tagName:"div",properties:{"data-line-type":e,"data-column-number":t,"data-line-index":n,...i},children:t!=null?[A({tagName:"span",properties:{"data-line-number-content":""},children:[W(`${t}`)]})]:void 0})}function j(e,t,n){return A({tagName:"div",properties:{"data-gutter-buffer":t,"data-buffer-size":n,"data-line-type":t==="annotation"?void 0:e,style:t==="annotation"?`grid-row: span ${n};`:`grid-row: span ${n};min-height:calc(${n} * 1lh);`}})}function so(){return A({tagName:"button",properties:{"data-utility-button":"",type:"button"},children:[pt({name:"diffs-icon-plus",properties:{"data-icon":""}})]})}function ao(e,t){return e.lineNumber===t.lineNumber&&e.side===t.side}var Pi=class{mode;options;hoveredLine;hoveredToken;pre;gutterUtilityLine;gutterUtilityContainer;gutterUtilityButton;gutterUtilitySlot;interactiveLinesAttr=!1;interactiveLineNumbersAttr=!1;hasPointerListeners=!1;hasDocumentPointerListeners=!1;selectedRange=null;proposedSelectedRange;renderedSelectionRange;selectionAnchor;queuedSelectionRender;pointerSession={mode:"idle"};constructor(e,t){this.mode=e,this.options=t}setOptions(e){this.options=e}cleanUp(){this.pre?.removeEventListener("click",this.handlePointerClick),this.pre?.removeEventListener("pointerdown",this.handlePointerDown),this.pre?.removeEventListener("pointermove",this.handlePointerMove),this.pre?.removeEventListener("pointerleave",this.handlePointerLeave),this.pre?.removeAttribute("data-interactive-lines"),this.pre?.removeAttribute("data-interactive-line-numbers"),this.pre=void 0,this.gutterUtilityContainer?.remove(),this.gutterUtilityLine=void 0,this.gutterUtilityContainer=void 0,this.gutterUtilityButton=void 0,this.gutterUtilitySlot=void 0,this.clearHoveredLine(),this.clearHoveredToken(),this.detachDocumentPointerListeners(),this.clearPointerSession(),this.queuedSelectionRender!=null&&(cancelAnimationFrame(this.queuedSelectionRender),this.queuedSelectionRender=void 0),this.interactiveLinesAttr=!1,this.interactiveLineNumbersAttr=!1,this.hasPointerListeners=!1}setup(e){this.setSelectionDirty();const{usesCustomGutterUtility:t=!1,enableGutterUtility:n=!1}=this.options;this.pre!==e&&(this.cleanUp(),this.pre=e),n?this.ensureGutterUtilityNode(t):this.gutterUtilityContainer!=null&&(this.gutterUtilityContainer.remove(),this.gutterUtilityLine=void 0,this.gutterUtilityContainer=void 0,this.gutterUtilityButton=void 0,this.gutterUtilitySlot=void 0,this.pointerSession.mode==="gutterSelecting"&&(this.clearPointerSession(),this.detachDocumentPointerListeners())),this.syncPointerListeners(e),this.updateInteractiveLineAttributes(),this.renderSelection(),this.placeUtility()}setSelectionDirty(){this.renderedSelectionRange=void 0}isSelectionDirty(){return this.renderedSelectionRange===null}setSelection(e,t){const n=!(e===this.selectedRange||Wt(e??void 0,this.selectedRange??void 0));!this.isSelectionDirty()&&!n||(this.proposedSelectedRange=void 0,this.selectedRange=e,this.renderSelection(),this.placeUtility(),n&&t?.notify!==!1&&this.notifySelectionCommitted())}getSelection(){return this.selectedRange}getHoveredLine=()=>{const e=this.gutterUtilityLine??this.hoveredLine;if(e!=null){if(this.mode==="diff"&&e.type==="diff-line")return{lineNumber:e.lineNumber,side:e.annotationSide};if(this.mode==="file"&&e.type==="line")return{lineNumber:e.lineNumber}}};handlePointerClick=e=>{const{onHunkExpand:t,onLineClick:n,onLineNumberClick:i,onTokenClick:r,onMergeConflictActionClick:o}=this.options;t==null&&n==null&&i==null&&o==null&&r==null||this.options.onGutterUtilityClick!=null&&et(e.composedPath())||(he(this.options.__debugPointerEvents,"click","FileDiff.DEBUG.handlePointerClick:",e),this.handlePointerEvent({eventType:"click",event:e}))};handlePointerMove=e=>{if(e.pointerType!=="mouse")return;const{lineHoverHighlight:t="disabled",onLineEnter:n,onLineLeave:i,onTokenEnter:r,onTokenLeave:o,enableGutterUtility:s=!1}=this.options;t==="disabled"&&!s&&n==null&&i==null&&r==null&&o==null||(he(this.options.__debugPointerEvents,"move","FileDiff.DEBUG.handlePointerMove:",e),this.handlePointerEvent({eventType:"move",event:e}))};handlePointerLeave=e=>{const{__debugPointerEvents:t}=this.options;if(he(t,"move","FileDiff.DEBUG.handlePointerLeave: no event"),this.hoveredLine==null&&this.hoveredToken==null){he(t,"move","FileDiff.DEBUG.handlePointerLeave: returned early, no hovered line or token");return}this.hoveredToken!=null&&(this.options.onTokenLeave?.(this.hoveredToken,e),this.clearHoveredToken()),this.hoveredLine!=null&&(this.options.onLineLeave?.({...this.hoveredLine,event:e}),this.clearHoveredLine()),this.placeUtility()};handlePointerEvent({eventType:e,event:t}){const{__debugPointerEvents:n}=this.options,i=t.composedPath();he(n,e,"FileDiff.DEBUG.handlePointerEvent:",{eventType:e,composedPath:i});const r=this.resolvePointerTarget(i);he(n,e,"FileDiff.DEBUG.handlePointerEvent: resolvePointerTarget result:",r);const{onLineClick:o,onLineNumberClick:s,onLineEnter:l,onLineLeave:a,onTokenClick:d,onTokenEnter:h,onTokenLeave:c,onHunkExpand:u,onMergeConflictActionClick:f}=this.options;switch(e){case"move":{const g=Tt(r)&&this.hoveredLine?.lineElement===r.lineElement;ut(r)&&this.hoveredToken?.tokenElement===r.tokenElement||(this.hoveredToken!=null&&(c?.(this.hoveredToken,t),this.clearHoveredToken()),ut(r)&&(this.setHoveredToken(this.toTokenEventBaseProps(r)),h?.(this.hoveredToken,t))),g||(this.hoveredLine!=null&&(a?.({...this.hoveredLine,event:t}),this.clearHoveredLine()),Tt(r)?(this.setHoveredLine(this.toEventBaseProps(r)),this.placeUtility(),l?.({...this.hoveredLine,event:t})):this.placeUtility());break}case"click":{if(r==null)break;if(co(r)&&f!=null){f(r);break}if(ho(r)&&u!=null){u(r.hunkIndex,r.all||t.shiftKey?"both":r.direction,r.all||t.shiftKey?Number.POSITIVE_INFINITY:void 0);break}if(!Tt(r))break;ut(r)&&d!=null&&d(this.toTokenEventBaseProps(r),t);const g=this.toEventBaseProps(r);s!=null&&r.numberColumn?s({...g,event:t}):o?.({...g,event:t});break}}}syncPointerListeners(e){const{__debugPointerEvents:t,lineHoverHighlight:n="disabled",onLineClick:i,onLineNumberClick:r,onLineEnter:o,onLineLeave:s,onTokenClick:l,onTokenEnter:a,onTokenLeave:d,onHunkExpand:h,onMergeConflictActionClick:c,enableGutterUtility:u=!1,enableLineSelection:f=!1,onGutterUtilityClick:g}=this.options,b=g!=null,y=n!=="disabled"||i!=null||r!=null||o!=null||s!=null||l!=null||a!=null||d!=null||h!=null||c!=null||u||f||b;y&&!this.hasPointerListeners?(e.addEventListener("click",this.handlePointerClick),e.addEventListener("pointerdown",this.handlePointerDown),e.addEventListener("pointermove",this.handlePointerMove),e.addEventListener("pointerleave",this.handlePointerLeave),this.hasPointerListeners=!0,he(t,"click","FileDiff.DEBUG.attachEventListeners: Attaching click events for:",(()=>{const C=[];return(t==="both"||t==="click")&&(i!=null&&C.push("onLineClick"),r!=null&&C.push("onLineNumberClick"),h!=null&&C.push("expandable hunk separators"),c!=null&&C.push("merge conflict actions")),C})()),he(t,"move","FileDiff.DEBUG.attachEventListeners: Attaching pointer move event"),he(t,"move","FileDiff.DEBUG.attachEventListeners: Attaching pointer leave event")):!y&&this.hasPointerListeners&&(e.removeEventListener("click",this.handlePointerClick),e.removeEventListener("pointerdown",this.handlePointerDown),e.removeEventListener("pointermove",this.handlePointerMove),e.removeEventListener("pointerleave",this.handlePointerLeave),this.hasPointerListeners=!1);const m=this.pointerSession.mode==="selecting"||this.pointerSession.mode==="pendingSingleLineUnselect",p=this.pointerSession.mode==="gutterSelecting";(!f&&m||!b&&p)&&(this.clearPointerSession(),this.detachDocumentPointerListeners(),this.selectionAnchor=void 0,this.clearPendingSingleLineState())}updateInteractiveLineAttributes(){if(this.pre==null)return;const{onLineClick:e,onLineNumberClick:t,enableLineSelection:n=!1}=this.options,i=e!=null,r=t!=null||n;i&&!this.interactiveLinesAttr?(this.pre.setAttribute("data-interactive-lines",""),this.interactiveLinesAttr=!0):!i&&this.interactiveLinesAttr&&(this.pre.removeAttribute("data-interactive-lines"),this.interactiveLinesAttr=!1),r&&!this.interactiveLineNumbersAttr?(this.pre.setAttribute("data-interactive-line-numbers",""),this.interactiveLineNumbersAttr=!0):!r&&this.interactiveLineNumbersAttr&&(this.pre.removeAttribute("data-interactive-line-numbers"),this.interactiveLineNumbersAttr=!1)}handlePointerDown=e=>{if(e.pointerType==="mouse"&&e.button!==0||this.pre==null||this.pointerSession.mode!=="idle")return;const t=e.composedPath();et(t)&&this.options.onGutterUtilityClick!=null?this.startGutterSelectionFromPointerDown(e):(e.pointerType!=="mouse"&&this.revealUtilityFromGutterPath(t),this.startLineSelectionFromPointerDown(e))};startLineSelectionFromPointerDown(e){const{enableLineSelection:t=!1}=this.options;if(!t)return;const n=this.resolveSelectionInfo(e,{source:"event-path",requireNumberColumn:!0});if(n==null)return;const{pre:i}=this;if(i==null)return;const{lineNumber:r,eventSide:o,lineIndex:s}=n;if(e.shiftKey&&this.selectedRange!=null){const l=this.getIndexesFromSelection(this.selectedRange,i.getAttribute("data-diff-type")==="split");if(l==null)return;const a=l.start<=l.end?s>=l.start:s<=l.end;this.selectionAnchor={lineNumber:a?this.selectedRange.start:this.selectedRange.end,side:a?this.selectedRange.side:this.selectedRange.endSide??this.selectedRange.side},this.updateSelection(r,o,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.pointerSession={mode:"selecting",pointerId:e.pointerId},this.attachDocumentPointerListeners();return}if(this.selectedRange?.start===r&&this.selectedRange?.end===r){const l={lineNumber:r,side:o};this.selectionAnchor=l,this.pointerSession={mode:"pendingSingleLineUnselect",pointerId:e.pointerId,anchor:l,pending:l},this.attachDocumentPointerListeners();return}this.options.controlledSelection===!0?this.proposedSelectedRange=null:this.selectedRange=null,this.placeUtility(),this.selectionAnchor={lineNumber:r,side:o},this.updateSelection(r,o,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.pointerSession={mode:"selecting",pointerId:e.pointerId},this.attachDocumentPointerListeners()}startGutterSelectionFromPointerDown(e){const{enableLineSelection:t=!1,onGutterUtilityClick:n}=this.options;if(n==null)return;const i=this.currentSelectionEnds(),r=i?.bottom??this.resolveSelectionPoint(e,{source:"event-path",excludeUtility:!1}),o=i?.top??r;r==null||o==null||(e.preventDefault(),e.stopPropagation(),this.pointerSession={mode:"gutterSelecting",pointerId:e.pointerId,anchor:o,current:r},t&&(this.selectionAnchor={lineNumber:o.lineNumber,side:o.side},this.updateSelection(r.lineNumber,r.side,!1),this.notifySelectionStart(this.getCurrentSelectionRange())),this.attachDocumentPointerListeners())}handleDocumentPointerMove=e=>{const{enableLineSelection:t=!1}=this.options;switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionPoint(e,{source:"coordinates-first"});if(n==null)return;this.pointerSession.current=n,t===!0&&this.updateSelection(n.lineNumber,n.side);return}case"selecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionInfo(e,{source:"coordinates-first",requireNumberColumn:!1});if(n==null||this.selectionAnchor==null)return;this.updateSelection(n.lineNumber,n.eventSide);return}case"pendingSingleLineUnselect":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const n=this.resolveSelectionInfo(e,{source:"coordinates-first",requireNumberColumn:!1});if(n==null||this.selectionAnchor==null)return;const i={lineNumber:n.lineNumber,side:n.eventSide};if(ao(this.pointerSession.pending,i))return;this.updateSelection(n.lineNumber,n.eventSide,!1),this.notifySelectionStart(this.getCurrentSelectionRange()),this.notifySelectionChangeDelta(),this.pointerSession={mode:"selecting",pointerId:e.pointerId};return}}};handleDocumentPointerUp=e=>{const{enableLineSelection:t=!1,onGutterUtilityClick:n}=this.options;switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":{if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault();const i=this.resolveSelectionPoint(e,{source:"coordinates-first"});i!=null&&(this.pointerSession.current=i,t&&this.updateSelection(i.lineNumber,i.side)),n?.(this.buildSelectedLineRange(this.pointerSession.anchor,this.pointerSession.current)),this.selectionAnchor=void 0,t&&(this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection()),this.clearPointerSession(),this.detachDocumentPointerListeners();return}case"pendingSingleLineUnselect":if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault(),this.updateSelection(null,void 0,!1),this.selectionAnchor=void 0,this.clearPendingSingleLineState(),this.detachDocumentPointerListeners(),this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection();return;case"selecting":if(e.pointerId!==this.pointerSession.pointerId)return;e.preventDefault(),this.selectionAnchor=void 0,this.detachDocumentPointerListeners(),this.clearPointerSession(),this.notifySelectionEnd(this.getCurrentSelectionRange()),this.notifySelectionCommitted(),this.clearProposedSelection()}};handleDocumentPointerCancel=e=>{switch(this.pointerSession.mode){case"idle":return;case"gutterSelecting":case"selecting":case"pendingSingleLineUnselect":if("pointerId"in this.pointerSession&&e.pointerId!==this.pointerSession.pointerId)return;this.selectionAnchor=void 0,this.clearProposedSelection(),this.clearPendingSingleLineState(),this.clearPointerSession(),this.detachDocumentPointerListeners()}};clearHoveredLine(){this.hoveredLine!=null&&(this.hoveredLine.lineElement.removeAttribute("data-hovered"),this.hoveredLine.numberElement.removeAttribute("data-hovered"),this.hoveredLine=void 0)}setHoveredLine(e){const{lineHoverHighlight:t="disabled"}=this.options;this.hoveredLine!=null&&this.clearHoveredLine(),this.hoveredLine=e,t!=="disabled"&&((t==="both"||t==="line")&&this.hoveredLine.lineElement.setAttribute("data-hovered",""),(t==="both"||t==="number")&&this.hoveredLine.numberElement.setAttribute("data-hovered",""))}clearHoveredToken(){this.hoveredToken!=null&&(this.hoveredToken=void 0)}setHoveredToken(e){this.hoveredToken!=null&&this.clearHoveredToken(),this.hoveredToken=e}ensureGutterUtilityNode(e){if(this.gutterUtilityContainer==null&&(this.gutterUtilityContainer=document.createElement("div"),this.gutterUtilityContainer.setAttribute("data-gutter-utility-slot","")),e)this.gutterUtilityButton!=null&&(this.gutterUtilityButton.remove(),this.gutterUtilityButton=void 0),this.gutterUtilitySlot==null&&(this.gutterUtilitySlot=document.createElement("slot"),this.gutterUtilitySlot.name="gutter-utility-slot"),this.gutterUtilitySlot.parentNode!==this.gutterUtilityContainer&&this.gutterUtilityContainer.replaceChildren(this.gutterUtilitySlot);else{if(this.gutterUtilitySlot?.remove(),this.gutterUtilitySlot=void 0,this.gutterUtilityButton==null){const t=document.createElement("div");t.innerHTML=pe(so());const n=t.firstElementChild;if(!(n instanceof HTMLButtonElement))throw new Error("InteractionManager.ensureGutterUtilityNode: Node element should be a button");n.remove(),this.gutterUtilityButton=n}this.gutterUtilityButton.parentNode!==this.gutterUtilityContainer&&this.gutterUtilityContainer.replaceChildren(this.gutterUtilityButton)}}revealUtilityFromGutterPath(e){if(this.placeUtilityFromSelection())return;const t=this.resolvePointerTarget(e);Ve(t)&&t.numberColumn&&this.showUtilityOnLine(this.toEventBaseProps(t))}placeUtility(){if(!this.placeUtilityFromSelection()){if(this.hoveredLine!=null){this.showUtilityOnLine(this.hoveredLine);return}this.hideUtility()}}placeUtilityFromSelection(){const e=this.currentSelectionEnds();if(e==null)return!1;const t=this.targetForSelectionPoint(e.bottom);return t==null?this.hideUtility():this.showUtilityOnLine(this.toEventBaseProps(t)),!0}showUtilityOnLine(e){this.gutterUtilityContainer!=null&&(this.gutterUtilityLine=e,e.numberElement.appendChild(this.gutterUtilityContainer))}hideUtility(){this.gutterUtilityContainer?.remove(),this.gutterUtilityLine=void 0}currentSelectionEnds(){const e=this.getCurrentSelectionRange();return e==null?void 0:this.selectionEnds(e)}selectionEnds(e){const t={lineNumber:e.start,side:e.side},n={lineNumber:e.end,side:e.endSide??e.side},i=this.selectionPointRowIndex(t),r=this.selectionPointRowIndex(n);if(!(i==null||r==null))return i>r?{top:n,bottom:t}:{top:t,bottom:n}}selectionPointRowIndex(e){const t=this.getLineIndex(e.lineNumber,e.side);if(t!=null)return this.isSplitDiff()?t[1]:t[0]}targetForSelectionPoint(e){if(this.pre==null)return;const t=this.getLineIndex(e.lineNumber,e.side);if(t==null)return;const n=this.mode==="diff"?`${t[0]},${t[1]}`:`${t[0]}`,i=this.pre.querySelectorAll(`[data-column-number="${e.lineNumber}"][data-line-index="${n}"]`);for(const r of i){if(!(r instanceof HTMLElement))continue;const o=this.resolvePointerTarget(Ze(r));if(Ve(o)&&!(this.mode==="diff"&&e.side!=null&&o.side!==e.side))return o}}attachDocumentPointerListeners(){this.hasDocumentPointerListeners||(document.addEventListener("pointermove",this.handleDocumentPointerMove),document.addEventListener("pointerup",this.handleDocumentPointerUp),document.addEventListener("pointercancel",this.handleDocumentPointerCancel),this.hasDocumentPointerListeners=!0)}detachDocumentPointerListeners(){this.hasDocumentPointerListeners&&(document.removeEventListener("pointermove",this.handleDocumentPointerMove),document.removeEventListener("pointerup",this.handleDocumentPointerUp),document.removeEventListener("pointercancel",this.handleDocumentPointerCancel),this.hasDocumentPointerListeners=!1)}clearPointerSession(){this.pointerSession={mode:"idle"}}clearPendingSingleLineState(){this.pointerSession.mode==="pendingSingleLineUnselect"&&(this.pointerSession={mode:"idle"})}selectionInfoFromPath(e,t){const n=this.resolvePointerTarget(e);if(Ve(n)&&!(t&&!n.numberColumn)&&n.splitLineIndex!=null)return{lineIndex:n.splitLineIndex,lineNumber:n.lineNumber,eventSide:this.mode==="diff"?n.side:void 0}}resolveSelectionInfo(e,t){const n=this.resolveSelectionPath(e,t);return n!=null?this.selectionInfoFromPath(n,t.requireNumberColumn):void 0}selectionPointFromPath(e){const t=this.resolvePointerTarget(e);if(Ve(t))return{lineNumber:t.lineNumber,side:this.mode==="diff"?t.side:void 0}}resolveSelectionPoint(e,t){const n=this.resolveSelectionPath(e,t);return n!=null?this.selectionPointFromPath(n):void 0}resolveSelectionPath(e,t){const n=t.excludeUtility!==!1;switch(t.source){case"event-path":return this.pathFromEventPath(e.composedPath(),n);case"coordinates-first":{const i=this.pathFromCoordinates(e,n);return i!==void 0?i??void 0:this.pathFromEventPath(e.composedPath(),n)}}}pathFromCoordinates(e,t){const n=this.hitTest(e);if(n!==void 0)return n===null?null:this.pathFromElement(n,t)??null}pathFromEventPath(e,t){if(!(t&&et(e))){for(const n of e)if(n instanceof Element)return this.pathFromElement(n,t)}}pathFromElement(e,t){const n=Ze(e);if(t&&et(n))return;const i=fo(e);return i!=null?Ze(i):this.pathFromAnnotationSlot(e)}pathFromAnnotationSlot(e){const t=go(po(e));if(t==null)return;const n=this.targetForSelectionPoint(t);return n!=null?Ze(n.lineElement):void 0}hitTest(e){if(!Number.isFinite(e.clientX)||!Number.isFinite(e.clientY))return;const t=this.pre?.getRootNode(),n=En(t)?t:En(document)?document:void 0;if(n!=null)return n.elementFromPoint(e.clientX,e.clientY)}getLineIndex(e,t){const{getLineIndex:n}=this.options;return n!=null?n(e,t):[e-1,e-1]}getCurrentSelectionRange(){return this.proposedSelectedRange!==void 0?this.proposedSelectedRange:this.selectedRange}clearProposedSelection(){this.proposedSelectedRange=void 0}updateSelection(e,t,n=!0){const i=this.getCurrentSelectionRange();let r;if(e==null)r=null;else{const o=this.selectionAnchor?.side??t,s=this.selectionAnchor?.lineNumber??e;r=this.buildSelectionRange(s,e,o,t)}Wt(i??void 0,r??void 0)||(this.options.controlledSelection===!0?this.proposedSelectedRange=r:(this.selectedRange=r,this.queuedSelectionRender??=requestAnimationFrame(this.renderSelection)),this.placeUtility(),n&&this.notifySelectionChangeDelta())}getIndexesFromSelection(e,t){if(this.pre==null)return;const n=this.getLineIndex(e.start,e.side),i=this.getLineIndex(e.end,e.endSide??e.side);return n!=null&&i!=null?{start:t?n[1]:n[0],end:t?i[1]:i[0]}:void 0}renderSelection=()=>{if(this.queuedSelectionRender!=null&&(cancelAnimationFrame(this.queuedSelectionRender),this.queuedSelectionRender=void 0),this.pre==null||this.renderedSelectionRange===this.selectedRange)return;const e=this.pre.querySelectorAll("[data-selected-line]");for(const l of e)l.removeAttribute("data-selected-line");if(this.renderedSelectionRange=this.selectedRange,this.selectedRange==null)return;const{children:t}=this.pre;if(t.length===0)return;if(t.length>2)throw console.error(t),new Error("InteractionManager.renderSelection: Somehow there are more than 2 code elements...");const n=this.pre.getAttribute("data-diff-type")==="split",i=this.getIndexesFromSelection(this.selectedRange,n);if(i==null)throw console.error({rowRange:i,selectedRange:this.selectedRange}),new Error("InteractionManager.renderSelection: No valid rowRange");const r=i.start===i.end,o=Math.min(i.start,i.end),s=Math.max(i.start,i.end);for(const l of t){const[a,d]=l.children,h=d.children.length;if(h!==a.children.length)throw new Error("InteractionManager.renderSelection: gutter and content children dont match, something is wrong");for(let c=0;c<h;c++){const u=d.children[c],f=a.children[c];if(!(u instanceof HTMLElement)||!(f instanceof HTMLElement))continue;const g=this.parseLineIndex(u,n);if((g??0)>s)break;if(g==null||g<o)continue;let b=r?"single":g===o?"first":g===s?"last":"";u.setAttribute("data-selected-line",b),f.setAttribute("data-selected-line",b),f.nextSibling instanceof HTMLElement&&u.nextSibling instanceof HTMLElement&&(u.nextSibling.hasAttribute("data-line-annotation")||u.nextSibling.hasAttribute("data-merge-conflict-actions"))&&(r?(b="last",u.setAttribute("data-selected-line","first")):g===o?b="":g===s&&u.setAttribute("data-selected-line",""),u.nextSibling.setAttribute("data-selected-line",b),f.nextSibling.setAttribute("data-selected-line",b))}}};notifySelectionCommitted(){this.options.onLineSelected?.(this.getCurrentSelectionRange()??null)}notifySelectionChangeDelta(){this.options.onLineSelectionChange?.(this.getCurrentSelectionRange()??null)}notifySelectionStart(e){this.options.onLineSelectionStart?.(e)}notifySelectionEnd(e){this.options.onLineSelectionEnd?.(e)}toEventBaseProps(e){return this.mode==="file"?{type:"line",lineElement:e.lineElement,lineNumber:e.lineNumber,numberColumn:e.numberColumn,numberElement:e.numberElement}:{type:"diff-line",annotationSide:e.side,lineType:e.lineType,lineElement:e.lineElement,numberElement:e.numberElement,lineNumber:e.lineNumber,numberColumn:e.numberColumn}}toTokenEventBaseProps({lineCharEnd:e,lineCharStart:t,lineNumber:n,side:i,tokenElement:r,tokenText:o}){return this.mode==="file"?{type:"token",lineCharEnd:e,lineCharStart:t,lineNumber:n,tokenElement:r,tokenText:o}:{type:"token",lineCharEnd:e,lineCharStart:t,lineNumber:n,side:i,tokenElement:r,tokenText:o}}buildSelectedLineRange(e,t){return this.buildSelectionRange(e.lineNumber,t.lineNumber,e.side,t.side)}buildSelectionRange(e,t,n,i){return{start:e,end:t,...n!=null?{side:n}:{},...n!==i&&i!=null?{endSide:i}:{}}}resolvePointerTarget(e){let t=!1,n,i,r,o,s,l,a,d,h,c;for(const f of e){if(!(f instanceof HTMLElement))continue;if(c==null&&f.hasAttribute("data-merge-conflict-action")){const m=f.getAttribute("data-merge-conflict-action")??void 0,p=f.getAttribute("data-merge-conflict-conflict-index")??void 0,C=p!=null?Number.parseInt(p,10):NaN;uo(m)&&Number.isFinite(C)&&(c={kind:"merge-conflict-action",resolution:m,conflictIndex:C})}if(l==null&&f.hasAttribute("data-char")){l=f;const m=f.getAttribute("data-char");if(m!=null){const p=Number.parseInt(m,10);if(!Number.isNaN(p)){const C=f.textContent??"",v=p+C.length;(C.trim()!==""||this.options.enableTokenInteractionsOnWhitespace===!0)&&(a={tokenElement:l,lineCharStart:p,lineCharEnd:v,tokenText:C});continue}}}const g=s==null?f.getAttribute("data-column-number")??void 0:void 0;if(g!=null){s=f,h=Number.parseInt(g,10),t=!0,n=In(f),o=f.getAttribute("data-line-index")??void 0;continue}const b=r==null?f.getAttribute("data-line")??void 0:void 0;if(b!=null){r=f,h=Number.parseInt(b,10),n=In(f),o=f.getAttribute("data-line-index")??void 0;continue}if(d==null&&(f.hasAttribute("data-expand-button")||f.hasAttribute("data-unmodified-lines"))){d={hunkIndex:void 0,direction:f.hasAttribute("data-expand-up")?"up":f.hasAttribute("data-expand-down")?"down":"both",all:f.hasAttribute("data-expand-all-button")};continue}const y=d!=null?f.getAttribute("data-expand-index")??void 0:void 0;if(d!=null&&y!=null){const m=Number.parseInt(y,10);Number.isNaN(m)||(d.hunkIndex=m);continue}if(i==null&&f.hasAttribute("data-code")){i=f;break}}if(c!=null)return c;if(d?.hunkIndex!=null)return{type:"line-info",hunkIndex:d.hunkIndex,direction:d.direction,all:d.all};if(r??=o!=null?wn(i,`[data-line][data-line-index="${o}"]`):void 0,s??=o!=null?wn(i,`[data-column-number][data-line-index="${o}"]`):void 0,i==null||r==null||s==null||n==null||h==null||Number.isNaN(h))return;const u=this.parseLineIndex(r,this.isSplitDiff());return a!=null?this.mode==="file"?{kind:"token",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:void 0,splitLineIndex:u,...a}:{kind:"token",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:Tn(n,i),splitLineIndex:u,...a}:this.mode==="file"?{kind:"line",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:void 0,splitLineIndex:u}:{kind:"line",lineType:n,lineElement:r,lineNumber:h,numberColumn:t,numberElement:s,side:Tn(n,i),splitLineIndex:u}}isSplitDiff(){return this.pre?.getAttribute("data-diff-type")==="split"}parseLineIndex(e,t){const n=(e.getAttribute("data-line-index")??"").split(",").map(i=>Number.parseInt(i,10)).filter(i=>!Number.isNaN(i));if(t&&n.length===2)return n[1];if(!t)return n[0]}};function Ke({enableTokenInteractionsOnWhitespace:e,enableGutterUtility:t,lineHoverHighlight:n,onGutterUtilityClick:i,onLineClick:r,onLineEnter:o,onLineLeave:s,onLineNumberClick:l,onTokenClick:a,onTokenEnter:d,onTokenLeave:h,renderGutterUtility:c,__debugPointerEvents:u,enableLineSelection:f,controlledSelection:g,onLineSelected:b,onLineSelectionStart:y,onLineSelectionChange:m,onLineSelectionEnd:p},C,v,x){return{enableTokenInteractionsOnWhitespace:e,enableGutterUtility:lo({enableGutterUtility:t,renderGutterUtility:c,onGutterUtilityClick:i}),usesCustomGutterUtility:c!=null,lineHoverHighlight:n,onGutterUtilityClick:i,onHunkExpand:C,onMergeConflictActionClick:x,onLineClick:r,onLineEnter:o,onLineLeave:s,onLineNumberClick:l,onTokenClick:a,onTokenEnter:d,onTokenLeave:h,__debugPointerEvents:u,enableLineSelection:f,controlledSelection:g,onLineSelected:b,onLineSelectionStart:y,onLineSelectionChange:m,onLineSelectionEnd:p,getLineIndex:v}}function lo({enableGutterUtility:e,renderGutterUtility:t,onGutterUtilityClick:n}){if(n!=null&&t!=null)throw new Error("Cannot use both 'onGutterUtilityClick' and 'renderGutterUtility'. Use only one gutter utility API.");return e??!1}function Ve(e){return e!=null&&"kind"in e&&e.kind==="line"}function ut(e){return e!=null&&"kind"in e&&e.kind==="token"}function Tt(e){return Ve(e)||ut(e)}function ho(e){return"type"in e&&e.type==="line-info"}function co(e){return"kind"in e&&e.kind==="merge-conflict-action"}function uo(e){return e==="current"||e==="incoming"||e==="both"}function wn(e,t){const n=e?.querySelector(t);return n instanceof HTMLElement?n:void 0}function Ze(e){const t=[];let n=e;for(;n!=null;)t.push(n),n=n.parentNode;return t}function fo(e){const t=e.closest("[data-line], [data-column-number]");if(t instanceof HTMLElement)return t;const n=e.closest('[data-line-annotation], [data-gutter-buffer="annotation"]');if(!(n instanceof HTMLElement))return;const i=n.previousElementSibling;return i instanceof HTMLElement&&(i.hasAttribute("data-line")||i.hasAttribute("data-column-number"))?i:void 0}function po(e){const t=e.closest('[slot^="annotation-"]');if(t instanceof HTMLElement)return t.getAttribute("slot")??void 0;if(e instanceof HTMLElement){const n=e.getAttribute("name")??void 0;return n!=null&&n.startsWith("annotation-")?n:void 0}}function go(e){if(e==null)return;const t=/^annotation-(?:(additions|deletions)-)?(\d+)$/.exec(e);if(t==null)return;const n=Number.parseInt(t[2],10);if(!(!Number.isFinite(n)||n<=0))return{lineNumber:n,side:t[1]}}function En(e){return e!=null&&typeof e.elementFromPoint=="function"}function Tn(e,t){switch(e){case"change-deletion":return"deletions";case"change-addition":return"additions";default:return t.hasAttribute("data-deletions")?"deletions":"additions"}}function In(e){const t=e.getAttribute("data-line-type");if(t!=null)switch(t){case"change-deletion":case"change-addition":case"context":case"context-expanded":return t;default:return}}function et(e){for(const t of e)if(t instanceof HTMLElement&&(t.hasAttribute("data-utility-button")||t.hasAttribute("data-gutter-utility-slot")||t.getAttribute("slot")==="gutter-utility-slot"||t.getAttribute("name")==="gutter-utility-slot"))return!0;return!1}function he(e="none",t,...n){switch(e){case"none":return;case"both":break;case"click":if(t!=="click")return;break;case"move":if(t!=="move")return;break}console.log(...n)}var _i=class ue{static resizeObserver;static managersByElement=new Map;static getResizeObserver(){const t=ue.resizeObserver??new ResizeObserver(ue.handleSharedResizeEntries);return ue.resizeObserver=t,t}static handleSharedResizeEntries(t){const n=new Map;for(const i of t){const r=ue.managersByElement.get(i.target);if(r==null)continue;const o=n.get(r);o==null?n.set(r,[i]):o.push(i)}for(const[i,r]of n)i.handleResizeEntries(r)}observedNodes=new Map;setup(t,n){const i=new Set;let r=0;const o=new Map(this.observedNodes);this.observedNodes.clear();for(const s of t.children){if(r===2)break;const l=(()=>{if(s instanceof HTMLElement&&s.tagName==="CODE")return s})();if(l==null)continue;r++;let a=o.get(l);if(a!=null&&a.type!=="code")throw new Error("ResizeManager.setup: somehow a code node is being used for an annotation, should be impossible");let d=l.firstElementChild;d instanceof HTMLElement||(d=null),a!=null?(this.observedNodes.set(l,a),o.delete(l),a.numberElement!==d?(a.numberElement!=null&&(this.unobserve(a.numberElement),o.delete(a.numberElement)),d!=null&&(this.observe(d),o.delete(d),this.observedNodes.set(d,a)),a.numberElement=d,a.numberWidth=0):a.numberElement!=null?(o.delete(a.numberElement),this.observedNodes.set(a.numberElement,a)):a.numberWidth=0):(a={type:"code",codeElement:l,numberElement:d,codeWidth:"auto",numberWidth:0},this.observedNodes.set(l,a),this.observe(l),d!=null&&(this.observedNodes.set(d,a),this.observe(d)))}if(r>1&&!n){const s=t.querySelectorAll('[data-line-annotation*=","]'),l=new Map;for(const a of s){if(!(a instanceof HTMLElement))continue;const d=a.getAttribute("data-line-annotation")??"";if(!/^-?\d+,-?\d+$/.test(d)){console.error("DiffFileRenderer.setupResizeObserver: Invalid element or annotation",{lineAnnotation:d,element:a});continue}let h=l.get(d);h==null&&(h=[],l.set(d,h)),h.push(a)}for(const[a,d]of l){if(d.length!==2){console.error("DiffFileRenderer.setupResizeObserver: Bad Pair",a,d);continue}const[h,c]=d,u=h.firstElementChild,f=c.firstElementChild;if(!(h instanceof HTMLElement)||!(c instanceof HTMLElement)||!(u instanceof HTMLElement)||!(f instanceof HTMLElement))continue;let g=o.get(u);if(g!=null){this.observedNodes.set(u,g),this.observedNodes.set(f,g),o.delete(u),o.delete(f);continue}const b=u.getBoundingClientRect().height,y=f.getBoundingClientRect().height;g={type:"annotations",column1:{container:h,child:u,childHeight:b},column2:{container:c,child:f,childHeight:y},currentHeight:"auto"},i.add({child1:u,child2:f,item:g,newHeight:Math.max(b,y)})}for(const a of i)this.applyNewHeight(a.item,a.newHeight),this.observedNodes.set(a.child1,a.item),this.observedNodes.set(a.child2,a.item),this.observe(a.child1),this.observe(a.child2);i.clear()}for(const[s,l]of o)this.unobserve(s),l.type==="code"?bo(l):Co(l);o.clear()}cleanUp(){for(const t of this.observedNodes.keys())this.unobserve(t);this.observedNodes.clear()}observe(t){const{managersByElement:n}=ue,i=n.get(t);if(i!==this){if(i!=null&&i!==this)throw new Error("ResizeManager.observe: element is already owned by another ResizeManager");n.set(t,this),ue.getResizeObserver().observe(t)}}unobserve(t){const{managersByElement:n,resizeObserver:i}=ue,r=n.get(t);if(r!=null){if(r!==this)throw new Error("ResizeManager.unobserve: element is owned by another ResizeManager");n.delete(t),i?.unobserve(t),i!=null&&n.size===0&&(i.disconnect(),ue.resizeObserver=void 0)}}handleResizeEntries(t){const n=new Map,i=new Set;for(const r of t){const{target:o,borderBoxSize:s,contentBoxSize:l}=r;if(!(o instanceof HTMLElement)){console.error("ResizeManager.handleResizeEntries: Invalid element for ResizeObserver",r);continue}const a=this.observedNodes.get(o);if(a==null){console.error("ResizeManager.handleResizeEntries: Not a valid observed node",r);continue}if(a.type==="annotations"){const d=(()=>{if(o===a.column1.child)return a.column1;if(o===a.column2.child)return a.column2})();if(d==null){console.error("ResizeManager.handleResizeEntries: Couldn't find a column for",{item:a,target:o});continue}d.childHeight=s[0].blockSize,i.add(a)}else if(a.type==="code"){const d=n.get(a)??{},h=l[0].inlineSize;o===a.codeElement?d.codeInlineSize=h:o===a.numberElement&&(d.numberInlineSize=h),n.set(a,d)}}this.applyAnnotationUpdates(i),i.clear(),this.applyColumnUpdates(n),n.clear()}applyAnnotationUpdates(t){for(const n of t)this.applyNewHeight(n,Math.max(n.column1.childHeight,n.column2.childHeight))}applyColumnUpdates=t=>{for(const[n,i]of t){const r=i.codeInlineSize!=null?mo(i.codeInlineSize):n.codeWidth,o=i.numberInlineSize!=null?vo(i.numberInlineSize):n.numberWidth,s=r!==n.codeWidth,l=o!==n.numberWidth;if(!(!s&&!l)&&(n.codeWidth=r,n.numberWidth=o,s&&n.codeElement.style.setProperty("--diffs-column-width",`${typeof r=="number"?`${r}px`:"auto"}`),l&&n.codeElement.style.setProperty("--diffs-column-number-width",`${o===0?"auto":`${o}px`}`),s||l&&r!=="auto")){const a=typeof r=="number"?Math.max(r-o,0):0;n.codeElement.style.setProperty("--diffs-column-content-width",`${a>0?`${a}px`:"auto"}`)}}};applyNewHeight(t,n){n!==t.currentHeight&&(t.currentHeight=Math.max(n,0),t.column1.container.style.setProperty("--diffs-annotation-min-height",`${t.currentHeight}px`),t.column2.container.style.setProperty("--diffs-annotation-min-height",`${t.currentHeight}px`))}};function mo(e){const t=Math.max(Math.floor(e),0);return t===0?"auto":t}function vo(e){return Math.max(Math.ceil(e),0)}function bo(e){e.codeElement.isConnected&&(e.codeElement.style.removeProperty("--diffs-column-content-width"),e.codeElement.style.removeProperty("--diffs-column-number-width"),e.codeElement.style.removeProperty("--diffs-column-width"))}function Co(e){e.column1.container.isConnected&&e.column1.container.style.removeProperty("--diffs-annotation-min-height"),e.column2.container.isConnected&&e.column2.container.style.removeProperty("--diffs-annotation-min-height")}const Se=new Map,It=new Map,jt=new Map,gt=new Set;function mt(e){for(const t of Array.isArray(e)?e:[e])if(!(t==="text"||t==="ansi")&&!gt.has(t))return!1;return!0}function Rn(e,t){e=Array.isArray(e)?e:[e];for(const n of e){if(gt.has(n.name))continue;let i=Se.get(n.name);i==null&&(i=n,Se.set(n.name,i)),gt.add(i.name),t.loadLanguageSync(i.data)}}function So(){Se.clear(),gt.clear()}function Oi(){return typeof WorkerGlobalScope<"u"&&typeof self<"u"&&self instanceof WorkerGlobalScope}async function Ni(e){if(Oi())throw new Error(`resolveLanguage("${e}") cannot be called from a worker context. Languages must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);const t=It.get(e);if(t!=null)return t;try{let n=jt.get(e);if(n==null&&Object.prototype.hasOwnProperty.call(Ln,e)&&(n=Ln[e]),n==null)throw new Error(`resolveLanguage: "${e}" not found in bundled or custom languages`);const i=n().then(({default:r})=>{const o={name:e,data:r};return Se.has(e)||Se.set(e,o),o});return It.set(e,i),await i}finally{It.delete(e)}}function Fi(e){return Se.get(e)??Ni(e)}const vt=new Set;function Ye(e){const t=[],n=new Set;for(const c of yo(e.themes)){const u=zi(c)?c.getThemes():[c];for(const f of u){if(n.has(f.name))throw new Error(`Theme collection already contains theme "${f.name}"`);n.add(f.name),t.push(f)}}const i=Object.freeze([...t]),r=Object.freeze(i.filter(c=>c.colorScheme==="light")),o=Object.freeze(i.filter(c=>c.colorScheme==="dark")),s=new Map(i.map(c=>[c.name,c])),l=Object.freeze(i.map(c=>c.name)),a=Object.freeze(r.map(c=>c.name)),d=Object.freeze(o.map(c=>c.name));function h(c){if(c==null)return i;const{colorScheme:u,collection:f}=c;return f==null?u==="light"?r:u==="dark"?o:i:i.filter(g=>g.collection!==f?!1:u==null||g.colorScheme===u)}return{getTheme(c){return s.get(c)},getThemes(c){return h(c)},getThemeNames(c){return c?.collection==null?c?.colorScheme==="light"?a:c?.colorScheme==="dark"?d:l:h(c).map(u=>u.name)},hasTheme(c){return s.has(c)},orderBy(c){return Ye({themes:i.map((u,f)=>({descriptor:u,index:f})).sort((u,f)=>{const g=c(u.descriptor,f.descriptor);return g!==0?g:u.index-f.index}).map(u=>u.descriptor)})},pick(c){const u=[],f=new Set;for(const g of c){if(f.has(g))throw new Error(`Theme collection pick already includes theme "${g}"`);f.add(g);const b=s.get(g);if(b==null)throw new Error(`Theme collection does not contain theme "${g}"`);u.push(b)}return Ye({themes:u})},registerInto(c){for(const u of i)c.registerThemeIfAbsent(u.name,u.load)}}}function yo(e){return xo(e)?[e]:e}function xo(e){return zi(e)||Lo(e)}function Lo(e){return typeof e.name=="string"&&typeof e.load=="function"}function zi(e){return typeof e.getThemes=="function"}function Ui(e){return e!==null&&typeof e=="object"&&"default"in e?e.default:e}var Vi=class extends Error{constructor(e){super(`Theme "${e}" is already registered`),this.name="DuplicateThemeError"}},ko=class extends Error{constructor(e){super(`No loader registered for theme "${e}"`),this.name="UnregisteredThemeError"}},wo=class extends Error{constructor(e){super(`Theme "${e}" has not been resolved`),this.name="UnresolvedThemeError"}};function Eo(){const e=new Map,t=new Map,n=new Map;let i=0;function r(m,p){if(e.has(m))throw new Vi(m);e.set(m,p)}function o(m,p){return e.has(m)?!1:(e.set(m,p),!0)}function s(m){return e.has(m)}function l(m){const p=t.get(m);if(p!==void 0)return Promise.resolve(p);const C=n.get(m);if(C!==void 0)return C;const v=e.get(m);if(v===void 0)return Promise.reject(new ko(m));const x=i,S=v().then(L=>{const E=Ui(L);return x===i&&t.set(m,E),n.get(m)===S&&n.delete(m),E}).catch(L=>{throw n.get(m)===S&&n.delete(m),L});return n.set(m,S),S}function a(m){return Promise.all(m.map(p=>l(p)))}function d(m,p){t.set(m,p)}function h(m){for(const[p,C]of m)d(p,C)}function c(m){return t.get(m)}function u(m){const p=[];for(const C of m){const v=t.get(C);if(v===void 0)throw new wo(C);p.push(v)}return p}function f(m){return t.has(m)}function g(m){for(const p of m)if(!t.has(p))return!1;return!0}function b(m){const p=t.get(m);return p!==void 0?p:l(m)}function y(){i++,t.clear(),n.clear()}return{clearResolvedThemes:y,getResolvedOrResolveTheme:b,getResolvedTheme:c,getResolvedThemes:u,hasRegisteredTheme:s,hasResolvedTheme:f,hasResolvedThemes:g,registerTheme:r,registerThemeIfAbsent:o,resolveTheme:l,resolveThemes:a,seedResolvedTheme:d,seedResolvedThemes:h}}const X=Eo();function An(e,t){e=Array.isArray(e)?e:[e];for(let n of e){let i;if(typeof n=="string"){if(i=X.getResolvedTheme(n),i==null)throw new Error(`loadResolvedThemes: ${n} is not resolved, you must resolve it before calling loadResolvedThemes`)}else i=n,n=n.name,X.getResolvedTheme(n)==null&&X.seedResolvedTheme(n,i);vt.has(n)||(vt.add(n),t.loadThemeSync(i))}}function To(){X.clearResolvedThemes(),vt.clear()}function hn({name:e,load:t,colorScheme:n,collection:i,displayName:r}){return{name:e,colorScheme:n,collection:i,displayName:r,load:Io(t)}}function Io(e){return async()=>Or(Ui(await e()))}const Ro="pierre",Ao=["pierre-dark","pierre-dark-soft","pierre-dark-vibrant","pierre-dark-protanopia-deuteranopia","pierre-dark-tritanopia"],Bi=["pierre-light","pierre-light-soft","pierre-light-vibrant","pierre-light-protanopia-deuteranopia","pierre-light-tritanopia"],Ho=[...Bi,...Ao],Mo=new Set(Bi);function Do(e){return Mo.has(e)?"light":"dark"}const Po={"pierre-dark":"Pierre Dark","pierre-dark-soft":"Pierre Dark Soft","pierre-dark-vibrant":"Pierre Dark Vibrant","pierre-dark-protanopia-deuteranopia":"Pierre Dark Protanopia & Deuteranopia","pierre-dark-tritanopia":"Pierre Dark Tritanopia","pierre-light":"Pierre Light","pierre-light-soft":"Pierre Light Soft","pierre-light-vibrant":"Pierre Light Vibrant","pierre-light-protanopia-deuteranopia":"Pierre Light Protanopia & Deuteranopia","pierre-light-tritanopia":"Pierre Light Tritanopia"},_o={"pierre-dark":()=>k(()=>import("./pierre-dark-CyvmCCZW.js"),[]),"pierre-dark-soft":()=>k(()=>import("./pierre-dark-soft-BHGpRqa4.js"),[]),"pierre-dark-vibrant":()=>k(()=>import("./pierre-dark-vibrant-BWBVywrn.js"),[]),"pierre-dark-protanopia-deuteranopia":()=>k(()=>import("./pierre-dark-protanopia-deuteranopia-Rgc0TwpF.js"),[]),"pierre-dark-tritanopia":()=>k(()=>import("./pierre-dark-tritanopia-Beq2gCRQ.js"),[]),"pierre-light":()=>k(()=>import("./pierre-light-480U9XYS.js"),[]),"pierre-light-soft":()=>k(()=>import("./pierre-light-soft-CVdyfjmI.js"),[]),"pierre-light-vibrant":()=>k(()=>import("./pierre-light-vibrant-DdTDNdfJ.js"),[]),"pierre-light-protanopia-deuteranopia":()=>k(()=>import("./pierre-light-protanopia-deuteranopia-CaVOBURG.js"),[]),"pierre-light-tritanopia":()=>k(()=>import("./pierre-light-tritanopia-B4_gpKOM.js"),[])};function Oo(e){return hn({name:e,collection:Ro,colorScheme:Do(e),displayName:Po[e],load:_o[e]})}const $i=Ye({themes:Ho.map(e=>Oo(e))}),No="shiki",Wi=["ayu-light","catppuccin-latte","everforest-light","github-light","github-light-default","github-light-high-contrast","gruvbox-light-hard","gruvbox-light-medium","gruvbox-light-soft","horizon-bright","kanagawa-lotus","light-plus","material-theme-lighter","min-light","night-owl-light","one-light","rose-pine-dawn","slack-ochin","snazzy-light","solarized-light","vitesse-light"],Fo=["andromeeda","aurora-x","ayu-dark","ayu-mirage","catppuccin-frappe","catppuccin-macchiato","catppuccin-mocha","dark-plus","dracula","dracula-soft","everforest-dark","github-dark","github-dark-default","github-dark-dimmed","github-dark-high-contrast","gruvbox-dark-hard","gruvbox-dark-medium","gruvbox-dark-soft","horizon","houston","kanagawa-dragon","kanagawa-wave","laserwave","material-theme","material-theme-darker","material-theme-ocean","material-theme-palenight","min-dark","monokai","night-owl","nord","one-dark-pro","plastic","poimandres","red","rose-pine","rose-pine-moon","slack-dark","solarized-dark","synthwave-84","tokyo-night","vesper","vitesse-black","vitesse-dark"],zo=new Set(Wi);function Uo(e){return zo.has(e)?"light":"dark"}const Vo={andromeeda:()=>k(()=>import("./andromeeda-C4gqWexZ.js"),[]),"aurora-x":()=>k(()=>import("./aurora-x-D-2ljcwZ.js"),[]),"ayu-dark":()=>k(()=>import("./ayu-dark-DYE7WIF3.js"),[]),"ayu-light":()=>k(()=>import("./ayu-light-BA47KaF1.js"),[]),"ayu-mirage":()=>k(()=>import("./ayu-mirage-32ctXXKs.js"),[]),"catppuccin-frappe":()=>k(()=>import("./catppuccin-frappe-DFWUc33u.js"),[]),"catppuccin-latte":()=>k(()=>import("./catppuccin-latte-C9dUb6Cb.js"),[]),"catppuccin-macchiato":()=>k(()=>import("./catppuccin-macchiato-DQyhUUbL.js"),[]),"catppuccin-mocha":()=>k(()=>import("./catppuccin-mocha-D87Tk5Gz.js"),[]),"dark-plus":()=>k(()=>import("./dark-plus-C3mMm8J8.js"),[]),dracula:()=>k(()=>import("./dracula-BzJJZx-M.js"),[]),"dracula-soft":()=>k(()=>import("./dracula-soft-BXkSAIEj.js"),[]),"everforest-dark":()=>k(()=>import("./everforest-dark-BgDCqdQA.js"),[]),"everforest-light":()=>k(()=>import("./everforest-light-C8M2exoo.js"),[]),"github-dark":()=>k(()=>import("./github-dark-DHJKELXO.js"),[]),"github-dark-default":()=>k(()=>import("./github-dark-default-Cuk6v7N8.js"),[]),"github-dark-dimmed":()=>k(()=>import("./github-dark-dimmed-DH5Ifo-i.js"),[]),"github-dark-high-contrast":()=>k(()=>import("./github-dark-high-contrast-E3gJ1_iC.js"),[]),"github-light":()=>k(()=>import("./github-light-DAi9KRSo.js"),[]),"github-light-default":()=>k(()=>import("./github-light-default-D7oLnXFd.js"),[]),"github-light-high-contrast":()=>k(()=>import("./github-light-high-contrast-BfjtVDDH.js"),[]),"gruvbox-dark-hard":()=>k(()=>import("./gruvbox-dark-hard-CFHQjOhq.js"),[]),"gruvbox-dark-medium":()=>k(()=>import("./gruvbox-dark-medium-GsRaNv29.js"),[]),"gruvbox-dark-soft":()=>k(()=>import("./gruvbox-dark-soft-CVdnzihN.js"),[]),"gruvbox-light-hard":()=>k(()=>import("./gruvbox-light-hard-CH1njM8p.js"),[]),"gruvbox-light-medium":()=>k(()=>import("./gruvbox-light-medium-DRw_LuNl.js"),[]),"gruvbox-light-soft":()=>k(()=>import("./gruvbox-light-soft-hJgmCMqR.js"),[]),horizon:()=>k(()=>import("./horizon-BUw7H-hv.js"),[]),"horizon-bright":()=>k(()=>import("./horizon-bright-CUuTKBJd.js"),[]),houston:()=>k(()=>import("./houston-DnULxvSX.js"),[]),"kanagawa-dragon":()=>k(()=>import("./kanagawa-dragon-CkXjmgJE.js"),[]),"kanagawa-lotus":()=>k(()=>import("./kanagawa-lotus-CfQXZHmo.js"),[]),"kanagawa-wave":()=>k(()=>import("./kanagawa-wave-DWedfzmr.js"),[]),laserwave:()=>k(()=>import("./laserwave-DUszq2jm.js"),[]),"light-plus":()=>k(()=>import("./light-plus-B7mTdjB0.js"),[]),"material-theme":()=>k(()=>import("./material-theme-D5KoaKCx.js"),[]),"material-theme-darker":()=>k(()=>import("./material-theme-darker-BfHTSMKl.js"),[]),"material-theme-lighter":()=>k(()=>import("./material-theme-lighter-B0m2ddpp.js"),[]),"material-theme-ocean":()=>k(()=>import("./material-theme-ocean-CyktbL80.js"),[]),"material-theme-palenight":()=>k(()=>import("./material-theme-palenight-Csfq5Kiy.js"),[]),"min-dark":()=>k(()=>import("./min-dark-CafNBF8u.js"),[]),"min-light":()=>k(()=>import("./min-light-CTRr51gU.js"),[]),monokai:()=>k(()=>import("./monokai-D4h5O-jR.js"),[]),"night-owl":()=>k(()=>import("./night-owl-C39BiMTA.js"),[]),"night-owl-light":()=>k(()=>import("./night-owl-light-CMTm3GFP.js"),[]),nord:()=>k(()=>import("./nord-Ddv68eIx.js"),[]),"one-dark-pro":()=>k(()=>import("./one-dark-pro-DVMEJ2y_.js"),[]),"one-light":()=>k(()=>import("./one-light-C3Wv6jpd.js"),[]),plastic:()=>k(()=>import("./plastic-3e1v2bzS.js"),[]),poimandres:()=>k(()=>import("./poimandres-CS3Unz2-.js"),[]),red:()=>k(()=>import("./red-bN70gL4F.js"),[]),"rose-pine":()=>k(()=>import("./rose-pine-qdsjHGoJ.js"),[]),"rose-pine-dawn":()=>k(()=>import("./rose-pine-dawn-DHQR4-dF.js"),[]),"rose-pine-moon":()=>k(()=>import("./rose-pine-moon-D4_iv3hh.js"),[]),"slack-dark":()=>k(()=>import("./slack-dark-BthQWCQV.js"),[]),"slack-ochin":()=>k(()=>import("./slack-ochin-DqwNpetd.js"),[]),"snazzy-light":()=>k(()=>import("./snazzy-light-Bw305WKR.js"),[]),"solarized-dark":()=>k(()=>import("./solarized-dark-DXbdFlpD.js"),[]),"solarized-light":()=>k(()=>import("./solarized-light-L9t79GZl.js"),[]),"synthwave-84":()=>k(()=>import("./synthwave-84-CbfX1IO0.js"),[]),"tokyo-night":()=>k(()=>import("./tokyo-night-hegEt444.js"),[]),vesper:()=>k(()=>import("./vesper-DRje8inN.js"),[]),"vitesse-black":()=>k(()=>import("./vitesse-black-Bkuqu6BP.js"),[]),"vitesse-dark":()=>k(()=>import("./vitesse-dark-D0r3Knsf.js"),[]),"vitesse-light":()=>k(()=>import("./vitesse-light-CVO1_9PV.js"),[])};function Hn(e){return hn({name:e,collection:No,colorScheme:Uo(e),load:Vo[e]})}const Gi=Ye({themes:Object.freeze([...Wi.map(e=>Hn(e)),...Fo.map(e=>Hn(e))])});Ye({themes:[$i,Gi]});function ji(e){if(Oi())throw new Error(`Theme "${e}" cannot be resolved from a worker context. Themes must be pre-resolved on the main thread and passed to the worker via the resolvedLanguages parameter.`);if(X.hasRegisteredTheme(e))return;const t=Gi.getTheme(e);if(t!=null){X.registerThemeIfAbsent(t.name,t.load);return}throw new Error(`No valid theme loader registered for "${e}"`)}function qi(e,t){if(t.name!==e)throw new Error(`resolvedTheme: themeName: ${e} does not match theme.name: ${t.name}`)}async function Bo(e){ji(e);const t=await X.resolveTheme(e);return qi(e,t),t}function $o(e){return X.getResolvedTheme(e)??Bo(e)}let $;async function xt({themes:e,langs:t,preferredHighlighter:n="shiki-js"}){$??=Nr({themes:[],langs:["text"],engine:n==="shiki-wasm"?Fr(k(()=>import("./wasm-CG6Dc4jp.js"),[])):zr()});const i=Wo($)?await $:$;$=i;const r=[];for(const s of t){if(s==="text"||s==="ansi")continue;const l=Fi(s);"then"in l?r.push(l):Rn(l,i)}const o=[];for(const s of e){const l=$o(s);"then"in l?o.push(l):An(l,$)}return(r.length>0||o.length>0)&&await Promise.all([Promise.all(r).then(s=>{Rn(s,i)}),Promise.all(o).then(s=>{An(s,i)})]),i}function ql(e=$){return e!=null&&!("then"in e)}function Ki(){if($!=null&&!("then"in $))return $}function Wo(e=$){return e!=null&&"then"in e}function Kl(e=$){return e==null}async function Yl(e){await xt(e)}async function Xl(){$!=null&&((await $).dispose(),So(),To(),$=void 0)}for(const e of $i.getThemes())X.registerThemeIfAbsent(e.name,e.load);function cn(e=_){const t=[];return typeof e=="string"?t.push(e):(t.push(e.dark),t.push(e.light)),t}function Ge(e){for(const t of cn(e))if(!vt.has(t))return!1;return!0}function Go(e){return X.hasResolvedThemes(e)}function Oe(e,t){return De(e.theme,t.theme)&&e.useTokenTransformer===t.useTokenTransformer&&e.tokenizeMaxLineLength===t.tokenizeMaxLineLength}function ae(e,t){return e?.cacheKey===t?.cacheKey&&e?.contents===t?.contents&&e?.name===t?.name&&e?.lang===t?.lang}function Lt(e,t){return e==null||t==null?e===t:e.startingLine===t.startingLine&&e.totalLines===t.totalLines&&e.bufferBefore===t.bufferBefore&&e.bufferAfter===t.bufferAfter}function qt(e){return A({tagName:"div",children:[A({tagName:"div",children:e.annotations?.map(t=>A({tagName:"slot",properties:{name:t}})),properties:{"data-annotation-content":""}})],properties:{"data-line-annotation":`${e.hunkIndex},${e.lineIndex}`}})}function jo(e){switch(e){case"file":return"diffs-icon-file-code";case"change":return"diffs-icon-symbol-modified";case"new":return"diffs-icon-symbol-added";case"deleted":return"diffs-icon-symbol-deleted";case"rename-pure":case"rename-changed":return"diffs-icon-symbol-moved"}}function Yi({fileOrDiff:e,mode:t,stickyHeader:n}){const i="type"in e?e:void 0,r={"data-diffs-header":t,"data-change-type":i?.type,"data-sticky":n?"":void 0};return A({tagName:"div",children:[t==="custom"?A({tagName:"slot",properties:{name:an}}):qo({name:e.name,prevName:"prevName"in e?e.prevName:void 0,iconType:i?.type??"file"}),...t==="custom"?[]:[Ko(i)]],properties:r})}function qo({name:e,prevName:t,iconType:n}){const i=[A({tagName:"slot",properties:{name:on}}),pt({name:jo(n),properties:{"data-change-icon":n}})];return t!=null&&(i.push(A({tagName:"div",children:[A({tagName:"bdi",children:[W(t)]})],properties:{"data-prev-name":""}})),i.push(pt({name:"diffs-icon-arrow-right-short",properties:{"data-rename-icon":""}}))),i.push(A({tagName:"div",children:[A({tagName:"bdi",children:[W(e)]})],properties:{"data-title":""}})),A({tagName:"div",children:i,properties:{"data-header-content":""}})}function Ko(e){const t=[];if(e!=null){let n=0,i=0;for(const r of e.hunks)n+=r.additionLines,i+=r.deletionLines;(i>0||n===0)&&t.push(A({tagName:"span",children:[W(`-${i}`)],properties:{"data-deletions-count":""}})),(n>0||i===0)&&t.push(A({tagName:"span",children:[W(`+${n}`)],properties:{"data-additions-count":""}}))}return t.push(A({tagName:"slot",properties:{name:sn}})),A({tagName:"div",children:t,properties:{"data-metadata":""}})}function Xi(e){return A({tagName:"pre",properties:Yo(e)})}function Yo({diffIndicators:e,disableBackground:t,disableLineNumbers:n,overflow:i,split:r,totalLines:o,type:s,customProperties:l}){return{...l,"data-diff":s==="diff"?"":void 0,"data-file":s==="file"?"":void 0,"data-diff-type":s==="diff"?r?"split":"single":void 0,"data-overflow":i,"data-disable-line-numbers":n?"":void 0,"data-background":t?void 0:"","data-indicators":e==="bars"||e==="classic"?e:void 0,style:`--diffs-min-number-column-width-default:${`${o}`.length}ch;`}}const Z=new Map;let bt=0;const Ne={"1c":"1c",abap:"abap",as:"actionscript-3",ada:"ada",adb:"ada",ads:"ada",adoc:"asciidoc",asciidoc:"asciidoc","component.html":"angular-html","component.ts":"angular-ts",conf:"nginx",htaccess:"apache",cls:"tex",trigger:"apex",apl:"apl",applescript:"applescript",scpt:"applescript",ara:"ara",asm:"asm",s:"riscv",astro:"astro",awk:"awk",bal:"ballerina",sh:"zsh",bash:"zsh",bat:"cmd",cmd:"cmd",be:"berry",beancount:"beancount",bib:"bibtex",bicep:"bicep","blade.php":"blade",bsl:"bsl",c:"c",h:"objective-cpp",cs:"csharp",cpp:"cpp",hpp:"cpp",cc:"cpp",cxx:"cpp",hh:"cpp",cdc:"cdc",cairo:"cairo",clar:"clarity",clj:"clojure",cljs:"clojure",cljc:"clojure",soy:"soy",cmake:"cmake","CMakeLists.txt":"cmake",cob:"cobol",cbl:"cobol",cobol:"cobol",CODEOWNERS:"codeowners",ql:"ql",coffee:"coffeescript",lisp:"lisp",cl:"lisp",lsp:"lisp",log:"log",v:"verilog",cql:"cql",cr:"crystal",css:"css",csv:"csv",cue:"cue",cypher:"cypher",cyp:"cypher",d:"d",dart:"dart",dax:"dax",desktop:"desktop",diff:"diff",patch:"diff",Dockerfile:"dockerfile",dockerfile:"dockerfile",env:"dotenv",dm:"dream-maker",edge:"edge",el:"emacs-lisp",ex:"elixir",exs:"elixir",elm:"elm",erb:"erb",erl:"erlang",hrl:"erlang",f:"fortran-fixed-form",for:"fortran-fixed-form",fs:"fsharp",fsi:"fsharp",fsx:"fsharp",f03:"f03",f08:"f08",f18:"f18",f77:"f77",f90:"fortran-free-form",f95:"fortran-free-form",fnl:"fennel",fish:"fish",ftl:"ftl",tres:"gdresource",res:"gdresource",gd:"gdscript",gdshader:"gdshader",gs:"genie",feature:"gherkin",COMMIT_EDITMSG:"git-commit","git-rebase-todo":"git-rebase",gjs:"glimmer-js",gleam:"gleam",gts:"glimmer-ts",glsl:"glsl",vert:"glsl",frag:"glsl",shader:"shaderlab",gp:"gnuplot",plt:"gnuplot",gnuplot:"gnuplot",go:"go",graphql:"graphql",gql:"graphql",groovy:"groovy",gvy:"groovy",hack:"hack",haml:"haml",hbs:"handlebars",handlebars:"handlebars",hs:"haskell",lhs:"haskell",hx:"haxe",hcl:"hcl",hjson:"hjson",hlsl:"hlsl",fx:"hlsl",html:"html",htm:"html",http:"http",rest:"http",hxml:"hxml",hy:"hy",imba:"imba",ini:"ini",cfg:"ini",jade:"pug",pug:"pug",java:"java",js:"javascript",mjs:"javascript",cjs:"javascript",jinja:"jinja",jinja2:"jinja",j2:"jinja",jison:"jison",jl:"julia",json:"json",json5:"json5",jsonc:"jsonc",jsonl:"jsonl",jsonnet:"jsonnet",libsonnet:"jsonnet",jssm:"jssm",jsx:"jsx",kt:"kotlin",kts:"kts",kql:"kusto",tex:"tex",ltx:"tex",lean:"lean4",less:"less",liquid:"liquid",lit:"lit",ll:"llvm",logo:"logo",lua:"lua",luau:"luau",Makefile:"makefile",mk:"makefile",makefile:"makefile",md:"markdown",markdown:"markdown",marko:"marko",m:"wolfram",mat:"matlab",mdc:"mdc",mdx:"mdx",wiki:"wikitext",mediawiki:"wikitext",mmd:"mermaid",mermaid:"mermaid",mips:"mipsasm",mojo:"mojo","🔥":"mojo",move:"move",nar:"narrat",nf:"nextflow",nim:"nim",nims:"nim",nimble:"nim",nix:"nix",nu:"nushell",mm:"objective-cpp",ml:"ocaml",mli:"ocaml",mll:"ocaml",mly:"ocaml",pas:"pascal",p:"pascal",pl:"prolog",pm:"perl",t:"perl",raku:"raku",p6:"raku",pl6:"raku",php:"php",phtml:"php",pls:"plsql",sql:"sql",po:"po",polar:"polar",pcss:"postcss",pot:"pot",potx:"potx",pq:"powerquery",pqm:"powerquery",ps1:"powershell",psm1:"powershell",psd1:"powershell",prisma:"prisma",pro:"prolog",P:"prolog",properties:"properties",proto:"protobuf",pp:"puppet",purs:"purescript",py:"python",pyw:"python",pyi:"python",qml:"qml",qmldir:"qmldir",qss:"qss",r:"r",R:"r",rkt:"racket",rktl:"racket",razor:"razor",cshtml:"razor",rb:"ruby",rbw:"ruby",reg:"reg",regex:"regexp",rel:"rel",rs:"rust",rst:"rst",rake:"ruby",gemspec:"ruby",jbuilder:"ruby",builder:"ruby",rabl:"ruby",arb:"ruby",ru:"ruby",podspec:"ruby",Gemfile:"ruby",Rakefile:"ruby",Guardfile:"ruby",Capfile:"ruby",Berksfile:"ruby",Brewfile:"ruby",Vagrantfile:"ruby",Thorfile:"ruby",Appraisals:"ruby",Dangerfile:"ruby",sas:"sas",sass:"sass",scala:"scala",sc:"scala",scm:"scheme",ss:"scheme",sld:"scheme",scss:"scss",sdbl:"sdbl",shadergraph:"shader",st:"smalltalk",sol:"solidity",sparql:"sparql",rq:"sparql",spl:"splunk",config:"ssh-config",do:"stata",ado:"stata",dta:"stata",styl:"stylus",stylus:"stylus",svelte:"svelte",swift:"swift",sv:"system-verilog",svh:"system-verilog",service:"systemd",socket:"systemd",device:"systemd",timer:"systemd",talon:"talonscript",tasl:"tasl",tcl:"tcl",templ:"templ",tf:"tf",tfvars:"tfvars",toml:"toml",ts:"typescript",tsp:"typespec",tsv:"tsv",tsx:"tsx",ttl:"turtle",twig:"twig",typ:"typst",vv:"v",vala:"vala",vapi:"vala",vb:"vb",vbs:"vb",bas:"vb",vh:"verilog",vhd:"vhdl",vhdl:"vhdl",vim:"vimscript",vue:"vue","vine.ts":"vue-vine",vy:"vyper",wasm:"wasm",wat:"wasm",wy:"文言",wgsl:"wgsl",wit:"wit",wl:"wolfram",nb:"wolfram",xml:"xml",xsl:"xsl",xslt:"xsl",yaml:"yaml",yml:"yml",zs:"zenscript",zig:"zig",zsh:"zsh",sty:"tex"};function Q(e){if(Z.has(e))return Z.get(e)??"text";if(Ne[e]!=null)return Ne[e];const t=e.match(/\.([^/\\]+\.[^/\\]+)$/);if(t!=null){if(Z.has(t[1]))return Z.get(t[1])??"text";if(Ne[t[1]]!=null)return Ne[t[1]]??"text"}const n=e.match(/\.([^.]+)$/)?.[1]??"";return Z.has(n)?Z.get(n)??"text":Ne[n]??"text"}function Ql(e,t){if(e<=bt)return!1;Z.clear();for(const n in t){const i=t[n];i!=null&&Z.set(n,i)}return bt=e,!0}function Jl(){return bt}function Xo(e,t){const n=Z.get(e);return n===t?!1:(n!=null&&console.warn(`setCustomExtension: overriding custom mapping for "${e}" from "${n}" to "${t}"`),Z.set(e,t),bt++,!0)}function Zl(){return Object.fromEntries(Z)}function un(e,{theme:t,preferredHighlighter:n="shiki-js"}){return{langs:[e??"text"],themes:cn(t),preferredHighlighter:n}}function ge(e){return`annotation-${"side"in e?`${e.side}-`:""}${e.lineNumber}`}function xe(e){return e.replace(/\n$|\r\n$/,"")}function Qo(e,t,n){const i=typeof n.lineInfo=="function"?n.lineInfo(t):n.lineInfo[t-1];if(i==null){const r=`processLine: line ${t}, contains no state.lineInfo`;throw console.error(r,{node:e,line:t,state:n}),new Error(r)}return e.tagName="div",e.properties["data-line"]=i.lineNumber,e.properties["data-alt-line"]=i.altLineNumber,e.properties["data-line-type"]=i.type,e.properties["data-line-index"]=i.lineIndex,e.children.length===0&&e.children.push(W(` `)),e}const tt=Symbol("no-token"),Rt=Symbol("multiple-tokens");function Qi(e){const t=Jo(e);if(t!=null)return t;let n=tt;const i=[];let r=[],o;const s=()=>{if(r.length===0||o==null){r=[],o=void 0;return}if(r.length===1){const a=r[0];if(a?.type==="element"){Zo(a,o);for(const d of a.children)ft(d)}else ft(a);i.push(a),r=[],o=void 0;return}for(const a of r)ft(a);i.push(A({tagName:"span",properties:{"data-char":o},children:r})),r=[],o=void 0},l=a=>{if(a!==tt){if(a===Rt){n=Rt;return}if(n===tt){n=a;return}n!==a&&(n=Rt)}};for(const a of e.children){const d=a.type==="element"?Qi(a):tt;if(l(d),typeof d!="number"){s(),i.push(a);continue}o!=null&&o!==d&&s(),o??=d,r.push(a)}return s(),e.children=i,n}function Jo(e){const t=e.properties["data-char"];if(typeof t=="number")return t}function ft(e){if(e.type==="element"){e.properties["data-char"]=void 0;for(const t of e.children)ft(t)}}function Zo(e,t){e.properties["data-char"]=t}function es(e={}){const{classPrefix:t="__shiki_",classSuffix:n="",classReplacer:i=l=>l}=e,r=new Map;function o(l){return Object.entries(l).map(([a,d])=>`${a}:${d}`).join(";")}function s(l){let a=t+ts(typeof l=="string"?l:o(l))+n;return a=i(a),r.has(a)||r.set(a,typeof l=="string"?l:{...l}),a}return{name:"@shikijs/transformers:style-to-class",pre(l){if(!l.properties.style)return;const a=s(l.properties.style);delete l.properties.style,this.addClassToHast(l,a)},tokens(l){for(const a of l)for(const d of a){if(!d.htmlStyle)continue;const h=s(d.htmlStyle);d.htmlStyle={},d.htmlAttrs||={},d.htmlAttrs.class?d.htmlAttrs.class+=` ${h}`:d.htmlAttrs.class=h}},getClassRegistry(){return r},getCSS(){let l="";for(const[a,d]of r.entries())l+=`.${a}{${typeof d=="string"?d:o(d)}}`;return l},clearRegistry(){r.clear()}}}function ts(e,t=0){let n=3735928559^t,i=1103547991^t;for(let r=0,o;r<e.length;r++)o=e.charCodeAt(r),n=Math.imul(n^o,2654435761),i=Math.imul(i^o,1597334677);return n=Math.imul(n^n>>>16,2246822507),n^=Math.imul(i^i>>>13,3266489909),i=Math.imul(i^i>>>16,2246822507),i^=Math.imul(n^n>>>13,3266489909),(4294967296*(2097151&i)+(n>>>0)).toString(36).slice(0,6)}function Ji(e=!1,t=!1){const n={lineInfo:[]},i=[{line(r){return delete r.properties.class,r},pre(r){const o=oo(r),s=[];if(o!=null){let l=1;for(const a of o.children)a.type==="element"&&(e&&Qi(a),s.push(Qo(a,l,n)),l++);o.children=s}return r},...e?{tokens(r){for(const o of r){let s=0;for(const l of o){const a=l;a.__lineChar??=s,s+=l.content.length}}},preprocess(r,o){o.mergeWhitespaces="never"},span(r,o,s,l,a){if(a?.offset!=null&&a.content!=null){const d=a.__lineChar;return d!=null&&(r.properties["data-char"]=d),r}return r}}:null}];return t&&i.push(ns,Mn),{state:n,transformers:i,toClass:Mn}}const Mn=es({classPrefix:"hl-"}),ns={name:"token-style-normalizer",tokens(e){for(const t of e)for(const n of t){if(n.htmlStyle!=null)continue;const i={};n.color!=null&&(i.color=n.color),n.bgColor!=null&&(i["background-color"]=n.bgColor),n.fontStyle!=null&&n.fontStyle!==0&&((n.fontStyle&1)!==0&&(i["font-style"]="italic"),(n.fontStyle&2)!==0&&(i["font-weight"]="bold"),(n.fontStyle&4)!==0&&(i["text-decoration"]="underline")),Object.keys(i).length>0&&(n.htmlStyle=i)}}};function B(e){return`--${e==="token"?"diffs-token":"diffs"}-`}const is=/^#(?:[0-9a-f]{3}0|[0-9a-f]{6}00)$/i,rs=/^0(?:\.0+)?%?$/;function os(e){const t=e.indexOf("(");if(t<=0||!e.endsWith(")"))return;const n=e.slice(0,t).trim();if(!/^(?:rgb|rgba|hsl|hsla|hwb|lab|lch|oklab|oklch|color)$/i.test(n))return;const i=e.slice(t+1,-1).trim();if(i.length===0)return;const r=i.lastIndexOf("/");if(r!==-1)return i.slice(r+1).trim();if(/^(?:rgba|hsla)$/i.test(n)){const o=i.split(",");if(o.length===4)return o[3]?.trim()}}function ss(e){const t=/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})\b/i.exec(e.trim());if(t==null)return null;const n=t[1];let i,r=1;return n.length===3?i=n.split("").map(o=>o+o).join(""):n.length===6?i=n:(i=n.slice(0,6),r=parseInt(n.slice(6,8),16)/255),[parseInt(i.slice(0,2),16),parseInt(i.slice(2,4),16),parseInt(i.slice(4,6),16),r]}function At(e){if(e==null)return null;const t=ss(e);if(t==null)return null;const n=t[0]/255,i=t[1]/255,r=t[2]/255,o=s=>s<=.03928?s/12.92:((s+.055)/1.055)**2.4;return .2126*o(n)+.7152*o(i)+.0722*o(r)}function Dn(e){if(e==null)return!1;const t=e.trim().toLowerCase();if(t==="transparent"||is.test(t))return!0;const n=os(t);return n!=null&&rs.test(n)}function as(e,t,n){if(t==null||n==null)return!1;const i=At(e),r=At(t),o=At(n);return i==null||r==null||o==null?!1:Math.abs(i-o)<Math.abs(i-r)}const Pn=new WeakMap;function Ht(e){const t=Pn.get(e);if(t!=null)return t;const n=e.colors??{},i={...n},r=n["editor.background"]??e.bg,o=n["editor.foreground"]??e.fg,s=n["sideBar.background"]??r,l=n["sideBar.foreground"]??o;ie(i,"editor.background",r),ie(i,"editor.foreground",o),ie(i,"sideBar.background",s),ie(i,"sideBar.foreground",l),ie(i,"input.background",n["input.background"]??s),ie(i,"sideBarSectionHeader.foreground",n["sideBarSectionHeader.foreground"]??l),ie(i,"list.activeSelectionForeground",n["list.activeSelectionForeground"]??l),ie(i,"gitDecoration.addedResourceForeground",Mt(n["gitDecoration.addedResourceForeground"],n["terminal.ansiGreen"],n["editorGutter.addedBackground"])),ie(i,"gitDecoration.modifiedResourceForeground",Mt(n["gitDecoration.modifiedResourceForeground"],n["terminal.ansiBlue"],n["editorGutter.modifiedBackground"])),ie(i,"gitDecoration.deletedResourceForeground",Mt(n["gitDecoration.deletedResourceForeground"],n["terminal.ansiRed"],n["editorGutter.deletedBackground"]));const a=(Dn(n["list.focusOutline"])?void 0:n["list.focusOutline"])??(Dn(n.focusBorder)?void 0:n.focusBorder);a!=null?i["list.focusOutline"]=a:delete i["list.focusOutline"];const d=n["list.hoverBackground"];d!=null&&(ls(d,s)||as(d,s,l))&&delete i["list.hoverBackground"];const h=Object.freeze({...e,colors:Object.freeze(i)});return Pn.set(e,h),h}function ie(e,t,n){n!=null&&n!==""&&(e[t]=n)}function Mt(...e){for(const t of e)if(t!=null&&t!=="")return t}function ls(e,t){return t!=null&&e.toLowerCase()===t.toLowerCase()}function fn({theme:e=_,highlighter:t,prefix:n}){let i="";if(typeof e=="string"){const r=t.getTheme(e),o=Ht(r);i+=`color:${o.fg};`,i+=`background-color:${o.bg};`,i+=`${B("global")}fg:${o.fg};`,i+=`${B("global")}bg:${o.bg};`,i+=Dt(r,n)}else{let r=t.getTheme(e.dark),o=Ht(r);i+=`${B("global")}dark:${o.fg};`,i+=`${B("global")}dark-bg:${o.bg};`,i+=Dt(r,"dark"),r=t.getTheme(e.light),o=Ht(r),i+=`${B("global")}light:${o.fg};`,i+=`${B("global")}light-bg:${o.bg};`,i+=Dt(r,"light")}return i}function Dt(e,t){t=t!=null?`${t}-`:"";let n="";const i=e.colors?.["gitDecoration.addedResourceForeground"]??e.colors?.["terminal.ansiGreen"];i!=null&&(n+=`${B("global")}${t}addition-color:${i};`);const r=e.colors?.["gitDecoration.deletedResourceForeground"]??e.colors?.["terminal.ansiRed"];r!=null&&(n+=`${B("global")}${t}deletion-color:${r};`);const o=e.colors?.["gitDecoration.modifiedResourceForeground"]??e.colors?.["terminal.ansiBlue"];return o!=null&&(n+=`${B("global")}${t}modified-color:${o};`),n}function Kt(e){let t=e.children[0];for(;t!=null;){if(t.type==="element"&&t.tagName==="code")return t.children;"children"in t?t=t.children[0]:t=null}throw console.error(e),new Error("getLineNodes: Unable to find children")}function Ct({lines:e,startingLine:t=0,totalLines:n=1/0,callback:i}){const r=Math.min(t+n,e.length),o=(()=>{const s=e.at(-1);return s===""||s===` `||s===`\r `||s==="\r"?Math.max(0,e.length-2):e.length-1})();for(let s=t;s<r;s++){const l=s===o;if(i({lineIndex:s,lineNumber:s+1,content:e[s],isLastLine:l})===!0||l)break}}function St(e){return e!==""?e.split(jr):[]}const ds={forcePlainText:!1};function hs(e,t,{theme:n=_,tokenizeMaxLineLength:i,useTokenTransformer:r},{forcePlainText:o,startingLine:s,totalLines:l,lines:a}=ds){o?(s??=0,l??=1/0):(s=0,l=1/0);const d=s>0||l<1/0,{state:h,transformers:c}=Ji(r),u=o?"text":e.lang??Q(e.name),f=typeof n=="string"?t.getTheme(n).type:void 0,g=fn({theme:n,highlighter:t});h.lineInfo=p=>({type:"context",lineIndex:p-1+s,lineNumber:p+s});const b=typeof n=="string"?{lang:u,theme:n,transformers:c,defaultColor:!1,cssVariablePrefix:B("token"),tokenizeMaxLineLength:i,tokenizeTimeLimit:0}:{lang:u,themes:n,transformers:c,defaultColor:!1,cssVariablePrefix:B("token"),tokenizeMaxLineLength:i,tokenizeTimeLimit:0},y=Kt(t.codeToHast(d?cs(a??St(e.contents),s,l):xe(e.contents),b)),m=d?new Array(s):y;return d&&m.push(...y),{code:m,themeStyles:g,baseThemeType:f}}function cs(e,t,n){let i="";return Ct({lines:e,startingLine:t,totalLines:n,callback({content:r}){i+=r}}),i}const Zi="-1,-1";function Yt(e){return e?.some(t=>t.lineNumber===0)??!1}function Xt(e){const t=e[0];return t!=null&&t.length>0?t:void 0}function kt(e){return e.startingLine===0&&e.totalLines>0}function er(e,t){return A({tagName:"div",children:e,properties:{"data-content":"",style:`grid-row: span ${t}`}})}function Qt(e){return(e.lang??Q(e.name))==="text"}function tr(e){return e.useTokenTransformer===!0||e.onTokenClick!=null||e.onTokenEnter!=null||e.onTokenLeave!=null}let us=-1;var fs=class{options;onRenderUpdate;workerManager;__id=`file-renderer:${++us}`;highlighter;renderCache;computedLang="text";lineAnnotations={};lineCache;constructor(e={theme:_},t,n){this.options=e,this.onRenderUpdate=t,this.workerManager=n,n?.isWorkingPool()!==!0&&(this.highlighter=Ge(e.theme??_)?Ki():void 0)}setOptions(e){this.options=e}mergeOptions(e){this.options={...this.options,...e}}setLineAnnotations(e){this.lineAnnotations={};for(const t of e){const n=this.lineAnnotations[t.lineNumber]??[];this.lineAnnotations[t.lineNumber]=n,n.push(t)}}cleanUp(){this.recycle(),this.workerManager=void 0,this.onRenderUpdate=void 0}recycle(){this.clearRenderCache(),this.highlighter=void 0,this.workerManager?.cleanUpTasks(this),this.lineCache=void 0}clearRenderCache(){this.renderCache=void 0}hydrate(e){const{options:t}=this.getRenderOptions(e),n=Pt(this.getOrCreateLineCache(e).length,this.getTokenizeMaxLength());let i=this.workerManager?.getFileResultCache(e);i!=null&&!Oe(t,i.options)&&(i=void 0),this.renderCache??={file:e,options:t,highlighted:!n&&!Qt(e),result:n?void 0:i?.result,renderRange:void 0},this.workerManager?.isWorkingPool()===!0?this.renderCache.result==null&&!n&&this.workerManager.highlightFileAST(this,e):this.highlighter==null&&(this.computedLang=e.lang??Q(e.name),this.initializeHighlighter())}getRenderOptions(e){const t=(()=>{if(this.workerManager?.isWorkingPool()===!0)return this.workerManager.getFileRenderOptions();const{theme:i=_,tokenizeMaxLineLength:r=1e3}=this.options;return{theme:i,useTokenTransformer:tr(this.options),tokenizeMaxLineLength:r}})(),{renderCache:n}=this;return n?.result==null?{options:t,forceHighlight:!0}:!ae(e,n.file)||!Oe(t,n.options)?{options:t,forceHighlight:!0}:{options:t,forceHighlight:!1}}getOrCreateLineCache(e){if(e.cacheKey==null)return this.lineCache=void 0,St(e.contents);let{lineCache:t}=this;return(t==null||t.cacheKey!==e.cacheKey)&&(t={cacheKey:e.cacheKey,lines:St(e.contents)}),this.lineCache=t,t.lines}renderFile(e=this.renderCache?.file,t=Ae){if(e==null)return;let{options:n,forceHighlight:i}=this.getRenderOptions(e);const r=this.getMatchingWorkerResultCache(e,n);r!=null&&!this.hasHighlightedRenderCache(e,n)&&(this.renderCache={file:e,highlighted:!0,renderRange:void 0,...r},i=!1),this.renderCache??={file:e,highlighted:!1,options:n,result:void 0,renderRange:void 0};const o=this.getOrCreateLineCache(e),s=e.contents.length>0,l=!s||Qt(e)||Pt(o.length,this.getTokenizeMaxLength()),a=!ae(e,this.renderCache.file),d=!Lt(this.renderCache.renderRange,t);if(this.workerManager?.isWorkingPool()===!0)(l||this.renderCache.result==null||!this.renderCache.highlighted&&(a||d))&&(this.renderCache.file=e,this.renderCache.options=n,this.renderCache.highlighted=!1,(this.renderCache.result==null||a||d||i)&&(this.renderCache.result=this.workerManager.getPlainFileAST(e,t.startingLine,t.totalLines,o)),this.renderCache.renderRange=t),!l&&s&&(!this.renderCache.highlighted||i)&&this.workerManager.highlightFileAST(this,e);else{this.computedLang=e.lang??Q(e.name);const h=this.highlighter!=null&&Ge(n.theme),c=this.highlighter!=null&&mt(this.computedLang),u=!l&&c;if(this.highlighter!=null&&h&&(i||l||!this.renderCache.highlighted&&u||this.renderCache.result==null)){const{result:f,options:g}=this.renderFileWithHighlighter(e,this.highlighter,l||!c);this.renderCache={file:e,options:g,highlighted:u,result:f,renderRange:void 0}}(!h||!l&&!c)&&this.asyncHighlight(e).then(({result:f,options:g})=>{this.renderCache!=null&&(this.renderCache.highlighted=!1),this.onHighlightSuccess(e,f,g,!l)})}return this.renderCache.result!=null?this.processFileResult(this.renderCache.file,t,this.renderCache.result):void 0}async asyncRender(e,t=Ae){const{result:n}=await this.asyncHighlight(e);return this.processFileResult(e,t,n)}async asyncHighlight(e){const t=Pt(this.getOrCreateLineCache(e).length,this.getTokenizeMaxLength());this.computedLang=t?"text":e.lang??Q(e.name);const n=this.highlighter!=null&&Go(cn(this.options.theme)),i=t||this.highlighter!=null&&mt(this.computedLang);return(this.highlighter==null||!n||!i)&&(this.highlighter=await this.initializeHighlighter()),this.renderFileWithHighlighter(e,this.highlighter,t)}renderFileWithHighlighter(e,t,n=!1){const{options:i}=this.getRenderOptions(e);return{result:hs(e,t,i,{forcePlainText:n}),options:i}}processFileResult(e,t,{code:n,themeStyles:i,baseThemeType:r}){const{disableFileHeader:o=!1}=this.options,s=[],l=Ee(),a=this.getOrCreateLineCache(e);let d=0;const h=kt(t)?Xt(this.lineAnnotations):void 0;return h!=null&&(l.children.push(j("context","annotation",1)),s.push(qt({hunkIndex:-1,lineIndex:-1,annotations:h.map(c=>ge(c))})),d++),Ct({lines:a,startingLine:t.startingLine,totalLines:t.totalLines,callback:({lineIndex:c,lineNumber:u})=>{const f=n[c];if(f==null){const g="FileRenderer.processFileResult: Line doesnt exist";throw console.error(g,{name:e.name,lineIndex:c,lineNumber:u,lines:a}),new Error(g)}if(f!=null){l.children.push(Di("context",u,`${c}`)),s.push(f),d++;const g=this.lineAnnotations[u];g!=null&&(l.children.push(j("context","annotation",1)),s.push(qt({hunkIndex:0,lineIndex:u,annotations:g.map(b=>ge(b))})),d++)}}}),l.properties.style=`grid-row: span ${d}`,{gutterAST:l.children??[],contentAST:s,preAST:this.createPreElement(a.length),headerAST:o?void 0:this.renderHeader(e),totalLines:a.length,rowCount:d,themeStyles:i,baseThemeType:r,bufferBefore:t.bufferBefore,bufferAfter:t.bufferAfter,css:""}}renderHeader(e){const{headerRenderMode:t="default",stickyHeader:n=!1}=this.options;return Yi({fileOrDiff:e,mode:t,stickyHeader:n})}renderFullHTML(e){return pe(this.renderFullAST(e))}renderFullAST(e,t=[]){return t.push(A({tagName:"code",children:this.renderCodeAST(e),properties:{"data-code":""}})),{...e.preAST,children:t}}renderCodeAST(e){const t=Ee();return t.children=e.gutterAST,t.properties.style=`grid-row: span ${e.rowCount}`,[t,er(e.contentAST,e.rowCount)]}renderPartialHTML(e,t=!1){return t?pe(A({tagName:"code",children:e,properties:{"data-code":""}})):pe(e)}async initializeHighlighter(){return this.highlighter=await xt(un(this.computedLang,this.options)),this.highlighter}onHighlightSuccess(e,t,n,i=!0){if(this.renderCache==null)return;const r=!ae(e,this.renderCache.file)||!this.renderCache.highlighted||!Oe(n,this.renderCache.options);this.renderCache={file:e,options:n,highlighted:i,result:t,renderRange:void 0},r&&this.onRenderUpdate?.()}getMatchingWorkerResultCache(e,t){const n=this.workerManager?.getFileResultCache(e);if(!(n==null||!Oe(t,n.options)))return n}hasHighlightedRenderCache(e,t){const{renderCache:n}=this;return n?.result!=null&&n.highlighted&&ae(e,n.file)&&Oe(t,n.options)}onHighlightError(e){console.error(e)}getTokenizeMaxLength(){return this.options.tokenizeMaxLength??1e5}createPreElement(e){const{disableLineNumbers:t=!1,overflow:n="scroll"}=this.options;return Xi({type:"file",diffIndicators:"none",disableBackground:!0,disableLineNumbers:t,overflow:n,split:!1,totalLines:e})}};function Pt(e,t){return e>t}const nr=`<svg data-icon-sprite aria-hidden="true" width="0" height="0"> diff --git a/apps/kimi-code/dist-web/assets/index10-BqVmm7xb.js b/apps/kimi-code/dist-web/assets/index10-BCo1_xRY.js similarity index 97% rename from apps/kimi-code/dist-web/assets/index10-BqVmm7xb.js rename to apps/kimi-code/dist-web/assets/index10-BCo1_xRY.js index 682443492..194aae351 100644 --- a/apps/kimi-code/dist-web/assets/index10-BqVmm7xb.js +++ b/apps/kimi-code/dist-web/assets/index10-BCo1_xRY.js @@ -1,2 +1,2 @@ -import{bQ as Re,M as Ae,b$ as qe,c0 as Ge,c1 as Je,c2 as Qe,aU as d,bl as Ke,af as We,bY as e1,bE as B,as as U,aD as n1,c3 as Ze,az as o1,aL as r,u,aY as ge,v as t,bk as s,bb as X,au as b,t as F,aw as Ce,bL as t1,bB as l1,s as a1,I as i1,bJ as r1,bO as s1,g as u1,T as c1,q as T,c4 as Ve,c5 as ie,c6 as d1,c7 as De,c8 as v1,c9 as m1,b_ as h1}from"./index-D1h84VfZ.js";var re=(R,xe,l)=>new Promise((a,J)=>{var V=c=>{try{H(l.next(c))}catch($){J($)}},Q=c=>{try{H(l.throw(c))}catch($){J($)}},H=c=>c.done?a(c.value):Promise.resolve(c.value).then(V,Q);H((l=l.apply(R,xe)).next())});const p1=["data-markstream-mode"],f1={key:0,class:"infographic-block-header flex justify-between items-center border-b"},w1={key:0},g1={key:1,class:"flex items-center gap-x-2 overflow-hidden"},C1=["innerHTML"],k1={key:2},x1={key:3,class:"infographic-mode-toggle flex items-center gap-0.5"},y1=["disabled"],b1={class:"flex items-center gap-x-1"},M1={class:"flex items-center gap-x-1"},B1={key:4},F1={key:5,class:"infographic-header-actions flex items-center"},T1=["aria-pressed"],H1={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},$1={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},j1=["disabled"],L1=["disabled"],P1={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},E1={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},z1={key:0,class:"infographic-source"},S1={class:"infographic-source-code text-sm font-mono whitespace-pre-wrap"},Z1={key:1,class:"relative"},V1={key:0,class:"absolute top-2 right-2 z-10 rounded-lg"},D1={class:"flex items-center gap-2 backdrop-blur rounded-lg"},N1={key:0,class:"infographic-pending-source text-sm font-mono whitespace-pre-wrap"},Y1={class:"dialog-panel infographic-modal-panel relative w-full h-full max-w-full max-h-full rounded overflow-hidden"},_1={class:"absolute top-6 right-6 z-50 flex items-center gap-2"},se="infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",ke=Re(Ae({__name:"InfographicBlockNode",props:{node:{},maxHeight:{default:void 0},estimatedPreviewHeightPx:{},loading:{type:Boolean,default:!0},isDark:{type:Boolean},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showFullscreenButton:{type:Boolean,default:!0},showZoomControls:{type:Boolean,default:!0}},emits:["copy","export","openModal"],setup(R,{emit:xe}){const l=R,{t:a}=qe(),J=Ge(),V=Je(),Q=Qe(),H=d(!1),c=d(!1),$=d(),p=d(),k=d(!0),ye=d(!1),j=d(!1),D=d(),K=d(null),L=d(!1),S=d(!1),A=d(null),P=d(typeof window>"u"||!Q.value),Ne=Ke(),x=We(e1,null);let E="";const be=T(()=>h1(l,Ne));typeof window<"u"&&B([()=>$.value,Q],([n,e])=>{var o,i,C;if((o=A.value)==null||o.destroy(),A.value=null,!e||P.value)return void(P.value=!0);if(!n)return void(P.value=!1);const f=(C=(i=V?.value.heavyBlockMargin)!=null?i:V?.value.rootMargin)!=null?C:"160px",w=J(n,{rootMargin:f,allowIdle:!1});A.value=w,P.value=w.isVisible.value,w.whenVisible.then(()=>{P.value=!0})},{immediate:!0});const z=T(()=>l.node.code),ue=T(()=>{var n;return(function(e){if(l.maxHeight==="none")return Ve(e,void 0,null);const o=ie(l.maxHeight);return Ve(e,void 0,o)})((n=ie(l.estimatedPreviewHeightPx))!=null?n:d1(z.value))}),ce=d(`${ue.value}px`),Ye=T(()=>ie(l.estimatedPreviewHeightPx)!=null);function Me(){var n;if(!p.value||Ye.value)return;const e=p.value.scrollHeight;if(e>0){const o=(n=ie((function(i){if(l.maxHeight==="none")return`${i}px`;if(l.maxHeight!=null){const f=Number.parseFloat(String(l.maxHeight));if(Number.isFinite(f))return`${Math.min(i,f)}px`}const C=p.value;if(C){const f=getComputedStyle(C).getPropertyValue("--ms-size-code-max-height").trim(),w=Number.parseFloat(f);if(Number.isFinite(w))return`${Math.min(i,w)}px`}return`${Math.min(i,500)}px`})(e)))!=null?n:e;ce.value=`${Math.max(o,ue.value)}px`}}const M=d(1),N=d(0),Y=d(0),_=d(!1),W=d({x:0,y:0}),Be=T(()=>z.value);function Fe(n){return!n||n.disabled}function h(n,e,o="top"){if(Fe(n.currentTarget))return;const i=n,C=i?.clientX!=null&&i?.clientY!=null?{x:i.clientX,y:i.clientY}:void 0;De(n.currentTarget,e,o,!1,C,l.isDark)}function v(){v1()}function Te(n){if(Fe(n.currentTarget))return;const e=H.value?a("common.copied")||"Copied":a("common.copy")||"Copy",o=n,i=o?.clientX!=null&&o?.clientY!=null?{x:o.clientX,y:o.clientY}:void 0;De(n.currentTarget,e,"top",!1,i,l.isDark)}function _e(){return re(this,null,function*(){try{const n=z.value;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(n)),H.value=!0,setTimeout(()=>{H.value=!1},1e3)}catch(n){console.error("Failed to copy:",n)}})}function He(n){(n!=="preview"||Ze())&&(ye.value=!0,k.value=n==="source")}function Ie(){var n;const e=(n=p.value)==null?void 0:n.querySelector("svg");e?(function(o){re(this,null,function*(){try{const i=new XMLSerializer().serializeToString(o),C=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),f=URL.createObjectURL(C);if(typeof document<"u"){const w=document.createElement("a");w.href=f,w.download=`infographic-${Date.now()}.svg`;try{document.body.appendChild(w),w.click(),document.body.removeChild(w)}catch{}URL.revokeObjectURL(f)}}catch(i){console.error("Failed to export SVG:",i)}})})(e):console.error("SVG element not found")}function de(n){n.key==="Escape"&&j.value&&ve()}function ve(){if(j.value=!1,D.value&&(D.value.innerHTML=""),K.value=null,typeof document<"u")try{document.body.style.overflow=""}catch{}if(typeof window<"u")try{window.removeEventListener("keydown",de)}catch{}}function Oe(){(function(){if(j.value=!0,typeof document<"u")try{document.body.style.overflow="hidden"}catch{}if(typeof window<"u")try{window.addEventListener("keydown",de)}catch{}U(()=>{if(p.value&&D.value){D.value.innerHTML="";const n=document.createElement("div");n.style.transition="transform 0.1s ease",n.style.transformOrigin="center center",n.style.width="100%",n.style.height="100%",n.style.display="flex",n.style.alignItems="center",n.style.justifyContent="center";const e=p.value.cloneNode(!0);e.classList.add("fullscreen"),e.style.height="auto",n.appendChild(e),D.value.appendChild(n),K.value=n,n.style.transform=`translate(${N.value}px, ${Y.value}px) scale(${M.value})`}})})()}function $e(){M.value<3&&(M.value+=.1)}function je(){M.value>.5&&(M.value-=.1)}function Le(){M.value=1,N.value=0,Y.value=0}function ee(n){_.value=!0,n instanceof MouseEvent?W.value={x:n.clientX-N.value,y:n.clientY-Y.value}:W.value={x:n.touches[0].clientX-N.value,y:n.touches[0].clientY-Y.value}}function ne(n){if(!_.value)return;let e,o;n instanceof MouseEvent?(e=n.clientX,o=n.clientY):(e=n.touches[0].clientX,o=n.touches[0].clientY),N.value=e-W.value.x,Y.value=o-W.value.y}function I(){_.value=!1}let g=null,me=!1,oe=!1,q=!1,te="",G=!1,he=0;function le(n){return!G&&n===he}function Pe(n=!1){return re(this,null,function*(){var e,o;if(G||!P.value||!p.value)return;if(me)return oe=!0,void(q=q||n);const i=Be.value;if(!n&&i===te&&L.value)return;const C=l.loading===!1,f=++he;me=!0,(function(){const m=be.value;m&&E!==m&&(E&&x?.markSettled(E),E=m,x?.markPending(m))})();const w=p.value.innerHTML,pe=L.value,Xe=S.value;S.value=!1;try{const m=yield m1();if(!le(f))return;if(!m)return void console.warn("Infographic library failed to load.");const Z=p.value;if(!Z)return;g&&((e=g.destroy)==null||e.call(g),g=null),Z.innerHTML="",g=new m({container:Z,width:"100%",height:"100%"});let fe="";if((o=g.on)==null||o.call(g,"error",we=>{fe=(Array.isArray(we)?we:[we]).map(y=>{var Se;return y instanceof Error?y.message:typeof y=="string"?y:String(y&&typeof y=="object"&&"message"in y?(Se=y.message)!=null?Se:"":y??"")}).filter(Boolean).join("; ")}),g.render(z.value),fe)throw new Error(fe);if(!Z.childNodes.length)throw new Error("Infographic render returned empty output.");L.value=!0,S.value=!1,te=i,U(()=>{le(f)&&Me()})}catch(m){if(!le(f))return;C&&l.loading===!1&&i===Be.value?(console.error("Failed to render infographic:",m),L.value=!1,S.value=!0,te="",p.value&&(p.value.innerHTML=`<div style="padding: var(--ms-inset-panel-body); color: hsl(var(--ms-destructive))">Failed to render infographic: ${m instanceof Error?m.message:"Unknown error"}</div>`)):(L.value=pe,S.value=Xe,pe&&p.value&&(p.value.innerHTML=w))}finally{if(me=!1,le(f))if(oe){const m=q;oe=!1,q=!1,U(()=>{Pe(m)})}else(function(){re(this,null,function*(){const m=E;m&&(E="",yield U(),(function(Z=be.value){Z&&$.value&&x?.reportHeight(Z,$.value.offsetHeight)})(m),x?.markSettled(m))})})()}})}function O(n=!1){G||!P.value||k.value||c.value||U(()=>{G||Pe(n)})}B(()=>z.value,()=>{O(!0)}),B(()=>l.loading,(n,e)=>{e&&!n&&O(!0)}),B(()=>k.value,n=>{n||O(!0)}),B(()=>c.value,n=>{n||O()}),B(()=>l.maxHeight,()=>{U(()=>{Me()})}),B([()=>l.estimatedPreviewHeightPx,()=>z.value],()=>{L.value||k.value||(ce.value=`${ue.value}px`)}),B(()=>P.value,n=>{!n||k.value||c.value||O()}),n1(()=>{!ye.value&&Ze(),O()}),o1(()=>{var n,e;if(G=!0,he+=1,oe=!1,q=!1,(n=A.value)==null||n.destroy(),A.value=null,(function(){const o=E;o&&(E="",x?.markSettled(o))})(),g&&((e=g.destroy)==null||e.call(g),g=null),te="",typeof window<"u")try{window.removeEventListener("keydown",de)}catch{}});const Ee=T(()=>!0),ae=T(()=>k.value||c.value),Ue=T(()=>k.value?"fallback":S.value?"error":L.value?"preview":"pending"),ze=T(()=>({transform:`translate(${N.value}px, ${Y.value}px) scale(${M.value})`}));return B(ze,n=>{j.value&&K.value&&(K.value.style.transform=n.transform)}),(n,e)=>(r(),u("div",{ref_key:"viewportTarget",ref:$,class:b(["infographic-block-container rounded-lg border overflow-hidden",[{"is-rendering":l.loading,dark:l.isDark}]]),"data-markstream-infographic":"1","data-markstream-mode":Ue.value},[l.showHeader?(r(),u("div",f1,[n.$slots["header-left"]?(r(),u("div",w1,[ge(n.$slots,"header-left",{},void 0,!0)])):(r(),u("div",g1,[t("span",{class:"icon-slot action-icon shrink-0",innerHTML:s(`<svg width="15.52" height="16" viewBox="0 0 291 300" fill="none" xmlns="http://www.w3.org/2000/svg"><g><path d="M140.904 239.376C128.83 239.683 119.675 239.299 115.448 243.843C110.902 248.07 111.288 257.227 110.979 269.302C111.118 274.675 111.118 279.478 111.472 283.52C111.662 285.638 111.95 287.547 112.406 289.224C112.411 289.243 112.416 289.259 112.422 289.28C112.462 289.419 112.496 289.558 112.539 289.691C113.168 291.787 114.088 293.491 115.446 294.758C116.662 296.064 118.283 296.963 120.264 297.59C120.36 297.614 120.464 297.646 120.555 297.675C120.56 297.68 120.56 297.68 120.566 297.68C120.848 297.768 121.142 297.846 121.443 297.923C121.454 297.923 121.464 297.928 121.478 297.934C122.875 298.272 124.424 298.507 126.11 298.678C126.326 298.696 126.542 298.718 126.763 298.739C130.79 299.086 135.558 299.088 140.904 299.222C152.974 298.912 162.128 299.302 166.36 294.758C170.904 290.526 170.515 281.371 170.824 269.302C170.515 257.227 170.907 248.07 166.36 243.843C162.131 239.299 152.974 239.683 140.904 239.376Z" fill="#FF6376"></path><path d="M21.2155 128.398C12.6555 128.616 6.16484 128.339 3.16751 131.56C-0.0538222 134.56 0.218178 141.054 -0.000488281 149.608C0.218178 158.168 -0.0538222 164.659 3.16751 167.656C6.16484 170.878 12.6555 170.606 21.2155 170.824C25.0262 170.726 28.4288 170.726 31.2955 170.475C32.7968 170.342 34.1488 170.136 35.3382 169.814C35.3542 169.811 35.3648 169.806 35.3782 169.803C35.4768 169.774 35.5755 169.747 35.6688 169.718C37.1568 169.272 38.3648 168.622 39.2635 167.656C40.1915 166.795 40.8262 165.646 41.2715 164.243C41.2875 164.174 41.3115 164.102 41.3328 164.035C41.3328 164.035 41.3355 164.032 41.3355 164.027C41.3968 163.827 41.4529 163.622 41.5062 163.406C41.5062 163.398 41.5115 163.392 41.5142 163.382C41.7542 162.392 41.9222 161.294 42.0422 160.096C42.0555 159.944 42.0715 159.792 42.0848 159.635C42.3328 156.779 42.3328 153.398 42.4262 149.608C42.2075 141.054 42.4848 134.56 39.2635 131.56C36.2635 128.339 29.7728 128.616 21.2155 128.398Z" fill="#FFCCCC"></path><path d="M81.0595 184.171C70.8568 184.433 63.1208 184.102 59.5475 187.942C55.7075 191.518 56.0328 199.254 55.7742 209.454C56.0328 219.657 55.7075 227.393 59.5475 230.963C63.1208 234.803 70.8568 234.478 81.0595 234.739C85.6008 234.622 89.6595 234.622 93.0728 234.323C94.8648 234.163 96.4755 233.921 97.8942 233.534C97.9102 233.529 97.9235 233.526 97.9422 233.521C98.0568 233.486 98.1742 233.457 98.2888 233.422C100.06 232.889 101.5 232.113 102.569 230.963C103.676 229.937 104.433 228.566 104.964 226.894C104.985 226.811 105.012 226.726 105.036 226.646C105.041 226.643 105.041 226.643 105.041 226.638C105.116 226.401 105.18 226.153 105.244 225.897C105.244 225.889 105.249 225.881 105.254 225.867C105.54 224.689 105.74 223.379 105.881 221.953C105.9 221.771 105.916 221.59 105.934 221.403C106.228 218.001 106.228 213.969 106.342 209.454C106.081 199.254 106.412 191.518 102.572 187.942C98.9955 184.102 91.2568 184.433 81.0595 184.171Z" fill="#FF939F"></path><path d="M260.591 151.87C215.652 151.87 203.02 164.523 203.02 209.462H198.476C198.476 164.523 185.836 151.881 140.895 151.881V147.337C185.836 147.337 198.487 134.705 198.487 89.7659H203.02C203.02 134.705 215.652 147.337 260.591 147.337V151.87ZM286.052 124.158C281.82 119.614 272.66 120.001 260.591 119.689C248.521 119.385 239.361 119.771 235.129 115.227C230.585 110.995 230.983 101.846 230.671 89.7659C230.513 83.7312 230.535 78.4272 230.023 74.1019C229.513 69.7659 228.481 66.4219 226.209 64.3046C221.967 59.7606 212.817 60.1472 200.748 59.8459C188.681 60.1472 179.519 59.7606 175.287 64.3046C170.753 68.5366 171.129 77.6966 170.828 89.7659C170.516 101.835 170.9 110.995 166.356 115.227C162.124 119.771 152.985 119.374 140.905 119.689C138.873 119.739 136.924 119.771 135.071 119.811C119.313 118.697 106.337 112.318 106.337 89.7659C106.212 84.6699 106.233 80.1792 105.807 76.5206C105.367 72.8726 104.492 70.0379 102.575 68.2566C99.0013 64.4112 91.2573 64.7446 81.0653 64.4832C70.86 64.7446 63.1186 64.4112 59.5533 68.2566C55.708 71.8299 56.0306 79.5632 55.7693 89.7659C56.0306 99.9686 55.708 107.702 59.5533 111.278C63.1186 115.113 70.86 114.79 81.0653 115.049C103.617 115.049 109.996 128.035 111.1 143.803C111.068 145.659 111.028 147.587 110.975 149.619C111.121 154.987 111.121 159.79 111.476 163.835C111.663 165.95 111.945 167.857 112.404 169.534C112.412 169.555 112.412 169.566 112.423 169.598C112.465 169.734 112.497 169.867 112.537 170.003C113.164 172.099 114.092 173.809 115.447 175.07C116.665 176.371 118.281 177.278 120.271 177.905C120.364 177.934 120.46 177.955 120.564 177.987C120.855 178.081 121.145 178.153 121.439 178.238C121.46 178.238 121.471 178.238 121.479 178.249C122.876 178.582 124.42 178.822 126.108 178.987C126.327 179.009 126.545 179.03 126.764 179.051C130.788 179.395 135.559 179.395 140.905 179.529C152.975 179.843 162.124 179.457 166.356 184.001C170.9 188.233 170.516 197.371 170.828 209.451C171.129 221.529 170.743 230.681 175.287 234.91C179.519 239.454 188.681 239.07 200.748 239.371C206.127 239.235 210.921 239.235 214.975 238.881C217.079 238.694 218.985 238.403 220.676 237.955C220.695 237.945 220.705 237.934 220.727 237.934C220.873 237.891 220.999 237.859 221.135 237.819C223.228 237.193 224.937 236.265 226.209 234.91C227.511 233.691 228.409 232.065 229.044 230.097C229.065 230.003 229.095 229.899 229.127 229.803V229.793C229.22 229.513 229.295 229.222 229.367 228.918C229.367 228.897 229.377 228.897 229.377 228.878C229.721 227.481 229.951 225.937 230.127 224.249C230.137 224.03 230.169 223.811 230.191 223.593C230.535 219.571 230.535 214.798 230.671 209.451C230.972 197.371 230.585 188.233 235.129 184.001C239.361 179.457 248.511 179.843 260.591 179.529C272.66 179.227 281.82 179.614 286.052 175.07C290.596 170.838 290.209 161.689 290.511 149.619C290.209 137.539 290.596 128.379 286.052 124.158Z" fill="#FF356A"></path><path d="M112.405 49.848C112.411 49.8694 112.416 49.8827 112.421 49.904C112.461 50.0427 112.499 50.1814 112.539 50.3147C113.171 52.4134 114.088 54.1147 115.448 55.384C116.661 56.6907 118.283 57.5894 120.264 58.2134C120.36 58.24 120.464 58.2694 120.555 58.3014C120.56 58.3067 120.56 58.3067 120.565 58.3067C120.848 58.3947 121.141 58.4694 121.443 58.5467C121.453 58.5467 121.464 58.552 121.48 58.5574C122.875 58.896 124.424 59.1334 126.112 59.3014C126.325 59.3227 126.541 59.3414 126.763 59.3627C130.789 59.712 135.56 59.712 140.904 59.8454C152.973 59.5387 162.128 59.928 166.36 55.384C170.907 51.152 170.515 41.9947 170.824 29.9254C170.517 17.8507 170.907 8.69602 166.363 4.46935C162.131 -0.0746511 152.973 0.309349 140.904 1.52588e-05C128.829 0.309349 119.675 -0.0746511 115.448 4.46935C110.904 8.69602 111.288 17.8507 110.979 29.9254C111.117 35.3014 111.117 40.1014 111.472 44.144C111.661 46.2614 111.949 48.1707 112.405 49.848Z" fill="#FF6376"></path></g></svg> +import{bQ as Re,M as Ae,b$ as Ge,c0 as qe,c1 as Je,c2 as Qe,aU as d,bl as Ke,af as We,bY as e1,bE as B,as as U,aD as n1,c3 as Ze,az as o1,aL as r,u,aY as ge,v as t,bk as s,bb as X,au as b,t as F,aw as Ce,bL as t1,bB as l1,s as a1,I as i1,bJ as r1,bO as s1,g as u1,T as c1,q as T,c4 as Ve,c5 as ie,c6 as d1,c7 as De,c8 as v1,c9 as m1,b_ as h1}from"./index-D-7nOosq.js";var re=(R,xe,l)=>new Promise((a,J)=>{var V=c=>{try{H(l.next(c))}catch($){J($)}},Q=c=>{try{H(l.throw(c))}catch($){J($)}},H=c=>c.done?a(c.value):Promise.resolve(c.value).then(V,Q);H((l=l.apply(R,xe)).next())});const p1=["data-markstream-mode"],f1={key:0,class:"infographic-block-header flex justify-between items-center border-b"},w1={key:0},g1={key:1,class:"flex items-center gap-x-2 overflow-hidden"},C1=["innerHTML"],k1={key:2},x1={key:3,class:"infographic-mode-toggle flex items-center gap-0.5"},y1=["disabled"],b1={class:"flex items-center gap-x-1"},M1={class:"flex items-center gap-x-1"},B1={key:4},F1={key:5,class:"infographic-header-actions flex items-center"},T1=["aria-pressed"],H1={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},$1={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},j1=["disabled"],L1=["disabled"],P1={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},E1={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},z1={key:0,class:"infographic-source"},S1={class:"infographic-source-code text-sm font-mono whitespace-pre-wrap"},Z1={key:1,class:"relative"},V1={key:0,class:"absolute top-2 right-2 z-10 rounded-lg"},D1={class:"flex items-center gap-2 backdrop-blur rounded-lg"},N1={key:0,class:"infographic-pending-source text-sm font-mono whitespace-pre-wrap"},Y1={class:"dialog-panel infographic-modal-panel relative w-full h-full max-w-full max-h-full rounded overflow-hidden"},_1={class:"absolute top-6 right-6 z-50 flex items-center gap-2"},se="infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",ke=Re(Ae({__name:"InfographicBlockNode",props:{node:{},maxHeight:{default:void 0},estimatedPreviewHeightPx:{},loading:{type:Boolean,default:!0},isDark:{type:Boolean},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showFullscreenButton:{type:Boolean,default:!0},showZoomControls:{type:Boolean,default:!0}},emits:["copy","export","openModal"],setup(R,{emit:xe}){const l=R,{t:a}=Ge(),J=qe(),V=Je(),Q=Qe(),H=d(!1),c=d(!1),$=d(),p=d(),k=d(!0),ye=d(!1),j=d(!1),D=d(),K=d(null),L=d(!1),S=d(!1),A=d(null),P=d(typeof window>"u"||!Q.value),Ne=Ke(),x=We(e1,null);let E="";const be=T(()=>h1(l,Ne));typeof window<"u"&&B([()=>$.value,Q],([n,e])=>{var o,i,C;if((o=A.value)==null||o.destroy(),A.value=null,!e||P.value)return void(P.value=!0);if(!n)return void(P.value=!1);const f=(C=(i=V?.value.heavyBlockMargin)!=null?i:V?.value.rootMargin)!=null?C:"160px",w=J(n,{rootMargin:f,allowIdle:!1});A.value=w,P.value=w.isVisible.value,w.whenVisible.then(()=>{P.value=!0})},{immediate:!0});const z=T(()=>l.node.code),ue=T(()=>{var n;return(function(e){if(l.maxHeight==="none")return Ve(e,void 0,null);const o=ie(l.maxHeight);return Ve(e,void 0,o)})((n=ie(l.estimatedPreviewHeightPx))!=null?n:d1(z.value))}),ce=d(`${ue.value}px`),Ye=T(()=>ie(l.estimatedPreviewHeightPx)!=null);function Me(){var n;if(!p.value||Ye.value)return;const e=p.value.scrollHeight;if(e>0){const o=(n=ie((function(i){if(l.maxHeight==="none")return`${i}px`;if(l.maxHeight!=null){const f=Number.parseFloat(String(l.maxHeight));if(Number.isFinite(f))return`${Math.min(i,f)}px`}const C=p.value;if(C){const f=getComputedStyle(C).getPropertyValue("--ms-size-code-max-height").trim(),w=Number.parseFloat(f);if(Number.isFinite(w))return`${Math.min(i,w)}px`}return`${Math.min(i,500)}px`})(e)))!=null?n:e;ce.value=`${Math.max(o,ue.value)}px`}}const M=d(1),N=d(0),Y=d(0),_=d(!1),W=d({x:0,y:0}),Be=T(()=>z.value);function Fe(n){return!n||n.disabled}function h(n,e,o="top"){if(Fe(n.currentTarget))return;const i=n,C=i?.clientX!=null&&i?.clientY!=null?{x:i.clientX,y:i.clientY}:void 0;De(n.currentTarget,e,o,!1,C,l.isDark)}function v(){v1()}function Te(n){if(Fe(n.currentTarget))return;const e=H.value?a("common.copied")||"Copied":a("common.copy")||"Copy",o=n,i=o?.clientX!=null&&o?.clientY!=null?{x:o.clientX,y:o.clientY}:void 0;De(n.currentTarget,e,"top",!1,i,l.isDark)}function _e(){return re(this,null,function*(){try{const n=z.value;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(n)),H.value=!0,setTimeout(()=>{H.value=!1},1e3)}catch(n){console.error("Failed to copy:",n)}})}function He(n){(n!=="preview"||Ze())&&(ye.value=!0,k.value=n==="source")}function Ie(){var n;const e=(n=p.value)==null?void 0:n.querySelector("svg");e?(function(o){re(this,null,function*(){try{const i=new XMLSerializer().serializeToString(o),C=new Blob([i],{type:"image/svg+xml;charset=utf-8"}),f=URL.createObjectURL(C);if(typeof document<"u"){const w=document.createElement("a");w.href=f,w.download=`infographic-${Date.now()}.svg`;try{document.body.appendChild(w),w.click(),document.body.removeChild(w)}catch{}URL.revokeObjectURL(f)}}catch(i){console.error("Failed to export SVG:",i)}})})(e):console.error("SVG element not found")}function de(n){n.key==="Escape"&&j.value&&ve()}function ve(){if(j.value=!1,D.value&&(D.value.innerHTML=""),K.value=null,typeof document<"u")try{document.body.style.overflow=""}catch{}if(typeof window<"u")try{window.removeEventListener("keydown",de)}catch{}}function Oe(){(function(){if(j.value=!0,typeof document<"u")try{document.body.style.overflow="hidden"}catch{}if(typeof window<"u")try{window.addEventListener("keydown",de)}catch{}U(()=>{if(p.value&&D.value){D.value.innerHTML="";const n=document.createElement("div");n.style.transition="transform 0.1s ease",n.style.transformOrigin="center center",n.style.width="100%",n.style.height="100%",n.style.display="flex",n.style.alignItems="center",n.style.justifyContent="center";const e=p.value.cloneNode(!0);e.classList.add("fullscreen"),e.style.height="auto",n.appendChild(e),D.value.appendChild(n),K.value=n,n.style.transform=`translate(${N.value}px, ${Y.value}px) scale(${M.value})`}})})()}function $e(){M.value<3&&(M.value+=.1)}function je(){M.value>.5&&(M.value-=.1)}function Le(){M.value=1,N.value=0,Y.value=0}function ee(n){_.value=!0,n instanceof MouseEvent?W.value={x:n.clientX-N.value,y:n.clientY-Y.value}:W.value={x:n.touches[0].clientX-N.value,y:n.touches[0].clientY-Y.value}}function ne(n){if(!_.value)return;let e,o;n instanceof MouseEvent?(e=n.clientX,o=n.clientY):(e=n.touches[0].clientX,o=n.touches[0].clientY),N.value=e-W.value.x,Y.value=o-W.value.y}function I(){_.value=!1}let g=null,me=!1,oe=!1,G=!1,te="",q=!1,he=0;function le(n){return!q&&n===he}function Pe(n=!1){return re(this,null,function*(){var e,o;if(q||!P.value||!p.value)return;if(me)return oe=!0,void(G=G||n);const i=Be.value;if(!n&&i===te&&L.value)return;const C=l.loading===!1,f=++he;me=!0,(function(){const m=be.value;m&&E!==m&&(E&&x?.markSettled(E),E=m,x?.markPending(m))})();const w=p.value.innerHTML,pe=L.value,Xe=S.value;S.value=!1;try{const m=yield m1();if(!le(f))return;if(!m)return void console.warn("Infographic library failed to load.");const Z=p.value;if(!Z)return;g&&((e=g.destroy)==null||e.call(g),g=null),Z.innerHTML="",g=new m({container:Z,width:"100%",height:"100%"});let fe="";if((o=g.on)==null||o.call(g,"error",we=>{fe=(Array.isArray(we)?we:[we]).map(y=>{var Se;return y instanceof Error?y.message:typeof y=="string"?y:String(y&&typeof y=="object"&&"message"in y?(Se=y.message)!=null?Se:"":y??"")}).filter(Boolean).join("; ")}),g.render(z.value),fe)throw new Error(fe);if(!Z.childNodes.length)throw new Error("Infographic render returned empty output.");L.value=!0,S.value=!1,te=i,U(()=>{le(f)&&Me()})}catch(m){if(!le(f))return;C&&l.loading===!1&&i===Be.value?(console.error("Failed to render infographic:",m),L.value=!1,S.value=!0,te="",p.value&&(p.value.innerHTML=`<div style="padding: var(--ms-inset-panel-body); color: hsl(var(--ms-destructive))">Failed to render infographic: ${m instanceof Error?m.message:"Unknown error"}</div>`)):(L.value=pe,S.value=Xe,pe&&p.value&&(p.value.innerHTML=w))}finally{if(me=!1,le(f))if(oe){const m=G;oe=!1,G=!1,U(()=>{Pe(m)})}else(function(){re(this,null,function*(){const m=E;m&&(E="",yield U(),(function(Z=be.value){Z&&$.value&&x?.reportHeight(Z,$.value.offsetHeight)})(m),x?.markSettled(m))})})()}})}function O(n=!1){q||!P.value||k.value||c.value||U(()=>{q||Pe(n)})}B(()=>z.value,()=>{O(!0)}),B(()=>l.loading,(n,e)=>{e&&!n&&O(!0)}),B(()=>k.value,n=>{n||O(!0)}),B(()=>c.value,n=>{n||O()}),B(()=>l.maxHeight,()=>{U(()=>{Me()})}),B([()=>l.estimatedPreviewHeightPx,()=>z.value],()=>{L.value||k.value||(ce.value=`${ue.value}px`)}),B(()=>P.value,n=>{!n||k.value||c.value||O()}),n1(()=>{!ye.value&&Ze(),O()}),o1(()=>{var n,e;if(q=!0,he+=1,oe=!1,G=!1,(n=A.value)==null||n.destroy(),A.value=null,(function(){const o=E;o&&(E="",x?.markSettled(o))})(),g&&((e=g.destroy)==null||e.call(g),g=null),te="",typeof window<"u")try{window.removeEventListener("keydown",de)}catch{}});const Ee=T(()=>!0),ae=T(()=>k.value||c.value),Ue=T(()=>k.value?"fallback":S.value?"error":L.value?"preview":"pending"),ze=T(()=>({transform:`translate(${N.value}px, ${Y.value}px) scale(${M.value})`}));return B(ze,n=>{j.value&&K.value&&(K.value.style.transform=n.transform)}),(n,e)=>(r(),u("div",{ref_key:"viewportTarget",ref:$,class:b(["infographic-block-container rounded-lg border overflow-hidden",[{"is-rendering":l.loading,dark:l.isDark}]]),"data-markstream-infographic":"1","data-markstream-mode":Ue.value},[l.showHeader?(r(),u("div",f1,[n.$slots["header-left"]?(r(),u("div",w1,[ge(n.$slots,"header-left",{},void 0,!0)])):(r(),u("div",g1,[t("span",{class:"icon-slot action-icon shrink-0",innerHTML:s(`<svg width="15.52" height="16" viewBox="0 0 291 300" fill="none" xmlns="http://www.w3.org/2000/svg"><g><path d="M140.904 239.376C128.83 239.683 119.675 239.299 115.448 243.843C110.902 248.07 111.288 257.227 110.979 269.302C111.118 274.675 111.118 279.478 111.472 283.52C111.662 285.638 111.95 287.547 112.406 289.224C112.411 289.243 112.416 289.259 112.422 289.28C112.462 289.419 112.496 289.558 112.539 289.691C113.168 291.787 114.088 293.491 115.446 294.758C116.662 296.064 118.283 296.963 120.264 297.59C120.36 297.614 120.464 297.646 120.555 297.675C120.56 297.68 120.56 297.68 120.566 297.68C120.848 297.768 121.142 297.846 121.443 297.923C121.454 297.923 121.464 297.928 121.478 297.934C122.875 298.272 124.424 298.507 126.11 298.678C126.326 298.696 126.542 298.718 126.763 298.739C130.79 299.086 135.558 299.088 140.904 299.222C152.974 298.912 162.128 299.302 166.36 294.758C170.904 290.526 170.515 281.371 170.824 269.302C170.515 257.227 170.907 248.07 166.36 243.843C162.131 239.299 152.974 239.683 140.904 239.376Z" fill="#FF6376"></path><path d="M21.2155 128.398C12.6555 128.616 6.16484 128.339 3.16751 131.56C-0.0538222 134.56 0.218178 141.054 -0.000488281 149.608C0.218178 158.168 -0.0538222 164.659 3.16751 167.656C6.16484 170.878 12.6555 170.606 21.2155 170.824C25.0262 170.726 28.4288 170.726 31.2955 170.475C32.7968 170.342 34.1488 170.136 35.3382 169.814C35.3542 169.811 35.3648 169.806 35.3782 169.803C35.4768 169.774 35.5755 169.747 35.6688 169.718C37.1568 169.272 38.3648 168.622 39.2635 167.656C40.1915 166.795 40.8262 165.646 41.2715 164.243C41.2875 164.174 41.3115 164.102 41.3328 164.035C41.3328 164.035 41.3355 164.032 41.3355 164.027C41.3968 163.827 41.4529 163.622 41.5062 163.406C41.5062 163.398 41.5115 163.392 41.5142 163.382C41.7542 162.392 41.9222 161.294 42.0422 160.096C42.0555 159.944 42.0715 159.792 42.0848 159.635C42.3328 156.779 42.3328 153.398 42.4262 149.608C42.2075 141.054 42.4848 134.56 39.2635 131.56C36.2635 128.339 29.7728 128.616 21.2155 128.398Z" fill="#FFCCCC"></path><path d="M81.0595 184.171C70.8568 184.433 63.1208 184.102 59.5475 187.942C55.7075 191.518 56.0328 199.254 55.7742 209.454C56.0328 219.657 55.7075 227.393 59.5475 230.963C63.1208 234.803 70.8568 234.478 81.0595 234.739C85.6008 234.622 89.6595 234.622 93.0728 234.323C94.8648 234.163 96.4755 233.921 97.8942 233.534C97.9102 233.529 97.9235 233.526 97.9422 233.521C98.0568 233.486 98.1742 233.457 98.2888 233.422C100.06 232.889 101.5 232.113 102.569 230.963C103.676 229.937 104.433 228.566 104.964 226.894C104.985 226.811 105.012 226.726 105.036 226.646C105.041 226.643 105.041 226.643 105.041 226.638C105.116 226.401 105.18 226.153 105.244 225.897C105.244 225.889 105.249 225.881 105.254 225.867C105.54 224.689 105.74 223.379 105.881 221.953C105.9 221.771 105.916 221.59 105.934 221.403C106.228 218.001 106.228 213.969 106.342 209.454C106.081 199.254 106.412 191.518 102.572 187.942C98.9955 184.102 91.2568 184.433 81.0595 184.171Z" fill="#FF939F"></path><path d="M260.591 151.87C215.652 151.87 203.02 164.523 203.02 209.462H198.476C198.476 164.523 185.836 151.881 140.895 151.881V147.337C185.836 147.337 198.487 134.705 198.487 89.7659H203.02C203.02 134.705 215.652 147.337 260.591 147.337V151.87ZM286.052 124.158C281.82 119.614 272.66 120.001 260.591 119.689C248.521 119.385 239.361 119.771 235.129 115.227C230.585 110.995 230.983 101.846 230.671 89.7659C230.513 83.7312 230.535 78.4272 230.023 74.1019C229.513 69.7659 228.481 66.4219 226.209 64.3046C221.967 59.7606 212.817 60.1472 200.748 59.8459C188.681 60.1472 179.519 59.7606 175.287 64.3046C170.753 68.5366 171.129 77.6966 170.828 89.7659C170.516 101.835 170.9 110.995 166.356 115.227C162.124 119.771 152.985 119.374 140.905 119.689C138.873 119.739 136.924 119.771 135.071 119.811C119.313 118.697 106.337 112.318 106.337 89.7659C106.212 84.6699 106.233 80.1792 105.807 76.5206C105.367 72.8726 104.492 70.0379 102.575 68.2566C99.0013 64.4112 91.2573 64.7446 81.0653 64.4832C70.86 64.7446 63.1186 64.4112 59.5533 68.2566C55.708 71.8299 56.0306 79.5632 55.7693 89.7659C56.0306 99.9686 55.708 107.702 59.5533 111.278C63.1186 115.113 70.86 114.79 81.0653 115.049C103.617 115.049 109.996 128.035 111.1 143.803C111.068 145.659 111.028 147.587 110.975 149.619C111.121 154.987 111.121 159.79 111.476 163.835C111.663 165.95 111.945 167.857 112.404 169.534C112.412 169.555 112.412 169.566 112.423 169.598C112.465 169.734 112.497 169.867 112.537 170.003C113.164 172.099 114.092 173.809 115.447 175.07C116.665 176.371 118.281 177.278 120.271 177.905C120.364 177.934 120.46 177.955 120.564 177.987C120.855 178.081 121.145 178.153 121.439 178.238C121.46 178.238 121.471 178.238 121.479 178.249C122.876 178.582 124.42 178.822 126.108 178.987C126.327 179.009 126.545 179.03 126.764 179.051C130.788 179.395 135.559 179.395 140.905 179.529C152.975 179.843 162.124 179.457 166.356 184.001C170.9 188.233 170.516 197.371 170.828 209.451C171.129 221.529 170.743 230.681 175.287 234.91C179.519 239.454 188.681 239.07 200.748 239.371C206.127 239.235 210.921 239.235 214.975 238.881C217.079 238.694 218.985 238.403 220.676 237.955C220.695 237.945 220.705 237.934 220.727 237.934C220.873 237.891 220.999 237.859 221.135 237.819C223.228 237.193 224.937 236.265 226.209 234.91C227.511 233.691 228.409 232.065 229.044 230.097C229.065 230.003 229.095 229.899 229.127 229.803V229.793C229.22 229.513 229.295 229.222 229.367 228.918C229.367 228.897 229.377 228.897 229.377 228.878C229.721 227.481 229.951 225.937 230.127 224.249C230.137 224.03 230.169 223.811 230.191 223.593C230.535 219.571 230.535 214.798 230.671 209.451C230.972 197.371 230.585 188.233 235.129 184.001C239.361 179.457 248.511 179.843 260.591 179.529C272.66 179.227 281.82 179.614 286.052 175.07C290.596 170.838 290.209 161.689 290.511 149.619C290.209 137.539 290.596 128.379 286.052 124.158Z" fill="#FF356A"></path><path d="M112.405 49.848C112.411 49.8694 112.416 49.8827 112.421 49.904C112.461 50.0427 112.499 50.1814 112.539 50.3147C113.171 52.4134 114.088 54.1147 115.448 55.384C116.661 56.6907 118.283 57.5894 120.264 58.2134C120.36 58.24 120.464 58.2694 120.555 58.3014C120.56 58.3067 120.56 58.3067 120.565 58.3067C120.848 58.3947 121.141 58.4694 121.443 58.5467C121.453 58.5467 121.464 58.552 121.48 58.5574C122.875 58.896 124.424 59.1334 126.112 59.3014C126.325 59.3227 126.541 59.3414 126.763 59.3627C130.789 59.712 135.56 59.712 140.904 59.8454C152.973 59.5387 162.128 59.928 166.36 55.384C170.907 51.152 170.515 41.9947 170.824 29.9254C170.517 17.8507 170.907 8.69602 166.363 4.46935C162.131 -0.0746511 152.973 0.309349 140.904 1.52588e-05C128.829 0.309349 119.675 -0.0746511 115.448 4.46935C110.904 8.69602 111.288 17.8507 110.979 29.9254C111.117 35.3014 111.117 40.1014 111.472 44.144C111.661 46.2614 111.949 48.1707 112.405 49.848Z" fill="#FF6376"></path></g></svg> `)},null,8,C1),e[21]||(e[21]=t("span",{class:"infographic-label font-medium font-mono truncate"},"Infographic",-1))])),n.$slots["header-center"]?(r(),u("div",k1,[ge(n.$slots,"header-center",{},void 0,!0)])):l.showModeToggle?(r(),u("div",x1,[t("button",{class:b(["infographic-mode-btn px-2 py-0.5 rounded transition-colors",[k.value?"":"is-active",Ee.value?"opacity-50 cursor-not-allowed":""]]),disabled:Ee.value,onClick:e[0]||(e[0]=()=>He("preview")),onMouseenter:e[1]||(e[1]=o=>h(o,s(a)("common.preview")||"Preview")),onFocus:e[2]||(e[2]=o=>h(o,s(a)("common.preview")||"Preview")),onMouseleave:v,onBlur:v},[t("div",b1,[e[22]||(e[22]=t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("path",{d:"M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"}),t("circle",{cx:"12",cy:"12",r:"3"})])],-1)),t("span",null,X(s(a)("common.preview")||"Preview"),1)])],42,y1),t("button",{class:b(["infographic-mode-btn px-2 py-0.5 rounded transition-colors",[k.value?"is-active":""]]),onClick:e[3]||(e[3]=()=>He("source")),onMouseenter:e[4]||(e[4]=o=>h(o,s(a)("common.source")||"Source")),onFocus:e[5]||(e[5]=o=>h(o,s(a)("common.source")||"Source")),onMouseleave:v,onBlur:v},[t("div",M1,[e[23]||(e[23]=t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m16 18l6-6l-6-6M8 6l-6 6l6 6"})],-1)),t("span",null,X(s(a)("common.source")||"Source"),1)])],34)])):F("",!0),n.$slots["header-right"]?(r(),u("div",B1,[ge(n.$slots,"header-right",{},void 0,!0)])):(r(),u("div",F1,[l.showCollapseButton?(r(),u("button",{key:0,class:b(se),"aria-pressed":c.value,onClick:e[6]||(e[6]=o=>c.value=!c.value),onMouseenter:e[7]||(e[7]=o=>h(o,c.value?s(a)("common.expand")||"Expand":s(a)("common.collapse")||"Collapse")),onFocus:e[8]||(e[8]=o=>h(o,c.value?s(a)("common.expand")||"Expand":s(a)("common.collapse")||"Collapse")),onMouseleave:v,onBlur:v},[(r(),u("svg",{style:Ce({rotate:c.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...e[24]||(e[24]=[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,T1)):F("",!0),l.showCopyButton?(r(),u("button",{key:1,class:b(se),onClick:_e,onMouseenter:e[9]||(e[9]=o=>Te(o)),onFocus:e[10]||(e[10]=o=>Te(o)),onMouseleave:v,onBlur:v},[H.value?(r(),u("svg",$1,[...e[26]||(e[26]=[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(r(),u("svg",H1,[...e[25]||(e[25]=[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),t("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],32)):F("",!0),l.showExportButton?(r(),u("button",{key:2,class:b(`${se} ${ae.value?"opacity-50 cursor-not-allowed":""}`),disabled:ae.value,onClick:Ie,onMouseenter:e[11]||(e[11]=o=>h(o,s(a)("common.export")||"Export")),onFocus:e[12]||(e[12]=o=>h(o,s(a)("common.export")||"Export")),onMouseleave:v,onBlur:v},[...e[27]||(e[27]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("path",{d:"M12 15V3m9 12v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}),t("path",{d:"m7 10l5 5l5-5"})])],-1)])],42,j1)):F("",!0),l.showFullscreenButton?(r(),u("button",{key:3,class:b(`${se} ${ae.value?"opacity-50 cursor-not-allowed":""}`),disabled:ae.value,onClick:Oe,onMouseenter:e[13]||(e[13]=o=>h(o,j.value?s(a)("common.minimize")||"Minimize":s(a)("common.open")||"Open")),onFocus:e[14]||(e[14]=o=>h(o,j.value?s(a)("common.minimize")||"Minimize":s(a)("common.open")||"Open")),onMouseleave:v,onBlur:v},[j.value?(r(),u("svg",E1,[...e[29]||(e[29]=[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6"},null,-1)])])):(r(),u("svg",P1,[...e[28]||(e[28]=[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6"},null,-1)])]))],42,L1)):F("",!0)]))])):F("",!0),t1(t("div",null,[k.value?(r(),u("div",z1,[t("pre",S1,X(z.value),1)])):(r(),u("div",Z1,[l.showZoomControls?(r(),u("div",V1,[t("div",D1,[t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:$e,onMouseenter:e[15]||(e[15]=o=>h(o,s(a)("common.zoomIn")||"Zoom in")),onFocus:e[16]||(e[16]=o=>h(o,s(a)("common.zoomIn")||"Zoom in")),onMouseleave:v,onBlur:v},[...e[30]||(e[30]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("circle",{cx:"11",cy:"11",r:"8"}),t("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])],32),t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:je,onMouseenter:e[17]||(e[17]=o=>h(o,s(a)("common.zoomOut")||"Zoom out")),onFocus:e[18]||(e[18]=o=>h(o,s(a)("common.zoomOut")||"Zoom out")),onMouseleave:v,onBlur:v},[...e[31]||(e[31]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("circle",{cx:"11",cy:"11",r:"8"}),t("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])],32),t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:Le,onMouseenter:e[19]||(e[19]=o=>h(o,s(a)("common.resetZoom")||"Reset zoom")),onFocus:e[20]||(e[20]=o=>h(o,s(a)("common.resetZoom")||"Reset zoom")),onMouseleave:v,onBlur:v},X(Math.round(100*M.value))+"% ",33)])])):F("",!0),t("div",{class:"infographic-preview relative transition-all overflow-hidden block",style:Ce({height:ce.value}),onMousedown:ee,onMousemove:ne,onMouseup:I,onMouseleave:I,onTouchstartPassive:ee,onTouchmovePassive:ne,onTouchendPassive:I},[L.value||S.value?F("",!0):(r(),u("pre",N1,X(z.value),1)),t("div",{class:b(["absolute inset-0 cursor-grab",{"cursor-grabbing":_.value}]),style:Ce(ze.value)},[t("div",{ref_key:"infographicContainer",ref:p,class:"w-full text-center flex items-center justify-center min-h-full"},null,512)],6)],36)]))],512),[[l1,!c.value]]),(r(),a1(c1,{to:"body"},[t("div",{class:b(["markstream-vue",{dark:l.isDark}])},[i1(u1,{name:"infographic-dialog",appear:""},{default:r1(()=>[j.value?(r(),u("div",{key:0,class:"infographic-modal-overlay fixed inset-0 z-50 flex items-center justify-center p-4",onClick:s1(ve,["self"])},[t("div",Y1,[t("div",_1,[t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:$e},[...e[32]||(e[32]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("circle",{cx:"11",cy:"11",r:"8"}),t("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])]),t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:je},[...e[33]||(e[33]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[t("circle",{cx:"11",cy:"11",r:"8"}),t("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])]),t("button",{class:"infographic-action-btn p-[var(--ms-action-btn-padding)] rounded",onClick:Le},X(Math.round(100*M.value))+"% ",1),t("button",{class:"infographic-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded",onClick:ve},[...e[34]||(e[34]=[t("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[t("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M18 6L6 18M6 6l12 12"})],-1)])])]),t("div",{ref_key:"modalContent",ref:D,class:b(["w-full h-full flex items-center justify-center p-4 overflow-hidden",{"cursor-grab":!_.value,"cursor-grabbing":_.value}]),onMousedown:ee,onMousemove:ne,onMouseup:I,onMouseleave:I,onTouchstartPassive:ee,onTouchmovePassive:ne,onTouchendPassive:I},null,34)])])):F("",!0)]),_:1})],2)]))],10,p1))}}),[["__scopeId","data-v-de34ec4b"]]);ke.install=R=>{R.component(ke.__name,ke)};export{ke as default}; diff --git a/apps/kimi-code/dist-web/assets/index11-Ci8_PlMN.js b/apps/kimi-code/dist-web/assets/index11-Ci8_PlMN.js new file mode 100644 index 000000000..6e0156958 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/index11-Ci8_PlMN.js @@ -0,0 +1,8 @@ +import{cq as _t,bQ as _n,M as Hn,c2 as Nn,c1 as In,b$ as Yn,c0 as qn,aU as f,bl as Wn,af as Xn,bY as Vn,bE as I,az as Un,c8 as wn,aD as Zn,as as Y,aI as Kn,aL as M,u as C,aY as Rt,v as u,bk as w,bb as Ke,au as ae,t as pe,aw as Ft,bL as Gn,bB as Jn,ar as yn,bd as kn,s as Qn,I as el,bJ as tl,bO as nl,g as ll,T as rl,q as F,c7 as xn,c5 as zt,cr as ol,cs as al,ct as il,cu as ul,cv as sl,b_ as cl,cw as dl}from"./index-D-7nOosq.js";import{i as At}from"./safeRaf-DGuzXxDK.js";function vl(d,m){return/(?:&#\d+|#\d+|&[a-z]+)$/i.test(d.slice(Math.max(0,m-12),m))}function Cn(d){return d.includes("->")||d.includes("-->")||d.includes("->>")||d.includes("-->>")||d.includes("-x")||d.includes("--x")||d.includes("-)")||d.includes("--)")||d.includes("-+")||d.includes("--+")}function fl(d){const m=d.trimStart();return/^(?:accDescr|accTitle|activate|actor|and|alt|autonumber|box|break|critical|create\s+(?:actor|participant)|deactivate|destroy|else|end|link|links|loop|Note|opt|option|par|participant|properties|rect)\b/i.test(m)||(function(y){const z=y.split(";",1)[0],a=z.indexOf(":");return a>0&&Cn(z.slice(0,a))})(m)}function ml(d){if(!d.includes(";"))return d;const m=d.indexOf(":");if(m===-1||!(function($,Q){const k=$.slice(0,Q);return/^\s*Note\b/i.test(k)||Cn(k)})(d,m))return d;const y=d.slice(0,m+1),z=d.slice(m+1),a=(function($){let Q="",k=!1;for(let P=0;P<$.length;P++){const ee=$[P];ee!==";"||vl($,P)||fl($.slice(P+1))?Q+=ee:(Q+="#59;",k=!0)}return k?Q:$})(z);return a===z?d:`${y}${a}`}function Lt(d){if(_t(d)!=="sequencediagram")return d;const m=d.split(/(\r\n|\n|\r)/);let y=!1;for(let z=0;z<m.length;z+=2){const a=m[z],$=ml(a);$!==a&&(m[z]=$,y=!0)}return y?m.join(""):d}var hl=Object.defineProperty,gl=Object.defineProperties,pl=Object.getOwnPropertyDescriptors,bn=Object.getOwnPropertySymbols,wl=Object.prototype.hasOwnProperty,yl=Object.prototype.propertyIsEnumerable,kl=Math.pow,Mn=(d,m,y)=>m in d?hl(d,m,{enumerable:!0,configurable:!0,writable:!0,value:y}):d[m]=y,Tn=(d,m)=>{for(var y in m||(m={}))wl.call(m,y)&&Mn(d,y,m[y]);if(bn)for(var y of bn(m))yl.call(m,y)&&Mn(d,y,m[y]);return d},T=(d,m,y)=>new Promise((z,a)=>{var $=P=>{try{k(y.next(P))}catch(ee){a(ee)}},Q=P=>{try{k(y.throw(P))}catch(ee){a(ee)}},k=P=>P.done?z(P.value):Promise.resolve(P.value).then($,Q);k((y=y.apply(d,m)).next())});const xl=["data-markstream-mode","data-markstream-pending"],bl={key:0,class:"mermaid-block-header flex items-center justify-between border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)]"},Ml={key:0},Tl={key:1,class:"flex items-center gap-x-2 overflow-hidden"},Cl=["innerHTML"],Bl={key:2},El={key:3,class:"mermaid-mode-toggle-group flex items-center gap-0.5"},Ol={class:"flex items-center gap-x-1"},Sl={class:"flex items-center gap-x-1"},$l={key:4},Pl={key:5,class:"mermaid-header-actions flex items-center"},Dl=["aria-pressed"],Rl={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},Fl={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},zl=["aria-label","disabled"],Al=["aria-label","disabled"],Ll={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},jl={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},_l={key:0,class:"mermaid-source-panel"},Hl={class:"mermaid-source-code text-sm font-mono whitespace-pre-wrap"},Nl={key:1,class:"relative"},Il={key:0,class:"absolute top-2 right-2 z-10 rounded-lg"},Yl={class:"flex items-center gap-2 backdrop-blur rounded-lg"},ql={class:"dialog-panel mermaid-modal-panel relative w-full h-full max-w-full max-h-full rounded overflow-hidden"},Wl={class:"absolute top-6 right-6 z-50 flex items-center gap-2"},pt="mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded",jt=_n(Hn({__name:"MermaidBlockNode",props:{node:{},maxHeight:{default:void 0},estimatedPreviewHeightPx:{},loading:{type:Boolean,default:!0},isDark:{type:Boolean},workerTimeoutMs:{default:1400},parseTimeoutMs:{default:1800},renderTimeoutMs:{default:2500},fullRenderTimeoutMs:{default:4e3},renderDebounceMs:{default:300},contentStableDelayMs:{default:500},previewPollDelayMs:{default:800},previewPollMaxDelayMs:{default:4e3},previewPollMaxAttempts:{default:12},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showFullscreenButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showZoomControls:{type:Boolean,default:!0},enableWheelZoom:{type:Boolean,default:!1},isStrict:{type:Boolean,default:!0},enableMermaidInteractions:{type:Boolean,default:!1},showTooltips:{type:Boolean,default:!0},onRenderError:{}},emits:["copy","export","openModal","toggleMode"],setup(d,{emit:m}){var y,z;const a=d,$=m,Q={USE_PROFILES:{svg:!0},FORBID_TAGS:["script"],FORBID_ATTR:[/^on/i],ADD_TAGS:["style"],ADD_ATTR:["style"],SAFE_FOR_TEMPLATES:!0},k=f(!1),P=f(typeof window>"u"),ee=Nn(),Ht=In(),Le=F(()=>a.isStrict?"strict":"loose"),Bn=F(()=>({startOnLoad:!1,securityLevel:Le.value,dompurifyConfig:Le.value==="strict"?Q:void 0,flowchart:Le.value==="strict"?{htmlLabels:!1}:void 0}));function we(e){if(e)try{e.replaceChildren()}catch{e.innerHTML=""}}function Ee(e,t,n={}){if(!e)return null;const l=(function(r,o){if(!r)return null;const c=sl(o);if(!c)return null;const h=(function(i,s){const p=Array.from(i.childNodes),E=document.createElement("div");return E.dataset.mermaidSvgLayer="1",E.style.zIndex="1",E.appendChild(s),i.insertBefore(E,i.firstChild),p.length>0&&(function(W){const j=()=>{var X;for(const J of W)(X=J.parentNode)==null||X.removeChild(J)};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(j)}):setTimeout(j,32)})(p),E})(r,c);return{svg:c.outerHTML,bindTarget:h}})(e,t);return l||n.keepPreviousOnFailure||we(e),l}let ie=null;function ye(e){if(a.enableMermaidInteractions&&e?.querySelector("svg"))try{ie?.(e)}catch{}}const{t:g}=Yn();let ue=!1,ke=0;function Ge(){return T(this,null,function*(){try{const e=yield il();return ue?null:(k.value=!!e,e)}catch(e){throw ue||(k.value=!1),e}finally{ue||(P.value=!0)}})}const Je=f(!1),V=f(!1),Qe=f(),Z=f(),v=f(),se=f(),et=f(null),En=qn(),je=f(null),xe=f(typeof window>"u"||!ee.value),On=Wn(),te=Xn(Vn,null);let ce="",be=0,tt=0;const Nt=F(()=>cl(a,On));function wt(){const e=Nt.value;e&&(ce&&ce!==e&&(te?.markSettled(ce),be=0),ce=e,be+=1,tt+=1,be===1&&te?.markPending(e))}function yt(){return T(this,null,function*(){const e=ce;if(!e||(be=Math.max(0,be-1),be>0))return;ce="";const t=++tt;yield Y(),t===tt&&((function(n=Nt.value){n&&Qe.value&&te?.reportHeight(n,Qe.value.offsetHeight)})(e),te?.markSettled(e))})}function It(){const e=ce;e&&(ce="",be=0,tt+=1,te?.markSettled(e))}const Yt=f(),D=F(()=>a.node.code.replace(/\]::([^:])/g,"]:::$1").replace(/:::subgraphNode$/gm,"::subgraphNode"));function Sn(e,t=D.value){const n=t,l={theme:e==="dark"?"dark":"default"};Le.value==="strict"&&(l.flowchart={htmlLabels:!1});const r=`%%{init: ${JSON.stringify(l)}}%% +`;return n.trim().startsWith("%%{")?n:r+n}function qt(){var e;return(function(t){const n=(function(){var r;const o=Z.value?getComputedStyle(Z.value).getPropertyValue("--ms-size-diagram-min-height").trim():"";return(r=zt(o))!=null?r:360})(),l=un();return ol(t,n,l)})((e=zt(a.estimatedPreviewHeightPx))!=null?e:al(D.value))}function Wt(){return`${qt()}px`}const _e=f(null);function kt(){var e;return!!((e=v.value)!=null&&e.querySelector("svg"))}function Xt(){return a.loading!==!1&&(kt()||!!_e.value)}const B=f(1),_=f(0),H=f(0),nt=f(!1),lt=f({x:0,y:0}),x=f(!0),rt=f(!1),re=f(!1),de=f(null);let xt="",bt=!1,ve="";const ot=f(0),Mt=f(!1),$n=F(()=>{var e;return Math.max(0,(e=a.renderDebounceMs)!=null?e:300)}),Pn=F(()=>{var e;return Math.max(0,(e=a.contentStableDelayMs)!=null?e:500)}),He=F(()=>{var e;return Math.max(120,(e=a.previewPollDelayMs)!=null?e:800)}),Dn=F(()=>{var e;return Math.max(He.value,(e=a.previewPollMaxDelayMs)!=null?e:4e3)}),Vt=F(()=>{var e;return Math.max(1,Math.trunc((e=a.previewPollMaxAttempts)!=null?e:12))}),fe=F(()=>a.loading!==!1);let Ne=null,Ie=null,Oe=null,Se=null,Ye=0;const Ut=(y=globalThis.requestIdleCallback)!=null?y:(e,t)=>setTimeout(()=>e({didTimeout:!0}),16),Zt=(z=globalThis.cancelIdleCallback)!=null?z:e=>clearTimeout(e);function b(e=ke){return!ue&&e===ke}function A(){return b()&&xe.value&&!V.value}function Tt(){Oe!=null&&(globalThis.clearTimeout(Oe),Oe=null),Se!=null&&(Zt(Se),Se=null)}function qe(){ue||Oe==null&&Se==null&&(Oe=globalThis.setTimeout(()=>{Oe=null,A()&&(Se=Ut(()=>{Se=null,A()&&gn()},{timeout:500}))},$n.value))}function We(){Ie!=null&&(globalThis.clearTimeout(Ie),Ie=null)}function Kt(e=600){if(typeof globalThis>"u"||ue)return;const t=Math.max(0,e);We(),Ie=globalThis.setTimeout(()=>{if(Ie=null,!ue){if(a.loading||re.value||!A())return void Kt(Math.min(1200,Math.max(300,1.2*t)));qe()}},t)}const q=f(Wt()),at=f(q.value);let $e=null;const O=f(!1),K=f(!1),me=f({}),he=f(0);let U=null,Pe=null;const N=f(!1),Rn=F(()=>{var e,t;return!(V.value||x.value||P.value&&!re.value&&!de.value&&(O.value||N.value&&((t=(e=v.value)==null?void 0:e.textContent)!=null&&t.trim())))}),Me=f({zoom:1,translateX:0,translateY:0,containerHeight:q.value}),Gt=F(()=>a.enableWheelZoom?{wheel:Fn}:{}),G=F(()=>{var e,t,n,l;return{worker:(e=a.workerTimeoutMs)!=null?e:1400,parse:(t=a.parseTimeoutMs)!=null?t:1800,render:(n=a.renderTimeoutMs)!=null?n:2500,fullRender:(l=a.fullRenderTimeoutMs)!=null?l:4e3}});let De=null,it=null,Re=!1,Te=He.value,ne=null,ut=0,Ct=!0,st=0;function Ce(e,t){const n=t?.timeoutMs,l=t?.signal;if(l?.aborted)return Promise.reject(new DOMException("Aborted","AbortError"));let r=null,o=!1,c=null;return new Promise((h,i)=>{const s=()=>{r!=null&&clearTimeout(r),c&&l&&l.removeEventListener("abort",c)};n&&n>0&&(r=globalThis.setTimeout(()=>{o||(o=!0,s(),i(new Error("Operation timed out")))},n)),l&&(c=()=>{o||(o=!0,s(),i(new DOMException("Aborted","AbortError")))},l.addEventListener("abort",c)),e().then(p=>{o||(o=!0,s(),h(p))}).catch(p=>{o||(o=!0,s(),i(p))})})}function Jt(e){if(typeof document>"u"||!v.value)return;if(typeof a.onRenderError=="function"&&a.onRenderError(e,D.value,v.value)===!0)return N.value=!0,void L();const t=document.createElement("div");t.style.padding="var(--ms-inset-panel-body)",t.style.color="hsl(var(--ms-destructive))",t.textContent="Failed to render diagram: ";const n=document.createElement("span");n.textContent=e instanceof Error?e.message:"Unknown error",t.appendChild(n),we(v.value),v.value.appendChild(t);const l=v.value?getComputedStyle(v.value).getPropertyValue("--ms-size-diagram-min-height").trim():"";q.value=l||"360px",at.value=q.value,N.value=!0,L()}function Qt(e){const t=typeof e=="string"?e:typeof e?.message=="string"?e.message:"";return typeof t=="string"&&/timed out/i.test(t)}function en(e){return e?.name==="AbortError"}function Bt(e){return!Qt(e)&&!en(e)}typeof window<"u"&&I([()=>Qe.value,ee],([e,t])=>{var n;if((n=je.value)==null||n.destroy(),je.value=null,!t||xe.value)return void(xe.value=!0);if(!e)return void(xe.value=!1);const l=En(e,{rootMargin:Ht?.value.heavyBlockMargin,allowIdle:!1});je.value=l,xe.value=l.isVisible.value,l.whenVisible.then(()=>{xe.value=!0})},{immediate:!0}),Un(()=>{var e;ue=!0,ke+=1,he.value+=1,(e=je.value)==null||e.destroy(),je.value=null,It(),Tt()});const ct=F(()=>a.showTooltips!==!1);function tn(e){return!e||e.disabled}function R(e,t,n="top"){if(!ct.value||tn(e.currentTarget))return;const l=e,r=l?.clientX!=null&&l?.clientY!=null?{x:l.clientX,y:l.clientY}:void 0;xn(e.currentTarget,t,n,!1,r,a.isDark)}function S(){ct.value&&wn()}function nn(e){if(!ct.value||tn(e.currentTarget))return;const t=Je.value?g("common.copied")||"Copied":g("common.copy")||"Copy",n=e,l=n?.clientX!=null&&n?.clientY!=null?{x:n.clientX,y:n.clientY}:void 0;xn(e.currentTarget,t,"top",!1,l,a.isDark)}function ln(e,t){const n={theme:t==="dark"?"dark":"default"};Le.value==="strict"&&(n.flowchart={htmlLabels:!1});const l=`%%{init: ${JSON.stringify(n)}}%% +`;return e.trimStart().startsWith("%%{")?e:l+e}function dt(){return Ct&&!x.value&&!O.value&&!N.value}function rn(e){const t=e.trim();return!(!t||t.startsWith("%%"))&&!/^(?:gantt|title|dateformat|axisformat|tickinterval|excludes|section|todaymarker|topaxis|weekday|weekend|acctitle|accdescr|accdescrmultiline)\b/i.test(t)&&t.includes(":")}function Et(e){if(_t(e)==="gantt")return(function(n){var l;const r=n.split(/\r?\n/);for(!/\r?\n$/.test(n)&&r.length>0&&r.pop();r.length>0;){const o=(l=r[r.length-1])==null?void 0:l.trim();if(o&&!o.startsWith("%%")){if(rn(o))break;r.pop()}else r.pop()}return r.some(rn)?r.join(` +`):""})(e);const t=e.split(/\r?\n/);for(;t.length>0;){const n=t[t.length-1].trimEnd();if(n!==""){if(!(/^[-=~>|<\s]+$/.test(n.trim())||/(?:--|==|~~|->|<-|-\||-\)|-x|o-|\|-|\.-)\s*$/.test(n)||/[-|><]$/.test(n)||/(?:graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt)\s*$/i.test(n)))break;t.pop()}else t.pop()}return t.join(` +`)}function on(e,t,n,l){return T(this,null,function*(){try{return yield Ce(()=>e.render(t,n),{timeoutMs:l})}catch(r){if(!Bt(r))throw r;const o=Lt(n);if(o===n)throw r;try{return yield Ce(()=>e.render(`${t}-retry`,o),{timeoutMs:l})}catch{throw r}}})}function vt(e,t,n){return T(this,null,function*(){var l;try{return yield dl(e,t,(l=n?.timeoutMs)!=null?l:G.value.worker,n?.signal)}catch(r){if(r?.name==="AbortError")throw r;const o=r?.code||r?.name;if(o!=="WORKER_BUSY"&&o!=="WORKER_TIMEOUT"&&o!=="WORKER_INIT_ERROR"&&o!=="MERMAID_DISABLED"&&o!=="WORKER_REPLACED"||r?.fallbackToRenderer)return yield(function(c,h,i){return T(this,null,function*(){var s,p,E,W;const j=yield Ge();if(!j)return;const X=j,J=ln(c,h);if(typeof X.parse=="function"){try{yield Ce(()=>X.parse(J),{timeoutMs:(s=i?.timeoutMs)!=null?s:G.value.parse,signal:i?.signal})}catch(oe){if(!Bt(oe))throw oe;const Ze=Lt(J);if(Ze===J)throw oe;try{yield Ce(()=>X.parse(Ze),{timeoutMs:(p=i?.timeoutMs)!=null?p:G.value.parse,signal:i?.signal})}catch{throw oe}}return!0}const Ue=`mermaid-parse-${Math.random().toString(36).slice(2,9)}`;try{yield Ce(()=>j.render(Ue,J),{timeoutMs:(E=i?.timeoutMs)!=null?E:G.value.render,signal:i?.signal})}catch(oe){if(!Bt(oe))throw oe;const Ze=Lt(J);if(Ze===J)throw oe;try{yield Ce(()=>j.render(`${Ue}-retry`,Ze),{timeoutMs:(W=i?.timeoutMs)!=null?W:G.value.render,signal:i?.signal})}catch{throw oe}}return!0})})(e,t,n);throw r}})}function an(e,t,n){return T(this,null,function*(){var l;if(_t(e)==="gantt"){const o=Et(e);if(!o.trim())return{fullOk:!1,prefixOk:!1};try{if(yield vt(o,t,n))return o===e?{fullOk:!0,prefixOk:!1}:{fullOk:!1,prefixOk:!0,prefix:o}}catch(c){if(c?.name==="AbortError")throw c}return{fullOk:!1,prefixOk:!1}}try{if(yield vt(e,t,n))return{fullOk:!0,prefixOk:!1}}catch(o){if(o?.name==="AbortError")throw o}let r=Et(e);if(r&&r.trim()&&r!==e)try{try{const o=yield ul(e,t,(l=n?.timeoutMs)!=null?l:G.value.worker,n?.signal);o&&o.trim()&&(r=o)}catch{}if(yield vt(r,t,n))return{fullOk:!1,prefixOk:!0,prefix:r}}catch(o){if(o?.name==="AbortError")throw o}return{fullOk:!1,prefixOk:!1}})}const ft=F(()=>x.value||re.value||V.value);function un(){if(a.maxHeight==="none")return null;if(a.maxHeight!=null){const t=Number.parseFloat(String(a.maxHeight));if(Number.isFinite(t))return t}const e=Z.value;if(e){const t=getComputedStyle(e).getPropertyValue("--ms-size-code-max-height").trim(),n=Number.parseFloat(t);if(Number.isFinite(n))return n}return 500}function Xe(e,t){if(!Z.value||!v.value)return;const n=!t?.force&&a.loading!==!1&&kt(),l=v.value.querySelector("svg");if(!l)return;let r=0,o=0;const c=l.getAttribute("viewBox"),h=l.getAttribute("width"),i=l.getAttribute("height");if(c){const s=c.split(" ");s.length===4&&(r=Number.parseFloat(s[2]),o=Number.parseFloat(s[3]))}if(r&&o||h&&i&&(r=Number.parseFloat(h),o=Number.parseFloat(i)),Number.isNaN(r)||Number.isNaN(o)||r<=0||o<=0)try{const s=l.getBBox();s&&s.width>0&&s.height>0&&(r=s.width,o=s.height)}catch(s){return void console.error("Failed to get SVG BBox:",s)}if(r>0&&o>0){const s=o/r,p=e??Z.value.clientWidth,E=l.getBoundingClientRect().width,W=E>0?E:p,j=un(),X=W*s,J=j==null?X:Math.min(X,j),Ue=Math.max(J,qt());at.value=`${Math.max(X,Ue)}px`,n||zt(a.estimatedPreviewHeightPx)!=null||(q.value=`${Ue}px`)}}const le=f(!1),Ot=F(()=>({transform:`translate(${_.value}px, ${H.value}px) scale(${B.value})`}));function sn(e){e.key==="Escape"&&le.value&&$t()}function St(){var e;if(!Z.value||!se.value)return!1;if(((e=se.value.firstElementChild)==null?void 0:e.getAttribute("data-mermaid-modal-clone"))==="1")return!0;const t=Z.value.cloneNode(!0);t.dataset.mermaidModalClone="1",t.classList.add("fullscreen"),t.style.height="100%",t.style.maxHeight="100%";const n=t.querySelector("._mermaid");n&&(n.style.contain="none",n.style.contentVisibility="visible");const l=t.querySelector("[data-mermaid-wrapper]");return l&&(et.value=l,l.style.transform=Ot.value.transform),we(se.value),se.value.appendChild(t),ye(t),!0}function $t(){if(le.value=!1,se.value&&we(se.value),et.value=null,typeof document<"u")try{document.body.style.overflow=""}catch{}if(typeof window<"u")try{window.removeEventListener("keydown",sn)}catch{}}function cn(){B.value<3&&(B.value+=.1)}function dn(){B.value>.5&&(B.value-=.1)}function vn(){B.value=1,_.value=0,H.value=0}function mt(e){nt.value=!0,e instanceof MouseEvent?lt.value={x:e.clientX-_.value,y:e.clientY-H.value}:lt.value={x:e.touches[0].clientX-_.value,y:e.touches[0].clientY-H.value}}function ht(e){if(!nt.value)return;let t,n;e instanceof MouseEvent?(t=e.clientX,n=e.clientY):(t=e.touches[0].clientX,n=e.touches[0].clientY),_.value=t-lt.value.x,H.value=n-lt.value.y}function Fe(){nt.value=!1}function Fn(e){if(a.enableWheelZoom&&(e.ctrlKey||e.metaKey)){if(e.preventDefault(),!Z.value)return;const t=Z.value.getBoundingClientRect(),n=e.clientX-t.left,l=e.clientY-t.top,r=n-t.width/2,o=l-t.height/2,c=(r-_.value)/B.value,h=(o-H.value)/B.value,i=.01,s=-e.deltaY*i,p=Math.min(Math.max(B.value+s,.5),3);p!==B.value&&(_.value=r-c*p,H.value=o-h*p,B.value=p)}}function zn(){return T(this,null,function*(){try{const e=D.value,t={payload:{type:"copy",text:e},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0}};if($("copy",t),t.defaultPrevented)return;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(e)),Je.value=!0,setTimeout(()=>{Je.value=!1},1e3)}catch(e){console.error("Failed to copy:",e)}})}function An(){var e;const t=(e=v.value)==null?void 0:e.querySelector("svg");if(!t)return void console.error("SVG element not found");const n=new XMLSerializer().serializeToString(t),l={payload:{type:"export"},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0},svgElement:t,svgString:n};$("export",l),l.defaultPrevented||(function(r,o=null){T(this,null,function*(){try{const c=o??new XMLSerializer().serializeToString(r),h=new Blob([c],{type:"image/svg+xml;charset=utf-8"}),i=URL.createObjectURL(h);if(typeof document<"u"){const s=document.createElement("a");s.href=i,s.download=`mermaid-diagram-${Date.now()}.svg`;try{document.body.appendChild(s),s.click(),document.body.removeChild(s)}catch{}URL.revokeObjectURL(i)}}catch(c){console.error("Failed to export SVG:",c)}})})(t,n)}function Ln(){var e,t;const n=(t=(e=v.value)==null?void 0:e.querySelector("svg"))!=null?t:null,l=n?new XMLSerializer().serializeToString(n):null,r={payload:{type:"open-modal"},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0},svgElement:n,svgString:l};$("openModal",r),r.defaultPrevented||(function(){if(le.value=!0,typeof document<"u")try{document.body.style.overflow="hidden"}catch{}if(typeof window<"u")try{window.addEventListener("keydown",sn)}catch{}Y(()=>{St()||Y(St)})})()}function fn(e){const t={payload:{type:"toggle-mode",target:e},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0}};$("toggleMode",e,t),t.defaultPrevented||mn(e)}function mn(e){return T(this,null,function*(){const t=Yt.value;if(!t)return rt.value=!0,void(x.value=e==="source");const n=t.getBoundingClientRect().height;t.style.height=`${n}px`,t.style.overflow="hidden",rt.value=!0,x.value=e==="source",yield Y();const l=t.scrollHeight;t.style.transition="height var(--ms-duration-standard) var(--ms-ease-standard)",t.offsetHeight,t.style.height=`${l}px`;const r=()=>{t.style.transition="",t.style.height="",t.style.overflow="",t.removeEventListener("transitionend",o)};function o(){r()}t.addEventListener("transitionend",o),setTimeout(()=>r(),220)})}function ge(e=D.value,t=a.isDark?"dark":"light",n=a.loading===!1){return{code:e,codeWithTheme:Sn(t,e),final:n,signature:`${t}\0${e}`,theme:t}}function ze(e){return e.signature===ge().signature}function Be(){return T(this,arguments,function*(e=ge()){const t=ke;if(!b(t)||!ze(e))return!1;if(re.value){const n=de.value,l=bt,r=xt;if(!n)return!1;const o=yield n;return!(!b(t)||!ze(e))&&(r===e.signature?!(!o||ve!==e.signature)||!(!e.final||a.loading!==!1||l)&&Be(e):Be(e))}if(!v.value){if(yield Y(),!b(t))return!1;if(!v.value)return console.warn("Mermaid container not ready"),!1}return!(!b(t)||!ze(e))&&(re.value=!0,bt=e.final,xt=e.signature,wt(),de.value=T(null,null,function*(){var n,l,r,o;try{const c=yield Ge();if(!b(t)||!c)return!1;const h=`mermaid-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;O.value||K.value||(n=c.initialize)==null||n.call(c,(r=Tn({},Bn.value),o={dompurifyConfig:Tn({},Q)},gl(r,pl(o))));const i=yield on(c,h,e.codeWithTheme,G.value.fullRender);if(!b(t)||!(function(E){return ze(E)||!E.final&&a.loading!==!1&&D.value.startsWith(E.code)})(e))return K.value&&(K.value=!1),!1;if(!v.value)return!1;const s=Ee(v.value,i?.svg,{keepPreviousOnFailure:!e.final||a.loading!==!1});if(!s)return K.value&&(K.value=!1),!1;const p=(l=i?.bindFunctions)!=null?l:null;return ie=p,ye(s.bindTarget),O.value||K.value||(At(()=>Xe()),O.value=!0,Me.value={zoom:B.value,translateX:_.value,translateY:H.value,containerHeight:q.value}),me.value[e.theme]={svg:s.svg,bindFunctions:p},K.value&&(K.value=!1),ve=e.signature,_e.value=v.value.innerHTML,N.value=!1,Ye=0,We(),!0}catch(c){if(!b(t)||!ze(e))return K.value&&(K.value=!1),!1;const h=Qt(c),i=Ye+1;return h&&i<=3?(Ye=i,Kt(Math.min(1200,600*i))):(Ye=0,We(),e.final&&a.loading===!1&&console.error("Failed to render mermaid diagram:",c),e.final&&a.loading===!1&&Jt(c)),!1}finally{bt=!1,xt="",re.value=!1,de.value=null,b(t)&&yt()}}),de.value)})}function Ae(){return T(this,null,function*(){var e;const t=D.value;if(!t.trim())return Xt()?void 0:(v.value&&we(v.value),_e.value=null,ve="",void(N.value=!1));if(!k.value||!A())return;const n=ge(t);O.value&&n.signature===ve&&((e=v.value)!=null&&e.querySelector("svg"))||(yield Be(n))&&(N.value=!1)})}function hn(e,t,n,l){return T(this,null,function*(){const r=ke;if(!b(r)||!dt()||!v.value&&(yield Y(),!b(r)||!v.value)||re.value)return;re.value=!0,wt();const o=ge(t,n),c=T(null,null,function*(){var h;try{const i=yield Ge();if(!b(r)||!i)return!1;const s=`mermaid-partial-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,p=Et(e),E=p&&p.trim()?p:e,W=yield on(i,s,ln(E,n),G.value.render);if(!b(r)||he.value!==l||a.loading===!1||!dt()||!ze(o))return!1;const j=W?.svg;if(!v.value||!j)return!1;const X=Ee(v.value,j,{keepPreviousOnFailure:!0});return!!X&&(ie=(h=W?.bindFunctions)!=null?h:null,ye(X.bindTarget),At(()=>Xe()),!1)}catch{return!1}finally{de.value===c&&(re.value=!1,de.value=null),b(r)&&yt()}});return de.value=c,c})}function gn(){return T(this,null,function*(){var e;if(!A())return;const t=ke,n=Date.now(),l=++he.value;wt();try{U&&U.abort(),U=new AbortController;const r=U.signal,o=a.isDark?"dark":"light",c=D.value;if(!c.trim())return Xt()?void 0:(v.value&&we(v.value),_e.value=null,ve="",void(N.value=!1));if(ge(c,o).signature===ve)return;try{const i=yield an(c,o,{signal:r,timeoutMs:G.value.worker});if(!b(t))return;if(i.fullOk)return r.aborted||he.value!==l||!(yield Be(ge(c,o)))?void 0:void(b(t)&&he.value===l&&(N.value=!1));const s=ut&&n<=ut;if(i.prefixOk&&i.prefix&&!r.aborted&&he.value===l&&dt()&&!s)return void(yield hn(i.prefix,c,o,l))}catch(i){if(i?.name==="AbortError")return}if(!b(t)||he.value!==l||N.value)return;const h=me.value[o];if(h&&v.value){const i=Ee(v.value,h.svg);i&&(ie=(e=h.bindFunctions)!=null?e:null,ye(i.bindTarget))}}finally{b(t)&&yt()}})}function L(){Re&&(Re=!1,Te=He.value,Ct=!1,ne&&(ne.abort(),ne=null),De&&(globalThis.clearTimeout(De),De=null),it&&(Zt(it),it=null),ut=Date.now())}function Ve(){if(L(),Tt(),U){try{U.abort()}catch{}U=null}if(ne){try{ne.abort()}catch{}ne=null}We(),Ye=0}function Pt(){Pe?.abort(),Pe=null}function Dt(e=He.value){Re&&(st>=Vt.value?L():(De&&globalThis.clearTimeout(De),De=globalThis.setTimeout(()=>{it=Ut(()=>T(null,null,function*(){if(!Re)return;if(!A()||x.value||O.value)return void L();const t=a.isDark?"dark":"light",n=D.value;if(!n.trim())return a.loading===!1?void L():void Dt(Te);if(st++,st>Vt.value)L();else{ne&&ne.abort(),ne=new AbortController;try{const l=yield an(n,t,{signal:ne.signal,timeoutMs:G.value.worker});if(l.fullOk){if((yield Be(ge(n,t)))&&O.value)return void L()}else l.prefixOk&&l.prefix&&dt()&&(yield hn(l.prefix,n,t,he.value))}catch{}Te=Math.min(Math.floor(1.5*Te),Dn.value),Dt(Te)}}),{timeout:500})},e)))}function gt(){Re||fe.value&&k.value&&A()&&(x.value||O.value||(Re=!0,ut=0,Ct=!0,st=0,Te=He.value,Dt(Te)))}function pn(){return T(this,null,function*(){const e=ke;b(e)&&(yield Ge().catch(t=>{b(e)&&(k.value=!1,console.warn("[markstream-vue] Failed to initialize mermaid renderer. Call enableMermaid() to configure a loader.",t))}),b(e)&&(yield Y(),b(e)&&(rt.value||(x.value=!k.value),A()&&(fe.value?(qe(),ot.value=D.value.length):x.value||Ae()))))})}return I(se,e=>{le.value&&e&&St()}),I(Ot,e=>{le.value&&et.value&&(et.value.style.transform=e.transform)},{immediate:!0}),I(ct,e=>{e||wn()}),I(()=>D.value,e=>{if((e.trim()||a.loading===!1)&&(O.value=!1,me.value={}),!fe.value)return L(),void(A()&&!x.value&&Ae());A()&&qe(),!x.value&&k.value&&A()?gt():L(),(function(){if(!fe.value||!x.value||!k.value)return;const t=D.value.length;t!==ot.value&&(Mt.value=!0,ot.value=t,Ne&&clearTimeout(Ne),Ne=setTimeout(()=>{Mt.value&&x.value&&D.value.trim()&&(Mt.value=!1,mn("preview"))},Pn.value))})()}),I(()=>a.isDark,()=>T(null,null,function*(){var e;if(N.value)return;const t=a.isDark?"dark":"light",n=me.value[t];if(n){if(v.value){const o=Ee(v.value,n.svg);o&&(ie=(e=n.bindFunctions)!=null?e:null,ye(o.bindTarget))}return}const l={zoom:B.value,translateX:_.value,translateY:H.value,containerHeight:q.value},r=B.value!==1||_.value!==0||H.value!==0;K.value=!0,r&&(B.value=1,_.value=0,H.value=0,yield Y()),yield Be(),r&&(yield Y(),B.value=l.zoom,_.value=l.translateX,H.value=l.translateY,q.value=l.containerHeight,Me.value=l)})),I(()=>x.value,e=>T(null,null,function*(){var t;if(e)L(),O.value&&(Me.value={zoom:B.value,translateX:_.value,translateY:H.value,containerHeight:q.value});else{if(N.value)return;const n=a.isDark?"dark":"light";if(O.value&&me.value[n]){if(yield Y(),v.value){const l=me.value[n],r=Ee(v.value,l.svg);r&&(ie=(t=l.bindFunctions)!=null?t:null,ye(r.bindTarget))}return B.value=Me.value.zoom,_.value=Me.value.translateX,H.value=Me.value.translateY,void(q.value=Me.value.containerHeight)}if(yield Y(),!k.value||!A())return;if(!fe.value)return L(),void(yield Ae());gt(),yield gn()}})),I(()=>a.loading,(e,t)=>T(null,null,function*(){var n;if(e)Pt();else if(t===!0){Pt();const l=D.value,r=l.trim();if(!r)return v.value&&we(v.value),_e.value=null,ve="",N.value=!1,Ve();if(!A())return void Ve();const o=a.isDark?"dark":"light",c=ge(l,o);if(O.value&&c.signature===ve){if(yield Y(),v.value&&!v.value.querySelector("svg")&&me.value[o]){const i=me.value[o],s=Ee(v.value,i.svg);s&&(ie=(n=i.bindFunctions)!=null?n:null,ye(s.bindTarget))}return Xe(void 0,{force:!0}),void Ve()}const h=new AbortController;Pe=h;try{let i=0;for(;;)try{yield vt(r,o,{signal:h.signal,timeoutMs:G.value.worker});break}catch(s){const p=s?.code==="WORKER_BUSY"||s?.code==="WORKER_TIMEOUT",E=s?.code==="WORKER_TIMEOUT"?2:8;if(!p||i>=E)throw s;const W=Math.min(50*kl(2,i),400);i++,yield Ce(()=>new Promise(j=>setTimeout(j,W)),{signal:h.signal})}if(!(yield Be(c)))return;N.value=!1,Ve()}catch(i){if(en(i))return;Ve(),Jt(i)}finally{Pe===h&&(Pe=null)}}})),I(Z,e=>{$e&&$e.disconnect(),e&&($e=new ResizeObserver(t=>{t&&t.length>0&&!x.value&&!V.value&&At(()=>{Xe(t[0].contentRect.width)})}),$e.observe(e))},{immediate:!0}),Zn(()=>{ee.value&&!A()||pn()}),I(()=>k.value,e=>{rt.value||(x.value=!e)}),I(()=>a.maxHeight,()=>{Y(()=>{Xe()})}),I([()=>a.estimatedPreviewHeightPx,()=>D.value],()=>{O.value||kt()||x.value||(q.value=Wt(),at.value=q.value)}),I(()=>xe.value,e=>T(null,null,function*(){e&&(P.value?(O.value||(fe.value?(qe(),ot.value=D.value.length):Ae()),a.loading||O.value||Ae(),!x.value&&k.value&&fe.value&>()):yield pn())}),{immediate:!1}),Kn(()=>{Ne&&clearTimeout(Ne),Tt(),$e&&$e.disconnect(),U&&(U.abort(),U=null),Pt(),L(),We(),It()}),I(()=>V.value,e=>T(null,null,function*(){e?(L(),U&&U.abort()):A()&&!O.value&&(yield Y(),fe.value?(qe(),gt()):x.value||Ae())}),{immediate:!1}),(e,t)=>(M(),C("div",{ref_key:"blockContainer",ref:Qe,class:ae(["mermaid-block-container rounded-lg border overflow-hidden",[{"is-rendering":a.loading,dark:a.isDark}]]),"data-markstream-mermaid":"1","data-markstream-mode":x.value?"fallback":O.value?"preview":"pending","data-markstream-pending":Rn.value?"true":void 0},[a.showHeader?(M(),C("div",bl,[e.$slots["header-left"]?(M(),C("div",Ml,[Rt(e.$slots,"header-left",{},void 0,!0)])):(M(),C("div",Tl,[u("span",{class:"icon-slot action-icon shrink-0",innerHTML:w(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> + <path fill="none" stroke="#ca9ee6" stroke-linecap="round" stroke-linejoin="round" d="M1.5 2.5c0 6 2.25 5.75 4 7 .83.67 1.17 2 1 4h3c-.17-2 .17-3.33 1-4 1.75-1.25 4-1 4-7C12 2.5 10 3 8 7 6 3 4 2.5 1.5 2.5" /> +</svg> +`)},null,8,Cl),t[21]||(t[21]=u("span",{class:"mermaid-label-text text-[length:var(--ms-text-label)] font-medium font-mono truncate"},"Mermaid",-1))])),e.$slots["header-center"]?(M(),C("div",Bl,[Rt(e.$slots,"header-center",{},void 0,!0)])):a.showModeToggle&&k.value?(M(),C("div",El,[u("button",{class:ae(["mermaid-mode-btn px-2 py-0.5 rounded transition-colors",[x.value?"":"is-active"]]),onClick:t[0]||(t[0]=()=>fn("preview")),onMouseenter:t[1]||(t[1]=n=>R(n,w(g)("common.preview")||"Preview")),onFocus:t[2]||(t[2]=n=>R(n,w(g)("common.preview")||"Preview")),onMouseleave:S,onBlur:S},[u("div",Ol,[t[22]||(t[22]=u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("path",{d:"M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"}),u("circle",{cx:"12",cy:"12",r:"3"})])],-1)),u("span",null,Ke(w(g)("common.preview")||"Preview"),1)])],34),u("button",{class:ae(["mermaid-mode-btn px-2 py-0.5 rounded transition-colors",[x.value?"is-active":""]]),onClick:t[3]||(t[3]=()=>fn("source")),onMouseenter:t[4]||(t[4]=n=>R(n,w(g)("common.source")||"Source")),onFocus:t[5]||(t[5]=n=>R(n,w(g)("common.source")||"Source")),onMouseleave:S,onBlur:S},[u("div",Sl,[t[23]||(t[23]=u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m16 18l6-6l-6-6M8 6l-6 6l6 6"})],-1)),u("span",null,Ke(w(g)("common.source")||"Source"),1)])],34)])):pe("",!0),e.$slots["header-right"]?(M(),C("div",$l,[Rt(e.$slots,"header-right",{},void 0,!0)])):(M(),C("div",Pl,[a.showCollapseButton?(M(),C("button",{key:0,class:ae(pt),"aria-pressed":V.value,onClick:t[6]||(t[6]=n=>V.value=!V.value),onMouseenter:t[7]||(t[7]=n=>R(n,V.value?w(g)("common.expand")||"Expand":w(g)("common.collapse")||"Collapse")),onFocus:t[8]||(t[8]=n=>R(n,V.value?w(g)("common.expand")||"Expand":w(g)("common.collapse")||"Collapse")),onMouseleave:S,onBlur:S},[(M(),C("svg",{style:Ft({rotate:V.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...t[24]||(t[24]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,Dl)):pe("",!0),a.showCopyButton?(M(),C("button",{key:1,class:ae(pt),onClick:zn,onMouseenter:t[9]||(t[9]=n=>nn(n)),onFocus:t[10]||(t[10]=n=>nn(n)),onMouseleave:S,onBlur:S},[Je.value?(M(),C("svg",Fl,[...t[26]||(t[26]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(M(),C("svg",Rl,[...t[25]||(t[25]=[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),u("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],32)):pe("",!0),a.showExportButton&&k.value?(M(),C("button",{key:2,class:ae(`${pt} ${ft.value?"opacity-50 cursor-not-allowed":""}`),"aria-label":w(g)("common.export")||"Export",disabled:ft.value,onClick:An,onMouseenter:t[11]||(t[11]=n=>R(n,w(g)("common.export")||"Export")),onFocus:t[12]||(t[12]=n=>R(n,w(g)("common.export")||"Export")),onMouseleave:S,onBlur:S},[...t[27]||(t[27]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("path",{d:"M12 15V3m9 12v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}),u("path",{d:"m7 10l5 5l5-5"})])],-1)])],42,zl)):pe("",!0),a.showFullscreenButton&&k.value?(M(),C("button",{key:3,class:ae(`${pt} ${ft.value?"opacity-50 cursor-not-allowed":""}`),"aria-label":le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open",disabled:ft.value,onClick:Ln,onMouseenter:t[13]||(t[13]=n=>R(n,le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open")),onFocus:t[14]||(t[14]=n=>R(n,le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open")),onMouseleave:S,onBlur:S},[le.value?(M(),C("svg",jl,[...t[29]||(t[29]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6"},null,-1)])])):(M(),C("svg",Ll,[...t[28]||(t[28]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6"},null,-1)])]))],42,Al)):pe("",!0)]))])):pe("",!0),Gn(u("div",{ref_key:"modeContainerRef",ref:Yt},[x.value?(M(),C("div",_l,[u("pre",Hl,Ke(D.value),1)])):(M(),C("div",Nl,[a.showZoomControls?(M(),C("div",Il,[u("div",Yl,[u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:cn,onMouseenter:t[15]||(t[15]=n=>R(n,w(g)("common.zoomIn")||"Zoom in")),onFocus:t[16]||(t[16]=n=>R(n,w(g)("common.zoomIn")||"Zoom in")),onMouseleave:S,onBlur:S},[...t[30]||(t[30]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])],32),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:dn,onMouseenter:t[17]||(t[17]=n=>R(n,w(g)("common.zoomOut")||"Zoom out")),onFocus:t[18]||(t[18]=n=>R(n,w(g)("common.zoomOut")||"Zoom out")),onMouseleave:S,onBlur:S},[...t[31]||(t[31]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])],32),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] text-[length:var(--ms-text-label)] rounded transition-colors",onClick:vn,onMouseenter:t[19]||(t[19]=n=>R(n,w(g)("common.resetZoom")||"Reset zoom")),onFocus:t[20]||(t[20]=n=>R(n,w(g)("common.resetZoom")||"Reset zoom")),onMouseleave:S,onBlur:S},Ke(Math.round(100*B.value))+"% ",33)])])):pe("",!0),u("div",yn({ref_key:"mermaidContainer",ref:Z,class:"mermaid-preview-area relative overflow-hidden block transition-[height] ease-out",style:{height:q.value}},kn(Gt.value,!0),{onMousedown:mt,onMousemove:ht,onMouseup:Fe,onMouseleave:Fe,onTouchstartPassive:mt,onTouchmovePassive:ht,onTouchendPassive:Fe}),[u("div",{"data-mermaid-wrapper":"",class:ae(["absolute inset-0 cursor-grab",{"cursor-grabbing":nt.value}]),style:Ft(Ot.value)},[u("div",{ref_key:"mermaidContent",ref:v,class:"_mermaid w-full text-center flex items-center justify-center min-h-full",style:Ft({height:at.value})},null,4)],6)],16),(M(),Qn(rl,{to:"body"},[u("div",{class:ae(["markstream-vue",{dark:a.isDark}])},[el(ll,{name:"mermaid-dialog",appear:""},{default:tl(()=>[le.value?(M(),C("div",{key:0,class:"mermaid-modal-overlay fixed inset-0 z-50 flex items-center justify-center p-4",onClick:nl($t,["self"])},[u("div",ql,[u("div",Wl,[u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:cn},[...t[32]||(t[32]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])]),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:dn},[...t[33]||(t[33]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])]),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] text-[length:var(--ms-text-label)] rounded transition-colors",onClick:vn},Ke(Math.round(100*B.value))+"% ",1),u("button",{class:"mermaid-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:$t},[...t[34]||(t[34]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M18 6L6 18M6 6l12 12"})],-1)])])]),u("div",yn({ref_key:"modalContent",ref:se,class:"w-full h-full flex items-center justify-center p-4 overflow-hidden"},kn(Gt.value,!0),{onMousedown:mt,onMousemove:ht,onMouseup:Fe,onMouseleave:Fe,onTouchstartPassive:mt,onTouchmovePassive:ht,onTouchendPassive:Fe}),null,16)])])):pe("",!0)]),_:1})],2)]))]))],512),[[Jn,!V.value]])],10,xl))}}),[["__scopeId","data-v-0aff75e3"]]);jt.install=d=>{d.component(jt.__name,jt)};export{jt as default}; diff --git a/apps/kimi-code/dist-web/assets/index11-DwTakJcU.js b/apps/kimi-code/dist-web/assets/index11-DwTakJcU.js deleted file mode 100644 index d5f57d74d..000000000 --- a/apps/kimi-code/dist-web/assets/index11-DwTakJcU.js +++ /dev/null @@ -1,8 +0,0 @@ -import{cq as _t,bQ as _n,M as Hn,c2 as Nn,c1 as In,b$ as Yn,c0 as qn,aU as m,bl as Wn,af as Xn,bY as Vn,bE as Y,az as Un,c8 as wn,aD as Zn,as as q,aI as Kn,aL as M,u as B,aY as Rt,v as u,bk as w,bb as Ze,au as ae,t as pe,aw as Ft,bL as Gn,bB as Jn,ar as yn,bd as kn,s as Qn,I as el,bJ as tl,bO as nl,g as ll,T as rl,q as F,c7 as xn,c5 as zt,cr as ol,cs as al,ct as il,cu as ul,cv as sl,b_ as cl,cw as dl}from"./index-D1h84VfZ.js";import{i as Lt}from"./safeRaf-DGuzXxDK.js";function vl(d,f){return/(?:&#\d+|#\d+|&[a-z]+)$/i.test(d.slice(Math.max(0,f-12),f))}function Cn(d){return d.includes("->")||d.includes("-->")||d.includes("->>")||d.includes("-->>")||d.includes("-x")||d.includes("--x")||d.includes("-)")||d.includes("--)")||d.includes("-+")||d.includes("--+")}function ml(d){const f=d.trimStart();return/^(?:accDescr|accTitle|activate|actor|and|alt|autonumber|box|break|critical|create\s+(?:actor|participant)|deactivate|destroy|else|end|link|links|loop|Note|opt|option|par|participant|properties|rect)\b/i.test(f)||(function(y){const z=y.split(";",1)[0],a=z.indexOf(":");return a>0&&Cn(z.slice(0,a))})(f)}function fl(d){if(!d.includes(";"))return d;const f=d.indexOf(":");if(f===-1||!(function($,Q){const k=$.slice(0,Q);return/^\s*Note\b/i.test(k)||Cn(k)})(d,f))return d;const y=d.slice(0,f+1),z=d.slice(f+1),a=(function($){let Q="",k=!1;for(let P=0;P<$.length;P++){const ee=$[P];ee!==";"||vl($,P)||ml($.slice(P+1))?Q+=ee:(Q+="#59;",k=!0)}return k?Q:$})(z);return a===z?d:`${y}${a}`}function At(d){if(_t(d)!=="sequencediagram")return d;const f=d.split(/(\r\n|\n|\r)/);let y=!1;for(let z=0;z<f.length;z+=2){const a=f[z],$=fl(a);$!==a&&(f[z]=$,y=!0)}return y?f.join(""):d}var hl=Object.defineProperty,gl=Object.defineProperties,pl=Object.getOwnPropertyDescriptors,bn=Object.getOwnPropertySymbols,wl=Object.prototype.hasOwnProperty,yl=Object.prototype.propertyIsEnumerable,kl=Math.pow,Mn=(d,f,y)=>f in d?hl(d,f,{enumerable:!0,configurable:!0,writable:!0,value:y}):d[f]=y,Tn=(d,f)=>{for(var y in f||(f={}))wl.call(f,y)&&Mn(d,y,f[y]);if(bn)for(var y of bn(f))yl.call(f,y)&&Mn(d,y,f[y]);return d},T=(d,f,y)=>new Promise((z,a)=>{var $=P=>{try{k(y.next(P))}catch(ee){a(ee)}},Q=P=>{try{k(y.throw(P))}catch(ee){a(ee)}},k=P=>P.done?z(P.value):Promise.resolve(P.value).then($,Q);k((y=y.apply(d,f)).next())});const xl=["data-markstream-mode","data-markstream-pending"],bl={key:0,class:"mermaid-block-header flex items-center justify-between border-b px-[var(--ms-inset-panel-x)] py-[var(--ms-inset-panel-y)]"},Ml={key:0},Tl={key:1,class:"flex items-center gap-x-2 overflow-hidden"},Cl=["innerHTML"],Bl={key:2},El={key:3,class:"mermaid-mode-toggle-group flex items-center gap-0.5"},Ol={class:"flex items-center gap-x-1"},Sl={class:"flex items-center gap-x-1"},$l={key:4},Pl={key:5,class:"mermaid-header-actions flex items-center"},Dl=["aria-pressed"],Rl={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},Fl={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},zl=["aria-label","disabled"],Ll=["aria-label","disabled"],Al={key:0,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},jl={key:1,xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},_l={key:0,class:"mermaid-source-panel"},Hl={class:"mermaid-source-code text-sm font-mono whitespace-pre-wrap"},Nl={key:1,class:"relative"},Il={key:0,class:"absolute top-2 right-2 z-10 rounded-lg"},Yl={class:"flex items-center gap-2 backdrop-blur rounded-lg"},ql={class:"dialog-panel mermaid-modal-panel relative w-full h-full max-w-full max-h-full rounded overflow-hidden"},Wl={class:"absolute top-6 right-6 z-50 flex items-center gap-2"},pt="mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded",jt=_n(Hn({__name:"MermaidBlockNode",props:{node:{},maxHeight:{default:void 0},estimatedPreviewHeightPx:{},loading:{type:Boolean,default:!0},isDark:{type:Boolean},workerTimeoutMs:{default:1400},parseTimeoutMs:{default:1800},renderTimeoutMs:{default:2500},fullRenderTimeoutMs:{default:4e3},renderDebounceMs:{default:300},contentStableDelayMs:{default:500},previewPollDelayMs:{default:800},previewPollMaxDelayMs:{default:4e3},previewPollMaxAttempts:{default:12},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showFullscreenButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showZoomControls:{type:Boolean,default:!0},enableWheelZoom:{type:Boolean,default:!1},isStrict:{type:Boolean,default:!0},enableMermaidInteractions:{type:Boolean,default:!1},showTooltips:{type:Boolean,default:!0},onRenderError:{}},emits:["copy","export","openModal","toggleMode"],setup(d,{emit:f}){var y,z;const a=d,$=f,Q={USE_PROFILES:{svg:!0},FORBID_TAGS:["script"],FORBID_ATTR:[/^on/i],ADD_TAGS:["style","br"],ADD_ATTR:["style"],SAFE_FOR_TEMPLATES:!0},k=m(!1),P=m(typeof window>"u"),ee=Nn(),Ht=In(),Ee=F(()=>a.isStrict?"strict":"loose"),Bn=F(()=>({startOnLoad:!1,securityLevel:Ee.value,dompurifyConfig:Ee.value==="strict"?Q:void 0,htmlLabels:Ee.value!=="strict"&&void 0,flowchart:Ee.value==="strict"?{htmlLabels:!1}:void 0}));function we(e){if(e)try{e.replaceChildren()}catch{e.innerHTML=""}}function Oe(e,t,n={}){if(!e)return null;const l=(function(r,o){if(!r)return null;const c=sl(o);if(!c)return null;const h=(function(i,s){const p=Array.from(i.childNodes),E=document.createElement("div");return E.dataset.mermaidSvgLayer="1",E.style.zIndex="1",E.appendChild(s),i.insertBefore(E,i.firstChild),p.length>0&&(function(W){const j=()=>{var U;for(const J of W)(U=J.parentNode)==null||U.removeChild(J)};typeof requestAnimationFrame=="function"?requestAnimationFrame(()=>{requestAnimationFrame(j)}):setTimeout(j,32)})(p),E})(r,c);return{svg:c.outerHTML,bindTarget:h}})(e,t);return l||n.keepPreviousOnFailure||we(e),l}let ie=null;function ye(e){if(a.enableMermaidInteractions&&e?.querySelector("svg"))try{ie?.(e)}catch{}}const{t:g}=Yn();let ue=!1,ke=0;function Ke(){return T(this,null,function*(){try{const e=yield il();return ue?null:(k.value=!!e,e)}catch(e){throw ue||(k.value=!1),e}finally{ue||(P.value=!0)}})}const Ge=m(!1),X=m(!1),Je=m(),Z=m(),v=m(),se=m(),Qe=m(null),En=qn(),je=m(null),xe=m(typeof window>"u"||!ee.value),On=Wn(),te=Xn(Vn,null);let ce="",be=0,et=0;const Nt=F(()=>cl(a,On));function wt(){const e=Nt.value;e&&(ce&&ce!==e&&(te?.markSettled(ce),be=0),ce=e,be+=1,et+=1,be===1&&te?.markPending(e))}function yt(){return T(this,null,function*(){const e=ce;if(!e||(be=Math.max(0,be-1),be>0))return;ce="";const t=++et;yield q(),t===et&&((function(n=Nt.value){n&&Je.value&&te?.reportHeight(n,Je.value.offsetHeight)})(e),te?.markSettled(e))})}function It(){const e=ce;e&&(ce="",be=0,et+=1,te?.markSettled(e))}const Yt=m(),D=F(()=>a.node.code.replace(/\]::([^:])/g,"]:::$1").replace(/:::subgraphNode$/gm,"::subgraphNode"));function Sn(e,t=D.value){const n=t,l={theme:e==="dark"?"dark":"default"};Ee.value==="strict"&&(l.htmlLabels=!1,l.flowchart={htmlLabels:!1});const r=`%%{init: ${JSON.stringify(l)}}%% -`;return n.trim().startsWith("%%{")?n:r+n}function qt(){var e;return(function(t){const n=(function(){var r;const o=Z.value?getComputedStyle(Z.value).getPropertyValue("--ms-size-diagram-min-height").trim():"";return(r=zt(o))!=null?r:360})(),l=un();return ol(t,n,l)})((e=zt(a.estimatedPreviewHeightPx))!=null?e:al(D.value))}function Wt(){return`${qt()}px`}const _e=m(null);function kt(){var e;return!!((e=v.value)!=null&&e.querySelector("svg"))}function Xt(){return a.loading!==!1&&(kt()||!!_e.value)}const C=m(1),_=m(0),H=m(0),tt=m(!1),nt=m({x:0,y:0}),x=m(!0),lt=m(!1),re=m(!1),de=m(null);let xt="",bt=!1,ve="";const rt=m(0),Mt=m(!1),$n=F(()=>{var e;return Math.max(0,(e=a.renderDebounceMs)!=null?e:300)}),Pn=F(()=>{var e;return Math.max(0,(e=a.contentStableDelayMs)!=null?e:500)}),He=F(()=>{var e;return Math.max(120,(e=a.previewPollDelayMs)!=null?e:800)}),Dn=F(()=>{var e;return Math.max(He.value,(e=a.previewPollMaxDelayMs)!=null?e:4e3)}),Vt=F(()=>{var e;return Math.max(1,Math.trunc((e=a.previewPollMaxAttempts)!=null?e:12))}),me=F(()=>a.loading!==!1);let Ne=null,Ie=null,Se=null,$e=null,Ye=0;const Ut=(y=globalThis.requestIdleCallback)!=null?y:(e,t)=>setTimeout(()=>e({didTimeout:!0}),16),Zt=(z=globalThis.cancelIdleCallback)!=null?z:e=>clearTimeout(e);function b(e=ke){return!ue&&e===ke}function L(){return b()&&xe.value&&!X.value}function Tt(){Se!=null&&(globalThis.clearTimeout(Se),Se=null),$e!=null&&(Zt($e),$e=null)}function qe(){ue||Se==null&&$e==null&&(Se=globalThis.setTimeout(()=>{Se=null,L()&&($e=Ut(()=>{$e=null,L()&&gn()},{timeout:500}))},$n.value))}function We(){Ie!=null&&(globalThis.clearTimeout(Ie),Ie=null)}function Kt(e=600){if(typeof globalThis>"u"||ue)return;const t=Math.max(0,e);We(),Ie=globalThis.setTimeout(()=>{if(Ie=null,!ue){if(a.loading||re.value||!L())return void Kt(Math.min(1200,Math.max(300,1.2*t)));qe()}},t)}const N=m(Wt()),ot=m(N.value);let Pe=null;const O=m(!1),K=m(!1),fe=m({}),he=m(0);let V=null,De=null;const I=m(!1),Rn=F(()=>{var e,t;return!(X.value||x.value||P.value&&!re.value&&!de.value&&(O.value||I.value&&((t=(e=v.value)==null?void 0:e.textContent)!=null&&t.trim())))}),Me=m({zoom:1,translateX:0,translateY:0,containerHeight:N.value}),Gt=F(()=>a.enableWheelZoom?{wheel:Fn}:{}),G=F(()=>{var e,t,n,l;return{worker:(e=a.workerTimeoutMs)!=null?e:1400,parse:(t=a.parseTimeoutMs)!=null?t:1800,render:(n=a.renderTimeoutMs)!=null?n:2500,fullRender:(l=a.fullRenderTimeoutMs)!=null?l:4e3}});let Re=null,at=null,Fe=!1,Te=He.value,ne=null,it=0,Ct=!0,ut=0;function Ce(e,t){const n=t?.timeoutMs,l=t?.signal;if(l?.aborted)return Promise.reject(new DOMException("Aborted","AbortError"));let r=null,o=!1,c=null;return new Promise((h,i)=>{const s=()=>{r!=null&&clearTimeout(r),c&&l&&l.removeEventListener("abort",c)};n&&n>0&&(r=globalThis.setTimeout(()=>{o||(o=!0,s(),i(new Error("Operation timed out")))},n)),l&&(c=()=>{o||(o=!0,s(),i(new DOMException("Aborted","AbortError")))},l.addEventListener("abort",c)),e().then(p=>{o||(o=!0,s(),h(p))}).catch(p=>{o||(o=!0,s(),i(p))})})}function Jt(e){if(typeof document>"u"||!v.value)return;if(typeof a.onRenderError=="function"&&a.onRenderError(e,D.value,v.value)===!0)return I.value=!0,void A();const t=document.createElement("div");t.style.padding="var(--ms-inset-panel-body)",t.style.color="hsl(var(--ms-destructive))",t.textContent="Failed to render diagram: ";const n=document.createElement("span");n.textContent=e instanceof Error?e.message:"Unknown error",t.appendChild(n),we(v.value),v.value.appendChild(t);const l=v.value?getComputedStyle(v.value).getPropertyValue("--ms-size-diagram-min-height").trim():"";N.value=l||"360px",ot.value=N.value,I.value=!0,A()}function Qt(e){const t=typeof e=="string"?e:typeof e?.message=="string"?e.message:"";return typeof t=="string"&&/timed out/i.test(t)}function en(e){return e?.name==="AbortError"}function Bt(e){return!Qt(e)&&!en(e)}typeof window<"u"&&Y([()=>Je.value,ee],([e,t])=>{var n;if((n=je.value)==null||n.destroy(),je.value=null,!t||xe.value)return void(xe.value=!0);if(!e)return void(xe.value=!1);const l=En(e,{rootMargin:Ht?.value.heavyBlockMargin,allowIdle:!1});je.value=l,xe.value=l.isVisible.value,l.whenVisible.then(()=>{xe.value=!0})},{immediate:!0}),Un(()=>{var e;ue=!0,ke+=1,he.value+=1,(e=je.value)==null||e.destroy(),je.value=null,It(),Tt()});const st=F(()=>a.showTooltips!==!1);function tn(e){return!e||e.disabled}function R(e,t,n="top"){if(!st.value||tn(e.currentTarget))return;const l=e,r=l?.clientX!=null&&l?.clientY!=null?{x:l.clientX,y:l.clientY}:void 0;xn(e.currentTarget,t,n,!1,r,a.isDark)}function S(){st.value&&wn()}function nn(e){if(!st.value||tn(e.currentTarget))return;const t=Ge.value?g("common.copied")||"Copied":g("common.copy")||"Copy",n=e,l=n?.clientX!=null&&n?.clientY!=null?{x:n.clientX,y:n.clientY}:void 0;xn(e.currentTarget,t,"top",!1,l,a.isDark)}function ln(e,t){const n={theme:t==="dark"?"dark":"default"};Ee.value==="strict"&&(n.htmlLabels=!1,n.flowchart={htmlLabels:!1});const l=`%%{init: ${JSON.stringify(n)}}%% -`;return e.trimStart().startsWith("%%{")?e:l+e}function ct(){return Ct&&!x.value&&!O.value&&!I.value}function rn(e){const t=e.trim();return!(!t||t.startsWith("%%"))&&!/^(?:gantt|title|dateformat|axisformat|tickinterval|excludes|section|todaymarker|topaxis|weekday|weekend|acctitle|accdescr|accdescrmultiline)\b/i.test(t)&&t.includes(":")}function Et(e){if(_t(e)==="gantt")return(function(n){var l;const r=n.split(/\r?\n/);for(!/\r?\n$/.test(n)&&r.length>0&&r.pop();r.length>0;){const o=(l=r[r.length-1])==null?void 0:l.trim();if(o&&!o.startsWith("%%")){if(rn(o))break;r.pop()}else r.pop()}return r.some(rn)?r.join(` -`):""})(e);const t=e.split(/\r?\n/);for(;t.length>0;){const n=t[t.length-1].trimEnd();if(n!==""){if(!(/^[-=~>|<\s]+$/.test(n.trim())||/(?:--|==|~~|->|<-|-\||-\)|-x|o-|\|-|\.-)\s*$/.test(n)||/[-|><]$/.test(n)||/(?:graph|flowchart|sequenceDiagram|classDiagram|stateDiagram|erDiagram|gantt)\s*$/i.test(n)))break;t.pop()}else t.pop()}return t.join(` -`)}function on(e,t,n,l){return T(this,null,function*(){try{return yield Ce(()=>e.render(t,n),{timeoutMs:l})}catch(r){if(!Bt(r))throw r;const o=At(n);if(o===n)throw r;try{return yield Ce(()=>e.render(`${t}-retry`,o),{timeoutMs:l})}catch{throw r}}})}function dt(e,t,n){return T(this,null,function*(){var l;try{return yield dl(e,t,(l=n?.timeoutMs)!=null?l:G.value.worker,n?.signal)}catch(r){if(r?.name==="AbortError")throw r;const o=r?.code||r?.name;if(o!=="WORKER_BUSY"&&o!=="WORKER_TIMEOUT"&&o!=="WORKER_INIT_ERROR"&&o!=="MERMAID_DISABLED"&&o!=="WORKER_REPLACED"||r?.fallbackToRenderer)return yield(function(c,h,i){return T(this,null,function*(){var s,p,E,W;const j=yield Ke();if(!j)return;const U=j,J=ln(c,h);if(typeof U.parse=="function"){try{yield Ce(()=>U.parse(J),{timeoutMs:(s=i?.timeoutMs)!=null?s:G.value.parse,signal:i?.signal})}catch(oe){if(!Bt(oe))throw oe;const Ue=At(J);if(Ue===J)throw oe;try{yield Ce(()=>U.parse(Ue),{timeoutMs:(p=i?.timeoutMs)!=null?p:G.value.parse,signal:i?.signal})}catch{throw oe}}return!0}const gt=`mermaid-parse-${Math.random().toString(36).slice(2,9)}`;try{yield Ce(()=>j.render(gt,J),{timeoutMs:(E=i?.timeoutMs)!=null?E:G.value.render,signal:i?.signal})}catch(oe){if(!Bt(oe))throw oe;const Ue=At(J);if(Ue===J)throw oe;try{yield Ce(()=>j.render(`${gt}-retry`,Ue),{timeoutMs:(W=i?.timeoutMs)!=null?W:G.value.render,signal:i?.signal})}catch{throw oe}}return!0})})(e,t,n);throw r}})}function an(e,t,n){return T(this,null,function*(){var l;if(_t(e)==="gantt"){const o=Et(e);if(!o.trim())return{fullOk:!1,prefixOk:!1};try{if(yield dt(o,t,n))return o===e?{fullOk:!0,prefixOk:!1}:{fullOk:!1,prefixOk:!0,prefix:o}}catch(c){if(c?.name==="AbortError")throw c}return{fullOk:!1,prefixOk:!1}}try{if(yield dt(e,t,n))return{fullOk:!0,prefixOk:!1}}catch(o){if(o?.name==="AbortError")throw o}let r=Et(e);if(r&&r.trim()&&r!==e)try{try{const o=yield ul(e,t,(l=n?.timeoutMs)!=null?l:G.value.worker,n?.signal);o&&o.trim()&&(r=o)}catch{}if(yield dt(r,t,n))return{fullOk:!1,prefixOk:!0,prefix:r}}catch(o){if(o?.name==="AbortError")throw o}return{fullOk:!1,prefixOk:!1}})}const vt=F(()=>x.value||re.value||X.value);function un(){if(a.maxHeight==="none")return null;if(a.maxHeight!=null){const t=Number.parseFloat(String(a.maxHeight));if(Number.isFinite(t))return t}const e=Z.value;if(e){const t=getComputedStyle(e).getPropertyValue("--ms-size-code-max-height").trim(),n=Number.parseFloat(t);if(Number.isFinite(n))return n}return 500}function Xe(e,t){if(!Z.value||!v.value)return;const n=!t?.force&&a.loading!==!1&&kt(),l=v.value.querySelector("svg");if(!l)return;let r=0,o=0;const c=l.getAttribute("viewBox"),h=l.getAttribute("width"),i=l.getAttribute("height");if(c){const s=c.split(" ");s.length===4&&(r=Number.parseFloat(s[2]),o=Number.parseFloat(s[3]))}if(r&&o||h&&i&&(r=Number.parseFloat(h),o=Number.parseFloat(i)),Number.isNaN(r)||Number.isNaN(o)||r<=0||o<=0)try{const s=l.getBBox();s&&s.width>0&&s.height>0&&(r=s.width,o=s.height)}catch(s){return void console.error("Failed to get SVG BBox:",s)}if(r>0&&o>0){const s=o/r,p=e??Z.value.clientWidth,E=l.getBoundingClientRect().width,W=E>0?E/Math.max(.01,C.value):p,j=un(),U=W*s,J=j==null?U:Math.min(U,j),gt=Math.max(J,qt());n||zt(a.estimatedPreviewHeightPx)!=null||(N.value=`${gt}px`),ot.value=N.value}}const le=m(!1),Ot=F(()=>({transform:`translate(${_.value}px, ${H.value}px) scale(${C.value})`}));function sn(e){e.key==="Escape"&&le.value&&$t()}function St(){var e;if(!Z.value||!se.value)return!1;if(((e=se.value.firstElementChild)==null?void 0:e.getAttribute("data-mermaid-modal-clone"))==="1")return!0;const t=Z.value.cloneNode(!0);t.dataset.mermaidModalClone="1",t.classList.add("fullscreen"),t.style.height="100%",t.style.maxHeight="100%";const n=t.querySelector("._mermaid");n&&(n.style.contain="none",n.style.contentVisibility="visible");const l=t.querySelector("[data-mermaid-wrapper]");return l&&(Qe.value=l,l.style.transform=Ot.value.transform),we(se.value),se.value.appendChild(t),ye(t),!0}function $t(){if(le.value=!1,se.value&&we(se.value),Qe.value=null,typeof document<"u")try{document.body.style.overflow=""}catch{}if(typeof window<"u")try{window.removeEventListener("keydown",sn)}catch{}}function cn(){C.value<3&&(C.value+=.1)}function dn(){C.value>.5&&(C.value-=.1)}function vn(){C.value=1,_.value=0,H.value=0}function mt(e){tt.value=!0,e instanceof MouseEvent?nt.value={x:e.clientX-_.value,y:e.clientY-H.value}:nt.value={x:e.touches[0].clientX-_.value,y:e.touches[0].clientY-H.value}}function ft(e){if(!tt.value)return;let t,n;e instanceof MouseEvent?(t=e.clientX,n=e.clientY):(t=e.touches[0].clientX,n=e.touches[0].clientY),_.value=t-nt.value.x,H.value=n-nt.value.y}function ze(){tt.value=!1}function Fn(e){if(a.enableWheelZoom&&(e.ctrlKey||e.metaKey)){if(e.preventDefault(),!Z.value)return;const t=Z.value.getBoundingClientRect(),n=e.clientX-t.left,l=e.clientY-t.top,r=n-t.width/2,o=l-t.height/2,c=(r-_.value)/C.value,h=(o-H.value)/C.value,i=.01,s=-e.deltaY*i,p=Math.min(Math.max(C.value+s,.5),3);p!==C.value&&(_.value=r-c*p,H.value=o-h*p,C.value=p)}}function zn(){return T(this,null,function*(){try{const e=D.value,t={payload:{type:"copy",text:e},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0}};if($("copy",t),t.defaultPrevented)return;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(e)),Ge.value=!0,setTimeout(()=>{Ge.value=!1},1e3)}catch(e){console.error("Failed to copy:",e)}})}function Ln(){var e;const t=(e=v.value)==null?void 0:e.querySelector("svg");if(!t)return void console.error("SVG element not found");const n=new XMLSerializer().serializeToString(t),l={payload:{type:"export"},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0},svgElement:t,svgString:n};$("export",l),l.defaultPrevented||(function(r,o=null){T(this,null,function*(){try{const c=o??new XMLSerializer().serializeToString(r),h=new Blob([c],{type:"image/svg+xml;charset=utf-8"}),i=URL.createObjectURL(h);if(typeof document<"u"){const s=document.createElement("a");s.href=i,s.download=`mermaid-diagram-${Date.now()}.svg`;try{document.body.appendChild(s),s.click(),document.body.removeChild(s)}catch{}URL.revokeObjectURL(i)}}catch(c){console.error("Failed to export SVG:",c)}})})(t,n)}function An(){var e,t;const n=(t=(e=v.value)==null?void 0:e.querySelector("svg"))!=null?t:null,l=n?new XMLSerializer().serializeToString(n):null,r={payload:{type:"open-modal"},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0},svgElement:n,svgString:l};$("openModal",r),r.defaultPrevented||(function(){if(le.value=!0,typeof document<"u")try{document.body.style.overflow="hidden"}catch{}if(typeof window<"u")try{window.addEventListener("keydown",sn)}catch{}q(()=>{St()||q(St)})})()}function mn(e){const t={payload:{type:"toggle-mode",target:e},defaultPrevented:!1,preventDefault(){this.defaultPrevented=!0}};$("toggleMode",e,t),t.defaultPrevented||fn(e)}function fn(e){return T(this,null,function*(){const t=Yt.value;if(!t)return lt.value=!0,void(x.value=e==="source");const n=t.getBoundingClientRect().height;t.style.height=`${n}px`,t.style.overflow="hidden",lt.value=!0,x.value=e==="source",yield q();const l=t.scrollHeight;t.style.transition="height var(--ms-duration-standard) var(--ms-ease-standard)",t.offsetHeight,t.style.height=`${l}px`;const r=()=>{t.style.transition="",t.style.height="",t.style.overflow="",t.removeEventListener("transitionend",o)};function o(){r()}t.addEventListener("transitionend",o),setTimeout(()=>r(),220)})}function ge(e=D.value,t=a.isDark?"dark":"light",n=a.loading===!1){return{code:e,codeWithTheme:Sn(t,e),final:n,signature:`${t}\0${e}`,theme:t}}function Le(e){return e.signature===ge().signature}function Be(){return T(this,arguments,function*(e=ge()){const t=ke;if(!b(t)||!Le(e))return!1;if(re.value){const n=de.value,l=bt,r=xt;if(!n)return!1;const o=yield n;return!(!b(t)||!Le(e))&&(r===e.signature?!(!o||ve!==e.signature)||!(!e.final||a.loading!==!1||l)&&Be(e):Be(e))}if(!v.value){if(yield q(),!b(t))return!1;if(!v.value)return console.warn("Mermaid container not ready"),!1}return!(!b(t)||!Le(e))&&(re.value=!0,bt=e.final,xt=e.signature,wt(),de.value=T(null,null,function*(){var n,l,r,o;try{const c=yield Ke();if(!b(t)||!c)return!1;const h=`mermaid-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;O.value||K.value||(n=c.initialize)==null||n.call(c,(r=Tn({},Bn.value),o={dompurifyConfig:Tn({},Q)},gl(r,pl(o))));const i=yield on(c,h,e.codeWithTheme,G.value.fullRender);if(!b(t)||!(function(E){return Le(E)||!E.final&&a.loading!==!1&&D.value.startsWith(E.code)})(e))return K.value&&(K.value=!1),!1;if(!v.value)return!1;const s=Oe(v.value,i?.svg,{keepPreviousOnFailure:!e.final||a.loading!==!1});if(!s)return K.value&&(K.value=!1),!1;const p=(l=i?.bindFunctions)!=null?l:null;return ie=p,ye(s.bindTarget),Lt(()=>Xe()),O.value||K.value||(O.value=!0,Me.value={zoom:C.value,translateX:_.value,translateY:H.value,containerHeight:N.value}),fe.value[e.theme]={svg:s.svg,bindFunctions:p},K.value&&(K.value=!1),ve=e.signature,_e.value=v.value.innerHTML,I.value=!1,Ye=0,We(),!0}catch(c){if(!b(t)||!Le(e))return K.value&&(K.value=!1),!1;const h=Qt(c),i=Ye+1;return h&&i<=3?(Ye=i,Kt(Math.min(1200,600*i))):(Ye=0,We(),e.final&&a.loading===!1&&console.error("Failed to render mermaid diagram:",c),e.final&&a.loading===!1&&Jt(c)),!1}finally{bt=!1,xt="",re.value=!1,de.value=null,b(t)&&yt()}}),de.value)})}function Ae(){return T(this,null,function*(){var e;const t=D.value;if(!t.trim())return Xt()?void 0:(v.value&&we(v.value),_e.value=null,ve="",void(I.value=!1));if(!k.value||!L())return;const n=ge(t);O.value&&n.signature===ve&&((e=v.value)!=null&&e.querySelector("svg"))||(yield Be(n))&&(I.value=!1)})}function hn(e,t,n,l){return T(this,null,function*(){const r=ke;if(!b(r)||!ct()||!v.value&&(yield q(),!b(r)||!v.value)||re.value)return;re.value=!0,wt();const o=ge(t,n),c=T(null,null,function*(){var h;try{const i=yield Ke();if(!b(r)||!i)return!1;const s=`mermaid-partial-${Date.now()}-${Math.random().toString(36).slice(2,9)}`,p=Et(e),E=p&&p.trim()?p:e,W=yield on(i,s,ln(E,n),G.value.render);if(!b(r)||he.value!==l||a.loading===!1||!ct()||!Le(o))return!1;const j=W?.svg;if(!v.value||!j)return!1;const U=Oe(v.value,j,{keepPreviousOnFailure:!0});return!!U&&(ie=(h=W?.bindFunctions)!=null?h:null,ye(U.bindTarget),Lt(()=>Xe()),!1)}catch{return!1}finally{de.value===c&&(re.value=!1,de.value=null),b(r)&&yt()}});return de.value=c,c})}function gn(){return T(this,null,function*(){var e;if(!L())return;const t=ke,n=Date.now(),l=++he.value;wt();try{V&&V.abort(),V=new AbortController;const r=V.signal,o=a.isDark?"dark":"light",c=D.value;if(!c.trim())return Xt()?void 0:(v.value&&we(v.value),_e.value=null,ve="",void(I.value=!1));if(ge(c,o).signature===ve)return;try{const i=yield an(c,o,{signal:r,timeoutMs:G.value.worker});if(!b(t))return;if(i.fullOk)return r.aborted||he.value!==l||!(yield Be(ge(c,o)))?void 0:void(b(t)&&he.value===l&&(I.value=!1));const s=it&&n<=it;if(i.prefixOk&&i.prefix&&!r.aborted&&he.value===l&&ct()&&!s)return void(yield hn(i.prefix,c,o,l))}catch(i){if(i?.name==="AbortError")return}if(!b(t)||he.value!==l||I.value)return;const h=fe.value[o];if(h&&v.value){const i=Oe(v.value,h.svg);i&&(ie=(e=h.bindFunctions)!=null?e:null,ye(i.bindTarget))}}finally{b(t)&&yt()}})}function A(){Fe&&(Fe=!1,Te=He.value,Ct=!1,ne&&(ne.abort(),ne=null),Re&&(globalThis.clearTimeout(Re),Re=null),at&&(Zt(at),at=null),it=Date.now())}function Ve(){if(A(),Tt(),V){try{V.abort()}catch{}V=null}if(ne){try{ne.abort()}catch{}ne=null}We(),Ye=0}function Pt(){De?.abort(),De=null}function Dt(e=He.value){Fe&&(ut>=Vt.value?A():(Re&&globalThis.clearTimeout(Re),Re=globalThis.setTimeout(()=>{at=Ut(()=>T(null,null,function*(){if(!Fe)return;if(!L()||x.value||O.value)return void A();const t=a.isDark?"dark":"light",n=D.value;if(!n.trim())return a.loading===!1?void A():void Dt(Te);if(ut++,ut>Vt.value)A();else{ne&&ne.abort(),ne=new AbortController;try{const l=yield an(n,t,{signal:ne.signal,timeoutMs:G.value.worker});if(l.fullOk){if((yield Be(ge(n,t)))&&O.value)return void A()}else l.prefixOk&&l.prefix&&ct()&&(yield hn(l.prefix,n,t,he.value))}catch{}Te=Math.min(Math.floor(1.5*Te),Dn.value),Dt(Te)}}),{timeout:500})},e)))}function ht(){Fe||me.value&&k.value&&L()&&(x.value||O.value||(Fe=!0,it=0,Ct=!0,ut=0,Te=He.value,Dt(Te)))}function pn(){return T(this,null,function*(){const e=ke;b(e)&&(yield Ke().catch(t=>{b(e)&&(k.value=!1,console.warn("[markstream-vue] Failed to initialize mermaid renderer. Call enableMermaid() to configure a loader.",t))}),b(e)&&(yield q(),b(e)&&(lt.value||(x.value=!k.value),L()&&(me.value?(qe(),rt.value=D.value.length):x.value||Ae()))))})}return Y(se,e=>{le.value&&e&&St()}),Y(Ot,e=>{le.value&&Qe.value&&(Qe.value.style.transform=e.transform)},{immediate:!0}),Y(st,e=>{e||wn()}),Y(()=>D.value,e=>{if((e.trim()||a.loading===!1)&&(O.value=!1,fe.value={}),!me.value)return A(),void(L()&&!x.value&&Ae());L()&&qe(),!x.value&&k.value&&L()?ht():A(),(function(){if(!me.value||!x.value||!k.value)return;const t=D.value.length;t!==rt.value&&(Mt.value=!0,rt.value=t,Ne&&clearTimeout(Ne),Ne=setTimeout(()=>{Mt.value&&x.value&&D.value.trim()&&(Mt.value=!1,fn("preview"))},Pn.value))})()}),Y(()=>a.isDark,()=>T(null,null,function*(){var e;if(I.value)return;const t=a.isDark?"dark":"light",n=fe.value[t];if(n){if(v.value){const o=Oe(v.value,n.svg);o&&(ie=(e=n.bindFunctions)!=null?e:null,ye(o.bindTarget))}return}const l={zoom:C.value,translateX:_.value,translateY:H.value,containerHeight:N.value},r=C.value!==1||_.value!==0||H.value!==0;K.value=!0,r&&(C.value=1,_.value=0,H.value=0,yield q()),yield Be(),r&&(yield q(),C.value=l.zoom,_.value=l.translateX,H.value=l.translateY,N.value=l.containerHeight,Me.value=l)})),Y(()=>x.value,e=>T(null,null,function*(){var t;if(e)A(),O.value&&(Me.value={zoom:C.value,translateX:_.value,translateY:H.value,containerHeight:N.value});else{if(I.value)return;const n=a.isDark?"dark":"light";if(O.value&&fe.value[n]){if(yield q(),v.value){const l=fe.value[n],r=Oe(v.value,l.svg);r&&(ie=(t=l.bindFunctions)!=null?t:null,ye(r.bindTarget))}return C.value=Me.value.zoom,_.value=Me.value.translateX,H.value=Me.value.translateY,void(N.value=Me.value.containerHeight)}if(yield q(),!k.value||!L())return;if(!me.value)return A(),void(yield Ae());ht(),yield gn()}})),Y(()=>a.loading,(e,t)=>T(null,null,function*(){var n;if(e)Pt();else if(t===!0){Pt();const l=D.value,r=l.trim();if(!r)return v.value&&we(v.value),_e.value=null,ve="",I.value=!1,Ve();if(!L())return void Ve();const o=a.isDark?"dark":"light",c=ge(l,o);if(O.value&&c.signature===ve){if(yield q(),v.value&&!v.value.querySelector("svg")&&fe.value[o]){const i=fe.value[o],s=Oe(v.value,i.svg);s&&(ie=(n=i.bindFunctions)!=null?n:null,ye(s.bindTarget))}return Xe(void 0,{force:!0}),void Ve()}const h=new AbortController;De=h;try{let i=0;for(;;)try{yield dt(r,o,{signal:h.signal,timeoutMs:G.value.worker});break}catch(s){const p=s?.code==="WORKER_BUSY"||s?.code==="WORKER_TIMEOUT",E=s?.code==="WORKER_TIMEOUT"?2:8;if(!p||i>=E)throw s;const W=Math.min(50*kl(2,i),400);i++,yield Ce(()=>new Promise(j=>setTimeout(j,W)),{signal:h.signal})}if(!(yield Be(c)))return;I.value=!1,Ve()}catch(i){if(en(i))return;Ve(),Jt(i)}finally{De===h&&(De=null)}}})),Y(Z,e=>{Pe&&Pe.disconnect(),e&&(Pe=new ResizeObserver(t=>{t&&t.length>0&&!x.value&&!X.value&&Lt(()=>{Xe(t[0].contentRect.width)})}),Pe.observe(e))},{immediate:!0}),Zn(()=>{ee.value&&!L()||pn()}),Y(()=>k.value,e=>{lt.value||(x.value=!e)}),Y(()=>a.maxHeight,()=>{q(()=>{Xe()})}),Y([()=>a.estimatedPreviewHeightPx,()=>D.value],()=>{O.value||kt()||x.value||(N.value=Wt(),ot.value=N.value)}),Y(()=>xe.value,e=>T(null,null,function*(){e&&(P.value?(O.value||(me.value?(qe(),rt.value=D.value.length):Ae()),a.loading||O.value||Ae(),!x.value&&k.value&&me.value&&ht()):yield pn())}),{immediate:!1}),Kn(()=>{Ne&&clearTimeout(Ne),Tt(),Pe&&Pe.disconnect(),V&&(V.abort(),V=null),Pt(),A(),We(),It()}),Y(()=>X.value,e=>T(null,null,function*(){e?(A(),V&&V.abort()):L()&&!O.value&&(yield q(),me.value?(qe(),ht()):x.value||Ae())}),{immediate:!1}),(e,t)=>(M(),B("div",{ref_key:"blockContainer",ref:Je,class:ae(["mermaid-block-container rounded-lg border overflow-hidden",[{"is-rendering":a.loading,dark:a.isDark}]]),"data-markstream-mermaid":"1","data-markstream-mode":x.value?"fallback":O.value?"preview":"pending","data-markstream-pending":Rn.value?"true":void 0},[a.showHeader?(M(),B("div",bl,[e.$slots["header-left"]?(M(),B("div",Ml,[Rt(e.$slots,"header-left",{},void 0,!0)])):(M(),B("div",Tl,[u("span",{class:"icon-slot action-icon shrink-0",innerHTML:w(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="16" height="16"> - <path fill="none" stroke="#ca9ee6" stroke-linecap="round" stroke-linejoin="round" d="M1.5 2.5c0 6 2.25 5.75 4 7 .83.67 1.17 2 1 4h3c-.17-2 .17-3.33 1-4 1.75-1.25 4-1 4-7C12 2.5 10 3 8 7 6 3 4 2.5 1.5 2.5" /> -</svg> -`)},null,8,Cl),t[21]||(t[21]=u("span",{class:"mermaid-label-text text-[length:var(--ms-text-label)] font-medium font-mono truncate"},"Mermaid",-1))])),e.$slots["header-center"]?(M(),B("div",Bl,[Rt(e.$slots,"header-center",{},void 0,!0)])):a.showModeToggle&&k.value?(M(),B("div",El,[u("button",{class:ae(["mermaid-mode-btn px-2 py-0.5 rounded transition-colors",[x.value?"":"is-active"]]),onClick:t[0]||(t[0]=()=>mn("preview")),onMouseenter:t[1]||(t[1]=n=>R(n,w(g)("common.preview")||"Preview")),onFocus:t[2]||(t[2]=n=>R(n,w(g)("common.preview")||"Preview")),onMouseleave:S,onBlur:S},[u("div",Ol,[t[22]||(t[22]=u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("path",{d:"M2.062 12.348a1 1 0 0 1 0-.696a10.75 10.75 0 0 1 19.876 0a1 1 0 0 1 0 .696a10.75 10.75 0 0 1-19.876 0"}),u("circle",{cx:"12",cy:"12",r:"3"})])],-1)),u("span",null,Ze(w(g)("common.preview")||"Preview"),1)])],34),u("button",{class:ae(["mermaid-mode-btn px-2 py-0.5 rounded transition-colors",[x.value?"is-active":""]]),onClick:t[3]||(t[3]=()=>mn("source")),onMouseenter:t[4]||(t[4]=n=>R(n,w(g)("common.source")||"Source")),onFocus:t[5]||(t[5]=n=>R(n,w(g)("common.source")||"Source")),onMouseleave:S,onBlur:S},[u("div",Sl,[t[23]||(t[23]=u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m16 18l6-6l-6-6M8 6l-6 6l6 6"})],-1)),u("span",null,Ze(w(g)("common.source")||"Source"),1)])],34)])):pe("",!0),e.$slots["header-right"]?(M(),B("div",$l,[Rt(e.$slots,"header-right",{},void 0,!0)])):(M(),B("div",Pl,[a.showCollapseButton?(M(),B("button",{key:0,class:ae(pt),"aria-pressed":X.value,onClick:t[6]||(t[6]=n=>X.value=!X.value),onMouseenter:t[7]||(t[7]=n=>R(n,X.value?w(g)("common.expand")||"Expand":w(g)("common.collapse")||"Collapse")),onFocus:t[8]||(t[8]=n=>R(n,X.value?w(g)("common.expand")||"Expand":w(g)("common.collapse")||"Collapse")),onMouseleave:S,onBlur:S},[(M(),B("svg",{style:Ft({rotate:X.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...t[24]||(t[24]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,Dl)):pe("",!0),a.showCopyButton?(M(),B("button",{key:1,class:ae(pt),onClick:zn,onMouseenter:t[9]||(t[9]=n=>nn(n)),onFocus:t[10]||(t[10]=n=>nn(n)),onMouseleave:S,onBlur:S},[Ge.value?(M(),B("svg",Fl,[...t[26]||(t[26]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(M(),B("svg",Rl,[...t[25]||(t[25]=[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),u("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],32)):pe("",!0),a.showExportButton&&k.value?(M(),B("button",{key:2,class:ae(`${pt} ${vt.value?"opacity-50 cursor-not-allowed":""}`),"aria-label":w(g)("common.export")||"Export",disabled:vt.value,onClick:Ln,onMouseenter:t[11]||(t[11]=n=>R(n,w(g)("common.export")||"Export")),onFocus:t[12]||(t[12]=n=>R(n,w(g)("common.export")||"Export")),onMouseleave:S,onBlur:S},[...t[27]||(t[27]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("path",{d:"M12 15V3m9 12v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}),u("path",{d:"m7 10l5 5l5-5"})])],-1)])],42,zl)):pe("",!0),a.showFullscreenButton&&k.value?(M(),B("button",{key:3,class:ae(`${pt} ${vt.value?"opacity-50 cursor-not-allowed":""}`),"aria-label":le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open",disabled:vt.value,onClick:An,onMouseenter:t[13]||(t[13]=n=>R(n,le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open")),onFocus:t[14]||(t[14]=n=>R(n,le.value?w(g)("common.minimize")||"Minimize":w(g)("common.open")||"Open")),onMouseleave:S,onBlur:S},[le.value?(M(),B("svg",jl,[...t[29]||(t[29]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m14 10l7-7m-1 7h-6V4M3 21l7-7m-6 0h6v6"},null,-1)])])):(M(),B("svg",Al,[...t[28]||(t[28]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M15 3h6v6m0-6l-7 7M3 21l7-7m-1 7H3v-6"},null,-1)])]))],42,Ll)):pe("",!0)]))])):pe("",!0),Gn(u("div",{ref_key:"modeContainerRef",ref:Yt},[x.value?(M(),B("div",_l,[u("pre",Hl,Ze(D.value),1)])):(M(),B("div",Nl,[a.showZoomControls?(M(),B("div",Il,[u("div",Yl,[u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:cn,onMouseenter:t[15]||(t[15]=n=>R(n,w(g)("common.zoomIn")||"Zoom in")),onFocus:t[16]||(t[16]=n=>R(n,w(g)("common.zoomIn")||"Zoom in")),onMouseleave:S,onBlur:S},[...t[30]||(t[30]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])],32),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:dn,onMouseenter:t[17]||(t[17]=n=>R(n,w(g)("common.zoomOut")||"Zoom out")),onFocus:t[18]||(t[18]=n=>R(n,w(g)("common.zoomOut")||"Zoom out")),onMouseleave:S,onBlur:S},[...t[31]||(t[31]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])],32),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] text-[length:var(--ms-text-label)] rounded transition-colors",onClick:vn,onMouseenter:t[19]||(t[19]=n=>R(n,w(g)("common.resetZoom")||"Reset zoom")),onFocus:t[20]||(t[20]=n=>R(n,w(g)("common.resetZoom")||"Reset zoom")),onMouseleave:S,onBlur:S},Ze(Math.round(100*C.value))+"% ",33)])])):pe("",!0),u("div",yn({ref_key:"mermaidContainer",ref:Z,class:"mermaid-preview-area relative overflow-hidden block transition-[height] ease-out",style:{height:N.value}},kn(Gt.value,!0),{onMousedown:mt,onMousemove:ft,onMouseup:ze,onMouseleave:ze,onTouchstartPassive:mt,onTouchmovePassive:ft,onTouchendPassive:ze}),[u("div",{"data-mermaid-wrapper":"",class:ae(["absolute inset-0 cursor-grab",{"cursor-grabbing":tt.value}]),style:Ft(Ot.value)},[u("div",{ref_key:"mermaidContent",ref:v,class:"_mermaid w-full text-center flex items-center justify-center min-h-full",style:Ft({height:ot.value})},null,4)],6)],16),(M(),Qn(rl,{to:"body"},[u("div",{class:ae(["markstream-vue",{dark:a.isDark}])},[el(ll,{name:"mermaid-dialog",appear:""},{default:tl(()=>[le.value?(M(),B("div",{key:0,class:"mermaid-modal-overlay fixed inset-0 z-50 flex items-center justify-center p-4",onClick:nl($t,["self"])},[u("div",ql,[u("div",Wl,[u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:cn},[...t[32]||(t[32]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M11 8v6m-3-3h6"})])],-1)])]),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:dn},[...t[33]||(t[33]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("circle",{cx:"11",cy:"11",r:"8"}),u("path",{d:"m21 21l-4.35-4.35M8 11h6"})])],-1)])]),u("button",{class:"mermaid-action-btn p-[var(--ms-action-btn-padding)] text-[length:var(--ms-text-label)] rounded transition-colors",onClick:vn},Ze(Math.round(100*C.value))+"% ",1),u("button",{class:"mermaid-action-btn inline-flex items-center justify-center p-[var(--ms-action-btn-padding)] rounded transition-colors",onClick:$t},[...t[34]||(t[34]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M18 6L6 18M6 6l12 12"})],-1)])])]),u("div",yn({ref_key:"modalContent",ref:se,class:"w-full h-full flex items-center justify-center p-4 overflow-hidden"},kn(Gt.value,!0),{onMousedown:mt,onMousemove:ft,onMouseup:ze,onMouseleave:ze,onTouchstartPassive:mt,onTouchmovePassive:ft,onTouchendPassive:ze}),null,16)])])):pe("",!0)]),_:1})],2)]))]))],512),[[Jn,!X.value]])],10,xl))}}),[["__scopeId","data-v-73c385f8"]]);jt.install=d=>{d.component(jt.__name,jt)};export{jt as default}; diff --git a/apps/kimi-code/dist-web/assets/index5-L7WSqVk4.js b/apps/kimi-code/dist-web/assets/index5-Cn2jfVMX.js similarity index 95% rename from apps/kimi-code/dist-web/assets/index5-L7WSqVk4.js rename to apps/kimi-code/dist-web/assets/index5-Cn2jfVMX.js index 0b040b849..1e6ee74e9 100644 --- a/apps/kimi-code/dist-web/assets/index5-L7WSqVk4.js +++ b/apps/kimi-code/dist-web/assets/index5-Cn2jfVMX.js @@ -1 +1 @@ -import c from"./CodeBlockNode-CJGhujJE.js";import{M as v,bl as g,aL as P,s as C,A as b,bJ as i,aY as d,av as k,a4 as x,ar as S,bk as T,q as O}from"./index-D1h84VfZ.js";import"./safeRaf-DGuzXxDK.js";var H=Object.defineProperty,z=Object.defineProperties,j=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,F=Object.prototype.hasOwnProperty,W=Object.prototype.propertyIsEnumerable,m=(o,s,e)=>s in o?H(o,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[s]=e;const h=v({__name:"MarkdownCodeBlockNode",props:{node:{},loading:{type:Boolean,default:!0},stream:{type:Boolean,default:!0},darkTheme:{default:"vitesse-dark"},lightTheme:{default:"vitesse-light"},isDark:{type:Boolean,default:!1},isShowPreview:{type:Boolean,default:!0},enableFontSizeControl:{type:Boolean,default:!0},minWidth:{default:void 0},maxWidth:{default:void 0},showPreviewButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},showTooltips:{type:Boolean},autoScrollOnUpdate:{type:Boolean},autoScrollInitial:{type:Boolean},estimatedHeightPx:{},estimatedContentHeightPx:{},themes:{},langs:{},showHeader:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0}},emits:["previewCode","copy"],setup(o,{emit:s}){const e=o,p=s,w=c,f=g(),y=O(()=>{return t=((a,n)=>{for(var r in n||(n={}))F.call(n,r)&&m(a,r,n[r]);if(u)for(var r of u(n))W.call(n,r)&&m(a,r,n[r]);return a})({},f),l={node:e.node,loading:e.loading,stream:e.stream,darkTheme:e.darkTheme,lightTheme:e.lightTheme,isDark:e.isDark,isShowPreview:e.isShowPreview,enableFontSizeControl:e.enableFontSizeControl,minWidth:e.minWidth,maxWidth:e.maxWidth,themes:e.themes,showHeader:e.showHeader,showCopyButton:e.showCopyButton,showExpandButton:e.showExpandButton,showPreviewButton:e.showPreviewButton,showCollapseButton:e.showCollapseButton,showFontSizeButtons:e.showFontSizeButtons,showTooltips:e.showTooltips,estimatedHeightPx:e.estimatedHeightPx,estimatedContentHeightPx:e.estimatedContentHeightPx},z(t,j(l));var t,l});function B(t){p("previewCode",{type:t.artifactType,content:e.node.code,title:t.artifactTitle})}return(t,l)=>(P(),C(T(w),S(y.value,{onPreviewCode:B,onCopy:l[0]||(l[0]=a=>p("copy",a))}),b({_:2},[t.$slots["header-left"]?{name:"header-left",fn:i(()=>[d(t.$slots,"header-left")]),key:"0"}:void 0,t.$slots["header-right"]?{name:"header-right",fn:i(()=>[d(t.$slots,"header-right")]),key:"1"}:void 0,t.$slots.loading?{name:"loading",fn:i(a=>[d(t.$slots,"loading",k(x(a)))]),key:"2"}:void 0]),1040))}});h.install=o=>{o.component(h.__name,h)};export{h as default}; +import c from"./CodeBlockNode-BAtAs_qm.js";import{M as v,bl as g,aL as P,s as C,A as b,bJ as i,aY as d,av as k,a4 as x,ar as S,bk as T,q as O}from"./index-D-7nOosq.js";import"./safeRaf-DGuzXxDK.js";var H=Object.defineProperty,z=Object.defineProperties,j=Object.getOwnPropertyDescriptors,u=Object.getOwnPropertySymbols,F=Object.prototype.hasOwnProperty,W=Object.prototype.propertyIsEnumerable,m=(o,s,e)=>s in o?H(o,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):o[s]=e;const h=v({__name:"MarkdownCodeBlockNode",props:{node:{},loading:{type:Boolean,default:!0},stream:{type:Boolean,default:!0},darkTheme:{default:"vitesse-dark"},lightTheme:{default:"vitesse-light"},isDark:{type:Boolean,default:!1},isShowPreview:{type:Boolean,default:!0},enableFontSizeControl:{type:Boolean,default:!0},minWidth:{default:void 0},maxWidth:{default:void 0},showPreviewButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0},showFontSizeButtons:{type:Boolean,default:!0},showTooltips:{type:Boolean},autoScrollOnUpdate:{type:Boolean},autoScrollInitial:{type:Boolean},estimatedHeightPx:{},estimatedContentHeightPx:{},themes:{},langs:{},showHeader:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExpandButton:{type:Boolean,default:!0}},emits:["previewCode","copy"],setup(o,{emit:s}){const e=o,p=s,w=c,f=g(),y=O(()=>{return t=((a,n)=>{for(var r in n||(n={}))F.call(n,r)&&m(a,r,n[r]);if(u)for(var r of u(n))W.call(n,r)&&m(a,r,n[r]);return a})({},f),l={node:e.node,loading:e.loading,stream:e.stream,darkTheme:e.darkTheme,lightTheme:e.lightTheme,isDark:e.isDark,isShowPreview:e.isShowPreview,enableFontSizeControl:e.enableFontSizeControl,minWidth:e.minWidth,maxWidth:e.maxWidth,themes:e.themes,showHeader:e.showHeader,showCopyButton:e.showCopyButton,showExpandButton:e.showExpandButton,showPreviewButton:e.showPreviewButton,showCollapseButton:e.showCollapseButton,showFontSizeButtons:e.showFontSizeButtons,showTooltips:e.showTooltips,estimatedHeightPx:e.estimatedHeightPx,estimatedContentHeightPx:e.estimatedContentHeightPx},z(t,j(l));var t,l});function B(t){p("previewCode",{type:t.artifactType,content:e.node.code,title:t.artifactTitle})}return(t,l)=>(P(),C(T(w),S(y.value,{onPreviewCode:B,onCopy:l[0]||(l[0]=a=>p("copy",a))}),b({_:2},[t.$slots["header-left"]?{name:"header-left",fn:i(()=>[d(t.$slots,"header-left")]),key:"0"}:void 0,t.$slots["header-right"]?{name:"header-right",fn:i(()=>[d(t.$slots,"header-right")]),key:"1"}:void 0,t.$slots.loading?{name:"loading",fn:i(a=>[d(t.$slots,"loading",k(x(a)))]),key:"2"}:void 0]),1040))}});h.install=o=>{o.component(h.__name,h)};export{h as default}; diff --git a/apps/kimi-code/dist-web/assets/index6-CBDuyf4L.js b/apps/kimi-code/dist-web/assets/index6-D4fZsFMu.js similarity index 98% rename from apps/kimi-code/dist-web/assets/index6-CBDuyf4L.js rename to apps/kimi-code/dist-web/assets/index6-D4fZsFMu.js index 1d9a307c9..29f5d93ae 100644 --- a/apps/kimi-code/dist-web/assets/index6-CBDuyf4L.js +++ b/apps/kimi-code/dist-web/assets/index6-D4fZsFMu.js @@ -1 +1 @@ -import{bQ as Q,M as Y,af as Z,bY as G,a0 as ee,bS as ne,bT as A,aU as _,bZ as te,bE as P,aD as ae,az as le,aL as I,u as O,I as oe,bJ as re,t as ie,v as ue,g as se,au as F,bb as ce,aw as de,q as X,bU as ve,as as j,bV as fe,bW as me,bX as he,b_ as ge}from"./index-D1h84VfZ.js";var q=(S,B,b)=>new Promise((t,s)=>{var i=c=>{try{T(b.next(c))}catch(d){s(d)}},k=c=>{try{T(b.throw(c))}catch(d){s(d)}},T=c=>c.done?t(c.value):Promise.resolve(c.value).then(i,k);T((b=b.apply(S,B)).next())});const pe=["data-markstream-mode","data-markstream-pending"],ye={key:0,class:"math-loading-overlay"},be=["innerHTML"],ke={key:1,class:"math-block__fallback text-left"},N=Q(Y({__name:"MathBlockNode",props:{node:{},indexKey:{},cacheScope:{}},setup(S){var B,b;const t=S,s=_(null),i=Z(G,null),k=X(()=>ve(t.node.content)),T=((b=(B=ee())==null?void 0:B.vnode.el)==null?void 0:b.nodeType)===1,c=X(()=>ge(t,{})),d=(function(){if(!t.node.content)return{html:"",text:t.node.raw,loading:!1};if(t.node.loading)return{html:"",text:"",loading:!0};const e=ne();if(!e){const n=typeof window>"u"||T;return{html:"",text:n?t.node.raw:"",loading:!n}}try{const n=e.renderToString(k.value,{throwOnError:!1,displayMode:!0});return A(k.value,!0,n),{html:n,text:"",loading:!1}}catch{return{html:"",text:t.node.loading?"":t.node.raw,loading:t.node.loading}}})(),u=_(d.html),f=_(d.text);let E=!1,x=0,v=!1,$=null;const m=te();let R=null,h="";const g=_(d.loading),K=_(!1),p=_(D());function H(e){e!=null&&e!==x||(K.value=!1)}function W(){var e;if(t.indexKey==null)return"";const n=(e=t.cacheScope)!=null?e:m?.scope;return`${n!=null&&String(n).length>0?`${String(n)}:`:""}math-block:${String(t.indexKey)}`}function D(){var e;const n=W();return n&&(e=m?.cache.get(n))!=null?e:0}function M(){if(p.value===0)return;p.value=0;const e=W();e&&m?.cache.set(e,0)}function L(e){if(u.value)return void M();if(!Number.isFinite(e)||e<=0)return;const n=Math.max(p.value,e);if(n===p.value)return;p.value=n;const a=W();a&&m?.cache.set(a,n)}function w(){j(()=>{var e,n;L((n=(e=s.value)==null?void 0:e.offsetHeight)!=null?n:0)})}function z(){const e=h;i&&e&&(h="",i.markSettled(e))}function U(){return q(this,null,function*(){if(v)return z(),void H();$&&($.abort(),$=null);const e=++x;if(!t.node.content)return z(),H(),g.value=!1,u.value="",f.value=t.node.raw,E=!1,void w();const n=new AbortController;$=n,K.value=!0,v||e!==x||n.signal.aborted?v||H(e):((function(){const a=c.value;i&&a&&h!==a&&(h&&i.markSettled(h),h=a,i.markPending(a))})(),fe(k.value,!0,{timeout:3e3,waitTimeout:2e3,maxRetries:8,signal:n.signal}).then(a=>{v||e!==x||(u.value=a,f.value="",E=!0,g.value=!1,M(),w())}).catch(a=>q(null,null,function*(){if(v||e!==x)return;const r=a?.code||a?.name,l=r==="KATEX_DISABLED";if(r==="WORKER_INIT_ERROR"||a?.fallbackToRenderer||(r===me||r==="WORKER_TIMEOUT")&&!t.node.loading){const o=yield he();if(v||e!==x)return;if(o){try{const y=o.renderToString(k.value,{throwOnError:t.node.loading,displayMode:!0});u.value=y,f.value="",E=!0,g.value=!1,M(),w(),A(k.value,!0,y)}catch{}return}}if(l||!t.node.loading)return g.value=!1,u.value="",f.value=t.node.raw,void w();E||(g.value=!0)})).finally(()=>{v||e!==x||(H(e),(function(){const a=h;i&&a&&(h="",j(()=>{var r,l;if(!v){const o=(l=(r=s.value)==null?void 0:r.offsetHeight)!=null?l:0;o>0&&i.reportHeight(a,o)}i.markSettled(a)}))})())}))})}d.html&&(E=!0),d.html&&M();const J=[{family:"$$",open:"$$",close:"$$"},{family:"\\[]",open:"\\[",close:"\\]"},{family:"\\[]",open:"\\[",close:"]"},{family:"[]",open:"[",close:"\\]"},{family:"[]",open:"[",close:"]"},{family:"\\()",open:"\\(",close:"\\)"},{family:"$",open:"$",close:"$"}];function V(e,n){return(function(r){const l=String(r??"");for(const{family:o,open:y,close:C}of J)if((y!=="$"||!l.startsWith("$$")&&!l.endsWith("$$"))&&l.length>=y.length+C.length&&l.startsWith(y)&&l.endsWith(C))return{family:o,inner:l.slice(y.length,l.length-C.length),trusted:!0};return null})(e)||{family:"content",inner:String(n??""),trusted:!1}}return P(()=>[t.node.content,t.node.loading,t.node.raw],([e,,n],[a,,r])=>{var l,o;l=V(r,a),o=V(n,e),l.inner===""||l.family===o.family&&(l.trusted&&o.trusted?o.inner.startsWith(l.inner):o.inner===l.inner)||M(),U()},{flush:"post"}),P([()=>t.indexKey,()=>t.cacheScope],()=>{p.value=D(),w()}),ae(()=>{typeof ResizeObserver<"u"&&s.value&&(R=new ResizeObserver(()=>{var e,n;L((n=(e=s.value)==null?void 0:e.offsetHeight)!=null?n:0)}),R.observe(s.value)),w(),u.value||U()}),le(()=>{v=!0,z(),$&&($.abort(),$=null),R?.disconnect(),R=null}),(e,n)=>(I(),O("div",{ref_key:"containerEl",ref:s,class:"math-block text-center overflow-x-auto relative","data-markstream-math":"block","data-markstream-mode":u.value?"katex":f.value?"fallback":"loading","data-markstream-pending":K.value?"true":void 0,style:de(p.value?{minHeight:`${p.value}px`}:void 0)},[oe(se,{name:"math-fade"},{default:re(()=>[!g.value||u.value||f.value?ie("",!0):(I(),O("div",ye,[...n[0]||(n[0]=[ue("div",{class:"math-loading-spinner"},null,-1)])]))]),_:1}),u.value?(I(),O("div",{key:0,class:F(["math-block__content",{"math-rendering":g.value}]),innerHTML:u.value},null,10,be)):f.value?(I(),O("pre",ke,ce(f.value),1)):(I(),O("div",{key:2,class:F(["math-block__content",{"math-rendering":g.value}])},null,2))],12,pe))}}),[["__scopeId","data-v-939191ad"]]);N.install=S=>{S.component(N.__name,N)};export{N as default}; +import{bQ as Q,M as Y,af as Z,bY as G,a0 as ee,bS as ne,bT as A,aU as _,bZ as te,bE as P,aD as ae,az as le,aL as I,u as O,I as oe,bJ as re,t as ie,v as ue,g as se,au as F,bb as ce,aw as de,q as X,bU as ve,as as j,bV as fe,bW as me,bX as he,b_ as ge}from"./index-D-7nOosq.js";var q=(S,B,b)=>new Promise((t,s)=>{var i=c=>{try{T(b.next(c))}catch(d){s(d)}},k=c=>{try{T(b.throw(c))}catch(d){s(d)}},T=c=>c.done?t(c.value):Promise.resolve(c.value).then(i,k);T((b=b.apply(S,B)).next())});const pe=["data-markstream-mode","data-markstream-pending"],ye={key:0,class:"math-loading-overlay"},be=["innerHTML"],ke={key:1,class:"math-block__fallback text-left"},N=Q(Y({__name:"MathBlockNode",props:{node:{},indexKey:{},cacheScope:{}},setup(S){var B,b;const t=S,s=_(null),i=Z(G,null),k=X(()=>ve(t.node.content)),T=((b=(B=ee())==null?void 0:B.vnode.el)==null?void 0:b.nodeType)===1,c=X(()=>ge(t,{})),d=(function(){if(!t.node.content)return{html:"",text:t.node.raw,loading:!1};if(t.node.loading)return{html:"",text:"",loading:!0};const e=ne();if(!e){const n=typeof window>"u"||T;return{html:"",text:n?t.node.raw:"",loading:!n}}try{const n=e.renderToString(k.value,{throwOnError:!1,displayMode:!0});return A(k.value,!0,n),{html:n,text:"",loading:!1}}catch{return{html:"",text:t.node.loading?"":t.node.raw,loading:t.node.loading}}})(),u=_(d.html),f=_(d.text);let E=!1,x=0,v=!1,$=null;const m=te();let R=null,h="";const g=_(d.loading),K=_(!1),p=_(D());function H(e){e!=null&&e!==x||(K.value=!1)}function W(){var e;if(t.indexKey==null)return"";const n=(e=t.cacheScope)!=null?e:m?.scope;return`${n!=null&&String(n).length>0?`${String(n)}:`:""}math-block:${String(t.indexKey)}`}function D(){var e;const n=W();return n&&(e=m?.cache.get(n))!=null?e:0}function M(){if(p.value===0)return;p.value=0;const e=W();e&&m?.cache.set(e,0)}function L(e){if(u.value)return void M();if(!Number.isFinite(e)||e<=0)return;const n=Math.max(p.value,e);if(n===p.value)return;p.value=n;const a=W();a&&m?.cache.set(a,n)}function w(){j(()=>{var e,n;L((n=(e=s.value)==null?void 0:e.offsetHeight)!=null?n:0)})}function z(){const e=h;i&&e&&(h="",i.markSettled(e))}function U(){return q(this,null,function*(){if(v)return z(),void H();$&&($.abort(),$=null);const e=++x;if(!t.node.content)return z(),H(),g.value=!1,u.value="",f.value=t.node.raw,E=!1,void w();const n=new AbortController;$=n,K.value=!0,v||e!==x||n.signal.aborted?v||H(e):((function(){const a=c.value;i&&a&&h!==a&&(h&&i.markSettled(h),h=a,i.markPending(a))})(),fe(k.value,!0,{timeout:3e3,waitTimeout:2e3,maxRetries:8,signal:n.signal}).then(a=>{v||e!==x||(u.value=a,f.value="",E=!0,g.value=!1,M(),w())}).catch(a=>q(null,null,function*(){if(v||e!==x)return;const r=a?.code||a?.name,l=r==="KATEX_DISABLED";if(r==="WORKER_INIT_ERROR"||a?.fallbackToRenderer||(r===me||r==="WORKER_TIMEOUT")&&!t.node.loading){const o=yield he();if(v||e!==x)return;if(o){try{const y=o.renderToString(k.value,{throwOnError:t.node.loading,displayMode:!0});u.value=y,f.value="",E=!0,g.value=!1,M(),w(),A(k.value,!0,y)}catch{}return}}if(l||!t.node.loading)return g.value=!1,u.value="",f.value=t.node.raw,void w();E||(g.value=!0)})).finally(()=>{v||e!==x||(H(e),(function(){const a=h;i&&a&&(h="",j(()=>{var r,l;if(!v){const o=(l=(r=s.value)==null?void 0:r.offsetHeight)!=null?l:0;o>0&&i.reportHeight(a,o)}i.markSettled(a)}))})())}))})}d.html&&(E=!0),d.html&&M();const J=[{family:"$$",open:"$$",close:"$$"},{family:"\\[]",open:"\\[",close:"\\]"},{family:"\\[]",open:"\\[",close:"]"},{family:"[]",open:"[",close:"\\]"},{family:"[]",open:"[",close:"]"},{family:"\\()",open:"\\(",close:"\\)"},{family:"$",open:"$",close:"$"}];function V(e,n){return(function(r){const l=String(r??"");for(const{family:o,open:y,close:C}of J)if((y!=="$"||!l.startsWith("$$")&&!l.endsWith("$$"))&&l.length>=y.length+C.length&&l.startsWith(y)&&l.endsWith(C))return{family:o,inner:l.slice(y.length,l.length-C.length),trusted:!0};return null})(e)||{family:"content",inner:String(n??""),trusted:!1}}return P(()=>[t.node.content,t.node.loading,t.node.raw],([e,,n],[a,,r])=>{var l,o;l=V(r,a),o=V(n,e),l.inner===""||l.family===o.family&&(l.trusted&&o.trusted?o.inner.startsWith(l.inner):o.inner===l.inner)||M(),U()},{flush:"post"}),P([()=>t.indexKey,()=>t.cacheScope],()=>{p.value=D(),w()}),ae(()=>{typeof ResizeObserver<"u"&&s.value&&(R=new ResizeObserver(()=>{var e,n;L((n=(e=s.value)==null?void 0:e.offsetHeight)!=null?n:0)}),R.observe(s.value)),w(),u.value||U()}),le(()=>{v=!0,z(),$&&($.abort(),$=null),R?.disconnect(),R=null}),(e,n)=>(I(),O("div",{ref_key:"containerEl",ref:s,class:"math-block text-center overflow-x-auto relative","data-markstream-math":"block","data-markstream-mode":u.value?"katex":f.value?"fallback":"loading","data-markstream-pending":K.value?"true":void 0,style:de(p.value?{minHeight:`${p.value}px`}:void 0)},[oe(se,{name:"math-fade"},{default:re(()=>[!g.value||u.value||f.value?ie("",!0):(I(),O("div",ye,[...n[0]||(n[0]=[ue("div",{class:"math-loading-spinner"},null,-1)])]))]),_:1}),u.value?(I(),O("div",{key:0,class:F(["math-block__content",{"math-rendering":g.value}]),innerHTML:u.value},null,10,be)):f.value?(I(),O("pre",ke,ce(f.value),1)):(I(),O("div",{key:2,class:F(["math-block__content",{"math-rendering":g.value}])},null,2))],12,pe))}}),[["__scopeId","data-v-939191ad"]]);N.install=S=>{S.component(N.__name,N)};export{N as default}; diff --git a/apps/kimi-code/dist-web/assets/index7-DnGHoBRb.js b/apps/kimi-code/dist-web/assets/index7-BT2SBznQ.js similarity index 98% rename from apps/kimi-code/dist-web/assets/index7-DnGHoBRb.js rename to apps/kimi-code/dist-web/assets/index7-BT2SBznQ.js index d5712e611..c35fdf607 100644 --- a/apps/kimi-code/dist-web/assets/index7-DnGHoBRb.js +++ b/apps/kimi-code/dist-web/assets/index7-BT2SBznQ.js @@ -1 +1 @@ -import{bQ as C,M as D,a0 as N,bS as U,bT as L,aU as h,bE as A,aD as K,az as W,aL as y,u as x,bb as z,s as H,bJ as P,v as M,aY as V,g as X,t as j,q as O,bU as q,bV as F,bW as J,bX as Q}from"./index-D1h84VfZ.js";var S=(f,b,r)=>new Promise((e,k)=>{var i=l=>{try{p(r.next(l))}catch(t){k(t)}},d=l=>{try{p(r.throw(l))}catch(t){k(t)}},p=l=>l.done?e(l.value):Promise.resolve(l.value).then(i,d);p((r=r.apply(f,b)).next())});const Y=["data-markstream-mode","data-markstream-pending"],G=["innerHTML"],Z={key:1,class:"math-inline math-inline--fallback"},ee={class:"math-inline__loading",role:"status","aria-live":"polite"},R=C(D({__name:"MathInlineNode",props:{node:{}},setup(f){var b,r;const e=f,k=h(null),i=O(()=>e.node.markup==="$$"),d=O(()=>q(e.node.content)),p=((r=(b=N())==null?void 0:b.vnode.el)==null?void 0:r.nodeType)===1,l=(function(){if(!e.node.content)return{html:"",text:e.node.loading?"":e.node.raw,loading:e.node.loading};if(e.node.loading)return{html:"",text:"",loading:!0};const a=U();if(!a){const n=typeof window>"u"||p;return{html:"",text:n?e.node.raw:"",loading:!n}}try{const n=a.renderToString(d.value,{throwOnError:!1,displayMode:i.value});return L(d.value,i.value,n),{html:n,text:"",loading:!1}}catch{return{html:"",text:e.node.loading?"":e.node.raw,loading:e.node.loading}}})(),t=h(l.html),u=h(l.text);let g=!1,m=0,s=!1,c=null;const v=h(l.loading),_=h(!1);function T(a){a!=null&&a!==m||(_.value=!1)}function B(){return S(this,null,function*(){if(s)return;c&&(c.abort(),c=null);const a=++m;if(!e.node.content)return T(),t.value="",u.value=e.node.loading?"":e.node.raw,v.value=e.node.loading,void(g=!1);const n=new AbortController;c=n,_.value=!0,s||a!==m||n.signal.aborted?T(a):F(d.value,i.value,{timeout:1500,waitTimeout:1500,maxRetries:8,signal:n.signal}).then(o=>{s||a!==m||(t.value=o,u.value="",v.value=!1,g=!0)}).catch(o=>S(null,null,function*(){if(s||a!==m)return;const w=o?.code||o?.name,$=w==="KATEX_DISABLED";if(w==="WORKER_INIT_ERROR"||o?.fallbackToRenderer||(w===J||w==="WORKER_TIMEOUT")&&!e.node.loading){const I=yield Q();if(s||a!==m)return;if(I){try{const E=I.renderToString(d.value,{throwOnError:e.node.loading,displayMode:i.value});t.value=E,u.value="",v.value=!1,g=!0,L(d.value,i.value,E)}catch{}return}}if($||!e.node.loading)return v.value=!1,t.value="",void(u.value=e.node.raw);g||(v.value=!0)})).finally(()=>{s||T(a)})})}return l.html&&(g=!0),A(()=>[e.node.content,e.node.loading,e.node.raw,e.node.markup],()=>{B()}),K(()=>{t.value||B()}),W(()=>{s=!0,c&&(c.abort(),c=null)}),(a,n)=>(y(),x("span",{ref_key:"containerEl",ref:k,class:"math-inline-wrapper","data-markstream-math":"inline","data-markstream-mode":t.value?"katex":u.value?"fallback":"loading","data-markstream-pending":_.value?"true":void 0},[t.value?(y(),x("span",{key:0,class:"math-inline",innerHTML:t.value},null,8,G)):u.value?(y(),x("span",Z,z(u.value),1)):v.value?(y(),H(X,{key:2,name:"table-node-fade"},{default:P(()=>[M("span",ee,[V(a.$slots,"loading",{isLoading:v.value},()=>[n[0]||(n[0]=M("span",{class:"math-inline__spinner animate-spin","aria-hidden":"true"},null,-1)),n[1]||(n[1]=M("span",{class:"sr-only"},"Loading",-1))],!0)])]),_:3})):j("",!0)],8,Y))}}),[["__scopeId","data-v-6c556261"]]);R.install=f=>{f.component(R.__name,R)};export{R as default}; +import{bQ as C,M as D,a0 as N,bS as U,bT as L,aU as h,bE as A,aD as K,az as W,aL as y,u as x,bb as z,s as H,bJ as P,v as M,aY as V,g as X,t as j,q as O,bU as q,bV as F,bW as J,bX as Q}from"./index-D-7nOosq.js";var S=(f,b,r)=>new Promise((e,k)=>{var i=l=>{try{p(r.next(l))}catch(t){k(t)}},d=l=>{try{p(r.throw(l))}catch(t){k(t)}},p=l=>l.done?e(l.value):Promise.resolve(l.value).then(i,d);p((r=r.apply(f,b)).next())});const Y=["data-markstream-mode","data-markstream-pending"],G=["innerHTML"],Z={key:1,class:"math-inline math-inline--fallback"},ee={class:"math-inline__loading",role:"status","aria-live":"polite"},R=C(D({__name:"MathInlineNode",props:{node:{}},setup(f){var b,r;const e=f,k=h(null),i=O(()=>e.node.markup==="$$"),d=O(()=>q(e.node.content)),p=((r=(b=N())==null?void 0:b.vnode.el)==null?void 0:r.nodeType)===1,l=(function(){if(!e.node.content)return{html:"",text:e.node.loading?"":e.node.raw,loading:e.node.loading};if(e.node.loading)return{html:"",text:"",loading:!0};const a=U();if(!a){const n=typeof window>"u"||p;return{html:"",text:n?e.node.raw:"",loading:!n}}try{const n=a.renderToString(d.value,{throwOnError:!1,displayMode:i.value});return L(d.value,i.value,n),{html:n,text:"",loading:!1}}catch{return{html:"",text:e.node.loading?"":e.node.raw,loading:e.node.loading}}})(),t=h(l.html),u=h(l.text);let g=!1,m=0,s=!1,c=null;const v=h(l.loading),_=h(!1);function T(a){a!=null&&a!==m||(_.value=!1)}function B(){return S(this,null,function*(){if(s)return;c&&(c.abort(),c=null);const a=++m;if(!e.node.content)return T(),t.value="",u.value=e.node.loading?"":e.node.raw,v.value=e.node.loading,void(g=!1);const n=new AbortController;c=n,_.value=!0,s||a!==m||n.signal.aborted?T(a):F(d.value,i.value,{timeout:1500,waitTimeout:1500,maxRetries:8,signal:n.signal}).then(o=>{s||a!==m||(t.value=o,u.value="",v.value=!1,g=!0)}).catch(o=>S(null,null,function*(){if(s||a!==m)return;const w=o?.code||o?.name,$=w==="KATEX_DISABLED";if(w==="WORKER_INIT_ERROR"||o?.fallbackToRenderer||(w===J||w==="WORKER_TIMEOUT")&&!e.node.loading){const I=yield Q();if(s||a!==m)return;if(I){try{const E=I.renderToString(d.value,{throwOnError:e.node.loading,displayMode:i.value});t.value=E,u.value="",v.value=!1,g=!0,L(d.value,i.value,E)}catch{}return}}if($||!e.node.loading)return v.value=!1,t.value="",void(u.value=e.node.raw);g||(v.value=!0)})).finally(()=>{s||T(a)})})}return l.html&&(g=!0),A(()=>[e.node.content,e.node.loading,e.node.raw,e.node.markup],()=>{B()}),K(()=>{t.value||B()}),W(()=>{s=!0,c&&(c.abort(),c=null)}),(a,n)=>(y(),x("span",{ref_key:"containerEl",ref:k,class:"math-inline-wrapper","data-markstream-math":"inline","data-markstream-mode":t.value?"katex":u.value?"fallback":"loading","data-markstream-pending":_.value?"true":void 0},[t.value?(y(),x("span",{key:0,class:"math-inline",innerHTML:t.value},null,8,G)):u.value?(y(),x("span",Z,z(u.value),1)):v.value?(y(),H(X,{key:2,name:"table-node-fade"},{default:P(()=>[M("span",ee,[V(a.$slots,"loading",{isLoading:v.value},()=>[n[0]||(n[0]=M("span",{class:"math-inline__spinner animate-spin","aria-hidden":"true"},null,-1)),n[1]||(n[1]=M("span",{class:"sr-only"},"Loading",-1))],!0)])]),_:3})):j("",!0)],8,Y))}}),[["__scopeId","data-v-6c556261"]]);R.install=f=>{f.component(R.__name,R)};export{R as default}; diff --git a/apps/kimi-code/dist-web/assets/index8-Dz0AkV3W.js b/apps/kimi-code/dist-web/assets/index8-BaK3y7fN.js similarity index 90% rename from apps/kimi-code/dist-web/assets/index8-Dz0AkV3W.js rename to apps/kimi-code/dist-web/assets/index8-BaK3y7fN.js index 95b28135e..769f0e8ce 100644 --- a/apps/kimi-code/dist-web/assets/index8-Dz0AkV3W.js +++ b/apps/kimi-code/dist-web/assets/index8-BaK3y7fN.js @@ -1 +1 @@ -import{bQ as ot,M as lt,bl as at,af as rt,bY as ut,b$ as it,c0 as st,c1 as ct,c2 as dt,aU as d,bE as Z,as as fe,aD as vt,az as mt,aL as v,u as m,v as u,bk as f,au as pe,bb as N,t as T,aw as ge,bL as ft,bB as pt,q as D,c7 as Se,c8 as gt,ca as ht,b_ as yt}from"./index-D1h84VfZ.js";var wt=Object.defineProperty,Le=Object.getOwnPropertySymbols,bt=Object.prototype.hasOwnProperty,kt=Object.prototype.propertyIsEnumerable,Ne=(p,n,i)=>n in p?wt(p,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):p[n]=i,he=(p,n)=>{for(var i in n||(n={}))bt.call(n,i)&&Ne(p,i,n[i]);if(Le)for(var i of Le(n))kt.call(n,i)&&Ne(p,i,n[i]);return p},ye=(p,n,i)=>new Promise((w,a)=>{var A=h=>{try{g(i.next(h))}catch(s){a(s)}},k=h=>{try{g(i.throw(h))}catch(s){a(s)}},g=h=>h.done?w(h.value):Promise.resolve(h.value).then(A,k);g((i=i.apply(p,n)).next())});const xt=["data-markstream-mode","data-markstream-pending"],Bt={key:0,class:"d2-block-header flex justify-between items-center border-b"},Dt={class:"d2-header-actions flex items-center"},Ct={key:0,class:"d2-mode-toggle flex items-center gap-0.5"},Mt=["aria-label"],Et={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},Tt={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},At=["aria-label"],jt=["aria-pressed"],Ot={key:0,class:"d2-source"},It={class:"d2-code"},Ft={key:0,class:"d2-error mt-2 text-xs"},Ht={key:1},St={key:0,class:"d2-source"},Lt={class:"d2-code"},Nt={key:0,class:"d2-error mt-2 text-xs"},Pt=["innerHTML"],Rt={key:0,class:"d2-error px-4 pb-3 text-xs"},we=ot(lt({__name:"D2BlockNode",props:{node:{},maxHeight:{default:void 0},loading:{type:Boolean,default:!0},isDark:{type:Boolean},progressiveRender:{type:Boolean,default:!0},progressiveIntervalMs:{default:700},themeId:{},darkThemeId:{},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0}},setup(p){const n=p,i=at(),w=rt(ut,null),{t:a}=it(),A=d(!1),k=d(!1),g=d(!1),h=d(!1),s=d(null),W=d(!1),j=d(""),ae=d(""),re=d(0),P=d(""),R=d(""),ee=d(null),ue=d(null),ie=d(null),Pe=st(),te=ct(),be=dt(),Y=d(null),ke=typeof window<"u",xe=d(!1),O=d(typeof window>"u"||!be.value),I=D(()=>{var t;return(t=n.node.code)!=null?t:""}),Re=D(()=>yt(n,i)),se=D(()=>{var t,e;return[n.isDark?"dark":"light",(t=n.themeId)!=null?t:"auto",(e=n.darkThemeId)!=null?e:"auto",I.value].join(":")}),ne=D(()=>!!j.value&&ae.value===se.value),Be=D(()=>{if(!xe.value||!I.value||g.value)return!1;const t=se.value;return!!W.value||P.value!==t&&(!s.value||R.value!==t)}),De=D(()=>ne.value||!!j.value&&Be.value),oe=D(()=>g.value||!h.value||!De.value),_e=D(()=>{if(oe.value&&ue.value)return{minHeight:`${ue.value}px`}}),Ue=D(()=>n.maxHeight==="none"?{maxHeight:"none"}:n.maxHeight!=null?{maxHeight:typeof n.maxHeight=="number"?`${n.maxHeight}px`:String(n.maxHeight)}:void 0);let x=null,ce=!1,_=!1,Ce=0,U=null,F=!1,$=null,C="";typeof window<"u"&&Z([()=>ie.value,be],([t,e])=>{var o,c,H;if((o=Y.value)==null||o.destroy(),Y.value=null,!e||O.value)return void(O.value=!0);if(!t)return void(O.value=!1);const S=(H=(c=te?.value.heavyBlockMargin)!=null?c:te?.value.rootMargin)!=null?H:"160px",V=Pe(t,{rootMargin:S,allowIdle:!1});Y.value=V,O.value=V.isVisible.value,V.whenVisible.then(()=>{O.value=!0})},{immediate:!0});const Ve={N1:"#E5E7EB",N2:"#CBD5E1",N3:"#94A3B8",N4:"#64748B",N5:"#475569",N6:"#334155",N7:"#0B1220",B1:"#60A5FA",B2:"#3B82F6",B3:"#2563EB",B4:"#1D4ED8",B5:"#1E40AF",B6:"#111827",AA2:"#22D3EE",AA4:"#0EA5E9",AA5:"#0284C7",AB4:"#FBBF24",AB5:"#F59E0B"};function Me(t){return!t||t.disabled}function M(t,e,o="top"){if(Me(t.currentTarget))return;const c=t,H=c?.clientX!=null&&c?.clientY!=null?{x:c.clientX,y:c.clientY}:void 0;Se(t.currentTarget,e,o,!1,H,n.isDark)}function b(){gt()}function Ee(t){if(Me(t.currentTarget))return;const e=A.value?a("common.copied")||"Copied":a("common.copy")||"Copy",o=t,c=o?.clientX!=null&&o?.clientY!=null?{x:o.clientX,y:o.clientY}:void 0;Se(t.currentTarget,e,"top",!1,c,n.isDark)}function ze(){return ye(this,null,function*(){try{const t=I.value;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(t)),A.value=!0,setTimeout(()=>{A.value=!1},1e3)}catch(t){console.error("Copy failed:",t)}})}function Ye(){k.value=!k.value}function Te(t){g.value=t==="source"}const $e=[/javascript:/i,/expression\s*\(/i,/url\s*\(\s*javascript:/i,/@import/i],qe=/^(?:https?:|mailto:|tel:|#|\/|data:image\/(?:png|gif|jpe?g|webp);)/i;function Xe(t){if(!t)return"";const e=t.trim();return qe.test(e)?e:""}function Ae(){j.value="",ae.value=""}function q(t){return _||t!==re.value}function Ge(){return ye(this,null,function*(){var t,e,o,c,H;if(!ke||_||!O.value||n.loading&&!n.progressiveRender)return;const S=se.value;if(S===P.value&&!s.value&&ne.value)return h.value=!0,void(n.loading&&(g.value=!1));const V=I.value;if(!V)return Ae(),s.value=null,P.value="",void(R.value="");const G=++re.value;W.value=!0,s.value=null,R.value="",(function(){const r=Re.value;w&&r&&C!==r&&(C&&w.markSettled(C),C=r,w.markPending(r))})();try{const r=yield(function(){return ye(this,null,function*(){if(x)return x;const l=yield ht();if(_||!l)return null;if(typeof l=="function"){const Q=new l;return Q&&typeof Q.compile=="function"?x=Q:typeof l.compile=="function"&&(x=l),x}return l?.D2&&typeof l.D2=="function"?(x=new l.D2,x):(typeof l.compile=="function"&&(x=l),x)})})();if(q(G))return;if(!r)return h.value=!1,g.value=!0,Ae(),s.value="D2 is not available.",void(R.value=S);if(typeof r.compile!="function"||typeof r.render!="function")throw new TypeError("D2 instance is missing compile/render methods.");h.value=!0;const y=yield r.compile(V);if(q(G))return;const le=(t=y?.diagram)!=null?t:y,B=(o=(e=y?.renderOptions)!=null?e:y?.options)!=null?o:{},Qe=(c=n.themeId)!=null?c:B.themeID,je=(H=n.darkThemeId)!=null?H:B.darkThemeID,J=he({},B);if(J.themeID=n.isDark&&je!=null?je:Qe,J.darkThemeID=null,J.darkThemeOverrides=null,n.isDark){const l=B.themeOverrides&&typeof B.themeOverrides=="object"?B.themeOverrides:null;J.themeOverrides=he(he({},Ve),l||{})}const Ke=yield r.render(le,J);if(q(G))return;const Oe=(function(l){return l?typeof l=="string"?l:typeof l.svg=="string"?l.svg:typeof l.data=="string"?l.data:"":""})(Ke);if(!Oe)throw new Error("D2 render returned empty output.");(function(l,Q){const Ie=(function(Fe){if(typeof window>"u"||typeof DOMParser>"u"||!Fe)return"";const Ze=Fe.replace(/["']\s*javascript:/gi,"#").replace(/\bjavascript:/gi,"#").replace(/["']\s*vbscript:/gi,"#").replace(/\bvbscript:/gi,"#").replace(/\bdata:text\/html/gi,"#"),ve=new DOMParser().parseFromString(Ze,"image/svg+xml").documentElement;if(!ve||ve.nodeName.toLowerCase()!=="svg")return"";const me=ve;return(function(He){const We=new Set(["script"]),et=[He,...Array.from(He.querySelectorAll("*"))];for(const L of et){if(We.has(L.tagName.toLowerCase())){L.remove();continue}const tt=Array.from(L.attributes);for(const z of tt){const E=z.name;if(/^on/i.test(E))L.removeAttribute(E);else{if(E==="style"&&z.value){const K=z.value;if($e.some(nt=>nt.test(K))){L.removeAttribute(E);continue}}if((E==="href"||E==="xlink:href")&&z.value){const K=Xe(z.value);if(!K){L.removeAttribute(E);continue}K!==z.value&&L.setAttribute(E,K)}}}}})(me),me.classList.add("markstream-d2-root-svg"),me.outerHTML})(l);j.value=Ie||"",ae.value=Ie?Q:""})(Oe,S),P.value=S,R.value="",n.loading&&(g.value=!1),s.value=null}catch(r){if(q(G))return;const y=r?.message?String(r.message):"D2 render failed.";n.loading||(s.value=y,R.value=S),P.value="",y.includes("@terrastruct/d2")&&(h.value=!1,g.value=!0)}finally{q(G)||(W.value=!1,F?(F=!1,X()):(function(){const r=C;w&&r&&(C="",fe(()=>{var y,le;if(!_){const B=(le=(y=ie.value)==null?void 0:y.offsetHeight)!=null?le:0;B>0&&w.reportHeight(r,B)}w.markSettled(r)}))})())}})}function X(t=!1){if(ce||!ke||_)return;if(W.value)return void(F=!0);const e=Math.max(120,Number(n.progressiveIntervalMs)||0),o=Date.now()-Ce;if(!t&&o<e)return F=!0,void(U==null&&(U=window.setTimeout(()=>{U=null,F&&(F=!1,X(!0))},Math.max(0,e-o))));ce=!0;const c=()=>{ce=!1,Ce=Date.now(),Ge()};typeof window<"u"&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(c):setTimeout(c,0)}function Je(){if(ne.value)try{const t=new Blob([j.value],{type:"image/svg+xml;charset=utf-8"}),e=URL.createObjectURL(t);if(typeof document<"u"){const o=document.createElement("a");o.href=e,o.download=`d2-diagram-${Date.now()}.svg`,document.body.appendChild(o),o.click(),document.body.removeChild(o)}URL.revokeObjectURL(e)}catch(t){console.error("Failed to export SVG:",t)}}function de(){const t=ee.value;if(!t)return;const e=t.getBoundingClientRect().height;e>0&&(ue.value=e)}return Z(()=>[n.node.code,n.loading,n.isDark,n.themeId,n.darkThemeId],()=>{X()},{immediate:!0}),Z(()=>n.loading,(t,e)=>{e&&!t&&X(!0)}),Z(()=>O.value,t=>{t&&X(!0)}),Z(()=>[oe.value,j.value,I.value],()=>{fe(()=>{de()})}),vt(()=>{xe.value=!0,fe(()=>{de()}),typeof ResizeObserver<"u"&&($=new ResizeObserver(()=>{de()}),ee.value&&$.observe(ee.value))}),mt(()=>{var t;_=!0,re.value+=1,F=!1,(function(){const e=C;w&&e&&(C="",w.markSettled(e))})(),P.value="",(t=Y.value)==null||t.destroy(),Y.value=null,U!=null&&(clearTimeout(U),U=null),$?.disconnect(),$=null}),(t,e)=>(v(),m("div",{ref_key:"viewportTarget",ref:ie,class:pe(["d2-block-container rounded-lg border overflow-hidden",{dark:n.isDark}]),"data-markstream-d2":"1","data-markstream-mode":oe.value?"fallback":"preview","data-markstream-pending":Be.value?"true":void 0},[n.showHeader?(v(),m("div",Bt,[e[16]||(e[16]=u("div",{class:"flex items-center gap-x-2"},[u("span",{class:"d2-label font-medium font-mono"},"D2")],-1)),u("div",Dt,[n.showModeToggle?(v(),m("div",Ct,[u("button",{type:"button",class:pe(["mode-btn px-2 py-0.5 rounded",g.value?"":"is-active"]),onClick:e[0]||(e[0]=o=>Te("preview")),onMouseenter:e[1]||(e[1]=o=>M(o,f(a)("common.preview")||"Preview")),onFocus:e[2]||(e[2]=o=>M(o,f(a)("common.preview")||"Preview")),onMouseleave:b,onBlur:b},N(f(a)("common.preview")||"Preview"),35),u("button",{type:"button",class:pe(["mode-btn px-2 py-0.5 rounded",g.value?"is-active":""]),onClick:e[3]||(e[3]=o=>Te("source")),onMouseenter:e[4]||(e[4]=o=>M(o,f(a)("common.source")||"Source")),onFocus:e[5]||(e[5]=o=>M(o,f(a)("common.source")||"Source")),onMouseleave:b,onBlur:b},N(f(a)("common.source")||"Source"),35)])):T("",!0),n.showCopyButton?(v(),m("button",{key:1,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-label":A.value?f(a)("common.copied")||"Copied":f(a)("common.copy")||"Copy",onClick:ze,onMouseenter:e[6]||(e[6]=o=>Ee(o)),onFocus:e[7]||(e[7]=o=>Ee(o)),onMouseleave:b,onBlur:b},[A.value?(v(),m("svg",Tt,[...e[13]||(e[13]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(v(),m("svg",Et,[...e[12]||(e[12]=[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),u("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],40,Mt)):T("",!0),n.showExportButton&&ne.value?(v(),m("button",{key:2,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-label":f(a)("common.export")||"Export",onClick:Je,onMouseenter:e[8]||(e[8]=o=>M(o,f(a)("common.export")||"Export")),onFocus:e[9]||(e[9]=o=>M(o,f(a)("common.export")||"Export")),onMouseleave:b,onBlur:b},[...e[14]||(e[14]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 3v12m0-12l-4 4m4-4l4 4M4 14v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4"})],-1)])],40,At)):T("",!0),n.showCollapseButton?(v(),m("button",{key:3,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-pressed":k.value,onClick:Ye,onMouseenter:e[10]||(e[10]=o=>M(o,k.value?f(a)("common.expand")||"Expand":f(a)("common.collapse")||"Collapse")),onFocus:e[11]||(e[11]=o=>M(o,k.value?f(a)("common.expand")||"Expand":f(a)("common.collapse")||"Collapse")),onMouseleave:b,onBlur:b},[(v(),m("svg",{style:ge({rotate:k.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...e[15]||(e[15]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,jt)):T("",!0)])])):T("",!0),ft(u("div",{ref_key:"bodyRef",ref:ee,class:"d2-block-body",style:ge(_e.value)},[n.loading&&!De.value?(v(),m("div",Ot,[u("pre",It,[u("code",null,N(I.value),1)]),s.value?(v(),m("p",Ft,N(s.value),1)):T("",!0)])):(v(),m("div",Ht,[oe.value?(v(),m("div",St,[u("pre",Lt,[u("code",null,N(I.value),1)]),s.value?(v(),m("p",Nt,N(s.value),1)):T("",!0)])):(v(),m("div",{key:1,class:"d2-render",style:ge(Ue.value)},[u("div",{class:"d2-svg",innerHTML:j.value},null,8,Pt),s.value?(v(),m("p",Rt,N(s.value),1)):T("",!0)],4))]))],4),[[pt,!k.value]])],10,xt))}}),[["__scopeId","data-v-3b434cf5"]]);we.install=p=>{p.component(we.__name,we)};export{we as default}; +import{bQ as ot,M as lt,bl as at,af as rt,bY as ut,b$ as it,c0 as st,c1 as ct,c2 as dt,aU as d,bE as Z,as as fe,aD as vt,az as mt,aL as v,u as m,v as u,bk as f,au as pe,bb as N,t as T,aw as ge,bL as ft,bB as pt,q as D,c7 as Se,c8 as gt,ca as ht,b_ as yt}from"./index-D-7nOosq.js";var wt=Object.defineProperty,Le=Object.getOwnPropertySymbols,bt=Object.prototype.hasOwnProperty,kt=Object.prototype.propertyIsEnumerable,Ne=(p,n,i)=>n in p?wt(p,n,{enumerable:!0,configurable:!0,writable:!0,value:i}):p[n]=i,he=(p,n)=>{for(var i in n||(n={}))bt.call(n,i)&&Ne(p,i,n[i]);if(Le)for(var i of Le(n))kt.call(n,i)&&Ne(p,i,n[i]);return p},ye=(p,n,i)=>new Promise((w,a)=>{var A=h=>{try{g(i.next(h))}catch(s){a(s)}},k=h=>{try{g(i.throw(h))}catch(s){a(s)}},g=h=>h.done?w(h.value):Promise.resolve(h.value).then(A,k);g((i=i.apply(p,n)).next())});const xt=["data-markstream-mode","data-markstream-pending"],Bt={key:0,class:"d2-block-header flex justify-between items-center border-b"},Dt={class:"d2-header-actions flex items-center"},Ct={key:0,class:"d2-mode-toggle flex items-center gap-0.5"},Mt=["aria-label"],Et={key:0,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},Tt={key:1,xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},At=["aria-label"],jt=["aria-pressed"],Ot={key:0,class:"d2-source"},Ft={class:"d2-code"},It={key:0,class:"d2-error mt-2 text-xs"},Ht={key:1},St={key:0,class:"d2-source"},Lt={class:"d2-code"},Nt={key:0,class:"d2-error mt-2 text-xs"},Pt=["innerHTML"],Rt={key:0,class:"d2-error px-4 pb-3 text-xs"},we=ot(lt({__name:"D2BlockNode",props:{node:{},maxHeight:{default:void 0},loading:{type:Boolean,default:!0},isDark:{type:Boolean},progressiveRender:{type:Boolean,default:!0},progressiveIntervalMs:{default:700},themeId:{},darkThemeId:{},showHeader:{type:Boolean,default:!0},showModeToggle:{type:Boolean,default:!0},showCopyButton:{type:Boolean,default:!0},showExportButton:{type:Boolean,default:!0},showCollapseButton:{type:Boolean,default:!0}},setup(p){const n=p,i=at(),w=rt(ut,null),{t:a}=it(),A=d(!1),k=d(!1),g=d(!1),h=d(!1),s=d(null),W=d(!1),j=d(""),ae=d(""),re=d(0),P=d(""),R=d(""),ee=d(null),ue=d(null),ie=d(null),Pe=st(),te=ct(),be=dt(),Y=d(null),ke=typeof window<"u",xe=d(!1),O=d(typeof window>"u"||!be.value),F=D(()=>{var t;return(t=n.node.code)!=null?t:""}),Re=D(()=>yt(n,i)),se=D(()=>{var t,e;return[n.isDark?"dark":"light",(t=n.themeId)!=null?t:"auto",(e=n.darkThemeId)!=null?e:"auto",F.value].join(":")}),ne=D(()=>!!j.value&&ae.value===se.value),Be=D(()=>{if(!xe.value||!F.value||g.value)return!1;const t=se.value;return!!W.value||P.value!==t&&(!s.value||R.value!==t)}),De=D(()=>ne.value||!!j.value&&Be.value),oe=D(()=>g.value||!h.value||!De.value),_e=D(()=>{if(oe.value&&ue.value)return{minHeight:`${ue.value}px`}}),Ue=D(()=>n.maxHeight==="none"?{maxHeight:"none"}:n.maxHeight!=null?{maxHeight:typeof n.maxHeight=="number"?`${n.maxHeight}px`:String(n.maxHeight)}:void 0);let x=null,ce=!1,_=!1,Ce=0,U=null,I=!1,$=null,C="";typeof window<"u"&&Z([()=>ie.value,be],([t,e])=>{var o,c,H;if((o=Y.value)==null||o.destroy(),Y.value=null,!e||O.value)return void(O.value=!0);if(!t)return void(O.value=!1);const S=(H=(c=te?.value.heavyBlockMargin)!=null?c:te?.value.rootMargin)!=null?H:"160px",V=Pe(t,{rootMargin:S,allowIdle:!1});Y.value=V,O.value=V.isVisible.value,V.whenVisible.then(()=>{O.value=!0})},{immediate:!0});const Ve={N1:"#E5E7EB",N2:"#CBD5E1",N3:"#94A3B8",N4:"#64748B",N5:"#475569",N6:"#334155",N7:"#0B1220",B1:"#60A5FA",B2:"#3B82F6",B3:"#2563EB",B4:"#1D4ED8",B5:"#1E40AF",B6:"#111827",AA2:"#22D3EE",AA4:"#0EA5E9",AA5:"#0284C7",AB4:"#FBBF24",AB5:"#F59E0B"};function Me(t){return!t||t.disabled}function M(t,e,o="top"){if(Me(t.currentTarget))return;const c=t,H=c?.clientX!=null&&c?.clientY!=null?{x:c.clientX,y:c.clientY}:void 0;Se(t.currentTarget,e,o,!1,H,n.isDark)}function b(){gt()}function Ee(t){if(Me(t.currentTarget))return;const e=A.value?a("common.copied")||"Copied":a("common.copy")||"Copy",o=t,c=o?.clientX!=null&&o?.clientY!=null?{x:o.clientX,y:o.clientY}:void 0;Se(t.currentTarget,e,"top",!1,c,n.isDark)}function ze(){return ye(this,null,function*(){try{const t=F.value;typeof navigator<"u"&&navigator.clipboard&&typeof navigator.clipboard.writeText=="function"&&(yield navigator.clipboard.writeText(t)),A.value=!0,setTimeout(()=>{A.value=!1},1e3)}catch(t){console.error("Copy failed:",t)}})}function Ye(){k.value=!k.value}function Te(t){g.value=t==="source"}const $e=[/javascript:/i,/expression\s*\(/i,/url\s*\(\s*javascript:/i,/@import/i],qe=/^(?:https?:|mailto:|tel:|#|\/|data:image\/(?:png|gif|jpe?g|webp);)/i;function Xe(t){if(!t)return"";const e=t.trim();return qe.test(e)?e:""}function Ae(){j.value="",ae.value=""}function q(t){return _||t!==re.value}function Ge(){return ye(this,null,function*(){var t,e,o,c,H;if(!ke||_||!O.value||n.loading&&!n.progressiveRender)return;const S=se.value;if(S===P.value&&!s.value&&ne.value)return h.value=!0,void(n.loading&&(g.value=!1));const V=F.value;if(!V)return Ae(),s.value=null,P.value="",void(R.value="");const G=++re.value;W.value=!0,s.value=null,R.value="",(function(){const r=Re.value;w&&r&&C!==r&&(C&&w.markSettled(C),C=r,w.markPending(r))})();try{const r=yield(function(){return ye(this,null,function*(){if(x)return x;const l=yield ht();if(_||!l)return null;if(typeof l=="function"){const Q=new l;return Q&&typeof Q.compile=="function"?x=Q:typeof l.compile=="function"&&(x=l),x}return l?.D2&&typeof l.D2=="function"?(x=new l.D2,x):(typeof l.compile=="function"&&(x=l),x)})})();if(q(G))return;if(!r)return h.value=!1,g.value=!0,Ae(),s.value="D2 is not available.",void(R.value=S);if(typeof r.compile!="function"||typeof r.render!="function")throw new TypeError("D2 instance is missing compile/render methods.");h.value=!0;const y=yield r.compile(V);if(q(G))return;const le=(t=y?.diagram)!=null?t:y,B=(o=(e=y?.renderOptions)!=null?e:y?.options)!=null?o:{},Qe=(c=n.themeId)!=null?c:B.themeID,je=(H=n.darkThemeId)!=null?H:B.darkThemeID,J=he({},B);if(J.themeID=n.isDark&&je!=null?je:Qe,J.darkThemeID=null,J.darkThemeOverrides=null,n.isDark){const l=B.themeOverrides&&typeof B.themeOverrides=="object"?B.themeOverrides:null;J.themeOverrides=he(he({},Ve),l||{})}const Ke=yield r.render(le,J);if(q(G))return;const Oe=(function(l){return l?typeof l=="string"?l:typeof l.svg=="string"?l.svg:typeof l.data=="string"?l.data:"":""})(Ke);if(!Oe)throw new Error("D2 render returned empty output.");(function(l,Q){const Fe=(function(Ie){if(typeof window>"u"||typeof DOMParser>"u"||!Ie)return"";const Ze=Ie.replace(/["']\s*javascript:/gi,"#").replace(/\bjavascript:/gi,"#").replace(/["']\s*vbscript:/gi,"#").replace(/\bvbscript:/gi,"#").replace(/\bdata:text\/html/gi,"#"),ve=new DOMParser().parseFromString(Ze,"image/svg+xml").documentElement;if(!ve||ve.nodeName.toLowerCase()!=="svg")return"";const me=ve;return(function(He){const We=new Set(["script"]),et=[He,...Array.from(He.querySelectorAll("*"))];for(const L of et){if(We.has(L.tagName.toLowerCase())){L.remove();continue}const tt=Array.from(L.attributes);for(const z of tt){const E=z.name;if(/^on/i.test(E))L.removeAttribute(E);else{if(E==="style"&&z.value){const K=z.value;if($e.some(nt=>nt.test(K))){L.removeAttribute(E);continue}}if((E==="href"||E==="xlink:href")&&z.value){const K=Xe(z.value);if(!K){L.removeAttribute(E);continue}K!==z.value&&L.setAttribute(E,K)}}}}})(me),me.classList.add("markstream-d2-root-svg"),me.outerHTML})(l);j.value=Fe||"",ae.value=Fe?Q:""})(Oe,S),P.value=S,R.value="",n.loading&&(g.value=!1),s.value=null}catch(r){if(q(G))return;const y=r?.message?String(r.message):"D2 render failed.";n.loading||(s.value=y,R.value=S),P.value="",y.includes("@terrastruct/d2")&&(h.value=!1,g.value=!0)}finally{q(G)||(W.value=!1,I?(I=!1,X()):(function(){const r=C;w&&r&&(C="",fe(()=>{var y,le;if(!_){const B=(le=(y=ie.value)==null?void 0:y.offsetHeight)!=null?le:0;B>0&&w.reportHeight(r,B)}w.markSettled(r)}))})())}})}function X(t=!1){if(ce||!ke||_)return;if(W.value)return void(I=!0);const e=Math.max(120,Number(n.progressiveIntervalMs)||0),o=Date.now()-Ce;if(!t&&o<e)return I=!0,void(U==null&&(U=window.setTimeout(()=>{U=null,I&&(I=!1,X(!0))},Math.max(0,e-o))));ce=!0;const c=()=>{ce=!1,Ce=Date.now(),Ge()};typeof window<"u"&&typeof window.requestAnimationFrame=="function"?window.requestAnimationFrame(c):setTimeout(c,0)}function Je(){if(ne.value)try{const t=new Blob([j.value],{type:"image/svg+xml;charset=utf-8"}),e=URL.createObjectURL(t);if(typeof document<"u"){const o=document.createElement("a");o.href=e,o.download=`d2-diagram-${Date.now()}.svg`,document.body.appendChild(o),o.click(),document.body.removeChild(o)}URL.revokeObjectURL(e)}catch(t){console.error("Failed to export SVG:",t)}}function de(){const t=ee.value;if(!t)return;const e=t.getBoundingClientRect().height;e>0&&(ue.value=e)}return Z(()=>[n.node.code,n.loading,n.isDark,n.themeId,n.darkThemeId],()=>{X()},{immediate:!0}),Z(()=>n.loading,(t,e)=>{e&&!t&&X(!0)}),Z(()=>O.value,t=>{t&&X(!0)}),Z(()=>[oe.value,j.value,F.value],()=>{fe(()=>{de()})}),vt(()=>{xe.value=!0,fe(()=>{de()}),typeof ResizeObserver<"u"&&($=new ResizeObserver(()=>{de()}),ee.value&&$.observe(ee.value))}),mt(()=>{var t;_=!0,re.value+=1,I=!1,(function(){const e=C;w&&e&&(C="",w.markSettled(e))})(),P.value="",(t=Y.value)==null||t.destroy(),Y.value=null,U!=null&&(clearTimeout(U),U=null),$?.disconnect(),$=null}),(t,e)=>(v(),m("div",{ref_key:"viewportTarget",ref:ie,class:pe(["d2-block-container rounded-lg border overflow-hidden",{dark:n.isDark}]),"data-markstream-d2":"1","data-markstream-mode":oe.value?"fallback":"preview","data-markstream-pending":Be.value?"true":void 0},[n.showHeader?(v(),m("div",Bt,[e[16]||(e[16]=u("div",{class:"flex items-center gap-x-2"},[u("span",{class:"d2-label font-medium font-mono"},"D2")],-1)),u("div",Dt,[n.showModeToggle?(v(),m("div",Ct,[u("button",{type:"button",class:pe(["mode-btn px-2 py-0.5 rounded",g.value?"":"is-active"]),onClick:e[0]||(e[0]=o=>Te("preview")),onMouseenter:e[1]||(e[1]=o=>M(o,f(a)("common.preview")||"Preview")),onFocus:e[2]||(e[2]=o=>M(o,f(a)("common.preview")||"Preview")),onMouseleave:b,onBlur:b},N(f(a)("common.preview")||"Preview"),35),u("button",{type:"button",class:pe(["mode-btn px-2 py-0.5 rounded",g.value?"is-active":""]),onClick:e[3]||(e[3]=o=>Te("source")),onMouseenter:e[4]||(e[4]=o=>M(o,f(a)("common.source")||"Source")),onFocus:e[5]||(e[5]=o=>M(o,f(a)("common.source")||"Source")),onMouseleave:b,onBlur:b},N(f(a)("common.source")||"Source"),35)])):T("",!0),n.showCopyButton?(v(),m("button",{key:1,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-label":A.value?f(a)("common.copied")||"Copied":f(a)("common.copy")||"Copy",onClick:ze,onMouseenter:e[6]||(e[6]=o=>Ee(o)),onFocus:e[7]||(e[7]=o=>Ee(o)),onMouseleave:b,onBlur:b},[A.value?(v(),m("svg",Tt,[...e[13]||(e[13]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M20 6L9 17l-5-5"},null,-1)])])):(v(),m("svg",Et,[...e[12]||(e[12]=[u("g",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2"},[u("rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}),u("path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"})],-1)])]))],40,Mt)):T("",!0),n.showExportButton&&ne.value?(v(),m("button",{key:2,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-label":f(a)("common.export")||"Export",onClick:Je,onMouseenter:e[8]||(e[8]=o=>M(o,f(a)("common.export")||"Export")),onFocus:e[9]||(e[9]=o=>M(o,f(a)("common.export")||"Export")),onMouseleave:b,onBlur:b},[...e[14]||(e[14]=[u("svg",{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"M12 3v12m0-12l-4 4m4-4l4 4M4 14v4a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-4"})],-1)])],40,At)):T("",!0),n.showCollapseButton?(v(),m("button",{key:3,type:"button",class:"d2-action-btn p-[var(--ms-action-btn-padding)] rounded-md","aria-pressed":k.value,onClick:Ye,onMouseenter:e[10]||(e[10]=o=>M(o,k.value?f(a)("common.expand")||"Expand":f(a)("common.collapse")||"Collapse")),onFocus:e[11]||(e[11]=o=>M(o,k.value?f(a)("common.expand")||"Expand":f(a)("common.collapse")||"Collapse")),onMouseleave:b,onBlur:b},[(v(),m("svg",{style:ge({rotate:k.value?"0deg":"90deg"}),xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",role:"img",width:"1em",height:"1em",viewBox:"0 0 24 24",class:"action-icon"},[...e[15]||(e[15]=[u("path",{fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-linejoin":"round","stroke-width":"2",d:"m9 18l6-6l-6-6"},null,-1)])],4))],40,jt)):T("",!0)])])):T("",!0),ft(u("div",{ref_key:"bodyRef",ref:ee,class:"d2-block-body",style:ge(_e.value)},[n.loading&&!De.value?(v(),m("div",Ot,[u("pre",Ft,[u("code",null,N(F.value),1)]),s.value?(v(),m("p",It,N(s.value),1)):T("",!0)])):(v(),m("div",Ht,[oe.value?(v(),m("div",St,[u("pre",Lt,[u("code",null,N(F.value),1)]),s.value?(v(),m("p",Nt,N(s.value),1)):T("",!0)])):(v(),m("div",{key:1,class:"d2-render",style:ge(Ue.value)},[u("div",{class:"d2-svg",innerHTML:j.value},null,8,Pt),s.value?(v(),m("p",Rt,N(s.value),1)):T("",!0)],4))]))],4),[[pt,!k.value]])],10,xt))}}),[["__scopeId","data-v-3b434cf5"]]);we.install=p=>{p.component(we.__name,we)};export{we as default}; diff --git a/apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-YBdL8hE1.js b/apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-DASw56fH.js similarity index 69% rename from apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-YBdL8hE1.js rename to apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-DASw56fH.js index 482fd2d76..a37e1ec64 100644 --- a/apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-YBdL8hE1.js +++ b/apps/kimi-code/dist-web/assets/infoDiagram-FWYZ7A6U-DASw56fH.js @@ -1,2 +1,2 @@ -import{_ as a,l as s,F as n,e as i}from"./mermaid.core-DaDTfY6S.js";import{p}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var g={parse:a(async r=>{const e=await p("info",r);s.debug(e)},"parse")},v={version:"11.16.0"},d=a(()=>v.version,"getVersion"),m={getVersion:d},c=a((r,e,o)=>{s.debug(`rendering info diagram +import{_ as a,l as s,F as n,e as i}from"./mermaid.core-CJB1tAev.js";import{p}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var g={parse:a(async r=>{const e=await p("info",r);s.debug(e)},"parse")},v={version:"11.16.0"},d=a(()=>v.version,"getVersion"),m={getVersion:d},c=a((r,e,o)=>{s.debug(`rendering info diagram `+r);const t=n(e);i(t,100,400,!0),t.append("g").append("text").attr("x",100).attr("y",40).attr("class","version").attr("font-size",32).style("text-anchor","middle").text(`v${o}`)},"draw"),l={draw:c},w={parser:g,db:m,renderer:l};export{w as diagram}; diff --git a/apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CJxOHefD.js b/apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CcPuml-k.js similarity index 99% rename from apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CJxOHefD.js rename to apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CcPuml-k.js index 1ac38f105..45e219b38 100644 --- a/apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CJxOHefD.js +++ b/apps/kimi-code/dist-web/assets/ishikawaDiagram-FXEZZL3T-CcPuml-k.js @@ -1,4 +1,4 @@ -import{_ as l,c as lt,a1 as ct,F as ut,al as dt,q as yt,k as ft,o as et,a as pt,b as gt,g as kt,s as mt,p as wt,e as _t}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var Q=(function(){var t=l(function(T,e,s,i){for(s=s||{},i=T.length;i--;s[T[i]]=e);return s},"o"),d=[1,4],n=[1,14],a=[1,12],o=[1,13],y=[6,7,8],p=[1,20],u=[1,18],m=[1,19],c=[6,7,11],k=[1,6,13,14],g=[1,23],_=[1,24],x=[1,6,7,11,13,14],D={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ishikawa:4,spaceLines:5,SPACELINE:6,NL:7,ISHIKAWA:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,TEXT:14,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"ISHIKAWA",11:"EOF",13:"SPACELIST",14:"TEXT"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,1],[12,1],[12,1]],performAction:l(function(e,s,i,h,f,r,v){var w=r.length-1;switch(f){case 6:case 7:return h;case 15:h.addNode(r[w-1].length,r[w].trim());break;case 16:h.addNode(0,r[w].trim());break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:d},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:d},{6:n,7:[1,10],9:9,12:11,13:a,14:o},t(y,[2,3]),{1:[2,2]},t(y,[2,4]),t(y,[2,5]),{1:[2,6],6:n,12:15,13:a,14:o},{6:n,9:16,12:11,13:a,14:o},{6:p,7:u,10:17,11:m},t(c,[2,18],{14:[1,21]}),t(c,[2,16]),t(c,[2,17]),{6:p,7:u,10:22,11:m},{1:[2,7],6:n,12:15,13:a,14:o},t(k,[2,14],{7:g,11:_}),t(x,[2,8]),t(x,[2,9]),t(x,[2,10]),t(c,[2,15]),t(k,[2,13],{7:g,11:_}),t(x,[2,11]),t(x,[2,12])],defaultActions:{2:[2,1],6:[2,2]},parseError:l(function(e,s){if(s.recoverable)this.trace(e);else{var i=new Error(e);throw i.hash=s,i}},"parseError"),parse:l(function(e){var s=this,i=[0],h=[],f=[null],r=[],v=this.table,w="",I=0,$=0,L=2,A=1,C=r.slice.call(arguments,1),b=Object.create(this.lexer),S={yy:{}};for(var P in this.yy)Object.prototype.hasOwnProperty.call(this.yy,P)&&(S.yy[P]=this.yy[P]);b.setInput(e,S.yy),S.yy.lexer=b,S.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var R=b.yylloc;r.push(R);var H=b.options&&b.options.ranges;typeof S.yy.parseError=="function"?this.parseError=S.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function X(B){i.length=i.length-2*B,f.length=f.length-B,r.length=r.length-B}l(X,"popStack");function J(){var B;return B=h.pop()||b.lex()||A,typeof B!="number"&&(B instanceof Array&&(h=B,B=h.pop()),B=s.symbols_[B]||B),B}l(J,"lex");for(var M,F,N,Y,W={},G,V,tt,U;;){if(F=i[i.length-1],this.defaultActions[F]?N=this.defaultActions[F]:((M===null||typeof M>"u")&&(M=J()),N=v[F]&&v[F][M]),typeof N>"u"||!N.length||!N[0]){var q="";U=[];for(G in v[F])this.terminals_[G]&&G>L&&U.push("'"+this.terminals_[G]+"'");b.showPosition?q="Parse error on line "+(I+1)+`: +import{_ as l,c as lt,a1 as ct,F as ut,al as dt,q as yt,k as ft,o as et,a as pt,b as gt,g as kt,s as mt,p as wt,e as _t}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var Q=(function(){var t=l(function(T,e,s,i){for(s=s||{},i=T.length;i--;s[T[i]]=e);return s},"o"),d=[1,4],n=[1,14],a=[1,12],o=[1,13],y=[6,7,8],p=[1,20],u=[1,18],m=[1,19],c=[6,7,11],k=[1,6,13,14],g=[1,23],_=[1,24],x=[1,6,7,11,13,14],D={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,ishikawa:4,spaceLines:5,SPACELINE:6,NL:7,ISHIKAWA:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,TEXT:14,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"ISHIKAWA",11:"EOF",13:"SPACELIST",14:"TEXT"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,1],[12,1],[12,1]],performAction:l(function(e,s,i,h,f,r,v){var w=r.length-1;switch(f){case 6:case 7:return h;case 15:h.addNode(r[w-1].length,r[w].trim());break;case 16:h.addNode(0,r[w].trim());break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:d},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:d},{6:n,7:[1,10],9:9,12:11,13:a,14:o},t(y,[2,3]),{1:[2,2]},t(y,[2,4]),t(y,[2,5]),{1:[2,6],6:n,12:15,13:a,14:o},{6:n,9:16,12:11,13:a,14:o},{6:p,7:u,10:17,11:m},t(c,[2,18],{14:[1,21]}),t(c,[2,16]),t(c,[2,17]),{6:p,7:u,10:22,11:m},{1:[2,7],6:n,12:15,13:a,14:o},t(k,[2,14],{7:g,11:_}),t(x,[2,8]),t(x,[2,9]),t(x,[2,10]),t(c,[2,15]),t(k,[2,13],{7:g,11:_}),t(x,[2,11]),t(x,[2,12])],defaultActions:{2:[2,1],6:[2,2]},parseError:l(function(e,s){if(s.recoverable)this.trace(e);else{var i=new Error(e);throw i.hash=s,i}},"parseError"),parse:l(function(e){var s=this,i=[0],h=[],f=[null],r=[],v=this.table,w="",I=0,$=0,L=2,A=1,C=r.slice.call(arguments,1),b=Object.create(this.lexer),S={yy:{}};for(var P in this.yy)Object.prototype.hasOwnProperty.call(this.yy,P)&&(S.yy[P]=this.yy[P]);b.setInput(e,S.yy),S.yy.lexer=b,S.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var R=b.yylloc;r.push(R);var H=b.options&&b.options.ranges;typeof S.yy.parseError=="function"?this.parseError=S.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function X(B){i.length=i.length-2*B,f.length=f.length-B,r.length=r.length-B}l(X,"popStack");function J(){var B;return B=h.pop()||b.lex()||A,typeof B!="number"&&(B instanceof Array&&(h=B,B=h.pop()),B=s.symbols_[B]||B),B}l(J,"lex");for(var M,F,N,Y,W={},G,V,tt,U;;){if(F=i[i.length-1],this.defaultActions[F]?N=this.defaultActions[F]:((M===null||typeof M>"u")&&(M=J()),N=v[F]&&v[F][M]),typeof N>"u"||!N.length||!N[0]){var q="";U=[];for(G in v[F])this.terminals_[G]&&G>L&&U.push("'"+this.terminals_[G]+"'");b.showPosition?q="Parse error on line "+(I+1)+`: `+b.showPosition()+` Expecting `+U.join(", ")+", got '"+(this.terminals_[M]||M)+"'":q="Parse error on line "+(I+1)+": Unexpected "+(M==A?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError(q,{text:b.match,token:this.terminals_[M]||M,line:b.yylineno,loc:R,expected:U})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+F+", token: "+M);switch(N[0]){case 1:i.push(M),f.push(b.yytext),r.push(b.yylloc),i.push(N[1]),M=null,$=b.yyleng,w=b.yytext,I=b.yylineno,R=b.yylloc;break;case 2:if(V=this.productions_[N[1]][1],W.$=f[f.length-V],W._$={first_line:r[r.length-(V||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(V||1)].first_column,last_column:r[r.length-1].last_column},H&&(W._$.range=[r[r.length-(V||1)].range[0],r[r.length-1].range[1]]),Y=this.performAction.apply(W,[w,$,I,S.yy,N[1],f,r].concat(C)),typeof Y<"u")return Y;V&&(i=i.slice(0,-1*V*2),f=f.slice(0,-1*V),r=r.slice(0,-1*V)),i.push(this.productions_[N[1]][0]),f.push(W.$),r.push(W._$),tt=v[i[i.length-2]][i[i.length-1]],i.push(tt);break;case 3:return!0}}return!0},"parse")},O=(function(){var T={EOF:1,parseError:l(function(s,i){if(this.yy.parser)this.yy.parser.parseError(s,i);else throw new Error(s)},"parseError"),setInput:l(function(e,s){return this.yy=s||this.yy||{},this._input=e,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:l(function(){var e=this._input[0];this.yytext+=e,this.yyleng++,this.offset++,this.match+=e,this.matched+=e;var s=e.match(/(?:\r\n?|\n).*/g);return s?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),e},"input"),unput:l(function(e){var s=e.length,i=e.split(/(?:\r\n?|\n)/g);this._input=e+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-s),this.offset-=s;var h=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),i.length-1&&(this.yylineno-=i.length-1);var f=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:i?(i.length===h.length?this.yylloc.first_column:0)+h[h.length-i.length].length-i[0].length:this.yylloc.first_column-s},this.options.ranges&&(this.yylloc.range=[f[0],f[0]+this.yyleng-s]),this.yyleng=this.yytext.length,this},"unput"),more:l(function(){return this._more=!0,this},"more"),reject:l(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:l(function(e){this.unput(this.match.slice(e))},"less"),pastInput:l(function(){var e=this.matched.substr(0,this.matched.length-this.match.length);return(e.length>20?"...":"")+e.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:l(function(){var e=this.match;return e.length<20&&(e+=this._input.substr(0,20-e.length)),(e.substr(0,20)+(e.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:l(function(){var e=this.pastInput(),s=new Array(e.length+1).join("-");return e+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-DHq-P2j9.js b/apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-BShuBRgf.js similarity index 98% rename from apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-DHq-P2j9.js rename to apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-BShuBRgf.js index fd3d88162..81454d202 100644 --- a/apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-DHq-P2j9.js +++ b/apps/kimi-code/dist-web/assets/journeyDiagram-5HDEW3XC-BShuBRgf.js @@ -1,4 +1,4 @@ -import{g as gt}from"./chunk-5VM5RSS4-B87d3yQb.js";import{a as mt,g as lt,h as xt,d as kt}from"./chunk-32BRIVSS-_Sd4SrsJ.js";import{g as _t,s as vt,a as bt,b as wt,p as Tt,o as St,_ as s,c as R,d as X,e as $t,q as Mt}from"./mermaid.core-DaDTfY6S.js";import{d as it}from"./arc-CC9q5kjc.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var U=(function(){var t=s(function(h,r,n,l){for(n=n||{},l=h.length;l--;n[h[l]]=r);return n},"o"),e=[6,8,10,11,12,14,16,17,18],a=[1,9],f=[1,10],i=[1,11],u=[1,12],p=[1,13],o=[1,14],g={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:s(function(r,n,l,y,d,c,v){var k=c.length-1;switch(d){case 1:return c[k-1];case 2:this.$=[];break;case 3:c[k-1].push(c[k]),this.$=c[k-1];break;case 4:case 5:this.$=c[k];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(c[k].substr(6)),this.$=c[k].substr(6);break;case 9:this.$=c[k].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=c[k].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(c[k].substr(8)),this.$=c[k].substr(8);break;case 13:y.addTask(c[k-1],c[k]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:a,12:f,14:i,16:u,17:p,18:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:a,12:f,14:i,16:u,17:p,18:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:s(function(r,n){if(n.recoverable)this.trace(r);else{var l=new Error(r);throw l.hash=n,l}},"parseError"),parse:s(function(r){var n=this,l=[0],y=[],d=[null],c=[],v=this.table,k="",C=0,Q=0,yt=2,D=1,dt=c.slice.call(arguments,1),_=Object.create(this.lexer),I={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(I.yy[O]=this.yy[O]);_.setInput(r,I.yy),I.yy.lexer=_,I.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var Y=_.yylloc;c.push(Y);var ft=_.options&&_.options.ranges;typeof I.yy.parseError=="function"?this.parseError=I.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pt(w){l.length=l.length-2*w,d.length=d.length-w,c.length=c.length-w}s(pt,"popStack");function tt(){var w;return w=y.pop()||_.lex()||D,typeof w!="number"&&(w instanceof Array&&(y=w,w=y.pop()),w=n.symbols_[w]||w),w}s(tt,"lex");for(var b,A,T,q,F={},N,M,et,z;;){if(A=l[l.length-1],this.defaultActions[A]?T=this.defaultActions[A]:((b===null||typeof b>"u")&&(b=tt()),T=v[A]&&v[A][b]),typeof T>"u"||!T.length||!T[0]){var H="";z=[];for(N in v[A])this.terminals_[N]&&N>yt&&z.push("'"+this.terminals_[N]+"'");_.showPosition?H="Parse error on line "+(C+1)+`: +import{g as gt}from"./chunk-5VM5RSS4-yyj9cAyF.js";import{a as mt,g as lt,h as xt,d as kt}from"./chunk-32BRIVSS-DUDRPqmY.js";import{g as _t,s as vt,a as bt,b as wt,p as Tt,o as St,_ as s,c as R,d as X,e as $t,q as Mt}from"./mermaid.core-CJB1tAev.js";import{d as it}from"./arc-IkhU3FHH.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var U=(function(){var t=s(function(h,r,n,l){for(n=n||{},l=h.length;l--;n[h[l]]=r);return n},"o"),e=[6,8,10,11,12,14,16,17,18],a=[1,9],f=[1,10],i=[1,11],u=[1,12],p=[1,13],o=[1,14],g={trace:s(function(){},"trace"),yy:{},symbols_:{error:2,start:3,journey:4,document:5,EOF:6,line:7,SPACE:8,statement:9,NEWLINE:10,title:11,acc_title:12,acc_title_value:13,acc_descr:14,acc_descr_value:15,acc_descr_multiline_value:16,section:17,taskName:18,taskData:19,$accept:0,$end:1},terminals_:{2:"error",4:"journey",6:"EOF",8:"SPACE",10:"NEWLINE",11:"title",12:"acc_title",13:"acc_title_value",14:"acc_descr",15:"acc_descr_value",16:"acc_descr_multiline_value",17:"section",18:"taskName",19:"taskData"},productions_:[0,[3,3],[5,0],[5,2],[7,2],[7,1],[7,1],[7,1],[9,1],[9,2],[9,2],[9,1],[9,1],[9,2]],performAction:s(function(r,n,l,y,d,c,v){var k=c.length-1;switch(d){case 1:return c[k-1];case 2:this.$=[];break;case 3:c[k-1].push(c[k]),this.$=c[k-1];break;case 4:case 5:this.$=c[k];break;case 6:case 7:this.$=[];break;case 8:y.setDiagramTitle(c[k].substr(6)),this.$=c[k].substr(6);break;case 9:this.$=c[k].trim(),y.setAccTitle(this.$);break;case 10:case 11:this.$=c[k].trim(),y.setAccDescription(this.$);break;case 12:y.addSection(c[k].substr(8)),this.$=c[k].substr(8);break;case 13:y.addTask(c[k-1],c[k]),this.$="task";break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},t(e,[2,2],{5:3}),{6:[1,4],7:5,8:[1,6],9:7,10:[1,8],11:a,12:f,14:i,16:u,17:p,18:o},t(e,[2,7],{1:[2,1]}),t(e,[2,3]),{9:15,11:a,12:f,14:i,16:u,17:p,18:o},t(e,[2,5]),t(e,[2,6]),t(e,[2,8]),{13:[1,16]},{15:[1,17]},t(e,[2,11]),t(e,[2,12]),{19:[1,18]},t(e,[2,4]),t(e,[2,9]),t(e,[2,10]),t(e,[2,13])],defaultActions:{},parseError:s(function(r,n){if(n.recoverable)this.trace(r);else{var l=new Error(r);throw l.hash=n,l}},"parseError"),parse:s(function(r){var n=this,l=[0],y=[],d=[null],c=[],v=this.table,k="",C=0,Q=0,yt=2,D=1,dt=c.slice.call(arguments,1),_=Object.create(this.lexer),I={yy:{}};for(var O in this.yy)Object.prototype.hasOwnProperty.call(this.yy,O)&&(I.yy[O]=this.yy[O]);_.setInput(r,I.yy),I.yy.lexer=_,I.yy.parser=this,typeof _.yylloc>"u"&&(_.yylloc={});var Y=_.yylloc;c.push(Y);var ft=_.options&&_.options.ranges;typeof I.yy.parseError=="function"?this.parseError=I.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pt(w){l.length=l.length-2*w,d.length=d.length-w,c.length=c.length-w}s(pt,"popStack");function tt(){var w;return w=y.pop()||_.lex()||D,typeof w!="number"&&(w instanceof Array&&(y=w,w=y.pop()),w=n.symbols_[w]||w),w}s(tt,"lex");for(var b,A,T,q,F={},N,M,et,z;;){if(A=l[l.length-1],this.defaultActions[A]?T=this.defaultActions[A]:((b===null||typeof b>"u")&&(b=tt()),T=v[A]&&v[A][b]),typeof T>"u"||!T.length||!T[0]){var H="";z=[];for(N in v[A])this.terminals_[N]&&N>yt&&z.push("'"+this.terminals_[N]+"'");_.showPosition?H="Parse error on line "+(C+1)+`: `+_.showPosition()+` Expecting `+z.join(", ")+", got '"+(this.terminals_[b]||b)+"'":H="Parse error on line "+(C+1)+": Unexpected "+(b==D?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(H,{text:_.match,token:this.terminals_[b]||b,line:_.yylineno,loc:Y,expected:z})}if(T[0]instanceof Array&&T.length>1)throw new Error("Parse Error: multiple actions possible at state: "+A+", token: "+b);switch(T[0]){case 1:l.push(b),d.push(_.yytext),c.push(_.yylloc),l.push(T[1]),b=null,Q=_.yyleng,k=_.yytext,C=_.yylineno,Y=_.yylloc;break;case 2:if(M=this.productions_[T[1]][1],F.$=d[d.length-M],F._$={first_line:c[c.length-(M||1)].first_line,last_line:c[c.length-1].last_line,first_column:c[c.length-(M||1)].first_column,last_column:c[c.length-1].last_column},ft&&(F._$.range=[c[c.length-(M||1)].range[0],c[c.length-1].range[1]]),q=this.performAction.apply(F,[k,Q,C,I.yy,T[1],d,c].concat(dt)),typeof q<"u")return q;M&&(l=l.slice(0,-1*M*2),d=d.slice(0,-1*M),c=c.slice(0,-1*M)),l.push(this.productions_[T[1]][0]),d.push(F.$),c.push(F._$),et=v[l[l.length-2]][l[l.length-1]],l.push(et);break;case 3:return!0}}return!0},"parse")},m=(function(){var h={EOF:1,parseError:s(function(n,l){if(this.yy.parser)this.yy.parser.parseError(n,l);else throw new Error(n)},"parseError"),setInput:s(function(r,n){return this.yy=n||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:s(function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var n=r.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},"input"),unput:s(function(r){var n=r.length,l=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),l.length-1&&(this.yylineno-=l.length-1);var d=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:l?(l.length===y.length?this.yylloc.first_column:0)+y[y.length-l.length].length-l[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[d[0],d[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},"unput"),more:s(function(){return this._more=!0,this},"more"),reject:s(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:s(function(r){this.unput(this.match.slice(r))},"less"),pastInput:s(function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:s(function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:s(function(){var r=this.pastInput(),n=new Array(r.length+1).join("-");return r+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-C6iL68OT.js b/apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-_UoHLqzR.js similarity index 99% rename from apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-C6iL68OT.js rename to apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-_UoHLqzR.js index d7d244bdd..a53d9abea 100644 --- a/apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-C6iL68OT.js +++ b/apps/kimi-code/dist-web/assets/kanban-definition-HUTT4EX6-_UoHLqzR.js @@ -1,4 +1,4 @@ -import{_ as o,l as te,c as H,F as fe,af as ye,ag as be,ah as me,ad as _e,D as Y,i as j,Y as ke,Z as Ee,aa as Se,ab as ce,ac as le}from"./mermaid.core-DaDTfY6S.js";import{g as Ne}from"./chunk-5VM5RSS4-B87d3yQb.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var $=(function(){var e=o(function(O,i,n,r){for(n=n||{},r=O.length;r--;n[O[r]]=i);return n},"o"),h=[1,4],p=[1,13],s=[1,12],d=[1,15],_=[1,16],m=[1,20],l=[1,19],D=[6,7,8],I=[1,26],g=[1,24],w=[1,25],k=[6,7,11],G=[1,31],N=[6,7,11,24],V=[1,6,13,16,17,20,23],f=[1,35],A=[1,36],L=[1,6,7,11,13,16,17,20,23],M=[1,38],T={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:o(function(i,n,r,a,u,t,U){var c=t.length-1;switch(u){case 6:case 7:return a;case 8:a.getLogger().trace("Stop NL ");break;case 9:a.getLogger().trace("Stop EOF ");break;case 11:a.getLogger().trace("Stop NL2 ");break;case 12:a.getLogger().trace("Stop EOF2 ");break;case 15:a.getLogger().info("Node: ",t[c-1].id),a.addNode(t[c-2].length,t[c-1].id,t[c-1].descr,t[c-1].type,t[c]);break;case 16:a.getLogger().info("Node: ",t[c].id),a.addNode(t[c-1].length,t[c].id,t[c].descr,t[c].type);break;case 17:a.getLogger().trace("Icon: ",t[c]),a.decorateNode({icon:t[c]});break;case 18:case 23:a.decorateNode({class:t[c]});break;case 19:a.getLogger().trace("SPACELIST");break;case 20:a.getLogger().trace("Node: ",t[c-1].id),a.addNode(0,t[c-1].id,t[c-1].descr,t[c-1].type,t[c]);break;case 21:a.getLogger().trace("Node: ",t[c].id),a.addNode(0,t[c].id,t[c].descr,t[c].type);break;case 22:a.decorateNode({icon:t[c]});break;case 27:a.getLogger().trace("node found ..",t[c-2]),this.$={id:t[c-1],descr:t[c-1],type:a.getType(t[c-2],t[c])};break;case 28:this.$={id:t[c],descr:t[c],type:0};break;case 29:a.getLogger().trace("node found ..",t[c-3]),this.$={id:t[c-3],descr:t[c-1],type:a.getType(t[c-2],t[c])};break;case 30:this.$=t[c-1]+t[c];break;case 31:this.$=t[c];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:h},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:h},{6:p,7:[1,10],9:9,12:11,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},e(D,[2,3]),{1:[2,2]},e(D,[2,4]),e(D,[2,5]),{1:[2,6],6:p,12:21,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},{6:p,9:22,12:11,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},{6:I,7:g,10:23,11:w},e(k,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:m,23:l}),e(k,[2,19]),e(k,[2,21],{15:30,24:G}),e(k,[2,22]),e(k,[2,23]),e(N,[2,25]),e(N,[2,26]),e(N,[2,28],{20:[1,32]}),{21:[1,33]},{6:I,7:g,10:34,11:w},{1:[2,7],6:p,12:21,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},e(V,[2,14],{7:f,11:A}),e(L,[2,8]),e(L,[2,9]),e(L,[2,10]),e(k,[2,16],{15:37,24:G}),e(k,[2,17]),e(k,[2,18]),e(k,[2,20],{24:M}),e(N,[2,31]),{21:[1,39]},{22:[1,40]},e(V,[2,13],{7:f,11:A}),e(L,[2,11]),e(L,[2,12]),e(k,[2,15],{24:M}),e(N,[2,30]),{22:[1,41]},e(N,[2,27]),e(N,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(i,n){if(n.recoverable)this.trace(i);else{var r=new Error(i);throw r.hash=n,r}},"parseError"),parse:o(function(i){var n=this,r=[0],a=[],u=[null],t=[],U=this.table,c="",W=0,se=0,ue=2,re=1,ge=t.slice.call(arguments,1),b=Object.create(this.lexer),R={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(R.yy[J]=this.yy[J]);b.setInput(i,R.yy),R.yy.lexer=b,R.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var Z=b.yylloc;t.push(Z);var de=b.options&&b.options.ranges;typeof R.yy.parseError=="function"?this.parseError=R.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pe(S){r.length=r.length-2*S,u.length=u.length-S,t.length=t.length-S}o(pe,"popStack");function ae(){var S;return S=a.pop()||b.lex()||re,typeof S!="number"&&(S instanceof Array&&(a=S,S=a.pop()),S=n.symbols_[S]||S),S}o(ae,"lex");for(var E,P,x,q,F={},z,C,oe,X;;){if(P=r[r.length-1],this.defaultActions[P]?x=this.defaultActions[P]:((E===null||typeof E>"u")&&(E=ae()),x=U[P]&&U[P][E]),typeof x>"u"||!x.length||!x[0]){var Q="";X=[];for(z in U[P])this.terminals_[z]&&z>ue&&X.push("'"+this.terminals_[z]+"'");b.showPosition?Q="Parse error on line "+(W+1)+`: +import{_ as o,l as te,c as H,F as fe,af as ye,ag as be,ah as me,ad as _e,D as Y,i as j,Y as ke,Z as Ee,aa as Se,ab as ce,ac as le}from"./mermaid.core-CJB1tAev.js";import{g as Ne}from"./chunk-5VM5RSS4-yyj9cAyF.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var $=(function(){var e=o(function(O,i,n,r){for(n=n||{},r=O.length;r--;n[O[r]]=i);return n},"o"),h=[1,4],p=[1,13],s=[1,12],d=[1,15],_=[1,16],m=[1,20],l=[1,19],D=[6,7,8],I=[1,26],g=[1,24],w=[1,25],k=[6,7,11],G=[1,31],N=[6,7,11,24],V=[1,6,13,16,17,20,23],f=[1,35],A=[1,36],L=[1,6,7,11,13,16,17,20,23],M=[1,38],T={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,KANBAN:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,shapeData:15,ICON:16,CLASS:17,nodeWithId:18,nodeWithoutId:19,NODE_DSTART:20,NODE_DESCR:21,NODE_DEND:22,NODE_ID:23,SHAPE_DATA:24,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"KANBAN",11:"EOF",13:"SPACELIST",16:"ICON",17:"CLASS",20:"NODE_DSTART",21:"NODE_DESCR",22:"NODE_DEND",23:"NODE_ID",24:"SHAPE_DATA"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,3],[12,2],[12,2],[12,2],[12,1],[12,2],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[19,3],[18,1],[18,4],[15,2],[15,1]],performAction:o(function(i,n,r,a,u,t,U){var c=t.length-1;switch(u){case 6:case 7:return a;case 8:a.getLogger().trace("Stop NL ");break;case 9:a.getLogger().trace("Stop EOF ");break;case 11:a.getLogger().trace("Stop NL2 ");break;case 12:a.getLogger().trace("Stop EOF2 ");break;case 15:a.getLogger().info("Node: ",t[c-1].id),a.addNode(t[c-2].length,t[c-1].id,t[c-1].descr,t[c-1].type,t[c]);break;case 16:a.getLogger().info("Node: ",t[c].id),a.addNode(t[c-1].length,t[c].id,t[c].descr,t[c].type);break;case 17:a.getLogger().trace("Icon: ",t[c]),a.decorateNode({icon:t[c]});break;case 18:case 23:a.decorateNode({class:t[c]});break;case 19:a.getLogger().trace("SPACELIST");break;case 20:a.getLogger().trace("Node: ",t[c-1].id),a.addNode(0,t[c-1].id,t[c-1].descr,t[c-1].type,t[c]);break;case 21:a.getLogger().trace("Node: ",t[c].id),a.addNode(0,t[c].id,t[c].descr,t[c].type);break;case 22:a.decorateNode({icon:t[c]});break;case 27:a.getLogger().trace("node found ..",t[c-2]),this.$={id:t[c-1],descr:t[c-1],type:a.getType(t[c-2],t[c])};break;case 28:this.$={id:t[c],descr:t[c],type:0};break;case 29:a.getLogger().trace("node found ..",t[c-3]),this.$={id:t[c-3],descr:t[c-1],type:a.getType(t[c-2],t[c])};break;case 30:this.$=t[c-1]+t[c];break;case 31:this.$=t[c];break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:h},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:h},{6:p,7:[1,10],9:9,12:11,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},e(D,[2,3]),{1:[2,2]},e(D,[2,4]),e(D,[2,5]),{1:[2,6],6:p,12:21,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},{6:p,9:22,12:11,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},{6:I,7:g,10:23,11:w},e(k,[2,24],{18:17,19:18,14:27,16:[1,28],17:[1,29],20:m,23:l}),e(k,[2,19]),e(k,[2,21],{15:30,24:G}),e(k,[2,22]),e(k,[2,23]),e(N,[2,25]),e(N,[2,26]),e(N,[2,28],{20:[1,32]}),{21:[1,33]},{6:I,7:g,10:34,11:w},{1:[2,7],6:p,12:21,13:s,14:14,16:d,17:_,18:17,19:18,20:m,23:l},e(V,[2,14],{7:f,11:A}),e(L,[2,8]),e(L,[2,9]),e(L,[2,10]),e(k,[2,16],{15:37,24:G}),e(k,[2,17]),e(k,[2,18]),e(k,[2,20],{24:M}),e(N,[2,31]),{21:[1,39]},{22:[1,40]},e(V,[2,13],{7:f,11:A}),e(L,[2,11]),e(L,[2,12]),e(k,[2,15],{24:M}),e(N,[2,30]),{22:[1,41]},e(N,[2,27]),e(N,[2,29])],defaultActions:{2:[2,1],6:[2,2]},parseError:o(function(i,n){if(n.recoverable)this.trace(i);else{var r=new Error(i);throw r.hash=n,r}},"parseError"),parse:o(function(i){var n=this,r=[0],a=[],u=[null],t=[],U=this.table,c="",W=0,se=0,ue=2,re=1,ge=t.slice.call(arguments,1),b=Object.create(this.lexer),R={yy:{}};for(var J in this.yy)Object.prototype.hasOwnProperty.call(this.yy,J)&&(R.yy[J]=this.yy[J]);b.setInput(i,R.yy),R.yy.lexer=b,R.yy.parser=this,typeof b.yylloc>"u"&&(b.yylloc={});var Z=b.yylloc;t.push(Z);var de=b.options&&b.options.ranges;typeof R.yy.parseError=="function"?this.parseError=R.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function pe(S){r.length=r.length-2*S,u.length=u.length-S,t.length=t.length-S}o(pe,"popStack");function ae(){var S;return S=a.pop()||b.lex()||re,typeof S!="number"&&(S instanceof Array&&(a=S,S=a.pop()),S=n.symbols_[S]||S),S}o(ae,"lex");for(var E,P,x,q,F={},z,C,oe,X;;){if(P=r[r.length-1],this.defaultActions[P]?x=this.defaultActions[P]:((E===null||typeof E>"u")&&(E=ae()),x=U[P]&&U[P][E]),typeof x>"u"||!x.length||!x[0]){var Q="";X=[];for(z in U[P])this.terminals_[z]&&z>ue&&X.push("'"+this.terminals_[z]+"'");b.showPosition?Q="Parse error on line "+(W+1)+`: `+b.showPosition()+` Expecting `+X.join(", ")+", got '"+(this.terminals_[E]||E)+"'":Q="Parse error on line "+(W+1)+": Unexpected "+(E==re?"end of input":"'"+(this.terminals_[E]||E)+"'"),this.parseError(Q,{text:b.match,token:this.terminals_[E]||E,line:b.yylineno,loc:Z,expected:X})}if(x[0]instanceof Array&&x.length>1)throw new Error("Parse Error: multiple actions possible at state: "+P+", token: "+E);switch(x[0]){case 1:r.push(E),u.push(b.yytext),t.push(b.yylloc),r.push(x[1]),E=null,se=b.yyleng,c=b.yytext,W=b.yylineno,Z=b.yylloc;break;case 2:if(C=this.productions_[x[1]][1],F.$=u[u.length-C],F._$={first_line:t[t.length-(C||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(C||1)].first_column,last_column:t[t.length-1].last_column},de&&(F._$.range=[t[t.length-(C||1)].range[0],t[t.length-1].range[1]]),q=this.performAction.apply(F,[c,se,W,R.yy,x[1],u,t].concat(ge)),typeof q<"u")return q;C&&(r=r.slice(0,-1*C*2),u=u.slice(0,-1*C),t=t.slice(0,-1*C)),r.push(this.productions_[x[1]][0]),u.push(F.$),t.push(F._$),oe=U[r[r.length-2]][r[r.length-1]],r.push(oe);break;case 3:return!0}}return!0},"parse")},K=(function(){var O={EOF:1,parseError:o(function(n,r){if(this.yy.parser)this.yy.parser.parseError(n,r);else throw new Error(n)},"parseError"),setInput:o(function(i,n){return this.yy=n||this.yy||{},this._input=i,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var i=this._input[0];this.yytext+=i,this.yyleng++,this.offset++,this.match+=i,this.matched+=i;var n=i.match(/(?:\r\n?|\n).*/g);return n?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),i},"input"),unput:o(function(i){var n=i.length,r=i.split(/(?:\r\n?|\n)/g);this._input=i+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-n),this.offset-=n;var a=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),r.length-1&&(this.yylineno-=r.length-1);var u=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:r?(r.length===a.length?this.yylloc.first_column:0)+a[a.length-r.length].length-r[0].length:this.yylloc.first_column-n},this.options.ranges&&(this.yylloc.range=[u[0],u[0]+this.yyleng-n]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(i){this.unput(this.match.slice(i))},"less"),pastInput:o(function(){var i=this.matched.substr(0,this.matched.length-this.match.length);return(i.length>20?"...":"")+i.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var i=this.match;return i.length<20&&(i+=this._input.substr(0,20-i.length)),(i.substr(0,20)+(i.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var i=this.pastInput(),n=new Array(i.length+1).join("-");return i+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/linear-BmFm-Eu7.js b/apps/kimi-code/dist-web/assets/linear-DH49UJnN.js similarity index 98% rename from apps/kimi-code/dist-web/assets/linear-BmFm-Eu7.js rename to apps/kimi-code/dist-web/assets/linear-DH49UJnN.js index a71e07285..e3bd183a1 100644 --- a/apps/kimi-code/dist-web/assets/linear-BmFm-Eu7.js +++ b/apps/kimi-code/dist-web/assets/linear-DH49UJnN.js @@ -1 +1 @@ -import{b9 as j,ba as p,bb as w,bc as k,bd as q}from"./mermaid.core-DaDTfY6S.js";import{i as D}from"./init-Gi6I4Gst.js";import{e as g,f as F,a as z,b as B}from"./defaultLocale-DX6XiGOO.js";function M(n,r){return n==null||r==null?NaN:n<r?-1:n>r?1:n>=r?0:NaN}function I(n,r){return n==null||r==null?NaN:r<n?-1:r>n?1:r>=n?0:NaN}function R(n){let r,t,e;n.length!==2?(r=M,t=(o,c)=>M(n(o),c),e=(o,c)=>n(o)-c):(r=n===M||n===I?n:P,t=n,e=n);function u(o,c,i=0,h=o.length){if(i<h){if(r(c,c)!==0)return h;do{const l=i+h>>>1;t(o[l],c)<0?i=l+1:h=l}while(i<h)}return i}function f(o,c,i=0,h=o.length){if(i<h){if(r(c,c)!==0)return h;do{const l=i+h>>>1;t(o[l],c)<=0?i=l+1:h=l}while(i<h)}return i}function a(o,c,i=0,h=o.length){const l=u(o,c,i,h-1);return l>i&&e(o[l-1],c)>-e(o[l],c)?l-1:l}return{left:u,center:a,right:f}}function P(){return 0}function V(n){return n===null?NaN:+n}const $=R(M),x=$.right;R(V).center;const O=Math.sqrt(50),T=Math.sqrt(10),C=Math.sqrt(2);function v(n,r,t){const e=(r-n)/Math.max(0,t),u=Math.floor(Math.log10(e)),f=e/Math.pow(10,u),a=f>=O?10:f>=T?5:f>=C?2:1;let o,c,i;return u<0?(i=Math.pow(10,-u)/a,o=Math.round(n*i),c=Math.round(r*i),o/i<n&&++o,c/i>r&&--c,i=-i):(i=Math.pow(10,u)*a,o=Math.round(n/i),c=Math.round(r/i),o*i<n&&++o,c*i>r&&--c),c<o&&.5<=t&&t<2?v(n,r,t*2):[o,c,i]}function E(n,r,t){if(r=+r,n=+n,t=+t,!(t>0))return[];if(n===r)return[n];const e=r<n,[u,f,a]=e?v(r,n,t):v(n,r,t);if(!(f>=u))return[];const o=f-u+1,c=new Array(o);if(e)if(a<0)for(let i=0;i<o;++i)c[i]=(f-i)/-a;else for(let i=0;i<o;++i)c[i]=(f-i)*a;else if(a<0)for(let i=0;i<o;++i)c[i]=(u+i)/-a;else for(let i=0;i<o;++i)c[i]=(u+i)*a;return c}function y(n,r,t){return r=+r,n=+n,t=+t,v(n,r,t)[2]}function G(n,r,t){r=+r,n=+n,t=+t;const e=r<n,u=e?y(r,n,t):y(n,r,t);return(e?-1:1)*(u<0?1/-u:u)}function H(n,r){r||(r=[]);var t=n?Math.min(r.length,n.length):0,e=r.slice(),u;return function(f){for(u=0;u<t;++u)e[u]=n[u]*(1-f)+r[u]*f;return e}}function J(n){return ArrayBuffer.isView(n)&&!(n instanceof DataView)}function K(n,r){var t=r?r.length:0,e=n?Math.min(t,n.length):0,u=new Array(e),f=new Array(t),a;for(a=0;a<e;++a)u[a]=N(n[a],r[a]);for(;a<t;++a)f[a]=r[a];return function(o){for(a=0;a<e;++a)f[a]=u[a](o);return f}}function L(n,r){var t=new Date;return n=+n,r=+r,function(e){return t.setTime(n*(1-e)+r*e),t}}function Q(n,r){var t={},e={},u;(n===null||typeof n!="object")&&(n={}),(r===null||typeof r!="object")&&(r={});for(u in r)u in n?t[u]=N(n[u],r[u]):e[u]=r[u];return function(f){for(u in t)e[u]=t[u](f);return e}}function N(n,r){var t=typeof r,e;return r==null||t==="boolean"?j(r):(t==="number"?p:t==="string"?(e=w(r))?(r=e,k):q:r instanceof w?k:r instanceof Date?L:J(r)?H:Array.isArray(r)?K:typeof r.valueOf!="function"&&typeof r.toString!="function"||isNaN(r)?Q:p)(n,r)}function U(n,r){return n=+n,r=+r,function(t){return Math.round(n*(1-t)+r*t)}}function W(n){return Math.max(0,-g(Math.abs(n)))}function X(n,r){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(g(r)/3)))*3-g(Math.abs(n)))}function Y(n,r){return n=Math.abs(n),r=Math.abs(r)-n,Math.max(0,g(r)-g(n))+1}function Z(n){return function(){return n}}function _(n){return+n}var A=[0,1];function m(n){return n}function d(n,r){return(r-=n=+n)?function(t){return(t-n)/r}:Z(isNaN(r)?NaN:.5)}function b(n,r){var t;return n>r&&(t=n,n=r,r=t),function(e){return Math.max(n,Math.min(r,e))}}function nn(n,r,t){var e=n[0],u=n[1],f=r[0],a=r[1];return u<e?(e=d(u,e),f=t(a,f)):(e=d(e,u),f=t(f,a)),function(o){return f(e(o))}}function rn(n,r,t){var e=Math.min(n.length,r.length)-1,u=new Array(e),f=new Array(e),a=-1;for(n[e]<n[0]&&(n=n.slice().reverse(),r=r.slice().reverse());++a<e;)u[a]=d(n[a],n[a+1]),f[a]=t(r[a],r[a+1]);return function(o){var c=x(n,o,1,e)-1;return f[c](u[c](o))}}function en(n,r){return r.domain(n.domain()).range(n.range()).interpolate(n.interpolate()).clamp(n.clamp()).unknown(n.unknown())}function tn(){var n=A,r=A,t=N,e,u,f,a=m,o,c,i;function h(){var s=Math.min(n.length,r.length);return a!==m&&(a=b(n[0],n[s-1])),o=s>2?rn:nn,c=i=null,l}function l(s){return s==null||isNaN(s=+s)?f:(c||(c=o(n.map(e),r,t)))(e(a(s)))}return l.invert=function(s){return a(u((i||(i=o(r,n.map(e),p)))(s)))},l.domain=function(s){return arguments.length?(n=Array.from(s,_),h()):n.slice()},l.range=function(s){return arguments.length?(r=Array.from(s),h()):r.slice()},l.rangeRound=function(s){return r=Array.from(s),t=U,h()},l.clamp=function(s){return arguments.length?(a=s?!0:m,h()):a!==m},l.interpolate=function(s){return arguments.length?(t=s,h()):t},l.unknown=function(s){return arguments.length?(f=s,l):f},function(s,S){return e=s,u=S,h()}}function un(){return tn()(m,m)}function an(n,r,t,e){var u=G(n,r,t),f;switch(e=F(e??",f"),e.type){case"s":{var a=Math.max(Math.abs(n),Math.abs(r));return e.precision==null&&!isNaN(f=X(u,a))&&(e.precision=f),z(e,a)}case"":case"e":case"g":case"p":case"r":{e.precision==null&&!isNaN(f=Y(u,Math.max(Math.abs(n),Math.abs(r))))&&(e.precision=f-(e.type==="e"));break}case"f":case"%":{e.precision==null&&!isNaN(f=W(u))&&(e.precision=f-(e.type==="%")*2);break}}return B(e)}function on(n){var r=n.domain;return n.ticks=function(t){var e=r();return E(e[0],e[e.length-1],t??10)},n.tickFormat=function(t,e){var u=r();return an(u[0],u[u.length-1],t??10,e)},n.nice=function(t){t==null&&(t=10);var e=r(),u=0,f=e.length-1,a=e[u],o=e[f],c,i,h=10;for(o<a&&(i=a,a=o,o=i,i=u,u=f,f=i);h-- >0;){if(i=y(a,o,t),i===c)return e[u]=a,e[f]=o,r(e);if(i>0)a=Math.floor(a/i)*i,o=Math.ceil(o/i)*i;else if(i<0)a=Math.ceil(a*i)/i,o=Math.floor(o*i)/i;else break;c=i}return n},n}function fn(){var n=un();return n.copy=function(){return en(n,fn())},D.apply(n,arguments),on(n)}export{en as a,R as b,un as c,fn as l,G as t}; +import{b9 as j,ba as p,bb as w,bc as k,bd as q}from"./mermaid.core-CJB1tAev.js";import{i as D}from"./init-Gi6I4Gst.js";import{e as g,f as F,a as z,b as B}from"./defaultLocale-DX6XiGOO.js";function M(n,r){return n==null||r==null?NaN:n<r?-1:n>r?1:n>=r?0:NaN}function I(n,r){return n==null||r==null?NaN:r<n?-1:r>n?1:r>=n?0:NaN}function R(n){let r,t,e;n.length!==2?(r=M,t=(o,c)=>M(n(o),c),e=(o,c)=>n(o)-c):(r=n===M||n===I?n:P,t=n,e=n);function u(o,c,i=0,h=o.length){if(i<h){if(r(c,c)!==0)return h;do{const l=i+h>>>1;t(o[l],c)<0?i=l+1:h=l}while(i<h)}return i}function f(o,c,i=0,h=o.length){if(i<h){if(r(c,c)!==0)return h;do{const l=i+h>>>1;t(o[l],c)<=0?i=l+1:h=l}while(i<h)}return i}function a(o,c,i=0,h=o.length){const l=u(o,c,i,h-1);return l>i&&e(o[l-1],c)>-e(o[l],c)?l-1:l}return{left:u,center:a,right:f}}function P(){return 0}function V(n){return n===null?NaN:+n}const $=R(M),x=$.right;R(V).center;const O=Math.sqrt(50),T=Math.sqrt(10),C=Math.sqrt(2);function v(n,r,t){const e=(r-n)/Math.max(0,t),u=Math.floor(Math.log10(e)),f=e/Math.pow(10,u),a=f>=O?10:f>=T?5:f>=C?2:1;let o,c,i;return u<0?(i=Math.pow(10,-u)/a,o=Math.round(n*i),c=Math.round(r*i),o/i<n&&++o,c/i>r&&--c,i=-i):(i=Math.pow(10,u)*a,o=Math.round(n/i),c=Math.round(r/i),o*i<n&&++o,c*i>r&&--c),c<o&&.5<=t&&t<2?v(n,r,t*2):[o,c,i]}function E(n,r,t){if(r=+r,n=+n,t=+t,!(t>0))return[];if(n===r)return[n];const e=r<n,[u,f,a]=e?v(r,n,t):v(n,r,t);if(!(f>=u))return[];const o=f-u+1,c=new Array(o);if(e)if(a<0)for(let i=0;i<o;++i)c[i]=(f-i)/-a;else for(let i=0;i<o;++i)c[i]=(f-i)*a;else if(a<0)for(let i=0;i<o;++i)c[i]=(u+i)/-a;else for(let i=0;i<o;++i)c[i]=(u+i)*a;return c}function y(n,r,t){return r=+r,n=+n,t=+t,v(n,r,t)[2]}function G(n,r,t){r=+r,n=+n,t=+t;const e=r<n,u=e?y(r,n,t):y(n,r,t);return(e?-1:1)*(u<0?1/-u:u)}function H(n,r){r||(r=[]);var t=n?Math.min(r.length,n.length):0,e=r.slice(),u;return function(f){for(u=0;u<t;++u)e[u]=n[u]*(1-f)+r[u]*f;return e}}function J(n){return ArrayBuffer.isView(n)&&!(n instanceof DataView)}function K(n,r){var t=r?r.length:0,e=n?Math.min(t,n.length):0,u=new Array(e),f=new Array(t),a;for(a=0;a<e;++a)u[a]=N(n[a],r[a]);for(;a<t;++a)f[a]=r[a];return function(o){for(a=0;a<e;++a)f[a]=u[a](o);return f}}function L(n,r){var t=new Date;return n=+n,r=+r,function(e){return t.setTime(n*(1-e)+r*e),t}}function Q(n,r){var t={},e={},u;(n===null||typeof n!="object")&&(n={}),(r===null||typeof r!="object")&&(r={});for(u in r)u in n?t[u]=N(n[u],r[u]):e[u]=r[u];return function(f){for(u in t)e[u]=t[u](f);return e}}function N(n,r){var t=typeof r,e;return r==null||t==="boolean"?j(r):(t==="number"?p:t==="string"?(e=w(r))?(r=e,k):q:r instanceof w?k:r instanceof Date?L:J(r)?H:Array.isArray(r)?K:typeof r.valueOf!="function"&&typeof r.toString!="function"||isNaN(r)?Q:p)(n,r)}function U(n,r){return n=+n,r=+r,function(t){return Math.round(n*(1-t)+r*t)}}function W(n){return Math.max(0,-g(Math.abs(n)))}function X(n,r){return Math.max(0,Math.max(-8,Math.min(8,Math.floor(g(r)/3)))*3-g(Math.abs(n)))}function Y(n,r){return n=Math.abs(n),r=Math.abs(r)-n,Math.max(0,g(r)-g(n))+1}function Z(n){return function(){return n}}function _(n){return+n}var A=[0,1];function m(n){return n}function d(n,r){return(r-=n=+n)?function(t){return(t-n)/r}:Z(isNaN(r)?NaN:.5)}function b(n,r){var t;return n>r&&(t=n,n=r,r=t),function(e){return Math.max(n,Math.min(r,e))}}function nn(n,r,t){var e=n[0],u=n[1],f=r[0],a=r[1];return u<e?(e=d(u,e),f=t(a,f)):(e=d(e,u),f=t(f,a)),function(o){return f(e(o))}}function rn(n,r,t){var e=Math.min(n.length,r.length)-1,u=new Array(e),f=new Array(e),a=-1;for(n[e]<n[0]&&(n=n.slice().reverse(),r=r.slice().reverse());++a<e;)u[a]=d(n[a],n[a+1]),f[a]=t(r[a],r[a+1]);return function(o){var c=x(n,o,1,e)-1;return f[c](u[c](o))}}function en(n,r){return r.domain(n.domain()).range(n.range()).interpolate(n.interpolate()).clamp(n.clamp()).unknown(n.unknown())}function tn(){var n=A,r=A,t=N,e,u,f,a=m,o,c,i;function h(){var s=Math.min(n.length,r.length);return a!==m&&(a=b(n[0],n[s-1])),o=s>2?rn:nn,c=i=null,l}function l(s){return s==null||isNaN(s=+s)?f:(c||(c=o(n.map(e),r,t)))(e(a(s)))}return l.invert=function(s){return a(u((i||(i=o(r,n.map(e),p)))(s)))},l.domain=function(s){return arguments.length?(n=Array.from(s,_),h()):n.slice()},l.range=function(s){return arguments.length?(r=Array.from(s),h()):r.slice()},l.rangeRound=function(s){return r=Array.from(s),t=U,h()},l.clamp=function(s){return arguments.length?(a=s?!0:m,h()):a!==m},l.interpolate=function(s){return arguments.length?(t=s,h()):t},l.unknown=function(s){return arguments.length?(f=s,l):f},function(s,S){return e=s,u=S,h()}}function un(){return tn()(m,m)}function an(n,r,t,e){var u=G(n,r,t),f;switch(e=F(e??",f"),e.type){case"s":{var a=Math.max(Math.abs(n),Math.abs(r));return e.precision==null&&!isNaN(f=X(u,a))&&(e.precision=f),z(e,a)}case"":case"e":case"g":case"p":case"r":{e.precision==null&&!isNaN(f=Y(u,Math.max(Math.abs(n),Math.abs(r))))&&(e.precision=f-(e.type==="e"));break}case"f":case"%":{e.precision==null&&!isNaN(f=W(u))&&(e.precision=f-(e.type==="%")*2);break}}return B(e)}function on(n){var r=n.domain;return n.ticks=function(t){var e=r();return E(e[0],e[e.length-1],t??10)},n.tickFormat=function(t,e){var u=r();return an(u[0],u[u.length-1],t??10,e)},n.nice=function(t){t==null&&(t=10);var e=r(),u=0,f=e.length-1,a=e[u],o=e[f],c,i,h=10;for(o<a&&(i=a,a=o,o=i,i=u,u=f,f=i);h-- >0;){if(i=y(a,o,t),i===c)return e[u]=a,e[f]=o,r(e);if(i>0)a=Math.floor(a/i)*i,o=Math.ceil(o/i)*i;else if(i<0)a=Math.ceil(a*i)/i,o=Math.floor(o*i)/i;else break;c=i}return n},n}function fn(){var n=un();return n.copy=function(){return en(n,fn())},D.apply(n,arguments),on(n)}export{en as a,R as b,un as c,fn as l,G as t}; diff --git a/apps/kimi-code/dist-web/assets/mermaid.core-DaDTfY6S.js b/apps/kimi-code/dist-web/assets/mermaid.core-CJB1tAev.js similarity index 99% rename from apps/kimi-code/dist-web/assets/mermaid.core-DaDTfY6S.js rename to apps/kimi-code/dist-web/assets/mermaid.core-CJB1tAev.js index b556fdbb8..9cd1ef691 100644 --- a/apps/kimi-code/dist-web/assets/mermaid.core-DaDTfY6S.js +++ b/apps/kimi-code/dist-web/assets/mermaid.core-CJB1tAev.js @@ -1,5 +1,5 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/dagre-VKFMJZFB-BV_7O_eU.js","assets/chunk-RYQCIY6F-D1Yl7opn.js","assets/graph-DOmOIIwC.js","assets/map-DxJ2ADlA.js","assets/layout-D-LzfAck.js","assets/index-D1h84VfZ.js","assets/index-BTY1et1y.css","assets/_commonjsHelpers-CqkleIqs.js","assets/swimlanes-5IMT3BWC-C4tzl2F_.js","assets/cose-bilkent-JH36ORCC-CDDliH5o.js","assets/cytoscape.esm-OyMbaexL.js","assets/c4Diagram-LMCZKHZV-CuD9sHro.js","assets/chunk-32BRIVSS-_Sd4SrsJ.js","assets/flowDiagram-23GEKE2U-D0EBISGr.js","assets/chunk-5VM5RSS4-B87d3yQb.js","assets/chunk-XXDRQBXY-BEgNawAD.js","assets/chunk-VR4S4FIN-Dzr2NgNj.js","assets/channel-d4fEaqwQ.js","assets/swimlanesDiagram-G3AALYLV-DU8WMkqz.js","assets/erDiagram-Q63AITRT-xK3dRTZk.js","assets/gitGraphDiagram-IHSO6WYX-DaTSF-Bh.js","assets/chunk-2Q5K7J3B-DqVWYlyS.js","assets/chunk-JWPE2WC7-XhS5NGpP.js","assets/cynefin-VYW2F7L2-0NmB13eq.js","assets/ganttDiagram-NO4QXBWP-IslzQD84.js","assets/linear-BmFm-Eu7.js","assets/init-Gi6I4Gst.js","assets/defaultLocale-DX6XiGOO.js","assets/infoDiagram-FWYZ7A6U-YBdL8hE1.js","assets/pieDiagram-ENE6RG2P-5Ehl6T8C.js","assets/arc-CC9q5kjc.js","assets/ordinal-Cboi1Yqb.js","assets/quadrantDiagram-ABIIQ3AL-8vMHBPBY.js","assets/xychartDiagram-FW5EYKEG-Bg0qevEv.js","assets/requirementDiagram-TGXJPOKE-B8hGppVZ.js","assets/sequenceDiagram-DBY2YBRQ-B2h-6vZ7.js","assets/classDiagram-OUVF2IWQ-DPiTyikT.js","assets/chunk-V7JOEXUC-czNi1QQl.js","assets/classDiagram-v2-EOCWNBFH-DPiTyikT.js","assets/stateDiagram-2N3HPSRC-ha3u0dwu.js","assets/chunk-EX3LRPZG-CyUsdK3n.js","assets/stateDiagram-v2-6OUMAXLB-B_OpM2in.js","assets/journeyDiagram-5HDEW3XC-DHq-P2j9.js","assets/timeline-definition-FHXFAJF6-CV7TbRUK.js","assets/mindmap-definition-LN4V7U3C-WAq6xftS.js","assets/kanban-definition-HUTT4EX6-C6iL68OT.js","assets/sankeyDiagram-HTMAVEWB-BhsqMuTt.js","assets/diagram-NH7WQ7WH-C09rk2Ua.js","assets/diagram-WEI45ONY-DRhsbaVI.js","assets/blockDiagram-677ZJIJ3-DMGXLKk2.js","assets/diagram-OA4YK3LP-DnPyyrOM.js","assets/architectureDiagram-ZJ3FMSHR-BkXVAeQG.js","assets/diagram-FQU43EPY-C_ItQEVf.js","assets/ishikawaDiagram-FXEZZL3T-CJxOHefD.js","assets/vennDiagram-L72KCM5P-BNRmZgGU.js","assets/diagram-G47NLZAW-Cm4DutfF.js","assets/wardleyDiagram-EHGQE667-DVjnwE-A.js","assets/cynefinDiagram-TSTJHNR4-CSvOhRTt.js","assets/railroadDiagram-RFXS5EU6-BBlgCMW5.js","assets/chunk-MOJQB5TN-Ce2Y728v.js","assets/ebnfDiagram-CCIWWBDH-C6JPA7C_.js","assets/abnfDiagram-VRR7QNED-BXPcW32X.js","assets/pegDiagram-2B236MQR-C7Ks7P9i.js"])))=>i.map(i=>d[i]); -import{bR as nt}from"./index-D1h84VfZ.js";import{g as gy}from"./_commonjsHelpers-CqkleIqs.js";var _c=Object.defineProperty,p=(e,t)=>_c(e,"name",{value:t,configurable:!0}),my=(e,t)=>{for(var r in t)_c(e,r,{get:t[r],enumerable:!0})},So={exports:{}},yy=So.exports,zl;function Cy(){return zl||(zl=1,(function(e,t){(function(r,i){e.exports=i()})(yy,(function(){var r=1e3,i=6e4,o=36e5,s="millisecond",a="second",n="minute",l="hour",c="day",h="week",d="month",f="quarter",u="year",g="date",m="Invalid Date",y=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,C=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,b={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var A=["th","st","nd","rd"],F=$%100;return"["+$+(A[(F-20)%10]||A[F]||A[0])+"]"}},k=function($,A,F){var D=String($);return!D||D.length>=A?$:""+Array(A+1-D.length).join(F)+$},T={s:k,z:function($){var A=-$.utcOffset(),F=Math.abs(A),D=Math.floor(F/60),M=F%60;return(A<=0?"+":"-")+k(D,2,"0")+":"+k(M,2,"0")},m:function $(A,F){if(A.date()<F.date())return-$(F,A);var D=12*(F.year()-A.year())+(F.month()-A.month()),M=A.clone().add(D,d),H=F-M<0,Y=A.clone().add(D+(H?-1:1),d);return+(-(D+(F-M)/(H?M-Y:Y-M))||0)},a:function($){return $<0?Math.ceil($)||0:Math.floor($)},p:function($){return{M:d,y:u,w:h,d:c,D:g,h:l,m:n,s:a,ms:s,Q:f}[$]||String($||"").toLowerCase().replace(/s$/,"")},u:function($){return $===void 0}},S="en",_={};_[S]=b;var L="$isDayjsObject",v=function($){return $ instanceof z||!(!$||!$[L])},N=function $(A,F,D){var M;if(!A)return S;if(typeof A=="string"){var H=A.toLowerCase();_[H]&&(M=H),F&&(_[H]=F,M=H);var Y=A.split("-");if(!M&&Y.length>1)return $(Y[0])}else{var G=A.name;_[G]=A,M=G}return!D&&M&&(S=M),M||!D&&S},R=function($,A){if(v($))return $.clone();var F=typeof A=="object"?A:{};return F.date=$,F.args=arguments,new z(F)},P=T;P.l=N,P.i=v,P.w=function($,A){return R($,{locale:A.$L,utc:A.$u,x:A.$x,$offset:A.$offset})};var z=(function(){function $(F){this.$L=N(F.locale,null,!0),this.parse(F),this.$x=this.$x||F.x||{},this[L]=!0}var A=$.prototype;return A.parse=function(F){this.$d=(function(D){var M=D.date,H=D.utc;if(M===null)return new Date(NaN);if(P.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var Y=M.match(y);if(Y){var G=Y[2]-1||0,lt=(Y[7]||"0").substring(0,3);return H?new Date(Date.UTC(Y[1],G,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,lt)):new Date(Y[1],G,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,lt)}}return new Date(M)})(F),this.init()},A.init=function(){var F=this.$d;this.$y=F.getFullYear(),this.$M=F.getMonth(),this.$D=F.getDate(),this.$W=F.getDay(),this.$H=F.getHours(),this.$m=F.getMinutes(),this.$s=F.getSeconds(),this.$ms=F.getMilliseconds()},A.$utils=function(){return P},A.isValid=function(){return this.$d.toString()!==m},A.isSame=function(F,D){var M=R(F);return this.startOf(D)<=M&&M<=this.endOf(D)},A.isAfter=function(F,D){return R(F)<this.startOf(D)},A.isBefore=function(F,D){return this.endOf(D)<R(F)},A.$g=function(F,D,M){return P.u(F)?this[D]:this.set(M,F)},A.unix=function(){return Math.floor(this.valueOf()/1e3)},A.valueOf=function(){return this.$d.getTime()},A.startOf=function(F,D){var M=this,H=!!P.u(D)||D,Y=P.p(F),G=function(Bt,St){var ut=P.w(M.$u?Date.UTC(M.$y,St,Bt):new Date(M.$y,St,Bt),M);return H?ut:ut.endOf(c)},lt=function(Bt,St){return P.w(M.toDate()[Bt].apply(M.toDate("s"),(H?[0,0,0,0]:[23,59,59,999]).slice(St)),M)},ht=this.$W,dt=this.$M,bt=this.$D,et="set"+(this.$u?"UTC":"");switch(Y){case u:return H?G(1,0):G(31,11);case d:return H?G(1,dt):G(0,dt+1);case h:var ft=this.$locale().weekStart||0,kt=(ht<ft?ht+7:ht)-ft;return G(H?bt-kt:bt+(6-kt),dt);case c:case g:return lt(et+"Hours",0);case l:return lt(et+"Minutes",1);case n:return lt(et+"Seconds",2);case a:return lt(et+"Milliseconds",3);default:return this.clone()}},A.endOf=function(F){return this.startOf(F,!1)},A.$set=function(F,D){var M,H=P.p(F),Y="set"+(this.$u?"UTC":""),G=(M={},M[c]=Y+"Date",M[g]=Y+"Date",M[d]=Y+"Month",M[u]=Y+"FullYear",M[l]=Y+"Hours",M[n]=Y+"Minutes",M[a]=Y+"Seconds",M[s]=Y+"Milliseconds",M)[H],lt=H===c?this.$D+(D-this.$W):D;if(H===d||H===u){var ht=this.clone().set(g,1);ht.$d[G](lt),ht.init(),this.$d=ht.set(g,Math.min(this.$D,ht.daysInMonth())).$d}else G&&this.$d[G](lt);return this.init(),this},A.set=function(F,D){return this.clone().$set(F,D)},A.get=function(F){return this[P.p(F)]()},A.add=function(F,D){var M,H=this;F=Number(F);var Y=P.p(D),G=function(dt){var bt=R(H);return P.w(bt.date(bt.date()+Math.round(dt*F)),H)};if(Y===d)return this.set(d,this.$M+F);if(Y===u)return this.set(u,this.$y+F);if(Y===c)return G(1);if(Y===h)return G(7);var lt=(M={},M[n]=i,M[l]=o,M[a]=r,M)[Y]||1,ht=this.$d.getTime()+F*lt;return P.w(ht,this)},A.subtract=function(F,D){return this.add(-1*F,D)},A.format=function(F){var D=this,M=this.$locale();if(!this.isValid())return M.invalidDate||m;var H=F||"YYYY-MM-DDTHH:mm:ssZ",Y=P.z(this),G=this.$H,lt=this.$m,ht=this.$M,dt=M.weekdays,bt=M.months,et=M.meridiem,ft=function(St,ut,de,Tt){return St&&(St[ut]||St(D,H))||de[ut].slice(0,Tt)},kt=function(St){return P.s(G%12||12,St,"0")},Bt=et||function(St,ut,de){var Tt=St<12?"AM":"PM";return de?Tt.toLowerCase():Tt};return H.replace(C,(function(St,ut){return ut||(function(de){switch(de){case"YY":return String(D.$y).slice(-2);case"YYYY":return P.s(D.$y,4,"0");case"M":return ht+1;case"MM":return P.s(ht+1,2,"0");case"MMM":return ft(M.monthsShort,ht,bt,3);case"MMMM":return ft(bt,ht);case"D":return D.$D;case"DD":return P.s(D.$D,2,"0");case"d":return String(D.$W);case"dd":return ft(M.weekdaysMin,D.$W,dt,2);case"ddd":return ft(M.weekdaysShort,D.$W,dt,3);case"dddd":return dt[D.$W];case"H":return String(G);case"HH":return P.s(G,2,"0");case"h":return kt(1);case"hh":return kt(2);case"a":return Bt(G,lt,!0);case"A":return Bt(G,lt,!1);case"m":return String(lt);case"mm":return P.s(lt,2,"0");case"s":return String(D.$s);case"ss":return P.s(D.$s,2,"0");case"SSS":return P.s(D.$ms,3,"0");case"Z":return Y}return null})(St)||Y.replace(":","")}))},A.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},A.diff=function(F,D,M){var H,Y=this,G=P.p(D),lt=R(F),ht=(lt.utcOffset()-this.utcOffset())*i,dt=this-lt,bt=function(){return P.m(Y,lt)};switch(G){case u:H=bt()/12;break;case d:H=bt();break;case f:H=bt()/3;break;case h:H=(dt-ht)/6048e5;break;case c:H=(dt-ht)/864e5;break;case l:H=dt/o;break;case n:H=dt/i;break;case a:H=dt/r;break;default:H=dt}return M?H:P.a(H)},A.daysInMonth=function(){return this.endOf(d).$D},A.$locale=function(){return _[this.$L]},A.locale=function(F,D){if(!F)return this.$L;var M=this.clone(),H=N(F,D,!0);return H&&(M.$L=H),M},A.clone=function(){return P.w(this.$d,this)},A.toDate=function(){return new Date(this.valueOf())},A.toJSON=function(){return this.isValid()?this.toISOString():null},A.toISOString=function(){return this.$d.toISOString()},A.toString=function(){return this.$d.toUTCString()},$})(),W=z.prototype;return R.prototype=W,[["$ms",s],["$s",a],["$m",n],["$H",l],["$W",c],["$M",d],["$y",u],["$D",g]].forEach((function($){W[$[1]]=function(A){return this.$g(A,$[0],$[1])}})),R.extend=function($,A){return $.$i||($(A,z,R),$.$i=!0),R},R.locale=N,R.isDayjs=v,R.unix=function($){return R(1e3*$)},R.en=_[S],R.Ls=_,R.p={},R}))})(So)),So.exports}var xy=Cy();const by=gy(xy);var Ne={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},q={trace:p((...e)=>{},"trace"),debug:p((...e)=>{},"debug"),info:p((...e)=>{},"info"),warn:p((...e)=>{},"warn"),error:p((...e)=>{},"error"),fatal:p((...e)=>{},"fatal")},Cn=p(function(e="fatal"){let t=Ne.fatal;typeof e=="string"?e.toLowerCase()in Ne&&(t=Ne[e]):typeof e=="number"&&(t=e),q.trace=()=>{},q.debug=()=>{},q.info=()=>{},q.warn=()=>{},q.error=()=>{},q.fatal=()=>{},t<=Ne.fatal&&(q.fatal=console.error?console.error.bind(console,he("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",he("FATAL"))),t<=Ne.error&&(q.error=console.error?console.error.bind(console,he("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",he("ERROR"))),t<=Ne.warn&&(q.warn=console.warn?console.warn.bind(console,he("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",he("WARN"))),t<=Ne.info&&(q.info=console.info?console.info.bind(console,he("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",he("INFO"))),t<=Ne.debug&&(q.debug=console.debug?console.debug.bind(console,he("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",he("DEBUG"))),t<=Ne.trace&&(q.trace=console.debug?console.debug.bind(console,he("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",he("TRACE")))},"setLogLevel"),he=p(e=>`%c${by().format("ss.SSS")} : ${e} : `,"format");const _o={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:e=>e>=255?255:e<0?0:e,g:e=>e>=255?255:e<0?0:e,b:e=>e>=255?255:e<0?0:e,h:e=>e%360,s:e=>e>=100?100:e<0?0:e,l:e=>e>=100?100:e<0?0:e,a:e=>e>=1?1:e<0?0:e},toLinear:e=>{const t=e/255;return e>.03928?Math.pow((t+.055)/1.055,2.4):t/12.92},hue2rgb:(e,t,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<1/6?e+(t-e)*6*r:r<1/2?t:r<2/3?e+(t-e)*(2/3-r)*6:e),hsl2rgb:({h:e,s:t,l:r},i)=>{if(!t)return r*2.55;e/=360,t/=100,r/=100;const o=r<.5?r*(1+t):r+t-r*t,s=2*r-o;switch(i){case"r":return _o.hue2rgb(s,o,e+1/3)*255;case"g":return _o.hue2rgb(s,o,e)*255;case"b":return _o.hue2rgb(s,o,e-1/3)*255}},rgb2hsl:({r:e,g:t,b:r},i)=>{e/=255,t/=255,r/=255;const o=Math.max(e,t,r),s=Math.min(e,t,r),a=(o+s)/2;if(i==="l")return a*100;if(o===s)return 0;const n=o-s,l=a>.5?n/(2-o-s):n/(o+s);if(i==="s")return l*100;switch(o){case e:return((t-r)/n+(t<r?6:0))*60;case t:return((r-e)/n+2)*60;case r:return((e-t)/n+4)*60;default:return-1}}},ky={clamp:(e,t,r)=>t>r?Math.min(t,Math.max(r,e)):Math.min(r,Math.max(t,e)),round:e=>Math.round(e*1e10)/1e10},wy={dec2hex:e=>{const t=Math.round(e).toString(16);return t.length>1?t:`0${t}`}},at={channel:_o,lang:ky,unit:wy},Je={};for(let e=0;e<=255;e++)Je[e]=at.unit.dec2hex(e);const Gt={ALL:0,RGB:1,HSL:2};class Ty{constructor(){this.type=Gt.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=Gt.ALL}is(t){return this.type===t}}class Sy{constructor(t,r){this.color=r,this.changed=!1,this.data=t,this.type=new Ty}set(t,r){return this.color=r,this.changed=!1,this.data=t,this.type.type=Gt.ALL,this}_ensureHSL(){const t=this.data,{h:r,s:i,l:o}=t;r===void 0&&(t.h=at.channel.rgb2hsl(t,"h")),i===void 0&&(t.s=at.channel.rgb2hsl(t,"s")),o===void 0&&(t.l=at.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r,g:i,b:o}=t;r===void 0&&(t.r=at.channel.hsl2rgb(t,"r")),i===void 0&&(t.g=at.channel.hsl2rgb(t,"g")),o===void 0&&(t.b=at.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,r=t.r;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"r"))}get g(){const t=this.data,r=t.g;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"g"))}get b(){const t=this.data,r=t.b;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"b"))}get h(){const t=this.data,r=t.h;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"h"))}get s(){const t=this.data,r=t.s;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"s"))}get l(){const t=this.data,r=t.l;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"l"))}get a(){return this.data.a}set r(t){this.type.set(Gt.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(Gt.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(Gt.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(Gt.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(Gt.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(Gt.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}const gs=new Sy({r:0,g:0,b:0,a:0},"transparent"),Xr={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:e=>{if(e.charCodeAt(0)!==35)return;const t=e.match(Xr.re);if(!t)return;const r=t[1],i=parseInt(r,16),o=r.length,s=o%4===0,a=o>4,n=a?1:17,l=a?8:4,c=s?0:-1,h=a?255:15;return gs.set({r:(i>>l*(c+3)&h)*n,g:(i>>l*(c+2)&h)*n,b:(i>>l*(c+1)&h)*n,a:s?(i&h)*n/255:1},e)},stringify:e=>{const{r:t,g:r,b:i,a:o}=e;return o<1?`#${Je[Math.round(t)]}${Je[Math.round(r)]}${Je[Math.round(i)]}${Je[Math.round(o*255)]}`:`#${Je[Math.round(t)]}${Je[Math.round(r)]}${Je[Math.round(i)]}`}},Cr={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:e=>{const t=e.match(Cr.hueRe);if(t){const[,r,i]=t;switch(i){case"grad":return at.channel.clamp.h(parseFloat(r)*.9);case"rad":return at.channel.clamp.h(parseFloat(r)*180/Math.PI);case"turn":return at.channel.clamp.h(parseFloat(r)*360)}}return at.channel.clamp.h(parseFloat(e))},parse:e=>{const t=e.charCodeAt(0);if(t!==104&&t!==72)return;const r=e.match(Cr.re);if(!r)return;const[,i,o,s,a,n]=r;return gs.set({h:Cr._hue2deg(i),s:at.channel.clamp.s(parseFloat(o)),l:at.channel.clamp.l(parseFloat(s)),a:a?at.channel.clamp.a(n?parseFloat(a)/100:parseFloat(a)):1},e)},stringify:e=>{const{h:t,s:r,l:i,a:o}=e;return o<1?`hsla(${at.lang.round(t)}, ${at.lang.round(r)}%, ${at.lang.round(i)}%, ${o})`:`hsl(${at.lang.round(t)}, ${at.lang.round(r)}%, ${at.lang.round(i)}%)`}},Ei={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:e=>{e=e.toLowerCase();const t=Ei.colors[e];if(t)return Xr.parse(t)},stringify:e=>{const t=Xr.stringify(e);for(const r in Ei.colors)if(Ei.colors[r]===t)return r}},wi={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:e=>{const t=e.charCodeAt(0);if(t!==114&&t!==82)return;const r=e.match(wi.re);if(!r)return;const[,i,o,s,a,n,l,c,h]=r;return gs.set({r:at.channel.clamp.r(o?parseFloat(i)*2.55:parseFloat(i)),g:at.channel.clamp.g(a?parseFloat(s)*2.55:parseFloat(s)),b:at.channel.clamp.b(l?parseFloat(n)*2.55:parseFloat(n)),a:c?at.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},e)},stringify:e=>{const{r:t,g:r,b:i,a:o}=e;return o<1?`rgba(${at.lang.round(t)}, ${at.lang.round(r)}, ${at.lang.round(i)}, ${at.lang.round(o)})`:`rgb(${at.lang.round(t)}, ${at.lang.round(r)}, ${at.lang.round(i)})`}},Ee={format:{keyword:Ei,hex:Xr,rgb:wi,rgba:wi,hsl:Cr,hsla:Cr},parse:e=>{if(typeof e!="string")return e;const t=Xr.parse(e)||wi.parse(e)||Cr.parse(e)||Ei.parse(e);if(t)return t;throw new Error(`Unsupported color format: "${e}"`)},stringify:e=>!e.changed&&e.color?e.color:e.type.is(Gt.HSL)||e.data.r===void 0?Cr.stringify(e):e.a<1||!Number.isInteger(e.r)||!Number.isInteger(e.g)||!Number.isInteger(e.b)?wi.stringify(e):Xr.stringify(e)},Bc=(e,t)=>{const r=Ee.parse(e);for(const i in t)r[i]=at.channel.clamp[i](t[i]);return Ee.stringify(r)},or=(e,t,r=0,i=1)=>{if(typeof e!="number")return Bc(e,{a:t});const o=gs.set({r:at.channel.clamp.r(e),g:at.channel.clamp.g(t),b:at.channel.clamp.b(r),a:at.channel.clamp.a(i)});return Ee.stringify(o)},_y=e=>{const{r:t,g:r,b:i}=Ee.parse(e),o=.2126*at.channel.toLinear(t)+.7152*at.channel.toLinear(r)+.0722*at.channel.toLinear(i);return at.lang.round(o)},By=e=>_y(e)>=.5,ke=e=>!By(e),vc=(e,t,r)=>{const i=Ee.parse(e),o=i[t],s=at.channel.clamp[t](o+r);return o!==s&&(i[t]=s),Ee.stringify(i)},O=(e,t)=>vc(e,"l",t),I=(e,t)=>vc(e,"l",-t),x=(e,t)=>{const r=Ee.parse(e),i={};for(const o in t)t[o]&&(i[o]=r[o]+t[o]);return Bc(e,i)},vy=(e,t,r=50)=>{const{r:i,g:o,b:s,a}=Ee.parse(e),{r:n,g:l,b:c,a:h}=Ee.parse(t),d=r/100,f=d*2-1,u=a-h,m=((f*u===-1?f:(f+u)/(1+f*u))+1)/2,y=1-m,C=i*m+n*y,b=o*m+l*y,k=s*m+c*y,T=a*d+h*(1-d);return or(C,b,k,T)},B=(e,t=100)=>{const r=Ee.parse(e);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,vy(r,e,t)};/*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE */function Hl(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,i=Array(t);r<t;r++)i[r]=e[r];return i}function Ly(e){if(Array.isArray(e))return e}function Fy(e,t){var r=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(r!=null){var i,o,s,a,n=[],l=!0,c=!1;try{if(s=(r=r.call(e)).next,t!==0)for(;!(l=(i=s.call(r)).done)&&(n.push(i.value),n.length!==t);l=!0);}catch(h){c=!0,o=h}finally{try{if(!l&&r.return!=null&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return n}}function Ay(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/dagre-VKFMJZFB-D8gdq5tS.js","assets/chunk-RYQCIY6F-Df2V79id.js","assets/graph-DOmOIIwC.js","assets/map-DxJ2ADlA.js","assets/layout-D-LzfAck.js","assets/index-D-7nOosq.js","assets/index-DGHD7Bg9.css","assets/_commonjsHelpers-CqkleIqs.js","assets/swimlanes-5IMT3BWC-D6xMtJ1E.js","assets/cose-bilkent-JH36ORCC-TWQPJk-P.js","assets/cytoscape.esm-OyMbaexL.js","assets/c4Diagram-LMCZKHZV-CUyKVoVi.js","assets/chunk-32BRIVSS-DUDRPqmY.js","assets/flowDiagram-23GEKE2U-CzI-GKO4.js","assets/chunk-5VM5RSS4-yyj9cAyF.js","assets/chunk-XXDRQBXY-5rh7CWvm.js","assets/chunk-VR4S4FIN-CEH7JYJn.js","assets/channel-xkK6nTGq.js","assets/swimlanesDiagram-G3AALYLV-DKIx012r.js","assets/erDiagram-Q63AITRT-DVzumNgk.js","assets/gitGraphDiagram-IHSO6WYX-D7UBC8np.js","assets/chunk-2Q5K7J3B-DsAC7dRk.js","assets/chunk-JWPE2WC7-Dsg3gA8l.js","assets/cynefin-VYW2F7L2-BIlq342y.js","assets/ganttDiagram-NO4QXBWP-B2lfrNfh.js","assets/linear-DH49UJnN.js","assets/init-Gi6I4Gst.js","assets/defaultLocale-DX6XiGOO.js","assets/infoDiagram-FWYZ7A6U-DASw56fH.js","assets/pieDiagram-ENE6RG2P-f3F4At6v.js","assets/arc-IkhU3FHH.js","assets/ordinal-Cboi1Yqb.js","assets/quadrantDiagram-ABIIQ3AL-3t7sFhfl.js","assets/xychartDiagram-FW5EYKEG-yQImOWPy.js","assets/requirementDiagram-TGXJPOKE-Bzvt0v7J.js","assets/sequenceDiagram-DBY2YBRQ-CnV0H-kS.js","assets/classDiagram-OUVF2IWQ-ClMG95L0.js","assets/chunk-V7JOEXUC-B4q9plWN.js","assets/classDiagram-v2-EOCWNBFH-ClMG95L0.js","assets/stateDiagram-2N3HPSRC-GIVsAB2M.js","assets/chunk-EX3LRPZG-BCWDroXJ.js","assets/stateDiagram-v2-6OUMAXLB-0KuGlzV7.js","assets/journeyDiagram-5HDEW3XC-BShuBRgf.js","assets/timeline-definition-FHXFAJF6-5u0AN8o0.js","assets/mindmap-definition-LN4V7U3C-HXhM1kRL.js","assets/kanban-definition-HUTT4EX6-_UoHLqzR.js","assets/sankeyDiagram-HTMAVEWB-B5WnWxzh.js","assets/diagram-NH7WQ7WH-DUn2m-AO.js","assets/diagram-WEI45ONY-CFwFRAWa.js","assets/blockDiagram-677ZJIJ3-BNXb88Fr.js","assets/diagram-OA4YK3LP-BOIp7TNe.js","assets/architectureDiagram-ZJ3FMSHR-CBluWNBt.js","assets/diagram-FQU43EPY-D2bRXH1a.js","assets/ishikawaDiagram-FXEZZL3T-CcPuml-k.js","assets/vennDiagram-L72KCM5P-ozNTLnJz.js","assets/diagram-G47NLZAW-BF9x_uf7.js","assets/wardleyDiagram-EHGQE667-BuQJYWm-.js","assets/cynefinDiagram-TSTJHNR4-zQaCQNIP.js","assets/railroadDiagram-RFXS5EU6-W9nf8fYD.js","assets/chunk-MOJQB5TN-JQ2kJR9W.js","assets/ebnfDiagram-CCIWWBDH-B4NTctc_.js","assets/abnfDiagram-VRR7QNED-C0Afmuc1.js","assets/pegDiagram-2B236MQR-_6D7zUy-.js"])))=>i.map(i=>d[i]); +import{bR as nt}from"./index-D-7nOosq.js";import{g as gy}from"./_commonjsHelpers-CqkleIqs.js";var _c=Object.defineProperty,p=(e,t)=>_c(e,"name",{value:t,configurable:!0}),my=(e,t)=>{for(var r in t)_c(e,r,{get:t[r],enumerable:!0})},So={exports:{}},yy=So.exports,zl;function Cy(){return zl||(zl=1,(function(e,t){(function(r,i){e.exports=i()})(yy,(function(){var r=1e3,i=6e4,o=36e5,s="millisecond",a="second",n="minute",l="hour",c="day",h="week",d="month",f="quarter",u="year",g="date",m="Invalid Date",y=/^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/,C=/\[([^\]]+)]|YYYY|YY|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g,b={name:"en",weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),ordinal:function($){var A=["th","st","nd","rd"],F=$%100;return"["+$+(A[(F-20)%10]||A[F]||A[0])+"]"}},k=function($,A,F){var D=String($);return!D||D.length>=A?$:""+Array(A+1-D.length).join(F)+$},T={s:k,z:function($){var A=-$.utcOffset(),F=Math.abs(A),D=Math.floor(F/60),M=F%60;return(A<=0?"+":"-")+k(D,2,"0")+":"+k(M,2,"0")},m:function $(A,F){if(A.date()<F.date())return-$(F,A);var D=12*(F.year()-A.year())+(F.month()-A.month()),M=A.clone().add(D,d),H=F-M<0,Y=A.clone().add(D+(H?-1:1),d);return+(-(D+(F-M)/(H?M-Y:Y-M))||0)},a:function($){return $<0?Math.ceil($)||0:Math.floor($)},p:function($){return{M:d,y:u,w:h,d:c,D:g,h:l,m:n,s:a,ms:s,Q:f}[$]||String($||"").toLowerCase().replace(/s$/,"")},u:function($){return $===void 0}},S="en",_={};_[S]=b;var L="$isDayjsObject",v=function($){return $ instanceof z||!(!$||!$[L])},N=function $(A,F,D){var M;if(!A)return S;if(typeof A=="string"){var H=A.toLowerCase();_[H]&&(M=H),F&&(_[H]=F,M=H);var Y=A.split("-");if(!M&&Y.length>1)return $(Y[0])}else{var G=A.name;_[G]=A,M=G}return!D&&M&&(S=M),M||!D&&S},R=function($,A){if(v($))return $.clone();var F=typeof A=="object"?A:{};return F.date=$,F.args=arguments,new z(F)},P=T;P.l=N,P.i=v,P.w=function($,A){return R($,{locale:A.$L,utc:A.$u,x:A.$x,$offset:A.$offset})};var z=(function(){function $(F){this.$L=N(F.locale,null,!0),this.parse(F),this.$x=this.$x||F.x||{},this[L]=!0}var A=$.prototype;return A.parse=function(F){this.$d=(function(D){var M=D.date,H=D.utc;if(M===null)return new Date(NaN);if(P.u(M))return new Date;if(M instanceof Date)return new Date(M);if(typeof M=="string"&&!/Z$/i.test(M)){var Y=M.match(y);if(Y){var G=Y[2]-1||0,lt=(Y[7]||"0").substring(0,3);return H?new Date(Date.UTC(Y[1],G,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,lt)):new Date(Y[1],G,Y[3]||1,Y[4]||0,Y[5]||0,Y[6]||0,lt)}}return new Date(M)})(F),this.init()},A.init=function(){var F=this.$d;this.$y=F.getFullYear(),this.$M=F.getMonth(),this.$D=F.getDate(),this.$W=F.getDay(),this.$H=F.getHours(),this.$m=F.getMinutes(),this.$s=F.getSeconds(),this.$ms=F.getMilliseconds()},A.$utils=function(){return P},A.isValid=function(){return this.$d.toString()!==m},A.isSame=function(F,D){var M=R(F);return this.startOf(D)<=M&&M<=this.endOf(D)},A.isAfter=function(F,D){return R(F)<this.startOf(D)},A.isBefore=function(F,D){return this.endOf(D)<R(F)},A.$g=function(F,D,M){return P.u(F)?this[D]:this.set(M,F)},A.unix=function(){return Math.floor(this.valueOf()/1e3)},A.valueOf=function(){return this.$d.getTime()},A.startOf=function(F,D){var M=this,H=!!P.u(D)||D,Y=P.p(F),G=function(Bt,St){var ut=P.w(M.$u?Date.UTC(M.$y,St,Bt):new Date(M.$y,St,Bt),M);return H?ut:ut.endOf(c)},lt=function(Bt,St){return P.w(M.toDate()[Bt].apply(M.toDate("s"),(H?[0,0,0,0]:[23,59,59,999]).slice(St)),M)},ht=this.$W,dt=this.$M,bt=this.$D,et="set"+(this.$u?"UTC":"");switch(Y){case u:return H?G(1,0):G(31,11);case d:return H?G(1,dt):G(0,dt+1);case h:var ft=this.$locale().weekStart||0,kt=(ht<ft?ht+7:ht)-ft;return G(H?bt-kt:bt+(6-kt),dt);case c:case g:return lt(et+"Hours",0);case l:return lt(et+"Minutes",1);case n:return lt(et+"Seconds",2);case a:return lt(et+"Milliseconds",3);default:return this.clone()}},A.endOf=function(F){return this.startOf(F,!1)},A.$set=function(F,D){var M,H=P.p(F),Y="set"+(this.$u?"UTC":""),G=(M={},M[c]=Y+"Date",M[g]=Y+"Date",M[d]=Y+"Month",M[u]=Y+"FullYear",M[l]=Y+"Hours",M[n]=Y+"Minutes",M[a]=Y+"Seconds",M[s]=Y+"Milliseconds",M)[H],lt=H===c?this.$D+(D-this.$W):D;if(H===d||H===u){var ht=this.clone().set(g,1);ht.$d[G](lt),ht.init(),this.$d=ht.set(g,Math.min(this.$D,ht.daysInMonth())).$d}else G&&this.$d[G](lt);return this.init(),this},A.set=function(F,D){return this.clone().$set(F,D)},A.get=function(F){return this[P.p(F)]()},A.add=function(F,D){var M,H=this;F=Number(F);var Y=P.p(D),G=function(dt){var bt=R(H);return P.w(bt.date(bt.date()+Math.round(dt*F)),H)};if(Y===d)return this.set(d,this.$M+F);if(Y===u)return this.set(u,this.$y+F);if(Y===c)return G(1);if(Y===h)return G(7);var lt=(M={},M[n]=i,M[l]=o,M[a]=r,M)[Y]||1,ht=this.$d.getTime()+F*lt;return P.w(ht,this)},A.subtract=function(F,D){return this.add(-1*F,D)},A.format=function(F){var D=this,M=this.$locale();if(!this.isValid())return M.invalidDate||m;var H=F||"YYYY-MM-DDTHH:mm:ssZ",Y=P.z(this),G=this.$H,lt=this.$m,ht=this.$M,dt=M.weekdays,bt=M.months,et=M.meridiem,ft=function(St,ut,de,Tt){return St&&(St[ut]||St(D,H))||de[ut].slice(0,Tt)},kt=function(St){return P.s(G%12||12,St,"0")},Bt=et||function(St,ut,de){var Tt=St<12?"AM":"PM";return de?Tt.toLowerCase():Tt};return H.replace(C,(function(St,ut){return ut||(function(de){switch(de){case"YY":return String(D.$y).slice(-2);case"YYYY":return P.s(D.$y,4,"0");case"M":return ht+1;case"MM":return P.s(ht+1,2,"0");case"MMM":return ft(M.monthsShort,ht,bt,3);case"MMMM":return ft(bt,ht);case"D":return D.$D;case"DD":return P.s(D.$D,2,"0");case"d":return String(D.$W);case"dd":return ft(M.weekdaysMin,D.$W,dt,2);case"ddd":return ft(M.weekdaysShort,D.$W,dt,3);case"dddd":return dt[D.$W];case"H":return String(G);case"HH":return P.s(G,2,"0");case"h":return kt(1);case"hh":return kt(2);case"a":return Bt(G,lt,!0);case"A":return Bt(G,lt,!1);case"m":return String(lt);case"mm":return P.s(lt,2,"0");case"s":return String(D.$s);case"ss":return P.s(D.$s,2,"0");case"SSS":return P.s(D.$ms,3,"0");case"Z":return Y}return null})(St)||Y.replace(":","")}))},A.utcOffset=function(){return 15*-Math.round(this.$d.getTimezoneOffset()/15)},A.diff=function(F,D,M){var H,Y=this,G=P.p(D),lt=R(F),ht=(lt.utcOffset()-this.utcOffset())*i,dt=this-lt,bt=function(){return P.m(Y,lt)};switch(G){case u:H=bt()/12;break;case d:H=bt();break;case f:H=bt()/3;break;case h:H=(dt-ht)/6048e5;break;case c:H=(dt-ht)/864e5;break;case l:H=dt/o;break;case n:H=dt/i;break;case a:H=dt/r;break;default:H=dt}return M?H:P.a(H)},A.daysInMonth=function(){return this.endOf(d).$D},A.$locale=function(){return _[this.$L]},A.locale=function(F,D){if(!F)return this.$L;var M=this.clone(),H=N(F,D,!0);return H&&(M.$L=H),M},A.clone=function(){return P.w(this.$d,this)},A.toDate=function(){return new Date(this.valueOf())},A.toJSON=function(){return this.isValid()?this.toISOString():null},A.toISOString=function(){return this.$d.toISOString()},A.toString=function(){return this.$d.toUTCString()},$})(),W=z.prototype;return R.prototype=W,[["$ms",s],["$s",a],["$m",n],["$H",l],["$W",c],["$M",d],["$y",u],["$D",g]].forEach((function($){W[$[1]]=function(A){return this.$g(A,$[0],$[1])}})),R.extend=function($,A){return $.$i||($(A,z,R),$.$i=!0),R},R.locale=N,R.isDayjs=v,R.unix=function($){return R(1e3*$)},R.en=_[S],R.Ls=_,R.p={},R}))})(So)),So.exports}var xy=Cy();const by=gy(xy);var Ne={trace:0,debug:1,info:2,warn:3,error:4,fatal:5},q={trace:p((...e)=>{},"trace"),debug:p((...e)=>{},"debug"),info:p((...e)=>{},"info"),warn:p((...e)=>{},"warn"),error:p((...e)=>{},"error"),fatal:p((...e)=>{},"fatal")},Cn=p(function(e="fatal"){let t=Ne.fatal;typeof e=="string"?e.toLowerCase()in Ne&&(t=Ne[e]):typeof e=="number"&&(t=e),q.trace=()=>{},q.debug=()=>{},q.info=()=>{},q.warn=()=>{},q.error=()=>{},q.fatal=()=>{},t<=Ne.fatal&&(q.fatal=console.error?console.error.bind(console,he("FATAL"),"color: orange"):console.log.bind(console,"\x1B[35m",he("FATAL"))),t<=Ne.error&&(q.error=console.error?console.error.bind(console,he("ERROR"),"color: orange"):console.log.bind(console,"\x1B[31m",he("ERROR"))),t<=Ne.warn&&(q.warn=console.warn?console.warn.bind(console,he("WARN"),"color: orange"):console.log.bind(console,"\x1B[33m",he("WARN"))),t<=Ne.info&&(q.info=console.info?console.info.bind(console,he("INFO"),"color: lightblue"):console.log.bind(console,"\x1B[34m",he("INFO"))),t<=Ne.debug&&(q.debug=console.debug?console.debug.bind(console,he("DEBUG"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",he("DEBUG"))),t<=Ne.trace&&(q.trace=console.debug?console.debug.bind(console,he("TRACE"),"color: lightgreen"):console.log.bind(console,"\x1B[32m",he("TRACE")))},"setLogLevel"),he=p(e=>`%c${by().format("ss.SSS")} : ${e} : `,"format");const _o={min:{r:0,g:0,b:0,s:0,l:0,a:0},max:{r:255,g:255,b:255,h:360,s:100,l:100,a:1},clamp:{r:e=>e>=255?255:e<0?0:e,g:e=>e>=255?255:e<0?0:e,b:e=>e>=255?255:e<0?0:e,h:e=>e%360,s:e=>e>=100?100:e<0?0:e,l:e=>e>=100?100:e<0?0:e,a:e=>e>=1?1:e<0?0:e},toLinear:e=>{const t=e/255;return e>.03928?Math.pow((t+.055)/1.055,2.4):t/12.92},hue2rgb:(e,t,r)=>(r<0&&(r+=1),r>1&&(r-=1),r<1/6?e+(t-e)*6*r:r<1/2?t:r<2/3?e+(t-e)*(2/3-r)*6:e),hsl2rgb:({h:e,s:t,l:r},i)=>{if(!t)return r*2.55;e/=360,t/=100,r/=100;const o=r<.5?r*(1+t):r+t-r*t,s=2*r-o;switch(i){case"r":return _o.hue2rgb(s,o,e+1/3)*255;case"g":return _o.hue2rgb(s,o,e)*255;case"b":return _o.hue2rgb(s,o,e-1/3)*255}},rgb2hsl:({r:e,g:t,b:r},i)=>{e/=255,t/=255,r/=255;const o=Math.max(e,t,r),s=Math.min(e,t,r),a=(o+s)/2;if(i==="l")return a*100;if(o===s)return 0;const n=o-s,l=a>.5?n/(2-o-s):n/(o+s);if(i==="s")return l*100;switch(o){case e:return((t-r)/n+(t<r?6:0))*60;case t:return((r-e)/n+2)*60;case r:return((e-t)/n+4)*60;default:return-1}}},ky={clamp:(e,t,r)=>t>r?Math.min(t,Math.max(r,e)):Math.min(r,Math.max(t,e)),round:e=>Math.round(e*1e10)/1e10},wy={dec2hex:e=>{const t=Math.round(e).toString(16);return t.length>1?t:`0${t}`}},at={channel:_o,lang:ky,unit:wy},Je={};for(let e=0;e<=255;e++)Je[e]=at.unit.dec2hex(e);const Gt={ALL:0,RGB:1,HSL:2};class Ty{constructor(){this.type=Gt.ALL}get(){return this.type}set(t){if(this.type&&this.type!==t)throw new Error("Cannot change both RGB and HSL channels at the same time");this.type=t}reset(){this.type=Gt.ALL}is(t){return this.type===t}}class Sy{constructor(t,r){this.color=r,this.changed=!1,this.data=t,this.type=new Ty}set(t,r){return this.color=r,this.changed=!1,this.data=t,this.type.type=Gt.ALL,this}_ensureHSL(){const t=this.data,{h:r,s:i,l:o}=t;r===void 0&&(t.h=at.channel.rgb2hsl(t,"h")),i===void 0&&(t.s=at.channel.rgb2hsl(t,"s")),o===void 0&&(t.l=at.channel.rgb2hsl(t,"l"))}_ensureRGB(){const t=this.data,{r,g:i,b:o}=t;r===void 0&&(t.r=at.channel.hsl2rgb(t,"r")),i===void 0&&(t.g=at.channel.hsl2rgb(t,"g")),o===void 0&&(t.b=at.channel.hsl2rgb(t,"b"))}get r(){const t=this.data,r=t.r;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"r"))}get g(){const t=this.data,r=t.g;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"g"))}get b(){const t=this.data,r=t.b;return!this.type.is(Gt.HSL)&&r!==void 0?r:(this._ensureHSL(),at.channel.hsl2rgb(t,"b"))}get h(){const t=this.data,r=t.h;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"h"))}get s(){const t=this.data,r=t.s;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"s"))}get l(){const t=this.data,r=t.l;return!this.type.is(Gt.RGB)&&r!==void 0?r:(this._ensureRGB(),at.channel.rgb2hsl(t,"l"))}get a(){return this.data.a}set r(t){this.type.set(Gt.RGB),this.changed=!0,this.data.r=t}set g(t){this.type.set(Gt.RGB),this.changed=!0,this.data.g=t}set b(t){this.type.set(Gt.RGB),this.changed=!0,this.data.b=t}set h(t){this.type.set(Gt.HSL),this.changed=!0,this.data.h=t}set s(t){this.type.set(Gt.HSL),this.changed=!0,this.data.s=t}set l(t){this.type.set(Gt.HSL),this.changed=!0,this.data.l=t}set a(t){this.changed=!0,this.data.a=t}}const gs=new Sy({r:0,g:0,b:0,a:0},"transparent"),Xr={re:/^#((?:[a-f0-9]{2}){2,4}|[a-f0-9]{3})$/i,parse:e=>{if(e.charCodeAt(0)!==35)return;const t=e.match(Xr.re);if(!t)return;const r=t[1],i=parseInt(r,16),o=r.length,s=o%4===0,a=o>4,n=a?1:17,l=a?8:4,c=s?0:-1,h=a?255:15;return gs.set({r:(i>>l*(c+3)&h)*n,g:(i>>l*(c+2)&h)*n,b:(i>>l*(c+1)&h)*n,a:s?(i&h)*n/255:1},e)},stringify:e=>{const{r:t,g:r,b:i,a:o}=e;return o<1?`#${Je[Math.round(t)]}${Je[Math.round(r)]}${Je[Math.round(i)]}${Je[Math.round(o*255)]}`:`#${Je[Math.round(t)]}${Je[Math.round(r)]}${Je[Math.round(i)]}`}},Cr={re:/^hsla?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(?:deg|grad|rad|turn)?)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?%)(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e-?\d+)?(%)?))?\s*?\)$/i,hueRe:/^(.+?)(deg|grad|rad|turn)$/i,_hue2deg:e=>{const t=e.match(Cr.hueRe);if(t){const[,r,i]=t;switch(i){case"grad":return at.channel.clamp.h(parseFloat(r)*.9);case"rad":return at.channel.clamp.h(parseFloat(r)*180/Math.PI);case"turn":return at.channel.clamp.h(parseFloat(r)*360)}}return at.channel.clamp.h(parseFloat(e))},parse:e=>{const t=e.charCodeAt(0);if(t!==104&&t!==72)return;const r=e.match(Cr.re);if(!r)return;const[,i,o,s,a,n]=r;return gs.set({h:Cr._hue2deg(i),s:at.channel.clamp.s(parseFloat(o)),l:at.channel.clamp.l(parseFloat(s)),a:a?at.channel.clamp.a(n?parseFloat(a)/100:parseFloat(a)):1},e)},stringify:e=>{const{h:t,s:r,l:i,a:o}=e;return o<1?`hsla(${at.lang.round(t)}, ${at.lang.round(r)}%, ${at.lang.round(i)}%, ${o})`:`hsl(${at.lang.round(t)}, ${at.lang.round(r)}%, ${at.lang.round(i)}%)`}},Ei={colors:{aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyanaqua:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc",ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",rebeccapurple:"#663399",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",transparent:"#00000000",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},parse:e=>{e=e.toLowerCase();const t=Ei.colors[e];if(t)return Xr.parse(t)},stringify:e=>{const t=Xr.stringify(e);for(const r in Ei.colors)if(Ei.colors[r]===t)return r}},wi={re:/^rgba?\(\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))\s*?(?:,|\s)\s*?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?))(?:\s*?(?:,|\/)\s*?\+?(-?(?:\d+(?:\.\d+)?|(?:\.\d+))(?:e\d+)?(%?)))?\s*?\)$/i,parse:e=>{const t=e.charCodeAt(0);if(t!==114&&t!==82)return;const r=e.match(wi.re);if(!r)return;const[,i,o,s,a,n,l,c,h]=r;return gs.set({r:at.channel.clamp.r(o?parseFloat(i)*2.55:parseFloat(i)),g:at.channel.clamp.g(a?parseFloat(s)*2.55:parseFloat(s)),b:at.channel.clamp.b(l?parseFloat(n)*2.55:parseFloat(n)),a:c?at.channel.clamp.a(h?parseFloat(c)/100:parseFloat(c)):1},e)},stringify:e=>{const{r:t,g:r,b:i,a:o}=e;return o<1?`rgba(${at.lang.round(t)}, ${at.lang.round(r)}, ${at.lang.round(i)}, ${at.lang.round(o)})`:`rgb(${at.lang.round(t)}, ${at.lang.round(r)}, ${at.lang.round(i)})`}},Ee={format:{keyword:Ei,hex:Xr,rgb:wi,rgba:wi,hsl:Cr,hsla:Cr},parse:e=>{if(typeof e!="string")return e;const t=Xr.parse(e)||wi.parse(e)||Cr.parse(e)||Ei.parse(e);if(t)return t;throw new Error(`Unsupported color format: "${e}"`)},stringify:e=>!e.changed&&e.color?e.color:e.type.is(Gt.HSL)||e.data.r===void 0?Cr.stringify(e):e.a<1||!Number.isInteger(e.r)||!Number.isInteger(e.g)||!Number.isInteger(e.b)?wi.stringify(e):Xr.stringify(e)},Bc=(e,t)=>{const r=Ee.parse(e);for(const i in t)r[i]=at.channel.clamp[i](t[i]);return Ee.stringify(r)},or=(e,t,r=0,i=1)=>{if(typeof e!="number")return Bc(e,{a:t});const o=gs.set({r:at.channel.clamp.r(e),g:at.channel.clamp.g(t),b:at.channel.clamp.b(r),a:at.channel.clamp.a(i)});return Ee.stringify(o)},_y=e=>{const{r:t,g:r,b:i}=Ee.parse(e),o=.2126*at.channel.toLinear(t)+.7152*at.channel.toLinear(r)+.0722*at.channel.toLinear(i);return at.lang.round(o)},By=e=>_y(e)>=.5,ke=e=>!By(e),vc=(e,t,r)=>{const i=Ee.parse(e),o=i[t],s=at.channel.clamp[t](o+r);return o!==s&&(i[t]=s),Ee.stringify(i)},O=(e,t)=>vc(e,"l",t),I=(e,t)=>vc(e,"l",-t),x=(e,t)=>{const r=Ee.parse(e),i={};for(const o in t)t[o]&&(i[o]=r[o]+t[o]);return Bc(e,i)},vy=(e,t,r=50)=>{const{r:i,g:o,b:s,a}=Ee.parse(e),{r:n,g:l,b:c,a:h}=Ee.parse(t),d=r/100,f=d*2-1,u=a-h,m=((f*u===-1?f:(f+u)/(1+f*u))+1)/2,y=1-m,C=i*m+n*y,b=o*m+l*y,k=s*m+c*y,T=a*d+h*(1-d);return or(C,b,k,T)},B=(e,t=100)=>{const r=Ee.parse(e);return r.r=255-r.r,r.g=255-r.g,r.b=255-r.b,vy(r,e,t)};/*! @license DOMPurify 3.4.11 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.11/LICENSE */function Hl(e,t){(t==null||t>e.length)&&(t=e.length);for(var r=0,i=Array(t);r<t;r++)i[r]=e[r];return i}function Ly(e){if(Array.isArray(e))return e}function Fy(e,t){var r=e==null?null:typeof Symbol<"u"&&e[Symbol.iterator]||e["@@iterator"];if(r!=null){var i,o,s,a,n=[],l=!0,c=!1;try{if(s=(r=r.call(e)).next,t!==0)for(;!(l=(i=s.call(r)).done)&&(n.push(i.value),n.length!==t);l=!0);}catch(h){c=!0,o=h}finally{try{if(!l&&r.return!=null&&(a=r.return(),Object(a)!==a))return}finally{if(c)throw o}}return n}}function Ay(){throw new TypeError(`Invalid attempt to destructure non-iterable instance. In order to be iterable, non-array objects must have a [Symbol.iterator]() method.`)}function Ey(e,t){return Ly(e)||Fy(e,t)||My(e,t)||Ay()}function My(e,t){if(e){if(typeof e=="string")return Hl(e,t);var r={}.toString.call(e).slice(8,-1);return r==="Object"&&e.constructor&&(r=e.constructor.name),r==="Map"||r==="Set"?Array.from(e):r==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(r)?Hl(e,t):void 0}}const Lc=Object.entries,Yl=Object.setPrototypeOf,$y=Object.isFrozen,Oy=Object.getPrototypeOf,Iy=Object.getOwnPropertyDescriptor;let Ut=Object.freeze,jt=Object.seal,zr=Object.create,Fc=typeof Reflect<"u"&&Reflect,ya=Fc.apply,Ca=Fc.construct;Ut||(Ut=function(t){return t});jt||(jt=function(t){return t});ya||(ya=function(t,r){for(var i=arguments.length,o=new Array(i>2?i-2:0),s=2;s<i;s++)o[s-2]=arguments[s];return t.apply(r,o)});Ca||(Ca=function(t){for(var r=arguments.length,i=new Array(r>1?r-1:0),o=1;o<r;o++)i[o-1]=arguments[o];return new t(...i)});const ui=Ot(Array.prototype.forEach),Dy=Ot(Array.prototype.lastIndexOf),Ul=Ot(Array.prototype.pop),Rr=Ot(Array.prototype.push),Py=Ot(Array.prototype.splice),er=Array.isArray,Ti=Ot(String.prototype.toLowerCase),Ks=Ot(String.prototype.toString),jl=Ot(String.prototype.match),fi=Ot(String.prototype.replace),Gl=Ot(String.prototype.indexOf),Ry=Ot(String.prototype.trim),Ny=Ot(Number.prototype.toString),qy=Ot(Boolean.prototype.toString),Xl=typeof BigInt>"u"?null:Ot(BigInt.prototype.toString),Vl=typeof Symbol>"u"?null:Ot(Symbol.prototype.toString),Nt=Ot(Object.prototype.hasOwnProperty),pi=Ot(Object.prototype.toString),zt=Ot(RegExp.prototype.test),fr=Wy(TypeError);function Ot(e){return function(t){t instanceof RegExp&&(t.lastIndex=0);for(var r=arguments.length,i=new Array(r>1?r-1:0),o=1;o<r;o++)i[o-1]=arguments[o];return ya(e,t,i)}}function Wy(e){return function(){for(var t=arguments.length,r=new Array(t),i=0;i<t;i++)r[i]=arguments[i];return Ca(e,r)}}function mt(e,t){let r=arguments.length>2&&arguments[2]!==void 0?arguments[2]:Ti;if(Yl&&Yl(e,null),!er(t))return e;let i=t.length;for(;i--;){let o=t[i];if(typeof o=="string"){const s=r(o);s!==o&&($y(t)||(t[i]=s),o=s)}e[o]=!0}return e}function zy(e){for(let t=0;t<e.length;t++)Nt(e,t)||(e[t]=null);return e}function Qt(e){const t=zr(null);for(const i of Lc(e)){var r=Ey(i,2);const o=r[0],s=r[1];Nt(e,o)&&(er(s)?t[o]=zy(s):s&&typeof s=="object"&&s.constructor===Object?t[o]=Qt(s):t[o]=s)}return t}function Hy(e){switch(typeof e){case"string":return e;case"number":return Ny(e);case"boolean":return qy(e);case"bigint":return Xl?Xl(e):"0";case"symbol":return Vl?Vl(e):"Symbol()";case"undefined":return pi(e);case"function":case"object":{if(e===null)return pi(e);const t=e,r=Be(t,"toString");if(typeof r=="function"){const i=r(t);return typeof i=="string"?i:pi(i)}return pi(e)}default:return pi(e)}}function Be(e,t){for(;e!==null;){const i=Iy(e,t);if(i){if(i.get)return Ot(i.get);if(typeof i.value=="function")return Ot(i.value)}e=Oy(e)}function r(){return null}return r}function Yy(e){try{return zt(e,""),!0}catch{return!1}}const Zl=Ut(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","search","section","select","shadow","slot","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),Qs=Ut(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","enterkeyhint","exportparts","filter","font","g","glyph","glyphref","hkern","image","inputmode","line","lineargradient","marker","mask","metadata","mpath","part","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),Js=Ut(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feDropShadow","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),Uy=Ut(["animate","color-profile","cursor","discard","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),ta=Ut(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover","mprescripts"]),jy=Ut(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),Kl=Ut(["#text"]),Ql=Ut(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","command","commandfor","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","exportparts","face","for","headers","height","hidden","high","href","hreflang","id","inert","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","part","pattern","placeholder","playsinline","popover","popovertarget","popovertargetaction","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","slot","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","wrap","xmlns"]),ea=Ut(["accent-height","accumulate","additive","alignment-baseline","amplitude","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","exponent","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","intercept","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","mask-type","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","slope","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","tablevalues","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),Jl=Ut(["accent","accentunder","align","bevelled","close","columnalign","columnlines","columnspacing","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lquote","lspace","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),uo=Ut(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),Gy=jt(/{{[\w\W]*|^[\w\W]*}}/g),Xy=jt(/<%[\w\W]*|^[\w\W]*%>/g),Vy=jt(/\${[\w\W]*/g),Zy=jt(/^data-[\-\w.\u00B7-\uFFFF]+$/),Ky=jt(/^aria-[\-\w]+$/),th=jt(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp|matrix):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),Qy=jt(/^(?:\w+script|data):/i),Jy=jt(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),t0=jt(/^html$/i),e0=jt(/^[a-z][.\w]*(-[.\w]+)+$/i),eh=jt(/<[/\w!]/g),r0=jt(/<[/\w]/g),i0=jt(/<\/no(script|embed|frames)/i),o0=jt(/\/>/i),_e={element:1,attribute:2,text:3,cdataSection:4,entityReference:5,entityNode:6,processingInstruction:7,comment:8,document:9,documentType:10,documentFragment:11,notation:12},s0=function(){return typeof window>"u"?null:window},a0=function(t,r){if(typeof t!="object"||typeof t.createPolicy!="function")return null;let i=null;const o="data-tt-policy-suffix";r&&r.hasAttribute(o)&&(i=r.getAttribute(o));const s="dompurify"+(i?"#"+i:"");try{return t.createPolicy(s,{createHTML(a){return a},createScriptURL(a){return a}})}catch{return console.warn("TrustedTypes policy "+s+" could not be created."),null}},rh=function(){return{afterSanitizeAttributes:[],afterSanitizeElements:[],afterSanitizeShadowDOM:[],beforeSanitizeAttributes:[],beforeSanitizeElements:[],beforeSanitizeShadowDOM:[],uponSanitizeAttribute:[],uponSanitizeElement:[],uponSanitizeShadowNode:[]}},Qe=function(t,r,i,o){return Nt(t,r)&&er(t[r])?mt(o.base?Qt(o.base):{},t[r],o.transform):i};function Ac(){let e=arguments.length>0&&arguments[0]!==void 0?arguments[0]:s0();const t=j=>Ac(j);if(t.version="3.4.11",t.removed=[],!e||!e.document||e.document.nodeType!==_e.document||!e.Element)return t.isSupported=!1,t;let r=e.document;const i=r,o=i.currentScript;e.DocumentFragment;const s=e.HTMLTemplateElement,a=e.Node,n=e.Element,l=e.NodeFilter,c=e.NamedNodeMap;c===void 0&&(e.NamedNodeMap||e.MozNamedAttrMap),e.HTMLFormElement;const h=e.DOMParser,d=e.trustedTypes,f=n.prototype,u=Be(f,"cloneNode"),g=Be(f,"remove"),m=Be(f,"nextSibling"),y=Be(f,"childNodes"),C=Be(f,"parentNode"),b=Be(f,"shadowRoot"),k=Be(f,"attributes"),T=a&&a.prototype?Be(a.prototype,"nodeType"):null,S=a&&a.prototype?Be(a.prototype,"nodeName"):null;if(typeof s=="function"){const j=r.createElement("template");j.content&&j.content.ownerDocument&&(r=j.content.ownerDocument)}let _,L="",v,N=!1,R=0;const P=function(){if(R>0)throw fr('A configured TRUSTED_TYPES_POLICY callback (createHTML or createScriptURL) must not call DOMPurify.sanitize, as that causes infinite recursion. Do not pass a policy whose callbacks wrap DOMPurify as TRUSTED_TYPES_POLICY; see the "DOMPurify and Trusted Types" section of the README.')},z=function(w){P(),R++;try{return _.createHTML(w)}finally{R--}},W=function(w){P(),R++;try{return _.createScriptURL(w)}finally{R--}},$=function(){return N||(v=a0(d,o),N=!0),v},A=r,F=A.implementation,D=A.createNodeIterator,M=A.createDocumentFragment,H=A.getElementsByTagName,Y=i.importNode;let G=rh();t.isSupported=typeof Lc=="function"&&typeof C=="function"&&F&&F.createHTMLDocument!==void 0;const lt=Gy,ht=Xy,dt=Vy,bt=Zy,et=Ky,ft=Qy,kt=Jy,Bt=e0;let St=th,ut=null;const de=mt({},[...Zl,...Qs,...Js,...ta,...Kl]);let Tt=null;const Mr=mt({},[...Ql,...ea,...Jl,...uo]);let Lt=Object.seal(zr(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),li=null,bl=null;const Ve=Object.seal(zr(null,{tagCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeCheck:{writable:!0,configurable:!1,enumerable:!0,value:null}}));let kl=!0,Os=!0,wl=!1,Tl=!0,Ze=!1,hi=!0,dr=!1,Is=!1,Ds=null,Ps=null,Rs=!1,$r=!1,oo=!1,so=!1,Sl=!0,_l=!1;const Bl="user-content-";let Ns=!0,qs=!1,Or={},Te=null;const Ws=mt({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","selectedcontent","style","svg","template","thead","title","video","xmp"]);let vl=null;const Ll=mt({},["audio","video","img","source","image","track"]);let zs=null;const Fl=mt({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),ao="http://www.w3.org/1998/Math/MathML",no="http://www.w3.org/2000/svg",Se="http://www.w3.org/1999/xhtml";let Ir=Se,Hs=!1,Ys=null;const Jm=mt({},[ao,no,Se],Ks),Al=Ut(["mi","mo","mn","ms","mtext"]);let Us=mt({},Al);const El=Ut(["annotation-xml"]);let js=mt({},El);const ty=mt({},["title","style","font","a","script"]);let ci=null;const ey=["application/xhtml+xml","text/html"],ry="text/html";let Ft=null,Dr=null;const iy=r.createElement("form"),Ml=function(w){return w instanceof RegExp||w instanceof Function},Gs=function(){let w=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};if(Dr&&Dr===w)return;(!w||typeof w!="object")&&(w={}),w=Qt(w),ci=ey.indexOf(w.PARSER_MEDIA_TYPE)===-1?ry:w.PARSER_MEDIA_TYPE,Ft=ci==="application/xhtml+xml"?Ks:Ti,ut=Qe(w,"ALLOWED_TAGS",de,{transform:Ft}),Tt=Qe(w,"ALLOWED_ATTR",Mr,{transform:Ft}),Ys=Qe(w,"ALLOWED_NAMESPACES",Jm,{transform:Ks}),zs=Qe(w,"ADD_URI_SAFE_ATTR",Fl,{transform:Ft,base:Fl}),vl=Qe(w,"ADD_DATA_URI_TAGS",Ll,{transform:Ft,base:Ll}),Te=Qe(w,"FORBID_CONTENTS",Ws,{transform:Ft}),li=Qe(w,"FORBID_TAGS",Qt({}),{transform:Ft}),bl=Qe(w,"FORBID_ATTR",Qt({}),{transform:Ft}),Or=Nt(w,"USE_PROFILES")?w.USE_PROFILES&&typeof w.USE_PROFILES=="object"?Qt(w.USE_PROFILES):w.USE_PROFILES:!1,kl=w.ALLOW_ARIA_ATTR!==!1,Os=w.ALLOW_DATA_ATTR!==!1,wl=w.ALLOW_UNKNOWN_PROTOCOLS||!1,Tl=w.ALLOW_SELF_CLOSE_IN_ATTR!==!1,Ze=w.SAFE_FOR_TEMPLATES||!1,hi=w.SAFE_FOR_XML!==!1,dr=w.WHOLE_DOCUMENT||!1,$r=w.RETURN_DOM||!1,oo=w.RETURN_DOM_FRAGMENT||!1,so=w.RETURN_TRUSTED_TYPE||!1,Rs=w.FORCE_BODY||!1,Sl=w.SANITIZE_DOM!==!1,_l=w.SANITIZE_NAMED_PROPS||!1,Ns=w.KEEP_CONTENT!==!1,qs=w.IN_PLACE||!1,St=Yy(w.ALLOWED_URI_REGEXP)?w.ALLOWED_URI_REGEXP:th,Ir=typeof w.NAMESPACE=="string"?w.NAMESPACE:Se,Us=Nt(w,"MATHML_TEXT_INTEGRATION_POINTS")&&w.MATHML_TEXT_INTEGRATION_POINTS&&typeof w.MATHML_TEXT_INTEGRATION_POINTS=="object"?Qt(w.MATHML_TEXT_INTEGRATION_POINTS):mt({},Al),js=Nt(w,"HTML_INTEGRATION_POINTS")&&w.HTML_INTEGRATION_POINTS&&typeof w.HTML_INTEGRATION_POINTS=="object"?Qt(w.HTML_INTEGRATION_POINTS):mt({},El);const E=Nt(w,"CUSTOM_ELEMENT_HANDLING")&&w.CUSTOM_ELEMENT_HANDLING&&typeof w.CUSTOM_ELEMENT_HANDLING=="object"?Qt(w.CUSTOM_ELEMENT_HANDLING):zr(null);if(Lt=zr(null),Nt(E,"tagNameCheck")&&Ml(E.tagNameCheck)&&(Lt.tagNameCheck=E.tagNameCheck),Nt(E,"attributeNameCheck")&&Ml(E.attributeNameCheck)&&(Lt.attributeNameCheck=E.attributeNameCheck),Nt(E,"allowCustomizedBuiltInElements")&&typeof E.allowCustomizedBuiltInElements=="boolean"&&(Lt.allowCustomizedBuiltInElements=E.allowCustomizedBuiltInElements),jt(Lt),Ze&&(Os=!1),oo&&($r=!0),Or&&(ut=mt({},Kl),Tt=zr(null),Or.html===!0&&(mt(ut,Zl),mt(Tt,Ql)),Or.svg===!0&&(mt(ut,Qs),mt(Tt,ea),mt(Tt,uo)),Or.svgFilters===!0&&(mt(ut,Js),mt(Tt,ea),mt(Tt,uo)),Or.mathMl===!0&&(mt(ut,ta),mt(Tt,Jl),mt(Tt,uo))),Ve.tagCheck=null,Ve.attributeCheck=null,Nt(w,"ADD_TAGS")&&(typeof w.ADD_TAGS=="function"?Ve.tagCheck=w.ADD_TAGS:er(w.ADD_TAGS)&&(ut===de&&(ut=Qt(ut)),mt(ut,w.ADD_TAGS,Ft))),Nt(w,"ADD_ATTR")&&(typeof w.ADD_ATTR=="function"?Ve.attributeCheck=w.ADD_ATTR:er(w.ADD_ATTR)&&(Tt===Mr&&(Tt=Qt(Tt)),mt(Tt,w.ADD_ATTR,Ft))),Nt(w,"ADD_URI_SAFE_ATTR")&&er(w.ADD_URI_SAFE_ATTR)&&mt(zs,w.ADD_URI_SAFE_ATTR,Ft),Nt(w,"FORBID_CONTENTS")&&er(w.FORBID_CONTENTS)&&(Te===Ws&&(Te=Qt(Te)),mt(Te,w.FORBID_CONTENTS,Ft)),Nt(w,"ADD_FORBID_CONTENTS")&&er(w.ADD_FORBID_CONTENTS)&&(Te===Ws&&(Te=Qt(Te)),mt(Te,w.ADD_FORBID_CONTENTS,Ft)),Ns&&(ut["#text"]=!0),dr&&mt(ut,["html","head","body"]),ut.table&&(mt(ut,["tbody"]),delete li.tbody),w.TRUSTED_TYPES_POLICY){if(typeof w.TRUSTED_TYPES_POLICY.createHTML!="function")throw fr('TRUSTED_TYPES_POLICY configuration option must provide a "createHTML" hook.');if(typeof w.TRUSTED_TYPES_POLICY.createScriptURL!="function")throw fr('TRUSTED_TYPES_POLICY configuration option must provide a "createScriptURL" hook.');const U=_;_=w.TRUSTED_TYPES_POLICY;try{L=z("")}catch(J){throw _=U,J}}else w.TRUSTED_TYPES_POLICY===null?(_=void 0,L=""):(_===void 0&&(_=$()),_&&typeof L=="string"&&(L=z("")));Ut&&Ut(w),Dr=w},$l=mt({},[...Qs,...Js,...Uy]),Ol=mt({},[...ta,...jy]),oy=function(w,E,U){return E.namespaceURI===Se?w==="svg":E.namespaceURI===ao?w==="svg"&&(U==="annotation-xml"||Us[U]):!!$l[w]},sy=function(w,E,U){return E.namespaceURI===Se?w==="math":E.namespaceURI===no?w==="math"&&js[U]:!!Ol[w]},ay=function(w,E,U){return E.namespaceURI===no&&!js[U]||E.namespaceURI===ao&&!Us[U]?!1:!Ol[w]&&(ty[w]||!$l[w])},ny=function(w){let E=C(w);(!E||!E.tagName)&&(E={namespaceURI:Ir,tagName:"template"});const U=Ti(w.tagName),J=Ti(E.tagName);return Ys[w.namespaceURI]?w.namespaceURI===no?oy(U,E,J):w.namespaceURI===ao?sy(U,E,J):w.namespaceURI===Se?ay(U,E,J):!!(ci==="application/xhtml+xml"&&Ys[w.namespaceURI]):!1},Ke=function(w){Rr(t.removed,{element:w});try{C(w).removeChild(w)}catch{if(g(w),!C(w))throw fr("a node selected for removal could not be detached from its tree and cannot be safely returned; refusing to sanitize in place")}},Il=function(w){const E=y(w);if(E){const J=[];ui(E,pt=>{Rr(J,pt)}),ui(J,pt=>{try{g(pt)}catch{}})}const U=k(w);if(U)for(let J=U.length-1;J>=0;--J){const pt=U[J],yt=pt&&pt.name;if(typeof yt=="string")try{w.removeAttribute(yt)}catch{}}},ur=function(w,E){try{Rr(t.removed,{attribute:E.getAttributeNode(w),from:E})}catch{Rr(t.removed,{attribute:null,from:E})}if(E.removeAttribute(w),w==="is")if($r||oo)try{Ke(E)}catch{}else try{E.setAttribute(w,"")}catch{}},ly=function(w){const E=k(w);if(E)for(let U=E.length-1;U>=0;--U){const J=E[U],pt=J&&J.name;if(!(typeof pt!="string"||Tt[Ft(pt)]))try{w.removeAttribute(pt)}catch{}}},hy=function(w){const E=[w];for(;E.length>0;){const U=E.pop();(T?T(U):U.nodeType)===_e.element&&ly(U);const pt=y(U);if(pt)for(let yt=pt.length-1;yt>=0;--yt)E.push(pt[yt])}},Dl=function(w){let E=null,U=null;if(Rs)w="<remove></remove>"+w;else{const yt=jl(w,/^[\r\n\t ]+/);U=yt&&yt[0]}ci==="application/xhtml+xml"&&Ir===Se&&(w='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+w+"</body></html>");const J=_?z(w):w;if(Ir===Se)try{E=new h().parseFromString(J,ci)}catch{}if(!E||!E.documentElement){E=F.createDocument(Ir,"template",null);try{E.documentElement.innerHTML=Hs?L:J}catch{}}const pt=E.body||E.documentElement;return w&&U&&pt.insertBefore(r.createTextNode(U),pt.childNodes[0]||null),Ir===Se?H.call(E,dr?"html":"body")[0]:dr?E.documentElement:pt},Pl=function(w){return D.call(w.ownerDocument||w,w,l.SHOW_ELEMENT|l.SHOW_COMMENT|l.SHOW_TEXT|l.SHOW_PROCESSING_INSTRUCTION|l.SHOW_CDATA_SECTION,null)},lo=function(w){return w=fi(w,lt," "),w=fi(w,ht," "),w=fi(w,dt," "),w},Xs=function(w){var E;w.normalize();const U=D.call(w.ownerDocument||w,w,l.SHOW_TEXT|l.SHOW_COMMENT|l.SHOW_CDATA_SECTION|l.SHOW_PROCESSING_INSTRUCTION,null);let J=U.nextNode();for(;J;)J.data=lo(J.data),J=U.nextNode();const pt=(E=w.querySelectorAll)===null||E===void 0?void 0:E.call(w,"template");pt&&ui(pt,yt=>{Pr(yt.content)&&Xs(yt.content)})},ho=function(w){const E=S?S(w):null;return typeof E!="string"||Ft(E)!=="form"?!1:typeof w.nodeName!="string"||typeof w.textContent!="string"||typeof w.removeChild!="function"||w.attributes!==k(w)||typeof w.removeAttribute!="function"||typeof w.setAttribute!="function"||typeof w.namespaceURI!="string"||typeof w.insertBefore!="function"||typeof w.hasChildNodes!="function"||w.nodeType!==T(w)||w.childNodes!==y(w)},Pr=function(w){if(!T||typeof w!="object"||w===null)return!1;try{return T(w)===_e.documentFragment}catch{return!1}},di=function(w){if(!T||typeof w!="object"||w===null)return!1;try{return typeof T(w)=="number"}catch{return!1}};function Re(j,w,E){j.length!==0&&ui(j,U=>{U.call(t,w,E,Dr)})}const cy=function(w,E){return!!(hi&&w.hasChildNodes()&&!di(w.firstElementChild)&&zt(eh,w.textContent)&&zt(eh,w.innerHTML)||hi&&w.namespaceURI===Se&&E==="style"&&di(w.firstElementChild)||w.nodeType===_e.processingInstruction||hi&&w.nodeType===_e.comment&&zt(r0,w.data))},dy=function(w,E){if(!li[E]&&ql(E)&&(Lt.tagNameCheck instanceof RegExp&&zt(Lt.tagNameCheck,E)||Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(E)))return!1;if(Ns&&!Te[E]){const U=C(w),J=y(w);if(J&&U){const pt=J.length;for(let yt=pt-1;yt>=0;--yt){const Rt=qs?J[yt]:u(J[yt],!0);U.insertBefore(Rt,m(w))}}}return Ke(w),!0},Rl=function(w){if(Re(G.beforeSanitizeElements,w,null),ho(w))return Ke(w),!0;const E=Ft(S?S(w):w.nodeName);if(Re(G.uponSanitizeElement,w,{tagName:E,allowedTags:ut}),cy(w,E))return Ke(w),!0;if(li[E]||!(Ve.tagCheck instanceof Function&&Ve.tagCheck(E))&&!ut[E])return dy(w,E);if((T?T(w):w.nodeType)===_e.element&&!ny(w)||(E==="noscript"||E==="noembed"||E==="noframes")&&zt(i0,w.innerHTML))return Ke(w),!0;if(Ze&&w.nodeType===_e.text){const J=lo(w.textContent);w.textContent!==J&&(Rr(t.removed,{element:w.cloneNode()}),w.textContent=J)}return Re(G.afterSanitizeElements,w,null),!1},Nl=function(w,E,U){if(bl[E]||Sl&&(E==="id"||E==="name")&&(U in r||U in iy))return!1;const J=Tt[E]||Ve.attributeCheck instanceof Function&&Ve.attributeCheck(E,w);if(!(Os&&zt(bt,E))){if(!(kl&&zt(et,E))){if(J){if(!zs[E]){if(!zt(St,fi(U,kt,""))){if(!((E==="src"||E==="xlink:href"||E==="href")&&w!=="script"&&Gl(U,"data:")===0&&vl[w])){if(!(wl&&!zt(ft,fi(U,kt,"")))){if(U)return!1}}}}}else if(!(ql(w)&&(Lt.tagNameCheck instanceof RegExp&&zt(Lt.tagNameCheck,w)||Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(w))&&(Lt.attributeNameCheck instanceof RegExp&&zt(Lt.attributeNameCheck,E)||Lt.attributeNameCheck instanceof Function&&Lt.attributeNameCheck(E,w))||E==="is"&&Lt.allowCustomizedBuiltInElements&&(Lt.tagNameCheck instanceof RegExp&&zt(Lt.tagNameCheck,U)||Lt.tagNameCheck instanceof Function&&Lt.tagNameCheck(U))))return!1}}return!0},uy=mt({},["annotation-xml","color-profile","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","missing-glyph"]),ql=function(w){return!uy[Ti(w)]&&zt(Bt,w)},fy=function(w,E,U,J){if(_&&typeof d=="object"&&typeof d.getAttributeType=="function"&&!U)switch(d.getAttributeType(w,E)){case"TrustedHTML":return z(J);case"TrustedScriptURL":return W(J)}return J},py=function(w,E,U,J){try{U?w.setAttributeNS(U,E,J):w.setAttribute(E,J),ho(w)?Ke(w):Ul(t.removed)}catch{ur(E,w)}},Wl=function(w){Re(G.beforeSanitizeAttributes,w,null);const E=w.attributes;if(!E||ho(w))return;const U={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:Tt,forceKeepAttr:void 0};let J=E.length;const pt=Ft(w.nodeName);for(;J--;){const yt=E[J],Rt=yt.name,Mt=yt.namespaceURI,le=yt.value,ue=Ft(Rt),Zs=le;let Kt=Rt==="value"?Zs:Ry(Zs);if(U.attrName=ue,U.attrValue=Kt,U.keepAttr=!0,U.forceKeepAttr=void 0,Re(G.uponSanitizeAttribute,w,U),Kt=U.attrValue,_l&&(ue==="id"||ue==="name")&&Gl(Kt,Bl)!==0&&(ur(Rt,w),Kt=Bl+Kt),hi&&zt(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i,Kt)){ur(Rt,w);continue}if(ue==="attributename"&&jl(Kt,"href")){ur(Rt,w);continue}if(!U.forceKeepAttr){if(!U.keepAttr){ur(Rt,w);continue}if(!Tl&&zt(o0,Kt)){ur(Rt,w);continue}if(Ze&&(Kt=lo(Kt)),!Nl(pt,ue,Kt)){ur(Rt,w);continue}Kt=fy(pt,ue,Mt,Kt),Kt!==Zs&&py(w,Rt,Mt,Kt)}}Re(G.afterSanitizeAttributes,w,null)},co=function(w){let E=null;const U=Pl(w);for(Re(G.beforeSanitizeShadowDOM,w,null);E=U.nextNode();)if(Re(G.uponSanitizeShadowNode,E,null),Rl(E),Wl(E),Pr(E.content)&&co(E.content),(T?T(E):E.nodeType)===_e.element){const pt=b(E);Pr(pt)&&(Vs(pt),co(pt))}Re(G.afterSanitizeShadowDOM,w,null)},Vs=function(w){const E=[{node:w,shadow:null}];for(;E.length>0;){const U=E.pop();if(U.shadow){co(U.shadow);continue}const J=U.node,yt=(T?T(J):J.nodeType)===_e.element,Rt=y(J);if(Rt)for(let Mt=Rt.length-1;Mt>=0;--Mt)E.push({node:Rt[Mt],shadow:null});if(yt){const Mt=S?S(J):null;if(typeof Mt=="string"&&Ft(Mt)==="template"){const le=J.content;Pr(le)&&E.push({node:le,shadow:null})}}if(yt){const Mt=b(J);Pr(Mt)&&E.push({node:null,shadow:Mt},{node:Mt,shadow:null})}}};return t.sanitize=function(j){let w=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{},E=null,U=null,J=null,pt=null;if(Hs=!j,Hs&&(j="<!-->"),typeof j!="string"&&!di(j)&&(j=Hy(j),typeof j!="string"))throw fr("dirty is not a string, aborting");if(!t.isSupported)return j;Is?(ut=Ds,Tt=Ps):Gs(w),(G.uponSanitizeElement.length>0||G.uponSanitizeAttribute.length>0)&&(ut=Qt(ut)),G.uponSanitizeAttribute.length>0&&(Tt=Qt(Tt)),t.removed=[];const yt=qs&&typeof j!="string"&&di(j);if(yt){const le=S?S(j):j.nodeName;if(typeof le=="string"){const ue=Ft(le);if(!ut[ue]||li[ue])throw fr("root node is forbidden and cannot be sanitized in-place")}if(ho(j))throw fr("root node is clobbered and cannot be sanitized in-place");try{Vs(j)}catch(ue){throw Il(j),ue}}else if(di(j))E=Dl("<!---->"),U=E.ownerDocument.importNode(j,!0),U.nodeType===_e.element&&U.nodeName==="BODY"||U.nodeName==="HTML"?E=U:E.appendChild(U),Vs(U);else{if(!$r&&!Ze&&!dr&&j.indexOf("<")===-1)return _&&so?z(j):j;if(E=Dl(j),!E)return $r?null:so?L:""}E&&Rs&&Ke(E.firstChild);const Rt=Pl(yt?j:E);try{for(;J=Rt.nextNode();)Rl(J),Wl(J),Pr(J.content)&&co(J.content)}catch(le){throw yt&&Il(j),le}if(yt)return ui(t.removed,le=>{le.element&&hy(le.element)}),Ze&&Xs(j),j;if($r){if(Ze&&Xs(E),oo)for(pt=M.call(E.ownerDocument);E.firstChild;)pt.appendChild(E.firstChild);else pt=E;return(Tt.shadowroot||Tt.shadowrootmode)&&(pt=Y.call(i,pt,!0)),pt}let Mt=dr?E.outerHTML:E.innerHTML;return dr&&ut["!doctype"]&&E.ownerDocument&&E.ownerDocument.doctype&&E.ownerDocument.doctype.name&&zt(t0,E.ownerDocument.doctype.name)&&(Mt="<!DOCTYPE "+E.ownerDocument.doctype.name+`> `+Mt),Ze&&(Mt=lo(Mt)),_&&so?z(Mt):Mt},t.setConfig=function(){let j=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Gs(j),Is=!0,Ds=ut,Ps=Tt},t.clearConfig=function(){Dr=null,Is=!1,Ds=null,Ps=null,_=v,L=""},t.isValidAttribute=function(j,w,E){Dr||Gs({});const U=Ft(j),J=Ft(w);return Nl(U,J,E)},t.addHook=function(j,w){typeof w=="function"&&Nt(G,j)&&Rr(G[j],w)},t.removeHook=function(j,w){if(Nt(G,j)){if(w!==void 0){const E=Dy(G[j],w);return E===-1?void 0:Py(G[j],E,1)[0]}return Ul(G[j])}},t.removeHooks=function(j){Nt(G,j)&&(G[j]=[])},t.removeAllHooks=function(){G=rh()},t}var Kr=Ac(),xa=p((e,t,{depth:r=2,clobber:i=!1}={})=>{const o={depth:r,clobber:i};return Array.isArray(t)&&!Array.isArray(e)?(t.forEach(s=>xa(e,s,o)),e):Array.isArray(t)&&Array.isArray(e)?(t.forEach(s=>{e.includes(s)||e.push(s)}),e):e===void 0||r<=0?e!=null&&typeof e=="object"&&typeof t=="object"?Object.assign(e,t):t:(t!==void 0&&typeof e=="object"&&typeof t=="object"&&Object.keys(t).forEach(s=>{typeof t[s]=="object"&&t[s]!==null&&(e[s]===void 0||typeof e[s]=="object")?(e[s]===void 0&&(e[s]=Array.isArray(t[s])?[]:{}),e[s]=xa(e[s],t[s],{depth:r-1,clobber:i})):(i||typeof e[s]!="object"&&typeof t[s]!="object")&&(e[s]=t[s])}),e)},"assignWithDepth"),Dt=xa,$e="#ffffff",Oe="#f2f2f2",st=p((e,t)=>t?x(e,{s:-40,l:10}):x(e,{s:-40,l:-10}),"mkBorder"),n0=class{static{p(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#fff4dd",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.radius=5,this.strokeWidth=1,this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.useGradient=!0,this.dropShadow="drop-shadow( 1px 2px 2px rgba(185,185,185,1))"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||O(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.vertLineColor=this.vertLineColor||"navy",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.noteFontWeight=this.noteFontWeight||"normal",this.fontWeight=this.fontWeight||"normal",this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.darkMode?(this.rowOdd=this.rowOdd||I(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||I(this.mainBkg,10)):(this.rowOdd=this.rowOdd||O(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||O(this.mainBkg,5)),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||this.tertiaryColor,this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330}),this.darkMode)for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],75);else for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||B(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||O(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||I(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;const e=this.darkMode?-4:-1;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(5+t*3)}),this["surfacePeer"+t]=this["surfacePeer"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(8+t*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||x(this.primaryColor,{h:64}),this.fillType3=this.fillType3||x(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||x(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||x(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||x(this.primaryColor,{h:128}),this.fillType7=this.fillType7||x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||x(this.primaryColor,{l:-10}),this.pie5=this.pie5||x(this.secondaryColor,{l:-10}),this.pie6=this.pie6||x(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||x(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.venn1=this.venn1??x(this.primaryColor,{l:-30}),this.venn2=this.venn2??x(this.secondaryColor,{l:-30}),this.venn3=this.venn3??x(this.tertiaryColor,{l:-30}),this.venn4=this.venn4??x(this.primaryColor,{h:60,l:-30}),this.venn5=this.venn5??x(this.primaryColor,{h:-60,l:-30}),this.venn6=this.venn6??x(this.secondaryColor,{h:60,l:-30}),this.venn7=this.venn7??x(this.primaryColor,{h:120,l:-30}),this.venn8=this.venn8??x(this.secondaryColor,{h:120,l:-30}),this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.cynefin={domainFontSize:this.cynefin?.domainFontSize||16,itemFontSize:this.cynefin?.itemFontSize||12,boundaryColor:this.cynefin?.boundaryColor||this.lineColor,boundaryWidth:this.cynefin?.boundaryWidth||2,cliffColor:this.cynefin?.cliffColor||"#8B0000",cliffWidth:this.cynefin?.cliffWidth||4,arrowColor:this.cynefin?.arrowColor||this.lineColor,arrowWidth:this.cynefin?.arrowWidth||2,complexBg:this.cynefin?.complexBg||"#E8F5E9",complicatedBg:this.cynefin?.complicatedBg||"#E3F2FD",chaoticBg:this.cynefin?.chaoticBg||"#FBE9E7",clearBg:this.cynefin?.clearBg||"#FFF8E1",confusionBg:this.cynefin?.confusionBg||"#F3E5F5",textColor:this.cynefin?.textColor||this.textColor,labelColor:this.cynefin?.labelColor||this.primaryTextColor},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.wardleyEvolutionColor=this.wardleyEvolutionColor||"#dc3545",this.wardley={backgroundColor:this.wardley?.backgroundColor||this.background,axisColor:this.wardley?.axisColor||this.lineColor,axisTextColor:this.wardley?.axisTextColor||this.primaryTextColor,gridColor:this.wardley?.gridColor||this.gridColor,componentFill:this.wardley?.componentFill||this.background,componentStroke:this.wardley?.componentStroke||this.lineColor,componentLabelColor:this.wardley?.componentLabelColor||this.primaryTextColor,linkStroke:this.wardley?.linkStroke||this.lineColor,evolutionStroke:this.wardley?.evolutionStroke||this.wardleyEvolutionColor,annotationStroke:this.wardley?.annotationStroke||this.lineColor,annotationTextColor:this.wardley?.annotationTextColor||this.primaryTextColor,annotationFill:this.wardley?.annotationFill||this.background},this.archEdgeColor=this.archEdgeColor||"#777",this.archEdgeArrowColor=this.archEdgeArrowColor||"#777",this.archEdgeWidth=this.archEdgeWidth||"3",this.archGroupBorderColor=this.archGroupBorderColor||"#000",this.archGroupBorderWidth=this.archGroupBorderWidth||"2px",this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,dataLabelColor:this.xyChart?.dataLabelColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||x(this.primaryColor,{h:-30}),this.git4=this.git4||x(this.primaryColor,{h:-60}),this.git5=this.git5||x(this.primaryColor,{h:-90}),this.git6=this.git6||x(this.primaryColor,{h:60}),this.git7=this.git7||x(this.primaryColor,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.emUiFill=this.emUiFill||"white",this.emUiStroke=this.emUiStroke||"#dbdada",this.emProcessorFill=this.emProcessorFill||"#edb3f6",this.emProcessorStroke=this.emProcessorStroke||"#b88cbf",this.emReadModelFill=this.emReadModelFill||"#d3f1a2",this.emReadModelStroke=this.emReadModelStroke||"#a3b732",this.emCommandFill=this.emCommandFill||"#bcd6fe",this.emCommandStroke=this.emCommandStroke||"#679ac3",this.emEventFill=this.emEventFill||"#ffb778",this.emEventStroke=this.emEventStroke||"#c19a0f",this.emSwimlaneBackgroundOdd=this.emSwimlaneBackgroundOdd||"rgb(250,250,250)",this.emSwimlaneBackgroundStroke=this.emSwimlaneBackgroundStroke||"rgb(240,240,240)",this.emArrowhead=this.emArrowhead||this.lineColor,this.emRelationStroke=this.emRelationStroke||this.lineColor,this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe,this.gradientStart=this.primaryBorderColor,this.gradientStop=this.secondaryBorderColor}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},l0=p(e=>{const t=new n0;return t.calculate(e),t},"getThemeVariables"),h0=class{static{p(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=O(this.primaryColor,16),this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=B(this.background),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.lineColor=B(this.background),this.textColor=B(this.background),this.mainBkg="#1f2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=O(B("#323D47"),10),this.lineColor="calculated",this.border1="#ccc",this.border2=or(255,255,255,.25),this.arrowheadColor="calculated",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.radius=5,this.strokeWidth=1,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#F9FFFE",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="calculated",this.activationBkgColor="calculated",this.sequenceNumberColor="black",this.clusterBkg="#302F3D",this.sectionBkgColor=I("#EAE8D9",30),this.altSectionBkgColor="calculated",this.sectionBkgColor2="#EAE8D9",this.excludeBkgColor=I(this.sectionBkgColor,10),this.taskBorderColor=or(255,255,255,70),this.taskBkgColor="calculated",this.taskTextColor="calculated",this.taskTextLightColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor=or(255,255,255,50),this.activeTaskBkgColor="#81B1DB",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="grey",this.critBorderColor="#E83737",this.critBkgColor="#E83737",this.taskTextDarkColor="calculated",this.todayLineColor="#DB5757",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd=this.rowOdd||O(this.mainBkg,5)||"#ffffff",this.rowEven=this.rowEven||I(this.mainBkg,10),this.labelColor="calculated",this.errorBkgColor="#a44141",this.errorTextColor="#ddd",this.useGradient=!0,this.gradientStart=this.primaryBorderColor,this.gradientStop=this.secondaryBorderColor,this.dropShadow="drop-shadow( 1px 2px 2px rgba(185,185,185,1))",this.noteFontWeight=this.noteFontWeight||"normal",this.fontWeight=this.fontWeight||"normal"}updateColors(){this.secondBkg=O(this.mainBkg,16),this.lineColor=this.mainContrastColor,this.arrowheadColor=this.mainContrastColor,this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.edgeLabelBackground=O(this.labelBackground,25),this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.actorTextColor=this.mainContrastColor,this.actorLineColor=this.actorBorder,this.signalColor=this.mainContrastColor,this.signalTextColor=this.mainContrastColor,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.mainContrastColor,this.loopTextColor=this.mainContrastColor,this.noteBorderColor=this.secondaryBorderColor,this.noteBkgColor=this.secondBkg,this.noteTextColor=this.secondaryTextColor,this.activationBorderColor=this.border1,this.activationBkgColor=this.secondBkg,this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.background,this.taskBkgColor=O(this.mainBkg,23),this.taskTextColor=this.darkTextColor,this.taskTextLightColor=this.mainContrastColor,this.taskTextOutsideColor=this.taskTextLightColor,this.gridColor=this.mainContrastColor,this.doneTaskBkgColor=this.mainContrastColor,this.taskTextDarkColor=B(this.doneTaskBkgColor),this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#555",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#f4f4f4",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=x(this.primaryColor,{h:64}),this.fillType3=x(this.secondaryColor,{h:64}),this.fillType4=x(this.primaryColor,{h:-64}),this.fillType5=x(this.secondaryColor,{h:-64}),this.fillType6=x(this.primaryColor,{h:128}),this.fillType7=x(this.secondaryColor,{h:128}),this.cScale1=this.cScale1||"#0b0000",this.cScale2=this.cScale2||"#4d1037",this.cScale3=this.cScale3||"#3f5258",this.cScale4=this.cScale4||"#4f2f1b",this.cScale5=this.cScale5||"#6e0a0a",this.cScale6=this.cScale6||"#3b0048",this.cScale7=this.cScale7||"#995a01",this.cScale8=this.cScale8||"#154706",this.cScale9=this.cScale9||"#161722",this.cScale10=this.cScale10||"#00296f",this.cScale11=this.cScale11||"#01629c",this.cScale12=this.cScale12||"#010029",this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330});for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||B(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScalePeer"+e]=this["cScalePeer"+e]||O(this["cScale"+e],10);for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||x(this.mainBkg,{h:30,s:-30,l:-(-10+e*4)}),this["surfacePeer"+e]=this["surfacePeer"+e]||x(this.mainBkg,{h:30,s:-30,l:-(-7+e*4)});this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["pie"+e]=this["cScale"+e];this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.mainContrastColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.mainContrastColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7";for(let e=0;e<8;e++)this["venn"+(e+1)]=this["venn"+(e+1)]??O(this["cScale"+e],30);this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.cynefin={domainFontSize:this.cynefin?.domainFontSize||16,itemFontSize:this.cynefin?.itemFontSize||12,boundaryColor:this.cynefin?.boundaryColor||this.lineColor,boundaryWidth:this.cynefin?.boundaryWidth||2,cliffColor:this.cynefin?.cliffColor||"#FF6B6B",cliffWidth:this.cynefin?.cliffWidth||4,arrowColor:this.cynefin?.arrowColor||this.lineColor,arrowWidth:this.cynefin?.arrowWidth||2,complexBg:this.cynefin?.complexBg||"#1B5E20",complicatedBg:this.cynefin?.complicatedBg||"#0D47A1",chaoticBg:this.cynefin?.chaoticBg||"#BF360C",clearBg:this.cynefin?.clearBg||"#F57F17",confusionBg:this.cynefin?.confusionBg||"#4A148C",textColor:this.cynefin?.textColor||this.textColor,labelColor:this.cynefin?.labelColor||this.primaryTextColor},this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,dataLabelColor:this.xyChart?.dataLabelColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#3498db,#2ecc71,#e74c3c,#f1c40f,#bdc3c7,#ffffff,#34495e,#9b59b6,#1abc9c,#e67e22"},this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.background},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.wardleyEvolutionColor=this.wardleyEvolutionColor||"#ff6b6b",this.wardley={backgroundColor:this.wardley?.backgroundColor||this.background,axisColor:this.wardley?.axisColor||this.lineColor,axisTextColor:this.wardley?.axisTextColor||this.primaryTextColor,gridColor:this.wardley?.gridColor||this.gridColor,componentFill:this.wardley?.componentFill||this.mainBkg,componentStroke:this.wardley?.componentStroke||this.lineColor,componentLabelColor:this.wardley?.componentLabelColor||this.primaryTextColor,linkStroke:this.wardley?.linkStroke||this.lineColor,evolutionStroke:this.wardley?.evolutionStroke||this.wardleyEvolutionColor,annotationStroke:this.wardley?.annotationStroke||this.lineColor,annotationTextColor:this.wardley?.annotationTextColor||this.primaryTextColor,annotationFill:this.wardley?.annotationFill||this.mainBkg},this.classText=this.primaryTextColor,this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=O(this.secondaryColor,20),this.git1=O(this.pie2||this.secondaryColor,20),this.git2=O(this.pie3||this.tertiaryColor,20),this.git3=O(this.pie4||x(this.primaryColor,{h:-30}),20),this.git4=O(this.pie5||x(this.primaryColor,{h:-60}),20),this.git5=O(this.pie6||x(this.primaryColor,{h:-90}),10),this.git6=O(this.pie7||x(this.primaryColor,{h:60}),10),this.git7=O(this.pie8||x(this.primaryColor,{h:120}),20),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||B(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||B(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.emUiFill=this.emUiFill||"#2d2d2d",this.emUiStroke=this.emUiStroke||"#555",this.emProcessorFill=this.emProcessorFill||O("#5a3d5c",10),this.emProcessorStroke=this.emProcessorStroke||"#8a6d8c",this.emReadModelFill=this.emReadModelFill||O("#3d5a2d",10),this.emReadModelStroke=this.emReadModelStroke||"#6d8c5c",this.emCommandFill=this.emCommandFill||O("#2d3d5a",10),this.emCommandStroke=this.emCommandStroke||"#5c6d8c",this.emEventFill=this.emEventFill||O("#5a452d",10),this.emEventStroke=this.emEventStroke||"#8c755c",this.emSwimlaneBackgroundOdd=this.emSwimlaneBackgroundOdd||O(this.background,5),this.emSwimlaneBackgroundStroke=this.emSwimlaneBackgroundStroke||O(this.background,12),this.emArrowhead=this.emArrowhead||this.lineColor,this.emRelationStroke=this.emRelationStroke||this.lineColor,this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||O(this.background,12),this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||O(this.background,2),this.nodeBorder=this.nodeBorder||"#999"}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},c0=p(e=>{const t=new h0;return t.calculate(e),t},"getThemeVariables"),d0=class{static{p(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#ECECFF",this.secondaryColor=x(this.primaryColor,{h:120}),this.secondaryColor="#ffffde",this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.lineColor=B(this.background),this.textColor=B(this.background),this.background="white",this.mainBkg="#ECECFF",this.secondBkg="#ffffde",this.lineColor="#333333",this.border1="#9370DB",this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.border2="#aaaa33",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.labelBackground="rgba(232,232,232, 0.8)",this.textColor="#333",this.THEME_COLOR_LIMIT=12,this.radius=5,this.strokeWidth=1,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="calculated",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.clusterBkg="#FBFBFF",this.sectionBkgColor="calculated",this.altSectionBkgColor="calculated",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="calculated",this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor="calculated",this.taskTextOutsideColor=this.taskTextDarkColor,this.taskTextClickableColor="calculated",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBorderColor="calculated",this.critBkgColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.sectionBkgColor=or(102,102,255,.49),this.altSectionBkgColor="white",this.sectionBkgColor2="#fff400",this.taskBorderColor="#534fbc",this.taskBkgColor="#8a90dd",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="#534fbc",this.activeTaskBkgColor="#bfc7ff",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="navy",this.noteFontWeight=this.noteFontWeight||"normal",this.fontWeight=this.fontWeight||"normal",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.rowOdd="calculated",this.rowEven="calculated",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.useGradient=!1,this.gradientStart=this.primaryBorderColor,this.gradientStop=this.secondaryBorderColor,this.dropShadow="drop-shadow(1px 2px 2px rgba(185, 185, 185, 1))",this.updateColors()}updateColors(){this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||I(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||I(this.tertiaryColor,40);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=I(this["cScale"+e],10),this["cScalePeer"+e]=this["cScalePeer"+e]||I(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||x(this["cScale"+e],{h:180});for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||x(this.mainBkg,{h:30,l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||x(this.mainBkg,{h:30,l:-(7+e*5)});if(this.scaleLabelColor=this.scaleLabelColor!=="calculated"&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor,this.labelTextColor!=="calculated"){this.cScaleLabel0=this.cScaleLabel0||B(this.labelTextColor),this.cScaleLabel3=this.cScaleLabel3||B(this.labelTextColor);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.labelTextColor}this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.textColor,this.edgeLabelBackground=this.labelBackground,this.actorBorder=this.border1,this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.signalColor=this.textColor,this.signalTextColor=this.textColor,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||O(this.primaryColor,75)||"#ffffff",this.rowEven=this.rowEven||O(this.primaryColor,1),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=x(this.primaryColor,{h:64}),this.fillType3=x(this.secondaryColor,{h:64}),this.fillType4=x(this.primaryColor,{h:-64}),this.fillType5=x(this.secondaryColor,{h:-64}),this.fillType6=x(this.primaryColor,{h:128}),this.fillType7=x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||x(this.tertiaryColor,{l:-40}),this.pie4=this.pie4||x(this.primaryColor,{l:-10}),this.pie5=this.pie5||x(this.secondaryColor,{l:-30}),this.pie6=this.pie6||x(this.tertiaryColor,{l:-20}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-20}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-40}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:-40}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-40}),this.pie11=this.pie11||x(this.primaryColor,{h:-90,l:-40}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-30}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.venn1=this.venn1??x(this.primaryColor,{l:-30}),this.venn2=this.venn2??x(this.secondaryColor,{l:-30}),this.venn3=this.venn3??x(this.tertiaryColor,{l:-40}),this.venn4=this.venn4??x(this.primaryColor,{h:60,l:-30}),this.venn5=this.venn5??x(this.primaryColor,{h:-60,l:-30}),this.venn6=this.venn6??x(this.secondaryColor,{h:60,l:-30}),this.venn7=this.venn7??x(this.primaryColor,{h:120,l:-30}),this.venn8=this.venn8??x(this.secondaryColor,{h:120,l:-30}),this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.cynefin={domainFontSize:this.cynefin?.domainFontSize||16,itemFontSize:this.cynefin?.itemFontSize||12,boundaryColor:this.cynefin?.boundaryColor||this.lineColor,boundaryWidth:this.cynefin?.boundaryWidth||2,cliffColor:this.cynefin?.cliffColor||"#8B0000",cliffWidth:this.cynefin?.cliffWidth||4,arrowColor:this.cynefin?.arrowColor||this.lineColor,arrowWidth:this.cynefin?.arrowWidth||2,complexBg:this.cynefin?.complexBg||"#E8F5E9",complicatedBg:this.cynefin?.complicatedBg||"#E3F2FD",chaoticBg:this.cynefin?.chaoticBg||"#FBE9E7",clearBg:this.cynefin?.clearBg||"#FFF8E1",confusionBg:this.cynefin?.confusionBg||"#F3E5F5",textColor:this.cynefin?.textColor||this.textColor,labelColor:this.cynefin?.labelColor||this.primaryTextColor},this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.wardleyEvolutionColor=this.wardleyEvolutionColor||"#dc3545",this.wardley={backgroundColor:this.wardley?.backgroundColor||this.background,axisColor:this.wardley?.axisColor||this.lineColor,axisTextColor:this.wardley?.axisTextColor||this.primaryTextColor,gridColor:this.wardley?.gridColor||this.gridColor,componentFill:this.wardley?.componentFill||this.background,componentStroke:this.wardley?.componentStroke||this.lineColor,componentLabelColor:this.wardley?.componentLabelColor||this.primaryTextColor,linkStroke:this.wardley?.linkStroke||this.lineColor,evolutionStroke:this.wardley?.evolutionStroke||this.wardleyEvolutionColor,annotationStroke:this.wardley?.annotationStroke||this.lineColor,annotationTextColor:this.wardley?.annotationTextColor||this.primaryTextColor,annotationFill:this.wardley?.annotationFill||this.background},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,dataLabelColor:this.xyChart?.dataLabelColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#ECECFF,#8493A6,#FFC3A0,#DCDDE1,#B8E994,#D1A36F,#C3CDE6,#FFB6C1,#496078,#F8F3E3"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.labelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||x(this.primaryColor,{h:-30}),this.git4=this.git4||x(this.primaryColor,{h:-60}),this.git5=this.git5||x(this.primaryColor,{h:-90}),this.git6=this.git6||x(this.primaryColor,{h:60}),this.git7=this.git7||x(this.primaryColor,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||I(B(this.git0),25),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||B(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||B(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.emUiFill=this.emUiFill||"white",this.emUiStroke=this.emUiStroke||"#dbdada",this.emProcessorFill=this.emProcessorFill||"#edb3f6",this.emProcessorStroke=this.emProcessorStroke||"#b88cbf",this.emReadModelFill=this.emReadModelFill||"#d3f1a2",this.emReadModelStroke=this.emReadModelStroke||"#a3b732",this.emCommandFill=this.emCommandFill||"#bcd6fe",this.emCommandStroke=this.emCommandStroke||"#679ac3",this.emEventFill=this.emEventFill||"#ffb778",this.emEventStroke=this.emEventStroke||"#c19a0f",this.emSwimlaneBackgroundOdd=this.emSwimlaneBackgroundOdd||"rgb(250,250,250)",this.emSwimlaneBackgroundStroke=this.emSwimlaneBackgroundStroke||"rgb(240,240,240)",this.emArrowhead=this.emArrowhead||this.lineColor,this.emRelationStroke=this.emRelationStroke||this.lineColor,this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(Object.keys(this).forEach(r=>{this[r]==="calculated"&&(this[r]=void 0)}),typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},u0=p(e=>{const t=new d0;return t.calculate(e),t},"getThemeVariables"),f0=class{static{p(this,"Theme")}constructor(){this.background="#f4f4f4",this.primaryColor="#cde498",this.secondaryColor="#cdffb2",this.background="white",this.mainBkg="#cde498",this.secondBkg="#cdffb2",this.lineColor="green",this.border1="#13540c",this.border2="#6eaa49",this.arrowheadColor="green",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.tertiaryColor=O("#cde498",10),this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.primaryColor),this.lineColor=B(this.background),this.textColor=B(this.background),this.THEME_COLOR_LIMIT=12,this.radius=5,this.strokeWidth=1,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="#333",this.edgeLabelBackground="#e8e8e8",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="black",this.actorLineColor="calculated",this.signalColor="#333",this.signalTextColor="#333",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="#326932",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="#fff5ad",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="#6eaa49",this.altSectionBkgColor="white",this.sectionBkgColor2="#6eaa49",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="#487e3a",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="black",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="lightgrey",this.doneTaskBkgColor="lightgrey",this.doneTaskBorderColor="grey",this.critBorderColor="#ff8888",this.critBkgColor="red",this.todayLineColor="red",this.vertLineColor="#00BFFF",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.noteFontWeight="normal",this.fontWeight="normal",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.useGradient=!0,this.gradientStart=this.primaryBorderColor,this.gradientStop=this.secondaryBorderColor,this.dropShadow="drop-shadow( 1px 2px 2px rgba(185,185,185,0.5))"}updateColors(){this.actorBorder=I(this.mainBkg,20),this.actorBkg=this.mainBkg,this.labelBoxBkgColor=this.actorBkg,this.labelTextColor=this.actorTextColor,this.loopTextColor=this.actorTextColor,this.noteBorderColor=this.border2,this.noteTextColor=this.actorTextColor,this.actorLineColor=this.actorBorder,this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330}),this.cScalePeer1=this.cScalePeer1||I(this.secondaryColor,45),this.cScalePeer2=this.cScalePeer2||I(this.tertiaryColor,40);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScale"+e]=I(this["cScale"+e],10),this["cScalePeer"+e]=this["cScalePeer"+e]||I(this["cScale"+e],25);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||x(this["cScale"+e],{h:180});this.scaleLabelColor=this.scaleLabelColor!=="calculated"&&this.scaleLabelColor?this.scaleLabelColor:this.labelTextColor;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||x(this.mainBkg,{h:30,s:-30,l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||x(this.mainBkg,{h:30,s:-30,l:-(8+e*5)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.taskBorderColor=this.border1,this.taskTextColor=this.taskTextLightColor,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.rowOdd=this.rowOdd||O(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||O(this.mainBkg,20),this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.primaryBorderColor,this.specialStateColor=this.lineColor,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=x(this.primaryColor,{h:64}),this.fillType3=x(this.secondaryColor,{h:64}),this.fillType4=x(this.primaryColor,{h:-64}),this.fillType5=x(this.secondaryColor,{h:-64}),this.fillType6=x(this.primaryColor,{h:128}),this.fillType7=x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||x(this.primaryColor,{l:-30}),this.pie5=this.pie5||x(this.secondaryColor,{l:-30}),this.pie6=this.pie6||x(this.tertiaryColor,{h:40,l:-40}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-50}),this.pie11=this.pie11||x(this.primaryColor,{h:-60,l:-50}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-50}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.venn1=this.venn1??x(this.primaryColor,{l:-30}),this.venn2=this.venn2??x(this.secondaryColor,{l:-30}),this.venn3=this.venn3??x(this.tertiaryColor,{l:-30}),this.venn4=this.venn4??x(this.primaryColor,{h:60,l:-30}),this.venn5=this.venn5??x(this.primaryColor,{h:-60,l:-30}),this.venn6=this.venn6??x(this.secondaryColor,{h:60,l:-30}),this.venn7=this.venn7??x(this.primaryColor,{h:120,l:-30}),this.venn8=this.venn8??x(this.secondaryColor,{h:120,l:-30}),this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.cynefin={domainFontSize:this.cynefin?.domainFontSize||16,itemFontSize:this.cynefin?.itemFontSize||12,boundaryColor:this.cynefin?.boundaryColor||this.lineColor,boundaryWidth:this.cynefin?.boundaryWidth||2,cliffColor:this.cynefin?.cliffColor||"#8B4513",cliffWidth:this.cynefin?.cliffWidth||4,arrowColor:this.cynefin?.arrowColor||this.lineColor,arrowWidth:this.cynefin?.arrowWidth||2,complexBg:this.cynefin?.complexBg||"#C8E6C9",complicatedBg:this.cynefin?.complicatedBg||"#DCEDC8",chaoticBg:this.cynefin?.chaoticBg||"#FFE0B2",clearBg:this.cynefin?.clearBg||"#FFF9C4",confusionBg:this.cynefin?.confusionBg||"#D7CCC8",textColor:this.cynefin?.textColor||this.textColor,labelColor:this.cynefin?.labelColor||this.primaryTextColor},this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.packet={startByteColor:this.primaryTextColor,endByteColor:this.primaryTextColor,labelColor:this.primaryTextColor,titleColor:this.primaryTextColor,blockStrokeColor:this.primaryTextColor,blockFillColor:this.mainBkg},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.wardleyEvolutionColor=this.wardleyEvolutionColor||"#dc3545",this.wardley={backgroundColor:this.wardley?.backgroundColor||this.background,axisColor:this.wardley?.axisColor||this.lineColor,axisTextColor:this.wardley?.axisTextColor||this.primaryTextColor,gridColor:this.wardley?.gridColor||this.gridColor,componentFill:this.wardley?.componentFill||this.background,componentStroke:this.wardley?.componentStroke||this.lineColor,componentLabelColor:this.wardley?.componentLabelColor||this.primaryTextColor,linkStroke:this.wardley?.linkStroke||this.lineColor,evolutionStroke:this.wardley?.evolutionStroke||this.wardleyEvolutionColor,annotationStroke:this.wardley?.annotationStroke||this.lineColor,annotationTextColor:this.wardley?.annotationTextColor||this.primaryTextColor,annotationFill:this.wardley?.annotationFill||this.background},this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,dataLabelColor:this.xyChart?.dataLabelColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#CDE498,#FF6B6B,#A0D2DB,#D7BDE2,#F0F0F0,#FFC3A0,#7FD8BE,#FF9A8B,#FAF3E0,#FFF176"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||x(this.primaryColor,{h:-30}),this.git4=this.git4||x(this.primaryColor,{h:-60}),this.git5=this.git5||x(this.primaryColor,{h:-90}),this.git6=this.git6||x(this.primaryColor,{h:60}),this.git7=this.git7||x(this.primaryColor,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.gitBranchLabel0=this.gitBranchLabel0||B(this.labelTextColor),this.gitBranchLabel1=this.gitBranchLabel1||this.labelTextColor,this.gitBranchLabel2=this.gitBranchLabel2||this.labelTextColor,this.gitBranchLabel3=this.gitBranchLabel3||B(this.labelTextColor),this.gitBranchLabel4=this.gitBranchLabel4||this.labelTextColor,this.gitBranchLabel5=this.gitBranchLabel5||this.labelTextColor,this.gitBranchLabel6=this.gitBranchLabel6||this.labelTextColor,this.gitBranchLabel7=this.gitBranchLabel7||this.labelTextColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.emUiFill=this.emUiFill||"white",this.emUiStroke=this.emUiStroke||"#dbdada",this.emProcessorFill=this.emProcessorFill||"#edb3f6",this.emProcessorStroke=this.emProcessorStroke||"#b88cbf",this.emReadModelFill=this.emReadModelFill||"#d3f1a2",this.emReadModelStroke=this.emReadModelStroke||"#a3b732",this.emCommandFill=this.emCommandFill||"#bcd6fe",this.emCommandStroke=this.emCommandStroke||"#679ac3",this.emEventFill=this.emEventFill||"#ffb778",this.emEventStroke=this.emEventStroke||"#c19a0f",this.emSwimlaneBackgroundOdd=this.emSwimlaneBackgroundOdd||"rgb(250,250,250)",this.emSwimlaneBackgroundStroke=this.emSwimlaneBackgroundStroke||"rgb(240,240,240)",this.emArrowhead=this.emArrowhead||this.lineColor,this.emRelationStroke=this.emRelationStroke||this.lineColor,this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},p0=p(e=>{const t=new f0;return t.calculate(e),t},"getThemeVariables"),g0=class{static{p(this,"Theme")}constructor(){this.primaryColor="#eee",this.contrast="#707070",this.secondaryColor=O(this.contrast,55),this.background="#ffffff",this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.lineColor=B(this.background),this.textColor=B(this.background),this.mainBkg="#eee",this.secondBkg="calculated",this.lineColor="#666",this.border1="#999",this.border2="calculated",this.note="#ffa",this.text="#333",this.critical="#d42",this.done="#bbb",this.arrowheadColor="#333333",this.fontFamily='"trebuchet ms", verdana, arial, sans-serif',this.fontSize="16px",this.THEME_COLOR_LIMIT=12,this.radius=5,this.strokeWidth=1,this.nodeBkg="calculated",this.nodeBorder="calculated",this.clusterBkg="calculated",this.clusterBorder="calculated",this.defaultLinkColor="calculated",this.titleColor="calculated",this.edgeLabelBackground="white",this.actorBorder="calculated",this.actorBkg="calculated",this.actorTextColor="calculated",this.actorLineColor=this.actorBorder,this.signalColor="calculated",this.signalTextColor="calculated",this.labelBoxBkgColor="calculated",this.labelBoxBorderColor="calculated",this.labelTextColor="calculated",this.loopTextColor="calculated",this.noteBorderColor="calculated",this.noteBkgColor="calculated",this.noteTextColor="calculated",this.activationBorderColor="#666",this.activationBkgColor="#f4f4f4",this.sequenceNumberColor="white",this.sectionBkgColor="calculated",this.altSectionBkgColor="white",this.sectionBkgColor2="calculated",this.excludeBkgColor="#eeeeee",this.taskBorderColor="calculated",this.taskBkgColor="calculated",this.taskTextLightColor="white",this.taskTextColor="calculated",this.taskTextDarkColor="calculated",this.taskTextOutsideColor="calculated",this.taskTextClickableColor="#003163",this.activeTaskBorderColor="calculated",this.activeTaskBkgColor="calculated",this.gridColor="calculated",this.doneTaskBkgColor="calculated",this.doneTaskBorderColor="calculated",this.critBkgColor="calculated",this.critBorderColor="calculated",this.todayLineColor="calculated",this.vertLineColor="calculated",this.personBorder=this.primaryBorderColor,this.personBkg=this.mainBkg,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.noteFontWeight="normal",this.fontWeight="normal",this.rowOdd=this.rowOdd||O(this.mainBkg,75)||"#ffffff",this.rowEven=this.rowEven||"#f4f4f4",this.labelColor="black",this.errorBkgColor="#552222",this.errorTextColor="#552222",this.useGradient=!0,this.gradientStart=this.primaryBorderColor,this.gradientStop=this.secondaryBorderColor,this.dropShadow="drop-shadow( 1px 2px 2px rgba(185,185,185,1))"}updateColors(){this.secondBkg=O(this.contrast,55),this.border2=this.contrast,this.actorBorder=O(this.border1,23),this.actorBkg=this.mainBkg,this.actorTextColor=this.text,this.actorLineColor=this.actorBorder,this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.signalColor=this.text,this.signalTextColor=this.text,this.labelBoxBkgColor=this.actorBkg,this.labelBoxBorderColor=this.actorBorder,this.labelTextColor=this.text,this.loopTextColor=this.text,this.noteBorderColor="#999",this.noteBkgColor="#666",this.noteTextColor="#fff",this.cScale0=this.cScale0||"#555",this.cScale1=this.cScale1||"#F4F4F4",this.cScale2=this.cScale2||"#555",this.cScale3=this.cScale3||"#BBB",this.cScale4=this.cScale4||"#777",this.cScale5=this.cScale5||"#999",this.cScale6=this.cScale6||"#DDD",this.cScale7=this.cScale7||"#FFF",this.cScale8=this.cScale8||"#DDD",this.cScale9=this.cScale9||"#BBB",this.cScale10=this.cScale10||"#999",this.cScale11=this.cScale11||"#777";for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleInv"+e]=this["cScaleInv"+e]||B(this["cScale"+e]);for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this.darkMode?this["cScalePeer"+e]=this["cScalePeer"+e]||O(this["cScale"+e],10):this["cScalePeer"+e]=this["cScalePeer"+e]||I(this["cScale"+e],10);this.scaleLabelColor=this.scaleLabelColor||(this.darkMode?"black":this.labelTextColor),this.cScaleLabel0=this.cScaleLabel0||this.cScale1,this.cScaleLabel2=this.cScaleLabel2||this.cScale1;for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["cScaleLabel"+e]=this["cScaleLabel"+e]||this.scaleLabelColor;for(let e=0;e<5;e++)this["surface"+e]=this["surface"+e]||x(this.mainBkg,{l:-(5+e*5)}),this["surfacePeer"+e]=this["surfacePeer"+e]||x(this.mainBkg,{l:-(8+e*5)});this.nodeBkg=this.mainBkg,this.nodeBorder=this.border1,this.clusterBkg=this.secondBkg,this.clusterBorder=this.border2,this.defaultLinkColor=this.lineColor,this.titleColor=this.text,this.sectionBkgColor=O(this.contrast,30),this.sectionBkgColor2=O(this.contrast,30),this.taskBorderColor=I(this.contrast,10),this.taskBkgColor=this.contrast,this.taskTextColor=this.taskTextLightColor,this.taskTextDarkColor=this.text,this.taskTextOutsideColor=this.taskTextDarkColor,this.activeTaskBorderColor=this.taskBorderColor,this.activeTaskBkgColor=this.mainBkg,this.gridColor=O(this.border1,30),this.doneTaskBkgColor=this.done,this.doneTaskBorderColor=this.lineColor,this.critBkgColor=this.critical,this.critBorderColor=I(this.critBkgColor,10),this.todayLineColor=this.critBkgColor,this.vertLineColor=this.critBkgColor,this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.transitionColor=this.transitionColor||"#000",this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f4f4f4",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.stateBorder=this.stateBorder||"#000",this.innerEndBackground=this.primaryBorderColor,this.specialStateColor="#222",this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.classText=this.primaryTextColor,this.fillType0=this.primaryColor,this.fillType1=this.secondaryColor,this.fillType2=x(this.primaryColor,{h:64}),this.fillType3=x(this.secondaryColor,{h:64}),this.fillType4=x(this.primaryColor,{h:-64}),this.fillType5=x(this.secondaryColor,{h:-64}),this.fillType6=x(this.primaryColor,{h:128}),this.fillType7=x(this.secondaryColor,{h:128});for(let e=0;e<this.THEME_COLOR_LIMIT;e++)this["pie"+e]=this["cScale"+e];this.pie12=this.pie0,this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7";for(let e=0;e<8;e++)this["venn"+(e+1)]=this["venn"+(e+1)]??this["cScale"+e];this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.cynefin={domainFontSize:this.cynefin?.domainFontSize||16,itemFontSize:this.cynefin?.itemFontSize||12,boundaryColor:this.cynefin?.boundaryColor||this.lineColor,boundaryWidth:this.cynefin?.boundaryWidth||2,cliffColor:this.cynefin?.cliffColor||"#8B0000",cliffWidth:this.cynefin?.cliffWidth||4,arrowColor:this.cynefin?.arrowColor||this.lineColor,arrowWidth:this.cynefin?.arrowWidth||2,complexBg:this.cynefin?.complexBg||"#E8F5E9",complicatedBg:this.cynefin?.complicatedBg||"#E3F2FD",chaoticBg:this.cynefin?.chaoticBg||"#FBE9E7",clearBg:this.cynefin?.clearBg||"#FFF8E1",confusionBg:this.cynefin?.confusionBg||"#F3E5F5",textColor:this.cynefin?.textColor||this.textColor,labelColor:this.cynefin?.labelColor||this.primaryTextColor},this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,dataLabelColor:this.xyChart?.dataLabelColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#EEE,#6BB8E4,#8ACB88,#C7ACD6,#E8DCC2,#FFB2A8,#FFF380,#7E8D91,#FFD8B1,#FAF3E0"},this.radar={axisColor:this.radar?.axisColor||this.lineColor,axisStrokeWidth:this.radar?.axisStrokeWidth||2,axisLabelFontSize:this.radar?.axisLabelFontSize||12,curveOpacity:this.radar?.curveOpacity||.5,curveStrokeWidth:this.radar?.curveStrokeWidth||2,graticuleColor:this.radar?.graticuleColor||"#DEDEDE",graticuleStrokeWidth:this.radar?.graticuleStrokeWidth||1,graticuleOpacity:this.radar?.graticuleOpacity||.3,legendBoxSize:this.radar?.legendBoxSize||12,legendFontSize:this.radar?.legendFontSize||12},this.wardleyEvolutionColor=this.wardleyEvolutionColor||"#dc3545",this.wardley={backgroundColor:this.wardley?.backgroundColor||this.background,axisColor:this.wardley?.axisColor||this.lineColor,axisTextColor:this.wardley?.axisTextColor||this.primaryTextColor,gridColor:this.wardley?.gridColor||this.gridColor,componentFill:this.wardley?.componentFill||this.background,componentStroke:this.wardley?.componentStroke||this.lineColor,componentLabelColor:this.wardley?.componentLabelColor||this.primaryTextColor,linkStroke:this.wardley?.linkStroke||this.lineColor,evolutionStroke:this.wardley?.evolutionStroke||this.wardleyEvolutionColor,annotationStroke:this.wardley?.annotationStroke||this.lineColor,annotationTextColor:this.wardley?.annotationTextColor||this.primaryTextColor,annotationFill:this.wardley?.annotationFill||this.background},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||this.edgeLabelBackground,this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=I(this.pie1,25)||this.primaryColor,this.git1=this.pie2||this.secondaryColor,this.git2=this.pie3||this.tertiaryColor,this.git3=this.pie4||x(this.primaryColor,{h:-30}),this.git4=this.pie5||x(this.primaryColor,{h:-60}),this.git5=this.pie6||x(this.primaryColor,{h:-90}),this.git6=this.pie7||x(this.primaryColor,{h:60}),this.git7=this.pie8||x(this.primaryColor,{h:120}),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||this.labelTextColor,this.gitBranchLabel0=this.branchLabelColor,this.gitBranchLabel1="white",this.gitBranchLabel2=this.branchLabelColor,this.gitBranchLabel3="white",this.gitBranchLabel4=this.branchLabelColor,this.gitBranchLabel5=this.branchLabelColor,this.gitBranchLabel6=this.branchLabelColor,this.gitBranchLabel7=this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.emUiFill=this.emUiFill||"white",this.emUiStroke=this.emUiStroke||"#dbdada",this.emProcessorFill=this.emProcessorFill||"#edb3f6",this.emProcessorStroke=this.emProcessorStroke||"#b88cbf",this.emReadModelFill=this.emReadModelFill||"#d3f1a2",this.emReadModelStroke=this.emReadModelStroke||"#a3b732",this.emCommandFill=this.emCommandFill||"#bcd6fe",this.emCommandStroke=this.emCommandStroke||"#679ac3",this.emEventFill=this.emEventFill||"#ffb778",this.emEventStroke=this.emEventStroke||"#c19a0f",this.emSwimlaneBackgroundOdd=this.emSwimlaneBackgroundOdd||"rgb(250,250,250)",this.emSwimlaneBackgroundStroke=this.emSwimlaneBackgroundStroke||"rgb(240,240,240)",this.emArrowhead=this.emArrowhead||this.lineColor,this.emRelationStroke=this.emRelationStroke||this.lineColor,this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},m0=p(e=>{const t=new g0;return t.calculate(e),t},"getThemeVariables"),y0=class{static{p(this,"Theme")}constructor(){this.background="#ffffff",this.primaryColor="#cccccc",this.mainBkg="#ffffff",this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.radius=3,this.strokeWidth=2,this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.fontFamily="arial, sans-serif",this.fontSize="14px",this.nodeBorder="#000000",this.stateBorder="#000000",this.useGradient=!0,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="drop-shadow( 0px 1px 2px rgba(0, 0, 0, 0.25));",this.tertiaryColor="#ffffff",this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.noteFontWeight="normal",this.fontWeight="normal"}updateColors(){this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor;const e="#ECECFE",t="#E9E9F1",r=x(e,{h:180,l:5});if(this.sectionBkgColor=this.sectionBkgColor||r,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||t,this.sectionBkgColor2=this.sectionBkgColor2||e,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||e,this.activeTaskBorderColor=this.activeTaskBorderColor||e,this.activeTaskBkgColor=this.activeTaskBkgColor||O(e,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||e,this.cScale1=this.cScale1||t,this.cScale2=this.cScale2||r,this.cScale3=this.cScale3||x(e,{h:30}),this.cScale4=this.cScale4||x(e,{h:60}),this.cScale5=this.cScale5||x(e,{h:90}),this.cScale6=this.cScale6||x(e,{h:120}),this.cScale7=this.cScale7||x(e,{h:150}),this.cScale8=this.cScale8||x(e,{h:210,l:150}),this.cScale9=this.cScale9||x(e,{h:270}),this.cScale10=this.cScale10||x(e,{h:300}),this.cScale11=this.cScale11||x(e,{h:330}),this.darkMode)for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScale"+o]=I(this["cScale"+o],75);else for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScale"+o]=I(this["cScale"+o],25);for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleInv"+o]=this["cScaleInv"+o]||B(this["cScale"+o]);for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this.darkMode?this["cScalePeer"+o]=this["cScalePeer"+o]||O(this["cScale"+o],10):this["cScalePeer"+o]=this["cScalePeer"+o]||I(this["cScale"+o],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleLabel"+o]=this["cScaleLabel"+o]||this.scaleLabelColor;const i=this.darkMode?-4:-1;for(let o=0;o<5;o++)this["surface"+o]=this["surface"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(5+o*3)}),this["surfacePeer"+o]=this["surfacePeer"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(8+o*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||e,this.fillType1=this.fillType1||t,this.fillType2=this.fillType2||x(e,{h:64}),this.fillType3=this.fillType3||x(t,{h:64}),this.fillType4=this.fillType4||x(e,{h:-64}),this.fillType5=this.fillType5||x(t,{h:-64}),this.fillType6=this.fillType6||x(e,{h:128}),this.fillType7=this.fillType7||x(t,{h:128}),this.pie1=this.pie1||e,this.pie2=this.pie2||t,this.pie3=this.pie3||r,this.pie4=this.pie4||x(e,{l:-10}),this.pie5=this.pie5||x(t,{l:-10}),this.pie6=this.pie6||x(r,{l:-10}),this.pie7=this.pie7||x(e,{h:60,l:-10}),this.pie8=this.pie8||x(e,{h:-60,l:-10}),this.pie9=this.pie9||x(e,{h:120,l:0}),this.pie10=this.pie10||x(e,{h:60,l:-20}),this.pie11=this.pie11||x(e,{h:-60,l:-20}),this.pie12=this.pie12||x(e,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||e,this.quadrant2Fill=this.quadrant2Fill||x(e,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(e,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(e,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||e,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||e,this.git1=this.git1||t,this.git2=this.git2||r,this.git3=this.git3||x(e,{h:-30}),this.git4=this.git4||x(e,{h:-60}),this.git5=this.git5||x(e,{h:-90}),this.git6=this.git6||x(e,{h:60}),this.git7=this.git7||x(e,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},C0=p(e=>{const t=new y0;return t.calculate(e),t},"getThemeVariables"),x0=class{static{p(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=O(this.primaryColor,16),this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=B(this.background),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.mainBkg="#2a2020",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=O(B("#323D47"),10),this.border1="#ccc",this.border2=or(255,255,255,.25),this.arrowheadColor=B(this.background),this.fontFamily="arial, sans-serif",this.fontSize="14px",this.labelBackground="#181818",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.radius=3,this.strokeWidth=1,this.noteBkgColor="#fff5ad",this.noteTextColor="#333",this.THEME_COLOR_LIMIT=12,this.fontFamily="arial, sans-serif",this.fontSize="14px",this.useGradient=!0,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="drop-shadow( 1px 2px 2px rgba(185,185,185,0.2))",this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.noteFontWeight="normal",this.fontWeight="normal"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#333"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#333",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.border1,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||O(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330}),this.darkMode)for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],75);else for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||B(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||O(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||I(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;const e=this.darkMode?-4:-1;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(5+t*3)}),this["surfacePeer"+t]=this["surfacePeer"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(8+t*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||x(this.primaryColor,{h:64}),this.fillType3=this.fillType3||x(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||x(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||x(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||x(this.primaryColor,{h:128}),this.fillType7=this.fillType7||x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||x(this.primaryColor,{l:-10}),this.pie5=this.pie5||x(this.secondaryColor,{l:-10}),this.pie6=this.pie6||x(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||x(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||"#0b0000",this.git1=this.git1||"#4d1037",this.git2=this.git2||"#3f5258",this.git3=this.git3||"#4f2f1b",this.git4=this.git4||"#6e0a0a",this.git5=this.git5||"#3b0048",this.git6=this.git6||"#995a01",this.git7=this.git7||"#154706",this.gitDarkMode=!0,this.gitDarkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},b0=p(e=>{const t=new x0;return t.calculate(e),t},"getThemeVariables"),k0=class{static{p(this,"Theme")}constructor(){this.background="#ffffff",this.primaryColor="#cccccc",this.mainBkg="#ffffff",this.noteBkgColor="#fff5ad",this.noteTextColor="#28253D",this.THEME_COLOR_LIMIT=12,this.radius=12,this.strokeWidth=2,this.primaryBorderColor=st("#28253D",this.darkMode),this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.nodeBorder="#28253D",this.stateBorder="#28253D",this.useGradient=!1,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="url(#drop-shadow)",this.nodeShadow=!0,this.tertiaryColor="#ffffff",this.clusterBkg="#F9F9FB",this.clusterBorder="#BDBCCC",this.noteBorderColor="#FACC15",this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.actorBorder="#28253D",this.filterColor="#000000"}updateColors(){this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#28253D"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#FEF9C3",this.noteTextColor=this.noteTextColor||"#28253D",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.noteFontWeight=600,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor;const e="#ECECFE",t="#E9E9F1",r=x(e,{h:180,l:5});this.sectionBkgColor=this.sectionBkgColor||r,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||t,this.sectionBkgColor2=this.sectionBkgColor2||e,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||e,this.activeTaskBorderColor=this.activeTaskBorderColor||e,this.activeTaskBkgColor=this.activeTaskBkgColor||O(e,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.compositeTitleBackground="#F9F9FB",this.altBackground="#F9F9FB",this.stateEdgeLabelBackground="#FFFFFF",this.fontWeight=600,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor;for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScale"+o]=this.mainBkg;if(this.darkMode)for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScale"+o]=I(this["cScale"+o],75);else for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScale"+o]=I(this["cScale"+o],25);for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleInv"+o]=this["cScaleInv"+o]||B(this["cScale"+o]);for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this.darkMode?this["cScalePeer"+o]=this["cScalePeer"+o]||O(this["cScale"+o],10):this["cScalePeer"+o]=this["cScalePeer"+o]||I(this["cScale"+o],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleLabel"+o]=this["cScaleLabel"+o]||this.scaleLabelColor;const i=this.darkMode?-4:-1;for(let o=0;o<5;o++)this["surface"+o]=this["surface"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(5+o*3)}),this["surfacePeer"+o]=this["surfacePeer"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(8+o*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||e,this.fillType1=this.fillType1||t,this.fillType2=this.fillType2||x(e,{h:64}),this.fillType3=this.fillType3||x(t,{h:64}),this.fillType4=this.fillType4||x(e,{h:-64}),this.fillType5=this.fillType5||x(t,{h:-64}),this.fillType6=this.fillType6||x(e,{h:128}),this.fillType7=this.fillType7||x(t,{h:128}),this.pie1=this.pie1||e,this.pie2=this.pie2||t,this.pie3=this.pie3||r,this.pie4=this.pie4||x(e,{l:-10}),this.pie5=this.pie5||x(t,{l:-10}),this.pie6=this.pie6||x(r,{l:-10}),this.pie7=this.pie7||x(e,{h:60,l:-10}),this.pie8=this.pie8||x(e,{h:-60,l:-10}),this.pie9=this.pie9||x(e,{h:120,l:0}),this.pie10=this.pie10||x(e,{h:60,l:-20}),this.pie11=this.pie11||x(e,{h:-60,l:-20}),this.pie12=this.pie12||x(e,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||e,this.quadrant2Fill=this.quadrant2Fill||x(e,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(e,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(e,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||e,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.requirementEdgeLabelBackground="#FFFFFF",this.git0=this.git0||e,this.git1=this.git1||t,this.git2=this.git2||r,this.git3=this.git3||x(e,{h:-30}),this.git4=this.git4||x(e,{h:-60}),this.git5=this.git5||x(e,{h:-90}),this.git6=this.git6||x(e,{h:60}),this.git7=this.git7||x(e,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.commitLineColor=this.commitLineColor??"#BDBCCC",this.erEdgeLabelBackground="#FFFFFF",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},w0=p(e=>{const t=new k0;return t.calculate(e),t},"getThemeVariables"),T0=class{static{p(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=O(this.primaryColor,16),this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=B(this.background),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.mainBkg="#111113",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=O(B("#323D47"),10),this.border1="#ccc",this.border2=or(255,255,255,.25),this.arrowheadColor=B(this.background),this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.labelBackground="#111113",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.radius=12,this.strokeWidth=2,this.noteBkgColor=this.noteBkgColor??"#FEF9C3",this.noteTextColor=this.noteTextColor??"#28253D",this.THEME_COLOR_LIMIT=12,this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.nodeBorder="#FFFFFF",this.stateBorder="#FFFFFF",this.useGradient=!1,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="url(#drop-shadow)",this.nodeShadow=!0,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.clusterBkg="#1E1A2E",this.clusterBorder="#BDBCCC",this.noteBorderColor="#FACC15",this.noteFontWeight=600,this.filterColor="#FFFFFF"}updateColors(){if(this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#FFFFFF"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#FFFFFF",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.border1,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder="#FFFFFF",this.signalColor="#FFFFFF",this.labelBoxBorderColor="#BDBCCC",this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||O(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.compositeBackground="#16141F",this.altBackground="#16141F",this.compositeTitleBackground="#16141F",this.stateEdgeLabelBackground="#16141F",this.fontWeight=600,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||this.primaryColor,this.cScale1=this.cScale1||this.secondaryColor,this.cScale2=this.cScale2||this.tertiaryColor,this.cScale3=this.cScale3||x(this.primaryColor,{h:30}),this.cScale4=this.cScale4||x(this.primaryColor,{h:60}),this.cScale5=this.cScale5||x(this.primaryColor,{h:90}),this.cScale6=this.cScale6||x(this.primaryColor,{h:120}),this.cScale7=this.cScale7||x(this.primaryColor,{h:150}),this.cScale8=this.cScale8||x(this.primaryColor,{h:210,l:150}),this.cScale9=this.cScale9||x(this.primaryColor,{h:270}),this.cScale10=this.cScale10||x(this.primaryColor,{h:300}),this.cScale11=this.cScale11||x(this.primaryColor,{h:330}),this.darkMode)for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],75);else for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScale"+t]=I(this["cScale"+t],25);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||B(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||O(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||I(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=this["cScaleLabel"+t]||this.scaleLabelColor;const e=this.darkMode?-4:-1;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(5+t*3)}),this["surfacePeer"+t]=this["surfacePeer"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(8+t*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||x(this.primaryColor,{h:64}),this.fillType3=this.fillType3||x(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||x(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||x(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||x(this.primaryColor,{h:128}),this.fillType7=this.fillType7||x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||x(this.primaryColor,{l:-10}),this.pie5=this.pie5||x(this.secondaryColor,{l:-10}),this.pie6=this.pie6||x(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||x(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.requirementEdgeLabelBackground="#16141F",this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||x(this.primaryColor,{h:-30}),this.git4=this.git4||x(this.primaryColor,{h:-60}),this.git5=this.git5||x(this.primaryColor,{h:-90}),this.git6=this.git6||x(this.primaryColor,{h:60}),this.git7=this.git7||x(this.primaryColor,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.commitLineColor=this.commitLineColor??"#BDBCCC",this.erEdgeLabelBackground="#16141F",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},S0=p(e=>{const t=new T0;return t.calculate(e),t},"getThemeVariables"),_0=class{static{p(this,"Theme")}constructor(){this.background="#ffffff",this.primaryColor="#cccccc",this.mainBkg="#ffffff",this.noteBkgColor="#fff5ad",this.noteTextColor="#28253D",this.THEME_COLOR_LIMIT=12,this.radius=12,this.strokeWidth=2,this.primaryBorderColor=st(this.primaryColor,this.darkMode),this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.nodeBorder="#28253D",this.stateBorder="#28253D",this.useGradient=!1,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="url(#drop-shadow)",this.nodeShadow=!0,this.tertiaryColor="#ffffff",this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.actorBorder="#28253D",this.noteBorderColor="#FACC15",this.noteFontWeight=600,this.borderColorArray=["#E879F9","#2DD4BF","#FB923C","#22D3EE","#4ADE80","#A78BFA","#F87171","#FACC15","#818CF8","#A3E635 ","#38BDF8","#FB7185"],this.bkgColorArray=["#FDF4FF","#F0FDFA","#FFF7ED","#ECFEFF","#F0FDF4","#F5F3FF","#FEF2F2","#FEFCE8","#EEF2FF","#F7FEE7","#F0F9FF","#FFF1F2"],this.filterColor="#000000"}updateColors(){this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#28253D"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#28253D",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.primaryBorderColor,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor;const e="#ECECFE",t="#E9E9F1",r=x(e,{h:180,l:5});this.sectionBkgColor=this.sectionBkgColor||r,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||t,this.sectionBkgColor2=this.sectionBkgColor2||e,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||e,this.activeTaskBorderColor=this.activeTaskBorderColor||e,this.activeTaskBkgColor=this.activeTaskBkgColor||O(e,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||"#f4a8ff",this.cScale1=this.cScale1||"#46ecd5",this.cScale2=this.cScale2||"#ffb86a",this.cScale3=this.cScale3||"#dab2ff",this.cScale4=this.cScale4||"#7bf1a8",this.cScale5=this.cScale5||"#c4b4ff",this.cScale6=this.cScale6||"#ffa2a2",this.cScale7=this.cScale7||"#ffdf20",this.cScale8=this.cScale8||"#a3b3ff",this.cScale9=this.cScale9||"#bbf451",this.cScale10=this.cScale10||"#74d4ff",this.cScale11=this.cScale11||"#ffa1ad";for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleInv"+o]=this["cScaleInv"+o]||B(this["cScale"+o]);for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this.darkMode?this["cScalePeer"+o]=this["cScalePeer"+o]||O(this["cScale"+o],10):this["cScalePeer"+o]=this["cScalePeer"+o]||I(this["cScale"+o],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let o=0;o<this.THEME_COLOR_LIMIT;o++)this["cScaleLabel"+o]=this["cScaleLabel"+o]||this.scaleLabelColor;const i=this.darkMode?-4:-1;for(let o=0;o<5;o++)this["surface"+o]=this["surface"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(5+o*3)}),this["surfacePeer"+o]=this["surfacePeer"+o]||x(this.mainBkg,{h:180,s:-15,l:i*(8+o*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||e,this.fillType1=this.fillType1||t,this.fillType2=this.fillType2||x(e,{h:64}),this.fillType3=this.fillType3||x(t,{h:64}),this.fillType4=this.fillType4||x(e,{h:-64}),this.fillType5=this.fillType5||x(t,{h:-64}),this.fillType6=this.fillType6||x(e,{h:128}),this.fillType7=this.fillType7||x(t,{h:128}),this.pie1=this.pie1||e,this.pie2=this.pie2||t,this.pie3=this.pie3||r,this.pie4=this.pie4||x(e,{l:-10}),this.pie5=this.pie5||x(t,{l:-10}),this.pie6=this.pie6||x(r,{l:-10}),this.pie7=this.pie7||x(e,{h:60,l:-10}),this.pie8=this.pie8||x(e,{h:-60,l:-10}),this.pie9=this.pie9||x(e,{h:120,l:0}),this.pie10=this.pie10||x(e,{h:60,l:-20}),this.pie11=this.pie11||x(e,{h:-60,l:-20}),this.pie12=this.pie12||x(e,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||e,this.quadrant2Fill=this.quadrant2Fill||x(e,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(e,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(e,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||e,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||e,this.git1=this.git1||t,this.git2=this.git2||r,this.git3=this.git3||x(e,{h:-30}),this.git4=this.git4||x(e,{h:-60}),this.git5=this.git5||x(e,{h:-90}),this.git6=this.git6||x(e,{h:60}),this.git7=this.git7||x(e,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLineColor=this.commitLineColor??"#BDBCCC",this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.fontWeight=600,this.erEdgeLabelBackground="#FFFFFF",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},B0=p(e=>{const t=new _0;return t.calculate(e),t},"getThemeVariables"),v0=class{static{p(this,"Theme")}constructor(){this.background="#333",this.primaryColor="#1f2020",this.secondaryColor=O(this.primaryColor,16),this.tertiaryColor=x(this.primaryColor,{h:-160}),this.primaryBorderColor=B(this.background),this.secondaryBorderColor=st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=st(this.tertiaryColor,this.darkMode),this.primaryTextColor=B(this.primaryColor),this.secondaryTextColor=B(this.secondaryColor),this.tertiaryTextColor=B(this.tertiaryColor),this.mainBkg="#111113",this.secondBkg="calculated",this.mainContrastColor="lightgrey",this.darkTextColor=O(B("#323D47"),10),this.border1="#ccc",this.border2=or(255,255,255,.25),this.arrowheadColor=B(this.background),this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.labelBackground="#111113",this.textColor="#ccc",this.THEME_COLOR_LIMIT=12,this.radius=12,this.strokeWidth=2,this.noteBkgColor=this.noteBkgColor??"#FEF9C3",this.noteTextColor=this.noteTextColor??"#28253D",this.THEME_COLOR_LIMIT=12,this.fontFamily='"Recursive Variable", arial, sans-serif',this.fontSize="14px",this.nodeBorder="#FFFFFF",this.stateBorder="#FFFFFF",this.useGradient=!1,this.gradientStart="#0042eb",this.gradientStop="#eb0042",this.dropShadow="url(#drop-shadow)",this.nodeShadow=!0,this.archEdgeColor="calculated",this.archEdgeArrowColor="calculated",this.archEdgeWidth="3",this.archGroupBorderColor=this.primaryBorderColor,this.archGroupBorderWidth="2px",this.clusterBkg="#1E1A2E",this.clusterBorder="#BDBCCC",this.noteBorderColor="#FACC15",this.noteFontWeight=600,this.borderColorArray=["#E879F9","#2DD4BF","#FB923C","#22D3EE","#4ADE80","#A78BFA","#F87171","#FACC15","#818CF8","#A3E635 ","#38BDF8","#FB7185"],this.bkgColorArray=[],this.filterColor="#FFFFFF"}updateColors(){this.primaryTextColor=this.primaryTextColor||(this.darkMode?"#eee":"#FFFFFF"),this.secondaryColor=this.secondaryColor||x(this.primaryColor,{h:-120}),this.tertiaryColor=this.tertiaryColor||x(this.primaryColor,{h:180,l:5}),this.primaryBorderColor=this.primaryBorderColor||st(this.primaryColor,this.darkMode),this.secondaryBorderColor=this.secondaryBorderColor||st(this.secondaryColor,this.darkMode),this.tertiaryBorderColor=this.tertiaryBorderColor||st(this.tertiaryColor,this.darkMode),this.noteBorderColor=this.noteBorderColor||st(this.noteBkgColor,this.darkMode),this.noteBkgColor=this.noteBkgColor||"#fff5ad",this.noteTextColor=this.noteTextColor||"#FFFFFF",this.secondaryTextColor=this.secondaryTextColor||B(this.secondaryColor),this.tertiaryTextColor=this.tertiaryTextColor||B(this.tertiaryColor),this.lineColor=this.lineColor||B(this.background),this.arrowheadColor=this.arrowheadColor||B(this.background),this.textColor=this.textColor||this.primaryTextColor,this.border2=this.border2||this.tertiaryBorderColor,this.nodeBkg=this.nodeBkg||this.primaryColor,this.mainBkg=this.mainBkg||this.primaryColor,this.nodeBorder=this.nodeBorder||this.border1,this.clusterBkg=this.clusterBkg||this.tertiaryColor,this.clusterBorder=this.clusterBorder||this.tertiaryBorderColor,this.defaultLinkColor=this.defaultLinkColor||this.lineColor,this.titleColor=this.titleColor||this.tertiaryTextColor,this.edgeLabelBackground=this.edgeLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.nodeTextColor=this.nodeTextColor||this.primaryTextColor,this.actorBorder="#FFFFFF",this.signalColor="#FFFFFF",this.labelBoxBorderColor="#BDBCCC",this.actorBorder=this.actorBorder||this.primaryBorderColor,this.actorBkg=this.actorBkg||this.mainBkg,this.actorTextColor=this.actorTextColor||this.primaryTextColor,this.actorLineColor=this.actorLineColor||this.actorBorder,this.labelBoxBkgColor=this.labelBoxBkgColor||this.actorBkg,this.signalColor=this.signalColor||this.textColor,this.signalTextColor=this.signalTextColor||this.textColor,this.labelBoxBorderColor=this.labelBoxBorderColor||this.actorBorder,this.labelTextColor=this.labelTextColor||this.actorTextColor,this.loopTextColor=this.loopTextColor||this.actorTextColor,this.activationBorderColor=this.activationBorderColor||I(this.secondaryColor,10),this.activationBkgColor=this.activationBkgColor||this.secondaryColor,this.sequenceNumberColor=this.sequenceNumberColor||B(this.lineColor),this.rectBkgColor=this.rectBkgColor||this.tertiaryColor,this.rootLabelColor="#FFFFFF",this.sectionBkgColor=this.sectionBkgColor||this.tertiaryColor,this.altSectionBkgColor=this.altSectionBkgColor||"white",this.sectionBkgColor=this.sectionBkgColor||this.secondaryColor,this.sectionBkgColor2=this.sectionBkgColor2||this.primaryColor,this.excludeBkgColor=this.excludeBkgColor||"#eeeeee",this.taskBorderColor=this.taskBorderColor||this.primaryBorderColor,this.taskBkgColor=this.taskBkgColor||this.primaryColor,this.activeTaskBorderColor=this.activeTaskBorderColor||this.primaryColor,this.activeTaskBkgColor=this.activeTaskBkgColor||O(this.primaryColor,23),this.gridColor=this.gridColor||"lightgrey",this.doneTaskBkgColor=this.doneTaskBkgColor||"lightgrey",this.doneTaskBorderColor=this.doneTaskBorderColor||"grey",this.critBorderColor=this.critBorderColor||"#ff8888",this.critBkgColor=this.critBkgColor||"red",this.todayLineColor=this.todayLineColor||"red",this.taskTextColor=this.taskTextColor||this.textColor,this.vertLineColor=this.vertLineColor||this.primaryBorderColor,this.taskTextOutsideColor=this.taskTextOutsideColor||this.textColor,this.taskTextLightColor=this.taskTextLightColor||this.textColor,this.taskTextColor=this.taskTextColor||this.primaryTextColor,this.taskTextDarkColor=this.taskTextDarkColor||this.textColor,this.taskTextClickableColor=this.taskTextClickableColor||"#003163",this.archEdgeColor=this.lineColor,this.archEdgeArrowColor=this.lineColor,this.personBorder=this.personBorder||this.primaryBorderColor,this.personBkg=this.personBkg||this.mainBkg,this.transitionColor=this.transitionColor||this.lineColor,this.transitionLabelColor=this.transitionLabelColor||this.textColor,this.stateLabelColor=this.stateLabelColor||this.stateBkg||this.primaryTextColor,this.stateBkg=this.stateBkg||this.mainBkg,this.labelBackgroundColor=this.labelBackgroundColor||this.stateBkg,this.compositeBackground=this.compositeBackground||this.background||this.tertiaryColor,this.altBackground=this.altBackground||"#f0f0f0",this.compositeTitleBackground=this.compositeTitleBackground||this.mainBkg,this.compositeBorder=this.compositeBorder||this.nodeBorder,this.innerEndBackground=this.nodeBorder,this.errorBkgColor=this.errorBkgColor||this.tertiaryColor,this.errorTextColor=this.errorTextColor||this.tertiaryTextColor,this.transitionColor=this.transitionColor||this.lineColor,this.specialStateColor=this.lineColor,this.cScale0=this.cScale0||"#f4a8ff",this.cScale1=this.cScale1||"#46ecd5",this.cScale2=this.cScale2||"#ffb86a",this.cScale3=this.cScale3||"#dab2ff",this.cScale4=this.cScale4||"#7bf1a8",this.cScale5=this.cScale5||"#c4b4ff",this.cScale6=this.cScale6||"#ffa2a2",this.cScale7=this.cScale7||"#ffdf20",this.cScale8=this.cScale8||"#a3b3ff",this.cScale9=this.cScale9||"#bbf451",this.cScale10=this.cScale10||"#74d4ff",this.cScale11=this.cScale11||"#ffa1ad";for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleInv"+t]=this["cScaleInv"+t]||B(this["cScale"+t]);for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this.darkMode?this["cScalePeer"+t]=this["cScalePeer"+t]||O(this["cScale"+t],10):this["cScalePeer"+t]=this["cScalePeer"+t]||I(this["cScale"+t],10);this.scaleLabelColor=this.scaleLabelColor||this.labelTextColor;for(let t=0;t<this.THEME_COLOR_LIMIT;t++)this["cScaleLabel"+t]=I(this["cScale"+t],75);const e=this.darkMode?-4:-1;for(let t=0;t<5;t++)this["surface"+t]=this["surface"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(5+t*3)}),this["surfacePeer"+t]=this["surfacePeer"+t]||x(this.mainBkg,{h:180,s:-15,l:e*(8+t*3)});this.classText=this.classText||this.textColor,this.fillType0=this.fillType0||this.primaryColor,this.fillType1=this.fillType1||this.secondaryColor,this.fillType2=this.fillType2||x(this.primaryColor,{h:64}),this.fillType3=this.fillType3||x(this.secondaryColor,{h:64}),this.fillType4=this.fillType4||x(this.primaryColor,{h:-64}),this.fillType5=this.fillType5||x(this.secondaryColor,{h:-64}),this.fillType6=this.fillType6||x(this.primaryColor,{h:128}),this.fillType7=this.fillType7||x(this.secondaryColor,{h:128}),this.pie1=this.pie1||this.primaryColor,this.pie2=this.pie2||this.secondaryColor,this.pie3=this.pie3||this.tertiaryColor,this.pie4=this.pie4||x(this.primaryColor,{l:-10}),this.pie5=this.pie5||x(this.secondaryColor,{l:-10}),this.pie6=this.pie6||x(this.tertiaryColor,{l:-10}),this.pie7=this.pie7||x(this.primaryColor,{h:60,l:-10}),this.pie8=this.pie8||x(this.primaryColor,{h:-60,l:-10}),this.pie9=this.pie9||x(this.primaryColor,{h:120,l:0}),this.pie10=this.pie10||x(this.primaryColor,{h:60,l:-20}),this.pie11=this.pie11||x(this.primaryColor,{h:-60,l:-20}),this.pie12=this.pie12||x(this.primaryColor,{h:120,l:-10}),this.pieTitleTextSize=this.pieTitleTextSize||"25px",this.pieTitleTextColor=this.pieTitleTextColor||this.taskTextDarkColor,this.pieSectionTextSize=this.pieSectionTextSize||"17px",this.pieSectionTextColor=this.pieSectionTextColor||this.textColor,this.pieLegendTextSize=this.pieLegendTextSize||"17px",this.pieLegendTextColor=this.pieLegendTextColor||this.taskTextDarkColor,this.pieStrokeColor=this.pieStrokeColor||"black",this.pieStrokeWidth=this.pieStrokeWidth||"2px",this.pieOuterStrokeWidth=this.pieOuterStrokeWidth||"2px",this.pieOuterStrokeColor=this.pieOuterStrokeColor||"black",this.pieOpacity=this.pieOpacity||"0.7",this.vennTitleTextColor=this.vennTitleTextColor??this.titleColor,this.vennSetTextColor=this.vennSetTextColor??this.textColor,this.quadrant1Fill=this.quadrant1Fill||this.primaryColor,this.quadrant2Fill=this.quadrant2Fill||x(this.primaryColor,{r:5,g:5,b:5}),this.quadrant3Fill=this.quadrant3Fill||x(this.primaryColor,{r:10,g:10,b:10}),this.quadrant4Fill=this.quadrant4Fill||x(this.primaryColor,{r:15,g:15,b:15}),this.quadrant1TextFill=this.quadrant1TextFill||this.primaryTextColor,this.quadrant2TextFill=this.quadrant2TextFill||x(this.primaryTextColor,{r:-5,g:-5,b:-5}),this.quadrant3TextFill=this.quadrant3TextFill||x(this.primaryTextColor,{r:-10,g:-10,b:-10}),this.quadrant4TextFill=this.quadrant4TextFill||x(this.primaryTextColor,{r:-15,g:-15,b:-15}),this.quadrantPointFill=this.quadrantPointFill||ke(this.quadrant1Fill)?O(this.quadrant1Fill):I(this.quadrant1Fill),this.quadrantPointTextFill=this.quadrantPointTextFill||this.primaryTextColor,this.quadrantXAxisTextFill=this.quadrantXAxisTextFill||this.primaryTextColor,this.quadrantYAxisTextFill=this.quadrantYAxisTextFill||this.primaryTextColor,this.quadrantInternalBorderStrokeFill=this.quadrantInternalBorderStrokeFill||this.primaryBorderColor,this.quadrantExternalBorderStrokeFill=this.quadrantExternalBorderStrokeFill||this.primaryBorderColor,this.quadrantTitleFill=this.quadrantTitleFill||this.primaryTextColor,this.xyChart={backgroundColor:this.xyChart?.backgroundColor||this.background,titleColor:this.xyChart?.titleColor||this.primaryTextColor,xAxisTitleColor:this.xyChart?.xAxisTitleColor||this.primaryTextColor,xAxisLabelColor:this.xyChart?.xAxisLabelColor||this.primaryTextColor,xAxisTickColor:this.xyChart?.xAxisTickColor||this.primaryTextColor,xAxisLineColor:this.xyChart?.xAxisLineColor||this.primaryTextColor,yAxisTitleColor:this.xyChart?.yAxisTitleColor||this.primaryTextColor,yAxisLabelColor:this.xyChart?.yAxisLabelColor||this.primaryTextColor,yAxisTickColor:this.xyChart?.yAxisTickColor||this.primaryTextColor,yAxisLineColor:this.xyChart?.yAxisLineColor||this.primaryTextColor,plotColorPalette:this.xyChart?.plotColorPalette||"#FFF4DD,#FFD8B1,#FFA07A,#ECEFF1,#D6DBDF,#C3E0A8,#FFB6A4,#FFD74D,#738FA7,#FFFFF0"},this.requirementBackground=this.requirementBackground||this.primaryColor,this.requirementBorderColor=this.requirementBorderColor||this.primaryBorderColor,this.requirementBorderSize=this.requirementBorderSize||"1",this.requirementTextColor=this.requirementTextColor||this.primaryTextColor,this.relationColor=this.relationColor||this.lineColor,this.relationLabelBackground=this.relationLabelBackground||(this.darkMode?I(this.secondaryColor,30):this.secondaryColor),this.relationLabelColor=this.relationLabelColor||this.actorTextColor,this.git0=this.git0||this.primaryColor,this.git1=this.git1||this.secondaryColor,this.git2=this.git2||this.tertiaryColor,this.git3=this.git3||x(this.primaryColor,{h:-30}),this.git4=this.git4||x(this.primaryColor,{h:-60}),this.git5=this.git5||x(this.primaryColor,{h:-90}),this.git6=this.git6||x(this.primaryColor,{h:60}),this.git7=this.git7||x(this.primaryColor,{h:120}),this.darkMode?(this.git0=O(this.git0,25),this.git1=O(this.git1,25),this.git2=O(this.git2,25),this.git3=O(this.git3,25),this.git4=O(this.git4,25),this.git5=O(this.git5,25),this.git6=O(this.git6,25),this.git7=O(this.git7,25)):(this.git0=I(this.git0,25),this.git1=I(this.git1,25),this.git2=I(this.git2,25),this.git3=I(this.git3,25),this.git4=I(this.git4,25),this.git5=I(this.git5,25),this.git6=I(this.git6,25),this.git7=I(this.git7,25)),this.gitInv0=this.gitInv0||B(this.git0),this.gitInv1=this.gitInv1||B(this.git1),this.gitInv2=this.gitInv2||B(this.git2),this.gitInv3=this.gitInv3||B(this.git3),this.gitInv4=this.gitInv4||B(this.git4),this.gitInv5=this.gitInv5||B(this.git5),this.gitInv6=this.gitInv6||B(this.git6),this.gitInv7=this.gitInv7||B(this.git7),this.branchLabelColor=this.branchLabelColor||(this.darkMode?"black":this.labelTextColor),this.gitBranchLabel0=this.gitBranchLabel0||this.branchLabelColor,this.gitBranchLabel1=this.gitBranchLabel1||this.branchLabelColor,this.gitBranchLabel2=this.gitBranchLabel2||this.branchLabelColor,this.gitBranchLabel3=this.gitBranchLabel3||this.branchLabelColor,this.gitBranchLabel4=this.gitBranchLabel4||this.branchLabelColor,this.gitBranchLabel5=this.gitBranchLabel5||this.branchLabelColor,this.gitBranchLabel6=this.gitBranchLabel6||this.branchLabelColor,this.gitBranchLabel7=this.gitBranchLabel7||this.branchLabelColor,this.tagLabelColor=this.tagLabelColor||this.primaryTextColor,this.tagLabelBackground=this.tagLabelBackground||this.primaryColor,this.tagLabelBorder=this.tagBorder||this.primaryBorderColor,this.tagLabelFontSize=this.tagLabelFontSize||"10px",this.commitLabelColor=this.commitLabelColor||this.secondaryTextColor,this.commitLabelBackground=this.commitLabelBackground||this.secondaryColor,this.commitLabelFontSize=this.commitLabelFontSize||"10px",this.commitLineColor=this.commitLineColor??"#BDBCCC",this.fontWeight=600,this.erEdgeLabelBackground="#16141F",this.attributeBackgroundColorOdd=this.attributeBackgroundColorOdd||$e,this.attributeBackgroundColorEven=this.attributeBackgroundColorEven||Oe}calculate(e){if(typeof e!="object"){this.updateColors();return}const t=Object.keys(e);t.forEach(r=>{this[r]=e[r]}),this.updateColors(),t.forEach(r=>{this[r]=e[r]})}},L0=p(e=>{const t=new v0;return t.calculate(e),t},"getThemeVariables"),He={base:{getThemeVariables:l0},dark:{getThemeVariables:c0},default:{getThemeVariables:u0},forest:{getThemeVariables:p0},neutral:{getThemeVariables:m0},neo:{getThemeVariables:C0},"neo-dark":{getThemeVariables:b0},redux:{getThemeVariables:w0},"redux-dark":{getThemeVariables:S0},"redux-color":{getThemeVariables:B0},"redux-dark-color":{getThemeVariables:L0}},Wt={flowchart:{useMaxWidth:!0,titleTopMargin:25,subGraphTitleMargin:{top:0,bottom:0},diagramPadding:8,htmlLabels:null,nodeSpacing:50,rankSpacing:50,curve:"basis",padding:15,defaultRenderer:"dagre-wrapper",wrappingWidth:200,inheritDir:!1},swimlane:{useMaxWidth:!0,lineHops:"arc",ignoreCrossLaneEdges:!0,optimizeRanksByCrossings:!0,automaticLaneOrdering:!1},sequence:{useMaxWidth:!0,hideUnusedParticipants:!1,activationWidth:10,diagramMarginX:50,diagramMarginY:10,actorMargin:50,width:150,height:65,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",mirrorActors:!0,forceMenus:!1,bottomMarginAdj:1,rightAngles:!1,showSequenceNumbers:!1,actorFontSize:14,actorFontFamily:'"Open Sans", sans-serif',actorFontWeight:400,noteFontSize:14,noteFontFamily:'"trebuchet ms", verdana, arial, sans-serif',noteFontWeight:400,noteAlign:"center",messageFontSize:16,messageFontFamily:'"trebuchet ms", verdana, arial, sans-serif',messageFontWeight:400,wrap:!1,wrapPadding:10,labelBoxWidth:50,labelBoxHeight:20},gantt:{useMaxWidth:!0,titleTopMargin:25,barHeight:20,barGap:4,topPadding:50,rightPadding:75,leftPadding:75,gridLineStartPadding:35,fontSize:11,sectionFontSize:11,numberSectionStyles:4,axisFormat:"%Y-%m-%d",topAxis:!1,displayMode:"",weekday:"sunday"},journey:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,maxLabelWidth:360,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],titleColor:"",titleFontFamily:'"trebuchet ms", verdana, arial, sans-serif',titleFontSize:"4ex"},class:{useMaxWidth:!0,titleTopMargin:25,arrowMarkerAbsolute:!1,dividerMargin:10,padding:5,textHeight:10,defaultRenderer:"dagre-wrapper",htmlLabels:!1,hideEmptyMembersBox:!1,hierarchicalNamespaces:!0},state:{useMaxWidth:!0,titleTopMargin:25,dividerMargin:10,sizeUnit:5,padding:8,textHeight:10,titleShift:-15,noteMargin:10,forkWidth:70,forkHeight:7,miniPadding:2,fontSizeFactor:5.02,fontSize:24,labelHeight:16,edgeLengthFactor:"20",compositTitleSize:35,radius:5,defaultRenderer:"dagre-wrapper"},er:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:20,layoutDirection:"TB",minEntityWidth:100,minEntityHeight:75,entityPadding:15,nodeSpacing:140,rankSpacing:80,stroke:"gray",fill:"honeydew",fontSize:12},pie:{useMaxWidth:!0,textPosition:.75,donutHole:0,legendPosition:"right",highlightSlice:""},quadrantChart:{useMaxWidth:!0,chartWidth:500,chartHeight:500,titleFontSize:20,titlePadding:10,quadrantPadding:5,xAxisLabelPadding:5,yAxisLabelPadding:5,xAxisLabelFontSize:16,yAxisLabelFontSize:16,quadrantLabelFontSize:16,quadrantTextTopPadding:5,pointTextPadding:5,pointLabelFontSize:12,pointRadius:5,xAxisPosition:"top",yAxisPosition:"left",quadrantInternalBorderStrokeWidth:1,quadrantExternalBorderStrokeWidth:2},xyChart:{useMaxWidth:!0,width:700,height:500,titleFontSize:20,titlePadding:10,showDataLabel:!1,showDataLabelOutsideBar:!1,showTitle:!0,xAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2,labelRotation:0},yAxis:{$ref:"#/$defs/XYChartAxisConfig",showLabel:!0,labelFontSize:14,labelPadding:5,showTitle:!0,titleFontSize:16,titlePadding:5,showTick:!0,tickLength:5,tickWidth:2,showAxisLine:!0,axisLineWidth:2,labelRotation:0},chartOrientation:"vertical",plotReservedSpacePercent:50},requirement:{useMaxWidth:!0,rect_fill:"#f9f9f9",text_color:"#333",rect_border_size:"0.5px",rect_border_color:"#bbb",rect_min_width:200,rect_min_height:200,fontSize:14,rect_padding:10,line_height:20},mindmap:{useMaxWidth:!0,padding:10,maxNodeWidth:200,layoutAlgorithm:"cose-bilkent"},ishikawa:{useMaxWidth:!0,diagramPadding:20},kanban:{useMaxWidth:!0,padding:8,sectionWidth:200,ticketBaseUrl:""},timeline:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,leftMargin:150,width:150,height:50,boxMargin:10,boxTextMargin:5,noteMargin:10,messageMargin:35,messageAlign:"center",bottomMarginAdj:1,rightAngles:!1,taskFontSize:14,taskFontFamily:'"Open Sans", sans-serif',taskMargin:50,activationWidth:10,textPlacement:"fo",actorColours:["#8FBC8F","#7CFC00","#00FFFF","#20B2AA","#B0E0E6","#FFFFE0"],sectionFills:["#191970","#8B008B","#4B0082","#2F4F4F","#800000","#8B4513","#00008B"],sectionColours:["#fff"],disableMulticolor:!1},gitGraph:{useMaxWidth:!0,titleTopMargin:25,diagramPadding:8,nodeLabel:{width:75,height:100,x:-25,y:0},mainBranchName:"main",mainBranchOrder:0,showCommitLabel:!0,showBranches:!0,rotateCommitLabel:!0,parallelCommits:!1,arrowMarkerAbsolute:!1},c4:{useMaxWidth:!0,diagramMarginX:50,diagramMarginY:10,c4ShapeMargin:50,c4ShapePadding:20,width:216,height:60,boxMargin:10,c4ShapeInRow:4,nextLinePaddingX:0,c4BoundaryInRow:2,personFontSize:14,personFontFamily:'"Open Sans", sans-serif',personFontWeight:"normal",external_personFontSize:14,external_personFontFamily:'"Open Sans", sans-serif',external_personFontWeight:"normal",systemFontSize:14,systemFontFamily:'"Open Sans", sans-serif',systemFontWeight:"normal",external_systemFontSize:14,external_systemFontFamily:'"Open Sans", sans-serif',external_systemFontWeight:"normal",system_dbFontSize:14,system_dbFontFamily:'"Open Sans", sans-serif',system_dbFontWeight:"normal",external_system_dbFontSize:14,external_system_dbFontFamily:'"Open Sans", sans-serif',external_system_dbFontWeight:"normal",system_queueFontSize:14,system_queueFontFamily:'"Open Sans", sans-serif',system_queueFontWeight:"normal",external_system_queueFontSize:14,external_system_queueFontFamily:'"Open Sans", sans-serif',external_system_queueFontWeight:"normal",boundaryFontSize:14,boundaryFontFamily:'"Open Sans", sans-serif',boundaryFontWeight:"normal",messageFontSize:12,messageFontFamily:'"Open Sans", sans-serif',messageFontWeight:"normal",containerFontSize:14,containerFontFamily:'"Open Sans", sans-serif',containerFontWeight:"normal",external_containerFontSize:14,external_containerFontFamily:'"Open Sans", sans-serif',external_containerFontWeight:"normal",container_dbFontSize:14,container_dbFontFamily:'"Open Sans", sans-serif',container_dbFontWeight:"normal",external_container_dbFontSize:14,external_container_dbFontFamily:'"Open Sans", sans-serif',external_container_dbFontWeight:"normal",container_queueFontSize:14,container_queueFontFamily:'"Open Sans", sans-serif',container_queueFontWeight:"normal",external_container_queueFontSize:14,external_container_queueFontFamily:'"Open Sans", sans-serif',external_container_queueFontWeight:"normal",componentFontSize:14,componentFontFamily:'"Open Sans", sans-serif',componentFontWeight:"normal",external_componentFontSize:14,external_componentFontFamily:'"Open Sans", sans-serif',external_componentFontWeight:"normal",component_dbFontSize:14,component_dbFontFamily:'"Open Sans", sans-serif',component_dbFontWeight:"normal",external_component_dbFontSize:14,external_component_dbFontFamily:'"Open Sans", sans-serif',external_component_dbFontWeight:"normal",component_queueFontSize:14,component_queueFontFamily:'"Open Sans", sans-serif',component_queueFontWeight:"normal",external_component_queueFontSize:14,external_component_queueFontFamily:'"Open Sans", sans-serif',external_component_queueFontWeight:"normal",wrap:!0,wrapPadding:10,person_bg_color:"#08427B",person_border_color:"#073B6F",external_person_bg_color:"#686868",external_person_border_color:"#8A8A8A",system_bg_color:"#1168BD",system_border_color:"#3C7FC0",system_db_bg_color:"#1168BD",system_db_border_color:"#3C7FC0",system_queue_bg_color:"#1168BD",system_queue_border_color:"#3C7FC0",external_system_bg_color:"#999999",external_system_border_color:"#8A8A8A",external_system_db_bg_color:"#999999",external_system_db_border_color:"#8A8A8A",external_system_queue_bg_color:"#999999",external_system_queue_border_color:"#8A8A8A",container_bg_color:"#438DD5",container_border_color:"#3C7FC0",container_db_bg_color:"#438DD5",container_db_border_color:"#3C7FC0",container_queue_bg_color:"#438DD5",container_queue_border_color:"#3C7FC0",external_container_bg_color:"#B3B3B3",external_container_border_color:"#A6A6A6",external_container_db_bg_color:"#B3B3B3",external_container_db_border_color:"#A6A6A6",external_container_queue_bg_color:"#B3B3B3",external_container_queue_border_color:"#A6A6A6",component_bg_color:"#85BBF0",component_border_color:"#78A8D8",component_db_bg_color:"#85BBF0",component_db_border_color:"#78A8D8",component_queue_bg_color:"#85BBF0",component_queue_border_color:"#78A8D8",external_component_bg_color:"#CCCCCC",external_component_border_color:"#BFBFBF",external_component_db_bg_color:"#CCCCCC",external_component_db_border_color:"#BFBFBF",external_component_queue_bg_color:"#CCCCCC",external_component_queue_border_color:"#BFBFBF"},sankey:{useMaxWidth:!0,width:600,height:400,linkColor:"gradient",nodeAlignment:"justify",showValues:!0,prefix:"",suffix:"",nodeWidth:10,nodePadding:12,labelStyle:"legacy"},block:{useMaxWidth:!0,padding:8},packet:{useMaxWidth:!0,rowHeight:32,bitWidth:32,bitsPerRow:32,showBits:!0,paddingX:5,paddingY:5},treeView:{useMaxWidth:!0,rowIndent:10,paddingX:5,paddingY:5,lineThickness:1,showIcons:!1,defaultIconPack:"",filenameIcons:{},extensionIcons:{}},architecture:{useMaxWidth:!0,padding:40,iconSize:80,fontSize:16,randomize:!1,nodeSeparation:75,idealEdgeLengthMultiplier:1.5,edgeElasticity:.45,numIter:2500,seed:1},eventmodeling:{useMaxWidth:!0,padding:30,rowHeight:32},radar:{useMaxWidth:!0,width:600,height:600,marginTop:50,marginRight:50,marginBottom:50,marginLeft:50,axisScaleFactor:1,axisLabelFactor:1.05,curveTension:.17},venn:{useMaxWidth:!0,width:800,height:450,padding:8,useDebugLayout:!1},cynefin:{useMaxWidth:!0,width:800,height:600,padding:40,showDomainDescriptions:!0,boundaryAmplitude:8,seed:0},theme:"default",look:"classic",handDrawnSeed:0,layout:"dagre",maxTextSize:5e4,maxEdges:500,darkMode:!1,fontFamily:'"trebuchet ms", verdana, arial, sans-serif;',logLevel:5,securityLevel:"strict",startOnLoad:!0,arrowMarkerAbsolute:!1,secure:["secure","securityLevel","startOnLoad","maxTextSize","suppressErrorRendering","maxEdges"],legacyMathML:!1,forceLegacyMathML:!1,deterministicIds:!1,fontSize:16,markdownAutoWrap:!0,suppressErrorRendering:!1},Ec={...Wt,deterministicIDSeed:void 0,elk:{mergeEdges:!1,nodePlacementStrategy:"BRANDES_KOEPF",forceNodeModelOrder:!1,considerModelOrder:"NODES_AND_EDGES"},themeCSS:void 0,themeVariables:He.default.getThemeVariables(),sequence:{...Wt.sequence,messageFont:p(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont"),noteFont:p(function(){return{fontFamily:this.noteFontFamily,fontSize:this.noteFontSize,fontWeight:this.noteFontWeight}},"noteFont"),actorFont:p(function(){return{fontFamily:this.actorFontFamily,fontSize:this.actorFontSize,fontWeight:this.actorFontWeight}},"actorFont")},class:{hideEmptyMembersBox:!1,hierarchicalNamespaces:!0},gantt:{...Wt.gantt,tickInterval:void 0,useWidth:void 0},c4:{...Wt.c4,useWidth:void 0,personFont:p(function(){return{fontFamily:this.personFontFamily,fontSize:this.personFontSize,fontWeight:this.personFontWeight}},"personFont"),flowchart:{...Wt.flowchart,inheritDir:!1},external_personFont:p(function(){return{fontFamily:this.external_personFontFamily,fontSize:this.external_personFontSize,fontWeight:this.external_personFontWeight}},"external_personFont"),systemFont:p(function(){return{fontFamily:this.systemFontFamily,fontSize:this.systemFontSize,fontWeight:this.systemFontWeight}},"systemFont"),external_systemFont:p(function(){return{fontFamily:this.external_systemFontFamily,fontSize:this.external_systemFontSize,fontWeight:this.external_systemFontWeight}},"external_systemFont"),system_dbFont:p(function(){return{fontFamily:this.system_dbFontFamily,fontSize:this.system_dbFontSize,fontWeight:this.system_dbFontWeight}},"system_dbFont"),external_system_dbFont:p(function(){return{fontFamily:this.external_system_dbFontFamily,fontSize:this.external_system_dbFontSize,fontWeight:this.external_system_dbFontWeight}},"external_system_dbFont"),system_queueFont:p(function(){return{fontFamily:this.system_queueFontFamily,fontSize:this.system_queueFontSize,fontWeight:this.system_queueFontWeight}},"system_queueFont"),external_system_queueFont:p(function(){return{fontFamily:this.external_system_queueFontFamily,fontSize:this.external_system_queueFontSize,fontWeight:this.external_system_queueFontWeight}},"external_system_queueFont"),containerFont:p(function(){return{fontFamily:this.containerFontFamily,fontSize:this.containerFontSize,fontWeight:this.containerFontWeight}},"containerFont"),external_containerFont:p(function(){return{fontFamily:this.external_containerFontFamily,fontSize:this.external_containerFontSize,fontWeight:this.external_containerFontWeight}},"external_containerFont"),container_dbFont:p(function(){return{fontFamily:this.container_dbFontFamily,fontSize:this.container_dbFontSize,fontWeight:this.container_dbFontWeight}},"container_dbFont"),external_container_dbFont:p(function(){return{fontFamily:this.external_container_dbFontFamily,fontSize:this.external_container_dbFontSize,fontWeight:this.external_container_dbFontWeight}},"external_container_dbFont"),container_queueFont:p(function(){return{fontFamily:this.container_queueFontFamily,fontSize:this.container_queueFontSize,fontWeight:this.container_queueFontWeight}},"container_queueFont"),external_container_queueFont:p(function(){return{fontFamily:this.external_container_queueFontFamily,fontSize:this.external_container_queueFontSize,fontWeight:this.external_container_queueFontWeight}},"external_container_queueFont"),componentFont:p(function(){return{fontFamily:this.componentFontFamily,fontSize:this.componentFontSize,fontWeight:this.componentFontWeight}},"componentFont"),external_componentFont:p(function(){return{fontFamily:this.external_componentFontFamily,fontSize:this.external_componentFontSize,fontWeight:this.external_componentFontWeight}},"external_componentFont"),component_dbFont:p(function(){return{fontFamily:this.component_dbFontFamily,fontSize:this.component_dbFontSize,fontWeight:this.component_dbFontWeight}},"component_dbFont"),external_component_dbFont:p(function(){return{fontFamily:this.external_component_dbFontFamily,fontSize:this.external_component_dbFontSize,fontWeight:this.external_component_dbFontWeight}},"external_component_dbFont"),component_queueFont:p(function(){return{fontFamily:this.component_queueFontFamily,fontSize:this.component_queueFontSize,fontWeight:this.component_queueFontWeight}},"component_queueFont"),external_component_queueFont:p(function(){return{fontFamily:this.external_component_queueFontFamily,fontSize:this.external_component_queueFontSize,fontWeight:this.external_component_queueFontWeight}},"external_component_queueFont"),boundaryFont:p(function(){return{fontFamily:this.boundaryFontFamily,fontSize:this.boundaryFontSize,fontWeight:this.boundaryFontWeight}},"boundaryFont"),messageFont:p(function(){return{fontFamily:this.messageFontFamily,fontSize:this.messageFontSize,fontWeight:this.messageFontWeight}},"messageFont")},pie:{...Wt.pie,useWidth:984},xyChart:{...Wt.xyChart,useWidth:void 0},requirement:{...Wt.requirement,useWidth:void 0},packet:{...Wt.packet},eventmodeling:{...Wt.eventmodeling},treeView:{...Wt.treeView,useWidth:void 0},radar:{...Wt.radar},railroad:{...Wt.railroad,fontSize:void 0,fontFamily:void 0,terminalFill:void 0,terminalStroke:void 0,terminalTextColor:void 0,nonTerminalFill:void 0,nonTerminalStroke:void 0,nonTerminalTextColor:void 0,lineColor:void 0,markerFill:void 0,commentFill:void 0,commentStroke:void 0,commentTextColor:void 0,specialFill:void 0,specialStroke:void 0,ruleNameColor:void 0},ishikawa:{...Wt.ishikawa},sankey:{...Wt.sankey,nodeColors:void 0},treemap:{useMaxWidth:!0,padding:10,diagramPadding:8,showValues:!0,nodeWidth:100,nodeHeight:40,borderWidth:1,valueFontSize:12,labelFontSize:14,valueFormat:","},venn:{...Wt.venn},cynefin:{...Wt.cynefin}},Mc=p((e,t="")=>Object.keys(e).reduce((r,i)=>Array.isArray(e[i])?r:typeof e[i]=="object"&&e[i]!==null?[...r,t+i,...Mc(e[i],"")]:[...r,t+i],[]),"keyify"),F0=new Set(Mc(Ec,"")),$c=Ec,A0={nodeColors:/^#[\da-f]{3,8}$|^rgb\([\d\s%,.]+\)$|^hsl\([\d\s%,.]+\)$|^[a-z]+$/i,filenameIcons:/^[\w-]+(?::[\w-]+)?$/,extensionIcons:/^[\w-]+(?::[\w-]+)?$/},E0=p((e,t)=>{for(const r of Object.keys(e)){const i=e[r];(r.startsWith("__")||r.includes("proto")||r.includes("constr")||typeof i!="string"||!t.test(i))&&(q.debug("sanitize deleting dictionary entry:",r,i),delete e[r])}},"sanitizeDictionaryConfig"),Ro=p(e=>{if(q.debug("sanitizeDirective called with",e),!(typeof e!="object"||e==null)){if(Array.isArray(e)){e.forEach(t=>Ro(t));return}for(const t of Object.keys(e)){if(q.debug("Checking key",t),t.startsWith("__")||t.includes("proto")||t.includes("constr")||!F0.has(t)||e[t]==null){q.debug("sanitize deleting key: ",t),delete e[t];continue}if(typeof e[t]=="object"){const i=A0[t];i?E0(e[t],i):(q.debug("sanitizing object",t),Ro(e[t]));continue}const r=["themeCSS","fontFamily","altFontFamily"];for(const i of r)t.includes(i)&&(q.debug("sanitizing css option",t),e[t]=Oc(e[t]))}if(e.themeVariables)for(const t of Object.keys(e.themeVariables)){const r=e.themeVariables[t];r?.match&&!r.match(/^[\d "#%(),.;A-Za-z]+$/)&&(e.themeVariables[t]="")}q.debug("After sanitization",e)}},"sanitizeDirective"),Oc=p(e=>{let t=0,r=0;for(const i of e){if(t<r)return"{ /* ERROR: Unbalanced CSS */ }";i==="{"?t++:i==="}"&&r++}return t!==r?"{ /* ERROR: Unbalanced CSS */ }":e},"sanitizeCss"),Qr=Object.freeze($c),Ie=p(e=>!(e===!1||["false","null","0"].includes(String(e).trim().toLowerCase())),"evaluate"),ie=Dt({},Qr),No,Tr=[],Mi=Dt({},Qr),ms=p((e,t)=>{let r=Dt({},e),i={};for(const o of t)Pc(o),i=Dt(i,o);if(r=Dt(r,i),i.theme&&i.theme in He){const o=Dt({},No),s=Dt(o.themeVariables||{},i.themeVariables);r.theme&&r.theme in He&&(r.themeVariables=He[r.theme].getThemeVariables(s))}return Mi=r,Nc(Mi),Mi},"updateCurrentConfig"),M0=p(e=>(ie=Dt({},Qr),ie=Dt(ie,e),e.theme&&He[e.theme]&&(ie.themeVariables=He[e.theme].getThemeVariables(e.themeVariables)),ms(ie,Tr),ie),"setSiteConfig"),$0=p(e=>{No=Dt({},e)},"saveConfigFromInitialize"),O0=p(e=>(ie=Dt(ie,e),ms(ie,Tr),ie),"updateSiteConfig"),Ic=p(()=>Dt({},ie),"getSiteConfig"),Dc=p(e=>(Nc(e),Dt(Mi,e),vt()),"setConfig"),vt=p(()=>Dt({},Mi),"getConfig"),Pc=p(e=>{e&&(["secure",...ie.secure??[]].forEach(t=>{Object.hasOwn(e,t)&&(q.debug(`Denied attempt to modify a secure key ${t}`,e[t]),delete e[t])}),Object.keys(e).forEach(t=>{t.startsWith("__")&&delete e[t]}),Object.keys(e).forEach(t=>{typeof e[t]=="string"&&(e[t].includes("<")||e[t].includes(">")||e[t].includes("url(data:"))&&delete e[t],typeof e[t]=="object"&&Pc(e[t])}))},"sanitize"),I0=p(e=>{Ro(e),e.fontFamily&&!e.themeVariables?.fontFamily&&(e.themeVariables={...e.themeVariables,fontFamily:e.fontFamily}),Tr.push(e),ms(ie,Tr)},"addDirective"),qo=p((e=ie)=>{Tr=[],ms(e,Tr)},"reset"),D0={LAZY_LOAD_DEPRECATED:"The configuration options lazyLoadedDiagrams and loadExternalDiagramsAtStartup are deprecated. Please use registerExternalDiagrams instead.",FLOWCHART_HTML_LABELS_DEPRECATED:"flowchart.htmlLabels is deprecated. Please use global htmlLabels instead."},ih={},Rc=p(e=>{ih[e]||(q.warn(D0[e]),ih[e]=!0)},"issueWarning"),Nc=p(e=>{e&&(e.lazyLoadedDiagrams||e.loadExternalDiagramsAtStartup)&&Rc("LAZY_LOAD_DEPRECATED")},"checkConfig"),kL=p(()=>{let e={};No&&(e=Dt(e,No));for(const t of Tr)e=Dt(e,t);return e},"getUserDefinedConfig"),ee=p(e=>(e.flowchart?.htmlLabels!=null&&Rc("FLOWCHART_HTML_LABELS_DEPRECATED"),Ie(e.htmlLabels??e.flowchart?.htmlLabels??!0)),"getEffectiveHtmlLabels"),qc=/^([^\S\n\r]*)-{3}\s*[\n\r](.*?)[\n\r]\1-{3}\s*[\n\r]+/s,$i=/%{2}{\s*(?:(\w+)\s*:|(\w+))\s*(?:(\w+)|((?:(?!}%{2}).|\r?\n)*))?\s*(?:}%{2})?/gi,P0=/\s*%%.*\n/gm,Wc=class extends Error{static{p(this,"UnknownDiagramError")}constructor(e){super(e),this.name="UnknownDiagramError"}},Sr={},xn=p(function(e,t){e=e.replace(qc,"").replace($i,"").replace(P0,` `);for(const[r,{detector:i}]of Object.entries(Sr))if(i(e,t))return r;throw new Wc(`No diagram type detected matching given configuration for text: ${e}`)},"detectType"),ba=p((...e)=>{for(const{id:t,detector:r,loader:i}of e)zc(t,r,i)},"registerLazyLoadedDiagrams"),zc=p((e,t,r)=>{Sr[e]&&q.warn(`Detector with key ${e} already exists. Overwriting.`),Sr[e]={detector:t,loader:r},q.debug(`Detector with key ${e} added${r?" with loader":""}`)},"addDetector"),R0=p(e=>Sr[e].loader,"getDiagramLoader"),Vi=/<br\s*\/?>/gi,N0=p(e=>e?Uc(e).replace(/\\n/g,"#br#").split("#br#"):[""],"getRows"),q0=(()=>{let e=!1;return()=>{e||(Hc(),e=!0)}})();function Hc(){const e="data-temp-href-target";Kr.addHook("beforeSanitizeAttributes",t=>{t.tagName==="A"&&t.hasAttribute("target")&&t.setAttribute(e,t.getAttribute("target")??"")}),Kr.addHook("afterSanitizeAttributes",t=>{t.tagName==="A"&&t.hasAttribute(e)&&(t.setAttribute("target",t.getAttribute(e)??""),t.removeAttribute(e),t.getAttribute("target")==="_blank"&&t.setAttribute("rel","noopener"))})}p(Hc,"setupDompurifyHooks");var Yc=p(e=>(q0(),Kr.sanitize(e)),"removeScript"),oh=p((e,t)=>{if(ee(t)){const r=t.securityLevel;r==="antiscript"||r==="strict"||r==="sandbox"?e=Yc(e):r!=="loose"&&(e=Uc(e),e=e.replace(/</g,"<").replace(/>/g,">"),e=e.replace(/=/g,"="),e=Y0(e))}return e},"sanitizeMore"),be=p((e,t)=>e&&(t.dompurifyConfig?e=Kr.sanitize(oh(e,t),t.dompurifyConfig).toString():e=Kr.sanitize(oh(e,t),{FORBID_TAGS:["style"]}).toString(),e),"sanitizeText"),W0=p((e,t)=>typeof e=="string"?be(e,t):e.flat().map(r=>be(r,t)),"sanitizeTextOrArray"),z0=p(e=>Vi.test(e),"hasBreaks"),H0=p(e=>e.split(Vi),"splitBreaks"),Y0=p(e=>e.replace(/#br#/g,"<br/>"),"placeholderToBreak"),Uc=p(e=>e.replace(Vi,"#br#"),"breakToPlaceholder"),U0=p(e=>{let t="";return e&&(t=window.location.protocol+"//"+window.location.host+window.location.pathname+window.location.search,t=CSS.escape(t)),t},"getUrl"),j0=p(function(...e){const t=e.filter(r=>!isNaN(r));return Math.max(...t)},"getMax"),G0=p(function(...e){const t=e.filter(r=>!isNaN(r));return Math.min(...t)},"getMin"),sh=p(function(e){const t=e.split(/(,)/),r=[];for(let i=0;i<t.length;i++){let o=t[i];if(o===","&&i>0&&i+1<t.length){const s=t[i-1],a=t[i+1];X0(s,a)&&(o=s+","+a,i++,r.pop())}r.push(V0(o))}return r.join("")},"parseGenericTypes"),ka=p((e,t)=>Math.max(0,e.split(t).length-1),"countOccurrence"),X0=p((e,t)=>{const r=ka(e,"~"),i=ka(t,"~");return r===1&&i===1},"shouldCombineSets"),V0=p(e=>{const t=ka(e,"~");let r=!1;if(t<=1)return e;t%2!==0&&e.startsWith("~")&&(e=e.substring(1),r=!0);const i=[...e];let o=i.indexOf("~"),s=i.lastIndexOf("~");for(;o!==-1&&s!==-1&&o!==s;)i[o]="<",i[s]=">",o=i.indexOf("~"),s=i.lastIndexOf("~");return r&&i.unshift("~"),i.join("")},"processSet"),ah=p(()=>window.MathMLElement!==void 0,"isMathMLSupported"),wa=/\$\$(.*?)\$\$/g,Pi=p(e=>(e.match(wa)?.length??0)>0,"hasKatex"),wL=p(async(e,t)=>{const r=document.createElement("div");r.innerHTML=await jc(e,t),r.id="katex-temp",r.style.visibility="hidden",r.style.position="absolute",r.style.top="0",document.querySelector("body")?.insertAdjacentElement("beforeend",r);const o={width:r.clientWidth,height:r.clientHeight};return r.remove(),o},"calculateMathMLDimensions"),Z0=p(async(e,t)=>{if(!Pi(e))return e;if(!(ah()||t.legacyMathML||t.forceLegacyMathML))return e.replace(wa,"MathML is unsupported in this environment.");{const{default:r}=await nt(async()=>{const{default:o}=await import("./katex-HP8lGamR.js");return{default:o}},[]),i=t.forceLegacyMathML||!ah()&&t.legacyMathML?"htmlAndMathml":"mathml";return e.split(Vi).map(o=>Pi(o)?`<div style="display: flex; align-items: center; justify-content: center; white-space: nowrap;">${o}</div>`:`<div>${o}</div>`).join("").replace(wa,(o,s)=>r.renderToString(s,{throwOnError:!0,displayMode:!0,output:i}).replace(/\n/g," ").replace(/<annotation.*<\/annotation>/g,""))}},"renderKatexUnsanitized"),jc=p(async(e,t)=>be(await Z0(e,t),t),"renderKatexSanitized"),Zi={getRows:N0,sanitizeText:be,sanitizeTextOrArray:W0,hasBreaks:z0,splitBreaks:H0,lineBreakRegex:Vi,removeScript:Yc,getUrl:U0,evaluate:Ie,getMax:j0,getMin:G0},K0=p(function(e,t){for(let r of t)e.attr(r[0],r[1])},"d3Attrs"),Q0=p(function(e,t,r){let i=new Map;return r?(i.set("width","100%"),i.set("style",`max-width: ${t}px;`)):(i.set("height",e),i.set("width",t)),i},"calculateSvgSizeAttrs"),Gc=p(function(e,t,r,i){const o=Q0(t,r,i);K0(e,o)},"configureSvgSize"),J0=p(function(e,t,r,i){const o=t.node().getBBox(),s=o.width,a=o.height;q.info(`SVG bounds: ${s}x${a}`,o);let n=0,l=0;q.info(`Graph bounds: ${n}x${l}`,e),n=s+r*2,l=a+r*2,q.info(`Calculated bounds: ${n}x${l}`),Gc(t,l,n,i);const c=`${o.x-r} ${o.y-r} ${o.width+2*r} ${o.height+2*r}`;t.attr("viewBox",c)},"setupGraphViewbox"),Bo={};function Ta(e){return[...e.cssRules].map(t=>t.cssText).join(` @@ -300,8 +300,8 @@ Please report this to https://github.com/markedjs/marked.`,t){let o="<p>An error L0,20`)},"requirement_arrow"),LS=p((e,t,r)=>{const i=vt(),{themeVariables:o}=i,{strokeWidth:s}=o;e.append("defs").append("marker").attr("id",r+"_"+t+"-requirement_arrowEnd").attr("refX",20).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").attr("markerUnits","userSpaceOnUse").attr("stroke-width",`${s}`).attr("viewBox","0 0 25 20").append("path").attr("d",`M0,0 L20,10 M20,10 - L0,20`).attr("stroke-linejoin","miter")},"requirement_arrow_neo"),FS=p((e,t,r)=>{const i=e.append("defs").append("marker").attr("id",r+"_"+t+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");i.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),i.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),i.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains"),AS=p((e,t,r)=>{const i=vt(),{themeVariables:o}=i,{strokeWidth:s}=o,a=e.append("defs").append("marker").attr("id",r+"_"+t+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").attr("markerUnits","userSpaceOnUse").append("g");a.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),a.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),a.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10),a.selectAll("*").attr("stroke-width",`${s}`)},"requirement_contains_neo"),ES={extension:hS,composition:cS,aggregation:dS,dependency:uS,lollipop:fS,point:pS,circle:gS,cross:mS,barb:yS,barbNeo:CS,only_one:xS,zero_or_one:bS,one_or_more:kS,zero_or_more:wS,only_one_neo:TS,zero_or_one_neo:SS,one_or_more_neo:_S,zero_or_more_neo:BS,requirement_arrow:vS,requirement_contains:FS,requirement_arrow_neo:LS,requirement_contains_neo:AS},MS=lS,$S={common:Zi,getConfig:vt,insertCluster:LT,insertEdge:nS,insertEdgeLabel:tS,insertMarkers:MS,insertNode:Hg,interpolateToCurve:Vn,labelHelper:it,log:q,positionEdgeLabel:eS},Gi={},Gg=p(e=>{for(const t of e)Gi[t.name]=t},"registerLayoutLoaders"),OS=p(()=>{Gg([{name:"dagre",loader:p(async()=>await nt(()=>import("./dagre-VKFMJZFB-BV_7O_eU.js"),__vite__mapDeps([0,1,2,3,4,5,6,7])),"loader")},{name:"swimlane",loader:p(async()=>await nt(()=>import("./swimlanes-5IMT3BWC-C4tzl2F_.js"),__vite__mapDeps([8,5,6,1,2,3,7])),"loader")},{name:"cose-bilkent",loader:p(async()=>await nt(()=>import("./cose-bilkent-JH36ORCC-CDDliH5o.js"),__vite__mapDeps([9,10,7,5,6])),"loader")}])},"registerDefaultLayoutLoaders");OS();var GL=p(async(e,t,r)=>{if(!(e.layoutAlgorithm in Gi))throw new Error(`Unknown layout algorithm: ${e.layoutAlgorithm}`);if(e.diagramId)for(const d of e.nodes){const f=d.domId||d.id;d.domId=`${e.diagramId}-${f}`}const i=Gi[e.layoutAlgorithm],o=await i.loader(),{theme:s,themeVariables:a}=e.config,{useGradient:n,gradientStart:l,gradientStop:c}=a,h=t.attr("id");if(t.append("defs").append("filter").attr("id",`${h}-drop-shadow`).attr("height","130%").attr("width","130%").append("feDropShadow").attr("dx","4").attr("dy","4").attr("stdDeviation",0).attr("flood-opacity","0.06").attr("flood-color",`${s?.includes("dark")?"#FFFFFF":"#000000"}`),t.append("defs").append("filter").attr("id",`${h}-drop-shadow-small`).attr("height","150%").attr("width","150%").append("feDropShadow").attr("dx","2").attr("dy","2").attr("stdDeviation",0).attr("flood-opacity","0.06").attr("flood-color",`${s?.includes("dark")?"#FFFFFF":"#000000"}`),n){const d=t.append("linearGradient").attr("id",t.attr("id")+"-gradient").attr("gradientUnits","objectBoundingBox").attr("x1","0%").attr("y1","0%").attr("x2","100%").attr("y2","0%");d.append("svg:stop").attr("offset","0%").attr("stop-color",l).attr("stop-opacity",1),d.append("svg:stop").attr("offset","100%").attr("stop-color",c).attr("stop-opacity",1)}return o.render(e,t,$S,{algorithm:i.algorithm},r)},"render"),XL=p((e="",{fallback:t="dagre"}={})=>{if(e in Gi)return e;if(t in Gi)return q.warn(`Layout algorithm ${e} is not registered. Using ${t} as fallback.`),t;throw new Error(`Both layout algorithms ${e} and ${t} are not registered.`)},"getRegisteredLayoutAlgorithm"),ml="comm",Xg="rule",Vg="decl",IS="@media",DS="@import",PS="@supports",RS="@namespace",un="@keyframes",Zg="@layer",NS="@scope",qS=Math.abs,Di=String.fromCharCode;function Kg(e){return e.trim()}function fn(e,t,r){return e.replace(t,r)}function Zr(e,t){return e.charCodeAt(t)|0}function ii(e,t,r){return e.slice(t,r)}function Fe(e){return e.length}function Qg(e){return e.length}function To(e,t){return t.push(e),e}var Es=1,oi=1,Jg=0,ce=0,$t=0,ni="";function yl(e,t,r,i,o,s,a,n){return{value:e,root:t,parent:r,type:i,props:o,children:s,line:Es,column:oi,length:a,return:"",siblings:n}}function WS(){return $t}function zS(){return $t=ce>0?Zr(ni,--ce):0,oi--,$t===10&&(oi=1,Es--),$t}function xe(){return $t=ce<Jg?Zr(ni,ce++):0,oi++,$t===10&&(oi=1,Es++),$t}function ir(){return Zr(ni,ce)}function Do(){return ce}function Ms(e,t){return ii(ni,e,t)}function Xi(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function HS(e){return Es=oi=1,Jg=Fe(ni=e),ce=0,[]}function YS(e){return ni="",e}function ga(e){return Kg(Ms(ce-1,pn(e===91?e+2:e===40?e+1:e)))}function US(e){for(;($t=ir())&&$t<33;)xe();return Xi(e)>2||Xi($t)>3?"":" "}function jS(e,t){for(;--t&&xe()&&!($t<48||$t>102||$t>57&&$t<65||$t>70&&$t<97););return Ms(e,Do()+(t<6&&ir()==32&&xe()==32))}function pn(e){for(;xe();)switch($t){case e:return ce;case 34:case 39:e!==34&&e!==39&&pn($t);break;case 40:e===41&&pn(e);break;case 92:xe();break}return ce}function GS(e,t){for(;xe()&&e+$t!==57;)if(e+$t===84&&ir()===47)break;return"/*"+Ms(t,ce-1)+"*"+Di(e===47?e:xe())}function XS(e){for(;!Xi(ir());)xe();return Ms(e,ce)}function VS(e){return YS(Po("",null,null,null,[""],e=HS(e),0,[0],e))}function Po(e,t,r,i,o,s,a,n,l){for(var c=0,h=0,d=a,f=0,u=0,g=0,m=1,y=1,C=1,b=0,k=0,T="",S=o,_=s,L=i,v=T;y;)switch(g=k,k=xe()){case 40:g!=108&&Zr(v,d-1)==58?(b++,v+="("):v+=ga(k);break;case 41:b--,v+=")";break;case 34:case 39:case 91:v+=ga(k);break;case 9:case 10:case 13:case 32:if(b>0){v+=Di(k);break}v+=US(g);break;case 92:v+=jS(Do()-1,7);continue;case 47:switch(ir()){case 42:case 47:To(ZS(GS(xe(),Do()),t,r,l),l),(Xi(g||1)==5||Xi(ir()||1)==5)&&Fe(v)&&ii(v,-1,void 0)!==" "&&(v+=" ");break;default:v+="/"}break;case 123*m:n[c++]=Fe(v)*C;case 125*m:case 59:case 0:if(b>0&&k){v+=Di(k);break}switch(k){case 0:case 125:y=0;case 59+h:C==-1&&(v=fn(v,/\f/g,"")),u>0&&(Fe(v)-d||m===0)&&To(u>32?bc(v+";",i,r,d-1,l):bc(fn(v," ","")+";",i,r,d-2,l),l);break;case 59:v+=";";default:if(To(L=xc(v,t,r,c,h,o,n,T,S=[],_=[],d,s),s),k===123)if(h===0)Po(v,t,L,L,S,s,d,n,_);else{switch(f){case 99:if(Zr(v,3)===110)break;case 108:if(Zr(v,2)===97)break;default:h=0;case 100:case 109:case 115:}h?Po(e,L,L,i&&To(xc(e,L,L,0,0,o,n,T,o,S=[],d,_),_),o,_,d,n,i?S:_):Po(v,L,L,L,[""],_,0,n,_)}}c=h=u=0,m=C=1,T=v="",d=a;break;case 58:d=1+Fe(v),u=g;default:if(m<1){if(k==123)--m;else if(k==125&&m++==0&&zS()==125)continue}switch(v+=Di(k),k*m){case 38:C=h>0?1:(v+="\f",-1);break;case 44:if(b>0)break;n[c++]=(Fe(v)-1)*C,C=1;break;case 64:ir()===45&&(v+=ga(xe())),f=ir(),h=d=Fe(T=v+=XS(Do())),k++;break;case 45:g===45&&Fe(v)==2&&(m=0)}}return s}function xc(e,t,r,i,o,s,a,n,l,c,h,d){for(var f=o-1,u=o===0?s:[""],g=Qg(u),m=0,y=0,C=0;m<i;++m)for(var b=0,k=ii(e,f+1,f=qS(y=a[m])),T=e;b<g;++b)(T=Kg(y>0?u[b]+" "+k:fn(k,/&\f/g,u[b])))&&(l[C++]=T);return yl(e,t,r,o===0?Xg:n,l,c,h,d)}function ZS(e,t,r,i){return yl(e,t,r,ml,Di(WS()),ii(e,2,-2),0,i)}function bc(e,t,r,i,o){return yl(e,t,r,Vg,ii(e,0,i),ii(e,i+1,-1),i,o)}function gn(e,t){for(var r="",i=0;i<e.length;i++)r+=t(e[i],i,e,t)||"";return r}function KS(e,t,r,i){switch(e.type){case Zg:if(e.children.length)break;case DS:case RS:case Vg:return e.return=e.return||e.value;case ml:return"";case un:return e.return=e.value+"{"+gn(e.children,i)+"}";case Xg:if(!Fe(e.value=e.props.join(",")))return""}return Fe(r=gn(e.children,i))?e.return=e.value+"{"+r+"}":""}function QS(e){var t=Qg(e);return function(r,i,o,s){for(var a="",n=0;n<t;n++)a+=e[n](r,i,o,s)||"";return a}}var tm="c4",JS=p(e=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(e),"detector"),t_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./c4Diagram-LMCZKHZV-CuD9sHro.js");return{diagram:t}},__vite__mapDeps([11,12,5,6,7]));return{id:tm,diagram:e}},"loader"),e_={id:tm,detector:JS,loader:t_},r_=e_,em="flowchart",i_=p((e,t)=>t?.flowchart?.defaultRenderer==="dagre-wrapper"||t?.flowchart?.defaultRenderer==="elk"?!1:/^\s*graph/.test(e),"detector"),o_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-D0EBISGr.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:em,diagram:e}},"loader"),s_={id:em,detector:i_,loader:o_},a_=s_,rm="flowchart-v2",n_=p((e,t)=>t?.flowchart?.defaultRenderer==="dagre-d3"?!1:(t?.flowchart?.defaultRenderer==="elk"&&(t.layout="elk"),/^\s*graph/.test(e)&&t?.flowchart?.defaultRenderer==="dagre-wrapper"?!0:/^\s*flowchart/.test(e)),"detector"),l_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-D0EBISGr.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:rm,diagram:e}},"loader"),h_={id:rm,detector:n_,loader:l_},c_=h_,im="swimlane",d_=p(e=>/^\s*swimlane-beta\b/.test(e),"detector"),u_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./swimlanesDiagram-G3AALYLV-DU8WMkqz.js");return{diagram:t}},__vite__mapDeps([18,13,14,15,16,12,17,5,6,7]));return{id:im,diagram:e}},"loader"),f_={id:im,detector:d_,loader:u_},p_=f_,om="er",g_=p(e=>/^\s*erDiagram/.test(e),"detector"),m_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./erDiagram-Q63AITRT-xK3dRTZk.js");return{diagram:t}},__vite__mapDeps([19,15,16,17,5,6,7]));return{id:om,diagram:e}},"loader"),y_={id:om,detector:g_,loader:m_},C_=y_,sm="gitGraph",x_=p(e=>/^\s*gitGraph/.test(e),"detector"),b_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./gitGraphDiagram-IHSO6WYX-DaTSF-Bh.js");return{diagram:t}},__vite__mapDeps([20,21,22,23,5,6,7]));return{id:sm,diagram:e}},"loader"),k_={id:sm,detector:x_,loader:b_},w_=k_,am="gantt",T_=p(e=>/^\s*gantt/.test(e),"detector"),S_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ganttDiagram-NO4QXBWP-IslzQD84.js");return{diagram:t}},__vite__mapDeps([24,7,25,26,27,5,6]));return{id:am,diagram:e}},"loader"),__={id:am,detector:T_,loader:S_},B_=__,nm="info",v_=p(e=>/^\s*info/.test(e),"detector"),L_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./infoDiagram-FWYZ7A6U-YBdL8hE1.js");return{diagram:t}},__vite__mapDeps([28,23,5,6,7]));return{id:nm,diagram:e}},"loader"),F_={id:nm,detector:v_,loader:L_},lm="pie",A_=p(e=>/^\s*pie/.test(e),"detector"),E_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./pieDiagram-ENE6RG2P-5Ehl6T8C.js");return{diagram:t}},__vite__mapDeps([29,22,23,5,6,30,31,26,7]));return{id:lm,diagram:e}},"loader"),M_={id:lm,detector:A_,loader:E_},hm="quadrantChart",$_=p(e=>/^\s*quadrantChart/.test(e),"detector"),O_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./quadrantDiagram-ABIIQ3AL-8vMHBPBY.js");return{diagram:t}},__vite__mapDeps([32,25,26,27,5,6,7]));return{id:hm,diagram:e}},"loader"),I_={id:hm,detector:$_,loader:O_},D_=I_,cm="xychart",P_=p(e=>/^\s*xychart(-beta)?/.test(e),"detector"),R_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./xychartDiagram-FW5EYKEG-Bg0qevEv.js");return{diagram:t}},__vite__mapDeps([33,26,31,25,27,5,6,7]));return{id:cm,diagram:e}},"loader"),N_={id:cm,detector:P_,loader:R_},q_=N_,dm="requirement",W_=p(e=>/^\s*requirement(Diagram)?/.test(e),"detector"),z_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./requirementDiagram-TGXJPOKE-B8hGppVZ.js");return{diagram:t}},__vite__mapDeps([34,15,16,5,6,7]));return{id:dm,diagram:e}},"loader"),H_={id:dm,detector:W_,loader:z_},Y_=H_,um="sequence",U_=p(e=>/^\s*sequenceDiagram/.test(e),"detector"),j_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./sequenceDiagram-DBY2YBRQ-B2h-6vZ7.js");return{diagram:t}},__vite__mapDeps([35,21,12,5,6,7]));return{id:um,diagram:e}},"loader"),G_={id:um,detector:U_,loader:j_},X_=G_,fm="class",V_=p((e,t)=>t?.class?.defaultRenderer==="dagre-wrapper"?!1:/^\s*classDiagram/.test(e),"detector"),Z_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./classDiagram-OUVF2IWQ-DPiTyikT.js");return{diagram:t}},__vite__mapDeps([36,37,14,15,16,12,5,6,7]));return{id:fm,diagram:e}},"loader"),K_={id:fm,detector:V_,loader:Z_},Q_=K_,pm="classDiagram",J_=p((e,t)=>/^\s*classDiagram/.test(e)&&t?.class?.defaultRenderer==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(e),"detector"),tB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./classDiagram-v2-EOCWNBFH-DPiTyikT.js");return{diagram:t}},__vite__mapDeps([38,37,14,15,16,12,5,6,7]));return{id:pm,diagram:e}},"loader"),eB={id:pm,detector:J_,loader:tB},rB=eB,gm="state",iB=p((e,t)=>t?.state?.defaultRenderer==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(e),"detector"),oB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./stateDiagram-2N3HPSRC-ha3u0dwu.js");return{diagram:t}},__vite__mapDeps([39,40,15,16,12,2,4,3,5,6,7]));return{id:gm,diagram:e}},"loader"),sB={id:gm,detector:iB,loader:oB},aB=sB,mm="stateDiagram",nB=p((e,t)=>!!(/^\s*stateDiagram-v2/.test(e)||/^\s*stateDiagram/.test(e)&&t?.state?.defaultRenderer==="dagre-wrapper"),"detector"),lB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./stateDiagram-v2-6OUMAXLB-B_OpM2in.js");return{diagram:t}},__vite__mapDeps([41,40,15,16,12,5,6,7]));return{id:mm,diagram:e}},"loader"),hB={id:mm,detector:nB,loader:lB},cB=hB,ym="journey",dB=p(e=>/^\s*journey/.test(e),"detector"),uB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./journeyDiagram-5HDEW3XC-DHq-P2j9.js");return{diagram:t}},__vite__mapDeps([42,14,12,30,5,6,7]));return{id:ym,diagram:e}},"loader"),fB={id:ym,detector:dB,loader:uB},pB=fB,gB=p((e,t,r)=>{q.debug(`rendering svg for syntax error -`);const i=Yk(t),o=i.append("g");i.attr("viewBox","0 0 2412 512"),Gc(i,100,512,!0),o.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),o.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),o.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),o.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),o.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),o.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),o.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),o.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw"),Cm={draw:gB},mB=Cm,yB={db:{},renderer:Cm,parser:{parse:p(()=>{},"parse")}},CB=yB,xm="flowchart-elk",xB=p((e,t={})=>/^\s*flowchart-elk/.test(e)||/^\s*(flowchart|graph)/.test(e)&&t?.flowchart?.defaultRenderer==="elk"?(t.layout="elk",!0):!1,"detector"),bB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-D0EBISGr.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:xm,diagram:e}},"loader"),kB={id:xm,detector:xB,loader:bB},wB=kB,bm="timeline",TB=p(e=>/^\s*timeline/.test(e),"detector"),SB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./timeline-definition-FHXFAJF6-CV7TbRUK.js");return{diagram:t}},__vite__mapDeps([43,30,5,6,7]));return{id:bm,diagram:e}},"loader"),_B={id:bm,detector:TB,loader:SB},BB=_B,km="mindmap",vB=p(e=>/^\s*mindmap/.test(e),"detector"),LB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./mindmap-definition-LN4V7U3C-WAq6xftS.js");return{diagram:t}},__vite__mapDeps([44,15,16,5,6,7]));return{id:km,diagram:e}},"loader"),FB={id:km,detector:vB,loader:LB},AB=FB,wm="kanban",EB=p(e=>/^\s*kanban/.test(e),"detector"),MB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./kanban-definition-HUTT4EX6-C6iL68OT.js");return{diagram:t}},__vite__mapDeps([45,14,5,6,7]));return{id:wm,diagram:e}},"loader"),$B={id:wm,detector:EB,loader:MB},OB=$B,Tm="sankey",IB=p(e=>/^\s*sankey(-beta)?/.test(e),"detector"),DB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./sankeyDiagram-HTMAVEWB-BhsqMuTt.js");return{diagram:t}},__vite__mapDeps([46,31,26,5,6,7]));return{id:Tm,diagram:e}},"loader"),PB={id:Tm,detector:IB,loader:DB},RB=PB,Sm="packet",NB=p(e=>/^\s*packet(-beta)?/.test(e),"detector"),qB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-NH7WQ7WH-C09rk2Ua.js");return{diagram:t}},__vite__mapDeps([47,22,23,5,6,7]));return{id:Sm,diagram:e}},"loader"),WB={id:Sm,detector:NB,loader:qB},_m="radar",zB=p(e=>/^\s*radar-beta/.test(e),"detector"),HB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-WEI45ONY-DRhsbaVI.js");return{diagram:t}},__vite__mapDeps([48,22,23,5,6,7]));return{id:_m,diagram:e}},"loader"),YB={id:_m,detector:zB,loader:HB},Bm="block",UB=p(e=>/^\s*block(-beta)?/.test(e),"detector"),jB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./blockDiagram-677ZJIJ3-DMGXLKk2.js");return{diagram:t}},__vite__mapDeps([49,14,2,17,5,6,7]));return{id:Bm,diagram:e}},"loader"),GB={id:Bm,detector:UB,loader:jB},XB=GB,vm="treeView",VB=p(e=>/^\s*treeView-beta/.test(e),"detector"),ZB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-OA4YK3LP-DnPyyrOM.js");return{diagram:t}},__vite__mapDeps([50,21,22,23,5,6,7]));return{id:vm,diagram:e}},"loader"),KB={id:vm,detector:VB,loader:ZB},QB=KB,Lm="architecture",JB=p(e=>/^\s*architecture/.test(e),"detector"),tv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./architectureDiagram-ZJ3FMSHR-BkXVAeQG.js");return{diagram:t}},__vite__mapDeps([51,22,23,5,6,10,7]));return{id:Lm,diagram:e}},"loader"),ev={id:Lm,detector:JB,loader:tv},rv=ev,Fm="eventmodeling",iv=p(e=>/^\s*eventmodeling/.test(e),"detector"),ov=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-FQU43EPY-C_ItQEVf.js");return{diagram:t}},__vite__mapDeps([52,22,23,5,6,7]));return{id:Fm,diagram:e}},"loader"),sv={id:Fm,detector:iv,loader:ov},av=sv,Am="ishikawa",nv=p(e=>/^\s*ishikawa(-beta)?\b/i.test(e),"detector"),lv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ishikawaDiagram-FXEZZL3T-CJxOHefD.js");return{diagram:t}},__vite__mapDeps([53,5,6,7]));return{id:Am,diagram:e}},"loader"),hv={id:Am,detector:nv,loader:lv},Em="venn",cv=p(e=>/^\s*venn-beta/.test(e),"detector"),dv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./vennDiagram-L72KCM5P-BNRmZgGU.js");return{diagram:t}},__vite__mapDeps([54,5,6,7]));return{id:Em,diagram:e}},"loader"),uv={id:Em,detector:cv,loader:dv},fv=uv,Mm="treemap",pv=p(e=>/^\s*treemap/.test(e),"detector"),gv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-G47NLZAW-Cm4DutfF.js");return{diagram:t}},__vite__mapDeps([55,22,16,23,5,6,27,31,26,7]));return{id:Mm,diagram:e}},"loader"),mv={id:Mm,detector:pv,loader:gv},$m="wardley",yv=p(e=>/^\s*wardley-beta/i.test(e),"detector"),Cv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./wardleyDiagram-EHGQE667-DVjnwE-A.js");return{diagram:t}},__vite__mapDeps([56,22,23,5,6,7]));return{id:$m,diagram:e}},"loader"),xv={id:$m,detector:yv,loader:Cv},bv=xv,Om="cynefin",kv=p(e=>/^\s*cynefin-beta(?:[\s:]|$)/.test(e),"detector"),wv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./cynefinDiagram-TSTJHNR4-CSvOhRTt.js");return{diagram:t}},__vite__mapDeps([57,22,23,5,6,7]));return{id:Om,diagram:e}},"loader"),Tv={id:Om,detector:kv,loader:wv},Im="railroad",Sv=p(e=>/^\s*railroad-beta/i.test(e),"detector"),_v=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./railroadDiagram-RFXS5EU6-BBlgCMW5.js");return{diagram:t}},__vite__mapDeps([58,59,22,23,5,6,7]));return{id:Im,diagram:e}},"loader"),Bv={id:Im,detector:Sv,loader:_v},Dm="railroadEbnf",vv=p(e=>/^\s*railroad-ebnf-beta/i.test(e),"detector"),Lv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ebnfDiagram-CCIWWBDH-C6JPA7C_.js");return{diagram:t}},__vite__mapDeps([60,59,22,23,5,6,7]));return{id:Dm,diagram:e}},"loader"),Fv={id:Dm,detector:vv,loader:Lv},Pm="railroadAbnf",Av=p(e=>/^\s*railroad-abnf-beta/i.test(e),"detector"),Ev=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./abnfDiagram-VRR7QNED-BXPcW32X.js");return{diagram:t}},__vite__mapDeps([61,59,22,23,5,6,7]));return{id:Pm,diagram:e}},"loader"),Mv={id:Pm,detector:Av,loader:Ev},Rm="railroadPeg",$v=p(e=>/^\s*railroad-peg-beta/i.test(e),"detector"),Ov=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./pegDiagram-2B236MQR-C7Ks7P9i.js");return{diagram:t}},__vite__mapDeps([62,59,22,23,5,6,7]));return{id:Rm,diagram:e}},"loader"),Iv={id:Rm,detector:$v,loader:Ov},kc=!1,$s=p(()=>{kc||(kc=!0,zo("error",CB,e=>e.toLowerCase().trim()==="error"),zo("---",{db:{clear:p(()=>{},"clear")},styles:{},renderer:{draw:p(()=>{},"draw")},parser:{parse:p(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:p(()=>null,"init")},e=>e.toLowerCase().trimStart().startsWith("---")),ba(wB,AB,rv),ba(r_,OB,rB,Q_,C_,B_,F_,M_,Y_,X_,p_,c_,a_,BB,w_,cB,aB,pB,D_,RB,WB,q_,XB,av,QB,YB,hv,mv,Bv,Fv,Mv,Iv,fv,bv,Tv))},"addDiagrams"),Dv=p(async()=>{q.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(Sr).map(async([r,{detector:i,loader:o}])=>{if(o)try{Sa(r)}catch{try{const{diagram:s,id:a}=await o();zo(a,s,i)}catch(s){throw q.error(`Failed to load external diagram with key ${r}. Removing from detectors.`),delete Sr[r],s}}}))).filter(r=>r.status==="rejected");if(t.length>0){q.error(`Failed to load ${t.length} external diagrams`);for(const r of t)q.error(r);throw new Error(`Failed to load ${t.length} external diagrams`)}},"loadRegisteredDiagrams"),Pv="graphics-document document";function Nm(e,t){e.attr("role",Pv),t!==""&&e.attr("aria-roledescription",t)}p(Nm,"setA11yDiagramInfo");function qm(e,t,r,i){if(e.insert!==void 0){if(r){const o=`chart-desc-${i}`;e.attr("aria-describedby",o),e.insert("desc",":first-child").attr("id",o).text(r)}if(t){const o=`chart-title-${i}`;e.attr("aria-labelledby",o),e.insert("title",":first-child").attr("id",o).text(t)}}}p(qm,"addSVGa11yTitleDescription");var mn=class Wm{constructor(t,r,i,o,s){this.type=t,this.text=r,this.db=i,this.parser=o,this.renderer=s}static{p(this,"Diagram")}static async fromText(t,r={}){const i=vt(),o=xn(t,i);t=Z2(t)+` + L0,20`).attr("stroke-linejoin","miter")},"requirement_arrow_neo"),FS=p((e,t,r)=>{const i=e.append("defs").append("marker").attr("id",r+"_"+t+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").append("g");i.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),i.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),i.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10)},"requirement_contains"),AS=p((e,t,r)=>{const i=vt(),{themeVariables:o}=i,{strokeWidth:s}=o,a=e.append("defs").append("marker").attr("id",r+"_"+t+"-requirement_containsStart").attr("refX",0).attr("refY",10).attr("markerWidth",20).attr("markerHeight",20).attr("orient","auto").attr("markerUnits","userSpaceOnUse").append("g");a.append("circle").attr("cx",10).attr("cy",10).attr("r",9).attr("fill","none"),a.append("line").attr("x1",1).attr("x2",19).attr("y1",10).attr("y2",10),a.append("line").attr("y1",1).attr("y2",19).attr("x1",10).attr("x2",10),a.selectAll("*").attr("stroke-width",`${s}`)},"requirement_contains_neo"),ES={extension:hS,composition:cS,aggregation:dS,dependency:uS,lollipop:fS,point:pS,circle:gS,cross:mS,barb:yS,barbNeo:CS,only_one:xS,zero_or_one:bS,one_or_more:kS,zero_or_more:wS,only_one_neo:TS,zero_or_one_neo:SS,one_or_more_neo:_S,zero_or_more_neo:BS,requirement_arrow:vS,requirement_contains:FS,requirement_arrow_neo:LS,requirement_contains_neo:AS},MS=lS,$S={common:Zi,getConfig:vt,insertCluster:LT,insertEdge:nS,insertEdgeLabel:tS,insertMarkers:MS,insertNode:Hg,interpolateToCurve:Vn,labelHelper:it,log:q,positionEdgeLabel:eS},Gi={},Gg=p(e=>{for(const t of e)Gi[t.name]=t},"registerLayoutLoaders"),OS=p(()=>{Gg([{name:"dagre",loader:p(async()=>await nt(()=>import("./dagre-VKFMJZFB-D8gdq5tS.js"),__vite__mapDeps([0,1,2,3,4,5,6,7])),"loader")},{name:"swimlane",loader:p(async()=>await nt(()=>import("./swimlanes-5IMT3BWC-D6xMtJ1E.js"),__vite__mapDeps([8,5,6,1,2,3,7])),"loader")},{name:"cose-bilkent",loader:p(async()=>await nt(()=>import("./cose-bilkent-JH36ORCC-TWQPJk-P.js"),__vite__mapDeps([9,10,7,5,6])),"loader")}])},"registerDefaultLayoutLoaders");OS();var GL=p(async(e,t,r)=>{if(!(e.layoutAlgorithm in Gi))throw new Error(`Unknown layout algorithm: ${e.layoutAlgorithm}`);if(e.diagramId)for(const d of e.nodes){const f=d.domId||d.id;d.domId=`${e.diagramId}-${f}`}const i=Gi[e.layoutAlgorithm],o=await i.loader(),{theme:s,themeVariables:a}=e.config,{useGradient:n,gradientStart:l,gradientStop:c}=a,h=t.attr("id");if(t.append("defs").append("filter").attr("id",`${h}-drop-shadow`).attr("height","130%").attr("width","130%").append("feDropShadow").attr("dx","4").attr("dy","4").attr("stdDeviation",0).attr("flood-opacity","0.06").attr("flood-color",`${s?.includes("dark")?"#FFFFFF":"#000000"}`),t.append("defs").append("filter").attr("id",`${h}-drop-shadow-small`).attr("height","150%").attr("width","150%").append("feDropShadow").attr("dx","2").attr("dy","2").attr("stdDeviation",0).attr("flood-opacity","0.06").attr("flood-color",`${s?.includes("dark")?"#FFFFFF":"#000000"}`),n){const d=t.append("linearGradient").attr("id",t.attr("id")+"-gradient").attr("gradientUnits","objectBoundingBox").attr("x1","0%").attr("y1","0%").attr("x2","100%").attr("y2","0%");d.append("svg:stop").attr("offset","0%").attr("stop-color",l).attr("stop-opacity",1),d.append("svg:stop").attr("offset","100%").attr("stop-color",c).attr("stop-opacity",1)}return o.render(e,t,$S,{algorithm:i.algorithm},r)},"render"),XL=p((e="",{fallback:t="dagre"}={})=>{if(e in Gi)return e;if(t in Gi)return q.warn(`Layout algorithm ${e} is not registered. Using ${t} as fallback.`),t;throw new Error(`Both layout algorithms ${e} and ${t} are not registered.`)},"getRegisteredLayoutAlgorithm"),ml="comm",Xg="rule",Vg="decl",IS="@media",DS="@import",PS="@supports",RS="@namespace",un="@keyframes",Zg="@layer",NS="@scope",qS=Math.abs,Di=String.fromCharCode;function Kg(e){return e.trim()}function fn(e,t,r){return e.replace(t,r)}function Zr(e,t){return e.charCodeAt(t)|0}function ii(e,t,r){return e.slice(t,r)}function Fe(e){return e.length}function Qg(e){return e.length}function To(e,t){return t.push(e),e}var Es=1,oi=1,Jg=0,ce=0,$t=0,ni="";function yl(e,t,r,i,o,s,a,n){return{value:e,root:t,parent:r,type:i,props:o,children:s,line:Es,column:oi,length:a,return:"",siblings:n}}function WS(){return $t}function zS(){return $t=ce>0?Zr(ni,--ce):0,oi--,$t===10&&(oi=1,Es--),$t}function xe(){return $t=ce<Jg?Zr(ni,ce++):0,oi++,$t===10&&(oi=1,Es++),$t}function ir(){return Zr(ni,ce)}function Do(){return ce}function Ms(e,t){return ii(ni,e,t)}function Xi(e){switch(e){case 0:case 9:case 10:case 13:case 32:return 5;case 33:case 43:case 44:case 47:case 62:case 64:case 126:case 59:case 123:case 125:return 4;case 58:return 3;case 34:case 39:case 40:case 91:return 2;case 41:case 93:return 1}return 0}function HS(e){return Es=oi=1,Jg=Fe(ni=e),ce=0,[]}function YS(e){return ni="",e}function ga(e){return Kg(Ms(ce-1,pn(e===91?e+2:e===40?e+1:e)))}function US(e){for(;($t=ir())&&$t<33;)xe();return Xi(e)>2||Xi($t)>3?"":" "}function jS(e,t){for(;--t&&xe()&&!($t<48||$t>102||$t>57&&$t<65||$t>70&&$t<97););return Ms(e,Do()+(t<6&&ir()==32&&xe()==32))}function pn(e){for(;xe();)switch($t){case e:return ce;case 34:case 39:e!==34&&e!==39&&pn($t);break;case 40:e===41&&pn(e);break;case 92:xe();break}return ce}function GS(e,t){for(;xe()&&e+$t!==57;)if(e+$t===84&&ir()===47)break;return"/*"+Ms(t,ce-1)+"*"+Di(e===47?e:xe())}function XS(e){for(;!Xi(ir());)xe();return Ms(e,ce)}function VS(e){return YS(Po("",null,null,null,[""],e=HS(e),0,[0],e))}function Po(e,t,r,i,o,s,a,n,l){for(var c=0,h=0,d=a,f=0,u=0,g=0,m=1,y=1,C=1,b=0,k=0,T="",S=o,_=s,L=i,v=T;y;)switch(g=k,k=xe()){case 40:g!=108&&Zr(v,d-1)==58?(b++,v+="("):v+=ga(k);break;case 41:b--,v+=")";break;case 34:case 39:case 91:v+=ga(k);break;case 9:case 10:case 13:case 32:if(b>0){v+=Di(k);break}v+=US(g);break;case 92:v+=jS(Do()-1,7);continue;case 47:switch(ir()){case 42:case 47:To(ZS(GS(xe(),Do()),t,r,l),l),(Xi(g||1)==5||Xi(ir()||1)==5)&&Fe(v)&&ii(v,-1,void 0)!==" "&&(v+=" ");break;default:v+="/"}break;case 123*m:n[c++]=Fe(v)*C;case 125*m:case 59:case 0:if(b>0&&k){v+=Di(k);break}switch(k){case 0:case 125:y=0;case 59+h:C==-1&&(v=fn(v,/\f/g,"")),u>0&&(Fe(v)-d||m===0)&&To(u>32?bc(v+";",i,r,d-1,l):bc(fn(v," ","")+";",i,r,d-2,l),l);break;case 59:v+=";";default:if(To(L=xc(v,t,r,c,h,o,n,T,S=[],_=[],d,s),s),k===123)if(h===0)Po(v,t,L,L,S,s,d,n,_);else{switch(f){case 99:if(Zr(v,3)===110)break;case 108:if(Zr(v,2)===97)break;default:h=0;case 100:case 109:case 115:}h?Po(e,L,L,i&&To(xc(e,L,L,0,0,o,n,T,o,S=[],d,_),_),o,_,d,n,i?S:_):Po(v,L,L,L,[""],_,0,n,_)}}c=h=u=0,m=C=1,T=v="",d=a;break;case 58:d=1+Fe(v),u=g;default:if(m<1){if(k==123)--m;else if(k==125&&m++==0&&zS()==125)continue}switch(v+=Di(k),k*m){case 38:C=h>0?1:(v+="\f",-1);break;case 44:if(b>0)break;n[c++]=(Fe(v)-1)*C,C=1;break;case 64:ir()===45&&(v+=ga(xe())),f=ir(),h=d=Fe(T=v+=XS(Do())),k++;break;case 45:g===45&&Fe(v)==2&&(m=0)}}return s}function xc(e,t,r,i,o,s,a,n,l,c,h,d){for(var f=o-1,u=o===0?s:[""],g=Qg(u),m=0,y=0,C=0;m<i;++m)for(var b=0,k=ii(e,f+1,f=qS(y=a[m])),T=e;b<g;++b)(T=Kg(y>0?u[b]+" "+k:fn(k,/&\f/g,u[b])))&&(l[C++]=T);return yl(e,t,r,o===0?Xg:n,l,c,h,d)}function ZS(e,t,r,i){return yl(e,t,r,ml,Di(WS()),ii(e,2,-2),0,i)}function bc(e,t,r,i,o){return yl(e,t,r,Vg,ii(e,0,i),ii(e,i+1,-1),i,o)}function gn(e,t){for(var r="",i=0;i<e.length;i++)r+=t(e[i],i,e,t)||"";return r}function KS(e,t,r,i){switch(e.type){case Zg:if(e.children.length)break;case DS:case RS:case Vg:return e.return=e.return||e.value;case ml:return"";case un:return e.return=e.value+"{"+gn(e.children,i)+"}";case Xg:if(!Fe(e.value=e.props.join(",")))return""}return Fe(r=gn(e.children,i))?e.return=e.value+"{"+r+"}":""}function QS(e){var t=Qg(e);return function(r,i,o,s){for(var a="",n=0;n<t;n++)a+=e[n](r,i,o,s)||"";return a}}var tm="c4",JS=p(e=>/^\s*C4Context|C4Container|C4Component|C4Dynamic|C4Deployment/.test(e),"detector"),t_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./c4Diagram-LMCZKHZV-CUyKVoVi.js");return{diagram:t}},__vite__mapDeps([11,12,5,6,7]));return{id:tm,diagram:e}},"loader"),e_={id:tm,detector:JS,loader:t_},r_=e_,em="flowchart",i_=p((e,t)=>t?.flowchart?.defaultRenderer==="dagre-wrapper"||t?.flowchart?.defaultRenderer==="elk"?!1:/^\s*graph/.test(e),"detector"),o_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-CzI-GKO4.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:em,diagram:e}},"loader"),s_={id:em,detector:i_,loader:o_},a_=s_,rm="flowchart-v2",n_=p((e,t)=>t?.flowchart?.defaultRenderer==="dagre-d3"?!1:(t?.flowchart?.defaultRenderer==="elk"&&(t.layout="elk"),/^\s*graph/.test(e)&&t?.flowchart?.defaultRenderer==="dagre-wrapper"?!0:/^\s*flowchart/.test(e)),"detector"),l_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-CzI-GKO4.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:rm,diagram:e}},"loader"),h_={id:rm,detector:n_,loader:l_},c_=h_,im="swimlane",d_=p(e=>/^\s*swimlane-beta\b/.test(e),"detector"),u_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./swimlanesDiagram-G3AALYLV-DKIx012r.js");return{diagram:t}},__vite__mapDeps([18,13,14,15,16,12,17,5,6,7]));return{id:im,diagram:e}},"loader"),f_={id:im,detector:d_,loader:u_},p_=f_,om="er",g_=p(e=>/^\s*erDiagram/.test(e),"detector"),m_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./erDiagram-Q63AITRT-DVzumNgk.js");return{diagram:t}},__vite__mapDeps([19,15,16,17,5,6,7]));return{id:om,diagram:e}},"loader"),y_={id:om,detector:g_,loader:m_},C_=y_,sm="gitGraph",x_=p(e=>/^\s*gitGraph/.test(e),"detector"),b_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./gitGraphDiagram-IHSO6WYX-D7UBC8np.js");return{diagram:t}},__vite__mapDeps([20,21,22,23,5,6,7]));return{id:sm,diagram:e}},"loader"),k_={id:sm,detector:x_,loader:b_},w_=k_,am="gantt",T_=p(e=>/^\s*gantt/.test(e),"detector"),S_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ganttDiagram-NO4QXBWP-B2lfrNfh.js");return{diagram:t}},__vite__mapDeps([24,7,25,26,27,5,6]));return{id:am,diagram:e}},"loader"),__={id:am,detector:T_,loader:S_},B_=__,nm="info",v_=p(e=>/^\s*info/.test(e),"detector"),L_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./infoDiagram-FWYZ7A6U-DASw56fH.js");return{diagram:t}},__vite__mapDeps([28,23,5,6,7]));return{id:nm,diagram:e}},"loader"),F_={id:nm,detector:v_,loader:L_},lm="pie",A_=p(e=>/^\s*pie/.test(e),"detector"),E_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./pieDiagram-ENE6RG2P-f3F4At6v.js");return{diagram:t}},__vite__mapDeps([29,22,23,5,6,30,31,26,7]));return{id:lm,diagram:e}},"loader"),M_={id:lm,detector:A_,loader:E_},hm="quadrantChart",$_=p(e=>/^\s*quadrantChart/.test(e),"detector"),O_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./quadrantDiagram-ABIIQ3AL-3t7sFhfl.js");return{diagram:t}},__vite__mapDeps([32,25,26,27,5,6,7]));return{id:hm,diagram:e}},"loader"),I_={id:hm,detector:$_,loader:O_},D_=I_,cm="xychart",P_=p(e=>/^\s*xychart(-beta)?/.test(e),"detector"),R_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./xychartDiagram-FW5EYKEG-yQImOWPy.js");return{diagram:t}},__vite__mapDeps([33,26,31,25,27,5,6,7]));return{id:cm,diagram:e}},"loader"),N_={id:cm,detector:P_,loader:R_},q_=N_,dm="requirement",W_=p(e=>/^\s*requirement(Diagram)?/.test(e),"detector"),z_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./requirementDiagram-TGXJPOKE-Bzvt0v7J.js");return{diagram:t}},__vite__mapDeps([34,15,16,5,6,7]));return{id:dm,diagram:e}},"loader"),H_={id:dm,detector:W_,loader:z_},Y_=H_,um="sequence",U_=p(e=>/^\s*sequenceDiagram/.test(e),"detector"),j_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./sequenceDiagram-DBY2YBRQ-CnV0H-kS.js");return{diagram:t}},__vite__mapDeps([35,21,12,5,6,7]));return{id:um,diagram:e}},"loader"),G_={id:um,detector:U_,loader:j_},X_=G_,fm="class",V_=p((e,t)=>t?.class?.defaultRenderer==="dagre-wrapper"?!1:/^\s*classDiagram/.test(e),"detector"),Z_=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./classDiagram-OUVF2IWQ-ClMG95L0.js");return{diagram:t}},__vite__mapDeps([36,37,14,15,16,12,5,6,7]));return{id:fm,diagram:e}},"loader"),K_={id:fm,detector:V_,loader:Z_},Q_=K_,pm="classDiagram",J_=p((e,t)=>/^\s*classDiagram/.test(e)&&t?.class?.defaultRenderer==="dagre-wrapper"?!0:/^\s*classDiagram-v2/.test(e),"detector"),tB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./classDiagram-v2-EOCWNBFH-ClMG95L0.js");return{diagram:t}},__vite__mapDeps([38,37,14,15,16,12,5,6,7]));return{id:pm,diagram:e}},"loader"),eB={id:pm,detector:J_,loader:tB},rB=eB,gm="state",iB=p((e,t)=>t?.state?.defaultRenderer==="dagre-wrapper"?!1:/^\s*stateDiagram/.test(e),"detector"),oB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./stateDiagram-2N3HPSRC-GIVsAB2M.js");return{diagram:t}},__vite__mapDeps([39,40,15,16,12,2,4,3,5,6,7]));return{id:gm,diagram:e}},"loader"),sB={id:gm,detector:iB,loader:oB},aB=sB,mm="stateDiagram",nB=p((e,t)=>!!(/^\s*stateDiagram-v2/.test(e)||/^\s*stateDiagram/.test(e)&&t?.state?.defaultRenderer==="dagre-wrapper"),"detector"),lB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./stateDiagram-v2-6OUMAXLB-0KuGlzV7.js");return{diagram:t}},__vite__mapDeps([41,40,15,16,12,5,6,7]));return{id:mm,diagram:e}},"loader"),hB={id:mm,detector:nB,loader:lB},cB=hB,ym="journey",dB=p(e=>/^\s*journey/.test(e),"detector"),uB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./journeyDiagram-5HDEW3XC-BShuBRgf.js");return{diagram:t}},__vite__mapDeps([42,14,12,30,5,6,7]));return{id:ym,diagram:e}},"loader"),fB={id:ym,detector:dB,loader:uB},pB=fB,gB=p((e,t,r)=>{q.debug(`rendering svg for syntax error +`);const i=Yk(t),o=i.append("g");i.attr("viewBox","0 0 2412 512"),Gc(i,100,512,!0),o.append("path").attr("class","error-icon").attr("d","m411.313,123.313c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32-9.375,9.375-20.688-20.688c-12.484-12.5-32.766-12.5-45.25,0l-16,16c-1.261,1.261-2.304,2.648-3.31,4.051-21.739-8.561-45.324-13.426-70.065-13.426-105.867,0-192,86.133-192,192s86.133,192 192,192 192-86.133 192-192c0-24.741-4.864-48.327-13.426-70.065 1.402-1.007 2.79-2.049 4.051-3.31l16-16c12.5-12.492 12.5-32.758 0-45.25l-20.688-20.688 9.375-9.375 32.001-31.999zm-219.313,100.687c-52.938,0-96,43.063-96,96 0,8.836-7.164,16-16,16s-16-7.164-16-16c0-70.578 57.422-128 128-128 8.836,0 16,7.164 16,16s-7.164,16-16,16z"),o.append("path").attr("class","error-icon").attr("d","m459.02,148.98c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l16,16c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16.001-16z"),o.append("path").attr("class","error-icon").attr("d","m340.395,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688 6.25-6.25 6.25-16.375 0-22.625l-16-16c-6.25-6.25-16.375-6.25-22.625,0s-6.25,16.375 0,22.625l15.999,16z"),o.append("path").attr("class","error-icon").attr("d","m400,64c8.844,0 16-7.164 16-16v-32c0-8.836-7.156-16-16-16-8.844,0-16,7.164-16,16v32c0,8.836 7.156,16 16,16z"),o.append("path").attr("class","error-icon").attr("d","m496,96.586h-32c-8.844,0-16,7.164-16,16 0,8.836 7.156,16 16,16h32c8.844,0 16-7.164 16-16 0-8.836-7.156-16-16-16z"),o.append("path").attr("class","error-icon").attr("d","m436.98,75.605c3.125,3.125 7.219,4.688 11.313,4.688 4.094,0 8.188-1.563 11.313-4.688l32-32c6.25-6.25 6.25-16.375 0-22.625s-16.375-6.25-22.625,0l-32,32c-6.251,6.25-6.251,16.375-0.001,22.625z"),o.append("text").attr("class","error-text").attr("x",1440).attr("y",250).attr("font-size","150px").style("text-anchor","middle").text("Syntax error in text"),o.append("text").attr("class","error-text").attr("x",1250).attr("y",400).attr("font-size","100px").style("text-anchor","middle").text(`mermaid version ${r}`)},"draw"),Cm={draw:gB},mB=Cm,yB={db:{},renderer:Cm,parser:{parse:p(()=>{},"parse")}},CB=yB,xm="flowchart-elk",xB=p((e,t={})=>/^\s*flowchart-elk/.test(e)||/^\s*(flowchart|graph)/.test(e)&&t?.flowchart?.defaultRenderer==="elk"?(t.layout="elk",!0):!1,"detector"),bB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./flowDiagram-23GEKE2U-CzI-GKO4.js").then(r=>r.f);return{diagram:t}},__vite__mapDeps([13,14,15,16,12,17]));return{id:xm,diagram:e}},"loader"),kB={id:xm,detector:xB,loader:bB},wB=kB,bm="timeline",TB=p(e=>/^\s*timeline/.test(e),"detector"),SB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./timeline-definition-FHXFAJF6-5u0AN8o0.js");return{diagram:t}},__vite__mapDeps([43,30,5,6,7]));return{id:bm,diagram:e}},"loader"),_B={id:bm,detector:TB,loader:SB},BB=_B,km="mindmap",vB=p(e=>/^\s*mindmap/.test(e),"detector"),LB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./mindmap-definition-LN4V7U3C-HXhM1kRL.js");return{diagram:t}},__vite__mapDeps([44,15,16,5,6,7]));return{id:km,diagram:e}},"loader"),FB={id:km,detector:vB,loader:LB},AB=FB,wm="kanban",EB=p(e=>/^\s*kanban/.test(e),"detector"),MB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./kanban-definition-HUTT4EX6-_UoHLqzR.js");return{diagram:t}},__vite__mapDeps([45,14,5,6,7]));return{id:wm,diagram:e}},"loader"),$B={id:wm,detector:EB,loader:MB},OB=$B,Tm="sankey",IB=p(e=>/^\s*sankey(-beta)?/.test(e),"detector"),DB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./sankeyDiagram-HTMAVEWB-B5WnWxzh.js");return{diagram:t}},__vite__mapDeps([46,31,26,5,6,7]));return{id:Tm,diagram:e}},"loader"),PB={id:Tm,detector:IB,loader:DB},RB=PB,Sm="packet",NB=p(e=>/^\s*packet(-beta)?/.test(e),"detector"),qB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-NH7WQ7WH-DUn2m-AO.js");return{diagram:t}},__vite__mapDeps([47,22,23,5,6,7]));return{id:Sm,diagram:e}},"loader"),WB={id:Sm,detector:NB,loader:qB},_m="radar",zB=p(e=>/^\s*radar-beta/.test(e),"detector"),HB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-WEI45ONY-CFwFRAWa.js");return{diagram:t}},__vite__mapDeps([48,22,23,5,6,7]));return{id:_m,diagram:e}},"loader"),YB={id:_m,detector:zB,loader:HB},Bm="block",UB=p(e=>/^\s*block(-beta)?/.test(e),"detector"),jB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./blockDiagram-677ZJIJ3-BNXb88Fr.js");return{diagram:t}},__vite__mapDeps([49,14,2,17,5,6,7]));return{id:Bm,diagram:e}},"loader"),GB={id:Bm,detector:UB,loader:jB},XB=GB,vm="treeView",VB=p(e=>/^\s*treeView-beta/.test(e),"detector"),ZB=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-OA4YK3LP-BOIp7TNe.js");return{diagram:t}},__vite__mapDeps([50,21,22,23,5,6,7]));return{id:vm,diagram:e}},"loader"),KB={id:vm,detector:VB,loader:ZB},QB=KB,Lm="architecture",JB=p(e=>/^\s*architecture/.test(e),"detector"),tv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./architectureDiagram-ZJ3FMSHR-CBluWNBt.js");return{diagram:t}},__vite__mapDeps([51,22,23,5,6,10,7]));return{id:Lm,diagram:e}},"loader"),ev={id:Lm,detector:JB,loader:tv},rv=ev,Fm="eventmodeling",iv=p(e=>/^\s*eventmodeling/.test(e),"detector"),ov=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-FQU43EPY-D2bRXH1a.js");return{diagram:t}},__vite__mapDeps([52,22,23,5,6,7]));return{id:Fm,diagram:e}},"loader"),sv={id:Fm,detector:iv,loader:ov},av=sv,Am="ishikawa",nv=p(e=>/^\s*ishikawa(-beta)?\b/i.test(e),"detector"),lv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ishikawaDiagram-FXEZZL3T-CcPuml-k.js");return{diagram:t}},__vite__mapDeps([53,5,6,7]));return{id:Am,diagram:e}},"loader"),hv={id:Am,detector:nv,loader:lv},Em="venn",cv=p(e=>/^\s*venn-beta/.test(e),"detector"),dv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./vennDiagram-L72KCM5P-ozNTLnJz.js");return{diagram:t}},__vite__mapDeps([54,5,6,7]));return{id:Em,diagram:e}},"loader"),uv={id:Em,detector:cv,loader:dv},fv=uv,Mm="treemap",pv=p(e=>/^\s*treemap/.test(e),"detector"),gv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./diagram-G47NLZAW-BF9x_uf7.js");return{diagram:t}},__vite__mapDeps([55,22,16,23,5,6,27,31,26,7]));return{id:Mm,diagram:e}},"loader"),mv={id:Mm,detector:pv,loader:gv},$m="wardley",yv=p(e=>/^\s*wardley-beta/i.test(e),"detector"),Cv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./wardleyDiagram-EHGQE667-BuQJYWm-.js");return{diagram:t}},__vite__mapDeps([56,22,23,5,6,7]));return{id:$m,diagram:e}},"loader"),xv={id:$m,detector:yv,loader:Cv},bv=xv,Om="cynefin",kv=p(e=>/^\s*cynefin-beta(?:[\s:]|$)/.test(e),"detector"),wv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./cynefinDiagram-TSTJHNR4-zQaCQNIP.js");return{diagram:t}},__vite__mapDeps([57,22,23,5,6,7]));return{id:Om,diagram:e}},"loader"),Tv={id:Om,detector:kv,loader:wv},Im="railroad",Sv=p(e=>/^\s*railroad-beta/i.test(e),"detector"),_v=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./railroadDiagram-RFXS5EU6-W9nf8fYD.js");return{diagram:t}},__vite__mapDeps([58,59,22,23,5,6,7]));return{id:Im,diagram:e}},"loader"),Bv={id:Im,detector:Sv,loader:_v},Dm="railroadEbnf",vv=p(e=>/^\s*railroad-ebnf-beta/i.test(e),"detector"),Lv=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./ebnfDiagram-CCIWWBDH-B4NTctc_.js");return{diagram:t}},__vite__mapDeps([60,59,22,23,5,6,7]));return{id:Dm,diagram:e}},"loader"),Fv={id:Dm,detector:vv,loader:Lv},Pm="railroadAbnf",Av=p(e=>/^\s*railroad-abnf-beta/i.test(e),"detector"),Ev=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./abnfDiagram-VRR7QNED-C0Afmuc1.js");return{diagram:t}},__vite__mapDeps([61,59,22,23,5,6,7]));return{id:Pm,diagram:e}},"loader"),Mv={id:Pm,detector:Av,loader:Ev},Rm="railroadPeg",$v=p(e=>/^\s*railroad-peg-beta/i.test(e),"detector"),Ov=p(async()=>{const{diagram:e}=await nt(async()=>{const{diagram:t}=await import("./pegDiagram-2B236MQR-_6D7zUy-.js");return{diagram:t}},__vite__mapDeps([62,59,22,23,5,6,7]));return{id:Rm,diagram:e}},"loader"),Iv={id:Rm,detector:$v,loader:Ov},kc=!1,$s=p(()=>{kc||(kc=!0,zo("error",CB,e=>e.toLowerCase().trim()==="error"),zo("---",{db:{clear:p(()=>{},"clear")},styles:{},renderer:{draw:p(()=>{},"draw")},parser:{parse:p(()=>{throw new Error("Diagrams beginning with --- are not valid. If you were trying to use a YAML front-matter, please ensure that you've correctly opened and closed the YAML front-matter with un-indented `---` blocks")},"parse")},init:p(()=>null,"init")},e=>e.toLowerCase().trimStart().startsWith("---")),ba(wB,AB,rv),ba(r_,OB,rB,Q_,C_,B_,F_,M_,Y_,X_,p_,c_,a_,BB,w_,cB,aB,pB,D_,RB,WB,q_,XB,av,QB,YB,hv,mv,Bv,Fv,Mv,Iv,fv,bv,Tv))},"addDiagrams"),Dv=p(async()=>{q.debug("Loading registered diagrams");const t=(await Promise.allSettled(Object.entries(Sr).map(async([r,{detector:i,loader:o}])=>{if(o)try{Sa(r)}catch{try{const{diagram:s,id:a}=await o();zo(a,s,i)}catch(s){throw q.error(`Failed to load external diagram with key ${r}. Removing from detectors.`),delete Sr[r],s}}}))).filter(r=>r.status==="rejected");if(t.length>0){q.error(`Failed to load ${t.length} external diagrams`);for(const r of t)q.error(r);throw new Error(`Failed to load ${t.length} external diagrams`)}},"loadRegisteredDiagrams"),Pv="graphics-document document";function Nm(e,t){e.attr("role",Pv),t!==""&&e.attr("aria-roledescription",t)}p(Nm,"setA11yDiagramInfo");function qm(e,t,r,i){if(e.insert!==void 0){if(r){const o=`chart-desc-${i}`;e.attr("aria-describedby",o),e.insert("desc",":first-child").attr("id",o).text(r)}if(t){const o=`chart-title-${i}`;e.attr("aria-labelledby",o),e.insert("title",":first-child").attr("id",o).text(t)}}}p(qm,"addSVGa11yTitleDescription");var mn=class Wm{constructor(t,r,i,o,s){this.type=t,this.text=r,this.db=i,this.parser=o,this.renderer=s}static{p(this,"Diagram")}static async fromText(t,r={}){const i=vt(),o=xn(t,i);t=Z2(t)+` `;try{Sa(o)}catch{const c=R0(o);if(!c)throw new Wc(`Diagram ${o} not found.`);const{id:h,diagram:d}=await c();zo(h,d)}const{db:s,parser:a,renderer:n,init:l}=Sa(o);return a.parser&&(a.parser.yy=s),s.clear?.(),l?.(i),r.title&&s.setDiagramTitle?.(r.title),await a.parse(t),new Wm(o,t,s,a,n)}async render(t,r){await this.renderer.draw(this.text,t,r,this)}getParser(){return this.parser}getType(){return this.type}},wc=[],Rv=p(()=>{wc.forEach(e=>{e()}),wc=[]},"attachFunctions"),Nv=p(e=>e.replace(/^\s*%%(?!{)[^\n]+\n?/gm,"").trimStart(),"cleanupComments");function zm(e){const t=e.match(qc);if(!t)return{text:e,metadata:{}};const r=t[1],i=r?t[2].split(` `).map(a=>a.startsWith(r)?a.slice(r.length):a).join(` `):t[2];let o=K1(i,{schema:Z1})??{};o=typeof o=="object"&&!Array.isArray(o)?o:{};const s={};return o.displayMode&&(s.displayMode=o.displayMode.toString()),o.title&&(s.title=o.title.toString()),o.config&&(s.config=o.config),{text:e.slice(t[0].length),metadata:s}}p(zm,"extractFrontMatter");var qv=p(e=>e.replace(/\r\n?/g,` diff --git a/apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-WAq6xftS.js b/apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-HXhM1kRL.js similarity index 98% rename from apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-WAq6xftS.js rename to apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-HXhM1kRL.js index 3b3e14b0d..75b39e1c1 100644 --- a/apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-WAq6xftS.js +++ b/apps/kimi-code/dist-web/assets/mindmap-definition-LN4V7U3C-HXhM1kRL.js @@ -1,4 +1,4 @@ -import{g as oe}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as ae}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as l,l as C,v as ce,x as le,z as he,D as G,c as B,i as F,b6 as de,aa as ge,ab as ue,ac as pe}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";const E=[];for(let e=0;e<256;++e)E.push((e+256).toString(16).slice(1));function fe(e,n=0){return(E[e[n+0]]+E[e[n+1]]+E[e[n+2]]+E[e[n+3]]+"-"+E[e[n+4]]+E[e[n+5]]+"-"+E[e[n+6]]+E[e[n+7]]+"-"+E[e[n+8]]+E[e[n+9]]+"-"+E[e[n+10]]+E[e[n+11]]+E[e[n+12]]+E[e[n+13]]+E[e[n+14]]+E[e[n+15]]).toLowerCase()}const me=new Uint8Array(16);function ye(){return crypto.getRandomValues(me)}function Ee(e,n,g){return crypto.randomUUID?crypto.randomUUID():_e(e)}function _e(e,n,g){e=e||{};const a=e.random??e.rng?.()??ye();if(a.length<16)throw new Error("Random bytes length must be >= 16");return a[6]=a[6]&15|64,a[8]=a[8]&63|128,fe(a)}var Y=(function(){var e=l(function(D,s,i,o){for(i=i||{},o=D.length;o--;i[D[o]]=s);return i},"o"),n=[1,4],g=[1,13],a=[1,12],t=[1,15],h=[1,16],f=[1,20],m=[1,19],_=[6,7,8],T=[1,26],I=[1,24],w=[1,25],d=[6,7,11],R=[1,6,13,15,16,19,22],q=[1,33],J=[1,34],A=[1,6,7,11,13,15,16,19,22],j={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:l(function(s,i,o,c,p,r,$){var u=r.length-1;switch(p){case 6:case 7:return c;case 8:c.getLogger().trace("Stop NL ");break;case 9:c.getLogger().trace("Stop EOF ");break;case 11:c.getLogger().trace("Stop NL2 ");break;case 12:c.getLogger().trace("Stop EOF2 ");break;case 15:c.getLogger().info("Node: ",r[u].id),c.addNode(r[u-1].length,r[u].id,r[u].descr,r[u].type);break;case 16:c.getLogger().trace("Icon: ",r[u]),c.decorateNode({icon:r[u]});break;case 17:case 21:c.decorateNode({class:r[u]});break;case 18:c.getLogger().trace("SPACELIST");break;case 19:c.getLogger().trace("Node: ",r[u].id),c.addNode(0,r[u].id,r[u].descr,r[u].type);break;case 20:c.decorateNode({icon:r[u]});break;case 25:c.getLogger().trace("node found ..",r[u-2]),this.$={id:r[u-1],descr:r[u-1],type:c.getType(r[u-2],r[u])};break;case 26:this.$={id:r[u],descr:r[u],type:c.nodeType.DEFAULT};break;case 27:c.getLogger().trace("node found ..",r[u-3]),this.$={id:r[u-3],descr:r[u-1],type:c.getType(r[u-2],r[u])};break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:n},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:n},{6:g,7:[1,10],9:9,12:11,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},e(_,[2,3]),{1:[2,2]},e(_,[2,4]),e(_,[2,5]),{1:[2,6],6:g,12:21,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},{6:g,9:22,12:11,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},{6:T,7:I,10:23,11:w},e(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:f,22:m}),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),e(d,[2,21]),e(d,[2,23]),e(d,[2,24]),e(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:T,7:I,10:32,11:w},{1:[2,7],6:g,12:21,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},e(R,[2,14],{7:q,11:J}),e(A,[2,8]),e(A,[2,9]),e(A,[2,10]),e(d,[2,15]),e(d,[2,16]),e(d,[2,17]),{20:[1,35]},{21:[1,36]},e(R,[2,13],{7:q,11:J}),e(A,[2,11]),e(A,[2,12]),{21:[1,37]},e(d,[2,25]),e(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:l(function(s,i){if(i.recoverable)this.trace(s);else{var o=new Error(s);throw o.hash=i,o}},"parseError"),parse:l(function(s){var i=this,o=[0],c=[],p=[null],r=[],$=this.table,u="",M=0,K=0,ne=2,Q=1,ie=r.slice.call(arguments,1),y=Object.create(this.lexer),L={yy:{}};for(var H in this.yy)Object.prototype.hasOwnProperty.call(this.yy,H)&&(L.yy[H]=this.yy[H]);y.setInput(s,L.yy),L.yy.lexer=y,L.yy.parser=this,typeof y.yylloc>"u"&&(y.yylloc={});var z=y.yylloc;r.push(z);var se=y.options&&y.options.ranges;typeof L.yy.parseError=="function"?this.parseError=L.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function re(k){o.length=o.length-2*k,p.length=p.length-k,r.length=r.length-k}l(re,"popStack");function Z(){var k;return k=c.pop()||y.lex()||Q,typeof k!="number"&&(k instanceof Array&&(c=k,k=c.pop()),k=i.symbols_[k]||k),k}l(Z,"lex");for(var b,v,S,W,O={},U,x,ee,V;;){if(v=o[o.length-1],this.defaultActions[v]?S=this.defaultActions[v]:((b===null||typeof b>"u")&&(b=Z()),S=$[v]&&$[v][b]),typeof S>"u"||!S.length||!S[0]){var X="";V=[];for(U in $[v])this.terminals_[U]&&U>ne&&V.push("'"+this.terminals_[U]+"'");y.showPosition?X="Parse error on line "+(M+1)+`: +import{g as oe}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as ae}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as l,l as C,v as ce,x as le,z as he,D as G,c as B,i as F,b6 as de,aa as ge,ab as ue,ac as pe}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";const E=[];for(let e=0;e<256;++e)E.push((e+256).toString(16).slice(1));function fe(e,n=0){return(E[e[n+0]]+E[e[n+1]]+E[e[n+2]]+E[e[n+3]]+"-"+E[e[n+4]]+E[e[n+5]]+"-"+E[e[n+6]]+E[e[n+7]]+"-"+E[e[n+8]]+E[e[n+9]]+"-"+E[e[n+10]]+E[e[n+11]]+E[e[n+12]]+E[e[n+13]]+E[e[n+14]]+E[e[n+15]]).toLowerCase()}const me=new Uint8Array(16);function ye(){return crypto.getRandomValues(me)}function Ee(e,n,g){return crypto.randomUUID?crypto.randomUUID():_e(e)}function _e(e,n,g){e=e||{};const a=e.random??e.rng?.()??ye();if(a.length<16)throw new Error("Random bytes length must be >= 16");return a[6]=a[6]&15|64,a[8]=a[8]&63|128,fe(a)}var Y=(function(){var e=l(function(D,s,i,o){for(i=i||{},o=D.length;o--;i[D[o]]=s);return i},"o"),n=[1,4],g=[1,13],a=[1,12],t=[1,15],h=[1,16],f=[1,20],m=[1,19],_=[6,7,8],T=[1,26],I=[1,24],w=[1,25],d=[6,7,11],R=[1,6,13,15,16,19,22],q=[1,33],J=[1,34],A=[1,6,7,11,13,15,16,19,22],j={trace:l(function(){},"trace"),yy:{},symbols_:{error:2,start:3,mindMap:4,spaceLines:5,SPACELINE:6,NL:7,MINDMAP:8,document:9,stop:10,EOF:11,statement:12,SPACELIST:13,node:14,ICON:15,CLASS:16,nodeWithId:17,nodeWithoutId:18,NODE_DSTART:19,NODE_DESCR:20,NODE_DEND:21,NODE_ID:22,$accept:0,$end:1},terminals_:{2:"error",6:"SPACELINE",7:"NL",8:"MINDMAP",11:"EOF",13:"SPACELIST",15:"ICON",16:"CLASS",19:"NODE_DSTART",20:"NODE_DESCR",21:"NODE_DEND",22:"NODE_ID"},productions_:[0,[3,1],[3,2],[5,1],[5,2],[5,2],[4,2],[4,3],[10,1],[10,1],[10,1],[10,2],[10,2],[9,3],[9,2],[12,2],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[12,1],[14,1],[14,1],[18,3],[17,1],[17,4]],performAction:l(function(s,i,o,c,p,r,$){var u=r.length-1;switch(p){case 6:case 7:return c;case 8:c.getLogger().trace("Stop NL ");break;case 9:c.getLogger().trace("Stop EOF ");break;case 11:c.getLogger().trace("Stop NL2 ");break;case 12:c.getLogger().trace("Stop EOF2 ");break;case 15:c.getLogger().info("Node: ",r[u].id),c.addNode(r[u-1].length,r[u].id,r[u].descr,r[u].type);break;case 16:c.getLogger().trace("Icon: ",r[u]),c.decorateNode({icon:r[u]});break;case 17:case 21:c.decorateNode({class:r[u]});break;case 18:c.getLogger().trace("SPACELIST");break;case 19:c.getLogger().trace("Node: ",r[u].id),c.addNode(0,r[u].id,r[u].descr,r[u].type);break;case 20:c.decorateNode({icon:r[u]});break;case 25:c.getLogger().trace("node found ..",r[u-2]),this.$={id:r[u-1],descr:r[u-1],type:c.getType(r[u-2],r[u])};break;case 26:this.$={id:r[u],descr:r[u],type:c.nodeType.DEFAULT};break;case 27:c.getLogger().trace("node found ..",r[u-3]),this.$={id:r[u-3],descr:r[u-1],type:c.getType(r[u-2],r[u])};break}},"anonymous"),table:[{3:1,4:2,5:3,6:[1,5],8:n},{1:[3]},{1:[2,1]},{4:6,6:[1,7],7:[1,8],8:n},{6:g,7:[1,10],9:9,12:11,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},e(_,[2,3]),{1:[2,2]},e(_,[2,4]),e(_,[2,5]),{1:[2,6],6:g,12:21,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},{6:g,9:22,12:11,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},{6:T,7:I,10:23,11:w},e(d,[2,22],{17:17,18:18,14:27,15:[1,28],16:[1,29],19:f,22:m}),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),e(d,[2,21]),e(d,[2,23]),e(d,[2,24]),e(d,[2,26],{19:[1,30]}),{20:[1,31]},{6:T,7:I,10:32,11:w},{1:[2,7],6:g,12:21,13:a,14:14,15:t,16:h,17:17,18:18,19:f,22:m},e(R,[2,14],{7:q,11:J}),e(A,[2,8]),e(A,[2,9]),e(A,[2,10]),e(d,[2,15]),e(d,[2,16]),e(d,[2,17]),{20:[1,35]},{21:[1,36]},e(R,[2,13],{7:q,11:J}),e(A,[2,11]),e(A,[2,12]),{21:[1,37]},e(d,[2,25]),e(d,[2,27])],defaultActions:{2:[2,1],6:[2,2]},parseError:l(function(s,i){if(i.recoverable)this.trace(s);else{var o=new Error(s);throw o.hash=i,o}},"parseError"),parse:l(function(s){var i=this,o=[0],c=[],p=[null],r=[],$=this.table,u="",M=0,K=0,ne=2,Q=1,ie=r.slice.call(arguments,1),y=Object.create(this.lexer),L={yy:{}};for(var H in this.yy)Object.prototype.hasOwnProperty.call(this.yy,H)&&(L.yy[H]=this.yy[H]);y.setInput(s,L.yy),L.yy.lexer=y,L.yy.parser=this,typeof y.yylloc>"u"&&(y.yylloc={});var z=y.yylloc;r.push(z);var se=y.options&&y.options.ranges;typeof L.yy.parseError=="function"?this.parseError=L.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function re(k){o.length=o.length-2*k,p.length=p.length-k,r.length=r.length-k}l(re,"popStack");function Z(){var k;return k=c.pop()||y.lex()||Q,typeof k!="number"&&(k instanceof Array&&(c=k,k=c.pop()),k=i.symbols_[k]||k),k}l(Z,"lex");for(var b,v,S,W,O={},U,x,ee,V;;){if(v=o[o.length-1],this.defaultActions[v]?S=this.defaultActions[v]:((b===null||typeof b>"u")&&(b=Z()),S=$[v]&&$[v][b]),typeof S>"u"||!S.length||!S[0]){var X="";V=[];for(U in $[v])this.terminals_[U]&&U>ne&&V.push("'"+this.terminals_[U]+"'");y.showPosition?X="Parse error on line "+(M+1)+`: `+y.showPosition()+` Expecting `+V.join(", ")+", got '"+(this.terminals_[b]||b)+"'":X="Parse error on line "+(M+1)+": Unexpected "+(b==Q?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(X,{text:y.match,token:this.terminals_[b]||b,line:y.yylineno,loc:z,expected:V})}if(S[0]instanceof Array&&S.length>1)throw new Error("Parse Error: multiple actions possible at state: "+v+", token: "+b);switch(S[0]){case 1:o.push(b),p.push(y.yytext),r.push(y.yylloc),o.push(S[1]),b=null,K=y.yyleng,u=y.yytext,M=y.yylineno,z=y.yylloc;break;case 2:if(x=this.productions_[S[1]][1],O.$=p[p.length-x],O._$={first_line:r[r.length-(x||1)].first_line,last_line:r[r.length-1].last_line,first_column:r[r.length-(x||1)].first_column,last_column:r[r.length-1].last_column},se&&(O._$.range=[r[r.length-(x||1)].range[0],r[r.length-1].range[1]]),W=this.performAction.apply(O,[u,K,M,L.yy,S[1],p,r].concat(ie)),typeof W<"u")return W;x&&(o=o.slice(0,-1*x*2),p=p.slice(0,-1*x),r=r.slice(0,-1*x)),o.push(this.productions_[S[1]][0]),p.push(O.$),r.push(O._$),ee=$[o[o.length-2]][o[o.length-1]],o.push(ee);break;case 3:return!0}}return!0},"parse")},te=(function(){var D={EOF:1,parseError:l(function(i,o){if(this.yy.parser)this.yy.parser.parseError(i,o);else throw new Error(i)},"parseError"),setInput:l(function(s,i){return this.yy=i||this.yy||{},this._input=s,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:l(function(){var s=this._input[0];this.yytext+=s,this.yyleng++,this.offset++,this.match+=s,this.matched+=s;var i=s.match(/(?:\r\n?|\n).*/g);return i?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),s},"input"),unput:l(function(s){var i=s.length,o=s.split(/(?:\r\n?|\n)/g);this._input=s+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-i),this.offset-=i;var c=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),o.length-1&&(this.yylineno-=o.length-1);var p=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:o?(o.length===c.length?this.yylloc.first_column:0)+c[c.length-o.length].length-o[0].length:this.yylloc.first_column-i},this.options.ranges&&(this.yylloc.range=[p[0],p[0]+this.yyleng-i]),this.yyleng=this.yytext.length,this},"unput"),more:l(function(){return this._more=!0,this},"more"),reject:l(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:l(function(s){this.unput(this.match.slice(s))},"less"),pastInput:l(function(){var s=this.matched.substr(0,this.matched.length-this.match.length);return(s.length>20?"...":"")+s.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:l(function(){var s=this.match;return s.length<20&&(s+=this._input.substr(0,20-s.length)),(s.substr(0,20)+(s.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:l(function(){var s=this.pastInput(),i=new Array(s.length+1).join("-");return s+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-C7Ks7P9i.js b/apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-_6D7zUy-.js similarity index 87% rename from apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-C7Ks7P9i.js rename to apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-_6D7zUy-.js index 851e38128..c2c272efd 100644 --- a/apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-C7Ks7P9i.js +++ b/apps/kimi-code/dist-web/assets/pegDiagram-2B236MQR-_6D7zUy-.js @@ -1 +1 @@ -import{g as l,r as m,d as a}from"./chunk-MOJQB5TN-Ce2Y728v.js";import{p}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as t,l as o}from"./mermaid.core-DaDTfY6S.js";import{M as u,d as c}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var f=c().RailroadPeg.parser.LangiumParser,i=t(e=>{const r=e.alternatives.map(d);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformOrderedChoice"),d=t(e=>{const r=e.elements.map(P);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformSequence"),P=t(e=>{const r=g(e.suffix);return e.operator?{type:"special",text:e.operator==="&"?`&${s(r)}`:`!${s(r)}`}:r},"transformPrefix"),s=t(e=>{switch(e.type){case"terminal":return`"${e.value}"`;case"nonterminal":return e.name;case"special":return e.text;default:return"(...)"}},"nodeToLabel"),g=t(e=>{const r=v(e.primary);if(!e.operator)return r;switch(e.operator){case"?":return{type:"optional",element:r};case"*":return{type:"repetition",element:r,min:0,max:1/0};case"+":return{type:"repetition",element:r,min:1,max:1/0};default:throw new Error(`Unsupported PEG suffix operator: ${e.operator}`)}},"transformSuffix"),v=t(e=>{switch(e.$type){case"PegLiteral":return{type:"terminal",value:e.value};case"PegIdentifier":return{type:"nonterminal",name:e.name};case"PegGroup":return i(e.element);case"PegAny":return{type:"special",text:e.dot};default:throw new Error(`Unsupported PEG primary node: ${e.$type}`)}},"transformPrimary"),y=t(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=t(e=>{p(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(y(r)))},"populateDb"),b={parse:t(e=>{a.clear(),o.debug("[PEG Parser] Starting Langium parse");const r=f.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new u(r);const n=r.value;o.debug("[PEG Parser] Parsed rules:",n.rules.length),h(n),o.debug("[PEG Parser] Parse complete")},"parse"),parser:{yy:a}},L={parser:b,db:a,renderer:m,styles:l};export{L as diagram}; +import{g as l,r as m,d as a}from"./chunk-MOJQB5TN-JQ2kJR9W.js";import{p}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as t,l as o}from"./mermaid.core-CJB1tAev.js";import{M as u,d as c}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var f=c().RailroadPeg.parser.LangiumParser,i=t(e=>{const r=e.alternatives.map(d);return r.length===1?r[0]:{type:"choice",alternatives:r}},"transformOrderedChoice"),d=t(e=>{const r=e.elements.map(P);return r.length===1?r[0]:{type:"sequence",elements:r}},"transformSequence"),P=t(e=>{const r=g(e.suffix);return e.operator?{type:"special",text:e.operator==="&"?`&${s(r)}`:`!${s(r)}`}:r},"transformPrefix"),s=t(e=>{switch(e.type){case"terminal":return`"${e.value}"`;case"nonterminal":return e.name;case"special":return e.text;default:return"(...)"}},"nodeToLabel"),g=t(e=>{const r=v(e.primary);if(!e.operator)return r;switch(e.operator){case"?":return{type:"optional",element:r};case"*":return{type:"repetition",element:r,min:0,max:1/0};case"+":return{type:"repetition",element:r,min:1,max:1/0};default:throw new Error(`Unsupported PEG suffix operator: ${e.operator}`)}},"transformSuffix"),v=t(e=>{switch(e.$type){case"PegLiteral":return{type:"terminal",value:e.value};case"PegIdentifier":return{type:"nonterminal",name:e.name};case"PegGroup":return i(e.element);case"PegAny":return{type:"special",text:e.dot};default:throw new Error(`Unsupported PEG primary node: ${e.$type}`)}},"transformPrimary"),y=t(e=>({name:e.name,definition:i(e.definition)}),"transformRule"),h=t(e=>{p(e,a),e.title&&a.setTitle(e.title),e.rules.map(r=>a.addRule(y(r)))},"populateDb"),b={parse:t(e=>{a.clear(),o.debug("[PEG Parser] Starting Langium parse");const r=f.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new u(r);const n=r.value;o.debug("[PEG Parser] Parsed rules:",n.rules.length),h(n),o.debug("[PEG Parser] Parse complete")},"parse"),parser:{yy:a}},L={parser:b,db:a,renderer:m,styles:l};export{L as diagram}; diff --git a/apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-5Ehl6T8C.js b/apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-f3F4At6v.js similarity index 94% rename from apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-5Ehl6T8C.js rename to apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-f3F4At6v.js index 417a0e433..b9b4f579b 100644 --- a/apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-5Ehl6T8C.js +++ b/apps/kimi-code/dist-web/assets/pieDiagram-ENE6RG2P-f3F4At6v.js @@ -1,4 +1,4 @@ -import{p as at}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{K as T,N as B,b5 as rt,g as nt,s as it,a as ot,b as st,p as lt,o as ct,_ as g,l as G,c as ut,B as dt,F as gt,a1 as pt,e as ht,q as ft,D as mt}from"./mermaid.core-DaDTfY6S.js";import{p as vt}from"./cynefin-VYW2F7L2-0NmB13eq.js";import{d as X}from"./arc-CC9q5kjc.js";import{o as xt}from"./ordinal-Cboi1Yqb.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function St(t,n){return n<t?-1:n>t?1:n>=t?0:NaN}function yt(t){return t}function wt(){var t=yt,n=St,y=null,b=T(0),l=T(B),p=T(0);function i(e){var r,s=(e=rt(e)).length,h,w,$=0,f=new Array(s),o=new Array(s),D=+b.apply(this,arguments),E=Math.min(B,Math.max(-B,l.apply(this,arguments)-D)),k,F=Math.min(Math.abs(E)/s,p.apply(this,arguments)),u=F*(E<0?-1:1),A;for(r=0;r<s;++r)(A=o[f[r]=r]=+t(e[r],r,e))>0&&($+=A);for(n!=null?f.sort(function(M,m){return n(o[M],o[m])}):y!=null&&f.sort(function(M,m){return y(e[M],e[m])}),r=0,w=$?(E-s*u)/$:0;r<s;++r,D=k)h=f[r],A=o[h],k=D+(A>0?A*w:0)+u,o[h]={data:e[h],index:r,value:A,startAngle:D,endAngle:k,padAngle:F};return o}return i.value=function(e){return arguments.length?(t=typeof e=="function"?e:T(+e),i):t},i.sortValues=function(e){return arguments.length?(n=e,y=null,i):n},i.sort=function(e){return arguments.length?(y=e,n=null,i):y},i.startAngle=function(e){return arguments.length?(b=typeof e=="function"?e:T(+e),i):b},i.endAngle=function(e){return arguments.length?(l=typeof e=="function"?e:T(+e),i):l},i.padAngle=function(e){return arguments.length?(p=typeof e=="function"?e:T(+e),i):p},i}var At=mt.pie,I={sections:new Map,showData:!1},W=I.sections,V=I.showData,Ct=structuredClone(At),$t=g(()=>structuredClone(Ct),"getConfig"),Dt=g(()=>{W=new Map,V=I.showData,ft()},"clear"),Tt=g(({label:t,value:n})=>{if(n<0)throw new Error(`"${t}" has invalid value: ${n}. Negative values are not allowed in pie charts. All slice values must be >= 0.`);W.has(t)||(W.set(t,n),G.debug(`added new section: ${t}, with value: ${n}`))},"addSection"),bt=g(()=>W,"getSections"),kt=g(t=>{V=t},"setShowData"),zt=g(()=>V,"getShowData"),Z={getConfig:$t,clear:Dt,setDiagramTitle:ct,getDiagramTitle:lt,setAccTitle:st,getAccTitle:ot,setAccDescription:it,getAccDescription:nt,addSection:Tt,getSections:bt,setShowData:kt,getShowData:zt},Et=g((t,n)=>{at(t,n),n.setShowData(t.showData),t.sections.map(n.addSection)},"populateDb"),Mt={parse:g(async t=>{const n=await vt("pie",t);G.debug(n),Et(n,Z)},"parse")},Rt=g(t=>` +import{p as at}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{K as T,N as B,b5 as rt,g as nt,s as it,a as ot,b as st,p as lt,o as ct,_ as g,l as G,c as ut,B as dt,F as gt,a1 as pt,e as ht,q as ft,D as mt}from"./mermaid.core-CJB1tAev.js";import{p as vt}from"./cynefin-VYW2F7L2-BIlq342y.js";import{d as X}from"./arc-IkhU3FHH.js";import{o as xt}from"./ordinal-Cboi1Yqb.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function St(t,n){return n<t?-1:n>t?1:n>=t?0:NaN}function yt(t){return t}function wt(){var t=yt,n=St,y=null,b=T(0),l=T(B),p=T(0);function i(e){var r,s=(e=rt(e)).length,h,w,$=0,f=new Array(s),o=new Array(s),D=+b.apply(this,arguments),E=Math.min(B,Math.max(-B,l.apply(this,arguments)-D)),k,F=Math.min(Math.abs(E)/s,p.apply(this,arguments)),u=F*(E<0?-1:1),A;for(r=0;r<s;++r)(A=o[f[r]=r]=+t(e[r],r,e))>0&&($+=A);for(n!=null?f.sort(function(M,m){return n(o[M],o[m])}):y!=null&&f.sort(function(M,m){return y(e[M],e[m])}),r=0,w=$?(E-s*u)/$:0;r<s;++r,D=k)h=f[r],A=o[h],k=D+(A>0?A*w:0)+u,o[h]={data:e[h],index:r,value:A,startAngle:D,endAngle:k,padAngle:F};return o}return i.value=function(e){return arguments.length?(t=typeof e=="function"?e:T(+e),i):t},i.sortValues=function(e){return arguments.length?(n=e,y=null,i):n},i.sort=function(e){return arguments.length?(y=e,n=null,i):y},i.startAngle=function(e){return arguments.length?(b=typeof e=="function"?e:T(+e),i):b},i.endAngle=function(e){return arguments.length?(l=typeof e=="function"?e:T(+e),i):l},i.padAngle=function(e){return arguments.length?(p=typeof e=="function"?e:T(+e),i):p},i}var At=mt.pie,I={sections:new Map,showData:!1},W=I.sections,V=I.showData,Ct=structuredClone(At),$t=g(()=>structuredClone(Ct),"getConfig"),Dt=g(()=>{W=new Map,V=I.showData,ft()},"clear"),Tt=g(({label:t,value:n})=>{if(n<0)throw new Error(`"${t}" has invalid value: ${n}. Negative values are not allowed in pie charts. All slice values must be >= 0.`);W.has(t)||(W.set(t,n),G.debug(`added new section: ${t}, with value: ${n}`))},"addSection"),bt=g(()=>W,"getSections"),kt=g(t=>{V=t},"setShowData"),zt=g(()=>V,"getShowData"),Z={getConfig:$t,clear:Dt,setDiagramTitle:ct,getDiagramTitle:lt,setAccTitle:st,getAccTitle:ot,setAccDescription:it,getAccDescription:nt,addSection:Tt,getSections:bt,setShowData:kt,getShowData:zt},Et=g((t,n)=>{at(t,n),n.setShowData(t.showData),t.sections.map(n.addSection)},"populateDb"),Mt={parse:g(async t=>{const n=await vt("pie",t);G.debug(n),Et(n,Z)},"parse")},Rt=g(t=>` .pieCircle{ stroke: ${t.pieStrokeColor}; stroke-width : ${t.pieStrokeWidth}; diff --git a/apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-8vMHBPBY.js b/apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-3t7sFhfl.js similarity index 99% rename from apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-8vMHBPBY.js rename to apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-3t7sFhfl.js index ff63087aa..3f7c3054a 100644 --- a/apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-8vMHBPBY.js +++ b/apps/kimi-code/dist-web/assets/quadrantDiagram-ABIIQ3AL-3t7sFhfl.js @@ -1,4 +1,4 @@ -import{s as Se,g as _e,p as ee,o as Ae,a as ke,b as Fe,_ as r,c as Et,l as qt,d as vt,e as Pe,q as ve,D as z,i as Ce,W as Le}from"./mermaid.core-DaDTfY6S.js";import{l as te}from"./linear-BmFm-Eu7.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";import"./defaultLocale-DX6XiGOO.js";var Ct=(function(){var t=r(function(Y,s,l,u){for(l=l||{},u=Y.length;u--;l[Y[u]]=s);return l},"o"),a=[1,3],p=[1,4],f=[1,5],o=[1,6],x=[1,7],_=[1,4,5,10,12,13,14,15,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],h=[1,4,5,10,12,13,14,15,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],c=[55,56,57],S=[2,36],m=[1,37],b=[1,36],y=[1,38],T=[1,35],q=[1,43],g=[1,41],k=[1,45],ct=[1,14],dt=[1,23],ut=[1,18],xt=[1,19],ot=[1,20],bt=[1,21],lt=[1,22],i=[1,24],Dt=[1,25],zt=[1,26],Vt=[1,27],It=[1,28],wt=[1,29],U=[1,32],Q=[1,33],F=[1,34],P=[1,39],v=[1,40],C=[1,42],L=[1,44],H=[1,63],X=[1,62],E=[4,5,8,10,12,13,14,15,18,44,47,49,55,56,57,63,64,65,66,67],Bt=[1,66],Rt=[1,67],Nt=[1,68],Wt=[1,69],Ut=[1,70],Qt=[1,71],Ot=[1,72],Ht=[1,73],Xt=[1,74],Mt=[1,75],Yt=[1,76],jt=[1,77],w=[4,5,6,7,8,9,10,11,12,13,14,15,18],K=[1,91],Z=[1,92],J=[1,93],$=[1,100],tt=[1,94],et=[1,97],it=[1,95],at=[1,96],nt=[1,98],st=[1,99],St=[1,103],Gt=[10,55,56,57],N=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],_t={trace:r(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:r(function(s,l,u,d,A,e,ht){var n=e.length-1;switch(A){case 23:this.$=e[n];break;case 24:this.$=e[n-1]+""+e[n];break;case 26:this.$=e[n-1]+e[n];break;case 27:this.$=[e[n].trim()];break;case 28:e[n-2].push(e[n].trim()),this.$=e[n-2];break;case 29:this.$=e[n-4],d.addClass(e[n-2],e[n]);break;case 37:this.$=[];break;case 42:this.$=e[n].trim(),d.setDiagramTitle(this.$);break;case 43:this.$=e[n].trim(),d.setAccTitle(this.$);break;case 44:case 45:this.$=e[n].trim(),d.setAccDescription(this.$);break;case 46:d.addSection(e[n].substr(8)),this.$=e[n].substr(8);break;case 47:d.addPoint(e[n-3],"",e[n-1],e[n],[]);break;case 48:d.addPoint(e[n-4],e[n-3],e[n-1],e[n],[]);break;case 49:d.addPoint(e[n-4],"",e[n-2],e[n-1],e[n]);break;case 50:d.addPoint(e[n-5],e[n-4],e[n-2],e[n-1],e[n]);break;case 51:d.setXAxisLeftText(e[n-2]),d.setXAxisRightText(e[n]);break;case 52:e[n-1].text+=" ⟶ ",d.setXAxisLeftText(e[n-1]);break;case 53:d.setXAxisLeftText(e[n]);break;case 54:d.setYAxisBottomText(e[n-2]),d.setYAxisTopText(e[n]);break;case 55:e[n-1].text+=" ⟶ ",d.setYAxisBottomText(e[n-1]);break;case 56:d.setYAxisBottomText(e[n]);break;case 57:d.setQuadrant1Text(e[n]);break;case 58:d.setQuadrant2Text(e[n]);break;case 59:d.setQuadrant3Text(e[n]);break;case 60:d.setQuadrant4Text(e[n]);break;case 64:this.$={text:e[n],type:"text"};break;case 65:this.$={text:e[n-1].text+""+e[n],type:e[n-1].type};break;case 66:this.$={text:e[n],type:"text"};break;case 67:this.$={text:e[n],type:"markdown"};break;case 68:this.$=e[n];break;case 69:this.$=e[n-1]+""+e[n];break}},"anonymous"),table:[{18:a,26:1,27:2,28:p,55:f,56:o,57:x},{1:[3]},{18:a,26:8,27:2,28:p,55:f,56:o,57:x},{18:a,26:9,27:2,28:p,55:f,56:o,57:x},t(_,[2,33],{29:10}),t(h,[2,61]),t(h,[2,62]),t(h,[2,63]),{1:[2,30]},{1:[2,31]},t(c,S,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:m,5:b,10:y,12:T,13:q,14:g,15:k,18:ct,25:dt,35:ut,37:xt,39:ot,41:bt,42:lt,48:i,50:Dt,51:zt,52:Vt,53:It,54:wt,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(_,[2,34]),{27:46,55:f,56:o,57:x},t(c,[2,37]),t(c,S,{24:13,32:15,33:16,34:17,43:30,58:31,31:47,4:m,5:b,10:y,12:T,13:q,14:g,15:k,18:ct,25:dt,35:ut,37:xt,39:ot,41:bt,42:lt,48:i,50:Dt,51:zt,52:Vt,53:It,54:wt,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(c,[2,39]),t(c,[2,40]),t(c,[2,41]),{36:[1,48]},{38:[1,49]},{40:[1,50]},t(c,[2,45]),t(c,[2,46]),{18:[1,51]},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:52,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:53,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:54,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:55,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:56,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:57,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,44:[1,58],47:[1,59],58:61,59:60,63:F,64:P,65:v,66:C,67:L},t(E,[2,64]),t(E,[2,66]),t(E,[2,67]),t(E,[2,70]),t(E,[2,71]),t(E,[2,72]),t(E,[2,73]),t(E,[2,74]),t(E,[2,75]),t(E,[2,76]),t(E,[2,77]),t(E,[2,78]),t(E,[2,79]),t(E,[2,80]),t(E,[2,81]),t(_,[2,35]),t(c,[2,38]),t(c,[2,42]),t(c,[2,43]),t(c,[2,44]),{3:65,4:Bt,5:Rt,6:Nt,7:Wt,8:Ut,9:Qt,10:Ot,11:Ht,12:Xt,13:Mt,14:Yt,15:jt,21:64},t(c,[2,53],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,49:[1,78],63:F,64:P,65:v,66:C,67:L}),t(c,[2,56],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,49:[1,79],63:F,64:P,65:v,66:C,67:L}),t(c,[2,57],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,58],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,59],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,60],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),{45:[1,80]},{44:[1,81]},t(E,[2,65]),t(E,[2,82]),t(E,[2,83]),t(E,[2,84]),{3:83,4:Bt,5:Rt,6:Nt,7:Wt,8:Ut,9:Qt,10:Ot,11:Ht,12:Xt,13:Mt,14:Yt,15:jt,18:[1,82]},t(w,[2,23]),t(w,[2,1]),t(w,[2,2]),t(w,[2,3]),t(w,[2,4]),t(w,[2,5]),t(w,[2,6]),t(w,[2,7]),t(w,[2,8]),t(w,[2,9]),t(w,[2,10]),t(w,[2,11]),t(w,[2,12]),t(c,[2,52],{58:31,43:84,4:m,5:b,10:y,12:T,13:q,14:g,15:k,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(c,[2,55],{58:31,43:85,4:m,5:b,10:y,12:T,13:q,14:g,15:k,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),{46:[1,86]},{45:[1,87]},{4:K,5:Z,6:J,8:$,11:tt,13:et,16:90,17:it,18:at,19:nt,20:st,22:89,23:88},t(w,[2,24]),t(c,[2,51],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,54],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,47],{22:89,16:90,23:101,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),{46:[1,102]},t(c,[2,29],{10:St}),t(Gt,[2,27],{16:104,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),t(N,[2,25]),t(N,[2,13]),t(N,[2,14]),t(N,[2,15]),t(N,[2,16]),t(N,[2,17]),t(N,[2,18]),t(N,[2,19]),t(N,[2,20]),t(N,[2,21]),t(N,[2,22]),t(c,[2,49],{10:St}),t(c,[2,48],{22:89,16:90,23:105,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),{4:K,5:Z,6:J,8:$,11:tt,13:et,16:90,17:it,18:at,19:nt,20:st,22:106},t(N,[2,26]),t(c,[2,50],{10:St}),t(Gt,[2,28],{16:104,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st})],defaultActions:{8:[2,30],9:[2,31]},parseError:r(function(s,l){if(l.recoverable)this.trace(s);else{var u=new Error(s);throw u.hash=l,u}},"parseError"),parse:r(function(s){var l=this,u=[0],d=[],A=[null],e=[],ht=this.table,n="",gt=0,Kt=0,Te=2,Zt=1,qe=e.slice.call(arguments,1),D=Object.create(this.lexer),j={yy:{}};for(var At in this.yy)Object.prototype.hasOwnProperty.call(this.yy,At)&&(j.yy[At]=this.yy[At]);D.setInput(s,j.yy),j.yy.lexer=D,j.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var kt=D.yylloc;e.push(kt);var me=D.options&&D.options.ranges;typeof j.yy.parseError=="function"?this.parseError=j.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function be(R){u.length=u.length-2*R,A.length=A.length-R,e.length=e.length-R}r(be,"popStack");function Jt(){var R;return R=d.pop()||D.lex()||Zt,typeof R!="number"&&(R instanceof Array&&(d=R,R=d.pop()),R=l.symbols_[R]||R),R}r(Jt,"lex");for(var B,G,W,Ft,rt={},pt,M,$t,yt;;){if(G=u[u.length-1],this.defaultActions[G]?W=this.defaultActions[G]:((B===null||typeof B>"u")&&(B=Jt()),W=ht[G]&&ht[G][B]),typeof W>"u"||!W.length||!W[0]){var Pt="";yt=[];for(pt in ht[G])this.terminals_[pt]&&pt>Te&&yt.push("'"+this.terminals_[pt]+"'");D.showPosition?Pt="Parse error on line "+(gt+1)+`: +import{s as Se,g as _e,p as ee,o as Ae,a as ke,b as Fe,_ as r,c as Et,l as qt,d as vt,e as Pe,q as ve,D as z,i as Ce,W as Le}from"./mermaid.core-CJB1tAev.js";import{l as te}from"./linear-DH49UJnN.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";import"./defaultLocale-DX6XiGOO.js";var Ct=(function(){var t=r(function(Y,s,l,u){for(l=l||{},u=Y.length;u--;l[Y[u]]=s);return l},"o"),a=[1,3],p=[1,4],f=[1,5],o=[1,6],x=[1,7],_=[1,4,5,10,12,13,14,15,18,25,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],h=[1,4,5,10,12,13,14,15,18,25,28,35,37,39,41,42,48,50,51,52,53,54,55,56,57,60,61,63,64,65,66,67],c=[55,56,57],S=[2,36],m=[1,37],b=[1,36],y=[1,38],T=[1,35],q=[1,43],g=[1,41],k=[1,45],ct=[1,14],dt=[1,23],ut=[1,18],xt=[1,19],ot=[1,20],bt=[1,21],lt=[1,22],i=[1,24],Dt=[1,25],zt=[1,26],Vt=[1,27],It=[1,28],wt=[1,29],U=[1,32],Q=[1,33],F=[1,34],P=[1,39],v=[1,40],C=[1,42],L=[1,44],H=[1,63],X=[1,62],E=[4,5,8,10,12,13,14,15,18,44,47,49,55,56,57,63,64,65,66,67],Bt=[1,66],Rt=[1,67],Nt=[1,68],Wt=[1,69],Ut=[1,70],Qt=[1,71],Ot=[1,72],Ht=[1,73],Xt=[1,74],Mt=[1,75],Yt=[1,76],jt=[1,77],w=[4,5,6,7,8,9,10,11,12,13,14,15,18],K=[1,91],Z=[1,92],J=[1,93],$=[1,100],tt=[1,94],et=[1,97],it=[1,95],at=[1,96],nt=[1,98],st=[1,99],St=[1,103],Gt=[10,55,56,57],N=[4,5,6,8,10,11,13,17,18,19,20,55,56,57],_t={trace:r(function(){},"trace"),yy:{},symbols_:{error:2,idStringToken:3,ALPHA:4,NUM:5,NODE_STRING:6,DOWN:7,MINUS:8,DEFAULT:9,COMMA:10,COLON:11,AMP:12,BRKT:13,MULT:14,UNICODE_TEXT:15,styleComponent:16,UNIT:17,SPACE:18,STYLE:19,PCT:20,idString:21,style:22,stylesOpt:23,classDefStatement:24,CLASSDEF:25,start:26,eol:27,QUADRANT:28,document:29,line:30,statement:31,axisDetails:32,quadrantDetails:33,points:34,title:35,title_value:36,acc_title:37,acc_title_value:38,acc_descr:39,acc_descr_value:40,acc_descr_multiline_value:41,section:42,text:43,point_start:44,point_x:45,point_y:46,class_name:47,"X-AXIS":48,"AXIS-TEXT-DELIMITER":49,"Y-AXIS":50,QUADRANT_1:51,QUADRANT_2:52,QUADRANT_3:53,QUADRANT_4:54,NEWLINE:55,SEMI:56,EOF:57,alphaNumToken:58,textNoTagsToken:59,STR:60,MD_STR:61,alphaNum:62,PUNCTUATION:63,PLUS:64,EQUALS:65,DOT:66,UNDERSCORE:67,$accept:0,$end:1},terminals_:{2:"error",4:"ALPHA",5:"NUM",6:"NODE_STRING",7:"DOWN",8:"MINUS",9:"DEFAULT",10:"COMMA",11:"COLON",12:"AMP",13:"BRKT",14:"MULT",15:"UNICODE_TEXT",17:"UNIT",18:"SPACE",19:"STYLE",20:"PCT",25:"CLASSDEF",28:"QUADRANT",35:"title",36:"title_value",37:"acc_title",38:"acc_title_value",39:"acc_descr",40:"acc_descr_value",41:"acc_descr_multiline_value",42:"section",44:"point_start",45:"point_x",46:"point_y",47:"class_name",48:"X-AXIS",49:"AXIS-TEXT-DELIMITER",50:"Y-AXIS",51:"QUADRANT_1",52:"QUADRANT_2",53:"QUADRANT_3",54:"QUADRANT_4",55:"NEWLINE",56:"SEMI",57:"EOF",60:"STR",61:"MD_STR",63:"PUNCTUATION",64:"PLUS",65:"EQUALS",66:"DOT",67:"UNDERSCORE"},productions_:[0,[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[3,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[16,1],[21,1],[21,2],[22,1],[22,2],[23,1],[23,3],[24,5],[26,2],[26,2],[26,2],[29,0],[29,2],[30,2],[31,0],[31,1],[31,2],[31,1],[31,1],[31,1],[31,2],[31,2],[31,2],[31,1],[31,1],[34,4],[34,5],[34,5],[34,6],[32,4],[32,3],[32,2],[32,4],[32,3],[32,2],[33,2],[33,2],[33,2],[33,2],[27,1],[27,1],[27,1],[43,1],[43,2],[43,1],[43,1],[62,1],[62,2],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[58,1],[59,1],[59,1],[59,1]],performAction:r(function(s,l,u,d,A,e,ht){var n=e.length-1;switch(A){case 23:this.$=e[n];break;case 24:this.$=e[n-1]+""+e[n];break;case 26:this.$=e[n-1]+e[n];break;case 27:this.$=[e[n].trim()];break;case 28:e[n-2].push(e[n].trim()),this.$=e[n-2];break;case 29:this.$=e[n-4],d.addClass(e[n-2],e[n]);break;case 37:this.$=[];break;case 42:this.$=e[n].trim(),d.setDiagramTitle(this.$);break;case 43:this.$=e[n].trim(),d.setAccTitle(this.$);break;case 44:case 45:this.$=e[n].trim(),d.setAccDescription(this.$);break;case 46:d.addSection(e[n].substr(8)),this.$=e[n].substr(8);break;case 47:d.addPoint(e[n-3],"",e[n-1],e[n],[]);break;case 48:d.addPoint(e[n-4],e[n-3],e[n-1],e[n],[]);break;case 49:d.addPoint(e[n-4],"",e[n-2],e[n-1],e[n]);break;case 50:d.addPoint(e[n-5],e[n-4],e[n-2],e[n-1],e[n]);break;case 51:d.setXAxisLeftText(e[n-2]),d.setXAxisRightText(e[n]);break;case 52:e[n-1].text+=" ⟶ ",d.setXAxisLeftText(e[n-1]);break;case 53:d.setXAxisLeftText(e[n]);break;case 54:d.setYAxisBottomText(e[n-2]),d.setYAxisTopText(e[n]);break;case 55:e[n-1].text+=" ⟶ ",d.setYAxisBottomText(e[n-1]);break;case 56:d.setYAxisBottomText(e[n]);break;case 57:d.setQuadrant1Text(e[n]);break;case 58:d.setQuadrant2Text(e[n]);break;case 59:d.setQuadrant3Text(e[n]);break;case 60:d.setQuadrant4Text(e[n]);break;case 64:this.$={text:e[n],type:"text"};break;case 65:this.$={text:e[n-1].text+""+e[n],type:e[n-1].type};break;case 66:this.$={text:e[n],type:"text"};break;case 67:this.$={text:e[n],type:"markdown"};break;case 68:this.$=e[n];break;case 69:this.$=e[n-1]+""+e[n];break}},"anonymous"),table:[{18:a,26:1,27:2,28:p,55:f,56:o,57:x},{1:[3]},{18:a,26:8,27:2,28:p,55:f,56:o,57:x},{18:a,26:9,27:2,28:p,55:f,56:o,57:x},t(_,[2,33],{29:10}),t(h,[2,61]),t(h,[2,62]),t(h,[2,63]),{1:[2,30]},{1:[2,31]},t(c,S,{30:11,31:12,24:13,32:15,33:16,34:17,43:30,58:31,1:[2,32],4:m,5:b,10:y,12:T,13:q,14:g,15:k,18:ct,25:dt,35:ut,37:xt,39:ot,41:bt,42:lt,48:i,50:Dt,51:zt,52:Vt,53:It,54:wt,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(_,[2,34]),{27:46,55:f,56:o,57:x},t(c,[2,37]),t(c,S,{24:13,32:15,33:16,34:17,43:30,58:31,31:47,4:m,5:b,10:y,12:T,13:q,14:g,15:k,18:ct,25:dt,35:ut,37:xt,39:ot,41:bt,42:lt,48:i,50:Dt,51:zt,52:Vt,53:It,54:wt,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(c,[2,39]),t(c,[2,40]),t(c,[2,41]),{36:[1,48]},{38:[1,49]},{40:[1,50]},t(c,[2,45]),t(c,[2,46]),{18:[1,51]},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:52,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:53,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:54,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:55,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:56,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,10:y,12:T,13:q,14:g,15:k,43:57,58:31,60:U,61:Q,63:F,64:P,65:v,66:C,67:L},{4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,44:[1,58],47:[1,59],58:61,59:60,63:F,64:P,65:v,66:C,67:L},t(E,[2,64]),t(E,[2,66]),t(E,[2,67]),t(E,[2,70]),t(E,[2,71]),t(E,[2,72]),t(E,[2,73]),t(E,[2,74]),t(E,[2,75]),t(E,[2,76]),t(E,[2,77]),t(E,[2,78]),t(E,[2,79]),t(E,[2,80]),t(E,[2,81]),t(_,[2,35]),t(c,[2,38]),t(c,[2,42]),t(c,[2,43]),t(c,[2,44]),{3:65,4:Bt,5:Rt,6:Nt,7:Wt,8:Ut,9:Qt,10:Ot,11:Ht,12:Xt,13:Mt,14:Yt,15:jt,21:64},t(c,[2,53],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,49:[1,78],63:F,64:P,65:v,66:C,67:L}),t(c,[2,56],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,49:[1,79],63:F,64:P,65:v,66:C,67:L}),t(c,[2,57],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,58],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,59],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,60],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),{45:[1,80]},{44:[1,81]},t(E,[2,65]),t(E,[2,82]),t(E,[2,83]),t(E,[2,84]),{3:83,4:Bt,5:Rt,6:Nt,7:Wt,8:Ut,9:Qt,10:Ot,11:Ht,12:Xt,13:Mt,14:Yt,15:jt,18:[1,82]},t(w,[2,23]),t(w,[2,1]),t(w,[2,2]),t(w,[2,3]),t(w,[2,4]),t(w,[2,5]),t(w,[2,6]),t(w,[2,7]),t(w,[2,8]),t(w,[2,9]),t(w,[2,10]),t(w,[2,11]),t(w,[2,12]),t(c,[2,52],{58:31,43:84,4:m,5:b,10:y,12:T,13:q,14:g,15:k,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),t(c,[2,55],{58:31,43:85,4:m,5:b,10:y,12:T,13:q,14:g,15:k,60:U,61:Q,63:F,64:P,65:v,66:C,67:L}),{46:[1,86]},{45:[1,87]},{4:K,5:Z,6:J,8:$,11:tt,13:et,16:90,17:it,18:at,19:nt,20:st,22:89,23:88},t(w,[2,24]),t(c,[2,51],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,54],{59:60,58:61,4:m,5:b,8:H,10:y,12:T,13:q,14:g,15:k,18:X,63:F,64:P,65:v,66:C,67:L}),t(c,[2,47],{22:89,16:90,23:101,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),{46:[1,102]},t(c,[2,29],{10:St}),t(Gt,[2,27],{16:104,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),t(N,[2,25]),t(N,[2,13]),t(N,[2,14]),t(N,[2,15]),t(N,[2,16]),t(N,[2,17]),t(N,[2,18]),t(N,[2,19]),t(N,[2,20]),t(N,[2,21]),t(N,[2,22]),t(c,[2,49],{10:St}),t(c,[2,48],{22:89,16:90,23:105,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st}),{4:K,5:Z,6:J,8:$,11:tt,13:et,16:90,17:it,18:at,19:nt,20:st,22:106},t(N,[2,26]),t(c,[2,50],{10:St}),t(Gt,[2,28],{16:104,4:K,5:Z,6:J,8:$,11:tt,13:et,17:it,18:at,19:nt,20:st})],defaultActions:{8:[2,30],9:[2,31]},parseError:r(function(s,l){if(l.recoverable)this.trace(s);else{var u=new Error(s);throw u.hash=l,u}},"parseError"),parse:r(function(s){var l=this,u=[0],d=[],A=[null],e=[],ht=this.table,n="",gt=0,Kt=0,Te=2,Zt=1,qe=e.slice.call(arguments,1),D=Object.create(this.lexer),j={yy:{}};for(var At in this.yy)Object.prototype.hasOwnProperty.call(this.yy,At)&&(j.yy[At]=this.yy[At]);D.setInput(s,j.yy),j.yy.lexer=D,j.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var kt=D.yylloc;e.push(kt);var me=D.options&&D.options.ranges;typeof j.yy.parseError=="function"?this.parseError=j.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function be(R){u.length=u.length-2*R,A.length=A.length-R,e.length=e.length-R}r(be,"popStack");function Jt(){var R;return R=d.pop()||D.lex()||Zt,typeof R!="number"&&(R instanceof Array&&(d=R,R=d.pop()),R=l.symbols_[R]||R),R}r(Jt,"lex");for(var B,G,W,Ft,rt={},pt,M,$t,yt;;){if(G=u[u.length-1],this.defaultActions[G]?W=this.defaultActions[G]:((B===null||typeof B>"u")&&(B=Jt()),W=ht[G]&&ht[G][B]),typeof W>"u"||!W.length||!W[0]){var Pt="";yt=[];for(pt in ht[G])this.terminals_[pt]&&pt>Te&&yt.push("'"+this.terminals_[pt]+"'");D.showPosition?Pt="Parse error on line "+(gt+1)+`: `+D.showPosition()+` Expecting `+yt.join(", ")+", got '"+(this.terminals_[B]||B)+"'":Pt="Parse error on line "+(gt+1)+": Unexpected "+(B==Zt?"end of input":"'"+(this.terminals_[B]||B)+"'"),this.parseError(Pt,{text:D.match,token:this.terminals_[B]||B,line:D.yylineno,loc:kt,expected:yt})}if(W[0]instanceof Array&&W.length>1)throw new Error("Parse Error: multiple actions possible at state: "+G+", token: "+B);switch(W[0]){case 1:u.push(B),A.push(D.yytext),e.push(D.yylloc),u.push(W[1]),B=null,Kt=D.yyleng,n=D.yytext,gt=D.yylineno,kt=D.yylloc;break;case 2:if(M=this.productions_[W[1]][1],rt.$=A[A.length-M],rt._$={first_line:e[e.length-(M||1)].first_line,last_line:e[e.length-1].last_line,first_column:e[e.length-(M||1)].first_column,last_column:e[e.length-1].last_column},me&&(rt._$.range=[e[e.length-(M||1)].range[0],e[e.length-1].range[1]]),Ft=this.performAction.apply(rt,[n,Kt,gt,j.yy,W[1],A,e].concat(qe)),typeof Ft<"u")return Ft;M&&(u=u.slice(0,-1*M*2),A=A.slice(0,-1*M),e=e.slice(0,-1*M)),u.push(this.productions_[W[1]][0]),A.push(rt.$),e.push(rt._$),$t=ht[u[u.length-2]][u[u.length-1]],u.push($t);break;case 3:return!0}}return!0},"parse")},ye=(function(){var Y={EOF:1,parseError:r(function(l,u){if(this.yy.parser)this.yy.parser.parseError(l,u);else throw new Error(l)},"parseError"),setInput:r(function(s,l){return this.yy=l||this.yy||{},this._input=s,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:r(function(){var s=this._input[0];this.yytext+=s,this.yyleng++,this.offset++,this.match+=s,this.matched+=s;var l=s.match(/(?:\r\n?|\n).*/g);return l?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),s},"input"),unput:r(function(s){var l=s.length,u=s.split(/(?:\r\n?|\n)/g);this._input=s+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-l),this.offset-=l;var d=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),u.length-1&&(this.yylineno-=u.length-1);var A=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:u?(u.length===d.length?this.yylloc.first_column:0)+d[d.length-u.length].length-u[0].length:this.yylloc.first_column-l},this.options.ranges&&(this.yylloc.range=[A[0],A[0]+this.yyleng-l]),this.yyleng=this.yytext.length,this},"unput"),more:r(function(){return this._more=!0,this},"more"),reject:r(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:r(function(s){this.unput(this.match.slice(s))},"less"),pastInput:r(function(){var s=this.matched.substr(0,this.matched.length-this.match.length);return(s.length>20?"...":"")+s.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:r(function(){var s=this.match;return s.length<20&&(s+=this._input.substr(0,20-s.length)),(s.substr(0,20)+(s.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:r(function(){var s=this.pastInput(),l=new Array(s.length+1).join("-");return s+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-BBlgCMW5.js b/apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-W9nf8fYD.js similarity index 84% rename from apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-BBlgCMW5.js rename to apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-W9nf8fYD.js index 2af4b656a..757f3d683 100644 --- a/apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-BBlgCMW5.js +++ b/apps/kimi-code/dist-web/assets/railroadDiagram-RFXS5EU6-W9nf8fYD.js @@ -1 +1 @@ -import{g as s,r as l,d as t}from"./chunk-MOJQB5TN-Ce2Y728v.js";import{p as m}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{_ as n,l as i}from"./mermaid.core-DaDTfY6S.js";import{M as p,c as u}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var d=u().Railroad.parser.LangiumParser,a=n(e=>{switch(e.$type){case"RailroadTerminalExpr":return{type:"terminal",value:e.value};case"RailroadNonTerminalExpr":return{type:"nonterminal",name:e.name};case"RailroadSpecialExpr":return{type:"special",text:e.text};case"RailroadSequenceExpr":{const r=e.elements.map(a);return r.length===1?r[0]:{type:"sequence",elements:r}}case"RailroadChoiceExpr":{const r=e.alternatives.map(a);return r.length===1?r[0]:{type:"choice",alternatives:r}}case"RailroadOptionalExpr":return{type:"optional",element:a(e.element)};case"RailroadOneOrMoreExpr":return{type:"repetition",element:a(e.element),min:1,max:1/0};case"RailroadZeroOrMoreExpr":return{type:"repetition",element:a(e.element),min:0,max:1/0};default:throw new Error(`Unsupported railroad expression: ${e.$type}`)}},"transformExpression"),c=n(e=>({name:e.name,definition:a(e.definition)}),"transformRule"),g=n(e=>{m(e,t),e.title&&t.setTitle(e.title),e.rules.map(r=>t.addRule(c(r)))},"populateDb"),y={parse:n(e=>{t.clear(),i.debug("[Railroad Parser] Starting Langium parse");const r=d.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new p(r);const o=r.value;i.debug("[Railroad Parser] Parsed rules:",o.rules.length),g(o),i.debug("[Railroad Parser] Parse complete")},"parse"),parser:{yy:t}},P={parser:y,db:t,renderer:l,styles:s};export{P as diagram}; +import{g as s,r as l,d as t}from"./chunk-MOJQB5TN-JQ2kJR9W.js";import{p as m}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{_ as n,l as i}from"./mermaid.core-CJB1tAev.js";import{M as p,c as u}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var d=u().Railroad.parser.LangiumParser,a=n(e=>{switch(e.$type){case"RailroadTerminalExpr":return{type:"terminal",value:e.value};case"RailroadNonTerminalExpr":return{type:"nonterminal",name:e.name};case"RailroadSpecialExpr":return{type:"special",text:e.text};case"RailroadSequenceExpr":{const r=e.elements.map(a);return r.length===1?r[0]:{type:"sequence",elements:r}}case"RailroadChoiceExpr":{const r=e.alternatives.map(a);return r.length===1?r[0]:{type:"choice",alternatives:r}}case"RailroadOptionalExpr":return{type:"optional",element:a(e.element)};case"RailroadOneOrMoreExpr":return{type:"repetition",element:a(e.element),min:1,max:1/0};case"RailroadZeroOrMoreExpr":return{type:"repetition",element:a(e.element),min:0,max:1/0};default:throw new Error(`Unsupported railroad expression: ${e.$type}`)}},"transformExpression"),c=n(e=>({name:e.name,definition:a(e.definition)}),"transformRule"),g=n(e=>{m(e,t),e.title&&t.setTitle(e.title),e.rules.map(r=>t.addRule(c(r)))},"populateDb"),y={parse:n(e=>{t.clear(),i.debug("[Railroad Parser] Starting Langium parse");const r=d.parse(e);if(r.lexerErrors.length>0||r.parserErrors.length>0)throw new p(r);const o=r.value;i.debug("[Railroad Parser] Parsed rules:",o.rules.length),g(o),i.debug("[Railroad Parser] Parse complete")},"parse"),parser:{yy:t}},P={parser:y,db:t,renderer:l,styles:s};export{P as diagram}; diff --git a/apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-B8hGppVZ.js b/apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-Bzvt0v7J.js similarity index 99% rename from apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-B8hGppVZ.js rename to apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-Bzvt0v7J.js index 07368fafc..7eb6523fe 100644 --- a/apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-B8hGppVZ.js +++ b/apps/kimi-code/dist-web/assets/requirementDiagram-TGXJPOKE-Bzvt0v7J.js @@ -1,4 +1,4 @@ -import{g as ze}from"./chunk-XXDRQBXY-BEgNawAD.js";import{s as Ge}from"./chunk-VR4S4FIN-Dzr2NgNj.js";import{_ as h,z as Ye,b as Xe,a as Je,s as Ze,g as et,o as tt,p as st,c as Te,l as Ne,q as it,u as rt,v as nt,x as at,y as lt}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var qe=(function(){var e=h(function($,r,a,c){for(a=a||{},c=$.length;c--;a[$[c]]=r);return a},"o"),u=[1,3],o=[1,4],n=[1,5],i=[1,6],f=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],_=[1,22],E=[2,7],g=[1,26],S=[1,27],k=[1,28],q=[1,29],C=[1,33],A=[1,34],V=[1,35],v=[1,36],L=[1,37],x=[1,38],O=[1,24],w=[1,31],D=[1,32],M=[1,30],p=[1,39],R=[1,40],d=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],P=[1,61],X=[89,90],Ce=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],de=[27,29],Ae=[1,70],Ve=[1,71],ve=[1,72],Le=[1,73],xe=[1,74],Oe=[1,75],we=[1,76],Z=[1,83],U=[1,80],ee=[1,84],te=[1,85],se=[1,86],ie=[1,87],re=[1,88],ne=[1,89],ae=[1,90],le=[1,91],ce=[1,92],Ee=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Y=[63,64],De=[1,101],Me=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],T=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],B=[1,110],Q=[1,106],H=[1,107],K=[1,108],W=[1,109],j=[1,111],oe=[1,116],he=[1,117],ue=[1,114],fe=[1,115],_e={trace:h(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:h(function(r,a,c,s,m,t,me){var l=t.length-1;switch(m){case 4:this.$=t[l].trim(),s.setAccTitle(this.$);break;case 5:case 6:this.$=t[l].trim(),s.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:s.setDirection("TB");break;case 18:s.setDirection("BT");break;case 19:s.setDirection("RL");break;case 20:s.setDirection("LR");break;case 21:s.addRequirement(t[l-3],t[l-4]);break;case 22:s.addRequirement(t[l-5],t[l-6]),s.setClass([t[l-5]],t[l-3]);break;case 23:s.setNewReqId(t[l-2]);break;case 24:s.setNewReqText(t[l-2]);break;case 25:s.setNewReqRisk(t[l-2]);break;case 26:s.setNewReqVerifyMethod(t[l-2]);break;case 29:this.$=s.RequirementType.REQUIREMENT;break;case 30:this.$=s.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=s.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=s.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=s.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=s.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=s.RiskLevel.LOW_RISK;break;case 36:this.$=s.RiskLevel.MED_RISK;break;case 37:this.$=s.RiskLevel.HIGH_RISK;break;case 38:this.$=s.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=s.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=s.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=s.VerifyType.VERIFY_TEST;break;case 42:s.addElement(t[l-3]);break;case 43:s.addElement(t[l-5]),s.setClass([t[l-5]],t[l-3]);break;case 44:s.setNewElementType(t[l-2]);break;case 45:s.setNewElementDocRef(t[l-2]);break;case 48:s.addRelationship(t[l-2],t[l],t[l-4]);break;case 49:s.addRelationship(t[l-2],t[l-4],t[l]);break;case 50:this.$=s.Relationships.CONTAINS;break;case 51:this.$=s.Relationships.COPIES;break;case 52:this.$=s.Relationships.DERIVES;break;case 53:this.$=s.Relationships.SATISFIES;break;case 54:this.$=s.Relationships.VERIFIES;break;case 55:this.$=s.Relationships.REFINES;break;case 56:this.$=s.Relationships.TRACES;break;case 57:this.$=t[l-2],s.defineClass(t[l-1],t[l]);break;case 58:s.setClass(t[l-1],t[l]);break;case 59:s.setClass([t[l-2]],t[l]);break;case 60:case 62:this.$=[t[l]];break;case 61:case 63:this.$=t[l-2].concat([t[l]]);break;case 64:this.$=t[l-2],s.setCssStyle(t[l-1],t[l]);break;case 65:this.$=[t[l]];break;case 66:t[l-2].push(t[l]),this.$=t[l-2];break;case 68:this.$=t[l-1]+t[l];break}},"anonymous"),table:[{3:1,4:2,6:u,9:o,11:n,13:i},{1:[3]},{3:8,4:2,5:[1,7],6:u,9:o,11:n,13:i},{5:[1,9]},{10:[1,10]},{12:[1,11]},e(f,[2,6]),{3:12,4:2,6:u,9:o,11:n,13:i},{1:[2,2]},{4:17,5:_,7:13,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},e(f,[2,4]),e(f,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:_,7:42,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:43,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:44,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:45,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:46,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:47,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:48,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:49,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:50,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},e(d,[2,17]),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),{30:60,33:62,75:P,89:p,90:R},{30:63,33:62,75:P,89:p,90:R},{30:64,33:62,75:P,89:p,90:R},e(X,[2,29]),e(X,[2,30]),e(X,[2,31]),e(X,[2,32]),e(X,[2,33]),e(X,[2,34]),e(Ce,[2,81]),e(Ce,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},e(de,[2,79]),e(de,[2,80]),{27:[1,67],29:[1,68]},e(de,[2,85]),e(de,[2,86]),{62:69,65:Ae,66:Ve,67:ve,68:Le,69:xe,70:Oe,71:we},{62:77,65:Ae,66:Ve,67:ve,68:Le,69:xe,70:Oe,71:we},{30:78,33:62,75:P,89:p,90:R},{73:79,75:Z,76:U,78:81,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},e(Ee,[2,60]),e(Ee,[2,62]),{73:93,75:Z,76:U,78:81,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},{30:94,33:62,75:P,76:U,89:p,90:R},{5:[1,95]},{30:96,33:62,75:P,89:p,90:R},{5:[1,97]},{30:98,33:62,75:P,89:p,90:R},{63:[1,99]},e(Y,[2,50]),e(Y,[2,51]),e(Y,[2,52]),e(Y,[2,53]),e(Y,[2,54]),e(Y,[2,55]),e(Y,[2,56]),{64:[1,100]},e(d,[2,59],{76:U}),e(d,[2,64],{76:De}),{33:103,75:[1,102],89:p,90:R},e(Me,[2,65],{79:104,75:Z,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce}),e(T,[2,67]),e(T,[2,69]),e(T,[2,70]),e(T,[2,71]),e(T,[2,72]),e(T,[2,73]),e(T,[2,74]),e(T,[2,75]),e(T,[2,76]),e(T,[2,77]),e(T,[2,78]),e(d,[2,57],{76:De}),e(d,[2,58],{76:U}),{5:B,28:105,31:Q,34:H,36:K,38:W,40:j},{27:[1,112],76:U},{5:oe,40:he,56:113,57:ue,59:fe},{27:[1,118],76:U},{33:119,89:p,90:R},{33:120,89:p,90:R},{75:Z,78:121,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},e(Ee,[2,61]),e(Ee,[2,63]),e(T,[2,68]),e(d,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:B,28:126,31:Q,34:H,36:K,38:W,40:j},e(d,[2,28]),{5:[1,127]},e(d,[2,42]),{32:[1,128]},{32:[1,129]},{5:oe,40:he,56:130,57:ue,59:fe},e(d,[2,47]),{5:[1,131]},e(d,[2,48]),e(d,[2,49]),e(Me,[2,66],{79:104,75:Z,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce}),{33:132,89:p,90:R},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},e(d,[2,27]),{5:B,28:145,31:Q,34:H,36:K,38:W,40:j},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},e(d,[2,46]),{5:oe,40:he,56:152,57:ue,59:fe},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},e(d,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},e(d,[2,43]),{5:B,28:159,31:Q,34:H,36:K,38:W,40:j},{5:B,28:160,31:Q,34:H,36:K,38:W,40:j},{5:B,28:161,31:Q,34:H,36:K,38:W,40:j},{5:B,28:162,31:Q,34:H,36:K,38:W,40:j},{5:oe,40:he,56:163,57:ue,59:fe},{5:oe,40:he,56:164,57:ue,59:fe},e(d,[2,23]),e(d,[2,24]),e(d,[2,25]),e(d,[2,26]),e(d,[2,44]),e(d,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:h(function(r,a){if(a.recoverable)this.trace(r);else{var c=new Error(r);throw c.hash=a,c}},"parseError"),parse:h(function(r){var a=this,c=[0],s=[],m=[null],t=[],me=this.table,l="",Re=0,Fe=0,He=2,$e=1,Ke=t.slice.call(arguments,1),y=Object.create(this.lexer),z={yy:{}};for(var Se in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Se)&&(z.yy[Se]=this.yy[Se]);y.setInput(r,z.yy),z.yy.lexer=y,z.yy.parser=this,typeof y.yylloc>"u"&&(y.yylloc={});var be=y.yylloc;t.push(be);var We=y.options&&y.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function je(I){c.length=c.length-2*I,m.length=m.length-I,t.length=t.length-I}h(je,"popStack");function Pe(){var I;return I=s.pop()||y.lex()||$e,typeof I!="number"&&(I instanceof Array&&(s=I,I=s.pop()),I=a.symbols_[I]||I),I}h(Pe,"lex");for(var b,G,N,Ie,J={},ge,F,Ue,ye;;){if(G=c[c.length-1],this.defaultActions[G]?N=this.defaultActions[G]:((b===null||typeof b>"u")&&(b=Pe()),N=me[G]&&me[G][b]),typeof N>"u"||!N.length||!N[0]){var ke="";ye=[];for(ge in me[G])this.terminals_[ge]&&ge>He&&ye.push("'"+this.terminals_[ge]+"'");y.showPosition?ke="Parse error on line "+(Re+1)+`: +import{g as ze}from"./chunk-XXDRQBXY-5rh7CWvm.js";import{s as Ge}from"./chunk-VR4S4FIN-CEH7JYJn.js";import{_ as h,z as Ye,b as Xe,a as Je,s as Ze,g as et,o as tt,p as st,c as Te,l as Ne,q as it,u as rt,v as nt,x as at,y as lt}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var qe=(function(){var e=h(function($,r,a,c){for(a=a||{},c=$.length;c--;a[$[c]]=r);return a},"o"),u=[1,3],o=[1,4],n=[1,5],i=[1,6],f=[5,6,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],_=[1,22],E=[2,7],g=[1,26],S=[1,27],k=[1,28],q=[1,29],C=[1,33],A=[1,34],V=[1,35],v=[1,36],L=[1,37],x=[1,38],O=[1,24],w=[1,31],D=[1,32],M=[1,30],p=[1,39],R=[1,40],d=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,77,89,90],P=[1,61],X=[89,90],Ce=[5,8,9,11,13,21,22,23,24,27,29,41,42,43,44,45,46,54,61,63,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],de=[27,29],Ae=[1,70],Ve=[1,71],ve=[1,72],Le=[1,73],xe=[1,74],Oe=[1,75],we=[1,76],Z=[1,83],U=[1,80],ee=[1,84],te=[1,85],se=[1,86],ie=[1,87],re=[1,88],ne=[1,89],ae=[1,90],le=[1,91],ce=[1,92],Ee=[5,8,9,11,13,21,22,23,24,27,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],Y=[63,64],De=[1,101],Me=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,76,77,89,90],T=[5,8,9,11,13,21,22,23,24,41,42,43,44,45,46,54,72,74,75,76,77,80,81,82,83,84,85,86,87,88,89,90],B=[1,110],Q=[1,106],H=[1,107],K=[1,108],W=[1,109],j=[1,111],oe=[1,116],he=[1,117],ue=[1,114],fe=[1,115],_e={trace:h(function(){},"trace"),yy:{},symbols_:{error:2,start:3,directive:4,NEWLINE:5,RD:6,diagram:7,EOF:8,acc_title:9,acc_title_value:10,acc_descr:11,acc_descr_value:12,acc_descr_multiline_value:13,requirementDef:14,elementDef:15,relationshipDef:16,direction:17,styleStatement:18,classDefStatement:19,classStatement:20,direction_tb:21,direction_bt:22,direction_rl:23,direction_lr:24,requirementType:25,requirementName:26,STRUCT_START:27,requirementBody:28,STYLE_SEPARATOR:29,idList:30,ID:31,COLONSEP:32,id:33,TEXT:34,text:35,RISK:36,riskLevel:37,VERIFYMTHD:38,verifyType:39,STRUCT_STOP:40,REQUIREMENT:41,FUNCTIONAL_REQUIREMENT:42,INTERFACE_REQUIREMENT:43,PERFORMANCE_REQUIREMENT:44,PHYSICAL_REQUIREMENT:45,DESIGN_CONSTRAINT:46,LOW_RISK:47,MED_RISK:48,HIGH_RISK:49,VERIFY_ANALYSIS:50,VERIFY_DEMONSTRATION:51,VERIFY_INSPECTION:52,VERIFY_TEST:53,ELEMENT:54,elementName:55,elementBody:56,TYPE:57,type:58,DOCREF:59,ref:60,END_ARROW_L:61,relationship:62,LINE:63,END_ARROW_R:64,CONTAINS:65,COPIES:66,DERIVES:67,SATISFIES:68,VERIFIES:69,REFINES:70,TRACES:71,CLASSDEF:72,stylesOpt:73,CLASS:74,ALPHA:75,COMMA:76,STYLE:77,style:78,styleComponent:79,NUM:80,COLON:81,UNIT:82,SPACE:83,BRKT:84,PCT:85,MINUS:86,LABEL:87,SEMICOLON:88,unqString:89,qString:90,$accept:0,$end:1},terminals_:{2:"error",5:"NEWLINE",6:"RD",8:"EOF",9:"acc_title",10:"acc_title_value",11:"acc_descr",12:"acc_descr_value",13:"acc_descr_multiline_value",21:"direction_tb",22:"direction_bt",23:"direction_rl",24:"direction_lr",27:"STRUCT_START",29:"STYLE_SEPARATOR",31:"ID",32:"COLONSEP",34:"TEXT",36:"RISK",38:"VERIFYMTHD",40:"STRUCT_STOP",41:"REQUIREMENT",42:"FUNCTIONAL_REQUIREMENT",43:"INTERFACE_REQUIREMENT",44:"PERFORMANCE_REQUIREMENT",45:"PHYSICAL_REQUIREMENT",46:"DESIGN_CONSTRAINT",47:"LOW_RISK",48:"MED_RISK",49:"HIGH_RISK",50:"VERIFY_ANALYSIS",51:"VERIFY_DEMONSTRATION",52:"VERIFY_INSPECTION",53:"VERIFY_TEST",54:"ELEMENT",57:"TYPE",59:"DOCREF",61:"END_ARROW_L",63:"LINE",64:"END_ARROW_R",65:"CONTAINS",66:"COPIES",67:"DERIVES",68:"SATISFIES",69:"VERIFIES",70:"REFINES",71:"TRACES",72:"CLASSDEF",74:"CLASS",75:"ALPHA",76:"COMMA",77:"STYLE",80:"NUM",81:"COLON",82:"UNIT",83:"SPACE",84:"BRKT",85:"PCT",86:"MINUS",87:"LABEL",88:"SEMICOLON",89:"unqString",90:"qString"},productions_:[0,[3,3],[3,2],[3,4],[4,2],[4,2],[4,1],[7,0],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[7,2],[17,1],[17,1],[17,1],[17,1],[14,5],[14,7],[28,5],[28,5],[28,5],[28,5],[28,2],[28,1],[25,1],[25,1],[25,1],[25,1],[25,1],[25,1],[37,1],[37,1],[37,1],[39,1],[39,1],[39,1],[39,1],[15,5],[15,7],[56,5],[56,5],[56,2],[56,1],[16,5],[16,5],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[62,1],[19,3],[20,3],[20,3],[30,1],[30,3],[30,1],[30,3],[18,3],[73,1],[73,3],[78,1],[78,2],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[79,1],[26,1],[26,1],[33,1],[33,1],[35,1],[35,1],[55,1],[55,1],[58,1],[58,1],[60,1],[60,1]],performAction:h(function(r,a,c,s,m,t,me){var l=t.length-1;switch(m){case 4:this.$=t[l].trim(),s.setAccTitle(this.$);break;case 5:case 6:this.$=t[l].trim(),s.setAccDescription(this.$);break;case 7:this.$=[];break;case 17:s.setDirection("TB");break;case 18:s.setDirection("BT");break;case 19:s.setDirection("RL");break;case 20:s.setDirection("LR");break;case 21:s.addRequirement(t[l-3],t[l-4]);break;case 22:s.addRequirement(t[l-5],t[l-6]),s.setClass([t[l-5]],t[l-3]);break;case 23:s.setNewReqId(t[l-2]);break;case 24:s.setNewReqText(t[l-2]);break;case 25:s.setNewReqRisk(t[l-2]);break;case 26:s.setNewReqVerifyMethod(t[l-2]);break;case 29:this.$=s.RequirementType.REQUIREMENT;break;case 30:this.$=s.RequirementType.FUNCTIONAL_REQUIREMENT;break;case 31:this.$=s.RequirementType.INTERFACE_REQUIREMENT;break;case 32:this.$=s.RequirementType.PERFORMANCE_REQUIREMENT;break;case 33:this.$=s.RequirementType.PHYSICAL_REQUIREMENT;break;case 34:this.$=s.RequirementType.DESIGN_CONSTRAINT;break;case 35:this.$=s.RiskLevel.LOW_RISK;break;case 36:this.$=s.RiskLevel.MED_RISK;break;case 37:this.$=s.RiskLevel.HIGH_RISK;break;case 38:this.$=s.VerifyType.VERIFY_ANALYSIS;break;case 39:this.$=s.VerifyType.VERIFY_DEMONSTRATION;break;case 40:this.$=s.VerifyType.VERIFY_INSPECTION;break;case 41:this.$=s.VerifyType.VERIFY_TEST;break;case 42:s.addElement(t[l-3]);break;case 43:s.addElement(t[l-5]),s.setClass([t[l-5]],t[l-3]);break;case 44:s.setNewElementType(t[l-2]);break;case 45:s.setNewElementDocRef(t[l-2]);break;case 48:s.addRelationship(t[l-2],t[l],t[l-4]);break;case 49:s.addRelationship(t[l-2],t[l-4],t[l]);break;case 50:this.$=s.Relationships.CONTAINS;break;case 51:this.$=s.Relationships.COPIES;break;case 52:this.$=s.Relationships.DERIVES;break;case 53:this.$=s.Relationships.SATISFIES;break;case 54:this.$=s.Relationships.VERIFIES;break;case 55:this.$=s.Relationships.REFINES;break;case 56:this.$=s.Relationships.TRACES;break;case 57:this.$=t[l-2],s.defineClass(t[l-1],t[l]);break;case 58:s.setClass(t[l-1],t[l]);break;case 59:s.setClass([t[l-2]],t[l]);break;case 60:case 62:this.$=[t[l]];break;case 61:case 63:this.$=t[l-2].concat([t[l]]);break;case 64:this.$=t[l-2],s.setCssStyle(t[l-1],t[l]);break;case 65:this.$=[t[l]];break;case 66:t[l-2].push(t[l]),this.$=t[l-2];break;case 68:this.$=t[l-1]+t[l];break}},"anonymous"),table:[{3:1,4:2,6:u,9:o,11:n,13:i},{1:[3]},{3:8,4:2,5:[1,7],6:u,9:o,11:n,13:i},{5:[1,9]},{10:[1,10]},{12:[1,11]},e(f,[2,6]),{3:12,4:2,6:u,9:o,11:n,13:i},{1:[2,2]},{4:17,5:_,7:13,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},e(f,[2,4]),e(f,[2,5]),{1:[2,1]},{8:[1,41]},{4:17,5:_,7:42,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:43,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:44,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:45,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:46,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:47,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:48,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:49,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{4:17,5:_,7:50,8:E,9:o,11:n,13:i,14:14,15:15,16:16,17:18,18:19,19:20,20:21,21:g,22:S,23:k,24:q,25:23,33:25,41:C,42:A,43:V,44:v,45:L,46:x,54:O,72:w,74:D,77:M,89:p,90:R},{26:51,89:[1,52],90:[1,53]},{55:54,89:[1,55],90:[1,56]},{29:[1,59],61:[1,57],63:[1,58]},e(d,[2,17]),e(d,[2,18]),e(d,[2,19]),e(d,[2,20]),{30:60,33:62,75:P,89:p,90:R},{30:63,33:62,75:P,89:p,90:R},{30:64,33:62,75:P,89:p,90:R},e(X,[2,29]),e(X,[2,30]),e(X,[2,31]),e(X,[2,32]),e(X,[2,33]),e(X,[2,34]),e(Ce,[2,81]),e(Ce,[2,82]),{1:[2,3]},{8:[2,8]},{8:[2,9]},{8:[2,10]},{8:[2,11]},{8:[2,12]},{8:[2,13]},{8:[2,14]},{8:[2,15]},{8:[2,16]},{27:[1,65],29:[1,66]},e(de,[2,79]),e(de,[2,80]),{27:[1,67],29:[1,68]},e(de,[2,85]),e(de,[2,86]),{62:69,65:Ae,66:Ve,67:ve,68:Le,69:xe,70:Oe,71:we},{62:77,65:Ae,66:Ve,67:ve,68:Le,69:xe,70:Oe,71:we},{30:78,33:62,75:P,89:p,90:R},{73:79,75:Z,76:U,78:81,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},e(Ee,[2,60]),e(Ee,[2,62]),{73:93,75:Z,76:U,78:81,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},{30:94,33:62,75:P,76:U,89:p,90:R},{5:[1,95]},{30:96,33:62,75:P,89:p,90:R},{5:[1,97]},{30:98,33:62,75:P,89:p,90:R},{63:[1,99]},e(Y,[2,50]),e(Y,[2,51]),e(Y,[2,52]),e(Y,[2,53]),e(Y,[2,54]),e(Y,[2,55]),e(Y,[2,56]),{64:[1,100]},e(d,[2,59],{76:U}),e(d,[2,64],{76:De}),{33:103,75:[1,102],89:p,90:R},e(Me,[2,65],{79:104,75:Z,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce}),e(T,[2,67]),e(T,[2,69]),e(T,[2,70]),e(T,[2,71]),e(T,[2,72]),e(T,[2,73]),e(T,[2,74]),e(T,[2,75]),e(T,[2,76]),e(T,[2,77]),e(T,[2,78]),e(d,[2,57],{76:De}),e(d,[2,58],{76:U}),{5:B,28:105,31:Q,34:H,36:K,38:W,40:j},{27:[1,112],76:U},{5:oe,40:he,56:113,57:ue,59:fe},{27:[1,118],76:U},{33:119,89:p,90:R},{33:120,89:p,90:R},{75:Z,78:121,79:82,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce},e(Ee,[2,61]),e(Ee,[2,63]),e(T,[2,68]),e(d,[2,21]),{32:[1,122]},{32:[1,123]},{32:[1,124]},{32:[1,125]},{5:B,28:126,31:Q,34:H,36:K,38:W,40:j},e(d,[2,28]),{5:[1,127]},e(d,[2,42]),{32:[1,128]},{32:[1,129]},{5:oe,40:he,56:130,57:ue,59:fe},e(d,[2,47]),{5:[1,131]},e(d,[2,48]),e(d,[2,49]),e(Me,[2,66],{79:104,75:Z,80:ee,81:te,82:se,83:ie,84:re,85:ne,86:ae,87:le,88:ce}),{33:132,89:p,90:R},{35:133,89:[1,134],90:[1,135]},{37:136,47:[1,137],48:[1,138],49:[1,139]},{39:140,50:[1,141],51:[1,142],52:[1,143],53:[1,144]},e(d,[2,27]),{5:B,28:145,31:Q,34:H,36:K,38:W,40:j},{58:146,89:[1,147],90:[1,148]},{60:149,89:[1,150],90:[1,151]},e(d,[2,46]),{5:oe,40:he,56:152,57:ue,59:fe},{5:[1,153]},{5:[1,154]},{5:[2,83]},{5:[2,84]},{5:[1,155]},{5:[2,35]},{5:[2,36]},{5:[2,37]},{5:[1,156]},{5:[2,38]},{5:[2,39]},{5:[2,40]},{5:[2,41]},e(d,[2,22]),{5:[1,157]},{5:[2,87]},{5:[2,88]},{5:[1,158]},{5:[2,89]},{5:[2,90]},e(d,[2,43]),{5:B,28:159,31:Q,34:H,36:K,38:W,40:j},{5:B,28:160,31:Q,34:H,36:K,38:W,40:j},{5:B,28:161,31:Q,34:H,36:K,38:W,40:j},{5:B,28:162,31:Q,34:H,36:K,38:W,40:j},{5:oe,40:he,56:163,57:ue,59:fe},{5:oe,40:he,56:164,57:ue,59:fe},e(d,[2,23]),e(d,[2,24]),e(d,[2,25]),e(d,[2,26]),e(d,[2,44]),e(d,[2,45])],defaultActions:{8:[2,2],12:[2,1],41:[2,3],42:[2,8],43:[2,9],44:[2,10],45:[2,11],46:[2,12],47:[2,13],48:[2,14],49:[2,15],50:[2,16],134:[2,83],135:[2,84],137:[2,35],138:[2,36],139:[2,37],141:[2,38],142:[2,39],143:[2,40],144:[2,41],147:[2,87],148:[2,88],150:[2,89],151:[2,90]},parseError:h(function(r,a){if(a.recoverable)this.trace(r);else{var c=new Error(r);throw c.hash=a,c}},"parseError"),parse:h(function(r){var a=this,c=[0],s=[],m=[null],t=[],me=this.table,l="",Re=0,Fe=0,He=2,$e=1,Ke=t.slice.call(arguments,1),y=Object.create(this.lexer),z={yy:{}};for(var Se in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Se)&&(z.yy[Se]=this.yy[Se]);y.setInput(r,z.yy),z.yy.lexer=y,z.yy.parser=this,typeof y.yylloc>"u"&&(y.yylloc={});var be=y.yylloc;t.push(be);var We=y.options&&y.options.ranges;typeof z.yy.parseError=="function"?this.parseError=z.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function je(I){c.length=c.length-2*I,m.length=m.length-I,t.length=t.length-I}h(je,"popStack");function Pe(){var I;return I=s.pop()||y.lex()||$e,typeof I!="number"&&(I instanceof Array&&(s=I,I=s.pop()),I=a.symbols_[I]||I),I}h(Pe,"lex");for(var b,G,N,Ie,J={},ge,F,Ue,ye;;){if(G=c[c.length-1],this.defaultActions[G]?N=this.defaultActions[G]:((b===null||typeof b>"u")&&(b=Pe()),N=me[G]&&me[G][b]),typeof N>"u"||!N.length||!N[0]){var ke="";ye=[];for(ge in me[G])this.terminals_[ge]&&ge>He&&ye.push("'"+this.terminals_[ge]+"'");y.showPosition?ke="Parse error on line "+(Re+1)+`: `+y.showPosition()+` Expecting `+ye.join(", ")+", got '"+(this.terminals_[b]||b)+"'":ke="Parse error on line "+(Re+1)+": Unexpected "+(b==$e?"end of input":"'"+(this.terminals_[b]||b)+"'"),this.parseError(ke,{text:y.match,token:this.terminals_[b]||b,line:y.yylineno,loc:be,expected:ye})}if(N[0]instanceof Array&&N.length>1)throw new Error("Parse Error: multiple actions possible at state: "+G+", token: "+b);switch(N[0]){case 1:c.push(b),m.push(y.yytext),t.push(y.yylloc),c.push(N[1]),b=null,Fe=y.yyleng,l=y.yytext,Re=y.yylineno,be=y.yylloc;break;case 2:if(F=this.productions_[N[1]][1],J.$=m[m.length-F],J._$={first_line:t[t.length-(F||1)].first_line,last_line:t[t.length-1].last_line,first_column:t[t.length-(F||1)].first_column,last_column:t[t.length-1].last_column},We&&(J._$.range=[t[t.length-(F||1)].range[0],t[t.length-1].range[1]]),Ie=this.performAction.apply(J,[l,Fe,Re,z.yy,N[1],m,t].concat(Ke)),typeof Ie<"u")return Ie;F&&(c=c.slice(0,-1*F*2),m=m.slice(0,-1*F),t=t.slice(0,-1*F)),c.push(this.productions_[N[1]][0]),m.push(J.$),t.push(J._$),Ue=me[c[c.length-2]][c[c.length-1]],c.push(Ue);break;case 3:return!0}}return!0},"parse")},Qe=(function(){var $={EOF:1,parseError:h(function(a,c){if(this.yy.parser)this.yy.parser.parseError(a,c);else throw new Error(a)},"parseError"),setInput:h(function(r,a){return this.yy=a||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:h(function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var a=r.match(/(?:\r\n?|\n).*/g);return a?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},"input"),unput:h(function(r){var a=r.length,c=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-a),this.offset-=a;var s=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),c.length-1&&(this.yylineno-=c.length-1);var m=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:c?(c.length===s.length?this.yylloc.first_column:0)+s[s.length-c.length].length-c[0].length:this.yylloc.first_column-a},this.options.ranges&&(this.yylloc.range=[m[0],m[0]+this.yyleng-a]),this.yyleng=this.yytext.length,this},"unput"),more:h(function(){return this._more=!0,this},"more"),reject:h(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:h(function(r){this.unput(this.match.slice(r))},"less"),pastInput:h(function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:h(function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:h(function(){var r=this.pastInput(),a=new Array(r.length+1).join("-");return r+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-BhsqMuTt.js b/apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-B5WnWxzh.js similarity index 99% rename from apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-BhsqMuTt.js rename to apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-B5WnWxzh.js index 5c2a62728..03db105c5 100644 --- a/apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-BhsqMuTt.js +++ b/apps/kimi-code/dist-web/assets/sankeyDiagram-HTMAVEWB-B5WnWxzh.js @@ -1,4 +1,4 @@ -import{o as kt,p as mt,s as xt,g as _t,b as vt,a as bt,_ as y,c as ot,b8 as St,d as G,ad as wt,q as Lt,k as Et}from"./mermaid.core-DaDTfY6S.js";import{o as At}from"./ordinal-Cboi1Yqb.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function Tt(t){for(var i=t.length/6|0,s=new Array(i),l=0;l<i;)s[l]="#"+t.slice(l*6,++l*6);return s}const Mt=Tt("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function at(t,i){let s;if(i===void 0)for(const l of t)l!=null&&(s<l||s===void 0&&l>=l)&&(s=l);else{let l=-1;for(let u of t)(u=i(u,++l,t))!=null&&(s<u||s===void 0&&u>=u)&&(s=u)}return s}function dt(t,i){let s;if(i===void 0)for(const l of t)l!=null&&(s>l||s===void 0&&l>=l)&&(s=l);else{let l=-1;for(let u of t)(u=i(u,++l,t))!=null&&(s>u||s===void 0&&u>=u)&&(s=u)}return s}function J(t,i){let s=0;if(i===void 0)for(let l of t)(l=+l)&&(s+=l);else{let l=-1;for(let u of t)(u=+i(u,++l,t))&&(s+=u)}return s}function Nt(t){return t.target.depth}function Ct(t){return t.depth}function Pt(t,i){return i-1-t.height}function gt(t,i){return t.sourceLinks.length?t.depth:i-1}function It(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?dt(t.sourceLinks,Nt)-1:0}function Y(t){return function(){return t}}function lt(t,i){return q(t.source,i.source)||t.index-i.index}function ct(t,i){return q(t.target,i.target)||t.index-i.index}function q(t,i){return t.y0-i.y0}function tt(t){return t.value}function Ot(t){return t.index}function $t(t){return t.nodes}function Dt(t){return t.links}function ut(t,i){const s=t.get(i);if(!s)throw new Error("missing: "+i);return s}function ht({nodes:t}){for(const i of t){let s=i.y0,l=s;for(const u of i.sourceLinks)u.y0=s+u.width/2,s+=u.width;for(const u of i.targetLinks)u.y1=l+u.width/2,l+=u.width}}function jt(){let t=0,i=0,s=1,l=1,u=24,x=8,g,k=Ot,o=gt,a,h,m=$t,_=Dt,d=6;function v(){const n={nodes:m.apply(null,arguments),links:_.apply(null,arguments)};return T(n),A(n),M(n),I(n),S(n),ht(n),n}v.update=function(n){return ht(n),n},v.nodeId=function(n){return arguments.length?(k=typeof n=="function"?n:Y(n),v):k},v.nodeAlign=function(n){return arguments.length?(o=typeof n=="function"?n:Y(n),v):o},v.nodeSort=function(n){return arguments.length?(a=n,v):a},v.nodeWidth=function(n){return arguments.length?(u=+n,v):u},v.nodePadding=function(n){return arguments.length?(x=g=+n,v):x},v.nodes=function(n){return arguments.length?(m=typeof n=="function"?n:Y(n),v):m},v.links=function(n){return arguments.length?(_=typeof n=="function"?n:Y(n),v):_},v.linkSort=function(n){return arguments.length?(h=n,v):h},v.size=function(n){return arguments.length?(t=i=0,s=+n[0],l=+n[1],v):[s-t,l-i]},v.extent=function(n){return arguments.length?(t=+n[0][0],s=+n[1][0],i=+n[0][1],l=+n[1][1],v):[[t,i],[s,l]]},v.iterations=function(n){return arguments.length?(d=+n,v):d};function T({nodes:n,links:f}){for(const[e,r]of n.entries())r.index=e,r.sourceLinks=[],r.targetLinks=[];const c=new Map(n.map((e,r)=>[k(e,r,n),e]));for(const[e,r]of f.entries()){r.index=e;let{source:p,target:b}=r;typeof p!="object"&&(p=r.source=ut(c,p)),typeof b!="object"&&(b=r.target=ut(c,b)),p.sourceLinks.push(r),b.targetLinks.push(r)}if(h!=null)for(const{sourceLinks:e,targetLinks:r}of n)e.sort(h),r.sort(h)}function A({nodes:n}){for(const f of n)f.value=f.fixedValue===void 0?Math.max(J(f.sourceLinks,tt),J(f.targetLinks,tt)):f.fixedValue}function M({nodes:n}){const f=n.length;let c=new Set(n),e=new Set,r=0;for(;c.size;){for(const p of c){p.depth=r;for(const{target:b}of p.sourceLinks)e.add(b)}if(++r>f)throw new Error("circular link");c=e,e=new Set}}function I({nodes:n}){const f=n.length;let c=new Set(n),e=new Set,r=0;for(;c.size;){for(const p of c){p.height=r;for(const{source:b}of p.targetLinks)e.add(b)}if(++r>f)throw new Error("circular link");c=e,e=new Set}}function N({nodes:n}){const f=at(n,r=>r.depth)+1,c=(s-t-u)/(f-1),e=new Array(f);for(const r of n){const p=Math.max(0,Math.min(f-1,Math.floor(o.call(null,r,f))));r.layer=p,r.x0=t+p*c,r.x1=r.x0+u,e[p]?e[p].push(r):e[p]=[r]}if(a)for(const r of e)r.sort(a);return e}function $(n){const f=dt(n,c=>(l-i-(c.length-1)*g)/J(c,tt));for(const c of n){let e=i;for(const r of c){r.y0=e,r.y1=e+r.value*f,e=r.y1+g;for(const p of r.sourceLinks)p.width=p.value*f}e=(l-e+g)/(c.length+1);for(let r=0;r<c.length;++r){const p=c[r];p.y0+=e*(r+1),p.y1+=e*(r+1)}w(c)}}function S(n){const f=N(n);g=Math.min(x,(l-i)/(at(f,c=>c.length)-1)),$(f);for(let c=0;c<d;++c){const e=Math.pow(.99,c),r=Math.max(1-e,(c+1)/d);F(f,e,r),C(f,e,r)}}function C(n,f,c){for(let e=1,r=n.length;e<r;++e){const p=n[e];for(const b of p){let L=0,z=0;for(const{source:W,value:Z}of b.targetLinks){let U=Z*(b.layer-W.layer);L+=P(W,b)*U,z+=U}if(!(z>0))continue;let V=(L/z-b.y0)*f;b.y0+=V,b.y1+=V,j(b)}a===void 0&&p.sort(q),D(p,c)}}function F(n,f,c){for(let e=n.length,r=e-2;r>=0;--r){const p=n[r];for(const b of p){let L=0,z=0;for(const{target:W,value:Z}of b.sourceLinks){let U=Z*(W.layer-b.layer);L+=E(b,W)*U,z+=U}if(!(z>0))continue;let V=(L/z-b.y0)*f;b.y0+=V,b.y1+=V,j(b)}a===void 0&&p.sort(q),D(p,c)}}function D(n,f){const c=n.length>>1,e=n[c];O(n,e.y0-g,c-1,f),R(n,e.y1+g,c+1,f),O(n,l,n.length-1,f),R(n,i,0,f)}function R(n,f,c,e){for(;c<n.length;++c){const r=n[c],p=(f-r.y0)*e;p>1e-6&&(r.y0+=p,r.y1+=p),f=r.y1+g}}function O(n,f,c,e){for(;c>=0;--c){const r=n[c],p=(r.y1-f)*e;p>1e-6&&(r.y0-=p,r.y1-=p),f=r.y0-g}}function j({sourceLinks:n,targetLinks:f}){if(h===void 0){for(const{source:{sourceLinks:c}}of f)c.sort(ct);for(const{target:{targetLinks:c}}of n)c.sort(lt)}}function w(n){if(h===void 0)for(const{sourceLinks:f,targetLinks:c}of n)f.sort(ct),c.sort(lt)}function P(n,f){let c=n.y0-(n.sourceLinks.length-1)*g/2;for(const{target:e,width:r}of n.sourceLinks){if(e===f)break;c+=r+g}for(const{source:e,width:r}of f.targetLinks){if(e===n)break;c-=r}return c}function E(n,f){let c=f.y0-(f.targetLinks.length-1)*g/2;for(const{source:e,width:r}of f.targetLinks){if(e===n)break;c+=r+g}for(const{target:e,width:r}of n.sourceLinks){if(e===f)break;c-=r}return c}return v}var et=Math.PI,nt=2*et,B=1e-6,zt=nt-B;function it(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function pt(){return new it}it.prototype=pt.prototype={constructor:it,moveTo:function(t,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)},closePath:function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,i){this._+="L"+(this._x1=+t)+","+(this._y1=+i)},quadraticCurveTo:function(t,i,s,l){this._+="Q"+ +t+","+ +i+","+(this._x1=+s)+","+(this._y1=+l)},bezierCurveTo:function(t,i,s,l,u,x){this._+="C"+ +t+","+ +i+","+ +s+","+ +l+","+(this._x1=+u)+","+(this._y1=+x)},arcTo:function(t,i,s,l,u){t=+t,i=+i,s=+s,l=+l,u=+u;var x=this._x1,g=this._y1,k=s-t,o=l-i,a=x-t,h=g-i,m=a*a+h*h;if(u<0)throw new Error("negative radius: "+u);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=i);else if(m>B)if(!(Math.abs(h*k-o*a)>B)||!u)this._+="L"+(this._x1=t)+","+(this._y1=i);else{var _=s-x,d=l-g,v=k*k+o*o,T=_*_+d*d,A=Math.sqrt(v),M=Math.sqrt(m),I=u*Math.tan((et-Math.acos((v+m-T)/(2*A*M)))/2),N=I/M,$=I/A;Math.abs(N-1)>B&&(this._+="L"+(t+N*a)+","+(i+N*h)),this._+="A"+u+","+u+",0,0,"+ +(h*_>a*d)+","+(this._x1=t+$*k)+","+(this._y1=i+$*o)}},arc:function(t,i,s,l,u,x){t=+t,i=+i,s=+s,x=!!x;var g=s*Math.cos(l),k=s*Math.sin(l),o=t+g,a=i+k,h=1^x,m=x?l-u:u-l;if(s<0)throw new Error("negative radius: "+s);this._x1===null?this._+="M"+o+","+a:(Math.abs(this._x1-o)>B||Math.abs(this._y1-a)>B)&&(this._+="L"+o+","+a),s&&(m<0&&(m=m%nt+nt),m>zt?this._+="A"+s+","+s+",0,1,"+h+","+(t-g)+","+(i-k)+"A"+s+","+s+",0,1,"+h+","+(this._x1=o)+","+(this._y1=a):m>B&&(this._+="A"+s+","+s+",0,"+ +(m>=et)+","+h+","+(this._x1=t+s*Math.cos(u))+","+(this._y1=i+s*Math.sin(u))))},rect:function(t,i,s,l){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)+"h"+ +s+"v"+ +l+"h"+-s+"Z"},toString:function(){return this._}};function ft(t){return function(){return t}}function Bt(t){return t[0]}function Ft(t){return t[1]}var Rt=Array.prototype.slice;function Vt(t){return t.source}function Wt(t){return t.target}function Ut(t){var i=Vt,s=Wt,l=Bt,u=Ft,x=null;function g(){var k,o=Rt.call(arguments),a=i.apply(this,o),h=s.apply(this,o);if(x||(x=k=pt()),t(x,+l.apply(this,(o[0]=a,o)),+u.apply(this,o),+l.apply(this,(o[0]=h,o)),+u.apply(this,o)),k)return x=null,k+""||null}return g.source=function(k){return arguments.length?(i=k,g):i},g.target=function(k){return arguments.length?(s=k,g):s},g.x=function(k){return arguments.length?(l=typeof k=="function"?k:ft(+k),g):l},g.y=function(k){return arguments.length?(u=typeof k=="function"?k:ft(+k),g):u},g.context=function(k){return arguments.length?(x=k??null,g):x},g}function Gt(t,i,s,l,u){t.moveTo(i,s),t.bezierCurveTo(i=(i+l)/2,s,i,u,l,u)}function Yt(){return Ut(Gt)}function qt(t){return[t.source.x1,t.y0]}function Ht(t){return[t.target.x0,t.y1]}function Xt(){return Yt().source(qt).target(Ht)}var rt=(function(){var t=y(function(k,o,a,h){for(a=a||{},h=k.length;h--;a[k[h]]=o);return a},"o"),i=[1,9],s=[1,10],l=[1,5,10,12],u={trace:y(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:y(function(o,a,h,m,_,d,v){var T=d.length-1;switch(_){case 7:const A=m.findOrCreateNode(d[T-4].trim().replaceAll('""','"')),M=m.findOrCreateNode(d[T-2].trim().replaceAll('""','"')),I=parseFloat(d[T].trim());m.addLink(A,M,I);break;case 8:case 9:case 11:this.$=d[T];break;case 10:this.$=d[T-1];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:i,20:s},{1:[2,6],7:11,10:[1,12]},t(s,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(l,[2,8]),t(l,[2,9]),{19:[1,16]},t(l,[2,11]),{1:[2,1]},{1:[2,5]},t(s,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:i,20:s},{15:18,16:7,17:8,18:i,20:s},{18:[1,19]},t(s,[2,3]),{12:[1,20]},t(l,[2,10]),{15:21,16:7,17:8,18:i,20:s},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:y(function(o,a){if(a.recoverable)this.trace(o);else{var h=new Error(o);throw h.hash=a,h}},"parseError"),parse:y(function(o){var a=this,h=[0],m=[],_=[null],d=[],v=this.table,T="",A=0,M=0,I=2,N=1,$=d.slice.call(arguments,1),S=Object.create(this.lexer),C={yy:{}};for(var F in this.yy)Object.prototype.hasOwnProperty.call(this.yy,F)&&(C.yy[F]=this.yy[F]);S.setInput(o,C.yy),C.yy.lexer=S,C.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var D=S.yylloc;d.push(D);var R=S.options&&S.options.ranges;typeof C.yy.parseError=="function"?this.parseError=C.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function O(L){h.length=h.length-2*L,_.length=_.length-L,d.length=d.length-L}y(O,"popStack");function j(){var L;return L=m.pop()||S.lex()||N,typeof L!="number"&&(L instanceof Array&&(m=L,L=m.pop()),L=a.symbols_[L]||L),L}y(j,"lex");for(var w,P,E,n,f={},c,e,r,p;;){if(P=h[h.length-1],this.defaultActions[P]?E=this.defaultActions[P]:((w===null||typeof w>"u")&&(w=j()),E=v[P]&&v[P][w]),typeof E>"u"||!E.length||!E[0]){var b="";p=[];for(c in v[P])this.terminals_[c]&&c>I&&p.push("'"+this.terminals_[c]+"'");S.showPosition?b="Parse error on line "+(A+1)+`: +import{o as kt,p as mt,s as xt,g as _t,b as vt,a as bt,_ as y,c as ot,b8 as St,d as G,ad as wt,q as Lt,k as Et}from"./mermaid.core-CJB1tAev.js";import{o as At}from"./ordinal-Cboi1Yqb.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./init-Gi6I4Gst.js";function Tt(t){for(var i=t.length/6|0,s=new Array(i),l=0;l<i;)s[l]="#"+t.slice(l*6,++l*6);return s}const Mt=Tt("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");function at(t,i){let s;if(i===void 0)for(const l of t)l!=null&&(s<l||s===void 0&&l>=l)&&(s=l);else{let l=-1;for(let u of t)(u=i(u,++l,t))!=null&&(s<u||s===void 0&&u>=u)&&(s=u)}return s}function dt(t,i){let s;if(i===void 0)for(const l of t)l!=null&&(s>l||s===void 0&&l>=l)&&(s=l);else{let l=-1;for(let u of t)(u=i(u,++l,t))!=null&&(s>u||s===void 0&&u>=u)&&(s=u)}return s}function J(t,i){let s=0;if(i===void 0)for(let l of t)(l=+l)&&(s+=l);else{let l=-1;for(let u of t)(u=+i(u,++l,t))&&(s+=u)}return s}function Nt(t){return t.target.depth}function Ct(t){return t.depth}function Pt(t,i){return i-1-t.height}function gt(t,i){return t.sourceLinks.length?t.depth:i-1}function It(t){return t.targetLinks.length?t.depth:t.sourceLinks.length?dt(t.sourceLinks,Nt)-1:0}function Y(t){return function(){return t}}function lt(t,i){return q(t.source,i.source)||t.index-i.index}function ct(t,i){return q(t.target,i.target)||t.index-i.index}function q(t,i){return t.y0-i.y0}function tt(t){return t.value}function Ot(t){return t.index}function $t(t){return t.nodes}function Dt(t){return t.links}function ut(t,i){const s=t.get(i);if(!s)throw new Error("missing: "+i);return s}function ht({nodes:t}){for(const i of t){let s=i.y0,l=s;for(const u of i.sourceLinks)u.y0=s+u.width/2,s+=u.width;for(const u of i.targetLinks)u.y1=l+u.width/2,l+=u.width}}function jt(){let t=0,i=0,s=1,l=1,u=24,x=8,g,k=Ot,o=gt,a,h,m=$t,_=Dt,d=6;function v(){const n={nodes:m.apply(null,arguments),links:_.apply(null,arguments)};return T(n),A(n),M(n),I(n),S(n),ht(n),n}v.update=function(n){return ht(n),n},v.nodeId=function(n){return arguments.length?(k=typeof n=="function"?n:Y(n),v):k},v.nodeAlign=function(n){return arguments.length?(o=typeof n=="function"?n:Y(n),v):o},v.nodeSort=function(n){return arguments.length?(a=n,v):a},v.nodeWidth=function(n){return arguments.length?(u=+n,v):u},v.nodePadding=function(n){return arguments.length?(x=g=+n,v):x},v.nodes=function(n){return arguments.length?(m=typeof n=="function"?n:Y(n),v):m},v.links=function(n){return arguments.length?(_=typeof n=="function"?n:Y(n),v):_},v.linkSort=function(n){return arguments.length?(h=n,v):h},v.size=function(n){return arguments.length?(t=i=0,s=+n[0],l=+n[1],v):[s-t,l-i]},v.extent=function(n){return arguments.length?(t=+n[0][0],s=+n[1][0],i=+n[0][1],l=+n[1][1],v):[[t,i],[s,l]]},v.iterations=function(n){return arguments.length?(d=+n,v):d};function T({nodes:n,links:f}){for(const[e,r]of n.entries())r.index=e,r.sourceLinks=[],r.targetLinks=[];const c=new Map(n.map((e,r)=>[k(e,r,n),e]));for(const[e,r]of f.entries()){r.index=e;let{source:p,target:b}=r;typeof p!="object"&&(p=r.source=ut(c,p)),typeof b!="object"&&(b=r.target=ut(c,b)),p.sourceLinks.push(r),b.targetLinks.push(r)}if(h!=null)for(const{sourceLinks:e,targetLinks:r}of n)e.sort(h),r.sort(h)}function A({nodes:n}){for(const f of n)f.value=f.fixedValue===void 0?Math.max(J(f.sourceLinks,tt),J(f.targetLinks,tt)):f.fixedValue}function M({nodes:n}){const f=n.length;let c=new Set(n),e=new Set,r=0;for(;c.size;){for(const p of c){p.depth=r;for(const{target:b}of p.sourceLinks)e.add(b)}if(++r>f)throw new Error("circular link");c=e,e=new Set}}function I({nodes:n}){const f=n.length;let c=new Set(n),e=new Set,r=0;for(;c.size;){for(const p of c){p.height=r;for(const{source:b}of p.targetLinks)e.add(b)}if(++r>f)throw new Error("circular link");c=e,e=new Set}}function N({nodes:n}){const f=at(n,r=>r.depth)+1,c=(s-t-u)/(f-1),e=new Array(f);for(const r of n){const p=Math.max(0,Math.min(f-1,Math.floor(o.call(null,r,f))));r.layer=p,r.x0=t+p*c,r.x1=r.x0+u,e[p]?e[p].push(r):e[p]=[r]}if(a)for(const r of e)r.sort(a);return e}function $(n){const f=dt(n,c=>(l-i-(c.length-1)*g)/J(c,tt));for(const c of n){let e=i;for(const r of c){r.y0=e,r.y1=e+r.value*f,e=r.y1+g;for(const p of r.sourceLinks)p.width=p.value*f}e=(l-e+g)/(c.length+1);for(let r=0;r<c.length;++r){const p=c[r];p.y0+=e*(r+1),p.y1+=e*(r+1)}w(c)}}function S(n){const f=N(n);g=Math.min(x,(l-i)/(at(f,c=>c.length)-1)),$(f);for(let c=0;c<d;++c){const e=Math.pow(.99,c),r=Math.max(1-e,(c+1)/d);F(f,e,r),C(f,e,r)}}function C(n,f,c){for(let e=1,r=n.length;e<r;++e){const p=n[e];for(const b of p){let L=0,z=0;for(const{source:W,value:Z}of b.targetLinks){let U=Z*(b.layer-W.layer);L+=P(W,b)*U,z+=U}if(!(z>0))continue;let V=(L/z-b.y0)*f;b.y0+=V,b.y1+=V,j(b)}a===void 0&&p.sort(q),D(p,c)}}function F(n,f,c){for(let e=n.length,r=e-2;r>=0;--r){const p=n[r];for(const b of p){let L=0,z=0;for(const{target:W,value:Z}of b.sourceLinks){let U=Z*(W.layer-b.layer);L+=E(b,W)*U,z+=U}if(!(z>0))continue;let V=(L/z-b.y0)*f;b.y0+=V,b.y1+=V,j(b)}a===void 0&&p.sort(q),D(p,c)}}function D(n,f){const c=n.length>>1,e=n[c];O(n,e.y0-g,c-1,f),R(n,e.y1+g,c+1,f),O(n,l,n.length-1,f),R(n,i,0,f)}function R(n,f,c,e){for(;c<n.length;++c){const r=n[c],p=(f-r.y0)*e;p>1e-6&&(r.y0+=p,r.y1+=p),f=r.y1+g}}function O(n,f,c,e){for(;c>=0;--c){const r=n[c],p=(r.y1-f)*e;p>1e-6&&(r.y0-=p,r.y1-=p),f=r.y0-g}}function j({sourceLinks:n,targetLinks:f}){if(h===void 0){for(const{source:{sourceLinks:c}}of f)c.sort(ct);for(const{target:{targetLinks:c}}of n)c.sort(lt)}}function w(n){if(h===void 0)for(const{sourceLinks:f,targetLinks:c}of n)f.sort(ct),c.sort(lt)}function P(n,f){let c=n.y0-(n.sourceLinks.length-1)*g/2;for(const{target:e,width:r}of n.sourceLinks){if(e===f)break;c+=r+g}for(const{source:e,width:r}of f.targetLinks){if(e===n)break;c-=r}return c}function E(n,f){let c=f.y0-(f.targetLinks.length-1)*g/2;for(const{source:e,width:r}of f.targetLinks){if(e===n)break;c+=r+g}for(const{target:e,width:r}of n.sourceLinks){if(e===f)break;c-=r}return c}return v}var et=Math.PI,nt=2*et,B=1e-6,zt=nt-B;function it(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function pt(){return new it}it.prototype=pt.prototype={constructor:it,moveTo:function(t,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)},closePath:function(){this._x1!==null&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,i){this._+="L"+(this._x1=+t)+","+(this._y1=+i)},quadraticCurveTo:function(t,i,s,l){this._+="Q"+ +t+","+ +i+","+(this._x1=+s)+","+(this._y1=+l)},bezierCurveTo:function(t,i,s,l,u,x){this._+="C"+ +t+","+ +i+","+ +s+","+ +l+","+(this._x1=+u)+","+(this._y1=+x)},arcTo:function(t,i,s,l,u){t=+t,i=+i,s=+s,l=+l,u=+u;var x=this._x1,g=this._y1,k=s-t,o=l-i,a=x-t,h=g-i,m=a*a+h*h;if(u<0)throw new Error("negative radius: "+u);if(this._x1===null)this._+="M"+(this._x1=t)+","+(this._y1=i);else if(m>B)if(!(Math.abs(h*k-o*a)>B)||!u)this._+="L"+(this._x1=t)+","+(this._y1=i);else{var _=s-x,d=l-g,v=k*k+o*o,T=_*_+d*d,A=Math.sqrt(v),M=Math.sqrt(m),I=u*Math.tan((et-Math.acos((v+m-T)/(2*A*M)))/2),N=I/M,$=I/A;Math.abs(N-1)>B&&(this._+="L"+(t+N*a)+","+(i+N*h)),this._+="A"+u+","+u+",0,0,"+ +(h*_>a*d)+","+(this._x1=t+$*k)+","+(this._y1=i+$*o)}},arc:function(t,i,s,l,u,x){t=+t,i=+i,s=+s,x=!!x;var g=s*Math.cos(l),k=s*Math.sin(l),o=t+g,a=i+k,h=1^x,m=x?l-u:u-l;if(s<0)throw new Error("negative radius: "+s);this._x1===null?this._+="M"+o+","+a:(Math.abs(this._x1-o)>B||Math.abs(this._y1-a)>B)&&(this._+="L"+o+","+a),s&&(m<0&&(m=m%nt+nt),m>zt?this._+="A"+s+","+s+",0,1,"+h+","+(t-g)+","+(i-k)+"A"+s+","+s+",0,1,"+h+","+(this._x1=o)+","+(this._y1=a):m>B&&(this._+="A"+s+","+s+",0,"+ +(m>=et)+","+h+","+(this._x1=t+s*Math.cos(u))+","+(this._y1=i+s*Math.sin(u))))},rect:function(t,i,s,l){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)+"h"+ +s+"v"+ +l+"h"+-s+"Z"},toString:function(){return this._}};function ft(t){return function(){return t}}function Bt(t){return t[0]}function Ft(t){return t[1]}var Rt=Array.prototype.slice;function Vt(t){return t.source}function Wt(t){return t.target}function Ut(t){var i=Vt,s=Wt,l=Bt,u=Ft,x=null;function g(){var k,o=Rt.call(arguments),a=i.apply(this,o),h=s.apply(this,o);if(x||(x=k=pt()),t(x,+l.apply(this,(o[0]=a,o)),+u.apply(this,o),+l.apply(this,(o[0]=h,o)),+u.apply(this,o)),k)return x=null,k+""||null}return g.source=function(k){return arguments.length?(i=k,g):i},g.target=function(k){return arguments.length?(s=k,g):s},g.x=function(k){return arguments.length?(l=typeof k=="function"?k:ft(+k),g):l},g.y=function(k){return arguments.length?(u=typeof k=="function"?k:ft(+k),g):u},g.context=function(k){return arguments.length?(x=k??null,g):x},g}function Gt(t,i,s,l,u){t.moveTo(i,s),t.bezierCurveTo(i=(i+l)/2,s,i,u,l,u)}function Yt(){return Ut(Gt)}function qt(t){return[t.source.x1,t.y0]}function Ht(t){return[t.target.x0,t.y1]}function Xt(){return Yt().source(qt).target(Ht)}var rt=(function(){var t=y(function(k,o,a,h){for(a=a||{},h=k.length;h--;a[k[h]]=o);return a},"o"),i=[1,9],s=[1,10],l=[1,5,10,12],u={trace:y(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SANKEY:4,NEWLINE:5,csv:6,opt_eof:7,record:8,csv_tail:9,EOF:10,"field[source]":11,COMMA:12,"field[target]":13,"field[value]":14,field:15,escaped:16,non_escaped:17,DQUOTE:18,ESCAPED_TEXT:19,NON_ESCAPED_TEXT:20,$accept:0,$end:1},terminals_:{2:"error",4:"SANKEY",5:"NEWLINE",10:"EOF",11:"field[source]",12:"COMMA",13:"field[target]",14:"field[value]",18:"DQUOTE",19:"ESCAPED_TEXT",20:"NON_ESCAPED_TEXT"},productions_:[0,[3,4],[6,2],[9,2],[9,0],[7,1],[7,0],[8,5],[15,1],[15,1],[16,3],[17,1]],performAction:y(function(o,a,h,m,_,d,v){var T=d.length-1;switch(_){case 7:const A=m.findOrCreateNode(d[T-4].trim().replaceAll('""','"')),M=m.findOrCreateNode(d[T-2].trim().replaceAll('""','"')),I=parseFloat(d[T].trim());m.addLink(A,M,I);break;case 8:case 9:case 11:this.$=d[T];break;case 10:this.$=d[T-1];break}},"anonymous"),table:[{3:1,4:[1,2]},{1:[3]},{5:[1,3]},{6:4,8:5,15:6,16:7,17:8,18:i,20:s},{1:[2,6],7:11,10:[1,12]},t(s,[2,4],{9:13,5:[1,14]}),{12:[1,15]},t(l,[2,8]),t(l,[2,9]),{19:[1,16]},t(l,[2,11]),{1:[2,1]},{1:[2,5]},t(s,[2,2]),{6:17,8:5,15:6,16:7,17:8,18:i,20:s},{15:18,16:7,17:8,18:i,20:s},{18:[1,19]},t(s,[2,3]),{12:[1,20]},t(l,[2,10]),{15:21,16:7,17:8,18:i,20:s},t([1,5,10],[2,7])],defaultActions:{11:[2,1],12:[2,5]},parseError:y(function(o,a){if(a.recoverable)this.trace(o);else{var h=new Error(o);throw h.hash=a,h}},"parseError"),parse:y(function(o){var a=this,h=[0],m=[],_=[null],d=[],v=this.table,T="",A=0,M=0,I=2,N=1,$=d.slice.call(arguments,1),S=Object.create(this.lexer),C={yy:{}};for(var F in this.yy)Object.prototype.hasOwnProperty.call(this.yy,F)&&(C.yy[F]=this.yy[F]);S.setInput(o,C.yy),C.yy.lexer=S,C.yy.parser=this,typeof S.yylloc>"u"&&(S.yylloc={});var D=S.yylloc;d.push(D);var R=S.options&&S.options.ranges;typeof C.yy.parseError=="function"?this.parseError=C.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function O(L){h.length=h.length-2*L,_.length=_.length-L,d.length=d.length-L}y(O,"popStack");function j(){var L;return L=m.pop()||S.lex()||N,typeof L!="number"&&(L instanceof Array&&(m=L,L=m.pop()),L=a.symbols_[L]||L),L}y(j,"lex");for(var w,P,E,n,f={},c,e,r,p;;){if(P=h[h.length-1],this.defaultActions[P]?E=this.defaultActions[P]:((w===null||typeof w>"u")&&(w=j()),E=v[P]&&v[P][w]),typeof E>"u"||!E.length||!E[0]){var b="";p=[];for(c in v[P])this.terminals_[c]&&c>I&&p.push("'"+this.terminals_[c]+"'");S.showPosition?b="Parse error on line "+(A+1)+`: `+S.showPosition()+` Expecting `+p.join(", ")+", got '"+(this.terminals_[w]||w)+"'":b="Parse error on line "+(A+1)+": Unexpected "+(w==N?"end of input":"'"+(this.terminals_[w]||w)+"'"),this.parseError(b,{text:S.match,token:this.terminals_[w]||w,line:S.yylineno,loc:D,expected:p})}if(E[0]instanceof Array&&E.length>1)throw new Error("Parse Error: multiple actions possible at state: "+P+", token: "+w);switch(E[0]){case 1:h.push(w),_.push(S.yytext),d.push(S.yylloc),h.push(E[1]),w=null,M=S.yyleng,T=S.yytext,A=S.yylineno,D=S.yylloc;break;case 2:if(e=this.productions_[E[1]][1],f.$=_[_.length-e],f._$={first_line:d[d.length-(e||1)].first_line,last_line:d[d.length-1].last_line,first_column:d[d.length-(e||1)].first_column,last_column:d[d.length-1].last_column},R&&(f._$.range=[d[d.length-(e||1)].range[0],d[d.length-1].range[1]]),n=this.performAction.apply(f,[T,M,A,C.yy,E[1],_,d].concat($)),typeof n<"u")return n;e&&(h=h.slice(0,-1*e*2),_=_.slice(0,-1*e),d=d.slice(0,-1*e)),h.push(this.productions_[E[1]][0]),_.push(f.$),d.push(f._$),r=v[h[h.length-2]][h[h.length-1]],h.push(r);break;case 3:return!0}}return!0},"parse")},x=(function(){var k={EOF:1,parseError:y(function(a,h){if(this.yy.parser)this.yy.parser.parseError(a,h);else throw new Error(a)},"parseError"),setInput:y(function(o,a){return this.yy=a||this.yy||{},this._input=o,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:y(function(){var o=this._input[0];this.yytext+=o,this.yyleng++,this.offset++,this.match+=o,this.matched+=o;var a=o.match(/(?:\r\n?|\n).*/g);return a?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),o},"input"),unput:y(function(o){var a=o.length,h=o.split(/(?:\r\n?|\n)/g);this._input=o+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-a),this.offset-=a;var m=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),h.length-1&&(this.yylineno-=h.length-1);var _=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:h?(h.length===m.length?this.yylloc.first_column:0)+m[m.length-h.length].length-h[0].length:this.yylloc.first_column-a},this.options.ranges&&(this.yylloc.range=[_[0],_[0]+this.yyleng-a]),this.yyleng=this.yytext.length,this},"unput"),more:y(function(){return this._more=!0,this},"more"),reject:y(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:y(function(o){this.unput(this.match.slice(o))},"less"),pastInput:y(function(){var o=this.matched.substr(0,this.matched.length-this.match.length);return(o.length>20?"...":"")+o.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:y(function(){var o=this.match;return o.length<20&&(o+=this._input.substr(0,20-o.length)),(o.substr(0,20)+(o.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:y(function(){var o=this.pastInput(),a=new Array(o.length+1).join("-");return o+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-B2h-6vZ7.js b/apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-CnV0H-kS.js similarity index 99% rename from apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-B2h-6vZ7.js rename to apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-CnV0H-kS.js index 9bc2f3f5d..4cd153b77 100644 --- a/apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-B2h-6vZ7.js +++ b/apps/kimi-code/dist-web/assets/sequenceDiagram-DBY2YBRQ-CnV0H-kS.js @@ -1,4 +1,4 @@ -import{I as tr}from"./chunk-2Q5K7J3B-DqVWYlyS.js";import{_ as x,X as er,c as $,d as Vt,l as at,j as Ce,e as rr,f as ar,k as N,b as ke,s as sr,o as ir,a as nr,g as or,p as cr,Y as lr,Z as hr,q as dr,i as Yt,y as Z,$ as Q,a0 as Pt,a1 as Me,a2 as Tr,z as Kt,a3 as pr,a4 as Be}from"./mermaid.core-DaDTfY6S.js";import{a as Er,b as ae,g as dt,d as ur,c as se,e as ie}from"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var te=(function(){var e=x(function(ut,S,v,P){for(v=v||{},P=ut.length;P--;v[ut[P]]=S);return v},"o"),t=[1,2],a=[1,3],r=[1,4],i=[2,4],n=[1,9],s=[1,11],o=[1,12],u=[1,14],d=[1,15],p=[1,17],_=[1,18],E=[1,19],O=[1,25],T=[1,26],g=[1,27],f=[1,28],I=[1,29],L=[1,30],b=[1,31],w=[1,32],A=[1,33],D=[1,34],M=[1,35],V=[1,36],W=[1,37],U=[1,38],G=[1,39],X=[1,40],nt=[1,42],j=[1,43],H=[1,44],st=[1,45],tt=[1,46],Y=[1,47],C=[1,4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,48,49,50,51,53,54,56,61,62,63,64,73],At=[1,74],kt=[1,80],m=[1,81],k=[1,82],lt=[1,83],et=[1,84],K=[1,85],Ot=[1,86],ne=[1,87],oe=[1,88],ce=[1,89],le=[1,90],he=[1,91],de=[1,92],Te=[1,93],pe=[1,94],Ee=[1,95],ue=[1,96],fe=[1,97],_e=[1,98],ge=[1,99],xe=[1,100],Ie=[1,101],ye=[1,102],Re=[1,103],Oe=[1,104],Le=[1,105],be=[2,78],St=[4,5,17,51,53,54],Dt=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,51,53,54,56,61,62,63,64,73],me=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,50,51,53,54,56,61,62,63,64,73],Ut=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,49,51,53,54,56,61,62,63,64,73],Ae=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,48,51,53,54,56,61,62,63,64,73],Gt=[5,52],F=[70,71,72,73],ot=[1,151],Xt={trace:x(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,INVALID:10,box_section:11,box_line:12,participant_statement:13,create:14,box:15,restOfLine:16,end:17,signal:18,autonumber:19,NUM:20,off:21,activate:22,actor:23,deactivate:24,note_statement:25,links_statement:26,link_statement:27,properties_statement:28,details_statement:29,title:30,legacy_title:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,loop:37,rect:38,opt:39,alt:40,else_sections:41,par:42,par_sections:43,par_over:44,critical:45,option_sections:46,break:47,option:48,and:49,else:50,participant:51,AS:52,participant_actor:53,destroy:54,actor_with_config:55,note:56,placement:57,text2:58,over:59,actor_pair:60,links:61,link:62,properties:63,details:64,spaceList:65,",":66,left_of:67,right_of:68,signaltype:69,"+":70,"-":71,"()":72,ACTOR:73,config_object:74,CONFIG_START:75,CONFIG_CONTENT:76,CONFIG_END:77,SOLID_OPEN_ARROW:78,DOTTED_OPEN_ARROW:79,SOLID_ARROW:80,SOLID_ARROW_TOP:81,SOLID_ARROW_BOTTOM:82,STICK_ARROW_TOP:83,STICK_ARROW_BOTTOM:84,SOLID_ARROW_TOP_DOTTED:85,SOLID_ARROW_BOTTOM_DOTTED:86,STICK_ARROW_TOP_DOTTED:87,STICK_ARROW_BOTTOM_DOTTED:88,SOLID_ARROW_TOP_REVERSE:89,SOLID_ARROW_BOTTOM_REVERSE:90,STICK_ARROW_TOP_REVERSE:91,STICK_ARROW_BOTTOM_REVERSE:92,SOLID_ARROW_TOP_REVERSE_DOTTED:93,SOLID_ARROW_BOTTOM_REVERSE_DOTTED:94,STICK_ARROW_TOP_REVERSE_DOTTED:95,STICK_ARROW_BOTTOM_REVERSE_DOTTED:96,BIDIRECTIONAL_SOLID_ARROW:97,DOTTED_ARROW:98,BIDIRECTIONAL_DOTTED_ARROW:99,SOLID_CROSS:100,DOTTED_CROSS:101,SOLID_POINT:102,DOTTED_POINT:103,TXT:104,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",10:"INVALID",14:"create",15:"box",16:"restOfLine",17:"end",19:"autonumber",20:"NUM",21:"off",22:"activate",24:"deactivate",30:"title",31:"legacy_title",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"loop",38:"rect",39:"opt",40:"alt",42:"par",44:"par_over",45:"critical",47:"break",48:"option",49:"and",50:"else",51:"participant",52:"AS",53:"participant_actor",54:"destroy",56:"note",59:"over",61:"links",62:"link",63:"properties",64:"details",66:",",67:"left_of",68:"right_of",70:"+",71:"-",72:"()",73:"ACTOR",75:"CONFIG_START",76:"CONFIG_CONTENT",77:"CONFIG_END",78:"SOLID_OPEN_ARROW",79:"DOTTED_OPEN_ARROW",80:"SOLID_ARROW",81:"SOLID_ARROW_TOP",82:"SOLID_ARROW_BOTTOM",83:"STICK_ARROW_TOP",84:"STICK_ARROW_BOTTOM",85:"SOLID_ARROW_TOP_DOTTED",86:"SOLID_ARROW_BOTTOM_DOTTED",87:"STICK_ARROW_TOP_DOTTED",88:"STICK_ARROW_BOTTOM_DOTTED",89:"SOLID_ARROW_TOP_REVERSE",90:"SOLID_ARROW_BOTTOM_REVERSE",91:"STICK_ARROW_TOP_REVERSE",92:"STICK_ARROW_BOTTOM_REVERSE",93:"SOLID_ARROW_TOP_REVERSE_DOTTED",94:"SOLID_ARROW_BOTTOM_REVERSE_DOTTED",95:"STICK_ARROW_TOP_REVERSE_DOTTED",96:"STICK_ARROW_BOTTOM_REVERSE_DOTTED",97:"BIDIRECTIONAL_SOLID_ARROW",98:"DOTTED_ARROW",99:"BIDIRECTIONAL_DOTTED_ARROW",100:"SOLID_CROSS",101:"DOTTED_CROSS",102:"SOLID_POINT",103:"DOTTED_POINT",104:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[8,1],[11,0],[11,2],[12,2],[12,1],[12,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[46,1],[46,4],[43,1],[43,4],[41,1],[41,4],[13,5],[13,3],[13,5],[13,3],[13,3],[13,5],[13,3],[13,5],[13,3],[25,4],[25,4],[26,3],[27,3],[28,3],[29,3],[65,2],[65,1],[60,3],[60,1],[57,1],[57,1],[18,5],[18,5],[18,5],[18,5],[18,6],[18,4],[55,2],[74,3],[23,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[58,1]],performAction:x(function(S,v,P,y,z,c,wt){var h=c.length-1;switch(z){case 3:return y.apply(c[h]),c[h];case 4:case 10:this.$=[];break;case 5:case 11:c[h-1].push(c[h]),this.$=c[h-1];break;case 6:case 7:case 12:case 13:this.$=c[h];break;case 8:case 9:case 14:this.$=[];break;case 16:c[h].type="createParticipant",this.$=c[h];break;case 17:c[h-1].unshift({type:"boxStart",boxData:y.parseBoxData(c[h-2])}),c[h-1].push({type:"boxEnd",boxText:c[h-2]}),this.$=c[h-1];break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(c[h-2]),sequenceIndexStep:Number(c[h-1]),sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceIndex:Number(c[h-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:y.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 23:this.$={type:"activeStart",signalType:y.LINETYPE.ACTIVE_START,actor:c[h-1].actor};break;case 24:this.$={type:"activeEnd",signalType:y.LINETYPE.ACTIVE_END,actor:c[h-1].actor};break;case 30:y.setDiagramTitle(c[h].substring(6)),this.$=c[h].substring(6);break;case 31:y.setDiagramTitle(c[h].substring(7)),this.$=c[h].substring(7);break;case 32:this.$=c[h].trim(),y.setAccTitle(this.$);break;case 33:case 34:this.$=c[h].trim(),y.setAccDescription(this.$);break;case 35:c[h-1].unshift({type:"loopStart",loopText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.LOOP_START}),c[h-1].push({type:"loopEnd",loopText:c[h-2],signalType:y.LINETYPE.LOOP_END}),this.$=c[h-1];break;case 36:c[h-1].unshift({type:"rectStart",color:y.parseMessage(c[h-2]),signalType:y.LINETYPE.RECT_START}),c[h-1].push({type:"rectEnd",color:y.parseMessage(c[h-2]),signalType:y.LINETYPE.RECT_END}),this.$=c[h-1];break;case 37:c[h-1].unshift({type:"optStart",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.OPT_START}),c[h-1].push({type:"optEnd",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.OPT_END}),this.$=c[h-1];break;case 38:c[h-1].unshift({type:"altStart",altText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.ALT_START}),c[h-1].push({type:"altEnd",signalType:y.LINETYPE.ALT_END}),this.$=c[h-1];break;case 39:c[h-1].unshift({type:"parStart",parText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.PAR_START}),c[h-1].push({type:"parEnd",signalType:y.LINETYPE.PAR_END}),this.$=c[h-1];break;case 40:c[h-1].unshift({type:"parStart",parText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.PAR_OVER_START}),c[h-1].push({type:"parEnd",signalType:y.LINETYPE.PAR_END}),this.$=c[h-1];break;case 41:c[h-1].unshift({type:"criticalStart",criticalText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.CRITICAL_START}),c[h-1].push({type:"criticalEnd",signalType:y.LINETYPE.CRITICAL_END}),this.$=c[h-1];break;case 42:c[h-1].unshift({type:"breakStart",breakText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.BREAK_START}),c[h-1].push({type:"breakEnd",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.BREAK_END}),this.$=c[h-1];break;case 44:this.$=c[h-3].concat([{type:"option",optionText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.CRITICAL_OPTION},c[h]]);break;case 46:this.$=c[h-3].concat([{type:"and",parText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.PAR_AND},c[h]]);break;case 48:this.$=c[h-3].concat([{type:"else",altText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.ALT_ELSE},c[h]]);break;case 49:c[h-3].draw="participant",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 50:c[h-1].draw="participant",c[h-1].type="addParticipant",this.$=c[h-1];break;case 51:c[h-3].draw="actor",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 52:case 57:c[h-1].draw="actor",c[h-1].type="addParticipant",this.$=c[h-1];break;case 53:c[h-1].type="destroyParticipant",this.$=c[h-1];break;case 54:c[h-3].draw="participant",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 55:c[h-1].draw="participant",c[h-1].type="addParticipant",this.$=c[h-1];break;case 56:c[h-3].draw="actor",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 58:this.$=[c[h-1],{type:"addNote",placement:c[h-2],actor:c[h-1].actor,text:c[h]}];break;case 59:c[h-2]=[].concat(c[h-1],c[h-1]).slice(0,2),c[h-2][0]=c[h-2][0].actor,c[h-2][1]=c[h-2][1].actor,this.$=[c[h-1],{type:"addNote",placement:y.PLACEMENT.OVER,actor:c[h-2].slice(0,2),text:c[h]}];break;case 60:this.$=[c[h-1],{type:"addLinks",actor:c[h-1].actor,text:c[h]}];break;case 61:this.$=[c[h-1],{type:"addALink",actor:c[h-1].actor,text:c[h]}];break;case 62:this.$=[c[h-1],{type:"addProperties",actor:c[h-1].actor,text:c[h]}];break;case 63:this.$=[c[h-1],{type:"addDetails",actor:c[h-1].actor,text:c[h]}];break;case 66:this.$=[c[h-2],c[h]];break;case 67:this.$=c[h];break;case 68:this.$=y.PLACEMENT.LEFTOF;break;case 69:this.$=y.PLACEMENT.RIGHTOF;break;case 70:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0},{type:"activeStart",signalType:y.LINETYPE.ACTIVE_START,actor:c[h-1].actor}];break;case 71:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h]},{type:"activeEnd",signalType:y.LINETYPE.ACTIVE_END,actor:c[h-4].actor}];break;case 72:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0,centralConnection:y.LINETYPE.CENTRAL_CONNECTION},{type:"centralConnection",signalType:y.LINETYPE.CENTRAL_CONNECTION,actor:c[h-1].actor}];break;case 73:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-2],msg:c[h],activate:!1,centralConnection:y.LINETYPE.CENTRAL_CONNECTION_REVERSE},{type:"centralConnectionReverse",signalType:y.LINETYPE.CENTRAL_CONNECTION_REVERSE,actor:c[h-4].actor}];break;case 74:this.$=[c[h-5],c[h-1],{type:"addMessage",from:c[h-5].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0,centralConnection:y.LINETYPE.CENTRAL_CONNECTION_DUAL},{type:"centralConnection",signalType:y.LINETYPE.CENTRAL_CONNECTION,actor:c[h-1].actor},{type:"centralConnectionReverse",signalType:y.LINETYPE.CENTRAL_CONNECTION_REVERSE,actor:c[h-5].actor}];break;case 75:this.$=[c[h-3],c[h-1],{type:"addMessage",from:c[h-3].actor,to:c[h-1].actor,signalType:c[h-2],msg:c[h]}];break;case 76:this.$={type:"addParticipant",actor:c[h-1],config:c[h]};break;case 77:this.$=c[h-1].trim();break;case 78:this.$={type:"addParticipant",actor:c[h]};break;case 79:this.$=y.LINETYPE.SOLID_OPEN;break;case 80:this.$=y.LINETYPE.DOTTED_OPEN;break;case 81:this.$=y.LINETYPE.SOLID;break;case 82:this.$=y.LINETYPE.SOLID_TOP;break;case 83:this.$=y.LINETYPE.SOLID_BOTTOM;break;case 84:this.$=y.LINETYPE.STICK_TOP;break;case 85:this.$=y.LINETYPE.STICK_BOTTOM;break;case 86:this.$=y.LINETYPE.SOLID_TOP_DOTTED;break;case 87:this.$=y.LINETYPE.SOLID_BOTTOM_DOTTED;break;case 88:this.$=y.LINETYPE.STICK_TOP_DOTTED;break;case 89:this.$=y.LINETYPE.STICK_BOTTOM_DOTTED;break;case 90:this.$=y.LINETYPE.SOLID_ARROW_TOP_REVERSE;break;case 91:this.$=y.LINETYPE.SOLID_ARROW_BOTTOM_REVERSE;break;case 92:this.$=y.LINETYPE.STICK_ARROW_TOP_REVERSE;break;case 93:this.$=y.LINETYPE.STICK_ARROW_BOTTOM_REVERSE;break;case 94:this.$=y.LINETYPE.SOLID_ARROW_TOP_REVERSE_DOTTED;break;case 95:this.$=y.LINETYPE.SOLID_ARROW_BOTTOM_REVERSE_DOTTED;break;case 96:this.$=y.LINETYPE.STICK_ARROW_TOP_REVERSE_DOTTED;break;case 97:this.$=y.LINETYPE.STICK_ARROW_BOTTOM_REVERSE_DOTTED;break;case 98:this.$=y.LINETYPE.BIDIRECTIONAL_SOLID;break;case 99:this.$=y.LINETYPE.DOTTED;break;case 100:this.$=y.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 101:this.$=y.LINETYPE.SOLID_CROSS;break;case 102:this.$=y.LINETYPE.DOTTED_CROSS;break;case 103:this.$=y.LINETYPE.SOLID_POINT;break;case 104:this.$=y.LINETYPE.DOTTED_POINT;break;case 105:this.$=y.parseMessage(c[h].trim().substring(1));break}},"anonymous"),table:[{3:1,4:t,5:a,6:r},{1:[3]},{3:5,4:t,5:a,6:r},{3:6,4:t,5:a,6:r},e([1,4,5,10,14,15,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,51,53,54,56,61,62,63,64,73],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},e(C,[2,5]),{9:48,13:13,14:u,15:d,18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},e(C,[2,7]),e(C,[2,8]),e(C,[2,9]),e(C,[2,15]),{13:49,51:U,53:G,54:X},{16:[1,50]},{5:[1,51]},{5:[1,54],20:[1,52],21:[1,53]},{23:55,73:Y},{23:56,73:Y},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},{5:[1,61]},e(C,[2,30]),e(C,[2,31]),{33:[1,62]},{35:[1,63]},e(C,[2,34]),{16:[1,64]},{16:[1,65]},{16:[1,66]},{16:[1,67]},{16:[1,68]},{16:[1,69]},{16:[1,70]},{16:[1,71]},{23:72,55:73,73:At},{23:75,55:76,73:At},{23:77,73:Y},{69:78,72:[1,79],78:kt,79:m,80:k,81:lt,82:et,83:K,84:Ot,85:ne,86:oe,87:ce,88:le,89:he,90:de,91:Te,92:pe,93:Ee,94:ue,95:fe,96:_e,97:ge,98:xe,99:Ie,100:ye,101:Re,102:Oe,103:Le},{57:106,59:[1,107],67:[1,108],68:[1,109]},{23:110,73:Y},{23:111,73:Y},{23:112,73:Y},{23:113,73:Y},e([5,66,72,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104],be),e(C,[2,6]),e(C,[2,16]),e(St,[2,10],{11:114}),e(C,[2,18]),{5:[1,116],20:[1,115]},{5:[1,117]},e(C,[2,22]),{5:[1,118]},{5:[1,119]},e(C,[2,25]),e(C,[2,26]),e(C,[2,27]),e(C,[2,28]),e(C,[2,29]),e(C,[2,32]),e(C,[2,33]),e(Dt,i,{7:120}),e(Dt,i,{7:121}),e(Dt,i,{7:122}),e(me,i,{41:123,7:124}),e(Ut,i,{43:125,7:126}),e(Ut,i,{7:126,43:127}),e(Ae,i,{46:128,7:129}),e(Dt,i,{7:130}),{5:[1,132],52:[1,131]},{5:[1,134],52:[1,133]},e(Gt,be,{74:135,75:[1,136]}),{5:[1,138],52:[1,137]},{5:[1,140],52:[1,139]},{5:[1,141]},{23:145,70:[1,142],71:[1,143],72:[1,144],73:Y},{69:146,78:kt,79:m,80:k,81:lt,82:et,83:K,84:Ot,85:ne,86:oe,87:ce,88:le,89:he,90:de,91:Te,92:pe,93:Ee,94:ue,95:fe,96:_e,97:ge,98:xe,99:Ie,100:ye,101:Re,102:Oe,103:Le},e(F,[2,79]),e(F,[2,80]),e(F,[2,81]),e(F,[2,82]),e(F,[2,83]),e(F,[2,84]),e(F,[2,85]),e(F,[2,86]),e(F,[2,87]),e(F,[2,88]),e(F,[2,89]),e(F,[2,90]),e(F,[2,91]),e(F,[2,92]),e(F,[2,93]),e(F,[2,94]),e(F,[2,95]),e(F,[2,96]),e(F,[2,97]),e(F,[2,98]),e(F,[2,99]),e(F,[2,100]),e(F,[2,101]),e(F,[2,102]),e(F,[2,103]),e(F,[2,104]),{23:147,73:Y},{23:149,60:148,73:Y},{73:[2,68]},{73:[2,69]},{58:150,104:ot},{58:152,104:ot},{58:153,104:ot},{58:154,104:ot},{4:[1,157],5:[1,159],12:156,13:158,17:[1,155],51:U,53:G,54:X},{5:[1,160]},e(C,[2,20]),e(C,[2,21]),e(C,[2,23]),e(C,[2,24]),{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,161],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,162],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,163],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,164]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,47],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,50:[1,165],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,166]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,45],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,49:[1,167],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,168]},{17:[1,169]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,43],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,48:[1,170],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,171],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{16:[1,172]},e(C,[2,50]),{16:[1,173]},e(C,[2,55]),e(Gt,[2,76]),{76:[1,174]},{16:[1,175]},e(C,[2,52]),{16:[1,176]},e(C,[2,57]),e(C,[2,53]),{23:177,73:Y},{23:178,73:Y},{23:179,73:Y},{58:180,104:ot},{23:181,72:[1,182],73:Y},{58:183,104:ot},{58:184,104:ot},{66:[1,185],104:[2,67]},{5:[2,60]},{5:[2,105]},{5:[2,61]},{5:[2,62]},{5:[2,63]},e(C,[2,17]),e(St,[2,11]),{13:186,51:U,53:G,54:X},e(St,[2,13]),e(St,[2,14]),e(C,[2,19]),e(C,[2,35]),e(C,[2,36]),e(C,[2,37]),e(C,[2,38]),{16:[1,187]},e(C,[2,39]),{16:[1,188]},e(C,[2,40]),e(C,[2,41]),{16:[1,189]},e(C,[2,42]),{5:[1,190]},{5:[1,191]},{77:[1,192]},{5:[1,193]},{5:[1,194]},{58:195,104:ot},{58:196,104:ot},{58:197,104:ot},{5:[2,75]},{58:198,104:ot},{23:199,73:Y},{5:[2,58]},{5:[2,59]},{23:200,73:Y},e(St,[2,12]),e(me,i,{7:124,41:201}),e(Ut,i,{7:126,43:202}),e(Ae,i,{7:129,46:203}),e(C,[2,49]),e(C,[2,54]),e(Gt,[2,77]),e(C,[2,51]),e(C,[2,56]),{5:[2,70]},{5:[2,71]},{5:[2,72]},{5:[2,73]},{58:204,104:ot},{104:[2,66]},{17:[2,48]},{17:[2,46]},{17:[2,44]},{5:[2,74]}],defaultActions:{5:[2,1],6:[2,2],108:[2,68],109:[2,69],150:[2,60],151:[2,105],152:[2,61],153:[2,62],154:[2,63],180:[2,75],183:[2,58],184:[2,59],195:[2,70],196:[2,71],197:[2,72],198:[2,73],200:[2,66],201:[2,48],202:[2,46],203:[2,44],204:[2,74]},parseError:x(function(S,v){if(v.recoverable)this.trace(S);else{var P=new Error(S);throw P.hash=v,P}},"parseError"),parse:x(function(S){var v=this,P=[0],y=[],z=[null],c=[],wt=this.table,h="",Ct=0,Se=0,Ze=2,we=1,Qe=c.slice.call(arguments,1),J=Object.create(this.lexer),gt={yy:{}};for(var Jt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Jt)&&(gt.yy[Jt]=this.yy[Jt]);J.setInput(S,gt.yy),gt.yy.lexer=J,gt.yy.parser=this,typeof J.yylloc>"u"&&(J.yylloc={});var Zt=J.yylloc;c.push(Zt);var $e=J.options&&J.options.ranges;typeof gt.yy.parseError=="function"?this.parseError=gt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function je(it){P.length=P.length-2*it,z.length=z.length-it,c.length=c.length-it}x(je,"popStack");function Ne(){var it;return it=y.pop()||J.lex()||we,typeof it!="number"&&(it instanceof Array&&(y=it,it=y.pop()),it=v.symbols_[it]||it),it}x(Ne,"lex");for(var rt,xt,ct,Qt,Lt={},Mt,Tt,Pe,Bt;;){if(xt=P[P.length-1],this.defaultActions[xt]?ct=this.defaultActions[xt]:((rt===null||typeof rt>"u")&&(rt=Ne()),ct=wt[xt]&&wt[xt][rt]),typeof ct>"u"||!ct.length||!ct[0]){var $t="";Bt=[];for(Mt in wt[xt])this.terminals_[Mt]&&Mt>Ze&&Bt.push("'"+this.terminals_[Mt]+"'");J.showPosition?$t="Parse error on line "+(Ct+1)+`: +import{I as tr}from"./chunk-2Q5K7J3B-DsAC7dRk.js";import{_ as x,X as er,c as $,d as Vt,l as at,j as Ce,e as rr,f as ar,k as N,b as ke,s as sr,o as ir,a as nr,g as or,p as cr,Y as lr,Z as hr,q as dr,i as Yt,y as Z,$ as Q,a0 as Pt,a1 as Me,a2 as Tr,z as Kt,a3 as pr,a4 as Be}from"./mermaid.core-CJB1tAev.js";import{a as Er,b as ae,g as dt,d as ur,c as se,e as ie}from"./chunk-32BRIVSS-DUDRPqmY.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var te=(function(){var e=x(function(ut,S,v,P){for(v=v||{},P=ut.length;P--;v[ut[P]]=S);return v},"o"),t=[1,2],a=[1,3],r=[1,4],i=[2,4],n=[1,9],s=[1,11],o=[1,12],u=[1,14],d=[1,15],p=[1,17],_=[1,18],E=[1,19],O=[1,25],T=[1,26],g=[1,27],f=[1,28],I=[1,29],L=[1,30],b=[1,31],w=[1,32],A=[1,33],D=[1,34],M=[1,35],V=[1,36],W=[1,37],U=[1,38],G=[1,39],X=[1,40],nt=[1,42],j=[1,43],H=[1,44],st=[1,45],tt=[1,46],Y=[1,47],C=[1,4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,48,49,50,51,53,54,56,61,62,63,64,73],At=[1,74],kt=[1,80],m=[1,81],k=[1,82],lt=[1,83],et=[1,84],K=[1,85],Ot=[1,86],ne=[1,87],oe=[1,88],ce=[1,89],le=[1,90],he=[1,91],de=[1,92],Te=[1,93],pe=[1,94],Ee=[1,95],ue=[1,96],fe=[1,97],_e=[1,98],ge=[1,99],xe=[1,100],Ie=[1,101],ye=[1,102],Re=[1,103],Oe=[1,104],Le=[1,105],be=[2,78],St=[4,5,17,51,53,54],Dt=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,51,53,54,56,61,62,63,64,73],me=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,50,51,53,54,56,61,62,63,64,73],Ut=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,49,51,53,54,56,61,62,63,64,73],Ae=[4,5,10,14,15,17,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,48,51,53,54,56,61,62,63,64,73],Gt=[5,52],F=[70,71,72,73],ot=[1,151],Xt={trace:x(function(){},"trace"),yy:{},symbols_:{error:2,start:3,SPACE:4,NEWLINE:5,SD:6,document:7,line:8,statement:9,INVALID:10,box_section:11,box_line:12,participant_statement:13,create:14,box:15,restOfLine:16,end:17,signal:18,autonumber:19,NUM:20,off:21,activate:22,actor:23,deactivate:24,note_statement:25,links_statement:26,link_statement:27,properties_statement:28,details_statement:29,title:30,legacy_title:31,acc_title:32,acc_title_value:33,acc_descr:34,acc_descr_value:35,acc_descr_multiline_value:36,loop:37,rect:38,opt:39,alt:40,else_sections:41,par:42,par_sections:43,par_over:44,critical:45,option_sections:46,break:47,option:48,and:49,else:50,participant:51,AS:52,participant_actor:53,destroy:54,actor_with_config:55,note:56,placement:57,text2:58,over:59,actor_pair:60,links:61,link:62,properties:63,details:64,spaceList:65,",":66,left_of:67,right_of:68,signaltype:69,"+":70,"-":71,"()":72,ACTOR:73,config_object:74,CONFIG_START:75,CONFIG_CONTENT:76,CONFIG_END:77,SOLID_OPEN_ARROW:78,DOTTED_OPEN_ARROW:79,SOLID_ARROW:80,SOLID_ARROW_TOP:81,SOLID_ARROW_BOTTOM:82,STICK_ARROW_TOP:83,STICK_ARROW_BOTTOM:84,SOLID_ARROW_TOP_DOTTED:85,SOLID_ARROW_BOTTOM_DOTTED:86,STICK_ARROW_TOP_DOTTED:87,STICK_ARROW_BOTTOM_DOTTED:88,SOLID_ARROW_TOP_REVERSE:89,SOLID_ARROW_BOTTOM_REVERSE:90,STICK_ARROW_TOP_REVERSE:91,STICK_ARROW_BOTTOM_REVERSE:92,SOLID_ARROW_TOP_REVERSE_DOTTED:93,SOLID_ARROW_BOTTOM_REVERSE_DOTTED:94,STICK_ARROW_TOP_REVERSE_DOTTED:95,STICK_ARROW_BOTTOM_REVERSE_DOTTED:96,BIDIRECTIONAL_SOLID_ARROW:97,DOTTED_ARROW:98,BIDIRECTIONAL_DOTTED_ARROW:99,SOLID_CROSS:100,DOTTED_CROSS:101,SOLID_POINT:102,DOTTED_POINT:103,TXT:104,$accept:0,$end:1},terminals_:{2:"error",4:"SPACE",5:"NEWLINE",6:"SD",10:"INVALID",14:"create",15:"box",16:"restOfLine",17:"end",19:"autonumber",20:"NUM",21:"off",22:"activate",24:"deactivate",30:"title",31:"legacy_title",32:"acc_title",33:"acc_title_value",34:"acc_descr",35:"acc_descr_value",36:"acc_descr_multiline_value",37:"loop",38:"rect",39:"opt",40:"alt",42:"par",44:"par_over",45:"critical",47:"break",48:"option",49:"and",50:"else",51:"participant",52:"AS",53:"participant_actor",54:"destroy",56:"note",59:"over",61:"links",62:"link",63:"properties",64:"details",66:",",67:"left_of",68:"right_of",70:"+",71:"-",72:"()",73:"ACTOR",75:"CONFIG_START",76:"CONFIG_CONTENT",77:"CONFIG_END",78:"SOLID_OPEN_ARROW",79:"DOTTED_OPEN_ARROW",80:"SOLID_ARROW",81:"SOLID_ARROW_TOP",82:"SOLID_ARROW_BOTTOM",83:"STICK_ARROW_TOP",84:"STICK_ARROW_BOTTOM",85:"SOLID_ARROW_TOP_DOTTED",86:"SOLID_ARROW_BOTTOM_DOTTED",87:"STICK_ARROW_TOP_DOTTED",88:"STICK_ARROW_BOTTOM_DOTTED",89:"SOLID_ARROW_TOP_REVERSE",90:"SOLID_ARROW_BOTTOM_REVERSE",91:"STICK_ARROW_TOP_REVERSE",92:"STICK_ARROW_BOTTOM_REVERSE",93:"SOLID_ARROW_TOP_REVERSE_DOTTED",94:"SOLID_ARROW_BOTTOM_REVERSE_DOTTED",95:"STICK_ARROW_TOP_REVERSE_DOTTED",96:"STICK_ARROW_BOTTOM_REVERSE_DOTTED",97:"BIDIRECTIONAL_SOLID_ARROW",98:"DOTTED_ARROW",99:"BIDIRECTIONAL_DOTTED_ARROW",100:"SOLID_CROSS",101:"DOTTED_CROSS",102:"SOLID_POINT",103:"DOTTED_POINT",104:"TXT"},productions_:[0,[3,2],[3,2],[3,2],[7,0],[7,2],[8,2],[8,1],[8,1],[8,1],[11,0],[11,2],[12,2],[12,1],[12,1],[9,1],[9,2],[9,4],[9,2],[9,4],[9,3],[9,3],[9,2],[9,3],[9,3],[9,2],[9,2],[9,2],[9,2],[9,2],[9,1],[9,1],[9,2],[9,2],[9,1],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[9,4],[46,1],[46,4],[43,1],[43,4],[41,1],[41,4],[13,5],[13,3],[13,5],[13,3],[13,3],[13,5],[13,3],[13,5],[13,3],[25,4],[25,4],[26,3],[27,3],[28,3],[29,3],[65,2],[65,1],[60,3],[60,1],[57,1],[57,1],[18,5],[18,5],[18,5],[18,5],[18,6],[18,4],[55,2],[74,3],[23,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[69,1],[58,1]],performAction:x(function(S,v,P,y,z,c,wt){var h=c.length-1;switch(z){case 3:return y.apply(c[h]),c[h];case 4:case 10:this.$=[];break;case 5:case 11:c[h-1].push(c[h]),this.$=c[h-1];break;case 6:case 7:case 12:case 13:this.$=c[h];break;case 8:case 9:case 14:this.$=[];break;case 16:c[h].type="createParticipant",this.$=c[h];break;case 17:c[h-1].unshift({type:"boxStart",boxData:y.parseBoxData(c[h-2])}),c[h-1].push({type:"boxEnd",boxText:c[h-2]}),this.$=c[h-1];break;case 19:this.$={type:"sequenceIndex",sequenceIndex:Number(c[h-2]),sequenceIndexStep:Number(c[h-1]),sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 20:this.$={type:"sequenceIndex",sequenceIndex:Number(c[h-1]),sequenceIndexStep:1,sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 21:this.$={type:"sequenceIndex",sequenceVisible:!1,signalType:y.LINETYPE.AUTONUMBER};break;case 22:this.$={type:"sequenceIndex",sequenceVisible:!0,signalType:y.LINETYPE.AUTONUMBER};break;case 23:this.$={type:"activeStart",signalType:y.LINETYPE.ACTIVE_START,actor:c[h-1].actor};break;case 24:this.$={type:"activeEnd",signalType:y.LINETYPE.ACTIVE_END,actor:c[h-1].actor};break;case 30:y.setDiagramTitle(c[h].substring(6)),this.$=c[h].substring(6);break;case 31:y.setDiagramTitle(c[h].substring(7)),this.$=c[h].substring(7);break;case 32:this.$=c[h].trim(),y.setAccTitle(this.$);break;case 33:case 34:this.$=c[h].trim(),y.setAccDescription(this.$);break;case 35:c[h-1].unshift({type:"loopStart",loopText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.LOOP_START}),c[h-1].push({type:"loopEnd",loopText:c[h-2],signalType:y.LINETYPE.LOOP_END}),this.$=c[h-1];break;case 36:c[h-1].unshift({type:"rectStart",color:y.parseMessage(c[h-2]),signalType:y.LINETYPE.RECT_START}),c[h-1].push({type:"rectEnd",color:y.parseMessage(c[h-2]),signalType:y.LINETYPE.RECT_END}),this.$=c[h-1];break;case 37:c[h-1].unshift({type:"optStart",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.OPT_START}),c[h-1].push({type:"optEnd",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.OPT_END}),this.$=c[h-1];break;case 38:c[h-1].unshift({type:"altStart",altText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.ALT_START}),c[h-1].push({type:"altEnd",signalType:y.LINETYPE.ALT_END}),this.$=c[h-1];break;case 39:c[h-1].unshift({type:"parStart",parText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.PAR_START}),c[h-1].push({type:"parEnd",signalType:y.LINETYPE.PAR_END}),this.$=c[h-1];break;case 40:c[h-1].unshift({type:"parStart",parText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.PAR_OVER_START}),c[h-1].push({type:"parEnd",signalType:y.LINETYPE.PAR_END}),this.$=c[h-1];break;case 41:c[h-1].unshift({type:"criticalStart",criticalText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.CRITICAL_START}),c[h-1].push({type:"criticalEnd",signalType:y.LINETYPE.CRITICAL_END}),this.$=c[h-1];break;case 42:c[h-1].unshift({type:"breakStart",breakText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.BREAK_START}),c[h-1].push({type:"breakEnd",optText:y.parseMessage(c[h-2]),signalType:y.LINETYPE.BREAK_END}),this.$=c[h-1];break;case 44:this.$=c[h-3].concat([{type:"option",optionText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.CRITICAL_OPTION},c[h]]);break;case 46:this.$=c[h-3].concat([{type:"and",parText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.PAR_AND},c[h]]);break;case 48:this.$=c[h-3].concat([{type:"else",altText:y.parseMessage(c[h-1]),signalType:y.LINETYPE.ALT_ELSE},c[h]]);break;case 49:c[h-3].draw="participant",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 50:c[h-1].draw="participant",c[h-1].type="addParticipant",this.$=c[h-1];break;case 51:c[h-3].draw="actor",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 52:case 57:c[h-1].draw="actor",c[h-1].type="addParticipant",this.$=c[h-1];break;case 53:c[h-1].type="destroyParticipant",this.$=c[h-1];break;case 54:c[h-3].draw="participant",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 55:c[h-1].draw="participant",c[h-1].type="addParticipant",this.$=c[h-1];break;case 56:c[h-3].draw="actor",c[h-3].type="addParticipant",c[h-3].description=y.parseMessage(c[h-1]),this.$=c[h-3];break;case 58:this.$=[c[h-1],{type:"addNote",placement:c[h-2],actor:c[h-1].actor,text:c[h]}];break;case 59:c[h-2]=[].concat(c[h-1],c[h-1]).slice(0,2),c[h-2][0]=c[h-2][0].actor,c[h-2][1]=c[h-2][1].actor,this.$=[c[h-1],{type:"addNote",placement:y.PLACEMENT.OVER,actor:c[h-2].slice(0,2),text:c[h]}];break;case 60:this.$=[c[h-1],{type:"addLinks",actor:c[h-1].actor,text:c[h]}];break;case 61:this.$=[c[h-1],{type:"addALink",actor:c[h-1].actor,text:c[h]}];break;case 62:this.$=[c[h-1],{type:"addProperties",actor:c[h-1].actor,text:c[h]}];break;case 63:this.$=[c[h-1],{type:"addDetails",actor:c[h-1].actor,text:c[h]}];break;case 66:this.$=[c[h-2],c[h]];break;case 67:this.$=c[h];break;case 68:this.$=y.PLACEMENT.LEFTOF;break;case 69:this.$=y.PLACEMENT.RIGHTOF;break;case 70:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0},{type:"activeStart",signalType:y.LINETYPE.ACTIVE_START,actor:c[h-1].actor}];break;case 71:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h]},{type:"activeEnd",signalType:y.LINETYPE.ACTIVE_END,actor:c[h-4].actor}];break;case 72:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0,centralConnection:y.LINETYPE.CENTRAL_CONNECTION},{type:"centralConnection",signalType:y.LINETYPE.CENTRAL_CONNECTION,actor:c[h-1].actor}];break;case 73:this.$=[c[h-4],c[h-1],{type:"addMessage",from:c[h-4].actor,to:c[h-1].actor,signalType:c[h-2],msg:c[h],activate:!1,centralConnection:y.LINETYPE.CENTRAL_CONNECTION_REVERSE},{type:"centralConnectionReverse",signalType:y.LINETYPE.CENTRAL_CONNECTION_REVERSE,actor:c[h-4].actor}];break;case 74:this.$=[c[h-5],c[h-1],{type:"addMessage",from:c[h-5].actor,to:c[h-1].actor,signalType:c[h-3],msg:c[h],activate:!0,centralConnection:y.LINETYPE.CENTRAL_CONNECTION_DUAL},{type:"centralConnection",signalType:y.LINETYPE.CENTRAL_CONNECTION,actor:c[h-1].actor},{type:"centralConnectionReverse",signalType:y.LINETYPE.CENTRAL_CONNECTION_REVERSE,actor:c[h-5].actor}];break;case 75:this.$=[c[h-3],c[h-1],{type:"addMessage",from:c[h-3].actor,to:c[h-1].actor,signalType:c[h-2],msg:c[h]}];break;case 76:this.$={type:"addParticipant",actor:c[h-1],config:c[h]};break;case 77:this.$=c[h-1].trim();break;case 78:this.$={type:"addParticipant",actor:c[h]};break;case 79:this.$=y.LINETYPE.SOLID_OPEN;break;case 80:this.$=y.LINETYPE.DOTTED_OPEN;break;case 81:this.$=y.LINETYPE.SOLID;break;case 82:this.$=y.LINETYPE.SOLID_TOP;break;case 83:this.$=y.LINETYPE.SOLID_BOTTOM;break;case 84:this.$=y.LINETYPE.STICK_TOP;break;case 85:this.$=y.LINETYPE.STICK_BOTTOM;break;case 86:this.$=y.LINETYPE.SOLID_TOP_DOTTED;break;case 87:this.$=y.LINETYPE.SOLID_BOTTOM_DOTTED;break;case 88:this.$=y.LINETYPE.STICK_TOP_DOTTED;break;case 89:this.$=y.LINETYPE.STICK_BOTTOM_DOTTED;break;case 90:this.$=y.LINETYPE.SOLID_ARROW_TOP_REVERSE;break;case 91:this.$=y.LINETYPE.SOLID_ARROW_BOTTOM_REVERSE;break;case 92:this.$=y.LINETYPE.STICK_ARROW_TOP_REVERSE;break;case 93:this.$=y.LINETYPE.STICK_ARROW_BOTTOM_REVERSE;break;case 94:this.$=y.LINETYPE.SOLID_ARROW_TOP_REVERSE_DOTTED;break;case 95:this.$=y.LINETYPE.SOLID_ARROW_BOTTOM_REVERSE_DOTTED;break;case 96:this.$=y.LINETYPE.STICK_ARROW_TOP_REVERSE_DOTTED;break;case 97:this.$=y.LINETYPE.STICK_ARROW_BOTTOM_REVERSE_DOTTED;break;case 98:this.$=y.LINETYPE.BIDIRECTIONAL_SOLID;break;case 99:this.$=y.LINETYPE.DOTTED;break;case 100:this.$=y.LINETYPE.BIDIRECTIONAL_DOTTED;break;case 101:this.$=y.LINETYPE.SOLID_CROSS;break;case 102:this.$=y.LINETYPE.DOTTED_CROSS;break;case 103:this.$=y.LINETYPE.SOLID_POINT;break;case 104:this.$=y.LINETYPE.DOTTED_POINT;break;case 105:this.$=y.parseMessage(c[h].trim().substring(1));break}},"anonymous"),table:[{3:1,4:t,5:a,6:r},{1:[3]},{3:5,4:t,5:a,6:r},{3:6,4:t,5:a,6:r},e([1,4,5,10,14,15,19,22,24,30,31,32,34,36,37,38,39,40,42,44,45,47,51,53,54,56,61,62,63,64,73],i,{7:7}),{1:[2,1]},{1:[2,2]},{1:[2,3],4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},e(C,[2,5]),{9:48,13:13,14:u,15:d,18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},e(C,[2,7]),e(C,[2,8]),e(C,[2,9]),e(C,[2,15]),{13:49,51:U,53:G,54:X},{16:[1,50]},{5:[1,51]},{5:[1,54],20:[1,52],21:[1,53]},{23:55,73:Y},{23:56,73:Y},{5:[1,57]},{5:[1,58]},{5:[1,59]},{5:[1,60]},{5:[1,61]},e(C,[2,30]),e(C,[2,31]),{33:[1,62]},{35:[1,63]},e(C,[2,34]),{16:[1,64]},{16:[1,65]},{16:[1,66]},{16:[1,67]},{16:[1,68]},{16:[1,69]},{16:[1,70]},{16:[1,71]},{23:72,55:73,73:At},{23:75,55:76,73:At},{23:77,73:Y},{69:78,72:[1,79],78:kt,79:m,80:k,81:lt,82:et,83:K,84:Ot,85:ne,86:oe,87:ce,88:le,89:he,90:de,91:Te,92:pe,93:Ee,94:ue,95:fe,96:_e,97:ge,98:xe,99:Ie,100:ye,101:Re,102:Oe,103:Le},{57:106,59:[1,107],67:[1,108],68:[1,109]},{23:110,73:Y},{23:111,73:Y},{23:112,73:Y},{23:113,73:Y},e([5,66,72,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104],be),e(C,[2,6]),e(C,[2,16]),e(St,[2,10],{11:114}),e(C,[2,18]),{5:[1,116],20:[1,115]},{5:[1,117]},e(C,[2,22]),{5:[1,118]},{5:[1,119]},e(C,[2,25]),e(C,[2,26]),e(C,[2,27]),e(C,[2,28]),e(C,[2,29]),e(C,[2,32]),e(C,[2,33]),e(Dt,i,{7:120}),e(Dt,i,{7:121}),e(Dt,i,{7:122}),e(me,i,{41:123,7:124}),e(Ut,i,{43:125,7:126}),e(Ut,i,{7:126,43:127}),e(Ae,i,{46:128,7:129}),e(Dt,i,{7:130}),{5:[1,132],52:[1,131]},{5:[1,134],52:[1,133]},e(Gt,be,{74:135,75:[1,136]}),{5:[1,138],52:[1,137]},{5:[1,140],52:[1,139]},{5:[1,141]},{23:145,70:[1,142],71:[1,143],72:[1,144],73:Y},{69:146,78:kt,79:m,80:k,81:lt,82:et,83:K,84:Ot,85:ne,86:oe,87:ce,88:le,89:he,90:de,91:Te,92:pe,93:Ee,94:ue,95:fe,96:_e,97:ge,98:xe,99:Ie,100:ye,101:Re,102:Oe,103:Le},e(F,[2,79]),e(F,[2,80]),e(F,[2,81]),e(F,[2,82]),e(F,[2,83]),e(F,[2,84]),e(F,[2,85]),e(F,[2,86]),e(F,[2,87]),e(F,[2,88]),e(F,[2,89]),e(F,[2,90]),e(F,[2,91]),e(F,[2,92]),e(F,[2,93]),e(F,[2,94]),e(F,[2,95]),e(F,[2,96]),e(F,[2,97]),e(F,[2,98]),e(F,[2,99]),e(F,[2,100]),e(F,[2,101]),e(F,[2,102]),e(F,[2,103]),e(F,[2,104]),{23:147,73:Y},{23:149,60:148,73:Y},{73:[2,68]},{73:[2,69]},{58:150,104:ot},{58:152,104:ot},{58:153,104:ot},{58:154,104:ot},{4:[1,157],5:[1,159],12:156,13:158,17:[1,155],51:U,53:G,54:X},{5:[1,160]},e(C,[2,20]),e(C,[2,21]),e(C,[2,23]),e(C,[2,24]),{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,161],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,162],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,163],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,164]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,47],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,50:[1,165],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,166]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,45],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,49:[1,167],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{17:[1,168]},{17:[1,169]},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[2,43],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,48:[1,170],51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{4:n,5:s,8:8,9:10,10:o,13:13,14:u,15:d,17:[1,171],18:16,19:p,22:_,23:41,24:E,25:20,26:21,27:22,28:23,29:24,30:O,31:T,32:g,34:f,36:I,37:L,38:b,39:w,40:A,42:D,44:M,45:V,47:W,51:U,53:G,54:X,56:nt,61:j,62:H,63:st,64:tt,73:Y},{16:[1,172]},e(C,[2,50]),{16:[1,173]},e(C,[2,55]),e(Gt,[2,76]),{76:[1,174]},{16:[1,175]},e(C,[2,52]),{16:[1,176]},e(C,[2,57]),e(C,[2,53]),{23:177,73:Y},{23:178,73:Y},{23:179,73:Y},{58:180,104:ot},{23:181,72:[1,182],73:Y},{58:183,104:ot},{58:184,104:ot},{66:[1,185],104:[2,67]},{5:[2,60]},{5:[2,105]},{5:[2,61]},{5:[2,62]},{5:[2,63]},e(C,[2,17]),e(St,[2,11]),{13:186,51:U,53:G,54:X},e(St,[2,13]),e(St,[2,14]),e(C,[2,19]),e(C,[2,35]),e(C,[2,36]),e(C,[2,37]),e(C,[2,38]),{16:[1,187]},e(C,[2,39]),{16:[1,188]},e(C,[2,40]),e(C,[2,41]),{16:[1,189]},e(C,[2,42]),{5:[1,190]},{5:[1,191]},{77:[1,192]},{5:[1,193]},{5:[1,194]},{58:195,104:ot},{58:196,104:ot},{58:197,104:ot},{5:[2,75]},{58:198,104:ot},{23:199,73:Y},{5:[2,58]},{5:[2,59]},{23:200,73:Y},e(St,[2,12]),e(me,i,{7:124,41:201}),e(Ut,i,{7:126,43:202}),e(Ae,i,{7:129,46:203}),e(C,[2,49]),e(C,[2,54]),e(Gt,[2,77]),e(C,[2,51]),e(C,[2,56]),{5:[2,70]},{5:[2,71]},{5:[2,72]},{5:[2,73]},{58:204,104:ot},{104:[2,66]},{17:[2,48]},{17:[2,46]},{17:[2,44]},{5:[2,74]}],defaultActions:{5:[2,1],6:[2,2],108:[2,68],109:[2,69],150:[2,60],151:[2,105],152:[2,61],153:[2,62],154:[2,63],180:[2,75],183:[2,58],184:[2,59],195:[2,70],196:[2,71],197:[2,72],198:[2,73],200:[2,66],201:[2,48],202:[2,46],203:[2,44],204:[2,74]},parseError:x(function(S,v){if(v.recoverable)this.trace(S);else{var P=new Error(S);throw P.hash=v,P}},"parseError"),parse:x(function(S){var v=this,P=[0],y=[],z=[null],c=[],wt=this.table,h="",Ct=0,Se=0,Ze=2,we=1,Qe=c.slice.call(arguments,1),J=Object.create(this.lexer),gt={yy:{}};for(var Jt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,Jt)&&(gt.yy[Jt]=this.yy[Jt]);J.setInput(S,gt.yy),gt.yy.lexer=J,gt.yy.parser=this,typeof J.yylloc>"u"&&(J.yylloc={});var Zt=J.yylloc;c.push(Zt);var $e=J.options&&J.options.ranges;typeof gt.yy.parseError=="function"?this.parseError=gt.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function je(it){P.length=P.length-2*it,z.length=z.length-it,c.length=c.length-it}x(je,"popStack");function Ne(){var it;return it=y.pop()||J.lex()||we,typeof it!="number"&&(it instanceof Array&&(y=it,it=y.pop()),it=v.symbols_[it]||it),it}x(Ne,"lex");for(var rt,xt,ct,Qt,Lt={},Mt,Tt,Pe,Bt;;){if(xt=P[P.length-1],this.defaultActions[xt]?ct=this.defaultActions[xt]:((rt===null||typeof rt>"u")&&(rt=Ne()),ct=wt[xt]&&wt[xt][rt]),typeof ct>"u"||!ct.length||!ct[0]){var $t="";Bt=[];for(Mt in wt[xt])this.terminals_[Mt]&&Mt>Ze&&Bt.push("'"+this.terminals_[Mt]+"'");J.showPosition?$t="Parse error on line "+(Ct+1)+`: `+J.showPosition()+` Expecting `+Bt.join(", ")+", got '"+(this.terminals_[rt]||rt)+"'":$t="Parse error on line "+(Ct+1)+": Unexpected "+(rt==we?"end of input":"'"+(this.terminals_[rt]||rt)+"'"),this.parseError($t,{text:J.match,token:this.terminals_[rt]||rt,line:J.yylineno,loc:Zt,expected:Bt})}if(ct[0]instanceof Array&&ct.length>1)throw new Error("Parse Error: multiple actions possible at state: "+xt+", token: "+rt);switch(ct[0]){case 1:P.push(rt),z.push(J.yytext),c.push(J.yylloc),P.push(ct[1]),rt=null,Se=J.yyleng,h=J.yytext,Ct=J.yylineno,Zt=J.yylloc;break;case 2:if(Tt=this.productions_[ct[1]][1],Lt.$=z[z.length-Tt],Lt._$={first_line:c[c.length-(Tt||1)].first_line,last_line:c[c.length-1].last_line,first_column:c[c.length-(Tt||1)].first_column,last_column:c[c.length-1].last_column},$e&&(Lt._$.range=[c[c.length-(Tt||1)].range[0],c[c.length-1].range[1]]),Qt=this.performAction.apply(Lt,[h,Se,Ct,gt.yy,ct[1],z,c].concat(Qe)),typeof Qt<"u")return Qt;Tt&&(P=P.slice(0,-1*Tt*2),z=z.slice(0,-1*Tt),c=c.slice(0,-1*Tt)),P.push(this.productions_[ct[1]][0]),z.push(Lt.$),c.push(Lt._$),Pe=wt[P[P.length-2]][P[P.length-1]],P.push(Pe);break;case 3:return!0}}return!0},"parse")},Je=(function(){var ut={EOF:1,parseError:x(function(v,P){if(this.yy.parser)this.yy.parser.parseError(v,P);else throw new Error(v)},"parseError"),setInput:x(function(S,v){return this.yy=v||this.yy||{},this._input=S,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:x(function(){var S=this._input[0];this.yytext+=S,this.yyleng++,this.offset++,this.match+=S,this.matched+=S;var v=S.match(/(?:\r\n?|\n).*/g);return v?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),S},"input"),unput:x(function(S){var v=S.length,P=S.split(/(?:\r\n?|\n)/g);this._input=S+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-v),this.offset-=v;var y=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),P.length-1&&(this.yylineno-=P.length-1);var z=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:P?(P.length===y.length?this.yylloc.first_column:0)+y[y.length-P.length].length-P[0].length:this.yylloc.first_column-v},this.options.ranges&&(this.yylloc.range=[z[0],z[0]+this.yyleng-v]),this.yyleng=this.yytext.length,this},"unput"),more:x(function(){return this._more=!0,this},"more"),reject:x(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:x(function(S){this.unput(this.match.slice(S))},"less"),pastInput:x(function(){var S=this.matched.substr(0,this.matched.length-this.match.length);return(S.length>20?"...":"")+S.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:x(function(){var S=this.match;return S.length<20&&(S+=this._input.substr(0,20-S.length)),(S.substr(0,20)+(S.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:x(function(){var S=this.pastInput(),v=new Array(S.length+1).join("-");return S+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-JndNlF5C.js b/apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-D5GqjpM0.js similarity index 86% rename from apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-JndNlF5C.js rename to apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-D5GqjpM0.js index 9803ab4ea..93fea43c4 100644 --- a/apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-JndNlF5C.js +++ b/apps/kimi-code/dist-web/assets/sizeCapture-X5ZJPWSS-D5GqjpM0.js @@ -1 +1 @@ -import{_ as o}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var p=1;function i(){if(!(typeof globalThis>"u"))return globalThis}o(i,"getCaptureGlobal");function c(){return!!i()?.mermaidCaptureSizes}o(c,"shouldCaptureSizes");function u(){return typeof location>"u"?"browser-dev":`${location.pathname}${location.search}`}o(u,"capturedFromLocation");function d(n,r){const t=i();if(!t)return;const e=r.node(),s=((e&&"ownerSVGElement"in e?e.ownerSVGElement:null)??e)?.id??"(unknown)";t.mermaidCapturedSizes??=[];const a={svgId:s,sizes:n};t.mermaidCapturedSizes.push(a),t.mermaidLastCapturedSizes=a}o(d,"emitCapturedSizes");function m(n,r){const t=[];for(const e of r.nodes)e.isGroup||t.push({id:e.id,width:e.width??0,height:e.height??0});t.length!==0&&d({metadata:{captureVersion:p,capturedAt:new Date().toISOString(),capturedFrom:u()},nodes:t},n)}o(m,"captureNodeSizes");export{m as captureNodeSizes,c as shouldCaptureSizes}; +import{_ as o}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var p=1;function i(){if(!(typeof globalThis>"u"))return globalThis}o(i,"getCaptureGlobal");function c(){return!!i()?.mermaidCaptureSizes}o(c,"shouldCaptureSizes");function u(){return typeof location>"u"?"browser-dev":`${location.pathname}${location.search}`}o(u,"capturedFromLocation");function d(n,r){const t=i();if(!t)return;const e=r.node(),s=((e&&"ownerSVGElement"in e?e.ownerSVGElement:null)??e)?.id??"(unknown)";t.mermaidCapturedSizes??=[];const a={svgId:s,sizes:n};t.mermaidCapturedSizes.push(a),t.mermaidLastCapturedSizes=a}o(d,"emitCapturedSizes");function m(n,r){const t=[];for(const e of r.nodes)e.isGroup||t.push({id:e.id,width:e.width??0,height:e.height??0});t.length!==0&&d({metadata:{captureVersion:p,capturedAt:new Date().toISOString(),capturedFrom:u()},nodes:t},n)}o(m,"captureNodeSizes");export{m as captureNodeSizes,c as shouldCaptureSizes}; diff --git a/apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-ha3u0dwu.js b/apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-GIVsAB2M.js similarity index 96% rename from apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-ha3u0dwu.js rename to apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-GIVsAB2M.js index 4b08c8452..e01e907e9 100644 --- a/apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-ha3u0dwu.js +++ b/apps/kimi-code/dist-web/assets/stateDiagram-2N3HPSRC-GIVsAB2M.js @@ -1 +1 @@ -import{s as R,a as W,S as N}from"./chunk-EX3LRPZG-CyUsdK3n.js";import{_ as f,c as t,d as H,l as S,e as P,k as z,a7 as _,a8 as U,a3 as C,y as F}from"./mermaid.core-DaDTfY6S.js";import{G as O}from"./graph-DOmOIIwC.js";import{l as J}from"./layout-D-LzfAck.js";import"./chunk-XXDRQBXY-BEgNawAD.js";import"./chunk-VR4S4FIN-Dzr2NgNj.js";import"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./map-DxJ2ADlA.js";var X=f(e=>e.append("circle").attr("class","start-state").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit).attr("cy",t().state.padding+t().state.sizeUnit),"drawStartState"),D=f(e=>e.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",t().state.textHeight).attr("class","divider").attr("x2",t().state.textHeight*2).attr("y1",0).attr("y2",0),"drawDivider"),Y=f((e,i)=>{const d=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+2*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),c=d.node().getBBox();return e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",c.width+2*t().state.padding).attr("height",c.height+2*t().state.padding).attr("rx",t().state.radius),d},"drawSimpleState"),I=f((e,i)=>{const d=f(function(o,B,y){const v=o.append("tspan").attr("x",2*t().state.padding).text(B);y||v.attr("dy",t().state.textHeight)},"addTspan"),n=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+1.3*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.descriptions[0]).node().getBBox(),l=n.height,p=e.append("text").attr("x",t().state.padding).attr("y",l+t().state.padding*.4+t().state.dividerMargin+t().state.textHeight).attr("class","state-description");let a=!0,s=!0;i.descriptions.forEach(function(o){a||(d(p,o,s),s=!1),a=!1});const m=e.append("line").attr("x1",t().state.padding).attr("y1",t().state.padding+l+t().state.dividerMargin/2).attr("y2",t().state.padding+l+t().state.dividerMargin/2).attr("class","descr-divider"),x=p.node().getBBox(),g=Math.max(x.width,n.width);return m.attr("x2",g+3*t().state.padding),e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",g+2*t().state.padding).attr("height",x.height+l+2*t().state.padding).attr("rx",t().state.radius),e},"drawDescrState"),$=f((e,i,d)=>{const c=t().state.padding,n=2*t().state.padding,l=e.node().getBBox(),p=l.width,a=l.x,s=e.append("text").attr("x",0).attr("y",t().state.titleShift).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),x=s.node().getBBox().width+n;let g=Math.max(x,p);g===p&&(g=g+n);let o;const B=e.node().getBBox();i.doc,o=a-c,x>p&&(o=(p-g)/2+c),Math.abs(a-B.x)<c&&x>p&&(o=a-(x-p)/2);const y=1-t().state.textHeight;return e.insert("rect",":first-child").attr("x",o).attr("y",y).attr("class",d?"alt-composit":"composit").attr("width",g).attr("height",B.height+t().state.textHeight+t().state.titleShift+1).attr("rx","0"),s.attr("x",o+c),x<=p&&s.attr("x",a+(g-n)/2-x/2+c),e.insert("rect",":first-child").attr("x",o).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",g).attr("height",t().state.textHeight*3).attr("rx",t().state.radius),e.insert("rect",":first-child").attr("x",o).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",g).attr("height",B.height+3+2*t().state.textHeight).attr("rx",t().state.radius),e},"addTitleAndBox"),q=f(e=>(e.append("circle").attr("class","end-state-outer").attr("r",t().state.sizeUnit+t().state.miniPadding).attr("cx",t().state.padding+t().state.sizeUnit+t().state.miniPadding).attr("cy",t().state.padding+t().state.sizeUnit+t().state.miniPadding),e.append("circle").attr("class","end-state-inner").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit+2).attr("cy",t().state.padding+t().state.sizeUnit+2)),"drawEndState"),Z=f((e,i)=>{let d=t().state.forkWidth,c=t().state.forkHeight;if(i.parentId){let n=d;d=c,c=n}return e.append("rect").style("stroke","black").style("fill","black").attr("width",d).attr("height",c).attr("x",t().state.padding).attr("y",t().state.padding)},"drawForkJoinState"),j=f((e,i,d,c)=>{let n=0;const l=c.append("text");l.style("text-anchor","start"),l.attr("class","noteText");let p=e.replace(/\r\n/g,"<br/>");p=p.replace(/\n/g,"<br/>");const a=p.split(z.lineBreakRegex);let s=1.25*t().state.noteMargin;for(const m of a){const x=m.trim();if(x.length>0){const g=l.append("tspan");if(g.text(x),s===0){const o=g.node().getBBox();s+=o.height}n+=s,g.attr("x",i+t().state.noteMargin),g.attr("y",d+n+1.25*t().state.noteMargin)}}return{textWidth:l.node().getBBox().width,textHeight:n}},"_drawLongText"),K=f((e,i)=>{i.attr("class","state-note");const d=i.append("rect").attr("x",0).attr("y",t().state.padding),c=i.append("g"),{textWidth:n,textHeight:l}=j(e,0,0,c);return d.attr("height",l+2*t().state.noteMargin),d.attr("width",n+t().state.noteMargin*2),d},"drawNote"),L=f(function(e,i){const d=i.id,c={id:d,label:i.id,width:0,height:0},n=e.append("g").attr("id",d).attr("class","stateGroup");i.type==="start"&&X(n),i.type==="end"&&q(n),(i.type==="fork"||i.type==="join")&&Z(n,i),i.type==="note"&&K(i.note.text,n),i.type==="divider"&&D(n),i.type==="default"&&i.descriptions.length===0&&Y(n,i),i.type==="default"&&i.descriptions.length>0&&I(n,i);const l=n.node().getBBox();return c.width=l.width+2*t().state.padding,c.height=l.height+2*t().state.padding,c},"drawState"),G=0,Q=f(function(e,i,d){const c=f(function(s){switch(s){case N.relationType.AGGREGATION:return"aggregation";case N.relationType.EXTENSION:return"extension";case N.relationType.COMPOSITION:return"composition";case N.relationType.DEPENDENCY:return"dependency"}},"getRelationType");i.points=i.points.filter(s=>!Number.isNaN(s.y));const n=i.points,l=_().x(function(s){return s.x}).y(function(s){return s.y}).curve(U),p=e.append("path").attr("d",l(n)).attr("id","edge"+G).attr("class","transition");let a="";if(t().state.arrowMarkerAbsolute&&(a=C(!0)),p.attr("marker-end","url("+a+"#"+c(N.relationType.DEPENDENCY)+"End)"),d.title!==void 0){const s=e.append("g").attr("class","stateLabel"),{x:m,y:x}=F.calcLabelPosition(i.points),g=z.getRows(d.title);let o=0;const B=[];let y=0,v=0;for(let u=0;u<=g.length;u++){const h=s.append("text").attr("text-anchor","middle").text(g[u]).attr("x",m).attr("y",x+o),w=h.node().getBBox();y=Math.max(y,w.width),v=Math.min(v,w.x),S.info(w.x,m,x+o),o===0&&(o=h.node().getBBox().height,S.info("Title height",o,x)),B.push(h)}let k=o*g.length;if(g.length>1){const u=(g.length-1)*o*.5;B.forEach((h,w)=>h.attr("y",x+w*o-u)),k=o*g.length}const r=s.node().getBBox();s.insert("rect",":first-child").attr("class","box").attr("x",m-y/2-t().state.padding/2).attr("y",x-k/2-t().state.padding/2-3.5).attr("width",y+t().state.padding).attr("height",k+t().state.padding),S.info(r)}G++},"drawEdge"),b,T={},V=f(function(){},"setConf"),tt=f(function(e){e.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),et=f(function(e,i,d,c){b=t().state;const n=t().securityLevel;let l;n==="sandbox"&&(l=H("#i"+i));const p=n==="sandbox"?H(l.nodes()[0].contentDocument.body):H("body"),a=n==="sandbox"?l.nodes()[0].contentDocument:document;S.debug("Rendering diagram "+e);const s=p.select(`[id='${i}']`);tt(s);const m=c.db.getRootDoc(),x=s.append("g").attr("id",i+"-root");A(m,x,void 0,!1,p,a,c);const g=b.padding,o=s.node().getBBox(),B=o.width+g*2,y=o.height+g*2,v=B*1.75;P(s,y,v,b.useMaxWidth),s.attr("viewBox",`${o.x-b.padding} ${o.y-b.padding} `+B+" "+y)},"draw"),at=f(e=>e?e.length*b.fontSizeFactor:1,"getLabelWidth"),A=f((e,i,d,c,n,l,p)=>{const a=new O({compound:!0,multigraph:!0});let s,m=!0;for(s=0;s<e.length;s++)if(e[s].stmt==="relation"){m=!1;break}d?a.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:m?1:b.edgeLengthFactor,nodeSep:m?1:50,isMultiGraph:!0}):a.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:m?1:b.edgeLengthFactor,nodeSep:m?1:50,ranker:"tight-tree",isMultiGraph:!0}),a.setDefaultEdgeLabel(function(){return{}});const x=p.db.getStates(),g=p.db.getRelations(),o=Object.keys(x);for(const r of o){const u=x[r];d&&(u.parentId=d);let h;if(u.doc){let w=i.append("g").attr("id",u.id).attr("class","stateGroup");h=A(u.doc,w,u.id,!c,n,l,p);{w=$(w,u,c);let E=w.node().getBBox();h.width=E.width,h.height=E.height+b.padding/2,T[u.id]={y:b.compositTitleSize}}}else h=L(i,u,a);if(u.note){const w={descriptions:[],id:u.id+"-note",note:u.note,type:"note"},E=L(i,w,a);u.note.position==="left of"?(a.setNode(h.id+"-note",E),a.setNode(h.id,h)):(a.setNode(h.id,h),a.setNode(h.id+"-note",E)),a.setParent(h.id,h.id+"-group"),a.setParent(h.id+"-note",h.id+"-group")}else a.setNode(h.id,h)}S.debug("Count=",a.nodeCount(),a);let B=0;g.forEach(function(r){B++,S.debug("Setting edge",r),a.setEdge(r.id1,r.id2,{relation:r,width:at(r.title),height:b.labelHeight*z.getRows(r.title).length,labelpos:"c"},"id"+B)}),J(a),S.debug("Graph after layout",a.nodes());const y=i.node();a.nodes().forEach(function(r){r!==void 0&&a.node(r)!==void 0?(S.warn("Node "+r+": "+JSON.stringify(a.node(r))),n.select("#"+y.id+" #"+r).attr("transform","translate("+(a.node(r).x-a.node(r).width/2)+","+(a.node(r).y+(T[r]?T[r].y:0)-a.node(r).height/2)+" )"),n.select("#"+y.id+" #"+r).attr("data-x-shift",a.node(r).x-a.node(r).width/2),l.querySelectorAll("#"+y.id+" #"+r+" .divider").forEach(h=>{const w=h.parentElement;let E=0,M=0;w&&(w.parentElement&&(E=w.parentElement.getBBox().width),M=parseInt(w.getAttribute("data-x-shift"),10),Number.isNaN(M)&&(M=0)),h.setAttribute("x1",0-M+8),h.setAttribute("x2",E-M-8)})):S.debug("No Node "+r+": "+JSON.stringify(a.node(r)))});let v=y.getBBox();a.edges().forEach(function(r){r!==void 0&&a.edge(r)!==void 0&&(S.debug("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(a.edge(r))),Q(i,a.edge(r),a.edge(r).relation))}),v=y.getBBox();const k={id:d||"root",label:d||"root",width:0,height:0};return k.width=v.width+2*b.padding,k.height=v.height+2*b.padding,S.debug("Doc rendered",k,a),k},"renderDoc"),it={setConf:V,draw:et},xt={parser:W,get db(){return new N(1)},renderer:it,styles:R,init:f(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")};export{xt as diagram}; +import{s as R,a as W,S as N}from"./chunk-EX3LRPZG-BCWDroXJ.js";import{_ as f,c as t,d as H,l as S,e as P,k as z,a7 as _,a8 as U,a3 as C,y as F}from"./mermaid.core-CJB1tAev.js";import{G as O}from"./graph-DOmOIIwC.js";import{l as J}from"./layout-D-LzfAck.js";import"./chunk-XXDRQBXY-5rh7CWvm.js";import"./chunk-VR4S4FIN-CEH7JYJn.js";import"./chunk-32BRIVSS-DUDRPqmY.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./map-DxJ2ADlA.js";var X=f(e=>e.append("circle").attr("class","start-state").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit).attr("cy",t().state.padding+t().state.sizeUnit),"drawStartState"),D=f(e=>e.append("line").style("stroke","grey").style("stroke-dasharray","3").attr("x1",t().state.textHeight).attr("class","divider").attr("x2",t().state.textHeight*2).attr("y1",0).attr("y2",0),"drawDivider"),Y=f((e,i)=>{const d=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+2*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),c=d.node().getBBox();return e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",c.width+2*t().state.padding).attr("height",c.height+2*t().state.padding).attr("rx",t().state.radius),d},"drawSimpleState"),I=f((e,i)=>{const d=f(function(o,B,y){const v=o.append("tspan").attr("x",2*t().state.padding).text(B);y||v.attr("dy",t().state.textHeight)},"addTspan"),n=e.append("text").attr("x",2*t().state.padding).attr("y",t().state.textHeight+1.3*t().state.padding).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.descriptions[0]).node().getBBox(),l=n.height,p=e.append("text").attr("x",t().state.padding).attr("y",l+t().state.padding*.4+t().state.dividerMargin+t().state.textHeight).attr("class","state-description");let a=!0,s=!0;i.descriptions.forEach(function(o){a||(d(p,o,s),s=!1),a=!1});const m=e.append("line").attr("x1",t().state.padding).attr("y1",t().state.padding+l+t().state.dividerMargin/2).attr("y2",t().state.padding+l+t().state.dividerMargin/2).attr("class","descr-divider"),x=p.node().getBBox(),g=Math.max(x.width,n.width);return m.attr("x2",g+3*t().state.padding),e.insert("rect",":first-child").attr("x",t().state.padding).attr("y",t().state.padding).attr("width",g+2*t().state.padding).attr("height",x.height+l+2*t().state.padding).attr("rx",t().state.radius),e},"drawDescrState"),$=f((e,i,d)=>{const c=t().state.padding,n=2*t().state.padding,l=e.node().getBBox(),p=l.width,a=l.x,s=e.append("text").attr("x",0).attr("y",t().state.titleShift).attr("font-size",t().state.fontSize).attr("class","state-title").text(i.id),x=s.node().getBBox().width+n;let g=Math.max(x,p);g===p&&(g=g+n);let o;const B=e.node().getBBox();i.doc,o=a-c,x>p&&(o=(p-g)/2+c),Math.abs(a-B.x)<c&&x>p&&(o=a-(x-p)/2);const y=1-t().state.textHeight;return e.insert("rect",":first-child").attr("x",o).attr("y",y).attr("class",d?"alt-composit":"composit").attr("width",g).attr("height",B.height+t().state.textHeight+t().state.titleShift+1).attr("rx","0"),s.attr("x",o+c),x<=p&&s.attr("x",a+(g-n)/2-x/2+c),e.insert("rect",":first-child").attr("x",o).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",g).attr("height",t().state.textHeight*3).attr("rx",t().state.radius),e.insert("rect",":first-child").attr("x",o).attr("y",t().state.titleShift-t().state.textHeight-t().state.padding).attr("width",g).attr("height",B.height+3+2*t().state.textHeight).attr("rx",t().state.radius),e},"addTitleAndBox"),q=f(e=>(e.append("circle").attr("class","end-state-outer").attr("r",t().state.sizeUnit+t().state.miniPadding).attr("cx",t().state.padding+t().state.sizeUnit+t().state.miniPadding).attr("cy",t().state.padding+t().state.sizeUnit+t().state.miniPadding),e.append("circle").attr("class","end-state-inner").attr("r",t().state.sizeUnit).attr("cx",t().state.padding+t().state.sizeUnit+2).attr("cy",t().state.padding+t().state.sizeUnit+2)),"drawEndState"),Z=f((e,i)=>{let d=t().state.forkWidth,c=t().state.forkHeight;if(i.parentId){let n=d;d=c,c=n}return e.append("rect").style("stroke","black").style("fill","black").attr("width",d).attr("height",c).attr("x",t().state.padding).attr("y",t().state.padding)},"drawForkJoinState"),j=f((e,i,d,c)=>{let n=0;const l=c.append("text");l.style("text-anchor","start"),l.attr("class","noteText");let p=e.replace(/\r\n/g,"<br/>");p=p.replace(/\n/g,"<br/>");const a=p.split(z.lineBreakRegex);let s=1.25*t().state.noteMargin;for(const m of a){const x=m.trim();if(x.length>0){const g=l.append("tspan");if(g.text(x),s===0){const o=g.node().getBBox();s+=o.height}n+=s,g.attr("x",i+t().state.noteMargin),g.attr("y",d+n+1.25*t().state.noteMargin)}}return{textWidth:l.node().getBBox().width,textHeight:n}},"_drawLongText"),K=f((e,i)=>{i.attr("class","state-note");const d=i.append("rect").attr("x",0).attr("y",t().state.padding),c=i.append("g"),{textWidth:n,textHeight:l}=j(e,0,0,c);return d.attr("height",l+2*t().state.noteMargin),d.attr("width",n+t().state.noteMargin*2),d},"drawNote"),L=f(function(e,i){const d=i.id,c={id:d,label:i.id,width:0,height:0},n=e.append("g").attr("id",d).attr("class","stateGroup");i.type==="start"&&X(n),i.type==="end"&&q(n),(i.type==="fork"||i.type==="join")&&Z(n,i),i.type==="note"&&K(i.note.text,n),i.type==="divider"&&D(n),i.type==="default"&&i.descriptions.length===0&&Y(n,i),i.type==="default"&&i.descriptions.length>0&&I(n,i);const l=n.node().getBBox();return c.width=l.width+2*t().state.padding,c.height=l.height+2*t().state.padding,c},"drawState"),G=0,Q=f(function(e,i,d){const c=f(function(s){switch(s){case N.relationType.AGGREGATION:return"aggregation";case N.relationType.EXTENSION:return"extension";case N.relationType.COMPOSITION:return"composition";case N.relationType.DEPENDENCY:return"dependency"}},"getRelationType");i.points=i.points.filter(s=>!Number.isNaN(s.y));const n=i.points,l=_().x(function(s){return s.x}).y(function(s){return s.y}).curve(U),p=e.append("path").attr("d",l(n)).attr("id","edge"+G).attr("class","transition");let a="";if(t().state.arrowMarkerAbsolute&&(a=C(!0)),p.attr("marker-end","url("+a+"#"+c(N.relationType.DEPENDENCY)+"End)"),d.title!==void 0){const s=e.append("g").attr("class","stateLabel"),{x:m,y:x}=F.calcLabelPosition(i.points),g=z.getRows(d.title);let o=0;const B=[];let y=0,v=0;for(let u=0;u<=g.length;u++){const h=s.append("text").attr("text-anchor","middle").text(g[u]).attr("x",m).attr("y",x+o),w=h.node().getBBox();y=Math.max(y,w.width),v=Math.min(v,w.x),S.info(w.x,m,x+o),o===0&&(o=h.node().getBBox().height,S.info("Title height",o,x)),B.push(h)}let k=o*g.length;if(g.length>1){const u=(g.length-1)*o*.5;B.forEach((h,w)=>h.attr("y",x+w*o-u)),k=o*g.length}const r=s.node().getBBox();s.insert("rect",":first-child").attr("class","box").attr("x",m-y/2-t().state.padding/2).attr("y",x-k/2-t().state.padding/2-3.5).attr("width",y+t().state.padding).attr("height",k+t().state.padding),S.info(r)}G++},"drawEdge"),b,T={},V=f(function(){},"setConf"),tt=f(function(e){e.append("defs").append("marker").attr("id","dependencyEnd").attr("refX",19).attr("refY",7).attr("markerWidth",20).attr("markerHeight",28).attr("orient","auto").append("path").attr("d","M 19,7 L9,13 L14,7 L9,1 Z")},"insertMarkers"),et=f(function(e,i,d,c){b=t().state;const n=t().securityLevel;let l;n==="sandbox"&&(l=H("#i"+i));const p=n==="sandbox"?H(l.nodes()[0].contentDocument.body):H("body"),a=n==="sandbox"?l.nodes()[0].contentDocument:document;S.debug("Rendering diagram "+e);const s=p.select(`[id='${i}']`);tt(s);const m=c.db.getRootDoc(),x=s.append("g").attr("id",i+"-root");A(m,x,void 0,!1,p,a,c);const g=b.padding,o=s.node().getBBox(),B=o.width+g*2,y=o.height+g*2,v=B*1.75;P(s,y,v,b.useMaxWidth),s.attr("viewBox",`${o.x-b.padding} ${o.y-b.padding} `+B+" "+y)},"draw"),at=f(e=>e?e.length*b.fontSizeFactor:1,"getLabelWidth"),A=f((e,i,d,c,n,l,p)=>{const a=new O({compound:!0,multigraph:!0});let s,m=!0;for(s=0;s<e.length;s++)if(e[s].stmt==="relation"){m=!1;break}d?a.setGraph({rankdir:"LR",multigraph:!0,compound:!0,ranker:"tight-tree",ranksep:m?1:b.edgeLengthFactor,nodeSep:m?1:50,isMultiGraph:!0}):a.setGraph({rankdir:"TB",multigraph:!0,compound:!0,ranksep:m?1:b.edgeLengthFactor,nodeSep:m?1:50,ranker:"tight-tree",isMultiGraph:!0}),a.setDefaultEdgeLabel(function(){return{}});const x=p.db.getStates(),g=p.db.getRelations(),o=Object.keys(x);for(const r of o){const u=x[r];d&&(u.parentId=d);let h;if(u.doc){let w=i.append("g").attr("id",u.id).attr("class","stateGroup");h=A(u.doc,w,u.id,!c,n,l,p);{w=$(w,u,c);let E=w.node().getBBox();h.width=E.width,h.height=E.height+b.padding/2,T[u.id]={y:b.compositTitleSize}}}else h=L(i,u,a);if(u.note){const w={descriptions:[],id:u.id+"-note",note:u.note,type:"note"},E=L(i,w,a);u.note.position==="left of"?(a.setNode(h.id+"-note",E),a.setNode(h.id,h)):(a.setNode(h.id,h),a.setNode(h.id+"-note",E)),a.setParent(h.id,h.id+"-group"),a.setParent(h.id+"-note",h.id+"-group")}else a.setNode(h.id,h)}S.debug("Count=",a.nodeCount(),a);let B=0;g.forEach(function(r){B++,S.debug("Setting edge",r),a.setEdge(r.id1,r.id2,{relation:r,width:at(r.title),height:b.labelHeight*z.getRows(r.title).length,labelpos:"c"},"id"+B)}),J(a),S.debug("Graph after layout",a.nodes());const y=i.node();a.nodes().forEach(function(r){r!==void 0&&a.node(r)!==void 0?(S.warn("Node "+r+": "+JSON.stringify(a.node(r))),n.select("#"+y.id+" #"+r).attr("transform","translate("+(a.node(r).x-a.node(r).width/2)+","+(a.node(r).y+(T[r]?T[r].y:0)-a.node(r).height/2)+" )"),n.select("#"+y.id+" #"+r).attr("data-x-shift",a.node(r).x-a.node(r).width/2),l.querySelectorAll("#"+y.id+" #"+r+" .divider").forEach(h=>{const w=h.parentElement;let E=0,M=0;w&&(w.parentElement&&(E=w.parentElement.getBBox().width),M=parseInt(w.getAttribute("data-x-shift"),10),Number.isNaN(M)&&(M=0)),h.setAttribute("x1",0-M+8),h.setAttribute("x2",E-M-8)})):S.debug("No Node "+r+": "+JSON.stringify(a.node(r)))});let v=y.getBBox();a.edges().forEach(function(r){r!==void 0&&a.edge(r)!==void 0&&(S.debug("Edge "+r.v+" -> "+r.w+": "+JSON.stringify(a.edge(r))),Q(i,a.edge(r),a.edge(r).relation))}),v=y.getBBox();const k={id:d||"root",label:d||"root",width:0,height:0};return k.width=v.width+2*b.padding,k.height=v.height+2*b.padding,S.debug("Doc rendered",k,a),k},"renderDoc"),it={setConf:V,draw:et},xt={parser:W,get db(){return new N(1)},renderer:it,styles:R,init:f(e=>{e.state||(e.state={}),e.state.arrowMarkerAbsolute=e.arrowMarkerAbsolute},"init")};export{xt as diagram}; diff --git a/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-0KuGlzV7.js b/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-0KuGlzV7.js new file mode 100644 index 000000000..cc6c7d042 --- /dev/null +++ b/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-0KuGlzV7.js @@ -0,0 +1 @@ +import{s as r,b as e,a,S as s}from"./chunk-EX3LRPZG-BCWDroXJ.js";import{_ as i}from"./mermaid.core-CJB1tAev.js";import"./chunk-XXDRQBXY-5rh7CWvm.js";import"./chunk-VR4S4FIN-CEH7JYJn.js";import"./chunk-32BRIVSS-DUDRPqmY.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var n={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{n as diagram}; diff --git a/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-B_OpM2in.js b/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-B_OpM2in.js deleted file mode 100644 index 5e54e3ff4..000000000 --- a/apps/kimi-code/dist-web/assets/stateDiagram-v2-6OUMAXLB-B_OpM2in.js +++ /dev/null @@ -1 +0,0 @@ -import{s as r,b as e,a,S as s}from"./chunk-EX3LRPZG-CyUsdK3n.js";import{_ as i}from"./mermaid.core-DaDTfY6S.js";import"./chunk-XXDRQBXY-BEgNawAD.js";import"./chunk-VR4S4FIN-Dzr2NgNj.js";import"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var n={parser:a,get db(){return new s(2)},renderer:e,styles:r,init:i(t=>{t.state||(t.state={}),t.state.arrowMarkerAbsolute=t.arrowMarkerAbsolute},"init")};export{n as diagram}; diff --git a/apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-C4tzl2F_.js b/apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-D6xMtJ1E.js similarity index 99% rename from apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-C4tzl2F_.js rename to apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-D6xMtJ1E.js index c2c847da9..f67834e7f 100644 --- a/apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-C4tzl2F_.js +++ b/apps/kimi-code/dist-web/assets/swimlanes-5IMT3BWC-D6xMtJ1E.js @@ -1,2 +1,2 @@ -const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sizeCapture-X5ZJPWSS-JndNlF5C.js","assets/mermaid.core-DaDTfY6S.js","assets/index-D1h84VfZ.js","assets/index-BTY1et1y.css","assets/_commonjsHelpers-CqkleIqs.js"])))=>i.map(i=>d[i]); -import{bR as Er}from"./index-D1h84VfZ.js";import{c as Tr}from"./chunk-RYQCIY6F-D1Yl7opn.js";import{am as wr,an as Ar,ao as Rr,ap as Nr,l as Ke,c as Or,ag as Pr,af as Br,ah as kr,at as _r,av as Fr,z as Dr,as as Hr,aw as Xr,y as Oe,ax as Ye,_ as d,ay as Ao}from"./mermaid.core-DaDTfY6S.js";import{G as Yr}from"./graph-DOmOIIwC.js";import"./map-DxJ2ADlA.js";import"./_commonjsHelpers-CqkleIqs.js";async function _o(t,e){const n=new Yr({multigraph:!0,compound:!0}),o=[...e.edges],s=Or(),r=t.insert("g").attr("class","root"),i=r.insert("g").attr("class","clusters"),c=r.insert("g").attr("class","edges edgePath"),a=r.insert("g").attr("class","edgeLabels"),l=r.insert("g").attr("class","nodes"),g=new Map,x=t.node()!=null;await Promise.all(e.nodes.map(async I=>{if(I.isGroup)n.setNode(I.id,{...I});else{if(x){const u=await Pr(l,I,{config:s,dir:I.dir}),p=u.node()?.getBBox()??{width:0,height:0};g.set(I.id,u),I.width=p.width,I.height=p.height}n.setNode(I.id,{...I})}}));for(const I of o)n.setEdge(I.start,I.end,{...I},I.id),e.edges.some(p=>p.id===I.id)||e.edges.push(I);if(globalThis.mermaidCaptureSizes){const{captureNodeSizes:I}=await Er(async()=>{const{captureNodeSizes:u}=await import("./sizeCapture-X5ZJPWSS-JndNlF5C.js");return{captureNodeSizes:u}},__vite__mapDeps([0,1,2,3,4]));I(t,e)}return{graph:n,groups:{clusters:i,edgePaths:c,edgeLabels:a,nodes:l,rootGroups:r},nodeElements:g}}d(_o,"createGraphWithElements");var Ro=5,Ge=1e-5,$e=1e-6;function qe(t){const e=[];for(let n=0;n<t.length-1;n++)e.push({a:t[n],b:t[n+1]});return e}d(qe,"buildSegmentList");function Fo(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=o.x-n.x,c=o.y-n.y,a=s*c-r*i;if(a===0)return null;const l=n.x-t.x,g=n.y-t.y,x=(l*c-g*i)/a,I=(l*r-g*s)/a;return x<=$e||x>=1-$e||I<=$e||I>=1-$e?null:{point:{x:t.x+x*s,y:t.y+x*r},tA:x,tB:I}}d(Fo,"segmentIntersection");function vn(t){return Math.abs(t.b.x-t.a.x)>=Math.abs(t.b.y-t.a.y)}d(vn,"isHorizontalSeg");function Do(t){const e=[];for(let n=0;n<t.length;n++){const o=t[n],s=qe(o.points);for(let r=n+1;r<t.length;r++){const i=t[r],c=qe(i.points);for(const[a,l]of s.entries())for(const[g,x]of c.entries()){const I=Fo(l.a,l.b,x.a,x.b);if(!I)continue;const u=vn(l),p=vn(x);(u!==p?u:!1)?e.push({jumpEdgeId:o.id,otherEdgeId:i.id,segIndex:a,t:I.tA,point:I.point}):e.push({jumpEdgeId:i.id,otherEdgeId:o.id,segIndex:g,t:I.tB,point:I.point})}}}return e}d(Do,"findEdgeIntersections");function re(t){const e=Math.round(t*1e3)/1e3;return Number.isInteger(e)?`${e}`:`${e}`}d(re,"fmt");function we(t){return`${re(t.x)},${re(t.y)}`}d(we,"pointToString");function Ho(t){const e=t.b.x-t.a.x,n=t.b.y-t.a.y;return Math.abs(e)>=Math.abs(n)?e>=0?1:0:n>=0?1:0}d(Ho,"getArcSweepFlag");var Gr=.001;function Xo(t,e){if(t.length<2)return t.map(r=>({...r}));const n=t.map(r=>({...r})),o=e.arrowTypeStart&&Ao[e.arrowTypeStart];if(o){const r=t[0],i=t[1],c=Math.atan2(i.y-r.y,i.x-r.x);n[0].x=r.x+o*Math.cos(c),n[0].y=r.y+o*Math.sin(c)}const s=e.arrowTypeEnd&&Ao[e.arrowTypeEnd];if(s){const r=t.length,i=t[r-2],c=t[r-1],a=Math.atan2(c.y-i.y,c.x-i.x);n[r-1].x=c.x-s*Math.cos(a),n[r-1].y=c.y-s*Math.sin(a)}return n}d(Xo,"applyMarkerOffsets");function Yo(t,e,n,o,s){const r=t.point.x,i=t.point.y,c={x:r-e*t.r,y:i-n*t.r},a={x:r+e*t.r,y:i+n*t.r},l=[`L${we(c)}`];return s==="arc"?l.push(`A${re(t.r)},${re(t.r)} 0 0 ${o} ${we(a)}`):l.push(`M${we(a)}`),l}d(Yo,"emitJump");function Ln(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=n.x-e.x,c=n.y-e.y,a=Math.hypot(s,r),l=Math.hypot(i,c);if(a<Ge||l<Ge)return null;const g=s/a,x=r/a,I=i/l,u=c/l,p=g*I+x*u,f=Math.max(-1,Math.min(1,p)),y=Math.acos(f);if(y<Ge||Math.abs(Math.PI-y)<Ge)return null;const v=Math.min(o/Math.sin(y/2),a/2,l/2);return{startX:e.x-g*v,startY:e.y-x*v,endX:e.x+I*v,endY:e.y+u*v,ctrlX:e.x,ctrlY:e.y,cutLen:v}}d(Ln,"computeRoundedCorner");function Go(t,e,n){const o=t.points;if(o.length<2)return"";const s=Xo(o,t),r=t.curve==="rounded",i=qe(s),c=new Map;for(const l of e){const g=i[l.segIndex];if(!g)continue;const x=Math.hypot(g.b.x-g.a.x,g.b.y-g.a.y),I=c.get(l.segIndex)??[];I.push({t:l.t,point:l.point,d:l.t*x,r:n.jumpRadius}),c.set(l.segIndex,I)}const a=[`M${we(s[0])}`];for(let l=0;l<i.length;l++){const g=i[l],x=Math.hypot(g.b.x-g.a.x,g.b.y-g.a.y),I=x===0?0:(g.b.x-g.a.x)/x,u=x===0?0:(g.b.y-g.a.y)/x,p=Ho(g);let f=0;if(r&&l>0){const E=Ln(s[l-1],s[l],s[l+1]??s[l],Ro);E&&(f=E.cutLen)}let y=x,v=null;r&&l<i.length-1&&(v=Ln(s[l],s[l+1],s[l+2]??s[l+1],Ro),v&&(y=x-v.cutLen));const M=[...c.get(l)??[]].sort((E,T)=>E.t-T.t);for(const E of M)E.r=Math.min(E.r,E.d-f,y-E.d);for(let E=0;E<M.length-1;E++){const T=M[E+1].d-M[E].d;if(M[E].r+M[E+1].r>T){const m=T/2;M[E].r=Math.min(M[E].r,m),M[E+1].r=Math.min(M[E+1].r,m)}}for(const E of M)E.r<Gr||a.push(...Yo(E,I,u,p,n.jumpStyle));r&&v?(a.push(`L${re(v.startX)},${re(v.startY)}`),a.push(`Q${re(v.ctrlX)},${re(v.ctrlY)} ${re(v.endX)},${re(v.endY)}`)):a.push(`L${we(g.b)}`)}return a.join(" ")}d(Go,"rewriteEdgePath");function $o(t){return/^[\d\s+,.LMelm-]*$/.test(t)}d($o,"isStraightPath");function zo(t){return t?t==="linear"||t==="rounded"||t==="step"||t==="stepBefore"||t==="stepAfter":!0}d(zo,"curveSupportsLineHops");function Vo(t){if(!t)return null;try{const e=typeof atob=="function"?atob(t):Buffer.from(t,"base64").toString(),n=JSON.parse(e);if(!Array.isArray(n))return null;const o=[];for(const s of n)s&&typeof s.x=="number"&&typeof s.y=="number"&&o.push({x:s.x,y:s.y});return o.length>=2?o:null}catch{return null}}d(Vo,"decodeDataPoints");function jo(t,e,n){if(!n.enabled)return;const o=t.node();if(!o)return;const s=new Map;for(const l of e)s.set(l.id,l);const r=[],i=new Map;for(const l of e){const g=typeof CSS<"u"&&CSS.escape?CSS.escape(l.id):l.id,x=o.querySelector(`path[data-id="${g}"]`);if(!x)continue;i.set(l.id,x);const u=Vo(x.getAttribute("data-points"))??l.points;r.push({...l,points:u})}const c=Do(r);if(c.length===0)return;const a=new Map;for(const l of c){const g=a.get(l.jumpEdgeId)??[];g.push(l),a.set(l.jumpEdgeId,g)}for(const l of r){const g=a.get(l.id);if(!g||g.length===0)continue;const I=s.get(l.id)?.curve;if(I!==void 0&&!zo(I))continue;const u=i.get(l.id);if(!u)continue;if(I===void 0){const E=u.getAttribute("d")??"";if(!$o(E))continue}const p=u.getAttribute("style")??"",f=/stroke-dasharray\s*:\s*0\s+([\d.]+)\s+[\d.]+\s+([\d.]+)/.exec(p),y=f?Number.parseFloat(f[1]):null,v=f?Number.parseFloat(f[2]):null,M=Go(l,g,n);if(u.setAttribute("d",M),y!==null&&v!==null&&typeof u.getTotalLength=="function"){const E=u.getTotalLength(),T=Math.max(0,E-y-v),m=`0 ${y} ${T} ${v}`,S=p.replace(/stroke-dasharray\s*:[^;]*;?/g,`stroke-dasharray: ${m};`).replace(/;\s*;+/g,";");u.setAttribute("style",S)}}}d(jo,"applyLineJumpsToSvg");async function Uo(t,e){for(const s of t.nodes)s.isGroup?await Br(e.clusters,s):kr(s);const n=new Map;for(const s of t.nodes)s?.id&&n.set(s.id,s);for(const s of t.edges){const r=s.start?n.get(s.start)??{}:{},i=s.end?n.get(s.end)??{}:{},c=_r(e.edgePaths,{...s},{},t.type,r,i,t.diagramId);s.label&&await Fr(e.rootGroups,s),s.label&&Wo(s,c)}const o=t.config?.swimlane?.lineHops;if(o!==!1){const s=o==="gap"?"gap":"arc",r=t.edges.filter(i=>Array.isArray(i.points)&&i.points.length>=2).map(i=>({id:i.id,points:i.points,curve:i.curve,arrowTypeStart:i.arrowTypeStart,arrowTypeEnd:i.arrowTypeEnd}));jo(e.edgePaths,r,{enabled:!0,jumpRadius:6,jumpStyle:s})}}d(Uo,"adjustLayout");function Wo(t,e){const n=e?.updatedPath??e?.originalPath,o=Dr(),{subGraphTitleTotalMargin:s}=Hr({flowchart:o.flowchart??{}});if(t.label){const r=Xr.get(t.id);let i=t.x,c=t.y;if(n){const a=Oe.calcLabelPosition(n);Ke.debug("Moving label "+t.label+" from (",i,",",c,") to (",a.x,",",a.y,") abc88"),e&&(i=a.x,c=a.y)}r.attr("transform",`translate(${i}, ${c+s/2})`)}if(t?.startLabelLeft){const r=Ye.get(t.id).startLeft;let i=t?.x,c=t?.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.startLabelRight){const r=Ye.get(t.id).startRight;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.endLabelLeft){const r=Ye.get(t.id).endLeft;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.endLabelRight){const r=Ye.get(t.id).endRight;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}}d(Wo,"positionEdgeLabel");var Mn="__swimlane_default__",$r=21,No=20;function En(t){return Math.max(t.padding??No,No)}d(En,"topLaneHorizontalPadding");function Ko(t){const{x:e,y:n,width:o,height:s}=t,r=t.swimlaneContentTop;if(typeof e!="number"||typeof n!="number"||typeof o!="number"||typeof s!="number"||typeof r!="number"||!Number.isFinite(e)||!Number.isFinite(n)||!Number.isFinite(o)||!Number.isFinite(s)||!Number.isFinite(r)||o<=0||s<=0){delete t.groupTitleRect;return}const i=n-s/2,c=Math.min(r,n+s/2),a=Math.min($r,Math.max(0,c-i)),l=i+a;if(l<=i){delete t.groupTitleRect;return}t.groupTitleRect={left:e-o/2,right:e+o/2,top:i,bottom:l}}d(Ko,"assignTopLaneTitleRect");function qo(t){const e=t.direction,n=t.nodes??=[];for(const r of t.nodes??[])r.isGroup&&!r.parentId&&(r.shape="swimlane",e&&(r.direction=e));const o=n.filter(r=>!r.isGroup&&!r.parentId);if(o.length===0)return;let s=n.find(r=>r.id===Mn);s?s.isGroup&&(s.shape="swimlane",e&&(s.direction=e)):(s={id:Mn,label:"",isGroup:!0,shape:"swimlane",padding:20,...e?{direction:e}:{}},n.push(s));for(const r of o)r.parentId=Mn}d(qo,"prepareLayoutForSwimlanes");function Jo(t){const e=new Map;for(const a of t.nodes??[])e.set(a.id,a);const n=[];for(const a of t.edges??[]){const l=typeof a.start=="string"?a.start:void 0,g=typeof a.end=="string"?a.end:void 0;!l||!g||a.labelNodeId||n.push({id:a.id,src:l,dst:g,ref:a})}const o=t.nodes??[],s=o.filter(a=>a.isGroup),r=o.filter(a=>!a.isGroup);return{nodes:[...[...s].reverse(),...r].map(a=>a.id),edges:n,layout:t,nodeById:e}}d(Jo,"toGraphView");function Zo(t,e,n,o){const{layout:s}=t,r=t.nodeById,i=o?.layerGap??100,c=o?.nodeGap??40;let a=0;for(const I of e.layers){let u=0;for(const p of I){const f=r.get(p);if(!f){u++;continue}f.layer=a,f.order=u;const y=n.x[p]??u*c,v=n.y[p]??a*i;f.x=y,f.y=v,u++}a++}const l=s.nodes??[],g=new Map,x=[];for(const I of l){if(!I?.isGroup)continue;I.parentId||x.push(I);const u=l.filter(M=>M.parentId===I.id);let p=1/0,f=-1/0,y=1/0,v=-1/0;for(const M of u){const E=M.x??n.x[M.id],T=M.y??n.y[M.id],m=M.width??0,S=M.height??0;E!=null&&T!=null&&(p=Math.min(p,E-m/2),f=Math.max(f,E+m/2),y=Math.min(y,T-S/2),v=Math.max(v,T+S/2))}if(p===1/0||y===1/0)I.x=I.x??0,I.y=I.y??0,I.width=I.width??0,I.height=I.height??0;else{const M=I.padding??20,E=I.parentId?M:2*En(I),T=M,m=Math.max(0,f-p)+E,S=Math.max(0,v-y)+T,A=(p+f)/2,R=(y+v)/2;I.x=A,I.y=R,I.width=m,I.height=S,g.set(I.id,{minX:p,maxX:f,minY:y,maxY:v})}}if(x.length>0&&g.size>0){let I=1/0,u=-1/0,p=0;for(const f of x){const y=f.padding??20;y>p&&(p=y);const v=g.get(f.id);v&&(I=Math.min(I,v.minY),u=Math.max(u,v.maxY))}if(I!==1/0&&u!==-1/0){const f=Math.max(0,u-I),v=Math.max(p,36),M=f+2*v,E=(I+u)/2;for(const k of x)k.y=E,k.height=M,k.swimlaneContentTop=I;const T=[...x].sort((k,O)=>{const _=k.x??0,H=O.x??0;return _-H}),m=[],S=[],A=[];for(const k of T){const O=g.get(k.id);if(!O)continue;const _=Math.max(0,O.maxX-O.minX)+2*En(k),H=(O.minX+O.maxX)/2;m.push(k.id),S.push(H),A.push(_)}const R=m.length;if(R>0){const k=new Map;if(R===1)k.set(m[0],A[0]);else{const O=[];for(let j=0;j<R-1;j++)O.push(S[j+1]-S[j]);const _=new Array(R);_[0]=0;for(let j=0;j<R-1;j++)_[j+1]=2*O[j]-_[j];let H=0,P=Number.POSITIVE_INFINITY;for(let j=0;j<R;j++){const J=A[j];j%2===0?H=Math.max(H,J-_[j]):P=Math.min(P,_[j]-J)}let G=H;H<=P?G=(H+P)/2:G=H;for(let j=0;j<R;j++){const J=_[j]+(j%2===0?G:-G),dt=Math.max(A[j],J);k.set(m[j],dt)}}for(const O of x){const _=k.get(O.id);_!=null&&(O.width=_),Ko(O)}}}}}d(Zo,"writeBackToLayoutData");var zr="[EdgeLabelNodes]";function Qo(t){const e=[],n=[],o=new Map;for(const i of t.nodes)o.set(i.id,i);for(const i of t.edges){if(!i.label||i.label.length===0||i.isLayoutOnly||i.labelNodeId)continue;const c=i.start?o.get(i.start):void 0,a=i.end?o.get(i.end):void 0;if(!c||!a){Ke.warn(zr,`Edge ${i.id} has missing source or target node`);continue}const l=`edge-label-${i.start}-${i.end}-${i.id}`,x=c.parentId!==a.parentId?a.parentId:c.parentId,I={id:l,label:i.label,edgeStart:i.start??"",edgeEnd:i.end??"",shape:"labelRect",width:0,height:0,isEdgeLabel:!0,isDummy:!0,parentId:x,isGroup:!1,labelStyle:Array.isArray(i.labelStyle)?i.labelStyle[0]:i.labelStyle??"",...c.dir?{dir:c.dir}:{}};e.push(I),i.labelNodeId=l,i.label=void 0,i.text=void 0;const u={id:`${i.id}-to-label`,start:i.start,end:l,type:"normal",isLayoutOnly:!0},p={id:`${i.id}-from-label`,start:l,end:i.end,type:"normal",isLayoutOnly:!0};n.push(u,p)}const s=[...t.nodes,...e],r=[...t.edges,...n];return{...t,nodes:s,edges:r}}d(Qo,"createEdgeLabelNodes");var Ft=.001;function oo(t){const e=t.x??0,n=t.y??0,o=t.width??0,s=t.height??0;return o>0&&s>0?{cx:e,cy:n,rect:Ae(e,n,o,s)}:void 0}d(oo,"measuredNodeRect");function so(t){if(t.isGroup)return;const e=oo(t);return e?{id:String(t.id??""),cx:e.cx,cy:e.cy,rect:e.rect}:void 0}d(so,"nodeBoundsInfoFor");function oe(t,e,n=Ft){return Math.abs(t.x-e.x)<n&&Math.abs(t.y-e.y)<n}d(oe,"samePoint");function ft(t,e,n=Ft){return Math.abs(t.x-e.x)<n}d(ft,"sameX");function ht(t,e,n=Ft){return Math.abs(t.y-e.y)<n}d(ht,"sameY");function Tt(t,e,n=Ft){return ht(t,e,n)&&Math.abs(t.x-e.x)>n}d(Tt,"isHorizontalSegment");function wt(t,e,n=Ft){return ft(t,e,n)&&Math.abs(t.y-e.y)>n}d(wt,"isVerticalSegment");function zt(t,e,n,o){return Math.max(0,Math.min(Math.max(t,e),Math.max(n,o))-Math.max(Math.min(t,e),Math.min(n,o)))}d(zt,"overlapLength");function ce(t,e,n=Ft){return t.horizontal&&e.horizontal&&ht(t.a,e.a,n)?zt(t.a.x,t.b.x,e.a.x,e.b.x):t.vertical&&e.vertical&&ft(t.a,e.a,n)?zt(t.a.y,t.b.y,e.a.y,e.b.y):0}d(ce,"sameAxisSegmentOverlapLength");function Re(t,e=Ft){const n=[];for(let o=0;o<t.length-1;o++){const s=t[o],r=t[o+1],i=Tt(s,r,e),c=wt(s,r,e);(i||c)&&n.push({index:o,a:s,b:r,horizontal:i,vertical:c})}return n}d(Re,"orthogonalSegmentsForPoints");function Qt(t,e=Ft){const n=Re(t,e);let o=0;for(let s=1;s<n.length;s++)n[s-1].horizontal!==n[s].horizontal&&o++;return o}d(Qt,"countOrthogonalBends");function pt(t,e=Ft){const n=[];for(const o of t){const s=n.length>0?n[n.length-1]:void 0;(!s||!oe(s,o,e))&&n.push({x:o.x,y:o.y})}return n}d(pt,"dedupeConsecutivePoints");function ro(t,e=Ft){if(!t||t.length!==4)return;const[n,o,s,r]=t;return Tt(n,o,e)&&wt(o,s,e)&&Tt(s,r,e)?{kind:"HVH",p0:n,p1:o,p2:s,p3:r}:wt(n,o,e)&&Tt(o,s,e)&&wt(s,r,e)?{kind:"VHV",p0:n,p1:o,p2:s,p3:r}:void 0}d(ro,"classifyThreeSegmentRoute");function cn(t,e,n,o=0){const s=Math.min(t.x,e.x),r=Math.max(t.x,e.x),i=Math.min(t.y,e.y),c=Math.max(t.y,e.y);return r>n.left-o&&s<n.right+o&&c>n.top-o&&i<n.bottom+o}d(cn,"segmentBoundsOverlapRect");function io(t,e,n=0){return t.x>e.left+n&&t.x<e.right-n&&t.y>e.top+n&&t.y<e.bottom-n}d(io,"pointInsideRect");function ts(t,e){return t.left<=e.left&&t.right>=e.right&&t.top<=e.top&&t.bottom>=e.bottom}d(ts,"rectContainsRect");function Je(t,e){return t.left<e.right&&t.right>e.left&&t.top<e.bottom&&t.bottom>e.top}d(Je,"rectsOverlap");function Tn(t,e){return{left:t.left-e,right:t.right+e,top:t.top-e,bottom:t.bottom+e}}d(Tn,"inflateRect");function Ae(t,e,n,o){return{left:t-n/2,right:t+n/2,top:e-o/2,bottom:e+o/2}}d(Ae,"rectFromCenterSize");function qt(t){return oo(t)?.rect}d(qt,"rectOfNodeBounds");function Ie(t,e){switch(e){case"top":return{x:t.cx,y:t.rect.top};case"bottom":return{x:t.cx,y:t.rect.bottom};case"left":return{x:t.rect.left,y:t.cy};case"right":return{x:t.rect.right,y:t.cy}}}d(Ie,"portForRectSide");function co(t,e,n,o,s,r=Ft){const i=e==="left"||e==="right",c=o==="left"||o==="right";if(i&&c){if(e==="right"&&o==="left"&&t.x<n.x||e==="left"&&o==="right"&&t.x>n.x){if(ht(t,n,r))return[t,n];const x=(t.x+n.x)/2;return[t,{x,y:t.y},{x,y:n.y},n]}if(e===o){if(ht(t,n,r))return;const x=e==="left"?Math.min(t.x,n.x)-s:Math.max(t.x,n.x)+s;return[t,{x,y:t.y},{x,y:n.y},n]}return}if(!i&&!c){if(e===o){if(ft(t,n,r))return;const I=e==="top"?Math.min(t.y,n.y)-s:Math.max(t.y,n.y)+s;return[t,{x:t.x,y:I},{x:n.x,y:I},n]}if(!(e==="bottom"&&o==="top"&&t.y<n.y||e==="top"&&o==="bottom"&&t.y>n.y))return;if(ft(t,n,r))return[t,n];const x=(t.y+n.y)/2;return[t,{x:t.x,y:x},{x:n.x,y:x},n]}if(i&&!c){const g=e==="right"&&n.x>t.x||e==="left"&&n.x<t.x,x=o==="top"&&t.y<n.y||o==="bottom"&&t.y>n.y;return g&&x?[t,{x:n.x,y:t.y},n]:void 0}const a=e==="bottom"&&n.y>t.y||e==="top"&&n.y<t.y,l=o==="left"&&t.x<n.x||o==="right"&&t.x>n.x;return a&&l?[t,{x:t.x,y:n.y},n]:void 0}d(co,"buildOrthogonalPortPath");function ao(t,e,n,o){return e==="left"||e==="right"?[t,{x:o,y:t.y},{x:o,y:n.y},n]:[t,{x:t.x,y:o},{x:n.x,y:o},n]}d(ao,"buildSameSideTrackPath");function an(t){const e=new Map,n=[];for(const o of t){if(o.isEdgeLabel)continue;const s=so(o);s&&(e.set(s.id,s),n.push({id:s.id,rect:s.rect}))}return{nodeInfoById:e,realNodeRects:n}}d(an,"collectRealNodeBounds");function me(t){const e=[],n=[];for(const o of t){const s=so(o);if(!s)continue;const r={id:s.id,rect:s.rect};o.isEdgeLabel?n.push(r):e.push(r)}return{realNodeRects:e,labelNodeRects:n}}d(me,"collectNodeRectEntries");function es(t,{includeEdgeLabels:e=!0}={}){const n=[];for(const o of t){if(o.isGroup||!e&&o.isEdgeLabel)continue;const s=o.x??0,r=o.y??0,i=o.width??0,c=o.height??0;n.push({nodeId:o.id,...Ae(s,r,i,c)})}return n}d(es,"collectLayoutNodeRects");function lo(t,e,n=Ft){const o=t.start,s=t.end;if(!o||!s)return;const r=e.get(o),i=e.get(s);if(!(!r||!i))return{srcId:o,dstId:s,srcInfo:r,dstInfo:i,collinearX:Math.abs(r.cx-i.cx)<n,collinearY:Math.abs(r.cy-i.cy)<n}}d(lo,"getNodePairGeometry");function At(t,e,n,o=[],s=0){for(const r of n)if(!o.includes(r.id)&&cn(t,e,r.rect,-s))return!0;return!1}d(At,"segmentHitsAnyRect");function fo(t,e,n,o,s=Ft,r=1e-6){const i=ht(t,e,s),c=ft(t,e,s),a=ht(n,o,s),l=ft(n,o,s);if(i&&a||c&&l||!(i||c)||!(a||l))return!1;const g=i?{a:t,b:e}:{a:n,b:o},x=c?{a:t,b:e}:{a:n,b:o},I=g.a.y,u=Math.min(g.a.x,g.b.x),p=Math.max(g.a.x,g.b.x),f=x.a.x,y=Math.min(x.a.y,x.b.y),v=Math.max(x.a.y,x.b.y);if(f<u||f>p||I<y||I>v)return!1;const M=Math.abs(f-g.a.x)<r&&Math.abs(I-g.a.y)<r||Math.abs(f-g.b.x)<r&&Math.abs(I-g.b.y)<r,E=Math.abs(f-x.a.x)<r&&Math.abs(I-x.a.y)<r||Math.abs(f-x.b.x)<r&&Math.abs(I-x.b.y)<r;return!(M&&E)}d(fo,"orthogonalSegmentsCross");function ns(t,e,n,o,s=Ft){const r=ht(t,e,s),i=ft(t,e,s),c=ht(n,o,s),a=ft(n,o,s);return i&&a&&ft(t,n,s)?zt(t.y,e.y,n.y,o.y)>s:r&&c&&ht(t,n,s)?zt(t.x,e.x,n.x,o.x)>s:!1}d(ns,"sameAxisSegmentsOverlap");function Ze(t,e,n,o,{epsilon:s=Ft,skipDegenerateOther:r=!1}={}){for(const i of n){if(i===o||i.isLayoutOnly)continue;const c=i.points;if(!(!c||c.length<2))for(let a=0;a<c.length-1;a++){const l=c[a],g=c[a+1];if(!(r&&oe(l,g,s))&&(fo(t,e,l,g,s)||ns(t,e,l,g,s)))return!0}}return!1}d(Ze,"segmentConflictsWithAnyEdge");function le(t,e,n,o,s=Ft){const r=ht(t,e,s),i=ft(t,e,s),c=ht(n,o,s),a=ft(n,o,s);if(!(r&&a||i&&c))return!1;const l=r?{a:t,b:e}:{a:n,b:o},g=r?{a:n,b:o}:{a:t,b:e},x=l.a.y,I=Math.min(l.a.x,l.b.x),u=Math.max(l.a.x,l.b.x),p=g.a.x,f=Math.min(g.a.y,g.b.y),y=Math.max(g.a.y,g.b.y);return p>I+s&&p<u-s&&x>f+s&&x<y-s}d(le,"orthogonalSegmentsStrictlyCross");function wn(t,e,n){const o=Math.min(e,n),s=Math.max(e,n);return t>o+Ft&&t<s-Ft}d(wn,"strictlyBetween");function os(t,e,n){return ft(t,e)&&ft(e,n)?wn(e.y,t.y,n.y):ht(t,e)&&ht(e,n)?wn(e.x,t.x,n.x):!1}d(os,"isCollinearIntermediate");function ss(t){let e=!1;const n=[];for(let o=0;o<t.length;o++){const s=n[n.length-1],r=t[o],i=o+1<t.length?t[o+1]:void 0;if(s&&i){if(oe(s,i)){o++,e=!0;continue}if(os(s,r,i)){e=!0;continue}}n.push(r)}return{points:n,changed:e}}d(ss,"simplifyPolylineOnce");function Qe(t){const e=[t[0]];for(let o=1;o<t.length;o++){const s=e[e.length-1],r=t[o];if(!ft(s,r)&&!ht(s,r)){const i=e.length>=2?e[e.length-2]:void 0,a=(i?ft(i,s):!1)?{x:s.x,y:r.y}:{x:r.x,y:s.y};e.push(a)}e.push(r)}const n=[];for(const o of e){const s=n[n.length-1];(!s||!oe(s,o))&&n.push(o)}return n}d(Qe,"orthogonalizePolyline");function ae(t){if(t.length<3)return t;let e=[...t];for(let n=0;n<32;n++){const o=ss(e);if(e=o.points,!o.changed)break}return e}d(ae,"simplifyPolyline");var nt=.001,Vr=.5,Oo=4;function uo(t,e,n){const o=t;if(o.isLayoutOnly||!o.points||o.points.length<n)return;const s=o.start?e.get(o.start):void 0,r=o.end?e.get(o.end):void 0;return{edge:o,points:o.points,srcRect:s?qt(s):void 0,dstRect:r?qt(r):void 0}}d(uo,"endpointContextFor");function rs(t,e,n){if(ht(t,e,nt))return{x:t.x<n.left?n.left:n.right,y:t.y};if(ft(t,e,nt)){const o=t.y<n.top?n.top:n.bottom;return{x:t.x,y:o}}return{x:Math.min(n.right,Math.max(n.left,t.x)),y:Math.min(n.bottom,Math.max(n.top,t.y))}}d(rs,"segmentEnterPoint");function An(t,e,n){const o=n?1:-1;let s=n?0:t.length-1;for(;s>=0&&s<t.length&&io(t[s],e,Vr);)s+=o;if(s<0||s>=t.length)return t;const r=s-o;if(r<0||r>=t.length)return t;const i=rs(t[s],t[r],e);return n?[i,...t.slice(s)]:[...t.slice(0,s+1),i]}d(An,"clipEndpoint");function is(t,e){for(const n of t){const o=uo(n,e,2);if(!o)continue;let s=[...o.points];o.srcRect&&(s=An(s,o.srcRect,!0)),o.dstRect&&(s=An(s,o.dstRect,!1)),s=ae(Qe(s)),s=ho(s,o.srcRect,o.dstRect),o.edge.points=ae(Qe(s))}}d(is,"clipEdgeEndpointsToNodeBoundaries");function Rn(t,e,n,o=!1){if(ht(t,e,nt)){if(e.y<n.top-nt||e.y>n.bottom+nt)return e;if(o){if(t.x<n.left-nt)return{x:n.left,y:t.y};if(t.x>n.right+nt)return{x:n.right,y:t.y}}return{x:Math.abs(e.x-n.left)<=Math.abs(e.x-n.right)?n.left:n.right,y:t.y}}if(ft(t,e,nt)){if(e.x<n.left-nt||e.x>n.right+nt)return e;if(o){if(t.y<n.top-nt)return{x:t.x,y:n.top};if(t.y>n.bottom+nt)return{x:t.x,y:n.bottom}}const s=Math.abs(e.y-n.top)<=Math.abs(e.y-n.bottom);return{x:t.x,y:s?n.top:n.bottom}}return e}d(Rn,"snapEndpointToBoundary");function tn(t,e,n){const o=t[e];for(let s=e+n;s>=0&&s<t.length;s+=n){const r=t[s];if(!oe(r,o,nt))return r}return t[e+n]}d(tn,"firstDistinctAdjacent");function en(t,e){const n=t+Oo,o=e-Oo;return n<=o?{lo:n,hi:o}:{lo:(t+e)/2,hi:(t+e)/2}}d(en,"cornerClearanceRange");function Nn(t,e,n){const{lo:o,hi:s}=en(e,n);return Math.min(s,Math.max(o,t))}d(Nn,"clampToCornerClearance");function cs(t){const e=Math.max(...t.map(o=>o.lo)),n=Math.min(...t.map(o=>o.hi));if(!(e>n))return{lo:e,hi:n}}d(cs,"intersectRanges");function On(t,e){return e==="left"||e==="right"?en(t.top,t.bottom):en(t.left,t.right)}d(On,"clearanceRangeForSide");function nn(t,e,n){const o=t.y>=n.top-nt&&t.y<=n.bottom+nt,s=t.x>=n.left-nt&&t.x<=n.right+nt;if(ht(t,e,nt)&&o){if(Math.abs(t.x-n.left)<nt)return"left";if(Math.abs(t.x-n.right)<nt)return"right"}if(ft(t,e,nt)&&s){if(Math.abs(t.y-n.top)<nt)return"top";if(Math.abs(t.y-n.bottom)<nt)return"bottom"}}d(nn,"terminalSideForSegment");function Pe(t){return t==="left"||t==="right"}d(Pe,"isHorizontalSide");function as(t,e,n,o,s){const r=[],i=n?nn(t,e,n):void 0,c=o?nn(e,t,o):void 0;return n&&i&&Pe(i)===s&&r.push(On(n,i)),o&&c&&Pe(c)===s&&r.push(On(o,c)),r.length>0?cs(r):void 0}d(as,"straightClearanceRange");function Pn(t,e,n,o,s){const r=as(t,e,n,o,s);if(!r)return;const i=s?t.y:t.x,c=Math.min(r.hi,Math.max(r.lo,i));if(!(Math.abs(c-i)<nt))return s?[{x:t.x,y:c},{x:e.x,y:c}]:[{x:c,y:t.y},{x:c,y:e.y}]}d(Pn,"clearStraightEndpointCornerAxis");function ho(t,e,n){if(t.length!==2)return t;const[o,s]=t;return ht(o,s,nt)?Pn(o,s,e,n,!0)??t:ft(o,s,nt)?Pn(o,s,e,n,!1)??t:t}d(ho,"clearStraightEndpointCornerConnections");function ls(t,e,n){return Pe(n)?{x:t.x,y:Nn(t.y,e.top,e.bottom)}:{x:Nn(t.x,e.left,e.right),y:t.y}}d(ls,"cornerClearedEndpoint");function fs(t,e,n,o,s,r){const i=t.map(c=>({...c}));for(let c=e;c>=0&&c<t.length;c+=n){const a=t[c];if(r&&!ht(a,o,nt)||!r&&!ft(a,o,nt))break;r?i[c].y=s.y:i[c].x=s.x}return i}d(fs,"moveCollinearEndpointRun");function Bn(t,e,n){if(t.length<2)return t;const o=n?0:t.length-1,s=n?1:-1,r=t[o],i=tn(t,o,s);if(!i)return t;const c=nn(r,i,e);if(!c)return t;const a=Pe(c),l=ls(r,e,c);return oe(r,l,nt)?t:fs(t,o,s,r,l,a)}d(Bn,"clearEndpointCornerConnection");function kn(t,e,n){const o=Math.min(t.x,e.x)>=n.left-nt&&Math.max(t.x,e.x)<=n.right+nt,s=Math.min(t.y,e.y)>=n.top-nt&&Math.max(t.y,e.y)<=n.bottom+nt;if(Math.abs(t.y-n.top)<nt&&Math.abs(e.y-n.top)<nt&&o)return"top";if(Math.abs(t.y-n.bottom)<nt&&Math.abs(e.y-n.bottom)<nt&&o)return"bottom";if(Math.abs(t.x-n.left)<nt&&Math.abs(e.x-n.left)<nt&&s)return"left";if(Math.abs(t.x-n.right)<nt&&Math.abs(e.x-n.right)<nt&&s)return"right"}d(kn,"borderSideForSegment");function _n(t,e,n,o){switch(t){case"top":return ft(e,n,nt)&&n.y<o.top-nt;case"bottom":return ft(e,n,nt)&&n.y>o.bottom+nt;case"left":return ht(e,n,nt)&&n.x<o.left-nt;case"right":return ht(e,n,nt)&&n.x>o.right+nt}}d(_n,"leavesOutward");function Fn(t,e,n){if(t.length<3)return t;if(n){const r=kn(t[0],t[1],e);return r&&_n(r,t[1],t[2],e)?t.slice(1):t}const o=t.length-1,s=kn(t[o-1],t[o],e);return s&&_n(s,t[o-1],t[o-2],e)?t.slice(0,o):t}d(Fn,"collapseOwnBorderStub");function ds(t,e,n){let o=t;if(e){const r=tn(o,0,1);if(r){const i=Rn(r,o[0],e);i!==o[0]&&(o=[i,...o.slice(1)])}o=Fn(o,e,!0)}if(n){const r=o.length-1,i=tn(o,r,-1);if(i){const c=Rn(i,o[r],n,!0);c!==o[r]&&(o=[...o.slice(0,r),c])}o=Fn(o,n,!1)}const s=ho(o,e,n);return s!==o||o.length===2?s:(e&&(o=Bn(o,e,!0)),n&&(o=Bn(o,n,!1)),o)}d(ds,"snapAndCollapseEndpoints");function Dn(t,e){for(const n of t){const o=uo(n,e,2);if(!o)continue;const s=pt(o.points,nt),r=ds(s,o.srcRect,o.dstRect);if(r.length<3){o.edge.points=r;continue}const i=[r[0],{...r[0]},...r.slice(1,-1),r[r.length-1],{...r[r.length-1]}];o.edge.points=i}}d(Dn,"prepareEdgeEndpointsForRenderer");function go(t){return new Map(t.map(e=>[e.id,e]))}d(go,"buildNodeMap");function us(t,e){let n=t.parentId,o=null;for(;n;){const s=e.get(n);if(!s?.isGroup)break;o=s.id,n=s.parentId}return o}d(us,"resolveTopLevelGroupId");function Hn(t,e){let n=0,o=t.parentId;for(;o;){const s=e.get(o);if(!s?.isGroup)break;n++,o=s.parentId}return n}d(Hn,"groupDepth");function po(t){let e=1/0,n=-1/0,o=1/0,s=-1/0;for(const r of t){const i=r.x,c=r.y;if(typeof i!="number"||typeof c!="number")continue;const a=r.width??0,l=r.height??0;e=Math.min(e,i-a/2),n=Math.max(n,i+a/2),o=Math.min(o,c-l/2),s=Math.max(s,c+l/2)}return e===1/0||o===1/0?null:{minX:e,maxX:n,minY:o,maxY:s}}d(po,"boundsForChildren");function hs(t,e){const n=t.padding??20;t.x=(e.minX+e.maxX)/2,t.y=(e.minY+e.maxY)/2,t.width=Math.max(0,e.maxX-e.minX)+n,t.height=Math.max(0,e.maxY-e.minY)+n}d(hs,"applyGroupBounds");function gs(t){const e=go(t),n=t.filter(o=>o.isGroup&&o.parentId).sort((o,s)=>Hn(s,e)-Hn(o,e));for(const o of n){const s=t.filter(i=>i.parentId===o.id),r=po(s);r&&hs(o,r)}}d(gs,"recomputeNestedGroupBounds");function on(t,e){const n=t.nodes??[],o=t.edges??[],s=n.filter(a=>!a.isGroup);let r=1/0,i=-1/0;for(const a of s){const l=a[e];typeof l=="number"&&(r=Math.min(r,l),i=Math.max(i,l))}if(!Number.isFinite(r)||!Number.isFinite(i))return!1;const c=d(a=>r+i-a,"mirror");for(const a of n){const l=a[e];typeof l=="number"&&(a[e]=c(l));const g=a.groupTitleRect;g&&(a.groupTitleRect=e==="x"?{...g,left:c(g.right),right:c(g.left)}:{...g,top:c(g.bottom),bottom:c(g.top)})}for(const a of o)for(const l of a.points??[])l[e]=c(l[e]);return!0}d(on,"mirrorAxis");function ps(t){return(t.nodes??[]).some(n=>!n.isGroup)?on(t,"y"):!0}d(ps,"applyBtDirectionTransform");function ms(t,e="LR"){const n=t.nodes??[],o=t.edges??[],s=n.filter(P=>!P.isGroup);let r=1/0,i=1/0;for(const P of s){const G=P.x??0,j=P.y??0;G<r&&(r=G),j<i&&(i=j)}if(!Number.isFinite(r)||!Number.isFinite(i))return!1;const c=36;let a=0,l=0;for(const P of s)a+=P.width??0,l+=P.height??0;const g=a/s.length,x=l/s.length,I=x>0?Math.max(1,g/x):1;for(const P of s){const G=P.x??0,J=((P.y??0)-i)*I+c,dt=G-r;P.x=J,P.y=dt}for(const P of o)if(P.points)for(const G of P.points){const j=G.x,dt=(G.y-i)*I+c,mt=j-r;G.x=dt,G.y=mt}gs(n);const u=n.filter(P=>P.isGroup&&!P.parentId);if(u.length===0)return e==="RL"&&on(t,"x"),!0;const p=go(n),f=new Map;for(const P of n){if(P.isGroup)continue;const G=us(P,p);if(!G)continue;const j=f.get(G)??[];j.push(P),f.set(G,j)}let y=0;for(const P of u){const G=P.padding??0;G>y&&(y=G)}const v=[];let M=1/0,E=-1/0;for(const P of u){const G=f.get(P.id)??[],j=po(G);j&&(M=Math.min(M,j.minX),E=Math.max(E,j.maxX),v.push({lane:P,contentTop:j.minY,contentBottom:j.maxY,centerY:(j.minY+j.maxY)/2}))}if(M===1/0||E===-1/0)return!0;const T=Math.max(0,E-M),m=Math.max(y,10),S=T+2*m,A=c+S,O=(M+E)/2-S/2-c,_=O+A/2,H=Math.max(y,c);v.sort((P,G)=>P.centerY-G.centerY);for(let P=0;P<v.length;P++){const G=v[P];let j,J;if(P===0?j=G.contentTop-H:j=(v[P-1].contentBottom+G.contentTop)/2,P===v.length-1)J=G.contentBottom+H;else{const kt=v[P+1];J=(G.contentBottom+kt.contentTop)/2}const dt=Math.max(0,J-j),mt=(j+J)/2;G.lane.x=_,G.lane.y=mt,G.lane.width=A,G.lane.height=dt,G.lane.swimlaneContentTop=G.contentTop,G.lane.groupTitleRect={left:O,right:O+c,top:j,bottom:J}}return e==="RL"&&on(t,"x"),!0}d(ms,"applyLrDirectionTransform");var se=1e-6,jr=8,ze=jr,Ur=[0,ze,-ze,2*ze,-2*ze];function ys(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e);for(const s of t){if(s.isLayoutOnly)continue;const r=s.points;if(!r||r.length<4)continue;const i=ro(pt(r,se),se);if(!i)continue;const{p3:c}=i,a=i.kind==="HVH",l=lo(s,n,se);if(!l)continue;const{srcId:g,dstId:x,srcInfo:I,dstInfo:u,collinearX:p,collinearY:f}=l;if(p||f)continue;let y;const v=I.rect;for(const M of Ur){let E,T,m;if(a){const _=u.cy>I.cy?v.bottom:v.top,H=I.cx+M;if(H<=v.left+se||H>=v.right-se)continue;E={x:H,y:_},T={x:H,y:c.y},m={x:c.x,y:c.y}}else{const _=u.cx>I.cx?v.right:v.left,H=I.cy+M;if(H<=v.top+se||H>=v.bottom-se)continue;E={x:_,y:H},T={x:c.x,y:H},m={x:c.x,y:c.y}}const S=oe(E,T,se),A=oe(T,m,se);if(S&&A||!S&&At(E,T,o,[g],1)||!A&&At(T,m,o,[x],1))continue;const R=!S&&Ze(E,T,t,s,{epsilon:se,skipDegenerateOther:!0}),k=!A&&Ze(T,m,t,s,{epsilon:se,skipDegenerateOther:!0});if(!(R||k)){S?y=[T,m]:A?y=[E,T]:y=[E,T,m];break}}y&&(s.points=y)}}d(ys,"portSwapToLShape");function xs(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values());for(const c of t){if(c.isLayoutOnly)continue;const a=c.points;if(!a||a.length<4)continue;const l=pt(a,.001);if(l.length<4)continue;const g=l.length-1,x=l[g],I=l[g-1],u=l[g-2],p=x.x-I.x,f=x.y-I.y,y=Math.hypot(p,f);if(y>=10||y<.001)continue;const v=I.x-u.x,M=I.y-u.y;if(Math.hypot(v,M)<.001)continue;const T=Tt(I,x,.001),m=wt(I,x,.001),S=Tt(u,I,.001),A=wt(u,I,.001);if(!(T&&A||m&&S))continue;const R=c.end,k=c.start,O=R?e.get(R):void 0;if(!O)continue;const _=O.x??0,H=O.y??0,P=qt(O);if(!P)continue;let G,j;if(A){const W=M<0;G={x:_,y:u.y},j={x:_,y:W?P.bottom:P.top}}else{const W=v>0;G={x:u.x,y:H},j={x:W?P.right:P.left,y:H}}if(At(G,j,r,R?[R]:[],-2)||At(G,j,i,[],-2))continue;if(k){const W=e.get(k),et=W?qt(W):void 0;if(et&&io(G,et,2))continue}const J=d((W,et)=>`${W.x.toFixed(3)},${W.y.toFixed(3)}|${et.x.toFixed(3)},${et.y.toFixed(3)}`,"ownSegmentKey"),dt=new Set;for(let W=0;W<l.length-1;W++)dt.add(J(l[W],l[W+1]));const mt=d((W,et)=>{for(const at of t){if(at===c||at.isLayoutOnly)continue;const gt=at.points;if(!(!gt||gt.length<2))for(let xt=0;xt<gt.length-1;xt++){const vt=gt[xt],Vt=gt[xt+1];if(!dt.has(J(vt,Vt))&&le(W,et,vt,Vt,.001))return!0}}return!1},"segmentCrossesOtherEdge");if(mt(G,j))continue;if(g-3>=0){const W=l[g-3],et=[k,R].filter(at=>!!at);if(At(W,G,r,et,-2)||mt(W,G))continue}const Pt=[...l.slice(0,g-2),G,j];c.points=Pt;const Q=c.labelNodeId;if(Q){const W=e.get(Q);if(W){const et=W.width??0,at=W.height??0;if(et>0&&at>0){let gt,xt,vt=-1;for(let Vt=0;Vt<Pt.length-1;Vt++){const jt=Pt[Vt],Ut=Pt[Vt+1],te=Math.hypot(Ut.x-jt.x,Ut.y-jt.y),Se=ht(jt,Ut,.001),de=ft(jt,Ut,.001);(Se&&te>=et+2||de&&te>=at+2)&&te>vt&&(vt=te,gt=(jt.x+Ut.x)/2,xt=(jt.y+Ut.y)/2)}gt!==void 0&&xt!==void 0&&(W.x=gt,W.y=xt)}}}}}d(xs,"collapseShortTerminalStub");var Z=.001,_t=8,it=Re,In=d((t,e)=>ft(t,e,Z)||ht(t,e,Z),"orthogonallyAligned");function bs(t,e){const s=d((u,p)=>{const f=u.x??0,y=u.y??0,v=p.x-f,M=p.y-y;let E=(u.width??0)/2,T=(u.height??0)/2;return Math.abs(M)*E>Math.abs(v)*T?(M<0&&(T=-T),{x:f+(M===0?0:T*v/M),y:y+T}):(v<0&&(E=-E),{x:f+E,y:y+(v===0?0:E*M/v)})},"rectIntersect"),r=d((u,p)=>{const f=pt(u.points??[]);if(f.length<2)return;const y=p?u.start:u.end,v=y?e.get(y):void 0,M=v?qt(v):void 0;if(!v||!y||!M)return;const E=p?f[0]:f[f.length-1],T=p?f[1]:f[f.length-2],m=s(v,E);let S=E;if(In(T,m)&&(S=T),ft(m,S,Z))return{edge:u,edgeId:String(u.id??""),nodeId:y,atStart:p,orientation:"V",coord:m.x,min:Math.min(m.y,S.y),max:Math.max(m.y,S.y),boundary:m,railEnd:S,rect:M};if(ht(m,S,Z))return{edge:u,edgeId:String(u.id??""),nodeId:y,atStart:p,orientation:"H",coord:m.y,min:Math.min(m.x,S.x),max:Math.max(m.x,S.x),boundary:m,railEnd:S,rect:M}},"terminalLaneFor"),i=d((u,p)=>Math.max(0,Math.min(u.max,p.max)-Math.max(u.min,p.min)),"projectedOverlapLength"),c=d((u,p)=>u.nodeId!==p.nodeId||u.orientation!==p.orientation?!1:u.orientation==="H"?(Math.abs(u.boundary.x-u.rect.left)<1||Math.abs(u.boundary.x-u.rect.right)<1)&&ft(u.boundary,p.boundary,1):(Math.abs(u.boundary.y-u.rect.top)<1||Math.abs(u.boundary.y-u.rect.bottom)<1)&&ht(u.boundary,p.boundary,1),"sameTerminalFace"),a=d((u,p)=>u.nodeId!==p.nodeId||u.orientation!==p.orientation?!1:i(u,p)>=_t&&Math.abs(u.coord-p.coord)<.5,"exactTerminalLaneConflict"),l=d((u,p)=>{if(u.nodeId!==p.nodeId||u.orientation!==p.orientation||u.orientation!=="H"||u.atStart===p.atStart)return!1;const f=i(u,p);if(f<_t)return!1;const y=u.rect.bottom-u.rect.top;return f<y||f>2*y?!1:c(u,p)&&Math.abs(u.coord-p.coord)<16},"nearTerminalLaneConflict"),g=d((u,p)=>{const f=pt(u.edge.points??[]);if(f.length<2)return;const y=u.orientation==="V"?{x:u.boundary.x+p,y:u.boundary.y}:{x:u.boundary.x,y:u.boundary.y+p},v=u.orientation==="V"?{x:u.railEnd.x+p,y:u.railEnd.y}:{x:u.railEnd.x,y:u.railEnd.y+p};if(!d(()=>Math.abs(u.boundary.y-u.rect.top)<1||Math.abs(u.boundary.y-u.rect.bottom)<1?ht(y,u.boundary,Z)&&y.x>=u.rect.left+1&&y.x<=u.rect.right-1:Math.abs(u.boundary.x-u.rect.left)<1||Math.abs(u.boundary.x-u.rect.right)<1?ft(y,u.boundary,Z)&&y.y>=u.rect.top+1&&y.y<=u.rect.bottom-1:!1,"boundaryStaysOnSameFace")())return;if(u.atStart){const S=f.length>1&&oe(f[1],u.railEnd,Z),A=f.slice(S?2:1),R=A[0];return R&&!In(R,v)?void 0:[y,v,...A]}const E=f.length>1&&oe(f[f.length-2],u.railEnd,Z),T=f.slice(0,E?-2:-1),m=T[T.length-1];if(!(m&&!In(m,v)))return[...T,v,y]},"shiftedCandidate"),x=d(u=>{const p=u.edge,f=pt(p.points??[]);if(f.length!==2)return!1;const y=p.start,v=p.end,M=y?e.get(y):void 0,E=v?e.get(v):void 0;if(!M||!E)return!1;const T=M.x??0,m=M.y??0,S=E.x??0,A=E.y??0,[R,k]=f;return ht(R,k,Z)&&Math.abs(m-A)<1&&Math.abs(T-S)>1||ft(R,k,Z)&&Math.abs(T-S)<1&&Math.abs(m-A)>1},"laneIsStraightCollinearConnector"),I=[-7,7,-14,14,-21,21];for(let u=0;u<8;u++){const p=t.filter(y=>!y.isLayoutOnly).flatMap(y=>[r(y,!0),r(y,!1)]).filter(y=>!!y);let f=!1;for(let y=0;y<p.length&&!f;y++)for(let v=y+1;v<p.length&&!f;v++){const M=p[y],E=p[v];if(M.edge===E.edge||!(a(M,E)||l(M,E)))continue;const T=!a(M,E),m=[M,E].sort((S,A)=>{const R=x(S),k=x(A);return R!==k?Number(R)-Number(k):+!A.atStart-+!S.atStart});for(const S of m){for(const A of I){const R=g(S,A);if(!R)continue;const k=r({...S.edge,points:R},S.atStart);if(!(!k||p.some(O=>O.edge!==S.edge&&(a(k,O)||T&&l(k,O))))){S.edge.points=R,f=!0;break}}if(f)break}}if(!f)return}}d(bs,"separateSharedRenderedTerminalLanes");function Ms(t,e){const{realNodeRects:o,labelNodeRects:s}=me(e.values()),r=d((c,a)=>{const l=c.start,g=c.end,x=it(a);if(x.length!==a.length-1)return!1;const I=[l,g].filter(u=>!!u);for(const u of x)if(At(u.a,u.b,o,I,-2)||At(u.a,u.b,s,[],-2))return!1;for(const u of t){if(u===c||u.isLayoutOnly)continue;const p=u.points;if(!(!p||p.length<2)){for(const f of x)for(const y of it(pt(p)))if(ce(f,y,.5)>=_t||le(f.a,f.b,y.a,y.b,Z))return!1}}return!0},"candidateIsSafe"),i=d((c,a)=>{if(a+4>=c.length)return;const l=c[a],g=c[a+1],x=c[a+2],I=c[a+3],u=c[a+4],p=Tt(l,g)&&wt(g,x)&&Tt(x,I)&&wt(I,u)&&ft(l,I,Z)&&ft(l,u,Z)&&ft(g,x,Z)&&(g.x-l.x)*(I.x-x.x)<0,f=wt(l,g)&&Tt(g,x)&&wt(x,I)&&Tt(I,u)&&ht(l,I,Z)&&ht(l,u,Z)&&ht(g,x,Z)&&(g.y-l.y)*(I.y-x.y)<0;if(p||f)return pt([...c.slice(0,a+1),u,...c.slice(a+5)]);if(a+5>=c.length)return;const y=c[a+5],v=wt(l,g)&&Tt(g,x)&&wt(x,I)&&Tt(I,u)&&wt(u,y)&&ft(l,u,Z)&&ft(l,y,Z)&&ft(x,I,Z)&&(x.x-g.x)*(u.x-I.x)<0,M=Tt(l,g)&&wt(g,x)&&Tt(x,I)&&wt(I,u)&&Tt(u,y)&&ht(l,u,Z)&&ht(l,y,Z)&&ht(x,I,Z)&&(x.y-g.y)*(u.y-I.y)<0;if(!(!v&&!M))return pt([...c.slice(0,a+1),y,...c.slice(a+6)])},"withoutDogleg");for(let c=0;c<8;c++){let a=!1;for(const l of t){if(l.isLayoutOnly)continue;const g=pt(l.points??[]);for(let x=0;x<=g.length-5;x++){const I=i(g,x);if(!(!I||!r(l,I))){l.points=I,a=!0;break}}if(a)break}if(!a)return}}d(Ms,"collapseRedundantRectangularDoglegs");function Xn(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values()),c=t.filter(p=>!p.isLayoutOnly),a=d((p,f,y)=>pt(p===f?y??[]:p.points??[]),"pointsFor"),l=d((p,f)=>{let y=0;for(let v=0;v<c.length;v++){const M=it(a(c[v],p,f));for(let E=v+1;E<c.length;E++){const T=it(a(c[E],p,f));for(const m of M)for(const S of T)le(m.a,m.b,S.a,S.b,Z)&&y++}}return y},"strictCrossingCount"),g=d(p=>{const f=it(p);if(f.length!==3)return;const y=f[1];if(!(f[0].horizontal===y.horizontal||f[2].horizontal===y.horizontal))return{index:y.index,horizontal:y.horizontal,vertical:y.vertical,segment:y}},"middleRail"),x=d((p,f)=>{const y=[p.start,p.end].filter(v=>!!v);return r.filter(v=>{if(y.includes(v.id))return!1;const M=v.rect;return f.horizontal?zt(f.a.x,f.b.x,M.left,M.right)>=_t&&f.a.y>=M.top-2&&f.a.y<=M.bottom+2:zt(f.a.y,f.b.y,M.top,M.bottom)>=_t&&f.a.x>=M.left-2&&f.a.x<=M.right+2})},"blockingRectsFor"),I=d((p,f,y)=>{const v=p.map(E=>({...E}));if(f.horizontal)v[f.index].y=y,v[f.index+1].y=y;else if(f.vertical)v[f.index].x=y,v[f.index+1].x=y;else return;const M=ae(pt(v));return it(M).length===M.length-1?M:void 0},"candidateByMovingRail"),u=d((p,f,y)=>{const v=[p.start,p.end].filter(E=>!!E),M=it(f);if(M.length!==f.length-1)return!1;for(const E of M)if(At(E.a,E.b,r,v,-2)||At(E.a,E.b,i,[],-2))return!1;for(const E of c)if(E!==p){for(const T of M)for(const m of it(a(E)))if(ce(T,m,.5)>=_t)return!1}return l(p,f)<=y},"candidateIsSafe");for(let p=0;p<8;p++){const f=l();let y=!1;for(const v of c){const M=a(v),E=g(M);if(!E)continue;const T=x(v,E.segment);if(T.length===0)continue;const m=E.horizontal?[Math.min(...T.map(S=>S.rect.top))-20,Math.max(...T.map(S=>S.rect.bottom))+20]:[Math.min(...T.map(S=>S.rect.left))-20,Math.max(...T.map(S=>S.rect.right))+20];for(const S of m){const A=I(M,E.segment,S);if(!(!A||!u(v,A,f))){v.points=A,y=!0;break}}if(y)break}if(!y)return}}d(Xn,"liftObstacleHuggingSameSideRails");function Yn(t,e){const o=d(a=>{const l=a.groupTitleRect;if(!(!l||typeof l.left!="number"||typeof l.right!="number"||typeof l.top!="number"||typeof l.bottom!="number"||!Number.isFinite(l.left)||!Number.isFinite(l.right)||!Number.isFinite(l.top)||!Number.isFinite(l.bottom)||l.right<=l.left||l.bottom<=l.top))return{left:l.left,right:l.right,top:l.top,bottom:l.bottom}},"validTitleRect"),s=d(a=>{if(!a.isGroup||a.parentId)return;const l=a.direction,g=typeof l=="string"?l.toUpperCase():"";if(g==="LR"||g==="RL"||g==="BT")return;const x=o(a),I=a.y,u=a.height;if(!x||typeof I!="number"||typeof u!="number"||!Number.isFinite(I)||!Number.isFinite(u)||u<=0)return;const p=x.right-x.left,f=x.bottom-x.top;if(!(f<=0||p<f))return{node:a,rect:x}},"topLaneTitleFor"),r=d((a,l)=>{if(!a.horizontal)return!1;const g=a.a.y;return g<=l.top+Z||g>=l.bottom-Z?!1:zt(a.a.x,a.b.x,l.left,l.right)>=_t},"horizontalSegmentIntersectsTitle"),i=[...e.values()].map(s).filter(a=>!!a);if(i.length===0)return;let c=0;for(const a of t){if(a.isLayoutOnly)continue;const l=pt(a.points??[]);for(const g of it(l))for(const x of i)r(g,x.rect)&&(c=Math.max(c,x.rect.bottom-g.a.y+4))}if(!(c<=Z))for(const a of i){const l=a.node.y,g=a.node.height;typeof l!="number"||typeof g!="number"||!Number.isFinite(l)||!Number.isFinite(g)||g<=0||(a.node.y=l-c/2,a.node.height=g+c,a.node.groupTitleRect={...a.rect,top:a.rect.top-c,bottom:a.rect.bottom-c})}}d(Yn,"liftTopLaneTitleBandsAboveRails");function Gn(t,e){const o=d(l=>{const g=l.groupTitleRect;if(!(!g||typeof g.left!="number"||typeof g.right!="number"||typeof g.top!="number"||typeof g.bottom!="number"||!Number.isFinite(g.left)||!Number.isFinite(g.right)||!Number.isFinite(g.top)||!Number.isFinite(g.bottom)||g.right<=g.left||g.bottom<=g.top))return{left:g.left,right:g.right,top:g.top,bottom:g.bottom}},"validTitleRect"),s=d(l=>{if(!l.isGroup||l.parentId||l.direction!=="LR")return;const x=o(l),I=l.x,u=l.width;if(!x||typeof I!="number"||typeof u!="number"||!Number.isFinite(I)||!Number.isFinite(u)||u<=0)return;const p=x.right-x.left,f=x.bottom-x.top;if(!(p<=0||f<p))return{node:l,rect:x}},"leftLaneTitleFor"),r=d((l,g)=>{if(!l.vertical)return!1;const x=l.a.x;return x<=g.left+Z||x>=g.right-Z?!1:zt(l.a.y,l.b.y,g.top,g.bottom)>=_t},"verticalSegmentIntersectsTitle"),i=d((l,g)=>{if(!l.horizontal)return!1;const x=l.a.y;return x<=g.top+Z||x>=g.bottom-Z?!1:zt(l.a.x,l.b.x,g.left,g.right)>=_t},"horizontalSegmentIntersectsTitle"),c=[...e.values()].map(s).filter(l=>!!l);if(c.length===0)return;let a=0;for(const l of t){if(l.isLayoutOnly)continue;const g=pt(l.points??[]);for(const x of it(g))for(const I of c)if(r(x,I.rect))a=Math.max(a,I.rect.right-x.a.x+4);else if(i(x,I.rect)){const u=Math.min(x.a.x,x.b.x);a=Math.max(a,I.rect.right-u+4)}}if(!(a<=Z))for(const l of c){const g=l.node.x,x=l.node.width;typeof g!="number"||typeof x!="number"||!Number.isFinite(g)||!Number.isFinite(x)||x<=0||(l.node.x=g-a/2,l.node.width=x+a,l.node.groupTitleRect={...l.rect,left:l.rect.left-a,right:l.rect.right-a})}}d(Gn,"shiftLeftLaneTitleBandsLeftOfRails");function Is(t,e){const{realNodeRects:o}=me(e.values()),s=t.filter(p=>!p.isLayoutOnly),r=d((p,f=new Map)=>pt(f.get(p)??p.points??[]),"replacementPointsFor"),i=d((p=new Map)=>{let f=0;for(let y=0;y<s.length;y++){const v=it(r(s[y],p));for(let M=y+1;M<s.length;M++){const E=it(r(s[M],p));for(const T of v)for(const m of E)le(T.a,T.b,m.a,m.b,Z)&&f++}}return f},"crossingCount"),c=d((p=new Map)=>s.reduce((f,y)=>f+Qt(r(y,p)),0),"totalBends"),a=d(p=>{const f=r(p);if(f.length<4)return;const y=f[f.length-2],v=f[f.length-1];if(!(!Tt(y,v,Z)&&!wt(y,v,Z)))return{tailStart:y,terminal:v}},"terminalTailFor"),l=d((p,f)=>{const y=r(p);if(y.length<3)return;const v=y[0],M=y[1];let E;if(Tt(v,M,Z))E={x:M.x,y:f.tailStart.y};else if(wt(v,M,Z))E={x:f.tailStart.x,y:M.y};else return;const T=ae(pt([v,M,E,f.tailStart,f.terminal]));return it(T).length===T.length-1?T:void 0},"candidateWithDestinationTail"),g=d((p,f)=>{const y=[p.start,p.end].filter(v=>!!v);for(const v of it(f))if(At(v.a,v.b,o,y,-2))return!0;return!1},"pathHasNodeHit"),x=d((p,f,y)=>{for(const v of s)if(v!==p){for(const M of it(f))for(const E of it(r(v,y)))if(ce(M,E,.5)>=_t)return!0}return!1},"pathHasSharedTrack"),I=d((p,f,y)=>!g(p,f)&&!x(p,f,y),"candidateIsSafe"),u=d(()=>{const p=new Map;for(const f of s){const y=f.end;if(!y||!e.has(y)||r(f).length<4)continue;const M=p.get(y)??[];M.push(f),p.set(y,M)}return p},"edgesByDestination");for(let p=0;p<4;p++){const f=i();if(f===0)return;const y=c();let v,M=f,E=y;for(const T of u().values())for(let m=0;m<T.length;m++)for(let S=m+1;S<T.length;S++){const A=T[m],R=T[S],k=a(A),O=a(R);if(!k||!O)continue;const _=l(A,O),H=l(R,k);if(!_||!H)continue;const P=new Map([[A,_],[R,H]]);if(!I(A,_,P)||!I(R,H,P))continue;const G=i(P),j=c(P);G>=f||G>M||G===M&&j>=E||(v=P,M=G,E=j)}if(!v)return;for(const[T,m]of v)T.points=m}}d(Is,"swapDestinationTerminalTailsToReduceCrossings");function Ss(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values()),c=t.filter(T=>!T.isLayoutOnly),a=d((T,m=new Map)=>pt(m.get(T)??T.points??[]),"replacementPointsFor"),l=d((T=new Map)=>{let m=0;for(let S=0;S<c.length;S++){const A=it(a(c[S],T));for(let R=S+1;R<c.length;R++){const k=it(a(c[R],T));for(const O of A)for(const _ of k)le(O.a,O.b,_.a,_.b,Z)&&m++}}return m},"strictCrossingCount"),g=d((T=new Map)=>c.reduce((m,S)=>m+Qt(a(S,T)),0),"totalBends"),x=d(T=>{const m=T.start,S=T.end,A=m?e.get(m):void 0,R=S?e.get(S):void 0,k=A?qt(A):void 0,O=R?qt(R):void 0;return k&&O?{src:k,dst:O}:void 0},"endpointRectsFor"),I=d((T,m,S)=>{if(S.index<=0||S.index+1>=m.length-1)return;const A=x(T);if(A){if(S.vertical){const R=S.a.x,k=Math.min(A.src.left,A.dst.left),O=Math.max(A.src.right,A.dst.right),_=R<k-Z?"left":R>O+Z?"right":void 0;return _?{edge:T,points:m,segmentIndex:S.index,axis:"vertical",side:_,coord:R,min:Math.min(S.a.y,S.b.y),max:Math.max(S.a.y,S.b.y)}:void 0}if(S.horizontal){const R=S.a.y,k=Math.min(A.src.top,A.dst.top),O=Math.max(A.src.bottom,A.dst.bottom),_=R<k-Z?"top":R>O+Z?"bottom":void 0;return _?{edge:T,points:m,segmentIndex:S.index,axis:"horizontal",side:_,coord:R,min:Math.min(S.a.x,S.b.x),max:Math.max(S.a.x,S.b.x)}:void 0}}},"externalRailForSegment"),u=d(()=>{const T=[];for(const m of c){const S=a(m);for(const A of it(S)){const R=I(m,S,A);R&&T.push(R)}}return T},"collectExternalRails"),p=d((T,m)=>T.edge!==m.edge&&T.axis===m.axis&&T.side===m.side&&zt(T.min,T.max,m.min,m.max)>=_t,"railsInteract"),f=d(T=>{const m=[],S=new Set;for(const A of T){if(S.has(A))continue;const R=[A],k=[];for(S.add(A);R.length>0;){const O=R.pop();k.push(O);for(const _ of T)!S.has(_)&&p(O,_)&&(S.add(_),R.push(_))}k.length>1&&m.push(k)}return m},"connectedComponents"),y=d(T=>{const m=[];for(const S of T)m.some(A=>Math.abs(A-S.coord)<Z)||m.push(S.coord);for(;m.length<T.length;){const S=Math.min(...m),A=Math.max(...m),R=T[0].side;m.push(R==="left"||R==="top"?S-12*(T.length-m.length):A+12*(T.length-m.length))}return m},"uniqueCoordsFor"),v=d(T=>{const m=T.map(R=>R.coord),S=y(T),A=[];if(T.length<=6){const R=new Array(S.length).fill(!1),k=[],O=d(()=>{if(k.length===T.length){k.some((_,H)=>Math.abs(_-m[H])>=Z)&&A.push([...k]);return}for(const[_,H]of S.entries())R[_]||(R[_]=!0,k.push(H),O(),k.pop(),R[_]=!1)},"visit");return O(),A}for(let R=0;R<m.length;R++)for(let k=R+1;k<m.length;k++){const O=[...m];[O[R],O[k]]=[O[k],O[R]],A.push(O)}return A},"coordinateAssignmentsFor"),M=d((T,m)=>{const S=new Map;for(const[R,k]of T.entries()){const O=m[R],_=S.get(k.edge)??k.points.map(H=>({x:H.x,y:H.y}));k.axis==="vertical"?(_[k.segmentIndex].x=O,_[k.segmentIndex+1].x=O):(_[k.segmentIndex].y=O,_[k.segmentIndex+1].y=O),S.set(k.edge,_)}const A=new Map;for(const[R,k]of S){const O=ae(pt(k));if(it(O).length!==O.length-1)return;A.set(R,O)}return A},"replacementsForAssignment"),E=d(T=>{for(const[m,S]of T){const A=[m.start,m.end].filter(R=>!!R);for(const R of it(S))if(At(R.a,R.b,r,A,-2)||At(R.a,R.b,i,[],-2))return!1}for(let m=0;m<c.length;m++){const S=c[m],A=T.has(S),R=it(a(S,T));for(let k=m+1;k<c.length;k++){const O=c[k];if(!A&&!T.has(O))continue;const _=it(a(O,T));for(const H of R)for(const P of _)if(ce(H,P,.5)>=_t)return!1}}return!0},"candidateIsSafe");for(let T=0;T<4;T++){const m=l();if(m===0)return;let S,A=m,R=g(),k=Number.POSITIVE_INFINITY;for(const O of f(u()))for(const _ of v(O)){const H=M(O,_);if(!H||!E(H))continue;const P=l(H);if(P>=m)continue;const G=g(H),j=O.reduce((J,dt,mt)=>J+Math.abs(_[mt]-dt.coord),0);P>A||P===A&&(G>R||G===R&&j>=k)||(S=H,A=P,R=G,k=j)}if(!S)return;for(const[O,_]of S)O.points=_}}d(Ss,"reassignCrossingExternalRailChannels");function Cs(t,e){const{realNodeRects:o,labelNodeRects:s}=me(e.values()),r=t.filter(u=>!u.isLayoutOnly),i=d((u,p,f)=>pt(u===p?f??[]:u.points??[]),"pointsFor"),c=d(u=>it(u).reduce((p,f)=>{const y=f.a.x-f.b.x,v=f.a.y-f.b.y;return p+Math.hypot(y,v)},0),"pathLength"),a=d((u,p)=>{let f=0;for(let y=0;y<r.length;y++){const v=it(i(r[y],u,p));for(let M=y+1;M<r.length;M++){const E=it(i(r[M],u,p));for(const T of v)for(const m of E)le(T.a,T.b,m.a,m.b,Z)&&f++}}return f},"strictCrossingCount"),l=d((u,p)=>{if(u.horizontal){const f=u.a.y;return(Math.abs(f-p.top)<1||Math.abs(f-p.bottom)<1)&&zt(u.a.x,u.b.x,p.left,p.right)>=_t}if(u.vertical){const f=u.a.x;return(Math.abs(f-p.left)<1||Math.abs(f-p.right)<1)&&zt(u.a.y,u.b.y,p.top,p.bottom)>=_t}return!1},"segmentRunsAlongRectBorder"),g=d(u=>{const p=[u.start,u.end].filter(y=>!!y),f=[];for(const y of p){const v=e.get(y),M=v?qt(v):void 0;M&&f.push(M)}return f},"endpointRectsFor"),x=d((u,p)=>{if(p+3>=u.length)return[];const f=u[p],y=u[p+1],v=u[p+2],M=u[p+3],E=Tt(f,y,Z)&&wt(y,v,Z)&&Tt(v,M,Z),T=wt(f,y,Z)&&Tt(y,v,Z)&&wt(v,M,Z);if(!E&&!T)return[];if(!(E?Math.sign(y.x-f.x)!==Math.sign(M.x-v.x):Math.sign(y.y-f.y)!==Math.sign(M.y-v.y)))return[];const S=ft(f,M,Z)||ht(f,M,Z)?[]:[{x:f.x,y:M.y},{x:M.x,y:f.y}],A=S.length===0?[[...u.slice(0,p+1),...u.slice(p+3)]]:S.map(k=>[...u.slice(0,p+1),k,...u.slice(p+3)]),R=new Set;return A.map(k=>ae(pt(k))).filter(k=>{if(it(k).length!==k.length-1||!k.some(_=>oe(_,M,Z)))return!1;const O=k.map(_=>`${_.x.toFixed(3)},${_.y.toFixed(3)}`).join("|");return R.has(O)?!1:(R.add(O),!0)})},"shortcutCandidatesAt"),I=d((u,p,f)=>{const y=[u.start,u.end].filter(M=>!!M),v=g(u);for(const M of it(p))if(At(M.a,M.b,o,y,-2)||At(M.a,M.b,s,[],-2)||v.some(E=>l(M,E)))return!1;for(const M of r)if(M!==u){for(const E of it(p))for(const T of it(i(M)))if(ce(E,T,.5)>=_t)return!1}return a(u,p)<=f},"candidateIsSafe");for(let u=0;u<8;u++){const p=a();let f,y,v=p,M=Number.POSITIVE_INFINITY,E=Number.POSITIVE_INFINITY;for(const T of r){const m=i(T),S=Qt(m,Z),A=c(m);for(let R=0;R<=m.length-4;R++)for(const k of x(m,R)){const O=Qt(k,Z),_=c(k);if(!(O<S||O===S&&_<A-Z)||!I(T,k,p))continue;const P=a(T,k);P>v||P===v&&(O>M||O===M&&_>=E)||(f=T,y=k,v=P,M=O,E=_)}}if(!f||!y)return;f.points=y}}d(Cs,"shortcutRedundantOrthogonalJogs");function vs(t,e){const i=[];for(const N of e.values()){if(N.isGroup||N.isEdgeLabel)continue;const F=N.x??0,D=N.y??0,V=qt(N);V&&i.push({id:String(N.id??""),cx:F,cy:D,rect:V})}if(i.length===0)return;const c=new Map(i.map(N=>[N.id,N])),a=i.map(N=>({id:N.id,rect:N.rect})),l=["top","bottom","left","right"],g={top:Math.min(...i.map(N=>N.rect.top))-20,bottom:Math.max(...i.map(N=>N.rect.bottom))+20,left:Math.min(...i.map(N=>N.rect.left))-20,right:Math.max(...i.map(N=>N.rect.right))+20},x=t.filter(N=>!N.isLayoutOnly),I=new Map(x.map((N,F)=>[N,F])),u=d(N=>{const F=N==="left"||N==="top"?-1:1,D=[];for(let V=0;V<=2;V++)D.push(g[N]+F*20*V);return D},"outwardTracksForSide"),p=d((N,F=new Map)=>pt(F.get(N)??N.points??[]),"replacementPointsFor"),f=d((N,F)=>{let D=0;for(const V of N)for(const h of F)le(V.a,V.b,h.a,h.b,Z)&&D++;return D},"crossingCountBetweenSegments"),y=d((N,F)=>f(it(N),it(F)),"crossingCountBetweenPaths"),v=d((N=new Map)=>{let F=0;const D=[],V=new Set,h=[],b=d(C=>{V.has(C)||(V.add(C),h.push(C))},"addEdge");for(let C=0;C<x.length;C++){const L=x[C],w=p(L,N);for(let B=C+1;B<x.length;B++){const U=x[B],q=y(w,p(U,N));q>0&&(F+=q,D.push({first:L,second:U,count:q}),b(L),b(U))}}return h.sort((C,L)=>(I.get(C)??0)-(I.get(L)??0)),{count:F,pairs:D,edgeSet:V,edges:h}},"crossingSnapshot"),M=d((N,F)=>{const D=new Set(F.keys());if(D.size===0)return N.count;let V=0;for(const b of N.pairs)(D.has(b.first)||D.has(b.second))&&(V+=b.count);let h=0;for(let b=0;b<x.length;b++){const C=x[b],L=D.has(C),w=p(C,F);for(let B=b+1;B<x.length;B++){const U=x[B];!L&&!D.has(U)||(h+=y(w,p(U,F)))}}return N.count-V+h},"crossingCountWithReplacements"),E=d(N=>{const F=new Map;for(const h of N.pairs){const b=F.get(h.first)??new Set;b.add(h.second),F.set(h.first,b);const C=F.get(h.second)??new Set;C.add(h.first),F.set(h.second,C)}const D=[],V=new Set;for(const h of N.edges){if(V.has(h))continue;const b=[h],C=[];for(V.add(h);b.length>0;){const L=b.pop();C.push(L);for(const w of F.get(L)??[])V.has(w)||(V.add(w),b.push(w))}C.sort((L,w)=>(I.get(L)??0)-(I.get(w)??0)),C.length>1&&D.push(C)}return D},"crossingComponents"),T=d(N=>[N.start,N.end].filter(F=>!!F),"endpointIdsFor"),m=d(N=>{const F=[];for(const D of E(N)){const V=new Set(D),h=new Set(D.flatMap(C=>T(C))),b=[...D];for(const C of x)V.has(C)||T(C).some(L=>h.has(L))&&b.push(C);b.sort((C,L)=>(I.get(C)??0)-(I.get(L)??0)),F.push(b)}return F},"pairSearchGroups"),S=d((N,F,D)=>M(N,new Map([[F,D]])),"crossingCountWithSingleReplacement"),A=d(N=>{const F=new Map;for(const D of N.pairs)F.set(D.first,(F.get(D.first)??0)+D.count),F.set(D.second,(F.get(D.second)??0)+D.count);return F},"currentCrossingsByEdge"),R=d(N=>N.slice(1).reduce((F,D,V)=>{const h=N[V];return F+Math.abs(D.x-h.x)+Math.abs(D.y-h.y)},0),"pathLength"),k=d((N=new Map)=>x.reduce((F,D)=>F+Qt(p(D,N)),0),"totalBends"),O=d((N=new Map)=>x.reduce((F,D)=>F+R(p(D,N)),0),"totalLength"),_=d((N,F,D=new Map)=>{const V=it(F);for(const h of x)if(h!==N){for(const b of V)for(const C of it(p(h,D)))if(ce(b,C,.5)>=_t)return!0}return!1},"pathHasSegmentConflict"),H=d((N,F)=>{const D=[N.start,N.end].filter(V=>!!V);for(const V of it(F))if(At(V.a,V.b,a,D,-2))return!0;return!1},"pathHitsNode"),P=d((N,F)=>{const D=ae(pt(F));it(D).length===D.length-1&&N.push(D)},"pushOrthogonalCandidate"),G=d(N=>N==="left"||N==="right","sideIsHorizontal"),j=d((N,F,D)=>{switch(F){case"left":return Math.min(N.x,D.x)-20;case"right":return Math.max(N.x,D.x)+20;case"top":return Math.min(N.y,D.y)-20;case"bottom":return Math.max(N.y,D.y)+20}},"localTrackForSameSide"),J=d((N,F,D,V)=>{const h=D==="left"||D==="top"?-1:1,b=[j(F,D,V),g[D]];for(const C of b)for(let L=0;L<=2;L++)P(N,ao(F,D,V,C+h*20*L))},"addSameSideCandidates"),dt=d((N,F,D,V,h)=>{for(const b of u(D))for(const C of u(h))P(N,[F,{x:b,y:F.y},{x:b,y:C},{x:V.x,y:C},V])},"addHorizontalToVerticalCandidates"),mt=d((N,F,D,V,h)=>{for(const b of u(D))for(const C of u(h))P(N,[F,{x:F.x,y:b},{x:C,y:b},{x:C,y:V.y},V])},"addVerticalToHorizontalCandidates"),kt=d((N,F,D,V,h)=>{const b=[...u("top"),...u("bottom")];for(const C of u(D))for(const L of u(h))for(const w of b)P(N,[F,{x:C,y:F.y},{x:C,y:w},{x:L,y:w},{x:L,y:V.y},V])},"addHorizontalPairCandidates"),Pt=d((N,F,D,V,h)=>{const b=[...u("left"),...u("right")];for(const C of u(D))for(const L of u(h))for(const w of b)P(N,[F,{x:F.x,y:C},{x:w,y:C},{x:w,y:L},{x:V.x,y:L},V])},"addVerticalPairCandidates"),Q=d(N=>{const F=new Set;return N.map(D=>pt(D)).filter(D=>{const V=D.map(h=>`${h.x.toFixed(3)},${h.y.toFixed(3)}`).join("|");return F.has(V)||D.length<2?!1:(F.add(V),!0)})},"dedupeCandidatePaths"),W=d((N,F,D,V)=>{const h=[],b=co(N,F,D,V,20,Z);b&&P(h,b),F===V&&J(h,N,F,D);const C=G(F),L=G(V);return C&&!L?dt(h,N,F,D,V):!C&&L?mt(h,N,F,D,V):C?kt(h,N,F,D,V):Pt(h,N,F,D,V),Q(h)},"buildCandidatesForSides"),et=d((N,F,D,V)=>{const h=[...u("left"),...u("right")],b=[...u("top"),...u("bottom")];for(const C of l){const L=Ie(V,C),w=C==="top"||C==="bottom"?u(C):b;for(const B of h){P(N,[F,D,{x:B,y:D.y},{x:B,y:L.y},L]);for(const U of w)P(N,[F,D,{x:B,y:D.y},{x:B,y:U},{x:L.x,y:U},L])}}},"addVerticalDepartureOuterTrackCandidates"),at=d((N,F,D,V)=>{const h=[...u("left"),...u("right")],b=[...u("top"),...u("bottom")];for(const C of l){const L=Ie(V,C),w=C==="left"||C==="right"?u(C):h;for(const B of b){P(N,[F,D,{x:D.x,y:B},{x:L.x,y:B},L]);for(const U of w)P(N,[F,D,{x:D.x,y:B},{x:U,y:B},{x:U,y:L.y},L])}}},"addHorizontalDepartureOuterTrackCandidates"),gt=d(N=>{const F=N.start,D=N.end,V=D?c.get(D):void 0;if(!F||!V)return[];const h=pt(N.points??[]);if(h.length<4)return[];const b=h[0],C=h[1],L=[];return wt(b,C,Z)?et(L,b,C,V):Tt(b,C,Z)&&at(L,b,C,V),L},"terminalPreservingOuterTrackCandidates"),xt=d(N=>{const F=N.start,D=N.end,V=F?c.get(F):void 0,h=D?c.get(D):void 0;if(!V||!h)return[];const b=[];for(const C of l){const L=Ie(V,C);for(const w of l)b.push(...W(L,C,Ie(h,w),w))}return b.push(...gt(N)),b},"candidatePathsFor"),vt=d(()=>new Map(x.map(N=>[N,it(p(N))])),"currentSegmentsByEdge"),Vt=d((N,F,D)=>{const V=new Set;for(const h of x){if(h===N)continue;const b=D.get(h)??it(p(h));F.some(C=>b.some(L=>ce(C,L,.5)>=_t))&&V.add(h)}return V},"sharedTrackConflictsFor"),jt=d((N,F,D,V)=>{const h=new Set;return xt(N).map(C=>ae(pt(C))).filter(C=>{if(H(N,C))return!1;const L=C.map(w=>`${w.x.toFixed(3)},${w.y.toFixed(3)}`).join("|");return h.has(L)||C.length<2?!1:(h.add(L),!0)}).map(C=>{const L=it(C);let w=0;for(const B of x)B!==N&&(w+=f(L,D.get(B)??it(p(B))));return{candidate:C,candidateSegments:L,crossings:F.count-(V.get(N)??0)+w,bends:Qt(C,Z),totalBends:Qt(C),length:R(C)}}).filter(({crossings:C})=>C<=F.count).sort((C,L)=>C.crossings-L.crossings||C.bends-L.bends||C.length-L.length).slice(0,48).map(C=>({path:C.candidate,segments:C.candidateSegments,sharedTrackConflicts:Vt(N,C.candidateSegments,D),totalBends:C.totalBends,length:C.length}))},"pairCandidatesFor"),Ut=d((N,F,D,V,h,b)=>{let C=0;for(const w of N.pairs)(w.first===F||w.second===F||w.first===V||w.second===V)&&(C+=w.count);let L=f(D.segments,h.segments);for(const w of x){if(w===F||w===V)continue;const B=b.get(w)??it(p(w));L+=f(D.segments,B)+f(h.segments,B)}return N.count-C+L},"pairCrossingCount"),te=d((N,F)=>{for(const D of N.sharedTrackConflicts)if(D!==F)return!1;return!0},"conflictsOnlyWith"),Se=d((N,F)=>N.segments.some(D=>F.segments.some(V=>ce(D,V,.5)>=_t)),"candidatesShareTrack"),de=d((N,F,D,V)=>te(F,D.edge)&&te(V,N.edge)&&!Se(F,V),"pairCandidatesAreCompatible"),Ce=d((N,F,D,V,h)=>{const b=Ut(N.current,F.edge,D,V.edge,h,N.baseSegments);if(!(b>=N.current.count))return{replacements:new Map([[F.edge,D.path],[V.edge,h.path]]),crossings:b,bends:N.currentBends-(N.baseBendsByEdge.get(F.edge)??0)-(N.baseBendsByEdge.get(V.edge)??0)+D.totalBends+h.totalBends,length:N.currentLength-(N.baseLengthByEdge.get(F.edge)??0)-(N.baseLengthByEdge.get(V.edge)??0)+D.length+h.length}},"scorePairReplacement"),dn=d((N,F)=>N.crossings<F.crossings||N.crossings===F.crossings&&(N.bends<F.bends||N.bends===F.bends&&N.length<F.length),"pairScoreIsBetter"),un=d((N,F,D,V)=>{let h=V;for(const b of F.candidates)for(const C of D.candidates){if(!de(F,b,D,C))continue;const L=Ce(N,F,b,D,C);L&&dn(L,h)&&(h=L)}return h},"bestScoreForOptionPair"),hn=d(N=>{const F=k(),D=O(),V=vt(),h=A(N),b=new Map(x.map(q=>[q,Qt(p(q))])),C=new Map(x.map(q=>[q,R(p(q))])),L=new Map,w=m(N);for(const q of w)for(const z of q){if(L.has(z))continue;const Y=jt(z,N,V,h);Y.length>0&&L.set(z,{edge:z,candidates:Y})}let B={replacements:new Map,crossings:N.count,bends:F,length:D};const U={current:N,currentBends:F,currentLength:D,baseBendsByEdge:b,baseLengthByEdge:C,baseSegments:V};for(const q of w){const z=new Set(q.filter(ot=>N.edgeSet.has(ot))),Y=q.map(ot=>L.get(ot)).filter(ot=>!!ot);for(let ot=0;ot<Y.length;ot++){const rt=Y[ot];for(let st=ot+1;st<Y.length;st++){const tt=Y[st];!z.has(rt.edge)&&!z.has(tt.edge)||(B=un(U,rt,tt,B))}}}return B.replacements.size>0?B.replacements:void 0},"bestPairedReplacement");for(let N=0;N<4;N++){const F=v(),D=F.count;if(D===0)return;let V,h,b=D,C=Number.POSITIVE_INFINITY;for(const w of F.edges){const B=Qt(p(w),Z);for(const U of xt(w)){const q=H(w,U),z=!q&&_(w,U),Y=S(F,w,U),ot=Qt(U,Z);q||z||!(Y<D||Y===D&&ot<B)||Y>b||Y===b&&ot>=C||(V=w,h=U,b=Y,C=ot)}}if(V&&h){V.points=h;continue}const L=hn(F);if(!L)return;for(const[w,B]of L)w.points=B}}d(vs,"resolveRenderedOrthogonalCrossings");var pe=.001,Wr=8;function Ls(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e),s=["top","bottom","left","right"],r=20,i={top:Math.min(...o.map(f=>f.rect.top))-r,bottom:Math.max(...o.map(f=>f.rect.bottom))+r,left:Math.min(...o.map(f=>f.rect.left))-r,right:Math.max(...o.map(f=>f.rect.right))+r},c=d((f,y,v,M)=>{const E=[],T=co(f,y,v,M,r,pe);return T&&E.push(T),y===M&&E.push(ao(f,y,v,i[y])),E},"buildOrthogonalPathCandidates"),a=d((f,y)=>{for(let v=0;v<f.length-1;v++){const M=f[v],E=f[v+1];if(At(M,E,o,y,1))return!0}return!1},"pathHitsNode"),l=d((f,y,v=!1)=>{let M=0;const E=Re(f,pe),T=y.start,m=y.end;for(const S of t){if(S===y||S.isLayoutOnly)continue;const A=S.start,R=S.end;if(!v&&T&&m&&(A===T||A===m||R===T||R===m))continue;const k=S.points;if(!(!k||k.length<2))for(const O of E)for(const _ of Re(k,pe)){if(fo(O.a,O.b,_.a,_.b,pe,pe)){M++;continue}ce(O,_,pe)>=Wr&&M++}}return M},"pathConflictCount"),g=4,x=d((f,y)=>{const v=Math.abs(f.y-y.rect.top),M=Math.abs(f.y-y.rect.bottom),E=Math.abs(f.x-y.rect.left),T=Math.abs(f.x-y.rect.right);let m="top",S=v;return M<S&&(m="bottom",S=M),E<S&&(m="left",S=E),T<S&&(m="right",S=T),m},"nearestSideOfRect"),I=new Map,u=d((f,y,v)=>{const M=I.get(f)??[];M.push({side:y,edgeId:v}),I.set(f,M)},"addFaceClaim");for(const f of t){if(f.isLayoutOnly)continue;const y=f.points??[];if(y.length<1)continue;const v=f.id??"",M=f.start,E=f.end;if(M){const T=n.get(M);T&&u(M,x(y[0],T),v)}if(E){const T=n.get(E);T&&u(E,x(y[y.length-1],T),v)}}const p=d((f,y,v)=>I.get(f)?.some(M=>M.edgeId!==v&&M.side===y)??!1,"faceIsClaimed");for(const f of t){if(f.isLayoutOnly)continue;const y=f.points;if(!y||y.length<2)continue;const v=Qt(y,pe);if(v<g)continue;const M=f.start,E=f.end;if(!M||!E)continue;const T=n.get(M),m=n.get(E);if(!T||!m)continue;const S=f.id??"",A=l(y,f,!0),R=l(y,f);let k,O=A,_=v;for(const H of s){if(p(M,H,S))continue;const P=Ie(T,H);for(const G of s){if(p(E,G,S))continue;const j=Ie(m,G);for(const J of c(P,H,j,G)){if(a(J,[M,E]))continue;const dt=Qt(J,pe);if(A>0){const mt=l(J,f,!0);if(mt>O||mt===O&&dt>=_)continue;O=mt,_=dt,k=J;continue}l(J,f)>R||dt<_&&(_=dt,k=J)}}}if(k){f.points=k;const H=I.get(M);H&&I.set(M,H.filter(G=>G.edgeId!==S));const P=I.get(E);P&&I.set(E,P.filter(G=>G.edgeId!==S)),u(M,x(k[0],T),S),u(E,x(k[k.length-1],m),S)}}}d(Ls,"simplifyDetouredEdges");var Kt=.001,Po=10,Ve=7;function $n(t,e){const n=e?0:t.length-1,o=e?1:-1,s=t[n],r=t[n+o];if(!s||!r)return;const i=r.x-s.x,c=r.y-s.y;if(!(Math.abs(i)+Math.abs(c)<Kt)){if(Math.abs(c)<=Kt){const l=s.x+Math.sign(i)*Po;return{left:Math.min(s.x,l),right:Math.max(s.x,l),top:s.y-Ve,bottom:s.y+Ve}}if(Math.abs(i)<=Kt){const l=s.y+Math.sign(c)*Po;return{left:s.x-Ve,right:s.x+Ve,top:Math.min(s.y,l),bottom:Math.max(s.y,l)}}return{left:Math.min(s.x,r.x),right:Math.max(s.x,r.x),top:Math.min(s.y,r.y),bottom:Math.max(s.y,r.y)}}}d($n,"markerClearanceRectFor");function Es(t){return{left:Math.min(t.left,t.right),right:Math.max(t.left,t.right),top:Math.min(t.top,t.bottom),bottom:Math.max(t.top,t.bottom)}}d(Es,"normalizeRect");function zn(t,e){const n=pt(e),o=$n(n,!0),s=$n(n,!1);return[o,s].some(r=>r&&Je(t,Es(r)))}d(zn,"labelOverlapsOwnMarker");function Ue(t,e){const n=[];for(const p of t){if(p.isLayoutOnly)continue;const f=p.points;if(!(!f||f.length<2))for(let y=0;y<f.length-1;y++)n.push({edgeId:p.id,p1:f[y],p2:f[y+1]})}const o=[],s=[];for(const p of e.values()){const f=p.isGroup,y=p.parentId;if(f&&!y){const M=qt(p);M&&s.push({id:p.id,rect:M});continue}if(f||p.isEdgeLabel)continue;const v=qt(p);v&&o.push({nodeId:p.id,rect:v})}const r=3,i=1,c=12,a=d((p,f)=>{const y=Tn(f,r);for(const{nodeId:v,rect:M}of o)if(v!==p&&Je(y,M))return!0;return!1},"labelOverlapsForeignNode"),l=d((p,f)=>{const y=Tn(f,r);for(const v of n)if(v.edgeId!==p&&cn(v.p1,v.p2,y))return!0;return!1},"labelOverlapsForeignEdge"),g=d((p,f,y)=>a(p,y)||l(f,y),"labelOverlapsAnything"),x=[],I=d(p=>{for(const{id:f,rect:y}of s)if(ts(y,p))return f},"findContainingLane"),u=d((p,f)=>x.some(y=>y.labelId!==p&&Je(f,y.rect)),"overlapsPlacedLabel");for(const p of t){if(p.isLayoutOnly)continue;const f=p.labelNodeId;if(!f)continue;const y=e.get(f);if(!y)continue;const v=p.points;if(!v||v.length<2)continue;const M=y.width??0,E=y.height??0;if(M<=0||E<=0)continue;const T=[];for(let Q=0;Q<v.length-1;Q++){const W=v[Q],et=v[Q+1],at=Math.abs(W.x-et.x),gt=Math.abs(W.y-et.y);at<Kt&><Kt||at>=Kt&>>=Kt||T.push({idx:Q,length:at+gt,orientation:at>=Kt?"horizontal":"vertical",midX:(W.x+et.x)/2,midY:(W.y+et.y)/2})}if(T.length===0)continue;const m=T.length>=3?T.filter(Q=>Q.idx>0&&Q.idx<T.length-1):T,S=m.length>0?m:T,A=M>=E?"horizontal":"vertical",R=d(Q=>[...Q].sort((W,et)=>{const at=W.orientation===A,gt=et.orientation===A;if(at!==gt)return at?-1:1;const xt=W.length>=(W.orientation==="horizontal"?M:E)+2,vt=et.length>=(et.orientation==="horizontal"?M:E)+2;return xt!==vt?xt?-1:1:et.length-W.length}),"rankSegments"),k=T[0],O=T[T.length-1],_=[.5,.25,.75,.05,.95,.15,.85,.1,.9],H=d((Q,W)=>{const et=v[Q.idx],at=v[Q.idx+1];return{midX:et.x+(at.x-et.x)*W,midY:et.y+(at.y-et.y)*W}},"anchorAtT"),P=d((Q,W,et)=>Math.min(et,Math.max(W,Q)),"clamp"),G=d((Q,W)=>Q.midX>=W.left-Kt&&Q.midX<=W.right+Kt&&Q.midY>=W.top-Kt&&Q.midY<=W.bottom+Kt,"pointInsideRectInclusive"),j=d(Q=>{const W=Ae(Q.midX,Q.midY,M,E),et=I(W);if(et)return{laneId:et,anchor:Q,rect:W};const at=s.find(({rect:te})=>G(Q,te));if(!at)return;const gt=at.rect.left+M/2+i,xt=at.rect.right-M/2-i,vt=at.rect.top+E/2+i,Vt=at.rect.bottom-E/2-i;if(gt>xt||vt>Vt)return;const jt={midX:P(Q.midX,gt,xt),midY:P(Q.midY,vt,Vt)},Ut=Ae(jt.midX,jt.midY,M,E);return G(Q,Ut)?{laneId:at.id,anchor:jt,rect:Ut}:void 0},"placementForAnchor"),J=d((Q,W,et)=>Q.orientation==="horizontal"?Math.abs(W.midX-et.x):Math.abs(W.midY-et.y),"distanceAlongSegment"),dt=d((Q,W)=>{const at=(Q.orientation==="horizontal"?M/2:E/2)+c;if(Q===k){const gt=v[Q.idx];if(J(Q,W,gt)+Kt<at)return!1}if(Q===O){const gt=v[Q.idx+1];if(J(Q,W,gt)+Kt<at)return!1}return!0},"labelClearsTerminalEndpoints"),mt=d(Q=>{const W=R(Q);for(const et of W)for(const at of _){const gt=H(et,at);if(!dt(et,gt))continue;const xt=j(gt);if(xt&&!zn(xt.rect,v)&&!u(f,xt.rect)&&!g(f,p.id,xt.rect))return{laneId:xt.laneId,anchor:xt.anchor}}},"tryPool"),kt=d((Q,W,et=!1)=>{const at=R(Q);for(const gt of at){const xt={midX:gt.midX,midY:gt.midY};if(W&&!dt(gt,xt))continue;const vt=j(xt);if(vt&&!zn(vt.rect,v)&&!u(f,vt.rect)&&!a(f,vt.rect)&&(et||!l(p.id,vt.rect)))return{laneId:vt.laneId,anchor:vt.anchor}}},"findLaneContainingFallback"),Pt=mt(S)??(S.length<T.length?mt(T):void 0)??kt(T,!0)??kt(T,!1)??kt(T,!1,!0);if(Pt){y.x=Pt.anchor.midX,y.y=Pt.anchor.midY,y.parentId=Pt.laneId;const Q=Ae(Pt.anchor.midX,Pt.anchor.midY,M,E),W=x.findIndex(et=>et.labelId===f);W>=0?x[W]={labelId:f,rect:Q}:x.push({labelId:f,rect:Q})}}}d(Ue,"anchorLabelsToPolyline");var Sn=1e-6,Kr=8,Bo=Kr/2,qr=3;function Vn(t,e){return t<e?`${t}::${e}`:`${e}::${t}`}d(Vn,"pairKey");function Ts(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e),s=new Map;for(const i of e){const c=i.id;if(!i.isGroup&&i.isEdgeLabel){s.set(c,{w:i.width??0,h:i.height??0});continue}}const r=d((i,c,a,l)=>{const g=Vn(c,a);let x=0;const I=d(u=>{if(!u)return;const p=s.get(u);if(!p)return;const f=l==="x"?p.w/2:p.h/2;f>x&&(x=f)},"consider");I(i.labelNodeId);for(const u of t){if(u===i||u.isLayoutOnly)continue;const p=u.start,f=u.end;!p||!f||Vn(p,f)===g&&I(u.labelNodeId)}return x>0?x+qr:0},"labelClearanceFor");for(const i of t){if(i.isLayoutOnly)continue;const c=i.points;if(!ro(c,Sn))continue;const a=lo(i,n,Sn);if(!a)continue;const{srcId:l,dstId:g,srcInfo:x,dstInfo:I,collinearX:u,collinearY:p}=a;if(u===p)continue;let f,y;if(u){const m=I.cy>x.cy;f={x:x.cx,y:m?x.rect.bottom:x.rect.top},y={x:I.cx,y:m?I.rect.top:I.rect.bottom}}else{const m=I.cx>x.cx;f={x:m?x.rect.right:x.rect.left,y:x.cy},y={x:m?I.rect.left:I.rect.right,y:I.cy}}if(At(f,y,o,[l,g],1))continue;const M=r(i,l,g,u?"x":"y"),E=M>Bo?M:Bo,T=[0,E,-E];for(const m of T){const S={...f},A={...y};if(u){if(S.x+=m,A.x+=m,S.x<=x.rect.left||S.x>=x.rect.right||A.x<=I.rect.left||A.x>=I.rect.right)continue}else if(S.y+=m,A.y+=m,S.y<=x.rect.top||S.y>=x.rect.bottom||A.y<=I.rect.top||A.y>=I.rect.bottom)continue;if(!At(S,A,o,[l,g],1)&&!Ze(S,A,t,i,{epsilon:Sn})){i.points=[S,A];break}}}}d(Ts,"straightenCollinearSiblingDetours");function jn(t,e){const{realNodeRects:a,labelNodeRects:l}=me(e.values()),g=d((m,S)=>Re(S,.001).map(A=>({...A,edge:m,interior:A.index>=1&&A.index<=S.length-3})),"segmentsFor"),x=d(()=>{const m=[];for(const S of t){if(S.isLayoutOnly)continue;const A=S.points;!A||A.length<2||m.push(...g(S,pt(A)))}return m},"allSegments"),I=d((m,S)=>m.horizontal&&S.horizontal?zt(m.a.x,m.b.x,S.a.x,S.b.x)>=8&&Math.abs(m.a.y-S.a.y)<7:m.vertical&&S.vertical?zt(m.a.y,m.b.y,S.a.y,S.b.y)>=8&&Math.abs(m.a.x-S.a.x)<7:!1,"hasCrowdedParallelTrack"),u=d((m,S)=>{const A=m.start,R=m.end,k=g(m,S);if(k.length!==S.length-1)return!1;const O=[A,R].filter(H=>!!H),_=m.labelNodeId?[m.labelNodeId]:[];for(const H of k)if(At(H.a,H.b,a,O,-2)||At(H.a,H.b,l,_,-2))return!1;for(const H of t){if(H===m||H.isLayoutOnly)continue;const P=H.points;if(!(!P||P.length<2)){for(const G of k)for(const j of g(H,pt(P)))if(I(G,j)||le(G.a,G.b,j.a,j.b,.001))return!1}}return!0},"candidateIsSafe"),p=d((m,S)=>{const A=pt(m.edge.points??[]);if(A.length<4||m.index>=A.length-1)return;const R=A.map(k=>({...k}));if(m.horizontal)R[m.index].y+=S,R[m.index+1].y+=S;else if(m.vertical)R[m.index].x+=S,R[m.index+1].x+=S;else return;return g(m.edge,R).length===R.length-1?R:void 0},"shiftedCandidate"),f=d((m,S)=>({x:m.x??(S.left+S.right)/2,y:m.y??(S.top+S.bottom)/2}),"nodeCenter"),y=d(m=>{const S=m.edge,A=pt(S.points??[]);if(A.length!==4||m.index!==1)return;const R=S.start?e.get(S.start):void 0,k=S.end?e.get(S.end):void 0,O=R?qt(R):void 0,_=k?qt(k):void 0,H=A.slice(m.index+2);if(!(!R||!k||!O||!_||H.length===0))return{sourceCenter:f(R,O),targetCenter:f(k,_),sourceRect:O,tail:H}},"sourceDetourContextFor"),v=d((m,S,A,R,k,O)=>{const _=R.y>=A.y,H=_?k.bottom:k.top,P=H+(_?20:-20);if(_&&m.b.y<=P+.001||!_&&m.b.y>=P-.001)return;const G=m.a.x+S;return pt([{x:A.x,y:H},{x:A.x,y:P},{x:G,y:P},{x:G,y:m.b.y},...O],.001)},"verticalSourceDetour"),M=d((m,S,A,R,k,O)=>{const _=R.x>=A.x,H=_?k.right:k.left,P=H+(_?20:-20);if(_&&m.b.x<=P+.001||!_&&m.b.x>=P-.001)return;const G=m.a.y+S;return pt([{x:H,y:A.y},{x:P,y:A.y},{x:P,y:G},{x:m.b.x,y:G},...O],.001)},"horizontalSourceDetour"),E=d((m,S)=>{const A=y(m);if(A){if(m.vertical)return v(m,S,A.sourceCenter,A.targetCenter,A.sourceRect,A.tail);if(m.horizontal)return M(m,S,A.sourceCenter,A.targetCenter,A.sourceRect,A.tail)}},"sourceDetourCandidate"),T=[-7,7,-14,14,-21,21];for(let m=0;m<12;m++){const S=x();let A=!1;for(let R=0;R<S.length&&!A;R++)for(let k=R+1;k<S.length&&!A;k++){const O=S[R],_=S[k];if(O.edge===_.edge||!I(O,_))continue;const H=[O,_].filter(P=>P.interior);for(const P of H){for(const G of T){const j=p(P,G);if(j&&u(P.edge,j)){P.edge.points=j,A=!0;break}const J=E(P,G);if(J&&u(P.edge,J)){P.edge.points=J,A=!0;break}}if(A)break}}if(!A)return}}d(jn,"nudgeSharedInteriorSubpaths");function ws(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=o.x-n.x,c=o.y-n.y,a=s*c-r*i;if(Math.abs(a)<1e-10)return!1;const l=n.x-t.x,g=n.y-t.y,x=(l*c-g*i)/a,I=(l*r-g*s)/a,u=.01;return x>u&&x<1-u&&I>u&&I<1-u}d(ws,"segmentsIntersect");function As(t){const e=t.nodes??[],n=t.edges??[],o=[];if(!n.length||!e.length)return o;const s=es(e),r=[];for(const c of n){if(c.isLayoutOnly)continue;const a=c.points;if(!a||a.length<2)continue;const l=c.start,g=c.end,x=c.labelNodeId,I=c.id??`${l}->${g}`;for(const u of s)if(!(u.nodeId===l||u.nodeId===g)&&!(x&&u.nodeId===x)){for(let p=0;p<a.length-1;p++)if(cn(a[p],a[p+1],u,-1)){o.push({type:"edge-node-overlap",edgeId:I,targetId:u.nodeId,detail:`segment ${p} passes through node "${u.nodeId}"`});break}}for(let u=0;u<a.length-1;u++)r.push({edgeId:I,start:l,end:g,p1:a[u],p2:a[u+1]})}const i=new Set;for(let c=0;c<r.length;c++)for(let a=c+1;a<r.length;a++){const l=r[c],g=r[a];if(l.edgeId!==g.edgeId&&!(l.start===g.start||l.start===g.end||l.end===g.start||l.end===g.end)&&ws(l.p1,l.p2,g.p1,g.p2)){const x=l.edgeId<g.edgeId?`${l.edgeId}|${g.edgeId}`:`${g.edgeId}|${l.edgeId}`;i.has(x)||(i.add(x),o.push({type:"edge-edge-crossing",edgeId:l.edgeId,targetId:g.edgeId,detail:`edges "${l.edgeId}" and "${g.edgeId}" cross`}))}}if(o.length>0){const c=o.filter(l=>l.type==="edge-node-overlap").length,a=o.filter(l=>l.type==="edge-edge-crossing").length;Ke.warn(`[SWIMLANE_VALIDATE] ${o.length} issue(s) detected: ${c} edge-node overlap(s), ${a} edge crossing(s)`);for(const l of o)Ke.warn(`[SWIMLANE_VALIDATE] ${l.type}: ${l.detail}`)}return o}d(As,"validateSwimlanesLayout");function Rs(t,e){const n=t.nodes??[],o=t.edges??[],s=n.filter(c=>!c.isGroup);if((e==="LR"||e==="RL")&&s.length>0&&!ms(t,e)||e==="BT"&&s.length>0&&!ps(t))return;for(const c of o){if(c.isLayoutOnly)continue;const a=c.points;!a||a.length<2||(c.points=ae(Qe(a)))}Ls(o,n),Ts(o,n),ys(o,n);const r=new Map;for(const c of n)r.set(String(c.id),c);Ue(o,r),is(o,r),xs(o,r),jn(o,r),bs(o,r),Ms(o,r),Xn(o,r),Is(o,r);const i=d(()=>{vs(o,r),Ss(o,r),Cs(o,r),Ue(o,r),Dn(o,r),Xn(o,r),Ue(o,r),Dn(o,r)},"finalizeRenderedEdges");i(),jn(o,r),i(),Yn(o,r),Gn(o,r),Yn(o,r),Gn(o,r)}d(Rs,"postProcessSwimlaneLayout");function ye(t){const e=new Map(t.nodeById),n=new Set,o=[];for(const r of t.edges){if(!e.has(r.src)||!e.has(r.dst))continue;const i=`${r.id}:${r.src}->${r.dst}`;n.has(i)||(n.add(i),o.push(r))}return{nodes:[...e.keys()],edges:o,layout:t.layout,nodeById:e}}d(ye,"normalizeGraph");function mo(t,e){return t.edges.filter(n=>n.dst===e)}d(mo,"incoming");function Ns(t){const e=new Map;for(const n of t.nodes)e.set(n,[]);for(const n of t.edges)e.get(n.src).push(n.dst);return e}d(Ns,"buildSuccessorMap");function yo(t){const e=Ns(t);for(const n of e.values())n.sort((o,s)=>o.localeCompare(s));return e}d(yo,"buildSortedSuccessorMap");function xo(t){const e=new Map;for(const n of t.nodes)e.set(n,0);for(const n of t.edges)e.set(n.dst,(e.get(n.dst)??0)+1);return e}d(xo,"buildInDegreeMap");function bo(t){return[...t.entries()].filter(([,e])=>e===0).map(([e])=>e).sort((e,n)=>e.localeCompare(n))}d(bo,"sortedZeroInDegreeNodes");function ln(t,e=()=>!0){const n=new Map,o=new Map;for(const s of t.nodes)n.set(s,[]),o.set(s,[]);for(const s of t.edges)e(s)&&(o.get(s.src).push(s.dst),n.get(s.dst).push(s.src));return{preds:n,succs:o}}d(ln,"buildPredecessorSuccessorMaps");function Mo(t,e,n,o){let s=0;for(const i of t.nodes)o?.skipGroups&&t.nodeById.get(i)?.isGroup||(s=Math.max(s,n[i]??0));const r=Array.from({length:s+1},()=>[]);for(const i of e)o?.skipGroups&&t.nodeById.get(i)?.isGroup||r[Math.max(0,n[i]??0)].push(i);return r}d(Mo,"buildLayersFromRanks");function Be(t){const e=xo(t),n=bo(e),o=[],s=yo(t);for(;n.length;){const r=n.shift();o.push(r);for(const i of s.get(r)??[])if(e.set(i,(e.get(i)??0)-1),(e.get(i)??0)===0){let c=0;for(;c<n.length&&n[c]<i;)c++;n.splice(c,0,i)}}return o.length===t.nodes.length?o:null}d(Be,"topoSortIfAcyclic");function Ne(t){const e=new Map;let n=0;for(const o of t)e.set(o,n),n++;return e}d(Ne,"buildLayerIndex");function Io(t){const e=new Array(t.length),n=d((o,s)=>{if(s-o<=1)return 0;const r=o+s>>1;let i=n(o,r)+n(r,s),c=o,a=r,l=o;for(;c<r||a<s;)a>=s||c<r&&t[c]<=t[a]?e[l++]=t[c++]:(e[l++]=t[a++],i+=r-c);for(let g=o;g<s;g++)t[g]=e[g];return i},"count");return n(0,t.length)}d(Io,"countInversions");function Os(t){const e=ye(t),n=new Map;for(const g of e.nodes)n.set(g,[]);for(const g of e.edges)n.get(g.src).push(g);for(const g of n.values())g.sort((x,I)=>x.dst===I.dst?x.id.localeCompare(I.id):x.dst.localeCompare(I.dst));const o=Object.create(null);for(const g of e.nodes)o[g]=0;const s=[],r=d(g=>{o[g]=1;for(const x of n.get(g)??[]){const I=x.dst;o[I]===0?r(I):o[I]===1&&s.push(x)}o[g]=2},"dfs"),i=[...e.nodes].sort((g,x)=>g.localeCompare(x));for(const g of i)o[g]===0&&r(g);const c=new Set(s.map(g=>`${g.id}:${g.src}->${g.dst}`)),a=e.edges.map(g=>c.has(`${g.id}:${g.src}->${g.dst}`)?{id:g.id,src:g.dst,dst:g.src,weight:g.weight,ref:g.ref}:g);return{acyclic:{nodes:[...e.nodes],edges:a,layout:e.layout,nodeById:new Map(e.nodeById)},reversed:s}}d(Os,"removeCycles_DFS");function Ps(t){const e=new Map,n=d(o=>{if(e.has(o))return e.get(o);const s=t.nodeById.get(o);if(!s)return e.set(o,null),null;const r=s.parentId;if(!r)return e.set(o,null),null;const c=n(r)??r;return e.set(o,c),c},"resolve");for(const o of t.nodes)n(o);return e}d(Ps,"buildTopLaneMap");function fe(t){const e=Ps(t);return n=>e.get(n)??null}d(fe,"createTopLaneResolver");function fn(t){const e=[];for(const n of t.layout.nodes??[])n.isGroup&&!n.parentId&&e.push(n.id);return[...new Set(e)].reverse()}d(fn,"buildTopLaneOrder");function So(t,e){const n=fn(t);if(!e||e.length===0)return n;const o=new Set(n),s=new Set,r=[];for(const i of e)!o.has(i)||s.has(i)||(s.add(i),r.push(i));for(const i of n)s.has(i)||r.push(i);return r}d(So,"resolveTopLaneOrder");var Jr={EPSILON:1e-6},sn={GRAVITY_ITERATIONS:8,MAX_CROSSING_OPTIMIZATION_PASSES:4,DEFAULT_COMPACT_SINGLE_INPUT:!0},ko={DEFAULT_LAYER_GAP:100,DEFAULT_NODE_GAP:40};function Bs(t,e){const n=ye(t),o=e?.laneOf??(()=>null),s=e?.rankHint,{preds:r}=ln(n);for(const m of r.values())m.sort((S,A)=>S.localeCompare(A));const i=Be(n)??[...n.nodes].sort((m,S)=>m.localeCompare(S)),c=new Map;for(const[m,S]of i.entries())c.set(S,m);const a=new Map,l=new Map;for(const m of n.nodes)l.set(m,[]);for(const m of i){const S=(r.get(m)??[]).filter(A=>a.has(A));if(S.length>0){const A=ks(m,S,{laneOf:o,rankHint:s,topoIndex:c});a.set(m,A),l.get(A).push(m)}else a.has(m)||a.set(m,null)}for(const m of n.nodes)a.has(m)||a.set(m,null);const g=new Set;for(const m of n.nodes)(a.get(m)??null)===null&&g.add(m);const x=[...g].sort((m,S)=>{const A=c.get(m)??0,R=c.get(S)??0;return A===R?m.localeCompare(S):A-R}),I=_s(n),u=new Map;for(const[m,S]of I.entries())u.set(m,[...S].sort((A,R)=>A.localeCompare(R)));const p=Fs(u),f=Ds(u),y=new Map;for(const m of n.nodes)y.set(m,[]);for(const m of f)for(const S of m.nodes){const A=y.get(S);A?A.push(m.id):y.set(S,[m.id])}const v=[],M=[],E=new Set,T=d(m=>{if(!E.has(m)){E.add(m),v.push(m);for(const S of l.get(m)??[])T(S);M.push(m)}},"walk");for(const m of x)T(m);for(const m of i)T(m);return{parent:a,children:l,roots:x,componentOf:p,blocks:f,nodeBlocks:y,adjacency:u,preorder:v,postorder:M,topologicalOrder:i}}d(Bs,"buildDrivingTree");function ks(t,e,n){const o=n.laneOf(t);return[...e].sort((r,i)=>{const c=n.laneOf(r),a=n.laneOf(i),l=c!=null&&c===o,g=a!=null&&a===o;if(l!==g)return l?-1:1;const x=n.rankHint?.[r],I=n.rankHint?.[i];if(x!=null&&I!=null&&x!==I)return I-x;const u=n.topoIndex.get(r)??0,p=n.topoIndex.get(i)??0;return u!==p?u-p:r.localeCompare(i)})[0]}d(ks,"chooseParent");function _s(t){const e=new Map;for(const n of t.nodes)e.set(n,new Set);for(const n of t.edges)e.get(n.src).add(n.dst),e.get(n.dst).add(n.src);return e}d(_s,"buildAdjacency");function Fs(t){const e=new Map;let n=0;for(const o of t.keys()){if(e.has(o))continue;const s=[o];for(;s.length>0;){const r=s.pop();if(!e.has(r)){e.set(r,n);for(const i of t.get(r)??[])e.has(i)||s.push(i)}}n++}return e}d(Fs,"assignComponents");function Ds(t){const e=new Map,n=new Map,o=[],s=[];let r=0;const i=d((c,a)=>{e.set(c,++r),n.set(c,r);for(const l of t.get(c)??[])l!==a&&(e.has(l)?(e.get(l)??0)<(e.get(c)??0)&&(o.push([c,l]),n.set(c,Math.min(n.get(c)??r,e.get(l)??r))):(o.push([c,l]),i(l,c),n.set(c,Math.min(n.get(c)??r,n.get(l)??r)),(n.get(l)??0)>=(e.get(c)??0)&&s.push(Hs(c,l,o,s.length))))},"visit");for(const c of t.keys())e.has(c)||i(c,null);return s}d(Ds,"computeBlocks");function Hs(t,e,n,o){const s=[],r=new Set;for(;n.length>0;){const i=n.pop();if(s.push(i),r.add(i[0]),r.add(i[1]),i[0]===t&&i[1]===e||i[0]===e&&i[1]===t)break}return{id:o,edges:s,nodes:[...r]}}d(Hs,"popBlock");function Xs(t,e,n){const o=[...t.nodes],s=new Map;for(const[M,E]of o.entries())s.set(E,M);const r=o.length,i=new Array(r).fill(-1),c=new Array(r).fill(0),a=[],l=new Set;for(const M of o){const E=n.parent.get(M)??null,T=s.get(M);T!=null&&E==null&&(i[T]=-1,c[T]=0,l.has(M)||(l.add(M),a.push(M)))}for(;a.length>0;){const M=a.shift(),E=s.get(M);if(E==null)continue;const T=n.children.get(M)??[];for(const m of T){if(l.has(m))continue;const S=s.get(m);S!=null&&(i[S]=E,c[S]=c[E]+1,l.add(m),a.push(m))}}for(const M of o){if(l.has(M))continue;const E=s.get(M);E!=null&&(i[E]=-1,c[E]=0,l.add(M))}const g=Math.max(1,Math.ceil(Math.log2(Math.max(1,r)))+1),x=Array.from({length:g},()=>new Array(r).fill(-1));for(let M=0;M<r;M++)x[0][M]=i[M];for(let M=1;M<g;M++)for(let E=0;E<r;E++){const T=x[M-1][E];x[M][E]=T===-1?-1:x[M-1][T]}const I=d((M,E)=>{if(M===-1||E===-1)return-1;c[M]<c[E]&&([M,E]=[E,M]);const T=c[M]-c[E];for(let m=0;m<g;m++)if(T>>m&1&&(M=x[m][M],M===-1))return-1;if(M===E)return M;for(let m=g-1;m>=0;m--){const S=x[m][M],A=x[m][E];S===-1||A===-1||S!==A&&(M=S,E=A)}return x[0][M]},"lcaIndex"),u=Array.from({length:r},()=>new Map);for(const M of t.edges){let E=M.src,T=M.dst,m=e[E],S=e[T];if(m==null||S==null||(m>S&&([E,T]=[T,E],[m,S]=[S,m]),m==null||S==null||m===S))continue;const A=s.get(E),R=s.get(T);if(A==null||R==null)continue;const k=I(A,R);if(k===-1)continue;const O=u[k];for(let _=m;_<S;_++)O.set(_,(O.get(_)??0)+1)}const p=new Map,f=d((M,E)=>{if(E.size!==0)for(const[T,m]of E)M.set(T,(M.get(T)??0)+m)},"mergeInto"),y=new Set,v=d(M=>{const E=s.get(M);y.add(M);const T=E==null?void 0:u[E],m=T?new Map(T):new Map,S=n.children.get(M)??[];for(const A of S){const R=v(A),k=e[M];if(k!=null){let O=p.get(M);O||(O=new Map,p.set(M,O));let _=R.get(k)??0;const H=e[A];H!=null&&H>k&&(_+=1),O.set(A,_)}f(m,R)}return m},"dfs");for(const M of n.roots)y.has(M)||v(M);for(const M of o)y.has(M)||v(M);return p}d(Xs,"computeSubtreeCrossCounts");function Ys(t,e,n){const o=new Map,s=d(r=>{let i=n[r]??0;const c=[...e.get(r)??[]];c.sort(Co(n));for(const a of c){s(a);const l=o.get(a);l!=null&&(i=Math.min(i,l))}o.set(r,i)},"annotate");for(const r of t)s(r);return o}d(Ys,"annotateMinimumLayers");function Co(t){return(e,n)=>{const o=t[e]??0,s=t[n]??0;return o===s?e.localeCompare(n):o-s}}d(Co,"compareByRankThenId");function Gs(t,e,n,o){let s=0;for(const a of e){const l=n[a]??0;l>s&&(s=l)}const r=Array.from({length:s+1},()=>[]),i=new Set,c=d(a=>{if(i.has(a))return;i.add(a);const l=n[a]??0;r[l]||(r[l]=[]),r[l].push(a);for(const g of o(a))c(g)},"emit");for(const a of t)c(a);for(const a of e)if(!i.has(a)){const l=n[a]??0;r[l]||(r[l]=[]),r[l].push(a),i.add(a)}return r}d(Gs,"emitNodesInTreeOrder");function $s(t){const e=[];for(const n of t){const o=new Set,s=[];for(const r of n)o.has(r)||(o.add(r),s.push(r));e.push(s)}return e}d($s,"deduplicateLayers");function zs(t,e,n,o){return s=>{const r=t.get(s)??[];if(r.length===0)return[];const i=e[s]??0,c=[],a=[],l=n.get(s);for(const g of r){const x=o.get(g)??i;x>i?c.push({child:g,min:x}):a.push(g)}return c.sort((g,x)=>g.min===x.min?g.child.localeCompare(x.child):g.min-x.min),a.sort((g,x)=>{const I=l?.get(g)??0,u=l?.get(x)??0;if(I!==u)return I-u;const p=o.get(g)??i,f=o.get(x)??i;return p!==f?p-f:g.localeCompare(x)}),[...c.map(g=>g.child),...a]}}d(zs,"createChildOrderer");function rn(t,e,n){const o=Bs(t,{rankHint:e,laneOf:n}),{children:s,roots:r}=o;for(const x of t.nodes)s.has(x)||s.set(x,[]);const i=Xs(t,e,o),c=[...r].sort(Co(e)),a=Ys(c,s,e),l=zs(s,e,i,a);let g=Gs(c,t.nodes,e,l);return g=$s(g),g}d(rn,"buildMultitreeLayerOrder");function Vs(t,e,n){const o=new Set(t),s=new Set(e),r=Ne(e),i=[];for(const c of n)o.has(c.src)&&s.has(c.dst)&&i.push(r.get(c.dst));return Io(i)}d(Vs,"countCrossingsBetweenAdjacent");function Un(t,e,n){const o=[];for(const r of e){const i=n[r.src],c=n[r.dst];if(i==null||c==null||i===c)continue;let a=r.src,l=r.dst,g=i,x=c;i>c&&(a=r.dst,l=r.src,g=c,x=i);for(let I=g;I<x;I++)o.push({id:`${r.id}@${I}`,src:a,dst:l,ref:r.ref})}let s=0;for(let r=0;r+1<t.length;r++)s+=Vs(t[r],t[r+1],o);return s}d(Un,"totalCrossings");function js(t,e){const n={...e},{preds:o}=ln(t),s=fe(t),r=rn(t,n,s);let i=Un(r,t.edges,n);const c=sn.MAX_CROSSING_OPTIMIZATION_PASSES;for(let a=0;a<c;a++){let l=!1;const g=[...t.nodes].sort((x,I)=>(n[I]??0)-(n[x]??0));for(const x of g){const I=n[x]??0;if(I===0)continue;let u=0;for(const v of o.get(x)??[])u=Math.max(u,(n[v]??0)+1);if(u>=I)continue;const p=I;n[x]=u;const f=rn(t,n,s),y=Un(f,t.edges,n);y<i?(i=y,l=!0):n[x]=p}if(!l)break}return n}d(js,"optimizeRanksByCrossings");function Us(t,e){const n=fe(t),o=[...t.nodes].sort((s,r)=>(e[s]??0)-(e[r]??0)||s.localeCompare(r));for(const s of o){const r=n(s);if(!r)continue;const i=t.edges.filter(f=>f.src===s);if(i.length===0)continue;let c=!1,a=0;for(const f of i){const y=n(f.dst);y==null||y===r?c=!0:a++}if(a===0||c)continue;let l=0,g=!1;for(const f of t.edges){if(f.dst!==s)continue;const y=n(f.src);y&&(y===r?g=!0:l++)}if(l>0||!g)continue;const x=e[s]??0,I=x+a;let u=0;for(const f of t.edges)f.dst===s&&(u=Math.max(u,(e[f.src]??0)+1));const p=Math.max(x,u,I);p!==x&&(e[s]=p)}}d(Us,"adjustCrossLaneSources");function Ws(t,e){const n=ye(t),o=Be(n)??[...n.nodes].sort(),s=e?.compactSingleInput??!1,r=fe(n);let i=Object.create(null);for(const a of o){const l=mo(n,a),g=e?.ignoreCrossLaneEdges?l.filter(x=>{const I=r(x.src),u=r(a);return!I||!u?!0:I===u}):l;if(g.length===0)i[a]=0;else if(s&&g.length===1){const x=g[0].src,I=r(x),u=r(a);I!==u?i[a]=i[x]??0:i[a]=(i[x]??0)+1}else{let x=-1/0;for(const I of g)x=Math.max(x,(i[I.src]??0)+1);i[a]=x===-1/0?0:x}}return(e?.optimizeRanksByCrossings??!1)&&(i=js(n,i)),e?.ignoreCrossLaneEdges&&Us(n,i),{layers:rn(n,i,r),rankOf:i,dummy:new Set}}d(Ws,"assignLayers_LongestPath");function Ks(t,e){const n=ye(t),s={...Ws(n,{compactSingleInput:e?.compactSingleInput,ignoreCrossLaneEdges:e?.ignoreCrossLaneEdges,optimizeRanksByCrossings:e?.optimizeRanksByCrossings}).rankOf},r=fe(n),{preds:i,succs:c}=ln(n,p=>{if(e?.ignoreCrossLaneEdges){const f=r(p.src),y=r(p.dst);if(f&&y&&f!==y)return!1}return!0}),a=Be(n)??[...n.nodes],l=[...a].reverse(),g=d((p,f)=>{let y=0;for(const E of i.get(p)??[])y=Math.max(y,(s[E]??0)+1);let v=Number.POSITIVE_INFINITY;const M=c.get(p)??[];return M.length>0&&(v=Math.min(...M.map(E=>(s[E]??0)-1))),Number.isFinite(v)||(v=Math.max(y,f)),Math.min(Math.max(f,y),v)},"clampFeasible"),x=sn.GRAVITY_ITERATIONS,I=d(p=>{let f=!1;for(const y of p){const v=i.get(y)??[],M=c.get(y)??[];if(v.length===0&&M.length===0)continue;const E=v.length>0?v.reduce((A,R)=>A+(s[R]??0)+1,0)/v.length:s[y]??0,T=M.length>0?M.reduce((A,R)=>A+(s[R]??0)-1,0)/M.length:s[y]??0,m=Math.round((E+T)/2),S=g(y,m);S!==s[y]&&(s[y]=S,f=!0)}return f},"relaxOrder");for(let p=0;p<x;p++){const f=I(a),y=I(l);if(!f&&!y)break}for(const p of a){let f=0;for(const y of i.get(p)??[])f=Math.max(f,(s[y]??0)+1);(s[p]??0)<f&&(s[p]=f)}for(const p of l){const f=c.get(p)??[];if(f.length>0){const y=Math.min(...f.map(v=>(s[v]??0)-1));(s[p]??0)>y&&(s[p]=y)}}return{layers:Mo(n,a,s),rankOf:s,dummy:new Set}}d(Ks,"assignLayers_Gravity");function qs(t){const e=xo(t),n=yo(t);let o=bo(e);const s=[];for(;o.length>0;){const r=[];for(const i of o){s.push(i);for(const c of n.get(i)??[])e.set(c,(e.get(c)??0)-1),(e.get(c)??0)===0&&r.push(c)}o=r.sort((i,c)=>i.localeCompare(c))}return s.length===t.nodes.length?s:null}d(qs,"topoSortByGenerationIfAcyclic");function Js(t,e){const n=ye(t),o=e?.direction==="LR"?qs(n)??[...n.nodes].sort():Be(n)??[...n.nodes].sort(),s=fe(n),r=d(g=>s(g)??g,"laneOf"),i=Object.create(null),c=new Map,a=d((g,x)=>e?.ignoreCrossLaneEdges??!0?r(g)===r(x)?1:0:1,"edgeWeight");for(const g of o){if(n.nodeById.get(g)?.isGroup)continue;const I=mo(n,g);let u=0;if(I.length>0)for(const v of I){const M=v.src,E=i[M]??0;u=Math.max(u,E+a(M,g))}const p=r(g),f=c.get(p)??0,y=Math.max(u,f);i[g]=y,c.set(p,y+1)}return{layers:Mo(n,o,i,{skipGroups:!0}),rankOf:i,dummy:new Set}}d(Js,"assignLayers_LaneAwareCompact");function Zs(t,e){const n=ye(e),{rankOf:o}=t,s=t.layers.map(u=>[...u]),r=new Set(t.dummy?[...t.dummy]:[]);let i=0;const c=new Map(n.nodeById),a=d(u=>{const p=`placeholder-${i++}`,f={id:p,isGroup:!1,isDummy:!0,width:0,height:0};for(c.set(p,f),r.add(p);s.length<=u;)s.push([]);return s[u].push(p),o[p]=u,p},"addDummyAt"),l=[...n.edges].sort((u,p)=>u.id===p.id?u.src===p.src?u.dst.localeCompare(p.dst):u.src.localeCompare(p.src):u.id.localeCompare(p.id)),g=[];for(const u of l){const p=o[u.src]??0,f=o[u.dst]??0;if(f-p<=1){g.push(u);continue}let y=u.src;for(let M=p+1,E=0;M<f;M++,E++){const T=a(M);g.push({id:`${u.id}#${E}`,src:y,dst:T,weight:u.weight,ref:u.ref}),y=T}const v=f-p-2;g.push({id:`${u.id}#${Math.max(v+1,0)}`,src:y,dst:u.dst,weight:u.weight,ref:u.ref})}const I={nodes:[...n.nodes,...[...r].filter(u=>!n.nodes.includes(u))],edges:g,layout:n.layout,nodeById:c};return{layering:{layers:s,rankOf:o,dummy:r},graphWithDummies:I}}d(Zs,"makeProperLayering");function Wn(t){const e=t.length;if(e===0)return Number.POSITIVE_INFINITY;const n=[...t].sort((o,s)=>o-s);return e%2===1?n[(e-1)/2]:.5*(n[e/2-1]+n[e/2])}d(Wn,"median");function Kn(t){return t.length===0?Number.POSITIVE_INFINITY:t.reduce((n,o)=>n+o,0)/t.length}d(Kn,"barycenter");function Qs(t,e,n,o){const s=new Map;for(const r of t)s.set(r,[]);for(const r of n)o==="down"?e.has(r.src)&&s.has(r.dst)&&s.get(r.dst).push(e.get(r.src)):e.has(r.dst)&&s.has(r.src)&&s.get(r.src).push(e.get(r.dst));return s}d(Qs,"neighborPositionsFor");function tr(t,e,n){const o=n.get(t)??0,s=n.get(e)??0;return o!==s?o-s:t.localeCompare(e)}d(tr,"currentOrderTieBreak");function qn(t,e,n){const o=new Set(t),s=new Set(e),r=Ne(t),i=Ne(e),c=[];for(const l of n)o.has(l.src)&&s.has(l.dst)&&c.push({u:r.get(l.src),v:i.get(l.dst)});c.sort((l,g)=>l.u===g.u?l.v-g.v:l.u-g.u);const a=c.map(l=>l.v);return Io(a)}d(qn,"countCrossingsBetweenAdjacent");function We(t,e,n){return[...t].sort((o,s)=>{const r=Wn(e.get(o)??[]),i=Wn(e.get(s)??[]);return r===i?tr(o,s,n):isFinite(r)?isFinite(i)?r-i:-1:1})}d(We,"sortByHeuristic");function Jn(t,e,n,o,s,r){const i=Ne(t),c=Ne(e),a=Qs(e,i,n,o);if(!s||!r||r.length===0)return We(e,a,c);const l=new Map;for(const I of e){const u=s(I),p=l.get(u)??[];p.push(I),l.set(u,p)}const g=[];for(const I of r){const u=l.get(I);if(!u||u.length===0)continue;const p=We(u,a,c);g.push(...p)}const x=l.get(null);if(x&&x.length>0){const I=We(x,a,c);for(const u of I){const p=Kn(a.get(u)??[]);let f=g.length;if(isFinite(p))for(const[y,v]of g.entries()){const M=Kn(a.get(v)??[]);if(p<M){f=y;break}}g.splice(f,0,u)}}return g}d(Jn,"reorderLayer");function Zn(t,e,n,o,s){const r=[...e],i=new Set(t),c=new Set(e),a=o?new Set(o):null,l=n.filter(f=>i.has(f.src)&&c.has(f.dst)),g=a?n.filter(f=>c.has(f.src)&&a.has(f.dst)):void 0,x=d(f=>{let y=qn(t,f,l);return g&&o&&(y+=qn(f,o,g)),y},"crossingScore"),I=s?new Map:null;if(s&&I)for(const f of e)I.set(f,s(f));let u=!0,p=x(r);for(;u;){u=!1;for(let f=0;f+1<r.length;f++){if(I){const M=I.get(r[f]),E=I.get(r[f+1]);if(M!==E)continue}const y=p;[r[f],r[f+1]]=[r[f+1],r[f]];const v=x(r);v<y?(p=v,u=!0):[r[f],r[f+1]]=[r[f+1],r[f]]}}return r}d(Zn,"transposeImprove");function er(t,e,n){const o=t.layers.map(c=>[...c]),s=e.edges,r=fe(e),i=So(e,n?.laneOrder);for(let c=0;c<3;c++){for(let a=1;a<o.length;a++)o[a]=Jn(o[a-1],o[a],s,"down",r,i),o[a]=Zn(o[a-1],o[a],s,o[a+1],r);for(let a=o.length-2;a>=0;a--)o[a]=Jn(o[a+1],o[a],s,"up",r,i),o[a]=Zn(o[a+1],o[a],s,o[a-1],r)}return{layers:o}}d(er,"orderLayers");function nr(t,e,n){const o=n?.layerGap??ko.DEFAULT_LAYER_GAP,s=n?.nodeGap??ko.DEFAULT_NODE_GAP,r=n?.laneGap??s*2,i=n?.direction??"TB",c=i==="LR"||i==="RL",a=t.layers,l=Object.create(null),g=Object.create(null),x=d(O=>e.nodeById.get(O),"getNode"),I=d(O=>x(O)?.width??0,"getWidth"),u=d(O=>x(O)?.height??0,"getHeight"),p=fe(e),f=So(e,n?.laneOrder),y=a.map(O=>O.reduce((_,H)=>Math.max(_,u(H)),0)),v=[];if(c)for(let O=0;O+1<a.length;O++){const _=a[O].reduce((mt,kt)=>Math.max(mt,I(kt)),0),H=a[O+1].reduce((mt,kt)=>Math.max(mt,I(kt)),0),P=y[O],G=y[O+1],j=P/2+G/2,J=(_+H)/2,dt=Math.max(0,J-j-o);v.push(dt)}const M=new Set;for(const O of a)for(const _ of O)M.add(p(_));const E=M.has(null),T=f.filter(O=>M.has(O)),m=[...E?[null]:[],...T],S=Object.create(null);for(const O of T)S[O]=0;E&&(S.null=0);for(const O of a){const _=Object.create(null),H=[];for(const P of O){const G=p(P);G===null?H.push(P):(_[G]||=[]).push(P)}for(const[P,G]of Object.entries(_)){const j=G.reduce((J,dt)=>J+I(dt),0)+s*Math.max(0,G.length-1);S[P]=Math.max(S[P]??0,j)}if(E&&H.length){const P=H.reduce((G,j)=>G+I(j),0)+s*Math.max(0,H.length-1);S.null=Math.max(S.null??0,P)}}const A=new Map;{const O=m.map(P=>(P===null?S.null:S[P])??0);let H=-(O.reduce((P,G)=>P+G,0)+r*Math.max(0,m.length-1))/2;for(let P=0;P<m.length;P++){const G=m[P],j=O[P]??0,J=H+j/2;A.set(G,J),H+=j,P<m.length-1&&(H+=r)}}let R=0;for(const[O,_]of a.entries()){const H=y[O]??0,P=new Map;for(const j of _){const J=p(j),dt=P.get(J)??[];dt.push(j),P.set(J,dt)}for(const j of m){const J=P.get(j)??[];if(J.length===0)continue;const dt=A.get(j);if(J.length===1){const mt=J[0];l[mt]=dt,g[mt]=R+H/2}else{const mt=J.map(Q=>I(Q)),kt=mt.reduce((Q,W)=>Q+W,0)+s*(J.length-1);let Pt=dt-kt/2;for(const[Q,W]of J.entries()){const et=mt[Q];l[W]=Pt+et/2,g[W]=R+H/2,Pt+=et+s}}}const G=v[O]??0;R+=H+o+G}const k=new Map;for(const O of e.edges){const _=O.ref.id;k.has(_)||k.set(_,[]),k.get(_).push(O)}for(const[,O]of k){if(O.length===0)continue;const _=O[0].ref,H=_.start,P=_.end;if(H==null||P==null)continue;const G=Math.round(((l[H]??0)+(l[P]??0))/2),j=new Set;for(const J of O)j.add(J.src),j.add(J.dst);for(const J of j){if(J===H||J===P)continue;e.nodeById.get(J)?.isDummy&&(l[J]=G)}}return{x:l,y:g}}d(nr,"assignCoordinates");var or=8;function sr(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619);return e>>>0}d(sr,"hashString");function rr(t){let e=t>>>0;return()=>{e+=1831565813;let n=e;return n=Math.imul(n^n>>>15,n|1),n^=n+Math.imul(n^n>>>7,n|61),((n^n>>>14)>>>0)/4294967296}}d(rr,"mulberry32");function ir(t,e){const n=[...t],o=rr(e);for(let s=n.length-1;s>0;s--){const r=Math.floor(o()*(s+1));[n[s],n[r]]=[n[r],n[s]]}return n}d(ir,"deterministicShuffle");function cr(t,e){let n=0;for(const[o,s]of t.entries())n+=Math.abs(o-(e.get(s)??o));return n}d(cr,"sourceDistance");function Qn(t,e){const n=new Map;for(const[s,r]of t.entries())n.set(r,s);let o=0;for(const{a:s,b:r,weight:i}of e){const c=n.get(s),a=n.get(r);c==null||a==null||(o+=i*Math.abs(c-a))}return o}d(Qn,"laneArrangementCost");function ar(t){const e=fn(t);if(e.length<2)return[];const n=new Map(e.map((r,i)=>[r,i])),o=fe(t),s=new Map;for(const r of t.layout.edges??[]){if(r.isLayoutOnly)continue;const i=typeof r.start=="string"?r.start:void 0,c=typeof r.end=="string"?r.end:void 0;if(!i||!c||!t.nodeById.has(i)||!t.nodeById.has(c))continue;const a=o(i),l=o(c);if(!a||!l||a===l)continue;const g=n.get(a),x=n.get(l);if(g==null||x==null)continue;const[I,u]=g<=x?[a,l]:[l,a],p=`${I}\0${u}`,f=s.get(p);f?f.weight++:s.set(p,{a:I,b:u,weight:1})}return[...s.values()]}d(ar,"buildWeightedLaneEdges");function to(t,e,n){const o=[...t];let s=Qn(o,e),r=!0,i=0;const c=Math.max(1,o.length);for(;r&&i<c;){r=!1,i++;for(let a=0;a+1<o.length;a++){[o[a],o[a+1]]=[o[a+1],o[a]];const l=Qn(o,e);l<s?(s=l,r=!0):[o[a],o[a+1]]=[o[a+1],o[a]]}}return{order:o,cost:s,sourceDistance:cr(o,n)}}d(to,"greedySwitch");function lr(t,e){return t.cost!==e.cost?t.cost<e.cost:t.sourceDistance<e.sourceDistance}d(lr,"isBetterCandidate");function fr(t,e,n){const o=[...e].sort((s,r)=>s.a===r.a?s.b.localeCompare(r.b):s.a.localeCompare(r.a)).map(({a:s,b:r,weight:i})=>`${s}:${r}:${i}`).join("|");return sr(`${t.join("|")}#${o}#${n}`)}d(fr,"seedForRestart");function dr(t,e={}){const n=fn(t);if(n.length<2)return n;const o=ar(t);if(o.length===0)return n;const s=new Map(n.map((c,a)=>[c,a]));let r=to(n,o,s);const i=Math.max(0,e.restarts??or);for(let c=0;c<i;c++){const a=fr(n,o,c),l=ir(n,a),g=to(l,o,s);lr(g,r)&&(r=g)}return r.order}d(dr,"optimizeTopLaneOrder");function ur(t,e){const n=e?.ignoreCrossLaneEdges??!0,o=e?.optimizeRanksByCrossings??!0,s=ye(t),r=e?.automaticLaneOrdering?dr(s,{restarts:or}):void 0,i=Os(s),c=i.acyclic,a=n?Js(c,{compactSingleInput:e?.compactSingleInput??sn.DEFAULT_COMPACT_SINGLE_INPUT,ignoreCrossLaneEdges:!0,direction:e?.direction}):Ks(c,{compactSingleInput:e?.compactSingleInput??sn.DEFAULT_COMPACT_SINGLE_INPUT,ignoreCrossLaneEdges:!1,optimizeRanksByCrossings:o}),{layering:l,graphWithDummies:g}=Zs(a,c),x=er(l,g,{laneOrder:r}),I=nr(x,g,{layerGap:e?.layerGap,nodeGap:e?.nodeGap,direction:e?.direction,laneOrder:r});return{acyclic:c,reversed:i.reversed,layering:l,ordered:x,coordinates:I}}d(ur,"sugiyamaLayout");var ct=Jr.EPSILON,Zr=8,be=15,Te=15,je=25,ne=20,Cn=10;function eo(t,e,n){const o=t.x??0,s=t.y??0,r=e.x-o,i=e.y-s,c=Math.abs(r),a=Math.abs(i);return c<ct&&a<ct?n:a>ct&&a*3>=c?i>0?"bottom":"top":c>ct?r>0?"right":"left":n}d(eo,"chooseOrthogonalSide");function no(t,e){return Math.abs(t.to-e.from)<ct||Math.abs(t.to-e.to)<ct?t.to:t.from}d(no,"sharedLineEndpointCoord");function Me(t,e){return t.orient==="vertical"?{x:t.coord,y:e}:{x:e,y:t.coord}}d(Me,"pointOnLine");function hr(t,e){const n=t.nodes??[],o=t.edges??[],s=[];for(const h of o)h.isLayoutOnly||s.push({...h,__originalEdge:h});const r=new Map,i=new Map,c=[],a=e==="LR";for(const h of n)r.set(h.id,h);const l=n.filter(h=>h.isGroup&&!h.parentId);for(const h of l){const b={id:h.id},C=d(L=>{i.set(L.id,b),n.filter(w=>w.parentId===L.id).forEach(C)},"assignLane");C(h)}const g=n.filter(h=>!h.isGroup&&!h.isEdgeLabel).map(h=>{const b=h.width??10,C=h.height??10,L=h.x??0,w=h.y??0,B=Zr;return{nodeId:h.id,minX:L-b/2-B,maxX:L+b/2+B,minY:w-C/2-B,maxY:w+C/2+B,visualXHalfExtent:a?C/2+B:b/2+B}}),x=d((h,b,C,L)=>{let w=c.find(B=>B.orientation===h&&Math.abs(B.coord-b)<1);return w||(w={id:`pipe-${h}-${b.toFixed(0)}`,orientation:h,coord:b,spanMin:C,spanMax:L,tracks:[]},c.push(w)),w.spanMin=Math.min(w.spanMin,C),w.spanMax=Math.max(w.spanMax,L),w},"getOrAddPipe"),I=d((h,b)=>{const C=h.width??10,L=h.height??10,w=h.x??0,B=h.y??0;switch(b){case"top":return{x:w,y:B-L/2};case"bottom":return{x:w,y:B+L/2};case"left":return{x:w-C/2,y:B};case"right":return{x:w+C/2,y:B}}},"portForSide"),u=d((h,b,C)=>I(h,eo(h,b,C?"bottom":"top")),"getOrthogonalPort"),p=[],f=[],y=new Set,v=1e3,M=d((h,b,C)=>{if(p.length===0)return 0;const L=Math.abs(b.y-C.y)<ct,w=Math.abs(b.x-C.x)<ct;if(!L&&!w)return 0;let B=0;if(L){const U=b.y,q=Math.min(b.x,C.x)-ct,z=Math.max(b.x,C.x)+ct;if(z<=q)return 0;for(const Y of p)Y.edgeIndex===h||Y.orientation!=="vertical"||Y.pipe.coord<q||Y.pipe.coord>z||Y.from-ct<=U&&Y.to+ct>=U&&(B+=v)}else if(w){const U=b.x,q=Math.min(b.y,C.y)-ct,z=Math.max(b.y,C.y)+ct;if(z<=q)return 0;for(const Y of p)Y.edgeIndex===h||Y.orientation!=="horizontal"||Y.pipe.coord<q||Y.pipe.coord>z||Y.from-ct<=U&&Y.to+ct>=U&&(B+=v)}return B},"crossingPenalty"),E=s.map((h,b)=>{if(!h.start||!h.end)return{idx:b,crossLane:0,dx:0,dy:0};const C=r.get(h.start),L=r.get(h.end),w=i.get(h.start),B=i.get(h.end),U=w&&B&&w.id!==B.id?1:0,q=C&&L?Math.abs((L.x??0)-(C.x??0)):0,z=C&&L?Math.abs((L.y??0)-(C.y??0)):0;return{idx:b,crossLane:U,dx:q,dy:z}}).sort((h,b)=>{if(h.crossLane!==b.crossLane)return b.crossLane-h.crossLane;const C=h.dx+h.dy,L=b.dx+b.dy;return Math.abs(C-L)>1?C-L:h.idx-b.idx}).map(h=>h.idx),T=d((h,b,C,L)=>{const w=Math.min(h.x,b.x),B=Math.max(h.x,b.x),U=Math.min(h.y,b.y),q=Math.max(h.y,b.y);return!!g.find(Y=>C&&Y.nodeId===C||L&&Y.nodeId===L?!1:Math.abs(h.x-b.x)>ct?Y.minY<h.y&&Y.maxY>h.y&&Y.maxX>w&&Y.minX<B:Y.minX<h.x&&Y.maxX>h.x&&Y.maxY>U&&Y.minY<q)},"isSegmentBlocked"),m=new Map,S=new Map;for(const h of s)!h.start||!h.end||h.start===h.end||(S.set(h.start,(S.get(h.start)??0)+1),S.set(h.end,(S.get(h.end)??0)+1));const A=d((h,b)=>eo(h,b,"bottom"),"determineSide"),R=new Map;for(const[h,b]of s.entries()){if(!b.start||!b.end||b.start===b.end||b.points&&b.points.length>0)continue;const C=r.get(b.start),L=r.get(b.end);if(!C||!L)continue;const w=(L.x??0)-(C.x??0),B=(L.y??0)-(C.y??0);R.set(h,{edgeIdx:h,srcId:b.start,dstId:b.end,srcSide:A(C,{x:L.x??0,y:L.y??0}),dstSide:A(L,{x:C.x??0,y:C.y??0}),absDx:Math.abs(w),absDy:Math.abs(B),dxSign:Math.sign(w),dySign:Math.sign(B)})}const k=d(h=>h.srcSide==="top"||h.srcSide==="bottom"?h.absDx===0?1/0:h.absDy/h.absDx:h.absDy===0?1/0:h.absDx/h.absDy,"preferenceStrength"),O=d(h=>h.srcSide==="top"||h.srcSide==="bottom"?h.dxSign>=0?"right":"left":h.dySign>=0?"bottom":"top","secondarySide"),_=new Map;for(const h of R.values()){const b=`${h.srcId}:${h.srcSide}`;_.has(b)||_.set(b,[]),_.get(b).push(h)}const H=new Map,P=d((h,b)=>`${h}:${b}`,"loadKey");for(const h of R.values())H.set(P(h.srcId,h.srcSide),(H.get(P(h.srcId,h.srcSide))??0)+1),H.set(P(h.dstId,h.dstSide),(H.get(P(h.dstId,h.dstSide))??0)+1);for(const h of _.values())if(!(h.length<2)){h.sort((b,C)=>{const L=k(b),w=k(C);return Math.abs(L-w)>1e-9?w-L:b.edgeIdx-C.edgeIdx});for(let b=1;b<h.length;b++){const C=h[b],L=O(C),w=H.get(P(C.srcId,C.srcSide))??0,B=H.get(P(C.srcId,L))??0;B>=w||(H.set(P(C.srcId,C.srcSide),w-1),H.set(P(C.srcId,L),B+1),C.srcSide=L)}}const G=d(h=>{const b=h?.shape;return b==="question"||b==="diamond"},"isDiamondNode"),j=new Map;for(const h of R.values())j.has(h.dstId)||j.set(h.dstId,new Set),j.get(h.dstId).add(h.dstSide);for(const h of R.values()){if(!G(r.get(h.srcId)))continue;const b=j.get(h.srcId);if(!b?.has(h.srcSide))continue;const C=O(h);if(b.has(C)||(H.get(P(h.srcId,C))??0)>0)continue;const L=H.get(P(h.srcId,h.srcSide))??0;H.set(P(h.srcId,h.srcSide),Math.max(0,L-1)),H.set(P(h.srcId,C),1),h.srcSide=C}for(const h of R.values()){const{edgeIdx:b,srcId:C,dstId:L,srcSide:w,dstSide:B}=h,U=r.get(C),q=r.get(L),z=`${C}:${w}:src`,Y=w==="top"||w==="bottom"?q.x??0:q.y??0;m.has(z)||m.set(z,[]),m.get(z).push({edgeIdx:b,oppositeCoord:Y});const ot=`${L}:${B}:dst`,rt=B==="top"||B==="bottom"?U.x??0:U.y??0;m.has(ot)||m.set(ot,[]),m.get(ot).push({edgeIdx:b,oppositeCoord:rt})}const J=new Map,dt=8;for(const[h,b]of m){if(b.length<2)continue;b.sort((Lt,Dt)=>Lt.oppositeCoord-Dt.oppositeCoord);const C=h.split(":"),L=C.slice(0,-2).join(":"),w=C[C.length-2],B=C[C.length-1],U=r.get(L);if(!U)continue;const z=w==="left"||w==="right"?U.height??10:U.width??10,Y=U.shape,rt=Y==="question"||Y==="diamond"?z*.3:z,tt=Math.min(20,Math.max(dt,rt/(b.length+1))),Rt=-(tt*(b.length-1))/2;for(const[Lt,Dt]of b.entries()){const Jt=Rt+Lt*tt,gn=`${Dt.edgeIdx}:${B}`;J.set(gn,Jt)}}const mt=d(h=>!!s[h]?.labelNodeId,"edgeHasLabelNode"),kt=d((h,b)=>h?(m.get(`${h}:${b}:src`)??[]).some(({edgeIdx:C})=>mt(C))||(m.get(`${h}:${b}:dst`)??[]).some(({edgeIdx:C})=>mt(C)):!1,"faceHasLabelNode"),Pt=d((h,b,C)=>b==="top"||b==="bottom"?{x:h.x+C,y:h.y}:{x:h.x,y:h.y+C},"applyPortOffset"),Q=d((h,b,C)=>{const L=R.get(h),w={x:C.x??0,y:C.y??0},B={x:b.x??0,y:b.y??0},U=L?.srcSide??A(b,w),q=L?.dstSide??A(C,B);let z=L?I(b,L.srcSide):u(b,w,!0),Y=L?I(C,L.dstSide):u(C,B,!1);const ot=J.get(`${h}:src`),rt=J.get(`${h}:dst`);return ot!==void 0&&(z=Pt(z,U,ot)),rt!==void 0&&(Y=Pt(Y,q,rt)),{pSrcPort:z,pDstPort:Y,srcSide:U,dstSide:q}},"portsForEdge");for(const h of E){const b=s[h];if(f[h]=[],!b.start||!b.end||b.points&&b.points.length>0||b.start===b.end)continue;const C=r.get(b.start),L=r.get(b.end);if(!C||!L)continue;const{pSrcPort:w,pDstPort:B,srcSide:U,dstSide:q}=Q(h,C,L),z={...w},Y={...B},ot=U==="top"||U==="bottom",rt=q==="top"||q==="bottom";if(ot){const X=w.y>(C.y??0);z.y=X?w.y+ne:w.y-ne}else{const X=w.x>(C.x??0);z.x=X?w.x+ne:w.x-ne}if(rt){const X=B.y>(L.y??0);Y.y=X?B.y+ne:B.y-ne}else{const X=B.x>(L.x??0);Y.x=X?B.x+ne:B.x-ne}const st=d((X,$)=>{for(const K of g)if(!$.includes(K.nodeId)&&X.x>K.minX&&X.x<K.maxX&&X.y>K.minY&&X.y<K.maxY)return{inside:!0,obstacle:K};return{inside:!1}},"isPointInObstacle"),tt=d((X,$,K,lt,Ct)=>{if(Ct){const Nt=X.y>($.y??0);return{x:(K.x??0)>=X.x?lt.maxX+be:lt.minX-be,y:Nt?lt.maxY+Te:lt.minY-Te,leavesPositiveSide:Nt}}const bt=X.x>($.x??0),Et=(K.y??0)>=X.y;return{x:bt?lt.maxX+be:lt.minX-be,y:Et?lt.maxY+Te:lt.minY-Te,leavesPositiveSide:bt}},"obstacleDetour");let yt=[];const Rt=[b.start,b.end],Lt=st(z,Rt);if(Lt.inside&&Lt.obstacle){const X=Lt.obstacle;if(ot){const $=tt(w,C,L,X,!0);z.x=$.x,z.y=$.y;const K=$.leavesPositiveSide?Math.min(X.minY-2,w.y+ne):Math.max(X.maxY+2,w.y-ne);yt=[{x:w.x,y:K},{x:$.x,y:K},{x:$.x,y:$.y}]}else{const $=tt(w,C,L,X,!1),K=$.leavesPositiveSide?Math.min(X.minX-2,w.x+ne):Math.max(X.maxX+2,w.x-ne);z.x=$.x,z.y=$.y,yt=[{x:K,y:w.y},{x:K,y:$.y},{x:$.x,y:$.y}]}}let Dt=[];const Jt=st(Y,Rt);if(Jt.inside&&Jt.obstacle){const X=Jt.obstacle;if(rt){const $=tt(B,L,C,X,!0);Y.x=$.x,Y.y=$.y,Dt=[{x:$.x,y:$.y},{x:B.x,y:$.y}]}else{const $=tt(B,L,C,X,!1);Y.x=$.x,Y.y=$.y,Dt=[{x:$.x,y:$.y},{x:$.x,y:B.y}]}}if(yt.length===0&&Dt.length===0){const X=be,$=Math.abs(z.x-Y.x)<X,K=Math.abs(z.y-Y.y)<X,lt=J.get(`${h}:src`)!==void 0||J.get(`${h}:dst`)!==void 0,Ct=(m.get(`${b.start??""}:${U}:src`)?.length??0)+(m.get(`${b.start??""}:${U}:dst`)?.length??0),bt=(m.get(`${b.end??""}:${q}:src`)?.length??0)+(m.get(`${b.end??""}:${q}:dst`)?.length??0),Et=Ct>1||bt>1,Nt=S.get(b.start??"")??0,ut=S.get(b.end??"")??0,Yt=Ct>1&&kt(b.start,U)||bt>1&&kt(b.end,q),ee=Ct<=1||Nt<=2,Bt=bt<=1||ut<=2;if(($||K)&&!lt&&(!Et||Et&&!Yt&&ee&&Bt)&&!T(w,B,b.start,b.end)){b.points=[{...w},{...z},{...Y},{...B}],y.add(h);const Mt=K?"horizontal":"vertical",$t=K?w.y:w.x,It=K?Math.min(w.x,B.x):Math.min(w.y,B.y),St=K?Math.max(w.x,B.x):Math.max(w.y,B.y),Wt={id:`fast-path-${Mt}-${$t.toFixed(0)}-${h}`,orientation:Mt,coord:$t,spanMin:It,spanMax:St,tracks:[]};p.push({edgeIndex:h,segmentIndex:0,orientation:Mt,pipe:Wt,trackIndex:0,from:It,to:St});continue}}const gn=x("vertical",z.x,z.y,z.y);z.x=gn.coord;const mr=x("vertical",Y.x,Y.y,Y.y);Y.x=mr.coord;let ue=Math.min(z.x,Y.x)-50,he=Math.max(z.x,Y.x)+50,ve=Math.min(z.y,Y.y)-50,Le=Math.max(z.y,Y.y)+50;for(const X of g){const $=Math.min(z.x,Y.x),K=Math.max(z.x,Y.x),lt=Math.min(z.y,Y.y),Ct=Math.max(z.y,Y.y);X.minX<K&&X.maxX>$&&X.minY<Ct&&X.maxY>lt&&(ue=Math.min(ue,X.minX-je),he=Math.max(he,X.maxX+je),ve=Math.min(ve,X.minY-je),Le=Math.max(Le,X.maxY+je))}for(const X of g){if(X.maxX<ue||X.minX>he||X.maxY<ve||X.minY>Le)continue;const $=be;x("horizontal",X.minY-$,ue,he),x("horizontal",X.maxY+$,ue,he);const K=Te;x("vertical",X.minX-K,ve,Le),x("vertical",X.maxX+K,ve,Le)}x("horizontal",z.y,ue,he),x("horizontal",Y.y,ue,he);const yr=c.filter(X=>X.orientation==="horizontal"&&X.coord>=ve&&X.coord<=Le),xr=c.filter(X=>X.orientation==="vertical"&&X.coord>=ue&&X.coord<=he),ke=d((X,$)=>`${X.toFixed(1)},${$.toFixed(1)}`,"getKey"),_e=ke(z.x,z.y),vo=ke(Y.x,Y.y),Fe=new Map,pn=new Map,mn=new Map,De=new Set,xe=[];Fe.set(_e,0),mn.set(_e,"n"),xe.push({key:_e,f:Math.hypot(Y.x-z.x,Y.y-z.y),pt:z}),De.add(_e);let Ht=[];const ge=d((X,$)=>T(X,$,b.start,b.end),"checkSegmentBlocked"),yn={x:Y.x,y:z.y},br=ge(z,yn),Mr=ge(yn,Y),Ir=br||Mr,xn={x:z.x,y:Y.y},Sr=ge(z,xn),Cr=ge(xn,Y);if(Ir?Sr||Cr||(Math.abs(z.x-Y.x)<ct?Ht=[z,Y]:Ht=[z,xn,Y]):Math.abs(z.y-Y.y)<ct||Math.abs(z.x-Y.x)<ct?Ht=[z,Y]:Ht=[z,yn,Y],Ht.length===0)for(;xe.length>0;){xe.sort((ut,Yt)=>ut.f-Yt.f);const X=xe.shift();if(De.delete(X.key),X.key===vo){let ut=vo,Yt=Y;for(Ht=[Yt];pn.has(ut);){const ee=pn.get(ut);Ht.unshift(ee),Yt=ee,ut=ke(ee.x,ee.y)}break}const $=X.pt.x,K=X.pt.y,lt=xr.sort((ut,Yt)=>ut.coord-Yt.coord),Ct=lt.findIndex(ut=>Math.abs(ut.coord-$)<1),bt=yr.sort((ut,Yt)=>ut.coord-Yt.coord),Et=bt.findIndex(ut=>Math.abs(ut.coord-K)<1),Nt=[];Ct>0&&Nt.push({x:lt[Ct-1].coord,y:K}),Ct>=0&&Ct<lt.length-1&&Nt.push({x:lt[Ct+1].coord,y:K}),Et>0&&Nt.push({x:$,y:bt[Et-1].coord}),Et>=0&&Et<bt.length-1&&Nt.push({x:$,y:bt[Et+1].coord});for(const ut of Nt){const Yt=Math.min($,ut.x),ee=Math.max($,ut.x),Bt=Math.min(K,ut.y),Gt=Math.max(K,ut.y);if(g.some(Zt=>Zt.nodeId===b.start||Zt.nodeId===b.end?!1:Yt!==ee?Zt.minY<K&&Zt.maxY>K&&Zt.maxX>Yt&&Zt.minX<ee:Zt.minX<$&&Zt.maxX>$&&Zt.maxY>Bt&&Zt.minY<Gt))continue;const Mt=ke(ut.x,ut.y),$t=Math.abs(ut.x-$)+Math.abs(ut.y-K),It=M(h,X.pt,ut);let St=0;const Wt=Y.x-z.x,Ee=Y.y-z.y,He=ut.x-$,bn=ut.y-K;(Ee>10&&bn<-5||Ee<-10&&bn>5)&&(St=Math.abs(bn)*100),(Wt>10&&He<-5||Wt<-10&&He>5)&&(St+=Math.abs(He)*50);let Lo=0;const Eo=mn.get(X.key)??"n",To=Math.abs(He)>ct?"h":"v";Eo!=="n"&&Eo!==To&&(Lo=50);const vr=$t+It+St+Lo,Xe=(Fe.get(X.key)??1/0)+vr,wo=Math.abs(Y.x-ut.x)+Math.abs(Y.y-ut.y);if(Xe<(Fe.get(Mt)??1/0))if(pn.set(Mt,X.pt),Fe.set(Mt,Xe),mn.set(Mt,To),!De.has(Mt))xe.push({key:Mt,f:Xe+wo,pt:ut}),De.add(Mt);else{const Zt=xe.findIndex(Lr=>Lr.key===Mt);Zt!==-1&&(xe[Zt].f=Xe+wo)}}}if(Ht.length===0&&(Ht=[z,{x:z.x,y:Y.y},Y]),Ht.length>4){const X=Ht[0],$=Ht[Ht.length-1];let K=Math.min(X.x,$.x),lt=Math.max(X.x,$.x),Ct=Math.min(X.y,$.y),bt=Math.max(X.y,$.y);for(const Bt of Ht)K=Math.min(K,Bt.x),lt=Math.max(lt,Bt.x),Ct=Math.min(Ct,Bt.y),bt=Math.max(bt,Bt.y);const Et=lt>Math.max(X.x,$.x),Nt=K<Math.min(X.x,$.x);if(a){const Bt=Te;if(Et){const Gt=Math.max(X.x,$.x),Ot=Math.min(X.y,$.y),Mt=Math.max(X.y,$.y),$t=g.filter(It=>It.minX<Gt&&It.maxX>Gt&&It.minY<Mt&&It.maxY>Ot);if($t.length>0){let It=Math.max(X.x,$.x);for(const St of $t){const Wt=(St.minX+St.maxX)/2;if(St.visualXHalfExtent===void 0||isNaN(St.visualXHalfExtent))continue;const Ee=Wt+St.visualXHalfExtent+Bt;It=Math.max(It,Ee)}isNaN(It)||(lt=It)}}if(Nt){const Gt=g.filter(Ot=>Ot.minX<Math.min(X.x,$.x)+Bt&&Ot.minY<Math.max(X.y,$.y)&&Ot.maxY>Math.min(X.y,$.y));if(Gt.length>0){let Ot=Math.min(X.x,$.x);for(const Mt of Gt){const It=(Mt.minX+Mt.maxX)/2-Mt.visualXHalfExtent-Bt;Ot=Math.min(Ot,It)}K=Ot}}}const ut=d(Bt=>{const Gt=$.y>X.y,Ot=g.filter(It=>{const St=Math.min(X.x,$.x)<It.maxX&&Math.max(X.x,$.x)>It.minX,Wt=Math.min(X.y,$.y)<It.maxY&&Math.max(X.y,$.y)>It.minY;return St&&Wt});let Mt=Ot;if(a&&Ot.length>0){const It=Ot.filter(St=>St.minX<Bt&&St.maxX>Bt);It.length>0&&(Mt=It)}if(Mt.length===0)return $.y;const $t=be;if(Gt){const St=Math.max(...Mt.map(Wt=>Wt.maxY))+$t;if(St<$.y-ct)return St}else{const St=Math.min(...Mt.map(Wt=>Wt.minY))-$t;if(St>$.y+ct)return St}return $.y},"findBestReturnY"),Yt=d(Bt=>{const Gt=ut(Bt),Ot={x:Bt,y:X.y},Mt={x:Bt,y:Gt},$t={x:$.x,y:Gt},It=ge(X,Ot),St=ge(Ot,Mt),Wt=ge(Mt,$t),Ee=Gt!==$.y?ge($t,$):!1;return!It&&!St&&!Wt&&!Ee?Math.abs(Gt-$.y)<ct?[X,Ot,Mt,$]:[X,Ot,Mt,$t,$]:null},"trySimplifyWithDetourX"),ee=Et&&!Nt?Yt(lt):Nt&&!Et?Yt(K):null;ee&&(Ht=ee)}const Xt=[w,...yt,...Ht,...Dt.reverse(),B];if(Xt.length>=3){const X=Xt[Xt.length-1],$=Xt[Xt.length-2],K=Xt[Xt.length-3],lt=Math.abs(K.y-$.y)<ct&&Math.abs($.y-X.y)<ct,Ct=Math.abs(K.x-$.x)<ct&&Math.abs($.x-X.x)<ct;if(lt){const bt=Math.sign($.x-K.x),Et=Math.sign(X.x-K.x);bt!==0&&bt===Et&&Math.abs($.x-K.x)>Math.abs(X.x-K.x)&&Xt.splice(-2,1)}else if(Ct){const bt=Math.sign($.y-K.y),Et=Math.sign(X.y-K.y);bt!==0&&bt===Et&&Math.abs($.y-K.y)>Math.abs(X.y-K.y)&&Xt.splice(-2,1)}}const ie=[Xt[0]];for(let X=1;X<Xt.length-1;X++){if(X===1){ie.push(Xt[X]);continue}const $=ie[ie.length-1],K=Xt[X],lt=Xt[X+1];if(Math.abs($.y-K.y)<ct&&Math.abs(K.y-lt.y)<ct){const Ct=K.x>$.x,bt=lt.x>K.x;if(Ct!==bt){ie.push(K);continue}continue}if(Math.abs($.x-K.x)<ct&&Math.abs(K.x-lt.x)<ct){const Ct=K.y>$.y,bt=lt.y>K.y;if(Ct!==bt){ie.push(K);continue}continue}ie.push(K)}ie.push(Xt[Xt.length-1]);for(let X=0;X<ie.length-1;X++){const $=ie[X],K=ie[X+1],lt=Math.abs($.x-K.x)<ct?"vertical":"horizontal",Ct=lt==="vertical"?$.x:$.y,bt=lt==="vertical"?Math.min($.y,K.y):Math.min($.x,K.x),Et=lt==="vertical"?Math.max($.y,K.y):Math.max($.x,K.x),Nt=x(lt,Ct,bt,Et),ut={edgeIndex:h,segmentIndex:X,orientation:lt,pipe:Nt,trackIndex:0,from:bt,to:Et};p.push(ut),f[h].push(p.length-1),Nt.tracks[0]||(Nt.tracks[0]={index:0,coord:Nt.coord,segments:[]}),Nt.tracks[0].segments.push({edgeIndex:h,segmentIndex:X,from:bt,to:Et})}}const W=d((h,b)=>h.from<b.to&&b.from<h.to,"segmentsOverlap"),et=d((h,b,C,L)=>{const w=!L.segments.some(U=>(U.edgeIndex!==b.edgeIndex||U.segmentIndex!==b.segmentIndex)&&W(U,h)),B=!C.segments.some(U=>(U.edgeIndex!==h.edgeIndex||U.segmentIndex!==h.segmentIndex)&&W(U,b));return w&&B?(h.trackIndex=L.index,b.trackIndex=C.index,C.segments=[...C.segments.filter(U=>U.edgeIndex!==h.edgeIndex||U.segmentIndex!==h.segmentIndex),{edgeIndex:b.edgeIndex,segmentIndex:b.segmentIndex,from:b.from,to:b.to}],L.segments=[...L.segments.filter(U=>U.edgeIndex!==b.edgeIndex||U.segmentIndex!==b.segmentIndex),{edgeIndex:h.edgeIndex,segmentIndex:h.segmentIndex,from:h.from,to:h.to}],!0):!1},"trySwapSegmentsAcrossTracks"),at=d(h=>{const b=h.tracks.length;return h.tracks[b]={index:b,coord:h.coord,segments:[]},b},"createNewTrack"),gt=d((h,b)=>{const C=h.pipe.tracks[h.trackIndex];C.segments=C.segments.filter(w=>w.edgeIndex!==h.edgeIndex||w.segmentIndex!==h.segmentIndex),h.trackIndex=b,h.pipe.tracks[b].segments.push({edgeIndex:h.edgeIndex,segmentIndex:h.segmentIndex,from:h.from,to:h.to})},"moveSegmentToTrack"),xt=d((h,b)=>{const C=f[h.edgeIndex];for(const L of C){const w=p[L];w.pipe===h.pipe&>(w,b)}},"moveSegmentChainToTrack"),vt=d(h=>{const b=f[h.edgeIndex],C=b.indexOf(p.indexOf(h)),L=[];return C>0&&L.push(p[b[C-1]]),C<b.length-1&&L.push(p[b[C+1]]),L},"getAdjacentSegmentsAlongEdge"),Vt=d((h,b)=>{if(h.orientation===b.orientation)return!1;const C=h.orientation==="horizontal"?h:b,L=h.orientation==="horizontal"?b:h;return L.pipe.coord>C.from&&L.pipe.coord<C.to&&C.pipe.coord>L.from&&C.pipe.coord<L.to},"haveAnyCrossing"),jt=d((h,b)=>{for(const C of h.tracks)if(!C.segments.some(w=>(w.edgeIndex!==b.edgeIndex||w.segmentIndex!==b.segmentIndex)&&W(w,b)))return C.index;return-1},"findAvailableTrack"),Ut=d((h,b)=>{if(h.trackIndex===b.trackIndex)return W(h,b);const C=vt(h),L=vt(b);return C.some(w=>L.some(B=>Vt(w,B)))},"segmentsConflict"),te=d((h,b,C)=>{if(et(h,b,h.pipe.tracks[h.trackIndex],b.pipe.tracks[b.trackIndex]))return;const L=jt(h.pipe,b);C(b,L!==-1?L:at(h.pipe))},"resolveTrackConflict"),Se=d(h=>{let b=0;for(let C=0;C<h.length;C++)for(let L=C+1;L<h.length;L++){const w=h[C],B=h[L];w.pipe===B.pipe&&Ut(w,B)&&(b++,te(w,B,xt))}return b},"resolveHandleConflicts"),de=new Map,Ce=d(h=>{if(de.has(h))return de.get(h);const b=f[h];if(b.length===0){const q={dest:0,deviation:0,base:0,delta:0};return de.set(h,q),q}const L=p[b[0]].pipe.coord;let w=L;for(let q=1;q<b.length;q++){const z=p[b[q]];if(z.orientation==="horizontal"){const Y=z.from,ot=z.to;w=Math.abs(Y-L)>Math.abs(ot-L)?Y:ot;break}}const B=Math.abs(w-L),U={dest:w,deviation:B,base:L,delta:w-L};return de.set(h,U),U},"getDestInfo"),dn=d(()=>{let h=0;const b=new Map;for(const[L,w]of s.entries())f[L].length!==0&&w.start&&(b.has(w.start)||b.set(w.start,[]),b.get(w.start).push(L));const C=d(L=>{const w=s[L];if(!w.start||!w.end)return 0;const B=r.get(w.start),U=r.get(w.end);if(!B||!U)return 0;const q=(U.x??0)-(B.x??0),z=(U.y??0)-(B.y??0);return Math.abs(q)+Math.abs(z)},"getEdgeDistance");for(const L of b.values()){L.sort((B,U)=>{const q=Ce(B),z=Ce(U);if(Math.abs(q.deviation-z.deviation)>1)return q.deviation-z.deviation;if(Math.abs(q.dest-z.dest)>1)return q.dest-z.dest;const Y=C(B),ot=C(U);if(Math.abs(Y-ot)>1)return ot-Y;const rt=f[B].length,st=f[U].length;if(rt!==st)return rt-st;if(rt===1){const tt=f[B][0],yt=f[U][0];if(p[tt]&&p[yt]){const Rt=p[tt],Lt=p[yt],Dt=Math.abs(Rt.to-Rt.from),Jt=Math.abs(Lt.to-Lt.from);if(Math.abs(Dt-Jt)>1)return Dt-Jt}}return 0});const w=L.map(B=>p[f[B][0]]);h+=Se(w)}return h},"fixSourceHandleCrossings"),un=d(()=>{let h=0;const b=new Map;for(const[C,L]of s.entries())f[C].length!==0&&L.end&&(b.has(L.end)||b.set(L.end,[]),b.get(L.end).push(C));for(const C of b.values()){C.sort((w,B)=>{const U=d(Y=>{const ot=f[Y];if(ot.length<2)return 0;const rt=p[ot[ot.length-2]];return Math.abs(rt.to-rt.from)},"getDist"),q=U(w),z=U(B);return Math.abs(q-z)>.1?q-z:w-B});const L=C.map(w=>p[f[w][f[w].length-1]]);h+=Se(L)}return h},"fixTargetHandleCrossings"),hn=d(()=>{let h=0;for(const b of c){const C=[];for(const L of b.tracks)for(const w of L.segments){const B=f[w.edgeIndex].find(U=>p[U].segmentIndex===w.segmentIndex);B!==void 0&&C.push(p[B])}C.sort((L,w)=>L.edgeIndex-w.edgeIndex||L.segmentIndex-w.segmentIndex);for(let L=0;L<C.length;L++)for(let w=L+1;w<C.length;w++){const B=C[L],U=C[w];Ut(B,U)&&(h++,te(B,U,gt))}}return h},"fixPipeCrossings");let N=0;const F=10;for(;N<F;){let h=0;if(h+=dn(),h+=un(),h+=hn(),h===0)break;N++}const D=new Map;for(const h of c){const b=[];h.tracks.forEach(L=>{L.segments.forEach(w=>{b.push({edgeIndex:w.edgeIndex,segmentIndex:w.segmentIndex,trackIndex:L.index,from:w.from,to:w.to})})}),b.sort((L,w)=>L.from-w.from);const C=[];if(b.length>0){let L=[b[0]],w=b[0].to;for(let B=1;B<b.length;B++){const U=b[B];U.from<w?(L.push(U),w=Math.max(w,U.to)):(C.push(L),L=[U],w=U.to)}C.push(L)}for(const L of C){const w=new Set;L.forEach(tt=>w.add(tt.trackIndex));const B=new Map;L.forEach(tt=>{const yt=Ce(tt.edgeIndex);B.set(tt.trackIndex,(B.get(tt.trackIndex)??0)+yt.delta)});const U=[...w].filter(tt=>(B.get(tt)??0)<-1),q=[...w].filter(tt=>(B.get(tt)??0)>1),z=[...w].filter(tt=>Math.abs(B.get(tt)??0)<=1);U.sort((tt,yt)=>(B.get(yt)??0)-(B.get(tt)??0)),q.sort((tt,yt)=>(B.get(tt)??0)-(B.get(yt)??0));const Y=d((tt,yt)=>{L.filter(Rt=>Rt.trackIndex===tt).forEach(Rt=>{const Lt=y.has(Rt.edgeIndex)?h.coord:yt;D.set(`${Rt.edgeIndex}-${Rt.segmentIndex}`,Lt)})},"assignCoord");let ot=0;for(const tt of U)ot++,Y(tt,h.coord-ot*Cn);if(z.length===0&&w.size>0){const tt=[...w].sort((Lt,Dt)=>Math.abs(B.get(Lt)??0)-Math.abs(B.get(Dt)??0))[0],yt=U.indexOf(tt);yt!==-1&&U.splice(yt,1);const Rt=q.indexOf(tt);Rt!==-1&&q.splice(Rt,1),z.push(tt)}let rt=0;for(const tt of z){if(rt===0)Y(tt,h.coord);else{const yt=rt%2===1?1:-1,Rt=Math.ceil(rt/2);Y(tt,h.coord+yt*Rt*Cn*.5)}rt++}let st=0;for(const tt of q)st++,Y(tt,h.coord+st*Cn)}}for(const[h,b]of s.entries()){const C=f[h]??[];if(C.length===0)continue;const L=[],w=r.get(b.start),B=r.get(b.end),{pSrcPort:U,pDstPort:q}=Q(h,w,B),z=C.map(rt=>{const st=p[rt],tt=D.get(`${st.edgeIndex}-${st.segmentIndex}`)??st.pipe.coord;return{orient:st.orientation,coord:tt,from:st.from,to:st.to}});L.push(U);for(let rt=0;rt<z.length;rt++){const st=z[rt],tt=L[L.length-1],yt=st.orient==="vertical"?tt.y:tt.x,Rt=st.orient==="vertical"?tt.x:tt.y,Lt=z[rt+1],Dt=rt<z.length-1;if(Math.abs(Rt-st.coord)>ct&&L.push(Me(st,yt)),Dt&&Lt.orient===st.orient)if(Math.abs(st.coord-Lt.coord)>ct){const Jt=st.orient==="vertical"?(yt+Lt.from)/2:no(st,Lt);L.push(Me(st,Jt),Me(Lt,Jt))}else(rt===0||rt===z.length-2)&&L.push(Me(st,no(st,Lt)));else if(Dt)L.push(Me(st,Lt.coord));else{const Jt=Math.abs(st.from-yt)<Math.abs(st.to-yt)?st.to:st.from;L.push(Me(st,Jt))}}const Y=L[L.length-1];(Math.abs(Y.x-q.x)>ct||Math.abs(Y.y-q.y)>ct)&&L.push(q);const ot=[];L.length>0&&ot.push(L[0]);for(let rt=1;rt<L.length;rt++){const st=L[rt],tt=ot[ot.length-1];(Math.abs(st.x-tt.x)>ct||Math.abs(st.y-tt.y)>ct)&&ot.push(st)}b.points=ot}for(const h of s){const b=h.__originalEdge;b&&h.points&&(b.points=h.points)}t.edges=(t.edges??[]).filter(h=>!h.isLayoutOnly);const V=d((h,b)=>{const C=b.x??0,L=b.y??0,w=b.width??0,B=b.height??0;if(w<=0||B<=0)return h;const U=C-w/2,q=C+w/2,z=L-B/2,Y=L+B/2;if(h.x<U||h.x>q||h.y<z||h.y>Y)return h;const ot=h.x-U,rt=q-h.x,st=h.y-z,tt=Y-h.y,yt=Math.min(ot,rt,st,tt);return yt===ot?{x:U,y:h.y}:yt===rt?{x:q,y:h.y}:yt===st?{x:h.x,y:z}:{x:h.x,y:Y}},"nodeBoundaryClamp");for(const h of t.edges){const b=h.points;if(!b||b.length<2)continue;const C=h.start,L=h.end,w=C?r.get(C):void 0,B=L?r.get(L):void 0;w&&(b[0]=V(b[0],w)),B&&(b[b.length-1]=V(b[b.length-1],B))}return t}d(hr,"routeEdgesOrthogonal");function gr(t){return t.direction??"TB"}d(gr,"getSwimlaneDirection");function pr(t){const e=Jo(t),n=t.config.flowchart?.nodeSpacing??40,o=t.config.flowchart?.rankSpacing??100,s=t.config.swimlane?.ignoreCrossLaneEdges??!0,r=t.config.swimlane?.optimizeRanksByCrossings??!0,i=t.config.swimlane?.automaticLaneOrdering??!1,c=gr(t),{ordered:a,coordinates:l}=ur(e,{nodeGap:n,layerGap:o,ignoreCrossLaneEdges:s,optimizeRanksByCrossings:r,automaticLaneOrdering:i,direction:c});Zo(e,a,l,{nodeGap:n,layerGap:o});for(const g of t.edges??[])delete g.points;hr(t,c);for(const g of t.edges??[])(!g.curve||g.curve==="basis")&&(g.curve="rounded");return Rs(t,c),As(t),c}d(pr,"runSwimlaneLayoutCore");async function Qr(t,e){const n=e.select("g");wr(n,t.markers,t.type,t.diagramId),Ar(),Rr(),Nr(),Tr(),qo(t);const o=Qo(t);t.nodes=o.nodes,t.edges=o.edges;const{groups:s}=await _o(n,t);pr(t),await Uo(t,s)}d(Qr,"render");export{Qr as render}; +const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/sizeCapture-X5ZJPWSS-D5GqjpM0.js","assets/mermaid.core-CJB1tAev.js","assets/index-D-7nOosq.js","assets/index-DGHD7Bg9.css","assets/_commonjsHelpers-CqkleIqs.js"])))=>i.map(i=>d[i]); +import{bR as Er}from"./index-D-7nOosq.js";import{c as Tr}from"./chunk-RYQCIY6F-Df2V79id.js";import{am as wr,an as Ar,ao as Rr,ap as Nr,l as Ke,c as Or,ag as Pr,af as Br,ah as kr,at as _r,av as Fr,z as Dr,as as Hr,aw as Xr,y as Oe,ax as Ye,_ as d,ay as Ao}from"./mermaid.core-CJB1tAev.js";import{G as Yr}from"./graph-DOmOIIwC.js";import"./map-DxJ2ADlA.js";import"./_commonjsHelpers-CqkleIqs.js";async function _o(t,e){const n=new Yr({multigraph:!0,compound:!0}),o=[...e.edges],s=Or(),r=t.insert("g").attr("class","root"),i=r.insert("g").attr("class","clusters"),c=r.insert("g").attr("class","edges edgePath"),a=r.insert("g").attr("class","edgeLabels"),l=r.insert("g").attr("class","nodes"),g=new Map,x=t.node()!=null;await Promise.all(e.nodes.map(async I=>{if(I.isGroup)n.setNode(I.id,{...I});else{if(x){const u=await Pr(l,I,{config:s,dir:I.dir}),p=u.node()?.getBBox()??{width:0,height:0};g.set(I.id,u),I.width=p.width,I.height=p.height}n.setNode(I.id,{...I})}}));for(const I of o)n.setEdge(I.start,I.end,{...I},I.id),e.edges.some(p=>p.id===I.id)||e.edges.push(I);if(globalThis.mermaidCaptureSizes){const{captureNodeSizes:I}=await Er(async()=>{const{captureNodeSizes:u}=await import("./sizeCapture-X5ZJPWSS-D5GqjpM0.js");return{captureNodeSizes:u}},__vite__mapDeps([0,1,2,3,4]));I(t,e)}return{graph:n,groups:{clusters:i,edgePaths:c,edgeLabels:a,nodes:l,rootGroups:r},nodeElements:g}}d(_o,"createGraphWithElements");var Ro=5,Ge=1e-5,$e=1e-6;function qe(t){const e=[];for(let n=0;n<t.length-1;n++)e.push({a:t[n],b:t[n+1]});return e}d(qe,"buildSegmentList");function Fo(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=o.x-n.x,c=o.y-n.y,a=s*c-r*i;if(a===0)return null;const l=n.x-t.x,g=n.y-t.y,x=(l*c-g*i)/a,I=(l*r-g*s)/a;return x<=$e||x>=1-$e||I<=$e||I>=1-$e?null:{point:{x:t.x+x*s,y:t.y+x*r},tA:x,tB:I}}d(Fo,"segmentIntersection");function vn(t){return Math.abs(t.b.x-t.a.x)>=Math.abs(t.b.y-t.a.y)}d(vn,"isHorizontalSeg");function Do(t){const e=[];for(let n=0;n<t.length;n++){const o=t[n],s=qe(o.points);for(let r=n+1;r<t.length;r++){const i=t[r],c=qe(i.points);for(const[a,l]of s.entries())for(const[g,x]of c.entries()){const I=Fo(l.a,l.b,x.a,x.b);if(!I)continue;const u=vn(l),p=vn(x);(u!==p?u:!1)?e.push({jumpEdgeId:o.id,otherEdgeId:i.id,segIndex:a,t:I.tA,point:I.point}):e.push({jumpEdgeId:i.id,otherEdgeId:o.id,segIndex:g,t:I.tB,point:I.point})}}}return e}d(Do,"findEdgeIntersections");function re(t){const e=Math.round(t*1e3)/1e3;return Number.isInteger(e)?`${e}`:`${e}`}d(re,"fmt");function we(t){return`${re(t.x)},${re(t.y)}`}d(we,"pointToString");function Ho(t){const e=t.b.x-t.a.x,n=t.b.y-t.a.y;return Math.abs(e)>=Math.abs(n)?e>=0?1:0:n>=0?1:0}d(Ho,"getArcSweepFlag");var Gr=.001;function Xo(t,e){if(t.length<2)return t.map(r=>({...r}));const n=t.map(r=>({...r})),o=e.arrowTypeStart&&Ao[e.arrowTypeStart];if(o){const r=t[0],i=t[1],c=Math.atan2(i.y-r.y,i.x-r.x);n[0].x=r.x+o*Math.cos(c),n[0].y=r.y+o*Math.sin(c)}const s=e.arrowTypeEnd&&Ao[e.arrowTypeEnd];if(s){const r=t.length,i=t[r-2],c=t[r-1],a=Math.atan2(c.y-i.y,c.x-i.x);n[r-1].x=c.x-s*Math.cos(a),n[r-1].y=c.y-s*Math.sin(a)}return n}d(Xo,"applyMarkerOffsets");function Yo(t,e,n,o,s){const r=t.point.x,i=t.point.y,c={x:r-e*t.r,y:i-n*t.r},a={x:r+e*t.r,y:i+n*t.r},l=[`L${we(c)}`];return s==="arc"?l.push(`A${re(t.r)},${re(t.r)} 0 0 ${o} ${we(a)}`):l.push(`M${we(a)}`),l}d(Yo,"emitJump");function Ln(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=n.x-e.x,c=n.y-e.y,a=Math.hypot(s,r),l=Math.hypot(i,c);if(a<Ge||l<Ge)return null;const g=s/a,x=r/a,I=i/l,u=c/l,p=g*I+x*u,f=Math.max(-1,Math.min(1,p)),y=Math.acos(f);if(y<Ge||Math.abs(Math.PI-y)<Ge)return null;const v=Math.min(o/Math.sin(y/2),a/2,l/2);return{startX:e.x-g*v,startY:e.y-x*v,endX:e.x+I*v,endY:e.y+u*v,ctrlX:e.x,ctrlY:e.y,cutLen:v}}d(Ln,"computeRoundedCorner");function Go(t,e,n){const o=t.points;if(o.length<2)return"";const s=Xo(o,t),r=t.curve==="rounded",i=qe(s),c=new Map;for(const l of e){const g=i[l.segIndex];if(!g)continue;const x=Math.hypot(g.b.x-g.a.x,g.b.y-g.a.y),I=c.get(l.segIndex)??[];I.push({t:l.t,point:l.point,d:l.t*x,r:n.jumpRadius}),c.set(l.segIndex,I)}const a=[`M${we(s[0])}`];for(let l=0;l<i.length;l++){const g=i[l],x=Math.hypot(g.b.x-g.a.x,g.b.y-g.a.y),I=x===0?0:(g.b.x-g.a.x)/x,u=x===0?0:(g.b.y-g.a.y)/x,p=Ho(g);let f=0;if(r&&l>0){const E=Ln(s[l-1],s[l],s[l+1]??s[l],Ro);E&&(f=E.cutLen)}let y=x,v=null;r&&l<i.length-1&&(v=Ln(s[l],s[l+1],s[l+2]??s[l+1],Ro),v&&(y=x-v.cutLen));const M=[...c.get(l)??[]].sort((E,T)=>E.t-T.t);for(const E of M)E.r=Math.min(E.r,E.d-f,y-E.d);for(let E=0;E<M.length-1;E++){const T=M[E+1].d-M[E].d;if(M[E].r+M[E+1].r>T){const m=T/2;M[E].r=Math.min(M[E].r,m),M[E+1].r=Math.min(M[E+1].r,m)}}for(const E of M)E.r<Gr||a.push(...Yo(E,I,u,p,n.jumpStyle));r&&v?(a.push(`L${re(v.startX)},${re(v.startY)}`),a.push(`Q${re(v.ctrlX)},${re(v.ctrlY)} ${re(v.endX)},${re(v.endY)}`)):a.push(`L${we(g.b)}`)}return a.join(" ")}d(Go,"rewriteEdgePath");function $o(t){return/^[\d\s+,.LMelm-]*$/.test(t)}d($o,"isStraightPath");function zo(t){return t?t==="linear"||t==="rounded"||t==="step"||t==="stepBefore"||t==="stepAfter":!0}d(zo,"curveSupportsLineHops");function Vo(t){if(!t)return null;try{const e=typeof atob=="function"?atob(t):Buffer.from(t,"base64").toString(),n=JSON.parse(e);if(!Array.isArray(n))return null;const o=[];for(const s of n)s&&typeof s.x=="number"&&typeof s.y=="number"&&o.push({x:s.x,y:s.y});return o.length>=2?o:null}catch{return null}}d(Vo,"decodeDataPoints");function jo(t,e,n){if(!n.enabled)return;const o=t.node();if(!o)return;const s=new Map;for(const l of e)s.set(l.id,l);const r=[],i=new Map;for(const l of e){const g=typeof CSS<"u"&&CSS.escape?CSS.escape(l.id):l.id,x=o.querySelector(`path[data-id="${g}"]`);if(!x)continue;i.set(l.id,x);const u=Vo(x.getAttribute("data-points"))??l.points;r.push({...l,points:u})}const c=Do(r);if(c.length===0)return;const a=new Map;for(const l of c){const g=a.get(l.jumpEdgeId)??[];g.push(l),a.set(l.jumpEdgeId,g)}for(const l of r){const g=a.get(l.id);if(!g||g.length===0)continue;const I=s.get(l.id)?.curve;if(I!==void 0&&!zo(I))continue;const u=i.get(l.id);if(!u)continue;if(I===void 0){const E=u.getAttribute("d")??"";if(!$o(E))continue}const p=u.getAttribute("style")??"",f=/stroke-dasharray\s*:\s*0\s+([\d.]+)\s+[\d.]+\s+([\d.]+)/.exec(p),y=f?Number.parseFloat(f[1]):null,v=f?Number.parseFloat(f[2]):null,M=Go(l,g,n);if(u.setAttribute("d",M),y!==null&&v!==null&&typeof u.getTotalLength=="function"){const E=u.getTotalLength(),T=Math.max(0,E-y-v),m=`0 ${y} ${T} ${v}`,S=p.replace(/stroke-dasharray\s*:[^;]*;?/g,`stroke-dasharray: ${m};`).replace(/;\s*;+/g,";");u.setAttribute("style",S)}}}d(jo,"applyLineJumpsToSvg");async function Uo(t,e){for(const s of t.nodes)s.isGroup?await Br(e.clusters,s):kr(s);const n=new Map;for(const s of t.nodes)s?.id&&n.set(s.id,s);for(const s of t.edges){const r=s.start?n.get(s.start)??{}:{},i=s.end?n.get(s.end)??{}:{},c=_r(e.edgePaths,{...s},{},t.type,r,i,t.diagramId);s.label&&await Fr(e.rootGroups,s),s.label&&Wo(s,c)}const o=t.config?.swimlane?.lineHops;if(o!==!1){const s=o==="gap"?"gap":"arc",r=t.edges.filter(i=>Array.isArray(i.points)&&i.points.length>=2).map(i=>({id:i.id,points:i.points,curve:i.curve,arrowTypeStart:i.arrowTypeStart,arrowTypeEnd:i.arrowTypeEnd}));jo(e.edgePaths,r,{enabled:!0,jumpRadius:6,jumpStyle:s})}}d(Uo,"adjustLayout");function Wo(t,e){const n=e?.updatedPath??e?.originalPath,o=Dr(),{subGraphTitleTotalMargin:s}=Hr({flowchart:o.flowchart??{}});if(t.label){const r=Xr.get(t.id);let i=t.x,c=t.y;if(n){const a=Oe.calcLabelPosition(n);Ke.debug("Moving label "+t.label+" from (",i,",",c,") to (",a.x,",",a.y,") abc88"),e&&(i=a.x,c=a.y)}r.attr("transform",`translate(${i}, ${c+s/2})`)}if(t?.startLabelLeft){const r=Ye.get(t.id).startLeft;let i=t?.x,c=t?.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_left",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.startLabelRight){const r=Ye.get(t.id).startRight;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeStart?10:0,"start_right",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.endLabelLeft){const r=Ye.get(t.id).endLeft;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_left",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}if(t.endLabelRight){const r=Ye.get(t.id).endRight;let i=t.x,c=t.y;if(n){const a=Oe.calcTerminalLabelPosition(t.arrowTypeEnd?10:0,"end_right",n);i=a.x,c=a.y}r.attr("transform",`translate(${i}, ${c})`)}}d(Wo,"positionEdgeLabel");var Mn="__swimlane_default__",$r=21,No=20;function En(t){return Math.max(t.padding??No,No)}d(En,"topLaneHorizontalPadding");function Ko(t){const{x:e,y:n,width:o,height:s}=t,r=t.swimlaneContentTop;if(typeof e!="number"||typeof n!="number"||typeof o!="number"||typeof s!="number"||typeof r!="number"||!Number.isFinite(e)||!Number.isFinite(n)||!Number.isFinite(o)||!Number.isFinite(s)||!Number.isFinite(r)||o<=0||s<=0){delete t.groupTitleRect;return}const i=n-s/2,c=Math.min(r,n+s/2),a=Math.min($r,Math.max(0,c-i)),l=i+a;if(l<=i){delete t.groupTitleRect;return}t.groupTitleRect={left:e-o/2,right:e+o/2,top:i,bottom:l}}d(Ko,"assignTopLaneTitleRect");function qo(t){const e=t.direction,n=t.nodes??=[];for(const r of t.nodes??[])r.isGroup&&!r.parentId&&(r.shape="swimlane",e&&(r.direction=e));const o=n.filter(r=>!r.isGroup&&!r.parentId);if(o.length===0)return;let s=n.find(r=>r.id===Mn);s?s.isGroup&&(s.shape="swimlane",e&&(s.direction=e)):(s={id:Mn,label:"",isGroup:!0,shape:"swimlane",padding:20,...e?{direction:e}:{}},n.push(s));for(const r of o)r.parentId=Mn}d(qo,"prepareLayoutForSwimlanes");function Jo(t){const e=new Map;for(const a of t.nodes??[])e.set(a.id,a);const n=[];for(const a of t.edges??[]){const l=typeof a.start=="string"?a.start:void 0,g=typeof a.end=="string"?a.end:void 0;!l||!g||a.labelNodeId||n.push({id:a.id,src:l,dst:g,ref:a})}const o=t.nodes??[],s=o.filter(a=>a.isGroup),r=o.filter(a=>!a.isGroup);return{nodes:[...[...s].reverse(),...r].map(a=>a.id),edges:n,layout:t,nodeById:e}}d(Jo,"toGraphView");function Zo(t,e,n,o){const{layout:s}=t,r=t.nodeById,i=o?.layerGap??100,c=o?.nodeGap??40;let a=0;for(const I of e.layers){let u=0;for(const p of I){const f=r.get(p);if(!f){u++;continue}f.layer=a,f.order=u;const y=n.x[p]??u*c,v=n.y[p]??a*i;f.x=y,f.y=v,u++}a++}const l=s.nodes??[],g=new Map,x=[];for(const I of l){if(!I?.isGroup)continue;I.parentId||x.push(I);const u=l.filter(M=>M.parentId===I.id);let p=1/0,f=-1/0,y=1/0,v=-1/0;for(const M of u){const E=M.x??n.x[M.id],T=M.y??n.y[M.id],m=M.width??0,S=M.height??0;E!=null&&T!=null&&(p=Math.min(p,E-m/2),f=Math.max(f,E+m/2),y=Math.min(y,T-S/2),v=Math.max(v,T+S/2))}if(p===1/0||y===1/0)I.x=I.x??0,I.y=I.y??0,I.width=I.width??0,I.height=I.height??0;else{const M=I.padding??20,E=I.parentId?M:2*En(I),T=M,m=Math.max(0,f-p)+E,S=Math.max(0,v-y)+T,A=(p+f)/2,R=(y+v)/2;I.x=A,I.y=R,I.width=m,I.height=S,g.set(I.id,{minX:p,maxX:f,minY:y,maxY:v})}}if(x.length>0&&g.size>0){let I=1/0,u=-1/0,p=0;for(const f of x){const y=f.padding??20;y>p&&(p=y);const v=g.get(f.id);v&&(I=Math.min(I,v.minY),u=Math.max(u,v.maxY))}if(I!==1/0&&u!==-1/0){const f=Math.max(0,u-I),v=Math.max(p,36),M=f+2*v,E=(I+u)/2;for(const k of x)k.y=E,k.height=M,k.swimlaneContentTop=I;const T=[...x].sort((k,O)=>{const _=k.x??0,H=O.x??0;return _-H}),m=[],S=[],A=[];for(const k of T){const O=g.get(k.id);if(!O)continue;const _=Math.max(0,O.maxX-O.minX)+2*En(k),H=(O.minX+O.maxX)/2;m.push(k.id),S.push(H),A.push(_)}const R=m.length;if(R>0){const k=new Map;if(R===1)k.set(m[0],A[0]);else{const O=[];for(let j=0;j<R-1;j++)O.push(S[j+1]-S[j]);const _=new Array(R);_[0]=0;for(let j=0;j<R-1;j++)_[j+1]=2*O[j]-_[j];let H=0,P=Number.POSITIVE_INFINITY;for(let j=0;j<R;j++){const J=A[j];j%2===0?H=Math.max(H,J-_[j]):P=Math.min(P,_[j]-J)}let G=H;H<=P?G=(H+P)/2:G=H;for(let j=0;j<R;j++){const J=_[j]+(j%2===0?G:-G),dt=Math.max(A[j],J);k.set(m[j],dt)}}for(const O of x){const _=k.get(O.id);_!=null&&(O.width=_),Ko(O)}}}}}d(Zo,"writeBackToLayoutData");var zr="[EdgeLabelNodes]";function Qo(t){const e=[],n=[],o=new Map;for(const i of t.nodes)o.set(i.id,i);for(const i of t.edges){if(!i.label||i.label.length===0||i.isLayoutOnly||i.labelNodeId)continue;const c=i.start?o.get(i.start):void 0,a=i.end?o.get(i.end):void 0;if(!c||!a){Ke.warn(zr,`Edge ${i.id} has missing source or target node`);continue}const l=`edge-label-${i.start}-${i.end}-${i.id}`,x=c.parentId!==a.parentId?a.parentId:c.parentId,I={id:l,label:i.label,edgeStart:i.start??"",edgeEnd:i.end??"",shape:"labelRect",width:0,height:0,isEdgeLabel:!0,isDummy:!0,parentId:x,isGroup:!1,labelStyle:Array.isArray(i.labelStyle)?i.labelStyle[0]:i.labelStyle??"",...c.dir?{dir:c.dir}:{}};e.push(I),i.labelNodeId=l,i.label=void 0,i.text=void 0;const u={id:`${i.id}-to-label`,start:i.start,end:l,type:"normal",isLayoutOnly:!0},p={id:`${i.id}-from-label`,start:l,end:i.end,type:"normal",isLayoutOnly:!0};n.push(u,p)}const s=[...t.nodes,...e],r=[...t.edges,...n];return{...t,nodes:s,edges:r}}d(Qo,"createEdgeLabelNodes");var Ft=.001;function oo(t){const e=t.x??0,n=t.y??0,o=t.width??0,s=t.height??0;return o>0&&s>0?{cx:e,cy:n,rect:Ae(e,n,o,s)}:void 0}d(oo,"measuredNodeRect");function so(t){if(t.isGroup)return;const e=oo(t);return e?{id:String(t.id??""),cx:e.cx,cy:e.cy,rect:e.rect}:void 0}d(so,"nodeBoundsInfoFor");function oe(t,e,n=Ft){return Math.abs(t.x-e.x)<n&&Math.abs(t.y-e.y)<n}d(oe,"samePoint");function ft(t,e,n=Ft){return Math.abs(t.x-e.x)<n}d(ft,"sameX");function ht(t,e,n=Ft){return Math.abs(t.y-e.y)<n}d(ht,"sameY");function Tt(t,e,n=Ft){return ht(t,e,n)&&Math.abs(t.x-e.x)>n}d(Tt,"isHorizontalSegment");function wt(t,e,n=Ft){return ft(t,e,n)&&Math.abs(t.y-e.y)>n}d(wt,"isVerticalSegment");function zt(t,e,n,o){return Math.max(0,Math.min(Math.max(t,e),Math.max(n,o))-Math.max(Math.min(t,e),Math.min(n,o)))}d(zt,"overlapLength");function ce(t,e,n=Ft){return t.horizontal&&e.horizontal&&ht(t.a,e.a,n)?zt(t.a.x,t.b.x,e.a.x,e.b.x):t.vertical&&e.vertical&&ft(t.a,e.a,n)?zt(t.a.y,t.b.y,e.a.y,e.b.y):0}d(ce,"sameAxisSegmentOverlapLength");function Re(t,e=Ft){const n=[];for(let o=0;o<t.length-1;o++){const s=t[o],r=t[o+1],i=Tt(s,r,e),c=wt(s,r,e);(i||c)&&n.push({index:o,a:s,b:r,horizontal:i,vertical:c})}return n}d(Re,"orthogonalSegmentsForPoints");function Qt(t,e=Ft){const n=Re(t,e);let o=0;for(let s=1;s<n.length;s++)n[s-1].horizontal!==n[s].horizontal&&o++;return o}d(Qt,"countOrthogonalBends");function pt(t,e=Ft){const n=[];for(const o of t){const s=n.length>0?n[n.length-1]:void 0;(!s||!oe(s,o,e))&&n.push({x:o.x,y:o.y})}return n}d(pt,"dedupeConsecutivePoints");function ro(t,e=Ft){if(!t||t.length!==4)return;const[n,o,s,r]=t;return Tt(n,o,e)&&wt(o,s,e)&&Tt(s,r,e)?{kind:"HVH",p0:n,p1:o,p2:s,p3:r}:wt(n,o,e)&&Tt(o,s,e)&&wt(s,r,e)?{kind:"VHV",p0:n,p1:o,p2:s,p3:r}:void 0}d(ro,"classifyThreeSegmentRoute");function cn(t,e,n,o=0){const s=Math.min(t.x,e.x),r=Math.max(t.x,e.x),i=Math.min(t.y,e.y),c=Math.max(t.y,e.y);return r>n.left-o&&s<n.right+o&&c>n.top-o&&i<n.bottom+o}d(cn,"segmentBoundsOverlapRect");function io(t,e,n=0){return t.x>e.left+n&&t.x<e.right-n&&t.y>e.top+n&&t.y<e.bottom-n}d(io,"pointInsideRect");function ts(t,e){return t.left<=e.left&&t.right>=e.right&&t.top<=e.top&&t.bottom>=e.bottom}d(ts,"rectContainsRect");function Je(t,e){return t.left<e.right&&t.right>e.left&&t.top<e.bottom&&t.bottom>e.top}d(Je,"rectsOverlap");function Tn(t,e){return{left:t.left-e,right:t.right+e,top:t.top-e,bottom:t.bottom+e}}d(Tn,"inflateRect");function Ae(t,e,n,o){return{left:t-n/2,right:t+n/2,top:e-o/2,bottom:e+o/2}}d(Ae,"rectFromCenterSize");function qt(t){return oo(t)?.rect}d(qt,"rectOfNodeBounds");function Ie(t,e){switch(e){case"top":return{x:t.cx,y:t.rect.top};case"bottom":return{x:t.cx,y:t.rect.bottom};case"left":return{x:t.rect.left,y:t.cy};case"right":return{x:t.rect.right,y:t.cy}}}d(Ie,"portForRectSide");function co(t,e,n,o,s,r=Ft){const i=e==="left"||e==="right",c=o==="left"||o==="right";if(i&&c){if(e==="right"&&o==="left"&&t.x<n.x||e==="left"&&o==="right"&&t.x>n.x){if(ht(t,n,r))return[t,n];const x=(t.x+n.x)/2;return[t,{x,y:t.y},{x,y:n.y},n]}if(e===o){if(ht(t,n,r))return;const x=e==="left"?Math.min(t.x,n.x)-s:Math.max(t.x,n.x)+s;return[t,{x,y:t.y},{x,y:n.y},n]}return}if(!i&&!c){if(e===o){if(ft(t,n,r))return;const I=e==="top"?Math.min(t.y,n.y)-s:Math.max(t.y,n.y)+s;return[t,{x:t.x,y:I},{x:n.x,y:I},n]}if(!(e==="bottom"&&o==="top"&&t.y<n.y||e==="top"&&o==="bottom"&&t.y>n.y))return;if(ft(t,n,r))return[t,n];const x=(t.y+n.y)/2;return[t,{x:t.x,y:x},{x:n.x,y:x},n]}if(i&&!c){const g=e==="right"&&n.x>t.x||e==="left"&&n.x<t.x,x=o==="top"&&t.y<n.y||o==="bottom"&&t.y>n.y;return g&&x?[t,{x:n.x,y:t.y},n]:void 0}const a=e==="bottom"&&n.y>t.y||e==="top"&&n.y<t.y,l=o==="left"&&t.x<n.x||o==="right"&&t.x>n.x;return a&&l?[t,{x:t.x,y:n.y},n]:void 0}d(co,"buildOrthogonalPortPath");function ao(t,e,n,o){return e==="left"||e==="right"?[t,{x:o,y:t.y},{x:o,y:n.y},n]:[t,{x:t.x,y:o},{x:n.x,y:o},n]}d(ao,"buildSameSideTrackPath");function an(t){const e=new Map,n=[];for(const o of t){if(o.isEdgeLabel)continue;const s=so(o);s&&(e.set(s.id,s),n.push({id:s.id,rect:s.rect}))}return{nodeInfoById:e,realNodeRects:n}}d(an,"collectRealNodeBounds");function me(t){const e=[],n=[];for(const o of t){const s=so(o);if(!s)continue;const r={id:s.id,rect:s.rect};o.isEdgeLabel?n.push(r):e.push(r)}return{realNodeRects:e,labelNodeRects:n}}d(me,"collectNodeRectEntries");function es(t,{includeEdgeLabels:e=!0}={}){const n=[];for(const o of t){if(o.isGroup||!e&&o.isEdgeLabel)continue;const s=o.x??0,r=o.y??0,i=o.width??0,c=o.height??0;n.push({nodeId:o.id,...Ae(s,r,i,c)})}return n}d(es,"collectLayoutNodeRects");function lo(t,e,n=Ft){const o=t.start,s=t.end;if(!o||!s)return;const r=e.get(o),i=e.get(s);if(!(!r||!i))return{srcId:o,dstId:s,srcInfo:r,dstInfo:i,collinearX:Math.abs(r.cx-i.cx)<n,collinearY:Math.abs(r.cy-i.cy)<n}}d(lo,"getNodePairGeometry");function At(t,e,n,o=[],s=0){for(const r of n)if(!o.includes(r.id)&&cn(t,e,r.rect,-s))return!0;return!1}d(At,"segmentHitsAnyRect");function fo(t,e,n,o,s=Ft,r=1e-6){const i=ht(t,e,s),c=ft(t,e,s),a=ht(n,o,s),l=ft(n,o,s);if(i&&a||c&&l||!(i||c)||!(a||l))return!1;const g=i?{a:t,b:e}:{a:n,b:o},x=c?{a:t,b:e}:{a:n,b:o},I=g.a.y,u=Math.min(g.a.x,g.b.x),p=Math.max(g.a.x,g.b.x),f=x.a.x,y=Math.min(x.a.y,x.b.y),v=Math.max(x.a.y,x.b.y);if(f<u||f>p||I<y||I>v)return!1;const M=Math.abs(f-g.a.x)<r&&Math.abs(I-g.a.y)<r||Math.abs(f-g.b.x)<r&&Math.abs(I-g.b.y)<r,E=Math.abs(f-x.a.x)<r&&Math.abs(I-x.a.y)<r||Math.abs(f-x.b.x)<r&&Math.abs(I-x.b.y)<r;return!(M&&E)}d(fo,"orthogonalSegmentsCross");function ns(t,e,n,o,s=Ft){const r=ht(t,e,s),i=ft(t,e,s),c=ht(n,o,s),a=ft(n,o,s);return i&&a&&ft(t,n,s)?zt(t.y,e.y,n.y,o.y)>s:r&&c&&ht(t,n,s)?zt(t.x,e.x,n.x,o.x)>s:!1}d(ns,"sameAxisSegmentsOverlap");function Ze(t,e,n,o,{epsilon:s=Ft,skipDegenerateOther:r=!1}={}){for(const i of n){if(i===o||i.isLayoutOnly)continue;const c=i.points;if(!(!c||c.length<2))for(let a=0;a<c.length-1;a++){const l=c[a],g=c[a+1];if(!(r&&oe(l,g,s))&&(fo(t,e,l,g,s)||ns(t,e,l,g,s)))return!0}}return!1}d(Ze,"segmentConflictsWithAnyEdge");function le(t,e,n,o,s=Ft){const r=ht(t,e,s),i=ft(t,e,s),c=ht(n,o,s),a=ft(n,o,s);if(!(r&&a||i&&c))return!1;const l=r?{a:t,b:e}:{a:n,b:o},g=r?{a:n,b:o}:{a:t,b:e},x=l.a.y,I=Math.min(l.a.x,l.b.x),u=Math.max(l.a.x,l.b.x),p=g.a.x,f=Math.min(g.a.y,g.b.y),y=Math.max(g.a.y,g.b.y);return p>I+s&&p<u-s&&x>f+s&&x<y-s}d(le,"orthogonalSegmentsStrictlyCross");function wn(t,e,n){const o=Math.min(e,n),s=Math.max(e,n);return t>o+Ft&&t<s-Ft}d(wn,"strictlyBetween");function os(t,e,n){return ft(t,e)&&ft(e,n)?wn(e.y,t.y,n.y):ht(t,e)&&ht(e,n)?wn(e.x,t.x,n.x):!1}d(os,"isCollinearIntermediate");function ss(t){let e=!1;const n=[];for(let o=0;o<t.length;o++){const s=n[n.length-1],r=t[o],i=o+1<t.length?t[o+1]:void 0;if(s&&i){if(oe(s,i)){o++,e=!0;continue}if(os(s,r,i)){e=!0;continue}}n.push(r)}return{points:n,changed:e}}d(ss,"simplifyPolylineOnce");function Qe(t){const e=[t[0]];for(let o=1;o<t.length;o++){const s=e[e.length-1],r=t[o];if(!ft(s,r)&&!ht(s,r)){const i=e.length>=2?e[e.length-2]:void 0,a=(i?ft(i,s):!1)?{x:s.x,y:r.y}:{x:r.x,y:s.y};e.push(a)}e.push(r)}const n=[];for(const o of e){const s=n[n.length-1];(!s||!oe(s,o))&&n.push(o)}return n}d(Qe,"orthogonalizePolyline");function ae(t){if(t.length<3)return t;let e=[...t];for(let n=0;n<32;n++){const o=ss(e);if(e=o.points,!o.changed)break}return e}d(ae,"simplifyPolyline");var nt=.001,Vr=.5,Oo=4;function uo(t,e,n){const o=t;if(o.isLayoutOnly||!o.points||o.points.length<n)return;const s=o.start?e.get(o.start):void 0,r=o.end?e.get(o.end):void 0;return{edge:o,points:o.points,srcRect:s?qt(s):void 0,dstRect:r?qt(r):void 0}}d(uo,"endpointContextFor");function rs(t,e,n){if(ht(t,e,nt))return{x:t.x<n.left?n.left:n.right,y:t.y};if(ft(t,e,nt)){const o=t.y<n.top?n.top:n.bottom;return{x:t.x,y:o}}return{x:Math.min(n.right,Math.max(n.left,t.x)),y:Math.min(n.bottom,Math.max(n.top,t.y))}}d(rs,"segmentEnterPoint");function An(t,e,n){const o=n?1:-1;let s=n?0:t.length-1;for(;s>=0&&s<t.length&&io(t[s],e,Vr);)s+=o;if(s<0||s>=t.length)return t;const r=s-o;if(r<0||r>=t.length)return t;const i=rs(t[s],t[r],e);return n?[i,...t.slice(s)]:[...t.slice(0,s+1),i]}d(An,"clipEndpoint");function is(t,e){for(const n of t){const o=uo(n,e,2);if(!o)continue;let s=[...o.points];o.srcRect&&(s=An(s,o.srcRect,!0)),o.dstRect&&(s=An(s,o.dstRect,!1)),s=ae(Qe(s)),s=ho(s,o.srcRect,o.dstRect),o.edge.points=ae(Qe(s))}}d(is,"clipEdgeEndpointsToNodeBoundaries");function Rn(t,e,n,o=!1){if(ht(t,e,nt)){if(e.y<n.top-nt||e.y>n.bottom+nt)return e;if(o){if(t.x<n.left-nt)return{x:n.left,y:t.y};if(t.x>n.right+nt)return{x:n.right,y:t.y}}return{x:Math.abs(e.x-n.left)<=Math.abs(e.x-n.right)?n.left:n.right,y:t.y}}if(ft(t,e,nt)){if(e.x<n.left-nt||e.x>n.right+nt)return e;if(o){if(t.y<n.top-nt)return{x:t.x,y:n.top};if(t.y>n.bottom+nt)return{x:t.x,y:n.bottom}}const s=Math.abs(e.y-n.top)<=Math.abs(e.y-n.bottom);return{x:t.x,y:s?n.top:n.bottom}}return e}d(Rn,"snapEndpointToBoundary");function tn(t,e,n){const o=t[e];for(let s=e+n;s>=0&&s<t.length;s+=n){const r=t[s];if(!oe(r,o,nt))return r}return t[e+n]}d(tn,"firstDistinctAdjacent");function en(t,e){const n=t+Oo,o=e-Oo;return n<=o?{lo:n,hi:o}:{lo:(t+e)/2,hi:(t+e)/2}}d(en,"cornerClearanceRange");function Nn(t,e,n){const{lo:o,hi:s}=en(e,n);return Math.min(s,Math.max(o,t))}d(Nn,"clampToCornerClearance");function cs(t){const e=Math.max(...t.map(o=>o.lo)),n=Math.min(...t.map(o=>o.hi));if(!(e>n))return{lo:e,hi:n}}d(cs,"intersectRanges");function On(t,e){return e==="left"||e==="right"?en(t.top,t.bottom):en(t.left,t.right)}d(On,"clearanceRangeForSide");function nn(t,e,n){const o=t.y>=n.top-nt&&t.y<=n.bottom+nt,s=t.x>=n.left-nt&&t.x<=n.right+nt;if(ht(t,e,nt)&&o){if(Math.abs(t.x-n.left)<nt)return"left";if(Math.abs(t.x-n.right)<nt)return"right"}if(ft(t,e,nt)&&s){if(Math.abs(t.y-n.top)<nt)return"top";if(Math.abs(t.y-n.bottom)<nt)return"bottom"}}d(nn,"terminalSideForSegment");function Pe(t){return t==="left"||t==="right"}d(Pe,"isHorizontalSide");function as(t,e,n,o,s){const r=[],i=n?nn(t,e,n):void 0,c=o?nn(e,t,o):void 0;return n&&i&&Pe(i)===s&&r.push(On(n,i)),o&&c&&Pe(c)===s&&r.push(On(o,c)),r.length>0?cs(r):void 0}d(as,"straightClearanceRange");function Pn(t,e,n,o,s){const r=as(t,e,n,o,s);if(!r)return;const i=s?t.y:t.x,c=Math.min(r.hi,Math.max(r.lo,i));if(!(Math.abs(c-i)<nt))return s?[{x:t.x,y:c},{x:e.x,y:c}]:[{x:c,y:t.y},{x:c,y:e.y}]}d(Pn,"clearStraightEndpointCornerAxis");function ho(t,e,n){if(t.length!==2)return t;const[o,s]=t;return ht(o,s,nt)?Pn(o,s,e,n,!0)??t:ft(o,s,nt)?Pn(o,s,e,n,!1)??t:t}d(ho,"clearStraightEndpointCornerConnections");function ls(t,e,n){return Pe(n)?{x:t.x,y:Nn(t.y,e.top,e.bottom)}:{x:Nn(t.x,e.left,e.right),y:t.y}}d(ls,"cornerClearedEndpoint");function fs(t,e,n,o,s,r){const i=t.map(c=>({...c}));for(let c=e;c>=0&&c<t.length;c+=n){const a=t[c];if(r&&!ht(a,o,nt)||!r&&!ft(a,o,nt))break;r?i[c].y=s.y:i[c].x=s.x}return i}d(fs,"moveCollinearEndpointRun");function Bn(t,e,n){if(t.length<2)return t;const o=n?0:t.length-1,s=n?1:-1,r=t[o],i=tn(t,o,s);if(!i)return t;const c=nn(r,i,e);if(!c)return t;const a=Pe(c),l=ls(r,e,c);return oe(r,l,nt)?t:fs(t,o,s,r,l,a)}d(Bn,"clearEndpointCornerConnection");function kn(t,e,n){const o=Math.min(t.x,e.x)>=n.left-nt&&Math.max(t.x,e.x)<=n.right+nt,s=Math.min(t.y,e.y)>=n.top-nt&&Math.max(t.y,e.y)<=n.bottom+nt;if(Math.abs(t.y-n.top)<nt&&Math.abs(e.y-n.top)<nt&&o)return"top";if(Math.abs(t.y-n.bottom)<nt&&Math.abs(e.y-n.bottom)<nt&&o)return"bottom";if(Math.abs(t.x-n.left)<nt&&Math.abs(e.x-n.left)<nt&&s)return"left";if(Math.abs(t.x-n.right)<nt&&Math.abs(e.x-n.right)<nt&&s)return"right"}d(kn,"borderSideForSegment");function _n(t,e,n,o){switch(t){case"top":return ft(e,n,nt)&&n.y<o.top-nt;case"bottom":return ft(e,n,nt)&&n.y>o.bottom+nt;case"left":return ht(e,n,nt)&&n.x<o.left-nt;case"right":return ht(e,n,nt)&&n.x>o.right+nt}}d(_n,"leavesOutward");function Fn(t,e,n){if(t.length<3)return t;if(n){const r=kn(t[0],t[1],e);return r&&_n(r,t[1],t[2],e)?t.slice(1):t}const o=t.length-1,s=kn(t[o-1],t[o],e);return s&&_n(s,t[o-1],t[o-2],e)?t.slice(0,o):t}d(Fn,"collapseOwnBorderStub");function ds(t,e,n){let o=t;if(e){const r=tn(o,0,1);if(r){const i=Rn(r,o[0],e);i!==o[0]&&(o=[i,...o.slice(1)])}o=Fn(o,e,!0)}if(n){const r=o.length-1,i=tn(o,r,-1);if(i){const c=Rn(i,o[r],n,!0);c!==o[r]&&(o=[...o.slice(0,r),c])}o=Fn(o,n,!1)}const s=ho(o,e,n);return s!==o||o.length===2?s:(e&&(o=Bn(o,e,!0)),n&&(o=Bn(o,n,!1)),o)}d(ds,"snapAndCollapseEndpoints");function Dn(t,e){for(const n of t){const o=uo(n,e,2);if(!o)continue;const s=pt(o.points,nt),r=ds(s,o.srcRect,o.dstRect);if(r.length<3){o.edge.points=r;continue}const i=[r[0],{...r[0]},...r.slice(1,-1),r[r.length-1],{...r[r.length-1]}];o.edge.points=i}}d(Dn,"prepareEdgeEndpointsForRenderer");function go(t){return new Map(t.map(e=>[e.id,e]))}d(go,"buildNodeMap");function us(t,e){let n=t.parentId,o=null;for(;n;){const s=e.get(n);if(!s?.isGroup)break;o=s.id,n=s.parentId}return o}d(us,"resolveTopLevelGroupId");function Hn(t,e){let n=0,o=t.parentId;for(;o;){const s=e.get(o);if(!s?.isGroup)break;n++,o=s.parentId}return n}d(Hn,"groupDepth");function po(t){let e=1/0,n=-1/0,o=1/0,s=-1/0;for(const r of t){const i=r.x,c=r.y;if(typeof i!="number"||typeof c!="number")continue;const a=r.width??0,l=r.height??0;e=Math.min(e,i-a/2),n=Math.max(n,i+a/2),o=Math.min(o,c-l/2),s=Math.max(s,c+l/2)}return e===1/0||o===1/0?null:{minX:e,maxX:n,minY:o,maxY:s}}d(po,"boundsForChildren");function hs(t,e){const n=t.padding??20;t.x=(e.minX+e.maxX)/2,t.y=(e.minY+e.maxY)/2,t.width=Math.max(0,e.maxX-e.minX)+n,t.height=Math.max(0,e.maxY-e.minY)+n}d(hs,"applyGroupBounds");function gs(t){const e=go(t),n=t.filter(o=>o.isGroup&&o.parentId).sort((o,s)=>Hn(s,e)-Hn(o,e));for(const o of n){const s=t.filter(i=>i.parentId===o.id),r=po(s);r&&hs(o,r)}}d(gs,"recomputeNestedGroupBounds");function on(t,e){const n=t.nodes??[],o=t.edges??[],s=n.filter(a=>!a.isGroup);let r=1/0,i=-1/0;for(const a of s){const l=a[e];typeof l=="number"&&(r=Math.min(r,l),i=Math.max(i,l))}if(!Number.isFinite(r)||!Number.isFinite(i))return!1;const c=d(a=>r+i-a,"mirror");for(const a of n){const l=a[e];typeof l=="number"&&(a[e]=c(l));const g=a.groupTitleRect;g&&(a.groupTitleRect=e==="x"?{...g,left:c(g.right),right:c(g.left)}:{...g,top:c(g.bottom),bottom:c(g.top)})}for(const a of o)for(const l of a.points??[])l[e]=c(l[e]);return!0}d(on,"mirrorAxis");function ps(t){return(t.nodes??[]).some(n=>!n.isGroup)?on(t,"y"):!0}d(ps,"applyBtDirectionTransform");function ms(t,e="LR"){const n=t.nodes??[],o=t.edges??[],s=n.filter(P=>!P.isGroup);let r=1/0,i=1/0;for(const P of s){const G=P.x??0,j=P.y??0;G<r&&(r=G),j<i&&(i=j)}if(!Number.isFinite(r)||!Number.isFinite(i))return!1;const c=36;let a=0,l=0;for(const P of s)a+=P.width??0,l+=P.height??0;const g=a/s.length,x=l/s.length,I=x>0?Math.max(1,g/x):1;for(const P of s){const G=P.x??0,J=((P.y??0)-i)*I+c,dt=G-r;P.x=J,P.y=dt}for(const P of o)if(P.points)for(const G of P.points){const j=G.x,dt=(G.y-i)*I+c,mt=j-r;G.x=dt,G.y=mt}gs(n);const u=n.filter(P=>P.isGroup&&!P.parentId);if(u.length===0)return e==="RL"&&on(t,"x"),!0;const p=go(n),f=new Map;for(const P of n){if(P.isGroup)continue;const G=us(P,p);if(!G)continue;const j=f.get(G)??[];j.push(P),f.set(G,j)}let y=0;for(const P of u){const G=P.padding??0;G>y&&(y=G)}const v=[];let M=1/0,E=-1/0;for(const P of u){const G=f.get(P.id)??[],j=po(G);j&&(M=Math.min(M,j.minX),E=Math.max(E,j.maxX),v.push({lane:P,contentTop:j.minY,contentBottom:j.maxY,centerY:(j.minY+j.maxY)/2}))}if(M===1/0||E===-1/0)return!0;const T=Math.max(0,E-M),m=Math.max(y,10),S=T+2*m,A=c+S,O=(M+E)/2-S/2-c,_=O+A/2,H=Math.max(y,c);v.sort((P,G)=>P.centerY-G.centerY);for(let P=0;P<v.length;P++){const G=v[P];let j,J;if(P===0?j=G.contentTop-H:j=(v[P-1].contentBottom+G.contentTop)/2,P===v.length-1)J=G.contentBottom+H;else{const kt=v[P+1];J=(G.contentBottom+kt.contentTop)/2}const dt=Math.max(0,J-j),mt=(j+J)/2;G.lane.x=_,G.lane.y=mt,G.lane.width=A,G.lane.height=dt,G.lane.swimlaneContentTop=G.contentTop,G.lane.groupTitleRect={left:O,right:O+c,top:j,bottom:J}}return e==="RL"&&on(t,"x"),!0}d(ms,"applyLrDirectionTransform");var se=1e-6,jr=8,ze=jr,Ur=[0,ze,-ze,2*ze,-2*ze];function ys(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e);for(const s of t){if(s.isLayoutOnly)continue;const r=s.points;if(!r||r.length<4)continue;const i=ro(pt(r,se),se);if(!i)continue;const{p3:c}=i,a=i.kind==="HVH",l=lo(s,n,se);if(!l)continue;const{srcId:g,dstId:x,srcInfo:I,dstInfo:u,collinearX:p,collinearY:f}=l;if(p||f)continue;let y;const v=I.rect;for(const M of Ur){let E,T,m;if(a){const _=u.cy>I.cy?v.bottom:v.top,H=I.cx+M;if(H<=v.left+se||H>=v.right-se)continue;E={x:H,y:_},T={x:H,y:c.y},m={x:c.x,y:c.y}}else{const _=u.cx>I.cx?v.right:v.left,H=I.cy+M;if(H<=v.top+se||H>=v.bottom-se)continue;E={x:_,y:H},T={x:c.x,y:H},m={x:c.x,y:c.y}}const S=oe(E,T,se),A=oe(T,m,se);if(S&&A||!S&&At(E,T,o,[g],1)||!A&&At(T,m,o,[x],1))continue;const R=!S&&Ze(E,T,t,s,{epsilon:se,skipDegenerateOther:!0}),k=!A&&Ze(T,m,t,s,{epsilon:se,skipDegenerateOther:!0});if(!(R||k)){S?y=[T,m]:A?y=[E,T]:y=[E,T,m];break}}y&&(s.points=y)}}d(ys,"portSwapToLShape");function xs(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values());for(const c of t){if(c.isLayoutOnly)continue;const a=c.points;if(!a||a.length<4)continue;const l=pt(a,.001);if(l.length<4)continue;const g=l.length-1,x=l[g],I=l[g-1],u=l[g-2],p=x.x-I.x,f=x.y-I.y,y=Math.hypot(p,f);if(y>=10||y<.001)continue;const v=I.x-u.x,M=I.y-u.y;if(Math.hypot(v,M)<.001)continue;const T=Tt(I,x,.001),m=wt(I,x,.001),S=Tt(u,I,.001),A=wt(u,I,.001);if(!(T&&A||m&&S))continue;const R=c.end,k=c.start,O=R?e.get(R):void 0;if(!O)continue;const _=O.x??0,H=O.y??0,P=qt(O);if(!P)continue;let G,j;if(A){const W=M<0;G={x:_,y:u.y},j={x:_,y:W?P.bottom:P.top}}else{const W=v>0;G={x:u.x,y:H},j={x:W?P.right:P.left,y:H}}if(At(G,j,r,R?[R]:[],-2)||At(G,j,i,[],-2))continue;if(k){const W=e.get(k),et=W?qt(W):void 0;if(et&&io(G,et,2))continue}const J=d((W,et)=>`${W.x.toFixed(3)},${W.y.toFixed(3)}|${et.x.toFixed(3)},${et.y.toFixed(3)}`,"ownSegmentKey"),dt=new Set;for(let W=0;W<l.length-1;W++)dt.add(J(l[W],l[W+1]));const mt=d((W,et)=>{for(const at of t){if(at===c||at.isLayoutOnly)continue;const gt=at.points;if(!(!gt||gt.length<2))for(let xt=0;xt<gt.length-1;xt++){const vt=gt[xt],Vt=gt[xt+1];if(!dt.has(J(vt,Vt))&&le(W,et,vt,Vt,.001))return!0}}return!1},"segmentCrossesOtherEdge");if(mt(G,j))continue;if(g-3>=0){const W=l[g-3],et=[k,R].filter(at=>!!at);if(At(W,G,r,et,-2)||mt(W,G))continue}const Pt=[...l.slice(0,g-2),G,j];c.points=Pt;const Q=c.labelNodeId;if(Q){const W=e.get(Q);if(W){const et=W.width??0,at=W.height??0;if(et>0&&at>0){let gt,xt,vt=-1;for(let Vt=0;Vt<Pt.length-1;Vt++){const jt=Pt[Vt],Ut=Pt[Vt+1],te=Math.hypot(Ut.x-jt.x,Ut.y-jt.y),Se=ht(jt,Ut,.001),de=ft(jt,Ut,.001);(Se&&te>=et+2||de&&te>=at+2)&&te>vt&&(vt=te,gt=(jt.x+Ut.x)/2,xt=(jt.y+Ut.y)/2)}gt!==void 0&&xt!==void 0&&(W.x=gt,W.y=xt)}}}}}d(xs,"collapseShortTerminalStub");var Z=.001,_t=8,it=Re,In=d((t,e)=>ft(t,e,Z)||ht(t,e,Z),"orthogonallyAligned");function bs(t,e){const s=d((u,p)=>{const f=u.x??0,y=u.y??0,v=p.x-f,M=p.y-y;let E=(u.width??0)/2,T=(u.height??0)/2;return Math.abs(M)*E>Math.abs(v)*T?(M<0&&(T=-T),{x:f+(M===0?0:T*v/M),y:y+T}):(v<0&&(E=-E),{x:f+E,y:y+(v===0?0:E*M/v)})},"rectIntersect"),r=d((u,p)=>{const f=pt(u.points??[]);if(f.length<2)return;const y=p?u.start:u.end,v=y?e.get(y):void 0,M=v?qt(v):void 0;if(!v||!y||!M)return;const E=p?f[0]:f[f.length-1],T=p?f[1]:f[f.length-2],m=s(v,E);let S=E;if(In(T,m)&&(S=T),ft(m,S,Z))return{edge:u,edgeId:String(u.id??""),nodeId:y,atStart:p,orientation:"V",coord:m.x,min:Math.min(m.y,S.y),max:Math.max(m.y,S.y),boundary:m,railEnd:S,rect:M};if(ht(m,S,Z))return{edge:u,edgeId:String(u.id??""),nodeId:y,atStart:p,orientation:"H",coord:m.y,min:Math.min(m.x,S.x),max:Math.max(m.x,S.x),boundary:m,railEnd:S,rect:M}},"terminalLaneFor"),i=d((u,p)=>Math.max(0,Math.min(u.max,p.max)-Math.max(u.min,p.min)),"projectedOverlapLength"),c=d((u,p)=>u.nodeId!==p.nodeId||u.orientation!==p.orientation?!1:u.orientation==="H"?(Math.abs(u.boundary.x-u.rect.left)<1||Math.abs(u.boundary.x-u.rect.right)<1)&&ft(u.boundary,p.boundary,1):(Math.abs(u.boundary.y-u.rect.top)<1||Math.abs(u.boundary.y-u.rect.bottom)<1)&&ht(u.boundary,p.boundary,1),"sameTerminalFace"),a=d((u,p)=>u.nodeId!==p.nodeId||u.orientation!==p.orientation?!1:i(u,p)>=_t&&Math.abs(u.coord-p.coord)<.5,"exactTerminalLaneConflict"),l=d((u,p)=>{if(u.nodeId!==p.nodeId||u.orientation!==p.orientation||u.orientation!=="H"||u.atStart===p.atStart)return!1;const f=i(u,p);if(f<_t)return!1;const y=u.rect.bottom-u.rect.top;return f<y||f>2*y?!1:c(u,p)&&Math.abs(u.coord-p.coord)<16},"nearTerminalLaneConflict"),g=d((u,p)=>{const f=pt(u.edge.points??[]);if(f.length<2)return;const y=u.orientation==="V"?{x:u.boundary.x+p,y:u.boundary.y}:{x:u.boundary.x,y:u.boundary.y+p},v=u.orientation==="V"?{x:u.railEnd.x+p,y:u.railEnd.y}:{x:u.railEnd.x,y:u.railEnd.y+p};if(!d(()=>Math.abs(u.boundary.y-u.rect.top)<1||Math.abs(u.boundary.y-u.rect.bottom)<1?ht(y,u.boundary,Z)&&y.x>=u.rect.left+1&&y.x<=u.rect.right-1:Math.abs(u.boundary.x-u.rect.left)<1||Math.abs(u.boundary.x-u.rect.right)<1?ft(y,u.boundary,Z)&&y.y>=u.rect.top+1&&y.y<=u.rect.bottom-1:!1,"boundaryStaysOnSameFace")())return;if(u.atStart){const S=f.length>1&&oe(f[1],u.railEnd,Z),A=f.slice(S?2:1),R=A[0];return R&&!In(R,v)?void 0:[y,v,...A]}const E=f.length>1&&oe(f[f.length-2],u.railEnd,Z),T=f.slice(0,E?-2:-1),m=T[T.length-1];if(!(m&&!In(m,v)))return[...T,v,y]},"shiftedCandidate"),x=d(u=>{const p=u.edge,f=pt(p.points??[]);if(f.length!==2)return!1;const y=p.start,v=p.end,M=y?e.get(y):void 0,E=v?e.get(v):void 0;if(!M||!E)return!1;const T=M.x??0,m=M.y??0,S=E.x??0,A=E.y??0,[R,k]=f;return ht(R,k,Z)&&Math.abs(m-A)<1&&Math.abs(T-S)>1||ft(R,k,Z)&&Math.abs(T-S)<1&&Math.abs(m-A)>1},"laneIsStraightCollinearConnector"),I=[-7,7,-14,14,-21,21];for(let u=0;u<8;u++){const p=t.filter(y=>!y.isLayoutOnly).flatMap(y=>[r(y,!0),r(y,!1)]).filter(y=>!!y);let f=!1;for(let y=0;y<p.length&&!f;y++)for(let v=y+1;v<p.length&&!f;v++){const M=p[y],E=p[v];if(M.edge===E.edge||!(a(M,E)||l(M,E)))continue;const T=!a(M,E),m=[M,E].sort((S,A)=>{const R=x(S),k=x(A);return R!==k?Number(R)-Number(k):+!A.atStart-+!S.atStart});for(const S of m){for(const A of I){const R=g(S,A);if(!R)continue;const k=r({...S.edge,points:R},S.atStart);if(!(!k||p.some(O=>O.edge!==S.edge&&(a(k,O)||T&&l(k,O))))){S.edge.points=R,f=!0;break}}if(f)break}}if(!f)return}}d(bs,"separateSharedRenderedTerminalLanes");function Ms(t,e){const{realNodeRects:o,labelNodeRects:s}=me(e.values()),r=d((c,a)=>{const l=c.start,g=c.end,x=it(a);if(x.length!==a.length-1)return!1;const I=[l,g].filter(u=>!!u);for(const u of x)if(At(u.a,u.b,o,I,-2)||At(u.a,u.b,s,[],-2))return!1;for(const u of t){if(u===c||u.isLayoutOnly)continue;const p=u.points;if(!(!p||p.length<2)){for(const f of x)for(const y of it(pt(p)))if(ce(f,y,.5)>=_t||le(f.a,f.b,y.a,y.b,Z))return!1}}return!0},"candidateIsSafe"),i=d((c,a)=>{if(a+4>=c.length)return;const l=c[a],g=c[a+1],x=c[a+2],I=c[a+3],u=c[a+4],p=Tt(l,g)&&wt(g,x)&&Tt(x,I)&&wt(I,u)&&ft(l,I,Z)&&ft(l,u,Z)&&ft(g,x,Z)&&(g.x-l.x)*(I.x-x.x)<0,f=wt(l,g)&&Tt(g,x)&&wt(x,I)&&Tt(I,u)&&ht(l,I,Z)&&ht(l,u,Z)&&ht(g,x,Z)&&(g.y-l.y)*(I.y-x.y)<0;if(p||f)return pt([...c.slice(0,a+1),u,...c.slice(a+5)]);if(a+5>=c.length)return;const y=c[a+5],v=wt(l,g)&&Tt(g,x)&&wt(x,I)&&Tt(I,u)&&wt(u,y)&&ft(l,u,Z)&&ft(l,y,Z)&&ft(x,I,Z)&&(x.x-g.x)*(u.x-I.x)<0,M=Tt(l,g)&&wt(g,x)&&Tt(x,I)&&wt(I,u)&&Tt(u,y)&&ht(l,u,Z)&&ht(l,y,Z)&&ht(x,I,Z)&&(x.y-g.y)*(u.y-I.y)<0;if(!(!v&&!M))return pt([...c.slice(0,a+1),y,...c.slice(a+6)])},"withoutDogleg");for(let c=0;c<8;c++){let a=!1;for(const l of t){if(l.isLayoutOnly)continue;const g=pt(l.points??[]);for(let x=0;x<=g.length-5;x++){const I=i(g,x);if(!(!I||!r(l,I))){l.points=I,a=!0;break}}if(a)break}if(!a)return}}d(Ms,"collapseRedundantRectangularDoglegs");function Xn(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values()),c=t.filter(p=>!p.isLayoutOnly),a=d((p,f,y)=>pt(p===f?y??[]:p.points??[]),"pointsFor"),l=d((p,f)=>{let y=0;for(let v=0;v<c.length;v++){const M=it(a(c[v],p,f));for(let E=v+1;E<c.length;E++){const T=it(a(c[E],p,f));for(const m of M)for(const S of T)le(m.a,m.b,S.a,S.b,Z)&&y++}}return y},"strictCrossingCount"),g=d(p=>{const f=it(p);if(f.length!==3)return;const y=f[1];if(!(f[0].horizontal===y.horizontal||f[2].horizontal===y.horizontal))return{index:y.index,horizontal:y.horizontal,vertical:y.vertical,segment:y}},"middleRail"),x=d((p,f)=>{const y=[p.start,p.end].filter(v=>!!v);return r.filter(v=>{if(y.includes(v.id))return!1;const M=v.rect;return f.horizontal?zt(f.a.x,f.b.x,M.left,M.right)>=_t&&f.a.y>=M.top-2&&f.a.y<=M.bottom+2:zt(f.a.y,f.b.y,M.top,M.bottom)>=_t&&f.a.x>=M.left-2&&f.a.x<=M.right+2})},"blockingRectsFor"),I=d((p,f,y)=>{const v=p.map(E=>({...E}));if(f.horizontal)v[f.index].y=y,v[f.index+1].y=y;else if(f.vertical)v[f.index].x=y,v[f.index+1].x=y;else return;const M=ae(pt(v));return it(M).length===M.length-1?M:void 0},"candidateByMovingRail"),u=d((p,f,y)=>{const v=[p.start,p.end].filter(E=>!!E),M=it(f);if(M.length!==f.length-1)return!1;for(const E of M)if(At(E.a,E.b,r,v,-2)||At(E.a,E.b,i,[],-2))return!1;for(const E of c)if(E!==p){for(const T of M)for(const m of it(a(E)))if(ce(T,m,.5)>=_t)return!1}return l(p,f)<=y},"candidateIsSafe");for(let p=0;p<8;p++){const f=l();let y=!1;for(const v of c){const M=a(v),E=g(M);if(!E)continue;const T=x(v,E.segment);if(T.length===0)continue;const m=E.horizontal?[Math.min(...T.map(S=>S.rect.top))-20,Math.max(...T.map(S=>S.rect.bottom))+20]:[Math.min(...T.map(S=>S.rect.left))-20,Math.max(...T.map(S=>S.rect.right))+20];for(const S of m){const A=I(M,E.segment,S);if(!(!A||!u(v,A,f))){v.points=A,y=!0;break}}if(y)break}if(!y)return}}d(Xn,"liftObstacleHuggingSameSideRails");function Yn(t,e){const o=d(a=>{const l=a.groupTitleRect;if(!(!l||typeof l.left!="number"||typeof l.right!="number"||typeof l.top!="number"||typeof l.bottom!="number"||!Number.isFinite(l.left)||!Number.isFinite(l.right)||!Number.isFinite(l.top)||!Number.isFinite(l.bottom)||l.right<=l.left||l.bottom<=l.top))return{left:l.left,right:l.right,top:l.top,bottom:l.bottom}},"validTitleRect"),s=d(a=>{if(!a.isGroup||a.parentId)return;const l=a.direction,g=typeof l=="string"?l.toUpperCase():"";if(g==="LR"||g==="RL"||g==="BT")return;const x=o(a),I=a.y,u=a.height;if(!x||typeof I!="number"||typeof u!="number"||!Number.isFinite(I)||!Number.isFinite(u)||u<=0)return;const p=x.right-x.left,f=x.bottom-x.top;if(!(f<=0||p<f))return{node:a,rect:x}},"topLaneTitleFor"),r=d((a,l)=>{if(!a.horizontal)return!1;const g=a.a.y;return g<=l.top+Z||g>=l.bottom-Z?!1:zt(a.a.x,a.b.x,l.left,l.right)>=_t},"horizontalSegmentIntersectsTitle"),i=[...e.values()].map(s).filter(a=>!!a);if(i.length===0)return;let c=0;for(const a of t){if(a.isLayoutOnly)continue;const l=pt(a.points??[]);for(const g of it(l))for(const x of i)r(g,x.rect)&&(c=Math.max(c,x.rect.bottom-g.a.y+4))}if(!(c<=Z))for(const a of i){const l=a.node.y,g=a.node.height;typeof l!="number"||typeof g!="number"||!Number.isFinite(l)||!Number.isFinite(g)||g<=0||(a.node.y=l-c/2,a.node.height=g+c,a.node.groupTitleRect={...a.rect,top:a.rect.top-c,bottom:a.rect.bottom-c})}}d(Yn,"liftTopLaneTitleBandsAboveRails");function Gn(t,e){const o=d(l=>{const g=l.groupTitleRect;if(!(!g||typeof g.left!="number"||typeof g.right!="number"||typeof g.top!="number"||typeof g.bottom!="number"||!Number.isFinite(g.left)||!Number.isFinite(g.right)||!Number.isFinite(g.top)||!Number.isFinite(g.bottom)||g.right<=g.left||g.bottom<=g.top))return{left:g.left,right:g.right,top:g.top,bottom:g.bottom}},"validTitleRect"),s=d(l=>{if(!l.isGroup||l.parentId||l.direction!=="LR")return;const x=o(l),I=l.x,u=l.width;if(!x||typeof I!="number"||typeof u!="number"||!Number.isFinite(I)||!Number.isFinite(u)||u<=0)return;const p=x.right-x.left,f=x.bottom-x.top;if(!(p<=0||f<p))return{node:l,rect:x}},"leftLaneTitleFor"),r=d((l,g)=>{if(!l.vertical)return!1;const x=l.a.x;return x<=g.left+Z||x>=g.right-Z?!1:zt(l.a.y,l.b.y,g.top,g.bottom)>=_t},"verticalSegmentIntersectsTitle"),i=d((l,g)=>{if(!l.horizontal)return!1;const x=l.a.y;return x<=g.top+Z||x>=g.bottom-Z?!1:zt(l.a.x,l.b.x,g.left,g.right)>=_t},"horizontalSegmentIntersectsTitle"),c=[...e.values()].map(s).filter(l=>!!l);if(c.length===0)return;let a=0;for(const l of t){if(l.isLayoutOnly)continue;const g=pt(l.points??[]);for(const x of it(g))for(const I of c)if(r(x,I.rect))a=Math.max(a,I.rect.right-x.a.x+4);else if(i(x,I.rect)){const u=Math.min(x.a.x,x.b.x);a=Math.max(a,I.rect.right-u+4)}}if(!(a<=Z))for(const l of c){const g=l.node.x,x=l.node.width;typeof g!="number"||typeof x!="number"||!Number.isFinite(g)||!Number.isFinite(x)||x<=0||(l.node.x=g-a/2,l.node.width=x+a,l.node.groupTitleRect={...l.rect,left:l.rect.left-a,right:l.rect.right-a})}}d(Gn,"shiftLeftLaneTitleBandsLeftOfRails");function Is(t,e){const{realNodeRects:o}=me(e.values()),s=t.filter(p=>!p.isLayoutOnly),r=d((p,f=new Map)=>pt(f.get(p)??p.points??[]),"replacementPointsFor"),i=d((p=new Map)=>{let f=0;for(let y=0;y<s.length;y++){const v=it(r(s[y],p));for(let M=y+1;M<s.length;M++){const E=it(r(s[M],p));for(const T of v)for(const m of E)le(T.a,T.b,m.a,m.b,Z)&&f++}}return f},"crossingCount"),c=d((p=new Map)=>s.reduce((f,y)=>f+Qt(r(y,p)),0),"totalBends"),a=d(p=>{const f=r(p);if(f.length<4)return;const y=f[f.length-2],v=f[f.length-1];if(!(!Tt(y,v,Z)&&!wt(y,v,Z)))return{tailStart:y,terminal:v}},"terminalTailFor"),l=d((p,f)=>{const y=r(p);if(y.length<3)return;const v=y[0],M=y[1];let E;if(Tt(v,M,Z))E={x:M.x,y:f.tailStart.y};else if(wt(v,M,Z))E={x:f.tailStart.x,y:M.y};else return;const T=ae(pt([v,M,E,f.tailStart,f.terminal]));return it(T).length===T.length-1?T:void 0},"candidateWithDestinationTail"),g=d((p,f)=>{const y=[p.start,p.end].filter(v=>!!v);for(const v of it(f))if(At(v.a,v.b,o,y,-2))return!0;return!1},"pathHasNodeHit"),x=d((p,f,y)=>{for(const v of s)if(v!==p){for(const M of it(f))for(const E of it(r(v,y)))if(ce(M,E,.5)>=_t)return!0}return!1},"pathHasSharedTrack"),I=d((p,f,y)=>!g(p,f)&&!x(p,f,y),"candidateIsSafe"),u=d(()=>{const p=new Map;for(const f of s){const y=f.end;if(!y||!e.has(y)||r(f).length<4)continue;const M=p.get(y)??[];M.push(f),p.set(y,M)}return p},"edgesByDestination");for(let p=0;p<4;p++){const f=i();if(f===0)return;const y=c();let v,M=f,E=y;for(const T of u().values())for(let m=0;m<T.length;m++)for(let S=m+1;S<T.length;S++){const A=T[m],R=T[S],k=a(A),O=a(R);if(!k||!O)continue;const _=l(A,O),H=l(R,k);if(!_||!H)continue;const P=new Map([[A,_],[R,H]]);if(!I(A,_,P)||!I(R,H,P))continue;const G=i(P),j=c(P);G>=f||G>M||G===M&&j>=E||(v=P,M=G,E=j)}if(!v)return;for(const[T,m]of v)T.points=m}}d(Is,"swapDestinationTerminalTailsToReduceCrossings");function Ss(t,e){const{realNodeRects:r,labelNodeRects:i}=me(e.values()),c=t.filter(T=>!T.isLayoutOnly),a=d((T,m=new Map)=>pt(m.get(T)??T.points??[]),"replacementPointsFor"),l=d((T=new Map)=>{let m=0;for(let S=0;S<c.length;S++){const A=it(a(c[S],T));for(let R=S+1;R<c.length;R++){const k=it(a(c[R],T));for(const O of A)for(const _ of k)le(O.a,O.b,_.a,_.b,Z)&&m++}}return m},"strictCrossingCount"),g=d((T=new Map)=>c.reduce((m,S)=>m+Qt(a(S,T)),0),"totalBends"),x=d(T=>{const m=T.start,S=T.end,A=m?e.get(m):void 0,R=S?e.get(S):void 0,k=A?qt(A):void 0,O=R?qt(R):void 0;return k&&O?{src:k,dst:O}:void 0},"endpointRectsFor"),I=d((T,m,S)=>{if(S.index<=0||S.index+1>=m.length-1)return;const A=x(T);if(A){if(S.vertical){const R=S.a.x,k=Math.min(A.src.left,A.dst.left),O=Math.max(A.src.right,A.dst.right),_=R<k-Z?"left":R>O+Z?"right":void 0;return _?{edge:T,points:m,segmentIndex:S.index,axis:"vertical",side:_,coord:R,min:Math.min(S.a.y,S.b.y),max:Math.max(S.a.y,S.b.y)}:void 0}if(S.horizontal){const R=S.a.y,k=Math.min(A.src.top,A.dst.top),O=Math.max(A.src.bottom,A.dst.bottom),_=R<k-Z?"top":R>O+Z?"bottom":void 0;return _?{edge:T,points:m,segmentIndex:S.index,axis:"horizontal",side:_,coord:R,min:Math.min(S.a.x,S.b.x),max:Math.max(S.a.x,S.b.x)}:void 0}}},"externalRailForSegment"),u=d(()=>{const T=[];for(const m of c){const S=a(m);for(const A of it(S)){const R=I(m,S,A);R&&T.push(R)}}return T},"collectExternalRails"),p=d((T,m)=>T.edge!==m.edge&&T.axis===m.axis&&T.side===m.side&&zt(T.min,T.max,m.min,m.max)>=_t,"railsInteract"),f=d(T=>{const m=[],S=new Set;for(const A of T){if(S.has(A))continue;const R=[A],k=[];for(S.add(A);R.length>0;){const O=R.pop();k.push(O);for(const _ of T)!S.has(_)&&p(O,_)&&(S.add(_),R.push(_))}k.length>1&&m.push(k)}return m},"connectedComponents"),y=d(T=>{const m=[];for(const S of T)m.some(A=>Math.abs(A-S.coord)<Z)||m.push(S.coord);for(;m.length<T.length;){const S=Math.min(...m),A=Math.max(...m),R=T[0].side;m.push(R==="left"||R==="top"?S-12*(T.length-m.length):A+12*(T.length-m.length))}return m},"uniqueCoordsFor"),v=d(T=>{const m=T.map(R=>R.coord),S=y(T),A=[];if(T.length<=6){const R=new Array(S.length).fill(!1),k=[],O=d(()=>{if(k.length===T.length){k.some((_,H)=>Math.abs(_-m[H])>=Z)&&A.push([...k]);return}for(const[_,H]of S.entries())R[_]||(R[_]=!0,k.push(H),O(),k.pop(),R[_]=!1)},"visit");return O(),A}for(let R=0;R<m.length;R++)for(let k=R+1;k<m.length;k++){const O=[...m];[O[R],O[k]]=[O[k],O[R]],A.push(O)}return A},"coordinateAssignmentsFor"),M=d((T,m)=>{const S=new Map;for(const[R,k]of T.entries()){const O=m[R],_=S.get(k.edge)??k.points.map(H=>({x:H.x,y:H.y}));k.axis==="vertical"?(_[k.segmentIndex].x=O,_[k.segmentIndex+1].x=O):(_[k.segmentIndex].y=O,_[k.segmentIndex+1].y=O),S.set(k.edge,_)}const A=new Map;for(const[R,k]of S){const O=ae(pt(k));if(it(O).length!==O.length-1)return;A.set(R,O)}return A},"replacementsForAssignment"),E=d(T=>{for(const[m,S]of T){const A=[m.start,m.end].filter(R=>!!R);for(const R of it(S))if(At(R.a,R.b,r,A,-2)||At(R.a,R.b,i,[],-2))return!1}for(let m=0;m<c.length;m++){const S=c[m],A=T.has(S),R=it(a(S,T));for(let k=m+1;k<c.length;k++){const O=c[k];if(!A&&!T.has(O))continue;const _=it(a(O,T));for(const H of R)for(const P of _)if(ce(H,P,.5)>=_t)return!1}}return!0},"candidateIsSafe");for(let T=0;T<4;T++){const m=l();if(m===0)return;let S,A=m,R=g(),k=Number.POSITIVE_INFINITY;for(const O of f(u()))for(const _ of v(O)){const H=M(O,_);if(!H||!E(H))continue;const P=l(H);if(P>=m)continue;const G=g(H),j=O.reduce((J,dt,mt)=>J+Math.abs(_[mt]-dt.coord),0);P>A||P===A&&(G>R||G===R&&j>=k)||(S=H,A=P,R=G,k=j)}if(!S)return;for(const[O,_]of S)O.points=_}}d(Ss,"reassignCrossingExternalRailChannels");function Cs(t,e){const{realNodeRects:o,labelNodeRects:s}=me(e.values()),r=t.filter(u=>!u.isLayoutOnly),i=d((u,p,f)=>pt(u===p?f??[]:u.points??[]),"pointsFor"),c=d(u=>it(u).reduce((p,f)=>{const y=f.a.x-f.b.x,v=f.a.y-f.b.y;return p+Math.hypot(y,v)},0),"pathLength"),a=d((u,p)=>{let f=0;for(let y=0;y<r.length;y++){const v=it(i(r[y],u,p));for(let M=y+1;M<r.length;M++){const E=it(i(r[M],u,p));for(const T of v)for(const m of E)le(T.a,T.b,m.a,m.b,Z)&&f++}}return f},"strictCrossingCount"),l=d((u,p)=>{if(u.horizontal){const f=u.a.y;return(Math.abs(f-p.top)<1||Math.abs(f-p.bottom)<1)&&zt(u.a.x,u.b.x,p.left,p.right)>=_t}if(u.vertical){const f=u.a.x;return(Math.abs(f-p.left)<1||Math.abs(f-p.right)<1)&&zt(u.a.y,u.b.y,p.top,p.bottom)>=_t}return!1},"segmentRunsAlongRectBorder"),g=d(u=>{const p=[u.start,u.end].filter(y=>!!y),f=[];for(const y of p){const v=e.get(y),M=v?qt(v):void 0;M&&f.push(M)}return f},"endpointRectsFor"),x=d((u,p)=>{if(p+3>=u.length)return[];const f=u[p],y=u[p+1],v=u[p+2],M=u[p+3],E=Tt(f,y,Z)&&wt(y,v,Z)&&Tt(v,M,Z),T=wt(f,y,Z)&&Tt(y,v,Z)&&wt(v,M,Z);if(!E&&!T)return[];if(!(E?Math.sign(y.x-f.x)!==Math.sign(M.x-v.x):Math.sign(y.y-f.y)!==Math.sign(M.y-v.y)))return[];const S=ft(f,M,Z)||ht(f,M,Z)?[]:[{x:f.x,y:M.y},{x:M.x,y:f.y}],A=S.length===0?[[...u.slice(0,p+1),...u.slice(p+3)]]:S.map(k=>[...u.slice(0,p+1),k,...u.slice(p+3)]),R=new Set;return A.map(k=>ae(pt(k))).filter(k=>{if(it(k).length!==k.length-1||!k.some(_=>oe(_,M,Z)))return!1;const O=k.map(_=>`${_.x.toFixed(3)},${_.y.toFixed(3)}`).join("|");return R.has(O)?!1:(R.add(O),!0)})},"shortcutCandidatesAt"),I=d((u,p,f)=>{const y=[u.start,u.end].filter(M=>!!M),v=g(u);for(const M of it(p))if(At(M.a,M.b,o,y,-2)||At(M.a,M.b,s,[],-2)||v.some(E=>l(M,E)))return!1;for(const M of r)if(M!==u){for(const E of it(p))for(const T of it(i(M)))if(ce(E,T,.5)>=_t)return!1}return a(u,p)<=f},"candidateIsSafe");for(let u=0;u<8;u++){const p=a();let f,y,v=p,M=Number.POSITIVE_INFINITY,E=Number.POSITIVE_INFINITY;for(const T of r){const m=i(T),S=Qt(m,Z),A=c(m);for(let R=0;R<=m.length-4;R++)for(const k of x(m,R)){const O=Qt(k,Z),_=c(k);if(!(O<S||O===S&&_<A-Z)||!I(T,k,p))continue;const P=a(T,k);P>v||P===v&&(O>M||O===M&&_>=E)||(f=T,y=k,v=P,M=O,E=_)}}if(!f||!y)return;f.points=y}}d(Cs,"shortcutRedundantOrthogonalJogs");function vs(t,e){const i=[];for(const N of e.values()){if(N.isGroup||N.isEdgeLabel)continue;const F=N.x??0,D=N.y??0,V=qt(N);V&&i.push({id:String(N.id??""),cx:F,cy:D,rect:V})}if(i.length===0)return;const c=new Map(i.map(N=>[N.id,N])),a=i.map(N=>({id:N.id,rect:N.rect})),l=["top","bottom","left","right"],g={top:Math.min(...i.map(N=>N.rect.top))-20,bottom:Math.max(...i.map(N=>N.rect.bottom))+20,left:Math.min(...i.map(N=>N.rect.left))-20,right:Math.max(...i.map(N=>N.rect.right))+20},x=t.filter(N=>!N.isLayoutOnly),I=new Map(x.map((N,F)=>[N,F])),u=d(N=>{const F=N==="left"||N==="top"?-1:1,D=[];for(let V=0;V<=2;V++)D.push(g[N]+F*20*V);return D},"outwardTracksForSide"),p=d((N,F=new Map)=>pt(F.get(N)??N.points??[]),"replacementPointsFor"),f=d((N,F)=>{let D=0;for(const V of N)for(const h of F)le(V.a,V.b,h.a,h.b,Z)&&D++;return D},"crossingCountBetweenSegments"),y=d((N,F)=>f(it(N),it(F)),"crossingCountBetweenPaths"),v=d((N=new Map)=>{let F=0;const D=[],V=new Set,h=[],b=d(C=>{V.has(C)||(V.add(C),h.push(C))},"addEdge");for(let C=0;C<x.length;C++){const L=x[C],w=p(L,N);for(let B=C+1;B<x.length;B++){const U=x[B],q=y(w,p(U,N));q>0&&(F+=q,D.push({first:L,second:U,count:q}),b(L),b(U))}}return h.sort((C,L)=>(I.get(C)??0)-(I.get(L)??0)),{count:F,pairs:D,edgeSet:V,edges:h}},"crossingSnapshot"),M=d((N,F)=>{const D=new Set(F.keys());if(D.size===0)return N.count;let V=0;for(const b of N.pairs)(D.has(b.first)||D.has(b.second))&&(V+=b.count);let h=0;for(let b=0;b<x.length;b++){const C=x[b],L=D.has(C),w=p(C,F);for(let B=b+1;B<x.length;B++){const U=x[B];!L&&!D.has(U)||(h+=y(w,p(U,F)))}}return N.count-V+h},"crossingCountWithReplacements"),E=d(N=>{const F=new Map;for(const h of N.pairs){const b=F.get(h.first)??new Set;b.add(h.second),F.set(h.first,b);const C=F.get(h.second)??new Set;C.add(h.first),F.set(h.second,C)}const D=[],V=new Set;for(const h of N.edges){if(V.has(h))continue;const b=[h],C=[];for(V.add(h);b.length>0;){const L=b.pop();C.push(L);for(const w of F.get(L)??[])V.has(w)||(V.add(w),b.push(w))}C.sort((L,w)=>(I.get(L)??0)-(I.get(w)??0)),C.length>1&&D.push(C)}return D},"crossingComponents"),T=d(N=>[N.start,N.end].filter(F=>!!F),"endpointIdsFor"),m=d(N=>{const F=[];for(const D of E(N)){const V=new Set(D),h=new Set(D.flatMap(C=>T(C))),b=[...D];for(const C of x)V.has(C)||T(C).some(L=>h.has(L))&&b.push(C);b.sort((C,L)=>(I.get(C)??0)-(I.get(L)??0)),F.push(b)}return F},"pairSearchGroups"),S=d((N,F,D)=>M(N,new Map([[F,D]])),"crossingCountWithSingleReplacement"),A=d(N=>{const F=new Map;for(const D of N.pairs)F.set(D.first,(F.get(D.first)??0)+D.count),F.set(D.second,(F.get(D.second)??0)+D.count);return F},"currentCrossingsByEdge"),R=d(N=>N.slice(1).reduce((F,D,V)=>{const h=N[V];return F+Math.abs(D.x-h.x)+Math.abs(D.y-h.y)},0),"pathLength"),k=d((N=new Map)=>x.reduce((F,D)=>F+Qt(p(D,N)),0),"totalBends"),O=d((N=new Map)=>x.reduce((F,D)=>F+R(p(D,N)),0),"totalLength"),_=d((N,F,D=new Map)=>{const V=it(F);for(const h of x)if(h!==N){for(const b of V)for(const C of it(p(h,D)))if(ce(b,C,.5)>=_t)return!0}return!1},"pathHasSegmentConflict"),H=d((N,F)=>{const D=[N.start,N.end].filter(V=>!!V);for(const V of it(F))if(At(V.a,V.b,a,D,-2))return!0;return!1},"pathHitsNode"),P=d((N,F)=>{const D=ae(pt(F));it(D).length===D.length-1&&N.push(D)},"pushOrthogonalCandidate"),G=d(N=>N==="left"||N==="right","sideIsHorizontal"),j=d((N,F,D)=>{switch(F){case"left":return Math.min(N.x,D.x)-20;case"right":return Math.max(N.x,D.x)+20;case"top":return Math.min(N.y,D.y)-20;case"bottom":return Math.max(N.y,D.y)+20}},"localTrackForSameSide"),J=d((N,F,D,V)=>{const h=D==="left"||D==="top"?-1:1,b=[j(F,D,V),g[D]];for(const C of b)for(let L=0;L<=2;L++)P(N,ao(F,D,V,C+h*20*L))},"addSameSideCandidates"),dt=d((N,F,D,V,h)=>{for(const b of u(D))for(const C of u(h))P(N,[F,{x:b,y:F.y},{x:b,y:C},{x:V.x,y:C},V])},"addHorizontalToVerticalCandidates"),mt=d((N,F,D,V,h)=>{for(const b of u(D))for(const C of u(h))P(N,[F,{x:F.x,y:b},{x:C,y:b},{x:C,y:V.y},V])},"addVerticalToHorizontalCandidates"),kt=d((N,F,D,V,h)=>{const b=[...u("top"),...u("bottom")];for(const C of u(D))for(const L of u(h))for(const w of b)P(N,[F,{x:C,y:F.y},{x:C,y:w},{x:L,y:w},{x:L,y:V.y},V])},"addHorizontalPairCandidates"),Pt=d((N,F,D,V,h)=>{const b=[...u("left"),...u("right")];for(const C of u(D))for(const L of u(h))for(const w of b)P(N,[F,{x:F.x,y:C},{x:w,y:C},{x:w,y:L},{x:V.x,y:L},V])},"addVerticalPairCandidates"),Q=d(N=>{const F=new Set;return N.map(D=>pt(D)).filter(D=>{const V=D.map(h=>`${h.x.toFixed(3)},${h.y.toFixed(3)}`).join("|");return F.has(V)||D.length<2?!1:(F.add(V),!0)})},"dedupeCandidatePaths"),W=d((N,F,D,V)=>{const h=[],b=co(N,F,D,V,20,Z);b&&P(h,b),F===V&&J(h,N,F,D);const C=G(F),L=G(V);return C&&!L?dt(h,N,F,D,V):!C&&L?mt(h,N,F,D,V):C?kt(h,N,F,D,V):Pt(h,N,F,D,V),Q(h)},"buildCandidatesForSides"),et=d((N,F,D,V)=>{const h=[...u("left"),...u("right")],b=[...u("top"),...u("bottom")];for(const C of l){const L=Ie(V,C),w=C==="top"||C==="bottom"?u(C):b;for(const B of h){P(N,[F,D,{x:B,y:D.y},{x:B,y:L.y},L]);for(const U of w)P(N,[F,D,{x:B,y:D.y},{x:B,y:U},{x:L.x,y:U},L])}}},"addVerticalDepartureOuterTrackCandidates"),at=d((N,F,D,V)=>{const h=[...u("left"),...u("right")],b=[...u("top"),...u("bottom")];for(const C of l){const L=Ie(V,C),w=C==="left"||C==="right"?u(C):h;for(const B of b){P(N,[F,D,{x:D.x,y:B},{x:L.x,y:B},L]);for(const U of w)P(N,[F,D,{x:D.x,y:B},{x:U,y:B},{x:U,y:L.y},L])}}},"addHorizontalDepartureOuterTrackCandidates"),gt=d(N=>{const F=N.start,D=N.end,V=D?c.get(D):void 0;if(!F||!V)return[];const h=pt(N.points??[]);if(h.length<4)return[];const b=h[0],C=h[1],L=[];return wt(b,C,Z)?et(L,b,C,V):Tt(b,C,Z)&&at(L,b,C,V),L},"terminalPreservingOuterTrackCandidates"),xt=d(N=>{const F=N.start,D=N.end,V=F?c.get(F):void 0,h=D?c.get(D):void 0;if(!V||!h)return[];const b=[];for(const C of l){const L=Ie(V,C);for(const w of l)b.push(...W(L,C,Ie(h,w),w))}return b.push(...gt(N)),b},"candidatePathsFor"),vt=d(()=>new Map(x.map(N=>[N,it(p(N))])),"currentSegmentsByEdge"),Vt=d((N,F,D)=>{const V=new Set;for(const h of x){if(h===N)continue;const b=D.get(h)??it(p(h));F.some(C=>b.some(L=>ce(C,L,.5)>=_t))&&V.add(h)}return V},"sharedTrackConflictsFor"),jt=d((N,F,D,V)=>{const h=new Set;return xt(N).map(C=>ae(pt(C))).filter(C=>{if(H(N,C))return!1;const L=C.map(w=>`${w.x.toFixed(3)},${w.y.toFixed(3)}`).join("|");return h.has(L)||C.length<2?!1:(h.add(L),!0)}).map(C=>{const L=it(C);let w=0;for(const B of x)B!==N&&(w+=f(L,D.get(B)??it(p(B))));return{candidate:C,candidateSegments:L,crossings:F.count-(V.get(N)??0)+w,bends:Qt(C,Z),totalBends:Qt(C),length:R(C)}}).filter(({crossings:C})=>C<=F.count).sort((C,L)=>C.crossings-L.crossings||C.bends-L.bends||C.length-L.length).slice(0,48).map(C=>({path:C.candidate,segments:C.candidateSegments,sharedTrackConflicts:Vt(N,C.candidateSegments,D),totalBends:C.totalBends,length:C.length}))},"pairCandidatesFor"),Ut=d((N,F,D,V,h,b)=>{let C=0;for(const w of N.pairs)(w.first===F||w.second===F||w.first===V||w.second===V)&&(C+=w.count);let L=f(D.segments,h.segments);for(const w of x){if(w===F||w===V)continue;const B=b.get(w)??it(p(w));L+=f(D.segments,B)+f(h.segments,B)}return N.count-C+L},"pairCrossingCount"),te=d((N,F)=>{for(const D of N.sharedTrackConflicts)if(D!==F)return!1;return!0},"conflictsOnlyWith"),Se=d((N,F)=>N.segments.some(D=>F.segments.some(V=>ce(D,V,.5)>=_t)),"candidatesShareTrack"),de=d((N,F,D,V)=>te(F,D.edge)&&te(V,N.edge)&&!Se(F,V),"pairCandidatesAreCompatible"),Ce=d((N,F,D,V,h)=>{const b=Ut(N.current,F.edge,D,V.edge,h,N.baseSegments);if(!(b>=N.current.count))return{replacements:new Map([[F.edge,D.path],[V.edge,h.path]]),crossings:b,bends:N.currentBends-(N.baseBendsByEdge.get(F.edge)??0)-(N.baseBendsByEdge.get(V.edge)??0)+D.totalBends+h.totalBends,length:N.currentLength-(N.baseLengthByEdge.get(F.edge)??0)-(N.baseLengthByEdge.get(V.edge)??0)+D.length+h.length}},"scorePairReplacement"),dn=d((N,F)=>N.crossings<F.crossings||N.crossings===F.crossings&&(N.bends<F.bends||N.bends===F.bends&&N.length<F.length),"pairScoreIsBetter"),un=d((N,F,D,V)=>{let h=V;for(const b of F.candidates)for(const C of D.candidates){if(!de(F,b,D,C))continue;const L=Ce(N,F,b,D,C);L&&dn(L,h)&&(h=L)}return h},"bestScoreForOptionPair"),hn=d(N=>{const F=k(),D=O(),V=vt(),h=A(N),b=new Map(x.map(q=>[q,Qt(p(q))])),C=new Map(x.map(q=>[q,R(p(q))])),L=new Map,w=m(N);for(const q of w)for(const z of q){if(L.has(z))continue;const Y=jt(z,N,V,h);Y.length>0&&L.set(z,{edge:z,candidates:Y})}let B={replacements:new Map,crossings:N.count,bends:F,length:D};const U={current:N,currentBends:F,currentLength:D,baseBendsByEdge:b,baseLengthByEdge:C,baseSegments:V};for(const q of w){const z=new Set(q.filter(ot=>N.edgeSet.has(ot))),Y=q.map(ot=>L.get(ot)).filter(ot=>!!ot);for(let ot=0;ot<Y.length;ot++){const rt=Y[ot];for(let st=ot+1;st<Y.length;st++){const tt=Y[st];!z.has(rt.edge)&&!z.has(tt.edge)||(B=un(U,rt,tt,B))}}}return B.replacements.size>0?B.replacements:void 0},"bestPairedReplacement");for(let N=0;N<4;N++){const F=v(),D=F.count;if(D===0)return;let V,h,b=D,C=Number.POSITIVE_INFINITY;for(const w of F.edges){const B=Qt(p(w),Z);for(const U of xt(w)){const q=H(w,U),z=!q&&_(w,U),Y=S(F,w,U),ot=Qt(U,Z);q||z||!(Y<D||Y===D&&ot<B)||Y>b||Y===b&&ot>=C||(V=w,h=U,b=Y,C=ot)}}if(V&&h){V.points=h;continue}const L=hn(F);if(!L)return;for(const[w,B]of L)w.points=B}}d(vs,"resolveRenderedOrthogonalCrossings");var pe=.001,Wr=8;function Ls(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e),s=["top","bottom","left","right"],r=20,i={top:Math.min(...o.map(f=>f.rect.top))-r,bottom:Math.max(...o.map(f=>f.rect.bottom))+r,left:Math.min(...o.map(f=>f.rect.left))-r,right:Math.max(...o.map(f=>f.rect.right))+r},c=d((f,y,v,M)=>{const E=[],T=co(f,y,v,M,r,pe);return T&&E.push(T),y===M&&E.push(ao(f,y,v,i[y])),E},"buildOrthogonalPathCandidates"),a=d((f,y)=>{for(let v=0;v<f.length-1;v++){const M=f[v],E=f[v+1];if(At(M,E,o,y,1))return!0}return!1},"pathHitsNode"),l=d((f,y,v=!1)=>{let M=0;const E=Re(f,pe),T=y.start,m=y.end;for(const S of t){if(S===y||S.isLayoutOnly)continue;const A=S.start,R=S.end;if(!v&&T&&m&&(A===T||A===m||R===T||R===m))continue;const k=S.points;if(!(!k||k.length<2))for(const O of E)for(const _ of Re(k,pe)){if(fo(O.a,O.b,_.a,_.b,pe,pe)){M++;continue}ce(O,_,pe)>=Wr&&M++}}return M},"pathConflictCount"),g=4,x=d((f,y)=>{const v=Math.abs(f.y-y.rect.top),M=Math.abs(f.y-y.rect.bottom),E=Math.abs(f.x-y.rect.left),T=Math.abs(f.x-y.rect.right);let m="top",S=v;return M<S&&(m="bottom",S=M),E<S&&(m="left",S=E),T<S&&(m="right",S=T),m},"nearestSideOfRect"),I=new Map,u=d((f,y,v)=>{const M=I.get(f)??[];M.push({side:y,edgeId:v}),I.set(f,M)},"addFaceClaim");for(const f of t){if(f.isLayoutOnly)continue;const y=f.points??[];if(y.length<1)continue;const v=f.id??"",M=f.start,E=f.end;if(M){const T=n.get(M);T&&u(M,x(y[0],T),v)}if(E){const T=n.get(E);T&&u(E,x(y[y.length-1],T),v)}}const p=d((f,y,v)=>I.get(f)?.some(M=>M.edgeId!==v&&M.side===y)??!1,"faceIsClaimed");for(const f of t){if(f.isLayoutOnly)continue;const y=f.points;if(!y||y.length<2)continue;const v=Qt(y,pe);if(v<g)continue;const M=f.start,E=f.end;if(!M||!E)continue;const T=n.get(M),m=n.get(E);if(!T||!m)continue;const S=f.id??"",A=l(y,f,!0),R=l(y,f);let k,O=A,_=v;for(const H of s){if(p(M,H,S))continue;const P=Ie(T,H);for(const G of s){if(p(E,G,S))continue;const j=Ie(m,G);for(const J of c(P,H,j,G)){if(a(J,[M,E]))continue;const dt=Qt(J,pe);if(A>0){const mt=l(J,f,!0);if(mt>O||mt===O&&dt>=_)continue;O=mt,_=dt,k=J;continue}l(J,f)>R||dt<_&&(_=dt,k=J)}}}if(k){f.points=k;const H=I.get(M);H&&I.set(M,H.filter(G=>G.edgeId!==S));const P=I.get(E);P&&I.set(E,P.filter(G=>G.edgeId!==S)),u(M,x(k[0],T),S),u(E,x(k[k.length-1],m),S)}}}d(Ls,"simplifyDetouredEdges");var Kt=.001,Po=10,Ve=7;function $n(t,e){const n=e?0:t.length-1,o=e?1:-1,s=t[n],r=t[n+o];if(!s||!r)return;const i=r.x-s.x,c=r.y-s.y;if(!(Math.abs(i)+Math.abs(c)<Kt)){if(Math.abs(c)<=Kt){const l=s.x+Math.sign(i)*Po;return{left:Math.min(s.x,l),right:Math.max(s.x,l),top:s.y-Ve,bottom:s.y+Ve}}if(Math.abs(i)<=Kt){const l=s.y+Math.sign(c)*Po;return{left:s.x-Ve,right:s.x+Ve,top:Math.min(s.y,l),bottom:Math.max(s.y,l)}}return{left:Math.min(s.x,r.x),right:Math.max(s.x,r.x),top:Math.min(s.y,r.y),bottom:Math.max(s.y,r.y)}}}d($n,"markerClearanceRectFor");function Es(t){return{left:Math.min(t.left,t.right),right:Math.max(t.left,t.right),top:Math.min(t.top,t.bottom),bottom:Math.max(t.top,t.bottom)}}d(Es,"normalizeRect");function zn(t,e){const n=pt(e),o=$n(n,!0),s=$n(n,!1);return[o,s].some(r=>r&&Je(t,Es(r)))}d(zn,"labelOverlapsOwnMarker");function Ue(t,e){const n=[];for(const p of t){if(p.isLayoutOnly)continue;const f=p.points;if(!(!f||f.length<2))for(let y=0;y<f.length-1;y++)n.push({edgeId:p.id,p1:f[y],p2:f[y+1]})}const o=[],s=[];for(const p of e.values()){const f=p.isGroup,y=p.parentId;if(f&&!y){const M=qt(p);M&&s.push({id:p.id,rect:M});continue}if(f||p.isEdgeLabel)continue;const v=qt(p);v&&o.push({nodeId:p.id,rect:v})}const r=3,i=1,c=12,a=d((p,f)=>{const y=Tn(f,r);for(const{nodeId:v,rect:M}of o)if(v!==p&&Je(y,M))return!0;return!1},"labelOverlapsForeignNode"),l=d((p,f)=>{const y=Tn(f,r);for(const v of n)if(v.edgeId!==p&&cn(v.p1,v.p2,y))return!0;return!1},"labelOverlapsForeignEdge"),g=d((p,f,y)=>a(p,y)||l(f,y),"labelOverlapsAnything"),x=[],I=d(p=>{for(const{id:f,rect:y}of s)if(ts(y,p))return f},"findContainingLane"),u=d((p,f)=>x.some(y=>y.labelId!==p&&Je(f,y.rect)),"overlapsPlacedLabel");for(const p of t){if(p.isLayoutOnly)continue;const f=p.labelNodeId;if(!f)continue;const y=e.get(f);if(!y)continue;const v=p.points;if(!v||v.length<2)continue;const M=y.width??0,E=y.height??0;if(M<=0||E<=0)continue;const T=[];for(let Q=0;Q<v.length-1;Q++){const W=v[Q],et=v[Q+1],at=Math.abs(W.x-et.x),gt=Math.abs(W.y-et.y);at<Kt&><Kt||at>=Kt&>>=Kt||T.push({idx:Q,length:at+gt,orientation:at>=Kt?"horizontal":"vertical",midX:(W.x+et.x)/2,midY:(W.y+et.y)/2})}if(T.length===0)continue;const m=T.length>=3?T.filter(Q=>Q.idx>0&&Q.idx<T.length-1):T,S=m.length>0?m:T,A=M>=E?"horizontal":"vertical",R=d(Q=>[...Q].sort((W,et)=>{const at=W.orientation===A,gt=et.orientation===A;if(at!==gt)return at?-1:1;const xt=W.length>=(W.orientation==="horizontal"?M:E)+2,vt=et.length>=(et.orientation==="horizontal"?M:E)+2;return xt!==vt?xt?-1:1:et.length-W.length}),"rankSegments"),k=T[0],O=T[T.length-1],_=[.5,.25,.75,.05,.95,.15,.85,.1,.9],H=d((Q,W)=>{const et=v[Q.idx],at=v[Q.idx+1];return{midX:et.x+(at.x-et.x)*W,midY:et.y+(at.y-et.y)*W}},"anchorAtT"),P=d((Q,W,et)=>Math.min(et,Math.max(W,Q)),"clamp"),G=d((Q,W)=>Q.midX>=W.left-Kt&&Q.midX<=W.right+Kt&&Q.midY>=W.top-Kt&&Q.midY<=W.bottom+Kt,"pointInsideRectInclusive"),j=d(Q=>{const W=Ae(Q.midX,Q.midY,M,E),et=I(W);if(et)return{laneId:et,anchor:Q,rect:W};const at=s.find(({rect:te})=>G(Q,te));if(!at)return;const gt=at.rect.left+M/2+i,xt=at.rect.right-M/2-i,vt=at.rect.top+E/2+i,Vt=at.rect.bottom-E/2-i;if(gt>xt||vt>Vt)return;const jt={midX:P(Q.midX,gt,xt),midY:P(Q.midY,vt,Vt)},Ut=Ae(jt.midX,jt.midY,M,E);return G(Q,Ut)?{laneId:at.id,anchor:jt,rect:Ut}:void 0},"placementForAnchor"),J=d((Q,W,et)=>Q.orientation==="horizontal"?Math.abs(W.midX-et.x):Math.abs(W.midY-et.y),"distanceAlongSegment"),dt=d((Q,W)=>{const at=(Q.orientation==="horizontal"?M/2:E/2)+c;if(Q===k){const gt=v[Q.idx];if(J(Q,W,gt)+Kt<at)return!1}if(Q===O){const gt=v[Q.idx+1];if(J(Q,W,gt)+Kt<at)return!1}return!0},"labelClearsTerminalEndpoints"),mt=d(Q=>{const W=R(Q);for(const et of W)for(const at of _){const gt=H(et,at);if(!dt(et,gt))continue;const xt=j(gt);if(xt&&!zn(xt.rect,v)&&!u(f,xt.rect)&&!g(f,p.id,xt.rect))return{laneId:xt.laneId,anchor:xt.anchor}}},"tryPool"),kt=d((Q,W,et=!1)=>{const at=R(Q);for(const gt of at){const xt={midX:gt.midX,midY:gt.midY};if(W&&!dt(gt,xt))continue;const vt=j(xt);if(vt&&!zn(vt.rect,v)&&!u(f,vt.rect)&&!a(f,vt.rect)&&(et||!l(p.id,vt.rect)))return{laneId:vt.laneId,anchor:vt.anchor}}},"findLaneContainingFallback"),Pt=mt(S)??(S.length<T.length?mt(T):void 0)??kt(T,!0)??kt(T,!1)??kt(T,!1,!0);if(Pt){y.x=Pt.anchor.midX,y.y=Pt.anchor.midY,y.parentId=Pt.laneId;const Q=Ae(Pt.anchor.midX,Pt.anchor.midY,M,E),W=x.findIndex(et=>et.labelId===f);W>=0?x[W]={labelId:f,rect:Q}:x.push({labelId:f,rect:Q})}}}d(Ue,"anchorLabelsToPolyline");var Sn=1e-6,Kr=8,Bo=Kr/2,qr=3;function Vn(t,e){return t<e?`${t}::${e}`:`${e}::${t}`}d(Vn,"pairKey");function Ts(t,e){const{nodeInfoById:n,realNodeRects:o}=an(e),s=new Map;for(const i of e){const c=i.id;if(!i.isGroup&&i.isEdgeLabel){s.set(c,{w:i.width??0,h:i.height??0});continue}}const r=d((i,c,a,l)=>{const g=Vn(c,a);let x=0;const I=d(u=>{if(!u)return;const p=s.get(u);if(!p)return;const f=l==="x"?p.w/2:p.h/2;f>x&&(x=f)},"consider");I(i.labelNodeId);for(const u of t){if(u===i||u.isLayoutOnly)continue;const p=u.start,f=u.end;!p||!f||Vn(p,f)===g&&I(u.labelNodeId)}return x>0?x+qr:0},"labelClearanceFor");for(const i of t){if(i.isLayoutOnly)continue;const c=i.points;if(!ro(c,Sn))continue;const a=lo(i,n,Sn);if(!a)continue;const{srcId:l,dstId:g,srcInfo:x,dstInfo:I,collinearX:u,collinearY:p}=a;if(u===p)continue;let f,y;if(u){const m=I.cy>x.cy;f={x:x.cx,y:m?x.rect.bottom:x.rect.top},y={x:I.cx,y:m?I.rect.top:I.rect.bottom}}else{const m=I.cx>x.cx;f={x:m?x.rect.right:x.rect.left,y:x.cy},y={x:m?I.rect.left:I.rect.right,y:I.cy}}if(At(f,y,o,[l,g],1))continue;const M=r(i,l,g,u?"x":"y"),E=M>Bo?M:Bo,T=[0,E,-E];for(const m of T){const S={...f},A={...y};if(u){if(S.x+=m,A.x+=m,S.x<=x.rect.left||S.x>=x.rect.right||A.x<=I.rect.left||A.x>=I.rect.right)continue}else if(S.y+=m,A.y+=m,S.y<=x.rect.top||S.y>=x.rect.bottom||A.y<=I.rect.top||A.y>=I.rect.bottom)continue;if(!At(S,A,o,[l,g],1)&&!Ze(S,A,t,i,{epsilon:Sn})){i.points=[S,A];break}}}}d(Ts,"straightenCollinearSiblingDetours");function jn(t,e){const{realNodeRects:a,labelNodeRects:l}=me(e.values()),g=d((m,S)=>Re(S,.001).map(A=>({...A,edge:m,interior:A.index>=1&&A.index<=S.length-3})),"segmentsFor"),x=d(()=>{const m=[];for(const S of t){if(S.isLayoutOnly)continue;const A=S.points;!A||A.length<2||m.push(...g(S,pt(A)))}return m},"allSegments"),I=d((m,S)=>m.horizontal&&S.horizontal?zt(m.a.x,m.b.x,S.a.x,S.b.x)>=8&&Math.abs(m.a.y-S.a.y)<7:m.vertical&&S.vertical?zt(m.a.y,m.b.y,S.a.y,S.b.y)>=8&&Math.abs(m.a.x-S.a.x)<7:!1,"hasCrowdedParallelTrack"),u=d((m,S)=>{const A=m.start,R=m.end,k=g(m,S);if(k.length!==S.length-1)return!1;const O=[A,R].filter(H=>!!H),_=m.labelNodeId?[m.labelNodeId]:[];for(const H of k)if(At(H.a,H.b,a,O,-2)||At(H.a,H.b,l,_,-2))return!1;for(const H of t){if(H===m||H.isLayoutOnly)continue;const P=H.points;if(!(!P||P.length<2)){for(const G of k)for(const j of g(H,pt(P)))if(I(G,j)||le(G.a,G.b,j.a,j.b,.001))return!1}}return!0},"candidateIsSafe"),p=d((m,S)=>{const A=pt(m.edge.points??[]);if(A.length<4||m.index>=A.length-1)return;const R=A.map(k=>({...k}));if(m.horizontal)R[m.index].y+=S,R[m.index+1].y+=S;else if(m.vertical)R[m.index].x+=S,R[m.index+1].x+=S;else return;return g(m.edge,R).length===R.length-1?R:void 0},"shiftedCandidate"),f=d((m,S)=>({x:m.x??(S.left+S.right)/2,y:m.y??(S.top+S.bottom)/2}),"nodeCenter"),y=d(m=>{const S=m.edge,A=pt(S.points??[]);if(A.length!==4||m.index!==1)return;const R=S.start?e.get(S.start):void 0,k=S.end?e.get(S.end):void 0,O=R?qt(R):void 0,_=k?qt(k):void 0,H=A.slice(m.index+2);if(!(!R||!k||!O||!_||H.length===0))return{sourceCenter:f(R,O),targetCenter:f(k,_),sourceRect:O,tail:H}},"sourceDetourContextFor"),v=d((m,S,A,R,k,O)=>{const _=R.y>=A.y,H=_?k.bottom:k.top,P=H+(_?20:-20);if(_&&m.b.y<=P+.001||!_&&m.b.y>=P-.001)return;const G=m.a.x+S;return pt([{x:A.x,y:H},{x:A.x,y:P},{x:G,y:P},{x:G,y:m.b.y},...O],.001)},"verticalSourceDetour"),M=d((m,S,A,R,k,O)=>{const _=R.x>=A.x,H=_?k.right:k.left,P=H+(_?20:-20);if(_&&m.b.x<=P+.001||!_&&m.b.x>=P-.001)return;const G=m.a.y+S;return pt([{x:H,y:A.y},{x:P,y:A.y},{x:P,y:G},{x:m.b.x,y:G},...O],.001)},"horizontalSourceDetour"),E=d((m,S)=>{const A=y(m);if(A){if(m.vertical)return v(m,S,A.sourceCenter,A.targetCenter,A.sourceRect,A.tail);if(m.horizontal)return M(m,S,A.sourceCenter,A.targetCenter,A.sourceRect,A.tail)}},"sourceDetourCandidate"),T=[-7,7,-14,14,-21,21];for(let m=0;m<12;m++){const S=x();let A=!1;for(let R=0;R<S.length&&!A;R++)for(let k=R+1;k<S.length&&!A;k++){const O=S[R],_=S[k];if(O.edge===_.edge||!I(O,_))continue;const H=[O,_].filter(P=>P.interior);for(const P of H){for(const G of T){const j=p(P,G);if(j&&u(P.edge,j)){P.edge.points=j,A=!0;break}const J=E(P,G);if(J&&u(P.edge,J)){P.edge.points=J,A=!0;break}}if(A)break}}if(!A)return}}d(jn,"nudgeSharedInteriorSubpaths");function ws(t,e,n,o){const s=e.x-t.x,r=e.y-t.y,i=o.x-n.x,c=o.y-n.y,a=s*c-r*i;if(Math.abs(a)<1e-10)return!1;const l=n.x-t.x,g=n.y-t.y,x=(l*c-g*i)/a,I=(l*r-g*s)/a,u=.01;return x>u&&x<1-u&&I>u&&I<1-u}d(ws,"segmentsIntersect");function As(t){const e=t.nodes??[],n=t.edges??[],o=[];if(!n.length||!e.length)return o;const s=es(e),r=[];for(const c of n){if(c.isLayoutOnly)continue;const a=c.points;if(!a||a.length<2)continue;const l=c.start,g=c.end,x=c.labelNodeId,I=c.id??`${l}->${g}`;for(const u of s)if(!(u.nodeId===l||u.nodeId===g)&&!(x&&u.nodeId===x)){for(let p=0;p<a.length-1;p++)if(cn(a[p],a[p+1],u,-1)){o.push({type:"edge-node-overlap",edgeId:I,targetId:u.nodeId,detail:`segment ${p} passes through node "${u.nodeId}"`});break}}for(let u=0;u<a.length-1;u++)r.push({edgeId:I,start:l,end:g,p1:a[u],p2:a[u+1]})}const i=new Set;for(let c=0;c<r.length;c++)for(let a=c+1;a<r.length;a++){const l=r[c],g=r[a];if(l.edgeId!==g.edgeId&&!(l.start===g.start||l.start===g.end||l.end===g.start||l.end===g.end)&&ws(l.p1,l.p2,g.p1,g.p2)){const x=l.edgeId<g.edgeId?`${l.edgeId}|${g.edgeId}`:`${g.edgeId}|${l.edgeId}`;i.has(x)||(i.add(x),o.push({type:"edge-edge-crossing",edgeId:l.edgeId,targetId:g.edgeId,detail:`edges "${l.edgeId}" and "${g.edgeId}" cross`}))}}if(o.length>0){const c=o.filter(l=>l.type==="edge-node-overlap").length,a=o.filter(l=>l.type==="edge-edge-crossing").length;Ke.warn(`[SWIMLANE_VALIDATE] ${o.length} issue(s) detected: ${c} edge-node overlap(s), ${a} edge crossing(s)`);for(const l of o)Ke.warn(`[SWIMLANE_VALIDATE] ${l.type}: ${l.detail}`)}return o}d(As,"validateSwimlanesLayout");function Rs(t,e){const n=t.nodes??[],o=t.edges??[],s=n.filter(c=>!c.isGroup);if((e==="LR"||e==="RL")&&s.length>0&&!ms(t,e)||e==="BT"&&s.length>0&&!ps(t))return;for(const c of o){if(c.isLayoutOnly)continue;const a=c.points;!a||a.length<2||(c.points=ae(Qe(a)))}Ls(o,n),Ts(o,n),ys(o,n);const r=new Map;for(const c of n)r.set(String(c.id),c);Ue(o,r),is(o,r),xs(o,r),jn(o,r),bs(o,r),Ms(o,r),Xn(o,r),Is(o,r);const i=d(()=>{vs(o,r),Ss(o,r),Cs(o,r),Ue(o,r),Dn(o,r),Xn(o,r),Ue(o,r),Dn(o,r)},"finalizeRenderedEdges");i(),jn(o,r),i(),Yn(o,r),Gn(o,r),Yn(o,r),Gn(o,r)}d(Rs,"postProcessSwimlaneLayout");function ye(t){const e=new Map(t.nodeById),n=new Set,o=[];for(const r of t.edges){if(!e.has(r.src)||!e.has(r.dst))continue;const i=`${r.id}:${r.src}->${r.dst}`;n.has(i)||(n.add(i),o.push(r))}return{nodes:[...e.keys()],edges:o,layout:t.layout,nodeById:e}}d(ye,"normalizeGraph");function mo(t,e){return t.edges.filter(n=>n.dst===e)}d(mo,"incoming");function Ns(t){const e=new Map;for(const n of t.nodes)e.set(n,[]);for(const n of t.edges)e.get(n.src).push(n.dst);return e}d(Ns,"buildSuccessorMap");function yo(t){const e=Ns(t);for(const n of e.values())n.sort((o,s)=>o.localeCompare(s));return e}d(yo,"buildSortedSuccessorMap");function xo(t){const e=new Map;for(const n of t.nodes)e.set(n,0);for(const n of t.edges)e.set(n.dst,(e.get(n.dst)??0)+1);return e}d(xo,"buildInDegreeMap");function bo(t){return[...t.entries()].filter(([,e])=>e===0).map(([e])=>e).sort((e,n)=>e.localeCompare(n))}d(bo,"sortedZeroInDegreeNodes");function ln(t,e=()=>!0){const n=new Map,o=new Map;for(const s of t.nodes)n.set(s,[]),o.set(s,[]);for(const s of t.edges)e(s)&&(o.get(s.src).push(s.dst),n.get(s.dst).push(s.src));return{preds:n,succs:o}}d(ln,"buildPredecessorSuccessorMaps");function Mo(t,e,n,o){let s=0;for(const i of t.nodes)o?.skipGroups&&t.nodeById.get(i)?.isGroup||(s=Math.max(s,n[i]??0));const r=Array.from({length:s+1},()=>[]);for(const i of e)o?.skipGroups&&t.nodeById.get(i)?.isGroup||r[Math.max(0,n[i]??0)].push(i);return r}d(Mo,"buildLayersFromRanks");function Be(t){const e=xo(t),n=bo(e),o=[],s=yo(t);for(;n.length;){const r=n.shift();o.push(r);for(const i of s.get(r)??[])if(e.set(i,(e.get(i)??0)-1),(e.get(i)??0)===0){let c=0;for(;c<n.length&&n[c]<i;)c++;n.splice(c,0,i)}}return o.length===t.nodes.length?o:null}d(Be,"topoSortIfAcyclic");function Ne(t){const e=new Map;let n=0;for(const o of t)e.set(o,n),n++;return e}d(Ne,"buildLayerIndex");function Io(t){const e=new Array(t.length),n=d((o,s)=>{if(s-o<=1)return 0;const r=o+s>>1;let i=n(o,r)+n(r,s),c=o,a=r,l=o;for(;c<r||a<s;)a>=s||c<r&&t[c]<=t[a]?e[l++]=t[c++]:(e[l++]=t[a++],i+=r-c);for(let g=o;g<s;g++)t[g]=e[g];return i},"count");return n(0,t.length)}d(Io,"countInversions");function Os(t){const e=ye(t),n=new Map;for(const g of e.nodes)n.set(g,[]);for(const g of e.edges)n.get(g.src).push(g);for(const g of n.values())g.sort((x,I)=>x.dst===I.dst?x.id.localeCompare(I.id):x.dst.localeCompare(I.dst));const o=Object.create(null);for(const g of e.nodes)o[g]=0;const s=[],r=d(g=>{o[g]=1;for(const x of n.get(g)??[]){const I=x.dst;o[I]===0?r(I):o[I]===1&&s.push(x)}o[g]=2},"dfs"),i=[...e.nodes].sort((g,x)=>g.localeCompare(x));for(const g of i)o[g]===0&&r(g);const c=new Set(s.map(g=>`${g.id}:${g.src}->${g.dst}`)),a=e.edges.map(g=>c.has(`${g.id}:${g.src}->${g.dst}`)?{id:g.id,src:g.dst,dst:g.src,weight:g.weight,ref:g.ref}:g);return{acyclic:{nodes:[...e.nodes],edges:a,layout:e.layout,nodeById:new Map(e.nodeById)},reversed:s}}d(Os,"removeCycles_DFS");function Ps(t){const e=new Map,n=d(o=>{if(e.has(o))return e.get(o);const s=t.nodeById.get(o);if(!s)return e.set(o,null),null;const r=s.parentId;if(!r)return e.set(o,null),null;const c=n(r)??r;return e.set(o,c),c},"resolve");for(const o of t.nodes)n(o);return e}d(Ps,"buildTopLaneMap");function fe(t){const e=Ps(t);return n=>e.get(n)??null}d(fe,"createTopLaneResolver");function fn(t){const e=[];for(const n of t.layout.nodes??[])n.isGroup&&!n.parentId&&e.push(n.id);return[...new Set(e)].reverse()}d(fn,"buildTopLaneOrder");function So(t,e){const n=fn(t);if(!e||e.length===0)return n;const o=new Set(n),s=new Set,r=[];for(const i of e)!o.has(i)||s.has(i)||(s.add(i),r.push(i));for(const i of n)s.has(i)||r.push(i);return r}d(So,"resolveTopLaneOrder");var Jr={EPSILON:1e-6},sn={GRAVITY_ITERATIONS:8,MAX_CROSSING_OPTIMIZATION_PASSES:4,DEFAULT_COMPACT_SINGLE_INPUT:!0},ko={DEFAULT_LAYER_GAP:100,DEFAULT_NODE_GAP:40};function Bs(t,e){const n=ye(t),o=e?.laneOf??(()=>null),s=e?.rankHint,{preds:r}=ln(n);for(const m of r.values())m.sort((S,A)=>S.localeCompare(A));const i=Be(n)??[...n.nodes].sort((m,S)=>m.localeCompare(S)),c=new Map;for(const[m,S]of i.entries())c.set(S,m);const a=new Map,l=new Map;for(const m of n.nodes)l.set(m,[]);for(const m of i){const S=(r.get(m)??[]).filter(A=>a.has(A));if(S.length>0){const A=ks(m,S,{laneOf:o,rankHint:s,topoIndex:c});a.set(m,A),l.get(A).push(m)}else a.has(m)||a.set(m,null)}for(const m of n.nodes)a.has(m)||a.set(m,null);const g=new Set;for(const m of n.nodes)(a.get(m)??null)===null&&g.add(m);const x=[...g].sort((m,S)=>{const A=c.get(m)??0,R=c.get(S)??0;return A===R?m.localeCompare(S):A-R}),I=_s(n),u=new Map;for(const[m,S]of I.entries())u.set(m,[...S].sort((A,R)=>A.localeCompare(R)));const p=Fs(u),f=Ds(u),y=new Map;for(const m of n.nodes)y.set(m,[]);for(const m of f)for(const S of m.nodes){const A=y.get(S);A?A.push(m.id):y.set(S,[m.id])}const v=[],M=[],E=new Set,T=d(m=>{if(!E.has(m)){E.add(m),v.push(m);for(const S of l.get(m)??[])T(S);M.push(m)}},"walk");for(const m of x)T(m);for(const m of i)T(m);return{parent:a,children:l,roots:x,componentOf:p,blocks:f,nodeBlocks:y,adjacency:u,preorder:v,postorder:M,topologicalOrder:i}}d(Bs,"buildDrivingTree");function ks(t,e,n){const o=n.laneOf(t);return[...e].sort((r,i)=>{const c=n.laneOf(r),a=n.laneOf(i),l=c!=null&&c===o,g=a!=null&&a===o;if(l!==g)return l?-1:1;const x=n.rankHint?.[r],I=n.rankHint?.[i];if(x!=null&&I!=null&&x!==I)return I-x;const u=n.topoIndex.get(r)??0,p=n.topoIndex.get(i)??0;return u!==p?u-p:r.localeCompare(i)})[0]}d(ks,"chooseParent");function _s(t){const e=new Map;for(const n of t.nodes)e.set(n,new Set);for(const n of t.edges)e.get(n.src).add(n.dst),e.get(n.dst).add(n.src);return e}d(_s,"buildAdjacency");function Fs(t){const e=new Map;let n=0;for(const o of t.keys()){if(e.has(o))continue;const s=[o];for(;s.length>0;){const r=s.pop();if(!e.has(r)){e.set(r,n);for(const i of t.get(r)??[])e.has(i)||s.push(i)}}n++}return e}d(Fs,"assignComponents");function Ds(t){const e=new Map,n=new Map,o=[],s=[];let r=0;const i=d((c,a)=>{e.set(c,++r),n.set(c,r);for(const l of t.get(c)??[])l!==a&&(e.has(l)?(e.get(l)??0)<(e.get(c)??0)&&(o.push([c,l]),n.set(c,Math.min(n.get(c)??r,e.get(l)??r))):(o.push([c,l]),i(l,c),n.set(c,Math.min(n.get(c)??r,n.get(l)??r)),(n.get(l)??0)>=(e.get(c)??0)&&s.push(Hs(c,l,o,s.length))))},"visit");for(const c of t.keys())e.has(c)||i(c,null);return s}d(Ds,"computeBlocks");function Hs(t,e,n,o){const s=[],r=new Set;for(;n.length>0;){const i=n.pop();if(s.push(i),r.add(i[0]),r.add(i[1]),i[0]===t&&i[1]===e||i[0]===e&&i[1]===t)break}return{id:o,edges:s,nodes:[...r]}}d(Hs,"popBlock");function Xs(t,e,n){const o=[...t.nodes],s=new Map;for(const[M,E]of o.entries())s.set(E,M);const r=o.length,i=new Array(r).fill(-1),c=new Array(r).fill(0),a=[],l=new Set;for(const M of o){const E=n.parent.get(M)??null,T=s.get(M);T!=null&&E==null&&(i[T]=-1,c[T]=0,l.has(M)||(l.add(M),a.push(M)))}for(;a.length>0;){const M=a.shift(),E=s.get(M);if(E==null)continue;const T=n.children.get(M)??[];for(const m of T){if(l.has(m))continue;const S=s.get(m);S!=null&&(i[S]=E,c[S]=c[E]+1,l.add(m),a.push(m))}}for(const M of o){if(l.has(M))continue;const E=s.get(M);E!=null&&(i[E]=-1,c[E]=0,l.add(M))}const g=Math.max(1,Math.ceil(Math.log2(Math.max(1,r)))+1),x=Array.from({length:g},()=>new Array(r).fill(-1));for(let M=0;M<r;M++)x[0][M]=i[M];for(let M=1;M<g;M++)for(let E=0;E<r;E++){const T=x[M-1][E];x[M][E]=T===-1?-1:x[M-1][T]}const I=d((M,E)=>{if(M===-1||E===-1)return-1;c[M]<c[E]&&([M,E]=[E,M]);const T=c[M]-c[E];for(let m=0;m<g;m++)if(T>>m&1&&(M=x[m][M],M===-1))return-1;if(M===E)return M;for(let m=g-1;m>=0;m--){const S=x[m][M],A=x[m][E];S===-1||A===-1||S!==A&&(M=S,E=A)}return x[0][M]},"lcaIndex"),u=Array.from({length:r},()=>new Map);for(const M of t.edges){let E=M.src,T=M.dst,m=e[E],S=e[T];if(m==null||S==null||(m>S&&([E,T]=[T,E],[m,S]=[S,m]),m==null||S==null||m===S))continue;const A=s.get(E),R=s.get(T);if(A==null||R==null)continue;const k=I(A,R);if(k===-1)continue;const O=u[k];for(let _=m;_<S;_++)O.set(_,(O.get(_)??0)+1)}const p=new Map,f=d((M,E)=>{if(E.size!==0)for(const[T,m]of E)M.set(T,(M.get(T)??0)+m)},"mergeInto"),y=new Set,v=d(M=>{const E=s.get(M);y.add(M);const T=E==null?void 0:u[E],m=T?new Map(T):new Map,S=n.children.get(M)??[];for(const A of S){const R=v(A),k=e[M];if(k!=null){let O=p.get(M);O||(O=new Map,p.set(M,O));let _=R.get(k)??0;const H=e[A];H!=null&&H>k&&(_+=1),O.set(A,_)}f(m,R)}return m},"dfs");for(const M of n.roots)y.has(M)||v(M);for(const M of o)y.has(M)||v(M);return p}d(Xs,"computeSubtreeCrossCounts");function Ys(t,e,n){const o=new Map,s=d(r=>{let i=n[r]??0;const c=[...e.get(r)??[]];c.sort(Co(n));for(const a of c){s(a);const l=o.get(a);l!=null&&(i=Math.min(i,l))}o.set(r,i)},"annotate");for(const r of t)s(r);return o}d(Ys,"annotateMinimumLayers");function Co(t){return(e,n)=>{const o=t[e]??0,s=t[n]??0;return o===s?e.localeCompare(n):o-s}}d(Co,"compareByRankThenId");function Gs(t,e,n,o){let s=0;for(const a of e){const l=n[a]??0;l>s&&(s=l)}const r=Array.from({length:s+1},()=>[]),i=new Set,c=d(a=>{if(i.has(a))return;i.add(a);const l=n[a]??0;r[l]||(r[l]=[]),r[l].push(a);for(const g of o(a))c(g)},"emit");for(const a of t)c(a);for(const a of e)if(!i.has(a)){const l=n[a]??0;r[l]||(r[l]=[]),r[l].push(a),i.add(a)}return r}d(Gs,"emitNodesInTreeOrder");function $s(t){const e=[];for(const n of t){const o=new Set,s=[];for(const r of n)o.has(r)||(o.add(r),s.push(r));e.push(s)}return e}d($s,"deduplicateLayers");function zs(t,e,n,o){return s=>{const r=t.get(s)??[];if(r.length===0)return[];const i=e[s]??0,c=[],a=[],l=n.get(s);for(const g of r){const x=o.get(g)??i;x>i?c.push({child:g,min:x}):a.push(g)}return c.sort((g,x)=>g.min===x.min?g.child.localeCompare(x.child):g.min-x.min),a.sort((g,x)=>{const I=l?.get(g)??0,u=l?.get(x)??0;if(I!==u)return I-u;const p=o.get(g)??i,f=o.get(x)??i;return p!==f?p-f:g.localeCompare(x)}),[...c.map(g=>g.child),...a]}}d(zs,"createChildOrderer");function rn(t,e,n){const o=Bs(t,{rankHint:e,laneOf:n}),{children:s,roots:r}=o;for(const x of t.nodes)s.has(x)||s.set(x,[]);const i=Xs(t,e,o),c=[...r].sort(Co(e)),a=Ys(c,s,e),l=zs(s,e,i,a);let g=Gs(c,t.nodes,e,l);return g=$s(g),g}d(rn,"buildMultitreeLayerOrder");function Vs(t,e,n){const o=new Set(t),s=new Set(e),r=Ne(e),i=[];for(const c of n)o.has(c.src)&&s.has(c.dst)&&i.push(r.get(c.dst));return Io(i)}d(Vs,"countCrossingsBetweenAdjacent");function Un(t,e,n){const o=[];for(const r of e){const i=n[r.src],c=n[r.dst];if(i==null||c==null||i===c)continue;let a=r.src,l=r.dst,g=i,x=c;i>c&&(a=r.dst,l=r.src,g=c,x=i);for(let I=g;I<x;I++)o.push({id:`${r.id}@${I}`,src:a,dst:l,ref:r.ref})}let s=0;for(let r=0;r+1<t.length;r++)s+=Vs(t[r],t[r+1],o);return s}d(Un,"totalCrossings");function js(t,e){const n={...e},{preds:o}=ln(t),s=fe(t),r=rn(t,n,s);let i=Un(r,t.edges,n);const c=sn.MAX_CROSSING_OPTIMIZATION_PASSES;for(let a=0;a<c;a++){let l=!1;const g=[...t.nodes].sort((x,I)=>(n[I]??0)-(n[x]??0));for(const x of g){const I=n[x]??0;if(I===0)continue;let u=0;for(const v of o.get(x)??[])u=Math.max(u,(n[v]??0)+1);if(u>=I)continue;const p=I;n[x]=u;const f=rn(t,n,s),y=Un(f,t.edges,n);y<i?(i=y,l=!0):n[x]=p}if(!l)break}return n}d(js,"optimizeRanksByCrossings");function Us(t,e){const n=fe(t),o=[...t.nodes].sort((s,r)=>(e[s]??0)-(e[r]??0)||s.localeCompare(r));for(const s of o){const r=n(s);if(!r)continue;const i=t.edges.filter(f=>f.src===s);if(i.length===0)continue;let c=!1,a=0;for(const f of i){const y=n(f.dst);y==null||y===r?c=!0:a++}if(a===0||c)continue;let l=0,g=!1;for(const f of t.edges){if(f.dst!==s)continue;const y=n(f.src);y&&(y===r?g=!0:l++)}if(l>0||!g)continue;const x=e[s]??0,I=x+a;let u=0;for(const f of t.edges)f.dst===s&&(u=Math.max(u,(e[f.src]??0)+1));const p=Math.max(x,u,I);p!==x&&(e[s]=p)}}d(Us,"adjustCrossLaneSources");function Ws(t,e){const n=ye(t),o=Be(n)??[...n.nodes].sort(),s=e?.compactSingleInput??!1,r=fe(n);let i=Object.create(null);for(const a of o){const l=mo(n,a),g=e?.ignoreCrossLaneEdges?l.filter(x=>{const I=r(x.src),u=r(a);return!I||!u?!0:I===u}):l;if(g.length===0)i[a]=0;else if(s&&g.length===1){const x=g[0].src,I=r(x),u=r(a);I!==u?i[a]=i[x]??0:i[a]=(i[x]??0)+1}else{let x=-1/0;for(const I of g)x=Math.max(x,(i[I.src]??0)+1);i[a]=x===-1/0?0:x}}return(e?.optimizeRanksByCrossings??!1)&&(i=js(n,i)),e?.ignoreCrossLaneEdges&&Us(n,i),{layers:rn(n,i,r),rankOf:i,dummy:new Set}}d(Ws,"assignLayers_LongestPath");function Ks(t,e){const n=ye(t),s={...Ws(n,{compactSingleInput:e?.compactSingleInput,ignoreCrossLaneEdges:e?.ignoreCrossLaneEdges,optimizeRanksByCrossings:e?.optimizeRanksByCrossings}).rankOf},r=fe(n),{preds:i,succs:c}=ln(n,p=>{if(e?.ignoreCrossLaneEdges){const f=r(p.src),y=r(p.dst);if(f&&y&&f!==y)return!1}return!0}),a=Be(n)??[...n.nodes],l=[...a].reverse(),g=d((p,f)=>{let y=0;for(const E of i.get(p)??[])y=Math.max(y,(s[E]??0)+1);let v=Number.POSITIVE_INFINITY;const M=c.get(p)??[];return M.length>0&&(v=Math.min(...M.map(E=>(s[E]??0)-1))),Number.isFinite(v)||(v=Math.max(y,f)),Math.min(Math.max(f,y),v)},"clampFeasible"),x=sn.GRAVITY_ITERATIONS,I=d(p=>{let f=!1;for(const y of p){const v=i.get(y)??[],M=c.get(y)??[];if(v.length===0&&M.length===0)continue;const E=v.length>0?v.reduce((A,R)=>A+(s[R]??0)+1,0)/v.length:s[y]??0,T=M.length>0?M.reduce((A,R)=>A+(s[R]??0)-1,0)/M.length:s[y]??0,m=Math.round((E+T)/2),S=g(y,m);S!==s[y]&&(s[y]=S,f=!0)}return f},"relaxOrder");for(let p=0;p<x;p++){const f=I(a),y=I(l);if(!f&&!y)break}for(const p of a){let f=0;for(const y of i.get(p)??[])f=Math.max(f,(s[y]??0)+1);(s[p]??0)<f&&(s[p]=f)}for(const p of l){const f=c.get(p)??[];if(f.length>0){const y=Math.min(...f.map(v=>(s[v]??0)-1));(s[p]??0)>y&&(s[p]=y)}}return{layers:Mo(n,a,s),rankOf:s,dummy:new Set}}d(Ks,"assignLayers_Gravity");function qs(t){const e=xo(t),n=yo(t);let o=bo(e);const s=[];for(;o.length>0;){const r=[];for(const i of o){s.push(i);for(const c of n.get(i)??[])e.set(c,(e.get(c)??0)-1),(e.get(c)??0)===0&&r.push(c)}o=r.sort((i,c)=>i.localeCompare(c))}return s.length===t.nodes.length?s:null}d(qs,"topoSortByGenerationIfAcyclic");function Js(t,e){const n=ye(t),o=e?.direction==="LR"?qs(n)??[...n.nodes].sort():Be(n)??[...n.nodes].sort(),s=fe(n),r=d(g=>s(g)??g,"laneOf"),i=Object.create(null),c=new Map,a=d((g,x)=>e?.ignoreCrossLaneEdges??!0?r(g)===r(x)?1:0:1,"edgeWeight");for(const g of o){if(n.nodeById.get(g)?.isGroup)continue;const I=mo(n,g);let u=0;if(I.length>0)for(const v of I){const M=v.src,E=i[M]??0;u=Math.max(u,E+a(M,g))}const p=r(g),f=c.get(p)??0,y=Math.max(u,f);i[g]=y,c.set(p,y+1)}return{layers:Mo(n,o,i,{skipGroups:!0}),rankOf:i,dummy:new Set}}d(Js,"assignLayers_LaneAwareCompact");function Zs(t,e){const n=ye(e),{rankOf:o}=t,s=t.layers.map(u=>[...u]),r=new Set(t.dummy?[...t.dummy]:[]);let i=0;const c=new Map(n.nodeById),a=d(u=>{const p=`placeholder-${i++}`,f={id:p,isGroup:!1,isDummy:!0,width:0,height:0};for(c.set(p,f),r.add(p);s.length<=u;)s.push([]);return s[u].push(p),o[p]=u,p},"addDummyAt"),l=[...n.edges].sort((u,p)=>u.id===p.id?u.src===p.src?u.dst.localeCompare(p.dst):u.src.localeCompare(p.src):u.id.localeCompare(p.id)),g=[];for(const u of l){const p=o[u.src]??0,f=o[u.dst]??0;if(f-p<=1){g.push(u);continue}let y=u.src;for(let M=p+1,E=0;M<f;M++,E++){const T=a(M);g.push({id:`${u.id}#${E}`,src:y,dst:T,weight:u.weight,ref:u.ref}),y=T}const v=f-p-2;g.push({id:`${u.id}#${Math.max(v+1,0)}`,src:y,dst:u.dst,weight:u.weight,ref:u.ref})}const I={nodes:[...n.nodes,...[...r].filter(u=>!n.nodes.includes(u))],edges:g,layout:n.layout,nodeById:c};return{layering:{layers:s,rankOf:o,dummy:r},graphWithDummies:I}}d(Zs,"makeProperLayering");function Wn(t){const e=t.length;if(e===0)return Number.POSITIVE_INFINITY;const n=[...t].sort((o,s)=>o-s);return e%2===1?n[(e-1)/2]:.5*(n[e/2-1]+n[e/2])}d(Wn,"median");function Kn(t){return t.length===0?Number.POSITIVE_INFINITY:t.reduce((n,o)=>n+o,0)/t.length}d(Kn,"barycenter");function Qs(t,e,n,o){const s=new Map;for(const r of t)s.set(r,[]);for(const r of n)o==="down"?e.has(r.src)&&s.has(r.dst)&&s.get(r.dst).push(e.get(r.src)):e.has(r.dst)&&s.has(r.src)&&s.get(r.src).push(e.get(r.dst));return s}d(Qs,"neighborPositionsFor");function tr(t,e,n){const o=n.get(t)??0,s=n.get(e)??0;return o!==s?o-s:t.localeCompare(e)}d(tr,"currentOrderTieBreak");function qn(t,e,n){const o=new Set(t),s=new Set(e),r=Ne(t),i=Ne(e),c=[];for(const l of n)o.has(l.src)&&s.has(l.dst)&&c.push({u:r.get(l.src),v:i.get(l.dst)});c.sort((l,g)=>l.u===g.u?l.v-g.v:l.u-g.u);const a=c.map(l=>l.v);return Io(a)}d(qn,"countCrossingsBetweenAdjacent");function We(t,e,n){return[...t].sort((o,s)=>{const r=Wn(e.get(o)??[]),i=Wn(e.get(s)??[]);return r===i?tr(o,s,n):isFinite(r)?isFinite(i)?r-i:-1:1})}d(We,"sortByHeuristic");function Jn(t,e,n,o,s,r){const i=Ne(t),c=Ne(e),a=Qs(e,i,n,o);if(!s||!r||r.length===0)return We(e,a,c);const l=new Map;for(const I of e){const u=s(I),p=l.get(u)??[];p.push(I),l.set(u,p)}const g=[];for(const I of r){const u=l.get(I);if(!u||u.length===0)continue;const p=We(u,a,c);g.push(...p)}const x=l.get(null);if(x&&x.length>0){const I=We(x,a,c);for(const u of I){const p=Kn(a.get(u)??[]);let f=g.length;if(isFinite(p))for(const[y,v]of g.entries()){const M=Kn(a.get(v)??[]);if(p<M){f=y;break}}g.splice(f,0,u)}}return g}d(Jn,"reorderLayer");function Zn(t,e,n,o,s){const r=[...e],i=new Set(t),c=new Set(e),a=o?new Set(o):null,l=n.filter(f=>i.has(f.src)&&c.has(f.dst)),g=a?n.filter(f=>c.has(f.src)&&a.has(f.dst)):void 0,x=d(f=>{let y=qn(t,f,l);return g&&o&&(y+=qn(f,o,g)),y},"crossingScore"),I=s?new Map:null;if(s&&I)for(const f of e)I.set(f,s(f));let u=!0,p=x(r);for(;u;){u=!1;for(let f=0;f+1<r.length;f++){if(I){const M=I.get(r[f]),E=I.get(r[f+1]);if(M!==E)continue}const y=p;[r[f],r[f+1]]=[r[f+1],r[f]];const v=x(r);v<y?(p=v,u=!0):[r[f],r[f+1]]=[r[f+1],r[f]]}}return r}d(Zn,"transposeImprove");function er(t,e,n){const o=t.layers.map(c=>[...c]),s=e.edges,r=fe(e),i=So(e,n?.laneOrder);for(let c=0;c<3;c++){for(let a=1;a<o.length;a++)o[a]=Jn(o[a-1],o[a],s,"down",r,i),o[a]=Zn(o[a-1],o[a],s,o[a+1],r);for(let a=o.length-2;a>=0;a--)o[a]=Jn(o[a+1],o[a],s,"up",r,i),o[a]=Zn(o[a+1],o[a],s,o[a-1],r)}return{layers:o}}d(er,"orderLayers");function nr(t,e,n){const o=n?.layerGap??ko.DEFAULT_LAYER_GAP,s=n?.nodeGap??ko.DEFAULT_NODE_GAP,r=n?.laneGap??s*2,i=n?.direction??"TB",c=i==="LR"||i==="RL",a=t.layers,l=Object.create(null),g=Object.create(null),x=d(O=>e.nodeById.get(O),"getNode"),I=d(O=>x(O)?.width??0,"getWidth"),u=d(O=>x(O)?.height??0,"getHeight"),p=fe(e),f=So(e,n?.laneOrder),y=a.map(O=>O.reduce((_,H)=>Math.max(_,u(H)),0)),v=[];if(c)for(let O=0;O+1<a.length;O++){const _=a[O].reduce((mt,kt)=>Math.max(mt,I(kt)),0),H=a[O+1].reduce((mt,kt)=>Math.max(mt,I(kt)),0),P=y[O],G=y[O+1],j=P/2+G/2,J=(_+H)/2,dt=Math.max(0,J-j-o);v.push(dt)}const M=new Set;for(const O of a)for(const _ of O)M.add(p(_));const E=M.has(null),T=f.filter(O=>M.has(O)),m=[...E?[null]:[],...T],S=Object.create(null);for(const O of T)S[O]=0;E&&(S.null=0);for(const O of a){const _=Object.create(null),H=[];for(const P of O){const G=p(P);G===null?H.push(P):(_[G]||=[]).push(P)}for(const[P,G]of Object.entries(_)){const j=G.reduce((J,dt)=>J+I(dt),0)+s*Math.max(0,G.length-1);S[P]=Math.max(S[P]??0,j)}if(E&&H.length){const P=H.reduce((G,j)=>G+I(j),0)+s*Math.max(0,H.length-1);S.null=Math.max(S.null??0,P)}}const A=new Map;{const O=m.map(P=>(P===null?S.null:S[P])??0);let H=-(O.reduce((P,G)=>P+G,0)+r*Math.max(0,m.length-1))/2;for(let P=0;P<m.length;P++){const G=m[P],j=O[P]??0,J=H+j/2;A.set(G,J),H+=j,P<m.length-1&&(H+=r)}}let R=0;for(const[O,_]of a.entries()){const H=y[O]??0,P=new Map;for(const j of _){const J=p(j),dt=P.get(J)??[];dt.push(j),P.set(J,dt)}for(const j of m){const J=P.get(j)??[];if(J.length===0)continue;const dt=A.get(j);if(J.length===1){const mt=J[0];l[mt]=dt,g[mt]=R+H/2}else{const mt=J.map(Q=>I(Q)),kt=mt.reduce((Q,W)=>Q+W,0)+s*(J.length-1);let Pt=dt-kt/2;for(const[Q,W]of J.entries()){const et=mt[Q];l[W]=Pt+et/2,g[W]=R+H/2,Pt+=et+s}}}const G=v[O]??0;R+=H+o+G}const k=new Map;for(const O of e.edges){const _=O.ref.id;k.has(_)||k.set(_,[]),k.get(_).push(O)}for(const[,O]of k){if(O.length===0)continue;const _=O[0].ref,H=_.start,P=_.end;if(H==null||P==null)continue;const G=Math.round(((l[H]??0)+(l[P]??0))/2),j=new Set;for(const J of O)j.add(J.src),j.add(J.dst);for(const J of j){if(J===H||J===P)continue;e.nodeById.get(J)?.isDummy&&(l[J]=G)}}return{x:l,y:g}}d(nr,"assignCoordinates");var or=8;function sr(t){let e=2166136261;for(let n=0;n<t.length;n++)e^=t.charCodeAt(n),e=Math.imul(e,16777619);return e>>>0}d(sr,"hashString");function rr(t){let e=t>>>0;return()=>{e+=1831565813;let n=e;return n=Math.imul(n^n>>>15,n|1),n^=n+Math.imul(n^n>>>7,n|61),((n^n>>>14)>>>0)/4294967296}}d(rr,"mulberry32");function ir(t,e){const n=[...t],o=rr(e);for(let s=n.length-1;s>0;s--){const r=Math.floor(o()*(s+1));[n[s],n[r]]=[n[r],n[s]]}return n}d(ir,"deterministicShuffle");function cr(t,e){let n=0;for(const[o,s]of t.entries())n+=Math.abs(o-(e.get(s)??o));return n}d(cr,"sourceDistance");function Qn(t,e){const n=new Map;for(const[s,r]of t.entries())n.set(r,s);let o=0;for(const{a:s,b:r,weight:i}of e){const c=n.get(s),a=n.get(r);c==null||a==null||(o+=i*Math.abs(c-a))}return o}d(Qn,"laneArrangementCost");function ar(t){const e=fn(t);if(e.length<2)return[];const n=new Map(e.map((r,i)=>[r,i])),o=fe(t),s=new Map;for(const r of t.layout.edges??[]){if(r.isLayoutOnly)continue;const i=typeof r.start=="string"?r.start:void 0,c=typeof r.end=="string"?r.end:void 0;if(!i||!c||!t.nodeById.has(i)||!t.nodeById.has(c))continue;const a=o(i),l=o(c);if(!a||!l||a===l)continue;const g=n.get(a),x=n.get(l);if(g==null||x==null)continue;const[I,u]=g<=x?[a,l]:[l,a],p=`${I}\0${u}`,f=s.get(p);f?f.weight++:s.set(p,{a:I,b:u,weight:1})}return[...s.values()]}d(ar,"buildWeightedLaneEdges");function to(t,e,n){const o=[...t];let s=Qn(o,e),r=!0,i=0;const c=Math.max(1,o.length);for(;r&&i<c;){r=!1,i++;for(let a=0;a+1<o.length;a++){[o[a],o[a+1]]=[o[a+1],o[a]];const l=Qn(o,e);l<s?(s=l,r=!0):[o[a],o[a+1]]=[o[a+1],o[a]]}}return{order:o,cost:s,sourceDistance:cr(o,n)}}d(to,"greedySwitch");function lr(t,e){return t.cost!==e.cost?t.cost<e.cost:t.sourceDistance<e.sourceDistance}d(lr,"isBetterCandidate");function fr(t,e,n){const o=[...e].sort((s,r)=>s.a===r.a?s.b.localeCompare(r.b):s.a.localeCompare(r.a)).map(({a:s,b:r,weight:i})=>`${s}:${r}:${i}`).join("|");return sr(`${t.join("|")}#${o}#${n}`)}d(fr,"seedForRestart");function dr(t,e={}){const n=fn(t);if(n.length<2)return n;const o=ar(t);if(o.length===0)return n;const s=new Map(n.map((c,a)=>[c,a]));let r=to(n,o,s);const i=Math.max(0,e.restarts??or);for(let c=0;c<i;c++){const a=fr(n,o,c),l=ir(n,a),g=to(l,o,s);lr(g,r)&&(r=g)}return r.order}d(dr,"optimizeTopLaneOrder");function ur(t,e){const n=e?.ignoreCrossLaneEdges??!0,o=e?.optimizeRanksByCrossings??!0,s=ye(t),r=e?.automaticLaneOrdering?dr(s,{restarts:or}):void 0,i=Os(s),c=i.acyclic,a=n?Js(c,{compactSingleInput:e?.compactSingleInput??sn.DEFAULT_COMPACT_SINGLE_INPUT,ignoreCrossLaneEdges:!0,direction:e?.direction}):Ks(c,{compactSingleInput:e?.compactSingleInput??sn.DEFAULT_COMPACT_SINGLE_INPUT,ignoreCrossLaneEdges:!1,optimizeRanksByCrossings:o}),{layering:l,graphWithDummies:g}=Zs(a,c),x=er(l,g,{laneOrder:r}),I=nr(x,g,{layerGap:e?.layerGap,nodeGap:e?.nodeGap,direction:e?.direction,laneOrder:r});return{acyclic:c,reversed:i.reversed,layering:l,ordered:x,coordinates:I}}d(ur,"sugiyamaLayout");var ct=Jr.EPSILON,Zr=8,be=15,Te=15,je=25,ne=20,Cn=10;function eo(t,e,n){const o=t.x??0,s=t.y??0,r=e.x-o,i=e.y-s,c=Math.abs(r),a=Math.abs(i);return c<ct&&a<ct?n:a>ct&&a*3>=c?i>0?"bottom":"top":c>ct?r>0?"right":"left":n}d(eo,"chooseOrthogonalSide");function no(t,e){return Math.abs(t.to-e.from)<ct||Math.abs(t.to-e.to)<ct?t.to:t.from}d(no,"sharedLineEndpointCoord");function Me(t,e){return t.orient==="vertical"?{x:t.coord,y:e}:{x:e,y:t.coord}}d(Me,"pointOnLine");function hr(t,e){const n=t.nodes??[],o=t.edges??[],s=[];for(const h of o)h.isLayoutOnly||s.push({...h,__originalEdge:h});const r=new Map,i=new Map,c=[],a=e==="LR";for(const h of n)r.set(h.id,h);const l=n.filter(h=>h.isGroup&&!h.parentId);for(const h of l){const b={id:h.id},C=d(L=>{i.set(L.id,b),n.filter(w=>w.parentId===L.id).forEach(C)},"assignLane");C(h)}const g=n.filter(h=>!h.isGroup&&!h.isEdgeLabel).map(h=>{const b=h.width??10,C=h.height??10,L=h.x??0,w=h.y??0,B=Zr;return{nodeId:h.id,minX:L-b/2-B,maxX:L+b/2+B,minY:w-C/2-B,maxY:w+C/2+B,visualXHalfExtent:a?C/2+B:b/2+B}}),x=d((h,b,C,L)=>{let w=c.find(B=>B.orientation===h&&Math.abs(B.coord-b)<1);return w||(w={id:`pipe-${h}-${b.toFixed(0)}`,orientation:h,coord:b,spanMin:C,spanMax:L,tracks:[]},c.push(w)),w.spanMin=Math.min(w.spanMin,C),w.spanMax=Math.max(w.spanMax,L),w},"getOrAddPipe"),I=d((h,b)=>{const C=h.width??10,L=h.height??10,w=h.x??0,B=h.y??0;switch(b){case"top":return{x:w,y:B-L/2};case"bottom":return{x:w,y:B+L/2};case"left":return{x:w-C/2,y:B};case"right":return{x:w+C/2,y:B}}},"portForSide"),u=d((h,b,C)=>I(h,eo(h,b,C?"bottom":"top")),"getOrthogonalPort"),p=[],f=[],y=new Set,v=1e3,M=d((h,b,C)=>{if(p.length===0)return 0;const L=Math.abs(b.y-C.y)<ct,w=Math.abs(b.x-C.x)<ct;if(!L&&!w)return 0;let B=0;if(L){const U=b.y,q=Math.min(b.x,C.x)-ct,z=Math.max(b.x,C.x)+ct;if(z<=q)return 0;for(const Y of p)Y.edgeIndex===h||Y.orientation!=="vertical"||Y.pipe.coord<q||Y.pipe.coord>z||Y.from-ct<=U&&Y.to+ct>=U&&(B+=v)}else if(w){const U=b.x,q=Math.min(b.y,C.y)-ct,z=Math.max(b.y,C.y)+ct;if(z<=q)return 0;for(const Y of p)Y.edgeIndex===h||Y.orientation!=="horizontal"||Y.pipe.coord<q||Y.pipe.coord>z||Y.from-ct<=U&&Y.to+ct>=U&&(B+=v)}return B},"crossingPenalty"),E=s.map((h,b)=>{if(!h.start||!h.end)return{idx:b,crossLane:0,dx:0,dy:0};const C=r.get(h.start),L=r.get(h.end),w=i.get(h.start),B=i.get(h.end),U=w&&B&&w.id!==B.id?1:0,q=C&&L?Math.abs((L.x??0)-(C.x??0)):0,z=C&&L?Math.abs((L.y??0)-(C.y??0)):0;return{idx:b,crossLane:U,dx:q,dy:z}}).sort((h,b)=>{if(h.crossLane!==b.crossLane)return b.crossLane-h.crossLane;const C=h.dx+h.dy,L=b.dx+b.dy;return Math.abs(C-L)>1?C-L:h.idx-b.idx}).map(h=>h.idx),T=d((h,b,C,L)=>{const w=Math.min(h.x,b.x),B=Math.max(h.x,b.x),U=Math.min(h.y,b.y),q=Math.max(h.y,b.y);return!!g.find(Y=>C&&Y.nodeId===C||L&&Y.nodeId===L?!1:Math.abs(h.x-b.x)>ct?Y.minY<h.y&&Y.maxY>h.y&&Y.maxX>w&&Y.minX<B:Y.minX<h.x&&Y.maxX>h.x&&Y.maxY>U&&Y.minY<q)},"isSegmentBlocked"),m=new Map,S=new Map;for(const h of s)!h.start||!h.end||h.start===h.end||(S.set(h.start,(S.get(h.start)??0)+1),S.set(h.end,(S.get(h.end)??0)+1));const A=d((h,b)=>eo(h,b,"bottom"),"determineSide"),R=new Map;for(const[h,b]of s.entries()){if(!b.start||!b.end||b.start===b.end||b.points&&b.points.length>0)continue;const C=r.get(b.start),L=r.get(b.end);if(!C||!L)continue;const w=(L.x??0)-(C.x??0),B=(L.y??0)-(C.y??0);R.set(h,{edgeIdx:h,srcId:b.start,dstId:b.end,srcSide:A(C,{x:L.x??0,y:L.y??0}),dstSide:A(L,{x:C.x??0,y:C.y??0}),absDx:Math.abs(w),absDy:Math.abs(B),dxSign:Math.sign(w),dySign:Math.sign(B)})}const k=d(h=>h.srcSide==="top"||h.srcSide==="bottom"?h.absDx===0?1/0:h.absDy/h.absDx:h.absDy===0?1/0:h.absDx/h.absDy,"preferenceStrength"),O=d(h=>h.srcSide==="top"||h.srcSide==="bottom"?h.dxSign>=0?"right":"left":h.dySign>=0?"bottom":"top","secondarySide"),_=new Map;for(const h of R.values()){const b=`${h.srcId}:${h.srcSide}`;_.has(b)||_.set(b,[]),_.get(b).push(h)}const H=new Map,P=d((h,b)=>`${h}:${b}`,"loadKey");for(const h of R.values())H.set(P(h.srcId,h.srcSide),(H.get(P(h.srcId,h.srcSide))??0)+1),H.set(P(h.dstId,h.dstSide),(H.get(P(h.dstId,h.dstSide))??0)+1);for(const h of _.values())if(!(h.length<2)){h.sort((b,C)=>{const L=k(b),w=k(C);return Math.abs(L-w)>1e-9?w-L:b.edgeIdx-C.edgeIdx});for(let b=1;b<h.length;b++){const C=h[b],L=O(C),w=H.get(P(C.srcId,C.srcSide))??0,B=H.get(P(C.srcId,L))??0;B>=w||(H.set(P(C.srcId,C.srcSide),w-1),H.set(P(C.srcId,L),B+1),C.srcSide=L)}}const G=d(h=>{const b=h?.shape;return b==="question"||b==="diamond"},"isDiamondNode"),j=new Map;for(const h of R.values())j.has(h.dstId)||j.set(h.dstId,new Set),j.get(h.dstId).add(h.dstSide);for(const h of R.values()){if(!G(r.get(h.srcId)))continue;const b=j.get(h.srcId);if(!b?.has(h.srcSide))continue;const C=O(h);if(b.has(C)||(H.get(P(h.srcId,C))??0)>0)continue;const L=H.get(P(h.srcId,h.srcSide))??0;H.set(P(h.srcId,h.srcSide),Math.max(0,L-1)),H.set(P(h.srcId,C),1),h.srcSide=C}for(const h of R.values()){const{edgeIdx:b,srcId:C,dstId:L,srcSide:w,dstSide:B}=h,U=r.get(C),q=r.get(L),z=`${C}:${w}:src`,Y=w==="top"||w==="bottom"?q.x??0:q.y??0;m.has(z)||m.set(z,[]),m.get(z).push({edgeIdx:b,oppositeCoord:Y});const ot=`${L}:${B}:dst`,rt=B==="top"||B==="bottom"?U.x??0:U.y??0;m.has(ot)||m.set(ot,[]),m.get(ot).push({edgeIdx:b,oppositeCoord:rt})}const J=new Map,dt=8;for(const[h,b]of m){if(b.length<2)continue;b.sort((Lt,Dt)=>Lt.oppositeCoord-Dt.oppositeCoord);const C=h.split(":"),L=C.slice(0,-2).join(":"),w=C[C.length-2],B=C[C.length-1],U=r.get(L);if(!U)continue;const z=w==="left"||w==="right"?U.height??10:U.width??10,Y=U.shape,rt=Y==="question"||Y==="diamond"?z*.3:z,tt=Math.min(20,Math.max(dt,rt/(b.length+1))),Rt=-(tt*(b.length-1))/2;for(const[Lt,Dt]of b.entries()){const Jt=Rt+Lt*tt,gn=`${Dt.edgeIdx}:${B}`;J.set(gn,Jt)}}const mt=d(h=>!!s[h]?.labelNodeId,"edgeHasLabelNode"),kt=d((h,b)=>h?(m.get(`${h}:${b}:src`)??[]).some(({edgeIdx:C})=>mt(C))||(m.get(`${h}:${b}:dst`)??[]).some(({edgeIdx:C})=>mt(C)):!1,"faceHasLabelNode"),Pt=d((h,b,C)=>b==="top"||b==="bottom"?{x:h.x+C,y:h.y}:{x:h.x,y:h.y+C},"applyPortOffset"),Q=d((h,b,C)=>{const L=R.get(h),w={x:C.x??0,y:C.y??0},B={x:b.x??0,y:b.y??0},U=L?.srcSide??A(b,w),q=L?.dstSide??A(C,B);let z=L?I(b,L.srcSide):u(b,w,!0),Y=L?I(C,L.dstSide):u(C,B,!1);const ot=J.get(`${h}:src`),rt=J.get(`${h}:dst`);return ot!==void 0&&(z=Pt(z,U,ot)),rt!==void 0&&(Y=Pt(Y,q,rt)),{pSrcPort:z,pDstPort:Y,srcSide:U,dstSide:q}},"portsForEdge");for(const h of E){const b=s[h];if(f[h]=[],!b.start||!b.end||b.points&&b.points.length>0||b.start===b.end)continue;const C=r.get(b.start),L=r.get(b.end);if(!C||!L)continue;const{pSrcPort:w,pDstPort:B,srcSide:U,dstSide:q}=Q(h,C,L),z={...w},Y={...B},ot=U==="top"||U==="bottom",rt=q==="top"||q==="bottom";if(ot){const X=w.y>(C.y??0);z.y=X?w.y+ne:w.y-ne}else{const X=w.x>(C.x??0);z.x=X?w.x+ne:w.x-ne}if(rt){const X=B.y>(L.y??0);Y.y=X?B.y+ne:B.y-ne}else{const X=B.x>(L.x??0);Y.x=X?B.x+ne:B.x-ne}const st=d((X,$)=>{for(const K of g)if(!$.includes(K.nodeId)&&X.x>K.minX&&X.x<K.maxX&&X.y>K.minY&&X.y<K.maxY)return{inside:!0,obstacle:K};return{inside:!1}},"isPointInObstacle"),tt=d((X,$,K,lt,Ct)=>{if(Ct){const Nt=X.y>($.y??0);return{x:(K.x??0)>=X.x?lt.maxX+be:lt.minX-be,y:Nt?lt.maxY+Te:lt.minY-Te,leavesPositiveSide:Nt}}const bt=X.x>($.x??0),Et=(K.y??0)>=X.y;return{x:bt?lt.maxX+be:lt.minX-be,y:Et?lt.maxY+Te:lt.minY-Te,leavesPositiveSide:bt}},"obstacleDetour");let yt=[];const Rt=[b.start,b.end],Lt=st(z,Rt);if(Lt.inside&&Lt.obstacle){const X=Lt.obstacle;if(ot){const $=tt(w,C,L,X,!0);z.x=$.x,z.y=$.y;const K=$.leavesPositiveSide?Math.min(X.minY-2,w.y+ne):Math.max(X.maxY+2,w.y-ne);yt=[{x:w.x,y:K},{x:$.x,y:K},{x:$.x,y:$.y}]}else{const $=tt(w,C,L,X,!1),K=$.leavesPositiveSide?Math.min(X.minX-2,w.x+ne):Math.max(X.maxX+2,w.x-ne);z.x=$.x,z.y=$.y,yt=[{x:K,y:w.y},{x:K,y:$.y},{x:$.x,y:$.y}]}}let Dt=[];const Jt=st(Y,Rt);if(Jt.inside&&Jt.obstacle){const X=Jt.obstacle;if(rt){const $=tt(B,L,C,X,!0);Y.x=$.x,Y.y=$.y,Dt=[{x:$.x,y:$.y},{x:B.x,y:$.y}]}else{const $=tt(B,L,C,X,!1);Y.x=$.x,Y.y=$.y,Dt=[{x:$.x,y:$.y},{x:$.x,y:B.y}]}}if(yt.length===0&&Dt.length===0){const X=be,$=Math.abs(z.x-Y.x)<X,K=Math.abs(z.y-Y.y)<X,lt=J.get(`${h}:src`)!==void 0||J.get(`${h}:dst`)!==void 0,Ct=(m.get(`${b.start??""}:${U}:src`)?.length??0)+(m.get(`${b.start??""}:${U}:dst`)?.length??0),bt=(m.get(`${b.end??""}:${q}:src`)?.length??0)+(m.get(`${b.end??""}:${q}:dst`)?.length??0),Et=Ct>1||bt>1,Nt=S.get(b.start??"")??0,ut=S.get(b.end??"")??0,Yt=Ct>1&&kt(b.start,U)||bt>1&&kt(b.end,q),ee=Ct<=1||Nt<=2,Bt=bt<=1||ut<=2;if(($||K)&&!lt&&(!Et||Et&&!Yt&&ee&&Bt)&&!T(w,B,b.start,b.end)){b.points=[{...w},{...z},{...Y},{...B}],y.add(h);const Mt=K?"horizontal":"vertical",$t=K?w.y:w.x,It=K?Math.min(w.x,B.x):Math.min(w.y,B.y),St=K?Math.max(w.x,B.x):Math.max(w.y,B.y),Wt={id:`fast-path-${Mt}-${$t.toFixed(0)}-${h}`,orientation:Mt,coord:$t,spanMin:It,spanMax:St,tracks:[]};p.push({edgeIndex:h,segmentIndex:0,orientation:Mt,pipe:Wt,trackIndex:0,from:It,to:St});continue}}const gn=x("vertical",z.x,z.y,z.y);z.x=gn.coord;const mr=x("vertical",Y.x,Y.y,Y.y);Y.x=mr.coord;let ue=Math.min(z.x,Y.x)-50,he=Math.max(z.x,Y.x)+50,ve=Math.min(z.y,Y.y)-50,Le=Math.max(z.y,Y.y)+50;for(const X of g){const $=Math.min(z.x,Y.x),K=Math.max(z.x,Y.x),lt=Math.min(z.y,Y.y),Ct=Math.max(z.y,Y.y);X.minX<K&&X.maxX>$&&X.minY<Ct&&X.maxY>lt&&(ue=Math.min(ue,X.minX-je),he=Math.max(he,X.maxX+je),ve=Math.min(ve,X.minY-je),Le=Math.max(Le,X.maxY+je))}for(const X of g){if(X.maxX<ue||X.minX>he||X.maxY<ve||X.minY>Le)continue;const $=be;x("horizontal",X.minY-$,ue,he),x("horizontal",X.maxY+$,ue,he);const K=Te;x("vertical",X.minX-K,ve,Le),x("vertical",X.maxX+K,ve,Le)}x("horizontal",z.y,ue,he),x("horizontal",Y.y,ue,he);const yr=c.filter(X=>X.orientation==="horizontal"&&X.coord>=ve&&X.coord<=Le),xr=c.filter(X=>X.orientation==="vertical"&&X.coord>=ue&&X.coord<=he),ke=d((X,$)=>`${X.toFixed(1)},${$.toFixed(1)}`,"getKey"),_e=ke(z.x,z.y),vo=ke(Y.x,Y.y),Fe=new Map,pn=new Map,mn=new Map,De=new Set,xe=[];Fe.set(_e,0),mn.set(_e,"n"),xe.push({key:_e,f:Math.hypot(Y.x-z.x,Y.y-z.y),pt:z}),De.add(_e);let Ht=[];const ge=d((X,$)=>T(X,$,b.start,b.end),"checkSegmentBlocked"),yn={x:Y.x,y:z.y},br=ge(z,yn),Mr=ge(yn,Y),Ir=br||Mr,xn={x:z.x,y:Y.y},Sr=ge(z,xn),Cr=ge(xn,Y);if(Ir?Sr||Cr||(Math.abs(z.x-Y.x)<ct?Ht=[z,Y]:Ht=[z,xn,Y]):Math.abs(z.y-Y.y)<ct||Math.abs(z.x-Y.x)<ct?Ht=[z,Y]:Ht=[z,yn,Y],Ht.length===0)for(;xe.length>0;){xe.sort((ut,Yt)=>ut.f-Yt.f);const X=xe.shift();if(De.delete(X.key),X.key===vo){let ut=vo,Yt=Y;for(Ht=[Yt];pn.has(ut);){const ee=pn.get(ut);Ht.unshift(ee),Yt=ee,ut=ke(ee.x,ee.y)}break}const $=X.pt.x,K=X.pt.y,lt=xr.sort((ut,Yt)=>ut.coord-Yt.coord),Ct=lt.findIndex(ut=>Math.abs(ut.coord-$)<1),bt=yr.sort((ut,Yt)=>ut.coord-Yt.coord),Et=bt.findIndex(ut=>Math.abs(ut.coord-K)<1),Nt=[];Ct>0&&Nt.push({x:lt[Ct-1].coord,y:K}),Ct>=0&&Ct<lt.length-1&&Nt.push({x:lt[Ct+1].coord,y:K}),Et>0&&Nt.push({x:$,y:bt[Et-1].coord}),Et>=0&&Et<bt.length-1&&Nt.push({x:$,y:bt[Et+1].coord});for(const ut of Nt){const Yt=Math.min($,ut.x),ee=Math.max($,ut.x),Bt=Math.min(K,ut.y),Gt=Math.max(K,ut.y);if(g.some(Zt=>Zt.nodeId===b.start||Zt.nodeId===b.end?!1:Yt!==ee?Zt.minY<K&&Zt.maxY>K&&Zt.maxX>Yt&&Zt.minX<ee:Zt.minX<$&&Zt.maxX>$&&Zt.maxY>Bt&&Zt.minY<Gt))continue;const Mt=ke(ut.x,ut.y),$t=Math.abs(ut.x-$)+Math.abs(ut.y-K),It=M(h,X.pt,ut);let St=0;const Wt=Y.x-z.x,Ee=Y.y-z.y,He=ut.x-$,bn=ut.y-K;(Ee>10&&bn<-5||Ee<-10&&bn>5)&&(St=Math.abs(bn)*100),(Wt>10&&He<-5||Wt<-10&&He>5)&&(St+=Math.abs(He)*50);let Lo=0;const Eo=mn.get(X.key)??"n",To=Math.abs(He)>ct?"h":"v";Eo!=="n"&&Eo!==To&&(Lo=50);const vr=$t+It+St+Lo,Xe=(Fe.get(X.key)??1/0)+vr,wo=Math.abs(Y.x-ut.x)+Math.abs(Y.y-ut.y);if(Xe<(Fe.get(Mt)??1/0))if(pn.set(Mt,X.pt),Fe.set(Mt,Xe),mn.set(Mt,To),!De.has(Mt))xe.push({key:Mt,f:Xe+wo,pt:ut}),De.add(Mt);else{const Zt=xe.findIndex(Lr=>Lr.key===Mt);Zt!==-1&&(xe[Zt].f=Xe+wo)}}}if(Ht.length===0&&(Ht=[z,{x:z.x,y:Y.y},Y]),Ht.length>4){const X=Ht[0],$=Ht[Ht.length-1];let K=Math.min(X.x,$.x),lt=Math.max(X.x,$.x),Ct=Math.min(X.y,$.y),bt=Math.max(X.y,$.y);for(const Bt of Ht)K=Math.min(K,Bt.x),lt=Math.max(lt,Bt.x),Ct=Math.min(Ct,Bt.y),bt=Math.max(bt,Bt.y);const Et=lt>Math.max(X.x,$.x),Nt=K<Math.min(X.x,$.x);if(a){const Bt=Te;if(Et){const Gt=Math.max(X.x,$.x),Ot=Math.min(X.y,$.y),Mt=Math.max(X.y,$.y),$t=g.filter(It=>It.minX<Gt&&It.maxX>Gt&&It.minY<Mt&&It.maxY>Ot);if($t.length>0){let It=Math.max(X.x,$.x);for(const St of $t){const Wt=(St.minX+St.maxX)/2;if(St.visualXHalfExtent===void 0||isNaN(St.visualXHalfExtent))continue;const Ee=Wt+St.visualXHalfExtent+Bt;It=Math.max(It,Ee)}isNaN(It)||(lt=It)}}if(Nt){const Gt=g.filter(Ot=>Ot.minX<Math.min(X.x,$.x)+Bt&&Ot.minY<Math.max(X.y,$.y)&&Ot.maxY>Math.min(X.y,$.y));if(Gt.length>0){let Ot=Math.min(X.x,$.x);for(const Mt of Gt){const It=(Mt.minX+Mt.maxX)/2-Mt.visualXHalfExtent-Bt;Ot=Math.min(Ot,It)}K=Ot}}}const ut=d(Bt=>{const Gt=$.y>X.y,Ot=g.filter(It=>{const St=Math.min(X.x,$.x)<It.maxX&&Math.max(X.x,$.x)>It.minX,Wt=Math.min(X.y,$.y)<It.maxY&&Math.max(X.y,$.y)>It.minY;return St&&Wt});let Mt=Ot;if(a&&Ot.length>0){const It=Ot.filter(St=>St.minX<Bt&&St.maxX>Bt);It.length>0&&(Mt=It)}if(Mt.length===0)return $.y;const $t=be;if(Gt){const St=Math.max(...Mt.map(Wt=>Wt.maxY))+$t;if(St<$.y-ct)return St}else{const St=Math.min(...Mt.map(Wt=>Wt.minY))-$t;if(St>$.y+ct)return St}return $.y},"findBestReturnY"),Yt=d(Bt=>{const Gt=ut(Bt),Ot={x:Bt,y:X.y},Mt={x:Bt,y:Gt},$t={x:$.x,y:Gt},It=ge(X,Ot),St=ge(Ot,Mt),Wt=ge(Mt,$t),Ee=Gt!==$.y?ge($t,$):!1;return!It&&!St&&!Wt&&!Ee?Math.abs(Gt-$.y)<ct?[X,Ot,Mt,$]:[X,Ot,Mt,$t,$]:null},"trySimplifyWithDetourX"),ee=Et&&!Nt?Yt(lt):Nt&&!Et?Yt(K):null;ee&&(Ht=ee)}const Xt=[w,...yt,...Ht,...Dt.reverse(),B];if(Xt.length>=3){const X=Xt[Xt.length-1],$=Xt[Xt.length-2],K=Xt[Xt.length-3],lt=Math.abs(K.y-$.y)<ct&&Math.abs($.y-X.y)<ct,Ct=Math.abs(K.x-$.x)<ct&&Math.abs($.x-X.x)<ct;if(lt){const bt=Math.sign($.x-K.x),Et=Math.sign(X.x-K.x);bt!==0&&bt===Et&&Math.abs($.x-K.x)>Math.abs(X.x-K.x)&&Xt.splice(-2,1)}else if(Ct){const bt=Math.sign($.y-K.y),Et=Math.sign(X.y-K.y);bt!==0&&bt===Et&&Math.abs($.y-K.y)>Math.abs(X.y-K.y)&&Xt.splice(-2,1)}}const ie=[Xt[0]];for(let X=1;X<Xt.length-1;X++){if(X===1){ie.push(Xt[X]);continue}const $=ie[ie.length-1],K=Xt[X],lt=Xt[X+1];if(Math.abs($.y-K.y)<ct&&Math.abs(K.y-lt.y)<ct){const Ct=K.x>$.x,bt=lt.x>K.x;if(Ct!==bt){ie.push(K);continue}continue}if(Math.abs($.x-K.x)<ct&&Math.abs(K.x-lt.x)<ct){const Ct=K.y>$.y,bt=lt.y>K.y;if(Ct!==bt){ie.push(K);continue}continue}ie.push(K)}ie.push(Xt[Xt.length-1]);for(let X=0;X<ie.length-1;X++){const $=ie[X],K=ie[X+1],lt=Math.abs($.x-K.x)<ct?"vertical":"horizontal",Ct=lt==="vertical"?$.x:$.y,bt=lt==="vertical"?Math.min($.y,K.y):Math.min($.x,K.x),Et=lt==="vertical"?Math.max($.y,K.y):Math.max($.x,K.x),Nt=x(lt,Ct,bt,Et),ut={edgeIndex:h,segmentIndex:X,orientation:lt,pipe:Nt,trackIndex:0,from:bt,to:Et};p.push(ut),f[h].push(p.length-1),Nt.tracks[0]||(Nt.tracks[0]={index:0,coord:Nt.coord,segments:[]}),Nt.tracks[0].segments.push({edgeIndex:h,segmentIndex:X,from:bt,to:Et})}}const W=d((h,b)=>h.from<b.to&&b.from<h.to,"segmentsOverlap"),et=d((h,b,C,L)=>{const w=!L.segments.some(U=>(U.edgeIndex!==b.edgeIndex||U.segmentIndex!==b.segmentIndex)&&W(U,h)),B=!C.segments.some(U=>(U.edgeIndex!==h.edgeIndex||U.segmentIndex!==h.segmentIndex)&&W(U,b));return w&&B?(h.trackIndex=L.index,b.trackIndex=C.index,C.segments=[...C.segments.filter(U=>U.edgeIndex!==h.edgeIndex||U.segmentIndex!==h.segmentIndex),{edgeIndex:b.edgeIndex,segmentIndex:b.segmentIndex,from:b.from,to:b.to}],L.segments=[...L.segments.filter(U=>U.edgeIndex!==b.edgeIndex||U.segmentIndex!==b.segmentIndex),{edgeIndex:h.edgeIndex,segmentIndex:h.segmentIndex,from:h.from,to:h.to}],!0):!1},"trySwapSegmentsAcrossTracks"),at=d(h=>{const b=h.tracks.length;return h.tracks[b]={index:b,coord:h.coord,segments:[]},b},"createNewTrack"),gt=d((h,b)=>{const C=h.pipe.tracks[h.trackIndex];C.segments=C.segments.filter(w=>w.edgeIndex!==h.edgeIndex||w.segmentIndex!==h.segmentIndex),h.trackIndex=b,h.pipe.tracks[b].segments.push({edgeIndex:h.edgeIndex,segmentIndex:h.segmentIndex,from:h.from,to:h.to})},"moveSegmentToTrack"),xt=d((h,b)=>{const C=f[h.edgeIndex];for(const L of C){const w=p[L];w.pipe===h.pipe&>(w,b)}},"moveSegmentChainToTrack"),vt=d(h=>{const b=f[h.edgeIndex],C=b.indexOf(p.indexOf(h)),L=[];return C>0&&L.push(p[b[C-1]]),C<b.length-1&&L.push(p[b[C+1]]),L},"getAdjacentSegmentsAlongEdge"),Vt=d((h,b)=>{if(h.orientation===b.orientation)return!1;const C=h.orientation==="horizontal"?h:b,L=h.orientation==="horizontal"?b:h;return L.pipe.coord>C.from&&L.pipe.coord<C.to&&C.pipe.coord>L.from&&C.pipe.coord<L.to},"haveAnyCrossing"),jt=d((h,b)=>{for(const C of h.tracks)if(!C.segments.some(w=>(w.edgeIndex!==b.edgeIndex||w.segmentIndex!==b.segmentIndex)&&W(w,b)))return C.index;return-1},"findAvailableTrack"),Ut=d((h,b)=>{if(h.trackIndex===b.trackIndex)return W(h,b);const C=vt(h),L=vt(b);return C.some(w=>L.some(B=>Vt(w,B)))},"segmentsConflict"),te=d((h,b,C)=>{if(et(h,b,h.pipe.tracks[h.trackIndex],b.pipe.tracks[b.trackIndex]))return;const L=jt(h.pipe,b);C(b,L!==-1?L:at(h.pipe))},"resolveTrackConflict"),Se=d(h=>{let b=0;for(let C=0;C<h.length;C++)for(let L=C+1;L<h.length;L++){const w=h[C],B=h[L];w.pipe===B.pipe&&Ut(w,B)&&(b++,te(w,B,xt))}return b},"resolveHandleConflicts"),de=new Map,Ce=d(h=>{if(de.has(h))return de.get(h);const b=f[h];if(b.length===0){const q={dest:0,deviation:0,base:0,delta:0};return de.set(h,q),q}const L=p[b[0]].pipe.coord;let w=L;for(let q=1;q<b.length;q++){const z=p[b[q]];if(z.orientation==="horizontal"){const Y=z.from,ot=z.to;w=Math.abs(Y-L)>Math.abs(ot-L)?Y:ot;break}}const B=Math.abs(w-L),U={dest:w,deviation:B,base:L,delta:w-L};return de.set(h,U),U},"getDestInfo"),dn=d(()=>{let h=0;const b=new Map;for(const[L,w]of s.entries())f[L].length!==0&&w.start&&(b.has(w.start)||b.set(w.start,[]),b.get(w.start).push(L));const C=d(L=>{const w=s[L];if(!w.start||!w.end)return 0;const B=r.get(w.start),U=r.get(w.end);if(!B||!U)return 0;const q=(U.x??0)-(B.x??0),z=(U.y??0)-(B.y??0);return Math.abs(q)+Math.abs(z)},"getEdgeDistance");for(const L of b.values()){L.sort((B,U)=>{const q=Ce(B),z=Ce(U);if(Math.abs(q.deviation-z.deviation)>1)return q.deviation-z.deviation;if(Math.abs(q.dest-z.dest)>1)return q.dest-z.dest;const Y=C(B),ot=C(U);if(Math.abs(Y-ot)>1)return ot-Y;const rt=f[B].length,st=f[U].length;if(rt!==st)return rt-st;if(rt===1){const tt=f[B][0],yt=f[U][0];if(p[tt]&&p[yt]){const Rt=p[tt],Lt=p[yt],Dt=Math.abs(Rt.to-Rt.from),Jt=Math.abs(Lt.to-Lt.from);if(Math.abs(Dt-Jt)>1)return Dt-Jt}}return 0});const w=L.map(B=>p[f[B][0]]);h+=Se(w)}return h},"fixSourceHandleCrossings"),un=d(()=>{let h=0;const b=new Map;for(const[C,L]of s.entries())f[C].length!==0&&L.end&&(b.has(L.end)||b.set(L.end,[]),b.get(L.end).push(C));for(const C of b.values()){C.sort((w,B)=>{const U=d(Y=>{const ot=f[Y];if(ot.length<2)return 0;const rt=p[ot[ot.length-2]];return Math.abs(rt.to-rt.from)},"getDist"),q=U(w),z=U(B);return Math.abs(q-z)>.1?q-z:w-B});const L=C.map(w=>p[f[w][f[w].length-1]]);h+=Se(L)}return h},"fixTargetHandleCrossings"),hn=d(()=>{let h=0;for(const b of c){const C=[];for(const L of b.tracks)for(const w of L.segments){const B=f[w.edgeIndex].find(U=>p[U].segmentIndex===w.segmentIndex);B!==void 0&&C.push(p[B])}C.sort((L,w)=>L.edgeIndex-w.edgeIndex||L.segmentIndex-w.segmentIndex);for(let L=0;L<C.length;L++)for(let w=L+1;w<C.length;w++){const B=C[L],U=C[w];Ut(B,U)&&(h++,te(B,U,gt))}}return h},"fixPipeCrossings");let N=0;const F=10;for(;N<F;){let h=0;if(h+=dn(),h+=un(),h+=hn(),h===0)break;N++}const D=new Map;for(const h of c){const b=[];h.tracks.forEach(L=>{L.segments.forEach(w=>{b.push({edgeIndex:w.edgeIndex,segmentIndex:w.segmentIndex,trackIndex:L.index,from:w.from,to:w.to})})}),b.sort((L,w)=>L.from-w.from);const C=[];if(b.length>0){let L=[b[0]],w=b[0].to;for(let B=1;B<b.length;B++){const U=b[B];U.from<w?(L.push(U),w=Math.max(w,U.to)):(C.push(L),L=[U],w=U.to)}C.push(L)}for(const L of C){const w=new Set;L.forEach(tt=>w.add(tt.trackIndex));const B=new Map;L.forEach(tt=>{const yt=Ce(tt.edgeIndex);B.set(tt.trackIndex,(B.get(tt.trackIndex)??0)+yt.delta)});const U=[...w].filter(tt=>(B.get(tt)??0)<-1),q=[...w].filter(tt=>(B.get(tt)??0)>1),z=[...w].filter(tt=>Math.abs(B.get(tt)??0)<=1);U.sort((tt,yt)=>(B.get(yt)??0)-(B.get(tt)??0)),q.sort((tt,yt)=>(B.get(tt)??0)-(B.get(yt)??0));const Y=d((tt,yt)=>{L.filter(Rt=>Rt.trackIndex===tt).forEach(Rt=>{const Lt=y.has(Rt.edgeIndex)?h.coord:yt;D.set(`${Rt.edgeIndex}-${Rt.segmentIndex}`,Lt)})},"assignCoord");let ot=0;for(const tt of U)ot++,Y(tt,h.coord-ot*Cn);if(z.length===0&&w.size>0){const tt=[...w].sort((Lt,Dt)=>Math.abs(B.get(Lt)??0)-Math.abs(B.get(Dt)??0))[0],yt=U.indexOf(tt);yt!==-1&&U.splice(yt,1);const Rt=q.indexOf(tt);Rt!==-1&&q.splice(Rt,1),z.push(tt)}let rt=0;for(const tt of z){if(rt===0)Y(tt,h.coord);else{const yt=rt%2===1?1:-1,Rt=Math.ceil(rt/2);Y(tt,h.coord+yt*Rt*Cn*.5)}rt++}let st=0;for(const tt of q)st++,Y(tt,h.coord+st*Cn)}}for(const[h,b]of s.entries()){const C=f[h]??[];if(C.length===0)continue;const L=[],w=r.get(b.start),B=r.get(b.end),{pSrcPort:U,pDstPort:q}=Q(h,w,B),z=C.map(rt=>{const st=p[rt],tt=D.get(`${st.edgeIndex}-${st.segmentIndex}`)??st.pipe.coord;return{orient:st.orientation,coord:tt,from:st.from,to:st.to}});L.push(U);for(let rt=0;rt<z.length;rt++){const st=z[rt],tt=L[L.length-1],yt=st.orient==="vertical"?tt.y:tt.x,Rt=st.orient==="vertical"?tt.x:tt.y,Lt=z[rt+1],Dt=rt<z.length-1;if(Math.abs(Rt-st.coord)>ct&&L.push(Me(st,yt)),Dt&&Lt.orient===st.orient)if(Math.abs(st.coord-Lt.coord)>ct){const Jt=st.orient==="vertical"?(yt+Lt.from)/2:no(st,Lt);L.push(Me(st,Jt),Me(Lt,Jt))}else(rt===0||rt===z.length-2)&&L.push(Me(st,no(st,Lt)));else if(Dt)L.push(Me(st,Lt.coord));else{const Jt=Math.abs(st.from-yt)<Math.abs(st.to-yt)?st.to:st.from;L.push(Me(st,Jt))}}const Y=L[L.length-1];(Math.abs(Y.x-q.x)>ct||Math.abs(Y.y-q.y)>ct)&&L.push(q);const ot=[];L.length>0&&ot.push(L[0]);for(let rt=1;rt<L.length;rt++){const st=L[rt],tt=ot[ot.length-1];(Math.abs(st.x-tt.x)>ct||Math.abs(st.y-tt.y)>ct)&&ot.push(st)}b.points=ot}for(const h of s){const b=h.__originalEdge;b&&h.points&&(b.points=h.points)}t.edges=(t.edges??[]).filter(h=>!h.isLayoutOnly);const V=d((h,b)=>{const C=b.x??0,L=b.y??0,w=b.width??0,B=b.height??0;if(w<=0||B<=0)return h;const U=C-w/2,q=C+w/2,z=L-B/2,Y=L+B/2;if(h.x<U||h.x>q||h.y<z||h.y>Y)return h;const ot=h.x-U,rt=q-h.x,st=h.y-z,tt=Y-h.y,yt=Math.min(ot,rt,st,tt);return yt===ot?{x:U,y:h.y}:yt===rt?{x:q,y:h.y}:yt===st?{x:h.x,y:z}:{x:h.x,y:Y}},"nodeBoundaryClamp");for(const h of t.edges){const b=h.points;if(!b||b.length<2)continue;const C=h.start,L=h.end,w=C?r.get(C):void 0,B=L?r.get(L):void 0;w&&(b[0]=V(b[0],w)),B&&(b[b.length-1]=V(b[b.length-1],B))}return t}d(hr,"routeEdgesOrthogonal");function gr(t){return t.direction??"TB"}d(gr,"getSwimlaneDirection");function pr(t){const e=Jo(t),n=t.config.flowchart?.nodeSpacing??40,o=t.config.flowchart?.rankSpacing??100,s=t.config.swimlane?.ignoreCrossLaneEdges??!0,r=t.config.swimlane?.optimizeRanksByCrossings??!0,i=t.config.swimlane?.automaticLaneOrdering??!1,c=gr(t),{ordered:a,coordinates:l}=ur(e,{nodeGap:n,layerGap:o,ignoreCrossLaneEdges:s,optimizeRanksByCrossings:r,automaticLaneOrdering:i,direction:c});Zo(e,a,l,{nodeGap:n,layerGap:o});for(const g of t.edges??[])delete g.points;hr(t,c);for(const g of t.edges??[])(!g.curve||g.curve==="basis")&&(g.curve="rounded");return Rs(t,c),As(t),c}d(pr,"runSwimlaneLayoutCore");async function Qr(t,e){const n=e.select("g");wr(n,t.markers,t.type,t.diagramId),Ar(),Rr(),Nr(),Tr(),qo(t);const o=Qo(t);t.nodes=o.nodes,t.edges=o.edges;const{groups:s}=await _o(n,t);pr(t),await Uo(t,s)}d(Qr,"render");export{Qr as render}; diff --git a/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DKIx012r.js b/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DKIx012r.js new file mode 100644 index 000000000..03ec388fe --- /dev/null +++ b/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DKIx012r.js @@ -0,0 +1,8 @@ +import{c as r,s as e}from"./flowDiagram-23GEKE2U-CzI-GKO4.js";import{_ as a}from"./mermaid.core-CJB1tAev.js";import"./chunk-5VM5RSS4-yyj9cAyF.js";import"./chunk-XXDRQBXY-5rh7CWvm.js";import"./chunk-VR4S4FIN-CEH7JYJn.js";import"./chunk-32BRIVSS-DUDRPqmY.js";import"./channel-xkK6nTGq.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var o=a(t=>`${e(t)} + .swimlane.cluster rect { + stroke: ${t.clusterBorder} !important; + } + [data-look="neo"].cluster rect { + filter: none; + } +`,"getStyles"),m=o,y=r({defaultLayout:"swimlane",styles:m});export{y as diagram}; diff --git a/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DU8WMkqz.js b/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DU8WMkqz.js deleted file mode 100644 index b83657d6f..000000000 --- a/apps/kimi-code/dist-web/assets/swimlanesDiagram-G3AALYLV-DU8WMkqz.js +++ /dev/null @@ -1,8 +0,0 @@ -import{c as r,s as e}from"./flowDiagram-23GEKE2U-D0EBISGr.js";import{_ as a}from"./mermaid.core-DaDTfY6S.js";import"./chunk-5VM5RSS4-B87d3yQb.js";import"./chunk-XXDRQBXY-BEgNawAD.js";import"./chunk-VR4S4FIN-Dzr2NgNj.js";import"./chunk-32BRIVSS-_Sd4SrsJ.js";import"./channel-d4fEaqwQ.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var o=a(t=>`${e(t)} - .swimlane.cluster rect { - stroke: ${t.clusterBorder} !important; - } - [data-look="neo"].cluster rect { - filter: none; - } -`,"getStyles"),m=o,y=r({defaultLayout:"swimlane",styles:m});export{y as diagram}; diff --git a/apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-CV7TbRUK.js b/apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-5u0AN8o0.js similarity index 99% rename from apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-CV7TbRUK.js rename to apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-5u0AN8o0.js index 01a98c52c..6787e09bf 100644 --- a/apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-CV7TbRUK.js +++ b/apps/kimi-code/dist-web/assets/timeline-definition-FHXFAJF6-5u0AN8o0.js @@ -1,4 +1,4 @@ -import{_ as o,z as pt,aa as Rt,ab as Ct,ac as Wt,c as gt,l as E,F as Pt,a1 as Bt,ad as ft,d as U,u as Vt,ae as Ft,q as zt}from"./mermaid.core-DaDTfY6S.js";import{d as ot}from"./arc-CC9q5kjc.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var tt=(function(){var e=o(function(k,s,d,l){for(d=d||{},l=k.length;l--;d[k[l]]=s);return d},"o"),t=[6,11,13,14,15,17,19,20,23,24],n=[1,12],i=[1,13],r=[1,14],h=[1,15],c=[1,16],a=[1,19],f=[1,20],g={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline_header:4,document:5,EOF:6,timeline:7,timeline_lr:8,timeline_td:9,line:10,SPACE:11,statement:12,NEWLINE:13,title:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,period_statement:21,event_statement:22,period:23,event:24,$accept:0,$end:1},terminals_:{2:"error",6:"EOF",7:"timeline",8:"timeline_lr",9:"timeline_td",11:"SPACE",13:"NEWLINE",14:"title",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",23:"period",24:"event"},productions_:[0,[3,3],[4,1],[4,1],[4,1],[5,0],[5,2],[10,2],[10,1],[10,1],[10,1],[12,1],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[21,1],[22,1]],performAction:o(function(s,d,l,p,x,u,S){var v=u.length-1;switch(x){case 1:return u[v-1];case 3:p.setDirection("LR");break;case 4:p.setDirection("TD");break;case 5:this.$=[];break;case 6:u[v-1].push(u[v]),this.$=u[v-1];break;case 7:case 8:this.$=u[v];break;case 9:case 10:this.$=[];break;case 11:p.getCommonDb().setDiagramTitle(u[v].substr(6)),this.$=u[v].substr(6);break;case 12:this.$=u[v].trim(),p.getCommonDb().setAccTitle(this.$);break;case 13:case 14:this.$=u[v].trim(),p.getCommonDb().setAccDescription(this.$);break;case 15:p.addSection(u[v].substr(8)),this.$=u[v].substr(8);break;case 18:p.addTask(u[v],0,""),this.$=u[v];break;case 19:p.addEvent(u[v].substr(2)),this.$=u[v];break}},"anonymous"),table:[{3:1,4:2,7:[1,3],8:[1,4],9:[1,5]},{1:[3]},e(t,[2,5],{5:6}),e(t,[2,2]),e(t,[2,3]),e(t,[2,4]),{6:[1,7],10:8,11:[1,9],12:10,13:[1,11],14:n,15:i,17:r,19:h,20:c,21:17,22:18,23:a,24:f},e(t,[2,10],{1:[2,1]}),e(t,[2,6]),{12:21,14:n,15:i,17:r,19:h,20:c,21:17,22:18,23:a,24:f},e(t,[2,8]),e(t,[2,9]),e(t,[2,11]),{16:[1,22]},{18:[1,23]},e(t,[2,14]),e(t,[2,15]),e(t,[2,16]),e(t,[2,17]),e(t,[2,18]),e(t,[2,19]),e(t,[2,7]),e(t,[2,12]),e(t,[2,13])],defaultActions:{},parseError:o(function(s,d){if(d.recoverable)this.trace(s);else{var l=new Error(s);throw l.hash=d,l}},"parseError"),parse:o(function(s){var d=this,l=[0],p=[],x=[null],u=[],S=this.table,v="",I=0,R=0,W=2,O=1,L=u.slice.call(arguments,1),w=Object.create(this.lexer),H={yy:{}};for(var V in this.yy)Object.prototype.hasOwnProperty.call(this.yy,V)&&(H.yy[V]=this.yy[V]);w.setInput(s,H.yy),H.yy.lexer=w,H.yy.parser=this,typeof w.yylloc>"u"&&(w.yylloc={});var F=w.yylloc;u.push(F);var K=w.options&&w.options.ranges;typeof H.yy.parseError=="function"?this.parseError=H.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function N(A){l.length=l.length-2*A,x.length=x.length-A,u.length=u.length-A}o(N,"popStack");function b(){var A;return A=p.pop()||w.lex()||O,typeof A!="number"&&(A instanceof Array&&(p=A,A=p.pop()),A=d.symbols_[A]||A),A}o(b,"lex");for(var _,$,T,P,C={},G,B,X,Z;;){if($=l[l.length-1],this.defaultActions[$]?T=this.defaultActions[$]:((_===null||typeof _>"u")&&(_=b()),T=S[$]&&S[$][_]),typeof T>"u"||!T.length||!T[0]){var Y="";Z=[];for(G in S[$])this.terminals_[G]&&G>W&&Z.push("'"+this.terminals_[G]+"'");w.showPosition?Y="Parse error on line "+(I+1)+`: +import{_ as o,z as pt,aa as Rt,ab as Ct,ac as Wt,c as gt,l as E,F as Pt,a1 as Bt,ad as ft,d as U,u as Vt,ae as Ft,q as zt}from"./mermaid.core-CJB1tAev.js";import{d as ot}from"./arc-IkhU3FHH.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var tt=(function(){var e=o(function(k,s,d,l){for(d=d||{},l=k.length;l--;d[k[l]]=s);return d},"o"),t=[6,11,13,14,15,17,19,20,23,24],n=[1,12],i=[1,13],r=[1,14],h=[1,15],c=[1,16],a=[1,19],f=[1,20],g={trace:o(function(){},"trace"),yy:{},symbols_:{error:2,start:3,timeline_header:4,document:5,EOF:6,timeline:7,timeline_lr:8,timeline_td:9,line:10,SPACE:11,statement:12,NEWLINE:13,title:14,acc_title:15,acc_title_value:16,acc_descr:17,acc_descr_value:18,acc_descr_multiline_value:19,section:20,period_statement:21,event_statement:22,period:23,event:24,$accept:0,$end:1},terminals_:{2:"error",6:"EOF",7:"timeline",8:"timeline_lr",9:"timeline_td",11:"SPACE",13:"NEWLINE",14:"title",15:"acc_title",16:"acc_title_value",17:"acc_descr",18:"acc_descr_value",19:"acc_descr_multiline_value",20:"section",23:"period",24:"event"},productions_:[0,[3,3],[4,1],[4,1],[4,1],[5,0],[5,2],[10,2],[10,1],[10,1],[10,1],[12,1],[12,2],[12,2],[12,1],[12,1],[12,1],[12,1],[21,1],[22,1]],performAction:o(function(s,d,l,p,x,u,S){var v=u.length-1;switch(x){case 1:return u[v-1];case 3:p.setDirection("LR");break;case 4:p.setDirection("TD");break;case 5:this.$=[];break;case 6:u[v-1].push(u[v]),this.$=u[v-1];break;case 7:case 8:this.$=u[v];break;case 9:case 10:this.$=[];break;case 11:p.getCommonDb().setDiagramTitle(u[v].substr(6)),this.$=u[v].substr(6);break;case 12:this.$=u[v].trim(),p.getCommonDb().setAccTitle(this.$);break;case 13:case 14:this.$=u[v].trim(),p.getCommonDb().setAccDescription(this.$);break;case 15:p.addSection(u[v].substr(8)),this.$=u[v].substr(8);break;case 18:p.addTask(u[v],0,""),this.$=u[v];break;case 19:p.addEvent(u[v].substr(2)),this.$=u[v];break}},"anonymous"),table:[{3:1,4:2,7:[1,3],8:[1,4],9:[1,5]},{1:[3]},e(t,[2,5],{5:6}),e(t,[2,2]),e(t,[2,3]),e(t,[2,4]),{6:[1,7],10:8,11:[1,9],12:10,13:[1,11],14:n,15:i,17:r,19:h,20:c,21:17,22:18,23:a,24:f},e(t,[2,10],{1:[2,1]}),e(t,[2,6]),{12:21,14:n,15:i,17:r,19:h,20:c,21:17,22:18,23:a,24:f},e(t,[2,8]),e(t,[2,9]),e(t,[2,11]),{16:[1,22]},{18:[1,23]},e(t,[2,14]),e(t,[2,15]),e(t,[2,16]),e(t,[2,17]),e(t,[2,18]),e(t,[2,19]),e(t,[2,7]),e(t,[2,12]),e(t,[2,13])],defaultActions:{},parseError:o(function(s,d){if(d.recoverable)this.trace(s);else{var l=new Error(s);throw l.hash=d,l}},"parseError"),parse:o(function(s){var d=this,l=[0],p=[],x=[null],u=[],S=this.table,v="",I=0,R=0,W=2,O=1,L=u.slice.call(arguments,1),w=Object.create(this.lexer),H={yy:{}};for(var V in this.yy)Object.prototype.hasOwnProperty.call(this.yy,V)&&(H.yy[V]=this.yy[V]);w.setInput(s,H.yy),H.yy.lexer=w,H.yy.parser=this,typeof w.yylloc>"u"&&(w.yylloc={});var F=w.yylloc;u.push(F);var K=w.options&&w.options.ranges;typeof H.yy.parseError=="function"?this.parseError=H.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function N(A){l.length=l.length-2*A,x.length=x.length-A,u.length=u.length-A}o(N,"popStack");function b(){var A;return A=p.pop()||w.lex()||O,typeof A!="number"&&(A instanceof Array&&(p=A,A=p.pop()),A=d.symbols_[A]||A),A}o(b,"lex");for(var _,$,T,P,C={},G,B,X,Z;;){if($=l[l.length-1],this.defaultActions[$]?T=this.defaultActions[$]:((_===null||typeof _>"u")&&(_=b()),T=S[$]&&S[$][_]),typeof T>"u"||!T.length||!T[0]){var Y="";Z=[];for(G in S[$])this.terminals_[G]&&G>W&&Z.push("'"+this.terminals_[G]+"'");w.showPosition?Y="Parse error on line "+(I+1)+`: `+w.showPosition()+` Expecting `+Z.join(", ")+", got '"+(this.terminals_[_]||_)+"'":Y="Parse error on line "+(I+1)+": Unexpected "+(_==O?"end of input":"'"+(this.terminals_[_]||_)+"'"),this.parseError(Y,{text:w.match,token:this.terminals_[_]||_,line:w.yylineno,loc:F,expected:Z})}if(T[0]instanceof Array&&T.length>1)throw new Error("Parse Error: multiple actions possible at state: "+$+", token: "+_);switch(T[0]){case 1:l.push(_),x.push(w.yytext),u.push(w.yylloc),l.push(T[1]),_=null,R=w.yyleng,v=w.yytext,I=w.yylineno,F=w.yylloc;break;case 2:if(B=this.productions_[T[1]][1],C.$=x[x.length-B],C._$={first_line:u[u.length-(B||1)].first_line,last_line:u[u.length-1].last_line,first_column:u[u.length-(B||1)].first_column,last_column:u[u.length-1].last_column},K&&(C._$.range=[u[u.length-(B||1)].range[0],u[u.length-1].range[1]]),P=this.performAction.apply(C,[v,R,I,H.yy,T[1],x,u].concat(L)),typeof P<"u")return P;B&&(l=l.slice(0,-1*B*2),x=x.slice(0,-1*B),u=u.slice(0,-1*B)),l.push(this.productions_[T[1]][0]),x.push(C.$),u.push(C._$),X=S[l[l.length-2]][l[l.length-1]],l.push(X);break;case 3:return!0}}return!0},"parse")},m=(function(){var k={EOF:1,parseError:o(function(d,l){if(this.yy.parser)this.yy.parser.parseError(d,l);else throw new Error(d)},"parseError"),setInput:o(function(s,d){return this.yy=d||this.yy||{},this._input=s,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:o(function(){var s=this._input[0];this.yytext+=s,this.yyleng++,this.offset++,this.match+=s,this.matched+=s;var d=s.match(/(?:\r\n?|\n).*/g);return d?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),s},"input"),unput:o(function(s){var d=s.length,l=s.split(/(?:\r\n?|\n)/g);this._input=s+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-d),this.offset-=d;var p=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),l.length-1&&(this.yylineno-=l.length-1);var x=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:l?(l.length===p.length?this.yylloc.first_column:0)+p[p.length-l.length].length-l[0].length:this.yylloc.first_column-d},this.options.ranges&&(this.yylloc.range=[x[0],x[0]+this.yyleng-d]),this.yyleng=this.yytext.length,this},"unput"),more:o(function(){return this._more=!0,this},"more"),reject:o(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:o(function(s){this.unput(this.match.slice(s))},"less"),pastInput:o(function(){var s=this.matched.substr(0,this.matched.length-this.match.length);return(s.length>20?"...":"")+s.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:o(function(){var s=this.match;return s.length<20&&(s+=this._input.substr(0,20-s.length)),(s.substr(0,20)+(s.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:o(function(){var s=this.pastInput(),d=new Array(s.length+1).join("-");return s+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-BNRmZgGU.js b/apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-ozNTLnJz.js similarity index 99% rename from apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-BNRmZgGU.js rename to apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-ozNTLnJz.js index ca3de407b..5780512f0 100644 --- a/apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-BNRmZgGU.js +++ b/apps/kimi-code/dist-web/assets/vennDiagram-L72KCM5P-ozNTLnJz.js @@ -1,4 +1,4 @@ -import{b4 as Wt,s as Kt,g as Ht,p as Yt,o as Xt,a as Zt,b as Jt,_ as w,z as wt,F as Qt,d as ot,al as $t,aa as te,ab as ee,ac as ne,e as se,q as ie,B as oe,D as re}from"./mermaid.core-DaDTfY6S.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";const kt=(t,n)=>Wt(t,"a",-n),_t=1e-10;function st(t,n){const s=le(t),e=s.filter(l=>ae(l,t));let i=0,o=0;const r=[];if(e.length>1){const l=Et(e);for(let u=0;u<e.length;++u){const a=e[u];a.angle=Math.atan2(a.x-l.x,a.y-l.y)}e.sort((u,a)=>a.angle-u.angle);let f=e[e.length-1];for(let u=0;u<e.length;++u){const a=e[u];o+=(f.x+a.x)*(a.y-f.y);const y={x:(a.x+f.x)/2,y:(a.y+f.y)/2};let h=null;for(let b=0;b<a.parentIndex.length;++b)if(f.parentIndex.includes(a.parentIndex[b])){const p=t[a.parentIndex[b]],M=Math.atan2(a.x-p.x,a.y-p.y),E=Math.atan2(f.x-p.x,f.y-p.y);let _=E-M;_<0&&(_+=2*Math.PI);const S=E-_/2;let g=q(y,{x:p.x+p.radius*Math.sin(S),y:p.y+p.radius*Math.cos(S)});g>p.radius*2&&(g=p.radius*2),(h==null||h.width>g)&&(h={circle:p,width:g,p1:a,p2:f,large:g>p.radius,sweep:!0})}h!=null&&(r.push(h),i+=lt(h.circle.radius,h.width),f=a)}}else{let l=t[0];for(let u=1;u<t.length;++u)t[u].radius<l.radius&&(l=t[u]);let f=!1;for(let u=0;u<t.length;++u)if(q(t[u],l)>Math.abs(l.radius-t[u].radius)){f=!0;break}f?i=o=0:(i=l.radius*l.radius*Math.PI,r.push({circle:l,p1:{x:l.x,y:l.y+l.radius},p2:{x:l.x-_t,y:l.y+l.radius},width:l.radius*2,large:!0,sweep:!0}))}return o/=2,n&&(n.area=i+o,n.arcArea=i,n.polygonArea=o,n.arcs=r,n.innerPoints=e,n.intersectionPoints=s),i+o}function ae(t,n){return n.every(s=>q(t,s)<s.radius+_t)}function le(t){const n=[];for(let s=0;s<t.length;++s)for(let e=s+1;e<t.length;++e){const i=Tt(t[s],t[e]);for(const o of i)o.parentIndex=[s,e],n.push(o)}return n}function lt(t,n){return t*t*Math.acos(1-n/t)-(t-n)*Math.sqrt(n*(2*t-n))}function q(t,n){return Math.sqrt((t.x-n.x)*(t.x-n.x)+(t.y-n.y)*(t.y-n.y))}function xt(t,n,s){if(s>=t+n)return 0;if(s<=Math.abs(t-n))return Math.PI*Math.min(t,n)*Math.min(t,n);const e=t-(s*s-n*n+t*t)/(2*s),i=n-(s*s-t*t+n*n)/(2*s);return lt(t,e)+lt(n,i)}function Tt(t,n){const s=q(t,n),e=t.radius,i=n.radius;if(s>=e+i||s<=Math.abs(e-i))return[];const o=(e*e-i*i+s*s)/(2*s),r=Math.sqrt(e*e-o*o),l=t.x+o*(n.x-t.x)/s,f=t.y+o*(n.y-t.y)/s,u=-(n.y-t.y)*(r/s),a=-(n.x-t.x)*(r/s);return[{x:l+u,y:f-a},{x:l-u,y:f+a}]}function Et(t){const n={x:0,y:0};for(const s of t)n.x+=s.x,n.y+=s.y;return n.x/=t.length,n.y/=t.length,n}function ce(t,n,s,e){e=e||{};const i=e.maxIterations||100,o=e.tolerance||1e-10,r=t(n),l=t(s);let f=s-n;if(r*l>0)throw"Initial bisect points must have opposite signs";if(r===0)return n;if(l===0)return s;for(let u=0;u<i;++u){f/=2;const a=n+f,y=t(a);if(y*r>=0&&(n=a),Math.abs(f)<o||y===0)return a}return n+f}function ct(t){const n=new Array(t);for(let s=0;s<t;++s)n[s]=0;return n}function Mt(t,n){return ct(t).map(()=>ct(n))}function $(t,n){let s=0;for(let e=0;e<t.length;++e)s+=t[e]*n[e];return s}function ut(t){return Math.sqrt($(t,t))}function ft(t,n,s){for(let e=0;e<n.length;++e)t[e]=n[e]*s}function J(t,n,s,e,i){for(let o=0;o<t.length;++o)t[o]=n*s[o]+e*i[o]}function zt(t,n,s){s=s||{};const e=s.maxIterations||n.length*200,i=s.nonZeroDelta||1.05,o=s.zeroDelta||.001,r=s.minErrorDelta||1e-6,l=s.minErrorDelta||1e-5,f=s.rho!==void 0?s.rho:1,u=s.chi!==void 0?s.chi:2,a=s.psi!==void 0?s.psi:-.5,y=s.sigma!==void 0?s.sigma:.5;let h;const b=n.length,p=new Array(b+1);p[0]=n,p[0].fx=t(n),p[0].id=0;for(let v=0;v<b;++v){const c=n.slice();c[v]=c[v]?c[v]*i:o,p[v+1]=c,p[v+1].fx=t(c),p[v+1].id=v+1}function M(v){for(let c=0;c<v.length;c++)p[b][c]=v[c];p[b].fx=v.fx}const E=(v,c)=>v.fx-c.fx,_=n.slice(),S=n.slice(),g=n.slice(),m=n.slice();for(let v=0;v<e;++v){if(p.sort(E),s.history){const x=p.map(d=>{const D=d.slice();return D.fx=d.fx,D.id=d.id,D});x.sort((d,D)=>d.id-D.id),s.history.push({x:p[0].slice(),fx:p[0].fx,simplex:x})}h=0;for(let x=0;x<b;++x)h=Math.max(h,Math.abs(p[0][x]-p[1][x]));if(Math.abs(p[0].fx-p[b].fx)<r&&h<l)break;for(let x=0;x<b;++x){_[x]=0;for(let d=0;d<b;++d)_[x]+=p[d][x];_[x]/=b}const c=p[b];if(J(S,1+f,_,-f,c),S.fx=t(S),S.fx<p[0].fx)J(m,1+u,_,-u,c),m.fx=t(m),m.fx<S.fx?M(m):M(S);else if(S.fx>=p[b-1].fx){let x=!1;if(S.fx>c.fx?(J(g,1+a,_,-a,c),g.fx=t(g),g.fx<c.fx?M(g):x=!0):(J(g,1-a*f,_,a*f,c),g.fx=t(g),g.fx<S.fx?M(g):x=!0),x){if(y>=1)break;for(let d=1;d<p.length;++d)J(p[d],1-y,p[0],y,p[d]),p[d].fx=t(p[d])}}else M(S)}return p.sort(E),{fx:p[0].fx,x:p[0]}}function ue(t,n,s,e,i,o,r){const l=s.fx,f=$(s.fxprime,n);let u=l,a=l,y=f,h=0;i=i||1,o=o||1e-6,r=r||.1;function b(p,M,E){for(let _=0;_<16;++_)if(i=(p+M)/2,J(e.x,1,s.x,i,n),u=e.fx=t(e.x,e.fxprime),y=$(e.fxprime,n),u>l+o*i*f||u>=E)M=i;else{if(Math.abs(y)<=-r*f)return i;y*(M-p)>=0&&(M=p),p=i,E=u}return 0}for(let p=0;p<10;++p){if(J(e.x,1,s.x,i,n),u=e.fx=t(e.x,e.fxprime),y=$(e.fxprime,n),u>l+o*i*f||p&&u>=a)return b(h,i,a);if(Math.abs(y)<=-r*f)return i;if(y>=0)return b(i,h,u);a=u,h=i,i*=2}return i}function fe(t,n,s){let e={x:n.slice(),fx:0,fxprime:n.slice()},i={x:n.slice(),fx:0,fxprime:n.slice()};const o=n.slice();let r,l,f=1,u;s=s||{},u=s.maxIterations||n.length*20,e.fx=t(e.x,e.fxprime),r=e.fxprime.slice(),ft(r,e.fxprime,-1);for(let a=0;a<u;++a){if(f=ue(t,r,e,i,f),s.history&&s.history.push({x:e.x.slice(),fx:e.fx,fxprime:e.fxprime.slice(),alpha:f}),!f)ft(r,e.fxprime,-1);else{J(o,1,i.fxprime,-1,e.fxprime);const y=$(e.fxprime,e.fxprime),h=Math.max(0,$(o,i.fxprime)/y);J(r,h,r,-1,i.fxprime),l=e,e=i,i=l}if(ut(e.fxprime)<=1e-5)break}return s.history&&s.history.push({x:e.x.slice(),fx:e.fx,fxprime:e.fxprime.slice(),alpha:f}),e}function At(t,n={}){n.maxIterations=n.maxIterations||500;const s=n.initialLayout||xe,e=n.lossFunction||tt,i=he(t,n),o=s(i,n),r=Object.keys(o),l=[];for(const a of r)l.push(o[a].x),l.push(o[a].y);const u=zt(a=>{const y={};for(let h=0;h<r.length;++h){const b=r[h];y[b]={x:a[2*h],y:a[2*h+1],radius:o[b].radius}}return e(y,i)},l,n).x;for(let a=0;a<r.length;++a){const y=r[a];o[y].x=u[2*a],o[y].y=u[2*a+1]}return o}const Rt=1e-10;function ht(t,n,s){return Math.min(t,n)*Math.min(t,n)*Math.PI<=s+Rt?Math.abs(t-n):ce(e=>xt(t,n,e)-s,0,t+n)}function he(t,n={}){const s=n.distinct,e=t.map(l=>Object.assign({},l));function i(l){return l.join(";")}if(s){const l=new Map;for(const f of e)for(let u=0;u<f.sets.length;u++){const a=String(f.sets[u]);l.set(a,f.size+(l.get(a)||0));for(let y=u+1;y<f.sets.length;y++){const h=String(f.sets[y]),b=`${a};${h}`,p=`${h};${a}`;l.set(b,f.size+(l.get(b)||0)),l.set(p,f.size+(l.get(p)||0))}}for(const f of e)f.sets.length<3&&(f.size=l.get(i(f.sets)))}const o=[],r=new Set;for(const l of e)if(l.sets.length===1)o.push(l.sets[0]);else if(l.sets.length===2){const f=l.sets[0],u=l.sets[1];r.add(i(l.sets)),r.add(i([u,f]))}o.sort((l,f)=>l===f?0:l<f?-1:1);for(let l=0;l<o.length;++l){const f=o[l];for(let u=l+1;u<o.length;++u){const a=o[u];r.has(i([f,a]))||e.push({sets:[f,a],size:0})}}return e}function de(t,n,s){const e=Mt(n.length,n.length),i=Mt(n.length,n.length);return t.filter(o=>o.sets.length===2).forEach(o=>{const r=s[o.sets[0]],l=s[o.sets[1]],f=Math.sqrt(n[r].size/Math.PI),u=Math.sqrt(n[l].size/Math.PI),a=ht(f,u,o.size);e[r][l]=e[l][r]=a;let y=0;o.size+1e-10>=Math.min(n[r].size,n[l].size)?y=1:o.size<=1e-10&&(y=-1),i[r][l]=i[l][r]=y}),{distances:e,constraints:i}}function ge(t,n,s,e){for(let o=0;o<n.length;++o)n[o]=0;let i=0;for(let o=0;o<s.length;++o){const r=t[2*o],l=t[2*o+1];for(let f=o+1;f<s.length;++f){const u=t[2*f],a=t[2*f+1],y=s[o][f],h=e[o][f],b=(u-r)*(u-r)+(a-l)*(a-l),p=Math.sqrt(b),M=b-y*y;h>0&&p<=y||h<0&&p>=y||(i+=2*M*M,n[2*o]+=4*M*(r-u),n[2*o+1]+=4*M*(l-a),n[2*f]+=4*M*(u-r),n[2*f+1]+=4*M*(a-l))}}return i}function xe(t,n={}){let s=pe(t,n);const e=n.lossFunction||tt;if(t.length>=8){const i=ye(t,n),o=e(i,t),r=e(s,t);o+1e-8<r&&(s=i)}return s}function ye(t,n={}){const s=n.restarts||10,e=[],i={};for(const h of t)h.sets.length===1&&(i[h.sets[0]]=e.length,e.push(h));let{distances:o,constraints:r}=de(t,e,i);const l=ut(o.map(ut))/o.length;o=o.map(h=>h.map(b=>b/l));const f=(h,b)=>ge(h,b,o,r);let u=null;for(let h=0;h<s;++h){const b=ct(o.length*2).map(Math.random),p=fe(f,b,n);(!u||p.fx<u.fx)&&(u=p)}const a=u.x,y={};for(let h=0;h<e.length;++h){const b=e[h];y[b.sets[0]]={x:a[2*h]*l,y:a[2*h+1]*l,radius:Math.sqrt(b.size/Math.PI)}}if(n.history)for(const h of n.history)ft(h.x,l);return y}function pe(t,n){const s=n&&n.lossFunction?n.lossFunction:tt,e={},i={};for(const y of t)if(y.sets.length===1){const h=y.sets[0];e[h]={x:1e10,y:1e10,rowid:e.length,size:y.size,radius:Math.sqrt(y.size/Math.PI)},i[h]=[]}t=t.filter(y=>y.sets.length===2);for(const y of t){let h=y.weight!=null?y.weight:1;const b=y.sets[0],p=y.sets[1];y.size+Rt>=Math.min(e[b].size,e[p].size)&&(h=0),i[b].push({set:p,size:y.size,weight:h}),i[p].push({set:b,size:y.size,weight:h})}const o=[];Object.keys(i).forEach(y=>{let h=0;for(let b=0;b<i[y].length;++b)h+=i[y][b].size*i[y][b].weight;o.push({set:y,size:h})});function r(y,h){return h.size-y.size}o.sort(r);const l={};function f(y){return y.set in l}function u(y,h){e[h].x=y.x,e[h].y=y.y,l[h]=!0}u({x:0,y:0},o[0].set);for(let y=1;y<o.length;++y){const h=o[y].set,b=i[h].filter(f),p=e[h];if(b.sort(r),b.length===0)throw"ERROR: missing pairwise overlap information";const M=[];for(var a=0;a<b.length;++a){const S=e[b[a].set],g=ht(p.radius,S.radius,b[a].size);M.push({x:S.x+g,y:S.y}),M.push({x:S.x-g,y:S.y}),M.push({y:S.y+g,x:S.x}),M.push({y:S.y-g,x:S.x});for(let m=a+1;m<b.length;++m){const v=e[b[m].set],c=ht(p.radius,v.radius,b[m].size),x=Tt({x:S.x,y:S.y,radius:g},{x:v.x,y:v.y,radius:c});M.push(...x)}}let E=1e50,_=M[0];for(const S of M){e[h].x=S.x,e[h].y=S.y;const g=s(e,t);g<E&&(E=g,_=S)}u(_,h)}return e}function tt(t,n){let s=0;for(const e of n){if(e.sets.length===1)continue;let i;if(e.sets.length===2){const r=t[e.sets[0]],l=t[e.sets[1]];i=xt(r.radius,l.radius,q(r,l))}else i=st(e.sets.map(r=>t[r]));const o=e.weight!=null?e.weight:1;s+=o*(i-e.size)*(i-e.size)}return s}function Dt(t,n){let s=0;for(const e of n){if(e.sets.length===1)continue;let i;if(e.sets.length===2){const l=t[e.sets[0]],f=t[e.sets[1]];i=xt(l.radius,f.radius,q(l,f))}else i=st(e.sets.map(l=>t[l]));const o=e.weight!=null?e.weight:1,r=Math.log((i+1)/(e.size+1));s+=o*r*r}return s}function me(t,n,s){if(s==null?t.sort((i,o)=>o.radius-i.radius):t.sort(s),t.length>0){const i=t[0].x,o=t[0].y;for(const r of t)r.x-=i,r.y-=o}if(t.length===2&&q(t[0],t[1])<Math.abs(t[1].radius-t[0].radius)&&(t[1].x=t[0].x+t[0].radius-t[1].radius-1e-10,t[1].y=t[0].y),t.length>1){const i=Math.atan2(t[1].x,t[1].y)-n,o=Math.cos(i),r=Math.sin(i);for(const l of t){const f=l.x,u=l.y;l.x=o*f-r*u,l.y=r*f+o*u}}if(t.length>2){let i=Math.atan2(t[2].x,t[2].y)-n;for(;i<0;)i+=2*Math.PI;for(;i>2*Math.PI;)i-=2*Math.PI;if(i>Math.PI){const o=t[1].y/(1e-10+t[1].x);for(const r of t){var e=(r.x+o*r.y)/(1+o*o);r.x=2*e-r.x,r.y=2*e*o-r.y}}}}function be(t){t.forEach(i=>{i.parent=i});function n(i){return i.parent!==i&&(i.parent=n(i.parent)),i.parent}function s(i,o){const r=n(i),l=n(o);r.parent=l}for(let i=0;i<t.length;++i)for(let o=i+1;o<t.length;++o){const r=t[i].radius+t[o].radius;q(t[i],t[o])+1e-10<r&&s(t[o],t[i])}const e=new Map;for(let i=0;i<t.length;++i){const o=n(t[i]).parent.setid;e.has(o)||e.set(o,[]),e.get(o).push(t[i])}return t.forEach(i=>{delete i.parent}),Array.from(e.values())}function dt(t){const n=s=>{const e=t.reduce((o,r)=>Math.max(o,r[s]+r.radius),Number.NEGATIVE_INFINITY),i=t.reduce((o,r)=>Math.min(o,r[s]-r.radius),Number.POSITIVE_INFINITY);return{max:e,min:i}};return{xRange:n("x"),yRange:n("y")}}function Ct(t,n,s){n==null&&(n=Math.PI/2);let e=Ft(t).map(u=>Object.assign({},u));const i=be(e);for(const u of i){me(u,n,s);const a=dt(u);u.size=(a.xRange.max-a.xRange.min)*(a.yRange.max-a.yRange.min),u.bounds=a}i.sort((u,a)=>a.size-u.size),e=i[0];let o=e.bounds;const r=(o.xRange.max-o.xRange.min)/50;function l(u,a,y){if(!u)return;const h=u.bounds;let b,p;if(a)b=o.xRange.max-h.xRange.min+r;else{b=o.xRange.max-h.xRange.max;const M=(h.xRange.max-h.xRange.min)/2-(o.xRange.max-o.xRange.min)/2;M<0&&(b+=M)}if(y)p=o.yRange.max-h.yRange.min+r;else{p=o.yRange.max-h.yRange.max;const M=(h.yRange.max-h.yRange.min)/2-(o.yRange.max-o.yRange.min)/2;M<0&&(p+=M)}for(const M of u)M.x+=b,M.y+=p,e.push(M)}let f=1;for(;f<i.length;)l(i[f],!0,!1),l(i[f+1],!1,!0),l(i[f+2],!0,!0),f+=3,o=dt(e);return Ot(e)}function Nt(t,n,s,e,i){const o=Ft(t);n-=2*e,s-=2*e;const{xRange:r,yRange:l}=dt(o);if(r.max===r.min||l.max===l.min)return console.log("not scaling solution: zero size detected"),t;let f,u;if(i){const b=Math.sqrt(i/Math.PI)*2;f=n/b,u=s/b}else f=n/(r.max-r.min),u=s/(l.max-l.min);const a=Math.min(u,f),y=(n-(r.max-r.min)*a)/2,h=(s-(l.max-l.min)*a)/2;return Ot(o.map(b=>({radius:a*b.radius,x:e+y+(b.x-r.min)*a,y:e+h+(b.y-l.min)*a,setid:b.setid})))}function Ot(t){const n={};for(const s of t)n[s.setid]=s;return n}function Ft(t){return Object.keys(t).map(s=>Object.assign(t[s],{setid:s}))}function ve(t={}){let n=!1,s=600,e=350,i=15,o=1e3,r=Math.PI/2,l=!0,f=null,u=!0,a=!0,y=null,h=null,b=!1,p=null,M=t&&t.symmetricalTextCentre?t.symmetricalTextCentre:!1,E={},_=t&&t.colourScheme?t.colourScheme:t&&t.colorScheme?t.colorScheme:["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],S=0,g=function(x){if(x in E)return E[x];var d=E[x]=_[S];return S+=1,S>=_.length&&(S=0),d},m=At,v=tt;function c(x){let d=x.datum();const D=new Set;d.forEach(k=>{k.size==0&&k.sets.length==1&&D.add(k.sets[0])}),d=d.filter(k=>!k.sets.some(F=>D.has(F)));let I={},C={};if(d.length>0){let k=m(d,{lossFunction:v,distinct:b});l&&(k=Ct(k,r,h)),I=Nt(k,s,e,i,f),C=Lt(I,d,M)}const U={};d.forEach(k=>{k.label&&(U[k.sets]=k.label)});function V(k){if(k.sets in U)return U[k.sets];if(k.sets.length==1)return""+k.sets[0]}x.selectAll("svg").data([I]).enter().append("svg");const O=x.select("svg");n?O.attr("viewBox",`0 0 ${s} ${e}`):O.attr("width",s).attr("height",e);const R={};let T=!1;O.selectAll(".venn-area path").each(function(k){const F=this.getAttribute("d");k.sets.length==1&&F&&!b&&(T=!0,R[k.sets[0]]=Me(F))});function A(k){return F=>{const H=k.sets.map(et=>{let Y=R[et],Z=I[et];return Y||(Y={x:s/2,y:e/2,radius:1}),Z||(Z={x:s/2,y:e/2,radius:1}),{x:Y.x*(1-F)+Z.x*F,y:Y.y*(1-F)+Z.y*F,radius:Y.radius*(1-F)+Z.radius*F}});return St(H,p)}}const G=O.selectAll(".venn-area").data(d,k=>k.sets),P=G.enter().append("g").attr("class",k=>`venn-area venn-${k.sets.length==1?"circle":"intersection"}${k.colour||k.color?" venn-coloured":""}`).attr("data-venn-sets",k=>k.sets.join("_")),B=P.append("path"),L=P.append("text").attr("class","label").text(k=>V(k)).attr("text-anchor","middle").attr("dy",".35em").attr("x",s/2).attr("y",e/2);a&&(B.style("fill-opacity","0").filter(k=>k.sets.length==1).style("fill",k=>k.colour?k.colour:k.color?k.color:g(k.sets)).style("fill-opacity",".25"),L.style("fill",k=>k.colour||k.color?"#FFF":t.textFill?t.textFill:k.sets.length==1?g(k.sets):"#444"));function K(k){return typeof k.transition=="function"?k.transition("venn").duration(o):k}let z=x;T&&typeof z.transition=="function"?(z=K(x),z.selectAll("path").attrTween("d",A)):z.selectAll("path").attr("d",k=>St(k.sets.map(F=>I[F])),p);const N=z.selectAll("text").filter(k=>k.sets in C).text(k=>V(k)).attr("x",k=>Math.floor(C[k.sets].x)).attr("y",k=>Math.floor(C[k.sets].y));u&&(T?"on"in N?N.on("end",rt(I,V)):N.each("end",rt(I,V)):N.each(rt(I,V)));const j=K(G.exit()).remove();typeof G.transition=="function"&&j.selectAll("path").attrTween("d",A);const X=j.selectAll("text").attr("x",s/2).attr("y",e/2);return y!==null&&(L.style("font-size","0px"),N.style("font-size",y),X.style("font-size","0px")),{circles:I,textCentres:C,nodes:G,enter:P,update:z,exit:j}}return c.wrap=function(x){return arguments.length?(u=x,c):u},c.useViewBox=function(){return n=!0,c},c.width=function(x){return arguments.length?(s=x,c):s},c.height=function(x){return arguments.length?(e=x,c):e},c.padding=function(x){return arguments.length?(i=x,c):i},c.distinct=function(x){return arguments.length?(b=x,c):b},c.colours=function(x){return arguments.length?(g=x,c):g},c.colors=function(x){return arguments.length?(g=x,c):g},c.fontSize=function(x){return arguments.length?(y=x,c):y},c.round=function(x){return arguments.length?(p=x,c):p},c.duration=function(x){return arguments.length?(o=x,c):o},c.layoutFunction=function(x){return arguments.length?(m=x,c):m},c.normalize=function(x){return arguments.length?(l=x,c):l},c.scaleToFit=function(x){return arguments.length?(f=x,c):f},c.styled=function(x){return arguments.length?(a=x,c):a},c.orientation=function(x){return arguments.length?(r=x,c):r},c.orientationOrder=function(x){return arguments.length?(h=x,c):h},c.lossFunction=function(x){return arguments.length?(v=x==="default"?tt:x==="logRatio"?Dt:x,c):v},c}function rt(t,n){return function(s){const e=this,i=t[s.sets[0]].radius||50,o=n(s)||"",r=o.split(/\s+/).reverse(),f=(o.length+r.length)/3;let u=r.pop(),a=[u],y=0;const h=1.1;e.textContent=null;const b=[];function p(g){const m=e.ownerDocument.createElementNS(e.namespaceURI,"tspan");return m.textContent=g,b.push(m),e.append(m),m}let M=p(u);for(;u=r.pop(),!!u;){a.push(u);const g=a.join(" ");M.textContent=g,g.length>f&&M.getComputedTextLength()>i&&(a.pop(),M.textContent=a.join(" "),a=[u],M=p(u),y++)}const E=.35-y*h/2,_=e.getAttribute("x"),S=e.getAttribute("y");b.forEach((g,m)=>{g.setAttribute("x",_),g.setAttribute("y",S),g.setAttribute("dy",`${E+m*h}em`)})}}function at(t,n,s){let e=n[0].radius-q(n[0],t);for(let i=1;i<n.length;++i){const o=n[i].radius-q(n[i],t);o<=e&&(e=o)}for(let i=0;i<s.length;++i){const o=q(s[i],t)-s[i].radius;o<=e&&(e=o)}return e}function jt(t,n,s){const e=[];for(const a of t)e.push({x:a.x,y:a.y}),e.push({x:a.x+a.radius/2,y:a.y}),e.push({x:a.x-a.radius/2,y:a.y}),e.push({x:a.x,y:a.y+a.radius/2}),e.push({x:a.x,y:a.y-a.radius/2});let i=e[0],o=at(e[0],t,n);for(let a=1;a<e.length;++a){const y=at(e[a],t,n);y>=o&&(i=e[a],o=y)}const r=zt(a=>-1*at({x:a[0],y:a[1]},t,n),[i.x,i.y],{maxIterations:500,minErrorDelta:1e-10}).x,l={x:s?0:r[0],y:r[1]};let f=!0;for(const a of t)if(q(l,a)>a.radius){f=!1;break}for(const a of n)if(q(l,a)<a.radius){f=!1;break}if(f)return l;if(t.length==1)return{x:t[0].x,y:t[0].y};const u={};return st(t,u),u.arcs.length===0?{x:0,y:-1e3,disjoint:!0}:u.arcs.length==1?{x:u.arcs[0].circle.x,y:u.arcs[0].circle.y}:n.length?jt(t,[]):Et(u.arcs.map(a=>a.p1))}function Ie(t){const n={},s=Object.keys(t);for(const e of s)n[e]=[];for(let e=0;e<s.length;e++){const i=s[e],o=t[i];for(let r=e+1;r<s.length;++r){const l=s[r],f=t[l],u=q(o,f);u+f.radius<=o.radius+1e-10?n[l].push(i):u+o.radius<=f.radius+1e-10&&n[i].push(l)}}return n}function Lt(t,n,s){const e={},i=Ie(t);for(let o=0;o<n.length;++o){const r=n[o].sets,l={},f={};for(let h=0;h<r.length;++h){l[r[h]]=!0;const b=i[r[h]];for(let p=0;p<b.length;++p)f[b[p]]=!0}const u=[],a=[];for(let h in t)h in l?u.push(t[h]):h in f||a.push(t[h]);const y=jt(u,a,s);e[r]=y,y.disjoint&&n[o].size>0&&console.log("WARNING: area "+r+" not represented on screen")}return e}function ke(t,n,s){const e=[];return e.push(` +import{b4 as Wt,s as Kt,g as Ht,p as Yt,o as Xt,a as Zt,b as Jt,_ as w,z as wt,F as Qt,d as ot,al as $t,aa as te,ab as ee,ac as ne,e as se,q as ie,B as oe,D as re}from"./mermaid.core-CJB1tAev.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";const kt=(t,n)=>Wt(t,"a",-n),_t=1e-10;function st(t,n){const s=le(t),e=s.filter(l=>ae(l,t));let i=0,o=0;const r=[];if(e.length>1){const l=Et(e);for(let u=0;u<e.length;++u){const a=e[u];a.angle=Math.atan2(a.x-l.x,a.y-l.y)}e.sort((u,a)=>a.angle-u.angle);let f=e[e.length-1];for(let u=0;u<e.length;++u){const a=e[u];o+=(f.x+a.x)*(a.y-f.y);const y={x:(a.x+f.x)/2,y:(a.y+f.y)/2};let h=null;for(let b=0;b<a.parentIndex.length;++b)if(f.parentIndex.includes(a.parentIndex[b])){const p=t[a.parentIndex[b]],M=Math.atan2(a.x-p.x,a.y-p.y),E=Math.atan2(f.x-p.x,f.y-p.y);let _=E-M;_<0&&(_+=2*Math.PI);const S=E-_/2;let g=q(y,{x:p.x+p.radius*Math.sin(S),y:p.y+p.radius*Math.cos(S)});g>p.radius*2&&(g=p.radius*2),(h==null||h.width>g)&&(h={circle:p,width:g,p1:a,p2:f,large:g>p.radius,sweep:!0})}h!=null&&(r.push(h),i+=lt(h.circle.radius,h.width),f=a)}}else{let l=t[0];for(let u=1;u<t.length;++u)t[u].radius<l.radius&&(l=t[u]);let f=!1;for(let u=0;u<t.length;++u)if(q(t[u],l)>Math.abs(l.radius-t[u].radius)){f=!0;break}f?i=o=0:(i=l.radius*l.radius*Math.PI,r.push({circle:l,p1:{x:l.x,y:l.y+l.radius},p2:{x:l.x-_t,y:l.y+l.radius},width:l.radius*2,large:!0,sweep:!0}))}return o/=2,n&&(n.area=i+o,n.arcArea=i,n.polygonArea=o,n.arcs=r,n.innerPoints=e,n.intersectionPoints=s),i+o}function ae(t,n){return n.every(s=>q(t,s)<s.radius+_t)}function le(t){const n=[];for(let s=0;s<t.length;++s)for(let e=s+1;e<t.length;++e){const i=Tt(t[s],t[e]);for(const o of i)o.parentIndex=[s,e],n.push(o)}return n}function lt(t,n){return t*t*Math.acos(1-n/t)-(t-n)*Math.sqrt(n*(2*t-n))}function q(t,n){return Math.sqrt((t.x-n.x)*(t.x-n.x)+(t.y-n.y)*(t.y-n.y))}function xt(t,n,s){if(s>=t+n)return 0;if(s<=Math.abs(t-n))return Math.PI*Math.min(t,n)*Math.min(t,n);const e=t-(s*s-n*n+t*t)/(2*s),i=n-(s*s-t*t+n*n)/(2*s);return lt(t,e)+lt(n,i)}function Tt(t,n){const s=q(t,n),e=t.radius,i=n.radius;if(s>=e+i||s<=Math.abs(e-i))return[];const o=(e*e-i*i+s*s)/(2*s),r=Math.sqrt(e*e-o*o),l=t.x+o*(n.x-t.x)/s,f=t.y+o*(n.y-t.y)/s,u=-(n.y-t.y)*(r/s),a=-(n.x-t.x)*(r/s);return[{x:l+u,y:f-a},{x:l-u,y:f+a}]}function Et(t){const n={x:0,y:0};for(const s of t)n.x+=s.x,n.y+=s.y;return n.x/=t.length,n.y/=t.length,n}function ce(t,n,s,e){e=e||{};const i=e.maxIterations||100,o=e.tolerance||1e-10,r=t(n),l=t(s);let f=s-n;if(r*l>0)throw"Initial bisect points must have opposite signs";if(r===0)return n;if(l===0)return s;for(let u=0;u<i;++u){f/=2;const a=n+f,y=t(a);if(y*r>=0&&(n=a),Math.abs(f)<o||y===0)return a}return n+f}function ct(t){const n=new Array(t);for(let s=0;s<t;++s)n[s]=0;return n}function Mt(t,n){return ct(t).map(()=>ct(n))}function $(t,n){let s=0;for(let e=0;e<t.length;++e)s+=t[e]*n[e];return s}function ut(t){return Math.sqrt($(t,t))}function ft(t,n,s){for(let e=0;e<n.length;++e)t[e]=n[e]*s}function J(t,n,s,e,i){for(let o=0;o<t.length;++o)t[o]=n*s[o]+e*i[o]}function zt(t,n,s){s=s||{};const e=s.maxIterations||n.length*200,i=s.nonZeroDelta||1.05,o=s.zeroDelta||.001,r=s.minErrorDelta||1e-6,l=s.minErrorDelta||1e-5,f=s.rho!==void 0?s.rho:1,u=s.chi!==void 0?s.chi:2,a=s.psi!==void 0?s.psi:-.5,y=s.sigma!==void 0?s.sigma:.5;let h;const b=n.length,p=new Array(b+1);p[0]=n,p[0].fx=t(n),p[0].id=0;for(let v=0;v<b;++v){const c=n.slice();c[v]=c[v]?c[v]*i:o,p[v+1]=c,p[v+1].fx=t(c),p[v+1].id=v+1}function M(v){for(let c=0;c<v.length;c++)p[b][c]=v[c];p[b].fx=v.fx}const E=(v,c)=>v.fx-c.fx,_=n.slice(),S=n.slice(),g=n.slice(),m=n.slice();for(let v=0;v<e;++v){if(p.sort(E),s.history){const x=p.map(d=>{const D=d.slice();return D.fx=d.fx,D.id=d.id,D});x.sort((d,D)=>d.id-D.id),s.history.push({x:p[0].slice(),fx:p[0].fx,simplex:x})}h=0;for(let x=0;x<b;++x)h=Math.max(h,Math.abs(p[0][x]-p[1][x]));if(Math.abs(p[0].fx-p[b].fx)<r&&h<l)break;for(let x=0;x<b;++x){_[x]=0;for(let d=0;d<b;++d)_[x]+=p[d][x];_[x]/=b}const c=p[b];if(J(S,1+f,_,-f,c),S.fx=t(S),S.fx<p[0].fx)J(m,1+u,_,-u,c),m.fx=t(m),m.fx<S.fx?M(m):M(S);else if(S.fx>=p[b-1].fx){let x=!1;if(S.fx>c.fx?(J(g,1+a,_,-a,c),g.fx=t(g),g.fx<c.fx?M(g):x=!0):(J(g,1-a*f,_,a*f,c),g.fx=t(g),g.fx<S.fx?M(g):x=!0),x){if(y>=1)break;for(let d=1;d<p.length;++d)J(p[d],1-y,p[0],y,p[d]),p[d].fx=t(p[d])}}else M(S)}return p.sort(E),{fx:p[0].fx,x:p[0]}}function ue(t,n,s,e,i,o,r){const l=s.fx,f=$(s.fxprime,n);let u=l,a=l,y=f,h=0;i=i||1,o=o||1e-6,r=r||.1;function b(p,M,E){for(let _=0;_<16;++_)if(i=(p+M)/2,J(e.x,1,s.x,i,n),u=e.fx=t(e.x,e.fxprime),y=$(e.fxprime,n),u>l+o*i*f||u>=E)M=i;else{if(Math.abs(y)<=-r*f)return i;y*(M-p)>=0&&(M=p),p=i,E=u}return 0}for(let p=0;p<10;++p){if(J(e.x,1,s.x,i,n),u=e.fx=t(e.x,e.fxprime),y=$(e.fxprime,n),u>l+o*i*f||p&&u>=a)return b(h,i,a);if(Math.abs(y)<=-r*f)return i;if(y>=0)return b(i,h,u);a=u,h=i,i*=2}return i}function fe(t,n,s){let e={x:n.slice(),fx:0,fxprime:n.slice()},i={x:n.slice(),fx:0,fxprime:n.slice()};const o=n.slice();let r,l,f=1,u;s=s||{},u=s.maxIterations||n.length*20,e.fx=t(e.x,e.fxprime),r=e.fxprime.slice(),ft(r,e.fxprime,-1);for(let a=0;a<u;++a){if(f=ue(t,r,e,i,f),s.history&&s.history.push({x:e.x.slice(),fx:e.fx,fxprime:e.fxprime.slice(),alpha:f}),!f)ft(r,e.fxprime,-1);else{J(o,1,i.fxprime,-1,e.fxprime);const y=$(e.fxprime,e.fxprime),h=Math.max(0,$(o,i.fxprime)/y);J(r,h,r,-1,i.fxprime),l=e,e=i,i=l}if(ut(e.fxprime)<=1e-5)break}return s.history&&s.history.push({x:e.x.slice(),fx:e.fx,fxprime:e.fxprime.slice(),alpha:f}),e}function At(t,n={}){n.maxIterations=n.maxIterations||500;const s=n.initialLayout||xe,e=n.lossFunction||tt,i=he(t,n),o=s(i,n),r=Object.keys(o),l=[];for(const a of r)l.push(o[a].x),l.push(o[a].y);const u=zt(a=>{const y={};for(let h=0;h<r.length;++h){const b=r[h];y[b]={x:a[2*h],y:a[2*h+1],radius:o[b].radius}}return e(y,i)},l,n).x;for(let a=0;a<r.length;++a){const y=r[a];o[y].x=u[2*a],o[y].y=u[2*a+1]}return o}const Rt=1e-10;function ht(t,n,s){return Math.min(t,n)*Math.min(t,n)*Math.PI<=s+Rt?Math.abs(t-n):ce(e=>xt(t,n,e)-s,0,t+n)}function he(t,n={}){const s=n.distinct,e=t.map(l=>Object.assign({},l));function i(l){return l.join(";")}if(s){const l=new Map;for(const f of e)for(let u=0;u<f.sets.length;u++){const a=String(f.sets[u]);l.set(a,f.size+(l.get(a)||0));for(let y=u+1;y<f.sets.length;y++){const h=String(f.sets[y]),b=`${a};${h}`,p=`${h};${a}`;l.set(b,f.size+(l.get(b)||0)),l.set(p,f.size+(l.get(p)||0))}}for(const f of e)f.sets.length<3&&(f.size=l.get(i(f.sets)))}const o=[],r=new Set;for(const l of e)if(l.sets.length===1)o.push(l.sets[0]);else if(l.sets.length===2){const f=l.sets[0],u=l.sets[1];r.add(i(l.sets)),r.add(i([u,f]))}o.sort((l,f)=>l===f?0:l<f?-1:1);for(let l=0;l<o.length;++l){const f=o[l];for(let u=l+1;u<o.length;++u){const a=o[u];r.has(i([f,a]))||e.push({sets:[f,a],size:0})}}return e}function de(t,n,s){const e=Mt(n.length,n.length),i=Mt(n.length,n.length);return t.filter(o=>o.sets.length===2).forEach(o=>{const r=s[o.sets[0]],l=s[o.sets[1]],f=Math.sqrt(n[r].size/Math.PI),u=Math.sqrt(n[l].size/Math.PI),a=ht(f,u,o.size);e[r][l]=e[l][r]=a;let y=0;o.size+1e-10>=Math.min(n[r].size,n[l].size)?y=1:o.size<=1e-10&&(y=-1),i[r][l]=i[l][r]=y}),{distances:e,constraints:i}}function ge(t,n,s,e){for(let o=0;o<n.length;++o)n[o]=0;let i=0;for(let o=0;o<s.length;++o){const r=t[2*o],l=t[2*o+1];for(let f=o+1;f<s.length;++f){const u=t[2*f],a=t[2*f+1],y=s[o][f],h=e[o][f],b=(u-r)*(u-r)+(a-l)*(a-l),p=Math.sqrt(b),M=b-y*y;h>0&&p<=y||h<0&&p>=y||(i+=2*M*M,n[2*o]+=4*M*(r-u),n[2*o+1]+=4*M*(l-a),n[2*f]+=4*M*(u-r),n[2*f+1]+=4*M*(a-l))}}return i}function xe(t,n={}){let s=pe(t,n);const e=n.lossFunction||tt;if(t.length>=8){const i=ye(t,n),o=e(i,t),r=e(s,t);o+1e-8<r&&(s=i)}return s}function ye(t,n={}){const s=n.restarts||10,e=[],i={};for(const h of t)h.sets.length===1&&(i[h.sets[0]]=e.length,e.push(h));let{distances:o,constraints:r}=de(t,e,i);const l=ut(o.map(ut))/o.length;o=o.map(h=>h.map(b=>b/l));const f=(h,b)=>ge(h,b,o,r);let u=null;for(let h=0;h<s;++h){const b=ct(o.length*2).map(Math.random),p=fe(f,b,n);(!u||p.fx<u.fx)&&(u=p)}const a=u.x,y={};for(let h=0;h<e.length;++h){const b=e[h];y[b.sets[0]]={x:a[2*h]*l,y:a[2*h+1]*l,radius:Math.sqrt(b.size/Math.PI)}}if(n.history)for(const h of n.history)ft(h.x,l);return y}function pe(t,n){const s=n&&n.lossFunction?n.lossFunction:tt,e={},i={};for(const y of t)if(y.sets.length===1){const h=y.sets[0];e[h]={x:1e10,y:1e10,rowid:e.length,size:y.size,radius:Math.sqrt(y.size/Math.PI)},i[h]=[]}t=t.filter(y=>y.sets.length===2);for(const y of t){let h=y.weight!=null?y.weight:1;const b=y.sets[0],p=y.sets[1];y.size+Rt>=Math.min(e[b].size,e[p].size)&&(h=0),i[b].push({set:p,size:y.size,weight:h}),i[p].push({set:b,size:y.size,weight:h})}const o=[];Object.keys(i).forEach(y=>{let h=0;for(let b=0;b<i[y].length;++b)h+=i[y][b].size*i[y][b].weight;o.push({set:y,size:h})});function r(y,h){return h.size-y.size}o.sort(r);const l={};function f(y){return y.set in l}function u(y,h){e[h].x=y.x,e[h].y=y.y,l[h]=!0}u({x:0,y:0},o[0].set);for(let y=1;y<o.length;++y){const h=o[y].set,b=i[h].filter(f),p=e[h];if(b.sort(r),b.length===0)throw"ERROR: missing pairwise overlap information";const M=[];for(var a=0;a<b.length;++a){const S=e[b[a].set],g=ht(p.radius,S.radius,b[a].size);M.push({x:S.x+g,y:S.y}),M.push({x:S.x-g,y:S.y}),M.push({y:S.y+g,x:S.x}),M.push({y:S.y-g,x:S.x});for(let m=a+1;m<b.length;++m){const v=e[b[m].set],c=ht(p.radius,v.radius,b[m].size),x=Tt({x:S.x,y:S.y,radius:g},{x:v.x,y:v.y,radius:c});M.push(...x)}}let E=1e50,_=M[0];for(const S of M){e[h].x=S.x,e[h].y=S.y;const g=s(e,t);g<E&&(E=g,_=S)}u(_,h)}return e}function tt(t,n){let s=0;for(const e of n){if(e.sets.length===1)continue;let i;if(e.sets.length===2){const r=t[e.sets[0]],l=t[e.sets[1]];i=xt(r.radius,l.radius,q(r,l))}else i=st(e.sets.map(r=>t[r]));const o=e.weight!=null?e.weight:1;s+=o*(i-e.size)*(i-e.size)}return s}function Dt(t,n){let s=0;for(const e of n){if(e.sets.length===1)continue;let i;if(e.sets.length===2){const l=t[e.sets[0]],f=t[e.sets[1]];i=xt(l.radius,f.radius,q(l,f))}else i=st(e.sets.map(l=>t[l]));const o=e.weight!=null?e.weight:1,r=Math.log((i+1)/(e.size+1));s+=o*r*r}return s}function me(t,n,s){if(s==null?t.sort((i,o)=>o.radius-i.radius):t.sort(s),t.length>0){const i=t[0].x,o=t[0].y;for(const r of t)r.x-=i,r.y-=o}if(t.length===2&&q(t[0],t[1])<Math.abs(t[1].radius-t[0].radius)&&(t[1].x=t[0].x+t[0].radius-t[1].radius-1e-10,t[1].y=t[0].y),t.length>1){const i=Math.atan2(t[1].x,t[1].y)-n,o=Math.cos(i),r=Math.sin(i);for(const l of t){const f=l.x,u=l.y;l.x=o*f-r*u,l.y=r*f+o*u}}if(t.length>2){let i=Math.atan2(t[2].x,t[2].y)-n;for(;i<0;)i+=2*Math.PI;for(;i>2*Math.PI;)i-=2*Math.PI;if(i>Math.PI){const o=t[1].y/(1e-10+t[1].x);for(const r of t){var e=(r.x+o*r.y)/(1+o*o);r.x=2*e-r.x,r.y=2*e*o-r.y}}}}function be(t){t.forEach(i=>{i.parent=i});function n(i){return i.parent!==i&&(i.parent=n(i.parent)),i.parent}function s(i,o){const r=n(i),l=n(o);r.parent=l}for(let i=0;i<t.length;++i)for(let o=i+1;o<t.length;++o){const r=t[i].radius+t[o].radius;q(t[i],t[o])+1e-10<r&&s(t[o],t[i])}const e=new Map;for(let i=0;i<t.length;++i){const o=n(t[i]).parent.setid;e.has(o)||e.set(o,[]),e.get(o).push(t[i])}return t.forEach(i=>{delete i.parent}),Array.from(e.values())}function dt(t){const n=s=>{const e=t.reduce((o,r)=>Math.max(o,r[s]+r.radius),Number.NEGATIVE_INFINITY),i=t.reduce((o,r)=>Math.min(o,r[s]-r.radius),Number.POSITIVE_INFINITY);return{max:e,min:i}};return{xRange:n("x"),yRange:n("y")}}function Ct(t,n,s){n==null&&(n=Math.PI/2);let e=Ft(t).map(u=>Object.assign({},u));const i=be(e);for(const u of i){me(u,n,s);const a=dt(u);u.size=(a.xRange.max-a.xRange.min)*(a.yRange.max-a.yRange.min),u.bounds=a}i.sort((u,a)=>a.size-u.size),e=i[0];let o=e.bounds;const r=(o.xRange.max-o.xRange.min)/50;function l(u,a,y){if(!u)return;const h=u.bounds;let b,p;if(a)b=o.xRange.max-h.xRange.min+r;else{b=o.xRange.max-h.xRange.max;const M=(h.xRange.max-h.xRange.min)/2-(o.xRange.max-o.xRange.min)/2;M<0&&(b+=M)}if(y)p=o.yRange.max-h.yRange.min+r;else{p=o.yRange.max-h.yRange.max;const M=(h.yRange.max-h.yRange.min)/2-(o.yRange.max-o.yRange.min)/2;M<0&&(p+=M)}for(const M of u)M.x+=b,M.y+=p,e.push(M)}let f=1;for(;f<i.length;)l(i[f],!0,!1),l(i[f+1],!1,!0),l(i[f+2],!0,!0),f+=3,o=dt(e);return Ot(e)}function Nt(t,n,s,e,i){const o=Ft(t);n-=2*e,s-=2*e;const{xRange:r,yRange:l}=dt(o);if(r.max===r.min||l.max===l.min)return console.log("not scaling solution: zero size detected"),t;let f,u;if(i){const b=Math.sqrt(i/Math.PI)*2;f=n/b,u=s/b}else f=n/(r.max-r.min),u=s/(l.max-l.min);const a=Math.min(u,f),y=(n-(r.max-r.min)*a)/2,h=(s-(l.max-l.min)*a)/2;return Ot(o.map(b=>({radius:a*b.radius,x:e+y+(b.x-r.min)*a,y:e+h+(b.y-l.min)*a,setid:b.setid})))}function Ot(t){const n={};for(const s of t)n[s.setid]=s;return n}function Ft(t){return Object.keys(t).map(s=>Object.assign(t[s],{setid:s}))}function ve(t={}){let n=!1,s=600,e=350,i=15,o=1e3,r=Math.PI/2,l=!0,f=null,u=!0,a=!0,y=null,h=null,b=!1,p=null,M=t&&t.symmetricalTextCentre?t.symmetricalTextCentre:!1,E={},_=t&&t.colourScheme?t.colourScheme:t&&t.colorScheme?t.colorScheme:["#1f77b4","#ff7f0e","#2ca02c","#d62728","#9467bd","#8c564b","#e377c2","#7f7f7f","#bcbd22","#17becf"],S=0,g=function(x){if(x in E)return E[x];var d=E[x]=_[S];return S+=1,S>=_.length&&(S=0),d},m=At,v=tt;function c(x){let d=x.datum();const D=new Set;d.forEach(k=>{k.size==0&&k.sets.length==1&&D.add(k.sets[0])}),d=d.filter(k=>!k.sets.some(F=>D.has(F)));let I={},C={};if(d.length>0){let k=m(d,{lossFunction:v,distinct:b});l&&(k=Ct(k,r,h)),I=Nt(k,s,e,i,f),C=Lt(I,d,M)}const U={};d.forEach(k=>{k.label&&(U[k.sets]=k.label)});function V(k){if(k.sets in U)return U[k.sets];if(k.sets.length==1)return""+k.sets[0]}x.selectAll("svg").data([I]).enter().append("svg");const O=x.select("svg");n?O.attr("viewBox",`0 0 ${s} ${e}`):O.attr("width",s).attr("height",e);const R={};let T=!1;O.selectAll(".venn-area path").each(function(k){const F=this.getAttribute("d");k.sets.length==1&&F&&!b&&(T=!0,R[k.sets[0]]=Me(F))});function A(k){return F=>{const H=k.sets.map(et=>{let Y=R[et],Z=I[et];return Y||(Y={x:s/2,y:e/2,radius:1}),Z||(Z={x:s/2,y:e/2,radius:1}),{x:Y.x*(1-F)+Z.x*F,y:Y.y*(1-F)+Z.y*F,radius:Y.radius*(1-F)+Z.radius*F}});return St(H,p)}}const G=O.selectAll(".venn-area").data(d,k=>k.sets),P=G.enter().append("g").attr("class",k=>`venn-area venn-${k.sets.length==1?"circle":"intersection"}${k.colour||k.color?" venn-coloured":""}`).attr("data-venn-sets",k=>k.sets.join("_")),B=P.append("path"),L=P.append("text").attr("class","label").text(k=>V(k)).attr("text-anchor","middle").attr("dy",".35em").attr("x",s/2).attr("y",e/2);a&&(B.style("fill-opacity","0").filter(k=>k.sets.length==1).style("fill",k=>k.colour?k.colour:k.color?k.color:g(k.sets)).style("fill-opacity",".25"),L.style("fill",k=>k.colour||k.color?"#FFF":t.textFill?t.textFill:k.sets.length==1?g(k.sets):"#444"));function K(k){return typeof k.transition=="function"?k.transition("venn").duration(o):k}let z=x;T&&typeof z.transition=="function"?(z=K(x),z.selectAll("path").attrTween("d",A)):z.selectAll("path").attr("d",k=>St(k.sets.map(F=>I[F])),p);const N=z.selectAll("text").filter(k=>k.sets in C).text(k=>V(k)).attr("x",k=>Math.floor(C[k.sets].x)).attr("y",k=>Math.floor(C[k.sets].y));u&&(T?"on"in N?N.on("end",rt(I,V)):N.each("end",rt(I,V)):N.each(rt(I,V)));const j=K(G.exit()).remove();typeof G.transition=="function"&&j.selectAll("path").attrTween("d",A);const X=j.selectAll("text").attr("x",s/2).attr("y",e/2);return y!==null&&(L.style("font-size","0px"),N.style("font-size",y),X.style("font-size","0px")),{circles:I,textCentres:C,nodes:G,enter:P,update:z,exit:j}}return c.wrap=function(x){return arguments.length?(u=x,c):u},c.useViewBox=function(){return n=!0,c},c.width=function(x){return arguments.length?(s=x,c):s},c.height=function(x){return arguments.length?(e=x,c):e},c.padding=function(x){return arguments.length?(i=x,c):i},c.distinct=function(x){return arguments.length?(b=x,c):b},c.colours=function(x){return arguments.length?(g=x,c):g},c.colors=function(x){return arguments.length?(g=x,c):g},c.fontSize=function(x){return arguments.length?(y=x,c):y},c.round=function(x){return arguments.length?(p=x,c):p},c.duration=function(x){return arguments.length?(o=x,c):o},c.layoutFunction=function(x){return arguments.length?(m=x,c):m},c.normalize=function(x){return arguments.length?(l=x,c):l},c.scaleToFit=function(x){return arguments.length?(f=x,c):f},c.styled=function(x){return arguments.length?(a=x,c):a},c.orientation=function(x){return arguments.length?(r=x,c):r},c.orientationOrder=function(x){return arguments.length?(h=x,c):h},c.lossFunction=function(x){return arguments.length?(v=x==="default"?tt:x==="logRatio"?Dt:x,c):v},c}function rt(t,n){return function(s){const e=this,i=t[s.sets[0]].radius||50,o=n(s)||"",r=o.split(/\s+/).reverse(),f=(o.length+r.length)/3;let u=r.pop(),a=[u],y=0;const h=1.1;e.textContent=null;const b=[];function p(g){const m=e.ownerDocument.createElementNS(e.namespaceURI,"tspan");return m.textContent=g,b.push(m),e.append(m),m}let M=p(u);for(;u=r.pop(),!!u;){a.push(u);const g=a.join(" ");M.textContent=g,g.length>f&&M.getComputedTextLength()>i&&(a.pop(),M.textContent=a.join(" "),a=[u],M=p(u),y++)}const E=.35-y*h/2,_=e.getAttribute("x"),S=e.getAttribute("y");b.forEach((g,m)=>{g.setAttribute("x",_),g.setAttribute("y",S),g.setAttribute("dy",`${E+m*h}em`)})}}function at(t,n,s){let e=n[0].radius-q(n[0],t);for(let i=1;i<n.length;++i){const o=n[i].radius-q(n[i],t);o<=e&&(e=o)}for(let i=0;i<s.length;++i){const o=q(s[i],t)-s[i].radius;o<=e&&(e=o)}return e}function jt(t,n,s){const e=[];for(const a of t)e.push({x:a.x,y:a.y}),e.push({x:a.x+a.radius/2,y:a.y}),e.push({x:a.x-a.radius/2,y:a.y}),e.push({x:a.x,y:a.y+a.radius/2}),e.push({x:a.x,y:a.y-a.radius/2});let i=e[0],o=at(e[0],t,n);for(let a=1;a<e.length;++a){const y=at(e[a],t,n);y>=o&&(i=e[a],o=y)}const r=zt(a=>-1*at({x:a[0],y:a[1]},t,n),[i.x,i.y],{maxIterations:500,minErrorDelta:1e-10}).x,l={x:s?0:r[0],y:r[1]};let f=!0;for(const a of t)if(q(l,a)>a.radius){f=!1;break}for(const a of n)if(q(l,a)<a.radius){f=!1;break}if(f)return l;if(t.length==1)return{x:t[0].x,y:t[0].y};const u={};return st(t,u),u.arcs.length===0?{x:0,y:-1e3,disjoint:!0}:u.arcs.length==1?{x:u.arcs[0].circle.x,y:u.arcs[0].circle.y}:n.length?jt(t,[]):Et(u.arcs.map(a=>a.p1))}function Ie(t){const n={},s=Object.keys(t);for(const e of s)n[e]=[];for(let e=0;e<s.length;e++){const i=s[e],o=t[i];for(let r=e+1;r<s.length;++r){const l=s[r],f=t[l],u=q(o,f);u+f.radius<=o.radius+1e-10?n[l].push(i):u+o.radius<=f.radius+1e-10&&n[i].push(l)}}return n}function Lt(t,n,s){const e={},i=Ie(t);for(let o=0;o<n.length;++o){const r=n[o].sets,l={},f={};for(let h=0;h<r.length;++h){l[r[h]]=!0;const b=i[r[h]];for(let p=0;p<b.length;++p)f[b[p]]=!0}const u=[],a=[];for(let h in t)h in l?u.push(t[h]):h in f||a.push(t[h]);const y=jt(u,a,s);e[r]=y,y.disjoint&&n[o].size>0&&console.log("WARNING: area "+r+" not represented on screen")}return e}function ke(t,n,s){const e=[];return e.push(` M`,t,n),e.push(` m`,-s,0),e.push(` a`,s,s,0,1,0,s*2,0),e.push(` diff --git a/apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-DL_Wfh3f.js b/apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-J0WjtLlK.js similarity index 98% rename from apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-DL_Wfh3f.js rename to apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-J0WjtLlK.js index 53544b5dd..6f6ac377f 100644 --- a/apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-DL_Wfh3f.js +++ b/apps/kimi-code/dist-web/assets/vue.runtime.esm-bundler-J0WjtLlK.js @@ -1,4 +1,4 @@ -import{B as t,a as o,C as r,D as n,E as i,b as c,c as l,F as d,K as p,R as b,S as m,d as f,T as u,e as h,f as S,g as y,h as R,i as v,V as C,j as g,k as w,l as T,m as E,n as x,o as M,p as k,q as D,r as P,s as V,t as A,u as B,v as H,w as N,x as O,y as I,z,A as F,G as U,H as K,I as W,J as j,L as q,M as G,N as L,O as J,P as Q,Q as X,U as Y,W as Z,X as _,Y as $,Z as aa,_ as ea,$ as sa,a0 as ta,a1 as oa,a2 as ra,a3 as na,a4 as ia,a5 as ca,a6 as la,a7 as da,a8 as pa,a9 as ba,aa as ma,ab as fa,ac as ua,ad as ha,ae as Sa,af as ya,ag as Ra,ah as va,ai as Ca,aj as ga,ak as wa,al as Ta,am as Ea,an as xa,ao as Ma,ap as ka,aq as Da,ar as Pa,as as Va,at as Aa,au as Ba,av as Ha,aw as Na,ax as Oa,ay as Ia,az as za,aA as Fa,aB as Ua,aC as Ka,aD as Wa,aE as ja,aF as qa,aG as Ga,aH as La,aI as Ja,aJ as Qa,aK as Xa,aL as Ya,aM as Za,aN as _a,aO as $a,aP as ae,aQ as ee,aR as se,aS as te,aT as oe,aU as re,aV as ne,aW as ie,aX as ce,aY as le,aZ as de,a_ as pe,a$ as be,b0 as me,b1 as fe,b2 as ue,b3 as he,b4 as Se,b5 as ye,b6 as Re,b7 as ve,b8 as Ce,b9 as ge,ba as we,bb as Te,bc as Ee,bd as xe,be as Me,bf as ke,bg as De,bh as Pe,bi as Ve,bj as Ae,bk as Be,bl as He,bm as Ne,bn as Oe,bo as Ie,bp as ze,bq as Fe,br as Ue,bs as Ke,bt as We,bu as je,bv as qe,bw as Ge,bx as Le,by as Je,bz as Qe,bA as Xe,bB as Ye,bC as Ze,bD as _e,bE as $e,bF as as,bG as es,bH as ss,bI as ts,bJ as os,bK as rs,bL as ns,bM as is,bN as cs,bO as ls,bP as ds}from"./index-D1h84VfZ.js";/** +import{B as t,a as o,C as r,D as n,E as i,b as c,c as l,F as d,K as p,R as b,S as m,d as f,T as u,e as h,f as S,g as y,h as R,i as v,V as C,j as g,k as w,l as T,m as E,n as x,o as M,p as k,q as D,r as P,s as V,t as A,u as B,v as H,w as N,x as O,y as I,z,A as F,G as U,H as K,I as W,J as j,L as q,M as G,N as L,O as J,P as Q,Q as X,U as Y,W as Z,X as _,Y as $,Z as aa,_ as ea,$ as sa,a0 as ta,a1 as oa,a2 as ra,a3 as na,a4 as ia,a5 as ca,a6 as la,a7 as da,a8 as pa,a9 as ba,aa as ma,ab as fa,ac as ua,ad as ha,ae as Sa,af as ya,ag as Ra,ah as va,ai as Ca,aj as ga,ak as wa,al as Ta,am as Ea,an as xa,ao as Ma,ap as ka,aq as Da,ar as Pa,as as Va,at as Aa,au as Ba,av as Ha,aw as Na,ax as Oa,ay as Ia,az as za,aA as Fa,aB as Ua,aC as Ka,aD as Wa,aE as ja,aF as qa,aG as Ga,aH as La,aI as Ja,aJ as Qa,aK as Xa,aL as Ya,aM as Za,aN as _a,aO as $a,aP as ae,aQ as ee,aR as se,aS as te,aT as oe,aU as re,aV as ne,aW as ie,aX as ce,aY as le,aZ as de,a_ as pe,a$ as be,b0 as me,b1 as fe,b2 as ue,b3 as he,b4 as Se,b5 as ye,b6 as Re,b7 as ve,b8 as Ce,b9 as ge,ba as we,bb as Te,bc as Ee,bd as xe,be as Me,bf as ke,bg as De,bh as Pe,bi as Ve,bj as Ae,bk as Be,bl as He,bm as Ne,bn as Oe,bo as Ie,bp as ze,bq as Fe,br as Ue,bs as Ke,bt as We,bu as je,bv as qe,bw as Ge,bx as Le,by as Je,bz as Qe,bA as Xe,bB as Ye,bC as Ze,bD as _e,bE as $e,bF as as,bG as es,bH as ss,bI as ts,bJ as os,bK as rs,bL as ns,bM as is,bN as cs,bO as ls,bP as ds}from"./index-D-7nOosq.js";/** * vue v3.5.39 * (c) 2018-present Yuxi (Evan) You and Vue contributors * @license MIT diff --git a/apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-DVjnwE-A.js b/apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-BuQJYWm-.js similarity index 99% rename from apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-DVjnwE-A.js rename to apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-BuQJYWm-.js index bb679a834..51ea34397 100644 --- a/apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-DVjnwE-A.js +++ b/apps/kimi-code/dist-web/assets/wardleyDiagram-EHGQE667-BuQJYWm-.js @@ -1,4 +1,4 @@ -import{p as St}from"./chunk-JWPE2WC7-XhS5NGpP.js";import{s as Mt,g as Nt,p as zt,o as Lt,a as Tt,b as At,_ as u,W as Xt,z as Et,B as U,l as K,F as Yt,e as It,q as Bt,c as j}from"./mermaid.core-DaDTfY6S.js";import{p as Ft}from"./cynefin-VYW2F7L2-0NmB13eq.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";var D=u((e,n)=>{const r=e<=1?e*100:e;if(r<0||r>100)throw new Error(`${n} must be between 0-1 (decimal) or 0-100 (percentage). Received: ${e}`);return r},"toPercent"),A=u((e,n,r)=>({x:D(n,`${r} evolution`),y:D(e,`${r} visibility`)}),"toCoordinates"),J=u(e=>{if(e){if(e==="+<>")return"bidirectional";if(e==="+<")return"backward";if(e==="+>")return"forward"}},"getFlowFromPort"),Rt=u(e=>{if(!e?.startsWith("+"))return{};const r=/^\+'([^']*)'/.exec(e)?.[1];return e.includes("<>")?{flow:"bidirectional",label:r}:e.includes("<")?{flow:"backward",label:r}:e.includes(">")?{flow:"forward",label:r}:{label:r}},"extractFlowFromArrow"),Ot=u((e,n)=>{if(St(e,n),e.size&&n.setSize(e.size.width,e.size.height),e.evolution){const r=e.evolution.stages.map(a=>a.secondName?`${a.name.trim()} / ${a.secondName.trim()}`:a.name.trim()),x=e.evolution.stages.filter(a=>a.boundary!==void 0).map(a=>a.boundary);n.updateAxes({stages:r,stageBoundaries:x})}if(e.anchors.forEach(r=>{const x=A(r.visibility,r.evolution,`Anchor "${r.name}"`);n.addNode(r.name,r.name,x.x,x.y,"anchor")}),e.components.forEach(r=>{const x=A(r.visibility,r.evolution,`Component "${r.name}"`),a=r.label?(r.label.negX?-1:1)*r.label.offsetX:void 0,d=r.label?(r.label.negY?-1:1)*r.label.offsetY:void 0,w=r.decorator?.strategy;n.addNode(r.name,r.name,x.x,x.y,"component",a,d,r.inertia,w)}),e.notes.forEach(r=>{const x=A(r.visibility,r.evolution,`Note "${r.text}"`);n.addNote(r.text,x.x,x.y)}),e.pipelines.forEach(r=>{const x=n.getNode(r.parent);if(!x||typeof x.y!="number")throw new Error(`Pipeline "${r.parent}" must reference an existing component with coordinates.`);const a=x.y;n.startPipeline(r.parent),r.components.forEach(d=>{const w=`${r.parent}_${d.name}`,C=d.label?(d.label.negX?-1:1)*d.label.offsetX:void 0,g=d.label?(d.label.negY?-1:1)*d.label.offsetY:void 0,F=D(d.evolution,`Pipeline component "${d.name}" evolution`);n.addNode(w,d.name,F,a,"pipeline-component",C,g),n.addPipelineComponent(r.parent,w)})}),e.links.forEach(r=>{const x=!!r.arrow&&(r.arrow.includes("-.->")||r.arrow.includes(".-."));let a=J(r.fromPort)??J(r.toPort);const{flow:d,label:w}=Rt(r.arrow);!a&&d&&(a=d);const C=r.linkLabel,g=w??C;n.addLink(n.resolveNodeId(r.from),n.resolveNodeId(r.to),x,g,a)}),e.evolves.forEach(r=>{const x=n.getNode(r.component);if(x?.y!==void 0){const a=D(r.target,`Evolve target for "${r.component}"`);n.addTrend(r.component,a,x.y)}}),e.annotations.length>0){const r=e.annotations[0],x=A(r.x,r.y,"Annotations box");n.setAnnotationsBox(x.x,x.y)}e.annotation.forEach(r=>{const x=A(r.x,r.y,`Annotation ${r.number}`);n.addAnnotation(r.number,[{x:x.x,y:x.y}],r.text)}),e.accelerators.forEach(r=>{const x=A(r.x,r.y,`Accelerator "${r.name}"`);n.addAccelerator(r.name,x.x,x.y)}),e.deaccelerators.forEach(r=>{const x=A(r.x,r.y,`Deaccelerator "${r.name}"`);n.addDeaccelerator(r.name,x.x,x.y)})},"populateDb"),Q={parser:{yy:void 0},parse:u(async e=>{const n=await Ft("wardley",e);K.debug(n);const r=Q.parser?.yy;if(!r||typeof r.addNode!="function")throw new Error("parser.parser?.yy was not a WardleyDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");Ot(n,r)},"parse")},Wt=class{constructor(){this.nodes=new Map,this.links=[],this.trends=new Map,this.pipelines=new Map,this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.axes={}}static{u(this,"WardleyBuilder")}addNode(e){const n=this.nodes.get(e.id)??{id:e.id,label:e.label},r={...n,...e,className:e.className??n.className,labelOffsetX:e.labelOffsetX??n.labelOffsetX,labelOffsetY:e.labelOffsetY??n.labelOffsetY};this.nodes.set(e.id,r)}addLink(e){this.links.push(e)}addTrend(e){this.trends.set(e.nodeId,e)}startPipeline(e){this.pipelines.set(e,{nodeId:e,componentIds:[]});const n=this.nodes.get(e);n&&(n.isPipelineParent=!0)}addPipelineComponent(e,n){const r=this.pipelines.get(e);r&&r.componentIds.push(n);const x=this.nodes.get(n);x&&(x.inPipeline=!0)}addAnnotation(e){this.annotations.push(e)}addNote(e){this.notes.push(e)}addAccelerator(e){this.accelerators.push(e)}addDeaccelerator(e){this.deaccelerators.push(e)}setAnnotationsBox(e,n){this.annotationsBox={x:e,y:n}}setAxes(e){this.axes={...this.axes,...e}}setSize(e,n){this.size={width:e,height:n}}getNode(e){return this.nodes.get(e)}resolveNodeId(e){if(this.nodes.has(e))return e;for(const[n,r]of this.nodes)if(r.label===e)return n;return e}build(){const e=[];for(const n of this.nodes.values()){if(typeof n.x!="number"||typeof n.y!="number")throw new Error(`Node "${n.label}" is missing coordinates`);e.push(n)}return{nodes:e,links:[...this.links],trends:[...this.trends.values()],pipelines:[...this.pipelines.values()],annotations:[...this.annotations],notes:[...this.notes],accelerators:[...this.accelerators],deaccelerators:[...this.deaccelerators],annotationsBox:this.annotationsBox,axes:{...this.axes},size:this.size}}clear(){this.nodes.clear(),this.links=[],this.trends.clear(),this.pipelines.clear(),this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.annotationsBox=void 0,this.axes={},this.size=void 0}},k=new Wt;function tt(){return j()["wardley-beta"]}u(tt,"getConfig");function et(e,n,r,x,a,d,w,C,g){k.addNode({id:e,label:n,x:r,y:x,className:a,labelOffsetX:d,labelOffsetY:w,inertia:C,sourceStrategy:g})}u(et,"addNode");function at(e,n,r=!1,x,a){k.addLink({source:e,target:n,dashed:r,label:x,flow:a})}u(at,"addLink");function rt(e,n,r){k.addTrend({nodeId:e,targetX:n,targetY:r})}u(rt,"addTrend");function ot(e,n,r){k.addAnnotation({number:e,coordinates:n,text:r})}u(ot,"addAnnotation");function nt(e,n,r){k.addNote({text:e,x:n,y:r})}u(nt,"addNote");function st(e,n,r){k.addAccelerator({name:e,x:n,y:r})}u(st,"addAccelerator");function it(e,n,r){k.addDeaccelerator({name:e,x:n,y:r})}u(it,"addDeaccelerator");function dt(e,n){k.setAnnotationsBox(e,n)}u(dt,"setAnnotationsBox");function lt(e,n){k.setSize(e,n)}u(lt,"setSize");function ct(e){k.startPipeline(e)}u(ct,"startPipeline");function pt(e,n){k.addPipelineComponent(e,n)}u(pt,"addPipelineComponent");function ft(e){k.setAxes(e)}u(ft,"updateAxes");function ht(e){return k.getNode(e)}u(ht,"getNode");function xt(e){return k.resolveNodeId(e)}u(xt,"resolveNodeId");function gt(){return k.build()}u(gt,"getWardleyData");function yt(){k.clear(),Bt()}u(yt,"clear");var Dt={getConfig:tt,addNode:et,addLink:at,addTrend:rt,addAnnotation:ot,addNote:nt,addAccelerator:st,addDeaccelerator:it,setAnnotationsBox:dt,setSize:lt,startPipeline:ct,addPipelineComponent:pt,updateAxes:ft,getNode:ht,resolveNodeId:xt,getWardleyData:gt,clear:yt,setAccTitle:At,getAccTitle:Tt,setDiagramTitle:Lt,getDiagramTitle:zt,getAccDescription:Nt,setAccDescription:Mt},Gt=["Genesis","Custom Built","Product","Commodity"],qt=u(()=>{const{themeVariables:e}=j();return{backgroundColor:e.wardley?.backgroundColor??e.background??"#fff",axisColor:e.wardley?.axisColor??"#000",axisTextColor:e.wardley?.axisTextColor??e.primaryTextColor??"#222",gridColor:e.wardley?.gridColor??"rgba(100, 100, 100, 0.2)",componentFill:e.wardley?.componentFill??"#fff",componentStroke:e.wardley?.componentStroke??"#000",componentLabelColor:e.wardley?.componentLabelColor??e.primaryTextColor??"#222",linkStroke:e.wardley?.linkStroke??"#000",evolutionStroke:e.wardley?.evolutionStroke??"#dc3545",annotationStroke:e.wardley?.annotationStroke??"#000",annotationTextColor:e.wardley?.annotationTextColor??e.primaryTextColor??"#222",annotationFill:e.wardley?.annotationFill??e.background??"#fff"}},"getTheme"),Ht=u(()=>{const e=j()["wardley-beta"];return{width:e?.width??900,height:e?.height??600,padding:e?.padding??48,nodeRadius:e?.nodeRadius??6,nodeLabelOffset:e?.nodeLabelOffset??8,axisFontSize:e?.axisFontSize??12,labelFontSize:e?.labelFontSize??10,showGrid:e?.showGrid??!1,useMaxWidth:e?.useMaxWidth??!0}},"getConfigValues"),jt=u((e,n,r,x)=>{K.debug(`Rendering Wardley map +import{p as St}from"./chunk-JWPE2WC7-Dsg3gA8l.js";import{s as Mt,g as Nt,p as zt,o as Lt,a as Tt,b as At,_ as u,W as Xt,z as Et,B as U,l as K,F as Yt,e as It,q as Bt,c as j}from"./mermaid.core-CJB1tAev.js";import{p as Ft}from"./cynefin-VYW2F7L2-BIlq342y.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";var D=u((e,n)=>{const r=e<=1?e*100:e;if(r<0||r>100)throw new Error(`${n} must be between 0-1 (decimal) or 0-100 (percentage). Received: ${e}`);return r},"toPercent"),A=u((e,n,r)=>({x:D(n,`${r} evolution`),y:D(e,`${r} visibility`)}),"toCoordinates"),J=u(e=>{if(e){if(e==="+<>")return"bidirectional";if(e==="+<")return"backward";if(e==="+>")return"forward"}},"getFlowFromPort"),Rt=u(e=>{if(!e?.startsWith("+"))return{};const r=/^\+'([^']*)'/.exec(e)?.[1];return e.includes("<>")?{flow:"bidirectional",label:r}:e.includes("<")?{flow:"backward",label:r}:e.includes(">")?{flow:"forward",label:r}:{label:r}},"extractFlowFromArrow"),Ot=u((e,n)=>{if(St(e,n),e.size&&n.setSize(e.size.width,e.size.height),e.evolution){const r=e.evolution.stages.map(a=>a.secondName?`${a.name.trim()} / ${a.secondName.trim()}`:a.name.trim()),x=e.evolution.stages.filter(a=>a.boundary!==void 0).map(a=>a.boundary);n.updateAxes({stages:r,stageBoundaries:x})}if(e.anchors.forEach(r=>{const x=A(r.visibility,r.evolution,`Anchor "${r.name}"`);n.addNode(r.name,r.name,x.x,x.y,"anchor")}),e.components.forEach(r=>{const x=A(r.visibility,r.evolution,`Component "${r.name}"`),a=r.label?(r.label.negX?-1:1)*r.label.offsetX:void 0,d=r.label?(r.label.negY?-1:1)*r.label.offsetY:void 0,w=r.decorator?.strategy;n.addNode(r.name,r.name,x.x,x.y,"component",a,d,r.inertia,w)}),e.notes.forEach(r=>{const x=A(r.visibility,r.evolution,`Note "${r.text}"`);n.addNote(r.text,x.x,x.y)}),e.pipelines.forEach(r=>{const x=n.getNode(r.parent);if(!x||typeof x.y!="number")throw new Error(`Pipeline "${r.parent}" must reference an existing component with coordinates.`);const a=x.y;n.startPipeline(r.parent),r.components.forEach(d=>{const w=`${r.parent}_${d.name}`,C=d.label?(d.label.negX?-1:1)*d.label.offsetX:void 0,g=d.label?(d.label.negY?-1:1)*d.label.offsetY:void 0,F=D(d.evolution,`Pipeline component "${d.name}" evolution`);n.addNode(w,d.name,F,a,"pipeline-component",C,g),n.addPipelineComponent(r.parent,w)})}),e.links.forEach(r=>{const x=!!r.arrow&&(r.arrow.includes("-.->")||r.arrow.includes(".-."));let a=J(r.fromPort)??J(r.toPort);const{flow:d,label:w}=Rt(r.arrow);!a&&d&&(a=d);const C=r.linkLabel,g=w??C;n.addLink(n.resolveNodeId(r.from),n.resolveNodeId(r.to),x,g,a)}),e.evolves.forEach(r=>{const x=n.getNode(r.component);if(x?.y!==void 0){const a=D(r.target,`Evolve target for "${r.component}"`);n.addTrend(r.component,a,x.y)}}),e.annotations.length>0){const r=e.annotations[0],x=A(r.x,r.y,"Annotations box");n.setAnnotationsBox(x.x,x.y)}e.annotation.forEach(r=>{const x=A(r.x,r.y,`Annotation ${r.number}`);n.addAnnotation(r.number,[{x:x.x,y:x.y}],r.text)}),e.accelerators.forEach(r=>{const x=A(r.x,r.y,`Accelerator "${r.name}"`);n.addAccelerator(r.name,x.x,x.y)}),e.deaccelerators.forEach(r=>{const x=A(r.x,r.y,`Deaccelerator "${r.name}"`);n.addDeaccelerator(r.name,x.x,x.y)})},"populateDb"),Q={parser:{yy:void 0},parse:u(async e=>{const n=await Ft("wardley",e);K.debug(n);const r=Q.parser?.yy;if(!r||typeof r.addNode!="function")throw new Error("parser.parser?.yy was not a WardleyDB. This is due to a bug within Mermaid, please report this issue at https://github.com/mermaid-js/mermaid/issues.");Ot(n,r)},"parse")},Wt=class{constructor(){this.nodes=new Map,this.links=[],this.trends=new Map,this.pipelines=new Map,this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.axes={}}static{u(this,"WardleyBuilder")}addNode(e){const n=this.nodes.get(e.id)??{id:e.id,label:e.label},r={...n,...e,className:e.className??n.className,labelOffsetX:e.labelOffsetX??n.labelOffsetX,labelOffsetY:e.labelOffsetY??n.labelOffsetY};this.nodes.set(e.id,r)}addLink(e){this.links.push(e)}addTrend(e){this.trends.set(e.nodeId,e)}startPipeline(e){this.pipelines.set(e,{nodeId:e,componentIds:[]});const n=this.nodes.get(e);n&&(n.isPipelineParent=!0)}addPipelineComponent(e,n){const r=this.pipelines.get(e);r&&r.componentIds.push(n);const x=this.nodes.get(n);x&&(x.inPipeline=!0)}addAnnotation(e){this.annotations.push(e)}addNote(e){this.notes.push(e)}addAccelerator(e){this.accelerators.push(e)}addDeaccelerator(e){this.deaccelerators.push(e)}setAnnotationsBox(e,n){this.annotationsBox={x:e,y:n}}setAxes(e){this.axes={...this.axes,...e}}setSize(e,n){this.size={width:e,height:n}}getNode(e){return this.nodes.get(e)}resolveNodeId(e){if(this.nodes.has(e))return e;for(const[n,r]of this.nodes)if(r.label===e)return n;return e}build(){const e=[];for(const n of this.nodes.values()){if(typeof n.x!="number"||typeof n.y!="number")throw new Error(`Node "${n.label}" is missing coordinates`);e.push(n)}return{nodes:e,links:[...this.links],trends:[...this.trends.values()],pipelines:[...this.pipelines.values()],annotations:[...this.annotations],notes:[...this.notes],accelerators:[...this.accelerators],deaccelerators:[...this.deaccelerators],annotationsBox:this.annotationsBox,axes:{...this.axes},size:this.size}}clear(){this.nodes.clear(),this.links=[],this.trends.clear(),this.pipelines.clear(),this.annotations=[],this.notes=[],this.accelerators=[],this.deaccelerators=[],this.annotationsBox=void 0,this.axes={},this.size=void 0}},k=new Wt;function tt(){return j()["wardley-beta"]}u(tt,"getConfig");function et(e,n,r,x,a,d,w,C,g){k.addNode({id:e,label:n,x:r,y:x,className:a,labelOffsetX:d,labelOffsetY:w,inertia:C,sourceStrategy:g})}u(et,"addNode");function at(e,n,r=!1,x,a){k.addLink({source:e,target:n,dashed:r,label:x,flow:a})}u(at,"addLink");function rt(e,n,r){k.addTrend({nodeId:e,targetX:n,targetY:r})}u(rt,"addTrend");function ot(e,n,r){k.addAnnotation({number:e,coordinates:n,text:r})}u(ot,"addAnnotation");function nt(e,n,r){k.addNote({text:e,x:n,y:r})}u(nt,"addNote");function st(e,n,r){k.addAccelerator({name:e,x:n,y:r})}u(st,"addAccelerator");function it(e,n,r){k.addDeaccelerator({name:e,x:n,y:r})}u(it,"addDeaccelerator");function dt(e,n){k.setAnnotationsBox(e,n)}u(dt,"setAnnotationsBox");function lt(e,n){k.setSize(e,n)}u(lt,"setSize");function ct(e){k.startPipeline(e)}u(ct,"startPipeline");function pt(e,n){k.addPipelineComponent(e,n)}u(pt,"addPipelineComponent");function ft(e){k.setAxes(e)}u(ft,"updateAxes");function ht(e){return k.getNode(e)}u(ht,"getNode");function xt(e){return k.resolveNodeId(e)}u(xt,"resolveNodeId");function gt(){return k.build()}u(gt,"getWardleyData");function yt(){k.clear(),Bt()}u(yt,"clear");var Dt={getConfig:tt,addNode:et,addLink:at,addTrend:rt,addAnnotation:ot,addNote:nt,addAccelerator:st,addDeaccelerator:it,setAnnotationsBox:dt,setSize:lt,startPipeline:ct,addPipelineComponent:pt,updateAxes:ft,getNode:ht,resolveNodeId:xt,getWardleyData:gt,clear:yt,setAccTitle:At,getAccTitle:Tt,setDiagramTitle:Lt,getDiagramTitle:zt,getAccDescription:Nt,setAccDescription:Mt},Gt=["Genesis","Custom Built","Product","Commodity"],qt=u(()=>{const{themeVariables:e}=j();return{backgroundColor:e.wardley?.backgroundColor??e.background??"#fff",axisColor:e.wardley?.axisColor??"#000",axisTextColor:e.wardley?.axisTextColor??e.primaryTextColor??"#222",gridColor:e.wardley?.gridColor??"rgba(100, 100, 100, 0.2)",componentFill:e.wardley?.componentFill??"#fff",componentStroke:e.wardley?.componentStroke??"#000",componentLabelColor:e.wardley?.componentLabelColor??e.primaryTextColor??"#222",linkStroke:e.wardley?.linkStroke??"#000",evolutionStroke:e.wardley?.evolutionStroke??"#dc3545",annotationStroke:e.wardley?.annotationStroke??"#000",annotationTextColor:e.wardley?.annotationTextColor??e.primaryTextColor??"#222",annotationFill:e.wardley?.annotationFill??e.background??"#fff"}},"getTheme"),Ht=u(()=>{const e=j()["wardley-beta"];return{width:e?.width??900,height:e?.height??600,padding:e?.padding??48,nodeRadius:e?.nodeRadius??6,nodeLabelOffset:e?.nodeLabelOffset??8,axisFontSize:e?.axisFontSize??12,labelFontSize:e?.labelFontSize??10,showGrid:e?.showGrid??!1,useMaxWidth:e?.useMaxWidth??!0}},"getConfigValues"),jt=u((e,n,r,x)=>{K.debug(`Rendering Wardley map `+e);const a=Ht(),d=qt(),w=a.nodeRadius*1.6,C=x.db,g=C.getWardleyData(),F=C.getDiagramTitle(),S=g.size?.width??a.width,b=g.size?.height??a.height,E=Yt(n);E.selectAll("*").remove(),It(E,b,S,a.useMaxWidth),E.attr("viewBox",`0 0 ${S} ${b}`);const v=E.append("g").attr("class","wardley-map"),G=E.append("defs");G.append("marker").attr("id",`arrow-${n}`).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",6).attr("markerHeight",6).attr("orient","auto-start-reverse").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("fill",d.evolutionStroke).attr("stroke","none"),G.append("marker").attr("id",`link-arrow-end-${n}`).attr("viewBox","0 0 10 10").attr("refX",9).attr("refY",5).attr("markerWidth",5).attr("markerHeight",5).attr("orient","auto").append("path").attr("d","M 0 0 L 10 5 L 0 10 z").attr("fill",d.linkStroke).attr("stroke","none"),G.append("marker").attr("id",`link-arrow-start-${n}`).attr("viewBox","0 0 10 10").attr("refX",1).attr("refY",5).attr("markerWidth",5).attr("markerHeight",5).attr("orient","auto").append("path").attr("d","M 10 0 L 0 5 L 10 10 z").attr("fill",d.linkStroke).attr("stroke","none"),v.append("rect").attr("class","wardley-background").attr("width",S).attr("height",b).attr("fill",d.backgroundColor);const Y=S-a.padding*2,I=b-a.padding*2;F&&v.append("text").attr("class","wardley-title").attr("x",S/2).attr("y",a.padding/2).attr("fill",d.axisTextColor).attr("font-size",a.axisFontSize*1.05).attr("font-weight","bold").attr("text-anchor","middle").attr("dominant-baseline","middle").text(F);const z=u(t=>a.padding+t/100*Y,"projectX"),L=u(t=>b-a.padding-t/100*I,"projectY"),R=v.append("g").attr("class","wardley-axes");R.append("line").attr("x1",a.padding).attr("x2",S-a.padding).attr("y1",b-a.padding).attr("y2",b-a.padding).attr("stroke",d.axisColor).attr("stroke-width",1),R.append("line").attr("x1",a.padding).attr("x2",a.padding).attr("y1",a.padding).attr("y2",b-a.padding).attr("stroke",d.axisColor).attr("stroke-width",1);const ut=g.axes.xLabel??"Evolution",wt=g.axes.yLabel??"Visibility";R.append("text").attr("class","wardley-axis-label wardley-axis-label-x").attr("x",a.padding+Y/2).attr("y",b-a.padding/4).attr("fill",d.axisTextColor).attr("font-size",a.axisFontSize).attr("font-weight","bold").attr("text-anchor","middle").text(ut),R.append("text").attr("class","wardley-axis-label wardley-axis-label-y").attr("x",a.padding/3).attr("y",a.padding+I/2).attr("fill",d.axisTextColor).attr("font-size",a.axisFontSize).attr("font-weight","bold").attr("text-anchor","middle").attr("transform",`rotate(-90 ${a.padding/3} ${a.padding+I/2})`).text(wt);const B=g.axes.stages&&g.axes.stages.length>0?g.axes.stages:Gt;if(B.length>0){const t=v.append("g").attr("class","wardley-stages"),s=g.axes.stageBoundaries,o=[];if(s&&s.length===B.length){let i=0;s.forEach(p=>{o.push({start:i,end:p}),i=p})}else{const i=1/B.length;B.forEach((p,l)=>{o.push({start:l*i,end:(l+1)*i})})}B.forEach((i,p)=>{const l=o[p],f=a.padding+l.start*Y,h=a.padding+l.end*Y,y=(f+h)/2;p>0&&t.append("line").attr("x1",f).attr("x2",f).attr("y1",a.padding).attr("y2",b-a.padding).attr("stroke","#000").attr("stroke-width",1).attr("stroke-dasharray","5 5").attr("opacity",.8),t.append("text").attr("class","wardley-stage-label").attr("x",y).attr("y",b-a.padding/1.5).attr("fill",d.axisTextColor).attr("font-size",a.axisFontSize-2).attr("text-anchor","middle").text(i)})}if(a.showGrid){const t=v.append("g").attr("class","wardley-grid");for(let s=1;s<4;s++){const o=s/4,i=a.padding+Y*o;t.append("line").attr("x1",i).attr("x2",i).attr("y1",a.padding).attr("y2",b-a.padding).attr("stroke",d.gridColor).attr("stroke-dasharray","2 6"),t.append("line").attr("x1",a.padding).attr("x2",S-a.padding).attr("y1",b-a.padding-I*o).attr("y2",b-a.padding-I*o).attr("stroke",d.gridColor).attr("stroke-dasharray","2 6")}}const c=new Map;if(g.nodes.forEach(t=>{c.set(t.id,{x:z(t.x),y:L(t.y),node:t})}),g.pipelines.length>0){const t=v.append("g").attr("class","wardley-pipelines"),s=v.append("g").attr("class","wardley-pipeline-links");g.pipelines.forEach(o=>{if(o.componentIds.length===0)return;const i=o.componentIds.map(h=>({id:h,pos:c.get(h),node:g.nodes.find(y=>y.id===h)})).filter(h=>h.pos&&h.node).sort((h,y)=>h.node.x-y.node.x);for(let h=0;h<i.length-1;h++){const y=i[h],m=i[h+1];s.append("line").attr("class","wardley-pipeline-evolution-link").attr("x1",y.pos.x).attr("y1",y.pos.y).attr("x2",m.pos.x).attr("y2",m.pos.y).attr("stroke",d.linkStroke).attr("stroke-width",1).attr("stroke-dasharray","4 4")}let p=1/0,l=-1/0,f=0;if(o.componentIds.forEach(h=>{const y=c.get(h);y&&(p=Math.min(p,y.x),l=Math.max(l,y.x),f=y.y)}),p!==1/0&&l!==-1/0){const y=a.nodeRadius*4,m=f-y/2,P=c.get(o.nodeId);if(P){const N=(p+l)/2;P.x=N,P.y=m-w/6}t.append("rect").attr("class","wardley-pipeline-box").attr("x",p-15).attr("y",m).attr("width",l-p+30).attr("height",y).attr("fill","none").attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("rx",4).attr("ry",4)}})}const V=v.append("g").attr("class","wardley-links"),_=new Map;g.pipelines.forEach(t=>{_.set(t.nodeId,new Set(t.componentIds))});const Z=g.links.filter(t=>!(!c.has(t.source)||!c.has(t.target)||_.get(t.target)?.has(t.source)));V.selectAll("line").data(Z).enter().append("line").attr("class",t=>`wardley-link${t.dashed?" wardley-link--dashed":""}`).attr("x1",t=>{const s=c.get(t.source),o=c.get(t.target),p=g.nodes.find(y=>y.id===t.source).isPipelineParent?w/Math.sqrt(2):a.nodeRadius,l=o.x-s.x,f=o.y-s.y,h=Math.sqrt(l*l+f*f);return s.x+l/h*p}).attr("y1",t=>{const s=c.get(t.source),o=c.get(t.target),p=g.nodes.find(y=>y.id===t.source).isPipelineParent?w/Math.sqrt(2):a.nodeRadius,l=o.x-s.x,f=o.y-s.y,h=Math.sqrt(l*l+f*f);return s.y+f/h*p}).attr("x2",t=>{const s=c.get(t.source),o=c.get(t.target),p=g.nodes.find(y=>y.id===t.target).isPipelineParent?w/Math.sqrt(2):a.nodeRadius,l=s.x-o.x,f=s.y-o.y,h=Math.sqrt(l*l+f*f);return o.x+l/h*p}).attr("y2",t=>{const s=c.get(t.source),o=c.get(t.target),p=g.nodes.find(y=>y.id===t.target).isPipelineParent?w/Math.sqrt(2):a.nodeRadius,l=s.x-o.x,f=s.y-o.y,h=Math.sqrt(l*l+f*f);return o.y+f/h*p}).attr("stroke",d.linkStroke).attr("stroke-width",1).attr("stroke-dasharray",t=>t.dashed?"6 6":null).attr("marker-end",t=>t.flow==="forward"||t.flow==="bidirectional"?`url(#link-arrow-end-${n})`:null).attr("marker-start",t=>t.flow==="backward"||t.flow==="bidirectional"?`url(#link-arrow-start-${n})`:null),V.selectAll("text").data(Z.filter(t=>t.label)).enter().append("text").attr("class","wardley-link-label").attr("x",t=>{const s=c.get(t.source),o=c.get(t.target),i=(s.x+o.x)/2,p=o.y-s.y,l=o.x-s.x,f=Math.sqrt(l*l+p*p),h=8,y=p/f;return i+y*h}).attr("y",t=>{const s=c.get(t.source),o=c.get(t.target),i=(s.y+o.y)/2,p=o.x-s.x,l=o.y-s.y,f=Math.sqrt(p*p+l*l),h=8,y=-p/f;return i+y*h}).attr("fill",d.axisTextColor).attr("font-size",a.labelFontSize).attr("text-anchor","middle").attr("dominant-baseline","middle").attr("transform",t=>{const s=c.get(t.source),o=c.get(t.target),i=(s.x+o.x)/2,p=(s.y+o.y)/2,l=o.x-s.x,f=o.y-s.y,h=Math.sqrt(l*l+f*f),y=8,m=f/h,P=-l/h,N=i+m*y,O=p+P*y;let X=Math.atan2(f,l)*180/Math.PI;return(X>90||X<-90)&&(X+=180),`rotate(${X} ${N} ${O})`}).text(t=>t.label);const mt=v.append("g").attr("class","wardley-trends"),kt=g.trends.map(t=>{const s=c.get(t.nodeId);if(!s)return null;const o=z(t.targetX),i=L(t.targetY),p=o-s.x,l=i-s.y,f=Math.sqrt(p*p+l*l),h=a.nodeRadius+2,y=f>h?o-p/f*h:o,m=f>h?i-l/f*h:i;return{origin:s,targetX:o,targetY:i,adjustedX2:y,adjustedY2:m}}).filter(t=>t!==null);mt.selectAll("line").data(kt).enter().append("line").attr("class","wardley-trend").attr("x1",t=>t.origin.x).attr("y1",t=>t.origin.y).attr("x2",t=>t.adjustedX2).attr("y2",t=>t.adjustedY2).attr("stroke",d.evolutionStroke).attr("stroke-width",1).attr("stroke-dasharray","4 4").attr("marker-end",`url(#arrow-${n})`);const M=v.append("g").attr("class","wardley-nodes").selectAll("g").data(g.nodes).enter().append("g").attr("class",t=>["wardley-node",t.className?`wardley-node--${t.className}`:""].filter(Boolean).join(" "));M.filter(t=>t.sourceStrategy==="outsource").append("circle").attr("class","wardley-outsource-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",a.nodeRadius*2).attr("fill","#666").attr("stroke",d.componentStroke).attr("stroke-width",1),M.filter(t=>t.sourceStrategy==="buy").append("circle").attr("class","wardley-buy-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",a.nodeRadius*2).attr("fill","#ccc").attr("stroke",d.componentStroke).attr("stroke-width",1),M.filter(t=>t.sourceStrategy==="build").append("circle").attr("class","wardley-build-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",a.nodeRadius*2).attr("fill","#eee").attr("stroke","#000").attr("stroke-width",1);const T=M.filter(t=>t.sourceStrategy==="market");T.append("circle").attr("class","wardley-market-overlay").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",a.nodeRadius*2).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",1),M.filter(t=>!t.isPipelineParent&&t.sourceStrategy!=="market"&&t.className!=="anchor").append("circle").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y).attr("r",a.nodeRadius).attr("fill",d.componentFill).attr("stroke",d.componentStroke).attr("stroke-width",1);const q=a.nodeRadius*.7,$=a.nodeRadius*1.2;if(T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x).attr("y1",t=>c.get(t.id).y-$).attr("x2",t=>c.get(t.id).x-$*Math.cos(Math.PI/6)).attr("y2",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x-$*Math.cos(Math.PI/6)).attr("y1",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("x2",t=>c.get(t.id).x+$*Math.cos(Math.PI/6)).attr("y2",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("line").attr("class","wardley-market-line").attr("x1",t=>c.get(t.id).x+$*Math.cos(Math.PI/6)).attr("y1",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("x2",t=>c.get(t.id).x).attr("y2",t=>c.get(t.id).y-$).attr("stroke",d.componentStroke).attr("stroke-width",1),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x).attr("cy",t=>c.get(t.id).y-$).attr("r",q).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x-$*Math.cos(Math.PI/6)).attr("cy",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("r",q).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),T.append("circle").attr("class","wardley-market-dot").attr("cx",t=>c.get(t.id).x+$*Math.cos(Math.PI/6)).attr("cy",t=>c.get(t.id).y+$*Math.sin(Math.PI/6)).attr("r",q).attr("fill","white").attr("stroke",d.componentStroke).attr("stroke-width",2),M.filter(t=>t.isPipelineParent===!0).append("rect").attr("x",t=>c.get(t.id).x-w/2).attr("y",t=>c.get(t.id).y-w/2).attr("width",w).attr("height",w).attr("fill",d.componentFill).attr("stroke",d.componentStroke).attr("stroke-width",1),M.filter(t=>t.inertia===!0).append("line").attr("class","wardley-inertia").attr("x1",t=>{const s=c.get(t.id);let o=t.isPipelineParent?w/2+15:a.nodeRadius+15;return t.sourceStrategy&&(o+=a.nodeRadius+10),s.x+o}).attr("y1",t=>{const s=c.get(t.id),o=t.isPipelineParent?w:a.nodeRadius*2;return s.y-o/2}).attr("x2",t=>{const s=c.get(t.id);let o=t.isPipelineParent?w/2+15:a.nodeRadius+15;return t.sourceStrategy&&(o+=a.nodeRadius+10),s.x+o}).attr("y2",t=>{const s=c.get(t.id),o=t.isPipelineParent?w:a.nodeRadius*2;return s.y+o/2}).attr("stroke",d.componentStroke).attr("stroke-width",6),M.append("text").attr("x",t=>{const s=c.get(t.id);if(t.className==="anchor")return t.labelOffsetX!==void 0?s.x+t.labelOffsetX:s.x;let o=a.nodeLabelOffset;t.sourceStrategy&&t.labelOffsetX===void 0&&(o+=10);const i=t.labelOffsetX??o;return s.x+i}).attr("y",t=>{const s=c.get(t.id);if(t.className==="anchor")return t.labelOffsetY!==void 0?s.y+t.labelOffsetY:s.y-3;let o=-a.nodeLabelOffset;t.sourceStrategy&&t.labelOffsetY===void 0&&(o-=10);const i=t.labelOffsetY??o;return s.y+i}).attr("class","wardley-node-label").attr("fill",t=>t.className==="evolved"?d.evolutionStroke:t.className==="anchor"?"#000":d.componentLabelColor).attr("font-size",a.labelFontSize).attr("font-weight",t=>t.className==="anchor"?"bold":"normal").attr("text-anchor",t=>t.className==="anchor"?"middle":"start").attr("dominant-baseline",t=>t.className==="anchor"?"middle":"auto").text(t=>t.label),g.annotations.length>0){const t=v.append("g").attr("class","wardley-annotations");if(g.annotations.forEach(s=>{const o=s.coordinates.map(i=>({x:z(i.x),y:L(i.y)}));if(o.length>1)for(let i=0;i<o.length-1;i++)t.append("line").attr("class","wardley-annotation-line").attr("x1",o[i].x).attr("y1",o[i].y).attr("x2",o[i+1].x).attr("y2",o[i+1].y).attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("stroke-dasharray","4 4");o.forEach(i=>{const p=t.append("g").attr("class","wardley-annotation");p.append("circle").attr("cx",i.x).attr("cy",i.y).attr("r",10).attr("fill","white").attr("stroke",d.axisColor).attr("stroke-width",1.5),p.append("text").attr("x",i.x).attr("y",i.y).attr("text-anchor","middle").attr("dominant-baseline","central").attr("font-size",10).attr("fill",d.axisTextColor).attr("font-weight","bold").text(s.number)})}),g.annotationsBox){let s=z(g.annotationsBox.x),o=L(g.annotationsBox.y);const i=10,p=16,l=11,f=t.append("g").attr("class","wardley-annotations-box"),h=[...g.annotations].filter(m=>m.text).sort((m,P)=>m.number-P.number),y=[];if(h.forEach((m,P)=>{const N=f.append("text").attr("x",s+i).attr("y",o+i+(P+1)*p).attr("font-size",l).attr("fill",d.axisTextColor).attr("text-anchor","start").attr("dominant-baseline","middle").text(`${m.number}. ${m.text}`);y.push(N)}),y.length>0){let m=0,P=0;y.forEach(H=>{const W=H.node(),Pt=W.getComputedTextLength();m=Math.max(m,Pt);const Ct=W.getBBox();P=Math.max(P,Ct.height)});const N=m+i*2+105,O=h.length*p+i*2+P/2,X=a.padding,bt=S-a.padding-N,$t=a.padding,vt=b-a.padding-O;s=Math.max(X,Math.min(s,bt)),o=Math.max($t,Math.min(o,vt)),y.forEach((H,W)=>{H.attr("x",s+i).attr("y",o+i+(W+1)*p)}),f.insert("rect","text").attr("x",s).attr("y",o).attr("width",N).attr("height",O).attr("fill","white").attr("stroke",d.axisColor).attr("stroke-width",1.5).attr("rx",4).attr("ry",4)}}}if(g.notes.length>0){const t=v.append("g").attr("class","wardley-notes");g.notes.forEach(s=>{const o=z(s.x),i=L(s.y);t.append("text").attr("x",o).attr("y",i).attr("text-anchor","start").attr("font-size",11).attr("fill",d.axisTextColor).attr("font-weight","bold").text(s.text)})}if(g.accelerators.length>0){const t=v.append("g").attr("class","wardley-accelerators");g.accelerators.forEach(s=>{const o=z(s.x),i=L(s.y),p=60,l=30,f=20,h=` M ${o} ${i-l/2} L ${o+p-f} ${i-l/2} diff --git a/apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-Bg0qevEv.js b/apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-yQImOWPy.js similarity index 99% rename from apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-Bg0qevEv.js rename to apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-yQImOWPy.js index 8038b697c..71acb3f13 100644 --- a/apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-Bg0qevEv.js +++ b/apps/kimi-code/dist-web/assets/xychartDiagram-FW5EYKEG-yQImOWPy.js @@ -1,4 +1,4 @@ -import{s as si,g as ai,p as Et,o as ni,a as oi,b as ri,_ as n,l as It,F as hi,e as li,q as ci,z as pt,i as ui,B as Mt,D as gi,W as xi,az as di,a7 as Dt}from"./mermaid.core-DaDTfY6S.js";import{i as fi}from"./init-Gi6I4Gst.js";import{o as pi}from"./ordinal-Cboi1Yqb.js";import{l as vt}from"./linear-BmFm-Eu7.js";import"./index-D1h84VfZ.js";import"./_commonjsHelpers-CqkleIqs.js";import"./defaultLocale-DX6XiGOO.js";function mi(t,i,e){t=+t,i=+i,e=(a=arguments.length)<2?(i=t,t=0,1):a<3?1:+e;for(var s=-1,a=Math.max(0,Math.ceil((i-t)/e))|0,c=new Array(a);++s<a;)c[s]=t+s*e;return c}function ut(){var t=pi().unknown(void 0),i=t.domain,e=t.range,s=0,a=1,c,l,f=!1,S=0,k=0,L=.5;delete t.unknown;function _(){var y=i().length,E=a<s,v=E?a:s,P=E?s:a;c=(P-v)/Math.max(1,y-S+k*2),f&&(c=Math.floor(c)),v+=(P-v-c*(y-S))*L,l=c*(1-S),f&&(v=Math.round(v),l=Math.round(l));var I=mi(y).map(function(p){return v+c*p});return e(E?I.reverse():I)}return t.domain=function(y){return arguments.length?(i(y),_()):i()},t.range=function(y){return arguments.length?([s,a]=y,s=+s,a=+a,_()):[s,a]},t.rangeRound=function(y){return[s,a]=y,s=+s,a=+a,f=!0,_()},t.bandwidth=function(){return l},t.step=function(){return c},t.round=function(y){return arguments.length?(f=!!y,_()):f},t.padding=function(y){return arguments.length?(S=Math.min(1,k=+y),_()):S},t.paddingInner=function(y){return arguments.length?(S=Math.min(1,y),_()):S},t.paddingOuter=function(y){return arguments.length?(k=+y,_()):k},t.align=function(y){return arguments.length?(L=Math.max(0,Math.min(1,y)),_()):L},t.copy=function(){return ut(i(),[s,a]).round(f).paddingInner(S).paddingOuter(k).align(L)},fi.apply(_(),arguments)}var gt=(function(){var t=n(function(F,r,u,g){for(u=u||{},g=F.length;g--;u[F[g]]=r);return u},"o"),i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],a=[1,5],c=[1,6],l=[1,7],f=[1,5,10,12,14,16,18,19,21,23,36,37,38],S=[1,25],k=[1,26],L=[1,28],_=[1,29],y=[1,30],E=[1,31],v=[1,32],P=[1,33],I=[1,34],p=[1,35],T=[1,36],h=[1,37],B=[1,43],W=[1,42],X=[1,47],Y=[1,50],C=[1,10,12,14,16,18,19,21,23,36,37,38],H=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38],b=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38,42,43,44,45,46,47,48,49,50,51],A=[1,65],V=[26,28],R={trace:n(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,dataPoints:25,SQUARE_BRACES_END:26,dataPoint:27,COMMA:28,NUMBER_WITH_DECIMAL:29,STR:30,xAxisData:31,bandData:32,ARROW_DELIMITER:33,commaSeparatedTexts:34,yAxisData:35,NEWLINE:36,SEMI:37,EOF:38,alphaNum:39,MD_STR:40,alphaNumToken:41,AMP:42,NUM:43,ALPHA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,MINUS:50,UNDERSCORE:51,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",28:"COMMA",29:"NUMBER_WITH_DECIMAL",30:"STR",33:"ARROW_DELIMITER",36:"NEWLINE",37:"SEMI",38:"EOF",40:"MD_STR",42:"AMP",43:"NUM",44:"ALPHA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"MINUS",51:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[27,2],[27,1],[13,1],[13,2],[13,1],[31,1],[31,3],[32,3],[34,3],[34,1],[15,1],[15,2],[15,1],[35,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[39,1],[39,2],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1]],performAction:n(function(r,u,g,x,w,o,K){var d=o.length-1;switch(w){case 5:x.setOrientation(o[d]);break;case 9:x.setDiagramTitle(o[d].text.trim());break;case 12:x.setLineData({text:"",type:"text"},o[d]);break;case 13:x.setLineData(o[d-1],o[d]);break;case 14:x.setBarData({text:"",type:"text"},o[d]);break;case 15:x.setBarData(o[d-1],o[d]);break;case 16:this.$=o[d].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=o[d].trim(),x.setAccDescription(this.$);break;case 19:this.$=o[d-1];break;case 20:case 30:this.$=[o[d-2],...o[d]];break;case 21:case 31:this.$=[o[d]];break;case 22:this.$={value:Number(o[d-1]),label:o[d]};break;case 23:this.$={value:Number(o[d]),label:""};break;case 24:x.setXAxisTitle(o[d]);break;case 25:x.setXAxisTitle(o[d-1]);break;case 26:x.setXAxisTitle({type:"text",text:""});break;case 27:x.setXAxisBand(o[d]);break;case 28:x.setXAxisRangeData(Number(o[d-2]),Number(o[d]));break;case 29:this.$=o[d-1];break;case 32:x.setYAxisTitle(o[d]);break;case 33:x.setYAxisTitle(o[d-1]);break;case 34:x.setYAxisTitle({type:"text",text:""});break;case 35:x.setYAxisRangeData(Number(o[d-2]),Number(o[d]));break;case 39:this.$={text:o[d],type:"text"};break;case 40:this.$={text:o[d],type:"text"};break;case 41:this.$={text:o[d],type:"markdown"};break;case 42:this.$=o[d];break;case 43:this.$=o[d-1]+""+o[d];break}},"anonymous"),table:[t(i,e,{3:1,4:2,7:4,5:s,36:a,37:c,38:l}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,36:a,37:c,38:l}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],36:a,37:c,38:l}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,36:a,37:c,38:l}),{1:[2,3]},t(f,[2,5]),t(i,[2,7],{4:22,36:a,37:c,38:l}),{11:23,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:39,13:38,24:B,29:W,30:S,31:40,32:41,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:45,15:44,29:X,30:S,35:46,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:49,17:48,24:Y,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:52,17:51,24:Y,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{20:[1,53]},{22:[1,54]},t(C,[2,18]),{1:[2,2]},t(C,[2,8]),t(C,[2,9]),t(H,[2,39],{41:55,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h}),t(H,[2,40]),t(H,[2,41]),t(b,[2,42]),t(b,[2,44]),t(b,[2,45]),t(b,[2,46]),t(b,[2,47]),t(b,[2,48]),t(b,[2,49]),t(b,[2,50]),t(b,[2,51]),t(b,[2,52]),t(b,[2,53]),t(C,[2,10]),t(C,[2,24],{32:41,31:56,24:B,29:W}),t(C,[2,26]),t(C,[2,27]),{33:[1,57]},{11:59,30:S,34:58,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},t(C,[2,11]),t(C,[2,32],{35:60,29:X}),t(C,[2,34]),{33:[1,61]},t(C,[2,12]),{17:62,24:Y},{25:63,27:64,29:A},t(C,[2,14]),{17:66,24:Y},t(C,[2,16]),t(C,[2,17]),t(b,[2,43]),t(C,[2,25]),{29:[1,67]},{26:[1,68]},{26:[2,31],28:[1,69]},t(C,[2,33]),{29:[1,70]},t(C,[2,13]),{26:[1,71]},{26:[2,21],28:[1,72]},t(V,[2,23],{30:[1,73]}),t(C,[2,15]),t(C,[2,28]),t(C,[2,29]),{11:59,30:S,34:74,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},t(C,[2,35]),t(C,[2,19]),{25:75,27:64,29:A},t(V,[2,22]),{26:[2,30]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],74:[2,30],75:[2,20]},parseError:n(function(r,u){if(u.recoverable)this.trace(r);else{var g=new Error(r);throw g.hash=u,g}},"parseError"),parse:n(function(r){var u=this,g=[0],x=[],w=[null],o=[],K=this.table,d="",et=0,Rt=0,Jt=2,_t=1,ti=o.slice.call(arguments,1),D=Object.create(this.lexer),U={yy:{}};for(var rt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,rt)&&(U.yy[rt]=this.yy[rt]);D.setInput(r,U.yy),U.yy.lexer=D,U.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var ht=D.yylloc;o.push(ht);var ii=D.options&&D.options.ranges;typeof U.yy.parseError=="function"?this.parseError=U.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ei(z){g.length=g.length-2*z,w.length=w.length-z,o.length=o.length-z}n(ei,"popStack");function kt(){var z;return z=x.pop()||D.lex()||_t,typeof z!="number"&&(z instanceof Array&&(x=z,z=x.pop()),z=u.symbols_[z]||z),z}n(kt,"lex");for(var M,$,O,lt,G={},st,N,Tt,at;;){if($=g[g.length-1],this.defaultActions[$]?O=this.defaultActions[$]:((M===null||typeof M>"u")&&(M=kt()),O=K[$]&&K[$][M]),typeof O>"u"||!O.length||!O[0]){var ct="";at=[];for(st in K[$])this.terminals_[st]&&st>Jt&&at.push("'"+this.terminals_[st]+"'");D.showPosition?ct="Parse error on line "+(et+1)+`: +import{s as si,g as ai,p as Et,o as ni,a as oi,b as ri,_ as n,l as It,F as hi,e as li,q as ci,z as pt,i as ui,B as Mt,D as gi,W as xi,az as di,a7 as Dt}from"./mermaid.core-CJB1tAev.js";import{i as fi}from"./init-Gi6I4Gst.js";import{o as pi}from"./ordinal-Cboi1Yqb.js";import{l as vt}from"./linear-DH49UJnN.js";import"./index-D-7nOosq.js";import"./_commonjsHelpers-CqkleIqs.js";import"./defaultLocale-DX6XiGOO.js";function mi(t,i,e){t=+t,i=+i,e=(a=arguments.length)<2?(i=t,t=0,1):a<3?1:+e;for(var s=-1,a=Math.max(0,Math.ceil((i-t)/e))|0,c=new Array(a);++s<a;)c[s]=t+s*e;return c}function ut(){var t=pi().unknown(void 0),i=t.domain,e=t.range,s=0,a=1,c,l,f=!1,S=0,k=0,L=.5;delete t.unknown;function _(){var y=i().length,E=a<s,v=E?a:s,P=E?s:a;c=(P-v)/Math.max(1,y-S+k*2),f&&(c=Math.floor(c)),v+=(P-v-c*(y-S))*L,l=c*(1-S),f&&(v=Math.round(v),l=Math.round(l));var I=mi(y).map(function(p){return v+c*p});return e(E?I.reverse():I)}return t.domain=function(y){return arguments.length?(i(y),_()):i()},t.range=function(y){return arguments.length?([s,a]=y,s=+s,a=+a,_()):[s,a]},t.rangeRound=function(y){return[s,a]=y,s=+s,a=+a,f=!0,_()},t.bandwidth=function(){return l},t.step=function(){return c},t.round=function(y){return arguments.length?(f=!!y,_()):f},t.padding=function(y){return arguments.length?(S=Math.min(1,k=+y),_()):S},t.paddingInner=function(y){return arguments.length?(S=Math.min(1,y),_()):S},t.paddingOuter=function(y){return arguments.length?(k=+y,_()):k},t.align=function(y){return arguments.length?(L=Math.max(0,Math.min(1,y)),_()):L},t.copy=function(){return ut(i(),[s,a]).round(f).paddingInner(S).paddingOuter(k).align(L)},fi.apply(_(),arguments)}var gt=(function(){var t=n(function(F,r,u,g){for(u=u||{},g=F.length;g--;u[F[g]]=r);return u},"o"),i=[1,10,12,14,16,18,19,21,23],e=[2,6],s=[1,3],a=[1,5],c=[1,6],l=[1,7],f=[1,5,10,12,14,16,18,19,21,23,36,37,38],S=[1,25],k=[1,26],L=[1,28],_=[1,29],y=[1,30],E=[1,31],v=[1,32],P=[1,33],I=[1,34],p=[1,35],T=[1,36],h=[1,37],B=[1,43],W=[1,42],X=[1,47],Y=[1,50],C=[1,10,12,14,16,18,19,21,23,36,37,38],H=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38],b=[1,10,12,14,16,18,19,21,23,24,26,28,29,36,37,38,42,43,44,45,46,47,48,49,50,51],A=[1,65],V=[26,28],R={trace:n(function(){},"trace"),yy:{},symbols_:{error:2,start:3,eol:4,XYCHART:5,chartConfig:6,document:7,CHART_ORIENTATION:8,statement:9,title:10,text:11,X_AXIS:12,parseXAxis:13,Y_AXIS:14,parseYAxis:15,LINE:16,plotData:17,BAR:18,acc_title:19,acc_title_value:20,acc_descr:21,acc_descr_value:22,acc_descr_multiline_value:23,SQUARE_BRACES_START:24,dataPoints:25,SQUARE_BRACES_END:26,dataPoint:27,COMMA:28,NUMBER_WITH_DECIMAL:29,STR:30,xAxisData:31,bandData:32,ARROW_DELIMITER:33,commaSeparatedTexts:34,yAxisData:35,NEWLINE:36,SEMI:37,EOF:38,alphaNum:39,MD_STR:40,alphaNumToken:41,AMP:42,NUM:43,ALPHA:44,PLUS:45,EQUALS:46,MULT:47,DOT:48,BRKT:49,MINUS:50,UNDERSCORE:51,$accept:0,$end:1},terminals_:{2:"error",5:"XYCHART",8:"CHART_ORIENTATION",10:"title",12:"X_AXIS",14:"Y_AXIS",16:"LINE",18:"BAR",19:"acc_title",20:"acc_title_value",21:"acc_descr",22:"acc_descr_value",23:"acc_descr_multiline_value",24:"SQUARE_BRACES_START",26:"SQUARE_BRACES_END",28:"COMMA",29:"NUMBER_WITH_DECIMAL",30:"STR",33:"ARROW_DELIMITER",36:"NEWLINE",37:"SEMI",38:"EOF",40:"MD_STR",42:"AMP",43:"NUM",44:"ALPHA",45:"PLUS",46:"EQUALS",47:"MULT",48:"DOT",49:"BRKT",50:"MINUS",51:"UNDERSCORE"},productions_:[0,[3,2],[3,3],[3,2],[3,1],[6,1],[7,0],[7,2],[9,2],[9,2],[9,2],[9,2],[9,2],[9,3],[9,2],[9,3],[9,2],[9,2],[9,1],[17,3],[25,3],[25,1],[27,2],[27,1],[13,1],[13,2],[13,1],[31,1],[31,3],[32,3],[34,3],[34,1],[15,1],[15,2],[15,1],[35,3],[4,1],[4,1],[4,1],[11,1],[11,1],[11,1],[39,1],[39,2],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1],[41,1]],performAction:n(function(r,u,g,x,w,o,K){var d=o.length-1;switch(w){case 5:x.setOrientation(o[d]);break;case 9:x.setDiagramTitle(o[d].text.trim());break;case 12:x.setLineData({text:"",type:"text"},o[d]);break;case 13:x.setLineData(o[d-1],o[d]);break;case 14:x.setBarData({text:"",type:"text"},o[d]);break;case 15:x.setBarData(o[d-1],o[d]);break;case 16:this.$=o[d].trim(),x.setAccTitle(this.$);break;case 17:case 18:this.$=o[d].trim(),x.setAccDescription(this.$);break;case 19:this.$=o[d-1];break;case 20:case 30:this.$=[o[d-2],...o[d]];break;case 21:case 31:this.$=[o[d]];break;case 22:this.$={value:Number(o[d-1]),label:o[d]};break;case 23:this.$={value:Number(o[d]),label:""};break;case 24:x.setXAxisTitle(o[d]);break;case 25:x.setXAxisTitle(o[d-1]);break;case 26:x.setXAxisTitle({type:"text",text:""});break;case 27:x.setXAxisBand(o[d]);break;case 28:x.setXAxisRangeData(Number(o[d-2]),Number(o[d]));break;case 29:this.$=o[d-1];break;case 32:x.setYAxisTitle(o[d]);break;case 33:x.setYAxisTitle(o[d-1]);break;case 34:x.setYAxisTitle({type:"text",text:""});break;case 35:x.setYAxisRangeData(Number(o[d-2]),Number(o[d]));break;case 39:this.$={text:o[d],type:"text"};break;case 40:this.$={text:o[d],type:"text"};break;case 41:this.$={text:o[d],type:"markdown"};break;case 42:this.$=o[d];break;case 43:this.$=o[d-1]+""+o[d];break}},"anonymous"),table:[t(i,e,{3:1,4:2,7:4,5:s,36:a,37:c,38:l}),{1:[3]},t(i,e,{4:2,7:4,3:8,5:s,36:a,37:c,38:l}),t(i,e,{4:2,7:4,6:9,3:10,5:s,8:[1,11],36:a,37:c,38:l}),{1:[2,4],9:12,10:[1,13],12:[1,14],14:[1,15],16:[1,16],18:[1,17],19:[1,18],21:[1,19],23:[1,20]},t(f,[2,36]),t(f,[2,37]),t(f,[2,38]),{1:[2,1]},t(i,e,{4:2,7:4,3:21,5:s,36:a,37:c,38:l}),{1:[2,3]},t(f,[2,5]),t(i,[2,7],{4:22,36:a,37:c,38:l}),{11:23,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:39,13:38,24:B,29:W,30:S,31:40,32:41,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:45,15:44,29:X,30:S,35:46,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:49,17:48,24:Y,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{11:52,17:51,24:Y,30:S,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},{20:[1,53]},{22:[1,54]},t(C,[2,18]),{1:[2,2]},t(C,[2,8]),t(C,[2,9]),t(H,[2,39],{41:55,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h}),t(H,[2,40]),t(H,[2,41]),t(b,[2,42]),t(b,[2,44]),t(b,[2,45]),t(b,[2,46]),t(b,[2,47]),t(b,[2,48]),t(b,[2,49]),t(b,[2,50]),t(b,[2,51]),t(b,[2,52]),t(b,[2,53]),t(C,[2,10]),t(C,[2,24],{32:41,31:56,24:B,29:W}),t(C,[2,26]),t(C,[2,27]),{33:[1,57]},{11:59,30:S,34:58,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},t(C,[2,11]),t(C,[2,32],{35:60,29:X}),t(C,[2,34]),{33:[1,61]},t(C,[2,12]),{17:62,24:Y},{25:63,27:64,29:A},t(C,[2,14]),{17:66,24:Y},t(C,[2,16]),t(C,[2,17]),t(b,[2,43]),t(C,[2,25]),{29:[1,67]},{26:[1,68]},{26:[2,31],28:[1,69]},t(C,[2,33]),{29:[1,70]},t(C,[2,13]),{26:[1,71]},{26:[2,21],28:[1,72]},t(V,[2,23],{30:[1,73]}),t(C,[2,15]),t(C,[2,28]),t(C,[2,29]),{11:59,30:S,34:74,39:24,40:k,41:27,42:L,43:_,44:y,45:E,46:v,47:P,48:I,49:p,50:T,51:h},t(C,[2,35]),t(C,[2,19]),{25:75,27:64,29:A},t(V,[2,22]),{26:[2,30]},{26:[2,20]}],defaultActions:{8:[2,1],10:[2,3],21:[2,2],74:[2,30],75:[2,20]},parseError:n(function(r,u){if(u.recoverable)this.trace(r);else{var g=new Error(r);throw g.hash=u,g}},"parseError"),parse:n(function(r){var u=this,g=[0],x=[],w=[null],o=[],K=this.table,d="",et=0,Rt=0,Jt=2,_t=1,ti=o.slice.call(arguments,1),D=Object.create(this.lexer),U={yy:{}};for(var rt in this.yy)Object.prototype.hasOwnProperty.call(this.yy,rt)&&(U.yy[rt]=this.yy[rt]);D.setInput(r,U.yy),U.yy.lexer=D,U.yy.parser=this,typeof D.yylloc>"u"&&(D.yylloc={});var ht=D.yylloc;o.push(ht);var ii=D.options&&D.options.ranges;typeof U.yy.parseError=="function"?this.parseError=U.yy.parseError:this.parseError=Object.getPrototypeOf(this).parseError;function ei(z){g.length=g.length-2*z,w.length=w.length-z,o.length=o.length-z}n(ei,"popStack");function kt(){var z;return z=x.pop()||D.lex()||_t,typeof z!="number"&&(z instanceof Array&&(x=z,z=x.pop()),z=u.symbols_[z]||z),z}n(kt,"lex");for(var M,$,O,lt,G={},st,N,Tt,at;;){if($=g[g.length-1],this.defaultActions[$]?O=this.defaultActions[$]:((M===null||typeof M>"u")&&(M=kt()),O=K[$]&&K[$][M]),typeof O>"u"||!O.length||!O[0]){var ct="";at=[];for(st in K[$])this.terminals_[st]&&st>Jt&&at.push("'"+this.terminals_[st]+"'");D.showPosition?ct="Parse error on line "+(et+1)+`: `+D.showPosition()+` Expecting `+at.join(", ")+", got '"+(this.terminals_[M]||M)+"'":ct="Parse error on line "+(et+1)+": Unexpected "+(M==_t?"end of input":"'"+(this.terminals_[M]||M)+"'"),this.parseError(ct,{text:D.match,token:this.terminals_[M]||M,line:D.yylineno,loc:ht,expected:at})}if(O[0]instanceof Array&&O.length>1)throw new Error("Parse Error: multiple actions possible at state: "+$+", token: "+M);switch(O[0]){case 1:g.push(M),w.push(D.yytext),o.push(D.yylloc),g.push(O[1]),M=null,Rt=D.yyleng,d=D.yytext,et=D.yylineno,ht=D.yylloc;break;case 2:if(N=this.productions_[O[1]][1],G.$=w[w.length-N],G._$={first_line:o[o.length-(N||1)].first_line,last_line:o[o.length-1].last_line,first_column:o[o.length-(N||1)].first_column,last_column:o[o.length-1].last_column},ii&&(G._$.range=[o[o.length-(N||1)].range[0],o[o.length-1].range[1]]),lt=this.performAction.apply(G,[d,Rt,et,U.yy,O[1],w,o].concat(ti)),typeof lt<"u")return lt;N&&(g=g.slice(0,-1*N*2),w=w.slice(0,-1*N),o=o.slice(0,-1*N)),g.push(this.productions_[O[1]][0]),w.push(G.$),o.push(G._$),Tt=K[g[g.length-2]][g[g.length-1]],g.push(Tt);break;case 3:return!0}}return!0},"parse")},Q=(function(){var F={EOF:1,parseError:n(function(u,g){if(this.yy.parser)this.yy.parser.parseError(u,g);else throw new Error(u)},"parseError"),setInput:n(function(r,u){return this.yy=u||this.yy||{},this._input=r,this._more=this._backtrack=this.done=!1,this.yylineno=this.yyleng=0,this.yytext=this.matched=this.match="",this.conditionStack=["INITIAL"],this.yylloc={first_line:1,first_column:0,last_line:1,last_column:0},this.options.ranges&&(this.yylloc.range=[0,0]),this.offset=0,this},"setInput"),input:n(function(){var r=this._input[0];this.yytext+=r,this.yyleng++,this.offset++,this.match+=r,this.matched+=r;var u=r.match(/(?:\r\n?|\n).*/g);return u?(this.yylineno++,this.yylloc.last_line++):this.yylloc.last_column++,this.options.ranges&&this.yylloc.range[1]++,this._input=this._input.slice(1),r},"input"),unput:n(function(r){var u=r.length,g=r.split(/(?:\r\n?|\n)/g);this._input=r+this._input,this.yytext=this.yytext.substr(0,this.yytext.length-u),this.offset-=u;var x=this.match.split(/(?:\r\n?|\n)/g);this.match=this.match.substr(0,this.match.length-1),this.matched=this.matched.substr(0,this.matched.length-1),g.length-1&&(this.yylineno-=g.length-1);var w=this.yylloc.range;return this.yylloc={first_line:this.yylloc.first_line,last_line:this.yylineno+1,first_column:this.yylloc.first_column,last_column:g?(g.length===x.length?this.yylloc.first_column:0)+x[x.length-g.length].length-g[0].length:this.yylloc.first_column-u},this.options.ranges&&(this.yylloc.range=[w[0],w[0]+this.yyleng-u]),this.yyleng=this.yytext.length,this},"unput"),more:n(function(){return this._more=!0,this},"more"),reject:n(function(){if(this.options.backtrack_lexer)this._backtrack=!0;else return this.parseError("Lexical error on line "+(this.yylineno+1)+`. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true). `+this.showPosition(),{text:"",token:null,line:this.yylineno});return this},"reject"),less:n(function(r){this.unput(this.match.slice(r))},"less"),pastInput:n(function(){var r=this.matched.substr(0,this.matched.length-this.match.length);return(r.length>20?"...":"")+r.substr(-20).replace(/\n/g,"")},"pastInput"),upcomingInput:n(function(){var r=this.match;return r.length<20&&(r+=this._input.substr(0,20-r.length)),(r.substr(0,20)+(r.length>20?"...":"")).replace(/\n/g,"")},"upcomingInput"),showPosition:n(function(){var r=this.pastInput(),u=new Array(r.length+1).join("-");return r+this.upcomingInput()+` diff --git a/apps/kimi-code/dist-web/index.html b/apps/kimi-code/dist-web/index.html index 1b6bd0089..f98318975 100644 --- a/apps/kimi-code/dist-web/index.html +++ b/apps/kimi-code/dist-web/index.html @@ -14,8 +14,8 @@ the server's Content-Security-Policy forbids inline scripts. --> <script src="/boot.js"></script> <title>Kimi Code Web - - + +
diff --git a/apps/kimi-code/package.json b/apps/kimi-code/package.json index 681eaed3c..08df2c2f1 100644 --- a/apps/kimi-code/package.json +++ b/apps/kimi-code/package.json @@ -1,6 +1,6 @@ { "name": "@moonshot-ai/kimi-code", - "version": "0.38.0", + "version": "0.35.0", "description": "The Starting Point for Next-Gen Agents", "license": "MIT", "author": "Moonshot AI", @@ -94,9 +94,7 @@ "@moonshot-ai/pi-tui": "workspace:^", "@moonshot-ai/vis-server": "workspace:^", "@moonshot-ai/vis-web": "workspace:*", - "@types/qrcode": "^1.5.6", "@types/semver": "^7.7.0", - "@types/ws": "^8.18.0", "@types/yazl": "^2.4.6", "chalk": "^5.4.1", "cli-highlight": "^2.1.11", @@ -112,9 +110,5 @@ }, "engines": { "node": ">=22.19.0" - }, - "dependencies": { - "qrcode": "^1.5.4", - "ws": "^8.18.0" } } diff --git a/apps/kimi-code/src/cli/commands.ts b/apps/kimi-code/src/cli/commands.ts index 6b6c3aca0..a090df4d0 100644 --- a/apps/kimi-code/src/cli/commands.ts +++ b/apps/kimi-code/src/cli/commands.ts @@ -15,7 +15,6 @@ export type MainCommandHandler = (opts: CLIOptions) => void; export type MigrateCommandHandler = () => void; export type PluginNodeRunnerHandler = (entry: string, args: readonly string[]) => void; export type UpgradeCommandHandler = () => void | Promise; -export type UpdateDownloadHandler = (version: string, manual: boolean) => void; export function createProgram( version: string, @@ -23,7 +22,6 @@ export function createProgram( onMigrate: MigrateCommandHandler, onPluginNodeRunner: PluginNodeRunnerHandler = () => {}, onUpgrade: UpgradeCommandHandler = () => {}, - onUpdateDownload: UpdateDownloadHandler = () => {}, ): Command { const program = new Command(CLI_COMMAND_NAME) .description('The Starting Point for Next-Gen Agents') @@ -140,17 +138,6 @@ export function createProgram( onPluginNodeRunner(entry, args); }); - // Self-spawned worker for native staged updates (detached background - // download, or foreground from `kimi upgrade` — `--manual` marks the - // latter's stage as user-requested). Hidden: not user-facing. - program - .command('__update_download', { hidden: true }) - .argument('') - .option('--manual', 'the stage answers an explicit user-initiated upgrade') - .action((targetVersion: string, options: { manual?: boolean }) => { - onUpdateDownload(targetVersion, options.manual === true); - }); - program.argument('[args...]').action((args: string[]) => { if (args.length > 0) { program.error(`unknown command '${args[0]}'. See '${CLI_COMMAND_NAME} --help'.`); diff --git a/apps/kimi-code/src/cli/run-shell.ts b/apps/kimi-code/src/cli/run-shell.ts index ceade4c81..d7a13cb75 100644 --- a/apps/kimi-code/src/cli/run-shell.ts +++ b/apps/kimi-code/src/cli/run-shell.ts @@ -1,4 +1,4 @@ -import { execFileSync, spawnSync } from 'node:child_process'; +import { execSync, spawnSync } from 'node:child_process'; import { homedir } from 'node:os'; import { join } from 'node:path'; @@ -29,7 +29,6 @@ import { startupTrace } from '#/utils/startup-trace'; import { currentTheme, getColorPalette } from '#/tui/theme'; import { toTerminalHyperlink } from '#/utils/terminal-hyperlink'; import { restoreTerminalModes } from '#/utils/terminal-restore'; -import { resolveCommandPath } from '#/utils/process/resolve-command'; import type { CLIOptions } from './options'; import { resolveAgentProfileSelection } from './agent-selection'; @@ -156,34 +155,28 @@ export async function runShell( }; let savedStty: string | undefined; - // stty runs before tui.start() reaches the workspace trust gate, so it must - // never be resolved by name through PATH: a `.` or empty PATH segment would - // let an untrusted checkout plant an `stty` executable and run it pre-trust. - // resolveCommandPath returns an absolute path and refuses hits inside the - // cwd; when it cannot resolve stty, skip the save/restore entirely — it is - // best-effort terminal hygiene, not required for startup. - // stty is also POSIX-only, so skip it on Windows instead of relying on the - // catch below. - const sttyPath = process.platform === 'win32' ? undefined : resolveCommandPath('stty'); - if (sttyPath !== undefined) { + // stty is a POSIX command and never works on Windows; skip it there instead + // of relying on the catch — a bare command name would resolve a planted + // `stty.exe` from the current directory before the workspace trust gate. + if (process.platform !== 'win32') { try { // stty operates on the terminal behind stdin, so stdin must be the TTY — // piping /dev/null (ignore) makes stty fail with "not a tty". - const saved = execFileSync(sttyPath, ['-g'], { + const saved = execSync('stty -g', { encoding: 'utf8', stdio: ['inherit', 'pipe', 'ignore'], }); - savedStty = saved.trim(); - execFileSync(sttyPath, ['-ixon'], { stdio: ['inherit', 'ignore', 'ignore'] }); + savedStty = typeof saved === 'string' ? saved.trim() : undefined; + execSync('stty -ixon', { stdio: ['inherit', 'ignore', 'ignore'] }); } catch { /* ignore */ } } const restoreStty = (): void => { - if (sttyPath === undefined || savedStty === undefined) return; + if (savedStty === undefined) return; const args = savedStty.split(/\s+/).filter((arg) => arg.length > 0); if (args.length === 0) return; - spawnSync(sttyPath, args, { stdio: ['inherit', 'ignore', 'ignore'] }); + spawnSync('stty', args, { stdio: ['inherit', 'ignore', 'ignore'] }); }; // If we crash without going through KimiTUI.stop(), the terminal is left in @@ -231,7 +224,7 @@ export async function runShell( const sessionId = tui.getCurrentSessionId(); const hasContent = tui.hasSessionContent(); setCrashPhase('shutdown'); - trackLifecycle('exit', { duration_ms: Date.now() - startedAt, tui_mode: tui.state.ui.mode }); + trackLifecycle('exit', { duration_ms: Date.now() - startedAt }); await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS }); const gutter = ' '.repeat(CHROME_GUTTER); process.stdout.write(`${gutter}Bye!\n`); @@ -269,12 +262,11 @@ export async function runShell( config_ms: configMs, init_ms: initMs, mcp_ms: mcpMs, - tui_mode: tui.state.ui.mode, }); } catch (error) { removeCrashHandlers(); setCrashPhase('shutdown'); - trackLifecycle('exit', { duration_ms: Date.now() - startedAt, tui_mode: tui.state.ui.mode }); + trackLifecycle('exit', { duration_ms: Date.now() - startedAt }); await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS }); await harness.close(); throw error; diff --git a/apps/kimi-code/src/cli/sub/acp-native.ts b/apps/kimi-code/src/cli/sub/acp-native.ts index 83d444e34..2b9886769 100644 --- a/apps/kimi-code/src/cli/sub/acp-native.ts +++ b/apps/kimi-code/src/cli/sub/acp-native.ts @@ -25,7 +25,7 @@ import { getVersion } from '#/cli/version'; import { KIMI_CODE_HOME_ENV } from '#/constant/app'; import { getDataDir } from '#/utils/paths'; -import { parseRegionFlag, runLoginFlow } from './login-flow'; +import { runLoginFlow } from './login-flow'; export function registerNativeAcpCommand(parent: Command): void { parent @@ -36,12 +36,9 @@ export function registerNativeAcpCommand(parent: Command): void { 'Run the device-code login flow then exit (entry point for ACP terminal-auth).', false, ) - .option('--region ', 'Login region used together with --login: "mainland-cn" (kimi.com) or "global" (kimi.ai).') - .action(async (opts: { login?: boolean; region?: string }) => { + .action(async (opts: { login?: boolean }) => { if (opts.login === true) { - await runLoginFlow({ - region: opts.region === undefined ? undefined : parseRegionFlag(opts.region), - }); + await runLoginFlow(); return; } // Forward `KIMI_CODE_HOME` (if set) into `authMethods[0].env` so the diff --git a/apps/kimi-code/src/cli/sub/acp.ts b/apps/kimi-code/src/cli/sub/acp.ts index d0803a852..4da7e892e 100644 --- a/apps/kimi-code/src/cli/sub/acp.ts +++ b/apps/kimi-code/src/cli/sub/acp.ts @@ -35,7 +35,7 @@ import { buildSkillSlashCommands } from '#/tui/commands/skills'; import { isLegacyEnabled } from '../experimental-v2'; import { registerNativeAcpCommand } from './acp-native'; -import { parseRegionFlag, runLoginFlow } from './login-flow'; +import { runLoginFlow } from './login-flow'; export function registerAcpCommand(parent: Command): void { if (!isLegacyEnabled()) { @@ -51,12 +51,9 @@ export function registerAcpCommand(parent: Command): void { 'Run the device-code login flow then exit (entry point for ACP terminal-auth).', false, ) - .option('--region ', 'Login region used together with --login: "mainland-cn" (kimi.com) or "global" (kimi.ai).') - .action(async (opts: { login?: boolean; region?: string }) => { + .action(async (opts: { login?: boolean }) => { if (opts.login === true) { - await runLoginFlow({ - region: opts.region === undefined ? undefined : parseRegionFlag(opts.region), - }); + await runLoginFlow(); return; } const identity = createKimiCodeHostIdentity(); diff --git a/apps/kimi-code/src/cli/sub/login-flow.ts b/apps/kimi-code/src/cli/sub/login-flow.ts index 34014660b..005dc1729 100644 --- a/apps/kimi-code/src/cli/sub/login-flow.ts +++ b/apps/kimi-code/src/cli/sub/login-flow.ts @@ -6,27 +6,11 @@ */ import { createKimiHarness } from '@moonshot-ai/kimi-code-sdk'; -import type { KimiRegion } from '@moonshot-ai/kimi-code-oauth'; import { createKimiCodeHostIdentity } from '#/cli/version'; import { openUrl } from '#/utils/open-url'; -import { persistedKimiOAuthRef, regionForBareLogin } from '#/utils/region'; -/** Parse a `--region` CLI flag; exits with an actionable message on bad input. */ -export function parseRegionFlag(value: string): KimiRegion { - if (value !== 'mainland-cn' && value !== 'global') { - process.stderr.write(`Invalid --region "${value}" (expected "mainland-cn" or "global").\n`); - process.exit(1); - } - return value; -} - -export async function runLoginFlow(options: { region?: KimiRegion } = {}): Promise { - // No flag: a fresh install follows the resolved region (env/marker/ - // default); an existing login keeps its own environment (see - // regionForBareLogin — the default slot re-pins mainland-cn, a scoped slot - // keeps its configured hosts). - const region = options.region ?? regionForBareLogin(persistedKimiOAuthRef()); +export async function runLoginFlow(): Promise { const identity = createKimiCodeHostIdentity(); const harness = createKimiHarness({ identity, @@ -39,7 +23,6 @@ export async function runLoginFlow(options: { region?: KimiRegion } = {}): Promi try { const result = await harness.auth.login(undefined, { signal: controller.signal, - region, onDeviceCode: (data) => { const url = data.verificationUriComplete || data.verificationUri; // Print the manual fallback before attempting to open the user's diff --git a/apps/kimi-code/src/cli/sub/login.ts b/apps/kimi-code/src/cli/sub/login.ts index 78510c995..2c17b4c3a 100644 --- a/apps/kimi-code/src/cli/sub/login.ts +++ b/apps/kimi-code/src/cli/sub/login.ts @@ -8,19 +8,13 @@ import type { Command } from 'commander'; -import { parseRegionFlag, runLoginFlow } from './login-flow'; +import { runLoginFlow } from './login-flow'; export function registerLoginCommand(parent: Command): void { parent .command('login') .description('Authenticate with Kimi Code CLI via the device-code flow.') - .option( - '--region ', - 'Login region: "mainland-cn" (kimi.com) or "global" (kimi.ai).', - ) - .action(async (opts: { region?: string }) => { - await runLoginFlow({ - region: opts.region === undefined ? undefined : parseRegionFlag(opts.region), - }); + .action(async () => { + await runLoginFlow(); }); } diff --git a/apps/kimi-code/src/cli/sub/update-download.ts b/apps/kimi-code/src/cli/sub/update-download.ts deleted file mode 100644 index efc582ecb..000000000 --- a/apps/kimi-code/src/cli/sub/update-download.ts +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Hidden `kimi __update_download ` sub-command: the self-spawned - * worker behind native staged updates. Preflight spawns it detached in the - * background (and the `upgrade` command in the foreground); it downloads, - * verifies and stages the binary next to the running exe. The swap into - * place happens on the next startup (see `cli/update/native-swap.ts`). - */ - -import { log } from '@moonshot-ai/kimi-code-sdk'; - -import { - readUpdateInstallLockVersion, - tryAcquireUpdateInstallLock, - type UpdateInstallLockHandle, -} from '#/cli/update/install-lock'; -import { - hashFileSha256, - promoteStagedUpdateToManual, - readStagedNativeUpdate, - stagedExePath, - stageNativeUpdate, -} from '#/cli/update/native-stage'; -import { detectNativeInstall } from '#/cli/update/source'; - -const LOCK_HELD_POLL_INTERVAL_MS = 2_000; - -type StagedUpdateWait = - | { readonly status: 'staged' } - | { readonly status: 'takeover'; readonly lock: UpdateInstallLockHandle | null }; - -/** - * Another worker holds the install lock for the SAME version. Returning right - * away would report a success that has not happened yet — the in-flight - * download may still fail — so wait for it: 'staged' once its staged update is - * verified on disk; 'takeover' once the lock becomes acquirable, with the lock - * already held for the caller. The lock goes stale the moment its holder dies - * (see install-lock), so a killed downloader cannot strand a foreground - * `kimi upgrade` in this loop. - * - * Adoption applies the same integrity bar as stageNativeUpdate's - * already-staged path: the recorded size proves nothing, and the holder may - * still be RE-STAGING a same-size-corrupted payload (its metadata is only - * replaced when the new generation publishes). A recorded stage whose payload - * fails the checksum is treated as not-yet-staged — the lock poll below takes - * over once the holder finishes without repairing it. - * - * A manual (explicit-upgrade) waiter adopts only after CONFIRMING the manual - * marker landed on the stage — a concurrent startup swap may be claiming and - * restoring the metadata right now, and reporting adoption for a promotion - * that never persisted would strand the update under the env opt-out. - */ -async function waitForStagedUpdate( - version: string, - exePath: string, - manual: boolean, -): Promise { - for (;;) { - const staged = await readStagedNativeUpdate(exePath); - const digest = - staged !== null && staged.version === version - ? await hashFileSha256(stagedExePath(exePath, staged)) - : null; - if (staged !== null && digest === staged.sha256) { - if (!manual || (await promoteStagedUpdateToManual(exePath, staged))) { - return { status: 'staged' }; - } - // The stage is being claimed/restored by a concurrent swap — the next - // poll either promotes the restored stage or takes over once it is - // gone. - } else { - // Poll the acquisition itself: while the holder lives its lock stays - // fresh and this returns null without side effects; when the holder - // finishes (or dies) without staging a VERIFIED payload, the takeover - // happens right here. - const lock = await tryAcquireUpdateInstallLock({ version }); - if (lock !== null) return { status: 'takeover', lock }; - } - await new Promise((resolve) => { - setTimeout(resolve, LOCK_HELD_POLL_INTERVAL_MS); - }); - } -} - -export async function runUpdateDownloadCommand( - version: string, - manual: boolean = false, -): Promise { - if (!detectNativeInstall()) { - process.stderr.write('error: update download is only available in the native build\n'); - return 1; - } - const out = process.stdout; - let lock = await tryAcquireUpdateInstallLock({ version }); - if (lock === null) { - const holderVersion = await readUpdateInstallLockVersion(); - if (holderVersion === version) { - // Another worker is already downloading this exact version: wait for it - // and adopt its verified result instead of exiting on a maybe. - out.write( - `A download of Kimi Code ${version} is already in progress; waiting for it to finish…\n`, - ); - const wait = await waitForStagedUpdate(version, process.execPath, manual); - if (wait.status === 'staged') { - out.write(`Kimi Code ${version} is downloaded; it applies on the next start.\n`); - return 0; - } - // The holder finished without staging (failed or died): take over. The - // lock may already be held by another winner of the takeover race — - // the null check below reports that as held. - lock = wait.lock; - } else if (holderVersion === undefined) { - // The lock was released between the two reads — retry the acquire once. - lock = await tryAcquireUpdateInstallLock({ version }); - } - if (lock === null) { - process.stderr.write( - `error: another update (${holderVersion ?? 'unknown version'}) is already downloading\n`, - ); - return 1; - } - } - const label = `Downloading Kimi Code ${version} (${process.platform}-${process.arch})…`; - const onProgress = createDownloadProgress(out, label); - try { - const result = await stageNativeUpdate({ - version, - exePath: process.execPath, - onProgress, - manual, - }); - if (out.isTTY) out.write('\n'); - if (result.status === 'already-staged') { - out.write(`Kimi Code ${version} is already downloaded; it applies on the next start.\n`); - } - return 0; - } catch (error) { - if (out.isTTY) out.write('\n'); - const message = error instanceof Error ? error.message : String(error); - process.stderr.write(`error: failed to download update ${version}: ${message}\n`); - log.warn('native update download failed', { version, error: message }); - return 1; - } finally { - await lock.release().catch(() => {}); - } -} - -const PROGRESS_FRAME_INTERVAL_MS = 100; -const PROGRESS_LINE_INTERVAL_BYTES = 32 * 1024 * 1024; - -function formatDownloadProgress(label: string, downloaded: number, total: number | null): string { - const mb = Math.floor(downloaded / (1024 * 1024)); - if (total === null || total <= 0) return `${label} ${mb} MB`; - const totalMb = Math.max(1, Math.round(total / (1024 * 1024))); - const percent = Math.min(100, Math.floor((downloaded / total) * 100)); - return `${label} ${percent}% (${mb}/${totalMb} MB)`; -} - -/** - * Download progress renderer for the (foreground) downloader: a single - * in-place line on a TTY (`\r` + clear-line, throttled to 10 fps, final frame - * always rendered), or one line per 32 MB when piped to a file. The caller - * owns the trailing newline. - */ -export function createDownloadProgress( - out: NodeJS.WriteStream, - label: string, -): (downloadedBytes: number, totalBytes: number | null) => void { - const isTTY = out.isTTY; - let lastFrameAt = 0; - let lastLineAt = 0; - if (!isTTY) out.write(`${label}\n`); - return (downloaded, total) => { - const done = total !== null && downloaded >= total; - if (isTTY) { - const now = Date.now(); - if (!done && now - lastFrameAt < PROGRESS_FRAME_INTERVAL_MS) return; - lastFrameAt = now; - out.write(`\r\u001B[K${formatDownloadProgress(label, downloaded, total)}`); - return; - } - if (!done && downloaded - lastLineAt < PROGRESS_LINE_INTERVAL_BYTES) return; - lastLineAt = downloaded; - out.write(`${formatDownloadProgress(label, downloaded, total)}\n`); - }; -} diff --git a/apps/kimi-code/src/cli/sub/web/index.ts b/apps/kimi-code/src/cli/sub/web/index.ts index c7bb5d836..8cf840671 100644 --- a/apps/kimi-code/src/cli/sub/web/index.ts +++ b/apps/kimi-code/src/cli/sub/web/index.ts @@ -13,7 +13,6 @@ import type { Command } from 'commander'; import { registerDeprecatedServerCommand } from './deprecated-server'; -import { isRemoteControlEnabled } from './remote-control'; import { registerRotateTokenCommand } from './rotate-token'; import { buildWebCommand } from './run'; @@ -25,11 +24,4 @@ export function registerWebCommand(program: Command): void { ); registerRotateTokenCommand(web); registerDeprecatedServerCommand(program); - buildWebCommand( - program - .command('rc', { hidden: !isRemoteControlEnabled() }) - .alias('remote') - .description('Run the local Kimi server and open the web UI through Remote Control (experimental).'), - { forceRemoteControl: true }, - ); } diff --git a/apps/kimi-code/src/cli/sub/web/remote-control-lock.ts b/apps/kimi-code/src/cli/sub/web/remote-control-lock.ts deleted file mode 100644 index bc5d02960..000000000 --- a/apps/kimi-code/src/cli/sub/web/remote-control-lock.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { randomBytes } from 'node:crypto'; -import { mkdir, open, readFile, unlink } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; - -export interface RemoteControlLockInfo { - readonly pid: number; - readonly nonce: string; - readonly localOrigin: string; - readonly deviceId: string; - readonly url: string; - readonly startedAt: number; -} - -interface RemoteControlLockDisk { - readonly pid: number; - readonly nonce: string; - readonly local_origin: string; - readonly device_id: string; - readonly url: string; - readonly started_at: number; -} - -export class RemoteControlAlreadyRunningError extends Error { - readonly holder: RemoteControlLockInfo; - - constructor(holder: RemoteControlLockInfo) { - super(formatRemoteControlAlreadyRunning(holder)); - this.name = 'RemoteControlAlreadyRunningError'; - this.holder = holder; - } -} - -export function formatRemoteControlAlreadyRunning(holder: RemoteControlLockInfo): string { - return [ - `Remote Control is already running on this machine (pid ${holder.pid}, ${holder.localOrigin}, since ${new Date(holder.startedAt).toLocaleString()}).`, - `Use the existing link: ${holder.url}`, - 'To start a new one here, stop the other `kimi web --remote-control` process first.', - ].join('\n'); -} - -export function remoteControlLockPath(homeDir: string): string { - return join(homeDir, 'server', 'rc.json'); -} - -export interface RemoteControlLock { - release(): Promise; -} - -const MAX_ACQUIRE_ATTEMPTS = 3; - -export async function acquireRemoteControlLock( - homeDir: string, - details: { localOrigin: string; deviceId: string; url: string }, -): Promise { - const lockPath = remoteControlLockPath(homeDir); - await mkdir(dirname(lockPath), { recursive: true }); - const info: RemoteControlLockInfo = { - pid: process.pid, - nonce: randomBytes(8).toString('hex'), - localOrigin: details.localOrigin, - deviceId: details.deviceId, - url: details.url, - startedAt: Date.now(), - }; - for (let attempt = 0; ; attempt += 1) { - try { - const handle = await open(lockPath, 'wx'); - try { - await handle.writeFile(encodeLock(info)); - } finally { - await handle.close(); - } - return { release: () => releaseRemoteControlLock(lockPath, info.nonce) }; - } catch (error) { - if ((error as NodeJS.ErrnoException).code !== 'EEXIST' || attempt >= MAX_ACQUIRE_ATTEMPTS) { - throw error; - } - const holder = await readRemoteControlLock(lockPath); - if (holder !== undefined && pidAlive(holder.pid)) { - throw new RemoteControlAlreadyRunningError(holder); - } - await removeFile(lockPath); - } - } -} - -export async function inspectRemoteControlLock( - homeDir: string, -): Promise { - const lockPath = remoteControlLockPath(homeDir); - const info = await readRemoteControlLock(lockPath); - if (info === undefined) return undefined; - if (!pidAlive(info.pid)) { - await removeFile(lockPath); - return undefined; - } - return info; -} - -async function releaseRemoteControlLock(lockPath: string, nonce: string): Promise { - const info = await readRemoteControlLock(lockPath); - if (info === undefined || info.nonce !== nonce) return; - await removeFile(lockPath); -} - -async function readRemoteControlLock(lockPath: string): Promise { - let raw: string; - try { - raw = await readFile(lockPath, 'utf8'); - } catch { - return undefined; - } - return decodeLock(raw); -} - -function encodeLock(info: RemoteControlLockInfo): string { - const disk: RemoteControlLockDisk = { - pid: info.pid, - nonce: info.nonce, - local_origin: info.localOrigin, - device_id: info.deviceId, - url: info.url, - started_at: info.startedAt, - }; - return JSON.stringify(disk); -} - -function decodeLock(raw: string): RemoteControlLockInfo | undefined { - try { - const parsed = JSON.parse(raw) as Partial; - if ( - typeof parsed.pid === 'number' && - typeof parsed.nonce === 'string' && - typeof parsed.local_origin === 'string' && - typeof parsed.device_id === 'string' && - typeof parsed.url === 'string' && - typeof parsed.started_at === 'number' - ) { - return { - pid: parsed.pid, - nonce: parsed.nonce, - localOrigin: parsed.local_origin, - deviceId: parsed.device_id, - url: parsed.url, - startedAt: parsed.started_at, - }; - } - return undefined; - } catch { - return undefined; - } -} - -async function removeFile(lockPath: string): Promise { - try { - await unlink(lockPath); - } catch (error) { - if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error; - } -} - -function pidAlive(pid: number): boolean { - try { - process.kill(pid, 0); - return true; - } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'ESRCH') return false; - return true; - } -} diff --git a/apps/kimi-code/src/cli/sub/web/remote-control.ts b/apps/kimi-code/src/cli/sub/web/remote-control.ts deleted file mode 100644 index 73e74f46f..000000000 --- a/apps/kimi-code/src/cli/sub/web/remote-control.ts +++ /dev/null @@ -1,1009 +0,0 @@ -import { hostname, platform } from 'node:os'; -import { join } from 'node:path'; -import { request as httpRequest, validateHeaderName, validateHeaderValue } from 'node:http'; -import { setTimeout as sleep } from 'node:timers/promises'; - -import { - createKimiDeviceId, - FileTokenStorage, - KIMI_CODE_PROVIDER_NAME, - resolveKimiTokenStorageName, -} from '@moonshot-ai/kimi-code-oauth'; -import { WebSocket, type RawData } from 'ws'; -import chalk from 'chalk'; - -import { getVersion } from '../../version'; -import { darkColors } from '../../../tui/theme/colors'; -import { supportsHyperlinks, toTerminalHyperlink } from '../../../utils/terminal-hyperlink'; -import { acquireRemoteControlLock } from './remote-control-lock'; - -export const REMOTE_CONTROL_RELAY_ORIGIN = 'https://code-rc.kimi.com'; - -export const REMOTE_CONTROL_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL'; - -const TRUTHY_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']); - -export function isRemoteControlEnabled( - env: Readonly> = process.env, -): boolean { - const truthy = (key: string): boolean => - TRUTHY_ENV_VALUES.has((env[key] ?? '').trim().toLowerCase()); - return truthy('KIMI_CODE_EXPERIMENTAL_FLAG') || truthy(REMOTE_CONTROL_FLAG_ENV); -} - -const MAX_HTTP_HEADER_BYTES = 64 * 1024; -const MAX_HTTP_REQUEST_BYTES = 10 * 1024 * 1024; -const HTTP_REQUEST_TIMEOUT_MS = 30_000; -const REGISTER_TIMEOUT_MS = 10_000; -const MAX_RECONNECT_DELAY_MS = 30_000; -const BLOCKED_REQUEST_HEADERS = new Set([ - 'authorization', - 'cookie', - 'host', - 'origin', - 'proxy-authorization', - 'proxy-authenticate', - 'accept-encoding', - 'connection', - 'keep-alive', - 'proxy-connection', - 'te', - 'trailer', - 'transfer-encoding', - 'upgrade', -]); -const BLOCKED_RESPONSE_HEADERS = new Set([ - 'connection', - 'content-length', - 'keep-alive', - 'proxy-authenticate', - 'proxy-authorization', - 'proxy-connection', - 'te', - 'trailer', - 'transfer-encoding', - 'upgrade', -]); - -interface RelayMessage { - readonly type: string; - readonly payload?: Record; -} - -interface PendingHttpRequest { - readonly chunks: Buffer[]; - size: number; -} - -export interface ParsedRawHttpRequest { - readonly method: string; - readonly path: string; - readonly headers: readonly [string, string][]; - readonly body: Buffer; -} - -export type RemoteControlStatus = - | 'relay_connected' - | 'relay_disconnected' - | 'device_connected' - | 'device_disconnected'; - -export interface RemoteControlOptions { - readonly homeDir: string; - readonly localOrigin: string; - readonly localServerToken: string; - readonly relayOrigin?: string; - readonly stderr?: Pick; - readonly onStatus?: (status: RemoteControlStatus) => void; -} - -export interface RemoteControlHandle { - readonly deviceId: string; - readonly deviceName: string; - readonly url: string; - close(): Promise; -} - -interface ActiveStream { - readonly local: WebSocket; - readonly tunnel: WebSocket; -} - -class RegistrationError extends Error {} - -export interface RemoteControlOutputOptions { - readonly url: string; - readonly localOrigin: string; - readonly deviceName: string; - readonly qrCode: string; - readonly pngPath: string; -} - -export function formatRemoteControlOutput(options: RemoteControlOutputOptions): string { - const title = (text: string): string => chalk.bold.hex(darkColors.primary)(text); - const label = (text: string): string => chalk.bold.hex(darkColors.textDim)(text); - const accent = (text: string): string => chalk.hex(darkColors.accent)(text); - const muted = (text: string): string => chalk.hex(darkColors.textMuted)(text); - const status = (text: string): string => chalk.hex(darkColors.success)(text); - const link = (url: string): string => - supportsHyperlinks() - ? toTerminalHyperlink(accent(shortRemoteControlUrl(url)), url) - : accent(url); - const docs = toTerminalHyperlink('docs', 'https://kimi.com/code/docs/remote-control'); - const feedback = toTerminalHyperlink('feedback', 'https://kimi.com/code/feedback'); - return [ - '', - ` ${title('Kimi Remote Control ready')} ${muted(`${getVersion()} (experimental)`)}`, - ` ${muted('Use Kimi Code on this machine from your phone or another computer.')}`, - '', - ` ${label('1.')} Scan the QR code, or open ${link(options.url)}`, - ` ${label('2.')} Log in with your Kimi account`, - ` ${label('3.')} Start chatting — sessions run on this machine`, - '', - ` ${status('✓')} ${muted(`Connected to ${new URL(options.url).host}, waiting for remote devices…`)}`, - ` ${label('This device: ')}${muted(options.deviceName)}`, - ` ${status('⚠')} ${muted('This link grants control of this machine. Do not share it.')}`, - '', - options.qrCode.trimEnd().replaceAll(/^/gm, ' '), - ` ${label('QR code PNG: ')}${options.pngPath} ${muted('(open this if the QR above does not scan)')}`, - ` ${label('Local UI: ')}${muted(options.localOrigin)} ${muted('(LAN: --host)')}`, - '', - ` ${muted('Experimental —')} ${docs} ${muted('·')} ${feedback}`, - ` ${label('Logs: ')}${muted('off (--log-level info)')} ${muted('·')} ${label('Stop: ')}${muted('Ctrl+C')}`, - '', - ].join('\n'); -} - -export function formatRemoteControlStatus(status: RemoteControlStatus): string { - const label = (text: string): string => chalk.bold.hex(darkColors.textDim)(text); - const value = (text: string): string => chalk.hex(darkColors.success)(text); - switch (status) { - case 'relay_connected': - return ` ${value('✓')} ${label('Connected to relay, waiting for remote devices…')}\n`; - case 'relay_disconnected': - return ` ${value('!')} ${label('Relay disconnected; reconnecting…')}\n`; - case 'device_connected': - return ` ${value('✓')} ${label('Remote device connected (1 active session)')}\n`; - case 'device_disconnected': - return ` ${value('→')} ${label('Remote device disconnected')}\n`; - } -} - -function shortRemoteControlUrl(url: string): string { - const parsed = new URL(url); - const parts = parsed.pathname.split('/'); - const deviceIndex = parts.indexOf('devices'); - const deviceId = deviceIndex >= 0 ? parts[deviceIndex + 1] : undefined; - if (deviceId !== undefined && deviceId.length > 12) { - parts[deviceIndex + 1] = `${deviceId.slice(0, 6)}…${deviceId.slice(-4)}`; - } - return `${parsed.host}${parts.join('/')}`; -} - -export function buildRemoteControlUrl( - deviceId: string, - sessionId?: string, - relayOrigin = REMOTE_CONTROL_RELAY_ORIGIN, -): string { - const url = new URL(relayOrigin); - const relayPath = url.pathname.replace(/\/+$/, ''); - const devicePath = `${relayPath}/devices/${encodeURIComponent(deviceId)}`; - url.pathname = - sessionId === undefined - ? `${devicePath}/` - : `${devicePath}/sessions/${encodeURIComponent(sessionId)}`; - url.search = new URLSearchParams({ rc: '1', from: 'kimi_code_cli' }).toString(); - url.hash = ''; - return url.toString(); -} - -export function parseRawHttpRequest(raw: Buffer): ParsedRawHttpRequest { - const separator = raw.indexOf('\r\n\r\n'); - if (separator < 0 || separator > MAX_HTTP_HEADER_BYTES) { - throw new SyntaxError('invalid HTTP request headers'); - } - const head = raw.subarray(0, separator).toString('latin1'); - const lines = head.split('\r\n'); - const requestLine = lines.shift(); - const match = requestLine?.match( - /^([!#$%&'*+.^_`|~0-9A-Za-z-]+) (\/[^\u0000-\u0020]*) HTTP\/1\.[01]$/, - ); - if (match === null || match === undefined || match[2]!.startsWith('//')) { - throw new SyntaxError('invalid HTTP request line'); - } - const headers: [string, string][] = []; - for (const line of lines) { - const colon = line.indexOf(':'); - if (colon <= 0) throw new SyntaxError('invalid HTTP request header'); - const name = line.slice(0, colon).trim(); - const value = line.slice(colon + 1).trim(); - try { - validateHeaderName(name); - validateHeaderValue(name, value); - } catch { - throw new SyntaxError('invalid HTTP request header'); - } - headers.push([name, value]); - } - return { - method: match[1]!, - path: match[2]!, - headers, - body: raw.subarray(separator + 4), - }; -} - -export function filterForwardRequestHeaders( - headers: readonly [string, string][], - serverToken: string, -): string[] { - const connectionHeaders = new Set(); - for (const [name, value] of headers) { - if (name.toLowerCase() === 'connection') { - for (const token of value.split(',')) connectionHeaders.add(token.trim().toLowerCase()); - } - } - const result: string[] = []; - for (const [name, value] of headers) { - const lower = name.toLowerCase(); - if (BLOCKED_REQUEST_HEADERS.has(lower) || connectionHeaders.has(lower)) continue; - result.push(name, value); - } - result.push('Authorization', `Bearer ${serverToken}`); - return result; -} - -export function rewriteRemoteControlResponse( - contentType: string, - body: Buffer, - publicPrefix: string, -): Buffer { - const normalizedPrefix = publicPrefix.replace(/\/+$/, ''); - if (contentType.toLowerCase().includes('text/html')) { - const prefixLiteral = JSON.stringify(normalizedPrefix); - const injected = ``; - let text = body.toString('utf8'); - const headMatch = /]*)?>/i.exec(text); - text = - headMatch === null - ? injected + text - : text.slice(0, headMatch.index + headMatch[0].length) + - injected + - text.slice(headMatch.index + headMatch[0].length); - text = text.replaceAll(/\bsrc="\//g, `src="${normalizedPrefix}/`); - text = text.replaceAll(/\bhref="\//g, `href="${normalizedPrefix}/`); - return Buffer.from(text); - } - const lower = contentType.toLowerCase(); - if (lower.includes('javascript') || lower.includes('text/css')) { - let text = body.toString('utf8'); - text = text.replaceAll('"/assets/', `"${normalizedPrefix}/assets/`); - text = text.replaceAll("'/assets/", `'${normalizedPrefix}/assets/`); - text = text.replaceAll('(/assets/', `(${normalizedPrefix}/assets/`); - text = text.replaceAll('"/sessions/"', `"${normalizedPrefix}/sessions/"`); - text = text.replaceAll('return"/"+', `return"${normalizedPrefix}/"+`); - return Buffer.from(text); - } - return body; -} - -export async function startRemoteControl( - options: RemoteControlOptions, -): Promise { - if (options.localServerToken.length === 0) { - throw new Error('Remote Control requires local server authentication.'); - } - const storage = new FileTokenStorage(join(options.homeDir, 'credentials')); - const token = await storage.load( - resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }), - ); - if (token?.refreshToken === undefined || token.refreshToken.length === 0) { - throw new Error('Remote Control requires a Kimi login. Run `kimi login` first.'); - } - const relayOrigin = options.relayOrigin ?? REMOTE_CONTROL_RELAY_ORIGIN; - const deviceId = createKimiDeviceId(options.homeDir); - const deviceName = hostname(); - const url = buildRemoteControlUrl(deviceId, undefined, relayOrigin); - const lock = await acquireRemoteControlLock(options.homeDir, { - localOrigin: options.localOrigin.replace(/\/+$/, ''), - deviceId, - url, - }); - const client = new RemoteControlClient({ - ...options, - relayOrigin, - deviceId, - refreshToken: token.refreshToken, - }); - try { - await client.start(); - } catch (error) { - await lock.release(); - throw error; - } - return { - deviceId, - deviceName, - url, - close: async () => { - await client.close(); - await lock.release(); - }, - }; -} - -class RemoteControlClient { - private readonly localOrigin: string; - private readonly localServerToken: string; - private readonly relayOrigin: string; - private readonly deviceId: string; - private readonly refreshToken: string; - private readonly stderr: Pick; - private readonly onStatus: (status: RemoteControlStatus) => void; - private readonly streams = new Map(); - private readonly pendingHttpRequests = new Map(); - private management: WebSocket | undefined; - private reconnectAbort: AbortController | undefined; - private http: WebSocket | undefined; - private pendingHttpBytes = 0; - private reconnectAttempt = 0; - private reconnectImmediately = false; - private stopped = false; - private connected = false; - private relayOnline = false; - private runPromise: Promise | undefined; - private initialResolve: (() => void) | undefined; - private initialReject: ((error: unknown) => void) | undefined; - - constructor( - options: RemoteControlOptions & { - readonly relayOrigin: string; - readonly deviceId: string; - readonly refreshToken: string; - }, - ) { - this.localOrigin = options.localOrigin.replace(/\/+$/, ''); - this.localServerToken = options.localServerToken; - this.relayOrigin = options.relayOrigin; - this.deviceId = options.deviceId; - this.refreshToken = options.refreshToken; - this.stderr = options.stderr ?? process.stderr; - this.onStatus = options.onStatus ?? (() => {}); - } - - async start(): Promise { - const initial = new Promise((resolve, reject) => { - this.initialResolve = resolve; - this.initialReject = reject; - }); - this.runPromise = this.run(); - await initial; - } - - async close(): Promise { - if (this.stopped) { - await this.runPromise; - return; - } - this.stopped = true; - if (!this.connected) this.rejectInitial(new Error('Remote Control closed before ready.')); - if (this.management?.readyState === WebSocket.OPEN) { - this.management.send( - JSON.stringify({ type: 'disconnect', payload: { reason: 'local_server_stopped' } }), - ); - } - this.closeCycle(); - this.reconnectAbort?.abort(); - await this.runPromise; - } - - private async run(): Promise { - while (!this.stopped) { - try { - await this.serveCycle(); - } catch (error) { - if (error instanceof RegistrationError) { - if (!this.connected) this.rejectInitial(error); - else this.stderr.write(`${error.message}\n`); - this.stopped = true; - return; - } - if (!this.stopped && !this.reconnectImmediately) { - this.stderr.write(`Remote Control disconnected: ${errorMessage(error)}\n`); - } - } finally { - this.closeCycle(); - } - if (this.stopped) { - if (!this.connected) this.rejectInitial(new Error('Remote Control stopped before ready.')); - return; - } - if (this.reconnectImmediately) { - this.reconnectImmediately = false; - continue; - } - this.reconnectAttempt += 1; - const delay = Math.min( - MAX_RECONNECT_DELAY_MS, - 1000 * 2 ** Math.min(this.reconnectAttempt - 1, 5), - ); - await this.waitForReconnect(delay); - } - } - - private async serveCycle(): Promise { - const management = await this.connectRelay('/v1/remote/create'); - this.management = management; - management.send( - JSON.stringify({ - type: 'register', - payload: { - device_id: this.deviceId, - alias: hostname(), - platform: platform(), - client_version: `kimi-code/${getVersion()}`, - local_base_url: this.localOrigin, - }, - }), - ); - const registration = await waitForRelayMessage(management, REGISTER_TIMEOUT_MS); - if (registration.type === 'register_nak') { - const code = stringField(registration.payload, 'error_code') ?? 'REGISTRATION_REJECTED'; - const message = stringField(registration.payload, 'error_message') ?? 'registration rejected'; - throw new RegistrationError(`Remote Control registration failed (${code}): ${message}`); - } - if (registration.type !== 'register_ack') { - throw new Error(`Remote Control expected register_ack, received ${registration.type}`); - } - - const managementEnd = waitForSocketEnd(management); - const http = await this.connectRelay( - `/v1/remote/http?device_id=${encodeURIComponent(this.deviceId)}`, - ); - this.http = http; - if (management.readyState !== WebSocket.OPEN) { - throw new Error('management connection closed'); - } - management.on('message', (data) => this.handleManagementMessage(data)); - http.on('message', (data) => this.handleHttpMessage(data)); - this.reconnectAttempt = 0; - this.relayOnline = true; - this.onStatus('relay_connected'); - - if (!this.connected) { - this.connected = true; - this.initialResolve?.(); - this.initialResolve = undefined; - this.initialReject = undefined; - } - - await Promise.race([managementEnd, waitForSocketEnd(http)]); - if (!this.stopped) throw new Error('relay connection closed'); - } - - private connectRelay(path: string): Promise { - return connectWebSocket(relayWebSocketUrl(this.relayOrigin, path), this.refreshToken); - } - - private rejectInitial(error: Error): void { - this.initialReject?.(error); - this.initialReject = undefined; - this.initialResolve = undefined; - } - - private handleManagementMessage(data: RawData): void { - let message: RelayMessage; - try { - message = parseRelayMessage(data); - } catch (error) { - this.stderr.write(`Remote Control message error: ${errorMessage(error)}\n`); - return; - } - if (message.type === 'open_ws') { - void this.openStream(message.payload ?? {}); - return; - } - if (message.type === 'close_ws') { - const streamId = stringField(message.payload, 'stream_id'); - if (streamId !== undefined) this.closeStream(streamId); - return; - } - if (message.type === 'disconnect') { - const reason = stringField(message.payload, 'reason'); - if (reason === 'user_requested') this.stopped = true; - if (reason === 'server_shutting_down') this.reconnectImmediately = true; - this.closeCycle(); - } - } - - private handleHttpMessage(data: RawData): void { - const text = rawDataText(data).trim(); - if (text.length === 0) return; - let requestId: string | undefined; - try { - const parsed = JSON.parse(text) as Record; - if (parsed['type'] !== 'request') return; - requestId = typeof parsed['request_id'] === 'string' ? parsed['request_id'] : undefined; - if ( - requestId === undefined || - typeof parsed['body_base64'] !== 'string' || - typeof parsed['is_last'] !== 'boolean' - ) { - throw new SyntaxError('invalid HTTP tunnel request message'); - } - const chunk = decodeBase64(parsed['body_base64']); - const pending = this.pendingHttpRequests.get(requestId) ?? { chunks: [], size: 0 }; - if (this.pendingHttpBytes + chunk.length > MAX_HTTP_REQUEST_BYTES) { - throw new SyntaxError('HTTP tunnel request exceeds 10 MiB'); - } - pending.chunks.push(chunk); - pending.size += chunk.length; - this.pendingHttpBytes += chunk.length; - this.pendingHttpRequests.set(requestId, pending); - if (!parsed['is_last']) return; - const rawRequest = Buffer.concat(pending.chunks, pending.size); - this.clearPendingHttpRequest(requestId); - void this.forwardHttpRequest(requestId, rawRequest); - } catch (error) { - if (requestId !== undefined) { - this.clearPendingHttpRequest(requestId); - this.sendHttpResponse(requestId, buildErrorResponse(400)); - } - this.stderr.write(`Remote Control HTTP message error: ${errorMessage(error)}\n`); - } - } - - private async forwardHttpRequest(requestId: string, rawRequest: Buffer): Promise { - try { - const parsed = parseRawHttpRequest(rawRequest); - const response = await requestLocalHttp( - this.localOrigin, - parsed, - this.localServerToken, - this.publicPrefix(), - ); - this.sendHttpResponse(requestId, response); - } catch (error) { - const status = error instanceof SyntaxError ? 400 : 502; - this.sendHttpResponse(requestId, buildErrorResponse(status)); - this.stderr.write(`Remote Control HTTP forwarding failed: ${errorMessage(error)}\n`); - } - } - - private sendHttpResponse(requestId: string, response: Buffer): void { - if (this.http?.readyState !== WebSocket.OPEN) return; - this.http.send( - JSON.stringify({ - request_id: requestId, - type: 'response', - is_last: true, - body_base64: response.toString('base64'), - }), - ); - } - - private async openStream(payload: Record): Promise { - const streamId = stringField(payload, 'stream_id'); - const path = stringField(payload, 'path'); - if (streamId === undefined || path === undefined || !path.startsWith('/') || path.startsWith('//')) { - if (streamId !== undefined) { - this.sendOpenStreamResult(streamId, false, 'LOCAL_WS_FAILED', 'invalid local WebSocket path'); - } - return; - } - - let local: WebSocket | undefined; - let tunnel: WebSocket | undefined; - const earlyLocalFrames: [RawData, boolean][] = []; - try { - local = await connectWebSocket( - localWebSocketUrl(this.localOrigin, path), - this.localServerToken, - relayHeaders(payload['headers']), - earlyLocalFrames, - ); - tunnel = await this.connectRelay(`/v1/remote/stream/${encodeURIComponent(streamId)}`); - if (this.stopped || this.management?.readyState !== WebSocket.OPEN) { - throw new Error('management connection closed'); - } - this.streams.set(streamId, { local, tunnel }); - this.onStatus('device_connected'); - bridgeSockets( - local, - tunnel, - () => { - if (this.streams.get(streamId)?.local === local) { - this.streams.delete(streamId); - this.onStatus('device_disconnected'); - } - }, - earlyLocalFrames, - ); - this.sendOpenStreamResult(streamId, true); - } catch (error) { - local?.close(); - tunnel?.close(); - this.sendOpenStreamResult( - streamId, - false, - local === undefined ? 'LOCAL_WS_FAILED' : 'TUNNEL_STREAM_FAILED', - errorMessage(error), - ); - } - } - - private sendOpenStreamResult( - streamId: string, - success: boolean, - errorCode?: string, - error?: string, - ): void { - if (this.management?.readyState !== WebSocket.OPEN) return; - this.management.send( - JSON.stringify({ - type: 'open_ws_result', - payload: { - stream_id: streamId, - success, - error_code: errorCode, - error_message: error, - }, - }), - ); - } - - private closeStream(streamId: string): void { - const stream = this.streams.get(streamId); - if (stream === undefined) return; - this.streams.delete(streamId); - this.onStatus('device_disconnected'); - stream.local.close(); - stream.tunnel.close(); - } - - private clearPendingHttpRequest(requestId: string): void { - const pending = this.pendingHttpRequests.get(requestId); - if (pending === undefined) return; - this.pendingHttpRequests.delete(requestId); - this.pendingHttpBytes -= pending.size; - } - - private closeCycle(): void { - for (const streamId of this.streams.keys()) this.closeStream(streamId); - this.pendingHttpRequests.clear(); - this.pendingHttpBytes = 0; - this.management?.close(); - this.http?.close(); - if (this.relayOnline) { - this.relayOnline = false; - this.onStatus('relay_disconnected'); - } - this.management = undefined; - this.http = undefined; - } - - private publicPrefix(): string { - const relayPath = new URL(this.relayOrigin).pathname.replace(/\/+$/, ''); - return `${relayPath}/devices/${encodeURIComponent(this.deviceId)}`; - } - - private async waitForReconnect(ms: number): Promise { - if (this.stopped) return; - const controller = new AbortController(); - this.reconnectAbort = controller; - try { - await sleep(ms, undefined, { signal: controller.signal }); - } catch (error) { - if (!(error instanceof Error) || error.name !== 'AbortError') throw error; - } finally { - if (this.reconnectAbort === controller) this.reconnectAbort = undefined; - } - } -} - -async function connectWebSocket( - url: string, - token: string, - headers: Record = {}, - earlyFrames?: [RawData, boolean][], -): Promise { - const protocol = `kimi-code.bearer.${token}`; - if (isWebSocketProtocolToken(protocol)) { - try { - return await connectWebSocketAttempt(url, [protocol], headers, earlyFrames); - } catch {} - } - return connectWebSocketAttempt( - url, - undefined, - { - ...headers, - Authorization: `Bearer ${token}`, - }, - earlyFrames, - ); -} - -function connectWebSocketAttempt( - url: string, - protocols: string[] | undefined, - headers: Record, - earlyFrames?: [RawData, boolean][], -): Promise { - return new Promise((resolve, reject) => { - const socket = new WebSocket(url, protocols, { - headers, - handshakeTimeout: REGISTER_TIMEOUT_MS, - }); - if (earlyFrames !== undefined) { - socket.on('message', (data, isBinary) => { - earlyFrames.push([data, isBinary]); - }); - } - let settled = false; - const cleanup = (): void => { - socket.off('open', onOpen); - socket.off('error', onError); - socket.off('close', onClose); - }; - const finish = (error?: Error): void => { - if (settled) return; - settled = true; - cleanup(); - if (error === undefined) resolve(socket); - else reject(error); - }; - const onOpen = (): void => finish(); - const onError = (error: Error): void => finish(error); - const onClose = (code: number, reason: Buffer): void => { - finish(new Error(`WebSocket closed during handshake (${code} ${reason.toString()})`)); - }; - socket.once('open', onOpen); - socket.once('error', onError); - socket.once('close', onClose); - }); -} - -function isWebSocketProtocolToken(value: string): boolean { - return /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(value); -} - -function waitForRelayMessage(socket: WebSocket, timeoutMs: number): Promise { - return new Promise((resolve, reject) => { - const timer = setTimeout(() => finish(new Error('Remote Control registration timed out')), timeoutMs); - const onMessage = (data: RawData): void => { - try { - finish(undefined, parseRelayMessage(data)); - } catch (error) { - finish(error); - } - }; - const onClose = (code: number, reason: Buffer): void => { - finish(new Error(`Remote Control registration closed (${code} ${reason.toString()})`)); - }; - const onError = (error: Error): void => finish(error); - const finish = (error?: unknown, message?: RelayMessage): void => { - clearTimeout(timer); - socket.off('message', onMessage); - socket.off('close', onClose); - socket.off('error', onError); - if (error !== undefined) reject(error); - else resolve(message!); - }; - socket.once('message', onMessage); - socket.once('close', onClose); - socket.once('error', onError); - }); -} - -function waitForSocketEnd(socket: WebSocket): Promise { - return new Promise((resolve) => { - socket.once('close', () => resolve()); - socket.once('error', () => resolve()); - }); -} - -function parseRelayMessage(data: RawData): RelayMessage { - const parsed = JSON.parse(rawDataText(data)) as Record; - if (typeof parsed['type'] !== 'string') throw new Error('relay message has no type'); - const payload = isRecord(parsed['payload']) ? parsed['payload'] : undefined; - return { type: parsed['type'], payload }; -} - -function requestLocalHttp( - localOrigin: string, - parsed: ParsedRawHttpRequest, - serverToken: string, - publicPrefix: string, -): Promise { - const origin = new URL(localOrigin); - return new Promise((resolve, reject) => { - const request = httpRequest( - { - protocol: origin.protocol, - hostname: origin.hostname, - port: origin.port, - method: parsed.method, - path: parsed.path, - headers: [ - ...filterForwardRequestHeaders(parsed.headers, serverToken), - 'Host', - origin.host, - ], - timeout: HTTP_REQUEST_TIMEOUT_MS, - }, - (response) => { - const chunks: Buffer[] = []; - response.on('data', (chunk: Buffer | string) => chunks.push(Buffer.from(chunk))); - response.once('error', reject); - response.once('end', () => { - const contentType = response.headers['content-type'] ?? ''; - const receivedBody = Buffer.concat(chunks); - const body = - response.headers['content-encoding'] === undefined - ? rewriteRemoteControlResponse(contentType, receivedBody, publicPrefix) - : receivedBody; - const rewritten = body !== receivedBody; - const headers = filterResponseHeaders(response.rawHeaders, rewritten); - if (rewritten) headers.push('Cache-Control', 'no-cache'); - headers.push('Content-Length', String(body.length)); - const statusCode = response.statusCode ?? 502; - const statusMessage = response.statusMessage ?? 'Bad Gateway'; - resolve( - Buffer.concat([ - Buffer.from(`HTTP/1.1 ${statusCode} ${statusMessage}\r\n${headerLines(headers)}\r\n\r\n`), - body, - ]), - ); - }); - }, - ); - request.once('timeout', () => request.destroy(new Error('local HTTP request timed out'))); - request.once('error', reject); - request.end(parsed.body); - }); -} - -function filterResponseHeaders(rawHeaders: readonly string[], blockCacheControl = false): string[] { - const connectionHeaders = new Set(); - for (let index = 0; index < rawHeaders.length; index += 2) { - if (rawHeaders[index]!.toLowerCase() === 'connection') { - for (const token of rawHeaders[index + 1]!.split(',')) { - connectionHeaders.add(token.trim().toLowerCase()); - } - } - } - const result: string[] = []; - for (let index = 0; index < rawHeaders.length; index += 2) { - const name = rawHeaders[index]!; - const lower = name.toLowerCase(); - if (BLOCKED_RESPONSE_HEADERS.has(lower) || connectionHeaders.has(lower)) { - continue; - } - if (blockCacheControl && lower === 'cache-control') continue; - result.push(name, rawHeaders[index + 1]!); - } - return result; -} - -function relayHeaders(value: unknown): Record { - if (!isRecord(value)) return {}; - const entries: [string, string][] = []; - for (const [name, raw] of Object.entries(value)) { - if (typeof raw !== 'string') continue; - const lower = name.toLowerCase(); - if (BLOCKED_REQUEST_HEADERS.has(lower)) continue; - try { - validateHeaderName(name); - validateHeaderValue(name, raw); - entries.push([name, raw]); - } catch {} - } - return Object.fromEntries(entries); -} - -function bridgeSockets( - left: WebSocket, - right: WebSocket, - onClose: () => void, - earlyLeftFrames?: [RawData, boolean][], -): void { - let closed = false; - const closeBoth = (code = 1000, reason = Buffer.alloc(0)): void => { - if (closed) return; - closed = true; - onClose(); - const safeCode = isValidCloseCode(code) ? code : 1000; - if (left.readyState === WebSocket.OPEN) left.close(safeCode, reason); - if (right.readyState === WebSocket.OPEN) right.close(safeCode, reason); - }; - if (earlyLeftFrames !== undefined) { - left.removeAllListeners('message'); - for (const [data, isBinary] of earlyLeftFrames) { - if (right.readyState === WebSocket.OPEN) right.send(data, { binary: isBinary }); - } - } - left.on('message', (data, isBinary) => { - if (right.readyState === WebSocket.OPEN) right.send(data, { binary: isBinary }); - }); - right.on('message', (data, isBinary) => { - if (left.readyState === WebSocket.OPEN) left.send(data, { binary: isBinary }); - }); - left.once('close', closeBoth); - right.once('close', closeBoth); - left.once('error', () => closeBoth(1011)); - right.once('error', () => closeBoth(1011)); -} - -function isValidCloseCode(code: number): boolean { - return ( - code === 1000 || - code === 1001 || - code === 1002 || - code === 1003 || - (code >= 1007 && code <= 1014) || - (code >= 3000 && code <= 4999) - ); -} - -function relayWebSocketUrl(origin: string, path: string): string { - const url = new URL(origin); - url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'; - const relayPath = url.pathname.replace(/\/+$/, ''); - const [pathname, query] = path.split('?', 2); - url.pathname = `${relayPath}${pathname}`; - url.search = query === undefined ? '' : query; - url.hash = ''; - return url.toString(); -} - -function localWebSocketUrl(origin: string, path: string): string { - const url = new URL(origin); - url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:'; - url.pathname = path.split('?', 1)[0]!; - const query = path.includes('?') ? path.slice(path.indexOf('?') + 1) : ''; - url.search = query; - url.hash = ''; - return url.toString(); -} - -function headerLines(headers: readonly string[]): string { - let result = ''; - for (let index = 0; index < headers.length; index += 2) { - result += `${headers[index]}: ${headers[index + 1]}\r\n`; - } - return result.replace(/\r\n$/, ''); -} - -function buildErrorResponse(status: number): Buffer { - const reason = status === 400 ? 'Bad Request' : 'Bad Gateway'; - return Buffer.from(`HTTP/1.1 ${status} ${reason}\r\nContent-Length: 0\r\n\r\n`); -} - -function stringField( - value: Record | undefined, - key: string, -): string | undefined { - const field = value?.[key]; - return typeof field === 'string' ? field : undefined; -} - -function decodeBase64(value: string): Buffer { - if (!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value)) { - throw new SyntaxError('invalid HTTP tunnel request base64'); - } - return Buffer.from(value, 'base64'); -} - -function rawDataText(data: RawData): string { - if (Array.isArray(data)) return Buffer.concat(data).toString('utf8'); - return Buffer.from(data as ArrayBuffer).toString('utf8'); -} - -function isRecord(value: unknown): value is Record { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function errorMessage(error: unknown): string { - return error instanceof Error ? error.message : String(error); -} diff --git a/apps/kimi-code/src/cli/sub/web/run.ts b/apps/kimi-code/src/cli/sub/web/run.ts index 261623444..3600cfe7b 100644 --- a/apps/kimi-code/src/cli/sub/web/run.ts +++ b/apps/kimi-code/src/cli/sub/web/run.ts @@ -14,14 +14,13 @@ import { join } from 'node:path'; import { createServerLogger, startServer, type ServerLogger } from '@moonshot-ai/kap-server'; import { shutdownTelemetry, track } from '@moonshot-ai/kimi-telemetry'; import chalk from 'chalk'; -import { type Command, Option } from 'commander'; +import { type Command } from 'commander'; import { CLI_SHUTDOWN_TIMEOUT_MS, WEB_USER_AGENT_SUFFIX } from '#/constant/app'; import { getNativeWebAssetsDir } from '#/native/web-assets'; import { darkColors } from '#/tui/theme/colors'; import { openUrl as defaultOpenUrl } from '#/utils/open-url'; import { getDataDir } from '#/utils/paths'; -import { generateRemoteControlQr } from '#/utils/remote-control-qr'; import { initializeServerTelemetry } from '../../telemetry'; import { @@ -36,16 +35,6 @@ import { splitTokenFragment, } from './access-urls'; import { type NetworkAddress } from './networks'; -import { - formatRemoteControlOutput, - formatRemoteControlStatus, - isRemoteControlEnabled, - REMOTE_CONTROL_FLAG_ENV, - startRemoteControl, - type RemoteControlHandle, - type RemoteControlOptions, - type RemoteControlStatus, -} from './remote-control'; import { DEFAULT_FOREGROUND_LOG_LEVEL, DEFAULT_LAN_HOST, @@ -73,13 +62,11 @@ interface RoutedServer { export interface WebCliOptions extends ServerCliOptions { open?: boolean; - remoteControl?: boolean; } export interface StartForegroundHooks { /** Fires once the server is listening, before the foreground runner blocks. */ - onReady?: (origin: string) => void | Promise; - onShutdown?: (reason: string) => void | Promise; + onReady?: (origin: string) => void; } export interface WebCommandDeps { @@ -88,7 +75,6 @@ export interface WebCommandDeps { options: ParsedServerOptions, hooks?: StartForegroundHooks, ) => Promise; - startRemoteControl?: (options: RemoteControlOptions) => Promise; openUrl(url: string): void; /** * Best-effort read of the server's persistent bearer token. When it returns @@ -119,12 +105,8 @@ export function buildWebUrl(origin: string, token: string): string { } /** Build the `web` command, mounting the runner action on `cmd` itself. */ -export function buildWebCommand( - cmd: Command, - opts: { forceRemoteControl?: boolean } = {}, -): Command { - const forceRemoteControl = opts.forceRemoteControl === true; - const withServerOptions = cmd +export function buildWebCommand(cmd: Command): Command { + return cmd .option( '--port ', `Bind port (default ${DEFAULT_SERVER_PORT})`, @@ -148,6 +130,11 @@ export function buildWebCommand( 'On a non-loopback bind, keep POST /api/v1/shutdown enabled (default: route is disabled → 404).', false, ) + .option( + '--allow-remote-terminals', + 'On a non-loopback bind, keep the PTY /api/v1/terminals/* routes enabled (default: disabled → 404). Remote shell is high risk.', + false, + ) .option( '--dangerous-bypass-auth', 'Disable bearer-token auth on every REST and WebSocket route, and advertise it via /api/v1/meta so the web UI connects without a token. Only use on a trusted network or behind your own authenticating proxy.', @@ -162,27 +149,10 @@ export function buildWebCommand( 'Mount /api/v1/debug/* routes for test introspection. OFF by default; production callers leave this unset.', false, ) - .option( - '--web-title ', - 'Set a custom browser tab title for this web UI instance (default: "<workspace dir> | Kimi Code").', - ); - if (!forceRemoteControl) { - withServerOptions.addOption( - new Option( - '--rc, --remote-control', - 'Expose the web UI through Kimi Remote Control (experimental).', - ) - .default(false) - .hideHelp(!isRemoteControlEnabled()), - ); - } - return withServerOptions .option('--no-open', 'Do not open the web UI in the default browser.', true) .action(async (opts: WebCliOptions) => { try { - await handleWebCommand( - forceRemoteControl ? { ...opts, remoteControl: true } : opts, - ); + await handleWebCommand(opts); } catch (error) { process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`); process.exit(1); @@ -195,21 +165,9 @@ export async function handleWebCommand( deps: WebCommandDeps = DEFAULT_WEB_COMMAND_DEPS, ): Promise<void> { const parsed = parseServerOptions(opts); - if (opts.remoteControl === true && !isRemoteControlEnabled()) { - throw new Error( - `--remote-control is experimental: set ${REMOTE_CONTROL_FLAG_ENV}=1 (or KIMI_CODE_EXPERIMENTAL_FLAG=1) to enable it.`, - ); - } - if (opts.remoteControl === true && parsed.dangerousBypassAuth) { - throw new Error('--remote-control cannot be combined with --dangerous-bypass-auth.'); - } - if (opts.remoteControl === true && !isLoopbackHost(parsed.host)) { - throw new Error('--remote-control requires a loopback host.'); - } const run = deps.startServerForeground ?? startServerForeground; - let remoteControl: RemoteControlHandle | undefined; await run(parsed, { - onReady: async (origin) => { + onReady: (origin) => { // Resolve the persistent token only once the server is up: a fresh // server writes `server.token` on first boot, so reading it beforehand // would miss first-time starts and the browser would hit the auth gate. @@ -218,38 +176,6 @@ export async function handleWebCommand( // token line when unavailable. When auth is bypassed, the token is // meaningless and is intentionally NOT shown or carried in the URL. const token = parsed.dangerousBypassAuth ? undefined : deps.resolveToken?.(); - if (opts.remoteControl === true) { - if (token === undefined) throw new Error('Unable to read the local server token.'); - const dataDir = getDataDir(); - let outputReady = false; - const pendingStatuses: string[] = []; - const onStatus = (status: RemoteControlStatus): void => { - const line = formatRemoteControlStatus(status); - if (outputReady) deps.stdout.write(line); - else pendingStatuses.push(line); - }; - remoteControl = await (deps.startRemoteControl ?? startRemoteControl)({ - homeDir: dataDir, - localOrigin: origin, - localServerToken: token, - stderr: deps.stderr, - onStatus, - }); - const qrCode = await generateRemoteControlQr(remoteControl.url, dataDir); - deps.stdout.write( - formatRemoteControlOutput({ - url: remoteControl.url, - localOrigin: origin, - deviceName: remoteControl.deviceName, - qrCode: qrCode.terminal, - pngPath: qrCode.pngPath, - }), - ); - outputReady = true; - for (const line of pendingStatuses) deps.stdout.write(line); - if (opts.open === true) deps.openUrl(remoteControl.url); - return; - } deps.stdout.write( parsed.logLevel === DEFAULT_FOREGROUND_LOG_LEVEL ? formatReadyBanner(origin, parsed.host, { @@ -263,9 +189,6 @@ export async function handleWebCommand( deps.openUrl(token !== undefined ? buildWebUrl(origin, token) : origin); } }, - onShutdown: async () => { - await remoteControl?.close(); - }, }); } @@ -303,7 +226,7 @@ export async function startServerForeground( options: ParsedServerOptions, hooks: StartForegroundHooks = {}, ): Promise<never> { - return runServerInProcess(options, hooks); + return runServerInProcess(options, hooks.onReady); } /** @@ -312,7 +235,7 @@ export async function startServerForeground( */ async function runServerInProcess( options: ParsedServerOptions, - hooks: StartForegroundHooks, + onReady?: (origin: string) => void, ): Promise<never> { const version = getVersion(); // Registers the telemetry provider for `track` / `shutdownTelemetry`; the @@ -326,14 +249,6 @@ async function runServerInProcess( if (stopping) return; stopping = true; running?.logger.info({ reason }, 'server shutting down'); - try { - await hooks.onShutdown?.(reason); - } catch (error) { - running?.logger.error( - { err: error instanceof Error ? error : new Error(String(error)) }, - 'foreground shutdown hook error', - ); - } try { await running?.close(); await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS }); @@ -377,9 +292,9 @@ async function runServerInProcess( debugEndpoints: options.debugEndpoints, insecureNoTls: options.insecureNoTls, allowRemoteShutdown: options.allowRemoteShutdown, + allowRemoteTerminals: options.allowRemoteTerminals, allowedHosts: options.allowedHosts, disableAuth: options.dangerousBypassAuth, - webTitle: options.webTitle, // Attach the engine's cloud telemetry appender (still gated by the config // `telemetry` toggle). Complements the v1 client registered above, which // only covers host-level events. @@ -404,17 +319,7 @@ async function runServerInProcess( running.logger.info({ address: running.address }, 'server ready'); - try { - await hooks.onReady?.(running.address); - } catch (error) { - try { - await hooks.onShutdown?.('startup_failed'); - } finally { - await running.close(); - await shutdownTelemetry({ timeoutMs: CLI_SHUTDOWN_TIMEOUT_MS }); - } - throw error; - } + onReady?.(running.address); return new Promise<never>(() => { // Keeps the event loop alive; the process ends via shutdown()/process.exit. diff --git a/apps/kimi-code/src/cli/sub/web/shared.ts b/apps/kimi-code/src/cli/sub/web/shared.ts index 91fede6c0..79dfff7d4 100644 --- a/apps/kimi-code/src/cli/sub/web/shared.ts +++ b/apps/kimi-code/src/cli/sub/web/shared.ts @@ -40,12 +40,12 @@ export interface ParsedServerOptions { insecureNoTls: boolean; /** Allow `POST /api/v1/shutdown` on a non-loopback bind. */ allowRemoteShutdown: boolean; + /** Allow PTY `/api/v1/terminals/*` routes on a non-loopback bind. */ + allowRemoteTerminals: boolean; /** Disable bearer-token auth on every route (`--dangerous-bypass-auth`). */ dangerousBypassAuth: boolean; /** Extra `Host` header values to allow through the DNS-rebinding check. */ allowedHosts: readonly string[]; - /** Custom browser tab title for this web UI instance (`--web-title`). */ - webTitle?: string; } export interface ServerCliOptions { @@ -57,12 +57,12 @@ export interface ServerCliOptions { insecureNoTls?: boolean; /** Allow remote shutdown on a non-loopback bind (`--allow-remote-shutdown`). */ allowRemoteShutdown?: boolean; + /** Allow remote terminals on a non-loopback bind (`--allow-remote-terminals`). */ + allowRemoteTerminals?: boolean; /** Disable bearer-token auth on every route (`--dangerous-bypass-auth`). */ dangerousBypassAuth?: boolean; /** Extra `Host` header values to allow (`--allowed-host`). */ allowedHost?: string[]; - /** Custom browser tab title for this web UI instance (`--web-title`). */ - webTitle?: string; } export function parseServerOptions(opts: ServerCliOptions): ParsedServerOptions { @@ -73,9 +73,9 @@ export function parseServerOptions(opts: ServerCliOptions): ParsedServerOptions debugEndpoints: opts.debugEndpoints === true, insecureNoTls: opts.insecureNoTls !== false, allowRemoteShutdown: opts.allowRemoteShutdown === true, + allowRemoteTerminals: opts.allowRemoteTerminals === true, dangerousBypassAuth: opts.dangerousBypassAuth === true, allowedHosts: parseAllowedHostArgs(opts.allowedHost), - webTitle: opts.webTitle, }; } diff --git a/apps/kimi-code/src/cli/telemetry.ts b/apps/kimi-code/src/cli/telemetry.ts index 3c3b63d8a..fefec09e3 100644 --- a/apps/kimi-code/src/cli/telemetry.ts +++ b/apps/kimi-code/src/cli/telemetry.ts @@ -17,7 +17,6 @@ import { } from '@moonshot-ai/kimi-telemetry'; import { CLI_USER_AGENT_PRODUCT, WEB_UI_MODE } from '#/constant/app'; -import { currentKimiProfile } from '#/utils/region'; import { createKimiCodeHostIdentity } from './version'; @@ -58,7 +57,6 @@ export function initializeCliTelemetry(options: InitializeCliTelemetryOptions): uiMode: options.uiMode, model: options.model ?? options.config.defaultModel, sessionId: options.sessionId, - endpoint: () => currentKimiProfile().telemetryEndpoint, getAccessToken: async () => (await options.harness.auth.getCachedAccessToken(KIMI_CODE_PROVIDER_NAME)) ?? null, }); @@ -107,7 +105,6 @@ export function initializeServerTelemetry( version: options.version, uiMode: WEB_UI_MODE, model: config.defaultModel, - endpoint: () => currentKimiProfile().telemetryEndpoint, getAccessToken: async () => (await auth.getCachedAccessToken(KIMI_CODE_PROVIDER_NAME)) ?? null, }); diff --git a/apps/kimi-code/src/cli/update/cdn.ts b/apps/kimi-code/src/cli/update/cdn.ts index 6e423cdb0..4990568c9 100644 --- a/apps/kimi-code/src/cli/update/cdn.ts +++ b/apps/kimi-code/src/cli/update/cdn.ts @@ -1,7 +1,7 @@ import { valid } from 'semver'; import { z } from 'zod'; -import { kimiCodeCdnLatestJsonUrl, kimiCodeCdnLatestUrl } from '#/constant/app'; +import { KIMI_CODE_CDN_LATEST_JSON_URL, KIMI_CODE_CDN_LATEST_URL } from '#/constant/app'; import type { UpdateManifest } from './types'; @@ -58,7 +58,7 @@ async function fetchWithTimeout(fetchImpl: typeof fetch, input: string): Promise export async function fetchLatestVersionFromCdn( fetchImpl: typeof fetch = fetch, ): Promise<string> { - const response = await fetchWithTimeout(fetchImpl, kimiCodeCdnLatestUrl()); + const response = await fetchWithTimeout(fetchImpl, KIMI_CODE_CDN_LATEST_URL); if (!response.ok) { throw new Error(`CDN /latest returned HTTP ${response.status}`); } @@ -70,7 +70,7 @@ export async function fetchLatestVersionFromCdn( } async function fetchUpdateManifestFromCdn(fetchImpl: typeof fetch): Promise<UpdateManifest> { - const response = await fetchWithTimeout(fetchImpl, kimiCodeCdnLatestJsonUrl()); + const response = await fetchWithTimeout(fetchImpl, KIMI_CODE_CDN_LATEST_JSON_URL); if (!response.ok) { throw new Error(`CDN /latest.json returned HTTP ${response.status}`); } diff --git a/apps/kimi-code/src/cli/update/install-lock.ts b/apps/kimi-code/src/cli/update/install-lock.ts index f42042ac3..0b6f3834c 100644 --- a/apps/kimi-code/src/cli/update/install-lock.ts +++ b/apps/kimi-code/src/cli/update/install-lock.ts @@ -1,26 +1,10 @@ -import { mkdir, readFile, stat, unlink } from 'node:fs/promises'; +import { mkdir, open, readFile, unlink } from 'node:fs/promises'; import { dirname } from 'node:path'; import { getUpdateInstallLockFile } from '#/utils/paths'; -import { createFileIfAbsent } from '#/utils/persistence'; const UPDATE_INSTALL_LOCK_STALE_MS = 30 * 60 * 1000; -/** - * A takeover's critical section is a few syscalls (microseconds), so a - * takeover lock older than this is crash residue and may be swept freely. - */ -const TAKEOVER_LOCK_STALE_MS = 60_000; - -/** - * On filesystems without hard links the lock is published by an exclusive - * create + write (see createFileIfAbsent), which IS observable between create - * and write. A young unparseable lock is almost always that publish window, - * not corruption — only an unparseable lock older than this is swept as - * crash residue. - */ -const LOCK_PUBLISH_GRACE_MS = 60_000; - export interface UpdateInstallLockRequest { readonly version: string; readonly now?: Date; @@ -28,8 +12,6 @@ export interface UpdateInstallLockRequest { export interface UpdateInstallLockHandle { readonly filePath: string; - /** The exact contents this handle published — its ownership identity. */ - readonly content: string; release(): Promise<void>; } @@ -45,95 +27,42 @@ function isAlreadyExists(error: unknown): boolean { ); } -/** - * Liveness probe for the lock holder. Signal 0 delivers nothing; ESRCH means - * the process is gone, EPERM means it exists but may not be signalled — which - * still counts as alive. - */ -function isProcessAlive(pid: number): boolean { +async function isStaleLock(filePath: string, now: Date): Promise<boolean> { try { - process.kill(pid, 0); - return true; + const raw = await readFile(filePath, 'utf-8'); + const parsed = JSON.parse(raw) as unknown; + if (typeof parsed !== 'object' || parsed === null) return true; + const lock = parsed as { readonly startedAt?: unknown }; + if (typeof lock.startedAt !== 'string') return true; + const startedAt = Date.parse(lock.startedAt); + if (!Number.isFinite(startedAt)) return true; + return now.getTime() - startedAt > UPDATE_INSTALL_LOCK_STALE_MS; } catch (error) { - return (error as NodeJS.ErrnoException).code === 'EPERM'; + if (isNotFound(error)) return true; + if (error instanceof SyntaxError) return true; + return false; } } -interface LockInspection { - readonly content: string; - readonly mtimeMs: number; -} - -/** Read the lock file's content and mtime; null when it is gone/unreadable. */ -async function inspectLockFile(filePath: string): Promise<LockInspection | null> { - const content = await readFile(filePath, 'utf-8').catch(() => null); - if (content === null) return null; - const info = await stat(filePath).catch(() => null); - if (info === null) return null; - return { content, mtimeMs: info.mtimeMs }; -} - -/** - * Staleness check over the lock file's CONTENTS. Shapeless content counts as - * stale (crash residue). Unparseable content is also crash residue — but only - * once it is older than the publish grace: on filesystems without hard links - * a fallback publish is observable mid-write (see LOCK_PUBLISH_GRACE_MS), and - * sweeping that window would break exclusivity. A holder that is gone can - * never release its lock (a killed process skips its finally) nor make - * progress — stale at ANY age; the atomic publish guarantees the pid was - * written complete by a then-live process, so a dead pid means the holder - * died afterwards. Past the age threshold a LIVE holder still survives: a - * native download is idle-bounded but intentionally not duration-bounded, so - * a slow link legitimately exceeds it. (A pid reused by an unrelated process - * can pin the lock until that process exits — a delayed update, never a - * corrupt one.) - */ -function isStaleLock(inspection: LockInspection, now: Date): boolean { - let parsed: unknown; - try { - parsed = JSON.parse(inspection.content); - } catch { - return now.getTime() - inspection.mtimeMs > LOCK_PUBLISH_GRACE_MS; - } - if (typeof parsed !== 'object' || parsed === null) return true; - const lock = parsed as { readonly startedAt?: unknown; readonly pid?: unknown }; - if (typeof lock.startedAt !== 'string') return true; - const startedAt = Date.parse(lock.startedAt); - if (!Number.isFinite(startedAt)) return true; - if (typeof lock.pid === 'number' && !isProcessAlive(lock.pid)) return true; - if (now.getTime() - startedAt <= UPDATE_INSTALL_LOCK_STALE_MS) return false; - return typeof lock.pid !== 'number'; -} - async function createLockFile( filePath: string, request: UpdateInstallLockRequest, -): Promise<UpdateInstallLockHandle | null> { +): Promise<UpdateInstallLockHandle> { const now = request.now ?? new Date(); - const content = `${JSON.stringify({ - version: request.version, - pid: process.pid, - startedAt: now.toISOString(), - }, null, 2)}\n`; - // Publish atomically and only into a still-free path (EEXIST propagates to - // the caller's inspection flow). The lock file is never observable empty - // on filesystems with hard links; elsewhere the exclusive-create fallback - // leaves a brief publish window, which the inspection side covers with - // LOCK_PUBLISH_GRACE_MS. - await createFileIfAbsent(filePath, content); - // A racing stale-takeover may have removed our just-published lock and - // published its own; only the survivor may proceed. - const published = await readFile(filePath, 'utf-8').catch(() => null); - if (published !== content) return null; + const file = await open(filePath, 'wx', 0o600); + try { + await file.writeFile(`${JSON.stringify({ + version: request.version, + pid: process.pid, + startedAt: now.toISOString(), + }, null, 2)}\n`, 'utf-8'); + } finally { + await file.close(); + } return { filePath, - content, release: async (): Promise<void> => { - // Release only the lock instance we own: a stale takeover may have - // replaced the file since we published it. - const current = await readFile(filePath, 'utf-8').catch(() => null); - if (current !== content) return; await unlink(filePath).catch((error: unknown) => { if (!isNotFound(error)) throw error; }); @@ -152,103 +81,15 @@ export async function tryAcquireUpdateInstallLock( if (!isAlreadyExists(error)) throw error; } - // A lock file exists. Inspect it once to decide whether it is stale. - const inspected = await inspectLockFile(filePath); - if (inspected !== null && !isStaleLock(inspected, request.now ?? new Date())) { - return null; - } - if (inspected === null) { - // Vanished between create and read — retry the create once. - try { - return await createLockFile(filePath, request); - } catch (error) { - if (isAlreadyExists(error)) return null; - throw error; - } - } + if (!(await isStaleLock(filePath, request.now ?? new Date()))) return null; + await unlink(filePath).catch((error: unknown) => { + if (!isNotFound(error)) throw error; + }); - // Stale lock. A pathname-level delete can never be conditioned on the file - // still being the inspected instance, so delete+publish MUST NOT run - // concurrently: serialize takeovers through a secondary create-if-absent - // lock and re-validate staleness inside that section. - const takeoverPath = `${filePath}.takeover`; - if (!(await acquireTakeoverLock(takeoverPath))) return null; try { - const current = await inspectLockFile(filePath); - if (current !== null && !isStaleLock(current, request.now ?? new Date())) { - // A fresh lock appeared while we waited for the takeover section. - return null; - } - if (current !== null) { - await unlink(filePath).catch(() => {}); - } - try { - // A fast-path creator may still win the briefly-free path — its lock is - // legitimate (the path really was free), we simply lose. - return await createLockFile(filePath, request); - } catch (error) { - if (isAlreadyExists(error)) return null; - throw error; - } - } finally { - await unlink(takeoverPath).catch(() => {}); - } -} - -/** - * The takeover lock serializes stale-lock recovery. create-if-absent via the - * shared primitive (hard link, or an exclusive create where unsupported); an - * ancient holder is crash residue (a live section lasts microseconds) and is - * swept, then retried once. - */ -async function acquireTakeoverLock(takeoverPath: string): Promise<boolean> { - if (await publishTakeoverMarker(takeoverPath)) return true; - const info = await stat(takeoverPath).catch(() => null); - if (info !== null && Date.now() - info.mtimeMs <= TAKEOVER_LOCK_STALE_MS) return false; - await unlink(takeoverPath).catch(() => {}); - return publishTakeoverMarker(takeoverPath); -} - -/** Create-if-absent publish of a small lock marker file. */ -async function publishTakeoverMarker(target: string): Promise<boolean> { - // Unique marker content doubles as the ownership identity below. - const marker = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`; - try { - await createFileIfAbsent(target, marker); + return await createLockFile(filePath, request); } catch (error) { - if (isAlreadyExists(error)) return false; + if (isAlreadyExists(error)) return null; throw error; } - // The stale-marker sweep races this publish: it may unlink our fresh marker - // and publish its own. Verify ownership so only the survivor of that race - // proceeds. (A delete landing after this read is the irreducible residual - // of pathname-only locking — there is no conditional-delete syscall; its - // worst case is a duplicated download cycle, never a corrupt install, - // because swap claims guard the executable independently.) - const published = await readFile(target, 'utf-8').catch(() => null); - return published === marker; -} - -/** - * Return the version recorded in the held lock file, or undefined when the - * lock is gone or unreadable. Lets a downloader that failed to acquire the - * lock distinguish "another instance is staging the SAME version" (its - * outcome is ours — report success) from "a different version is in flight" - * (must not be reported as success to a foreground `kimi upgrade`). - */ -export async function readUpdateInstallLockVersion( - filePath: string = getUpdateInstallLockFile(), -): Promise<string | undefined> { - let raw: string; - try { - raw = await readFile(filePath, 'utf-8'); - } catch { - return undefined; - } - try { - const version: unknown = (JSON.parse(raw) as { version?: unknown }).version; - return typeof version === 'string' && version.length > 0 ? version : undefined; - } catch { - return undefined; - } } diff --git a/apps/kimi-code/src/cli/update/native-manifest.ts b/apps/kimi-code/src/cli/update/native-manifest.ts deleted file mode 100644 index 0b47fb393..000000000 --- a/apps/kimi-code/src/cli/update/native-manifest.ts +++ /dev/null @@ -1,101 +0,0 @@ -/** - * Per-release native artifact manifest (`/binaries/<version>/manifest.json`). - * - * Published alongside the release and consumed by the install scripts; the - * staged updater reuses the same file so checksums and file names have a - * single source of truth. Entries point at the bare platform binary - * (`kimi-code-<target>[.exe]`), not an archive. - */ - -import { valid } from 'semver'; -import { z } from 'zod'; - -import { kimiCodeCdnBinariesBase } from '#/constant/app'; - -const MANIFEST_FETCH_TIMEOUT_MS = 10_000; - -const PlatformEntrySchema = z.object({ - filename: z.string().min(1), - checksum: z.string().regex(/^[a-f0-9]{64}$/, { error: 'invalid sha256' }), -}); - -/** - * Deliberately NOT `.strict()` — unknown fields are ignored so future - * manifest additions never break shipped clients (same contract philosophy - * as the rollout manifest in `cdn.ts`). - */ -export const NativeReleaseManifestSchema = z.object({ - version: z.string().refine((value) => valid(value) !== null, { error: 'invalid semver' }), - platforms: z.record(z.string(), PlatformEntrySchema), -}); - -export type NativeReleaseManifest = z.infer<typeof NativeReleaseManifestSchema>; -export type NativePlatformEntry = z.infer<typeof PlatformEntrySchema>; - -export function nativeManifestUrl(version: string): string { - return `${kimiCodeCdnBinariesBase()}/${version}/manifest.json`; -} - -export function nativeBinaryUrl(version: string, filename: string): string { - return `${kimiCodeCdnBinariesBase()}/${version}/${filename}`; -} - -/** - * Fetch and parse the per-release manifest. **Throws** on any failure - * (network, non-2xx, malformed body, unknown version) — callers treat a - * throw as "staging failed" and record an install failure. - * - * `version` goes into the URL, so it must be a valid semver (it always is: - * upstream sources are the CDN `latest.json` / the `upgrade` command). - * `fetchImpl` is injectable for tests. - */ -export async function fetchNativeReleaseManifest( - version: string, - fetchImpl: typeof fetch = fetch, -): Promise<NativeReleaseManifest> { - if (valid(version) === null) { - throw new Error(`invalid semver for native manifest lookup: ${JSON.stringify(version)}`); - } - const controller = new AbortController(); - const timeout = setTimeout(() => { - controller.abort(); - }, MANIFEST_FETCH_TIMEOUT_MS); - // The timeout must stay armed until the BODY is fully consumed: a CDN or - // proxy can deliver headers within the limit and then stall mid-body, and - // resolving `fetch()` alone would clear the timer and hang the worker. - try { - const response = await fetchImpl(nativeManifestUrl(version), { signal: controller.signal }); - if (!response.ok) { - throw new Error(`native manifest for ${version} returned HTTP ${response.status}`); - } - const manifest = NativeReleaseManifestSchema.parse(JSON.parse(await response.text())); - // A stale or mispublished endpoint can answer with ANOTHER release's - // manifest: its checksums would then be applied to this version's binary - // and every download would fail verification. Reject the mismatch here. - if (manifest.version !== version) { - throw new Error(`manifest for ${version} served content for ${manifest.version}`); - } - return manifest; - } finally { - clearTimeout(timeout); - } -} - -/** - * Pick the entry for the running platform. The release pipeline keys - * platforms by `<node platform>-<node arch>` (win32-x64, darwin-arm64, …). - * **Throws** when the platform is missing — a silent skip would strand the - * update in a retry loop. - */ -export function selectPlatformEntry( - manifest: NativeReleaseManifest, - platform: NodeJS.Platform, - arch: string, -): NativePlatformEntry { - const target = `${platform}-${arch}`; - const entry = manifest.platforms[target]; - if (entry === undefined) { - throw new Error(`platform ${target} not found in native manifest for ${manifest.version}`); - } - return entry; -} diff --git a/apps/kimi-code/src/cli/update/native-stage.ts b/apps/kimi-code/src/cli/update/native-stage.ts deleted file mode 100644 index f85b86d7c..000000000 --- a/apps/kimi-code/src/cli/update/native-stage.ts +++ /dev/null @@ -1,486 +0,0 @@ -/** - * Native staged update: download + verify into `<exe dir>/.staging/`, - * without touching the running executable. The actual swap happens on the - * next startup (see `native-swap.ts`). - * - * The CDN serves the bare platform binary (e.g. `kimi-code-win32-x64.exe`), - * whose sha256 comes from the per-release manifest over HTTPS — a staged - * binary is byte-exact what the release pipeline produced. - */ - -import { createHash } from 'node:crypto'; -import { createReadStream } from 'node:fs'; -import { chmod, mkdir, open, readFile, readdir, rename, rm, rmdir, stat, unlink } from 'node:fs/promises'; -import { basename, join } from 'node:path'; - -import { valid } from 'semver'; -import { z } from 'zod'; - -import { KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME } from '#/constant/app'; -import { getNativeStagedStateFile, getNativeStagingDir } from '#/utils/paths'; -import { writeJsonFile } from '#/utils/persistence'; - -import { - fetchNativeReleaseManifest, - nativeBinaryUrl, - selectPlatformEntry, -} from './native-manifest'; - -const StagedNativeUpdateSchema = z - .object({ - version: z.string().min(1), - target: z.string().min(1), - /** Base name of the staged executable inside `.staging/`. */ - exeFileName: z - .string() - .min(1) - .refine((value) => basename(value) === value, { error: 'must be a plain file name' }), - /** sha256 of the staged binary (the manifest's checksum). */ - sha256: z.string().regex(/^[a-f0-9]{64}$/), - exeSize: z.number().int().min(1), - stagedAt: z.string().min(1), - /** - * True when the stage was produced by an explicit user-initiated - * `kimi upgrade` (vs the passive background downloader): manual stages - * still apply when automatic updates are opted out via env. - */ - manual: z.boolean().optional(), - }) - .strict(); - -export type StagedNativeUpdate = z.infer<typeof StagedNativeUpdateSchema>; - -export function stagedExeFileName(version: string, platform: NodeJS.Platform): string { - return platform === 'win32' ? `kimi-${version}.exe` : `kimi-${version}`; -} - -/** Uniquifies the published staged-exe name across concurrent in-process workers. */ -let stageTempCounter = 0; - -/** - * The name a stage is published under: the base name plus a unique per-worker - * infix (`kimi-<version>.<pid>.<epoch-ms>.<n>[.exe]`). Once published, a - * staged executable is NEVER replaced — a same-version re-download publishes - * a new generation and the atomic metadata write retargets the pointer — so - * the pathname a swap validates at claim time is stable: no concurrent - * publisher can exchange the bytes between validation and install. - */ -function uniqueStagedExeFileName(version: string, platform: NodeJS.Platform): string { - const infix = `.${process.pid}.${Date.now()}.${stageTempCounter}`; - stageTempCounter += 1; - return platform === 'win32' ? `kimi-${version}${infix}.exe` : `kimi-${version}${infix}`; -} - -export function stagedExePath(exePath: string, staged: StagedNativeUpdate): string { - return join(getNativeStagingDir(exePath), staged.exeFileName); -} - -/** Parse staged-update metadata from raw text; null when malformed. */ -export function parseStagedNativeUpdate(raw: string): StagedNativeUpdate | null { - let json: unknown; - try { - json = JSON.parse(raw); - } catch { - return null; - } - const parsed = StagedNativeUpdateSchema.safeParse(json); - return parsed.success ? parsed.data : null; -} - -/** - * Read the staged-update metadata, returning null when anything is off: - * missing/corrupt `staged.json`, or the staged exe went away / changed size. - * A null result makes callers behave as if no update was ever staged. - */ -export async function readStagedNativeUpdate( - exePath: string, - filePath: string = getNativeStagedStateFile(exePath), -): Promise<StagedNativeUpdate | null> { - let raw: string; - try { - raw = await readFile(filePath, 'utf-8'); - } catch { - return null; - } - const staged = parseStagedNativeUpdate(raw); - if (staged === null) return null; - const info = await stat(stagedExePath(exePath, staged)).catch(() => null); - if (info === null || info.size !== staged.exeSize) return null; - return staged; -} - -/** - * Two staged records are the same generation when every field matches — - * ignoring only the `manual` marker that promotion flips. Used to make sure - * a read-modify-write still acts on the record it read. - */ -function isSameStagedRecord(a: StagedNativeUpdate, b: StagedNativeUpdate): boolean { - return ( - a.version === b.version && - a.target === b.target && - a.exeFileName === b.exeFileName && - a.sha256 === b.sha256 && - a.exeSize === b.exeSize && - a.stagedAt === b.stagedAt - ); -} - -/** - * Mark the adopted staged update as manual, confirming the marker actually - * persisted. Used when an explicit `kimi upgrade` adopts a payload the - * passive downloader staged (already on disk, or still downloading): the - * marker lets the startup swap apply it even under the env opt-out. - * - * `expected` is the record the caller read and decided to adopt. The promote - * write only happens while the on-disk metadata still IS that record — a - * concurrent downloader may have published a different stage meanwhile, and - * overwriting its record would orphan a payload whose worker already - * reported success. (Pathname-only writes cannot compare-and-swap, so a - * residual publish-between-check-and-write window remains; the identity - * re-read narrows it to that gap.) - * - * Returns false when the record changed / is concurrently claimed by a - * startup swap (nothing to promote) or a confirming read never sees the - * promoted record — callers must NOT report adoption for a promotion that - * never landed. The write and the confirmation use the same atomic metadata - * path as staging; a swap that claims the PROMOTED file proceeds with the - * marker, which is the desired outcome anyway. - */ -export async function promoteStagedUpdateToManual( - exePath: string, - expected: StagedNativeUpdate, -): Promise<boolean> { - if (expected.manual === true) return true; - for (let attempt = 0; attempt < 2; attempt += 1) { - const staged = await readStagedNativeUpdate(exePath); - if (staged === null || !isSameStagedRecord(staged, expected)) return false; - // Another promoter already marked this exact record — our work is done. - if (staged.manual === true) return true; - await writeJsonFile(getNativeStagedStateFile(exePath), StagedNativeUpdateSchema, { - ...staged, - manual: true, - }); - // Confirm: a concurrent claim/restore cycle could leave unpromoted - // content behind (the restore never overwrites, so a confirmed marker - // cannot be displaced afterwards). The confirmation must see the - // promoted ADOPTION CANDIDATE itself, not just any manual record. - const confirmed = await readStagedNativeUpdate(exePath); - if (confirmed?.manual === true && isSameStagedRecord(confirmed, expected)) return true; - } - return false; -} - -/** Stream a file's sha256 as hex; null when the file cannot be read. */ -export async function hashFileSha256(filePath: string): Promise<string | null> { - try { - const hash = createHash('sha256'); - for await (const chunk of createReadStream(filePath)) { - hash.update(chunk as Buffer); - } - return hash.digest('hex'); - } catch { - return null; - } -} - -/** - * Whether a `.staging/` entry is an updater-owned artifact: a staged - * executable (`kimi-<version>[.<pid>.<epoch-ms>.<n>][.exe]`) or a download - * intermediate (the same plus `.part`). Ownership derives from the - * semver/file-name contract (prerelease and build metadata included), so - * foreign files in the directory are never matched. - */ -function isUpdaterOwnedStagingFile(entry: string): boolean { - if (!entry.startsWith('kimi-')) return false; - let name = entry.slice('kimi-'.length); - if (name.endsWith('.part')) name = name.slice(0, -'.part'.length); - if (name.endsWith('.exe')) name = name.slice(0, -'.exe'.length); - // Published artifacts may carry a unique per-worker infix after the - // version (.<pid>.<epoch-ms>.<n>, or the older .<pid>.<n>) — try with and - // without stripping it (the infix is dot-numeric, which is ambiguous with - // prerelease suffixes, so every candidate is checked). - const candidates = [ - name, - name.replace(/\.\d+\.\d+$/, ''), - name.replace(/\.\d+\.\d+\.\d+$/, ''), - ]; - return candidates.some((candidate) => valid(candidate) !== null); -} - -/** - * An unreferenced artifact is only deleted once it is older than this. A - * concurrent worker's payload publishes BEFORE its metadata, so a freshly - * renamed staged exe can look like an orphan for a moment; publication takes - * milliseconds, so anything unreferenced AND old is definitively abandoned. - */ -const STAGING_ORPHAN_GRACE_MS = 60 * 60 * 1000; - -/** - * Remove files in `.staging/` that nothing references: interrupted downloads - * (`.part`), and staged exes whose `staged.json` never landed (downloader - * killed between the two writes) — each such orphan is ~180 MB and would - * otherwise accumulate forever. The exe referenced by the CURRENT - * `staged.json` is preserved (a superseded record is only replaced by the - * final atomic write, so its payload is still the applicable update while - * this run downloads), and so are swap claim files (`staged.json.swap-*`) - * with the exes they reference: another instance may be mid-swap. - */ -async function cleanupStagingOrphans(stagingDir: string): Promise<void> { - let entries: string[]; - try { - entries = await readdir(stagingDir); - } catch { - return; - } - const keep = new Set<string>([KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME]); - for (const entry of entries) { - // The current record and every swap claim pin the exe they reference. - if ( - entry !== KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME && - !entry.startsWith(`${KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME}.swap-`) - ) { - continue; - } - keep.add(entry); - const raw = await readFile(join(stagingDir, entry), 'utf-8').catch(() => null); - if (raw === null) continue; - try { - const exeFileName: unknown = (JSON.parse(raw) as { exeFileName?: unknown }).exeFileName; - if (typeof exeFileName === 'string' && exeFileName.length > 0) { - // basename(): the metadata contract is a plain file name — never let - // a hand-crafted path escape the staging dir. - keep.add(basename(exeFileName)); - } - } catch { - // Unparseable record/claim: keep the file itself, touch nothing else. - } - } - for (const entry of entries) { - if (keep.has(entry)) continue; - // Only ever unlink updater-owned artifact names (files, never - // directories): the staging dir sits next to the exe and may contain - // data that is not ours. - if (!isUpdaterOwnedStagingFile(entry)) continue; - const full = join(stagingDir, entry); - const info = await stat(full).catch(() => null); - if (info === null) continue; - // Too young to be abandoned — a concurrent worker may be about to - // publish its metadata. - if (Date.now() - info.mtimeMs < STAGING_ORPHAN_GRACE_MS) continue; - await unlink(full).catch(() => {}); - } -} - -export interface StageNativeUpdateOptions { - readonly version: string; - /** Path of the installed executable the staged binary will later replace. */ - readonly exePath: string; - readonly platform?: NodeJS.Platform; - readonly arch?: string; - readonly fetchImpl?: typeof fetch; - /** Download progress (bytes so far, Content-Length total when known). */ - readonly onProgress?: (downloadedBytes: number, totalBytes: number | null) => void; - /** Test hook: override the download idle timeout (default 30 s). */ - readonly idleTimeoutMs?: number; - /** True when the stage answers an explicit user-initiated `kimi upgrade`. */ - readonly manual?: boolean; -} - -export type StageNativeUpdateStatus = 'already-staged' | 'staged'; - -export interface StageNativeUpdateResult { - readonly status: StageNativeUpdateStatus; - readonly staged: StagedNativeUpdate; -} - -/** - * Idle timeout for the binary stream: any 30 s without a arriving chunk - * aborts the download. Total duration is intentionally unbounded — slow - * networks may take as long as they need as long as bytes keep flowing. - */ -const DOWNLOAD_IDLE_TIMEOUT_MS = 30_000; - -async function downloadAndHash( - url: string, - partPath: string, - expectedSha256: string, - fetchImpl: typeof fetch, - onProgress?: (downloadedBytes: number, totalBytes: number | null) => void, - idleTimeoutMs: number = DOWNLOAD_IDLE_TIMEOUT_MS, -): Promise<number> { - const controller = new AbortController(); - let idleTimeout: ReturnType<typeof setTimeout> | undefined; - const armIdleTimeout = (): void => { - if (idleTimeout !== undefined) clearTimeout(idleTimeout); - idleTimeout = setTimeout(() => { - controller.abort(new Error(`download stalled: no data for ${idleTimeoutMs}ms`)); - }, idleTimeoutMs); - }; - armIdleTimeout(); - let response: Response; - try { - response = await fetchImpl(url, { signal: controller.signal }); - } catch (error) { - clearTimeout(idleTimeout); - throw error; - } - if (!response.ok || response.body === null) { - clearTimeout(idleTimeout); - throw new Error(`native binary download returned HTTP ${response.status}`); - } - const contentLength = response.headers.get('content-length'); - const total = - contentLength !== null && /^\d+$/.test(contentLength) ? Number(contentLength) : null; - const hash = createHash('sha256'); - let size = 0; - const file = await open(partPath, 'w'); - try { - for await (const chunk of response.body as AsyncIterable<Uint8Array>) { - armIdleTimeout(); - hash.update(chunk); - size += chunk.length; - // FileHandle.write may persist FEWER bytes than requested (a short - // write, e.g. near disk exhaustion) while the hash and size above - // already account for the whole chunk — an unretried short write would - // publish a truncated binary under a valid checksum. Loop until the - // chunk is fully on disk. - let offset = 0; - while (offset < chunk.length) { - const { bytesWritten } = await file.write(chunk, offset); - if (bytesWritten === 0) { - throw new Error('failed to write the native binary to disk (disk full?)'); - } - offset += bytesWritten; - } - onProgress?.(size, total); - } - } finally { - clearTimeout(idleTimeout); - await file.close(); - } - const digest = hash.digest('hex'); - if (digest !== expectedSha256) { - throw new Error(`sha256 mismatch: expected ${expectedSha256}, got ${digest}`); - } - return size; -} - -/** - * Download + verify `version` next to the running executable. - * - * Short-circuits with `already-staged` when the same version is ready on - * disk (repeat `kimi upgrade`, or foreground/background overlap). **Throws** - * on any failure after cleaning up this version's leftovers — the caller - * records an install failure. - */ -export async function stageNativeUpdate( - options: StageNativeUpdateOptions, -): Promise<StageNativeUpdateResult> { - const platform = options.platform ?? process.platform; - const arch = options.arch ?? process.arch; - // Validate BEFORE anything derives a filesystem path from the version: the - // hidden download command takes it from argv, and a non-semver could carry - // path traversal into the cleanup paths below. - if (valid(options.version) === null) { - throw new Error(`invalid semver for native staging: ${JSON.stringify(options.version)}`); - } - const fetchImpl = options.fetchImpl ?? fetch; - const target = `${platform}-${arch}`; - // Unique per-worker publish name — see uniqueStagedExeFileName: a staged - // exe is never replaced once published, so the pathname a swap validates - // at claim time cannot be exchanged by a concurrent publisher. - const exeFileName = uniqueStagedExeFileName(options.version, platform); - - const existing = await readStagedNativeUpdate(options.exePath); - if (existing !== null && existing.version === options.version) { - // readStagedNativeUpdate checks only the recorded size — a same-size - // corruption after the download (disk damage, a non-durable write) - // would still be adopted here and reported as success, only for the - // startup swap's claim-time re-verify to reject and discard it. Compare - // the actual digest before adopting; a mismatch falls through and - // re-stages from the CDN (published under a new generation name — the - // damaged exe is left for the age-gated orphan cleanup). - const digest = await hashFileSha256(stagedExePath(options.exePath, existing)); - if (digest === existing.sha256) { - // An explicit upgrade adopts an auto-staged payload — but only report - // the adoption once the manual marker is confirmed persisted. A stage - // currently being claimed by a startup swap cannot be promoted here; - // fall through and stage afresh instead. - if (options.manual === true && existing.manual !== true) { - if (await promoteStagedUpdateToManual(options.exePath, existing)) { - return { status: 'already-staged', staged: { ...existing, manual: true } }; - } - } else { - return { status: 'already-staged', staged: existing }; - } - } - } - - // A different version was staged earlier and never swapped (skipped - // rollout, user stayed offline, …), or the same version's payload failed - // the integrity check above. The old record is LEFT IN PLACE until the - // atomic metadata write below replaces it: a pathname-level delete could - // remove a concurrent worker's freshly published record (orphaning a - // payload whose worker already reported success), and a swap claiming the - // old stage meanwhile applies a still-valid update. The old exe stays too - // — an unreferenced one is reaped by the age-gated orphan cleanup. - const stagingDir = getNativeStagingDir(options.exePath); - await mkdir(stagingDir, { recursive: true }); - // Drop orphans from interrupted earlier runs before writing ours. - await cleanupStagingOrphans(stagingDir); - - const staged: StagedNativeUpdate = { - version: options.version, - target, - exeFileName, - sha256: '', - exeSize: 0, - stagedAt: new Date().toISOString(), - manual: options.manual === true ? true : undefined, - }; - - // The .part intermediate is just the publish name plus the suffix — the - // name already carries this worker's unique infix, so concurrent workers - // never interleave writes into a shared path. - const partPath = join(stagingDir, `${exeFileName}.part`); - try { - const manifest = await fetchNativeReleaseManifest(options.version, fetchImpl); - const entry = selectPlatformEntry(manifest, platform, arch); - const size = await downloadAndHash( - nativeBinaryUrl(options.version, entry.filename), - partPath, - entry.checksum, - fetchImpl, - options.onProgress, - options.idleTimeoutMs, - ); - // sha256 matched the manifest. Make the private .part file executable - // BEFORE publishing it: a concurrent swap may move the staged exe into - // the install path the instant it appears at its published name, so a - // post-publish chmod could land on a path that is already gone — leaving - // a non-executable installation behind. - await chmod(partPath, 0o755); - await rename(partPath, stagedExePath(options.exePath, staged)); - - staged.sha256 = entry.checksum; - staged.exeSize = size; - // Atomic write: staged.json only ever appears complete and consistent. - await writeJsonFile( - getNativeStagedStateFile(options.exePath), - StagedNativeUpdateSchema, - staged, - ); - return { status: 'staged', staged }; - } catch (error) { - // Remove only what THIS attempt privately owns: its unique .part file. - // If the failure landed after the publishing rename, this attempt's exe - // is already at its unique name with no metadata pointing at it — left - // in place (a just-published exe may belong to a concurrent metadata - // write) and reaped by the age-gated orphan cleanup. - await rm(partPath, { force: true }).catch(() => {}); - // Best effort: drop the staging dir itself when empty (a concurrent - // worker's files keep it around — rmdir only removes empty dirs). - await rmdir(getNativeStagingDir(options.exePath)).catch(() => {}); - throw error; - } -} diff --git a/apps/kimi-code/src/cli/update/native-swap.ts b/apps/kimi-code/src/cli/update/native-swap.ts deleted file mode 100644 index 9b477efab..000000000 --- a/apps/kimi-code/src/cli/update/native-swap.ts +++ /dev/null @@ -1,642 +0,0 @@ -/** - * Native staged swap, executed at the very top of startup. - * - * When a staged update is ready (`.staging/staged.json` next to the running - * exe), swap it in atomically and re-exec so the user session runs the new - * binary immediately. Everything here is best-effort: any failure leaves the - * current exe intact (rollback from `.bak`) and startup continues normally. - * - * Windows semantics make this safe: a running exe can be renamed but not - * overwritten, so the sequence is `rename exe→.bak` (the running process is - * unaffected), `rename staged→exe`, then delete `.bak` (best effort — a - * concurrent old instance keeps it locked until it exits). This is the same - * mechanism install.ps1 already relies on, and the Squirrel/NSIS-style - * "next launch performs the swap" pattern. Leftovers a swap cannot remove - * (its own `.bak` while still running, crash residue in `.staging/`) are - * swept best-effort on every launch. - */ - -import { spawn } from 'node:child_process'; -import { readdir, readFile, rename, rmdir, stat, unlink, utimes } from 'node:fs/promises'; -import { constants as osConstants } from 'node:os'; -import { basename, dirname, join } from 'node:path'; - -import { gt } from 'semver'; - -import { log } from '@moonshot-ai/kimi-code-sdk'; - -import { - KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME, - KIMI_CODE_UPDATE_REEXEC_ENV, -} from '#/constant/app'; - -import { readUpdateInstallState, writeUpdateInstallState } from './install-state'; -import { - hashFileSha256, - parseStagedNativeUpdate, - readStagedNativeUpdate, - stagedExePath, - type StagedNativeUpdate, -} from './native-stage'; -import { isAutoUpdateDisabledByEnv, shouldAutoInstallUpdates } from './preflight'; -import { getNativeStagedStateFile, getNativeStagingDir } from '#/utils/paths'; -import { createFileIfAbsent } from '#/utils/persistence'; - -export interface NativeSwapDeps { - readonly exePath: string; - readonly argv: readonly string[]; - readonly env: NodeJS.ProcessEnv; - readonly currentVersion: string; - readonly isNative: boolean; - readonly spawnImpl?: typeof spawn; - readonly exitImpl?: (code: number) => void; -} - -export interface SpawnedChild { - once(event: 'error', listener: (error: Error) => void): void; - once(event: 'exit', listener: (code: number | null, signal: NodeJS.Signals | null) => void): void; - once(event: 'close', listener: (code: number | null, signal: NodeJS.Signals | null) => void): void; -} - -function isTruthy(value: string | undefined): boolean { - return ['1', 'true', 'yes', 'on'].includes((value ?? '').trim().toLowerCase()); -} - -function isNotFound(error: unknown): boolean { - return ( - typeof error === 'object' && error !== null && (error as { code?: string }).code === 'ENOENT' - ); -} - -function isAlreadyExists(error: unknown): boolean { - return ( - typeof error === 'object' && error !== null && (error as { code?: string }).code === 'EEXIST' - ); -} - -/** - * A `staged.json.swap-<pid>` claim file younger than this marks a swap in - * progress in another instance; older ones are crash residue. The bound - * comfortably exceeds the slowest swap (smoke-check timeout included). - */ -const SWAP_CLAIM_STALE_MS = 5 * 60 * 1000; - -/** - * The swap's executable-renaming critical section is a few filesystem ops - * (well under a second), so a swap mutex older than this is crash residue. - */ -const SWAP_MUTEX_STALE_MS = 60_000; - -/** - * A young unparseable `staged.json` may be an in-flight exclusive-create - * publish (observable mid-write on filesystems without hard links — see - * createFileIfAbsent), not corruption. The publish gap is microscopic, so - * only records younger than this get the benefit of the doubt. - */ -const STAGED_PUBLISH_GRACE_MS = 60_000; - -// First launch of a fresh ~150 MB unsigned exe can sit in an antivirus scan; -// give Windows extra headroom so a slow scan is not misread as a broken binary. -const SMOKE_CHECK_TIMEOUT_MS = process.platform === 'win32' ? 30_000 : 15_000; - -function logSwap(message: string, payload: Record<string, unknown>): void { - try { - log.info(`native update swap: ${message}`, payload); - } catch { - // Diagnostics must never affect startup. - } -} - -/** Record a swap failure so preflight stops re-staging the same bad version. */ -async function recordSwapFailure(version: string): Promise<void> { - try { - const state = await readUpdateInstallState(); - const attempts = - (state.lastFailure?.version === version ? state.lastFailure.attempts : 0) + 1; - await writeUpdateInstallState({ - ...state, - active: null, - lastFailure: { version, failedAt: new Date().toISOString(), attempts }, - }); - } catch { - // Never block startup on bookkeeping. - } -} - -/** - * Run `exe --version` as a smoke check: exit code 0 and the EXACT staged - * version as the output (commander prints `<version>\n`). A substring check - * would let a mispublished binary satisfy the wrong target (`1.2.30` - * contains `1.2.3`) — and the manifest checksum cannot catch that case when - * it also describes the wrong artifact. - */ -function smokeCheck( - exePath: string, - staged: StagedNativeUpdate, - spawnImpl: typeof spawn, -): Promise<boolean> { - return new Promise((resolve) => { - let stdout = ''; - let settled = false; - const finish = (ok: boolean): void => { - if (settled) return; - settled = true; - resolve(ok); - }; - let child: SpawnedChild & { readonly stdout?: NodeJS.ReadableStream | null; kill(): void }; - try { - child = spawnImpl(exePath, ['--version'], { stdio: ['ignore', 'pipe', 'ignore'], windowsHide: true }) as unknown as typeof child; - } catch { - finish(false); - return; - } - const timeout = setTimeout(() => { - try { - child.kill(); - } catch { - // Already gone. - } - finish(false); - }, SMOKE_CHECK_TIMEOUT_MS); - child.stdout?.on('data', (chunk: Buffer) => { - stdout += chunk.toString('utf-8'); - }); - child.once('error', () => { - clearTimeout(timeout); - finish(false); - }); - // 'close', not 'exit': stdio may still be flushing when 'exit' fires, and - // the check needs the complete version output. - child.once('close', (code) => { - clearTimeout(timeout); - finish(code === 0 && stdout.trim() === staged.version); - }); - }); -} - -interface ClaimedStaged { - readonly staged: StagedNativeUpdate; - readonly claimedPath: string; -} - -/** - * Atomically claim the staged metadata file (rename is atomic on both NTFS - * and POSIX, so exactly one of several concurrently starting instances wins), - * THEN parse the claimed contents. Claim-first matters: a concurrent - * downloader may supersede `staged.json` at any moment, so validating before - * the rename could act on metadata this swap never claimed. - * - * Returns null when there is nothing staged, the file disappeared under us, - * or the claimed metadata failed consistency checks. A claimed record that is - * UNPARSEABLE but was young at claim time may be an in-flight - * exclusive-create publish (observable mid-write where hard links are - * unsupported): it is put back with the same inode so the writer completes - * it, never destroyed. Aged corrupt residue and well-formed records whose exe - * is gone/changed are deterministically dead and discarded. - */ -async function claimStagedUpdate(exePath: string): Promise<ClaimedStaged | null> { - const stateFile = getNativeStagedStateFile(exePath); - const claimedPath = `${stateFile}.swap-${process.pid}`; - // Capture the record's age BEFORE the stamp below rewrites it. - const before = await stat(stateFile).catch(() => null); - const youngAtClaim = - before === null || Date.now() - before.mtimeMs <= STAGED_PUBLISH_GRACE_MS; - try { - // The metadata's mtime can be arbitrarily old — the download may have - // finished hours before this launch. Stamp it BEFORE the rename so the - // claim is born fresh: a concurrent launch's sweep never observes a live - // claim that looks like crash residue (and would delete the staged exe - // plus this swap's rollback backup). Stamping the state file itself is - // harmless — nothing reads its mtime. - await utimes(stateFile, new Date(), new Date()).catch(() => {}); - await rename(stateFile, claimedPath); - } catch { - return null; - } - // Parse exactly the metadata we claimed. - const staged = await readStagedNativeUpdate(exePath, claimedPath); - if (staged === null) { - const raw = await readFile(claimedPath, 'utf-8').catch(() => null); - const wellFormed = raw !== null && parseStagedNativeUpdate(raw) !== null; - if (!wellFormed && youngAtClaim) { - // Possible in-flight publish: put the SAME inode back so the writer's - // pending write completes it. rename can overwrite a concurrently - // published newer record — bounded to this parse-failure window, and - // the loser is a newer stage that simply re-downloads, never a corrupt - // install. - await rename(claimedPath, stateFile).catch(() => {}); - return null; - } - await unlink(claimedPath).catch(() => {}); - return null; - } - return { staged, claimedPath }; -} - -/** - * Put a claimed stage's metadata back so a later launch can retry — but only - * into a still-free state-file path: a downloader may have published a NEWER - * stage meanwhile, and an unconditional restore would silently replace it. - * The publish is create-if-absent (hard link, or an exclusive create on - * filesystems without hard-link support), so the restore never overwrites. - * - * The claim file is removed only when the restore landed or the path was - * taken by a newer stage (ours is superseded either way). A transient - * failure (ENOSPC, EACCES, …) RETAINS the claim: discarding it would orphan - * the staged exe with no newer stage to show for it, and the stale-claim - * sweep retries the restore on a later launch. - */ -async function restoreClaimedUpdate(exePath: string, claimedPath: string): Promise<void> { - const content = await readFile(claimedPath, 'utf-8').catch(() => null); - if (content === null) { - // Nothing readable to restore — drop the residue. - await unlink(claimedPath).catch(() => {}); - return; - } - try { - await createFileIfAbsent(getNativeStagedStateFile(exePath), content); - } catch (error) { - if (!isAlreadyExists(error)) return; - // EEXIST: a concurrently published newer stage won the path. - } - await unlink(claimedPath).catch(() => {}); -} - -/** - * Discard a claimed stage: only the claimed metadata file is removed — never - * the staged exe. A same-version downloader may have just renamed its fresh - * payload onto that path (payloads publish before their metadata), and - * genuinely unreferenced exes are reaped by the downloader's own orphan - * cleanup before its next stage. - */ -async function discardClaimedUpdate(claimedPath: string): Promise<void> { - await unlink(claimedPath).catch(() => {}); -} - -async function rollback(bakPath: string, exePath: string): Promise<boolean> { - try { - await rename(bakPath, exePath); - return true; - } catch { - return false; - } -} - -export interface SwapMutexHandle { - release(): Promise<void>; -} - -/** - * Serialize the swap's executable-renaming critical section across CLI - * processes. The fresh-claim sweep is only a directory SNAPSHOT: two - * processes can both pass it before either claims, then claim different - * stage generations and rename the same installed exe concurrently — - * deleting or replacing each other's `.bak` rollback source. The mutex is - * create-if-absent (via createFileIfAbsent); an aged holder is crash residue - * (the section lasts well under a second) and is swept, then retried once. - */ -async function acquireSwapMutex(stagingDir: string): Promise<SwapMutexHandle | null> { - const mutexPath = join(stagingDir, 'swap.lock'); - const marker = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`; - for (let attempt = 0; attempt < 2; attempt += 1) { - try { - await createFileIfAbsent(mutexPath, marker); - } catch (error) { - if (!isAlreadyExists(error)) { - // Transient IO failure (ENOSPC, EACCES, …): defer the swap rather - // than abort it — the caller restores the claim for a later launch. - return null; - } - if (attempt === 1) return null; - // Held — or crash residue: only an AGED mutex may be swept. - const info = await stat(mutexPath).catch(() => null); - if (info !== null && Date.now() - info.mtimeMs <= SWAP_MUTEX_STALE_MS) return null; - await unlink(mutexPath).catch(() => {}); - continue; - } - // The stale sweep races this publish; only the survivor proceeds (same - // irreducible residual as the install lock's takeover marker). - const published = await readFile(mutexPath, 'utf-8').catch(() => null); - if (published !== marker) return null; - return { - release: async (): Promise<void> => { - // Release only the mutex instance we own. - const current = await readFile(mutexPath, 'utf-8').catch(() => null); - if (current !== marker) return; - await unlink(mutexPath).catch(() => {}); - }, - }; - } - return null; -} - -/** - * Remove leftover `.bak` siblings of the exe from earlier swaps/installs. - * Only names the updater itself creates are removed: the exact `<exe>.bak` - * and the numeric PID fallback `<exe>.<pid>.bak` — anything else with the - * prefix (`kimi.config.bak`, …) belongs to the user. A `.bak` still mapped - * by a running old instance cannot be deleted on Windows — it is simply - * left for a later launch. - */ -async function cleanupBackups(exePath: string, keepPath?: string): Promise<void> { - const dir = dirname(exePath); - const base = basename(exePath); - let entries: string[]; - try { - entries = await readdir(dir); - } catch { - return; - } - for (const entry of entries) { - if (!entry.startsWith(`${base}.`) || !entry.endsWith('.bak')) continue; - const middle = entry.slice(base.length + 1, -'.bak'.length); - if (middle !== '' && !/^\d+$/.test(middle)) continue; - const full = join(dir, entry); - if (full === keepPath) continue; - await unlink(full).catch(() => {}); - } -} - -/** - * Recover `staged.json.swap-<pid>` claim files left by instances that died - * mid-swap (or kept by a restore that hit a transient error). An AGED claim - * is restored back onto the state-file path — create-if-absent, so a newer - * published stage is never overwritten — and this very launch can then claim - * and retry the swap; the claim file is dropped once the record is restored - * or superseded, and retained on transient errors. The referenced exes are - * never touched here: they may belong to a freshly published stage, and - * genuinely unreferenced ones are reaped by the downloader's own orphan - * cleanup before its next stage. Returns true when a FRESH claim file was - * seen — i.e. another instance is swapping right now. - */ -async function cleanupStaleSwapClaims(exePath: string): Promise<boolean> { - const stagingDir = getNativeStagingDir(exePath); - let entries: string[]; - try { - entries = await readdir(stagingDir); - } catch { - return false; - } - let swapInProgress = false; - for (const entry of entries) { - if (!entry.startsWith(`${KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME}.swap-`)) continue; - const full = join(stagingDir, entry); - const info = await stat(full).catch(() => null); - if (info === null) continue; - if (Date.now() - info.mtimeMs < SWAP_CLAIM_STALE_MS) { - swapInProgress = true; - continue; - } - await restoreClaimedUpdate(exePath, full); - } - return swapInProgress; -} - -/** - * Best-effort startup hygiene for update leftovers, run on every native - * launch. The swap itself can never fully clean up after its own run — the - * old process still holds its renamed image (`.bak`) on Windows — so later - * launches sweep what the previous run could not. - * - * Returns true when another instance holds a fresh swap claim or swap mutex: - * every artifact is then left alone and the caller must not start a second - * swap. - */ -async function sweepStaleNativeUpdateArtifacts(exePath: string): Promise<boolean> { - try { - if (await cleanupStaleSwapClaims(exePath)) { - // Another instance is mid-swap: leave every artifact alone — the `.bak` - // next to the exe is its rollback source. - return true; - } - // A live swap critical section holds the mutex: same deference. (Only a - // snapshot, but the swap re-checks the mutex after claiming, so a - // freshly-started swap is never entered concurrently.) - const mutexInfo = await stat(join(getNativeStagingDir(exePath), 'swap.lock')).catch( - () => null, - ); - if (mutexInfo !== null && Date.now() - mutexInfo.mtimeMs <= SWAP_MUTEX_STALE_MS) { - return true; - } - await cleanupBackups(exePath); - } catch { - // Hygiene must never affect startup. - } - return false; -} - -/** - * Re-exec the (newly swapped) exe with the original argv, forwarding its exit - * code so the swap is invisible to the caller. Returns false when the spawn - * itself failed — the caller then continues startup with the old in-memory - * code; the binary on disk is already the new version. - */ -function reexec( - deps: NativeSwapDeps & { readonly spawnImpl: typeof spawn }, -): Promise<boolean> { - return new Promise((resolve) => { - let child: SpawnedChild; - try { - child = deps.spawnImpl(deps.exePath, deps.argv.slice(2), { - stdio: 'inherit', - env: { ...deps.env, [KIMI_CODE_UPDATE_REEXEC_ENV]: '1' }, - }) as unknown as SpawnedChild; - } catch (error) { - logSwap('re-exec spawn threw', { error: String(error) }); - resolve(false); - return; - } - child.once('error', (error) => { - logSwap('re-exec spawn failed', { error: error.message }); - resolve(false); - }); - child.once('exit', (code, signal) => { - resolve(true); - const exitImpl = deps.exitImpl ?? ((exitCode: number) => process.exit(exitCode)); - if (code !== null) { - exitImpl(code); - return; - } - // Terminated by a signal (OOM kill, external SIGKILL, …): mirror the - // shell's 128 + signo convention so the wrapper never reports a killed - // run as a successful CLI invocation. - const signo = signal !== null ? (osConstants.signals[signal] ?? 0) : 0; - exitImpl(signo > 0 ? 128 + signo : 1); - }); - }); -} - -/** - * Swap in a staged native update and re-exec when one is ready. - * - * Returns true only when the process was re-launched (the caller must not - * continue startup — the exit handler fires once the child exits). Every - * other outcome returns false so startup proceeds untouched. - */ -export async function maybeRelaunchWithStagedNativeUpdate( - deps: NativeSwapDeps, -): Promise<boolean> { - if (!deps.isNative) return false; - const swapInProgress = await sweepStaleNativeUpdateArtifacts(deps.exePath); - if (isTruthy(deps.env[KIMI_CODE_UPDATE_REEXEC_ENV])) { - // Read-once guard: drop it so this session's children (and any nested - // kimi launches from them) do not inherit the swap skip. - delete deps.env[KIMI_CODE_UPDATE_REEXEC_ENV]; - return false; - } - if (swapInProgress) { - // Another instance holds a fresh swap claim and finishes (or rolls back) - // on its own. Starting a second swap here would rename the install path - // from under it and let each launcher delete the `.bak` the other may - // still need for rollback. Its re-exec — or our next launch — lands the - // update, so this session simply runs the current exe. - logSwap('another instance is mid-swap, skipping', { exePath: deps.exePath }); - return false; - } - - const claimed = await claimStagedUpdate(deps.exePath); - if (claimed === null) return false; - const { staged, claimedPath } = claimed; - const spawnImpl = deps.spawnImpl ?? spawn; - - const discard = async (): Promise<boolean> => { - await discardClaimedUpdate(claimedPath); - return false; - }; - - // Downgrade guard: the staged version must be newer than what is running. - // (The user may have installed a newer build manually after we staged.) - if (!gt(staged.version, deps.currentVersion)) { - logSwap('discarding staged update (not newer)', { - staged: staged.version, - current: deps.currentVersion, - }); - return discard(); - } - - // Automatic stages apply only while automatic updates are enabled — both - // the env opt-out and the persisted `[upgrade] auto_install = false` - // preference gate them. Evaluated on the CLAIMED metadata: a pre-claim - // snapshot could be replaced by a downloader before the claim, smuggling an - // automatic payload past the gate. A manually requested stage always - // applies. When disabled, restore the claim (never overwriting a newer - // stage) so a later launch without the opt-out can still apply it. - if ( - staged.manual !== true && - (isAutoUpdateDisabledByEnv(deps.env) || !(await shouldAutoInstallUpdates())) - ) { - await restoreClaimedUpdate(deps.exePath, claimedPath); - return false; - } - - // Re-verify the staged bytes against the recorded checksum: the exe could - // have been damaged on disk after the download verified it (corruption, a - // non-durable interrupted write), and the `--version` smoke check alone - // would not catch every such case. Only paid once the swap actually - // proceeds. A mismatch discards the stage so a later cycle re-downloads - // it — this is not a swap failure. - const digest = await hashFileSha256(stagedExePath(deps.exePath, staged)); - if (digest !== staged.sha256) { - logSwap('staged exe failed checksum verification, discarding', { - version: staged.version, - }); - return discard(); - } - - const stagedExe = stagedExePath(deps.exePath, staged); - - // 1. Smoke-check the staged exe BEFORE touching the install path: a staged - // binary that cannot start (or lies about its version) is discarded with - // the running exe never moved — the safest possible failure shape. - if (!(await smokeCheck(stagedExe, staged, spawnImpl))) { - logSwap('smoke check failed, discarding staged update', { version: staged.version }); - await recordSwapFailure(staged.version); - return discard(); - } - - // The fresh-claim sweep at startup is only a directory snapshot — another - // instance may have begun its swap after our sweep ran. Take the swap - // mutex before touching the install path so two swaps never rename the - // same exe concurrently (each would delete the other's `.bak` rollback - // source). The staged payload is immutable (unique generation name), so - // nothing validated above can change while we contend here. - const swapMutex = await acquireSwapMutex(getNativeStagingDir(deps.exePath)); - if (swapMutex === null) { - logSwap('another instance is in its swap critical section, deferring', { - exePath: deps.exePath, - }); - await restoreClaimedUpdate(deps.exePath, claimedPath); - return false; - } - try { - // 2. Pick a backup slot and move the running exe aside (rename of a running - // exe is legal on Windows and POSIX alike; overwriting is not). - // - // Crash window: if the process dies between this rename and step 3, the - // install path is left empty and no CLI code can run to self-heal. Each - // rename is atomic, the window is two adjacent syscalls, and recovery is - // `mv <exe>.bak <exe>` or re-running the install script. - let bakPath = `${deps.exePath}.bak`; - try { - await unlink(bakPath); - } catch (error) { - if (!isNotFound(error)) { - // The leftover `.bak` is locked by a still-running old instance (or - // undeletable for another reason) — take a unique backup name, the same - // fallback install.ps1 uses. It is best-effort cleaned up on later runs. - bakPath = `${deps.exePath}.${process.pid}.bak`; - } - } - try { - await rename(deps.exePath, bakPath); - } catch (error) { - // Nothing was moved: startup continues with the old exe. Restore the - // claimed metadata so a later launch retries the swap (transient locks - // clear on reboot) — but only into a still-free state-file path: a - // downloader may have published a NEWER stage while we smoke-checked, - // and an unconditional restore would silently replace it. The restore is - // create-if-absent, so it can never overwrite; when the path is taken, - // the newer stage wins and ours is discarded. - logSwap('failed to move exe aside', { exePath: deps.exePath, error: String(error) }); - await restoreClaimedUpdate(deps.exePath, claimedPath); - return false; - } - - // 3. Move the staged exe into place; roll back on failure. - if ((await rename(stagedExe, deps.exePath).catch(() => null)) === null) { - logSwap('failed to move staged exe into place, rolling back', { exePath: deps.exePath }); - if (!(await rollback(bakPath, deps.exePath))) { - // Rollback failed too (transient file lock, AV, …): the install path is - // now absent and no next launch can start. Keep every artifact instead - // of discarding — the `.bak` IS the old exe and the staged payload is a - // second recovery copy, so `mv <exe>.bak <exe>` or re-running the - // installer still recovers. - logSwap('rollback failed, keeping recovery artifacts', { - exePath: deps.exePath, - bakPath, - }); - await recordSwapFailure(staged.version); - return false; - } - await recordSwapFailure(staged.version); - return await discard(); - } - - // 4. Success: clean up, STILL INSIDE the mutex — a swap that acquires it - // the instant we release could rename the exe we just installed to the - // shared `.bak` path, and this cleanup would delete that rollback - // source. Then re-exec into the new binary. - await unlink(claimedPath).catch(() => {}); - await unlink(bakPath).catch(() => {}); - await cleanupBackups(deps.exePath, bakPath); - logSwap('swap succeeded, re-launching', { version: staged.version }); - } finally { - await swapMutex.release(); - } - // Cosmetic, now that the release removed our mutex file: drop the staging - // dir when empty. And re-exec OUTSIDE the critical section: the child runs - // the user session, so awaiting it inside the try would hold the mutex for - // its whole lifetime. - await rmdir(getNativeStagingDir(deps.exePath)).catch(() => {}); - return reexec({ ...deps, spawnImpl }); -} diff --git a/apps/kimi-code/src/cli/update/preflight.ts b/apps/kimi-code/src/cli/update/preflight.ts index 9d6d1f172..5bcad7c9b 100644 --- a/apps/kimi-code/src/cli/update/preflight.ts +++ b/apps/kimi-code/src/cli/update/preflight.ts @@ -4,9 +4,9 @@ import { log, type Logger } from '@moonshot-ai/kimi-code-sdk'; import type { TelemetryProperties } from '@moonshot-ai/kimi-telemetry'; import { - kimiCodeOfficialInstallUrl, - nativeInstallCommandUnix, - nativeInstallCommandWin, + KIMI_CODE_OFFICIAL_INSTALL_URL, + NATIVE_INSTALL_COMMAND_UNIX, + NATIVE_INSTALL_COMMAND_WIN, } from '#/constant/app'; import { loadTuiConfig } from '#/tui/config'; import { resolveCommandPath } from '#/utils/process/resolve-command'; @@ -82,13 +82,13 @@ export function installCommandFor( case 'homebrew': return 'brew upgrade kimi-code'; case 'native': - return platform === 'win32' ? nativeInstallCommandWin() : nativeInstallCommandUnix(); + return platform === 'win32' ? NATIVE_INSTALL_COMMAND_WIN : NATIVE_INSTALL_COMMAND_UNIX; case 'unsupported': return `npm install -g ${NPM_PACKAGE_NAME}@${version}`; } } -export function canAutoInstall(source: InstallSource, _platform: NodeJS.Platform): boolean { +export function canAutoInstall(source: InstallSource, platform: NodeJS.Platform): boolean { switch (source) { case 'npm-global': case 'pnpm-global': @@ -100,8 +100,7 @@ export function canAutoInstall(source: InstallSource, _platform: NodeJS.Platform // behind the CDN release — prompt the user to run `brew upgrade` manually. return false; case 'native': - // Staged-swap self update works on every platform (win32 included). - return true; + return platform !== 'win32'; case 'unsupported': return false; } @@ -129,12 +128,12 @@ export function spawnForSource( case 'homebrew': return { cmd: 'brew', args: ['upgrade', 'kimi-code'] }; case 'native': - // Native installs self-spawn the hidden downloader sub-command, which - // stages the binary next to the exe (verified against the release - // manifest's sha256); the swap happens on the next startup. This - // replaces the old `curl|bash` / `irm|iex` re-install dance — no shell, - // no pipeline exit-status loss, no PowerShell dependency on Windows. - return { cmd: process.execPath, args: ['__update_download', version] }; + // `curl … | bash` reports only the trailing bash's exit status, so a + // failed download (curl can't connect → empty stdin → bash exits 0) + // would look like a successful update. `pipefail` makes the pipeline + // surface curl's non-zero status so installUpdate() rejects and we warn + // instead of printing "Updated …". + return { cmd: 'bash', args: ['-c', `set -o pipefail; ${NATIVE_INSTALL_COMMAND_UNIX}`] }; case 'unsupported': throw new Error('unsupported install source cannot be auto-installed'); } @@ -159,38 +158,9 @@ function resolveSpawnCommand(cmd: string, platform: NodeJS.Platform): string | u return platform === 'win32' ? `"${resolved}"` : resolved; } -/** - * Resolve the spawn target for an install. Package managers are resolved from - * `PATH` to an absolute executable via `resolveSpawnCommand` (workspace-trust - * safety, see above). The native self-spawn instead uses `process.execPath` - * verbatim — already absolute — and never goes through a shell. Returns the - * shell flag alongside, since Windows package-manager shims (.cmd) still - * need one. - */ -function resolveInstallSpawn( - source: InstallSource, - version: string, - platform: NodeJS.Platform, - options?: { readonly manual?: boolean }, -): { readonly resolvedCmd: string; readonly args: readonly string[]; readonly shell: boolean } | undefined { - const { cmd, args } = spawnForSource(source, version, platform); - if (source === 'native') { - // A user-confirmed install marks the stage as manual so the startup swap - // applies it even when automatic updates are opted out via env. - return { resolvedCmd: cmd, args: options?.manual === true ? [...args, '--manual'] : args, shell: false }; - } - const resolvedCmd = resolveSpawnCommand(cmd, platform); - if (resolvedCmd === undefined) return undefined; - return { resolvedCmd, args, shell: platform === 'win32' }; -} - -// Built per call: the official-installer URL follows the current region. -function thirdPartySourceNote(): string { - return ( - '\nNote: Third-party sources may lag behind the official release.\n' + - `For the latest updates, use the official installer: ${kimiCodeOfficialInstallUrl()}\n` - ); -} +const THIRD_PARTY_SOURCE_NOTE = + '\nNote: Third-party sources may lag behind the official release.\n' + + `For the latest updates, use the official installer: ${KIMI_CODE_OFFICIAL_INSTALL_URL}\n`; export function renderManualUpdateMessage( currentVersion: string, @@ -210,7 +180,7 @@ export function renderManualUpdateMessage( sourceDesc = 'homebrew'; break; case 'native': - sourceDesc = 'native installer'; + sourceDesc = 'native (windows). Auto-update is not supported on this platform.'; break; case 'unsupported': sourceDesc = 'unsupported package manager or layout.'; @@ -221,7 +191,7 @@ export function renderManualUpdateMessage( `(${currentVersion} -> ${target.version}).\n` + `Detected install source: ${sourceDesc}\n` + `To update manually, run: ${installCommand}\n` + - (source === 'homebrew' ? thirdPartySourceNote() : '') + (source === 'homebrew' ? THIRD_PARTY_SOURCE_NOTE : '') ); } @@ -391,44 +361,6 @@ function hasFreshActiveInstall(state: UpdateInstallState, target: UpdateTarget): return Date.now() - startedAt < AUTO_INSTALL_ACTIVE_TTL_MS; } -/** - * A fresh-looking `active` record is not proof of work for native installs: - * the parent that wrote it may have exited before the spawned downloader's - * exit event (or the downloader died before doing anything), and the 6 h TTL - * would then silently block every retry. Past the spawn grace window — the - * worker needs a moment to self-acquire the lock — lock liveness IS the - * truth: held ⇒ a download is running; free ⇒ the record is an orphan and - * the caller may start a new attempt. Package-manager sources have no such - * liveness signal and keep the TTL behavior above. - */ -const NATIVE_INSTALL_SPAWN_GRACE_MS = 60_000; - -async function hasNativeInstallInFlight( - state: UpdateInstallState, - target: UpdateTarget, -): Promise<boolean> { - const active = state.active; - if (active === null || active.version !== target.version) return false; - const startedAt = Date.parse(active.startedAt); - if (Number.isFinite(startedAt) && Date.now() - startedAt < NATIVE_INSTALL_SPAWN_GRACE_MS) { - return true; - } - const probe = await tryAcquireUpdateInstallLock({ version: target.version }); - if (probe === null) return true; - await probe.release().catch(() => {}); - return false; -} - -async function hasInstallInFlight( - source: InstallSource, - state: UpdateInstallState, - target: UpdateTarget, -): Promise<boolean> { - return source === 'native' - ? hasNativeInstallInFlight(state, target) - : hasFreshActiveInstall(state, target); -} - async function showPendingBackgroundInstallNotice( state: UpdateInstallState, currentVersion: string, @@ -492,23 +424,17 @@ async function showPendingBackgroundInstallNotice( /** * `KIMI_CODE_NO_AUTO_UPDATE` (or the legacy `KIMI_CLI_NO_AUTO_UPDATE` alias) - * fully disables automatic update behavior — no check, no background install, - * no prompt, and no staged-swap at startup (see `native-swap.ts`). Migrated - * from kimi-cli, where the variable gated all auto-update behavior. Accepts - * the usual truthy values (`1`/`true`/`yes`/`on`). + * fully disables the update preflight — no check, no background install, no + * prompt. Migrated from kimi-cli, where the variable gated all auto-update + * behavior. Accepts the usual truthy values (`1`/`true`/`yes`/`on`). */ -export function isAutoUpdateDisabledByEnv(env: NodeJS.ProcessEnv = process.env): boolean { +function isAutoUpdateDisabledByEnv(env: NodeJS.ProcessEnv = process.env): boolean { const truthy = (value?: string): boolean => ['1', 'true', 'yes', 'on'].includes((value ?? '').trim().toLowerCase()); return truthy(env['KIMI_CODE_NO_AUTO_UPDATE']) || truthy(env['KIMI_CLI_NO_AUTO_UPDATE']); } -/** - * The persisted `[upgrade].auto_install` preference (defaults to true when - * the config cannot be read). Gates the passive background install — and the - * startup swap of automatically staged payloads (see `native-swap.ts`). - */ -export async function shouldAutoInstallUpdates(): Promise<boolean> { +async function shouldAutoInstallUpdates(): Promise<boolean> { try { const config = await loadTuiConfig(); return config.upgrade.autoInstall; @@ -582,23 +508,19 @@ export async function installUpdate( version: string, platform: NodeJS.Platform, ): Promise<void> { - // installUpdate only runs after an explicit user choice (the `upgrade` - // command or the interactive prompt) — mark the stage as manual. - const spawnTarget = resolveInstallSpawn(source, version, platform, { manual: true }); - if (spawnTarget === undefined) { - throw new Error( - `${spawnForSource(source, version, platform).cmd} was not found in PATH; cannot install the update`, - ); + const { cmd, args } = spawnForSource(source, version, platform); + const resolvedCmd = resolveSpawnCommand(cmd, platform); + if (resolvedCmd === undefined) { + throw new Error(`${cmd} was not found in PATH; cannot install the update`); } await new Promise<void>((resolve, reject) => { // Windows package managers (npm/pnpm/yarn) are .cmd shims. Since the // CVE-2024-27980 fix, Node throws EINVAL when spawning a .cmd/.bat without // a shell, so run through the shell on win32. The version is a validated - // semver and the package name is a constant, so args are shell-safe. The - // native self-spawn is an .exe and needs no shell. - const child = spawn(spawnTarget.resolvedCmd, [...spawnTarget.args], { + // semver and the package name is a constant, so args are shell-safe. + const child = spawn(resolvedCmd, [...args], { stdio: 'inherit', - shell: spawnTarget.shell ? true : undefined, + shell: platform === 'win32' ? true : undefined, }); child.once('error', reject); child.once('exit', (code, signal) => { @@ -607,7 +529,7 @@ export async function installUpdate( return; } const detail = signal !== null ? `signal ${signal}` : `code ${String(code)}`; - reject(new Error(`update install exited with ${detail}`)); + reject(new Error(`${cmd} exited with ${detail}`)); }); }); } @@ -622,20 +544,13 @@ async function startBackgroundInstall( logger: UpdateLogger, rolloutTelemetry: RolloutTelemetry, ): Promise<void> { - // The native self-spawned downloader holds the install lock itself for the - // whole download — taking it here too would race the child (it starts before - // this function's finally releases) into a false success. Package-manager - // installs keep the outer lock, which only guards against duplicate spawns. - const lock = - source === 'native' - ? { filePath: '', release: async (): Promise<void> => {} } - : await tryAcquireUpdateInstallLock({ version: target.version }); + const lock = await tryAcquireUpdateInstallLock({ version: target.version }); if (lock === null) return; try { const freshState = await readUpdateInstallState().catch(() => state); if ( - (await hasInstallInFlight(source, freshState, target)) || + hasFreshActiveInstall(freshState, target) || failureAttemptsFor(freshState, target) >= AUTO_INSTALL_FAILURE_PROMPT_THRESHOLD ) { return; @@ -662,7 +577,7 @@ async function startBackgroundInstall( source, }); - const spawnTarget = resolveInstallSpawn(source, target.version, platform); + const { cmd, args } = spawnForSource(source, target.version, platform); let settled = false; const finish = (succeeded: boolean): void => { @@ -714,17 +629,18 @@ async function startBackgroundInstall( }); }; - if (spawnTarget === undefined) { + const resolvedCmd = resolveSpawnCommand(cmd, platform); + if (resolvedCmd === undefined) { // The package manager cannot be resolved to an absolute path outside // the cwd — record a normal install failure instead of spawning a bare // command name that Windows would resolve into the untrusted workspace. finish(false); return; } - const child = spawn(spawnTarget.resolvedCmd, [...spawnTarget.args], { + const child = spawn(resolvedCmd, [...args], { detached: true, stdio: 'ignore', - shell: spawnTarget.shell ? true : undefined, + shell: platform === 'win32' ? true : undefined, // On Windows a detached child gets its own console window; with shell:true // that window would flash during a passive background update. Hide it so // the silent updater stays silent. @@ -754,7 +670,7 @@ async function tryStartAutomaticBackgroundInstall( if (failureAttemptsFor(installState, target) >= AUTO_INSTALL_FAILURE_PROMPT_THRESHOLD) { return false; } - if (!(await hasInstallInFlight(source, installState, target))) { + if (!hasFreshActiveInstall(installState, target)) { await startBackgroundInstall( installState, currentVersion, diff --git a/apps/kimi-code/src/cli/v2/run-v2-print.ts b/apps/kimi-code/src/cli/v2/run-v2-print.ts index 299e926ca..2585336ce 100644 --- a/apps/kimi-code/src/cli/v2/run-v2-print.ts +++ b/apps/kimi-code/src/cli/v2/run-v2-print.ts @@ -7,7 +7,7 @@ * - `bootstrap()`s the app scope, * - creates / resumes a session and its main agent via native services, * - subscribes to the main agent's per-agent `IEventBus` and renders the - * native `Event2` stream (payloads are already v1-protocol-shaped), + * native `DomainEvent` stream (payloads are already v1-protocol-shaped), * - drives a turn through `IAgentPromptService.enqueue()` and awaits * `Turn.result` for authoritative completion, * - applies the print-mode background policy (config-driven, v1-aligned: @@ -19,8 +19,7 @@ import { readFile } from 'node:fs/promises'; import { - AgentCron, - AgentGoal, + IAgentGoalService, IAgentLifecycleService, IAgentPermissionModeService, IAgentProfileService, @@ -31,12 +30,13 @@ import { IConfigService, IEventBus, IOAuthToolkit, + ISessionCronService, ISessionIndex, - ISessionManager, + ISessionLifecycleService, + IWorkspaceLifecycleService, ITelemetryService, PRINT_MAX_TURNS_DEFAULT, PRINT_WAIT_CEILING_S_DEFAULT, - agentContextOf, applyPrintModeConfigDefaults, bootstrap, createCloudAppender, @@ -50,7 +50,7 @@ import { resolveLoggingConfig, resolvePrintBackgroundMode, setClampedTimeout, - type Event2, + type DomainEvent, type IAgentScopeHandle, type ISessionScopeHandle, type LoopRunResult, @@ -58,20 +58,6 @@ import { type Scope, } from '@moonshot-ai/agent-core-v2'; import { createKimiDefaultHeaders, createKimiDeviceId } from '@moonshot-ai/kimi-code-oauth'; -import type { GoalUpdated } from '@moonshot-ai/agent-core-v2/features/goal/goalOps'; -import type { TurnEnded } from '@moonshot-ai/agent-core-v2/agent/loop/turnOps'; -import type { - AssistantDelta, - ThinkingDelta, - ToolCallDelta, -} from '@moonshot-ai/agent-core-v2/agent/loop/turnEvents'; -import type { TurnStepRetrying } from '@moonshot-ai/agent-core-v2/agent/stepRetry/stepRetryService'; -import type { HookResult } from '@moonshot-ai/agent-core-v2/features/externalHooks/agent/agentExternalHooksService'; -import type { - ToolCallStarted, - ToolProgress, - ToolResultEvent, -} from '@moonshot-ai/agent-core-v2/agent/toolExecutor/toolExecutorEvents'; import { resolve } from 'pathe'; import { @@ -276,7 +262,7 @@ async function resolveNativeSession( defaultModel: string | undefined, stderr: PromptOutput, ): Promise<ResolvedNativeSession> { - const sessions = app.accessor.get(ISessionManager); + const workspaceLifecycle = app.accessor.get(IWorkspaceLifecycleService); const index = app.accessor.get(ISessionIndex); // `--agent` selects a catalog profile by name; otherwise `--agent-file` @@ -357,8 +343,7 @@ async function resolveNativeSession( throw new Error(`Session "${opts.session}" was created under a different directory.`); } const session = await resumeById(opts.session); - const agentContext = await ensureMainAgent(session); - const agent = session.accessor.get(IAgentLifecycleService).handleOf(agentContext.agentId)!; + const agent = await ensureMainAgent(session); const profile = agent.accessor.get(IAgentProfileService); await applyModelOverride(profile, opts.model); const currentModel = profile.getModel(); @@ -377,8 +362,7 @@ async function resolveNativeSession( const previous = page.items.find((summary) => summary.cwd === workDir); if (previous !== undefined) { const session = await resumeById(previous.id); - const agentContext = await ensureMainAgent(session); - const agent = session.accessor.get(IAgentLifecycleService).handleOf(agentContext.agentId)!; + const agent = await ensureMainAgent(session); const profile = agent.accessor.get(IAgentProfileService); await applyModelOverride(profile, opts.model); const currentModel = profile.getModel(); @@ -395,7 +379,8 @@ async function resolveNativeSession( } const model = requireConfiguredModel(opts.model, defaultModel); - const session = await sessions.create({ + const handler = await workspaceLifecycle.handlerFor({ root: workDir }); + const session = await handler.accessor.get(ISessionLifecycleService).create({ workDir, additionalDirs: opts.addDirs?.length ? opts.addDirs : undefined, mainAgentBinding: { @@ -403,8 +388,7 @@ async function resolveNativeSession( model, }, }); - const agentContext = await ensureMainAgent(session); - const agent = session.accessor.get(IAgentLifecycleService).handleOf(agentContext.agentId)!; + const agent = await ensureMainAgent(session); agent.accessor.get(IAgentPermissionModeService).setMode('auto'); return { session, @@ -432,12 +416,12 @@ async function runNativeTurn( await agent.accessor.get(IAuthSummaryService).ensureReady(); const turnEndings = createPrintTurnEndings(); - const subscription = agent.accessor.get(IEventBus).subscribe((event: Event2<any>) => { + const subscription = agent.accessor.get(IEventBus).subscribe((event: DomainEvent) => { dispatchNativeEvent(writer, event, stderr); // Arm the turn-endings collector before `turn.result` settles so a // background-task completion that steers a new turn right after the main // turn ends cannot have its `turn.ended` slip past the policy loop. - if (event.type === 'turn.ended') turnEndings.push(event as TurnEnded); + if (event.type === 'turn.ended') turnEndings.push(event); }); try { const handle = await agent.accessor.get(IAgentPromptService).enqueue({ @@ -469,12 +453,8 @@ async function runNativeTurn( if (result.type === 'completed') { const configService = app.accessor.get(IConfigService); const taskConfig = resolveAgentTaskConfig(configService); - const goalService = session.accessor - .get(IAgentLifecycleService) - .resolve(agentContextOf(agent), AgentGoal); - const cronService = session.accessor - .get(IAgentLifecycleService) - .resolve(agentContextOf(agent), AgentCron); + const goalService = agent.accessor.get(IAgentGoalService); + const cronService = session.accessor.get(ISessionCronService); try { await applyPrintBackgroundPolicy({ mode: resolvePrintBackgroundMode(configService), @@ -527,20 +507,19 @@ async function runNativeGoal( stderr: PromptOutput, ): Promise<void> { requireConfiguredModel(model); - const goalService = session.accessor - .get(IAgentLifecycleService) - .resolve(agentContextOf(agent), AgentGoal); + const goalService = agent.accessor.get(IAgentGoalService); await goalService.createGoal({ objective: goal.objective, replace: goal.replace, }); let completedSnapshot: { readonly status: string } | null = null; - const subscription = agent.accessor.get(IEventBus).subscribe((event: Event2<any>) => { - if (event.type === 'goal.updated') { - const updated = event as unknown as GoalUpdated; - if (updated.change?.kind === 'completion' && updated.snapshot !== null) { - completedSnapshot = updated.snapshot; - } + const subscription = agent.accessor.get(IEventBus).subscribe((event: DomainEvent) => { + if ( + event.type === 'goal.updated' && + event.change?.kind === 'completion' && + event.snapshot !== null + ) { + completedSnapshot = event.snapshot; } }); try { @@ -561,7 +540,7 @@ async function runNativeGoal( function dispatchNativeEvent( writer: PromptTurnWriter, - event: Event2<any>, + event: DomainEvent, stderr: PromptOutput, ): void { switch (event.type) { @@ -571,43 +550,35 @@ function dispatchNativeEvent( return; case 'turn.step.retrying': writer.discardAssistant(); - writer.writeRetrying(event as unknown as TurnStepRetrying); + writer.writeRetrying(event); return; case 'assistant.delta': - writer.writeAssistantDelta((event as unknown as AssistantDelta).delta); + writer.writeAssistantDelta(event.delta); return; case 'hook.result': - writer.writeHookResult(event as unknown as HookResult); + writer.writeHookResult(event); return; case 'thinking.delta': - writer.writeThinkingDelta((event as unknown as ThinkingDelta).delta); + writer.writeThinkingDelta(event.delta); return; - case 'tool.call.started': { - const started = event as unknown as ToolCallStarted; - writer.writeToolCall(started.toolCallId, started.name, started.args); + case 'tool.call.started': + writer.writeToolCall(event.toolCallId, event.name, event.args); return; - } - case 'tool.call.delta': { - const delta = event as unknown as ToolCallDelta; - writer.writeToolCallDelta(delta.toolCallId, delta.name, delta.argumentsPart); + case 'tool.call.delta': + writer.writeToolCallDelta(event.toolCallId, event.name, event.argumentsPart); return; - } - case 'tool.result': { - const result = event as unknown as ToolResultEvent; - writer.writeToolResult(result.toolCallId, result.output); + case 'tool.result': + writer.writeToolResult(event.toolCallId, event.output); return; - } - case 'tool.progress': { - const progress = (event as unknown as ToolProgress).update; - if (progress.text !== undefined && progress.text.length > 0) { - stderr.write(progress.text.endsWith('\n') ? progress.text : `${progress.text}\n`); + case 'tool.progress': + if (event.update.text !== undefined && event.update.text.length > 0) { + stderr.write(event.update.text.endsWith('\n') ? event.update.text : `${event.update.text}\n`); } return; - } } } -export type PrintTurnEnding = TurnEnded; +export type PrintTurnEnding = Extract<DomainEvent, { type: 'turn.ended' }>; /** * Source of `turn.ended` events for the print steer loop. `next` resolves with @@ -831,10 +802,7 @@ function formatTurnEndingFailure(ending: PrintTurnEnding): string { function countPendingBackgroundTasks(session: ISessionScopeHandle): number { let count = 0; - const agentManager = session.accessor.get(IAgentLifecycleService); - for (const agent of agentManager.list()) { - const handle = agentManager.handleOf(agent.agentId); - if (handle === undefined) continue; + for (const handle of session.accessor.get(IAgentLifecycleService).list()) { count += handle.accessor.get(IAgentTaskService).list(true).length; } return count; @@ -856,10 +824,7 @@ async function drainBackgroundTasks( const batch: Promise<unknown>[] = []; const suppressions: Promise<void>[] = []; let activeCount = 0; - const agentManager = session.accessor.get(IAgentLifecycleService); - for (const agent of agentManager.list()) { - const handle = agentManager.handleOf(agent.agentId); - if (handle === undefined) continue; + for (const handle of session.accessor.get(IAgentLifecycleService).list()) { const taskService = handle.accessor.get(IAgentTaskService); for (const task of taskService.list(true)) { activeCount++; diff --git a/apps/kimi-code/src/constant/app.ts b/apps/kimi-code/src/constant/app.ts index 328b8190e..9cccb3634 100644 --- a/apps/kimi-code/src/constant/app.ts +++ b/apps/kimi-code/src/constant/app.ts @@ -1,7 +1,5 @@ import { ErrorCodes } from '@moonshot-ai/kimi-code-sdk'; -import { currentKimiProfile } from '#/utils/region'; - export const PRODUCT_NAME = 'Kimi Code'; export const CLI_COMMAND_NAME = 'kimi'; export const PROCESS_NAME = 'kimi-code'; @@ -55,12 +53,6 @@ export const KIMI_CODE_UPDATE_INSTALL_STATE_FILE_NAME = 'install.json'; export const KIMI_CODE_UPDATE_INSTALL_LOCK_FILE_NAME = 'install.lock'; export const KIMI_CODE_UPDATE_ROLLOUT_LOG_FILE_NAME = 'rollout.log'; export const KIMI_CODE_PLUGIN_UPDATE_NOTICE_STATE_FILE_NAME = 'plugin-notices.json'; -// Native staged update: the staged binary + metadata live next to the running -// executable (`<exe dir>/.staging/`); the re-exec guard env breaks the -// swap → re-exec → swap loop. -export const KIMI_CODE_NATIVE_STAGING_DIR_NAME = '.staging'; -export const KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME = 'staged.json'; -export const KIMI_CODE_UPDATE_REEXEC_ENV = 'KIMI_CODE_UPDATE_REEXEC'; export const KIMI_CODE_INPUT_HISTORY_DIR_NAME = 'user-history'; export const KIMI_CODE_BANNER_DIR_NAME = 'banner'; export const KIMI_CODE_BANNER_STATE_FILE_NAME = 'state.json'; @@ -76,9 +68,7 @@ export const OAUTH_LOGIN_REQUIRED_CODE = ErrorCodes.AUTH_LOGIN_REQUIRED; export const FEEDBACK_ISSUE_URL = 'https://github.com/MoonshotAI/kimi-code/issues'; // Sign-up / sign-in page offered to signed-out users so they can create an // account and submit feedback through the authenticated channel next time. -export function kimiCodeSignupUrl(): string { - return `${currentKimiProfile().siteBase}/code`; -} +export const KIMI_CODE_SIGNUP_URL = 'https://www.kimi.com/code'; // Sent in the feedback `version` field so the backend can distinguish this // TypeScript client from clients that send a bare version. @@ -88,59 +78,24 @@ export const FEEDBACK_VERSION_PREFIX = 'kimi-code-'; export const FEEDBACK_TELEMETRY_EVENT = 'feedback_submitted'; // CDN source of truth: all version checks and native install scripts pull from here. -// The off-session endpoints derive from the current region profile so a -// global login points at the .ai deployment; they are resolved per call so -// a region switch (login/logout + refreshKimiRegion) takes effect immediately. -export function kimiCodeCdnBase(): string { - return currentKimiProfile().cdnBase; -} -export function kimiCodeCdnLatestUrl(): string { - return `${kimiCodeCdnBase()}/latest`; -} +export const KIMI_CODE_CDN_BASE = 'https://code.kimi.com/kimi-code'; +export const KIMI_CODE_CDN_LATEST_URL = `${KIMI_CODE_CDN_BASE}/latest`; // Rollout manifest consumed by update checks; the plain-text `/latest` above // stays unchanged forever — already-shipped clients hard-fail on non-semver // bodies, and the CDN install scripts read it for fresh installs. -export function kimiCodeCdnLatestJsonUrl(): string { - return `${kimiCodeCdnBase()}/latest.json`; -} -// Per-release native artifacts: `/binaries/<version>/manifest.json` + -// `/binaries/<version>/kimi-code-<target>[.exe]` — the bare platform binary -// (same layout install.ps1 consumes). -export function kimiCodeCdnBinariesBase(): string { - return `${kimiCodeCdnBase()}/binaries`; -} -// The marketplace env override name lives in the shared agent-core-v2 plugin -// domain (kap-server consumes it from there). Deep-path import: this module is -// evaluated on every CLI invocation, so it must not pull in the engine root. -export { KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV } from '@moonshot-ai/agent-core-v2/app/plugin/marketplace'; -// The CLI-side default catalog derives from the current region profile; the -// env override above takes priority at the call site. -export function kimiCodePluginMarketplaceUrl(): string { - return `${kimiCodeCdnBase()}/plugins/marketplace.json`; -} -// Bound on each background "latest release" lookup when the TUI fills in -// marketplace versions. Without it a stalled connection to github.com hangs -// the version phase for undici's default header timeout (300s). -export const MARKETPLACE_VERSION_LOOKUP_TIMEOUT_MS = 5000; +export const KIMI_CODE_CDN_LATEST_JSON_URL = `${KIMI_CODE_CDN_BASE}/latest.json`; +export const KIMI_CODE_TIPS_BANNER_URL = 'https://cdn.kimi.com/kimi-code-tips/tips.json'; +export const KIMI_CODE_PLUGIN_MARKETPLACE_URL = `${KIMI_CODE_CDN_BASE}/plugins/marketplace.json`; +export const KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV = 'KIMI_CODE_PLUGIN_MARKETPLACE_URL'; // Official plugins whose usage bills against the user's plan quota. Installing // one of these shows a quota note after the install result. export const QUOTA_CONSUMING_PLUGIN_IDS: readonly string[] = ['kimi-datasource']; -export function kimiCodeInstallShUrl(): string { - return `${kimiCodeCdnBase()}/install.sh`; -} -export function kimiCodeInstallPs1Url(): string { - return `${kimiCodeCdnBase()}/install.ps1`; -} +export const KIMI_CODE_INSTALL_SH_URL = `${KIMI_CODE_CDN_BASE}/install.sh`; +export const KIMI_CODE_INSTALL_PS1_URL = `${KIMI_CODE_CDN_BASE}/install.ps1`; // Official download page, referenced by prompt copy that steers users away // from third-party install sources. -export function kimiCodeOfficialInstallUrl(): string { - return `${currentKimiProfile().siteBase}/code`; -} +export const KIMI_CODE_OFFICIAL_INSTALL_URL = 'https://www.kimi.com/code'; // Native install commands, split by platform. Use these for prompt copy and spawn calls only; do not assemble the strings elsewhere. -export function nativeInstallCommandUnix(): string { - return `curl -fsSL ${kimiCodeInstallShUrl()} | bash`; -} -export function nativeInstallCommandWin(): string { - return `irm ${kimiCodeInstallPs1Url()} | iex`; -} +export const NATIVE_INSTALL_COMMAND_UNIX = `curl -fsSL ${KIMI_CODE_INSTALL_SH_URL} | bash`; +export const NATIVE_INSTALL_COMMAND_WIN = `irm ${KIMI_CODE_INSTALL_PS1_URL} | iex`; diff --git a/apps/kimi-code/src/main.ts b/apps/kimi-code/src/main.ts index 37ec0a882..cfcfb0928 100644 --- a/apps/kimi-code/src/main.ts +++ b/apps/kimi-code/src/main.ts @@ -31,12 +31,9 @@ import { runPrompt } from './cli/run-prompt'; import { runShell } from './cli/run-shell'; import { formatStartupError } from './cli/startup-error'; import { runPluginNodeEntry } from './cli/sub/plugin-run-node'; -import { runUpdateDownloadCommand } from './cli/sub/update-download'; import { handleUpgrade } from './cli/sub/upgrade'; import { createCliTelemetryBootstrap, initializeCliTelemetry } from './cli/telemetry'; import { runUpdatePreflight } from './cli/update/preflight'; -import { detectNativeInstall } from './cli/update/source'; -import { maybeRelaunchWithStagedNativeUpdate } from './cli/update/native-swap'; import { createKimiCodeHostIdentity, getVersion } from './cli/version'; import { CLI_SHUTDOWN_TIMEOUT_MS, CLI_UI_MODE, PROCESS_NAME } from './constant/app'; import { cleanupStaleNativeCacheForCurrent } from './native/native-assets'; @@ -147,24 +144,6 @@ const MIGRATE_CLI_OPTIONS: CLIOptions = { export function main(): void { process.title = PROCESS_NAME; installCrashHandlers(); - // A staged native update is swapped in and re-exec'd here, before any other - // initialization, so the user session immediately runs the new binary (and - // the old process never replaces itself while running). Every failure path - // inside falls back to a normal startup with the current exe. - void maybeRelaunchWithStagedNativeUpdate({ - exePath: process.execPath, - argv: process.argv, - env: process.env, - currentVersion: getVersion(), - isNative: detectNativeInstall(), - }) - .catch(() => false) - .then((relaunched) => { - if (!relaunched) bootstrap(); - }); -} - -function bootstrap(): void { // Route all outbound fetch through HTTP_PROXY/HTTPS_PROXY (honoring NO_PROXY) // before any client is constructed. No-op when no proxy variable is set; an // invalid proxy URL is reported and ignored rather than aborting startup. @@ -267,17 +246,6 @@ function bootstrap(): void { process.exit(1); }); }, - (targetVersion, manual) => { - void runUpdateDownloadCommand(targetVersion, manual).then( - (code) => { - process.exit(code); - }, - async (error: unknown) => { - await logStartupFailure('download update', error); - process.exit(1); - }, - ); - }, ); program.parse(process.argv); diff --git a/apps/kimi-code/src/tui/banner/banner-config.ts b/apps/kimi-code/src/tui/banner/banner-config.ts deleted file mode 100644 index 4b0a2e74b..000000000 --- a/apps/kimi-code/src/tui/banner/banner-config.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { z } from 'zod'; - -import { fetchClientConfig, type ClientConfigFetchOptions } from '#/utils/client-configs'; - -/** The tips/banner payload is one named config on the client-configs endpoint. */ -const CONFIG_NAME = 'client_banner'; - -/** The payload keeps the legacy tips.json shape, which banner-provider parses - defensively; the schema only guarantees an object. */ -const bannerConfigSchema = z.looseObject({}); - -export type BannerConfig = z.infer<typeof bannerConfigSchema>; -export type BannerConfigFetchOptions = ClientConfigFetchOptions; - -/** - * Fetches the banner config straight from the endpoint — banners are - * time-sensitive announcements, so no caching layer is used. Any failure - * resolves to `undefined` — callers treat that as "no banner". - */ -export async function getBannerConfig( - options: BannerConfigFetchOptions = {}, -): Promise<BannerConfig | undefined> { - return fetchClientConfig(CONFIG_NAME, bannerConfigSchema, options); -} diff --git a/apps/kimi-code/src/tui/banner/banner-provider.ts b/apps/kimi-code/src/tui/banner/banner-provider.ts index 57536346b..daf54f952 100644 --- a/apps/kimi-code/src/tui/banner/banner-provider.ts +++ b/apps/kimi-code/src/tui/banner/banner-provider.ts @@ -2,9 +2,9 @@ import { createHash } from 'node:crypto'; import { eq, gte, lt, valid } from 'semver'; +import { KIMI_CODE_TIPS_BANNER_URL } from '#/constant/app'; import type { BannerDisplay, BannerState } from '#/tui/types'; -import { getBannerConfig } from './banner-config'; import type { BannerDisplayState } from './state'; interface BannerVersionFields { @@ -19,11 +19,8 @@ interface TipsBannerFallbackItem extends BannerVersionFields { banner_title?: string | null; banner_maintext?: string; banner_subtext?: string | null; - banner_start_time?: string | null; - banner_end_time?: string | null; banner_display?: unknown; banner_display_ttl_hours?: unknown; - banner_platform?: string | null; } interface TipsBannerJson extends BannerVersionFields { @@ -38,7 +35,6 @@ interface TipsBannerJson extends BannerVersionFields { banner_display_ttl_hours?: unknown; banner_fallback_enabled?: boolean; banner_fallback_list?: unknown[]; - banner_platform?: string | null; } interface BannerHashInput { @@ -133,15 +129,6 @@ function meetsVersion(banner: BannerVersionFields, clientVersion: string): boole ); } -/** The CLI shows banners targeting every platform (missing / empty / 'all') - or the CLI itself; any other platform value ('desktop', 'web', …) hides - the banner here. */ -function meetsPlatform(value: unknown): boolean { - if (typeof value !== 'string') return true; - const platform = value.trim().toLowerCase(); - return platform === '' || platform === 'all' || platform === 'cli'; -} - function parseBannerDisplay(value: unknown): BannerDisplay { if (value === 'once') return 'once'; if (value === 'cooldown') return 'cooldown'; @@ -211,7 +198,6 @@ function pickActiveBanner( ): BannerState | null { if (json.banner_enabled !== true) return null; if (!meetsVersion(json, clientVersion)) return null; - if (!meetsPlatform(json.banner_platform)) return null; const start = parseDate(json.banner_start_time); const end = parseDate(json.banner_end_time); if (!isWithinWindow(start, end, now)) return null; @@ -233,7 +219,6 @@ function pickActiveBanner( function pickFallbackCandidates( json: TipsBannerJson, clientVersion: string, - now: Date, ): BannerState[] { if (json.banner_fallback_enabled !== true) return []; const list = Array.isArray(json.banner_fallback_list) ? json.banner_fallback_list : []; @@ -243,10 +228,6 @@ function pickFallbackCandidates( const item = raw as TipsBannerFallbackItem; if (item.enabled !== true) continue; if (!meetsVersion(item, clientVersion)) continue; - if (!meetsPlatform(item.banner_platform)) continue; - const start = parseDate(item.banner_start_time); - const end = parseDate(item.banner_end_time); - if (!isWithinWindow(start, end, now)) continue; const mainText = normalizeText(item.banner_maintext); if (mainText === null) continue; const display = parseBannerDisplay(item.banner_display); @@ -258,8 +239,6 @@ function pickFallbackCandidates( subText: item.banner_subtext, display, ttlHours: display === 'cooldown' ? parseBannerDisplayTtlHours(item.banner_display_ttl_hours) : undefined, - startTime: item.banner_start_time, - endTime: item.banner_end_time, }), ); } @@ -275,10 +254,9 @@ function pickRandomCandidate(candidates: BannerState[], random: () => number): B function pickFallbackBanner( json: TipsBannerJson, clientVersion: string, - now: Date, random: () => number, ): BannerState | null { - return pickRandomCandidate(pickFallbackCandidates(json, clientVersion, now), random); + return pickRandomCandidate(pickFallbackCandidates(json, clientVersion), random); } function parseShownAt(value: string | undefined): Date | null { @@ -314,7 +292,7 @@ export function selectBannerState( const typed = typeof json === 'object' && json !== null ? (json as TipsBannerJson) : {}; return ( pickActiveBanner(typed, clientVersion, now) ?? - pickFallbackBanner(typed, clientVersion, now, random) + pickFallbackBanner(typed, clientVersion, random) ); } @@ -328,29 +306,44 @@ export function selectDisplayableBanner({ const typed = typeof json === 'object' && json !== null ? (json as TipsBannerJson) : {}; const active = pickActiveBanner(typed, clientVersion, now); if (active !== null && shouldDisplayBanner(active, state, now)) return active; - const candidates = pickFallbackCandidates(typed, clientVersion, now).filter((candidate) => + const candidates = pickFallbackCandidates(typed, clientVersion).filter((candidate) => shouldDisplayBanner(candidate, state, now), ); return pickRandomCandidate(candidates, random); } export class BannerProvider { - constructor(private readonly clientVersion: string) {} + constructor( + private readonly clientVersion: string, + private readonly url: string = KIMI_CODE_TIPS_BANNER_URL, + ) {} - async load(options: BannerProviderLoadOptions = {}): Promise<BannerState | null> { - // getBannerConfig never throws; undefined means "config unavailable". - const json = await getBannerConfig(); - if (json === undefined) return null; - const now = options.now ?? new Date(); - const random = options.random ?? Math.random; - return options.state === undefined - ? selectBannerState(json, this.clientVersion, now, random) - : selectDisplayableBanner({ - json, - clientVersion: this.clientVersion, - now, - random, - state: options.state, - }); + async load( + fetchImpl: typeof fetch = fetch, + options: BannerProviderLoadOptions = {}, + ): Promise<BannerState | null> { + try { + const controller = new AbortController(); + const timeout = setTimeout(() => { + controller.abort(); + }, 3000); + const response = await fetchImpl(this.url, { signal: controller.signal }); + clearTimeout(timeout); + if (!response.ok) return null; + const json = await response.json(); + const now = options.now ?? new Date(); + const random = options.random ?? Math.random; + return options.state === undefined + ? selectBannerState(json, this.clientVersion, now, random) + : selectDisplayableBanner({ + json, + clientVersion: this.clientVersion, + now, + random, + state: options.state, + }); + } catch { + return null; + } } } diff --git a/apps/kimi-code/src/tui/commands/auth.ts b/apps/kimi-code/src/tui/commands/auth.ts index 197c141d4..a44b4fab5 100644 --- a/apps/kimi-code/src/tui/commands/auth.ts +++ b/apps/kimi-code/src/tui/commands/auth.ts @@ -4,7 +4,6 @@ import { filterModelsByPrefix, getOpenPlatformById, OpenPlatformApiError, - type KimiRegion, type ManagedKimiCodeModelInfo, type ManagedKimiConfigShape, type OpenPlatformDefinition, @@ -14,10 +13,6 @@ import { log } from '@moonshot-ai/kimi-code-sdk'; import type { ChoiceOption } from '../components/dialogs/choice-picker'; import { DEFAULT_OAUTH_PROVIDER_NAME, PRODUCT_NAME } from '../constant/kimi-tui'; import { formatErrorMessage } from '../utils/event-payload'; -import { - KIMI_CODE_GLOBAL_PLATFORM_VALUE, - refreshKimiRegion, -} from '#/utils/region'; import type { LoginProgressSpinnerHandle } from '../types'; import { promptApiKey, @@ -35,9 +30,8 @@ export async function handleLoginCommand(host: SlashCommandHost): Promise<void> const platformId = await promptPlatformSelection(host); if (platformId === undefined) return; - if (platformId === 'kimi-code' || platformId === KIMI_CODE_GLOBAL_PLATFORM_VALUE) { - const region: KimiRegion = platformId === KIMI_CODE_GLOBAL_PLATFORM_VALUE ? 'global' : 'mainland-cn'; - await handleKimiCodeOAuthLogin(host, region); + if (platformId === 'kimi-code') { + await handleKimiCodeOAuthLogin(host); return; } @@ -46,10 +40,7 @@ export async function handleLoginCommand(host: SlashCommandHost): Promise<void> await handleOpenPlatformLogin(host, platform); } -async function handleKimiCodeOAuthLogin( - host: SlashCommandHost, - region: KimiRegion, -): Promise<void> { +async function handleKimiCodeOAuthLogin(host: SlashCommandHost): Promise<void> { const status = await host.harness.auth.status(DEFAULT_OAUTH_PROVIDER_NAME); const alreadyLoggedIn = status.providers.some( (provider) => provider.providerName === DEFAULT_OAUTH_PROVIDER_NAME && provider.hasToken, @@ -62,17 +53,12 @@ async function handleKimiCodeOAuthLogin( }; host.cancelInFlight = cancelLogin; try { - // The facade maps region → profile hosts (env overrides keep priority); - // 'mainland-cn' is passed explicitly too so switching back overrides a - // persisted global login. await host.harness.auth.login(DEFAULT_OAUTH_PROVIDER_NAME, { signal: controller.signal, - region, onDeviceCode: (data) => { spinner = host.showLoginAuthorizationPrompt(data); }, }); - refreshKimiRegion(); spinner?.stop({ ok: true, label: 'Logged in.' }); spinner = undefined; try { @@ -241,6 +227,7 @@ export async function handleLogoutCommand(host: SlashCommandHost): Promise<void> if (target === currentProvider) { await host.authFlow.refreshConfigAfterLogout(); + await host.authFlow.clearActiveSessionAfterLogout(); } else { const updated = await host.harness.getConfig({ reload: true }); host.setAppState({ @@ -248,7 +235,6 @@ export async function handleLogoutCommand(host: SlashCommandHost): Promise<void> availableProviders: updated.providers ?? {}, }); } - refreshKimiRegion(); host.track('logout', { provider: target }); const label = target === DEFAULT_OAUTH_PROVIDER_NAME ? PRODUCT_NAME : target; diff --git a/apps/kimi-code/src/tui/commands/btw.ts b/apps/kimi-code/src/tui/commands/btw.ts index 72b3b5806..a55ceca0a 100644 --- a/apps/kimi-code/src/tui/commands/btw.ts +++ b/apps/kimi-code/src/tui/commands/btw.ts @@ -1,6 +1,5 @@ import { LLM_NOT_SET_MESSAGE } from '../constant/kimi-tui'; import { formatErrorMessage } from '../utils/event-payload'; -import { extractInlineSkillActivations } from '../utils/inline-skill-tokens'; import type { SlashCommandHost } from './dispatch'; export async function handleBtwCommand(host: SlashCommandHost, args: string): Promise<void> { @@ -14,14 +13,7 @@ export async function handleBtwCommand(host: SlashCommandHost, args: string): Pr try { const agentId = await session.startBtw(); - const activations = host.engineV2 - ? extractInlineSkillActivations(prompt, host.skillCommandMap, { includeLeading: true }) - : []; - host.btwPanelController.open( - agentId, - prompt, - activations.length > 0 ? activations : undefined, - ); + host.btwPanelController.open(agentId, prompt); } catch (error) { host.showError(`Failed to start /btw: ${formatErrorMessage(error)}`); } diff --git a/apps/kimi-code/src/tui/commands/config.ts b/apps/kimi-code/src/tui/commands/config.ts index 003ec54b7..a3a0f9999 100644 --- a/apps/kimi-code/src/tui/commands/config.ts +++ b/apps/kimi-code/src/tui/commands/config.ts @@ -1,8 +1,8 @@ import { effectiveModelAlias, - PRIMARY_SUBAGENT_MODEL_CHOICE, SECONDARY_DERIVED_MODEL_ALIAS, type ExperimentalFeatureState, + type KimiConfig, type ModelAlias, type PermissionMode, type Session, @@ -57,7 +57,6 @@ export function currentTuiConfig(host: Pick<SlashCommandHost, 'state'>): TuiConf theme: host.state.appState.theme, editorCommand: host.state.appState.editorCommand, disablePasteBurst: host.state.appState.disablePasteBurst ?? DEFAULT_TUI_CONFIG.disablePasteBurst, - renderLatex: host.state.appState.renderLatex ?? DEFAULT_TUI_CONFIG.renderLatex ?? true, cacheExpiryHint: host.state.appState.cacheExpiryHint ?? DEFAULT_TUI_CONFIG.cacheExpiryHint, notifications: host.state.appState.notifications, upgrade: host.state.appState.upgrade, @@ -270,15 +269,6 @@ export async function handleSecondaryModelCommand(host: SlashCommandHost, args: const alias = args.trim(); await refreshModelsForPicker(host); const models = pickerModelsForHost(host); - // The pool reserves `primary` as the symbolic "caller's own model" choice — - // a user alias with that name can never be the subagent default. - delete models[PRIMARY_SUBAGENT_MODEL_CHOICE]; - if (alias === PRIMARY_SUBAGENT_MODEL_CHOICE) { - host.showError( - `"${PRIMARY_SUBAGENT_MODEL_CHOICE}" is reserved by the subagent model pool (it always binds the caller's own model) — rename the [models] alias to use it here.`, - ); - return; - } if (Object.keys(models).length === 0) { host.showNotice( 'No models configured', @@ -291,10 +281,7 @@ export async function handleSecondaryModelCommand(host: SlashCommandHost, args: return; } const secondary = (await host.harness.getConfig()).secondaryModel; - // The v2 engine honors a lone legacy `model` key as the fallback pool - // default — reflect it as the picker's current value. - const current = secondary?.defaultModel ?? secondary?.model ?? ''; - showSecondaryModelPicker(host, models, current, alias.length > 0 ? alias : undefined); + showSecondaryModelPicker(host, models, secondary?.model ?? '', secondary?.defaultEffort, alias); } export async function handleEffortCommand(host: SlashCommandHost, args: string): Promise<void> { @@ -440,8 +427,8 @@ async function applyEditorChoice(host: SlashCommandHost, value: string): Promise /** * The models a picker may offer: the user's configured aliases with * host-effective provider resolution applied, minus the synthesized - * `__secondary__` derived entry — a runtime artifact of the v1 engine's - * `[secondary_model]` recipe that must never be selectable as a model. + * `__secondary__` derived entry — a runtime artifact of the `[secondary_model]` + * recipe that must never be selectable as a primary or secondary model. */ function pickerModelsForHost(host: SlashCommandHost): Record<string, ModelAlias> { return Object.fromEntries( @@ -597,7 +584,7 @@ async function persistModelSelection( const model = host.state.appState.availableModels[alias]; const full = thinkingEffortToConfig( effort, - model === undefined ? undefined : effectiveModelForHost(host, model), + model === undefined ? undefined : effectiveModelForHost(host, model).supportEfforts, ); // Re-confirming the effort shown when the picker opened is not an explicit // choice — persist the model but leave the stored effort preference alone. @@ -617,13 +604,14 @@ async function persistModelSelection( } // --------------------------------------------------------------------------- -// Secondary model (`/secondary-model`) — persists `[secondary_model] default_model` +// Secondary model (`/secondary_model`) // --------------------------------------------------------------------------- function showSecondaryModelPicker( host: SlashCommandHost, models: Record<string, ModelAlias>, currentValue: string, + currentEffort: string | undefined, selectedValue?: string, ): void { host.mountEditorReplacement( @@ -631,14 +619,11 @@ function showSecondaryModelPicker( models, currentValue, selectedValue, - currentThinkingEffort: 'off', - // Subagent pool bindings carry no explicit thinking level, so the picker - // hides the Thinking footer instead of offering a no-op choice. - thinkingControl: false, + currentThinkingEffort: currentEffort ?? 'off', title: ' Select a secondary model (subagents)', - onSelect: ({ alias }) => { + onSelect: ({ alias, thinking }) => { host.restoreEditor(); - void performSecondaryModelSave(host, alias); + void performSecondaryModelSwitch(host, alias, thinking); }, onCancel: () => { host.restoreEditor(); @@ -648,32 +633,65 @@ function showSecondaryModelPicker( } /** - * Persists `[secondary_model] default_model`. When a - * `[secondary_model.models]` pool exists and does not list the alias yet, the - * alias is added with an empty description — the engine requires the default - * to be a pool key. Without a pool the default alone forms an implicit - * single-entry pool, so nothing else is written. No live-apply step: the - * engine resolves the pool per spawn, so the next subagent dispatch picks the - * new value up on its own. + * Persist-first, then live-apply: the synthesized derived entry only exists in + * the core config after a reload. No session-only variant — a session-local + * recipe with patch fields would bind a derived alias the core config cannot + * resolve. */ -async function performSecondaryModelSave(host: SlashCommandHost, alias: string): Promise<void> { +async function performSecondaryModelSwitch( + host: SlashCommandHost, + alias: string, + effort: ThinkingEffort, +): Promise<void> { const displayName = modelDisplayName(alias, host.state.appState.availableModels[alias]); + let updatedConfig: KimiConfig; try { - const config = await host.harness.getConfig({ reload: true }); - const existing = config.secondaryModel?.models; - const patch: { defaultModel: string; models?: Record<string, string> } = { - defaultModel: alias, - }; - if (existing !== undefined) { - patch.models = { ...existing, [alias]: existing[alias] ?? '' }; - } - await host.harness.setConfig({ secondaryModel: patch }); + updatedConfig = await host.harness.setConfig({ + secondaryModel: { model: alias, defaultEffort: effort }, + }); } catch (error) { host.showError(`Failed to save secondary model: ${formatErrorMessage(error)}`); return; } + if (host.session !== undefined) { + try { + await host.session.applyPersistedSecondaryModel(); + } catch (error) { + host.showError( + `Saved ${displayName} as the secondary model, but failed to apply it to this session: ${formatErrorMessage(error)}`, + ); + return; + } + } + host.setAppState({ availableModels: updatedConfig.models ?? {} }); + // Report the effective binding from the reloaded config, not the picked + // value: KIMI_SECONDARY_MODEL / KIMI_SECONDARY_EFFORT override the recipe at + // runtime, and the session binds the overlaid snapshot (mirrors how + // /model displays the effective alias read back from the session). + const effective = updatedConfig.secondaryModel; + const envOverrides: string[] = []; + if (effective?.model !== undefined && effective.model !== alias) { + envOverrides.push(`KIMI_SECONDARY_MODEL=${effective.model}`); + } + if (effective?.defaultEffort !== undefined && effective.defaultEffort !== effort) { + envOverrides.push(`KIMI_SECONDARY_EFFORT=${effective.defaultEffort}`); + } + if (envOverrides.length > 0 && effective?.model !== undefined) { + const effectiveName = modelDisplayName( + effective.model, + updatedConfig.models?.[effective.model], + ); + host.showStatus( + `Saved ${displayName} as the secondary model, but ${envOverrides.join(' and ')} ` + + `overrides it at runtime — subagents bind ${effectiveName} until the env var is unset.`, + 'warning', + ); + return; + } host.showStatus( - `Secondary model set to ${displayName}. Newly spawned subagents will use it by default.`, + host.session === undefined + ? `Secondary model set to ${displayName} with thinking ${effort}; applies to new sessions.` + : `Secondary model set to ${displayName} with thinking ${effort}.`, 'success', ); } @@ -807,12 +825,6 @@ export async function applyExperimentalFeatureChanges( } else { host.showStatus('Experimental features updated.', 'success'); } - if (changes.some((change) => change.id === 'tower')) { - // TowerFeature assembles its tool/profile contributions once at App - // scope construction, so a live flag flip cannot install or retract - // them; only the mode machinery (enter/injection/guards) reacts live. - host.showNotice('Tower mode takes effect after restarting Kimi Code.'); - } host.track('experimental_features_apply', { changed: changes.length }); } catch (error) { host.showError(`Failed to update experimental features: ${formatErrorMessage(error)}`); diff --git a/apps/kimi-code/src/tui/commands/dispatch.ts b/apps/kimi-code/src/tui/commands/dispatch.ts index 05a692d39..b36951c78 100644 --- a/apps/kimi-code/src/tui/commands/dispatch.ts +++ b/apps/kimi-code/src/tui/commands/dispatch.ts @@ -14,16 +14,11 @@ import type { ResolvedTheme } from '../theme/colors'; import type { TUIState } from '../tui-state'; import type { AppState, - InlineSkillActivation, LoginProgressSpinnerHandle, QueuedMessage, TranscriptEntry, } from '../types'; import { formatErrorMessage } from '../utils/event-payload'; -import { - extractInlineSkillActivations, - findInlineSkillTokens, -} from '../utils/inline-skill-tokens'; import { handleLoginCommand, handleLogoutCommand } from './auth'; import { handleBtwCommand } from './btw'; import { handleCopyCommand } from './copy'; @@ -56,7 +51,6 @@ import { import { handleReloadCommand, handleReloadTuiCommand } from './reload'; import type { SkillListSession } from './skills'; import { - canRestoreSubmittedInput, resolveSlashCommandInput, slashBusyMessage, slashCommandBusyReason, @@ -69,9 +63,8 @@ import { handleTitleCommand, } from './session'; import { handleSwarmCommand } from './swarm'; -import { handleTowerCommand } from './tower'; import { handleUndoCommand } from './undo'; -import { handleRemoteControlCommand, handleWebCommand } from './web'; +import { handleWebCommand } from './web'; // --------------------------------------------------------------------------- // Re-exports — keep existing consumers working @@ -97,7 +90,6 @@ export { showSettingsSelector, } from './config'; export { handleSwarmCommand } from './swarm'; -export { handleTowerCommand } from './tower'; export { handleFeedbackCommand, showMcpServers, showStatusReport, showUsage } from './info'; export { handlePluginsCommand } from './plugins'; export { handleReloadCommand, handleReloadTuiCommand } from './reload'; @@ -110,7 +102,7 @@ export { handleTitleCommand, } from './session'; export { handleUndoCommand } from './undo'; -export { handleRemoteControlCommand, handleWebCommand } from './web'; +export { handleWebCommand } from './web'; // --------------------------------------------------------------------------- // Host interface @@ -198,12 +190,6 @@ export interface SlashCommandHost { createNewSession(): Promise<void>; showSessionPicker(): Promise<void>; sendNormalUserInput(text: string): void; - /** - * Submit a prompt that explicitly activates one or more skills inline - * (v2 engine only): all activations ride the same submission as the prompt - * and launch as a single turn. - */ - sendInlineSkillUserInput(text: string, activations: readonly InlineSkillActivation[]): Promise<void>; sendSkillActivation(session: Session, skillName: string, skillArgs: string): void; activatePluginCommand( session: Session, @@ -227,80 +213,12 @@ export interface SlashCommandHost { export function dispatchInput(host: SlashCommandHost, text: string): void { if (parseSlashInput(text) !== null) { - // A leading skill command combined with further inline skill tokens - // (`/skill:a args /skill:b`) is one grouped submission on the v2 engine. - if (host.engineV2 && dispatchInlineSkillCombo(host, text)) { - return; - } void executeSlashCommand(host, text); return; } - // Inline skill tokens anywhere in a plain prompt (v2 engine only); on the - // legacy engine they keep their plain-text meaning. - if (host.engineV2) { - const activations = extractInlineSkillActivations(text, host.skillCommandMap); - if (activations.length > 0) { - void host.sendInlineSkillUserInput(text, activations); - return; - } - } host.sendNormalUserInput(text); } -/** - * Handle a leading-slash input that may be a bundled submission. Returns true - * when the input was claimed, false when it should fall through to the - * regular single-skill slash path. - * - * Bundle rule: two or more known skill tokens with the first one leading the - * input make the whole input one bundled prompt in which every token - * activates with NO args — the mention is the whole interface, and args stay - * a standalone-activation concept (`/skill:a some args` with no other tokens - * keeps its single-skill path). Tokenization is whitespace-generic, so - * space- and newline-separated bundles behave identically. A recognized - * builtin or plugin command always keeps its own path, no matter how many - * skill tokens its arguments mention. - */ -function dispatchInlineSkillCombo(host: SlashCommandHost, text: string): boolean { - // The intent is parsed without the busy flags on purpose: submissions - // through sendInlineSkillUserInput queue while busy — only genuine - // single-skill commands reject. - const intent = resolveSlashCommandInput({ - input: text, - skillCommandMap: host.skillCommandMap, - pluginCommandMap: host.pluginCommandMap, - isStreaming: false, - isCompacting: false, - engineV2: host.engineV2, - }); - if (intent.kind !== 'skill' && intent.kind !== 'message') return false; - - const tokens = findInlineSkillTokens(text, { - isKnownSkill: (commandName) => - host.skillCommandMap.has(commandName) || host.skillCommandMap.has(`skill:${commandName}`), - includeLeading: true, - }); - // The 'message' kind joins the bundle rule because parseSlashInput only - // splits on a literal space: a newline after a leading skill resolves to - // 'message' instead of 'skill', and must not silently drop the leading - // activation. - if (tokens.length >= 2 && tokens[0]!.start === 0) { - const activations = extractInlineSkillActivations(text, host.skillCommandMap, { - includeLeading: true, - }); - void host.sendInlineSkillUserInput(text, activations); - return true; - } - - // An unrecognized leading slash token makes the whole input a plain - // message; scan it for inline skills like any other plain prompt. - if (intent.kind !== 'message') return false; - const activations = extractInlineSkillActivations(text, host.skillCommandMap); - if (activations.length === 0) return false; - void host.sendInlineSkillUserInput(text, activations); - return true; -} - async function executeSlashCommand(host: SlashCommandHost, input: string): Promise<void> { const parsedCommand = parseSlashInput(input); const intent = resolveSlashCommandInput({ @@ -309,7 +227,6 @@ async function executeSlashCommand(host: SlashCommandHost, input: string): Promi pluginCommandMap: host.pluginCommandMap, isStreaming: host.state.appState.streamingPhase !== 'idle', isCompacting: host.state.appState.isCompacting, - engineV2: host.engineV2, }); switch (intent.kind) { @@ -318,9 +235,6 @@ async function executeSlashCommand(host: SlashCommandHost, input: string): Promi case 'blocked': host.track('input_command_invalid', { reason: 'blocked', command: intent.commandName }); host.showError(slashBusyMessage(intent.commandName, intent.reason)); - // The editor buffer was already cleared on submit; give the rejected - // command line back so hand-typed input is not lost. - host.restoreInputText(input); return; case 'invalid': host.track('input_command_invalid', { @@ -396,7 +310,7 @@ async function executeSlashCommand(host: SlashCommandHost, input: string): Promi host.track('clear'); } try { - await handleBuiltInSlashCommand(host, intent.name, intent.args, input); + await handleBuiltInSlashCommand(host, intent.name, intent.args); } catch (error) { host.showError(formatErrorMessage(error)); } @@ -437,16 +351,10 @@ async function handleBuiltInSlashCommand( host: SlashCommandHost, name: BuiltinSlashCommandName, args: string, - input: string, ): Promise<void> { if (host.session === undefined && SESSION_REQUIRING_COMMANDS.has(name)) { const session = await ensureSessionForCommand(host); - if (session === undefined) { - // Creation failed after submit cleared the buffer; give the input - // back unless the user moved on — a newer draft or an opened panel. - if (canRestoreSubmittedInput(host)) host.restoreInputText(input); - return; - } + if (session === undefined) return; // A first prompt may have started a turn while the session was being // created; re-check the availability gate that was resolved before the // await (idle-only commands are blocked while a turn is active). @@ -461,9 +369,6 @@ async function handleBuiltInSlashCommand( resolveSlashCommandAvailability(command, args) === 'idle-only' ) { host.showError(slashBusyMessage(name, busyReason)); - // Same as the dispatch blocked branch: give the cleared input back, - // guarded the same way — session creation awaited above. - if (canRestoreSubmittedInput(host)) host.restoreInputText(input); return; } } @@ -535,7 +440,7 @@ async function handleBuiltInSlashCommand( case 'model': await handleModelCommand(host, args); return; - case 'secondary-model': + case 'secondary_model': await handleSecondaryModelCommand(host, args); return; case 'effort': @@ -577,9 +482,6 @@ async function handleBuiltInSlashCommand( case 'swarm': await handleSwarmCommand(host, args); return; - case 'tower': - await handleTowerCommand(host, args); - return; case 'compact': await handleCompactCommand(host, args); return; @@ -613,9 +515,6 @@ async function handleBuiltInSlashCommand( case 'web': await handleWebCommand(host); return; - case 'remote-control': - await handleRemoteControlCommand(host); - return; default: host.showError(`Unknown slash command: /${String(name)}`); return; diff --git a/apps/kimi-code/src/tui/commands/goal.ts b/apps/kimi-code/src/tui/commands/goal.ts index 169234b45..de790b906 100644 --- a/apps/kimi-code/src/tui/commands/goal.ts +++ b/apps/kimi-code/src/tui/commands/goal.ts @@ -25,7 +25,6 @@ import { type GoalQueueSnapshot, } from '../goal-queue-store'; import { formatErrorMessage } from '../utils/event-payload'; -import { canRestoreSubmittedInput } from './resolve'; import type { SlashCommandHost } from './dispatch'; const MAX_GOAL_OBJECTIVE_LENGTH = 4000; @@ -64,13 +63,7 @@ export type ParsedGoalCommand = } | { readonly kind: 'next-add'; readonly objective: string } | { readonly kind: 'next-manage' } - | { - readonly kind: 'error'; - readonly message: string; - readonly severity?: 'error' | 'hint'; - /** Restore the typed `/goal ...` line into the editor so the input is not lost. */ - readonly restoreInput?: boolean; - }; + | { readonly kind: 'error'; readonly message: string; readonly severity?: 'error' | 'hint' }; const CONTROL_SUBCOMMANDS = new Set(['pause', 'resume', 'cancel']); @@ -121,8 +114,7 @@ export function parseGoalCommand(rawArgs: string): ParsedGoalCommand { if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { return { kind: 'error', - restoreInput: true, - message: `Goal objective is too long (max ${MAX_GOAL_OBJECTIVE_LENGTH} characters). Put long content in a file and reference the file path.`, + message: `Goal objective is too long (max ${MAX_GOAL_OBJECTIVE_LENGTH} characters). Reference long details by file path.`, }; } return { kind: 'create', objective, replace }; @@ -134,12 +126,6 @@ export async function handleGoalCommand(host: SlashCommandHost, args: string): P case 'error': if (parsed.severity === 'hint') host.showStatus(parsed.message); else host.showError(parsed.message); - // Give rejected input back so a long hand-typed objective is not - // lost — unless the user already moved on (a newer draft or an - // opened panel), which is possible after the async lazy-session - // creation on the v2 engine. - if (parsed.restoreInput === true && canRestoreSubmittedInput(host)) - host.restoreInputText(`/goal ${args}`); return; case 'status': await showGoalStatus(host); @@ -181,57 +167,12 @@ function parseNextGoalCommand(tokens: readonly string[]): ParsedGoalCommand { if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { return { kind: 'error', - restoreInput: true, - message: `Goal objective is too long (max ${MAX_GOAL_OBJECTIVE_LENGTH} characters). Put long content in a file and reference the file path.`, + message: `Goal objective is too long (max ${MAX_GOAL_OBJECTIVE_LENGTH} characters). Reference long details by file path.`, }; } return { kind: 'next-add', objective }; } -/** - * Live pre-send check for the main editor: when the typed text is a `/goal` - * create/next command whose objective already exceeds the length limit, - * returns a warning to show while typing — before anything is submitted or - * sent to the server. Returns undefined for non-goal input and for control - * forms (`status`/`pause`/`resume`/`cancel`/`next manage`). - */ -export function goalObjectiveLengthWarning(text: string): string | undefined { - // Submitted text is trimmed before dispatch, so match leading whitespace. - const trimmed = text.trimStart(); - if (!trimmed.startsWith('/goal')) return undefined; - const args = trimmed.slice('/goal'.length); - // parseSlashInput splits the command name at a literal space only, so a - // newline/tab boundary (`/goal⏎…`, `/goalfoo`) is not the goal command. - if (args.length > 0 && args.charAt(0) !== ' ') return undefined; - const objective = extractGoalObjective(args); - if (objective === undefined || objective.length <= MAX_GOAL_OBJECTIVE_LENGTH) return undefined; - return `Goal objective is too long (${objective.length}/${MAX_GOAL_OBJECTIVE_LENGTH} characters); put long content in a file and reference the file path.`; -} - -/** - * Mirrors the parse grammar above: strips `next` / `replace` / `--` and - * returns the objective text, or undefined when the args form a control - * command that carries no objective. - */ -function extractGoalObjective(rawArgs: string): string | undefined { - const args = rawArgs.trim(); - if (args.length === 0 || args === 'status') return undefined; - const tokens = args.split(/\s+/); - const first = tokens[0]; - let index = 0; - if (first === 'next') { - if (tokens.length === 2 && tokens[1] === 'manage') return undefined; - index = 1; - } else { - if (first !== undefined && CONTROL_SUBCOMMANDS.has(first) && tokens.length === 1) { - return undefined; - } - if (tokens[index] === 'replace') index += 1; - } - if (tokens[index] === '--') index += 1; - return tokens.slice(index).join(' ').trim(); -} - async function queueNextGoal( host: SlashCommandHost, parsed: Extract<ParsedGoalCommand, { kind: 'next-add' }>, diff --git a/apps/kimi-code/src/tui/commands/index.ts b/apps/kimi-code/src/tui/commands/index.ts index 6bbffc67b..7449dba9b 100644 --- a/apps/kimi-code/src/tui/commands/index.ts +++ b/apps/kimi-code/src/tui/commands/index.ts @@ -23,15 +23,14 @@ export { showSettingsSelector, } from './config'; export { handleSwarmCommand } from './swarm'; -export { handleTowerCommand } from './tower'; export { handleFeedbackCommand, showMcpServers, showStatusReport, showUsage } from './info'; export { handlePluginsCommand } from './plugins'; export { handleReloadCommand, handleReloadTuiCommand } from './reload'; -export { handleGoalCommand, parseGoalCommand, goalObjectiveLengthWarning } from './goal'; +export { handleGoalCommand, parseGoalCommand } from './goal'; export { goalArgumentCompletions } from './registry'; export { handleForkCommand, handleInitCommand, handleTitleCommand } from './session'; export { handleUndoCommand } from './undo'; -export { handleRemoteControlCommand, handleWebCommand } from './web'; +export { handleWebCommand } from './web'; export { promptApiKey, promptCatalogProviderSelection, diff --git a/apps/kimi-code/src/tui/commands/info.ts b/apps/kimi-code/src/tui/commands/info.ts index 8de248ca8..feccd19ce 100644 --- a/apps/kimi-code/src/tui/commands/info.ts +++ b/apps/kimi-code/src/tui/commands/info.ts @@ -5,7 +5,6 @@ import type { McpServerInfo, SessionStatus, SessionUsage } from '@moonshot-ai/ki import { buildMcpStatusReportLines } from '../components/messages/mcp-status-panel'; import { buildStatusReportLines } from '../components/messages/status-panel'; import { buildUsageReportLines, UsagePanelComponent, type ManagedUsageReport } from '../components/messages/usage-panel'; -import { isExperimentalFlagEnabled } from './experimental-flags'; import { FEEDBACK_ISSUE_URL, FEEDBACK_STATUS_CANCELLED, @@ -18,7 +17,7 @@ import { FEEDBACK_TELEMETRY_EVENT, feedbackIdLine, feedbackSessionLine, - kimiCodeSignupUrl, + KIMI_CODE_SIGNUP_URL, withFeedbackVersionPrefix, } from '../constant/feedback'; import { DEFAULT_OAUTH_PROVIDER_NAME, isManagedUsageProvider } from '../constant/kimi-tui'; @@ -56,7 +55,7 @@ export async function handleFeedbackCommand(host: SlashCommandHost): Promise<voi } if (!signedIn) { host.showStatus(FEEDBACK_STATUS_NOT_SIGNED_IN); - host.showStatus(kimiCodeSignupUrl()); + host.showStatus(KIMI_CODE_SIGNUP_URL); host.showStatus(FEEDBACK_ISSUE_URL); return; } @@ -177,8 +176,6 @@ export async function showStatusReport(host: SlashCommandHost): Promise<void> { thinkingEffort: appState.thinkingEffort, permissionMode: appState.permissionMode, planMode: appState.planMode, - towerMode: appState.towerMode, - towerAvailable: host.engineV2 && isExperimentalFlagEnabled('tower'), contextUsage: appState.contextUsage, contextTokens: appState.contextTokens, maxContextTokens: appState.maxContextTokens, diff --git a/apps/kimi-code/src/tui/commands/plugins.ts b/apps/kimi-code/src/tui/commands/plugins.ts index 80c8931a8..9244c7d25 100644 --- a/apps/kimi-code/src/tui/commands/plugins.ts +++ b/apps/kimi-code/src/tui/commands/plugins.ts @@ -29,23 +29,13 @@ import { import { UsagePanelComponent } from '../components/messages/usage-panel'; import { createMarkdownTheme } from '../theme/pi-tui-theme'; import { formatErrorMessage } from '../utils/event-payload'; -import { createMarkdownOptions } from '../utils/markdown-options'; import { formatPluginSourceLabel, isOfficialPluginInstall, isOfficialPluginSource, } from '../utils/plugin-source-label'; -import { - KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV, - QUOTA_CONSUMING_PLUGIN_IDS, -} from '#/constant/app'; -import { - loadPluginMarketplace, - withBuiltInEntries, - withMarketplaceLatestVersions, - type PluginMarketplace, - type PluginMarketplaceEntry, -} from '#/utils/plugin-marketplace'; +import { KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV, QUOTA_CONSUMING_PLUGIN_IDS } from '#/constant/app'; +import { loadPluginMarketplace, type PluginMarketplaceEntry } from '#/utils/plugin-marketplace'; import { openUrl } from '#/utils/open-url'; import type { SlashCommandHost } from './dispatch'; @@ -354,49 +344,18 @@ async function loadMarketplaceCatalog( source: string | undefined, capabilities: readonly CapabilityStatus[], ): Promise<void> { - const builtInEntries = - host.engineV2 && isDefaultMarketplaceCatalog(source) - ? capabilities.map(capabilityMarketplaceEntry) - : undefined; - let marketplace: PluginMarketplace; - let catalog: PluginMarketplace; try { - // Phase 1: render the catalog as soon as it arrives. Version lookups - // (GitHub releases/latest round trips) must not gate the first paint. - // Keep the raw parsed catalog for phase 2: injecting built-ins first - // would mask the matching catalog entries' GitHub sources behind - // `capability:<id>` rows, making their versions unresolvable. - catalog = await loadPluginMarketplace({ + const marketplace = await loadPluginMarketplace({ workDir: host.state.appState.workDir, source, - skipLatestVersions: true, + builtInEntries: + host.engineV2 && isDefaultMarketplaceCatalog(source) + ? capabilities.map(capabilityMarketplaceEntry) + : undefined, }); - marketplace = - builtInEntries !== undefined ? withBuiltInEntries(catalog, builtInEntries) : catalog; panel.setMarketplace(marketplace.plugins, marketplace.source); - host.state.ui.requestRender(); } catch (error) { - // Any phase-1 failure (unreachable OR malformed catalog) surfaces as an - // error: the panel keeps built-in capability rows installable in the - // Official tab while the error is shown, and a broken catalog must not - // be masked as a successfully loaded, built-ins-only marketplace. panel.setMarketplaceError(formatErrorMessage(error)); - host.state.ui.requestRender(); - return; - } - try { - // Phase 2: resolve latest versions in the background (against the raw - // catalog), re-apply the built-in injection so resolved versions flow - // onto capability rows, then refresh so update badges appear. Failures - // degrade to badge-less rows and never clobber the rendered list. - const enrichedCatalog = await withMarketplaceLatestVersions(catalog); - const enriched = - builtInEntries !== undefined - ? withBuiltInEntries(enrichedCatalog, builtInEntries) - : enrichedCatalog; - panel.setMarketplace(enriched.plugins, enriched.source); - } catch (error) { - log.warn('marketplace version lookup failed', { error }); } host.state.ui.requestRender(); } @@ -607,7 +566,7 @@ async function installCapabilityFromPanel( host.showNotice(`${label} is installed.`); host.state.transcriptContainer.addChild(new Spacer(1)); host.state.transcriptContainer.addChild( - new Markdown(WEBBRIDGE_POST_INSTALL_MARKDOWN, 2, 0, createMarkdownTheme(), undefined, createMarkdownOptions()), + new Markdown(WEBBRIDGE_POST_INSTALL_MARKDOWN, 2, 0, createMarkdownTheme()), ); host.state.ui.requestRender(); return; diff --git a/apps/kimi-code/src/tui/commands/provider.ts b/apps/kimi-code/src/tui/commands/provider.ts index d31c97006..dbfbddfcb 100644 --- a/apps/kimi-code/src/tui/commands/provider.ts +++ b/apps/kimi-code/src/tui/commands/provider.ts @@ -6,19 +6,16 @@ import { } from '@moonshot-ai/kimi-code-oauth'; import { applyCatalogProvider, - cascadeSubagentModelPool, catalogProviderModels, CatalogFetchError, DEFAULT_CATALOG_URL, resolveCatalogImport, - SECONDARY_DERIVED_MODEL_ALIAS, type Catalog, type ThinkingEffort, } from '@moonshot-ai/kimi-code-sdk'; import { createKimiCodeUserAgent } from '#/cli/version'; import { fetchCatalogOrBuiltIn } from '#/utils/catalog-fetch'; -import { refreshKimiRegion } from '#/utils/region'; import { ChoicePickerComponent } from '../components/dialogs/choice-picker'; import { CustomRegistryImportDialogComponent, @@ -90,11 +87,8 @@ async function handleProviderManagerDeleteSource( async function handleProviderDelete(host: SlashCommandHost, providerId: string): Promise<void> { if (providerId === DEFAULT_OAUTH_PROVIDER_NAME) { await host.harness.auth.logout(DEFAULT_OAUTH_PROVIDER_NAME); - // Drop the process-wide region cache with the credential: derived - // endpoints (updates, marketplace, site links, telemetry) must fall back - // to the marker/default profile, not the logged-out region. - refreshKimiRegion(); await host.authFlow.refreshConfigAfterLogout(); + await host.authFlow.clearActiveSessionAfterLogout(); return; } @@ -103,6 +97,7 @@ async function handleProviderDelete(host: SlashCommandHost, providerId: string): const config = await host.harness.removeProvider(providerId); if (activeProvider === providerId) { await host.authFlow.refreshConfigAfterLogout(); + await host.authFlow.clearActiveSessionAfterLogout(); } else { host.setAppState({ availableProviders: config.providers ?? {}, @@ -236,10 +231,6 @@ async function handleCatalogProviderAdd(host: SlashCommandHost): Promise<void> { // entered. The model selector that follows is just a convenience to pick the // default model; ESC leaves the provider in place without a default selection. const existingConfig = await host.harness.getConfig(); - const poolSnapshot = - existingConfig.providers[providerId] !== undefined - ? existingConfig.secondaryModel - : undefined; if (existingConfig.providers[providerId] !== undefined) { await host.harness.removeProvider(providerId); } @@ -260,16 +251,6 @@ async function handleCatalogProviderAdd(host: SlashCommandHost): Promise<void> { models: config.models, }); - // removeProvider cascaded the subagent pool against a model table where - // every `${providerId}/...` alias was absent; restore the entries that - // survived the re-add (aliases the catalog genuinely dropped stay dropped). - if (poolSnapshot !== undefined) { - const restored = cascadeSubagentModelPool(poolSnapshot, config.models ?? {}); - if (restored !== null) { - await host.harness.setConfig({ secondaryModel: restored ?? poolSnapshot }); - } - } - await host.authFlow.refreshConfigAfterLogin(); host.track('connect', { provider: providerId, method: 'catalog' }); host.showStatus(`Provider added: ${entry.name ?? providerId}`); @@ -282,11 +263,8 @@ async function handleCatalogProviderAdd(host: SlashCommandHost): Promise<void> { // Build a merged model dictionary that includes existing models plus the // newly-persisted provider's models, so the tabbed selector shows every // provider's tab (the new provider's tab starts active via initialTabId). - // The v1 runtime may carry the synthesized `__secondary__` derived entry — - // never selectable in a picker. const stateModels = await host.harness.getConfig().then((c) => c.models ?? {}); const mergedModels = { ...stateModels }; - delete mergedModels[SECONDARY_DERIVED_MODEL_ALIAS]; const selector = new TabbedModelSelectorComponent({ models: mergedModels, @@ -307,7 +285,7 @@ async function handleCatalogProviderAdd(host: SlashCommandHost): Promise<void> { host.mountEditorReplacement(selector); } -export async function setDefaultModel( +async function setDefaultModel( host: SlashCommandHost, alias: string, effort: ThinkingEffort, @@ -315,23 +293,16 @@ export async function setDefaultModel( // Resolve efforts the same way the /model path does (effectiveModelForHost // applies overrides and the protocol-profile inference): catalog entries for // e.g. Anthropic models declare no support_efforts on the alias, and without - // the inference an above-default pick would slip through as a persisted effort. + // the inference a top-tier pick would slip through as a persisted effort. const model = host.state.appState.availableModels[alias]; - const thinking = thinkingEffortToConfig( - effort, - model === undefined ? undefined : effectiveModelForHost(host, model), - ); await host.harness.setConfig({ defaultModel: alias, - thinking, + thinking: thinkingEffortToConfig( + effort, + model === undefined ? undefined : effectiveModelForHost(host, model).supportEfforts, + ), }); await host.authFlow.refreshConfigAfterLogin(); - // refreshConfigAfterLogin reactivates from the persisted config, so a pick - // the gate keeps session-only never reaches the runtime — apply it after - // the refresh, or the persisted value would clobber it. - if (thinking.effort === undefined && effort !== 'off' && effort !== 'on') { - await host.authFlow.activateModelAfterLogin(alias, effort); - } host.track('model_switch', { model: alias }); host.showStatus(`Default model set to ${alias} with thinking ${effort}.`); } @@ -385,10 +356,8 @@ async function handleCustomRegistryAddViaDialog(host: SlashCommandHost): Promise ); // Offer the model selector so the user can pick a default, just like the - // catalog (known-provider) flow. Copy without the v1-synthesized - // `__secondary__` derived entry — never selectable in a picker. - const stateModels = { ...(await host.harness.getConfig().then((c) => c.models ?? {})) }; - delete stateModels[SECONDARY_DERIVED_MODEL_ALIAS]; + // catalog (known-provider) flow. + const stateModels = await host.harness.getConfig().then((c) => c.models ?? {}); const firstNewAlias = Object.keys(stateModels).find((a) => addedProviderIds.some((pid) => a.startsWith(`${pid}/`)), ); diff --git a/apps/kimi-code/src/tui/commands/registry.ts b/apps/kimi-code/src/tui/commands/registry.ts index 67e7cd74d..48b57aa3f 100644 --- a/apps/kimi-code/src/tui/commands/registry.ts +++ b/apps/kimi-code/src/tui/commands/registry.ts @@ -26,13 +26,6 @@ const SWARM_ARG_COMPLETIONS: readonly ArgCompletionSpec[] = [ { value: 'off', description: 'Turn swarm mode off' }, ]; -const TOWER_ARG_COMPLETIONS: readonly ArgCompletionSpec[] = [ - { value: 'status', description: 'Report tower status' }, - { value: 'teardown', description: 'Tear down the tower' }, - { value: 'on', description: 'Turn tower mode on' }, - { value: 'off', description: 'Turn tower mode off' }, -]; - const ADD_DIR_ARG_COMPLETIONS: readonly ArgCompletionSpec[] = [ { value: 'list', description: 'Show configured additional workspace directories' }, ]; @@ -56,11 +49,6 @@ export function swarmArgumentCompletions(argumentPrefix: string): AutocompleteIt return completeLeadingArg(SWARM_ARG_COMPLETIONS, argumentPrefix); } -/** Argument autocompletion for the `/tower` command (subcommands). */ -export function towerArgumentCompletions(argumentPrefix: string): AutocompleteItem[] | null { - return completeLeadingArg(TOWER_ARG_COMPLETIONS, argumentPrefix); -} - /** Argument autocompletion for the `/add-dir` command. */ export function addDirArgumentCompletions(argumentPrefix: string): AutocompleteItem[] | null { if (isPathLikeAddDirArgument(argumentPrefix)) { @@ -189,20 +177,6 @@ export const BUILTIN_SLASH_COMMANDS = [ completeArgs: swarmArgumentCompletions, availability: 'idle-only', }, - { - name: 'tower', - aliases: [], - description: 'Report tower status, toggle tower mode, or set the tower objective', - priority: 100, - argumentHint: '[status|teardown|on|off] | <objective>', - completeArgs: towerArgumentCompletions, - // Every form stays available while busy: objectives steer into the - // running coordinator turn (see sendMessage in kimi-tui.ts), so /tower - // commands never wait for the previous one to finish. - availability: 'always', - experimentalFlag: 'tower', - requiresEngineV2: true, - }, { name: 'model', aliases: [], @@ -211,8 +185,8 @@ export const BUILTIN_SLASH_COMMANDS = [ availability: 'always', }, { - name: 'secondary-model', - aliases: ['subagent-model'], + name: 'secondary_model', + aliases: [], description: 'Configure the secondary model for subagents', priority: 90, availability: 'always', @@ -431,14 +405,6 @@ export const BUILTIN_SLASH_COMMANDS = [ priority: 40, availability: 'always', }, - { - name: 'remote-control', - aliases: ['rc'], - description: 'Open the current session through Kimi Remote Control (experimental)', - priority: 40, - availability: 'always', - experimentalFlag: 'remote-control', - }, { name: 'exit', aliases: ['quit', 'q'], diff --git a/apps/kimi-code/src/tui/commands/reload.ts b/apps/kimi-code/src/tui/commands/reload.ts index 041ec2d24..482b852ff 100644 --- a/apps/kimi-code/src/tui/commands/reload.ts +++ b/apps/kimi-code/src/tui/commands/reload.ts @@ -2,7 +2,6 @@ import type { KimiConfig } from '@moonshot-ai/kimi-code-sdk'; import { currentTheme, lightColors } from '#/tui/theme'; import { loadTuiConfig, type TuiConfig } from '../config'; -import { setMarkdownRenderLatex } from '../utils/markdown-options'; import type { SlashCommandHost } from './dispatch'; import { setExperimentalFeatures } from './experimental-flags'; @@ -56,10 +55,6 @@ export async function applyReloadedTuiConfig( host: SlashCommandHost, config: TuiConfig, ): Promise<void> { - // Set the LaTeX toggle before applyTheme: theme application invalidates the - // transcript components, which rebuild their Markdown children and copy the - // options at construction — so the new value must be live by then. - setMarkdownRenderLatex(config.renderLatex ?? true); const resolved = config.theme === 'auto' ? (currentTheme.palette === lightColors ? 'light' : 'dark') : undefined; @@ -68,7 +63,6 @@ export async function applyReloadedTuiConfig( host.setAppState({ editorCommand: config.editorCommand, disablePasteBurst: config.disablePasteBurst, - renderLatex: config.renderLatex, cacheExpiryHint: config.cacheExpiryHint, notifications: config.notifications, upgrade: config.upgrade, diff --git a/apps/kimi-code/src/tui/commands/resolve.ts b/apps/kimi-code/src/tui/commands/resolve.ts index de1d89a57..e67457a94 100644 --- a/apps/kimi-code/src/tui/commands/resolve.ts +++ b/apps/kimi-code/src/tui/commands/resolve.ts @@ -6,7 +6,6 @@ import { } from './registry'; import { isExperimentalFlagEnabled } from './experimental-flags'; import { parseSlashInput } from './parse'; -import type { TUIState } from '../tui-state'; import type { KimiSlashCommand, SlashCommandBusyReason, @@ -51,7 +50,6 @@ export interface ResolveSlashCommandInput { readonly pluginCommandMap: ReadonlyMap<string, string>; readonly isStreaming: boolean; readonly isCompacting: boolean; - readonly engineV2: boolean; } export function resolveSlashCommandInput(options: ResolveSlashCommandInput): SlashCommandIntent { @@ -62,8 +60,7 @@ export function resolveSlashCommandInput(options: ResolveSlashCommandInput): Sla // `command` is a literal union where only some members carry `experimentalFlag`; widen to read it. if ( command !== undefined && - isExperimentalFlagEnabled((command as KimiSlashCommand).experimentalFlag) && - (!(command as KimiSlashCommand).requiresEngineV2 || options.engineV2) + isExperimentalFlagEnabled((command as KimiSlashCommand).experimentalFlag) ) { const busyReason = slashCommandBusyReason(options); if ( @@ -86,10 +83,14 @@ export function resolveSlashCommandInput(options: ResolveSlashCommandInput): Sla const skillName = resolveSkillCommand(options.skillCommandMap, parsed.name); if (skillName !== undefined) { - // Skill activations are never blocked by a busy session: the TUI queues - // them behind the running turn exactly like normal messages (see - // sendSkillActivation), and Ctrl-S steers them as real activations, so - // skill commands can be issued any time. + const busyReason = slashCommandBusyReason(options); + if (busyReason !== undefined) { + return { + kind: 'blocked', + commandName: parsed.name, + reason: busyReason, + }; + } return { kind: 'skill', commandName: parsed.name, @@ -148,12 +149,3 @@ export function slashBusyMessage( } return `Cannot /${commandName} while compacting — wait for compaction to finish first.`; } - -/** - * Whether a delayed input restore is still safe: the editor must be empty - * (no newer draft) and still mounted (no editor-replacement panel opened - * meanwhile). Restores that run synchronously with submit do not need this. - */ -export function canRestoreSubmittedInput(host: { state: TUIState }): boolean { - return host.state.editor.getText().length === 0 && !host.state.editorReplacementMounted; -} diff --git a/apps/kimi-code/src/tui/commands/session.ts b/apps/kimi-code/src/tui/commands/session.ts index df853fde5..1a80c1947 100644 --- a/apps/kimi-code/src/tui/commands/session.ts +++ b/apps/kimi-code/src/tui/commands/session.ts @@ -5,9 +5,7 @@ import { pathToFileURL } from 'node:url'; import type { Session } from '@moonshot-ai/kimi-code-sdk'; import { detectInstallSource } from '#/cli/update/source'; -import { copyTextToClipboard } from '#/utils/clipboard/clipboard-text'; import { detectShellEnvironment } from '#/utils/process/shell-env'; -import { quoteShellArg } from '#/utils/shell-quote'; import { toTerminalHyperlink } from '#/utils/terminal-hyperlink'; import { LLM_NOT_SET_MESSAGE, NO_ACTIVE_SESSION_MESSAGE } from '../constant/kimi-tui'; import { isAbortError } from '../utils/errors'; @@ -78,26 +76,9 @@ export async function handleForkCommand(host: SlashCommandHost, args: string): P } // Stay in the source session: switching to the fork would close the // source, killing its in-flight turn and background tasks. The fork is - // an independent copy the user can switch to explicitly via /sessions, - // or enter from a new CLI process with the printed resume command. - const command = forkResumeCommand(host.state.appState.workDir, forkId); - let clipboardNote: string; - try { - const method = await copyTextToClipboard(command); - // OSC 52 delivery is fire-and-forget: terminals without OSC 52 support - // silently drop the sequence, so only native delivery may claim success - // (same wording convention as /copy). - clipboardNote = - method === 'native' - ? 'Command copied to clipboard' - : 'Command copied via terminal escape sequence (unverified)'; - } catch { - clipboardNote = 'Failed to copy command to clipboard'; - } + // an independent copy the user can switch to explicitly via /sessions. host.showStatus( - `Session forked (${forkId}). Still in the original session; switch to the fork via /sessions.\n` + - ` To enter the fork in a new process, run: ${command}\n` + - ` ${clipboardNote}`, + `Session forked (${forkId}). Still in the original session; switch to the fork via /sessions.`, ); } catch (error) { const msg = formatErrorMessage(error); @@ -105,16 +86,6 @@ export async function handleForkCommand(host: SlashCommandHost, args: string): P } } -function forkResumeCommand(workDir: string, forkId: string): string { - const dir = quoteShellArg(workDir); - // cmd.exe's `cd` only updates the given drive's remembered directory — a - // terminal on a different drive stays put, and the resume then runs in the - // wrong working directory. `pushd` switches drive + directory in both - // cmd.exe and PowerShell (`cd /d` would break PowerShell). - const changeDir = process.platform === 'win32' ? `pushd ${dir}` : `cd ${dir}`; - return `${changeDir} && kimi --resume ${quoteShellArg(forkId)}`; -} - function forkSourceTitle(host: SlashCommandHost, session: Session): string { const currentTitle = host.state.appState.sessionTitle?.trim(); if (currentTitle !== undefined && currentTitle.length > 0) return currentTitle; diff --git a/apps/kimi-code/src/tui/commands/tower.ts b/apps/kimi-code/src/tui/commands/tower.ts deleted file mode 100644 index b10d84c37..000000000 --- a/apps/kimi-code/src/tui/commands/tower.ts +++ /dev/null @@ -1,103 +0,0 @@ -import type { Session } from '@moonshot-ai/kimi-code-sdk'; - -import { - LLM_NOT_SET_MESSAGE, - NO_ACTIVE_SESSION_MESSAGE, - TOWER_STATUS_PROMPT, - TOWER_TEARDOWN_PROMPT, -} from '../constant/kimi-tui'; -import { formatErrorMessage } from '../utils/event-payload'; -import type { SlashCommandHost } from './dispatch'; - -export async function handleTowerCommand(host: SlashCommandHost, args: string): Promise<void> { - const input = args.trim(); - const sub = input.toLowerCase(); - - if (sub === 'on') { - await applyTowerMode(host, true); - return; - } - if (sub === 'off') { - await applyTowerMode(host, false); - return; - } - if (sub === '' || sub === 'status') { - host.sendNormalUserInput(TOWER_STATUS_PROMPT); - return; - } - if (sub === 'teardown') { - host.sendNormalUserInput(TOWER_TEARDOWN_PROMPT); - return; - } - - await startTowerObjective(host, input); -} - -async function startTowerObjective(host: SlashCommandHost, objective: string): Promise<void> { - const wasActive = host.state.appState.towerMode; - // Validate prompt prerequisites before mutating the mode — otherwise a - // rejected objective (no model configured) would leave tower on with the - // next ordinary prompt unexpectedly running under the tower injection. - if (host.state.appState.model.trim().length === 0) { - host.showError(LLM_NOT_SET_MESSAGE); - return; - } - // The engine's enter is idempotent, so never let the cached state skip the - // mutation: it may be stale (mode changed elsewhere or an unlanded event). - if (!(await setTowerMode(host, true))) return; - if (!wasActive) host.showNotice('Tower mode: ON'); - host.sendNormalUserInput(objective); -} - -async function applyTowerMode(host: SlashCommandHost, enabled: boolean): Promise<void> { - const wasActive = host.state.appState.towerMode; - // Like startTowerObjective: the setter is idempotent engine-side, so always - // reassert — a stale cache must not leave the authoritative mode unchanged. - if (!(await setTowerMode(host, enabled))) return; - if (wasActive === enabled) { - host.showStatus(`Tower mode is already ${enabled ? 'on' : 'off'}.`); - return; - } - host.showNotice(enabled ? 'Tower mode: ON' : 'Tower mode: OFF'); -} - -async function setTowerMode(host: SlashCommandHost, enabled: boolean): Promise<boolean> { - const session = await requireSessionEnsured(host); - if (session === undefined) return false; - try { - await session.setTowerMode(enabled); - // The engine may silently refuse entry (flag off, feature not assembled - // until a restart, another session owning the workspace tower) — confirm - // the mode actually took before reporting success or letting an objective - // ride on it. - const status = await session.getStatus(); - const effective = status.towerMode ?? false; - if (effective !== enabled) { - host.setAppState({ towerMode: effective }); - host.showError( - enabled - ? 'Tower mode could not be enabled — another session owns this workspace tower, or the experiment is off / was just turned on and needs a restart.' - : 'Tower mode could not be disabled.', - ); - return false; - } - } catch (error) { - host.showError( - `Failed to ${enabled ? 'enable' : 'disable'} tower mode: ${formatErrorMessage(error)}`, - ); - return false; - } - host.setAppState({ towerMode: enabled }); - return true; -} - -async function requireSessionEnsured(host: SlashCommandHost): Promise<Session | undefined> { - if (host.session !== undefined) return host.session; - if (!host.engineV2) { - host.showError(NO_ACTIVE_SESSION_MESSAGE); - return undefined; - } - // v2 session-less: lazy-create the session, then toggle — the same path - // the first prompt takes. - return host.ensureSession(); -} diff --git a/apps/kimi-code/src/tui/commands/types.ts b/apps/kimi-code/src/tui/commands/types.ts index b317e5d07..1ec3c6835 100644 --- a/apps/kimi-code/src/tui/commands/types.ts +++ b/apps/kimi-code/src/tui/commands/types.ts @@ -1,4 +1,5 @@ import type { AutocompleteItem, SlashCommand } from '@moonshot-ai/pi-tui'; +import type { FlagId } from '@moonshot-ai/kimi-code-sdk'; export type SlashCommandAvailability = 'always' | 'idle-only'; @@ -8,11 +9,8 @@ export interface KimiSlashCommand<Name extends string = string> extends SlashCom readonly description: string; readonly priority?: number; readonly availability?: SlashCommandAvailability | ((args: string) => SlashCommandAvailability); - /** When set, the command is hidden from the palette and blocked unless this flag is enabled. - * A plain string: the gating flag may live in either engine's registry (v1 core or v2 domain). */ - readonly experimentalFlag?: string; - /** When set, the command is hidden and unresolved on the legacy (v1) engine. */ - readonly requiresEngineV2?: boolean; + /** When set, the command is hidden from the palette and blocked unless this flag is enabled. */ + readonly experimentalFlag?: FlagId; /** * Generic argument autocompletion. `argumentPrefix` is the text typed after * `/<command> `; return suggestions or `null`. Declared as a plain function diff --git a/apps/kimi-code/src/tui/commands/undo.ts b/apps/kimi-code/src/tui/commands/undo.ts index c3aef7f8d..23d5a673e 100644 --- a/apps/kimi-code/src/tui/commands/undo.ts +++ b/apps/kimi-code/src/tui/commands/undo.ts @@ -90,9 +90,6 @@ async function undoByCount(host: SlashCommandHost, count: number): Promise<boole showUndoLimitStatus(host, 'Nothing to undo.'); return false; } - // When the anchor is a bundled prompt, its skill activation cards sit - // before it (contiguous, marked at submission/replay time) and are removed - // together with it. try { await session.undoHistory(count); @@ -107,48 +104,19 @@ async function undoByCount(host: SlashCommandHost, count: number): Promise<boole return false; } host.noteContextCut?.(); - await refreshTodoPanel(host); const children = host.state.transcriptContainer.children; const lastUserComponentIndex = findUndoAnchorComponentIndex(children, count); if (lastUserComponentIndex !== undefined) { - // A hook result may interleave between the bundle's cards and its prompt - // and survives undo in the engine, so it is skipped (kept) while the - // cards around it are removed. Only the contiguous marked run belongs to - // this submission: a standalone `/skill` card is unmarked and never - // swept. Structural removal only: the container's ref-checked render - // cache detects the child-list change; no tree-wide invalidate needed. - const groupChildIndices = new Set<number>(); - for (let i = lastUserComponentIndex - 1; i >= 0; i--) { - const entry = getTranscriptComponentEntry(children[i]!); - if (entry?.bundledWithPrompt === true) { - groupChildIndices.add(i); - continue; - } - if (entry?.hookResult === true) continue; - break; - } - removeUndoContextComponents(children, lastUserComponentIndex, groupChildIndices); + // Structural removal only: the container's ref-checked render cache + // detects the child-list change; no tree-wide invalidate needed. + removeUndoContextComponents(children, lastUserComponentIndex); } - const groupEntryIndices = new Set<number>(); - for (let i = lastUserIndex - 1; i >= 0; i--) { - const prev = entries[i]; - if (prev?.bundledWithPrompt === true) { - groupEntryIndices.add(i); - continue; - } - if (prev?.hookResult === true) continue; - break; - } - const preservedEntries = entries.filter( - (entry, index) => - !( - (index >= lastUserIndex || groupEntryIndices.has(index)) && - isUndoContextEntry(entry) - ), + const preservedEntries = entries.slice(lastUserIndex).filter( + (entry) => !isUndoContextEntry(entry), ); - entries.splice(0, entries.length, ...preservedEntries); + entries.splice(lastUserIndex, entries.length - lastUserIndex, ...preservedEntries); if (entries.length === 0) { renderWelcome(host); @@ -158,21 +126,6 @@ async function undoByCount(host: SlashCommandHost, count: number): Promise<boole return true; } -async function refreshTodoPanel(host: SlashCommandHost): Promise<void> { - const session = host.session; - if (session === undefined) return; - try { - const todos = await session.getTodos(); - if (todos.length > 0 && todos.every((todo) => todo.status === 'done')) { - host.streamingUI.setTodoList([]); - return; - } - host.streamingUI.setTodoList(todos); - } catch { - return; - } -} - async function showUndoSelector(host: SlashCommandHost): Promise<void> { if (host.session === undefined) { host.showError(NO_ACTIVE_SESSION_MESSAGE); @@ -440,9 +393,7 @@ function undoLimitFromError( function isUndoAnchorEntry(entry: TranscriptEntry): boolean { return ( entry.kind === 'user' || - (entry.kind === 'skill_activation' && - entry.skillTrigger === 'user-slash' && - entry.bundledWithPrompt !== true) || + (entry.kind === 'skill_activation' && entry.skillTrigger === 'user-slash') || entry.kind === 'plugin_command' ); } @@ -498,27 +449,19 @@ function findUndoAnchorComponentIndex( function removeUndoContextComponents( children: Component[], startIndex: number, - additionalIndices: ReadonlySet<number>, ): void { - for (let i = children.length - 1; i >= 0; i--) { + for (let i = children.length - 1; i >= startIndex; i--) { const child = children[i]; - if ( - child !== undefined && - (i >= startIndex || additionalIndices.has(i)) && - isUndoContextComponent(child) - ) { + if (child !== undefined && isUndoContextComponent(child)) { children.splice(i, 1); } } } function isUndoAnchorComponent(child: Component): boolean { - const entry = getTranscriptComponentEntry(child); return ( child instanceof UserMessageComponent || - (child instanceof SkillActivationComponent && - child.trigger === 'user-slash' && - entry?.bundledWithPrompt !== true) || + (child instanceof SkillActivationComponent && child.trigger === 'user-slash') || child instanceof PluginCommandComponent ); } diff --git a/apps/kimi-code/src/tui/commands/web.ts b/apps/kimi-code/src/tui/commands/web.ts index e759466aa..4a9035a32 100644 --- a/apps/kimi-code/src/tui/commands/web.ts +++ b/apps/kimi-code/src/tui/commands/web.ts @@ -1,22 +1,10 @@ import chalk from 'chalk'; import { splitTokenFragment } from '#/cli/sub/web/access-urls'; -import { - buildRemoteControlUrl, - formatRemoteControlOutput, - formatRemoteControlStatus, - startRemoteControl, - type RemoteControlStatus, -} from '#/cli/sub/web/remote-control'; -import { - formatRemoteControlAlreadyRunning, - inspectRemoteControlLock, -} from '#/cli/sub/web/remote-control-lock'; import { formatReadyBanner, startServerForeground } from '#/cli/sub/web/run'; import { parseServerOptions, tryResolveServerToken } from '#/cli/sub/web/shared'; import { openUrl } from '#/utils/open-url'; import { getDataDir } from '#/utils/paths'; -import { generateRemoteControlQr } from '#/utils/remote-control-qr'; import { NO_ACTIVE_SESSION_MESSAGE } from '../constant/kimi-tui'; import { darkColors } from '../theme/colors'; @@ -42,65 +30,6 @@ export async function handleWebCommand(host: SlashCommandHost): Promise<void> { await host.stop(); } -export async function handleRemoteControlCommand(host: SlashCommandHost): Promise<void> { - await host.waitForLazyCreation(); - const session = host.session; - - const holder = await inspectRemoteControlLock(getDataDir()); - if (holder !== undefined) { - host.showError(formatRemoteControlAlreadyRunning(holder)); - return; - } - - host.setExitForegroundTask(async () => { - const options = parseServerOptions({}); - let remoteControl: Awaited<ReturnType<typeof startRemoteControl>> | undefined; - try { - await startServerForeground(options, { - onReady: async (origin) => { - const dataDir = getDataDir(); - const token = tryResolveServerToken(dataDir); - if (token === undefined) throw new Error('Unable to read the local server token.'); - let outputReady = false; - const pendingStatuses: string[] = []; - const onStatus = (status: RemoteControlStatus): void => { - const line = formatRemoteControlStatus(status); - if (outputReady) process.stdout.write(line); - else pendingStatuses.push(line); - }; - remoteControl = await startRemoteControl({ - homeDir: dataDir, - localOrigin: origin, - localServerToken: token, - onStatus, - }); - const url = buildRemoteControlUrl(remoteControl.deviceId, session?.id); - const qrCode = await generateRemoteControlQr(url, dataDir); - process.stdout.write( - formatRemoteControlOutput({ - url, - localOrigin: origin, - deviceName: remoteControl.deviceName, - qrCode: qrCode.terminal, - pngPath: qrCode.pngPath, - }), - ); - outputReady = true; - for (const line of pendingStatuses) process.stdout.write(line); - openUrl(url); - }, - onShutdown: async () => { - await remoteControl?.close(); - }, - }); - } catch (error) { - process.stderr.write(`Failed to start Remote Control: ${formatErrorMessage(error)}\n`); - process.exit(1); - } - }); - await host.stop(); -} - /** * Register the exit takeover that turns this process into the new server once * the TUI has shut down (where `process.exit` would normally happen): the @@ -134,12 +63,12 @@ function startNewServerAfterExit(host: SlashCommandHost, sessionId: string): voi /** Styled `Session:` line for the foreground handoff; the token fragment is * dimmed like in the ready banner so the host/path stands out. */ -function sessionLine(url: string, labelText = 'Session: '): string { +function sessionLine(url: string): string { const label = (text: string): string => chalk.bold.hex(darkColors.textDim)(text); const accent = (text: string): string => chalk.hex(darkColors.accent)(text); const dim = (text: string): string => chalk.hex(darkColors.textDim)(text); const [base, frag] = splitTokenFragment(url); - return `${label(labelText)}${accent(base)}${frag === '' ? '' : dim(frag)}`; + return `${label('Session: ')}${accent(base)}${frag === '' ? '' : dim(frag)}`; } /** diff --git a/apps/kimi-code/src/tui/components/chrome/banner.ts b/apps/kimi-code/src/tui/components/chrome/banner.ts index 1ecf4af2c..58b6faa58 100644 --- a/apps/kimi-code/src/tui/components/chrome/banner.ts +++ b/apps/kimi-code/src/tui/components/chrome/banner.ts @@ -6,14 +6,6 @@ import type { BannerState } from '#/tui/types'; const PREFIX_STAR = '✦'; const PADDING = ' '; -/** - * Minimum column count the main text gets next to an inline tag. A long tag - * (e.g. a full sentence from the remote banner config) can fit on the line - * yet leave only a sliver for the main text, which then wraps into a narrow, - * hard-broken column. When that would happen the tag moves onto its own line - * and the main text uses (nearly) the full width instead. - */ -const MIN_INLINE_MAIN_TEXT_WIDTH = 16; export class BannerComponent implements Component { constructor(private readonly state: BannerState) {} @@ -38,22 +30,14 @@ export class BannerComponent implements Component { const tagDisplay = tagStyled.length > 0 ? tagStyled + PADDING : ''; const tagWidth = visibleWidth(tagDisplay); const showTag = tagWidth > 0 && tagWidth < width; - // Hanging indent aligning with the tag text (right after "✦ "). - const hangingWidth = visibleWidth(PREFIX_STAR + PADDING); - // If the inline tag would squeeze the main text into too narrow a column, - // render the tag on its own line and give the main text the full width. - const tagOnOwnLine = showTag && width - tagWidth < MIN_INLINE_MAIN_TEXT_WIDTH; - const inlineTag = showTag && !tagOnOwnLine; // Body lines (continuations of the main text) indent to match the first - // line's main-text column, which starts right after the tag display. When - // the tag is on its own line, the main text aligns with the tag text. - const bodyIndent = inlineTag ? ' '.repeat(tagWidth) : tagOnOwnLine ? ' '.repeat(hangingWidth) : ''; + // line's main-text column, which starts right after the tag display. + const bodyIndent = showTag ? ' '.repeat(tagWidth) : ''; // Descriptive subtext lines (the second line in the design) start at the // column after the leading star + space, aligning with the tag text itself. - const descIndent = showTag ? ' '.repeat(hangingWidth) : ''; - const bodyContentWidth = - width - (inlineTag ? tagWidth : tagOnOwnLine ? hangingWidth : 0); - const descContentWidth = width - (showTag ? hangingWidth : 0); + const descIndent = showTag ? ' '.repeat(visibleWidth(PREFIX_STAR + PADDING)) : ''; + const bodyContentWidth = width - (showTag ? tagWidth : 0); + const descContentWidth = width - (showTag ? visibleWidth(PREFIX_STAR + PADDING) : 0); if (bodyContentWidth <= 0) { return ['']; @@ -63,14 +47,11 @@ export class BannerComponent implements Component { const subSegments = this.state.subText ? this.state.subText.split('\n') : []; const result: string[] = []; - if (tagOnOwnLine) { - result.push(tagStyled); - } for (let i = 0; i < mainSegments.length; i++) { const wrapped = wrapTextWithAnsi(mainSegments[i]!, bodyContentWidth); for (let j = 0; j < wrapped.length; j++) { const boldLine = main(wrapped[j]!); - if (i === 0 && j === 0 && inlineTag) { + if (i === 0 && j === 0 && showTag) { result.push(tagDisplay + boldLine); } else { result.push(bodyIndent + boldLine); diff --git a/apps/kimi-code/src/tui/components/chrome/footer.ts b/apps/kimi-code/src/tui/components/chrome/footer.ts index 4619c4468..4bb8a75f9 100644 --- a/apps/kimi-code/src/tui/components/chrome/footer.ts +++ b/apps/kimi-code/src/tui/components/chrome/footer.ts @@ -194,7 +194,6 @@ export class FooterComponent implements Component { private gitCache: GitStatusCache; private gitCacheWorkDir: string; private transientHint: string | null = null; - private warningHint: string | null = null; private goalSnapshotKey: string | null = null; private goalObservedAtMs = Date.now(); private goalTimer: ReturnType<typeof setInterval> | null = null; @@ -259,17 +258,6 @@ export class FooterComponent implements Component { return this.transientHint; } - /** - * Longer-lived warning for line 2 (e.g. the over-long `/goal` objective - * warning). Unlike the transient hint it has no owner/timeout: the caller - * sets and clears it directly. A transient hint takes precedence while - * present; the warning returns as soon as the transient hint clears. - * Pass `null` to clear. - */ - setWarningHint(hint: string | null): void { - this.warningHint = hint; - } - /** * Sync both background-task badges with live counts. Each non-zero * count produces its own bracketed badge on line 1; zeros hide them @@ -337,7 +325,7 @@ export class FooterComponent implements Component { } } - // ── Line 2: hint (bottom-left) + context (right) ── + // ── Line 2: transient hint (bottom-left) + context (right) ── const contextText = formatContextStatus( state.contextUsage, state.contextTokens, @@ -345,11 +333,12 @@ export class FooterComponent implements Component { ); const contextWidth = visibleWidth(contextText); let line2: string; - const hint = this.transientHint ?? this.warningHint; - if (hint) { + if (this.transientHint) { const maxHintWidth = Math.max(0, width - contextWidth - 1); const shownHint = - visibleWidth(hint) <= maxHintWidth ? hint : truncateToWidth(hint, maxHintWidth, '…'); + visibleWidth(this.transientHint) <= maxHintWidth + ? this.transientHint + : truncateToWidth(this.transientHint, maxHintWidth, '…'); const hintWidth = visibleWidth(shownHint); const pad = Math.max(0, width - hintWidth - contextWidth); line2 = @@ -391,7 +380,6 @@ export class FooterComponent implements Component { if (state.permissionMode === 'yolo') modes.push(chalk.hex(colors.warning).bold('yolo')); if (state.planMode) modes.push(chalk.hex(colors.primary).bold('plan')); if (state.swarmMode) modes.push(chalk.hex(colors.accent).bold('swarm')); - if (state.towerMode) modes.push(chalk.hex(colors.accent).bold('tower')); if (modes.length > 0) slots['mode'] = [modes.join(' ')]; const goalBadge = formatGoalBadge(state.goal, colors, this.goalWallClockMs(state.goal)); diff --git a/apps/kimi-code/src/tui/components/chrome/gutter-container.ts b/apps/kimi-code/src/tui/components/chrome/gutter-container.ts index 43e076ec0..ed19793af 100644 --- a/apps/kimi-code/src/tui/components/chrome/gutter-container.ts +++ b/apps/kimi-code/src/tui/components/chrome/gutter-container.ts @@ -18,7 +18,6 @@ import { Container } from '@moonshot-ai/pi-tui'; import type { Component } from '@moonshot-ai/pi-tui'; -import { prefixPreservingOsc133Zone } from '#/tui/utils/osc133'; import { isRenderCacheEnabled } from '#/tui/utils/render-cache'; interface TranscriptRenderCache { @@ -69,9 +68,7 @@ export class GutterContainer extends Container { prefixed.push(cache.prefixed[i]!); } else { allReused = false; - // OSC 133 zone markers must stay at byte 0 for the fullscreen - // renderer's prompt navigation, so the gutter goes after them. - prefixed.push(lines.map((line) => prefixPreservingOsc133Zone(line, lead))); + prefixed.push(lines.map((line) => lead + line)); } i++; } diff --git a/apps/kimi-code/src/tui/components/dialogs/goal-queue-manager.ts b/apps/kimi-code/src/tui/components/dialogs/goal-queue-manager.ts index 4a45d6243..b5c2e7ac1 100644 --- a/apps/kimi-code/src/tui/components/dialogs/goal-queue-manager.ts +++ b/apps/kimi-code/src/tui/components/dialogs/goal-queue-manager.ts @@ -295,7 +295,7 @@ export class GoalQueueEditDialogComponent extends Container implements Focusable return; } if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { - this.error = `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters; put long content in a file and reference the file path.`; + this.error = `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters.`; return; } this.opts.onDone({ kind: 'save', goalId: this.opts.goal.id, objective }); diff --git a/apps/kimi-code/src/tui/components/dialogs/model-selector.ts b/apps/kimi-code/src/tui/components/dialogs/model-selector.ts index 2532f14a2..0299c6fde 100644 --- a/apps/kimi-code/src/tui/components/dialogs/model-selector.ts +++ b/apps/kimi-code/src/tui/components/dialogs/model-selector.ts @@ -80,9 +80,6 @@ export interface ModelSelectorOptions { * line; wraps instead of truncating when it exceeds the width (e.g. the * mid-conversation switch cost notice). */ readonly warning?: string; - /** Set to false to hide the Thinking footer and disable ←/→ effort - * switching — for pickers whose selection carries no thinking level. */ - readonly thinkingControl?: boolean; readonly onSelect: (selection: ModelSelection) => void; /** When provided, Alt+S invokes this instead of onSelect — used to apply the * choice to the current session only, without persisting it as the default. */ @@ -228,10 +225,7 @@ export class ModelSelectorComponent extends Container implements Focusable { } // Left/Right move the active thinking effort within the model's segments. - if ( - this.opts.thinkingControl !== false && - (matchesKey(data, Key.left) || matchesKey(data, Key.right)) - ) { + if (matchesKey(data, Key.left) || matchesKey(data, Key.right)) { const selected = this.selectedChoice(); if (selected !== undefined) { const segments = segmentsFor(selected.model); @@ -358,13 +352,13 @@ export class ModelSelectorComponent extends Container implements Focusable { lines.push(''); const selected = this.selectedChoice(); - if (selected !== undefined && this.opts.thinkingControl !== false) { + if (selected !== undefined) { const canSwitch = segmentsFor(selected.model).length > 1; const thinkingHeader = canSwitch ? ' Thinking (←→ to switch)' : ' Thinking'; lines.push(currentTheme.fg('textMuted', thinkingHeader)); lines.push(this.renderThinkingControl(selected)); - lines.push(''); } + lines.push(''); lines.push(currentTheme.fg('primary', '─'.repeat(width))); return lines.map((line) => truncateToWidth(line, width)); } diff --git a/apps/kimi-code/src/tui/components/dialogs/platform-selector.ts b/apps/kimi-code/src/tui/components/dialogs/platform-selector.ts index 89a51d6c6..a332f70af 100644 --- a/apps/kimi-code/src/tui/components/dialogs/platform-selector.ts +++ b/apps/kimi-code/src/tui/components/dialogs/platform-selector.ts @@ -1,25 +1,11 @@ import { OPEN_PLATFORMS } from '@moonshot-ai/kimi-code-oauth'; -import { KIMI_CODE_GLOBAL_PLATFORM_VALUE } from '#/utils/region'; - import { ChoicePickerComponent, type ChoiceOption } from './choice-picker'; -const KIMI_CODE_MAINLAND_CN_OPTION: ChoiceOption = { - value: 'kimi-code', - label: 'Kimi Code (kimi.com/code)', -}; -const KIMI_CODE_GLOBAL_OPTION: ChoiceOption = { - value: KIMI_CODE_GLOBAL_PLATFORM_VALUE, - label: 'Kimi Code (kimi.ai/code)', -}; - -function platformOptions(): readonly ChoiceOption[] { - return [ - KIMI_CODE_MAINLAND_CN_OPTION, - KIMI_CODE_GLOBAL_OPTION, - ...OPEN_PLATFORMS.map((platform) => ({ value: platform.id, label: platform.name })), - ]; -} +const PLATFORM_OPTIONS: readonly ChoiceOption[] = [ + { value: 'kimi-code', label: 'Kimi Code (OAuth)' }, + ...OPEN_PLATFORMS.map((platform) => ({ value: platform.id, label: platform.name })), +]; export interface PlatformSelectorOptions { readonly onSelect: (platformId: string) => void; @@ -30,7 +16,7 @@ export class PlatformSelectorComponent extends ChoicePickerComponent { constructor(opts: PlatformSelectorOptions) { super({ title: 'Select a platform', - options: [...platformOptions()], + options: [...PLATFORM_OPTIONS], onSelect: opts.onSelect, onCancel: opts.onCancel, }); diff --git a/apps/kimi-code/src/tui/components/dialogs/tabbed-model-selector.ts b/apps/kimi-code/src/tui/components/dialogs/tabbed-model-selector.ts index 9726ad483..d94de3b06 100644 --- a/apps/kimi-code/src/tui/components/dialogs/tabbed-model-selector.ts +++ b/apps/kimi-code/src/tui/components/dialogs/tabbed-model-selector.ts @@ -41,17 +41,15 @@ export interface TabbedModelSelectorOptions { readonly selectedValue?: string; readonly currentThinkingEffort: string; /** Forwarded to each inner selector; overrides the default ' Select a model' - * title line. */ + * title line (e.g. the secondary-model picker). */ readonly title?: string; /** When set, the tab for this provider id is initially active instead of the * tab derived from `currentValue`. */ readonly initialTabId?: string; - /** When set, warning-colored lines are rendered directly below the key-hint - * line, wrapping as needed (e.g. the mid-conversation switch cost notice). */ + /** Forwarded to each inner selector; when set, warning-colored lines are + * rendered directly below the key-hint line, wrapping as needed (e.g. the + * mid-conversation switch cost notice). */ readonly warning?: string; - /** Forwarded to each inner selector; set to false to hide the Thinking - * footer and disable ←/→ effort switching. */ - readonly thinkingControl?: boolean; readonly onSelect: (selection: ModelSelection) => void; /** Forwarded to each inner selector; when set, Alt+S applies the choice to * the current session only without persisting it as the default. */ @@ -189,7 +187,6 @@ function makeSelector( searchable: true, providerSwitchHint: true, warning: opts.warning, - thinkingControl: opts.thinkingControl, onSelect: opts.onSelect, onSessionOnlySelect: opts.onSessionOnlySelect, onCancel: opts.onCancel, diff --git a/apps/kimi-code/src/tui/components/dialogs/task-output-viewer.ts b/apps/kimi-code/src/tui/components/dialogs/task-output-viewer.ts index ad266fbb6..4a463671c 100644 --- a/apps/kimi-code/src/tui/components/dialogs/task-output-viewer.ts +++ b/apps/kimi-code/src/tui/components/dialogs/task-output-viewer.ts @@ -22,7 +22,6 @@ import type { BackgroundTaskInfo, BackgroundTaskStatus } from '@moonshot-ai/kimi import { currentTheme } from '#/tui/theme'; import { printableChar } from '@/tui/utils/printable-key'; -import { sanitizeShellOutput } from '#/tui/utils/shell-output'; const ELLIPSIS = '…'; @@ -105,7 +104,7 @@ export class TaskOutputViewer extends Container implements Focusable { } private splitOutput(output: string): string[] { - return (output.length > 0 ? sanitizeShellOutput(output) : '[no output captured]').split('\n'); + return (output.length > 0 ? output : '[no output captured]').split('\n'); } // ── input ────────────────────────────────────────────────────────── diff --git a/apps/kimi-code/src/tui/components/dialogs/tasks-browser.ts b/apps/kimi-code/src/tui/components/dialogs/tasks-browser.ts index 1b33a5bf3..1874d0e7a 100644 --- a/apps/kimi-code/src/tui/components/dialogs/tasks-browser.ts +++ b/apps/kimi-code/src/tui/components/dialogs/tasks-browser.ts @@ -27,7 +27,6 @@ import type { BackgroundTaskInfo, BackgroundTaskStatus } from '@moonshot-ai/kimi import { SELECT_POINTER } from '@/tui/constant/symbols'; import { currentTheme } from '#/tui/theme'; import { printableChar } from '@/tui/utils/printable-key'; -import { sanitizeShellOutput } from '#/tui/utils/shell-output'; const ELLIPSIS = '…'; @@ -604,7 +603,7 @@ export class TasksBrowserApp extends Container implements Focusable { if (this.props.tailLoading) body = '[loading…]'; else if (this.props.tailOutput === undefined || this.props.tailOutput.length === 0) body = '[no output captured]'; - else body = sanitizeShellOutput(this.props.tailOutput); + else body = this.props.tailOutput; const rawLines = body.split('\n'); const tailLines = rawLines.slice(-innerHeight); diff --git a/apps/kimi-code/src/tui/components/dialogs/trust-prompt.ts b/apps/kimi-code/src/tui/components/dialogs/trust-prompt.ts index 811ad888e..0ecca3732 100644 --- a/apps/kimi-code/src/tui/components/dialogs/trust-prompt.ts +++ b/apps/kimi-code/src/tui/components/dialogs/trust-prompt.ts @@ -7,8 +7,6 @@ import { type Focusable, } from '@moonshot-ai/pi-tui'; -import type { WorkspaceTrustMcpServerInfo } from '@moonshot-ai/kimi-code-sdk'; - import { SELECT_POINTER } from '#/tui/constant/symbols'; import { currentTheme } from '#/tui/theme'; @@ -17,7 +15,7 @@ export type TrustPromptChoice = 'trust' | 'distrust'; export interface TrustPromptOptions { readonly workDir: string; /** Project-level MCP servers that trusting would enable; may be empty. */ - readonly gatedMcpServers: readonly WorkspaceTrustMcpServerInfo[]; + readonly gatedMcpServers: readonly string[]; /** Esc resolves to 'distrust' as well. */ readonly onSelect: (choice: TrustPromptChoice) => void; } @@ -43,7 +41,7 @@ const OPTIONS: readonly TrustPromptOption[] = [ export class TrustPromptComponent implements Component, Focusable { focused = false; - private selectedIndex = 1; + private selectedIndex = 0; constructor(private readonly opts: TrustPromptOptions) {} @@ -81,19 +79,12 @@ export class TrustPromptComponent implements Component, Focusable { ]; const notice = - 'Project-level MCP servers are disabled until you explicitly choose Trust. Trust starts the listed project MCP targets and remembers this folder.'; + this.opts.gatedMcpServers.length > 0 + ? `Kimi Code loads project-level MCP servers (.mcp.json, .kimi-code/mcp.json) only in trusted folders. They run as local processes on your machine. This folder defines: ${this.opts.gatedMcpServers.join(', ')}.` + : 'Kimi Code loads project-level MCP servers (.mcp.json, .kimi-code/mcp.json) only in trusted folders. They run as local processes on your machine.'; for (const line of wrapTextWithAnsi(notice, Math.max(20, width - 2))) { lines.push(` ${currentTheme.fg('textMuted', line)}`); } - if (this.opts.gatedMcpServers.length > 0) { - lines.push(` ${currentTheme.fg('warning', 'Project MCP targets:')}`); - for (const server of this.opts.gatedMcpServers) { - const details = formatMcpTarget(server); - for (const line of wrapTextWithAnsi(details, Math.max(20, width - 4))) { - lines.push(` ${currentTheme.fg('warning', line)}`); - } - } - } lines.push(''); for (let i = 0; i < OPTIONS.length; i += 1) { @@ -114,27 +105,3 @@ export class TrustPromptComponent implements Component, Focusable { return lines.map((line) => truncateToWidth(line, width)); } } - -function formatMcpTarget(server: WorkspaceTrustMcpServerInfo): string { - if (server.transport === 'stdio') { - const args = server.args === undefined ? '' : ` args=${JSON.stringify(server.args)}`; - const cwd = server.cwd === undefined ? '' : ` cwd=${server.cwd}`; - return sanitizeForDisplay(`${server.name} (stdio): command=${server.command ?? ''}${args}${cwd}`); - } - return sanitizeForDisplay(`${server.name} (${server.transport}): url=${server.url ?? ''}`); -} - -/** - * Drops C0/C1 control characters (including ESC) from workspace-supplied text: - * the trust prompt renders before the workspace is trusted, so a planted - * `.mcp.json` must not inject terminal control sequences into it. - */ -function sanitizeForDisplay(value: string): string { - let result = ''; - for (const char of value) { - const code = char.codePointAt(0) ?? 0; - if (code <= 0x1f || (code >= 0x7f && code <= 0x9f)) continue; - result += char; - } - return result; -} diff --git a/apps/kimi-code/src/tui/components/editor/custom-editor.ts b/apps/kimi-code/src/tui/components/editor/custom-editor.ts index 2a2802093..51958dbe9 100644 --- a/apps/kimi-code/src/tui/components/editor/custom-editor.ts +++ b/apps/kimi-code/src/tui/components/editor/custom-editor.ts @@ -18,7 +18,6 @@ import { createEditorTheme } from '#/tui/theme/pi-tui-theme'; import { printableChar } from '#/tui/utils/printable-key'; import { extractAtPrefix } from './file-mention-provider'; -import { findInlineSkillTokens } from '../../utils/inline-skill-tokens'; import { WrappingSelectList } from './wrapping-select-list'; // oxlint-disable-next-line no-control-regex -- ESC (\x1b) is required to match ANSI SGR escape sequences @@ -155,27 +154,19 @@ export class CustomEditor extends Editor { * Alt-V on Windows — Ctrl-V is terminal-reserved there). Return * `true` to consume the key (image was read and handled); return * `false` to let the key fall through to the normal paste path. - * The callback may be async; CustomEditor queues subsequent keystrokes until - * it settles before dispatching them. + * The callback may be async; pi-tui awaits it before dispatching + * the next keystroke. */ public onPasteImage?: () => Promise<boolean>; private consumingPaste = false; private consumeBuffer = ''; - /** Serialize paste callbacks so Enter/typing cannot overtake an image paste. */ - private pasteInFlight = false; - private readonly pasteInputQueue: string[] = []; private argumentHints: ReadonlyMap<string, string> = new Map(); - private skillCommandNames: ReadonlySet<string> = new Set(); setArgumentHints(hints: ReadonlyMap<string, string>): void { this.argumentHints = hints; } - setSkillCommandNames(names: ReadonlySet<string>): void { - this.skillCommandNames = names; - } - constructor(tui: TUI, options: CustomEditorOptions = {}) { // paddingX: 4 reserves column 0 for the left vertical border (│), // column 1 as a single space between border and prompt, column 2 for @@ -183,11 +174,7 @@ export class CustomEditor extends Editor { // content. The right side mirrors with 3 padding columns and the right // border at the last column. const theme = createEditorTheme(); - super(tui, theme, { - paddingX: 4, - disablePasteBurst: options.disablePasteBurst, - inlineSlashTrigger: true, - }); + super(tui, theme, { paddingX: 4, disablePasteBurst: options.disablePasteBurst }); // pi-tui keeps `createAutocompleteList` private; shadow it with an // instance property so slash command menus render descriptions wrapped @@ -248,9 +235,7 @@ export class CustomEditor extends Editor { const text = this.getText(); const offset = lines.slice(0, line).reduce((sum, l) => sum + l.length + 1, 0) + start; const newText = text.slice(0, offset) + content + text.slice(offset + match[0].length); - // Keep the paste registry intact: the text still holds other live markers - // whose entries a plain setText would drop (upstream resets the registry). - this.setText(newText, { preservePasteRegistry: true }); + this.setText(newText); return true; } return false; @@ -277,42 +262,16 @@ export class CustomEditor extends Editor { const firstContentIdx = 1; const isBash = this.inputMode === 'bash'; const text = this.getText().trimStart(); - if (!isBash) { - // Paint the leading slash command on the first content line only, then - // inline skill tokens on every content line (multi-line prompts can - // reference skills anywhere). + if (text.startsWith('/') && !isBash) { + // Paint only the FIRST editor content line; multi-line slash commands + // are not a thing in practice. const original = lines[firstContentIdx]; if (original !== undefined) { - let highlighted = original; - let leadingRange: { start: number; end: number } | null = null; - if (text.startsWith('/')) { - leadingRange = leadingSlashTokenRange(stripSgr(original)); - const leading = highlightFirstSlashToken(original, 'primary'); - if (leading !== undefined) { - highlighted = leading; - } - } - const inline = highlightInlineSkillTokens( - highlighted, - this.skillCommandNames, - leadingRange, - 'primary', - ); - if (inline !== undefined) { - highlighted = inline; - } - if (highlighted !== original) { + const highlighted = highlightFirstSlashToken(original, 'primary'); + if (highlighted !== undefined) { lines[firstContentIdx] = highlighted; } } - for (let i = firstContentIdx + 1; i < lines.length - 1; i++) { - const original = lines[i]; - if (original === undefined) continue; - const inline = highlightInlineSkillTokens(original, this.skillCommandNames, null, 'primary'); - if (inline !== undefined) { - lines[i] = inline; - } - } } const hint = this.computeArgumentHint(); if (hint !== undefined) { @@ -366,16 +325,6 @@ export class CustomEditor extends Editor { return; } - // Clipboard reads are asynchronous. Queue every key received while a - // paste callback is in flight and replay it once the callback settles - // (clipboard read + placeholder insert — compression and the daemon - // upload continue in the background off this path), so Enter cannot - // submit a draft that is still missing the pasted image. - if (this.pasteInFlight) { - this.pasteInputQueue.push(normalized); - return; - } - // Any input other than a lone Escape breaks a pending double-Esc sequence, // so the shortcut only fires for two consecutive Escape presses. if (!matchesKey(normalized, Key.escape)) { @@ -419,21 +368,17 @@ export class CustomEditor extends Editor { this.onTextPaste?.(); super.handleInput.call(this, normalized); }; - this.pasteInFlight = true; - void handler() - .then((handled) => { + void handler().then( + (handled) => { if (!handled) pasteAsText(); - }) - .catch(() => { + }, + () => { // A rejecting image-paste handler must not leak an unhandled // rejection (the CLI turns those into a silent exit) — treat it // the same as "no image available" and fall back to text paste. pasteAsText(); - }) - .finally(() => { - this.pasteInFlight = false; - this.flushPasteInputQueue(); - }); + }, + ); return; } } @@ -558,14 +503,6 @@ export class CustomEditor extends Editor { this.reopenAutocompleteAfterInput(); } - private flushPasteInputQueue(): void { - if (this.pasteInFlight) return; - const next = this.pasteInputQueue.shift(); - if (next === undefined) return; - this.handleInput(next); - if (!this.pasteInFlight) this.flushPasteInputQueue(); - } - private reopenAutocompleteAfterInput(): void { if (this.isShowingAutocomplete()) return; const { line, col } = this.getCursor(); @@ -632,22 +569,12 @@ export class CustomEditor extends Editor { */ export function highlightFirstSlashToken(line: string, token: 'primary'): string | undefined { const visible = stripSgr(line); - const range = leadingSlashTokenRange(visible); - if (range === null) return undefined; - const ranges = [range]; - if (visible.slice(range.start, range.end) === '/goal') { - ranges.push(...goalCommandPathRanges(visible, range.end)); - } - return highlightVisibleRanges(line, ranges, token); -} - -function leadingSlashTokenRange(visible: string): { start: number; end: number } | null { const slashIdx = visible.indexOf('/'); - if (slashIdx < 0) return null; + if (slashIdx < 0) return undefined; // Guard: only paint when `/` is the first non-whitespace character // on the line (avoids colouring a mid-sentence slash). for (let i = 0; i < slashIdx; i++) { - if (visible[i] !== ' ' && visible[i] !== '\t') return null; + if (visible[i] !== ' ' && visible[i] !== '\t') return undefined; } // Token ends at the next whitespace (or the visible end). let endVisible = slashIdx + 1; @@ -657,32 +584,11 @@ function leadingSlashTokenRange(visible: string): { start: number; end: number } endVisible++; } const visibleToken = visible.slice(slashIdx, endVisible); - if (visibleToken.slice(1).includes('/')) return null; - return { start: slashIdx, end: endVisible }; -} - -/** - * Highlight inline skill tokens in `line`. A token is painted only when it - * names a known skill; `exclude` (the already-painted leading slash command - * range) is skipped so the leading command is not painted twice. - */ -export function highlightInlineSkillTokens( - line: string, - skillCommandNames: ReadonlySet<string>, - exclude: { start: number; end: number } | null, - token: 'primary', -): string | undefined { - if (skillCommandNames.size === 0) return undefined; - const visible = stripSgr(line); - const ranges = findInlineSkillTokens(visible, { - isKnownSkill: (commandName) => - skillCommandNames.has(commandName) || skillCommandNames.has(`skill:${commandName}`), - includeLeading: true, - }).filter( - (inlineToken) => - exclude === null || inlineToken.start >= exclude.end || inlineToken.end <= exclude.start, - ); - if (ranges.length === 0) return undefined; + if (visibleToken.slice(1).includes('/')) return undefined; + const ranges = [{ start: slashIdx, end: endVisible }]; + if (visibleToken === '/goal') { + ranges.push(...goalCommandPathRanges(visible, endVisible)); + } return highlightVisibleRanges(line, ranges, token); } diff --git a/apps/kimi-code/src/tui/components/editor/file-mention-provider.ts b/apps/kimi-code/src/tui/components/editor/file-mention-provider.ts index daf72ca64..722682db6 100644 --- a/apps/kimi-code/src/tui/components/editor/file-mention-provider.ts +++ b/apps/kimi-code/src/tui/components/editor/file-mention-provider.ts @@ -10,8 +10,6 @@ import { type SlashCommand, } from '@moonshot-ai/pi-tui'; -import { findInlineSkillTokens } from '../../utils/inline-skill-tokens'; - const PATH_DELIMITERS = new Set([' ', '\t', '"', "'", '=']); const MAX_FALLBACK_SCAN = 2000; const MAX_FALLBACK_SUGGESTIONS = 50; @@ -47,7 +45,6 @@ export class FileMentionProvider implements AutocompleteProvider { private readonly fdPath: string | null, additionalDirs: readonly string[] = [], private readonly getInputMode: () => 'prompt' | 'bash' = () => 'prompt', - private readonly skillCommandNames?: ReadonlySet<string>, ) { this.additionalDirs = additionalDirs.map((dir) => normalizePath(resolve(workDir, dir))); // Build an expanded list that includes alias entries so that @@ -103,34 +100,11 @@ export class FileMentionProvider implements AutocompleteProvider { } } - // An inline skill token the cursor is still on stays eligible for skill - // selection even when the input begins with a slash command and has text - // after the cursor — the argument suppression below guards the command's - // own arguments, not an inline skill the user inserts mid-text. Computed - // before the leading-whitespace suppression: an indented inline token - // (` /skill:rev`) is a skill reference, not a path to suppress. - const inlineSkillPrefix = extractInlineSkillPrefix(textBeforeCursor, cursorLine); - - if ( - inlineSkillPrefix === null && - shouldSuppressLeadingWhitespaceSlashPath(textBeforeCursor, options.force) - ) { + if (shouldSuppressLeadingWhitespaceSlashPath(textBeforeCursor, options.force)) { return null; } - // A `/` at the start of a later line is an inline skill reference, not a - // start-of-message slash command: offer the skill-only picker there. if ( - cursorLine > 0 && - textBeforeCursor.trim() === '/' && - this.getInputMode() !== 'bash' && - options.force !== true - ) { - return this.getInlineSkillSuggestions('/'); - } - - if ( - inlineSkillPrefix === null && shouldSuppressSlashArgumentCompletion( textBeforeCursor, currentLine.slice(cursorCol), @@ -141,9 +115,8 @@ export class FileMentionProvider implements AutocompleteProvider { } // Handle slash-command name completion ourselves so that aliases are - // searchable and visible in the label. Only the first line can host a - // start-of-message slash command; later lines are inline skill territory. - if (!options.force && cursorLine === 0 && textBeforeCursor.startsWith('/')) { + // searchable and visible in the label. + if (!options.force && textBeforeCursor.startsWith('/')) { const spaceIndex = textBeforeCursor.indexOf(' '); if (spaceIndex === -1) { const tokens = textBeforeCursor @@ -212,20 +185,6 @@ export class FileMentionProvider implements AutocompleteProvider { } } - // Inline skill selection: `/` after whitespace mid-input in prompt mode. - // Runs after slash-command argument handling so known commands such as - // `/add-dir /` keep their own argument completions. - if ( - inlineSkillPrefix !== null && - this.getInputMode() !== 'bash' && - options.force !== true - ) { - // A mid-input `/` in prompt mode is only meaningful as skill selection; - // when no skills are registered, suppress path completion instead of - // offering root directories. - return this.getInlineSkillSuggestions(inlineSkillPrefix); - } - try { const inner = await this.inner.getSuggestions(lines, cursorLine, cursorCol, options); if (inner === null || this.getInputMode() !== 'bash') { @@ -240,37 +199,6 @@ export class FileMentionProvider implements AutocompleteProvider { } } - private getInlineSkillSuggestions(prefix: string): AutocompleteSuggestions | null { - if (this.skillCommandNames === undefined || this.skillCommandNames.size === 0) return null; - const names = this.skillCommandNames; - const tokens = prefix - .slice(1) - .trim() - .split(/\s+/) - .filter((t) => t.length > 0); - - const matches: Array<{ cmd: SlashAutocompleteCommand; score: number }> = []; - for (const cmd of this.slashCommands) { - if (!names.has(cmd.name)) continue; - const score = scoreTokens(tokens, cmd.name); - if (score !== null) { - matches.push({ cmd, score }); - } - } - matches.sort((a, b) => a.score - b.score); - - if (matches.length === 0) return null; - return { - items: matches.map((m) => ({ - value: m.cmd.name, - label: m.cmd.name, - description: formatSlashCommandDescription(m.cmd), - data: { inlineSkill: true }, - })), - prefix, - }; - } - applyCompletion( lines: string[], cursorLine: number, @@ -278,30 +206,6 @@ export class FileMentionProvider implements AutocompleteProvider { item: AutocompleteItem, prefix: string, ): { lines: string[]; cursorLine: number; cursorCol: number } { - // Inline skill selection mid-input: pi-tui's default applyCompletion - // treats mid-line slash prefixes as file paths and drops the `/`. Preserve - // the slash and add a trailing space so the completed token stays a valid - // skill reference (e.g. `hello /rev` -> `hello /skill:review `). - if ( - item.data?.['inlineSkill'] === true && - this.getInputMode() !== 'bash' && - prefix.startsWith('/') - ) { - const currentLine = lines[cursorLine] ?? ''; - const textBeforeCursor = currentLine.slice(0, cursorCol); - if (extractInlineSkillPrefix(textBeforeCursor, cursorLine) === prefix) { - const beforePrefix = currentLine.slice(0, cursorCol - prefix.length); - const afterCursor = currentLine.slice(cursorCol); - const newLines = [...lines]; - newLines[cursorLine] = `${beforePrefix}/${item.value} ${afterCursor}`; - return { - lines: newLines, - cursorLine, - // +2 for the preserved "/" and the appended " ". - cursorCol: beforePrefix.length + item.value.length + 2, - }; - } - } // In bash mode a leading `/` is a path, but pi-tui's applyCompletion // mistakes it for a slash command (prefix starts with `/`, nothing before // it, no second `/`) and prepends another `/`, producing e.g. @@ -315,32 +219,6 @@ export class FileMentionProvider implements AutocompleteProvider { } } -/** - * Extract the inline skill prefix (e.g. `/rev`) from `text` when the cursor is - * positioned after a `/` that is preceded by whitespace and not part of the - * leading slash-command area. Returns `null` when the context is not an inline - * skill trigger. - * - * On lines after the first, a `/` at the start of the line always begins an - * inline skill prefix — including the partially typed `/rev` — so the picker - * stays in skill-only mode while the token is completed. - */ -export function extractInlineSkillPrefix(text: string, cursorLine: number = 0): string | null { - if (cursorLine > 0) { - const trimmedStart = text.trimStart(); - const match = /^\/[^\s/]*$/.exec(trimmedStart); - if (match !== null) return match[0]; - } - // findInlineSkillTokens skips the leading slash-command area, so a line such - // as `/skill:review args /` still yields the trailing `/` token. - const tokens = findInlineSkillTokens(text, { - isKnownSkill: () => true, - allowEmpty: true, - }); - const token = tokens.findLast((t) => t.end === text.length); - return token === undefined ? null : text.slice(token.start); -} - export function extractAtPrefix(text: string): string | null { let tokenStart = 0; for (let i = text.length - 1; i >= 0; i -= 1) { diff --git a/apps/kimi-code/src/tui/components/messages/assistant-message.ts b/apps/kimi-code/src/tui/components/messages/assistant-message.ts index 64ed6bbf8..c1b39537d 100644 --- a/apps/kimi-code/src/tui/components/messages/assistant-message.ts +++ b/apps/kimi-code/src/tui/components/messages/assistant-message.ts @@ -11,8 +11,6 @@ import { MESSAGE_INDENT } from '#/tui/constant/rendering'; import { STATUS_BULLET } from '#/tui/constant/symbols'; import { currentTheme } from '#/tui/theme'; import { createMarkdownTheme } from '#/tui/theme/pi-tui-theme'; -import { createMarkdownOptions } from '#/tui/utils/markdown-options'; -import { markOsc133Zone } from '#/tui/utils/osc133'; import { isRenderCacheEnabled } from '#/tui/utils/render-cache'; type AssistantMarkdownOptions = { @@ -63,14 +61,7 @@ export class AssistantMessageComponent implements Component { if (this.markdown === undefined || this.markdownTransient !== transient) { this.contentContainer.clear(); - this.markdown = new Markdown( - displayText, - 0, - 0, - createMarkdownTheme({ transient }), - undefined, - createMarkdownOptions(), - ); + this.markdown = new Markdown(displayText, 0, 0, createMarkdownTheme({ transient })); this.markdownTransient = transient; this.contentContainer.addChild(this.markdown); return; @@ -93,8 +84,6 @@ export class AssistantMessageComponent implements Component { 0, 0, createMarkdownTheme({ transient: this.lastTransient }), - undefined, - createMarkdownOptions(), ); this.markdownTransient = this.lastTransient; this.contentContainer.addChild(this.markdown); @@ -125,7 +114,7 @@ export class AssistantMessageComponent implements Component { i === 0 && this.showBullet ? currentTheme.fg('text', STATUS_BULLET) : MESSAGE_INDENT; lines.push(p + contentLines[i]); } - const rendered = markOsc133Zone(lines.map((line) => truncateToWidth(line, safeWidth, '…'))); + const rendered = lines.map((line) => truncateToWidth(line, safeWidth, '…')); if (isRenderCacheEnabled()) { this.renderCache = { width: safeWidth, lines: rendered }; } diff --git a/apps/kimi-code/src/tui/components/messages/plan-box.ts b/apps/kimi-code/src/tui/components/messages/plan-box.ts index 2b46b31d3..d1eeec03c 100644 --- a/apps/kimi-code/src/tui/components/messages/plan-box.ts +++ b/apps/kimi-code/src/tui/components/messages/plan-box.ts @@ -10,7 +10,6 @@ import { pathToFileURL } from 'node:url'; import { Markdown, truncateToWidth, visibleWidth, type Component, type MarkdownTheme } from '@moonshot-ai/pi-tui'; import chalk from 'chalk'; -import { createMarkdownOptions } from '#/tui/utils/markdown-options'; import { toTerminalHyperlink } from '#/utils/terminal-hyperlink'; const LEFT_MARGIN = 2; // two-space indent matching other tool call children @@ -42,7 +41,7 @@ export class PlanBoxComponent implements Component { // parse + wrap output keyed on (text, width), so reusing the same // instance means repeated render() calls from the parent Container // hit the cache instead of re-parsing on every frame. - this.markdown = new Markdown(plan.trim(), 0, 0, markdownTheme, undefined, createMarkdownOptions()); + this.markdown = new Markdown(plan.trim(), 0, 0, markdownTheme); this.status = opts?.status; } diff --git a/apps/kimi-code/src/tui/components/messages/shell-run.ts b/apps/kimi-code/src/tui/components/messages/shell-run.ts index 747bc3860..ca99f2e76 100644 --- a/apps/kimi-code/src/tui/components/messages/shell-run.ts +++ b/apps/kimi-code/src/tui/components/messages/shell-run.ts @@ -1,50 +1,40 @@ import { Container, Text } from '@moonshot-ai/pi-tui'; -import { SHELL_OUTPUT_PREVIEW_LINES } from '#/tui/constant/rendering'; import { currentTheme } from '#/tui/theme'; import { formatBashOutputForDisplay, sanitizeShellOutput } from '#/tui/utils/shell-output'; -import { TruncatedOutputComponent } from './tool-renderers/truncated'; - const RUNNING_TAIL_LINES = 5; const TIMER_INTERVAL_MS = 1000; // Cap the live running buffer so a command that spews output for minutes can't // grow memory without bound or make every render re-strip a multi-MB string. // Only affects the transient running tail; the final view uses the full -// captured stdout/stderr passed to finish(). When the cap drops older output, -// the expanded running view says so via TRUNCATED_RUNNING_NOTICE. +// captured stdout/stderr passed to finish(). const MAX_COMBINED_CHARS = 256 * 1024; const KEEP_COMBINED_CHARS = 64 * 1024; -const TRUNCATED_RUNNING_NOTICE = '... (output truncated)'; - /** * Live view for a user-initiated `!` shell command. Two phases: * - * - running: dim, ANSI-stripped tail of the combined output (the last - * RUNNING_TAIL_LINES lines, or the whole buffer when expanded via - * ctrl+o), a `+N lines` overflow marker, an elapsed `(Xs)` timer that - * ticks every second, and a `(ctrl+b to run in background)` hint — - * matching claude-code's running card so warnings are grey rather than - * red while the command works. + * - running: dim, ANSI-stripped tail of the combined output, a `+N lines` + * overflow marker, an elapsed `(Xs)` timer that ticks every second, and a + * `(ctrl+b to run in background)` hint — matching claude-code's running card + * so warnings are grey rather than red while the command works. * - finished: the standard `formatBashOutputForDisplay` view (stderr red only - * on failure) through the shared TruncatedOutputComponent — collapsed to - * the first SHELL_OUTPUT_PREVIEW_LINES visual rows, expanded to the full - * output by the global ctrl+o toggle. + * on failure), the timer stopped and the running chrome removed. * * Hardened so a misbehaving command can never crash the TUI: the running * buffer is capped, and every render/render-request path swallows errors. */ export class ShellRunComponent extends Container { private readonly textComponent: Text; - private finalOutput = ''; private combined = ''; - private combinedTruncated = false; private running = true; private backgrounded = false; private disposed = false; - private expanded = false; + private finalStdout = ''; + private finalStderr = ''; + private finalIsError?: boolean; private readonly startedAt = Date.now(); private timer: ReturnType<typeof setInterval> | undefined; @@ -60,7 +50,6 @@ export class ShellRunComponent extends Container { this.combined += text; if (this.combined.length > MAX_COMBINED_CHARS) { this.combined = this.combined.slice(-KEEP_COMBINED_CHARS); - this.combinedTruncated = true; } this.flush(); } @@ -68,9 +57,10 @@ export class ShellRunComponent extends Container { finish(stdout: string, stderr: string, isError?: boolean): void { if (this.disposed || !this.running) return; this.running = false; + this.finalStdout = stdout; + this.finalStderr = stderr; + this.finalIsError = isError; this.clearTimer(); - this.finalOutput = formatBashOutputForDisplay(stdout, stderr, isError); - this.rebuildResult(); this.flush(); } @@ -87,41 +77,6 @@ export class ShellRunComponent extends Container { this.clearTimer(); } - setExpanded(expanded: boolean): void { - if (this.disposed || this.expanded === expanded) return; - this.expanded = expanded; - // Running and backgrounded views re-render in place; only a finished - // card rebuilds its result component with the new state. - if (this.running || this.backgrounded) { - this.flush(); - return; - } - this.rebuildResult(); - this.flush(); - } - - // Rebuild-on-toggle, mirroring ToolCallComponent: the result component is - // immutable, so a new expansion state means a new component instance. - private rebuildResult(): void { - try { - // Build before clearing: if the constructor throws, the old view stays. - const next = new TruncatedOutputComponent(this.finalOutput, { - expanded: this.expanded, - // The stream colours are already baked into the formatted text, so - // the component must not re-colour the whole block as an error. - isError: false, - maxLines: SHELL_OUTPUT_PREVIEW_LINES, - expandHint: true, - }); - this.clear(); - this.addChild(next); - } catch { - // finish() runs in a promise continuation and setExpanded() in a key - // handler — an escaping error would surface as an unhandled rejection - // or take down the TUI. - } - } - private tick(): void { if (!this.running) return; this.flush(); @@ -130,9 +85,7 @@ export class ShellRunComponent extends Container { private flush(): void { if (this.disposed) return; try { - if (this.running || this.backgrounded) { - this.textComponent.setText(this.renderText()); - } + this.textComponent.setText(this.renderText()); this.requestRender(); } catch { // Never let a render/render-request error escape into a timer or event @@ -152,6 +105,12 @@ export class ShellRunComponent extends Container { if (this.backgrounded) { return ` ${currentTheme.fg('textDim', 'Moved to background.')}`; } + if (!this.running) { + return formatBashOutputForDisplay(this.finalStdout, this.finalStderr, this.finalIsError) + .split('\n') + .map((line) => ` ${line}`) + .join('\n'); + } const elapsed = Math.floor((Date.now() - this.startedAt) / 1000); const dim = (s: string): string => currentTheme.fg('textDim', s); const trimmed = sanitizeShellOutput(this.combined).trimEnd(); @@ -159,14 +118,6 @@ export class ShellRunComponent extends Container { let extra = 0; if (trimmed.length === 0) { body = ` ${dim('Running…')}`; - } else if (this.expanded) { - const notice = this.combinedTruncated ? ` ${dim(TRUNCATED_RUNNING_NOTICE)}\n` : ''; - body = - notice + - trimmed - .split('\n') - .map((line) => ` ${dim(line)}`) - .join('\n'); } else { const lines = trimmed.split('\n'); const tail = lines.slice(-RUNNING_TAIL_LINES); diff --git a/apps/kimi-code/src/tui/components/messages/status-panel.ts b/apps/kimi-code/src/tui/components/messages/status-panel.ts index dfd1cf8d0..4c6799e03 100644 --- a/apps/kimi-code/src/tui/components/messages/status-panel.ts +++ b/apps/kimi-code/src/tui/components/messages/status-panel.ts @@ -44,9 +44,6 @@ export interface StatusReportOptions { readonly thinkingEffort: ThinkingEffort; readonly permissionMode: PermissionMode; readonly planMode: boolean; - readonly towerMode: boolean; - /** Whether the tower experiment is enabled on engine v2 — gates the Tower mode row. */ - readonly towerAvailable: boolean; readonly contextUsage: number; readonly contextTokens: number; readonly maxContextTokens: number; @@ -109,18 +106,14 @@ export function buildStatusReportLines(options: StatusReportOptions): string[] { const permission = options.status?.permission ?? options.permissionMode; const planMode = options.status?.planMode ?? options.planMode; - const towerMode = options.status?.towerMode ?? options.towerMode; const sessionId = options.sessionId.trim().length > 0 ? options.sessionId : 'none'; const rows: FieldRow[] = [ { label: 'Model', value: formatModelStatus(options) }, { label: 'Directory', value: options.workDir }, { label: 'Permissions', value: permission }, { label: 'Plan mode', value: planMode ? 'on' : 'off' }, + { label: 'Session', value: sessionId }, ]; - if (options.towerAvailable) { - rows.push({ label: 'Tower mode', value: towerMode ? 'on' : 'off' }); - } - rows.push({ label: 'Session', value: sessionId }); const title = options.sessionTitle?.trim(); if (title !== undefined && title.length > 0) rows.push({ label: 'Title', value: title }); if (options.statusError !== undefined) { diff --git a/apps/kimi-code/src/tui/components/messages/tool-call.ts b/apps/kimi-code/src/tui/components/messages/tool-call.ts index 4ca5541bb..050a9a245 100644 --- a/apps/kimi-code/src/tui/components/messages/tool-call.ts +++ b/apps/kimi-code/src/tui/components/messages/tool-call.ts @@ -36,7 +36,6 @@ import { ShellExecutionComponent } from './shell-execution'; import { countNonEmptyLines, pickChip } from './tool-renderers/chip'; import { buildGoalToolHeader } from './tool-renderers/goal'; import { isGenericToolResult, pickResultRenderer } from './tool-renderers/registry'; -import { buildWaitForHeader } from './tool-renderers/wait-for'; const MAX_ARG_LENGTH = 60; const MAX_SUB_TOOL_CALLS_SHOWN = 4; @@ -621,7 +620,6 @@ export class ToolCallComponent extends Container { // spinner). Cleared when the result lands — the result is the // authoritative final state. private progressLines: string[] = []; - private progressStatusRows = 0; private static readonly MAX_PROGRESS_LINES = 24; private liveOutput = ''; @@ -733,7 +731,6 @@ export class ToolCallComponent extends Container { // authoritative final state. Without this clear, a finished tool would // show both the streamed status lines and the final output stacked. this.progressLines = []; - this.progressStatusRows = 0; this.liveOutput = ''; this.detachHintVisible = false; this.stopDetachHintTimer(); @@ -762,26 +759,15 @@ export class ToolCallComponent extends Container { /** * Append a live progress line emitted by the tool via * `onUpdate({kind:'status', text})`. Splits on newlines so multi-line - * status payloads render row-by-row. With `options.replace`, the previous - * replaceable status block is swapped out first — periodic "still - * waiting" updates would otherwise pile up to the cap with stale rows. - * Old lines are dropped once the + * status payloads render row-by-row. Old lines are dropped once the * buffer fills past {@link ToolCallComponent.MAX_PROGRESS_LINES} so a * misbehaving tool can't grow the box unboundedly. */ - appendProgress(text: string, options?: { readonly replace?: boolean }): void { + appendProgress(text: string): void { if (this.result !== undefined) return; - if (options?.replace === true && this.progressStatusRows > 0) { - this.progressLines.splice( - Math.max(0, this.progressLines.length - this.progressStatusRows), - this.progressStatusRows, - ); - } - const lines = text.split('\n'); - for (const line of lines) { + for (const line of text.split('\n')) { this.progressLines.push(line); } - this.progressStatusRows = options?.replace === true ? lines.length : 0; while (this.progressLines.length > ToolCallComponent.MAX_PROGRESS_LINES) { this.progressLines.shift(); } @@ -1393,14 +1379,14 @@ export class ToolCallComponent extends Container { this.ui?.requestRender(); } - appendSubToolLiveOutput(id: string, text: string, options?: { readonly replace?: boolean }): void { + appendSubToolLiveOutput(id: string, text: string): void { if (text.length === 0) return; const activity = this.subToolActivities.get(id); const ongoing = this.ongoingSubCalls.get(id); if (activity === undefined && ongoing === undefined) return; const name = activity?.name ?? ongoing?.name ?? 'Tool'; const args = activity?.args ?? ongoing?.args ?? {}; - const existingOutput = options?.replace === true ? '' : (activity?.output ?? ''); + const existingOutput = activity?.output ?? ''; let output = existingOutput + text; if (output.length > MAX_LIVE_OUTPUT_CHARS) { output = `[...truncated]\n${output.slice(output.length - MAX_LIVE_OUTPUT_CHARS)}`; @@ -1517,14 +1503,6 @@ export class ToolCallComponent extends Container { }); if (goalHeader !== undefined) return goalHeader; - const waitForHeader = buildWaitForHeader({ - toolCall, - result, - bullet, - chip: isFinished && result !== undefined ? this.buildHeaderChip(result) : '', - }); - if (waitForHeader !== undefined) return waitForHeader; - if (this.isSingleSubagentView()) { return this.buildSingleSubagentHeader(); } @@ -1902,7 +1880,7 @@ export class ToolCallComponent extends Container { current?.phase === 'ongoing' && current.output !== undefined && current.output.trim().length > 0 && - (current.name === 'Bash' || current.name === 'WaitFor' || isGenericToolResult(current.name)) + (current.name === 'Bash' || isGenericToolResult(current.name)) ) { return { text: current.output, tone: 'text' }; } diff --git a/apps/kimi-code/src/tui/components/messages/tool-renderers/chip.ts b/apps/kimi-code/src/tui/components/messages/tool-renderers/chip.ts index 37536c140..c7c8120f2 100644 --- a/apps/kimi-code/src/tui/components/messages/tool-renderers/chip.ts +++ b/apps/kimi-code/src/tui/components/messages/tool-renderers/chip.ts @@ -14,7 +14,6 @@ import type { ToolCallBlockData, ToolResultBlockData } from '#/tui/types'; import { goalStatusChip } from './goal'; import { readMediaChip } from './media'; import { strArg } from './types'; -import { waitForChip } from './wait-for'; export type ChipProvider = (toolCall: ToolCallBlockData, result: ToolResultBlockData) => string; @@ -126,7 +125,6 @@ const REGISTRY: Record<string, ChipProvider> = { WebSearch: webSearchChip, CreateGoal: goalStatusOutputChip, GetGoal: goalStatusOutputChip, - WaitFor: waitForChip, }; export function pickChip(toolName: string): ChipProvider | undefined { diff --git a/apps/kimi-code/src/tui/components/messages/tool-renderers/registry.ts b/apps/kimi-code/src/tui/components/messages/tool-renderers/registry.ts index eedc4316a..2a7b39539 100644 --- a/apps/kimi-code/src/tui/components/messages/tool-renderers/registry.ts +++ b/apps/kimi-code/src/tui/components/messages/tool-renderers/registry.ts @@ -13,7 +13,6 @@ import { readMediaSummary } from './media'; import { shellExecutionResultRenderer } from '../shell-execution'; import { goalSummary } from './goal'; -import { waitForSummary } from './wait-for'; import { editSummary, fetchSummary, @@ -64,8 +63,6 @@ export function pickResultRenderer(toolName: string): ResultRenderer { case 'SetGoalBudget': case 'UpdateGoal': return goalSummary; - case 'WaitFor': - return waitForSummary; default: return renderTruncated; } diff --git a/apps/kimi-code/src/tui/components/messages/tool-renderers/wait-for.ts b/apps/kimi-code/src/tui/components/messages/tool-renderers/wait-for.ts deleted file mode 100644 index 8d95a8a66..000000000 --- a/apps/kimi-code/src/tui/components/messages/tool-renderers/wait-for.ts +++ /dev/null @@ -1,179 +0,0 @@ -/** - * WaitFor renderer — the wait result is a timeline (header fields, then - * `[finished]` / `[completed_during_wait]` / `[still_running]` sections), - * so the collapsed body shows what the wait came back with instead of the - * raw key-value dump: the finished task with its outcome, plus counts of - * tasks that finished alongside or are still running. A timeout is not an - * error (the tool says so itself), so it renders in the warning tone. - */ - -import { Text, type Component } from '@moonshot-ai/pi-tui'; - -import { STATUS_BULLET } from '#/tui/constant/symbols'; -import { currentTheme } from '#/tui/theme'; -import type { ToolCallBlockData, ToolResultBlockData } from '#/tui/types'; - -import { formatGoalElapsed } from '../goal-format'; -import { renderTruncated } from './truncated'; -import type { ResultRenderer } from './types'; - -const DESCRIPTION_MAX = 72; -const RUNNING_SAMPLES = 3; - -type WaitForStatus = 'completed' | 'timed_out' | 'no_tasks'; - -interface WaitForResultView { - readonly status: WaitForStatus; - readonly waitedMs: number; - readonly finishedTaskId?: string; - readonly finishedStatus?: string; - readonly finishedDescription?: string; - readonly extraCount: number; - readonly runningCount: number; - readonly runningSamples: readonly string[]; -} - -export const waitForSummary: ResultRenderer = (toolCall, result, ctx) => { - if (result.is_error) return renderTruncated(toolCall, result, ctx); - const view = parseWaitForOutput(result.output); - if (view === undefined) return renderTruncated(toolCall, result, ctx); - - const out: Component[] = []; - for (const line of glanceLines(view)) { - out.push(new Text(` ${currentTheme.dim(line)}`, 0, 0)); - } - if (ctx.expanded && result.output.length > 0) { - out.push(new Text(currentTheme.dim(result.output), 4, 0)); - } - return out; -}; - -export function buildWaitForHeader(options: { - readonly toolCall: ToolCallBlockData; - readonly result: ToolResultBlockData | undefined; - readonly bullet: string; - readonly chip: string; -}): string | undefined { - const { toolCall, result, bullet, chip } = options; - if (toolCall.name !== 'WaitFor') return undefined; - - const taskId = typeof toolCall.args['task_id'] === 'string' ? toolCall.args['task_id'] : undefined; - const argText = - taskId === undefined ? '' : currentTheme.dimFg('textDim', ` (${taskId})`); - - if (result === undefined) { - const label = - taskId === undefined ? 'Waiting for any background task' : 'Waiting for background task'; - return `${bullet}${currentTheme.boldFg('primary', label)}${argText}`; - } - if (result.is_error === true) { - return `${bullet}${currentTheme.boldFg('error', 'Could not wait for background task')}${argText}`; - } - - const status = parseWaitForOutput(result.output)?.status; - if (status === 'timed_out') { - return `${currentTheme.fg('warning', STATUS_BULLET)}${currentTheme.boldFg('warning', 'Wait timed out')}${argText}${chip}`; - } - if (status === 'no_tasks') { - return `${bullet}${currentTheme.boldFg('primary', 'No background tasks running')}${chip}`; - } - const label = taskId === undefined ? 'Waited for a background task' : 'Waited for background task'; - return `${bullet}${currentTheme.boldFg('primary', label)}${argText}${chip}`; -} - -export const waitForChip = (_toolCall: ToolCallBlockData, result: ToolResultBlockData): string => { - if (result.is_error === true) return ''; - const view = parseWaitForOutput(result.output); - if (view === undefined || view.status === 'no_tasks') return ''; - return formatGoalElapsed(view.waitedMs); -}; - -function glanceLines(view: WaitForResultView): string[] { - switch (view.status) { - case 'no_tasks': - return []; - case 'timed_out': { - if (view.runningCount === 0) return []; - const summary = `${pluralizeTasks(view.runningCount)} still running`; - if (view.runningSamples.length === 0) return [summary]; - const remaining = view.runningCount - view.runningSamples.length; - const tail = remaining > 0 ? `, +${String(remaining)} more` : ''; - return [`${summary}: ${view.runningSamples.join(', ')}${tail}`]; - } - case 'completed': { - const taskId = view.finishedTaskId ?? 'task'; - const status = view.finishedStatus ?? 'completed'; - const marker = status === 'completed' ? '✓' : '✗'; - const description = - view.finishedDescription === undefined - ? '' - : ` · ${truncateOneLine(view.finishedDescription, DESCRIPTION_MAX)}`; - const lines = [`${marker} ${taskId} ${status}${description}`]; - const parts: string[] = []; - if (view.extraCount > 0) parts.push(`+${String(view.extraCount)} more finished during wait`); - if (view.runningCount > 0) parts.push(`${pluralizeTasks(view.runningCount)} still running`); - if (parts.length > 0) lines.push(parts.join(' · ')); - return lines; - } - } -} - -function pluralizeTasks(count: number): string { - return `${String(count)} background task${count === 1 ? '' : 's'}`; -} - -function parseWaitForOutput(output: string): WaitForResultView | undefined { - const status = field(output, 'wait_status'); - if (status !== 'completed' && status !== 'timed_out' && status !== 'no_tasks') return undefined; - const waitedMs = Number(field(output, 'waited_ms') ?? 0); - const finished = section(output, 'finished'); - const duringWait = section(output, 'completed_during_wait'); - const stillRunning = section(output, 'still_running'); - const runningCount = stillRunning === undefined ? 0 : countField(stillRunning, 'active_background_tasks'); - return { - status, - waitedMs: Number.isFinite(waitedMs) ? waitedMs : 0, - finishedTaskId: field(output, 'task_id'), - finishedStatus: finished === undefined ? undefined : field(finished, 'status'), - finishedDescription: finished === undefined ? undefined : field(finished, 'description'), - extraCount: duringWait === undefined ? 0 : countOccurrences(duringWait, /^task_id: /gm), - runningCount, - runningSamples: - stillRunning === undefined ? [] : sampleDescriptions(stillRunning, runningCount), - }; -} - -function field(text: string, name: string): string | undefined { - const match = new RegExp(`^${name}: (.+)$`, 'm').exec(text); - return match?.[1]; -} - -function countField(text: string, name: string): number { - const value = Number(field(text, name) ?? 0); - return Number.isFinite(value) ? value : 0; -} - -function section(output: string, name: string): string | undefined { - const match = new RegExp(`^\\[${name}\\]$`, 'm').exec(output); - if (match === null) return undefined; - const rest = output.slice(match.index + match[0].length); - const next = /^\[/m.exec(rest); - return (next === null ? rest : rest.slice(0, next.index)).trim(); -} - -function countOccurrences(text: string, pattern: RegExp): number { - return text.match(pattern)?.length ?? 0; -} - -function sampleDescriptions(stillRunning: string, runningCount: number): readonly string[] { - const descriptions = [...stillRunning.matchAll(/^description: (.+)$/gm)].map((match) => - truncateOneLine(match[1] ?? '', 40), - ); - return descriptions.slice(0, Math.min(RUNNING_SAMPLES, runningCount)); -} - -function truncateOneLine(text: string, max: number): string { - const firstLine = text.replaceAll(/\s+/g, ' ').trim(); - if (firstLine.length <= max) return firstLine; - return `${firstLine.slice(0, Math.max(0, max - 1))}…`; -} diff --git a/apps/kimi-code/src/tui/components/messages/user-message.ts b/apps/kimi-code/src/tui/components/messages/user-message.ts index 4e61ab15c..e7241e963 100644 --- a/apps/kimi-code/src/tui/components/messages/user-message.ts +++ b/apps/kimi-code/src/tui/components/messages/user-message.ts @@ -8,7 +8,6 @@ import { ImageThumbnail } from '#/tui/components/media/image-thumbnail'; import { USER_MESSAGE_BULLET } from '#/tui/constant/symbols'; import { currentTheme } from '#/tui/theme'; import type { ImageAttachment } from '#/tui/utils/image-attachment-store'; -import { markOsc133Zone } from '#/tui/utils/osc133'; import { isRenderCacheEnabled } from '#/tui/utils/render-cache'; export class UserMessageComponent implements Component { @@ -78,17 +77,15 @@ export class UserMessageComponent implements Component { } } - const rendered = markOsc133Zone( - lines.map((line) => { - // Inline image sequences (Kitty / iTerm2) carry their own placement - // information and have zero visible width, but pi-tui's truncateToWidth - // treats the embedded base64 payload as visible text and would chop the - // escape sequence in half, leaving garbage like "0m...". Skip truncation - // for those lines; the image itself already respects maxWidthCells. - if (isImageLine(line)) return line; - return truncateToWidth(line, safeWidth, '…'); - }), - ); + const rendered = lines.map((line) => { + // Inline image sequences (Kitty / iTerm2) carry their own placement + // information and have zero visible width, but pi-tui's truncateToWidth + // treats the embedded base64 payload as visible text and would chop the + // escape sequence in half, leaving garbage like "0m...". Skip truncation + // for those lines; the image itself already respects maxWidthCells. + if (isImageLine(line)) return line; + return truncateToWidth(line, safeWidth, '…'); + }); if (isRenderCacheEnabled()) { this.renderCache = { width: safeWidth, lines: rendered }; } diff --git a/apps/kimi-code/src/tui/components/panes/btw-panel.ts b/apps/kimi-code/src/tui/components/panes/btw-panel.ts index 3dbb88508..f32aa9321 100644 --- a/apps/kimi-code/src/tui/components/panes/btw-panel.ts +++ b/apps/kimi-code/src/tui/components/panes/btw-panel.ts @@ -9,8 +9,6 @@ import chalk from 'chalk'; import { THINKING_PREVIEW_LINES } from '../../constant/rendering'; import { currentTheme } from '../../theme'; -import type { InlineSkillActivation } from '../../types'; -import { createMarkdownOptions } from '../../utils/markdown-options'; type BtwPanelPhase = 'running' | 'done' | 'failed'; @@ -32,10 +30,7 @@ interface BtwBodyRender { export interface BtwPanelOptions { readonly markdownTheme: MarkdownTheme; readonly canUseScrollKeys: () => boolean; - readonly onPrompt: ( - prompt: string, - inlineSkillActivations?: readonly InlineSkillActivation[], - ) => void; + readonly onPrompt: (prompt: string) => void; readonly terminalRows: () => number; } @@ -49,7 +44,7 @@ export class BtwPanelComponent implements Component { constructor(private readonly options: BtwPanelOptions) {} - submit(prompt: string, inlineSkillActivations?: readonly InlineSkillActivation[]): void { + submit(prompt: string): void { const normalized = prompt.trim(); if (normalized.length === 0 || this.isRunning()) return; this.followTail = true; @@ -61,7 +56,7 @@ export class BtwPanelComponent implements Component { thinking: '', phase: 'running', }); - this.options.onPrompt(normalized, inlineSkillActivations); + this.options.onPrompt(normalized); } addTransientNotice(message: string): void { @@ -200,9 +195,7 @@ export class BtwPanelComponent implements Component { const answer = turn.answer.trim(); const thinking = turn.thinking.trim(); if (answer.length > 0) { - lines.push( - ...new Markdown(answer, 0, 0, this.options.markdownTheme, undefined, createMarkdownOptions()).render(width), - ); + lines.push(...new Markdown(answer, 0, 0, this.options.markdownTheme).render(width)); } else if (thinking.length > 0) { const thinkingLines = new Text(chalk.hex(currentTheme.palette.textDim)(thinking), 0, 0).render( width, diff --git a/apps/kimi-code/src/tui/components/panes/queue-pane.ts b/apps/kimi-code/src/tui/components/panes/queue-pane.ts index 209c90266..1a2b26d07 100644 --- a/apps/kimi-code/src/tui/components/panes/queue-pane.ts +++ b/apps/kimi-code/src/tui/components/panes/queue-pane.ts @@ -23,7 +23,7 @@ export class QueuePaneComponent extends Container { if (options.messages.length > 0) { // Bash commands (`! …`) are not steerable, so only advertise Ctrl-S when - // there is at least one plain-text or skill item steering would send. + // there is at least one plain-text item that steering would actually send. const hasSteerable = options.messages.some((m) => m.mode !== 'bash'); const canSteer = options.canSteerImmediately && hasSteerable; this.hint = diff --git a/apps/kimi-code/src/tui/config.ts b/apps/kimi-code/src/tui/config.ts index 5a08af8ff..95f40d6bb 100644 --- a/apps/kimi-code/src/tui/config.ts +++ b/apps/kimi-code/src/tui/config.ts @@ -53,7 +53,6 @@ export const DEFAULT_STATUS_LINE_CONFIG: StatusLineConfig = { export const TuiConfigFileSchema = z.object({ theme: TuiThemeSchema.optional(), - render_latex: z.boolean().optional(), disable_paste_burst: z.boolean().optional(), cache_expiry_hint: z.boolean().optional(), editor: z @@ -77,9 +76,6 @@ export const TuiConfigFileSchema = z.object({ export const TuiConfigSchema = z.object({ theme: TuiThemeSchema, - /** LaTeX math rendering in Markdown; optional only so older hand-built test - * fixtures still typecheck. */ - renderLatex: z.boolean().optional(), disablePasteBurst: z.boolean(), /** Present in every normalized config; optional only so hand-built test * fixtures from before this field existed still typecheck. */ @@ -108,7 +104,6 @@ export const DEFAULT_UPGRADE_PREFERENCES: UpgradePreferences = { export const DEFAULT_TUI_CONFIG: TuiConfig = TuiConfigSchema.parse({ theme: 'auto', - renderLatex: true, disablePasteBurst: false, cacheExpiryHint: true, editorCommand: null, @@ -195,7 +190,6 @@ export function normalizeTuiConfig( .map((item) => item as StatusLineItem) ?? null; return TuiConfigSchema.parse({ theme: config.theme ?? DEFAULT_TUI_CONFIG.theme, - renderLatex: config.render_latex ?? DEFAULT_TUI_CONFIG.renderLatex, disablePasteBurst: config.disable_paste_burst ?? DEFAULT_TUI_CONFIG.disablePasteBurst, cacheExpiryHint: config.cache_expiry_hint ?? DEFAULT_TUI_CONFIG.cacheExpiryHint, editorCommand: command === undefined || command.length === 0 ? null : command, @@ -245,7 +239,6 @@ export function renderTuiConfig(config: TuiConfig): string { # Agent/runtime settings stay in ~/.kimi-code/config.toml. theme = "${escapeTomlBasicString(config.theme)}" # "auto" | "dark" | "light" | custom theme name -render_latex = ${String(config.renderLatex !== false)} # false keeps LaTeX math in assistant messages as raw source disable_paste_burst = ${String(config.disablePasteBurst)} # true disables non-bracketed paste-burst fallback cache_expiry_hint = ${String(config.cacheExpiryHint !== false)} # false disables the "cache expired" dialog on resume / idle submit diff --git a/apps/kimi-code/src/tui/constant/feedback.ts b/apps/kimi-code/src/tui/constant/feedback.ts index f33fc112c..8f2ad7a0f 100644 --- a/apps/kimi-code/src/tui/constant/feedback.ts +++ b/apps/kimi-code/src/tui/constant/feedback.ts @@ -13,7 +13,7 @@ export { FEEDBACK_ISSUE_URL, FEEDBACK_TELEMETRY_EVENT, FEEDBACK_VERSION_PREFIX, - kimiCodeSignupUrl, + KIMI_CODE_SIGNUP_URL, } from '#/constant/app'; export const FEEDBACK_STATUS_SUBMITTING = 'Submitting feedback…'; diff --git a/apps/kimi-code/src/tui/constant/kimi-tui.ts b/apps/kimi-code/src/tui/constant/kimi-tui.ts index 45c77d177..642323539 100644 --- a/apps/kimi-code/src/tui/constant/kimi-tui.ts +++ b/apps/kimi-code/src/tui/constant/kimi-tui.ts @@ -10,10 +10,6 @@ export const MAIN_AGENT_ID = 'main'; export const OAUTH_LOGIN_REQUIRED_STARTUP_NOTICE = 'OAuth login expired. Send /login to login.'; export const SESSIONLESS_STARTUP_NOTICE = 'No session yet — one will be created on your first message.'; -export const TOWER_STATUS_PROMPT = - 'Report the current tower status: call TowerStatus and give a compact summary.'; -export const TOWER_TEARDOWN_PROMPT = - 'Tear down the tower: call TowerTeardown and report what it did. It refuses to destroy dirty worktrees unless forced.'; export const EXIT_CONFIRM_WINDOW_MS = 1500; // Time window for treating two consecutive Esc presses as a double-Esc, which // opens the undo selector. Kept short (double-click feel) so two deliberate diff --git a/apps/kimi-code/src/tui/constant/media.ts b/apps/kimi-code/src/tui/constant/media.ts deleted file mode 100644 index 67618714d..000000000 --- a/apps/kimi-code/src/tui/constant/media.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** TUI-only daemon staging lifetimes for pasted media. */ - -export const MEDIA_STAGING_TTL_SECONDS = 60 * 60; -export const MEDIA_FILE_REF_MIN_REMAINING_MS = 60_000; -/** How long submit waits for a just-pasted medium's background ingestion before giving up on the daemon-ref form. */ -export const MEDIA_INGESTION_SUBMIT_WAIT_MS = 2_000; diff --git a/apps/kimi-code/src/tui/constant/rendering.ts b/apps/kimi-code/src/tui/constant/rendering.ts index 8b20e9a95..d3de252f3 100644 --- a/apps/kimi-code/src/tui/constant/rendering.ts +++ b/apps/kimi-code/src/tui/constant/rendering.ts @@ -1,15 +1,6 @@ // Continuation indent for transcript rows that use a two-cell leading marker. export const MESSAGE_INDENT = ' '; -// OSC 133 semantic-zone markers (FinalTerm/shell-integration protocol): -// zero-width escape sequences prefixed onto the first/last rendered line of -// transcript messages. The fullscreen renderer strips them at paint and uses -// the A marker for previous/next-prompt navigation (Ctrl-Shift-Up/Down); in -// regular mode they pass through to native scrollback invisibly. -export const OSC133_ZONE_START = '\x1b]133;A\x07'; -export const OSC133_ZONE_END = '\x1b]133;B\x07'; -export const OSC133_ZONE_FINAL = '\x1b]133;C\x07'; - // Outer left/right padding applied to the transcript, panels, and the // statusline so the chrome's left edge lines up with the input box's // interior (the `>` prompt). The editor itself stays at column 0 — its @@ -18,8 +9,6 @@ export const CHROME_GUTTER = 1; // Shared preview caps used by thinking, tool results, and shell snippets. export const RESULT_PREVIEW_LINES = 3; -// Collapsed row cap for a finished `!` shell command's output card. -export const SHELL_OUTPUT_PREVIEW_LINES = 10; export const THINKING_PREVIEW_LINES = 2; export const COMMAND_PREVIEW_LINES = 10; diff --git a/apps/kimi-code/src/tui/controllers/auth-flow.ts b/apps/kimi-code/src/tui/controllers/auth-flow.ts index 0940e445a..67fac913c 100644 --- a/apps/kimi-code/src/tui/controllers/auth-flow.ts +++ b/apps/kimi-code/src/tui/controllers/auth-flow.ts @@ -40,6 +40,7 @@ export interface AuthFlowHost { resetSessionRuntime(): void; setSession(session: Session): Promise<void>; syncRuntimeState(session?: Session): Promise<void>; + closeSession(reason: string): Promise<void>; appendStartupNotice(extra: string): void; hydrateLazyConfigDefaults(): Promise<void>; readonly sessionEventHandler: SessionEventHandler; @@ -133,6 +134,18 @@ export class AuthFlowController { void host.refreshPluginCommands(host.session); } + async clearActiveSessionAfterLogout(): Promise<void> { + await this.host.closeSession('logged out'); + this.host.resetSessionRuntime(); + this.host.setAppState({ + sessionId: '', + model: '', + sessionTitle: null, + }); + await this.host.refreshSkillCommands(); + await this.host.refreshPluginCommands(); + } + async refreshConfigAfterLogin(): Promise<void> { const { host } = this; const config = await host.harness.getConfig({ reload: true }); @@ -170,17 +183,9 @@ export class AuthFlowController { async refreshConfigAfterLogout(): Promise<void> { const config = await this.host.harness.getConfig({ reload: true }); - const availableModels = config.models ?? {}; - const availableProviders = config.providers ?? {}; - - if (this.host.session !== undefined) { - this.host.setAppState({ availableModels, availableProviders }); - return; - } - this.host.setAppState({ - availableModels, - availableProviders, + availableModels: config.models ?? {}, + availableProviders: config.providers ?? {}, model: '', thinkingEffort: 'off', maxContextTokens: 0, diff --git a/apps/kimi-code/src/tui/controllers/btw-panel.ts b/apps/kimi-code/src/tui/controllers/btw-panel.ts index 186e1b85b..a8ee45e61 100644 --- a/apps/kimi-code/src/tui/controllers/btw-panel.ts +++ b/apps/kimi-code/src/tui/controllers/btw-panel.ts @@ -11,7 +11,6 @@ import { BtwPanelComponent } from '../components/panes/btw-panel'; import { formatErrorMessage } from '../utils/event-payload'; import { formatHookResultPlain } from '../utils/hook-result-format'; import { createMarkdownTheme } from '../theme/pi-tui-theme'; -import type { InlineSkillActivation } from '../types'; import type { TUIState } from '../tui-state'; const BTW_BUSY_NOTICE = 'Wait for /btw to finish before sending another question.'; @@ -35,24 +34,20 @@ export class BtwPanelController { constructor(private readonly host: BtwPanelHost) {} - open( - agentId: string, - initialPrompt: string, - inlineSkillActivations?: readonly InlineSkillActivation[], - ): void { + open(agentId: string, initialPrompt: string): void { let panel: BtwPanelComponent; panel = new BtwPanelComponent({ markdownTheme: createMarkdownTheme(), canUseScrollKeys: () => this.host.state.editor.getText().length === 0, terminalRows: () => this.host.state.terminal.rows, - onPrompt: (prompt, inlineSkillActivations) => { - this.promptAgent(agentId, prompt, panel, inlineSkillActivations); + onPrompt: (prompt) => { + this.promptAgent(agentId, prompt, panel); }, }); this.active = { agentId, panel }; this.panelsByAgentId.set(agentId, panel); this.mount(panel); - panel.submit(initialPrompt, inlineSkillActivations); + panel.submit(initialPrompt); } clear(): void { @@ -84,14 +79,14 @@ export class BtwPanelController { return true; } - sendUserInput(text: string, inlineSkillActivations?: readonly InlineSkillActivation[]): boolean { + sendUserInput(text: string): boolean { const active = this.active; if (active === undefined) return false; if (active.panel.isRunning()) { this.showBusyNotice(active, text); return true; } - active.panel.submit(text, inlineSkillActivations); + active.panel.submit(text); this.host.state.ui.setFocus(this.host.state.editor); this.host.state.ui.requestRender(); return true; @@ -170,30 +165,14 @@ export class BtwPanelController { this.host.state.ui.requestRender(); } - private promptAgent( - agentId: string, - prompt: string, - panel: BtwPanelComponent, - inlineSkillActivations?: readonly InlineSkillActivation[], - ): void { + private promptAgent(agentId: string, prompt: string, panel: BtwPanelComponent): void { const session = this.host.session; if (session === undefined) { panel.markFailed(NO_ACTIVE_SESSION_MESSAGE); this.host.state.ui.requestRender(); return; } - const send = - inlineSkillActivations !== undefined && inlineSkillActivations.length > 0 - ? () => - session.promptWithSkills( - prompt, - inlineSkillActivations.map((activation) => ({ - name: activation.skillName, - args: activation.args, - })), - ) - : () => session.prompt(prompt); - void this.withInteractiveAgent(agentId, send).catch((error: unknown) => { + void this.withInteractiveAgent(agentId, () => session.prompt(prompt)).catch((error: unknown) => { panel.markFailed(`Failed to send /btw prompt: ${formatErrorMessage(error)}`); this.host.state.ui.requestRender(); }); diff --git a/apps/kimi-code/src/tui/controllers/cache-hint-controller.ts b/apps/kimi-code/src/tui/controllers/cache-hint-controller.ts index 5863d7679..4a1aa4626 100644 --- a/apps/kimi-code/src/tui/controllers/cache-hint-controller.ts +++ b/apps/kimi-code/src/tui/controllers/cache-hint-controller.ts @@ -17,24 +17,17 @@ import { } from '../components/dialogs/cache-hint-dialog'; import { saveTuiConfig } from '../config'; import { MAIN_AGENT_ID } from '../constant/kimi-tui'; -import type { AppState, InlineSkillActivation } from '../types'; +import type { AppState } from '../types'; import type { TUIState } from '../tui-state'; import { evaluateCacheHint } from '../utils/cache-hint'; import { formatErrorMessage } from '../utils/event-payload'; -import { - makeExtractionResendable, - originalsDirForSession, - type ExtractionResult, -} from '../utils/image-placeholder'; +import type { ExtractionResult } from '../utils/image-placeholder'; /** A swallowed submit: the raw text plus its media extraction (done before * the dialog so pasted attachments survive a later store clear). */ interface StashedSubmit { readonly text: string; readonly extraction?: ExtractionResult; - /** Session that owned any daemon refs inside {@link extraction}. */ - readonly sessionId: string; - readonly inlineSkillActivations?: readonly InlineSkillActivation[]; } export interface CacheHintHost { @@ -47,20 +40,9 @@ export interface CacheHintHost { mountEditorReplacement(panel: Component & Focusable): void; restoreEditor(): void; restoreInputText(text: string): void; - /** - * A stashed submission going back to the editor releases its extraction's - * staged media with queue-recall semantics (consume retains, retire staged - * copies, rebase videos) — without this the retains/copies would leak. - */ - recallStashedMedia(extraction: ExtractionResult | undefined): void; showError(message: string): void; createNewSession(): Promise<void>; sendNormalUserInput(text: string, preExtracted?: ExtractionResult): Promise<void>; - sendInlineSkillUserInput( - text: string, - activations: readonly InlineSkillActivation[], - preExtracted?: ExtractionResult, - ): Promise<void>; } type HintDecision = { readonly idleSeconds: number; readonly totalTokens: number }; @@ -254,11 +236,7 @@ export class CacheHintController { * is swallowed while the config is fetched (spec: the trigger must reach * the interface); the message is then either shown the dialog or released. */ - maybeInterceptOnSubmit( - text: string, - extraction?: ExtractionResult, - inlineSkillActivations?: readonly InlineSkillActivation[], - ): boolean { + maybeInterceptOnSubmit(text: string, extraction?: ExtractionResult): boolean { const { host } = this; if (!host.engineV2 || host.session === undefined) return false; // A stashed message being released re-enters the send path here — never @@ -275,7 +253,7 @@ export class CacheHintController { // Coarse floor: configured cache durations are 10min+, so anything // fresher than a minute can never hint. if (Date.now() - this.lastActivityAt < 60_000) return false; - const stash: StashedSubmit = { text, extraction, sessionId: host.session.id, inlineSkillActivations }; + const stash: StashedSubmit = { text, extraction }; const cached = peekCacheHintConfig(); if (cached !== undefined) { const decision = evaluateCacheHint({ @@ -317,7 +295,7 @@ export class CacheHintController { // would reorder the conversation. if (this.idlePrompted) { if (this.lastDialogRestored) { - this.restoreStashedInput(stash); + this.restoreStashedInput(stash.text); } else { await this.releaseStashed(stash); } @@ -328,7 +306,7 @@ export class CacheHintController { // meanwhile, never send the stashed text into the wrong session — hand it // back to the editor instead. if (host.session?.id !== sessionId) { - this.restoreStashedInput(stash); + this.restoreStashedInput(stash.text); return; } // If a foreground operation (turn, /compact, …) started meanwhile, don't @@ -364,37 +342,18 @@ export class CacheHintController { private async releaseStashed(stash: StashedSubmit): Promise<void> { this.releasingStashed = true; try { - await this.releaseToSendPath(stash); + await this.host.sendNormalUserInput(stash.text, stash.extraction); } finally { this.releasingStashed = false; } } - private async releaseToSendPath(stash: StashedSubmit): Promise<void> { - // A session reset cleared the image store: rebuild the extraction from - // its snapshots, persisting compressed pastes' originals into the NEW - // session's originals dir so the compression caption survives the move. - const extraction = - stash.extraction !== undefined && this.host.state.appState.sessionId !== stash.sessionId - ? makeExtractionResendable(stash.extraction, originalsDirForSession(this.host.session)) - : stash.extraction; - if (stash.inlineSkillActivations !== undefined && stash.inlineSkillActivations.length > 0) { - await this.host.sendInlineSkillUserInput(stash.text, stash.inlineSkillActivations, extraction); - return; - } - await this.host.sendNormalUserInput(stash.text, extraction); - } - /** Restore a stashed input to the editor, appending to anything already - * restored this cycle so earlier text is not overwritten, and release the - * stash's staged media with recall semantics — the restored draft still - * references its attachments, so retains are consumed (the next submit - * re-retains) and staged copies retire instead of leaking. */ - private restoreStashedInput(stash: StashedSubmit | undefined): void { - if (stash === undefined) return; - this.restoredTexts.push(stash.text); + * restored this cycle so earlier text is not overwritten. */ + private restoreStashedInput(text: string | undefined): void { + if (text === undefined) return; + this.restoredTexts.push(text); this.host.restoreInputText(this.restoredTexts.join('\n')); - this.host.recallStashedMedia(stash.extraction); } private upstreamModelId(): string | undefined { @@ -460,7 +419,7 @@ export class CacheHintController { const { host } = this; const restoreInput = () => { this.lastDialogRestored = true; - this.restoreStashedInput(stashed); + this.restoreStashedInput(stashed?.text); }; switch (action) { case 'dismiss': @@ -511,7 +470,7 @@ export class CacheHintController { break; } this.lastDialogRestored = false; - if (stashed !== undefined) await this.releaseStashed(stashed); + if (stashed !== undefined) await host.sendNormalUserInput(stashed.text, stashed.extraction); } /** Bounded wait for the engine to flip `isCompacting` after a compact RPC. */ diff --git a/apps/kimi-code/src/tui/controllers/editor-keyboard.ts b/apps/kimi-code/src/tui/controllers/editor-keyboard.ts index e4474e742..55df80609 100644 --- a/apps/kimi-code/src/tui/controllers/editor-keyboard.ts +++ b/apps/kimi-code/src/tui/controllers/editor-keyboard.ts @@ -1,13 +1,7 @@ -import { readFile } from 'node:fs/promises'; +import type { KimiHarness, Session } from '@moonshot-ai/kimi-code-sdk'; +import { compressImageForModel, persistOriginalImage, sessionMediaOriginalsDir } from '@moonshot-ai/kimi-code-sdk'; -import type { FileMeta, KimiHarness, Session } from '@moonshot-ai/kimi-code-sdk'; -import { compressImageForModel } from '@moonshot-ai/kimi-code-sdk'; - -import { - ClipboardMediaError, - readClipboardMedia, - type ClipboardVideo, -} from '#/utils/clipboard/clipboard-image'; +import { ClipboardMediaError, readClipboardMedia } from '#/utils/clipboard/clipboard-image'; import { parseImageMeta } from '#/utils/image/image-mime'; import { editInExternalEditor, resolveEditorCommand } from '#/utils/process/external-editor'; @@ -19,15 +13,9 @@ import { LLM_NOT_SET_MESSAGE, NO_ACTIVE_SESSION_MESSAGE, } from '../constant/kimi-tui'; -import { MEDIA_STAGING_TTL_SECONDS } from '../constant/media'; import { formatErrorMessage } from '../utils/event-payload'; -import type { - ImageAttachment, - ImageAttachmentStore, - VideoAttachment, -} from '../utils/image-attachment-store'; -import { extractMediaAttachments, imageExtensionForMime } from '../utils/image-placeholder'; -import { extractInlineSkillActivations } from '../utils/inline-skill-tokens'; +import type { ImageAttachmentStore } from '../utils/image-attachment-store'; +import { extractMediaAttachments } from '../utils/image-placeholder'; import type { PendingExit, QueuedMessage, SteerInputItem } from '../types'; import type { TUIState } from '../tui-state'; import type { BtwPanelController } from './btw-panel'; @@ -35,12 +23,6 @@ import type { BtwPanelController } from './btw-panel'; export interface EditorKeyboardHost { state: TUIState; session: Session | undefined; - /** - * True when the TUI runs on the agent-core-v2 engine (startup-selected). - * Gates the paste-time upload to the daemon file store; the v1 engine has - * no file store, so images keep the submit-time inline base64 form and - * videos cannot be submitted at all. - */ readonly engineV2: boolean; cancelInFlight: (() => void) | undefined; /** @@ -52,21 +34,16 @@ export interface EditorKeyboardHost { handleUserInput(text: string): void; readonly btwPanelController: BtwPanelController; - readonly skillCommandMap: Map<string, string>; steerMessage(session: Session, input: readonly SteerInputItem[]): void; - steerSkillActivation(session: Session, skillName: string, skillArgs: string): void; validateMediaCapabilities(extraction: { hasMedia: boolean; imageAttachmentIds: readonly number[]; videoAttachmentIds: readonly number[]; }): boolean; - releaseStagingMedia(mediaAttachmentIds: readonly number[]): void; recallLastQueued(): QueuedMessage | undefined; showError(msg: string): void; track(event: string, props?: Record<string, unknown>): void; updateEditorBorderHighlight(text?: string): void; - /** `undefined` means the input cannot be a `/goal` command (clear without measuring). */ - updateGoalLengthWarning(text: string | undefined): void; updateQueueDisplay(): void; toggleToolOutputExpansion(): void; toggleTodoPanelExpansion(): void; @@ -80,7 +57,6 @@ export interface EditorKeyboardHost { handleInputModeChange(mode: 'prompt' | 'bash'): void; clearQueuedMessages(): void; setExternalEditorRunning(running: boolean): void; - updateActivityPane(): void; } export class EditorKeyboardController { @@ -103,24 +79,6 @@ export class EditorKeyboardController { editor.onChange = (text: string) => { if (this.pendingExit) this.clearPendingExit(); host.updateEditorBorderHighlight(text); - // Expanding paste markers costs a full-text pass, and only `/goal` - // input can trip the objective length limit — so skip the expansion - // for ordinary prompts. Submitted text is trimmed before dispatch, so - // gate on the trimmed text too. A paste marker may itself expand into - // part of the command (`[paste #…]` → `/goal …`, or completing a - // partial prefix like `/go[paste #1 …]` → `/goal …`), so any input - // containing a marker that can still become a `/goal` command must - // pass the gate as well. - const trimmed = text.trimStart(); - const mightBeGoal = - trimmed.startsWith('/goal') || - trimmed.startsWith('[paste #') || - (trimmed.startsWith('/') && trimmed.includes('[paste #')); - if (editor.inputMode !== 'bash' && mightBeGoal) { - host.updateGoalLengthWarning(editor.getExpandedText()); - } else { - host.updateGoalLengthWarning(undefined); - } }; // bash mode recalls only shell (`!`-prefixed) history entries; prompt mode @@ -311,86 +269,41 @@ export class EditorKeyboardController { const text = editor.getText().trim(); const editorIsBash = editor.inputMode === 'bash'; - // Bash commands (`! …`) are not steerable: they stay queued so they run - // after the current task. Grouped inline-skill submissions are not - // steerable either — steer carries no skill activations, so they stay - // queued and submit intact when the session drains; the same applies to - // an editor draft carrying inline skill tokens. Steering stops at the - // first such bundle: items behind it stay queued too, or a later - // message would jump ahead of its bundle and reverse the conversational - // order. Everything else steers in queue order — plain text as a - // steered message, slash-skill items as activations fired into the - // running turn (never as literal text). + // Bash commands (`! …`) are not steerable: keep them queued so they run + // after the current task instead of being injected into the turn as text. const queued = host.state.queuedMessages; - const firstBundle = queued.findIndex((m) => m.inlineSkillActivations !== undefined); - const windowBeforeFirstBundle = firstBundle === -1 ? queued : queued.slice(0, firstBundle); - const steerable = windowBeforeFirstBundle.filter((m) => m.mode !== 'bash'); - const editorHasInlineSkills = - !editorIsBash && - text.length > 0 && - host.engineV2 && - extractInlineSkillActivations(text, host.skillCommandMap).length > 0; + const steerable = queued.filter((m) => m.mode !== 'bash'); - type SteerRun = - | { readonly kind: 'text'; readonly items: SteerInputItem[] } - | { readonly kind: 'skill'; readonly skillName: string; readonly skillArgs: string }; - const runs: SteerRun[] = []; - let textRun: SteerInputItem[] = []; - const flushTextRun = (): void => { - if (textRun.length > 0) { - runs.push({ kind: 'text', items: textRun }); - textRun = []; - } - }; + const items: SteerInputItem[] = []; for (const m of steerable) { - if (m.mode === 'skill' && m.skillName !== undefined) { - flushTextRun(); - runs.push({ kind: 'skill', skillName: m.skillName, skillArgs: m.skillArgs ?? '' }); - continue; - } const trimmed = m.text.trim(); if (trimmed.length > 0) { // Queued items carry the parts extracted when they were submitted // (and were already capability-validated then). - textRun.push({ - text: trimmed, - parts: m.parts, - imageAttachmentIds: m.imageAttachmentIds, - videoAttachmentIds: m.videoAttachmentIds, - }); + items.push({ text: trimmed, parts: m.parts, imageAttachmentIds: m.imageAttachmentIds }); } } let editorExtraction: ReturnType<typeof extractMediaAttachments> | undefined; - if (!editorIsBash && text.length > 0 && !editorHasInlineSkills && firstBundle === -1) { + if (!editorIsBash && text.length > 0) { try { - // Synchronous path: an image still ingesting in the background - // extracts to its inline fallback here (no bounded wait like - // `sendNormalUserInput` — this handler cannot await without - // interleaving queue/draft edits); a video still uploading refuses - // the submission instead (no inline form exists). editorExtraction = extractMediaAttachments(text, this.imageStore); } catch (error) { - // Media expansion failed (e.g. the pasted video's upload is still - // in flight) — leave the queue and the editor draft untouched. + // Cache copy failed (e.g. the pasted video's source vanished) — + // leave the queue and the editor draft untouched. host.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); return; } - textRun.push({ + items.push({ text, parts: editorExtraction.hasMedia ? editorExtraction.parts : undefined, imageAttachmentIds: editorExtraction.imageAttachmentIds.length > 0 ? editorExtraction.imageAttachmentIds : undefined, - videoAttachmentIds: - editorExtraction.videoAttachmentIds.length > 0 - ? editorExtraction.videoAttachmentIds - : undefined, }); } - flushTextRun(); - if (runs.length > 0) { + if (items.length > 0) { // The editor draft is fresh input: gate it on the model's media // capabilities before splicing the queue, so a rejection leaves the // queue and the draft untouched. @@ -398,31 +311,15 @@ export class EditorKeyboardController { editorExtraction !== undefined && !host.validateMediaCapabilities(editorExtraction) ) { - host.releaseStagingMedia([ - ...editorExtraction.imageAttachmentIds, - ...editorExtraction.videoAttachmentIds, - ]); return; } + host.state.queuedMessages = queued.filter((m) => m.mode === 'bash'); + if (!editorIsBash) editor.setText(''); const session = host.session; if (host.state.appState.model.trim().length === 0 || session === undefined) { - host.releaseStagingMedia([ - ...(editorExtraction?.imageAttachmentIds ?? []), - ...(editorExtraction?.videoAttachmentIds ?? []), - ]); host.showError(LLM_NOT_SET_MESSAGE); - return; - } - host.state.queuedMessages = queued.filter( - (m, index) => m.mode === 'bash' || (firstBundle !== -1 && index >= firstBundle), - ); - if (!editorIsBash && !editorHasInlineSkills && firstBundle === -1) editor.setText(''); - for (const run of runs) { - if (run.kind === 'text') { - host.steerMessage(session, run.items); - } else { - host.steerSkillActivation(session, run.skillName, run.skillArgs); - } + } else { + host.steerMessage(session, items); } } host.updateQueueDisplay(); @@ -456,9 +353,7 @@ export class EditorKeyboardController { editor.setText(recalled.text); // Restore the queued item's mode so a recalled `!` command runs as a // shell command again instead of being submitted as a normal prompt. - // Skill activations recall as prompt mode: their text is the original - // `/name args` slash command, which re-parses on submit. - const mode = recalled.mode === 'bash' ? 'bash' : 'prompt'; + const mode = recalled.mode ?? 'prompt'; if (editor.inputMode !== mode) { editor.inputMode = mode; editor.onInputModeChange?.(mode); @@ -555,79 +450,27 @@ export class EditorKeyboardController { if (media === null) return false; if (media.kind === 'video') { - // Same shape as the image flow below: register the attachment and put - // its placeholder in the editor first, then upload the source file to - // the daemon file store in the background — typing never waits on it, - // and submit gives a pending upload the bounded `pendingMediaIngestions` - // wait. Unlike an image there is no inline fallback form, so a video - // whose upload has not landed (or failed) refuses the submission at - // extraction time. const attachment = this.imageStore.addVideo(media.mimeType, media.sourcePath, media.filename); this.host.state.editor.insertTextAtCursor?.(`${attachment.placeholder} `); this.host.state.ui.requestRender(); this.host.track('shortcut_paste', { kind: 'video' }); - attachment.pending = this.finishClipboardVideoPaste(attachment, media).catch( - (error: unknown) => { - this.host.showError(`Failed to process pasted video: ${formatErrorMessage(error)}`); - }, - ); return true; } const meta = parseImageMeta(media.bytes); if (meta === null) return false; - - // Register the attachment and put its placeholder in the editor before - // any of the asynchronous ingestion work below. CustomEditor only holds - // keystrokes until this handler settles, so the callback returns right - // after the placeholder lands and ingestion continues in the background — - // typing never waits on compression or the daemon upload. Submit gives a - // pending ingestion a bounded wait (`pendingImageIngestions`) and falls - // back to the inline form when it has not finished. - const attachment = this.imageStore.addImage( - media.bytes, - meta.mime, - meta.width, - meta.height, - ); - this.host.state.editor.insertTextAtCursor?.(`${attachment.placeholder} `); - this.host.state.ui.requestRender(); - this.host.track('shortcut_paste', { kind: 'image' }); - - attachment.pending = this.finishClipboardImagePaste( - attachment, - media.bytes, - meta.mime, - meta.width, - meta.height, - ).catch((error: unknown) => { - // The raw attachment and its already-visible placeholder are still a - // valid inline fallback when optional ingestion work fails. - this.host.showError(`Failed to process pasted image: ${formatErrorMessage(error)}`); - }); - return true; - } - - private async finishClipboardImagePaste( - attachment: ImageAttachment, - originalBytes: Uint8Array, - originalMime: string, - originalWidth: number, - originalHeight: number, - ): Promise<void> { // Compress at ingestion — a pure data step while building the attachment, so // the stored bytes, the inline thumbnail, the `[image #N (W×H)]` placeholder, // and the submitted image all agree, and the agent core only ever sees an // already-compressed image. Best effort: originals pass through on failure. - // When compression changed the bytes, the pre-compression original is kept - // on the attachment in memory: the session whose media-originals dir it - // belongs in may not exist yet at paste time, so dispatch-time caption - // resolution (`resolveOriginalCaptions`) persists it and announces the - // compression, pointing the model at the full-fidelity copy. + // When compression changed the bytes, the original is persisted (into the + // session's media-originals dir when known, else the temp-dir fallback) + // and recorded on the attachment, so submit-time expansion can announce + // the compression and point the model at the full-fidelity copy. // The edge cap comes from the host harness's [image] config (resolved per // paste so a config reload applies immediately); hosts without a harness // use the env/built-in default. - const compressed = await compressImageForModel(originalBytes, originalMime, { + const compressed = await compressImageForModel(media.bytes, meta.mime, { maxEdge: this.host.harness?.imageLimits?.maxEdgePx(), telemetry: { client: { @@ -637,112 +480,39 @@ export class EditorKeyboardController { source: 'tui_paste', }, }); + const sessionDir = this.host.session?.summary?.sessionDir; // Dimensions come from the compression result, not parseImageMeta: the // compressor reports display space (EXIF orientation applied) — the space // the sent image, the caption, and ReadMediaFile region readback share — // while parseImageMeta reads the raw pre-rotation header. - const original = compressed.changed - ? { - bytes: originalBytes, - width: compressed.originalWidth, - height: compressed.originalHeight, - byteLength: originalBytes.length, - mime: originalMime, - } - : undefined; - // v2 only: upload the final bytes to the daemon file store so submit-time - // expansion emits a `kimi-file://` reference instead of inline base64. - const uploaded = await this.uploadImageToDaemonFileStore( - compressed.changed ? compressed.data : originalBytes, - compressed.changed ? compressed.mimeType : originalMime, - ); - const completed = this.imageStore.completeImage(attachment, { - bytes: compressed.changed ? compressed.data : originalBytes, - mime: compressed.changed ? compressed.mimeType : originalMime, - width: compressed.width || originalWidth, - height: compressed.height || originalHeight, - original, - fileId: uploaded?.id, - fileExpiresAt: parseExpiry(uploaded), - }); - if (completed === undefined && uploaded !== undefined) { - await this.host.harness?.deleteFile(uploaded.id).catch(() => undefined); - } - this.host.state.ui.requestRender(); - } - - /** - * Paste-time upload of the final image bytes to the engine's daemon file - * store (agent-core-v2 only), run as part of the background ingestion — - * typing never waits on it, and submit only gives it the bounded - * `pendingImageIngestions` wait. Best effort: any failure returns undefined, - * so the attachment keeps no `fileId` and submit-time expansion falls back - * to the inline base64 form. - */ - private async uploadImageToDaemonFileStore( - bytes: Uint8Array, - mime: string, - ): Promise<FileMeta | undefined> { - if (!this.host.engineV2) return undefined; - const harness = this.host.harness; - if (harness === undefined) return undefined; - try { - const meta = await harness.uploadFile(bytes, { - name: `pasted-image.${imageExtensionForMime(mime)}`, - mimeType: mime, - expiresInSec: MEDIA_STAGING_TTL_SECONDS, - }); - return meta; - } catch { - return undefined; - } - } - - /** - * Paste-time upload of the video's source file to the engine's daemon file - * store (agent-core-v2 only), run as background ingestion exactly like the - * image upload above. Best effort: any failure returns undefined, leaving - * the attachment without a `fileId` — submit-time expansion then refuses - * the submission, since a video has no inline fallback form. - */ - private async uploadVideoToDaemonFileStore( - media: ClipboardVideo, - ): Promise<FileMeta | undefined> { - if (!this.host.engineV2) return undefined; - const harness = this.host.harness; - if (harness === undefined) return undefined; - let bytes: Uint8Array; - try { - bytes = await readFile(media.sourcePath); - } catch { - // The source (e.g. a clipboard temp file) vanished before the upload - // could read it — same outcome as a failed upload. - return undefined; - } - try { - return await harness.uploadFile(bytes, { - name: media.filename, - mimeType: media.mimeType, - expiresInSec: MEDIA_STAGING_TTL_SECONDS, - }); - } catch { - return undefined; - } - } - - private async finishClipboardVideoPaste( - attachment: VideoAttachment, - media: ClipboardVideo, - ): Promise<void> { - const uploaded = await this.uploadVideoToDaemonFileStore(media); - const completed = this.imageStore.completeVideo(attachment, { - fileId: uploaded?.id, - fileExpiresAt: parseExpiry(uploaded), - }); - if (completed === undefined && uploaded !== undefined) { - await this.host.harness?.deleteFile(uploaded.id).catch(() => undefined); - } + const attachment = compressed.changed + ? this.imageStore.addImage( + compressed.data, + compressed.mimeType, + compressed.width, + compressed.height, + { + path: await persistOriginalImage( + media.bytes, + meta.mime, + sessionDir === undefined ? {} : { dir: sessionMediaOriginalsDir(sessionDir) }, + ), + width: compressed.originalWidth, + height: compressed.originalHeight, + byteLength: media.bytes.length, + mime: meta.mime, + }, + ) + : this.imageStore.addImage( + media.bytes, + meta.mime, + compressed.width || meta.width, + compressed.height || meta.height, + ); + this.host.state.editor.insertTextAtCursor?.(`${attachment.placeholder} `); this.host.state.ui.requestRender(); + this.host.track('shortcut_paste', { kind: 'image' }); + return true; } private async openExternalEditor(): Promise<void> { @@ -755,10 +525,7 @@ export class EditorKeyboardController { } this.host.setExternalEditorRunning(true); const seed = state.editor.getExpandedText?.() ?? state.editor.getText(); - // Fullscreen: a plain stop() would replay the whole transcript into the - // main screen on exit; the external editor only needs the alternate - // screen released, so preserve the screen instead. - state.ui.stop({ preserveScreen: state.ui.mode === 'fullscreen' ? true : undefined }); + state.ui.stop(); await new Promise<void>((resolve) => { setImmediate(resolve); }); @@ -777,18 +544,7 @@ export class EditorKeyboardController { state.ui.start(); state.ui.setFocus(state.editor); state.ui.requestRender(true); - // terminal.stop() cleared the OSC 9;4 progress indicator while the - // app-side progressActive flag still reads true; resync so a turn that - // was streaming while the editor was open gets its progress back. - state.terminalState.progressActive = false; - this.host.updateActivityPane(); this.host.setExternalEditorRunning(false); } } } - -function parseExpiry(meta: FileMeta | undefined): number | undefined { - if (meta?.expires_at === undefined) return undefined; - const value = Date.parse(meta.expires_at); - return Number.isFinite(value) ? value : undefined; -} diff --git a/apps/kimi-code/src/tui/controllers/plugin-update-notifier.ts b/apps/kimi-code/src/tui/controllers/plugin-update-notifier.ts index 3f8e21585..ab6d72807 100644 --- a/apps/kimi-code/src/tui/controllers/plugin-update-notifier.ts +++ b/apps/kimi-code/src/tui/controllers/plugin-update-notifier.ts @@ -1,6 +1,6 @@ import type { PluginSummary } from '@moonshot-ai/kimi-code-sdk'; -import { kimiCodePluginMarketplaceUrl } from '#/constant/app'; +import { KIMI_CODE_PLUGIN_MARKETPLACE_URL } from '#/constant/app'; import { computeUpdateStatus, loadPluginMarketplace, @@ -166,7 +166,7 @@ export class PluginUpdateNotifier { // Only the default official catalog can back an "Official Marketplace" // notice — a custom catalog (KIMI_CODE_PLUGIN_MARKETPLACE_URL) may // advertise anything under any id. - if (marketplace.source !== kimiCodePluginMarketplaceUrl()) return; + if (marketplace.source !== KIMI_CODE_PLUGIN_MARKETPLACE_URL) return; const entry = marketplace.plugins.find((plugin) => plugin.id === pluginId); if (entry === undefined) return; const installed = (await session.listPlugins()).find((plugin) => plugin.id === pluginId); diff --git a/apps/kimi-code/src/tui/controllers/session-event-handler.ts b/apps/kimi-code/src/tui/controllers/session-event-handler.ts index 9cc95eba3..9cb1029bd 100644 --- a/apps/kimi-code/src/tui/controllers/session-event-handler.ts +++ b/apps/kimi-code/src/tui/controllers/session-event-handler.ts @@ -119,8 +119,6 @@ export interface SessionEventHost { updateTerminalTitle(): void; sendQueuedMessage(session: Session, item: QueuedMessage): void; shiftQueuedMessage(): QueuedMessage | undefined; - handleTurnStarted?(event: TurnStartedEvent): void; - handleTurnEnded?(event: TurnEndedEvent): void; readonly btwPanelController: BtwPanelController; readonly tasksBrowserController: TasksBrowserController; } @@ -321,7 +319,6 @@ export class SessionEventHandler { // --------------------------------------------------------------------------- private handleTurnBegin(event: TurnStartedEvent): void { - this.host.handleTurnStarted?.(event); this.currentTurnHasAssistantText = false; if (event.origin?.kind === 'plugin_command') { this.pluginCommandTurns.set(String(event.turnId), event.origin.pluginId); @@ -359,7 +356,6 @@ export class SessionEventHandler { } private handleTurnEnd(event: TurnEndedEvent, sendQueued: (item: QueuedMessage) => void): void { - this.host.handleTurnEnded?.(event); this.host.streamingUI.flushNow(); this.clearStepRetry(); if (event.reason === 'cancelled') { @@ -599,7 +595,6 @@ export class SessionEventHandler { turnId: String(event.turnId), renderMode: 'markdown', content: formatHookResultMarkdown(event), - hookResult: true, }); this.host.patchLivePane({ mode: 'idle', @@ -663,7 +658,7 @@ export class SessionEventHandler { const tc = this.host.streamingUI.getToolComponent(event.toolCallId); if (tc === undefined) return; if (event.update.kind === 'status') { - tc.appendProgress(text, { replace: event.update.replace === true }); + tc.appendProgress(text); return; } if (event.update.kind === 'stdout' || event.update.kind === 'stderr') { @@ -717,7 +712,6 @@ export class SessionEventHandler { if (event.maxContextTokens !== undefined) patch.maxContextTokens = event.maxContextTokens; if (event.planMode !== undefined) patch.planMode = event.planMode; if (event.swarmMode !== undefined) patch.swarmMode = event.swarmMode; - if (event.towerMode !== undefined) patch.towerMode = event.towerMode; if (event.permission !== undefined) { patch.permissionMode = event.permission; } diff --git a/apps/kimi-code/src/tui/controllers/session-replay.ts b/apps/kimi-code/src/tui/controllers/session-replay.ts index ca9980657..1eebd5a72 100644 --- a/apps/kimi-code/src/tui/controllers/session-replay.ts +++ b/apps/kimi-code/src/tui/controllers/session-replay.ts @@ -9,7 +9,6 @@ import type { } from '@moonshot-ai/kimi-code-sdk'; import { ToolCallComponent } from '../components/messages/tool-call'; -import { ShellRunComponent } from '../components/messages/shell-run'; import { ReplayTurnBoundaryComponent } from '../components/messages/user-message'; import { currentTheme } from '../theme'; import type { TodoItem } from '../components/chrome/todo-panel'; @@ -29,7 +28,6 @@ import { markTranscriptComponent } from '../utils/transcript-component-metadata' import { appStateFromResumeAgent, backgroundOrigin, - bundledSkillsFromOrigin, collectReplayMessageContent, contentPartsToText, countActiveBackgroundTasks, @@ -41,7 +39,6 @@ import { replayBackgroundProjection, replayEntry, skillActivationFromOrigin, - stripBundledSkillParts, pluginCommandFromOrigin, toolCallFromReplayMessage, toolResultOutput, @@ -84,33 +81,6 @@ function unescapeBashXml(text: string): string { .replaceAll('&', '&'); } -/** - * Replay records within the turn limit, but never cut between a bundled - * prompt and the hook results recorded immediately before it: when the - * limiter's first retained record is a bundled prompt, the consecutive - * preceding hook results are pulled back into the window so the oldest - * visible bundle keeps its hook context. - */ -function preserveBundleHookResults( - replay: readonly AgentReplayRecord[], - maxTurns: number, -): readonly AgentReplayRecord[] { - const limited = limitReplayRecordsByTurn(replay, maxTurns); - const first = limited[0]; - if (first?.type !== 'message' || bundledSkillsFromOrigin(first.message.origin).length === 0) { - return limited; - } - const firstIndex = replay.indexOf(first); - if (firstIndex < 0) return limited; - let start = firstIndex; - for (;;) { - const candidate = replay[start - 1]; - if (candidate?.type !== 'message' || candidate.message.origin?.kind !== 'hook_result') break; - start -= 1; - } - return start === firstIndex ? limited : [...replay.slice(start, firstIndex), ...limited]; -} - export class SessionReplayRenderer { constructor(private readonly host: SessionReplayHost) {} @@ -222,48 +192,13 @@ export class SessionReplayRenderer { private renderRecords(agent: ResumedAgentState): void { const context = createReplayRenderContext(); - const records = [...preserveBundleHookResults(agent.replay, REPLAY_TURN_LIMIT)]; - for (let i = 0; i < records.length; i++) { - i = this.renderRecordWithBundleLookahead(context, records, i); + for (const record of limitReplayRecordsByTurn(agent.replay, REPLAY_TURN_LIMIT)) { + this.renderRecord(context, record); } this.flushAssistant(context); this.cleanupRuntime(context); } - private renderRecordWithBundleLookahead( - context: ReplayRenderContext, - records: readonly AgentReplayRecord[], - index: number, - ): number { - const record = records[index]!; - // Hook results recorded ahead of a bundled prompt are projected inside - // the bundle's window — after its skill cards, before the prompt — - // matching the live event order instead of attaching them to the - // previous turn. - if (record.type === 'message' && record.message.origin?.kind === 'hook_result') { - let end = index; - for (;;) { - const candidate = records[end + 1]; - if (candidate?.type !== 'message' || candidate.message.origin?.kind !== 'hook_result') { - break; - } - end += 1; - } - const next = records[end + 1]; - if (next?.type === 'message' && bundledSkillsFromOrigin(next.message.origin).length > 0) { - const hookResults: ContextMessage[] = []; - for (let j = index; j <= end; j++) { - const hookRecord = records[j]!; - if (hookRecord.type === 'message') hookResults.push(hookRecord.message); - } - this.renderBundledPrompt(context, next.message, hookResults); - return end + 1; - } - } - this.renderRecord(context, record); - return index; - } - private renderRecord(context: ReplayRenderContext, record: AgentReplayRecord): void { switch (record.type) { case 'message': @@ -356,23 +291,8 @@ export class SessionReplayRenderer { } else { const stdout = (extractBashTag(text, 'bash-stdout') ?? '').trim(); const stderr = (extractBashTag(text, 'bash-stderr') ?? '').trim(); - // Replayed `!` output is a finished card: mount the same component the - // live view uses, already finished, so the ctrl+o toggle reaches it. - const output = new ShellRunComponent(() => this.host.state.ui.requestRender()); - output.finish(stdout, stderr, message.origin.isError); - // Inherit the current ctrl+o state, same as the live card — the global - // toggle only reaches components that exist when it fires. - if (this.host.state.toolOutputExpanded) output.setExpanded(true); - markTranscriptComponent( - output, - replayEntry( - context, - 'status', - formatBashOutputForDisplay(stdout, stderr, message.origin.isError), - 'plain', - ), - ); - this.host.state.transcriptContainer.addChild(output); + const out = formatBashOutputForDisplay(stdout, stderr, message.origin.isError); + this.host.appendTranscriptEntry(replayEntry(context, 'status', out, 'plain')); } return; } @@ -419,40 +339,12 @@ export class SessionReplayRenderer { return; } - if (bundledSkillsFromOrigin(message.origin).length > 0) { - this.renderBundledPrompt(context, message); - return; - } this.advanceTurn(context); this.host.appendTranscriptEntry( replayEntry(context, 'user', contentPartsToText(message.content), 'plain'), ); } - private renderBundledPrompt( - context: ReplayRenderContext, - message: ContextMessage, - hookResults: readonly ContextMessage[] = [], - ): void { - // The bundle is one message: advance once, rebuild the per-skill cards - // from the prompt origin, then show the caller's own parts (the engine - // prepends one rendered text part per bundled skill to the content). - this.advanceTurn(context); - this.renderBundledSkillCards(context, message); - for (const hookResult of hookResults) { - this.renderHookResult(context, hookResult); - } - this.host.appendTranscriptEntry( - replayEntry(context, 'user', contentPartsToText(stripBundledSkillParts(message)), 'plain'), - ); - } - - private renderBundledSkillCards(context: ReplayRenderContext, message: ContextMessage): void { - for (const skill of bundledSkillsFromOrigin(message.origin)) { - this.renderSkillActivation(context, skill); - } - } - private renderToolCalls(context: ReplayRenderContext, toolCalls: readonly ToolCall[]): void { if (toolCalls.length === 0) return; const { streamingUI } = this.host; @@ -540,7 +432,6 @@ export class SessionReplayRenderer { skillName: skill.skillName, skillArgs: skill.skillArgs, skillTrigger: skill.trigger, - bundledWithPrompt: skill.bundled === true ? true : undefined, }); } @@ -635,8 +526,8 @@ export class SessionReplayRenderer { private renderHookResult(context: ReplayRenderContext, message: ContextMessage): void { if (message.origin?.kind !== 'hook_result') return; this.flushAssistant(context); - this.host.appendTranscriptEntry({ - ...replayEntry( + this.host.appendTranscriptEntry( + replayEntry( context, 'assistant', formatHookResultMessageForTranscript( @@ -646,8 +537,7 @@ export class SessionReplayRenderer { ), 'markdown', ), - hookResult: true, - }); + ); } private renderCronJob(context: ReplayRenderContext, message: ContextMessage): void { diff --git a/apps/kimi-code/src/tui/controllers/staging-leases.ts b/apps/kimi-code/src/tui/controllers/staging-leases.ts deleted file mode 100644 index bc9bfcd78..000000000 --- a/apps/kimi-code/src/tui/controllers/staging-leases.ts +++ /dev/null @@ -1,307 +0,0 @@ -/** - * `StagingLeaseTracker` — owns the lifecycle of staged prompt media (daemon - * uploads + local cache copies) between submission and the session that - * consumes it. - * - * A paste/upload edge stages media before the prompt exists. The two staged - * forms age differently once the consuming turn ends: - * - * - Daemon uploads become garbage — the engine materialized its own session - * copy at intake — so the turn-end release deletes them. - * - Local cache copies may still be referenced by persisted history: slash / - * plugin command args carry the path as plain text (the model reads it - * with `ReadMediaFile`), and that form is never rewritten to the session - * media dir. Turn-end release therefore retires cache copies to a - * session-lifetime bucket, deleted at session close / shutdown. - * - * Media that never gets consumed (validation/render failure, queue discard, - * a dispatch RPC that failed before any turn claimed the lease) is deleted - * immediately, whatever form it takes. - * - * A submission diverted before dispatch hands its lease back via `defer`: - * the media stays staged under raw (ids, paths) ownership — a queued message - * re-leases at dequeue dispatch, and the cache-hint stash's restore/resend - * exits release it through `releaseRecalled` / a fresh lease. - * - * The tracker holds one lease per submission, binds it to the consuming turn - * (explicitly at dispatch, by exact submission id when the turn echoes the - * client-chosen prompt id, or heuristically when a matching-origin turn - * starts), and releases it when that turn ends. The heuristic claims the - * earliest unclaimed lease of the same origin; that is only sound because the - * TUI serializes same-origin dispatches (one in-flight submission at a time, - * see `beginSessionRequest`) and `turn.started` arrives in dispatch order. - * - * Exact binding: a lease created with a `submissionId` is registered in - * `leasesBySubmissionId`, and the submission sends that id as the prompt id; - * the consuming turn's `turn.started` echoes it as `promptId`, so - * `handleTurnStarted` binds the exact lease instead of guessing. The - * heuristic below remains the fallback for submissions without an id echo. - * - * INVARIANT: at most one unclaimed lease per origin at any moment — with two - * or more, the heuristic cannot tell which submission the turn belongs to. - * `handleTurnStarted` reports a violation through the `warn` effect and still - * claims the earliest (a mis-claim only mis-times deletions, so it is not - * worth failing the turn over). An exact `promptId` hit bypasses the - * heuristic entirely, so it neither trips nor needs the invariant. - * - * Unclaimed leases are released at session close / shutdown, and every - * in-flight cleanup is drainable via {@link drain}. - * - * Self-contained state machine extracted from `KimiTUI`: the two side effects - * (resolving attachment ids to daemon file ids, deleting the staged files) - * are injected, so the tracker is unit-testable without a TUI. - */ - -import type { TurnEndedEvent, TurnStartedEvent } from '@moonshot-ai/kimi-code-sdk'; - -import type { QueuedMessage } from '../types'; - -export type StagingLeaseOrigin = 'user' | 'skill_activation' | 'plugin_command'; - -export interface StagingLease { - readonly mediaAttachmentIds: readonly number[]; - readonly paths: readonly string[]; - readonly origin: StagingLeaseOrigin; - readonly submissionId?: string; - turnId: string | undefined; - released: boolean; -} - -export interface StagingLeaseEffects { - /** Resolve attachment ids to the staged daemon file ids, consuming the mapping. */ - readonly takeFileIds: (mediaAttachmentIds: readonly number[]) => readonly string[]; - /** Consume retains without taking the staged files (queue recall keeps them). */ - readonly releaseRetains: (mediaAttachmentIds: readonly number[]) => void; - /** Delete staged files (daemon uploads + local cache copies); never rejects. */ - readonly deleteFiles: (fileIds: readonly string[], paths: readonly string[]) => Promise<void>; - /** - * Optional sink for invariant violations (see the INVARIANT note above). - * The tracker keeps operating; the warning exists to make a broken - * same-origin ordering assumption visible instead of mis-binding silently. - */ - readonly warn?: (message: string) => void; -} - -export class StagingLeaseTracker { - private readonly cleanups = new Set<Promise<void>>(); - /** Staged media is owned by the turn that consumes it, not by the RPC call. */ - private readonly leases = new Set<StagingLease>(); - private readonly leasesByTurn = new Map<string, Set<StagingLease>>(); - /** Leases carrying a client-chosen submission id, for exact `promptId` binding. */ - private readonly leasesBySubmissionId = new Map<string, StagingLease>(); - /** - * Cache copies whose consuming turn already ended. Persisted history may - * still reference their paths (skill/plugin args carry them as plain - * text), so they survive until the session closes. - */ - private readonly retiredPaths = new Set<string>(); - - constructor(private readonly effects: StagingLeaseEffects) {} - - create( - mediaAttachmentIds: readonly number[], - paths: readonly string[], - origin: StagingLeaseOrigin, - submissionId?: string, - ): StagingLease | undefined { - // `mediaAttachmentIds` multiplicity is the retain count this lease must - // release: each extraction/rewrite retains once per unique id, so callers - // dedupe repeated placeholder occurrences per contribution before handing - // the ids over (one message referencing an image twice contributes it - // once; two batched messages sharing an image contribute it twice). - if (mediaAttachmentIds.length === 0 && paths.length === 0) return undefined; - const lease: StagingLease = { - mediaAttachmentIds: [...mediaAttachmentIds], - paths: [...paths], - origin, - submissionId, - turnId: undefined, - released: false, - }; - this.leases.add(lease); - if (submissionId !== undefined) this.leasesBySubmissionId.set(submissionId, lease); - return lease; - } - - bindToTurn(lease: StagingLease | undefined, turnId: string): void { - if (lease === undefined || lease.released || lease.turnId !== undefined) return; - lease.turnId = turnId; - let leases = this.leasesByTurn.get(turnId); - if (leases === undefined) { - leases = new Set<StagingLease>(); - this.leasesByTurn.set(turnId, leases); - } - leases.add(lease); - } - - handleTurnStarted(event: TurnStartedEvent): void { - const kind = event.origin?.kind; - if (kind !== 'user' && kind !== 'skill_activation' && kind !== 'plugin_command') return; - if (event.promptId !== undefined) { - // Exact binding: the turn echoes the submission's client-chosen prompt - // id — bind that lease directly and skip the origin heuristic (and its - // ambiguity warning) entirely. - const exact = this.leasesBySubmissionId.get(event.promptId); - if (exact !== undefined && exact.turnId === undefined) { - this.bindToTurn(exact, String(event.turnId)); - return; - } - } - const candidates = [...this.leases].filter( - (candidate) => - !candidate.released && candidate.turnId === undefined && candidate.origin === kind, - ); - if (candidates.length > 1) { - // INVARIANT violation: the earliest-unclaimed pick cannot tell - // same-origin leases apart — same-origin dispatch serialization or the - // turn.started ordering assumption may be broken. - this.effects.warn?.( - `staging lease: ${candidates.length} unclaimed '${kind}' leases when turn ` + - `${String(event.turnId)} started; claiming the earliest`, - ); - } - this.bindToTurn(candidates[0], String(event.turnId)); - } - - handleTurnEnded(event: TurnEndedEvent): void { - const turnId = String(event.turnId); - const leases = this.leasesByTurn.get(turnId); - if (leases === undefined) return; - for (const lease of leases) this.releaseConsumed(lease); - this.leasesByTurn.delete(turnId); - } - - /** - * Track a dispatch RPC carrying staged media. When it rejects, run - * `onError` and release the lease — but only while no turn has claimed it: - * a bound lease is owned by the turn and released at turn end, whatever the - * RPC's later outcome. - */ - trackDispatch( - lease: StagingLease | undefined, - request: Promise<unknown>, - onError: (error: unknown) => void, - ): void { - this.track( - request - .catch((error: unknown) => { - onError(error); - if (lease?.turnId === undefined) this.release(lease); - }) - .then(() => undefined), - ); - } - - /** - * Release staged media that will never be consumed (dispatch failed before - * a turn claimed the lease): delete daemon uploads and cache copies now. - */ - release(lease: StagingLease | undefined): void { - if (lease === undefined || lease.released) return; - this.unbind(lease); - this.deleteStaged(this.takeFileIds(lease), lease.paths); - } - - /** Release every unclaimed lease and the retired cache copies (session close / shutdown). */ - releaseAll(): void { - for (const lease of this.leases) this.release(lease); - const retired = [...this.retiredPaths]; - this.retiredPaths.clear(); - this.deleteStaged([], retired); - } - - /** Release staged media that never got a lease (validation/render failures). */ - releaseMedia(mediaAttachmentIds: readonly number[], paths: readonly string[]): void { - const fileIds = this.effects.takeFileIds(mediaAttachmentIds); - this.deleteStaged(fileIds, paths); - } - - releaseQueued(items: readonly QueuedMessage[]): void { - const fileIds = items.flatMap((item) => - this.effects.takeFileIds([ - ...(item.imageAttachmentIds ?? []), - ...(item.videoAttachmentIds ?? []), - ]), - ); - this.deleteStaged(fileIds, []); - } - - /** - * Release a queued item (or a cache-hint stash's extraction) recalled into - * the editor: the restored draft still references its attachments, so this - * is not a discard — daemon uploads stay staged (only the retain is - * consumed; the next submit re-retains them). `retirePaths` carries the - * slash/plugin-args channel's cache copies: the queued rewrite's args - * reference them by path, so they retire to session lifetime instead of - * being deleted. - */ - releaseRecalled( - mediaAttachmentIds: readonly number[], - retirePaths: readonly string[] = [], - ): void { - this.effects.releaseRetains(mediaAttachmentIds); - for (const path of retirePaths) this.retiredPaths.add(path); - } - - /** - * Hand a lease's staged media back to raw (ids, paths) ownership without - * consuming retains or deleting files: the lease is simply unbound. Used - * when a submission is diverted before dispatch — queued behind a running - * turn or swallowed by the cache-hint stash; see the header note. - */ - defer(lease: StagingLease | undefined): void { - if (lease === undefined || lease.released) return; - this.unbind(lease); - } - - /** Track an in-flight staging-related promise so {@link drain} can await it. */ - track(cleanup: Promise<void>): void { - let tracked!: Promise<void>; - tracked = cleanup.catch(() => undefined).finally(() => { - this.cleanups.delete(tracked); - }); - this.cleanups.add(tracked); - } - - async drain(): Promise<void> { - while (this.cleanups.size > 0) { - await Promise.allSettled(this.cleanups); - } - } - - /** Schedule deletion of already-resolved staged files (e.g. a store clear). */ - deleteStaged(fileIds: readonly string[], paths: readonly string[] = []): void { - if (fileIds.length === 0 && paths.length === 0) return; - this.track(this.effects.deleteFiles(fileIds, paths)); - } - - /** - * Turn-end release: the daemon uploads are safe to delete — the engine - * materialized its own session copies at intake — while the cache copies - * retire to session lifetime (see {@link retiredPaths}). - */ - private releaseConsumed(lease: StagingLease): void { - if (lease.released) return; - this.unbind(lease); - for (const path of lease.paths) this.retiredPaths.add(path); - this.deleteStaged(this.takeFileIds(lease)); - } - - private unbind(lease: StagingLease): void { - lease.released = true; - this.leases.delete(lease); - if (lease.submissionId !== undefined) this.leasesBySubmissionId.delete(lease.submissionId); - if (lease.turnId !== undefined) { - const leases = this.leasesByTurn.get(lease.turnId); - leases?.delete(lease); - if (leases?.size === 0) this.leasesByTurn.delete(lease.turnId); - } - } - - private takeFileIds(lease: StagingLease): readonly string[] { - // Multiplicity in the lease's id list is the retain count (creation sites - // dedupe per extraction before contributing ids): consume one retain per - // occurrence. - return lease.mediaAttachmentIds.flatMap((id) => this.effects.takeFileIds([id])); - } -} diff --git a/apps/kimi-code/src/tui/controllers/subagent-activity-store.ts b/apps/kimi-code/src/tui/controllers/subagent-activity-store.ts index 2f768513f..a612ece5b 100644 --- a/apps/kimi-code/src/tui/controllers/subagent-activity-store.ts +++ b/apps/kimi-code/src/tui/controllers/subagent-activity-store.ts @@ -220,8 +220,7 @@ export class SubagentActivityStore { return; } case 'tool.progress': { - const kind = event.update.kind; - if (kind !== 'stdout' && kind !== 'stderr' && kind !== 'status') return; + if (event.update.kind !== 'stdout' && event.update.kind !== 'stderr') return; const text = event.update.text; if (text === undefined || text.trim().length === 0) return; const record = this.records.get(event.agentId); diff --git a/apps/kimi-code/src/tui/controllers/subagent-event-handler.ts b/apps/kimi-code/src/tui/controllers/subagent-event-handler.ts index 9b9005cdf..6bbf7b3be 100644 --- a/apps/kimi-code/src/tui/controllers/subagent-event-handler.ts +++ b/apps/kimi-code/src/tui/controllers/subagent-event-handler.ts @@ -119,16 +119,10 @@ export class SubAgentEventHandler { }); } else if ( event.type === 'tool.progress' && - (event.update.kind === 'stdout' || - event.update.kind === 'stderr' || - event.update.kind === 'status') && + (event.update.kind === 'stdout' || event.update.kind === 'stderr') && event.update.text !== undefined ) { - toolCall.appendSubToolLiveOutput( - `${childAgentId}:${event.toolCallId}`, - event.update.text, - { replace: event.update.replace === true }, - ); + toolCall.appendSubToolLiveOutput(`${childAgentId}:${event.toolCallId}`, event.update.text); } else if (event.type === 'tool.result') { toolCall.finishSubToolCall({ tool_call_id: `${childAgentId}:${event.toolCallId}`, @@ -143,7 +137,8 @@ export class SubAgentEventHandler { usage: totalUsage, // The bound model alias rides every child status update (emitted right // after spawn); surface it on the subagent card. `modelDisplayName` - // falls back to the alias itself when the entry is unknown. + // falls back to the alias itself when the entry is unknown (e.g. the + // synthesized `__secondary__` derived entry is missing). modelDisplay: event.model === undefined ? undefined @@ -594,7 +589,8 @@ export class SubAgentEventHandler { // The bound model alias rides every child status update (emitted right // after spawn). Swarm members share one binding, so the panel shows it // once in the header instead of per cell. `modelDisplayName` falls back - // to the alias itself when the entry is unknown. + // to the alias itself when the entry is unknown (e.g. the synthesized + // `__secondary__` derived entry is missing). progress.setModelDisplay( modelDisplayName(event.model, this.host.state.appState.availableModels[event.model]), ); @@ -666,11 +662,8 @@ export class SubAgentEventHandler { } const width = Math.floor(terminalColumns); - const dock = state.dockContainer; - // Fullscreen: the root children are empty (layout root holds a ScrollView + - // dock); the chrome below the transcript is the dock's children instead. const rowsAfterSwarm = renderedRowsAfterChild( - dock !== undefined ? [state.transcriptContainer, ...dock.children] : state.ui.children, + state.ui.children, state.transcriptContainer, width, ); diff --git a/apps/kimi-code/src/tui/controllers/tasks-browser.ts b/apps/kimi-code/src/tui/controllers/tasks-browser.ts index 7db2f0a82..187d4619e 100644 --- a/apps/kimi-code/src/tui/controllers/tasks-browser.ts +++ b/apps/kimi-code/src/tui/controllers/tasks-browser.ts @@ -1,16 +1,11 @@ import type { BackgroundTaskInfo, Session } from '@moonshot-ai/kimi-code-sdk'; -import type { ProcessTerminal, TUI } from '@moonshot-ai/pi-tui'; +import type { Component, ProcessTerminal, TUI } from '@moonshot-ai/pi-tui'; import { AgentActivityViewer, formatSubagentActivityPreview } from '../components/dialogs/agent-activity-viewer'; import { TaskOutputViewer } from '../components/dialogs/task-output-viewer'; import { TasksBrowserApp, type TasksFilter } from '../components/dialogs/tasks-browser'; import type { Theme } from '#/tui/theme'; import type { CustomEditor } from '../components/editor/custom-editor'; -import { - beginScreenTakeover, - endScreenTakeover, - type ScreenTakeover, -} from '../utils/screen-takeover'; import type { SessionEventHandler } from './session-event-handler'; import type { SubagentActivityRecord } from './subagent-activity-store'; @@ -31,7 +26,7 @@ export interface TasksBrowserHost { export type TasksBrowserState = { component: TasksBrowserApp; - takeover: ScreenTakeover; + savedChildren: readonly Component[]; filter: TasksFilter; selectedTaskId: string | undefined; tailOutput: string | undefined; @@ -43,7 +38,7 @@ export type TasksBrowserState = { viewer: | { component: TaskOutputViewer | AgentActivityViewer; - takeover: ScreenTakeover; + savedChildren: readonly Component[]; taskId: string; output: string; refreshId: number; @@ -91,7 +86,9 @@ export class TasksBrowserController { state.terminal, ); - const takeover = beginScreenTakeover(state.ui, component); + const savedChildren = [...state.ui.children]; + state.ui.clear(); + state.ui.addChild(component); state.ui.setFocus(component); state.ui.requestRender(true); @@ -101,7 +98,7 @@ export class TasksBrowserController { this.host.setTasksBrowser({ component, - takeover, + savedChildren, filter, selectedTaskId, tailOutput: undefined, @@ -126,7 +123,10 @@ export class TasksBrowserController { if (browser.pollTimer !== undefined) clearInterval(browser.pollTimer); if (browser.flashTimer !== undefined) clearTimeout(browser.flashTimer); - endScreenTakeover(state.ui, browser.takeover); + state.ui.clear(); + for (const child of browser.savedChildren) { + state.ui.addChild(child); + } this.host.setTasksBrowser(undefined); state.ui.setFocus(state.editor); state.ui.requestRender(true); @@ -383,7 +383,9 @@ export class TasksBrowserController { state.terminal, ); - const takeover = beginScreenTakeover(state.ui, viewer); + const savedBrowserChildren = [...state.ui.children]; + state.ui.clear(); + state.ui.addChild(viewer); state.ui.setFocus(viewer); state.ui.requestRender(true); @@ -393,7 +395,7 @@ export class TasksBrowserController { browser.viewer = { component: viewer, - takeover, + savedChildren: savedBrowserChildren, taskId, output, refreshId: 0, @@ -422,7 +424,9 @@ export class TasksBrowserController { state.terminal, ); - const takeover = beginScreenTakeover(state.ui, viewer); + const savedBrowserChildren = [...state.ui.children]; + state.ui.clear(); + state.ui.addChild(viewer); state.ui.setFocus(viewer); state.ui.requestRender(true); @@ -433,7 +437,7 @@ export class TasksBrowserController { browser.viewer = { component: viewer, - takeover, + savedChildren: savedBrowserChildren, taskId, output: '', refreshId: 0, @@ -534,7 +538,10 @@ export class TasksBrowserController { const viewer = browser.viewer; clearInterval(viewer.pollTimer); browser.viewer = undefined; - endScreenTakeover(this.host.state.ui, viewer.takeover); + this.host.state.ui.clear(); + for (const child of viewer.savedChildren) { + this.host.state.ui.addChild(child); + } this.host.state.ui.setFocus(browser.component); this.host.state.ui.requestRender(true); } diff --git a/apps/kimi-code/src/tui/goal-queue-store.ts b/apps/kimi-code/src/tui/goal-queue-store.ts index e3b0ccb47..0b98eda67 100644 --- a/apps/kimi-code/src/tui/goal-queue-store.ts +++ b/apps/kimi-code/src/tui/goal-queue-store.ts @@ -210,7 +210,7 @@ function normalizeObjective(value: string): string { if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { throw new KimiError( ErrorCodes.GOAL_OBJECTIVE_TOO_LONG, - `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters. Put long content in a file and reference the file path.`, + `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters`, ); } return objective; diff --git a/apps/kimi-code/src/tui/kimi-tui.ts b/apps/kimi-code/src/tui/kimi-tui.ts index c82c6e7d3..488b426cd 100644 --- a/apps/kimi-code/src/tui/kimi-tui.ts +++ b/apps/kimi-code/src/tui/kimi-tui.ts @@ -1,6 +1,4 @@ -import { randomUUID } from 'node:crypto'; import { writeFileSync } from 'node:fs'; -import { unlink } from 'node:fs/promises'; import { join } from 'node:path'; import type { DeviceAuthorization } from '@moonshot-ai/kimi-code-oauth'; @@ -17,8 +15,6 @@ import type { Session, SkillSummary, TokenUsage, - TurnEndedEvent, - TurnStartedEvent, WorkspaceTrustInfo, } from '@moonshot-ai/kimi-code-sdk'; import type { MigrationPlan } from '@moonshot-ai/migration-legacy'; @@ -28,8 +24,6 @@ import { type Focusable, getCapabilities, Spacer, - TuiAltScreen, - TuiMainScreen, } from '@moonshot-ai/pi-tui'; import { resolve } from 'pathe'; @@ -49,7 +43,6 @@ import { BUILTIN_SLASH_COMMANDS, buildPluginSlashCommands, buildSkillSlashCommands, - goalObjectiveLengthWarning, isExperimentalFlagEnabled, setExperimentalFeatures, sortSlashCommands, @@ -115,7 +108,6 @@ import { SESSION_LIST_PAGE_SIZE, SESSIONLESS_STARTUP_NOTICE, } from './constant/kimi-tui'; -import { MEDIA_INGESTION_SUBMIT_WAIT_MS } from './constant/media'; import { CHROME_GUTTER } from './constant/rendering'; import { MAX_TERMINAL_TITLE_LENGTH } from './constant/terminal'; import { AuthFlowController } from './controllers/auth-flow'; @@ -124,7 +116,6 @@ import { ClipboardImageHintController } from './controllers/clipboard-image-hint import { EditorKeyboardController } from './controllers/editor-keyboard'; import { SessionEventHandler } from './controllers/session-event-handler'; import { SessionReplayRenderer } from './controllers/session-replay'; -import { StagingLeaseTracker, type StagingLease } from './controllers/staging-leases'; import { StreamingUIController } from './controllers/streaming-ui'; import { TasksBrowserController } from './controllers/tasks-browser'; import { installRainbowDance } from './easter-eggs/dance'; @@ -141,7 +132,6 @@ import { createTUIState, type TUIState } from './tui-state'; import { INITIAL_LIVE_PANE, type AppState, - type InlineSkillActivation, type KimiTUIOptions, type LivePaneState, type LoginProgressSpinnerHandle, @@ -157,21 +147,12 @@ import { isDeadTerminalError } from './utils/dead-terminal'; import { formatErrorMessage } from './utils/event-payload'; import { pickForegroundTasks } from './utils/foreground-task'; import { ImageAttachmentStore, type ImageAttachment } from './utils/image-attachment-store'; -import { - extractMediaAttachments, - originalsDirForSession, - pendingMediaIngestions, - refreshExpiringImageFileRefs, - resolveOriginalCaptions, - rewriteMediaPlaceholders, -} from './utils/image-placeholder'; +import { extractMediaAttachments, rewriteMediaPlaceholders } from './utils/image-placeholder'; import type { ExtractionResult } from './utils/image-placeholder'; import { installInputLatencyProbe } from './utils/input-latency'; -import { combineSteerInput } from './utils/steer-input'; import { startupTrace } from '#/utils/startup-trace'; -import { REPLAY_FETCH_TURN_LIMIT } from './utils/message-replay'; +import { REPLAY_TURN_LIMIT } from './utils/message-replay'; import { hasPatchChanges } from './utils/object-patch'; -import { beginScreenTakeover, endScreenTakeover, type ScreenTakeover } from './utils/screen-takeover'; import { sessionRowsForPicker } from './utils/session-picker-rows'; import { formatStepRetryDetail, formatStepRetryLabel } from './utils/step-retry'; import { formatBashOutputForDisplay } from './utils/shell-output'; @@ -259,7 +240,6 @@ function createInitialAppState(input: KimiTUIStartupInput): AppState { planMode: input.cliOptions.plan, inputMode: 'prompt', swarmMode: false, - towerMode: false, thinkingEffort: 'off', contextUsage: 0, contextTokens: 0, @@ -273,7 +253,6 @@ function createInitialAppState(input: KimiTUIStartupInput): AppState { version: input.version, editorCommand: input.tuiConfig.editorCommand, disablePasteBurst: input.tuiConfig.disablePasteBurst, - renderLatex: input.tuiConfig.renderLatex, cacheExpiryHint: input.tuiConfig.cacheExpiryHint, notifications: input.tuiConfig.notifications, upgrade: input.tuiConfig.upgrade, @@ -290,14 +269,51 @@ function createInitialAppState(input: KimiTUIStartupInput): AppState { interface SendMessageOptions { readonly parts?: readonly PromptPart[]; readonly imageAttachmentIds?: readonly number[]; - readonly videoAttachmentIds?: readonly number[]; readonly hasMedia?: boolean; - /** - * Lease pre-created at extraction time by `sendNormalUserInput`. Dispatch - * reuses it (carrying its exact-binding submission id); enqueueing defers - * it — the queue item owns the raw ids and re-leases at dequeue. - */ - readonly lease?: StagingLease; +} + +/** + * Flatten steer items into the payload `session.steer` expects: the + * historical `'\n\n'`-joined string when nothing carries media, or a + * merged part list when any item has extracted media parts (queued image + * messages, or the editor draft after placeholder extraction). + * + * Items are separated by the historical `'\n\n'`, which merges into the + * adjacent text part. The one exception is two touching media parts: a + * standalone `{type:'text',text:'\n\n'}` between them would be rejected + * by `normalizePromptInput` as an empty text part, so the separator is + * dropped there (media parts are self-delimiting anyway). + */ +function combineSteerInput(items: readonly SteerInputItem[]): string | PromptPart[] { + const hasMedia = items.some((item) => item.parts !== undefined && item.parts.length > 0); + if (!hasMedia) return items.map((item) => item.text).join('\n\n'); + const parts: PromptPart[] = []; + for (const item of items) { + const startsWithMedia = + item.parts !== undefined && item.parts.length > 0 && item.parts[0]?.type !== 'text'; + const lastIsMedia = parts.length > 0 && parts.at(-1)?.type !== 'text'; + if (parts.length > 0 && !(lastIsMedia && startsWithMedia)) { + appendSteerText(parts, '\n\n'); + } + if (item.parts !== undefined && item.parts.length > 0) { + for (const part of item.parts) { + if (part.type === 'text') appendSteerText(parts, part.text); + else parts.push(part); + } + } else { + appendSteerText(parts, item.text); + } + } + return parts; +} + +function appendSteerText(parts: PromptPart[], text: string): void { + const last = parts.at(-1); + if (last?.type === 'text') { + parts[parts.length - 1] = { type: 'text', text: last.text + text }; + return; + } + parts.push({ type: 'text', text }); } /** How long the one-shot "moved to background" footer hint stays visible. */ @@ -311,8 +327,6 @@ export class KimiTUI { /** In-flight lazy session creation (v2 engine), shared by concurrent first-use triggers. */ private ensureSessionPromise: Promise<Session | undefined> | null = null; private readonly cacheHint = new CacheHintController(this); - /** Staged prompt media lifecycle (daemon uploads + cache copies) — see StagingLeaseTracker. */ - private readonly staging: StagingLeaseTracker; private readonly approvalController = new ApprovalController(); private readonly questionController = new QuestionController(); private readonly reverseRpcDisposers: Array<() => void> = []; @@ -369,13 +383,12 @@ export class KimiTUI { // preview viewer can restore focus to the exact same instance (and its // selection / feedback state) when it closes. private activeApprovalPanel: ApprovalPanelComponent | undefined; - // Active full-screen approval preview. While set, the previous screen is - // stashed in `takeover` (root children in regular mode, the layout root in - // fullscreen); closing restores it. + // Active full-screen approval preview. While set, the root UI's normal + // children are stashed in `savedChildren`; closing restores them. private approvalPreview: | { component: ApprovalPreviewViewer; - takeover: ScreenTakeover; + savedChildren: readonly Component[]; panel: ApprovalPanelComponent; } | undefined; @@ -398,21 +411,6 @@ export class KimiTUI { constructor(harness: KimiHarness, startupInput: KimiTUIStartupInput) { this.harness = harness; - this.staging = new StagingLeaseTracker({ - takeFileIds: (ids) => this.imageStore.takeFileIds(ids), - releaseRetains: (ids) => { - this.imageStore.releaseRetains(ids); - }, - deleteFiles: async (fileIds, paths) => { - await Promise.all([ - ...fileIds.map((fileId) => this.harness.deleteFile(fileId).catch(() => undefined)), - ...paths.map((path) => unlink(path).catch(() => undefined)), - ]); - }, - warn: (message) => { - this.track('staging_lease_invariant', { message }); - }, - }); const tuiOptions: KimiTUIOptions = { initialAppState: createInitialAppState(startupInput), startup: { @@ -469,10 +467,8 @@ export class KimiTUI { // ========================================================================= private getSlashCommands(): readonly KimiSlashCommand[] { - const builtins = sortSlashCommands(BUILTIN_SLASH_COMMANDS).filter( - (command) => - isExperimentalFlagEnabled(command.experimentalFlag) && - (!command.requiresEngineV2 || this.engineV2), + const builtins = sortSlashCommands(BUILTIN_SLASH_COMMANDS).filter((command) => + isExperimentalFlagEnabled(command.experimentalFlag), ); return [...builtins, ...this.skillCommands, ...this.pluginCommands]; } @@ -490,14 +486,12 @@ export class KimiTUI { : {}), }; }); - const skillCommandNames = new Set(this.skillCommandMap.keys()); const provider = new FileMentionProvider( slashCommands, this.state.appState.workDir, this.fdPath, this.state.appState.additionalDirs, () => this.state.appState.inputMode, - skillCommandNames, ); this.state.editor.setAutocompleteProvider(provider); @@ -510,7 +504,6 @@ export class KimiTUI { } } this.state.editor.setArgumentHints(argumentHints); - this.state.editor.setSkillCommandNames(skillCommandNames); } refreshSlashCommandAutocomplete(): void { @@ -668,7 +661,7 @@ export class KimiTUI { const provider = new BannerProvider(this.state.appState.version); const displayState = await readBannerDisplayState(); const now = new Date(); - const banner = await provider.load({ + const banner = await provider.load(fetch, { state: displayState, now, }); @@ -896,7 +889,7 @@ export class KimiTUI { session = await this.harness.resumeSession({ id: startup.sessionFlag, additionalDirs: createSessionOptions.additionalDirs, - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); shouldReplayHistory = true; } else { @@ -908,7 +901,7 @@ export class KimiTUI { session = await this.harness.resumeSession({ id: target.id, additionalDirs: createSessionOptions.additionalDirs, - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); shouldReplayHistory = true; } else { @@ -991,10 +984,6 @@ export class KimiTUI { // raw mode with a hidden cursor. try { await this.closeSession('shutting down'); - this.clearQueuedMessages(); - this.staging.releaseAll(); - this.staging.deleteStaged(this.imageStore.clear()); - await this.staging.drain(); await this.harness.close(); } finally { this.sessionEventHandler.stopAllMcpServerStatusSpinners(); @@ -1006,7 +995,7 @@ export class KimiTUI { // best effort — the terminal may already be dead (SIGHUP / EIO). } try { - this.stopUiForExit(); + this.state.ui.stop(); } catch { // best effort terminal restore. } @@ -1091,9 +1080,6 @@ export class KimiTUI { private buildLayout(): void { const { ui } = this.state; - // Fullscreen mounts its layout root (transcript ScrollView + bottom dock) - // in createTUIState; the root children list stays empty there. - if (ui instanceof TuiAltScreen) return; ui.clear(); ui.addChild(this.state.transcriptContainer); ui.addChild(this.state.activityContainer); @@ -1112,43 +1098,9 @@ export class KimiTUI { private mountFooter(): void { const footerWrap = new GutterContainer(CHROME_GUTTER, CHROME_GUTTER); footerWrap.addChild(this.state.footer); - const dock = this.state.dockContainer; - if (dock !== undefined) { - // Dock sizing contract: the footer may shrink to 1 row under extreme - // height pressure, but never disappears (see createTUIState). - dock.addChild(footerWrap, { shrink: 1, minSize: 1 }); - return; - } this.state.ui.addChild(footerWrap); } - // Fullscreen exit: leave the alternate screen with the frame preserved, - // then replay the transcript through a main-screen renderer so native - // scrollback ends up with the same inline layout a regular session would - // have produced (pi's "transcript" exit form). - private stopUiForExit(): void { - const ui = this.state.ui; - if (!(ui instanceof TuiAltScreen)) { - ui.stop(); - return; - } - ui.stop({ preserveScreen: true }); - const main = new TuiMainScreen(ui.terminal); - main.addChild(this.state.transcriptContainer); - main.addChild(this.state.activityContainer); - main.addChild(this.state.todoPanelContainer); - main.addChild(this.state.queueContainer); - main.addChild(this.state.btwPanelContainer); - main.addChild(this.state.editorContainer); - const footerWrap = new GutterContainer(CHROME_GUTTER, CHROME_GUTTER); - footerWrap.addChild(this.state.footer); - main.addChild(footerWrap); - // First paint of a main-screen renderer writes every line sequentially, - // landing the whole transcript in native scrollback. - main.renderNow(); - main.stop(); - } - // ========================================================================= // Input Dispatch // ========================================================================= @@ -1236,9 +1188,6 @@ export class KimiTUI { content: '', }; const outputComponent = new ShellRunComponent(() => this.state.ui.requestRender()); - // Inherit the current ctrl+o state, same as freshly mounted tool calls — - // the global toggle only reaches components that exist when it fires. - if (this.state.toolOutputExpanded) outputComponent.setExpanded(true); this.shellOutputStreams.set(commandId, { entry: outputEntry, component: outputComponent }); this.state.transcriptEntries.push(outputEntry); markTranscriptComponent(outputComponent, outputEntry); @@ -1314,12 +1263,11 @@ export class KimiTUI { } private drainOneQueuedMessage(): void { - const session = this.session; - if (session === undefined) return; const item = this.shiftQueuedMessage(); if (item === undefined) return; + const session = this.session; + if (session === undefined) return; if (item.mode === 'bash') { - this.staging.releaseQueued([item]); void this.runShellCommandFromInput(item.text); } else { this.sendQueuedMessage(session, item); @@ -1334,90 +1282,40 @@ export class KimiTUI { return; } let extraction: ReturnType<typeof extractMediaAttachments>; - if (preExtracted === undefined) { - // A just-pasted image/video may still be finishing its background - // ingestion (compression/daemon upload): give it a bounded moment so - // the submit can use the daemon-ref form — a slower image ingestion - // extracts to the inline fallback instead, a slower video upload - // refuses the submission below. Undefined when nothing is pending, - // keeping the media-free send path synchronous. - const ingestionWait = pendingMediaIngestions( - text, - this.imageStore, - MEDIA_INGESTION_SUBMIT_WAIT_MS, - ); - if (ingestionWait !== undefined) await ingestionWait; - } try { + // Pasted videos are copied into the cache and expand to a `file://` + // `video_url` part; the engine resolves (uploads or degrades) them + // inside the turn, so submission stays fully synchronous. + // // A cache-hint-swallowed resend passes its pre-dialog extraction back // in: the image store may already be cleared (e.g. after "Start a new // session"), so re-extracting from the text would lose the media. extraction = preExtracted ?? extractMediaAttachments(text, this.imageStore); - if (preExtracted !== undefined) { - const parts = refreshExpiringImageFileRefs( - extraction.parts, - extraction.imageAttachmentIds, - this.imageStore, - ); - if (parts !== extraction.parts) extraction = { ...extraction, parts }; - } } catch (error) { - // A pasted video's daemon upload was unusable (still in flight, - // failed, expired); nothing was dispatched. + // A video cache copy failed (unwritable cache dir, vanished source…); + // nothing was dispatched. this.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); return; } - // Create the staging lease right after extraction, so every exit below - // releases through the tracker instead of open-coding ids — a - // forgotten exit degrades to an unclaimed lease (swept by `releaseAll`) - // instead of a permanently retained upload. The lease carries the - // exact-binding submission id: the consuming turn's `turn.started` echoes - // it as `promptId`. A goal-active submission is steered and binds its - // lease explicitly in sendMessageInternal, so it gets no id. - const stagingLease = this.staging.create( - // One retain per unique id per extraction: dedupe repeated placeholder - // occurrences so the lease's id multiplicity matches the retain count. - [...new Set([...extraction.imageAttachmentIds, ...extraction.videoAttachmentIds])], - [], - 'user', - extraction.hasMedia && this.state.appState.goal?.status !== 'active' - ? randomUUID() - : undefined, - ); - if (!this.validateMediaCapabilities(extraction)) { - this.staging.release(stagingLease); - return; - } + if (!this.validateMediaCapabilities(extraction)) return; // Idle cache-hint interception sits before session creation; it is - // synchronous unless a hint actually fires. Aside from the bounded - // ingestion wait above, the send path stays await-free up to sendMessage. - if (this.cacheHint.maybeInterceptOnSubmit(text, extraction)) { - // The stash owns the extraction from here: its resend re-leases inside - // the re-entered send path, its restore goes through releaseRecalled - // (see CacheHintController). Detach so the stash is not double-owned. - this.staging.defer(stagingLease); - return; - } + // synchronous unless a hint actually fires, keeping the send path + // await-free up to sendMessage. + if (this.cacheHint.maybeInterceptOnSubmit(text, extraction)) return; let session = this.session; if (session === undefined) { if (!this.engineV2) { this.showError(LLM_NOT_SET_MESSAGE); - this.staging.release(stagingLease); return; } session = await this.ensureSession(); - if (session === undefined) { - this.staging.release(stagingLease); - return; - } + if (session === undefined) return; } if (extraction.hasMedia) { this.sendMessage(session, text, { hasMedia: true, parts: extraction.parts, imageAttachmentIds: extraction.imageAttachmentIds, - videoAttachmentIds: extraction.videoAttachmentIds, - lease: stagingLease, }); } else { this.sendMessage(session, text); @@ -1426,115 +1324,14 @@ export class KimiTUI { this.state.ui.requestRender(); } - async sendInlineSkillUserInput( - text: string, - activations: readonly InlineSkillActivation[], - preExtracted?: ExtractionResult, - ): Promise<void> { - if (this.btwPanelController.sendUserInput(text, activations)) return; - if (this.state.appState.model.trim().length === 0) { - this.showError(LLM_NOT_SET_MESSAGE); - return; - } - let extraction: ReturnType<typeof extractMediaAttachments>; - try { - extraction = preExtracted ?? extractMediaAttachments(text, this.imageStore); - } catch (error) { - this.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); - return; - } - if (!this.validateMediaCapabilities(extraction)) return; - if (this.cacheHint.maybeInterceptOnSubmit(text, extraction, activations)) return; - let session = this.session; - if (session === undefined) { - // Dispatch only routes here on the v2 engine, so the session is created - // lazily on first use exactly like a normal prompt. - session = await this.ensureSession(); - if (session === undefined) return; - } - if ( - this.deferUserMessages || - this.state.appState.goal?.status === 'active' || - this.state.appState.streamingPhase !== 'idle' || - this.state.appState.isCompacting - ) { - this.enqueueMessage( - text, - extraction.hasMedia - ? { - hasMedia: true, - parts: extraction.parts, - imageAttachmentIds: extraction.imageAttachmentIds, - videoAttachmentIds: extraction.videoAttachmentIds, - inlineSkillActivations: activations, - } - : { inlineSkillActivations: activations }, - ); - this.updateQueueDisplay(); - this.state.ui.requestRender(); - return; - } - this.beginSessionRequest(); - void this.runInlineSkillActivations(session, text, activations, extraction).catch( - (error: unknown) => { - this.failSessionRequest(`Skill activation failed: ${formatErrorMessage(error)}`); - }, - ); - } - - private async runInlineSkillActivations( - session: Session, - text: string, - activations: readonly InlineSkillActivation[], - extraction: ReturnType<typeof extractMediaAttachments>, - ): Promise<void> { - const knownEntryIds = new Set(this.state.transcriptEntries.map((entry) => entry.id)); - await session.promptWithSkills( - extraction.hasMedia - ? resolveOriginalCaptions( - extraction.parts, - extraction.imageAttachmentIds, - this.imageStore, - originalsDirForSession(session), - ) - : text, - activations.map((activation) => ({ name: activation.skillName, args: activation.args })), - ); - // The engine bundles the activations into the prompt's own message, and - // the `skill.activated` events land synchronously during the call — so - // the cards appended for this submission are the skill_activation entries - // with fresh ids (the window trim may replace the entries array mid-call, - // so membership is decided by id, not by index into a captured array). - // Appending the user entry afterwards keeps the live transcript in the - // same order as a resumed replay (skill cards first, prompt last). - // Marking only happens once the submission was accepted: a rejected - // bundle leaves no cards and must not leave a local undo anchor the - // engine never recorded. - for (const entry of this.state.transcriptEntries) { - if (entry.kind === 'skill_activation' && !knownEntryIds.has(entry.id)) { - entry.bundledWithPrompt = true; - } - } - this.appendTranscriptEntry({ - id: nextTranscriptId(), - kind: 'user', - turnId: undefined, - renderMode: 'plain', - content: text, - imageAttachmentIds: - extraction.imageAttachmentIds.length > 0 ? extraction.imageAttachmentIds : undefined, - }); - } - validateMediaCapabilities(extraction: { hasMedia: boolean; imageAttachmentIds: readonly number[]; videoAttachmentIds: readonly number[]; - imageSnapshots?: readonly unknown[]; }): boolean { if (!extraction.hasMedia) return true; if ( - (extraction.imageAttachmentIds.length > 0 || (extraction.imageSnapshots?.length ?? 0) > 0) && + extraction.imageAttachmentIds.length > 0 && !this.supportsCurrentModelCapability('image_in') ) { this.showError('Current model does not support image input.'); @@ -1588,39 +1385,16 @@ export class KimiTUI { if (this.state.queuedMessages.length === 0) return undefined; const last = this.state.queuedMessages.at(-1)!; this.state.queuedMessages = this.state.queuedMessages.slice(0, -1); - // A recall restores the draft into the editor — it is not a discard: - // consumes the retains only, keeping the staged daemon uploads alive - // (see `releaseRecalled`) so the restored draft resubmits them. - this.staging.releaseRecalled([ - ...(last.imageAttachmentIds ?? []), - ...(last.videoAttachmentIds ?? []), - ]); return last; } - /** - * Cache-hint restore: a dismissed/hand-back interception returns its draft - * to the editor — same semantics as a queue recall (consume the stash - * extraction's retains; the staged daemon uploads stay alive for the - * restored draft). - */ - recallStashedMedia(extraction: ExtractionResult | undefined): void { - if (extraction === undefined) return; - this.staging.releaseRecalled([ - ...extraction.imageAttachmentIds, - ...extraction.videoAttachmentIds, - ]); - } - // ========================================================================= // Session Requests / Queues // ========================================================================= private enqueueMessage( text: string, - options?: SendMessageOptions & { - readonly inlineSkillActivations?: readonly InlineSkillActivation[]; - }, + options?: SendMessageOptions, mode?: 'prompt' | 'bash', ): void { this.state.queuedMessages.push({ @@ -1631,12 +1405,7 @@ export class KimiTUI { options?.imageAttachmentIds !== undefined && options.imageAttachmentIds.length > 0 ? options.imageAttachmentIds : undefined, - videoAttachmentIds: - options?.videoAttachmentIds !== undefined && options.videoAttachmentIds.length > 0 - ? options.videoAttachmentIds - : undefined, mode, - inlineSkillActivations: options?.inlineSkillActivations, }); this.track('input_queue'); } @@ -1667,76 +1436,17 @@ export class KimiTUI { sendQueuedMessage(session: Session, item: QueuedMessage): void { if (item.mode === 'bash') { - this.staging.releaseQueued([item]); void this.runShellCommandFromInput(item.text); return; } - if (item.mode === 'skill' && item.skillName !== undefined) { - // sendSkillActivation re-checks the busy state, so a premature drain - // re-queues at the tail instead of racing the running turn. - this.sendSkillActivation(session, item.skillName, item.skillArgs ?? ''); - return; - } - if (item.inlineSkillActivations !== undefined && item.inlineSkillActivations.length > 0) { - // Media was extracted and validated at enqueue time; reuse the queued - // parts rather than re-extracting from a possibly-cleared image store. - // Expiring daemon refs refresh at dispatch, same as the plain tail below. - const refreshed = - item.parts === undefined - ? [] - : [ - ...refreshExpiringImageFileRefs( - item.parts, - item.imageAttachmentIds ?? [], - this.imageStore, - ), - ]; - this.beginSessionRequest(); - void this.runInlineSkillActivations( - session, - item.text, - item.inlineSkillActivations, - { - parts: refreshed, - hasMedia: refreshed.length > 0, - imageAttachmentIds: item.imageAttachmentIds !== undefined ? [...item.imageAttachmentIds] : [], - videoAttachmentIds: item.videoAttachmentIds !== undefined ? [...item.videoAttachmentIds] : [], - imageSnapshots: [], - }, - ).catch((error: unknown) => { - this.failSessionRequest(`Skill activation failed: ${formatErrorMessage(error)}`); - }); - return; - } - const parts = - item.parts === undefined - ? undefined - : refreshExpiringImageFileRefs( - item.parts, - item.imageAttachmentIds ?? [], - this.imageStore, - ); this.harness.withInteractiveAgent(item.agentId ?? MAIN_AGENT_ID, () => { this.sendMessageInternal(session, item.text, { - parts, + parts: item.parts, imageAttachmentIds: item.imageAttachmentIds, - videoAttachmentIds: item.videoAttachmentIds, }); }); } - handleTurnStarted(event: TurnStartedEvent): void { - this.staging.handleTurnStarted(event); - } - - handleTurnEnded(event: TurnEndedEvent): void { - this.staging.handleTurnEnded(event); - } - - releaseStagingMedia(mediaAttachmentIds: readonly number[]): void { - this.staging.releaseMedia(mediaAttachmentIds, []); - } - requestQueuedGoalPromotion(): void { this.sessionEventHandler.requestQueuedGoalPromotion(); } @@ -1754,71 +1464,29 @@ export class KimiTUI { content: input, imageAttachmentIds, }); - // A goal-active steer is buffered into the running goal turn — no new - // turn.started will fire for handleTurnStarted to claim the lease — so - // bind it to that turn here. The turn context must be read BEFORE - // beginSessionRequest resets it, and only while a turn is actually live - // (finalizeTurn clears the id at turn end; a queued dispatch can land - // while the goal driver's next continuation turn is already streaming). - const runningTurnId = - this.state.appState.streamingPhase === 'idle' || this.state.appState.streamingPhase === 'shell' - ? undefined - : this.streamingUI.getTurnContext().turnId; + this.beginSessionRequest(); - // Compression captions for pasted images are authored here — not at - // extraction — because only now is the session (and its media-originals - // dir) known: extraction runs before a first session exists. - const sdkInput = - options?.parts !== undefined - ? resolveOriginalCaptions( - options.parts, - options.imageAttachmentIds ?? [], - this.imageStore, - originalsDirForSession(session), - ) - : input; - const goalActive = this.state.appState.goal?.status === 'active'; - // The lease normally arrives pre-created by sendNormalUserInput (carrying - // its exact-binding submission id). Queued dispatches and steer batches - // arrive with raw ids instead: a prompt submission carrying staged - // media gets a client-chosen prompt id minted here — the engine echoes it - // on the consuming turn's `turn.started` (`promptId`), so the lease binds - // exactly instead of through the origin heuristic. The goal-steer path - // binds its lease explicitly below, so it gets no id. - const stagingIds = [ - ...(options?.imageAttachmentIds ?? []), - ...(options?.videoAttachmentIds ?? []), - ]; - const stagingLease = - options?.lease ?? - this.staging.create( - // One retain per unique id per extraction: dedupe repeated placeholder - // occurrences so the lease's id multiplicity matches the retain count. - [...new Set(stagingIds)], - [], - 'user', - !goalActive && stagingIds.length > 0 ? randomUUID() : undefined, - ); - const submissionId = stagingLease?.submissionId; + const sdkInput = options?.parts ?? input; // While a goal is being pursued the engine holds its active turn across the // whole continuation loop, so a fresh prompt races the goal driver at every // continuation boundary and is rejected with `turn.agent_busy`, dropping // the message. Steer instead: the engine buffers it into the running goal // turn, or launches a turn of its own if the loop just ended. - if (goalActive) { - if (runningTurnId !== undefined) this.staging.bindToTurn(stagingLease, runningTurnId); - this.staging.trackDispatch(stagingLease, session.steer(sdkInput), (error) => { + if (this.state.appState.goal?.status === 'active') { + void session.steer(sdkInput).catch((error: unknown) => { + const message = formatErrorMessage(error); // Same reset as the prompt path: beginSessionRequest already moved the // TUI to the waiting phase, and no turn events may follow a failed // steer (e.g. the session is gone), which would leave the UI stuck // queueing input behind a request that never completes. - this.failSessionRequest(`Failed to steer: ${formatErrorMessage(error)}`); + this.failSessionRequest(`Failed to steer: ${message}`); }); return; } - this.staging.trackDispatch(stagingLease, session.prompt(sdkInput, { promptId: submissionId }), (error) => { - this.failSessionRequest(`Failed to send: ${formatErrorMessage(error)}`); + void session.prompt(sdkInput).catch((error: unknown) => { + const message = formatErrorMessage(error); + this.failSessionRequest(`Failed to send: ${message}`); }); } @@ -1836,51 +1504,12 @@ export class KimiTUI { this.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); return; } - if (!this.validateMediaCapabilities(rewrite)) { - this.staging.releaseMedia(rewrite.imageAttachmentIds, rewrite.stagingPaths); - return; - } - // Compacting (or deferred input): queue behind it — visible and recallable. - // Slash-skill items steer like any queued input on Ctrl-S (the activation - // fires into the running turn instead of the literal text) — see - // editor-keyboard.ts. - // A running turn queues the activation too: every skill behaves like - // plain input — queued by default, steered on demand — because the engine - // steers activations into a running turn exactly like a steered user - // message (v2 `prompt.inject`, v1 `SkillManager.recordActivation`). - // The rewritten args reference the staging cache copies by plain path, - // never the daemon uploads, so queueing takes recall semantics: the - // retains are consumed and the copies retire to session lifetime — they - // must stay readable until the item drains. - const turnRunning = this.state.appState.streamingPhase !== 'idle'; - if (this.deferUserMessages || this.state.appState.isCompacting || turnRunning) { - const args = rewrite.text.trim(); - this.state.queuedMessages.push({ - text: `/${skillName}${args.length > 0 ? ` ${args}` : ''}`, - agentId: this.harness.interactiveAgentId, - mode: 'skill', - skillName, - skillArgs: rewrite.text, - }); - this.staging.releaseRecalled([...rewrite.imageAttachmentIds], rewrite.stagingPaths); - this.track('input_queue'); - this.updateQueueDisplay(); - this.state.ui.requestRender(); - return; - } - const stagingLease = this.staging.create( - [...new Set(rewrite.imageAttachmentIds)], - rewrite.stagingPaths, - 'skill_activation', - ); + if (!this.validateMediaCapabilities(rewrite)) return; this.beginSessionRequest(); - this.staging.trackDispatch( - stagingLease, - session.activateSkill(skillName, rewrite.text), - (error) => { - this.failSessionRequest(`Skill "${skillName}" failed: ${formatErrorMessage(error)}`); - }, - ); + void session.activateSkill(skillName, rewrite.text).catch((error: unknown) => { + const message = formatErrorMessage(error); + this.failSessionRequest(`Skill "${skillName}" failed: ${message}`); + }); } activatePluginCommand( @@ -1899,85 +1528,22 @@ export class KimiTUI { this.showError(`Failed to prepare media attachment: ${formatErrorMessage(error)}`); return; } - const stagingLease = this.staging.create( - [...new Set(rewrite.imageAttachmentIds)], - rewrite.stagingPaths, - 'plugin_command', - ); - if (!this.validateMediaCapabilities(rewrite)) { - this.staging.release(stagingLease); - return; - } + if (!this.validateMediaCapabilities(rewrite)) return; this.beginSessionRequest(); - this.staging.trackDispatch( - stagingLease, - session.activatePluginCommand(pluginId, commandName, rewrite.text), - (error) => { - this.failSessionRequest( - `Command "${pluginId}:${commandName}" failed: ${formatErrorMessage(error)}`, - ); - }, - ); + void session + .activatePluginCommand(pluginId, commandName, rewrite.text) + .catch((error: unknown) => { + const message = formatErrorMessage(error); + this.failSessionRequest(`Command "${pluginId}:${commandName}" failed: ${message}`); + }); } private sendMessage(session: Session, input: string, options?: SendMessageOptions): void { - const phase = this.state.appState.streamingPhase; - // Tower mode keeps the main agent as a long-lived coordinator: while its - // turn is live, new input steers into that turn instead of queueing - // behind it, so consecutive /tower objectives are accepted immediately - // rather than serialized one turn at a time. A foreground shell command - // ('shell') has no turn to steer into and keeps queue semantics, as do - // input deferral and compaction. - const steerIntoCoordinator = - this.state.appState.towerMode && - phase !== 'idle' && - phase !== 'shell' && - !this.deferUserMessages && - !this.state.appState.isCompacting; - // Submission order must survive a mid-turn compaction: objectives queued - // while compacting stay queued when the turn outlives the compaction, so - // steering this input ahead of them would reorder the conversation. - // Prompt-only backlog rides along in the same steer batch, ahead of the - // new input; a non-steerable backlog (bash, slash-skill, inline-skill - // bundle) cannot, and then this input queues behind it instead. - const backlog = this.state.queuedMessages; - const backlogSteerable = backlog.every( - (m) => m.inlineSkillActivations === undefined && m.mode !== 'bash' && m.mode !== 'skill', - ); - if (steerIntoCoordinator && backlogSteerable) { - // Same lease hand-off as the queue path below: the pre-dispatch lease - // defers to the raw ids on the steer item, which re-leases inside - // steerMessage and binds to the running turn. - this.staging.defer(options?.lease); - const items: SteerInputItem[] = [ - ...backlog.map((m) => ({ - text: m.text, - parts: m.parts, - imageAttachmentIds: m.imageAttachmentIds, - videoAttachmentIds: m.videoAttachmentIds, - })), - { - text: input, - parts: options?.parts, - imageAttachmentIds: options?.imageAttachmentIds, - videoAttachmentIds: options?.videoAttachmentIds, - }, - ]; - if (backlog.length > 0) { - this.state.queuedMessages = []; - this.updateQueueDisplay(); - } - this.steerMessage(session, items); - return; - } if ( this.deferUserMessages || this.state.appState.streamingPhase !== 'idle' || this.state.appState.isCompacting ) { - // A queued message re-leases its staged media at dequeue dispatch; the - // pre-dispatch lease defers to the queue item's raw ids. - this.staging.defer(options?.lease); this.enqueueMessage(input, options); return; } @@ -2012,40 +1578,9 @@ export class KimiTUI { }); } - // Dedupe per item, not across the batch: each queued message retained a - // shared medium once, so the batch's id multiplicity is the retain count. - const mediaAttachmentIds = input.flatMap((item) => [ - ...new Set([...(item.imageAttachmentIds ?? []), ...(item.videoAttachmentIds ?? [])]), - ]); - const stagingLease = this.staging.create(mediaAttachmentIds, [], 'user'); - const currentTurnId = this.streamingUI.getTurnContext().turnId; - if (currentTurnId !== undefined) this.staging.bindToTurn(stagingLease, currentTurnId); - // Same dispatch-time caption resolution as sendMessageInternal — the - // running turn's session owns the persisted originals. - const resolvedInput = input.map((item) => - item.parts === undefined - ? item - : { - ...item, - parts: resolveOriginalCaptions( - item.parts, - item.imageAttachmentIds ?? [], - this.imageStore, - originalsDirForSession(session), - ), - }, - ); - this.staging.trackDispatch(stagingLease, session.steer(combineSteerInput(resolvedInput)), (error) => { - this.showError(`Failed to steer: ${formatErrorMessage(error)}`); - }); - } - - steerSkillActivation(session: Session, skillName: string, skillArgs: string): void { - // Ctrl-S on a queued slash-skill item: the activation fires into the - // running turn (the engine steers it there, never the literal text). No - // beginSessionRequest — the live pane belongs to the running turn. - void session.activateSkill(skillName, skillArgs).catch((error: unknown) => { - this.showError(`Skill "${skillName}" failed: ${formatErrorMessage(error)}`); + void session.steer(combineSteerInput(input)).catch((error: unknown) => { + const message = formatErrorMessage(error); + this.showError(`Failed to steer: ${message}`); }); } @@ -2058,9 +1593,7 @@ export class KimiTUI { } clearQueuedMessages(): void { - const queued = this.state.queuedMessages; this.state.queuedMessages = []; - this.staging.releaseQueued(queued); } shiftQueuedMessage(): QueuedMessage | undefined { @@ -2345,15 +1878,6 @@ export class KimiTUI { async setSession(session: Session): Promise<void> { const previous = this.unloadCurrentSession('switching session'); await previous?.close(); - // A session switch abandons the previous session's in-flight staging - // leases and retires its history-owned cache copies. Do this at the - // boundary so retired paths cannot accumulate until process shutdown. - // Only when actually replacing a live session, though: on lazy first - // creation the outstanding lease belongs to the new session's first - // prompt, whose dispatch continues right after this — releasing it here - // would delete the staged media (e.g. a pasted image's daemon upload) - // before the engine's intake can read it. - if (previous !== undefined) this.staging.releaseAll(); this.session = session; this.harness.setTelemetryContext({ sessionId: session.id }); this.registerSessionHandlers(session); @@ -2369,7 +1893,6 @@ export class KimiTUI { permissionMode: status.permission, planMode: status.planMode, swarmMode: status.swarmMode ?? false, - towerMode: status.towerMode ?? false, contextTokens: status.contextTokens, maxContextTokens: status.maxContextTokens, contextUsage: status.contextUsage, @@ -2423,7 +1946,6 @@ export class KimiTUI { async closeSession(reason: string): Promise<void> { const previous = this.unloadCurrentSession(reason); await previous?.close(); - this.staging.releaseAll(); } private unloadCurrentSession(reason: string): Session | undefined { @@ -2569,7 +2091,7 @@ export class KimiTUI { this.aborted = false; this.cacheHint.resetRuntime(); this.streamingUI.discardPending(); - this.clearQueuedMessages(); + this.state.queuedMessages = []; this.state.swarmModeEntry = undefined; this.streamingUI.resetToolCallState(); this.streamingUI.resetToolUi(); @@ -2619,7 +2141,7 @@ export class KimiTUI { try { session = await this.harness.resumeSession({ id: targetSessionId, - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); } catch (error) { const msg = formatErrorMessage(error); @@ -2920,8 +2442,7 @@ export class KimiTUI { this.clearTerminalInlineImages(); this.state.todoPanel.clear(); this.state.todoPanelContainer.clear(); - const stagingFileIds = this.imageStore.clear(); - this.staging.deleteStaged(stagingFileIds); + this.imageStore.clear(); this.renderWelcome(); // No forced full render on session reset: let the differential renderer // converge on its own (a mass change above the viewport still makes the @@ -2946,17 +2467,6 @@ export class KimiTUI { return entry.turnId === undefined || entry.turnId.startsWith('replay:'); } - /** - * Fold-segment boundary: everything {@link isTurnBoundaryComponent} counts, - * plus the cron card. A cron-fired turn mounts no user message, so without - * the card as a boundary its output would share the previous user turn's - * fold segment — and the completed-turn assistant cap would fold that turn's - * final answer into the step summary. - */ - private isFoldSegmentBoundaryComponent(child: Component): boolean { - return this.isTurnBoundaryComponent(child) || child instanceof CronMessageComponent; - } - private trimTranscriptWindow(): boolean { if (!TRANSCRIPT_WINDOW_ENABLED || TRANSCRIPT_MAX_TURNS <= 0) return false; // Session replay already caps history to its own turn limit; trimming during @@ -2983,8 +2493,7 @@ export class KimiTUI { // only be dropped once its owning user message leaves the transcript. for (const entry of toRemove) { if (entry.kind === 'user' && entry.imageAttachmentIds !== undefined) { - const stagingFileIds = this.imageStore.removeMany(entry.imageAttachmentIds); - this.staging.deleteStaged(stagingFileIds); + this.imageStore.removeMany(entry.imageAttachmentIds); } } @@ -3058,10 +2567,10 @@ export class KimiTUI { if (keepSteps <= 0 && keepAssistants <= 0) return false; const children = this.state.transcriptContainer.children; - // Find the start of the current fold segment. + // Find the start of the current turn (last turn-starting user message). let turnStart = -1; for (let i = children.length - 1; i >= 0; i--) { - if (this.isFoldSegmentBoundaryComponent(children[i]!)) { + if (this.isTurnBoundaryComponent(children[i]!)) { turnStart = i; break; } @@ -3143,7 +2652,7 @@ export class KimiTUI { const boundaries: number[] = []; for (let i = 0; i < children.length; i++) { - if (this.isFoldSegmentBoundaryComponent(children[i]!)) boundaries.push(i); + if (this.isTurnBoundaryComponent(children[i]!)) boundaries.push(i); } if (boundaries.length === 0) return; @@ -3570,21 +3079,6 @@ export class KimiTUI { this.state.ui.requestRender(); } - /** - * Live pre-send warning in the footer while the typed `/goal` objective - * exceeds the length limit, so the user can trim it (or move it into a - * file) before submitting instead of losing the input to a rejection. - * `undefined` input means the text cannot be a `/goal` command and is not - * measured at all. The footer keeps this warning in its own slot, so - * transient hints (exit confirm, detach, image paste) only displace it - * temporarily. - */ - updateGoalLengthWarning(text: string | undefined): void { - const warning = text === undefined ? undefined : goalObjectiveLengthWarning(text); - this.state.footer.setWarningHint(warning ?? null); - this.state.ui.requestRender(); - } - async applyTheme(themeName: ThemeName, resolved?: ResolvedTheme): Promise<void> { const palette = await getColorPalette(themeName === 'auto' ? (resolved ?? 'dark') : themeName); currentTheme.setPalette(palette); @@ -3686,7 +3180,6 @@ export class KimiTUI { // ========================================================================= mountEditorReplacement(panel: Component & Focusable): void { - this.state.editorReplacementMounted = true; this.state.editorContainer.clear(); this.state.editorContainer.addChild(panel); this.state.ui.setFocus(panel); @@ -3694,7 +3187,6 @@ export class KimiTUI { } restoreEditor(): void { - this.state.editorReplacementMounted = false; this.state.editorContainer.clear(); this.state.editorContainer.addChild(this.state.editor); this.state.ui.setFocus(this.state.editor); @@ -4017,12 +3509,12 @@ export class KimiTUI { // Mounts the full-screen approval preview viewer on top of the current // approval panel. Uses the same nested-takeover pattern as - // openTaskOutputViewer: beginScreenTakeover swaps the viewer in (root - // children in regular mode, layout root in fullscreen) and closing restores - // it. The approval panel instance is + // openTaskOutputViewer: we snapshot the root container's children, swap + // in the viewer, and restore on close. The approval panel instance is // kept around in `activeApprovalPanel` so its selection state survives. private openApprovalPreview(panel: ApprovalPanelComponent, block: ApprovalPreviewBlock): void { if (this.approvalPreview !== undefined) return; + const savedChildren = [...this.state.ui.children]; const viewer = new ApprovalPreviewViewer( { block, @@ -4032,17 +3524,21 @@ export class KimiTUI { }, this.state.terminal, ); - const takeover = beginScreenTakeover(this.state.ui, viewer); + this.state.ui.clear(); + this.state.ui.addChild(viewer); this.state.ui.setFocus(viewer); this.state.ui.requestRender(true); - this.approvalPreview = { component: viewer, takeover, panel }; + this.approvalPreview = { component: viewer, savedChildren, panel }; } private closeApprovalPreview(): void { const preview = this.approvalPreview; if (preview === undefined) return; this.approvalPreview = undefined; - endScreenTakeover(this.state.ui, preview.takeover); + this.state.ui.clear(); + for (const child of preview.savedChildren) { + this.state.ui.addChild(child); + } this.state.ui.setFocus(preview.panel); this.state.ui.requestRender(true); } diff --git a/apps/kimi-code/src/tui/tui-state.ts b/apps/kimi-code/src/tui/tui-state.ts index b5568ecbf..589d79c57 100644 --- a/apps/kimi-code/src/tui/tui-state.ts +++ b/apps/kimi-code/src/tui/tui-state.ts @@ -1,17 +1,11 @@ import { Container, ProcessTerminal, - ScrollView, - TuiAltScreen, - TuiMainScreen, - VStack, - type TUI, + TUI, } from '@moonshot-ai/pi-tui'; -import { clipboard } from '#/utils/clipboard/clipboard-native'; -import { openUrl } from '#/utils/open-url'; - -import { FooterComponent } from './components/chrome/footer';import { GutterContainer } from './components/chrome/gutter-container'; +import { FooterComponent } from './components/chrome/footer'; +import { GutterContainer } from './components/chrome/gutter-container'; import type { MoonLoader, SpinnerStyle } from './components/chrome/moon-loader'; import { TodoPanelComponent } from './components/chrome/todo-panel'; import type { SessionRow } from './components/dialogs/session-picker'; @@ -20,7 +14,6 @@ import { DEFAULT_TUI_CONFIG } from './config'; import { CHROME_GUTTER } from './constant/rendering'; import type { TasksBrowserState } from './controllers/tasks-browser'; import { currentTheme, type Theme } from './theme'; -import { setMarkdownRenderLatex } from './utils/markdown-options'; import { createTerminalState, type TerminalState } from './utils/terminal-state'; import { INITIAL_LIVE_PANE, @@ -42,12 +35,6 @@ export interface TUIState { queueContainer: Container; btwPanelContainer: Container; editorContainer: Container; - /** - * Fullscreen mode only: the bottom dock (activity/todo/queue/btw/editor + - * footer) stacked under the transcript ScrollView. Undefined in regular - * mode, where all chrome is a direct child of the root container. - */ - dockContainer: VStack | undefined; footer: FooterComponent; editor: CustomEditor; theme: Theme; @@ -66,12 +53,6 @@ export interface TUIState { sessionsLoadingMore: boolean; sessionsScope: 'cwd' | 'all'; activeDialog: 'session-picker' | 'help' | 'trust-prompt' | 'cache-hint' | null; - /** - * True while an editor-replacement panel (help, trust prompt, goal queue - * manager, …) is mounted in place of the editor. Delayed input restores - * must not run in that state — they would displace the newer panel. - */ - editorReplacementMounted: boolean; tasksBrowser: TasksBrowserState | undefined; externalEditorRunning: boolean; queuedMessages: QueuedMessage[]; @@ -90,32 +71,7 @@ export function createTUIState(options: KimiTUIOptions): TUIState { const theme = currentTheme; const terminal = new ProcessTerminal(); - setMarkdownRenderLatex(initialAppState.renderLatex ?? DEFAULT_TUI_CONFIG.renderLatex ?? true); - // Fullscreen is experimental and env-gated for now: KIMI_CODE_TUI_FULL_SCREEN=1. - const fullscreen = process.env['KIMI_CODE_TUI_FULL_SCREEN'] === '1'; - const ui = - fullscreen - ? new TuiAltScreen(terminal, undefined, undefined, { - // Mouse capture takes over the terminal's native link activation, so - // route OSC 8 clicks through our own opener. - openUrl, - // Likewise, on Windows the terminal's native right-click paste is - // intercepted; feed the clipboard to the focused component as a - // bracketed paste instead (renderer only calls this on win32). - onRightClickPaste: () => { - const target = ui.getFocusedComponent(); - if (!target?.handleInput || clipboard?.getText === undefined) return; - void clipboard - .getText() - .then((text) => { - if (!text || ui.getFocusedComponent() !== target) return; - target.handleInput?.(`\x1b[200~${text}\x1b[201~`); - ui.requestRender(); - }) - .catch(() => {}); - }, - }) - : new TuiMainScreen(terminal); + const ui = new TUI(terminal); const transcriptContainer = new GutterContainer(CHROME_GUTTER, CHROME_GUTTER); const activityContainer = new GutterContainer(CHROME_GUTTER, CHROME_GUTTER); @@ -131,33 +87,6 @@ export function createTUIState(options: KimiTUIOptions): TUIState { ui.requestRender(); }); - let dockContainer: VStack | undefined; - if (ui instanceof TuiAltScreen) { - // Fullscreen (alternate screen): the transcript scrolls inside the primary - // ScrollView while the rest of the chrome stays docked at the bottom. The - // footer joins the dock later via mountFooter(). - // Sizing contract (mirrors pi's interactive layout): the transcript starts - // from basis 0 and grows; the dock keeps its intrinsic height, with the - // editor never squeezed below its 3 rows (top border / input / bottom - // border) and the footer below 1 — otherwise the box outline gets clipped. - const scrollView = new ScrollView(transcriptContainer, { - follow: 'end', - primary: true, - overscroll: 'chain', - scrollbar: 'auto', - }); - dockContainer = new VStack(); - dockContainer.addChild(activityContainer, { shrink: 1, minSize: 0 }); - dockContainer.addChild(todoPanelContainer, { shrink: 1, minSize: 0 }); - dockContainer.addChild(queueContainer, { shrink: 1, minSize: 0 }); - dockContainer.addChild(btwPanelContainer, { shrink: 1, minSize: 0 }); - dockContainer.addChild(editorContainer, { shrink: 1, minSize: 3 }); - const root = new VStack(); - root.addChild(scrollView, { basis: 0, grow: 1, shrink: 1, minSize: 1 }); - root.addChild(dockContainer, { basis: 'auto', grow: 0, shrink: 1, minSize: 1 }); - ui.setLayoutRoot(root); - } - return { ui, terminal, @@ -168,7 +97,6 @@ export function createTUIState(options: KimiTUIOptions): TUIState { queueContainer, btwPanelContainer, editorContainer, - dockContainer, editor, footer, theme, @@ -185,7 +113,6 @@ export function createTUIState(options: KimiTUIOptions): TUIState { sessionsLoadingMore: false, sessionsScope: 'cwd', activeDialog: null, - editorReplacementMounted: false, tasksBrowser: undefined, externalEditorRunning: false, queuedMessages: [], diff --git a/apps/kimi-code/src/tui/types.ts b/apps/kimi-code/src/tui/types.ts index 83aff8c87..d1e3341d8 100644 --- a/apps/kimi-code/src/tui/types.ts +++ b/apps/kimi-code/src/tui/types.ts @@ -39,7 +39,6 @@ export interface AppState { /** 'bash' when the editor is in `!` shell-command mode. */ inputMode: 'prompt' | 'bash'; swarmMode: boolean; - towerMode: boolean; /** Live thinking effort of the active session (e.g. 'off', 'on', 'high'); * mirrors the runtime. The single source of truth for the thinking state in * the TUI. */ @@ -72,8 +71,6 @@ export interface AppState { editorCommand: string | null; /** Mirrors the TUI config toggle; defaults to false when absent from older fixtures. */ disablePasteBurst?: boolean; - /** LaTeX math rendering in Markdown; defaults to true when absent from older fixtures. */ - renderLatex?: boolean; /** Mirrors the TUI config toggle; defaults to true when absent from older fixtures. */ cacheExpiryHint?: boolean; notifications: NotificationsConfig; @@ -237,10 +234,6 @@ export interface TranscriptEntry { skillName?: string; skillArgs?: string; skillTrigger?: SkillActivationTrigger; - /** Card belongs to the following prompt's bundled submission: undo removes them together. */ - bundledWithPrompt?: boolean; - /** Entry renders a UserPromptSubmit hook result (sits inside its prompt's group window). */ - hookResult?: boolean; pluginCommandData?: PluginCommandTranscriptData; } @@ -257,32 +250,14 @@ export interface LivePaneState { pendingQuestion: PendingQuestion | null; } -export interface InlineSkillActivation { - readonly skillName: string; - /** - * Skill arguments. Only set for a leading `/skill:<name> args` command that - * is combined with further inline skills; inline tokens carry no args. - */ - readonly args?: string; -} - export interface QueuedMessage { readonly text: string; readonly agentId?: string; readonly parts?: readonly PromptPart[]; readonly imageAttachmentIds?: readonly number[]; - readonly videoAttachmentIds?: readonly number[]; /** `bash` for a `!` shell command queued while another command is running; - * `skill` for a slash-skill activation queued while the session is busy; * undefined (=`prompt`) for a normal message. */ - readonly mode?: 'prompt' | 'bash' | 'skill'; - /** Set when mode === 'skill': the skill to activate when the item drains. - * `text` then holds the display/recall string (`/name args`). */ - readonly skillName?: string; - /** Set when mode === 'skill': the raw (media-rewritten) args to activate with. */ - readonly skillArgs?: string; - /** Skills to activate together with this queued message's prompt. */ - readonly inlineSkillActivations?: readonly InlineSkillActivation[]; + readonly mode?: 'prompt' | 'bash'; } /** @@ -295,7 +270,6 @@ export interface SteerInputItem { readonly text: string; readonly parts?: readonly PromptPart[]; readonly imageAttachmentIds?: readonly number[]; - readonly videoAttachmentIds?: readonly number[]; } export const INITIAL_LIVE_PANE: LivePaneState = { diff --git a/apps/kimi-code/src/tui/utils/export-markdown.ts b/apps/kimi-code/src/tui/utils/export-markdown.ts index 594a411c4..9531efa10 100644 --- a/apps/kimi-code/src/tui/utils/export-markdown.ts +++ b/apps/kimi-code/src/tui/utils/export-markdown.ts @@ -139,9 +139,6 @@ function formatTurnMd(messages: readonly ContextMessage[], turnNumber: number): if (msg.role === 'user') { lines.push('### User', ''); - // A daemon-ref media part is self-contained and renders as - // `[image]`/`[video]` below; a standalone `<media path>` tag is user - // text and exports verbatim. for (const part of msg.content) { const text = formatContentPartMd(part); if (text.trim()) { diff --git a/apps/kimi-code/src/tui/utils/image-attachment-store.ts b/apps/kimi-code/src/tui/utils/image-attachment-store.ts index 86320f72a..8d653159a 100644 --- a/apps/kimi-code/src/tui/utils/image-attachment-store.ts +++ b/apps/kimi-code/src/tui/utils/image-attachment-store.ts @@ -6,11 +6,9 @@ * (640×480)]` / `[video #2 sample.mov]`). The placeholder is what the * user sees in the input field; on submit, `extractMediaAttachments` * walks the text and expands image placeholders to image content parts - * (dispatch-time caption resolution then precedes them with a compression - * caption when paste-time compression shrank the bytes — see - * `ImageAttachment.original`) and video placeholders to `kimi-file://` - * daemon references (the paste was uploaded to the daemon file store in - * the background, exactly like an uploaded image). + * (preceded by a compression caption when paste-time compression shrank + * the bytes — see `ImageAttachment.original`) and video placeholders to + * file-path tags for `ReadMediaFile`. * * Scope is per-`KimiTUI` instance. Reloads (`/new`, `/clear`, * session switch) call `clear()` so ids restart from 1 and stale @@ -21,24 +19,14 @@ export interface ImageAttachmentOriginal { /** - * Pre-compression bytes, kept in memory until dispatch-time caption - * resolution (`resolveOriginalCaptions`) persists them — the session whose - * media-originals dir they belong in may not exist yet at paste time. - * Released once persistence succeeds; the on-disk copy is the original - * from then on. + * Where the pre-compression bytes were persisted for readback + * (ReadMediaFile + region); null when persistence failed. */ - bytes?: Uint8Array; + readonly path: string | null; readonly width: number; readonly height: number; - /** Pre-compression size, retained for captions after `bytes` is released. */ readonly byteLength: number; readonly mime: string; - /** - * Where the original was persisted for readback (ReadMediaFile + region). - * Undefined until dispatch-time persistence succeeds; failures are retried - * at the next dispatch. - */ - path?: string; } export interface ImageAttachment { @@ -50,28 +38,10 @@ export interface ImageAttachment { readonly height: number; /** * Pre-compression original, recorded when paste-time compression changed - * the bytes. Drives the compression caption authored on dispatch so the - * model knows it received a downsampled copy. Absent for untouched pastes. + * the bytes. Drives the compression caption emitted on submit so the model + * knows it received a downsampled copy. Absent for untouched pastes. */ readonly original?: ImageAttachmentOriginal | undefined; - /** - * Daemon file-store id, set when the bytes were uploaded at paste time - * (v2 engine only). Submit-time expansion then emits a `kimi-file://` - * reference plus an `<image path>` tag instead of inline base64; absent - * means the inline form is used. - */ - fileId?: string; - /** Epoch milliseconds when the daemon staging upload expires. */ - fileExpiresAt?: number; - /** - * Background ingestion (compression/daemon upload) still in flight. The - * paste callback settles once the placeholder is in the editor — typing - * never waits on this — but submit holds it briefly - * (`pendingImageIngestions`) so a fast paste-then-Enter still gets the - * compressed/ref form; a slow ingestion submits the inline form instead. - * Cleared when ingestion completes. - */ - pending?: Promise<void>; /** Rendered placeholder string, e.g. `[image #1 (640×480)]`. */ readonly placeholder: string; } @@ -83,35 +53,15 @@ export interface VideoAttachment { readonly filename: string; readonly sourcePath: string; readonly label: string; - /** - * Daemon file-store id, set when the source file was uploaded at paste - * time. Submit-time expansion emits a `kimi-file://` video reference; - * absent means the upload failed or is still in flight (`pending`), and - * expansion refuses the submission — a video has no inline fallback. - */ - fileId?: string; - /** Epoch milliseconds when the daemon staging upload expires. */ - fileExpiresAt?: number; - /** - * Background upload still in flight (see `ImageAttachment.pending` — the - * same bounded submit wait applies, `pendingMediaIngestions`). Cleared - * when the upload completes. - */ - pending?: Promise<void>; /** Rendered placeholder string, e.g. `[video #1 sample.mov]`. */ readonly placeholder: string; } export type MediaAttachment = ImageAttachment | VideoAttachment; -type MutableImageAttachment = { - -readonly [Property in keyof ImageAttachment]: ImageAttachment[Property]; -}; - export class ImageAttachmentStore { private nextId = 1; private readonly byId = new Map<number, MediaAttachment>(); - private readonly stagingUses = new Map<number, number>(); addImage( bytes: Uint8Array, @@ -119,8 +69,6 @@ export class ImageAttachmentStore { width: number, height: number, original?: ImageAttachmentOriginal, - fileId?: string, - fileExpiresAt?: number, ): ImageAttachment { const id = this.nextId; this.nextId += 1; @@ -132,8 +80,6 @@ export class ImageAttachmentStore { width, height, original, - fileId, - fileExpiresAt, placeholder: formatPlaceholder(id, width, height), }; this.byId.set(id, attachment); @@ -160,168 +106,26 @@ export class ImageAttachmentStore { return attachment; } - /** - * Complete an image that was inserted into the editor before its ingestion - * work (compression/upload) finished. Returns undefined when the attachment - * was cleared while that work was in flight. - */ - completeImage( - attachment: ImageAttachment, - input: { - bytes: Uint8Array; - mime: string; - width: number; - height: number; - original?: ImageAttachmentOriginal; - fileId?: string; - fileExpiresAt?: number; - }, - ): ImageAttachment | undefined { - const current = this.byId.get(attachment.id); - if (current !== attachment || attachment.kind !== 'image') return undefined; - const mutable = attachment as MutableImageAttachment; - mutable.bytes = input.bytes; - mutable.mime = input.mime; - mutable.width = input.width; - mutable.height = input.height; - mutable.original = input.original; - mutable.fileId = input.fileId; - mutable.fileExpiresAt = input.fileExpiresAt; - mutable.pending = undefined; - mutable.placeholder = formatPlaceholder(attachment.id, input.width, input.height); - return attachment; - } - - /** - * Complete a video whose background daemon upload finished. Returns - * undefined when the attachment was cleared while the upload was in - * flight — the caller then deletes the orphaned upload. - */ - completeVideo( - attachment: VideoAttachment, - input: { - fileId?: string; - fileExpiresAt?: number; - }, - ): VideoAttachment | undefined { - const current = this.byId.get(attachment.id); - if (current !== attachment || attachment.kind !== 'video') return undefined; - attachment.fileId = input.fileId; - attachment.fileExpiresAt = input.fileExpiresAt; - attachment.pending = undefined; - return attachment; - } - - /** - * Record where an attachment's pre-compression original was persisted and - * release the in-memory buffer — the on-disk copy is the original from - * then on, and the caption only needs the retained metadata. Dispatch-time - * caption resolution calls this after a successful write; failures leave - * the path unset so a later dispatch retries. - */ - setOriginalPath(id: number, path: string): void { - const attachment = this.byId.get(id); - if (attachment?.kind !== 'image' || attachment.original === undefined) return; - attachment.original.path = path; - attachment.original.bytes = undefined; - } - get(id: number): MediaAttachment | undefined { return this.byId.get(id); } - /** - * Drop every attachment and return the staged daemon file ids to delete. - * Uploads with an outstanding retain are excluded: a stashed/queued draft - * still references them (e.g. a cache-hint resend into the NEXT session), - * so they stay alive for that consumer; if none claims them, the daemon's - * staging TTL reaps them. - */ - clear(): readonly string[] { - const fileIds = this.fileIds((id) => (this.stagingUses.get(id) ?? 0) === 0); + clear(): void { this.byId.clear(); - this.stagingUses.clear(); this.nextId = 1; - return fileIds; } /** * Drop a single attachment, releasing its bytes. Used to reclaim image * memory once the transcript entry that references it is trimmed. */ - remove(id: number): string | undefined { - const attachment = this.byId.get(id); - const fileId = attachment?.fileId; + remove(id: number): void { this.byId.delete(id); - this.stagingUses.delete(id); - return fileId; } /** Drop many attachments at once. See {@link remove}. */ - removeMany(ids: Iterable<number>): readonly string[] { - const fileIds: string[] = []; - for (const id of ids) { - const fileId = this.remove(id); - if (fileId !== undefined) fileIds.push(fileId); - } - return fileIds; - } - - retainFileIds(ids: Iterable<number>): void { - const retained = new Set<number>(); - for (const id of ids) { - if (retained.has(id)) continue; - retained.add(id); - const attachment = this.byId.get(id); - if (attachment?.fileId === undefined) continue; - this.stagingUses.set(id, (this.stagingUses.get(id) ?? 0) + 1); - } - } - - takeFileIds(ids: Iterable<number>): readonly string[] { - const fileIds: string[] = []; - const taken = new Set<number>(); - for (const id of ids) { - if (taken.has(id)) continue; - taken.add(id); - const attachment = this.byId.get(id); - if (attachment?.fileId === undefined) continue; - const uses = this.stagingUses.get(id) ?? 0; - if (uses > 1) { - this.stagingUses.set(id, uses - 1); - continue; - } - this.stagingUses.delete(id); - fileIds.push(attachment.fileId); - attachment.fileId = undefined; - attachment.fileExpiresAt = undefined; - } - return fileIds; - } - - /** - * Consume the retains a recalled submission held WITHOUT taking the staged - * files: the recalled draft still references the attachments, so their - * daemon uploads stay alive and the next submit re-retains them. Used by - * queue recall; every other release path goes through {@link takeFileIds}. - */ - releaseRetains(ids: Iterable<number>): void { - const released = new Set<number>(); - for (const id of ids) { - if (released.has(id)) continue; - released.add(id); - const uses = this.stagingUses.get(id) ?? 0; - if (uses > 1) this.stagingUses.set(id, uses - 1); - else this.stagingUses.delete(id); - } - } - - private fileIds(include?: (id: number) => boolean): readonly string[] { - return [...this.byId.values()].flatMap((attachment) => - attachment.fileId !== undefined && (include?.(attachment.id) ?? true) - ? [attachment.fileId] - : [], - ); + removeMany(ids: Iterable<number>): void { + for (const id of ids) this.byId.delete(id); } size(): number { diff --git a/apps/kimi-code/src/tui/utils/image-placeholder.ts b/apps/kimi-code/src/tui/utils/image-placeholder.ts index d6984a906..87d53eabc 100644 --- a/apps/kimi-code/src/tui/utils/image-placeholder.ts +++ b/apps/kimi-code/src/tui/utils/image-placeholder.ts @@ -3,26 +3,15 @@ * we'll send to the SDK prompt endpoint. * * `extractMediaAttachments` (sync) is the single expansion path for prompts: - * - image placeholders expand to inline image content parts. When the paste - * was uploaded to the daemon file store (`ImageAttachment.fileId`, v2 - * engine only), the placeholder instead expands to a bare - * `kimi-file://<id>` image part — the engine's prompt intake materializes - * the session copy and rewrites the reference with its `?path=`, making - * the part self-contained (no paired tag is authored); without a `fileId` - * the inline base64 form is emitted unchanged (the only form the v1 - * engine accepts). Compression captions for paste-time-downsampled images - * are NOT authored here: extraction runs before a first session exists, - * so `resolveOriginalCaptions` adds them at dispatch time, persisting the - * in-memory original (`ImageAttachment.original`) into the session's - * media-originals dir first; - * - video placeholders expand to a bare `kimi-file://<id>` video part: - * the paste was uploaded to the daemon file store in the background - * (`VideoAttachment.fileId`), and the engine's prompt intake - * materializes the session copy and rewrites the reference with its - * `?path=`, exactly like an uploaded image. A video without a usable - * upload — still in flight after the bounded submit wait, failed, or - * expired — aborts extraction with an error: video bytes have no - * inline fallback form. + * - image placeholders expand to inline image content parts (preceded by a + * compression caption when paste-time compression shrank the bytes — see + * `ImageAttachment.original`); + * - video placeholders are copied into the shared cache (`getCacheDir()`) + * and expand to a `video_url` part pointing at the cache copy with a + * `file://` url. The v1 engine resolves that local reference inside the + * turn — uploading it (the `ms://` inline form) or degrading to a + * `<video path>` tag the model reads with `ReadMediaFile` — before the + * prompt lands in history. * * `rewriteMediaPlaceholders` is the separate text channel for slash-command * args (`/skill`, plugin commands): those are plain text, so media is rendered @@ -39,22 +28,16 @@ * noise between two media parts. */ -import { createHash, randomUUID } from 'node:crypto'; -import { copyFileSync, mkdirSync, readdirSync, statSync, unlinkSync, writeFileSync } from 'node:fs'; -import { tmpdir } from 'node:os'; +import { randomUUID } from 'node:crypto'; +import { copyFileSync, mkdirSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; +import { pathToFileURL } from 'node:url'; -import type { PromptPart, Session } from '@moonshot-ai/kimi-code-sdk'; -import { - buildDaemonFileUrl, - buildImageCompressionCaption, - buildMediaPathTag, - sessionMediaOriginalsDir, -} from '@moonshot-ai/kimi-code-sdk'; +import type { PromptPart } from '@moonshot-ai/kimi-code-sdk'; +import { buildImageCompressionCaption } from '@moonshot-ai/kimi-code-sdk'; import { getCacheDir } from '#/utils/paths'; -import { MEDIA_FILE_REF_MIN_REMAINING_MS } from '../constant/media'; import type { ImageAttachment, ImageAttachmentStore, @@ -75,31 +58,6 @@ export interface ExtractionResult { imageAttachmentIds: number[]; /** Video attachment ids matched, in the order they appeared. */ videoAttachmentIds: number[]; - /** - * Image bytes captured while extracting the prompt. A cache-hint resend can - * outlive the attachment store and daemon file ids, so it uses these - * snapshots to rebuild the image parts as inline data URLs. - */ - imageSnapshots: ImageResendSnapshot[]; -} - -export interface ImageResendSnapshot { - readonly bytes: Uint8Array; - readonly mime: string; - readonly width: number; - readonly height: number; - /** - * Pre-compression original captured at extraction, so a new-session resend - * can still persist it and author the compression caption after the image - * store (and its attachments) was cleared. Absent for untouched pastes and - * for originals already persisted and released. - */ - readonly original?: { - readonly bytes: Uint8Array; - readonly width: number; - readonly height: number; - readonly mime: string; - }; } export function extractMediaAttachments( @@ -109,7 +67,6 @@ export function extractMediaAttachments( const parts: PromptPart[] = []; const imageAttachmentIds: number[] = []; const videoAttachmentIds: number[] = []; - const imageSnapshots: ImageResendSnapshot[] = []; let cursor = 0; let hasMedia = false; @@ -126,45 +83,18 @@ export function extractMediaAttachments( const before = text.slice(cursor, match.index); pushText(parts, before); if (attachment.kind === 'video') { - // The paste was uploaded to the daemon file store in the background: - // reference it by a bare `kimi-file://` url — the engine's prompt - // intake materializes the session copy, so the edge stages no local - // copy. Throws when the upload is unusable (still in flight, failed, - // expired): a video has no inline fallback. - parts.push(videoPartForAttachment(attachment)); + // Copy the paste into the shared cache and reference it by a `file://` + // url; the engine resolves (uploads or degrades) it inside the turn. + const cachePath = materializeVideoToCache(attachment); + parts.push(videoPartForCachePath(cachePath)); videoAttachmentIds.push(id); } else { - const original = attachment.original; - imageSnapshots.push({ - bytes: attachment.bytes, - mime: attachment.mime, - width: attachment.width, - height: attachment.height, - original: - original?.bytes === undefined - ? undefined - : { - bytes: original.bytes, - width: original.width, - height: original.height, - mime: original.mime, - }, - }); - // No compression caption here: `resolveOriginalCaptions` authors it - // at dispatch time, once the session (and its media-originals dir) - // is known. - if (attachment.fileId !== undefined) { - // The bytes were uploaded to the daemon file store at paste time - // (v2): reference them by a bare `kimi-file://` url — the engine's - // prompt intake materializes the session copy and rewrites the - // reference with its `?path=`, so the edge stages no local copy. - parts.push({ - type: 'image_url', - imageUrl: { url: buildDaemonFileUrl(attachment.fileId) }, - }); - } else { - parts.push(imagePartForAttachment(attachment)); + // Paste-time compression is announced next to the image so the model + // knows it received a downsampled copy and where the original lives. + if (attachment.original !== undefined) { + pushText(parts, captionForCompressedImage(attachment)); } + parts.push(imagePartForAttachment(attachment)); imageAttachmentIds.push(id); } hasMedia = true; @@ -173,173 +103,15 @@ export function extractMediaAttachments( const tail = text.slice(cursor); pushText(parts, tail); - store.retainFileIds([...imageAttachmentIds, ...videoAttachmentIds]); - const freshParts = refreshExpiringImageFileRefs(parts, imageAttachmentIds, store); return { // Text-only submissions drop the synthesised parts array — the // caller's contract is "parts is meaningful iff hasMedia", and // emitting a stray TextPart confuses consumers that branch on // `parts.length > 0`. - parts: hasMedia ? freshParts : [], + parts: hasMedia ? parts : [], hasMedia, imageAttachmentIds, videoAttachmentIds, - imageSnapshots, - }; -} - -/** - * Give media referenced by `text` a bounded moment to finish its background - * paste ingestion (image compression/upload, video daemon upload — see - * `ImageAttachment.pending` / `VideoAttachment.pending`) before extraction, - * so a paste-then-immediately-submit still expands to the daemon-ref form. - * The returned promise resolves after `timeoutMs` at the latest; an image - * whose ingestion has not landed by then extracts to the inline fallback - * form, a video refuses the submission (no inline form exists). Returns - * undefined when nothing is pending, so the submit path stays synchronous - * for media-free prompts. - */ -export function pendingMediaIngestions( - text: string, - store: ImageAttachmentStore, - timeoutMs: number, -): Promise<void> | undefined { - const pendings: Promise<void>[] = []; - PLACEHOLDER_REGEX.lastIndex = 0; - let match: RegExpExecArray | null; - while ((match = PLACEHOLDER_REGEX.exec(text)) !== null) { - const [, kind, idStr] = match; - if (kind !== 'image' && kind !== 'video') continue; - if (idStr === undefined) continue; - const attachment = store.get(Number.parseInt(idStr, 10)); - if (attachment?.kind === kind && attachment.pending !== undefined) { - pendings.push(attachment.pending); - } - } - if (pendings.length === 0) return undefined; - let timer: ReturnType<typeof setTimeout> | undefined; - return Promise.race([ - Promise.allSettled(pendings).then(() => undefined), - new Promise<void>((resolve) => { - timer = setTimeout(resolve, timeoutMs); - }), - ]).finally(() => { - clearTimeout(timer); - }); -} - -/** - * Replace daemon refs that may expire before validation reaches the server - * with the attachment's retained bytes. Called both at extraction time and - * again when a queued/cache-hint submission is actually dispatched. - */ -export function refreshExpiringImageFileRefs( - parts: readonly PromptPart[], - imageAttachmentIds: readonly number[], - store: ImageAttachmentStore, - now = Date.now(), -): PromptPart[] { - if (imageAttachmentIds.length === 0) return [...parts]; - let imageIndex = 0; - let changed = false; - const next = parts.map((part) => { - if (part.type !== 'image_url') return part; - const attachmentId = imageAttachmentIds[imageIndex++]; - if (attachmentId === undefined || !part.imageUrl.url.startsWith('kimi-file://')) return part; - const attachment = store.get(attachmentId); - if (attachment?.kind !== 'image') return part; - - const fileId = attachment.fileId; - const expiresAt = attachment.fileExpiresAt; - const usable = - fileId !== undefined && - (expiresAt === undefined || expiresAt - now > MEDIA_FILE_REF_MIN_REMAINING_MS); - if (usable) { - const url = buildDaemonFileUrl(fileId); - if (url === part.imageUrl.url) return part; - changed = true; - return { ...part, imageUrl: { ...part.imageUrl, url } }; - } - - attachment.fileId = undefined; - attachment.fileExpiresAt = undefined; - changed = true; - return imagePartForAttachment(attachment); - }); - return changed ? next : [...parts]; -} - -/** - * Make an extraction safe to resend after a session reset. The reset clears - * the image store and deletes unretained daemon file ids, so uploaded image - * refs must be replaced with the bytes captured during the original - * extraction. Video refs pass through unchanged: their uploads were retained - * by the stash, and `ImageAttachmentStore.clear` keeps retained uploads - * alive for exactly this resend (unclaimed survivors fall to the daemon's - * staging TTL). - * - * Snapshots of compressed pastes also carry the pre-compression original: the - * cleared store took the attachment with it, so dispatch-time caption - * resolution can no longer find either. `makeExtractionResendable` persists - * that original into `originalsDir` (the NEW session's media-originals dir; - * temp-dir fallback when undefined) and authors the compression caption - * itself, right before the rebuilt image part. - */ -export function makeExtractionResendable( - extraction: ExtractionResult, - originalsDir?: string, -): ExtractionResult { - if (extraction.imageSnapshots.length === 0) return extraction; - - let imageIndex = 0; - const parts: PromptPart[] = []; - for (const part of extraction.parts) { - if (part.type !== 'image_url') { - parts.push(part); - continue; - } - const snapshot = extraction.imageSnapshots[imageIndex++]; - const original = snapshot?.original; - if (snapshot !== undefined && original !== undefined) { - parts.push({ - type: 'text', - text: buildImageCompressionCaption({ - original: { - width: original.width, - height: original.height, - byteLength: original.bytes.length, - mimeType: original.mime, - }, - final: { - width: snapshot.width, - height: snapshot.height, - byteLength: snapshot.bytes.length, - mimeType: snapshot.mime, - }, - originalPath: persistOriginalImageSync(original.bytes, original.mime, originalsDir), - }), - }); - } - if (snapshot === undefined || !part.imageUrl.url.startsWith('kimi-file://')) { - parts.push(part); - continue; - } - parts.push({ - ...part, - imageUrl: { - ...part.imageUrl, - url: `data:${snapshot.mime};base64,${Buffer.from(snapshot.bytes).toString('base64')}`, - }, - }); - } - - return { - ...extraction, - parts, - // The new session's store no longer contains these ids. The rebuilt parts - // carry their own bytes, so keeping stale ids would break thumbnail and - // later cleanup lookups. - imageAttachmentIds: [], }; } @@ -349,7 +121,6 @@ export interface MediaTagRewriteResult { hasMedia: boolean; imageAttachmentIds: number[]; videoAttachmentIds: number[]; - stagingPaths: string[]; } /** @@ -381,65 +152,39 @@ export function rewriteMediaPlaceholders( ): MediaTagRewriteResult { const imageAttachmentIds: number[] = []; const videoAttachmentIds: number[] = []; - const stagingPaths: string[] = []; let cursor = 0; let out = ''; - try { - PLACEHOLDER_REGEX.lastIndex = 0; - let match: RegExpExecArray | null; - while ((match = PLACEHOLDER_REGEX.exec(text)) !== null) { - const [literal, kind, idStr] = match; - if (kind !== 'image' && kind !== 'video') continue; - if (idStr === undefined) continue; - const id = Number.parseInt(idStr, 10); - const attachment = store.get(id); - if (attachment === undefined) continue; // stale / user-typed — leave as text - if (attachment.kind !== kind) continue; - out += text.slice(cursor, match.index); - if (attachment.kind === 'video') { - const path = materializeVideoToCache(attachment, style === 'plain'); - stagingPaths.push(path); - out += - style === 'plain' - ? formatMediaReference('video', path) - : buildMediaPathTag('video', path); - videoAttachmentIds.push(id); - } else { - const path = materializeImageToCache(attachment); - stagingPaths.push(path); - out += - style === 'plain' - ? formatMediaReference('image', path) - : buildMediaPathTag('image', path); - imageAttachmentIds.push(id); - } - cursor = match.index + literal.length; + PLACEHOLDER_REGEX.lastIndex = 0; + let match: RegExpExecArray | null; + while ((match = PLACEHOLDER_REGEX.exec(text)) !== null) { + const [literal, kind, idStr] = match; + if (kind !== 'image' && kind !== 'video') continue; + if (idStr === undefined) continue; + const id = Number.parseInt(idStr, 10); + const attachment = store.get(id); + if (attachment === undefined) continue; // stale / user-typed — leave as text + if (attachment.kind !== kind) continue; + out += text.slice(cursor, match.index); + if (attachment.kind === 'video') { + const path = materializeVideoToCache(attachment, style === 'plain'); + out += style === 'plain' ? formatMediaReference('video', path) : formatMediaTag('video', path); + videoAttachmentIds.push(id); + } else { + const path = materializeImageToCache(attachment); + out += style === 'plain' ? formatMediaReference('image', path) : formatMediaTag('image', path); + imageAttachmentIds.push(id); } - - const hasMedia = imageAttachmentIds.length + videoAttachmentIds.length > 0; - store.retainFileIds(imageAttachmentIds); - return { - text: hasMedia ? out + text.slice(cursor) : text, - hasMedia, - imageAttachmentIds, - videoAttachmentIds, - stagingPaths, - }; - } catch (error) { - cleanupStagingPaths(stagingPaths); - throw error; + cursor = match.index + literal.length; } -} -function cleanupStagingPaths(paths: readonly string[]): void { - for (const path of paths) { - try { - unlinkSync(path); - } catch { - // Best effort: a failed copy may not have created the target. - } - } + const hasMedia = imageAttachmentIds.length + videoAttachmentIds.length > 0; + return { + text: hasMedia ? out + text.slice(cursor) : text, + hasMedia, + imageAttachmentIds, + videoAttachmentIds, + }; } function pushText(parts: PromptPart[], segment: string): void { @@ -456,7 +201,7 @@ function pushText(parts: PromptPart[], segment: string): void { parts.push({ type: 'text', text: segment }); } -function imagePartForAttachment(att: ImageAttachment): Extract<PromptPart, { type: 'image_url' }> { +function imagePartForAttachment(att: ImageAttachment): PromptPart { const base64 = Buffer.from(att.bytes).toString('base64'); return { type: 'image_url', @@ -465,56 +210,17 @@ function imagePartForAttachment(att: ImageAttachment): Extract<PromptPart, { typ } /** - * Is this image part still what the attachment holds? Extraction encodes the - * attachment as of extraction time; a paste whose background ingestion - * (compression/daemon upload) landed afterwards mutated it, leaving the part - * carrying the pre-compression form — which no caption may describe. + * A `video_url` prompt part pointing at a cache copy by `file://` url. The v1 + * engine resolves the local reference in-turn (upload → `ms://`, or degrade to + * a `<video path>` tag) before it reaches the model or the persisted history. */ -function imagePartMatchesAttachment( - part: Extract<PromptPart, { type: 'image_url' }>, - attachment: ImageAttachment, -): boolean { - const url = part.imageUrl.url; - if (url.startsWith('kimi-file://')) { - return attachment.fileId !== undefined && url === buildDaemonFileUrl(attachment.fileId); - } - return url === imagePartForAttachment(attachment).imageUrl.url; +function videoPartForCachePath(cachePath: string): PromptPart { + return { + type: 'video_url', + videoUrl: { url: pathToFileURL(cachePath).href }, + }; } -/** - * A `video_url` prompt part referencing the paste's daemon upload by a bare - * `kimi-file://` url — the engine's prompt intake materializes the session - * copy before the part reaches the model or the persisted history. Throws - * when the upload is unusable: video bytes have no inline fallback, so the - * submission is refused with an actionable message instead. - */ -function videoPartForAttachment(att: VideoAttachment): PromptPart { - const fileId = att.fileId; - const expired = - att.fileExpiresAt !== undefined && - att.fileExpiresAt - Date.now() <= MEDIA_FILE_REF_MIN_REMAINING_MS; - if (fileId !== undefined && !expired) { - return { - type: 'video_url', - videoUrl: { url: buildDaemonFileUrl(fileId) }, - }; - } - if (att.pending !== undefined) { - throw new Error(`Video "${att.label}" is still uploading; try again in a moment.`); - } - throw new Error( - expired - ? `Video "${att.label}" expired before it was sent; paste it again.` - : `Video "${att.label}" could not be uploaded; paste it again.`, - ); -} - -/** - * Copy a pasted video into the shared cache for the slash-command args - * channel (`rewriteMediaPlaceholders`): command args are plain text, so the - * model reaches the video through `ReadMediaFile` on the cache copy — the - * prompt-part channel never stages one (see `videoPartForAttachment`). - */ function materializeVideoToCache(att: VideoAttachment, escapeProofName = false): string { const cacheDir = getCacheDir(); mkdirSync(cacheDir, { recursive: true }); @@ -536,177 +242,39 @@ const IMAGE_MIME_EXTENSION: Readonly<Record<string, string>> = { 'image/tiff': 'tif', }; -/** - * File-extension hint for an image MIME (`image/png` → `png`). The real - * format is always sniffed from the bytes, so this only names files (cache - * copies, daemon upload labels). - */ -export function imageExtensionForMime(mime: string): string { - return IMAGE_MIME_EXTENSION[mime.trim().toLowerCase()] ?? 'img'; -} - function materializeImageToCache(att: ImageAttachment): string { const cacheDir = getCacheDir(); mkdirSync(cacheDir, { recursive: true }); // ReadMediaFile sniffs the real format from the bytes, so the extension // only needs to be a reasonable hint. - const target = join(cacheDir, `${randomUUID()}.${imageExtensionForMime(att.mime)}`); + const ext = IMAGE_MIME_EXTENSION[att.mime.trim().toLowerCase()] ?? 'img'; + const target = join(cacheDir, `${randomUUID()}.${ext}`); writeFileSync(target, att.bytes); return target; } -/** Opening every compression caption starts with (see buildImageCompressionCaption). */ -const CAPTION_OPENING = '<system>Image compressed to fit model limits:'; - -/** - * The session-owned originals store for compression captions, when the - * session's dir is known; undefined falls back to the shared temp dir. - */ -export function originalsDirForSession(session: Session | undefined): string | undefined { - const sessionDir = session?.summary?.sessionDir; - return sessionDir === undefined ? undefined : sessionMediaOriginalsDir(sessionDir); +function captionForCompressedImage(att: ImageAttachment): string { + const original = att.original; + if (original === undefined) return ''; + return buildImageCompressionCaption({ + original: { + width: original.width, + height: original.height, + byteLength: original.byteLength, + mimeType: original.mime, + }, + final: { + width: att.width, + height: att.height, + byteLength: att.bytes.length, + mimeType: att.mime, + }, + originalPath: original.path, + }); } -/** - * Author a compression caption before every referenced image whose paste-time - * compression shrank the bytes, persisting not-yet-persisted originals into - * `originalsDir` (the session's media-originals dir; the shared temp-dir - * fallback when undefined) so the caption points at a real readback path. - * - * Extraction deliberately does not do this: it can run before the session - * exists (first submit creates it lazily), and the original belongs with the - * session — owned by it, cleaned up with it, immune to OS temp reaping. The - * dispatch paths call this once the session is known. Synchronous because - * those paths cannot await; the write is a single small file, same as the - * cache copies extraction itself stages. Idempotent: an image already - * preceded by a compression caption gets it refreshed in place, so a - * re-resolved part list never grows a duplicate. - */ -export function resolveOriginalCaptions( - parts: readonly PromptPart[], - imageAttachmentIds: readonly number[], - store: ImageAttachmentStore, - originalsDir: string | undefined, -): PromptPart[] { - let imageIndex = 0; - let changed = false; - const out: PromptPart[] = []; - for (const part of parts) { - if (part.type !== 'image_url') { - out.push(part); - continue; - } - const attachmentId = imageAttachmentIds[imageIndex++]; - const attachment = attachmentId === undefined ? undefined : store.get(attachmentId); - if (attachment?.kind !== 'image' || attachment.original === undefined) { - out.push(part); - continue; - } - // The part was encoded from the attachment at extraction; a paste whose - // background ingestion landed afterwards mutated it (compressed bytes, - // daemon file id), leaving the part carrying the pre-compression form. - // Caption only when the two still agree — otherwise the caption would - // describe an image the model did not receive. - if (!imagePartMatchesAttachment(part, attachment)) { - out.push(part); - continue; - } - const original = attachment.original; - if (original.path === undefined && original.bytes !== undefined) { - // A persistence failure (unwritable dir, full disk) leaves the path - // unset — and the bytes retained — so a later dispatch retries; this - // dispatch captions without a readback path. - const path = persistOriginalImageSync(original.bytes, original.mime, originalsDir); - if (path !== null) store.setOriginalPath(attachment.id, path); - } - const caption = buildImageCompressionCaption({ - original: { - width: original.width, - height: original.height, - byteLength: original.byteLength, - mimeType: original.mime, - }, - final: { - width: attachment.width, - height: attachment.height, - byteLength: attachment.bytes.length, - mimeType: attachment.mime, - }, - originalPath: original.path, - }); - const previous = out.at(-1); - if (previous?.type === 'text' && previous.text.startsWith(CAPTION_OPENING)) { - out[out.length - 1] = { type: 'text', text: caption }; - } else { - out.push({ type: 'text', text: caption }); - } - changed = true; - out.push(part); - } - return changed ? out : [...parts]; -} - -/** - * Synchronous twin of the engine's `persistOriginalImage` — same - * content-addressed naming and the same size-capped eviction: the dispatch - * paths that resolve captions cannot await. Exported for tests; production - * callers go through `resolveOriginalCaptions` / `makeExtractionResendable`. - */ -export function persistOriginalImageSync( - bytes: Uint8Array, - mime: string, - dir: string | undefined, - maxTotalBytes = DEFAULT_MAX_TOTAL_BYTES, -): string | null { - if (bytes.length === 0) return null; - try { - const targetDir = dir ?? originalImageTempDir(); - const hash = createHash('sha256').update(bytes).digest('hex').slice(0, 32); - const target = join(targetDir, `${hash}.${imageExtensionForMime(mime)}`); - mkdirSync(targetDir, { recursive: true }); - const existing = statSync(target, { throwIfNoEntry: false }); - // Content-addressed: an existing entry with the right size IS this image. - if (existing === undefined || existing.size !== bytes.length) { - writeFileSync(target, bytes); - } - sweepCacheSync(targetDir, maxTotalBytes); - // The just-written file may itself have been evicted by the sweep when a - // single original exceeds the cap; report persistence honestly. - return statSync(target, { throwIfNoEntry: false }) === undefined ? null : target; - } catch { - return null; - } -} - -/** Per-store ceiling; mirrors the engine originals store. */ -const DEFAULT_MAX_TOTAL_BYTES = 1024 * 1024 * 1024; // 1 GiB - -/** Evict oldest files (by mtime) until the store fits `maxTotalBytes`. */ -function sweepCacheSync(dir: string, maxTotalBytes: number): void { - const entries: { path: string; size: number; mtimeMs: number }[] = []; - for (const name of readdirSync(dir)) { - const path = join(dir, name); - const info = statSync(path, { throwIfNoEntry: false }); - if (info === undefined || !info.isFile()) continue; - entries.push({ path, size: info.size, mtimeMs: info.mtimeMs }); - } - let total = entries.reduce((sum, entry) => sum + entry.size, 0); - if (total <= maxTotalBytes) return; - entries.sort((a, b) => a.mtimeMs - b.mtimeMs); - for (const entry of entries) { - if (total <= maxTotalBytes) break; - try { - unlinkSync(entry.path); - total -= entry.size; - } catch { - // Best effort, mirroring the async twin. - } - } -} - -/** Mirrors agent-core's `originalImageCacheDir` (not re-exported through the SDK). */ -function originalImageTempDir(): string { - return join(tmpdir(), 'kimi-code-original-images'); +function formatMediaTag(tag: 'image' | 'video', path: string): string { + return `<${tag} path="${escapeAttribute(path)}"></${tag}>`; } /** @@ -718,3 +286,11 @@ function originalImageTempDir(): string { function formatMediaReference(kind: 'image' | 'video', path: string): string { return `Attached ${kind} file: ${path} (open it with ReadMediaFile)`; } + +function escapeAttribute(value: string): string { + return value + .replaceAll('&', '&') + .replaceAll('"', '"') + .replaceAll('<', '<') + .replaceAll('>', '>'); +} diff --git a/apps/kimi-code/src/tui/utils/inline-skill-tokens.ts b/apps/kimi-code/src/tui/utils/inline-skill-tokens.ts deleted file mode 100644 index 5444304a9..000000000 --- a/apps/kimi-code/src/tui/utils/inline-skill-tokens.ts +++ /dev/null @@ -1,97 +0,0 @@ -/** - * Scanner for inline skill `/tokens` inside a prompt. - * - * Dispatch, editor highlighting, and autocomplete share this so all three - * agree on what counts as an inline skill reference: a `/name` token whose `/` - * is preceded by whitespace (space, tab, or newline), with no internal `/`. - * The leading slash-command area at the very start of the input is handled by - * the regular slash-command path and is skipped here by default. - */ - -import type { InlineSkillActivation } from '../types'; - -export interface InlineSkillToken { - readonly commandName: string; - readonly start: number; - readonly end: number; -} - -export interface FindInlineSkillTokensOptions { - /** Decide whether a syntactically valid token names a known skill. */ - readonly isKnownSkill: (commandName: string) => boolean; - /** Include tokens with an empty command name (a bare trailing `/`). */ - readonly allowEmpty?: boolean; - /** Also treat a `/` at the very start of the input as a token. */ - readonly includeLeading?: boolean; -} - -const WHITESPACE = /\s/; - -export function findInlineSkillTokens( - text: string, - options: FindInlineSkillTokensOptions, -): InlineSkillToken[] { - const tokens: InlineSkillToken[] = []; - - let searchStart = 0; - if (text.startsWith('/') && options.includeLeading !== true) { - const firstWhitespace = text.search(WHITESPACE); - searchStart = firstWhitespace === -1 ? text.length : firstWhitespace + 1; - } - - for (let i = searchStart; i < text.length; i++) { - if (text[i] !== '/') continue; - - const isLeadingSlash = i === 0 && options.includeLeading === true; - const charBefore = i > 0 ? text[i - 1] : undefined; - if (!isLeadingSlash && (charBefore === undefined || !WHITESPACE.test(charBefore))) continue; - - let end = i + 1; - while (end < text.length && !WHITESPACE.test(text[end] ?? '')) { - end++; - } - - const commandName = text.slice(i + 1, end); - if (commandName.includes('/')) continue; - if (commandName.length === 0 && options.allowEmpty !== true) continue; - if (!options.isKnownSkill(commandName)) continue; - - tokens.push({ commandName, start: i, end }); - } - - return tokens; -} - -export interface ExtractInlineSkillActivationsOptions { - /** Also treat a `/` at the very start of the input as a skill token. */ - readonly includeLeading?: boolean; -} - -/** - * Resolve the skill tokens of `text` through `skillCommandMap` (command name → - * skill name, with the same `skill:` prefix fallback as the leading-command - * path) and return the deduplicated activations in first-occurrence order. - * Unknown tokens, paths, URLs, and fractions are ignored. - */ -export function extractInlineSkillActivations( - text: string, - skillCommandMap: ReadonlyMap<string, string>, - options?: ExtractInlineSkillActivationsOptions, -): InlineSkillActivation[] { - const tokens = findInlineSkillTokens(text, { - isKnownSkill: (commandName) => - skillCommandMap.has(commandName) || skillCommandMap.has(`skill:${commandName}`), - includeLeading: options?.includeLeading, - }); - - const seen = new Set<string>(); - const activations: InlineSkillActivation[] = []; - for (const token of tokens) { - const skillName = - skillCommandMap.get(token.commandName) ?? skillCommandMap.get(`skill:${token.commandName}`); - if (skillName === undefined || seen.has(skillName)) continue; - seen.add(skillName); - activations.push({ skillName }); - } - return activations; -} diff --git a/apps/kimi-code/src/tui/utils/markdown-options.ts b/apps/kimi-code/src/tui/utils/markdown-options.ts deleted file mode 100644 index d765e599b..000000000 --- a/apps/kimi-code/src/tui/utils/markdown-options.ts +++ /dev/null @@ -1,21 +0,0 @@ -/** - * Shared Markdown behavior options (distinct from the visual theme). - * - * Holds the process-wide LaTeX toggle from tui.toml so transcript components - * don't each need the config threaded through construction. Mirrors the - * render-cache toggle pattern (see utils/render-cache.ts). - */ - -import type { MarkdownOptions } from '@moonshot-ai/pi-tui'; - -// Default on, matching upstream pi-tui; overridden from tui.toml at startup -// and on /reload. -let renderLatex = true; - -export function setMarkdownRenderLatex(value: boolean): void { - renderLatex = value; -} - -export function createMarkdownOptions(): MarkdownOptions { - return { renderLatex }; -} diff --git a/apps/kimi-code/src/tui/utils/media-url.ts b/apps/kimi-code/src/tui/utils/media-url.ts index 14bc4eba8..f04edeb29 100644 --- a/apps/kimi-code/src/tui/utils/media-url.ts +++ b/apps/kimi-code/src/tui/utils/media-url.ts @@ -1,5 +1,3 @@ -import { isDaemonFileUrl } from '@moonshot-ai/kimi-code-sdk'; - export type MediaUrlKind = 'audio' | 'image' | 'video'; export function mediaUrlPartToText(kind: MediaUrlKind, url: string): string { @@ -8,10 +6,6 @@ export function mediaUrlPartToText(kind: MediaUrlKind, url: string): string { const size = summary.bytes !== undefined ? `, ${formatByteSize(summary.bytes)}` : ''; return `[${kind} ${summary.mime}${size}]`; } - // An internal daemon file reference (`kimi-file://…?path=…`) never renders - // its wire form: the scheme resolves nowhere for the user and the query - // carries the materialization path. Render the bare placeholder instead. - if (isDaemonFileUrl(url)) return `[${kind}]`; return `<${kind} url="${escapeAttribute(url)}">`; } diff --git a/apps/kimi-code/src/tui/utils/message-replay.ts b/apps/kimi-code/src/tui/utils/message-replay.ts index 1ef5c544c..c068ac106 100644 --- a/apps/kimi-code/src/tui/utils/message-replay.ts +++ b/apps/kimi-code/src/tui/utils/message-replay.ts @@ -24,16 +24,6 @@ import { nextTranscriptId } from './transcript-id'; export const REPLAY_TURN_LIMIT = 10; -/** - * Resume fetches one extra turn of records: the SDK trims the replay to the - * requested limit before returning it, and a trim that lands between a - * bundled prompt and the hook results recorded immediately before it would - * make them unrecoverable. The extra margin lets the TUI-side limiter - * (session-replay's preserveBundleHookResults) do the final cut without - * losing them. - */ -export const REPLAY_FETCH_TURN_LIMIT = REPLAY_TURN_LIMIT + 1; - export interface ReplayRenderContext { turnIndex: number; stepIndex: number; @@ -54,8 +44,6 @@ export interface SkillActivationProjection { readonly skillName: string; readonly skillArgs?: string; readonly trigger: SkillActivationTrigger; - /** The activation rode a bundled prompt message, not a standalone one. */ - readonly bundled?: boolean; } export interface PluginCommandProjection { @@ -230,10 +218,6 @@ export function toolResultOutput(content: readonly ContentPart[]): string { } export function contentPartsToText(content: readonly ContentPart[]): string { - // A daemon-ref media part is self-contained and renders as a bare - // `[image]`/`[video]` placeholder downstream — neither the materialization - // path nor the internal `kimi-file://` url may surface as user text. A - // standalone `<media path>` tag is user text and stays verbatim. return content.map(contentPartToText).join(''); } @@ -271,48 +255,6 @@ export function skillActivationFromOrigin( }; } -/** - * The v2 engine bundles a prompt's inline skill activations into the prompt - * message itself: the rendered skill blocks precede the caller's parts in - * the content, and this origin field carries every activation's metadata so - * replay can rebuild the per-skill cards from the single message. The SDK's - * origin union is typed from the v1 engine, which never sets the field, so - * read it structurally here instead of widening the deprecated v1 package's - * types. - */ -export function bundledSkillsFromOrigin( - origin: PromptOrigin | undefined, -): readonly SkillActivationProjection[] { - if (origin?.kind !== 'user') return []; - const activations = ( - origin as { - readonly skillActivations?: readonly { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - }[]; - } - ).skillActivations; - if (activations === undefined) return []; - return activations.map((activation) => ({ - activationId: activation.activationId, - skillName: activation.skillName, - skillArgs: activation.skillArgs, - trigger: 'user-slash' as const, - bundled: true, - })); -} - -/** - * Content parts the caller actually typed: the engine prepends one rendered - * text part per bundled skill, so the caller's own parts start right after - * them. - */ -export function stripBundledSkillParts(message: ContextMessage): readonly ContentPart[] { - const bundledCount = bundledSkillsFromOrigin(message.origin).length; - return bundledCount === 0 ? message.content : message.content.slice(bundledCount); -} - export function pluginCommandFromOrigin( origin: PromptOrigin | undefined, ): PluginCommandProjection | undefined { diff --git a/apps/kimi-code/src/tui/utils/osc133.ts b/apps/kimi-code/src/tui/utils/osc133.ts deleted file mode 100644 index 3273fe15a..000000000 --- a/apps/kimi-code/src/tui/utils/osc133.ts +++ /dev/null @@ -1,34 +0,0 @@ -/** - * OSC 133 zone marking for transcript messages. The fullscreen renderer - * anchors previous/next-prompt navigation on lines whose first bytes are an - * OSC 133;A zone marker (and strips the markers at paint), so the marks must - * survive every container between the message component and the ScrollView. - */ - -import { - OSC133_ZONE_END, - OSC133_ZONE_FINAL, - OSC133_ZONE_START, -} from '#/tui/constant/rendering'; - -// One or more consecutive A/B/C zone markers anchored at the line start. -const OSC133_ZONE_PREFIX = /^(?:\x1b\]133;[ABC](?:\x07|\x1b\\))+/; - -/** - * Mark a message's rendered lines as a semantic zone: A on the first line, - * B+C on the last. Mutates and returns the given array — call it on freshly - * built lines before handing them to a render cache (cached lines then - * already carry the marks, so they are never marked twice). - */ -export function markOsc133Zone(lines: string[]): string[] { - if (lines.length === 0) return lines; - lines[0] = OSC133_ZONE_START + lines[0]!; - lines[lines.length - 1] = OSC133_ZONE_END + OSC133_ZONE_FINAL + lines[lines.length - 1]!; - return lines; -} - -/** Prefix a rendered line while keeping any leading OSC 133 zone at byte 0. */ -export function prefixPreservingOsc133Zone(line: string, prefix: string): string { - const zone = OSC133_ZONE_PREFIX.exec(line)?.[0]; - return zone === undefined ? prefix + line : zone + prefix + line.slice(zone.length); -} diff --git a/apps/kimi-code/src/tui/utils/plugin-source-label.ts b/apps/kimi-code/src/tui/utils/plugin-source-label.ts index e5d8ee41a..370ab0a94 100644 --- a/apps/kimi-code/src/tui/utils/plugin-source-label.ts +++ b/apps/kimi-code/src/tui/utils/plugin-source-label.ts @@ -6,13 +6,6 @@ export const THIRD_PARTY_BADGE = 'third-party'; export type PluginTrustLabel = 'official' | 'curated' | 'third-party'; -// Trusted plugin hosts come in .com / .ai region pairs: code.kimi.* is the -// per-region marketplace CDN (cdnBase), cdn.kimi.* the content CDN. Both -// families are trusted regardless of the current region — a zip served by -// either deployment is still an official build. -const CODE_CDN_HOSTS = new Set(['code.kimi.com', 'code.kimi.ai']); -const CONTENT_CDN_HOSTS = new Set(['cdn.kimi.com', 'cdn.kimi.ai']); - /** * Human-readable provenance label for a plugin, suitable for inline display * in `/plugins` overviews and lists. @@ -47,7 +40,7 @@ export function pluginTrustLabel(plugin: PluginSummary): PluginTrustLabel { } if ( url.protocol === 'https:' && - CODE_CDN_HOSTS.has(url.hostname) && + url.hostname === 'code.kimi.com' && url.pathname.startsWith('/kimi-code/plugins/curated/') ) { return 'curated'; @@ -91,9 +84,9 @@ export function isOfficialPluginInstall(plugin: PluginSummary): boolean { function isOfficialPluginUrl(url: URL): boolean { if (url.protocol !== 'https:') return false; return ( - (CODE_CDN_HOSTS.has(url.hostname) && + (url.hostname === 'code.kimi.com' && url.pathname.startsWith('/kimi-code/plugins/official/')) || - (CONTENT_CDN_HOSTS.has(url.hostname) && + (url.hostname === 'cdn.kimi.com' && (url.pathname.startsWith('/kimi-computer-use/') || url.pathname.startsWith('/kimi-computer-use-windows/'))) ); diff --git a/apps/kimi-code/src/tui/utils/screen-takeover.ts b/apps/kimi-code/src/tui/utils/screen-takeover.ts deleted file mode 100644 index 05107a84e..000000000 --- a/apps/kimi-code/src/tui/utils/screen-takeover.ts +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Mode-aware full-screen viewer takeover. - * - * In regular mode a viewer is mounted by snapshotting the root container's - * children and swapping the viewer in. In fullscreen (alternate screen) the - * root children are not painted at all — the layout root is — so the viewer - * must become the layout root instead. Both shapes restore cleanly and nest - * (a viewer opened from another viewer). - */ - -import type { Component, TUI } from '@moonshot-ai/pi-tui'; -import { TuiAltScreen } from '@moonshot-ai/pi-tui'; - -/** Restore data for a screen takeover; opaque to callers. */ -export type ScreenTakeover = - | { readonly kind: 'children'; readonly children: readonly Component[] } - | { readonly kind: 'root'; readonly root: Component | undefined }; - -export function beginScreenTakeover(ui: TUI, viewer: Component): ScreenTakeover { - if (ui instanceof TuiAltScreen) { - const root = ui.getLayoutRoot(); - ui.setLayoutRoot(viewer); - return { kind: 'root', root }; - } - const children = [...ui.children]; - ui.clear(); - ui.addChild(viewer); - return { kind: 'children', children }; -} - -export function endScreenTakeover(ui: TUI, takeover: ScreenTakeover): void { - if (takeover.kind === 'root') { - if (ui instanceof TuiAltScreen) ui.setLayoutRoot(takeover.root); - return; - } - ui.clear(); - for (const child of takeover.children) ui.addChild(child); -} diff --git a/apps/kimi-code/src/tui/utils/steer-input.ts b/apps/kimi-code/src/tui/utils/steer-input.ts deleted file mode 100644 index d69c999d8..000000000 --- a/apps/kimi-code/src/tui/utils/steer-input.ts +++ /dev/null @@ -1,56 +0,0 @@ -/** - * Steer-input composition for `session.steer`: flattens queued items (and the - * editor draft) into one payload — the historical `'\n\n'`-joined string when - * nothing carries media, or a merged part list when any item has extracted - * media parts (queued image messages, or the editor draft after placeholder - * extraction). Media parts are self-contained daemon references; no machine - * `<media path>` tag is authored, so text parts always merge freely. - */ - -import type { PromptPart } from '@moonshot-ai/kimi-code-sdk'; - -import type { SteerInputItem } from '../types'; - -/** - * Flatten steer items into the payload `session.steer` expects. - * - * Items are separated by the historical `'\n\n'`, which merges into the - * adjacent text part. The one exception is two touching media parts: a - * standalone `{type:'text',text:'\n\n'}` between them would be rejected - * by `normalizePromptInput` as an empty text part, so the separator is - * dropped there (media parts are self-delimiting anyway). - */ -export function combineSteerInput(items: readonly SteerInputItem[]): string | PromptPart[] { - const hasMedia = items.some((item) => item.parts !== undefined && item.parts.length > 0); - if (!hasMedia) return items.map((item) => item.text).join('\n\n'); - const parts: PromptPart[] = []; - for (const item of items) { - const first = item.parts?.[0]; - const startsWithMedia = first !== undefined && first.type !== 'text'; - const lastIsMedia = parts.length > 0 && parts.at(-1)?.type !== 'text'; - if (parts.length > 0 && !(lastIsMedia && startsWithMedia)) { - appendSteerText(parts, '\n\n'); - } - if (item.parts !== undefined && item.parts.length > 0) { - for (const part of item.parts) { - if (part.type !== 'text') { - parts.push(part); - continue; - } - appendSteerText(parts, part.text); - } - } else { - appendSteerText(parts, item.text); - } - } - return parts; -} - -function appendSteerText(parts: PromptPart[], text: string): void { - const last = parts.at(-1); - if (last?.type === 'text') { - parts[parts.length - 1] = { type: 'text', text: last.text + text }; - return; - } - parts.push({ type: 'text', text }); -} diff --git a/apps/kimi-code/src/tui/utils/thinking-config.ts b/apps/kimi-code/src/tui/utils/thinking-config.ts index 79dff4323..da3ea1360 100644 --- a/apps/kimi-code/src/tui/utils/thinking-config.ts +++ b/apps/kimi-code/src/tui/utils/thinking-config.ts @@ -1,4 +1,4 @@ -import type { ModelAlias, ThinkingEffort } from '@moonshot-ai/kimi-code-sdk'; +import type { ThinkingEffort } from '@moonshot-ai/kimi-code-sdk'; /** Whether a thinking effort represents "thinking enabled" (anything but 'off'). */ export function isThinkingOn(effort: ThinkingEffort): boolean { @@ -11,37 +11,24 @@ export function isThinkingOn(effort: ThinkingEffort): boolean { * on-signal rather than a declared effort, so it only persists `enabled` — * boolean models resolve back to `'on'` at runtime via * `defaultThinkingEffortFor`. A concrete effort persists as the global - * default, EXCEPT when it ranks above the model's effective default - * effort: `support_efforts` is ordered by strength (the same assumption - * the `middleOf` default-effort resolution makes), and a pick more - * expensive than the default stays session-only and records just - * `enabled`, so it never becomes the global default for every new - * session. The default here is the effective model's, however it arose — - * declared via the catalog or `[models.*.overrides]`, or synthesized by - * the protocol-profile inference (`withAnthropicProfile` resolves Claude - * models to 'high', so an 'xhigh' pick stays session-only there). When - * the effective model carries no default effort at all, its highest - * declared level stays session-only (the historical rule). Undeclared - * values persist as-is — the configured provider validates them. + * default, EXCEPT the model's highest declared level — the last entry of + * `support_efforts` (the list is ordered by strength, the same assumption + * the `middleOf` default-effort resolution makes) — which is session-only + * and records just `enabled`, so the most expensive tier never becomes the + * global default for every new session. When the model's levels are unknown + * the concrete effort is persisted as-is. */ export function thinkingEffortToConfig( effort: ThinkingEffort, - model?: Pick<ModelAlias, 'supportEfforts' | 'defaultEffort'>, + supportEfforts?: readonly string[], ): { enabled: boolean; effort?: string; } { if (effort === 'off') return { enabled: false }; if (effort === 'on') return { enabled: true }; - const efforts = model?.supportEfforts; - if (efforts !== undefined && efforts.includes(effort)) { - const declared = model?.defaultEffort; - const ceiling = - declared !== undefined && efforts.includes(declared) - ? efforts.indexOf(declared) - : efforts.length - 2; - if (efforts.indexOf(effort) > ceiling) return { enabled: true }; - } + const top = supportEfforts?.at(-1); + if (top !== undefined && effort === top) return { enabled: true }; return { enabled: true, effort }; } diff --git a/apps/kimi-code/src/utils/client-configs.ts b/apps/kimi-code/src/utils/client-configs.ts index b1955d855..02156aabf 100644 --- a/apps/kimi-code/src/utils/client-configs.ts +++ b/apps/kimi-code/src/utils/client-configs.ts @@ -1,14 +1,14 @@ import { join } from 'node:path'; +import { kimiCodeBaseUrl } from '@moonshot-ai/kimi-code-oauth'; import { z } from 'zod'; import { getCacheDir } from '#/utils/paths'; import { readJsonFile, writeJsonFile } from '#/utils/persistence'; -import { currentKimiProfile, currentKimiRegion } from '#/utils/region'; /** * Generic client for the public client-configs endpoint: - * `POST {baseUrl}/client_configs {"name": "<config name>"}` returns + * `POST {kimiCodeBaseUrl}/client_configs {"name": "<config name>"}` returns * `{ name, config: <payload> }`, where the payload shape is config-specific * and validated by the caller-supplied schema. * @@ -25,19 +25,6 @@ const CLIENT_CONFIGS_PATH = '/client_configs'; const CONFIG_CACHE_TTL_MS = 24 * 60 * 60 * 1000; const FETCH_TIMEOUT_MS = 5000; -/** The endpoint's API base: the env override keeps winning (custom/internal - envs); otherwise the active region profile, so a global login's token is - not sent to the mainland-China deployment. */ -function clientConfigsBaseUrl(): string { - return (process.env['KIMI_CODE_BASE_URL'] ?? currentKimiProfile().baseUrl).replace(/\/+$/, ''); -} - -/** Cache entries are partitioned by region so a login switch never serves - the other deployment's cached config. */ -function cacheKeyFor(name: string): string { - return `${currentKimiRegion()}:${name}`; -} - export interface ClientConfigFetchOptions { /** Managed OAuth token; sent as Bearer when present. The endpoint is * public, so anonymous fetches work too. */ @@ -62,7 +49,7 @@ const cacheFileEnvelopeSchema = z.object({ function cacheFileFor(name: string, options: ClientConfigFetchOptions): string | undefined { if (options.cacheFile === null) return undefined; if (options.cacheFile !== undefined) return options.cacheFile; - return join(getCacheDir(), 'client-configs', `${cacheKeyFor(name).replaceAll(/[^a-zA-Z0-9_-]/g, '_')}.json`); + return join(getCacheDir(), 'client-configs', `${name.replaceAll(/[^a-zA-Z0-9_-]/g, '_')}.json`); } /** Fresh disk entry, or undefined when missing/stale/invalid. */ @@ -109,8 +96,7 @@ export async function getClientConfig<S extends z.ZodType>( options: ClientConfigFetchOptions = {}, ): Promise<z.infer<S> | undefined> { const now = options.now ?? Date.now(); - const key = cacheKeyFor(name); - const hit = cache.get(key); + const hit = cache.get(name); if (hit !== undefined && now - hit.fetchedAt < CONFIG_CACHE_TTL_MS) { return hit.data as z.infer<S>; } @@ -120,13 +106,13 @@ export async function getClientConfig<S extends z.ZodType>( if (diskHit !== undefined) { // Warm the in-process layer with the original fetch time, so the entry // still expires a day after it was actually fetched. - cache.set(key, diskHit); + cache.set(name, diskHit); return diskHit.data; } } const data = await fetchClientConfig(name, schema, options); if (data === undefined) return undefined; - cache.set(key, { fetchedAt: now, data }); + cache.set(name, { fetchedAt: now, data }); if (file !== undefined) await writeDiskCache(file, data, now); return data; } @@ -150,7 +136,7 @@ export function peekClientConfig<S extends z.ZodType>( schema: S, now: number = Date.now(), ): z.infer<S> | undefined { - const hit = cache.get(cacheKeyFor(name)); + const hit = cache.get(name); if (hit === undefined || now - hit.fetchedAt >= CONFIG_CACHE_TTL_MS) return undefined; const parsed = schema.safeParse(hit.data); return parsed.success ? (parsed.data as z.infer<S>) : undefined; @@ -170,7 +156,7 @@ export async function fetchClientConfig<S extends z.ZodType>( headers['authorization'] = `Bearer ${options.accessToken}`; } try { - const response = await fetchFn(`${clientConfigsBaseUrl()}${CLIENT_CONFIGS_PATH}`, { + const response = await fetchFn(`${kimiCodeBaseUrl()}${CLIENT_CONFIGS_PATH}`, { method: 'POST', headers, body: JSON.stringify({ name }), @@ -196,6 +182,6 @@ export function resetClientConfigCache(name?: string): void { if (name === undefined) { cache.clear(); } else { - cache.delete(cacheKeyFor(name)); + cache.delete(name); } } diff --git a/apps/kimi-code/src/utils/paths.ts b/apps/kimi-code/src/utils/paths.ts index f9d595837..2127726cc 100644 --- a/apps/kimi-code/src/utils/paths.ts +++ b/apps/kimi-code/src/utils/paths.ts @@ -7,7 +7,7 @@ import { createHash } from 'node:crypto'; import { homedir } from 'node:os'; -import { dirname, join } from 'node:path'; +import { join } from 'node:path'; import { KIMI_CODE_BANNER_DIR_NAME, @@ -18,8 +18,6 @@ import { KIMI_CODE_HOME_ENV, KIMI_CODE_INPUT_HISTORY_DIR_NAME, KIMI_CODE_LOG_DIR_NAME, - KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME, - KIMI_CODE_NATIVE_STAGING_DIR_NAME, KIMI_CODE_PLUGIN_UPDATE_NOTICE_STATE_FILE_NAME, KIMI_CODE_UPDATE_INSTALL_LOCK_FILE_NAME, KIMI_CODE_UPDATE_INSTALL_STATE_FILE_NAME, @@ -101,24 +99,6 @@ export function getPluginUpdateNoticeStateFile(): string { ); } -/** - * Return the native staged-update directory: `<exe dir>/.staging/`. - * - * Anchored on the running executable (not `~/.kimi-code/bin`) because the - * Windows installer honors `KIMI_INSTALL_DIR`, and the swap's atomic renames - * require the staged binary to sit on the same volume as the exe. - */ -export function getNativeStagingDir(exePath: string): string { - return join(dirname(exePath), KIMI_CODE_NATIVE_STAGING_DIR_NAME); -} - -/** - * Return the staged-update metadata file: `<exe dir>/.staging/staged.json`. - */ -export function getNativeStagedStateFile(exePath: string): string { - return join(getNativeStagingDir(exePath), KIMI_CODE_NATIVE_STAGED_STATE_FILE_NAME); -} - /** * Return the banner display state file: `<dataDir>/cache/banner/state.json`. */ diff --git a/apps/kimi-code/src/utils/persistence.ts b/apps/kimi-code/src/utils/persistence.ts index 0b60e5109..a458ae02a 100644 --- a/apps/kimi-code/src/utils/persistence.ts +++ b/apps/kimi-code/src/utils/persistence.ts @@ -6,7 +6,7 @@ * these helpers. */ -import { appendFile, link, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises'; +import { appendFile, mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises'; import { basename, dirname, join } from 'node:path'; import type { z } from 'zod'; @@ -17,15 +17,6 @@ function isNotFound(error: unknown): boolean { ); } -/** - * Hard links need filesystem support: FAT/exFAT (and some network mounts) - * answer link() with ENOTSUP/ENOSYS/EPERM instead. - */ -function isHardLinkUnsupported(error: unknown): boolean { - const code = (error as { code?: string } | null)?.code; - return code === 'ENOTSUP' || code === 'ENOSYS' || code === 'EPERM'; -} - function assertNonConfigWrite(filePath: string): void { if (basename(filePath) === 'config.toml') { throw new Error( @@ -75,32 +66,6 @@ export async function writeJsonFile<T>( } } -/** - * Create `filePath` with `content` only while the path is still free — - * atomically, and throwing EEXIST when it is already taken. - * - * Primary primitive: hard-link a fully written temp file into place, so the - * destination is never observable in an empty/partial state. Filesystems - * without hard-link support (FAT/exFAT, some network mounts) fall back to an - * exclusive create + write — whose create→write gap IS observable, so readers - * of such files must grant young unparseable content a publish grace before - * treating it as corrupt (see the update install lock for an example). - */ -export async function createFileIfAbsent(filePath: string, content: string): Promise<void> { - assertNonConfigWrite(filePath); - await mkdir(dirname(filePath), { recursive: true }); - const tmpPath = tempPathFor(filePath); - await writeFile(tmpPath, content, { encoding: 'utf-8', mode: 0o600 }); - try { - await link(tmpPath, filePath); - } catch (error) { - if (!isHardLinkUnsupported(error)) throw error; - await writeFile(filePath, content, { encoding: 'utf-8', mode: 0o600, flag: 'wx' }); - } finally { - await unlink(tmpPath).catch(() => {}); - } -} - export async function readJsonlFile<T>( filePath: string, lineSchema: z.ZodType<T>, diff --git a/apps/kimi-code/src/utils/plugin-marketplace.ts b/apps/kimi-code/src/utils/plugin-marketplace.ts index bbc2dc673..2ad4caa89 100644 --- a/apps/kimi-code/src/utils/plugin-marketplace.ts +++ b/apps/kimi-code/src/utils/plugin-marketplace.ts @@ -1,41 +1,77 @@ -/** - * `#/utils/plugin-marketplace` — CLI-side wrapper over the shared plugin - * marketplace client/parser (`@moonshot-ai/agent-core-v2`, - * `app/plugin/marketplace`). The shared module owns catalog reading, the - * lenient entry normalization, source resolution, and version derivation; - * this wrapper adds only the CLI's configured-source resolution (option → - * env → production default), the source-checkout fallback for offline dev, - * and the caller-supplied built-in capability entry injection. - */ +import { readFile, stat } from 'node:fs/promises'; +import { homedir } from 'node:os'; +import { dirname, isAbsolute, join, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; -import { stat } from 'node:fs/promises'; -import { resolve } from 'node:path'; - -import { - parsePluginMarketplace, - readPluginMarketplace, - withBuiltInEntries, - withLatestVersions, - type MarketplaceLocation, - type PluginMarketplace, - type PluginMarketplaceEntry, -} from '@moonshot-ai/agent-core-v2/app/plugin/marketplace'; +import { gt, valid } from 'semver'; import { + KIMI_CODE_PLUGIN_MARKETPLACE_URL, KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV, - kimiCodePluginMarketplaceUrl, - MARKETPLACE_VERSION_LOOKUP_TIMEOUT_MS, } from '#/constant/app'; -export { - computeUpdateStatus, - PLUGIN_MARKETPLACE_TIERS, - withBuiltInEntries, - type PluginMarketplace, - type PluginMarketplaceEntry, - type PluginMarketplaceTier, - type MarketplaceUpdateStatus, -} from '@moonshot-ai/agent-core-v2/app/plugin/marketplace'; +export const PLUGIN_MARKETPLACE_TIERS = ['official', 'curated'] as const; + +export type PluginMarketplaceTier = (typeof PLUGIN_MARKETPLACE_TIERS)[number]; + +export interface PluginMarketplaceEntry { + readonly id: string; + readonly displayName: string; + readonly source: string; + readonly tier?: PluginMarketplaceTier; + readonly version?: string; + readonly description?: string; + readonly homepage?: string; + readonly keywords?: readonly string[]; + /** + * Internal provenance flag for client-injected built-in rows. The catalog + * parser builds entries field-by-field and never sets it, so a custom + * catalog cannot forge it (unlike the `capability:<id>` source string). + */ + readonly builtIn?: boolean; +} + +export interface PluginMarketplace { + readonly source: string; + readonly version?: string; + readonly plugins: readonly PluginMarketplaceEntry[]; +} + +export type PluginUpdateStatus = + | { readonly kind: 'not-installed' } + | { readonly kind: 'up-to-date'; readonly version?: string } + | { readonly kind: 'update'; readonly local: string; readonly latest: string }; + +/** + * Compare a marketplace entry's (latest) version against the locally installed + * version. Only reports `update` when both are valid semver and latest > local, + * so a stale or non-semver version never produces a spurious or downgrading prompt. + */ +export function computeUpdateStatus( + latest: string | undefined, + local: string | undefined, + installed: boolean, +): PluginUpdateStatus { + if (!installed) return { kind: 'not-installed' }; + if ( + latest !== undefined && + local !== undefined && + valid(latest) !== null && + valid(local) !== null && + gt(latest, local) + ) { + return { kind: 'update', local, latest }; + } + // Report only the actual installed version. When it is unknown, don't borrow the + // marketplace version — that would falsely claim "up to date" and hide future updates. + return { kind: 'up-to-date', version: local }; +} + +interface MarketplaceLocation { + readonly raw: string; + readonly kind: 'remote' | 'local'; + readonly resolved: string; +} export interface LoadPluginMarketplaceOptions { readonly workDir: string; @@ -47,67 +83,358 @@ export interface LoadPluginMarketplaceOptions { * Undefined means no injection. */ readonly builtInEntries?: readonly PluginMarketplaceEntry[]; - /** - * Skip the per-entry "latest GitHub release" lookups so the catalog can be - * rendered as soon as it is parsed; the caller resolves versions in the - * background via {@link withMarketplaceLatestVersions} and re-renders. - */ - readonly skipLatestVersions?: boolean; -} - -/** - * Second phase of the marketplace load: fill in `version` for entries that - * need a GitHub `releases/latest` lookup. Every lookup gets a hard timeout - * (MARKETPLACE_VERSION_LOOKUP_TIMEOUT_MS) and per-entry failures degrade to - * a missing version (badge-less row), so this never throws for network - * reasons and never blocks the first paint. - */ -export async function withMarketplaceLatestVersions( - marketplace: PluginMarketplace, - fetchImpl: typeof fetch = fetch, -): Promise<PluginMarketplace> { - const timedFetch: typeof fetch = (input, init) => - fetchImpl(input, { - ...init, - signal: AbortSignal.timeout(MARKETPLACE_VERSION_LOOKUP_TIMEOUT_MS), - }); - return withLatestVersions(marketplace, timedFetch); } export async function loadPluginMarketplace( options: LoadPluginMarketplaceOptions, ): Promise<PluginMarketplace> { const configuredSource = options.source ?? process.env[KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV]; - const source = configuredSource ?? kimiCodePluginMarketplaceUrl(); + const location = resolveMarketplaceLocation( + configuredSource ?? KIMI_CODE_PLUGIN_MARKETPLACE_URL, + options.workDir, + ); const fetchImpl = options.fetchImpl ?? fetch; - let read: { raw: string; location: MarketplaceLocation }; + let raw: string; try { - read = await readPluginMarketplace({ - source, - workDir: options.workDir, - fetchImpl, - sourceCheckoutLocation: - configuredSource === undefined ? getSourceCheckoutMarketplaceLocation : undefined, - }); + raw = await readMarketplaceText(location, fetchImpl); } catch (error) { - if (options.builtInEntries !== undefined) { - // The built-in entries do not come from the catalog — keep them - // visible when the catalog itself is unreachable. - return withBuiltInEntries({ source, plugins: [] }, options.builtInEntries); + const fallback = + configuredSource === undefined ? await getSourceCheckoutMarketplaceLocation() : undefined; + if (fallback === undefined) { + if (options.builtInEntries !== undefined) { + // The built-in entries do not come from the catalog — keep them + // visible when the catalog itself is unreachable. + return withBuiltInEntries({ source: location.resolved, plugins: [] }, options.builtInEntries); + } + throw error; } - throw error; + raw = await readMarketplaceText(fallback, fetchImpl); + const marketplace = await withLatestVersions(parsePluginMarketplace(raw, fallback), fetchImpl); + return options.builtInEntries !== undefined + ? withBuiltInEntries(marketplace, options.builtInEntries) + : marketplace; } - const marketplace = options.skipLatestVersions === true - ? parsePluginMarketplace(read.raw, read.location) - : await withLatestVersions(parsePluginMarketplace(read.raw, read.location), fetchImpl); + const marketplace = await withLatestVersions(parsePluginMarketplace(raw, location), fetchImpl); return options.builtInEntries !== undefined ? withBuiltInEntries(marketplace, options.builtInEntries) : marketplace; } +/** + * Built-in capability entries (kimi-cu, kimi-webbridge) are injected by the + * client instead of being served by the marketplace catalog, so their + * visibility is bound to the client version — older clients never see them. + * Same-id catalog rows are MASKED, not merged: what these ids mean stays + * decided by the client release. The catalog may contribute only its version + * so the built-in row can use the normal update badge while keeping the + * capability install route and client-owned copy. + */ +function withBuiltInEntries( + marketplace: PluginMarketplace, + builtIns: readonly PluginMarketplaceEntry[], +): PluginMarketplace { + const builtInIds = new Set(builtIns.map((entry) => entry.id)); + const catalogById = new Map(marketplace.plugins.map((entry) => [entry.id, entry])); + const catalog = marketplace.plugins.filter((entry) => !builtInIds.has(entry.id)); + const enrichedBuiltIns = builtIns.map((entry) => { + const version = catalogById.get(entry.id)?.version; + return version === undefined ? entry : { ...entry, version }; + }); + return { ...marketplace, plugins: [...catalog, ...enrichedBuiltIns] }; +} + +async function withLatestVersions( + marketplace: PluginMarketplace, + fetchImpl: typeof fetch, +): Promise<PluginMarketplace> { + const plugins = await Promise.all( + marketplace.plugins.map(async (entry) => { + if (entry.version !== undefined) return entry; + const latest = await resolveLatestGithubRelease(entry.source, fetchImpl); + return latest === undefined ? entry : { ...entry, version: latest }; + }), + ); + return { ...marketplace, plugins }; +} + +export function parsePluginMarketplace(raw: string, location: MarketplaceLocation): PluginMarketplace { + let parsed: unknown; + try { + parsed = JSON.parse(raw); + } catch (error) { + throw new Error(`Plugin marketplace is not valid JSON: ${formatParseError(error)}`, { + cause: error, + }); + } + + if (!isRecord(parsed)) { + throw new TypeError('Plugin marketplace must be an object.'); + } + const rawPlugins = parsed['plugins']; + if (!Array.isArray(rawPlugins)) { + throw new TypeError('Plugin marketplace must contain a "plugins" array.'); + } + + return { + source: location.resolved, + version: stringField(parsed, 'version'), + plugins: rawPlugins.map((entry, index) => parseMarketplaceEntry(entry, index, location)), + }; +} + +function resolveMarketplaceLocation(source: string, workDir: string): MarketplaceLocation { + const trimmed = source.trim(); + if (trimmed.length === 0) { + throw new Error(`${KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV} cannot be empty.`); + } + if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) { + return { raw: trimmed, kind: 'remote', resolved: trimmed }; + } + if (trimmed.startsWith('file://')) { + const path = fileURLToPath(trimmed); + return { raw: trimmed, kind: 'local', resolved: path }; + } + return { raw: trimmed, kind: 'local', resolved: resolveLocalPath(trimmed, workDir) }; +} + async function getSourceCheckoutMarketplaceLocation(): Promise<MarketplaceLocation | undefined> { - const marketplacePath = resolve(import.meta.dirname, '../../../../plugins/marketplace.json'); + const sourceDir = dirname(fileURLToPath(import.meta.url)); + const marketplacePath = resolve(sourceDir, '../../../../plugins/marketplace.json'); const info = await stat(marketplacePath).catch(() => undefined); if (info?.isFile() !== true) return undefined; return { raw: marketplacePath, kind: 'local', resolved: marketplacePath }; } + +async function readMarketplaceText( + location: MarketplaceLocation, + fetchImpl: typeof fetch, +): Promise<string> { + if (location.kind === 'local') { + return readFile(location.resolved, 'utf8'); + } + const response = await fetchImpl(location.resolved); + if (!response.ok) { + throw new Error(`Plugin marketplace returned HTTP ${response.status}`); + } + return response.text(); +} + +function parseMarketplaceEntry( + value: unknown, + index: number, + location: MarketplaceLocation, +): PluginMarketplaceEntry { + if (!isRecord(value)) { + throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`); + } + const id = requiredString(value, 'id', index); + validateMarketplaceEntryType(value, id); + const source = stringField(value, 'source') ?? + stringField(value, 'url') ?? + stringField(value, 'downloadUrl'); + if (source === undefined) { + throw new Error(`Plugin marketplace entry ${id} must define "source".`); + } + const resolvedSource = resolveEntrySource(source, location); + return { + id, + displayName: stringField(value, 'displayName') ?? stringField(value, 'name') ?? id, + source: resolvedSource, + tier: parseMarketplaceTier(value, id), + version: stringField(value, 'version') ?? deriveVersionFromGithubSource(resolvedSource), + description: stringField(value, 'description') ?? stringField(value, 'shortDescription'), + homepage: stringField(value, 'homepage') ?? stringField(value, 'websiteURL'), + keywords: stringArrayField(value, 'keywords'), + }; +} + +function validateMarketplaceEntryType(value: Record<string, unknown>, id: string): void { + const raw = value['type']; + if (raw === undefined) return; + if (typeof raw !== 'string') { + throw new TypeError(`Plugin marketplace entry ${id} "type" must be a string.`); + } + const type = raw.trim(); + if (type === 'plugin' || type === 'managed' || type === 'guide') return; + throw new Error( + `Plugin marketplace entry ${id} "type" must be "plugin". Legacy aliases "managed" and "guide" are also accepted.`, + ); +} + +function parseMarketplaceTier( + value: Record<string, unknown>, + id: string, +): PluginMarketplaceTier | undefined { + const raw = value['tier']; + if (raw === undefined) return undefined; + if (typeof raw !== 'string') { + throw new TypeError(`Plugin marketplace entry ${id} "tier" must be a string.`); + } + const tier = raw.trim(); + if (tier.length === 0) return undefined; + if ((PLUGIN_MARKETPLACE_TIERS as readonly string[]).includes(tier)) { + return tier as PluginMarketplaceTier; + } + throw new Error( + `Plugin marketplace entry ${id} "tier" must be one of: ${PLUGIN_MARKETPLACE_TIERS.join(', ')}.`, + ); +} + +function resolveEntrySource(source: string, location: MarketplaceLocation): string { + const trimmed = source.trim(); + if ( + trimmed.startsWith('http://') || + trimmed.startsWith('https://') || + trimmed.startsWith('~/') || + trimmed === '~' || + isAbsolute(trimmed) + ) { + return trimmed; + } + if (trimmed.startsWith('file://')) return fileURLToPath(trimmed); + if (location.kind === 'remote') { + return new URL(trimmed, location.resolved).toString(); + } + return resolve(dirname(location.resolved), trimmed); +} + +/** + * Best-effort derivation of a semver version from a GitHub source URL that pins + * a specific ref. Lets a marketplace entry omit `version` when the source + * already encodes the release (for example `/releases/tag/v6.0.3`), keeping the + * source URL the single source of truth and avoiding drift between the two. + * + * Only refs shaped like semver (`v6.0.3`, `6.0.3`, `6.0.3-rc.1`) are accepted; + * bare repo URLs, branch names and commit SHAs yield `undefined`, so update + * detection degrades to "unknown" instead of comparing meaningless values. + */ +function deriveVersionFromGithubSource(source: string): string | undefined { + let url: URL; + try { + url = new URL(source); + } catch { + return undefined; + } + if (url.hostname !== 'github.com' && url.hostname !== 'www.github.com') { + return undefined; + } + // Pathname shape: /<owner>/<repo>/<tail...>. Recognized tails: + // releases/tag/<tag> + // tree/<ref> + // commit/<sha> + const [, , kind, a, b] = url.pathname.split('/').filter(Boolean); + const ref = + kind === 'releases' && a === 'tag' ? b : kind === 'tree' || kind === 'commit' ? a : undefined; + if (ref === undefined) return undefined; + let decoded: string; + try { + decoded = decodeURIComponent(ref); + } catch { + decoded = ref; + } + const candidate = decoded.replace(/^v/i, ''); + return valid(candidate) !== null ? candidate : undefined; +} + +async function resolveLatestGithubRelease( + source: string, + fetchImpl: typeof fetch, +): Promise<string | undefined> { + const repo = parseGithubRepo(source); + if (repo === undefined) return undefined; + try { + const tag = await fetchLatestReleaseTag(repo.owner, repo.repo, fetchImpl); + if (tag === undefined) return undefined; + const candidate = tag.replace(/^v/i, ''); + return valid(candidate) !== null ? candidate : undefined; + } catch { + return undefined; + } +} + +function parseGithubRepo(source: string): { owner: string; repo: string } | undefined { + let url: URL; + try { + url = new URL(source); + } catch { + return undefined; + } + if (url.hostname !== 'github.com' && url.hostname !== 'www.github.com') return undefined; + // Only bare repo URLs (/<owner>/<repo>) qualify — URLs with a ref tail are + // already handled by deriveVersionFromGithubSource. + const segments = url.pathname.split('/').filter(Boolean); + if (segments.length !== 2) return undefined; + const [owner, repo] = segments; + return { owner: owner!, repo: repo! }; +} + +async function fetchLatestReleaseTag( + owner: string, + repo: string, + fetchImpl: typeof fetch, +): Promise<string | undefined> { + // Avoid api.github.com: its anonymous quota is shared with the user's browser + // and other tools, and a first-time lookup failing because something else + // burned the budget is unacceptable. The /releases/latest UI route 302s to + // the tag and is not part of the API quota. + const url = `https://github.com/${owner}/${repo}/releases/latest`; + const resp = await fetchImpl(url, { redirect: 'manual' }); + if (resp.status === 404) return undefined; + if (resp.status !== 301 && resp.status !== 302) { + throw new Error( + `Could not look up latest release of ${owner}/${repo}: HTTP ${resp.status} (${url}).`, + ); + } + const location = resp.headers.get('location'); + if (location === null) return undefined; + const match = /\/releases\/tag\/([^/?#]+)/.exec(location); + const tag = match?.[1]; + if (tag === undefined) return undefined; + try { + return decodeURIComponent(tag); + } catch { + return tag; + } +} + +function resolveLocalPath(input: string, workDir: string): string { + if (input === '~') return homedir(); + if (input.startsWith('~/')) return join(homedir(), input.slice(2)); + return isAbsolute(input) ? input : resolve(workDir, input); +} + +function requiredString(value: Record<string, unknown>, field: string, index: number): string { + const result = stringField(value, field); + if (result === undefined) { + throw new Error(`Plugin marketplace entry ${index + 1} must define "${field}".`); + } + return result; +} + +function stringField(value: Record<string, unknown>, field: string): string | undefined { + const raw = value[field]; + if (typeof raw !== 'string') return undefined; + const trimmed = raw.trim(); + return trimmed.length > 0 ? trimmed : undefined; +} + +function stringArrayField( + value: Record<string, unknown>, + field: string, +): readonly string[] | undefined { + const raw = value[field]; + if (!Array.isArray(raw)) return undefined; + const out = raw + .filter((item): item is string => typeof item === 'string') + .map((item) => item.trim()) + .filter((item) => item.length > 0); + return out.length > 0 ? out : undefined; +} + +function isRecord(value: unknown): value is Record<string, unknown> { + return typeof value === 'object' && value !== null && !Array.isArray(value); +} + +function formatParseError(error: unknown): string { + return error instanceof Error ? error.message : String(error); +} diff --git a/apps/kimi-code/src/utils/process/fd-detect.ts b/apps/kimi-code/src/utils/process/fd-detect.ts index 48d5e147c..ed97a0000 100644 --- a/apps/kimi-code/src/utils/process/fd-detect.ts +++ b/apps/kimi-code/src/utils/process/fd-detect.ts @@ -15,11 +15,11 @@ import { join } from 'node:path'; import { Readable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; -import { kimiCodeCdnBase } from '#/constant/app'; +import { KIMI_CODE_CDN_BASE } from '#/constant/app'; import { getBinDir } from '#/utils/paths'; -import { resolveCommandPath } from '#/utils/process/resolve-command'; const CANDIDATES = ['fd', 'fdfind']; +const FD_BASE_URL = `${KIMI_CODE_CDN_BASE}/fd`; const DOWNLOAD_TIMEOUT_MS = 120_000; const FD_ARCHIVE_SHA256: Record<string, string> = { @@ -56,11 +56,9 @@ export async function ensureFdPath(): Promise<string | null> { function detectSystemFdPath(): string | null { for (const name of CANDIDATES) { - const commandPath = resolveCommandPath(name); - if (commandPath === undefined) continue; try { - const result = spawnSync(commandPath, ['--version'], { stdio: 'ignore' }); - if (result.status === 0) return commandPath; + const result = spawnSync(name, ['--version'], { stdio: 'ignore' }); + if (result.status === 0) return name; } catch { // ENOENT, EACCES, etc. — try next candidate. } @@ -120,7 +118,7 @@ async function downloadFd(): Promise<string | null> { const archivePath = join(extractDir, assetName); try { - const downloadUrl = `${kimiCodeCdnBase()}/fd/${assetName}`; + const downloadUrl = `${FD_BASE_URL}/${assetName}`; await downloadFile(downloadUrl, archivePath); verifyArchive(archivePath, expectedSha256); extractArchive(archivePath, extractDir, assetName); diff --git a/apps/kimi-code/src/utils/region.ts b/apps/kimi-code/src/utils/region.ts deleted file mode 100644 index 2b34050c3..000000000 --- a/apps/kimi-code/src/utils/region.ts +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Process-wide region cache for the CLI/TUI. - * - * Region decides which deployment (mainland-China .com / international .ai) - * the client's off-session endpoints point at: CDN (updates, plugins, tips), - * site links, telemetry. The OAuth login flow itself does NOT read this — it - * takes explicit hosts; this cache is for everything derived afterwards. - * - * Resolution lives in `@moonshot-ai/kimi-code-oauth` (see `resolveKimiRegion`); - * this module only adds the one thing that package deliberately does not own: - * reading the persisted login's oauth ref (credential key + `oauthHost`) out - * of config.toml, synchronously, via the SDK's safe config reader. First call - * wins; `refreshKimiRegion` re-resolves after login/logout rewrote the oauth - * ref. - */ - -import { loadRuntimeConfigSafe, resolveConfigPath } from '@moonshot-ai/kimi-code-sdk'; -import { - KIMI_CODE_OAUTH_KEY, - KIMI_REGION_PROFILES, - resolveKimiRegion, - type KimiRegion, - type KimiRegionProfile, -} from '@moonshot-ai/kimi-code-oauth'; - -// Same value as DEFAULT_OAUTH_PROVIDER_NAME in '#/constant/app' — inlined here -// to keep the import one-directional (constant/app derives URLs from this -// module, so this module must not import back from it). -const MANAGED_KIMI_CODE_PROVIDER_KEY = 'managed:kimi-code'; - -/** Platform-selector value for the global OAuth login entry. */ -export const KIMI_CODE_GLOBAL_PLATFORM_VALUE = 'kimi-code-global'; - -let cached: KimiRegion | undefined; - -export interface PersistedKimiOAuthRef { - readonly key: string; - readonly oauthHost?: string; -} - -/** The oauth ref persisted by a previous login, if any. */ -export function persistedKimiOAuthRef(): PersistedKimiOAuthRef | undefined { - const result = loadRuntimeConfigSafe(resolveConfigPath({})); - // `providers` is always present on a real config load; the `?.` guards - // hosts/tests that hand us a partial config shape. - const oauth = result.config.providers?.[MANAGED_KIMI_CODE_PROVIDER_KEY]?.oauth; - if (oauth === undefined) return undefined; - return { key: oauth.key, oauthHost: oauth.oauthHost }; -} - -/** Region for a no-flag `kimi login` / `kimi acp --login`: a fresh install - follows the resolved region (env/marker/default); the default slot (only - ever a mainland-cn login) re-pins the profile explicitly; a scoped slot — - a global login, or a custom env persisted with only KIMI_CODE_BASE_URL and - no oauthHost — keeps its configured hosts (`undefined`). */ -export function regionForBareLogin(ref: PersistedKimiOAuthRef | undefined): KimiRegion | undefined { - if (ref === undefined) return currentKimiRegion(); - return ref.key === KIMI_CODE_OAUTH_KEY ? 'mainland-cn' : undefined; -} - -export function currentKimiRegion(): KimiRegion { - if (cached === undefined) { - const persisted = persistedKimiOAuthRef(); - cached = resolveKimiRegion({ - configuredOAuthHost: persisted?.oauthHost, - configuredOAuthKey: persisted?.key, - readMarker: process.env['KIMI_CODE_REGION_MARKER'] !== 'off', - }); - } - return cached; -} - -export function currentKimiProfile(): KimiRegionProfile { - return KIMI_REGION_PROFILES[currentKimiRegion()]; -} - -/** Drop the cache and re-resolve. Call after login/logout rewrote config. */ -export function refreshKimiRegion(): KimiRegion { - cached = undefined; - return currentKimiRegion(); -} diff --git a/apps/kimi-code/src/utils/remote-control-qr.ts b/apps/kimi-code/src/utils/remote-control-qr.ts deleted file mode 100644 index b7e3fab6e..000000000 --- a/apps/kimi-code/src/utils/remote-control-qr.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { mkdir, writeFile } from 'node:fs/promises'; -import { resolve } from 'node:path'; - -import { - getCapabilities, - getCellDimensions, - getPngDimensions, - renderImage, -} from '@moonshot-ai/pi-tui'; -import * as QRCode from 'qrcode'; - -const TERMINAL_QR_MARGIN = 2; -const TERMINAL_QR_DARK = '0;0;0'; -const TERMINAL_QR_LIGHT = '255;255;255'; -const ANSI_RESET = '\u001B[0m'; - -const QR_PNG_MARGIN = 4; -const QR_IMAGE_MIN_PX_PER_MODULE = 4; - -export async function generateRemoteControlQr( - url: string, - dataDir: string, -): Promise<{ terminal: string; pngPath: string }> { - await mkdir(dataDir, { recursive: true }); - const pngPath = resolve(dataDir, 'rc-qrcode.png'); - const png = await QRCode.toBuffer(url, { type: 'png', margin: QR_PNG_MARGIN }); - await writeFile(pngPath, png); - const terminal = renderInlineImageQr(url, png) ?? renderTerminalQr(url); - return { terminal, pngPath }; -} - -function renderInlineImageQr(url: string, png: Buffer): string | null { - if (getCapabilities().images === null) return null; - const base64 = png.toString('base64'); - const dimensions = getPngDimensions(base64); - if (dimensions === null) return null; - const moduleCount = - QRCode.create(url, { errorCorrectionLevel: 'M' }).modules.size + QR_PNG_MARGIN * 2; - const maxWidthCells = Math.ceil( - (moduleCount * QR_IMAGE_MIN_PX_PER_MODULE) / getCellDimensions().widthPx, - ); - const rendered = renderImage(base64, dimensions, { maxWidthCells }); - return rendered === null ? null : `${rendered.sequence}\n`; -} - -export function renderTerminalQr(url: string): string { - const qr = QRCode.create(url, { errorCorrectionLevel: 'M' }); - const size: number = qr.modules.size; - const data: Uint8Array = qr.modules.data; - const isDark = (x: number, y: number): boolean => - x >= 0 && y >= 0 && x < size && y < size && data[y * size + x] === 1; - let output = ''; - for (let y = -TERMINAL_QR_MARGIN; y < size + TERMINAL_QR_MARGIN; y += 2) { - for (let x = -TERMINAL_QR_MARGIN; x < size + TERMINAL_QR_MARGIN; x++) { - const top = isDark(x, y) ? TERMINAL_QR_DARK : TERMINAL_QR_LIGHT; - const bottom = isDark(x, y + 1) ? TERMINAL_QR_DARK : TERMINAL_QR_LIGHT; - output += `\u001B[38;2;${top}m\u001B[48;2;${bottom}m▀`; - } - output += `${ANSI_RESET}\n`; - } - return output + ANSI_RESET; -} diff --git a/apps/kimi-code/src/utils/terminal-hyperlink.ts b/apps/kimi-code/src/utils/terminal-hyperlink.ts index c82dfe296..43d27f0a3 100644 --- a/apps/kimi-code/src/utils/terminal-hyperlink.ts +++ b/apps/kimi-code/src/utils/terminal-hyperlink.ts @@ -1,24 +1,3 @@ -const HYPERLINK_TERM_PROGRAMS = new Set([ - 'iTerm.app', - 'WezTerm', - 'vscode', - 'ghostty', - 'WarpTerminal', - 'Hyper', -]); -const HYPERLINK_TERMS = new Set(['xterm-kitty', 'xterm-ghostty', 'wezterm', 'foot', 'contour']); - -export function supportsHyperlinks(env: NodeJS.ProcessEnv = process.env): boolean { - const force = env['FORCE_HYPERLINK']; - if (force !== undefined) return force !== '0'; - if ((env['WT_SESSION'] ?? '').length > 0) return true; - if (HYPERLINK_TERM_PROGRAMS.has(env['TERM_PROGRAM'] ?? '')) return true; - if (HYPERLINK_TERMS.has(env['TERM'] ?? '')) return true; - if (Number(env['VTE_VERSION'] ?? '0') >= 5000) return true; - if ((env['KONSOLE_VERSION'] ?? '').length > 0) return true; - return false; -} - export function toTerminalHyperlink(text: string, url: string): string { - return `]8;;${url}${text}]8;;`; + return `\u001B]8;;${url}\u0007${text}\u001B]8;;\u0007`; } diff --git a/apps/kimi-code/test/cli/export.test.ts b/apps/kimi-code/test/cli/export.test.ts index c4fcc286a..25f72ae1e 100644 --- a/apps/kimi-code/test/cli/export.test.ts +++ b/apps/kimi-code/test/cli/export.test.ts @@ -14,7 +14,6 @@ import { Command } from 'commander'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { handleExport, registerExportCommand } from '#/cli/sub/export'; -import { refreshKimiRegion } from '#/utils/region'; import type { ExportDeps } from '#/cli/sub/export'; import type { ExportSessionInput, @@ -106,16 +105,11 @@ beforeEach(() => { // Pin the legacy engine so the default-deps cases keep exercising the legacy // SDK harness this suite asserts on; the routing cases below re-stub it. vi.stubEnv('KIMI_CODE_LEGACY_FLAG', '1'); - // Pin region to cn: the telemetry endpoint assertion must not follow the - // dev machine's own login/marker state. - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.com'); - refreshKimiRegion(); tmp = mkdtempSync(join(tmpdir(), 'kimi-export-')); }); afterEach(() => { vi.unstubAllEnvs(); - refreshKimiRegion(); rmSync(tmp, { recursive: true, force: true }); vi.clearAllMocks(); mocks.harnessGetConfig.mockResolvedValue({ @@ -432,14 +426,8 @@ describe('kimi export', () => { uiMode: 'shell', model: 'k2', sessionId: undefined, - endpoint: expect.any(Function), getAccessToken: expect.any(Function), }); - // The endpoint resolver defers to the active region profile at flush time. - const telemetryOptions = mocks.initializeTelemetry.mock.calls[0]![0] as { - endpoint: () => string; - }; - expect(telemetryOptions.endpoint()).toBe('https://telemetry-logs.kimi.com/v1/event'); expect(mocks.initializeTelemetry.mock.invocationCallOrder[0]).toBeLessThan( mocks.harnessExportSession.mock.invocationCallOrder[0]!, ); diff --git a/apps/kimi-code/test/cli/main.test.ts b/apps/kimi-code/test/cli/main.test.ts index d115c6e76..8e058068a 100644 --- a/apps/kimi-code/test/cli/main.test.ts +++ b/apps/kimi-code/test/cli/main.test.ts @@ -49,8 +49,6 @@ const mocks = vi.hoisted(() => { }, KimiHarness: vi.fn(), createKimiHarness: vi.fn(), - maybeRelaunch: vi.fn(async () => false), - runUpdateDownloadCommand: vi.fn(async () => 0), }; }); @@ -124,14 +122,6 @@ vi.mock('../../src/cli/update/preflight', () => ({ runUpdatePreflight: mocks.runUpdatePreflight, })); -vi.mock('../../src/cli/update/native-swap', () => ({ - maybeRelaunchWithStagedNativeUpdate: mocks.maybeRelaunch, -})); - -vi.mock('../../src/cli/sub/update-download', () => ({ - runUpdateDownloadCommand: mocks.runUpdateDownloadCommand, -})); - vi.mock('../../src/cli/run-shell', () => ({ runShell: mocks.runShell, })); @@ -180,14 +170,6 @@ async function waitForAssertion(assertion: () => void): Promise<void> { throw lastError; } -/** main() now boots asynchronously (after the staged-swap check resolves). */ -async function waitForProgramArgs(): Promise<unknown[]> { - await waitForAssertion(() => { - expect(mocks.createProgram).toHaveBeenCalled(); - }); - return mocks.createProgram.mock.calls[0] as unknown as unknown[]; -} - async function runHandleMainCommand(opts: CLIOptions): Promise<number | null> { const exitSpy = vi.spyOn(process, 'exit').mockImplementation((code?: string | number | null) => { throw new ExitCalled(Number(code ?? 0)); @@ -312,7 +294,7 @@ describe('main entry command handling', () => { mocks.finalizeHeadlessRun.mockResolvedValue(void 0); main(); - const programArgs = await waitForProgramArgs(); + const programArgs = mocks.createProgram.mock.calls[0] as unknown as unknown[]; const mainAction = programArgs[1] as (opts: CLIOptions) => void; mainAction(opts); @@ -337,7 +319,7 @@ describe('main entry command handling', () => { try { main(); - const programArgs = await waitForProgramArgs(); + const programArgs = mocks.createProgram.mock.calls[0] as unknown as unknown[]; const mainAction = programArgs[1] as (opts: CLIOptions) => void; mainAction(opts); @@ -367,44 +349,14 @@ describe('main entry command handling', () => { expect(runShell).toHaveBeenCalledWith(opts, '0.0.1-alpha.2'); }); - it('installs crash handlers before parsing CLI arguments', async () => { + it('installs crash handlers before parsing CLI arguments', () => { main(); expect(mocks.installCrashHandlers).toHaveBeenCalledTimes(1); - await waitForAssertion(() => { - expect(mocks.installCrashHandlers.mock.invocationCallOrder[0]).toBeLessThan( - mocks.createProgram.mock.invocationCallOrder[0]!, - ); - expect(mocks.parse).toHaveBeenCalledWith(process.argv); - }); - }); - - it('runs the staged-swap check before bootstrap and skips startup when it relaunches', async () => { - mocks.maybeRelaunch.mockResolvedValueOnce(true); - - main(); - - await waitForAssertion(() => { - expect(mocks.maybeRelaunch).toHaveBeenCalledTimes(1); - }); - // Relaunched → the parent must sit on the child, never bootstrap. - await new Promise((resolve) => setTimeout(resolve, 20)); - expect(mocks.createProgram).not.toHaveBeenCalled(); - }); - - it('passes the runtime context to the staged-swap check', async () => { - main(); - - await waitForAssertion(() => { - expect(mocks.maybeRelaunch).toHaveBeenCalledWith( - expect.objectContaining({ - exePath: process.execPath, - argv: process.argv, - currentVersion: '0.0.1-alpha.2', - isNative: false, - }), - ); - }); + expect(mocks.installCrashHandlers.mock.invocationCallOrder[0]).toBeLessThan( + mocks.createProgram.mock.invocationCallOrder[0]!, + ); + expect(mocks.parse).toHaveBeenCalledWith(process.argv); }); it('sets the process title during startup', () => { diff --git a/apps/kimi-code/test/cli/options.test.ts b/apps/kimi-code/test/cli/options.test.ts index 9ff60d5d5..95936fe5c 100644 --- a/apps/kimi-code/test/cli/options.test.ts +++ b/apps/kimi-code/test/cli/options.test.ts @@ -5,7 +5,7 @@ * Run: pnpm -C apps/kimi-code exec vitest run test/cli/options.test.ts */ -import { describe, expect, it, onTestFinished, vi } from 'vitest'; +import { describe, expect, it } from 'vitest'; import { createProgram } from '#/cli/commands'; import type { CLIOptions } from '#/cli/options'; @@ -572,16 +572,13 @@ describe('CLI options parsing', () => { }); it('registers the visible sub-commands', () => { - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', '0'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '0'); - onTestFinished(() => { vi.unstubAllEnvs(); }); const program = createProgram( '0.0.0', () => {}, () => {}, ); const commandNames: string[] = program.commands - .filter((command) => !command.name().startsWith('__') && !(command as unknown as { _hidden?: boolean })._hidden) + .filter((command) => !command.name().startsWith('__')) .map((command) => command.name()); expect(commandNames).toEqual([ 'export', diff --git a/apps/kimi-code/test/cli/run-shell.test.ts b/apps/kimi-code/test/cli/run-shell.test.ts index 51909bde9..35a096659 100644 --- a/apps/kimi-code/test/cli/run-shell.test.ts +++ b/apps/kimi-code/test/cli/run-shell.test.ts @@ -1,10 +1,9 @@ -import { execFileSync } from 'node:child_process'; +import { execSync } from 'node:child_process'; import type { createKimiDeviceId as createKimiDeviceIdFn } from '@moonshot-ai/kimi-code-oauth'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { runShell } from '#/cli/run-shell'; -import { refreshKimiRegion } from '#/utils/region'; import { captureProcessWrite, ExitCalled, mockProcessExit } from '../helpers/process'; @@ -62,9 +61,7 @@ const mocks = vi.hoisted(() => { resolveKimiHome: vi.fn((homeDir?: string) => homeDir ?? '/tmp/kimi-code-test-home'), flushDiagnosticLogsSync: vi.fn(), harnessCreatesDeviceIdOnConstruction: false, - execFileSync: vi.fn(() => ''), - spawnSync: vi.fn(), - resolveCommandPath: vi.fn(() => '/bin/stty' as string | undefined), + execSync: vi.fn(), TuiConfigParseError, }; }); @@ -135,8 +132,6 @@ vi.mock('../../src/tui/index', () => ({ KimiTUI: class { onExit?: () => Promise<void>; - readonly state = { ui: { mode: 'regular' as const } }; - constructor(...args: unknown[]) { mocks.kimiTuiConstructor(this, ...args); } @@ -157,27 +152,17 @@ vi.mock('../../src/migration/index', () => ({ })); vi.mock('node:child_process', () => ({ - execFileSync: mocks.execFileSync, - spawnSync: mocks.spawnSync, -})); - -vi.mock('../../src/utils/process/resolve-command', () => ({ - resolveCommandPath: mocks.resolveCommandPath, + execSync: mocks.execSync, })); describe('runShell', () => { beforeEach(() => { vi.stubEnv('KIMI_CODE_LEGACY_FLAG', '1'); - // Pin region to cn: the telemetry endpoint assertion below must not - // follow the dev machine's own login/marker state. - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.com'); - refreshKimiRegion(); }); afterEach(() => { vi.clearAllMocks(); vi.unstubAllEnvs(); - refreshKimiRegion(); mocks.harnessGetConfig.mockResolvedValue({ providers: {}, defaultModel: 'k2', @@ -190,7 +175,6 @@ describe('runShell', () => { mocks.resolveKimiHome.mockImplementation( (homeDir?: string) => homeDir ?? '/tmp/kimi-code-test-home', ); - mocks.resolveCommandPath.mockImplementation(() => '/bin/stty'); mocks.harnessCreatesDeviceIdOnConstruction = false; }); @@ -313,15 +297,12 @@ describe('runShell', () => { expect(mocks.harnessEnsureConfigFile.mock.invocationCallOrder[0]).toBeLessThan( mocks.harnessGetConfig.mock.invocationCallOrder[0]!, ); - // stty is resolved to an absolute path before the trust gate and skipped - // entirely on Windows (a bare `stty` name would resolve into the - // untrusted cwd). + // stty is POSIX-only; on Windows the save/restore block is skipped + // entirely (a bare `stty` name would resolve into the untrusted cwd). if (process.platform !== 'win32') { - expect(execFileSync).toHaveBeenCalledWith('/bin/stty', ['-ixon'], { - stdio: ['inherit', 'ignore', 'ignore'], - }); + expect(execSync).toHaveBeenCalledWith('stty -ixon', { stdio: ['inherit', 'ignore', 'ignore'] }); } else { - expect(execFileSync).not.toHaveBeenCalled(); + expect(execSync).not.toHaveBeenCalled(); } expect(mocks.kimiTuiConstructor).toHaveBeenCalledTimes(1); expect(mocks.createKimiDeviceId).toHaveBeenCalledWith( @@ -337,14 +318,8 @@ describe('runShell', () => { uiMode: 'shell', model: 'k2', sessionId: undefined, - endpoint: expect.any(Function), getAccessToken: expect.any(Function), }); - // The endpoint resolver defers to the active region profile at flush time. - const telemetryOptions = mocks.initializeTelemetry.mock.calls[0]![0] as { - endpoint: () => string; - }; - expect(telemetryOptions.endpoint()).toBe('https://telemetry-logs.kimi.com/v1/event'); expect(mocks.setCrashPhase).toHaveBeenCalledWith('runtime'); const [, harness, startupInput] = mocks.kimiTuiConstructor.mock.calls[0]!; @@ -367,7 +342,6 @@ describe('runShell', () => { config_ms: expect.any(Number), init_ms: expect.any(Number), mcp_ms: 47, - tui_mode: 'regular', }); }); @@ -377,21 +351,12 @@ describe('runShell', () => { Object.defineProperty(process, 'platform', { value: 'win32' }); try { await runShell(minimalCliOptions, '1.2.3-test'); - expect(execFileSync).not.toHaveBeenCalled(); + expect(execSync).not.toHaveBeenCalled(); } finally { Object.defineProperty(process, 'platform', { value: originalPlatform }); } }); - it('skips stty when it cannot be resolved outside the untrusted cwd', async () => { - stubTuiStartup(); - if (process.platform === 'win32') return; - mocks.resolveCommandPath.mockReturnValue(undefined); - await runShell(minimalCliOptions, '1.2.3-test'); - expect(mocks.resolveCommandPath).toHaveBeenCalledWith('stty'); - expect(execFileSync).not.toHaveBeenCalled(); - }); - it('resolves the --agent profile into the TUI startup input', async () => { mocks.loadTuiConfig.mockResolvedValue({ theme: 'dark', @@ -575,7 +540,6 @@ describe('runShell', () => { config_ms: expect.any(Number), init_ms: expect.any(Number), mcp_ms: 47, - tui_mode: 'regular', }); }); @@ -833,10 +797,7 @@ describe('runShell', () => { ).rejects.toThrow('boom'); expect(mocks.setCrashPhase).toHaveBeenCalledWith('shutdown'); - expect(mocks.harnessTrack).toHaveBeenCalledWith('exit', { - duration_ms: expect.any(Number), - tui_mode: 'regular', - }); + expect(mocks.harnessTrack).toHaveBeenCalledWith('exit', { duration_ms: expect.any(Number) }); expect(mocks.shutdownTelemetry).toHaveBeenCalledOnce(); expect(mocks.harnessClose).toHaveBeenCalledOnce(); }); @@ -885,7 +846,6 @@ describe('runShell', () => { expect(mocks.withTelemetryContext).toHaveBeenCalledWith({ sessionId: 'ses-1' }); expect(mocks.lifecycleTrack).toHaveBeenCalledWith('exit', { duration_ms: expect.any(Number), - tui_mode: 'regular', }); expect(mocks.harnessTrack).not.toHaveBeenCalledWith('exit', expect.anything()); expect(mocks.shutdownTelemetry).toHaveBeenCalledOnce(); diff --git a/apps/kimi-code/test/cli/run-v2-print.test.ts b/apps/kimi-code/test/cli/run-v2-print.test.ts index 63c9264c1..f4927455b 100644 --- a/apps/kimi-code/test/cli/run-v2-print.test.ts +++ b/apps/kimi-code/test/cli/run-v2-print.test.ts @@ -13,7 +13,7 @@ function ending( turnId: number, reason: PrintTurnEnding['reason'] = 'completed', ): PrintTurnEnding { - return { type: 'turn.ended', turnId, reason } as unknown as PrintTurnEnding; + return { type: 'turn.ended', turnId, reason }; } interface ScriptedEntry { diff --git a/apps/kimi-code/test/cli/update-download.test.ts b/apps/kimi-code/test/cli/update-download.test.ts deleted file mode 100644 index 991e250c4..000000000 --- a/apps/kimi-code/test/cli/update-download.test.ts +++ /dev/null @@ -1,261 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; - -import { createDownloadProgress, runUpdateDownloadCommand } from '#/cli/sub/update-download'; - -const mocks = vi.hoisted(() => ({ - detectNativeInstall: vi.fn(() => true), - tryAcquireUpdateInstallLock: vi.fn(), - readUpdateInstallLockVersion: vi.fn(), - stageNativeUpdate: vi.fn(), - readStagedNativeUpdate: vi.fn(), - promoteStagedUpdateToManual: vi.fn(async () => true), - hashFileSha256: vi.fn(), - stagedExePath: vi.fn(() => '/tmp/staged-exe'), -})); - -vi.mock('#/cli/update/source', () => ({ - detectNativeInstall: mocks.detectNativeInstall, -})); - -vi.mock('#/cli/update/install-lock', () => ({ - tryAcquireUpdateInstallLock: mocks.tryAcquireUpdateInstallLock, - readUpdateInstallLockVersion: mocks.readUpdateInstallLockVersion, -})); - -vi.mock('#/cli/update/native-stage', () => ({ - stageNativeUpdate: mocks.stageNativeUpdate, - readStagedNativeUpdate: mocks.readStagedNativeUpdate, - promoteStagedUpdateToManual: mocks.promoteStagedUpdateToManual, - hashFileSha256: mocks.hashFileSha256, - stagedExePath: mocks.stagedExePath, -})); - -vi.mock('@moonshot-ai/kimi-code-sdk', async () => { - const actual = await vi.importActual<typeof import('@moonshot-ai/kimi-code-sdk')>( - '@moonshot-ai/kimi-code-sdk', - ); - return { - ...actual, - log: { ...actual.log, warn: vi.fn() }, - }; -}); - -function fakeOut(isTTY: boolean): { readonly out: NodeJS.WriteStream; readonly chunks: string[] } { - const chunks: string[] = []; - const out = { - isTTY, - write(chunk: string) { - chunks.push(chunk); - return true; - }, - } as unknown as NodeJS.WriteStream; - return { out, chunks }; -} - -describe('createDownloadProgress', () => { - it('renders a throttled in-place line on a TTY, with the final frame always shown', () => { - const { out, chunks } = fakeOut(true); - const progress = createDownloadProgress(out, 'Downloading…'); - const total = 100 * 1024 * 1024; - - const nowSpy = vi.spyOn(Date, 'now'); - nowSpy.mockReturnValue(1_000); - progress(10 * 1024 * 1024, total); - nowSpy.mockReturnValue(1_050); // inside the 100 ms throttle window → skipped - progress(20 * 1024 * 1024, total); - nowSpy.mockReturnValue(1_200); - progress(30 * 1024 * 1024, total); - progress(total, total); // final frame is never throttled - - expect(chunks).toEqual([ - '\r\u001B[KDownloading… 10% (10/100 MB)', - '\r\u001B[KDownloading… 30% (30/100 MB)', - '\r\u001B[KDownloading… 100% (100/100 MB)', - ]); - nowSpy.mockRestore(); - }); - - it('prints the label up front and one line per 32 MB when piped', () => { - const { out, chunks } = fakeOut(false); - const progress = createDownloadProgress(out, 'Downloading…'); - const total = 100 * 1024 * 1024; - - progress(10 * 1024 * 1024, total); // below the 32 MB line interval → skipped - progress(40 * 1024 * 1024, total); - progress(total, total); - - expect(chunks).toEqual([ - 'Downloading…\n', - 'Downloading… 40% (40/100 MB)\n', - 'Downloading… 100% (100/100 MB)\n', - ]); - }); - - it('degrades to plain MB counts when Content-Length is unknown', () => { - const { out, chunks } = fakeOut(true); - const progress = createDownloadProgress(out, 'Downloading…'); - progress(5 * 1024 * 1024, null); - expect(chunks).toEqual(['\r\u001B[KDownloading… 5 MB']); - }); -}); - -describe('runUpdateDownloadCommand', () => { - const STAGED_HASH = 'a'.repeat(64); - - beforeEach(() => { - vi.clearAllMocks(); - mocks.detectNativeInstall.mockReturnValue(true); - mocks.tryAcquireUpdateInstallLock.mockResolvedValue({ - filePath: '/tmp/install.lock', - release: vi.fn(async () => {}), - }); - mocks.stageNativeUpdate.mockResolvedValue({ status: 'staged', staged: {} }); - mocks.hashFileSha256.mockResolvedValue(STAGED_HASH); - }); - - afterEach(() => { - vi.restoreAllMocks(); - }); - - it('refuses on non-native installs', async () => { - mocks.detectNativeInstall.mockReturnValue(false); - const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(1); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('native build')); - }); - - it('waits for and adopts the result when another instance downloads the same version', async () => { - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mocks.readUpdateInstallLockVersion.mockResolvedValue('0.7.0'); - // The other worker's staged update is verified on disk on the first poll. - mocks.readStagedNativeUpdate.mockResolvedValue({ version: '0.7.0', sha256: STAGED_HASH }); - const stdoutSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(stdoutSpy).toHaveBeenCalledWith(expect.stringContaining('already in progress')); - // A background waiter's adoption keeps the auto marker. - expect(mocks.promoteStagedUpdateToManual).not.toHaveBeenCalled(); - }); - - it('promotes the adopted stage to manual when an explicit upgrade waited for it', async () => { - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mocks.readUpdateInstallLockVersion.mockResolvedValue('0.7.0'); - mocks.readStagedNativeUpdate.mockResolvedValue({ version: '0.7.0', sha256: STAGED_HASH }); - vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0', true)).resolves.toBe(0); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(mocks.promoteStagedUpdateToManual).toHaveBeenCalledTimes(1); - }); - - it('keeps waiting until the manual promotion is confirmed persisted', async () => { - // The first promotion attempt loses a race with a concurrent swap's - // claim/restore cycle; the loop must not report adoption until the - // marker is confirmed. - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mocks.readUpdateInstallLockVersion.mockResolvedValue('0.7.0'); - mocks.readStagedNativeUpdate.mockResolvedValue({ version: '0.7.0', sha256: STAGED_HASH }); - mocks.promoteStagedUpdateToManual - .mockResolvedValueOnce(false) - .mockResolvedValueOnce(true); - vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0', true)).resolves.toBe(0); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(mocks.promoteStagedUpdateToManual).toHaveBeenCalledTimes(2); - }); - - it('waits instead of adopting when the recorded payload fails the checksum', async () => { - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mocks.readUpdateInstallLockVersion.mockResolvedValue('0.7.0'); - mocks.readStagedNativeUpdate.mockResolvedValue({ version: '0.7.0', sha256: STAGED_HASH }); - // First poll: the recorded payload is corrupt (the holder is re-staging - // it — its metadata is only replaced when the repaired generation - // publishes); second poll: the repaired generation verifies. - mocks.hashFileSha256.mockResolvedValueOnce('corrupt').mockResolvedValue(STAGED_HASH); - vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(mocks.hashFileSha256).toHaveBeenCalledTimes(2); - }); - - it('takes over when the holder dies leaving a corrupt stage behind', async () => { - const release = vi.fn(async () => {}); - mocks.tryAcquireUpdateInstallLock - .mockResolvedValueOnce(null) // initial acquire: held - .mockResolvedValue({ filePath: '/tmp/install.lock', release }); // in-loop takeover - mocks.readUpdateInstallLockVersion.mockResolvedValueOnce('0.7.0'); - mocks.readStagedNativeUpdate.mockResolvedValue({ version: '0.7.0', sha256: STAGED_HASH }); - // The recorded payload never verifies: the lock poll takes over and - // stageNativeUpdate's own adoption check re-stages it. - mocks.hashFileSha256.mockResolvedValue('corrupt'); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).toHaveBeenCalledWith( - expect.objectContaining({ version: '0.7.0' }), - ); - expect(release).toHaveBeenCalledTimes(1); - }); - - it('takes over when the same-version holder finishes without staging', async () => { - const release = vi.fn(async () => {}); - mocks.tryAcquireUpdateInstallLock - .mockResolvedValueOnce(null) // held by the other worker… - .mockResolvedValueOnce({ filePath: '/tmp/install.lock', release }); // …won inside the wait loop - mocks.readUpdateInstallLockVersion.mockResolvedValueOnce('0.7.0'); // the initial holder check - mocks.readStagedNativeUpdate.mockResolvedValue(null); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).toHaveBeenCalledWith( - expect.objectContaining({ version: '0.7.0' }), - ); - expect(release).toHaveBeenCalledTimes(1); - }); - - it('fails instead of a false success when the lock holder stages another version', async () => { - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mocks.readUpdateInstallLockVersion.mockResolvedValue('0.8.0'); - const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(1); - expect(mocks.stageNativeUpdate).not.toHaveBeenCalled(); - expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('0.8.0')); - }); - - it('retries the acquire when the lock vanished between the two reads', async () => { - const release = vi.fn(async () => {}); - mocks.tryAcquireUpdateInstallLock - .mockResolvedValueOnce(null) - .mockResolvedValueOnce({ filePath: '/tmp/install.lock', release }); - mocks.readUpdateInstallLockVersion.mockResolvedValue(undefined); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).toHaveBeenCalledWith( - expect.objectContaining({ version: '0.7.0' }), - ); - expect(release).toHaveBeenCalledTimes(1); - }); - - it('stages against the running exe and releases the lock', async () => { - const release = vi.fn(async () => {}); - mocks.tryAcquireUpdateInstallLock.mockResolvedValue({ filePath: '/tmp/install.lock', release }); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(0); - expect(mocks.stageNativeUpdate).toHaveBeenCalledWith( - expect.objectContaining({ version: '0.7.0', exePath: process.execPath }), - ); - expect(release).toHaveBeenCalledTimes(1); - }); - - it('marks the stage as manual when the download answers an explicit upgrade', async () => { - mocks.tryAcquireUpdateInstallLock.mockResolvedValue({ - filePath: '/tmp/install.lock', - release: vi.fn(async () => {}), - }); - await expect(runUpdateDownloadCommand('0.7.0', true)).resolves.toBe(0); - expect(mocks.stageNativeUpdate).toHaveBeenCalledWith( - expect.objectContaining({ version: '0.7.0', manual: true }), - ); - }); - - it('reports staging failures with a non-zero exit code', async () => { - mocks.stageNativeUpdate.mockRejectedValue(new Error('sha256 mismatch')); - const stderrSpy = vi.spyOn(process.stderr, 'write').mockImplementation(() => true); - await expect(runUpdateDownloadCommand('0.7.0')).resolves.toBe(1); - expect(stderrSpy).toHaveBeenCalledWith(expect.stringContaining('sha256 mismatch')); - }); -}); diff --git a/apps/kimi-code/test/cli/update/cdn.test.ts b/apps/kimi-code/test/cli/update/cdn.test.ts index bbfaf965b..7eba81080 100644 --- a/apps/kimi-code/test/cli/update/cdn.test.ts +++ b/apps/kimi-code/test/cli/update/cdn.test.ts @@ -1,7 +1,7 @@ import { describe, expect, it, vi } from 'vitest'; import { fetchLatestFromCdn, fetchLatestVersionFromCdn } from '#/cli/update/cdn'; -import { kimiCodeCdnLatestJsonUrl, kimiCodeCdnLatestUrl } from '#/constant/app'; +import { KIMI_CODE_CDN_LATEST_JSON_URL, KIMI_CODE_CDN_LATEST_URL } from '#/constant/app'; function mockFetchOk(body: string): typeof fetch { return vi.fn(async () => ({ @@ -54,7 +54,7 @@ describe('fetchLatestVersionFromCdn', () => { const f = mockFetchOk(' 0.5.0\n'); await expect(fetchLatestVersionFromCdn(f)).resolves.toBe('0.5.0'); expect(f).toHaveBeenCalledWith( - kimiCodeCdnLatestUrl(), + KIMI_CODE_CDN_LATEST_URL, expect.objectContaining({ signal: expect.any(AbortSignal) }), ); }); @@ -83,7 +83,7 @@ describe('fetchLatestVersionFromCdn', () => { describe('fetchLatestFromCdn', () => { it('parses latest.json and returns the manifest', async () => { - const f = mockRoutedFetch({ [kimiCodeCdnLatestJsonUrl()]: { body: MANIFEST_BODY } }); + const f = mockRoutedFetch({ [KIMI_CODE_CDN_LATEST_JSON_URL]: { body: MANIFEST_BODY } }); await expect(fetchLatestFromCdn(f)).resolves.toEqual({ latest: '2.0.0', manifest: { @@ -97,7 +97,7 @@ describe('fetchLatestFromCdn', () => { }, }); expect(f).toHaveBeenCalledWith( - kimiCodeCdnLatestJsonUrl(), + KIMI_CODE_CDN_LATEST_JSON_URL, expect.objectContaining({ signal: expect.any(AbortSignal) }), ); expect(f).toHaveBeenCalledTimes(1); @@ -111,7 +111,7 @@ describe('fetchLatestFromCdn', () => { rollout: [], futureField: { nested: true }, }); - const f = mockRoutedFetch({ [kimiCodeCdnLatestJsonUrl()]: { body } }); + const f = mockRoutedFetch({ [KIMI_CODE_CDN_LATEST_JSON_URL]: { body } }); const result = await fetchLatestFromCdn(f); expect(result.manifest).toEqual({ version: '2.0.0', @@ -125,7 +125,7 @@ describe('fetchLatestFromCdn', () => { version: '2.0.0', publishedAt: '2026-06-12T00:00:00.000Z', }); - const f = mockRoutedFetch({ [kimiCodeCdnLatestJsonUrl()]: { body } }); + const f = mockRoutedFetch({ [KIMI_CODE_CDN_LATEST_JSON_URL]: { body } }); const result = await fetchLatestFromCdn(f); expect(result.manifest?.rollout).toEqual([]); }); @@ -155,8 +155,8 @@ describe('fetchLatestFromCdn', () => { for (const [name, route] of fallbackCases) { it(`falls back to plain /latest when ${name}`, async () => { const f = mockRoutedFetch({ - [kimiCodeCdnLatestJsonUrl()]: route, - [kimiCodeCdnLatestUrl()]: { body: '1.9.0\n' }, + [KIMI_CODE_CDN_LATEST_JSON_URL]: route, + [KIMI_CODE_CDN_LATEST_URL]: { body: '1.9.0\n' }, }); await expect(fetchLatestFromCdn(f)).resolves.toEqual({ latest: '1.9.0', @@ -167,16 +167,16 @@ describe('fetchLatestFromCdn', () => { it('throws when both latest.json and plain /latest fail', async () => { const f = mockRoutedFetch({ - [kimiCodeCdnLatestJsonUrl()]: { status: 500 }, - [kimiCodeCdnLatestUrl()]: { status: 500 }, + [KIMI_CODE_CDN_LATEST_JSON_URL]: { status: 500 }, + [KIMI_CODE_CDN_LATEST_URL]: { status: 500 }, }); await expect(fetchLatestFromCdn(f)).rejects.toThrow(/HTTP 500/); }); it('propagates the plain /latest error when the fallback also breaks', async () => { const f = mockRoutedFetch({ - [kimiCodeCdnLatestJsonUrl()]: new Error('json down'), - [kimiCodeCdnLatestUrl()]: { body: 'not-a-version' }, + [KIMI_CODE_CDN_LATEST_JSON_URL]: new Error('json down'), + [KIMI_CODE_CDN_LATEST_URL]: { body: 'not-a-version' }, }); await expect(fetchLatestFromCdn(f)).rejects.toThrow(/invalid semver/); }); @@ -185,14 +185,14 @@ describe('fetchLatestFromCdn', () => { vi.useFakeTimers(); try { const f = vi.fn(async (input: string | URL, init?: RequestInit) => { - if (String(input) === kimiCodeCdnLatestJsonUrl()) { + if (String(input) === KIMI_CODE_CDN_LATEST_JSON_URL) { return new Promise<Response>((_resolve, reject) => { init?.signal?.addEventListener('abort', () => { reject(new Error('aborted')); }, { once: true }); }); } - if (String(input) === kimiCodeCdnLatestUrl()) { + if (String(input) === KIMI_CODE_CDN_LATEST_URL) { return { ok: true, status: 200, text: async () => '1.9.0\n' }; } return { ok: false, status: 404, text: async () => '' }; diff --git a/apps/kimi-code/test/cli/update/install-lock.test.ts b/apps/kimi-code/test/cli/update/install-lock.test.ts index 63bfbc783..fd7b568f8 100644 --- a/apps/kimi-code/test/cli/update/install-lock.test.ts +++ b/apps/kimi-code/test/cli/update/install-lock.test.ts @@ -1,36 +1,12 @@ -import { spawn } from 'node:child_process'; -import { mkdirSync, mkdtempSync, readFileSync, rmSync, utimesSync, writeFileSync } from 'node:fs'; +import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { dirname, join } from 'node:path'; -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { tryAcquireUpdateInstallLock } from '#/cli/update/install-lock'; import { getUpdateInstallLockFile } from '#/utils/paths'; -const fsMocks = vi.hoisted(() => ({ - /** When set, link() throws an error with this code (no hard-link support). */ - linkError: null as string | null, -})); - -vi.mock('node:fs/promises', async (importOriginal) => { - const actual = await importOriginal<typeof import('node:fs/promises')>(); - return { - ...actual, - link: async ( - src: Parameters<typeof actual.link>[0], - dst: Parameters<typeof actual.link>[1], - ) => { - if (fsMocks.linkError !== null) { - throw Object.assign(new Error('link() is not supported (mocked)'), { - code: fsMocks.linkError, - }); - } - return actual.link(src, dst); - }, - }; -}); - const originalEnv = { ...process.env }; let dir: string; @@ -38,7 +14,6 @@ let dir: string; beforeEach(() => { dir = mkdtempSync(join(tmpdir(), 'kimi-update-install-lock-')); process.env['KIMI_CODE_HOME'] = dir; - fsMocks.linkError = null; }); afterEach(() => { @@ -62,153 +37,10 @@ describe('update install lock', () => { await third?.release(); }); - it('grants the lock to exactly one of many concurrent acquirers', async () => { - // The lock file must never be observable in an empty/partial state: - // losers of the create race used to sweep the just-created (still empty) - // lock as "corrupt" and also win, breaking exclusivity. - const attempts = await Promise.all( - Array.from({ length: 20 }, () => tryAcquireUpdateInstallLock({ version: '0.5.0' })), - ); - const winners = attempts.filter((handle) => handle !== null); - expect(winners).toHaveLength(1); - const held = JSON.parse(readFileSync(getUpdateInstallLockFile(), 'utf-8')) as { - version: string; - }; - expect(held.version).toBe('0.5.0'); - await winners[0]?.release(); - }); - - it('grants exactly one winner when racing to take over a stale lock', async () => { - // A dead holder's aged lock: every contender classifies it as stale and - // tries to take it over. Compare-and-delete plus post-publish - // verification must leave exactly one survivor. - const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' }); - await new Promise((resolve) => child.once('exit', resolve)); - writeAgedLock(child.pid ?? -1); - - const attempts = await Promise.all( - Array.from({ length: 20 }, () => tryAcquireUpdateInstallLock({ version: '0.5.0' })), - ); - const winners = attempts.filter((handle) => handle !== null); - expect(winners).toHaveLength(1); - await winners[0]?.release(); - }); - it('recovers from a corrupt lock file', async () => { const filePath = getUpdateInstallLockFile(); mkdirSync(dirname(filePath), { recursive: true }); writeFileSync(filePath, '{', 'utf-8'); - // Crash residue is old; a YOUNG unparseable file is treated as a publish - // still in progress (see the publish grace), so age it past the grace. - const old = new Date(Date.now() - 2 * 60 * 1000); - utimesSync(filePath, old, old); - - const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - - expect(lock).not.toBeNull(); - await lock?.release(); - }); - - it('treats a young unparseable lock as a publish in progress', async () => { - // The exclusive-create fallback (filesystems without hard links) is - // observable between create and write; sweeping that window would break - // exclusivity, so young unparseable content is NOT stale. - const filePath = getUpdateInstallLockFile(); - mkdirSync(dirname(filePath), { recursive: true }); - writeFileSync(filePath, '{', 'utf-8'); - - const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - - expect(lock).toBeNull(); - }); - - it('acquires, excludes and releases on filesystems without hard-link support', async () => { - fsMocks.linkError = 'ENOTSUP'; - - const first = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - expect(first).not.toBeNull(); - expect(await tryAcquireUpdateInstallLock({ version: '0.5.0' })).toBeNull(); - - await first?.release(); - const again = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - expect(again).not.toBeNull(); - await again?.release(); - }); - - it('grants exactly one winner under concurrent exclusive-create publishes', async () => { - fsMocks.linkError = 'ENOTSUP'; - - const attempts = await Promise.all( - Array.from({ length: 20 }, () => tryAcquireUpdateInstallLock({ version: '0.5.0' })), - ); - const winners = attempts.filter((handle) => handle !== null); - expect(winners).toHaveLength(1); - await winners[0]?.release(); - }); - - it('takes over a stale lock without hard-link support', async () => { - fsMocks.linkError = 'ENOTSUP'; - const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' }); - await new Promise((resolve) => child.once('exit', resolve)); - writeAgedLock(child.pid ?? -1); - - const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - - expect(lock).not.toBeNull(); - await lock?.release(); - }); - - function writeAgedLock(pid: number): void { - const filePath = getUpdateInstallLockFile(); - mkdirSync(dirname(filePath), { recursive: true }); - writeFileSync( - filePath, - `${JSON.stringify({ - version: '0.5.0', - pid, - startedAt: new Date(Date.now() - 60 * 60 * 1000).toISOString(), - })}\n`, - 'utf-8', - ); - } - - it('does not treat an aged lock as stale while its holder process is alive', async () => { - // The holder is this very test process — guaranteed alive. A long native - // download must survive past the 30-minute age threshold. - writeAgedLock(process.pid); - - const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - - expect(lock).toBeNull(); - }); - - it('sweeps an aged lock whose holder process is gone', async () => { - const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' }); - await new Promise((resolve) => child.once('exit', resolve)); - writeAgedLock(child.pid ?? -1); - - const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); - - expect(lock).not.toBeNull(); - await lock?.release(); - }); - - it('sweeps a young lock whose holder process is gone', async () => { - // A killed holder skips its finally and never releases: the dead pid must - // make the lock stale immediately, not after the 30-minute threshold. - const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' }); - await new Promise((resolve) => child.once('exit', resolve)); - const filePath = getUpdateInstallLockFile(); - mkdirSync(dirname(filePath), { recursive: true }); - writeFileSync( - filePath, - `${JSON.stringify({ - version: '0.5.0', - pid: child.pid ?? -1, - startedAt: new Date().toISOString(), - })}\n`, - 'utf-8', - ); const lock = await tryAcquireUpdateInstallLock({ version: '0.5.0' }); diff --git a/apps/kimi-code/test/cli/update/native-manifest.test.ts b/apps/kimi-code/test/cli/update/native-manifest.test.ts deleted file mode 100644 index 3c4df548f..000000000 --- a/apps/kimi-code/test/cli/update/native-manifest.test.ts +++ /dev/null @@ -1,152 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; - -import { - fetchNativeReleaseManifest, - nativeBinaryUrl, - nativeManifestUrl, - selectPlatformEntry, -} from '#/cli/update/native-manifest'; -import { kimiCodeCdnBinariesBase } from '#/constant/app'; - -const VERSION = '0.7.0'; - -function mockFetch(response: { - readonly ok: boolean; - readonly status: number; - readonly body?: string; -}): typeof fetch { - return vi.fn(async () => ({ - ok: response.ok, - status: response.status, - text: async () => response.body ?? '', - })) as unknown as typeof fetch; -} - -const MANIFEST_BODY = JSON.stringify({ - version: VERSION, - tag: `@moonshot-ai/kimi-code@${VERSION}`, - platforms: { - 'win32-x64': { - filename: `kimi-code-win32-x64.zip`, - checksum: 'a'.repeat(64), - }, - 'darwin-arm64': { - filename: `kimi-code-darwin-arm64.zip`, - checksum: 'b'.repeat(64), - }, - }, -}); - -describe('fetchNativeReleaseManifest', () => { - it('fetches and parses the manifest for the given version', async () => { - const f = mockFetch({ ok: true, status: 200, body: MANIFEST_BODY }); - const manifest = await fetchNativeReleaseManifest(VERSION, f); - expect(manifest.version).toBe(VERSION); - expect(Object.keys(manifest.platforms)).toEqual(['win32-x64', 'darwin-arm64']); - expect(f).toHaveBeenCalledWith( - nativeManifestUrl(VERSION), - expect.objectContaining({ signal: expect.any(AbortSignal) }), - ); - }); - - it('ignores unknown fields (lenient parsing)', async () => { - const body = JSON.stringify({ - version: VERSION, - platforms: {}, - futureField: { nested: true }, - }); - const manifest = await fetchNativeReleaseManifest(VERSION, mockFetch({ ok: true, status: 200, body })); - expect(manifest.version).toBe(VERSION); - }); - - it('rejects a non-semver version argument before hitting the network', async () => { - const f = mockFetch({ ok: true, status: 200, body: MANIFEST_BODY }); - await expect(fetchNativeReleaseManifest('nope', f)).rejects.toThrow(/invalid semver/); - expect(f).not.toHaveBeenCalled(); - }); - - it('rejects a manifest served for a different release', async () => { - // A stale/mispublished endpoint answering with another version's manifest - // must not apply that release's checksums to this version's binary. - const body = JSON.stringify({ version: '0.9.9', platforms: {} }); - await expect( - fetchNativeReleaseManifest(VERSION, mockFetch({ ok: true, status: 200, body })), - ).rejects.toThrow(/0\.9\.9/); - }); - - it('throws on non-2xx', async () => { - await expect( - fetchNativeReleaseManifest(VERSION, mockFetch({ ok: false, status: 404 })), - ).rejects.toThrow(/HTTP 404/); - }); - - it('throws on a malformed checksum', async () => { - const body = JSON.stringify({ - version: VERSION, - platforms: { 'win32-x64': { filename: 'kimi-code-win32-x64.zip', checksum: 'xyz' } }, - }); - await expect( - fetchNativeReleaseManifest(VERSION, mockFetch({ ok: true, status: 200, body })), - ).rejects.toThrow(); - }); - - it('propagates fetch errors', async () => { - const f = vi.fn(async () => { - throw new Error('network down'); - }) as unknown as typeof fetch; - await expect(fetchNativeReleaseManifest(VERSION, f)).rejects.toThrow(/network down/); - }); - - it('rejects when the response body stalls past the request timeout', async () => { - vi.useFakeTimers(); - try { - const f = vi.fn(async (_input: string | URL, init?: RequestInit) => ({ - ok: true, - status: 200, - // Headers arrive, then the body stalls; only the timeout can end this. - text: async () => - new Promise<string>((_, reject) => { - init?.signal?.addEventListener('abort', () => { - reject(new Error('aborted')); - }, { once: true }); - }), - })) as unknown as typeof fetch; - const promise = fetchNativeReleaseManifest(VERSION, f); - const assertion = expect(promise).rejects.toThrow(/aborted/); - await vi.advanceTimersByTimeAsync(11_000); - await assertion; - } finally { - vi.useRealTimers(); - } - }); -}); - -describe('selectPlatformEntry', () => { - const manifest = { - version: VERSION, - platforms: { - 'win32-x64': { filename: 'kimi-code-win32-x64.zip', checksum: 'a'.repeat(64) }, - }, - }; - - it('returns the entry matching platform-arch', () => { - expect(selectPlatformEntry(manifest, 'win32', 'x64')).toEqual( - manifest.platforms['win32-x64'], - ); - }); - - it('throws when the platform is missing', () => { - expect(() => selectPlatformEntry(manifest, 'linux', 'arm64')).toThrow( - /linux-arm64 not found/, - ); - }); -}); - -describe('url helpers', () => { - it('builds the manifest and binary URLs from the binaries base', () => { - expect(nativeManifestUrl(VERSION)).toBe(`${kimiCodeCdnBinariesBase()}/${VERSION}/manifest.json`); - expect(nativeBinaryUrl(VERSION, 'kimi-code-win32-x64.zip')).toBe( - `${kimiCodeCdnBinariesBase()}/${VERSION}/kimi-code-win32-x64.zip`, - ); - }); -}); diff --git a/apps/kimi-code/test/cli/update/native-stage.test.ts b/apps/kimi-code/test/cli/update/native-stage.test.ts deleted file mode 100644 index 97641fc66..000000000 --- a/apps/kimi-code/test/cli/update/native-stage.test.ts +++ /dev/null @@ -1,815 +0,0 @@ -import { createHash } from 'node:crypto'; -import { mkdtemp, readdir, readFile, rm, stat, utimes, writeFile } from 'node:fs/promises'; -import { tmpdir } from 'node:os'; -import { join } from 'node:path'; - -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; - -import { nativeBinaryUrl, nativeManifestUrl } from '#/cli/update/native-manifest'; -import { - promoteStagedUpdateToManual, - readStagedNativeUpdate, - stagedExePath, - stageNativeUpdate, -} from '#/cli/update/native-stage'; -import { getNativeStagedStateFile, getNativeStagingDir } from '#/utils/paths'; - -const fsMocks = vi.hoisted(() => ({ - /** Records chmod/rename calls (path-based) so tests can assert ordering. */ - calls: [] as Array<{ readonly op: 'chmod' | 'rename'; readonly path: string; readonly dst?: string }>, - /** When > 0, the next open() wraps its handle so the first write is short. */ - shortWriteBudget: 0, -})); - -vi.mock('node:fs/promises', async (importOriginal) => { - const actual = await importOriginal<typeof import('node:fs/promises')>(); - return { - ...actual, - chmod: async ( - path: Parameters<typeof actual.chmod>[0], - mode: Parameters<typeof actual.chmod>[1], - ) => { - fsMocks.calls.push({ op: 'chmod', path: String(path) }); - return actual.chmod(path, mode); - }, - rename: async ( - src: Parameters<typeof actual.rename>[0], - dst: Parameters<typeof actual.rename>[1], - ) => { - fsMocks.calls.push({ op: 'rename', path: String(src), dst: String(dst) }); - return actual.rename(src, dst); - }, - open: async ( - path: Parameters<typeof actual.open>[0], - flags: Parameters<typeof actual.open>[1], - mode: Parameters<typeof actual.open>[2], - ) => { - const handle = await actual.open(path, flags, mode); - if (fsMocks.shortWriteBudget <= 0) return handle; - fsMocks.shortWriteBudget -= 1; - let truncated = false; - return { - // FileHandle methods live on the prototype, so delegate explicitly. - write: async ( - buffer: Buffer, - offset?: number | null, - length?: number | null, - position?: number | null, - ) => { - const off = offset ?? 0; - const len = length ?? buffer.length - off; - // The first write persists only half the requested bytes. - const effectiveLen = !truncated && len > 1 ? Math.floor(len / 2) : len; - truncated = true; - const result = await handle.write(buffer, off, effectiveLen, position ?? null); - return { bytesWritten: result.bytesWritten, buffer: result.buffer }; - }, - close: () => handle.close(), - }; - }, - }; -}); - -const VERSION = '0.7.0'; -const PAYLOAD = Buffer.from('fake-sea-binary-payload'); -// The CDN serves the bare platform binary; the manifest checksum is its sha256. -const BINARY_FILENAME = 'kimi-code-linux-x64'; - -function sha256Hex(data: Buffer): string { - return createHash('sha256').update(data).digest('hex'); -} - -/** Write a staging artifact old enough for the orphan sweep to reap it. */ -async function agedOrphan(path: string, content: string | Buffer): Promise<void> { - await writeFile(path, content); - const old = new Date(Date.now() - 2 * 60 * 60 * 1000); - await utimes(path, old, old); -} - -interface MockCdnOptions { - readonly version?: string; - readonly payload: Buffer; - readonly checksum?: string; -} - -function mockCdnFetch(options: MockCdnOptions): typeof fetch { - const version = options.version ?? VERSION; - const manifestBody = JSON.stringify({ - version, - tag: `v${version}`, - platforms: { - 'linux-x64': { - filename: BINARY_FILENAME, - checksum: options.checksum ?? sha256Hex(options.payload), - }, - }, - }); - return vi.fn(async (input: string | URL) => { - const url = String(input); - if (url === nativeManifestUrl(version)) { - return { ok: true, status: 200, text: async () => manifestBody, body: null }; - } - if (url === nativeBinaryUrl(version, BINARY_FILENAME)) { - return { - ok: true, - status: 200, - text: async (): Promise<string> => '', - headers: { - get: (name: string): string | null => - name === 'content-length' ? String(options.payload.length) : null, - }, - body: [options.payload], - }; - } - return { ok: false, status: 404, text: async () => '', body: null }; - }) as unknown as typeof fetch; -} - -describe('stageNativeUpdate', () => { - let workDir: string; - let exePath: string; - - beforeEach(async () => { - workDir = await mkdtemp(join(tmpdir(), 'kimi-stage-test-')); - exePath = join(workDir, 'bin', 'kimi'); - fsMocks.calls.length = 0; - fsMocks.shortWriteBudget = 0; - }); - - afterEach(async () => { - await rm(workDir, { recursive: true, force: true }); - }); - - it('downloads, verifies and records the staged metadata', async () => { - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - - expect(result.status).toBe('staged'); - expect(result.staged).toMatchObject({ - version: VERSION, - target: 'linux-x64', - sha256: sha256Hex(PAYLOAD), - exeSize: PAYLOAD.length, - }); - // The published exe name carries a unique per-worker infix: a staged - // executable is never replaced once published, so the pathname a swap - // validates at claim time is stable. - expect(result.staged.exeFileName).toMatch(/^kimi-0\.7\.0\.\d+\.\d+\.\d+$/); - - const stagedOnDisk = await readStagedNativeUpdate(exePath); - expect(stagedOnDisk).toEqual(result.staged); - const exeBytes = await readFile(stagedExePath(exePath, result.staged)); - expect(exeBytes.equals(PAYLOAD)).toBe(true); - // The .part intermediate is gone once the download was promoted. - const leftovers = (await readdir(getNativeStagingDir(exePath))).filter((entry) => - entry.endsWith('.part'), - ); - expect(leftovers).toEqual([]); - }); - - it('marks the staged exe executable', async () => { - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - const info = await stat(stagedExePath(exePath, result.staged)); - expect(info.mode & 0o111).not.toBe(0); - }); - - it('records the manual marker when the stage answers an explicit upgrade', async () => { - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - manual: true, - }); - expect(result.staged.manual).toBe(true); - // And it round-trips through the on-disk metadata. - expect((await readStagedNativeUpdate(exePath))?.manual).toBe(true); - }); - - it('makes the download executable before publishing it at the staged name', async () => { - // A concurrent swap may move the staged exe into place the instant it - // appears at its published name, so the chmod must land on the private - // .part file first — a later chmod could hit an already-moved path. - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - const stagedExe = stagedExePath(exePath, result.staged); - const chmodCall = fsMocks.calls.find( - (call) => call.op === 'chmod' && call.path.endsWith('.part'), - ); - const publishCall = fsMocks.calls.find( - (call) => call.op === 'rename' && call.dst === stagedExe, - ); - if (chmodCall === undefined || publishCall === undefined) { - throw new Error('expected chmod(.part) and rename(.part → staged) calls'); - } - // The chmod lands on the very .part file that gets published, before it. - expect(publishCall.path).toBe(chmodCall.path); - expect(fsMocks.calls.indexOf(chmodCall)).toBeLessThan( - fsMocks.calls.indexOf(publishCall), - ); - }); - - it('reports download progress with the Content-Length total', async () => { - const progress: Array<readonly [number, number | null]> = []; - await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - onProgress: (downloaded, total) => { - progress.push([downloaded, total]); - }, - }); - // One frame per chunk; the mock stream delivers the payload in one piece. - expect(progress).toEqual([[PAYLOAD.length, PAYLOAD.length]]); - }); - - it('aborts a stalled download after the idle timeout', async () => { - const manifestBody = JSON.stringify({ - version: VERSION, - platforms: { - 'linux-x64': { filename: BINARY_FILENAME, checksum: 'a'.repeat(64) }, - }, - }); - const fetchImpl = vi.fn(async (input: string | URL, init?: RequestInit) => { - const url = String(input); - if (url === nativeManifestUrl(VERSION)) { - return { ok: true, status: 200, text: async () => manifestBody, body: null }; - } - if (url === nativeBinaryUrl(VERSION, BINARY_FILENAME)) { - const signal = init?.signal; - const body = (async function* (): AsyncGenerator<Buffer> { - yield Buffer.from('first-chunk'); - // Stall forever — only the idle timeout's abort can end this. - await new Promise((_, reject) => { - signal?.addEventListener('abort', () => { - reject(signal.reason instanceof Error ? signal.reason : new Error('aborted')); - }, { once: true }); - }); - })(); - return { - ok: true, - status: 200, - text: async (): Promise<string> => '', - headers: { get: (): string | null => null }, - body, - }; - } - return { ok: false, status: 404, text: async (): Promise<string> => '', body: null }; - }) as unknown as typeof fetch; - - // Real timers with a 50 ms test override — fake timers interact badly - // with async-generator suspension, so the idle timeout is injectable. - await expect( - stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl, - idleTimeoutMs: 50, - }), - ).rejects.toThrow(/stalled/); - // The failed attempt cleans up after itself. - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - }); - - it('short-circuits when the same version is already staged', async () => { - const firstFetch = mockCdnFetch({ payload: PAYLOAD }); - await stageNativeUpdate({ version: VERSION, exePath, platform: 'linux', arch: 'x64', fetchImpl: firstFetch }); - - const secondFetch = mockCdnFetch({ payload: PAYLOAD }); - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: secondFetch, - }); - - expect(result.status).toBe('already-staged'); - expect(secondFetch).not.toHaveBeenCalled(); - }); - - it('promotes an auto-staged payload to manual when an explicit upgrade adopts it', async () => { - // The passive downloader staged the version first (no manual marker). - await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - manual: true, - }); - - expect(result.status).toBe('already-staged'); - expect(result.staged.manual).toBe(true); - // The promotion persisted to the on-disk metadata. - expect((await readStagedNativeUpdate(exePath))?.manual).toBe(true); - }); - - it('re-stages when the staged exe is corrupted at the same size', async () => { - const first = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - // Same-size corruption after the download: the metadata still validates - // (size matches), but the bytes no longer hash to the recorded checksum. - await writeFile(stagedExePath(exePath, first.staged), Buffer.alloc(PAYLOAD.length)); - // Size-only readers still see the stage as valid… - expect(await readStagedNativeUpdate(exePath)).not.toBeNull(); - - const secondFetch = mockCdnFetch({ payload: PAYLOAD }); - const second = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: secondFetch, - }); - - // …but adoption re-verifies the digest, so the payload is re-downloaded - // and published under a NEW generation name (a published exe is never - // replaced — the damaged one is left for the orphan cleanup). - expect(second.status).toBe('staged'); - expect(secondFetch).toHaveBeenCalled(); - expect(second.staged.exeFileName).not.toBe(first.staged.exeFileName); - const repaired = await readFile(stagedExePath(exePath, second.staged)); - expect(repaired.equals(PAYLOAD)).toBe(true); - }); - - it('re-stages when the staged exe went missing', async () => { - const first = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - // The metadata stays but the exe is deleted → not trustworthy, re-stage. - await rm(stagedExePath(exePath, first.staged)); - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - - const second = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(second.status).toBe('staged'); - }); - - it('keeps the previous staged record when the superseding download fails', async () => { - await stageNativeUpdate({ - version: '0.6.0', - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ version: '0.6.0', payload: Buffer.from('old-payload') }), - }); - - // The superseding download fails verification. The old record must - // survive: deleting it before the replacement is ready could remove a - // concurrent worker's freshly published record, and here it would lose - // a still-valid staged update. - await expect( - stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD, checksum: 'f'.repeat(64) }), - }), - ).rejects.toThrow(/sha256 mismatch/); - - expect((await readStagedNativeUpdate(exePath))?.version).toBe('0.6.0'); - }); - - it('throws on a checksum mismatch and cleans up leftovers', async () => { - await expect( - stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD, checksum: 'f'.repeat(64) }), - }), - ).rejects.toThrow(/sha256 mismatch/); - - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - // Both the staged metadata and the .part download are gone. - await expect(stat(getNativeStagedStateFile(exePath))).rejects.toThrow(); - await expect(stat(getNativeStagingDir(exePath))).rejects.toThrow(); - }); - - it('throws when the platform is missing from the manifest', async () => { - await expect( - stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'win32', - arch: 'arm64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }), - ).rejects.toThrow(/win32-arm64 not found/); - }); - - it('rejects a traversal version before deriving any filesystem path', async () => { - const fetchImpl = mockCdnFetch({ payload: PAYLOAD }); - await expect( - stageNativeUpdate({ - version: 'x/../../kimi', - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl, - }), - ).rejects.toThrow(/invalid semver/); - expect(fetchImpl).not.toHaveBeenCalled(); - // Nothing was created anywhere. - await expect(stat(getNativeStagingDir(exePath))).rejects.toThrow(); - }); - - it('supersedes a staged older version', async () => { - const first = await stageNativeUpdate({ - version: '0.6.0', - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ version: '0.6.0', payload: Buffer.from('old-payload') }), - }); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - - expect(result.status).toBe('staged'); - expect(result.staged.version).toBe(VERSION); - // The older stage's exe is left in place (it may be claim-held by a live - // swap); an unreferenced one is reaped by a later orphan cleanup. - await expect( - stat(join(getNativeStagingDir(exePath), first.staged.exeFileName)), - ).resolves.toBeDefined(); - }); - - it('preserves the exe referenced by the current record during orphan cleanup', async () => { - const first = await stageNativeUpdate({ - version: '0.6.0', - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ version: '0.6.0', payload: Buffer.from('old-payload') }), - }); - // Age the staged exe past the orphan grace period: it is still the - // applicable update (staged.json references it until the final atomic - // write replaces the record), so the cleanup must not reap it. - const oldExe = stagedExePath(exePath, first.staged); - const old = new Date(Date.now() - 2 * 60 * 60 * 1000); - await utimes(oldExe, old, old); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(result.status).toBe('staged'); - - // Referenced at cleanup time → survives this run (a later cleanup reaps - // it once the new record has replaced the old one). - await expect(stat(oldExe)).resolves.toBeDefined(); - }); - - it('cleans orphaned staging files before downloading, preserving live swap claims', async () => { - const stagingDir = getNativeStagingDir(exePath); - const { mkdir } = await import('node:fs/promises'); - await mkdir(stagingDir, { recursive: true }); - // Orphans from interrupted earlier runs: a referenced-by-nothing exe and - // a stale .part download (aged past the orphan grace period). - await agedOrphan(join(stagingDir, 'kimi-9.9.9'), Buffer.from('orphan-exe')); - await agedOrphan(join(stagingDir, 'kimi-9.9.9.part'), Buffer.from('partial')); - // A live swap claim referencing its own staged exe must survive. - const claimExe = 'kimi-8.8.8'; - await writeFile(join(stagingDir, claimExe), Buffer.from('swap-in-progress')); - await writeFile( - join(stagingDir, 'staged.json.swap-1234'), - JSON.stringify({ exeFileName: claimExe }), - ); - // A fresh unreferenced exe is too young to be reaped: a concurrent - // worker may be about to publish its metadata. - const youngExe = 'kimi-7.7.7'; - await writeFile(join(stagingDir, youngExe), Buffer.from('just-published')); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(result.status).toBe('staged'); - - await expect(stat(join(stagingDir, 'kimi-9.9.9'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'kimi-9.9.9.part'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'staged.json.swap-1234'))).resolves.toBeDefined(); - await expect(stat(join(stagingDir, claimExe))).resolves.toBeDefined(); - await expect(stat(join(stagingDir, youngExe))).resolves.toBeDefined(); - }); - - it('retries short writes until each chunk is fully persisted', async () => { - // The first write to the .part file persists only half its bytes; the - // write loop must make up the remainder or the staged exe is truncated. - fsMocks.shortWriteBudget = 1; - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(result.status).toBe('staged'); - const exeBytes = await readFile(stagedExePath(exePath, result.staged)); - expect(exeBytes.equals(PAYLOAD)).toBe(true); - }); - - it('leaves foreign files in the staging directory alone', async () => { - const stagingDir = getNativeStagingDir(exePath); - const { mkdir } = await import('node:fs/promises'); - await mkdir(join(stagingDir, 'some-other-tool'), { recursive: true }); - await writeFile(join(stagingDir, 'user-notes.txt'), 'not ours', 'utf-8'); - await writeFile(join(stagingDir, 'some-other-tool', 'cache.bin'), 'not ours either'); - // A genuine updater-owned orphan to prove cleanup still works (aged past - // the orphan grace period). - await agedOrphan(join(stagingDir, 'kimi-9.9.9'), Buffer.from('orphan-exe')); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(result.status).toBe('staged'); - - await expect(stat(join(stagingDir, 'kimi-9.9.9'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'user-notes.txt'))).resolves.toBeDefined(); - await expect(stat(join(stagingDir, 'some-other-tool', 'cache.bin'))).resolves.toBeDefined(); - }); - - it('cleans orphans with prerelease and build-metadata versions', async () => { - const stagingDir = getNativeStagingDir(exePath); - const { mkdir } = await import('node:fs/promises'); - await mkdir(stagingDir, { recursive: true }); - await agedOrphan(join(stagingDir, 'kimi-1.2.3-rc.1'), Buffer.from('orphan')); - await agedOrphan(join(stagingDir, 'kimi-1.2.3+build.5.exe'), Buffer.from('orphan')); - await agedOrphan(join(stagingDir, 'kimi-1.2.3-rc.1.123.0.part'), Buffer.from('partial')); - // New-style published name with the unique per-worker infix. - await agedOrphan(join(stagingDir, 'kimi-4.5.6.1234.1700000000000.0'), Buffer.from('orphan')); - - const result = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - expect(result.status).toBe('staged'); - - await expect(stat(join(stagingDir, 'kimi-1.2.3-rc.1'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'kimi-1.2.3+build.5.exe'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'kimi-1.2.3-rc.1.123.0.part'))).rejects.toThrow(); - await expect(stat(join(stagingDir, 'kimi-4.5.6.1234.1700000000000.0'))).rejects.toThrow(); - }); - - it("preserves another worker's staged result when this attempt fails", async () => { - const stagingDir = getNativeStagingDir(exePath); - const exeFileName = `kimi-${VERSION}`; - const otherPayload = Buffer.from('other-worker-payload'); - const fetchImpl = vi.fn(async (input: string | URL) => { - const url = String(input); - if (url === nativeManifestUrl(VERSION)) { - const manifestBody = JSON.stringify({ - version: VERSION, - platforms: { - 'linux-x64': { filename: BINARY_FILENAME, checksum: sha256Hex(PAYLOAD) }, - }, - }); - return { ok: true, status: 200, text: async () => manifestBody, body: null }; - } - if (url === nativeBinaryUrl(VERSION, BINARY_FILENAME)) { - // A concurrent worker publishes its valid stage mid-download… - const { mkdir } = await import('node:fs/promises'); - await mkdir(stagingDir, { recursive: true }); - await writeFile(join(stagingDir, exeFileName), otherPayload); - await writeFile( - getNativeStagedStateFile(exePath), - `${JSON.stringify({ - version: VERSION, - target: 'linux-x64', - exeFileName, - sha256: sha256Hex(otherPayload), - exeSize: otherPayload.length, - stagedAt: new Date().toISOString(), - })}\n`, - ); - // …then this attempt's download fails. - return { ok: false, status: 503, text: async () => '', body: null }; - } - return { ok: false, status: 404, text: async (): Promise<string> => '', body: null }; - }) as unknown as typeof fetch; - - await expect( - stageNativeUpdate({ version: VERSION, exePath, platform: 'linux', arch: 'x64', fetchImpl }), - ).rejects.toThrow(/503/); - - // The concurrent worker's stage survives this attempt's failure cleanup. - const staged = await readStagedNativeUpdate(exePath); - expect(staged?.version).toBe(VERSION); - const bytes = await readFile(join(stagingDir, exeFileName)); - expect(bytes.equals(otherPayload)).toBe(true); - }); - - it('preserves the staged exe a live swap claim references when this attempt fails', async () => { - const stagingDir = getNativeStagingDir(exePath); - const exeFileName = `kimi-${VERSION}`; - const fetchImpl = vi.fn(async (input: string | URL) => { - const url = String(input); - if (url === nativeManifestUrl(VERSION)) { - const manifestBody = JSON.stringify({ - version: VERSION, - platforms: { - 'linux-x64': { filename: BINARY_FILENAME, checksum: sha256Hex(PAYLOAD) }, - }, - }); - return { ok: true, status: 200, text: async () => manifestBody, body: null }; - } - if (url === nativeBinaryUrl(VERSION, BINARY_FILENAME)) { - // A swap claims the stage mid-download: the metadata is renamed - // aside (invisible to the metadata check), the exe still referenced - // by the live claim. - const { mkdir } = await import('node:fs/promises'); - await mkdir(stagingDir, { recursive: true }); - await writeFile(join(stagingDir, exeFileName), PAYLOAD); - await writeFile( - join(stagingDir, 'staged.json.swap-4321'), - JSON.stringify({ exeFileName }), - ); - // …then this attempt's download fails. - return { ok: false, status: 503, text: async () => '', body: null }; - } - return { ok: false, status: 404, text: async (): Promise<string> => '', body: null }; - }) as unknown as typeof fetch; - - await expect( - stageNativeUpdate({ version: VERSION, exePath, platform: 'linux', arch: 'x64', fetchImpl }), - ).rejects.toThrow(/503/); - - // The exe owned by the live swap survives this attempt's failure cleanup. - const bytes = await readFile(join(stagingDir, exeFileName)); - expect(bytes.equals(PAYLOAD)).toBe(true); - }); -}); - -describe('promoteStagedUpdateToManual', () => { - let workDir: string; - let exePath: string; - - beforeEach(async () => { - workDir = await mkdtemp(join(tmpdir(), 'kimi-promote-test-')); - exePath = join(workDir, 'bin', 'kimi'); - }); - - afterEach(async () => { - await rm(workDir, { recursive: true, force: true }); - }); - - it('promotes the adopted record to manual', async () => { - await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - const adopted = await readStagedNativeUpdate(exePath); - if (adopted === null) throw new Error('expected a staged record'); - - await expect(promoteStagedUpdateToManual(exePath, adopted)).resolves.toBe(true); - expect((await readStagedNativeUpdate(exePath))?.manual).toBe(true); - }); - - it('refuses to promote a record the staged metadata no longer matches', async () => { - await stageNativeUpdate({ - version: '0.6.0', - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ version: '0.6.0', payload: Buffer.from('old-payload') }), - }); - const adopted = await readStagedNativeUpdate(exePath); - if (adopted === null) throw new Error('expected a staged record'); - - // A newer stage is published before the explicit upgrade's promote - // lands: the stale record must not overwrite it. - await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - - await expect(promoteStagedUpdateToManual(exePath, adopted)).resolves.toBe(false); - const current = await readStagedNativeUpdate(exePath); - expect(current?.version).toBe(VERSION); - expect(current?.manual).toBeUndefined(); - }); -}); - -describe('readStagedNativeUpdate', () => { - let workDir: string; - let exePath: string; - - beforeEach(async () => { - workDir = await mkdtemp(join(tmpdir(), 'kimi-staged-read-test-')); - exePath = join(workDir, 'bin', 'kimi'); - }); - - afterEach(async () => { - await rm(workDir, { recursive: true, force: true }); - }); - - it('returns null for malformed staged.json content', async () => { - const { mkdir } = await import('node:fs/promises'); - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - await writeFile(getNativeStagedStateFile(exePath), '{not json', 'utf-8'); - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - }); - - it('returns null when exeFileName is not a plain file name', async () => { - const { mkdir } = await import('node:fs/promises'); - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - await writeFile( - getNativeStagedStateFile(exePath), - JSON.stringify({ - version: '0.7.0', - target: 'linux-x64', - exeFileName: '../../evil', - sha256: 'a'.repeat(64), - exeSize: 42, - stagedAt: new Date().toISOString(), - }), - 'utf-8', - ); - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - }); - - it('returns null when the exe size drifted from the metadata', async () => { - const { staged } = await stageNativeUpdate({ - version: VERSION, - exePath, - platform: 'linux', - arch: 'x64', - fetchImpl: mockCdnFetch({ payload: PAYLOAD }), - }); - await writeFile(stagedExePath(exePath, staged), Buffer.alloc(PAYLOAD.length + 1)); - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - }); -}); diff --git a/apps/kimi-code/test/cli/update/native-swap.test.ts b/apps/kimi-code/test/cli/update/native-swap.test.ts deleted file mode 100644 index ec105abc4..000000000 --- a/apps/kimi-code/test/cli/update/native-swap.test.ts +++ /dev/null @@ -1,833 +0,0 @@ -import { createHash } from 'node:crypto'; -import { existsSync, writeFileSync } from 'node:fs'; -import { mkdtemp, mkdir, readdir, readFile, rename, rm, stat, utimes, writeFile } from 'node:fs/promises'; -import { tmpdir } from 'node:os'; -import { join } from 'node:path'; - -import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; - -import { readUpdateInstallState } from '#/cli/update/install-state'; -import { readStagedNativeUpdate, stagedExeFileName } from '#/cli/update/native-stage'; -import { - maybeRelaunchWithStagedNativeUpdate, - type NativeSwapDeps, -} from '#/cli/update/native-swap'; -import { KIMI_CODE_UPDATE_REEXEC_ENV } from '#/constant/app'; -import { getNativeStagedStateFile, getNativeStagingDir } from '#/utils/paths'; - -const fsMocks = vi.hoisted(() => ({ - /** When set, renames matching the predicate fail with an injected error. */ - renameBlocker: null as null | ((src: string, dst: string) => boolean), - /** When set, link() throws an error with this code (no hard-link support). */ - linkError: null as string | null, -})); - -vi.mock('node:fs/promises', async (importOriginal) => { - const actual = await importOriginal<typeof import('node:fs/promises')>(); - return { - ...actual, - rename: async ( - src: Parameters<typeof actual.rename>[0], - dst: Parameters<typeof actual.rename>[1], - ) => { - if (fsMocks.renameBlocker?.(String(src), String(dst)) === true) { - throw new Error('injected rename failure'); - } - return actual.rename(src, dst); - }, - link: async ( - src: Parameters<typeof actual.link>[0], - dst: Parameters<typeof actual.link>[1], - ) => { - if (fsMocks.linkError !== null) { - throw Object.assign(new Error('link() is not supported (mocked)'), { - code: fsMocks.linkError, - }); - } - return actual.link(src, dst); - }, - }; -}); - -const CURRENT_VERSION = '0.6.0'; -const STAGED_VERSION = '0.7.0'; -const STAGED_EXE_SIZE = 42; - -interface FakeChildHandlers { - readonly onEvent: (event: 'error' | 'exit' | 'close', cb: (...args: unknown[]) => void) => void; - readonly child: unknown; -} - -function fakeChild(options: { - readonly code?: number | null; - readonly stdout?: string; - readonly error?: Error; - readonly signal?: NodeJS.Signals | null; -}): FakeChildHandlers { - const listeners = new Map<string, (...args: unknown[]) => void>(); - const stdoutChunks: string[] = []; - const stdoutListeners: Array<(chunk: Buffer) => void> = []; - const child = { - once(event: string, cb: (...args: unknown[]) => void) { - listeners.set(event, cb); - }, - stdout: { - on(_event: 'data', cb: (chunk: Buffer) => void) { - stdoutListeners.push(cb); - }, - }, - kill: vi.fn(), - }; - queueMicrotask(() => { - if (options.error !== undefined) { - listeners.get('error')?.(options.error); - return; - } - if (options.stdout !== undefined) { - for (const cb of stdoutListeners) cb(Buffer.from(options.stdout)); - } - const code = options.code === undefined ? 0 : options.code; - const signal = options.signal ?? null; - // The smoke check listens on 'close', the re-exec waiter on 'exit'. - listeners.get('close')?.(code, signal); - listeners.get('exit')?.(code, signal); - }); - void stdoutChunks; - return { onEvent: () => {}, child }; -} - -interface SpawnCall { - readonly cmd: string; - readonly args: readonly string[]; - readonly options: Record<string, unknown>; -} - -function createSpawnMock(routes: { - readonly smokeCode?: number; - readonly smokeStdout?: string; - readonly reexecCode?: number; - readonly reexecError?: Error; - readonly reexecSignal?: NodeJS.Signals; -}): { readonly calls: SpawnCall[]; readonly spawnImpl: NativeSwapDeps['spawnImpl'] } { - const calls: SpawnCall[] = []; - const spawnImpl = ((cmd: string, args: readonly string[], options: Record<string, unknown>) => { - calls.push({ cmd, args, options }); - if (args[0] === '--version') { - return fakeChild({ - code: routes.smokeCode ?? 0, - stdout: routes.smokeStdout ?? `${STAGED_VERSION}\n`, - }).child; - } - return fakeChild({ - code: routes.reexecSignal !== undefined ? null : (routes.reexecCode ?? 0), - error: routes.reexecError, - signal: routes.reexecSignal ?? null, - }).child; - }) as unknown as NativeSwapDeps['spawnImpl']; - return { calls, spawnImpl }; -} - -async function seedStagedUpdate( - exePath: string, - version: string, - options?: { readonly manual?: boolean }, -): Promise<void> { - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const exeBytes = Buffer.alloc(STAGED_EXE_SIZE, 1); - await writeFile(join(stagingDir, stagedExeFileName(version, 'linux')), exeBytes); - await writeFile( - getNativeStagedStateFile(exePath), - `${JSON.stringify({ - version, - target: 'linux-x64', - exeFileName: stagedExeFileName(version, 'linux'), - // The swap re-verifies the staged bytes against this checksum, so the - // seed must record the payload's real sha256. - sha256: createHash('sha256').update(exeBytes).digest('hex'), - exeSize: STAGED_EXE_SIZE, - stagedAt: new Date().toISOString(), - manual: options?.manual === true ? true : undefined, - }, null, 2)}\n`, - 'utf-8', - ); -} - -function makeDeps( - exePath: string, - overrides: Partial<NativeSwapDeps> & { readonly spawnImpl: NativeSwapDeps['spawnImpl'] }, -): NativeSwapDeps { - return { - exePath, - argv: ['node', exePath, '--flag', 'value'], - env: { PATH: '/usr/bin' }, - currentVersion: CURRENT_VERSION, - isNative: true, - exitImpl: vi.fn(), - ...overrides, - }; -} - -describe('maybeRelaunchWithStagedNativeUpdate', () => { - let workDir: string; - let exePath: string; - let homeDir: string; - - beforeEach(async () => { - workDir = await mkdtemp(join(tmpdir(), 'kimi-swap-test-')); - homeDir = join(workDir, 'home'); - exePath = join(workDir, 'bin', 'kimi'); - await mkdir(join(workDir, 'bin'), { recursive: true }); - await writeFile(exePath, 'old-binary'); - vi.stubEnv('KIMI_CODE_HOME', homeDir); - fsMocks.renameBlocker = null; - fsMocks.linkError = null; - }); - - afterEach(async () => { - vi.unstubAllEnvs(); - await rm(workDir, { recursive: true, force: true }); - }); - - it('does nothing when the re-exec guard env is set', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const env = { [KIMI_CODE_UPDATE_REEXEC_ENV]: '1' }; - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, env }), - ); - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // Read-once: the guard is dropped so children of this session do not inherit it. - expect(env[KIMI_CODE_UPDATE_REEXEC_ENV]).toBeUndefined(); - // Staged files untouched for the "real" next launch. - await expect(stat(getNativeStagedStateFile(exePath))).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('does nothing when not running as a native binary', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, isNative: false }), - ); - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('does nothing when nothing is staged', async () => { - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - }); - - it('discards a staged update that is not newer than the running version', async () => { - await seedStagedUpdate(exePath, CURRENT_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - // The metadata is gone, so future launches do not retry the discard; the - // exe is left for the downloader's orphan cleanup (it may belong to a - // freshly republished stage). - await expect(stat(getNativeStagedStateFile(exePath))).rejects.toThrow(); - await expect( - stat(join(getNativeStagingDir(exePath), stagedExeFileName(CURRENT_VERSION, 'linux'))), - ).resolves.toBeDefined(); - }); - - it('discards staged metadata whose exe is missing', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - await rm(join(getNativeStagingDir(exePath), stagedExeFileName(STAGED_VERSION, 'linux'))); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('swaps in the staged exe, re-execs with the original argv and forwards the exit code', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({ reexecCode: 3 }); - const exitImpl = vi.fn(); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, exitImpl }), - ); - - expect(relaunched).toBe(true); - // Smoke check + re-exec. - expect(calls).toHaveLength(2); - expect(calls[0]?.args).toEqual(['--version']); - expect(calls[1]?.cmd).toBe(exePath); - expect(calls[1]?.args).toEqual(['--flag', 'value']); - expect((calls[1]?.options['env'] as Record<string, string>)[KIMI_CODE_UPDATE_REEXEC_ENV]).toBe('1'); - expect(calls[1]?.options['stdio']).toBe('inherit'); - expect(exitImpl).toHaveBeenCalledWith(3); - - // The exe was replaced with the staged payload; backup and staging are gone. - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - await expect(stat(`${exePath}.bak`)).rejects.toThrow(); - await expect(stat(getNativeStagedStateFile(exePath))).rejects.toThrow(); - await expect(stat(getNativeStagingDir(exePath))).rejects.toThrow(); - }); - - it('rolls back when the smoke check fails and records an install failure', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({ smokeCode: 1 }); - const exitImpl = vi.fn(); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, exitImpl }), - ); - - expect(relaunched).toBe(false); - expect(exitImpl).not.toHaveBeenCalled(); - expect(calls).toHaveLength(1); // smoke only, no re-exec - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - await expect(stat(getNativeStagedStateFile(exePath))).rejects.toThrow(); - // The exe is left for the downloader's orphan cleanup (see the - // not-newer discard test). - - const state = await readUpdateInstallState(); - expect(state.lastFailure).toMatchObject({ version: STAGED_VERSION, attempts: 1 }); - }); - - it('rolls back when the smoke output does not contain the staged version', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { spawnImpl } = createSpawnMock({ smokeStdout: '0.0.0-bogus\n' }); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - expect(relaunched).toBe(false); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('rolls back when the smoke output merely contains the staged version as a substring', async () => { - // `0.7.01` contains `0.7.0` but is a different release — a mispublished - // endpoint could serve exactly that with a matching checksum. - await seedStagedUpdate(exePath, STAGED_VERSION); - const { spawnImpl } = createSpawnMock({ smokeStdout: `${STAGED_VERSION}1\n` }); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - expect(relaunched).toBe(false); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('continues startup with the old in-memory code when the re-exec spawn fails', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { spawnImpl } = createSpawnMock({ reexecError: new Error('spawn EACCES') }); - const exitImpl = vi.fn(); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, exitImpl }), - ); - expect(relaunched).toBe(false); - expect(exitImpl).not.toHaveBeenCalled(); - // The binary on disk is already the new version; the next launch picks it up. - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); - - it('forwards a signal-derived nonzero exit code when the re-exec child is killed', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { spawnImpl } = createSpawnMock({ reexecSignal: 'SIGKILL' }); - const exitImpl = vi.fn(); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl, exitImpl }), - ); - expect(relaunched).toBe(true); - // 128 + 9 (SIGKILL), never a success-looking 0. - expect(exitImpl).toHaveBeenCalledWith(137); - }); - - it('restores the staged metadata when the exe cannot be moved aside', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // rename(exe → bak) fails when the in-service exe is gone. - await rm(exePath); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - // The smoke check runs before anything is moved; only the re-exec is absent. - expect(calls).toHaveLength(1); - expect(calls[0]?.args).toEqual(['--version']); - // The staged update is restored, not dropped: a later launch retries the swap. - const restored = await readStagedNativeUpdate(exePath); - expect(restored).toMatchObject({ version: STAGED_VERSION }); - await expect( - stat(join(getNativeStagingDir(exePath), stagedExeFileName(STAGED_VERSION, 'linux'))), - ).resolves.toBeDefined(); - }); - - it('restores the staged metadata without hard-link support', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // The restore publishes create-if-absent; on filesystems without hard - // links it must fall back to an exclusive create, not drop the stage. - fsMocks.linkError = 'ENOTSUP'; - // rename(exe → bak) fails when the in-service exe is gone. - await rm(exePath); - const { spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - const restored = await readStagedNativeUpdate(exePath); - expect(restored).toMatchObject({ version: STAGED_VERSION }); - }); - - it('retains the claim when the restore hits a transient error', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // rename(exe → bak) fails when the in-service exe is gone. - await rm(exePath); - // ENOSPC is not a hard-link-support error: the restore's create-if-absent - // publish fails transiently, and the claim must be RETAINED for a later - // launch's sweep — dropping it would orphan the staged exe with no newer - // stage to show for it. - fsMocks.linkError = 'ENOSPC'; - const { spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - // The state file was not published, and the claim is still there. - expect(await readStagedNativeUpdate(exePath)).toBeNull(); - const names = await readdir(getNativeStagingDir(exePath)); - expect(names.some((name) => name.startsWith('staged.json.swap-'))).toBe(true); - }); - - it('restores an aged orphaned claim and swaps it on that very launch', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // Simulate a claim left by a dead swap: the record renamed aside and aged - // past the claim-stale threshold. - const claimPath = join(getNativeStagingDir(exePath), 'staged.json.swap-99999'); - await rename(getNativeStagedStateFile(exePath), claimPath); - const old = new Date(Date.now() - 10 * 60 * 1000); - await utimes(claimPath, old, old); - - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - // The sweep restored the claim, and this launch swapped the update in. - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); - - it('defers the swap while another instance holds the swap mutex', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // A fresh swap.lock = another instance in its rename critical section. - await writeFile(join(getNativeStagingDir(exePath), 'swap.lock'), 'other-instance'); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // The stage is untouched for a later launch; the exe is untouched. - expect(await readStagedNativeUpdate(exePath)).toMatchObject({ version: STAGED_VERSION }); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('sweeps an aged swap mutex and proceeds with the swap', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const mutexPath = join(getNativeStagingDir(exePath), 'swap.lock'); - await writeFile(mutexPath, 'crash-residue'); - const old = new Date(Date.now() - 10 * 60 * 1000); - await utimes(mutexPath, old, old); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); - // The mutex was released after the swap. - await expect(stat(mutexPath)).rejects.toThrow(); - }); - - it('puts a young unparseable staged record back instead of destroying it', async () => { - // An in-flight exclusive-create publish (filesystems without hard links) - // is observable mid-write; claiming and discarding it would orphan the - // staged exe while the writer still reports success. - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const stateFile = getNativeStagedStateFile(exePath); - await writeFile(stateFile, '{', 'utf-8'); - const { spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(await readFile(stateFile, 'utf-8')).toBe('{'); - }); - - it('discards an aged unparseable staged record as crash residue', async () => { - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const stateFile = getNativeStagedStateFile(exePath); - await writeFile(stateFile, '{', 'utf-8'); - const old = new Date(Date.now() - 10 * 60 * 1000); - await utimes(stateFile, old, old); - const { spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - await expect(stat(stateFile)).rejects.toThrow(); - }); - - it('falls back to a pid-named backup when the plain .bak cannot be removed', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // A directory at `${exePath}.bak` cannot be removed via unlink → pid fallback. - await mkdir(`${exePath}.bak`); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - // The pid-named backup was cleaned after the swap; the directory is untouched. - const names = await readdir(join(workDir, 'bin')); - expect(names.toSorted()).toEqual(['kimi', 'kimi.bak']); - expect((await stat(`${exePath}.bak`)).isDirectory()).toBe(true); - }); - - it('sweeps stale backups from earlier swaps on startup', async () => { - await writeFile(`${exePath}.bak`, 'stale-backup'); - await writeFile(`${exePath}.12345.bak`, 'stale-backup'); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - await expect(stat(`${exePath}.bak`)).rejects.toThrow(); - await expect(stat(`${exePath}.12345.bak`)).rejects.toThrow(); - }); - - it('leaves foreign .bak files alone during backup cleanup', async () => { - await writeFile(`${exePath}.bak`, 'stale-backup'); - await writeFile(`${exePath}.config.bak`, 'user-backup'); - await writeFile(`${exePath}.notes.bak`, 'user-backup'); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // Only the updater-owned exact backup is swept. - await expect(stat(`${exePath}.bak`)).rejects.toThrow(); - expect(await readFile(`${exePath}.config.bak`, 'utf-8')).toBe('user-backup'); - expect(await readFile(`${exePath}.notes.bak`, 'utf-8')).toBe('user-backup'); - }); - - it('leaves every artifact alone while another instance holds a fresh swap claim', async () => { - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const claimPath = join(stagingDir, 'staged.json.swap-4242'); - await writeFile(claimPath, '{}\n', 'utf-8'); - await writeFile(`${exePath}.bak`, 'in-use-backup'); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // A mid-swap instance owns these: nothing is touched. - await expect(stat(claimPath)).resolves.toBeDefined(); - await expect(stat(`${exePath}.bak`)).resolves.toBeDefined(); - }); - - it('does not claim a newly staged update while another instance is mid-swap', async () => { - // Instance A holds a fresh claim; a downloader has since published a new - // staged.json. Claiming it here would start a second concurrent swap. - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const claimPath = join(stagingDir, 'staged.json.swap-4242'); - await writeFile(claimPath, '{}\n', 'utf-8'); - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // The staged update and the claim stay put; the launch after the - // in-flight swap ends picks the update up. - await expect(stat(getNativeStagedStateFile(exePath))).resolves.toBeDefined(); - await expect(stat(claimPath)).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('cleans up stale swap claims without touching staged exes', async () => { - const stagingDir = getNativeStagingDir(exePath); - await mkdir(stagingDir, { recursive: true }); - const exeFileName = stagedExeFileName(STAGED_VERSION, 'linux'); - const orphanedExe = join(stagingDir, exeFileName); - await writeFile(orphanedExe, Buffer.alloc(STAGED_EXE_SIZE, 1)); - const claimPath = join(stagingDir, 'staged.json.swap-4242'); - await writeFile( - claimPath, - `${JSON.stringify({ - version: STAGED_VERSION, - target: 'linux-x64', - exeFileName, - sha256: 'a'.repeat(64), - exeSize: STAGED_EXE_SIZE, - stagedAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), - }, null, 2)}\n`, - 'utf-8', - ); - // Crash residue: the claim is older than the stale window. - const past = new Date(Date.now() - 10 * 60 * 1000); - await utimes(claimPath, past, past); - - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - await expect(stat(claimPath)).rejects.toThrow(); - // The exe the claim referenced is left in place: it may belong to a - // freshly republished stage, and the downloader's orphan cleanup reaps - // it if nothing references it. - await expect(stat(orphanedExe)).resolves.toBeDefined(); - }); - - it('keeps recovery artifacts when both the swap-in rename and the rollback fail', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // Every rename INTO the install path fails: the staged exe cannot move - // in, and the backup cannot move back (transient lock, AV, …). - fsMocks.renameBlocker = (_src, dst) => dst === exePath; - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(1); // smoke check only, no re-exec - // The install path stays absent, but both recovery copies survive: the - // `.bak` IS the old exe, and the staged payload plus its claim are not - // discarded. - await expect(stat(exePath)).rejects.toThrow(); - expect(await readFile(`${exePath}.bak`, 'utf-8')).toBe('old-binary'); - const stagingDir = getNativeStagingDir(exePath); - await expect( - stat(join(stagingDir, stagedExeFileName(STAGED_VERSION, 'linux'))), - ).resolves.toBeDefined(); - await expect( - stat(join(stagingDir, `staged.json.swap-${process.pid}`)), - ).resolves.toBeDefined(); - }); - - it('keeps the exe a fresh staged.json references when sweeping a stale claim', async () => { - // A swap crashed after claiming V (stale claim residue), and a downloader - // has since re-staged V: both records reference the same version-derived - // exe name. Sweeping the claim must not delete the freshly staged exe. - await seedStagedUpdate(exePath, STAGED_VERSION); - const stagingDir = getNativeStagingDir(exePath); - const claimPath = join(stagingDir, 'staged.json.swap-4242'); - await writeFile( - claimPath, - `${JSON.stringify({ - version: STAGED_VERSION, - target: 'linux-x64', - exeFileName: stagedExeFileName(STAGED_VERSION, 'linux'), - sha256: 'a'.repeat(64), - exeSize: STAGED_EXE_SIZE, - stagedAt: new Date(Date.now() - 10 * 60 * 1000).toISOString(), - })}\n`, - 'utf-8', - ); - const past = new Date(Date.now() - 10 * 60 * 1000); - await utimes(claimPath, past, past); - - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - // The stale claim is swept, the fresh stage survives and is swapped in. - await expect(stat(claimPath)).rejects.toThrow(); - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); // smoke check + re-exec - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); - - it('discards a staged update whose exe fails the recorded checksum', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // Same size, different bytes — post-download on-disk damage. - const stagingDir = getNativeStagingDir(exePath); - const stagedExe = join(stagingDir, stagedExeFileName(STAGED_VERSION, 'linux')); - await writeFile(stagedExe, Buffer.alloc(STAGED_EXE_SIZE, 2)); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // The corrupt stage's metadata is discarded so a later cycle re-stages - // it; the exe is left for the downloader's orphan cleanup, and the - // running exe is never touched. - await expect(stat(getNativeStagedStateFile(exePath))).rejects.toThrow(); - await expect(stat(stagedExe)).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('leaves a staged update in place when automatic updates are disabled by env', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { - spawnImpl, - env: { PATH: '/usr/bin', KIMI_CODE_NO_AUTO_UPDATE: '1' }, - }), - ); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - // The payload stays staged for a later launch without the opt-out; the - // running exe is untouched. - await expect(stat(getNativeStagedStateFile(exePath))).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('applies a manually staged update even when automatic updates are disabled by env', async () => { - // The opt-out targets automatic updates; an explicit `kimi upgrade` - // stages with manual: true and must still apply. - await seedStagedUpdate(exePath, STAGED_VERSION, { manual: true }); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { - spawnImpl, - env: { PATH: '/usr/bin', KIMI_CODE_NO_AUTO_UPDATE: '1' }, - }), - ); - - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); // smoke check + re-exec - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); - - it('leaves an automatic stage in place when auto_install is disabled in the tui config', async () => { - await mkdir(homeDir, { recursive: true }); - await writeFile(join(homeDir, 'tui.toml'), '[upgrade]\nauto_install = false\n', 'utf-8'); - await seedStagedUpdate(exePath, STAGED_VERSION); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - expect(calls).toHaveLength(0); - await expect(stat(getNativeStagedStateFile(exePath))).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('applies a manual stage even when auto_install is disabled in the tui config', async () => { - await mkdir(homeDir, { recursive: true }); - await writeFile(join(homeDir, 'tui.toml'), '[upgrade]\nauto_install = false\n', 'utf-8'); - await seedStagedUpdate(exePath, STAGED_VERSION, { manual: true }); - const { calls, spawnImpl } = createSpawnMock({}); - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(true); - expect(calls).toHaveLength(2); // smoke check + re-exec - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); - - it('does not overwrite a concurrently published stage when restoring the claim', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // The exe move (step 2) fails. - fsMocks.renameBlocker = (src) => src === exePath; - const v2 = '0.8.0'; - const spawnImpl = ((cmd: string, args: readonly string[]) => { - if (args[0] === '--version') { - // Mid-smoke: a downloader publishes a NEWER stage (the state-file - // path is free — we claimed the older one). - const stagingDir = getNativeStagingDir(exePath); - const v2Exe = stagedExeFileName(v2, 'linux'); - writeFileSync(join(stagingDir, v2Exe), 'newer-binary'); - writeFileSync( - getNativeStagedStateFile(exePath), - `${JSON.stringify({ - version: v2, - target: 'linux-x64', - exeFileName: v2Exe, - sha256: 'b'.repeat(64), - exeSize: Buffer.byteLength('newer-binary'), - stagedAt: new Date().toISOString(), - })}\n`, - ); - return fakeChild({ code: 0, stdout: `${STAGED_VERSION}\n` }).child; - } - return fakeChild({ code: 0 }).child; - }) as unknown as NativeSwapDeps['spawnImpl']; - const relaunched = await maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl })); - - expect(relaunched).toBe(false); - // The newer stage survived; the older claim's metadata was discarded - // instead of clobbering it (its exe is left for the downloader's orphan - // cleanup), and the running exe never moved. - const staged = await readStagedNativeUpdate(exePath); - expect(staged?.version).toBe(v2); - await expect( - stat(join(getNativeStagingDir(exePath), stagedExeFileName(STAGED_VERSION, 'linux'))), - ).resolves.toBeDefined(); - expect(await readFile(exePath, 'utf-8')).toBe('old-binary'); - }); - - it('stamps the claim with a fresh mtime so a concurrent launch does not misread it as stale', async () => { - await seedStagedUpdate(exePath, STAGED_VERSION); - // The metadata may have been staged long before this launch (background - // download finished hours ago); rename alone would keep that old mtime. - const longAgo = new Date(Date.now() - 10 * 60 * 1000); - await utimes(getNativeStagedStateFile(exePath), longAgo, longAgo); - - // Instance A: park inside the smoke check, holding the claim mid-swap. - let releaseSmoke!: () => void; - const smokeGate = new Promise<void>((resolve) => { - releaseSmoke = resolve; - }); - const spawnImplA = ((cmd: string, args: readonly string[]) => { - if (args[0] !== '--version') return fakeChild({ code: 0 }).child; // re-exec - const listeners = new Map<string, (...args: unknown[]) => void>(); - const stdoutListeners: Array<(chunk: Buffer) => void> = []; - const child = { - once(event: string, cb: (...args: unknown[]) => void) { - listeners.set(event, cb); - }, - stdout: { - on(_event: 'data', cb: (chunk: Buffer) => void) { - stdoutListeners.push(cb); - }, - }, - kill: vi.fn(), - }; - const emitSmokeSuccess = (): void => { - for (const cb of stdoutListeners) cb(Buffer.from(`${STAGED_VERSION}\n`)); - listeners.get('close')?.(0, null); - listeners.get('exit')?.(0, null); - }; - queueMicrotask(() => { - void smokeGate.then(emitSmokeSuccess); - }); - return child; - }) as unknown as NativeSwapDeps['spawnImpl']; - const promiseA = maybeRelaunchWithStagedNativeUpdate(makeDeps(exePath, { spawnImpl: spawnImplA })); - - // Wait until A holds the claim. - const stagingDir = getNativeStagingDir(exePath); - const claimPath = join(stagingDir, `staged.json.swap-${process.pid}`); - await vi.waitFor(() => { - expect(existsSync(claimPath)).toBe(true); - }); - // The claim carries the claim time, not the staged file's old mtime. - expect((await stat(claimPath)).mtimeMs).toBeGreaterThan(Date.now() - 60_000); - - // Instance B: its sweep must treat A's claim as live and touch nothing. - const { calls: callsB, spawnImpl: spawnImplB } = createSpawnMock({}); - const relaunchedB = await maybeRelaunchWithStagedNativeUpdate( - makeDeps(exePath, { spawnImpl: spawnImplB }), - ); - expect(relaunchedB).toBe(false); - expect(callsB).toHaveLength(0); - await expect(stat(claimPath)).resolves.toBeDefined(); - await expect( - stat(join(stagingDir, stagedExeFileName(STAGED_VERSION, 'linux'))), - ).resolves.toBeDefined(); - - // A finishes the swap unharmed. - releaseSmoke(); - await expect(promiseA).resolves.toBe(true); - const newExe = await readFile(exePath); - expect(newExe.equals(Buffer.alloc(STAGED_EXE_SIZE, 1))).toBe(true); - }); -}); diff --git a/apps/kimi-code/test/cli/update/preflight.test.ts b/apps/kimi-code/test/cli/update/preflight.test.ts index fcc57ad6b..3382d622e 100644 --- a/apps/kimi-code/test/cli/update/preflight.test.ts +++ b/apps/kimi-code/test/cli/update/preflight.test.ts @@ -1,4 +1,5 @@ import type * as ChildProcess from 'node:child_process'; +import { spawnSync } from 'node:child_process'; import { EventEmitter } from 'node:events'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; @@ -9,7 +10,7 @@ import { readUpdateInstallState, writeUpdateInstallState, } from '#/cli/update/install-state'; -import { installCommandFor, runUpdatePreflight } from '#/cli/update/preflight'; +import { runUpdatePreflight, spawnForSource } from '#/cli/update/preflight'; import { promptForInstallChoice } from '#/cli/update/prompt'; import type * as PromptModule from '#/cli/update/prompt'; import { refreshUpdateCache } from '#/cli/update/refresh'; @@ -23,7 +24,6 @@ import { type UpdateManifest, } from '#/cli/update/types'; import type { TuiConfig } from '#/tui/config'; -import { refreshKimiRegion } from '#/utils/region'; const mocks = vi.hoisted(() => ({ readUpdateCache: vi.fn(), @@ -238,10 +238,6 @@ describe('runUpdatePreflight', () => { // regardless of the host environment (the flag bypasses batch holds). // Tests that exercise the bypass opt back in with `vi.stubEnv(..., '1')`. vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', ''); - // Pin the region to cn so address assertions don't follow the dev - // machine's own login/marker state; global tests override below. - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.com'); - refreshKimiRegion(); mocks.readUpdateInstallState.mockResolvedValue(emptyUpdateInstallState()); mocks.writeUpdateInstallState.mockResolvedValue(undefined); mocks.loadTuiConfig.mockResolvedValue(tuiConfig()); @@ -254,7 +250,7 @@ describe('runUpdatePreflight', () => { mocks.resolveCommandPath.mockImplementation((cmd: string) => cmd); }); - afterEach(() => { vi.clearAllMocks(); vi.unstubAllEnvs(); refreshKimiRegion(); }); + afterEach(() => { vi.clearAllMocks(); vi.unstubAllEnvs(); }); it('skips all update work when KIMI_CODE_NO_AUTO_UPDATE is set', async () => { vi.stubEnv('KIMI_CODE_NO_AUTO_UPDATE', '1'); @@ -504,7 +500,7 @@ describe('runUpdatePreflight', () => { expect(mocks.spawn).not.toHaveBeenCalled(); }); - it('native: self-spawns the staged downloader sub-command', async () => { + it('native on darwin: spawns bash -c with pipefail-guarded curl|bash', async () => { disableAutoInstall(); mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); @@ -514,65 +510,37 @@ describe('runUpdatePreflight', () => { const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: 'darwin' }); try { - const { stdout, options } = captureOutput(); - await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('exit'); - expect(mocks.spawn).toHaveBeenCalledWith( - process.execPath, - ['__update_download', '0.5.0', '--manual'], - expect.objectContaining({ stdio: 'inherit' }), - ); - expect(stdout.join('')).toContain('Updated @moonshot-ai/kimi-code to 0.5.0'); + const { options } = captureOutput(); + await runUpdatePreflight('0.4.0', options); + const call = mocks.spawn.mock.calls[0]; + expect(call?.[0]).toBe('bash'); + expect(call?.[2]).toEqual({ stdio: 'inherit' }); + const [flag, script] = call?.[1] as string[]; + expect(flag).toBe('-c'); + // pipefail must come before the pipeline so a failed `curl` is not masked + // by the trailing `bash` exiting 0 (see "surfaces a failed curl" below). + expect(script).toContain('set -o pipefail'); + expect(script).toContain('curl -fsSL https://code.kimi.com/kimi-code/install.sh'); + expect(script).toContain('| bash'); } finally { Object.defineProperty(process, 'platform', { value: originalPlatform }); } }); - it('native on win32: auto-installs via the staged downloader sub-command', async () => { - disableAutoInstall(); + it('native on win32: prints manual powershell command, does not spawn', async () => { mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); mocks.detectInstallSource.mockResolvedValue('native'); - mocks.promptForInstallChoice.mockResolvedValue('install'); - mockSpawnExit(0); const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: 'win32' }); try { const { stdout, options } = captureOutput(); - await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('exit'); - expect(mocks.spawn).toHaveBeenCalledWith( - process.execPath, - ['__update_download', '0.5.0', '--manual'], - expect.objectContaining({ stdio: 'inherit' }), - ); - expect(stdout.join('')).toContain('Updated @moonshot-ai/kimi-code to 0.5.0'); - expect(stdout.join('')).not.toContain('Auto-update is not supported'); - } finally { - Object.defineProperty(process, 'platform', { value: originalPlatform }); - } - }); - - it('global region: derives install commands and site links from the .ai profile', async () => { - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.ai'); - refreshKimiRegion(); - mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - const originalPlatform = process.platform; - Object.defineProperty(process, 'platform', { value: 'win32' }); - try { - // Native updates self-spawn the staged downloader silently, so the - // region surface there is the manual install command text. - expect(installCommandFor('native', '0.5.0', 'win32')).toBe( - 'irm https://code.kimi.ai/kimi-code/install.ps1 | iex', - ); - - mocks.detectInstallSource.mockResolvedValue('homebrew'); - const brew = captureOutput(); - await expect(runUpdatePreflight('0.4.0', brew.options)).resolves.toBe('continue'); - expect(brew.stdout.join('')).toContain('https://www.kimi.ai/code'); + await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('continue'); + expect(stdout.join('')).toContain('irm https://code.kimi.com/kimi-code/install.ps1 | iex'); + expect(promptForInstallChoice).not.toHaveBeenCalled(); expect(mocks.spawn).not.toHaveBeenCalled(); } finally { Object.defineProperty(process, 'platform', { value: originalPlatform }); - refreshKimiRegion(); } }); @@ -730,71 +698,6 @@ describe('runUpdatePreflight', () => { } }); - it('native: retries the background install when an old active record has no live lock', async () => { - // Orphaned `active`: older than the spawn grace window and the lock is - // free (beforeEach default) ⇒ the previous downloader is gone; retry. - mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.readUpdateInstallState.mockResolvedValue(installState({ - active: { - version: '0.5.0', - source: 'native', - startedAt: new Date(Date.now() - 120_000).toISOString(), - }, - })); - mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.detectInstallSource.mockResolvedValue('native'); - mockSpawnExit(0); - const { options } = captureOutput(); - - await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('continue'); - expect(mocks.spawn).toHaveBeenCalledWith( - process.execPath, - ['__update_download', '0.5.0'], - expect.objectContaining({ detached: true, stdio: 'ignore' }), - ); - }); - - it('native: does not re-spawn while the install lock is genuinely held', async () => { - mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.readUpdateInstallState.mockResolvedValue(installState({ - active: { - version: '0.5.0', - source: 'native', - startedAt: new Date(Date.now() - 120_000).toISOString(), - }, - })); - mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.detectInstallSource.mockResolvedValue('native'); - // Lock probe fails ⇒ a downloader is actually in flight; trust it. - mocks.tryAcquireUpdateInstallLock.mockResolvedValue(null); - mockSpawnExit(0); - const { options } = captureOutput(); - - await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('continue'); - expect(mocks.spawn).not.toHaveBeenCalled(); - }); - - it('native: trusts a fresh active record within the spawn grace window', async () => { - mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.readUpdateInstallState.mockResolvedValue(installState({ - active: { - version: '0.5.0', - source: 'native', - startedAt: new Date().toISOString(), - }, - })); - mocks.refreshUpdateCache.mockResolvedValue(cacheWith('0.5.0')); - mocks.detectInstallSource.mockResolvedValue('native'); - mockSpawnExit(0); - const { options } = captureOutput(); - - await expect(runUpdatePreflight('0.4.0', options)).resolves.toBe('continue'); - expect(mocks.spawn).not.toHaveBeenCalled(); - // Inside the grace window the lock is never probed — the freshly spawned - // worker may simply not have reached its self-acquire yet. - expect(mocks.tryAcquireUpdateInstallLock).not.toHaveBeenCalled(); - }); - it('tracks and logs successful background update installs', async () => { mocks.readUpdateCache.mockResolvedValue(cacheWith('0.5.0')); mocks.readUpdateInstallState.mockResolvedValue(installState()); @@ -1276,3 +1179,23 @@ describe('runUpdatePreflight', () => { }); }); }); + +describe('spawnForSource native', () => { + // No spawn mock here — we run real bash to prove the failure contract + // end-to-end. `curl … | bash` reports only the trailing bash's exit status, + // so a curl that never connects (exit 7, empty stdin → bash exits 0) is + // masked and the update is wrongly reported as successful. `set -o pipefail` + // makes the pipeline surface curl's failure. Shadowing `curl` with a shell + // function keeps this offline and deterministic; skipped on Windows (no bash, + // and native auto-install is unsupported there anyway). + it.skipIf(process.platform === 'win32')( + 'surfaces a failed curl download as a non-zero exit', + () => { + const { cmd, args } = spawnForSource('native', '0.5.0', 'darwin'); + const script = `curl() { return 7; }\n${args[1] ?? ''}`; + const result = spawnSync(cmd, [args[0] ?? '-c', script], { encoding: 'utf8' }); + expect(result.error).toBeUndefined(); + expect(result.status).toBeGreaterThan(0); + }, + ); +}); diff --git a/apps/kimi-code/test/cli/v2-run-print.test.ts b/apps/kimi-code/test/cli/v2-run-print.test.ts index cd6bb4622..c7b76db42 100644 --- a/apps/kimi-code/test/cli/v2-run-print.test.ts +++ b/apps/kimi-code/test/cli/v2-run-print.test.ts @@ -5,13 +5,11 @@ import { join } from 'node:path'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { - AgentCron, - AgentGoal, + IAgentGoalService, IAgentLifecycleService, IAgentPermissionModeService, IAgentProfileService, IAgentPromptService, - IAgentScopeContext, IAgentTaskService, IAuthSummaryService, IBootstrapService, @@ -19,12 +17,13 @@ import { IEventBus, IFileSystemStorageService, IOAuthToolkit, + ISessionCronService, ISessionIndex, - ISessionManager, + ISessionLifecycleService, + IWorkspaceLifecycleService, ITelemetryService, - makeAgentScopeContext, type BootstrapInput, - type Event2, + type DomainEvent, } from '@moonshot-ai/agent-core-v2'; import { runV2Print } from '../../src/cli/v2/run-v2-print'; @@ -125,7 +124,7 @@ function opts(overrides: Record<string, unknown> = {}) { function makeFakeHarness() { // Native event listeners registered on the main agent's IEventBus; the turn // emits a streaming assistant delta before completing. - const eventListeners = new Set<(event: Event2<any>) => void>(); + const eventListeners = new Set<(event: DomainEvent) => void>(); const profileState: { profileName: string | undefined } = { profileName: undefined }; const agentServices = new Map<unknown, unknown>([ @@ -143,7 +142,7 @@ function makeFakeHarness() { [ IEventBus, { - subscribe: vi.fn((handler: (event: Event2<any>) => void) => { + subscribe: vi.fn((handler: (event: DomainEvent) => void) => { eventListeners.add(handler); return { dispose: () => eventListeners.delete(handler) }; }), @@ -155,7 +154,7 @@ function makeFakeHarness() { enqueue: vi.fn(async () => { // Emit a native assistant delta on the main agent bus, then complete. for (const listener of [...eventListeners]) { - listener({ type: 'assistant.delta', turnId: 1, delta: 'hello world' } as unknown as Event2<any>); + listener({ type: 'assistant.delta', turnId: 1, delta: 'hello world' } as DomainEvent); } return { launched: Promise.resolve({ @@ -167,31 +166,28 @@ function makeFakeHarness() { }, ], [IAgentTaskService, { list: vi.fn(() => []) }], - [ - IAgentScopeContext, - makeAgentScopeContext({ agentId: 'main', agentScope: 'agents/main' }), - ], + [IAgentGoalService, { createGoal: vi.fn(), getGoal: vi.fn() }], ]); - const goal = { createGoal: vi.fn(), getGoal: vi.fn() }; - const cron = { getNextFireTime: vi.fn(() => null) }; const agent = fakeScope('main', agentServices); const sessionServices = new Map<unknown, unknown>([ // drain enumerates agents; empty → no background work to wait on. + [IAgentLifecycleService, { list: vi.fn(() => []) }], + // No scheduled cron tasks → no future fire time to wait on. + [ISessionCronService, { getNextFireTime: vi.fn(() => null) }], + ]); + const session = fakeScope('ses_v2', sessionServices); + + const handlerServices = new Map<unknown, unknown>([ [ - IAgentLifecycleService, + ISessionLifecycleService, { - list: vi.fn(() => []), - handleOf: vi.fn(() => agent), - resolve: vi.fn((_context: unknown, capability: unknown) => { - if (capability === AgentGoal) return goal; - if (capability === AgentCron) return cron; - throw new Error('unexpected capability'); - }), + create: vi.fn(async () => session), + resume: vi.fn(async () => session), }, ], ]); - const session = fakeScope('ses_v2', sessionServices); + const workspace = fakeScope('wd_v2', handlerServices); const appServices = new Map<unknown, unknown>([ [ @@ -207,13 +203,10 @@ function makeFakeHarness() { }, ], [ - ISessionManager, + IWorkspaceLifecycleService, { - create: vi.fn(async () => session), - resume: vi.fn(async () => session), - get: vi.fn(() => session), - list: vi.fn(() => [session]), - } as unknown as ISessionManager, + handlerFor: vi.fn(async () => workspace), + }, ], [ ISessionIndex, @@ -262,7 +255,7 @@ function makeFakeHarness() { ], ]); const app = fakeScope('app', appServices); - return { app, agent, session, agentServices, appServices, profileState }; + return { app, agent, session, agentServices, appServices, handlerServices, profileState }; } describe('runV2Print', () => { @@ -282,7 +275,7 @@ describe('runV2Print', () => { const { app, agent, agentServices } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts() as never, '1.2.3-test', { stdout, stderr }); @@ -307,7 +300,7 @@ describe('runV2Print', () => { const { app, agent } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts({ skillsDirs: ['/skills'] }) as never, '1.2.3-test', { stdout, @@ -324,7 +317,7 @@ describe('runV2Print', () => { const { app, agent } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts() as never, '1.2.3-test', { stdout, stderr }); @@ -335,10 +328,10 @@ describe('runV2Print', () => { it('seeds explicit agent files from --agentFile and binds the --agent profile', async () => { const stdout = writer(); const stderr = writer(); - const { app, agent, appServices, agentServices } = makeFakeHarness(); + const { app, agent, appServices, agentServices, handlerServices } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print( opts({ agent: 'reviewer', agentFiles: ['/agents/reviewer.md'] }) as never, @@ -349,8 +342,10 @@ describe('runV2Print', () => { const input = mocks.bootstrap.mock.calls[0]?.[0] as BootstrapInput; expect(input.args?.agentFiles).toEqual(['/agents/reviewer.md']); - const sessions = appServices.get(ISessionManager) as { create: ReturnType<typeof vi.fn> }; - expect(sessions.create).toHaveBeenCalledWith({ + const lifecycle = handlerServices.get(ISessionLifecycleService) as { + create: ReturnType<typeof vi.fn>; + }; + expect(lifecycle.create).toHaveBeenCalledWith({ workDir: process.cwd(), additionalDirs: undefined, mainAgentBinding: { profile: 'reviewer', model: 'k2' }, @@ -368,10 +363,10 @@ describe('runV2Print', () => { ); const stdout = writer(); const stderr = writer(); - const { app, agent, appServices, agentServices } = makeFakeHarness(); + const { app, agent, appServices, agentServices, handlerServices } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts({ agentFiles: [agentFile] }) as never, '1.2.3-test', { stdout, @@ -381,8 +376,10 @@ describe('runV2Print', () => { const input = mocks.bootstrap.mock.calls[0]?.[0] as BootstrapInput; expect(input.args?.agentFiles).toEqual([agentFile]); - const sessions = appServices.get(ISessionManager) as { create: ReturnType<typeof vi.fn> }; - expect(sessions.create).toHaveBeenCalledWith({ + const lifecycle = handlerServices.get(ISessionLifecycleService) as { + create: ReturnType<typeof vi.fn>; + }; + expect(lifecycle.create).toHaveBeenCalledWith({ workDir: process.cwd(), additionalDirs: undefined, mainAgentBinding: { profile: 'file-reviewer', model: 'k2' }, @@ -394,9 +391,11 @@ describe('runV2Print', () => { it('does not materialize a main agent after fresh profile binding fails', async () => { const stdout = writer(); const stderr = writer(); - const { app, appServices } = makeFakeHarness(); - const sessions = appServices.get(ISessionManager) as { create: ReturnType<typeof vi.fn> }; - sessions.create.mockRejectedValueOnce(new Error('Unknown agent profile')); + const { app, handlerServices } = makeFakeHarness(); + const lifecycle = handlerServices.get(ISessionLifecycleService) as { + create: ReturnType<typeof vi.fn>; + }; + lifecycle.create.mockRejectedValueOnce(new Error('Unknown agent profile')); mocks.bootstrap.mockReturnValue({ app }); await expect( @@ -415,7 +414,7 @@ describe('runV2Print', () => { const { app, agent, agentServices } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await expect( runV2Print(opts({ agentFiles: [agentFile] }) as never, '1.2.3-test', { stdout, stderr }), @@ -433,7 +432,7 @@ describe('runV2Print', () => { const { app, agent } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts() as never, '1.2.3-test', { stdout, stderr }); @@ -447,7 +446,7 @@ describe('runV2Print', () => { const { app, agent } = makeFakeHarness(); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print( opts({ agent: 'reviewer', agentFiles: ['~/agents/reviewer.md'] }) as never, @@ -469,7 +468,7 @@ describe('runV2Print', () => { index.get.mockResolvedValue({ id: 'ses_1', cwd: process.cwd() }); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print(opts({ session: 'ses_1', agent: 'reviewer' }) as never, '1.2.3-test', { stdout, @@ -494,7 +493,7 @@ describe('runV2Print', () => { index.get.mockResolvedValue({ id: 'ses_1', cwd: process.cwd() }); mocks.bootstrap.mockReturnValue({ app }); - mocks.ensureMainAgent.mockResolvedValue({ agentId: 'main', generation: 1 }); + mocks.ensureMainAgent.mockResolvedValue(agent); await runV2Print( opts({ session: 'ses_1', agent: 'reviewer', model: 'new-model' }) as never, diff --git a/apps/kimi-code/test/cli/web/remote-control.test.ts b/apps/kimi-code/test/cli/web/remote-control.test.ts deleted file mode 100644 index cbad20c4c..000000000 --- a/apps/kimi-code/test/cli/web/remote-control.test.ts +++ /dev/null @@ -1,718 +0,0 @@ -import { createServer, type IncomingMessage } from 'node:http'; -import { spawn } from 'node:child_process'; -import { mkdtempSync, rmSync } from 'node:fs'; -import { mkdir, readFile, writeFile } from 'node:fs/promises'; -import { tmpdir } from 'node:os'; -import { join } from 'node:path'; - -import { - FileTokenStorage, - KIMI_CODE_PROVIDER_NAME, - resolveKimiTokenStorageName, - type TokenInfo, -} from '@moonshot-ai/kimi-code-oauth'; -import { afterEach, describe, expect, it, vi } from 'vitest'; -import { WebSocketServer, type RawData, type WebSocket } from 'ws'; - -import { - buildRemoteControlUrl, - filterForwardRequestHeaders, - formatRemoteControlOutput, - formatRemoteControlStatus, - isRemoteControlEnabled, - parseRawHttpRequest, - rewriteRemoteControlResponse, - startRemoteControl, - type RemoteControlHandle, -} from '#/cli/sub/web/remote-control'; -import { remoteControlLockPath } from '#/cli/sub/web/remote-control-lock'; - -const TOKEN: TokenInfo = { - accessToken: 'access-token', - refreshToken: 'refresh-token', - expiresAt: 0, - scope: '', - tokenType: 'Bearer', - expiresIn: 0, -}; - -const cleanups: Array<() => Promise<void> | void> = []; - -afterEach(async () => { - vi.unstubAllEnvs(); - while (cleanups.length > 0) await cleanups.pop()!(); -}); - -describe('Remote Control experimental flag', () => { - it('is off unless the per-feature env or the master switch is truthy', () => { - expect(isRemoteControlEnabled({})).toBe(false); - expect(isRemoteControlEnabled({ KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL: '0' })).toBe(false); - expect(isRemoteControlEnabled({ KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL: '1' })).toBe(true); - expect(isRemoteControlEnabled({ KIMI_CODE_EXPERIMENTAL_FLAG: 'true' })).toBe(true); - expect( - isRemoteControlEnabled({ - KIMI_CODE_EXPERIMENTAL_FLAG: '0', - KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL: 'yes', - }), - ).toBe(true); - }); -}); - -describe('Remote Control URLs', () => { - it('builds the public device entry without a local token', () => { - const url = buildRemoteControlUrl('device/one'); - expect(url).toBe( - 'https://code-rc.kimi.com/devices/device%2Fone/?rc=1&from=kimi_code_cli', - ); - expect(url).not.toContain('token'); - }); - - it('builds an encoded session deep link before the query', () => { - expect(buildRemoteControlUrl('device-1', 'session/a b')).toBe( - 'https://code-rc.kimi.com/devices/device-1/sessions/session%2Fa%20b?rc=1&from=kimi_code_cli', - ); - }); -}); - -describe('Remote Control output', () => { - const outputOptions = { - url: 'https://example.test/devices/example-device/?rc=1&from=kimi_code_cli', - localOrigin: 'http://127.0.0.1:1234', - deviceName: 'example-device', - qrCode: 'QR\n', - pngPath: '/tmp/example-qr.png', - }; - - it('keeps the full URL clickable while showing a short link and the setup contract', () => { - vi.stubEnv('FORCE_HYPERLINK', '1'); - const output = formatRemoteControlOutput(outputOptions); - const url = outputOptions.url; - expect(output).toContain('Use Kimi Code on this machine'); - expect(output).toContain('1.'); - expect(output).toContain('2.'); - expect(output).toContain('3.'); - expect(output).toContain('example.test/devices/exampl…vice/'); - expect(output).toContain(`\u001B]8;;${url}`); - expect(output).toContain('Connected to example.test'); - expect(output).toContain('This device:'); - expect(output).not.toContain('Manage devices'); - expect(output).toContain('PNG:'); - expect(output).toContain('\n QR'); - expect(output).toContain('grants control of this machine'); - expect(output).toContain('docs'); - expect(output).toContain('feedback'); - expect(output).toContain('Logs: off'); - expect(output).not.toContain('stream-1'); - }); - - it('prints the full URL as plain text when the terminal cannot render hyperlinks', () => { - vi.stubEnv('FORCE_HYPERLINK', '0'); - const output = formatRemoteControlOutput(outputOptions); - expect(output).toContain(`open ${outputOptions.url}`); - expect(output).not.toContain('exampl…vice'); - expect(output).not.toContain('Manage devices'); - }); - - it('formats relay and device lifecycle states', () => { - expect(formatRemoteControlStatus('relay_connected').toLowerCase()).toContain('connected'); - expect(formatRemoteControlStatus('relay_disconnected')).toContain('disconnected'); - expect(formatRemoteControlStatus('device_connected').toLowerCase()).toContain('connected'); - expect(formatRemoteControlStatus('device_disconnected')).toContain('disconnected'); - }); -}); - -describe('Remote Control HTTP forwarding', () => { - it('parses raw requests and replaces relay credentials with local bearer auth', () => { - const parsed = parseRawHttpRequest( - Buffer.from( - 'POST /api/v1/messages?q=1 HTTP/1.1\r\nHost: relay.example\r\nAuthorization: Bearer relay\r\nCookie: sid=1\r\nOrigin: https://relay.example\r\nConnection: keep-alive, X-Hop\r\nX-Hop: remove\r\nX-Keep: yes\r\nContent-Length: 4\r\n\r\ndata', - ), - ); - expect(parsed).toMatchObject({ method: 'POST', path: '/api/v1/messages?q=1' }); - expect(parsed.body.toString()).toBe('data'); - expect(filterForwardRequestHeaders(parsed.headers, 'local-token')).toEqual([ - 'X-Keep', - 'yes', - 'Content-Length', - '4', - 'Authorization', - 'Bearer local-token', - ]); - }); - - it('rejects absolute-form and malformed request targets', () => { - expect(() => - parseRawHttpRequest(Buffer.from('GET https://example.test/ HTTP/1.1\r\n\r\n')), - ).toThrow(/request line/); - expect(() => parseRawHttpRequest(Buffer.from('GET //example.test/ HTTP/1.1\r\n\r\n'))).toThrow( - /request line/, - ); - }); - - it('rewrites HTML, JavaScript, and CSS under the device prefix', () => { - const prefix = '/coding-relay/devices/device-1'; - const html = rewriteRemoteControlResponse( - 'text/html; charset=utf-8', - Buffer.from('<html><head></head><body><script src="/boot.js"></script><a href="/x">x</a></body></html>'), - prefix, - ).toString(); - expect(html).toContain(`src="${prefix}/boot.js"`); - expect(html).toContain(`href="${prefix}/x"`); - expect(html).toContain("sessionStorage.setItem('kimi-desktop-server-origin',location.origin+p)"); - expect(html).toContain('history.pushState=w(history.pushState)'); - - const js = rewriteRemoteControlResponse( - 'text/javascript', - Buffer.from( - 'const a="/assets/a.js";const s="/sessions/";const p=function(e){return"/"+e};', - ), - prefix, - ).toString(); - expect(js).toBe( - `const a="${prefix}/assets/a.js";const s="${prefix}/sessions/";const p=function(e){return"${prefix}/"+e};`, - ); - - const css = rewriteRemoteControlResponse( - 'text/css', - Buffer.from('.x{background:url(/assets/x.png)}'), - prefix, - ).toString(); - expect(css).toBe(`.x{background:url(${prefix}/assets/x.png)}`); - }); -}); - -describe('Remote Control tunnel', () => { - it('surfaces register_nak details', async () => { - const homeDir = mkdtempSync(join(tmpdir(), 'kimi-rc-nak-')); - cleanups.push(() => rmSync(homeDir, { recursive: true, force: true })); - await new FileTokenStorage(join(homeDir, 'credentials')).save( - resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }), - TOKEN, - ); - const managementServer = new WebSocketServer({ noServer: true }); - const relayServer = createServer(); - managementServer.on('connection', (ws) => { - ws.once('message', () => { - ws.send( - JSON.stringify({ - type: 'register_nak', - payload: { - error_code: 'DEVICE_LIMIT_EXCEEDED', - error_message: 'membership allows 3 devices', - }, - }), - ); - }); - }); - relayServer.on('upgrade', (request, socket, head) => { - managementServer.handleUpgrade(request, socket, head, (ws) => - managementServer.emit('connection', ws, request), - ); - }); - const relayPort = await listen(relayServer); - cleanups.push(() => closeServer(relayServer)); - - await expect( - startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:1', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relayPort}/coding-relay`, - stderr: { write: () => true }, - }), - ).rejects.toThrow(/DEVICE_LIMIT_EXCEEDED.*membership allows 3 devices/); - }); - - it('uses only Authorization when the refresh token is not a valid subprotocol token', async () => { - const homeDir = await createRemoteControlHome('invalid/token='); - const relay = await startAuthRelay(); - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - - handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:1', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}/coding-relay`, - stderr: { write: () => true }, - }); - - expect(relay.requests).toHaveLength(2); - expect(relay.requests.every((request) => request.protocol === undefined)).toBe(true); - expect(relay.requests.every((request) => request.authorization === 'Bearer invalid/token=')).toBe( - true, - ); - }); - - it('retries with only Authorization when the server does not echo the subprotocol', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay({ echoProtocol: false }); - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - - handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:1', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}/coding-relay`, - stderr: { write: () => true }, - }); - - expect(relay.requests.some((request) => request.protocol?.startsWith('kimi-code.bearer.'))).toBe( - true, - ); - expect( - relay.requests.some( - (request) => - request.protocol === undefined && - request.authorization === `Bearer ${TOKEN.refreshToken}`, - ), - ).toBe(true); - }); - - it('keeps the initial start pending through transient failures and recovers', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay({ rejectUpgrades: 2 }); - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - - handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:1', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}/coding-relay`, - stderr: { write: () => true }, - }); - - expect(relay.requests.length).toBeGreaterThanOrEqual(4); - expect(handle.url).toContain('?rc=1&from=kimi_code_cli'); - }, 6000); - - it('reconnects when management closes during the HTTP tunnel handshake', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay({ closeManagementDuringFirstHttpHandshake: true }); - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - - handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:1', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}/coding-relay`, - stderr: { write: () => true }, - }); - - expect(relay.requests.length).toBeGreaterThanOrEqual(4); - }, 6000); - - it('registers, forwards HTTP and WS with local auth, then reconnects the pair', async () => { - const homeDir = mkdtempSync(join(tmpdir(), 'kimi-rc-')); - cleanups.push(() => rmSync(homeDir, { recursive: true, force: true })); - await new FileTokenStorage(join(homeDir, 'credentials')).save( - resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }), - TOKEN, - ); - - let localHttpRequest: IncomingMessage | undefined; - let localWsRequest: IncomingMessage | undefined; - const localWsServer = new WebSocketServer({ noServer: true }); - const localServer = createServer((request, response) => { - localHttpRequest = request; - response.writeHead(200, { - 'Content-Type': 'text/html', - 'Cache-Control': 'public, max-age=31536000, immutable', - Connection: 'X-Remove', - 'X-Remove': 'gone', - }); - response.end('<html><head></head><script src="/boot.js"></script></html>'); - }); - localServer.on('upgrade', (request, socket, head) => { - localWsRequest = request; - localWsServer.handleUpgrade(request, socket, head, (ws) => localWsServer.emit('connection', ws, request)); - }); - const localPort = await listen(localServer); - cleanups.push(() => closeServer(localServer)); - - const managementServer = new WebSocketServer({ noServer: true }); - const httpTunnelServer = new WebSocketServer({ noServer: true }); - const streamServer = new WebSocketServer({ noServer: true }); - const relayServer = createServer(); - const managementConnections: WebSocket[] = []; - const httpConnections: WebSocket[] = []; - const streamConnections: WebSocket[] = []; - const registrations: unknown[] = []; - const managementMessages: unknown[] = []; - const streamMessages: string[] = []; - let localWs: WebSocket | undefined; - - managementServer.on('connection', (ws) => { - managementConnections.push(ws); - ws.on('message', (data) => { - const message = JSON.parse(rawDataText(data)) as { type: string }; - managementMessages.push(message); - if (message.type === 'register') { - registrations.push(message); - ws.send(JSON.stringify({ type: 'register_ack', payload: { success: true } })); - } - }); - }); - httpTunnelServer.on('connection', (ws) => httpConnections.push(ws)); - streamServer.on('connection', (ws) => { - streamConnections.push(ws); - ws.on('message', (data) => streamMessages.push(rawDataText(data))); - }); - localWsServer.on('connection', (ws) => { - localWs = ws; - ws.send('server-hello-frame'); - }); - relayServer.on('upgrade', (request, socket, head) => { - const pathname = new URL(request.url!, 'http://relay.test').pathname; - const target = pathname.endsWith('/v1/remote/create') - ? managementServer - : pathname.endsWith('/v1/remote/http') - ? httpTunnelServer - : streamServer; - target.handleUpgrade(request, socket, head, (ws) => target.emit('connection', ws, request)); - }); - const relayPort = await listen(relayServer); - cleanups.push(() => closeServer(relayServer)); - - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - handle = await startRemoteControl({ - homeDir, - localOrigin: `http://127.0.0.1:${localPort}`, - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relayPort}/coding-relay`, - stderr: { write: () => true }, - }); - - expect(registrations).toHaveLength(1); - expect(handle.url).toContain('/coding-relay/devices/'); - expect(handle.url).toContain('?rc=1&from=kimi_code_cli'); - - const rawRequest = Buffer.from( - 'GET / HTTP/1.1\r\nHost: relay.test\r\nAuthorization: Bearer relay-token\r\nCookie: sid=1\r\nOrigin: https://relay.test\r\nConnection: X-Hop\r\nX-Hop: remove\r\nX-Keep: yes\r\n\r\n', - ); - const splitAt = Math.floor(rawRequest.length / 2); - httpConnections[0]!.send( - JSON.stringify({ - request_id: 'request-1', - type: 'request', - is_last: false, - body_base64: rawRequest.subarray(0, splitAt).toString('base64'), - }), - ); - await new Promise((resolve) => setTimeout(resolve, 20)); - expect(localHttpRequest).toBeUndefined(); - const responsePromise = nextJsonMessage(httpConnections[0]!); - httpConnections[0]!.send( - JSON.stringify({ - request_id: 'request-1', - type: 'request', - is_last: true, - body_base64: rawRequest.subarray(splitAt).toString('base64'), - }), - ); - const responseMessage = await responsePromise; - const response = Buffer.from(responseMessage['body_base64'] as string, 'base64').toString(); - expect(response).toContain('HTTP/1.1 200 OK'); - expect(localHttpRequest?.headers.authorization).toBe('Bearer local-server-token'); - expect(localHttpRequest?.headers.cookie).toBeUndefined(); - expect(localHttpRequest?.headers.origin).toBeUndefined(); - expect(localHttpRequest?.headers['x-hop']).toBeUndefined(); - expect(localHttpRequest?.headers['x-keep']).toBe('yes'); - expect(response).not.toContain('X-Remove'); - expect(response).not.toContain('immutable'); - expect(response).toContain('Cache-Control: no-cache'); - expect(response).toContain(`/coding-relay/devices/${handle.deviceId}/boot.js`); - - managementConnections[0]!.send( - JSON.stringify({ - type: 'open_ws', - payload: { - stream_id: 'stream-1', - path: '/api/v1/ws', - headers: { Cookie: 'relay-cookie', Origin: 'https://relay.test', 'X-Keep': 'yes' }, - }, - }), - ); - await waitFor(() => streamConnections.length === 1 && localWs !== undefined); - expect(localWsRequest?.headers['sec-websocket-protocol']).toBe( - 'kimi-code.bearer.local-server-token', - ); - expect(localWsRequest?.headers.authorization).toBeUndefined(); - expect(localWsRequest?.headers.cookie).toBeUndefined(); - expect(localWsRequest?.headers.origin).toBeUndefined(); - expect(localWsRequest?.headers['x-keep']).toBe('yes'); - await waitFor(() => - managementMessages.some( - (value) => - (value as { type?: string }).type === 'open_ws_result' && - (value as { payload?: { success?: boolean } }).payload?.success === true, - ), - ); - - await waitFor(() => streamMessages.includes('server-hello-frame')); - const localMessage = nextTextMessage(localWs!); - streamConnections[0]!.send('from-relay'); - await expect(localMessage).resolves.toBe('from-relay'); - const relayMessage = nextTextMessage(streamConnections[0]!); - localWs!.send('from-local'); - await expect(relayMessage).resolves.toBe('from-local'); - - streamConnections[0]!.terminate(); - await waitFor(() => localWs?.readyState === 3); - - httpConnections[0]!.terminate(); - await waitFor(() => registrations.length === 2 && httpConnections.length === 2, 4000); - - await handle.close(); - await waitFor(() => - managementMessages.some( - (value) => - (value as { type?: string; payload?: { reason?: string } }).type === 'disconnect' && - (value as { payload?: { reason?: string } }).payload?.reason === 'local_server_stopped', - ), - ); - }); -}); - -describe('Remote Control single-instance lock', () => { - async function deadPid(): Promise<number> { - const child = spawn(process.execPath, ['-e', ''], { stdio: 'ignore' }); - await new Promise<void>((resolve) => child.on('exit', () => resolve())); - return child.pid!; - } - - it('refuses a second instance on the same home and reports the running link', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay(); - let first: RemoteControlHandle | undefined; - cleanups.push(async () => first?.close()); - first = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:58627', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}`, - stderr: { write: () => true }, - }); - - await expect( - startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:58628', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}`, - stderr: { write: () => true }, - }), - ).rejects.toThrow(/already running[\s\S]*127\.0\.0\.1:58627[\s\S]*\/devices\//); - expect(relay.requests).toHaveLength(2); - }); - - it('reaps a stale lock left by a dead process', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - await mkdir(join(homeDir, 'server'), { recursive: true }); - await writeFile( - remoteControlLockPath(homeDir), - JSON.stringify({ - pid: await deadPid(), - nonce: 'stale', - local_origin: 'http://127.0.0.1:1', - device_id: 'dead-device', - url: 'https://code-rc.kimi.com/devices/dead-device/', - started_at: 0, - }), - ); - const relay = await startAuthRelay(); - let handle: RemoteControlHandle | undefined; - cleanups.push(async () => handle?.close()); - - handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:58627', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}`, - stderr: { write: () => true }, - }); - - const lock = JSON.parse(await readFile(remoteControlLockPath(homeDir), 'utf8')) as { - pid: number; - }; - expect(lock.pid).toBe(process.pid); - }); - - it('releases the lock on close so a new instance can start', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay(); - const options = { - homeDir, - localOrigin: 'http://127.0.0.1:58627', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}`, - stderr: { write: () => true }, - }; - const first = await startRemoteControl(options); - await first.close(); - - let second: RemoteControlHandle | undefined; - cleanups.push(async () => second?.close()); - second = await startRemoteControl(options); - expect(second.url).toContain('/devices/'); - }); - - it('does not remove a successor lock when closing', async () => { - const homeDir = await createRemoteControlHome(TOKEN.refreshToken); - const relay = await startAuthRelay(); - const handle = await startRemoteControl({ - homeDir, - localOrigin: 'http://127.0.0.1:58627', - localServerToken: 'local-server-token', - relayOrigin: `http://127.0.0.1:${relay.port}`, - stderr: { write: () => true }, - }); - cleanups.push(async () => handle?.close()); - await writeFile( - remoteControlLockPath(homeDir), - JSON.stringify({ - pid: process.pid, - nonce: 'successor', - local_origin: 'http://127.0.0.1:58628', - device_id: 'device-2', - url: 'https://code-rc.kimi.com/devices/device-2/', - started_at: Date.now(), - }), - ); - - await handle.close(); - - const lock = JSON.parse(await readFile(remoteControlLockPath(homeDir), 'utf8')) as { - nonce: string; - }; - expect(lock.nonce).toBe('successor'); - }); -}); - -async function createRemoteControlHome(refreshToken: string): Promise<string> { - const homeDir = mkdtempSync(join(tmpdir(), 'kimi-rc-auth-')); - cleanups.push(() => rmSync(homeDir, { recursive: true, force: true })); - await new FileTokenStorage(join(homeDir, 'credentials')).save( - resolveKimiTokenStorageName({ providerName: KIMI_CODE_PROVIDER_NAME }), - { - ...TOKEN, - refreshToken, - }, - ); - return homeDir; -} - -async function startAuthRelay( - options: { - echoProtocol?: boolean; - rejectUpgrades?: number; - closeManagementDuringFirstHttpHandshake?: boolean; - } = {}, -): Promise<{ - port: number; - requests: Array<{ authorization?: string; protocol?: string }>; -}> { - const handleProtocols = options.echoProtocol === false ? (): false => false : undefined; - const managementServer = new WebSocketServer({ noServer: true, handleProtocols }); - const httpTunnelServer = new WebSocketServer({ noServer: true, handleProtocols }); - const relayServer = createServer(); - const requests: Array<{ authorization?: string; protocol?: string }> = []; - let remainingRejections = options.rejectUpgrades ?? 0; - let closeManagement = options.closeManagementDuringFirstHttpHandshake === true; - let delayHttpUpgrade = closeManagement; - - managementServer.on('connection', (ws) => { - ws.on('error', () => {}); - ws.on('message', (data) => { - const message = JSON.parse(rawDataText(data)) as { type?: string }; - if (message.type === 'register') { - ws.send(JSON.stringify({ type: 'register_ack', payload: { success: true } })); - if (closeManagement) { - closeManagement = false; - setTimeout(() => ws.close(), 10); - } - } - }); - }); - httpTunnelServer.on('connection', (ws) => ws.on('error', () => {})); - relayServer.on('upgrade', (request, socket, head) => { - const authorization = request.headers.authorization; - const protocol = request.headers['sec-websocket-protocol']; - requests.push({ - authorization: Array.isArray(authorization) ? authorization[0] : authorization, - protocol: Array.isArray(protocol) ? protocol[0] : protocol, - }); - if (remainingRejections > 0) { - remainingRejections -= 1; - socket.end( - 'HTTP/1.1 503 Service Unavailable\r\nConnection: close\r\nContent-Length: 0\r\n\r\n', - ); - return; - } - const pathname = new URL(request.url!, 'http://relay.test').pathname; - const target = pathname.endsWith('/v1/remote/create') - ? managementServer - : httpTunnelServer; - const upgrade = (): void => { - target.handleUpgrade(request, socket, head, (ws) => target.emit('connection', ws, request)); - }; - if (target === httpTunnelServer && delayHttpUpgrade) { - delayHttpUpgrade = false; - setTimeout(upgrade, 50); - return; - } - upgrade(); - }); - const port = await listen(relayServer); - cleanups.push(() => closeServer(relayServer)); - return { port, requests }; -} - -function listen(server: ReturnType<typeof createServer>): Promise<number> { - return new Promise((resolve, reject) => { - server.once('error', reject); - server.listen(0, '127.0.0.1', () => { - const address = server.address(); - if (address === null || typeof address === 'string') reject(new Error('missing address')); - else resolve(address.port); - }); - }); -} - -function closeServer(server: ReturnType<typeof createServer>): Promise<void> { - return new Promise((resolve, reject) => { - server.close((error) => { - if (error === undefined) resolve(); - else reject(error); - }); - }); -} - -function rawDataText(data: RawData): string { - if (Array.isArray(data)) return Buffer.concat(data).toString('utf8'); - return Buffer.from(data as ArrayBuffer).toString('utf8'); -} - -function nextJsonMessage(socket: WebSocket): Promise<Record<string, unknown>> { - return new Promise((resolve) => { - socket.once('message', (data) => resolve(JSON.parse(rawDataText(data)) as Record<string, unknown>)); - }); -} - -function nextTextMessage(socket: WebSocket): Promise<string> { - return new Promise((resolve) => { - socket.once('message', (data) => resolve(rawDataText(data))); - }); -} - -async function waitFor(predicate: () => boolean, timeoutMs = 2000): Promise<void> { - const deadline = Date.now() + timeoutMs; - while (!predicate()) { - if (Date.now() >= deadline) throw new Error('condition timed out'); - await new Promise((resolve) => setTimeout(resolve, 10)); - } -} diff --git a/apps/kimi-code/test/cli/web/web.test.ts b/apps/kimi-code/test/cli/web/web.test.ts index 5f7f2a6f3..1b51bfc53 100644 --- a/apps/kimi-code/test/cli/web/web.test.ts +++ b/apps/kimi-code/test/cli/web/web.test.ts @@ -15,8 +15,6 @@ import chalk, { Chalk } from 'chalk'; import { Command } from 'commander'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; -import { resetCapabilitiesCache, setCapabilities } from '@moonshot-ai/pi-tui'; - import { registerWebCommand } from '#/cli/sub/web'; import type { LegacyKillDeps } from '#/cli/sub/web/legacy-kill'; import type { WebCommandDeps } from '#/cli/sub/web/run'; @@ -52,7 +50,7 @@ function makeRunner(origin = 'http://127.0.0.1:58627'): { const calls: { options: ParsedServerOptions | undefined } = { options: undefined }; const runner: ForegroundRunner = async (options, hooks) => { calls.options = options; - await hooks?.onReady?.(origin); + hooks?.onReady?.(origin); return undefined as never; }; return { runner, calls }; @@ -101,12 +99,10 @@ describe('kimi web', () => { expect(longs).toContain('--allowed-host'); expect(longs).toContain('--insecure-no-tls'); expect(longs).toContain('--allow-remote-shutdown'); + expect(longs).toContain('--allow-remote-terminals'); expect(longs).toContain('--dangerous-bypass-auth'); expect(longs).toContain('--log-level'); expect(longs).toContain('--debug-endpoints'); - expect(longs).toContain('--web-title'); - const remoteControl = web!.options.find((option) => option.long === '--remote-control'); - expect(remoteControl?.short).toBe('--rc'); // web opens the browser by default → the option is the negative --no-open. expect(longs).toContain('--no-open'); // The background/daemon era flags are gone: the server always runs in the @@ -115,7 +111,6 @@ describe('kimi web', () => { expect(longs).not.toContain('--keep-alive'); expect(longs).not.toContain('--daemon'); expect(longs).not.toContain('--idle-grace-ms'); - expect(longs).not.toContain('--allow-remote-terminals'); }); it('routes `kimi server` and any legacy subcommand to a deprecation notice', async () => { @@ -287,8 +282,8 @@ describe('ready banner reflects the bind class', () => { startServerForeground: runner, resolveToken: () => 'tok-xyz', networkAddresses: [ - { address: '192.0.2.66', family: 'IPv4' }, - { address: '198.51.100.216', family: 'IPv4' }, + { address: '192.168.98.66', family: 'IPv4' }, + { address: '10.8.12.216', family: 'IPv4' }, ], openUrl: vi.fn(), stdout, @@ -303,8 +298,8 @@ describe('ready banner reflects the bind class', () => { // Full token-bearing URLs are printed plainly (no box, no truncation) so // they are easy to copy. expect(raw).toContain('http://localhost:58627/#token=tok-xyz'); - expect(raw).toContain('http://192.0.2.66:58627/#token=tok-xyz'); - expect(raw).toContain('http://198.51.100.216:58627/#token=tok-xyz'); + expect(raw).toContain('http://192.168.98.66:58627/#token=tok-xyz'); + expect(raw).toContain('http://10.8.12.216:58627/#token=tok-xyz'); expect(raw).toContain('Token:'); expect(raw).toContain('tok-xyz'); expect(raw).not.toContain('╭'); @@ -321,7 +316,7 @@ describe('ready banner reflects the bind class', () => { startServerForeground: runner, resolveToken: () => 'tok-loop', // Injected interface addresses must NOT leak into a loopback banner. - networkAddresses: [{ address: '192.0.2.66', family: 'IPv4' }], + networkAddresses: [{ address: '192.168.98.66', family: 'IPv4' }], openUrl: vi.fn(), stdout, stderr, @@ -337,17 +332,12 @@ describe('ready banner reflects the bind class', () => { // No network URLs on a loopback bind — just the "off" hint. expect(raw).toContain('use --host to enable'); expect(raw).not.toContain('Network: http'); - expect(raw).not.toContain('192.0.2.66'); + expect(raw).not.toContain('192.168.98.66'); expect(raw).not.toContain('╭'); }); }); describe('`kimi web` opens the browser', () => { - afterEach(() => { - vi.unstubAllEnvs(); - resetCapabilitiesCache(); - }); - it('opens the Web UI URL with the #token= fragment by default', async () => { const { handleWebCommand } = await import('#/cli/sub/web/run'); const { runner } = makeRunner(); @@ -401,108 +391,6 @@ describe('`kimi web` opens the browser', () => { expect(openUrl).not.toHaveBeenCalled(); }); - - it('maps --remote-control and --rc to the same option', () => { - for (const flag of ['--remote-control', '--rc']) { - const program = makeProgram(); - const web = program.commands.find((command) => command.name() === 'web')!; - web.parseOptions([flag]); - expect(web.opts()).toMatchObject({ remoteControl: true }); - } - }); - - it('rejects Remote Control on a non-loopback host', async () => { - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '1'); - const { handleWebCommand } = await import('#/cli/sub/web/run'); - const { runner } = makeRunner(); - const { stdout, stderr } = makeIo(); - - await expect( - handleWebCommand( - { remoteControl: true, host: '0.0.0.0', open: false }, - { startServerForeground: runner, openUrl: vi.fn(), stdout, stderr }, - ), - ).rejects.toThrow('--remote-control requires a loopback host.'); - }); - - it('rejects --remote-control while the experimental flag is off', async () => { - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', '0'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '0'); - const { handleWebCommand } = await import('#/cli/sub/web/run'); - const { runner } = makeRunner(); - const { stdout, stderr } = makeIo(); - - await expect( - handleWebCommand( - { remoteControl: true, open: false }, - { startServerForeground: runner, openUrl: vi.fn(), stdout, stderr }, - ), - ).rejects.toThrow('--remote-control is experimental:'); - }); - - it('hides --remote-control from help unless the experimental flag is on', () => { - const remoteControlOption = () => - makeProgram() - .commands.find((command) => command.name() === 'web')! - .options.find((option) => option.long === '--remote-control'); - - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', '0'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '0'); - expect(remoteControlOption()?.hidden).toBe(true); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '1'); - expect(remoteControlOption()?.hidden).toBe(false); - }); -}); - -describe('kimi rc', () => { - afterEach(() => { - vi.unstubAllEnvs(); - }); - - it('registers `rc` with the `remote` alias and the web server options, without a --remote-control flag', () => { - const program = makeProgram(); - const rc = program.commands.find((c) => c.name() === 'rc'); - expect(rc).toBeDefined(); - expect(rc!.alias()).toBe('remote'); - const longs = rc!.options.map((o) => o.long).filter(Boolean); - expect(longs).toContain('--port'); - expect(longs).toContain('--host'); - expect(longs).toContain('--no-open'); - expect(longs).not.toContain('--remote-control'); - }); - - it('hides `rc` from help unless the experimental flag is on', () => { - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', '0'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '0'); - expect(makeProgram().helpInformation()).not.toContain('rc|remote'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '1'); - expect(makeProgram().helpInformation()).toContain('rc|remote'); - }); - - it('forces Remote Control for both `rc` and `remote`', async () => { - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_FLAG', '0'); - vi.stubEnv('KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL', '0'); - for (const name of ['rc', 'remote']) { - const program = makeProgram(); - let stderr = ''; - const errSpy = vi.spyOn(process.stderr, 'write').mockImplementation((chunk) => { - stderr += String(chunk); - return true; - }); - const exitSpy = vi - .spyOn(process, 'exit') - .mockImplementation(() => undefined as never); - try { - await program.parseAsync(['node', 'kimi', name]); - } finally { - errSpy.mockRestore(); - exitSpy.mockRestore(); - } - // The flag-off experimental error proves remoteControl was forced before - // the runner could start. - expect(stderr).toContain('--remote-control is experimental:'); - } - }); }); describe('`kimi web` option threading', () => { @@ -520,6 +408,7 @@ describe('`kimi web` option threading', () => { dangerousBypassAuth: true, debugEndpoints: true, allowRemoteShutdown: true, + allowRemoteTerminals: true, open: false, }, { startServerForeground: runner, openUrl: vi.fn(), stdout, stderr }, @@ -532,6 +421,7 @@ describe('`kimi web` option threading', () => { debugEndpoints: true, insecureNoTls: true, allowRemoteShutdown: true, + allowRemoteTerminals: true, dangerousBypassAuth: true, allowedHosts: ['.example.com'], }); @@ -580,32 +470,6 @@ describe('`kimi web` option threading', () => { expect(calls.options).toMatchObject({ logLevel: 'debug' }); }); - it('passes --web-title through to the runner', async () => { - const { handleWebCommand } = await import('#/cli/sub/web/run'); - const { runner, calls } = makeRunner(); - const { stdout, stderr } = makeIo(); - - await handleWebCommand( - { port: '58627', webTitle: 'My Dev Box', open: false }, - { startServerForeground: runner, openUrl: vi.fn(), stdout, stderr }, - ); - - expect(calls.options).toMatchObject({ webTitle: 'My Dev Box' }); - }); - - it('leaves webTitle undefined when --web-title is not passed', async () => { - const { handleWebCommand } = await import('#/cli/sub/web/run'); - const { runner, calls } = makeRunner(); - const { stdout, stderr } = makeIo(); - - await handleWebCommand( - { port: '58627', open: false }, - { startServerForeground: runner, openUrl: vi.fn(), stdout, stderr }, - ); - - expect(calls.options?.webTitle).toBeUndefined(); - }); - it('rejects an invalid --log-level before calling the runner', async () => { const { handleWebCommand } = await import('#/cli/sub/web/run'); const startServerForeground = vi.fn(async () => undefined as never); diff --git a/apps/kimi-code/test/tui/banner/banner-provider.test.ts b/apps/kimi-code/test/tui/banner/banner-provider.test.ts index 12f8573ca..b21de59d8 100644 --- a/apps/kimi-code/test/tui/banner/banner-provider.test.ts +++ b/apps/kimi-code/test/tui/banner/banner-provider.test.ts @@ -428,105 +428,6 @@ describe('selectBannerState', () => { ttlHours: 168, }); }); - - it('shows the banner when banner_platform is missing, empty, all, or cli', () => { - for (const banner_platform of [undefined, null, '', ' ', 'all', 'cli', 'ALL', ' CLI ']) { - const result = selectBannerState( - { - banner_enabled: true, - banner_maintext: 'Active', - banner_platform, - }, - '0.14.0', - now, - () => 0, - ); - expect(result, `platform=${String(banner_platform)}`).not.toBeNull(); - } - }); - - it('skips the active banner when banner_platform targets other platforms', () => { - for (const banner_platform of ['desktop', 'web']) { - const result = selectBannerState( - { - banner_enabled: true, - banner_maintext: 'Active', - banner_platform, - banner_fallback_enabled: true, - banner_fallback_list: [{ enabled: true, banner_maintext: 'Fallback' }], - }, - '0.14.0', - now, - () => 0, - ); - expectAlwaysBanner(result, { tag: null, mainText: 'Fallback', subText: null }); - } - }); - - it('filters fallback entries by banner_platform', () => { - const result = selectBannerState( - { - banner_enabled: false, - banner_fallback_enabled: true, - banner_fallback_list: [ - { enabled: true, banner_maintext: 'Desktop tip', banner_platform: 'desktop' }, - { enabled: true, banner_maintext: 'Web tip', banner_platform: 'web' }, - { enabled: true, banner_maintext: 'Cli tip', banner_platform: 'cli' }, - ], - }, - '0.14.0', - now, - () => 0.99, - ); - expectAlwaysBanner(result, { tag: null, mainText: 'Cli tip', subText: null }); - }); - - it('filters fallback entries by their time window', () => { - const result = selectBannerState( - { - banner_enabled: false, - banner_fallback_enabled: true, - banner_fallback_list: [ - { - enabled: true, - banner_maintext: 'Expired tip', - banner_end_time: '2026-06-01T00:00:00+08:00', - }, - { - enabled: true, - banner_maintext: 'Future tip', - banner_start_time: '2026-07-01T00:00:00+08:00', - }, - { - enabled: true, - banner_maintext: 'Current tip', - banner_start_time: '2026-06-01T00:00:00+08:00', - banner_end_time: '2026-06-30T00:00:00+08:00', - }, - ], - }, - '0.14.0', - now, - () => 0.99, - ); - expectAlwaysBanner(result, { tag: null, mainText: 'Current tip', subText: null }); - }); - - it('treats fallback entries without time fields as always valid', () => { - const result = selectBannerState( - { - banner_enabled: false, - banner_fallback_enabled: true, - banner_fallback_list: [ - { enabled: true, banner_maintext: 'No window', banner_start_time: '', banner_end_time: null }, - ], - }, - '0.14.0', - now, - () => 0, - ); - expectAlwaysBanner(result, { tag: null, mainText: 'No window', subText: null }); - }); }); describe('shouldDisplayBanner', () => { diff --git a/apps/kimi-code/test/tui/commands/experiments.test.ts b/apps/kimi-code/test/tui/commands/experiments.test.ts index c8b8e3b11..89bf62da6 100644 --- a/apps/kimi-code/test/tui/commands/experiments.test.ts +++ b/apps/kimi-code/test/tui/commands/experiments.test.ts @@ -50,7 +50,6 @@ function makeHost() { restoreEditor: vi.fn(), showStatus: vi.fn(), showError: vi.fn(), - showNotice: vi.fn(), track: vi.fn(), } as unknown as SlashCommandHost & { harness: { @@ -114,24 +113,4 @@ describe('experimental feature command handlers', () => { 'textMuted', ); }); - - it('notices that tower mode needs a restart when the tower flag changes', async () => { - const host = makeHost(); - - await applyExperimentalFeatureChanges(host, [{ id: 'tower', enabled: true }]); - - expect(host.showNotice).toHaveBeenCalledWith( - 'Tower mode takes effect after restarting Kimi Code.', - ); - }); - - it('does not show the restart notice for non-tower changes', async () => { - const host = makeHost(); - - await applyExperimentalFeatureChanges(host, [ - { id: 'micro_compaction', enabled: false }, - ]); - - expect(host.showNotice).not.toHaveBeenCalled(); - }); }); diff --git a/apps/kimi-code/test/tui/commands/goal.test.ts b/apps/kimi-code/test/tui/commands/goal.test.ts index d9c4a5d34..ea59d4fae 100644 --- a/apps/kimi-code/test/tui/commands/goal.test.ts +++ b/apps/kimi-code/test/tui/commands/goal.test.ts @@ -4,7 +4,6 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { dispatchInput, goalArgumentCompletions, - goalObjectiveLengthWarning, handleGoalCommand, parseGoalCommand, setExperimentalFeatures, @@ -107,7 +106,6 @@ function makeHost( streamingPhase: overrides.streaming ? 'streaming' : 'idle', isCompacting: false, }, - editor: { getText: vi.fn(() => '') }, transcriptContainer, ui: { requestRender: vi.fn() }, theme: { palette: getBuiltInPalette('dark') }, @@ -215,61 +213,8 @@ describe('parseGoalCommand', () => { }); }); - it('rejects objectives longer than 4000 characters with a file-reference hint', () => { - expect(parseGoalCommand('x'.repeat(4001))).toEqual({ - kind: 'error', - restoreInput: true, - message: - 'Goal objective is too long (max 4000 characters). Put long content in a file and reference the file path.', - }); - expect(parseGoalCommand(`next ${'x'.repeat(4001)}`)).toEqual({ - kind: 'error', - restoreInput: true, - message: - 'Goal objective is too long (max 4000 characters). Put long content in a file and reference the file path.', - }); - }); -}); - -describe('goalObjectiveLengthWarning', () => { - it('warns once the typed /goal objective exceeds the limit', () => { - const warning = goalObjectiveLengthWarning(`/goal ${'x'.repeat(4001)}`); - expect(warning).toContain('(4001/4000 characters)'); - expect(warning).toContain('reference the file path'); - }); - - it('ignores leading whitespace because submitted text is trimmed', () => { - expect(goalObjectiveLengthWarning(` /goal ${'x'.repeat(4001)}`)).toBeDefined(); - }); - - it('warns for over-limit /goal next and /goal replace objectives', () => { - expect(goalObjectiveLengthWarning(`/goal next ${'x'.repeat(4001)}`)).toBeDefined(); - expect(goalObjectiveLengthWarning(`/goal replace ${'x'.repeat(4001)}`)).toBeDefined(); - expect(goalObjectiveLengthWarning(`/goal -- ${'x'.repeat(4001)}`)).toBeDefined(); - }); - - it('stays quiet for valid objectives and non-goal input', () => { - expect(goalObjectiveLengthWarning(`/goal ${'x'.repeat(4000)}`)).toBeUndefined(); - expect(goalObjectiveLengthWarning('/goal Ship feature X')).toBeUndefined(); - expect(goalObjectiveLengthWarning('Ship feature X')).toBeUndefined(); - }); - - it('stays quiet for control forms and lookalike commands', () => { - expect(goalObjectiveLengthWarning('/goal')).toBeUndefined(); - expect(goalObjectiveLengthWarning('/goal status')).toBeUndefined(); - expect(goalObjectiveLengthWarning('/goal pause')).toBeUndefined(); - expect(goalObjectiveLengthWarning('/goal next manage')).toBeUndefined(); - expect(goalObjectiveLengthWarning(`/goalie ${'x'.repeat(4001)}`)).toBeUndefined(); - }); - - it('stays quiet when the boundary is a newline or tab (dispatch sends those as plain messages)', () => { - expect(goalObjectiveLengthWarning(`/goal\n${'x'.repeat(4001)}`)).toBeUndefined(); - expect(goalObjectiveLengthWarning(`/goal\t${'x'.repeat(4001)}`)).toBeUndefined(); - }); - - it('still warns for multiline objectives after a literal-space boundary', () => { - const objective = `${'x'.repeat(2000)}\n${'x'.repeat(2001)}`; - expect(goalObjectiveLengthWarning(`/goal ${objective}`)).toBeDefined(); + it('rejects objectives longer than 4000 characters', () => { + expect(parseGoalCommand('x'.repeat(4001))).toMatchObject({ kind: 'error' }); }); }); @@ -321,34 +266,6 @@ describe('handleGoalCommand', () => { expect(calls).toEqual([{ receiver: host, text: 'Ship feature X' }]); }); - it('rejects an over-limit objective before sending and restores the typed input', async () => { - const args = 'x'.repeat(4001); - await handleGoalCommand(host, args); - - expect(session.createGoal).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - expect(host.showError).toHaveBeenCalledWith( - 'Goal objective is too long (max 4000 characters). Put long content in a file and reference the file path.', - ); - expect(host.restoreInputText).toHaveBeenCalledWith(`/goal ${args}`); - }); - - it('does not restore input for the empty-objective usage hint', async () => { - await handleGoalCommand(host, 'replace'); - - expect(host.showStatus).toHaveBeenCalled(); - expect(host.restoreInputText).not.toHaveBeenCalled(); - }); - - it('does not restore over a draft typed while validation was pending', async () => { - vi.mocked(host.state.editor.getText).mockReturnValue('a newer draft'); - - await handleGoalCommand(host, 'x'.repeat(4001)); - - expect(host.showError).toHaveBeenCalled(); - expect(host.restoreInputText).not.toHaveBeenCalled(); - }); - it('asks before starting a goal in Manual mode', async () => { const { host: manualHost, session: s } = makeHost({ permissionMode: 'manual' }); @@ -806,102 +723,6 @@ describe('dispatchInput /goal integration', () => { expect(host.sendNormalUserInput).toHaveBeenCalledWith('Ship feature X'); expect(host.sendNormalUserInput).not.toHaveBeenCalledWith('/goal Ship feature X'); }); - - it('restores the input when /goal is rejected by the busy gate while streaming', async () => { - const { host, session } = makeHost({ streaming: true }); - - dispatchInput(host, '/goal Ship feature X'); - - await vi.waitFor(() => { - expect(host.showError).toHaveBeenCalledWith( - 'Cannot /goal while streaming — press Esc or Ctrl-C first.', - ); - }); - expect(session.createGoal).not.toHaveBeenCalled(); - expect(host.restoreInputText).toHaveBeenCalledWith('/goal Ship feature X'); - }); - - it('restores the input when the post-creation busy re-check rejects /goal', async () => { - const { host, session } = makeHost({ hasSession: false }); - Object.assign(host, { - engineV2: true, - // A first prompt starts a turn while the lazy session creation awaits. - ensureSession: vi.fn(async () => { - host.state.appState.streamingPhase = 'thinking'; - return session; - }), - }); - - dispatchInput(host, '/goal Ship feature X'); - - await vi.waitFor(() => { - expect(host.showError).toHaveBeenCalledWith( - 'Cannot /goal while streaming — press Esc or Ctrl-C first.', - ); - }); - expect(session.createGoal).not.toHaveBeenCalled(); - expect(host.restoreInputText).toHaveBeenCalledWith('/goal Ship feature X'); - }); - - it('does not restore over a draft typed while lazy session creation was pending', async () => { - const { host, session } = makeHost({ hasSession: false }); - Object.assign(host, { - engineV2: true, - ensureSession: vi.fn(async () => { - host.state.appState.streamingPhase = 'thinking'; - // The user kept typing after submitting /goal. - vi.mocked(host.state.editor.getText).mockReturnValue('a newer draft'); - return session; - }), - }); - - dispatchInput(host, '/goal Ship feature X'); - - await vi.waitFor(() => { - expect(host.showError).toHaveBeenCalledWith( - 'Cannot /goal while streaming — press Esc or Ctrl-C first.', - ); - }); - expect(session.createGoal).not.toHaveBeenCalled(); - expect(host.restoreInputText).not.toHaveBeenCalled(); - }); - - it('restores the input when lazy session creation fails before /goal runs', async () => { - const { host, session } = makeHost({ hasSession: false }); - Object.assign(host, { - engineV2: true, - ensureSession: vi.fn(async () => undefined), - }); - - dispatchInput(host, '/goal Ship feature X'); - - await vi.waitFor(() => { - expect(host.restoreInputText).toHaveBeenCalledWith('/goal Ship feature X'); - }); - expect(session.createGoal).not.toHaveBeenCalled(); - }); - - it('does not restore when an editor-replacement panel opened during creation', async () => { - const { host, session } = makeHost({ hasSession: false }); - Object.assign(host, { - engineV2: true, - ensureSession: vi.fn(async () => { - // The user opened a panel (e.g. /help) while creation was pending. - Object.assign(host.state, { editorReplacementMounted: true }); - return undefined; - }), - }); - - dispatchInput(host, '/goal Ship feature X'); - - await vi.waitFor(() => { - expect(host.state.editorReplacementMounted).toBe(true); - }); - // Allow the post-creation branch to run before asserting. - await new Promise((resolve) => setImmediate(resolve)); - expect(session.createGoal).not.toHaveBeenCalled(); - expect(host.restoreInputText).not.toHaveBeenCalled(); - }); }); describe('goalArgumentCompletions', () => { diff --git a/apps/kimi-code/test/tui/commands/provider.test.ts b/apps/kimi-code/test/tui/commands/provider.test.ts deleted file mode 100644 index 92efe4edb..000000000 --- a/apps/kimi-code/test/tui/commands/provider.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -/** - * Scenario: /provider post-add default-model selection. - * Responsibilities: the picked effort is gated for persistence by the model's - * effective default, and a session-only pick is still applied to the runtime - * after the config refresh (which only reactivates from persisted values). - * Wiring: real setDefaultModel with the harness/authFlow boundaries stubbed by - * a small host rig. - * Run: pnpm -C apps/kimi-code exec vitest run test/tui/commands/provider.test.ts - */ -import type { ModelAlias } from '@moonshot-ai/kimi-code-sdk'; -import { describe, expect, it, vi } from 'vitest'; - -import type { SlashCommandHost } from '#/tui/commands'; -import { setDefaultModel } from '#/tui/commands/provider'; - -function makeHost() { - const appState = { - availableModels: { - // Declares no efforts; the Anthropic profile inference supplies - // [low, medium, high, xhigh, max] with the default resolved to 'high'. - opus: { - provider: 'compatible', - model: 'claude-opus-4-7', - maxContextSize: 200_000, - } as unknown as ModelAlias, - }, - availableProviders: { - compatible: { type: 'anthropic' }, - }, - }; - const host = { - state: { appState }, - harness: { - setConfig: vi.fn(async () => ({})), - }, - authFlow: { - refreshConfigAfterLogin: vi.fn(async () => {}), - activateModelAfterLogin: vi.fn(async () => {}), - }, - track: vi.fn(), - showStatus: vi.fn(), - } as unknown as SlashCommandHost & { - harness: { setConfig: ReturnType<typeof vi.fn> }; - authFlow: { - refreshConfigAfterLogin: ReturnType<typeof vi.fn>; - activateModelAfterLogin: ReturnType<typeof vi.fn>; - }; - }; - return { host }; -} - -describe('setDefaultModel', () => { - it('applies an above-default pick to the runtime when the gate keeps it session-only', async () => { - const { host } = makeHost(); - - await setDefaultModel(host, 'opus', 'xhigh'); - - expect(host.harness.setConfig).toHaveBeenCalledWith({ - defaultModel: 'opus', - thinking: { enabled: true }, - }); - expect(host.authFlow.activateModelAfterLogin).toHaveBeenCalledWith('opus', 'xhigh'); - // The application must come after the refresh, or the persisted value - // reactivated by refreshConfigAfterLogin would clobber the pick. - expect( - host.authFlow.activateModelAfterLogin.mock.invocationCallOrder[0]!, - ).toBeGreaterThan(host.authFlow.refreshConfigAfterLogin.mock.invocationCallOrder[0]!); - }); - - it('does not re-apply the effort when the pick persists', async () => { - const { host } = makeHost(); - - await setDefaultModel(host, 'opus', 'high'); - - expect(host.harness.setConfig).toHaveBeenCalledWith({ - defaultModel: 'opus', - thinking: { enabled: true, effort: 'high' }, - }); - expect(host.authFlow.activateModelAfterLogin).not.toHaveBeenCalled(); - }); - - it('does not re-apply a boolean on pick', async () => { - const { host } = makeHost(); - - await setDefaultModel(host, 'opus', 'on'); - - expect(host.harness.setConfig).toHaveBeenCalledWith({ - defaultModel: 'opus', - thinking: { enabled: true }, - }); - expect(host.authFlow.activateModelAfterLogin).not.toHaveBeenCalled(); - }); -}); diff --git a/apps/kimi-code/test/tui/commands/registry.test.ts b/apps/kimi-code/test/tui/commands/registry.test.ts index 1113a5998..a1964b5cb 100644 --- a/apps/kimi-code/test/tui/commands/registry.test.ts +++ b/apps/kimi-code/test/tui/commands/registry.test.ts @@ -6,7 +6,6 @@ import { addDirArgumentCompletions, sortSlashCommands, swarmArgumentCompletions, - towerArgumentCompletions, type KimiSlashCommand, } from '#/tui/commands/index'; import { describe, expect, it } from 'vitest'; @@ -76,22 +75,6 @@ describe('built-in slash command registry', () => { expect(values('Ship feature X')).toBeNull(); }); - it('offers tower subcommand argument completions', () => { - const values = (prefix: string): string[] | null => { - const items = towerArgumentCompletions(prefix); - return items === null ? null : items.map((item) => item.value); - }; - - expect(values('')).toEqual(['status', 'teardown', 'on', 'off']); - expect(values('T')).toEqual(['teardown']); - expect(towerArgumentCompletions('tea')).toEqual([ - { value: 'teardown', label: 'teardown', description: 'Tear down the tower' }, - ]); - expect(values('status')).toBeNull(); - expect(values('on')).toBeNull(); - expect(values('Ship feature X')).toBeNull(); - }); - it('offers add-dir list and directory argument completions', () => { const values = (prefix: string): string[] | null => { const items = addDirArgumentCompletions(prefix); @@ -184,13 +167,12 @@ describe('built-in slash command registry', () => { 'plan', 'reload', 'reload-tui', - 'secondary-model', + 'secondary_model', 'sessions', 'settings', 'status', 'theme', 'title', - 'tower', 'undo', 'usage', 'version', @@ -209,36 +191,10 @@ describe('built-in slash command registry', () => { expect(resolveSlashCommandAvailability(reloadTui!, '')).toBe('always'); }); - it('gates secondary-model behind the secondary-model experiment, always available', () => { - const command = findBuiltInSlashCommand('secondary-model'); + it('gates secondary_model behind the secondary-model experiment, always available', () => { + const command = findBuiltInSlashCommand('secondary_model'); expect(command).toBeDefined(); expect((command as KimiSlashCommand).experimentalFlag).toBe('secondary-model'); expect(resolveSlashCommandAvailability(command!, '')).toBe('always'); }); - - it('gates tower behind the tower experiment and the v2 engine', () => { - const command = findBuiltInSlashCommand('tower'); - expect(command).toBeDefined(); - expect((command as KimiSlashCommand).experimentalFlag).toBe('tower'); - expect((command as KimiSlashCommand).requiresEngineV2).toBe(true); - }); - - it('keeps every tower subcommand always available, including objectives', () => { - const command = findBuiltInSlashCommand('tower'); - expect(command).toBeDefined(); - expect(resolveSlashCommandAvailability(command!, '')).toBe('always'); - expect(resolveSlashCommandAvailability(command!, 'on')).toBe('always'); - expect(resolveSlashCommandAvailability(command!, 'off')).toBe('always'); - expect(resolveSlashCommandAvailability(command!, 'status')).toBe('always'); - expect(resolveSlashCommandAvailability(command!, 'teardown')).toBe('always'); - expect(resolveSlashCommandAvailability(command!, 'Ship feature X')).toBe('always'); - }); - - it('gates remote-control behind the remote-control experiment, always available', () => { - const command = findBuiltInSlashCommand('remote-control'); - expect(command).toBeDefined(); - expect((command as KimiSlashCommand).experimentalFlag).toBe('remote-control'); - expect(resolveSlashCommandAvailability(command!, '')).toBe('always'); - }); - }); diff --git a/apps/kimi-code/test/tui/commands/reload.test.ts b/apps/kimi-code/test/tui/commands/reload.test.ts index e0d935240..b36f96213 100644 --- a/apps/kimi-code/test/tui/commands/reload.test.ts +++ b/apps/kimi-code/test/tui/commands/reload.test.ts @@ -14,10 +14,6 @@ import { isExperimentalFlagEnabled, setExperimentalFeatures, } from '#/tui/commands/experimental-flags'; -import { - createMarkdownOptions, - setMarkdownRenderLatex, -} from '#/tui/utils/markdown-options'; const tempDirs: string[] = []; const originalKimiCodeHome = process.env['KIMI_CODE_HOME']; @@ -120,27 +116,6 @@ auto_install = false expect(themeWhenTracked).toBe('auto'); }); - it('applies the render_latex toggle before theme application rebuilds Markdown', async () => { - await writeTuiConfig('render_latex = false\n'); - const host = makeHost(); - - // applyTheme invalidates transcript components, which rebuild their - // Markdown children by copying the shared options — the reloaded value - // must already be live at that point. - let latexWhenThemeApplied: boolean | undefined; - const mutable = host as unknown as { applyTheme: unknown }; - mutable.applyTheme = vi.fn(() => { - latexWhenThemeApplied = createMarkdownOptions().renderLatex; - }); - - try { - await handleReloadTuiCommand(host); - expect(latexWhenThemeApplied).toBe(false); - } finally { - setMarkdownRenderLatex(true); - } - }); - it('refreshes workspace commands and lazy defaults on a session-less v2 reload', async () => { await writeTuiConfig('theme = "dark"\n'); const host = makeHost(); diff --git a/apps/kimi-code/test/tui/commands/resolve.test.ts b/apps/kimi-code/test/tui/commands/resolve.test.ts index d11ce73f9..614553bb4 100644 --- a/apps/kimi-code/test/tui/commands/resolve.test.ts +++ b/apps/kimi-code/test/tui/commands/resolve.test.ts @@ -17,7 +17,6 @@ function resolve( pluginCommandMap: new Map<string, string>(), isStreaming: false, isCompacting: false, - engineV2: true, ...overrides, }); } @@ -64,13 +63,6 @@ describe('resolveSlashCommandInput', () => { }); }); - it('gates /remote-control behind the remote-control experimental flag', () => { - expect(resolve('/rc')).toEqual({ kind: 'message', input: '/rc' }); - setExperimentalFeatures([{ id: 'remote-control', enabled: true }]); - expect(resolve('/rc')).toMatchObject({ kind: 'builtin', name: 'remote-control' }); - expect(resolve('/remote-control')).toMatchObject({ kind: 'builtin', name: 'remote-control' }); - }); - it('blocks idle-only built-ins while streaming', () => { expect(resolve('/new', { isStreaming: true })).toEqual({ kind: 'blocked', @@ -203,7 +195,7 @@ describe('resolveSlashCommandInput', () => { }); }); - it('resolves skill commands and keeps them resolvable while busy (queued downstream)', () => { + it('resolves skill commands and blocks them while busy', () => { const skillCommandMap = new Map([['skill:review', 'review']]); expect(resolve('/skill:review src/app.ts', { skillCommandMap })).toEqual({ @@ -213,14 +205,13 @@ describe('resolveSlashCommandInput', () => { args: 'src/app.ts', }); expect(resolve('/skill:review src/app.ts', { skillCommandMap, isStreaming: true })).toEqual({ - kind: 'skill', + kind: 'blocked', commandName: 'skill:review', - skillName: 'review', - args: 'src/app.ts', + reason: 'streaming', }); }); - it('resolves unprefixed built-in skill commands and keeps them resolvable while busy', () => { + it('resolves unprefixed built-in skill commands and blocks them while busy', () => { const skillCommandMap = new Map([['mcp-config', 'mcp-config']]); expect(resolve('/mcp-config', { skillCommandMap })).toEqual({ @@ -230,10 +221,9 @@ describe('resolveSlashCommandInput', () => { args: '', }); expect(resolve('/mcp-config', { skillCommandMap, isCompacting: true })).toEqual({ - kind: 'skill', + kind: 'blocked', commandName: 'mcp-config', - skillName: 'mcp-config', - args: '', + reason: 'compacting', }); }); @@ -263,31 +253,6 @@ describe('resolveSlashCommandInput', () => { }); }); - it('resolves /tower to the builtin command when the tower flag is enabled', () => { - setExperimentalFeatures([{ id: 'tower', enabled: true }]); - - expect(resolve('/tower Ship feature X')).toMatchObject({ - kind: 'builtin', - name: 'tower', - args: 'Ship feature X', - }); - }); - - it('does not resolve /tower as a builtin when the tower flag is disabled', () => { - expect(resolve('/tower Ship feature X')).toEqual({ - kind: 'message', - input: '/tower Ship feature X', - }); - }); - - it('does not resolve /tower as a builtin on the legacy engine', () => { - setExperimentalFeatures([{ id: 'tower', enabled: true }]); - - expect(resolve('/tower on', { engineV2: false })).toEqual({ - kind: 'message', - input: '/tower on', - }); - }); }); describe('goal command resolution', () => { diff --git a/apps/kimi-code/test/tui/commands/secondary-model.test.ts b/apps/kimi-code/test/tui/commands/secondary-model.test.ts index 9bce58d4c..81b309ef0 100644 --- a/apps/kimi-code/test/tui/commands/secondary-model.test.ts +++ b/apps/kimi-code/test/tui/commands/secondary-model.test.ts @@ -1,11 +1,10 @@ /** - * Scenario: /secondary-model command behavior in the interactive TUI. - * Responsibilities: picker filtering, persistence of `[secondary_model] default_model` - * (keeping existing pool descriptions), and error paths. + * Scenario: /secondary_model command behavior in the interactive TUI. + * Responsibilities: picker filtering, persistence, live apply, and effective-model state refresh. * Wiring: real command and selector with the SDK/session boundaries stubbed by a small host rig. * Run: pnpm -C apps/kimi-code exec vitest run test/tui/commands/secondary-model.test.ts */ -import type { ModelAlias } from '@moonshot-ai/kimi-code-sdk'; +import type { ModelAlias, ThinkingEffort } from '@moonshot-ai/kimi-code-sdk'; import { describe, expect, it, vi } from 'vitest'; import type { SlashCommandHost } from '#/tui/commands'; @@ -15,10 +14,9 @@ import { TabbedModelSelectorComponent } from '#/tui/components/dialogs/tabbed-mo interface PickerOptions { readonly models: Record<string, ModelAlias>; readonly currentValue: string; - readonly selectedValue?: string; + readonly currentThinkingEffort: string; readonly title?: string; - readonly thinkingControl?: boolean; - readonly onSelect: (selection: { alias: string }) => void; + readonly onSelect: (selection: { alias: string; thinking: ThinkingEffort }) => void; } function model(name: string): ModelAlias { @@ -31,16 +29,21 @@ function model(name: string): ModelAlias { } function makeHost(options?: { - readonly secondaryModel?: { defaultModel?: string; models?: Record<string, string> }; + readonly withSession?: boolean; + readonly secondaryModel?: { model: string; defaultEffort?: string }; + readonly persistedModels?: Record<string, ModelAlias>; + /** The secondary model the reloaded config carries — env overlays win. */ + readonly effectiveSecondary?: { model: string; defaultEffort?: string }; }) { + const session = options?.withSession === false + ? undefined + : { applyPersistedSecondaryModel: vi.fn(async () => {}) }; const appState = { availableModels: { k2: model('k2'), cheap: model('cheap'), - // The v1 derived entry must never be selectable. + // The synthesized derived entry must never be selectable. '__secondary__': model('cheap'), - // The pool's reserved symbolic choice must never be selectable either. - 'primary': model('primary'), } as Record<string, ModelAlias>, availableProviders: {}, transcriptEntries: [], @@ -58,8 +61,13 @@ function makeHost(options?: { providers: {}, secondaryModel: options?.secondaryModel, })), - setConfig: vi.fn(async () => ({})), + setConfig: vi.fn(async () => ({ + providers: {}, + models: options?.persistedModels, + secondaryModel: options?.effectiveSecondary, + })), }, + session, setAppState: vi.fn((patch) => Object.assign(appState, patch)), mountEditorReplacement: vi.fn(), restoreEditor: vi.fn(), @@ -77,7 +85,7 @@ function makeHost(options?: { showError: ReturnType<typeof vi.fn>; showNotice: ReturnType<typeof vi.fn>; }; - return { host }; + return { host, session }; } function mountedPicker(host: { mountEditorReplacement: ReturnType<typeof vi.fn> }): PickerOptions { @@ -88,86 +96,108 @@ function mountedPicker(host: { mountEditorReplacement: ReturnType<typeof vi.fn> } describe('handleSecondaryModelCommand', () => { - it('opens the picker filtered to user models, with the configured default as current', async () => { - const { host } = makeHost({ secondaryModel: { defaultModel: 'cheap' } }); + it('opens the picker filtered to user models, with the configured recipe as current', async () => { + const { host } = makeHost({ secondaryModel: { model: 'cheap', defaultEffort: 'high' } }); await handleSecondaryModelCommand(host, ''); const opts = mountedPicker(host); expect(Object.keys(opts.models)).toEqual(['k2', 'cheap']); expect(opts.currentValue).toBe('cheap'); + expect(opts.currentThinkingEffort).toBe('high'); expect(opts.title).toContain('secondary model'); - // Pool bindings carry no explicit thinking level — the picker hides the - // Thinking footer instead of offering a no-op choice. - expect(opts.thinkingControl).toBe(false); }); - it('persists only default_model when no pool exists (implicit single-entry pool)', async () => { - const { host } = makeHost(); + it('persists first, then live-applies the selection to the session', async () => { + const { host, session } = makeHost(); await handleSecondaryModelCommand(host, ''); - mountedPicker(host).onSelect({ alias: 'k2' }); + mountedPicker(host).onSelect({ alias: 'k2', thinking: 'high' }); await vi.waitFor(() => { expect(host.showStatus).toHaveBeenCalled(); }); expect(host.harness.setConfig).toHaveBeenCalledWith({ - secondaryModel: { defaultModel: 'k2' }, + secondaryModel: { model: 'k2', defaultEffort: 'high' }, }); + expect(session!.applyPersistedSecondaryModel).toHaveBeenCalledWith(); + expect(host.harness.setConfig.mock.invocationCallOrder[0]).toBeLessThan( + session!.applyPersistedSecondaryModel.mock.invocationCallOrder[0]!, + ); expect(host.showError).not.toHaveBeenCalled(); }); - it('adds the picked alias to an existing pool with an empty description', async () => { + it('refreshes the effective model map after a live secondary-model switch', async () => { const { host } = makeHost({ - secondaryModel: { - defaultModel: 'cheap', - models: { cheap: 'fast and cheap' }, + persistedModels: { + k2: model('k2'), + cheap: model('cheap'), + '__secondary__': model('k2'), }, }); await handleSecondaryModelCommand(host, ''); - mountedPicker(host).onSelect({ alias: 'k2' }); + mountedPicker(host).onSelect({ alias: 'k2', thinking: 'high' }); + + await vi.waitFor(() => { + expect(host.showStatus).toHaveBeenCalled(); + }); + expect(host.state.appState.availableModels['__secondary__']?.displayName).toBe('k2'); + }); + + it('warns with the env-overridden effective binding instead of the picked model', async () => { + // KIMI_SECONDARY_MODEL / KIMI_SECONDARY_EFFORT win over the persisted + // recipe: the reloaded config carries the overlaid values, and the status + // message must name them rather than echo the pick. + const { host } = makeHost({ + effectiveSecondary: { model: 'cheap', defaultEffort: 'low' }, + }); + + await handleSecondaryModelCommand(host, ''); + mountedPicker(host).onSelect({ alias: 'k2', thinking: 'high' }); + + await vi.waitFor(() => { + expect(host.showStatus).toHaveBeenCalled(); + }); + const [message, color] = host.showStatus.mock.calls[0]!; + expect(message).toContain('KIMI_SECONDARY_MODEL=cheap'); + expect(message).toContain('KIMI_SECONDARY_EFFORT=low'); + expect(color).toBe('warning'); + expect(host.showError).not.toHaveBeenCalled(); + }); + + it('keeps the current effective model map when live apply fails', async () => { + const { host, session } = makeHost({ + persistedModels: { + k2: model('k2'), + cheap: model('cheap'), + '__secondary__': model('k2'), + }, + }); + session!.applyPersistedSecondaryModel.mockRejectedValueOnce(new Error('apply failed')); + + await handleSecondaryModelCommand(host, ''); + mountedPicker(host).onSelect({ alias: 'k2', thinking: 'high' }); + + await vi.waitFor(() => { + expect(host.showError).toHaveBeenCalled(); + }); + expect(host.state.appState.availableModels['__secondary__']?.displayName).toBe('cheap'); + }); + + it('persists only when there is no session', async () => { + const { host } = makeHost({ withSession: false }); + + await handleSecondaryModelCommand(host, ''); + mountedPicker(host).onSelect({ alias: 'k2', thinking: 'off' }); await vi.waitFor(() => { expect(host.showStatus).toHaveBeenCalled(); }); expect(host.harness.setConfig).toHaveBeenCalledWith({ - secondaryModel: { - defaultModel: 'k2', - models: { cheap: 'fast and cheap', k2: '' }, - }, + secondaryModel: { model: 'k2', defaultEffort: 'off' }, }); - }); - - it('keeps existing pool descriptions and other pool entries on save', async () => { - const { host } = makeHost({ - secondaryModel: { - defaultModel: 'cheap', - models: { cheap: 'fast and cheap', k2: 'hard tasks' }, - }, - }); - - await handleSecondaryModelCommand(host, ''); - mountedPicker(host).onSelect({ alias: 'k2' }); - - await vi.waitFor(() => { - expect(host.showStatus).toHaveBeenCalled(); - }); - expect(host.harness.setConfig).toHaveBeenCalledWith({ - secondaryModel: { - defaultModel: 'k2', - models: { cheap: 'fast and cheap', k2: 'hard tasks' }, - }, - }); - }); - - it('pre-selects a valid alias argument instead of erroring', async () => { - const { host } = makeHost(); - - await handleSecondaryModelCommand(host, 'cheap'); - - const opts = mountedPicker(host); - expect(opts.selectedValue).toBe('cheap'); + expect(host.showStatus.mock.calls[0]![0]).toContain('new sessions'); }); it('rejects an unknown alias argument without opening the picker', async () => { @@ -188,26 +218,6 @@ describe('handleSecondaryModelCommand', () => { expect(host.mountEditorReplacement).not.toHaveBeenCalled(); }); - it('rejects the reserved primary alias as an argument', async () => { - const { host } = makeHost(); - - await handleSecondaryModelCommand(host, 'primary'); - - expect(host.showError).toHaveBeenCalledWith(expect.stringContaining('reserved')); - expect(host.mountEditorReplacement).not.toHaveBeenCalled(); - }); - - it('reports the reserved error for primary even when it is the only configured model', async () => { - const { host } = makeHost(); - host.state.appState.availableModels = { primary: model('primary') }; - - await handleSecondaryModelCommand(host, 'primary'); - - expect(host.showError).toHaveBeenCalledWith(expect.stringContaining('reserved')); - expect(host.showNotice).not.toHaveBeenCalled(); - expect(host.mountEditorReplacement).not.toHaveBeenCalled(); - }); - it('shows a notice when no models are configured', async () => { const { host } = makeHost(); host.state.appState.availableModels = {}; @@ -217,18 +227,4 @@ describe('handleSecondaryModelCommand', () => { expect(host.showNotice).toHaveBeenCalled(); expect(host.mountEditorReplacement).not.toHaveBeenCalled(); }); - - it('reports a persistence failure without a status message', async () => { - const { host } = makeHost(); - host.harness.setConfig.mockRejectedValueOnce(new Error('disk full')); - - await handleSecondaryModelCommand(host, ''); - mountedPicker(host).onSelect({ alias: 'k2' }); - - await vi.waitFor(() => { - expect(host.showError).toHaveBeenCalled(); - }); - expect(host.showError.mock.calls[0]![0]).toContain('disk full'); - expect(host.showStatus).not.toHaveBeenCalled(); - }); }); diff --git a/apps/kimi-code/test/tui/commands/tower.test.ts b/apps/kimi-code/test/tui/commands/tower.test.ts deleted file mode 100644 index 0f89d4da9..000000000 --- a/apps/kimi-code/test/tui/commands/tower.test.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; - -import type { Session } from '@moonshot-ai/kimi-code-sdk'; - -import { handleTowerCommand } from '#/tui/commands/index'; -import type { SlashCommandHost } from '#/tui/commands/dispatch'; -import { - LLM_NOT_SET_MESSAGE, - TOWER_STATUS_PROMPT, - TOWER_TEARDOWN_PROMPT, -} from '#/tui/constant/kimi-tui'; - -function makeHost( - overrides: { - hasSession?: boolean; - towerMode?: boolean; - engineV2?: boolean; - refuseTowerEntry?: boolean; - model?: string; - } = {}, -) { - let engineMode = overrides.towerMode ?? false; - const session = { - setTowerMode: vi.fn(async (enabled: boolean) => { - if (!(overrides.refuseTowerEntry && enabled)) engineMode = enabled; - }), - getStatus: vi.fn(async () => ({ towerMode: engineMode })), - }; - const hasSession = overrides.hasSession ?? true; - const host = { - state: { - appState: { - towerMode: overrides.towerMode ?? false, - model: overrides.model ?? 'test-model', - }, - }, - engineV2: overrides.engineV2 ?? true, - session: hasSession ? session : undefined, - ensureSession: vi.fn(async () => { - host.session = session as unknown as Session; - return session as unknown as Session; - }), - requireSession: () => { - if (host.session === undefined) throw new Error('No active session'); - return host.session; - }, - setAppState: vi.fn((patch: Record<string, unknown>) => Object.assign(host.state.appState, patch)), - showError: vi.fn(), - showStatus: vi.fn(), - showNotice: vi.fn(), - sendNormalUserInput: vi.fn(), - } as unknown as SlashCommandHost; - return { host, session }; -} - -describe('handleTowerCommand', () => { - it('reports tower status when called without args, without touching the mode', async () => { - const { host, session } = makeHost({ towerMode: false }); - - await handleTowerCommand(host, ''); - - expect(host.sendNormalUserInput).toHaveBeenCalledWith(TOWER_STATUS_PROMPT); - expect(session.setTowerMode).not.toHaveBeenCalled(); - expect(host.ensureSession).not.toHaveBeenCalled(); - }); - - it('reports tower status for the status subcommand, without touching the mode', async () => { - const { host, session } = makeHost({ towerMode: true }); - - await handleTowerCommand(host, 'status'); - - expect(host.sendNormalUserInput).toHaveBeenCalledWith(TOWER_STATUS_PROMPT); - expect(session.setTowerMode).not.toHaveBeenCalled(); - }); - - it('sends the teardown instruction for the teardown subcommand, without touching the mode', async () => { - const { host, session } = makeHost({ towerMode: true }); - - await handleTowerCommand(host, 'teardown'); - - expect(host.sendNormalUserInput).toHaveBeenCalledWith(TOWER_TEARDOWN_PROMPT); - expect(session.setTowerMode).not.toHaveBeenCalled(); - }); - - it('turns tower mode on with an explicit on subcommand', async () => { - const { host, session } = makeHost({ towerMode: false }); - - await handleTowerCommand(host, 'on'); - - expect(session.setTowerMode).toHaveBeenCalledWith(true); - expect(host.setAppState).toHaveBeenCalledWith({ towerMode: true }); - expect(host.showNotice).toHaveBeenCalledWith('Tower mode: ON'); - expect(host.showError).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('turns tower mode off with an explicit off subcommand', async () => { - const { host, session } = makeHost({ towerMode: true }); - - await handleTowerCommand(host, 'off'); - - expect(session.setTowerMode).toHaveBeenCalledWith(false); - expect(host.setAppState).toHaveBeenCalledWith({ towerMode: false }); - expect(host.showNotice).toHaveBeenCalledWith('Tower mode: OFF'); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('reasserts the mode idempotently when tower mode is already on', async () => { - const { host, session } = makeHost({ towerMode: true }); - - await handleTowerCommand(host, 'on'); - - expect(session.setTowerMode).toHaveBeenCalledWith(true); - expect(host.showStatus).toHaveBeenCalledWith('Tower mode is already on.'); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('reasserts the mode idempotently when tower mode is already off', async () => { - const { host, session } = makeHost({ towerMode: false }); - - await handleTowerCommand(host, 'off'); - - expect(session.setTowerMode).toHaveBeenCalledWith(false); - expect(host.showStatus).toHaveBeenCalledWith('Tower mode is already off.'); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('enables tower mode and sends the objective as a normal prompt', async () => { - const { host, session } = makeHost({ towerMode: false }); - - await handleTowerCommand(host, 'Ship feature X'); - - expect(session.setTowerMode).toHaveBeenCalledWith(true); - expect(host.setAppState).toHaveBeenCalledWith({ towerMode: true }); - expect(host.showNotice).toHaveBeenCalledWith('Tower mode: ON'); - expect(host.sendNormalUserInput).toHaveBeenCalledWith('Ship feature X'); - }); - - it('refuses the objective without touching the mode when no model is configured', async () => { - const { host, session } = makeHost({ towerMode: false, model: '' }); - - await handleTowerCommand(host, 'Ship feature X'); - - expect(host.showError).toHaveBeenCalledWith(LLM_NOT_SET_MESSAGE); - expect(session.setTowerMode).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('re-asserts tower mode idempotently for the objective when already on, without a notice', async () => { - const { host, session } = makeHost({ towerMode: true }); - - await handleTowerCommand(host, 'Ship feature X'); - - expect(session.setTowerMode).toHaveBeenCalledWith(true); - expect(host.showNotice).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).toHaveBeenCalledWith('Ship feature X'); - }); - - it('does not send the objective when enabling tower mode fails', async () => { - const { host, session } = makeHost({ towerMode: false }); - session.setTowerMode.mockRejectedValueOnce(new Error('denied')); - - await handleTowerCommand(host, 'Ship feature X'); - - expect(host.showError).toHaveBeenCalledWith( - expect.stringContaining('Failed to enable tower mode'), - ); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('reports a failure when disabling tower mode fails', async () => { - const { host, session } = makeHost({ towerMode: true }); - session.setTowerMode.mockRejectedValueOnce(new Error('denied')); - - await handleTowerCommand(host, 'off'); - - expect(host.showError).toHaveBeenCalledWith( - expect.stringContaining('Failed to disable tower mode'), - ); - expect(host.setAppState).not.toHaveBeenCalledWith({ towerMode: false }); - }); - - it('does not show ON or send the objective when the engine refuses entry', async () => { - const { host } = makeHost({ towerMode: false, refuseTowerEntry: true }); - - await handleTowerCommand(host, 'Ship feature X'); - - expect(host.showError).toHaveBeenCalledWith(expect.stringContaining('could not be enabled')); - expect(host.setAppState).toHaveBeenCalledWith({ towerMode: false }); - expect(host.showNotice).not.toHaveBeenCalledWith('Tower mode: ON'); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('shows an error when no session is active on the legacy engine', async () => { - const { host, session } = makeHost({ hasSession: false, engineV2: false }); - - await handleTowerCommand(host, 'on'); - - expect(host.showError).toHaveBeenCalledWith(expect.stringContaining('session')); - expect(host.ensureSession).not.toHaveBeenCalled(); - expect(session.setTowerMode).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - - it('lazy-creates the session on the v2 engine when none exists', async () => { - const { host, session } = makeHost({ hasSession: false }); - - await handleTowerCommand(host, 'on'); - - expect(host.ensureSession).toHaveBeenCalled(); - expect(session.setTowerMode).toHaveBeenCalledWith(true); - expect(host.showNotice).toHaveBeenCalledWith('Tower mode: ON'); - expect(host.showError).not.toHaveBeenCalled(); - }); - - it('returns quietly when lazy session creation fails', async () => { - const { host, session } = makeHost({ hasSession: false }); - host.ensureSession = vi.fn(async () => undefined); - - await handleTowerCommand(host, 'on'); - - expect(session.setTowerMode).not.toHaveBeenCalled(); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); -}); diff --git a/apps/kimi-code/test/tui/commands/undo.test.ts b/apps/kimi-code/test/tui/commands/undo.test.ts deleted file mode 100644 index ff950e2ea..000000000 --- a/apps/kimi-code/test/tui/commands/undo.test.ts +++ /dev/null @@ -1,162 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; - -import { handleUndoCommand } from '#/tui/commands/undo'; -import type { SlashCommandHost } from '#/tui/commands/dispatch'; -import type { TranscriptEntry } from '#/tui/types'; - -function entry(partial: Partial<TranscriptEntry> & Pick<TranscriptEntry, 'kind' | 'content'>): TranscriptEntry { - return { - id: `t-${Math.random().toString(36).slice(2, 10)}`, - turnId: undefined, - renderMode: 'plain', - ...partial, - }; -} - -function hostWith(entries: TranscriptEntry[]): SlashCommandHost { - return { - session: { undoHistory: vi.fn(async () => {}) }, - state: { - transcriptEntries: entries, - transcriptContainer: { children: [], addChild: vi.fn() }, - ui: { requestRender: vi.fn() }, - appState: { streamingPhase: 'idle' }, - }, - showError: vi.fn(), - } as unknown as SlashCommandHost; -} - -describe('/undo with bundled prompts', () => { - it('removes the bundle cards with their prompt, keeping a standalone skill card before them', async () => { - const entries: TranscriptEntry[] = [ - entry({ kind: 'user', content: 'earlier question' }), - entry({ - kind: 'skill_activation', - content: 'Activated skill: review', - skillTrigger: 'user-slash', - }), - entry({ kind: 'user', content: 'prompt one' }), - entry({ kind: 'assistant', content: 'answer one' }), - entry({ - kind: 'skill_activation', - content: 'Activated skill: security', - skillTrigger: 'user-slash', - bundledWithPrompt: true, - }), - entry({ kind: 'user', content: 'prompt two' }), - entry({ kind: 'assistant', content: 'answer two' }), - ]; - const host = hostWith(entries); - - await handleUndoCommand(host, '1'); - - expect(host.session?.undoHistory).toHaveBeenCalledWith(1); - expect(entries.map((item) => item.content)).toEqual([ - 'earlier question', - 'Activated skill: review', - 'prompt one', - 'answer one', - ]); - }); - - it('removes bundle cards around an interleaved hook result and keeps the hook result', async () => { - const entries: TranscriptEntry[] = [ - entry({ - kind: 'skill_activation', - content: 'Activated skill: review', - skillTrigger: 'user-slash', - bundledWithPrompt: true, - }), - entry({ kind: 'assistant', content: 'hook note', hookResult: true }), - entry({ kind: 'user', content: 'bundled prompt' }), - entry({ kind: 'assistant', content: 'bundled answer' }), - ]; - const host = hostWith(entries); - - await handleUndoCommand(host, '1'); - - expect(host.session?.undoHistory).toHaveBeenCalledWith(1); - expect(entries.map((item) => item.content)).toEqual(['hook note']); - }); - - it('does not count bundle cards as undo anchors of their own', async () => { - const entries: TranscriptEntry[] = [ - entry({ kind: 'user', content: 'prompt one' }), - entry({ kind: 'assistant', content: 'answer one' }), - entry({ - kind: 'skill_activation', - content: 'Activated skill: review', - skillTrigger: 'user-slash', - bundledWithPrompt: true, - }), - entry({ kind: 'user', content: 'prompt two' }), - entry({ kind: 'assistant', content: 'answer two' }), - ]; - const host = hostWith(entries); - - await handleUndoCommand(host, '2'); - - expect(host.session?.undoHistory).toHaveBeenCalledWith(2); - expect(entries).toHaveLength(0); - }); -}); - -describe('/undo todo panel refresh', () => { - function hostWithTodos( - entries: TranscriptEntry[], - session: Record<string, unknown>, - ): { host: SlashCommandHost; setTodoList: ReturnType<typeof vi.fn> } { - const host = hostWith(entries); - const setTodoList = vi.fn(); - (host as { streamingUI?: unknown }).streamingUI = { setTodoList }; - (host as { session?: unknown }).session = session; - return { host, setTodoList }; - } - - it('re-pulls the engine todo state after a successful undo', async () => { - const entries: TranscriptEntry[] = [ - entry({ kind: 'user', content: 'question' }), - entry({ kind: 'assistant', content: 'answer' }), - ]; - const { host, setTodoList } = hostWithTodos(entries, { - undoHistory: vi.fn(async () => {}), - getTodos: vi.fn(async () => [{ title: 'kept', status: 'pending' }]), - }); - - await handleUndoCommand(host, '1'); - - expect(setTodoList).toHaveBeenCalledWith([{ title: 'kept', status: 'pending' }]); - }); - - it('keeps the panel as-is when the engine has no todo read surface', async () => { - const entries: TranscriptEntry[] = [ - entry({ kind: 'user', content: 'question' }), - entry({ kind: 'assistant', content: 'answer' }), - ]; - const { host, setTodoList } = hostWithTodos(entries, { - undoHistory: vi.fn(async () => {}), - getTodos: vi.fn(async () => { - throw new Error('getTodos is only available on the agent-core-v2 engine.'); - }), - }); - - await handleUndoCommand(host, '1'); - - expect(setTodoList).not.toHaveBeenCalled(); - }); - - it('hides the panel when the restored todos are all done', async () => { - const entries: TranscriptEntry[] = [ - entry({ kind: 'user', content: 'question' }), - entry({ kind: 'assistant', content: 'answer' }), - ]; - const { host, setTodoList } = hostWithTodos(entries, { - undoHistory: vi.fn(async () => {}), - getTodos: vi.fn(async () => [{ title: 'finished', status: 'done' }]), - }); - - await handleUndoCommand(host, '1'); - - expect(setTodoList).toHaveBeenCalledWith([]); - }); -}); diff --git a/apps/kimi-code/test/tui/commands/update-preferences.test.ts b/apps/kimi-code/test/tui/commands/update-preferences.test.ts index 8e79bfe91..bf56ba018 100644 --- a/apps/kimi-code/test/tui/commands/update-preferences.test.ts +++ b/apps/kimi-code/test/tui/commands/update-preferences.test.ts @@ -43,7 +43,6 @@ describe('update preference commands', () => { theme: 'auto', editorCommand: null, disablePasteBurst: false, - renderLatex: true, cacheExpiryHint: true, notifications: { enabled: true, condition: 'unfocused' }, upgrade: { autoInstall: false }, @@ -53,29 +52,4 @@ describe('update preference commands', () => { expect(track).toHaveBeenCalledWith('upgrade_preference_changed', { auto_install: false }); expect(showStatus).toHaveBeenCalledWith('Automatic updates disabled.'); }); - - it('preserves a render_latex opt-out when saving an unrelated preference', async () => { - mocks.saveTuiConfig.mockClear(); - const host = { - state: { - appState: { - theme: 'auto' as const, - editorCommand: null, - renderLatex: false, - notifications: { enabled: true, condition: 'unfocused' as const }, - upgrade: { autoInstall: true }, - }, - theme: { palette: darkColors }, - }, - setAppState: vi.fn(), - showStatus: vi.fn(), - track: vi.fn(), - }; - - await applyUpdatePreferenceChoice(host, false); - - expect(mocks.saveTuiConfig).toHaveBeenCalledWith( - expect.objectContaining({ renderLatex: false }), - ); - }); }); diff --git a/apps/kimi-code/test/tui/commands/web.test.ts b/apps/kimi-code/test/tui/commands/web.test.ts index 31d0b7307..92a01a483 100644 --- a/apps/kimi-code/test/tui/commands/web.test.ts +++ b/apps/kimi-code/test/tui/commands/web.test.ts @@ -1,29 +1,16 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { setCapabilities } from '@moonshot-ai/pi-tui'; - import { findBuiltInSlashCommand, resolveSlashCommandAvailability } from '#/tui/commands/index'; import type { SlashCommandHost } from '#/tui/commands/dispatch'; -import { - handleRemoteControlCommand, - handleWebCommand, - webSessionUrl, -} from '#/tui/commands/web'; -import { renderTerminalQr } from '#/utils/remote-control-qr'; +import { handleWebCommand, webSessionUrl } from '#/tui/commands/web'; const mocks = vi.hoisted(() => ({ startServerForeground: vi.fn(), - startRemoteControl: vi.fn(), tryResolveServerToken: vi.fn(), getDataDir: vi.fn(() => '/tmp/kimi-home'), openUrl: vi.fn(), })); -vi.mock('#/cli/sub/web/remote-control', async (importOriginal) => { - const actual = await importOriginal<typeof import('#/cli/sub/web/remote-control')>(); - return { ...actual, startRemoteControl: mocks.startRemoteControl }; -}); - vi.mock('#/cli/sub/web/run', async (importOriginal) => { const actual = await importOriginal<typeof import('#/cli/sub/web/run')>(); return { ...actual, startServerForeground: mocks.startServerForeground }; @@ -47,9 +34,6 @@ vi.mock('#/utils/paths', async (importOriginal) => { return { ...actual, getDataDir: mocks.getDataDir }; }); -const indentedQr = (url: string): string => - renderTerminalQr(url).trimEnd().replaceAll(/^/gm, ' '); - function makeHost() { const host = { session: { id: 'ses-1' }, @@ -60,7 +44,6 @@ function makeHost() { setExitOpenUrl: vi.fn(), setExitForegroundTask: vi.fn(), stop: vi.fn(async () => {}), - waitForLazyCreation: vi.fn(async () => {}), } as unknown as SlashCommandHost & { showStatus: ReturnType<typeof vi.fn>; showError: ReturnType<typeof vi.fn>; @@ -69,7 +52,6 @@ function makeHost() { setExitOpenUrl: ReturnType<typeof vi.fn>; setExitForegroundTask: ReturnType<typeof vi.fn>; stop: ReturnType<typeof vi.fn>; - waitForLazyCreation: ReturnType<typeof vi.fn>; }; return host; } @@ -80,13 +62,6 @@ describe('web slash command', () => { expect(command).toBeDefined(); expect(resolveSlashCommandAvailability(command!, '')).toBe('always'); }); - - it('registers /remote-control and /rc as the same always-available built-in', () => { - const command = findBuiltInSlashCommand('remote-control'); - expect(command).toBeDefined(); - expect(findBuiltInSlashCommand('rc')).toBe(command); - expect(resolveSlashCommandAvailability(command!, '')).toBe('always'); - }); }); describe('handleWebCommand', () => { @@ -145,175 +120,6 @@ describe('handleWebCommand', () => { }); }); -describe('handleRemoteControlCommand', () => { - it('stays in the TUI with a readable error when another instance holds Remote Control', async () => { - vi.clearAllMocks(); - const { mkdtempSync, mkdirSync, rmSync, writeFileSync } = await import('node:fs'); - const { tmpdir } = await import('node:os'); - const { join } = await import('node:path'); - const tempRoot = mkdtempSync(join(tmpdir(), 'kimi-rc-lock-')); - const dataDir = join(tempRoot, 'home'); - mkdirSync(join(dataDir, 'server'), { recursive: true }); - writeFileSync( - join(dataDir, 'server', 'rc.json'), - JSON.stringify({ - pid: process.pid, - nonce: 'holder', - local_origin: 'http://127.0.0.1:58627', - device_id: 'device-1', - url: 'https://code-rc.kimi.com/devices/device-1/?rc=1&from=kimi_code_cli', - started_at: Date.now(), - }), - ); - mocks.getDataDir.mockReturnValue(dataDir); - const host = makeHost(); - - try { - await handleRemoteControlCommand(host); - - expect(host.showError).toHaveBeenCalledWith(expect.stringContaining('already running')); - expect(host.showError).toHaveBeenCalledWith( - expect.stringContaining('/devices/device-1/'), - ); - expect(host.setExitForegroundTask).not.toHaveBeenCalled(); - expect(host.stop).not.toHaveBeenCalled(); - expect(mocks.startServerForeground).not.toHaveBeenCalled(); - } finally { - rmSync(tempRoot, { recursive: true, force: true }); - } - }); - - it('starts the tunnel and saves a token-free session QR code', async () => { - vi.clearAllMocks(); - setCapabilities({ images: null, trueColor: true, hyperlinks: false }); - const { mkdtempSync, readFileSync, rmSync } = await import('node:fs'); - const { tmpdir } = await import('node:os'); - const { isAbsolute, join } = await import('node:path'); - const QRCode = await import('qrcode'); - const tempRoot = mkdtempSync(join(tmpdir(), 'kimi-rc-qrcode-')); - const dataDir = join(tempRoot, 'custom-home'); - const entryUrl = - 'https://code-rc.kimi.com/devices/device-1/?rc=1&from=kimi_code_cli'; - const sessionUrl = - 'https://code-rc.kimi.com/devices/device-1/sessions/ses-1?rc=1&from=kimi_code_cli'; - const pngPath = join(dataDir, 'rc-qrcode.png'); - mocks.getDataDir.mockReturnValue(dataDir); - mocks.tryResolveServerToken.mockReturnValue('local-server-token'); - const close = vi.fn(async () => {}); - mocks.startRemoteControl.mockResolvedValue({ - deviceId: 'device-1', - deviceName: 'example-device', - url: entryUrl, - close, - }); - mocks.startServerForeground.mockImplementation( - async ( - _options: unknown, - hooks: { - onReady?: (origin: string) => void | Promise<void>; - onShutdown?: (reason: string) => void | Promise<void>; - }, - ) => { - await hooks.onReady?.('http://127.0.0.1:58627'); - await hooks.onShutdown?.('SIGINT'); - }, - ); - const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - const host = makeHost(); - - try { - await handleRemoteControlCommand(host); - const task = host.setExitForegroundTask.mock.calls[0]![0] as () => Promise<void>; - await task(); - - expect(mocks.startRemoteControl).toHaveBeenCalledWith( - expect.objectContaining({ - homeDir: dataDir, - localOrigin: 'http://127.0.0.1:58627', - localServerToken: 'local-server-token', - }), - ); - expect(mocks.openUrl).toHaveBeenCalledWith(sessionUrl); - const written = writeSpy.mock.calls.map((call) => String(call[0])).join(''); - expect(written).toContain('Kimi Remote Control ready'); - expect(written).toContain(indentedQr(sessionUrl)); - expect(written).not.toContain(indentedQr(entryUrl)); - expect(isAbsolute(pngPath)).toBe(true); - expect(written).toContain(`QR code PNG: ${pngPath}`); - const png = readFileSync(pngPath); - expect(png.subarray(0, 8)).toEqual(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10])); - expect(png).toEqual(await QRCode.toBuffer(sessionUrl)); - expect(written).not.toContain('local-server-token'); - expect(written).not.toContain('#token='); - expect(close).toHaveBeenCalledOnce(); - } finally { - writeSpy.mockRestore(); - rmSync(tempRoot, { recursive: true, force: true }); - } - }); - - it('opens the device entry URL without a session instead of creating one', async () => { - vi.clearAllMocks(); - setCapabilities({ images: null, trueColor: true, hyperlinks: false }); - const { mkdtempSync, readFileSync, rmSync } = await import('node:fs'); - const { tmpdir } = await import('node:os'); - const { join } = await import('node:path'); - const QRCode = await import('qrcode'); - const tempRoot = mkdtempSync(join(tmpdir(), 'kimi-rc-entry-')); - const dataDir = join(tempRoot, 'custom-home'); - const entryUrl = - 'https://code-rc.kimi.com/devices/device-1/?rc=1&from=kimi_code_cli'; - mocks.getDataDir.mockReturnValue(dataDir); - mocks.tryResolveServerToken.mockReturnValue('local-server-token'); - const close = vi.fn(async () => {}); - mocks.startRemoteControl.mockResolvedValue({ - deviceId: 'device-1', - deviceName: 'example-device', - url: entryUrl, - close, - }); - mocks.startServerForeground.mockImplementation( - async ( - _options: unknown, - hooks: { - onReady?: (origin: string) => void | Promise<void>; - onShutdown?: (reason: string) => void | Promise<void>; - }, - ) => { - await hooks.onReady?.('http://127.0.0.1:58627'); - await hooks.onShutdown?.('SIGINT'); - }, - ); - const writeSpy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true); - const host = makeHost(); - host.session = undefined; - - try { - await handleRemoteControlCommand(host); - - expect(host.waitForLazyCreation).toHaveBeenCalledOnce(); - expect(host.showError).not.toHaveBeenCalled(); - expect(host.setExitForegroundTask).toHaveBeenCalledOnce(); - expect(host.stop).toHaveBeenCalledOnce(); - - const task = host.setExitForegroundTask.mock.calls[0]![0] as () => Promise<void>; - await task(); - - expect(mocks.openUrl).toHaveBeenCalledWith(entryUrl); - const written = writeSpy.mock.calls.map((call) => String(call[0])).join(''); - expect(written).toContain(indentedQr(entryUrl)); - expect(written).not.toContain('/sessions/'); - expect(readFileSync(join(dataDir, 'rc-qrcode.png'))).toEqual( - await QRCode.toBuffer(entryUrl), - ); - expect(close).toHaveBeenCalledOnce(); - } finally { - writeSpy.mockRestore(); - rmSync(tempRoot, { recursive: true, force: true }); - } - }); -}); - describe('webSessionUrl', () => { it('deep-links to the session under the origin', () => { expect(webSessionUrl('http://127.0.0.1:58627', 'abc123')).toBe( diff --git a/apps/kimi-code/test/tui/components/chrome/banner.test.ts b/apps/kimi-code/test/tui/components/chrome/banner.test.ts index 1d2d5034a..aecf815d9 100644 --- a/apps/kimi-code/test/tui/components/chrome/banner.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/banner.test.ts @@ -182,7 +182,7 @@ describe('BannerComponent', () => { }); it('keeps subsequent main lines indented to the main-text column and subtext aligned with the tag text', () => { - const width = 24; + const width = 20; const lines = new BannerComponent( makeBannerState({ tag: 'New:', @@ -196,47 +196,9 @@ describe('BannerComponent', () => { expect(lines[0]).toContain('✦ New:'); const firstLine = lines[0]!; const mainTextStart = visibleWidth(firstLine.slice(0, firstLine.indexOf('Line 1'))); - const continuationLine = lines.find((line) => line.includes('of content'))!; - expect(visibleWidth(continuationLine.slice(0, continuationLine.indexOf('of content')))).toBe(mainTextStart); + const continuationLine = lines.find((line) => line.includes('lot of'))!; + expect(visibleWidth(continuationLine.slice(0, continuationLine.indexOf('lot of')))).toBe(mainTextStart); const subLine = lines.find((line) => line.includes('Sub text'))!; expect(visibleWidth(subLine.slice(0, subLine.indexOf('Sub text')))).toBe(visibleWidth('✦ ')); }); - - it('moves a long tag onto its own line so the main text keeps a usable width', () => { - // Regression: remote banner configs can set a full-sentence tag. Inline it - // would leave the main text only a few columns, which hard-breaks words. - const width = 50; - const lines = new BannerComponent( - makeBannerState({ - tag: 'Use Kimi K3 with High thinking effort', - mainText: '- for the best balance between token spend and capability', - subText: 'Run /model to switch to K3 and set thinking effort to High', - }), - ).render(width); - for (const line of lines) { - expect(visibleWidth(line)).toBeLessThanOrEqual(width); - } - // The tag occupies the first line alone; no main text is squeezed next to it. - expect(lines[0]).toContain('✦ Use Kimi K3 with High thinking effort'); - expect(lines[0]).not.toContain('- for'); - // Words stay intact (no mid-word hard breaks like "balan"/"ce"). - const joined = lines.join('\n'); - for (const word of ['balance', 'between', 'capability', 'thinking', 'effort']) { - expect(joined).toContain(word); - } - // Main text and subtext align with the tag text (right after "✦ "). - const mainLine = lines.find((line) => line.includes('- for'))!; - expect(visibleWidth(mainLine.slice(0, mainLine.indexOf('- for')))).toBe(visibleWidth('✦ ')); - const subLine = lines.find((line) => line.includes('Run /model'))!; - expect(visibleWidth(subLine.slice(0, subLine.indexOf('Run /model')))).toBe(visibleWidth('✦ ')); - }); - - it('keeps a short tag inline when the remaining width is enough', () => { - const width = 40; - const lines = new BannerComponent( - makeBannerState({ tag: 'Tip:', mainText: 'Use /help to list commands.' }), - ).render(width); - expect(lines[0]).toContain('✦ Tip:'); - expect(lines[0]).toContain('Use /help'); - }); }); diff --git a/apps/kimi-code/test/tui/components/chrome/footer-status-line.test.ts b/apps/kimi-code/test/tui/components/chrome/footer-status-line.test.ts index 08883ebd3..36bd1fcf5 100644 --- a/apps/kimi-code/test/tui/components/chrome/footer-status-line.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/footer-status-line.test.ts @@ -33,7 +33,6 @@ const baseState: AppState = { planMode: false, inputMode: 'prompt', swarmMode: false, - towerMode: false, theme: 'dark', editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, diff --git a/apps/kimi-code/test/tui/components/chrome/footer.test.ts b/apps/kimi-code/test/tui/components/chrome/footer.test.ts index cb69e6697..79abf826e 100644 --- a/apps/kimi-code/test/tui/components/chrome/footer.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/footer.test.ts @@ -52,7 +52,6 @@ const appState: AppState = { planMode: false, inputMode: 'prompt', swarmMode: false, - towerMode: false, theme: 'dark', editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, @@ -145,14 +144,6 @@ describe('FooterComponent', () => { expect(rendered).toContain('thinking'); expect(rendered).not.toContain('thinking:high'); }); - - it('shows the tower mode chip only when tower mode is on', () => { - const on = new FooterComponent({ ...appState, towerMode: true }); - expect(on.render(120).join('\n')).toContain('tower'); - - const off = new FooterComponent(appState); - expect(off.render(120).join('\n')).not.toContain('tower'); - }); }); describe('FooterComponent overrides', () => { @@ -197,38 +188,3 @@ describe('FooterComponent displayName override', () => { expect(footer.render(120).join('\n')).not.toContain('Remote Name'); }); }); - -describe('FooterComponent line-2 hints', () => { - function stripAnsi(text: string): string { - return text.replaceAll(/\[[0-9;]*m/g, ''); - } - - it('shows the warning hint on line 2', () => { - const footer = new FooterComponent(appState); - footer.setWarningHint('Goal objective is too long'); - - const line2 = stripAnsi(footer.render(120)[1] ?? ''); - - expect(line2).toContain('Goal objective is too long'); - }); - - it('gives the transient hint precedence, then restores the warning hint', () => { - const footer = new FooterComponent(appState); - footer.setWarningHint('Goal objective is too long'); - - footer.setTransientHint('Press Ctrl+C again to exit'); - expect(stripAnsi(footer.render(120)[1] ?? '')).toContain('Press Ctrl+C again to exit'); - expect(stripAnsi(footer.render(120)[1] ?? '')).not.toContain('Goal objective is too long'); - - footer.setTransientHint(null); - expect(stripAnsi(footer.render(120)[1] ?? '')).toContain('Goal objective is too long'); - }); - - it('clears the warning hint with null', () => { - const footer = new FooterComponent(appState); - footer.setWarningHint('Goal objective is too long'); - footer.setWarningHint(null); - - expect(stripAnsi(footer.render(120)[1] ?? '')).not.toContain('Goal objective is too long'); - }); -}); diff --git a/apps/kimi-code/test/tui/components/chrome/gutter-container.test.ts b/apps/kimi-code/test/tui/components/chrome/gutter-container.test.ts index e62c4c25a..295363a74 100644 --- a/apps/kimi-code/test/tui/components/chrome/gutter-container.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/gutter-container.test.ts @@ -54,15 +54,4 @@ describe('GutterContainer', () => { c.addChild(new FakeChild(() => [colored])); expect(c.render(20)).toEqual([` ${colored}`]); }); - - it('keeps a leading OSC 133 zone marker at byte 0, before the gutter', () => { - const c = new GutterContainer(2, 2); - const marked = `\x1b]133;A\x07content`; - const doubleMarked = `\x1b]133;B\x07\x1b]133;C\x07last`; - c.addChild(new FakeChild(() => [marked, doubleMarked])); - expect(c.render(20)).toEqual([ - `\x1b]133;A\x07 content`, - `\x1b]133;B\x07\x1b]133;C\x07 last`, - ]); - }); }); diff --git a/apps/kimi-code/test/tui/components/chrome/welcome.test.ts b/apps/kimi-code/test/tui/components/chrome/welcome.test.ts index 47e6b7a0f..18eef1440 100644 --- a/apps/kimi-code/test/tui/components/chrome/welcome.test.ts +++ b/apps/kimi-code/test/tui/components/chrome/welcome.test.ts @@ -29,7 +29,6 @@ const appState: AppState = { planMode: false, inputMode: 'prompt', swarmMode: false, - towerMode: false, theme: 'dark', editorCommand: null, notifications: { enabled: true, condition: 'unfocused' }, diff --git a/apps/kimi-code/test/tui/components/dialogs/model-selector.test.ts b/apps/kimi-code/test/tui/components/dialogs/model-selector.test.ts index e5159ec0d..8fced4176 100644 --- a/apps/kimi-code/test/tui/components/dialogs/model-selector.test.ts +++ b/apps/kimi-code/test/tui/components/dialogs/model-selector.test.ts @@ -99,39 +99,6 @@ describe('ModelSelectorComponent', () => { expect(text(picker)).toContain('Thinking (←→ to switch)'); }); - it('hides the Thinking footer when thinkingControl is false', () => { - const picker = new ModelSelectorComponent({ - models: { kimi: model('Kimi K2', ['thinking']) }, - currentValue: 'kimi', - currentThinkingEffort: 'on', - thinkingControl: false, - onSelect: vi.fn(), - onCancel: vi.fn(), - }); - - expect(text(picker)).not.toContain('Thinking'); - }); - - it('ignores Left/Right when thinkingControl is false', () => { - const onSelect = vi.fn(); - const picker = new ModelSelectorComponent({ - models: { kimi: model('Kimi K2', ['thinking']) }, - currentValue: 'kimi', - currentThinkingEffort: 'on', - thinkingControl: false, - onSelect, - onCancel: vi.fn(), - }); - - // Same setup as the toggle test above: either arrow would flip 'on' to 'off'. - picker.handleInput(LEFT); - picker.handleInput('\r'); - expect(onSelect).toHaveBeenLastCalledWith({ alias: 'kimi', thinking: 'on' }); - picker.handleInput(RIGHT); - picker.handleInput('\r'); - expect(onSelect).toHaveBeenLastCalledWith({ alias: 'kimi', thinking: 'on' }); - }); - it('forces always-thinking models on and unsupported models off', () => { const onSelect = vi.fn(); const picker = new ModelSelectorComponent({ diff --git a/apps/kimi-code/test/tui/components/dialogs/plugins-selector.test.ts b/apps/kimi-code/test/tui/components/dialogs/plugins-selector.test.ts index f7aef8e76..abfde3668 100644 --- a/apps/kimi-code/test/tui/components/dialogs/plugins-selector.test.ts +++ b/apps/kimi-code/test/tui/components/dialogs/plugins-selector.test.ts @@ -195,33 +195,6 @@ describe('plugins selector dialogs', () => { })).toBe('third-party'); }); - it('trusts the .ai Kimi plugin hosts with the same path rules', () => { - const labelFor = (originalSource: string) => - pluginTrustLabel({ - id: 'demo', - displayName: 'Demo', - enabled: true, - state: 'ok', - skillCount: 0, - mcpServerCount: 0, - enabledMcpServerCount: 0, - hookCount: 0, - commandCount: 0, - hasErrors: false, - source: 'zip-url', - originalSource, - }); - // code.kimi.ai mirrors the cdnBase rules; cdn.kimi.ai the content-CDN ones. - expect(labelFor('https://code.kimi.ai/kimi-code/plugins/official/kimi-datasource.zip')).toBe('official'); - expect(labelFor('https://code.kimi.ai/kimi-code/plugins/curated/superpowers.zip')).toBe('curated'); - expect(labelFor('https://cdn.kimi.ai/kimi-computer-use/latest/kimi-cu-plugin.zip')).toBe('official'); - expect(labelFor('https://cdn.kimi.ai/kimi-computer-use-windows/latest/kimi-cu-win-plugin.zip')).toBe('official'); - // Non-plugin paths on the .ai hosts, and lookalike hosts, stay third-party. - expect(labelFor('https://code.kimi.ai/demo.zip')).toBe('third-party'); - expect(labelFor('https://cdn.kimi.ai/unrelated/plugin.zip')).toBe('third-party'); - expect(labelFor('https://code.kimi.ai.example.test/kimi-code/plugins/official/x.zip')).toBe('third-party'); - }); - it('recognizes installed plugins by official provenance', () => { const base = { id: 'kimi-datasource', @@ -241,11 +214,6 @@ describe('plugins selector dialogs', () => { source: 'zip-url', originalSource: 'https://code.kimi.com/kimi-code/plugins/official/kimi-datasource.zip', })).toBe(true); - expect(isOfficialPluginInstall({ - ...base, - source: 'zip-url', - originalSource: 'https://code.kimi.ai/kimi-code/plugins/official/kimi-datasource.zip', - })).toBe(true); expect(isOfficialPluginInstall({ ...base, id: 'kimi-cu', @@ -304,16 +272,6 @@ describe('plugins selector dialogs', () => { 'https://cdn.kimi.com/kimi-computer-use-windows/latest/kimi-cu-win-plugin.zip', ), ).toBe(true); - // The .ai region family follows the same path rules. - expect(isOfficialPluginSource('https://code.kimi.ai/kimi-code/plugins/official/kimi-datasource.zip')).toBe(true); - expect(isOfficialPluginSource('https://cdn.kimi.ai/kimi-computer-use/latest/kimi-cu-plugin.zip')).toBe(true); - expect( - isOfficialPluginSource( - 'https://cdn.kimi.ai/kimi-computer-use-windows/latest/kimi-cu-win-plugin.zip', - ), - ).toBe(true); - expect(isOfficialPluginSource('https://code.kimi.ai/kimi-code/plugins/curated/superpowers.zip')).toBe(false); - expect(isOfficialPluginSource('https://cdn.kimi.ai/unrelated/plugin.zip')).toBe(false); // Curated and other Kimi CDN paths are not "official" for the install gate. expect(isOfficialPluginSource('https://code.kimi.com/kimi-code/plugins/curated/superpowers.zip')).toBe(false); expect(isOfficialPluginSource('https://code.kimi.com/kimi-code/plugins/foo.zip')).toBe(false); diff --git a/apps/kimi-code/test/tui/components/dialogs/tabbed-model-selector.test.ts b/apps/kimi-code/test/tui/components/dialogs/tabbed-model-selector.test.ts index c202e0bf8..f6ffc6496 100644 --- a/apps/kimi-code/test/tui/components/dialogs/tabbed-model-selector.test.ts +++ b/apps/kimi-code/test/tui/components/dialogs/tabbed-model-selector.test.ts @@ -139,12 +139,12 @@ describe('TabbedModelSelectorComponent', () => { models: { k2: model('Kimi K2', 'managed:kimi-code') }, currentValue: 'k2', currentThinkingEffort: 'off', - title: ' Choose a model for this task', + title: ' Select a secondary model (subagents)', onSelect: vi.fn(), onCancel: vi.fn(), }); const out = strip(titled.render(120).join('\n')); - expect(out).toContain('Choose a model for this task'); + expect(out).toContain('Select a secondary model (subagents)'); expect(out).not.toContain('Select a model '); }); diff --git a/apps/kimi-code/test/tui/components/dialogs/trust-prompt.test.ts b/apps/kimi-code/test/tui/components/dialogs/trust-prompt.test.ts index 4fe7d5361..389b21149 100644 --- a/apps/kimi-code/test/tui/components/dialogs/trust-prompt.test.ts +++ b/apps/kimi-code/test/tui/components/dialogs/trust-prompt.test.ts @@ -1,7 +1,5 @@ import { describe, expect, it, vi } from 'vitest'; -import type { WorkspaceTrustMcpServerInfo } from '@moonshot-ai/kimi-code-sdk'; - import { TrustPromptComponent } from '#/tui/components/dialogs/trust-prompt'; const ANSI_SGR = /\[[0-9;]*m/g; @@ -10,7 +8,7 @@ function strip(text: string): string { return text.replaceAll(ANSI_SGR, ''); } -function renderLines(gatedMcpServers: readonly WorkspaceTrustMcpServerInfo[] = []): string[] { +function renderLines(gatedMcpServers: readonly string[] = []): string[] { const prompt = new TrustPromptComponent({ workDir: '/tmp/demo-workspace', gatedMcpServers, @@ -32,30 +30,14 @@ describe('TrustPromptComponent', () => { }); it('lists the gated project MCP servers when present', () => { - const lines = renderLines([ - { name: 'nested-server', transport: 'stdio', command: 'nested-cmd', args: ['--safe'], cwd: '/tmp' }, - { name: 'root-server', transport: 'http', url: 'https://example.test/mcp' }, - ]); - expect(lines.some((l) => l.includes('Project MCP targets'))).toBe(true); - expect(lines.some((l) => l.includes('nested-server (stdio): command=nested-cmd'))).toBe(true); - expect(lines.some((l) => l.includes('args=["--safe"] cwd=/tmp'))).toBe(true); - expect(lines.some((l) => l.includes('root-server (http): url=https://example.test/mcp'))).toBe(true); + const lines = renderLines(['nested-server', 'root-server']); + expect(lines.some((l) => l.includes('This folder defines'))).toBe(true); + expect(lines.some((l) => l.includes('nested-server'))).toBe(true); + expect(lines.some((l) => l.includes('root-server'))).toBe(true); expect(renderLines().some((l) => l.includes('This folder defines'))).toBe(false); }); - it('strips terminal control characters from workspace-supplied MCP targets', () => { - const lines = renderLines([ - { name: 'evil', transport: 'stdio', command: 'cmd\u001B[2J\u0007evil' }, - { name: 'multi\nline', transport: 'http', url: 'https://example.test/\u001B]8;;https://evil.test\u0007' }, - ]); - const text = lines.join('\n'); - // ESC and BEL are dropped, defusing the sequences into harmless literal text. - expect(text).toContain('evil (stdio): command=cmd[2Jevil'); - expect(text).toContain('multiline (http): url=https://example.test/]8;;https://evil.test'); - expect(text).not.toContain('\u001B]8;;https://evil.test'); - }); - - it("defaults to Don't trust", () => { + it('selects trust on Enter with the default highlight', () => { const onSelect = vi.fn(); const prompt = new TrustPromptComponent({ workDir: '/tmp/demo-workspace', @@ -63,18 +45,6 @@ describe('TrustPromptComponent', () => { onSelect, }); prompt.handleInput('\r'); - expect(onSelect).toHaveBeenCalledWith('distrust'); - }); - - it('selects trust only after moving to it explicitly', () => { - const onSelect = vi.fn(); - const prompt = new TrustPromptComponent({ - workDir: '/tmp/demo-workspace', - gatedMcpServers: [], - onSelect, - }); - prompt.handleInput('\u001B[A'); - prompt.handleInput('\r'); expect(onSelect).toHaveBeenCalledWith('trust'); }); diff --git a/apps/kimi-code/test/tui/components/editor/custom-editor.test.ts b/apps/kimi-code/test/tui/components/editor/custom-editor.test.ts index 6b68d83e1..f66c92e7d 100644 --- a/apps/kimi-code/test/tui/components/editor/custom-editor.test.ts +++ b/apps/kimi-code/test/tui/components/editor/custom-editor.test.ts @@ -516,6 +516,8 @@ describe('CustomEditor paste marker expansion', () => { expect(editor.getText()).toContain('[paste #1'); expect(editor.getText()).toContain('[paste #2'); + editor.setText('[paste #1 +15 lines] [paste #2 +15 lines]'); + simulateLargePaste(editor, 'anything'); expect(editor.getText()).toContain('[paste #1'); @@ -548,9 +550,7 @@ describe('CustomEditor paste marker expansion', () => { simulateLargePaste(editor, 'anything'); expect(editor.getText()).toContain(longText); - // Undo (Ctrl+-) restores both the marker text and its paste-registry entry. - editor.handleInput('\x1b[45;5u'); - expect(editor.getText()).toContain('[paste #1'); + editor.setText(markerText); simulateLargePaste(editor, 'anything'); expect(editor.getText()).not.toContain('[paste #'); @@ -615,33 +615,6 @@ describe('CustomEditor paste marker expansion', () => { process.off('unhandledRejection', onRejection); } }); - - it('queues Enter and typing until an asynchronous image paste inserts its placeholder', async () => { - const editor = makeEditor(); - const submit = vi.fn(); - editor.onSubmit = submit; - let resolvePaste!: (handled: boolean) => void; - editor.onPasteImage = () => - new Promise<boolean>((resolve) => { - resolvePaste = (handled) => { - editor.insertTextAtCursor?.('[image #1 (1×1)] '); - resolve(handled); - }; - }); - - const pasteKey = process.platform === 'win32' ? '\u001Bv' : '\u0016'; - editor.handleInput(pasteKey); - editor.handleInput('hello'); - editor.handleInput('\r'); - - expect(editor.getText()).toBe(''); - expect(submit).not.toHaveBeenCalled(); - - resolvePaste(true); - await new Promise((resolve) => setImmediate(resolve)); - - expect(submit).toHaveBeenCalledWith('[image #1 (1×1)] hello'); - }); }); describe('CustomEditor shortcut telemetry hooks', () => { diff --git a/apps/kimi-code/test/tui/components/editor/file-mention-provider.test.ts b/apps/kimi-code/test/tui/components/editor/file-mention-provider.test.ts index de34a88c0..b53b49a83 100644 --- a/apps/kimi-code/test/tui/components/editor/file-mention-provider.test.ts +++ b/apps/kimi-code/test/tui/components/editor/file-mention-provider.test.ts @@ -640,143 +640,4 @@ describe('FileMentionProvider', () => { expect(result?.items.map((item) => item.label)).toContain('shared/'); }); }); - - describe('inline skill completion', () => { - const REVIEW_COMMAND = { - name: 'skill:review', - aliases: [], - description: 'Review changes', - }; - const SECURITY_COMMAND = { - name: 'skill:security', - aliases: [], - description: 'Check security', - }; - const SKILL_NAMES = new Set(['skill:review', 'skill:security']); - - function skillProvider( - commands: ConstructorParameters<typeof FileMentionProvider>[0] = [ - REVIEW_COMMAND, - SECURITY_COMMAND, - HELP_COMMAND, - ], - ) { - return new FileMentionProvider( - commands, - workDir, - NO_FD, - [], - () => 'prompt', - SKILL_NAMES, - ); - } - - it('offers skill-only suggestions for a `/` after whitespace mid-input', async () => { - const provider = skillProvider(); - const line = 'hello /'; - const result = await provider.getSuggestions([line], 0, line.length, { signal: ctrl() }); - - expect(result).not.toBeNull(); - expect(result!.prefix).toBe('/'); - expect(result!.items.map((item) => item.value).sort()).toEqual([ - 'skill:review', - 'skill:security', - ]); - }); - - it('filters inline suggestions by the typed prefix', async () => { - const provider = skillProvider(); - const line = 'hello /rev'; - const result = await provider.getSuggestions([line], 0, line.length, { signal: ctrl() }); - - expect(result).not.toBeNull(); - expect(result!.prefix).toBe('/rev'); - expect(result!.items.map((item) => item.value)).toEqual(['skill:review']); - }); - - it('offers the skill picker for a `/` at the start of a later line', async () => { - const provider = skillProvider(); - const result = await provider.getSuggestions(['first line', '/'], 1, 1, { signal: ctrl() }); - - expect(result).not.toBeNull(); - expect(result!.items.map((item) => item.value).sort()).toEqual([ - 'skill:review', - 'skill:security', - ]); - }); - - it('stays in skill-only mode while typing a token on a later line', async () => { - const provider = skillProvider(); - const result = await provider.getSuggestions(['first line', '/rev'], 1, 4, { - signal: ctrl(), - }); - - expect(result).not.toBeNull(); - expect(result!.prefix).toBe('/rev'); - expect(result!.items.map((item) => item.value)).toEqual(['skill:review']); - }); - - it('offers inline skills on an indented later line', async () => { - const provider = skillProvider(); - const result = await provider.getSuggestions(['first line', ' /skill:rev'], 1, 12, { - signal: ctrl(), - }); - - expect(result).not.toBeNull(); - expect(result!.prefix).toBe('/skill:rev'); - expect(result!.items.map((item) => item.value)).toEqual(['skill:review']); - }); - - it('offers inline skills for an indented token on the first line', async () => { - const provider = skillProvider(); - const result = await provider.getSuggestions([' /skill:rev'], 0, 12, { signal: ctrl() }); - - expect(result).not.toBeNull(); - expect(result!.prefix).toBe('/skill:rev'); - expect(result!.items.map((item) => item.value)).toEqual(['skill:review']); - }); - - it('does not leak built-in commands onto later lines', async () => { - const provider = skillProvider(); - const result = await provider.getSuggestions(['first line', '/hel'], 1, 4, { - signal: ctrl(), - }); - - expect(result?.items.map((item) => item.value) ?? []).not.toContain('help'); - }); - - it('returns null for a prose slash when no skills are registered', async () => { - const provider = new FileMentionProvider([HELP_COMMAND], workDir, NO_FD, [], () => 'prompt'); - const line = 'hello /'; - const result = await provider.getSuggestions([line], 0, line.length, { signal: ctrl() }); - expect(result).toBeNull(); - }); - - it('keeps slash-command argument completions ahead of inline skills', async () => { - const provider = skillProvider([ADD_DIR_COMMAND, REVIEW_COMMAND]); - const line = '/add-dir /'; - const result = await provider.getSuggestions([line], 0, line.length, { - signal: ctrl(), - force: false, - }); - - expect(result).not.toBeNull(); - expect(result!.items.map((item) => item.value)).toEqual(['/tmp/shared/']); - }); - - it('applyCompletion preserves the slash and appends a trailing space', () => { - const provider = skillProvider(); - const line = 'hello /rev'; - const result = provider.applyCompletion( - [line], - 0, - line.length, - { value: 'skill:review', label: 'skill:review', data: { inlineSkill: true } }, - '/rev', - ); - - expect(result.lines[0]).toBe('hello /skill:review '); - expect(result.cursorCol).toBe('hello /skill:review '.length); - }); - }); }); diff --git a/apps/kimi-code/test/tui/components/editor/slash-highlight.test.ts b/apps/kimi-code/test/tui/components/editor/slash-highlight.test.ts index 02e885b3d..d47f29b56 100644 --- a/apps/kimi-code/test/tui/components/editor/slash-highlight.test.ts +++ b/apps/kimi-code/test/tui/components/editor/slash-highlight.test.ts @@ -1,7 +1,7 @@ import chalk from 'chalk'; import { describe, it, expect, beforeAll } from 'vitest'; -import { highlightFirstSlashToken, highlightInlineSkillTokens } from '#/tui/components/editor/custom-editor'; +import { highlightFirstSlashToken } from '#/tui/components/editor/custom-editor'; beforeAll(() => { // Vitest runs without a TTY so chalk auto-detects colour support as @@ -86,47 +86,3 @@ describe('highlightFirstSlashToken', () => { expect(out!).toContain(' /b'); }); }); - -describe('highlightInlineSkillTokens', () => { - const SKILLS = new Set(['skill:review', 'skill:security', 'commit']); - - it('colours known skill tokens anywhere in the line', () => { - const out = highlightInlineSkillTokens('please /skill:review this', SKILLS, null, 'primary'); - expect(out).toBeDefined(); - expect(strip(out!)).toBe('please /skill:review this'); - expectHighlighted(out!, '/skill:review'); - }); - - it('colours multiple skill tokens in one line', () => { - const out = highlightInlineSkillTokens( - '/skill:review then /skill:security', - SKILLS, - null, - 'primary', - ); - expect(out).toBeDefined(); - expectHighlighted(out!, '/skill:review'); - expectHighlighted(out!, '/skill:security'); - }); - - it('skips the excluded leading command range', () => { - const visible = '/skill:review args'; - const out = highlightInlineSkillTokens( - visible, - SKILLS, - { start: 0, end: 13 }, - 'primary', - ); - expect(out).toBeUndefined(); - }); - - it('ignores unknown tokens and plain slashes', () => { - expect(highlightInlineSkillTokens('and /not-a-skill or /tmp', SKILLS, null, 'primary')).toBeUndefined(); - }); - - it('supports the skill: prefix fallback for bare names', () => { - const out = highlightInlineSkillTokens('please /review this', SKILLS, null, 'primary'); - expect(out).toBeDefined(); - expectHighlighted(out!, '/review'); - }); -}); diff --git a/apps/kimi-code/test/tui/components/messages/assistant-message.test.ts b/apps/kimi-code/test/tui/components/messages/assistant-message.test.ts index 89dec20b9..e078e6dd2 100644 --- a/apps/kimi-code/test/tui/components/messages/assistant-message.test.ts +++ b/apps/kimi-code/test/tui/components/messages/assistant-message.test.ts @@ -5,7 +5,6 @@ import { describe, expect, it, vi } from 'vitest'; import { AssistantMessageComponent } from '#/tui/components/messages/assistant-message'; import { STATUS_BULLET } from '#/tui/constant/symbols'; import { createMarkdownTheme } from '#/tui/theme/pi-tui-theme'; -import { setMarkdownRenderLatex } from '#/tui/utils/markdown-options'; import { captureProcessWrite } from '../../../helpers/process'; @@ -18,9 +17,7 @@ vi.mock('cli-highlight', async () => { }); function strip(text: string): string { - return text - .replaceAll(/\u001B\[[0-9;]*m/g, '') - .replaceAll(/\u001B\]133;[ABC]\u0007/g, ''); + return text.replaceAll(/\u001B\[[0-9;]*m/g, ''); } describe('AssistantMessageComponent', () => { @@ -128,31 +125,4 @@ describe('AssistantMessageComponent', () => { finalTheme.highlightCode?.(code, 'typescript'); expect(highlightSpy).toHaveBeenCalled(); }); - - it('marks the rendered zone with OSC 133 markers, once across cache hits', () => { - const component = new AssistantMessageComponent(); - component.updateContent('hello'); - - const lines = component.render(80); - expect(lines[0]).toMatch(/^\u001B\]133;A\u0007/); - expect(lines[lines.length - 1]).toMatch(/^\u001B\]133;B\u0007\u001B\]133;C\u0007/); - - const cached = component.render(80); - expect(cached[0]).toBe(lines[0]); - }); - - it('renders LaTeX math by default and keeps raw source when disabled', () => { - const component = new AssistantMessageComponent(); - try { - setMarkdownRenderLatex(true); - component.updateContent('能量公式 $E = mc^2$'); - expect(strip(component.render(80).join('\n'))).toContain('E = mc²'); - - setMarkdownRenderLatex(false); - component.invalidate(); - expect(strip(component.render(80).join('\n'))).toContain('$E = mc^2$'); - } finally { - setMarkdownRenderLatex(true); - } - }); }); diff --git a/apps/kimi-code/test/tui/components/messages/shell-run.test.ts b/apps/kimi-code/test/tui/components/messages/shell-run.test.ts index be89c6f03..510da06bd 100644 --- a/apps/kimi-code/test/tui/components/messages/shell-run.test.ts +++ b/apps/kimi-code/test/tui/components/messages/shell-run.test.ts @@ -68,110 +68,3 @@ describe('ShellRunComponent hardening', () => { }).not.toThrow(); }); }); - -describe('ShellRunComponent finished collapse', () => { - let component: ShellRunComponent | undefined; - - afterEach(() => { - component?.dispose(); - component = undefined; - }); - - function create(): ShellRunComponent { - component = new ShellRunComponent(() => {}); - return component; - } - - function rows(n: number): string { - return Array.from({ length: n }, (_, i) => `row-${String(i + 1).padStart(2, '0')}`).join('\n'); - } - - it('collapses finished output to the first 10 visual rows with an expand hint', () => { - const c = create(); - c.finish(rows(30), '', false); - const rendered = stripTheme(c.render(80).join('\n')); - expect(rendered).toContain('... (20 more lines, ctrl+o to expand)'); - expect(rendered).toContain('row-01'); - expect(rendered).toContain('row-10'); - expect(rendered).not.toContain('row-11'); - }); - - it('renders short finished output in full without a hint', () => { - const c = create(); - c.finish(rows(10), '', false); - const rendered = stripTheme(c.render(80).join('\n')); - expect(rendered).toContain('row-01'); - expect(rendered).toContain('row-10'); - expect(rendered).not.toContain('more lines'); - }); - - it('setExpanded toggles the finished view', () => { - const c = create(); - c.finish(rows(30), '', false); - - c.setExpanded(true); - const expanded = stripTheme(c.render(80).join('\n')); - expect(expanded).toContain('row-30'); - expect(expanded).not.toContain('more lines'); - - c.setExpanded(false); - const collapsed = stripTheme(c.render(80).join('\n')); - expect(collapsed).toContain('... (20 more lines, ctrl+o to expand)'); - expect(collapsed).not.toContain('row-11'); - }); - - it('expands the running view via setExpanded', () => { - const c = create(); - c.append(rows(10)); - - c.setExpanded(true); - const expanded = stripTheme(c.render(80).join('\n')); - expect(expanded).toContain('row-01'); - expect(expanded).toContain('row-10'); - expect(expanded).toContain('(ctrl+b to run in background)'); - expect(expanded).not.toContain('+5 lines'); - - c.setExpanded(false); - const collapsed = stripTheme(c.render(80).join('\n')); - expect(collapsed).toContain('+5 lines'); - expect(collapsed).not.toContain('row-01'); - }); - - it('carries the expanded state over to the finished view', () => { - const c = create(); - c.append(rows(10)); - c.setExpanded(true); - - c.finish(rows(30), '', false); - const finished = stripTheme(c.render(80).join('\n')); - expect(finished).toContain('row-30'); - expect(finished).not.toContain('more lines'); - }); - - it('flags a truncated buffer in the expanded running view', () => { - const c = create(); - c.append('x'.repeat(300 * 1024)); - c.setExpanded(true); - const rendered = stripTheme(c.render(80).join('\n')); - expect(rendered).toContain('... (output truncated)'); - }); - - it('keeps the backgrounded view when toggled', () => { - const c = create(); - c.finishBackgrounded(); - c.setExpanded(true); - const rendered = stripTheme(c.render(80).join('\n')); - expect(rendered).toContain('Moved to background.'); - }); - - it('collapses failed output the same way instead of auto-expanding', () => { - const c = create(); - c.finish(rows(30), 'boom', true); - const collapsed = stripTheme(c.render(80).join('\n')); - expect(collapsed).toContain('... (21 more lines, ctrl+o to expand)'); - - c.setExpanded(true); - const expanded = stripTheme(c.render(80).join('\n')); - expect(expanded).toContain('boom'); - }); -}); diff --git a/apps/kimi-code/test/tui/components/messages/status-panel.test.ts b/apps/kimi-code/test/tui/components/messages/status-panel.test.ts index fd534ab85..0e81fda89 100644 --- a/apps/kimi-code/test/tui/components/messages/status-panel.test.ts +++ b/apps/kimi-code/test/tui/components/messages/status-panel.test.ts @@ -17,8 +17,6 @@ describe('status panel report lines', () => { thinkingEffort: 'on', permissionMode: 'manual', planMode: false, - towerMode: false, - towerAvailable: true, contextUsage: 0.25, contextTokens: 2500, maxContextTokens: 10000, @@ -71,58 +69,6 @@ describe('status panel report lines', () => { expect(output).not.toContain('Runtime'); }); - it('prefers the fetched status tower mode over the cached value', () => { - const lines = buildStatusReportLines({ - version: '1.2.3', - model: 'k2', - workDir: '/tmp/project', - sessionId: 'ses-1', - sessionTitle: null, - thinkingEffort: 'off', - permissionMode: 'manual', - planMode: false, - towerMode: false, - towerAvailable: true, - contextUsage: 0, - contextTokens: 0, - maxContextTokens: 0, - availableModels: {}, - status: { - model: 'k2', - thinkingEffort: 'off', - permission: 'manual', - planMode: false, - towerMode: true, - contextTokens: 0, - maxContextTokens: 0, - contextUsage: 0, - }, - }).map(strip); - - expect(lines.join('\n')).toContain('Tower mode on'); - }); - - it('omits the tower mode row when the experiment is unavailable', () => { - const lines = buildStatusReportLines({ - version: '1.2.3', - model: 'k2', - workDir: '/tmp/project', - sessionId: 'ses-1', - sessionTitle: null, - thinkingEffort: 'off', - permissionMode: 'manual', - planMode: false, - towerMode: false, - towerAvailable: false, - contextUsage: 0, - contextTokens: 0, - maxContextTokens: 0, - availableModels: {}, - }).map(strip); - - expect(lines.join('\n')).not.toContain('Tower mode'); - }); - it('formats extra usage section in status report', () => { const lines = buildStatusReportLines({ version: '1.2.3', @@ -133,8 +79,6 @@ describe('status panel report lines', () => { thinkingEffort: 'off', permissionMode: 'manual', planMode: false, - towerMode: false, - towerAvailable: true, contextUsage: 0, contextTokens: 0, maxContextTokens: 0, @@ -173,8 +117,6 @@ describe('status panel report lines', () => { thinkingEffort: 'off', permissionMode: 'manual', planMode: false, - towerMode: false, - towerAvailable: true, contextUsage: 0, contextTokens: 0, maxContextTokens: 0, diff --git a/apps/kimi-code/test/tui/components/messages/tool-call.test.ts b/apps/kimi-code/test/tui/components/messages/tool-call.test.ts index 367e62a56..4426e0e5a 100644 --- a/apps/kimi-code/test/tui/components/messages/tool-call.test.ts +++ b/apps/kimi-code/test/tui/components/messages/tool-call.test.ts @@ -1933,179 +1933,4 @@ describe('ToolCallComponent', () => { stderr.restore(); } }); - - describe('WaitFor header', () => { - const waitForCompletedOutput = [ - 'wait_status: completed', - 'task_id: question-80w0h7nw', - 'waited_ms: 9607', - 'timeout_ms: 300000', - '', - '[finished]', - 'task_id: question-80w0h7nw', - 'description: demo question', - 'status: completed', - 'kind: question', - ].join('\n'); - - it('shows the waiting tense with the task id while pending', () => { - const component = new ToolCallComponent( - { - id: 'call_wait_pending', - name: 'WaitFor', - args: { task_id: 'question-80w0h7nw', timeout: 300 }, - }, - undefined, - stubTui(30), - ); - - expect(strip(component.render(100).join('\n'))).toContain( - 'Waiting for background task (question-80w0h7nw)', - ); - - component.dispose(); - }); - - it('falls back to "any background task" when no task id is given', () => { - const component = new ToolCallComponent( - { id: 'call_wait_any', name: 'WaitFor', args: { timeout: 300 } }, - undefined, - stubTui(30), - ); - - expect(strip(component.render(100).join('\n'))).toContain('Waiting for any background task'); - - component.dispose(); - }); - - it('shows the waited tense with the elapsed chip once completed', () => { - const component = new ToolCallComponent( - { - id: 'call_wait_done', - name: 'WaitFor', - args: { task_id: 'question-80w0h7nw', timeout: 300 }, - }, - { - tool_call_id: 'call_wait_done', - output: waitForCompletedOutput, - is_error: false, - }, - ); - - const out = strip(component.render(100).join('\n')); - expect(out).toContain('Waited for background task (question-80w0h7nw)'); - expect(out).toContain('10s'); - }); - - it('renders a timeout as its own non-error header', () => { - const component = new ToolCallComponent( - { - id: 'call_wait_timeout', - name: 'WaitFor', - args: { task_id: 'question-80w0h7nw', timeout: 1 }, - }, - { - tool_call_id: 'call_wait_timeout', - output: 'wait_status: timed_out\ntask_id: question-80w0h7nw\nwaited_ms: 1000\ntimeout_ms: 1000', - is_error: false, - }, - ); - - expect(strip(component.render(100).join('\n'))).toContain( - 'Wait timed out (question-80w0h7nw)', - ); - }); - - it('renders errors with the failure tense', () => { - const component = new ToolCallComponent( - { - id: 'call_wait_error', - name: 'WaitFor', - args: { task_id: 'bash-x', timeout: 300 }, - }, - { - tool_call_id: 'call_wait_error', - output: 'Task not found: bash-x', - is_error: true, - }, - ); - - expect(strip(component.render(100).join('\n'))).toContain( - 'Could not wait for background task (bash-x)', - ); - }); - - it('replaces the previous status block when progress arrives with replace', () => { - const component = new ToolCallComponent( - { id: 'call_wait_replace', name: 'WaitFor', args: { timeout: 600 } }, - undefined, - stubTui(30), - ); - - component.appendProgress('Waiting 10s / 600s · 2 background tasks still running', { - replace: true, - }); - component.appendProgress('Waiting 20s / 600s · 1 background task still running', { - replace: true, - }); - - const out = strip(component.render(100).join('\n')); - expect(out).toContain('Waiting 20s / 600s'); - expect(out).not.toContain('Waiting 10s / 600s'); - - component.dispose(); - }); - - it('keeps appending status rows when replace is not set', () => { - const component = new ToolCallComponent( - { id: 'call_wait_append', name: 'WaitFor', args: { timeout: 600 } }, - undefined, - stubTui(30), - ); - - component.appendProgress('first status'); - component.appendProgress('second status'); - - const out = strip(component.render(100).join('\n')); - expect(out).toContain('first status'); - expect(out).toContain('second status'); - - component.dispose(); - }); - - it('replaces a sub-tool status row when child progress arrives with replace', () => { - const component = new ToolCallComponent( - { id: 'call_agent_wait', name: 'Agent', args: { description: 'child wait' } }, - undefined, - stubTui(30), - ); - component.onSubagentSpawned({ - agentId: 'sub_wait_1', - agentName: 'coder', - runInBackground: false, - }); - component.appendSubToolCall({ - id: 'sub_wait_1:wait', - name: 'WaitFor', - args: { timeout: 600 }, - }); - - component.appendSubToolLiveOutput( - 'sub_wait_1:wait', - 'Waiting 10s / 600s · 2 background tasks still running\n', - { replace: true }, - ); - component.appendSubToolLiveOutput( - 'sub_wait_1:wait', - 'Waiting 20s / 600s · 1 background task still running\n', - { replace: true }, - ); - - const out = strip(component.render(120).join('\n')); - expect(out).toContain('Waiting 20s / 600s'); - expect(out).not.toContain('Waiting 10s / 600s'); - - component.dispose(); - }); - }); }); diff --git a/apps/kimi-code/test/tui/components/messages/tool-renderers/registry.test.ts b/apps/kimi-code/test/tui/components/messages/tool-renderers/registry.test.ts index cff95e628..6570aac46 100644 --- a/apps/kimi-code/test/tui/components/messages/tool-renderers/registry.test.ts +++ b/apps/kimi-code/test/tui/components/messages/tool-renderers/registry.test.ts @@ -250,125 +250,4 @@ describe('tool-result registry', () => { expect(out).not.toContain(longLine); expect(out).toContain('... ('); }); - - const waitForCompletedOutput = [ - 'wait_status: completed', - 'task_id: question-80w0h7nw', - 'waited_ms: 9607', - 'timeout_ms: 300000', - '', - '[finished]', - 'task_id: question-80w0h7nw', - 'description: Pick one so I can demonstrate WaitFor with background questions?', - 'status: completed', - 'kind: question', - '', - '[output]', - '{"answers":{"Pick one":"Beta"}}', - ].join('\n'); - - it('WaitFor completed renders the finished task instead of raw fields', () => { - const renderer = pickResultRenderer('WaitFor'); - const out = strip( - joinRender( - renderer(call('WaitFor', { task_id: 'question-80w0h7nw' }), result(waitForCompletedOutput), ctx), - ), - ); - expect(out).toContain('✓ question-80w0h7nw completed'); - expect(out).toContain('Pick one so I can demonstrate'); - expect(out).not.toContain('waited_ms'); - expect(out).not.toContain('[finished]'); - }); - - it('WaitFor completed expands to the raw timeline output', () => { - const renderer = pickResultRenderer('WaitFor'); - const out = strip( - joinRender( - renderer( - call('WaitFor', { task_id: 'question-80w0h7nw' }), - result(waitForCompletedOutput), - expandedCtx, - ), - ), - ); - expect(out).toContain('[finished]'); - expect(out).toContain('waited_ms: 9607'); - }); - - it('WaitFor completed mentions extras and still-running counts', () => { - const output = [ - 'wait_status: completed', - 'task_id: bash-a1', - 'waited_ms: 1200', - 'timeout_ms: 30000', - '', - '[finished]', - 'task_id: bash-a1', - 'description: main wait', - 'status: failed', - '', - '[completed_during_wait]', - 'task_id: bash-b2', - 'description: side task', - 'status: completed', - '', - '[still_running]', - 'active_background_tasks: 2', - 'task_id: bash-c3', - 'description: slow one', - 'status: running', - '---', - 'task_id: agent-d4', - 'description: another slow one', - 'status: running', - ].join('\n'); - const renderer = pickResultRenderer('WaitFor'); - const out = strip(joinRender(renderer(call('WaitFor', { task_id: 'bash-a1' }), result(output), ctx))); - expect(out).toContain('✗ bash-a1 failed'); - expect(out).toContain('+1 more finished during wait'); - expect(out).toContain('2 background tasks still running'); - }); - - it('WaitFor timed_out lists the still-running tasks without an error tone', () => { - const output = [ - 'wait_status: timed_out', - 'task_id: bash-a1', - 'waited_ms: 30000', - 'timeout_ms: 30000', - 'The wait ended before the task finished.', - '', - '[still_running]', - 'active_background_tasks: 2', - 'task_id: bash-a1', - 'description: bg sleep', - 'status: running', - '---', - 'task_id: agent-b2', - 'description: investigate flaky test', - 'status: running', - ].join('\n'); - const renderer = pickResultRenderer('WaitFor'); - const out = strip(joinRender(renderer(call('WaitFor', { task_id: 'bash-a1' }), result(output), ctx))); - expect(out).toContain('2 background tasks still running'); - expect(out).toContain('bg sleep'); - expect(out).toContain('investigate flaky test'); - expect(out).not.toContain('waited_ms'); - }); - - it('WaitFor no_tasks renders no body in collapsed state', () => { - const renderer = pickResultRenderer('WaitFor'); - const output = 'wait_status: no_tasks\nwaited_ms: 0\ntimeout_ms: 30000'; - const out = joinRender(renderer(call('WaitFor', { timeout: 30 }), result(output), ctx)); - expect(out.trim()).toBe(''); - }); - - it('WaitFor errors fall back to the truncated renderer', () => { - const renderer = pickResultRenderer('WaitFor'); - const out = strip( - joinRender( - renderer(call('WaitFor', { task_id: 'bash-x' }), result('Task not found: bash-x', true), ctx), - ), - ); - expect(out).toContain('Task not found: bash-x'); - }); }); diff --git a/apps/kimi-code/test/tui/components/messages/user-message.test.ts b/apps/kimi-code/test/tui/components/messages/user-message.test.ts index 7f8a1d1ae..e6a10a05c 100644 --- a/apps/kimi-code/test/tui/components/messages/user-message.test.ts +++ b/apps/kimi-code/test/tui/components/messages/user-message.test.ts @@ -5,9 +5,7 @@ import { UserMessageComponent } from '#/tui/components/messages/user-message'; import type { ImageAttachment } from '#/tui/utils/image-attachment-store'; function stripAnsi(text: string): string { - return text - .replaceAll(/\u001B\[[0-9;]*m/g, '') - .replaceAll(/\u001B\]133;[ABC]\u0007/g, ''); + return text.replaceAll(/\u001B\[[0-9;]*m/g, ''); } describe('UserMessageComponent', () => { @@ -106,16 +104,4 @@ describe('UserMessageComponent', () => { // The `$` sits at the leading column where the bullet used to be. expect(contentLine?.startsWith('$ ls')).toBe(true); }); - - it('marks the rendered zone with OSC 133 markers, once across cache hits', () => { - setCapabilities({ images: null, trueColor: true, hyperlinks: true }); - const component = new UserMessageComponent('hello', []); - - const lines = component.render(80); - expect(lines[0]).toMatch(/^\u001B\]133;A\u0007/); - expect(lines[lines.length - 1]).toMatch(/^\u001B\]133;B\u0007\u001B\]133;C\u0007/); - - const cached = component.render(80); - expect(cached[0]).toBe(lines[0]); - }); }); diff --git a/apps/kimi-code/test/tui/config.test.ts b/apps/kimi-code/test/tui/config.test.ts index 48df47303..9ae144a2b 100644 --- a/apps/kimi-code/test/tui/config.test.ts +++ b/apps/kimi-code/test/tui/config.test.ts @@ -60,7 +60,6 @@ auto_install = false expect(config).toEqual({ theme: 'light', - renderLatex: true, disablePasteBurst: false, cacheExpiryHint: true, editorCommand: 'code --wait', @@ -79,16 +78,6 @@ disable_paste_burst = true expect(config.disablePasteBurst).toBe(true); }); - it('defaults render_latex to true and parses false', () => { - expect(parseTuiConfig('').renderLatex).toBe(true); - - const config = parseTuiConfig(` -render_latex = false -`); - - expect(config.renderLatex).toBe(false); - }); - it('parses cache_expiry_hint', () => { const config = parseTuiConfig(` theme = "dark" @@ -106,7 +95,6 @@ command = " " expect(config).toEqual({ theme: 'auto', - renderLatex: true, disablePasteBurst: false, cacheExpiryHint: true, editorCommand: null, @@ -153,7 +141,6 @@ command = " " expect(await loadTuiConfig(filePath)).toEqual({ theme: 'light', - renderLatex: true, disablePasteBurst: false, cacheExpiryHint: true, editorCommand: 'vim', diff --git a/apps/kimi-code/test/tui/controllers/cache-hint-controller.test.ts b/apps/kimi-code/test/tui/controllers/cache-hint-controller.test.ts index b1c506fb1..99834d9d9 100644 --- a/apps/kimi-code/test/tui/controllers/cache-hint-controller.test.ts +++ b/apps/kimi-code/test/tui/controllers/cache-hint-controller.test.ts @@ -5,7 +5,6 @@ import { type CacheHintHost, } from '#/tui/controllers/cache-hint-controller'; import type { CacheHintConfig } from '#/utils/cache-hint-config'; -import type { ExtractionResult } from '#/tui/utils/image-placeholder'; const peekMock = vi.fn<() => CacheHintConfig | undefined>(() => undefined); const getMock = vi.fn(async (): Promise<CacheHintConfig | undefined> => undefined); @@ -53,13 +52,11 @@ function makeHost( mountEditorReplacement: vi.fn(), restoreEditor: vi.fn(), restoreInputText: vi.fn(), - recallStashedMedia: vi.fn(), showError: vi.fn(), createNewSession: vi.fn(async () => { if (overrides.createNewSessionFails !== true) state.appState.sessionId = 's2'; }), sendNormalUserInput: vi.fn(async () => undefined), - sendInlineSkillUserInput: vi.fn(async () => undefined), }; return { host, state }; } @@ -83,23 +80,6 @@ async function flush(times = 20): Promise<void> { for (let i = 0; i < times; i++) await new Promise((r) => setImmediate(r)); } -function uploadedExtraction(fileId: string, byte: number): ExtractionResult { - const path = `/tmp/${fileId}.png`; - return { - parts: [ - { type: 'text', text: `<image path="${path}"></image>` }, - { - type: 'image_url', - imageUrl: { url: `kimi-file://${fileId}?path=${encodeURIComponent(path)}` }, - }, - ], - hasMedia: true, - imageAttachmentIds: [1], - videoAttachmentIds: [], - imageSnapshots: [{ bytes: new Uint8Array([byte]), mime: 'image/png', width: 640, height: 480 }], - }; -} - beforeEach(() => { peekMock.mockReset().mockReturnValue(undefined); getMock.mockReset().mockResolvedValue(undefined); @@ -168,26 +148,6 @@ describe('CacheHintController scenario 2 (idle submit)', () => { vi.restoreAllMocks(); }); - it('releases a stashed inline-skill submit through the inline-skill path', async () => { - const { host } = makeHost(); - const controller = new CacheHintController(host); - controller.recordActivity(); - vi.spyOn(Date, 'now').mockReturnValue(Date.now() + 1200_000); - const activations = [{ skillName: 'review' }]; - expect(controller.maybeInterceptOnSubmit('check /skill:review', undefined, activations)).toBe( - true, - ); - await flush(); - vi.restoreAllMocks(); - - expect(host.sendInlineSkillUserInput).toHaveBeenCalledWith( - 'check /skill:review', - activations, - undefined, - ); - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - }); - it('fetches on a cold-cache submit and shows the dialog when a rule matches', async () => { getMock.mockResolvedValue(CONFIG); const { host } = makeHost(); @@ -247,34 +207,6 @@ describe('CacheHintController scenario 2 (idle submit)', () => { expect(host.restoreInputText).toHaveBeenLastCalledWith('hello\nworld'); }); - it('releases stashed media with recall semantics when the dialog is dismissed', async () => { - getMock.mockResolvedValue(CONFIG); - const { host } = makeHost(); - const controller = new CacheHintController(host); - controller.recordActivity(); - vi.spyOn(Date, 'now').mockReturnValue(Date.now() + 1200_000); - const extraction = uploadedExtraction('file-1', 1); - - expect(controller.maybeInterceptOnSubmit('describe [image #1 (1×1)]', extraction)).toBe(true); - await vi.waitFor(() => { - expect(host.mountEditorReplacement).toHaveBeenCalled(); - }); - vi.restoreAllMocks(); - - const dialog = (host.mountEditorReplacement as ReturnType<typeof vi.fn>).mock.calls[0]![0] as { - handleInput: (data: string) => void; - }; - dialog.handleInput('\u001B'); // dismiss - await flush(); - - // Nothing was sent; the draft is back in the editor and the stash's - // retains go through recall — without this the retain count never - // returns to zero and the upload can never be lease-deleted. - expect(host.sendNormalUserInput).not.toHaveBeenCalled(); - expect(host.restoreInputText).toHaveBeenCalledWith('describe [image #1 (1×1)]'); - expect(host.recallStashedMedia).toHaveBeenCalledWith(extraction); - }); - it('hands the stashed input back when the session switched during the fetch', async () => { const { host } = makeHost(); const controller = new CacheHintController(host); @@ -429,68 +361,6 @@ describe('CacheHintController scenario 2 (idle submit)', () => { expect(host.sendNormalUserInput).toHaveBeenCalledWith('hello', undefined); }); - it('resends an uploaded image inline after starting a new session', async () => { - peekMock.mockReturnValue(CONFIG); - const { host } = makeHost(); - const controller = new CacheHintController(host); - controller.recordActivity(); - vi.spyOn(Date, 'now').mockReturnValue(Date.now() + 1200_000); - const extraction = uploadedExtraction('file-1', 1); - - controller.maybeInterceptOnSubmit('describe [image #1 (1×1)]', extraction); - vi.restoreAllMocks(); - - const dialog = (host.mountEditorReplacement as ReturnType<typeof vi.fn>).mock.calls[0]![0] as { - handleInput: (data: string) => void; - }; - dialog.handleInput('\u001B[B'); - dialog.handleInput('\r'); - await flush(); - - const resend = vi.mocked(host.sendNormalUserInput).mock.calls[0]?.[1]; - expect(resend?.imageAttachmentIds).toEqual([]); - expect(resend?.parts).toContainEqual({ - type: 'image_url', - imageUrl: { url: 'data:image/png;base64,AQ==' }, - }); - }); - - it('resends every chained uploaded image inline after starting a new session', async () => { - getMock.mockResolvedValue(CONFIG); - const { host } = makeHost(); - const controller = new CacheHintController(host); - controller.recordActivity(); - vi.spyOn(Date, 'now').mockReturnValue(Date.now() + 1200_000); - - expect(controller.maybeInterceptOnSubmit('first', uploadedExtraction('file-1', 1))).toBe(true); - expect(controller.maybeInterceptOnSubmit('second', uploadedExtraction('file-2', 2))).toBe(true); - await vi.waitFor(() => { - expect(host.mountEditorReplacement).toHaveBeenCalled(); - }); - vi.restoreAllMocks(); - - const dialog = (host.mountEditorReplacement as ReturnType<typeof vi.fn>).mock.calls[0]![0] as { - handleInput: (data: string) => void; - }; - dialog.handleInput('\u001B[B'); - dialog.handleInput('\r'); - await flush(); - - const sendCalls = ( - host.sendNormalUserInput as unknown as { - mock: { calls: Array<[string, ExtractionResult | undefined]> }; - } - ).mock.calls; - const imageUrls = sendCalls.map(([, extraction]) => { - const imagePart = extraction?.parts.find((part) => part.type === 'image_url'); - return imagePart?.type === 'image_url' ? imagePart.imageUrl.url : undefined; - }); - expect(imageUrls).toEqual([ - 'data:image/png;base64,AQ==', - 'data:image/png;base64,Ag==', - ]); - }); - it('keeps the input when new-session creation fails', async () => { peekMock.mockReturnValue(CONFIG); const { host, state } = makeHost({ createNewSessionFails: true }); diff --git a/apps/kimi-code/test/tui/controllers/editor-keyboard-image-paste.test.ts b/apps/kimi-code/test/tui/controllers/editor-keyboard-image-paste.test.ts index 7737cb58f..b87b2d4d5 100644 --- a/apps/kimi-code/test/tui/controllers/editor-keyboard-image-paste.test.ts +++ b/apps/kimi-code/test/tui/controllers/editor-keyboard-image-paste.test.ts @@ -5,19 +5,14 @@ * - an oversized pasted image is downsampled while building the attachment, * so the stored bytes, the `[image #N (W×H)]` placeholder, and the eventual * submitted image all agree on the compressed size - * - the pre-compression original is recorded on the attachment in memory — - * never persisted at paste time, because the session whose - * media-originals dir it belongs in may not exist yet; dispatch-time - * caption resolution owns persistence (see image-placeholder tests) + * - the pre-compression original is persisted and recorded on the + * attachment, so the submitted prompt can announce the compression and + * point the model at the full-fidelity bytes * - a within-budget paste is stored byte-for-byte (fast path), with no * original recorded - * - on the v2 engine the final bytes are uploaded to the daemon file store - * with a crash-recovery TTL, and the attachment carries the returned id - * and expiry; an upload failure leaves the paste on the inline fallback */ -import { existsSync } from 'node:fs'; -import { mkdtemp, rm, writeFile } from 'node:fs/promises'; +import { mkdtemp, readFile, rm, unlink } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; @@ -44,23 +39,10 @@ vi.mock('#/utils/clipboard/clipboard-image', async (importActual) => { interface PasteHarness { readonly store: ImageAttachmentStore; readonly track: ReturnType<typeof vi.fn>; - /** Invoke the paste handler, then wait for the background ingestion to settle. */ pasteImage(): Promise<void>; - /** Invoke the paste handler only — background ingestion may still be pending. */ - pasteImageRaw(): Promise<boolean>; } -function createPasteHarness( - options: { - sessionDir?: string; - imageLimits?: ImageLimits; - engineV2?: boolean; - uploadFile?: ( - data: Uint8Array, - opts: { name: string; mimeType?: string; expiresInSec?: number }, - ) => Promise<{ id: string }>; - } = {}, -): PasteHarness { +function createPasteHarness(options: { sessionDir?: string; imageLimits?: ImageLimits } = {}): PasteHarness { const editor: Record<string, ((...args: never[]) => unknown) | undefined> = { setHistoryFilter: vi.fn() as unknown as (...args: never[]) => unknown, }; @@ -79,38 +61,28 @@ function createPasteHarness( ? undefined : { summary: { sessionDir: options.sessionDir } }, btwPanelController: { closeOrCancel: vi.fn(() => false) }, - engineV2: options.engineV2, track, showError: vi.fn(), openUndoSelector: vi.fn(), cancelRunningShellCommand: vi.fn(), } as unknown as EditorKeyboardHost; - if (options.imageLimits !== undefined || options.uploadFile !== undefined) { + if (options.imageLimits !== undefined) { (host as unknown as { harness: KimiHarness }).harness = { imageLimits: options.imageLimits, - uploadFile: options.uploadFile, } as unknown as KimiHarness; } const controller = new EditorKeyboardController(host, store); controller.install(); - const pasteImageRaw = (): Promise<boolean> => { - const handler = editor['onPasteImage']; - if (handler === undefined) throw new Error('onPasteImage handler not installed'); - return (handler as () => Promise<boolean>)(); - }; - return { store, track, async pasteImage() { - await pasteImageRaw(); - for (let id = 1; id <= store.size(); id++) { - await store.get(id)?.pending; - } + const handler = editor['onPasteImage']; + if (handler === undefined) throw new Error('onPasteImage handler not installed'); + await (handler as () => Promise<boolean>)(); }, - pasteImageRaw, }; } @@ -126,14 +98,6 @@ async function solidJpeg(width: number, height: number): Promise<Uint8Array> { ); } -/** Typed `uploadFile` stub so `mock.calls` keeps the (data, options) tuple. */ -function uploadFileMock(id: string) { - return vi.fn(async ( - _data: Uint8Array, - _opts: { name: string; mimeType?: string; expiresInSec?: number }, - ) => ({ id, expires_at: '2030-01-02T03:04:05.000Z' })); -} - /** * Insert a minimal EXIF APP1 segment carrying only an Orientation tag right * after the JPEG SOI marker (jimp itself never writes EXIF). Mirrors the @@ -212,7 +176,7 @@ describe('clipboard image paste compression', () => { expect(Math.max(dims!.width, dims!.height)).toBe(800); }); - it('records the pre-compression original in memory for an oversized paste', async () => { + it('records and persists the pre-compression original for an oversized paste', async () => { const big = await solidPng(3600, 1800); readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: big, mimeType: 'image/png' }); @@ -222,18 +186,19 @@ describe('clipboard image paste compression', () => { const att = store.get(1); if (att?.kind !== 'image') throw new Error('expected image attachment'); expect(att.original).toBeDefined(); - expect(att.original?.bytes).toEqual(big); expect(att.original?.width).toBe(3600); expect(att.original?.height).toBe(1800); expect(att.original?.byteLength).toBe(big.length); expect(att.original?.mime).toBe('image/png'); - // Nothing is persisted at paste time — dispatch-time caption resolution - // owns that, once the session (and its media-originals dir) is known. - expect(att.original?.path).toBeUndefined(); + // The original bytes are readable back from the persisted path. + expect(att.original?.path).not.toBeNull(); + const persisted = await readFile(att.original!.path!); + expect(new Uint8Array(persisted)).toEqual(big); + await unlink(att.original!.path!).catch(() => undefined); }); - it('does not persist the original at paste time, even with a known session', async () => { + it('persists the original into the session media-originals dir when the session is known', async () => { const sessionDir = await mkdtemp(join(tmpdir(), 'kimi-paste-session-')); const big = await solidPng(3600, 1800); readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: big, mimeType: 'image/png' }); @@ -243,9 +208,10 @@ describe('clipboard image paste compression', () => { const att = store.get(1); if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.original?.bytes).toEqual(big); - expect(att.original?.path).toBeUndefined(); - expect(existsSync(join(sessionDir, 'media-originals'))).toBe(false); + expect(att.original?.path).not.toBeNull(); + expect(att.original!.path!.startsWith(join(sessionDir, 'media-originals'))).toBe(true); + const persisted = await readFile(att.original!.path!); + expect(new Uint8Array(persisted)).toEqual(big); await rm(sessionDir, { recursive: true, force: true }); }); @@ -290,6 +256,7 @@ describe('clipboard image paste compression', () => { expect(att.original?.height).toBe(3600); // The compressed attachment itself keeps the portrait aspect. expect(att.width).toBeLessThan(att.height); + await unlink(att.original!.path!).catch(() => undefined); }, 15_000, ); @@ -329,259 +296,4 @@ describe('clipboard image paste compression', () => { expect(props['source']).toBe('tui_paste'); expect(props['outcome']).toBe('compressed'); }); - - it('uploads final bytes with a crash-recovery TTL while the staging lease owns normal cleanup', async () => { - const small = await solidPng(80, 80); - readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: small, mimeType: 'image/png' }); - const uploadFile = uploadFileMock('file-1'); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); - - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.fileId).toBe('file-1'); - expect(att.fileExpiresAt).toBe(Date.parse('2030-01-02T03:04:05.000Z')); - expect(uploadFile).toHaveBeenCalledTimes(1); - const [data, opts] = uploadFile.mock.calls[0]!; - expect(new Uint8Array(data)).toEqual(small); - expect(opts).toEqual({ - name: 'pasted-image.png', - mimeType: 'image/png', - expiresInSec: 60 * 60, - }); - // The bytes stay on the attachment for the inline fallback / cache copy. - expect(att.bytes).toBe(small); - }); - - it('uploads the compressed bytes when paste-time compression changed them (v2)', async () => { - const big = await solidPng(3600, 1800); - readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: big, mimeType: 'image/png' }); - const uploadFile = uploadFileMock('file-9'); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); - - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.fileId).toBe('file-9'); - // The upload carries exactly what the attachment stores — the compressed - // bytes, not the clipboard original. - const [data] = uploadFile.mock.calls[0]!; - expect(data).toBe(att.bytes); - expect(att.bytes).not.toBe(big); - }); - - it('keeps the paste on the inline fallback when the daemon upload fails (v2)', async () => { - const small = await solidPng(80, 80); - readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: small, mimeType: 'image/png' }); - const uploadFile = vi.fn( - async ( - _data: Uint8Array, - _opts: { name: string; mimeType?: string; expiresInSec?: number }, - ): Promise<{ id: string }> => { - throw new Error('daemon down'); - }, - ); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); // must not throw - - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.fileId).toBeUndefined(); - expect(att.bytes).toBe(small); - }); - - it('never uploads on the v1 engine', async () => { - const small = await solidPng(80, 80); - readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: small, mimeType: 'image/png' }); - const uploadFile = uploadFileMock('file-1'); - - // engineV2 unset — the v1 host shape. - const { store, pasteImage } = createPasteHarness({ uploadFile }); - await pasteImage(); - - expect(uploadFile).not.toHaveBeenCalled(); - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.fileId).toBeUndefined(); - }); - - it('settles the paste callback before the background daemon upload completes (v2)', async () => { - const small = await solidPng(80, 80); - readClipboardMedia.mockResolvedValue({ kind: 'image', bytes: small, mimeType: 'image/png' }); - let resolveUpload!: (meta: { id: string }) => void; - const uploadFile = vi.fn( - ( - _data: Uint8Array, - _opts: { name: string; mimeType?: string; expiresInSec?: number }, - ): Promise<{ id: string }> => - new Promise<{ id: string }>((resolve) => { - resolveUpload = resolve; - }), - ); - - const { store, pasteImageRaw } = createPasteHarness({ engineV2: true, uploadFile }); - // The handler returns once the placeholder is in the editor; the upload - // is still unresolved here — typing is never held behind it. - await pasteImageRaw(); - - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - expect(att.placeholder).toBe('[image #1 (80×80)]'); - expect(att.fileId).toBeUndefined(); - expect(att.pending).toBeDefined(); - - resolveUpload({ id: 'file-late' }); - await att.pending; - - expect(att.fileId).toBe('file-late'); - expect(att.pending).toBeUndefined(); - }); -}); - -describe('clipboard video paste upload', () => { - beforeEach(() => { - readClipboardMedia.mockReset(); - }); - - async function withSourceVideo(run: (sourcePath: string) => Promise<void>): Promise<void> { - const dir = await mkdtemp(join(tmpdir(), 'paste-video-')); - try { - const sourcePath = join(dir, 'clip.mp4'); - await writeFile(sourcePath, 'video-bytes'); - await run(sourcePath); - } finally { - await rm(dir, { recursive: true, force: true }); - } - } - - it('uploads the pasted video to the daemon file store (v2)', async () => { - await withSourceVideo(async (sourcePath) => { - readClipboardMedia.mockResolvedValue({ - kind: 'video', - mimeType: 'video/mp4', - filename: 'clip.mp4', - sourcePath, - }); - const uploadFile = uploadFileMock('file-v1'); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); - - const att = store.get(1); - if (att?.kind !== 'video') throw new Error('expected video attachment'); - expect(att.placeholder).toBe('[video #1 clip.mp4]'); - expect(att.fileId).toBe('file-v1'); - expect(att.fileExpiresAt).toBe(Date.parse('2030-01-02T03:04:05.000Z')); - expect(att.pending).toBeUndefined(); - const [data, opts] = uploadFile.mock.calls[0]!; - expect(new Uint8Array(data)).toEqual(new TextEncoder().encode('video-bytes')); - expect(opts).toEqual({ name: 'clip.mp4', mimeType: 'video/mp4', expiresInSec: 60 * 60 }); - }); - }); - - it('settles the paste callback before the background upload completes (v2)', async () => { - await withSourceVideo(async (sourcePath) => { - readClipboardMedia.mockResolvedValue({ - kind: 'video', - mimeType: 'video/mp4', - filename: 'clip.mp4', - sourcePath, - }); - let resolveUpload!: (meta: { id: string }) => void; - const uploadFile = vi.fn( - ( - _data: Uint8Array, - _opts: { name: string; mimeType?: string; expiresInSec?: number }, - ): Promise<{ id: string }> => - new Promise<{ id: string }>((resolve) => { - resolveUpload = resolve; - }), - ); - - const { store, pasteImageRaw } = createPasteHarness({ engineV2: true, uploadFile }); - // The handler returns once the placeholder is in the editor; the upload - // is still unresolved here — typing is never held behind it. - await pasteImageRaw(); - - const att = store.get(1); - if (att?.kind !== 'video') throw new Error('expected video attachment'); - expect(att.fileId).toBeUndefined(); - expect(att.pending).toBeDefined(); - - // The upload starts once the source file has been read in the - // background; only then can it be resolved. - await vi.waitFor(() => { - expect(uploadFile).toHaveBeenCalled(); - }); - resolveUpload({ id: 'file-vlate' }); - await att.pending; - - expect(att.fileId).toBe('file-vlate'); - expect(att.pending).toBeUndefined(); - }); - }); - - it('leaves the video without a fileId when the daemon upload fails (v2)', async () => { - await withSourceVideo(async (sourcePath) => { - readClipboardMedia.mockResolvedValue({ - kind: 'video', - mimeType: 'video/mp4', - filename: 'clip.mp4', - sourcePath, - }); - const uploadFile = vi.fn(async (): Promise<{ id: string }> => { - throw new Error('daemon down'); - }); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); // must not throw - - const att = store.get(1); - if (att?.kind !== 'video') throw new Error('expected video attachment'); - expect(att.fileId).toBeUndefined(); - expect(att.pending).toBeUndefined(); - }); - }); - - it('leaves the video without a fileId when the source file vanished (v2)', async () => { - readClipboardMedia.mockResolvedValue({ - kind: 'video', - mimeType: 'video/mp4', - filename: 'clip.mp4', - sourcePath: '/tmp/kimi-paste-vanished-source.mp4', - }); - const uploadFile = uploadFileMock('file-v1'); - - const { store, pasteImage } = createPasteHarness({ engineV2: true, uploadFile }); - await pasteImage(); - - expect(uploadFile).not.toHaveBeenCalled(); - const att = store.get(1); - if (att?.kind !== 'video') throw new Error('expected video attachment'); - expect(att.fileId).toBeUndefined(); - }); - - it('never uploads on the v1 engine', async () => { - await withSourceVideo(async (sourcePath) => { - readClipboardMedia.mockResolvedValue({ - kind: 'video', - mimeType: 'video/mp4', - filename: 'clip.mp4', - sourcePath, - }); - const uploadFile = uploadFileMock('file-v1'); - - // engineV2 unset — the v1 host shape. - const { store, pasteImage } = createPasteHarness({ uploadFile }); - await pasteImage(); - - expect(uploadFile).not.toHaveBeenCalled(); - const att = store.get(1); - if (att?.kind !== 'video') throw new Error('expected video attachment'); - expect(att.fileId).toBeUndefined(); - }); - }); }); diff --git a/apps/kimi-code/test/tui/controllers/editor-keyboard.test.ts b/apps/kimi-code/test/tui/controllers/editor-keyboard.test.ts index 626728e78..049d2e480 100644 --- a/apps/kimi-code/test/tui/controllers/editor-keyboard.test.ts +++ b/apps/kimi-code/test/tui/controllers/editor-keyboard.test.ts @@ -46,8 +46,6 @@ function createHarness(options: { streamingPhase?: string; isCompacting?: boolea btwPanelController: { cancelRunning: btwCancelRunning, closeOrCancel: btwCloseOrCancel }, openUndoSelector, cancelRunningShellCommand, - updateEditorBorderHighlight: vi.fn(), - updateGoalLengthWarning: vi.fn(), } as unknown as EditorKeyboardHost; const controller = new EditorKeyboardController( @@ -288,101 +286,6 @@ describe('EditorKeyboardController shell history recall', () => { }); }); -describe('EditorKeyboardController input changes', () => { - function installExpandedText( - editor: Harness['editor'], - expanded: string, - ): ReturnType<typeof vi.fn> { - const getExpandedText = vi.fn(() => expanded); - editor['getExpandedText'] = getExpandedText as unknown as (...args: never[]) => unknown; - return getExpandedText; - } - - it('forwards text changes to the border highlight and goal length warning', () => { - const { host, editor } = createHarness(); - installExpandedText(editor, '/goal Ship feature X'); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - onChange('/goal Ship feature X'); - - expect(host.updateEditorBorderHighlight).toHaveBeenCalledWith('/goal Ship feature X'); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith('/goal Ship feature X'); - }); - - it('measures the goal length warning on paste-expanded text, not the collapsed marker', () => { - const { host, editor } = createHarness(); - const expanded = `/goal ${'x'.repeat(4001)}`; - installExpandedText(editor, expanded); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - // The visible text only holds the collapsed paste marker. - onChange('/goal [paste #1 +4000 chars]'); - - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(expanded); - }); - - it('expands a leading paste marker because its content may start with /goal', () => { - const { host, editor } = createHarness(); - const expanded = `/goal ${'x'.repeat(4001)}`; - const getExpandedText = installExpandedText(editor, expanded); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - onChange('[paste #1 +4000 chars]'); - - expect(getExpandedText).toHaveBeenCalled(); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(expanded); - }); - - it('expands a paste that can complete a partially typed /goal command', () => { - const { host, editor } = createHarness(); - const expanded = `/goal ${'x'.repeat(4001)}`; - const getExpandedText = installExpandedText(editor, expanded); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - // Visible text is `/go[paste #1 …]`; the paste completes the command. - onChange('/go[paste #1 +3999 chars]'); - - expect(getExpandedText).toHaveBeenCalled(); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(expanded); - }); - - it('skips paste expansion entirely for non-goal input', () => { - const { host, editor } = createHarness(); - const getExpandedText = installExpandedText(editor, 'whatever'); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - onChange('just a normal prompt'); - onChange('/help'); - - expect(getExpandedText).not.toHaveBeenCalled(); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(undefined); - }); - - it('gates on trimmed text because submit trims leading whitespace', () => { - const { host, editor } = createHarness(); - const expanded = `/goal ${'x'.repeat(4001)}`; - const getExpandedText = installExpandedText(editor, expanded); - const onChange = editor['onChange'] as unknown as (text: string) => void; - - onChange(` /goal ${'x'.repeat(4001)}`); - - expect(getExpandedText).toHaveBeenCalled(); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(expanded); - }); - - it('skips the goal length warning in bash mode', () => { - const { host, editor } = createHarness(); - const getExpandedText = installExpandedText(editor, '/goal x'); - (editor as unknown as { inputMode: string }).inputMode = 'bash'; - const onChange = editor['onChange'] as unknown as (text: string) => void; - - onChange('/goal x'); - - expect(getExpandedText).not.toHaveBeenCalled(); - expect(host.updateGoalLengthWarning).toHaveBeenCalledWith(undefined); - }); -}); - describe('EditorKeyboardController Shift-Tab plan toggle', () => { function createShiftTabHarness(options: { sessionless?: boolean; engineV2?: boolean } = {}) { const editor: Record<string, ((...args: never[]) => unknown) | undefined> = { @@ -463,189 +366,3 @@ describe('EditorKeyboardController Shift-Tab plan toggle', () => { expect(handlePlanToggle).not.toHaveBeenCalled(); }); }); - -/** - * Ctrl-S steering of the TUI queue: plain-text items steer as messages, - * slash-skill items fire as real activations into the running turn (never as - * literal text), grouped inline-skill submissions stay queued for the drain - * path, bash items stay queued — all in queue order. - */ -describe('EditorKeyboardController Ctrl-S steering', () => { - function createCtrlSHarness(options: { - editorText: string; - queued: Array<Record<string, unknown>>; - engineV2?: boolean; - skillCommandMap?: Map<string, string>; - }) { - const steerMessage = vi.fn(); - const steerSkillActivation = vi.fn(); - const updateQueueDisplay = vi.fn(); - const setText = vi.fn(); - const editor: Record<string, ((...args: never[]) => unknown) | undefined> = { - setHistoryFilter: vi.fn() as unknown as (...args: never[]) => unknown, - setInputMode: vi.fn() as unknown as (...args: never[]) => unknown, - getText: vi.fn(() => options.editorText) as unknown as (...args: never[]) => unknown, - setText: setText as unknown as (...args: never[]) => unknown, - inputMode: 'prompt' as unknown as (...args: never[]) => unknown, - }; - const host = { - state: { - editor, - activeDialog: null, - queuedMessages: options.queued, - appState: { streamingPhase: 'waiting', isCompacting: false, model: 'k2' }, - footer: { setTransientHint: vi.fn() }, - ui: { requestRender: vi.fn() }, - }, - session: { id: 's1' }, - engineV2: options.engineV2 ?? false, - skillCommandMap: options.skillCommandMap ?? new Map(), - steerMessage, - steerSkillActivation, - updateQueueDisplay, - validateMediaCapabilities: vi.fn(() => true), - showError: vi.fn(), - track: vi.fn(), - btwPanelController: { - cancelRunning: vi.fn(() => false), - closeOrCancel: vi.fn(() => false), - }, - } as unknown as EditorKeyboardHost; - const controller = new EditorKeyboardController( - host, - undefined as unknown as ImageAttachmentStore, - ); - controller.install(); - const onCtrlS = editor['onCtrlS']; - if (onCtrlS === undefined) throw new Error('onCtrlS handler not installed'); - return { - host, - editor, - setText, - steerMessage, - steerSkillActivation, - updateQueueDisplay, - onCtrlS: onCtrlS as () => void, - }; - } - - it('steers text as a message, skill items as activations, and keeps bash queued', () => { - const { host, steerMessage, steerSkillActivation, updateQueueDisplay, onCtrlS } = - createCtrlSHarness({ - editorText: '', - queued: [ - { text: 'queued text', agentId: 'main' }, - { - text: '/tower status', - agentId: 'main', - mode: 'skill', - skillName: 'tower', - skillArgs: 'status', - }, - { text: '!ls', agentId: 'main', mode: 'bash' }, - ], - }); - - onCtrlS(); - - expect(steerMessage).toHaveBeenCalledWith(host.session, [ - { text: 'queued text', parts: undefined, imageAttachmentIds: undefined }, - ]); - expect(steerSkillActivation).toHaveBeenCalledWith(host.session, 'tower', 'status'); - expect(host.state.queuedMessages).toEqual([{ text: '!ls', agentId: 'main', mode: 'bash' }]); - expect(updateQueueDisplay).toHaveBeenCalled(); - }); - - it('steers plain queued messages but keeps grouped inline-skill submissions queued', () => { - const { host, steerMessage, updateQueueDisplay, onCtrlS } = createCtrlSHarness({ - editorText: '', - queued: [ - { text: 'plain note', agentId: 'main' }, - { - text: 'check /skill:review', - agentId: 'main', - inlineSkillActivations: [{ skillName: 'review' }], - }, - ], - }); - - onCtrlS(); - - expect(steerMessage).toHaveBeenCalledWith(host.session, [ - { text: 'plain note', parts: undefined, imageAttachmentIds: undefined }, - ]); - expect(host.state.queuedMessages).toEqual([ - { - text: 'check /skill:review', - agentId: 'main', - inlineSkillActivations: [{ skillName: 'review' }], - }, - ]); - expect(updateQueueDisplay).toHaveBeenCalled(); - }); - - it('stops steering at the first bundle so later messages keep FIFO order', () => { - const { host, steerMessage, onCtrlS } = createCtrlSHarness({ - editorText: '', - queued: [ - { text: 'earlier note', agentId: 'main' }, - { - text: 'check /skill:review', - agentId: 'main', - inlineSkillActivations: [{ skillName: 'review' }], - }, - { text: 'later note', agentId: 'main' }, - ], - }); - - onCtrlS(); - - expect(steerMessage).toHaveBeenCalledWith(host.session, [ - { text: 'earlier note', parts: undefined, imageAttachmentIds: undefined }, - ]); - expect(host.state.queuedMessages).toEqual([ - { - text: 'check /skill:review', - agentId: 'main', - inlineSkillActivations: [{ skillName: 'review' }], - }, - { text: 'later note', agentId: 'main' }, - ]); - }); - - it('steers nothing when a bundle leads the queue', () => { - const { host, steerMessage, onCtrlS } = createCtrlSHarness({ - editorText: '', - queued: [ - { - text: 'check /skill:review', - agentId: 'main', - inlineSkillActivations: [{ skillName: 'review' }], - }, - { text: 'later note', agentId: 'main' }, - ], - }); - - onCtrlS(); - - expect(steerMessage).not.toHaveBeenCalled(); - expect(host.state.queuedMessages).toHaveLength(2); - }); - - it('leaves an editor draft with inline skill tokens in the editor for the grouped path', () => { - const { host, setText, steerMessage, onCtrlS } = createCtrlSHarness({ - editorText: 'check /skill:review', - queued: [{ text: 'plain note', agentId: 'main' }], - engineV2: true, - skillCommandMap: new Map([['skill:review', 'review']]), - }); - - onCtrlS(); - - expect(steerMessage).toHaveBeenCalledWith(host.session, [ - { text: 'plain note', parts: undefined, imageAttachmentIds: undefined }, - ]); - expect(setText).not.toHaveBeenCalled(); - expect(host.state.queuedMessages).toEqual([]); - }); -}); diff --git a/apps/kimi-code/test/tui/controllers/plugin-update-notifier.test.ts b/apps/kimi-code/test/tui/controllers/plugin-update-notifier.test.ts index c7bc0c5f6..ca66af33f 100644 --- a/apps/kimi-code/test/tui/controllers/plugin-update-notifier.test.ts +++ b/apps/kimi-code/test/tui/controllers/plugin-update-notifier.test.ts @@ -6,7 +6,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import type { PluginSummary } from '@moonshot-ai/kimi-code-sdk'; -import { kimiCodePluginMarketplaceUrl } from '#/constant/app'; +import { KIMI_CODE_PLUGIN_MARKETPLACE_URL } from '#/constant/app'; import { PluginUpdateNotifier, type PluginUpdateNotifierSession, @@ -49,7 +49,7 @@ function makeMarketplaceEntry( function makeMarketplace(version = '3.4.0'): PluginMarketplace { return { - source: kimiCodePluginMarketplaceUrl(), + source: KIMI_CODE_PLUGIN_MARKETPLACE_URL, plugins: [makeMarketplaceEntry('kimi-datasource', 'Kimi Datasource', version)], }; } @@ -268,7 +268,7 @@ describe('PluginUpdateNotifier', () => { it('keeps every notified plugin when a turn uses two outdated plugins', async () => { const harness = makeHarness({ marketplace: { - source: kimiCodePluginMarketplaceUrl(), + source: KIMI_CODE_PLUGIN_MARKETPLACE_URL, plugins: [ makeMarketplaceEntry('kimi-datasource', 'Kimi Datasource', '3.4.0'), makeMarketplaceEntry('another-plugin', 'Another Plugin', '2.0.0'), diff --git a/apps/kimi-code/test/tui/controllers/session-event-handler-todo.test.ts b/apps/kimi-code/test/tui/controllers/session-event-handler-todo.test.ts deleted file mode 100644 index c28e26727..000000000 --- a/apps/kimi-code/test/tui/controllers/session-event-handler-todo.test.ts +++ /dev/null @@ -1,87 +0,0 @@ -import type { Event } from '@moonshot-ai/kimi-code-sdk'; -import { describe, expect, it, vi } from 'vitest'; - -import { SessionEventHandler } from '#/tui/controllers/session-event-handler'; -import type { ToolCallBlockData } from '#/tui/types'; - -function makeHarness() { - const activeCalls = new Map<string, ToolCallBlockData>(); - const streamingUI = { - setTurnId: vi.fn(), - flushNow: vi.fn(), - getTurnContext: vi.fn(() => ({ turnId: 1, step: 0 })), - registerToolCall: vi.fn((call: ToolCallBlockData) => { - activeCalls.set(call.id, call); - return true; - }), - completeToolResult: vi.fn((toolCallId: string) => { - const call = activeCalls.get(toolCallId); - activeCalls.delete(toolCallId); - return call; - }), - setTodoList: vi.fn(), - }; - const host = { - state: { - appState: { availableModels: {}, workDir: '/tmp/work', stepRetry: null }, - ui: { requestRender: vi.fn() }, - transcriptContainer: { addChild: vi.fn() }, - }, - session: undefined, - streamingUI, - appendTranscriptEntry: vi.fn(), - patchLivePane: vi.fn(), - setAppState: vi.fn(), - btwPanelController: { routeEvent: vi.fn(() => false) }, - updateActivityPane: vi.fn(), - showStatus: vi.fn(), - }; - const handler = new SessionEventHandler(host as never); - return { handler, streamingUI }; -} - -function todoCallStarted(toolCallId: string, todos: unknown): Event { - return { - sessionId: 's1', - agentId: 'main', - type: 'tool.call.started', - turnId: 1, - toolCallId, - name: 'TodoList', - args: { todos }, - } as unknown as Event; -} - -function todoResult(toolCallId: string, isError = false): Event { - return { - sessionId: 's1', - agentId: 'main', - type: 'tool.result', - turnId: 1, - toolCallId, - output: 'ok', - isError, - } as unknown as Event; -} - -describe('SessionEventHandler — todo panel feed', () => { - it('feeds the panel from TodoList call args when the tool result arrives', () => { - const { handler, streamingUI } = makeHarness(); - const todos = [{ title: '测试 Todo 项', status: 'in_progress' }]; - - handler.handleEvent(todoCallStarted('tc-1', todos), vi.fn()); - expect(streamingUI.setTodoList).not.toHaveBeenCalled(); - - handler.handleEvent(todoResult('tc-1'), vi.fn()); - expect(streamingUI.setTodoList).toHaveBeenCalledWith(todos); - }); - - it('ignores failed TodoList results', () => { - const { handler, streamingUI } = makeHarness(); - - handler.handleEvent(todoCallStarted('tc-1', [{ title: 'x', status: 'pending' }]), vi.fn()); - handler.handleEvent(todoResult('tc-1', true), vi.fn()); - - expect(streamingUI.setTodoList).not.toHaveBeenCalled(); - }); -}); diff --git a/apps/kimi-code/test/tui/controllers/staging-leases.test.ts b/apps/kimi-code/test/tui/controllers/staging-leases.test.ts deleted file mode 100644 index 6463df90d..000000000 --- a/apps/kimi-code/test/tui/controllers/staging-leases.test.ts +++ /dev/null @@ -1,359 +0,0 @@ -import type { TurnEndedEvent, TurnStartedEvent } from '@moonshot-ai/kimi-code-sdk'; -import { describe, expect, it, vi } from 'vitest'; - -import { - StagingLeaseTracker, - type StagingLeaseEffects, - type StagingLeaseOrigin, -} from '#/tui/controllers/staging-leases'; - -function turnStarted(turnId: number | string, kind: string, promptId?: string): TurnStartedEvent { - return { type: 'turn.started', agentId: 'main', turnId, origin: { kind }, promptId } as TurnStartedEvent; -} - -function turnEnded(turnId: number | string): TurnEndedEvent { - return { type: 'turn.ended', agentId: 'main', turnId, reason: 'completed' } as TurnEndedEvent; -} - -function makeEffects(): { - effects: StagingLeaseEffects; - takeFileIds: ReturnType<typeof vi.fn<(ids: readonly number[]) => readonly string[]>>; - releaseRetains: ReturnType<typeof vi.fn<(ids: readonly number[]) => void>>; - deleteFiles: ReturnType< - typeof vi.fn<(fileIds: readonly string[], paths: readonly string[]) => Promise<void>> - >; - warn: ReturnType<typeof vi.fn<(message: string) => void>>; - deleted: { fileIds: string[]; paths: string[] }; -} { - const deleted = { fileIds: [] as string[], paths: [] as string[] }; - const takeFileIds = vi.fn((ids: readonly number[]) => ids.map((id) => `file-${id}`)); - const releaseRetains = vi.fn((ids: readonly number[]) => void ids); - const deleteFiles = vi.fn((fileIds: readonly string[], paths: readonly string[]) => { - deleted.fileIds.push(...fileIds); - deleted.paths.push(...paths); - return Promise.resolve(); - }); - const warn = vi.fn((message: string) => void message); - return { - effects: { takeFileIds, releaseRetains, deleteFiles, warn }, - takeFileIds, - releaseRetains, - deleteFiles, - warn, - deleted, - }; -} - -function makeTracker(): ReturnType<typeof makeEffects> & { tracker: StagingLeaseTracker } { - const mocks = makeEffects(); - return { ...mocks, tracker: new StagingLeaseTracker(mocks.effects) }; -} - -describe('StagingLeaseTracker', () => { - describe('create', () => { - it('returns undefined when nothing is staged', () => { - const { tracker } = makeTracker(); - expect(tracker.create([], [], 'user')).toBeUndefined(); - }); - }); - - describe('turn claiming', () => { - it('claims the earliest unbound lease of the matching origin', () => { - const { tracker } = makeTracker(); - const first = tracker.create([], ['/cache/a'], 'user'); - const second = tracker.create([], ['/cache/b'], 'user'); - - tracker.handleTurnStarted(turnStarted(1, 'user')); - expect(first?.turnId).toBe('1'); - expect(second?.turnId).toBeUndefined(); - - tracker.handleTurnStarted(turnStarted(2, 'user')); - expect(second?.turnId).toBe('2'); - }); - - it('warns when several unclaimed same-origin leases make the heuristic claim ambiguous', () => { - const { tracker, warn } = makeTracker(); - tracker.create([], ['/cache/a'], 'user'); - tracker.create([], ['/cache/b'], 'user'); - - tracker.handleTurnStarted(turnStarted(1, 'user')); - - expect(warn).toHaveBeenCalledOnce(); - expect(warn.mock.calls[0]![0]).toContain("'user'"); - expect(warn.mock.calls[0]![0]).toContain('1'); - }); - - it('stays silent while at most one same-origin lease is unclaimed', () => { - const { tracker, warn } = makeTracker(); - tracker.create([], ['/cache/a'], 'user'); - - tracker.handleTurnStarted(turnStarted(1, 'user')); - tracker.handleTurnStarted(turnStarted(2, 'user')); - - expect(warn).not.toHaveBeenCalled(); - }); - - it('binds the exact lease when turn.started echoes its submission id', () => { - const { tracker, warn } = makeTracker(); - const earlier = tracker.create([], ['/cache/a'], 'user'); - const exact = tracker.create([], ['/cache/b'], 'user', 'sub-2'); - - // The exact id wins over the earlier unclaimed same-origin lease, and - // the ambiguity warning stays silent. - tracker.handleTurnStarted(turnStarted(1, 'user', 'sub-2')); - - expect(exact?.turnId).toBe('1'); - expect(earlier?.turnId).toBeUndefined(); - expect(warn).not.toHaveBeenCalled(); - }); - - it('falls back to the origin heuristic when the promptId is unknown', () => { - const { tracker, warn } = makeTracker(); - const first = tracker.create([], ['/cache/a'], 'user', 'sub-1'); - const second = tracker.create([], ['/cache/b'], 'user'); - - tracker.handleTurnStarted(turnStarted(1, 'user', 'sub-unknown')); - - expect(first?.turnId).toBe('1'); - expect(second?.turnId).toBeUndefined(); - expect(warn).toHaveBeenCalledOnce(); - }); - - it('does not exact-bind a released lease whose submission id is echoed again', () => { - const { tracker } = makeTracker(); - const released = tracker.create([], ['/cache/a'], 'user', 'sub-1'); - tracker.release(released); - const fallback = tracker.create([], ['/cache/b'], 'user'); - - tracker.handleTurnStarted(turnStarted(1, 'user', 'sub-1')); - - expect(released?.turnId).toBeUndefined(); - expect(fallback?.turnId).toBe('1'); - }); - - it('ignores turns of other or unknown origins', () => { - const { tracker } = makeTracker(); - const lease = tracker.create([], ['/cache/a'], 'skill_activation'); - - tracker.handleTurnStarted(turnStarted(1, 'user')); - tracker.handleTurnStarted(turnStarted(2, 'plugin_command')); - tracker.handleTurnStarted(turnStarted(3, 'system_trigger')); - expect(lease?.turnId).toBeUndefined(); - - tracker.handleTurnStarted(turnStarted(4, 'skill_activation')); - expect(lease?.turnId).toBe('4'); - }); - - it('does not rebind a bound or released lease', () => { - const { tracker } = makeTracker(); - const lease = tracker.create([], ['/cache/a'], 'user'); - tracker.bindToTurn(lease, '1'); - tracker.bindToTurn(lease, '2'); - expect(lease?.turnId).toBe('1'); - - tracker.release(lease); - tracker.bindToTurn(lease, '3'); - expect(lease?.turnId).toBe('1'); - }); - }); - - describe('turn-end release', () => { - it('deletes daemon uploads but retires cache copies to session lifetime', () => { - const { tracker, deleted } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], 'user'); - tracker.bindToTurn(lease, '1'); - - tracker.handleTurnEnded(turnEnded(1)); - - expect(deleted.fileIds).toEqual(['file-1']); - expect(deleted.paths).toEqual([]); - }); - - it('deletes retired cache copies at session close', () => { - const { tracker, deleted } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], 'user'); - tracker.bindToTurn(lease, '1'); - tracker.handleTurnEnded(turnEnded(1)); - expect(deleted.paths).toEqual([]); - - tracker.releaseAll(); - expect(deleted.paths).toEqual(['/cache/a']); - }); - - it('releases a bound lease exactly once across repeated turn.ended events', () => { - const { tracker, deleteFiles } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], 'user'); - tracker.bindToTurn(lease, '1'); - - tracker.handleTurnEnded(turnEnded(1)); - tracker.handleTurnEnded(turnEnded(1)); - tracker.release(lease); - - expect(deleteFiles).toHaveBeenCalledTimes(1); - }); - - it('ignores turn.ended for unknown turns', () => { - const { tracker, deleteFiles } = makeTracker(); - tracker.create([1], ['/cache/a'], 'user'); - tracker.handleTurnEnded(turnEnded(99)); - expect(deleteFiles).not.toHaveBeenCalled(); - }); - - it('consumes one retain per id occurrence at turn end', () => { - const { tracker, takeFileIds } = makeTracker(); - // Multiplicity in the lease's id list is the retain count (creation - // sites dedupe per extraction): [7, 7] means two retains, e.g. a - // batched steer of two queued messages sharing the image. - tracker.create([7, 7], [], 'user', 'sub-dup'); - tracker.handleTurnStarted(turnStarted(1, 'user', 'sub-dup')); - - tracker.handleTurnEnded(turnEnded(1)); - - expect(takeFileIds.mock.calls).toEqual([[[7]], [[7]]]); - }); - }); - - describe('abandonment', () => { - // Every abandonment entry point deletes daemon uploads and cache copies - // immediately, whether or not a turn ever consumed the lease. - it.each([ - [ - 'release', - (tracker: StagingLeaseTracker) => { - tracker.release(tracker.create([1], ['/cache/a'], 'user')); - tracker.release(tracker.create([2], ['/cache/b'], 'user')); - }, - ], - [ - 'releaseMedia and releaseQueued', - (tracker: StagingLeaseTracker) => { - tracker.releaseMedia([1], ['/cache/a', '/cache/b']); - tracker.releaseQueued([{ text: 'q', agentId: 'main', videoAttachmentIds: [2] }]); - }, - ], - [ - 'releaseAll', - (tracker: StagingLeaseTracker) => { - tracker.create([1], ['/cache/a'], 'user'); - tracker.bindToTurn(tracker.create([2], ['/cache/b'], 'user'), '1'); - tracker.releaseAll(); - }, - ], - ] as const)('%s deletes daemon uploads and cache copies immediately', (_name, abandon) => { - const { tracker, deleted } = makeTracker(); - - abandon(tracker); - - expect(deleted.fileIds).toEqual(['file-1', 'file-2']); - expect(deleted.paths).toEqual(['/cache/a', '/cache/b']); - }); - }); - - describe('queue recall', () => { - it('consumes only the retain and retires cache copies instead of deleting', () => { - const { tracker, releaseRetains, deleted } = makeTracker(); - - // A recall restores the draft into the editor — not a discard: the - // daemon upload stays staged (only the retain is consumed) and the - // rewrite channel's cache copy retires to session lifetime. - tracker.releaseRecalled([2], ['/cache/b']); - - expect(releaseRetains).toHaveBeenCalledWith([2]); - expect(deleted.fileIds).toEqual([]); - expect(deleted.paths).toEqual([]); - - tracker.releaseAll(); - expect(deleted.fileIds).toEqual([]); - expect(deleted.paths).toEqual(['/cache/b']); - }); - }); - - describe('defer', () => { - it('unbinds the lease without consuming retains or deleting files', () => { - const { tracker, takeFileIds, releaseRetains, deleted } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], 'user', 'sub-1'); - - tracker.defer(lease); - - expect(lease?.released).toBe(true); - expect(takeFileIds).not.toHaveBeenCalled(); - expect(releaseRetains).not.toHaveBeenCalled(); - expect(deleted).toEqual({ fileIds: [], paths: [] }); - - // A deferred lease is gone for good: turn events cannot claim it and - // releaseAll does not sweep its media. - tracker.handleTurnStarted(turnStarted(1, 'user', 'sub-1')); - expect(lease?.turnId).toBeUndefined(); - tracker.releaseAll(); - expect(deleted).toEqual({ fileIds: [], paths: [] }); - }); - }); - - describe('trackDispatch', () => { - const origin: StagingLeaseOrigin = 'user'; - - it('keeps the lease when the dispatch resolves', async () => { - const { tracker, deleteFiles } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], origin); - const onError = vi.fn(); - - tracker.trackDispatch(lease, Promise.resolve(), onError); - await tracker.drain(); - - expect(onError).not.toHaveBeenCalled(); - expect(deleteFiles).not.toHaveBeenCalled(); - expect(lease?.released).toBe(false); - }); - - it('releases an unclaimed lease exactly once when the dispatch rejects', async () => { - const { tracker, deleted } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], origin); - const onError = vi.fn(); - - tracker.trackDispatch(lease, Promise.reject(new Error('boom')), onError); - await tracker.drain(); - - expect(onError).toHaveBeenCalledOnce(); - expect(deleted.fileIds).toEqual(['file-1']); - expect(deleted.paths).toEqual(['/cache/a']); - // A later turn end must not delete again. - tracker.handleTurnEnded(turnEnded(1)); - tracker.releaseAll(); - expect(deleted.fileIds).toEqual(['file-1']); - }); - - it('does not release a lease a turn already claimed when the dispatch rejects', async () => { - const { tracker, deleted } = makeTracker(); - const lease = tracker.create([1], ['/cache/a'], origin); - tracker.bindToTurn(lease, '7'); - - tracker.trackDispatch(lease, Promise.reject(new Error('boom')), vi.fn()); - await tracker.drain(); - expect(deleted.fileIds).toEqual([]); - - // The owning turn still releases it at turn end (uploads deleted, copies retired). - tracker.handleTurnEnded(turnEnded(7)); - expect(deleted.fileIds).toEqual(['file-1']); - expect(deleted.paths).toEqual([]); - }); - }); - - describe('track/drain', () => { - it('drain awaits in-flight cleanups and track swallows rejections', async () => { - const { tracker } = makeTracker(); - let settled = false; - tracker.track( - new Promise<void>((resolve) => { - setTimeout(() => { - settled = true; - resolve(); - }, 10); - }), - ); - tracker.track(Promise.reject(new Error('ignored'))); - - await tracker.drain(); - expect(settled).toBe(true); - }); - }); -}); diff --git a/apps/kimi-code/test/tui/controllers/subagent-activity-store.test.ts b/apps/kimi-code/test/tui/controllers/subagent-activity-store.test.ts index 06b90dd69..d7c73f2a7 100644 --- a/apps/kimi-code/test/tui/controllers/subagent-activity-store.test.ts +++ b/apps/kimi-code/test/tui/controllers/subagent-activity-store.test.ts @@ -62,25 +62,6 @@ describe('SubagentActivityStore', () => { expect(record?.version).toBeGreaterThan(0); }); - it('shows a status progress update as the live output tail', () => { - const store = new SubagentActivityStore(); - store.ensureRecord(spawn()); - store.applyEvent( - ev({ type: 'tool.call.started', turnId: 1, toolCallId: 't1', name: 'WaitFor', args: { timeout: 600 } }), - ); - store.applyEvent( - ev({ - type: 'tool.progress', - turnId: 1, - toolCallId: 't1', - update: { kind: 'status', text: 'Waiting 10s / 600s · 1 background task still running', replace: true }, - }), - ); - - const call = store.get('agent-1')?.steps[0]?.toolCalls[0]; - expect(call?.liveOutputTail).toBe('Waiting 10s / 600s · 1 background task still running'); - }); - it('creates a call from streaming deltas and replaces args on start', () => { const store = new SubagentActivityStore(); store.ensureRecord(spawn()); diff --git a/apps/kimi-code/test/tui/create-tui-state.test.ts b/apps/kimi-code/test/tui/create-tui-state.test.ts index 67227c561..8e17cc8f6 100644 --- a/apps/kimi-code/test/tui/create-tui-state.test.ts +++ b/apps/kimi-code/test/tui/create-tui-state.test.ts @@ -1,7 +1,5 @@ -import { describe, it, expect, vi } from 'vitest'; - -import { TuiAltScreen, TuiMainScreen } from '@moonshot-ai/pi-tui'; +import { describe, it, expect } from 'vitest'; import { createTUIState, type KimiTUIOptions } from '#/tui/kimi-tui'; import type { AppState } from '#/tui/types'; @@ -16,7 +14,6 @@ function fakeInitialAppState(): AppState { planMode: false, inputMode: 'prompt', swarmMode: false, - towerMode: false, thinkingEffort: 'off', contextUsage: 0, contextTokens: 0, @@ -88,61 +85,4 @@ describe('createTUIState', () => { expect(state.sessionsScope).toBe('cwd'); expect(state.activitySpinner).toBeNull(); }); - - it('uses the main-screen renderer by default', () => { - const state = createTUIState({ - initialAppState: fakeInitialAppState(), - startup: { - continueLast: false, - yolo: false, - auto: false, - plan: false, - }, - }); - - expect(state.ui).toBeInstanceOf(TuiMainScreen); - expect(state.ui.mode).toBe('regular'); - expect(state.dockContainer).toBeUndefined(); - }); - - it('builds an alternate-screen renderer with a docked layout in fullscreen mode', () => { - vi.stubEnv('KIMI_CODE_TUI_FULL_SCREEN', '1'); - const state = createTUIState({ - initialAppState: fakeInitialAppState(), - startup: { - continueLast: false, - yolo: false, - auto: false, - plan: false, - }, - }); - vi.unstubAllEnvs(); - - expect(state.ui).toBeInstanceOf(TuiAltScreen); - expect(state.ui.mode).toBe('fullscreen'); - - // The chrome docks below the transcript ScrollView, in z-order. - const dock = state.dockContainer; - expect(dock).toBeDefined(); - expect(dock?.children).toEqual([ - state.activityContainer, - state.todoPanelContainer, - state.queueContainer, - state.btwPanelContainer, - state.editorContainer, - ]); - - // The layout root is mounted and the root children list stays empty. - expect((state.ui as TuiAltScreen).getLayoutRoot()).toBeDefined(); - expect(state.ui.children).toHaveLength(0); - - // Mouse capture replaces native terminal link activation / right-click - // paste, so both must be routed through renderer callbacks. - const internals = state.ui as unknown as { - openUrl?: (url: string) => void; - onRightClickPaste?: () => void; - }; - expect(typeof internals.openUrl).toBe('function'); - expect(typeof internals.onRightClickPaste).toBe('function'); - }); }); diff --git a/apps/kimi-code/test/tui/export-markdown.test.ts b/apps/kimi-code/test/tui/export-markdown.test.ts index 7e6557733..05a6eb8ad 100644 --- a/apps/kimi-code/test/tui/export-markdown.test.ts +++ b/apps/kimi-code/test/tui/export-markdown.test.ts @@ -316,54 +316,6 @@ describe('buildExportMarkdown', () => { expect(md).toContain('deep thought'); }); - it('renders an uploaded image daemon ref as [image] in the exported user message', () => { - // An uploaded image persists as a self-contained `kimi-file://` part — - // the export keeps the real text and `[image]`, never the materialization - // path or the internal url. - const msgs: ContextMessage[] = [ - { - role: 'user', - content: [ - { type: 'text', text: 'what is this? ' }, - { - type: 'image_url', - imageUrl: { url: 'kimi-file://f_1?path=%2FUsers%2Falice%2Fmedia%2Ff_1.png' }, - }, - ], - toolCalls: [], - origin: { kind: 'user' }, - }, - assistantMsg('a screenshot'), - ]; - const md = buildExportMarkdown({ - sessionId: 'ses_test', - workDir: '/tmp', - history: msgs, - tokenCount: 0, - now, - }); - expect(md).toContain('what is this?'); - expect(md).toContain('[image]'); - expect(md).not.toContain('/Users/alice'); - expect(md).not.toContain('kimi-file'); - expect(md).not.toContain('<image path='); - }); - - it('keeps an unpaired standalone <media path> tag as user text in the export', () => { - const msgs: ContextMessage[] = [ - userMsg('<image path="/tmp/shot.png">', { kind: 'user' }), - assistantMsg('ok'), - ]; - const md = buildExportMarkdown({ - sessionId: 'ses_test', - workDir: '/tmp', - history: msgs, - tokenCount: 0, - now, - }); - expect(md).toContain('<image path="/tmp/shot.png">'); - }); - it('renders tool calls and results', () => { const tc = makeToolCall('c1', 'Read', { file_path: '/foo.ts' }); const msgs: ContextMessage[] = [ diff --git a/apps/kimi-code/test/tui/fullscreen-layout.test.ts b/apps/kimi-code/test/tui/fullscreen-layout.test.ts deleted file mode 100644 index dd847d05f..000000000 --- a/apps/kimi-code/test/tui/fullscreen-layout.test.ts +++ /dev/null @@ -1,171 +0,0 @@ -/** - * Fullscreen layout contract tests: the docked chrome must keep the editor's - * full height (top border / input / bottom border) even when the transcript - * far exceeds the screen. Regression: the dock used to participate in VStack - * shrink distribution with no minSize, so a tall transcript crushed it and - * the editor's bottom border row was clipped off screen. - */ -import { describe, expect, it, vi } from 'vitest'; - -import { Spacer, type Terminal, TuiAltScreen } from '@moonshot-ai/pi-tui'; -import { VirtualTerminal } from '../../../../packages/pi-tui/test/virtual-terminal'; - -import { GutterContainer } from '#/tui/components/chrome/gutter-container'; -import { MoonLoader } from '#/tui/components/chrome/moon-loader'; -import { AssistantMessageComponent } from '#/tui/components/messages/assistant-message'; -import { StatusMessageComponent } from '#/tui/components/messages/status-message'; -import { UserMessageComponent } from '#/tui/components/messages/user-message'; -import { ActivityPaneComponent } from '#/tui/components/panes/activity-pane'; -import { CHROME_GUTTER } from '#/tui/constant/rendering'; -import { createTUIState, type KimiTUIOptions } from '#/tui/kimi-tui'; -import type { AppState } from '#/tui/types'; - -const WIDTH = 120; -const HEIGHT = 30; - -function fakeInitialAppState(): AppState { - return { - model: 'test-model', - workDir: '/tmp/kimi-test', - additionalDirs: [], - sessionId: 'sess-1', - permissionMode: 'manual', - planMode: false, - inputMode: 'prompt', - swarmMode: false, - towerMode: false, - thinkingEffort: 'off', - contextUsage: 0, - contextTokens: 0, - maxContextTokens: 0, - isCompacting: false, - isReplaying: false, - streamingPhase: 'idle', - streamingStartTime: 0, - stepRetry: null, - theme: 'dark', - version: '0.0.0-test', - editorCommand: null, - notifications: { enabled: true, condition: 'unfocused' }, - upgrade: { autoInstall: true }, - availableModels: {}, - availableProviders: {}, - sessionTitle: null, - mcpServersSummary: null, - }; -} - -function stripAnsi(s: string): string { - // eslint-disable-next-line no-control-regex - return s.replace(/\x1b\[[0-9;?]*[a-zA-Z]|\x1b\][^\x07]*\x07/g, ''); -} - -const LONG_MARKDOWN = Array.from( - { length: 40 }, - (_, i) => `### Section ${i + 1}\n\nSome **bold** and \`code\` content in paragraph ${i + 1}.\n`, -).join('\n'); - -async function mountFullscreen(): Promise<{ - state: ReturnType<typeof createTUIState>; - vt: VirtualTerminal; -}> { - const opts: KimiTUIOptions = { - initialAppState: fakeInitialAppState(), - startup: { continueLast: false, yolo: false, auto: false, plan: false }, - }; - vi.stubEnv('KIMI_CODE_TUI_FULL_SCREEN', '1'); - const state = createTUIState(opts); - vi.unstubAllEnvs(); - const vt = new VirtualTerminal(WIDTH, HEIGHT); - (state.ui as { terminal: Terminal }).terminal = vt; - - // Footer is mounted into the dock after init (mirrors mountFooter()). - const footerWrap = new GutterContainer(CHROME_GUTTER, CHROME_GUTTER); - footerWrap.addChild(state.footer); - state.dockContainer?.addChild(footerWrap, { shrink: 1, minSize: 1 }); - state.editorContainer.addChild(state.editor); - state.ui.setFocus(state.editor); - state.ui.start(); - await vt.waitForRender(); - return { state, vt }; -} - -describe('fullscreen layout', () => { - it('keeps the editor bottom border visible after a streaming grow/shrink cycle', async () => { - const { state, vt } = await mountFullscreen(); - expect(state.ui).toBeInstanceOf(TuiAltScreen); - - const screenRows = (): string[] => { - const rows: string[] = []; - for (let i = 0; i < HEIGHT; i++) rows.push(stripAnsi(vt.getViewport()[i] ?? '').trimEnd()); - return rows; - }; - - // User message, then a streaming assistant message with the activity pane up. - state.transcriptContainer.addChild(new UserMessageComponent('分析下这个项目')); - const spinner = new MoonLoader(state.ui); - state.activityContainer.addChild( - new ActivityPaneComponent({ mode: 'tool', spinner, tip: 'streaming' }), - ); - const assistant = new AssistantMessageComponent(); - state.transcriptContainer.addChild(assistant); - assistant.updateContent(LONG_MARKDOWN, { transient: true }); - state.ui.requestRender(true); - await vt.waitForRender(); - - // Streaming ends: final highlight, spinner -> one-row placeholder, debug line. - assistant.updateContent(LONG_MARKDOWN, { transient: false }); - state.activityContainer.clear(); - state.activityContainer.addChild(new Spacer(1)); - state.transcriptContainer.addChild( - new StatusMessageComponent('[Debug] TTFT: 4.3s | TPS: 203 tok/s'), - ); - state.ui.requestRender(true); - await vt.waitForRender(); - - const rows = screenRows(); - const promptRow = rows.findIndex((line) => /│\s*>/.test(line)); - expect(promptRow).toBeGreaterThan(0); - expect(rows[promptRow + 1]).toContain('╰'); - - state.ui.stop(); - }); - - it('jumps between prompts with Ctrl-Shift-Up/Down (OSC 133 zones survive the chain)', async () => { - const { state, vt } = await mountFullscreen(); - - state.transcriptContainer.addChild(new UserMessageComponent('第一轮提问')); - const first = new AssistantMessageComponent(); - state.transcriptContainer.addChild(first); - first.updateContent(`回答一\n\n${LONG_MARKDOWN}`); - state.transcriptContainer.addChild(new UserMessageComponent('第二轮提问')); - const second = new AssistantMessageComponent(); - state.transcriptContainer.addChild(second); - second.updateContent(`回答二\n\n${LONG_MARKDOWN}`); - state.ui.requestRender(true); - await vt.waitForRender(); - - const alt = state.ui as TuiAltScreen; - expect(alt.isFollowingOutput).toBe(true); - - const topRows = (): string[] => - Array.from({ length: 6 }, (_, i) => stripAnsi(vt.getViewport()[i] ?? '').trimEnd()); - - // Zones anchor every user/assistant message, so the nearest previous zone - // below the fold is the current turn's assistant message, then the user - // message that started the turn. - vt.sendInput('\x1b[1;6A'); // ctrl+shift+up = previous prompt - await vt.waitForRender(); - expect(topRows()[1]).toContain('回答二'); - - vt.sendInput('\x1b[1;6A'); - await vt.waitForRender(); - expect(topRows()[1]).toContain('第二轮提问'); - - vt.sendInput('\x1b[1;6B'); // ctrl+shift+down = next prompt - await vt.waitForRender(); - expect(topRows()[1]).toContain('回答二'); - - state.ui.stop(); - }); -}); diff --git a/apps/kimi-code/test/tui/input/image-attachment-store.test.ts b/apps/kimi-code/test/tui/input/image-attachment-store.test.ts index 6cf3fb45d..6add1e428 100644 --- a/apps/kimi-code/test/tui/input/image-attachment-store.test.ts +++ b/apps/kimi-code/test/tui/input/image-attachment-store.test.ts @@ -49,53 +49,12 @@ describe('ImageAttachmentStore', () => { expect(att.mime).toBe('image/jpeg'); }); - it('completes a pending image without changing its attachment id', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 20); - - const completed = s.completeImage(att, { - bytes: new Uint8Array([2, 3]), - mime: 'image/jpeg', - width: 30, - height: 40, - fileId: 'file-2', - }); - - expect(completed).toBe(att); - expect(att.id).toBe(1); - expect(att.bytes).toEqual(new Uint8Array([2, 3])); - expect(att.mime).toBe('image/jpeg'); - expect(att.placeholder).toBe('[image #1 (30×40)]'); - const stale = att; - s.clear(); - const fresh = s.addImage(new Uint8Array([9]), 'image/png', 2, 2); - expect(s.completeImage(stale, { - bytes: new Uint8Array([8]), - mime: 'image/png', - width: 3, - height: 3, - })).toBeUndefined(); - expect(fresh.bytes).toEqual(new Uint8Array([9])); - }); - - it('records the daemon file-store id when the paste was uploaded (v2)', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 20, undefined, 'file-abc'); - expect(att.fileId).toBe('file-abc'); - }); - - it('leaves fileId undefined for attachments that were not uploaded', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 20); - expect(att.fileId).toBeUndefined(); - }); - it('clear() resets ids and empties storage', () => { const s = new ImageAttachmentStore(); - s.addImage(new Uint8Array(), 'image/png', 10, 10, undefined, 'file-1'); + s.addImage(new Uint8Array(), 'image/png', 10, 10); s.addImage(new Uint8Array(), 'image/png', 10, 10); expect(s.size()).toBe(2); - expect(s.clear()).toEqual(['file-1']); + s.clear(); expect(s.size()).toBe(0); const next = s.addImage(new Uint8Array(), 'image/png', 10, 10); expect(next.id).toBe(1); @@ -126,103 +85,4 @@ describe('ImageAttachmentStore', () => { expect(s.get(a.id)).toBeUndefined(); expect(s.get(c.id)).toBeUndefined(); }); - - it('transfers staging file ownership without dropping thumbnail bytes', () => { - const s = new ImageAttachmentStore(); - const bytes = new Uint8Array([1, 2, 3]); - const att = s.addImage(bytes, 'image/png', 10, 10, undefined, 'file-1'); - - expect(s.takeFileIds([att.id])).toEqual(['file-1']); - expect(att.fileId).toBeUndefined(); - expect(att.bytes).toBe(bytes); - expect(s.takeFileIds([att.id])).toEqual([]); - }); - - it('keeps a daemon upload until every extracted message releases it', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 10, undefined, 'file-1'); - - s.retainFileIds([att.id]); - s.retainFileIds([att.id]); - expect(s.takeFileIds([att.id])).toEqual([]); - expect(att.fileId).toBe('file-1'); - expect(s.takeFileIds([att.id])).toEqual(['file-1']); - expect(att.fileId).toBeUndefined(); - }); - - it('releaseRetains consumes the retain but keeps the staged upload on the attachment', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 10, undefined, 'file-1'); - - s.retainFileIds([att.id]); - s.releaseRetains([att.id]); - expect(att.fileId).toBe('file-1'); - // The retain is gone: a later take consumes the upload immediately. - expect(s.takeFileIds([att.id])).toEqual(['file-1']); - expect(att.fileId).toBeUndefined(); - }); - - it('releaseRetains leaves retains held by other submissions untouched', () => { - const s = new ImageAttachmentStore(); - const att = s.addImage(new Uint8Array([1]), 'image/png', 10, 10, undefined, 'file-1'); - - s.retainFileIds([att.id]); // submission A queues - s.retainFileIds([att.id]); // submission B queues - s.releaseRetains([att.id]); // A is recalled into the editor - s.retainFileIds([att.id]); // A's restored draft resubmits - // A's consuming turn ends: one retain (B's) is still outstanding, so the - // upload survives. - expect(s.takeFileIds([att.id])).toEqual([]); - expect(att.fileId).toBe('file-1'); - // B's turn ends: the last retain is gone, the upload is taken. - expect(s.takeFileIds([att.id])).toEqual(['file-1']); - expect(att.fileId).toBeUndefined(); - }); - - it('completeVideo lands the daemon upload id and clears the pending marker', () => { - const s = new ImageAttachmentStore(); - const att = s.addVideo('video/mp4', '/tmp/original.mp4'); - att.pending = Promise.resolve(); - - const completed = s.completeVideo(att, { fileId: 'file-v1', fileExpiresAt: 123_000 }); - - expect(completed).toBe(att); - expect(att.fileId).toBe('file-v1'); - expect(att.fileExpiresAt).toBe(123_000); - expect(att.pending).toBeUndefined(); - - // A cleared attachment is not completed — the caller deletes the upload. - s.clear(); - const stale = att; - const fresh = s.addVideo('video/mp4', '/tmp/other.mp4'); - expect(s.completeVideo(stale, { fileId: 'file-v2' })).toBeUndefined(); - expect(fresh.fileId).toBeUndefined(); - }); - - it('clear() keeps staged uploads that still have an outstanding retain', () => { - const s = new ImageAttachmentStore(); - const img = s.addImage(new Uint8Array(), 'image/png', 10, 10, undefined, 'file-1'); - const vid = s.addVideo('video/mp4', '/tmp/a.mp4'); - s.completeVideo(vid, { fileId: 'file-2' }); - - // The video's upload is still referenced by a stashed/queued draft; the - // image's is not, so only the latter comes back for deletion. - s.retainFileIds([vid.id]); - expect(s.clear()).toEqual(['file-1']); - expect(s.size()).toBe(0); - expect(img.fileId).toBe('file-1'); - }); - - it('takes a video upload through the same retain/take lifecycle as an image', () => { - const s = new ImageAttachmentStore(); - const vid = s.addVideo('video/mp4', '/tmp/a.mp4'); - s.completeVideo(vid, { fileId: 'file-v1' }); - - s.retainFileIds([vid.id]); - s.retainFileIds([vid.id]); - expect(s.takeFileIds([vid.id])).toEqual([]); - expect(vid.fileId).toBe('file-v1'); - expect(s.takeFileIds([vid.id])).toEqual(['file-v1']); - expect(vid.fileId).toBeUndefined(); - }); }); diff --git a/apps/kimi-code/test/tui/input/image-placeholder.test.ts b/apps/kimi-code/test/tui/input/image-placeholder.test.ts index 67f5939bd..85755641c 100644 --- a/apps/kimi-code/test/tui/input/image-placeholder.test.ts +++ b/apps/kimi-code/test/tui/input/image-placeholder.test.ts @@ -1,25 +1,14 @@ -/** - * Media placeholder expansion and rewrite contracts, including dispatch-time - * fallback from expiring daemon uploads to bytes retained by the TUI. - */ - -import { existsSync, mkdtempSync, readFileSync, readdirSync, rmSync, utimesSync, writeFileSync } from 'node:fs'; +import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; +import { fileURLToPath } from 'node:url'; import { describe, it, expect } from 'vitest'; -import { parseDaemonFileUrl } from '@moonshot-ai/kimi-code-sdk'; - import { KIMI_CODE_HOME_ENV } from '#/constant/app'; import { ImageAttachmentStore } from '#/tui/utils/image-attachment-store'; import { extractMediaAttachments, - makeExtractionResendable, - pendingMediaIngestions, - persistOriginalImageSync, - refreshExpiringImageFileRefs, - resolveOriginalCaptions, rewriteMediaPlaceholders, } from '#/tui/utils/image-placeholder'; import { getCacheDir } from '#/utils/paths'; @@ -55,14 +44,14 @@ function makeTempDir(): string { type VideoUrlPart = { type: 'video_url'; videoUrl: { url: string } }; // Prompt-attached videos are emitted as a `video_url` part whose url is a -// bare `kimi-file://` daemon reference (the paste was uploaded at paste -// time); pull the url out for assertions. -function videoUrlFromParts(parts: unknown[]): string { +// local `file://` reference to the cache copy; decode it back to a filesystem +// path for assertions. +function videoPathFromParts(parts: unknown[]): string { const part = parts.find( (p): p is VideoUrlPart => (p as VideoUrlPart).type === 'video_url', ); if (!part) throw new Error(`no video_url part found in: ${JSON.stringify(parts)}`); - return part.videoUrl.url; + return fileURLToPath(part.videoUrl.url); } describe('extractMediaAttachments', () => { @@ -104,21 +93,30 @@ describe('extractMediaAttachments', () => { }); it('keeps matched-placeholder order with mixed image and video attachments', () => { - const store = new ImageAttachmentStore(); - const img = store.addImage(new Uint8Array([1]), 'image/png', 10, 10); - const vid = store.addVideo('video/quicktime', '/tmp/clip.mov'); - store.completeVideo(vid, { fileId: 'file-v1' }); - const text = `first ${img.placeholder} then ${vid.placeholder} end`; - const r = extractMediaAttachments(text, store); - expect(r.imageAttachmentIds).toEqual([1]); - expect(r.videoAttachmentIds).toEqual([2]); - expect(r.parts).toEqual([ - { type: 'text', text: 'first ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,AQ==' } }, - { type: 'text', text: ' then ' }, - { type: 'video_url', videoUrl: { url: 'kimi-file://file-v1' } }, - { type: 'text', text: ' end' }, - ]); + const { cleanup } = setupTempCache(); + const srcDir = makeTempDir(); + try { + const srcVideo = join(srcDir, 'clip.mov'); + writeFileSync(srcVideo, 'video-bytes'); + const store = new ImageAttachmentStore(); + const img = store.addImage(new Uint8Array([1]), 'image/png', 10, 10); + const vid = store.addVideo('video/quicktime', srcVideo); + const text = `first ${img.placeholder} then ${vid.placeholder} end`; + const r = extractMediaAttachments(text, store); + expect(r.imageAttachmentIds).toEqual([1]); + expect(r.videoAttachmentIds).toEqual([2]); + expect(r.parts[0]).toEqual({ type: 'text', text: 'first ' }); + expect(r.parts[1]).toEqual({ + type: 'image_url', + imageUrl: { url: 'data:image/png;base64,AQ==' }, + }); + const cachePath = videoPathFromParts(r.parts); + expect(cachePath.startsWith(getCacheDir())).toBe(true); + expect(readFileSync(cachePath, 'utf8')).toBe('video-bytes'); + } finally { + cleanup(); + rmSync(srcDir, { recursive: true, force: true }); + } }); it('leaves unresolved (typed by hand) placeholders as literal text', () => { @@ -139,73 +137,90 @@ describe('extractMediaAttachments', () => { }); }); - it('emits a bare kimi-file video_url part for an uploaded video', () => { + it('keeps the video label (including special chars) in the cache path', () => { const { cleanup } = setupTempCache(); + const srcDir = makeTempDir(); try { + const srcVideo = join(srcDir, 'source.mp4'); + writeFileSync(srcVideo, 'x'); const store = new ImageAttachmentStore(); - const att = store.addVideo('video/mp4', '/tmp/sample.mp4'); - store.completeVideo(att, { fileId: 'file-v1' }); + // The filename drives the cache label; `&` is a valid path char the cache + // copy keeps verbatim (the engine escapes it if it later renders a tag). + const att = store.addVideo('video/mp4', srcVideo, 'a&b.mp4'); const r = extractMediaAttachments(att.placeholder, store); - expect(r.hasMedia).toBe(true); - expect(r.videoAttachmentIds).toEqual([1]); expect(r.parts).toHaveLength(1); - const part = r.parts[0] as VideoUrlPart; - expect(part.type).toBe('video_url'); - // No cache copy and no `?path=`: the engine's prompt intake - // materializes the session copy and rewrites the reference — the part - // is self-contained. - expect(parseDaemonFileUrl(part.videoUrl.url)).toEqual({ fileId: 'file-v1' }); - expect(existsSync(getCacheDir())).toBe(false); + expect((r.parts[0] as VideoUrlPart).type).toBe('video_url'); + expect(videoPathFromParts(r.parts).endsWith('a&b.mp4')).toBe(true); } finally { cleanup(); + rmSync(srcDir, { recursive: true, force: true }); } }); - it('refuses a video whose upload is still in flight', () => { - const store = new ImageAttachmentStore(); - const att = store.addVideo('video/mp4', '/tmp/sample.mp4'); - att.pending = new Promise<void>(() => undefined); // never settles - expect(() => extractMediaAttachments(att.placeholder, store)).toThrow( - /still uploading/, - ); + it('copies video placeholders into the cache and emits a file:// video_url part', () => { + const { cleanup } = setupTempCache(); + const srcDir = makeTempDir(); + try { + const srcVideo = join(srcDir, 'sample.mp4'); + writeFileSync(srcVideo, 'video-data'); + const store = new ImageAttachmentStore(); + const att = store.addVideo('video/mp4', srcVideo); + const r = extractMediaAttachments(att.placeholder, store); + expect(r.hasMedia).toBe(true); + expect(r.videoAttachmentIds).toEqual([1]); + const part = r.parts[0] as VideoUrlPart; + expect(part.type).toBe('video_url'); + expect(part.videoUrl.url.startsWith('file:')).toBe(true); + const cachePath = videoPathFromParts(r.parts); + // The part points at the cache copy, not the original source path. + expect(cachePath.startsWith(getCacheDir())).toBe(true); + expect(cachePath).not.toBe(srcVideo); + expect(readFileSync(cachePath, 'utf8')).toBe('video-data'); + } finally { + cleanup(); + rmSync(srcDir, { recursive: true, force: true }); + } }); - it('refuses a video whose upload failed or is missing', () => { - const store = new ImageAttachmentStore(); - const att = store.addVideo('video/mp4', '/tmp/sample.mp4'); - expect(() => extractMediaAttachments(att.placeholder, store)).toThrow( - /could not be uploaded/, - ); - }); - - it('refuses a video whose staged upload is too close to expiry', () => { - const store = new ImageAttachmentStore(); - const att = store.addVideo('video/mp4', '/tmp/sample.mp4'); - store.completeVideo(att, { - fileId: 'file-v1', - fileExpiresAt: Date.now() + 1_000, - }); - expect(() => extractMediaAttachments(att.placeholder, store)).toThrow(/expired/); - }); - - it('expands a compressed paste without a caption — captions are authored at dispatch', () => { + it('inserts a compression caption before an image that was compressed at paste time', () => { const store = new ImageAttachmentStore(); const att = store.addImage(new Uint8Array([1, 2, 3]), 'image/png', 2000, 2000, { - bytes: new Uint8Array([9, 8, 7]), + path: '/tmp/kimi-code-original-images/abc.png', width: 2600, height: 2600, - byteLength: 3, + byteLength: 123456, mime: 'image/png', }); const r = extractMediaAttachments(`look ${att.placeholder}`, store); - // Extraction stays persistence-free: no caption part, no original path. - expect(r.parts).toEqual([ - { type: 'text', text: 'look ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,AQID' } }, - ]); - expect(att.original?.path).toBeUndefined(); + expect(r.parts).toHaveLength(2); + const caption = r.parts[0]; + if (caption?.type !== 'text') throw new Error('expected leading text part'); + expect(caption.text).toContain('Image compressed'); + expect(caption.text).toContain('2600x2600'); + expect(caption.text).toContain('/tmp/kimi-code-original-images/abc.png'); + expect(r.parts[1]).toEqual({ + type: 'image_url', + imageUrl: { url: 'data:image/png;base64,AQID' }, + }); + }); + + it('notes an unpreserved original when persistence failed at paste time', () => { + const store = new ImageAttachmentStore(); + const att = store.addImage(new Uint8Array([1]), 'image/png', 2000, 2000, { + path: null, + width: 2600, + height: 2600, + byteLength: 123456, + mime: 'image/png', + }); + + const r = extractMediaAttachments(att.placeholder, store); + + const caption = r.parts[0]; + if (caption?.type !== 'text') throw new Error('expected leading text part'); + expect(caption.text).toMatch(/not preserved/i); }); it('adds no caption for an uncompressed image attachment', () => { @@ -214,427 +229,6 @@ describe('extractMediaAttachments', () => { expect(r.parts).toHaveLength(1); expect(r.parts[0]?.type).toBe('image_url'); }); - - it('expands an uploaded (fileId) image into a bare kimi-file reference', () => { - const { cleanup } = setupTempCache(); - try { - const store = new ImageAttachmentStore(); - const att = store.addImage(new Uint8Array([0x89, 0x50, 0x4e, 0x47]), 'image/png', 640, 480, undefined, 'file-1'); - const r = extractMediaAttachments(`describe ${att.placeholder} please`, store); - expect(r.hasMedia).toBe(true); - expect(r.imageAttachmentIds).toEqual([1]); - // No tag text part and no `?path=`: the engine's prompt intake - // materializes the session copy and rewrites the reference with its - // path — the part is self-contained, no paired tag is authored. - expect(r.parts).toEqual([ - { type: 'text', text: 'describe ' }, - { type: 'image_url', imageUrl: { url: 'kimi-file://file-1' } }, - { type: 'text', text: ' please' }, - ]); - expect(parseDaemonFileUrl('kimi-file://file-1')).toEqual({ fileId: 'file-1' }); - // The edge stages no local copy for an uploaded image — the cache dir - // is never even created. - expect(existsSync(getCacheDir())).toBe(false); - } finally { - cleanup(); - } - }); - - it('falls back to retained bytes when an uploaded image is too close to expiry', () => { - const store = new ImageAttachmentStore(); - const att = store.addImage( - new Uint8Array([0x89, 0x50, 0x4e, 0x47]), - 'image/png', - 640, - 480, - undefined, - 'file-1', - 1_060_000, - ); - - const parts = refreshExpiringImageFileRefs( - [{ type: 'image_url', imageUrl: { url: 'kimi-file://file-1' } }], - [att.id], - store, - 1_000_000, - ); - - expect(parts).toEqual([ - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,iVBORw==' } }, - ]); - expect(att.fileId).toBeUndefined(); - expect(att.fileExpiresAt).toBeUndefined(); - }); - - it('rebuilds an uploaded image as inline bytes for a new-session resend', () => { - const { cleanup } = setupTempCache(); - try { - const bytes = new Uint8Array([0x89, 0x50, 0x4e, 0x47]); - const store = new ImageAttachmentStore(); - const att = store.addImage(bytes, 'image/png', 640, 480, undefined, 'file-1'); - const extraction = extractMediaAttachments(att.placeholder, store); - - const resend = makeExtractionResendable(extraction); - - expect(resend.imageAttachmentIds).toEqual([]); - expect(resend.parts).toContainEqual({ - type: 'image_url', - imageUrl: { url: 'data:image/png;base64,iVBORw==' }, - }); - } finally { - cleanup(); - } - }); - - it('rebuilds a compressed paste with its caption and original for a new-session resend', () => { - const dir = makeTempDir(); - try { - const store = new ImageAttachmentStore(); - const att = store.addImage( - new Uint8Array([1, 2, 3]), - 'image/png', - 2000, - 1000, - { - bytes: new Uint8Array([9, 8, 7, 6]), - width: 2600, - height: 2600, - byteLength: 4, - mime: 'image/png', - }, - 'file-1', - ); - // The session reset clears the store, so the snapshot is the only place - // the original survives — the resend must persist it into the NEW - // session's originals dir and author the caption itself. - const extraction = extractMediaAttachments(att.placeholder, store); - - const resend = makeExtractionResendable(extraction, dir); - - expect(resend.imageAttachmentIds).toEqual([]); - expect(resend.parts).toHaveLength(2); - const caption = resend.parts[0]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toContain('Image compressed'); - expect(caption.text).toContain('2600x2600'); - const files = readdirSync(dir); - expect(files).toHaveLength(1); - expect(caption.text).toContain(join(dir, files[0]!)); - expect(resend.parts[1]).toEqual({ - type: 'image_url', - imageUrl: { url: 'data:image/png;base64,AQID' }, - }); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('keeps expanding an uploaded image as a bare reference when the cache dir is broken', () => { - const { cleanup } = setupTempCache(); - try { - // A file at the cache dir path breaks local cache copies, but neither - // form stages one: an uploaded image expands to a bare reference and - // the inline (no fileId) form embeds its bytes. - writeFileSync(getCacheDir(), 'occupied'); - const store = new ImageAttachmentStore(); - const uploaded = store.addImage(new Uint8Array([1]), 'image/png', 10, 10, undefined, 'file-1'); - const plain = store.addImage(new Uint8Array([2]), 'image/png', 20, 20); - const r = extractMediaAttachments(`${uploaded.placeholder} and ${plain.placeholder}`, store); - expect(r.imageAttachmentIds).toEqual([1, 2]); - expect(r.parts).toEqual([ - { type: 'image_url', imageUrl: { url: 'kimi-file://file-1' } }, - { type: 'text', text: ' and ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,Ag==' } }, - ]); - } finally { - cleanup(); - } - }); - - it('stages nothing when a later video refuses the submission', () => { - const { cleanup } = setupTempCache(); - try { - const store = new ImageAttachmentStore(); - const first = store.addVideo('video/mp4', '/tmp/first.mp4'); - store.completeVideo(first, { fileId: 'file-v1' }); - const missing = store.addVideo('video/mp4', '/tmp/missing.mp4'); - - expect(() => - extractMediaAttachments(`${first.placeholder} ${missing.placeholder}`, store), - ).toThrow(/could not be uploaded/); - // The prompt path stages no cache copies at all, so the throw leaves - // no local cleanup behind — the first video's daemon upload is owned - // by its retain, not by a staging path. - expect(existsSync(getCacheDir())).toBe(false); - } finally { - cleanup(); - } - }); -}); - -describe('resolveOriginalCaptions', () => { - function storeWithOriginal( - original?: { - bytes: Uint8Array; - width: number; - height: number; - byteLength: number; - mime: string; - path?: string; - }, - fileId?: string, - ) { - const store = new ImageAttachmentStore(); - const att = store.addImage( - new Uint8Array([1, 2, 3]), - 'image/png', - 2000, - 1000, - original, - fileId, - ); - return { store, att }; - } - - it('persists the original into the given dir and inserts the caption before the image', () => { - const dir = makeTempDir(); - try { - const originalBytes = new Uint8Array([9, 8, 7, 6]); - const { store, att } = storeWithOriginal({ - bytes: originalBytes, - width: 2600, - height: 2600, - byteLength: originalBytes.length, - mime: 'image/png', - }); - const r = extractMediaAttachments(`look ${att.placeholder}`, store); - - const resolved = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - expect(att.original?.path?.startsWith(dir)).toBe(true); - expect(readFileSync(att.original!.path!)).toEqual(Buffer.from(originalBytes)); - expect(resolved).toHaveLength(3); - const caption = resolved[1]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toContain('Image compressed'); - expect(caption.text).toContain('2600x2600'); - expect(caption.text).toContain(att.original!.path!); - expect(resolved[2]).toEqual({ - type: 'image_url', - imageUrl: { url: 'data:image/png;base64,AQID' }, - }); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('releases the in-memory original bytes once persistence succeeds', () => { - const dir = makeTempDir(); - try { - const originalBytes = new Uint8Array([9, 8, 7, 6]); - const { store, att } = storeWithOriginal({ - bytes: originalBytes, - width: 2600, - height: 2600, - byteLength: originalBytes.length, - mime: 'image/png', - }); - const r = extractMediaAttachments(att.placeholder, store); - resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - // The on-disk copy is the original from here on; the caption still - // renders the original size from the retained metadata. - expect(att.original?.bytes).toBeUndefined(); - const again = resolveOriginalCaptions( - r.parts, - r.imageAttachmentIds, - store, - dir, - ); - const caption = again[0]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toContain('2600x2600'); - expect(caption.text).toContain('4 B'); - expect(caption.text).toContain(att.original!.path!); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('authors the caption before the bare kimi-file reference', () => { - const dir = makeTempDir(); - try { - const { store, att } = storeWithOriginal( - { bytes: new Uint8Array([9, 9]), width: 2600, height: 2600, byteLength: 2, mime: 'image/png' }, - 'file-2', - ); - const r = extractMediaAttachments(att.placeholder, store); - - const resolved = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - expect(resolved).toHaveLength(2); - const caption = resolved[0]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toContain('Image compressed'); - expect(caption.text).toContain(att.original!.path!); - expect(resolved[1]).toEqual({ - type: 'image_url', - imageUrl: { url: 'kimi-file://file-2' }, - }); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('refreshes an already-authored caption in place instead of duplicating it', () => { - const dir = makeTempDir(); - try { - const { store, att } = storeWithOriginal({ - bytes: new Uint8Array([9]), - width: 2600, - height: 2600, - byteLength: 1, - mime: 'image/png', - }); - const r = extractMediaAttachments(att.placeholder, store); - const once = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - const twice = resolveOriginalCaptions(once, r.imageAttachmentIds, store, dir); - - expect(twice).toHaveLength(2); - expect(twice[0]?.type).toBe('text'); - expect(twice[1]?.type).toBe('image_url'); - // The content-addressed original was persisted exactly once. - expect(att.original?.path?.startsWith(dir)).toBe(true); - expect(readdirSync(dir)).toHaveLength(1); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('reuses an already-persisted original path without rewriting the file', () => { - const dir = makeTempDir(); - try { - const existing = join(dir, 'already.png'); - writeFileSync(existing, 'orig'); - const { store, att } = storeWithOriginal({ - bytes: new Uint8Array([7, 7, 7]), - width: 2600, - height: 2600, - byteLength: 3, - mime: 'image/png', - path: existing, - }); - const r = extractMediaAttachments(att.placeholder, store); - - const resolved = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - const caption = resolved[0]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toContain(existing); - expect(readFileSync(existing, 'utf8')).toBe('orig'); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('notes an unpreserved original when persistence fails, then retries at a later dispatch', () => { - const dir = makeTempDir(); - try { - // A file where the target directory must be created breaks persistence. - const occupied = join(dir, 'occupied'); - writeFileSync(occupied, 'x'); - const { store, att } = storeWithOriginal({ - bytes: new Uint8Array([5, 5]), - width: 2600, - height: 2600, - byteLength: 2, - mime: 'image/png', - }); - const r = extractMediaAttachments(att.placeholder, store); - - const failed = resolveOriginalCaptions( - r.parts, - r.imageAttachmentIds, - store, - join(occupied, 'sub'), - ); - - const caption = failed[0]; - if (caption?.type !== 'text') throw new Error('expected caption text part'); - expect(caption.text).toMatch(/not preserved/i); - // The failure is not terminal: the path stays unset and the bytes are - // retained, so a later dispatch retries the write. - expect(att.original?.path).toBeUndefined(); - expect(att.original?.bytes).toBeDefined(); - - const retried = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - expect(att.original?.path?.startsWith(dir)).toBe(true); - const retryCaption = retried[0]; - if (retryCaption?.type !== 'text') throw new Error('expected caption text part'); - expect(retryCaption.text).toContain(att.original!.path!); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('skips the caption when ingestion landed after extraction (stale inline part)', () => { - const dir = makeTempDir(); - try { - const store = new ImageAttachmentStore(); - const rawBytes = new Uint8Array([1, 2, 3, 4]); - // Extraction raced the background ingestion: the part encodes the raw - // paste bytes… - const att = store.addImage(rawBytes, 'image/png', 2600, 2600); - const r = extractMediaAttachments(att.placeholder, store); - // …then ingestion completed, recording the compressed form. Captioning - // now would describe an image the model did not receive. - store.completeImage(att, { - bytes: new Uint8Array([1, 2, 3]), - mime: 'image/png', - width: 2000, - height: 2000, - original: { bytes: rawBytes, width: 2600, height: 2600, byteLength: 4, mime: 'image/png' }, - }); - - const resolved = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, dir); - - expect(resolved).toHaveLength(1); - expect(resolved[0]?.type).toBe('image_url'); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('leaves images without an original untouched', () => { - const { store, placeholder } = storeWith(new Uint8Array([0xaa])); - const r = extractMediaAttachments(placeholder, store); - const resolved = resolveOriginalCaptions(r.parts, r.imageAttachmentIds, store, undefined); - expect(resolved).toHaveLength(1); - expect(resolved[0]?.type).toBe('image_url'); - }); -}); - -describe('persistOriginalImageSync', () => { - it('evicts the oldest originals once the store exceeds the size cap', () => { - const dir = makeTempDir(); - try { - const first = persistOriginalImageSync(new Uint8Array(6).fill(1), 'image/png', dir); - expect(first).not.toBeNull(); - // Pin the first file far into the past so eviction order is deterministic. - const old = new Date(Date.now() - 60_000); - utimesSync(first!, old, old); - - const second = persistOriginalImageSync(new Uint8Array(6).fill(2), 'image/png', dir, 10); - - expect(second).not.toBeNull(); - expect(existsSync(first!)).toBe(false); - expect(existsSync(second!)).toBe(true); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); }); describe('rewriteMediaPlaceholders', () => { @@ -781,89 +375,3 @@ describe('rewriteMediaPlaceholders', () => { } }); }); - -describe('pendingMediaIngestions', () => { - it('returns undefined for text without media placeholders', () => { - const store = new ImageAttachmentStore(); - expect(pendingMediaIngestions('hello world', store, 5)).toBeUndefined(); - }); - - it('returns undefined when no referenced image has a pending ingestion', () => { - const { store, placeholder } = storeWith(new Uint8Array([0xaa, 0xbb])); - expect(pendingMediaIngestions(`describe ${placeholder}`, store, 5)).toBeUndefined(); - }); - - it('waits for a pending ingestion so extraction can use the daemon-ref form', async () => { - const { store, placeholder } = storeWith(new Uint8Array([0xaa, 0xbb])); - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - let finish!: () => void; - att.pending = new Promise<void>((resolve) => { - finish = () => { - // Complete like the background ingestion would: land the upload id, - // then resolve and clear the pending marker. - att.fileId = 'file-1'; - att.fileExpiresAt = Date.now() + 60 * 60 * 1000; - att.pending = undefined; - resolve(); - }; - }); - - const waited = pendingMediaIngestions(`describe ${placeholder}`, store, 1_000); - if (waited === undefined) throw new Error('expected a pending wait'); - let settled = false; - void waited.then(() => { - settled = true; - }); - await new Promise((resolve) => setTimeout(resolve, 10)); - expect(settled).toBe(false); - - finish(); - await waited; - expect(settled).toBe(true); - - const r = extractMediaAttachments(`describe ${placeholder}`, store); - const part = r.parts.find((p) => p.type === 'image_url'); - expect(part?.type).toBe('image_url'); - if (part?.type !== 'image_url') throw new Error('expected an image part'); - expect(parseDaemonFileUrl(part.imageUrl.url)?.fileId).toBe('file-1'); - }); - - it('waits for a pending video upload so extraction can use the daemon-ref form', async () => { - const store = new ImageAttachmentStore(); - const att = store.addVideo('video/mp4', '/tmp/clip.mp4'); - let finish!: () => void; - att.pending = new Promise<void>((resolve) => { - finish = () => { - store.completeVideo(att, { fileId: 'file-v1' }); - resolve(); - }; - }); - - const waited = pendingMediaIngestions(`watch ${att.placeholder}`, store, 1_000); - if (waited === undefined) throw new Error('expected a pending wait'); - finish(); - await waited; - - const r = extractMediaAttachments(`watch ${att.placeholder}`, store); - expect(videoUrlFromParts(r.parts)).toBe('kimi-file://file-v1'); - }); - - it('bounds the wait by the timeout so a slow ingestion extracts to the inline form', async () => { - const { store, placeholder } = storeWith(new Uint8Array([0xaa, 0xbb])); - const att = store.get(1); - if (att?.kind !== 'image') throw new Error('expected image attachment'); - att.pending = new Promise<void>(() => undefined); // never settles - - const start = Date.now(); - const waited = pendingMediaIngestions(`describe ${placeholder}`, store, 20); - if (waited === undefined) throw new Error('expected a pending wait'); - await waited; - expect(Date.now() - start).toBeLessThan(1_000); - - const r = extractMediaAttachments(`describe ${placeholder}`, store); - const part = r.parts.find((p) => p.type === 'image_url'); - if (part?.type !== 'image_url') throw new Error('expected an image part'); - expect(part.imageUrl.url.startsWith('data:image/png;base64,')).toBe(true); - }); -}); diff --git a/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts b/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts index 5e56a7aea..619ecf2c2 100644 --- a/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts +++ b/apps/kimi-code/test/tui/kimi-tui-message-flow.test.ts @@ -1,5 +1,4 @@ import { AsyncLocalStorage } from 'node:async_hooks'; -import { existsSync } from 'node:fs'; import { mkdtemp, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join, resolve } from 'node:path'; @@ -14,13 +13,12 @@ import type { ApprovalResponse, Event, GoalSnapshot, - Session, } from '@moonshot-ai/kimi-code-sdk'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { ApprovalPanelComponent } from '#/tui/components/dialogs/approval-panel'; import { EffortSelectorComponent } from '#/tui/components/dialogs/effort-selector'; -import { kimiCodePluginMarketplaceUrl } from '#/constant/app'; +import { KIMI_CODE_PLUGIN_MARKETPLACE_URL } from '#/constant/app'; import { MOON_SPINNER_FRAMES } from '#/tui/constant/rendering'; import { AgentSwarmProgressComponent, @@ -30,7 +28,6 @@ import { AssistantMessageComponent } from '#/tui/components/messages/assistant-m import { StepSummaryComponent } from '#/tui/components/messages/step-summary'; import { ToolCallComponent } from '#/tui/components/messages/tool-call'; import { - groupTurns, TRANSCRIPT_KEEP_RECENT_ASSISTANT, TRANSCRIPT_KEEP_RECENT_ASSISTANT_COMPLETED, TRANSCRIPT_KEEP_RECENT_STEPS, @@ -48,10 +45,8 @@ import { PluginsPanelComponent, } from '#/tui/components/dialogs/plugins-selector'; import { KimiTUI, type KimiTUIStartupInput, type TUIState } from '#/tui/kimi-tui'; -import type { SessionReplayRenderer } from '#/tui/controllers/session-replay'; import type { StreamingUIController } from '#/tui/controllers/streaming-ui'; import { handleFeedbackCommand } from '#/tui/commands/info'; -import { copyTextToClipboard } from '#/utils/clipboard/clipboard-text'; import { openUrl } from '#/utils/open-url'; import { createFeedbackArchivePath } from '../../src/feedback/archive'; import { packageCodebase, scanCodebase } from '../../src/feedback/codebase'; @@ -62,12 +57,8 @@ import { runModelSelector, type FeedbackPromptResult, } from '#/tui/commands/prompts'; -import type { QueuedMessage, TranscriptEntry } from '#/tui/types'; +import type { QueuedMessage } from '#/tui/types'; import type { ImageAttachmentStore } from '#/tui/utils/image-attachment-store'; -import { - extractMediaAttachments, - type ExtractionResult, -} from '#/tui/utils/image-placeholder'; vi.mock('#/tui/commands/prompts', async (importOriginal) => { const actual = await importOriginal<typeof import('#/tui/commands/prompts')>(); @@ -106,12 +97,6 @@ vi.mock('../../src/feedback/archive', async (importOriginal) => { // out so the test suite never spawns a browser window. vi.mock('#/utils/open-url', () => ({ openUrl: vi.fn() })); -// Clipboard access spawns platform tools (pbcopy/wl-copy …) and emits OSC 52 — -// stub it out so the suite never touches the real clipboard or stdout. -vi.mock('#/utils/clipboard/clipboard-text', () => ({ - copyTextToClipboard: vi.fn(async () => 'native'), -})); - const ESC = String.fromCodePoint(0x1b); const BEL = String.fromCodePoint(0x07); @@ -124,7 +109,6 @@ function stripSgr(text: string): string { interface MessageDriver { state: TUIState; streamingUI: StreamingUIController; - sessionReplay: SessionReplayRenderer; pluginCommandMap: Map<string, string>; sessionEventHandler: { startSubscription(): void; @@ -132,14 +116,8 @@ interface MessageDriver { }; init(): Promise<boolean>; handleUserInput(text: string): void; - appendTranscriptEntry(entry: TranscriptEntry): void; persistInputHistory(text: string): Promise<void>; sendQueuedMessage(session: unknown, item: QueuedMessage): void; - recallLastQueued(): QueuedMessage | undefined; - recallStashedMedia(extraction: ExtractionResult | undefined): void; - clearQueuedMessages(): void; - closeSession(reason: string): Promise<void>; - setSession(session: unknown): Promise<void>; getCurrentSessionId(): string; } @@ -268,7 +246,6 @@ function makeSession(overrides: Record<string, unknown> = {}) { reloadPlugins: vi.fn(async () => ({ added: [], removed: [], errors: [] })), reloadSession: vi.fn(async () => ({})), activateSkill: vi.fn(async () => {}), - promptWithSkills: vi.fn(async () => {}), getPluginInfo: vi.fn(async (id: string) => ({ id, displayName: id, @@ -308,7 +285,6 @@ function makeHarness(session = makeSession(), overrides: Record<string, unknown> sessionDir: '/tmp/session-a', manifest: {}, })), - deleteFile: vi.fn(async () => {}), close: vi.fn(async () => {}), track: vi.fn(), setTelemetryContext: vi.fn(), @@ -468,26 +444,6 @@ async function makeTempHome(): Promise<string> { return dir; } -function stagedImage(imageStore: ImageAttachmentStore, fileId: string) { - return imageStore.addImage(new Uint8Array([0xaa, 0xbb]), 'image/png', 1, 1, undefined, fileId); -} - -/** - * Emits the turn.started/turn.ended pair that claims and then releases a - * staged-media lease; `between` runs assertions after the claim. - */ -function emitTurn(driver: MessageDriver, turnId: number, between?: () => void): void { - driver.sessionEventHandler.handleEvent( - { type: 'turn.started', agentId: 'main', turnId, origin: { kind: 'user' } } as Event, - () => {}, - ); - between?.(); - driver.sessionEventHandler.handleEvent( - { type: 'turn.ended', agentId: 'main', turnId, reason: 'completed' } as Event, - () => {}, - ); -} - async function makeExportedSessionZip(content = 'session zip'): Promise<string> { const dir = await mkdtemp(join(tmpdir(), 'kimi-code-feedback-export-')); tempDirs.push(dir); @@ -558,7 +514,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); expect(harness.createSession).toHaveBeenCalledTimes(1); expect(harness.createSession).toHaveBeenCalledWith({ @@ -631,624 +587,6 @@ describe('KimiTUI message flow', () => { expect(driver.getCurrentSessionId()).toBe('ses-lazy'); }); - it('submits inline skill tokens with the prompt as one grouped submission (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('please /skill:review and /skill:security this change'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith( - 'please /skill:review and /skill:security this change', - [{ name: 'review' }, { name: 'security' }], - ); - }); - expect(session.prompt).not.toHaveBeenCalled(); - expect(session.activateSkill).not.toHaveBeenCalled(); - }); - - it('combines a leading skill command with later inline skills into one submission (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/skill:review check this /skill:security'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith( - '/skill:review check this /skill:security', - [{ name: 'review' }, { name: 'security' }], - ); - }); - expect(session.activateSkill).not.toHaveBeenCalled(); - }); - - it('bundles a repeated leading skill as one bundled submission (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/skill:review check /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith('/skill:review check /skill:review', [ - { name: 'review' }, - ]); - }); - expect(session.activateSkill).not.toHaveBeenCalled(); - }); - - it('passes no args in a bundle while media rides the prompt parts (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addImage(new Uint8Array([0xaa, 0xbb]), 'image/png', 1, 1); - - driver.handleUserInput(`/skill:review inspect ${attachment.placeholder} /skill:security`); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith( - [ - { type: 'text', text: '/skill:review inspect ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }, - { type: 'text', text: ' /skill:security' }, - ], - [{ name: 'review' }, { name: 'security' }], - ); - }); - }); - - it('bundles newline-separated skills with the leading one included (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/skill:review\ncheck this /skill:security'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith( - '/skill:review\ncheck this /skill:security', - [{ name: 'review' }, { name: 'security' }], - ); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - - it('scans inline skills in messages that start with an unknown slash token (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/dance please use /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith( - '/dance please use /skill:review', - [{ name: 'review' }], - ); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - - it('keeps inline skill tokens as plain text on the legacy engine', async () => { - const session = makeSession({ id: 'ses-1' }); - const { driver } = await makeDriver(session, { - listSkills: undefined, - listPluginCommands: vi.fn(async () => []), - }); - ( - driver as unknown as { skillCommandMap: Map<string, string> } - ).skillCommandMap.set('skill:review', 'review'); - - driver.handleUserInput('please /skill:review this'); - - await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('please /skill:review this', { promptId: undefined }); - }); - expect(session.promptWithSkills).not.toHaveBeenCalled(); - }); - - it('queues an inline-skill prompt while a goal is active (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - // Materialize the lazy session first: an active goal only exists inside a - // live session, and lazy creation would refresh (and clear) the goal - // snapshot set up below. - await (driver as unknown as { ensureSession(): Promise<unknown> }).ensureSession(); - driver.state.appState.goal = makeActiveGoalSnapshot(); - - driver.handleUserInput('check /skill:review'); - - expect(session.promptWithSkills).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - expect.objectContaining({ - text: 'check /skill:review', - inlineSkillActivations: [{ skillName: 'review' }], - }), - ]); - }); - - it('queues a leading-combo bundle while busy instead of rejecting it (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await (driver as unknown as { ensureSession(): Promise<unknown> }).ensureSession(); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - driver.state.appState.goal = makeActiveGoalSnapshot(); - - driver.handleUserInput('/skill:review check this /skill:security'); - - expect(session.promptWithSkills).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - expect.objectContaining({ - text: '/skill:review check this /skill:security', - inlineSkillActivations: [{ skillName: 'review' }, { skillName: 'security' }], - }), - ]); - }); - - it('does not append a user entry when the grouped submission is rejected (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - promptWithSkills: vi.fn(async () => { - throw new Error('Skill "review" was not found'); - }), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('please /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalled(); - }); - await vi.waitFor(() => { - expect(driver.state.appState.streamingPhase).toBe('idle'); - }); - // A rejected group leaves no local undo anchor the engine never recorded. - expect(driver.state.transcriptEntries.filter((entry) => entry.kind === 'user')).toHaveLength(0); - }); - - it('renders a bundled replay submission as a single turn', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver(session, {}, startupInput); - (session.getResumeState as ReturnType<typeof vi.fn>).mockReturnValue({ - sessionMetadata: {}, - agents: { - main: { - config: { modelCapabilities: { max_context_tokens: 100 }, modelAlias: 'k2' }, - plan: null, - permission: { mode: 'manual' }, - swarmMode: false, - context: { history: [], tokenCount: 0 }, - background: [], - toolStore: {}, - replay: [ - { - type: 'message', - time: 1, - message: { - role: 'user', - content: [{ type: 'text', text: 'earlier question' }], - toolCalls: [], - origin: { kind: 'user' }, - }, - }, - { - type: 'message', - time: 2, - message: { - role: 'assistant', - content: [{ type: 'text', text: 'earlier answer' }], - toolCalls: [], - }, - }, - { - type: 'message', - time: 3, - message: { - role: 'user', - content: [{ type: 'text', text: 'hook note' }], - toolCalls: [], - origin: { kind: 'hook_result', event: 'UserPromptSubmit' }, - }, - }, - { - type: 'message', - time: 4, - message: { - role: 'user', - content: [ - { type: 'text', text: 'skill card A body' }, - { type: 'text', text: 'skill card B body' }, - { type: 'text', text: 'please /skill:review and /skill:security' }, - ], - toolCalls: [], - origin: { - kind: 'user', - skillActivations: [ - { activationId: 'act-1', skillName: 'review' }, - { activationId: 'act-2', skillName: 'security' }, - ], - }, - }, - }, - { - type: 'message', - time: 5, - message: { - role: 'assistant', - content: [{ type: 'text', text: 'bundled answer' }], - toolCalls: [], - }, - }, - { - type: 'message', - time: 6, - message: { - role: 'user', - content: [ - { type: 'text', text: 'skill card C body' }, - { type: 'text', text: 'please /commit' }, - ], - toolCalls: [], - origin: { - kind: 'user', - skillActivations: [{ activationId: 'act-3', skillName: 'commit' }], - }, - }, - }, - ], - }, - }, - }); - - const replayed = await driver.sessionReplay.hydrateFromReplay(session as unknown as Session); - expect(replayed).toBe(true); - - const turns = groupTurns(driver.state.transcriptEntries); - expect(turns).toHaveLength(3); - // The hook result is projected inside the bundle's window (after the - // skill cards, before the prompt), matching the live event order. - expect(turns[1]!.entries.map((entry) => entry.kind)).toEqual([ - 'skill_activation', - 'skill_activation', - 'assistant', - 'user', - 'assistant', - ]); - expect(turns[1]!.entries[2]!.hookResult).toBe(true); - // The user entry shows only the caller's own text — the rendered skill - // blocks the engine prepended to the content are stripped. - expect(turns[1]!.entries[3]!.content).toBe('please /skill:review and /skill:security'); - expect( - turns[1]!.entries.slice(0, 2).map((entry) => entry.bundledWithPrompt), - ).toEqual([true, true]); - expect(turns[2]!.entries.map((entry) => entry.kind)).toEqual(['skill_activation', 'user']); - expect(turns[2]!.entries[1]!.content).toBe('please /commit'); - }); - - it('keeps hook results recorded before the oldest retained bundle within the replay limit', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver(session, {}, startupInput); - const plainTurn = (index: number) => [ - { - type: 'message', - time: index * 2, - message: { - role: 'user', - content: [{ type: 'text', text: `question ${index}` }], - toolCalls: [], - origin: { kind: 'user' }, - }, - }, - { - type: 'message', - time: index * 2 + 1, - message: { - role: 'assistant', - content: [{ type: 'text', text: `answer ${index}` }], - toolCalls: [], - }, - }, - ]; - (session.getResumeState as ReturnType<typeof vi.fn>).mockReturnValue({ - sessionMetadata: {}, - agents: { - main: { - config: { modelCapabilities: { max_context_tokens: 100 }, modelAlias: 'k2' }, - plan: null, - permission: { mode: 'manual' }, - swarmMode: false, - context: { history: [], tokenCount: 0 }, - background: [], - toolStore: {}, - replay: [ - ...plainTurn(0), - { - type: 'message', - time: 1, - message: { - role: 'user', - content: [{ type: 'text', text: 'hook note' }], - toolCalls: [], - origin: { kind: 'hook_result', event: 'UserPromptSubmit' }, - }, - }, - { - type: 'message', - time: 2, - message: { - role: 'user', - content: [ - { type: 'text', text: 'review body' }, - { type: 'text', text: 'bundled question' }, - ], - toolCalls: [], - origin: { - kind: 'user', - skillActivations: [{ activationId: 'act-1', skillName: 'review' }], - }, - }, - }, - { - type: 'message', - time: 3, - message: { - role: 'assistant', - content: [{ type: 'text', text: 'bundled answer' }], - toolCalls: [], - }, - }, - ...Array.from({ length: 9 }, (_, i) => plainTurn(i + 10)).flat(), - ], - }, - }, - }); - - const replayed = await driver.sessionReplay.hydrateFromReplay(session as unknown as Session); - expect(replayed).toBe(true); - - const entries = driver.state.transcriptEntries; - const hookIndex = entries.findIndex((entry) => entry.hookResult === true); - expect(hookIndex).toBeGreaterThan(-1); - expect(entries[hookIndex]!.content).toContain('hook note'); - const contents = entries.map((entry) => entry.content); - expect(contents.indexOf('Activated skill: review')).toBeLessThan(hookIndex); - expect(contents.indexOf('bundled question')).toBeGreaterThan(hookIndex); - expect(contents).not.toContain('question 0'); - }); - - it('appends the user entry after the skill cards for a bundled submission (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - // Hold the RPC open so the skill.activated event can land mid-flight, - // exactly how the in-process wiring delivers it during the call. - let release!: () => void; - const heldPrompt = new Promise<void>((resolve) => { - release = resolve; - }); - (session.promptWithSkills as ReturnType<typeof vi.fn>).mockReturnValue(heldPrompt); - - driver.handleUserInput('please /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalled(); - }); - driver.sessionEventHandler.handleEvent( - { - type: 'skill.activated', - sessionId: 'ses-lazy', - agentId: 'main', - activationId: 'act-1', - skillName: 'review', - trigger: 'user-slash', - } as Event, - () => {}, - ); - release(); - - await vi.waitFor(() => { - expect(driver.state.transcriptEntries.map((entry) => entry.kind)).toEqual([ - 'skill_activation', - 'user', - ]); - }); - expect(driver.state.transcriptEntries[0]!.bundledWithPrompt).toBe(true); - }); - it('serializes concurrent lazy session creation (v2 engine)', async () => { const session = makeSession({ id: 'ses-lazy' }); const startupInput: KimiTUIStartupInput = { @@ -1339,7 +677,7 @@ describe('KimiTUI message flow', () => { // The prompt continuation starts its turn first; /new (idle-only) must // then be blocked instead of switching away from the active session. await vi.waitFor(() => { - expect(lazySession.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(lazySession.prompt).toHaveBeenCalledWith('hello'); expect(stripSgr(renderTranscript(driver))).toContain('Cannot /new while streaming'); }); expect(harness.createSession).toHaveBeenCalledTimes(1); @@ -1391,7 +729,7 @@ describe('KimiTUI message flow', () => { // The prompt starts its turn first; the switch must then be rejected // instead of being silently overwritten by the session assembly. await vi.waitFor(() => { - expect(lazySession.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(lazySession.prompt).toHaveBeenCalledWith('hello'); expect(stripSgr(renderTranscript(driver))).toContain('Cannot switch models while streaming'); }); expect(lazySession.setThinking).not.toHaveBeenCalled(); @@ -1474,7 +812,7 @@ describe('KimiTUI message flow', () => { // The prompt starts its turn first; the switch must then be rejected // instead of being overwritten when the lazy creation completes. await vi.waitFor(() => { - expect(lazySession.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(lazySession.prompt).toHaveBeenCalledWith('hello'); expect(stripSgr(renderTranscript(driver))).toContain('Cannot switch sessions while streaming'); }); expect(harness.resumeSession).not.toHaveBeenCalled(); @@ -1500,7 +838,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); expect(harness.createSession).toHaveBeenCalledWith( expect.objectContaining({ model: 'k2', thinking: 'high' }), @@ -1535,7 +873,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); expect(harness.createSession).toHaveBeenCalledWith( expect.objectContaining({ planMode: undefined }), @@ -1554,7 +892,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); expect(harness.createSession).toHaveBeenCalledWith( expect.objectContaining({ planMode: true }), @@ -1578,7 +916,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('ls'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); // The shell command must be queued, not run concurrently with the prompt. expect(runShellCommand).not.toHaveBeenCalled(); @@ -1635,7 +973,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('/skill:my-skill'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); // The skill activation must be blocked, not run concurrently with the // prompt's turn. @@ -1925,7 +1263,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); // The engine applies the config default at create; repeating --plan would // re-enter plan mode and throw, so it must not be passed again. @@ -1974,7 +1312,7 @@ describe('KimiTUI message flow', () => { driver.handleUserInput('hello'); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); }); expect(harness.createSession).toHaveBeenCalledWith( expect.objectContaining({ permission: 'yolo' }), @@ -2762,7 +2100,7 @@ command = "vim" driver.handleUserInput('hello'); - expect(session.prompt).toHaveBeenCalledWith('hello', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('hello'); expect(driver.state.appState.streamingPhase).not.toBe('idle'); expect(driver.state.appState.streamingPhase).toBe('waiting'); expect(driver.state.livePane.mode).toBe('waiting'); @@ -3156,87 +2494,62 @@ command = "vim" expect(transcript).not.toContain('review'); }); - it('deletes a pasted video’s daemon upload when the consuming turn ends', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); + it('sends a pasted video as a file:// video_url part', async () => { + const { driver, session } = await makeDriver(); const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addVideo('video/mp4', '/tmp/clip.mp4'); - imageStore.completeVideo(attachment, { fileId: 'file-v1' }); + const dir = await mkdtemp(join(tmpdir(), 'tui-video-')); + try { + const srcVideo = join(dir, 'clip.mp4'); + await writeFile(srcVideo, 'video-bytes'); + const attachment = imageStore.addVideo('video/mp4', srcVideo); - // The paste was uploaded to the daemon file store, so the submission - // carries a bare `kimi-file://` reference — no local cache copy. - driver.handleUserInput(`watch ${attachment.placeholder}`); + // Submission is fully synchronous: the paste is copied to the cache and + // referenced by a `file://` video_url the engine resolves in-turn. + driver.handleUserInput(`watch ${attachment.placeholder}`); - const parts = vi.mocked(session.prompt).mock.calls[0]?.[0] as - | Array<{ - type: string; - text?: string; - videoUrl?: { url: string }; - }> - | undefined; - expect(parts?.[0]).toEqual({ type: 'text', text: 'watch ' }); - expect(parts?.[1]).toEqual({ type: 'video_url', videoUrl: { url: 'kimi-file://file-v1' } }); - expect(harness.deleteFile).not.toHaveBeenCalled(); - - emitTurn(driver, 1); - - // The engine materialized its own session copy at intake, so the staged - // upload is garbage once the consuming turn ends. - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-v1'); - }); - expect(attachment.fileId).toBeUndefined(); + const parts = vi.mocked(session.prompt).mock.calls[0]?.[0] as + | Array<{ + type: string; + text?: string; + videoUrl?: { url: string }; + }> + | undefined; + expect(parts?.[0]).toEqual({ type: 'text', text: 'watch ' }); + expect(parts?.[1]?.type).toBe('video_url'); + expect(parts?.[1]?.videoUrl?.url).toMatch(/^file:\/\/.*clip\.mp4$/); + } finally { + await rm(dir, { recursive: true, force: true }); + } }); - it('queues a pasted video (kimi-file part) while a turn is streaming', async () => { + it('queues a pasted video (file:// part) while a turn is streaming', async () => { const session = makeSession(); const { driver } = await makeDriver(session); const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addVideo('video/mp4', '/tmp/clip.mp4'); - imageStore.completeVideo(attachment, { fileId: 'file-v1' }); - driver.state.appState.streamingPhase = 'waiting'; + const dir = await mkdtemp(join(tmpdir(), 'tui-video-')); + try { + const srcVideo = join(dir, 'clip.mp4'); + await writeFile(srcVideo, 'video-bytes'); + const attachment = imageStore.addVideo('video/mp4', srcVideo); + driver.state.appState.streamingPhase = 'waiting'; - driver.handleUserInput(`describe ${attachment.placeholder}`); + driver.handleUserInput(`describe ${attachment.placeholder}`); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toHaveLength(1); - const queued = driver.state.queuedMessages[0]; - const parts = queued?.parts as Array<{ type: string; text?: string; videoUrl?: { url: string } }>; - expect(parts?.[0]).toEqual({ type: 'text', text: 'describe ' }); - expect(parts?.[1]).toEqual({ type: 'video_url', videoUrl: { url: 'kimi-file://file-v1' } }); - expect(queued?.videoAttachmentIds).toEqual([attachment.id]); + expect(session.prompt).not.toHaveBeenCalled(); + expect(driver.state.queuedMessages).toHaveLength(1); + const queued = driver.state.queuedMessages[0]; + const parts = queued?.parts as Array<{ type: string; text?: string; videoUrl?: { url: string } }>; + expect(parts?.[0]).toEqual({ type: 'text', text: 'describe ' }); + expect(parts?.[1]?.type).toBe('video_url'); + expect(parts?.[1]?.videoUrl?.url).toMatch(/^file:\/\/.*clip\.mp4$/); - driver.sendQueuedMessage(session, queued!); - expect(vi.mocked(session.prompt).mock.calls[0]?.[0]).toEqual(parts); + driver.sendQueuedMessage(session, queued!); + expect(session.prompt).toHaveBeenCalledWith(parts); + } finally { + await rm(dir, { recursive: true, force: true }); + } }); - it('falls back to retained bytes when a queued image upload expires before dispatch', async () => { - const session = makeSession(); - const { driver } = await makeDriver(session); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addImage( - new Uint8Array([0xaa, 0xbb]), - 'image/png', - 1, - 1, - undefined, - 'file-expired', - 1, - ); - - driver.sendQueuedMessage(session, { - text: `describe ${attachment.placeholder}`, - parts: [ - { type: 'image_url', imageUrl: { url: 'kimi-file://file-expired' } }, - ], - imageAttachmentIds: [attachment.id], - }); - - expect(session.prompt).toHaveBeenCalledWith( - [{ type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }], - { promptId: expect.any(String) }, - ); - }); it('sends pasted image placeholders as image content parts', async () => { const { driver, session } = await makeDriver(); @@ -3245,15 +2558,10 @@ command = "vim" driver.handleUserInput(`describe ${attachment.placeholder}`); - expect(session.prompt).toHaveBeenCalledWith( - [ - { type: 'text', text: 'describe ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }, - ], - // Staged media rides with a client-chosen prompt id so the consuming - // turn's `turn.started` can bind the lease exactly. - { promptId: expect.any(String) }, - ); + expect(session.prompt).toHaveBeenCalledWith([ + { type: 'text', text: 'describe ' }, + { type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }, + ]); expect(driver.state.transcriptEntries).toEqual([ expect.objectContaining({ kind: 'user', @@ -3263,218 +2571,6 @@ command = "vim" ]); }); - it('keeps an image staging upload until the consuming turn ends', async () => { - const { driver, session, harness } = await makeDriver(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-1'); - - driver.handleUserInput(attachment.placeholder); - - expect(session.prompt).toHaveBeenCalledOnce(); - emitTurn(driver, 1, () => { - expect(harness.deleteFile).not.toHaveBeenCalled(); - }); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-1'); - }); - expect(attachment.fileId).toBeUndefined(); - expect(attachment.bytes).toEqual(new Uint8Array([0xaa, 0xbb])); - }); - - it('keeps an image staging upload across lazy session creation (v2 engine)', async () => { - const session = makeSession({ id: 'ses-lazy' }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver, harness } = await makeDriver(session, {}, startupInput); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-lazy'); - - driver.handleUserInput(attachment.placeholder); - - // The lease is created at extraction, before the session exists: lazy - // creation runs setSession mid-dispatch, and the first prompt's lease - // must survive it — the engine's intake only reads the upload once the - // prompt lands. - await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith( - [{ type: 'image_url', imageUrl: { url: 'kimi-file://file-lazy' } }], - { promptId: expect.any(String) }, - ); - }); - expect(harness.deleteFile).not.toHaveBeenCalled(); - emitTurn(driver, 1, () => { - expect(harness.deleteFile).not.toHaveBeenCalled(); - }); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-lazy'); - }); - }); - - it('still deletes the staging upload when a cache-hint dismissal precedes the resend', async () => { - const { driver, session, harness } = await makeDriver(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-dismissed'); - const text = `describe ${attachment.placeholder}`; - - // Simulate a cache-hint interception dismissed back into the editor: the - // submit's extraction is stashed, then restored with recall semantics - // (retain consumed, staged upload kept for the restored draft). - const extraction = extractMediaAttachments(text, imageStore); - driver.recallStashedMedia(extraction); - - // The restored draft resubmits and re-retains; the consuming turn must - // still delete the daemon upload — a retain leaked by the dismissal would - // keep the count above zero and pin the upload until its TTL. - driver.handleUserInput(text); - - expect(session.prompt).toHaveBeenCalledOnce(); - emitTurn(driver, 1, () => { - expect(harness.deleteFile).not.toHaveBeenCalled(); - }); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-dismissed'); - }); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - }); - - it('waits briefly for a pending paste ingestion so the submit uses the daemon-ref form', async () => { - const { driver, session } = await makeDriver(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addImage(new Uint8Array([0xaa, 0xbb]), 'image/png', 1, 1); - // Simulate a paste whose background ingestion is still uploading when the - // user hits Enter: the send path waits for it instead of dispatching the - // inline fallback. - let finishIngestion!: () => void; - attachment.pending = new Promise<void>((resolve) => { - finishIngestion = () => { - attachment.fileId = 'file-late'; - attachment.fileExpiresAt = Date.now() + 60 * 60 * 1000; - attachment.pending = undefined; - resolve(); - }; - }); - - driver.handleUserInput(`describe ${attachment.placeholder}`); - expect(session.prompt).not.toHaveBeenCalled(); - - finishIngestion(); - await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith( - [ - { type: 'text', text: 'describe ' }, - { type: 'image_url', imageUrl: { url: 'kimi-file://file-late' } }, - ], - { promptId: expect.any(String) }, - ); - }); - }); - - it('releases staged media exactly once when the prompt dispatch rejects', async () => { - const session = makeSession({ - prompt: vi.fn(async () => { - throw new Error('session closed'); - }), - }); - const { driver, harness } = await makeDriver(session); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-reject'); - - driver.handleUserInput(attachment.placeholder); - - await vi.waitFor(() => { - expect(driver.state.appState.streamingPhase).toBe('idle'); - }); - expect(stripSgr(renderTranscript(driver))).toContain('Failed to send: session closed'); - expect(harness.deleteFile).toHaveBeenCalledWith('file-reject'); - - // The released lease must not be claimed or deleted again by later turn - // events or by session close. - emitTurn(driver, 1); - await driver.closeSession('test'); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - }); - - it('releases goal-steered staging media when the running goal turn ends', async () => { - const { driver, session, harness } = await makeDriver(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-goal'); - // The goal driver's continuation turn (origin system_trigger — it never - // claims leases through handleTurnStarted) is streaming when the queued - // steer dispatch lands. - driver.state.appState.goal = makeActiveGoalSnapshot(); - driver.state.appState.streamingPhase = 'waiting'; - driver.streamingUI.setTurnId('7'); - - driver.sendQueuedMessage(session, { - text: attachment.placeholder, - agentId: 'main', - parts: [{ type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }], - imageAttachmentIds: [attachment.id], - }); - - expect(session.steer).toHaveBeenCalledOnce(); - expect(harness.deleteFile).not.toHaveBeenCalled(); - driver.sessionEventHandler.handleEvent( - { type: 'turn.ended', agentId: 'main', turnId: 7, reason: 'completed' } as Event, - () => {}, - ); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-goal'); - }); - expect(attachment.fileId).toBeUndefined(); - }); - - it('releases every queued use of shared media when the queue is discarded', async () => { - process.env['KIMI_CODE_HOME'] = await makeTempHome(); - const { driver, harness } = await makeDriver(); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-queued'); - driver.state.appState.streamingPhase = 'waiting'; - - driver.handleUserInput(`first ${attachment.placeholder}`); - driver.handleUserInput(`second ${attachment.placeholder}`); - expect(driver.state.queuedMessages).toHaveLength(2); - - driver.clearQueuedMessages(); - - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-queued'); - }); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - expect(attachment.fileId).toBeUndefined(); - }); - - it('does not delete shared daemon media while another turn still uses it', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); - driver.state.appState.model = 'k2'; - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-shared-turn'); - - driver.handleUserInput(`first ${attachment.placeholder}`); - driver.sessionEventHandler.handleEvent( - { type: 'turn.started', agentId: 'main', turnId: 1, origin: { kind: 'user' } } as Event, - () => {}, - ); - driver.state.appState.streamingPhase = 'waiting'; - driver.handleUserInput(`second ${attachment.placeholder}`); - driver.clearQueuedMessages(); - - await Promise.resolve(); - expect(harness.deleteFile).not.toHaveBeenCalled(); - - driver.sessionEventHandler.handleEvent( - { type: 'turn.ended', agentId: 'main', turnId: 1, reason: 'completed' } as Event, - () => {}, - ); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-shared-turn'); - }); - }); - it('queues editor input instead of prompting while a turn is already streaming', async () => { const { driver, session, harness } = await makeDriver(); driver.state.appState.streamingPhase = 'waiting'; @@ -3488,90 +2584,6 @@ command = "vim" expect(harness.track).toHaveBeenCalledWith('input_queue', undefined); }); - it('queues a slash-skill activation while a turn is streaming (like any other input) and activates on drain', async () => { - const session = makeSession({ - listSkills: vi.fn(async () => [ - { - name: 'demo', - description: 'demo skill', - path: 'builtin://demo', - source: 'builtin', - type: 'inline', - }, - ]), - }); - const { driver, harness } = await makeDriver(session); - await ( - driver as unknown as { refreshSkillCommands(s: unknown): Promise<void> } - ).refreshSkillCommands(session); - driver.state.appState.streamingPhase = 'waiting'; - harness.track.mockClear(); - - driver.handleUserInput('/demo refactor auth and ui'); - - expect(session.activateSkill).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - { - text: '/demo refactor auth and ui', - agentId: 'main', - mode: 'skill', - skillName: 'demo', - skillArgs: 'refactor auth and ui', - }, - ]); - expect(harness.track).toHaveBeenCalledWith('input_queue', undefined); - - // Turn ends: the drain re-enters sendSkillActivation, which now fires. - driver.state.appState.streamingPhase = 'idle'; - const queued = driver.state.queuedMessages[0]!; - driver.state.queuedMessages = []; - driver.sendQueuedMessage(session, queued); - - expect(session.activateSkill).toHaveBeenCalledWith('demo', 'refactor auth and ui'); - }); - - it('queues a slash-skill activation while compacting and activates it on drain', async () => { - const session = makeSession({ - listSkills: vi.fn(async () => [ - { - name: 'demo', - description: 'demo skill', - path: 'builtin://demo', - source: 'builtin', - type: 'inline', - }, - ]), - }); - const { driver, harness } = await makeDriver(session); - await ( - driver as unknown as { refreshSkillCommands(s: unknown): Promise<void> } - ).refreshSkillCommands(session); - driver.state.appState.isCompacting = true; - harness.track.mockClear(); - - driver.handleUserInput('/demo refactor auth and ui'); - - expect(session.activateSkill).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - { - text: '/demo refactor auth and ui', - agentId: 'main', - mode: 'skill', - skillName: 'demo', - skillArgs: 'refactor auth and ui', - }, - ]); - expect(driver.state.queueContainer.children.length).toBeGreaterThan(0); - expect(harness.track).toHaveBeenCalledWith('input_queue', undefined); - - driver.state.appState.isCompacting = false; - const queued = driver.state.queuedMessages[0]!; - driver.state.queuedMessages = []; - driver.sendQueuedMessage(session, queued); - - expect(session.activateSkill).toHaveBeenCalledWith('demo', 'refactor auth and ui'); - }); - it('steers fresh input while a goal is active even when the streaming phase is idle', async () => { const { driver, session } = await makeDriver(); driver.state.appState.goal = makeActiveGoalSnapshot(); @@ -3588,92 +2600,6 @@ command = "vim" ]); }); - it('steers fresh input into the running turn while tower mode is active', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - driver.state.appState.streamingPhase = 'waiting'; - - driver.handleUserInput('second objective'); - - expect(session.steer).toHaveBeenCalledWith('second objective'); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([]); - expect(driver.state.transcriptEntries).toEqual([ - expect.objectContaining({ kind: 'user', content: 'second objective' }), - ]); - }); - - it('prompts immediately while tower mode is active and the session is idle', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - - driver.handleUserInput('first objective'); - - expect(session.prompt).toHaveBeenCalledWith('first objective', { promptId: undefined }); - expect(session.steer).not.toHaveBeenCalled(); - }); - - it('queues input while tower mode is active but a foreground shell command is running', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - driver.state.appState.streamingPhase = 'shell'; - - driver.handleUserInput('objective during shell'); - - expect(session.steer).not.toHaveBeenCalled(); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - { text: 'objective during shell', agentId: 'main' }, - ]); - }); - - it('queues input while tower mode is active but compaction is running', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - driver.state.appState.streamingPhase = 'waiting'; - driver.state.appState.isCompacting = true; - - driver.handleUserInput('objective during compaction'); - - expect(session.steer).not.toHaveBeenCalled(); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - { text: 'objective during compaction', agentId: 'main' }, - ]); - }); - - it('steers the compaction backlog ahead of fresh input once compaction ends mid-turn', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - driver.state.appState.streamingPhase = 'waiting'; - driver.state.appState.isCompacting = true; - driver.handleUserInput('objective one'); - expect(driver.state.queuedMessages).toHaveLength(1); - - driver.state.appState.isCompacting = false; - driver.handleUserInput('objective two'); - - expect(session.steer).toHaveBeenCalledWith('objective one\n\nobjective two'); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([]); - }); - - it('queues fresh input behind a non-steerable backlog instead of jumping ahead', async () => { - const { driver, session } = await makeDriver(); - driver.state.appState.towerMode = true; - driver.state.appState.streamingPhase = 'waiting'; - driver.state.queuedMessages = [{ text: 'make build', agentId: 'main', mode: 'bash' }]; - - driver.handleUserInput('objective two'); - - expect(session.steer).not.toHaveBeenCalled(); - expect(session.prompt).not.toHaveBeenCalled(); - expect(driver.state.queuedMessages).toEqual([ - { text: 'make build', agentId: 'main', mode: 'bash' }, - { text: 'objective two', agentId: 'main' }, - ]); - }); - it('resets the streaming phase when steering mid-goal input fails', async () => { const session = makeSession({ steer: vi.fn(async () => { @@ -3738,7 +2664,7 @@ command = "vim" ); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('after the turn', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('after the turn'); }); expect(session.steer).not.toHaveBeenCalled(); }); @@ -3921,15 +2847,10 @@ command = "vim" driver.sendQueuedMessage(session, queued!); - expect(session.prompt).toHaveBeenCalledWith( - [ - { type: 'text', text: 'describe ' }, - { type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }, - ], - // Staged media rides with a client-chosen prompt id so the consuming - // turn's `turn.started` can bind the lease exactly. - { promptId: expect.any(String) }, - ); + expect(session.prompt).toHaveBeenCalledWith([ + { type: 'text', text: 'describe ' }, + { type: 'image_url', imageUrl: { url: 'data:image/png;base64,qrs=' } }, + ]); }); it('steers editor image input as media parts', async () => { @@ -3979,124 +2900,6 @@ command = "vim" expect(driver.state.queuedMessages).toEqual([]); }); - it('releases every queued use of shared media after a batched steer', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); - driver.state.appState.model = 'k2'; - driver.state.appState.streamingPhase = 'waiting'; - driver.streamingUI.setTurnId('1'); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-batched'); - driver.handleUserInput(`first ${attachment.placeholder}`); - driver.handleUserInput(`second ${attachment.placeholder}`); - expect(driver.state.queuedMessages).toHaveLength(2); - - driver.state.editor.onCtrlS?.(); - - expect(session.steer).toHaveBeenCalledOnce(); - driver.sessionEventHandler.handleEvent( - { type: 'turn.ended', agentId: 'main', turnId: 1, reason: 'completed' } as Event, - () => {}, - ); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-batched'); - }); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - expect(attachment.fileId).toBeUndefined(); - expect(driver.state.queuedMessages).toEqual([]); - }); - - it('keeps a shared staged upload alive while another submission still holds it', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); - driver.state.appState.model = 'k2'; - driver.state.appState.streamingPhase = 'waiting'; - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-shared'); - - // One message referencing the same image twice retains it once; a second - // queued message retains it again — two retains total. - driver.handleUserInput(`compare ${attachment.placeholder} with ${attachment.placeholder}`); - driver.handleUserInput(`and ${attachment.placeholder}`); - const [first, second] = driver.state.queuedMessages; - - driver.sendQueuedMessage(session, first!); - emitTurn(driver, 1); - await new Promise((resolve) => setTimeout(resolve, 0)); - // The first turn consumed the only retain its submission held; the second - // queued message's retain keeps the upload alive. - expect(harness.deleteFile).not.toHaveBeenCalled(); - - driver.sendQueuedMessage(session, second!); - emitTurn(driver, 2); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-shared'); - }); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - }); - - it('keeps staged media when a queued message is recalled into the editor', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); - driver.state.appState.model = 'k2'; - driver.state.appState.streamingPhase = 'waiting'; - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = stagedImage(imageStore, 'file-recall'); - - driver.handleUserInput(`look ${attachment.placeholder}`); - expect(driver.state.queuedMessages).toHaveLength(1); - - const recalled = driver.recallLastQueued(); - expect(recalled?.text).toContain(attachment.placeholder); - await new Promise((resolve) => setTimeout(resolve, 0)); - // Recalled, not discarded: the daemon upload stays staged for the - // restored draft. - expect(harness.deleteFile).not.toHaveBeenCalled(); - expect(attachment.fileId).toBe('file-recall'); - - // Re-queueing the restored draft reuses the daemon-ref form, and the - // consuming turn's end releases the upload exactly once. - driver.handleUserInput(recalled!.text); - const requeued = driver.state.queuedMessages[0]!; - expect(requeued.parts).toContainEqual({ - type: 'image_url', - imageUrl: { url: 'kimi-file://file-recall' }, - }); - - driver.sendQueuedMessage(session, requeued); - emitTurn(driver, 1); - await vi.waitFor(() => { - expect(harness.deleteFile).toHaveBeenCalledWith('file-recall'); - }); - expect(harness.deleteFile).toHaveBeenCalledTimes(1); - }); - - it('keeps a recalled video’s daemon upload alive for the restored draft', async () => { - const session = makeSession(); - const { driver, harness } = await makeDriver(session); - const imageStore = (driver as unknown as { imageStore: ImageAttachmentStore }).imageStore; - const attachment = imageStore.addVideo('video/mp4', '/tmp/clip.mp4'); - imageStore.completeVideo(attachment, { fileId: 'file-v1' }); - driver.state.appState.streamingPhase = 'waiting'; - - driver.handleUserInput(`describe ${attachment.placeholder}`); - expect(driver.state.queuedMessages).toHaveLength(1); - - const recalled = driver.recallLastQueued(); - expect(recalled?.text).toContain(attachment.placeholder); - // The recall consumed the retain but kept the upload, so resubmitting - // the restored draft re-extracts the same daemon reference — a vanished - // original source cannot lose the media. - expect(attachment.fileId).toBe('file-v1'); - expect(harness.deleteFile).not.toHaveBeenCalled(); - - driver.handleUserInput(recalled!.text); - const queued = driver.state.queuedMessages[0]; - const parts = queued?.parts as Array<{ type: string; videoUrl?: { url: string } }>; - expect(parts?.[1]).toEqual({ type: 'video_url', videoUrl: { url: 'kimi-file://file-v1' } }); - expect(queued?.videoAttachmentIds).toEqual([attachment.id]); - }); - it('steers consecutive image-only messages without a whitespace-only separator part', async () => { const session = makeSession(); const { driver } = await makeDriver(session); @@ -4295,83 +3098,6 @@ command = "vim" expect(transcript).not.toContain('! ls'); }); - it('collapses long ! output to its first 10 rows and expands it with ctrl+o', async () => { - const stdout = Array.from({ length: 30 }, (_, i) => `row-${String(i + 1).padStart(2, '0')}`).join( - '\n', - ); - const runShellCommand = vi.fn(async () => ({ stdout, stderr: '', isError: false })); - const session = makeSession({ runShellCommand }); - const { driver } = await makeDriver(session); - driver.state.appState.inputMode = 'bash'; - driver.state.editor.inputMode = 'bash'; - - driver.handleUserInput('seq 30'); - await vi.waitFor(() => { - const transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('... (20 more lines, ctrl+o to expand)'); - }); - - let transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('row-01'); - expect(transcript).not.toContain('row-11'); - - driver.state.editor.onToggleToolExpand?.(); - transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('row-30'); - expect(transcript).not.toContain('more lines'); - - driver.state.editor.onToggleToolExpand?.(); - transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('... (20 more lines, ctrl+o to expand)'); - expect(transcript).not.toContain('row-11'); - }); - - it('a new ! card inherits an already-on ctrl+o expand state', async () => { - const stdout = Array.from({ length: 30 }, (_, i) => `row-${String(i + 1).padStart(2, '0')}`).join( - '\n', - ); - let resolveCmd!: (value: { stdout: string; stderr: string; isError: boolean }) => void; - const runShellCommand = vi.fn( - () => - new Promise<{ stdout: string; stderr: string; isError: boolean }>((resolve) => { - resolveCmd = resolve; - }), - ); - const session = makeSession({ runShellCommand }); - const { driver } = await makeDriver(session); - driver.state.toolOutputExpanded = true; - driver.state.appState.inputMode = 'bash'; - driver.state.editor.inputMode = 'bash'; - - driver.handleUserInput('seq 30'); - await Promise.resolve(); - const outputEntry = driver.state.transcriptEntries.at(-1); - expect(outputEntry).toBeDefined(); - - driver.sessionEventHandler.handleEvent( - { - type: 'shell.output', - agentId: 'main', - sessionId: 'ses-1', - commandId: outputEntry!.id, - update: { kind: 'stdout', text: stdout }, - } as Event, - vi.fn(), - ); - let transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('row-01'); - expect(transcript).not.toContain('+25 lines'); - - resolveCmd({ stdout, stderr: '', isError: false }); - await vi.waitFor(() => { - const finished = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(finished).toContain('row-30'); - }); - transcript = stripSgr(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('row-01'); - expect(transcript).not.toContain('more lines'); - }); - it('renders cron fired events as distinct transcript entries', async () => { const { driver } = await makeDriver(); @@ -4412,85 +3138,6 @@ command = "vim" expect(transcript).not.toContain('<cron-fire'); }); - it('keeps the previous turn’s final answer mounted when a cron turn completes', async () => { - const { driver } = await makeDriver(); - const emit = (event: Event) => driver.sessionEventHandler.handleEvent(event, () => {}); - let entrySeq = 0; - const entry = (kind: 'user' | 'assistant', content: string, turnId?: string) => { - entrySeq += 1; - driver.appendTranscriptEntry({ - id: `cron-fold-${entrySeq}`, - kind, - turnId, - renderMode: kind === 'assistant' ? 'markdown' : 'plain', - content, - }); - }; - - entry('user', 'what is the answer?'); - emit({ type: 'turn.started', agentId: 'main', turnId: 1, origin: { kind: 'user' } } as Event); - entry('assistant', 'working on it', '1'); - entry('assistant', 'FINAL-ANSWER', '1'); - emit({ type: 'turn.ended', agentId: 'main', turnId: 1, reason: 'completed' } as Event); - - expect(stripSgr(renderTranscript(driver))).toContain('FINAL-ANSWER'); - - const cronOrigin = { - kind: 'cron_job', - jobId: 'job-42', - cron: '*/5 * * * *', - recurring: true, - coalescedCount: 1, - stale: false, - }; - emit({ type: 'turn.started', agentId: 'main', turnId: 2, origin: cronOrigin } as Event); - emit({ type: 'cron.fired', agentId: 'main', origin: cronOrigin, prompt: 'inspect the fleet' } as Event); - entry('assistant', 'cron report part one', '2'); - entry('assistant', 'cron report final', '2'); - emit({ type: 'turn.ended', agentId: 'main', turnId: 2, reason: 'completed' } as Event); - - const transcript = stripSgr(renderTranscript(driver)); - expect(transcript).toContain('cron report final'); - expect(transcript).toContain('FINAL-ANSWER'); - }); - - it('keeps the in-flight answer mounted when a cron fires mid-turn', async () => { - const { driver } = await makeDriver(); - const emit = (event: Event) => driver.sessionEventHandler.handleEvent(event, () => {}); - let entrySeq = 0; - const entry = (kind: 'user' | 'assistant', content: string, turnId?: string) => { - entrySeq += 1; - driver.appendTranscriptEntry({ - id: `cron-buffered-${entrySeq}`, - kind, - turnId, - renderMode: kind === 'assistant' ? 'markdown' : 'plain', - content, - }); - }; - - entry('user', 'what is the answer?'); - emit({ type: 'turn.started', agentId: 'main', turnId: 1, origin: { kind: 'user' } } as Event); - entry('assistant', 'FINAL-ANSWER', '1'); - - const cronOrigin = { - kind: 'cron_job', - jobId: 'job-42', - cron: '*/5 * * * *', - recurring: true, - coalescedCount: 1, - stale: false, - }; - emit({ type: 'cron.fired', agentId: 'main', origin: cronOrigin, prompt: 'inspect the fleet' } as Event); - entry('assistant', 'cron report part one', '1'); - entry('assistant', 'cron report final', '1'); - emit({ type: 'turn.ended', agentId: 'main', turnId: 1, reason: 'completed' } as Event); - - const transcript = stripSgr(renderTranscript(driver)); - expect(transcript).toContain('FINAL-ANSWER'); - expect(transcript).toContain('cron report final'); - }); - it('coalesces assistant delta component updates', async () => { vi.useFakeTimers(); try { @@ -4855,162 +3502,6 @@ command = "vim" expect(stripSgr(renderBtwPanel(driver))).toContain('Q: What are you working on right now?'); }); - it('sends /btw panel input with inline skills via promptWithSkills (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/btw'); - await vi.waitFor(() => { - expect(session.startBtw).toHaveBeenCalledWith(); - }); - expect(stripSgr(renderBtwPanel(driver))).toContain('Ready for a side question...'); - - driver.handleUserInput('check /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith('check /skill:review', [ - { name: 'review' }, - ]); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - - it('activates inline skills in the initial /btw prompt (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/btw check this /skill:review'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith('check this /skill:review', [ - { name: 'review' }, - ]); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - - it('activates a leading skill token in the initial /btw prompt (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/btw /skill:review check this'); - - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith('/skill:review check this', [ - { name: 'review' }, - ]); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - - it('keeps /btw as the leading command when its prompt mentions multiple skills (v2 engine)', async () => { - const session = makeSession({ - id: 'ses-lazy', - listSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - }); - const startupInput: KimiTUIStartupInput = { - ...makeStartupInput(), - engineV2: true, - cliOptions: { ...makeStartupInput().cliOptions, model: 'k2' }, - }; - const { driver } = await makeDriver( - session, - { - listWorkspaceSkills: vi.fn(async () => [ - { name: 'review', description: 'Review skill', path: '/tmp/review', source: 'user' }, - { name: 'security', description: 'Security skill', path: '/tmp/security', source: 'user' }, - ]), - listPluginCommands: vi.fn(async () => []), - }, - startupInput, - ); - await ( - driver as unknown as { refreshSkillCommands(): Promise<void> } - ).refreshSkillCommands(); - - driver.handleUserInput('/btw check /skill:review /skill:security'); - - await vi.waitFor(() => { - expect(session.startBtw).toHaveBeenCalledWith(); - }); - await vi.waitFor(() => { - expect(session.promptWithSkills).toHaveBeenCalledWith('check /skill:review /skill:security', [ - { name: 'review' }, - { name: 'security' }, - ]); - }); - expect(session.prompt).not.toHaveBeenCalled(); - }); - it('cancels an unused /btw side agent when closing an empty panel', async () => { const session = makeSession(); const { driver } = await makeDriver(session); @@ -5614,32 +4105,6 @@ command = "vim" expect(driver.state.appState.thinkingEffort).toBe('mid'); }); - it('applies tower mode from status updates', async () => { - const { driver } = await makeDriver(); - - driver.sessionEventHandler.handleEvent( - { - type: 'agent.status.updated', - agentId: 'main', - sessionId: 'ses-1', - towerMode: true, - } as Event, - vi.fn(), - ); - expect(driver.state.appState.towerMode).toBe(true); - - driver.sessionEventHandler.handleEvent( - { - type: 'agent.status.updated', - agentId: 'main', - sessionId: 'ses-1', - towerMode: false, - } as Event, - vi.fn(), - ); - expect(driver.state.appState.towerMode).toBe(false); - }); - it('renders swarm mode markers from /swarm commands, not tool-triggered status updates', async () => { const { driver } = await makeDriver(); @@ -5741,7 +4206,7 @@ command = "vim" resolveInit?.(); await vi.waitFor(() => { - expect(session.prompt).toHaveBeenCalledWith('apply after init', { promptId: undefined }); + expect(session.prompt).toHaveBeenCalledWith('apply after init'); }); expect(driver.state.queuedMessages).toEqual([]); }); @@ -7181,7 +5646,7 @@ command = "vim" 'https://code.kimi.com/kimi-code/plugins/official/kimi-datasource.zip', ); }); - expect(globalThis.fetch).toHaveBeenCalledWith(kimiCodePluginMarketplaceUrl()); + expect(globalThis.fetch).toHaveBeenCalledWith(KIMI_CODE_PLUGIN_MARKETPLACE_URL); } finally { vi.stubGlobal('fetch', originalFetch); } @@ -7720,110 +6185,6 @@ command = "vim" }); }); - it('persists max when the model default effort is max', async () => { - let switched = false; - const session = makeSession({ - getStatus: vi.fn(async () => ({ - model: 'k2', - thinkingEffort: switched ? 'max' : 'high', - permission: 'manual', - planMode: false, - contextTokens: 0, - maxContextTokens: 100, - contextUsage: 0, - })), - setThinking: vi.fn(async () => { - switched = true; - }), - }); - const setConfig = vi.fn(async () => ({ providers: {} })); - const { driver } = await makeDriver(session, { - getConfig: vi.fn(async () => ({ - models: { - k2: { - provider: 'managed:kimi-code', - model: 'kimi-k2', - maxContextSize: 100, - displayName: 'Kimi K2', - capabilities: ['thinking'], - supportEfforts: ['low', 'high', 'max'], - defaultEffort: 'max', - }, - }, - defaultModel: 'k2', - // A previously stored effort keeps the runtime below the delivered - // max default, so picking max is an explicit change. - thinking: { enabled: true, effort: 'high' }, - })), - setConfig, - }); - - driver.handleUserInput('/effort max'); - - await vi.waitFor(() => { - expect(session.setThinking).toHaveBeenCalledWith('max'); - }); - await vi.waitFor(() => { - expect(setConfig).toHaveBeenCalledWith({ - defaultModel: 'k2', - thinking: { enabled: true, effort: 'max' }, - }); - }); - expect(driver.state.appState.thinkingEffort).toBe('max'); - }); - - it('keeps an xhigh pick session-only for a Claude model via the profile inference', async () => { - // claude-opus-4-7 declares no efforts; the Anthropic profile inference - // supplies [low, medium, high, xhigh, max] and resolves the default to - // 'high', so an xhigh pick ranks above the persistence ceiling. - let switched = false; - const session = makeSession({ - getStatus: vi.fn(async () => ({ - model: 'opus', - thinkingEffort: switched ? 'xhigh' : 'high', - permission: 'manual', - planMode: false, - contextTokens: 0, - maxContextTokens: 100, - contextUsage: 0, - })), - setThinking: vi.fn(async () => { - switched = true; - }), - }); - const setConfig = vi.fn(async () => ({ providers: {} })); - const { driver } = await makeDriver(session, { - getConfig: vi.fn(async () => ({ - providers: { - compatible: { type: 'anthropic', apiKey: 'test-key' }, - }, - models: { - opus: { - provider: 'compatible', - model: 'claude-opus-4-7', - maxContextSize: 100, - }, - }, - defaultModel: 'opus', - thinking: { enabled: true, effort: 'high' }, - })), - setConfig, - }); - - driver.handleUserInput('/effort xhigh'); - - await vi.waitFor(() => { - expect(session.setThinking).toHaveBeenCalledWith('xhigh'); - }); - await vi.waitFor(() => { - expect(setConfig).toHaveBeenCalledWith({ - defaultModel: 'opus', - thinking: { enabled: true }, - }); - }); - expect(driver.state.appState.thinkingEffort).toBe('xhigh'); - }); - it('refreshes only OAuth provider models before opening /model picker', async () => { const { driver } = await makeDriver(makeSession(), { getConfig: vi.fn(async () => ({ @@ -8020,14 +6381,6 @@ command = "vim" 'Session forked (ses-fork). Still in the original session; switch to the fork via /sessions.', ); }); - expect(copyTextToClipboard).toHaveBeenCalledWith( - "cd '/tmp/proj-a' && kimi --resume 'ses-fork'", - ); - const transcript = driver.state.transcriptContainer.render(120).join('\n'); - expect(transcript).toContain( - "To enter the fork in a new process, run: cd '/tmp/proj-a' && kimi --resume 'ses-fork'", - ); - expect(transcript).toContain('Command copied to clipboard'); expect(driver.getCurrentSessionId()).toBe('ses-source'); expect(source.close).not.toHaveBeenCalled(); expect(forked.close).toHaveBeenCalledOnce(); @@ -8040,70 +6393,6 @@ command = "vim" } }); - it('still prints the fork resume command when the clipboard copy fails', async () => { - vi.mocked(copyTextToClipboard).mockRejectedValueOnce(new Error('no clipboard')); - const source = makeSession({ id: 'ses-source' }); - const forked = makeSession({ id: 'ses-fork' }); - const forkSession = vi.fn(async () => forked); - const { driver } = await makeDriver(source, { forkSession }); - - driver.handleUserInput('/fork'); - - await vi.waitFor(() => { - const transcript = driver.state.transcriptContainer.render(120).join('\n'); - expect(transcript).toContain( - "To enter the fork in a new process, run: cd '/tmp/proj-a' && kimi --resume 'ses-fork'", - ); - expect(transcript).toContain('Failed to copy command to clipboard'); - }); - expect(driver.getCurrentSessionId()).toBe('ses-source'); - }); - - it('labels OSC 52 clipboard delivery as unverified after a fork', async () => { - vi.mocked(copyTextToClipboard).mockResolvedValueOnce('osc52'); - const source = makeSession({ id: 'ses-source' }); - const forked = makeSession({ id: 'ses-fork' }); - const forkSession = vi.fn(async () => forked); - const { driver } = await makeDriver(source, { forkSession }); - - driver.handleUserInput('/fork'); - - await vi.waitFor(() => { - expect(driver.state.transcriptContainer.render(120).join('\n')).toContain( - 'Command copied via terminal escape sequence (unverified)', - ); - }); - expect(driver.getCurrentSessionId()).toBe('ses-source'); - }); - - it('prints a pushd-based fork resume command on Windows', async () => { - const platformDescriptor = Object.getOwnPropertyDescriptor(process, 'platform'); - Object.defineProperty(process, 'platform', { value: 'win32' }); - try { - const source = makeSession({ id: 'ses-source' }); - const forked = makeSession({ id: 'ses-fork' }); - const forkSession = vi.fn(async () => forked); - const { driver } = await makeDriver(source, { forkSession }, { - ...makeStartupInput(), - workDir: 'D:\\proj', - }); - - driver.handleUserInput('/fork'); - - // cmd.exe's `cd` does not switch drives; pushd works in cmd + PowerShell. - await vi.waitFor(() => { - expect(copyTextToClipboard).toHaveBeenCalledWith( - 'pushd "D:\\proj" && kimi --resume "ses-fork"', - ); - }); - expect(driver.getCurrentSessionId()).toBe('ses-source'); - } finally { - if (platformDescriptor !== undefined) { - Object.defineProperty(process, 'platform', platformDescriptor); - } - } - }); - it('keeps the current session when fork fails', async () => { const forkSession = vi.fn(async () => { throw new Error('fork unavailable'); diff --git a/apps/kimi-code/test/tui/kimi-tui-startup.test.ts b/apps/kimi-code/test/tui/kimi-tui-startup.test.ts index 0aea0a76d..a621fdaba 100644 --- a/apps/kimi-code/test/tui/kimi-tui-startup.test.ts +++ b/apps/kimi-code/test/tui/kimi-tui-startup.test.ts @@ -13,7 +13,7 @@ import { promptPlatformSelection, promptLogoutProviderSelection } from '#/tui/co import { BannerComponent } from '#/tui/components/chrome/banner'; import { WelcomeComponent } from '#/tui/components/chrome/welcome'; import { KimiTUI, type KimiTUIStartupInput, type TUIState } from '#/tui/kimi-tui'; -import { REPLAY_FETCH_TURN_LIMIT } from '#/tui/utils/message-replay'; +import { REPLAY_TURN_LIMIT } from '#/tui/utils/message-replay'; import { copyTextToClipboard } from '#/utils/clipboard/clipboard-text'; import { quoteShellArg } from '#/utils/shell-quote'; import { @@ -326,24 +326,6 @@ describe('KimiTUI startup', () => { }); }); - it('mounts the docked fullscreen layout when KIMI_CODE_TUI_FULL_SCREEN=1', async () => { - const harness = makeHarness(makeSession()); - vi.stubEnv('KIMI_CODE_TUI_FULL_SCREEN', '1'); - const driver = makeDriver(harness, { ...makeStartupInput(), engineV2: true }); - vi.unstubAllEnvs(); - - // buildLayout() runs in the constructor: fullscreen keeps the root - // children list empty and mounts the layout root instead. - expect(driver.state.ui.mode).toBe('fullscreen'); - expect(driver.state.ui.children).toHaveLength(0); - - await expect(driver.init()).resolves.toBe(false); - (driver as unknown as { mountFooter(): void }).mountFooter(); - - // Dock = 5 chrome containers + footer wrap, below the transcript viewport. - expect(driver.state.dockContainer?.children).toHaveLength(6); - }); - it('shows a session-less notice on v2 startup', async () => { const harness = makeHarness(makeSession()); const driver = makeDriver(harness, { ...makeStartupInput(), engineV2: true }); @@ -560,7 +542,7 @@ describe('KimiTUI startup', () => { expect(harness.resumeSession).toHaveBeenCalledWith({ id: 'ses-latest', - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); expect(harness.createSession).not.toHaveBeenCalled(); expect(driver.state.startupState).toBe('ready'); @@ -1904,33 +1886,21 @@ describe('KimiTUI startup', () => { } }); - it('tracks logout while preserving the active session model', async () => { - let loggedOut = false; + it('tracks logout after managed credentials and session state are cleared', async () => { const session = makeSession(); - const logout = vi.fn(async () => { - loggedOut = true; - }); const harness = makeHarness(session, { - getConfig: vi.fn(async () => - loggedOut - ? { models: {}, providers: {} } - : { - models: { - k2: { - provider: 'managed:kimi-code', - model: 'moonshot-v1', - maxContextSize: 100, - }, - }, - providers: { 'managed:kimi-code': { type: 'kimi' } }, - }, - ), + getConfig: vi.fn(async () => ({ + models: { + k2: { provider: 'managed:kimi-code', model: 'moonshot-v1', maxContextSize: 100 }, + }, + providers: { 'managed:kimi-code': { type: 'kimi' } }, + })), auth: { status: vi.fn(async () => ({ providers: [{ providerName: 'managed:kimi-code', hasToken: true }], })), login: vi.fn(async () => {}), - logout, + logout: vi.fn(), getManagedUsage: vi.fn(), }, }); @@ -1943,66 +1913,13 @@ describe('KimiTUI startup', () => { await handleLogoutCommand(driver as any); expect(harness.auth.logout).toHaveBeenCalledWith('managed:kimi-code'); - expect(session.close).not.toHaveBeenCalled(); - expect(driver.state.appState).toMatchObject({ - sessionId: 'ses-1', - model: 'k2', - sessionTitle: 'Session title', - contextTokens: 10, - maxContextTokens: 100, - availableModels: {}, - availableProviders: {}, - }); - expect(harness.track).toHaveBeenCalledWith('logout', { provider: 'managed:kimi-code' }); - }); - - it('clears the config-derived model when logging out without an active session', async () => { - let loggedOut = false; - const logout = vi.fn(async () => { - loggedOut = true; - }); - const harness = makeHarness(makeSession(), { - getConfig: vi.fn(async () => - loggedOut - ? { models: {}, providers: {} } - : { - models: { - k2: { - provider: 'managed:kimi-code', - model: 'moonshot-v1', - maxContextSize: 100, - }, - }, - providers: { 'managed:kimi-code': { type: 'kimi' } }, - defaultModel: 'k2', - }, - ), - auth: { - status: vi.fn(async () => ({ - providers: [{ providerName: 'managed:kimi-code', hasToken: true }], - })), - login: vi.fn(async () => {}), - logout, - getManagedUsage: vi.fn(), - }, - }); - const driver = makeDriver(harness, { ...makeStartupInput(), engineV2: true }); - - await expect(driver.init()).resolves.toBe(false); - expect(driver.state.appState.model).toBe('k2'); - - vi.mocked(promptLogoutProviderSelection).mockResolvedValue('managed:kimi-code'); - await handleLogoutCommand(driver as any); - - expect(harness.createSession).not.toHaveBeenCalled(); + expect(session.close).toHaveBeenCalledOnce(); expect(driver.state.appState).toMatchObject({ sessionId: '', model: '', - contextTokens: 0, - maxContextTokens: 0, - availableModels: {}, - availableProviders: {}, + sessionTitle: null, }); + expect(harness.track).toHaveBeenCalledWith('logout', { provider: 'managed:kimi-code' }); }); it('keeps the active session when logging out a different provider', async () => { @@ -2089,7 +2006,7 @@ describe('KimiTUI startup', () => { expect(harness.resumeSession).toHaveBeenCalledWith({ id: 'ses-latest', - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); expect(harness.createSession).not.toHaveBeenCalled(); expect(driver.state.startupState).toBe('ready'); @@ -2109,7 +2026,7 @@ describe('KimiTUI startup', () => { expect(harness.resumeSession).toHaveBeenCalledWith({ id: 'ses-target', - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); expect(driver.state.startupState).toBe('ready'); expect(driver.state.appState.sessionId).toBe(''); @@ -2168,7 +2085,7 @@ describe('KimiTUI startup', () => { // later startup steps spawned child processes in an untrusted directory. const getWorkspaceTrustInfo = vi.fn(async () => ({ trusted: true, - gatedMcpServers: [], + gatedMcpServers: [] as string[], })); const harness = makeHarness(makeSession(), { getWorkspaceTrustInfo }); const driver = makeDriver(harness, { @@ -2198,7 +2115,7 @@ describe('KimiTUI startup', () => { it('prompts for workspace trust before migrating an untrusted workspace', async () => { const getWorkspaceTrustInfo = vi.fn(async () => ({ trusted: false, - gatedMcpServers: [], + gatedMcpServers: [] as string[], })); const trustWorkspace = vi.fn(async () => {}); const harness = makeHarness(makeSession(), { getWorkspaceTrustInfo, trustWorkspace }); @@ -2224,8 +2141,7 @@ describe('KimiTUI startup', () => { await vi.waitFor(() => { expect(mountSpy).toHaveBeenCalled(); }); - // Move from the safe default to the explicit trust choice, then confirm. - mountSpy.mock.calls[0]![0].handleInput('\u001B[A'); + // Choose the default "Trust this folder" option with Enter. mountSpy.mock.calls[0]![0].handleInput('\r'); await startPromise; @@ -2440,7 +2356,7 @@ describe('KimiTUI startup', () => { }); expect(harness.resumeSession).toHaveBeenCalledWith({ id: 'ses-target', - replayTurnLimit: REPLAY_FETCH_TURN_LIMIT, + replayTurnLimit: REPLAY_TURN_LIMIT, }); expect(driver.state.appState.sessionId).toBe('ses-target'); }); diff --git a/apps/kimi-code/test/tui/media-url.test.ts b/apps/kimi-code/test/tui/media-url.test.ts index c13ae0103..79c73b9f9 100644 --- a/apps/kimi-code/test/tui/media-url.test.ts +++ b/apps/kimi-code/test/tui/media-url.test.ts @@ -9,15 +9,6 @@ describe('mediaUrlPartToText', () => { ); }); - it('renders an internal daemon file reference as a bare placeholder', () => { - // `kimi-file://…?path=…` resolves nowhere for the user and carries the - // materialization path — never render the wire form. - expect( - mediaUrlPartToText('image', 'kimi-file://f_1?path=%2FUsers%2Falice%2Fmedia%2Ff_1.png'), - ).toBe('[image]'); - expect(mediaUrlPartToText('video', 'kimi-file://f_2')).toBe('[video]'); - }); - it('summarizes base64 data URLs without returning the payload', () => { expect(mediaUrlPartToText('image', 'data:image/png;base64,qrs=')).toBe( '[image image/png, 2 B]', diff --git a/apps/kimi-code/test/tui/message-replay.test.ts b/apps/kimi-code/test/tui/message-replay.test.ts index 80b4e2be6..be5446a08 100644 --- a/apps/kimi-code/test/tui/message-replay.test.ts +++ b/apps/kimi-code/test/tui/message-replay.test.ts @@ -320,57 +320,6 @@ describe('KimiTUI resume message replay', () => { expect(transcript).not.toContain('Goal complete'); }); - it('renders an uploaded image daemon ref as a bare placeholder on replay', async () => { - // An uploaded image persists as a self-contained `kimi-file://` part; on - // replay it renders as a bare `[image]` placeholder — neither the - // materialization path nor the internal url may surface. - const driver = await replayIntoDriver([ - message( - 'user', - [ - { type: 'text', text: 'what is this? ' }, - { - type: 'image_url', - imageUrl: { url: 'kimi-file://f_1?path=%2FUsers%2Falice%2Fmedia%2Ff_1.png' }, - }, - ], - { origin: { kind: 'user' } }, - ), - ]); - - const transcript = stripAnsi(driver.state.transcriptContainer.render(140).join('\n')); - expect(transcript).toContain('what is this?'); - expect(transcript).toContain('[image]'); - expect(transcript).not.toContain('/Users/alice'); - expect(transcript).not.toContain('kimi-file'); - }); - - it('keeps the tag of a legacy upload pair as user text on replay', async () => { - // Legacy history paired the daemon ref with an `<image path>` tag. The - // pairing is gone: the tag is plain user text and replays verbatim while - // the ref still renders as `[image]`. - const driver = await replayIntoDriver([ - message( - 'user', - [ - { type: 'text', text: 'what is this? ' }, - { type: 'text', text: '<image path="/Users/alice/media/f_1.png"></image>' }, - { - type: 'image_url', - imageUrl: { url: 'kimi-file://f_1?path=%2FUsers%2Falice%2Fmedia%2Ff_1.png' }, - }, - ], - { origin: { kind: 'user' } }, - ), - ]); - - const transcript = stripAnsi(driver.state.transcriptContainer.render(140).join('\n')); - expect(transcript).toContain('what is this?'); - expect(transcript).toContain('[image]'); - expect(transcript).toContain('<image path="/Users/alice/media/f_1.png"></image>'); - expect(transcript).not.toContain('kimi-file'); - }); - it('unescapes bash tag delimiters when replaying shell output', async () => { const driver = await replayIntoDriver([ message( @@ -389,46 +338,6 @@ describe('KimiTUI resume message replay', () => { expect(transcript).toContain('pre</bash-stdout>post'); }); - it('collapses long replayed shell output to its first 10 rows', async () => { - const stdout = Array.from({ length: 30 }, (_, i) => `row-${String(i + 1).padStart(2, '0')}`).join( - '\n', - ); - const driver = await replayIntoDriver([ - message( - 'user', - [{ type: 'text', text: `<bash-stdout>${stdout}</bash-stdout><bash-stderr></bash-stderr>` }], - { origin: { kind: 'shell_command', phase: 'output' } }, - ), - ]); - - const transcript = stripAnsi(driver.state.transcriptContainer.render(140).join('\n')); - expect(transcript).toContain('... (20 more lines, ctrl+o to expand)'); - expect(transcript).toContain('row-01'); - expect(transcript).not.toContain('row-11'); - }); - - it('replayed shell output inherits an already-on ctrl+o expand state', async () => { - const stdout = Array.from({ length: 30 }, (_, i) => `row-${String(i + 1).padStart(2, '0')}`).join( - '\n', - ); - const initial = makeSession([]); - const resumed = makeSession([ - message( - 'user', - [{ type: 'text', text: `<bash-stdout>${stdout}</bash-stdout><bash-stderr></bash-stderr>` }], - { origin: { kind: 'shell_command', phase: 'output' } }, - ), - ]); - const driver = await makeDriver(initial); - driver.state.toolOutputExpanded = true; - await driver.switchToSession(resumed, 'Resumed session (ses-replay).'); - - const transcript = stripAnsi(driver.state.transcriptContainer.render(140).join('\n')); - expect(transcript).toContain('row-01'); - expect(transcript).toContain('row-30'); - expect(transcript).not.toContain('more lines'); - }); - it('does not render neutral goal completion context reminders as transcript messages', async () => { const driver = await replayIntoDriver([ message( @@ -1115,31 +1024,6 @@ describe('KimiTUI resume message replay', () => { ).toEqual(['run nightly']); }); - it('keeps the previous turn’s final answer visible when a cron turn follows in replay', async () => { - const cronFire = - '<cron-fire jobId="job-1" cron="*/5 * * * *" recurring="true" coalescedCount="1" stale="false">\n<prompt>\nrun nightly\n</prompt>\n</cron-fire>'; - const driver = await replayIntoDriver([ - message('user', [{ type: 'text', text: 'real prompt' }]), - message('assistant', [{ type: 'text', text: 'real answer' }]), - message('user', [{ type: 'text', text: cronFire }], { - origin: { - kind: 'cron_job', - jobId: 'job-1', - cron: '*/5 * * * *', - recurring: true, - coalescedCount: 1, - stale: false, - }, - }), - message('assistant', [{ type: 'text', text: 'cron report part one' }]), - message('assistant', [{ type: 'text', text: 'cron report final' }]), - ]); - - const transcript = stripAnsi(driver.state.transcriptContainer.render(120).join('\n')); - expect(transcript).toContain('cron report final'); - expect(transcript).toContain('real answer'); - }); - it('renders cron_missed origin records during replay without exposing raw XML', async () => { const cronMissed = '<cron-fire jobId="job-2" missed="true" count="3">\n3 one-shot tasks missed while offline\n</cron-fire>'; diff --git a/apps/kimi-code/test/tui/task-output-viewer.test.ts b/apps/kimi-code/test/tui/task-output-viewer.test.ts index 41470c96b..5948ec6c8 100644 --- a/apps/kimi-code/test/tui/task-output-viewer.test.ts +++ b/apps/kimi-code/test/tui/task-output-viewer.test.ts @@ -111,17 +111,6 @@ describe('TaskOutputViewer — rendering', () => { expect(out).toContain('delta'); expect(out).toContain('echo'); }); - - it('does not pass terminal controls from task output into the framed body', () => { - const rendered = makeViewer({ - output: 'Downloading wheel 25%\rDownloading wheel 75%\u001B[2Jdone', - }).render(120); - const raw = rendered.join('\n'); - - expect(raw).not.toContain('\r'); - expect(raw).not.toContain('\u001B[2J'); - expect(strip(raw)).toContain('Downloading wheel 25%Downloading wheel 75%done'); - }); }); describe('TaskOutputViewer — scrolling', () => { diff --git a/apps/kimi-code/test/tui/tasks-browser.test.ts b/apps/kimi-code/test/tui/tasks-browser.test.ts index d173af25f..7d5a54c3b 100644 --- a/apps/kimi-code/test/tui/tasks-browser.test.ts +++ b/apps/kimi-code/test/tui/tasks-browser.test.ts @@ -243,19 +243,6 @@ describe('TasksBrowserApp — full-screen rendering', () => { expect(out).toContain('listening on :3000'); }); - it('does not pass terminal controls from tail output into the framed preview', () => { - const rendered = makeApp({ - tasks: [task({ taskId: 'bash-aaaaaaaa' })], - selectedTaskId: 'bash-aaaaaaaa', - tailOutput: 'Downloading wheel 25%\rDownloading wheel 75%\u001B[2Jdone', - }).render(120); - const raw = rendered.join('\n'); - - expect(raw).not.toContain('\r'); - expect(raw).not.toContain('\u001B[2J'); - expect(strip(raw)).toContain('Downloading wheel 25%Downloading wheel 75%done'); - }); - it('shows a loading state when tail is loading', () => { const out = strip( makeApp({ diff --git a/apps/kimi-code/test/tui/tui-frame.bench.ts b/apps/kimi-code/test/tui/tui-frame.bench.ts index 0ada071af..2fc06ec02 100644 --- a/apps/kimi-code/test/tui/tui-frame.bench.ts +++ b/apps/kimi-code/test/tui/tui-frame.bench.ts @@ -14,7 +14,7 @@ */ import type { Component, Terminal } from '@moonshot-ai/pi-tui'; -import { TuiMainScreen } from '@moonshot-ai/pi-tui'; +import { TUI } from '@moonshot-ai/pi-tui'; import { bench, describe } from 'vitest'; const WIDTH = 120; @@ -72,7 +72,7 @@ class SpinnerComponent implements Component { describe('TUI steady-state frame', () => { const terminal = new StubTerminal(); - const tui = new TuiMainScreen(terminal); + const tui = new TUI(terminal); const spinner = new SpinnerComponent(); tui.addChild( new StaticTranscript( diff --git a/apps/kimi-code/test/tui/utils/inline-skill-tokens.test.ts b/apps/kimi-code/test/tui/utils/inline-skill-tokens.test.ts deleted file mode 100644 index d307a5611..000000000 --- a/apps/kimi-code/test/tui/utils/inline-skill-tokens.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { - extractInlineSkillActivations, - findInlineSkillTokens, -} from '#/tui/utils/inline-skill-tokens'; - -const SKILL_COMMAND_MAP = new Map([ - ['skill:review', 'review'], - ['skill:security', 'security'], - ['commit', 'commit'], -]); - -function findAll(text: string, includeLeading = false) { - return findInlineSkillTokens(text, { - isKnownSkill: (name) => SKILL_COMMAND_MAP.has(name) || SKILL_COMMAND_MAP.has(`skill:${name}`), - includeLeading, - }); -} - -describe('findInlineSkillTokens', () => { - it('finds tokens preceded by whitespace in first-occurrence order', () => { - expect(findAll('please /skill:review and /skill:security this')).toEqual([ - { commandName: 'skill:review', start: 7, end: 20 }, - { commandName: 'skill:security', start: 25, end: 40 }, - ]); - }); - - it('skips the leading slash-command area by default', () => { - expect(findAll('/skill:review')).toEqual([]); - expect(findAll('/skill:review')).toHaveLength(0); - expect(findAll('/skill:review', true)).toEqual([ - { commandName: 'skill:review', start: 0, end: 13 }, - ]); - }); - - it('finds tokens after the leading command and its arguments', () => { - expect(findAll('/skill:review some args /skill:security')).toEqual([ - { commandName: 'skill:security', start: 24, end: 39 }, - ]); - }); - - it('treats a newline as whitespace, so multi-line prompts work', () => { - expect(findAll('first line\n/skill:review more')).toEqual([ - { commandName: 'skill:review', start: 11, end: 24 }, - ]); - }); - - it('ignores slashes inside words, paths, and URLs', () => { - expect(findAll('and/or')).toEqual([]); - expect(findAll('see /tmp/file and https://example.com/a')).toEqual([]); - expect(findAll('1/2')).toEqual([]); - }); - - it('ignores unknown command names', () => { - expect(findAll('hello /not-a-skill world')).toEqual([]); - }); -}); - -describe('extractInlineSkillActivations', () => { - it('resolves command names to skill names, deduped in first-occurrence order', () => { - expect( - extractInlineSkillActivations( - '/skill:review then /skill:review again /skill:security', - SKILL_COMMAND_MAP, - { includeLeading: true }, - ), - ).toEqual([{ skillName: 'review' }, { skillName: 'security' }]); - }); - - it('supports the skill: prefix fallback for bare names', () => { - expect(extractInlineSkillActivations('hello /review', SKILL_COMMAND_MAP)).toEqual([ - { skillName: 'review' }, - ]); - }); - - it('keeps builtin skill command names as-is', () => { - expect(extractInlineSkillActivations('please /commit this', SKILL_COMMAND_MAP)).toEqual([ - { skillName: 'commit' }, - ]); - }); - - it('returns an empty list when nothing matches', () => { - expect(extractInlineSkillActivations('no tokens here', SKILL_COMMAND_MAP)).toEqual([]); - }); -}); diff --git a/apps/kimi-code/test/tui/utils/screen-takeover.test.ts b/apps/kimi-code/test/tui/utils/screen-takeover.test.ts deleted file mode 100644 index c3132bc30..000000000 --- a/apps/kimi-code/test/tui/utils/screen-takeover.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import type { Component, Terminal } from '@moonshot-ai/pi-tui'; -import { Text, TuiAltScreen, TuiMainScreen } from '@moonshot-ai/pi-tui'; - -import { beginScreenTakeover, endScreenTakeover } from '#/tui/utils/screen-takeover'; - -/** Minimal Terminal stub: takeover logic never starts the terminal. */ -function stubTerminal(): Terminal { - return { - start: () => {}, - stop: () => {}, - drainInput: async () => {}, - write: () => {}, - get columns() { - return 80; - }, - get rows() { - return 24; - }, - get kittyProtocolActive() { - return false; - }, - moveBy: () => {}, - hideCursor: () => {}, - showCursor: () => {}, - clearLine: () => {}, - clearFromCursor: () => {}, - clearScreen: () => {}, - setTitle: () => {}, - setProgress: () => {}, - }; -} - -function line(text: string): Component { - return new Text(text, 0, 0); -} - -describe('screen-takeover', () => { - it('swaps and restores root children in regular mode', () => { - const ui = new TuiMainScreen(stubTerminal()); - const transcript = line('transcript'); - const editor = line('editor'); - ui.addChild(transcript); - ui.addChild(editor); - - const viewer = line('viewer'); - const takeover = beginScreenTakeover(ui, viewer); - expect(ui.children).toEqual([viewer]); - - endScreenTakeover(ui, takeover); - expect(ui.children).toEqual([transcript, editor]); - }); - - it('swaps and restores the layout root in fullscreen mode', () => { - const ui = new TuiAltScreen(stubTerminal()); - const mainRoot = line('main-layout'); - ui.setLayoutRoot(mainRoot); - // The root children list is unused in fullscreen and stays empty. - expect(ui.children).toHaveLength(0); - - const viewer = line('viewer'); - const takeover = beginScreenTakeover(ui, viewer); - expect(ui.getLayoutRoot()).toBe(viewer); - - endScreenTakeover(ui, takeover); - expect(ui.getLayoutRoot()).toBe(mainRoot); - }); - - it('nests takeovers (viewer opened from a viewer)', () => { - const ui = new TuiAltScreen(stubTerminal()); - const mainRoot = line('main-layout'); - ui.setLayoutRoot(mainRoot); - - const browser = line('browser'); - const first = beginScreenTakeover(ui, browser); - const detail = line('detail'); - const second = beginScreenTakeover(ui, detail); - expect(ui.getLayoutRoot()).toBe(detail); - - endScreenTakeover(ui, second); - expect(ui.getLayoutRoot()).toBe(browser); - endScreenTakeover(ui, first); - expect(ui.getLayoutRoot()).toBe(mainRoot); - }); -}); diff --git a/apps/kimi-code/test/tui/utils/steer-input.test.ts b/apps/kimi-code/test/tui/utils/steer-input.test.ts deleted file mode 100644 index 8cadccfd1..000000000 --- a/apps/kimi-code/test/tui/utils/steer-input.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import type { PromptPart } from '@moonshot-ai/kimi-code-sdk'; - -import type { SteerInputItem } from '#/tui/types'; -import { combineSteerInput } from '#/tui/utils/steer-input'; - -describe('combineSteerInput', () => { - const refPart = { - type: 'image_url', - imageUrl: { url: 'kimi-file://f_1?path=%2Fcache%2Ff_1.png' }, - } as const; - - it('keeps a bare daemon-ref part intact while merging the surrounding text', () => { - const result = combineSteerInput([ - { - text: 'what is this?', - parts: [{ type: 'text', text: 'what is this? ' }, refPart], - }, - ]); - expect(result).toEqual([{ type: 'text', text: 'what is this? ' }, refPart]); - }); - - it('merges plain text across items around the media parts', () => { - const result = combineSteerInput([ - { text: 'a', parts: [{ type: 'text', text: 'a ' }, refPart] }, - { text: 'b', parts: [{ type: 'text', text: 'b ' }, refPart] }, - ]); - expect(result).toEqual([ - { type: 'text', text: 'a ' }, - refPart, - { type: 'text', text: '\n\nb ' }, - refPart, - ]); - }); - - it.each([ - { - name: 'between two touching media parts', - first: { text: '', parts: [refPart] } as SteerInputItem, - head: [] as PromptPart[], - }, - { - name: 'when a media-ending item is followed by a media-first item', - first: { - text: 'a', - parts: [{ type: 'text', text: 'a ' }, refPart], - } as SteerInputItem, - head: [{ type: 'text', text: 'a ' }] as PromptPart[], - }, - ])('drops the separator $name', ({ first, head }) => { - // Inserting '\n\n' there would strand a whitespace-only text part between - // the two media parts, which `normalizePromptInput` rejects. - const refPart2 = { - type: 'image_url', - imageUrl: { url: 'kimi-file://f_2?path=%2Fcache%2Ff_2.png' }, - } as const; - const result = combineSteerInput([first, { text: '', parts: [refPart2] }]); - expect(result).toEqual([...head, refPart, refPart2]); - }); - - it('treats a standalone <media path> tag as plain user text', () => { - // Extraction no longer authors machine tags, so a tag in the input is - // user text: it merges with adjacent text instead of staying atomic. - const tag = '<image path="/cache/f_1.png"></image>'; - const result = combineSteerInput([ - { - text: `look ${tag}`, - parts: [{ type: 'text', text: 'look ' }, { type: 'text', text: tag }, refPart], - }, - ]); - expect(result).toEqual([{ type: 'text', text: `look ${tag}` }, refPart]); - }); - - it('joins text-only items with the historical separator', () => { - expect(combineSteerInput([{ text: 'one' }, { text: 'two' }])).toBe('one\n\ntwo'); - }); -}); diff --git a/apps/kimi-code/test/tui/utils/thinking-config.test.ts b/apps/kimi-code/test/tui/utils/thinking-config.test.ts index fd41b7668..e0a953595 100644 --- a/apps/kimi-code/test/tui/utils/thinking-config.test.ts +++ b/apps/kimi-code/test/tui/utils/thinking-config.test.ts @@ -21,85 +21,20 @@ describe('thinkingEffortToConfig', () => { }); it.each([ - // With no declared default effort, the historical rule applies: the - // model's highest declared level (last support_efforts entry) is + // The model's highest declared level (last support_efforts entry) is // session-only; anything below it persists as the global default. ['low', { enabled: true, effort: 'low' }], ['high', { enabled: true, effort: 'high' }], ['max', { enabled: true }], // Undeclared values persist as-is (the provider validates them). ['ultra', { enabled: true, effort: 'ultra' }], - ] as const)('maps %s → %o for [low, high, max] without a default', (effort, expected) => { - expect(thinkingEffortToConfig(effort, { supportEfforts: ['low', 'high', 'max'] })).toEqual( - expected, - ); + ] as const)('maps %s → %o for [low, high, max]', (effort, expected) => { + expect(thinkingEffortToConfig(effort, ['low', 'high', 'max'])).toEqual(expected); }); it('treats a single declared level as the top tier', () => { - expect(thinkingEffortToConfig('max', { supportEfforts: ['max'] })).toEqual({ enabled: true }); + expect(thinkingEffortToConfig('max', ['max'])).toEqual({ enabled: true }); }); - - it.each([ - ['low', { enabled: true, effort: 'low' }], - ['high', { enabled: true, effort: 'high' }], - // Above the delivered default: session-only. - ['max', { enabled: true }], - ] as const)('maps %s → %o for [low, high, max] with default high', (effort, expected) => { - expect( - thinkingEffortToConfig(effort, { - supportEfforts: ['low', 'high', 'max'], - defaultEffort: 'high', - }), - ).toEqual(expected); - }); - - it('persists the top tier when the delivered default is the top tier', () => { - expect( - thinkingEffortToConfig('max', { - supportEfforts: ['low', 'high', 'max'], - defaultEffort: 'max', - }), - ).toEqual({ enabled: true, effort: 'max' }); - }); - - it('keeps a non-top pick above the delivered default session-only', () => { - expect( - thinkingEffortToConfig('high', { - supportEfforts: ['low', 'high', 'max'], - defaultEffort: 'low', - }), - ).toEqual({ enabled: true }); - }); - - it('falls back to the top-tier rule when the declared default is not a listed level', () => { - expect( - thinkingEffortToConfig('max', { - supportEfforts: ['low', 'high', 'max'], - defaultEffort: 'ultra', - }), - ).toEqual({ enabled: true }); - }); - - it.each([ - ['low', { enabled: true, effort: 'low' }], - ['medium', { enabled: true, effort: 'medium' }], - ['high', { enabled: true, effort: 'high' }], - // Above the effective default: session-only. - ['xhigh', { enabled: true }], - ['max', { enabled: true }], - ] as const)( - // The shape the Anthropic profile inference hands the gate for the - // latest Claude models: five tiers with the default resolved to 'high'. - 'maps %s → %o for [low, medium, high, xhigh, max] with default high', - (effort, expected) => { - expect( - thinkingEffortToConfig(effort, { - supportEfforts: ['low', 'medium', 'high', 'xhigh', 'max'], - defaultEffort: 'high', - }), - ).toEqual(expected); - }, - ); }); describe('isThinkingOn', () => { diff --git a/apps/kimi-code/test/utils/client-configs.test.ts b/apps/kimi-code/test/utils/client-configs.test.ts index 0290c3c7e..f97effa8f 100644 --- a/apps/kimi-code/test/utils/client-configs.test.ts +++ b/apps/kimi-code/test/utils/client-configs.test.ts @@ -10,7 +10,6 @@ import { peekClientConfig, resetClientConfigCache, } from '#/utils/client-configs'; -import { refreshKimiRegion } from '#/utils/region'; import { z } from 'zod'; const configSchema = z.object({ @@ -355,50 +354,3 @@ describe('getClientConfig disk cache', () => { expect(result).toEqual(CONFIG); }); }); - -describe('region awareness', () => { - beforeEach(() => { - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.ai'); - refreshKimiRegion(); - }); - - afterEach(() => { - vi.unstubAllEnvs(); - refreshKimiRegion(); - }); - - it('fetches from the active region profile and partitions the cache by region', async () => { - const fetchImpl = vi.fn(async () => jsonResponse(ENVELOPE)); - - const data = await getClientConfig('estimated_cache_duration', configSchema, { - fetchImpl: fetchImpl as typeof fetch, - cacheFile: null, - }); - - expect(data).toEqual(CONFIG); - expect(fetchImpl).toHaveBeenCalledWith( - expect.stringContaining('https://api.kimi.ai/coding/v1/client_configs'), - expect.anything(), - ); - expect(peekClientConfig('estimated_cache_duration', configSchema)).toEqual(CONFIG); - - // A region switch must not serve the other deployment's cached entry. - vi.stubEnv('KIMI_CODE_OAUTH_HOST', 'https://auth.kimi.com'); - refreshKimiRegion(); - expect(peekClientConfig('estimated_cache_duration', configSchema)).toBeUndefined(); - }); - - it('keeps honoring the KIMI_CODE_BASE_URL override ahead of the profile', async () => { - vi.stubEnv('KIMI_CODE_BASE_URL', 'https://env-api.example.com'); - const fetchImpl = vi.fn(async () => jsonResponse(ENVELOPE)); - - await fetchClientConfig('estimated_cache_duration', configSchema, { - fetchImpl: fetchImpl as typeof fetch, - }); - - expect(fetchImpl).toHaveBeenCalledWith( - expect.stringContaining('https://env-api.example.com/client_configs'), - expect.anything(), - ); - }); -}); diff --git a/apps/kimi-code/test/utils/kimi-datasource-plugin.test.ts b/apps/kimi-code/test/utils/kimi-datasource-plugin.test.ts index 9978bf7ad..c81fc0794 100644 --- a/apps/kimi-code/test/utils/kimi-datasource-plugin.test.ts +++ b/apps/kimi-code/test/utils/kimi-datasource-plugin.test.ts @@ -328,22 +328,9 @@ describe('kimi-datasource MCP server', () => { 'gildata', 'sec_edgar', 'sp_data', - 'china_nda', - 'china_nbs', - 'china_standards', - 'who', - 'fao', - 'unsd', - 'ecb', - 'eurostat', - 'unicef', - 'oecd', - 'fred', - 'xhcj', - 'caixin', ]); expect(call?.description).toContain( - 'For a simple lookup, use one specialized source and stop once a result covers the user', + 'For a simple lookup, use one specialized source and stop after its first successful result', ); expect(call?.description).toContain('When the user names a data source, use that source'); expect(call?.inputSchema.properties['data_source_name']?.description).toContain( diff --git a/apps/kimi-code/test/utils/plugin-marketplace.test.ts b/apps/kimi-code/test/utils/plugin-marketplace.test.ts index eb0a39837..5bc803ec3 100644 --- a/apps/kimi-code/test/utils/plugin-marketplace.test.ts +++ b/apps/kimi-code/test/utils/plugin-marketplace.test.ts @@ -6,16 +6,10 @@ import { fileURLToPath } from 'node:url'; import { describe, expect, it, vi } from 'vitest'; import { + KIMI_CODE_PLUGIN_MARKETPLACE_URL, KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV, - kimiCodePluginMarketplaceUrl, } from '#/constant/app'; -import { - computeUpdateStatus, - loadPluginMarketplace, - withBuiltInEntries, - withMarketplaceLatestVersions, - type PluginMarketplaceEntry, -} from '#/utils/plugin-marketplace'; +import { computeUpdateStatus, loadPluginMarketplace } from '#/utils/plugin-marketplace'; const REPO_ROOT = join(dirname(fileURLToPath(import.meta.url)), '../../../..'); @@ -254,18 +248,18 @@ describe('loadPluginMarketplace', () => { const marketplace = await loadPluginMarketplace({ workDir: '/tmp/work', - source: kimiCodePluginMarketplaceUrl(), + source: KIMI_CODE_PLUGIN_MARKETPLACE_URL, fetchImpl, }); - expect(fetchImpl).toHaveBeenCalledWith(kimiCodePluginMarketplaceUrl()); + expect(fetchImpl).toHaveBeenCalledWith(KIMI_CODE_PLUGIN_MARKETPLACE_URL); expect(marketplace.plugins[0]).toEqual( expect.objectContaining({ id: 'kimi-datasource', displayName: 'Kimi Datasource', source: new URL( './official/kimi-datasource.zip', - kimiCodePluginMarketplaceUrl(), + KIMI_CODE_PLUGIN_MARKETPLACE_URL, ).toString(), }), ); @@ -281,7 +275,7 @@ describe('loadPluginMarketplace', () => { try { const marketplace = await loadPluginMarketplace({ workDir: '/tmp/work', fetchImpl }); - expect(fetchImpl).toHaveBeenCalledWith(kimiCodePluginMarketplaceUrl()); + expect(fetchImpl).toHaveBeenCalledWith(KIMI_CODE_PLUGIN_MARKETPLACE_URL); expect(marketplace.source).toBe(join(REPO_ROOT, 'plugins/marketplace.json')); expect(marketplace.plugins).toContainEqual( expect.objectContaining({ @@ -305,7 +299,7 @@ describe('loadPluginMarketplace', () => { await expect(loadPluginMarketplace({ workDir: '/tmp/work', - source: kimiCodePluginMarketplaceUrl(), + source: KIMI_CODE_PLUGIN_MARKETPLACE_URL, fetchImpl, })).rejects.toThrow(/fetch failed/); }); @@ -594,127 +588,4 @@ describe('loadPluginMarketplace', () => { ); }); - describe('two-phase version lookup', () => { - async function writeCatalog(dir: string) { - const file = join(dir, 'marketplace.json'); - await writeFile( - file, - JSON.stringify({ - plugins: [ - { id: 'demo', displayName: 'Demo', source: 'https://github.com/owner/repo' }, - ], - }), - 'utf8', - ); - return file; - } - - it('skipLatestVersions returns the catalog without querying GitHub', async () => { - const fetchImpl = vi.fn(async () => { - throw new Error('should not be called'); - }) as unknown as typeof fetch; - const dir = await mkdtemp(join(tmpdir(), 'kimi-plugin-marketplace-')); - const file = await writeCatalog(dir); - - const marketplace = await loadPluginMarketplace({ - workDir: dir, - source: file, - fetchImpl, - skipLatestVersions: true, - }); - - expect(marketplace.plugins[0]?.version).toBeUndefined(); - expect(fetchImpl).not.toHaveBeenCalled(); - }); - - it('withMarketplaceLatestVersions fills versions from the latest release redirect', async () => { - const fetchImpl = vi.fn(async (input: unknown) => ({ - ok: false, - status: 302, - headers: new Headers({ - location: 'https://github.com/owner/repo/releases/tag/v1.2.3', - }), - text: async () => '', - })) as unknown as typeof fetch; - const dir = await mkdtemp(join(tmpdir(), 'kimi-plugin-marketplace-')); - const file = await writeCatalog(dir); - const marketplace = await loadPluginMarketplace({ - workDir: dir, - source: file, - skipLatestVersions: true, - }); - - const enriched = await withMarketplaceLatestVersions(marketplace, fetchImpl); - - expect(fetchImpl).toHaveBeenCalledWith( - 'https://github.com/owner/repo/releases/latest', - expect.objectContaining({ redirect: 'manual', signal: expect.any(AbortSignal) }), - ); - expect(enriched.plugins[0]?.version).toBe('1.2.3'); - }); - - it('withMarketplaceLatestVersions degrades to a missing version when the lookup aborts', async () => { - const fetchImpl = vi.fn(async (_input: unknown, init?: { signal?: AbortSignal }) => { - // Simulate the lookup hitting the timeout: undici rejects with the - // signal's reason once the AbortSignal fires. - throw init?.signal?.aborted === true - ? init.signal.reason - : new DOMException('This operation was aborted', 'AbortError'); - }) as unknown as typeof fetch; - const dir = await mkdtemp(join(tmpdir(), 'kimi-plugin-marketplace-')); - const file = await writeCatalog(dir); - const marketplace = await loadPluginMarketplace({ - workDir: dir, - source: file, - skipLatestVersions: true, - }); - - const enriched = await withMarketplaceLatestVersions(marketplace, fetchImpl); - - expect(enriched.plugins[0]?.version).toBeUndefined(); - expect(enriched.plugins[0]?.id).toBe('demo'); - }); - - it('carries a resolved catalog version onto a built-in row injected after enrichment', async () => { - // Regression for the resolve-before-inject ordering: enriching the - // built-in-masked marketplace cannot see the catalog entry's GitHub - // source, so built-in rows would never get update badges. - const fetchImpl = vi.fn(async () => ({ - ok: false, - status: 302, - headers: new Headers({ - location: 'https://github.com/owner/repo/releases/tag/v2.0.0', - }), - text: async () => '', - })) as unknown as typeof fetch; - const dir = await mkdtemp(join(tmpdir(), 'kimi-plugin-marketplace-')); - const file = join(dir, 'marketplace.json'); - await writeFile( - file, - JSON.stringify({ - plugins: [{ id: 'demo', displayName: 'Demo', source: 'https://github.com/owner/repo' }], - }), - 'utf8', - ); - const catalog = await loadPluginMarketplace({ - workDir: dir, - source: file, - skipLatestVersions: true, - }); - const builtIns: readonly PluginMarketplaceEntry[] = [ - { id: 'demo', displayName: 'Demo Capability', source: 'capability:demo', builtIn: true }, - ]; - - const enriched = withBuiltInEntries( - await withMarketplaceLatestVersions(catalog, fetchImpl), - builtIns, - ); - - expect(enriched.plugins).toHaveLength(1); - expect(enriched.plugins[0]).toEqual( - expect.objectContaining({ id: 'demo', builtIn: true, version: '2.0.0' }), - ); - }); - }); - }); diff --git a/apps/kimi-code/test/utils/process/fd-detect.test.ts b/apps/kimi-code/test/utils/process/fd-detect.test.ts index 76e48b71a..cd6fd249c 100644 --- a/apps/kimi-code/test/utils/process/fd-detect.test.ts +++ b/apps/kimi-code/test/utils/process/fd-detect.test.ts @@ -7,16 +7,6 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; import { detectFdPath, getFdAssetName } from '#/utils/process/fd-detect'; import { getBinDir } from '#/utils/paths'; -const mocks = vi.hoisted(() => ({ - resolveCommandPath: vi.fn(), - spawnSync: vi.fn(), -})); - -vi.mock('#/utils/process/resolve-command', () => ({ - resolveCommandPath: mocks.resolveCommandPath, -})); -vi.mock('node:child_process', () => ({ spawnSync: mocks.spawnSync })); - const originalEnv = { ...process.env }; let tempHome: string | undefined; @@ -26,7 +16,6 @@ afterEach(() => { tempHome = undefined; } process.env = { ...originalEnv }; - vi.clearAllMocks(); vi.unstubAllGlobals(); }); @@ -54,20 +43,6 @@ describe('getFdAssetName', () => { }); describe('detectFdPath', () => { - it('returns the absolute resolved path for a system fd binary', () => { - tempHome = mkdtempSync(join(tmpdir(), 'kimi-fd-home-')); - process.env['KIMI_CODE_HOME'] = tempHome; - mocks.resolveCommandPath.mockImplementation((name: string) => - name === 'fd' ? '/usr/local/bin/fd' : undefined, - ); - mocks.spawnSync.mockReturnValue({ status: 0 }); - - expect(detectFdPath()).toBe('/usr/local/bin/fd'); - expect(mocks.spawnSync).toHaveBeenCalledWith('/usr/local/bin/fd', ['--version'], { - stdio: 'ignore', - }); - }); - it('prefers the managed fd binary under KIMI_CODE_HOME', () => { tempHome = mkdtempSync(join(tmpdir(), 'kimi-fd-home-')); process.env['KIMI_CODE_HOME'] = tempHome; diff --git a/apps/kimi-code/test/utils/region.test.ts b/apps/kimi-code/test/utils/region.test.ts deleted file mode 100644 index dfb8c25a5..000000000 --- a/apps/kimi-code/test/utils/region.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { mkdtempSync, rmSync, writeFileSync } from 'node:fs'; -import { tmpdir } from 'node:os'; -import { join } from 'node:path'; - -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; - -import { currentKimiRegion, refreshKimiRegion, regionForBareLogin } from '#/utils/region'; - -const originalEnv = { ...process.env }; - -let home: string; - -beforeEach(() => { - home = mkdtempSync(join(tmpdir(), 'kimi-region-test-')); - process.env['KIMI_CODE_HOME'] = home; - delete process.env['KIMI_CODE_OAUTH_HOST']; - delete process.env['KIMI_OAUTH_HOST']; - delete process.env['KIMI_CODE_REGION_MARKER']; - refreshKimiRegion(); -}); - -afterEach(() => { - process.env = { ...originalEnv }; - refreshKimiRegion(); - rmSync(home, { recursive: true, force: true }); -}); - -describe('currentKimiRegion', () => { - it('follows the install-channel marker before the first login', () => { - writeFileSync(join(home, 'region'), 'global\n'); - expect(refreshKimiRegion()).toBe('global'); - expect(currentKimiRegion()).toBe('global'); - }); - - it('ignores the marker when KIMI_CODE_REGION_MARKER=off (embedded server)', () => { - writeFileSync(join(home, 'region'), 'global\n'); - process.env['KIMI_CODE_REGION_MARKER'] = 'off'; - expect(refreshKimiRegion()).toBe('mainland-cn'); - }); - - it('still honors a persisted global login when the marker is opted out', () => { - writeFileSync(join(home, 'region'), 'global\n'); - writeFileSync( - join(home, 'config.toml'), - [ - '[providers."managed:kimi-code"]', - 'type = "kimi"', - '', - '[providers."managed:kimi-code".oauth]', - 'storage = "file"', - 'key = "oauth/kimi-code-env-0123456789abcdef"', - 'oauthHost = "https://auth.kimi.ai"', - '', - ].join('\n'), - ); - process.env['KIMI_CODE_REGION_MARKER'] = 'off'; - expect(refreshKimiRegion()).toBe('global'); - }); -}); - -describe('regionForBareLogin', () => { - it('follows the resolved region for a fresh install (no persisted ref)', () => { - expect(regionForBareLogin(undefined)).toBe('mainland-cn'); - writeFileSync(join(home, 'region'), 'global\n'); - refreshKimiRegion(); - expect(regionForBareLogin(undefined)).toBe('global'); - }); - - it('re-pins mainland-cn for the default slot', () => { - expect(regionForBareLogin({ key: 'oauth/kimi-code' })).toBe('mainland-cn'); - }); - - it('keeps the configured environment for a scoped slot without a persisted host', () => { - expect(regionForBareLogin({ key: 'oauth/kimi-code-env-0123456789abcdef' })).toBeUndefined(); - }); - - it('keeps the persisted environment for a global login', () => { - expect( - regionForBareLogin({ - key: 'oauth/kimi-code-env-0123456789abcdef', - oauthHost: 'https://auth.kimi.ai', - }), - ).toBeUndefined(); - }); -}); diff --git a/apps/kimi-code/test/utils/remote-control-qr.test.ts b/apps/kimi-code/test/utils/remote-control-qr.test.ts deleted file mode 100644 index e69cb8347..000000000 --- a/apps/kimi-code/test/utils/remote-control-qr.test.ts +++ /dev/null @@ -1,104 +0,0 @@ -import { mkdtempSync, readFileSync, rmSync } from 'node:fs'; -import { tmpdir } from 'node:os'; -import { join } from 'node:path'; - -import { resetCapabilitiesCache, setCapabilities } from '@moonshot-ai/pi-tui'; -import { afterEach, describe, expect, it } from 'vitest'; - -import * as QRCode from 'qrcode'; - -import { generateRemoteControlQr, renderTerminalQr } from '#/utils/remote-control-qr'; - -const RESET = '\u001B[0m'; -const WHITE_CELL = '\u001B[38;2;255;255;255m\u001B[48;2;255;255;255m▀'; - -describe('renderTerminalQr', () => { - it('renders truecolor black-on-white half blocks with a white quiet zone', () => { - const url = 'https://example.test/rc/entry'; - const output = renderTerminalQr(url); - const size = QRCode.create(url, { errorCorrectionLevel: 'M' }).modules.size; - const width = size + 4; - - expect(output).toContain('\u001B[38;2;0;0;0m'); - expect(output).not.toContain('\u001B[40m'); - expect(output).not.toContain('\u001B[47m'); - expect(output).not.toContain('\u001B[30m'); - expect(output).not.toContain('\u001B[37m'); - expect(output.endsWith(RESET)).toBe(true); - - const lines = output.split('\n'); - expect(lines.at(-1)).toBe(RESET); - const rows = lines.slice(0, -1); - expect(rows.length).toBe(Math.ceil((size + 4) / 2)); - for (const row of rows) { - expect(row.startsWith(WHITE_CELL.repeat(2))).toBe(true); - expect(row.endsWith(`${WHITE_CELL.repeat(2)}${RESET}`)).toBe(true); - expect(row.split('▀').length - 1).toBe(width); - } - expect(rows[0]).toBe(`${WHITE_CELL.repeat(width)}${RESET}`); - expect(rows.at(-1)).toBe(`${WHITE_CELL.repeat(width)}${RESET}`); - }); - - it('renders different output for different URLs', () => { - expect(renderTerminalQr('https://example.test/a')).not.toBe( - renderTerminalQr('https://example.test/b'), - ); - }); -}); - -describe('generateRemoteControlQr terminal rendering', () => { - afterEach(() => { - resetCapabilitiesCache(); - }); - - async function generateInTempDir(url: string) { - const dir = mkdtempSync(join(tmpdir(), 'kimi-rc-qr-')); - try { - const result = await generateRemoteControlQr(url, dir); - return { ...result, dir }; - } catch (error) { - rmSync(dir, { recursive: true, force: true }); - throw error; - } - } - - it('falls back to half-block rendering when the terminal has no image protocol', async () => { - setCapabilities({ images: null, trueColor: true, hyperlinks: false }); - const url = 'https://example.test/rc/entry'; - const { terminal, pngPath, dir } = await generateInTempDir(url); - try { - expect(terminal).toBe(renderTerminalQr(url)); - expect(readFileSync(pngPath)).toEqual(await QRCode.toBuffer(url)); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('renders the PNG as a kitty image when the kitty protocol is available', async () => { - setCapabilities({ images: 'kitty', trueColor: true, hyperlinks: true }); - const url = 'https://example.test/rc/entry'; - const { terminal, pngPath, dir } = await generateInTempDir(url); - try { - const png = readFileSync(pngPath); - expect(terminal).toContain('\u001B_G'); - expect(terminal).toContain(png.toString('base64')); - expect(terminal).not.toBe(renderTerminalQr(url)); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); - - it('renders the PNG as an iterm2 inline image when the iterm2 protocol is available', async () => { - setCapabilities({ images: 'iterm2', trueColor: true, hyperlinks: true }); - const url = 'https://example.test/rc/entry'; - const { terminal, pngPath, dir } = await generateInTempDir(url); - try { - const png = readFileSync(pngPath); - expect(terminal).toContain('\u001B]1337;File='); - expect(terminal).toContain(png.toString('base64')); - expect(terminal).not.toBe(renderTerminalQr(url)); - } finally { - rmSync(dir, { recursive: true, force: true }); - } - }); -}); diff --git a/apps/kimi-inspect/AGENTS.md b/apps/kimi-inspect/AGENTS.md index 15782d128..2cafed501 100644 --- a/apps/kimi-inspect/AGENTS.md +++ b/apps/kimi-inspect/AGENTS.md @@ -6,18 +6,18 @@ Web inspector for the kap-server `/api/v1/debug` RPC surface — workspace/sessi A left icon rail (`src/components/NavRail.tsx`) switches top-level views: -- **Chat workspace** — the per-session chat (see "Chat view" below), with the session tree on the left: `src/components/Sidebar.tsx` is a single-column workspace → session tree over the v2 list's grouped projection (`GET /api/v2/sessions?view=by_workspace`, client in `src/sessions/api.ts` — v1-style `{ code, msg, data }` envelope, opaque-cursor pagination over groups; each workspace group carries its first `group.page_size` sessions plus the full matching total, and a "Show all" row falls back to the flat per-workspace listing). Preset views in `src/sessions/views.ts` map onto the endpoint's status / archived / git query conditions; the active view, collapsed workspaces, and panel width persist to localStorage; live activity badges come from the hub. +- **Chat workspace** — the per-session chat (see "Chat view" below), with the session table on the left: `src/components/Sidebar.tsx` is a spreadsheet-like table panel over `GET /api/v2/sessions` (client in `src/sessions/api.ts` — v1-style `{ code, msg, data }` envelope, opaque-cursor pagination; preset views in `src/sessions/views.ts` map onto the endpoint's status / archived / git query conditions), with column visibility + active view persisted to localStorage, server-side sort toggles on the Updated / Created headers, live activity badges from the hub, and a per-workspace grouped view. - **Global message search** (`src/components/SearchView.tsx`) — cross-session full-text search over `POST /api/v1/search`, cursor-paged via a manual Load more; an exact-match checkbox maps to the API's `mode: 'literal'` substring search, which ignores sort and orders newest-first; a `live`/`index` badge on the results shows which server route served them (in-memory session transcript vs the persisted index). - **Model Catalog** (`src/components/ModelCatalogView.tsx`) — every Provider with its Models and the default marker, via `IModelCatalog` / `IModelService` channel proxies. Expanding a Model opens the model inspector inside that view: provider/model config layers plus the resolved runtime view with per-value provenance (config / override / builtin / env / synthesized), served on demand by `IModelCatalog.inspect` — the same resolution pass the runtime's `get` serves, traced via `ResolutionTraceCollector` and assembled by `kosong/model/inspection.ts`. - **App Services** (`src/components/AppServicesView.tsx`) — the app-scope Service reflection, full width, joined by the **Workspace Services** view (`src/components/WorkspaceServicesView.tsx`) — the workspace-scope counterpart with a left sidebar directory browser (`src/components/WorkspaceDirBrowser.tsx` — server-side fs browsing over the App-scope `IHostFolderBrowser`, marking entries that are registered workspaces with their `IWorkspaceTrust` trust state, and registering a picked folder on demand via `IWorkspaceService.createOrTouch`), its proxies riding the `/workspace/:id` route, which materializes the handler on demand via `IWorkspaceLifecycleService.handlerFor`. - **DI view** (`src/components/DiInspectionView.tsx`) — the engine's Service × Effect × DI debug surface over the App-scope `IDebugLedgerService` / `IDebugGraphService` / `IDebugEventsService` / `IDebugCascadeService`: the unit tree = ledger tree with unprovide / update / dispose triggers, the dependency DAG as Miller columns (`di/DiGraphPanel.tsx`), the event-subscription ledger (unit-book `on:<name>` entries + per-bus listener counts, `di/DiEventsPanel.tsx`), the cascade history, and the waiting area; the five panels poll on a short interval and refresh eagerly off the global `event.di.unit_changed` WS frame via `src/activity/di.ts`, which invalidates the `['di']` react-query prefix. -The **Agent scope** stays in the Chat view's right dock (`src/components/RightPanel.tsx` — Audit / Agent / State / Session tabs) across two of them: +The **Agent scope** stays in the Chat view's right dock (`src/components/RightPanel.tsx`) across two tabs: - `Agent` tab — `Inspector`: agent switcher + a Plan lookup card (`PlanCard` in `src/components/Inspector.tsx` — querying `GET /sessions/{id}/transcript/plan` (one tool_call_id, or every plan of the agent) via `src/transcript/api.ts`'s `fetchTranscriptPlan`) plus the agent Service panels. - `State` tab — every key an Agent Service registered into the agent-state container, polled live via `IAgentStateService.snapshot()` — the same live diff-tree view as the session State tab, sharing `StateCard` from `src/components/StateCard.tsx`. -The **Session scope** lives in the same right dock as the `Session` tab (`src/components/SessionPane.tsx`, embedded by `RightPanel`) with two sub-tabs: Services (the pending-interactions card — `src/components/InteractionsCard.tsx` — plus the session Service panels) and State (every key a Session Service registered into the session-state container, read on demand via `ISessionStateService.snapshot()`). +The **Session scope** has its own column right next to the session-list sidebar (`src/components/SessionPane.tsx`) with two tabs: Services (the pending-interactions card — `src/components/InteractionsCard.tsx` — plus the session Service panels) and State (every key a Session Service registered into the session-state container, read on demand via `ISessionStateService.snapshot()`). ## Channel layer @@ -25,7 +25,7 @@ Built on its own old-klient-style channel layer (`src/channel/`: the VS Code `Pr ## Session activity -Session-level coarse status is the one exception to no-push: `src/activity/` holds a second `/api/v1/ws` client (`GlobalEventsWs`) that subscribes to nothing and consumes the server-pushed global facts — `event.session.work_changed` updates a per-session activity map (`SessionActivityHub` + subscribe/version store, seeded on connect/reconnect from `GET /api/v1/sessions`), while `event.session.created` / `event.session.archived` / `session.meta.updated` / `event.workspace.*` invalidate the `['sessions']` / `['v2-sessions']` / `['workspaces']` queries (an archive also drops the session's live activity entry, since no further `work_changed` frames will correct a stale badge); the session tree rows render `running` / `approval` / `question` / `failed` badges from it via `useSessionActivities` (live facts override the REST `activity.status`). +Session-level coarse status is the one exception to no-push: `src/activity/` holds a second `/api/v1/ws` client (`GlobalEventsWs`) that subscribes to nothing and consumes the server-pushed global facts — `event.session.work_changed` updates a per-session activity map (`SessionActivityHub` + subscribe/version store, seeded on connect/reconnect from `GET /api/v1/sessions`), while `event.session.created` / `session.meta.updated` invalidate the `['sessions']` / `['v2-sessions']` queries; the session table rows render `running` / `approval` / `question` / `failed` badges from it via `useSessionActivities` (live facts override the REST `activity.status`). ## Dev server diff --git a/apps/kimi-inspect/src/App.tsx b/apps/kimi-inspect/src/App.tsx index def8a9213..a3ce38d58 100644 --- a/apps/kimi-inspect/src/App.tsx +++ b/apps/kimi-inspect/src/App.tsx @@ -4,10 +4,9 @@ * event streams was removed server-side, so Service panels and the pending * interactions card fetch on demand and the sidebar polls. * Layout: header / icon rail / view. The `chat` view is a strip of the - * left sidebar (a workspace → session tree), the chat column, and the - * right dock (`RightPanel`) merging the transcript audit, the agent - * inspector, and the session pane under Audit / Agent / State / Session - * tabs; + * left sidebar (workspaces + sessions), the session pane (session Services + * / State tabs), the chat column, and the right dock (`RightPanel`) merging + * the transcript audit and the agent inspector under Audit / Agent tabs; * the `models` view is the full-width model catalog; the `services` view is * the full-width app-scope Service reflection (`AppServicesView`); the * `workspace` view is the workspace-scope counterpart @@ -19,7 +18,8 @@ * chat timeline. */ -import { ISessionManager } from '@moonshot-ai/agent-core-v2/app/sessionManager/sessionManager'; +import { ISessionIndex } from '@moonshot-ai/agent-core-v2/app/sessionIndex/sessionIndex'; +import { ISessionLifecycleService } from '@moonshot-ai/agent-core-v2/workspace/sessionLifecycle/sessionLifecycle'; import { useEffect, useState } from 'react'; import type { AuditTrail } from './audit/trail'; @@ -27,12 +27,12 @@ import { AppServicesView } from './components/AppServicesView'; import { BashParserView } from './components/BashParserView'; import { ChatView, type ChatJump } from './components/ChatView'; import { DiInspectionView } from './components/DiInspectionView'; -import { FsSuggestView } from './components/FsSuggestView'; import { ModelCatalogView } from './components/ModelCatalogView'; import { NavRail, type AppView } from './components/NavRail'; import { RightPanel } from './components/RightPanel'; import { SearchView } from './components/SearchView'; import { ServerSwitcher } from './components/ServerSwitcher'; +import { SessionPane } from './components/SessionPane'; import { Sidebar } from './components/Sidebar'; import { WorkspaceServicesView } from './components/WorkspaceServicesView'; import { useConnection } from './connection'; @@ -61,10 +61,14 @@ export function App() { setReady(false); setResumeError(null); klient - .core(ISessionManager) - .resume(sessionId) - .then((session) => { - if (session === undefined) throw new Error(`session ${sessionId} does not exist`); + .core(ISessionIndex) + .get(sessionId) + .then((summary) => { + if (summary === undefined) throw new Error(`session ${sessionId} does not exist`); + return klient + .workspace(summary.workspaceId) + .service(ISessionLifecycleService) + .resume(sessionId); }) .then(() => { if (!cancelled) setReady(true); @@ -118,8 +122,6 @@ export function App() { <AppServicesView /> ) : view === 'workspace' ? ( <WorkspaceServicesView /> - ) : view === 'suggest' ? ( - <FsSuggestView /> ) : view === 'bash' ? ( <BashParserView /> ) : view === 'di' ? ( @@ -136,6 +138,7 @@ export function App() { ) : ( <> <Sidebar activeSessionId={sessionId} onSelectSession={setSessionId} /> + <SessionPane sessionId={sessionId} ready={ready} /> {resumeError !== null ? ( <div className="flex flex-1 items-center justify-center p-6 text-center text-[12px] text-red-400"> Failed to open session: {errorMessage(resumeError)} diff --git a/apps/kimi-inspect/src/activity/store.test.ts b/apps/kimi-inspect/src/activity/store.test.ts index 64f191f3a..dea649664 100644 --- a/apps/kimi-inspect/src/activity/store.test.ts +++ b/apps/kimi-inspect/src/activity/store.test.ts @@ -170,43 +170,4 @@ describe('SessionActivityHub', () => { expect(hub.store.get('s1')).toBeUndefined(); hub.close(); }); - - it('forwards archived and workspace frames as list-level signals and drops archived facts', () => { - const { ctor, instances } = makeFakeWsCtor(); - const onListChanged = vi.fn(); - const hub = new SessionActivityHub({ - url: 'http://127.0.0.1:58627', - onListChanged, - WebSocketImpl: ctor, - fetchImpl: seedFetch([]), - }); - instances[0]!.emit('open'); - - instances[0]!.emitFrame({ - type: 'event.session.work_changed', - session_id: 's1', - payload: { type: 'event.session.work_changed', busy: true }, - }); - expect(hub.store.get('s1')).toBeDefined(); - - // Global-dispatched frames carry the __global__ watermark; the real - // session id rides in the payload. - instances[0]!.emitFrame({ - type: 'event.session.archived', - session_id: '__global__', - payload: { type: 'event.session.archived', sessionId: 's1', workspace_id: 'wd_1' }, - }); - expect(hub.store.get('s1')).toBeUndefined(); - expect(onListChanged).toHaveBeenCalledTimes(1); - - for (const type of [ - 'event.workspace.created', - 'event.workspace.updated', - 'event.workspace.deleted', - ]) { - instances[0]!.emitFrame({ type, session_id: '__global__', payload: {} }); - } - expect(onListChanged).toHaveBeenCalledTimes(4); - hub.close(); - }); }); diff --git a/apps/kimi-inspect/src/activity/store.ts b/apps/kimi-inspect/src/activity/store.ts index addadaca6..b68fffc61 100644 --- a/apps/kimi-inspect/src/activity/store.ts +++ b/apps/kimi-inspect/src/activity/store.ts @@ -58,12 +58,6 @@ export class SessionActivityStore { this.bump(); } - /** Drop one session's live facts (e.g. it was archived — no further - * work_changed frames will arrive to correct a stale badge). */ - remove(sessionId: string): void { - if (this.activities.delete(sessionId)) this.bump(); - } - private bump(): void { this.version += 1; for (const listener of this.listeners) listener(); @@ -102,11 +96,6 @@ export class SessionActivityHub { onWorkChanged: (sessionId, facts) => this.store.applyWorkChanged(sessionId, facts), onSessionCreated: () => opts.onListChanged(), onMetaUpdated: () => opts.onListChanged(), - onSessionArchived: (sessionId) => { - this.store.remove(sessionId); - opts.onListChanged(); - }, - onWorkspaceChanged: () => opts.onListChanged(), onReconnected: () => void this.seed(), }, }); diff --git a/apps/kimi-inspect/src/activity/useSessionActivity.ts b/apps/kimi-inspect/src/activity/useSessionActivity.ts index 651cb6db8..c435b1238 100644 --- a/apps/kimi-inspect/src/activity/useSessionActivity.ts +++ b/apps/kimi-inspect/src/activity/useSessionActivity.ts @@ -33,7 +33,6 @@ export function useSessionActivities(): { onListChanged: () => { void queryClient.invalidateQueries({ queryKey: ['sessions'] }); void queryClient.invalidateQueries({ queryKey: ['v2-sessions'] }); - void queryClient.invalidateQueries({ queryKey: ['workspaces'] }); }, }); setHub(created); diff --git a/apps/kimi-inspect/src/activity/ws.ts b/apps/kimi-inspect/src/activity/ws.ts index f4ecbe214..c7ff61089 100644 --- a/apps/kimi-inspect/src/activity/ws.ts +++ b/apps/kimi-inspect/src/activity/ws.ts @@ -12,8 +12,6 @@ * pending_interaction, last_turn_reason}` for one session; * - `event.session.created` / `session.meta.updated` → list-level signals * (a session appeared / retitled), forwarded for list invalidation; - * - `event.session.archived` (live or cold) / `event.workspace.*` → - * list-level signals, forwarded for list invalidation; * - `event.di.unit_changed` → one DI unit state transition of the engine's * scope tree (the debug-surface feed), forwarded for `['di']` * invalidation. Global like the rest: it carries the `__global__` @@ -60,12 +58,6 @@ export interface GlobalEventsWsHandlers { onSessionCreated: (sessionId: string) => void; /** A session's title/patch changed (list-level signal). */ onMetaUpdated: (sessionId: string) => void; - /** A session was archived, live or cold (list-level signal). The envelope - * carries the `__global__` watermark; the real session id rides in the - * payload. */ - onSessionArchived?: ((sessionId: string) => void) | undefined; - /** A workspace was created / updated / deleted (list-level signal). */ - onWorkspaceChanged?: (() => void) | undefined; /** A DI unit of the engine's scope tree changed state (debug feed). */ onDiUnitChanged?: ((payload: DiUnitChangedPayload) => void) | undefined; /** Socket established (initial connect and every reconnect) — the consumer @@ -187,20 +179,6 @@ export class GlobalEventsWs { this.handlers.onSessionCreated(sessionId); return; } - case 'event.session.archived': { - const payload = frame.payload as { sessionId?: unknown } | undefined; - const archivedId = payload?.sessionId; - if (typeof archivedId === 'string' && archivedId !== '') { - this.handlers.onSessionArchived?.(archivedId); - } - return; - } - case 'event.workspace.created': - case 'event.workspace.updated': - case 'event.workspace.deleted': { - this.handlers.onWorkspaceChanged?.(); - return; - } case 'session.meta.updated': { this.handlers.onMetaUpdated(sessionId); return; diff --git a/apps/kimi-inspect/src/channel/channel.test.ts b/apps/kimi-inspect/src/channel/channel.test.ts index fdf2de26c..1064924fe 100644 --- a/apps/kimi-inspect/src/channel/channel.test.ts +++ b/apps/kimi-inspect/src/channel/channel.test.ts @@ -8,13 +8,7 @@ import { afterEach, describe, expect, it, vi } from 'vitest'; import type { Event, IChannel } from './channel'; import { probeDebugSurface } from './channels'; -import { createInspectClient } from './client'; import { RPCError } from './errors'; -import { - fetchAgentRuntimeBinding, - fetchSessionWorkspaceAssociation, - fetchWorkspaceSnapshot, -} from '../snapshots/api'; import { makeProxy } from './proxy'; import { ProxyChannel } from './proxyChannel'; @@ -37,14 +31,14 @@ describe('ProxyChannel.call', () => { it('POSTs the command to the service base URL; no body and no header without args/token', async () => { const { calls, fetchImpl } = fakeFetch(ok({ id: 's1' })); const channel = new ProxyChannel({ - baseUrl: 'http://h:1/api/v1/debug/session/s%201/agent/main/agentLoopService', + baseUrl: 'http://h:1/api/v1/debug/session/s%201/agent/main/agentRPCService', fetch: fetchImpl, }); const result = await channel.call('getModel', []); expect(result).toEqual({ id: 's1' }); expect(calls).toHaveLength(1); expect(calls[0]!.url).toBe( - 'http://h:1/api/v1/debug/session/s%201/agent/main/agentLoopService/getModel', + 'http://h:1/api/v1/debug/session/s%201/agent/main/agentRPCService/getModel', ); expect(calls[0]!.init?.method).toBe('POST'); expect(calls[0]!.init?.body).toBeUndefined(); @@ -122,42 +116,6 @@ describe('ProxyChannel.listen', () => { }); }); -describe('business snapshots', () => { - it('uses explicit workspace, session association, and agent binding routes', async () => { - const calls: string[] = []; - vi.stubGlobal('fetch', async (url: string | URL) => { - const value = String(url); - calls.push(value); - if (value.endsWith('/workspace/w%201/snapshot')) { - return { json: async () => ok({ metadata: { id: 'w 1' } }) }; - } - if (value.endsWith('/session/s%201/association')) { - return { json: async () => ok({ sessionId: 's 1', workspaceId: 'w 1', cwd: '/work' }) }; - } - return { - json: async () => ok({ - binding: { workspaceId: 'w 1', runtimeId: 'remote' }, - available: true, - runtime: { runtimeId: 'remote', generation: 'g2', status: 'ready', capabilities: ['process'] }, - }), - }; - }); - const client = createInspectClient({ url: 'http://h:9', token: 'tok' }); - - await expect(fetchWorkspaceSnapshot(client, 'w 1')).resolves.toMatchObject({ metadata: { id: 'w 1' } }); - await expect(fetchSessionWorkspaceAssociation(client, 's 1')).resolves.toMatchObject({ workspaceId: 'w 1' }); - await expect(fetchAgentRuntimeBinding(client, 's 1', 'main')).resolves.toMatchObject({ - binding: { runtimeId: 'remote' }, - runtime: { generation: 'g2' }, - }); - expect(calls).toEqual([ - 'http://h:9/api/v1/debug/workspace/w%201/snapshot', - 'http://h:9/api/v1/debug/session/s%201/association', - 'http://h:9/api/v1/debug/session/s%201/agent/main/runtime-binding', - ]); - }); -}); - describe('probeDebugSurface', () => { function stubProbeFetch(impl: (url: string, init?: RequestInit) => unknown) { const calls: { url: string; init?: RequestInit }[] = []; diff --git a/apps/kimi-inspect/src/channel/channels.ts b/apps/kimi-inspect/src/channel/channels.ts index c97405f08..c2f28c007 100644 --- a/apps/kimi-inspect/src/channel/channels.ts +++ b/apps/kimi-inspect/src/channel/channels.ts @@ -19,7 +19,7 @@ import { DEBUG_RPC_BASE, type InspectClient } from './client'; import { RPCError } from './errors'; /** Wire scope kinds reported by the channels endpoint (`app` ≡ the core route). */ -export type ChannelScope = 'app' | 'session' | 'agent'; +export type ChannelScope = 'app' | 'workspace' | 'session' | 'agent'; /** Mirror of `ChannelDescriptor` in kap-server (`GET /api/v1/debug/channels`). */ export interface ChannelDescriptor { @@ -94,6 +94,7 @@ export async function probeDebugSurface(options: { export interface ServiceTarget { readonly scope: ChannelScope; + readonly workspaceId?: string; readonly sessionId?: string; readonly agentId?: string; } @@ -112,6 +113,10 @@ export function serviceByName<T extends object>( ): ServiceProxy<T> | undefined { const id = createDecorator<T>(name); if (target.scope === 'app') return client.core(id); + if (target.scope === 'workspace') { + if (target.workspaceId === undefined) return undefined; + return client.workspace(target.workspaceId).service(id); + } if (target.sessionId === undefined) return undefined; const base = client.session(target.sessionId); if (target.scope === 'session') return base.service(id); diff --git a/apps/kimi-inspect/src/channel/client.ts b/apps/kimi-inspect/src/channel/client.ts index 04eb6a760..f0149efb1 100644 --- a/apps/kimi-inspect/src/channel/client.ts +++ b/apps/kimi-inspect/src/channel/client.ts @@ -8,7 +8,7 @@ * await client.core(ISessionIndex).listRecent({}); * await client.workspace('wd_1').service(ISessionLifecycleService).resume('s1'); * await client.session('s1').service(ISessionMetadata).read(); - * await client.session('s1').agent('main').service(IAgentLoopService).cancelFromUser(); + * await client.session('s1').agent('main').service(IAgentRPCService).cancel({}); * * The `agent-core-v2` service token is the whole key: its type parameter `T` * types the returned proxy, and its decorator id (`String(id)`) is the channel @@ -40,6 +40,7 @@ export interface InspectClient { /** Bearer token in use, when any. */ readonly token?: string; core<T extends object>(id: ServiceRef<T>): ServiceProxy<T>; + workspace(workspaceId: string): InspectAgentHandle; session(sessionId: string): InspectSessionHandle; } @@ -68,6 +69,9 @@ export function createInspectClient(options: InspectClientOptions): InspectClien baseUrl: url, token: options.token, core: (id) => proxy('', id), + workspace: (workspaceId) => ({ + service: (id) => proxy(`/workspace/${encodeURIComponent(workspaceId)}`, id), + }), session: (sessionId) => { const scopePath = `/session/${encodeURIComponent(sessionId)}`; return { diff --git a/apps/kimi-inspect/src/components/ChatView.tsx b/apps/kimi-inspect/src/components/ChatView.tsx index 9d9933f12..2ba937a2e 100644 --- a/apps/kimi-inspect/src/components/ChatView.tsx +++ b/apps/kimi-inspect/src/components/ChatView.tsx @@ -14,14 +14,12 @@ * a full REST refresh; nothing is resynced from the socket itself. * * Rendering is turn-granular (turn → step → frame) and typed entirely by the - * transcript data model. Prompts/cancels go through the `IAgentPromptService` - * / `IAgentLoopService` channels + * transcript data model. Prompts/cancels go through the `IAgentRPCService` * over the debug RPC surface (`/api/v1/debug`); the running indicator * derives from transcript state (`meta.activity` / running turns). */ -import { IAgentLoopService } from '@moonshot-ai/agent-core-v2/agent/loop/loop'; -import { IAgentPromptService } from '@moonshot-ai/agent-core-v2/agent/prompt/prompt'; +import { IAgentRPCService } from '@moonshot-ai/agent-core-v2/agent/rpc/rpc'; import { ISessionApprovalService } from '@moonshot-ai/agent-core-v2/session/approval/approval'; import { ISessionQuestionService, @@ -61,12 +59,7 @@ import { import { AuditTrail } from '../audit/trail'; import { useConnection } from '../connection'; import type { SearchHit } from '../search/api'; -import { - fetchTranscriptAttachment, - fetchTranscriptOps, - fetchTranscriptPage, - TRANSCRIPT_PAGE_SIZE, -} from '../transcript/api'; +import { fetchTranscriptOps, fetchTranscriptPage, TRANSCRIPT_PAGE_SIZE } from '../transcript/api'; import { createCoalescedRunner, hasTurnId, @@ -568,8 +561,8 @@ export function ChatView({ await klient .session(sessionId) .agent(agentId) - .service(IAgentPromptService) - .submit({ input: [{ type: 'text', text }] }); + .service(IAgentRPCService) + .prompt({ input: [{ type: 'text', text }] }); trail?.recordEvent('prompt', text, state); } catch (error) { setSendError(error); @@ -579,7 +572,7 @@ export function ChatView({ const cancel = async () => { if (sessionId === null) return; try { - await klient.session(sessionId).agent(agentId).service(IAgentLoopService).cancelFromUser(); + await klient.session(sessionId).agent(agentId).service(IAgentRPCService).cancel({}); trail?.recordEvent('cancel', undefined, state); } catch (error) { setSendError(error); @@ -950,6 +943,7 @@ function AttachmentChips({ {ids.map((id) => { const attachment = attachments.get(id); const label = attachment?.name ?? attachment?.mediaType ?? id; + const href = attachment?.source?.kind === 'url' ? attachment.source.url : undefined; return ( <span key={id} @@ -957,7 +951,13 @@ function AttachmentChips({ title={attachment?.mediaType} > 📎{' '} - <AttachmentLink attachment={attachment} label={label} /> + {href !== undefined ? ( + <a href={href} className="underline"> + {label} + </a> + ) : ( + label + )} </span> ); })} @@ -965,63 +965,6 @@ function AttachmentChips({ ); } -function AttachmentLink({ - attachment, - label, -}: { - attachment: TranscriptAttachment | undefined; - label: string; -}) { - const sessionId = useContext(SessionContext); - const { baseUrl, config } = useConnection(); - const [downloading, setDownloading] = useState(false); - const [error, setError] = useState<string | null>(null); - const source = attachment?.source; - if (source === undefined) return label; - if (source.kind === 'url') { - return ( - <a href={source.url} target="_blank" rel="noreferrer" className="underline"> - {label} - </a> - ); - } - const download = async (): Promise<void> => { - setDownloading(true); - setError(null); - try { - const blob = await fetchTranscriptAttachment({ - baseUrl, - token: config.token.trim() || undefined, - sessionId, - source, - }); - const href = URL.createObjectURL(blob); - const link = document.createElement('a'); - link.href = href; - link.download = attachment?.name ?? source.fileId; - link.click(); - setTimeout(() => { - URL.revokeObjectURL(href); - }, 0); - } catch (error) { - setError(error instanceof Error ? error.message : String(error)); - } finally { - setDownloading(false); - } - }; - return ( - <button - type="button" - className="underline disabled:cursor-wait disabled:opacity-60" - disabled={downloading} - title={error ?? undefined} - onClick={() => void download()} - > - {downloading ? 'Downloading…' : label} - </button> - ); -} - function FrameView({ frame, tasks, diff --git a/apps/kimi-inspect/src/components/FsSuggestView.tsx b/apps/kimi-inspect/src/components/FsSuggestView.tsx deleted file mode 100644 index ab5cf6f3f..000000000 --- a/apps/kimi-inspect/src/components/FsSuggestView.tsx +++ /dev/null @@ -1,256 +0,0 @@ -import { IWorkspaceService, type Workspace } from '@moonshot-ai/agent-core-v2/app/workspace/workspace'; -import { useMutation, useQuery } from '@tanstack/react-query'; -import { useEffect, useState } from 'react'; - -import { useConnection } from '../connection'; -import { fetchFsSuggest, type FsSuggestResult } from '../fs/api'; -import { Badge, ErrorLine } from '../ui'; -import { WorkspaceDirBrowser } from './WorkspaceDirBrowser'; - -function parseGlobs(value: string): string[] | undefined { - const globs = value - .split(',') - .map((glob) => glob.trim()) - .filter((glob) => glob.length > 0); - return globs.length === 0 ? undefined : globs; -} - -function parseRoots(value: string): string[] { - return value - .split(/[\n,]/) - .map((root) => root.trim()) - .filter((root) => root.length > 0); -} - -export function FsSuggestView() { - const { klient, baseUrl } = useConnection(); - const [workspace, setWorkspace] = useState<Workspace | null>(null); - const [rootsText, setRootsText] = useState(''); - const [query, setQuery] = useState(''); - const [limit, setLimit] = useState('50'); - const [followGitignore, setFollowGitignore] = useState(true); - const [showHidden, setShowHidden] = useState(false); - const [includeGlobs, setIncludeGlobs] = useState(''); - const [excludeGlobs, setExcludeGlobs] = useState(''); - - const workspaces = useQuery({ - queryKey: ['workspaces', klient.baseUrl], - queryFn: () => klient.core(IWorkspaceService).list(), - }); - - const suggest = useMutation<FsSuggestResult, Error>({ - mutationFn: async () => { - const roots = parseRoots(rootsText); - const parsedLimit = Number.parseInt(limit, 10); - const shared = { - baseUrl: klient.baseUrl, - token: klient.token, - query, - limit: Number.isFinite(parsedLimit) && parsedLimit > 0 ? parsedLimit : undefined, - followGitignore, - showHidden, - includeGlobs: parseGlobs(includeGlobs), - excludeGlobs: parseGlobs(excludeGlobs), - }; - if (roots.length > 0) { - return fetchFsSuggest({ ...shared, roots }); - } - if (workspace === null) throw new Error('select a workspace or enter roots first'); - return fetchFsSuggest({ ...shared, roots: [workspace.root] }); - }, - }); - - useEffect(() => { - setWorkspace(null); - suggest.reset(); - }, [baseUrl]); - - const selectWorkspace = (next: Workspace) => { - setWorkspace(next); - suggest.reset(); - }; - - return ( - <div className="flex min-h-0 min-w-0 flex-1"> - <aside className="flex w-72 shrink-0 flex-col border-r border-neutral-800"> - <div className="border-b border-neutral-800 px-3 py-2"> - <div className="text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Workspace - </div> - <div title={workspace?.root} className="truncate font-mono text-[11px] text-neutral-300"> - {workspace === null ? <span className="text-neutral-600 italic">none selected</span> : `${workspace.name} — ${workspace.root}`} - </div> - {workspaces.isError ? <ErrorLine error={workspaces.error} /> : null} - </div> - <WorkspaceDirBrowser - klient={klient} - workspaces={workspaces.data} - onSelect={selectWorkspace} - /> - </aside> - <main className="min-h-0 min-w-0 flex-1 overflow-y-auto p-4"> - <div className="mx-auto max-w-6xl space-y-4"> - <div> - <h1 className="text-sm font-semibold text-neutral-200">Filesystem Suggest</h1> - <p className="mt-1 text-[11px] text-neutral-500"> - Query file and directory completion candidates via the workspace-independent - fs:suggest API — the selected workspace supplies its root, or enter arbitrary - roots to override it. - </p> - </div> - <form - className="grid gap-3 rounded border border-neutral-800 bg-neutral-900/30 p-3 md:grid-cols-2" - onSubmit={(event) => { - event.preventDefault(); - suggest.mutate(); - }} - > - <label className="md:col-span-2"> - <span className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Roots (absolute paths, one per line or comma-separated; overrides the workspace selection) - </span> - <textarea - className="h-16 w-full resize-y rounded border border-neutral-700 bg-neutral-950 px-2 py-1.5 font-mono text-[12px] text-neutral-100 outline-none focus:border-sky-600" - value={rootsText} - onChange={(event) => setRootsText(event.target.value)} - placeholder="/abs/primary-root /abs/additional-root" - /> - </label> - <label className="md:col-span-2"> - <span className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Query - </span> - <input - autoFocus - className="w-full rounded border border-neutral-700 bg-neutral-950 px-2 py-1.5 font-mono text-[12px] text-neutral-100 outline-none focus:border-sky-600" - value={query} - onChange={(event) => setQuery(event.target.value)} - placeholder="apps/de or README" - /> - </label> - <label> - <span className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Limit - </span> - <input - className="w-full rounded border border-neutral-700 bg-neutral-950 px-2 py-1.5 font-mono text-[12px] text-neutral-100 outline-none focus:border-sky-600" - inputMode="numeric" - value={limit} - onChange={(event) => setLimit(event.target.value)} - /> - </label> - <div className="flex items-end gap-4 pb-1 text-[11px] text-neutral-300"> - <label className="flex items-center gap-1.5"> - <input - type="checkbox" - checked={followGitignore} - onChange={(event) => setFollowGitignore(event.target.checked)} - /> - follow gitignore - </label> - <label className="flex items-center gap-1.5"> - <input - type="checkbox" - checked={showHidden} - onChange={(event) => setShowHidden(event.target.checked)} - /> - show hidden - </label> - </div> - <label> - <span className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Include globs - </span> - <input - className="w-full rounded border border-neutral-700 bg-neutral-950 px-2 py-1.5 font-mono text-[11px] text-neutral-100 outline-none focus:border-sky-600" - value={includeGlobs} - onChange={(event) => setIncludeGlobs(event.target.value)} - placeholder="**/*.ts, src/**" - /> - </label> - <label> - <span className="mb-1 block text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> - Exclude globs - </span> - <input - className="w-full rounded border border-neutral-700 bg-neutral-950 px-2 py-1.5 font-mono text-[11px] text-neutral-100 outline-none focus:border-sky-600" - value={excludeGlobs} - onChange={(event) => setExcludeGlobs(event.target.value)} - placeholder="dist/**, node_modules/**" - /> - </label> - <div className="flex items-end md:col-span-2"> - <button - type="submit" - disabled={(workspace === null && parseRoots(rootsText).length === 0) || suggest.isPending} - className="rounded bg-sky-600 px-3 py-1.5 text-[12px] font-medium text-white hover:bg-sky-500 disabled:opacity-40" - > - {suggest.isPending ? 'loading…' : 'Suggest'} - </button> - {workspace === null && parseRoots(rootsText).length === 0 ? ( - <span className="ml-3 text-[11px] text-neutral-600">select a workspace or enter roots first</span> - ) : null} - </div> - </form> - {suggest.isError ? <ErrorLine error={suggest.error} /> : null} - {suggest.data === undefined && !suggest.isError ? ( - <div className="rounded border border-dashed border-neutral-800 p-6 text-center text-[12px] text-neutral-600"> - Submit a query to inspect the complete response. - </div> - ) : null} - {suggest.data !== undefined ? <SuggestResult result={suggest.data} /> : null} - </div> - </main> - </div> - ); -} - -function SuggestResult({ result }: { readonly result: FsSuggestResult }) { - return ( - <div className="space-y-3"> - <div className="flex items-center gap-2 text-[11px] text-neutral-400"> - <span>{result.items.length} items</span> - <Badge tone={result.truncated ? 'amber' : 'green'}> - {result.truncated ? 'truncated' : 'complete'} - </Badge> - </div> - <section className="overflow-x-auto rounded border border-neutral-800"> - <table className="w-full min-w-[680px] text-left text-[11px]"> - <thead className="border-b border-neutral-800 bg-neutral-900/50 text-neutral-500"> - <tr> - <th className="px-2 py-1.5">path</th> - <th className="px-2 py-1.5">name</th> - <th className="px-2 py-1.5">kind</th> - <th className="px-2 py-1.5">score</th> - <th className="px-2 py-1.5">match positions</th> - </tr> - </thead> - <tbody> - {result.items.map((item) => ( - <tr key={item.path} className="border-b border-neutral-900 last:border-0"> - <td className="px-2 py-1.5 font-mono text-neutral-200">{item.path}</td> - <td className="px-2 py-1.5 font-mono text-neutral-400">{item.name}</td> - <td className="px-2 py-1.5 text-neutral-400">{item.kind}</td> - <td className="px-2 py-1.5 font-mono text-neutral-400">{item.score}</td> - <td className="px-2 py-1.5 font-mono text-neutral-400"> - {item.matchPositions.join(', ') || '—'} - </td> - </tr> - ))} - </tbody> - </table> - {result.items.length === 0 ? ( - <div className="p-4 text-center text-[11px] text-neutral-600">no matching items</div> - ) : null} - </section> - <details className="rounded border border-neutral-800 bg-neutral-950/50"> - <summary className="cursor-pointer px-3 py-2 text-[11px] font-semibold uppercase tracking-wider text-neutral-500"> - Full JSON response - </summary> - <pre className="max-h-[420px] overflow-auto border-t border-neutral-800 p-3 text-[11px] leading-relaxed text-neutral-300"> - {JSON.stringify(result, null, 2)} - </pre> - </details> - </div> - ); -} diff --git a/apps/kimi-inspect/src/components/Inspector.tsx b/apps/kimi-inspect/src/components/Inspector.tsx index 1f9ccd1ee..0afb270a4 100644 --- a/apps/kimi-inspect/src/components/Inspector.tsx +++ b/apps/kimi-inspect/src/components/Inspector.tsx @@ -20,7 +20,6 @@ import { useEffect, useMemo, useState } from 'react'; import { serviceByName } from '../channel'; import { useConnection } from '../connection'; import { type AnyService } from '../panels'; -import { fetchAgentRuntimeBinding } from '../snapshots/api'; import { fetchTranscriptPlan, type TranscriptPlanInfo } from '../transcript/api'; import { ActionButton, Badge, ErrorLine } from '../ui'; import { ScopePanels } from './ServicePanels'; @@ -58,12 +57,6 @@ export function Inspector({ // Keep the selected agent valid as the registry changes. const effectiveAgent = agentIds.includes(agentId) ? agentId : agentIds[0]!; - const runtimeBinding = useQuery({ - queryKey: ['agent-runtime-binding', klient.baseUrl, sessionId, effectiveAgent], - queryFn: () => fetchAgentRuntimeBinding(klient, sessionId as string, effectiveAgent), - enabled: sessionId !== null && ready, - refetchInterval: 1_000, - }); useEffect(() => { if (effectiveAgent !== agentId) onAgentChange(effectiveAgent); }, [effectiveAgent, agentId, onAgentChange]); @@ -138,29 +131,6 @@ export function Inspector({ </div> ) : ( <> - <div className="mb-3 rounded border border-neutral-800 bg-neutral-950/40 p-2 text-[11px]"> - <div className="mb-1 flex items-center gap-2 font-semibold uppercase tracking-wider text-neutral-500"> - Runtime binding - {runtimeBinding.data !== undefined ? ( - <Badge tone={runtimeBinding.data.available ? 'green' : 'red'}> - {runtimeBinding.data.available ? 'available' : 'unavailable'} - </Badge> - ) : null} - </div> - <div className="grid grid-cols-[80px_minmax(0,1fr)] gap-1 font-mono"> - <span className="text-neutral-600">workspace</span> - <span className="break-all text-neutral-300">{runtimeBinding.data?.binding.workspaceId ?? 'loading…'}</span> - <span className="text-neutral-600">runtime</span> - <span className="break-all text-neutral-300">{runtimeBinding.data?.binding.runtimeId ?? 'loading…'}</span> - <span className="text-neutral-600">generation</span> - <span className="break-all text-neutral-300">{runtimeBinding.data?.runtime?.generation ?? 'unavailable'}</span> - <span className="text-neutral-600">status</span> - <span className="text-neutral-300">{runtimeBinding.data?.runtime?.status ?? 'unavailable'}</span> - <span className="text-neutral-600">capabilities</span> - <span className="text-neutral-300">{runtimeBinding.data?.runtime?.capabilities.join(', ') ?? 'none'}</span> - </div> - {runtimeBinding.isError ? <ErrorLine error={runtimeBinding.error} /> : null} - </div> <PlanCard sessionId={sessionId} agentId={effectiveAgent} /> <ScopePanels scope="agent" diff --git a/apps/kimi-inspect/src/components/InteractionsCard.tsx b/apps/kimi-inspect/src/components/InteractionsCard.tsx index c11017e3f..9bda4f056 100644 --- a/apps/kimi-inspect/src/components/InteractionsCard.tsx +++ b/apps/kimi-inspect/src/components/InteractionsCard.tsx @@ -5,45 +5,33 @@ */ import { ISessionApprovalService } from '@moonshot-ai/agent-core-v2/session/approval/approval'; +import { ISessionInteractionService } from '@moonshot-ai/agent-core-v2/session/interaction/interaction'; import { ISessionQuestionService } from '@moonshot-ai/agent-core-v2/session/question/question'; import { useState } from 'react'; import { useConnection } from '../connection'; -import { ActionButton, Badge, ErrorLine, JsonView } from '../ui'; +import { ActionButton, Badge, ErrorLine, JsonView, relTime } from '../ui'; interface PendingInteraction { readonly id: string; - /** Known kinds: 'approval' | 'question'. */ + /** Known kinds: 'approval' | 'question' | 'user_tool'; other kinds may appear. */ readonly kind: string; readonly payload: Record<string, unknown>; + readonly createdAt: number; } export function InteractionsCard({ sessionId }: { sessionId: string }) { const { klient } = useConnection(); const [pending, setPending] = useState<readonly PendingInteraction[]>([]); const [error, setError] = useState<unknown>(null); + const interaction = klient.session(sessionId).service(ISessionInteractionService); const approval = klient.session(sessionId).service(ISessionApprovalService); const question = klient.session(sessionId).service(ISessionQuestionService); const reload = async () => { try { setError(null); - const [approvals, questions] = await Promise.all([ - approval.listPending() as Promise<readonly { id: string }[]>, - question.listPending() as Promise<readonly { id: string }[]>, - ]); - setPending([ - ...approvals.map((p) => ({ - id: p.id, - kind: 'approval', - payload: p as unknown as Record<string, unknown>, - })), - ...questions.map((p) => ({ - id: p.id, - kind: 'question', - payload: p as unknown as Record<string, unknown>, - })), - ]); + setPending((await interaction.listPending()) as readonly PendingInteraction[]); } catch (error) { setError(error); } @@ -101,6 +89,7 @@ export function InteractionsCard({ sessionId }: { sessionId: string }) { <div className="mb-1 flex items-center gap-2"> <Badge tone="amber">{item.kind}</Badge> <span className="font-mono text-[10px] text-neutral-500">{item.id}</span> + <span className="text-[10px] text-neutral-600">{relTime(item.createdAt)}</span> </div> {item.kind === 'approval' ? ( <> diff --git a/apps/kimi-inspect/src/components/ModelCatalogView.tsx b/apps/kimi-inspect/src/components/ModelCatalogView.tsx index e0d1f2dd1..7d61f0f0a 100644 --- a/apps/kimi-inspect/src/components/ModelCatalogView.tsx +++ b/apps/kimi-inspect/src/components/ModelCatalogView.tsx @@ -18,7 +18,8 @@ */ import { IAgentProfileService } from '@moonshot-ai/agent-core-v2/agent/profile/profile'; -import { ISessionManager } from '@moonshot-ai/agent-core-v2/app/sessionManager/sessionManager'; +import { ISessionIndex } from '@moonshot-ai/agent-core-v2/app/sessionIndex/sessionIndex'; +import { ISessionLifecycleService } from '@moonshot-ai/agent-core-v2/workspace/sessionLifecycle/sessionLifecycle'; import type { InspectionSource } from '@moonshot-ai/agent-core-v2/kosong/contract/inspection'; import type { TokenUsage } from '@moonshot-ai/agent-core-v2/kosong/contract/usage'; import { @@ -405,7 +406,13 @@ function ModelSection({ const envelope = (await res.json()) as { code: number; msg: string; data: { id: string } }; if (envelope.code !== 0) throw new Error(envelope.msg); const sessionId = envelope.data.id; - await klient.core(ISessionManager).resume(sessionId); + const summary = await klient.core(ISessionIndex).get(sessionId); + if (summary !== undefined) { + await klient + .workspace(summary.workspaceId) + .service(ISessionLifecycleService) + .resume(sessionId); + } await klient .session(sessionId) .agent('main') diff --git a/apps/kimi-inspect/src/components/NavRail.tsx b/apps/kimi-inspect/src/components/NavRail.tsx index 6d67a2aaf..c06a646d8 100644 --- a/apps/kimi-inspect/src/components/NavRail.tsx +++ b/apps/kimi-inspect/src/components/NavRail.tsx @@ -6,15 +6,7 @@ import type { ReactNode } from 'react'; -export type AppView = - | 'chat' - | 'search' - | 'models' - | 'services' - | 'workspace' - | 'suggest' - | 'bash' - | 'di'; +export type AppView = 'chat' | 'search' | 'models' | 'services' | 'workspace' | 'bash' | 'di'; interface ViewDef { readonly id: AppView; @@ -78,23 +70,13 @@ const VIEWS: readonly ViewDef[] = [ }, { id: 'workspace', - title: 'Workspace Runtime', + title: 'Workspace Services', icon: ( <svg {...iconProps}> <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" /> </svg> ), }, - { - id: 'suggest', - title: 'Filesystem Suggest', - icon: ( - <svg {...iconProps}> - <path d="M4 4h6l2 2h8v14H4z" /> - <path d="m9 14 2 2 4-4" /> - </svg> - ), - }, { id: 'bash', title: 'Bash Parser', diff --git a/apps/kimi-inspect/src/components/RightPanel.tsx b/apps/kimi-inspect/src/components/RightPanel.tsx index 67cf31ee4..b6d5edcd7 100644 --- a/apps/kimi-inspect/src/components/RightPanel.tsx +++ b/apps/kimi-inspect/src/components/RightPanel.tsx @@ -1,16 +1,16 @@ /** * Right dock — the single right-hand column of the chat view. Merges what - * used to be three separate columns (the transcript audit panel docked - * inside the chat view, the agent inspector on the far right, and the - * session pane next to the session list) into one tabbed column: `Audit` - * replays how the visible transcript store was built, entry by entry; - * `Agent` hosts the agent switcher, the Plan lookup card, and the agent - * Service panels; `State` reads the active agent's registered plain-data - * state through `IAgentStateService.snapshot()`; `Session` embeds - * `SessionPane` (session Services / State tabs). Tabs switch with `hidden` - * instead of unmounting, so panel-local state (the audit timeline position, - * Plan lookup input/results, expanded Service panels, the state tree's open - * rows) survives tab switches. + * used to be two separate columns (the transcript audit panel docked inside + * the chat view, and the agent inspector on the far right) into one tabbed + * column: `Audit` replays how the visible transcript store was built, entry + * by entry; `Agent` hosts the agent switcher, the Plan lookup card, and the + * agent Service panels; `State` reads the active agent's registered + * plain-data state through `IAgentStateService.snapshot()` (the same live + * diff-tree view as the session State tab in `SessionPane`, shared via + * `StateCard`). Tabs switch with `hidden` instead of unmounting, so + * panel-local state (the audit timeline position, Plan lookup input/results, + * expanded Service panels, the state tree's open rows) survives tab + * switches. */ import { IAgentStateService } from '@moonshot-ai/agent-core-v2/agent/state/agentState'; @@ -21,10 +21,9 @@ import { useConnection } from '../connection'; import { Badge } from '../ui'; import { AuditPanel } from './audit/AuditPanel'; import { Inspector } from './Inspector'; -import { SessionPane } from './SessionPane'; import { StateCard } from './StateCard'; -type Tab = 'audit' | 'agent' | 'state' | 'session'; +type Tab = 'audit' | 'agent' | 'state'; export function RightPanel({ sessionId, @@ -46,7 +45,7 @@ export function RightPanel({ return ( <div className="flex h-full w-[440px] shrink-0 flex-col border-l border-neutral-800 bg-neutral-900/30"> <div className="flex border-b border-neutral-800 text-[11px]"> - {(['audit', 'agent', 'state', 'session'] as const).map((t) => ( + {(['audit', 'agent', 'state'] as const).map((t) => ( <button key={t} className={`flex-1 px-2 py-2 font-medium uppercase tracking-wider ${ @@ -54,7 +53,7 @@ export function RightPanel({ }`} onClick={() => setTab(t)} > - {t === 'audit' ? 'Audit' : t === 'agent' ? 'Agent' : t === 'state' ? 'State' : 'Session'} + {t === 'audit' ? 'Audit' : t === 'agent' ? 'Agent' : 'State'} </button> ))} </div> @@ -97,9 +96,6 @@ export function RightPanel({ )} </div> </div> - <div className={tab === 'session' ? 'flex min-h-0 flex-1 flex-col' : 'hidden'}> - <SessionPane sessionId={sessionId} ready={ready} /> - </div> </div> ); } diff --git a/apps/kimi-inspect/src/components/SessionPane.tsx b/apps/kimi-inspect/src/components/SessionPane.tsx index 8d72c349c..3469c08ee 100644 --- a/apps/kimi-inspect/src/components/SessionPane.tsx +++ b/apps/kimi-inspect/src/components/SessionPane.tsx @@ -1,23 +1,21 @@ /** - * Session pane — everything session-scoped: the pending-interactions card + * Session pane — the column right next to the session-list sidebar in the + * chat view. Hosts everything session-scoped: the pending-interactions card * and the session Service panels under the `Services` tab, plus a `State` * tab reading the session's registered plain-data state through * `ISessionStateService.snapshot()` (every key a Session Service registered - * into the session-state container, JSON-safe). Rendered as the `Session` - * tab of the chat view's right dock (`RightPanel`). The Service panels are + * into the session-state container, JSON-safe). The Service panels are * fetch-on-demand (no Service-event push channel exists); the State tab * instead auto-loads on mount and polls once a second, so it stays live * without a Refresh button. */ import { ISessionStateService } from '@moonshot-ai/agent-core-v2/session/state/sessionState'; -import { useQuery } from '@tanstack/react-query'; import { useMemo, useState } from 'react'; import { serviceByName } from '../channel'; import { useConnection } from '../connection'; import { type AnyService } from '../panels'; -import { fetchSessionWorkspaceAssociation } from '../snapshots/api'; import { InteractionsCard } from './InteractionsCard'; import { ScopePanels } from './ServicePanels'; import { StateCard } from './StateCard'; @@ -27,12 +25,6 @@ type Tab = 'services' | 'state'; export function SessionPane({ sessionId, ready }: { sessionId: string | null; ready: boolean }) { const { klient } = useConnection(); const [tab, setTab] = useState<Tab>('services'); - const association = useQuery({ - queryKey: ['session-workspace-association', klient.baseUrl, sessionId], - queryFn: () => fetchSessionWorkspaceAssociation(klient, sessionId as string), - enabled: sessionId !== null && ready, - refetchInterval: 1_000, - }); const proxyFor = useMemo(() => { return (name: string): AnyService | null => { @@ -48,7 +40,7 @@ export function SessionPane({ sessionId, ready }: { sessionId: string | null; re const blocked = sessionId === null || !ready; return ( - <div className="flex h-full min-h-0 flex-1 flex-col"> + <div className="flex h-full w-[420px] shrink-0 flex-col border-l border-neutral-800 bg-neutral-900/30"> <div className="flex border-b border-neutral-800 text-[11px]"> {(['services', 'state'] as const).map((t) => ( <button @@ -67,32 +59,19 @@ export function SessionPane({ sessionId, ready }: { sessionId: string | null; re <div className="text-[12px] text-neutral-600"> {sessionId === null ? 'No session selected.' : 'Loading session…'} </div> - ) : ( + ) : tab === 'services' ? ( <> - <div className="mb-3 rounded border border-neutral-800 bg-neutral-950/40 p-2 text-[11px]"> - <div className="mb-1 font-semibold uppercase tracking-wider text-neutral-500">Workspace association</div> - <div className="grid grid-cols-[80px_minmax(0,1fr)] gap-1 font-mono"> - <span className="text-neutral-600">workspace</span> - <span className="break-all text-neutral-300">{association.data?.workspaceId ?? 'loading…'}</span> - <span className="text-neutral-600">cwd</span> - <span className="break-all text-neutral-300">{association.data?.cwd ?? 'loading…'}</span> - </div> - </div> - {tab === 'services' ? ( - <> - <InteractionsCard sessionId={sessionId} /> - <ScopePanels scope="session" proxyFor={proxyFor} /> - </> - ) : ( - <StateCard - id={sessionId} - queryKey={['sessionState', sessionId]} - title="Session state" - label="sessionStateService" - fetchSnapshot={() => klient.session(sessionId).service(ISessionStateService).snapshot()} - /> - )} + <InteractionsCard sessionId={sessionId} /> + <ScopePanels scope="session" proxyFor={proxyFor} /> </> + ) : ( + <StateCard + id={sessionId} + queryKey={['sessionState', sessionId]} + title="Session state" + label="sessionStateService" + fetchSnapshot={() => klient.session(sessionId).service(ISessionStateService).snapshot()} + /> )} </div> </div> diff --git a/apps/kimi-inspect/src/components/Sidebar.tsx b/apps/kimi-inspect/src/components/Sidebar.tsx index b46acbcd4..4e85623b2 100644 --- a/apps/kimi-inspect/src/components/Sidebar.tsx +++ b/apps/kimi-inspect/src/components/Sidebar.tsx @@ -1,21 +1,18 @@ /** - * Left sidebar — a single-column workspace → session tree backed by the v2 - * list's grouped projection (`GET /api/v2/sessions?view=by_workspace`, see - * `src/sessions/api.ts`): one request returns every workspace with a matching - * session, each carrying its first `group.page_size` sessions under the - * requested sort plus the workspace's full matching total. Preset views + * Left sidebar — a spreadsheet-like session table backed by the v2 REST + * list (`GET /api/v2/sessions`, see `src/sessions/api.ts`). Preset views * (`src/sessions/views.ts`) map onto the endpoint's status / archived / git - * query conditions; the active view, collapsed workspaces, and the panel - * width persist to localStorage. Group pagination is the endpoint's opaque - * cursor (Load more), with a slow poll on top; a workspace whose total - * outruns the served slice expands inline into the flat per-workspace - * listing. Live activity frames (`useSessionActivities`) override the REST - * status badge. Session creation still goes through the v1 REST endpoint. + * query conditions; column visibility and the active view persist to + * localStorage; sort clicks only offer what the server sorts. Pagination is + * the endpoint's opaque cursor (Load more), with a slow poll on top. Live + * activity frames (`useSessionActivities`) override the REST status badge. + * Session creation still goes through the v1 REST endpoint. */ import { IAgentProfileService } from '@moonshot-ai/agent-core-v2/agent/profile/profile'; import { IConfigService } from '@moonshot-ai/agent-core-v2/app/config/config'; -import { ISessionManager } from '@moonshot-ai/agent-core-v2/app/sessionManager/sessionManager'; +import { ISessionIndex } from '@moonshot-ai/agent-core-v2/app/sessionIndex/sessionIndex'; +import { ISessionLifecycleService } from '@moonshot-ai/agent-core-v2/workspace/sessionLifecycle/sessionLifecycle'; import { IWorkspaceService, type Workspace, @@ -29,22 +26,49 @@ import { useSessionActivities } from '../activity/useSessionActivity'; import type { InspectClient } from '../channel'; import { useConnection } from '../connection'; import { - fetchV2SessionGroups, fetchV2SessionsPage, type V2ActivityStatus, type V2Session, - type V2SessionGroup, type V2SessionSort, } from '../sessions/api'; -import { SESSION_VIEWS, sessionViewById, type SessionView } from '../sessions/views'; +import { SESSION_VIEWS, sessionViewById } from '../sessions/views'; import { Badge, ErrorLine, relTime } from '../ui'; const STORAGE_KEY = 'kimi-inspect.session-table'; -const DEFAULT_WIDTH = 320; -const MIN_WIDTH = 240; -const MAX_WIDTH = 640; -const GROUP_PAGE_SIZE = 50; +const DEFAULT_WIDTH = 560; +const MIN_WIDTH = 380; +const MAX_WIDTH = 960; + +// --------------------------------------------------------------------------- +// Columns +// --------------------------------------------------------------------------- + +type ColumnId = 'status' | 'title' | 'workspace' | 'branch' | 'pr' | 'updated' | 'created'; + +interface ColumnDef { + readonly id: ColumnId; + readonly label: string; + readonly width: string; + /** Title is the identity column and cannot be hidden. */ + readonly hideable: boolean; +} + +const COLUMNS: readonly ColumnDef[] = [ + { id: 'status', label: 'Status', width: '76px', hideable: true }, + { id: 'title', label: 'Title', width: 'minmax(120px, 1fr)', hideable: false }, + { id: 'workspace', label: 'Workspace', width: '110px', hideable: true }, + { id: 'branch', label: 'Branch', width: '100px', hideable: true }, + { id: 'pr', label: 'PR', width: '56px', hideable: true }, + { id: 'updated', label: 'Updated', width: '72px', hideable: true }, + { id: 'created', label: 'Created', width: '72px', hideable: true }, +]; + +function defaultColumns(includeGit: boolean): readonly ColumnId[] { + return includeGit + ? ['status', 'title', 'workspace', 'branch', 'pr', 'updated'] + : ['status', 'title', 'workspace', 'updated']; +} // --------------------------------------------------------------------------- // Persisted panel prefs @@ -52,8 +76,8 @@ const GROUP_PAGE_SIZE = 50; interface PanelPrefs { readonly view?: string; - /** Collapsed workspace ids; absent = everything expanded. */ - readonly collapsed?: readonly string[]; + /** Visible columns per view id; absent = the view's defaults. */ + readonly columns?: Record<string, readonly ColumnId[]>; readonly width?: number; } @@ -92,12 +116,6 @@ const STATUS_TONES: Record<V2ActivityStatus, 'green' | 'amber' | 'sky' | 'red' | idle: 'neutral', }; -const SORTS: readonly { readonly id: V2SessionSort; readonly label: string }[] = [ - { id: 'meta.updated_at_desc', label: 'Updated ↓' }, - { id: 'meta.updated_at_asc', label: 'Updated ↑' }, - { id: 'meta.created_at_desc', label: 'Created ↓' }, -]; - /** * Default model for a fresh session: the configured global `defaultModel` * first (the same fallback the profile bind uses), then the first connected @@ -131,8 +149,8 @@ export function Sidebar({ const [prefs, setPrefs] = useState<PanelPrefs>(readPrefs); const view = sessionViewById(prefs.view); const [sort, setSort] = useState<V2SessionSort>('meta.updated_at_desc'); + const visibleColumns = prefs.columns?.[view.id] ?? defaultColumns(view.includeGit === true); const width = prefs.width ?? DEFAULT_WIDTH; - const collapsed = useMemo(() => new Set(prefs.collapsed ?? []), [prefs.collapsed]); const updatePrefs = (patch: PanelPrefs) => { setPrefs((prev) => { @@ -142,15 +160,14 @@ export function Sidebar({ }); }; - const toggleCollapsed = (workspaceId: string) => { - const next = new Set(collapsed); - if (next.has(workspaceId)) next.delete(workspaceId); - else next.add(workspaceId); - updatePrefs({ collapsed: [...next] }); + const toggleColumn = (column: ColumnId) => { + const next = visibleColumns.includes(column) + ? visibleColumns.filter((c) => c !== column) + : COLUMNS.map((c) => c.id).filter((c) => c === column || visibleColumns.includes(c)); + updatePrefs({ columns: { ...prefs.columns, [view.id]: next } }); }; const token = config.token.trim(); - const authToken = token === '' ? undefined : token; const workspaces = useQuery({ queryKey: ['workspaces'], @@ -162,18 +179,17 @@ export function Sidebar({ [workspaces.data], ); - const groups = useInfiniteQuery({ - queryKey: ['v2-sessions', 'tree', view.id, sort], + const sessions = useInfiniteQuery({ + queryKey: ['v2-sessions', view.id, sort], queryFn: ({ pageParam }) => - fetchV2SessionGroups({ + fetchV2SessionsPage({ baseUrl, - token: authToken, + token: token === '' ? undefined : token, statuses: view.statuses, archived: view.archived, includeGit: view.includeGit, sort, pageSize: 50, - groupPageSize: GROUP_PAGE_SIZE, pageToken: pageParam, }), initialPageParam: undefined as string | undefined, @@ -181,10 +197,7 @@ export function Sidebar({ refetchInterval: 15_000, }); - const groupList = useMemo( - () => groups.data?.pages.flatMap((page) => page.groups) ?? [], - [groups.data], - ); + const items = useMemo(() => sessions.data?.pages.flatMap((page) => page.items) ?? [], [sessions.data]); const createSession = async (ws: Workspace | null) => { // With a workspace, the server derives workDir from workspace.root, so no cwd is needed. @@ -216,7 +229,13 @@ export function Sidebar({ try { const model = await resolveDefaultModel(klient); if (model !== undefined) { - await klient.core(ISessionManager).resume(sessionId); + const summary = await klient.core(ISessionIndex).get(sessionId); + if (summary !== undefined) { + await klient + .workspace(summary.workspaceId) + .service(ISessionLifecycleService) + .resume(sessionId); + } await klient.session(sessionId).agent('main').service(IAgentProfileService).setModel(model); } } catch (error) { @@ -226,9 +245,15 @@ export function Sidebar({ onSelectSession(sessionId); }; - const cycleSort = () => { - const index = SORTS.findIndex((s) => s.id === sort); - setSort(SORTS[(index + 1) % SORTS.length]!.id); + const visibleDefs = COLUMNS.filter((c) => visibleColumns.includes(c.id)); + const gridTemplate = visibleDefs.map((c) => c.width).join(' '); + + const onSortClick = (column: ColumnId) => { + if (column === 'updated') { + setSort((s) => (s === 'meta.updated_at_desc' ? 'meta.updated_at_asc' : 'meta.updated_at_desc')); + } else if (column === 'created') { + setSort('meta.created_at_desc'); + } }; const startResize = (e: React.MouseEvent) => { @@ -271,50 +296,67 @@ export function Sidebar({ ))} </div> - {/* Toolbar: new session + sort */} + {/* Toolbar: new session + column config */} <div className="flex items-center justify-between border-b border-neutral-800 px-2 py-1"> <NewSessionMenu workspaces={workspaces.data ?? []} onCreate={createSession} /> - <button - className="rounded border border-neutral-700 px-2 py-0.5 text-[11px] text-neutral-400 hover:bg-neutral-800" - title="Click to change sort" - onClick={cycleSort} - > - {SORTS.find((s) => s.id === sort)?.label} - </button> + <ColumnMenu + visible={visibleColumns} + onToggle={toggleColumn} + /> </div> - {/* Tree body */} + {/* Header row */} + <div + className="grid items-center gap-2 border-b border-neutral-800 px-3 py-1.5 text-[10px] font-semibold uppercase tracking-wider text-neutral-500" + style={{ gridTemplateColumns: gridTemplate }} + > + {visibleDefs.map((c) => { + const sortable = c.id === 'updated' || c.id === 'created'; + const activeSort = + (c.id === 'updated' && sort !== 'meta.created_at_desc') || + (c.id === 'created' && sort === 'meta.created_at_desc'); + return ( + <div + key={c.id} + className={`truncate ${sortable ? 'cursor-pointer select-none hover:text-neutral-300' : ''} ${ + activeSort ? 'text-neutral-300' : '' + }`} + onClick={sortable ? () => onSortClick(c.id) : undefined} + title={sortable ? 'Click to change sort' : undefined} + > + {c.label} + {activeSort ? (sort === 'meta.updated_at_asc' ? ' ↑' : ' ↓') : null} + </div> + ); + })} + </div> + + {/* Body */} <div className="flex-1 overflow-y-auto"> - {groups.isError ? <ErrorLine error={groups.error} /> : null} - {groupList.map((group) => ( - <WorkspaceNode - key={group.workspace.id} - group={group} - view={view} - sort={sort} - collapsed={collapsed.has(group.workspace.id)} - onToggleCollapsed={() => toggleCollapsed(group.workspace.id)} - workspaceNames={workspaceNames} - activeSessionId={activeSessionId} - activityOf={(id) => activities.get(id)} - onSelect={onSelectSession} - baseUrl={baseUrl} - token={authToken} - /> - ))} - {groups.isLoading ? ( + {sessions.isError ? <ErrorLine error={sessions.error} /> : null} + <SessionRows + items={items} + gridTemplate={gridTemplate} + visibleDefs={visibleDefs} + groupByWorkspace={view.groupByWorkspace === true} + workspaceNames={workspaceNames} + activeSessionId={activeSessionId} + activityOf={(id) => activities.get(id)} + onSelect={onSelectSession} + /> + {sessions.isLoading ? ( <div className="px-3 py-2 text-[11px] text-neutral-600">loading…</div> ) : null} - {!groups.isLoading && groupList.length === 0 && !groups.isError ? ( + {!sessions.isLoading && items.length === 0 && !sessions.isError ? ( <div className="px-3 py-2 text-[11px] text-neutral-600">no sessions</div> ) : null} - {groups.hasNextPage ? ( + {sessions.hasNextPage ? ( <button className="w-full border-t border-neutral-800 px-3 py-1.5 text-[11px] text-sky-500 hover:bg-neutral-800/60 hover:text-sky-400" - disabled={groups.isFetchingNextPage} - onClick={() => void groups.fetchNextPage()} + disabled={sessions.isFetchingNextPage} + onClick={() => void sessions.fetchNextPage()} > - {groups.isFetchingNextPage ? 'loading…' : 'Load more workspaces'} + {sessions.isFetchingNextPage ? 'loading…' : 'Load more'} </button> ) : null} </div> @@ -329,203 +371,137 @@ export function Sidebar({ } // --------------------------------------------------------------------------- -// Tree nodes +// Rows // --------------------------------------------------------------------------- -function WorkspaceNode({ - group, - view, - sort, - collapsed, - onToggleCollapsed, +function SessionRows({ + items, + gridTemplate, + visibleDefs, + groupByWorkspace, workspaceNames, activeSessionId, activityOf, onSelect, - baseUrl, - token, }: { - group: V2SessionGroup; - view: SessionView; - sort: V2SessionSort; - collapsed: boolean; - onToggleCollapsed: () => void; + items: readonly V2Session[]; + gridTemplate: string; + visibleDefs: readonly ColumnDef[]; + groupByWorkspace: boolean; workspaceNames: ReadonlyMap<string, string>; activeSessionId: string | null; activityOf: (sessionId: string) => SessionWorkFacts | undefined; onSelect: (sessionId: string) => void; - baseUrl: string; - token?: string | undefined; }) { - const [showAll, setShowAll] = useState(false); - const hasMore = group.total > group.sessions.length; + if (!groupByWorkspace) { + return ( + <> + {items.map((s) => ( + <SessionRow + key={s.id} + s={s} + gridTemplate={gridTemplate} + visibleDefs={visibleDefs} + workspaceNames={workspaceNames} + active={s.id === activeSessionId} + activity={activityOf(s.id)} + onClick={() => onSelect(s.id)} + /> + ))} + </> + ); + } + + const groups = new Map<string, V2Session[]>(); + for (const s of items) { + const list = groups.get(s.workspace.id); + if (list === undefined) groups.set(s.workspace.id, [s]); + else list.push(s); + } return ( - <div> - <div - className="flex cursor-pointer items-center gap-1.5 border-b border-neutral-800 px-2 py-1.5 select-none hover:bg-neutral-800/60" - onClick={onToggleCollapsed} - title={group.workspace.cwd ?? group.workspace.id} - > - <span className="w-3 shrink-0 text-center text-[9px] text-neutral-600"> - {collapsed ? '▸' : '▾'} - </span> - <span className="min-w-0 flex-1 truncate text-[11px] font-semibold text-neutral-300"> - {workspaceNames.get(group.workspace.id) ?? group.workspace.cwd ?? group.workspace.id} - </span> - <span className="shrink-0 text-[10px] text-neutral-600">{group.total}</span> - </div> - {collapsed ? null : ( - <> - {showAll ? null : ( - <> - {group.sessions.map((s) => ( - <SessionNode - key={s.id} - s={s} - active={s.id === activeSessionId} - activity={activityOf(s.id)} - onClick={() => onSelect(s.id)} - /> - ))} - {hasMore ? ( - <button - className="w-full border-b border-neutral-800/50 py-1 pl-6 text-left text-[10px] text-sky-500 hover:bg-neutral-800/60 hover:text-sky-400" - onClick={() => setShowAll(true)} - > - Show all {group.total}… - </button> - ) : null} - </> - )} - {showAll ? ( - <FullGroupList - workspaceId={group.workspace.id} - view={view} - sort={sort} - baseUrl={baseUrl} - token={token} - activeSessionId={activeSessionId} - activityOf={activityOf} - onSelect={onSelect} + <> + {[...groups.entries()].map(([workspaceId, sessions]) => ( + <div key={workspaceId}> + <div className="sticky top-0 border-b border-neutral-800 bg-neutral-900 px-3 py-1 text-[10px] font-semibold uppercase tracking-wider text-neutral-400"> + {workspaceNames.get(workspaceId) ?? sessions[0]?.workspace.cwd ?? workspaceId} + <span className="ml-1 text-neutral-600">{sessions.length}</span> + </div> + {sessions.map((s) => ( + <SessionRow + key={s.id} + s={s} + gridTemplate={gridTemplate} + visibleDefs={visibleDefs} + workspaceNames={workspaceNames} + active={s.id === activeSessionId} + activity={activityOf(s.id)} + onClick={() => onSelect(s.id)} /> - ) : null} - </> - )} - </div> - ); -} - -/** - * The flat per-workspace listing behind "Show all" — pages the ungrouped - * projection filtered to this workspace, so sessions beyond the grouped - * slice stay reachable. - */ -function FullGroupList({ - workspaceId, - view, - sort, - baseUrl, - token, - activeSessionId, - activityOf, - onSelect, -}: { - workspaceId: string; - view: SessionView; - sort: V2SessionSort; - baseUrl: string; - token?: string | undefined; - activeSessionId: string | null; - activityOf: (sessionId: string) => SessionWorkFacts | undefined; - onSelect: (sessionId: string) => void; -}) { - const sessions = useInfiniteQuery({ - queryKey: ['v2-sessions', 'tree-full', workspaceId, view.id, sort], - queryFn: ({ pageParam }) => - fetchV2SessionsPage({ - baseUrl, - token, - workspaceIds: [workspaceId], - statuses: view.statuses, - archived: view.archived, - includeGit: view.includeGit, - sort, - pageSize: 50, - pageToken: pageParam, - }), - initialPageParam: undefined as string | undefined, - getNextPageParam: (last) => last.nextPageToken, - }); - const seen = new Set<string>(); - const items = (sessions.data?.pages.flatMap((page) => page.items) ?? []).filter((s) => { - if (seen.has(s.id)) return false; - seen.add(s.id); - return true; - }); - return ( - <div className="bg-neutral-950/40"> - {items.map((s) => ( - <SessionNode - key={s.id} - s={s} - active={s.id === activeSessionId} - activity={activityOf(s.id)} - onClick={() => onSelect(s.id)} - /> + ))} + </div> ))} - {sessions.isLoading ? ( - <div className="py-1 pl-6 text-[10px] text-neutral-600">loading…</div> - ) : null} - {sessions.hasNextPage ? ( - <button - className="w-full py-1 pl-6 text-left text-[10px] text-sky-500 hover:bg-neutral-800/60 hover:text-sky-400" - disabled={sessions.isFetchingNextPage} - onClick={() => void sessions.fetchNextPage()} - > - {sessions.isFetchingNextPage ? 'loading…' : 'Load more'} - </button> - ) : null} - </div> + </> ); } -function SessionNode({ +function SessionRow({ s, + gridTemplate, + visibleDefs, + workspaceNames, active, activity, onClick, }: { s: V2Session; + gridTemplate: string; + visibleDefs: readonly ColumnDef[]; + workspaceNames: ReadonlyMap<string, string>; active: boolean; activity?: SessionWorkFacts | undefined; onClick: () => void; }) { const status = liveStatus(activity) ?? s.activity.status; - return ( - <div - className={`cursor-pointer border-b border-neutral-800/50 py-1 pr-2 pl-6 hover:bg-neutral-800/60 ${ - active ? 'bg-sky-950/60' : '' - }`} - onClick={onClick} - > - <div className="flex items-center gap-1.5"> - {status === 'idle' ? null : <Badge tone={STATUS_TONES[status]}>{status}</Badge>} - <span className="min-w-0 flex-1 truncate text-[12px] text-neutral-200"> - {s.meta.title ?? s.meta.lastPrompt ?? s.id} - </span> - {s.meta.archived ? <Badge tone="neutral">archived</Badge> : null} - <span className="shrink-0 text-[10px] text-neutral-500">{relTime(s.meta.updatedAt)}</span> - </div> - <div className="flex items-center gap-2 truncate font-mono text-[10px] text-neutral-600"> - <span className="truncate">{s.id.slice(0, 12)}</span> - {s.git !== undefined && s.git.branch !== null ? ( - <span className="truncate" title={s.git.branch}> + const cell = (id: ColumnId): React.ReactNode => { + switch (id) { + case 'status': + return status === 'idle' ? ( + <span className="text-neutral-700">—</span> + ) : ( + <Badge tone={STATUS_TONES[status]}>{status}</Badge> + ); + case 'title': + return ( + <div className="min-w-0"> + <div className="flex items-center gap-1.5"> + <span className="min-w-0 flex-1 truncate text-[12px] text-neutral-200"> + {s.meta.title ?? s.meta.lastPrompt ?? s.id} + </span> + {s.meta.archived ? <Badge tone="neutral">archived</Badge> : null} + </div> + <div className="truncate font-mono text-[10px] text-neutral-600"> + {s.id.slice(0, 12)} + </div> + </div> + ); + case 'workspace': + return ( + <span className="truncate" title={s.workspace.cwd ?? s.workspace.id}> + {workspaceNames.get(s.workspace.id) ?? s.workspace.cwd ?? s.workspace.id.slice(0, 8)} + </span> + ); + case 'branch': + return s.git !== undefined && s.git.branch !== null ? ( + <span className="truncate font-mono" title={s.git.branch}> {s.git.branch} </span> - ) : null} - {s.git !== undefined && s.git.pullRequest !== null ? ( + ) : ( + <span className="text-neutral-700">—</span> + ); + case 'pr': + return s.git !== undefined && s.git.pullRequest !== null ? ( <a - className="shrink-0 text-sky-500 hover:text-sky-400" + className="truncate text-sky-500 hover:text-sky-400" href={s.git.pullRequest.url} target="_blank" rel="noreferrer" @@ -533,8 +509,28 @@ function SessionNode({ > #{s.git.pullRequest.number} </a> - ) : null} - </div> + ) : ( + <span className="text-neutral-700">—</span> + ); + case 'updated': + return <span className="text-neutral-500">{relTime(s.meta.updatedAt)}</span>; + case 'created': + return <span className="text-neutral-500">{relTime(s.meta.createdAt)}</span>; + } + }; + return ( + <div + className={`grid cursor-pointer items-center gap-2 border-b border-neutral-800/50 px-3 py-1.5 text-[11px] text-neutral-300 hover:bg-neutral-800/60 ${ + active ? 'bg-sky-950/60' : '' + }`} + style={{ gridTemplateColumns: gridTemplate }} + onClick={onClick} + > + {visibleDefs.map((c) => ( + <div key={c.id} className="min-w-0 truncate"> + {cell(c.id)} + </div> + ))} </div> ); } @@ -600,3 +596,44 @@ function NewSessionMenu({ </div> ); } + +function ColumnMenu({ + visible, + onToggle, +}: { + visible: readonly ColumnId[]; + onToggle: (column: ColumnId) => void; +}) { + const { open, toggle, close } = useDropdown(); + const hideable = COLUMNS.filter((c) => c.hideable); + return ( + <div className="relative"> + <button + className="rounded border border-neutral-700 px-2 py-0.5 text-[11px] text-neutral-400 hover:bg-neutral-800" + onClick={toggle} + > + Columns + </button> + {open ? ( + <> + <div className="fixed inset-0 z-10" onClick={close} /> + <div className="absolute right-0 z-20 mt-1 w-40 rounded border border-neutral-700 bg-neutral-900 py-1 shadow-xl"> + {hideable.map((c) => ( + <label + key={c.id} + className="flex cursor-pointer items-center gap-2 px-3 py-1 text-[11px] text-neutral-200 hover:bg-neutral-800" + > + <input + type="checkbox" + checked={visible.includes(c.id)} + onChange={() => onToggle(c.id)} + /> + {c.label} + </label> + ))} + </div> + </> + ) : null} + </div> + ); +} diff --git a/apps/kimi-inspect/src/components/WorkspaceDirBrowser.tsx b/apps/kimi-inspect/src/components/WorkspaceDirBrowser.tsx index 1dd38a5d2..e9aee3c40 100644 --- a/apps/kimi-inspect/src/components/WorkspaceDirBrowser.tsx +++ b/apps/kimi-inspect/src/components/WorkspaceDirBrowser.tsx @@ -19,11 +19,11 @@ import { IWorkspaceService, type Workspace, } from '@moonshot-ai/agent-core-v2/app/workspace/workspace'; +import { IWorkspaceTrust } from '@moonshot-ai/agent-core-v2/workspace/workspaceTrust/workspaceTrust'; import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; import { useState } from 'react'; import type { InspectClient } from '../channel'; -import { fetchWorkspaceSnapshot } from '../snapshots/api'; import { ErrorLine } from '../ui'; function normalizePath(path: string): string { @@ -75,8 +75,8 @@ export function WorkspaceDirBrowser(props: { const entries = await Promise.all( workspaceList.map(async (ws) => { try { - const snapshot = await fetchWorkspaceSnapshot(klient, ws.id); - return [normalizePath(ws.root), snapshot.program.trusted] as const; + const trusted = await klient.workspace(ws.id).service(IWorkspaceTrust).get(); + return [normalizePath(ws.root), trusted] as const; } catch { return [normalizePath(ws.root), undefined] as const; } diff --git a/apps/kimi-inspect/src/components/WorkspaceServicesView.tsx b/apps/kimi-inspect/src/components/WorkspaceServicesView.tsx index a3a65e881..4b094c924 100644 --- a/apps/kimi-inspect/src/components/WorkspaceServicesView.tsx +++ b/apps/kimi-inspect/src/components/WorkspaceServicesView.tsx @@ -13,11 +13,13 @@ import { IWorkspaceService } from '@moonshot-ai/agent-core-v2/app/workspace/workspace'; import { useQuery } from '@tanstack/react-query'; -import { useEffect, useState, type ReactNode } from 'react'; +import { useCallback, useEffect, useState } from 'react'; +import { serviceByName } from '../channel'; import { useConnection } from '../connection'; -import { fetchWorkspaceSnapshot } from '../snapshots/api'; -import { Badge, ErrorLine } from '../ui'; +import type { AnyService } from '../panels'; +import { ErrorLine } from '../ui'; +import { ScopePanelsScrollspy } from './ServicePanels'; import { WorkspaceDirBrowser } from './WorkspaceDirBrowser'; export function WorkspaceServicesView() { @@ -28,19 +30,22 @@ export function WorkspaceServicesView() { queryKey: ['workspaces', klient.baseUrl], queryFn: () => klient.core(IWorkspaceService).list(), }); - const snapshot = useQuery({ - queryKey: ['workspace-snapshot', klient.baseUrl, workspaceId], - queryFn: () => fetchWorkspaceSnapshot(klient, workspaceId as string), - enabled: workspaceId !== null, - refetchInterval: 1_000, - }); + // Switching servers invalidates the selection: workspaces belong to the + // server they were listed from. useEffect(() => { setWorkspaceId(null); }, [baseUrl]); const selected = (workspaces.data ?? []).find((ws) => ws.id === workspaceId); - const data = snapshot.data; + + const proxyFor = useCallback( + (name: string): AnyService | null => + workspaceId === null + ? null + : (serviceByName<AnyService>(klient, name, { scope: 'workspace', workspaceId }) ?? null), + [klient, workspaceId], + ); return ( <div className="flex min-h-0 min-w-0 flex-1"> @@ -49,7 +54,10 @@ export function WorkspaceServicesView() { <div className="text-[10px] font-semibold uppercase tracking-wider text-neutral-500"> Workspace </div> - <div title={selected?.root} className="truncate font-mono text-[11px] text-neutral-300"> + <div + title={selected?.root} + className="truncate font-mono text-[11px] text-neutral-300" + > {selected === undefined ? ( <span className="text-neutral-600 italic">none selected</span> ) : ( @@ -61,78 +69,25 @@ export function WorkspaceServicesView() { <WorkspaceDirBrowser klient={klient} workspaces={workspaces.data} - onSelect={(workspace) => setWorkspaceId(workspace.id)} + onSelect={(workspace) => { + setWorkspaceId(workspace.id); + }} /> </aside> - <div className="min-h-0 min-w-0 flex-1 overflow-y-auto p-4"> + <div className="flex min-h-0 min-w-0 flex-1 flex-col"> {workspaceId === null ? ( - <div className="flex h-full items-center justify-center text-[12px] text-neutral-600 italic"> - select a workspace to inspect + <div className="flex flex-1 items-center justify-center p-6 text-[12px] text-neutral-600 italic"> + select a workspace to inspect its Services </div> - ) : snapshot.isError ? ( - <ErrorLine error={snapshot.error} /> - ) : data === undefined ? ( - <div className="text-[12px] text-neutral-600">loading workspace snapshot…</div> ) : ( - <div className="space-y-4"> - <SnapshotPanel title="Workspace"> - <SnapshotRow label="id" value={data.metadata.id} /> - <SnapshotRow label="name" value={data.metadata.name} /> - <SnapshotRow label="root" value={data.metadata.root} /> - <SnapshotRow label="lifecycle" value={<Badge tone="sky">{data.lifecycle}</Badge>} /> - </SnapshotPanel> - <SnapshotPanel title="Program"> - <SnapshotRow label="binding" value={`${data.program.binding.workspaceId} / ${data.program.binding.runtimeId}`} /> - <SnapshotRow label="status" value={<Badge tone={data.program.status === 'ready' ? 'green' : 'neutral'}>{data.program.status}</Badge>} /> - <SnapshotRow label="ready" value={String(data.program.ready)} /> - <SnapshotRow label="generation" value={data.program.generation ?? 'unavailable'} /> - <SnapshotRow label="trusted" value={data.program.trusted === undefined ? 'unknown' : String(data.program.trusted)} /> - <SnapshotRow label="skills" value={`${data.program.catalog.skills.total} total / ${data.program.catalog.skills.invocable} invocable / ${data.program.catalog.skills.skipped} skipped`} /> - <SnapshotRow label="agent profiles" value={String(data.program.catalog.agentProfiles)} /> - <SnapshotRow label="MCP servers" value={String(data.program.catalog.mcpServers)} /> - </SnapshotPanel> - <SnapshotPanel title="Runtimes"> - {data.runtimes.runtimes.length === 0 ? ( - <div className="text-[11px] text-neutral-600">no current generations</div> - ) : data.runtimes.runtimes.map((runtime) => ( - <div key={`${runtime.runtimeId}:${runtime.generation}`} className="rounded border border-neutral-800 bg-neutral-950/40 p-2"> - <div className="mb-1 flex items-center gap-2"> - <span className="font-mono text-[12px] text-neutral-200">{runtime.runtimeId}</span> - <Badge tone={runtime.status === 'ready' ? 'green' : 'neutral'}>{runtime.status}</Badge> - </div> - <SnapshotRow label="generation" value={runtime.generation} /> - <SnapshotRow label="capabilities" value={runtime.capabilities.join(', ') || 'none'} /> - </div> - ))} - </SnapshotPanel> - <SnapshotPanel title="Source provenance"> - <SnapshotRow label="skills" value={data.program.sources.skills.map((source) => `${source.source}:${source.count}`).join(', ') || 'none'} /> - <SnapshotRow label="skill roots" value={data.program.sources.skillRoots.join(', ') || 'none'} /> - <SnapshotRow label="agent profiles" value={data.program.sources.agentProfiles.map((source) => `${source.sourceId}:${source.profiles.join('|')}`).join(', ') || 'none'} /> - <SnapshotRow label="instructions" value={data.program.sources.instructionPaths.join(', ') || 'none'} /> - <SnapshotRow label="MCP" value={data.program.sources.mcpServers.join(', ') || 'none'} /> - </SnapshotPanel> - </div> + <ScopePanelsScrollspy + key={workspaceId} + scope="workspace" + title="Workspace Services" + proxyFor={proxyFor} + /> )} </div> </div> ); } - -function SnapshotPanel({ title, children }: { readonly title: string; readonly children: ReactNode }) { - return ( - <section className="rounded border border-neutral-800 bg-neutral-900/30 p-3"> - <h2 className="mb-2 text-[11px] font-semibold uppercase tracking-wider text-neutral-400">{title}</h2> - <div className="space-y-1">{children}</div> - </section> - ); -} - -function SnapshotRow({ label, value }: { readonly label: string; readonly value: ReactNode }) { - return ( - <div className="grid grid-cols-[120px_minmax(0,1fr)] gap-2 text-[11px]"> - <span className="text-neutral-600">{label}</span> - <span className="min-w-0 break-all font-mono text-neutral-300">{value}</span> - </div> - ); -} diff --git a/apps/kimi-inspect/src/fs/api.test.ts b/apps/kimi-inspect/src/fs/api.test.ts deleted file mode 100644 index 362c2956c..000000000 --- a/apps/kimi-inspect/src/fs/api.test.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import { fetchFsSuggest } from './api'; - -function okEnvelope(data: unknown) { - return { code: 0, msg: 'success', data, request_id: 'r1' }; -} - -function fakeFetch(envelope: unknown) { - const calls: { url: string; init?: RequestInit }[] = []; - const fetchImpl = (async (url: string | URL, init?: RequestInit) => { - calls.push({ url: String(url), init }); - return { json: async () => envelope }; - }) as unknown as typeof fetch; - return { calls, fetchImpl }; -} - -const resultData = { - items: [ - { - path: 'apps/desktop', - name: 'desktop', - kind: 'directory', - score: 0.9, - match_positions: [5, 6], - }, - { path: 'README.md', name: 'README.md', kind: 'file', score: 0.8, match_positions: [0, 1] }, - { path: 'broken' }, - ], - truncated: true, -}; - -describe('fetchFsSuggest', () => { - it('posts the roots suggestion request and maps items', async () => { - const { calls, fetchImpl } = fakeFetch(okEnvelope(resultData)); - const result = await fetchFsSuggest({ - baseUrl: 'http://h:1/', - token: 'tok', - roots: ['/repo', '/extra'], - query: 'apps/de', - limit: 20, - followGitignore: false, - showHidden: true, - includeGlobs: ['**/*.ts'], - excludeGlobs: ['dist/**'], - runtimeId: 'local', - fetchImpl, - }); - - expect(calls[0]!.url).toBe('http://h:1/api/v1/fs:suggest'); - expect(calls[0]!.init?.method).toBe('POST'); - expect(calls[0]!.init?.headers).toEqual({ - 'content-type': 'application/json', - authorization: 'Bearer tok', - }); - expect(JSON.parse(calls[0]!.init?.body as string)).toEqual({ - roots: ['/repo', '/extra'], - query: 'apps/de', - limit: 20, - follow_gitignore: false, - show_hidden: true, - include_globs: ['**/*.ts'], - exclude_globs: ['dist/**'], - runtime_id: 'local', - }); - expect(result.items).toHaveLength(2); - expect(result.items[0]).toEqual({ - path: 'apps/desktop', - name: 'desktop', - kind: 'directory', - score: 0.9, - matchPositions: [5, 6], - }); - expect(result.truncated).toBe(true); - }); - - it('omits optional fields and authorization when not configured', async () => { - const { calls, fetchImpl } = fakeFetch(okEnvelope({ items: [], truncated: false })); - await fetchFsSuggest({ baseUrl: 'http://h:1', roots: ['/repo'], query: '', fetchImpl }); - expect(calls[0]!.init?.headers).toEqual({ 'content-type': 'application/json' }); - expect(JSON.parse(calls[0]!.init?.body as string)).toEqual({ - roots: ['/repo'], - query: '', - }); - }); - - it('throws on a non-zero envelope code', async () => { - const { fetchImpl } = fakeFetch({ code: 40409, msg: 'root missing', data: null }); - await expect( - fetchFsSuggest({ baseUrl: 'http://h:1', roots: ['/missing'], query: 'x', fetchImpl }), - ).rejects.toThrow(/40409/); - }); - - it('throws on a malformed payload', async () => { - const { fetchImpl } = fakeFetch(okEnvelope({ truncated: false })); - await expect( - fetchFsSuggest({ baseUrl: 'http://h:1', roots: ['/repo'], query: 'x', fetchImpl }), - ).rejects.toThrow(/unexpected response shape/); - }); -}); diff --git a/apps/kimi-inspect/src/fs/api.ts b/apps/kimi-inspect/src/fs/api.ts deleted file mode 100644 index 7d994e9ab..000000000 --- a/apps/kimi-inspect/src/fs/api.ts +++ /dev/null @@ -1,96 +0,0 @@ -export type FsSuggestKind = 'file' | 'directory' | 'symlink'; - -export interface FsSuggestItem { - readonly path: string; - readonly name: string; - readonly kind: FsSuggestKind; - readonly score: number; - readonly matchPositions: readonly number[]; -} - -export interface FsSuggestResult { - readonly items: readonly FsSuggestItem[]; - readonly truncated: boolean; -} - -export interface FetchFsSuggestOptions { - readonly baseUrl: string; - readonly token?: string; - readonly roots: readonly string[]; - readonly query: string; - readonly limit?: number; - readonly followGitignore?: boolean; - readonly showHidden?: boolean; - readonly includeGlobs?: readonly string[]; - readonly excludeGlobs?: readonly string[]; - readonly runtimeId?: string; - readonly fetchImpl?: typeof fetch; -} - -const KINDS = new Set<FsSuggestKind>(['file', 'directory', 'symlink']); - -function parseItem(value: unknown): FsSuggestItem | undefined { - if (value === null || typeof value !== 'object' || Array.isArray(value)) return undefined; - const item = value as Record<string, unknown>; - if ( - typeof item['path'] !== 'string' || - typeof item['name'] !== 'string' || - typeof item['kind'] !== 'string' || - !KINDS.has(item['kind'] as FsSuggestKind) || - typeof item['score'] !== 'number' || - !Array.isArray(item['match_positions']) || - !item['match_positions'].every((position) => typeof position === 'number') - ) { - return undefined; - } - return { - path: item['path'], - name: item['name'], - kind: item['kind'] as FsSuggestKind, - score: item['score'], - matchPositions: item['match_positions'] as number[], - }; -} - -async function postSuggest( - body: Record<string, unknown>, - opts: { baseUrl: string; token?: string; fetchImpl?: typeof fetch }, -): Promise<FsSuggestResult> { - const headers: Record<string, string> = { 'content-type': 'application/json' }; - if (opts.token !== undefined && opts.token !== '') { - headers['authorization'] = `Bearer ${opts.token}`; - } - const doFetch = opts.fetchImpl ?? fetch; - const res = await doFetch(`${opts.baseUrl.replace(/\/$/, '')}/api/v1/fs:suggest`, { - method: 'POST', - headers, - body: JSON.stringify(body), - }); - const envelope = (await res.json()) as { code: number; msg: string; data: unknown }; - if (envelope.code !== 0) { - throw new Error(`fs:suggest failed (${envelope.code}): ${envelope.msg}`); - } - const data = envelope.data as Record<string, unknown> | null; - if (data === null || typeof data !== 'object' || !Array.isArray(data['items'])) { - throw new Error('fs:suggest: unexpected response shape'); - } - return { - items: (data['items'] as unknown[]) - .map(parseItem) - .filter((item): item is FsSuggestItem => item !== undefined), - truncated: data['truncated'] === true, - }; -} - -export async function fetchFsSuggest(opts: FetchFsSuggestOptions): Promise<FsSuggestResult> { - return postSuggest({ - roots: [...opts.roots], - query: opts.query, - limit: opts.limit, - follow_gitignore: opts.followGitignore, - show_hidden: opts.showHidden, - include_globs: opts.includeGlobs, - exclude_globs: opts.excludeGlobs, - runtime_id: opts.runtimeId, - }, opts); -} diff --git a/apps/kimi-inspect/src/panels.ts b/apps/kimi-inspect/src/panels.ts index c2c298dc1..51e66304a 100644 --- a/apps/kimi-inspect/src/panels.ts +++ b/apps/kimi-inspect/src/panels.ts @@ -17,21 +17,26 @@ */ import { IAgentActivityView } from '@moonshot-ai/agent-core-v2/agent/activityView/activityView'; +import { IAgentGoalService } from '@moonshot-ai/agent-core-v2/agent/goal/goal'; import { IAgentMcpService } from '@moonshot-ai/agent-core-v2/agent/mcp/mcp'; import { IAgentPermissionModeService } from '@moonshot-ai/agent-core-v2/agent/permissionMode/permissionMode'; import { IAgentPermissionRulesService } from '@moonshot-ai/agent-core-v2/agent/permissionRules/permissionRules'; import { IAgentPlanService } from '@moonshot-ai/agent-core-v2/features/plan/plan'; import { IAgentProfileService } from '@moonshot-ai/agent-core-v2/agent/profile/profile'; -import { IAgentSwarmService } from '@moonshot-ai/agent-core-v2/features/swarm/agent/swarm'; +import { IAgentRPCService } from '@moonshot-ai/agent-core-v2/agent/rpc/rpc'; +import { IAgentSwarmService } from '@moonshot-ai/agent-core-v2/agent/swarm/swarm'; import { IAgentTaskService } from '@moonshot-ai/agent-core-v2/agent/task/task'; +import { IAgentTokenCountingService } from '@moonshot-ai/agent-core-v2/agent/tokenCounting/tokenCounting'; import { IAgentToolRegistryService } from '@moonshot-ai/agent-core-v2/agent/toolRegistry/toolRegistry'; +import { IAgentUsageService } from '@moonshot-ai/agent-core-v2/agent/usage/usage'; import { IAuthSummaryService } from '@moonshot-ai/agent-core-v2/app/auth/auth'; import { IConfigService } from '@moonshot-ai/agent-core-v2/app/config/config'; import { IFlagService } from '@moonshot-ai/agent-core-v2/app/flag/flag'; import { IProviderService } from '@moonshot-ai/agent-core-v2/kosong/provider/provider'; import { ISessionApprovalService } from '@moonshot-ai/agent-core-v2/session/approval/approval'; +import { ISessionInteractionService } from '@moonshot-ai/agent-core-v2/session/interaction/interaction'; import { ISessionQuestionService } from '@moonshot-ai/agent-core-v2/session/question/question'; -import { ISessionInitService } from '@moonshot-ai/agent-core-v2/features/sessionInit/sessionInit'; +import { ISessionInitService } from '@moonshot-ai/agent-core-v2/session/sessionInit/sessionInit'; import { ISessionMetadata } from '@moonshot-ai/agent-core-v2/session/sessionMetadata/sessionMetadata'; import { ISessionWorkspaceContext } from '@moonshot-ai/agent-core-v2/session/workspaceContext/workspaceContext'; @@ -122,6 +127,12 @@ export const SESSION_PANELS: readonly ServicePanelDef[] = [ scope: 'session', fetch: (svc) => call(svc, 'listPending'), }, + { + id: String(ISessionInteractionService), + label: 'SessionInteractionService', + scope: 'session', + fetch: (svc) => call(svc, 'listPending'), + }, { id: String(ISessionWorkspaceContext), label: 'SessionWorkspaceContext', @@ -158,8 +169,21 @@ export const AGENT_PANELS: readonly ServicePanelDef[] = [ }), actions: [ { label: 'Set model', input: 'Model id', run: (svc, model) => call(svc, 'setModel', model) }, + { label: 'Refresh system prompt', run: (svc) => call(svc, 'refreshSystemPrompt') }, ], }, + { + id: String(IAgentUsageService), + label: 'AgentUsageService', + scope: 'agent', + fetch: (svc) => call(svc, 'status'), + }, + { + id: String(IAgentTokenCountingService), + label: 'AgentTokenCountingService', + scope: 'agent', + fetch: (svc) => call(svc, 'get'), + }, { id: String(IAgentPermissionModeService), label: 'AgentPermissionModeService', @@ -187,6 +211,17 @@ export const AGENT_PANELS: readonly ServicePanelDef[] = [ { label: 'clear', run: (svc) => call(svc, 'clear') }, ], }, + { + id: String(IAgentGoalService), + label: 'AgentGoalService', + scope: 'agent', + fetch: (svc) => call(svc, 'getGoal'), + actions: [ + { label: 'pause', run: (svc) => call(svc, 'pauseGoal', {}) }, + { label: 'resume', run: (svc) => call(svc, 'resumeGoal', {}) }, + { label: 'cancel', danger: true, run: (svc) => call(svc, 'cancelGoal', {}) }, + ], + }, { id: String(IAgentTaskService), label: 'AgentTaskService', @@ -234,4 +269,17 @@ export const AGENT_PANELS: readonly ServicePanelDef[] = [ { label: 'exit', run: (svc) => call(svc, 'exit') }, ], }, + { + id: String(IAgentRPCService), + label: 'AgentRPCService', + scope: 'agent', + actions: [ + { label: 'cancel turn', run: (svc) => call(svc, 'cancel', {}) }, + { + label: 'undoHistory', + input: 'Steps', + run: (svc, n) => call(svc, 'undoHistory', { count: Number(n) }), + }, + ], + }, ]; diff --git a/apps/kimi-inspect/src/sessions/api.test.ts b/apps/kimi-inspect/src/sessions/api.test.ts index da885212f..57dd37d97 100644 --- a/apps/kimi-inspect/src/sessions/api.test.ts +++ b/apps/kimi-inspect/src/sessions/api.test.ts @@ -6,7 +6,7 @@ import { describe, expect, it } from 'vitest'; -import { fetchV2SessionGroups, fetchV2SessionsPage } from './api'; +import { fetchV2SessionsPage } from './api'; function fakeFetch(status: number, body: unknown) { const calls: { url: string; init?: RequestInit }[] = []; @@ -175,67 +175,3 @@ describe('fetchV2SessionsPage', () => { ); }); }); - -describe('fetchV2SessionGroups', () => { - const groupData = { - groups: [ - { - workspace: { id: 'ws1', cwd: '/tmp/proj' }, - sessions: [pageData.items[0]], - total: 7, - }, - { - workspace: { id: 'ws2', cwd: null }, - sessions: [], - total: 0, - }, - // Malformed groups are dropped, not fatal. - { workspace: { cwd: '/x' }, sessions: [], total: 1 }, - { id: 'nope' }, - ], - total: 3, - has_more: true, - next_page_token: 'tok-groups', - }; - - it('requests the by_workspace view and parses groups with per-group totals', async () => { - const { calls, fetchImpl } = fakeFetch(200, okBody(groupData)); - const page = await fetchV2SessionGroups({ - baseUrl: 'http://h:1', - token: 'tok', - statuses: ['running'], - sort: 'meta.updated_at_asc', - pageSize: 10, - groupPageSize: 5, - pageToken: 'tok-prev', - fetchImpl, - }); - - const url = new URL(calls[0]!.url); - expect(url.searchParams.get('view')).toBe('by_workspace'); - expect(url.searchParams.get('group.page_size')).toBe('5'); - expect(url.searchParams.get('page_size')).toBe('10'); - expect(url.searchParams.get('sort')).toBe('meta.updated_at_asc'); - expect(url.searchParams.get('page_token')).toBe('tok-prev'); - - expect(page.groups).toHaveLength(2); - const first = page.groups[0]!; - expect(first.workspace).toEqual({ id: 'ws1', cwd: '/tmp/proj' }); - expect(first.sessions.map((s) => s.id)).toEqual(['s1']); - expect(first.total).toBe(7); - expect(page.groups[1]!.workspace).toEqual({ id: 'ws2', cwd: null }); - expect(page.hasMore).toBe(true); - expect(page.nextPageToken).toBe('tok-groups'); - }); - - it('omits group.page_size when not set and throws on a malformed success payload', async () => { - const { calls, fetchImpl } = fakeFetch(200, okBody(groupData)); - await fetchV2SessionGroups({ baseUrl: 'http://h:1', fetchImpl }); - expect(new URL(calls[0]!.url).searchParams.get('group.page_size')).toBeNull(); - - const { fetchImpl: broken } = fakeFetch(200, okBody({ has_more: false })); - await expect(fetchV2SessionGroups({ baseUrl: 'http://h:1', fetchImpl: broken })).rejects.toThrow( - /unexpected response shape/, - ); - }); -}); diff --git a/apps/kimi-inspect/src/sessions/api.ts b/apps/kimi-inspect/src/sessions/api.ts index 4255bad4c..0645ba490 100644 --- a/apps/kimi-inspect/src/sessions/api.ts +++ b/apps/kimi-inspect/src/sessions/api.ts @@ -57,19 +57,6 @@ export interface V2SessionsQuery { readonly pageToken?: string; } -export interface V2SessionGroup { - readonly workspace: { readonly id: string; readonly cwd: string | null }; - readonly sessions: readonly V2Session[]; - /** Full matching-session count of this workspace (≥ sessions.length). */ - readonly total: number; -} - -export interface V2SessionGroupPage { - readonly groups: readonly V2SessionGroup[]; - readonly hasMore: boolean; - readonly nextPageToken?: string; -} - export interface V2SessionPage { readonly items: readonly V2Session[]; readonly hasMore: boolean; @@ -145,29 +132,21 @@ function parseSession(value: unknown): V2Session | undefined { }; } -interface FetchOptions { - readonly baseUrl: string; - readonly token?: string; - readonly fetchImpl?: typeof fetch; -} - -function buildParams(query: V2SessionsQuery): URLSearchParams { +export async function fetchV2SessionsPage( + opts: { readonly baseUrl: string; readonly token?: string } & V2SessionsQuery & { + readonly fetchImpl?: typeof fetch; + }, +): Promise<V2SessionPage> { const params = new URLSearchParams(); - for (const id of query.workspaceIds ?? []) params.append('workspace.id', id); - for (const status of query.statuses ?? []) params.append('activity.status', status); - if (query.updatedAfter !== undefined) params.set('meta.updated_after', String(query.updatedAfter)); - if (query.archived !== undefined) params.set('meta.archived', query.archived); - if (query.sort !== undefined) params.set('sort', query.sort); - if (query.includeGit === true) params.set('include', 'git'); - if (query.pageSize !== undefined) params.set('page_size', String(query.pageSize)); - if (query.pageToken !== undefined) params.set('page_token', query.pageToken); - return params; -} + for (const id of opts.workspaceIds ?? []) params.append('workspace.id', id); + for (const status of opts.statuses ?? []) params.append('activity.status', status); + if (opts.updatedAfter !== undefined) params.set('meta.updated_after', String(opts.updatedAfter)); + if (opts.archived !== undefined) params.set('meta.archived', opts.archived); + if (opts.sort !== undefined) params.set('sort', opts.sort); + if (opts.includeGit === true) params.set('include', 'git'); + if (opts.pageSize !== undefined) params.set('page_size', String(opts.pageSize)); + if (opts.pageToken !== undefined) params.set('page_token', opts.pageToken); -async function requestData( - opts: FetchOptions, - params: URLSearchParams, -): Promise<Record<string, unknown>> { const headers: Record<string, string> = {}; if (opts.token !== undefined && opts.token !== '') { headers['authorization'] = `Bearer ${opts.token}`; @@ -188,74 +167,16 @@ async function requestData( throw new Error(`v2 sessions failed (${code ?? `http_${res.status}`}): ${msg}`); } const data = envelope['data'] as Record<string, unknown> | null; - if (data === null || typeof data !== 'object') { - throw new Error('v2 sessions: unexpected response shape'); - } - return data; -} - -function pageMeta(data: Record<string, unknown>): { - readonly hasMore: boolean; - readonly nextPageToken?: string; -} { - return { - hasMore: data['has_more'] === true, - nextPageToken: - typeof data['next_page_token'] === 'string' ? data['next_page_token'] : undefined, - }; -} - -export async function fetchV2SessionsPage( - opts: FetchOptions & V2SessionsQuery, -): Promise<V2SessionPage> { - const data = await requestData(opts, buildParams(opts)); - if (!Array.isArray(data['items'])) { + if (data === null || typeof data !== 'object' || !Array.isArray(data['items'])) { throw new Error('v2 sessions: unexpected response shape'); } const items = (data['items'] as unknown[]) .map(parseSession) .filter((s): s is V2Session => s !== undefined); - return { items, ...pageMeta(data) }; -} - -/** - * The workspace-grouped projection (`view=by_workspace`): one request returns - * every workspace with a matching session, each carrying its first - * `groupPageSize` sessions under the requested sort plus the workspace's full - * matching `total`. The opaque cursor pages over groups. - */ -export async function fetchV2SessionGroups( - opts: FetchOptions & V2SessionsQuery & { readonly groupPageSize?: number }, -): Promise<V2SessionGroupPage> { - const params = buildParams(opts); - params.set('view', 'by_workspace'); - if (opts.groupPageSize !== undefined) params.set('group.page_size', String(opts.groupPageSize)); - const data = await requestData(opts, params); - if (!Array.isArray(data['groups'])) { - throw new Error('v2 sessions: unexpected response shape'); - } - const groups: V2SessionGroup[] = []; - for (const value of data['groups'] as unknown[]) { - if (value === null || typeof value !== 'object' || Array.isArray(value)) continue; - const g = value as Record<string, unknown>; - const workspace = g['workspace'] as Record<string, unknown> | null; - if ( - workspace === null || - typeof workspace !== 'object' || - typeof workspace['id'] !== 'string' || - !Array.isArray(g['sessions']) || - typeof g['total'] !== 'number' - ) { - continue; - } - const cwd = workspace['cwd']; - groups.push({ - workspace: { id: workspace['id'], cwd: typeof cwd === 'string' ? cwd : null }, - sessions: (g['sessions'] as unknown[]) - .map(parseSession) - .filter((s): s is V2Session => s !== undefined), - total: g['total'], - }); - } - return { groups, ...pageMeta(data) }; + return { + items, + hasMore: data['has_more'] === true, + nextPageToken: + typeof data['next_page_token'] === 'string' ? data['next_page_token'] : undefined, + }; } diff --git a/apps/kimi-inspect/src/sessions/views.ts b/apps/kimi-inspect/src/sessions/views.ts index 6d3fe6b71..14d1c97d9 100644 --- a/apps/kimi-inspect/src/sessions/views.ts +++ b/apps/kimi-inspect/src/sessions/views.ts @@ -1,7 +1,7 @@ /** - * Preset tree views for the session panel. Each view is a named combination + * Preset table views for the session panel. Each view is a named combination * of the `/api/v2/sessions` query conditions (status filter / archived mode / - * git opt-in) applied on top of the endpoint's workspace-grouped projection. + * git opt-in) plus a client-side presentation tweak (workspace grouping). * Views are fixed in code — there is no user-defined view editor. */ @@ -14,8 +14,10 @@ export interface SessionView { readonly statuses?: readonly V2ActivityStatus[]; /** Maps to `meta.archived`; default server-side is 'false'. */ readonly archived?: 'true' | 'false' | 'all'; - /** Adds `include=git` (branch / pull_request details on session rows). */ + /** Adds `include=git` (branch / pull_request columns). */ readonly includeGit?: boolean; + /** Group the loaded rows under per-workspace headers client-side. */ + readonly groupByWorkspace?: boolean; } export const SESSION_VIEWS: readonly SessionView[] = [ @@ -29,6 +31,7 @@ export const SESSION_VIEWS: readonly SessionView[] = [ statuses: ['running', 'approval', 'question', 'failed'], }, { id: 'archived', label: 'Archived', archived: 'true' }, + { id: 'workspace', label: 'By workspace', groupByWorkspace: true }, { id: 'git', label: 'Git', includeGit: true }, ]; diff --git a/apps/kimi-inspect/src/snapshots/api.ts b/apps/kimi-inspect/src/snapshots/api.ts deleted file mode 100644 index 824f44862..000000000 --- a/apps/kimi-inspect/src/snapshots/api.ts +++ /dev/null @@ -1,53 +0,0 @@ -import type { - AgentRuntimeBindingSnapshot, - SessionWorkspaceAssociationSnapshot, - WorkspaceInstanceSnapshot, - WorkspaceInstancesSnapshot, -} from '@moonshot-ai/agent-core-v2'; - -import { DEBUG_RPC_BASE, type InspectClient } from '../channel'; -import { RPCError } from '../channel/errors'; - -export function fetchWorkspaceSnapshots(client: InspectClient): Promise<WorkspaceInstancesSnapshot> { - return fetchSnapshot(client, '/workspaces'); -} - -export function fetchWorkspaceSnapshot( - client: InspectClient, - workspaceId: string, -): Promise<WorkspaceInstanceSnapshot> { - return fetchSnapshot(client, `/workspace/${encodeURIComponent(workspaceId)}/snapshot`); -} - -export function fetchSessionWorkspaceAssociation( - client: InspectClient, - sessionId: string, -): Promise<SessionWorkspaceAssociationSnapshot> { - return fetchSnapshot(client, `/session/${encodeURIComponent(sessionId)}/association`); -} - -export function fetchAgentRuntimeBinding( - client: InspectClient, - sessionId: string, - agentId: string, -): Promise<AgentRuntimeBindingSnapshot> { - return fetchSnapshot( - client, - `/session/${encodeURIComponent(sessionId)}/agent/${encodeURIComponent(agentId)}/runtime-binding`, - ); -} - -async function fetchSnapshot<T>(client: InspectClient, path: string): Promise<T> { - const headers: Record<string, string> = {}; - if (client.token !== undefined && client.token !== '') { - headers['authorization'] = `Bearer ${client.token}`; - } - const response = await fetch(`${client.baseUrl}${DEBUG_RPC_BASE}${path}`, { headers }); - const envelope = (await response.json()) as { - code: number; - msg: string; - data: T; - }; - if (envelope.code !== 0) throw new RPCError(envelope.code, envelope.msg); - return envelope.data; -} diff --git a/apps/kimi-inspect/src/transcript/api.ts b/apps/kimi-inspect/src/transcript/api.ts index 7aa54cee8..bca4ed4fc 100644 --- a/apps/kimi-inspect/src/transcript/api.ts +++ b/apps/kimi-inspect/src/transcript/api.ts @@ -17,7 +17,6 @@ import { transcriptOpsCatchupResponseSchema, transcriptPlanResponseSchema, transcriptResponseSchema, - type AttachmentSource, type TranscriptAttachment, type TranscriptInteraction, type TranscriptItem, @@ -27,44 +26,6 @@ import { type TranscriptTodo, } from '@moonshot-ai/transcript'; -type StoredAttachmentSource = Extract<AttachmentSource, { kind: 'file' | 'session_media' }>; - -export interface FetchTranscriptAttachmentOptions { - readonly baseUrl: string; - readonly token?: string; - readonly sessionId: string; - readonly source: StoredAttachmentSource; - readonly fetchImpl?: typeof fetch; -} - -export function transcriptAttachmentUrl( - baseUrl: string, - sessionId: string, - source: AttachmentSource, -): string { - if (source.kind === 'url') return source.url; - if (source.kind === 'file') { - return `${baseUrl}/api/v1/files/${encodeURIComponent(source.fileId)}`; - } - return `${baseUrl}/api/v1/sessions/${encodeURIComponent(sessionId)}/media/${encodeURIComponent(source.fileId)}`; -} - -export async function fetchTranscriptAttachment( - opts: FetchTranscriptAttachmentOptions, -): Promise<Blob> { - const headers: Record<string, string> = {}; - if (opts.token !== undefined && opts.token !== '') { - headers['authorization'] = `Bearer ${opts.token}`; - } - const doFetch = opts.fetchImpl ?? fetch; - const res = await doFetch( - transcriptAttachmentUrl(opts.baseUrl, opts.sessionId, opts.source), - { headers }, - ); - if (!res.ok) throw new Error(`attachment download failed (${res.status})`); - return res.blob(); -} - /** One transcript page as merged by the chat store. */ export interface TranscriptPage { readonly items: readonly TranscriptItem[]; diff --git a/apps/kimi-inspect/src/transcript/transcript.test.ts b/apps/kimi-inspect/src/transcript/transcript.test.ts index 507d5c15e..8a7bab27b 100644 --- a/apps/kimi-inspect/src/transcript/transcript.test.ts +++ b/apps/kimi-inspect/src/transcript/transcript.test.ts @@ -16,11 +16,9 @@ import { describe, expect, it, vi } from 'vitest'; import type { WsLike } from '../channel/wsLike'; import { - fetchTranscriptAttachment, fetchTranscriptOps, fetchTranscriptPage, fetchTranscriptPlan, - transcriptAttachmentUrl, type TranscriptPage, } from './api'; import { @@ -46,44 +44,6 @@ function stepHeader(stepId: string, ordinal: number): StepHeader { return { kind: 'step', stepId, turnId: stepId.split('.')[0] ?? 't1', ordinal, state: 'running' }; } -describe('transcript attachments', () => { - it('maps each attachment locator to its transport route', () => { - expect( - transcriptAttachmentUrl('http://h:1', 's 1', { kind: 'file', fileId: 'f 1' }), - ).toBe('http://h:1/api/v1/files/f%201'); - expect( - transcriptAttachmentUrl('http://h:1', 's 1', { - kind: 'session_media', - fileId: 'f 1', - }), - ).toBe('http://h:1/api/v1/sessions/s%201/media/f%201'); - expect( - transcriptAttachmentUrl('http://h:1', 's1', { - kind: 'url', - url: 'https://example.com/a.png', - }), - ).toBe('https://example.com/a.png'); - }); - - it('fetches stored attachment bytes with bearer auth', async () => { - const fetchImpl = vi.fn(async () => new Response('media-bytes', { status: 200 })); - - const blob = await fetchTranscriptAttachment({ - baseUrl: 'http://h:1', - token: 'tok', - sessionId: 's1', - source: { kind: 'session_media', fileId: 'f_1' }, - fetchImpl: fetchImpl as typeof fetch, - }); - - expect(fetchImpl).toHaveBeenCalledWith( - 'http://h:1/api/v1/sessions/s1/media/f_1', - { headers: { authorization: 'Bearer tok' } }, - ); - await expect(blob.text()).resolves.toBe('media-bytes'); - }); -}); - const textFrameUpsert = (turnId: string, stepId: string, frameId: string, text: string) => ({ op: 'frame.upsert' as const, turnId, diff --git a/apps/vis/server/src/lib/agent-record-types.ts b/apps/vis/server/src/lib/agent-record-types.ts index 13df18048..6d7ef505e 100644 --- a/apps/vis/server/src/lib/agent-record-types.ts +++ b/apps/vis/server/src/lib/agent-record-types.ts @@ -3,7 +3,9 @@ // Do NOT add local interfaces that duplicate upstream shapes. export type { + AgentRecord, AgentRecordEvents, + AgentRecordOf, AgentConfigUpdateData, CompactionBeginData, CompactionResult, @@ -28,28 +30,7 @@ export type { Message, ContentPart, ToolCall, TokenUsage } from '@moonshot-ai/ko // Local bindings for the upstream types referenced by the vis-only DTOs // below. The `export type { … }` re-export above forwards the names to // consumers but does NOT bring them into this module's scope. -import type { - AgentRecord as UpstreamAgentRecord, - BackgroundTaskInfo, -} from '@moonshot-ai/agent-core'; - -/** - * The wire record union vis projects, widened with the v2-engine tower-mode - * records (`tower_mode.enter` / `tower_mode.exit`, empty payloads). The - * upstream v1 union is frozen ahead of its deprecation and does not carry - * them; the local widening keeps the context projector's exhaustiveness - * check covering tower session wires. - */ -export type AgentRecord = - | UpstreamAgentRecord - | { readonly type: 'tower_mode.enter'; readonly time?: number } - | { readonly type: 'tower_mode.exit'; readonly time?: number }; - -/** Extract one record kind from the (locally widened) union. */ -export type AgentRecordOf<K extends AgentRecord['type']> = Extract< - AgentRecord, - { readonly type: K } ->; +import type { AgentRecord, BackgroundTaskInfo } from '@moonshot-ai/agent-core'; /** * Persistent representation of a cron task. diff --git a/apps/vis/server/src/lib/context-projector.ts b/apps/vis/server/src/lib/context-projector.ts index 838ade963..b70e98815 100644 --- a/apps/vis/server/src/lib/context-projector.ts +++ b/apps/vis/server/src/lib/context-projector.ts @@ -498,9 +498,6 @@ export function projectContext( case 'swarm_mode.exit': swarm = { active: false }; break; - case 'tower_mode.enter': - case 'tower_mode.exit': - break; // Kinds that don't affect the projected timeline / derived state, // including the observability records (request trace — `llm.*`, // `mcp.tools_discovered`), which are never part of context state: diff --git a/apps/vis/web/src/components/wire/renderers.tsx b/apps/vis/web/src/components/wire/renderers.tsx index b4156433e..d59b239cf 100644 --- a/apps/vis/web/src/components/wire/renderers.tsx +++ b/apps/vis/web/src/components/wire/renderers.tsx @@ -590,18 +590,6 @@ export const WIRE_RENDERERS: RendererMap = { headline: () => ({ main: <Dim>swarm mode exited</Dim> }), }, - 'tower_mode.enter': { - tone: 'subagent', - label: 'tower↻', - headline: () => ({ main: <Dim>tower mode entered</Dim> }), - }, - - 'tower_mode.exit': { - tone: 'subagent', - label: 'tower✓', - headline: () => ({ main: <Dim>tower mode exited</Dim> }), - }, - 'goal.create': { tone: 'lifecycle', label: 'goal+', diff --git a/apps/vscode/CHANGELOG.md b/apps/vscode/CHANGELOG.md index 9c4cd482d..13326d0d2 100644 --- a/apps/vscode/CHANGELOG.md +++ b/apps/vscode/CHANGELOG.md @@ -1,41 +1,5 @@ # Changelog -## 0.7.2 - -### Patch Changes - -- [#3079](https://github.com/MoonshotAI/kimi-code/pull/3079) [`35befdc`](https://github.com/MoonshotAI/kimi-code/commit/35befdcef2be344d931ea20063cb64113350dc4b) Thanks [@gaoyuan1223m](https://github.com/gaoyuan1223m)! - Fix multi-select questions jumping to the next question after only one answer is selected. - -- Updated dependencies [[`3d77620`](https://github.com/MoonshotAI/kimi-code/commit/3d7762003a4a35cbeb8571d471c6898a006152e6)]: - - @moonshot-ai/kimi-code-sdk@0.19.1 - -## 0.7.1 - -### Patch Changes - -- [#3026](https://github.com/MoonshotAI/kimi-code/pull/3026) [`13857f3`](https://github.com/MoonshotAI/kimi-code/commit/13857f383200881aa77dc972a8963ba421eeb2b6) Thanks [@bj456736](https://github.com/bj456736)! - Show plugin- and file-declared MCP servers as read-only entries in the MCP servers panel. - -- Updated dependencies [[`d833a1a`](https://github.com/MoonshotAI/kimi-code/commit/d833a1a893c4d69d96af542f40557442992085e0), [`61591bc`](https://github.com/MoonshotAI/kimi-code/commit/61591bce09f4467aa1664cb8ecb6aa6904b7accd), [`d833a1a`](https://github.com/MoonshotAI/kimi-code/commit/d833a1a893c4d69d96af542f40557442992085e0), [`13857f3`](https://github.com/MoonshotAI/kimi-code/commit/13857f383200881aa77dc972a8963ba421eeb2b6)]: - - @moonshot-ai/kimi-code-sdk@0.19.0 - -## 0.7.0 - -### Minor Changes - -- [#2916](https://github.com/MoonshotAI/kimi-code/pull/2916) [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797) Thanks [@Grapedge](https://github.com/Grapedge)! - Run the extension on the v2 agent engine by default; the interface, sessions, and workflows are unchanged. To roll back, enable the `kimi.useAgentCoreV1` setting and reload the window. - -### Patch Changes - -- Updated dependencies [[`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797)]: - - @moonshot-ai/kimi-code-sdk@0.18.0 - -## 0.6.9 - -### Patch Changes - -- Updated dependencies [[`c9bfe8b`](https://github.com/MoonshotAI/kimi-code/commit/c9bfe8b2c8314ba4ef8806fb3b92ac654c1d1860), [`c212ae9`](https://github.com/MoonshotAI/kimi-code/commit/c212ae9715371c0d7939c15e664acbe0d7cf7fc3)]: - - @moonshot-ai/kimi-code-sdk@0.17.0 - ## 0.6.8 ### Patch Changes diff --git a/apps/vscode/package.json b/apps/vscode/package.json index 06b5dfd54..ee249a0b3 100644 --- a/apps/vscode/package.json +++ b/apps/vscode/package.json @@ -3,7 +3,7 @@ "publisher": "moonshot-ai", "displayName": "Kimi Code", "description": "Official Kimi Code plugin for VS Code", - "version": "0.7.2", + "version": "0.6.8", "private": true, "license": "Apache-2.0", "type": "module", @@ -95,11 +95,6 @@ "Share when active file changes" ], "description": "Control when to share the active editor's file and cursor position with Kimi" - }, - "kimi.useAgentCoreV1": { - "type": "boolean", - "default": false, - "description": "Temporary rollback switch: run Kimi on the legacy v1 engine instead of the current one. This setting will be removed in a future version. Requires a window reload to take effect." } } }, diff --git a/apps/vscode/shared/legacy-sdk.ts b/apps/vscode/shared/legacy-sdk.ts index 1a88ee6a4..03c5bafbd 100644 --- a/apps/vscode/shared/legacy-sdk.ts +++ b/apps/vscode/shared/legacy-sdk.ts @@ -191,12 +191,6 @@ export interface MCPServerConfig { headers?: Record<string, string>; auth?: 'oauth'; bearerTokenEnvVar?: string; - /** Unified management view tags; absent on cores predating the management plane. */ - source?: 'global' | 'plugin' | 'caller'; - /** global: defining file path; plugin: plugin id. */ - origin?: string; - /** false for plugin / project-layer entries — the panel hides mutating actions for them. */ - mutable?: boolean; } export interface UpdateMCPServerRequest { diff --git a/apps/vscode/src/bridge-handler.ts b/apps/vscode/src/bridge-handler.ts index e4d410710..04ef41a5e 100644 --- a/apps/vscode/src/bridge-handler.ts +++ b/apps/vscode/src/bridge-handler.ts @@ -37,28 +37,14 @@ export class BridgeHandler { private readonly showLogs: ShowLogsFn, private readonly writeLog: (message: string) => void, ) { - const useAgentCoreV1 = VSCodeSettings.useAgentCoreV1; - try { - this.runtime = new KimiRuntime({ - version: VSCodeSettings.getExtensionConfig().version, - useAgentCoreV1, - broadcast, - captureBaseline: (session, filePath, webviewIds) => { - this.captureFileBaseline(session, filePath, webviewIds); - }, - log: (message, error) => this.logRuntimeError(message, error), - }); - } catch (error) { - // No silent fallback: report the failure with the rollback path, so the - // user can report it or switch engines and reload. - const rollbackHint = useAgentCoreV1 - ? "" - : " You can roll back to the legacy engine: enable the 'kimi.useAgentCoreV1' setting and reload the window."; - throw new Error( - `Failed to start the Kimi engine: ${error instanceof Error ? error.message : String(error)}.${rollbackHint}`, - { cause: error }, - ); - } + this.runtime = new KimiRuntime({ + version: VSCodeSettings.getExtensionConfig().version, + broadcast, + captureBaseline: (session, filePath, webviewIds) => { + this.captureFileBaseline(session, filePath, webviewIds); + }, + log: (message, error) => this.logRuntimeError(message, error), + }); this.baselineManager = new BaselineManager(globalStoragePath, this.runtime.harness.homeDir); this.fileManager = new FileManager(this.baselineManager, broadcast); } diff --git a/apps/vscode/src/config/vscode-settings.ts b/apps/vscode/src/config/vscode-settings.ts index 76dd6e99a..9bca3b126 100644 --- a/apps/vscode/src/config/vscode-settings.ts +++ b/apps/vscode/src/config/vscode-settings.ts @@ -4,27 +4,6 @@ import type { ExtensionConfig } from "../../shared/types"; declare const __EXTENSION_VERSION__: string; const EXTENSION_VERSION = typeof __EXTENSION_VERSION__ !== "undefined" ? __EXTENSION_VERSION__ : "0.0.0"; -/** Support backdoor with the highest priority: a truthy value forces the legacy v1 engine. */ -export const LEGACY_ENGINE_ENV = "KIMI_CODE_LEGACY_FLAG"; - -const TRUTHY_ENV_VALUES = new Set(["1", "true", "yes", "on"]); - -/** - * The single engine-selection decision for the whole extension. A truthy - * `KIMI_CODE_LEGACY_FLAG` wins over the `kimi.useAgentCoreV1` setting, so - * support and headless test runs can force the legacy engine without - * touching user settings. Both default to the v2 engine. - */ -export function resolveUseAgentCoreV1( - settingValue: boolean, - env: Readonly<Record<string, string | undefined>>, -): boolean { - if (TRUTHY_ENV_VALUES.has((env[LEGACY_ENGINE_ENV] ?? "").trim().toLowerCase())) { - return true; - } - return settingValue; -} - function getConfig() { return vscode.workspace.getConfiguration("kimi"); } @@ -58,11 +37,6 @@ export const VSCodeSettings = { return getConfig().get<"never" | "onConversationStart" | "onFileChange">("editorContext", "never"); }, - /** Read once at activation; a change needs a window reload to take effect. */ - get useAgentCoreV1(): boolean { - return resolveUseAgentCoreV1(getConfig().get<boolean>("useAgentCoreV1", false), process.env); - }, - getExtensionConfig(): ExtensionConfig { return { yoloMode: this.yoloMode, diff --git a/apps/vscode/src/handlers/config.handler.ts b/apps/vscode/src/handlers/config.handler.ts index 87d9b7dcf..079c81670 100644 --- a/apps/vscode/src/handlers/config.handler.ts +++ b/apps/vscode/src/handlers/config.handler.ts @@ -3,7 +3,6 @@ import { effectiveModelAlias, type KimiConfig as SdkKimiConfig, type ModelAlias, - type ProviderType, type ThinkingEffort, } from "@moonshot-ai/kimi-code-sdk"; @@ -42,14 +41,9 @@ const saveConfig: Handler<SessionConfig, { ok: boolean }> = async (params, ctx) const effortChanged = params.effortChanged !== false; const config = await ctx.harness.getConfig({ reload: true }); const model = config.models?.[params.model]; - // Resolve with the provider type the way the TUI's effectiveModelForHost - // does: without it the Anthropic fallback profile (e.g. `claude-latest`) - // never matches, so the inferred default that gates persistence is missed. - const providerType = - model === undefined ? undefined : (config.providers?.[model.provider]?.type ?? model.protocol); const full = thinkingConfig( effort, - model === undefined ? undefined : effectiveModelAlias(model, providerType), + model === undefined ? undefined : effectiveModelAlias(model).supportEfforts, ); // Re-confirming the effort already shown is not an explicit choice — // persist the model but leave the stored effort preference alone (the TUI's @@ -132,12 +126,7 @@ export const configHandlers = { export function toWebviewConfig(config: SdkKimiConfig): WebviewKimiConfig { const models: ModelConfig[] = Object.entries(config.models ?? {}) - // Resolve with the provider type the way saveConfig does: without it the - // Anthropic fallback profile never matches, and the webview's effort - // persistence seed would gate on a different effective model. - .map(([id, model]) => - toWebviewModel(id, model, config.providers?.[model.provider]?.type ?? model.protocol), - ) + .map(([id, model]) => toWebviewModel(id, model)) .toSorted((left, right) => left.name.localeCompare(right.name)); return { defaultModel: config.defaultModel ?? models[0]?.id ?? null, @@ -147,8 +136,8 @@ export function toWebviewConfig(config: SdkKimiConfig): WebviewKimiConfig { }; } -function toWebviewModel(id: string, model: ModelAlias, providerType?: ProviderType): ModelConfig { - const effective = effectiveModelAlias(model, providerType); +function toWebviewModel(id: string, model: ModelAlias): ModelConfig { + const effective = effectiveModelAlias(model); return { id, name: effective.displayName ?? effective.model ?? id, @@ -170,33 +159,20 @@ function sessionConfigEffort(config: SessionConfig): ThinkingEffort { * Project a thinking effort to the `[thinking]` config patch persisted to * config.toml — mirrors the TUI's thinkingEffortToConfig. "off" disables * thinking; "on" is the boolean-model on-signal, so it only persists - * `enabled`. A concrete effort persists as the global default, EXCEPT when it - * ranks above the model's effective default effort: `support_efforts` is - * ordered by strength, and a pick more expensive than the default stays - * session-only and records just `enabled`, so it never becomes the global - * default for every new session. The default here is the effective model's, - * however it arose — declared via the catalog or overrides, or synthesized - * by the protocol-profile inference (`withAnthropicProfile` resolves Claude - * models to "high", so an "xhigh" pick stays session-only there). When the - * effective model carries no default effort at all, its highest declared - * level stays session-only (the historical rule). When the model's levels - * are unknown the concrete effort is persisted as-is. + * `enabled`. A concrete effort persists as the global default, EXCEPT the + * model's highest declared level — the last entry of `support_efforts` — + * which is session-only and records just `enabled`, so the most expensive + * tier never becomes the global default for every new session. When the + * model's levels are unknown the concrete effort is persisted as-is. */ function thinkingConfig( effort: ThinkingEffort, - model?: Pick<ModelAlias, "supportEfforts" | "defaultEffort">, + supportEfforts?: readonly string[], ): { enabled: boolean; effort?: string } { if (effort === "off") return { enabled: false }; if (effort === "on") return { enabled: true }; - const efforts = model?.supportEfforts; - if (efforts !== undefined && efforts.includes(effort)) { - const declared = model?.defaultEffort; - const ceiling = - declared !== undefined && efforts.includes(declared) - ? efforts.indexOf(declared) - : efforts.length - 2; - if (efforts.indexOf(effort) > ceiling) return { enabled: true }; - } + const top = supportEfforts?.at(-1); + if (top !== undefined && effort === top) return { enabled: true }; return { enabled: true, effort }; } diff --git a/apps/vscode/src/handlers/mcp.handler.ts b/apps/vscode/src/handlers/mcp.handler.ts index 72c883d74..a310f64de 100644 --- a/apps/vscode/src/handlers/mcp.handler.ts +++ b/apps/vscode/src/handlers/mcp.handler.ts @@ -1,9 +1,5 @@ import * as vscode from "vscode"; -import type { - McpManagedServerInfo, - McpServerConfig as SdkMcpServerConfig, - McpTestResult, -} from "@moonshot-ai/kimi-code-sdk"; +import type { McpServerConfig as SdkMcpServerConfig, McpTestResult } from "@moonshot-ai/kimi-code-sdk"; import { Events, Methods } from "../../shared/bridge"; import { @@ -29,13 +25,12 @@ interface NameParams { name: string } export const mcpHandlers: Record<string, Handler<any, any>> = { [Methods.GetMCPServers]: async (_, ctx): Promise<MCPServerConfig[]> => { - return listWorkspaceServers(ctx); + return toWebviewServers(await ctx.harness.listMcpServers()); }, [Methods.AddMCPServer]: async (params: MCPServerConfig, ctx): Promise<MCPServerConfig[]> => { const server = restoreMaskedSecrets(undefined, params); - await ctx.harness.addMcpServer(toSdkServer(server)); - const servers = await listWorkspaceServers(ctx); + const servers = toWebviewServers(await ctx.harness.addMcpServer(toSdkServer(server))); ctx.broadcast(Events.MCPServersChanged, servers); return servers; }, @@ -45,20 +40,20 @@ export const mcpHandlers: Record<string, Handler<any, any>> = { ctx, ): Promise<MCPServerConfig[]> => { const request = normalizeUpdateRequest(params); - const current = ( - await ctx.harness.listMcpServers({ cwd: ctx.workDir ?? undefined }) - ).find((server) => server.name === request.originalName); + const current = (await ctx.harness.listMcpServers()).find( + (server) => server.name === request.originalName, + ); const edited = restoreMaskedSecrets(current, request.server); const next = mergeEditableServer(current, edited, request.replaceEditableFields); - await updateOrRenameServer(ctx.harness, request.originalName, current, next); - const servers = await listWorkspaceServers(ctx); + const servers = toWebviewServers( + await updateOrRenameServer(ctx.harness, request.originalName, current, next), + ); ctx.broadcast(Events.MCPServersChanged, servers); return servers; }, [Methods.RemoveMCPServer]: async ({ name }: NameParams, ctx): Promise<MCPServerConfig[]> => { - await ctx.harness.removeMcpServer(name); - const servers = await listWorkspaceServers(ctx); + const servers = toWebviewServers(await ctx.harness.removeMcpServer(name)); ctx.broadcast(Events.MCPServersChanged, servers); return servers; }, @@ -119,29 +114,14 @@ export const mcpHandlers: Record<string, Handler<any, any>> = { }, }; -/** - * The workspace-aware server list shown in the modal. The mutation RPCs - * (add/update/remove) return a list resolved without a cwd, so the webview - * refresh after every mutation must re-list with the workspace cwd — - * otherwise project-layer entries drop out of the modal until the next full - * load. - */ -async function listWorkspaceServers(ctx: Parameters<Handler>[1]): Promise<MCPServerConfig[]> { - return toWebviewServers(await ctx.harness.listMcpServers({ cwd: ctx.workDir ?? undefined })); -} - -function toWebviewServers(servers: readonly McpManagedServerInfo[]): MCPServerConfig[] { +function toWebviewServers(servers: readonly SdkMcpServerConfig[]): MCPServerConfig[] { return servers .filter((server) => server.transport === "stdio" || server.transport === "http") .map((server) => { - // The management view's source/origin/mutable tags stay in the webview - // payload so the panel can hide mutating controls on read-only entries; - // only the nested plugin origin detail is dropped. - const { plugin: _plugin, ...config } = server; - if (config.transport === "stdio") { - return { ...config, env: maskSecretValues(config.env) } as MCPServerConfig; + if (server.transport === "stdio") { + return { ...server, env: maskSecretValues(server.env) } as MCPServerConfig; } - return { ...config, headers: maskSecretValues(config.headers) } as MCPServerConfig; + return { ...server, headers: maskSecretValues(server.headers) } as MCPServerConfig; }); } @@ -290,10 +270,9 @@ async function updateOrRenameServer( originalName: string, current: SdkMcpServerConfig | undefined, next: SdkMcpServerConfig, -): Promise<void> { +): Promise<readonly SdkMcpServerConfig[]> { if (next.name === originalName) { - await harness.updateMcpServer(next); - return; + return harness.updateMcpServer(next); } if (current === undefined) { throw new Error(`MCP server "${originalName}" was not found`); @@ -301,7 +280,7 @@ async function updateOrRenameServer( await harness.addMcpServer(next); try { - await harness.removeMcpServer(originalName); + return await harness.removeMcpServer(originalName); } catch (error) { await harness.removeMcpServer(next.name).catch(() => undefined); throw error; diff --git a/apps/vscode/src/runtime/kimi-runtime.ts b/apps/vscode/src/runtime/kimi-runtime.ts index f3c6db4c6..d07af86f8 100644 --- a/apps/vscode/src/runtime/kimi-runtime.ts +++ b/apps/vscode/src/runtime/kimi-runtime.ts @@ -1,6 +1,5 @@ import { createKimiHarness, - createKimiHarnessV2, type KimiHarness, type Session, type SessionSummary, @@ -30,12 +29,6 @@ export interface KimiRuntimeOptions { readonly log: (message: string, error?: unknown) => void; readonly homeDir?: string; readonly harness?: KimiHarness; - /** - * Engine rollback: create the legacy v1 harness instead of the default v2 - * one. The decision is made once in `config/vscode-settings.ts`; a change - * applies on the next window reload, when the runtime is rebuilt. - */ - readonly useAgentCoreV1?: boolean; } export interface OpenSessionOptions { @@ -62,11 +55,10 @@ export class KimiRuntime { this.broadcast = options.broadcast; this.captureBaseline = options.captureBaseline; this.log = options.log; - const createHarness = options.useAgentCoreV1 ? createKimiHarness : createKimiHarnessV2; this.harness = options.harness ?? - createHarness({ - homeDir: options.homeDir, + createKimiHarness({ + ...(options.homeDir === undefined ? {} : { homeDir: options.homeDir }), identity: { productName: "kimi-code-vscode", version: options.version, diff --git a/apps/vscode/test/bridge-handler.test.ts b/apps/vscode/test/bridge-handler.test.ts index 5c6ca4297..51b203823 100644 --- a/apps/vscode/test/bridge-handler.test.ts +++ b/apps/vscode/test/bridge-handler.test.ts @@ -55,8 +55,6 @@ const host = vi.hoisted(() => { Uri, watcher, harness, - createKimiHarness: vi.fn(() => harness), - createKimiHarnessV2: vi.fn(() => harness), showWarningMessage, workspaceFolders: [] as Array<{ uri: Uri }>, }; @@ -77,11 +75,7 @@ vi.mock("vscode", () => ({ vi.mock("@moonshot-ai/kimi-code-sdk", async (importOriginal) => { const original = await importOriginal<typeof import("@moonshot-ai/kimi-code-sdk")>(); - return { - ...original, - createKimiHarness: () => host.createKimiHarness(), - createKimiHarnessV2: () => host.createKimiHarnessV2(), - }; + return { ...original, createKimiHarness: () => host.harness }; }); let bridge: BridgeHandler; @@ -98,8 +92,6 @@ beforeEach(async () => { host.harness.resumeSession.mockReset(); host.harness.getConfig.mockReset(); host.harness.getConfig.mockResolvedValue({ models: {} }); - host.createKimiHarness.mockImplementation(() => host.harness); - host.createKimiHarnessV2.mockImplementation(() => host.harness); host.showWarningMessage.mockReset(); host.showWarningMessage.mockResolvedValue(undefined); workspaceState = { get: vi.fn((_key, fallback) => fallback), update: vi.fn() }; @@ -116,44 +108,9 @@ beforeEach(async () => { afterEach(async () => { await bridge.dispose(); vi.clearAllMocks(); - vi.unstubAllEnvs(); await rm(root, { recursive: true, force: true }); }); -describe("Engine startup", () => { - function constructBridge(): void { - new BridgeHandler( - vi.fn(), - workspaceState as unknown as vscode.Memento, - join(root, "global-storage-2"), - vi.fn(), - showLogs, - writeLog, - ); - } - - it("reports the rollback setting when the default engine cannot start", () => { - // Keep v2 the default even when the suite itself runs under the legacy flag. - vi.stubEnv("KIMI_CODE_LEGACY_FLAG", ""); - host.createKimiHarnessV2.mockImplementationOnce(() => { - throw new Error("engine boom"); - }); - - expect(constructBridge).toThrow( - /Failed to start the Kimi engine: engine boom\..*kimi\.useAgentCoreV1/s, - ); - }); - - it("reports no rollback hint when the legacy engine itself cannot start", () => { - vi.stubEnv("KIMI_CODE_LEGACY_FLAG", "1"); - host.createKimiHarness.mockImplementationOnce(() => { - throw new Error("legacy boom"); - }); - - expect(constructBridge).toThrow(/^Failed to start the Kimi engine: legacy boom\.$/); - }); -}); - describe("Webview RPC boundary (validates requests before host dispatch)", () => { it("returns a readable error when the envelope is not a plain object", async () => { const result = await bridge.handle([], "view-1"); @@ -293,36 +250,6 @@ describe("Webview RPC boundary (validates requests before host dispatch)", () => }); }); - it("resolves the fallback-profile default effort with the provider type", async () => { - // claude-latest declares efforts but no default; the Anthropic fallback - // profile only matches when the provider type joins the resolution. - host.harness.getConfig.mockResolvedValueOnce({ - defaultModel: "custom/claude", - providers: { - custom: { type: "anthropic", apiKey: "test-key" }, - }, - models: { - "custom/claude": { - provider: "custom", - model: "claude-latest", - supportEfforts: ["low", "medium", "high", "xhigh", "max"], - }, - }, - }); - - const result = await bridge.handle({ id: "rpc-models", method: Methods.GetModels }, "view-1"); - - expect(result).toMatchObject({ - result: { - models: [{ - id: "custom/claude", - support_efforts: ["low", "medium", "high", "xhigh", "max"], - default_effort: "high", - }], - }, - }); - }); - it("does not expose the session storage path when listing sessions", async () => { host.harness.listSessions.mockResolvedValueOnce([ { @@ -532,7 +459,7 @@ describe("Webview config saves (thinking effort persistence parity with the TUI) }); }); - it("keeps a pick above the model's delivered default session-only", async () => { + it("keeps the model's top declared tier session-only", async () => { mockConfig(); await bridge.handle( @@ -546,42 +473,6 @@ describe("Webview config saves (thinking effort persistence parity with the TUI) }); }); - it("persists the top tier when the model's delivered default is the top tier", async () => { - host.harness.getConfig.mockResolvedValue({ - defaultModel: "kimi/reasoning", - models: { "kimi/reasoning": { ...effortModel, defaultEffort: "max" } }, - } as never); - - await bridge.handle( - { id: "rpc-1", method: Methods.SaveConfig, params: { model: "kimi/reasoning", thinking: true, effort: "max" } }, - "view-1", - ); - - expect(host.harness.setConfig).toHaveBeenCalledWith({ - defaultModel: "kimi/reasoning", - thinking: { enabled: true, effort: "max" }, - }); - }); - - it("keeps an xhigh pick session-only when the default comes from the Anthropic profile inference", async () => { - // claude-opus-4-7 declares no efforts; the profile inference supplies - // [low, medium, high, xhigh, max] and resolves the default to "high". - host.harness.getConfig.mockResolvedValue({ - defaultModel: "custom/claude", - models: { "custom/claude": { provider: "custom", model: "claude-opus-4-7" } }, - } as never); - - await bridge.handle( - { id: "rpc-1", method: Methods.SaveConfig, params: { model: "custom/claude", thinking: true, effort: "xhigh" } }, - "view-1", - ); - - expect(host.harness.setConfig).toHaveBeenCalledWith({ - defaultModel: "custom/claude", - thinking: { enabled: true }, - }); - }); - it("persists the concrete effort when the model's levels are unknown", async () => { host.harness.getConfig.mockResolvedValue({ defaultModel: "other/model", models: {} }); diff --git a/apps/vscode/test/kimi-harness.integration.test.ts b/apps/vscode/test/kimi-harness.integration.test.ts index 6614606f4..ea53fae3d 100644 --- a/apps/vscode/test/kimi-harness.integration.test.ts +++ b/apps/vscode/test/kimi-harness.integration.test.ts @@ -2,7 +2,6 @@ * Scenario: the VS Code host and another Node SDK client share one in-process Kimi home. * Responsibilities: outbound host identity, config/session interoperability, MCP credential/edit compatibility, and terminal provider failures. * Wiring: KimiRuntime, KimiHarness, core, storage, and HTTP provider adapter are real; only the remote provider is local. - * The runtime harness follows the extension engine decision (v2 by default, the legacy v1 under KIMI_CODE_LEGACY_FLAG). * Run: pnpm --filter kimi-code exec vitest run test/kimi-harness.integration.test.ts */ @@ -43,7 +42,6 @@ import { chatHandlers } from "../src/handlers/chat.handler"; import { mcpHandlers } from "../src/handlers/mcp.handler"; import { parseHostSlashCommand, runHostSlashCommand } from "../src/handlers/slash-command"; import type { HandlerContext } from "../src/handlers/types"; -import { VSCodeSettings } from "../src/config/vscode-settings"; import { KimiRuntime } from "../src/runtime/kimi-runtime"; import type { SessionRuntime } from "../src/runtime/session-runtime"; @@ -73,7 +71,6 @@ interface RuntimeRig { } interface McpHandlerRig { - readonly homeDir: string; readonly harness: KimiHarness; readonly broadcasts: BroadcastRecord[]; readonly logs: LogRecord[]; @@ -108,9 +105,6 @@ async function createRuntimeRig(extraAliases: readonly string[] = []): Promise<R const runtime = new KimiRuntime({ version, homeDir, - // The dual-engine CI matrix reruns this suite with KIMI_CODE_LEGACY_FLAG=1; - // the vscode mock above keeps the setting itself at its default. - useAgentCoreV1: VSCodeSettings.useAgentCoreV1, broadcast: (event: string, data: unknown, webviewId?: string) => { broadcasts.push({ event, data, webviewId }); }, @@ -127,7 +121,7 @@ async function createRuntimeRig(extraAliases: readonly string[] = []): Promise<R try { await closeProvider(); } finally { - await rm(rootDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 }); + await rm(rootDir, { recursive: true, force: true }); } } }); @@ -155,11 +149,11 @@ async function createPlainHarness(homeDir: string): Promise<KimiHarness> { async function createMcpHandlerRig(): Promise<McpHandlerRig> { const homeDir = await mkdtemp(join(tmpdir(), "kimi-vscode-mcp-handler-")); - cleanups.push(() => rm(homeDir, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 })); + cleanups.push(() => rm(homeDir, { recursive: true, force: true })); const harness = await createPlainHarness(homeDir); const broadcasts: BroadcastRecord[] = []; const logs: LogRecord[] = []; - return { homeDir, harness, broadcasts, logs }; + return { harness, broadcasts, logs }; } async function updateMcpServer( @@ -173,26 +167,6 @@ async function getMcpServers(rig: McpHandlerRig): Promise<MCPServerConfig[]> { return mcpHandlers[Methods.GetMCPServers]!(undefined, mcpHandlerContext(rig)) as Promise<MCPServerConfig[]>; } -/** - * `harness.listMcpServers()` without the management-plane tags (`source` / - * `origin` / `mutable`) — these tests assert the stored config payload only. - */ -async function listStoredMcpServers(rig: McpHandlerRig): Promise<unknown[]> { - return (await rig.harness.listMcpServers()).map( - ({ source: _source, origin: _origin, mutable: _mutable, ...entry }) => entry, - ); -} - -/** - * The Webview payload minus the management-plane tags — most handler tests - * assert the config payload only; the tags have their own passthrough test. - */ -function stripMcpTags(servers: MCPServerConfig[]): unknown[] { - return servers.map( - ({ source: _source, origin: _origin, mutable: _mutable, ...entry }) => entry, - ); -} - function mcpHandlerContext(rig: McpHandlerRig): HandlerContext { return { harness: rig.harness, @@ -246,9 +220,7 @@ model = "mock-model" max_context_size = 128000 ${extra} [loop_control] -# The v1 engine reads max_retries_per_step; v2 renamed it to max_attempts_per_step. max_retries_per_step = 1 -max_attempts_per_step = 1 `, "utf8", ); @@ -456,7 +428,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () const servers = await getMcpServers(rig); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "remote", transport: "http", @@ -481,65 +453,6 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () expect(JSON.stringify(servers)).not.toMatch(/header-secret|cookie-secret|api-key-secret|env-secret/); }); - it("passes the management-plane tags through to the Webview payload", async () => { - const rig = await createMcpHandlerRig(); - await rig.harness.addMcpServer({ - name: "remote", - transport: "http", - url: "https://example.test/mcp", - }); - - const servers = await getMcpServers(rig); - - expect(servers).toEqual([ - { - name: "remote", - transport: "http", - url: "https://example.test/mcp", - source: "global", - origin: join(rig.homeDir, "mcp.json"), - mutable: true, - }, - ]); - }); - - it("keeps project-layer servers in the list refreshed after every mutation", async () => { - const rig = await createMcpHandlerRig(); - const project = await mkdtemp(join(tmpdir(), "kimi-vscode-mcp-project-")); - cleanups.push(() => rm(project, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 })); - await mkdir(join(project, ".git"), { recursive: true }); - await writeFile( - join(project, ".mcp.json"), - JSON.stringify({ - mcpServers: { "project-api": { transport: "http", url: "https://example.test/project" } }, - }), - ); - const ctx = { ...mcpHandlerContext(rig), workDir: project } as HandlerContext; - const call = <T>(handler: string, params: unknown) => - mcpHandlers[handler]!(params, ctx) as Promise<T>; - - // The initial workspace-aware list shows the project entry as read-only, - // and every mutation's refreshed list keeps showing it (the mutation RPCs - // return a cwd-less list, so the handler must re-list with the workspace). - const assertList = (servers: MCPServerConfig[]): void => { - const projectEntry = servers.find((server) => server.name === "project-api"); - expect(projectEntry).toMatchObject({ mutable: false, url: "https://example.test/project" }); - }; - assertList(await call(Methods.GetMCPServers, undefined)); - - const added = await call<MCPServerConfig[]>(Methods.AddMCPServer, { - name: "user-api", - transport: "http", - url: "https://example.test/user", - }); - assertList(added); - assertList(rig.broadcasts.at(-1)!.data as MCPServerConfig[]); - - const removed = await call<MCPServerConfig[]>(Methods.RemoveMCPServer, { name: "user-api" }); - assertList(removed); - assertList(rig.broadcasts.at(-1)!.data as MCPServerConfig[]); - }); - it("logs a failed MCP test without returning credential values to the Webview", async () => { const rig = await createMcpHandlerRig(); vi.spyOn(rig.harness, "testMcpServer").mockResolvedValue({ @@ -591,7 +504,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "remote", transport: "http", @@ -605,7 +518,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () expect(rig.broadcasts).toEqual([ { event: Events.MCPServersChanged, data: servers, webviewId: undefined }, ]); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "remote", transport: "http", @@ -643,7 +556,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "local", transport: "stdio", @@ -654,7 +567,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }, ]); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "local", transport: "stdio", @@ -687,7 +600,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }); expect(servers[0]?.headers).toEqual({ Authorization: MCP_SECRET_MASK }); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "remote", transport: "http", @@ -717,7 +630,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }); expect(servers[0]?.env).toEqual({ SERVICE_TOKEN: MCP_SECRET_MASK }); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "local", transport: "stdio", @@ -744,7 +657,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () auth: "oauth", }); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "remote", transport: "http", @@ -776,7 +689,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "local", transport: "stdio", @@ -806,7 +719,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "local", transport: "stdio", @@ -838,7 +751,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "remote", transport: "http", @@ -871,7 +784,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "remote", transport: "http", @@ -904,7 +817,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "remote", transport: "http", @@ -935,7 +848,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "new-name", transport: "stdio", @@ -944,7 +857,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () enabled: false, }, ]); - await expect(listStoredMcpServers(rig)).resolves.toEqual([ + await expect(rig.harness.listMcpServers()).resolves.toEqual([ { name: "new-name", transport: "stdio", @@ -972,7 +885,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "windows", transport: "stdio", @@ -999,7 +912,7 @@ describe("VS Code Kimi harness integration (shares one in-process SDK home)", () }, }); - expect(stripMcpTags(servers)).toEqual([ + expect(servers).toEqual([ { name: "windows", transport: "stdio", diff --git a/apps/vscode/test/kimi-runtime.test.ts b/apps/vscode/test/kimi-runtime.test.ts index 94fb08f99..6a86f7f2d 100644 --- a/apps/vscode/test/kimi-runtime.test.ts +++ b/apps/vscode/test/kimi-runtime.test.ts @@ -20,31 +20,11 @@ import type { SessionSummary, ThinkingEffort, } from "@moonshot-ai/kimi-code-sdk"; -import { describe, expect, it, vi } from "vitest"; +import { describe, expect, it } from "vitest"; import { Events } from "../shared/bridge"; import { KimiRuntime, type OpenSessionOptions } from "../src/runtime/kimi-runtime"; -const sdkFactories = vi.hoisted(() => { - const v1Harness = { homeDir: "/tmp/kimi-runtime-v1-home", close: vi.fn(async () => undefined) }; - const v2Harness = { homeDir: "/tmp/kimi-runtime-v2-home", close: vi.fn(async () => undefined) }; - return { - v1Harness, - v2Harness, - createKimiHarness: vi.fn(() => v1Harness), - createKimiHarnessV2: vi.fn(() => v2Harness), - }; -}); - -vi.mock("@moonshot-ai/kimi-code-sdk", async (importOriginal) => { - const original = await importOriginal<typeof import("@moonshot-ai/kimi-code-sdk")>(); - return { - ...original, - createKimiHarness: sdkFactories.createKimiHarness, - createKimiHarnessV2: sdkFactories.createKimiHarnessV2, - }; -}); - interface FakeSessionBoundary { readonly session: Session; readonly setModels: string[]; @@ -266,39 +246,6 @@ function createRuntime( } describe("Kimi runtime (owns shared SDK sessions for Webviews)", () => { - it("creates the v2 harness by default and the v1 harness for rollback", async () => { - const defaults = new KimiRuntime({ - version: "0.6.0", - broadcast: () => undefined, - captureBaseline: () => undefined, - log: () => undefined, - }); - expect(sdkFactories.createKimiHarnessV2).toHaveBeenCalledOnce(); - expect(sdkFactories.createKimiHarnessV2).toHaveBeenCalledWith({ - homeDir: undefined, - identity: { - productName: "kimi-code-vscode", - version: "0.6.0", - platform: "kimi_code_vscode", - }, - uiMode: "vscode", - }); - expect(sdkFactories.createKimiHarness).not.toHaveBeenCalled(); - expect(defaults.harness).toBe(sdkFactories.v2Harness as unknown as KimiHarness); - await defaults.dispose(); - - const rollback = new KimiRuntime({ - version: "0.6.0", - useAgentCoreV1: true, - broadcast: () => undefined, - captureBaseline: () => undefined, - log: () => undefined, - }); - expect(sdkFactories.createKimiHarness).toHaveBeenCalledOnce(); - expect(rollback.harness).toBe(sdkFactories.v1Harness as unknown as KimiHarness); - await rollback.dispose(); - }); - it("forwards the requested settings when creating an SDK session", async () => { const { runtime, sdk } = createRuntime(); diff --git a/apps/vscode/test/settings-store.test.ts b/apps/vscode/test/settings-store.test.ts index 38af845f2..93d0decad 100644 --- a/apps/vscode/test/settings-store.test.ts +++ b/apps/vscode/test/settings-store.test.ts @@ -384,7 +384,7 @@ describe("Webview thinking effort parity with the TUI", () => { expect(boundary.saveConfig).not.toHaveBeenCalled(); }); - it("seeds the top tier when it is the model's delivered default", () => { + it("does not seed future sessions with the model's top declared tier", () => { boundary.saveConfig.mockResolvedValue({ ok: true }); useSettingsStore.getState().initModels(MODELS, "reasoning", false); @@ -392,128 +392,6 @@ describe("Webview thinking effort parity with the TUI", () => { expect(useSettingsStore.getState().thinkingEffort).toBe("high"); expect(boundary.saveConfig).toHaveBeenCalledWith({ model: "reasoning", thinking: true, effort: "high" }); - expect(useSettingsStore.getState().defaultThinkingEffort).toBe("high"); - }); - - it("does not seed a pick above the model's delivered default", () => { - boundary.saveConfig.mockResolvedValue({ ok: true }); - useSettingsStore.getState().initModels([ - { - id: "reasoning", - name: "Reasoning", - provider: "managed:kimi-code", - capabilities: ["thinking"], - support_efforts: ["low", "high", "max"], - default_effort: "low", - }, - ], "reasoning", false); - - useSettingsStore.getState().selectThinkingEffort("high"); - - expect(useSettingsStore.getState().thinkingEffort).toBe("high"); - expect(boundary.saveConfig).toHaveBeenCalledWith({ model: "reasoning", thinking: true, effort: "high" }); - expect(useSettingsStore.getState().defaultThinkingEffort).toBeUndefined(); - }); - - it("does not seed the top tier when the model declares no default", () => { - boundary.saveConfig.mockResolvedValue({ ok: true }); - useSettingsStore.getState().initModels([ - { - id: "reasoning", - name: "Reasoning", - provider: "managed:kimi-code", - capabilities: ["thinking"], - support_efforts: ["low", "high"], - }, - ], "reasoning", false); - - useSettingsStore.getState().selectThinkingEffort("high"); - - expect(useSettingsStore.getState().thinkingEffort).toBe("high"); - expect(boundary.saveConfig).toHaveBeenCalledWith({ model: "reasoning", thinking: true, effort: "high" }); - expect(useSettingsStore.getState().defaultThinkingEffort).toBeUndefined(); - }); - - const SWITCH_MODELS = [ - { - id: "seeded", - name: "Seeded", - provider: "managed:kimi-code", - capabilities: ["thinking"], - support_efforts: ["low", "medium"], - default_effort: "medium", - }, - { - id: "max-default", - name: "Max Default", - provider: "managed:kimi-code", - capabilities: ["thinking"], - support_efforts: ["low", "max"], - default_effort: "max", - }, - ]; - - it("updates the seed when a model switch persists the derived effort", () => { - boundary.saveConfig.mockResolvedValue({ ok: true }); - useSettingsStore.getState().initModels(SWITCH_MODELS, "seeded", true, "medium"); - - // "medium" is unsupported here, so the switch derives the model default - // "max"; with the delivered default at the top tier the host persists it. - useSettingsStore.getState().updateModel("max-default"); - - expect(useSettingsStore.getState().thinkingEffort).toBe("max"); - expect(boundary.saveConfig).toHaveBeenCalledWith({ - model: "max-default", - thinking: true, - effort: "max", - effortChanged: true, - }); - expect(useSettingsStore.getState().defaultThinkingEffort).toBe("max"); - }); - - it("rolls the seed back when the model-switch save fails", async () => { - let rejectSave!: (error: Error) => void; - boundary.saveConfig.mockReturnValue(new Promise((_resolve, reject) => { - rejectSave = reject; - })); - useSettingsStore.getState().initModels(SWITCH_MODELS, "seeded", true, "medium"); - - useSettingsStore.getState().updateModel("max-default"); - expect(useSettingsStore.getState().defaultThinkingEffort).toBe("max"); - - rejectSave(new Error("config.toml is read-only")); - await vi.waitFor(() => { - expect(useSettingsStore.getState().defaultThinkingEffort).toBe("medium"); - }); - }); - - it("leaves the seed alone when the switch re-confirms the active effort", () => { - boundary.saveConfig.mockResolvedValue({ ok: true }); - // No persisted effort: the seed starts undefined and the session derives - // "max" from the model default. - useSettingsStore.getState().initModels([ - ...SWITCH_MODELS, - { - id: "max-default-b", - name: "Max Default B", - provider: "managed:kimi-code", - capabilities: ["thinking"], - support_efforts: ["low", "max"], - default_effort: "max", - }, - ], "max-default", true); - - // The derived effort equals the active one, so the host leaves the stored - // preference untouched — the seed must not invent one either. - useSettingsStore.getState().updateModel("max-default-b"); - - expect(useSettingsStore.getState().thinkingEffort).toBe("max"); - expect(boundary.saveConfig).toHaveBeenCalledWith({ - model: "max-default-b", - thinking: true, - effort: "max", - effortChanged: false, - }); expect(useSettingsStore.getState().defaultThinkingEffort).toBeUndefined(); }); diff --git a/apps/vscode/test/vscode-settings.test.ts b/apps/vscode/test/vscode-settings.test.ts deleted file mode 100644 index 9156b0075..000000000 --- a/apps/vscode/test/vscode-settings.test.ts +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Scenario: the engine rollback switch is the single engine-selection decision. - * Responsibilities: default to the v2 engine, honor the setting, let a truthy - * KIMI_CODE_LEGACY_FLAG override the setting, and ignore non-truthy env values. - * Wiring: the real VSCodeSettings module; the vscode configuration store is a - * mutable in-memory fake. - * Run: pnpm --filter kimi-code exec vitest run test/vscode-settings.test.ts - */ -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; - -const configStore = vi.hoisted(() => ({ values: new Map<string, unknown>() })); - -vi.mock("vscode", () => ({ - workspace: { - getConfiguration: () => ({ - get: (key: string, fallback: unknown) => configStore.values.get(key) ?? fallback, - }), - }, -})); - -import { - LEGACY_ENGINE_ENV, - resolveUseAgentCoreV1, - VSCodeSettings, -} from "../src/config/vscode-settings"; - -beforeEach(() => { - // A developer shell may export the flag; the cases set it explicitly. - vi.stubEnv(LEGACY_ENGINE_ENV, ""); -}); - -afterEach(() => { - configStore.values.clear(); - vi.unstubAllEnvs(); -}); - -describe("resolveUseAgentCoreV1", () => { - it("defaults to the v2 engine", () => { - expect(resolveUseAgentCoreV1(false, {})).toBe(false); - }); - - it("honors the setting when the env var is absent", () => { - expect(resolveUseAgentCoreV1(true, {})).toBe(true); - }); - - it("lets a truthy env var override a false setting", () => { - for (const value of ["1", "true", "TRUE", " yes ", "on"]) { - expect(resolveUseAgentCoreV1(false, { [LEGACY_ENGINE_ENV]: value })).toBe(true); - } - }); - - it("ignores non-truthy env values and falls back to the setting", () => { - for (const value of ["", "0", "false", "off", "anything"]) { - expect(resolveUseAgentCoreV1(true, { [LEGACY_ENGINE_ENV]: value })).toBe(true); - expect(resolveUseAgentCoreV1(false, { [LEGACY_ENGINE_ENV]: value })).toBe(false); - } - }); -}); - -describe("VSCodeSettings.useAgentCoreV1", () => { - it("reads the kimi.useAgentCoreV1 setting", () => { - expect(VSCodeSettings.useAgentCoreV1).toBe(false); - configStore.values.set("useAgentCoreV1", true); - expect(VSCodeSettings.useAgentCoreV1).toBe(true); - }); - - it("lets the env var override the setting", () => { - vi.stubEnv(LEGACY_ENGINE_ENV, "1"); - expect(VSCodeSettings.useAgentCoreV1).toBe(true); - }); -}); diff --git a/apps/vscode/webview-ui/src/components/LoginScreen.tsx b/apps/vscode/webview-ui/src/components/LoginScreen.tsx index 8826e362d..07fff46b4 100644 --- a/apps/vscode/webview-ui/src/components/LoginScreen.tsx +++ b/apps/vscode/webview-ui/src/components/LoginScreen.tsx @@ -70,11 +70,6 @@ export function LoginScreen({ onLoginSuccess, onSkip }: LoginScreenProps) { }; const handleSubscribe = () => { - // TODO(region-split): derive this from the region profile's siteBase - // (`https://www.kimi.ai/code` for overseas logins). The webview cannot - // resolve the region itself — @moonshot-ai/kimi-code-oauth is not a - // webview dependency and its region resolver is Node-only — so the - // extension host needs to hand the site URL over the bridge first. window.open("https://www.kimi.com/code", "_blank"); setShowSubscribeDialog(false); }; diff --git a/apps/vscode/webview-ui/src/components/MCPServersModal.tsx b/apps/vscode/webview-ui/src/components/MCPServersModal.tsx index 991f87055..326534f61 100644 --- a/apps/vscode/webview-ui/src/components/MCPServersModal.tsx +++ b/apps/vscode/webview-ui/src/components/MCPServersModal.tsx @@ -379,11 +379,9 @@ function ServerItem({ server, onDelete }: { server: MCPServerConfig; onDelete: ( <Button variant="ghost" size="icon" className="size-6" onClick={() => { void handleTest(); }} disabled={isLoading}> {isLoading ? <IconLoader2 className="size-3 animate-spin" /> : <IconPlugConnected className="size-3" />} </Button> - {server.mutable !== false && ( - <Button variant="ghost" size="icon" className="size-6 text-muted-foreground hover:text-destructive" onClick={onDelete} disabled={isLoading}> - <IconTrash className="size-3" /> - </Button> - )} + <Button variant="ghost" size="icon" className="size-6 text-muted-foreground hover:text-destructive" onClick={onDelete} disabled={isLoading}> + <IconTrash className="size-3" /> + </Button> </div> <IconChevronDown className={cn("size-3.5 text-muted-foreground transition-transform", expanded && "rotate-180")} /> </div> @@ -399,15 +397,7 @@ function ServerItem({ server, onDelete }: { server: MCPServerConfig; onDelete: ( ))} </div> )} - {server.mutable === false ? ( - <p className="text-[10px] text-muted-foreground"> - {server.source === "plugin" - ? `Contributed by plugin "${server.origin ?? ""}" — update the plugin manifest instead` - : `Defined in ${server.origin ?? "a project config file"} — edit that file instead`} - </p> - ) : ( - <ServerForm data={form} onChange={setForm} onSubmit={() => { void handleUpdate(); }} onCancel={() => setExpanded(false)} submitLabel="Update" /> - )} + <ServerForm data={form} onChange={setForm} onSubmit={() => { void handleUpdate(); }} onCancel={() => setExpanded(false)} submitLabel="Update" /> </div> )} </div> diff --git a/apps/vscode/webview-ui/src/components/QuestionDialog.tsx b/apps/vscode/webview-ui/src/components/QuestionDialog.tsx index c5f2e46fd..c4919269a 100644 --- a/apps/vscode/webview-ui/src/components/QuestionDialog.tsx +++ b/apps/vscode/webview-ui/src/components/QuestionDialog.tsx @@ -9,12 +9,9 @@ export function QuestionDialog() { const [selectedIndex, setSelectedIndex] = useState(1); const [questionIndex, setQuestionIndex] = useState(0); const [answers, setAnswers] = useState<Record<string, string>>({}); - const [multiSelected, setMultiSelected] = useState<string[]>([]); const questions = pendingQuestion?.questions ?? []; const question = questions[questionIndex]; - const isMultiSelect = question?.multi_select === true; - const isLastQuestion = questionIndex + 1 >= questions.length; useEffect(() => { if (pendingQuestion) { @@ -23,7 +20,6 @@ export function QuestionDialog() { setSelectedIndex(1); setQuestionIndex(0); setAnswers({}); - setMultiSelected([]); } }, [pendingQuestion?.id]); @@ -32,43 +28,28 @@ export function QuestionDialog() { // Step through the questions one by one; submit all answers after the last. const handleAnswer = async (answer: string) => { const nextAnswers = { ...answers, [question.question]: answer }; - if (!isLastQuestion) { + if (questionIndex + 1 < questions.length) { setAnswers(nextAnswers); setQuestionIndex(questionIndex + 1); setShowCustom(false); setCustomInput(""); setSelectedIndex(1); - setMultiSelected([]); } else { await respondQuestion(nextAnswers); } }; const handleSelect = async (optionLabel: string) => { - if (isMultiSelect) { - setMultiSelected((prev) => - prev.includes(optionLabel) ? prev.filter((value) => value !== optionLabel) : [...prev, optionLabel], - ); - return; - } await handleAnswer(optionLabel); }; const handleCustomSubmit = async () => { - const value = customInput.trim(); - if (!value) return; - if (isMultiSelect) { - setMultiSelected((prev) => (prev.includes(value) ? prev : [...prev, value])); - setCustomInput(""); - setShowCustom(false); - return; - } - await handleAnswer(value); + if (!customInput.trim()) return; + await handleAnswer(customInput.trim()); }; const options = question.options || []; const customIndex = options.length + 1; - const customValues = multiSelected.filter((value) => !options.some((option) => option.label === value)); return ( <div className={cn("mb-0.5 border border-blue-200 dark:border-blue-800 rounded-lg overflow-hidden bg-background flex flex-col shrink")}> @@ -80,51 +61,25 @@ export function QuestionDialog() { )} {question.header && <div className="text-[10px] text-muted-foreground uppercase tracking-wide">{question.header}</div>} <div className="text-xs font-semibold text-foreground">{question.question}</div> - {isMultiSelect && <div className="text-[10px] text-muted-foreground">Select all that apply</div>} <div className="space-y-1.5"> - {options.map((option, idx) => { - const isChecked = isMultiSelect && multiSelected.includes(option.label); - const isHighlighted = selectedIndex === idx + 1; - return ( - <button - key={idx} - onClick={() => { - void handleSelect(option.label); - }} - onMouseEnter={() => setSelectedIndex(idx + 1)} - className={cn( - "w-full text-left px-2 py-1 rounded-md text-xs transition-colors", - "border cursor-pointer", - isChecked - ? "bg-blue-500/15 border-blue-500" - : isHighlighted - ? "bg-blue-500 text-white border-blue-500" - : "bg-background border-border hover:bg-muted/50", - )} - > - <span className={cn("mr-2", isHighlighted && !isChecked ? "text-blue-200" : "text-muted-foreground")}> - {isChecked ? "✓" : idx + 1} - </span> - <span className="font-medium">{option.label}</span> - {option.description && ( - <span className={cn("ml-2", isHighlighted && !isChecked ? "text-blue-200" : "text-muted-foreground")}>- {option.description}</span> - )} - </button> - ); - })} - {customValues.map((value) => ( + {options.map((option, idx) => ( <button - key={value} + key={idx} onClick={() => { - void handleSelect(value); + void handleSelect(option.label); }} + onMouseEnter={() => setSelectedIndex(idx + 1)} className={cn( "w-full text-left px-2 py-1 rounded-md text-xs transition-colors", - "border cursor-pointer bg-blue-500/15 border-blue-500", + "border border-border cursor-pointer", + selectedIndex === idx + 1 ? "bg-blue-500 text-white border-blue-500" : "bg-background hover:bg-muted/50", )} > - <span className="mr-2 text-muted-foreground">✓</span> - <span className="font-medium">{value}</span> + <span className={cn("mr-2", selectedIndex === idx + 1 ? "text-blue-200" : "text-muted-foreground")}>{idx + 1}</span> + <span className="font-medium">{option.label}</span> + {option.description && ( + <span className={cn("ml-2", selectedIndex === idx + 1 ? "text-blue-200" : "text-muted-foreground")}>- {option.description}</span> + )} </button> ))} {showCustom ? ( @@ -164,17 +119,6 @@ export function QuestionDialog() { <span className="font-medium">Custom response...</span> </button> )} - {isMultiSelect && ( - <button - onClick={() => { - void handleAnswer(multiSelected.join(", ")); - }} - disabled={multiSelected.length === 0} - className="w-full px-2 py-1 rounded-md text-xs bg-blue-500 text-white disabled:opacity-50 cursor-pointer" - > - {isLastQuestion ? "Submit" : "Next"} - </button> - )} </div> </div> </div> diff --git a/apps/vscode/webview-ui/src/stores/settings.store.ts b/apps/vscode/webview-ui/src/stores/settings.store.ts index 9eed4e8b2..4c8c4e7a1 100644 --- a/apps/vscode/webview-ui/src/stores/settings.store.ts +++ b/apps/vscode/webview-ui/src/stores/settings.store.ts @@ -102,23 +102,6 @@ function defaultEffortForModel(model: ModelConfig, defaultThinking: boolean, con return defaultThinking ? "on" : "off"; } -/** - * Whether picking `effort` persists it as the global default — mirrors the - * extension host's thinkingConfig gate: a pick above the model's effective - * default effort stays session-only, with the ceiling falling back to the - * tier below the top when the model carries no listed default. Only listed - * efforts reach this helper (selectThinkingEffort rejects the rest). - */ -function persistsAsDefaultEffort(model: ModelConfig, effort: string): boolean { - const efforts = model.support_efforts ?? []; - const declared = model.default_effort; - const ceiling = - declared !== undefined && efforts.includes(declared) - ? efforts.indexOf(declared) - : efforts.length - 2; - return efforts.indexOf(effort) <= ceiling; -} - export function isImageModel(model: ModelConfig): boolean { return model.capabilities.includes("image_in"); } @@ -220,29 +203,15 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({ } const thinkingEffort = defaultEffortForModel(model, defaultThinking, defaultThinkingEffort); - const effortChanged = thinkingEffort !== previousEffort; - set({ - currentModel: modelId, - thinkingEffort, - // The save below persists the derived effort when it changed and - // clears the gate — keep the seed in sync, or the next switch derives - // from a stale value and saves it back over the persisted one. - defaultThinkingEffort: - effortChanged && - thinkingEffort !== "off" && - thinkingEffort !== "on" && - persistsAsDefaultEffort(model, thinkingEffort) - ? thinkingEffort - : defaultThinkingEffort, - }); + set({ currentModel: modelId, thinkingEffort }); saveConfigWithRollback( { model: modelId, thinking: thinkingEffort !== "off", effort: thinkingEffort, - effortChanged, + effortChanged: thinkingEffort !== previousEffort, }, - { currentModel, thinkingEffort: previousEffort, defaultThinkingEffort }, + { currentModel, thinkingEffort: previousEffort }, set, ); }, @@ -289,13 +258,11 @@ export const useSettingsStore = create<SettingsState>((set, get) => ({ set({ thinkingEffort, defaultThinking: thinkingEffort !== "off", - // A pick above the model's effective default effort is session-only - // (only the boolean toggle is persisted), so it must not become the - // configured-effort seed for future sessions. + // The model's top declared tier is session-only (only the boolean + // toggle is persisted), so it must not become the configured-effort + // seed for future sessions. defaultThinkingEffort: - thinkingEffort !== "off" && - thinkingEffort !== "on" && - persistsAsDefaultEffort(model, thinkingEffort) + thinkingEffort !== "off" && thinkingEffort !== "on" && thinkingEffort !== allowed.at(-1) ? thinkingEffort : defaultThinkingEffort, }); diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 7d8ea8a71..f35266ad5 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -56,7 +56,6 @@ const config = withMermaid(defineConfig({ { text: '会话与上下文', link: '/zh/guides/sessions' }, { text: '使用目标模式', link: '/zh/guides/goals' }, { text: '在 IDE 中使用', link: '/zh/guides/ides' }, - { text: '本地服务与 API', link: '/zh/guides/server' }, ], }, ], @@ -67,7 +66,7 @@ const config = withMermaid(defineConfig({ { text: 'Model Context Protocol', link: '/zh/customization/mcp' }, { text: 'Agent Skills', link: '/zh/customization/skills' }, { text: 'Plugins', link: '/zh/customization/plugins' }, - { text: 'Agent 与 subagent', link: '/zh/customization/agents' }, + { text: 'Agent 与子 Agent', link: '/zh/customization/agents' }, { text: 'Hooks', link: '/zh/customization/hooks' }, { text: '自定义主题', link: '/zh/customization/themes' }, ], @@ -91,7 +90,6 @@ const config = withMermaid(defineConfig({ items: [ { text: 'kimi 命令', link: '/zh/reference/kimi-command' }, { text: 'kimi acp 子命令', link: '/zh/reference/kimi-acp' }, - { text: '服务 API', link: '/zh/reference/server-api' }, { text: '内置工具', link: '/zh/reference/tools' }, { text: '斜杠命令', link: '/zh/reference/slash-commands' }, { text: '键盘快捷键', link: '/zh/reference/keyboard' }, @@ -135,7 +133,6 @@ const config = withMermaid(defineConfig({ { text: 'Sessions and Context', link: '/en/guides/sessions' }, { text: 'Using Goals', link: '/en/guides/goals' }, { text: 'Using in IDEs', link: '/en/guides/ides' }, - { text: 'Local Server and API', link: '/en/guides/server' }, ], }, ], @@ -170,7 +167,6 @@ const config = withMermaid(defineConfig({ items: [ { text: 'kimi Command', link: '/en/reference/kimi-command' }, { text: 'kimi acp Subcommand', link: '/en/reference/kimi-acp' }, - { text: 'Server API', link: '/en/reference/server-api' }, { text: 'Built-in Tools', link: '/en/reference/tools' }, { text: 'Slash Commands', link: '/en/reference/slash-commands' }, { text: 'Keyboard Shortcuts', link: '/en/reference/keyboard' }, diff --git a/docs/AGENTS.md b/docs/AGENTS.md index c03f44391..86f36083d 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -67,8 +67,8 @@ Term mapping (Chinese <-> English, and proper noun handling): | Chinese | English | Proper noun (zh) | Proper noun (en) | | --- | --- | --- | --- | | Agent | agent | yes | no | -| main agent | main agent | no | no | -| subagent | subagent | no | no | +| 主 Agent | main agent | yes (Agent) | no | +| 子 Agent | subagent | yes (Agent) | no | | Shell | shell | yes | no | | Plan 模式 | Plan mode | yes | yes (Plan mode) | | YOLO 模式 | YOLO mode | yes | yes (YOLO mode) | diff --git a/docs/en/configuration/config-files.md b/docs/en/configuration/config-files.md index d4867efba..27f5f03f3 100644 --- a/docs/en/configuration/config-files.md +++ b/docs/en/configuration/config-files.md @@ -40,7 +40,7 @@ model = "k3" max_context_size = 1048576 capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] display_name = "K3" -support_efforts = [ "low", "high", "max" ] +support_efforts = [ "max" ] default_effort = "max" [models."kimi-code/kimi-for-coding"] @@ -192,110 +192,34 @@ You can also switch models temporarily without touching the config file — by s ## `secondary_model` -Subagents inherit the model the main agent is running by default. The `[secondary_model]` section makes this configurable: it offers subagents a pool of candidate models plus a default binding — typically a cheaper model for subtasks that do not need the main model's capability. +The secondary model is a second model configuration alongside the main model — typically a cheaper one, for features that do not need the main model's capability. Its consumer today is subagent spawning: when set, newly spawned subagents (`Agent` / `AgentSwarm`) bind to it by default instead of inheriting the main agent's model; when unset, subagents inherit the main agent's model. -### Subagent model pool +This is a default binding, not a forced one. With the experiment enabled, the `Agent` / `AgentSwarm` tools gain a `model` parameter (accepting only the symbolic values `"secondary"` / `"primary"`), and the tool description lists the available models with the default marked. A spawn resolves the subagent's model in this order: an explicit tool-call `model` → the profile's [`model_preference`](../customization/agents.md#agent-file-format) → the configured secondary model (the default). Here `"primary"` means the model the main agent is currently running, not necessarily `default_model` — for example after a mid-session `/model` switch. -This feature is experimental and disabled by default. Enable it with `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`, or the master `KIMI_CODE_EXPERIMENTAL_FLAG=1`; it takes effect in every launch mode, including the interactive TUI. While the experiment is off, the pool keys stay inert: subagents inherit the caller's model and session startup skips the pool validation. +Because overriding the default is the main agent's own decision (the tool description merely suggests `"secondary"` for routine tasks and `"primary"` for hard, quality-sensitive ones), there is no per-spawn switch on the user side. To steer a specific subagent to the main model, ask the main agent in your prompt to pass `model: "primary"`, or set `model_preference: "primary"` in the corresponding profile. -The minimal configuration is one line — a lone `default_model` is a pool with a single entry: +This feature is experimental and disabled by default. Enable it with `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`, or the master `KIMI_CODE_EXPERIMENTAL_FLAG=1`. It takes effect in every launch mode, including the interactive TUI. -```toml -[secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -``` +In the interactive TUI, the [`/secondary_model`](../reference/slash-commands.md) command opens a model picker that writes this section and live-applies it to the current session, so newly spawned subagents bind the new secondary model right away. | Field | Type | Default | Description | | --- | --- | --- | --- | -| `default_model` | `string` | — | The default model for subagents | -| `models` | `table<string, string>` | — | Subagent model pool. Each key is the alias of a configured [`[models]`](#models) entry; each value is the selection hint shown to the main agent | -| `force` | `boolean` | `false` | Pin every subagent to `default_model`, taking the choice away from the main agent | -| `default_effort` | `string` | — | The thinking effort every spawned subagent binds with; outranks the bound model entry's own `default_effort` | +| `model` | `string` | — | The alias of a configured [`[models]`](#models) entry, e.g. `kimi-code/kimi-k2.5` (any provider, not limited to Kimi models) | +| `default_effort` | `string` | — | Thinking effort applied when subagents bind to the secondary model. Unset, the effort resolves naturally (global `[thinking]` config → the bound model's default effort) instead of inheriting the main agent's effort. Follows the main model's thinking-effort semantics: models with strict effort validation (e.g. Kimi models) fall back to their default effort for unsupported values; other providers receive the value as-is | +| Other fields | — | — | Accepts every field of [`[models."<alias>".overrides]`](#models) (`max_context_size`, `max_output_size`, `support_efforts`, …) as a model patch applied only to subagents | -Constraints between the fields: - -- `default_model`: required when a `models` table is configured, and must be one of its keys. -- `models`: values may be Chinese or English; an empty string lists the alias with no hint. -- `force`: requires `default_model` and cannot be combined with a `models` table — the table exists to offer a choice, and force removes it. -- `default_effort` is section-wide: every spawn binds it regardless of the chosen pool entry (or the forced model). For per-entry efforts, leave it unset and use model variants (see below). -- `primary` is a reserved alias (see below) and cannot be a pool key. - -In the interactive TUI, the [`/secondary-model`](../reference/slash-commands.md) command (alias `/subagent-model`) opens a model selector: the choice is written to `default_model` (when a models table exists and the picked alias is not in it, an entry with an empty description is added), and newly spawned subagents pick up the new default immediately — no session restart needed. - -A configured pool — an explicit `models` table or a lone `default_model` — enables model selection: the `Agent` / `AgentSwarm` tools gain a `model` parameter, and the tool description lists the pool (the default marked `[default]`) so the main agent can choose per spawn. Pool keys can only reference configured [`[models]`](#models) entries — the `kimi-code/*` aliases below are provisioned by `/login`: +Every field besides `model` forms a patch: when at least one patch field is set, the runtime synthesizes a derived model entry in memory (a copy of the pointed entry with the patch merged into its overrides, patch winning conflicts) and subagents bind that derived entry; with no patch fields, subagents bind the pointed entry directly. The derived entry lives only in memory (never written back to `config.toml`) and is hidden from model-selection lists. ```toml [secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -[secondary_model.models] -"kimi-code/k3" = "Pick this for hard problems. Strong at complex reasoning, algorithm design, deep debugging, math, and systematic challenges." -"kimi-code/kimi-for-coding-highspeed" = "Fast but priced higher. Good for latency-sensitive tasks: daily refactoring, code explanation, small edits, and summaries." -"kimi-code/kimi-for-coding" = "A balanced coding workhorse. Good for most feature development and code-change tasks." +model = "kimi-code/kimi-k2.5" +default_effort = "low" +max_output_size = 8192 ``` -A spawn resolves the subagent's model in this order: +`model` / `default_effort` can be overridden by the `KIMI_SECONDARY_MODEL` / `KIMI_SECONDARY_EFFORT` environment variables, which take higher priority than `config.toml`. -1. An explicit `model` passed in the tool call -2. `default_model` - -Rules for the `model` parameter: - -- It accepts any pool alias, or `"primary"` — the model the caller itself is running, always valid even when not in the pool. -- When neither `default_model` nor `models` is configured, the parameter is not advertised and subagents inherit the caller's model. -- Binding a pool alias does not inherit the caller's thinking effort. The section's `default_effort` wins when set. Otherwise, `[thinking].enabled = false` keeps Thinking off; when Thinking is enabled, resolution continues with the bound model entry's `default_effort`, the global `[thinking].effort`, then the middle of the bound model's `support_efforts`. -- `"primary"` inherits both the model and the effort level from the caller. -- A value that is neither a pool alias nor `"primary"` fails the spawn with an error listing the available choices. - -To take the choice away from the main agent and run every subagent on one fixed model, add `force = true`: - -```toml -[secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -force = true -``` - -With `force` set, the `model` parameter is not advertised (just like when nothing is configured) and every spawn binds `default_model`; an explicit `model` argument, `"primary"` included, is rejected with an error. - -### Different thinking efforts per pool entry - -Binding a pool alias lands the subagent on the bound model's default effort. You can exploit this by registering a "variant" entry for the same underlying model, so the main agent picks the thinking level together with the alias: - -1. Register a second entry for the same underlying model in [`[models]`](#models), overriding only `default_effort` via [`[models."<alias>".overrides]`](#model-overrides). -2. List both the original alias and the variant alias in the pool. - -```toml -# "kimi-code/k3" is provisioned by /login (default: high); this registers -# a max-effort variant of the same model -[models.k3-max] -provider = "managed:kimi-code" -model = "k3" -max_context_size = 1048576 -capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] -support_efforts = [ "low", "high", "max" ] - -[models.k3-max.overrides] -default_effort = "max" - -[secondary_model] -default_model = "kimi-code/k3" -[secondary_model.models] -"kimi-code/k3" = "Default high effort. Good for most implementation, analysis, and multi-turn interaction tasks." -k3-max = "The same model at max thinking effort. Good for the hardest subtasks." -``` - -Two prerequisites: - -- The underlying model must declare `support_efforts` (under `managed:kimi-code` only the k3 family currently declares effort levels). -- The variant is a standalone entry and does not inherit fields from the entry it points at — copy `capabilities`, `support_efforts`, and the other metadata over in full, otherwise `default_effort` has no effect (it must be a member of `support_efforts`). - -Note the asymmetry between the main agent and pool-bound subagents: for the main agent, a configured global `[thinking].effort` overrides the variant's `default_effort`; for subagents the variant's `default_effort` wins over the global value, and only `[secondary_model].default_effort` outranks it. Value and fallback rules follow the [`[models]` entry's `default_effort`](#models). - -::: warning Note -Configuration errors fail loudly instead of falling back silently. Session creation, resume, and fork all fail at startup when: - -- `default_model` is missing, is not a pool key, or a pool key does not resolve to a configured [`[models]`](#models) entry; -- `force` is set without `default_model`, or combined with a `models` table. -::: +When the experiment is enabled, the configuration is validated as the session starts: an unresolvable `model`, or a `default_effort` not listed by the (patched) model, produces a startup warning (also returned by the session-warnings API). The check is advisory — a broken secondary model still fails at spawn time, with the same source hint attached to the spawn error. ## `thinking` @@ -357,28 +281,15 @@ Retries only apply to transient failures — connection errors, timeouts, HTTP 4 `keep_alive_on_exit` can be overridden by the `KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT` environment variable, and `max_running_tasks` by `KIMI_CODE_BACKGROUND_MAX_RUNNING_TASKS`; both take higher priority than `config.toml`. -In print mode (`kimi -p "<prompt>"`), Kimi Code stays alive after the main agent's turn as long as background tasks are still pending: each completion is fed back to the main agent as a synthetic user message, steering it into a new turn (`print_background_mode = "steer"` by default), and the run exits once a turn ends with nothing pending. The loop is bounded by `print_wait_ceiling_s` and `print_max_turns`, both effectively unbounded by default. Background work is never killed by a wall-clock cap in print mode either: background `Bash` tasks default to no timeout (`bash_task_timeout_s = 0`), and subagents run without a timeout (`[subagent] timeout_ms` and `[swarm] timeout_ms` both default to `0` unless explicitly set), so only the model itself stops a task. Set `print_background_mode` to `"drain"` to wait for tasks without feeding results back, or `"exit"` to end the run as soon as the main agent finishes. +In print mode (`kimi -p "<prompt>"`), Kimi Code stays alive after the main agent's turn as long as background tasks are still pending: each completion is fed back to the main agent as a synthetic user message, steering it into a new turn (`print_background_mode = "steer"` by default), and the run exits once a turn ends with nothing pending. The loop is bounded by `print_wait_ceiling_s` and `print_max_turns`, both effectively unbounded by default. Background work is never killed by a wall-clock cap in print mode either: background `Bash` tasks default to no timeout (`bash_task_timeout_s = 0`), and subagents run without a timeout (`[subagent] timeout_ms = 0`), so only the model itself stops a task. Set `print_background_mode` to `"drain"` to wait for tasks without feeding results back, or `"exit"` to end the run as soon as the main agent finishes. ## `subagent` -`subagent` controls how subagents spawned by the `Agent` tool run. - | Field | Type | Default | Description | | --- | --- | --- | --- | -| `timeout_ms` | `integer` | `7200000` (2 hours) | Maximum wall-clock time (milliseconds) a single `Agent` subagent is allowed to run before it is settled as `timed_out`. `0` means no timeout — the subagent runs until it finishes or the model stops it. This is the background-task manager's per-task timeout for each subagent task, so it applies to both foreground and background subagents. In print mode (`kimi -p`) the default is `0` unless explicitly set. Note: any value above `2147483647` (about 24.8 days) is clamped to roughly 24.8 days by the runtime | - +| `timeout_ms` | `integer` | `7200000` (2 hours) | Maximum wall-clock time (milliseconds) a single subagent (`Agent` / `AgentSwarm`) is allowed to run before it is settled as `timed_out`. `0` means no timeout — the subagent runs until it finishes or the model stops it. This is the background-task manager's per-task timeout for each subagent task, so it applies to both foreground and background subagents. In print mode (`kimi -p`) the default is `0` unless explicitly set. Note: any value above `2147483647` (about 24.8 days) is clamped to roughly 24.8 days by the runtime | `timeout_ms` can be overridden by the `KIMI_SUBAGENT_TIMEOUT_MS` environment variable, which takes higher priority than `config.toml`. -## `swarm` - -`swarm` controls how subagents launched by the `AgentSwarm` tool run, independently of `[subagent]`. - -| Field | Type | Default | Description | -| --- | --- | --- | --- | -| `timeout_ms` | `integer` | `7200000` (2 hours) | Maximum wall-clock time (milliseconds) a single `AgentSwarm` subagent is allowed to run. On timeout that subagent is aborted and marked as failed in the aggregated report (`Subagent timed out.`); the other subagents are unaffected. `0` means no timeout — the subagent runs until it finishes or the model stops it. In print mode (`kimi -p`) the default is `0` unless explicitly set. Note: any value above `2147483647` (about 24.8 days) is clamped to roughly 24.8 days by the runtime | - -`timeout_ms` can be overridden by the `KIMI_CODE_SWARM_TIMEOUT_MS` environment variable, which takes higher priority than `config.toml`. - ## `mcp` | Field | Type | Default | Description | @@ -517,7 +428,6 @@ Alongside `config.toml`, the CLI keeps terminal-UI and client preferences in a c | Field | Type | Default | Description | | --- | --- | --- | --- | | `theme` | `string` | `auto` | Color theme: `auto` (follow the terminal), `dark`, `light`, or the name of a [custom theme](../customization/themes.md) | -| `render_latex` | `boolean` | `true` | Render LaTeX math expressions (`$…$`, `$$…$$`) in Markdown messages as Unicode text; `false` keeps the raw source | | `disable_paste_burst` | `boolean` | `false` | Disable the non-bracketed paste-burst fallback that keeps rapid multi-line pastes from submitting line by line | | `cache_expiry_hint` | `boolean` | `true` | Show a dialog when resuming a long-idle session or submitting after a long idle stretch, warning that the context cache has likely expired and offering to compact or start a new session (v2 engine only) | | `[editor].command` | `string` | `""` | External editor command for composing long input; empty falls back to `$VISUAL` / `$EDITOR` | @@ -530,7 +440,6 @@ Alongside `config.toml`, the CLI keeps terminal-UI and client preferences in a c ```toml # ~/.kimi-code/tui.toml theme = "auto" # "auto" | "dark" | "light" | custom theme name -render_latex = true # false keeps LaTeX math in messages as raw source disable_paste_burst = false # true disables non-bracketed paste-burst fallback cache_expiry_hint = true # false disables the "cache expired" dialog on resume / idle submit diff --git a/docs/en/configuration/env-vars.md b/docs/en/configuration/env-vars.md index 144a4520b..4e519dda4 100644 --- a/docs/en/configuration/env-vars.md +++ b/docs/en/configuration/env-vars.md @@ -36,22 +36,6 @@ export KIMI_DISABLE_TELEMETRY=1 Switch models temporarily without modifying `config.toml` — when `KIMI_MODEL_NAME` is set, the CLI synthesizes a temporary provider in memory; the change does not persist after restart. See [Define a model from environment variables](#define-a-model-from-environment-variables-kimi-model). -### `KIMI_CODE_CUSTOM_HEADERS` - -Attaches custom HTTP headers to every outbound model request — both LLM chat requests (across all provider protocols) and `/models` listing requests. Useful when a gateway routes by header, for example to pin a specific cluster: - -```sh -export KIMI_CODE_CUSTOM_HEADERS=$'X-Gateway-Cluster: my-cluster\nX-Custom-Tag: debug' -``` - -The format mirrors `ANTHROPIC_CUSTOM_HEADERS`: newline-separated `Name: Value` lines. Names and values are trimmed, and lines without a colon are ignored. - -::: info Added -Added in 0.20.2. -::: - -> Precedence: the Kimi identity headers (`User-Agent`, `X-Msh-*`) and a provider's `custom_headers` in `config.toml` (see [Config files](./config-files.md#providers)) override same-named entries here. Authentication is protocol-dependent: on the `kimi`, `openai`, and `openai_responses` protocols an exact `Authorization` entry replaces the generated bearer token, while `/models` listing requests keep their own authentication. A case variant such as `authorization` is never treated as the same name — it is combined with the real header, which can break requests. Do not use this variable for authentication or other reserved headers. Use `custom_headers` when headers need to differ per provider. - ## Provider credential key names (written in config.toml) The key names below are not read directly from the shell — they are key names written inside the `[providers.<name>.env]` sub-table of `config.toml`, serving as fallback values for `api_key` / `base_url`. The CLI reads only from the config file, not from `process.env`. @@ -137,26 +121,23 @@ Switches that control the behavior of subsystems such as telemetry, background t | Variable | Purpose | Valid values | | --- | --- | --- | | `KIMI_DISABLE_TELEMETRY` | Disable anonymous telemetry reporting | `1`, `true`, `yes`, `y` (case-insensitive) | -| `KIMI_CODE_PASSWORD` | Set a parallel auth credential for the `kimi web` local server, valid alongside the bearer token; recommended when binding the server beyond loopback — see [Local server and API](../guides/server.md#authentication) | Any non-empty string; when unset, only the token is valid | | `KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT` | Whether to keep background tasks when the session closes; takes higher priority than `config.toml`. The default is to stop them on exit | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | | `KIMI_CODE_BACKGROUND_MAX_RUNNING_TASKS` | Cap on concurrently running background tasks; takes higher priority than `[background] max_running_tasks` in `config.toml` (unset means no cap) | Positive integer; invalid values are ignored | | `KIMI_IMAGE_MAX_EDGE_PX` | Longest-edge ceiling (px) for image compression; takes higher priority than `[image] max_edge_px` in `config.toml` (default `2000`) | Positive integer; invalid values are ignored | | `KIMI_IMAGE_READ_BYTE_BUDGET` | Per-image byte budget for model-initiated image reads (`ReadMediaFile` default reads); takes higher priority than `[image] read_byte_budget` in `config.toml` (default `262144`, i.e. 256 KB) | Positive integer; invalid values are ignored | | `KIMI_CODE_PLUGIN_MARKETPLACE_URL` | Override the plugin marketplace JSON loaded by `/plugins`; useful for dev loopback servers, staging CDN files, or alternate marketplace directories | `https://code.kimi.com/kimi-code/plugins/marketplace.json`; also accepts `http://`, `file://` URLs, and local paths | | `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` | Cap how many AgentSwarm subagents run concurrently during the initial ramp; leave unset for no cap | Positive integer; invalid values fail fast | -| `KIMI_SUBAGENT_TIMEOUT_MS` | Maximum wall-clock time (ms) a single `Agent` subagent may run; takes higher priority than `[subagent] timeout_ms` in `config.toml` (default `7200000`, i.e. 2 hours) | Positive integer; invalid values fall back to the config or default | -| `KIMI_CODE_SWARM_TIMEOUT_MS` | Maximum wall-clock time (ms) a single `AgentSwarm` subagent may run; takes higher priority than `[swarm] timeout_ms` in `config.toml` (default `7200000`, i.e. 2 hours) | Positive integer; invalid values fall back to the config or default | +| `KIMI_SUBAGENT_TIMEOUT_MS` | Maximum wall-clock time (ms) a single subagent (`Agent` / `AgentSwarm`) may run; takes higher priority than `[subagent] timeout_ms` in `config.toml` (default `7200000`, i.e. 2 hours) | Positive integer; invalid values fall back to the config or default | | `KIMI_CODE_IDENTITY_NAME` | Display name the agent calls itself in the system prompt; takes higher priority than `[identity] name` in `config.toml` and is never written back to it | Any non-empty string; blank values read as unset | | `KIMI_CODE_IDENTITY_SLUG` | Protocol identifier for the `User-Agent` product token sent to third-party providers and the MCP client name; takes higher priority than `[identity] slug`. Derived from the name when unset | Any non-empty string; normalized to lowercase with non-alphanumeric runs folded to `-` | | `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` | Whether the built-in skills documenting Kimi Code itself are offered to the model; takes higher priority than `builtin_product_skills` in `config.toml` (default enabled) | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | -| `KIMI_CODE_TUI_FULL_SCREEN` | Enable the experimental fullscreen alternate-screen UI: scrollable transcript viewport, mouse text selection, clickable links, and Ctrl-Shift-F transcript search | `1` enables it; anything else keeps the regular inline UI | -| `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL` | Enable the experimental [subagent model pool](./config-files.md#subagent-model-pool) in every launch mode, including the interactive TUI; the master `KIMI_CODE_EXPERIMENTAL_FLAG=1` also enables it | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | -| `KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK` | Enable the experimental `fork` parameter on the `Agent` and `AgentSwarm` tools, letting the model start a subagent with a snapshot of the calling agent's conversation history instead of an empty context; the master `KIMI_CODE_EXPERIMENTAL_FLAG=1` also enables it | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | +| `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL` | Enable the experimental secondary-model feature in every launch mode, including the interactive TUI; the master `KIMI_CODE_EXPERIMENTAL_FLAG=1` also enables it | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | +| `KIMI_SECONDARY_MODEL` | Secondary model; takes higher priority than [`[secondary_model] model`](./config-files.md#secondary-model) in `config.toml`. When the secondary-model experiment is enabled, newly spawned subagents (`Agent` / `AgentSwarm`) bind to it by default instead of inheriting the main agent's model | The alias of a configured `[models]` entry, e.g. `kimi-code/kimi-k2.5`; blank values are ignored | +| `KIMI_SECONDARY_EFFORT` | Thinking effort for the secondary model; takes higher priority than `[secondary_model] default_effort` in `config.toml` and applies only when both the model and its experiment are enabled | An effort value, e.g. `low`; blank values are ignored | | `KIMI_MCP_STARTUP_TIMEOUT_MS` | Global default connection timeout (ms) for all MCP servers; takes higher priority than `[mcp] startup_timeout_ms` in `config.toml`, but a per-server `startupTimeoutMs` in `mcp.json` still wins (default `30000`) | Integer from `1` to `2147483647`; invalid values are ignored | | `KIMI_MCP_TOOL_TIMEOUT_MS` | Global default single tool-call timeout (ms) for all MCP servers; takes higher priority than `[mcp] tool_timeout_ms` in `config.toml`, but a per-server `toolTimeoutMs` in `mcp.json` still wins (default `60000`) | Integer from `1` to `2147483647`; invalid values are ignored | | `KIMI_LOOP_MAX_STEPS_PER_TURN` | Maximum Agent steps per turn; takes higher priority than `[loop_control] max_steps_per_turn` in `config.toml` (unset or `0` means unlimited) | Non-negative integer; invalid values are ignored | | `KIMI_LOOP_MAX_ATTEMPTS_PER_STEP` | Maximum total attempts for a failing step (including the initial attempt); takes higher priority than `[loop_control] max_attempts_per_step` in `config.toml` (default `10`). The deprecated `KIMI_LOOP_MAX_RETRIES_PER_STEP` is still honored with a warning when this variable is unset | Non-negative integer; invalid values are ignored | -| `KIMI_CODE_INFINITE_RETRY` | Retry every failed LLM request indefinitely — turn steps and background operations such as compaction alike — instead of failing the task; waits use exponential backoff (capped at 32 s) and honor the server's `Retry-After` header, and aborting still cancels immediately. Intended for long-running unattended evaluations against endpoints that may fail temporarily | Truthy: `1`/`true`/`yes`/`on`; falsy: `0`/`false`/`no`/`off` | | `KIMI_TOKEN_COUNTING_STRATEGY` | Which context token count is reported externally (the context-size display); takes higher priority than `[token_counting] strategy` in `config.toml` (default `measured+estimated`) | `measured+estimated`, `measured`, `estimated` (case-insensitive); invalid values are ignored | | `KIMI_WEB_SEARCH_BASE_URL` | API URL of the web search (`WebSearch`) service; takes higher priority than `[services.moonshot_search] base_url` in `config.toml`, and enables the service without that config section. Persisted credentials and custom headers are not forwarded to an env-selected endpoint | Non-blank string; blank values are ignored | | `KIMI_WEB_SEARCH_API_KEY` | API key of the web search (`WebSearch`) service; replaces both the configured API key and OAuth credential when set | Non-blank string; blank values are ignored | @@ -173,7 +154,7 @@ Switches that control the behavior of subsystems such as telemetry, background t | `KIMI_CODE_NO_AUTO_UPDATE` | Fully disable the update preflight — no check, background install, or prompt. Legacy alias `KIMI_CLI_NO_AUTO_UPDATE` is also honored | Truthy: `1`/`true`/`yes`/`on` | | `KIMI_DISABLE_CRON` | Disable the scheduled-task tool (`CronCreate` rejects new schedules; existing tasks do not fire) | `1` to disable | -The `KIMI_CODE_INFINITE_RETRY`, `KIMI_CODE_IDENTITY_*`, and `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` variables are read by the default `agent-core-v2` engine. The legacy `kimi` / `kimi -p` path selected with `KIMI_CODE_LEGACY_FLAG=1` ignores them. +The three `KIMI_CODE_IDENTITY_*` / `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` variables are read by the default `agent-core-v2` engine. The legacy `kimi` / `kimi -p` path selected with `KIMI_CODE_LEGACY_FLAG=1` ignores them. ## Diagnostic logs diff --git a/docs/en/customization/agents.md b/docs/en/customization/agents.md index 83c87b1b5..2b247a3a0 100644 --- a/docs/en/customization/agents.md +++ b/docs/en/customization/agents.md @@ -12,7 +12,7 @@ Kimi Code CLI includes three built-in sub-agents, ready to use out of the box, e - **`explore`**: Dedicated to codebase exploration; performs read-only operations only and does not modify any files. Ideal for quickly searching, reading, and summarizing a repository without touching files. - **`plan`**: Dedicated to implementation planning and architecture design; even shell commands are not available, keeping the focus on "figuring out how to do something" rather than "actually doing it." -A `coder` sub-agent shares most of the main Agent's tool set: it can run shell commands in the background, maintain todo lists, enter Plan mode, and invoke Agent Skills. Built-in sub-agents cannot dispatch further sub-agents. By default a custom agent inherits the built-in delegation allowlist (`coder`, `explore`, `plan`), whose members cannot dispatch further either, so delegation chains always terminate — unbounded recursive spawning is impossible without an explicit opt-in. A custom agent can opt into deeper chains by declaring an explicit [`subagents`](#agent-file-format) allowlist. If a sub-agent finishes its turn while background tasks are still running, its run only reports completion after those tasks settle, so the parent receives the result after the underlying work has actually finished. +A `coder` sub-agent shares most of the main Agent's tool set: it can run shell commands in the background, maintain todo lists, enter Plan mode, invoke Agent Skills, and dispatch its own nested sub-agents when a task decomposes naturally. If it finishes its turn while background tasks are still running, its run only reports completion after those tasks settle, so the parent receives the result after the underlying work has actually finished. ## How to Invoke @@ -81,6 +81,7 @@ name: reviewer description: Strict code reviewer that reports severity-ranked findings whenToUse: Code reviews and PR checks override: false +model_preference: primary tools: - Read - Grep @@ -99,9 +100,10 @@ You are a strict code reviewer. Read the diff, then report findings grouped by s | `description` | yes | What the agent does. Shown to the main Agent when it picks a sub-agent, so write it to guide delegation decisions | | `whenToUse` | no | Extra hint describing when the agent should be used | | `override` | no | Whether this file may replace a same-name built-in Agent. Defaults to `false`; `--agent-file` is already explicit and does not require this field | +| `model_preference` | no | Symbolic default used when `Agent` or `AgentSwarm` spawns this profile: `primary` selects the model the caller is currently running, while `secondary` selects [`[secondary_model] model`](../configuration/config-files.md#secondary-model). An explicit tool-call `model` (which likewise accepts only `"primary"` / `"secondary"`) wins over this field; without either setting, the configured secondary model remains the default. If no secondary model is configured, the subagent inherits the caller's model | | `tools` | no | Allowlist of tool names such as `Read` or `Bash`; MCP tools are matched with globs such as `mcp__github__*`. Accepts a YAML list or a comma-separated string (`tools: Read, Grep`). Omit to allow all tools; a lone `*` also allows all tools; an empty list (`tools: []`) disables all tools | | `disallowedTools` | no | Denylist with the same syntax and matching rules, applied after `tools` | -| `subagents` | no | Allowlist of sub-agent names this agent may delegate to, with the same syntax as `tools` (YAML list or comma-separated string). Omit to inherit the default agent's allowlist (built-in default: `coder`, `explore`, `plan`, whose members cannot delegate further, so inherited chains always terminate); a lone `*` allows every type. The main agent's effective allowlist additionally includes every discovered custom agent, so custom agents stay delegatable by default | +| `subagents` | no | Allowlist of sub-agent names this agent may delegate to, with the same syntax as `tools` (YAML list or comma-separated string). Omit to allow every type; a lone `*` also allows all types | Built-in and user tools match by exact, case-sensitive name; entries starting with `mcp__` match MCP tools as globs. Three entry shapes never match anything and are reported with a warning when the profile takes effect: a wildcard outside an `mcp__` pattern (a bare `*` in `disallowedTools` disables nothing), an `mcp__` literal that is not a full `mcp__<server>__<tool>` name (`mcp__github` matches nothing — use `mcp__github__*` for the whole server), and a name no registered or built-in tool has (usually a typo, such as `read` instead of `Read`). @@ -109,6 +111,8 @@ The body is the agent's system prompt, and it is rendered as a template each tim Unknown fields are ignored, so newer files stay readable by older versions. Fields from other agent tools (such as Claude Code's `model` or OpenCode's `mode`) are ignored the same way, the comma-separated `tools` form keeps Claude Code-style agent files loadable, and a missing `name` falls back to the file name so OpenCode-style files load too — a minimal file with `description` and a body works across tools. +`model_preference` applies only to newly spawned subagents when the secondary-model experiment is enabled — set `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`, or the master `KIMI_CODE_EXPERIMENTAL_FLAG=1`. It takes effect in every launch mode, including the interactive TUI. The field never names a concrete model alias, and resumed subagents keep their existing model. The selected preference is shown to the main agent alongside the profile description so it can still pass an explicit `model` when a task needs a different choice. + A file with invalid content discovered in a directory is skipped with a warning and does not affect other files. A file passed explicitly via `--agent-file` must be valid — otherwise the CLI reports the error and exits. ::: warning Note diff --git a/docs/en/customization/mcp.md b/docs/en/customization/mcp.md index 019576d97..a6533c38f 100644 --- a/docs/en/customization/mcp.md +++ b/docs/en/customization/mcp.md @@ -23,8 +23,6 @@ Run `/mcp-config` in the TUI to interactively add, edit, or delete servers witho Deleting a server from the configuration does not interrupt open sessions: the server stays listed in `/mcp` as `removed`, its tools remain visible there, and calls to them fail with a removal notice, while new sessions do not register the tools at all. Conversely, a server added mid-session — by editing `mcp.json` or installing a plugin — is not registered in already-open sessions; it only joins sessions created later. -When Kimi Code finds project-level MCP servers in an untrusted folder, it shows each server's transport and launch target in the workspace trust prompt. The prompt defaults to `Don't trust`; move to `Trust this folder` and confirm only after reviewing the listed command and arguments or remote URL. Trusting the folder enables the project-level MCP servers for that workspace. - Structure of `mcp.json`: ```json @@ -65,7 +63,7 @@ You do not have to set the connection timeout or the single tool-call timeout pe HTTP and SSE servers support providing static credentials via `headers` or `bearerTokenEnvVar`. When OAuth is needed, run `/mcp-config login <server-name>` to complete browser-based authorization. -Plugins can also declare MCP servers in their manifest. Servers declared by a plugin are enabled by default and can be disabled or re-enabled in `/plugins`: disabling or removing stops the tools in open sessions — calls fail with a removal notice — and adding or enabling a server connects it in open sessions right away. See [Plugins](./plugins.md#mcp-servers-in-plugins) for details. +Plugins can also declare MCP servers in their manifest. Servers declared by a plugin are enabled by default and can be disabled or re-enabled in `/plugins`: disabling or removing stops the tools in open sessions — calls fail with a removal notice — while adding or enabling a server takes effect in new sessions or after `/reload`. See [Plugins](./plugins.md#mcp-servers-in-plugins) for details. ::: warning Note stdio entries in a project-level `.kimi-code/mcp.json` execute local commands when a session starts. Only enable these in repositories you trust. diff --git a/docs/en/customization/plugins.md b/docs/en/customization/plugins.md index 760e0155a..c424b92ae 100644 --- a/docs/en/customization/plugins.md +++ b/docs/en/customization/plugins.md @@ -79,7 +79,7 @@ Pass a custom marketplace JSON path or URL to `/plugins marketplace <source>`, o Official plugins are plugins and built-in product capabilities maintained by Kimi. There are currently three: -- **[Kimi Datasource](#kimi-datasource)**: Query financial market data, financial news, macroeconomic indicators, corporate registration records, academic literature, Chinese laws and regulations, and official data from intergovernmental organizations in natural language +- **[Kimi Datasource](#kimi-datasource)**: Query financial market data, macroeconomic indicators, corporate registration records, academic literature, and Chinese laws and regulations in natural language - **[Kimi WebBridge](#kimi-webbridge)**: Let AI drive your own browser to get web tasks done - **[Kimi Computer Use](#kimi-computer-use)**: Let AI operate your desktop apps (macOS and Windows) @@ -97,11 +97,9 @@ Kimi WebBridge installs in two parts: after the steps above, you also need to [i Official plugins do not update automatically — when an update is available, you'll be prompted the next time you use the old version. To upgrade, repeat the installation steps above. -### Kimi Datasource <Badge type="tip" text="v3.4.0" /> +### Kimi Datasource <Badge type="tip" text="v3.3.0" /> -Kimi Datasource is the official Kimi Code data plugin, letting you query financial market data, financial news, macroeconomic indicators, corporate registration records, academic literature, Chinese laws and regulations, and official data from intergovernmental organizations in natural language — no manual API calls or data accounts required. - -Sources include authoritative institutions and leading databases such as the World Bank, IMF, OECD, FRED, WHO, FAO, the National Bureau of Statistics of China, Wind, S&P Capital IQ, SEC EDGAR, Caixin, Xinhua Finance, and Hundsun Juyuan — all traceable to their original publishers. +Kimi Datasource is the official Kimi Code data plugin, letting you query financial market data, macroeconomic indicators, corporate registration records, academic literature, and Chinese laws and regulations in natural language — no manual API calls or data accounts required. You must first complete OAuth login with a Kimi Code account via `/login`; data queries consume your Kimi Code plan quota. @@ -112,49 +110,27 @@ You must first complete OAuth login with a Kimi Code account via `/login`; data #### What you can do -::: details **Live market research** — Want to run a quantitative analysis on a stock? -Pull three years of daily closing prices, MACD, and KDJ signals in a single query, no third-party data platforms needed. -::: +**Live market research**: Want to run a quantitative analysis on a stock? Pull three years of daily closing prices, MACD, and KDJ signals in a single query — no third-party data platforms needed. -::: details **Cross-country macro comparison** — Studying supply-chain shifts across China, India, and Vietnam? -Get complete GDP growth, trade volume, and demographic time-series for multiple countries from World Bank data spanning 50+ years, all in one go. -::: +**Cross-country macro comparison**: Studying supply-chain shifts across China, India, and Vietnam? Get complete GDP growth, trade volume, and demographic time-series from World Bank data spanning 50+ years, all in one go. -::: details **Pre-contract risk check** — Need to vet a counterparty minutes before signing? -Type the company name and instantly get business registration, equity structure, litigation disputes, and credit blacklist status, right when you need it. -::: +**Pre-contract risk check**: Need to vet a counterparty fast? Type the company name and instantly get business registration, equity structure, litigation disputes, and credit blacklist status — right when you need it. -::: details **Literature review acceleration** — Tracing the research arc of RLHF for a paper? -Get the most-cited papers, key authors, and core findings in seconds, so your literature review outline takes shape in half the time. -::: +**Literature review acceleration**: Tracing the research arc of RLHF? Get the most-cited papers, key authors, and core findings in seconds, so your literature review outline takes shape in half the time. -::: details **On-the-spot legal lookup** — Need to confirm the statute behind a residence-right contract dispute? -Pinpoint the relevant Civil Code articles (full text, authority level, and validity) in one query, then pull a few comparable precedents to back them up, without digging through statute databases. -::: +**On-the-spot legal lookup**: Stuck on which statute governs a residence-right contract dispute? Pinpoint the relevant Civil Code articles — full text, authority level, and validity — then pull a few comparable precedents to back them up, without digging through statute databases. -::: details **Institutional-grade US equity research** — Writing a deep dive on a US stock? -Pull the annual report, standardized financial metrics, top-50 holders, and consensus estimates in one go, no more juggling multiple data terminals. -::: - -::: details **Financial news and industry data** — Tracking market hotspots or policy moves? -Query Caixin's market news, bond/fund/futures data, and listed-company supply-chain relationships, plus news, policies, announcements, and market flashes from the Xinhua Finance national financial information platform — authoritative and traceable sources. -::: - -::: details **Standards lookup** — Need to check compliance against Chinese standards? -Look up national (GB), industry, local, and association standards by number or topic, with status and full-text entry points. -::: +**Institutional-grade US equity research**: Writing a deep dive on a US stock? Pull the annual report, standardized financial metrics, top-50 holders, and consensus estimates in one go — no more juggling multiple data terminals. #### Coverage | Category | Scope | |---|---| | Stocks & financial markets | Well-known databases such as Wind, S&P Capital IQ, and SEC EDGAR, covering prices, technical indicators, financials and valuation, and consensus estimates across A-shares, HK, US, and other major markets, plus official filings for 8,000+ US-listed companies | -| Financial news & industry data | Well-known data platforms such as Caixin and Xinhua Finance, covering market news and flashes, listed-company announcements, regulatory policies, bond/fund/futures data, corporate credit violation records, and listed-company supply-chain relationships | -| Macroeconomics | Well-known databases such as the World Bank, IMF, OECD, FRED, and China's National Bureau of Statistics, plus official statistics from IGOs such as WHO and FAO, covering 50+ years of time series for 189 countries and China indicators at national/provincial/municipal levels: GDP, trade, population, exchange rates, CPI, balance of payments, GDP forecasts, and more | -| China standards | National (GB), industry, local, and association standards — numbers, titles, status, and details, with official full-text entry points for some national and public association standards | +| Macroeconomics | Well-known databases such as the World Bank and IMF, covering 50+ years of time series for 189 countries: GDP, trade, population, exchange rates, CPI, balance of payments, GDP forecasts, and more | | Corporate data | Business registration, equity chain, legal risk, and related-entity graph for mainland Chinese companies | | Academic literature | Millions of papers across physics, mathematics, CS, quantitative finance, economics — including preprints | -| Legal | Yuandian Legal and other leading legal databases, covering Chinese laws, regulations, and judicial cases — statute search and detail lookup across all authority levels, plus ordinary and authoritative case search | +| Legal | Chinese laws, regulations, and judicial cases — statute search and detail lookup across all authority levels, plus ordinary and authoritative case search | | Smart screening | Well-known databases such as Gildata, covering natural-language screening for stocks, funds, and fund managers, plus macro-industry data, research reports, announcements, and news | #### Billing and limitations diff --git a/docs/en/guides/goals.md b/docs/en/guides/goals.md index f54c531bb..65cf4a781 100644 --- a/docs/en/guides/goals.md +++ b/docs/en/guides/goals.md @@ -12,8 +12,6 @@ Write the objective after `/goal`: Kimi Code saves the objective, sends it as the next user message, and starts goal mode. After each turn, it checks whether the goal is complete, blocked, paused, or still active. -Objectives are capped at 4000 characters; a longer objective is rejected with a warning, and the typed text is kept in the input box for editing. - Goals work best when the objective names the finish line and the evidence that proves it: ```sh diff --git a/docs/en/guides/interaction.md b/docs/en/guides/interaction.md index b83354d6a..ff59fe8b2 100644 --- a/docs/en/guides/interaction.md +++ b/docs/en/guides/interaction.md @@ -27,15 +27,13 @@ Anything starting with `/` is treated as a slash command. Typing `/` opens a com Active [Agent Skills](../customization/skills.md) are automatically registered as slash commands: ordinary external Skills are invoked with `/skill:<name>`, external sub-skills appear as dotted commands such as `/parent.child`, and built-in Skills appear directly as `/<name>` in the slash command panel. If an external skill name does not conflict with a system slash command, you can also drop the `skill:` prefix and type `/<name>` directly. -Inside a longer prompt, typing `/` after whitespace — including at the start of a later line — opens a skill-only completion menu. You can reference several Skills in one prompt this way: Kimi Code activates them together and runs them with the prompt as a single turn (one `/undo` reverts the whole submission), and the prompt text is sent unchanged. A Skill mention in a prompt never carries arguments — activation is by name only; arguments remain a standalone `/skill:<name> args` concept. Built-in and plugin commands still only work at the very start of the input. - Some commands are only available when the agent is idle — you need to press `Esc` to interrupt streaming output or context compression before using them. Mode-toggle and query commands like `/yolo`, `/plan`, `/help`, and `/btw` are always available. For the full list, see [Slash commands reference](../reference/slash-commands.md). ## File references Type `@` to trigger file-path completion. Selecting a path inserts its relative form into your message; the agent loads the file content directly when it reads the message. File references work in both git and non-git directories, and folder suggestions end with `/` so you can keep completing paths inside them. If the fast search helper is still downloading, Kimi Code falls back to a basic filesystem scan. Hidden paths are available, but `.git` is excluded from suggestions. -> `@` references and slash commands are two separate mechanisms: `@` gives the agent file context, while `/` invokes built-in features or Skills. After whitespace, `/` offers Skill completions only; use a leading `/` for built-in and plugin commands. +> `@` references and slash commands are two separate mechanisms: `@` gives the agent file context, while `/` invokes built-in features or Skills. A `/` typed after leading whitespace is treated as normal text, not as the slash-command menu. ## Approval flow @@ -74,7 +72,6 @@ Shell mode lets you run terminal commands without leaving the conversation. The - Exit: press `Backspace` or `Esc` in an empty input box; submitting a command also returns you to normal mode automatically. - Run in background: while a command is running, press `Ctrl+B` to move it to a background task. - Recall previous commands: with the input box empty in shell mode, press `↑` to browse earlier shell commands; recalling one keeps you in shell mode so it runs as a command again. -- Long output: when a finished command's output is too long, the output card collapses automatically; press `Ctrl-O` to expand or collapse it together with tool output. In shell mode the input box shows a `!` prompt on the left and the border turns violet. For example, you can run `!gh auth login` to sign in to the GitHub CLI without opening a new terminal, so Kimi can use `gh` afterward. diff --git a/docs/en/guides/server.md b/docs/en/guides/server.md deleted file mode 100644 index 1df4d4674..000000000 --- a/docs/en/guides/server.md +++ /dev/null @@ -1,116 +0,0 @@ -# Local Server and API - -Kimi Code CLI ships with a built-in local server: running `kimi web` starts a foreground process that mounts three things at once — the web UI in your browser, a REST API (`/api/v1`), and a WebSocket event stream (`/api/v1/ws`). The web UI lets you use Kimi Code in a browser; the REST and WebSocket APIs are for scripts and third-party tools, letting you create sessions, submit prompts, and follow execution from code — all reading and writing the same session data as the TUI and the web UI. - -> Make sure Kimi Code CLI is installed and ready to use first — either logged in via `/login` (in the TUI, or `kimi login`), or with a provider configured in `config.toml`. The server shares the CLI's login state and configuration, so no separate credential is needed for it. - -::: warning -The REST and WebSocket APIs described on this page are experimental: interface stability is not guaranteed, and endpoints, fields, and event types may change in any release. When integrating, rely on the `/openapi.json` and `/asyncapi.json` documents served by your version. -::: - -## Start the server - -```sh -kimi web # run the server in the foreground and open the browser -kimi web --no-open # run the server only, don't open the browser -kimi web --port 58628 # pick a specific bind port -``` - -The server binds to `127.0.0.1:58627` by default (loopback only). If the port is taken it automatically retries with the next one, so multiple instances can coexist on the same machine; each instance registers under `~/.kimi-code/server/instances/`. The startup banner prints the access URL and the plaintext token: - -```text -Local: http://127.0.0.1:58627/#token=... -Token: ... -Stop: Ctrl+C -``` - -The server runs in the foreground; press `Ctrl-C` for a clean shutdown. For the full option list such as `--host` and `--log-level`, see the [kimi command reference](../reference/kimi-command.md#kimi-web). - -## Authentication - -Every `/api/*` endpoint requires a bearer token (any request carrying this string is treated as authorized). The token is generated on the first server boot, persisted at `~/.kimi-code/server.token` (file mode 0600), and reused across restarts. - -Pick the carrying method that fits your client: - -- **REST**: the `Authorization: Bearer <token>` request header. -- **web UI**: the URL in the startup banner carries a `#token=` fragment, so opening it in a browser completes sign-in automatically. The fragment is never sent to the server. -- **WebSocket**: clients that can set headers use `Authorization: Bearer`; clients that cannot (such as browsers) pass the subprotocol (a protocol name declared during the WebSocket handshake) `kimi-code.bearer.<token>` instead. - -If the token leaks, run `kimi web rotate-token`: the new token is written to `server.token` immediately, the old one stops working at once, and running instances pick up the new token without a restart. - -If you bind the server to a non-loopback address (`--host`), also set the `KIMI_CODE_PASSWORD` environment variable as a parallel credential; the server then rate-limits authentication failures automatically. - -::: danger -`--dangerous-bypass-auth` disables authentication entirely — anyone who can reach the port can control your sessions, file system, and shell. Only use it on trusted networks or behind your own authenticating proxy. See the [kimi command reference](../reference/kimi-command.md#kimi-web). -::: - -## Drive a session over the API - -The minimal flow with curl: check the server → create a session → subscribe to events → submit a prompt → read history back. The examples assume the server runs at the default address and the token is stored in the shell variable `TOKEN`. - -1. Check server status: - -```sh -curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:58627/api/v1/meta -``` - -Every JSON response is wrapped in a uniform envelope — `{ "code": 0, "msg": "success", "data": ..., "request_id": "..." }`. The business outcome lives in `code` (`0` means success); the HTTP status only reports transport-level results. - -2. Create a session; `metadata.cwd` sets the working directory: - -```sh -curl -s -X POST http://127.0.0.1:58627/api/v1/sessions \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"metadata": {"cwd": "/path/to/project"}}' -``` - -The returned `data.id` (shaped like `session_...`) is the session id used by every subsequent request. - -3. Connect to the WebSocket and subscribe to session events. Any WebSocket client works; below is a dependency-free Node.js script (Node.js 22+ ships a built-in `WebSocket` client): - -```js -// subscribe.mjs — usage: TOKEN=... node subscribe.mjs session_... -const ws = new WebSocket('ws://127.0.0.1:58627/api/v1/ws', [ - `kimi-code.bearer.${process.env.TOKEN}`, -]); -ws.onmessage = (e) => console.log(e.data); -ws.onopen = () => - ws.send( - JSON.stringify({ - type: 'subscribe', - id: '1', - payload: { session_ids: [process.argv[2]] }, - }), - ); -``` - -4. Submit a prompt: - -```sh -curl -s -X POST http://127.0.0.1:58627/api/v1/sessions/<session_id>/prompts \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"content": [{"type": "text", "text": "Introduce this repository in one sentence"}]}' -``` - -The subscriber sees, in order: `turn.started` (turn begins) → `assistant.delta` (streaming text increments) → `tool.call.started` / `tool.result` when tool calls happen → `turn.ended` (turn finishes). - -5. Read history back over REST at any time: - -```sh -curl -s -H "Authorization: Bearer $TOKEN" \ - "http://127.0.0.1:58627/api/v1/sessions/<session_id>/messages?page_size=20" -``` - -## Live specification documents - -While running, the server describes itself with two specification documents, both requiring the bearer token: - -- `GET /openapi.json` — an OpenAPI document for the REST API, with request/response schemas for every endpoint; import it into Swagger UI, Postman, and similar tools. -- `GET /asyncapi.json` — an AsyncAPI document for the WebSocket protocol, covering control frames and event types. - -## Next steps - -- [Server API](../reference/server-api.md) — full REST endpoint inventory, error codes, WebSocket events, and the transcript protocol -- [kimi command](../reference/kimi-command.md#kimi-web) — all `kimi web` command-line options diff --git a/docs/en/guides/sessions.md b/docs/en/guides/sessions.md index 62f7afa28..b63ee8d24 100644 --- a/docs/en/guides/sessions.md +++ b/docs/en/guides/sessions.md @@ -87,8 +87,6 @@ To explore a new direction without disrupting the current conversation, use `/fo Forking does not switch you away: you stay in the original session and the conversation continues untouched. The fork is an independent copy you can switch to at any time using `/sessions`. A saved `/goal` is not copied to the fork. Start a new goal there if you want autonomous goal work. -After forking, the CLI prints a ready-to-run `kimi --resume` command (also copied to the clipboard) so you can enter the fork directly from a new terminal process. - ## Exporting a session Use `kimi export` to package a session as a ZIP file — useful for sharing, archiving, or filing a bug report: @@ -112,6 +110,8 @@ You can also export from inside the TUI without leaving the interactive session: In the web UI, `/export` downloads the current session as a diagnostic ZIP. It includes the persisted session data, diagnostic logs, and a bounded metadata-only `logs/kimi-web.jsonl` record of key browser events. Prompt text, WebSocket payloads, and console arguments are not copied into this browser log. This web command differs from the TUI `/export` alias above. +The browser buffers the ZIP before saving it, so web exports are limited to 64 MiB. For a larger session, use `kimi export <sessionId>` or the TUI `/export-debug-zip` command. + ::: tip Exported files may contain code, command output, and file paths that are sensitive. Review the content before sharing. ::: diff --git a/docs/en/reference/keyboard.md b/docs/en/reference/keyboard.md index e534a548f..a641282d7 100644 --- a/docs/en/reference/keyboard.md +++ b/docs/en/reference/keyboard.md @@ -67,9 +67,9 @@ Pressing `Ctrl-S` causes the model to see your message at the next interruptible | Shortcut | Function | | --- | --- | -| `Ctrl-O` | Expand or collapse tool output, shell command output, and compaction summaries | +| `Ctrl-O` | Expand or collapse tool output and compaction summaries | -When collapsed tool call results or shell command outputs exist in the history, press `Ctrl-O` to toggle between collapsed and expanded views. After compaction, the same shortcut shows or hides the compaction summary in the compaction block. +When collapsed tool call results exist in the history, press `Ctrl-O` to toggle between collapsed and expanded views. After compaction, the same shortcut shows or hides the compaction summary in the compaction block. ## Approval Panel diff --git a/docs/en/reference/kimi-command.md b/docs/en/reference/kimi-command.md index 4124b4df9..36480081d 100644 --- a/docs/en/reference/kimi-command.md +++ b/docs/en/reference/kimi-command.md @@ -157,7 +157,7 @@ kimi acp Run the local Kimi server in the foreground of the current terminal — a single process that exposes the REST + WebSocket API and serves the web UI from the same origin — and open the web UI in the default browser once it is ready. The command stays attached to the terminal and shuts down cleanly on `SIGINT` / `SIGTERM` (e.g. `Ctrl-C`). -When the server is running, `GET /openapi.json` returns the REST OpenAPI document and `GET /asyncapi.json` returns the local WebSocket AsyncAPI document. For an end-to-end walkthrough of driving sessions over the API, see [Local server and API](../guides/server.md); for the protocol details, see the [Server API](./server-api.md) reference. +When the server is running, `GET /openapi.json` returns the REST OpenAPI document and `GET /asyncapi.json` returns the local WebSocket AsyncAPI document. ```sh kimi web # run the server in the foreground and open the browser @@ -175,7 +175,6 @@ Multiple instances can share one home directory: each registers itself under `~/ | `--log-level <level>` | Enable server logs at the selected level; omitted by default | | `--debug-endpoints` | Mount `/api/v1/debug/*` routes (off by default) | | `--dangerous-bypass-auth` | Disable bearer-token auth on all REST and WebSocket routes so the web UI connects without a token; only for trusted networks or behind an authenticating proxy | -| `--web-title <title>` | Custom browser tab title for the web UI; defaults to the workspace directory name | | `--no-open` | Do not open the browser once the server is ready | `kimi web` binds to local loopback only by default and prints the bearer token in the startup banner; the web UI authenticates automatically via the `#token=` URL fragment. @@ -269,7 +268,7 @@ Immediately check for the latest version and display an update prompt; exits aft kimi upgrade ``` -For global npm, pnpm, yarn, and bun installations, `kimi upgrade` shows update options; selecting `Install update now` runs the corresponding foreground install command. For native installations (including Windows), it downloads and verifies the new binary in the foreground and swaps it in on the next start. When the current installation method cannot be upgraded automatically, the manual update command is printed instead. +For global npm, pnpm, yarn, bun, and macOS / Linux native installations, `kimi upgrade` shows update options; selecting `Install update now` runs the corresponding foreground install command. When the current installation method cannot be upgraded automatically (e.g., Windows native installation), the manual update command is printed instead. ### `kimi vis` diff --git a/docs/en/reference/server-api.md b/docs/en/reference/server-api.md deleted file mode 100644 index d1419fc33..000000000 --- a/docs/en/reference/server-api.md +++ /dev/null @@ -1,2322 +0,0 @@ -# Server API - -The local server started by `kimi web` exposes two programmatic surfaces: a REST API (`/api/v1`, plus `/api/v2/sessions` and `/api/v2/mcp`) and a WebSocket event stream (`/api/v1/ws`). This page is the protocol reference for both. For how to start the server and its command-line options, see the [kimi command](./kimi-command.md#kimi-web) reference; for an end-to-end walkthrough, see [Local server and API](../guides/server.md). - -This page is a curated, human-readable reference: it documents every endpoint's parameters, request bodies, and response shapes below. The precise machine-readable schema of every endpoint is owned by the server's live specification documents: `GET /openapi.json` (OpenAPI) and `GET /asyncapi.json` (AsyncAPI), both generated from the same validation schemas the server enforces at runtime. Both require authentication; when this page and the live spec ever disagree, the live spec wins. - -::: warning -The REST and WebSocket APIs described on this page are experimental: interface stability is not guaranteed, and endpoints, fields, and event types may change in any release. When integrating, rely on the `/openapi.json` and `/asyncapi.json` documents served by your version. -::: - -## Conventions - -### Address - -The default address is `http://127.0.0.1:58627`. When the port is taken, the server retries with the next port (up to 100 times); use `--port` / `--host` to change the bind. Multiple instances can coexist under the same home directory; running instances register under `~/.kimi-code/server/instances/`. - -### Authentication - -All `/api/*` paths (including `/openapi.json` and `/asyncapi.json`) require the bearer token, except: - -- `OPTIONS` preflight requests -- `GET /api/v1/healthz` (liveness probe) -- Static web assets (non-`/api/` paths) - -How to carry it: REST uses the `Authorization: Bearer <token>` header; the WebSocket upgrade accepts the same header or the subprotocol `kimi-code.bearer.<token>`. Token generation and rotation are covered in [Local server and API: Authentication](../guides/server.md#authentication). - -Failed authentication returns HTTP 401 with envelope code `40101`. On non-loopback binds, a source that fails authentication 10 times within 60 seconds is banned for 60 seconds, during which every request gets HTTP 429 (code `42901`). - -### Response envelope - -Every JSON response is wrapped in a uniform envelope: - -```json -{ - "code": 0, - "msg": "success", - "data": {}, - "request_id": "01JZX4A6E7M8V0R3Q0N2K2M5Q9" -} -``` - -- `code`: the business outcome; `0` means success. See the error-code bands below. -- `data`: the payload on success. Note that some "error" envelopes also carry a non-null `data` — for example, resolving an already-resolved approval returns `40902` with `data.resolved` set to `false` — so clients should check `code` first, then `data`. -- `request_id`: a ULID for this request. Clients may supply one via the `X-Request-Id` header; invalid values are regenerated by the server. - -The HTTP status is almost always 200; the business outcome lives in `code`. Exceptions: - -| Situation | HTTP status | -| --- | --- | -| Authentication failure / rate limit | 401 / 429 | -| Provider created, provider catalog imported | 201 | -| Provider deleted | 204 | -| Binary/streaming endpoints | 206 (Range) / 304 (ETag unchanged) where supported — capabilities differ per endpoint, see [Binary and streaming endpoints](#binary-and-streaming-endpoints) | -| `GET /api/v1/files/{file_id}` download errors | real 404 / 500 (still carrying an envelope body) | - -The 201 responses still carry the standard envelope (`code` 0) — only the status line follows the REST convention for resource creation. A 204 response has no body by definition, so a successful delete is reported by the status code itself. - -### Error codes - -Error codes are grouped by band: - -| Band | Meaning | Examples | -| --- | --- | --- | -| `0` | Success | | -| `400xx` | Bad request | `40001` validation failed (`details` lists each field), `40003` provider is OAuth-managed | -| `401xx` | Auth and readiness | `40101` unauthorized, `40110` no provider configured, `40113` model not resolved | -| `404xx` | Not found | `40401` session, `40408` MCP server, `40409` file path | -| `409xx` | State conflict | `40901` session busy, `40902` approval already resolved, `40922` page conditions mismatch `page_token` | -| `410xx` | Expired | `41001` approval timed out, `41002` question timed out, `41003` temporary file expired | -| `413xx` | Size or boundary exceeded | `41302` file read over 10 MB, `41304` path escapes the session directory | -| `429xx` | Rate limited | `42901` auth-failure ban, `42902` too many fs watches | -| `500xx` | Server internal error | `50001` uncaught exception, `50003` persistence failure | -| `6xxxx` / `7xxxx` / `8xxxx` | Tool runtime / LLM provider / MCP passthrough errors; `msg` carries the upstream text | | - -### Pagination - -List endpoints come in two styles: - -- **Cursor style**: `before_id` / `after_id` (mutually exclusive) plus `page_size` (1–100), responding with `{ items, has_more }`. Used by the session list, message list, transcript, and others. -- **`page_token`**: an opaque token (bound to a fingerprint of the query conditions), used by `POST /api/v1/search` and `GET /api/v2/sessions`. Changing any query condition mid-pagination invalidates the token: v2 returns `40922`, search returns `40001`. `GET /api/v2/sessions` also offers a stateless `page` page-number mode as an alternative. - -## REST endpoints - -Endpoints are grouped by resource below. A `:{action}` suffix in a path is the action convention — POST to `path:action` on a single resource for non-CRUD operations (such as `:fork` and `:archive` on a session). - -### Server and metadata - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/healthz` | Liveness probe; auth-exempt | -| `GET /api/v1/meta` | Server version, capability map, `server_id`, experimental flags | -| `POST /api/v1/shutdown` | Graceful shutdown (replies 200 first); mounted only on loopback binds | - -#### `GET /api/v1/healthz` - -Liveness probe for scripts and process supervisors. It is the one `/api` endpoint exempt from the bearer token (see [Authentication](#authentication)) and answers without touching config or the engine. - -On success, `data` is `{ "ok": true }`. - -#### `GET /api/v1/meta` - -Returns this instance's identity and capability map. Most fields are frozen at boot; `experimental_flags` and `features` are resolved per request, so a flag flip or a failed feature shows up in the next response. - -On success, `data` carries: - -| Field | Type | Description | -| --- | --- | --- | -| `server_version` | string | Server version | -| `capabilities` | object | Capability map — `websocket`, `file_upload`, `fs_query`, `mcp`, `tasks`, `terminal`, all always `true` | -| `server_id` | string | Unique id of this server instance | -| `started_at` | string | Boot time, ISO 8601 | -| `open_in_apps` | array | Host apps usable as `open-in` targets (`finder` / `cursor` / `vscode` / `iterm` / `terminal`); currently always empty | -| `dangerous_bypass_auth` | boolean | Whether the server was started with `--dangerous-bypass-auth` (clients may skip the token prompt) | -| `backend` | string | Engine backend, `v1` or `v2`; always `v2` for this server | -| `web_title` | string | Custom browser tab title from `--web-title`; omitted when unset | -| `experimental_flags` | object | Experimental flag id → enabled, resolved at request time | -| `features` | array | Engine features as `{ name, state, meta }`; `state` is `Pending` / `Activating` / `Active` / `Unloading` / `Failed` | - -#### `POST /api/v1/shutdown` - -Asks the server to shut down gracefully. The reply is sent first and the shutdown runs immediately after, so the caller can trust the response it received. The route is mounted only on loopback binds — on a non-loopback bind it is not registered at all (requests hit a 404) unless the server was started with `--allow-remote-shutdown`. - -On success, `data` is `{ "ok": true }`. - -### Login and usage - -These endpoints drive the managed Kimi OAuth login lifecycle and expose account-level information. The managed provider is named `managed:kimi-code`; the optional `provider` parameter on every endpoint below defaults to it. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/auth` | Auth readiness snapshot | -| `POST /api/v1/oauth/login` | Start the OAuth device-code login flow | -| `GET /api/v1/oauth/login` | Poll the login flow state | -| `DELETE /api/v1/oauth/login` | Cancel a pending login flow | -| `POST /api/v1/oauth/logout` | Log out the managed provider | -| `GET /api/v1/oauth/usage` | Plan usage and limits | -| `GET /api/v1/oauth/userinfo` | Account profile | -| `GET /api/v1/oauth/region` | Resolve the client region (`mainland-cn` / `global`) | - -#### `GET /api/v1/auth` - -Auth readiness snapshot: whether the server has a usable model configuration, plus the managed provider's login state. `ready` is `true` when at least one provider is configured, a default model is set, and the managed provider (when present) is not revoked. - -On success, `data` carries `ready` (boolean), `providers_count` (number of configured providers), `default_model` (the global default model alias, or `null`), and `managed_provider` (`null`, or `{ name, status }` with `status` one of `authenticated` / `expired` / `revoked` / `unauthenticated`). - -#### `POST /api/v1/oauth/login` - -Starts an OAuth device-code login flow for the managed provider; starting a new flow aborts any pending flow for the same provider. When the account is already authenticated, no user interaction is needed and the response reports `authenticated` immediately. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | body | string | Managed provider name. Default `managed:kimi-code` | -| `region` | body | string | `mainland-cn` or `global`; overrides the region resolution described under `GET /api/v1/oauth/region` for this flow | - -On success, `data` has one of two shapes. A pending flow — `{ flow_id, provider, status: "pending", verification_uri, verification_uri_complete, user_code, expires_in, interval, expires_at }`: open `verification_uri_complete` (or `verification_uri` and enter `user_code`), then poll `GET /api/v1/oauth/login` every `interval` seconds until the flow resolves or `expires_at` passes (`expires_in` is the same deadline in seconds). The already-authenticated fast path — `{ flow_id, provider, status: "authenticated" }`. - -#### `GET /api/v1/oauth/login` - -Polls the login flow state for a provider. Returns `null` when no flow has been started. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | query | string | Managed provider name. Default `managed:kimi-code` | - -On success, `data` is `null` or a flow snapshot: `{ flow_id, provider, status, verification_uri, verification_uri_complete, user_code, expires_in, expires_at, interval }`, where `status` is `pending` / `authenticated` / `denied` / `expired` / `cancelled`. Once the flow leaves `pending`, `resolved_at` records when it reached its terminal state and `error_message` describes a failed flow. - -#### `DELETE /api/v1/oauth/login` - -Cancels the pending login flow for a provider. When no flow is pending, the call is a no-op that reports the last known state. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | query | string | Managed provider name. Default `managed:kimi-code` | - -On success, `data` is `{ cancelled, status }`: `cancelled` is `true` only when a `pending` flow was actually aborted, and `status` is the flow state after the call. - -#### `POST /api/v1/oauth/logout` - -Logs out the managed provider: discards the stored OAuth credential, aborts any pending login flow, and removes the managed provider from the configuration. OAuth-managed providers reject manual edit and delete (see `PUT` / `DELETE /api/v1/providers/{provider_id}` below), so log out first to remove one. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | body | string | Managed provider name. Default `managed:kimi-code` | - -On success, `data` is `{ logged_out: true, provider }`. - -#### `GET /api/v1/oauth/usage` - -Plan usage and limits of the managed account, fetched live from the account service. An upstream failure does not fail the envelope — it comes back in-band with `kind: "error"`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | query | string | Managed provider name. Default `managed:kimi-code` | - -On success, `data` is `{ kind: "ok", summary, limits, extra_usage }` or `{ kind: "error", message, status? }`, where `status` is the upstream HTTP status when one exists. In the `ok` shape, `summary` (nullable) is the primary quota row and `limits` lists every quota window; a row is `{ name?, window?, used, limit, reset_at? }` with `window` as `{ duration, unit }`, `unit` one of `minute` / `hour` / `day` / `week`. `extra_usage` (nullable) is the pay-as-you-go wallet: `{ balance_cents, total_cents, monthly_charge_limit_enabled, monthly_charge_limit_cents, monthly_used_cents, currency }`. - -#### `GET /api/v1/oauth/userinfo` - -Profile of the managed account, with the same in-band `kind: "error"` convention as `GET /api/v1/oauth/usage`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider` | query | string | Managed provider name. Default `managed:kimi-code` | - -On success, `data` is `{ kind: "ok", userInfo }` or `{ kind: "error", message, status? }`. `userInfo` always carries `userId`, `nickname`, `status`, `region`, `userLevel`, `userLevelName`, `domain`, and `domainName`, and may add `globalId`, `bio`, `avatar`, `username`, `email`, `phone` (`{ countryCode, number }`), `createdTime`, and `lastLoginTime`. - -#### `GET /api/v1/oauth/region` - -Resolves which Kimi region this client belongs to. The answer is derived locally, not probed over the network: an OAuth host pinned by environment or config wins first, then the configured OAuth key, then the region marker file in the home directory; the default is `mainland-cn`. - -On success, `data` is `{ region }` with `region` one of `mainland-cn` / `global`. - -### Config - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/config` | Read the global config (secret fields redacted) | -| `POST /api/v1/config` | Merge-patch the config; broadcasts `event.config.changed` | - -#### `GET /api/v1/config` - -Returns the resolved global configuration — the effective result of `config.toml` plus overlays. Secrets are redacted: each provider reports only `has_api_key`, never the stored key. - -On success, `data` is the config object; its fields mirror the top-level domains documented under [Top-level fields](../configuration/config-files.md#top-level-fields): - -| Field | Type | Description | -| --- | --- | --- | -| `providers` | object | Map of provider id → `{ type, base_url?, default_model?, has_api_key }` | -| `default_provider` | string | Global default provider id | -| `default_model` | string | Global default model alias | -| `models` | object | Map of model alias → model record | -| `thinking` | object | Default parameters for Thinking mode | -| `plan_mode` | boolean | Plan mode flag | -| `yolo` | boolean | Derived: `true` when `default_permission_mode` is `yolo` | -| `default_permission_mode` | string | Default permission mode for new sessions | -| `default_plan_mode` | boolean | Whether new sessions start in Plan mode | -| `permission` | object | Initial permission rules | -| `hooks` | array | Lifecycle hooks | -| `services` | object | Built-in external service configuration | -| `merge_all_available_skills` | boolean | Whether to merge Agent Skills from all available directories | -| `extra_skill_dirs` | array | Extra skill search directories | -| `loop_control` | object | Agent loop control parameters | -| `background` | object | Background task runtime parameters | -| `subagent` | object | Subagent configuration | -| `secondary_model` | object | Secondary model pool for subagents | -| `experimental` | object | Experimental flag id → enabled | -| `telemetry` | boolean | Whether anonymous telemetry is enabled | -| `raw` | object | Raw parsed `config.toml` content, unmodeled fields included | - -#### `POST /api/v1/config` - -Merge-patches the global configuration: each top-level domain in the body is deep-merged into that domain, and domains absent from the body are left untouched. Setting `yolo` to `true` is shorthand for `default_permission_mode: "yolo"`. After a successful update the server broadcasts the global `event.config.changed` event with the changed field names and the full updated config; a rejected patch (invalid value or persistence failure) returns `40001` with the underlying message. - -The body is a partial config object — any subset of the response domains above except `raw`, all optional: - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `providers` | body | object | Map of provider id → provider table | -| `default_provider` | body | string | Global default provider id | -| `default_model` | body | string | Global default model alias | -| `models` | body | object | Map of model alias → model record | -| `thinking` | body | object | Default parameters for Thinking mode | -| `plan_mode` | body | boolean | Plan mode flag | -| `yolo` | body | boolean | `true` maps to `default_permission_mode: "yolo"`; `false` is ignored | -| `default_permission_mode` | body | string | `manual` / `yolo` / `auto` | -| `default_plan_mode` | body | boolean | Whether new sessions start in Plan mode | -| `permission` | body | object | Initial permission rules | -| `hooks` | body | array | Lifecycle hooks | -| `services` | body | object | Built-in external service configuration | -| `merge_all_available_skills` | body | boolean | Whether to merge Agent Skills from all available directories | -| `extra_skill_dirs` | body | array | Extra skill search directories | -| `loop_control` | body | object | Agent loop control parameters | -| `background` | body | object | Background task runtime parameters | -| `subagent` | body | object | Subagent configuration | -| `secondary_model` | body | object | Secondary model pool for subagents | -| `experimental` | body | object | Experimental flag id → enabled | -| `telemetry` | body | boolean | Whether anonymous telemetry is enabled | - -On success, `data` is the full updated config in the same shape as `GET /api/v1/config`. - -### Models and providers - -These endpoints manage the two halves of model configuration — the [providers](../configuration/providers.md) table and the model-alias table of `config.toml` — plus a server-proxied models.dev directory for one-shot imports. A model alias id is the exact configured alias key: aliases created through the provider-management endpoints take the form `provider_id/model` (for example `my-provider/kimi-for-coding`), while a bare model-table key such as `turbo` is used as-is; anywhere the API takes a `model_id`, including the global `default_model`, it means this alias id. An unsupported action on a `:{action}` route returns `40001`. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/models` | List configured model aliases | -| `POST /api/v1/models/{model_id}:set_default` | Set the global default model | -| `GET /api/v1/providers` | List providers | -| `POST /api/v1/providers` | Create a provider (201) | -| `GET /api/v1/providers/{provider_id}` | Read a provider (reveals the stored key) | -| `PUT /api/v1/providers/{provider_id}` | Replace a provider | -| `DELETE /api/v1/providers/{provider_id}` | Delete a provider (204) | -| `POST /api/v1/providers/{provider_id}:refresh` | Refresh one provider's model metadata | -| `POST /api/v1/providers:{action}` | Collection actions: `refresh` / `refresh_oauth` / `import_catalog` / `import_registry` | -| `GET /api/v1/catalog/providers` | Browse the models.dev directory (server-proxied) | -| `GET /api/v1/catalog/providers/{catalog_id}` | Read one directory entry | - -#### `GET /api/v1/models` - -Lists every configured model alias across all providers. - -On success, `data.items` is an array of `{ provider, model, display_name?, max_context_size, capabilities?, support_efforts?, default_effort? }`: `model` is the alias id (`provider_id/model` for provider-managed aliases, otherwise the bare key), `provider` the owning provider id, `max_context_size` the context window in tokens, and `capabilities` / `support_efforts` / `default_effort` describe capability flags and Thinking-mode effort support. - -#### `POST /api/v1/models/{model_id}:set_default` - -Sets the global `default_model` to an existing alias. `model_id` is the exact configured alias key — for a bare key like `turbo` the call is `POST /api/v1/models/turbo:set_default`; URL-encode the id when it contains `/`, as in `POST /api/v1/models/my-provider%2Fkimi-for-coding:set_default`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `model_id` | path | string | **Required.** The exact configured model alias key; URL-encode it when it contains `/` | - -On success, `data` is `{ default_model, model }` — the alias now in effect and its catalog item (same shape as a `GET /api/v1/models` item). - -- `40001`: malformed or unsupported action suffix in the path -- `40413`: no model alias with that id - -#### `GET /api/v1/providers` - -Lists every configured provider with its credential and model-discovery state, without revealing any key. This is the provider item shape referenced by the other provider endpoints. - -On success, `data.items` is an array of: - -| Field | Type | Description | -| --- | --- | --- | -| `id` | string | Provider id | -| `type` | string | Wire protocol: `kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `base_url` | string | API base URL, when set | -| `default_model` | string | The provider's default model alias, when set | -| `has_api_key` | boolean | Whether a credential is stored | -| `status` | string | `connected` when an API key or cached OAuth token exists, `unconfigured` otherwise (`error` is reserved in the schema) | -| `models` | array | The provider's model alias ids | - -#### `POST /api/v1/providers` - -Creates a provider and its model aliases in one save; the reply is HTTP 201 with the standard envelope. When no global `default_model` is configured at all (fresh setup), it is seeded with the new provider's `default_model` (or first model); an existing default is never modified. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `id` | body | string | **Required.** Provider id — letters, digits, `-`, `_`, and spaces; must start with a letter or digit | -| `type` | body | string | **Required.** Wire protocol: `kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `api_key` | body | string | API key, stored in `config.toml` | -| `base_url` | body | string | API base URL; must not contain an environment variable placeholder (`${...}`) | -| `default_model` | body | string | The provider's default model; must be one of `models[].model` | -| `models` | body | array | **Required.** At least one entry, no duplicate `model` values; entry shape below | - -Each `models[]` entry declares one alias whose id becomes `id/model`: - -| Field | Type | Description | -| --- | --- | --- | -| `model` | string | **Required.** Upstream model name | -| `max_context_size` | integer | **Required.** Context window in tokens, ≥ 1 | -| `display_name` | string | Display name | -| `capabilities` | array | Capability flags such as `thinking` or `image_in` | -| `max_output_size` | integer | Max output tokens, ≥ 1 | -| `support_efforts` | array | Supported Thinking-mode effort levels | -| `adaptive_thinking` | boolean | Adaptive thinking toggle | - -On success, `data` is the created provider item (same shape as a `GET /api/v1/providers` item). - -- `40921`: a provider with this `id` already exists - -#### `GET /api/v1/providers/{provider_id}` - -Reads one provider. Unlike the list route, the response reveals the stored `api_key` when one is set, so a local edit form can prefill — keep this in mind when exposing the port. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider_id` | path | string | **Required.** Provider id | - -On success, `data` is the provider item plus `api_key` when a key is stored. - -- `40412`: provider not found - -#### `PUT /api/v1/providers/{provider_id}` - -Replaces a provider in one save: `type`, `base_url`, and the model list are rewritten, and the provider's aliases are rebuilt from `models` — aliases no longer listed disappear from `config.toml`, while other providers' aliases are untouched. `api_key` is tri-state: omitted keeps the stored key, `""` clears it, any other value replaces it. Beyond the `new_id` rename migration, the global default pointers are never modified. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider_id` | path | string | **Required.** Current provider id | -| `new_id` | body | string | Rename the provider; the providers key, model aliases, `default_provider`, a `default_model` pointing at an old alias, and the subagent secondary-model pool all migrate. Same id rules as `POST /api/v1/providers` | -| `type` | body | string | **Required.** Wire protocol: `kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `api_key` | body | string | Tri-state, see above | -| `base_url` | body | string | API base URL; must not contain an environment variable placeholder (`${...}`) | -| `default_model` | body | string | The provider's default model; must be one of `models[].model` | -| `models` | body | array | **Required.** At least one entry, no duplicate `model` values; same entry shape as `POST /api/v1/providers` | - -On success, `data` is `{ provider }` with the saved provider item. - -- `40001`: a renamed alias id would collide with another provider's alias -- `40003`: provider is OAuth-managed — log out via `POST /api/v1/oauth/logout` instead -- `40412`: provider not found -- `40921`: `new_id` is already taken - -#### `DELETE /api/v1/providers/{provider_id}` - -Deletes a provider and all of its model aliases; the subagent secondary-model pool is cascaded. The global `default_provider` / `default_model` pointers are left untouched, even when they point at the deleted provider — they are the user's settings, not this endpoint's to garbage-collect. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider_id` | path | string | **Required.** Provider id | - -On success the server answers 204 with no body — the status line itself reports the delete (see [Response envelope](#response-envelope)). - -- `40003`: provider is OAuth-managed — log out via `POST /api/v1/oauth/logout` instead -- `40412`: provider not found - -#### `POST /api/v1/providers/{provider_id}:refresh` - -Re-discovers one provider's model metadata from its upstream source and rewrites the provider's aliases. Providers with a static model source are reported `unchanged` without any network call. When at least one provider's aliases change, the server broadcasts the global `event.model_catalog.changed` event. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `provider_id` | path | string | **Required.** Provider id | - -On success, `data` is a refresh report: `changed` is an array of `{ provider_id, provider_name, added, removed }` (added/removed alias counts), `unchanged` is an array of provider ids with no diff, and `failed` is an array of `{ provider, reason }`. - -- `40001`: malformed or unsupported action suffix in the path -- `40412`: provider not found - -#### `POST /api/v1/providers:refresh` - -Refreshes model metadata for every provider. The body is optional and ignored. - -On success, `data` is the same refresh report as `POST /api/v1/providers/{provider_id}:refresh` (`changed` / `unchanged` / `failed`). - -#### `POST /api/v1/providers:refresh_oauth` - -Same refresh as `POST /api/v1/providers:refresh`, limited to OAuth-backed providers. The body is optional and ignored. - -On success, `data` is the refresh report (`changed` / `unchanged` / `failed`). - -#### `POST /api/v1/providers:import_catalog` - -Imports one models.dev directory entry as a configured provider; the reply is HTTP 201 with the standard envelope. The wire protocol and endpoint come from the catalog resolution, and every catalogued model is written as an alias. Importing an id that already exists is a refresh — the provider entry and its aliases are rewritten from the catalog, and an omitted `api_key` keeps the stored key. The global default pointers are never modified, except that `default_model` is seeded from the first imported model when none is configured at all. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `catalog_id` | body | string | **Required.** Directory entry id from `GET /api/v1/catalog/providers` | -| `id` | body | string | Override the catalog id as the local provider id. Same id rules as `POST /api/v1/providers` | -| `api_key` | body | string | API key for the imported provider | -| `base_url` | body | string | Override the catalog-resolved endpoint; required when the entry's `needs_base_url` is `true` | - -On success, `data` is `{ provider, models_imported }` — the provider item and the number of aliases written. - -- `40001`: `catalog_id` missing or another body validation failure -- `40003`: the target provider exists and is OAuth-managed -- `40004`: the entry cannot be imported (rejected, requires a `base_url`, has no importable models, or its id is unusable as a provider id) -- `40417`: no directory entry with that `catalog_id` -- `50004`: the models.dev directory is unavailable - -#### `POST /api/v1/providers:import_registry` - -Imports a models.dev-shaped private registry — an `api.json` URL plus an optional Bearer key — as configured providers; the reply is HTTP 201 with the standard envelope. Every listed provider is written with a `source` record so scheduled refreshes rediscover it. Re-importing the same URL removes providers that disappeared upstream — the URL is the registry's stable identity, so rotating the key is safe. The global default pointers follow the same rules as `:import_catalog`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `url` | body | string | **Required.** URL of the registry's `api.json` | -| `api_key` | body | string | Bearer key for the registry; when omitted, the key from the previous import of the same URL is reused | - -On success, `data` is `{ providers, models_imported }` — an array of provider items and the total number of aliases written. - -- `40001`: `url` missing or another body validation failure -- `40003`: a listed provider exists and is OAuth-managed -- `40005`: the registry cannot be fetched or parsed, or lists no importable providers - -#### `GET /api/v1/catalog/providers` - -Browses the models.dev directory, proxied by the server with a 10-minute in-memory cache and a built-in snapshot fallback. Items keep the upstream directory order. Entries the server cannot import carry `rejected: true` with a machine-readable `reject_reason`; entries with `needs_base_url: true` require a base URL at import time. - -On success, `data.items` is an array of `{ id, name, wire_type, guessed, needs_base_url, rejected, reject_reason, env_key, models }`: `wire_type` is the resolved protocol (nullable, same enum as a provider `type`), `guessed` marks a heuristic resolution, `env_key` is the upstream's conventional API-key environment variable (nullable), and `models` is an array of `{ id, name?, max_context_size, capabilities?, reasoning }`. - -- `50004`: the directory is unavailable (both the live fetch and the built-in snapshot failed) - -#### `GET /api/v1/catalog/providers/{catalog_id}` - -Reads one models.dev directory entry by catalog id — the same item shape as `GET /api/v1/catalog/providers`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `catalog_id` | path | string | **Required.** Directory entry id | - -On success, `data` is the directory entry (same shape as a `GET /api/v1/catalog/providers` item). - -- `40417`: no directory entry with that `catalog_id` -- `50004`: the directory is unavailable - -### Sessions - -These endpoints create, list, and inspect sessions, drive session-level actions (fork, compact, undo, and friends), and read per-session rollups. Most of them return a session in the wire shape documented once under [The session object](#the-session-object); non-CRUD operations use the `:{action}` convention described above. - -| Method and path | Description | -| --- | --- | -| `POST /api/v1/sessions` | Create a session (requires `workspace_id` or `metadata.cwd`) | -| `GET /api/v1/sessions` | List sessions; cursor pagination with filters such as `busy` and `archived_only` | -| `GET /api/v1/sessions/{session_id}` | Read one session | -| `GET /api/v1/sessions/{session_id}/profile` | Read the session profile | -| `POST /api/v1/sessions/{session_id}/profile` | Update title, metadata, agent config | -| `POST /api/v1/sessions/{session_id}/title/generate` | Generate a title via the managed `chat_title` tool | -| `POST /api/v1/sessions/{session_id}:{action}` | Session actions: `fork` / `compact` / `undo` / `abort` / `btw` / `archive` / `restore` | -| `GET /api/v1/sessions/{session_id}/children` | List child sessions | -| `POST /api/v1/sessions/{session_id}/children` | Create a child session (fork with a tag) | -| `GET /api/v1/sessions/{session_id}/status` | Realtime status rollup | -| `GET /api/v1/sessions/{session_id}/goal` | Current goal snapshot (`null` when none) | -| `GET /api/v1/sessions/{session_id}/warnings` | Session-level warnings | -| `GET /api/v1/sessions/{session_id}/runtime` | Read the main agent's runtime binding | -| `POST /api/v1/sessions/{session_id}/runtime` | Switch the main agent's runtime binding | -| `POST /api/v1/sessions/{session_id}/export` | Export the session with diagnostics (zip stream, not enveloped) | -| `GET /api/v1/sessions/{session_id}/snapshot` | Full snapshot for client rebuilds (with `as_of_seq` and `epoch`) | -| `GET /api/v1/sessions/{session_id}/media/{file_id}` | Download prompt media by file id (binary) | - -#### The session object - -Every endpoint that returns a session uses this wire shape. The live facts (`busy`, `main_turn_active`, `pending_interaction`, `last_turn_reason`) are resolved from the session's activity aggregate: a session that is not loaded in this server process (a cold session) always reports not-busy with no pending interaction. A few fields are placeholders in the current projection — this is noted per field. - -| Field | Type | Description | -| --- | --- | --- | -| `id` | string | Session id (`session_...`) | -| `workspace_id` | string | Owning workspace id | -| `title` | string | Session title; `""` when untitled | -| `created_at` / `updated_at` | string | Creation and last-update times, ISO 8601 | -| `archived` | boolean | Whether the session is archived (hidden from the default session list) | -| `archived_at` | string | Archive time, ISO 8601; present only when archived | -| `busy` | boolean | Any agent has an active turn or background task | -| `main_turn_active` | boolean | The main agent has an active turn | -| `pending_interaction` | string | `none` / `approval` / `question` — an unanswered interaction is waiting | -| `last_turn_reason` | string | Main agent's latest turn outcome: `completed` / `cancelled` / `failed` | -| `last_prompt` | string | Most recent user prompt text, when present | -| `metadata` | object | Custom metadata; always carries `cwd` (the session's working directory) | -| `agent_config` | object | Projected as `{ model }`; `model` is `""` in most responses and only filled with the live model by `GET /api/v1/sessions/{session_id}/snapshot` | -| `usage` | object | Token rollup `{ input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, context_tokens, context_limit?, total_cost_usd?, turn_count? }`; all zeros outside the snapshot endpoint | -| `permission_rules` | array | Session permission rules; currently always `[]` | -| `message_count` | integer | Message count; currently always `0` | -| `last_seq` | integer | Last event sequence number; currently always `0` | - -#### `POST /api/v1/sessions` - -Creates a session and returns it. The target directory comes from `workspace_id` (an already-registered workspace) or from `metadata.cwd` (the workspace is registered on first use); passing both requires them to agree. Creation broadcasts the global `event.session.created` event. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | body | string | **Required** when `metadata.cwd` is absent. Registered workspace id; the session is created at that workspace's root | -| `metadata` | body | object | Custom metadata. `metadata.cwd` is the working directory and is **required** when `workspace_id` is absent; with both given, it must equal the workspace root | -| `title` | body | string | Initial title (at least 1 character); the session is untitled otherwise | -| `agent_config` | body | object | Accepted by the schema but currently not applied — set the model and modes through `POST /api/v1/sessions/{session_id}/profile` | - -On success, `data` is [the session object](#the-session-object) of the new session. - -- `40001`: neither `workspace_id` nor `metadata.cwd` given, or `metadata.cwd` does not match the workspace root (`details` lists the field) -- `40409`: the working directory does not exist or is not a directory -- `40410`: no registered workspace with that `workspace_id` - -#### `GET /api/v1/sessions` - -Lists sessions across workspaces, newest `updated_at` first. Cursor pagination follows [Pagination](#pagination), with one twist: without `page_size` (and without `archived_only`) the response is a single unpaginated window whose `has_more` is always `false`, so pass `page_size` to actually page. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `before_id` | query | string | Only sessions older than this id; mutually exclusive with `after_id` | -| `after_id` | query | string | Only sessions newer than this id; mutually exclusive with `before_id` | -| `page_size` | query | integer | 1–100. When paging applies, the default is `20`; see the note above for the unpaginated default behavior | -| `busy` | query | boolean | Keep only busy (or only idle) sessions | -| `include_archive` | query | boolean | Include archived sessions alongside live ones. Default `false` | -| `archived_only` | query | boolean | Keep only archived sessions; mutually exclusive with `include_archive`; implies cursor paging even without `page_size` | -| `exclude_empty` | query | boolean | Drop sessions that carry no user prompt | -| `workspace_id` | query | string | Restrict to one workspace (aliases are resolved) | - -On success, `data` is `{ items, has_more }` where each item is [the session object](#the-session-object). - -- `40001`: validation failure — for example `before_id` combined with `after_id`, or `archived_only` combined with `include_archive` -- `40410`: unknown `workspace_id` - -#### `GET /api/v1/sessions/{session_id}` - -Reads one session from the index. Live facts are included when the session is loaded in this process; a cold session reports not-busy with its last persisted turn outcome. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is [the session object](#the-session-object). - -- `40401`: session not found, or its workspace can no longer be resolved - -#### `GET /api/v1/sessions/{session_id}/profile` - -Reads the session profile — the same wire payload as `GET /api/v1/sessions/{session_id}`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is [the session object](#the-session-object). - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/profile` - -Updates the session's profile: title, custom metadata, and the main agent's config. A title set here becomes a custom title, which wins over generated titles; setting one broadcasts the global `session.meta.updated` event. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `title` | body | string | New title (at least 1 character); becomes a custom title | -| `metadata` | body | object | Keys merged into the session's custom metadata | -| `agent_config` | body | object | Partial main-agent config; fields below, all optional | - -Each `agent_config` field is applied immediately to the main agent: - -| Field | Type | Description | -| --- | --- | --- | -| `model` | string | Model alias id; an empty string is ignored | -| `thinking` | string | Thinking-mode effort level | -| `permission_mode` | string | `manual` / `yolo` / `auto` | -| `plan_mode` | boolean | Enter or exit Plan mode | -| `swarm_mode` | boolean | Enter or exit swarm mode | -| `goal_objective` | string | Create a goal with this objective | -| `goal_control` | string | `pause` / `resume` / `cancel` the current goal | - -The schema also accepts `system_prompt`, `tools`, `mcp_servers` inside `agent_config`, and a top-level `permission_rules` array, but the update route currently does not apply them. - -On success, `data` is the updated [session object](#the-session-object). - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/title/generate` - -Generates a title from the session's prompts through the managed provider's `chat_title` tool and applies it, broadcasting `session.meta.updated`. Generation requires the managed OAuth login and the `auto_session_title` experimental flag; without `force`, a session that already has a custom or generated title is reported unavailable instead of being overwritten. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `force` | body | boolean | Regenerate even when a custom or generated title exists. Default `false` | -| `source` | body | string | Title input: `user_prompts` (default) / `first_turn` / `digest` | - -On success, `data` is `{ title }` — the title now applied to the session. - -- `40401`: session not found -- `40923`: generation unavailable — the flag is off, there is no managed OAuth login or no prompt content yet, an existing title without `force`, or the backend request failed - -#### `POST /api/v1/sessions/{session_id}:{action}` - -Session actions are dispatched through one route: the path tail is parsed as `{session_id}:{action}`, the body is validated against the action's schema, and a missing or unknown action fails `40001` (`unsupported action: ...`). Every action resolves the session first, so all of them can return `40401` for an unknown session. The supported actions are documented one by one below. - -#### `POST /api/v1/sessions/{session_id}:fork` - -Copies the session — its transcript, agent state, and files — into a new session in the same workspace, and broadcasts `event.session.created`. Forking is rejected while any of the session's agents has an active turn. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `title` | body | string | Title for the fork (at least 1 character). Default `Fork: <source title>` | -| `metadata` | body | object | Custom metadata for the fork | - -On success, `data` is [the session object](#the-session-object) of the new session. - -- `40901`: the session has an active turn and cannot be forked - -#### `POST /api/v1/sessions/{session_id}:compact` - -Starts a manual full compaction of the main agent's context. The call returns immediately; progress and completion are delivered as the `compaction.*` WebSocket events. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `instruction` | body | string | Extra guidance for the compaction summary; a blank value is ignored | - -On success, `data` is an empty object. - -- `40910`: a turn or another context change is active, or the history has nothing to compact - -#### `POST /api/v1/sessions/{session_id}:undo` - -Rewinds the main agent's conversation by `count` turns and reconciles the derived session state (including the session's `last_prompt`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `count` | body | integer | Number of turns to undo; positive integer. Default `1` | -| `page_size` | body | integer | Size of the returned history window, 1–100. Default `50` | - -On success, `data` is `{ messages, status }`: `messages` is a `{ items, has_more }` page of the remaining context messages, newest first, and `status` is the same rollup as `GET /api/v1/sessions/{session_id}/status`. - -- `40901`: a turn is active or a compaction is running — wait for it to finish, then retry -- `40911`: that many turns cannot be undone (a compaction boundary or lost checkpoints); `data` carries `{ reason, requestedCount, undoableCount }` - -#### `POST /api/v1/sessions/{session_id}:abort` - -Cancels the main agent's running turn — the programmatic equivalent of the user aborting the turn in the TUI. - -On success, `data` is `{ aborted: true }`. - -#### `POST /api/v1/sessions/{session_id}:btw` - -Starts a "by the way" side conversation: forks the main agent into a child agent whose tool calls are disabled, so quick side questions run in isolation without touching the working context. Requires a usable model configuration. - -On success, `data` is `{ agent_id }` — the id of the new child agent. - -#### `POST /api/v1/sessions/{session_id}:archive` - -Marks the session archived: it disappears from the default session list (it stays listed with `include_archive` or `archived_only`), and the server broadcasts the global `event.session.archived` event. - -On success, `data` is `{ archived: true }`. - -#### `POST /api/v1/sessions/{session_id}:restore` - -Un-archives the session and resumes it. - -On success, `data` is [the session object](#the-session-object) with `archived: false`. - -#### `GET /api/v1/sessions/{session_id}/children` - -Lists the session's children — the sessions created through `POST /api/v1/sessions/{session_id}/children`. Cursor pagination follows [Pagination](#pagination). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `before_id` | query | string | Only children older than this id; mutually exclusive with `after_id` | -| `after_id` | query | string | Only children newer than this id; mutually exclusive with `before_id` | -| `page_size` | query | integer | 1–100. Default `100` | -| `busy` | query | boolean | Keep only busy (or only idle) children | - -On success, `data` is `{ items, has_more }` where each item is [the session object](#the-session-object). - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/children` - -Creates a child session: a fork of this session recorded as its child, so it shows up under `GET /api/v1/sessions/{session_id}/children`. The same active-turn restriction as `:fork` applies. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `title` | body | string | Title for the child (at least 1 character). Default `Child: <source title>` | -| `metadata` | body | object | Custom metadata for the child | - -On success, `data` is [the session object](#the-session-object) of the new session, and the server broadcasts `event.session.created`. - -- `40901`: the session has an active turn and cannot be forked - -#### `GET /api/v1/sessions/{session_id}/status` - -Realtime status rollup of the main agent; reading it resumes the session if it is cold. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ busy, model?, thinking_level, permission, plan_mode, swarm_mode, context_tokens, max_context_tokens?, context_usage? }`: `busy` reports an active turn, `model` / `thinking_level` / `permission` are the effective agent settings, `plan_mode` / `swarm_mode` are the mode flags, and `context_tokens` with `max_context_tokens` and `context_usage` (0–1) describe context-window consumption. - -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/goal` - -Reads the session's current goal snapshot, or `null` when no goal is active. Note that this payload uses camelCase keys, unlike most of this API. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `null` or `{ goalId, objective, completionCriterion?, status, turnsUsed, tokensUsed, wallClockMs, budget, terminalReason? }`, where `status` is `active` / `paused` / `blocked` / `complete` and `budget` reports the token, turn, and wall-clock budgets together with the remaining amounts and per-budget reached flags (each nullable when no such budget is set). - -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/warnings` - -Reads session-level warnings. The current producer is the oversized `AGENTS.md` check (`agents-md-oversized`), so the list is empty for most sessions. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ warnings }`, each entry `{ code, message, severity }` with `severity` one of `info` / `warning` / `error`. - -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/runtime` - -Reads the main agent's runtime binding — which runtime the session's agent loop runs on. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ workspace_id, runtime_id }`. - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/runtime` - -Switches the main agent's runtime binding. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `runtime_id` | body | string | **Required.** Target runtime id | - -On success, `data` is the new binding `{ workspace_id, runtime_id }`. - -- `40420`: no runtime with that `runtime_id` -- `40926`: the runtime exists but is unavailable - -#### `POST /api/v1/sessions/{session_id}/export` - -Exports the session together with diagnostic logs as a zip attachment (`kimi-session-<id>.zip`). The response is a binary stream, not a JSON envelope — capabilities and failure semantics are covered under [Binary and streaming endpoints](#binary-and-streaming-endpoints). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `web_log` | body | string | Client log text to include in the archive, at most 256 KB UTF-8 | -| `desktop` | body | boolean | Also include the desktop host's log. Default `false` | - -#### `GET /api/v1/sessions/{session_id}/snapshot` - -Assembles an atomic snapshot for rebuilding a client after a resync: the session, recent messages, the in-flight turn, live subagents, and pending interactions, all stamped with the `as_of_seq` watermark and `epoch` used to resubscribe — see [Reconnect and recovery](#reconnect-and-recovery). Unlike the plain session endpoints, the embedded session carries the live `agent_config.model` and real `usage` totals. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ as_of_seq, epoch, session, messages, in_flight_turn, subagents?, pending_approvals, pending_questions }`: `session` is [the session object](#the-session-object), `messages` is the newest 100 messages as `{ items, has_more }`, `in_flight_turn` is the partially streamed turn (`null` when idle, with `current_prompt_id` when known), `subagents` lists live subagent tasks, and `pending_approvals` / `pending_questions` carry the unanswered interactions. - -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/media/{file_id}` - -Downloads a prompt media file (an image or other attachment referenced by the session's prompts) by file id; an id not yet committed to the session falls back to the staged uploads. The response is binary with `Range` support (206 on ranged requests) — see [Binary and streaming endpoints](#binary-and-streaming-endpoints) for the shared conventions; unlike the enveloped endpoints there, a missing session or file answers with a real 404 status carrying an envelope body. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `file_id` | path | string | **Required.** Media file id | - -### Messages and transcript - -The `messages` endpoints page the main agent's flattened message history, while the `transcript` endpoints serve the structured per-agent transcript — turns, tasks, interactions, attachments — that the WebSocket [Transcript protocol](#transcript-protocol) streams live. Use these endpoints for history paging and catch-up, and the WebSocket subscription for the live tail. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/messages` | Page messages (`before_id` / `after_id` / `role`) | -| `GET /api/v1/sessions/{session_id}/messages/{message_id}` | Read one message | -| `GET /api/v1/sessions/{session_id}/transcript` | Turn-paged transcript (requires `agent_id`); global state rides along unpaginated | -| `GET /api/v1/sessions/{session_id}/transcript/ops` | Op-batch catch-up (`since_seq`); `complete: false` means a full refresh is needed | -| `GET /api/v1/sessions/{session_id}/transcript/user-messages` | Turn-opening user inputs, unpaginated | -| `GET /api/v1/sessions/{session_id}/transcript/plan` | ExitPlanMode plan content, path, and review outcome | - -#### `GET /api/v1/sessions/{session_id}/messages` - -Pages the main agent's message history — the flattened context transcript shared with the session snapshot — newest first. Cursor pagination follows [Pagination](#pagination); reading the history resumes the session when it is cold. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `before_id` | query | string | Only messages older than this message id; mutually exclusive with `after_id` | -| `after_id` | query | string | Only messages newer than this message id; mutually exclusive with `before_id` | -| `page_size` | query | integer | 1–100. Default `50` | -| `role` | query | string | Keep only one role: `user` / `assistant` / `tool` / `system`. The filter applies after the page is sliced, so a filtered page can hold fewer than `page_size` items while `has_more` is still `true` — keep paging until `has_more` is `false` | - -On success, `data` is `{ items, has_more }` where each item is a message object `{ id, session_id, role, content, created_at, prompt_id?, parent_message_id?, metadata? }`; `content` is an array of content parts in the wire format documented under [Prompts](#prompts) (`text`, `tool_use`, `tool_result`, `image`, `video`, `file`, `thinking`). - -- `40001`: validation failure — for example `before_id` combined with `after_id` -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/messages/{message_id}` - -Reads one message from the same history by id. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `message_id` | path | string | **Required.** Message id | - -On success, `data` is the message object in the item shape documented under `GET /api/v1/sessions/{session_id}/messages` above. - -- `40401`: session not found -- `40403`: no message with that id in this session - -#### `GET /api/v1/sessions/{session_id}/transcript` - -Returns one page of an agent's structured transcript: turns (with their steps and frames) plus the markers and task references between them. Live sessions answer from the in-memory store (the requested agent's persisted history is backfilled first); cold sessions rebuild the agent from the persisted wire records. This is the history half of the transcript surface — the live streaming half is the [Transcript protocol](#transcript-protocol) subscription. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `agent_id` | query | string | **Required.** Agent whose transcript to read; must be a plain agent id (letters, digits, `.`, `_`, `-` — no path separators) | -| `before_turn` | query | string | Only turns older than this turn id; mutually exclusive with `after_turn` | -| `after_turn` | query | string | Only turns newer than this turn id; mutually exclusive with `before_turn` | -| `page_size` | query | integer | 1–100 turns. Default `20` | - -The page unit is the turn: without a cursor the newest page is returned, and `has_more` reports that older turns remain. On success, `data` is `{ agent_id, items, has_more, tasks, interactions, attachments, todos, meta, agents, pending_interactions, seq? }` — `items` is the paged turn slice, `tasks` / `interactions` / `attachments` / `todos` / `meta` / `agents` / `pending_interactions` are global agent state that ships unpaginated with every response, and `seq` is the agent's op-batch watermark for resuming the stream (live sessions only). - -- `40001`: validation failure — `before_turn` combined with `after_turn`, or a non-plain `agent_id` -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/transcript/ops` - -Serves point-to-point catch-up from the server's op journal: the journaled op batches with `seq > since_seq` for one agent, oldest first. It is the REST counterpart of the `transcript_since` resume cursor described in [Transcript protocol](#transcript-protocol) and shares the same bounded journal, so the same fallback rule applies. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `agent_id` | query | string | **Required.** Agent id (plain id, same constraint as the transcript endpoint) | -| `since_seq` | query | integer | **Required.** The caller's last applied op-batch seq, minimum `0`; batches above it are returned | - -On success, `data` is `{ agent_id, batches, latest_seq, complete }`, each batch `{ seq, ops }`. `complete: true` means every batch up to `latest_seq` is present; `complete: false` means the journal no longer reaches back to `since_seq` (or the session is not live at all), and the caller must fall back to a full `GET .../transcript` refresh. - -- `40001`: validation failure -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/transcript/user-messages` - -Lists every turn-opening input of the session, grouped per agent and unpaginated: real user text, user-slash skill and plugin commands, and cron prompts — distinguishable via `origin` — plus attachment-only prompts projected with an empty `prompt`. Attachment entities referenced by the listed messages ride along (metadata only, never bytes). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `agent_id` | query | string | Read one agent only (plain id). Default reads every rostered agent | - -On success, `data` is `{ agents }` where each entry is `{ agent_id, messages, attachments }`; a message is `{ turn_id, ordinal, state, origin, prompt, attachment_ids?, started_at? }` with `state` the turn state (`queued` / `running` / `completed` / `failed` / `cancelled`). - -- `40001`: validation failure — a non-plain `agent_id` -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/transcript/plan` - -Reads the plan information of an agent's `ExitPlanMode` tool calls — plan content, plan file path, offered options, and the review outcome — in timeline order. Content is projected from the first available fact: the linked approval interaction (interactive reviews), the live tool frame's display (auto mode), or the tool result output text; each entry records which one in `source`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `agent_id` | query | string | **Required.** Agent id (plain id) | -| `tool_call_id` | query | string | Narrow the read to one `ExitPlanMode` call; absent lists every call with recoverable plan content | - -On success, `data` is `{ agent_id, plans }` where each plan is `{ tool_call_id, turn_id, source, plan, path?, options?, review? }`: `source` is `interaction` / `display` / `output`, `options` are the review choices as `{ label, description? }`, and `review` (present only for interactive reviews) is `{ state, selected_option?, feedback? }` with `state` one of `pending` / `approved` / `rejected` / `cancelled`. - -- `40001`: validation failure -- `40401`: session not found -- `40416`: `tool_call_id` given, but no `ExitPlanMode` call with that id exists - -### Prompts - -A prompt is one unit of user input: submitting one enqueues it on the session's main agent (or a named agent), a queued prompt can be steered into the active turn, and a running prompt can be aborted. Turn progress itself streams over the WebSocket [events](#events), not these endpoints. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/prompts` | Active and queued prompts | -| `POST /api/v1/sessions/{session_id}/prompts` | Submit a prompt (content-part array, optional model / permission-mode overrides) | -| `POST /api/v1/sessions/{session_id}/prompts:steer` | Steer queued prompts into the active turn | -| `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort` | Abort a running prompt | -| `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer` | Steer one queued prompt | - -#### `GET /api/v1/sessions/{session_id}/prompts` - -Reads the main agent's prompt queue snapshot. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ active, queued }`: `active` is the running prompt (`null` when idle) and `queued` lists the pending prompts in order. A prompt is `{ prompt_id, user_message_id, status, content, created_at }` with `status` one of `running` / `queued` / `blocked` and `content` in the content-part format accepted by `POST /api/v1/sessions/{session_id}/prompts`. - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/prompts` - -Submits a user prompt to the session. Media references are validated first, then the optional overrides are applied to the target agent — `profile` (bound together with `model` / `thinking`), then `model`, `thinking`, `permission_mode`, and `disabled_tools` — and the prompt is enqueued; the response returns as soon as the prompt is accepted, without waiting for the turn. With `skills`, the prompt runs as a bundled skill activation instead of a plain user prompt. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `content` | body | array | **Required.** Non-empty array of content parts; variants below | -| `agent_id` | body | string | Target agent. Default the main agent | -| `prompt_id` | body | string | Client-chosen prompt id for idempotent submission; an id already reserved by an in-flight prompt fails `40927`, one that has already completed fails `40903`. Cannot be combined with `skills` | -| `skills` | body | array | Bundled skill activations, at least 1 entry of `{ name, args? }`; every skill must exist and be user-activatable | -| `profile` | body | string | Agent profile to bind before submitting | -| `model` | body | string | Model alias to switch the agent to | -| `thinking` | body | string | Thinking-mode effort level | -| `permission_mode` | body | string | `manual` / `yolo` / `auto` | -| `disabled_tools` | body | array | Tool names to disable for the session | - -The schema also accepts `metadata`, `plan_mode`, `swarm_mode`, `goal_objective`, and `goal_control`, but the submit route currently does not apply them. Each `content` part is an object discriminated by `type`: - -| Part | Fields | Description | -| --- | --- | --- | -| `text` | `text` | Plain text | -| `image` / `video` | `source` | Media input; `source` is one of `{ kind: "url", url, id? }`, `{ kind: "base64", media_type, data }`, `{ kind: "file", file_id }` (an upload from `POST /api/v1/files`), or `{ kind: "session_media", file_id }` (media already committed to this session) | -| `file` | `file_id`, `name`, `media_type`, `size` | A file attachment uploaded through `POST /api/v1/files` | - -The schema also accepts the `tool_use`, `tool_result`, and `thinking` parts of the shared message format, but they are not meaningful in a user prompt. Unknown or mis-kinded `file_id` references are rejected before the prompt is created and before any override is applied. - -On success, `data` is the accepted prompt `{ prompt_id, user_message_id, status, content, created_at }`. - -- `40001`: validation failure — for example `prompt_id` combined with `skills`, or an unknown `profile` -- `40110`: no provider configured yet — finish login first -- `40111`: the resolved provider has no credential (`details.provider_id`) -- `40112`: the provider's credential was rejected (`details.provider_id`) -- `40113`: the model could not be resolved (`details.model_id` / `details.provider_id` when known) -- `40401`: session not found -- `40407`: a referenced `file_id` does not exist (or does not match the part's media kind) -- `40415`: a `skills` entry names an unknown skill -- `40903`: `prompt_id` belongs to an already-completed prompt; `data` carries `{ aborted: false }` -- `40912`: the skill exists but cannot be activated by the user -- `40927`: `prompt_id` is already reserved by an in-flight prompt - -#### `POST /api/v1/sessions/{session_id}/prompts:steer` - -Steers queued prompts into the active turn, so the running turn consumes them immediately instead of finishing first. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `prompt_ids` | body | array | **Required.** Non-empty array of queued prompt ids | - -On success, `data` is `{ steered: true, prompt_ids }`. - -- `40001`: validation failure -- `40401`: session not found -- `40402`: a listed prompt id is not in the queue - -#### `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort` - -Aborts a running prompt. This endpoint and `:steer` below dispatch through one route, `POST /api/v1/sessions/{session_id}/prompts/{tail}`: the tail is parsed as `{prompt_id}:{action}`, and a missing or unknown action fails `40001` (`unsupported action: ...`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `prompt_id` | path | string | **Required.** Prompt id | - -On success, `data` is `{ aborted: true }`. - -- `40401`: session not found -- `40402`: no prompt with that id -- `40903`: the prompt already completed; `data` carries `{ aborted: false }` - -#### `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer` - -Steers one queued prompt into the active turn — the single-prompt form of `POST /api/v1/sessions/{session_id}/prompts:steer`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `prompt_id` | path | string | **Required.** Queued prompt id | - -On success, `data` is `{ steered: true, prompt_ids: [prompt_id] }`. - -- `40401`: session not found -- `40402`: no queued prompt with that id - -### Approvals and questions - -Approvals and questions are the session's two pending-interaction kinds: an approval asks permission for a tool call, a question asks for structured input with labeled options. These endpoints list and resolve them; new requests arrive over the WebSocket as `event.approval.requested` and `event.question.requested`. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/approvals` | List pending approval requests (`status=pending` is required) | -| `POST /api/v1/sessions/{session_id}/approvals/{approval_id}` | Resolve an approval | -| `GET /api/v1/sessions/{session_id}/questions` | List pending questions (`status=pending` is required) | -| `POST /api/v1/sessions/{session_id}/questions/{question_id}` | Answer a question | -| `POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss` | Dismiss a question | - -#### `GET /api/v1/sessions/{session_id}/approvals` - -Lists the session's pending approval requests — the permission prompts raised by tool calls. Reading the list resumes the session when it is cold. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `status` | query | string | **Required.** Must be `pending` | - -On success, `data` is `{ items }` where each item is `{ approval_id, session_id, turn_id?, tool_call_id, tool_name, action, tool_input_display, created_at, expires_at }`: `tool_name` / `action` / `tool_input_display` describe the call waiting for permission, and `expires_at` is 24 hours after `created_at`. - -- `40001`: `status` missing or not `pending` -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/approvals/{approval_id}` - -Resolves a pending approval request, letting the waiting tool call proceed (or not). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `approval_id` | path | string | **Required.** Approval request id | -| `decision` | body | string | **Required.** `approved` / `rejected` / `cancelled` | -| `scope` | body | string | With `approved`, `session` (the only value) also remembers the approval rule for the rest of the session | -| `feedback` | body | string | Free-form feedback handed back to the agent | -| `selected_label` | body | string | The label of the chosen option, when the request offered labeled choices (for example a plan review) | - -On success, `data` is `{ resolved: true, resolved_at }`. - -- `40001`: validation failure -- `40401`: session not found -- `40404`: no pending approval with that id -- `40902`: the approval was already resolved; `data` carries `{ resolved: false }` - -#### `GET /api/v1/sessions/{session_id}/questions` - -Lists the session's pending questions. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `status` | query | string | **Required.** Must be `pending` | - -On success, `data` is `{ items }` where each item is `{ question_id, session_id, turn_id?, tool_call_id?, questions, created_at }`. `questions` holds 1–4 items `{ id, question, header?, body?, options, multi_select?, allow_other?, other_label?, other_description? }`, each with 2–4 `options` of `{ id, label, description? }`; `multi_select` allows several options, `allow_other` a free-text answer. - -- `40001`: `status` missing or not `pending` -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/questions/{question_id}` - -Answers a pending question. Both question endpoints dispatch through one route, `POST /api/v1/sessions/{session_id}/questions/{tail}`: a bare question id answers the question, a `{question_id}:dismiss` tail dismisses it, and anything else fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `question_id` | path | string | **Required.** Question id | -| `answers` | body | object | **Required.** Map of question item id (`q_0`, …) to an answer object; variants below | -| `method` | body | string | How the answer was produced: `enter` / `space` / `number_key` / `click` | -| `note` | body | string | Free-form note attached to the response | - -Each answer is an object discriminated by `kind`: - -| Kind | Fields | Description | -| --- | --- | --- | -| `single` | `option_id` | One chosen option | -| `multi` | `option_ids` | Several chosen options (at least 1) | -| `other` | `text` | A free-text answer | -| `multi_with_other` | `option_ids`, `other_text` | Options plus free text | -| `skipped` | — | The item was skipped | - -On success, `data` is `{ resolved: true, resolved_at }`. - -- `40001`: validation failure (`details` lists each field) -- `40401`: session not found -- `40405`: no pending question with that id -- `40902`: the question was already resolved; `data` carries `{ resolved: false }` - -#### `POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss` - -Dismisses a pending question without answering it. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `question_id` | path | string | **Required.** Question id | - -On success the envelope `code` is `40909` (`question dismissed`) rather than `0`, with `data` `{ dismissed: true, dismissed_at }` — clients must special-case this endpoint's success code. - -- `40401`: session not found -- `40405`: no pending question with that id -- `40902`: the question was already resolved; `data` carries `{ resolved: false }` - -### Background tasks - -Background tasks are the session's asynchronous units — background shells, subagents, and long-running tool tasks. The registry is live-only: a session not loaded in this server process reports an empty list. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/tasks` | List background tasks | -| `GET /api/v1/sessions/{session_id}/tasks/{task_id}` | Read a task (optional output preview) | -| `POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel` | Cancel a task | - -#### `GET /api/v1/sessions/{session_id}/tasks` - -Lists the session's background tasks. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `status` | query | string | Keep only one status: `running` / `completed` / `failed` / `cancelled` | - -On success, `data` is `{ items }` where each item is a task object `{ id, session_id, kind, description, status, created_at, started_at?, completed_at?, command?, model?, thinking_effort?, agent_id?, subagent_type?, parent_tool_call_id?, output_preview?, output_bytes? }`. `kind` is `bash` / `subagent` / `tool`; `command` is set for `bash` tasks, the model and agent fields for `subagent` tasks, and the output fields only when a task is read with `with_output`. Timed-out and lost tasks report `failed`; killed tasks report `cancelled`. - -- `40001`: validation failure — an unknown `status` -- `40401`: session not found - -#### `GET /api/v1/sessions/{session_id}/tasks/{task_id}` - -Reads one background task, optionally with a tail of its output. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `task_id` | path | string | **Required.** Task id | -| `with_output` | query | boolean | Include an output tail in the response. Default `false` | -| `output_bytes` | query | integer | Size of the requested output tail in bytes, minimum `0`. Default `32768` | - -On success, `data` is the task object documented under `GET /api/v1/sessions/{session_id}/tasks` above; with `with_output=true` and non-empty output, `output_preview` carries the tail text and `output_bytes` its byte length. - -- `40001`: validation failure -- `40401`: session not found -- `40406`: no task with that id (a cold session has no live tasks at all) - -#### `POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel` - -Cancels a running task. It dispatches through `POST /api/v1/sessions/{session_id}/tasks/{tail}` with `cancel` as the only action — a bare task id or an unknown action fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `task_id` | path | string | **Required.** Task id | - -On success, `data` is `{ cancelled: true }`. - -- `40001`: missing or unknown action suffix -- `40401`: session not found -- `40406`: no task with that id -- `40904`: the task already finished; `data` carries `{ cancelled: false }` and `details.current_status` the terminal status - -### Skills, tools, and MCP - -These endpoints expose the skill catalogs a session or workspace sees, the effective agent's tool list, and its MCP servers. Skill activation and MCP restart use the `:{action}` convention; activation is the REST analogue of the `/<skill>` slash command. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/skills` | Per-session skill catalog | -| `GET /api/v1/workspaces/{workspace_id}/skills` | Session-less skill catalog for a workspace | -| `POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate` | Activate a skill (starts a turn) | -| `GET /api/v1/tools` | List tools of the effective agent | -| `GET /api/v1/mcp/servers` | List MCP servers | -| `POST /api/v1/mcp/servers/{mcp_server_id}:restart` | Restart an MCP server | - -#### `GET /api/v1/sessions/{session_id}/skills` - -Lists the skills available to one session, merged from every source (built-in, plugin, extra, user, project) with the session's precedence applied. Reading the catalog resumes the session when it is cold. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ skills }` where each item is a skill descriptor `{ name, description, path, source, type?, disable_model_invocation? }`: `source` is `project` / `user` / `extra` / `builtin`, `type` classifies the skill (only user-activatable types can be activated), and `disable_model_invocation` hides the skill from the model. - -- `40401`: session not found (or not activated) - -#### `GET /api/v1/workspaces/{workspace_id}/skills` - -Lists the skill catalog a session in this workspace would see, without creating or resuming a session — the same merge of built-in, plugin, extra, user, and project sources computed for the workspace root. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Registered workspace id | - -On success, `data` is `{ skills }` with the skill descriptor documented under `GET /api/v1/sessions/{session_id}/skills` above. - -- `40410`: workspace not found - -#### `POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate` - -Activates a skill in the session — the REST analogue of the `/<skill>` slash command — starting a turn on the main agent with the skill's content plus `args` and attachments. The endpoint dispatches through one route, `POST /api/v1/sessions/{session_id}/skills/{tail}`: the tail is parsed as `{skill_name}:{action}`, `activate` is the only action, and a bare name or an unknown action fails `40001` (`unsupported action: ...`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `skill_name` | path | string | **Required.** Name of the skill to activate | -| `args` | body | string | Free-form arguments handed to the skill, like the text after a slash command | -| `attachments` | body | array | Media parts attached to the activation. Image and video parts carry a `source` object whose `kind` is `url` / `base64` / `file` / `session_media` (same shapes as the prompt content parts); file parts carry the top-level `file_id`, `name`, `media_type`, and `size` | - -On success, `data` is `{ activated: true, skill_name }`. - -- `40001`: validation failure or unsupported action suffix -- `40401`: session not found (or not activated) -- `40407`: a referenced attachment file does not exist -- `40415`: no skill with that name -- `40912`: the skill exists but its type cannot be activated by the user - -#### `GET /api/v1/tools` - -Lists the tools of the effective agent — the main agent of the session given by `session_id`, or of the most recently created session when the parameter is omitted. When no such session is live in this server process, the list is empty. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | query | string | Session whose main agent to inspect. Default the most recently created session | - -On success, `data` is `{ tools }` where each item is `{ name, description, input_schema, source, mcp_server_id?, active? }`: `source` is `builtin` / `skill` / `mcp`, `mcp_server_id` is set on MCP tools (parsed from the `mcp__<server>__<tool>` name), and `active` reports the tool policy's verdict. `input_schema` is currently always `null`. - -#### `GET /api/v1/mcp/servers` - -Lists the MCP servers configured for the effective agent (the most recently created live session's main agent, as in `GET /api/v1/tools`). With no live session, the list is empty. - -On success, `data` is `{ servers }` where each item is `{ id, name, transport, status, last_error?, tool_count }`: `transport` is `stdio` / `http` / `sse`, `status` is `connected` / `connecting` / `disconnected` / `error`, and `last_error` carries the failure text when the server is in `error`. - -#### `POST /api/v1/mcp/servers/{mcp_server_id}:restart` - -Reconnects one MCP server of the effective agent. The endpoint dispatches through `POST /api/v1/mcp/servers/{tail}` with `restart` as the only action — a bare server id or an unknown action fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `mcp_server_id` | path | string | **Required.** MCP server id (its configured name) | - -On success, `data` is `{ restarting: true }`. - -- `40001`: missing or unknown action suffix -- `40408`: no MCP server with that id (also reported when no session is live) - -### Capabilities and plugins - -Capabilities are built-in features with layered readiness — detection steps plus a background install; the current build registers `kimi-cu` (Kimi Computer Use) and `kimi-webbridge` (Kimi WebBridge). Plugins are installed packages of skills, MCP servers, hooks, and commands. These endpoints report capability status and drive capability installs, and manage the plugin lifecycle from marketplace listing to removal. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/capabilities` | List built-in capabilities with readiness status | -| `GET /api/v1/capabilities/{capability_id}` | Read one capability's status | -| `POST /api/v1/capabilities/{capability_id}:install` | Start a capability install (background; poll GET for progress) | -| `GET /api/v1/plugins` | List installed plugins | -| `POST /api/v1/plugins` | Install a plugin from a local path, zip URL, or GitHub repo | -| `GET /api/v1/plugins/marketplace` | Marketplace catalog merged with live install state | -| `POST /api/v1/plugins/{plugin_id}:{action}` | Plugin actions: `enable` / `disable` / `remove` | - -#### `GET /api/v1/capabilities` - -Lists every registered capability with its readiness status. - -On success, `data` is `{ capabilities }` where each item is a capability status object `{ id, pluginId?, displayName, description, supported, state, version?, steps, install }`. `state` is `ready` (every required detection step `ok`) / `partial` (some step `ok`) / `not_installed` / `unsupported` (not available on this platform/architecture); `steps` lists the detection steps as `{ id, state, detail?, optional? }` with `state` one of `ok` / `missing` / `failed`; `install` is the install progress `{ running, step?, percent?, error?, note? }` with `percent` between 0 and 100. - -#### `GET /api/v1/capabilities/{capability_id}` - -Reads one capability's readiness status — the polling counterpart of the `:install` action. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `capability_id` | path | string | **Required.** Capability id | - -On success, `data` is the capability status object documented under `GET /api/v1/capabilities` above. - -- `40418`: no capability with that id - -#### `POST /api/v1/capabilities/{capability_id}:install` - -Starts installing a capability in the background and returns immediately with the current status (`install.running` is `true`); poll `GET /api/v1/capabilities/{capability_id}` for progress. The endpoint dispatches through `POST /api/v1/capabilities/{tail}` with `install` as the only action — a bare id or an unknown action fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `capability_id` | path | string | **Required.** Capability id | - -On success, `data` is the capability status object documented under `GET /api/v1/capabilities` above. - -- `40001`: missing or unknown action suffix -- `40418`: no capability with that id -- `40924`: an install of this capability is already running -- `40925`: the capability is not supported on this platform/architecture - -#### `GET /api/v1/plugins` - -Lists installed plugins. - -On success, `data` is `{ plugins }` where each item is `{ id, displayName, version?, enabled, state, skillCount, mcpServerCount, enabledMcpServerCount, hookCount, commandCount, hasErrors, source, originalSource?, github? }`: `state` is `ok` / `error` (load failures also set `hasErrors`), `source` is `local-path` / `zip-url` / `github`, and `github` carries the provenance `{ owner, repo, ref, installedSha? }` with `ref` `{ kind: branch|tag|sha, value }` for GitHub-sourced plugins. - -#### `POST /api/v1/plugins` - -Installs a plugin and returns its summary. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `source` | body | string | **Required.** Where to install from: an absolute local path, an `http(s)` URL to a zip archive, or a GitHub URL — `https://github.com/<owner>/<repo>`, optionally pinned with `/tree/<branch-or-sha>`, `/releases/tag/<tag>`, or `/commit/<sha>` | - -On success, `data` is the plugin summary documented under `GET /api/v1/plugins` above. - -- `40001`: validation failure — for example `source` is neither a URL nor an absolute path, or the plugin failed to load -- `40409`: the local path does not exist - -#### `GET /api/v1/plugins/marketplace` - -Lists the plugin marketplace catalog merged with live install state. The catalog is fetched per request (10-second timeout) from the configured marketplace URL; with the default catalog, built-in capabilities missing from the catalog are merged in as rows (with `capabilityId` set) and rows whose capability is unsupported on this platform are dropped. - -On success, `data` is `{ entries }` where each item is `{ id, tier, displayName, description?, homepage?, keywords?, version?, source, installed?, updateAvailable?, capabilityId? }`: `tier` is `official` / `curated` / `third-party`, `installed` is `{ version?, enabled }` when the plugin is installed, and `updateAvailable` marks rows whose catalog version is newer than the installed one. An entry's `source` feeds the `source` field of `POST /api/v1/plugins`. - -- `50001`: the marketplace is unreachable or returned an invalid catalog - -#### `POST /api/v1/plugins/{plugin_id}:enable` - -Enables an installed plugin. Plugin actions dispatch through one route, `POST /api/v1/plugins/{tail}`: the tail is parsed as `{plugin_id}:{action}` with `enable` / `disable` / `remove` as the actions, and a bare id or an unknown action fails `40001` (`unsupported action: ...`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **Required.** Installed plugin id | - -On success, `data` is `{ ok: true }`. - -- `40001`: missing or unknown action suffix -- `40419`: no installed plugin with that id - -#### `POST /api/v1/plugins/{plugin_id}:disable` - -Disables an installed plugin without removing it; the dispatch contract matches `:enable` above. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **Required.** Installed plugin id | - -On success, `data` is `{ ok: true }`. - -- `40001`: missing or unknown action suffix -- `40419`: no installed plugin with that id - -#### `POST /api/v1/plugins/{plugin_id}:remove` - -Removes an installed plugin; the dispatch contract matches `:enable` above. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **Required.** Installed plugin id | - -On success, `data` is `{ ok: true }`. - -- `40001`: missing or unknown action suffix -- `40419`: no installed plugin with that id - -### Terminals - -PTY terminal endpoints; mounted only on loopback binds (a non-loopback bind skips them unless `--allow-remote-terminals` is passed). Terminal input, output, and resize flow over WebSocket `terminal_*` frames — the REST surface manages the terminal lifecycle only. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/terminals` | List terminals | -| `POST /api/v1/sessions/{session_id}/terminals` | Create a terminal | -| `GET /api/v1/sessions/{session_id}/terminals/{terminal_id}` | Read a terminal | -| `POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close` | Close a terminal | - -#### `GET /api/v1/sessions/{session_id}/terminals` - -Lists the session's terminals. Reading the list resumes the session when it is cold. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | - -On success, `data` is `{ items }` where each item is a terminal object `{ id, session_id, cwd, shell, cols, rows, status, created_at, exited_at?, exit_code? }`: `status` is `running` / `exited`, and an exited terminal carries `exited_at` plus `exit_code` (`null` when the process reported none, for example after a signal). Scrollback is not part of the object — output replays and streams over the WebSocket. - -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/terminals` - -Creates a PTY terminal for the session. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `runtime_id` | body | string | Runtime to spawn in. Default `local` | -| `cwd` | body | string | Working directory, relative to the session workspace (an absolute path fails validation). Default the workspace root | -| `shell` | body | string | Shell executable. Default the runtime's shell | -| `cols` | body | integer | Terminal width, positive. Default `80` | -| `rows` | body | integer | Terminal height, positive. Default `24` | - -On success, `data` is the terminal object documented under `GET /api/v1/sessions/{session_id}/terminals` above. - -- `40001`: validation failure (`details` lists each field) -- `40401`: session not found -- `41304`: `cwd` resolves outside the session workspace - -#### `GET /api/v1/sessions/{session_id}/terminals/{terminal_id}` - -Reads one terminal. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `terminal_id` | path | string | **Required.** Terminal id | - -On success, `data` is the terminal object documented under `GET /api/v1/sessions/{session_id}/terminals` above. - -- `40401`: session not found -- `40414`: no terminal with that id - -#### `POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close` - -Closes a terminal, killing its process. The endpoint dispatches through `POST /api/v1/sessions/{session_id}/terminals/{tail}` with `close` as the only action — a bare id or an unknown action fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `terminal_id` | path | string | **Required.** Terminal id | - -On success, `data` is `{ closed: true }`. - -- `40001`: missing or unknown action suffix -- `40401`: session not found -- `40414`: no terminal with that id - -### Workspaces - -Workspaces are the registered project directories sessions live in. These endpoints manage the registry — list, register, rename, unregister — plus the per-workspace trust state that gates project-level MCP config. Every endpoint that returns a workspace uses the wire shape documented once under [The workspace object](#the-workspace-object). - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/workspaces` | List registered workspaces | -| `POST /api/v1/workspaces` | Register a workspace (idempotent on the root path) | -| `PATCH /api/v1/workspaces/{workspace_id}` | Rename | -| `DELETE /api/v1/workspaces/{workspace_id}` | Unregister (keeps on-disk content) | -| `GET /api/v1/workspaces/{workspace_id}/trust` | Read the trust state | -| `POST /api/v1/workspaces/{workspace_id}/trust` | Grant trust | -| `POST /api/v1/workspaces/{workspace_id}/untrust` | Revoke trust | - -#### The workspace object - -Every endpoint that returns a workspace uses this wire shape. Registration and rename broadcast the global `event.workspace.created` / `event.workspace.updated` events. - -| Field | Type | Description | -| --- | --- | --- | -| `id` | string | Workspace id, a `wd_<slug>_<hash12>` string derived from the root path | -| `root` | string | Absolute path of the project directory | -| `name` | string | Display name, 1–100 characters; defaults to the root's base name | -| `created_at` | string | Registration time, ISO 8601 | -| `last_opened_at` | string | Last time the workspace was opened or re-registered, ISO 8601 | -| `session_count` | integer | Number of sessions in the workspace | - -#### `GET /api/v1/workspaces` - -Lists every registered workspace. - -On success, `data` is `{ items }` where each item is [the workspace object](#the-workspace-object). - -#### `POST /api/v1/workspaces` - -Registers a workspace and returns it. Registration is idempotent on the root path: registering an already-registered root returns the existing workspace with only `last_opened_at` refreshed (the stored name is kept), broadcasting `event.workspace.updated` instead of `event.workspace.created`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `root` | body | string | **Required.** Absolute path of an existing directory | -| `name` | body | string | Display name, 1–100 characters. Default the root's base name | - -On success, `data` is [the workspace object](#the-workspace-object). - -- `40001`: `root` is missing or not an absolute path (`details` lists the field) -- `40409`: `root` does not exist or is not a directory - -#### `PATCH /api/v1/workspaces/{workspace_id}` - -Renames a workspace — the display name only; the root path never changes. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Workspace id | -| `name` | body | string | **Required.** New display name, 1–100 characters | - -On success, `data` is [the workspace object](#the-workspace-object). - -- `40001`: validation failure (`details` lists each field) -- `40410`: workspace not found - -#### `DELETE /api/v1/workspaces/{workspace_id}` - -Unregisters a workspace. Only the registry entry is removed — the on-disk directory is untouched. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Workspace id | - -On success, `data` is `{ deleted: true }`. - -- `40410`: workspace not found - -#### `GET /api/v1/workspaces/{workspace_id}/trust` - -Reads the workspace trust state. Trust gates whether project-level MCP config loads for the workspace. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Workspace id | - -On success, `data` is `{ trusted }`. - -- `40410`: workspace not found - -#### `POST /api/v1/workspaces/{workspace_id}/trust` - -Marks the workspace trusted, loading its project-level MCP config. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Workspace id | - -On success, `data` is `{ trusted: true }`. - -- `40410`: workspace not found - -#### `POST /api/v1/workspaces/{workspace_id}/untrust` - -Revokes workspace trust, unloading its project-level MCP config. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **Required.** Workspace id | - -On success, `data` is `{ trusted: false }`. - -- `40410`: workspace not found - -### File system - -In-session file operations go through `POST /api/v1/sessions/{session_id}/fs:{action}` with JSON bodies; actions are `list` / `read` / `list_many` / `stat` / `stat_many` / `mkdir` / `search` / `grep` / `git_status` / `diff` / `open` / `open-in` / `reveal`. Every action body also accepts an optional `runtime_id` (string, default `local`) selecting the runtime that executes the operation; `open`, `open-in`, and `reveal` only work on the `local` runtime. In addition: - -| Method and path | Description | -| --- | --- | -| `POST /api/v1/workspace/fs:search` | Session-less workspace search (the body carries the workspace reference) | -| `POST /api/v1/workspace/fs:suggest` | Session-less file-completion candidates (for `@` file mentions) | -| `GET /api/v1/sessions/{session_id}/fs/{path}:download` | Download a session file (binary, see below) | -| `GET /api/v1/fs:browse` | List host directories (folder picker) | -| `GET /api/v1/fs:home` | The user's home directory and recent workspaces | -| `GET /api/v1/fs:content` | Raw bytes of any host file (gated only by the token — be careful when exposing the port) | -| `POST /api/v1/fs:mkdir` | Create a directory by absolute path | - -#### `POST /api/v1/sessions/{session_id}/fs:list` - -Lists the entries of a session workspace directory, optionally recursing into subdirectories. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | Directory to list, relative to the session work directory. Default `.` | -| `depth` | body | integer | Recursion depth, 1–10. Default `1` | -| `limit` | body | integer | Maximum entries, 1–1000. Default `200` | -| `show_hidden` | body | boolean | Include dotfiles. Default `false` | -| `follow_gitignore` | body | boolean | Skip gitignored paths. Default `true` | -| `exclude_globs` | body | string[] | Additional globs to skip | -| `sort` | body | string | `type_first` (default) / `name_asc` / `name_desc` / `mtime_desc` / `size_desc` | -| `include_git_status` | body | boolean | Attach each entry's git status. Default `false` | - -On success, `data` is `{ items, truncated }` — plus `children_by_path` (a path → entries map) when `depth` is greater than 1. Each item is an entry object `{ path, name, kind, size?, modified_at, etag?, mime?, language_id?, is_binary?, is_symlink_to?, git_status?, child_count? }`, where `kind` is `file` / `directory` / `symlink` and `git_status` (present only with `include_git_status: true`) is one of `clean` / `modified` / `added` / `deleted` / `renamed` / `untracked` / `ignored` / `conflicted`; `truncated` reports that `limit` cut the listing short. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found (including a `path` that is not a directory) -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:read` - -Reads a slice of a session file as text or base64. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** File path, relative to the session work directory | -| `offset` | body | integer | Byte offset to start at. Default `0` | -| `length` | body | integer | Bytes to read, 1–10485760 (10 MiB). Default `1048576` (1 MiB) | -| `encoding` | body | string | `auto` (default) / `utf-8` / `base64` | - -On success, `data` is `{ path, content, encoding, size, truncated, etag, mime, language_id?, line_count?, is_binary }`, where `encoding` reports the encoding actually used (`utf-8` or `base64`) and `size` is the full file size. With `encoding: "auto"`, text comes back as `utf-8` (non-UTF-8 text is transcoded) and binary content as `base64`; `encoding: "utf-8"` forces text and rejects binary files. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found -- `40906`: path is a directory -- `40907`: binary file requested with `encoding: "utf-8"` -- `41302`: file exceeds the 10 MiB read ceiling -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:list_many` - -Lists several session directories in one call; a failing path folds into the response instead of failing the whole request. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `paths` | body | string[] | **Required.** Directories to list, 1–100 entries | - -The remaining body fields (`depth`, `limit`, `show_hidden`, `follow_gitignore`, `exclude_globs`, `sort`, `include_git_status`) have the same types, ranges, and defaults as `fs:list`. On success, `data` is `{ results }`, a map from each requested path to its entry array (entry objects as described under `fs:list`), plus `truncated_paths` (paths whose listing hit `limit`) and `partial_errors`, a map from a failed path to its `{ code, msg }` error. - -- `40001`: body validation failure -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/fs:stat` - -Stats one path in the session workspace. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** Path to stat, relative to the session work directory | - -On success, `data` is the entry object described under `fs:list`. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:stat_many` - -Stats many session paths in one call; missing paths report `null` instead of failing the request. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `paths` | body | string[] | **Required.** Paths to stat, 1–1000 entries | - -On success, `data` is `{ entries }`, a map from each requested path to its entry object (as described under `fs:list`) or `null` when the path does not exist. - -- `40001`: body validation failure -- `40401`: session not found - -#### `POST /api/v1/sessions/{session_id}/fs:mkdir` - -Creates a directory inside the session workspace. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** Directory to create, relative to the session work directory | -| `recursive` | body | boolean | Create missing parent directories. Default `false` | - -On success, `data` is the created directory's entry object (as described under `fs:list`). - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: parent directory not found (non-recursive create) -- `40919`: path already exists (non-recursive create) -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:search` - -Fuzzy-searches file and directory names across the session workspace. An empty `query` lists the top-level entries instead. When the `{session_id}` slot carries a workspace reference (a registered workspace id or an absolute root) rather than a session id, the search runs against that workspace — the session-less form for a not-yet-created draft session; the first-class session-less endpoint is `POST /api/v1/workspace/fs:search`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id, or a workspace reference | -| `query` | body | string | **Required.** Search text; `""` lists the top level | -| `limit` | body | integer | Maximum hits, 1–200. Default `50` | -| `include_globs` | body | string[] | Only paths matching one of these globs | -| `exclude_globs` | body | string[] | Skip paths matching these globs | -| `follow_gitignore` | body | boolean | Skip gitignored paths. Default `true` | - -On success, `data` is `{ items, truncated }` where each item is `{ path, name, kind, score, match_positions }` — `kind` is `file` / `directory` / `symlink`, `score` is the fuzzy-match score between 0 and 1, and `match_positions` lists the matched character offsets. Hits sort by score (ties by path), and `truncated` reports that hits beyond `limit` were dropped. - -- `40001`: body validation failure -- `40401`: neither a session nor a resolvable workspace with that reference - -#### `POST /api/v1/sessions/{session_id}/fs:grep` - -Searches file contents across the session workspace — a literal string by default, a regular expression with `regex: true`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `pattern` | body | string | **Required.** Text or regex to search for | -| `regex` | body | boolean | Treat `pattern` as a regular expression. Default `false` | -| `case_sensitive` | body | boolean | Default `true` | -| `include_globs` | body | string[] | Only files matching one of these globs | -| `exclude_globs` | body | string[] | Skip files matching these globs | -| `follow_gitignore` | body | boolean | Skip gitignored paths. Default `true` | -| `max_files` | body | integer | Files to scan at most, 1–10000. Default `200` | -| `max_matches_per_file` | body | integer | Matches kept per file, 1–10000. Default `50` | -| `max_total_matches` | body | integer | Matches kept overall, 1–100000. Default `5000` | -| `context_lines` | body | integer | Context lines around each match, 0–10. Default `2` | - -On success, `data` is `{ files, files_scanned, truncated, elapsed_ms }` where each entry of `files` is `{ path, matches }` and each match is `{ line, col, text, before, after }` (`before` / `after` carry up to `context_lines` surrounding lines); `truncated` reports that one of the match budgets cut the results short. - -- `40001`: body validation failure -- `40401`: session not found -- `41305`: the search timed out - -#### `POST /api/v1/sessions/{session_id}/fs:git_status` - -Reads the git status of the session workspace, optionally restricted to a set of paths. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `paths` | body | string[] | Restrict the status to these paths; omitted means the whole workspace | - -On success, `data` is `{ branch, ahead, behind, entries, additions, deletions, pullRequest }` where `entries` maps each changed path to its status (`clean` / `modified` / `added` / `deleted` / `renamed` / `untracked` / `ignored` / `conflicted`) and `pullRequest` is `{ number, state, url }` (`state` is `open` / `merged` / `closed` / `draft`) or `null`. - -- `40001`: body validation failure -- `40401`: session not found -- `40908`: git is unavailable (not a repository, or no git binary) - -#### `POST /api/v1/sessions/{session_id}/fs:diff` - -Returns the unified git diff of one file in the session workspace. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** File to diff, relative to the session work directory | - -On success, `data` is `{ path, diff, truncated }` where `diff` is the unified diff text and `truncated` reports an over-long diff cut short. - -- `40001`: body validation failure -- `40401`: session not found -- `40908`: git is unavailable (not a repository, or no git binary) -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:open` - -Opens a session file with the host operating system's default handler. Local runtime only. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** File to open, relative to the session work directory | -| `line` | body | integer | Line number to jump to where the handler supports it (positive integer) | - -On success, `data` is `{ opened: true }`. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found -- `41304`: path escapes the session workspace - -#### `POST /api/v1/sessions/{session_id}/fs:open-in` - -Opens a session file or directory in a specific host application. Local runtime only. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `app_id` | body | string | **Required.** Target application: `finder` / `cursor` / `vscode` / `iterm` / `terminal` | -| `path` | body | string | **Required.** File or directory to open, relative to the session work directory | -| `line` | body | integer | Line number to jump to where the application supports it (positive integer) | - -On success, `data` is `{ opened: true }`. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found -- `41304`: path escapes the session workspace -- `50001`: the application failed to launch - -#### `POST /api/v1/sessions/{session_id}/fs:reveal` - -Reveals a session file in the host operating system's file manager. Local runtime only. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | body | string | **Required.** File to reveal, relative to the session work directory | - -On success, `data` is `{ revealed: true }`. - -- `40001`: body validation failure -- `40401`: session not found -- `40409`: path not found -- `41304`: path escapes the session workspace - -#### `GET /api/v1/sessions/{session_id}/fs/{path}:download` - -Downloads a file from the session workspace; `{path}` is the workspace-relative file path with the literal `:download` suffix. The response is a binary stream with range and ETag support — see [Binary and streaming endpoints](#binary-and-streaming-endpoints). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `session_id` | path | string | **Required.** Session id | -| `path` | path | string | **Required.** Workspace-relative file path plus the `:download` suffix | -| `runtime_id` | query | string | Runtime to read from. Default `local` | - -- `40001`: missing or empty path -- `40401`: session not found -- `40409`: path not found -- `41304`: path escapes the session workspace - -#### `POST /api/v1/workspace/fs:search` - -The session-less form of `fs:search`: the workspace travels in the body instead of the URL. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace` | body | string | **Required.** Registered workspace id or absolute root (registered on the spot) | -| `query` | body | string | **Required.** Search text; `""` lists the top level | -| `limit` | body | integer | Maximum hits, 1–200. Default `50` | -| `include_globs` | body | string[] | Only paths matching one of these globs | -| `exclude_globs` | body | string[] | Skip paths matching these globs | -| `follow_gitignore` | body | boolean | Skip gitignored paths. Default `true` | -| `runtime_id` | body | string | Runtime to search on. Default `local` | - -On success, `data` is `{ items, truncated }` with the same hit shape and ordering as `fs:search`. - -- `40001`: body validation failure -- `40410`: workspace not found and not a usable absolute path - -#### `POST /api/v1/workspace/fs:suggest` - -Suggests file and directory completion candidates in a workspace without a session — the backend for `@` file mentions in the composer. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `workspace` | body | string | **Required.** Registered workspace id or absolute root (registered on the spot) | -| `query` | body | string | **Required.** Partial path text to complete | -| `limit` | body | integer | Maximum candidates, 1–200. Default `50` | -| `follow_gitignore` | body | boolean | Skip gitignored paths. Default `true` | -| `show_hidden` | body | boolean | Include dotfiles. Default `false` | -| `include_globs` | body | string[] | Only paths matching one of these globs | -| `exclude_globs` | body | string[] | Skip paths matching these globs | -| `runtime_id` | body | string | Runtime to complete on. Default `local` | - -On success, `data` is `{ items, truncated }` where each item is `{ path, name, kind, score, match_positions }`, the same hit shape as `fs:search`. - -- `40001`: body validation failure -- `40410`: workspace not found and not a usable absolute path - -#### `GET /api/v1/fs:browse` - -Lists the subdirectories of one host directory — the backend of the folder picker. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `path` | query | string | Absolute directory path. Default the user's home directory | - -On success, `data` is `{ path, parent, entries }` where `path` is the resolved directory, `parent` its parent (`null` at the filesystem root), and each entry is `{ name, path, is_dir: true }`. - -- `40001`: `path` is not absolute -- `40409`: path not found -- `40411`: permission denied - -#### `GET /api/v1/fs:home` - -Returns the folder picker's landing payload. No parameters. - -On success, `data` is `{ home, recent_roots }` where `home` is the user's home directory and `recent_roots` lists the roots of the registered workspaces. - -#### `GET /api/v1/fs:content` - -Streams the raw bytes of any file on the host filesystem — gated only by the API token, so be careful when exposing the port. Range requests and ETag caching are supported; see [Binary and streaming endpoints](#binary-and-streaming-endpoints). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `path` | query | string | **Required.** Absolute file path | - -- `40001`: `path` is not absolute, or not a regular file -- `40409`: path not found -- `40411`: permission denied -- `40906`: path is a directory - -#### `POST /api/v1/fs:mkdir` - -Creates one directory on the host filesystem by absolute path — the folder picker's "new folder" backend. Non-recursive: the parent directory must already exist. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `path` | body | string | **Required.** Absolute directory path | - -On success, `data` is `{ path }`. - -- `40001`: `path` is not absolute -- `40409`: parent path not found -- `40411`: permission denied -- `40919`: path already exists - -### File uploads - -| Method and path | Description | -| --- | --- | -| `POST /api/v1/files` | Multipart upload (`file` field, optional `name` and `expires_in_sec`); returns file metadata | -| `GET /api/v1/files/{file_id}` | Download (binary; errors use real HTTP statuses) | -| `DELETE /api/v1/files/{file_id}` | Delete | - -#### `POST /api/v1/files` - -Uploads a file as `multipart/form-data` for later reference (for example as a prompt attachment). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `file` | body | binary | **Required.** The multipart file part | -| `name` | body | string | Stored display name. Default the uploaded filename | -| `expires_in_sec` | body | number | Seconds until the file expires (non-negative). Default never expires | - -On success, `data` is the file metadata `{ id, name, media_type, size, created_at, expires_at? }` with `media_type` taken from the upload's content type. - -- `40001`: the multipart body has no `file` field - -#### `GET /api/v1/files/{file_id}` - -Downloads an uploaded file. The response is a binary stream that honors range requests but ignores `If-None-Match`; failures use real HTTP statuses — see [Binary and streaming endpoints](#binary-and-streaming-endpoints). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `file_id` | path | string | **Required.** File id from the upload response | - -- `40407` (HTTP 404): no file with that id (including an expired file) - -#### `DELETE /api/v1/files/{file_id}` - -Deletes an uploaded file. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `file_id` | path | string | **Required.** File id from the upload response | - -On success, `data` is `{ deleted: true }`. - -- `40407` (HTTP 404): no file with that id - -### GUI store - -A server-backed key/value store that mirrors the browser `localStorage` interface, persisted under the server's home directory; the web UI keeps cross-client UI state here. Values are opaque strings — serialization is the caller's job. - -| Method and path | Description | -| --- | --- | -| `GET /api/v1/gui/store/length` | Number of stored keys | -| `GET /api/v1/gui/store/getItem` | Read a value by key | -| `POST /api/v1/gui/store/setItem` | Write a value by key | -| `POST /api/v1/gui/store/removeItem` | Delete a value by key | -| `POST /api/v1/gui/store/clear` | Delete all values | - -#### `GET /api/v1/gui/store/length` - -Returns the number of stored keys (mirrors `localStorage.length`). No parameters. - -On success, `data` is `{ length }`. - -#### `GET /api/v1/gui/store/getItem` - -Reads one value (mirrors `localStorage.getItem`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `key` | query | string | **Required.** Key to read, 1–256 characters | - -On success, `data` is `{ value }`, the stored string or `null` when the key does not exist. - -#### `POST /api/v1/gui/store/setItem` - -Writes one value (mirrors `localStorage.setItem`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `key` | body | string | **Required.** Key to write, 1–256 characters | -| `value` | body | string | **Required.** Value to store | - -On success, `data` is `null`. - -#### `POST /api/v1/gui/store/removeItem` - -Deletes one value (mirrors `localStorage.removeItem`). - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `key` | body | string | **Required.** Key to delete, 1–256 characters | - -On success, `data` is `null`. - -#### `POST /api/v1/gui/store/clear` - -Deletes every stored value (mirrors `localStorage.clear`). No parameters. - -On success, `data` is `null`. - -### Global search and misc - -| Method and path | Description | -| --- | --- | -| `POST /api/v1/search` | Cross-session full-text search; `mode` is `terms` (default) or `literal` (exact substring); `page_token` pagination | -| `GET /api/v1/connections` | List live WebSocket connections | -| `GET /api/v2/sessions` | Next-generation session list, see below | -| `POST /api/v2/sessions:archive` | Batch-archive sessions, see below | -| `POST /api/v2/sessions:restore` | Batch-restore archived sessions, see below | -| `/api/v2/mcp/*` | Unified MCP management plane, see below | -| `/api/v1/debug/*` | Reflection debug RPC; mounted only with `--debug-endpoints` on loopback, not a stable protocol | - -#### `POST /api/v1/search` - -Cross-session full-text search over user messages, assistant replies, and session titles, backed by the server's persistent search index. When `container.session_id` names a session live in this server process, the search instead scans that session's in-memory transcript directly, and the response's `source` field (`index` or `live`) reports which path served the page. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `query` | body | string | **Required.** Search text | -| `mode` | body | string | `terms` (default) / `literal` | -| `op` | body | string | Term combiner in `terms` mode: `AND` (default) / `OR` | -| `container` | body | object | Restrict the search to `{ session_id?, agent_id? }` | -| `role` | body | string | Restrict to `user` / `assistant` / `title` hits | -| `start_time` | body | integer | Only hits at or after this time (epoch milliseconds) | -| `end_time` | body | integer | Only hits at or before this time (epoch milliseconds) | -| `sort` | body | string | `score` (default) / `time_desc` / `time_asc`; ignored by `literal` mode, which always returns newest-first | -| `page_size` | body | integer | Hits per page, 1–50. Default `20` | -| `page_token` | body | string | Token from the previous page's response | - -In `terms` mode the query is tokenized (ASCII words plus CJK n-grams), deduplicated, and matched against the inverted index with at most 32 terms; `literal` mode is an exact substring search with zero false positives. On success, `data` is `{ items, has_more, page_token?, index_state, source }` where each item is `{ session_id, workspace_id, session_title, agent_id, role, snippet, time, turn?, step_id?, score }`. `index_state` is `{ state, indexed_sessions, total_sessions, documents, stale?, degraded? }` with `state` one of `building` / `ready` / `readonly`; `stale` marks a behind view still catching up, and `degraded` carries the last refresh failure. An over-budget page additionally carries `incomplete`, one of `candidate_cap` / `postings_budget` / `deadline`. Page tokens pin the index generation and the query conditions — a rebuild or a changed query invalidates them. - -- `40001`: body validation failure, an unusable query (empty, or more than 32 terms), or an invalid page token - -#### `GET /api/v1/connections` - -Lists the WebSocket clients currently connected to this server, oldest connection first. No parameters. - -On success, `data` is `{ connections }` where each item is `{ id, connected_at, remote_address, user_agent, has_client_hello, subscriptions }`: `connected_at` is an ISO 8601 timestamp, `remote_address` and `user_agent` are `null` when unknown, `has_client_hello` reports whether the client sent its handshake frame, and `subscriptions` lists the session ids the connection is subscribed to. - -### `GET /api/v2/sessions` - -A next-generation session query for list views — filtering, sorting, and field groups all travel in query parameters: - -| Parameter | Description | -| --- | --- | -| `workspace.id` | Filter by workspace; repeatable | -| `activity.status` | Filter by activity status: `running` / `approval` / `question` / `failed` / `idle`; repeatable | -| `meta.updated_after` | Only sessions updated after this time (epoch milliseconds) | -| `meta.updated_before` | Only sessions updated before this time (epoch milliseconds) | -| `meta.archived` | `true` / `false` (default) / `all` | -| `meta.has_prompt` | `true` keeps only sessions that carry a user prompt, `false` keeps only empty ones (the `exclude_empty` equivalent of `GET /api/v1/sessions`) | -| `view` | `flat` (default) / `by_workspace`, see below | -| `group.page_size` | Sessions returned per workspace under `view=by_workspace`: 1–100, default 5 (up to 10000 with the `id,archived` projection); rejected without the grouped view (`40001`) | -| `sort` | `meta.updated_at_desc` (default) / `meta.updated_at_asc` / `meta.created_at_desc` | -| `include` | Comma-separated extra field groups; currently only `git` (branch and PR info, deduplicated per directory and cached for 60 seconds) | -| `fields` | Comma-separated item projection; currently only `id,archived`, trimming each item to `{ id, archived }` (select-all-matching flows). Not combinable with `include=git` (`40001`) | -| `page_size` | 1–100, default 50; up to 10000 with the `id,archived` projection. Under `view=by_workspace` it counts groups per page | -| `page_token` | Pagination token from the previous page | -| `page` | Stateless 1-based page number; mutually exclusive with `page_token` (`40001` when combined) | - -Every response item carries the `workspace`, `meta`, and `activity` groups, plus `git` when `include=git` — or just `{ id, archived }` under `fields=id,archived`. Every page additionally carries `total`, the size of the filtered set. The page token binds the first page's query conditions (including the projection); changing them mid-pagination returns `40922`. `page` mode is a stateless alternative for jumping to arbitrary pages: every request is an independent snapshot, no token is minted, and `next_page_token` is always `null`. - -With `view=by_workspace` the same filtered, sorted set is re-projected into per-workspace groups, so an overview client replaces one polling loop per workspace with a single request: - -```json -{ - "code": 0, - "msg": "success", - "data": { - "groups": [ - { - "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" }, - "sessions": [ { "id": "session_...", "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" }, "meta": { "title": "Fix the login page", "last_prompt": "adjust the button spacing", "created_at": 1787000000000, "updated_at": 1787000100000, "archived": false, "archived_at": null }, "activity": { "status": "idle" } } ], - "total": 42 - } - ], - "total": 7, - "has_more": true, - "next_page_token": "eyJ2IjoxLCJmIjoi..." - }, - "request_id": "req_..." -} -``` - -Each group carries the workspace's first `group.page_size` sessions under the requested `sort` plus `total`, the workspace's full matching-session count (for a "view all" entry). Only workspaces with at least one matching session appear; groups order by their first session's sort key, ties broken by workspace id. `page` and `page_token` paginate over groups (the outer `total` is the group count), with the same fingerprint binding: the token also covers `view` and the grouping parameters, so flipping them mid-pagination returns `40922`. - -### `POST /api/v2/sessions:archive` and `POST /api/v2/sessions:restore` - -Batch archive/restore for session-management views. The body is `{ "ids": ["session_..."] }` — non-empty, at most 5000 unique ids (duplicates collapse). Live sessions go through the full lifecycle; cold sessions are patched on disk without being loaded. - -Only a body validation failure fails the whole request (`40001`). Otherwise the response is per-item: `data.results` keeps the input order with `{ id, ok }` or `{ id, ok: false, error }` (an unknown id reports `40401` in its own item), plus `succeeded` / `failed` counts. - -```json -{ - "code": 0, - "msg": "success", - "data": { - "results": [ - { "id": "session_a", "ok": true }, - { "id": "session_b", "ok": false, "error": { "code": 40401, "message": "session session_b does not exist" } } - ], - "succeeded": 1, - "failed": 1 - }, - "request_id": "req_..." -} -``` - -### MCP management (`/api/v2/mcp`) - -The `/api/v2/mcp/*` routes are the server's unified MCP management plane: they manage the MCP server registry itself, independent of any session — global (user-level) CRUD with per-entry validation, connection-test probes, a locator-addressed inspection catalog, per-server auth-status listing, and the full OAuth flow lifecycle. - -| Method and path | Description | -| --- | --- | -| `GET /api/v2/mcp/servers` | List every known MCP server | -| `GET /api/v2/mcp/servers/{name}` | Get one server by runtime name | -| `POST /api/v2/mcp/servers` | Add a server to the user-level `mcp.json` | -| `PUT /api/v2/mcp/servers/{name}` | Replace a user-level entry | -| `DELETE /api/v2/mcp/servers/{name}` | Remove a user-level entry | -| `POST /api/v2/mcp/servers:test` | Probe a real connection to one server | -| `POST /api/v2/mcp/servers:inspect` | Locator-addressed catalog with a batched connection probe | -| `GET /api/v2/mcp/auth-statuses` | Per-server OAuth state over the catalog | -| `POST /api/v2/mcp/auth:begin` | Begin an interactive OAuth flow | -| `POST /api/v2/mcp/auth:complete` | Await the browser callback and finish the code exchange | -| `POST /api/v2/mcp/auth:cancel` | Tear down a begun OAuth flow | -| `POST /api/v2/mcp/auth:reset` | Clear a server's stored credentials | - -Two addressing schemes appear on this plane. The CRUD routes and `servers:test` take a plain runtime `name`; the inspection and OAuth routes take a **locator** — `{ "source": "global", "name" }` for a file-layer entry or `{ "source": "plugin", "pluginId", "serverName" }` for a plugin-manifest entry — because a plugin entry and a file entry can share one runtime name. Inspection items additionally carry a stable `serverId` wire id: `global:<name>` or `plugin:<pluginId>:<serverName>` (URL-encoded). - -Most routes accept an optional `cwd` (a query parameter, or a body field on the `:`-action routes). Without it the catalog covers the user-level file and plugin manifests only; with it, the project-root and project-local layers of that directory join in — but only when the workspace is trusted, otherwise the project layers are skipped. For `servers:test` on a stdio server, `cwd` is also the child process's working directory. Connection probes and OAuth calls wait for the server's configuration to finish loading before acting. - -#### `GET /api/v2/mcp/servers` and `GET /api/v2/mcp/servers/{name}` - -Lists every MCP server the management plane knows about; the second route returns the single entry with that runtime name. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `name` | path | string | **Required (get only).** Runtime name of the server | -| `cwd` | query | string | Include the project layers of this (trusted) directory | - -On success, `data` is an array of managed servers (a single object for the get route), each `{ name, config, source, origin, mutable, plugin? }`: - -- `source`: `global` (a config-file layer) or `plugin` (a plugin manifest) -- `origin`: where the entry is defined — a file path or a plugin id -- `mutable`: only user-level entries are mutable; plugin and project-layer entries are read-only -- `config`: mutable entries carry the full config so edit UIs can prefill it; read-only entries are redacted to sorted key lists (`envKeys` / `headerKeys`) and never disclose secret values -- `plugin`: `{ id, name }`, present on plugin entries - -- `40001`: validation failure -- `40408`: no server with that name - -#### `POST` / `PUT` / `DELETE /api/v2/mcp/servers` - -Global CRUD against the user-level `mcp.json`. The add body is a full server config including `name` — `transport` (`stdio` / `http` / `sse`) discriminates the shape, and each entry is validated before it is written. The update body carries the same config without `name` (the path names the entry); delete takes no body. All three return the refreshed server list in `data`. A write whose name collides with a project-layer entry is rejected as read-only — edit the defining file instead; a same-named plugin entry does not block the write, and the new file entry shadows it. - -- `40001`: validation failure, or the target entry is read-only -- `40408`: (update/delete) no server with that name - -#### `POST /api/v2/mcp/servers:test` - -Probes a real connection to one server and never persists anything. Pass either `name` to test a registry entry (plugin and trusted project layers included) or `server` (a full inline config, `name` included) to probe it as-is; passing both or neither fails `40001`. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `name` | body | string | Runtime name of a registry entry | -| `server` | body | object | Inline server config to probe as-is | -| `cwd` | body | string | Project layers join the resolution; also the stdio working directory | - -On success, `data` is `{ success, output }`: when the connection succeeds, `output` lists the server's available tools; otherwise it carries the failure text. - -- `40001`: both or neither target form passed, an invalid inline config, or a runtime name shared by multiple enabled servers -- `40408`: no server with that name - -#### `POST /api/v2/mcp/servers:inspect` - -The locator-addressed catalog (redacted configs) plus a batched real-connection probe of every OAuth candidate. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `targets` | body | array | Locators narrowing the catalog; omitted inspects all servers | -| `cwd` | body | string | Include the project layers of this (trusted) directory | - -On success, `data` is an array of inspections, each `{ serverId, locator, runtimeName, canonicalUrl?, origin, config, enabled, editable, authStatus, checkedAt?, error? }`: `canonicalUrl` is the credential URL of a remote server, `config` is the redacted view, and `authStatus` is one of `not-applicable` / `bearer-token` / `oauth-required` / `oauth-authorized` / `oauth-expired` / `unavailable`. A runtime name shared by multiple enabled servers cannot be probed unambiguously and reports `unavailable` with an explanatory `error`. A probe that hits an expired grant may refresh or invalidate the stored credentials. - -- `40001`: validation failure -- `40408`: a `targets` locator matches nothing - -#### `GET /api/v2/mcp/auth-statuses` - -Per-server OAuth state over the registry catalog — the lightweight alternative to `servers:inspect` when only the auth dimension is needed. - -| Parameter | In | Type | Description | -| --- | --- | --- | --- | -| `cwd` | query | string | Include the project layers of this (trusted) directory | -| `verify` | query | string | `true` probes every OAuth candidate through a real connection; `false` is fully offline (config and stored tokens only); omitted preserves implicit OAuth detection, probing only unpinned remote servers without stored credentials | - -On success, `data` is an array of `{ name, authStatus }` with the same `authStatus` enum as `servers:inspect`. Verification probes may refresh or invalidate stored credentials. - -#### `POST /api/v2/mcp/auth:begin` / `:complete` / `:cancel` / `:reset` - -The OAuth flow lifecycle for remote servers. `auth:begin` takes a locator body (plus the optional `cwd` query) and answers `data` `{ status: "authorization-required", flowId, authorizationUrl }` — open the URL in a browser to grant access — or `{ status: "already-authorized" }` when a grant already exists. The target server must use a remote transport (`http` / `sse`) and must not carry a static bearer token; static headers are allowed only when the config explicitly sets `auth: "oauth"`. - -`auth:complete` waits for the browser callback of a begun flow and finishes the code exchange. Its body is `{ flowId, timeoutMs? }`: the wait defaults to 15 minutes (`timeoutMs` overrides it), an idle flow expires after 15 minutes regardless, and closing the HTTP connection aborts the wait. `data` is `null` on success. - -`auth:cancel` tears down a begun flow (`{ flowId }`) without finishing it; unknown flows are ignored. `auth:reset` takes a locator body and clears the server's stored credentials — the invalidation event reaches live sessions. - -- `40001`: validation failure — including an unknown `flowId` on `:complete`, or a server that cannot do OAuth (stdio transport, a static bearer token, or static headers without `auth: "oauth"`) on `:begin` -- `40408`: (`:begin` / `:reset`) the locator matches nothing -- `40929`: the OAuth flow itself failed - -## WebSocket protocol - -### Connect - -The only endpoint is `ws://<host>:<port>/api/v1/ws`; authentication happens at the upgrade request (see [Authentication](#authentication) above). Once connected, the server immediately sends `server_hello`: - -```json -{ - "type": "server_hello", - "timestamp": "2026-01-01T00:00:00.000Z", - "payload": { - "ws_connection_id": "conn_01JZX4...", - "protocol_version": 2, - "max_event_buffer_size": 1000, - "capabilities": { "event_batching": false, "compression": false } - } -} -``` - -Note that the server never sends heartbeats and never disconnects an idle connection — keepalive and reconnection are the client's job. - -### Control frames - -Clients send JSON frames `{ "type", "id"?, "payload" }`; every request frame gets an acknowledgement `{ "type": "ack", "id", "code", "msg", "payload" }`, where `code` 0 means success. - -| Frame | payload | Description | -| --- | --- | --- | -| `subscribe` | `{ session_ids, cursors?, agent_filter? }` | Subscribe to session events; with `cursors` (per-session `{seq, epoch}`) the server replays missed durable events | -| `unsubscribe` | `{ session_ids }` | Drop session subscriptions | -| `subscribe_v2` | `{ session_id, transcript, transcript_since? }` | Subscribe to transcript streams (the only transcript channel); `transcript` sets per-agent grades | -| `unsubscribe_v2` | `{ session_id, agent_ids? }` | Detach transcript streams; omitting `agent_ids` means the whole session | -| `watch_fs_add` / `watch_fs_remove` | `{ session_id, paths, recursive? }` | Subscribe to / unsubscribe from file-change notifications (`event.fs.changed`) | -| `client_hello` | `{ client_id }` | Handshake frame; the remaining fields are legacy compatibility | - -### Events - -Event frames look like `{ "type", "seq", "epoch"?, "volatile"?, "offset"?, "session_id"?, "timestamp", "payload" }`, where `type` is the event type itself. Two delivery scopes: - -- **Global events**: sent to every established connection, no subscription needed — `session.meta.updated`, `event.session.created`, `event.session.archived`, `event.session.work_changed`, `event.session.status_changed`, `event.workspace.*`, `event.config.*`. -- **Session events**: sent only to connections subscribed to that session, subject to `agent_filter`. Main families: - -| Family | Main events | -| --- | --- | -| Turns | `turn.started`, `turn.ended`, `turn.step.started` / `completed` / `interrupted` / `retrying` | -| Streaming text | `assistant.delta`, `thinking.delta` (carry `offset` for alignment) | -| Tool calls | `tool.call.started`, `tool.call.delta`, `tool.progress`, `tool.result` | -| Interactions | `event.approval.requested` / `resolved`, `event.question.requested` / `answered` / `dismissed` | -| Subagents | `subagent.spawned` / `started` / `suspended` / `completed` / `failed` | -| Background | `task.started` / `terminated`, `shell.started` / `output` / `completed` | -| Misc | `compaction.*`, `skill.activated`, `goal.updated`, `prompt.*`, `error`, `warning` | - -Three global lifecycle events keep a cross-workspace overview fresh without polling per workspace. `event.session.archived` fires on both the live and the cold archive path; its envelope `session_id` is the global watermark `__global__` and the real session id rides in the payload: `{ "type": "event.session.archived", "workspace_id": "wd_...", "sessionId": "session_..." }` (payload keys `workspace_id` / `sessionId`). `event.workspace.created` / `updated` carry the full workspace object (`{ id, root, name, created_at, last_opened_at, session_count }` — an `updated` also fires when a session creation touches the workspace), and `event.workspace.deleted` carries `{ "workspace_id", "root" }`. These events only cover changes made inside this server process; changes from other processes (for example a CLI writing to the same home) surface through the index reconciliation (about a minute), so overview clients should keep a low-frequency fallback poll. There is no session-deleted event. - -Events also split into durable and volatile: durable events carry a strictly increasing `seq`, are journaled, and can be replayed; volatile events (the `*.delta` family, `tool.progress`, `shell.*`, and similar) are marked `volatile: true` and never replayed. When consuming a volatile text stream, compare `offset` (the cumulative character offset within the turn) against your locally accumulated text: below the local length means a duplicate frame; above means a gap that needs snapshot recovery. - -### Reconnect and recovery - -After reconnecting, pass each session's last applied `{seq, epoch}` in `subscribe`'s `cursors`; the server replays the gap. If you fall more than the buffer (1000 events) behind, or the cursor is no longer valid, you get `resync_required` instead. In that case, call `GET /api/v1/sessions/{session_id}/snapshot` for a full snapshot (with `as_of_seq` and `epoch`), then subscribe again with the fresh cursor. - -### Transcript protocol - -`subscribe_v2`'s `transcript` field sets a per-agent grade: `off` / `turn` / `block` / `delta` (the `"*"` key sets the default grade), with higher grades pushing finer detail. An agent with a non-`off` grade receives two frame types: `transcript.reset` (a baseline snapshot; history pages in over REST) and `transcript.ops` (incremental op batches with a per-agent strictly increasing `seq`). The agent's legacy events are suppressed on that connection and carried by transcript frames instead. After a disconnect, resume with `transcript_since`; when the server's op journal cannot cover the gap (REST catch-up returns `complete: false`), do a full refresh. The REST counterparts are `GET .../transcript` (turn-paged) and `GET .../transcript/ops?since_seq=` (op-batch catch-up). - -## Binary and streaming endpoints - -The following endpoints stream binary bodies instead of a JSON payload. Their HTTP capabilities differ per endpoint: - -| Method and path | Description | Range (206) | ETag / 304 | -| --- | --- | --- | --- | -| `GET /api/v1/files/{file_id}` | Download an uploaded file | Yes | No (sends an `etag` header but ignores `If-None-Match`) | -| `GET /api/v1/sessions/{session_id}/fs/{path}:download` | Download a session workspace file | Yes | Yes | -| `GET /api/v1/fs:content` | Raw bytes of any host file (gated only by the token — be careful when exposing the port) | Yes | Yes | -| `POST /api/v1/sessions/{session_id}/export` | Export the session with diagnostics (zip stream) | No | No | - -Error semantics differ as well: `GET /api/v1/files/{file_id}` answers lookup and storage failures with real 404 / 500 statuses (parameter validation still uses the HTTP 200 envelope), while the other three report every failure through the standard [response envelope](#response-envelope) — clients must keep checking the envelope `code` on those endpoints. - -## Next steps - -- [Local server and API](../guides/server.md) — startup, authentication, and the end-to-end calling flow -- [kimi command](./kimi-command.md#kimi-web) — all `kimi web` command-line options diff --git a/docs/en/reference/slash-commands.md b/docs/en/reference/slash-commands.md index 841d20e27..f4aa14171 100644 --- a/docs/en/reference/slash-commands.md +++ b/docs/en/reference/slash-commands.md @@ -16,7 +16,7 @@ Some commands are only available in the idle state. Executing these commands whi | `/logout` | — | Clear credentials for the currently selected account | No | | `/provider` | — | Open the interactive provider manager to view, add, and remove configured providers. See [Platforms & Models — `/provider` and provider management](../configuration/providers.md#provider-—-interactive-provider-management) | Yes | | `/model` | — | Switch the LLM model used in the current session | Yes | -| `/secondary-model` | `/subagent-model` | Pick the default model for subagents (writes `[secondary_model] default_model`; see the [subagent model pool](../configuration/config-files.md#subagent-model-pool)). Visible when the subagent model pool experiment is enabled | Yes | +| `/secondary_model` | — | Configure the secondary model that newly spawned subagents bind to by default (writes the [`[secondary_model]`](../configuration/config-files.md#secondary-model) section and applies to the current session immediately). Requires the `secondary-model` experiment | Yes | | `/settings` | `/config` | Open the settings panel inside the TUI | Yes | | `/experiments` | `/experimental` | Open the experimental feature panel | Yes | | `/permission` | — | Select a permission mode | Yes | @@ -154,7 +154,7 @@ For convenience, external Skill commands also support a shorthand form that omit Built-in Skills shipped with Kimi Code CLI appear directly as `/<name>` in the slash command panel. For example, `/mcp-config` helps configure MCP servers and handle MCP OAuth login, and `/custom-theme [extra text]` invokes the custom-theme workflow to create or edit a TUI theme. ::: info -External Skill commands entered while the agent is busy are queued behind the running turn instead of being rejected — press `Ctrl-S` to steer a queued command into the running turn immediately. `flow`-type Skills are also exposed via `/skill:<name>` — there is no separate `/flow:` namespace. +All Skill commands are only available in the idle state. `flow`-type Skills are also exposed via `/skill:<name>` — there is no separate `/flow:` namespace. ::: For installing and authoring Skills, see [Agent Skills](../customization/skills.md). diff --git a/docs/en/reference/tools.md b/docs/en/reference/tools.md index 12272bb76..8b412b536 100644 --- a/docs/en/reference/tools.md +++ b/docs/en/reference/tools.md @@ -19,9 +19,9 @@ File tools handle reading, writing, and searching the local filesystem — the f **`Read`** accepts a file path (`path`) plus optional `line_offset` (starting line number; negative values count from the end) and `n_lines` (maximum number of lines to read). Returns at most 1000 lines or 100 KB per call; content beyond that limit is accompanied by a truncation notice. If the file is an image or video, the tool suggests using `ReadMediaFile` instead. -**`Write`** accepts `path`, `content`, and an optional `mode` (`overwrite` or `append`; defaults to overwrite). Missing parent directories are created automatically; `append` mode appends content to the end of the file without automatically adding a newline. Writing to an existing file — in either `overwrite` or `append` mode — requires a prior `Read` of that file in the session; the write is rejected if the file changed on disk since the last read, while creating a new file is exempt. +**`Write`** accepts `path`, `content`, and an optional `mode` (`overwrite` or `append`; defaults to overwrite). Missing parent directories are created automatically; `append` mode appends content to the end of the file without automatically adding a newline. -**`Edit`** accepts `path`, `old_string` (the exact text to replace), and `new_string` (the replacement text). By default it replaces only one unique match; if the same content appears multiple times in the file, the tool returns an error and suggests using `replace_all: true`. `old_string` and `new_string` must not be identical. The target file must have been read with `Read` earlier in the session, and the edit is rejected if the file changed on disk since that read. +**`Edit`** accepts `path`, `old_string` (the exact text to replace), and `new_string` (the replacement text). By default it replaces only one unique match; if the same content appears multiple times in the file, the tool returns an error and suggests using `replace_all: true`. `old_string` and `new_string` must not be identical. **`Grep`** invokes ripgrep to search file contents, supporting regular expressions (`pattern`), a search path (`path`), file type filtering (`type`, e.g., `ts`, `py`), glob filtering (`glob`), and output mode (`output_mode`: `files_with_matches` / `content` / `count_matches`; defaults to `files_with_matches`). `content` mode supports context lines (`-A`, `-B`, `-C`), case-insensitive matching (`-i`), line numbers (`-n`, default true), and multiline matching (`multiline`). All modes support `offset` + `head_limit` pagination; `head_limit` defaults to 250 and `0` means unlimited. Sensitive files such as `.env` files and private keys are automatically filtered out; set `include_ignored=true` to search files ignored by `.gitignore`, though sensitive files remain filtered. @@ -89,9 +89,9 @@ Collaboration tools handle inter-Agent coordination, user interaction, and Skill | `AskUserQuestion` | Auto-allow | Ask the user a question to gather structured input | | `Skill` | Auto-allow | Invoke a registered inline Skill | -**`Agent`** delegates a subtask to a sub-Agent. Required parameters: `prompt` (complete task description) and `description` (a 3–5 word short summary). Optional parameters: `subagent_type` (defaults to `coder`), `resume` (ID of an existing Agent to resume; mutually exclusive with `subagent_type`), `run_in_background` (defaults to false), and `model` (available only when the [subagent model pool](../configuration/config-files.md#subagent-model-pool) experiment is enabled and a pool is configured — a `[secondary_model.models]` table or a lone `default_model`: a pool alias, or `"primary"` for the model the caller itself is running; ignored when resuming). Without it, the subagent binds the pool's `default_model`; without a configured pool, subagents always inherit the caller's model. Agent tasks time out after 2 hours by default; the limit is configurable via `[subagent] timeout_ms` in `config.toml` (`0` = no timeout, or the `KIMI_SUBAGENT_TIMEOUT_MS` env var), and defaults to no timeout in print mode (`kimi -p`). In foreground mode the parent Agent waits for the sub-Agent to complete before continuing; in background mode a task ID is returned immediately and the result is automatically delivered back to the main Agent via a synthetic User message when done. When several foreground `Agent` calls run in the same step, the TUI groups them and shows each subagent's running, waiting, completed, or failed status with elapsed time. See [Agent & Sub-Agents](../customization/agents.md) for details. +**`Agent`** delegates a subtask to a sub-Agent. Required parameters: `prompt` (complete task description) and `description` (a 3–5 word short summary). Optional parameters: `subagent_type` (defaults to `coder`), `resume` (ID of an existing Agent to resume; mutually exclusive with `subagent_type`), `run_in_background` (defaults to false), and `model` (`"secondary"` for the secondary model configured via `[secondary_model] model`, or `"primary"` for the main model; ignored when resuming; available when the secondary-model experiment is enabled). An explicit `model` overrides the selected [agent profile's `model_preference`](../customization/agents.md#agent-file-format); without either, the configured secondary model is the default, or the subagent inherits the caller's model when no secondary model is configured. Agent tasks time out after 2 hours by default; the limit is configurable via `[subagent] timeout_ms` in `config.toml` (`0` = no timeout, or the `KIMI_SUBAGENT_TIMEOUT_MS` env var), and defaults to no timeout in print mode (`kimi -p`). In foreground mode the parent Agent waits for the sub-Agent to complete before continuing; in background mode a task ID is returned immediately and the result is automatically delivered back to the main Agent via a synthetic User message when done. When several foreground `Agent` calls run in the same step, the TUI groups them and shows each subagent's running, waiting, completed, or failed status with elapsed time. See [Agent & Sub-Agents](../customization/agents.md) for details. -**`AgentSwarm`** launches subagents from a shared `prompt_template` and an `items` array, resumes existing subagents through `resume_agent_ids`, or combines both in one call. The template must contain the `{{item}}` placeholder; each item replaces that placeholder and launches one new subagent. Pass `subagent_type` to choose the profile used by every spawned subagent in the swarm, or omit it to use `coder`. Pass `model` (available only when the [subagent model pool](../configuration/config-files.md#subagent-model-pool) experiment is enabled and a pool is configured — a `[secondary_model.models]` table or a lone `default_model`) to run item-spawned subagents on a pool alias or on the caller's own model (`"primary"`). Without it, item-spawned subagents bind the pool's `default_model`; without a configured pool, they inherit the caller's model. Resumed subagents keep their own model. Without `resume_agent_ids`, the tool requires at least 2 items; with `resume_agent_ids`, it can resume one or more existing subagents. The tool supports up to 128 total subagents, waits for all subagents to finish, and returns an aggregated report. Each subagent times out after 2 hours by default; the limit is configurable via [`[swarm] timeout_ms`](../configuration/config-files.md#swarm) in `config.toml` (`0` = no timeout, or the `KIMI_CODE_SWARM_TIMEOUT_MS` env var), and defaults to no timeout in print mode (`kimi -p`). A timed-out subagent is aborted and marked as failed in the aggregated report. In the TUI, foreground swarms show a live `Agent swarm` progress panel above the input box. If a model response calls `AgentSwarm`, that call must be the only tool call in the response; to run multiple swarms, call one `AgentSwarm`, wait for its result, then call the next, or combine the work into one swarm when a single template can cover it. In `manual` permission mode, `AgentSwarm` calls outside active swarm mode request approval unless a permission rule allows them; while swarm mode is active, `AgentSwarm` itself is auto-approved. Permission rules match `AgentSwarm` by tool name only — argument patterns such as `AgentSwarm(swarm)` are not supported. By default the tool ramps up concurrency without an upper limit (5 subagents start immediately, then 1 more every 700 ms); set `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` to a positive integer to cap how many subagents run at the same time during that ramp, or leave it unset for no cap. If it is set to a value that is not a positive integer, the AgentSwarm call fails fast. +**`AgentSwarm`** launches subagents from a shared `prompt_template` and an `items` array, resumes existing subagents through `resume_agent_ids`, or combines both in one call. The template must contain the `{{item}}` placeholder; each item replaces that placeholder and launches one new subagent. Pass `subagent_type` to choose the profile used by every spawned subagent in the swarm, or omit it to use `coder`. Pass `model` (available when the secondary-model experiment is enabled) to run item-spawned subagents on the secondary model configured via `[secondary_model] model` (`"secondary"`) or the main model (`"primary"`). This explicit choice overrides the selected [agent profile's `model_preference`](../customization/agents.md#agent-file-format); without either, the configured secondary model is the default, or the subagent inherits the caller's model when no secondary model is configured. Resumed subagents keep their own model. Without `resume_agent_ids`, the tool requires at least 2 items; with `resume_agent_ids`, it can resume one or more existing subagents. The tool supports up to 128 total subagents, waits for all subagents to finish, and returns an aggregated report. In the TUI, foreground swarms show a live `Agent swarm` progress panel above the input box. If a model response calls `AgentSwarm`, that call must be the only tool call in the response; to run multiple swarms, call one `AgentSwarm`, wait for its result, then call the next, or combine the work into one swarm when a single template can cover it. In `manual` permission mode, `AgentSwarm` calls outside active swarm mode request approval unless a permission rule allows them; while swarm mode is active, `AgentSwarm` itself is auto-approved. Permission rules match `AgentSwarm` by tool name only — argument patterns such as `AgentSwarm(swarm)` are not supported. By default the tool ramps up concurrency without an upper limit (5 subagents start immediately, then 1 more every 700 ms); set `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` to a positive integer to cap how many subagents run at the same time during that ramp, or leave it unset for no cap. If it is set to a value that is not a positive integer, the AgentSwarm call fails fast. **`AskUserQuestion`** asks the user a structured multiple-choice question — useful for disambiguation or option selection. The `questions` parameter accepts 1–4 questions; each question requires `question` (ending with `?`), `options` (2–4 choices, each with a `label` and `description`), and optional `header` (max 12 characters) and `multi_select` (defaults to false). An "Other" option is appended automatically. Setting `background` to true starts a background question task and returns a task ID immediately. When the host does not support interactive questioning, a failure message is returned and the Agent should ask the user directly in a text reply instead. @@ -99,14 +99,13 @@ Collaboration tools handle inter-Agent coordination, user interaction, and Skill ## Background Tasks -Background task tools manage tasks started via `Bash`, `Agent`, or `AskUserQuestion`. When a task reaches a terminal state, its status and saved output path are automatically delivered back to the Agent; use `TaskOutput` to check progress early, or `WaitFor` to wait for a result inside the current turn. +Background task tools manage tasks started via `Bash`, `Agent`, or `AskUserQuestion`. When a task reaches a terminal state, its status and saved output path are automatically delivered back to the Agent; use `TaskOutput` to check progress early. | Tool | Default Approval | Description | | --- | --- | --- | | `TaskList` | Auto-allow | List background tasks | | `TaskOutput` | Auto-allow | View the output of a background task | | `TaskStop` | Requires approval | Stop a running background task | -| `WaitFor` | Auto-allow | Wait for background tasks to finish | **`TaskList`** returns the list of background tasks. Optional parameters: `active_only` (defaults to true; lists only running tasks) and `limit` (defaults to 20; range 1–100). @@ -114,8 +113,6 @@ Background task tools manage tasks started via `Bash`, `Agent`, or `AskUserQuest **`TaskStop`** accepts a `task_id` and optional `reason` (defaults to `Stopped by TaskStop`). Safe to call on tasks that are already in a terminal state. -**`WaitFor`** suspends the current turn until a background task finishes or the timeout elapses. Parameters: `timeout` (required, in seconds, max 600) and optional `task_id`. Without `task_id`, the wait ends as soon as any background task that was running at call time finishes; when no background tasks are running, it returns immediately. A timeout is not an error — the result lists the tasks still running, and the Agent can wait again or do other work meanwhile. A task whose result was reported by `WaitFor` does not also produce an automatic completion notification. - ## Scheduled Tasks Scheduled task tools allow the Agent to re-inject a prompt into the current session at a future time — either as a one-time reminder or as a recurring cron-triggered task (periodic checks, daily reports, deployment monitoring, etc.). Schedules are bound to the session and remain active when you resume it with `kimi --session`, but are not carried into a brand-new session. A single session can hold at most 50 active scheduled tasks. Set `KIMI_DISABLE_CRON=1` to disable them entirely; see [Environment Variables](../configuration/env-vars.md#runtime-switches). diff --git a/docs/en/release-notes/changelog.md b/docs/en/release-notes/changelog.md index 51e620963..abdd0a2d0 100644 --- a/docs/en/release-notes/changelog.md +++ b/docs/en/release-notes/changelog.md @@ -6,125 +6,6 @@ outline: 2 This page documents the changes in each Kimi Code CLI release. -## 0.38.0 (2026-08-20) - -### Features - -- Support two OAuth login methods — kimi.ai and kimi.com. -- Add the WaitFor tool: the agent can now wait for a background task to finish within the current turn instead of ending the turn and being re-invoked. -- Add 13 data sources to the official Kimi Datasource plugin — Chinese government data (NDA/NBS) and standards (GB/HB/DB/TT), eight international organization datasets (WHO, FAO, UNSD, ECB, Eurostat, UNICEF, OECD, FRED), Xinhua Finance, and Caixin. Update the plugin from the Official tab in /plugins. -- web: Add a Pin action to the chat header more-menu. - -### Polish - -- Edit and Write now require reading an existing file before modifying it. -<!-- - Sub-agents no longer spawn their own sub-agents by default; custom agent profiles can still allow it explicitly. --> -- Collapse long `!` shell command output instead of flooding the transcript. Press ctrl+o to expand or collapse it together with tool output. - -### Bug Fixes - -- Fix config.toml entries being lost when the file had a syntax error or was edited outside the app. -- Fix several known issues and make various refinements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - -## 0.37.2 (2026-08-19) - -### Polish - -- web: Settings gains a Lab tab with a new multi-tab sidebar toggle; when enabled, the sidebar shows the Open / Done / Workspaces tabs. -- Make several refinements and internal improvements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - -## 0.37.1 (2026-08-18) - -### Bug Fixes - -- Fix pasted images and videos failing to reach the model. - -## 0.37.0 (2026-08-18) - -### Features - -- Activate multiple skills in a single prompt. Type `/` after whitespace to insert a skill token. -- The Windows native (single-binary) CLI now supports automatic updates. -- web: The sidebar gains Open / Done / Workspaces tabs, and sessions can be marked as done. -- web: Add a session management page. - -### Polish - -- Queue slash skill commands entered while the agent is busy instead of rejecting them. -- web: @-mentioned files, folders, and skills in chat messages now render as icon pills. -- web: The browser tab title now shows the current workspace directory name. -- web: The search dialog now finds workspaces too, and picking a workspace or session result expands the sidebar and scrolls the item into view. -- web: Renamed the Subagent panel to "Background Agent". -- Warn when a typed `/goal` objective exceeds the 4000-character limit, and keep the input if it is rejected. - -### Bug Fixes - -- Fix Gemini tool-calling sessions failing on follow-up requests. -- web: Fix Ctrl+K in the composer opening session search on macOS — session search now only answers to Cmd+K. -- web: Fix the Background Agent panel showing incorrect task counts and statuses. -- web: Fix pasting a copied folder into the composer failing the upload with a connection error — folders are now skipped instead. -- Fix several known issues and make various refinements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - -## 0.36.1 (2026-08-14) - -### Features - -- web: Generate session titles with AI (experimental). Off by default — set `KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE=1` (or the master flag `KIMI_CODE_EXPERIMENTAL_FLAG=1`) to turn it on. - -### Polish - -- web: Polish the Plan, Goal, and Swarm toggles in the composer, which now live in the + menu next to the input box. - -### Bug Fixes - -- Fix several known issues and make various refinements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - -## 0.36.0 (2026-08-13) - -### Features - -- Upgrade the experimental subagent model setting to a model pool: the `[secondary_model]` section can now hold a set of candidate models with descriptions, and the main agent picks from them per spawn based on the task. - - Set `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1` (or the master flag `KIMI_CODE_EXPERIMENTAL_FLAG=1`) before starting Kimi to enable it. - - Recommended setups: - - - Minimal: run `/secondary-model` in the TUI, or write a single `default_model` line in `config.toml`, to make every subagent run the same model by default; add `force = true` to pin that choice so the main agent cannot override it. - - Declare a named pool with a one-line scenario description for each alias — the descriptions are what the main agent sees when choosing: - - ```toml - [secondary_model] - default_model = "kimi-code/kimi-for-coding-highspeed" - [secondary_model.models] - "kimi-code/kimi-for-coding-highspeed" = "Fast and cheap — good for daily refactoring, code explanation, and small edits." - "kimi-code/k3" = "Strong at complex reasoning and deep debugging — pick it for hard problems." - ``` - - See the [subagent model pool docs](https://moonshotai.github.io/kimi-code/en/configuration/config-files.html#subagent-model-pool) for details. -- Add an experimental fullscreen TUI mode. Set the `KIMI_CODE_TUI_FULL_SCREEN=1` environment variable to enable it. -- Support rendering LaTeX math formulas (`$…$` / `$$…$$`) in TUI messages as Unicode formulas. - -### Bug Fixes - -- Show project MCP launch targets in the workspace trust prompt, default to declining trust, and resolve `fd` and `stty` binaries to absolute paths so untrusted workspaces cannot plant bare-name executables before confirmation. -- Fix sessions failing with a provider 400 error on every follow-up request after a turn is interrupted while the model is still thinking, on strict OpenAI-compatible providers (e.g. DeepSeek). -- Fix Ctrl+C being ignored during automatic retries of failed API requests. -- Fix several known issues and make various refinements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - -## 0.35.0 (2026-08-12) - -### Features - -- Add the Modern Web Guidance plugin to the bundled plugin marketplace. Run `/plugins` and select Modern Web Guidance to install it. -- Show the live work progress of background subagents in the `/tasks` panel. - -### Bug Fixes - -- Fix coder subagents spawning further subagents by default. -- Fix the token counts reported after compaction reading far below the real context size; they now match the numbers shown while the session runs. -- Fix two binary-planting risks on Windows. -- Fix several known issues and make various refinements. See the [changelog on GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md) for more technical entries. - ## 0.34.0 (2026-08-06) ### Features diff --git a/docs/zh/configuration/config-files.md b/docs/zh/configuration/config-files.md index 4b13c72d7..f102efba0 100644 --- a/docs/zh/configuration/config-files.md +++ b/docs/zh/configuration/config-files.md @@ -40,7 +40,7 @@ model = "k3" max_context_size = 1048576 capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] display_name = "K3" -support_efforts = [ "low", "high", "max" ] +support_efforts = [ "max" ] default_effort = "max" [models."kimi-code/kimi-for-coding"] @@ -192,109 +192,34 @@ display_name = "Kimi for Coding (custom)" ## `secondary_model` -subagent 默认继承 main agent 正在运行的模型。`[secondary_model]` 节把这件事变成可配置的:为 subagent 准备一批候选模型(模型池)并指定默认绑定——典型用法是给不需要主模型能力的子任务换一个更便宜的模型。 +次主力模型是主模型之外的第二个模型配置——通常是一个更便宜的模型,供不需要主模型能力的功能绑定使用。它目前的消费者是子 Agent 派生:设置后,新派生的子 Agent(`Agent` / `AgentSwarm`)默认绑定该模型,而不再继承主 Agent 的模型;未设置时,子 Agent 继承主 Agent 的模型。 -### subagent 模型池 +这是默认绑定而非强制。实验功能启用后,`Agent` / `AgentSwarm` 工具会获得 `model` 参数(仅接受 `"secondary"` / `"primary"` 两个符号值),工具描述中也会列出可选模型并标注默认值。派生时按以下顺序解析子 Agent 的模型:工具调用显式传入的 `model` → 子 Agent profile 的 [`model_preference`](../customization/agents.md#agent-文件格式) → 已配置的次主力模型(默认)。其中 `"primary"` 指主 Agent 当前正在运行的模型,不一定是 `default_model`——例如会话中途用 `/model` 切换过模型。 -该功能目前是实验功能,默认关闭。通过 `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1` 启用,或使用 master `KIMI_CODE_EXPERIMENTAL_FLAG=1`,在包括交互式 TUI 在内的所有启动方式下生效。实验功能关闭时模型池配置不生效:subagent 继承调用方模型,会话启动也会跳过池校验。 +由于是否覆盖默认值由主 Agent 自行决定(工具描述仅建议常规任务用 `"secondary"`、困难或质量敏感的任务用 `"primary"`,不构成强制),用户没有单次派生级别的直接开关。想让某个子 Agent 使用主模型,可以在提示词中要求主 Agent 传入 `model: "primary"`,或在对应 profile 中设置 `model_preference: "primary"`。 -最小配置只有一行——单独写下的 `default_model` 就是只含一个条目的模型池: +该功能目前是实验功能,默认关闭。通过 `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1` 启用,或使用 master `KIMI_CODE_EXPERIMENTAL_FLAG=1`。它在包括交互式 TUI 在内的所有启动方式下生效。 -```toml -[secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -``` +在交互式 TUI 中,可以使用 [`/secondary_model`](../reference/slash-commands.md) 命令打开模型选择器来设置该配置:选择后会写入本小节配置,并在当前会话立即生效——之后派生的子 Agent 会直接绑定新的次主力模型。 | 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | -| `default_model` | `string` | — | subagent 的默认模型 | -| `models` | `table<string, string>` | — | subagent 模型池。key 是 [`[models]`](#models) 条目的别名,value 是给 main agent 的挑选提示 | -| `force` | `boolean` | `false` | 把所有 subagent 固定到 `default_model`,收回 main agent 的选择权 | -| `default_effort` | `string` | — | 每次派生的 subagent 绑定的 Thinking 档位,优先于所绑定模型条目自己的 `default_effort` | +| `model` | `string` | — | [`[models]`](#models) 中已配置条目的别名,如 `kimi-code/kimi-k2.5`(不限 kimi 模型,可用任意供应商) | +| `default_effort` | `string` | — | 子 Agent 绑定次主力模型时使用的 thinking effort。未设置时按"全局 `[thinking]` 配置 → 模型默认 effort"的链路解析,不再继承主 Agent 的 effort。与主模型的 thinking effort 语义一致:严格校验 effort 的模型(如 kimi 模型)在不支持该取值时回退到模型默认 effort,其他供应商的模型按原样发送给后端 | +| 其他字段 | — | — | 接受 [`[models."<alias>".overrides]`](#models) 的全部字段(`max_context_size`、`max_output_size`、`support_efforts` 等),作为仅对子 Agent 生效的模型补丁 | -字段之间的约束: - -- `default_model`:配置 `models` 表时必填,且必须是其中的 key。 -- `models`:value 中英文均可;空字符串表示只列出别名、不给提示。 -- `force`:必须搭配 `default_model`,且不能与 `models` 表同用——表的意义在于提供选择,而 force 取消了选择。 -- `default_effort` 是节级设置:无论派生绑定到池中哪个条目(或 force 固定的模型)都生效。想按条目区分档位时不要设置它,改用下文的模型「变体」。 -- `primary` 是保留字(含义见下文),不能作为池中 key。 - -在交互式 TUI 中,也可以用 [`/secondary-model`](../reference/slash-commands.md) 命令(别名 `/subagent-model`)打开模型选择器:选择后写入 `default_model`(已有 models 表而所选别名不在其中时,会一并补一条空描述条目),之后派生的 subagent 立即按新默认值绑定,无需重启会话。 - -配置了模型池(显式的 `models` 表或隐式的单条目池)即启用模型选择:`Agent` / `AgentSwarm` 工具会获得 `model` 参数,工具描述中列出模型池(默认模型标注 `[default]`),main agent 可按次派生选择模型。池 key 只能引用已配置的 [`[models]`](#models) 条目——下面的 `kimi-code/*` 别名由 `/login` 自动提供: +`model` 之外的字段构成补丁:存在补丁字段时,运行时会在内存中合成一个派生模型条目(被指向条目的拷贝,补丁并入其 overrides 且补丁优先),子 Agent 实际绑定该派生条目;没有补丁字段时,子 Agent 直接绑定 `model` 指向的条目。派生条目只存在于内存中(不写回 `config.toml`),也不会出现在模型选择列表里。 ```toml [secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -[secondary_model.models] -"kimi-code/k3" = "难题选它。擅长复杂推理、算法设计、深度调试、数学和系统性难题。" -"kimi-code/kimi-for-coding-highspeed" = "速度快但单价较高。适合日常重构、代码解释、小改动、总结等看重响应速度的任务。" -"kimi-code/kimi-for-coding" = "均衡的编码主力。适合大多数功能开发和代码修改任务。" +model = "kimi-code/kimi-k2.5" +default_effort = "low" +max_output_size = 8192 ``` -派生时按以下顺序解析 subagent 的模型: +`model` / `default_effort` 可被环境变量 `KIMI_SECONDARY_MODEL` / `KIMI_SECONDARY_EFFORT` 覆盖,优先级均高于配置文件。 -1. 工具调用显式传入的 `model` -2. `default_model` - -`model` 参数的取值规则: - -- 接受池中任意别名,或 `"primary"`——调用方自己正在运行的模型,始终合法,即使不在池中。 -- `default_model` 与 `models` 都未配置时该参数不存在,subagent 继承调用方模型。 -- 绑定池中别名时不继承调用方的 Thinking 档位。本节设置了 `default_effort` 时以它为准;否则,`[thinking].enabled = false` 会保持关闭 Thinking;开启 Thinking 时,再依次使用所绑定模型条目的 `default_effort`、全局 `[thinking].effort`、所绑定模型 `support_efforts` 的中间项。 -- `"primary"` 则连模型带档位一起继承调用方。 -- 传入的值既不是池中别名也不是 `"primary"` 时,本次派生报错并列出可选值。 - -要收回 main agent 的选择权、让所有 subagent 固定跑同一个模型,加上 `force = true`: - -```toml -[secondary_model] -default_model = "kimi-code/kimi-for-coding-highspeed" -force = true -``` - -设置 `force` 后不再提供 `model` 参数(与完全未配置时一样),每次派生都绑定 `default_model`;显式传入 `model`(包括 `"primary"`)会报错。 - -### 为池内条目配置不同 Thinking 档位 - -绑定池中别名时,subagent 的 Thinking 档位会落到所绑定模型的默认 effort。利用这一点,可以为同一底层模型注册一个「变体」条目,让 main agent 选别名时同时选定档位: - -1. 在 [`[models]`](#models) 中为同一底层模型再注册一个条目,用 [`[models."<alias>".overrides]`](#模型覆盖项) 只覆盖 `default_effort`。 -2. 把原别名和变体别名都放进模型池。 - -```toml -# "kimi-code/k3" 由 /login 提供(默认 high 档);这里为同一模型注册一个 max 档位变体 -[models.k3-max] -provider = "managed:kimi-code" -model = "k3" -max_context_size = 1048576 -capabilities = [ "thinking", "always_thinking", "image_in", "video_in", "tool_use" ] -support_efforts = [ "low", "high", "max" ] - -[models.k3-max.overrides] -default_effort = "max" - -[secondary_model] -default_model = "kimi-code/k3" -[secondary_model.models] -"kimi-code/k3" = "默认 high 档位。适合大多数实现、分析和多轮交互任务。" -k3-max = "同一模型的 max Thinking 档位。适合最难的子任务。" -``` - -两个前提: - -- 底层模型必须声明了 `support_efforts`(`managed:kimi-code` 下目前只有 k3 系列声明了档位)。 -- 变体是独立条目,不会继承被指向条目的字段——`capabilities`、`support_efforts` 等元数据要完整照抄,否则 `default_effort` 不生效(它必须是 `support_efforts` 列表中的值)。 - -另外注意 main agent 与 subagent 的不对称:对 main agent,全局 `[thinking].effort` 一旦设置就压过变体的 `default_effort`;对绑定池内别名的 subagent,变体的 `default_effort` 优先于全局值,只有 `[secondary_model].default_effort` 的优先级更高。取值与回落规则同 [`[models]` 条目的 `default_effort`](#models)。 - -::: warning 注意 -配置错误一律直接报错,不做静默回退。出现以下情况时,会话的创建、恢复(resume)与 fork 都会在启动时失败: - -- `default_model` 缺失、不是池中 key,或池中 key 无法解析到已配置的 [`[models]`](#models) 条目; -- `force` 未搭配 `default_model`,或与 `models` 表同时使用。 -::: +实验功能启用后,会话启动时会校验该配置:`model` 无法解析,或 `default_effort` 不在(应用补丁后的)模型 effort 列表中时,会在启动时显示警告(并通过会话警告 API 返回)。该检查仅为提示——配置有误的次主力模型仍会在派生子 Agent 时失败,派生错误中同样附带配置来源提示。 ## `thinking` @@ -350,34 +275,21 @@ k3-max = "同一模型的 max Thinking 档位。适合最难的子任务。" | `kill_grace_period_ms` | `integer` | `5000` | 会话关闭、手动停止或任务超时请求正常终止后,等待任务自行结束的宽限时间(毫秒)。超过该时间仍在运行时,Kimi Code 会尝试强制停止该任务 | | `bash_auto_background_on_timeout` | `boolean` | `true` | 前台 `Bash` 命令触及超时时间时,将其转为后台任务而不是直接终止:命令完成时 agent 会收到通知,转入后台的命令受 `bash_task_timeout_s` 默认后台超时约束。设为 `false` 则恢复超时即终止的行为 | | `bash_task_timeout_s` | `integer` | `600` | 后台 `Bash` 任务在调用未传 `timeout` 时的默认超时(秒);前台命令超时转后台后也按此值重新计时。`0` 表示无超时——任务一直运行到自行结束或被模型手动停止。显式传入的 `timeout` 不受影响。在 print 模式(`kimi -p`)下未显式设置时默认为 `0` | -| `print_background_mode` | `"exit" \| "drain" \| "steer"` | `"steer"` | 仅 print 模式(`kimi -p`)生效,决定 main agent 的 turn 结束后如何处理未返回的后台任务:`"exit"` 立即退出;`"drain"` 退出前等待所有后台任务进入终态(结果不回馈给 main agent);`"steer"` 不退出,让后台任务完成时像后台 subagent 一样以合成 user 消息 steer main agent 进入新 turn,直到某 turn 结束时无未决后台任务或触及上限。设置后优先级高于 `keep_alive_on_exit` 的 print 回退 | +| `print_background_mode` | `"exit" \| "drain" \| "steer"` | `"steer"` | 仅 print 模式(`kimi -p`)生效,决定主 agent 的 turn 结束后如何处理未返回的后台任务:`"exit"` 立即退出;`"drain"` 退出前等待所有后台任务进入终态(结果不回馈给主 agent);`"steer"` 不退出,让后台任务完成时像后台子代理一样以合成 user 消息 steer 主 agent 进入新 turn,直到某 turn 结束时无未决后台任务或触及上限。设置后优先级高于 `keep_alive_on_exit` 的 print 回退 | | `print_wait_ceiling_s` | `integer` | `2147483` | print 模式(`kimi -p`)下,`print_background_mode` 为 `"drain"` 或 `"steer"` 时,等待/steer 循环的墙钟上限(秒;默认约 24.8 天,近似不设限)。在非 print 模式或 `"exit"` 时无效 | | `print_max_turns` | `integer` | `100000` | print 模式(`kimi -p`)且 `print_background_mode = "steer"` 时,允许由后台任务完成触发的新 turn 的最大数量,防止 steer 循环失控(默认值近似不设限) | `keep_alive_on_exit` 可被环境变量 `KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT` 覆盖,`max_running_tasks` 可被 `KIMI_CODE_BACKGROUND_MAX_RUNNING_TASKS` 覆盖,优先级均高于配置文件。 -在 print 模式(`kimi -p "<prompt>"`)下,只要还有未决的后台任务,Kimi Code 在 main agent 的 turn 结束后不会退出:每个任务完成都会以合成 user 消息回馈给 main agent,steer 出新的 turn(默认 `print_background_mode = "steer"`),直到某 turn 结束时没有任何未决任务才退出。该循环受 `print_wait_ceiling_s` 与 `print_max_turns` 约束,默认值都近似不设限。print 模式下后台工作也不会被墙钟超时杀掉:后台 `Bash` 任务默认无超时(`bash_task_timeout_s = 0`),subagent 默认无超时(`[subagent] timeout_ms` 与 `[swarm] timeout_ms` 未显式设置时均为 `0`),只有模型自己能停止任务。将 `print_background_mode` 设为 `"drain"` 可等待任务结束但不回馈结果,设为 `"exit"` 则在 main agent 结束后立即退出。 +在 print 模式(`kimi -p "<prompt>"`)下,只要还有未决的后台任务,Kimi Code 在主 agent 的 turn 结束后不会退出:每个任务完成都会以合成 user 消息回馈给主 agent,steer 出新的 turn(默认 `print_background_mode = "steer"`),直到某 turn 结束时没有任何未决任务才退出。该循环受 `print_wait_ceiling_s` 与 `print_max_turns` 约束,默认值都近似不设限。print 模式下后台工作也不会被墙钟超时杀掉:后台 `Bash` 任务默认无超时(`bash_task_timeout_s = 0`),子代理默认无超时(`[subagent] timeout_ms = 0`),只有模型自己能停止任务。将 `print_background_mode` 设为 `"drain"` 可等待任务结束但不回馈结果,设为 `"exit"` 则在主 agent 结束后立即退出。 ## `subagent` -`subagent` 控制 `Agent` 工具派生的 subagent 的运行方式。 - | 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | -| `timeout_ms` | `integer` | `7200000`(2 小时) | 单个 `Agent` subagent 允许运行的最长时间(毫秒)。超时后 subagent 以 `timed_out` 收尾。`0` 表示无超时——subagent 一直运行到自行结束或被模型手动停止。该值是后台任务管理器对每个 subagent 任务的 per-task timeout,因此对前台与后台 subagent 同时生效。在 print 模式(`kimi -p`)下未显式设置时默认为 `0`。注意:超过 `2147483647`(约 24.8 天)的值会被运行时钳到约 24.8 天 | - +| `timeout_ms` | `integer` | `7200000`(2 小时) | 单个子代理(`Agent` / `AgentSwarm`)允许运行的最长时间(毫秒)。超时后子代理以 `timed_out` 收尾。`0` 表示无超时——子代理一直运行到自行结束或被模型手动停止。该值是后台任务管理器对每个子代理任务的 per-task timeout,因此对前台与后台子代理同时生效。在 print 模式(`kimi -p`)下未显式设置时默认为 `0`。注意:超过 `2147483647`(约 24.8 天)的值会被运行时钳到约 24.8 天 | `timeout_ms` 可被环境变量 `KIMI_SUBAGENT_TIMEOUT_MS` 覆盖,优先级高于配置文件。 -## `swarm` - -`swarm` 控制 `AgentSwarm` 工具启动的 subagent 的运行方式,与 `[subagent]` 相互独立、互不影响。 - -| 字段 | 类型 | 默认值 | 说明 | -| --- | --- | --- | --- | -| `timeout_ms` | `integer` | `7200000`(2 小时) | `AgentSwarm` 启动的单个 subagent 允许运行的最长时间(毫秒)。超时后该 subagent 被中止,聚合报告中标记为失败(`Subagent timed out.`),其余 subagent 不受影响。`0` 表示无超时——subagent 一直运行到自行结束或被模型手动停止。在 print 模式(`kimi -p`)下未显式设置时默认为 `0`。注意:超过 `2147483647`(约 24.8 天)的值会被运行时钳到约 24.8 天 | - -`timeout_ms` 可被环境变量 `KIMI_CODE_SWARM_TIMEOUT_MS` 覆盖,优先级高于配置文件。 - ## `mcp` | 字段 | 类型 | 默认值 | 说明 | @@ -516,7 +428,6 @@ MCP server 的声明配置写在 `~/.kimi-code/mcp.json` 或项目内 `.kimi-cod | 字段 | 类型 | 默认值 | 说明 | | --- | --- | --- | --- | | `theme` | `string` | `auto` | 配色主题:`auto`(跟随终端)、`dark`、`light`,或[自定义主题](../customization/themes.md)的名字 | -| `render_latex` | `boolean` | `true` | 将 Markdown 消息中的 LaTeX 公式(`$…$`、`$$…$$`)渲染为 Unicode 文本;`false` 则保留原始源码 | | `disable_paste_burst` | `boolean` | `false` | 禁用非 bracketed paste 的粘贴突发兜底;默认开启,避免快速多行粘贴被逐行提交 | | `cache_expiry_hint` | `boolean` | `true` | resume 长时间未活动的会话、或长时间空闲后发送消息时,若上下文缓存可能已过期则弹出提醒,可选择先压缩或新建会话(仅 v2 引擎) | | `[editor].command` | `string` | `""` | 编写长输入用的外部编辑器命令;留空则回退到 `$VISUAL` / `$EDITOR` | @@ -529,7 +440,6 @@ MCP server 的声明配置写在 `~/.kimi-code/mcp.json` 或项目内 `.kimi-cod ```toml # ~/.kimi-code/tui.toml theme = "auto" # "auto" | "dark" | "light" | 自定义主题名 -render_latex = true # false 表示消息中的 LaTeX 公式保留原始源码 disable_paste_burst = false # true 表示禁用非 bracketed paste 的粘贴突发兜底 cache_expiry_hint = true # false 表示关闭 resume / 空闲提交时的"缓存已过期"提醒弹窗 diff --git a/docs/zh/configuration/data-locations.md b/docs/zh/configuration/data-locations.md index 302198278..5ab5aaa02 100644 --- a/docs/zh/configuration/data-locations.md +++ b/docs/zh/configuration/data-locations.md @@ -76,9 +76,9 @@ $KIMI_CODE_HOME (默认 ~/.kimi-code) - **`state.json`**:会话标题、`lastPrompt`、创建/更新时间、`forkedFrom` 等元数据。 - **`upcoming-goals.json`**:由 `/goal next <objective>` 创建的 TUI 专属队列。它不属于 Agent 对话;只有当前目标完成并提升后续目标后,才会进入 Agent 对话。 -- **`agents/main/wire.jsonl`**:main agent 的完整通信记录,用于会话恢复和回放。 +- **`agents/main/wire.jsonl`**:主 Agent 的完整通信记录,用于会话恢复和回放。 - **`agents/main/plans/`**:Plan 模式下写入的计划文件,按计划 id 命名(`<id>.md`)。 -- **`agents/agent-0/` 等**:subagent 实例目录,各自含 `wire.jsonl`。 +- **`agents/agent-0/` 等**:子 Agent 实例目录,各自含 `wire.jsonl`。 - **`logs/kimi-code.log`**:该会话的诊断日志,只有发生诊断事件时才存在。 - **`tasks/`**:后台任务持久化——`tasks/<task_id>.json` 保存状态/pid/退出码,`tasks/<task_id>/output.log` 保存输出。 - **`cron/`**:定时任务持久化,用 `kimi --session` 恢复会话时重新加载到调度器。详见[定时任务](../reference/tools.md#定时任务)。 diff --git a/docs/zh/configuration/env-vars.md b/docs/zh/configuration/env-vars.md index 4e9552262..8d44b7873 100644 --- a/docs/zh/configuration/env-vars.md +++ b/docs/zh/configuration/env-vars.md @@ -36,22 +36,6 @@ export KIMI_DISABLE_TELEMETRY=1 不修改 `config.toml` 临时切换模型——设置 `KIMI_MODEL_NAME` 后,CLI 在内存里合成一个临时供应商,重启后失效。详见[用环境变量定义模型](#用环境变量定义模型-kimi-model)。 -### `KIMI_CODE_CUSTOM_HEADERS` - -为所有出站的模型请求附加自定义 HTTP 请求头——LLM 聊天请求(所有供应商协议)和 `/models` 模型列表请求都会携带。适合网关按请求头路由的场景,例如指定集群: - -```sh -export KIMI_CODE_CUSTOM_HEADERS=$'X-Gateway-Cluster: my-cluster\nX-Custom-Tag: debug' -``` - -格式与 `ANTHROPIC_CUSTOM_HEADERS` 一致:由换行分隔的 `Name: Value` 行,键名和值两端的空白会被去除,不含冒号的行会被忽略。 - -::: info 新增 -新增于 0.20.2。 -::: - -> 优先级:Kimi 身份头(`User-Agent`、`X-Msh-*`)和 `config.toml` 里供应商的 `custom_headers`(见 [配置文件](./config-files.md#providers))会覆盖这里的同名条目。认证头的行为因协议而异:在 `kimi`、`openai`、`openai_responses` 协议上,`Authorization` 条目会替换生成的 bearer token;`/models` 列表请求始终使用自己的认证头。`authorization` 这类大小写变体不会被当作同名头——它会与真正的头合并,可能导致请求失败。不要用它设置认证等保留头。需要按供应商区分请求头时,请改用 `custom_headers`。 - ## 供应商凭证键(写在 config.toml 里) 下面这些键名不是直接从 shell 读取的——它们是写在 `config.toml` 的 `[providers.<name>.env]` 子表里、作为 `api_key` / `base_url` 备用来源的键名。CLI 只从配置文件读取,不从 `process.env` 读取。 @@ -137,26 +121,23 @@ kimi | 环境变量 | 用途 | 合法值 | | --- | --- | --- | | `KIMI_DISABLE_TELEMETRY` | 关闭匿名遥测上报 | `1`、`true`、`yes`、`y`(不区分大小写) | -| `KIMI_CODE_PASSWORD` | 为 `kimi web` 本地服务设置并列鉴权密码,与 bearer token 同时有效;把服务绑定到非本机地址时建议设置,见[本地服务与 API](../guides/server.md#鉴权) | 任意非空字符串;未设置时仅 token 有效 | | `KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT` | 会话关闭时是否保留后台任务,优先级高于 `config.toml`。默认会在退出时停止后台任务 | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | | `KIMI_CODE_BACKGROUND_MAX_RUNNING_TASKS` | 同时运行的后台任务数上限,优先级高于 `config.toml` 的 `[background] max_running_tasks`(不设置表示无上限) | 正整数;非法值被忽略 | | `KIMI_IMAGE_MAX_EDGE_PX` | 图片压缩的最长边上限(像素),优先级高于 `config.toml` 的 `[image] max_edge_px`(默认 `2000`) | 正整数;非法值被忽略 | | `KIMI_IMAGE_READ_BYTE_BUDGET` | 模型自行读图(`ReadMediaFile` 默认读取)的单图字节预算,优先级高于 `config.toml` 的 `[image] read_byte_budget`(默认 `262144`,即 256 KB) | 正整数;非法值被忽略 | | `KIMI_CODE_PLUGIN_MARKETPLACE_URL` | 覆盖 `/plugins` 加载的 plugin marketplace JSON,适合 dev loopback server、测试 CDN 文件或替换 marketplace 目录 | `https://code.kimi.com/kimi-code/plugins/marketplace.json`;也接受 `http://`、`file://` URL 和本地路径 | -| `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` | 限制 AgentSwarm 初始提升并发阶段可同时运行的 subagent 数量;不设置表示不限制 | 正整数;非法值会立即失败 | -| `KIMI_SUBAGENT_TIMEOUT_MS` | 单个 `Agent` subagent 可运行的最长时间(毫秒);优先级高于 `config.toml` 的 `[subagent] timeout_ms`(默认 `7200000`,即 2 小时) | 正整数;非法值回退到配置或默认值 | -| `KIMI_CODE_SWARM_TIMEOUT_MS` | 单个 `AgentSwarm` subagent 可运行的最长时间(毫秒);优先级高于 `config.toml` 的 `[swarm] timeout_ms`(默认 `7200000`,即 2 小时) | 正整数;非法值回退到配置或默认值 | +| `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` | 限制 AgentSwarm 初始提升并发阶段可同时运行的子 Agent 数量;不设置表示不限制 | 正整数;非法值会立即失败 | +| `KIMI_SUBAGENT_TIMEOUT_MS` | 单个子 Agent(`Agent` / `AgentSwarm`)可运行的最长时间(毫秒);优先级高于 `config.toml` 的 `[subagent] timeout_ms`(默认 `7200000`,即 2 小时) | 正整数;非法值回退到配置或默认值 | | `KIMI_CODE_IDENTITY_NAME` | Agent 在系统提示词中的自称,优先级高于 `config.toml` 的 `[identity] name`,且不会被写回配置文件 | 任意非空字符串;空值视为未设置 | | `KIMI_CODE_IDENTITY_SLUG` | 协议标识,用于发给第三方 provider 的 `User-Agent` 产品名和 MCP 客户端名,优先级高于 `[identity] slug`。未设置时由名称派生 | 任意非空字符串;会转小写并将连续非字母数字字符折叠为 `-` | | `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` | 是否向模型提供介绍 Kimi Code 自身的内置 Skills,优先级高于 `config.toml` 的 `builtin_product_skills`(默认开启) | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | -| `KIMI_CODE_TUI_FULL_SCREEN` | 启用实验性的 fullscreen alternate-screen 界面:可滚动的 transcript 视口、鼠标选择文本、可点击链接、Ctrl-Shift-F 搜索 | `1` 开启;其他值保持常规内联界面 | -| `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL` | 在包括交互式 TUI 在内的所有启动方式下启用实验性的[subagent 模型池](./config-files.md#subagent-模型池);master `KIMI_CODE_EXPERIMENTAL_FLAG=1` 也会启用本功能 | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | -| `KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK` | 在 `Agent` 和 `AgentSwarm` 工具上启用实验性的 `fork` 参数,让模型可以以调用方 Agent 对话历史的快照而不是空上下文启动 subagent;master `KIMI_CODE_EXPERIMENTAL_FLAG=1` 也会启用本功能 | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | +| `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL` | 在包括交互式 TUI 在内的所有启动方式下启用实验性的次主力模型功能;master `KIMI_CODE_EXPERIMENTAL_FLAG=1` 也会启用本功能 | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | +| `KIMI_SECONDARY_MODEL` | 次主力模型;优先级高于 `config.toml` 的 [`[secondary_model] model`](./config-files.md#secondary-model)。次主力模型实验功能启用后,新派生的子 Agent 默认绑定该模型,而不再继承主 Agent 的模型 | `[models]` 中已配置条目的别名,如 `kimi-code/kimi-k2.5`;空白值被忽略 | +| `KIMI_SECONDARY_EFFORT` | 次主力模型的 thinking effort;优先级高于 `config.toml` 的 `[secondary_model] default_effort`,仅在次主力模型及其实验功能均启用时生效 | effort 取值,如 `low`;空白值被忽略 | | `KIMI_MCP_STARTUP_TIMEOUT_MS` | 所有 MCP server 的全局默认连接超时(毫秒);优先级高于 `config.toml` 的 `[mcp] startup_timeout_ms`,但低于 `mcp.json` 中单个 server 的 `startupTimeoutMs`(默认 `30000`) | `1` 到 `2147483647` 的整数;非法值被忽略 | | `KIMI_MCP_TOOL_TIMEOUT_MS` | 所有 MCP server 的全局默认单次工具调用超时(毫秒);优先级高于 `config.toml` 的 `[mcp] tool_timeout_ms`,但低于 `mcp.json` 中单个 server 的 `toolTimeoutMs`(默认 `60000`) | `1` 到 `2147483647` 的整数;非法值被忽略 | | `KIMI_LOOP_MAX_STEPS_PER_TURN` | Agent 单轮最大步数;优先级高于 `config.toml` 的 `[loop_control] max_steps_per_turn`(不设或 `0` 表示无上限) | 非负整数;非法值被忽略 | | `KIMI_LOOP_MAX_ATTEMPTS_PER_STEP` | 单步失败后的最大总尝试次数(含首次尝试);优先级高于 `config.toml` 的 `[loop_control] max_attempts_per_step`(默认 `10`)。旧的 `KIMI_LOOP_MAX_RETRIES_PER_STEP` 已废弃,但在本变量未设置时仍生效并给出警告 | 非负整数;非法值被忽略 | -| `KIMI_CODE_INFINITE_RETRY` | 让所有失败的 LLM 请求无限重试(包括轮次内步骤和 compaction 等后台操作)而不是终止任务;重试等待按指数退避(32 秒封顶)并尊重服务端 `Retry-After` 头,等待期间中断仍立即生效。适用于端点可能短暂故障的长时间无人值守评测 | 真值:`1`/`true`/`yes`/`on`;假值:`0`/`false`/`no`/`off` | | `KIMI_TOKEN_COUNTING_STRATEGY` | 对外上报的上下文 token 计数(上下文大小显示);优先级高于 `config.toml` 的 `[token_counting] strategy`(默认 `measured+estimated`) | `measured+estimated`、`measured`、`estimated`(不区分大小写);非法值被忽略 | | `KIMI_WEB_SEARCH_BASE_URL` | 网页搜索(`WebSearch`)服务的 API URL;优先级高于 `config.toml` 的 `[services.moonshot_search] base_url`,未写配置段时也可启用服务。文件中持久化的凭据和自定义 header 不会发送到环境变量指定的端点 | 非空字符串;空白值被忽略 | | `KIMI_WEB_SEARCH_API_KEY` | 网页搜索(`WebSearch`)服务的 API 密钥;设置后同时替换配置中的 API 密钥和 OAuth 凭据 | 非空字符串;空白值被忽略 | @@ -173,7 +154,7 @@ kimi | `KIMI_CODE_NO_AUTO_UPDATE` | 完全禁用更新预检——不检查、不后台安装、不提示。同时兼容旧名 `KIMI_CLI_NO_AUTO_UPDATE` | 真值:`1`/`true`/`yes`/`on` | | `KIMI_DISABLE_CRON` | 禁用定时任务工具(`CronCreate` 拒绝新计划,已有任务不触发) | `1` 表示禁用 | -`KIMI_CODE_INFINITE_RETRY`、`KIMI_CODE_IDENTITY_*` 和 `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` 这几个变量由默认的 `agent-core-v2` 引擎读取。设置 `KIMI_CODE_LEGACY_FLAG=1` 后,旧版 `kimi` / `kimi -p` 路径会忽略它们。 +`KIMI_CODE_IDENTITY_*` 和 `KIMI_CODE_BUILTIN_PRODUCT_SKILLS` 这三个变量由默认的 `agent-core-v2` 引擎读取。设置 `KIMI_CODE_LEGACY_FLAG=1` 后,旧版 `kimi` / `kimi -p` 路径会忽略它们。 ## 诊断日志 diff --git a/docs/zh/customization/agents.md b/docs/zh/customization/agents.md index 4d3fe30fe..97d98de3e 100644 --- a/docs/zh/customization/agents.md +++ b/docs/zh/customization/agents.md @@ -1,47 +1,47 @@ -# Agent 与 subagent +# Agent 与子 Agent -Kimi Code CLI 中的每次会话都由一个**main agent** 驱动。main agent 理解用户意图、规划步骤、调用工具,并在需要时向外派发**subagent** 处理更聚焦的子任务——例如探索一个陌生代码库、并行审阅多处实现、或在不触碰主上下文的情况下规划一次大型重构。 +Kimi Code CLI 中的每次会话都由一个**主 Agent** 驱动。主 Agent 理解用户意图、规划步骤、调用工具,并在需要时向外派发**子 Agent** 处理更聚焦的子任务——例如探索一个陌生代码库、并行审阅多处实现、或在不触碰主上下文的情况下规划一次大型重构。 -subagent 接受 main agent 给出的任务描述,在自己的独立上下文里工作,最后把结论返回。它不会与用户直接对话,中间的思考和工具调用记录也不会混入 main agent 的历史。 +子 Agent 接受主 Agent 给出的任务描述,在自己的独立上下文里工作,最后把结论返回。它不会与用户直接对话,中间的思考和工具调用记录也不会混入主 Agent 的历史。 -## 内置 subagent +## 内置子 Agent -Kimi Code CLI 内置三种 subagent,开箱即用,分别面向不同任务形态: +Kimi Code CLI 内置三种子 Agent,开箱即用,分别面向不同任务形态: -- **`coder`**:默认 subagent,通用软件工程助手,可以读写文件、执行命令、搜索代码并落地具体改动。 +- **`coder`**:默认子 Agent,通用软件工程助手,可以读写文件、执行命令、搜索代码并落地具体改动。 - **`explore`**:代码库探索专用,只做只读操作,不修改任何文件。适合在不改动文件的前提下快速搜索、阅读和总结仓库。 - **`plan`**:实现规划与架构设计专用,连 Shell 命令都不提供,专注于"想清楚怎么做"而不是"动手做"。 -`coder` subagent 与 main agent 共享大部分工具集:可以在后台执行 Shell 命令、维护待办列表、进入 Plan 模式、调用 Agent Skills。内置 subagent 都不能继续派发新的 subagent。自定义 Agent 缺省时继承内置委派列表(`coder`、`explore`、`plan`),而这些内置类型自身同样不能再派发,因此委派链默认必然终止——不存在不受限的递归派发。自定义 Agent 可以通过显式声明 [`subagents`](#agent-文件格式) 列表来获得更深的委派链。如果 subagent 结束自己的轮次时仍有后台任务在运行,那么只有在这些后台任务全部落定后,这次运行才会回报完成——main agent 拿到结果时,背后的工作也已经真正完成。 +`coder` 子 Agent 与主 Agent 共享大部分工具集:可以在后台执行 Shell 命令、维护待办列表、进入 Plan 模式、调用 Agent Skills,也可以在任务自然拆解时继续派发自己的嵌套子 Agent。如果它结束自己的轮次时仍有后台任务在运行,那么只有在这些后台任务全部落定后,这次运行才会回报完成——主 Agent 拿到结果时,背后的工作也已经真正完成。 ## 调用方式 -subagent 由 main agent 自动调度——根据任务复杂度、上下文消耗和子任务的独立性,在适当时机派发,无需用户手动指定。 +子 Agent 由主 Agent 自动调度——根据任务复杂度、上下文消耗和子任务的独立性,在适当时机派发,无需用户手动指定。 -每次派发都会在终端以审批请求的形式呈现(除非命中 allow 规则或处于 YOLO 模式),方便你审视任务描述。你也可以在对话中直接指示 main agent 使用特定 subagent,例如"先用 explore 把相关文件梳理一遍再动手"。 +每次派发都会在终端以审批请求的形式呈现(除非命中 allow 规则或处于 YOLO 模式),方便你审视任务描述。你也可以在对话中直接指示主 Agent 使用特定子 Agent,例如"先用 explore 把相关文件梳理一遍再动手"。 -subagent 支持在后台运行:完成后结果自动回到 main agent,无需手动轮询。也可以唤回已有的 subagent 实例继续推进同一任务。 +子 Agent 支持在后台运行:完成后结果自动回到主 Agent,无需手动轮询。也可以唤回已有的子 Agent 实例继续推进同一任务。 ## 上下文隔离与资源开销 -每个 subagent 拥有完全独立的上下文窗口,只能看到 main agent 显式传入的任务描述,看不到 main agent 的对话历史。subagent 自己的中间思考和工具调用记录不会回流,只有最终结果会出现在 main agent 的上下文里。 +每个子 Agent 拥有完全独立的上下文窗口,只能看到主 Agent 显式传入的任务描述,看不到主 Agent 的对话历史。子 Agent 自己的中间思考和工具调用记录不会回流,只有最终结果会出现在主 Agent 的上下文里。 这种隔离带来两个好处: -- **main agent 上下文保持精炼**,长会话中不会被大量探索性日志撑满。 -- **多个 subagent 可以并行运行**,互不干扰。 +- **主 Agent 上下文保持精炼**,长会话中不会被大量探索性日志撑满。 +- **多个子 Agent 可以并行运行**,互不干扰。 -需要注意的是,每个 subagent 都会独立消耗模型 token。简单任务没有必要派发 subagent,main agent 直接处理更经济。 +需要注意的是,每个子 Agent 都会独立消耗模型 token。简单任务没有必要派发子 Agent,主 Agent 直接处理更经济。 ## 权限继承 -subagent 的权限规则继承自 main agent:main agent 通过 `/permission` 或在审批中接受的"始终允许"规则,会自动覆盖到它派发出的所有 subagent,subagent 不需要重新审批同类工具调用。`Agent` 工具本身默认放行,因此 main agent 可以在不打断用户的前提下完成多次委派。 +子 Agent 的权限规则继承自主 Agent:主 Agent 通过 `/permission` 或在审批中接受的"始终允许"规则,会自动覆盖到它派发出的所有子 Agent,子 Agent 不需要重新审批同类工具调用。`Agent` 工具本身默认放行,因此主 Agent 可以在不打断用户的前提下完成多次委派。 -如果需要某类工具在 subagent 中始终不可用,应收紧 main agent 的权限规则。 +如果需要某类工具在子 Agent 中始终不可用,应收紧主 Agent 的权限规则。 ## 自定义 Agent -除了三个内置 subagent,你还可以用 Markdown 文件定义自己的 Agent。每个文件描述一个 Agent:文件顶部的 Frontmatter(YAML 元数据)声明名称、描述和工具权限,文件正文是它的系统提示词。自定义 Agent 可以作为 subagent 被委派 —— main agent 会自动发现它们,与内置 subagent 并列 —— 也可以在启动时选为 main agent。 +除了三个内置子 Agent,你还可以用 Markdown 文件定义自己的 Agent。每个文件描述一个 Agent:文件顶部的 Frontmatter(YAML 元数据)声明名称、描述和工具权限,文件正文是它的系统提示词。自定义 Agent 可以作为子 Agent 被委派 —— 主 Agent 会自动发现它们,与内置子 Agent 并列 —— 也可以在启动时选为主 Agent。 ### Agent 目录 @@ -65,10 +65,10 @@ extra_agent_dirs = ["~/team-agents", ".agents/team-agents"] **Plugin 级**:已启用 plugin 在其 manifest 的 `agents` 字段中声明的目录(省略时自动采用 plugin 根下的 `agents/` 目录),见[插件 Agent](./plugins.md#插件-agent)。Plugin Agent 优先级仅高于内置 Agent。 -**内置 Agent** 随 CLI 分发,优先级最低。目录中发现的文件不会仅凭同名覆盖内置 Agent;如确需替换,必须在 Frontmatter 中声明 `override: true`。通过 `--agent-file` 加载的文件视为显式启动意图,可以覆盖同名内置 Agent,优先级高于所有目录作用域,且仅对本次启动生效。另外,`$KIMI_CODE_HOME/SYSTEM.md` 可永久覆盖默认 main agent 的系统提示词(它不参与 Agent 文件发现),其优先级交互见下文 SYSTEM.md 小节。 +**内置 Agent** 随 CLI 分发,优先级最低。目录中发现的文件不会仅凭同名覆盖内置 Agent;如确需替换,必须在 Frontmatter 中声明 `override: true`。通过 `--agent-file` 加载的文件视为显式启动意图,可以覆盖同名内置 Agent,优先级高于所有目录作用域,且仅对本次启动生效。另外,`$KIMI_CODE_HOME/SYSTEM.md` 可永久覆盖默认主 Agent 的系统提示词(它不参与 Agent 文件发现),其优先级交互见下文 SYSTEM.md 小节。 ::: warning 信任模型 -Agent 文件属于提示词配置,而项目级文件来自仓库本身 —— 包括你刚刚 clone、尚不可信的仓库。项目作用域的文件可以完全接管内置 Agent:命名为 `agent.md` 并声明 `override: true` 会替换**默认 main agent 的整个系统提示词**,`coder.md` 加 `override: true` 则会替换默认 subagent 类型。与 `AGENTS.md` 内容(作为参考资料注入提示词)不同,override 文件**就是**系统提示词本身,且不写 `tools` 的文件保留全部工具。在不熟悉的仓库中运行 Kimi Code 之前,请以对待脚本同样的谨慎检查其中的 `.kimi-code/agents/` 与 `.agents/agents/` 目录。 +Agent 文件属于提示词配置,而项目级文件来自仓库本身 —— 包括你刚刚 clone、尚不可信的仓库。项目作用域的文件可以完全接管内置 Agent:命名为 `agent.md` 并声明 `override: true` 会替换**默认主 Agent 的整个系统提示词**,`coder.md` 加 `override: true` 则会替换默认子 Agent 类型。与 `AGENTS.md` 内容(作为参考资料注入提示词)不同,override 文件**就是**系统提示词本身,且不写 `tools` 的文件保留全部工具。在不熟悉的仓库中运行 Kimi Code 之前,请以对待脚本同样的谨慎检查其中的 `.kimi-code/agents/` 与 `.agents/agents/` 目录。 ::: ### Agent 文件格式 @@ -81,6 +81,7 @@ name: reviewer description: 严格的代码审查 Agent,按严重度分级报告问题 whenToUse: 代码评审与 PR 检查 override: false +model_preference: primary tools: - Read - Grep @@ -96,12 +97,13 @@ disallowedTools: | 字段 | 必填 | 说明 | | --- | --- | --- | | `name` | 否 | kebab-case 唯一标识。缺省时取文件名(去掉扩展名,如 `review.md` → `review`);解析后名字缺失或不是 kebab-case 的文件会被跳过并告警 | -| `description` | 是 | Agent 的用途。main agent 挑选 subagent 时会看到,请围绕委派决策来写 | +| `description` | 是 | Agent 的用途。主 Agent 挑选子 Agent 时会看到,请围绕委派决策来写 | | `whenToUse` | 否 | 补充说明何时应使用该 Agent | | `override` | 否 | 是否允许覆盖同名内置 Agent,默认 `false`。`--agent-file` 属于显式启动意图,无需设置此字段 | +| `model_preference` | 否 | `Agent` 或 `AgentSwarm` 启动该 profile 时的符号默认值:`primary` 选择调用方当前运行的模型,`secondary` 选择 [`[secondary_model] model`](../configuration/config-files.md#secondary-model)。工具调用显式传入的 `model`(同样只接受 `"primary"` / `"secondary"` 两个符号值)优先于该字段;两者均未设置时,已配置的次主力模型仍为默认值。未配置次主力模型时,子 Agent 继承调用方模型 | | `tools` | 否 | 工具名允许列表,如 `Read`、`Bash`;MCP 工具用 glob 匹配,如 `mcp__github__*`。支持 YAML 列表或逗号分隔字符串(`tools: Read, Grep`)两种写法。缺省表示允许全部工具;单独的 `*` 同样表示允许全部工具;空列表(`tools: []`)表示禁用全部工具 | | `disallowedTools` | 否 | 禁止列表,写法与匹配规则相同,在 `tools` 之后应用 | -| `subagents` | 否 | 允许委派的 subagent 名称列表,写法与 `tools` 相同(YAML 列表或逗号分隔字符串)。缺省表示继承默认 Agent 的委派列表(内置默认为 `coder`、`explore`、`plan`,它们自身都不能再派发,因此继承得到的链路必然终止);单独的 `*` 表示可委派所有类型。main agent 的有效委派列表还会自动并入所有发现的自定义 Agent,因此自定义 Agent 默认即可被委派 | +| `subagents` | 否 | 允许委派的子 Agent 名称列表,写法与 `tools` 相同(YAML 列表或逗号分隔字符串)。缺省表示可委派所有类型;单独的 `*` 同样表示全部 | 内置工具与用户工具按名称精确匹配(区分大小写);以 `mcp__` 开头的条目按 glob 匹配 MCP 工具。有三种写法永远匹配不到任何工具,在 profile 生效时会给出警告:`mcp__` 模式之外使用通配符(`disallowedTools` 里单独的 `*` 什么也禁不掉);不是完整 `mcp__<服务器>__<工具>` 形式的 `mcp__` 字面量(`mcp__github` 匹配不到任何工具 —— 匹配整个服务器要用 `mcp__github__*`);以及任何已注册或内置工具都没有的名字(通常是笔误,如把 `Read` 写成 `read`)。 @@ -109,19 +111,21 @@ disallowedTools: 未知字段会被忽略,新版本写的文件在旧版本上仍可读取。其他 Agent 工具的字段(如 Claude Code 的 `model`、OpenCode 的 `mode`)同样会被忽略;加上 `tools` 的逗号分隔写法和 `name` 缺省回退到文件名,Claude Code 与 OpenCode 风格的 Agent 文件一般可直接加载 —— 只含 `description` 和正文的最小文件可跨工具通用。 +`model_preference` 仅在次主力模型实验功能启用时对新启动的子 Agent 生效——设置 `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`,或 master `KIMI_CODE_EXPERIMENTAL_FLAG=1`。它在包括交互式 TUI 在内的所有启动方式下生效。该字段不用于填写具体模型 alias,已恢复的子 Agent 也会保持原模型。主 Agent 会在 profile 描述中看到这项偏好,因此仍可在某项任务需要不同选择时显式传入 `model`。 + 目录中发现的非法文件会被跳过并告警,不影响其他文件。通过 `--agent-file` 显式传入的文件必须合法 —— 否则 CLI 会报错并退出。 ::: warning 注意 -`tools` 与 `disallowedTools` 不仅决定模型能"看到"哪些工具,还会在执行前再次强制检查。`subagents` 同样双重生效:`Agent` 工具的类型列表只包含允许委派的 subagent,`Agent` 与 `AgentSwarm` 在实际派发前都会强制校验;唤回已有 subagent 不受此限制。权限规则仍是独立的控制层,用于决定哪些操作需要审批。 +`tools` 与 `disallowedTools` 不仅决定模型能"看到"哪些工具,还会在执行前再次强制检查。`subagents` 同样双重生效:`Agent` 工具的类型列表只包含允许委派的子 Agent,`Agent` 与 `AgentSwarm` 在实际派发前都会强制校验;唤回已有子 Agent 不受此限制。权限规则仍是独立的控制层,用于决定哪些操作需要审批。 ::: -作为 subagent 委派的自定义 Agent 不会携带内置 subagent 的角色框架("你的最后一条消息就是完整交付")。如果编写的 Agent 用于委派,请在正文中说明:其最后一条消息应当是交付给调用方的完整、自包含的结果。 +作为子 Agent 委派的自定义 Agent 不会携带内置子 Agent 的角色框架("你的最后一条消息就是完整交付")。如果编写的 Agent 用于委派,请在正文中说明:其最后一条消息应当是交付给调用方的完整、自包含的结果。 -### 选择 main agent +### 选择主 Agent 两个 CLI flag 用于选择驱动新会话的 Agent,在 print 模式(`kimi -p`)和交互式 TUI 中均可使用: -- **`--agent <name>`**:以指定 Agent 作为 main agent 启动会话。名称可以指向内置 Agent 或任何已发现的文件;名称不存在时会报错,并列出可用的 Agent。 +- **`--agent <name>`**:以指定 Agent 作为主 Agent 启动会话。名称可以指向内置 Agent 或任何已发现的文件;名称不存在时会报错,并列出可用的 Agent。 - **`--agent-file <path>`**:以最高优先级加载一个 Agent 文件(仅本次启动)并以其启动。该 flag 只接受一个文件:不可重复传入,也不能与 `--agent` 同时使用。 两个 flag 都仅在新建会话时有效——都不能与 `--session`/`--continue` 组合。Agent 在会话创建时绑定,恢复会话时会自动还原已绑定的 Agent,因此恢复时不需要(也不允许)携带这些 flag。 @@ -135,11 +139,11 @@ kimi -p --agent reviewer "审查这个分支上的改动" 绑定的 Agent 即会话的身份:在会话首次绑定后即固定,之后不可切换。在 TUI 中,这些 flag 只绑定启动时的会话;之后在同一进程内新建的会话(例如通过 `/new`)使用默认 Agent。 -定制 main agent 时,在正文中引用 `${base_prompt}` 可保持有效默认提示词中已有的环境、工作区指令、Skill 和 plugin 注入生效。如果要替换默认提示词、但只保留 plugin 提供的指令,请改用 `${plugin_sections}`。正文同时不引用 `${base_prompt}` 和 `${plugin_sections}` 时,会完全拥有自己的提示词并排除 plugin 指令,适合自包含的 subagent。 +定制主 Agent 时,在正文中引用 `${base_prompt}` 可保持有效默认提示词中已有的环境、工作区指令、Skill 和 plugin 注入生效。如果要替换默认提示词、但只保留 plugin 提供的指令,请改用 `${plugin_sections}`。正文同时不引用 `${base_prompt}` 和 `${plugin_sections}` 时,会完全拥有自己的提示词并排除 plugin 指令,适合自包含的子 Agent。 -### 用 SYSTEM.md 覆盖 main agent 的系统提示词 +### 用 SYSTEM.md 覆盖主 Agent 的系统提示词 -希望永久覆盖 main agent 的系统提示词、而不必每次启动都传入 `--agent` 或 `--agent-file` 时,可以写一份 `$KIMI_CODE_HOME/SYSTEM.md`(默认:`~/.kimi-code/SYSTEM.md`,随 `KIMI_CODE_HOME` 移动)。文件存在且非空期间,它整体替换内置默认 main agent 的系统提示词——但只替换提示词,描述、工具集与允许委派的 subagent 列表仍沿用内置默认值。SYSTEM.md 在包括交互式 TUI 会话在内的所有启动方式下生效。 +希望永久覆盖主 Agent 的系统提示词、而不必每次启动都传入 `--agent` 或 `--agent-file` 时,可以写一份 `$KIMI_CODE_HOME/SYSTEM.md`(默认:`~/.kimi-code/SYSTEM.md`,随 `KIMI_CODE_HOME` 移动)。文件存在且非空期间,它整体替换内置默认主 Agent 的系统提示词——但只替换提示词,描述、工具集与允许委派的子 Agent 列表仍沿用内置默认值。SYSTEM.md 在包括交互式 TUI 会话在内的所有启动方式下生效。 SYSTEM.md 是纯 Markdown 正文,不需要也不读取 Frontmatter。文件缺失或为空时不生效;读取失败时会告警并回退到内置提示词。优先级上,显式意图仍然胜出:项目作用域中声明了 `override: true` 的同名 Agent 文件、通过 `--agent-file` 传入的文件都排在 SYSTEM.md 之前,用 `--agent` 选择其他 Agent 时 SYSTEM.md 也不会生效;而在用户作用域内部,SYSTEM.md 优先于 `agents/` 目录中扫描到的同名文件。 @@ -176,7 +180,7 @@ ${plugin_sections} ## 会话目录中的存储位置 -subagent 的运行状态持久化到当前会话目录的 `agents/` 子目录下,每个 subagent 实例对应一个独立目录,其中包含按时间顺序记录提示词、消息历史与最终状态的 `wire.jsonl` 文件。后台 subagent 还会通过 `tasks/` 子目录暴露生命周期状态。 +子 Agent 的运行状态持久化到当前会话目录的 `agents/` 子目录下,每个子 Agent 实例对应一个独立目录,其中包含按时间顺序记录提示词、消息历史与最终状态的 `wire.jsonl` 文件。后台子 Agent 还会通过 `tasks/` 子目录暴露生命周期状态。 ::: warning 注意 会话目录、wire 文件和任务记录都属于本地调试材料,可能包含用户 prompt、命令输出、仓库路径、工具返回内容或凭证痕迹。不要把这些文件直接提交到公开仓库、issue 或聊天记录里;如确需分享,请先脱敏。 @@ -184,5 +188,5 @@ subagent 的运行状态持久化到当前会话目录的 `agents/` 子目录下 ## 下一步 -- [Hooks](./hooks.md) — 在 subagent 完成等关键节点触发本地脚本通知或拦截 -- [Agent Skills](./skills.md) — 给 subagent 注入专业知识和工作流程 +- [Hooks](./hooks.md) — 在子 Agent 完成等关键节点触发本地脚本通知或拦截 +- [Agent Skills](./skills.md) — 给子 Agent 注入专业知识和工作流程 diff --git a/docs/zh/customization/hooks.md b/docs/zh/customization/hooks.md index b23ec9143..93c220673 100644 --- a/docs/zh/customization/hooks.md +++ b/docs/zh/customization/hooks.md @@ -112,8 +112,8 @@ Hook 命令的工作目录是当前会话的项目目录。非 Windows 平台上 | `SessionStart` | `startup` 或 `resume` | — | 新会话启动或历史会话恢复后触发;payload 含 `source`、`model` 和 `profile` | | `SessionEnd` | `exit` 或 `archive` | — | 会话关闭后触发;`archive` 表示会话被归档而非退出 | | `SessionHeartbeat` | 空字符串 | — | 会话存活期间每 60 秒触发一次;仅当配置了本事件时计时器才会运行。payload 含 `uptime_ms`(观察用) | -| `SubagentStart` | subagent 名称 | — | subagent 开始运行前触发 | -| `SubagentStop` | subagent 名称 | — | subagent 成功完成后触发(观察用) | +| `SubagentStart` | 子 Agent 名称 | — | 子 Agent 开始运行前触发 | +| `SubagentStop` | 子 Agent 名称 | — | 子 Agent 成功完成后触发(观察用) | | `TaskStarted` | 任务类型(`agent`、`process` 或 `question`) | — | 后台任务启动时触发;payload 含 `task_id`、`description` 和 `detached`(观察用) | | `StopFailure` | 错误类型 | — | 本轮因错误失败后触发(观察用) | | `Interrupt` | 空字符串 | — | 用户中断本轮时触发(例如按下 Esc);超时或其他程序性中断不会触发。中断时 `Stop` 不会触发,由本事件替代。payload 含 `reason` 字段(观察用) | @@ -160,4 +160,4 @@ process.stdin.on('end', () => { ## 下一步 - [配置](#配置) — `[[hooks]]` 在 `config.toml` 中的完整字段声明 -- [Agent 与 subagent](./agents.md) — 利用 `SubagentStop` 事件在 subagent 完成后触发通知 +- [Agent 与子 Agent](./agents.md) — 利用 `SubagentStop` 事件在子 Agent 完成后触发通知 diff --git a/docs/zh/customization/mcp.md b/docs/zh/customization/mcp.md index 0bd78a2bf..bfc6fd4bb 100644 --- a/docs/zh/customization/mcp.md +++ b/docs/zh/customization/mcp.md @@ -23,8 +23,6 @@ MCP server 配置写在 `mcp.json` 中,分两层: 从配置中删除某个 server 不会打断进行中的会话:该 server 在 `/mcp` 中仍显示为 `removed`,其工具在这些会话中保持可见,但调用会失败并返回移除提示;新会话则完全不会注册这些工具。反过来,会话进行中新增的 server——无论是编辑 `mcp.json` 还是安装 plugin——都不会注册到已打开的会话中,只会加入之后创建的会话。 -当 Kimi Code 在不受信任的文件夹中发现项目级 MCP server 时,工作区信任提示会显示每个 server 的传输方式和启动目标。提示默认选中 `Don't trust`;请先移动到 `Trust this folder`,核对列出的命令与参数或远程 URL 后,再确认信任。信任文件夹后,该工作区的项目级 MCP server 才会启用。 - `mcp.json` 的结构: ```json @@ -65,7 +63,7 @@ MCP server 配置写在 `mcp.json` 中,分两层: HTTP 与 SSE server 支持通过 `headers` 或 `bearerTokenEnvVar` 提供静态凭证。需要 OAuth 时,运行 `/mcp-config login <server-name>` 完成浏览器授权。 -Plugins 也可以在 manifest 中声明 MCP servers。Plugin 声明的 servers 默认启用,可以在 `/plugins` 中禁用或重新启用:禁用或移除后,已打开会话中的工具调用会失败并返回移除提示;新增或启用 server 会立即连接到已打开的会话。详见 [Plugins](./plugins.md#plugin-中的-mcp-servers)。 +Plugins 也可以在 manifest 中声明 MCP servers。Plugin 声明的 servers 默认启用,可以在 `/plugins` 中禁用或重新启用:禁用或移除后,已打开会话中的工具调用会失败并返回移除提示;新增或启用 server 则在新会话或 `/reload` 后生效。详见 [Plugins](./plugins.md#plugin-中的-mcp-servers)。 ::: warning 注意 项目级 `.kimi-code/mcp.json` 中的 stdio 条目会在会话启动时执行本地命令,只在你信任的仓库里启用。 diff --git a/docs/zh/customization/plugins.md b/docs/zh/customization/plugins.md index 2163ce1ae..aa46a04b4 100644 --- a/docs/zh/customization/plugins.md +++ b/docs/zh/customization/plugins.md @@ -79,7 +79,7 @@ Plugins 把可复用的 Kimi Code CLI 能力打包成可安装单元——可以 官方插件是 Kimi 官方维护的 plugin 和内置产品能力,目前有以下三种: -- **[Kimi Datasource](#kimi-datasource)**:用自然语言查询金融行情、财经资讯、宏观经济、企业工商、学术文献、法律法规和国际组织官方数据 +- **[Kimi Datasource](#kimi-datasource)**:用自然语言查询金融行情、宏观经济、企业工商、学术文献和法律法规 - **[Kimi WebBridge](#kimi-webbridge)**:让 AI 直接操控你自己的浏览器,完成各类网页操作 - **[Kimi Computer Use](#kimi-computer-use)**:让 AI 操作你的桌面应用(macOS 和 Windows) @@ -97,11 +97,9 @@ Kimi WebBridge 分两步安装:完成上述步骤后,还需要[安装浏览 官方插件更新后会在使用旧版时提示更新,不会自动更新,要升级到新版本,重复上述安装步骤即可。 -### Kimi Datasource <Badge type="tip" text="v3.4.0" /> +### Kimi Datasource <Badge type="tip" text="v3.3.0" /> -Kimi Datasource 是 Kimi Code 官方数据插件,让你用自然语言直接查询金融行情、财经资讯、宏观经济、企业工商、学术文献、中国法律法规和国际组织官方数据,无需手动调用接口或申请数据账号。 - -数据来源包括世界银行、IMF、OECD、FRED、WHO、FAO、国家统计局、Wind、S&P Capital IQ、SEC EDGAR、财新、新华财经、恒生聚源等权威机构与知名数据库,信源可溯源。 +Kimi Datasource 是 Kimi Code 官方数据插件,让你用自然语言直接查询金融行情、宏观经济、企业工商、学术文献和中国法律法规,无需手动调用接口或申请数据账号。 使用前需先通过 `/login` 完成 Kimi Code 账号 OAuth 登录,数据查询会消耗你的 Kimi Code 套餐额度。 @@ -112,49 +110,27 @@ Kimi Datasource 是 Kimi Code 官方数据插件,让你用自然语言直接 #### 能做什么 -::: details **实时量化研究** — 想盯着茅台做个量化分析? -一句话拉取近三年的每日收盘价、MACD 和 KDJ 信号,直接出结论,不用找第三方数据平台。 -::: +**实时量化研究**:盯着茅台想做个量化分析?一句话拉取近三年的每日收盘价、MACD 和 KDJ 信号,直接出结论,不用找第三方数据平台。 -::: details **跨国宏观对比** — 研究中印越产业转移? -基于世界银行 50 年历史数据,一次查询拿到三国 GDP 增速、贸易额、人口结构的完整时间序列对比。 -::: +**跨国宏观对比**:研究中印越产业转移?基于世界银行 50 年历史数据,一次查询拿到三国 GDP 增速、贸易额、人口结构的完整时间序列对比。 -::: details **合同前风险排查** — 签合同前五分钟才想起来查对方背景? -输入公司名,立刻拿到工商注册信息、股权穿透、司法纠纷和失信记录,当场决策。 -::: +**合同前风险排查**:签合同前五分钟才想起来要查对方背景?输入公司名,立刻拿到工商注册信息、股权穿透、司法纠纷和失信记录,当场决策。 -::: details **文献综述加速** — 写论文要梳理 RLHF 领域的研究脉络? -直接列出高引论文、主要作者和核心结论,综述提纲半小时内成型。 -::: +**文献综述加速**:写论文要梳理 RLHF 领域的研究脉络?直接列出高引论文、主要作者和核心结论,综述提纲半小时内成型。 -::: details **法律条文速查** — 碰上居住权合同纠纷想确认法条? -一句话定位《民法典》相关条文原文、效力级别和时效性,再顺手拉几个相近判例佐证,不用翻法规库。 -::: +**法律条文速查**:碰上居住权的合同纠纷,拿不准法条?一句话定位《民法典》相关条文原文、效力级别和时效性,再顺手拉几个相近判例佐证,不用翻法规库。 -::: details **机构级美股研究** — 要写一份美股深度报告? -一句话拉出年报原文、标准化财务指标、前 50 大股东和分析师一致预期,不用在多个数据终端之间来回切。 -::: - -::: details **财经资讯与行业数据** — 想追市场热点或政策动向? -直接查询财新的市场资讯、债券基金期货数据与上市公司产业链关系,以及新华财经国家金融信息平台的资讯、政策、公告与市场快讯,信源权威可溯源。 -::: - -::: details **标准查询** — 查合规要对照国标? -按标准号或主题查询国标、行标、地标和团标的编号、状态与全文入口。 -::: +**机构级美股研究**:写美股深度报告?一句话拉出年报原文、标准化财务指标、前 50 大股东和分析师一致预期,不用在多个数据终端之间来回切。 #### 数据覆盖 | 类别 | 覆盖范围 | |---|---| | 股票与金融市场 | Wind、S&P Capital IQ、SEC EDGAR 等知名数据库,能力涵盖 A 股、港股、美股等主要市场的行情、技术指标、财报估值、分析师预期,以及 8,000+ 美股上市公司的官方披露文件 | -| 财经资讯与行业数据 | 财新、新华财经等知名数据平台,能力涵盖市场资讯与快讯、上市公司公告、监管政策、债券基金期货数据、企业失信记录、上市公司产业链关系 | -| 宏观经济 | 世界银行、IMF、OECD、FRED、国家统计局等知名数据库及 WHO、FAO 等国际组织官方统计,能力涵盖全球 189 个国家 50 年以上时间序列与中国全国/省/市指标:GDP、贸易、人口、汇率、CPI、国际收支、GDP 预测等 | -| 中国标准 | 国家标准(GB)、行业标准、地方标准和团体标准的编号、名称、发布状态与详情,部分国标和公开团标提供官方全文入口 | +| 宏观经济 | 世界银行、IMF 等知名数据库,能力涵盖全球 189 个国家 50 年以上的时间序列:GDP、贸易、人口、汇率、CPI、国际收支、GDP 预测等 | | 企业数据 | 中国大陆境内企业工商信息、股权穿透、司法风险、关联图谱 | | 学术文献 | 物理、数学、计算机、金融、经济等领域百万量级论文,支持预印本查询 | -| 法律法规 | 元典智库等知名法律数据库,能力涵盖中国法律法规与司法案例:各效力层次的法规检索与详情,普通及权威判例检索 | +| 法律法规 | 中国法律法规与司法案例:各效力层次的法规检索与详情,普通及权威判例检索 | | 智能筛选 | 恒生聚源等知名数据库,能力涵盖自然语言选股、选基金、选基金经理,以及宏观行业数据、研报、公告与新闻 | #### 计费与限制 @@ -278,7 +254,7 @@ Plugin 是一个带 manifest 的目录或 zip 文件。Manifest 可以放在以 | `interface` | 在 `/plugins` 中展示的字段:`displayName`、`shortDescription`、`longDescription`、`developerName`、`websiteURL` | | `skills` | 一个或多个 `./` 路径,必须位于 plugin 根目录内。省略时根目录的 `SKILL.md` 被当作单个 Skill root | | `agents` | 一个或多个 `./` 路径,必须位于 plugin 根目录内,指向含有 [Agent 文件](./agents.md#自定义-agent)的目录。省略时根下的 `agents/` 目录(若存在)被自动采用 | -| `sessionStart.skill` | 在新会话或恢复会话开始时,把指定 plugin Skill 加载到 main agent | +| `sessionStart.skill` | 在新会话或恢复会话开始时,把指定 plugin Skill 加载到主 Agent | | `skillInstructions` | 每次加载此 plugin 的 Skill 时一并附带的额外说明 | | `systemPrompt` | plugin 启用期间提供给 Agent 系统提示词的内联指令 | | `systemPromptPath` | 指向 UTF-8 文本文件的 `./` 路径;同时设置 `systemPrompt` 时,文件内容拼接在内联指令之后 | @@ -305,7 +281,7 @@ Plugin 是一个带 manifest 的目录或 zip 文件。Manifest 可以放在以 新会话和新建 Agent 会读取当前已启用 plugin 的指令。正在进行的请求会继续使用已有的系统提示词。`/plugins reload` 会刷新 plugin Skill 列表,并请求重建活跃 Agent 的提示词;如果需要让变更在下一轮前明确收敛,请使用这个命令。在 v2 引擎中,安装、启用、禁用或移除 plugin 会立即更新 catalog,后续的提示词重建(例如压缩上下文或修改工具策略后)可能会读取新的指令。legacy 引擎会让每个活跃 session 保留自己的 plugin 快照,直到 `/plugins reload` 或创建新 session。从磁盘恢复的 session 会先使用持久化的提示词,后续重建再遵循对应引擎的行为。切换 plugin 的 MCP server 不会改变系统提示词指令。 -内置 Agent 提示词会自动包含已启用 plugin 的指令。自定义 `SYSTEM.md` 或 Agent 文件完全拥有自己的模板,因此应在希望出现 plugin 指令的位置加入 `${plugin_sections}`。如果自定义模板包含 `${base_prompt}`,且该有效默认提示词已经包含 plugin 块,就不要再重复加入 `${plugin_sections}`。完整变量表见 [自定义 Agent 与 SYSTEM.md](./agents.md#用-system-md-覆盖-main-agent-的系统提示词)。 +内置 Agent 提示词会自动包含已启用 plugin 的指令。自定义 `SYSTEM.md` 或 Agent 文件完全拥有自己的模板,因此应在希望出现 plugin 指令的位置加入 `${plugin_sections}`。如果自定义模板包含 `${base_prompt}`,且该有效默认提示词已经包含 plugin 块,就不要再重复加入 `${plugin_sections}`。完整变量表见 [自定义 Agent 与 SYSTEM.md](./agents.md#用-system-md-覆盖主-agent-的系统提示词)。 ## 插件斜杠命令 @@ -383,13 +359,13 @@ my-plugin/ SKILL.md ``` -`sessionStart.skill` 在会话启动时把一个 plugin Skill 加载到 main agent,适合放置初始化说明、工作流规则,或把其他工具中的术语映射到 Kimi Code CLI。它只注入文本,不执行代码。 +`sessionStart.skill` 在会话启动时把一个 plugin Skill 加载到主 Agent,适合放置初始化说明、工作流规则,或把其他工具中的术语映射到 Kimi Code CLI。它只注入文本,不执行代码。 无论 Skill 通过哪种方式加载(`sessionStart.skill`、`/skill:<name>` 或模型自动调用),`skillInstructions` 都会随该 plugin 的 Skill 一起出现。 ## 插件 Agent -Plugin 可以携带自定义 Agent:在 manifest 的 `agents` 字段里声明一个或多个 `./` 目录(或直接在 plugin 根下放置 `agents/` 目录),其中的 Agent 文件与[自定义 Agent](./agents.md#自定义-agent) 格式相同,会在 plugin 启用期间作为 subagent 被 main agent 自动发现和委派。 +Plugin 可以携带自定义 Agent:在 manifest 的 `agents` 字段里声明一个或多个 `./` 目录(或直接在 plugin 根下放置 `agents/` 目录),其中的 Agent 文件与[自定义 Agent](./agents.md#自定义-agent) 格式相同,会在 plugin 启用期间作为子 Agent 被主 Agent 自动发现和委派。 ```text my-plugin/ diff --git a/docs/zh/customization/skills.md b/docs/zh/customization/skills.md index a6472210a..8fd45fa17 100644 --- a/docs/zh/customization/skills.md +++ b/docs/zh/customization/skills.md @@ -127,4 +127,4 @@ arguments: ## 下一步 - [Plugins](./plugins.md) — 把 Skills 打包成可安装单元,与团队共享 -- [Agent 与 subagent](./agents.md) — Skills 如何影响 subagent 的行为 +- [Agent 与子 Agent](./agents.md) — Skills 如何影响子 Agent 的行为 diff --git a/docs/zh/guides/goals.md b/docs/zh/guides/goals.md index 8600e266f..104f3cbb1 100644 --- a/docs/zh/guides/goals.md +++ b/docs/zh/guides/goals.md @@ -12,8 +12,6 @@ Kimi Code 会保存该目标,把它作为下一条用户消息发送,并进入目标模式。每个轮次结束后,它会检查目标是「完成(`complete`)」、「阻塞(`blocked`)」、「暂停(`paused`)」,还是仍然「活跃(`active`)」。 -目标最长 4000 个字符;超长会被拒绝并给出警告,已输入的文本会保留在输入框中供继续编辑。 - 好的目标应当说清楚具体的完成条件: ```sh diff --git a/docs/zh/guides/interaction.md b/docs/zh/guides/interaction.md index 965dbcee8..628525e9d 100644 --- a/docs/zh/guides/interaction.md +++ b/docs/zh/guides/interaction.md @@ -27,15 +27,13 @@ Kimi Code CLI 支持在输入框中直接粘贴图片和视频,让 AI 结合 已激活的 [Agent Skills](../customization/skills.md) 会自动注册为斜杠命令:普通外部 Skill 以 `/skill:<name>` 调用,外部子 Skill 以 `/parent.child` 这样的点分命令显示,内置 Skill 直接以 `/<name>` 出现在斜杠命令面板中;若外部 Skill 名称与系统斜杠命令不冲突,也可以省略 `skill:` 前缀直接输入 `/<name>`。 -在较长的提示词中,也可以在空白字符后(包括后续行的行首)输入 `/` 打开仅包含 Skill 的补全菜单。这样可以在一条提示词里引用多个 Skill:Kimi Code 会将它们一起激活,与提示词作为同一轮次运行(一次 `/undo` 即可整体撤销),提示词原文保持不变。提示词中的 Skill 引用不携带参数——只按名称激活;参数仍是单独以 `/skill:<name> args` 调用时的概念。内置命令和 plugin 命令仍需放在输入开头。 - 部分命令仅在 Agent 空闲时可用,流式输出或上下文压缩期间需先按 `Esc` 中断。`/yolo`、`/plan`、`/help`、`/btw` 等模式切换和查询类命令则始终可用。全部命令说明见[斜杠命令参考](../reference/slash-commands.md)。 ## 文件引用 键入 `@` 触发文件路径补全,选中后在输入中插入相对路径,Agent 读取时会直接加载该文件内容。文件引用在 git 和非 git 目录都可用;文件夹候选会以 `/` 结尾,方便继续补全其下路径。如果快速搜索辅助工具仍在下载,Kimi Code 会先回退到基础的文件系统扫描。隐藏路径也可补全,但 `.git` 会从候选中排除。 -> `@` 引用和斜杠命令是两套不同的机制:`@` 向 Agent 提供文件上下文,`/` 调用内置功能或 Skill。空白字符后的 `/` 仅提供 Skill 补全;内置命令和 plugin 命令需要使用开头的 `/`。 +> `@` 引用和斜杠命令是两套不同的机制:`@` 向 Agent 提供文件上下文,`/` 调用内置功能或 Skill。前面有空白字符时输入 `/` 会按普通文本处理,不会打开斜杠命令菜单。 ## 审批流程 @@ -74,7 +72,6 @@ Shell 模式让你不离开对话就能运行终端命令,命令输出会写 - 退出:在空输入框中按 `Backspace` 或 `Esc`;提交命令后也会自动回到普通模式。 - 后台运行:命令执行期间按 `Ctrl+B` 可将其转为后台任务。 - 召回历史命令:在 Shell 模式的空输入框中按 `↑` 浏览此前运行过的 Shell 命令,召回后仍处于 Shell 模式,可再次作为命令执行。 -- 长输出:命令输出过长时,结束后的输出卡片会自动折叠,按 `Ctrl-O` 可与工具输出一起展开或折叠。 进入 Shell 模式后,输入框左侧会显示 `!` 提示符,边框变为紫色。例如,无需新开终端就能运行 `!gh auth login` 登录 GitHub CLI,登录后 Kimi 就可以直接使用 `gh`。 diff --git a/docs/zh/guides/server.md b/docs/zh/guides/server.md deleted file mode 100644 index 38657b80e..000000000 --- a/docs/zh/guides/server.md +++ /dev/null @@ -1,116 +0,0 @@ -# 本地服务与 API - -Kimi Code CLI 内置一个本地服务:运行 `kimi web` 会在前台启动一个进程,同时挂载浏览器里的 web UI、REST API(`/api/v1`)和 WebSocket 事件流(`/api/v1/ws`)。web UI 用于在浏览器里直接使用 Kimi Code;REST 与 WebSocket API 面向脚本和第三方工具,可以用代码创建会话、提交提示词、实时跟进执行过程——它们与 TUI、web UI 读写同一份会话数据。 - -> 开始前请确认 Kimi Code CLI 已安装并处于可用状态——完成 `/login` 登录(TUI 内或 `kimi login`),或已在 `config.toml` 配置供应商。服务与 CLI 共享同一份登录态与配置,无需为服务单独准备凭证。 - -::: warning 注意 -本页介绍的 REST 与 WebSocket API 为实验性特性:不保证接口稳定性,端点、字段与事件类型可能随版本随时更改。集成时请以当前版本服务的 `/openapi.json` 与 `/asyncapi.json` 为准。 -::: - -## 启动服务 - -```sh -kimi web # 前台运行服务并打开浏览器 -kimi web --no-open # 只运行服务,不打开浏览器 -kimi web --port 58628 # 指定绑定端口 -``` - -服务默认绑定 `127.0.0.1:58627`(仅本机访问);端口被占用时自动 +1 重试,同一台机器因此可以并存多个实例,每个实例登记在 `~/.kimi-code/server/instances/` 下。启动横幅会打印访问地址和明文 token: - -```text -Local: http://127.0.0.1:58627/#token=... -Token: ... -Stop: Ctrl+C -``` - -服务在前台运行,按 `Ctrl-C` 干净退出。`--host`、`--log-level` 等完整选项见 [kimi 命令参考](../reference/kimi-command.md#kimi-web)。 - -## 鉴权 - -所有 `/api/*` 接口都要求 bearer token(持有者令牌:任何携带该字符串的请求都被视为已授权)。token 在首次启动服务时生成,持久化在 `~/.kimi-code/server.token`(文件权限 0600),跨重启复用。 - -按客户端类型选择携带方式: - -- **REST**:请求头 `Authorization: Bearer <token>`。 -- **web UI**:启动横幅里的地址自带 `#token=` 片段,浏览器打开后自动完成登录;该片段不会发送到服务端。 -- **WebSocket**:能自定义请求头的客户端用 `Authorization: Bearer`;浏览器等不能自定义头的客户端改用子协议(WebSocket 握手时声明的协议名)`kimi-code.bearer.<token>`。 - -token 泄露时运行 `kimi web rotate-token` 轮换:新 token 立即写入 `server.token`,旧 token 即刻失效,正在运行的实例无需重启。 - -如果把服务绑定到非本机地址(`--host`),建议额外设置 `KIMI_CODE_PASSWORD` 环境变量作为并列凭证;此时服务端会对鉴权失败自动限流。 - -::: danger 警告 -`--dangerous-bypass-auth` 会彻底关闭鉴权,任何能访问该端口的人都能控制你的会话、文件系统和 shell。仅在可信网络或自有鉴权代理之后使用,详见 [kimi 命令参考](../reference/kimi-command.md#kimi-web)。 -::: - -## 用 API 驱动一个会话 - -下面用 curl 走一遍最小流程:确认服务状态 → 创建会话 → 订阅事件 → 提交提示词 → 回读历史。示例假设服务跑在默认地址,token 已存入 shell 变量 `TOKEN`。 - -1. 确认服务状态: - -```sh -curl -s -H "Authorization: Bearer $TOKEN" http://127.0.0.1:58627/api/v1/meta -``` - -所有 JSON 响应都包在统一信封里——`{ "code": 0, "msg": "success", "data": ..., "request_id": "..." }`,业务结果以 `code` 为准(`0` 表示成功),HTTP 状态码只表达传输层结果。 - -2. 创建会话,`metadata.cwd` 指定工作目录: - -```sh -curl -s -X POST http://127.0.0.1:58627/api/v1/sessions \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"metadata": {"cwd": "/path/to/project"}}' -``` - -返回的 `data.id`(形如 `session_...`)就是后续所有请求要用的会话 id。 - -3. 连接 WebSocket 并订阅会话事件。任何 WebSocket 客户端都可以;下面是一个零依赖的 Node.js 脚本(Node.js 22+ 内置 `WebSocket` 客户端): - -```js -// subscribe.mjs —— 用法:TOKEN=... node subscribe.mjs session_... -const ws = new WebSocket('ws://127.0.0.1:58627/api/v1/ws', [ - `kimi-code.bearer.${process.env.TOKEN}`, -]); -ws.onmessage = (e) => console.log(e.data); -ws.onopen = () => - ws.send( - JSON.stringify({ - type: 'subscribe', - id: '1', - payload: { session_ids: [process.argv[2]] }, - }), - ); -``` - -4. 提交提示词: - -```sh -curl -s -X POST http://127.0.0.1:58627/api/v1/sessions/<session_id>/prompts \ - -H "Authorization: Bearer $TOKEN" \ - -H "Content-Type: application/json" \ - -d '{"content": [{"type": "text", "text": "用一句话介绍这个仓库"}]}' -``` - -订阅端会依次看到 `turn.started`(轮次开始)→ `assistant.delta`(流式文本增量)→ 发生工具调用时的 `tool.call.started` / `tool.result` → `turn.ended`(轮次结束)。 - -5. 随时可以用 REST 回读历史消息: - -```sh -curl -s -H "Authorization: Bearer $TOKEN" \ - "http://127.0.0.1:58627/api/v1/sessions/<session_id>/messages?page_size=20" -``` - -## 在线规范文档 - -服务运行时会自描述两份规范文档,同样需要 bearer token: - -- `GET /openapi.json` — REST API 的 OpenAPI 文档,含每个端点的请求 / 响应 schema,可直接导入 Swagger UI、Postman 等工具。 -- `GET /asyncapi.json` — WebSocket 协议的 AsyncAPI 文档,覆盖控制帧与事件类型。 - -## 下一步 - -- [服务 API](../reference/server-api.md) — REST 端点全集、错误码、WebSocket 事件与转录协议 -- [kimi 命令](../reference/kimi-command.md#kimi-web) — `kimi web` 的全部命令行选项 diff --git a/docs/zh/guides/sessions.md b/docs/zh/guides/sessions.md index fde31a44f..fb979b077 100644 --- a/docs/zh/guides/sessions.md +++ b/docs/zh/guides/sessions.md @@ -87,8 +87,6 @@ kimi --session fork 后你仍停留在原会话,对话不受影响、可以直接继续;派生出的副本与原会话彼此独立,可以随时通过 `/sessions` 切换过去。已保存的 `/goal` 不会复制到派生会话。如果你想在派生会话中进行自主 goal 工作,需要在那里开始一个新 goal。 -fork 完成后,CLI 会打印一条可直接运行的 `kimi --resume` 命令(并自动复制到剪贴板),方便你在新终端进程中直接进入派生会话。 - ## 导出会话 用 `kimi export` 把会话打包为 ZIP,适合分享、归档或提交问题反馈: @@ -112,6 +110,8 @@ kimi export <sessionId> -o ~/Desktop/my-session.zip 在 web UI 中,`/export` 会把当前会话下载为诊断 ZIP。压缩包包含持久化的会话数据、诊断日志,以及记录浏览器关键事件且大小有上限、只含元数据的 `logs/kimi-web.jsonl`;提示词正文、WebSocket 内容和 console 参数不会写入这份浏览器日志。这里的 web 命令与上面的 TUI `/export` 别名行为不同。 +浏览器需要先把 ZIP 缓存在内存中再保存,因此 web 导出上限为 64 MiB。更大的会话请使用 `kimi export <sessionId>` 或 TUI 的 `/export-debug-zip`。 + ::: tip 提示 导出文件可能包含代码、命令输出和路径等敏感信息,分享前请先确认内容。 ::: diff --git a/docs/zh/guides/use-cases.md b/docs/zh/guides/use-cases.md index 9318b94fd..bfd1a93bc 100644 --- a/docs/zh/guides/use-cases.md +++ b/docs/zh/guides/use-cases.md @@ -24,7 +24,7 @@ src/runtime 下的 event loop 是怎么工作的?事件从哪里产生、又 这个项目里「权限审批」是怎么实现的?涉及哪些文件,关键类型是什么? ``` -大型调研可以让 main agent 派发**subagent** 并行处理子任务,详见 [Agent 与 subagent](../customization/agents.md)。 +大型调研可以让主 Agent 派发**子 Agent** 并行处理子任务,详见 [Agent 与子 Agent](../customization/agents.md)。 ## 实现新功能 @@ -143,6 +143,6 @@ src/api 下所有公开函数里,凡是没有 docstring 的都补上文档注 ## 下一步 -- [Agent 与 subagent](../customization/agents.md) — 如何让 Agent 派发子任务并行处理 +- [Agent 与子 Agent](../customization/agents.md) — 如何让 Agent 派发子任务并行处理 - [Hooks](../customization/hooks.md) — 在任务完成等节点触发本地脚本 - [内置工具](../reference/tools.md) — Agent 可调用的全部工具参考 diff --git a/docs/zh/reference/keyboard.md b/docs/zh/reference/keyboard.md index 3e95dad0e..9e3c54a5a 100644 --- a/docs/zh/reference/keyboard.md +++ b/docs/zh/reference/keyboard.md @@ -67,9 +67,9 @@ Kimi Code CLI 的 TUI 交互模式支持一套键盘快捷键。键位按使用 | 快捷键 | 功能 | | --- | --- | -| `Ctrl-O` | 展开或折叠工具输出、Shell 命令输出和压缩摘要 | +| `Ctrl-O` | 展开或折叠工具输出和压缩摘要 | -历史中存在折叠的工具调用结果或 Shell 命令输出时,按 `Ctrl-O` 可在折叠和展开之间切换。压缩完成后,同一个快捷键也会在压缩块中显示或隐藏压缩摘要。 +历史中存在折叠的工具调用结果时,按 `Ctrl-O` 可在折叠和展开之间切换。压缩完成后,同一个快捷键也会在压缩块中显示或隐藏压缩摘要。 ## 审批面板 diff --git a/docs/zh/reference/kimi-command.md b/docs/zh/reference/kimi-command.md index 587f7b531..642026c79 100644 --- a/docs/zh/reference/kimi-command.md +++ b/docs/zh/reference/kimi-command.md @@ -24,7 +24,7 @@ kimi <subcommand> [options] | `--auto` | | 以 auto 权限模式启动;工具审批自动处理,Agent 不会向用户提问 | | `--plan` | | 以 Plan 模式启动新会话,AI 会优先使用只读工具进行探索和规划 | | `--skills-dir <dir>` | | 从指定目录加载 Skills,替换自动发现的用户和项目目录。可重复传入 | -| `--agent <name>` | | 以指定 Agent 作为 main agent 启动新会话。不能与 `--session`/`--continue` 同时使用 | +| `--agent <name>` | | 以指定 Agent 作为主 Agent 启动新会话。不能与 `--session`/`--continue` 同时使用 | | `--agent-file <path>` | | 从 Markdown 文件加载自定义 Agent 并为新会话选中它。不可重复传入,也不能与 `--agent`、`--session` 或 `--continue` 同时使用 | | `--add-dir <dir>` | | 为本次会话添加额外的工作目录。相对路径按当前工作目录解析。可重复传入 | @@ -105,7 +105,7 @@ kimi --agent reviewer kimi -p --agent reviewer "审查这个分支上的改动" ``` -`--agent-file` 以最高优先级注册单个 Agent 文件(仅本次启动)并选中它;该 flag 不可重复传入,`--agent` 与 `--agent-file` 互斥。两个 flag 都仅在新建会话时有效——都不能与 `--session`/`--continue` 组合,因为 Agent 在会话创建时绑定,恢复会话时会自动还原已绑定的 Agent。选择在会话首次绑定后即固定,之后不可切换;在 TUI 中,这些 flag 只绑定启动时的会话,之后在同一进程内新建的会话(例如通过 `/new`)使用默认 Agent。Agent 文件格式与发现目录详见 [Agent 与 subagent](../customization/agents.md#自定义-agent)。 +`--agent-file` 以最高优先级注册单个 Agent 文件(仅本次启动)并选中它;该 flag 不可重复传入,`--agent` 与 `--agent-file` 互斥。两个 flag 都仅在新建会话时有效——都不能与 `--session`/`--continue` 组合,因为 Agent 在会话创建时绑定,恢复会话时会自动还原已绑定的 Agent。选择在会话首次绑定后即固定,之后不可切换;在 TUI 中,这些 flag 只绑定启动时的会话,之后在同一进程内新建的会话(例如通过 `/new`)使用默认 Agent。Agent 文件格式与发现目录详见 [Agent 与子 Agent](../customization/agents.md#自定义-agent)。 ## 非交互执行 @@ -157,7 +157,7 @@ kimi acp 在当前终端前台运行本地 Kimi 服务 —— 同一个进程同时挂载 REST + WebSocket API 与 web UI —— 并在服务就绪后用默认浏览器打开 web UI。命令会一直挂在终端,直到收到 `SIGINT` / `SIGTERM`(如 `Ctrl-C`)时干净退出。 -服务运行时,`GET /openapi.json` 会返回 REST OpenAPI 文档,`GET /asyncapi.json` 会返回本地 WebSocket 协议的 AsyncAPI 文档。用 API 驱动会话的完整流程见[本地服务与 API](../guides/server.md),协议细节见[服务 API](./server-api.md)。 +服务运行时,`GET /openapi.json` 会返回 REST OpenAPI 文档,`GET /asyncapi.json` 会返回本地 WebSocket 协议的 AsyncAPI 文档。 ```sh kimi web # 前台运行服务并打开浏览器 @@ -175,7 +175,6 @@ kimi web --port 58628 # 指定绑定端口 | `--log-level <level>` | 按所选级别开启服务日志;默认不输出 | | `--debug-endpoints` | 挂载 `/api/v1/debug/*` 调试路由(默认关闭) | | `--dangerous-bypass-auth` | 关闭所有 REST 与 WebSocket 路由的 bearer token 鉴权,使 web UI 无需 token 即可连接;仅用于可信网络或自有鉴权代理之后 | -| `--web-title <title>` | 自定义 web UI 的浏览器标签页标题;默认为工作区目录名 | | `--no-open` | 就绪后不自动打开浏览器 | `kimi web` 默认只绑定本机 loopback 地址,并在启动横幅中打印 bearer token;web UI 通过 URL 的 `#token=` 片段自动完成鉴权。 @@ -269,7 +268,7 @@ kimi migrate kimi upgrade ``` -对全局 npm、pnpm、yarn、bun 安装,`kimi upgrade` 会展示更新选项;选择 `Install update now` 后运行对应的前台安装命令。对 native 安装(含 Windows),会在前台下载并校验新二进制,并在下次启动时替换生效。当前安装方式无法自动升级时,改为打印手动更新命令。 +对全局 npm、pnpm、yarn、bun 以及 macOS / Linux native 安装,`kimi upgrade` 会展示更新选项;选择 `Install update now` 后运行对应的前台安装命令。当前安装方式无法自动升级时(如 Windows native 安装),改为打印手动更新命令。 ### `kimi vis` @@ -381,4 +380,4 @@ kimi provider catalog add anthropic --api-key sk-ant-... --default-model claude- - [斜杠命令](./slash-commands.md) — 交互式 TUI 内的控制命令速查 - [配置文件](../configuration/config-files.md) — `default_model`、权限模式等启动参数的持久化配置 - [Agent Skills](../customization/skills.md) — `--skills-dir` 加载的 Skill 文件格式 -- [Agent 与 subagent](../customization/agents.md) — 内置 subagent、自定义 Agent 文件与通过 `--agent` 选择 main agent +- [Agent 与子 Agent](../customization/agents.md) — 内置子 Agent、自定义 Agent 文件与通过 `--agent` 选择主 Agent diff --git a/docs/zh/reference/server-api.md b/docs/zh/reference/server-api.md deleted file mode 100644 index fc47fcec7..000000000 --- a/docs/zh/reference/server-api.md +++ /dev/null @@ -1,2322 +0,0 @@ -# 服务 API - -`kimi web` 启动的本地服务暴露两组程序化接口:REST API(`/api/v1`,另有 `/api/v2/sessions` 和 `/api/v2/mcp`)和 WebSocket 事件流(`/api/v1/ws`)。本页是这两组接口的协议参考。如何启动服务及其命令行选项见 [kimi 命令](./kimi-command.md#kimi-web) 参考;端到端的上手流程见 [本地服务与 API](../guides/server.md)。 - -本页是一份经过整理、面向人阅读的参考:下文逐一记录每个端点的参数、请求体与响应结构。每个端点精确的机器可读 schema 以服务的在线规范文档为准:`GET /openapi.json`(OpenAPI)与 `GET /asyncapi.json`(AsyncAPI),两者都由服务运行时实际执行的校验 schema 生成。两者都需要鉴权;当本页与在线规范不一致时,以在线规范为准。 - -::: warning 注意 -本页描述的 REST 与 WebSocket API 为实验性特性:不保证接口稳定性,端点、字段与事件类型可能随任何版本更改。集成时请以你所用版本服务的 `/openapi.json` 与 `/asyncapi.json` 文档为准。 -::: - -## 基础约定 - -### 地址 - -默认地址为 `http://127.0.0.1:58627`。端口被占用时,服务会用下一个端口重试(至多 100 次);可用 `--port` / `--host` 修改绑定。同一 home 目录下可并存多个实例,运行中的实例登记在 `~/.kimi-code/server/instances/`。 - -### 鉴权 - -除以下例外,所有 `/api/*` 路径(含 `/openapi.json` 与 `/asyncapi.json`)都要求 bearer token: - -- `OPTIONS` 预检请求 -- `GET /api/v1/healthz`(探活) -- 静态 web 资源(非 `/api/` 路径) - -携带方式:REST 用 `Authorization: Bearer <token>` 请求头;WebSocket 升级请求接受同一请求头,或子协议 `kimi-code.bearer.<token>`。token 的生成与轮换见 [本地服务与 API:鉴权](../guides/server.md#authentication)。 - -鉴权失败返回 HTTP 401,信封 `code` 为 `40101`。在非 loopback 绑定上,同一来源 60 秒内鉴权失败 10 次会被封禁 60 秒,期间每个请求都返回 HTTP 429(`code` 为 `42901`)。 - -### 响应信封 - -所有 JSON 响应统一包在信封里: - -```json -{ - "code": 0, - "msg": "success", - "data": {}, - "request_id": "01JZX4A6E7M8V0R3Q0N2K2M5Q9" -} -``` - -- `code`:业务结果,`0` 表示成功;错误码分段见下文。 -- `data`:成功时的业务数据。注意部分「错误」信封也携带非空 `data`——例如重复解决审批返回 `40902` 且 `data.resolved` 为 `false`——客户端应先判 `code` 再看 `data`。 -- `request_id`:本次请求的 ULID;客户端可用 `X-Request-Id` 请求头指定,非法值会被服务端重新生成。 - -HTTP 状态码几乎总是 200,业务结果以 `code` 为准。例外情况: - -| 场景 | HTTP 状态 | -| --- | --- | -| 鉴权失败 / 触发限流 | 401 / 429 | -| 创建供应商、导入供应商目录成功 | 201 | -| 删除供应商成功 | 204 | -| 二进制与流式端点 | 支持时返回 206(Range 分段)/ 304(ETag 未变),各端点能力不同,详见「[二进制与流式端点](#二进制与流式端点)」 | -| `GET /api/v1/files/{file_id}` 下载错误 | 真实 404 / 500(响应体仍为信封) | - -其中 201 的响应体仍是标准信封(`code` 为 `0`),只是状态行遵循 REST 的资源创建惯例;204 按定义没有响应体,删除成功以状态码本身为准。 - -### 错误码 - -错误码按段位分组: - -| 段位 | 含义 | 示例 | -| --- | --- | --- | -| `0` | 成功 | | -| `400xx` | 请求参数错误 | `40001` 校验失败(`details` 逐字段说明)、`40003` 供应商由 OAuth 托管 | -| `401xx` | 鉴权与就绪状态 | `40101` 未授权、`40110` 未配置供应商、`40113` 模型未解析 | -| `404xx` | 资源不存在 | `40401` 会话、`40408` MCP 服务、`40409` 文件路径 | -| `409xx` | 状态冲突 | `40901` 会话忙、`40902` 审批已解决、`40922` 分页条件与 `page_token` 不符 | -| `410xx` | 资源已过期 | `41001` 审批超时、`41002` 提问超时、`41003` 临时文件过期 | -| `413xx` | 体积或边界超限 | `41302` 读取文件超 10 MB、`41304` 路径越出会话目录 | -| `429xx` | 限流 | `42901` 鉴权失败封禁、`42902` 文件监听数超限 | -| `500xx` | 服务端内部错误 | `50001` 未捕获异常、`50003` 持久化失败 | -| `6xxxx` / `7xxxx` / `8xxxx` | 工具运行时 / LLM 供应商 / MCP 透传错误,`msg` 保留上游原文 | | - -### 分页 - -列表端点有两种分页风格: - -- **游标式**:`before_id` / `after_id`(互斥)加 `page_size`(1–100),响应为 `{ items, has_more }`。用于会话列表、消息列表、转录等。 -- **`page_token`**:不透明令牌(绑定了查询条件的指纹),用于 `POST /api/v1/search` 与 `GET /api/v2/sessions`。翻页途中改变任何查询条件会使令牌失效:v2 返回 `40922`,search 返回 `40001`。`GET /api/v2/sessions` 另提供无状态的 `page` 页码模式作为替代。 - -## REST 端点 - -下文按资源分组列出端点。路径里的 `:{action}` 后缀是动作约定——对单个资源 POST 到 `路径:动作` 执行非 CRUD 操作(如会话的 `:fork`、`:archive`)。 - -### 服务与元信息 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/healthz` | 探活,免鉴权 | -| `GET /api/v1/meta` | 服务版本、能力集、`server_id`、实验开关 | -| `POST /api/v1/shutdown` | 优雅退出(先回 200 再关闭);仅 loopback 绑定时挂载 | - -#### `GET /api/v1/healthz` - -供脚本与进程管理器使用的探活端点。它是唯一豁免 bearer token 的 `/api` 端点(见 [鉴权](#鉴权)),应答时不触碰配置与引擎。 - -成功时 `data` 为 `{ "ok": true }`。 - -#### `GET /api/v1/meta` - -返回本实例的身份信息与能力集。大多数字段在启动时即固定;`experimental_flags` 与 `features` 按请求实时解析,因此开关翻转或某个 feature 失败会体现在下一次响应中。 - -成功时 `data` 携带: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `server_version` | string | 服务版本 | -| `capabilities` | object | 能力集——`websocket`、`file_upload`、`fs_query`、`mcp`、`tasks`、`terminal`,均恒为 `true` | -| `server_id` | string | 本服务实例的唯一 id | -| `started_at` | string | 启动时间,ISO 8601 格式 | -| `open_in_apps` | array | 可作为 `open-in` 目标的宿主应用(`finder` / `cursor` / `vscode` / `iterm` / `terminal`);目前恒为空 | -| `dangerous_bypass_auth` | boolean | 服务是否以 `--dangerous-bypass-auth` 启动(客户端可跳过 token 提示) | -| `backend` | string | 引擎后端,`v1` 或 `v2`;本服务恒为 `v2` | -| `web_title` | string | 来自 `--web-title` 的自定义浏览器标签页标题;未设置时省略 | -| `experimental_flags` | object | 实验开关 id → 是否启用,按请求时解析 | -| `features` | array | 引擎 feature,形如 `{ name, state, meta }`;`state` 为 `Pending` / `Activating` / `Active` / `Unloading` / `Failed` | - -#### `POST /api/v1/shutdown` - -请求服务优雅退出。响应先发出,随后立即执行关闭,因此调用方可以信任收到的响应。该路由仅在 loopback 绑定时挂载——非 loopback 绑定时它根本不会被注册(请求得到 404),除非服务以 `--allow-remote-shutdown` 启动。 - -成功时 `data` 为 `{ "ok": true }`。 - -### 登录与用量 - -这组端点驱动托管 Kimi OAuth 登录的生命周期,并暴露账号级信息。托管供应商名为 `managed:kimi-code`;下面每个端点上可选的 `provider` 参数都默认取它。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/auth` | 鉴权就绪状态快照 | -| `POST /api/v1/oauth/login` | 发起 OAuth device-code 登录流程 | -| `GET /api/v1/oauth/login` | 轮询登录流程状态 | -| `DELETE /api/v1/oauth/login` | 取消进行中的登录流程 | -| `POST /api/v1/oauth/logout` | 登出托管供应商 | -| `GET /api/v1/oauth/usage` | 套餐用量与限额 | -| `GET /api/v1/oauth/userinfo` | 账号资料 | -| `GET /api/v1/oauth/region` | 解析客户端所属区域(`mainland-cn` / `global`) | - -#### `GET /api/v1/auth` - -鉴权就绪状态快照:服务是否具备可用的模型配置,以及托管供应商的登录状态。当至少配置了一个供应商、设置了默认模型、且托管供应商(如存在)未被吊销时,`ready` 为 `true`。 - -成功时 `data` 携带 `ready`(布尔值)、`providers_count`(已配置供应商数量)、`default_model`(全局默认模型别名,或 `null`)与 `managed_provider`(`null`,或 `{ name, status }`,其中 `status` 为 `authenticated` / `expired` / `revoked` / `unauthenticated` 之一)。 - -#### `POST /api/v1/oauth/login` - -为托管供应商发起 OAuth device-code 登录流程;发起新流程会中止同一供应商进行中的流程。账号已登录时无需用户交互,响应会立即报告 `authenticated`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | body | string | 托管供应商名称。默认 `managed:kimi-code` | -| `region` | body | string | `mainland-cn` 或 `global`;覆盖 `GET /api/v1/oauth/region` 一节描述的区域解析结果,仅对本次流程生效 | - -成功时 `data` 有两种形态。进行中的流程——`{ flow_id, provider, status: "pending", verification_uri, verification_uri_complete, user_code, expires_in, interval, expires_at }`:打开 `verification_uri_complete`(或打开 `verification_uri` 并输入 `user_code`),然后每隔 `interval` 秒轮询 `GET /api/v1/oauth/login`,直到流程完结或超过 `expires_at`(`expires_in` 是以秒表示的同一时限)。已登录的快速路径——`{ flow_id, provider, status: "authenticated" }`。 - -#### `GET /api/v1/oauth/login` - -轮询某供应商的登录流程状态。尚未发起过流程时返回 `null`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | query | string | 托管供应商名称。默认 `managed:kimi-code` | - -成功时 `data` 为 `null` 或流程快照:`{ flow_id, provider, status, verification_uri, verification_uri_complete, user_code, expires_in, expires_at, interval }`,其中 `status` 为 `pending` / `authenticated` / `denied` / `expired` / `cancelled`。流程离开 `pending` 后,`resolved_at` 记录其到达终态的时间,`error_message` 描述失败的流程。 - -#### `DELETE /api/v1/oauth/login` - -取消某供应商进行中的登录流程。没有进行中的流程时,该调用为空操作,返回最近一次已知状态。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | query | string | 托管供应商名称。默认 `managed:kimi-code` | - -成功时 `data` 为 `{ cancelled, status }`:只有确实中止了一个 `pending` 流程时 `cancelled` 才为 `true`,`status` 为调用后的流程状态。 - -#### `POST /api/v1/oauth/logout` - -登出托管供应商:丢弃已存储的 OAuth 凭据、中止进行中的登录流程,并把托管供应商从配置中移除。OAuth 托管的供应商拒绝手动编辑与删除(见下文 `PUT` / `DELETE /api/v1/providers/{provider_id}`),因此要移除它需先登出。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | body | string | 托管供应商名称。默认 `managed:kimi-code` | - -成功时 `data` 为 `{ logged_out: true, provider }`。 - -#### `GET /api/v1/oauth/usage` - -托管账号的套餐用量与限额,实时取自账号服务。上游失败不会让信封失败——它以 `kind: "error"` 的形式带内返回。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | query | string | 托管供应商名称。默认 `managed:kimi-code` | - -成功时 `data` 为 `{ kind: "ok", summary, limits, extra_usage }` 或 `{ kind: "error", message, status? }`,其中 `status` 为上游 HTTP 状态码(如存在)。在 `ok` 形态中,`summary`(可空)是主配额行,`limits` 列出每个配额窗口;一行的结构为 `{ name?, window?, used, limit, reset_at? }`,其中 `window` 为 `{ duration, unit }`,`unit` 为 `minute` / `hour` / `day` / `week` 之一。`extra_usage`(可空)是按量付费钱包:`{ balance_cents, total_cents, monthly_charge_limit_enabled, monthly_charge_limit_cents, monthly_used_cents, currency }`。 - -#### `GET /api/v1/oauth/userinfo` - -托管账号的资料,带内 `kind: "error"` 约定与 `GET /api/v1/oauth/usage` 相同。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider` | query | string | 托管供应商名称。默认 `managed:kimi-code` | - -成功时 `data` 为 `{ kind: "ok", userInfo }` 或 `{ kind: "error", message, status? }`。`userInfo` 始终携带 `userId`、`nickname`、`status`、`region`、`userLevel`、`userLevelName`、`domain`、`domainName`,并可能附加 `globalId`、`bio`、`avatar`、`username`、`email`、`phone`(`{ countryCode, number }`)、`createdTime` 与 `lastLoginTime`。 - -#### `GET /api/v1/oauth/region` - -解析该客户端所属的 Kimi 区域。结果在本地推导,不经网络探测:优先取环境变量或配置固定的 OAuth host,其次是已配置的 OAuth key,再次是 home 目录中的区域标记文件;默认为 `mainland-cn`。 - -成功时 `data` 为 `{ region }`,`region` 为 `mainland-cn` / `global` 之一。 - -### 配置 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/config` | 读取全局配置(密钥字段脱敏) | -| `POST /api/v1/config` | 合并式更新配置,并广播 `event.config.changed` | - -#### `GET /api/v1/config` - -返回解析后的全局配置——`config.toml` 叠加覆盖层后的生效结果。密钥已脱敏:每个供应商只报告 `has_api_key`,绝不返回存储的密钥。 - -成功时 `data` 为配置对象;其字段与 [顶层字段](../configuration/config-files.md#top-level-fields) 记录的顶层域一一对应: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `providers` | object | 供应商 id → `{ type, base_url?, default_model?, has_api_key }` 的映射 | -| `default_provider` | string | 全局默认供应商 id | -| `default_model` | string | 全局默认模型别名 | -| `models` | object | 模型别名 → 模型记录的映射 | -| `thinking` | object | Thinking 模式的默认参数 | -| `plan_mode` | boolean | Plan 模式开关 | -| `yolo` | boolean | 派生值:`default_permission_mode` 为 `yolo` 时为 `true` | -| `default_permission_mode` | string | 新会话的默认权限模式 | -| `default_plan_mode` | boolean | 新会话是否以 Plan 模式启动 | -| `permission` | object | 初始权限规则 | -| `hooks` | array | 生命周期钩子 | -| `services` | object | 内置外部服务配置 | -| `merge_all_available_skills` | boolean | 是否合并所有可用目录中的 Agent Skills | -| `extra_skill_dirs` | array | 额外的 Skill 搜索目录 | -| `loop_control` | object | Agent 循环控制参数 | -| `background` | object | 后台任务运行参数 | -| `subagent` | object | subagent 配置 | -| `secondary_model` | object | subagent 的次级模型池 | -| `experimental` | object | 实验开关 id → 是否启用 | -| `telemetry` | boolean | 是否启用匿名遥测 | -| `raw` | object | 原始解析的 `config.toml` 内容,包含未建模字段 | - -#### `POST /api/v1/config` - -合并式更新全局配置:请求体中的每个顶层域被深合并进对应域,未出现在请求体中的域保持不动。把 `yolo` 设为 `true` 是 `default_permission_mode: "yolo"` 的简写。更新成功后,服务会广播全局 `event.config.changed` 事件,携带变更的字段名与完整的更新后配置;被拒绝的补丁(值非法或持久化失败)返回 `40001` 与底层错误信息。 - -请求体是部分配置对象——上述响应域中除 `raw` 外的任意子集,均为可选: - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `providers` | body | object | 供应商 id → 供应商表的映射 | -| `default_provider` | body | string | 全局默认供应商 id | -| `default_model` | body | string | 全局默认模型别名 | -| `models` | body | object | 模型别名 → 模型记录的映射 | -| `thinking` | body | object | Thinking 模式的默认参数 | -| `plan_mode` | body | boolean | Plan 模式开关 | -| `yolo` | body | boolean | `true` 映射为 `default_permission_mode: "yolo"`;`false` 被忽略 | -| `default_permission_mode` | body | string | `manual` / `yolo` / `auto` | -| `default_plan_mode` | body | boolean | 新会话是否以 Plan 模式启动 | -| `permission` | body | object | 初始权限规则 | -| `hooks` | body | array | 生命周期钩子 | -| `services` | body | object | 内置外部服务配置 | -| `merge_all_available_skills` | body | boolean | 是否合并所有可用目录中的 Agent Skills | -| `extra_skill_dirs` | body | array | 额外的 Skill 搜索目录 | -| `loop_control` | body | object | Agent 循环控制参数 | -| `background` | body | object | 后台任务运行参数 | -| `subagent` | body | object | subagent 配置 | -| `secondary_model` | body | object | subagent 的次级模型池 | -| `experimental` | body | object | 实验开关 id → 是否启用 | -| `telemetry` | body | boolean | 是否启用匿名遥测 | - -成功时 `data` 为完整的更新后配置,形态与 `GET /api/v1/config` 相同。 - -### 模型与供应商 - -这组端点管理模型配置的两半——`config.toml` 的 [供应商](../configuration/providers.md) 表与模型别名表——外加一个由服务端代理的 models.dev 目录,用于一次性导入。模型别名 id 就是配置中的别名键:通过供应商管理端点创建的别名形如 `provider_id/model`(例如 `my-provider/kimi-for-coding`),而模型别名表中的裸键(如 `turbo`)原样使用;API 中任何接收 `model_id` 的地方(包括全局 `default_model`)指的都是这个别名 id。`:{action}` 路由上不支持的动作返回 `40001`。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/models` | 列出已配置的模型别名 | -| `POST /api/v1/models/{model_id}:set_default` | 设置全局默认模型 | -| `GET /api/v1/providers` | 列出供应商 | -| `POST /api/v1/providers` | 创建供应商(201) | -| `GET /api/v1/providers/{provider_id}` | 读取供应商(含已存密钥) | -| `PUT /api/v1/providers/{provider_id}` | 整体替换供应商配置 | -| `DELETE /api/v1/providers/{provider_id}` | 删除供应商(204) | -| `POST /api/v1/providers/{provider_id}:refresh` | 刷新该供应商的模型元数据 | -| `POST /api/v1/providers:{action}` | 集合级动作:`refresh` / `refresh_oauth` / `import_catalog` / `import_registry` | -| `GET /api/v1/catalog/providers` | 浏览 models.dev 目录(服务端代理) | -| `GET /api/v1/catalog/providers/{catalog_id}` | 读取目录中单个条目 | - -#### `GET /api/v1/models` - -列出所有供应商下已配置的模型别名。 - -成功时 `data.items` 为 `{ provider, model, display_name?, max_context_size, capabilities?, support_efforts?, default_effort? }` 数组:`model` 是别名 id(供应商管理的别名为 `provider_id/model`,否则为裸键),`provider` 是所属供应商 id,`max_context_size` 是以 token 计的上下文窗口,`capabilities` / `support_efforts` / `default_effort` 描述能力标志与 Thinking 模式的 effort 支持。 - -#### `POST /api/v1/models/{model_id}:set_default` - -把全局 `default_model` 设为一个已存在的别名。`model_id` 是配置中的别名键原样——裸键如 `POST /api/v1/models/turbo:set_default`;当 id 含 `/` 时需做 URL 编码,如 `POST /api/v1/models/my-provider%2Fkimi-for-coding:set_default`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `model_id` | path | string | **必填。** 配置中的模型别名键原样;含 `/` 时需 URL 编码 | - -成功时 `data` 为 `{ default_model, model }`——当前生效的别名及其目录项(形态与 `GET /api/v1/models` 的单项相同)。 - -- `40001`:路径中的动作后缀非法或不支持 -- `40413`:不存在该 id 的模型别名 - -#### `GET /api/v1/providers` - -列出每个已配置供应商及其凭据与模型发现状态,不泄露任何密钥。这也是其他供应商端点引用的供应商条目形态。 - -成功时 `data.items` 为如下结构的数组: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `id` | string | 供应商 id | -| `type` | string | 通信协议:`kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `base_url` | string | API 基础 URL,如已设置 | -| `default_model` | string | 该供应商的默认模型别名,如已设置 | -| `has_api_key` | boolean | 是否已存储凭据 | -| `status` | string | 存在 API 密钥或缓存的 OAuth token 时为 `connected`,否则为 `unconfigured`(`error` 在 schema 中保留) | -| `models` | array | 该供应商的模型别名 id | - -#### `POST /api/v1/providers` - -一次保存创建供应商及其模型别名;响应为 HTTP 201 加标准信封。当全局 `default_model` 完全未配置时(全新安装),会以新供应商的 `default_model`(或第一个模型)播种;已有默认值绝不被修改。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `id` | body | string | **必填。** 供应商 id——字母、数字、`-`、`_` 与空格;必须以字母或数字开头 | -| `type` | body | string | **必填。** 通信协议:`kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `api_key` | body | string | API 密钥,存储于 `config.toml` | -| `base_url` | body | string | API 基础 URL;不得包含环境变量占位符(`${...}`) | -| `default_model` | body | string | 该供应商的默认模型;必须是 `models[].model` 之一 | -| `models` | body | array | **必填。** 至少一条,不允许重复的 `model` 值;条目结构见下文 | - -每个 `models[]` 条目声明一个别名,其 id 为 `id/model`: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `model` | string | **必填。** 上游模型名 | -| `max_context_size` | integer | **必填。** 以 token 计的上下文窗口,≥ 1 | -| `display_name` | string | 显示名 | -| `capabilities` | array | 能力标志,如 `thinking` 或 `image_in` | -| `max_output_size` | integer | 最大输出 token 数,≥ 1 | -| `support_efforts` | array | 支持的 Thinking 模式 effort 档位 | -| `adaptive_thinking` | boolean | 自适应 thinking 开关 | - -成功时 `data` 为创建好的供应商条目(形态与 `GET /api/v1/providers` 的单项相同)。 - -- `40921`:已存在该 `id` 的供应商 - -#### `GET /api/v1/providers/{provider_id}` - -读取单个供应商。与列表路由不同,设置了密钥时响应会暴露存储的 `api_key`,以便本地编辑表单预填——暴露端口时请牢记这一点。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider_id` | path | string | **必填。** 供应商 id | - -成功时 `data` 为供应商条目,存有密钥时附带 `api_key`。 - -- `40412`:供应商不存在 - -#### `PUT /api/v1/providers/{provider_id}` - -一次保存整体替换供应商:`type`、`base_url` 与模型列表被重写,该供应商的别名按 `models` 重建——不再列出的别名从 `config.toml` 中消失,其他供应商的别名不受影响。`api_key` 是三态的:省略表示保留已存密钥,`""` 表示清除,其他值表示替换。除 `new_id` 重命名迁移外,全局默认指针绝不被修改。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider_id` | path | string | **必填。** 当前供应商 id | -| `new_id` | body | string | 重命名供应商;providers 键、模型别名、`default_provider`、指向旧别名的 `default_model` 以及 subagent 次级模型池都会随之迁移。id 规则与 `POST /api/v1/providers` 相同 | -| `type` | body | string | **必填。** 通信协议:`kimi` / `openai` / `openai_responses` / `anthropic` / `google-genai` / `vertexai` | -| `api_key` | body | string | 三态,见上文 | -| `base_url` | body | string | API 基础 URL;不得包含环境变量占位符(`${...}`) | -| `default_model` | body | string | 该供应商的默认模型;必须是 `models[].model` 之一 | -| `models` | body | array | **必填。** 至少一条,不允许重复的 `model` 值;条目结构与 `POST /api/v1/providers` 相同 | - -成功时 `data` 为 `{ provider }`,即保存后的供应商条目。 - -- `40001`:重命名后的别名 id 会与其他供应商的别名冲突 -- `40003`:供应商由 OAuth 托管——请改用 `POST /api/v1/oauth/logout` 登出 -- `40412`:供应商不存在 -- `40921`:`new_id` 已被占用 - -#### `DELETE /api/v1/providers/{provider_id}` - -删除供应商及其全部模型别名;subagent 次级模型池会级联清理。全局 `default_provider` / `default_model` 指针保持不动,即使它们指向被删的供应商——那是用户的设置,不由本端点代为回收。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider_id` | path | string | **必填。** 供应商 id | - -成功时服务应答 204 且无响应体——状态行本身即表示删除成功(见 [响应信封](#响应信封))。 - -- `40003`:供应商由 OAuth 托管——请改用 `POST /api/v1/oauth/logout` 登出 -- `40412`:供应商不存在 - -#### `POST /api/v1/providers/{provider_id}:refresh` - -从上游来源重新发现单个供应商的模型元数据,并重写该供应商的别名。模型来源为静态的供应商不经任何网络调用直接报告 `unchanged`。至少一个供应商的别名发生变化时,服务会广播全局 `event.model_catalog.changed` 事件。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `provider_id` | path | string | **必填。** 供应商 id | - -成功时 `data` 为刷新报告:`changed` 是 `{ provider_id, provider_name, added, removed }`(新增 / 移除的别名数)的数组,`unchanged` 是无差异的供应商 id 数组,`failed` 是 `{ provider, reason }` 的数组。 - -- `40001`:路径中的动作后缀非法或不支持 -- `40412`:供应商不存在 - -#### `POST /api/v1/providers:refresh` - -刷新每个供应商的模型元数据。请求体可选且被忽略。 - -成功时 `data` 为与 `POST /api/v1/providers/{provider_id}:refresh` 相同的刷新报告(`changed` / `unchanged` / `failed`)。 - -#### `POST /api/v1/providers:refresh_oauth` - -与 `POST /api/v1/providers:refresh` 相同的刷新,仅限 OAuth 凭据的供应商。请求体可选且被忽略。 - -成功时 `data` 为刷新报告(`changed` / `unchanged` / `failed`)。 - -#### `POST /api/v1/providers:import_catalog` - -把一个 models.dev 目录条目导入为已配置供应商;响应为 HTTP 201 加标准信封。通信协议与端点来自目录解析,目录中的每个模型都写为一个别名。导入已存在的 id 等同于刷新——供应商条目及其别名按目录重写,省略 `api_key` 表示保留已存密钥。全局默认指针绝不被修改,仅在完全未配置默认模型时,以第一个导入的模型播种 `default_model`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `catalog_id` | body | string | **必填。** 来自 `GET /api/v1/catalog/providers` 的目录条目 id | -| `id` | body | string | 覆盖目录 id 作为本地供应商 id。id 规则与 `POST /api/v1/providers` 相同 | -| `api_key` | body | string | 导入供应商的 API 密钥 | -| `base_url` | body | string | 覆盖目录解析出的端点;条目的 `needs_base_url` 为 `true` 时必填 | - -成功时 `data` 为 `{ provider, models_imported }`——供应商条目与写入的别名数量。 - -- `40001`:缺少 `catalog_id` 或其他请求体校验失败 -- `40003`:目标供应商已存在且由 OAuth 托管 -- `40004`:条目无法导入(被拒绝、要求 `base_url`、没有可导入的模型,或其 id 不能用作供应商 id) -- `40417`:不存在该 `catalog_id` 的目录条目 -- `50004`:models.dev 目录不可用 - -#### `POST /api/v1/providers:import_registry` - -把一个 models.dev 形态的私有注册表——一个 `api.json` URL 加可选的 Bearer key——导入为已配置供应商;响应为 HTTP 201 加标准信封。每个列出的供应商都带 `source` 记录写入,以便定时刷新重新发现。重复导入同一 URL 会移除上游已消失的供应商——URL 是注册表的稳定身份,因此轮换 key 是安全的。全局默认指针遵循与 `:import_catalog` 相同的规则。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `url` | body | string | **必填。** 注册表 `api.json` 的 URL | -| `api_key` | body | string | 注册表的 Bearer key;省略时复用上一次导入同一 URL 所用的 key | - -成功时 `data` 为 `{ providers, models_imported }`——供应商条目数组与写入的别名总数。 - -- `40001`:缺少 `url` 或其他请求体校验失败 -- `40003`:某个列出的供应商已存在且由 OAuth 托管 -- `40005`:注册表无法获取或解析,或未列出可导入的供应商 - -#### `GET /api/v1/catalog/providers` - -浏览 models.dev 目录,由服务端代理,带 10 分钟内存缓存与内置快照兜底。条目保持上游目录顺序。服务无法导入的条目携带 `rejected: true` 与机器可读的 `reject_reason`;`needs_base_url: true` 的条目在导入时要求提供 base URL。 - -成功时 `data.items` 为 `{ id, name, wire_type, guessed, needs_base_url, rejected, reject_reason, env_key, models }` 数组:`wire_type` 是解析出的协议(可空,枚举与供应商 `type` 相同),`guessed` 标记启发式解析,`env_key` 是上游约定的 API 密钥环境变量(可空),`models` 是 `{ id, name?, max_context_size, capabilities?, reasoning }` 的数组。 - -- `50004`:目录不可用(在线拉取与内置快照均失败) - -#### `GET /api/v1/catalog/providers/{catalog_id}` - -按 catalog id 读取单个 models.dev 目录条目——条目形态与 `GET /api/v1/catalog/providers` 相同。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `catalog_id` | path | string | **必填。** 目录条目 id | - -成功时 `data` 为该目录条目(形态与 `GET /api/v1/catalog/providers` 的单项相同)。 - -- `40417`:不存在该 `catalog_id` 的目录条目 -- `50004`:目录不可用 - -### 会话 - -这些端点用于创建、列出和查看会话,执行会话级动作(fork、compact、undo 等),并读取会话级汇总。其中大多数返回的会话采用 [session 对象](#session-对象) 中统一说明的线上格式;非 CRUD 操作使用上文介绍的 `:{action}` 约定。 - -| 方法与路径 | 说明 | -| --- | --- | -| `POST /api/v1/sessions` | 创建会话(需 `workspace_id` 或 `metadata.cwd`) | -| `GET /api/v1/sessions` | 列出会话,游标分页,支持 `busy` / `archived_only` 等过滤 | -| `GET /api/v1/sessions/{session_id}` | 读取单个会话 | -| `GET /api/v1/sessions/{session_id}/profile` | 读取会话档案 | -| `POST /api/v1/sessions/{session_id}/profile` | 更新标题、元数据、Agent 配置 | -| `POST /api/v1/sessions/{session_id}/title/generate` | 通过托管的 `chat_title` 工具生成标题 | -| `POST /api/v1/sessions/{session_id}:{action}` | 会话动作:`fork` / `compact` / `undo` / `abort` / `btw` / `archive` / `restore` | -| `GET /api/v1/sessions/{session_id}/children` | 列出子会话 | -| `POST /api/v1/sessions/{session_id}/children` | 创建子会话(fork 并打标) | -| `GET /api/v1/sessions/{session_id}/status` | 实时状态汇总 | -| `GET /api/v1/sessions/{session_id}/goal` | 当前目标快照(无则 `null`) | -| `GET /api/v1/sessions/{session_id}/warnings` | 会话级告警 | -| `GET /api/v1/sessions/{session_id}/runtime` | 读取 main agent 的运行时绑定 | -| `POST /api/v1/sessions/{session_id}/runtime` | 切换 main agent 的运行时绑定 | -| `POST /api/v1/sessions/{session_id}/export` | 导出会话与诊断信息(zip 流,不走信封) | -| `GET /api/v1/sessions/{session_id}/snapshot` | 客户端重建用全量快照(含 `as_of_seq` 与 `epoch`) | -| `GET /api/v1/sessions/{session_id}/media/{file_id}` | 按文件 id 下载提示词媒体(二进制) | - -#### session 对象 - -每个返回会话的端点都使用这种线上格式。实时状态字段(`busy`、`main_turn_active`、`pending_interaction`、`last_turn_reason`)由会话的活动聚合解析得出:未加载到本服务进程中的会话(冷会话)始终上报为不忙碌且无待处理交互。少数字段在当前投影中是占位值——已逐字段注明。 - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `id` | string | 会话 id(`session_...`) | -| `workspace_id` | string | 所属工作区 id | -| `title` | string | 会话标题;无标题时为 `""` | -| `created_at` / `updated_at` | string | 创建时间与最后更新时间,ISO 8601 | -| `archived` | boolean | 会话是否已归档(归档后从默认会话列表中隐藏) | -| `archived_at` | string | 归档时间,ISO 8601;仅在已归档时存在 | -| `busy` | boolean | 是否有任一 Agent 存在进行中的轮次或后台任务 | -| `main_turn_active` | boolean | main agent 是否有进行中的轮次 | -| `pending_interaction` | string | `none` / `approval` / `question`——有未答复的交互在等待 | -| `last_turn_reason` | string | main agent 最近一次轮次的结果:`completed` / `cancelled` / `failed` | -| `last_prompt` | string | 最近一条用户提示词文本(如有) | -| `metadata` | object | 自定义元数据;始终携带 `cwd`(会话的工作目录) | -| `agent_config` | object | 投影为 `{ model }`;`model` 在大多数响应中为 `""`,仅由 `GET /api/v1/sessions/{session_id}/snapshot` 填入实时模型 | -| `usage` | object | token 汇总 `{ input_tokens, output_tokens, cache_read_tokens, cache_creation_tokens, context_tokens, context_limit?, total_cost_usd?, turn_count? }`;在 snapshot 端点之外全为零 | -| `permission_rules` | array | 会话权限规则;当前始终为 `[]` | -| `message_count` | integer | 消息数;当前始终为 `0` | -| `last_seq` | integer | 最后的事件序列号;当前始终为 `0` | - -#### `POST /api/v1/sessions` - -创建会话并返回。目标目录来自 `workspace_id`(已注册的工作区)或 `metadata.cwd`(首次使用时注册该工作区);两者同时提供时必须一致。创建时会广播全局 `event.session.created` 事件。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | body | string | 未提供 `metadata.cwd` 时**必填**。已注册的工作区 id;会话创建于该工作区的根目录 | -| `metadata` | body | object | 自定义元数据。`metadata.cwd` 为工作目录,未提供 `workspace_id` 时**必填**;两者同时提供时必须等于工作区根目录 | -| `title` | body | string | 初始标题(至少 1 个字符);否则会话无标题 | -| `agent_config` | body | object | schema 接受该字段但当前不会应用——模型与各模式请通过 `POST /api/v1/sessions/{session_id}/profile` 设置 | - -成功时,`data` 为新会话的 [session 对象](#session-对象)。 - -- `40001`:`workspace_id` 与 `metadata.cwd` 都未提供,或 `metadata.cwd` 与工作区根目录不一致(`details` 会列出该字段) -- `40409`:工作目录不存在或不是目录 -- `40410`:没有以该 `workspace_id` 注册的工作区 - -#### `GET /api/v1/sessions` - -跨工作区列出会话,按 `updated_at` 最新在前。游标分页遵循 [分页](#分页),但有一个特例:不提供 `page_size`(且不提供 `archived_only`)时,响应是单个不分页的窗口,其 `has_more` 恒为 `false`,因此要真正翻页请传入 `page_size`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `before_id` | query | string | 只保留早于该 id 的会话;与 `after_id` 互斥 | -| `after_id` | query | string | 只保留晚于该 id 的会话;与 `before_id` 互斥 | -| `page_size` | query | integer | 1–100。分页生效时默认为 `20`;不分页的默认行为见上文说明 | -| `busy` | query | boolean | 只保留忙碌(或只保留空闲)的会话 | -| `include_archive` | query | boolean | 在活跃会话之外同时包含已归档会话。默认 `false` | -| `archived_only` | query | boolean | 只保留已归档会话;与 `include_archive` 互斥;即使不提供 `page_size` 也会启用游标分页 | -| `exclude_empty` | query | boolean | 去掉没有任何用户提示词的会话 | -| `workspace_id` | query | string | 限定到单个工作区(别名会被解析) | - -成功时,`data` 为 `{ items, has_more }`,其中每个元素为 [session 对象](#session-对象)。 - -- `40001`:校验失败——例如 `before_id` 与 `after_id` 同用,或 `archived_only` 与 `include_archive` 同用 -- `40410`:未知的 `workspace_id` - -#### `GET /api/v1/sessions/{session_id}` - -从索引中读取单个会话。会话已加载到本进程时会包含实时状态字段;冷会话上报为不忙碌,并携带其最后持久化的轮次结果。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 [session 对象](#session-对象)。 - -- `40401`:会话不存在,或其工作区已无法解析 - -#### `GET /api/v1/sessions/{session_id}/profile` - -读取会话档案——与 `GET /api/v1/sessions/{session_id}` 相同的线上载荷。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 [session 对象](#session-对象)。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/profile` - -更新会话档案:标题、自定义元数据以及 main agent 的配置。在这里设置的标题会成为自定义标题,优先级高于生成的标题;设置标题会广播全局 `session.meta.updated` 事件。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `title` | body | string | 新标题(至少 1 个字符);会成为自定义标题 | -| `metadata` | body | object | 合并进会话自定义元数据的键 | -| `agent_config` | body | object | main agent 的部分配置;字段如下,均为可选 | - -每个 `agent_config` 字段都会立即应用到 main agent: - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `model` | string | 模型别名 id;空字符串会被忽略 | -| `thinking` | string | Thinking 强度等级 | -| `permission_mode` | string | `manual` / `yolo` / `auto` | -| `plan_mode` | boolean | 进入或退出 Plan 模式 | -| `swarm_mode` | boolean | 进入或退出 swarm 模式 | -| `goal_objective` | string | 以该文本为内容创建一个目标 | -| `goal_control` | string | `pause` / `resume` / `cancel` 当前目标 | - -schema 还接受 `agent_config` 内的 `system_prompt`、`tools`、`mcp_servers`,以及顶层的 `permission_rules` 数组,但更新路由当前不会应用它们。 - -成功时,`data` 为更新后的 [session 对象](#session-对象)。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/title/generate` - -通过托管供应商的 `chat_title` 工具根据会话的提示词生成标题并应用,同时广播 `session.meta.updated`。生成需要托管 OAuth 登录和 `auto_session_title` 实验开关;未提供 `force` 时,已有自定义标题或已生成标题的会话会上报为不可用,而不会被覆盖。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `force` | body | boolean | 即使已有自定义或生成的标题也重新生成。默认 `false` | -| `source` | body | string | 标题输入:`user_prompts`(默认)/ `first_turn` / `digest` | - -成功时,`data` 为 `{ title }`——当前应用到会话的标题。 - -- `40401`:会话不存在 -- `40923`:生成不可用——开关未开启、没有托管 OAuth 登录或尚无任何提示词内容、已有标题但未提供 `force`,或后端请求失败 - -#### `POST /api/v1/sessions/{session_id}:{action}` - -会话动作通过同一条路由分发:路径尾部解析为 `{session_id}:{action}`,请求体按该动作的 schema 校验,动作缺失或未知时返回 `40001`(`unsupported action: ...`)。每个动作都会先解析会话,因此会话未知时都可能返回 `40401`。支持的动作在下面逐一说明。 - -#### `POST /api/v1/sessions/{session_id}:fork` - -将会话——其转录、Agent 状态与文件——复制到同一工作区中的新会话,并广播 `event.session.created`。当会话中任一 Agent 有进行中的轮次时,fork 会被拒绝。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `title` | body | string | fork 的标题(至少 1 个字符)。默认 `Fork: <source title>` | -| `metadata` | body | object | fork 的自定义元数据 | - -成功时,`data` 为新会话的 [session 对象](#session-对象)。 - -- `40901`:会话有进行中的轮次,无法 fork - -#### `POST /api/v1/sessions/{session_id}:compact` - -对 main agent 的上下文发起一次手动全量压缩。调用立即返回;进度与完成通过 `compaction.*` WebSocket 事件投递。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `instruction` | body | string | 给压缩摘要的额外指引;空值会被忽略 | - -成功时,`data` 为空对象。 - -- `40910`:有轮次或其他上下文变更正在进行,或历史中没有可压缩的内容 - -#### `POST /api/v1/sessions/{session_id}:undo` - -将 main agent 的对话回退 `count` 个轮次,并同步修正派生的会话状态(包括会话的 `last_prompt`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `count` | body | integer | 要撤销的轮次数;正整数。默认 `1` | -| `page_size` | body | integer | 返回的历史窗口大小,1–100。默认 `50` | - -成功时,`data` 为 `{ messages, status }`:`messages` 是剩余上下文消息按最新在前的 `{ items, has_more }` 分页,`status` 与 `GET /api/v1/sessions/{session_id}/status` 的汇总相同。 - -- `40901`:有轮次正在进行或压缩正在运行——等其结束后重试 -- `40911`:无法撤销那么多轮次(遇到压缩边界或检查点丢失);`data` 携带 `{ reason, requestedCount, undoableCount }` - -#### `POST /api/v1/sessions/{session_id}:abort` - -取消 main agent 正在运行的轮次——等同于用户在 TUI 中中止轮次的程序化版本。 - -成功时,`data` 为 `{ aborted: true }`。 - -#### `POST /api/v1/sessions/{session_id}:btw` - -开启一个 `"by the way"` 旁路对话:把 main agent fork 成一个禁用工具调用的子 Agent,让快速的临时问题在隔离环境中运行,不触碰工作上下文。需要可用的模型配置。 - -成功时,`data` 为 `{ agent_id }`——新子 Agent 的 id。 - -#### `POST /api/v1/sessions/{session_id}:archive` - -将会话标记为已归档:它从默认会话列表中消失(使用 `include_archive` 或 `archived_only` 时仍会列出),并且服务端广播全局 `event.session.archived` 事件。 - -成功时,`data` 为 `{ archived: true }`。 - -#### `POST /api/v1/sessions/{session_id}:restore` - -取消会话的归档状态并恢复它。 - -成功时,`data` 为 `archived: false` 的 [session 对象](#session-对象)。 - -#### `GET /api/v1/sessions/{session_id}/children` - -列出会话的子会话——即通过 `POST /api/v1/sessions/{session_id}/children` 创建的会话。游标分页遵循 [分页](#分页)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `before_id` | query | string | 只保留早于该 id 的子会话;与 `after_id` 互斥 | -| `after_id` | query | string | 只保留晚于该 id 的子会话;与 `before_id` 互斥 | -| `page_size` | query | integer | 1–100。默认 `100` | -| `busy` | query | boolean | 只保留忙碌(或只保留空闲)的子会话 | - -成功时,`data` 为 `{ items, has_more }`,其中每个元素为 [session 对象](#session-对象)。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/children` - -创建子会话:fork 当前会话并记录为其子会话,因此会出现在 `GET /api/v1/sessions/{session_id}/children` 下。适用与 `:fork` 相同的进行中轮次限制。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `title` | body | string | 子会话的标题(至少 1 个字符)。默认 `Child: <source title>` | -| `metadata` | body | object | 子会话的自定义元数据 | - -成功时,`data` 为新会话的 [session 对象](#session-对象),并且服务端广播 `event.session.created`。 - -- `40901`:会话有进行中的轮次,无法 fork - -#### `GET /api/v1/sessions/{session_id}/status` - -main agent 的实时状态汇总;读取它会在会话为冷态时将其恢复。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `{ busy, model?, thinking_level, permission, plan_mode, swarm_mode, context_tokens, max_context_tokens?, context_usage? }`:`busy` 表示是否有进行中的轮次,`model` / `thinking_level` / `permission` 为当前生效的 Agent 设置,`plan_mode` / `swarm_mode` 为模式标志,`context_tokens` 与 `max_context_tokens`、`context_usage`(0–1)描述上下文窗口的占用情况。 - -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/goal` - -读取会话当前的目标快照;没有活跃目标时为 `null`。注意,与本 API 的大多数载荷不同,该载荷使用 camelCase 键。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `null` 或 `{ goalId, objective, completionCriterion?, status, turnsUsed, tokensUsed, wallClockMs, budget, terminalReason? }`,其中 `status` 为 `active` / `paused` / `blocked` / `complete`,`budget` 报告 token、轮次与 wall-clock 三项预算,以及各自的剩余量与每项预算的 reached 标志(未设置对应预算时各项为 null)。 - -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/warnings` - -读取会话级告警。目前的产生者只有 `AGENTS.md` 过大检查(`agents-md-oversized`),因此大多数会话的列表为空。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `{ warnings }`,每个条目为 `{ code, message, severity }`,其中 `severity` 为 `info` / `warning` / `error` 之一。 - -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/runtime` - -读取 main agent 的运行时绑定——即该会话的 Agent 循环运行在哪个运行时上。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `{ workspace_id, runtime_id }`。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/runtime` - -切换 main agent 的运行时绑定。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `runtime_id` | body | string | **必填。** 目标运行时 id | - -成功时,`data` 为新的绑定 `{ workspace_id, runtime_id }`。 - -- `40420`:不存在该 `runtime_id` 的运行时 -- `40926`:运行时存在但不可用 - -#### `POST /api/v1/sessions/{session_id}/export` - -将会话连同诊断日志一起导出为 zip 附件(`kimi-session-<id>.zip`)。响应是二进制流,不是 JSON 信封——能力与失败语义见 [二进制与流式端点](#二进制与流式端点)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `web_log` | body | string | 要包含在归档中的客户端日志文本,最多 256 KB UTF-8 | -| `desktop` | body | boolean | 同时包含桌面宿主的日志。默认 `false` | - -#### `GET /api/v1/sessions/{session_id}/snapshot` - -为重新同步后重建客户端组装一份原子快照:会话、最近的消息、进行中的轮次、存活的 subagent 以及待处理交互,全部盖上 `as_of_seq` 水位与用于重新订阅的 `epoch`——见 [断线恢复](#断线恢复)。与普通的会话端点不同,内嵌的会话携带实时的 `agent_config.model` 与真实的 `usage` 总计。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `{ as_of_seq, epoch, session, messages, in_flight_turn, subagents?, pending_approvals, pending_questions }`:`session` 为 [session 对象](#session-对象),`messages` 为最新 100 条消息的 `{ items, has_more }`,`in_flight_turn` 为已部分流式输出的轮次(空闲时为 `null`,已知时带 `current_prompt_id`),`subagents` 列出存活的 subagent 任务,`pending_approvals` / `pending_questions` 承载未答复的交互。 - -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/media/{file_id}` - -按文件 id 下载提示词媒体文件(会话提示词引用的图片或其他附件);尚未提交到会话的 id 会回退到暂存的上传中查找。响应为二进制并支持 `Range`(范围请求返回 206)——共享约定见 [二进制与流式端点](#二进制与流式端点);与那里走信封的端点不同,会话或文件不存在时会返回真正的 404 状态码并携带信封体。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `file_id` | path | string | **必填。** 媒体文件 id | - -### 消息与转录 - -`messages` 端点分页返回 main agent 的扁平化消息历史,`transcript` 端点则提供按 Agent 组织的结构化转录——轮次、任务、交互、附件——即 WebSocket [转录协议](#转录协议) 实时流式推送的内容。历史分页与补漏用这些端点,实时尾部用 WebSocket 订阅。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/messages` | 消息分页(`before_id` / `after_id` / `role`) | -| `GET /api/v1/sessions/{session_id}/messages/{message_id}` | 读取单条消息 | -| `GET /api/v1/sessions/{session_id}/transcript` | 按轮次分页的转录(需 `agent_id`);全局状态不分页随响应返回 | -| `GET /api/v1/sessions/{session_id}/transcript/ops` | op 批次补漏(`since_seq`);`complete: false` 表示需要全量刷新 | -| `GET /api/v1/sessions/{session_id}/transcript/user-messages` | 各轮次起始的用户输入,不分页 | -| `GET /api/v1/sessions/{session_id}/transcript/plan` | ExitPlanMode 计划内容、路径与审阅结果 | - -#### `GET /api/v1/sessions/{session_id}/messages` - -分页返回 main agent 的消息历史——与会话快照共享的扁平化上下文转录——最新在前。游标分页遵循 [分页](#分页);读取历史会在会话为冷态时将其恢复。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `before_id` | query | string | 只保留早于该消息 id 的消息;与 `after_id` 互斥 | -| `after_id` | query | string | 只保留晚于该消息 id 的消息;与 `before_id` 互斥 | -| `page_size` | query | integer | 1–100。默认 `50` | -| `role` | query | string | 只保留单一角色:`user` / `assistant` / `tool` / `system`。过滤在分页切片之后应用,因此过滤后的一页可能少于 `page_size` 条而 `has_more` 仍为 `true`——持续翻页直到 `has_more` 为 `false` | - -成功时,`data` 为 `{ items, has_more }`,其中每个元素是消息对象 `{ id, session_id, role, content, created_at, prompt_id?, parent_message_id?, metadata? }`;`content` 是按 [提示词](#提示词) 中说明的线上格式组成的内容块数组(`text`、`tool_use`、`tool_result`、`image`、`video`、`file`、`thinking`)。 - -- `40001`:校验失败——例如 `before_id` 与 `after_id` 同用 -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/messages/{message_id}` - -按 id 从同一历史中读取单条消息。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `message_id` | path | string | **必填。** 消息 id | - -成功时,`data` 为上文 `GET /api/v1/sessions/{session_id}/messages` 中说明的元素形态的消息对象。 - -- `40401`:会话不存在 -- `40403`:该会话中不存在此 id 的消息 - -#### `GET /api/v1/sessions/{session_id}/transcript` - -返回某个 Agent 的结构化转录中的一页:轮次(含其步骤与帧)以及轮次之间的标记与任务引用。活跃会话从内存存储应答(先回填所请求 Agent 的持久化历史);冷会话则从持久化的线上记录重建 Agent。这是转录能力的历史半边——实时流式半边是 [转录协议](#转录协议) 订阅。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `agent_id` | query | string | **必填。** 要读取其转录的 Agent;必须是纯文本形式的 agent id(字母、数字、`.`、`_`、`-`——不含路径分隔符) | -| `before_turn` | query | string | 只保留早于该轮次 id 的轮次;与 `after_turn` 互斥 | -| `after_turn` | query | string | 只保留晚于该轮次 id 的轮次;与 `before_turn` 互斥 | -| `page_size` | query | integer | 1–100 个轮次。默认 `20` | - -分页单位是轮次:不带游标时返回最新的一页,`has_more` 表示还有更早的轮次。成功时,`data` 为 `{ agent_id, items, has_more, tasks, interactions, attachments, todos, meta, agents, pending_interactions, seq? }`——`items` 是本次分页的轮次切片,`tasks` / `interactions` / `attachments` / `todos` / `meta` / `agents` / `pending_interactions` 是不分页、随每次响应一起返回的全局 Agent 状态,`seq` 是该 Agent 用于恢复流的 op 批次水位(仅活跃会话)。 - -- `40001`:校验失败——`before_turn` 与 `after_turn` 同用,或 `agent_id` 不是纯文本形式 -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/transcript/ops` - -从服务端的 op 日志提供点对点的补漏:某个 Agent 的 `seq > since_seq` 的已记录 op 批次,最旧在前。它是 [转录协议](#转录协议) 中 `transcript_since` 恢复游标的 REST 对应物,共享同一份有界日志,因此适用相同的回退规则。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `agent_id` | query | string | **必填。** Agent id(纯文本形式,约束与转录端点相同) | -| `since_seq` | query | integer | **必填。** 调用方已应用的最后一个 op 批次 seq,最小为 `0`;返回其之后的批次 | - -成功时,`data` 为 `{ agent_id, batches, latest_seq, complete }`,每个批次为 `{ seq, ops }`。`complete: true` 表示直到 `latest_seq` 的每个批次都在;`complete: false` 表示日志已不再覆盖到 `since_seq`(或会话根本不是活跃状态),调用方必须回退为一次完整的 `GET .../transcript` 刷新。 - -- `40001`:校验失败 -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/transcript/user-messages` - -列出会话中每个开启轮次的输入,按 Agent 分组且不分页:真实用户文本、以斜杠命令形式使用的 Skill 与插件命令、以及 cron 提示词——可通过 `origin` 区分——另有仅含附件的提示词,其 `prompt` 投影为空。所列消息引用的附件实体会随响应一起返回(仅元数据,绝不包含字节内容)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `agent_id` | query | string | 只读取一个 Agent(纯文本 id)。默认读取所有在册 Agent | - -成功时,`data` 为 `{ agents }`,每个条目为 `{ agent_id, messages, attachments }`;消息为 `{ turn_id, ordinal, state, origin, prompt, attachment_ids?, started_at? }`,其中 `state` 为轮次状态(`queued` / `running` / `completed` / `failed` / `cancelled`)。 - -- `40001`:校验失败——`agent_id` 不是纯文本形式 -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/transcript/plan` - -按时间线顺序读取某个 Agent 的 `ExitPlanMode` 工具调用的计划信息——计划内容、计划文件路径、提供的选项以及审阅结果。内容投影自第一个可用的事实来源:关联的审批交互(交互式审阅)、实时工具帧的展示(auto 模式),或工具结果的输出文本;每个条目在 `source` 中记录了具体来源。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `agent_id` | query | string | **必填。** Agent id(纯文本形式) | -| `tool_call_id` | query | string | 将读取范围限定到单次 `ExitPlanMode` 调用;不提供时列出所有可恢复计划内容的调用 | - -成功时,`data` 为 `{ agent_id, plans }`,每个计划为 `{ tool_call_id, turn_id, source, plan, path?, options?, review? }`:`source` 为 `interaction` / `display` / `output`,`options` 是审阅选项,形如 `{ label, description? }`,`review`(仅交互式审阅时存在)为 `{ state, selected_option?, feedback? }`,其中 `state` 为 `pending` / `approved` / `rejected` / `cancelled` 之一。 - -- `40001`:校验失败 -- `40401`:会话不存在 -- `40416`:提供了 `tool_call_id`,但不存在该 id 的 `ExitPlanMode` 调用 - -### 提示词 - -提示词是一次用户输入的单位:提交一条提示词会把它排入会话的 main agent(或指定 Agent)的队列,排队中的提示词可以插入进行中的轮次,运行中的提示词可以中止。轮次进度本身通过 WebSocket [事件](#事件) 流式推送,不经过这些端点。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/prompts` | 进行中与排队中的提示词 | -| `POST /api/v1/sessions/{session_id}/prompts` | 提交提示词(内容块数组,可带模型 / 权限模式覆盖) | -| `POST /api/v1/sessions/{session_id}/prompts:steer` | 把排队的提示词插入进行中的轮次 | -| `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort` | 中止运行中的提示词 | -| `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer` | 插入单条排队的提示词 | - -#### `GET /api/v1/sessions/{session_id}/prompts` - -读取 main agent 的提示词队列快照。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时,`data` 为 `{ active, queued }`:`active` 是运行中的提示词(空闲时为 `null`),`queued` 按顺序列出等待中的提示词。提示词为 `{ prompt_id, user_message_id, status, content, created_at }`,其中 `status` 为 `running` / `queued` / `blocked` 之一,`content` 采用 `POST /api/v1/sessions/{session_id}/prompts` 接受的内容块格式。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/prompts` - -向会话提交一条用户提示词。先校验媒体引用,然后把可选的覆盖项应用到目标 Agent——`profile`(与 `model` / `thinking` 一起绑定),接着是 `model`、`thinking`、`permission_mode` 和 `disabled_tools`——随后提示词入队;响应在提示词被接受后立即返回,不等待轮次执行。提供 `skills` 时,提示词以打包的 Skill 激活方式运行,而不是普通用户提示词。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `content` | body | array | **必填。** 非空的内容块数组;变体见下 | -| `agent_id` | body | string | 目标 Agent。默认为 main agent | -| `prompt_id` | body | string | 客户端选定的提示词 id,用于幂等提交;已被进行中提示词占用的 id 返回 `40927`,已完成的返回 `40903`。不能与 `skills` 同用 | -| `skills` | body | array | 打包的 Skill 激活,至少 1 个 `{ name, args? }` 条目;每个 Skill 必须存在且可由用户激活 | -| `profile` | body | string | 提交前要绑定的 Agent 档案 | -| `model` | body | string | 要切换到的模型别名 | -| `thinking` | body | string | Thinking 强度等级 | -| `permission_mode` | body | string | `manual` / `yolo` / `auto` | -| `disabled_tools` | body | array | 要为会话禁用的工具名 | - -schema 还接受 `metadata`、`plan_mode`、`swarm_mode`、`goal_objective` 和 `goal_control`,但提交路由当前不会应用它们。每个 `content` 内容块是按 `type` 区分的对象: - -| 内容块 | 字段 | 说明 | -| --- | --- | --- | -| `text` | `text` | 纯文本 | -| `image` / `video` | `source` | 媒体输入;`source` 为 `{ kind: "url", url, id? }`、`{ kind: "base64", media_type, data }`、`{ kind: "file", file_id }`(来自 `POST /api/v1/files` 的上传)或 `{ kind: "session_media", file_id }`(已提交到本会话的媒体)之一 | -| `file` | `file_id`、`name`、`media_type`、`size` | 通过 `POST /api/v1/files` 上传的文件附件 | - -schema 还接受共享消息格式中的 `tool_use`、`tool_result` 和 `thinking` 内容块,但它们在用户提示词中没有意义。未知或 kind 不匹配的 `file_id` 引用会在提示词创建之前、任何覆盖项应用之前被拒绝。 - -成功时,`data` 为被接受的提示词 `{ prompt_id, user_message_id, status, content, created_at }`。 - -- `40001`:校验失败——例如 `prompt_id` 与 `skills` 同用,或未知的 `profile` -- `40110`:尚未配置供应商——请先完成登录 -- `40111`:解析出的供应商没有凭据(`details.provider_id`) -- `40112`:供应商的凭据被拒绝(`details.provider_id`) -- `40113`:模型无法解析(已知时带 `details.model_id` / `details.provider_id`) -- `40401`:会话不存在 -- `40407`:引用的 `file_id` 不存在(或与内容块的媒体 kind 不匹配) -- `40415`:某个 `skills` 条目指向未知的 Skill -- `40903`:`prompt_id` 属于已完成的提示词;`data` 携带 `{ aborted: false }` -- `40912`:Skill 存在但无法由用户激活 -- `40927`:`prompt_id` 已被进行中的提示词占用 - -#### `POST /api/v1/sessions/{session_id}/prompts:steer` - -把排队的提示词插入进行中的轮次,让运行中的轮次立即消费它们,而不是先运行结束。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `prompt_ids` | body | array | **必填。** 非空的排队提示词 id 数组 | - -成功时,`data` 为 `{ steered: true, prompt_ids }`。 - -- `40001`:校验失败 -- `40401`:会话不存在 -- `40402`:所列提示词 id 不在队列中 - -#### `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:abort` - -中止运行中的提示词。本端点与下面的 `:steer` 通过同一条路由 `POST /api/v1/sessions/{session_id}/prompts/{tail}` 分发:尾部解析为 `{prompt_id}:{action}`,动作缺失或未知时返回 `40001`(`unsupported action: ...`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `prompt_id` | path | string | **必填。** 提示词 id | - -成功时,`data` 为 `{ aborted: true }`。 - -- `40401`:会话不存在 -- `40402`:不存在该 id 的提示词 -- `40903`:提示词已完成;`data` 携带 `{ aborted: false }` - -#### `POST /api/v1/sessions/{session_id}/prompts/{prompt_id}:steer` - -把单条排队的提示词插入进行中的轮次——是 `POST /api/v1/sessions/{session_id}/prompts:steer` 的单提示词形式。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `prompt_id` | path | string | **必填。** 排队中的提示词 id | - -成功时,`data` 为 `{ steered: true, prompt_ids: [prompt_id] }`。 - -- `40401`:会话不存在 -- `40402`:没有该 id 的排队提示词 - -### 审批与提问 - -审批与提问是会话的两类待处理交互:审批是为工具调用请求许可,提问是请求带标签选项的结构化输入。这些端点用于列出和答复它们;新的请求通过 WebSocket 以 `event.approval.requested` 与 `event.question.requested` 到达。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/approvals` | 列出待处理的审批请求(必须 `status=pending`) | -| `POST /api/v1/sessions/{session_id}/approvals/{approval_id}` | 答复审批 | -| `GET /api/v1/sessions/{session_id}/questions` | 列出待处理的提问(必须 `status=pending`) | -| `POST /api/v1/sessions/{session_id}/questions/{question_id}` | 回答提问 | -| `POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss` | 忽略提问 | - -#### `GET /api/v1/sessions/{session_id}/approvals` - -列出会话待处理的审批请求——即工具调用发起的权限提示。读取列表会在会话为冷态时将其恢复。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `status` | query | string | **必填。** 必须为 `pending` | - -成功时,`data` 为 `{ items }`,每个元素为 `{ approval_id, session_id, turn_id?, tool_call_id, tool_name, action, tool_input_display, created_at, expires_at }`:`tool_name` / `action` / `tool_input_display` 描述等待许可的调用,`expires_at` 为 `created_at` 之后 24 小时。 - -- `40001`:`status` 缺失或不是 `pending` -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/approvals/{approval_id}` - -答复一个待处理的审批请求,让等待中的工具调用继续执行(或不执行)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `approval_id` | path | string | **必填。** 审批请求 id | -| `decision` | body | string | **必填。** `approved` / `rejected` / `cancelled` | -| `scope` | body | string | 配合 `approved` 使用,`session`(唯一取值)还会让该审批规则在会话的剩余时间内被记住 | -| `feedback` | body | string | 回传给 Agent 的自由文本反馈 | -| `selected_label` | body | string | 当请求提供了带标签的选项时(例如计划审阅),所选选项的标签 | - -成功时,`data` 为 `{ resolved: true, resolved_at }`。 - -- `40001`:校验失败 -- `40401`:会话不存在 -- `40404`:没有该 id 的待处理审批 -- `40902`:审批已被答复;`data` 携带 `{ resolved: false }` - -#### `GET /api/v1/sessions/{session_id}/questions` - -列出会话待处理的提问。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `status` | query | string | **必填。** 必须为 `pending` | - -成功时,`data` 为 `{ items }`,每个元素为 `{ question_id, session_id, turn_id?, tool_call_id?, questions, created_at }`。`questions` 包含 1–4 个 `{ id, question, header?, body?, options, multi_select?, allow_other?, other_label?, other_description? }` 条目,每个条目带 2–4 个 `{ id, label, description? }` 形式的 `options`;`multi_select` 允许选择多个选项,`allow_other` 允许自由文本回答。 - -- `40001`:`status` 缺失或不是 `pending` -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/questions/{question_id}` - -回答一个待处理的提问。两个提问端点通过同一条路由 `POST /api/v1/sessions/{session_id}/questions/{tail}` 分发:单独的提问 id 表示回答问题,`{question_id}:dismiss` 尾部表示忽略问题,其他情况返回 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `question_id` | path | string | **必填。** 提问 id | -| `answers` | body | object | **必填。** 提问条目 id(`q_0`……)到答案对象的映射;变体见下 | -| `method` | body | string | 答案的产生方式:`enter` / `space` / `number_key` / `click` | -| `note` | body | string | 附在回答上的自由文本备注 | - -每个答案是按 `kind` 区分的对象: - -| kind 值 | 字段 | 说明 | -| --- | --- | --- | -| `single` | `option_id` | 选中的单个选项 | -| `multi` | `option_ids` | 选中的多个选项(至少 1 个) | -| `other` | `text` | 自由文本回答 | -| `multi_with_other` | `option_ids`、`other_text` | 选项加自由文本 | -| `skipped` | — | 跳过了该条目 | - -成功时,`data` 为 `{ resolved: true, resolved_at }`。 - -- `40001`:校验失败(`details` 列出每个字段) -- `40401`:会话不存在 -- `40405`:没有该 id 的待处理提问 -- `40902`:提问已被答复;`data` 携带 `{ resolved: false }` - -#### `POST /api/v1/sessions/{session_id}/questions/{question_id}:dismiss` - -忽略一个待处理的提问,不作回答。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `question_id` | path | string | **必填。** 提问 id | - -成功时信封的 `code` 是 `40909`(`question dismissed`)而不是 `0`,`data` 为 `{ dismissed: true, dismissed_at }`——客户端必须特殊处理该端点的成功码。 - -- `40401`:会话不存在 -- `40405`:没有该 id 的待处理提问 -- `40902`:提问已被答复;`data` 携带 `{ resolved: false }` - -### 后台任务 - -后台任务是会话的异步单元——后台 Shell、subagent 与长时间运行的工具任务。注册表仅包含实时数据:未加载到本服务进程中的会话会返回空列表。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/tasks` | 列出后台任务 | -| `GET /api/v1/sessions/{session_id}/tasks/{task_id}` | 读取任务(可选输出预览) | -| `POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel` | 取消任务 | - -#### `GET /api/v1/sessions/{session_id}/tasks` - -列出会话的后台任务。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `status` | query | string | 只保留单一状态:`running` / `completed` / `failed` / `cancelled` | - -成功时,`data` 为 `{ items }`,每个元素是任务对象 `{ id, session_id, kind, description, status, created_at, started_at?, completed_at?, command?, model?, thinking_effort?, agent_id?, subagent_type?, parent_tool_call_id?, output_preview?, output_bytes? }`。`kind` 为 `bash` / `subagent` / `tool`;`command` 仅在 `bash` 任务时设置,模型与 Agent 字段仅在 `subagent` 任务时设置,输出字段仅在以 `with_output` 读取任务时设置。超时与丢失的任务上报为 `failed`;被杀死的任务上报为 `cancelled`。 - -- `40001`:校验失败——未知的 `status` -- `40401`:会话不存在 - -#### `GET /api/v1/sessions/{session_id}/tasks/{task_id}` - -读取单个后台任务,可选携带输出的末尾片段。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `task_id` | path | string | **必填。** 任务 id | -| `with_output` | query | boolean | 在响应中包含输出末尾片段。默认 `false` | -| `output_bytes` | query | integer | 请求的输出末尾片段的字节大小,最小 `0`。默认 `32768` | - -成功时,`data` 为上文 `GET /api/v1/sessions/{session_id}/tasks` 中说明的任务对象;当 `with_output=true` 且输出非空时,`output_preview` 携带末尾片段文本,`output_bytes` 为其字节长度。 - -- `40001`:校验失败 -- `40401`:会话不存在 -- `40406`:没有该 id 的任务(冷会话完全没有实时任务) - -#### `POST /api/v1/sessions/{session_id}/tasks/{task_id}:cancel` - -取消运行中的任务。它通过 `POST /api/v1/sessions/{session_id}/tasks/{tail}` 分发,`cancel` 是唯一的动作——单独的任务 id 或未知动作返回 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `task_id` | path | string | **必填。** 任务 id | - -成功时,`data` 为 `{ cancelled: true }`。 - -- `40001`:动作后缀缺失或未知 -- `40401`:会话不存在 -- `40406`:没有该 id 的任务 -- `40904`:任务已结束;`data` 携带 `{ cancelled: false }`,`details.current_status` 为最终状态 - -### 技能、工具与 MCP - -这组端点暴露会话或工作区可见的技能目录、当前生效 agent 的工具列表及其 MCP 服务。技能激活与 MCP 重启使用 `:{action}` 约定;激活即斜杠命令 `/<skill>` 的 REST 等价形式。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/skills` | 会话级技能目录 | -| `GET /api/v1/workspaces/{workspace_id}/skills` | 无会话的工作区技能目录 | -| `POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate` | 激活技能(开启一个轮次) | -| `GET /api/v1/tools` | 列出当前生效 agent 的工具 | -| `GET /api/v1/mcp/servers` | 列出 MCP 服务 | -| `POST /api/v1/mcp/servers/{mcp_server_id}:restart` | 重启 MCP 服务 | - -#### `GET /api/v1/sessions/{session_id}/skills` - -列出单个会话可用的技能,按会话的优先级合并所有来源(内置、插件、extra、用户、项目)。会话处于冷态时,读取目录会恢复该会话。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时 `data` 为 `{ skills }`,每项是一个技能描述符 `{ name, description, path, source, type?, disable_model_invocation? }`:`source` 为 `project` / `user` / `extra` / `builtin`;`type` 标识技能类别(只有用户可激活的类型才能被激活);`disable_model_invocation` 会让技能对模型不可见。 - -- `40401`:会话不存在(或未激活) - -#### `GET /api/v1/workspaces/{workspace_id}/skills` - -列出该工作区中的会话将看到的技能目录,但不创建或恢复会话——即针对工作区根目录计算出的同一套内置、插件、extra、用户、项目来源合并结果。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 已注册工作区 id | - -成功时 `data` 为 `{ skills }`,技能描述符见上文 `GET /api/v1/sessions/{session_id}/skills` 的说明。 - -- `40410`:工作区不存在 - -#### `POST /api/v1/sessions/{session_id}/skills/{skill_name}:activate` - -在会话中激活技能——即斜杠命令 `/<skill>` 的 REST 等价形式——以技能内容加上 `args` 与附件在 main agent 上开启一个轮次。该端点经单一路由 `POST /api/v1/sessions/{session_id}/skills/{tail}` 分发:尾部按 `{skill_name}:{action}` 解析,`activate` 是唯一动作;只给名称或动作未知时返回 `40001`(`unsupported action: ...`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `skill_name` | path | string | **必填。** 要激活的技能名 | -| `args` | body | string | 传给技能的自由文本参数,相当于斜杠命令后的文本 | -| `attachments` | body | array | 随激活携带的媒体块。`image` / `video` 块带 `source` 对象(`kind` 为 `url` / `base64` / `file` / `session_media`,与提示词内容块同形);`file` 块带顶层 `file_id`、`name`、`media_type`、`size` | - -成功时 `data` 为 `{ activated: true, skill_name }`。 - -- `40001`:校验失败或动作后缀不支持 -- `40401`:会话不存在(或未激活) -- `40407`:引用的附件文件不存在 -- `40415`:没有该名称的技能 -- `40912`:技能存在,但其类型不允许用户激活 - -#### `GET /api/v1/tools` - -列出当前生效 agent 的工具——即 `session_id` 指定会话的 main agent;省略参数时取最近创建的会话。若该会话不在本服务进程中存活,列表为空。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | query | string | 要查看其 main agent 的会话。默认最近创建的会话 | - -成功时 `data` 为 `{ tools }`,每项为 `{ name, description, input_schema, source, mcp_server_id?, active? }`:`source` 为 `builtin` / `skill` / `mcp`;`mcp_server_id` 仅 MCP 工具携带(从 `mcp__<server>__<tool>` 名称解析);`active` 报告工具策略的判定结果。`input_schema` 目前恒为 `null`。 - -#### `GET /api/v1/mcp/servers` - -列出当前生效 agent 配置的 MCP 服务(与 `GET /api/v1/tools` 相同,取最近创建的存活会话的 main agent)。没有存活会话时列表为空。 - -成功时 `data` 为 `{ servers }`,每项为 `{ id, name, transport, status, last_error?, tool_count }`:`transport` 为 `stdio` / `http` / `sse`;`status` 为 `connected` / `connecting` / `disconnected` / `error`;服务处于 `error` 时 `last_error` 携带失败信息。 - -#### `POST /api/v1/mcp/servers/{mcp_server_id}:restart` - -重新连接当前生效 agent 的某个 MCP 服务。该端点经 `POST /api/v1/mcp/servers/{tail}` 分发,`restart` 是唯一动作——只给服务 id 或动作未知时返回 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `mcp_server_id` | path | string | **必填。** MCP 服务 id(即其配置名称) | - -成功时 `data` 为 `{ restarting: true }`。 - -- `40001`:缺少动作后缀或动作未知 -- `40408`:没有该 id 的 MCP 服务(无存活会话时同样返回此错误) - -### 能力与插件 - -能力是带有分层就绪状态的内置特性——由检测步骤加后台安装组成;当前版本注册了 `kimi-cu`(Kimi Computer Use)与 `kimi-webbridge`(Kimi WebBridge)。插件是已安装的技能、MCP 服务、hook 与命令的打包集合。这组端点报告能力状态、驱动能力安装,并管理插件从市场列表到移除的整个生命周期。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/capabilities` | 列出内置能力及其就绪状态 | -| `GET /api/v1/capabilities/{capability_id}` | 读取单个能力的状态 | -| `POST /api/v1/capabilities/{capability_id}:install` | 开始安装能力(后台进行,轮询 GET 查看进度) | -| `GET /api/v1/plugins` | 列出已安装插件 | -| `POST /api/v1/plugins` | 从本地路径、zip URL 或 GitHub 仓库安装插件 | -| `GET /api/v1/plugins/marketplace` | 插件市场目录,合并实时安装状态 | -| `POST /api/v1/plugins/{plugin_id}:{action}` | 插件动作:`enable` / `disable` / `remove` | - -#### `GET /api/v1/capabilities` - -列出所有已注册能力及其就绪状态。 - -成功时 `data` 为 `{ capabilities }`,每项是一个能力状态对象 `{ id, pluginId?, displayName, description, supported, state, version?, steps, install }`。`state` 为 `ready`(所有必需检测步骤均为 `ok`)/ `partial`(部分步骤 `ok`)/ `not_installed` / `unsupported`(当前平台/架构不可用);`steps` 以 `{ id, state, detail?, optional? }` 列出各检测步骤,其 `state` 为 `ok` / `missing` / `failed` 之一;`install` 为安装进度 `{ running, step?, percent?, error?, note? }`,其中 `percent` 取值 0 到 100。 - -#### `GET /api/v1/capabilities/{capability_id}` - -读取单个能力的就绪状态——即 `:install` 动作的轮询对应端点。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `capability_id` | path | string | **必填。** 能力 id | - -成功时 `data` 为上文 `GET /api/v1/capabilities` 说明的能力状态对象。 - -- `40418`:没有该 id 的能力 - -#### `POST /api/v1/capabilities/{capability_id}:install` - -在后台开始安装能力并立即返回当前状态(`install.running` 为 `true`);轮询 `GET /api/v1/capabilities/{capability_id}` 查看进度。该端点经 `POST /api/v1/capabilities/{tail}` 分发,`install` 是唯一动作——只给 id 或动作未知时返回 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `capability_id` | path | string | **必填。** 能力 id | - -成功时 `data` 为上文 `GET /api/v1/capabilities` 说明的能力状态对象。 - -- `40001`:缺少动作后缀或动作未知 -- `40418`:没有该 id 的能力 -- `40924`:该能力的安装已在进行中 -- `40925`:当前平台/架构不支持该能力 - -#### `GET /api/v1/plugins` - -列出已安装插件。 - -成功时 `data` 为 `{ plugins }`,每项为 `{ id, displayName, version?, enabled, state, skillCount, mcpServerCount, enabledMcpServerCount, hookCount, commandCount, hasErrors, source, originalSource?, github? }`:`state` 为 `ok` / `error`(加载失败也会置 `hasErrors`);`source` 为 `local-path` / `zip-url` / `github`;GitHub 来源的插件由 `github` 携带来源信息 `{ owner, repo, ref, installedSha? }`,其中 `ref` 为 `{ kind: branch|tag|sha, value }`。 - -#### `POST /api/v1/plugins` - -安装插件并返回其摘要。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `source` | body | string | **必填。** 安装来源:本地绝对路径、指向 zip 压缩包的 `http(s)` URL,或 GitHub URL——`https://github.com/<owner>/<repo>`,可选地用 `/tree/<branch-or-sha>`、`/releases/tag/<tag>` 或 `/commit/<sha>` 锁定版本 | - -成功时 `data` 为上文 `GET /api/v1/plugins` 说明的插件摘要。 - -- `40001`:校验失败——例如 `source` 既不是 URL 也不是绝对路径,或插件加载失败 -- `40409`:本地路径不存在 - -#### `GET /api/v1/plugins/marketplace` - -列出插件市场目录并合并实时安装状态。目录按请求从配置的市场 URL 拉取(超时 10 秒);使用默认目录时,目录中缺少的内置能力会作为条目合并进来(带 `capabilityId`),而当前平台不支持的能力对应条目会被剔除。 - -成功时 `data` 为 `{ entries }`,每项为 `{ id, tier, displayName, description?, homepage?, keywords?, version?, source, installed?, updateAvailable?, capabilityId? }`:`tier` 为 `official` / `curated` / `third-party`;插件已安装时 `installed` 为 `{ version?, enabled }`;`updateAvailable` 标记目录版本新于已安装版本的条目。条目的 `source` 即 `POST /api/v1/plugins` 的 `source` 字段取值。 - -- `50001`:市场不可达或返回了非法目录 - -#### `POST /api/v1/plugins/{plugin_id}:enable` - -启用一个已安装插件。插件动作经单一路由 `POST /api/v1/plugins/{tail}` 分发:尾部按 `{plugin_id}:{action}` 解析,动作为 `enable` / `disable` / `remove`;只给 id 或动作未知时返回 `40001`(`unsupported action: ...`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **必填。** 已安装插件 id | - -成功时 `data` 为 `{ ok: true }`。 - -- `40001`:缺少动作后缀或动作未知 -- `40419`:没有该 id 的已安装插件 - -#### `POST /api/v1/plugins/{plugin_id}:disable` - -停用一个已安装插件但不移除它;分发约定同上文 `:enable`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **必填。** 已安装插件 id | - -成功时 `data` 为 `{ ok: true }`。 - -- `40001`:缺少动作后缀或动作未知 -- `40419`:没有该 id 的已安装插件 - -#### `POST /api/v1/plugins/{plugin_id}:remove` - -移除一个已安装插件;分发约定同上文 `:enable`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `plugin_id` | path | string | **必填。** 已安装插件 id | - -成功时 `data` 为 `{ ok: true }`。 - -- `40001`:缺少动作后缀或动作未知 -- `40419`:没有该 id 的已安装插件 - -### 终端 - -PTY 终端接口;仅在 loopback 绑定时挂载(非 loopback 绑定会跳过它们,除非传入 `--allow-remote-terminals`)。终端的输入、输出与尺寸调整经 WebSocket 的 `terminal_*` 帧传输——REST 侧只管理终端生命周期。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/sessions/{session_id}/terminals` | 列出终端 | -| `POST /api/v1/sessions/{session_id}/terminals` | 创建终端 | -| `GET /api/v1/sessions/{session_id}/terminals/{terminal_id}` | 读取终端 | -| `POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close` | 关闭终端 | - -#### `GET /api/v1/sessions/{session_id}/terminals` - -列出会话的终端。会话处于冷态时,读取列表会恢复该会话。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | - -成功时 `data` 为 `{ items }`,每项是一个终端对象 `{ id, session_id, cwd, shell, cols, rows, status, created_at, exited_at?, exit_code? }`:`status` 为 `running` / `exited`;已退出的终端携带 `exited_at` 与 `exit_code`(进程未报告退出码时为 `null`,例如因信号终止)。回滚缓冲不属于该对象——输出经 WebSocket 回放与流式推送。 - -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/terminals` - -为会话创建一个 PTY 终端。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `runtime_id` | body | string | 生成终端进程的运行时。默认 `local` | -| `cwd` | body | string | 工作目录,相对于会话工作区(传绝对路径会校验失败)。默认工作区根目录 | -| `shell` | body | string | Shell 可执行文件。默认该运行时的 shell | -| `cols` | body | integer | 终端宽度,正数。默认 `80` | -| `rows` | body | integer | 终端高度,正数。默认 `24` | - -成功时 `data` 为上文 `GET /api/v1/sessions/{session_id}/terminals` 说明的终端对象。 - -- `40001`:校验失败(`details` 逐字段说明) -- `40401`:会话不存在 -- `41304`:`cwd` 解析后越出会话工作区 - -#### `GET /api/v1/sessions/{session_id}/terminals/{terminal_id}` - -读取单个终端。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `terminal_id` | path | string | **必填。** 终端 id | - -成功时 `data` 为上文 `GET /api/v1/sessions/{session_id}/terminals` 说明的终端对象。 - -- `40401`:会话不存在 -- `40414`:没有该 id 的终端 - -#### `POST /api/v1/sessions/{session_id}/terminals/{terminal_id}:close` - -关闭终端并结束其进程。该端点经 `POST /api/v1/sessions/{session_id}/terminals/{tail}` 分发,`close` 是唯一动作——只给 id 或动作未知时返回 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `terminal_id` | path | string | **必填。** 终端 id | - -成功时 `data` 为 `{ closed: true }`。 - -- `40001`:缺少动作后缀或动作未知 -- `40401`:会话不存在 -- `40414`:没有该 id 的终端 - -### 工作区 - -工作区是已注册的项目目录,会话都落在其中。这组端点管理注册表——列出、注册、重命名、注销——以及控制项目级 MCP 配置是否加载的每工作区信任状态。所有返回工作区的端点都使用 [workspace 对象](#workspace-对象) 中统一说明的传输结构。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/workspaces` | 列出已注册工作区 | -| `POST /api/v1/workspaces` | 注册工作区(按根路径幂等) | -| `PATCH /api/v1/workspaces/{workspace_id}` | 重命名 | -| `DELETE /api/v1/workspaces/{workspace_id}` | 注销(保留磁盘内容) | -| `GET /api/v1/workspaces/{workspace_id}/trust` | 读取信任状态 | -| `POST /api/v1/workspaces/{workspace_id}/trust` | 授予信任 | -| `POST /api/v1/workspaces/{workspace_id}/untrust` | 撤销信任 | - -#### workspace 对象 - -所有返回工作区的端点都使用此传输结构。注册与重命名会广播全局事件 `event.workspace.created` / `event.workspace.updated`。 - -| 字段 | 类型 | 说明 | -| --- | --- | --- | -| `id` | string | 工作区 id,由根路径派生的 `wd_<slug>_<hash12>` 字符串 | -| `root` | string | 项目目录的绝对路径 | -| `name` | string | 显示名,1–100 个字符;默认取根目录的基名 | -| `created_at` | string | 注册时间,ISO 8601 | -| `last_opened_at` | string | 最近一次打开或重新注册工作区的时间,ISO 8601 | -| `session_count` | integer | 工作区内的会话数 | - -#### `GET /api/v1/workspaces` - -列出所有已注册工作区。 - -成功时 `data` 为 `{ items }`,每项是一个 [workspace 对象](#workspace-对象)。 - -#### `POST /api/v1/workspaces` - -注册工作区并返回它。注册按根路径幂等:重复注册同一根路径会返回已存在的工作区,仅刷新 `last_opened_at`(保留已存名称),并广播 `event.workspace.updated` 而非 `event.workspace.created`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `root` | body | string | **必填。** 已存在目录的绝对路径 | -| `name` | body | string | 显示名,1–100 个字符。默认根目录的基名 | - -成功时 `data` 为 [workspace 对象](#workspace-对象)。 - -- `40001`:`root` 缺失或不是绝对路径(`details` 会列出该字段) -- `40409`:`root` 不存在或不是目录 - -#### `PATCH /api/v1/workspaces/{workspace_id}` - -重命名工作区——仅修改显示名,根路径不变。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 工作区 id | -| `name` | body | string | **必填。** 新的显示名,1–100 个字符 | - -成功时 `data` 为 [workspace 对象](#workspace-对象)。 - -- `40001`:校验失败(`details` 逐字段说明) -- `40410`:工作区不存在 - -#### `DELETE /api/v1/workspaces/{workspace_id}` - -注销工作区。只移除注册表条目——磁盘上的目录不受影响。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 工作区 id | - -成功时 `data` 为 `{ deleted: true }`。 - -- `40410`:工作区不存在 - -#### `GET /api/v1/workspaces/{workspace_id}/trust` - -读取工作区信任状态。信任状态决定是否为该工作区加载项目级 MCP 配置。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 工作区 id | - -成功时 `data` 为 `{ trusted }`。 - -- `40410`:工作区不存在 - -#### `POST /api/v1/workspaces/{workspace_id}/trust` - -将工作区标记为信任,并加载其项目级 MCP 配置。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 工作区 id | - -成功时 `data` 为 `{ trusted: true }`。 - -- `40410`:工作区不存在 - -#### `POST /api/v1/workspaces/{workspace_id}/untrust` - -撤销工作区信任,并卸载其项目级 MCP 配置。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace_id` | path | string | **必填。** 工作区 id | - -成功时 `data` 为 `{ trusted: false }`。 - -- `40410`:工作区不存在 - -### 文件系统 - -会话内文件操作走 `POST /api/v1/sessions/{session_id}/fs:{action}`,请求体为 JSON;动作包括 `list` / `read` / `list_many` / `stat` / `stat_many` / `mkdir` / `search` / `grep` / `git_status` / `diff` / `open` / `open-in` / `reveal`。每个动作的请求体还接受可选的 `runtime_id`(string,默认 `local`),用于选择执行操作的运行时;`open`、`open-in` 与 `reveal` 仅在 `local` 运行时上可用。另有: - -| 方法与路径 | 说明 | -| --- | --- | -| `POST /api/v1/workspace/fs:search` | 无会话的工作区搜索(body 携带工作区引用) | -| `POST /api/v1/workspace/fs:suggest` | 无会话的文件补全候选(用于 `@` 文件提及) | -| `GET /api/v1/sessions/{session_id}/fs/{path}:download` | 下载会话文件(二进制,见下文) | -| `GET /api/v1/fs:browse` | 列出本机目录(文件夹选择器用) | -| `GET /api/v1/fs:home` | 用户主目录与最近工作区 | -| `GET /api/v1/fs:content` | 读取本机任意文件原始字节(仅受 token 保护,谨慎暴露端口) | -| `POST /api/v1/fs:mkdir` | 按绝对路径创建目录 | - -#### `POST /api/v1/sessions/{session_id}/fs:list` - -列出会话工作区目录下的条目,可选递归子目录。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | 要列出的目录,相对于会话工作目录。默认 `.` | -| `depth` | body | integer | 递归深度,1–10。默认 `1` | -| `limit` | body | integer | 最大条目数,1–1000。默认 `200` | -| `show_hidden` | body | boolean | 包含点文件。默认 `false` | -| `follow_gitignore` | body | boolean | 跳过 gitignore 的路径。默认 `true` | -| `exclude_globs` | body | string[] | 额外要跳过的 glob | -| `sort` | body | string | `type_first`(默认)/ `name_asc` / `name_desc` / `mtime_desc` / `size_desc` | -| `include_git_status` | body | boolean | 附带每个条目的 git 状态。默认 `false` | - -成功时 `data` 为 `{ items, truncated }`——`depth` 大于 1 时另附 `children_by_path`(路径 → 条目的映射)。每项是一个条目对象 `{ path, name, kind, size?, modified_at, etag?, mime?, language_id?, is_binary?, is_symlink_to?, git_status?, child_count? }`,其中 `kind` 为 `file` / `directory` / `symlink`;`git_status`(仅 `include_git_status: true` 时存在)为 `clean` / `modified` / `added` / `deleted` / `renamed` / `untracked` / `ignored` / `conflicted` 之一;`truncated` 表示 `limit` 截断了列表。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在(包括 `path` 不是目录的情况) -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:read` - -以文本或 base64 读取会话文件的一段内容。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 文件路径,相对于会话工作目录 | -| `offset` | body | integer | 起始字节偏移。默认 `0` | -| `length` | body | integer | 读取字节数,1–10485760(10 MiB)。默认 `1048576`(1 MiB) | -| `encoding` | body | string | `auto`(默认)/ `utf-8` / `base64` | - -成功时 `data` 为 `{ path, content, encoding, size, truncated, etag, mime, language_id?, line_count?, is_binary }`,其中 `encoding` 报告实际使用的编码(`utf-8` 或 `base64`),`size` 为文件完整大小。`encoding: "auto"` 时文本以 `utf-8` 返回(非 UTF-8 文本会被转码),二进制内容以 `base64` 返回;`encoding: "utf-8"` 强制按文本读取并拒绝二进制文件。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `40906`:路径是目录 -- `40907`:二进制文件却指定了 `encoding: "utf-8"` -- `41302`:文件超过 10 MiB 读取上限 -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:list_many` - -一次调用列出多个会话目录;失败的路径会折进响应里,而不是让整个请求失败。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `paths` | body | string[] | **必填。** 要列出的目录,1–100 条 | - -其余请求体字段(`depth`、`limit`、`show_hidden`、`follow_gitignore`、`exclude_globs`、`sort`、`include_git_status`)的类型、取值范围与默认值同 `fs:list`。成功时 `data` 为 `{ results }`——每个请求路径到其条目数组(条目对象见 `fs:list` 的说明)的映射,另附 `truncated_paths`(达到 `limit` 的路径)与 `partial_errors`(失败路径到其 `{ code, msg }` 错误的映射)。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/fs:stat` - -查询会话工作区内单个路径的元信息。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 要查询的路径,相对于会话工作目录 | - -成功时 `data` 为 `fs:list` 中说明的条目对象。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:stat_many` - -一次调用查询多个会话路径的元信息;不存在的路径返回 `null`,不会让整个请求失败。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `paths` | body | string[] | **必填。** 要查询的路径,1–1000 条 | - -成功时 `data` 为 `{ entries }`——每个请求路径到其条目对象(见 `fs:list` 的说明)的映射,路径不存在时为 `null`。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 - -#### `POST /api/v1/sessions/{session_id}/fs:mkdir` - -在会话工作区内创建目录。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 要创建的目录,相对于会话工作目录 | -| `recursive` | body | boolean | 创建缺失的父目录。默认 `false` | - -成功时 `data` 为所建目录的条目对象(见 `fs:list` 的说明)。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:父目录不存在(非递归创建) -- `40919`:路径已存在(非递归创建) -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:search` - -在会话工作区内模糊搜索文件与目录名。`query` 为空时改为列出顶层条目。当 `{session_id}` 位置携带的是工作区引用(已注册工作区 id 或绝对根路径)而非会话 id 时,搜索针对该工作区执行——这是为尚未创建的草稿会话准备的无会话形式;正式的无会话端点是 `POST /api/v1/workspace/fs:search`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id,或工作区引用 | -| `query` | body | string | **必填。** 搜索文本;`""` 表示列出顶层 | -| `limit` | body | integer | 最大命中数,1–200。默认 `50` | -| `include_globs` | body | string[] | 只保留匹配这些 glob 之一的路径 | -| `exclude_globs` | body | string[] | 跳过匹配这些 glob 的路径 | -| `follow_gitignore` | body | boolean | 跳过 gitignore 的路径。默认 `true` | - -成功时 `data` 为 `{ items, truncated }`,每项为 `{ path, name, kind, score, match_positions }`——`kind` 为 `file` / `directory` / `symlink`,`score` 为 0 到 1 之间的模糊匹配得分,`match_positions` 列出匹配到的字符偏移。命中按得分排序(同分按路径),`truncated` 表示超出 `limit` 的命中被丢弃。 - -- `40001`:请求体校验失败 -- `40401`:该引用既不是会话,也不是可解析的工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:grep` - -在会话工作区内搜索文件内容——默认按字面字符串,`regex: true` 时按正则表达式。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `pattern` | body | string | **必填。** 要搜索的文本或正则 | -| `regex` | body | boolean | 将 `pattern` 视为正则表达式。默认 `false` | -| `case_sensitive` | body | boolean | 默认 `true` | -| `include_globs` | body | string[] | 只保留匹配这些 glob 之一的文件 | -| `exclude_globs` | body | string[] | 跳过匹配这些 glob 的文件 | -| `follow_gitignore` | body | boolean | 跳过 gitignore 的路径。默认 `true` | -| `max_files` | body | integer | 最多扫描的文件数,1–10000。默认 `200` | -| `max_matches_per_file` | body | integer | 每个文件保留的匹配数,1–10000。默认 `50` | -| `max_total_matches` | body | integer | 总共保留的匹配数,1–100000。默认 `5000` | -| `context_lines` | body | integer | 每个匹配携带的上下文行数,0–10。默认 `2` | - -成功时 `data` 为 `{ files, files_scanned, truncated, elapsed_ms }`,其中 `files` 的每项为 `{ path, matches }`,每个匹配为 `{ line, col, text, before, after }`(`before` / `after` 最多携带 `context_lines` 行上下文);`truncated` 表示某个匹配配额截断了结果。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `41305`:搜索超时 - -#### `POST /api/v1/sessions/{session_id}/fs:git_status` - -读取会话工作区的 git 状态,可选限定在一组路径内。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `paths` | body | string[] | 将状态限定在这些路径;省略表示整个工作区 | - -成功时 `data` 为 `{ branch, ahead, behind, entries, additions, deletions, pullRequest }`,其中 `entries` 把每个变更路径映射到其状态(`clean` / `modified` / `added` / `deleted` / `renamed` / `untracked` / `ignored` / `conflicted`),`pullRequest` 为 `{ number, state, url }`(`state` 为 `open` / `merged` / `closed` / `draft`)或 `null`。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40908`:git 不可用(不是仓库,或没有 git 可执行文件) - -#### `POST /api/v1/sessions/{session_id}/fs:diff` - -返回会话工作区内单个文件的 unified git diff。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 要 diff 的文件,相对于会话工作目录 | - -成功时 `data` 为 `{ path, diff, truncated }`,其中 `diff` 为 unified diff 文本,`truncated` 表示过长的 diff 被截断。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40908`:git 不可用(不是仓库,或没有 git 可执行文件) -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:open` - -用宿主操作系统的默认程序打开会话文件。仅限 local 运行时。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 要打开的文件,相对于会话工作目录 | -| `line` | body | integer | 在处理程序支持时跳转到的行号(正整数) | - -成功时 `data` 为 `{ opened: true }`。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/sessions/{session_id}/fs:open-in` - -在指定的宿主应用程序中打开会话文件或目录。仅限 local 运行时。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `app_id` | body | string | **必填。** 目标应用:`finder` / `cursor` / `vscode` / `iterm` / `terminal` | -| `path` | body | string | **必填。** 要打开的文件或目录,相对于会话工作目录 | -| `line` | body | integer | 在应用支持时跳转到的行号(正整数) | - -成功时 `data` 为 `{ opened: true }`。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `41304`:路径越出会话工作区 -- `50001`:应用启动失败 - -#### `POST /api/v1/sessions/{session_id}/fs:reveal` - -在宿主操作系统的文件管理器中显示会话文件。仅限 local 运行时。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | body | string | **必填。** 要显示的文件,相对于会话工作目录 | - -成功时 `data` 为 `{ revealed: true }`。 - -- `40001`:请求体校验失败 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `41304`:路径越出会话工作区 - -#### `GET /api/v1/sessions/{session_id}/fs/{path}:download` - -从会话工作区下载文件;`{path}` 是相对于工作区的文件路径,并带字面量 `:download` 后缀。响应为支持 Range 与 ETag 的二进制流——见 [二进制与流式端点](#二进制与流式端点)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `session_id` | path | string | **必填。** 会话 id | -| `path` | path | string | **必填。** 相对于工作区的文件路径,加 `:download` 后缀 | -| `runtime_id` | query | string | 从哪个运行时读取。默认 `local` | - -- `40001`:路径缺失或为空 -- `40401`:会话不存在 -- `40409`:路径不存在 -- `41304`:路径越出会话工作区 - -#### `POST /api/v1/workspace/fs:search` - -`fs:search` 的无会话形式:工作区改由请求体而非 URL 携带。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace` | body | string | **必填。** 已注册工作区 id 或绝对根路径(当场注册) | -| `query` | body | string | **必填。** 搜索文本;`""` 表示列出顶层 | -| `limit` | body | integer | 最大命中数,1–200。默认 `50` | -| `include_globs` | body | string[] | 只保留匹配这些 glob 之一的路径 | -| `exclude_globs` | body | string[] | 跳过匹配这些 glob 的路径 | -| `follow_gitignore` | body | boolean | 跳过 gitignore 的路径。默认 `true` | -| `runtime_id` | body | string | 在哪个运行时上搜索。默认 `local` | - -成功时 `data` 为 `{ items, truncated }`,命中结构与排序同 `fs:search`。 - -- `40001`:请求体校验失败 -- `40410`:工作区不存在,且不是可用的绝对路径 - -#### `POST /api/v1/workspace/fs:suggest` - -在无会话的情况下给出工作区内的文件与目录补全候选——即输入框中 `@` 文件提及的后端。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `workspace` | body | string | **必填。** 已注册工作区 id 或绝对根路径(当场注册) | -| `query` | body | string | **必填。** 要补全的部分路径文本 | -| `limit` | body | integer | 最大候选数,1–200。默认 `50` | -| `follow_gitignore` | body | boolean | 跳过 gitignore 的路径。默认 `true` | -| `show_hidden` | body | boolean | 包含点文件。默认 `false` | -| `include_globs` | body | string[] | 只保留匹配这些 glob 之一的路径 | -| `exclude_globs` | body | string[] | 跳过匹配这些 glob 的路径 | -| `runtime_id` | body | string | 在哪个运行时上补全。默认 `local` | - -成功时 `data` 为 `{ items, truncated }`,每项为 `{ path, name, kind, score, match_positions }`,命中结构同 `fs:search`。 - -- `40001`:请求体校验失败 -- `40410`:工作区不存在,且不是可用的绝对路径 - -#### `GET /api/v1/fs:browse` - -列出某个本机目录的子目录——文件夹选择器的后端。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `path` | query | string | 绝对目录路径。默认用户主目录 | - -成功时 `data` 为 `{ path, parent, entries }`,其中 `path` 为解析后的目录,`parent` 为其父目录(文件系统根处为 `null`),每条目为 `{ name, path, is_dir: true }`。 - -- `40001`:`path` 不是绝对路径 -- `40409`:路径不存在 -- `40411`:权限不足 - -#### `GET /api/v1/fs:home` - -返回文件夹选择器的落地数据。无参数。 - -成功时 `data` 为 `{ home, recent_roots }`,其中 `home` 为用户主目录,`recent_roots` 列出已注册工作区的根目录。 - -#### `GET /api/v1/fs:content` - -以流式返回本机文件系统上任意文件的原始字节——仅受 API token 保护,暴露端口时务必谨慎。支持 Range 请求与 ETag 缓存;见 [二进制与流式端点](#二进制与流式端点)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `path` | query | string | **必填。** 绝对文件路径 | - -- `40001`:`path` 不是绝对路径,或不是普通文件 -- `40409`:路径不存在 -- `40411`:权限不足 -- `40906`:路径是目录 - -#### `POST /api/v1/fs:mkdir` - -按绝对路径在本机文件系统上创建一个目录——文件夹选择器「新建文件夹」的后端。非递归:父目录必须已存在。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `path` | body | string | **必填。** 绝对目录路径 | - -成功时 `data` 为 `{ path }`。 - -- `40001`:`path` 不是绝对路径 -- `40409`:父路径不存在 -- `40411`:权限不足 -- `40919`:路径已存在 - -### 文件上传 - -| 方法与路径 | 说明 | -| --- | --- | -| `POST /api/v1/files` | multipart 上传(字段 `file`,可选 `name`、`expires_in_sec`),返回文件元信息 | -| `GET /api/v1/files/{file_id}` | 下载(二进制,错误用真实 HTTP 状态码) | -| `DELETE /api/v1/files/{file_id}` | 删除 | - -#### `POST /api/v1/files` - -以 `multipart/form-data` 上传文件,供后续引用(例如作为提示词附件)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `file` | body | binary | **必填。** multipart 的文件部分 | -| `name` | body | string | 存储的显示名。默认上传文件名 | -| `expires_in_sec` | body | number | 文件过期前的秒数(非负)。默认永不过期 | - -成功时 `data` 为文件元信息 `{ id, name, media_type, size, created_at, expires_at? }`,其中 `media_type` 取自上传的内容类型。 - -- `40001`:multipart 请求体缺少 `file` 字段 - -#### `GET /api/v1/files/{file_id}` - -下载已上传的文件。响应为二进制流,支持 Range 请求但不处理 `If-None-Match`;失败使用真实 HTTP 状态码——见 [二进制与流式端点](#二进制与流式端点)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `file_id` | path | string | **必填。** 上传响应返回的文件 id | - -- `40407`(HTTP 404):没有该 id 的文件(包括已过期的文件) - -#### `DELETE /api/v1/files/{file_id}` - -删除已上传的文件。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `file_id` | path | string | **必填。** 上传响应返回的文件 id | - -成功时 `data` 为 `{ deleted: true }`。 - -- `40407`(HTTP 404):没有该 id 的文件 - -### GUI 存储 - -由服务端支撑的键值存储,接口对齐浏览器的 `localStorage`,持久化在服务的 home 目录下;web UI 用它保存跨客户端的 UI 状态。值是不透明字符串——序列化由调用方负责。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v1/gui/store/length` | 已存键的数量 | -| `GET /api/v1/gui/store/getItem` | 按键读取值 | -| `POST /api/v1/gui/store/setItem` | 按键写入值 | -| `POST /api/v1/gui/store/removeItem` | 按键删除值 | -| `POST /api/v1/gui/store/clear` | 删除所有值 | - -#### `GET /api/v1/gui/store/length` - -返回已存键的数量(对齐 `localStorage.length`)。无参数。 - -成功时 `data` 为 `{ length }`。 - -#### `GET /api/v1/gui/store/getItem` - -读取一个值(对齐 `localStorage.getItem`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `key` | query | string | **必填。** 要读取的键,1–256 个字符 | - -成功时 `data` 为 `{ value }`——已存字符串,键不存在时为 `null`。 - -#### `POST /api/v1/gui/store/setItem` - -写入一个值(对齐 `localStorage.setItem`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `key` | body | string | **必填。** 要写入的键,1–256 个字符 | -| `value` | body | string | **必填。** 要存储的值 | - -成功时 `data` 为 `null`。 - -#### `POST /api/v1/gui/store/removeItem` - -删除一个值(对齐 `localStorage.removeItem`)。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `key` | body | string | **必填。** 要删除的键,1–256 个字符 | - -成功时 `data` 为 `null`。 - -#### `POST /api/v1/gui/store/clear` - -删除所有已存值(对齐 `localStorage.clear`)。无参数。 - -成功时 `data` 为 `null`。 - -### 全局搜索与其他 - -| 方法与路径 | 说明 | -| --- | --- | -| `POST /api/v1/search` | 跨会话全文搜索,`mode` 为 `terms`(默认)或 `literal`(精确子串),`page_token` 分页 | -| `GET /api/v1/connections` | 列出当前在线的 WebSocket 连接 | -| `GET /api/v2/sessions` | 新一代会话列表,见下文 | -| `POST /api/v2/sessions:archive` | 批量归档会话,见下文 | -| `POST /api/v2/sessions:restore` | 批量恢复已归档会话,见下文 | -| `/api/v2/mcp/*` | 统一的 MCP 管理面,见下文 | -| `/api/v1/debug/*` | 反射式调试 RPC,仅 `--debug-endpoints` 且 loopback 时挂载,不属于稳定协议 | - -#### `POST /api/v1/search` - -跨会话全文搜索,覆盖 User 消息、Assistant 回复与会话标题,由服务端的持久搜索索引支撑。当 `container.session_id` 指向本服务进程中存活的会话时,搜索改为直接扫描该会话的内存转录,响应的 `source` 字段(`index` 或 `live`)会报告本页结果由哪条路径提供。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `query` | body | string | **必填。** 搜索文本 | -| `mode` | body | string | `terms`(默认)/ `literal` | -| `op` | body | string | `terms` 模式下的词项组合符:`AND`(默认)/ `OR` | -| `container` | body | object | 将搜索限定在 `{ session_id?, agent_id? }` | -| `role` | body | string | 限定 `user` / `assistant` / `title` 命中 | -| `start_time` | body | integer | 只看不早于该时间的命中(epoch 毫秒) | -| `end_time` | body | integer | 只看不晚于该时间的命中(epoch 毫秒) | -| `sort` | body | string | `score`(默认)/ `time_desc` / `time_asc`;`literal` 模式忽略此参数,始终最新在前 | -| `page_size` | body | integer | 每页命中数,1–50。默认 `20` | -| `page_token` | body | string | 上一页响应返回的令牌 | - -`terms` 模式下查询会被分词(ASCII 词加 CJK n-gram)、去重,并以至多 32 个词项匹配倒排索引;`literal` 模式是零误报的精确子串搜索。成功时 `data` 为 `{ items, has_more, page_token?, index_state, source }`,每项为 `{ session_id, workspace_id, session_title, agent_id, role, snippet, time, turn?, step_id?, score }`。`index_state` 为 `{ state, indexed_sessions, total_sessions, documents, stale?, degraded? }`,其中 `state` 为 `building` / `ready` / `readonly` 之一;`stale` 标记仍在追赶的落后视图,`degraded` 携带最近一次刷新失败的信息。超出预算的页会额外携带 `incomplete`,取值为 `candidate_cap` / `postings_budget` / `deadline` 之一。分页令牌锁定索引代际与查询条件——索引重建或查询变更会使其失效。 - -- `40001`:请求体校验失败、查询不可用(为空或超过 32 个词项),或分页令牌非法 - -#### `GET /api/v1/connections` - -列出当前连接到本服务的 WebSocket 客户端,按连接时间最早在前。无参数。 - -成功时 `data` 为 `{ connections }`,每项为 `{ id, connected_at, remote_address, user_agent, has_client_hello, subscriptions }`:`connected_at` 为 ISO 8601 时间戳;`remote_address` 与 `user_agent` 未知时为 `null`;`has_client_hello` 报告客户端是否已发送握手帧;`subscriptions` 列出该连接订阅的会话 id。 - -### `GET /api/v2/sessions` - -面向列表页的新一代会话查询,筛选、排序、字段组都在查询参数里: - -| 参数 | 说明 | -| --- | --- | -| `workspace.id` | 按工作区过滤,可重复 | -| `activity.status` | 按活动状态过滤:`running` / `approval` / `question` / `failed` / `idle`,可重复 | -| `meta.updated_after` | 只看该时间(epoch 毫秒)之后更新过的会话 | -| `meta.updated_before` | 只看该时间(epoch 毫秒)之前更新过的会话 | -| `meta.archived` | `true` / `false`(默认)/ `all` | -| `meta.has_prompt` | `true` 只保留有用户 prompt 的会话,`false` 只保留空会话(等价 `GET /api/v1/sessions` 的 `exclude_empty`) | -| `view` | `flat`(默认)/ `by_workspace`,见下文 | -| `group.page_size` | `view=by_workspace` 时每个工作区返回的会话数:1–100,默认 5(使用 `id,archived` 投影时上限 10000);未开分组视图时传入返回 `40001` | -| `sort` | `meta.updated_at_desc`(默认)/ `meta.updated_at_asc` / `meta.created_at_desc` | -| `include` | 逗号分隔的附加字段组;目前支持 `git`(分支与 PR 信息,按目录去重并缓存 60 秒) | -| `fields` | 逗号分隔的字段投影;目前仅支持 `id,archived`,每项裁剪为 `{ id, archived }`(用于全选匹配场景)。不可与 `include=git` 同传(`40001`) | -| `page_size` | 1–100,默认 50;使用 `id,archived` 投影时上限放宽至 10000。`view=by_workspace` 时按组计数 | -| `page_token` | 上一页返回的翻页令牌 | -| `page` | 无状态的 1 起始页码;与 `page_token` 互斥(同传返回 `40001`) | - -响应每项固定包含 `workspace`、`meta`、`activity` 三组,`include=git` 时附加 `git` 组;`fields=id,archived` 时仅返回 `{ id, archived }`。每页额外携带 `total`,即过滤后的集合大小。翻页令牌绑定首页查询条件(含投影),中途改条件返回 `40922`。`page` 模式是跳页用的无状态替代:每次请求都是独立快照,不签发令牌,`next_page_token` 恒为 `null`。 - -`view=by_workspace` 时,同一份过滤、排序后的集合会重新投影为按工作区分组的形态,概览页因此可以用一次请求替代「每个工作区各一轮询」: - -```json -{ - "code": 0, - "msg": "success", - "data": { - "groups": [ - { - "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" }, - "sessions": [ { "id": "session_...", "workspace": { "id": "wd_my-app_a1b2c3d4e5f6", "cwd": "/Users/dev/my-app" }, "meta": { "title": "Fix the login page", "last_prompt": "adjust the button spacing", "created_at": 1787000000000, "updated_at": 1787000100000, "archived": false, "archived_at": null }, "activity": { "status": "idle" } } ], - "total": 42 - } - ], - "total": 7, - "has_more": true, - "next_page_token": "eyJ2IjoxLCJmIjoi..." - }, - "request_id": "req_..." -} -``` - -每组携带该工作区按请求 `sort` 排序的前 `group.page_size` 条会话,以及该工作区匹配过滤条件的会话总数 `total`(用作「查看全部」入口)。只有至少有一条匹配会话的工作区才会出现;组间按组内首条会话的 sort key 排序,相同则按工作区 id。`page` 与 `page_token` 按组翻页(外层 `total` 为组数),指纹绑定规则相同:令牌同时覆盖 `view` 与分组参数,翻页途中变更同样返回 `40922`。 - -### `POST /api/v2/sessions:archive` 与 `POST /api/v2/sessions:restore` - -面向会话管理页的批量归档/恢复。请求体为 `{ "ids": ["session_..."] }`——非空、去重后不超过 5000 条。仍在线的会话走完整生命周期;未加载的冷会话直接改写磁盘上的元数据,不会被加载。 - -只有请求体校验失败才会让整个请求失败(`40001`);其余情况按条返回:`data.results` 保持输入顺序,每项为 `{ id, ok }` 或 `{ id, ok: false, error }`(不存在的 id 在自身条目里报 `40401`),并附 `succeeded` / `failed` 计数。 - -```json -{ - "code": 0, - "msg": "success", - "data": { - "results": [ - { "id": "session_a", "ok": true }, - { "id": "session_b", "ok": false, "error": { "code": 40401, "message": "session session_b does not exist" } } - ], - "succeeded": 1, - "failed": 1 - }, - "request_id": "req_..." -} -``` - -### MCP 管理(`/api/v2/mcp`) - -`/api/v2/mcp/*` 路由是服务的统一 MCP 管理面:独立于任何会话,直接管理 MCP server 注册表本身——全局(用户级)CRUD 与逐条校验、连接测试探测、locator 寻址的检查目录、按 server 的授权状态列表,以及完整的 OAuth 流程生命周期。 - -| 方法与路径 | 说明 | -| --- | --- | -| `GET /api/v2/mcp/servers` | 列出所有已知 MCP server | -| `GET /api/v2/mcp/servers/{name}` | 按运行时名称获取单个 server | -| `POST /api/v2/mcp/servers` | 向用户级 `mcp.json` 添加 server | -| `PUT /api/v2/mcp/servers/{name}` | 替换一个用户级条目 | -| `DELETE /api/v2/mcp/servers/{name}` | 删除一个用户级条目 | -| `POST /api/v2/mcp/servers:test` | 对单个 server 发起真实连接探测 | -| `POST /api/v2/mcp/servers:inspect` | locator 寻址的目录及批量连接探测 | -| `GET /api/v2/mcp/auth-statuses` | 目录中各 server 的 OAuth 状态 | -| `POST /api/v2/mcp/auth:begin` | 开始一次交互式 OAuth 流程 | -| `POST /api/v2/mcp/auth:complete` | 等待浏览器回调并完成 code 交换 | -| `POST /api/v2/mcp/auth:cancel` | 终止已开始的 OAuth 流程 | -| `POST /api/v2/mcp/auth:reset` | 清除某个 server 已存储的凭据 | - -该管理面有两种寻址方式。CRUD 路由与 `servers:test` 使用普通的运行时 `name`;检查与 OAuth 路由使用 **locator**——文件层条目用 `{ "source": "global", "name" }`,插件清单条目用 `{ "source": "plugin", "pluginId", "serverName" }`——因为插件条目和文件条目可能共用同一个运行时名称。检查条目还带有一个稳定的 `serverId` 线上标识:`global:<name>` 或 `plugin:<pluginId>:<serverName>`(URL 编码)。 - -大多数路由接受可选的 `cwd`(查询参数,`:`-action 路由则为请求体字段)。不传时目录只覆盖用户级文件与插件清单;传入后,该目录的项目根层与项目本地层会并入——但仅当工作区受信任时,否则项目层会被跳过。对 stdio server 执行 `servers:test` 时,`cwd` 同时是子进程的工作目录。连接探测与 OAuth 调用会等待服务配置加载完成后再执行。 - -#### `GET /api/v2/mcp/servers` 与 `GET /api/v2/mcp/servers/{name}` - -列出管理面已知的全部 MCP server;第二个路由返回该运行时名称对应的单个条目。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `name` | path | string | **必填(仅 get)。** server 的运行时名称 | -| `cwd` | query | string | 并入该(受信任)目录的项目层 | - -成功时 `data` 是受管 server 数组(get 路由为单个对象),每项为 `{ name, config, source, origin, mutable, plugin? }`: - -- `source`:`global`(配置文件层)或 `plugin`(插件清单) -- `origin`:条目的定义位置——文件路径或插件 id -- `mutable`:只有用户级条目可变;插件与项目层条目均为只读 -- `config`:可变条目携带完整配置,便于编辑界面预填;只读条目被脱敏为排序后的键名列表(`envKeys` / `headerKeys`),绝不泄露密钥值 -- `plugin`:`{ id, name }`,仅插件条目携带 - -- `40001`:校验失败 -- `40408`:不存在该名称的 server - -#### `POST` / `PUT` / `DELETE /api/v2/mcp/servers` - -针对用户级 `mcp.json` 的全局 CRUD。新增请求体是包含 `name` 的完整 server 配置——`transport`(`stdio` / `http` / `sse`)决定配置形状,每条配置写入前都会校验。更新请求体携带同样的配置但不含 `name`(由路径指定条目);删除无请求体。三者都在 `data` 中返回刷新后的 server 列表。若写入与项目层的同名条目冲突,会因只读被拒绝——请改为编辑定义它的文件;与同名的插件条目冲突并不阻止写入,新的文件条目会将其遮蔽。 - -- `40001`:校验失败,或目标条目为只读 -- `40408`:(更新/删除)不存在该名称的 server - -#### `POST /api/v2/mcp/servers:test` - -对单个 server 发起真实连接探测,不持久化任何内容。传 `name` 探测注册表条目(含插件与受信任的项目层),或传 `server`(包含 `name` 的完整内联配置)按原样探测;两者都传或都不传会报 `40001`。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `name` | body | string | 注册表条目的运行时名称 | -| `server` | body | object | 按原样探测的内联 server 配置 | -| `cwd` | body | string | 项目层并入解析;同时是 stdio 的工作目录 | - -成功时 `data` 为 `{ success, output }`:连接成功时 `output` 列出该 server 的可用工具,否则携带失败信息。 - -- `40001`:两种目标形式都传或都不传、内联配置无效,或运行时名称被多个启用的 server 共用 -- `40408`:不存在该名称的 server - -#### `POST /api/v2/mcp/servers:inspect` - -locator 寻址的目录(脱敏配置),外加对每个 OAuth 候选的批量真实连接探测。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `targets` | body | array | 缩小目录范围的 locator 数组;不传则检查全部 server | -| `cwd` | body | string | 并入该(受信任)目录的项目层 | - -成功时 `data` 是检查结果数组,每项为 `{ serverId, locator, runtimeName, canonicalUrl?, origin, config, enabled, editable, authStatus, checkedAt?, error? }`:`canonicalUrl` 是远程 server 的凭据 URL,`config` 为脱敏视图,`authStatus` 取值为 `not-applicable` / `bearer-token` / `oauth-required` / `oauth-authorized` / `oauth-expired` / `unavailable` 之一。运行时名称被多个启用的 server 共用时无法无歧义地探测,会报告 `unavailable` 并在 `error` 中给出说明。探测遇到过期授权时,可能刷新或作废已存储的凭据。 - -- `40001`:校验失败 -- `40408`:`targets` 中有 locator 未匹配到任何条目 - -#### `GET /api/v2/mcp/auth-statuses` - -注册表目录中各 server 的 OAuth 状态——只需要授权维度时,这是比 `servers:inspect` 更轻量的选择。 - -| 参数 | 位置 | 类型 | 说明 | -| --- | --- | --- | --- | -| `cwd` | query | string | 并入该(受信任)目录的项目层 | -| `verify` | query | string | `true` 对每个 OAuth 候选发起真实连接验证;`false` 完全离线(仅凭配置与已存储 token 分类);缺省保留隐式 OAuth 探测,只探测未固定且没有已存储凭据的远程 server | - -成功时 `data` 是 `{ name, authStatus }` 数组,`authStatus` 取值与 `servers:inspect` 相同。验证探测可能刷新或作废已存储的凭据。 - -#### `POST /api/v2/mcp/auth:begin` / `:complete` / `:cancel` / `:reset` - -远程 server 的 OAuth 流程生命周期。`auth:begin` 接受 locator 请求体(外加可选的 `cwd` 查询参数),返回 `data` 为 `{ status: "authorization-required", flowId, authorizationUrl }`——在浏览器中打开该 URL 完成授权——或当授权已存在时返回 `{ status: "already-authorized" }`。目标 server 必须使用远程传输(`http` / `sse`)且不含静态 bearer token;静态请求头仅当配置显式设置 `auth: "oauth"` 时允许。 - -`auth:complete` 等待已开始流程的浏览器回调并完成 code 交换。请求体为 `{ flowId, timeoutMs? }`:等待默认 15 分钟(`timeoutMs` 可覆盖),空闲流程无论如何都会在 15 分钟后过期,关闭 HTTP 连接会中止等待。成功时 `data` 为 `null`。 - -`auth:cancel` 在未完成的情况下终止已开始的流程(`{ flowId }`);未知流程会被忽略。`auth:reset` 接受 locator 请求体,清除该 server 已存储的凭据——失效事件会送达存活的会话。 - -- `40001`:校验失败——包括 `:complete` 的 `flowId` 未知,或 `:begin` 的 server 无法使用 OAuth(stdio 传输、静态 bearer token,或未设置 `auth: "oauth"` 的静态请求头) -- `40408`:(`:begin` / `:reset`)locator 未匹配到任何条目 -- `40929`:OAuth 流程本身失败 - -## WebSocket 协议 - -### 建立连接 - -唯一端点是 `ws://<host>:<port>/api/v1/ws`;鉴权在升级请求时完成(见上文 [鉴权](#鉴权))。连接建立后服务端立即发送 `server_hello`: - -```json -{ - "type": "server_hello", - "timestamp": "2026-01-01T00:00:00.000Z", - "payload": { - "ws_connection_id": "conn_01JZX4...", - "protocol_version": 2, - "max_event_buffer_size": 1000, - "capabilities": { "event_batching": false, "compression": false } - } -} -``` - -注意服务端不发送心跳,也不会主动断开空闲连接——保活与重连由客户端自己负责。 - -### 控制帧 - -客户端发送 JSON 帧 `{ "type", "id"?, "payload" }`;每个请求帧都会收到应答 `{ "type": "ack", "id", "code", "msg", "payload" }`,`code` 为 `0` 表示成功。 - -| 帧 | payload | 说明 | -| --- | --- | --- | -| `subscribe` | `{ session_ids, cursors?, agent_filter? }` | 订阅会话事件;带 `cursors`(每会话 `{seq, epoch}`)时回放错过的持久事件 | -| `unsubscribe` | `{ session_ids }` | 取消会话订阅 | -| `subscribe_v2` | `{ session_id, transcript, transcript_since? }` | 订阅转录流(唯一的转录订阅通道),`transcript` 按 agent 指定粒度 | -| `unsubscribe_v2` | `{ session_id, agent_ids? }` | 退订转录流;省略 `agent_ids` 表示整个会话 | -| `watch_fs_add` / `watch_fs_remove` | `{ session_id, paths, recursive? }` | 订阅 / 取消文件变更通知(`event.fs.changed`) | -| `client_hello` | `{ client_id }` | 握手帧,其余字段为遗留兼容 | - -### 事件 - -事件帧形状为 `{ "type", "seq", "epoch"?, "volatile"?, "offset"?, "session_id"?, "timestamp", "payload" }`,`type` 即事件类型。按投递范围分两类: - -- **全局事件**:发送到每个已建立连接,无需订阅——`session.meta.updated`、`event.session.created`、`event.session.archived`、`event.session.work_changed`、`event.session.status_changed`、`event.workspace.*`、`event.config.*`。 -- **会话事件**:只发给订阅了该会话的连接,受 `agent_filter` 过滤。主要事件族: - -| 事件族 | 主要事件 | -| --- | --- | -| 轮次 | `turn.started`、`turn.ended`、`turn.step.started` / `completed` / `interrupted` / `retrying` | -| 流式文本 | `assistant.delta`、`thinking.delta`(带 `offset` 用于对齐) | -| 工具调用 | `tool.call.started`、`tool.call.delta`、`tool.progress`、`tool.result` | -| 交互 | `event.approval.requested` / `resolved`、`event.question.requested` / `answered` / `dismissed` | -| subagent | `subagent.spawned` / `started` / `suspended` / `completed` / `failed` | -| 后台 | `task.started` / `terminated`、`shell.started` / `output` / `completed` | -| 其他 | `compaction.*`、`skill.activated`、`goal.updated`、`prompt.*`、`error`、`warning` | - -有三个全局生命周期事件可以让跨工作区概览免掉逐工作区轮询。`event.session.archived` 在在线归档与冷归档两条路径上都会发出;其事件帧 `session_id` 是全局水位 `__global__`,真实会话 id 在 payload 里:`{ "type": "event.session.archived", "workspace_id": "wd_...", "sessionId": "session_..." }`(payload 字段为 `workspace_id` / `sessionId`)。`event.workspace.created` / `updated` 携带完整工作区对象(`{ id, root, name, created_at, last_opened_at, session_count }`——会话创建触碰工作区时也会发 `updated`),`event.workspace.deleted` 携带 `{ "workspace_id", "root" }`。这些事件只覆盖本服务进程内的变更;其他进程(例如写同一 home 目录的 CLI)的变更要等索引 reconcile(约一分钟)才可见,因此概览客户端应保留低频兜底轮询。目前没有会话删除事件。 - -事件另分持久与易失两种:持久事件带严格递增的 `seq`,落盘并可回放;易失事件(各 `*.delta`、`tool.progress`、`shell.*` 等)标 `volatile: true`,不回放。消费易失文本流时用 `offset`(该轮次内的累计字符偏移)与本地已累积文本比对:小于本地长度说明是重复帧,大于说明有缺漏、需走快照恢复。 - -### 断线恢复 - -重连后在 `subscribe` 的 `cursors` 里带上每个会话最后应用事件的 `{seq, epoch}`,服务端会回放缺口;落后超过缓冲(1000 条)或游标失效时改为收到 `resync_required`。此时调用 `GET /api/v1/sessions/{session_id}/snapshot` 拿全量快照(含 `as_of_seq` 与 `epoch`),再以新游标重新订阅。 - -### 转录协议 - -`subscribe_v2` 的 `transcript` 按 agent 指定粒度:`off` / `turn` / `block` / `delta`(键 `"*"` 表示默认粒度),粒度越高推送越细。粒度非 `off` 的 agent 走两帧推送:`transcript.reset`(基线快照,历史经 REST 分页回读)和 `transcript.ops`(增量批次,带每个 agent 连续递增的 `seq`);该 agent 的旧式事件在同一连接上被抑制,改由转录帧承载。断线时用 `transcript_since` 续传;服务端批次日志无法覆盖缺口时(REST 补漏返回 `complete: false`)需全量刷新。REST 侧对应 `GET .../transcript`(按轮次分页)与 `GET .../transcript/ops?since_seq=`(批次补漏)。 - -## 二进制与流式端点 - -以下端点返回二进制流而非 JSON 载荷,各端点的 HTTP 能力并不相同: - -| 方法与路径 | 说明 | Range 分段(206) | ETag / 304 | -| --- | --- | --- | --- | -| `GET /api/v1/files/{file_id}` | 下载已上传文件 | 支持 | 不支持(会发送 `etag` 头,但不处理 `If-None-Match`) | -| `GET /api/v1/sessions/{session_id}/fs/{path}:download` | 下载会话工作区文件 | 支持 | 支持 | -| `GET /api/v1/fs:content` | 读取本机任意文件(仅受 token 保护,谨慎暴露端口) | 支持 | 支持 | -| `POST /api/v1/sessions/{session_id}/export` | 导出会话与诊断信息(zip 流) | 不支持 | 不支持 | - -错误语义也不相同:`GET /api/v1/files/{file_id}` 对查找和存储失败返回真实 404 / 500 状态码(参数校验失败仍走 HTTP 200 信封),其余三个端点的所有失败都走标准 [响应信封](#响应信封)——客户端在这三个端点上仍需检查信封中的 `code`。 - -## 下一步 - -- [本地服务与 API](../guides/server.md) — 启动、鉴权与端到端调用流程 -- [kimi 命令](./kimi-command.md#kimi-web) — `kimi web` 的全部命令行选项 diff --git a/docs/zh/reference/slash-commands.md b/docs/zh/reference/slash-commands.md index dda54ec7e..4a8b24451 100644 --- a/docs/zh/reference/slash-commands.md +++ b/docs/zh/reference/slash-commands.md @@ -16,7 +16,7 @@ | `/logout` | — | 清除当前所选账号的凭据 | 否 | | `/provider` | — | 打开交互式供应商管理器,查看、添加和删除已配置的供应商。详见[平台与模型 — `/provider` 与供应商管理](../configuration/providers.md#provider-—-交互式供应商管理) | 是 | | `/model` | — | 切换当前会话使用的 LLM 模型 | 是 | -| `/secondary-model` | `/subagent-model` | 选择 subagent 的默认模型(写入 `[secondary_model] default_model`,详见[subagent 模型池](../configuration/config-files.md#subagent-模型池))。在 subagent 模型池实验功能启用时可见 | 是 | +| `/secondary_model` | — | 配置子 Agent 默认绑定的次主力模型(写入 [`[secondary_model]`](../configuration/config-files.md#secondary-model) 配置并在当前会话立即生效)。需开启 `secondary-model` 实验功能 | 是 | | `/settings` | `/config` | 打开 TUI 内的设置面板 | 是 | | `/experiments` | `/experimental` | 打开实验功能面板 | 是 | | `/permission` | — | 选择权限模式 | 是 | @@ -100,7 +100,7 @@ Prompt 模式在目标完成时以退出码 `0` 退出,在目标阻塞时以 ` | 命令 | 别名 | 说明 | 随时可用 | | --- | --- | --- | --- | | `/help` | `/h`、`/?` | 显示快捷键和所有可用命令 | 是 | -| `/btw [问题]` | — | 在 fork 出的 subagent 中打开旁路对话,不改变当前 main agent 轮次;不带问题时会先打开面板等待输入 | 是 | +| `/btw [问题]` | — | 在 fork 出的子 Agent 中打开旁路对话,不改变当前主 Agent 轮次;不带问题时会先打开面板等待输入 | 是 | | `/usage` | — | 显示 token 用量、上下文占用以及配额信息 | 是 | | `/status` | — | 显示当前会话运行时状态:版本、模型、工作目录、权限模式等 | 是 | | `/mcp` | — | 列出当前会话中的 MCP server 及连接状态 | 是 | @@ -152,7 +152,7 @@ Kimi Code CLI 随包内置了一组 Skill,直接以 `/<name>` 形式出现在 Kimi Code CLI 随包内置的 Skill 会直接以 `/<name>` 形式出现在斜杠命令面板中。例如,`/mcp-config` 用于配置 MCP server 和处理 MCP OAuth 登录,`/custom-theme [附加文本]` 用于进入自定义主题流程,创建或编辑 TUI 主题。 ::: info 说明 -Agent 忙碌时输入的外部 Skill 命令不会被拒绝,而是排队等待当前轮次结束——按 `Ctrl-S` 可让排队的命令立即插入正在运行的轮次。`flow` 类型的 Skill 同样通过 `/skill:<name>` 暴露,没有独立的 `/flow:` 命名空间。 +所有 Skill 命令仅在空闲状态下可用。`flow` 类型的 Skill 同样通过 `/skill:<name>` 暴露,没有独立的 `/flow:` 命名空间。 ::: Skill 的安装与编写详见 [Agent Skills](../customization/skills.md)。 diff --git a/docs/zh/reference/tools.md b/docs/zh/reference/tools.md index 2a872d36e..009ff3d05 100644 --- a/docs/zh/reference/tools.md +++ b/docs/zh/reference/tools.md @@ -19,9 +19,9 @@ **`Read`** 接受文件路径(`path`)以及可选的 `line_offset`(起始行号,支持负数从末尾倒数)和 `n_lines`(读取行数上限)。单次最多返回 1000 行或 100 KB,超出部分会附带截断提示。如果文件是图片或视频,工具会提示改用 `ReadMediaFile`。 -**`Write`** 接受 `path`、`content` 和可选的 `mode`(`overwrite` 或 `append`,默认覆盖)。缺失的父目录会自动创建;`append` 模式将内容追加到文件末尾,不自动添加换行。写入已存在的文件(无论 `overwrite` 还是 `append` 模式)要求本会话中先用 `Read` 读过该文件——若文件自上次读取后在磁盘上发生变化,写入会被拒绝;新建文件不受此限。 +**`Write`** 接受 `path`、`content` 和可选的 `mode`(`overwrite` 或 `append`,默认覆盖)。缺失的父目录会自动创建;`append` 模式将内容追加到文件末尾,不自动添加换行。 -**`Edit`** 接受 `path`、`old_string`(要替换的精确文本)和 `new_string`(替换后的文本)。默认只替换唯一一处匹配,若文件中存在多处相同内容会报错并提示使用 `replace_all: true`。`old_string` 与 `new_string` 不能相同。目标文件必须在本会话中先用 `Read` 读过;若文件自读取后在磁盘上发生变化,编辑会被拒绝。 +**`Edit`** 接受 `path`、`old_string`(要替换的精确文本)和 `new_string`(替换后的文本)。默认只替换唯一一处匹配,若文件中存在多处相同内容会报错并提示使用 `replace_all: true`。`old_string` 与 `new_string` 不能相同。 **`Grep`** 调用 ripgrep 搜索文件内容,支持正则表达式(`pattern`)、搜索路径(`path`)、文件类型过滤(`type`,如 `ts`、`py`)、glob 过滤(`glob`)和输出模式(`output_mode`:`files_with_matches` / `content` / `count_matches`,默认 `files_with_matches`)。`content` 模式支持上下文行(`-A`、`-B`、`-C`)、忽略大小写(`-i`)、行号(`-n`,默认 true)、跨行匹配(`multiline`)。所有模式支持 `offset` + `head_limit` 分页,`head_limit` 默认 250、传 0 表示不限。`.env`、私钥等敏感文件会被自动过滤;`include_ignored=true` 可搜索被 `.gitignore` 忽略的文件,但敏感文件仍保持过滤。 @@ -84,14 +84,14 @@ Plan 模式是一种受约束的工作状态:进入后 `Write` 与 `Edit` 只 | 工具 | 默认审批 | 说明 | | --- | --- | --- | -| `Agent` | 自动放行 | 派生 subagent 执行子任务 | -| `AgentSwarm` | swarm mode 中自动放行,否则需审批 | 启动基于 item 的 subagent,或恢复已有 subagent | +| `Agent` | 自动放行 | 派生子 Agent 执行子任务 | +| `AgentSwarm` | swarm mode 中自动放行,否则需审批 | 启动基于 item 的子 Agent,或恢复已有子 Agent | | `AskUserQuestion` | 自动放行 | 向用户提问以获取结构化输入 | | `Skill` | 自动放行 | 调用已注册的 inline Skill | -**`Agent`** 将子任务委托给 subagent 执行。必填参数:`prompt`(完整任务描述)和 `description`(3–5 个词的简短说明)。可选参数:`subagent_type`(默认 `coder`)、`resume`(恢复已有 Agent 的 ID,与 `subagent_type` 互斥)、`run_in_background`(默认 false)和 `model`(仅在启用 [subagent 模型池](../configuration/config-files.md#subagent-模型池) 实验功能并配置模型池后可用——`[secondary_model.models]` 表或仅一行 `default_model`:池中别名,或 `"primary"` 表示调用方自己运行的模型;resume 时无效)。未传入时 subagent 绑定池的 `default_model`;未配置模型池时,subagent 一律继承调用方模型。Agent 任务默认 2 小时超时,可通过 `config.toml` 的 `[subagent] timeout_ms`(`0` = 无超时,或 `KIMI_SUBAGENT_TIMEOUT_MS` 环境变量)配置,且在 print 模式(`kimi -p`)下默认无超时。前台模式下父 Agent 等待 subagent 完成再继续;后台模式立即返回任务 ID,完成时通过合成 User 消息自动回到 main agent。多个前台 `Agent` 调用在同一步运行时,TUI 会合并展示,并为每个 subagent 显示运行、等待、完成或失败状态以及已耗时长。subagent 体系细节见 [Agent 与 subagent](../customization/agents.md)。 +**`Agent`** 将子任务委托给子 Agent 执行。必填参数:`prompt`(完整任务描述)和 `description`(3–5 个词的简短说明)。可选参数:`subagent_type`(默认 `coder`)、`resume`(恢复已有 Agent 的 ID,与 `subagent_type` 互斥)、`run_in_background`(默认 false)和 `model`(`"secondary"` 表示 `[secondary_model] model` 配置的次主力模型,`"primary"` 表示主模型;resume 时无效;次主力模型实验功能启用后可用)。显式 `model` 会覆盖所选 [Agent profile 的 `model_preference`](../customization/agents.md#agent-文件格式);两者均未设置时,已配置的次主力模型为默认值,未配置时则继承调用方模型。Agent 任务默认 2 小时超时,可通过 `config.toml` 的 `[subagent] timeout_ms`(`0` = 无超时,或 `KIMI_SUBAGENT_TIMEOUT_MS` 环境变量)配置,且在 print 模式(`kimi -p`)下默认无超时。前台模式下父 Agent 等待子 Agent 完成再继续;后台模式立即返回任务 ID,完成时通过合成 User 消息自动回到主 Agent。多个前台 `Agent` 调用在同一步运行时,TUI 会合并展示,并为每个子 Agent 显示运行、等待、完成或失败状态以及已耗时长。子 Agent 体系细节见 [Agent 与子 Agent](../customization/agents.md)。 -**`AgentSwarm`** 可以从共享的 `prompt_template` 和 `items` 数组启动 subagent,也可以通过 `resume_agent_ids` 恢复已有 subagent,或在一次调用中同时使用两者。模板必须包含 `{{item}}` 占位符;每个 item 会替换该占位符,并启动一个新的 subagent。传入 `subagent_type` 可以指定整个 swarm 中所有新启动的 subagent 使用的 profile;省略时默认使用 `coder`。传入 `model`(仅在启用 [subagent 模型池](../configuration/config-files.md#subagent-模型池) 实验功能并配置模型池后可用——`[secondary_model.models]` 表或仅一行 `default_model`)可以让新启动的 subagent 运行在池中别名指定的模型或调用方自己的模型(`"primary"`)上。未传入时新启动的 subagent 绑定池的 `default_model`;未配置模型池时则继承调用方模型。恢复的 subagent 保持其原有模型。不传 `resume_agent_ids` 时,本工具要求至少 2 个 item;传入 `resume_agent_ids` 时,可以恢复 1 个或多个已有 subagent。本工具最多支持 128 个 subagent,会等待全部 subagent 完成,并返回聚合报告。每个 subagent 默认 2 小时超时,可通过 `config.toml` 的 [`[swarm] timeout_ms`](../configuration/config-files.md#swarm)(`0` = 无超时,或 `KIMI_CODE_SWARM_TIMEOUT_MS` 环境变量)配置,且在 print 模式(`kimi -p`)下默认无超时;超时的 subagent 会被中止,并在聚合报告中标记为失败。在 TUI 中,前台 swarm 会在输入框上方显示实时 `Agent swarm` 进度面板。若一次模型响应调用 `AgentSwarm`,该调用必须是该响应中的唯一工具调用;如需运行多个 swarm,应先调用一个 `AgentSwarm` 并等待结果,再调用下一个,若单个模板可以覆盖这些工作,也可以合并为一个 swarm。在 `manual` 权限模式下,未处于 swarm mode 时调用 `AgentSwarm` 会触发审批,除非已有权限规则允许;swarm mode 已开启时,`AgentSwarm` 本身会自动放行。权限规则只能按工具名 `AgentSwarm` 匹配,不支持 `AgentSwarm(swarm)` 这类参数模式。默认情况下,本工具会逐步提升并发且不设上限(立即启动 5 个 subagent,之后每 700 毫秒再启动 1 个);将 `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` 设为正整数可限制该阶段同时运行的 subagent 数量,不设置则表示不限制。若设置为非正整数的值,本次 AgentSwarm 调用会立即失败。 +**`AgentSwarm`** 可以从共享的 `prompt_template` 和 `items` 数组启动子 Agent,也可以通过 `resume_agent_ids` 恢复已有子 Agent,或在一次调用中同时使用两者。模板必须包含 `{{item}}` 占位符;每个 item 会替换该占位符,并启动一个新的子 Agent。传入 `subagent_type` 可以指定整个 swarm 中所有新启动的子 Agent 使用的 profile;省略时默认使用 `coder`。传入 `model`(次主力模型实验功能启用后可用)可以让新启动的子 Agent 运行在 `[secondary_model] model` 配置的次主力模型(`"secondary"`)或主模型(`"primary"`)上。这项显式选择会覆盖所选 [Agent profile 的 `model_preference`](../customization/agents.md#agent-文件格式);两者均未设置时,已配置的次主力模型为默认值,未配置时则继承调用方模型。恢复的子 Agent 保持其原有模型。不传 `resume_agent_ids` 时,本工具要求至少 2 个 item;传入 `resume_agent_ids` 时,可以恢复 1 个或多个已有子 Agent。本工具最多支持 128 个子 Agent,会等待全部子 Agent 完成,并返回聚合报告。在 TUI 中,前台 swarm 会在输入框上方显示实时 `Agent swarm` 进度面板。若一次模型响应调用 `AgentSwarm`,该调用必须是该响应中的唯一工具调用;如需运行多个 swarm,应先调用一个 `AgentSwarm` 并等待结果,再调用下一个,若单个模板可以覆盖这些工作,也可以合并为一个 swarm。在 `manual` 权限模式下,未处于 swarm mode 时调用 `AgentSwarm` 会触发审批,除非已有权限规则允许;swarm mode 已开启时,`AgentSwarm` 本身会自动放行。权限规则只能按工具名 `AgentSwarm` 匹配,不支持 `AgentSwarm(swarm)` 这类参数模式。默认情况下,本工具会逐步提升并发且不设上限(立即启动 5 个子 Agent,之后每 700 毫秒再启动 1 个);将 `KIMI_CODE_AGENT_SWARM_MAX_CONCURRENCY` 设为正整数可限制该阶段同时运行的子 Agent 数量,不设置则表示不限制。若设置为非正整数的值,本次 AgentSwarm 调用会立即失败。 **`AskUserQuestion`** 以结构化多选题的形式向用户提问,适用于需要消歧或选择方案的场景。`questions` 参数接受 1–4 道题,每道题需提供 `question`(以 `?` 结尾)、`options`(2–4 个选项,每项含 `label` 和 `description`)以及可选的 `header`(最多 12 字符)和 `multi_select`(默认 false)。系统自动附加"其他"选项。`background` 为 true 时启动后台问题任务并立即返回任务 ID。宿主未实现交互式提问能力时返回失败提示,Agent 应改为在文本回复中直接提问。 @@ -99,14 +99,13 @@ Plan 模式是一种受约束的工作状态:进入后 `Write` 与 `Edit` 只 ## 后台任务 -后台任务工具用于管理通过 `Bash`、`Agent` 或 `AskUserQuestion` 启动的后台任务。任务进入终止状态时会自动把状态和已保存的输出路径送回 Agent;如需提前检查进度,使用 `TaskOutput`;如果下一步必须等待某个任务的结果,使用 `WaitFor` 在当前轮次内等待。 +后台任务工具用于管理通过 `Bash`、`Agent` 或 `AskUserQuestion` 启动的后台任务。任务进入终止状态时会自动把状态和已保存的输出路径送回 Agent;如需提前检查进度,使用 `TaskOutput`。 | 工具 | 默认审批 | 说明 | | --- | --- | --- | | `TaskList` | 自动放行 | 列出后台任务 | | `TaskOutput` | 自动放行 | 查看后台任务的输出 | | `TaskStop` | 需审批 | 停止正在运行的后台任务 | -| `WaitFor` | 自动放行 | 等待后台任务结束 | **`TaskList`** 返回后台任务列表。可选参数 `active_only`(默认 true,仅列出运行中的任务)和 `limit`(默认 20,取值范围 1–100)。 @@ -114,8 +113,6 @@ Plan 模式是一种受约束的工作状态:进入后 `Write` 与 `Edit` 只 **`TaskStop`** 接受 `task_id` 和可选的 `reason`(默认 `Stopped by TaskStop`)。对已处于终止状态的任务也能安全调用。 -**`WaitFor`** 把当前轮次挂起,直到后台任务结束或超时。参数:`timeout`(必填,单位秒,上限 600)和可选的 `task_id`。不传 `task_id` 时,调用时刻运行中的任意一个后台任务结束即返回;当前没有运行中的后台任务时立即返回。超时不是错误——结果会列出仍在运行的任务,Agent 可以再次等待,也可以先处理其他工作。已通过 `WaitFor` 汇报结果的任务不会再推送自动完成通知。 - ## 定时任务 定时任务工具允许 Agent 把一段 prompt 在未来某个时间重新注入到当前会话——既可以是一次性提醒,也可以是按 cron 周期触发的任务(定期巡检、每日报表、部署监控等)。计划绑定到会话,用 `kimi --session` 恢复会话后仍然有效,但不会带入全新的会话。单个会话最多保留 50 个生效中的定时任务。设置 `KIMI_DISABLE_CRON=1` 可整体禁用,详见[环境变量](../configuration/env-vars.md#运行时开关)。 @@ -136,6 +133,6 @@ Plan 模式是一种受约束的工作状态:进入后 `Write` 与 `Edit` 只 ## 下一步 -- [Agent 与 subagent](../customization/agents.md) — `Agent` 工具的调度机制与上下文隔离 +- [Agent 与子 Agent](../customization/agents.md) — `Agent` 工具的调度机制与上下文隔离 - [Hooks](../customization/hooks.md) — 在工具调用前后触发本地脚本 - [斜杠命令](./slash-commands.md) — TUI 内置控制命令速查 diff --git a/docs/zh/release-notes/changelog.md b/docs/zh/release-notes/changelog.md index 53549983f..0a09e9537 100644 --- a/docs/zh/release-notes/changelog.md +++ b/docs/zh/release-notes/changelog.md @@ -6,125 +6,6 @@ outline: 2 本页记录 Kimi Code CLI 每个版本的变更内容。 -## 0.38.0(2026-08-20) - -### 新功能 - -- 支持 kimi.ai 与 kimi.com 两种 OAuth 登录方式。 -- 新增 WaitFor 工具:Agent 可以在当前轮次内等待后台任务完成,无需结束轮次后再次被唤起。 -- 官方 Kimi Datasource 插件新增 13 个数据源:中国政府数据(NDA/NBS)与标准(GB/HB/DB/TT)、八个国际组织数据集(WHO、FAO、UNSD、ECB、Eurostat、UNICEF、OECD、FRED)、新华财经和财新。在 /plugins 的 Official 标签页中更新插件。 -- web: 聊天头部的更多菜单新增置顶操作。 - -### 优化 - -- Edit 和 Write 现在要求先读取已存在的文件再进行修改。 -<!-- - 子 Agent 默认不再派生自己的子 Agent;自定义 Agent 配置仍可显式允许。 --> -- 折叠过长的 `!` Shell 命令输出,避免刷屏;按 ctrl+o 可与工具输出一起展开或折叠。 - -### 修复 - -- 修复 config.toml 在存在语法错误或在应用外被编辑时条目丢失的问题。 -- 修复了一些已知问题,并做了若干细节优化。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - -## 0.37.2(2026-08-19) - -### 优化 - -- web: 设置页新增 「实验室」标签页,上线「多标签侧边栏开关」功能;开启后侧边栏显示 Open / Done / Workspaces 标签页。 -- 做了若干细节优化和内部改进。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - -## 0.37.1(2026-08-18) - -### 修复 - -- 修复粘贴的图片和视频无法发送给模型的问题。 - -## 0.37.0(2026-08-18) - -### 新功能 - -- 支持在单条提示词中激活多个 skill:在空白后输入 `/` 即可插入 skill 标记。 -- Windows 原生(单文件)CLI 现支持自动更新。 -- web: 侧边栏新增 Open / Done / Workspaces 标签页,会话可标记为 Done。 -- web: 新增会话管理页面。 - -### 优化 - -- Agent 忙碌时输入的 skill 斜杠命令现在会排队执行,不再直接拒绝。 -- web: 聊天消息中 @提及的文件、文件夹和 skill 现在渲染为图标胶囊。 -- web: 浏览器标签页标题现在显示当前工作区目录名。 -- web: 搜索对话框现在支持搜索工作区,选中结果后会展开侧边栏并滚动定位到该条目。 -- web: Subagent 面板更名为 "Background Agent"。 -- 输入的 `/goal` 目标超过 4000 字符限制时现在会给出警告,且被拒绝时保留已输入的内容。 - -### 修复 - -- 修复 Gemini 工具调用会话后续请求失败的问题。 -- web: 修复 macOS 上输入框中 Ctrl+K 误打开会话搜索的问题,会话搜索现仅响应 Cmd+K。 -- web: 修复 Background Agent 面板显示数量和状态不对的问题。 -- web: 修复把复制的文件夹粘贴进输入框会导致上传报连接错误的问题,现在文件夹会被直接跳过。 -- 修复了一些已知问题,并做了若干细节优化。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - -## 0.36.1(2026-08-14) - -### 新功能 - -- web: AI 自动生成会话标题(实验性)。默认关闭,设置 `KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE=1`(或实验总开关 `KIMI_CODE_EXPERIMENTAL_FLAG=1`)开启。 - -### 优化 - -- web: 优化输入框的 Plan、Goal、Swarm 开关,现收进了输入框旁的 + 号菜单。 - -### 修复 - -- 修复了一些已知问题,并做了若干细节优化。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - -## 0.36.0(2026-08-13) - -### 新功能 - -- 实验性的子 Agent 模型配置升级为模型池:现在可以在 `[secondary_model]` 中配置一组带描述的候选模型,由主 Agent 每次派生时按任务挑选。 - - 启动前设置 `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL=1`(或实验总开关 `KIMI_CODE_EXPERIMENTAL_FLAG=1`)即可启用。 - - 推荐用法: - - - 极简用法:在 TUI 中运行 `/secondary-model` 选择,或在 `config.toml` 中写一行 `default_model`,让所有子 Agent 默认跑同一个模型;再加 `force = true` 可彻底固定该选择,主 Agent 无法改选。 - - 配置命名模型池,并为每个别名写一句适用场景的描述——描述会展示给主 Agent 作为挑选依据: - - ```toml - [secondary_model] - default_model = "kimi-code/kimi-for-coding-highspeed" - [secondary_model.models] - "kimi-code/kimi-for-coding-highspeed" = "快速、便宜,适合日常重构、代码解释和小改动。" - "kimi-code/k3" = "擅长复杂推理与深度调试,难题选它。" - ``` - - 详见 [子 Agent 模型池文档](https://moonshotai.github.io/kimi-code/zh/configuration/config-files.html#subagent-模型池)。 -- 新增实验性全屏 TUI 模式,设置 `KIMI_CODE_TUI_FULL_SCREEN=1` 环境变量即可启用。 -- TUI 支持渲染 LaTeX 数学公式(`$…$` 与 `$$…$$`),消息中的公式会显示为 Unicode 公式。 - -### 修复 - -- 修复未信任工作区可在信任确认前植入同名 `fd`/`stty` 可执行文件的风险;信任提示现在展示项目 MCP 的启动目标,并默认拒绝信任。 -- 修复在严格的 OpenAI 兼容供应商(如 DeepSeek)下,模型思考阶段打断轮次后,后续每轮请求都报 400 错误的问题。 -- 修复 API 请求失败自动重试期间按 Ctrl+C 无反应的问题。 -- 修复了一些已知问题,并做了若干细节优化。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - -## 0.35.0(2026-08-12) - -### 新功能 - -- 内置插件市场新增 Modern Web Guidance 插件,通过 `/plugins` 选择 Modern Web Guidance 安装。 -- `/tasks` 面板现实时展示后台子 Agent 的工作进度。 - -### 修复 - -- 修复 coder 子 Agent 默认可继续派生子 Agent 的问题。 -- 修复压缩后 token 数显示偏低的问题,现在与会话中看到的数字一致。 -- 修复 Windows 上的两处二进制植入风险。 -- 修复了一些已知问题,并做了若干细节优化。更详细的变更记录见 [GitHub](https://github.com/MoonshotAI/kimi-code/blob/main/apps/kimi-code/CHANGELOG.md)。 - ## 0.34.0(2026-08-06) ### 新功能 diff --git a/flake.nix b/flake.nix index df575b0ac..a102e68b9 100644 --- a/flake.nix +++ b/flake.nix @@ -162,7 +162,7 @@ inherit (finalAttrs) pname version src pnpmWorkspaces; inherit pnpm; fetcherVersion = 3; - hash = "sha256-NDcCQ5vxsGaSdJ3U0bvq2RkXKwrYTI7/8zZn/x1fvJ8="; + hash = "sha256-P450+LKDYkRyk7OZ2mSOX0/RwtbivwR5ZksN8FM6+TU="; }; nativeBuildInputs = [ diff --git a/package.json b/package.json index 5cbcad953..4acbcbef6 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "vis": "pnpm -C apps/vis run dev", "dev:docs": "pnpm -C docs install --ignore-workspace && pnpm -C docs run dev", "typecheck": "pnpm run build:packages && pnpm -r --filter './packages/*' run typecheck && pnpm --filter @moonshot-ai/kimi-code run typecheck && pnpm --filter kimi-code run typecheck && pnpm --filter @moonshot-ai/vis-server run typecheck && pnpm --filter @moonshot-ai/vis-web run typecheck", - "lint": "node scripts/check-no-comments.mjs && oxlint --type-aware", + "lint": "oxlint --type-aware", "lint:fix": "pnpm run lint --fix", "lint:pkg": "pnpm --filter @moonshot-ai/kimi-code exec publint && npm_config_cache=${TMPDIR:-/tmp}/kimi-code-npm-cache pnpm --filter @moonshot-ai/kimi-code exec attw --pack . --profile node16", "sherif": "sherif -i @agentclientprotocol/sdk", diff --git a/packages/acp-adapter/CHANGELOG.md b/packages/acp-adapter/CHANGELOG.md index d23df121d..956468657 100644 --- a/packages/acp-adapter/CHANGELOG.md +++ b/packages/acp-adapter/CHANGELOG.md @@ -1,27 +1,5 @@ # @moonshot-ai/acp-adapter -## 0.3.10 - -### Patch Changes - -- Updated dependencies [[`d833a1a`](https://github.com/MoonshotAI/kimi-code/commit/d833a1a893c4d69d96af542f40557442992085e0), [`61591bc`](https://github.com/MoonshotAI/kimi-code/commit/61591bce09f4467aa1664cb8ecb6aa6904b7accd), [`d833a1a`](https://github.com/MoonshotAI/kimi-code/commit/d833a1a893c4d69d96af542f40557442992085e0), [`13857f3`](https://github.com/MoonshotAI/kimi-code/commit/13857f383200881aa77dc972a8963ba421eeb2b6)]: - - @moonshot-ai/kimi-code-sdk@0.19.0 - -## 0.3.9 - -### Patch Changes - -- Updated dependencies [[`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797), [`7475c2e`](https://github.com/MoonshotAI/kimi-code/commit/7475c2e2e3dd86ac0b8a8d51d4f1d233ed7df797)]: - - @moonshot-ai/kimi-code-sdk@0.18.0 - - @moonshot-ai/agent-core@0.15.8 - -## 0.3.8 - -### Patch Changes - -- Updated dependencies [[`c9bfe8b`](https://github.com/MoonshotAI/kimi-code/commit/c9bfe8b2c8314ba4ef8806fb3b92ac654c1d1860), [`c212ae9`](https://github.com/MoonshotAI/kimi-code/commit/c212ae9715371c0d7939c15e664acbe0d7cf7fc3)]: - - @moonshot-ai/kimi-code-sdk@0.17.0 - ## 0.3.7 ### Patch Changes diff --git a/packages/acp-adapter/package.json b/packages/acp-adapter/package.json index 9991e0364..8820447f3 100644 --- a/packages/acp-adapter/package.json +++ b/packages/acp-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@moonshot-ai/acp-adapter", - "version": "0.3.10", + "version": "0.3.7", "private": true, "description": "Agent Client Protocol adapter for kimi-code", "license": "MIT", diff --git a/packages/acp-server/CHANGELOG.md b/packages/acp-server/CHANGELOG.md deleted file mode 100644 index a333c2e72..000000000 --- a/packages/acp-server/CHANGELOG.md +++ /dev/null @@ -1,9 +0,0 @@ -# @moonshot-ai/acp-server - -## 0.0.1 - -### Patch Changes - -- Updated dependencies [[`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629), [`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629), [`249d8fa`](https://github.com/MoonshotAI/kimi-code/commit/249d8faa3447427665185a900926d048213d2ac7)]: - - @moonshot-ai/agent-core-v2@0.4.0 - - @moonshot-ai/klient@0.1.2 diff --git a/packages/acp-server/package.json b/packages/acp-server/package.json index 46720ff5c..dc85d3be7 100644 --- a/packages/acp-server/package.json +++ b/packages/acp-server/package.json @@ -1,6 +1,6 @@ { "name": "@moonshot-ai/acp-server", - "version": "0.0.1", + "version": "0.0.0", "private": true, "description": "Agent Client Protocol (ACP) host backed directly by the DI × Scope agent engine (agent-core-v2)", "license": "MIT", diff --git a/packages/acp-server/src/acp-terminal/acpTerminalRunner.ts b/packages/acp-server/src/acp-terminal/acpTerminalRunner.ts index 9016d48b6..a644b657b 100644 --- a/packages/acp-server/src/acp-terminal/acpTerminalRunner.ts +++ b/packages/acp-server/src/acp-terminal/acpTerminalRunner.ts @@ -1,33 +1,69 @@ -import * as posixPath from 'node:path/posix'; -import * as win32Path from 'node:path/win32'; +/** + * `acp-terminal` — ACP-backed `ISessionProcessRunner`, the Slice-5 terminal + * reverse-RPC bridge. + * + * Registered at AGENT scope so it shadows the handler-seeded workspace runner + * for Agent-scope consumers (the Bash tool resolves `ISessionProcessRunner` + * at Agent scope). A Session-scope registration would lose to the + * `sessionLifecycleService` seed — `buildCollection` applies seeds after + * registered descriptors on the same scope level — while a child scope's own + * collection is consulted before the parent's (see `test/di-shadow.test.ts`). + * + * Capability gating: when the client did not advertise + * `clientCapabilities.terminal` (`IAcpConnection.terminalEnabled`), or the + * invocation does not look like a Bash-tool shell command, `exec` delegates + * to a local spawn with the exact semantics of the engine's + * `SessionProcessRunner` (per-call cwd wins over the session cwd; a per-call + * env is overlaid onto `process.env`). Behavior with the capability off is + * therefore identical to today's. + * + * Terminal lifecycle (capability on): + * `terminal/create` — once per `exec` (the client runs the command) + * `terminal/output` — polled while running; deltas feed `stdout` + * `terminal/wait_for_exit` — resolves `IProcess.wait()` with the exit code + * `terminal/kill` — `IProcess.kill()` (SIGTERM/SIGKILL both map here; + * the client owns the actual signal semantics) + * `terminal/release` — `IProcess.dispose()` (frees the terminal; the + * client kills the command if it is still running) + * + * Output de-duplication is handled by the adapter (`AcpSession`), which + * attaches a `{type: 'terminal'}` content entry to the tool card and + * suppresses the textual tool-result content for terminal-backed calls — the + * model still receives the full captured output, only the client card is + * de-duplicated. + */ + import { PassThrough, Writable, type Readable } from 'node:stream'; -import type { - HostEnvironmentInfo, - HostProcessOptions, - IHostEnvironment, - IHostFileSystem, - IHostProcess, +import { IHostProcessService, + type IProcess, ISessionContext, - Runtime, - RuntimePath, - RuntimeProviderAttachment, - RuntimeProviderContext, - RuntimeProviderFactory, - RuntimeProviderHost, + ISessionProcessRunner, + LifecycleScope, + type ProcessExecOptions, + registerScopedService, + ScopeActivation, } from '@moonshot-ai/agent-core-v2'; -import { AcpHostFileSystem, IAcpConnection, type IAcpTerminalHandle } from '../acp-fs'; +import { IAcpConnection, type IAcpTerminalHandle } from '../acp-fs'; +/** Retained-output ceiling handed to the client on `terminal/create`. */ const OUTPUT_BYTE_LIMIT = 4 * 1024 * 1024; +/** Polling cadence for `terminal/output` while the command runs. */ const OUTPUT_POLL_MS = 250; -let nextGeneration = 1; -function isBashToolInvocation(args: readonly string[], options?: HostProcessOptions): boolean { +/** + * Whether an `exec` call is the Bash tool's shell invocation. The Bash tool + * always spawns `[shellPath, '-c', 'cd <cwd> && <command>']` with the + * noninteractive env `{ NO_COLOR: '1', TERM: 'dumb', … }`; other Agent-scope + * callers (e.g. profile prompt-prefix commands) do not. Only Bash-tool + * invocations get a client-visible terminal — internal commands stay local. + */ +function isBashToolInvocation(args: readonly string[], options?: ProcessExecOptions): boolean { return ( - args.length === 2 && - args[0] === '-c' && + args.length === 3 && + args[1] === '-c' && options?.env?.['NO_COLOR'] === '1' && options?.env?.['TERM'] === 'dumb' ); @@ -40,50 +76,77 @@ function envRecordToAcp( return Object.entries(env).map(([name, value]) => ({ name, value })); } -class AcpProcessService implements IHostProcessService { +export class AcpProcessRunner implements ISessionProcessRunner { declare readonly _serviceBrand: undefined; constructor( - private readonly sessionId: string, - private readonly cwd: string, - private readonly connection: IAcpConnection, - private readonly local: IHostProcessService, + @ISessionContext private readonly ctx: ISessionContext, + @IAcpConnection private readonly connection: IAcpConnection, + @IHostProcessService private readonly hostProcess: IHostProcessService, ) {} - async spawn( - command: string, - args: readonly string[] = [], - options?: HostProcessOptions, - ): Promise<IHostProcess> { + async exec(args: readonly string[], options?: ProcessExecOptions): Promise<IProcess> { + const command = args[0]; + if (command === undefined) { + throw new Error( + 'AcpProcessRunner.exec(): at least one argument (the command to run) is required.', + ); + } if (!this.connection.terminalEnabled || !isBashToolInvocation(args, options)) { - return this.local.spawn(command, args, { ...options, cwd: options?.cwd ?? this.cwd }); + return this.execLocal(command, args.slice(1), options); } const handle = await this.connection.get().createTerminal({ - sessionId: this.sessionId, + sessionId: this.ctx.sessionId, command, - args: [...args], + args: args.slice(1), env: envRecordToAcp(options?.env), - cwd: options?.cwd ?? this.cwd, + cwd: options?.cwd ?? this.ctx.cwd, outputByteLimit: OUTPUT_BYTE_LIMIT, }); + // Tell the adapter which shell command this terminal runs so it can + // correlate the terminal with the in-flight Bash tool call. this.connection.notifyTerminalCreated({ - sessionId: this.sessionId, - shellCommand: args[1] ?? '', + sessionId: this.ctx.sessionId, + shellCommand: args[2] ?? '', terminalId: handle.id, }); return new AcpTerminalProcess(handle); } + + /** + * Local fallback with the engine `SessionProcessRunner` semantics: default + * cwd from the session context, per-call env overlaid onto `process.env`. + */ + private execLocal( + command: string, + restArgs: readonly string[], + options?: ProcessExecOptions, + ): Promise<IProcess> { + const cwd = options?.cwd ?? this.ctx.cwd; + const env = + options?.env === undefined + ? undefined + : { ...(process.env as Record<string, string>), ...options.env }; + return this.hostProcess.spawn(command, restArgs, { cwd, env }); + } } -class AcpTerminalProcess implements IHostProcess { - declare readonly _serviceBrand: undefined; +/** + * `IProcess` over an ACP client terminal. The terminal protocol exposes a + * single combined output stream (no stdout/stderr split), so `stdout` + * carries the polled output deltas and `stderr` stays empty. `stdin` is a + * sink — the protocol has no input channel. + */ +class AcpTerminalProcess implements IProcess { readonly stdin: Writable; readonly stdout: PassThrough; readonly stderr: Readable; + /** ACP terminals expose no pid; reported as 0 in background-task metadata. */ readonly pid = 0; private _exitCode: number | null = null; + /** Bytes of client output already forwarded to `stdout`. */ private emitted = 0; private readonly pollTimer: ReturnType<typeof setInterval>; private readonly waitPromise: Promise<number>; @@ -99,9 +162,14 @@ class AcpTerminalProcess implements IHostProcess { const stderr = new PassThrough(); stderr.end(); this.stderr = stderr; + const waitPromise = this.run(); + // Mark the rejection as handled: `wait()` consumers still observe it, but + // paths that kill+dispose without awaiting (spawn-error cleanup) must not + // crash the process with an unhandled rejection. waitPromise.catch(() => {}); this.waitPromise = waitPromise; + this.pollTimer = setInterval(() => { void this.pump(); }, OUTPUT_POLL_MS); @@ -117,6 +185,9 @@ class AcpTerminalProcess implements IHostProcess { } async kill(_signal?: NodeJS.Signals): Promise<void> { + // The protocol has a single kill operation; the client decides the + // signal. The terminal stays valid afterwards (final output still + // readable), matching the two-phase kill the task service performs. await this.handle.kill(); } @@ -127,18 +198,22 @@ class AcpTerminalProcess implements IHostProcess { try { await this.handle.release(); } catch { + // Best-effort — teardown must never throw. } } private async run(): Promise<number> { const status = await this.handle.waitForExit(); + // Mirror the host process semantics: signal termination reports -1. this._exitCode = status.exitCode ?? -1; + // Final flush catches output produced between the last poll and exit. await this.pump(); this.stopPolling(); this.stdout.end(); return this._exitCode; } + /** Forward newly-retained client output to `stdout`. */ private async pump(): Promise<void> { try { const { output } = await this.handle.currentOutput(); @@ -146,9 +221,13 @@ class AcpTerminalProcess implements IHostProcess { this.stdout.write(output.slice(this.emitted)); this.emitted = output.length; } else if (output.length < this.emitted) { + // The client truncated from the beginning to stay under the byte + // limit; the rotated-away middle is unrecoverable — skip ahead + // instead of re-emitting. this.emitted = output.length; } } catch { + // The terminal may be released mid-poll; the stream ends via run(). } } @@ -157,128 +236,10 @@ class AcpTerminalProcess implements IHostProcess { } } -class AcpSessionRuntime implements Runtime { - readonly identity; - readonly capabilities = new Set(['process', 'fs'] as const); - readonly environment: HostEnvironmentInfo; - readonly path: RuntimePath; - readonly workspace = { mapRoots: (roots: { workDir: string; additionalDirs?: readonly string[] }) => roots }; - readonly fs: IHostFileSystem; - readonly process; - readonly watch = undefined; - readonly terminal = undefined; - readonly status = 'ready' as const; - readonly onDidChangeStatus = () => ({ dispose: () => {} }); - - constructor( - workspaceId: string, - sessionId: string, - cwd: string, - connection: IAcpConnection, - environment: IHostEnvironment, - local: IHostProcessService, - ) { - this.identity = { - workspaceId, - runtimeId: AcpRuntimeProviderFactory.runtimeId(sessionId), - generation: `acp-${String(nextGeneration++)}`, - }; - this.environment = { - osKind: environment.osKind, - osArch: environment.osArch, - osVersion: environment.osVersion, - shellName: environment.shellName, - shellPath: environment.shellPath, - pathClass: environment.pathClass, - homeDir: environment.homeDir, - }; - const path = environment.pathClass === 'win32' ? win32Path : posixPath; - this.path = { - separator: path.sep as '/' | '\\', - delimiter: path.delimiter as ':' | ';', - isAbsolute: (p: string) => path.isAbsolute(p), - join: (...paths: readonly string[]) => path.join(...paths), - relative: (from: string, to: string) => path.relative(from, to), - resolve: (...paths: readonly string[]) => path.resolve(...paths), - basename: (p: string) => path.basename(p), - dirname: (p: string) => path.dirname(p), - }; - this.fs = new AcpHostFileSystem({ sessionId } as unknown as ISessionContext, connection); - this.process = new AcpProcessService(sessionId, cwd, connection, local); - } - - dispose(): void {} -} - -class AcpWorkspaceRuntimeAttachment implements RuntimeProviderAttachment { - private readonly sessions = new Map<string, { remove(): Promise<void> }>(); - - constructor( - private readonly workspace: RuntimeProviderContext, - private readonly host: RuntimeProviderHost, - private readonly connection: IAcpConnection, - private readonly environment: IHostEnvironment, - private readonly local: IHostProcessService, - ) {} - - bindSession(sessionId: string, cwd: string): string { - const runtimeId = AcpRuntimeProviderFactory.runtimeId(sessionId); - if (this.sessions.has(sessionId)) return runtimeId; - const registration = this.host.registerRuntime( - new AcpSessionRuntime(this.workspace.id, sessionId, cwd, this.connection, this.environment, this.local), - ); - this.sessions.set(sessionId, registration); - return runtimeId; - } - - async unbindSession(sessionId: string): Promise<void> { - const registration = this.sessions.get(sessionId); - if (registration === undefined) return; - this.sessions.delete(sessionId); - await registration.remove(); - } - - async dispose(): Promise<void> { - const registrations = [...this.sessions.values()]; - this.sessions.clear(); - for (const registration of registrations.reverse()) await registration.remove(); - } -} - -export class AcpRuntimeProviderFactory implements RuntimeProviderFactory { - readonly id = 'acp'; - readonly imports = { root: [], imports: [], local: [] }; - private readonly attachments = new Map<string, AcpWorkspaceRuntimeAttachment>(); - - constructor( - private readonly connection: IAcpConnection, - private readonly environment: IHostEnvironment, - private readonly local: IHostProcessService, - ) {} - - static runtimeId(sessionId: string): string { - return `acp:${sessionId}`; - } - - async attach(workspace: RuntimeProviderContext, host: RuntimeProviderHost): Promise<RuntimeProviderAttachment> { - const attachment = new AcpWorkspaceRuntimeAttachment(workspace, host, this.connection, this.environment, this.local); - this.attachments.set(workspace.id, attachment); - return { - dispose: async () => { - if (this.attachments.get(workspace.id) !== attachment) return; - this.attachments.delete(workspace.id); - await attachment.dispose(); - }, - }; - } - - bindSession(workspaceId: string, sessionId: string, cwd: string): string { - const attachment = this.attachments.get(workspaceId); - if (attachment === undefined) throw new Error(`ACP runtime provider is not attached to workspace ${workspaceId}`); - return attachment.bindSession(sessionId, cwd); - } - - async unbindSession(workspaceId: string, sessionId: string): Promise<void> { - await this.attachments.get(workspaceId)?.unbindSession(sessionId); - } -} +registerScopedService( + LifecycleScope.Agent, + ISessionProcessRunner, + AcpProcessRunner, + ScopeActivation.OnDemand, + 'acp', +); diff --git a/packages/acp-server/src/acp-terminal/index.ts b/packages/acp-server/src/acp-terminal/index.ts index 1035d11d3..afbcb966b 100644 --- a/packages/acp-server/src/acp-terminal/index.ts +++ b/packages/acp-server/src/acp-terminal/index.ts @@ -1 +1,12 @@ -export { AcpRuntimeProviderFactory } from './acpTerminalRunner'; +/** + * `acp-terminal` barrel — registers the ACP-backed Agent-scope + * `ISessionProcessRunner`. + * + * Imported for its module side effects by `start.ts` before any session is + * created, so the runner shadow is in place when the first agent scope is + * built. + */ + +import './acpTerminalRunner'; + +export { AcpProcessRunner } from './acpTerminalRunner'; diff --git a/packages/acp-server/src/convert.ts b/packages/acp-server/src/convert.ts index 48c34bff6..3e405039a 100644 --- a/packages/acp-server/src/convert.ts +++ b/packages/acp-server/src/convert.ts @@ -181,7 +181,6 @@ export function acpMcpServersToConfigRecord( command: server.command, args: server.args, env: namedPairsToRecord(server.env), - runtime_id: 'local', }; continue; } diff --git a/packages/acp-server/src/index.ts b/packages/acp-server/src/index.ts index 397c5478c..5f4a9acd0 100644 --- a/packages/acp-server/src/index.ts +++ b/packages/acp-server/src/index.ts @@ -86,7 +86,7 @@ export { questionRequestToElicitationParams, } from './question'; export { projectHistoryToSessionUpdates } from './replay'; -export { AcpRuntimeProviderFactory } from './acp-terminal'; +export { AcpProcessRunner } from './acp-terminal'; export type { AcpTerminalCreatedEvent, AcpTerminalCreatedListener, diff --git a/packages/acp-server/src/server.ts b/packages/acp-server/src/server.ts index 6e4ee8784..4f1b3e464 100644 --- a/packages/acp-server/src/server.ts +++ b/packages/acp-server/src/server.ts @@ -63,7 +63,6 @@ import type { SessionRestoreOptions, SessionSummary, } from '@moonshot-ai/klient'; -import { ErrorCodes, isError2 } from '@moonshot-ai/agent-core-v2'; import { RPCError } from '@moonshot-ai/klient'; import type { AcpClient } from './acp-client'; @@ -81,13 +80,6 @@ import { negotiateVersion } from './version'; */ const SESSION_NOT_FOUND_CODE = 40404; -function isSessionNotFound(error: unknown): boolean { - return ( - (error instanceof RPCError && error.code === SESSION_NOT_FOUND_CODE) || - (isError2(error) && error.code === ErrorCodes.SESSION_NOT_FOUND) - ); -} - /** Host-provided slash commands plus optional aliases that activate engine skills. */ export interface SlashCommandsSnapshot { readonly commands: ReadonlyArray<AvailableCommand>; @@ -135,8 +127,6 @@ export interface AcpServerOptions { * scope. Absent → `persistOriginalImage`'s shared temp-dir fallback. */ readonly resolveOriginalsDir?: (sessionId: string) => string | undefined; - readonly bindSessionRuntime?: (sessionId: string) => Promise<void>; - readonly unbindSessionRuntime?: (sessionId: string) => Promise<void>; /** Static or per-session host command palette, compatible with acp-adapter. */ readonly slashCommands?: SlashCommandsResolver; } @@ -148,8 +138,6 @@ export class AcpServer { private readonly terminalAuthEnv: Readonly<Record<string, string>> | undefined; private readonly terminalAuthLegacyCommand: string | undefined; private readonly resolveOriginalsDir: ((sessionId: string) => string | undefined) | undefined; - private readonly bindSessionRuntime: ((sessionId: string) => Promise<void>) | undefined; - private readonly unbindSessionRuntime: ((sessionId: string) => Promise<void>) | undefined; private readonly resolveSlashCommands: ( session: SessionHandle, ) => Promise<ReadonlyArray<AvailableCommand> | SlashCommandsSnapshot>; @@ -171,8 +159,6 @@ export class AcpServer { this.terminalAuthEnv = opts.terminalAuthEnv; this.terminalAuthLegacyCommand = opts.terminalAuthLegacyCommand; this.resolveOriginalsDir = opts.resolveOriginalsDir; - this.bindSessionRuntime = opts.bindSessionRuntime; - this.unbindSessionRuntime = opts.unbindSessionRuntime; const slashCommands = opts.slashCommands; this.resolveSlashCommands = typeof slashCommands === 'function' @@ -275,7 +261,7 @@ export class AcpServer { try { forkedId = (await this.klient.session(params.sessionId).fork()).id; } catch (error) { - if (isSessionNotFound(error)) { + if (error instanceof RPCError && error.code === SESSION_NOT_FOUND_CODE) { throw RequestError.invalidParams( { sessionId: params.sessionId }, `Unknown sessionId: ${params.sessionId}`, @@ -337,7 +323,6 @@ export class AcpServer { this.sessions.delete(params.sessionId); } await this.klient.session(params.sessionId).close(); - await this.unbindSessionRuntime?.(params.sessionId); } /** @@ -352,7 +337,7 @@ export class AcpServer { try { await this.klient.session(params.sessionId).delete(); } catch (error) { - if (isSessionNotFound(error)) { + if (error instanceof RPCError && error.code === SESSION_NOT_FOUND_CODE) { throw RequestError.invalidParams( { sessionId: params.sessionId }, `Unknown sessionId: ${params.sessionId}`, @@ -365,7 +350,6 @@ export class AcpServer { acpSession.dispose(); this.sessions.delete(params.sessionId); } - await this.unbindSessionRuntime?.(params.sessionId); return {}; } @@ -555,7 +539,6 @@ export class AcpServer { private async wireSession(sessionId: string): Promise<AcpSession> { const session = this.klient.session(sessionId); await this.bindDefaultModel(session.agent('main')); - await this.bindSessionRuntime?.(sessionId); const hostCommands = await this.resolveSlashCommands(session); const acpSession = new AcpSession( this.conn, diff --git a/packages/acp-server/src/session.ts b/packages/acp-server/src/session.ts index 9c82c912e..66741fe42 100644 --- a/packages/acp-server/src/session.ts +++ b/packages/acp-server/src/session.ts @@ -552,8 +552,8 @@ export class AcpSession { } /** - * Activate a skill through the engine (the agent's `AgentSkill` runtime - * behind the klient facade): the engine renders the skill prompt (content + args) + * Activate a skill through the engine (`IAgentSkillService.activate` behind + * the klient facade): the engine renders the skill prompt (content + args) * and drives it as a normal turn, so the turn events stream and settle * exactly like a plain prompt. Empty args go over as `undefined`, matching * the other consumers. diff --git a/packages/acp-server/src/start.ts b/packages/acp-server/src/start.ts index 5b60cac57..47835ecee 100644 --- a/packages/acp-server/src/start.ts +++ b/packages/acp-server/src/start.ts @@ -16,20 +16,13 @@ import { Readable, Writable } from 'node:stream'; import { ndJsonStream, type AgentConnection, type Stream } from '@agentclientprotocol/sdk'; import { bootstrap, - drainLogCloses, drainQueryStoreDisposals, drainSessionIndexMirror, drainSessionMetadataWrites, - ensureMainAgent, getLiveSessionById, - IAgentLifecycleService, - IAgentRuntimeBindingService, IAppendLogStore, - IHostEnvironment, - IHostProcessService, ISessionContext, ISessionIndexMirror, - IWorkspaceInstanceManager, logSeed, resolveConfigPath, resolveKimiHome, @@ -47,7 +40,9 @@ import { acpClientFromContext } from './acp-client'; // module side effects. `IAcpConnection` is used below to bind the ACP client // connection. import { IAcpConnection } from './acp-fs'; -import { AcpRuntimeProviderFactory } from './acp-terminal'; +// Importing the `acp-terminal` barrel registers the ACP-backed Agent-scope +// `ISessionProcessRunner` (capability-gated — see the module doc). +import './acp-terminal'; import { AcpServer, type AcpServerOptions, createAcpAgentApp } from './server'; export interface RunAcpServerOptions extends AcpServerOptions { @@ -142,35 +137,12 @@ export async function runAcpServerWithStream( // file IO. The `acp` `IHostFileSystem` reads it lazily via // `IAcpConnection.get()`. acpConnection.bind(client); - const workspaceManager = core.accessor.get(IWorkspaceInstanceManager); - const acpRuntimeProvider = new AcpRuntimeProviderFactory(acpConnection, core.accessor.get(IHostEnvironment), core.accessor.get(IHostProcessService)); - const acpProviderRegistration = await workspaceManager.addProvider(acpRuntimeProvider); - const sessionWorkspaces = new Map<string, string>(); server = new AcpServer(client, klient, acpConnection, { agentInfo: opts.agentInfo, disableAuth: opts.disableAuth, terminalAuthEnv: opts.terminalAuthEnv, terminalAuthLegacyCommand: opts.terminalAuthLegacyCommand, slashCommands: opts.slashCommands, - bindSessionRuntime: async (sessionId) => { - const handle = getLiveSessionById(core.accessor, sessionId); - if (handle === undefined) throw new Error(`session ${sessionId} is not live`); - const context = handle.accessor.get(ISessionContext); - const runtimeId = acpRuntimeProvider.bindSession(context.workspaceId, sessionId, context.cwd); - sessionWorkspaces.set(sessionId, context.workspaceId); - const agentContext = await ensureMainAgent(handle, { runtimeId }); - handle.accessor - .get(IAgentLifecycleService) - .handleOf(agentContext.agentId)! - .accessor.get(IAgentRuntimeBindingService) - .switch(runtimeId); - }, - unbindSessionRuntime: async (sessionId) => { - const workspaceId = sessionWorkspaces.get(sessionId); - if (workspaceId === undefined) return; - sessionWorkspaces.delete(sessionId); - await acpRuntimeProvider.unbindSession(workspaceId, sessionId); - }, // Prompt-image compression persists originals into the session's own // media-originals dir (same resolution as kap-server's prompt route): // live session scope → `ISessionContext.sessionDir`. A session that is @@ -193,9 +165,8 @@ export async function runAcpServerWithStream( // Flush the append-log write-behind before disposing, so a clean shutdown // never races a pending drain against teardown (and doesn't drop the last // persisted ops). Best-effort: a flush failure must not block disposal. - const appendLogStore = core.accessor.get(IAppendLogStore); try { - await appendLogStore.flush(); + await core.accessor.get(IAppendLogStore).flush(); } catch { // ignore — disposal proceeds regardless } @@ -204,18 +175,14 @@ export async function runAcpServerWithStream( // still open, so a queued summary lands in the read model. await drainSessionMetadataWrites(); await core.accessor.get(ISessionIndexMirror).drain(); - await acpProviderRegistration.dispose(); core.dispose(); // `core.dispose()` runs the mirror's and the query store's synchronous // `dispose()`, whose drains/closes are asynchronous — await them so an // embedding host that removes homeDir right after close() never races - // an in-flight shard close (ENOTEMPTY on teardown). The same window - // exists for the append-log retirement flushes released by disposal. - await appendLogStore.drainRetirements(); + // an in-flight shard close (ENOTEMPTY on teardown). await drainSessionIndexMirror(); await drainQueryStoreDisposals(); await drainSessionMetadataWrites(); - await drainLogCloses(); })(); return closePromise; }; diff --git a/packages/acp-server/test/acp-terminal.test.ts b/packages/acp-server/test/acp-terminal.test.ts deleted file mode 100644 index 30b83d19f..000000000 --- a/packages/acp-server/test/acp-terminal.test.ts +++ /dev/null @@ -1,196 +0,0 @@ -import { describe, expect, it } from 'vitest'; - -import type { - HostProcessOptions, - IHostEnvironment, - IHostProcess, - IHostProcessService, - Runtime, - RuntimeProviderHost, -} from '@moonshot-ai/agent-core-v2'; - -import type { IAcpConnection, IAcpTerminalHandle } from '../src/acp-fs/acpConnection'; -import { AcpHostFileSystem } from '../src/acp-fs/acpFsService'; -import { AcpRuntimeProviderFactory } from '../src/acp-terminal/acpTerminalRunner'; - -function makeConnection( - options: { terminalEnabled?: boolean; createTerminal?: () => IAcpTerminalHandle } = {}, -): IAcpConnection { - return { - _serviceBrand: undefined, - bound: true, - fsReadTextFile: true, - fsWriteTextFile: true, - terminalEnabled: options.terminalEnabled ?? true, - bind: () => {}, - get: () => ({ createTerminal: async () => options.createTerminal?.() }) as never, - bindFsCapabilities: () => {}, - bindTerminalCapability: () => {}, - notifyTerminalCreated: () => {}, - onTerminalCreated: () => () => {}, - }; -} - -interface LocalSpawnCall { - readonly command: string; - readonly args: readonly string[]; - readonly options: HostProcessOptions | undefined; -} - -function makeLocalProcessService(): { local: IHostProcessService; calls: LocalSpawnCall[] } { - const calls: LocalSpawnCall[] = []; - const local: IHostProcessService = { - _serviceBrand: undefined, - spawn: async (command, args = [], options) => { - calls.push({ command, args, options }); - return {} as IHostProcess; - }, - }; - return { local, calls }; -} - -function makeEnvironment(overrides: Partial<IHostEnvironment> = {}): IHostEnvironment { - return { - _serviceBrand: undefined, - osKind: 'macOS', - osArch: 'arm64', - osVersion: '24.0.0', - shellName: 'bash', - shellPath: '/bin/bash', - pathClass: 'posix', - homeDir: '/Users/test', - ready: Promise.resolve(), - ...overrides, - } as IHostEnvironment; -} - -async function bindRuntime( - environment: IHostEnvironment, - options: { connection?: IAcpConnection; local?: IHostProcessService } = {}, -): Promise<Runtime> { - const runtimes: Runtime[] = []; - const host = { - registerRuntime: (runtime: Runtime) => { - runtimes.push(runtime); - return { remove: async () => {} }; - }, - } as unknown as RuntimeProviderHost; - const factory = new AcpRuntimeProviderFactory( - options.connection ?? makeConnection(), - environment, - options.local ?? makeLocalProcessService().local, - ); - await factory.attach({ id: 'w1' } as never, host); - factory.bindSession('w1', 's1', '/repo'); - const runtime = runtimes[0]; - if (runtime === undefined) throw new Error('runtime was not registered'); - return runtime; -} - -describe('AcpSessionRuntime', () => { - it('mirrors the probed host environment and exposes fs + process capabilities', async () => { - const runtime = await bindRuntime(makeEnvironment()); - - expect([...runtime.capabilities].sort()).toEqual(['fs', 'process']); - expect(runtime.environment).toMatchObject({ - osKind: 'macOS', - osArch: 'arm64', - shellName: 'bash', - shellPath: '/bin/bash', - pathClass: 'posix', - homeDir: '/Users/test', - }); - expect(runtime.fs).toBeInstanceOf(AcpHostFileSystem); - expect(runtime.path.isAbsolute('/repo')).toBe(true); - }); - - it('adapts path semantics and shell to a win32 host environment', async () => { - const runtime = await bindRuntime( - makeEnvironment({ - osKind: 'Windows', - osArch: 'x64', - shellName: 'bash', - shellPath: 'C:\\Program Files\\Git\\bin\\bash.exe', - pathClass: 'win32', - homeDir: 'C:\\Users\\test', - }), - ); - - expect(runtime.environment).toMatchObject({ - osKind: 'Windows', - shellPath: 'C:\\Program Files\\Git\\bin\\bash.exe', - pathClass: 'win32', - homeDir: 'C:\\Users\\test', - }); - expect(runtime.path.separator).toBe('\\'); - expect(runtime.path.isAbsolute('C:\\repo')).toBe(true); - expect(runtime.path.isAbsolute('repo')).toBe(false); - expect(runtime.path.resolve('C:\\repo', 'src')).toBe('C:\\repo\\src'); - }); -}); - -describe('AcpProcessService local fallback', () => { - const bashEnv = { NO_COLOR: '1', TERM: 'dumb' }; - - function makeTerminalHandle(): IAcpTerminalHandle { - return { - id: 'term-1', - currentOutput: async () => ({ output: '', truncated: false }), - waitForExit: async () => ({ exitCode: 0 }), - kill: async () => ({}), - release: async () => ({}), - }; - } - - it('runs Bash-shaped spawns in the client terminal when the capability is advertised', async () => { - let created = 0; - const connection = makeConnection({ - terminalEnabled: true, - createTerminal: () => { - created += 1; - return makeTerminalHandle(); - }, - }); - const { local, calls } = makeLocalProcessService(); - const runtime = await bindRuntime(makeEnvironment(), { connection, local }); - - await runtime.process!.spawn('/bin/bash', ['-c', 'echo hi'], { env: { ...bashEnv } }); - - expect(created).toBe(1); - expect(calls).toHaveLength(0); - }); - - it('falls back to local execution for Bash-shaped spawns without the terminal capability', async () => { - const connection = makeConnection({ terminalEnabled: false }); - const { local, calls } = makeLocalProcessService(); - const runtime = await bindRuntime(makeEnvironment(), { connection, local }); - - await runtime.process!.spawn('/bin/bash', ['-c', 'echo hi'], { env: { ...bashEnv } }); - - expect(calls).toHaveLength(1); - expect(calls[0]).toMatchObject({ - command: '/bin/bash', - args: ['-c', 'echo hi'], - options: { env: bashEnv, cwd: '/repo' }, - }); - }); - - it('falls back to local execution for non-Bash spawns even with the terminal capability', async () => { - let created = 0; - const connection = makeConnection({ - terminalEnabled: true, - createTerminal: () => { - created += 1; - return makeTerminalHandle(); - }, - }); - const { local, calls } = makeLocalProcessService(); - const runtime = await bindRuntime(makeEnvironment(), { connection, local }); - - await runtime.process!.spawn('rg', ['--files', '--hidden']); - - expect(created).toBe(0); - expect(calls).toHaveLength(1); - expect(calls[0]).toMatchObject({ command: 'rg', args: ['--files', '--hidden'], options: { cwd: '/repo' } }); - }); -}); diff --git a/packages/acp-server/test/convert.test.ts b/packages/acp-server/test/convert.test.ts index 5dd8482d2..fe34f1662 100644 --- a/packages/acp-server/test/convert.test.ts +++ b/packages/acp-server/test/convert.test.ts @@ -19,7 +19,7 @@ describe('acpMcpServersToConfigRecord', () => { expect(acpMcpServersToConfigRecord([])).toBeUndefined(); }); - it('maps stdio servers (no type field) to local stdio configs', () => { + it('maps stdio servers (no `type` discriminator) with env pairs as a record', () => { const servers: McpServer[] = [ { name: 'fs', @@ -37,7 +37,6 @@ describe('acpMcpServersToConfigRecord', () => { command: '/usr/local/bin/mcp-fs', args: ['--root', '/tmp'], env: { API_KEY: 'secret', DEBUG: '1' }, - runtime_id: 'local', }, }); }); diff --git a/packages/acp-server/test/e2e-turn.test.ts b/packages/acp-server/test/e2e-turn.test.ts index db4c1e937..b14a327e4 100644 --- a/packages/acp-server/test/e2e-turn.test.ts +++ b/packages/acp-server/test/e2e-turn.test.ts @@ -15,7 +15,6 @@ import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; import { getLiveSessionById, IAgentLifecycleService, IEventBus } from '@moonshot-ai/agent-core-v2'; -import { ToolProgress } from '@moonshot-ai/agent-core-v2/agent/toolExecutor/toolExecutorEvents'; import { afterEach, describe, expect, it } from 'vitest'; import { mapPromptLaunchError } from '../src/session'; @@ -45,25 +44,12 @@ describe('acp-server real prompt turn (scripted LLM)', () => { } }); - function installTerminalClient(c: TestClient): void { - c.onRequest('terminal/create', () => ({ terminalId: 'term-1' })); - c.onRequest('terminal/output', () => ({ - output: 'hello_from_bash\ndelta_stream\n', - truncated: false, - exitStatus: { exitCode: 0, signal: null }, - })); - c.onRequest('terminal/wait_for_exit', () => ({ exitCode: 0, signal: null })); - c.onRequest('terminal/kill', () => ({})); - c.onRequest('terminal/release', () => ({})); - } - async function boot(clientCapabilities: Record<string, unknown> = {}): Promise<TestClient> { homeDir = await mkdtemp(join(tmpdir(), 'acp-e2e-turn-')); await writeFakeModelConfig(homeDir); scripted = createScriptedProvider(); client = await createTestClient({ homeDir, extraSeeds: [scripted.seed] }); await client.send('initialize', { protocolVersion: 1, clientCapabilities }); - if (clientCapabilities['terminal'] === true) installTerminalClient(client); return client; } @@ -106,7 +92,7 @@ describe('acp-server real prompt turn (scripted LLM)', () => { }, 30_000); it('runs a tool call and bridges the approval request to the client', async () => { - const c = await boot({ terminal: true }); + const c = await boot(); // First model response: a Bash tool call. Second: a short text wrap-up // after the tool result is fed back to the model. scripted!.mockNextResponse({ @@ -162,7 +148,8 @@ describe('acp-server real prompt turn (scripted LLM)', () => { .map((m) => (m.params as { update?: ToolCallUpdate }).update) .find((u) => u?.sessionUpdate === 'tool_call_update' && u?.status === 'completed'); expect(terminal).toBeDefined(); - expect(JSON.stringify(scripted!.callHistory()[1])).toContain('hello_from_bash'); + const text = terminal?.content?.map((c) => c.content?.text ?? '').join('\n') ?? ''; + expect(text).toContain('hello_from_bash'); }, 30_000); it('bridges AskUserQuestion through elicitation/create for form-capable clients', async () => { @@ -407,7 +394,7 @@ describe('acp-server real prompt turn (scripted LLM)', () => { }, 30_000); it('streams tool-call args deltas: lazy pending CREATE → cumulative update → started upgrade → completed', async () => { - const c = await boot({ terminal: true }); + const c = await boot(); // Args stream in two fragments; the merge yields the full command. scripted!.mockNextResponse( { type: 'function', id: 'call_1', name: 'Bash', arguments: '{"command":"ec' }, @@ -471,7 +458,7 @@ describe('acp-server real prompt turn (scripted LLM)', () => { const terminal = updates.at(-1); expect(terminal?.sessionUpdate).toBe('tool_call_update'); expect(terminal?.status).toBe('completed'); - expect(JSON.stringify(scripted!.callHistory()[1])).toContain('delta_stream'); + expect(textOf(terminal)).toContain('delta_stream'); }, 30_000); it('refreshes the tool card title on a status progress update and drops other progress kinds', async () => { @@ -506,25 +493,21 @@ describe('acp-server real prompt turn (scripted LLM)', () => { const wireId = (create.params as { update?: { toolCallId?: string } }).update?.toolCallId; const turnId = Number(wireId?.split(':')[0]); const session = getLiveSessionById(c.server.core.accessor, created.sessionId); - const agentHandle = session?.accessor.get(IAgentLifecycleService).handleOf('main'); + const agentHandle = session?.accessor.get(IAgentLifecycleService).get('main'); const bus = agentHandle?.accessor.get(IEventBus); expect(bus).toBeDefined(); - bus!.publish( - new ToolProgress({ - agentId: 'main', - turnId, - toolCallId: 'call_1', - update: { kind: 'stdout', text: 'raw-stdout-bytes' }, - }), - ); - bus!.publish( - new ToolProgress({ - agentId: 'main', - turnId, - toolCallId: 'call_1', - update: { kind: 'status', text: 'Still working…' }, - }), - ); + bus!.publish({ + type: 'tool.progress', + turnId, + toolCallId: 'call_1', + update: { kind: 'stdout', text: 'raw-stdout-bytes' }, + }); + bus!.publish({ + type: 'tool.progress', + turnId, + toolCallId: 'call_1', + update: { kind: 'status', text: 'Still working…' }, + }); const result = (await promptPromise) as { stopReason: string }; expect(result.stopReason).toBe('end_turn'); @@ -725,10 +708,10 @@ describe('acp-server builtin slash commands (local execution, no LLM turn)', () cwd: homeDir, mcpServers: [ { - type: 'http', name: 'mock', - url: 'http://127.0.0.1:1/mcp', - headers: [{ name: 'X-Test-Fixture', value: STDIO_MCP_FIXTURE }], + command: process.execPath, + args: [STDIO_MCP_FIXTURE], + env: [{ name: 'KIMI_TEST_MCP_START_DELAY_MS', value: '0' }], }, ], })) as { sessionId: string }; @@ -737,7 +720,7 @@ describe('acp-server builtin slash commands (local execution, no LLM turn)', () const { chunk, stopReason } = await runSlash(c, created.sessionId, '/mcp'); expect(stopReason).toBe('end_turn'); expect(chunk).toContain('MCP servers (1):'); - expect(chunk).toContain('- mock (http):'); + expect(chunk).toContain('- mock (stdio):'); expect(scripted!.callCount()).toBe(0); }, 30_000); @@ -999,7 +982,7 @@ describe('acp-server terminal reverse-RPC (clientCapabilities.terminal)', () => const { stopReason } = await runPrompt(c); expect(stopReason).toBe('end_turn'); - // No terminal reverse-RPC at all — the command ran locally. + // No terminal reverse-RPC at all — behavior identical to today. expect(terminals).toHaveLength(0); const terminalRpcs = c.received.filter( (m) => typeof m.method === 'string' && m.method.startsWith('terminal/'), diff --git a/packages/acp-server/test/lifecycle.test.ts b/packages/acp-server/test/lifecycle.test.ts index 5b505203f..f6e910fd7 100644 --- a/packages/acp-server/test/lifecycle.test.ts +++ b/packages/acp-server/test/lifecycle.test.ts @@ -5,9 +5,10 @@ import { fileURLToPath } from 'node:url'; import { IOAuthToolkit, - ISessionManager, + ISessionLifecycleService, ISessionMcpHandle, - IWorkspaceInstanceManager, + IWorkspaceDirs, + IWorkspaceLifecycleService, } from '@moonshot-ai/agent-core-v2'; import { afterEach, describe, expect, it } from 'vitest'; @@ -92,11 +93,11 @@ describe('acp-server session lifecycle', () => { async function sessionMcpEntries( c: TestClient, sessionId: string, - ): Promise<readonly { readonly name: string; readonly status: string; readonly error?: string }[]> { - await c.server.core.accessor - .get(IWorkspaceInstanceManager) - .getOrCreate({ root: homeDir! }); - const handle = c.server.core.accessor.get(ISessionManager).get(sessionId); + ): Promise<readonly { readonly name: string; readonly status: string }[]> { + const handler = await c.server.core.accessor + .get(IWorkspaceLifecycleService) + .handlerFor({ root: homeDir! }); + const handle = handler.accessor.get(ISessionLifecycleService).get(sessionId); expect(handle).toBeDefined(); const mcp = handle!.accessor.get(ISessionMcpHandle); await mcp.ready; @@ -354,10 +355,10 @@ describe('acp-server session lifecycle', () => { // The workspace handler merges create-time dirs into its // (ephemeral) additional-dir set. - const workspace = await c.server.core.accessor - .get(IWorkspaceInstanceManager) - .getOrCreate({ root: homeDir! }); - const dirs = workspace.program.dirs; + const handler = await c.server.core.accessor + .get(IWorkspaceLifecycleService) + .handlerFor({ root: homeDir! }); + const dirs = handler.accessor.get(IWorkspaceDirs); await dirs.ready; expect(dirs.additionalDirs).toContain(extraDir); }, diff --git a/packages/agent-core-v2/AGENTS.md b/packages/agent-core-v2/AGENTS.md index 43b6e2e3a..d7509008c 100644 --- a/packages/agent-core-v2/AGENTS.md +++ b/packages/agent-core-v2/AGENTS.md @@ -10,22 +10,22 @@ Four `LifecycleScope` tiers — `App` / `Workspace` / `Session` / `Agent` (strin The DI kernel (`src/_base/di/`) owns the unit layer on top of the scoped registry: -- `service.ts` — `Service`: the unit base class (extends `Disposable`). Capabilities live on `this` (`provide` / `effect` / `on` / `get` / `ref`, plus `name` / `state` / `config`). Two-phase construction: inside the ctor `provide`/`on`/`effect` buffer (writes only — `get`/`ref` throw, dependencies are constructor parameters); the kernel binds the runtime after `Reflect.construct` and flushes in writing order; a manually `new`ed instance throws on every capability call. Services whose own members collide with the `Service` vocabulary keep `extends Disposable` — still full DI units (cascade/ledger do not require `Service`). +- `service.ts` — `Service`: the unit base class (extends `Disposable`). Capabilities live on `this` (`provide` / `effect` / `on` / `get` / `ref`, plus `name` / `state` / `config`). Two-phase construction: inside the ctor `provide`/`on`/`effect` buffer (writes only — `get`/`ref` throw, dependencies are constructor parameters); the kernel binds the runtime after `Reflect.construct` and flushes in writing order; a manually `new`ed instance throws on every capability call. Services whose own members collide with the `Service` vocabulary keep `extends Disposable` with a NOTE comment — still full DI units (cascade/ledger do not require `Service`). - `fiber.ts` — the `Fiber` capability interface (not a DI token), `FiberHandle` (thenable / `state` / `uid` / `update` / `dispose`), `ServiceRecipe` (class / arrow function / `{apply}`), the `FiberState` five-state machine, and `ScopeUnits(kind)` — the materialization collection token, one per scope kind. - `collection.ts` — `collection<T>(name)` contribution tokens. Contribute with `this.provide(token, value)`; a fold declares the token as a constructor parameter and receives a `CollectionView<T>` (`items` / `records` / incremental `onDidChange`). Records are visible to the provider's ancestors and descendants (never sibling subtrees); provider death withdraws. Collection edges enter the graph for introspection but never join a cascade contagion set. - `scopeUnits.ts` — the kernel fold: every scope-creation point (`createScopedChildHandle` / `Scope.createApp` / `Scope.createChild`) runs `watchScopeUnits(container, kind)` before eager activation, materializing each visible `ScopeUnits(kind)` record's recipe as a unit inside the new scope (disposal hangs on the record provider's book — provider death tears the materialized units down across the tree). `ScopeOptions.configureContainer` runs at the same point (the session seed adapters use it). - `instantiation.ts` — the `@ref(IX)` decorator factory (`LiveRef<T>`: `current` live read + `onDidChange` availability event; observation creates no binding and no graph edge) and `ScopeActivation`. - `src/app/feature/` — `IFeatureManager` (App scope): runtime unit assembly (`provideUnit` / `unprovideUnit` / `updateUnit`) and introspection (`units()` / `onDidChangeUnits`); managed units hang on the manager's own book. External package management stays with `IPluginService`. The `features` assembly (`src/features/featureAssemblyService.ts`) drains the module-level feature table through it. -The four contribution seams (token → fold): config sections — `ConfigSectionContribution` → `ConfigRegistry` fold (`src/app/config/`; module-level `registerConfigSection` stays the static built-in channel drained at construction, a withdrawn runtime record unregisters the section while user TOML values survive); agent tools — `AgentToolContribution` → `AgentToolActivationService` fold (built-in records provided once at App scope by `builtinToolAssemblyService`; `registerAgentToolService` stays the static channel: Agent-scope DI `OnDemand` registration + module table); agent profiles — `AgentProfileContribution` → `IAgentProfileRegistry` fold (see Scopes); event/state vocabulary — `EventStateContribution` → `IEventDispatcher` fold (a record bundles `events`; `registerEvent2Class` stays the static channel drained at fold time, while `defineState(...).replayable(...)` keys are explicit owner-service contributions: each replayable key's owning service contributes it via `contributeState` at construction — Agent-scope owners are eager — while the todo/cron/interaction/goal domains are Agent Runtime definitions (`contributeAgentRuntime`): their durable participants attach to the agent's dispatcher before `restore()` through `ManagedAgent.attachDurableRuntimes`, and replaying a withdrawn domain's history lands on the unknown-type skip-and-count path). A fifth seam: executable commands — `CommandContribution` → `IAgentCommandService` fold (`src/agent/command/`; a contributed command runs engine-side — `run(ctx)` gets `ctx.get` resolving through the agent container, valid only during the synchronous part of `run`; name-level dedup, last record wins; surfaced over RPC as `agentCommandService.list` / `run`). +The four contribution seams (token → fold): config sections — `ConfigSectionContribution` → `ConfigRegistry` fold (`src/app/config/`; module-level `registerConfigSection` stays the static built-in channel drained at construction, a withdrawn runtime record unregisters the section while user TOML values survive); agent tools — `AgentToolContribution` → `AgentToolActivationService` fold (built-in records provided once at App scope by `builtinToolAssemblyService`; `registerAgentToolService` stays the static channel: Agent-scope DI `OnDemand` registration + module table); agent profiles — `AgentProfileContribution` → `IAgentProfileRegistry` fold (see Scopes); wire vocabulary — `WireModelContribution` → `WireService` fold (a record bundles `models` / `ops` / `crossReducers` / `checkpointedModels`; the built-in layer is the module tables drained at fold time — `defineOp` / `defineModel` / `defineCheckpointedModel` stay the static channel — and replaying a withdrawn domain's history lands on the unknown-op skip-and-count path). A fifth seam: executable commands — `CommandContribution` → `IAgentCommandService` fold (`src/agent/command/`; a contributed command runs engine-side — `run(ctx)` gets `ctx.get` resolving through the agent container, valid only during the synchronous part of `run`; name-level dedup, last record wins; surfaced over RPC as `agentRPCService.listCommands` / `runCommand`). -`src/features/` — built-in capabilities authored as self-contained Feature units (`plan` was the first, extracted from `agent/plan` + `agent/tools/plan`; `externalHooks` from `app/externalHooksRunner` + `session/externalHooks` + `agent/externalHooks`; `swarm` followed, extracted from `agent/swarm` + `session/swarm` + `agent/tools/agent-swarm` into a scope-organized `agent/` + `session/` + `tools/` layout; `goal` followed, extracted from `agent/goal` + `agent/tools/goal`; `skill` followed, extracted from `app/skillCatalog` + `workspace/workspaceSkillCatalog` + `session/sessionSkillCatalog` + `agent/skill` + `agent/tools/skill` into a `catalog/` + `workspace/` + `session/` + `tools/` layout around the lazy non-durable `AgentSkill` runtime; `tower` lives here as `features/tower/` — protocol store, rate limit, tower-mode service with a mode injection (`injection/`) whose reminders carry the orchestration manual, eleven `Tower*` tools, and the `tower-worker` profile). A `Feature` (`src/features/feature.ts`) is an App-scope unit recipe with a `static override readonly name` and `contribute*` helpers composing the seams: `contributeService(scope, id, ctor)` / `contributeAgentService` (per-scope materialization via `ScopeUnits` — provider death retracts everywhere, 连坐), `contributeTool` (per-agent `OnDemand` registration + the `AgentToolContribution` record), `contributeProfiles`, `contributeConfig`, `contributeCommand`, plus `onDispose`. Feature modules self-register at import (`registerFeature`, `src/features/featureRegistry.ts`); the App-scope `IFeatureAssemblyService` drains the table through `IFeatureManager.provideUnit`, so every feature is a named, introspectable, retractable managed unit. Built-in features keep user-facing static contracts — config sections, agent profiles, wire vocabulary — on the static import=register channels (the config/state manifest generators read static tables / call sites; wire records must stay replayable); the Feature unit carries the runtime capabilities (services, tools, commands). The string form of the unit `on(...)` capability (`this.on('turn.ended', …)`) is backed by the production `FiberEventResolver` registered in `src/app/event/fiberEventResolver.ts`, resolving against the scope's `IEventBus`. +`src/features/` — built-in capabilities authored as self-contained Feature units (`plan` is the first, extracted from `agent/plan` + `agent/tools/plan`). A `Feature` (`src/features/feature.ts`) is an App-scope unit recipe with a `static override readonly name` and `contribute*` helpers composing the seams: `contributeService(scope, id, ctor)` / `contributeAgentService` (per-scope materialization via `ScopeUnits` — provider death retracts everywhere, 连坐), `contributeTool` (per-agent `OnDemand` registration + the `AgentToolContribution` record), `contributeProfiles`, `contributeConfig`, `contributeCommand`, plus `onDispose`. Feature modules self-register at import (`registerFeature`, `src/features/featureRegistry.ts`); the App-scope `IFeatureAssemblyService` drains the table through `IFeatureManager.provideUnit`, so every feature is a named, introspectable, retractable managed unit. Built-in features keep user-facing static contracts — config sections, agent profiles, wire vocabulary — on the static import=register channels (the config/state manifest generators read static tables / call sites; wire records must stay replayable); the Feature unit carries the runtime capabilities (services, tools, commands). The string form of the unit `on(...)` capability (`this.on('turn.ended', …)`) is backed by the production `FiberEventResolver` registered in `src/app/event/fiberEventResolver.ts`, resolving against the scope's `IEventBus`. ## Ledger and cascade (L0/L2) - `src/_base/lifecycle/` — the Ledger (L0): ordered, dual-track (sync / async disposable) effect bookkeeping with strict reverse-order serial teardown and reason passthrough (`'scope-close' | 'cascade' | 'unload'`). Scopes, containers, and units all anchor side effects here; `Disposable` / `DisposableStore` (`_base/di/lifecycle.ts`) delegate to it. - `cascadeEngine.ts` — one engine per scope container with tree-wide orchestration (L2): `provide` / `unprovide` / `update` run as transactions (contagion set from the persistent dependency graph — instance edges may point child → parent across scopes → abort hook → global reverse-topo teardown → apply → waiting-area recheck to a fixpoint → history ring). Units are five-state (`Pending / Activating / Active / Unloading / Failed`): construction failure is sticky `Failed` (no auto-retry; `update()` reloads; resolving a Failed unit rethrows its error); units with unsatisfiable declared dependencies park in the waiting area and auto-activate when the deps arrive, across scopes. An `ondemand` unit counts as available — consumers pull it transitively at materialization. -- Static and dynamic share one provide path: scope creation (`createScopedChildHandle` / `Scope.createApp` / `Scope.createChild`) submits the kind's whole `registerScopedService` batch as ONE cascade transaction via `provideAll` — every token registers before the activation wave, so registration order never matters (untracked transitive `createInstance` resolutions succeed inside the batch). The static registry is unique per (scope, token): `registerScopedService` throws a `BugIndicatingError` on a duplicate registration at import time — token identity is the decorator object, so an aliased second registration blows up the same way — and intentional replacement goes through `overrideScopedService`, which throws when no registration exists. A seed occupying a token overrides the static registration. `activateScopeServices` is gone — eager activation failure is a sticky `Failed` unit, not a scope-creation error. +- Static and dynamic share one provide path: scope creation (`createScopedChildHandle` / `Scope.createApp` / `Scope.createChild`) submits the kind's whole `registerScopedService` batch as ONE cascade transaction via `provideAll` — every token registers before the activation wave, so registration order never matters (untracked transitive `createInstance` resolutions succeed inside the batch); a seed occupying a token overrides the static registration. `activateScopeServices` is gone — eager activation failure is a sticky `Failed` unit, not a scope-creation error. ## Examples @@ -35,8 +35,25 @@ Domain-slice scenarios that used to live in `examples/<name>.example.ts` are now ## Comment conventions -- **No comments.** The code is the source of truth; do not write file headers, section banners, implementation narration, or JSDoc — no comments of any kind, on exported symbols or not. -- **Lint-suppression directives are the tooling exception.** `oxlint-disable` / `eslint-disable` comments are allowed where they suppress an active rule for a deliberate pattern (e.g. the Event2 class+payload-interface merging idiom). `@ts-expect-error`, `@ts-ignore`, and `ts-nocheck` stay banned — fix the underlying type problem instead; negative type-safety cases go into compiler-asserted fixtures. +- **Header only, external role only.** Comments live solely in the top-of-file `/** */` block — never beside functions, methods, or statements. Say what the module exposes and the responsibility it owns; the code is the source of truth for how it works, so do not narrate implementation steps, enumerate every export, or note porting / skeleton status. +- **Identity line first.** Start with `` `<domain>` domain — <one-line role>. `` Keep an existing `(cross-cutting)` label as-is. Write the role as a responsibility ("drives the turn lifecycle"), not a symbol list ("turn driver + context + loop runner"). +- **Impl files add collaborators + scope; contract files add the public contract + scope.** For impls, list every imported cross-domain collaborator as a role ("persists records through `records`") — declared dependencies count even if not yet wired in this WIP port; infrastructure imports (`_base/**`) are not collaborators. Read scope from `registerScopedService(LifecycleScope.X, …)`. + +### Examples + +Impl (`src/session/sessionMetadata/sessionMetadataService.ts`): + +```ts +/** + * `sessionMetadata` domain — `ISessionMetadata` implementation. + * + * Persists the session metadata document (`state.json`) through the `storage` + * access-pattern store (`IAtomicDocumentStore`), rooted at the `metaScope` + * namespace from `sessionContext`. Loads the existing document on + * construction (creating it on first run), and logs through `log`. Bound at + * Session scope. + */ +``` ## Telemetry @@ -61,25 +78,13 @@ Business domains **do not implement persistence themselves** — they depend on Business code must not `import 'node:fs'`, write SQL, hand-roll append-logs / atomic writes, or hold file handles. Generic Stores are named by **access pattern** (`IAppendLogStore`, `IAtomicDocumentStore`); only domain-unique Stores are named after the domain (`ISessionIndex`). See `.agents/skills/agent-core-dev/persistence.md` for the full layering rules and decision tree. -One accepted exception: `features/tower/protocol` manages the `.tower/` directory inside the *user's* repository (worktree slots, comms files, activity log) — workspace content, not engine state — and is a verbatim port of the v1 protocol whose semantics (atomic tmp+rename, real `git` CLI for worktrees/merges) are the feature. It keeps direct `node:fs` / `node:child_process` access; do not "modernize" it onto the Stores above without a dedicated migration. - -## MCP management plane - -The App scope owns the process-wide MCP management surface, split across three domains: `mcpConfig` (`src/app/mcpConfig/` — the `[mcp]` config section, the layered mcp.json loader with per-entry origins, `IMcpConfigStore` as the single write point for the user-level `mcp.json`, `IMcpOAuthStore` credential persistence, and `IMcpOAuthService`, the process-wide OAuth orchestrator with credential events, single-flight refresh, and proactive refresh timers), `mcpRegistry` (`IMcpRegistryService` — the unified read view over the file layers and plugin manifests with `source`/`origin`/`mutable`; runtime-name collisions keep both entries, and runtime resolution ranks the file entry above plugin entries — a file entry wins by presence, even disabled, while a disabled plugin descriptor is treated as absent; a project layer joins the view only when the queried cwd itself is trusted, matching what the workspace runtime would load), and `mcpManagement` (`IMcpManagementService` — guarded CRUD (project-layer entries reject as read-only; plugin entries never block, so a user-level write may shadow a plugin), connection-test probes, the locator-addressed inspection/auth-status surface, and locator-addressed OAuth begin/complete/cancel/reset with ambiguity rejection plus an idle timeout that cancels abandoned flows). The engine services and the edge exposure (kap-server routes, klient facade) are ungated. On the Workspace side, `workspaceMcpConfig` merges the same sources (same file-over-plugin precedence), watches the files and plugin reloads, follows the store's `onDidWrite` for immediate management-plane reloads, and publishes fingerprint diffs that `workspaceMcp` applies to the handler-shared `McpConnectionManager` (tombstones for removals); `workspaceMcp` also subscribes the OAuth service's credential events to reconnect affected entries. Session overlays (`session/mcp`) keep caller-injected ephemeral servers session-local. - -Name-collision precedence is a deliberate, documented divergence from v1: v1 ranks an enabled plugin above the file layers (#2858), v2 keeps its historical file-over-plugin order, and each engine's management guards follow its own winner — the same `mcp.json` plus plugin set can therefore resolve a collision differently per engine. Do not "re-align" one side without an explicit product decision. - ## Session index `ISessionIndex` (`src/app/sessionIndex/`, App scope) serves session list/resume reads over two paths: the authoritative directory scan (`sessionIndexSource`, always correct, linear) and the minidb-backed derived read model (`IQueryStore` at `<home>/cache/query-store`, keyset-paged, `O(log N + limit)`), gated by the `persistence_minidb_readmodel` flag (default ON; roll back via `KIMI_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL=false` or the `[experimental]` config section). The read model has an explicit lifecycle — `uninitialized → preparing → ready/degraded` via `prepare()`/`status()`; reads while preparing answer from the authoritative store immediately and fold the `ISessionIndexMirror` queue in for read-your-writes; the first list shares one single-flight authoritative scan with the initial projection. The query-store is structural-only — text-index definitions are rejected at definition level, so session operations never touch the global full-text index (`<home>/search-index`, owned by kap-server's search surface). ## Conversation undo -`context.undo` is the only persisted undo fact. `contextMemory/conversationTime.ts` owns the conversation clock (`isUndoAnchor` — the single tick predicate used by `computeUndoCut`, the checkpoint folds, and the transcript reducer) and registers the undoable protocol (`registerUndoableProtocol`). A state key whose value must follow conversation undo (todo, plan, task-notification delivery, …) **MUST** chain `.undoable()` on its `defineState(...).replayable(...)` definition — never hand-roll the checkpoint/clear/rollback folds — so the dispatcher expands the protocol folds (undo anchors push a checkpoint, compaction/clear drop the markers, `context.undo` rolls back through inverse patches; a custom `onUndo` replaces the rollback, as the conversation history does) and the undo pipeline's pre-cut depth check sees the key (the dispatcher tracks patch history and checkpoint markers per state key). World-time state (turn counters, task registries, revision counters) must stay outside undoable keys. - -## Model-facing reminders - -Two delivery paths only — never introduce a third (no deferred-delivery queues, no mid-step splice channels), both owned by the `AgentReminder` Agent Runtime and obtained only through `IAgentLifecycleService.resolve(agentContext, AgentReminder)`: reminders that restate current state (goal state, plan mode, date change, …) call `register(variant, provider)` and reconcile at every step head before the request is built, re-emitting after compaction or undo; reminders that report a one-off event (goal cancelled, AGENTS.md discovered, `/init` finished, …) call `notify(content, { variant, ownerPromptId? })` at a safe event point (a step/restore hook, an idle moment, or the loop-event fold's deferred append). The runtime owns `<system-reminder>` wrapping and stamps `{ kind: 'injection', variant }`; `kind: 'injection'` is a lifecycle classification (hidden from the UI, not an undo anchor, dropped by compaction), not a provenance claim, and prompt-owned attachments carry `ownerPromptId` so undo treats them as part of their host prompt. +`context.undo` is the only persisted undo fact. `contextMemory/conversationTime.ts` owns the conversation clock (`isUndoAnchor` — the single tick predicate used by `computeUndoCut`, the checkpoint reducers, and the transcript reducer) and the checkpoint protocol. A wire Model whose state must follow conversation undo (todo, plan, task-notification delivery, …) **MUST** be defined with `defineCheckpointedModel` — never hand-roll the push/clear/restore reducers — which also registers it into `CHECKPOINTED_MODELS` for the undo pipeline's pre-cut depth check. World-time state (turn counters, task registries, revision counters) must stay outside checkpointed Models. ## Docs @@ -92,5 +97,5 @@ Per-domain references live in `docs/`. - [`docs/di-testing.md`](docs/di-testing.md) — Read **before writing or touching any DI/Scope test**: picking the right harness (`InstantiationService` vs `TestInstantiationService` vs `createScopedTestHost`), declaring deps with `@IService`, stubbing collaborators, and teardown via `DisposableStore`. - [`docs/features.md`](docs/features.md) — Read **before adding or extracting a built-in feature** (`src/features/<name>/`): the `Feature` base class, the `contribute*` seams, the static-vs-feature channel rules, and the assembly/retraction lifecycle. - [`docs/config-manifest.toml`](docs/config-manifest.toml) — Generated list of every registered config section, in the on-disk `config.toml` shape (owner, scope, defaults, env bindings, schema fields). Do not edit by hand; regenerate with `pnpm gen:config-manifest` after adding or removing a `registerConfigSection` call — `test/app/config/configManifest.test.ts` enforces freshness. -- [`docs/wire-manifest.d.ts`](docs/wire-manifest.d.ts) — Generated declaration file listing every durable wire record type (an `Event2` subclass with `static durable = true` + `static schema`) as a payload interface (folding states, blob codec owners, and owner file in the doc comment; payload fields in real TS type syntax), plus a `WirePayloadMap`. Do not edit by hand; regenerate with `pnpm gen:wire-manifest` after adding or removing a durable `Event2` class — `test/wire/wireManifest.test.ts` enforces freshness and checks the file parses. -- [`docs/state-manifest.d.ts`](docs/state-manifest.d.ts) — Generated declaration file listing every state key registered into `IAppStateService` / `IWorkspaceStateService` / `ISessionStateService` / `IAgentStateService`, as `AppStateSnapshot` / `WorkspaceStateSnapshot` / `SessionStateSnapshot` / `AgentStateSnapshot` interfaces (keys grouped by defining file), plus the `AppStateKey` / `WorkspaceStateKey` / `SessionStateKey` / `AgentStateKey` unions. Self-contained: every value type is expanded fully inline with each named type marked by a `/* TypeName — source/file.ts */` comment (recursion stops with a `recursive` marker) — no imports, no helper declarations. Do not edit by hand; regenerate with `pnpm gen:state-manifest` after adding or removing a `states.contributeState(...)` call or a `defineState(...).replayable(...)` key (the Agent section covers the replayable keys contributed by their owner services, with each replayable key's fold/durable/undoable info) — `test/state/stateManifest.test.ts` enforces freshness and checks the file parses. +- [`docs/wire-manifest.d.ts`](docs/wire-manifest.d.ts) — Generated declaration file listing every registered wire record type as a payload interface (model, persist policy, `toEvent`, cross-reducers in the doc comment; payload fields in real TS type syntax), plus a `WirePayloadMap`. Do not edit by hand; regenerate with `pnpm gen:wire-manifest` after adding or removing a `defineOp` call — `test/wire/wireManifest.test.ts` enforces freshness and checks the file parses. +- [`docs/state-manifest.d.ts`](docs/state-manifest.d.ts) — Generated declaration file listing every state key registered into `IAppStateService` / `IWorkspaceStateService` / `ISessionStateService` / `IAgentStateService`, as `AppStateSnapshot` / `WorkspaceStateSnapshot` / `SessionStateSnapshot` / `AgentStateSnapshot` interfaces (keys grouped by defining file), plus the `AppStateKey` / `WorkspaceStateKey` / `SessionStateKey` / `AgentStateKey` unions. Self-contained: every value type is expanded fully inline with each named type marked by a `/* TypeName — source/file.ts */` comment (recursion stops with a `recursive` marker) — no imports, no helper declarations. Do not edit by hand; regenerate with `pnpm gen:state-manifest` after adding or removing a `states.register(...)` call — `test/state/stateManifest.test.ts` enforces freshness and checks the file parses. diff --git a/packages/agent-core-v2/CHANGELOG.md b/packages/agent-core-v2/CHANGELOG.md index 403c6b81e..94e48650d 100644 --- a/packages/agent-core-v2/CHANGELOG.md +++ b/packages/agent-core-v2/CHANGELOG.md @@ -1,30 +1,5 @@ # @moonshot-ai/agent-core-v2 -## 0.4.1 - -### Patch Changes - -- [#3109](https://github.com/MoonshotAI/kimi-code/pull/3109) [`f1208c8`](https://github.com/MoonshotAI/kimi-code/commit/f1208c8d7241e8ef428d83ff235f5a218911b342) Thanks [@liruifengv](https://github.com/liruifengv)! - Rework the session title excerpts: rebalance the segment budgets toward user prompts (400 chars each, assistant 300), cap each prompt in the `user_prompts` excerpt, and compose the `digest` excerpt from the full conversation arc — every natural-language user prompt in the live window paired with its own turn's final assistant text, interleaved chronologically, within per-segment caps and a 3000-char total budget (middle turns elided). - -## 0.4.0 - -### Minor Changes - -- [#2351](https://github.com/MoonshotAI/kimi-code/pull/2351) [`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629) Thanks [@7Sageer](https://github.com/7Sageer)! - Add the Session-scoped `ISessionTitleService` for managed AI session titles: composes the excerpt sent to the platform chat_title tool from the main agent's conversation (the first user prompts, the strict `first_turn` pair, or the head+tail `digest` for multi-turn sessions; assistant segments keep only final text), persists the result with a `titleKind` (`replaceable` / `generated` / `custom`) that never overwrites a user-renamed title unless explicitly forced, and rebroadcasts `session.meta.updated`. Gated by the new experimental `auto_session_title` flag and a managed OAuth login. - -### Patch Changes - -- [#2911](https://github.com/MoonshotAI/kimi-code/pull/2911) [`249d8fa`](https://github.com/MoonshotAI/kimi-code/commit/249d8faa3447427665185a900926d048213d2ac7) Thanks [@7Sageer](https://github.com/7Sageer)! - Normalize provider tool call ids at the LLM ingestion boundary (`ToolCallIdNormalizer` in `llmRequester`): self-hosted endpoints may renumber ids per response, and a repeated id corrupted every downstream keying — dropped tool results in context rebuild, `duplicate_tool_call_dropped` in the strict projector, merged transcript frames, misrouted approvals. The first occurrence passes through unchanged; later ones are rewritten to a readable `<id>__<n>` suffix, kept consistent between streamed deltas and the finalized message, logged for provenance, and rolled back when the attempt fails so projection retries re-stream under the same ids. Interaction ids are additionally minted engine-side (`approval_<uuid>` / `question_<uuid>` / `user_tool_<uuid>`) instead of deriving from the provider toolCallId. - -- Updated dependencies [[`6be2697`](https://github.com/MoonshotAI/kimi-code/commit/6be26978b123bacf1c5ebce52bbeb6f7b7ff0629), [`4a93f70`](https://github.com/MoonshotAI/kimi-code/commit/4a93f70aa2cf5f70a88b4f8eeb2e409aab2c8f59)]: - - @moonshot-ai/kimi-code-oauth@0.4.0 - -## 0.3.2 - -### Patch Changes - -- [#2815](https://github.com/MoonshotAI/kimi-code/pull/2815) [`43c68f5`](https://github.com/MoonshotAI/kimi-code/commit/43c68f58f578c88d9f503afb72f12d343c2aa5c7) Thanks [@liruifengv](https://github.com/liruifengv)! - Keep session updatedAt stable across metadata management writes: rename and archive/restore no longer bump it, fork inherits the source session's recency, and agent registration is non-touching; add SessionMeta.archivedAt (set on archive, cleared on restore) and surface it as archived_at through the session index and the v1/v2 session routes. - ## 0.3.1 ### Patch Changes diff --git a/packages/agent-core-v2/docs/config-manifest.toml b/packages/agent-core-v2/docs/config-manifest.toml index 695e6b176..a63872839 100644 --- a/packages/agent-core-v2/docs/config-manifest.toml +++ b/packages/agent-core-v2/docs/config-manifest.toml @@ -8,35 +8,35 @@ # commented "# field: type" lines describe the remaining schema fields. # Values resolve as: default -> config.toml -> env overlay -> memory. -# Index (26 sections · 2 overlay(s)) +# Index (25 sections · 3 overlay(s)) # background src/agent/task/configSection.ts -# builtinProductSkills src/features/skill/catalog/configSection.ts -# cron src/features/cron/configSection.ts +# builtinProductSkills src/app/skillCatalog/configSection.ts +# cron src/app/cron/configSection.ts # defaultPermissionMode src/agent/permissionMode/configSection.ts # defaultPlanMode src/features/plan/configSection.ts # experimental src/app/flag/flag.ts # extraAgentDirs src/workspace/workspaceAgentProfileLoader/configSection.ts -# extraSkillDirs src/features/skill/catalog/configSection.ts -# hooks src/features/externalHooks/configSection.ts +# extraSkillDirs src/app/skillCatalog/configSection.ts +# hooks src/agent/externalHooks/configSection.ts # identity src/app/agentIdentity/configSection.ts # image src/agent/media/configSection.ts # loopControl src/agent/loop/configSection.ts # mcp src/app/mcpConfig/configSection.ts -# mergeAllAvailableSkills src/features/skill/catalog/configSection.ts +# mergeAllAvailableSkills src/app/skillCatalog/configSection.ts # modelCatalog src/app/kosongConfig/configSection.ts # models src/app/kosongConfig/configSection.ts # permission src/agent/permissionRules/configSection.ts # providers src/app/kosongConfig/configSection.ts -# secondaryModel src/session/subagent/configSection.ts +# secondaryModel src/app/kosongConfig/configSection.ts # services src/app/auth/configSection.ts # subagent src/session/subagent/configSection.ts -# swarm src/features/swarm/configSection.ts # task src/agent/task/configSection.ts # thinking src/app/kosongConfig/configSection.ts # tokenCounting src/agent/tokenCounting/configSection.ts # tools src/agent/toolPolicy/configSection.ts # (overlay) servicesCredentialEnvOverlay src/app/auth/configSection.ts # (overlay) kimiModelEnvOverlay src/app/kosongConfig/envOverlay.ts +# (overlay) secondaryModelOverlay src/app/kosongConfig/secondaryModelOverlay.ts # ########################################################################## # background @@ -60,7 +60,7 @@ # ########################################################################## # builtinProductSkills (config.toml: builtin_product_skills) -# owner: src/features/skill/catalog/configSection.ts +# owner: src/app/skillCatalog/configSection.ts # scope: core # hooks: stripEnv # env: @@ -71,7 +71,7 @@ builtin_product_skills = true # ########################################################################## # cron -# owner: src/features/cron/configSection.ts +# owner: src/app/cron/configSection.ts # scope: core # hooks: stripEnv # env: @@ -128,7 +128,7 @@ extra_agent_dirs = [] # ########################################################################## # extraSkillDirs (config.toml: extra_skill_dirs) -# owner: src/features/skill/catalog/configSection.ts +# owner: src/app/skillCatalog/configSection.ts # scope: core # ########################################################################## @@ -136,7 +136,7 @@ extra_skill_dirs = [] # ########################################################################## # hooks -# owner: src/features/externalHooks/configSection.ts +# owner: src/agent/externalHooks/configSection.ts # scope: core # hooks: custom fromToml · custom toToml # ########################################################################## @@ -212,7 +212,7 @@ extra_skill_dirs = [] # ########################################################################## # mergeAllAvailableSkills (config.toml: merge_all_available_skills) -# owner: src/features/skill/catalog/configSection.ts +# owner: src/app/skillCatalog/configSection.ts # scope: core # ########################################################################## @@ -318,15 +318,15 @@ merge_all_available_skills = true # ########################################################################## # secondaryModel (config.toml: secondary_model) -# owner: src/session/subagent/configSection.ts +# owner: src/app/kosongConfig/configSection.ts # scope: core +# hooks: stripEnv +# env: +# model <- KIMI_SECONDARY_MODEL (custom parse) +# default_effort <- KIMI_SECONDARY_EFFORT (custom parse) # ########################################################################## [secondary_model] -# default_model: string -# models: record<string, string> -# force: boolean -# model: string # max_context_size: integer # max_input_size: integer # max_output_size: integer @@ -337,6 +337,7 @@ merge_all_available_skills = true # support_efforts: string[] # default_effort: string # off_effort: string +# model: string # ########################################################################## # services @@ -382,18 +383,6 @@ merge_all_available_skills = true [subagent] timeout_ms = 7200000 -# ########################################################################## -# swarm -# owner: src/features/swarm/configSection.ts -# scope: core -# hooks: stripEnv -# env: -# timeout_ms <- KIMI_CODE_SWARM_TIMEOUT_MS (custom parse) -# ########################################################################## - -[swarm] -timeout_ms = 7200000 - # ########################################################################## # task # owner: src/agent/task/configSection.ts diff --git a/packages/agent-core-v2/docs/di-testing.md b/packages/agent-core-v2/docs/di-testing.md index 86681fc59..4b304b9b2 100644 --- a/packages/agent-core-v2/docs/di-testing.md +++ b/packages/agent-core-v2/docs/di-testing.md @@ -158,14 +158,6 @@ Always `_clearScopedRegistryForTests()` and re-register explicitly in `registerScopedService(...)` side-effect: import order then becomes part of the test, and another suite's `_clearScopedRegistryForTests()` can wipe it. -When a test intentionally replaces an existing static registration — swapping -one production implementation for a fake while keeping the rest of the registry -— use `overrideScopedService` (same signature). `registerScopedService` throws -on a duplicate (scope, id) pair, and `overrideScopedService` throws when nothing -is registered for the pair yet. Tool tests that re-register or restore agent -tool contributions use `overrideAgentToolService`, which replaces the scoped -registration and upserts the contribution-table entry. - The scoped registration signature is `registerScopedService(scope, id, ctor, activation = ScopeActivation.OnScopeCreated, domain?)`. The fourth argument is activation and the fifth is domain. diff --git a/packages/agent-core-v2/docs/di.md b/packages/agent-core-v2/docs/di.md index 427e24daf..dad69a259 100644 --- a/packages/agent-core-v2/docs/di.md +++ b/packages/agent-core-v2/docs/di.md @@ -416,7 +416,7 @@ A 创建中要 B,B 创建中又要 A——容器会抛 `CyclicDependencyError` 5. 父 scope 的服务不依赖子 scope 的服务(运行时也解析不到)。 6. **不写循环依赖**——容器会抛 `CyclicDependencyError`;撞上时按场景 9 重构,激活方式不能绕过循环检测。 7. `ServicesAccessor` 只在 `invokeFunction` 调用期间有效,不存起来异步用。 -8. 注册写在实现文件顶层;同一 (scope, token) 只能静态注册一次——重复注册(包括经别名的同一 decorator 对象)在 import 期抛 `BugIndicatingError`,有意替换用 `overrideScopedService`(目标没有注册时同样抛错)。测试里用 `_clearScopedRegistryForTests()` 后显式重注册,不依赖生产 import 顺序。 +8. 注册写在实现文件顶层;测试里用 `_clearScopedRegistryForTests()` 后显式重注册,不依赖生产 import 顺序。 ## 附录 C:新增一个服务的标准动作 diff --git a/packages/agent-core-v2/docs/errors.md b/packages/agent-core-v2/docs/errors.md index 5903c2a32..c4355465d 100644 --- a/packages/agent-core-v2/docs/errors.md +++ b/packages/agent-core-v2/docs/errors.md @@ -72,7 +72,7 @@ The os / persistence / wire domains show the standard shapes: - **`os.fs` (`HostFsError`, `os/interface/hostFsErrors.ts`)** — every `IHostFileSystem` backend translates raw errnos at its boundary via the pure `toHostFsError(err, { path, op })`: `ENOENT→os.fs.not_found`, `EISDIR→os.fs.is_directory`, `ENOTDIR→os.fs.not_directory`, `EEXIST→os.fs.already_exists`, `EACCES/EPERM→os.fs.permission_denied`, `ENOTEMPTY→os.fs.not_empty`, everything else `os.fs.unknown`. `details` carries `{ path, op, errno?, syscall? }`. Documented boolean semantics (e.g. `createExclusive` returning `false` on `EEXIST`) stay booleans, not errors. - **`os.process` (`HostProcessError`, `os/interface/hostProcess.ts`)** — `os.process.spawn_failed` (details `{ command, args?, cwd?, errno? }`) and `os.process.kill_failed`; both carry the raw error as `cause`. Kill keeps its deliberate tolerances: `ESRCH` is a silent no-op, `EPERM` degrades to `child.kill()`. - **`storage` (`StorageError`, `persistence/interface/storage.ts`)** — `storage.not_found` / `decode_failed` / `corrupted` / `io_failed` / `locked` / `permission_denied` / `disk_full`. ENOENT keeps its established absence semantics (`read → undefined`, `list → []`) and is *not* an error; other I/O failures are mapped by errno at the backend boundary via `toStorageIoError`: `EACCES/EPERM→storage.permission_denied`, `ENOSPC→storage.disk_full`, an unexpected `ENOENT→storage.not_found`, everything else `storage.io_failed` (the only retryable one besides `storage.locked`). Codec parse failures become `storage.decode_failed` with `{ scope, key, format }`; append-log corruption is `AppendLogCorruptedError` (`storage.corrupted`). `storage.locked` is reserved for a store exclusively held by another process — consumers (e.g. `FileSessionIndex`) catch it explicitly and fall back to their non-read-model path with a one-time warning; there is no silent no-op degradation. (The minidb query-store backend is a multi-process `ClusterDb` and no longer throws it: peers share the store, and per-shard lock contention surfaces as a transient `LockError` instead.) -- **`wire` (`WireError`, `wire/errors.ts`)** — `wire.unknown_record`: restore skips records whose durable event type is absent from the folded registry (compatibility) and reports each skip through `onUnexpectedError`; `wire.migration_missing` covers journals that predate the migration chain. The sibling `event`/`state` domains own `event.duplicate_event` (a build-time bug), `state.duplicate_fold`, `state.durability_mismatch`, and `CycleError` (`state.cycle`, details carry the drain depth and a capped event-type sample). +- **`wire` (`WireError`, `wire/errors.ts`)** — `DuplicateOpError` (`wire.duplicate_op`, a build-time bug), `CycleError` (`wire.cycle`, details carry the drain depth and a capped op-type sample), and `wire.unknown_record`: replay skips records whose Op type is absent from `OP_REGISTRY` (compatibility), reports each skip through `onUnexpectedError`, and returns `{ unknownRecords }` so the caller knows the restore was lossy. ## Serialization & boundary translation diff --git a/packages/agent-core-v2/docs/features.md b/packages/agent-core-v2/docs/features.md index 15b83107b..43c330885 100644 --- a/packages/agent-core-v2/docs/features.md +++ b/packages/agent-core-v2/docs/features.md @@ -31,10 +31,7 @@ registerFeature(PlanFeature); // import = register `Feature extends Service`, so every contribution runs through the normal two-phase construction protocol (declare contributions in the constructor; they are buffered and -flushed by the kernel). A feature may also declare `static readonly meta = { ... }` — -free-form self-description that `IFeatureManager.units()` introspection carries (and -kap-server surfaces via `GET /api/v1/meta`); it defaults to `{}`. The helpers are thin -compositions over the existing seams: +flushed by the kernel). The helpers are thin compositions over the existing seams: | Helper | Composition | Semantics | |---|---|---| @@ -74,9 +71,8 @@ they belong to a feature: `docs/config-manifest.toml`. - **Agent profiles** contributed via `registerAgentProfile` — same static-table reasoning. -- **Wire vocabulary** (durable `Event2` classes / - `defineState(...).replayable(...)`) — wire records must remain replayable even if the - feature unit is retracted. +- **Wire vocabulary** (`defineOp` / `defineModel` / `defineCheckpointedModel`) — wire + records must remain replayable even if the feature unit is retracted. The Feature unit carries the **runtime capabilities**: services, tools, commands, hook subscriptions. `PlanFeature` is the example: `configSection.ts` and `profile/plan.ts` @@ -96,7 +92,7 @@ keep their static registrations; the service and the two tools go through the Fe ## Adding a new feature -1. `src/features/<name>/` — domain files follow the usual conventions (no comments, +1. `src/features/<name>/` — domain files follow the usual conventions (header comments, one service per file pair, `.md?raw` assets move with the feature). 2. `<name>Feature.ts` — the Feature subclass + `registerFeature(...)`. 3. `src/index.ts` — precise leaf imports/exports; no barrel. diff --git a/packages/agent-core-v2/docs/rw-model-design.md b/packages/agent-core-v2/docs/rw-model-design.md index bb6787ad7..5e5ad829d 100644 --- a/packages/agent-core-v2/docs/rw-model-design.md +++ b/packages/agent-core-v2/docs/rw-model-design.md @@ -88,9 +88,7 @@ - V3 resume 期 signal 靠 `emitLive` 隐式压制(skill/swarm)——"这个 signal 发不发 得出去"取决于调用时相位,调用点看不出来。 - V4 `IEventService` payload 无类型、事件名裸字符串、同一事件两处发布者。 -- V5 `prompt.submitted` 曾长期只存在于协议而无人发,现已由 `AgentPromptService` - 在提交时发出(排队/运行以 `status` 区分,启动时再发 `prompt.started`); - `AsyncEmitter/handleVetos` 是死代码。 +- V5 `prompt.submitted` 协议里存在但无人发;`AsyncEmitter/handleVetos` 是死代码。 **回环与相位** - L1 订阅者回写链真实存在且无统一约束:turn.onEnded→goal 续跑→再 launch turn; @@ -213,8 +211,8 @@ replaying ──(日志折叠完)──▶ ready ──(首个 live commit)─ 各写一次**,且违规是响声(throw)不是静默。 > 今天"resume 里合法地想写"的场景(goal 的 fork reminder 每次 restore 重新 -> 生成)改由 **AgentReminder** Runtime 的 `register` provider 或 ready 相位的 -> 一次性 Effect 承担——派生内容本来就不该伪装成回放副作用。 +> 生成)改由 **context injector**(已存在的 `IAgentContextInjectorService`)或 +> ready 相位的一次性 Effect 承担——派生内容本来就不该伪装成回放副作用。 > `postRestoring` 窗口取消:task 磁盘对账、cron 启动等归入 ready 时刻的 > 一次性 Effect。 diff --git a/packages/agent-core-v2/docs/state-manifest.d.ts b/packages/agent-core-v2/docs/state-manifest.d.ts index e5de2174c..bdc979551 100644 --- a/packages/agent-core-v2/docs/state-manifest.d.ts +++ b/packages/agent-core-v2/docs/state-manifest.d.ts @@ -7,12 +7,8 @@ // Workspace-scope IWorkspaceStateService, the Session-scope // ISessionStateService, or the Agent-scope IAgentStateService (see // src/_base/state/stateRegistry.ts), collected statically from the -// `states.contributeState(...)` call sites and the replayable key chains — a -// `defineState(...).replayable(...)` key is contributed into the Agent-scope -// service by its owner service at construction, and -// carries a `// replayable · durable|transient · undoable? — folds: ...` line. -// Replayable values are excluded from snapshot()/inspect(). A key defined via -// defineState but never registered nor replayable does not appear here. Each entry shows the +// `states.register(...)` call sites — a key defined via +// defineState but never registered does not appear here. Each entry shows the // compile-time StateKey<T> value type fully expanded inline, so the manifest is // self-contained (no imports, no helper declarations). A named type is marked // at its expansion site with a `/* TypeName — source/file.ts */` comment; a @@ -27,22 +23,31 @@ // references become '(circular)', and class instances collapse to a '(ClassName)' // marker — the wire shape of an entry is the JSON projection of the type here. // -// Index (App: 0 keys · Workspace: 6 keys · Session: 9 keys · Agent: 79 keys) +// Index (App: 0 keys · Workspace: 6 keys · Session: 18 keys · Agent: 70 keys) // App // Workspace // workspaceDirs.ephemeralDirs src/workspace/workspaceDirs/workspaceDirsService.ts // workspaceDirs.fileDirs src/workspace/workspaceDirs/workspaceDirsService.ts // workspaceInstructions.current src/workspace/workspaceInstructions/workspaceInstructionsService.ts -// workspaceSkillCatalog.contributions src/features/skill/workspace/workspaceSkillCatalogService.ts -// workspaceSkillCatalog.merged src/features/skill/workspace/workspaceSkillCatalogService.ts +// workspaceSkillCatalog.contributions src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts +// workspaceSkillCatalog.merged src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts // workspaceTrust.trusted src/workspace/workspaceTrust/workspaceTrustService.ts // Session +// cron.inFlight src/session/cron/sessionCronServiceImpl.ts +// cron.lastSeenAt src/session/cron/sessionCronServiceImpl.ts +// cron.parsedCache src/session/cron/sessionCronServiceImpl.ts +// cron.seededFromStore src/session/cron/sessionCronServiceImpl.ts +// cron.started src/session/cron/sessionCronServiceImpl.ts +// cron.tasks src/session/cron/sessionCronServiceImpl.ts +// interaction.nextId src/session/interaction/interactionService.ts +// interaction.pending src/session/interaction/interactionService.ts +// interaction.recentlyResolved src/session/interaction/interactionService.ts // sessionActivity.current src/session/sessionActivity/sessionActivityService.ts // sessionActivity.folds src/session/sessionActivity/sessionActivityService.ts // sessionLog.rootLevel src/session/sessionLog/sessionLogService.ts // sessionMetadata.data src/session/sessionMetadata/sessionMetadataService.ts -// sessionSkillCatalog.contributions src/features/skill/session/skillCatalogService.ts -// sessionSkillCatalog.merged src/features/skill/session/skillCatalogService.ts +// sessionSkillCatalog.contributions src/session/sessionSkillCatalog/skillCatalogService.ts +// sessionSkillCatalog.merged src/session/sessionSkillCatalog/skillCatalogService.ts // sessionToolPolicy.state src/session/sessionToolPolicy/sessionToolPolicyService.ts // workspaceContext.additionalDirs src/session/workspaceContext/workspaceContextService.ts // workspaceContext.workDir src/session/workspaceContext/workspaceContextService.ts @@ -52,21 +57,30 @@ // activityView.lastTurn src/agent/activityView/activityViewService.ts // activityView.lifecycle src/agent/activityView/activityViewService.ts // activityView.turn src/agent/activityView/activityViewService.ts -// agentPlugin.sessionStartRefreshPending src/agent/plugin/agentPluginService.ts // agentsMdReminder.cwd src/agent/agentsMdReminder/agentsMdReminderService.ts // agentsMdReminder.known src/agent/agentsMdReminder/agentsMdReminderService.ts // agentsMdReminder.seeded src/agent/agentsMdReminder/agentsMdReminderService.ts -// contextMemory src/agent/contextMemory/contextOps.ts +// contextInjector.isNewTurn src/agent/contextInjector/contextInjectorService.ts // contextProjector.lastRepairSignature src/agent/contextProjector/contextProjectorService.ts -// externalHooks.stopHookContinuationUsed src/features/externalHooks/agent/agentExternalHooksService.ts -// fullCompaction src/agent/fullCompaction/compactionOps.ts +// dateChange.seed src/agent/dateChange/dateChangeService.ts +// externalHooks.stopHookContinuationUsed src/agent/externalHooks/externalHooksService.ts // fullCompaction.activeTurnId src/agent/fullCompaction/fullCompactionService.ts // fullCompaction.compactionCountInTurn src/agent/fullCompaction/fullCompactionService.ts // fullCompaction.consecutiveOverflowCompactions src/agent/fullCompaction/fullCompactionService.ts // fullCompaction.lastCompactedTokenCount src/agent/fullCompaction/fullCompactionService.ts // fullCompaction.observedMaxContextTokensByModel src/agent/fullCompaction/fullCompactionService.ts -// interruptionReminder src/agent/interruptionReminder/interruptionReminderOps.ts -// llm.requestTrace src/agent/llmRequester/llmRequestOps.ts +// goal.budgetGraceTurns src/agent/goal/goalService.ts +// goal.countedGoalTurns src/agent/goal/goalService.ts +// goal.exhaustedTurnBudgetGoals src/agent/goal/goalService.ts +// goal.goalDrivenTurns src/agent/goal/goalService.ts +// goal.goalOutcomeContinuationTurns src/agent/goal/goalService.ts +// goal.goalOutcomeToolResultTurns src/agent/goal/goalService.ts +// goal.goalStarterTurns src/agent/goal/goalService.ts +// goal.goalTurnTargets src/agent/goal/goalService.ts +// goal.liveTurnId src/agent/goal/goalService.ts +// goal.liveWallClockStartedAt src/agent/goal/goalService.ts +// goal.pendingContinuationGoals src/agent/goal/goalService.ts +// goal.resumeContinuation src/agent/goal/goalService.ts // llmRequester.emittedThinkingEffortWarnings src/agent/llmRequester/llmRequesterService.ts // llmRequester.lastConfigLogSignature src/agent/llmRequester/llmRequesterService.ts // llmRequester.mediaDegradedTurns src/agent/llmRequester/llmRequesterService.ts @@ -75,39 +89,24 @@ // loop.disposing src/agent/loop/loopService.ts // loop.lastRequestTraceId src/agent/loop/loopService.ts // loop.nextReservedTurnId src/agent/loop/loopService.ts -// mcp.discovery src/agent/mcp/mcpDiscoveryOps.ts // mcp.discoveryWritesReady src/agent/mcp/mcpService.ts // mcp.mcpToolsByServer src/agent/mcp/mcpService.ts // media.registeredKey src/agent/media/mediaToolsRegistrar.ts -// media.resolved src/agent/media/mediaResolverService.ts -// permissionMode src/agent/permissionMode/permissionModeOps.ts -// permissionMode.configured src/agent/permissionMode/permissionModeOps.ts +// media.resolved src/agent/media/videoResolverService.ts // permissionMode.lastMode src/agent/permissionMode/injection/permissionModeInjection.ts -// permissionRules src/agent/permissionRules/permissionRulesOps.ts -// plan src/features/plan/planOps.ts // plan.wasActive src/features/plan/injection/planModeInjection.ts -// pluginSessionStartSnapshot src/agent/plugin/agentPluginOps.ts -// profile src/agent/profile/profileOps.ts // profile.activeToolNamesOverlay src/agent/profile/profileService.ts -// profile.activeTools src/agent/profile/profileOps.ts // profile.agentsMdWarning src/agent/profile/profileService.ts // profile.emittedPluginBudgetWarnings src/agent/profile/profileService.ts // profile.emittedThinkingEffortWarnings src/agent/profile/profileService.ts // profile.emittedToolPatternWarnings src/agent/profile/profileService.ts // prompt.launching src/agent/prompt/promptService.ts -// promptAdmission src/agent/prompt/promptOps.ts -// runtime.binding src/agent/runtimeBinding/runtimeBindingService.ts -// runtimeBinding src/agent/runtimeBinding/runtimeBindingOps.ts // shellCommand.tasks src/agent/shellCommand/shellCommandService.ts -// staleGuard src/features/staleGuard/staleGuardOps.ts // stepRetry.failedAttempts src/agent/stepRetry/stepRetryService.ts // stepRetry.lastFailedDriverId src/agent/stepRetry/stepRetryService.ts -// swarm src/features/swarm/swarmOps.ts -// task src/agent/task/taskOps.ts // task.activeTaskReminderPending src/agent/task/taskService.ts // task.deliveredNotificationKeys src/agent/task/taskService.ts // task.ghosts src/agent/task/taskService.ts -// task.notificationDelivery src/agent/task/taskService.ts // task.scheduledNotificationKeys src/agent/task/taskService.ts // toolDedupe.activeStep src/agent/toolDedupe/toolDedupeService.ts // toolDedupe.activeTurnId src/agent/toolDedupe/toolDedupeService.ts @@ -117,15 +116,12 @@ // toolDedupe.originalCallIndex src/agent/toolDedupe/toolDedupeService.ts // toolDedupe.stepCalls src/agent/toolDedupe/toolDedupeService.ts // toolDedupe.syntheticCallIds src/agent/toolDedupe/toolDedupeService.ts -// toolDedupe.turnCallRecords src/agent/toolDedupe/toolDedupeService.ts -// toolDedupe.turnRepeatCount src/agent/toolDedupe/toolDedupeService.ts // toolExecutor.dupTypeTurnId src/agent/toolExecutor/toolExecutorService.ts // toolExecutor.toolCallDupTypes src/agent/toolExecutor/toolExecutorService.ts +// toolSelect.needsBoundaryInjection src/agent/toolSelect/toolSelectAnnouncementsService.ts // toolSelect.pendingLoaded src/agent/toolSelect/toolSelectService.ts -// tower src/features/tower/towerOps.ts -// tower.owner src/features/tower/towerOps.ts -// turn src/agent/loop/turnOps.ts -// userTool src/agent/userTool/userToolOps.ts +// usage.currentTurn src/agent/usage/usageService.ts +// usage.currentTurnId src/agent/usage/usageService.ts /** App-scope keys registered into IAppStateService. */ export interface AppStateSnapshot { @@ -135,254 +131,6 @@ export type AppStateKey = keyof AppStateSnapshot; /** Workspace-scope keys registered into IWorkspaceStateService. */ export interface WorkspaceStateSnapshot { - // src/features/skill/workspace/workspaceSkillCatalogService.ts - 'workspaceSkillCatalog.contributions': Map<string, { - readonly c: /* SkillContribution — packages/agent-core-v2/src/features/skill/catalog/skillSource.ts */ { - readonly skills: readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }[]; - readonly skipped?: readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly path: string; - readonly type: string; - readonly reason: string; - }[]; - readonly scannedRoots?: readonly string[]; - }; - readonly priority: number; - }>; - 'workspaceSkillCatalog.merged': /* InMemorySkillCatalog — packages/agent-core-v2/src/features/skill/catalog/registry.ts */ { - registerBuiltinSkill: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }) => void; - register: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }, options?: { - readonly replace?: boolean; - }) => void; - recordSkipped: (skills: readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly path: string; - readonly type: string; - readonly reason: string; - }[]) => void; - addRoots: (roots: readonly string[]) => void; - getSkill: (name: string) => /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - } | undefined; - getPluginSkill: (pluginId: string, name: string) => /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - } | undefined; - renderSkillPrompt: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }, rawArgs: string, context?: { - readonly sessionId?: string; - }) => string; - listSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }[]; - listInvocableSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name: string; - readonly description: string; - readonly path: string; - readonly dir: string; - readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly name?: string; - readonly description?: string; - readonly type?: string; - readonly whenToUse?: string; - readonly disableModelInvocation?: boolean; - readonly isSubSkill?: boolean; - readonly safe?: boolean; - readonly arguments?: string | readonly unknown[]; - [key: string]: unknown; - }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly id: string; - readonly instructions?: string; - }; - readonly mermaid?: string; - readonly d2?: string; - readonly productSpecific?: boolean; - readonly experimentalFlag?: string; - }[]; - getSkillRoots: () => readonly string[]; - getSkippedByPolicy: () => readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { - readonly path: string; - readonly type: string; - readonly reason: string; - }[]; - getKimiSkillsDescription: () => string; - getModelSkillListing: () => string; - }; // src/workspace/workspaceDirs/workspaceDirsService.ts 'workspaceDirs.ephemeralDirs': readonly string[]; 'workspaceDirs.fileDirs': readonly string[]; @@ -392,24 +140,16 @@ export interface WorkspaceStateSnapshot { readonly agentsMdWarning: string | undefined; readonly agentsMdPaths: readonly string[] | undefined; }; - // src/workspace/workspaceTrust/workspaceTrustService.ts - 'workspaceTrust.trusted': boolean; -} - -export type WorkspaceStateKey = keyof WorkspaceStateSnapshot; - -/** Session-scope keys registered into ISessionStateService. */ -export interface SessionStateSnapshot { - // src/features/skill/session/skillCatalogService.ts - 'sessionSkillCatalog.contributions': Map<string, { - readonly c: /* SkillContribution — packages/agent-core-v2/src/features/skill/catalog/skillSource.ts */ { - readonly skills: readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + // src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts + 'workspaceSkillCatalog.contributions': Map<string, { + readonly c: /* SkillContribution — packages/agent-core-v2/src/app/skillCatalog/skillSource.ts */ { + readonly skills: readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -420,17 +160,16 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }[]; - readonly skipped?: readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly skipped?: readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly path: string; readonly type: string; readonly reason: string; @@ -439,14 +178,14 @@ export interface SessionStateSnapshot { }; readonly priority: number; }>; - 'sessionSkillCatalog.merged': /* InMemorySkillCatalog — packages/agent-core-v2/src/features/skill/catalog/registry.ts */ { - registerBuiltinSkill: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + 'workspaceSkillCatalog.merged': /* InMemorySkillCatalog — packages/agent-core-v2/src/app/skillCatalog/registry.ts */ { + registerBuiltinSkill: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -457,23 +196,22 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }) => void; - register: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + register: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -484,31 +222,30 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }, options?: { readonly replace?: boolean; }) => void; - recordSkipped: (skills: readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + recordSkipped: (skills: readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly path: string; readonly type: string; readonly reason: string; }[]) => void; addRoots: (roots: readonly string[]) => void; - getSkill: (name: string) => /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + getSkill: (name: string) => /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -519,23 +256,22 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; } | undefined; - getPluginSkill: (pluginId: string, name: string) => /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + getPluginSkill: (pluginId: string, name: string) => /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -546,23 +282,22 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; } | undefined; - renderSkillPrompt: (skill: /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + renderSkillPrompt: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -573,25 +308,24 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }, rawArgs: string, context?: { readonly sessionId?: string; }) => string; - listSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + listSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -602,23 +336,22 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }[]; - listInvocableSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + listInvocableSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name: string; readonly description: string; readonly path: string; readonly dir: string; readonly content: string; - readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly name?: string; readonly description?: string; readonly type?: string; @@ -629,18 +362,17 @@ export interface SessionStateSnapshot { readonly arguments?: string | readonly unknown[]; [key: string]: unknown; }; - readonly source: /* SkillSource — packages/agent-core-v2/src/features/skill/catalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; - readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly id: string; readonly instructions?: string; }; readonly mermaid?: string; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; }[]; getSkillRoots: () => readonly string[]; - getSkippedByPolicy: () => readonly /* SkippedSkill — packages/agent-core-v2/src/features/skill/catalog/types.ts */ { + getSkippedByPolicy: () => readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { readonly path: string; readonly type: string; readonly reason: string; @@ -648,11 +380,59 @@ export interface SessionStateSnapshot { getKimiSkillsDescription: () => string; getModelSkillListing: () => string; }; + // src/workspace/workspaceTrust/workspaceTrustService.ts + 'workspaceTrust.trusted': boolean; +} + +export type WorkspaceStateKey = keyof WorkspaceStateSnapshot; + +/** Session-scope keys registered into ISessionStateService. */ +export interface SessionStateSnapshot { + // src/session/cron/sessionCronServiceImpl.ts + 'cron.inFlight': Set<string>; + 'cron.lastSeenAt': Map<string, number>; + 'cron.parsedCache': Map<string, /* ParsedCronExpression — packages/agent-core-v2/src/app/cron/cron-expr.ts */ { + readonly raw: string; + readonly minutes: ReadonlySet<number>; + readonly hours: ReadonlySet<number>; + readonly daysOfMonth: ReadonlySet<number>; + readonly months: ReadonlySet<number>; + readonly daysOfWeek: ReadonlySet<number>; + readonly daysOfMonthWildcard: boolean; + readonly daysOfWeekWildcard: boolean; + }>; + 'cron.seededFromStore': Set<string>; + 'cron.started': boolean; + 'cron.tasks': Map<string, /* CronTask — packages/agent-core-v2/src/app/cron/cronTask.ts */ { + readonly id: string; + readonly cron: string; + readonly prompt: string; + readonly createdAt: number; + readonly recurring?: boolean; + readonly lastFiredAt?: number; + readonly tags?: Readonly<Record<string, string>>; + }>; + // src/session/interaction/interactionService.ts + 'interaction.nextId': number; + 'interaction.pending': Map<string, /* Pending — packages/agent-core-v2/src/session/interaction/interactionService.ts */ { + readonly interaction: { + readonly id: string; + readonly kind: /* InteractionKind — packages/agent-core-v2/src/session/interaction/interaction.ts */ 'approval' | 'question' | 'user_tool'; + readonly payload: unknown; + readonly origin: /* InteractionOrigin — packages/agent-core-v2/src/session/interaction/interaction.ts */ { + readonly agentId?: string; + readonly turnId?: number; + }; + readonly createdAt: number; + }; + readonly resolve: (response: unknown) => void; + }>; + 'interaction.recentlyResolved': Map<string, number>; // src/session/sessionActivity/sessionActivityService.ts 'sessionActivity.current': /* SessionActivityState — packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts */ { readonly busy: boolean; readonly mainTurnActive: boolean; - readonly pendingInteraction: /* SessionPendingInteraction — packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts */ 'none' | 'approval' | 'question'; + readonly pendingInteraction: /* SessionPendingInteraction — packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts */ 'approval' | 'question' | 'none'; readonly lastTurnReason?: 'completed' | 'cancelled' | 'failed'; }; 'sessionActivity.folds': Map<string, /* AgentWorkFold — packages/agent-core-v2/src/session/sessionActivity/sessionActivityService.ts */ { @@ -669,12 +449,11 @@ export interface SessionStateSnapshot { readonly id: string; readonly version?: number; readonly title?: string; - readonly titleKind?: 'replaceable' | 'generated' | 'custom'; + readonly isCustomTitle?: boolean; readonly lastPrompt?: string; readonly createdAt: number; readonly updatedAt: number; readonly archived: boolean; - readonly archivedAt?: number; readonly cwd?: string; readonly forkedFrom?: string; readonly agents?: Readonly<Record<string, /* AgentMeta — packages/agent-core-v2/src/session/sessionMetadata/sessionMetadata.ts */ { @@ -688,6 +467,246 @@ export interface SessionStateSnapshot { readonly custom?: Record<string, unknown>; readonly lastTurnReason?: 'completed' | 'cancelled' | 'failed'; } | undefined; + // src/session/sessionSkillCatalog/skillCatalogService.ts + 'sessionSkillCatalog.contributions': Map<string, { + readonly c: /* SkillContribution — packages/agent-core-v2/src/app/skillCatalog/skillSource.ts */ { + readonly skills: readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }[]; + readonly skipped?: readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly path: string; + readonly type: string; + readonly reason: string; + }[]; + readonly scannedRoots?: readonly string[]; + }; + readonly priority: number; + }>; + 'sessionSkillCatalog.merged': /* InMemorySkillCatalog — packages/agent-core-v2/src/app/skillCatalog/registry.ts */ { + registerBuiltinSkill: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }) => void; + register: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }, options?: { + readonly replace?: boolean; + }) => void; + recordSkipped: (skills: readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly path: string; + readonly type: string; + readonly reason: string; + }[]) => void; + addRoots: (roots: readonly string[]) => void; + getSkill: (name: string) => /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + } | undefined; + getPluginSkill: (pluginId: string, name: string) => /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + } | undefined; + renderSkillPrompt: (skill: /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }, rawArgs: string, context?: { + readonly sessionId?: string; + }) => string; + listSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }[]; + listInvocableSkills: () => readonly /* SkillDefinition — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name: string; + readonly description: string; + readonly path: string; + readonly dir: string; + readonly content: string; + readonly metadata: /* SkillMetadata — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly name?: string; + readonly description?: string; + readonly type?: string; + readonly whenToUse?: string; + readonly disableModelInvocation?: boolean; + readonly isSubSkill?: boolean; + readonly safe?: boolean; + readonly arguments?: string | readonly unknown[]; + [key: string]: unknown; + }; + readonly source: /* SkillSource — packages/agent-core-v2/src/app/skillCatalog/types.ts */ 'project' | 'user' | 'extra' | 'builtin'; + readonly plugin?: /* SkillPluginContext — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly id: string; + readonly instructions?: string; + }; + readonly mermaid?: string; + readonly d2?: string; + readonly productSpecific?: boolean; + }[]; + getSkillRoots: () => readonly string[]; + getSkippedByPolicy: () => readonly /* SkippedSkill — packages/agent-core-v2/src/app/skillCatalog/types.ts */ { + readonly path: string; + readonly type: string; + readonly reason: string; + }[]; + getKimiSkillsDescription: () => string; + getModelSkillListing: () => string; + }; // src/session/sessionToolPolicy/sessionToolPolicyService.ts 'sessionToolPolicy.state': /* SessionToolPolicyState — packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicyService.ts */ { readonly disabledTools: readonly string[]; @@ -713,14 +732,6 @@ export interface AgentStateSnapshot { readonly turnId: number; readonly origin: /* PromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ /* UserPromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'user'; - readonly skillActivations?: readonly /* BundledSkillActivation — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: 'project' | 'user' | 'extra' | 'builtin'; - }[]; } | /* SkillActivationOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'skill_activation'; readonly activationId: string; @@ -741,7 +752,12 @@ export interface AgentStateSnapshot { readonly kind: 'injection'; readonly variant: string; readonly ownerPromptId?: string; - readonly disclosure?: unknown; + readonly disclosure?: /* ContextInjectionDisclosure — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { + readonly kind: 'date'; + readonly renderGeneration: number; + readonly localDate: string; + readonly timeZone: string; + }; } | /* ShellCommandOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'shell_command'; readonly phase: 'input' | 'output'; @@ -846,14 +862,6 @@ export interface AgentStateSnapshot { turnId: number; origin: /* PromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ /* UserPromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'user'; - readonly skillActivations?: readonly /* BundledSkillActivation — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: 'project' | 'user' | 'extra' | 'builtin'; - }[]; } | /* SkillActivationOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'skill_activation'; readonly activationId: string; @@ -874,7 +882,12 @@ export interface AgentStateSnapshot { readonly kind: 'injection'; readonly variant: string; readonly ownerPromptId?: string; - readonly disclosure?: unknown; + readonly disclosure?: /* ContextInjectionDisclosure — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { + readonly kind: 'date'; + readonly renderGeneration: number; + readonly localDate: string; + readonly timeZone: string; + }; } | /* ShellCommandOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'shell_command'; readonly phase: 'input' | 'output'; @@ -911,14 +924,6 @@ export interface AgentStateSnapshot { readonly turnId: number; readonly origin: /* PromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ /* UserPromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'user'; - readonly skillActivations?: readonly /* BundledSkillActivation — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: 'project' | 'user' | 'extra' | 'builtin'; - }[]; } | /* SkillActivationOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'skill_activation'; readonly activationId: string; @@ -939,7 +944,12 @@ export interface AgentStateSnapshot { readonly kind: 'injection'; readonly variant: string; readonly ownerPromptId?: string; - readonly disclosure?: unknown; + readonly disclosure?: /* ContextInjectionDisclosure — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { + readonly kind: 'date'; + readonly renderGeneration: number; + readonly localDate: string; + readonly timeZone: string; + }; } | /* ShellCommandOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { readonly kind: 'shell_command'; readonly phase: 'input' | 'output'; @@ -1002,143 +1012,40 @@ export interface AgentStateSnapshot { 'agentsMdReminder.cwd': string | undefined; 'agentsMdReminder.known': Set<string>; 'agentsMdReminder.seeded': boolean; - // src/agent/contextMemory/contextOps.ts - // replayable · durable · undoable — folds: ContextAppendMessage, ContextAppendLoopEvent, ContextClear, ContextApplyCompaction - 'contextMemory': (/* ContextMessage — packages/agent-core-v2/src/agent/contextMemory/types.ts */ /* Message — packages/agent-core-v2/src/kosong/contract/message.ts */ { - readonly role: /* Role — packages/agent-core-v2/src/kosong/contract/message.ts */ 'user' | 'assistant' | 'system' | 'tool'; - readonly name?: string; - readonly content: (/* ContentPart — packages/agent-core-v2/src/kosong/contract/message.ts */ /* TextPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'text'; - text: string; - } | /* ThinkPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'think'; - think: string; - encrypted?: string; - } | /* ImageURLPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'image_url'; - imageUrl: { - url: string; - id?: string; - }; - } | /* AudioURLPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'audio_url'; - audioUrl: { - url: string; - id?: string; - }; - } | /* VideoURLPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'video_url'; - videoUrl: { - url: string; - id?: string; - }; - })[]; - readonly toolCalls: /* ToolCall — packages/agent-core-v2/src/kosong/contract/message.ts */ { - type: 'function'; - id: string; - name: string; - arguments: string | null; - extras?: Record<string, unknown>; - _streamIndex?: string | number; - }[]; - readonly toolCallId?: string; - readonly partial?: boolean; - readonly tools?: readonly /* Tool — packages/agent-core-v2/src/kosong/contract/tool.ts */ { - name: string; - description: string; - parameters: Record<string, unknown>; - deferred?: true; - }[]; - } & { - readonly id?: string; - readonly providerMessageId?: string; - readonly origin?: /* UserPromptOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'user'; - readonly skillActivations?: readonly /* BundledSkillActivation — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: 'project' | 'user' | 'extra' | 'builtin'; - }[]; - } | /* SkillActivationOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'skill_activation'; - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly trigger: 'user-slash' | 'model-tool' | 'nested-skill'; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: 'project' | 'user' | 'extra' | 'builtin'; - } | /* PluginCommandOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'plugin_command'; - readonly activationId: string; - readonly pluginId: string; - readonly commandName: string; - readonly commandArgs?: string; - readonly trigger: 'user-slash'; - } | /* InjectionOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'injection'; - readonly variant: string; - readonly ownerPromptId?: string; - readonly disclosure?: unknown; - } | /* ShellCommandOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'shell_command'; - readonly phase: 'input' | 'output'; - readonly isError?: boolean; - } | /* CompactionSummaryOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'compaction_summary'; - } | /* SystemTriggerOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'system_trigger'; - readonly name: string; - } | /* TaskOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'task'; - readonly taskId: string; - readonly status: /* AgentTaskStatus — packages/agent-core-v2/src/agent/task/types.ts */ 'completed' | 'failed' | 'running' | 'timed_out' | 'killed' | 'lost'; - readonly notificationId: string; - } | /* CronJobOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'cron_job'; - readonly jobId: string; - readonly cron: string; - readonly recurring: boolean; - readonly coalescedCount: number; - readonly stale: boolean; - } | /* CronMissedOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'cron_missed'; - readonly count: number; - } | /* HookResultOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'hook_result'; - readonly event: string; - readonly blocked?: boolean; - } | /* RetryOrigin — packages/agent-core-v2/src/agent/contextMemory/types.ts */ { - readonly kind: 'retry'; - readonly trigger?: string; - }; - readonly isError?: boolean; - readonly note?: string; - })[]; + // src/agent/contextInjector/contextInjectorService.ts + 'contextInjector.isNewTurn': boolean; // src/agent/contextProjector/contextProjectorService.ts 'contextProjector.lastRepairSignature': string | null; - // src/agent/fullCompaction/compactionOps.ts - // replayable · durable — folds: FullCompactionBegin, FullCompactionCancel, FullCompactionComplete - 'fullCompaction': /* CompactionState — packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts */ { - readonly phase: /* CompactionPhase — packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts */ 'completed' | 'cancelled' | 'running' | 'idle'; - }; + // src/agent/dateChange/dateChangeService.ts + 'dateChange.seed': /* DateDisclosure — packages/agent-core-v2/src/agent/dateChange/dateChangeService.ts */ { + readonly localDate: string; + readonly timeZone: string; + readonly renderGeneration: number; + } | undefined; + // src/agent/externalHooks/externalHooksService.ts + 'externalHooks.stopHookContinuationUsed': boolean; // src/agent/fullCompaction/fullCompactionService.ts 'fullCompaction.activeTurnId': number | undefined; 'fullCompaction.compactionCountInTurn': number; 'fullCompaction.consecutiveOverflowCompactions': number; 'fullCompaction.lastCompactedTokenCount': number | null; 'fullCompaction.observedMaxContextTokensByModel': Map<string, number>; - // src/agent/interruptionReminder/interruptionReminderOps.ts - // replayable · durable — folds: InterruptionReminderRecorded - 'interruptionReminder': null; - // src/agent/llmRequester/llmRequestOps.ts - // replayable · durable — folds: LlmToolsSnapshot, LlmRequest - 'llm.requestTrace': /* LlmRequestTraceState — packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts */ { - readonly seenToolsHashes: readonly string[]; - }; + // src/agent/goal/goalService.ts + 'goal.budgetGraceTurns': Set<number>; + 'goal.countedGoalTurns': Set<number>; + 'goal.exhaustedTurnBudgetGoals': Map<number, string>; + 'goal.goalDrivenTurns': Map<number, string>; + 'goal.goalOutcomeContinuationTurns': Set<number>; + 'goal.goalOutcomeToolResultTurns': Map<number, string>; + 'goal.goalStarterTurns': Set<number>; + 'goal.goalTurnTargets': Map<number, string>; + 'goal.liveTurnId': number | undefined; + 'goal.liveWallClockStartedAt': number | undefined; + 'goal.pendingContinuationGoals': Map<number, string>; + 'goal.resumeContinuation': /* ResumeContinuation — packages/agent-core-v2/src/agent/goal/goalService.ts */ { + readonly turnId: number; + readonly goalId: string; + } | undefined; // src/agent/llmRequester/llmRequesterService.ts 'llmRequester.emittedThinkingEffortWarnings': Set<string>; 'llmRequester.lastConfigLogSignature': string | undefined; @@ -1184,26 +1091,12 @@ export interface AgentStateSnapshot { 'loop.disposing': boolean; 'loop.lastRequestTraceId': string | undefined; 'loop.nextReservedTurnId': number | undefined; - // src/agent/loop/turnOps.ts - // replayable · durable — folds: ContextAppendLoopEvent, TurnPrompt, TurnSteer, TurnCancel, TurnEnded - 'turn': /* TurnModelState — packages/agent-core-v2/src/agent/loop/turnOps.ts */ { - readonly nextTurnId: number; - readonly cancelledTurnIds: readonly number[]; - readonly lastEnded?: { - readonly turnId: number; - readonly reason: 'completed' | 'cancelled' | 'failed' | 'blocked'; - readonly durationMs?: number; - }; - }; - // src/agent/mcp/mcpDiscoveryOps.ts - // replayable · durable — folds: McpToolsDiscovered - 'mcp.discovery': /* McpDiscoveryState — packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts */ { - readonly seen: readonly string[]; - }; // src/agent/mcp/mcpService.ts 'mcp.discoveryWritesReady': boolean; 'mcp.mcpToolsByServer': Map<string, string[]>; - // src/agent/media/mediaResolverService.ts + // src/agent/media/mediaToolsRegistrar.ts + 'media.registeredKey': string | undefined; + // src/agent/media/videoResolverService.ts 'media.resolved': Map<string, /* ContentPart — packages/agent-core-v2/src/kosong/contract/message.ts */ /* TextPart — packages/agent-core-v2/src/kosong/contract/message.ts */ { type: 'text'; text: string; @@ -1230,133 +1123,21 @@ export interface AgentStateSnapshot { id?: string; }; }>; - // src/agent/media/mediaToolsRegistrar.ts - 'media.registeredKey': string | undefined; // src/agent/permissionMode/injection/permissionModeInjection.ts - 'permissionMode.lastMode': 'manual' | 'auto' | 'yolo' | undefined; - // src/agent/permissionMode/permissionModeOps.ts - // replayable · durable — folds: PermissionSetMode - 'permissionMode': /* PermissionMode — packages/agent-core-v2/src/agent/permissionPolicy/types.ts */ 'manual' | 'auto' | 'yolo'; - // replayable · durable — folds: PermissionSetMode - 'permissionMode.configured': boolean; - // src/agent/permissionRules/permissionRulesOps.ts - // replayable · durable — folds: PermissionRulesAdd, PermissionRecordApprovalResult - 'permissionRules': /* PermissionRulesModelState — packages/agent-core-v2/src/agent/permissionRules/permissionRulesOps.ts */ { - readonly rules: readonly /* PermissionRule — packages/agent-core-v2/src/agent/permissionRules/permissionRules.ts */ { - readonly decision: /* PermissionRuleDecision — packages/agent-core-v2/src/agent/permissionRules/permissionRules.ts */ 'allow' | 'deny' | 'ask'; - readonly scope: /* PermissionRuleScope — packages/agent-core-v2/src/agent/permissionRules/permissionRules.ts */ 'project' | 'user' | 'turn-override' | 'session-runtime'; - readonly pattern: string; - readonly reason?: string; - }[]; - readonly sessionApprovalRulePatterns: readonly string[]; - }; - // src/agent/plugin/agentPluginOps.ts - // replayable · durable — folds: PluginSessionStartEvent - 'pluginSessionStartSnapshot': /* PluginSessionStartSnapshotState — packages/agent-core-v2/src/agent/plugin/agentPluginOps.ts */ { - readonly initialized: boolean; - readonly content?: string; - }; - // src/agent/plugin/agentPluginService.ts - 'agentPlugin.sessionStartRefreshPending': boolean; - // src/agent/profile/profileOps.ts - // replayable · durable — folds: ProfileBind, ConfigUpdate - 'profile': /* ProfileModelState — packages/agent-core-v2/src/agent/profile/profileOps.ts */ { - readonly modelAlias?: string; - readonly profileName?: string; - readonly thinkingLevel: string; - readonly systemPrompt: string; - readonly environmentDisclosure?: /* EnvironmentDisclosureSnapshot — packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts */ { - readonly cwd: string; - readonly date: { - readonly disclosed: true; - readonly value: { - readonly localDate: string; - readonly timeZone: string; - }; - } | { - readonly disclosed: false; - }; - }; - readonly renderGeneration: number; - readonly agentsMdPaths?: readonly string[]; - readonly disallowedTools?: readonly string[]; - readonly subagents?: readonly string[]; - }; - // replayable · durable — folds: ToolsSetActiveTools, ToolsResetActiveTools, ProfileBind - 'profile.activeTools': /* ActiveToolsState — packages/agent-core-v2/src/agent/profile/profileOps.ts */ readonly string[] | undefined; + 'permissionMode.lastMode': 'manual' | 'yolo' | 'auto' | undefined; // src/agent/profile/profileService.ts 'profile.activeToolNamesOverlay': readonly string[] | undefined; 'profile.agentsMdWarning': string | undefined; 'profile.emittedPluginBudgetWarnings': Set<string>; 'profile.emittedThinkingEffortWarnings': Set<string>; 'profile.emittedToolPatternWarnings': Set<string>; - // src/agent/prompt/promptOps.ts - // replayable · durable — folds: PromptAccepted - 'promptAdmission': Map<string, true>; // src/agent/prompt/promptService.ts 'prompt.launching': boolean; - // src/agent/runtimeBinding/runtimeBindingOps.ts - // replayable · durable — folds: RuntimeSetBinding - 'runtimeBinding': /* RuntimeBinding — packages/agent-core-v2/src/runtime/runtime.ts */ { - readonly workspaceId: string; - readonly runtimeId: string; - } | undefined; - // src/agent/runtimeBinding/runtimeBindingService.ts - 'runtime.binding': /* RuntimeBinding — packages/agent-core-v2/src/runtime/runtime.ts */ { - readonly workspaceId: string; - readonly runtimeId: string; - }; // src/agent/shellCommand/shellCommandService.ts 'shellCommand.tasks': Map<string, string>; // src/agent/stepRetry/stepRetryService.ts 'stepRetry.failedAttempts': number; 'stepRetry.lastFailedDriverId': string | undefined; - // src/agent/task/taskOps.ts - // replayable · durable — folds: TaskStarted, TaskTerminated - 'task': /* TaskModelState — packages/agent-core-v2/src/agent/task/taskOps.ts */ Map<string, /* AgentTaskInfo — packages/agent-core-v2/src/agent/task/types.ts */ /* QuestionTaskInfo — packages/agent-core-v2/src/agent/tools/ask-user-question/question-background-task.ts */ { - readonly kind: 'question'; - readonly questionCount: number; - readonly toolCallId?: string; - readonly taskId: string; - readonly description: string; - readonly status: /* AgentTaskStatus — packages/agent-core-v2/src/agent/task/types.ts */ 'completed' | 'failed' | 'running' | 'timed_out' | 'killed' | 'lost'; - readonly detached?: boolean; - readonly startedAt: number; - readonly endedAt: number | null; - readonly stopReason?: string; - readonly terminalNotificationSuppressed?: boolean; - readonly timeoutMs?: number; - } | /* SubagentTaskInfo — packages/agent-core-v2/src/agent/tools/agent/subagent-task.ts */ { - readonly kind: 'agent'; - readonly agentId?: string; - readonly subagentType?: string; - readonly parentToolCallId?: string; - readonly model?: string; - readonly thinkingEffort?: string; - readonly taskId: string; - readonly description: string; - readonly status: /* AgentTaskStatus — packages/agent-core-v2/src/agent/task/types.ts */ 'completed' | 'failed' | 'running' | 'timed_out' | 'killed' | 'lost'; - readonly detached?: boolean; - readonly startedAt: number; - readonly endedAt: number | null; - readonly stopReason?: string; - readonly terminalNotificationSuppressed?: boolean; - readonly timeoutMs?: number; - } | /* ProcessTaskInfo — packages/agent-core-v2/src/agent/tools/os/bash/process-task.ts */ { - readonly kind: 'process'; - readonly command: string; - readonly pid: number; - readonly exitCode: number | null; - readonly taskId: string; - readonly description: string; - readonly status: /* AgentTaskStatus — packages/agent-core-v2/src/agent/task/types.ts */ 'completed' | 'failed' | 'running' | 'timed_out' | 'killed' | 'lost'; - readonly detached?: boolean; - readonly startedAt: number; - readonly endedAt: number | null; - readonly stopReason?: string; - readonly terminalNotificationSuppressed?: boolean; - readonly timeoutMs?: number; - }>; // src/agent/task/taskService.ts 'task.activeTaskReminderPending': boolean; 'task.deliveredNotificationKeys': Set<string>; @@ -1377,7 +1158,6 @@ export interface AgentStateSnapshot { readonly kind: 'agent'; readonly agentId?: string; readonly subagentType?: string; - readonly parentToolCallId?: string; readonly model?: string; readonly thinkingEffort?: string; readonly taskId: string; @@ -1404,8 +1184,6 @@ export interface AgentStateSnapshot { readonly terminalNotificationSuppressed?: boolean; readonly timeoutMs?: number; }>; - // replayable · durable · undoable — folds: ContextAppendMessage, TaskWaitDelivered - 'task.notificationDelivery': readonly string[]; 'task.scheduledNotificationKeys': Set<string>; // src/agent/toolDedupe/toolDedupeService.ts 'toolDedupe.activeStep': number; @@ -1416,46 +1194,23 @@ export interface AgentStateSnapshot { 'toolDedupe.originalCallIndex': Map<string, number>; 'toolDedupe.stepCalls': string[]; 'toolDedupe.syntheticCallIds': Set<string>; - 'toolDedupe.turnCallRecords': Map<string, /* TurnCallRecord — packages/agent-core-v2/src/agent/toolDedupe/toolDedupeService.ts */ { - count: number; - lastStep: number; - }>; - 'toolDedupe.turnRepeatCount': number; // src/agent/toolExecutor/toolExecutorService.ts 'toolExecutor.dupTypeTurnId': number | undefined; 'toolExecutor.toolCallDupTypes': Map<string, /* ToolCallDupType — packages/agent-core-v2/src/agent/toolExecutor/toolExecutor.ts */ 'same_step' | 'cross_step'>; + // src/agent/toolSelect/toolSelectAnnouncementsService.ts + 'toolSelect.needsBoundaryInjection': boolean; // src/agent/toolSelect/toolSelectService.ts 'toolSelect.pendingLoaded': Set<string>; - // src/agent/userTool/userToolOps.ts - // replayable · durable — folds: ToolsRegisterUserTool, ToolsUnregisterUserTool - 'userTool': /* UserToolModelState — packages/agent-core-v2/src/agent/userTool/userToolOps.ts */ Map<string, /* UserToolRegistration — packages/agent-core-v2/src/agent/userTool/userTool.ts */ { - readonly name: string; - readonly description: string; - readonly parameters: Record<string, unknown>; - readonly disclosure?: 'deferred' | 'inline'; - }>; - // src/features/externalHooks/agent/agentExternalHooksService.ts - 'externalHooks.stopHookContinuationUsed': boolean; + // src/agent/usage/usageService.ts + 'usage.currentTurn': /* TokenUsage — packages/agent-core-v2/src/kosong/contract/usage.ts */ { + inputOther: number; + output: number; + inputCacheRead: number; + inputCacheCreation: number; + } | undefined; + 'usage.currentTurnId': number | undefined; // src/features/plan/injection/planModeInjection.ts 'plan.wasActive': boolean; - // src/features/plan/planOps.ts - // replayable · durable · undoable — folds: PlanModeEnter, PlanModeCancel, PlanModeExit, PlanRevision - 'plan': /* PlanState — packages/agent-core-v2/src/features/plan/planOps.ts */ { - readonly active: boolean; - readonly id?: string; - readonly revisionCount?: Readonly<Record<string, number>>; - }; - // src/features/staleGuard/staleGuardOps.ts - // replayable · durable — folds: StaleGuardRecorded, StaleGuardCleared - 'staleGuard': /* StaleGuardModelState — packages/agent-core-v2/src/features/staleGuard/staleGuardOps.ts */ Map<string, number>; - // src/features/swarm/swarmOps.ts - // replayable · durable — folds: SwarmModeEnter, SwarmModeExit - 'swarm': 'task' | 'tool' | 'manual' | null; - // src/features/tower/towerOps.ts - // replayable · durable — folds: TowerModeEnter, TowerModeExit - 'tower': boolean; - // replayable · durable — folds: TowerModeEnter, TowerModeExit - 'tower.owner': string | undefined; } export type AgentStateKey = keyof AgentStateSnapshot; diff --git a/packages/agent-core-v2/docs/wire-manifest.d.ts b/packages/agent-core-v2/docs/wire-manifest.d.ts index 0ef3e5124..aaf5e4a41 100644 --- a/packages/agent-core-v2/docs/wire-manifest.d.ts +++ b/packages/agent-core-v2/docs/wire-manifest.d.ts @@ -5,89 +5,78 @@ // // protocol_version: "1.5" (migrations: 1.0 -> 1.1 -> 1.2 -> 1.3 -> 1.4 -> 1.5) // -// One declaration per durable record type — an Event2 subclass declaring -// `static type` + `static durable = true` + `static schema` — drained from the -// runtime EVENT2_REGISTRY ("import = register"). Every payload declaration -// carries its record type in a `_name` field. Payload sketches use TypeScript -// type syntax; when a named type is expanded inline, its name appears as a doc -// comment (`/** ContextMessage */`). Bare type names (ContentPart, -// ContextMessage, …) refer to the real types in src/ — they are intentionally -// not resolved here. `// …` marks a capped field list. On disk (wire.jsonl) -// the journal opens with a metadata line {"type": "metadata", -// "protocol_version", "created_at"}; each record is {"type", ...payload, -// "time"} — object payloads spread at the top level. +// One declaration per record type registered via defineOp(...) and drained from +// the runtime OP_REGISTRY. Every payload declaration carries its record type in +// a `_name` field. Payload sketches use TypeScript type syntax; when a +// named type is expanded inline, its name appears as a doc comment +// (`/** ContextMessage */`). Bare type names (ContentPart, ContextMessage, …) +// refer to the real types in src/ — they are intentionally not resolved here. +// `// …` marks a capped field list. On disk (wire.jsonl) the journal opens with +// a metadata line {"type": "metadata", "protocol_version", "created_at"}; each +// op record is {"type", ...payload, "time"} — object payloads spread at the +// top level, scalar payloads nest under a "payload" key. // -// Every listed type is durable by construction — transient Event2 classes -// never enter EVENT2_REGISTRY, so there is no persisted flag. Declaration -// header lines: states (every state folding this record type on dispatch and -// replay; any state beyond the first is what the retired format listed as -// cross-reducers), blobs (the folding states whose blob codec offloads inline -// media to blob storage), owner (the source file declaring the class). +// Declaration flags: persisted (written to the journal; absent = transient), +// toEvent (also publishes an IEventBus fact on live dispatch), blobs (the +// owning model offloads inline media to blob storage), cross-reducers +// (foreign models that also reduce this record on dispatch and replay). -// Index (55 record types) -// config.update profile src/agent/profile/profileOps.ts -// context.append_loop_event contextMemory, turn src/agent/contextMemory/contextEvents.ts -// context.append_message contextMemory, plan, task.notificationDelivery src/agent/contextMemory/contextEvents.ts -// context.apply_compaction contextMemory, plan, task.notificationDelivery src/agent/contextMemory/contextEvents.ts -// context.clear contextMemory, plan, task.notificationDelivery src/agent/contextMemory/contextEvents.ts -// context.undo contextMemory, plan, task.notificationDelivery src/agent/contextMemory/contextEvents.ts -// cron.add (none) src/features/cron/cronOps.ts -// cron.cursor (none) src/features/cron/cronOps.ts -// cron.delete (none) src/features/cron/cronOps.ts -// forked (none) src/features/goal/goalOps.ts -// full_compaction.begin fullCompaction src/agent/fullCompaction/compactionOps.ts -// full_compaction.cancel fullCompaction src/agent/fullCompaction/compactionOps.ts -// full_compaction.complete fullCompaction src/agent/fullCompaction/compactionOps.ts -// goal.clear (none) src/features/goal/goalOps.ts -// goal.create (none) src/features/goal/goalOps.ts -// goal.update (none) src/features/goal/goalOps.ts -// interaction.request (none) src/features/interaction/interactionOps.ts -// interaction.resolved (none) src/features/interaction/interactionOps.ts -// interruptionReminder.recorded interruptionReminder src/agent/interruptionReminder/interruptionReminderOps.ts -// llm.request llm.requestTrace src/agent/llmRequester/llmRequestOps.ts -// llm.tools_snapshot llm.requestTrace src/agent/llmRequester/llmRequestOps.ts -// mcp.tools_discovered mcp.discovery src/agent/mcp/mcpDiscoveryOps.ts -// permission.record_approval_result permissionRules src/agent/permissionRules/permissionRulesOps.ts -// permission.set_mode permissionMode, permissionMode.configured src/agent/permissionMode/permissionModeOps.ts -// plan_mode.cancel plan src/features/plan/planOps.ts -// plan_mode.enter plan src/features/plan/planOps.ts -// plan_mode.exit plan src/features/plan/planOps.ts -// plan.revision plan src/features/plan/planOps.ts -// plugin.session_start pluginSessionStartSnapshot src/agent/plugin/agentPluginOps.ts -// profile.bind profile, profile.activeTools src/agent/profile/profileOps.ts -// prompt.accepted promptAdmission src/agent/prompt/promptOps.ts -// runtime.set_binding runtimeBinding src/agent/runtimeBinding/runtimeBindingOps.ts -// staleGuard.cleared staleGuard src/features/staleGuard/staleGuardOps.ts -// staleGuard.recorded staleGuard src/features/staleGuard/staleGuardOps.ts -// swarm_mode.enter swarm src/features/swarm/swarmOps.ts -// swarm_mode.exit contextMemory, swarm src/features/swarm/swarmOps.ts -// task.started task src/agent/task/taskOps.ts -// task.terminated task src/agent/task/taskOps.ts -// task.waitDelivered task.notificationDelivery src/agent/task/taskOps.ts -// token_counting.measured (none) src/agent/tokenCounting/tokenCountingOps.ts -// token_counting.rebased (none) src/agent/tokenCounting/tokenCountingOps.ts -// token_counting.truncated (none) src/agent/tokenCounting/tokenCountingOps.ts -// token_counting.turn_recorded (none) src/agent/tokenCounting/tokenCountingOps.ts -// tools.register_user_tool userTool src/agent/userTool/userToolOps.ts -// tools.reset_active_tools profile.activeTools src/agent/profile/profileOps.ts -// tools.set_active_tools profile.activeTools src/agent/profile/profileOps.ts -// tools.unregister_user_tool userTool src/agent/userTool/userToolOps.ts -// tools.update_store (none) src/features/todo/todoOps.ts -// tower_mode.enter tower, tower.owner src/features/tower/towerOps.ts -// tower_mode.exit tower, tower.owner src/features/tower/towerOps.ts -// turn.cancel turn src/agent/loop/turnOps.ts -// turn.ended turn src/agent/loop/turnOps.ts -// turn.prompt turn src/agent/loop/turnOps.ts -// turn.steer turn src/agent/loop/turnOps.ts -// usage.record (none) src/agent/usage/usageOps.ts +// Index (48 record types) +// config.update profile persisted src/agent/profile/profileOps.ts +// context.append_loop_event contextMemory persisted src/agent/contextMemory/contextOps.ts +// context.append_message contextMemory persisted src/agent/contextMemory/contextOps.ts +// context.apply_compaction contextMemory persisted src/agent/contextMemory/contextOps.ts +// context.clear contextMemory persisted src/agent/contextMemory/contextOps.ts +// context.undo contextMemory persisted src/agent/contextMemory/contextOps.ts +// cron.add cron transient src/session/cron/cronOps.ts +// cron.cursor cron transient src/session/cron/cronOps.ts +// cron.delete cron transient src/session/cron/cronOps.ts +// forked goal persisted src/agent/goal/goalOps.ts +// full_compaction.begin fullCompaction persisted src/agent/fullCompaction/compactionOps.ts +// full_compaction.cancel fullCompaction persisted src/agent/fullCompaction/compactionOps.ts +// full_compaction.complete fullCompaction persisted src/agent/fullCompaction/compactionOps.ts +// goal.clear goal persisted src/agent/goal/goalOps.ts +// goal.create goal persisted src/agent/goal/goalOps.ts +// goal.update goal persisted src/agent/goal/goalOps.ts +// interaction.request interaction persisted src/session/interaction/interactionOps.ts +// interaction.resolved interaction persisted src/session/interaction/interactionOps.ts +// interruptionReminder.recorded interruptionReminder persisted src/agent/interruptionReminder/interruptionReminderOps.ts +// llm.request llm.requestTrace persisted src/agent/llmRequester/llmRequestOps.ts +// llm.tools_snapshot llm.requestTrace persisted src/agent/llmRequester/llmRequestOps.ts +// mcp.tools_discovered mcp.discovery persisted src/agent/mcp/mcpDiscoveryOps.ts +// permission.record_approval_result permissionRules persisted src/agent/permissionRules/permissionRulesOps.ts +// permission.rules.add permissionRules transient src/agent/permissionRules/permissionRulesOps.ts +// permission.set_mode permissionMode persisted src/agent/permissionMode/permissionModeOps.ts +// plan_mode.cancel plan persisted src/features/plan/planOps.ts +// plan_mode.enter plan persisted src/features/plan/planOps.ts +// plan_mode.exit plan persisted src/features/plan/planOps.ts +// plan.revision plan persisted src/features/plan/planOps.ts +// profile.bind profile persisted src/agent/profile/profileOps.ts +// skill.activate skill transient src/agent/skill/skillOps.ts +// swarm_mode.enter swarm persisted src/agent/swarm/swarmOps.ts +// swarm_mode.exit swarm persisted src/agent/swarm/swarmOps.ts +// task.started task persisted src/agent/task/taskOps.ts +// task.terminated task persisted src/agent/task/taskOps.ts +// token_counting.measured tokenCounting transient src/agent/tokenCounting/tokenCountingOps.ts +// token_counting.rebased tokenCounting transient src/agent/tokenCounting/tokenCountingOps.ts +// token_counting.truncated tokenCounting transient src/agent/tokenCounting/tokenCountingOps.ts +// tools.register_user_tool userTool persisted src/agent/userTool/userToolOps.ts +// tools.reset_active_tools profile.activeTools persisted src/agent/profile/profileOps.ts +// tools.set_active_tools profile.activeTools persisted src/agent/profile/profileOps.ts +// tools.unregister_user_tool userTool persisted src/agent/userTool/userToolOps.ts +// tools.update_store todo persisted src/session/todo/todoOps.ts +// turn.cancel turn persisted src/agent/loop/turnOps.ts +// turn.ended turn persisted src/agent/loop/turnOps.ts +// turn.prompt turn persisted src/agent/loop/turnOps.ts +// turn.steer turn persisted src/agent/loop/turnOps.ts +// usage.record usage persisted src/agent/usage/usageOps.ts /** - * states: profile + * model: profile · persisted * owner: src/agent/profile/profileOps.ts */ interface ConfigUpdatePayload { _name: 'config.update'; - agentId: string; modelAlias?: string; profileName?: string; /** ThinkingEffort */ @@ -106,23 +95,21 @@ interface ConfigUpdatePayload { } /** - * states: contextMemory, turn · blobs: contextMemory - * owner: src/agent/contextMemory/contextEvents.ts + * model: contextMemory · persisted · blobs · cross-reducers: turn + * owner: src/agent/contextMemory/contextOps.ts */ interface ContextAppendLoopEventPayload { _name: 'context.append_loop_event'; - agentId: string; /** LoopRecordedEvent */ event: 'step.begin' | 'step.end' | 'content.part' | 'tool.call' | 'tool.result'; } /** - * states: contextMemory, plan, task.notificationDelivery · blobs: contextMemory - * owner: src/agent/contextMemory/contextEvents.ts + * model: contextMemory · persisted · blobs · cross-reducers: plan, goalForkNotice, task.notificationDelivery, todo + * owner: src/agent/contextMemory/contextOps.ts */ interface ContextAppendMessagePayload { _name: 'context.append_message'; - agentId: string; /** ContextMessage */ message: { role: 'system' | 'user' | 'assistant' | 'tool'; @@ -153,37 +140,36 @@ interface ContextAppendMessagePayload { } /** - * states: contextMemory, plan, task.notificationDelivery · blobs: contextMemory - * owner: src/agent/contextMemory/contextEvents.ts + * model: contextMemory · persisted · blobs · cross-reducers: plan, task.notificationDelivery, todo + * owner: src/agent/contextMemory/contextOps.ts * shared base: ...contextCompactionBaseShape */ type ContextApplyCompactionPayload = { _name: 'context.apply_compaction'; } & ({ summary: string, compactedCount: number, contextSummary?: string } | { contextSummary: string, compactedCount: number, summary?: string } | { summary: ContextMessage, count: number, compactedCount?: number }); /** - * states: contextMemory, plan, task.notificationDelivery · blobs: contextMemory - * owner: src/agent/contextMemory/contextEvents.ts + * model: contextMemory · persisted · blobs · cross-reducers: plan, task.notificationDelivery, todo + * owner: src/agent/contextMemory/contextOps.ts */ interface ContextClearPayload { _name: 'context.clear'; - agentId: string; } /** - * states: contextMemory, plan, task.notificationDelivery · blobs: contextMemory - * owner: src/agent/contextMemory/contextEvents.ts + * model: contextMemory · persisted · blobs · cross-reducers: plan, task.notificationDelivery, todo + * owner: src/agent/contextMemory/contextOps.ts */ interface ContextUndoPayload { _name: 'context.undo'; - agentId: string; count: number; } /** - * states: (none) - * owner: src/features/cron/cronOps.ts + * model: cron + * owner: src/session/cron/cronOps.ts */ interface CronAddPayload { _name: 'cron.add'; + /** CronTask */ task: { id: string; cron: string; @@ -191,13 +177,13 @@ interface CronAddPayload { createdAt: number; recurring?: boolean; lastFiredAt?: number; - tags?: Record<string, string>; + tags?: Readonly<Record<string, string>>; }; } /** - * states: (none) - * owner: src/features/cron/cronOps.ts + * model: cron + * owner: src/session/cron/cronOps.ts */ interface CronCursorPayload { _name: 'cron.cursor'; @@ -206,8 +192,8 @@ interface CronCursorPayload { } /** - * states: (none) - * owner: src/features/cron/cronOps.ts + * model: cron + * owner: src/session/cron/cronOps.ts */ interface CronDeletePayload { _name: 'cron.delete'; @@ -215,60 +201,54 @@ interface CronDeletePayload { } /** - * states: (none) - * owner: src/features/goal/goalOps.ts + * model: goal · persisted · cross-reducers: goalForkNotice + * owner: src/agent/goal/goalOps.ts */ interface ForkedPayload { _name: 'forked'; - agentId: string; } /** - * states: fullCompaction + * model: fullCompaction · persisted · toEvent * owner: src/agent/fullCompaction/compactionOps.ts + * payload type: CompactionBeginData */ interface FullCompactionBeginPayload { _name: 'full_compaction.begin'; - agentId: string; instruction?: string; - /** CompactionSource */ source: 'manual' | 'auto'; } /** - * states: fullCompaction + * model: fullCompaction · persisted * owner: src/agent/fullCompaction/compactionOps.ts */ interface FullCompactionCancelPayload { _name: 'full_compaction.cancel'; - agentId: string; } /** - * states: fullCompaction + * model: fullCompaction · persisted * owner: src/agent/fullCompaction/compactionOps.ts */ interface FullCompactionCompletePayload { _name: 'full_compaction.complete'; - agentId: string; } /** - * states: (none) - * owner: src/features/goal/goalOps.ts + * model: goal · persisted · cross-reducers: goalForkNotice + * owner: src/agent/goal/goalOps.ts */ interface GoalClearPayload { _name: 'goal.clear'; - agentId: string; } /** - * states: (none) - * owner: src/features/goal/goalOps.ts + * model: goal · persisted · cross-reducers: goalForkNotice + * owner: src/agent/goal/goalOps.ts */ interface GoalCreatePayload { _name: 'goal.create'; - agentId: string; goalId: string; objective: string; completionCriterion?: string; @@ -283,12 +263,11 @@ interface GoalCreatePayload { } /** - * states: (none) - * owner: src/features/goal/goalOps.ts + * model: goal · persisted + * owner: src/agent/goal/goalOps.ts */ interface GoalUpdatePayload { _name: 'goal.update'; - agentId: string; goalId?: string; status?: 'active' | 'paused' | 'blocked' | 'complete'; reason?: string; @@ -305,46 +284,43 @@ interface GoalUpdatePayload { } /** - * states: (none) - * owner: src/features/interaction/interactionOps.ts + * model: interaction · persisted + * owner: src/session/interaction/interactionOps.ts */ interface InteractionRequestPayload { _name: 'interaction.request'; - agentId: string; id: string; kind: 'approval' | 'question' | 'user_tool'; toolCallId?: string; + agentId?: string; request: any; } /** - * states: (none) - * owner: src/features/interaction/interactionOps.ts + * model: interaction · persisted + * owner: src/session/interaction/interactionOps.ts */ interface InteractionResolvedPayload { _name: 'interaction.resolved'; - agentId: string; id: string; response: any; } /** - * states: interruptionReminder + * model: interruptionReminder · persisted * owner: src/agent/interruptionReminder/interruptionReminderOps.ts */ interface InterruptionReminderRecordedPayload { _name: 'interruptionReminder.recorded'; - agentId: string; turnId: number; } /** - * states: llm.requestTrace + * model: llm.requestTrace · persisted * owner: src/agent/llmRequester/llmRequestOps.ts */ interface LlmRequestPayload { _name: 'llm.request'; - agentId: string; kind: 'loop' | 'compaction'; provider: string; model: string; @@ -363,17 +339,16 @@ interface LlmRequestPayload { messageCount: number; turnStep?: string; attempt?: string; - projection?: 'strict' | 'media-degraded' | 'media-stripped' | 'strict-media-degraded' | 'strict-media-stripped'; + projection?: 'strict' | 'media-degraded' | 'media-stripped'; droppedCount?: number; } /** - * states: llm.requestTrace + * model: llm.requestTrace · persisted * owner: src/agent/llmRequester/llmRequestOps.ts */ interface LlmToolsSnapshotPayload { _name: 'llm.tools_snapshot'; - agentId: string; hash: string; tools: { name: string; @@ -383,12 +358,11 @@ interface LlmToolsSnapshotPayload { } /** - * states: mcp.discovery + * model: mcp.discovery · persisted * owner: src/agent/mcp/mcpDiscoveryOps.ts */ interface McpToolsDiscoveredPayload { _name: 'mcp.tools_discovered'; - agentId: string; serverName: string; hash: string; tools: readonly MCPToolDefinition[]; @@ -401,68 +375,72 @@ interface McpToolsDiscoveredPayload { } /** - * states: permissionRules + * model: permissionRules · persisted * owner: src/agent/permissionRules/permissionRulesOps.ts + * payload type: PermissionApprovalResultRecord */ interface PermissionRecordApprovalResultPayload { _name: 'permission.record_approval_result'; - agentId: string; turnId: number; toolCallId: string; toolName: string; action: string; sessionApprovalRule?: string; - result: PermissionApprovalResultRecord['result']; + result: ApprovalResponse; } /** - * states: permissionMode, permissionMode.configured + * model: permissionRules + * owner: src/agent/permissionRules/permissionRulesOps.ts + */ +interface PermissionRulesAddPayload { + _name: 'permission.rules.add'; + rules: readonly PermissionRule[]; +} + +/** + * model: permissionMode · persisted · cross-reducers: permissionMode.configured * owner: src/agent/permissionMode/permissionModeOps.ts */ interface PermissionSetModePayload { _name: 'permission.set_mode'; - agentId: string; /** PermissionMode */ mode: 'manual' | 'yolo' | 'auto'; } /** - * states: plan + * model: plan · persisted · toEvent * owner: src/features/plan/planOps.ts */ interface PlanModeCancelPayload { _name: 'plan_mode.cancel'; - agentId: string; id?: string; } /** - * states: plan + * model: plan · persisted · toEvent * owner: src/features/plan/planOps.ts */ interface PlanModeEnterPayload { _name: 'plan_mode.enter'; - agentId: string; id: string; } /** - * states: plan + * model: plan · persisted · toEvent * owner: src/features/plan/planOps.ts */ interface PlanModeExitPayload { _name: 'plan_mode.exit'; - agentId: string; id?: string; } /** - * states: plan + * model: plan · persisted · toEvent * owner: src/features/plan/planOps.ts */ interface PlanRevisionPayload { _name: 'plan.revision'; - agentId: string; id: string; version: number; path: string; @@ -471,22 +449,11 @@ interface PlanRevisionPayload { } /** - * states: pluginSessionStartSnapshot - * owner: src/agent/plugin/agentPluginOps.ts - */ -interface PluginSessionStartPayload { - _name: 'plugin.session_start'; - agentId: string; - content: string | null; -} - -/** - * states: profile, profile.activeTools + * model: profile · persisted · cross-reducers: profile.activeTools * owner: src/agent/profile/profileOps.ts */ interface ProfileBindPayload { _name: 'profile.bind'; - agentId: string; modelAlias?: string; profileName?: string; /** ThinkingEffort */ @@ -505,235 +472,160 @@ interface ProfileBindPayload { } /** - * states: promptAdmission - * owner: src/agent/prompt/promptOps.ts + * model: skill · toEvent + * owner: src/agent/skill/skillOps.ts */ -interface PromptAcceptedPayload { - _name: 'prompt.accepted'; - agentId: string; - promptId: string; - content?: any; +interface SkillActivatePayload { + _name: 'skill.activate'; + /** SkillActivationOrigin */ + origin: { + kind: 'skill_activation'; + activationId: string; + skillName: string; + skillArgs?: string | undefined; + trigger: 'user-slash' | 'model-tool' | 'nested-skill'; + skillType?: string | undefined; + skillPath?: string | undefined; + skillSource?: 'project' | 'user' | 'extra' | 'builtin' | undefined; + }; } /** - * states: runtimeBinding - * owner: src/agent/runtimeBinding/runtimeBindingOps.ts - */ -interface RuntimeSetBindingPayload { - _name: 'runtime.set_binding'; - agentId: string; - workspaceId: string; - runtimeId: string; -} - -/** - * states: staleGuard - * owner: src/features/staleGuard/staleGuardOps.ts - */ -interface StaleGuardClearedPayload { - _name: 'staleGuard.cleared'; -} - -/** - * states: staleGuard - * owner: src/features/staleGuard/staleGuardOps.ts - */ -interface StaleGuardRecordedPayload { - _name: 'staleGuard.recorded'; - path: string; - mtimeMs: number; -} - -/** - * states: swarm - * owner: src/features/swarm/swarmOps.ts + * model: swarm · persisted · toEvent + * owner: src/agent/swarm/swarmOps.ts */ interface SwarmModeEnterPayload { _name: 'swarm_mode.enter'; - agentId: string; /** SwarmModeTrigger */ trigger: 'manual' | 'task' | 'tool'; } /** - * states: contextMemory, swarm · blobs: contextMemory - * owner: src/features/swarm/swarmOps.ts + * model: swarm · persisted · toEvent · cross-reducers: contextMemory + * owner: src/agent/swarm/swarmOps.ts */ interface SwarmModeExitPayload { _name: 'swarm_mode.exit'; - agentId: string; } /** - * states: task + * model: task · persisted · toEvent * owner: src/agent/task/taskOps.ts */ interface TaskStartedPayload { _name: 'task.started'; - agentId: string; /** AgentTaskInfo */ info: AgentTaskInfoByKind[AgentTaskKind]; } /** - * states: task + * model: task · persisted · toEvent * owner: src/agent/task/taskOps.ts */ interface TaskTerminatedPayload { _name: 'task.terminated'; - agentId: string; /** AgentTaskInfo */ info: AgentTaskInfoByKind[AgentTaskKind]; outputTail?: string; } /** - * states: task.notificationDelivery - * owner: src/agent/task/taskOps.ts - */ -interface TaskWaitDeliveredPayload { - _name: 'task.waitDelivered'; - agentId: string; - keys: string[]; -} - -/** - * states: (none) + * model: tokenCounting · toEvent * owner: src/agent/tokenCounting/tokenCountingOps.ts */ interface TokenCountingMeasuredPayload { _name: 'token_counting.measured'; - agentId: string; length: number; tokens: number; } /** - * states: (none) + * model: tokenCounting · toEvent * owner: src/agent/tokenCounting/tokenCountingOps.ts */ interface TokenCountingRebasedPayload { _name: 'token_counting.rebased'; - agentId: string; length: number; tokens: number; measured: boolean; } /** - * states: (none) + * model: tokenCounting · toEvent * owner: src/agent/tokenCounting/tokenCountingOps.ts */ interface TokenCountingTruncatedPayload { _name: 'token_counting.truncated'; - agentId: string; length: number; tokens: number; } /** - * states: (none) - * owner: src/agent/tokenCounting/tokenCountingOps.ts - */ -interface TokenCountingTurnRecordedPayload { - _name: 'token_counting.turn_recorded'; - agentId: string; - length: number; - tokens: number; - turnId: number; -} - -/** - * states: userTool + * model: userTool · persisted * owner: src/agent/userTool/userToolOps.ts + * payload type: UserToolRegistration */ interface ToolsRegisterUserToolPayload { _name: 'tools.register_user_tool'; - agentId: string; name: string; description: string; - parameters: UserToolRegistration['parameters']; - disclosure?: UserToolRegistration['disclosure']; + parameters: Record<string, unknown>; + disclosure?: 'inline' | 'deferred'; } /** - * states: profile.activeTools + * model: profile.activeTools · persisted * owner: src/agent/profile/profileOps.ts */ interface ToolsResetActiveToolsPayload { _name: 'tools.reset_active_tools'; - agentId: string; } /** - * states: profile.activeTools + * model: profile.activeTools · persisted * owner: src/agent/profile/profileOps.ts */ interface ToolsSetActiveToolsPayload { _name: 'tools.set_active_tools'; - agentId: string; names: string[]; } /** - * states: userTool + * model: userTool · persisted * owner: src/agent/userTool/userToolOps.ts */ interface ToolsUnregisterUserToolPayload { _name: 'tools.unregister_user_tool'; - agentId: string; name: string; } /** - * states: (none) - * owner: src/features/todo/todoOps.ts + * model: todo · persisted + * owner: src/session/todo/todoOps.ts */ interface ToolsUpdateStorePayload { _name: 'tools.update_store'; - agentId: string; key: string; value: any; } /** - * states: tower, tower.owner - * owner: src/features/tower/towerOps.ts - */ -interface TowerModeEnterPayload { - _name: 'tower_mode.enter'; - agentId: string; - sessionId?: string; -} - -/** - * states: tower, tower.owner - * owner: src/features/tower/towerOps.ts - */ -interface TowerModeExitPayload { - _name: 'tower_mode.exit'; - agentId: string; -} - -/** - * states: turn + * model: turn · persisted · cross-reducers: interruptionReminder * owner: src/agent/loop/turnOps.ts */ interface TurnCancelPayload { _name: 'turn.cancel'; - agentId: string; turnId?: number; target?: 'active' | 'queued'; reason?: 'user_cancelled' | 'aborted'; } /** - * states: turn + * model: turn · persisted * owner: src/agent/loop/turnOps.ts */ interface TurnEndedPayload { _name: 'turn.ended'; - agentId: string; turnId: number; reason: 'completed' | 'cancelled' | 'failed' | 'blocked'; /** KimiErrorPayload */ @@ -784,36 +676,33 @@ interface TurnEndedPayload { } /** - * states: turn + * model: turn · persisted * owner: src/agent/loop/turnOps.ts */ interface TurnPromptPayload { _name: 'turn.prompt'; - agentId: string; input: readonly ContentPart[]; /** PromptOrigin */ origin: 'user' | 'skill_activation' | 'plugin_command' | 'injection' | 'shell_command' | 'compaction_summary' | 'system_trigger' | 'task' | 'cron_job' | 'cron_missed' | 'hook_result' | 'retry'; } /** - * states: turn + * model: turn · persisted * owner: src/agent/loop/turnOps.ts */ interface TurnSteerPayload { _name: 'turn.steer'; - agentId: string; input: readonly ContentPart[]; /** PromptOrigin */ origin: 'user' | 'skill_activation' | 'plugin_command' | 'injection' | 'shell_command' | 'compaction_summary' | 'system_trigger' | 'task' | 'cron_job' | 'cron_missed' | 'hook_result' | 'retry'; } /** - * states: (none) + * model: usage · persisted * owner: src/agent/usage/usageOps.ts */ interface UsageRecordPayload { _name: 'usage.record'; - agentId: string; model: string; /** TokenUsage */ usage: { @@ -851,33 +740,26 @@ interface WirePayloadMap { "llm.tools_snapshot": LlmToolsSnapshotPayload; "mcp.tools_discovered": McpToolsDiscoveredPayload; "permission.record_approval_result": PermissionRecordApprovalResultPayload; + "permission.rules.add": PermissionRulesAddPayload; "permission.set_mode": PermissionSetModePayload; "plan_mode.cancel": PlanModeCancelPayload; "plan_mode.enter": PlanModeEnterPayload; "plan_mode.exit": PlanModeExitPayload; "plan.revision": PlanRevisionPayload; - "plugin.session_start": PluginSessionStartPayload; "profile.bind": ProfileBindPayload; - "prompt.accepted": PromptAcceptedPayload; - "runtime.set_binding": RuntimeSetBindingPayload; - "staleGuard.cleared": StaleGuardClearedPayload; - "staleGuard.recorded": StaleGuardRecordedPayload; + "skill.activate": SkillActivatePayload; "swarm_mode.enter": SwarmModeEnterPayload; "swarm_mode.exit": SwarmModeExitPayload; "task.started": TaskStartedPayload; "task.terminated": TaskTerminatedPayload; - "task.waitDelivered": TaskWaitDeliveredPayload; "token_counting.measured": TokenCountingMeasuredPayload; "token_counting.rebased": TokenCountingRebasedPayload; "token_counting.truncated": TokenCountingTruncatedPayload; - "token_counting.turn_recorded": TokenCountingTurnRecordedPayload; "tools.register_user_tool": ToolsRegisterUserToolPayload; "tools.reset_active_tools": ToolsResetActiveToolsPayload; "tools.set_active_tools": ToolsSetActiveToolsPayload; "tools.unregister_user_tool": ToolsUnregisterUserToolPayload; "tools.update_store": ToolsUpdateStorePayload; - "tower_mode.enter": TowerModeEnterPayload; - "tower_mode.exit": TowerModeExitPayload; "turn.cancel": TurnCancelPayload; "turn.ended": TurnEndedPayload; "turn.prompt": TurnPromptPayload; diff --git a/packages/agent-core-v2/package.json b/packages/agent-core-v2/package.json index 003c43bed..ea85c28ee 100644 --- a/packages/agent-core-v2/package.json +++ b/packages/agent-core-v2/package.json @@ -1,6 +1,6 @@ { "name": "@moonshot-ai/agent-core-v2", - "version": "0.4.1", + "version": "0.3.1", "private": true, "description": "The unified agent engine for Kimi (v2 — DI Scope architecture)", "license": "MIT", @@ -69,7 +69,6 @@ "ajv-formats": "^3.0.1", "chokidar": "^4.0.3", "ignore": "^5.3.2", - "immer": "^11.1.0", "jimp": "^1.6.1", "js-yaml": "^4.1.1", "linkedom": "^0.18.12", @@ -78,13 +77,11 @@ "pathe": "^2.0.3", "picomatch": "^4.0.4", "retry": "0.13.1", - "semver": "^7.7.4", "smol-toml": "^1.6.1", "socks": "^2.8.9", "tar": "^7.5.13", "ulid": "^3.0.1", "undici": "^7.27.1", - "xstate": "^5.32.5", "yauzl": "^3.3.0", "yazl": "^3.3.1", "zod": "^4.3.6" @@ -93,7 +90,6 @@ "@types/js-yaml": "^4.0.9", "@types/picomatch": "^4.0.3", "@types/retry": "0.12.0", - "@types/semver": "^7.7.0", "@types/sinon": "^21.0.1", "@types/tar": "^7.0.87", "@types/yauzl": "^2.10.3", diff --git a/packages/agent-core-v2/scripts/check-import-boundaries.mjs b/packages/agent-core-v2/scripts/check-import-boundaries.mjs index 9d8a5aa9e..5239f29de 100644 --- a/packages/agent-core-v2/scripts/check-import-boundaries.mjs +++ b/packages/agent-core-v2/scripts/check-import-boundaries.mjs @@ -1,4 +1,40 @@ #!/usr/bin/env node +/** + * Import-boundary checker for `agent-core-v2`. + * + * Enforces two rules over `packages/agent-core-v2/src/**` (and the v1-import + * ban over `test/**` too): + * + * 1. **No v1 imports** — v2 must never `import '@moonshot-ai/agent-core'` + * (or any subpath). v2 ports logic; it never depends on v1. + * 2. **Kosong layering** — the `src/kosong/{contract,protocol,provider,model}` + * subtree has strict internal rules: + * - internal order: contract(L0) ← protocol(L1) ← provider/model(L2) + * ← catalog(L3); a lower layer never imports a higher one (so L1 + * protocol never sees L2 — trait contexts carry only `providerId`). + * - peer rule: `model` may import `provider`, never the reverse. + * - purity: `contract` imports no other domain (only `_base` helpers) + * and no external package at all (no SDKs, not even types); + * `protocol` imports only `_base` + `contract` and no wire SDK. + * All pure layers may additionally import the DI vocabulary modules + * in `KOSONG_ALLOWED_VOCABULARY` (`app/scopes`). + * - `provider/bases/` sub-boundary: base implementation files must not + * import the registries (`protocolBase`, `protocolAdapterRegistry`), + * `providerDefinition`, or any `*.contrib.ts` module. The + * registration side lives in `*.contrib.ts` and in each base + * directory's `index.ts` barrel (import = registration); both are + * exempt. + * Kosong directories that do not exist yet are skipped silently (later + * refactor phases add them). + * + * Intra-package relative imports, `#/`-alias imports, and the package's + * self-reference (`@moonshot-ai/agent-core-v2/<path>` → `src/<path>`) are + * resolved against `src/`. Sibling packages (`@moonshot-ai/*` other than v1) + * and third-party imports are out of scope (except for the kosong purity + * bans above). + * + * Run: `node scripts/check-import-boundaries.mjs`. Exits non-zero on violation. + */ import { readFileSync, readdirSync, statSync } from 'node:fs'; import { dirname, join, relative, resolve } from 'node:path'; @@ -12,10 +48,24 @@ const TEST_ROOT = join(PKG_ROOT, 'test'); const V1_PACKAGE = '@moonshot-ai/agent-core'; const SELF_PACKAGE_PREFIX = '@moonshot-ai/agent-core-v2/'; +/** + * Scope directories introduced by the `src/{scope}/{domain}` layout. A path's + * first segment is a scope tier, not a domain; the domain is the next segment. + */ const SCOPE_DIRS = new Set(['app', 'workspace', 'session', 'agent', 'persistence', 'os', 'kosong']); +/** + * Two-level scope directories: `persistence` and `os` use `{scope}/{tier}` + * (e.g. `persistence/interface`, `os/backends`) as the domain key; `kosong` + * uses `{scope}/{layer}` (e.g. `kosong/contract`) the same way. + */ const TWO_LEVEL_SCOPES = new Set(['persistence', 'os', 'kosong']); +/** + * Kosong-internal layer order: contract ← protocol ← provider/model. + * A lower layer never imports a higher one; `model` → `provider` + * is the only allowed peer edge. Keyed by the segment under `src/kosong/`. + */ const KOSONG_LAYER = new Map([ ['contract', 0], ['protocol', 1], @@ -23,12 +73,40 @@ const KOSONG_LAYER = new Map([ ['model', 2], ]); +/** + * Kosong is a pure provider/model abstraction layer: NO kosong subdomain may + * import another v2 domain outside kosong itself — only `_base` utilities + * are allowed, plus the DI vocabulary modules in + * `KOSONG_ALLOWED_VOCABULARY` (`app/scopes`: the `LifecycleScope` tier names + * every self-registering Service needs). (`protocol` additionally sees + * `kosong/contract`, handled by the internal-layer rule above.) Config + * persistence, OAuth tokens, events, + * and discovery orchestration all live in the upper `app/kosongConfig` + * wrapper — kosong must never reach up to them. + */ const KOSONG_BASE_ONLY_SUBDOMAINS = new Set(['contract', 'protocol', 'provider', 'model']); +/** + * Non-`_base` modules the pure kosong layers may still import, keyed by + * extensionless `src/`-relative path. `app/scopes` is DI vocabulary (the + * scope tier names + topology declaration), not app orchestration, so a + * kosong Service may read its registration tier from it. + */ const KOSONG_ALLOWED_VOCABULARY = new Set(['app/scopes']); +/** + * Wire SDK packages the pure kosong layers must never import — not even + * types. `contract` in fact imports no external package at all; this list + * covers the SDK ban for `protocol`. + */ const KOSONG_BANNED_SDK_PACKAGES = ['@anthropic-ai/sdk', '@google/genai', 'openai']; +/** + * Parse an absolute path under `src/kosong/` into its subdomain info. + * Returns `undefined` for paths outside `src/kosong/`. + * @param {string} absPath + * @returns {{ sub: string | undefined, inBases: boolean, isContrib: boolean, isIndex: boolean } | undefined} + */ function kosongInfoOf(absPath) { const rel = relative(SRC_ROOT, absPath); if (rel.startsWith('..') || rel === '') return undefined; @@ -37,6 +115,7 @@ function kosongInfoOf(absPath) { const sub = segments[1]; const last = segments[segments.length - 1] ?? ''; return { + // A file directly under `src/kosong/` has no subdomain. sub: sub === undefined || sub.endsWith('.ts') ? undefined : sub, inBases: sub === 'provider' && segments[2] === 'bases', isContrib: last.endsWith('.contrib.ts'), @@ -44,6 +123,16 @@ function kosongInfoOf(absPath) { }; } +/** + * Whether an import target is off-limits to base implementation files under + * `kosong/provider/bases/` (everything except `*.contrib.ts` and the + * registration `index.ts` barrels): the base registry + * (`kosong/protocol/protocolBase`), the adapter registry + * (`kosong/provider/protocolAdapterRegistry`), the provider-definition + * registry (`kosong/provider/providerDefinition`), or any contrib + * side-effect module. Matches extensionless specifiers too. + * @param {string} targetAbs + */ function isKosongBasesBannedTarget(targetAbs) { const rel = relative(SRC_ROOT, targetAbs).split(/[\\/]/).join('/'); const stripped = rel.endsWith('.ts') ? rel.slice(0, -'.ts'.length) : rel; @@ -55,13 +144,21 @@ function isKosongBasesBannedTarget(targetAbs) { ); } +/** + * Resolve a `src/`-relative path to its domain, skipping the scope tier when + * present. Returns `undefined` for top-level root files (e.g. the package + * barrel `index.ts`, or the `errors`/`hooks` facades). + * @param {string} rel + */ function domainFromRel(rel) { const segments = rel.split(/[\\/]/); if (TWO_LEVEL_SCOPES.has(segments[0])) { + // `src/{persistence|os}/{interface|backends}/…` return segments[1] ? `${segments[0]}/${segments[1]}` : segments[0]; } if (SCOPE_DIRS.has(segments[0])) { if (segments.length === 2 && segments[1]?.endsWith('.ts')) return segments[0]; + // `src/{scope}/{domain}/…` if (segments[0] === 'agent' && segments[1] === 'task') return 'agentTask'; if (segments[0] === 'agent' && segments[1] === 'plugin') return 'agentPlugin'; return segments[1]; @@ -69,16 +166,30 @@ function domainFromRel(rel) { return segments[0]; } +/** + * Determine the v2 domain for an *import target* absolute path. A target may + * resolve straight to a domain directory — e.g. the bare domain import + * `#/turn` resolves to `src/agent/turn`, whose domain is `turn`. + * @param {string} targetAbs + */ function targetDomainOf(targetAbs) { const rel = relative(SRC_ROOT, targetAbs); if (rel.startsWith('..') || rel === '') return undefined; return domainFromRel(rel); } +/** + * Resolve an import specifier to an absolute v2 `src/` path, or `undefined` + * when the specifier is not an intra-v2 import. + * @param {string} specifier + * @param {string} fromFile absolute path of the importing file + */ function resolveIntraV2(specifier, fromFile) { if (specifier.startsWith('#/')) { return join(SRC_ROOT, specifier.slice(2)); } + // The package's legal self-reference: `@moonshot-ai/agent-core-v2/x` maps + // to `src/x` via the `./*` export. if (specifier.startsWith(SELF_PACKAGE_PREFIX)) { return join(SRC_ROOT, specifier.slice(SELF_PACKAGE_PREFIX.length)); } @@ -88,9 +199,22 @@ function resolveIntraV2(specifier, fromFile) { return undefined; } +// Matches: import ... from 'x' | export ... from 'x' | import('x') | require('x') const IMPORT_RE = /(?:import|export)\s+(?:type\s+)?(?:[^'";]*?\s+from\s+)?['"]([^'"]+)['"]|(?:import|require)\s*\(\s*['"]([^'"]+)['"]\s*\)/g; +/** + * @typedef {{ file: string, line: number, message: string }} Violation + */ + +/** + * Check source text for boundary violations. `absFile` is used only to + * resolve relative specifiers and determine the source location; the file + * need not exist on disk (handy for tests). + * @param {string} source + * @param {string} absFile + * @returns {Violation[]} + */ export function checkSource(source, absFile) { const violations = []; const inSrc = !relative(SRC_ROOT, absFile).startsWith('..'); @@ -102,6 +226,7 @@ export function checkSource(source, absFile) { if (!specifier) continue; const line = source.slice(0, match.index).split('\n').length; + // Rule 1: v2 must not import v1. if (specifier === V1_PACKAGE || specifier.startsWith(`${V1_PACKAGE}/`)) { violations.push({ file: absFile, @@ -111,11 +236,15 @@ export function checkSource(source, absFile) { continue; } + // Rule 2: kosong subtree (production code only). if (!inSrc) continue; const targetAbs = resolveIntraV2(specifier, absFile); const sourceKosong = kosongInfoOf(absFile); if (sourceKosong === undefined) continue; + // Rule 2a: kosong purity bans on external packages. The L0 contract + // imports no external package at all (no SDKs, not even types); the L1 + // protocol layer is SDK-free but may use general-purpose packages. if (targetAbs === undefined) { if (sourceKosong.sub === 'contract') { violations.push({ @@ -138,6 +267,9 @@ export function checkSource(source, absFile) { continue; } + // Rule 2b: kosong-internal layering. Runs even for same-domain imports + // because the provider/bases sub-boundary also bans same-domain targets + // (registries and contrib modules live beside the bases). const targetKosong = kosongInfoOf(targetAbs); if (targetKosong !== undefined) { const sourceKosongLayer = KOSONG_LAYER.get(sourceKosong.sub); @@ -172,6 +304,11 @@ export function checkSource(source, absFile) { continue; } + // Rule 2c: outside the kosong subtree, kosong code may only depend on + // `_base` utilities plus the DI vocabulary in KOSONG_ALLOWED_VOCABULARY + // (`protocol` additionally sees `kosong/contract`, + // handled by Rule 2b above). This is what keeps kosong a pure + // abstraction layer with no upward dependencies. if (KOSONG_BASE_ONLY_SUBDOMAINS.has(sourceKosong.sub)) { const targetDomain = targetDomainOf(targetAbs); const targetRel = relative(SRC_ROOT, targetAbs).split(/[\\/]/).join('/'); @@ -189,11 +326,17 @@ export function checkSource(source, absFile) { return violations; } +/** + * Check a single source file for boundary violations. + * @param {string} absFile + * @returns {Violation[]} + */ export function checkFile(absFile) { return checkSource(readFileSync(absFile, 'utf8'), absFile); } function walk(dir) { + /** @type {string[]} */ const out = []; for (const entry of readdirSync(dir)) { if (entry === 'node_modules' || entry === 'dist') continue; diff --git a/packages/agent-core-v2/scripts/debarrel.mjs b/packages/agent-core-v2/scripts/debarrel.mjs index 84715e0fd..a95bc56b7 100644 --- a/packages/agent-core-v2/scripts/debarrel.mjs +++ b/packages/agent-core-v2/scripts/debarrel.mjs @@ -1,4 +1,20 @@ #!/usr/bin/env node +/** + * debarrel.mjs — agent-core-v2 barrel removal tool (ts-morph). + * + * Rewrites `#/<dir>` barrel imports/exports to precise leaf-file specifiers and + * regenerates the package entry `src/index.ts` so it loads every domain leaf + * (triggering all top-level `register*` side effects) without domain barrels. + * + * Modes: + * (default) rewrite all consumer files (src + test) EXCEPT src/index.ts + * --only=<reldir> limit consumer rewriting to one barrel, e.g. app/event + * --entry regenerate src/index.ts only (no consumer rewriting) + * --delete-barrels delete every domain barrel (per-domain src index.ts except entry) + * --list-registers print the top-level register* files (coverage set) + * --verify-coverage exit non-zero if any register file is unreachable from entry + * --dry-run report planned edits without writing + */ import { Project } from 'ts-morph'; import path from 'node:path'; import fs from 'node:fs'; @@ -34,6 +50,8 @@ const barrelOfDecl = (decl) => { return sf && isBarrelFile(sf) ? sf : null; }; +// Resolve a name exported by `barrel` to the leaf file that declares it and the +// name that leaf uses to export it (handles `export { A as B }` at barrel level). function resolveName(barrel, name) { const decls = barrel.getExportedDeclarations().get(name); if (!decls || decls.length === 0) return null; @@ -51,6 +69,8 @@ function resolveName(barrel, name) { return { leafFile: leaf.getFilePath(), leafName }; } +// Ordered re-export clauses of a barrel (recursively inlines nested barrels), +// preserving source order so `export *` collision resolution is unchanged. function expandBarrelClauses(barrel) { const clauses = []; for (const ed of barrel.getExportDeclarations()) { @@ -101,9 +121,13 @@ function allLeavesUnderDir(dirAbs) { return out.sort((a, b) => a.localeCompare(b)); } +// --------------------------------------------------------------------------- +// Consumer rewriting (imports + named exports + export *) for a single file. +// --------------------------------------------------------------------------- function rewriteConsumerFile(sf, onlyBarrelPath) { const report = { imports: 0, exports: 0, manuals: [], sideEffects: 0 }; + // Imports. for (const decl of sf.getImportDeclarations()) { const barrel = barrelOfDecl(decl); if (!barrel) continue; @@ -116,6 +140,7 @@ function rewriteConsumerFile(sf, onlyBarrelPath) { const hasDefault = !!decl.getDefaultImport(); const named = decl.getNamedImports(); if (!hasDefault && named.length === 0) { + // side-effect: import '#/B' -> load each leaf of B. const leaves = [...new Set(expandBarrelClauses(barrel).map((c) => c.file))]; const idx = sf.getImportDeclarations().indexOf(decl); sf.insertImportDeclarations( @@ -129,7 +154,7 @@ function rewriteConsumerFile(sf, onlyBarrelPath) { } const declType = decl.isTypeOnly(); - const groups = new Map(); + const groups = new Map(); // leafFile -> [{name, alias, isTypeOnly}] const add = (leaf, spec) => { if (!groups.has(leaf)) groups.set(leaf, []); groups.get(leaf).push(spec); @@ -141,7 +166,7 @@ function rewriteConsumerFile(sf, onlyBarrelPath) { else add(r.leafFile, { default: decl.getDefaultImport().getText() }); } for (const s of named) { - const lookup = s.getName(); + const lookup = s.getName(); // module-exported name const local = s.getAliasNode()?.getText() || s.getName(); const r = resolveName(barrel, lookup); if (!r) { @@ -161,6 +186,7 @@ function rewriteConsumerFile(sf, onlyBarrelPath) { report.imports++; } + // Exports. for (const decl of sf.getExportDeclarations()) { const barrel = barrelOfDecl(decl); if (!barrel) continue; @@ -177,10 +203,11 @@ function rewriteConsumerFile(sf, onlyBarrelPath) { report.manuals.push({ sf: sf.getFilePath(), text: decl.getText(), why: 'namespace export' }); continue; } + // named re-export const declType = decl.isTypeOnly(); const groups = new Map(); for (const s of decl.getNamedExports()) { - const lookup = s.getName(); + const lookup = s.getName(); // name the consumer re-exports (= barrel's exported name) const exportedAs = s.getAliasNode()?.getText() || s.getName(); const r = resolveName(barrel, lookup); if (!r) { @@ -246,12 +273,17 @@ function exportClauseToText(c) { return renderNamedExport(relSpec(c.file), c.specs, c.isTypeOnly); } +// --------------------------------------------------------------------------- +// Entry (src/index.ts) regeneration. +// --------------------------------------------------------------------------- function regenerateEntry() { const entrySf = project.getSourceFileOrThrow(ENTRY); const original = entrySf.getFullText(); const headerMatch = original.match(/^\s*\/\*\*[\s\S]*?\*\//); const header = headerMatch ? headerMatch[0] : '/** agent-core-v2 public surface. */'; + // First pass: classify each referenced barrel and how it is referenced. + /** @type {Array<{decl: any, barrel: any, mode: 'star'|'named'|'side'}>} */ const refs = []; for (const decl of [...entrySf.getExportDeclarations(), ...entrySf.getImportDeclarations()]) { const barrel = barrelOfDecl(decl); @@ -277,6 +309,7 @@ function regenerateEntry() { const starLeaves = new Set(clauses.filter((c) => c.kind === 'star').map((c) => c.file)); if (mode === 'star') { + // Public: replay the barrel's clauses in order against precise leaves. for (const c of clauses) publicLines.push(exportClauseToText(c)); } else if (mode === 'named') { const declType = decl.isTypeOnly(); @@ -300,9 +333,11 @@ function regenerateEntry() { publicLines.push(renderNamedExport(relSpec(leaf), specs, allType)); } } + // Loading: any leaf of this domain not already pulled in by an `export *` + // line must be imported for its side effects (registers). for (const leaf of allLeaves) { const key = leaf; - if (starLeaves.has(leaf)) continue; + if (starLeaves.has(leaf)) continue; // loaded by export * if (processed.has(key)) continue; processed.add(key); loadingLines.push(`import '${relSpec(leaf)}';`); @@ -325,6 +360,9 @@ function regenerateEntry() { return { publicLines: publicLines.length, loadingLines: loadingLines.length }; } +// --------------------------------------------------------------------------- +// Register-file enumeration + coverage verification. +// --------------------------------------------------------------------------- const REGISTER_NAMES = new Set([ 'registerScopedService', 'registerAgentToolService', @@ -381,7 +419,7 @@ function reachedFromEntry() { if (!isUnderSrc(f)) return; const edges = [...sf.getImportDeclarations(), ...sf.getExportDeclarations()]; for (const d of edges) { - if (d.isTypeOnly && d.isTypeOnly()) continue; + if (d.isTypeOnly && d.isTypeOnly()) continue; // type-only edges don't execute const t = resolvedFile(d); if (t && isUnderSrc(t.getFilePath())) visit(t); } @@ -414,6 +452,9 @@ function deleteBarrels() { return n; } +// --------------------------------------------------------------------------- +// Main dispatch. +// --------------------------------------------------------------------------- function main() { if (LIST_REGS) { for (const f of findRegisterFiles()) console.log(path.relative(PKG, f)); @@ -442,7 +483,7 @@ function main() { for (const sf of project.getSourceFiles()) { const f = sf.getFilePath(); if (!isUnderSrc(f) && !f.startsWith(path.join(PKG, 'test') + path.sep)) continue; - if (f === ENTRY) continue; + if (f === ENTRY) continue; // entry handled by --entry const before = sf.getFullText(); const r = rewriteConsumerFile(sf, onlyBarrelPath); if (sf.getFullText() !== before) { diff --git a/packages/agent-core-v2/scripts/gen-config-manifest.mts b/packages/agent-core-v2/scripts/gen-config-manifest.mts index 411c5b5df..5853bce21 100644 --- a/packages/agent-core-v2/scripts/gen-config-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-config-manifest.mts @@ -1,3 +1,26 @@ +/** + * Generates `docs/config-manifest.toml` — the single place to see every config + * section registered via `registerConfigSection(...)` plus every effective + * overlay registered via `registerConfigOverlay(...)`. + * + * Two passes: + * 1. Static scan of `src/**` maps each registered section domain (and each + * overlay) to the source file that registers it — the "owner". + * 2. Runtime pass imports `src/index.ts` ("import = register") and drains the + * module-level contributions, capturing defaults, env bindings, and the + * registered hooks exactly as the running process sees them. + * + * The output is TOML in the on-disk shape (snake_case keys): one `[table]` per + * section, uncommented assignments for registered defaults, and commented + * `# field: type` lines for the remaining schema fields. + * + * Usage: + * pnpm --filter @moonshot-ai/agent-core-v2 gen:config-manifest # write the file + * pnpm --filter @moonshot-ai/agent-core-v2 gen:config-manifest --check # freshness check (CI-style) + * + * Freshness is also enforced by `test/app/config/configManifest.test.ts`. + */ + import { readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; import { join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; @@ -21,6 +44,10 @@ const PKG = join(import.meta.dirname, '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'config-manifest.toml'); +// --------------------------------------------------------------------------- +// Static pass — domain/overlay → owner file +// --------------------------------------------------------------------------- + function walk(dir: string, out: string[] = []): string[] { for (const entry of readdirSync(dir)) { const p = join(dir, entry); @@ -35,6 +62,7 @@ function constStringValue(source: string, ident: string): string | undefined { return re.exec(source)?.[1]; } +/** domain key → owner file (relative to the package root). */ function scanSectionOwners(): Map<string, string> { const owners = new Map<string, string>(); for (const file of walk(SRC)) { @@ -49,9 +77,12 @@ function scanSectionOwners(): Map<string, string> { return owners; } +/** overlay variable name → owner file (relative to the package root). */ function scanOverlayOwners(): Map<string, string> { const owners = new Map<string, string>(); for (const file of walk(SRC)) { + // Skip the collector module itself — its `registerConfigOverlay(overlay)` + // function signature is not a registration. if (file.endsWith('configOverlayContributions.ts')) continue; const source = readFileSync(file, 'utf-8'); if (!source.includes('registerConfigOverlay(')) continue; @@ -63,6 +94,11 @@ function scanOverlayOwners(): Map<string, string> { return owners; } +// --------------------------------------------------------------------------- +// TOML-like rendering helpers +// --------------------------------------------------------------------------- + +/** Serialize a small JSON value as an inline TOML value. */ function toTomlValue(value: unknown): string { if (typeof value === 'string') return JSON.stringify(value); if (typeof value === 'number' || typeof value === 'boolean') return String(value); @@ -80,6 +116,7 @@ interface EnvRow { readonly detail: string; } +/** Property access shape of an `EnvBinding` object (avoids index-signature access). */ interface EnvBindingFields { readonly env?: unknown; readonly deprecatedEnv?: unknown; @@ -111,6 +148,11 @@ function snakePath(field: string): string { const RULE = `# ${'#'.repeat(74)}`; +// --------------------------------------------------------------------------- +// Section rendering +// --------------------------------------------------------------------------- + +/** `# field: type (default: x)` comment lines for an object schema's properties. */ function renderFieldComments( properties: Record<string, unknown>, root: JsonSchema, @@ -123,6 +165,8 @@ function renderFieldComments( const propDefault = asJsonSchema(resolved)?.default; const defNote = propDefault !== undefined ? ` (default: ${JSON.stringify(propDefault)})` : ''; lines.push(`${indent}# ${camelToSnake(name)}: ${describeType(resolved)}${defNote}`); + // Expand nested object fields one level at a time (depth-capped so a + // recursive $ref cannot loop). const subProps = asJsonSchema(resolved)?.properties; if (depth < 3 && isRecord(subProps) && Object.keys(subProps).length > 0) { lines.push(...renderFieldComments(subProps, root, `${indent} `, depth + 1)); @@ -137,6 +181,7 @@ function renderBody(section: ConfigSectionContribution): string[] { const jsonSchema = schema === undefined ? undefined : toJsonSchema(schema); if (jsonSchema === undefined) { + // No schema (passthrough) or a schema that JSON Schema cannot represent. if (isRecord(options.defaultValue)) { return [ `[${key}]`, @@ -152,6 +197,7 @@ function renderBody(section: ConfigSectionContribution): string[] { return [`[${key}]`, `# (${schema === undefined ? 'no schema — passthrough' : 'schema uses transforms; see the owner file'})`]; } + // Object with named fields. if (isRecord(jsonSchema.properties) && Object.keys(jsonSchema.properties).length > 0) { const defaults = isRecord(options.defaultValue) ? options.defaultValue : {}; const lines = [`[${key}]`]; @@ -161,6 +207,8 @@ function renderBody(section: ConfigSectionContribution): string[] { lines.push(`${fieldKey} = ${truncate(toTomlValue(defaults[name]))}`); continue; } + // A nested object field is an on-disk sub-table (`[section.field]`) — + // render its own fields instead of a flat `field: object` comment. const resolved = resolveRef(prop, jsonSchema); const subProps = asJsonSchema(resolved)?.properties; if (isRecord(subProps) && Object.keys(subProps).length > 0) { @@ -169,6 +217,7 @@ function renderBody(section: ConfigSectionContribution): string[] { lines.push(...renderFieldComments(subProps, jsonSchema, ' ')); continue; } + // An array-of-objects field carries its element fields inline. const itemProps = asJsonSchema( resolveRef(asJsonSchema(resolved)?.items, jsonSchema), )?.properties; @@ -182,6 +231,7 @@ function renderBody(section: ConfigSectionContribution): string[] { return lines; } + // Record section — one sub-table per entry. if (jsonSchema.additionalProperties !== undefined) { const valueSchema = resolveRef(jsonSchema.additionalProperties, jsonSchema); const valueProps = asJsonSchema(valueSchema)?.properties; @@ -197,6 +247,10 @@ function renderBody(section: ConfigSectionContribution): string[] { return lines; } + // Array-of-tables section — one `[[section]]` entry per element. There is + // no `[section]` parent table in TOML, so the whole shape stays commented; + // emitting a bare `[${key}]` header would parse as a plain table, which + // array sections (e.g. `hooks`) reject on load. if (jsonSchema.type === 'array') { const itemProps = asJsonSchema(resolveRef(jsonSchema.items, jsonSchema))?.properties; if (isRecord(itemProps) && Object.keys(itemProps).length > 0) { @@ -208,6 +262,7 @@ function renderBody(section: ConfigSectionContribution): string[] { } } + // Scalar / array section — a plain top-level key. if (options.defaultValue !== undefined) { return [`${key} = ${truncate(toTomlValue(options.defaultValue))}`]; } @@ -247,7 +302,12 @@ function renderSection(section: ConfigSectionContribution, owner: string | undef return lines; } +// --------------------------------------------------------------------------- +// Manifest rendering +// --------------------------------------------------------------------------- + export async function buildConfigManifest(): Promise<string> { + // "import = register": loading the package root fills the contribution bags. await import('../src/index.ts'); const sections = getConfigSectionContributions().toSorted((a, b) => a.domain.localeCompare(b.domain), @@ -285,6 +345,10 @@ export async function buildConfigManifest(): Promise<string> { return out.join('\n'); } +// --------------------------------------------------------------------------- +// CLI +// --------------------------------------------------------------------------- + async function main(): Promise<void> { const check = process.argv.includes('--check'); const manifest = await buildConfigManifest(); diff --git a/packages/agent-core-v2/scripts/gen-contract-types.mjs b/packages/agent-core-v2/scripts/gen-contract-types.mjs index c9a631ad9..2cd8307b0 100644 --- a/packages/agent-core-v2/scripts/gen-contract-types.mjs +++ b/packages/agent-core-v2/scripts/gen-contract-types.mjs @@ -1,3 +1,22 @@ +/** + * Generates a black-box "contract" declaration tree for agent-core-v2. + * + * The output mirrors `src/` but with every registered service IMPLEMENTATION + * class removed, leaving only the contract surface: interfaces, types, models, + * error domains, factory functions, the `ServiceIdentifier` accessors, and the + * DI primitives. Consumers (kimi-code-mini-bench) type-check against this tree + * so tests cannot import an impl class, while at runtime the real linked + * package still binds the real implementations. + * + * Pipeline: + * 1. `tsc --emitDeclarationOnly` over `src/` into a temp dir. + * 2. Detect impl files = source files containing a top-level + * `registerScopedService(...)` call; the 3rd argument is the impl class. + * 3. In each impl file's emitted `.d.ts`, drop the registered class + * declaration(s) and keep everything else. + * 4. Copy the scrubbed tree to the output directory. + */ + import { execFileSync } from 'node:child_process'; import { cpSync, @@ -15,7 +34,7 @@ import { createRequire } from 'node:module'; import { Project, SyntaxKind } from 'ts-morph'; const __dirname = dirname(fileURLToPath(import.meta.url)); -const PKG = join(__dirname, '..'); +const PKG = join(__dirname, '..'); // packages/agent-core-v2 const SRC = join(PKG, 'src'); const TMP = join(PKG, '.contract-types-tmp'); const TSCONFIG = join(PKG, 'tsconfig.contract.json'); @@ -40,9 +59,13 @@ function walk(dir, out) { } } +// 1. Emit declarations for the whole src tree. rmSync(TMP, { recursive: true, force: true }); mkdirSync(TMP, { recursive: true }); log(`emitting declarations via tsc -> ${relative(PKG, TMP)}`); +// tsc exits non-zero on the repo's pre-existing type errors (WIP port), but +// still emits `.d.ts` for every file when `noEmitOnError` is off. We only need +// the declarations, so tolerate a non-zero exit and continue. try { execFileSync(process.execPath, [tscBin, '-p', TSCONFIG, '--outDir', TMP], { cwd: PKG, @@ -53,10 +76,12 @@ try { log(`tsc exited ${String(code)} (non-fatal; declarations are still emitted)`); } +// 2. Detect impl files + registered class names (AST only). log('scanning for registerScopedService(...) bindings'); const project = new Project(); project.addSourceFilesAtPaths(join(SRC, '**', '*.ts')); +/** @type {Map<string, Set<string>>} dtsPath -> class names to drop */ const dropByDts = new Map(); const implFiles = []; @@ -72,6 +97,7 @@ for (const sf of project.getSourceFiles()) { const args = call.getArguments(); if (args.length < 3) continue; const text = args[2].getText().trim(); + // Only treat a bare identifier as a class name; otherwise signal "drop all". names.add(/^[A-Za-z_$][\w$]*$/.test(text) ? text : '*'); } @@ -84,6 +110,7 @@ for (const sf of project.getSourceFiles()) { log(`found ${implFiles.length} impl files`); +// 3. Scrub registered classes from each impl .d.ts. let scrubbedFiles = 0; let scrubbedClasses = 0; for (const [dtsPath, names] of dropByDts) { @@ -107,52 +134,19 @@ for (const [dtsPath, names] of dropByDts) { } log(`scrubbed ${scrubbedClasses} impl class(es) across ${scrubbedFiles} file(s)`); -function resolveReexportTarget(dtsPath, spec) { - const clean = spec.endsWith('.js') ? spec.slice(0, -'.js'.length) : spec; - if (clean.startsWith('.')) return join(dirname(dtsPath), `${clean}.d.ts`); - if (clean.startsWith('#/')) return join(TMP, `${clean.slice(2)}.d.ts`); - return undefined; -} - -let scrubbedReexports = 0; -const emittedDts = []; -walk(TMP, emittedDts); -const reexportProject = new Project(); -for (const dtsPath of emittedDts) { - if (!dtsPath.endsWith('.d.ts')) continue; - const dts = reexportProject.addSourceFileAtPath(dtsPath); - let changed = false; - for (const exp of dts.getExportDeclarations()) { - const spec = exp.getModuleSpecifierValue(); - if (spec === undefined) continue; - const target = resolveReexportTarget(dtsPath, spec); - const names = target === undefined ? undefined : dropByDts.get(target); - if (names === undefined) continue; - let removedHere = false; - for (const specifier of exp.getNamedExports()) { - const name = specifier.getNameNode().getText(); - if (names.has('*') || names.has(name)) { - specifier.remove(); - removedHere = true; - scrubbedReexports++; - } - } - if (removedHere && exp.getNamedExports().length === 0) exp.remove(); - changed = changed || removedHere; - } - if (changed) dts.saveSync(); -} -log(`scrubbed ${scrubbedReexports} re-export(s) of impl classes from alias modules`); - +// 4. Copy the scrubbed tree to the output directory. rmSync(OUT, { recursive: true, force: true }); mkdirSync(dirname(OUT), { recursive: true }); cpSync(TMP, OUT, { recursive: true }); +// Sanity summary: report emitted files + a quick leak check (any impl class +// name still declared in its own file). const emitted = []; walk(OUT, emitted); const dtsCount = emitted.filter((f) => f.endsWith('.d.ts')).length; log(`wrote ${dtsCount} declaration file(s) -> ${OUT}`); +// Verify no registered class name survives in the file that registered it. const leaks = []; for (const [dtsPath, names] of dropByDts) { const outPath = join(OUT, relative(TMP, dtsPath)); diff --git a/packages/agent-core-v2/scripts/gen-state-manifest.mts b/packages/agent-core-v2/scripts/gen-state-manifest.mts index 1a0cc7be9..b4e8d7acc 100644 --- a/packages/agent-core-v2/scripts/gen-state-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-state-manifest.mts @@ -1,9 +1,44 @@ +/** + * Generates `docs/state-manifest.d.ts` — the single place to see every state + * key registered into the four scoped state services (App-scope + * `IAppStateService`, Workspace-scope `IWorkspaceStateService`, Session-scope + * `ISessionStateService`, Agent-scope `IAgentStateService`). + * + * Pure static pass (state keys are registered inside DI scope constructors, so + * there is no process-level registry to drain the way `gen-wire-manifest` + * does): + * 1. A ts-morph scan of `src/{app,workspace,session,agent,features}/**` + * collects every top-level `defineState('name', ...)` key constant. + * 2. Every `.register(key)` call site resolves its argument back to a key + * constant (following imports); the key joins the scope of the + * registering file (`src/app/**` → App, `src/workspace/**` → Workspace, + * `src/session/**` → Session, `src/agent/**` → Agent). Files under + * `src/features/**` register into whichever scope their services are + * materialized in, so the scope is resolved from the register-call + * receiver's type (`IAgentStateService` → Agent, …). + * A key that is defined but never registered is excluded. + * + * The output is a self-contained `.d.ts`: each key's value type is the + * compile-time `StateKey<T>` parameter, expanded fully inline through the type + * checker — no imports and no helper declarations. Every named type is marked + * at its expansion site with an inline `TypeName — source/file.ts` comment; + * recursion stops with a `TypeName — recursive` marker on an `unknown`. Generic + * instantiations are expanded structurally and classes render as their public + * instance shape; only lib globals (`Map`/`Set`/…) and a few noted external + * ambient types keep their names. + * + * Usage: + * pnpm --filter @moonshot-ai/agent-core-v2 gen:state-manifest # write the file + * pnpm --filter @moonshot-ai/agent-core-v2 gen:state-manifest --check # freshness check (CI-style) + * + * Freshness is also enforced by `test/state/stateManifest.test.ts`. + */ + import { readFileSync, writeFileSync } from 'node:fs'; import { join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; import { - type CallExpression, Node, Project, SyntaxKind, @@ -23,6 +58,7 @@ const REPO_ROOT = join(PKG, '..', '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'state-manifest.d.ts'); +/** src first-level directory → manifest section. */ const SCOPES = [ { dir: 'app', @@ -55,14 +91,10 @@ type ScopeDir = (typeof SCOPES)[number]['dir']; interface KeyDef { readonly constName: string; readonly keyName: string; + /** Absolute path of the file defining the key constant. */ readonly file: string; readonly exported: boolean; readonly declaration: VariableDeclaration; - readonly replayable?: { - readonly durable: boolean; - readonly undoable: boolean; - readonly folds: readonly string[]; - }; } interface Registration { @@ -72,6 +104,7 @@ interface Registration { interface StateManifestModel { readonly registrations: readonly Registration[]; + /** Keys defined under the scope dirs but never registered (dead candidates). */ readonly unregistered: readonly KeyDef[]; } @@ -84,6 +117,7 @@ function isFeaturesFile(file: string): boolean { return relative(SRC, file).split(/[\\/]/)[0] === 'features'; } +/** Feature files register into the scope of their materialized services — resolve it from the register-call receiver's state-service type. */ const FEATURES_RECEIVER_SCOPE: Readonly<Record<string, ScopeDir>> = { IAppStateService: 'app', IWorkspaceStateService: 'workspace', @@ -91,20 +125,13 @@ const FEATURES_RECEIVER_SCOPE: Readonly<Record<string, ScopeDir>> = { IAgentStateService: 'agent', }; -function receiverScope( - expression: PropertyAccessExpression, - checker: TypeChecker, -): ScopeDir | undefined { - const typeName = checker.getTypeAtLocation(expression.getExpression()).getSymbol()?.getName(); - return typeName === undefined ? undefined : FEATURES_RECEIVER_SCOPE[typeName]; -} - function featuresRegisterScope( expression: PropertyAccessExpression, checker: TypeChecker, sf: SourceFile, ): ScopeDir { - const scope = receiverScope(expression, checker); + const typeName = checker.getTypeAtLocation(expression.getExpression()).getSymbol()?.getName(); + const scope = typeName === undefined ? undefined : FEATURES_RECEIVER_SCOPE[typeName]; if (scope === undefined) { throw new Error( `[gen-state-manifest] cannot resolve the state-service scope of '${expression.getText()}' ` + @@ -115,23 +142,36 @@ function featuresRegisterScope( return scope; } +/** Package-root-relative posix path (used in index/comment columns). */ function srcRelative(file: string): string { return relative(PKG, file).split('\\').join('/'); } +/** Repo-root-relative posix path (used in type-name comments). */ function repoRelative(file: string): string { return relative(REPO_ROOT, file).split('\\').join('/'); } +/** Quote a property key only when it is not a plain identifier. */ function tsFieldKey(key: string): string { return /^[$A-Z_a-z][$\w]*$/.test(key) ? key : JSON.stringify(key); } +/** + * The checker names a `unique symbol` key `__@<declName>@<globalSymbolId>` — + * the numeric id is a compilation-global counter that shifts with unrelated + * edits, so the manifest renders the stable `__@<declName>` form instead. + */ function stableSymbolKey(key: string): string { const match = /^__@(.+)@\d+$/.exec(key); return match === null ? key : `__@${match[1]}`; } +// --------------------------------------------------------------------------- +// Static pass — key constants and their register call sites +// --------------------------------------------------------------------------- + +/** Pass 1 — every top-level `defineState('name', ...)` constant under the scope dirs. */ function collectKeyDefs(project: Project): Map<VariableDeclaration, KeyDef> { const defs = new Map<VariableDeclaration, KeyDef>(); for (const sf of project.getSourceFiles()) { @@ -141,15 +181,15 @@ function collectKeyDefs(project: Project): Map<VariableDeclaration, KeyDef> { for (const declaration of statement.getDeclarations()) { const initializer = declaration.getInitializer(); if (initializer === undefined || !Node.isCallExpression(initializer)) continue; - const parsed = parseDefineStateChain(initializer); - if (parsed === undefined) continue; + if (initializer.getExpression().getText() !== 'defineState') continue; + const [nameArg] = initializer.getArguments(); + if (nameArg === undefined || !Node.isStringLiteral(nameArg)) continue; defs.set(declaration, { constName: declaration.getName(), - keyName: parsed.keyName, + keyName: nameArg.getLiteralValue(), file: sf.getFilePath(), exported: statement.isExported(), declaration, - replayable: parsed.replayable, }); } } @@ -157,49 +197,7 @@ function collectKeyDefs(project: Project): Map<VariableDeclaration, KeyDef> { return defs; } -function parseDefineStateChain( - initializer: CallExpression, -): { keyName: string; replayable?: KeyDef['replayable'] } | undefined { - let durable = true; - let undoable = false; - let replayable = false; - const folds: string[] = []; - let current: CallExpression = initializer; - for (;;) { - const expression = current.getExpression(); - if (Node.isIdentifier(expression) && expression.getText() === 'defineState') { - const [nameArg] = current.getArguments(); - if (nameArg === undefined || !Node.isStringLiteral(nameArg)) return undefined; - return { - keyName: nameArg.getLiteralValue(), - replayable: replayable ? { durable, undoable, folds } : undefined, - }; - } - if (!Node.isPropertyAccessExpression(expression)) return undefined; - const method = expression.getName(); - if (method === 'replayable') { - replayable = true; - const [arg] = current.getArguments(); - if (arg !== undefined && Node.isObjectLiteralExpression(arg)) { - const durableProp = arg.getProperty('durable'); - if (durableProp !== undefined && Node.isPropertyAssignment(durableProp)) { - durable = durableProp.getInitializer()?.getText() !== 'false'; - } - } - } else if (method === 'undoable') { - undoable = true; - } else if (method === 'on') { - const [eventArg] = current.getArguments(); - if (eventArg !== undefined) folds.unshift(eventArg.getText()); - } else { - return undefined; - } - const inner = expression.getExpression(); - if (!Node.isCallExpression(inner)) return undefined; - current = inner; - } -} - +/** Resolve a `.register(...)` argument back to its `defineState` constant. */ function resolveKeyDef( identifier: Identifier, defs: ReadonlyMap<VariableDeclaration, KeyDef>, @@ -214,23 +212,21 @@ function resolveKeyDef( return undefined; } +/** Pass 2 — every `.register(key)` call site whose argument is a state key. */ function collectRegistrations( project: Project, defs: ReadonlyMap<VariableDeclaration, KeyDef>, ): Registration[] { const checker = project.getTypeChecker(); const registrations: Registration[] = []; - const seen = new Map<string, string>(); + const seen = new Set<string>(); for (const sf of project.getSourceFiles()) { const fileScope = scopeDirOf(sf.getFilePath()); const featuresFile = isFeaturesFile(sf.getFilePath()); if (fileScope === undefined && !featuresFile) continue; for (const call of sf.getDescendantsOfKind(SyntaxKind.CallExpression)) { const expression = call.getExpression(); - if ( - !Node.isPropertyAccessExpression(expression) || - expression.getName() !== 'contributeState' - ) { + if (!Node.isPropertyAccessExpression(expression) || expression.getName() !== 'register') { continue; } const args = call.getArguments(); @@ -238,7 +234,7 @@ function collectRegistrations( if (args.length !== 1 || arg === undefined || !Node.isIdentifier(arg)) continue; const def = resolveKeyDef(arg, defs); if (def === undefined) continue; - const scope = receiverScope(expression, checker) ?? fileScope ?? featuresRegisterScope(expression, checker, sf); + const scope = fileScope ?? featuresRegisterScope(expression, checker, sf); if (!def.exported) { throw new Error( `[gen-state-manifest] state key '${def.keyName}' (${srcRelative(def.file)}) is ` + @@ -246,14 +242,12 @@ function collectRegistrations( ); } const dedupe = `${scope}:${def.keyName}`; - const seenFile = seen.get(dedupe); - if (seenFile !== undefined) { - if (seenFile === sf.getFilePath()) continue; + if (seen.has(dedupe)) { throw new Error( `[gen-state-manifest] state key '${def.keyName}' is registered twice in ${scope} scope.`, ); } - seen.set(dedupe, sf.getFilePath()); + seen.add(dedupe); registrations.push({ def, scope }); } } @@ -269,19 +263,36 @@ function createProject(): Project { return project; } +// --------------------------------------------------------------------------- +// Type expansion — render every key's value type fully inline. +// +// Every named type declared in the repo is expanded at the use site and marked +// with a `/* TypeName — source/file.ts */` comment; a recursion point stops +// with a `/* TypeName — recursive (...) */ unknown` marker. Types from lib +// (`Map`, `Set`, `Date`, …) or node_modules are ambient and keep their names +// (type arguments are still rendered recursively). Generic instantiations and +// anonymous shapes are expanded structurally from their apparent members, so +// the checker always hands us substituted, concrete member types. +// --------------------------------------------------------------------------- + const NO_TRUNCATION = ts.TypeFormatFlags.NoTruncation; class TypeRenderer { private readonly checker: ts.TypeChecker; + /** Cycle guard for anonymous / generic-instantiation structural expansion. */ private readonly expanding = new Set<ts.Type>(); + /** Named types currently being expanded along this path (recursion guard). */ private readonly expandingNamed: ts.Symbol[] = []; + /** Ambient names kept as-is whose declaration lives outside the TS lib. */ readonly externals = new Set<string>(); + /** Degradations worth reporting (cycle fallbacks). */ readonly warnings = new Set<string>(); constructor(private readonly project: Project) { this.checker = project.getTypeChecker().compilerObject; } + /** Render the value type `T` of a key's `StateKey<T>`. */ renderKeyType(def: KeyDef): string { const valueType = def.declaration.getType().getTypeArguments()[0]; if (valueType === undefined) { @@ -292,6 +303,8 @@ class TypeRenderer { return this.renderType(valueType, def.declaration, 0); } + // -- core dispatch -------------------------------------------------------- + private renderType( type: MorphType, location: Node, @@ -300,10 +313,12 @@ class TypeRenderer { ): string { if (depth > 40) return this.fallback(type, location, 'depth cap'); + // A single enum-literal type (e.g. `FaultKind.A`) — value + enum comment. if ((type.getFlags() & ts.TypeFlags.EnumLiteral) !== 0) { return this.renderEnumLiteral(type); } + // The boolean union (`false | true`) collapses to `boolean`. if (type.isUnion() && (type.getFlags() & ts.TypeFlags.Boolean) !== 0) return 'boolean'; if (type.isUnion()) { @@ -348,6 +363,11 @@ class TypeRenderer { return this.fallback(type, location, 'unhandled type kind'); } + /** + * Render union members: a `false | true` pair anywhere collapses to + * `boolean`, `null`/`undefined` sort last, duplicates removed, and parens + * are only added when the union actually has multiple members. + */ private renderUnionMembers( members: readonly MorphType[], location: Node, @@ -400,8 +420,10 @@ class TypeRenderer { ); } + /** typeToString is only safe on leaf types (never emits `import(...)`). */ private leafText(type: MorphType): string { const text = this.checker.typeToString(type.compilerType, undefined, NO_TRUNCATION); + // Normalize double-quoted string literals to the repo's single-quote style. if (text.length >= 2 && text.startsWith('"') && text.endsWith('"')) { const value = JSON.parse(text) as string; return value.includes("'") ? JSON.stringify(value) : `'${value}'`; @@ -419,6 +441,9 @@ class TypeRenderer { return text; } + // -- enums ---------------------------------------------------------------- + + /** The literal value of an enum-literal type, quoted TS-style. */ private enumLiteralValue(type: MorphType): string { const value = (type.compilerType as ts.LiteralType).value; if (typeof value === 'string') { @@ -428,6 +453,7 @@ class TypeRenderer { return this.leafText(type); } + /** The enum declaration backing an enum-literal type, if any. */ private enumDeclOf(type: MorphType): Node | undefined { const memberDecl = type.getSymbol()?.getDeclarations()[0]; if (memberDecl === undefined || !Node.isEnumMember(memberDecl)) return undefined; @@ -446,6 +472,7 @@ class TypeRenderer { return text; } + /** Collapse a union covering every member of one enum: comment + values. */ private tryRenderEnumUnion(type: MorphType): string | undefined { const members = type.getUnionTypes(); if (members.length === 0) return undefined; @@ -465,6 +492,13 @@ class TypeRenderer { return `/* ${sym.getName()} — ${repoRelative(enumDecl.getSourceFile().getFilePath())} */ ${values.join(' | ')}`; } + // -- named-type annotation -------------------------------------------------- + + /** + * Where do the symbol's declarations live: repo ('named' — expand inline + * with a name comment), lib/node_modules ('ambient' — keep the name), or + * mixed/anonymous ('inline' — expand without a comment). + */ private classify(sym: MorphSymbol): 'named' | 'ambient' | 'inline' { const decls = sym.getDeclarations(); if (decls.length === 0) return 'inline'; @@ -497,6 +531,10 @@ class TypeRenderer { } } + /** + * `Name — origin` comment prefixed to the expansion. A named type already + * on the expansion path stops with a recursion marker instead. + */ private renderNamed(sym: MorphSymbol, expand: () => string): string { const decl = sym.getDeclarations()[0]; const origin = @@ -515,6 +553,14 @@ class TypeRenderer { } } + /** + * Render a type through the alias it was referenced with, when that alias is + * worth keeping: a repo-declared non-generic alias expands inline under its + * name comment; a lib or node_modules alias (`Readonly`, `Record`, + * `Partial`, …) is referenced as `Name<args>` with recursive arguments. + * `skipSymbol` suppresses the alias's own annotation while its right-hand + * side is being rendered (the alias type still carries itself as aliasSymbol). + */ private tryRenderAlias( type: MorphType, location: Node, @@ -541,6 +587,8 @@ class TypeRenderer { return undefined; } + // -- object types ----------------------------------------------------------- + private renderObjectType( type: MorphType, location: Node, @@ -551,6 +599,8 @@ class TypeRenderer { if (alias !== undefined) return alias; const sym = type.getSymbol(); const typeArgs = type.getTypeArguments(); + // `__type`/`__object` are checker names for anonymous shapes — they are + // never real symbols, so skip the named-type paths and expand structurally. const anonymous = sym === undefined || /^__(type|object)$/.test(sym.getName()); if (!anonymous && sym.compilerSymbol !== skipSymbol) { const kind = this.classify(sym); @@ -568,7 +618,9 @@ class TypeRenderer { return this.renderStructural(type, location, depth); } + /** Structural rendering from the type's apparent members (braced or arrow). */ private renderStructural(type: MorphType, location: Node, depth: number): string { + // Cycle guard for self-referential instantiations expanded inline. if (this.expanding.has(type.compilerType)) { return this.fallback(type, location, 'cycle expanding'); } @@ -599,6 +651,7 @@ class TypeRenderer { } } + /** Member lines of an object type, each indented by two spaces. */ private renderObjectBody( type: MorphType, location: Node, @@ -615,6 +668,7 @@ class TypeRenderer { const at = decl ?? location; const propType = prop.getTypeAtLocation(at); const optional = (prop.getFlags() & ts.SymbolFlags.Optional) !== 0; + // An optional prop's `| undefined` is redundant with the `?` — drop it. const rendered = optional && propType.isUnion() ? this.renderUnionMembers( @@ -696,6 +750,10 @@ class TypeRenderer { } } +// --------------------------------------------------------------------------- +// Manifest rendering +// --------------------------------------------------------------------------- + function renderManifest( model: StateManifestModel, project: Project, @@ -711,6 +769,7 @@ function renderManifest( ); } + // Snapshot interfaces — rendering these fills the external-name registry. const sections: string[] = []; for (const scope of SCOPES) { const regs = byScope.get(scope.dir) ?? []; @@ -727,16 +786,6 @@ function renderManifest( for (const file of [...byFile.keys()].toSorted()) { lines.push(` // ${srcRelative(file)}`); for (const r of byFile.get(file) ?? []) { - if (r.def.replayable !== undefined) { - const meta = r.def.replayable; - const flags = [ - meta.durable ? 'durable' : 'transient', - ...(meta.undoable ? ['undoable'] : []), - ]; - lines.push( - ` // replayable · ${flags.join(' · ')} — folds: ${meta.folds.length > 0 ? meta.folds.join(', ') : '(protocol only)'}`, - ); - } const rendered = renderer.renderKeyType(r.def).split('\n'); rendered[rendered.length - 1] += ';'; lines.push(` '${r.def.keyName}': ${rendered[0]}`, ...rendered.slice(1).map((l) => ` ${l}`)); @@ -761,12 +810,8 @@ function renderManifest( '// Workspace-scope IWorkspaceStateService, the Session-scope', '// ISessionStateService, or the Agent-scope IAgentStateService (see', '// src/_base/state/stateRegistry.ts), collected statically from the', - '// `states.contributeState(...)` call sites and the replayable key chains — a', - '// `defineState(...).replayable(...)` key is contributed into the Agent-scope', - '// service by its owner service at construction, and', - '// carries a `// replayable · durable|transient · undoable? — folds: ...` line.', - '// Replayable values are excluded from snapshot()/inspect(). A key defined via', - '// defineState but never registered nor replayable does not appear here. Each entry shows the', + '// `states.register(...)` call sites — a key defined via', + '// defineState but never registered does not appear here. Each entry shows the', '// compile-time StateKey<T> value type fully expanded inline, so the manifest is', '// self-contained (no imports, no helper declarations). A named type is marked', '// at its expansion site with a `/* TypeName — source/file.ts */` comment; a', @@ -815,23 +860,6 @@ function buildAll(): BuildResult { const defs = collectKeyDefs(project); const registrations = collectRegistrations(project, defs); const registered = new Set(registrations.map((r) => r.def)); - for (const def of defs.values()) { - if (def.replayable === undefined) continue; - if (!registered.has(def)) { - throw new Error( - `[gen-state-manifest] replayable state key '${def.keyName}' (${srcRelative(def.file)}) is ` + - 'never contributed — its owner service must contributeState it into the Agent-scope state service.', - ); - } - for (const registration of registrations) { - if (registration.def === def && registration.scope !== 'agent') { - throw new Error( - `[gen-state-manifest] replayable state key '${def.keyName}' (${srcRelative(def.file)}) is ` + - `contributed into the ${registration.scope} scope — replayable keys belong to the Agent scope.`, - ); - } - } - } const unregistered = [...defs.values()].filter((def) => !registered.has(def)); const model: StateManifestModel = { registrations, unregistered }; const { manifest, warnings } = renderManifest(model, project); @@ -842,6 +870,10 @@ export function buildStateManifest(): string { return buildAll().manifest; } +// --------------------------------------------------------------------------- +// CLI +// --------------------------------------------------------------------------- + function main(): void { const check = process.argv.includes('--check'); const { model, manifest, warnings } = buildAll(); diff --git a/packages/agent-core-v2/scripts/gen-wire-manifest.mts b/packages/agent-core-v2/scripts/gen-wire-manifest.mts index a51b0a7c1..a747a064c 100644 --- a/packages/agent-core-v2/scripts/gen-wire-manifest.mts +++ b/packages/agent-core-v2/scripts/gen-wire-manifest.mts @@ -1,8 +1,33 @@ +/** + * Generates `docs/wire-manifest.d.ts` — the single place to see every wire + * record type registered via `defineOp(...)`. + * + * Two passes: + * 1. Static scan of `src/**` maps each op type to the source file that + * defines it — the "owner" — and collects the migration chain from + * `src/wire/migration/v*.ts`. + * 2. Runtime pass imports `src/index.ts` plus every op module found in the + * static pass ("import = register") and drains `OP_REGISTRY`, capturing + * the owning model, the persist policy, `toEvent`, and the payload schema + * exactly as the running process sees them. + * + * The output is a `.d.ts` — one payload declaration per record type, with a + * `WirePayloadMap` from record type to declaration — using real TypeScript + * type syntax for the sketches. + * + * Usage: + * pnpm --filter @moonshot-ai/agent-core-v2 gen:wire-manifest # write the file + * pnpm --filter @moonshot-ai/agent-core-v2 gen:wire-manifest --check # freshness check (CI-style) + * + * Freshness is also enforced by `test/wire/wireManifest.test.ts`. + */ + import { existsSync, readdirSync, readFileSync, statSync, writeFileSync } from 'node:fs'; import { dirname, join, relative } from 'node:path'; import { pathToFileURL } from 'node:url'; -import { EVENT2_REGISTRY } from '#/app/event/event2'; +import { MODEL_CROSS_REDUCERS } from '#/wire/model'; +import { OP_REGISTRY } from '#/wire/op'; import { asJsonSchema, @@ -18,6 +43,10 @@ const PKG = join(import.meta.dirname, '..'); const SRC = join(PKG, 'src'); export const MANIFEST_PATH = join(PKG, 'docs', 'wire-manifest.d.ts'); +// --------------------------------------------------------------------------- +// Static pass — op type → owner file; migration chain +// --------------------------------------------------------------------------- + function walk(dir: string, out: string[] = []): string[] { for (const entry of readdirSync(dir)) { const p = join(dir, entry); @@ -27,46 +56,25 @@ function walk(dir: string, out: string[] = []): string[] { return out; } -const TYPE_DECL_RE = /static\s+override\s+readonly\s+type\s*=\s*'([^']+)'/g; -const DURABLE_DECL_RE = /static\s+override\s+readonly\s+durable\s*=\s*true/; -const CLASS_DECL_RE = /class\s+(\w+)\s+extends\s+(?:AgentEvent2|Event2)/g; - -function scanEventDeclarations(): { - owners: Map<string, string>; - importFiles: string[]; - durableTypes: Set<string>; - classTypes: Map<string, string>; -} { +/** op type → owner file (relative to the package root). */ +function scanOpOwners(): { owners: Map<string, string>; opFiles: string[] } { const owners = new Map<string, string>(); - const importFiles: string[] = []; - const durableTypes = new Set<string>(); - const classTypes = new Map<string, string>(); + const opFiles: string[] = []; for (const file of walk(SRC)) { const source = readFileSync(file, 'utf-8'); - const matches = [...source.matchAll(TYPE_DECL_RE)]; - const hasStates = source.includes('.replayable('); - if (matches.length > 0 || hasStates) importFiles.push(file); - for (const [i, match] of matches.entries()) { + if (!source.includes('defineOp(')) continue; + const matches = [...source.matchAll(/defineOp\(\s*'([^']+)'/g)]; + if (matches.length === 0) continue; + opFiles.push(file); + for (const match of matches) { const type = match[1]; - if (type === undefined) continue; - owners.set(type, relative(PKG, file)); - const windowEnd = i + 1 < matches.length ? matches[i + 1]!.index : source.length; - if (DURABLE_DECL_RE.test(source.slice(match.index, windowEnd))) durableTypes.add(type); - } - const classMatches = [...source.matchAll(CLASS_DECL_RE)]; - for (const [i, match] of classMatches.entries()) { - const className = match[1]; - if (className === undefined) continue; - const windowEnd = i + 1 < classMatches.length ? classMatches[i + 1]!.index : source.length; - const typeMatch = /static\s+override\s+readonly\s+type\s*=\s*'([^']+)'/.exec( - source.slice(match.index, windowEnd), - ); - if (typeMatch?.[1] !== undefined) classTypes.set(className, typeMatch[1]); + if (type !== undefined) owners.set(type, relative(PKG, file)); } } - return { owners, importFiles, durableTypes, classTypes }; + return { owners, opFiles }; } +/** `1.0 -> 1.1 -> ...` chain read from the `src/wire/migration/v*.ts` files. */ function scanMigrationChain(): string { const dir = join(SRC, 'wire', 'migration'); const pairs: { source: string; target: string }[] = []; @@ -84,129 +92,23 @@ function scanMigrationChain(): string { return chain.join(' -> '); } -interface ReplayableStateScan { - readonly keyName: string; - readonly constName: string; - readonly undoable: boolean; - readonly blobs: boolean; - readonly foldClasses: string[]; -} - -const ON_FOLD_RE = /\.on\(\s*([A-Za-z_$][\w$]*)/g; -const KEY_ON_RE = /\b([A-Za-z_$][\w$]*)\.on\(\s*([A-Za-z_$][\w$]*)/g; -const PROTOCOL_EVENT_RE = /(?:appendMessage|applyCompaction|clear|undo):\s*([A-Za-z_$][\w$]*)/g; - -function readCallArguments(text: string, parenIndex: number): string { - let depth = 0; - for (let i = parenIndex; i < text.length; i++) { - const ch = text[i]; - if (ch === "'" || ch === '"' || ch === '`') { - const quote = ch; - i += 1; - while (i < text.length && text[i] !== quote) { - if (text[i] === '\\') i += 1; - i += 1; - } - continue; - } - if (ch === '(') depth += 1; - else if (ch === ')') { - depth -= 1; - if (depth === 0) return text.slice(parenIndex + 1, i); - } - } - return text.slice(parenIndex + 1); -} - -function readChain(source: string, start: number): string { - let depth = 0; - const n = source.length; - for (let i = start; i < n; i++) { - const ch = source[i]; - if (ch === "'" || ch === '"' || ch === '`') { - const quote = ch; - i += 1; - while (i < n && source[i] !== quote) { - if (source[i] === '\\') i += 1; - i += 1; - } - continue; - } - if (ch === '{' || ch === '(' || ch === '[') depth += 1; - else if (ch === '}' || ch === ')' || ch === ']') depth = Math.max(0, depth - 1); - else if (ch === ';' && depth === 0) return source.slice(start, i); - } - return source.slice(start); -} - -function scanReplayableStates(): ReplayableStateScan[] { - const states: ReplayableStateScan[] = []; - const byConst = new Map<string, ReplayableStateScan>(); - const constChainRe = - /(?:export\s+)?const\s+([A-Za-z_$][\w$]*)\s*=\s*defineState\(\s*'([^']+)'/g; - for (const file of walk(SRC)) { - const source = readFileSync(file, 'utf-8'); - if (!source.includes('.replayable(') && !source.includes('.on(')) continue; - for (const match of source.matchAll(constChainRe)) { - const constName = match[1]; - const keyName = match[2]; - if (constName === undefined || keyName === undefined) continue; - const chain = readChain(source, source.indexOf('defineState', match.index)); - const replayableIndex = chain.indexOf('.replayable('); - if (replayableIndex === -1) continue; - const replayableArgs = readCallArguments(chain, replayableIndex + '.replayable'.length); - const scan: ReplayableStateScan = { - keyName, - constName, - undoable: chain.includes('.undoable('), - blobs: /\bblobs\s*:/.test(replayableArgs), - foldClasses: [...chain.matchAll(ON_FOLD_RE)].map((m) => m[1]!), - }; - states.push(scan); - byConst.set(constName, scan); - } - } - for (const file of walk(SRC)) { - const source = readFileSync(file, 'utf-8'); - if (!source.includes('.on(')) continue; - for (const match of source.matchAll(KEY_ON_RE)) { - const scan = byConst.get(match[1]!); - const cls = match[2]; - if (scan === undefined || cls === undefined) continue; - if (!scan.foldClasses.includes(cls)) scan.foldClasses.push(cls); - } - } - return states; -} - -function scanUndoableProtocolTypes(classTypes: ReadonlyMap<string, string>): string[] { - for (const file of walk(SRC)) { - const source = readFileSync(file, 'utf-8'); - const index = source.indexOf('registerUndoableProtocol('); - if (index === -1) continue; - const window = readChain(source, index); - const types: string[] = []; - for (const match of window.matchAll(PROTOCOL_EVENT_RE)) { - const cls = match[1]!; - const type = classTypes.get(cls); - if (type === undefined) { - throw new Error( - `[gen-wire-manifest] undoable protocol event class '${cls}' has no resolved type`, - ); - } - types.push(type); - } - return types; - } - throw new Error('[gen-wire-manifest] registerUndoableProtocol call not found under src/'); -} +// --------------------------------------------------------------------------- +// Payload sketch +// +// A Sketch is a small tree: strings are one-line type annotations, dicts are +// object shapes, and a one-element array marks an array-of shape. The d.ts +// renderer below turns the tree into real TypeScript syntax. +// --------------------------------------------------------------------------- type SketchDict = { [key: string]: Sketch }; type Sketch = string | SketchDict | [Sketch]; +/** First key of a dict produced by expanding a named type. */ const TYPE_KEY = '_type'; +/** Marker key rendered as a `// …` comment when a field list is capped. */ const MORE_KEY = '…'; +/** Compact one-line rendering of a Sketch (used inside unions/intersections). */ function stringifySketch(sketch: Sketch): string { if (typeof sketch === 'string') return sketch; if (Array.isArray(sketch)) { @@ -218,6 +120,7 @@ function stringifySketch(sketch: Sketch): string { .join(', ')} }`; } +/** Build a Sketch tree from a zod JSON-schema projection. */ function sketchFromJsonSchema(schema: unknown, root: JsonSchema, depth: number): Sketch { const resolved = resolveRef(schema, root); const s = asJsonSchema(resolved); @@ -238,6 +141,7 @@ function sketchFromJsonSchema(schema: unknown, root: JsonSchema, depth: number): return describeType(resolved, tsQuote); } +/** Build the payload Sketch tree for one op (all three data paths converge). */ function buildPayloadSketch( schema: unknown, staticSketch?: string | Map<string, Sketch>, @@ -258,6 +162,7 @@ function buildPayloadSketch( } return dict; } + // An empty object schema (`z.object({})`) is a payload-less record. if ( jsonSchema.type === 'object' && (jsonSchema.additionalProperties === undefined || jsonSchema.additionalProperties === false) @@ -267,6 +172,10 @@ function buildPayloadSketch( return describeType(jsonSchema, tsQuote); } +// --------------------------------------------------------------------------- +// d.ts rendering — Sketch tree → TypeScript declarations +// --------------------------------------------------------------------------- + function pascalCase(name: string): string { return name .split(/[^A-Za-z0-9]+/) @@ -279,6 +188,11 @@ function tsFieldKey(key: string): string { return /^[$A-Z_a-z][$\w]*$/.test(key) ? key : JSON.stringify(key); } +/** + * Convert a one-line sketch annotation into a valid TS type expression. + * Returns the type plus an optional doc note (the expanded type's name, or a + * hoisted shared spread that cannot be expressed inline). + */ function sketchStringToTs(text: string): { type: string; doc?: string } { let t = text.trim(); const docs: string[] = []; @@ -287,6 +201,7 @@ function sketchStringToTs(text: string): { type: string; doc?: string } { docs.push(named[1]); t = named[2].trim(); } + // A hoisted shared spread (`...base & A | B`) becomes a doc note + variants. const spread = /^((?:\.\.\.[$\w]+(?: \+ )?)+) & ([\s\S]+)$/.exec(t); if (spread?.[1] !== undefined && spread[2] !== undefined) { docs.push(`shared base: ${spread[1]}`); @@ -298,6 +213,10 @@ function sketchStringToTs(text: string): { type: string; doc?: string } { return { type: t, doc: docs.length > 0 ? docs.join(' · ') : undefined }; } +/** + * Render a Sketch as TS type-expression lines. The first line continues after + * the field's `key: `; subsequent lines carry `indent`. + */ function renderTsType(sketch: Sketch, indent: string): { doc?: string; lines: string[] } { if (typeof sketch === 'string') { const { type, doc } = sketchStringToTs(sketch); @@ -322,7 +241,7 @@ function emitTsDict(lines: string[], dict: SketchDict, indent: string): void { lines.push(`${indent}// …`); continue; } - if (key === TYPE_KEY) continue; + if (key === TYPE_KEY) continue; // surfaces as the field's doc comment if (key.startsWith('...')) { lines.push(`${indent}// spread: ${key}`); continue; @@ -339,10 +258,10 @@ function emitTsDict(lines: string[], dict: SketchDict, indent: string): void { } } +/** One record type's payload declaration (`interface` for objects, `type` otherwise). */ function renderPayloadDecl( - entry: { type: string }, + entry: { type: string; model: { name: string }; persist?: boolean; toEvent?: unknown }, owner: string | undefined, - states: string[], flags: string[], sketch: Sketch, ): string[] { @@ -350,12 +269,13 @@ function renderPayloadDecl( const nameField = `_name: '${entry.type}';`; const header = [ '/**', - ` * states: ${states.length > 0 ? states.join(', ') : '(none)'}${flags.length > 0 ? ` · ${flags.join(' · ')}` : ''}`, + ` * model: ${entry.model.name}${flags.length > 0 ? ` · ${flags.join(' · ')}` : ''}`, ` * owner: ${owner ?? '(unresolved)'}`, ]; if (typeof sketch === 'string') { const { type, doc } = sketchStringToTs(sketch); if (type.startsWith('(')) { + // Unrepresentable schema note — keep the declaration parseable. header.push(` * ${type.slice(1, -1)}`); header.push(' */'); return [...header, `interface ${name} {\n ${nameField}\n}`, '']; @@ -389,6 +309,12 @@ function renderPayloadDecl( return lines; } +// --------------------------------------------------------------------------- +// Static payload fallback — sketch fields from source when the zod schema +// cannot be projected to JSON Schema (payloads using `z.custom<T>()`) +// --------------------------------------------------------------------------- + +/** Find the index of the closer matching the opener at `start` (quotes-aware). */ function matchDelimiter(source: string, start: number, open: string, close: string): number { let depth = 0; for (let i = start; i < source.length; i++) { @@ -422,6 +348,7 @@ function matchDelimiter(source: string, start: number, open: string, close: stri return -1; } +/** Split `body` into top-level parts on any of `separators` (quotes/nesting-aware). */ function splitTopLevel(body: string, separators: readonly string[] = [',']): string[] { const parts: string[] = []; let depth = 0; @@ -449,6 +376,7 @@ function splitTopLevel(body: string, separators: readonly string[] = [',']): str return parts.filter((p) => p !== ''); } +/** Split an object literal's body into top-level `key: expr` fields. */ function splitObjectFields(body: string): Map<string, string> { const fields = new Map<string, string>(); for (const part of splitTopLevel(body)) { @@ -463,11 +391,13 @@ function splitObjectFields(body: string): Map<string, string> { return fields; } +/** Extract the body of the first balanced `{...}` in `text` starting at `braceIndex`. */ function objectBody(text: string, braceIndex: number): string | undefined { const end = matchDelimiter(text, braceIndex, '{', '}'); return end === -1 ? undefined : text.slice(braceIndex + 1, end); } +/** Read one expression from `start` up to the top-level `;` that ends the statement. */ function readExpression(source: string, start: number): string { let depth = 0; const n = source.length; @@ -489,20 +419,20 @@ function readExpression(source: string, start: number): string { return source.slice(start); } +/** Quote a string literal TS-style (single quotes) so sketches need no JSON escapes. */ function tsQuote(raw: string): string { return raw.includes("'") ? JSON.stringify(raw) : `'${raw}'`; } -function escapeRegExp(raw: string): string { - return raw.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'); -} - +/** Resolve a `schema:` expression to an object-literal body, following local consts. */ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | undefined { if (depth > 2) return undefined; + // z.object({ ... }) / z.strictObject({ ... }) — inline literal. const inline = /^z\.\w*[oO]bject\s*\(/.exec(expr); if (inline !== null) { const rest = expr.slice(inline[0].length).trimStart(); if (rest.startsWith('{')) return objectBody(rest, 0); + // z.object(SHAPE_CONST) — look up the local shape const. const shapeName = /^([$\w]+)/.exec(rest)?.[1]; if (shapeName !== undefined) { const constRe = new RegExp(`const\\s+${shapeName}\\s*(?::[^=;]+)?=\\s*\\{`); @@ -511,6 +441,7 @@ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | } return undefined; } + // schema: SOME_CONST — follow `const X = z.object(...)` in the same file. const ident = /^([$\w]+)$/.exec(expr.trim())?.[1]; if (ident !== undefined) { const constRe = new RegExp(`const\\s+${ident}\\s*(?::[^=;]+)?=\\s*`); @@ -523,6 +454,13 @@ function resolveSchemaLiteral(expr: string, source: string, depth = 0): string | return undefined; } +// --------------------------------------------------------------------------- +// TS type summarizer — expand `z.custom<T>()` type names into readable sketches +// by resolving the alias (or interface) across local definitions, imports, and +// re-exports. Discriminated unions collapse to `union on type: "a" | "b"`. +// Resolution work is bounded by a per-expansion step budget. +// --------------------------------------------------------------------------- + interface Budget { remaining: number; } @@ -551,6 +489,7 @@ interface TsField { readonly optional: boolean; } +/** Split a TS object type literal body into fields (separators: `;` / `,`). */ function splitTsTypeFields(body: string): Map<string, TsField> { const fields = new Map<string, TsField>(); for (const part of splitTopLevel(body, [';', ','])) { @@ -593,6 +532,7 @@ function renderTsFields( return dict; } +/** Find a local `type X = ...` / `interface X {...}` definition's RHS text. */ function findTsTypeDef(name: string, file: string): string | undefined { const source = readCached(file); const typeRe = new RegExp(`(?:export\\s+)?type\\s+${name}(?:<[^>;=]*>)?\\s*=\\s*`); @@ -607,6 +547,7 @@ function findTsTypeDef(name: string, file: string): string | undefined { return undefined; } +/** Find the module specifier a name is imported (or named-re-exported) from. */ function findImportSource(file: string, name: string): string | undefined { const source = readCached(file); const re = /(?:import|export)\s+(?:type\s+)?\{([^}]+)\}\s*from\s*'([^']+)'/g; @@ -638,6 +579,8 @@ function summarizeTsUnion( charBudget: number, depth: number, ): string { + // Resolve member idents one level so alias unions (ContextMessage = A | B | C) + // still expose their object shapes. const resolved = members.map((m) => { const t = m.trim(); if (/^[$\w]+$/.test(t)) { @@ -649,6 +592,7 @@ function summarizeTsUnion( const bodies = resolved.map((m) => (m.trim().startsWith('{') ? objectBody(m.trim(), 0) : undefined)); if (bodies.length > 0 && bodies.every((b) => b !== undefined)) { const fieldMaps = bodies.map((b) => splitTsTypeFields(b!)); + // Discriminated union: one field is a string literal in every member. for (const [name, info] of fieldMaps[0]!) { if ( /^'[^']*'$/.test(info.type) && @@ -658,6 +602,7 @@ function summarizeTsUnion( return truncate(`union on ${name}: ${values.join(' | ')}`, charBudget); } } + // Unions stay one-line strings; object members use the compact renderer. return truncate( fieldMaps .map((fm) => stringifySketch(renderTsFields(fm, file, budget, charBudget, depth + 1))) @@ -700,6 +645,7 @@ function summarizeTsTypeExpr( if (intersections.length > 1) { if (!spend(budget)) return truncate(text, 80); const sides = intersections.map((m) => summarizeTsTypeExpr(m, file, budget, charBudget, depth + 1)); + // An intersection of object shapes merges into one dictionary. if (sides.every((side) => typeof side !== 'string' && !Array.isArray(side))) { return Object.assign({}, ...sides) as SketchDict; } @@ -719,6 +665,7 @@ function summarizeTsTypeExpr( return truncate(text, 80); } +/** Resolve a type name to a readable summary across aliases, imports, re-exports. */ function summarizeTsType(name: string, fromFile: string, budget: Budget): Sketch | undefined { if (!spend(budget)) return undefined; const def = findTsTypeDef(name, fromFile); @@ -737,8 +684,16 @@ function summarizeTsType(name: string, fromFile: string, budget: Budget): Sketch return undefined; } +/** + * Render a zod field expression as a Sketch, in the same notation the + * JSON-Schema path produces (`string`, `'a' | 'b'`, `Foo[]`). `z.custom<T>()` + * and bare type idents expand through the TS type summarizer — object shapes + * become nested dicts (keyed with the type name under `_type`), everything + * else stays a one-line string. + */ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { let text = expr.replaceAll(/\s+/g, ' ').trim(); + // Strip trailing modifiers the sketch does not mark. let stripped = true; while (stripped) { stripped = false; @@ -754,6 +709,8 @@ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { const custom = /^z\.custom<(.+)>\(\)$/.exec(text); if (custom?.[1] !== undefined) { const typeName = custom[1].trim(); + // Expand the TS type only at the top levels — nested fields keep the bare + // type name so long union member sketches stay readable. if (depth > 1) return typeName; const summary = summarizeTsType(typeName, ownerFile, TS_BUDGET()); if (summary === undefined) return typeName; @@ -827,12 +784,14 @@ function friendlyZodExpr(expr: string, ownerFile: string, depth = 0): Sketch { return truncate(text, 80); } +/** Sketch a `z.union([...])` body (one-line string); object members get field sketches. */ function friendlyZodUnion(body: string, ownerFile: string, depth: number): string { const members = splitTopLevel(body.trim().replace(/^\[/, '').replace(/\]$/, '')); const source = readCached(ownerFile); const bodies = members.map((m) => resolveSchemaLiteral(m, source)); if (members.length > 0 && bodies.every((b) => b !== undefined)) { - const fieldMaps = bodies.map((b) => splitObjectFields(b)); + const fieldMaps = bodies.map((b) => splitObjectFields(b!)); + // Hoist spreads shared by every member (`...base & { … } | { … }`). const spreadSets = fieldMaps.map((fm) => [...fm.keys()].filter((k) => fm.get(k) === '')); const commonSpreads = (spreadSets[0] ?? []).filter((s) => spreadSets.every((set) => set.includes(s)), @@ -855,27 +814,30 @@ function friendlyZodUnion(body: string, ownerFile: string, depth: number): strin ); } +/** + * Best-effort payload sketch from the owner source for schemas that use + * `z.custom` (not representable as JSON Schema). Returns a field map for + * object payloads, a type string for whole-payload custom schemas, or + * `undefined` when the source shape is not recognized. + */ function sketchPayloadFromSource( ownerFile: string, type: string, ): string | Map<string, Sketch> | undefined { const absFile = join(PKG, ownerFile); const source = readCached(absFile); - const typeRe = new RegExp( - `static\\s+override\\s+readonly\\s+type\\s*=\\s*'${escapeRegExp(type)}'`, - ); - const typeMatch = typeRe.exec(source); - if (typeMatch === null) return undefined; - const rest = source.slice(typeMatch.index + typeMatch[0].length); - const nextType = /static\s+override\s+readonly\s+type\s*=/.exec(rest); - const classWindow = nextType === null ? rest : rest.slice(0, nextType.index); - const schemaMatch = /static\s+override\s+readonly\s+schema\s*=\s*/.exec(classWindow); - if (schemaMatch === null) return undefined; - const schemaExpr = readExpression( - classWindow, - schemaMatch.index + schemaMatch[0].length, - ).trim(); - if (schemaExpr === '') return undefined; + const callRe = new RegExp(`defineOp\\(\\s*'${type.replaceAll('.', '\\.')}'\\s*,\\s*\\{`); + const call = callRe.exec(source); + if (call === null) return undefined; + const optionsBody = objectBody(source, call.index + call[0].length - 1); + if (optionsBody === undefined) return undefined; + const schemaField = /(?:^|[,\n])\s*schema\s*:/.exec(optionsBody); + if (schemaField === null) return undefined; + const afterSchema = optionsBody.slice(schemaField.index + schemaField[0].length).trimStart(); + // The schema expression ends at the next top-level comma. + const exprFields = splitObjectFields(`schema: ${afterSchema}`); + const schemaExpr = exprFields.get('schema'); + if (schemaExpr === undefined) return undefined; const literal = resolveSchemaLiteral(schemaExpr, source); if (literal === undefined) { const sketch = friendlyZodExpr(schemaExpr, absFile); @@ -895,57 +857,25 @@ function sketchPayloadFromSource( return sketch; } +// --------------------------------------------------------------------------- +// Manifest rendering +// --------------------------------------------------------------------------- + export async function buildWireManifest(): Promise<string> { - const { owners, importFiles, durableTypes, classTypes } = scanEventDeclarations(); + const { owners, opFiles } = scanOpOwners(); + // "import = register": loading the package root plus every op module found in + // the static pass fills OP_REGISTRY, even for modules index.ts does not load. await import('../src/index.ts'); - for (const file of importFiles) { + for (const file of opFiles) { await import(relative(join(PKG, 'scripts'), file)); } const { WIRE_PROTOCOL_VERSION } = (await import('#/wire/migration/migration')) as { WIRE_PROTOCOL_VERSION: string; }; - const entries = [...EVENT2_REGISTRY.values()].toSorted((a, b) => a.type.localeCompare(b.type)); + const entries = [...OP_REGISTRY.values()].toSorted((a, b) => a.type.localeCompare(b.type)); const migrationChain = scanMigrationChain(); - const folding = new Map<string, { states: string[]; blobs: string[] }>(); - const protocolTypes = scanUndoableProtocolTypes(classTypes); - for (const state of scanReplayableStates()) { - const eventTypes = new Set<string>(); - for (const cls of state.foldClasses) { - const type = classTypes.get(cls); - if (type === undefined) { - throw new Error( - `[gen-wire-manifest] state '${state.keyName}' folds unresolved event class '${cls}'`, - ); - } - eventTypes.add(type); - } - if (state.undoable) { - for (const type of protocolTypes) eventTypes.add(type); - } - for (const type of eventTypes) { - let info = folding.get(type); - if (info === undefined) { - info = { states: [], blobs: [] }; - folding.set(type, info); - } - info.states.push(state.keyName); - if (state.blobs) info.blobs.push(state.keyName); - } - } - for (const info of folding.values()) { - info.states.sort(); - info.blobs.sort(); - } - - const unregistered = [...durableTypes].filter((type) => !EVENT2_REGISTRY.has(type)); - if (unregistered.length > 0) { - console.error( - `[gen-wire-manifest] declared durable but never registered (no fold, not in EVENT2_REGISTRY): ${unregistered.toSorted().join(', ')}`, - ); - } - const out: string[] = [ '// Wire Protocol Manifest', '//', @@ -954,52 +884,52 @@ export async function buildWireManifest(): Promise<string> { '//', `// protocol_version: "${WIRE_PROTOCOL_VERSION}" (migrations: ${migrationChain})`, '//', - '// One declaration per durable record type — an Event2 subclass declaring', - '// `static type` + `static durable = true` + `static schema` — drained from the', - '// runtime EVENT2_REGISTRY ("import = register"). Every payload declaration', - '// carries its record type in a `_name` field. Payload sketches use TypeScript', - '// type syntax; when a named type is expanded inline, its name appears as a doc', - '// comment (`/** ContextMessage */`). Bare type names (ContentPart,', - '// ContextMessage, …) refer to the real types in src/ — they are intentionally', - '// not resolved here. `// …` marks a capped field list. On disk (wire.jsonl)', - '// the journal opens with a metadata line {"type": "metadata",', - '// "protocol_version", "created_at"}; each record is {"type", ...payload,', - '// "time"} — object payloads spread at the top level.', + '// One declaration per record type registered via defineOp(...) and drained from', + '// the runtime OP_REGISTRY. Every payload declaration carries its record type in', + '// a `_name` field. Payload sketches use TypeScript type syntax; when a', + '// named type is expanded inline, its name appears as a doc comment', + '// (`/** ContextMessage */`). Bare type names (ContentPart, ContextMessage, …)', + '// refer to the real types in src/ — they are intentionally not resolved here.', + '// `// …` marks a capped field list. On disk (wire.jsonl) the journal opens with', + '// a metadata line {"type": "metadata", "protocol_version", "created_at"}; each', + '// op record is {"type", ...payload, "time"} — object payloads spread at the', + '// top level, scalar payloads nest under a "payload" key.', '//', - '// Every listed type is durable by construction — transient Event2 classes', - '// never enter EVENT2_REGISTRY, so there is no persisted flag. Declaration', - '// header lines: states (every state folding this record type on dispatch and', - '// replay; any state beyond the first is what the retired format listed as', - '// cross-reducers), blobs (the folding states whose blob codec offloads inline', - '// media to blob storage), owner (the source file declaring the class).', + '// Declaration flags: persisted (written to the journal; absent = transient),', + '// toEvent (also publishes an IEventBus fact on live dispatch), blobs (the', + '// owning model offloads inline media to blob storage), cross-reducers', + '// (foreign models that also reduce this record on dispatch and replay).', '', `// Index (${entries.length} record types)`, ]; const width = Math.max(...entries.map((e) => e.type.length)); - const statesWidth = Math.max( - ...entries.map((e) => (folding.get(e.type)?.states.join(', ') ?? '(none)').length), - ); + const modelWidth = Math.max(...entries.map((e) => e.model.name.length)); for (const entry of entries) { - const states = folding.get(entry.type)?.states.join(', ') ?? '(none)'; + const flags = entry.persist === false ? 'transient' : 'persisted'; out.push( - `// ${entry.type.padEnd(width)} ${states.padEnd(statesWidth)} ${owners.get(entry.type) ?? '(unresolved)'}`, + `// ${entry.type.padEnd(width)} ${entry.model.name.padEnd(modelWidth)} ${flags} ${owners.get(entry.type) ?? '(unresolved)'}`, ); } out.push(''); const declNames: [string, string][] = []; for (const entry of entries) { - const info = folding.get(entry.type); - const states = info?.states ?? []; const flags: string[] = []; - if (info !== undefined && info.blobs.length > 0) flags.push(`blobs: ${info.blobs.join(', ')}`); + if (entry.persist !== false) flags.push('persisted'); + if (entry.toEvent !== undefined) flags.push('toEvent'); + if (entry.model.blobs !== undefined) flags.push('blobs'); + const crossReducers = (MODEL_CROSS_REDUCERS.get(entry.type) ?? []) + .map((r) => (r.model as { name: string }).name) + .filter((name) => name !== entry.model.name); + if (crossReducers.length > 0) flags.push(`cross-reducers: ${crossReducers.join(', ')}`); const owner = owners.get(entry.type); const staticSketch = owner === undefined ? undefined : sketchPayloadFromSource(owner, entry.type); const sketch = buildPayloadSketch(entry.schema as unknown, staticSketch); - out.push(...renderPayloadDecl(entry, owner, states, flags, sketch)); + out.push(...renderPayloadDecl(entry, owner, flags, sketch)); declNames.push([entry.type, `${pascalCase(entry.type)}Payload`]); } + // Record type → payload declaration map. out.push('/** Record type → payload sketch. */'); out.push('interface WirePayloadMap {'); for (const [type, declName] of declNames) { @@ -1010,6 +940,10 @@ export async function buildWireManifest(): Promise<string> { return out.join('\n'); } +// --------------------------------------------------------------------------- +// CLI +// --------------------------------------------------------------------------- + async function main(): Promise<void> { const check = process.argv.includes('--check'); const manifest = await buildWireManifest(); diff --git a/packages/agent-core-v2/scripts/generate-webp-dec-wasm.mjs b/packages/agent-core-v2/scripts/generate-webp-dec-wasm.mjs index 04ac72d65..77ac100a2 100644 --- a/packages/agent-core-v2/scripts/generate-webp-dec-wasm.mjs +++ b/packages/agent-core-v2/scripts/generate-webp-dec-wasm.mjs @@ -1,3 +1,15 @@ +/** + * Regenerate `src/agent/media/webp-dec-wasm.ts` from the installed + * `@jsquash/webp` package. + * + * The WebP decoder wasm is committed as a base64 string module because the + * published CLI bundles every dependency into a single file with no runtime + * node_modules — a file-path lookup for the .wasm would break there, while a + * string constant survives every packaging (vitest on sources, tsdown + * bundling, nix builds) unchanged. Run this after bumping @jsquash/webp: + * + * node scripts/generate-webp-dec-wasm.mjs + */ import { createRequire } from 'node:module'; import { readFileSync, writeFileSync } from 'node:fs'; import { resolve } from 'node:path'; diff --git a/packages/agent-core-v2/scripts/lib/jsonSchema.mts b/packages/agent-core-v2/scripts/lib/jsonSchema.mts index e02f182a0..4e2f9c793 100644 --- a/packages/agent-core-v2/scripts/lib/jsonSchema.mts +++ b/packages/agent-core-v2/scripts/lib/jsonSchema.mts @@ -1,3 +1,11 @@ +/** + * Shared JSON-schema helpers for the manifest generators + * (`gen-config-manifest.mts`, `gen-wire-manifest.mts`). + * + * Both generators drain runtime registries that carry zod schemas and render + * field/type sketches from their JSON Schema projection. + */ + import { z } from 'zod'; export function isRecord(value: unknown): value is Record<string, unknown> { @@ -8,6 +16,7 @@ export function truncate(text: string, max = 100): string { return text.length > max ? `${text.slice(0, max - 1)}…` : text; } +/** Property access shape of a JSON Schema node (avoids index-signature access). */ export interface JsonSchema { readonly $ref?: unknown; readonly $defs?: unknown; @@ -27,18 +36,20 @@ export function asJsonSchema(value: unknown): JsonSchema | undefined { return isRecord(value) ? (value as JsonSchema) : undefined; } +/** Resolve a `#/$defs/<name>` reference against the root schema. */ export function resolveRef(schema: unknown, root: JsonSchema): unknown { const s = asJsonSchema(schema); if (typeof s?.$ref === 'string' && s.$ref.startsWith('#/$defs/')) { const defs = asJsonSchema(root.$defs); const name = s.$ref.slice('#/$defs/'.length); if (defs !== undefined && isRecord(defs) && name in defs) { - return defs[name]; + return (defs as Record<string, unknown>)[name]; } } return schema; } +/** One-line type description of a JSON Schema node (`"a" | "b"`, `Foo[]`, …). */ export function describeType( schema: unknown, quoteString: (raw: string) => string = (s) => JSON.stringify(s), @@ -65,6 +76,9 @@ export function describeType( } if (s.type === 'array') return `${describeType(s.items, quoteString)}[]`; if (s.type === 'object') { + // Named sub-tables (zod objects emit `additionalProperties: false`) are + // rendered by the caller; only a schema-valued additionalProperties marks + // a true record. if (isRecord(s.properties)) return 'object'; if (isRecord(s.additionalProperties)) { return `record<string, ${describeType(s.additionalProperties, quoteString)}>`; @@ -75,6 +89,7 @@ export function describeType( return 'any'; } +/** Project a zod schema to JSON Schema; `undefined` when it uses transforms. */ export function toJsonSchema(schema: unknown): JsonSchema | undefined { try { return z.toJSONSchema(schema as never) as JsonSchema; diff --git a/packages/agent-core-v2/src/_base/asyncEventQueue.ts b/packages/agent-core-v2/src/_base/asyncEventQueue.ts index e49240fd7..a917d87a6 100644 --- a/packages/agent-core-v2/src/_base/asyncEventQueue.ts +++ b/packages/agent-core-v2/src/_base/asyncEventQueue.ts @@ -1,3 +1,17 @@ +/** + * `_base.asyncEventQueue` — push-based async iterable. + * + * Bridges a callback-driven producer (e.g. a streaming LLM's `onMessagePart`) + * to an async-generator consumer. Values pushed while there is a pending + * `next()` waiter are delivered immediately; otherwise they buffer in-order. + * `end()` signals normal termination; `fail(err)` terminates with an error + * that is thrown at the next `next()` (once the buffered values have been + * drained). Idempotent — repeated `end`/`fail`/`push` after termination are + * no-ops. + * + * Layer L0 substrate. + */ + export class AsyncEventQueue<T> implements AsyncIterable<T>, AsyncIterator<T> { private readonly values: T[] = []; private readonly waiters: Array<{ diff --git a/packages/agent-core-v2/src/_base/contribution/registry.ts b/packages/agent-core-v2/src/_base/contribution/registry.ts index 9c3f23092..5db87eb20 100644 --- a/packages/agent-core-v2/src/_base/contribution/registry.ts +++ b/packages/agent-core-v2/src/_base/contribution/registry.ts @@ -1,3 +1,19 @@ +/** + * `_base/contribution` domain — generic source-keyed contribution + * registry. + * + * The storage half of the Contribution / Registry / Catalog extension-point + * pattern: a *contribution* is a plain data structure offered by an outer + * contributor (a loader, a plugin, a code module); the *registry* stores at + * most one contribution per `sourceId` — re-registering the same `sourceId` + * replaces the previous entry, which is the only dedup this layer performs. + * Content-level dedup (e.g. by item name), ordering, and merge rules are the + * Catalog's projection job, never the registry's. `register` returns a handle + * whose `dispose` unregisters — but only the entry it registered, so a stale + * handle can never evict a newer re-registration. Every mutation fires + * `onDidChange` with the affected `sourceId` so catalogs can re-project. + */ + import { Disposable, type IDisposable } from '../di/lifecycle'; import { Emitter, type Event } from '../event'; @@ -11,6 +27,7 @@ export interface RegisterContributionOptions { readonly priority?: number; } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ContributionRegistry<T> extends Disposable { private readonly registrations = new Map<string, ContributionRegistration<T>>(); private readonly onDidChangeEmitter = this._register(new Emitter<string>()); diff --git a/packages/agent-core-v2/src/_base/di/cascadeEngine.ts b/packages/agent-core-v2/src/_base/di/cascadeEngine.ts index e33425c37..472100d1f 100644 --- a/packages/agent-core-v2/src/_base/di/cascadeEngine.ts +++ b/packages/agent-core-v2/src/_base/di/cascadeEngine.ts @@ -1,3 +1,33 @@ +/** + * `di` domain — cascade engine + wait scheduler (L2), one per container, with + * tree-wide orchestration (D9: cascades propagate along instance edges across + * scopes). + * + * The dependency graph, request queue, in-flight set, and settle waiters are + * shared by the whole scope tree (`CascadeTree`, owned by the root). Every + * change (provide / unprovide / update) runs as a single transaction + * orchestrated by the engine of the scope where the change was submitted: + * ① compute the contagion set from the tree-global graph; + * ② broadcast WillCascade to the orchestrator's abort hook (bounded wait, + * then forced; failures are best-effort, never a veto); + * ③ tear the contagion set down in global reverse topological order, serially + * (each scope's engine executes its own units; Active → Unloading → + * Pending, or removed for an unprovided token; a descendant scope that dies + * mid-transaction is skipped idempotently); + * ④ apply the change in its own scope (a replace never passes through the + * waiting area); + * ⑤ recheck the waiting area across scopes and rebuild satisfied units in + * global topological order; + * ⑥ append the transaction to the orchestrator's history ring. + * + * Requests serialize through the tree queue; requests queued together merge + * their contagion sets (deduped by scope+token) into one transaction. This is + * one transaction across the tree but not a distributed transaction: a single + * orchestrator, a deterministic order, local execution per scope. Like the + * Ledger, the engine has a sync fast path: with no async abort wait and no + * async disposers, a transaction completes within the tick. + */ + import { onUnexpectedError } from '../errors/unexpectedError'; import { Emitter, type Event } from '../event'; import { isPromiseLike } from '../lifecycle/disposer'; @@ -18,6 +48,7 @@ export type UnitActivation = 'eager' | 'ondemand'; export interface CascadeChange { readonly action: CascadeAction; + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier<any>; readonly descriptor?: SyncDescriptor<unknown>; readonly instance?: unknown; @@ -65,25 +96,37 @@ export interface CascadeEngineOptions { } export interface CascadeHost { + // eslint-disable-next-line @typescript-eslint/no-explicit-any isRegistered(token: ServiceIdentifier<any>): boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any ownerScopeOf(token: ServiceIdentifier<any>): object | undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any isMaterialized(token: ServiceIdentifier<any>): boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any materialize(token: ServiceIdentifier<any>): unknown; + // eslint-disable-next-line @typescript-eslint/no-explicit-any retire(token: ServiceIdentifier<any>): void | Promise<void>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any applyProvide( + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, descriptor: SyncDescriptor<unknown>, config: unknown, ): number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any applyProvideInstance( + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, instance: unknown, config: unknown, ): number; + // eslint-disable-next-line @typescript-eslint/no-explicit-any applyUnprovide(token: ServiceIdentifier<any>): void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any recipeOf(token: ServiceIdentifier<any>): SyncDescriptor<unknown> | undefined; dependenciesOf( recipe: SyncDescriptor<unknown>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): Array<ServiceIdentifier<any>>; } @@ -182,11 +225,14 @@ export class CascadeTree { export class CascadeEngine { private readonly _units = new Map< + // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier<any>, UnitRecord >(); private readonly _pendingIndex = new Map< + // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier<any>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any Set<ServiceIdentifier<any>> >(); private readonly _history: CascadeHistoryEntry[] = []; @@ -210,23 +256,28 @@ export class CascadeEngine { this._options = { ...this._options, ...options }; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any stateOf(token: ServiceIdentifier<any>): UnitState | undefined { return this._units.get(token)?.state; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any activationOf(token: ServiceIdentifier<any>): UnitActivation | undefined { return this._units.get(token)?.activation; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any materializable(token: ServiceIdentifier<any>): boolean { return this._host.recipeOf(token) !== undefined; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any failureOf(token: ServiceIdentifier<any>): unknown { const unit = this._units.get(token); return unit?.state === 'Failed' ? unit.error : undefined; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any isInFlight(token: ServiceIdentifier<any>): boolean { const owner = this._host.ownerScopeOf(token) ?? this._scope; return this._tree.inFlightHas({ scope: owner, token }); @@ -284,6 +335,7 @@ export class CascadeEngine { }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any update(token: ServiceIdentifier<any>, reason?: string): Promise<void> { return this.submit({ action: 'update', @@ -304,6 +356,7 @@ export class CascadeEngine { } resolveWhenAvailable<T>( + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, timeoutMs?: number, ): Promise<T> { @@ -334,6 +387,7 @@ export class CascadeEngine { }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any observedMaterialization(token: ServiceIdentifier<any>): void { const unit = this._units.get(token); if (unit !== undefined && unit.state === 'Pending') { @@ -361,7 +415,9 @@ export class CascadeEngine { this._onDidCascade.dispose(); } + _teardownForCascade( + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, tornDown: string[], parkAsPending: boolean, @@ -411,6 +467,7 @@ export class CascadeEngine { } } + private _pump(): void { if (this._tree.running) { return; @@ -448,6 +505,7 @@ export class CascadeEngine { } } + private _transact(batch: QueuedRequest[]): void | Promise<void> { const changes = mergeBatch(batch); const started = this._options.now?.() ?? Date.now(); @@ -598,6 +656,8 @@ export class CascadeEngine { return undefined; } + + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _unitFor(token: ServiceIdentifier<any>): UnitRecord { let unit = this._units.get(token); if (unit === undefined) { @@ -609,6 +669,7 @@ export class CascadeEngine { } private _setUnitState( + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, unit: UnitRecord, state: UnitState, @@ -626,6 +687,7 @@ export class CascadeEngine { } } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _markPending( token: ServiceIdentifier<any>, activation?: UnitActivation, @@ -644,6 +706,7 @@ export class CascadeEngine { private _recheckPending(rebuilt: string[], failed: string[]): void { for (;;) { this._pendingIndex.clear(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const satisfied: ServiceIdentifier<any>[] = []; for (const [token, unit] of this._units) { if (unit.state !== 'Pending') continue; @@ -684,6 +747,7 @@ export class CascadeEngine { } } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _activate(token: ServiceIdentifier<any>, rebuilt: string[], failed: string[]): void { const unit = this._unitFor(token); this._setUnitState(token, unit, 'Activating', undefined); @@ -698,6 +762,7 @@ export class CascadeEngine { } } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _missingDeps(token: ServiceIdentifier<any>): Array<ServiceIdentifier<any>> { const recipe = this._host.recipeOf(token); if (recipe === undefined) { @@ -708,6 +773,7 @@ export class CascadeEngine { .filter((dep) => !this._isAvailable(dep)); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _isAvailable(dep: ServiceIdentifier<any>): boolean { if (!this._host.isRegistered(dep)) { return false; diff --git a/packages/agent-core-v2/src/_base/di/collection.ts b/packages/agent-core-v2/src/_base/di/collection.ts index bfc23561b..4f69dedbb 100644 --- a/packages/agent-core-v2/src/_base/di/collection.ts +++ b/packages/agent-core-v2/src/_base/di/collection.ts @@ -1,8 +1,30 @@ +/** + * `di` domain — collection tokens, live views, and the tree-global record + * store (L3, D12). + * + * A contribution point is a `collection<T>(name)` token; contributing is + * `this.provide(token, value)` — no registry API. Records physically live + * under the provider's scope and are visible to the provider's ancestors AND + * descendants (never to sibling subtrees): capabilities flow upward, and a + * fold at any tier also sees what its own subtree contributed. Every record + * carries the provider unit's name and scope path so folds can group/filter + * by source. Record lifetime hangs on the provider's book — provider death + * withdraws the record (and scope death tears the provider's book). + * + * A fold service declares the token as a constructor parameter and receives + * a `CollectionView<T>`: `items`/`records` are computed live, `onDidChange` + * delivers incremental `{added, removed}` payloads. Collection edges are + * recorded in the persistent graph for introspection but never join a + * cascade contagion set — a fold refolds incrementally instead of being + * rebuilt. + */ + import { Emitter, type Event } from '../event'; import type { Ledger } from '../lifecycle/ledger'; import { storeCustomDependency, type ServiceIdentifier } from './instantiation'; export interface CollectionToken<T> { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (target: any, key: string | symbol | undefined, index: number): void; readonly name: string; @@ -12,43 +34,16 @@ export interface CollectionToken<T> { toString(): string; } -export interface DefinitionToken<T> extends CollectionToken<T> { - readonly __definition?: T; -} - -export interface DefinitionRecord<T> { - readonly definition: T; - readonly owner: string; - readonly generation: number; -} - -export interface DefinitionChange<T> { - readonly current: DefinitionRecord<T> | undefined; - readonly previous: DefinitionRecord<T> | undefined; -} - -export interface DefinitionView<T> { - readonly current: DefinitionRecord<T> | undefined; - readonly onDidChangeDefinition: Event<DefinitionChange<T>>; -} - const _collectionTokens = new Map<string, CollectionToken<unknown>>(); const _collectionTokenSet = new WeakSet<object>(); -const _definitionTokenSet = new WeakSet<object>(); -const _collectionValidators = new WeakMap< - object, - (value: unknown, existing: readonly unknown[]) => void ->(); -export function collection<T>( - name: string, - options: { readonly validate?: (value: T, existing: readonly T[]) => void } = {}, -): CollectionToken<T> { +export function collection<T>(name: string): CollectionToken<T> { const existing = _collectionTokens.get(name); if (existing !== undefined) { return existing as CollectionToken<T>; } const token = function collectionDecorator( + // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, _key: string | symbol | undefined, index: number, @@ -56,6 +51,7 @@ export function collection<T>( if (arguments.length !== 3) { throw new Error('@CollectionToken-decorator can only be used to decorate a parameter'); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any storeCustomDependency(token as unknown as ServiceIdentifier<any>, 'collection', target, index); } as unknown as CollectionToken<T>; Object.defineProperty(token, 'toString', { @@ -65,22 +61,6 @@ export function collection<T>( Object.defineProperty(token, 'name', { value: name, enumerable: false, configurable: true }); _collectionTokens.set(name, token as CollectionToken<unknown>); _collectionTokenSet.add(token); - if (options.validate !== undefined) { - _collectionValidators.set( - token, - options.validate as (value: unknown, existing: readonly unknown[]) => void, - ); - } - return token; -} - -export function definition<T>(name: string): DefinitionToken<T> { - const token = collection<T>(name, { - validate: (_value, existing) => { - if (existing.length > 0) throw new Error(`Definition ${name} already has an active provider`); - }, - }) as DefinitionToken<T>; - _definitionTokenSet.add(token); return token; } @@ -88,10 +68,6 @@ export function isCollectionToken(thing: unknown): thing is CollectionToken<unkn return typeof thing === 'function' && _collectionTokenSet.has(thing); } -export function isDefinitionToken(thing: unknown): thing is DefinitionToken<unknown> { - return typeof thing === 'function' && _definitionTokenSet.has(thing); -} - export interface CollectionRecord<T> { readonly value: T; readonly providerName: string; @@ -143,10 +119,6 @@ export class CollectionStore { records = new Map(); this._records.set(token as CollectionToken<unknown>, records); } - _collectionValidators.get(token)?.( - value, - [...records.values()].map((entry) => entry.value), - ); const record: StoredRecord = { id: ++this._nextId, value, @@ -223,19 +195,6 @@ export class CollectionStore { return out; } - definitionFor<T>(token: CollectionToken<T>, consumer: object): DefinitionRecord<T> | undefined { - const record = this.storedRecordsFor( - token as CollectionToken<unknown>, - consumer, - )[0]; - if (record === undefined) return undefined; - return { - definition: record.value as T, - owner: `${record.providerName}@${record.scopePath}`, - generation: record.id, - }; - } - private _isRelated(consumer: object, provider: object): boolean { for (let c: object | undefined = consumer; c !== undefined; c = this._parentOf(c)) { if (c === provider) return true; @@ -247,12 +206,9 @@ export class CollectionStore { } } -export class CollectionViewImpl<T> implements CollectionView<T>, DefinitionView<T> { +export class CollectionViewImpl<T> implements CollectionView<T> { private readonly _onDidChange = new Emitter<CollectionChange<T>>(); - private readonly _onDidChangeDefinition = new Emitter<DefinitionChange<T>>(); readonly onDidChange: Event<CollectionChange<T>> = this._onDidChange.event; - readonly onDidChangeDefinition: Event<DefinitionChange<T>> = - this._onDidChangeDefinition.event; constructor( private readonly _store: CollectionStore, @@ -268,35 +224,17 @@ export class CollectionViewImpl<T> implements CollectionView<T>, DefinitionView< return this.records.map((record) => record.value); } - get current(): DefinitionRecord<T> | undefined { - return this._store.definitionFor(this.token, this.consumer); - } - _fireDelta(kind: 'added' | 'removed', records: readonly StoredRecord[]): void { - const previous = kind === 'removed' ? this.definitionRecord(records[0]) : undefined; const values = records.map((record) => record.value as T); this._onDidChange.fire( kind === 'added' ? { added: values, removed: [] } : { added: [], removed: values }, ); - if (isDefinitionToken(this.token)) { - this._onDidChangeDefinition.fire({ current: this.current, previous }); - } } dispose(): void { this._store.dropView(this as unknown as CollectionViewImpl<unknown>); this._onDidChange.dispose(); - this._onDidChangeDefinition.dispose(); - } - - private definitionRecord(record: StoredRecord | undefined): DefinitionRecord<T> | undefined { - if (record === undefined) return undefined; - return { - definition: record.value as T, - owner: `${record.providerName}@${record.scopePath}`, - generation: record.id, - }; } } diff --git a/packages/agent-core-v2/src/_base/di/dependencyGraph.ts b/packages/agent-core-v2/src/_base/di/dependencyGraph.ts index 69f574eb8..bfc936e9d 100644 --- a/packages/agent-core-v2/src/_base/di/dependencyGraph.ts +++ b/packages/agent-core-v2/src/_base/di/dependencyGraph.ts @@ -1,7 +1,23 @@ +/** + * `di` domain — persistent dependency graph (L2 substrate), tree-global. + * + * One graph is shared by every container of a scope tree. Edges are recorded + * when a service's constructor dependencies are resolved and removed when the + * consumer is torn down, so the graph always mirrors the live containers. + * Both ends of an edge are scope-tagged: a consumer in a child scope may bind + * a token owned by an ancestor scope (child → parent only — a parent can never + * resolve a child's token, so cross-tree cycles are impossible by + * construction). Instance edges bind a consumer to its dependency's + * generation (the dependency changes → the consumer is torn down and rebuilt, + * across scopes); collection edges (Phase 3) are recorded for introspection + * but never join a cascade contagion set. + */ + import type { ServiceIdentifier } from './instantiation'; export interface ScopedToken { readonly scope: object; + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier<any>; } @@ -15,6 +31,7 @@ export interface DependencyEdge { export class PairIndex<V> { private readonly _map = new Map<object, Map< + // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier<any>, V >>(); @@ -65,6 +82,7 @@ export class DependencyGraph { addInstance( instance: object, scope: object, + // eslint-disable-next-line @typescript-eslint/no-explicit-any token: ServiceIdentifier<any>, ): void { const ref: ScopedToken = { scope, token }; diff --git a/packages/agent-core-v2/src/_base/di/descriptors.ts b/packages/agent-core-v2/src/_base/di/descriptors.ts index e9f81dd58..c841d4f5d 100644 --- a/packages/agent-core-v2/src/_base/di/descriptors.ts +++ b/packages/agent-core-v2/src/_base/di/descriptors.ts @@ -1,8 +1,15 @@ +/** + * `di` domain — `SyncDescriptor` packaging a constructor and its static arguments. + */ + export class SyncDescriptor<T> { + // eslint-disable-next-line @typescript-eslint/no-explicit-any public readonly ctor: any; constructor( + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: new (...args: any[]) => T, + // eslint-disable-next-line @typescript-eslint/no-explicit-any public readonly staticArguments: ReadonlyArray<any> = [], ) { this.ctor = ctor; diff --git a/packages/agent-core-v2/src/_base/di/errors.ts b/packages/agent-core-v2/src/_base/di/errors.ts index 391d8a908..e95353c31 100644 --- a/packages/agent-core-v2/src/_base/di/errors.ts +++ b/packages/agent-core-v2/src/_base/di/errors.ts @@ -1,14 +1,20 @@ +/** + * `di` domain — `CyclicDependencyError` raised on DI dependency cycles. + */ + import type { Graph } from './graph'; export class CyclicDependencyError extends Error { readonly path: ReadonlyArray<string>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(pathOrGraph: ReadonlyArray<string> | Graph<any>) { if (Array.isArray(pathOrGraph)) { const path = pathOrGraph as ReadonlyArray<string>; super(`Cyclic DI dependency detected: ${path.join(' → ')}`); this.path = path; } else { + // eslint-disable-next-line @typescript-eslint/no-explicit-any const graph = pathOrGraph as Graph<any>; const cycle = graph.findCycleSlow(); const detail = cycle ?? `UNABLE to detect cycle, dumping graph:\n${graph.toString()}`; diff --git a/packages/agent-core-v2/src/_base/di/fiber.ts b/packages/agent-core-v2/src/_base/di/fiber.ts index aed277c56..6c7220b0d 100644 --- a/packages/agent-core-v2/src/_base/di/fiber.ts +++ b/packages/agent-core-v2/src/_base/di/fiber.ts @@ -1,3 +1,34 @@ +/** + * `di` domain — the L3 unit layer: the `Fiber` capability contract, unit + * recipes, and the construction protocol that binds them to a container. + * + * A unit recipe comes in three shapes — a class extending `Service` + * (`service.ts`), a function `(fiber, config) => cleanup`, or an object with + * `apply(fiber, config)` — carrying optional statics (`name` / `inject` / + * `Config`; `Config` is a standard-schema that must validate + * synchronously). A materialized unit receives a `Fiber` facade exposing the + * five capabilities: `provide` (token-bound units, anonymous sub-units, and + * collection records), `effect` (ledger-anchored side effects), `on` (event + * subscriptions), `get` (declared-dependency resolution) and `ref` (live + * references). Every capability returns a `FiberHandle` — a thenable that + * settles once the unit is active, and carries `update` / `dispose`. + * + * `FiberRuntime` never touches the container directly: it delegates to a + * `FiberHost` (implemented by the instantiation service) and anchors every + * teardown into the unit's `Ledger`, so provider death withdraws everything + * the unit provided. `get` is restricted to the recipe's declared + * dependencies (constructor parameters for class recipes, the `inject` + * static for function/object recipes). + * + * The construction protocol bridges class recipes and the container: the + * container pushes a `ConstructionFrame`, the `Service` base buffers + * capability calls made inside the constructor as `BufferedOp`s (answered + * with `PendingFiberHandle`s), and `bindServiceUnit` flushes the buffer + * against the freshly bound runtime once construction finishes — 构造期只写 + * 不读. `ScopeUnits(kind)` mints the per-scope-kind materialization + * collection token folded by `scopeUnits.ts`. + */ + import type { IDisposable } from './lifecycle'; import type { Emitter } from '../event'; import { isPromiseLike, type EffectBody } from '../lifecycle/disposer'; @@ -33,24 +64,29 @@ export interface ConfigSchema { export interface RecipeStatics { readonly name?: string; + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly inject?: readonly ServiceIdentifier<any>[]; readonly Config?: ConfigSchema; - readonly meta?: Record<string, unknown>; } export type ServiceClassRecipe = + // eslint-disable-next-line @typescript-eslint/no-explicit-any (new (...args: any[]) => unknown) & RecipeStatics; export type ServiceFunctionRecipe = (( fiber: Fiber, + // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ) => any) & RecipeStatics; export type ServiceObjectRecipe = { apply( fiber: Fiber, + // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): any; } & RecipeStatics; @@ -80,6 +116,7 @@ export interface Fiber { effect(body: EffectBody, label?: string): FiberHandle; + // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter<any>, handler: (e: any) => void): FiberHandle; get<T>(id: ServiceIdentifier<T>): T; @@ -109,8 +146,10 @@ export class ServiceRecipeError extends Error { } export interface ConstructionFrame { + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly ctor: new (...args: any[]) => any; readonly config: unknown; + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly token: ServiceIdentifier<any> | undefined; readonly host: FiberHost; } @@ -131,6 +170,7 @@ export function currentConstruction(): ConstructionFrame | undefined { export const SERVICE_MARK = Symbol('serviceUnit'); +// eslint-disable-next-line @typescript-eslint/no-explicit-any export function isServiceRecipe(ctor: any): ctor is ServiceClassRecipe { return typeof ctor === 'function' && ctor.prototype?.[SERVICE_MARK] === true; } @@ -161,12 +201,15 @@ export interface FiberHost { }, ): TokenProvideCore; provideTokenInstance<T>(id: ServiceIdentifier<T>, instance: T): TokenProvideCore; + // eslint-disable-next-line @typescript-eslint/no-explicit-any tokenState(id: ServiceIdentifier<any>): string | undefined; + // eslint-disable-next-line @typescript-eslint/no-explicit-any updateToken(id: ServiceIdentifier<any>, config: unknown, hasConfig: boolean): Promise<void>; resolveTokenWhenAvailable<T>(id: ServiceIdentifier<T>): Promise<T>; resolveInstance<T>(id: ServiceIdentifier<T>): T; materializedInstance<T>(id: ServiceIdentifier<T>): T | undefined; liveRef<T>(id: ServiceIdentifier<T>): LiveRef<T>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any recordInstanceEdge(node: object | undefined, id: ServiceIdentifier<any>): void; collectionView<T>(token: CollectionToken<T>): CollectionView<T>; addCollectionRecord<T>( @@ -175,6 +218,7 @@ export interface FiberHost { providerBook: Ledger, value: T, ): () => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructService<T>(ctor: new (...args: any[]) => T, config: unknown): T; } @@ -187,6 +231,7 @@ export interface TokenProvideCore { export type FiberEventResolver = ( host: FiberHost, event: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any handler: (e: any) => void, ) => IDisposable; @@ -201,6 +246,7 @@ export function bindServiceUnit(instance: UnitInternals & IDisposable, frame: Co if (buffer === null) { return; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any const ctor = (instance as any).constructor as ServiceClassRecipe; const runtime = new FiberRuntime( frame.host, @@ -270,7 +316,9 @@ export class FiberRuntime implements Fiber { private readonly _book: Ledger, readonly name: string, readonly config: unknown, + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _token: ServiceIdentifier<any> | undefined, + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _declared: ReadonlySet<ServiceIdentifier<any>>, private readonly _edgeNode: object | undefined, ) {} @@ -291,7 +339,9 @@ export class FiberRuntime implements Fiber { provide(recipe: ServiceRecipe, opts?: FiberProvideOptions): FiberHandle; provide<T>(token: CollectionToken<T>, value: T): FiberHandle; provide( + // eslint-disable-next-line @typescript-eslint/no-explicit-any first: ServiceIdentifier<any> | ServiceRecipe | CollectionToken<any>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any second?: any, third?: FiberProvideOptions, ): FiberHandle { @@ -334,6 +384,7 @@ export class FiberRuntime implements Fiber { }); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter<any>, handler: (e: any) => void): FiberHandle { let subscription: IDisposable; if (typeof event === 'string') { @@ -392,6 +443,7 @@ export class FiberRuntime implements Fiber { const config = validateConfig(recipe.Config, opts?.config, name); const core = this._host.provideToken( id, + // eslint-disable-next-line @typescript-eslint/no-explicit-any new SyncDescriptor<T>(recipe as new (...args: any[]) => T), { activation: opts?.activation === ScopeActivation.OnDemand ? 'ondemand' : 'eager', diff --git a/packages/agent-core-v2/src/_base/di/graph.ts b/packages/agent-core-v2/src/_base/di/graph.ts index e137209d7..b4d10d9ab 100644 --- a/packages/agent-core-v2/src/_base/di/graph.ts +++ b/packages/agent-core-v2/src/_base/di/graph.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — directed `Graph` with cycle detection for DI instantiation. + */ + export class Node<T> { readonly incoming = new Map<string, Node<T>>(); readonly outgoing = new Map<string, Node<T>>(); diff --git a/packages/agent-core-v2/src/_base/di/instantiation.ts b/packages/agent-core-v2/src/_base/di/instantiation.ts index 7adc73615..370dad62f 100644 --- a/packages/agent-core-v2/src/_base/di/instantiation.ts +++ b/packages/agent-core-v2/src/_base/di/instantiation.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — service identifiers, `createDecorator`, and the `IInstantiationService` contract. + */ + import type { SyncDescriptor, SyncDescriptor0 } from './descriptors'; import type { CascadeEngine } from './cascadeEngine'; import type { Event } from '../event'; @@ -6,12 +10,15 @@ import type { ServiceCollection } from './serviceCollection'; export type DependencyKind = 'instance' | 'collection' | 'ref'; +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace _util { + // eslint-disable-next-line @typescript-eslint/no-explicit-any export const serviceIds = new Map<string, ServiceIdentifier<any>>(); export const DI_TARGET = '$di$target'; export const DI_DEPENDENCIES = '$di$dependencies'; export interface ServiceDependency { + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly id: ServiceIdentifier<any>; readonly index: number; readonly kind: DependencyKind; @@ -31,8 +38,11 @@ export namespace _util { ); } + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type export interface DI_TARGET_OBJ extends Function { + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type [DI_TARGET]: Function; + // eslint-disable-next-line @typescript-eslint/no-explicit-any [DI_DEPENDENCIES]: { id: ServiceIdentifier<any>; index: number; kind: DependencyKind }[]; } } @@ -43,12 +53,14 @@ export interface IConstructorSignature<T, Args extends any[] = []> { new <Services extends BrandedService[]>(...args: [...Args, ...Services]): T; } +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type GetLeadingNonServiceArgs<TArgs extends any[]> = TArgs extends [] ? [] : TArgs extends [...infer TFirst, BrandedService] ? GetLeadingNonServiceArgs<TFirst> : TArgs; export interface ServiceIdentifier<T> { + // eslint-disable-next-line @typescript-eslint/no-explicit-any (target: any, key: string | symbol | undefined, index: number): void; readonly type: T; @@ -57,7 +69,9 @@ export interface ServiceIdentifier<T> { } function storeServiceDependency( + // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier<any>, + // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type target: Function, index: number, kind: DependencyKind = 'instance', @@ -72,8 +86,10 @@ function storeServiceDependency( } export function storeCustomDependency( + // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier<any>, kind: DependencyKind, + // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, index: number, ): void { @@ -87,6 +103,7 @@ export function createDecorator<T>(name: string): ServiceIdentifier<T> { } const id = function serviceDecorator( + // eslint-disable-next-line @typescript-eslint/no-explicit-any target: any, _key: string | symbol | undefined, index: number, @@ -113,6 +130,10 @@ export function createDecorator<T>(name: string): ServiceIdentifier<T> { return id; } +export function lookupServiceDecorator(name: string): ServiceIdentifier<unknown> | undefined { + return _util.serviceIds.get(name); +} + const SERVICE_IDENTIFIER_MARK = Symbol('serviceIdentifier'); export function isServiceIdentifier(thing: unknown): thing is ServiceIdentifier<unknown> { @@ -141,6 +162,7 @@ export interface LiveRef<T> { export function ref<T>( id: ServiceIdentifier<T>, ): (target: object, key: string | symbol | undefined, index: number) => void { + // eslint-disable-next-line @typescript-eslint/no-explicit-any return function refDecorator(target: any, _key: string | symbol | undefined, index: number): void { if (arguments.length !== 3) { throw new Error('@ref-decorator can only be used to decorate a parameter'); @@ -177,9 +199,11 @@ export interface IInstantiationService { fn: (accessor: ServicesAccessor, ...args: TS) => R, ...args: TS ): R; + // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance<T>(descriptor: SyncDescriptor0<T>): T; createInstance< Ctor extends new ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...args: any[] ) => unknown, R extends InstanceType<Ctor>, @@ -196,17 +220,20 @@ export interface IInstantiationService { provideAll(entries: ReadonlyArray<ProvideAllEntry>): void; unprovide<T>(id: ServiceIdentifier<T>): void; dispose(): void; - disposeAsync(): Promise<void>; } export const IInstantiationService: ServiceIdentifier<IInstantiationService> = createDecorator<IInstantiationService>('instantiationService'); export interface ServiceCollectionLike { + // eslint-disable-next-line @typescript-eslint/no-explicit-any set<T>(id: ServiceIdentifier<T>, instanceOrDescriptor: any): unknown; + // eslint-disable-next-line @typescript-eslint/no-explicit-any get<T>(id: ServiceIdentifier<T>): any; + // eslint-disable-next-line @typescript-eslint/no-explicit-any has(id: ServiceIdentifier<any>): boolean; forEach( + // eslint-disable-next-line @typescript-eslint/no-explicit-any callback: (id: ServiceIdentifier<any>, value: any) => void, ): void; } diff --git a/packages/agent-core-v2/src/_base/di/instantiationService.ts b/packages/agent-core-v2/src/_base/di/instantiationService.ts index cd3ca5272..5a4004291 100644 --- a/packages/agent-core-v2/src/_base/di/instantiationService.ts +++ b/packages/agent-core-v2/src/_base/di/instantiationService.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — `InstantiationService` container (instantiation, child scopes, cycle detection). + */ + import { SyncDescriptor } from './descriptors'; import { CascadeEngine, CascadeTree, type CascadeChange, type CascadeHost } from './cascadeEngine'; import { @@ -37,6 +41,7 @@ import { Ledger, type LedgerEntry } from '../lifecycle/ledger'; import type { Disposer } from '../lifecycle/disposer'; import { ServiceCollection } from './serviceCollection'; +// eslint-disable-next-line @typescript-eslint/no-unused-vars const enum TraceType { None = 0, Creation = 1, @@ -53,6 +58,7 @@ export class Trace { override branch() { return this; } }; + // eslint-disable-next-line @typescript-eslint/no-explicit-any static traceInvocation(_enableTracing: boolean, fn: any): Trace { return !_enableTracing ? Trace._None @@ -62,12 +68,14 @@ export class Trace { ); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any static traceCreation(_enableTracing: boolean, ctor: any): Trace { return !_enableTracing ? Trace._None : new Trace(TraceType.Creation, ctor.name); } private static _totals: number = 0; private readonly _start: number = Date.now(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _dep: [ServiceIdentifier<any>, boolean, Trace?][] = []; private constructor( @@ -75,6 +83,7 @@ export class Trace { readonly name: string | null ) { } + // eslint-disable-next-line @typescript-eslint/no-explicit-any branch(id: ServiceIdentifier<any>, first: boolean): Trace { const child = new Trace(TraceType.Branch, id.toString()); this._dep.push([id, first, child]); @@ -140,6 +149,7 @@ export class InstantiationService implements IInstantiationService { private readonly _instanceEntries = new Map<unknown, LedgerEntry>(); private readonly _provideEntries = new Map< + // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier<any>, { readonly entry: LedgerEntry; readonly core: TokenProvideCore } >(); @@ -148,14 +158,17 @@ export class InstantiationService implements IInstantiationService { protected readonly _children = new Set<InstantiationService>(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _inProgress: ServiceIdentifier<any>[] = []; + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _activeInstantiations = new Set<ServiceIdentifier<any>>(); private readonly _collectionStore: CollectionStore; private readonly _collectionViews = new Map< CollectionToken<unknown>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any CollectionViewImpl<any> >(); @@ -227,6 +240,7 @@ export class InstantiationService implements IInstantiationService { return (this._parent?.cascadeDepth ?? -1) + 1; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _ownerOf(id: ServiceIdentifier<any>): InstantiationService | undefined { if (this._services.has(id)) { return this; @@ -417,6 +431,7 @@ export class InstantiationService implements IInstantiationService { void this._unprovideCore(id); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _releaseProvideEntry(id: ServiceIdentifier<any>): void { const prev = this._provideEntries.get(id); if (prev !== undefined) { @@ -487,16 +502,13 @@ export class InstantiationService implements IInstantiationService { return this._ledger.register(disposer, label); } - anchorKernelFinalizer(disposer: Disposer, label: string): LedgerEntry { - return this._ledger.registerFinalizer(disposer, label); - } - private _getFiberHost(): FiberHost { this._fiberHost ??= { mintUid: () => ++this._root()._nextUnitUid, provideToken: (id, descriptor, options) => this._provideCore(id, descriptor, options), provideTokenInstance: <T>(id: ServiceIdentifier<T>, instance: T) => this._provideCore(id, instance, undefined), + // eslint-disable-next-line @typescript-eslint/no-explicit-any tokenState: (id: ServiceIdentifier<any>) => { const owner = this._ownerOf(id) ?? this; return owner.cascade.stateOf(id); @@ -518,6 +530,7 @@ export class InstantiationService implements IInstantiationService { materializedInstance: <T>(id: ServiceIdentifier<T>): T | undefined => this._materializedInstanceOf(id), liveRef: <T>(id: ServiceIdentifier<T>): LiveRef<T> => this._liveRef(id), + // eslint-disable-next-line @typescript-eslint/no-explicit-any recordInstanceEdge: (node: object | undefined, id: ServiceIdentifier<any>) => { if (node === undefined) { return; @@ -543,6 +556,7 @@ export class InstantiationService implements IInstantiationService { providerBook, value, ), + // eslint-disable-next-line @typescript-eslint/no-explicit-any constructService: <T>(ctor: new (...args: any[]) => T, config: unknown): T => { return this._createInstance(ctor, [], Trace.traceCreation(this._enableTracing, ctor), { config, @@ -608,10 +622,14 @@ export class InstantiationService implements IInstantiationService { return labels.join('/'); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance<T>(descriptor: SyncDescriptor<T>, ...rest: any[]): T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any createInstance<T>(ctor: new (...args: any[]) => T, ...rest: any[]): T; createInstance<T>( + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctorOrDescriptor: SyncDescriptor<T> | (new (...args: any[]) => T), + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...rest: any[] ): T { this._assertNotDisposed(); @@ -652,31 +670,18 @@ export class InstantiationService implements IInstantiationService { return new InstantiationService(services, this._strict, this, this._enableTracing); } - private _disposePromise: Promise<void> | undefined; - dispose(): void { - void this.disposeAsync(); - } - - disposeAsync(): Promise<void> { - this._disposePromise ??= this.disposeCore(); - return this._disposePromise; - } - - private disposeCore(): Promise<void> { if (this._disposed) { - return Promise.resolve(); + return; } this._disposed = true; - const childTeardowns: Promise<void>[] = []; - let teardown: void | Promise<void> = undefined; try { for (const child of Array.from(this._children)) { - childTeardowns.push(child.disposeAsync()); + child.dispose(); } this._children.clear(); - teardown = this._ledger.teardown('scope-close'); + void this._ledger.teardown('scope-close'); this._services.dispose(); this.cascade.dispose(); for (const view of this._collectionViews.values()) { @@ -691,10 +696,11 @@ export class InstantiationService implements IInstantiationService { this._parent._children.delete(this); } } - return Promise.all([...childTeardowns, Promise.resolve(teardown)]).then(() => undefined); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createInstance<T>(ctor: any, args: unknown[], _trace: Trace, unit?: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any id?: ServiceIdentifier<any>; config?: unknown; }): T { @@ -724,6 +730,7 @@ export class InstantiationService implements IInstantiationService { serviceDependencies.length > 0 ? serviceDependencies[0]!.index : args.length; if (args.length !== firstServiceArgPos) { + // eslint-disable-next-line no-console globalThis.console.trace( `[createInstance] First service dependency of ${(ctor as { name?: string }).name} at position ${firstServiceArgPos + 1} conflicts with ${args.length} static arguments`, ); @@ -748,6 +755,7 @@ export class InstantiationService implements IInstantiationService { pushConstructionFrame(frame); let instance: T; try { + // eslint-disable-next-line @typescript-eslint/no-explicit-any instance = Reflect.construct<unknown[], T>(ctor as new (...args: any[]) => T, finalArgs); } finally { popConstructionFrame(); @@ -806,6 +814,7 @@ export class InstantiationService implements IInstantiationService { desc: SyncDescriptor<T>, _trace: Trace, ): T { + // eslint-disable-next-line @typescript-eslint/no-explicit-any type Triple = { id: ServiceIdentifier<any>; desc: SyncDescriptor<any>; _trace: Trace }; const graph = new Graph<Triple>(data => data.id.toString()); @@ -878,6 +887,7 @@ export class InstantiationService implements IInstantiationService { private _createServiceInstanceWithOwner<T>( id: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: any, args: ReadonlyArray<unknown> = [], _trace: Trace, @@ -898,6 +908,7 @@ export class InstantiationService implements IInstantiationService { private _createServiceInstance<T>( id: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: any, args: ReadonlyArray<unknown> = [], _trace: Trace, @@ -966,6 +977,7 @@ export class InstantiationService implements IInstantiationService { private _getServiceInstanceOrDescriptor<T>( id: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ): T | SyncDescriptor<T> | undefined { const instanceOrDesc = this._services.get(id); if (instanceOrDesc === undefined && this._parent) { @@ -976,6 +988,7 @@ export class InstantiationService implements IInstantiationService { private _throwIfStrict(msg: string, printWarning: boolean): void { if (printWarning) { + // eslint-disable-next-line no-console globalThis.console.warn(msg); } if (this._strict) { diff --git a/packages/agent-core-v2/src/_base/di/lifecycle.ts b/packages/agent-core-v2/src/_base/di/lifecycle.ts index bc5020698..4cb5dc5d1 100644 --- a/packages/agent-core-v2/src/_base/di/lifecycle.ts +++ b/packages/agent-core-v2/src/_base/di/lifecycle.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — disposable lifecycle primitives (`Disposable`, `DisposableStore`, `IDisposable`). + */ + import { onUnexpectedError } from '../errors/unexpectedError'; import { Ledger, type LedgerEntry } from '../lifecycle/ledger'; @@ -336,6 +340,7 @@ export abstract class Disposable implements IDisposable { } } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Disposable { export const None: IDisposable = Object.freeze({ dispose(): void {}, @@ -555,6 +560,7 @@ export class DisposableMap<K, V extends IDisposable = IDisposable> set(key: K, value: V, skipDisposeOnOverwrite = false): void { if (this._isDisposed) { + // eslint-disable-next-line no-console console.warn( new Error( 'Trying to add a disposable to a DisposableMap that has already been disposed of. The added object will be leaked!', @@ -637,6 +643,7 @@ export class DisposableSet<V extends IDisposable = IDisposable> add(value: V): void { if (this._isDisposed) { + // eslint-disable-next-line no-console console.warn( new Error( 'Trying to add a disposable to a DisposableSet that has already been disposed of. The added object will be leaked!', diff --git a/packages/agent-core-v2/src/_base/di/scope.ts b/packages/agent-core-v2/src/_base/di/scope.ts index 4db1ae683..ced7a35f9 100644 --- a/packages/agent-core-v2/src/_base/di/scope.ts +++ b/packages/agent-core-v2/src/_base/di/scope.ts @@ -1,3 +1,14 @@ +/** + * `di` domain — DI Scope tree (`Scope`) and scoped service registry. + * + * Scoped services are resolved when their scope is created by default; + * registrations that defer construction until first resolution use `OnDemand`. + * + * The kernel only knows the scope tree and the `ScopeKind` partial order. + * The tier set is a business concept: the host bootstrap declares it through + * `setScopeTopology` (see `src/app/scopes.ts`). + */ + import { BugIndicatingError } from '../errors/errors'; import { SyncDescriptor } from './descriptors'; import { ScopeActivation, type ProvideAllEntry } from './instantiation'; @@ -40,23 +51,14 @@ export interface ScopedEntry { const _scopedRegistry: ScopedEntry[] = []; -function findScopedEntryIndex(scope: ScopeKind, id: ServiceIdentifier<unknown>): number { - return _scopedRegistry.findIndex((entry) => entry.scope === scope && entry.id === id); -} - export function registerScopedService<T>( scope: ScopeKind, id: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor: new (...args: any[]) => T, activation: ScopeActivation = ScopeActivation.OnScopeCreated, domain: string = 'unknown', ): void { - const existing = findScopedEntryIndex(scope, id as ServiceIdentifier<unknown>); - if (existing !== -1) { - throw new BugIndicatingError( - `duplicate scoped service registration for '${String(id)}' in scope '${scope}' (registered domain '${_scopedRegistry[existing]?.domain}', attempted domain '${domain}'); use overrideScopedService for intentional replacement`, - ); - } const descriptor = new SyncDescriptor<T>(ctor); _scopedRegistry.push({ scope, @@ -67,29 +69,6 @@ export function registerScopedService<T>( }); } -export function overrideScopedService<T>( - scope: ScopeKind, - id: ServiceIdentifier<T>, - ctor: new (...args: any[]) => T, - activation: ScopeActivation = ScopeActivation.OnScopeCreated, - domain: string = 'unknown', -): void { - const index = findScopedEntryIndex(scope, id as ServiceIdentifier<unknown>); - if (index === -1) { - throw new BugIndicatingError( - `overrideScopedService found no registration for '${String(id)}' in scope '${scope}' (domain '${domain}'); use registerScopedService for the initial registration`, - ); - } - const descriptor = new SyncDescriptor<T>(ctor); - _scopedRegistry[index] = { - scope, - id: id as ServiceIdentifier<unknown>, - descriptor: descriptor as SyncDescriptor<unknown>, - domain, - activation, - }; -} - export function getScopedServiceDescriptors(scope: ScopeKind): ReadonlyArray<ScopedEntry> { return _scopedRegistry.filter((entry) => entry.scope === scope); } @@ -99,6 +78,7 @@ export function _clearScopedRegistryForTests(): void { } export type ScopeSeed = ReadonlyArray< + // eslint-disable-next-line @typescript-eslint/no-explicit-any readonly [ServiceIdentifier<any>, unknown] >; @@ -112,10 +92,11 @@ export interface IScopeHandle<K extends ScopeKind = ScopeKind> { readonly id: string; readonly kind: K; readonly accessor: ServicesAccessor; - dispose(): void | Promise<void>; + dispose(): void; } export type IAppScopeHandle = IScopeHandle<'app'>; +export type IWorkspaceScopeHandle = IScopeHandle<'workspace'>; export type ISessionScopeHandle = IScopeHandle<'session'>; export type IAgentScopeHandle = IScopeHandle<'agent'>; @@ -171,7 +152,7 @@ export function createScopedChildHandle( get: <T>(serviceId: ServiceIdentifier<T>): T => child.invokeFunction((a) => a.get(serviceId)), }; - return { id, kind, accessor, dispose: () => child.disposeAsync() }; + return { id, kind, accessor, dispose: () => child.dispose() }; } export class Scope implements IDisposable { diff --git a/packages/agent-core-v2/src/_base/di/scopeUnits.ts b/packages/agent-core-v2/src/_base/di/scopeUnits.ts index db02af075..7fd6688a4 100644 --- a/packages/agent-core-v2/src/_base/di/scopeUnits.ts +++ b/packages/agent-core-v2/src/_base/di/scopeUnits.ts @@ -1,3 +1,31 @@ +/** + * `di` domain — the kernel-side `ScopeUnits(kind)` fold (L3, D11/G2). + * + * `ScopeUnits(kind)` is the materialization collection token the kernel mints + * per scope kind. When a scope of that kind is created, this fold watches the + * new scope's live view of the token and materializes every record's recipe + * as a unit INSIDE that scope (cross-scope materialization): a feature + * contributed once at App scope becomes one live unit per Session/Agent + * scope, automatically. + * + * Lifetime rules (per §5.6): + * - the materialized unit's disposal hangs on the RECORD PROVIDER's book — + * disposing the provider retracts the record and tears the materialized + * units down across the tree (连坐); + * - a target scope's natural death tears its materialized units down with it + * (the fold ledger is anchored into the scope's container ledger); both + * anchors are idempotent, so a provider dying mid-teardown is a no-op; + * - records visible at creation are materialized immediately; the view's + * incremental changes reconcile the set by record identity. + * + * A materialized unit's own `this.provide(...)` registrations are ordinary + * token provides in the target scope — they join the graph and cascades as + * usual. The materialized unit itself carries no token identity, so its own + * constructor dependencies do not independently join cascades (feature + * recipes are dependency-free assemblies by convention, per the Plan + * sample); its provided tokens fully participate. + */ + import { onUnexpectedError } from '../errors/unexpectedError'; import type { IDisposable } from './lifecycle'; import { Ledger } from '../lifecycle/ledger'; @@ -22,7 +50,7 @@ export function watchScopeUnits(container: InstantiationService, kind: ScopeKind const foldLedger = new Ledger(`scope-units:${kind}`); container.anchorKernelEntry((reason) => foldLedger.teardown(reason), `scope-units:${kind}`); - const materialized = new Map<number, () => void | Promise<void>>(); + const materialized = new Map<number, () => void>(); const materialize = (record: StoredRecord): void => { const recipe = record.value as ServiceRecipe; @@ -32,7 +60,7 @@ export function watchScopeUnits(container: InstantiationService, kind: ScopeKind if (isClassRecipe(recipe)) { const instance = host.constructService(recipe, undefined) as Partial<IDisposable>; unitLedger.register(() => { - return instance.dispose?.(); + instance.dispose?.(); }, `unit:${name}`); } else { const facade = new FiberRuntime( @@ -57,23 +85,23 @@ export function watchScopeUnits(container: InstantiationService, kind: ScopeKind } let retracted = false; - const retract = (): void | Promise<void> => { + const retract = (): void => { if (retracted) { - return undefined; + return; } retracted = true; materialized.delete(record.id); - return unitLedger.teardown('unload'); + void unitLedger.teardown('unload'); }; if (!record.providerBook.isActive) { - void retract(); + retract(); return; } record.providerBook.register(() => { - void retract(); + retract(); }, `scope-units:${kind}`); foldLedger.register(() => { - return retract(); + retract(); }, `record:${name}`); materialized.set(record.id, retract); }; @@ -90,9 +118,10 @@ export function watchScopeUnits(container: InstantiationService, kind: ScopeKind materialize(record); } } + // Snapshot: `retract()` deletes its own entry from `materialized`. for (const [id, retract] of Array.from(materialized)) { if (!seen.has(id)) { - void retract(); + retract(); } } }; diff --git a/packages/agent-core-v2/src/_base/di/service.ts b/packages/agent-core-v2/src/_base/di/service.ts index 66d61583a..c7c30e74c 100644 --- a/packages/agent-core-v2/src/_base/di/service.ts +++ b/packages/agent-core-v2/src/_base/di/service.ts @@ -1,3 +1,25 @@ +/** + * `di` domain — the `Service` base class for L3 unit recipes. + * + * Extending `Service` turns a class into a unit recipe with the five `Fiber` + * capabilities (`this.provide` / `effect` / `on` / `get` / `ref`). The class + * follows the two-phase construction protocol: inside the constructor — when + * the container builds the instance under a matching `ConstructionFrame` — + * capability calls do not run immediately; they are buffered as + * `BufferedOp`s and answered with `PendingFiberHandle`s, then flushed + * against the real `FiberRuntime` by `bindServiceUnit` right after + * construction (`fiber.ts`). Reads (`get` / `ref`) are forbidden during this + * phase — declare dependencies as constructor parameters instead (构造期只写 + * 不读). A `Service` created by manual `new` never gets a bound runtime, and + * its capability calls throw `FiberProtocolError`. + * + * The `SERVICE_MARK` prototype marker (set below) lets the container + * recognize `Service`-derived class recipes and drive them through this + * protocol; services whose members collide with the `Service` vocabulary + * keep `extends Disposable` and use the function/object recipe forms + * instead. + */ + import type { Emitter } from '../event'; import type { EffectBody } from '../lifecycle/disposer'; import type { Ledger } from '../lifecycle/ledger'; @@ -34,6 +56,7 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals const frame = currentConstruction(); if ( frame !== undefined && + // eslint-disable-next-line @typescript-eslint/no-explicit-any frame.ctor === (new.target as unknown as new (...args: any[]) => any) ) { this.__unitBuffer = []; @@ -42,6 +65,7 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals this.__unitBuffer = null; this.config = undefined; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any this.name = (this.constructor as any).name || 'anonymous'; } @@ -54,7 +78,9 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals provide(recipe: ServiceRecipe, opts?: FiberProvideOptions): FiberHandle; provide<T>(token: CollectionToken<T>, value: T): FiberHandle; provide( + // eslint-disable-next-line @typescript-eslint/no-explicit-any first: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any second?: any, third?: FiberProvideOptions, ): FiberHandle { @@ -79,6 +105,7 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals return this._runtime().effect(body, label); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any on(event: string | Emitter<any>, handler: (e: any) => void): FiberHandle { const label = typeof event === 'string' ? `on:${event}` : 'on:emitter'; if (this.__unitBuffer !== null) { @@ -127,6 +154,7 @@ export abstract class Service extends Disposable implements Fiber, UnitInternals return this.__unitRuntime; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _pendingName(first: any): string { if (typeof first === 'function') { return (first as RecipeStatics).name ?? String(first); diff --git a/packages/agent-core-v2/src/_base/di/serviceCollection.ts b/packages/agent-core-v2/src/_base/di/serviceCollection.ts index ba8550eb6..b553fbf63 100644 --- a/packages/agent-core-v2/src/_base/di/serviceCollection.ts +++ b/packages/agent-core-v2/src/_base/di/serviceCollection.ts @@ -1,3 +1,12 @@ +/** + * `di` domain — `ServiceCollection`: the dynamic registry (L1). + * + * Maps a service id to its recipe (`SyncDescriptor`) or materialized instance. + * Every write stamps the entry with a container-monotonic `uid` (a generation + * marker used for introspection and history — it plays no role in change + * detection) and fires the token's availability event with `{ oldUid, newUid }`. + */ + import { Emitter } from '../event'; import { SyncDescriptor } from './descriptors'; import type { ServiceIdentifier } from './instantiation'; @@ -16,14 +25,17 @@ export interface AvailabilityChange { } export class ServiceCollection { + // eslint-disable-next-line @typescript-eslint/no-explicit-any private readonly _entries = new Map<ServiceIdentifier<any>, ServiceCollectionEntry<any>>(); private readonly _emitters = new Map< + // eslint-disable-next-line @typescript-eslint/no-explicit-any ServiceIdentifier<any>, Emitter<AvailabilityChange> >(); private _nextUid = 0; constructor( + // eslint-disable-next-line @typescript-eslint/no-explicit-any ...entries: ReadonlyArray<readonly [ServiceIdentifier<any>, unknown]> ) { for (const [id, value] of entries) { @@ -90,14 +102,17 @@ export class ServiceCollection { return prev.value as T | SyncDescriptor<T> | undefined; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any entry(id: ServiceIdentifier<any>): ServiceCollectionEntry | undefined { return this._entries.get(id); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any uidOf(id: ServiceIdentifier<any>): number | undefined { return this._entries.get(id)?.uid; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any configOf(id: ServiceIdentifier<any>): unknown { return this._entries.get(id)?.config; } @@ -109,6 +124,7 @@ export class ServiceCollection { return this._emitterFor(id).event(listener); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any has(id: ServiceIdentifier<any>): boolean { return this._entries.has(id); } @@ -119,6 +135,7 @@ export class ServiceCollection { forEach( callback: ( + // eslint-disable-next-line @typescript-eslint/no-explicit-any id: ServiceIdentifier<any>, value: unknown, ) => void, diff --git a/packages/agent-core-v2/src/_base/di/test.ts b/packages/agent-core-v2/src/_base/di/test.ts index 5b41a4e68..d861e7115 100644 --- a/packages/agent-core-v2/src/_base/di/test.ts +++ b/packages/agent-core-v2/src/_base/di/test.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — scoped test host and service-stub helpers for DI domain tests. + */ + export { createServices, TestInstantiationService, @@ -9,7 +13,7 @@ export type { } from './testInstantiationService'; import { type ServiceIdentifier } from './instantiation'; -import { createAppScope, createScopedChildHandle, Scope, type ScopeKind, type ScopeSeed } from './scope'; +import { createAppScope, Scope, type ScopeKind, type ScopeSeed } from './scope'; export interface ScopedTestHost { readonly app: Scope; @@ -23,17 +27,6 @@ export function createScopedTestHost(appStubs: ScopeSeed = []): ScopedTestHost { return { app, child(kind, id, stubs = []) { - if (kind === 'program') { - const handle = createScopedChildHandle(app.instantiation, kind, id, { seeds: stubs }); - return { - id: handle.id, - kind: handle.kind, - accessor: handle.accessor, - dispose: () => { - void handle.dispose(); - }, - } as Scope; - } return app.createChild(kind, id, { seeds: stubs }); }, childOf(parent, kind, id, stubs = []) { diff --git a/packages/agent-core-v2/src/_base/di/testInstantiationService.ts b/packages/agent-core-v2/src/_base/di/testInstantiationService.ts index aaa07a175..f7fb86aa6 100644 --- a/packages/agent-core-v2/src/_base/di/testInstantiationService.ts +++ b/packages/agent-core-v2/src/_base/di/testInstantiationService.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — `TestInstantiationService` and scoped test-container helpers. + */ + import * as sinon from 'sinon'; import { SyncDescriptor, type SyncDescriptor0 } from './descriptors'; @@ -10,10 +14,12 @@ import { InstantiationService, Trace } from './instantiationService'; import { DisposableStore, dispose, isDisposable, toDisposable, type IDisposable } from './lifecycle'; import { ServiceCollection } from './serviceCollection'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any type AnyConstructor<T = unknown> = new (...args: any[]) => T; interface IServiceMock<T> { id: ServiceIdentifier<T>; + // eslint-disable-next-line @typescript-eslint/no-explicit-any service?: any; } @@ -73,6 +79,7 @@ export class TestInstantiationService extends InstantiationService implements ID ...args: GetLeadingNonServiceArgs<ConstructorParameters<Ctor>> ): R; public override createInstance( + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctorOrDescriptor: any, ...rest: unknown[] ): unknown { @@ -109,8 +116,10 @@ export class TestInstantiationService extends InstantiationService implements ID ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stub<T>( id: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg2: any, arg3?: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg4?: any, ): T | SyncDescriptor<T> | sinon.SinonStub | sinon.SinonSpy { if (arg2 instanceof SyncDescriptor && typeof arg3 !== 'string') { @@ -147,24 +156,31 @@ export class TestInstantiationService extends InstantiationService implements ID public stubPromise<T>( id?: ServiceIdentifier<T>, fnProperty?: string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any value?: any, ): T | sinon.SinonStub; public stubPromise<T, V>( id?: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any ctor?: any, fnProperty?: string, value?: V, ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stubPromise<T, V>( id?: ServiceIdentifier<T>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any obj?: any, fnProperty?: string, value?: V, ): V extends Function ? sinon.SinonSpy : sinon.SinonStub; public stubPromise( + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg1?: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg2?: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg3?: any, + // eslint-disable-next-line @typescript-eslint/no-explicit-any arg4?: any, ): unknown { arg3 = typeof arg2 === 'string' ? Promise.resolve(arg3) : arg3; @@ -179,7 +195,9 @@ export class TestInstantiationService extends InstantiationService implements ID } private _create<T>(serviceMock: IServiceMock<T>, options: SinonOptions, reset?: boolean): T; + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _create<T>(ctor: any, options: SinonOptions): T | sinon.SinonMock; + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _create(arg1: any, options: SinonOptions, reset: boolean = false): any { if (this._isServiceMock(arg1)) { const service = this._getOrCreateService(arg1, options, reset); @@ -220,6 +238,7 @@ export class TestInstantiationService extends InstantiationService implements ID return service as T; } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createStub(arg: any): any { if (arg instanceof SyncDescriptor) { return sinon.createStubInstance(arg.ctor); @@ -233,6 +252,7 @@ export class TestInstantiationService extends InstantiationService implements ID return Object.create(null); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _createReplacement(value: any): sinon.SinonStub | sinon.SinonSpy { if (typeof value === 'function') { return isSinonSpyLike(value) ? value : sinon.spy(value); @@ -240,10 +260,12 @@ export class TestInstantiationService extends InstantiationService implements ID return value ? sinon.stub().returns(value) : sinon.stub(); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _hasSinonOption(service: any, key: keyof SinonOptions): boolean { return Boolean(service?.sinonOptions?.[key]); } + // eslint-disable-next-line @typescript-eslint/no-explicit-any private _isServiceMock(arg: any): arg is IServiceMock<unknown> { return typeof arg === 'object' && arg !== null && 'id' in arg; } @@ -262,14 +284,6 @@ export class TestInstantiationService extends InstantiationService implements ID super.dispose(); } } - - public override disposeAsync(): Promise<void> { - sinon.restore(); - if (this._properDispose) { - return super.disposeAsync(); - } - return Promise.resolve(); - } } interface SinonOptions { @@ -278,6 +292,7 @@ interface SinonOptions { } export interface ServiceRegistration { + // eslint-disable-next-line @typescript-eslint/no-explicit-any define<T>(id: ServiceIdentifier<T>, ctor: new (...args: any[]) => T): void; defineInstance<T>(id: ServiceIdentifier<T>, instance: T): void; definePartialInstance<T>(id: ServiceIdentifier<T>, instance: Partial<T>): void; @@ -296,6 +311,7 @@ export function createServices( options: CreateServicesOptions = {}, ): TestInstantiationService { const serviceCollection = new ServiceCollection(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any const instanceIds = new Set<ServiceIdentifier<any>>(); const register = <T>( diff --git a/packages/agent-core-v2/src/_base/di/util/linkedList.ts b/packages/agent-core-v2/src/_base/di/util/linkedList.ts index 4ae8b60a6..625208058 100644 --- a/packages/agent-core-v2/src/_base/di/util/linkedList.ts +++ b/packages/agent-core-v2/src/_base/di/util/linkedList.ts @@ -1,3 +1,7 @@ +/** + * `di` domain — `LinkedList` with O(1) push/removal for parked event listeners. + */ + class Node<E> { static readonly Undefined = new Node<unknown>(undefined); diff --git a/packages/agent-core-v2/src/_base/errors/codes.ts b/packages/agent-core-v2/src/_base/errors/codes.ts index c10012fad..e6fd5aabf 100644 --- a/packages/agent-core-v2/src/_base/errors/codes.ts +++ b/packages/agent-core-v2/src/_base/errors/codes.ts @@ -1,3 +1,12 @@ +/** + * `errors` domain (cross-cutting) — error-code contract, runtime registry, and + * metadata backing serialization. + * + * Owns the `ErrorDomain` contract every business domain uses to contribute its + * codes, the registry (`registerErrorDomain` / `errorInfo` / `isErrorCode`), + * and the domain-independent core codes (`internal`, `not_implemented`). + */ + export interface ErrorInfo { readonly title: string; readonly retryable: boolean; diff --git a/packages/agent-core-v2/src/_base/errors/errorMessage.ts b/packages/agent-core-v2/src/_base/errors/errorMessage.ts index d30f2ea6b..de1230a7e 100644 --- a/packages/agent-core-v2/src/_base/errors/errorMessage.ts +++ b/packages/agent-core-v2/src/_base/errors/errorMessage.ts @@ -1,3 +1,7 @@ +/** + * Render thrown values as human-readable lines for logs and CLI output. + */ + import { isCodedError } from './serialize'; export function toErrorMessage(error: unknown, verbose = false): string { diff --git a/packages/agent-core-v2/src/_base/errors/errors.ts b/packages/agent-core-v2/src/_base/errors/errors.ts index 88b1ce272..d5cd7cebe 100644 --- a/packages/agent-core-v2/src/_base/errors/errors.ts +++ b/packages/agent-core-v2/src/_base/errors/errors.ts @@ -1,3 +1,8 @@ +/** + * Base error classes shared by every domain — `Error2` and related + * control-flow errors. + */ + import { CoreErrors } from './codes'; import type { ErrorCode } from '#/errors'; diff --git a/packages/agent-core-v2/src/_base/errors/serialize.ts b/packages/agent-core-v2/src/_base/errors/serialize.ts index 2176204e1..5b6ad0b40 100644 --- a/packages/agent-core-v2/src/_base/errors/serialize.ts +++ b/packages/agent-core-v2/src/_base/errors/serialize.ts @@ -1,3 +1,13 @@ +/** + * `errors` domain (cross-cutting) — wire serialization of thrown values. + * + * Converts between thrown values and the portable `ErrorPayload` that crosses + * process / language boundaries, recursively through the `cause` chain. Knows + * only coded errors and the core codes: business-domain translation (e.g. + * provider API errors) happens at the owning domain's boundary before errors + * reach this layer, so `_base/errors` never imports a business domain. + */ + import { CoreErrors, errorInfo, isErrorCode } from './codes'; import type { ErrorCode } from '#/errors'; import { Error2 } from './errors'; diff --git a/packages/agent-core-v2/src/_base/errors/unexpectedError.ts b/packages/agent-core-v2/src/_base/errors/unexpectedError.ts index 3d1dcdedb..8b55d0265 100644 --- a/packages/agent-core-v2/src/_base/errors/unexpectedError.ts +++ b/packages/agent-core-v2/src/_base/errors/unexpectedError.ts @@ -1,6 +1,12 @@ +/** + * Unexpected-error reporting hook (`onUnexpectedError`) — surfaces exceptions + * thrown by listener callbacks. + */ + export type UnexpectedErrorHandler = (err: unknown) => void; const defaultHandler: UnexpectedErrorHandler = (err) => { + // eslint-disable-next-line no-console console.error('[unexpected]', err); }; @@ -18,6 +24,7 @@ export function onUnexpectedError(err: unknown): void { try { currentHandler(err); } catch (handlerErr) { + // eslint-disable-next-line no-console console.error('[unexpected] handler threw', handlerErr, 'while reporting', err); } } diff --git a/packages/agent-core-v2/src/_base/event.ts b/packages/agent-core-v2/src/_base/event.ts index 1c53bb85a..35b0559cc 100644 --- a/packages/agent-core-v2/src/_base/event.ts +++ b/packages/agent-core-v2/src/_base/event.ts @@ -1,3 +1,14 @@ +/** + * `event` domain — `Event` / `Emitter` primitives, the async + * `AsyncEmitter` / `IWaitUntil` participation primitive (for interceptable + * `onWill` events whose listeners register work via `waitUntil`), the + * `handleVetos` helper (for `onBefore*` veto events whose listeners answer + * with `veto(value, id)`), and event combinators (`once` / `map` / `filter` + * / `any`). `Emitter` accepts an optional debug name that its + * `EventSubscription` carries as an `on:<name>` ledger label, so event + * subscriptions stay identifiable in unit-book introspection. + */ + import { onUnexpectedError, safelyCallListener } from './errors/unexpectedError'; import { Disposable, @@ -112,24 +123,6 @@ export type IWaitUntilData<T> = Omit<T, 'waitUntil' | 'signal'>; export class AsyncEmitter<T extends IWaitUntil> extends Emitter<T> { private _asyncDeliveryQueue?: LinkedList<[(event: T) => void, IWaitUntilData<T>]>; - async fireAsyncConcurrent(data: IWaitUntilData<T>, signal: AbortSignal): Promise<void> { - if (this.isDisposed || this._listeners === undefined || signal.aborted) { - return; - } - const snapshot = Array.from(this._listeners); - await Promise.all( - snapshot.map((entry) => - this.deliverAsync( - (event) => { - entry.listener.call(entry.thisArg, event); - }, - data, - signal, - ), - ), - ); - } - async fireAsync(data: IWaitUntilData<T>, signal: AbortSignal): Promise<void> { if (this.isDisposed || this._listeners === undefined) { return; @@ -147,37 +140,32 @@ export class AsyncEmitter<T extends IWaitUntil> extends Emitter<T> { while (this._asyncDeliveryQueue.size > 0 && !signal.aborted) { const [deliver, eventData] = this._asyncDeliveryQueue.shift()!; - await this.deliverAsync(deliver, eventData, signal); - } - } + const thenables: Promise<unknown>[] = []; - private async deliverAsync( - deliver: (event: T) => void, - data: IWaitUntilData<T>, - signal: AbortSignal, - ): Promise<void> { - const thenables: Promise<unknown>[] = []; - const event = { - ...data, - signal, - waitUntil: (p: Promise<unknown>): void => { - if (Object.isFrozen(thenables)) { - throw new Error('waitUntil can NOT be called asynchronously'); + const event = { + ...eventData, + signal, + waitUntil: (p: Promise<unknown>): void => { + if (Object.isFrozen(thenables)) { + throw new Error('waitUntil can NOT be called asynchronously'); + } + thenables.push(p); + }, + } as T; + + try { + deliver(event); + } catch (error) { + onUnexpectedError(error); + continue; + } + + void Object.freeze(thenables); + const settled = await Promise.allSettled(thenables); + for (const result of settled) { + if (result.status === 'rejected') { + onUnexpectedError(result.reason); } - thenables.push(p); - }, - } as T; - try { - deliver(event); - } catch (error) { - onUnexpectedError(error); - return; - } - void Object.freeze(thenables); - const settled = await Promise.allSettled(thenables); - for (const result of settled) { - if (result.status === 'rejected') { - onUnexpectedError(result.reason); } } } @@ -219,6 +207,7 @@ export function handleVetos( return Promise.allSettled(promises).then(() => lazyValue); } +// eslint-disable-next-line @typescript-eslint/no-namespace export namespace Event { export const None: Event<unknown> = () => Disposable.None; diff --git a/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts b/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts index 00ed8dece..a89a60527 100644 --- a/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts +++ b/packages/agent-core-v2/src/_base/execEnv/bufferedReadable.ts @@ -1,3 +1,12 @@ +/** + * `_base/execEnv` — `BufferedReadable` stream helper. + * + * A `Readable` wrapper that preserves source backpressure while still allowing + * consumers to read buffered output after the source has ended. Used by process + * spawners so `wait()`-then-read on small/medium outputs works without draining + * unboundedly. Kept as a pure helper with no DI dependencies. + */ + import { Readable } from 'node:stream'; export class BufferedReadable extends Readable { diff --git a/packages/agent-core-v2/src/_base/execEnv/decodeText.ts b/packages/agent-core-v2/src/_base/execEnv/decodeText.ts index 2f0a12908..543a83c82 100644 --- a/packages/agent-core-v2/src/_base/execEnv/decodeText.ts +++ b/packages/agent-core-v2/src/_base/execEnv/decodeText.ts @@ -1,3 +1,11 @@ +/** + * `_base/execEnv` — Python-compatible text decoding with `errors` handling. + * + * Reads text with the same `strict`/`replace`/`ignore` semantics Python's + * `open(..., errors=)` provides. Kept as a pure helper with no DI + * dependencies. + */ + export type TextDecodeErrors = 'strict' | 'replace' | 'ignore'; function isUtf8Continuation(byte: number): boolean { @@ -127,6 +135,7 @@ export function decodeTextWithErrors( ignoreBOM: boolean = false, ): string { let webLabel: string | undefined; + // eslint-disable-next-line typescript-eslint/switch-exhaustiveness-check switch (encoding) { case 'utf-8': case 'utf8': diff --git a/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts b/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts index 6f8618551..a9c4e5ffc 100644 --- a/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts +++ b/packages/agent-core-v2/src/_base/execEnv/environmentProbe.ts @@ -1,3 +1,22 @@ +/** + * `_base/execEnv` — OS / shell probe. + * + * Detects the host operating system, architecture, kernel release, and a + * usable POSIX shell path. The result is a pure function of injected probes + * (`platform` / `arch` / `release` / `env` / `isFile` / `execFileText`) so the + * same suite runs identically on any host OS. `probeHostEnvironmentFromNode()` + * bundles the Node defaults for production callers and memoises the promise. + * + * On Windows the probe expects bash from Git for Windows or MSYS2. If no + * shell can be located the function throws `ProbeShellNotFoundError`, a + * distinct type carrying the checked paths (`checked`) with an install hint + * in its message, so the DI boundary can tell a missing shell apart from + * other probe errors and translate it into a coded error. Set + * `KIMI_SHELL_PATH` to override. + * + * Kept as a pure helper with no DI dependencies. + */ + import { execFile as nodeExecFile } from 'node:child_process'; import { constants as fsConstants } from 'node:fs'; import { access } from 'node:fs/promises'; diff --git a/packages/agent-core-v2/src/_base/execEnv/globPattern.ts b/packages/agent-core-v2/src/_base/execEnv/globPattern.ts index 4efd1eb02..6dc9db8b8 100644 --- a/packages/agent-core-v2/src/_base/execEnv/globPattern.ts +++ b/packages/agent-core-v2/src/_base/execEnv/globPattern.ts @@ -1,3 +1,15 @@ +/** + * `_base/execEnv` — glob-pattern-to-regex conversion. + * + * Pure function. Mirrors Python pathlib semantics: includes dotfiles, + * case-sensitive by default. + */ + +/** + * Convert a single glob pattern segment (e.g. `"*.txt"`, `"file?.log"`) into + * a RegExp. `*` matches any run of non-`/` characters; `?` matches any single + * non-`/` character; `[abc]` matches one of a set (leading `!` negates). + */ export function globPatternToRegex(pattern: string, caseSensitive: boolean): RegExp { let regex = '^'; for (let i = 0; i < pattern.length; i++) { diff --git a/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts b/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts index b72c4a499..c36234732 100644 --- a/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts +++ b/packages/agent-core-v2/src/_base/execEnv/loginShellPath.ts @@ -1,3 +1,26 @@ +/** + * `_base/execEnv` — login-shell PATH probe. + * + * Enriches `process.env.PATH` with entries from the user's login shell. When + * kimi-code is launched from a context that skipped the user's shell profile + * (GUI launchers, non-login parent shells), `process.env.PATH` misses entries + * like `/opt/homebrew/bin`, so commands spawned by the Bash tool can't find + * tools the user has in their interactive shell (e.g. `gh`). We run the user's + * login shell once (`$SHELL -l -c /usr/bin/env`), extract its PATH, and append + * the entries the current PATH lacks. Existing entries keep their order and + * priority; failures (no resolvable shell, hung or broken profile) silently + * leave PATH untouched. + * + * launchd/daemon launches can leave `$SHELL` unset or blank, so the probe falls + * back to the OS account's login shell from the user database before giving up. + * + * The probe is a pure function of injected deps so the suite runs identically + * on any host. Windows is skipped: the problem is specific to POSIX + * login-shell profiles. + * + * Kept as a pure helper with no DI dependencies. + */ + import { userInfo } from 'node:os'; import { execFileText } from './environmentProbe'; diff --git a/packages/agent-core-v2/src/_base/execEnv/shellPathBridge.ts b/packages/agent-core-v2/src/_base/execEnv/shellPathBridge.ts deleted file mode 100644 index 7303c5d87..000000000 --- a/packages/agent-core-v2/src/_base/execEnv/shellPathBridge.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { execFileSync as nodeExecFileSync } from 'node:child_process'; -import { existsSync } from 'node:fs'; -import * as nodePath from 'node:path'; - -import type { HostEnvironmentInfo } from './environmentProbe'; - -export interface ShellPathBridge { - toShellPath(nativePath: string): string; - fromShellPath(path: string): string; -} - -export type ShellPathBridgeEnv = Pick<HostEnvironmentInfo, 'osKind' | 'shellName' | 'shellPath'>; - -export interface ShellPathBridgeDeps { - readonly execFileSync: (file: string, args: readonly string[]) => string; - readonly isFile: (path: string) => boolean; -} - -const CYGPATH_TIMEOUT_MS = 5_000; - -const DRIVE_COLON_RE = /^\/([a-zA-Z]):(?:[\\/]|$)/; -const CYGDRIVE_RE = /^\/cygdrive\/([a-zA-Z])(?:\/|$)/; -const DRIVE_RE = /^\/([a-zA-Z])(?:\/|$)/; - -const VIRTUAL_FS_PREFIXES: readonly string[] = ['/dev/', '/proc/', '/sys/']; - -const WIN32_DRIVE_ABSOLUTE_RE = /^[A-Za-z]:[\\/]/; - -function joinDrive(letter: string, rest: string): string { - const normalizedRest = rest.replaceAll('\\', '/'); - return normalizedRest === '' - ? `${letter.toUpperCase()}:/` - : `${letter.toUpperCase()}:${normalizedRest}`; -} - -export function translateShellDrivePath(path: string): string { - const colonMatch = DRIVE_COLON_RE.exec(path); - if (colonMatch !== null) { - return joinDrive(colonMatch[1]!, path.slice(3)); - } - const cygdriveMatch = CYGDRIVE_RE.exec(path); - if (cygdriveMatch !== null) { - return joinDrive(cygdriveMatch[1]!, path.slice(`/cygdrive/${cygdriveMatch[1]!}`.length)); - } - const driveMatch = DRIVE_RE.exec(path); - if (driveMatch !== null) { - return joinDrive(driveMatch[1]!, path.slice(2)); - } - return path; -} - -export function createShellPathBridge( - env: ShellPathBridgeEnv, - deps: ShellPathBridgeDeps, -): ShellPathBridge { - const enabled = env.osKind === 'Windows' && env.shellName === 'bash'; - - let cygpathExe: string | null | undefined; - const segmentCache = new Map<string, string>(); - - function locateCygpath(): string | null { - if (cygpathExe !== undefined) return cygpathExe; - const shellDir = nodePath.win32.dirname(env.shellPath); - const candidates = [nodePath.win32.join(shellDir, 'cygpath.exe')]; - if (nodePath.win32.basename(shellDir).toLowerCase() === 'bin') { - candidates.push(nodePath.win32.join(shellDir, '..', 'usr', 'bin', 'cygpath.exe')); - } - cygpathExe = candidates.find((candidate) => deps.isFile(candidate)) ?? null; - return cygpathExe; - } - - function resolveRootSegment(firstSegment: string): string | null { - const cached = segmentCache.get(firstSegment); - if (cached !== undefined) return cached; - - const exe = locateCygpath(); - if (exe === null) return null; - let resolved: string; - try { - const output = deps.execFileSync(exe, ['-w', '-C', 'UTF8', '--', `/${firstSegment}`]); - const trimmed = output.replace(/\r?\n$/, ''); - if (!WIN32_DRIVE_ABSOLUTE_RE.test(trimmed) && !trimmed.startsWith('\\\\')) return null; - resolved = trimmed.replace(/[\\/]$/, ''); - } catch { - return null; - } - segmentCache.set(firstSegment, resolved); - return resolved; - } - - function fromShellPath(path: string): string { - if (!enabled) return path; - - if (path.startsWith('//')) return path; - - if (path.startsWith('/')) { - const normalized = nodePath.posix.normalize(path); - const lexical = translateShellDrivePath(normalized); - if (lexical !== normalized) return lexical; - if (normalized === '/') return normalized; - if (VIRTUAL_FS_PREFIXES.some((prefix) => normalized.startsWith(prefix))) return normalized; - const firstSegment = normalized.slice(1).split('/')[0]!; - const prefix = resolveRootSegment(firstSegment); - if (prefix === null) return normalized; - const remainder = normalized.slice(firstSegment.length + 1); - const joined = `${prefix}${remainder}`.replaceAll('\\', '/'); - return /^[A-Za-z]:$/.test(joined) ? `${joined}/` : joined; - } - - return path; - } - - function toShellPath(nativePath: string): string { - if (!enabled) return nativePath; - - if (nativePath.startsWith('\\\\')) { - return nativePath.replaceAll('\\', '/'); - } - - const driveMatch = /^([A-Za-z]):(?:[\\/]|$)/.exec(nativePath); - if (driveMatch !== null) { - const drive = driveMatch[1]!.toLowerCase(); - const rest = nativePath.slice(2).replaceAll('\\', '/'); - return `/${drive}${rest.startsWith('/') ? rest : `/${rest}`}`; - } - - return nativePath.replaceAll('\\', '/'); - } - - return { toShellPath, fromShellPath }; -} - -const bridgeCache = new Map<string, ShellPathBridge>(); - -export function getShellPathBridge(env: ShellPathBridgeEnv): ShellPathBridge { - const key = `${env.osKind} ${env.shellName} ${env.shellPath}`; - const cached = bridgeCache.get(key); - if (cached !== undefined) return cached; - const bridge = createShellPathBridge(env, { - execFileSync: (file, args) => - nodeExecFileSync(file, [...args], { - encoding: 'utf8', - timeout: CYGPATH_TIMEOUT_MS, - windowsHide: true, - }), - isFile: (path) => existsSync(path), - }); - bridgeCache.set(key, bridge); - return bridge; -} diff --git a/packages/agent-core-v2/src/_base/lifecycle/disposer.ts b/packages/agent-core-v2/src/_base/lifecycle/disposer.ts index 6e7a9a566..a40ca6618 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/disposer.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/disposer.ts @@ -1,3 +1,13 @@ +/** + * `_base.lifecycle` — disposer types shared by the Ledger. + * + * A `Disposer` undoes one registered side effect. Disposers are dual-track + * (sync / async), mirroring ES explicit resource management: a Ledger whose + * entries are all synchronous tears down within a single tick; any async + * entry suspends the teardown promise until it settles. + */ + +/** Why the ledger is being torn down; threaded through to every disposer. */ export type TeardownReason = 'scope-close' | 'cascade' | 'unload'; export type Disposer = (reason: TeardownReason) => void | Promise<void>; diff --git a/packages/agent-core-v2/src/_base/lifecycle/errors.ts b/packages/agent-core-v2/src/_base/lifecycle/errors.ts index e210bbdda..4ea32c5d9 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/errors.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/errors.ts @@ -1,3 +1,7 @@ +/** + * `_base.lifecycle` — Ledger errors. + */ + export class LedgerDisposedError extends Error { constructor( readonly ledgerLabel: string, diff --git a/packages/agent-core-v2/src/_base/lifecycle/keyedResource.ts b/packages/agent-core-v2/src/_base/lifecycle/keyedResource.ts deleted file mode 100644 index 14d79adf6..000000000 --- a/packages/agent-core-v2/src/_base/lifecycle/keyedResource.ts +++ /dev/null @@ -1,150 +0,0 @@ -export interface KeyedResourceGeneration { - readonly owner: string; - readonly generation: string | number; -} - -export interface KeyedResource { - dispose(): void | Promise<void>; - abort?(reason?: unknown): void; -} - -export interface KeyedResourceLease<Resource> { - readonly resource: Resource; - release(): void; -} - -interface ResourceEntry<Resource extends KeyedResource> { - promise: Promise<Resource>; - resource?: Resource; - leases: number; - draining: boolean; - abortOnDrain: boolean; - aborted: boolean; - disposed: boolean; - drainPromise?: Promise<void>; - releaseDrain?: () => void; -} - -export class KeyedResourceLeasePool<Key, Resource extends KeyedResource> { - private readonly entries = new Map<Key, ResourceEntry<Resource>>(); - private withdrawn = false; - private withdrawal?: Promise<void>; - - constructor( - readonly identity: KeyedResourceGeneration, - private readonly create: (key: Key) => Resource | Promise<Resource>, - ) {} - - acquire(key: Key): Promise<KeyedResourceLease<Resource>> { - if (this.withdrawn) return Promise.reject(this.unavailable()); - let entry = this.entries.get(key); - if (entry === undefined) { - entry = this.createEntry(key); - this.entries.set(key, entry); - } - if (entry.draining) return Promise.reject(this.unavailable()); - entry.leases += 1; - return entry.promise.then( - (resource) => { - let active = true; - return { - resource, - release: () => { - if (!active) return; - active = false; - entry.leases -= 1; - if (entry.leases === 0) entry.releaseDrain?.(); - }, - }; - }, - (error: unknown) => { - entry.leases -= 1; - if (entry.leases === 0) entry.releaseDrain?.(); - throw error; - }, - ); - } - - has(key: Key): boolean { - return this.entries.has(key); - } - - disposeKey(key: Key, reason?: unknown, abort = false): Promise<void> { - const entry = this.entries.get(key); - if (entry === undefined) return Promise.resolve(); - this.entries.delete(key); - return this.drain(entry, reason, abort); - } - - withdraw(reason?: unknown): Promise<void> { - if (this.withdrawal !== undefined) return this.withdrawal; - this.withdrawn = true; - const entries = [...this.entries.values()]; - this.entries.clear(); - this.withdrawal = Promise.all(entries.map((entry) => this.drain(entry, reason, false))).then( - () => undefined, - ); - return this.withdrawal; - } - - private createEntry(key: Key): ResourceEntry<Resource> { - const entry: ResourceEntry<Resource> = { - promise: undefined as unknown as Promise<Resource>, - leases: 0, - draining: false, - abortOnDrain: false, - aborted: false, - disposed: false, - }; - entry.promise = Promise.resolve() - .then(() => this.create(key)) - .then( - (resource) => { - entry.resource = resource; - if (entry.abortOnDrain) this.abort(entry); - return resource; - }, - (error: unknown) => { - if (this.entries.get(key) === entry) this.entries.delete(key); - throw error; - }, - ); - return entry; - } - - private drain(entry: ResourceEntry<Resource>, reason?: unknown, abort = false): Promise<void> { - entry.abortOnDrain ||= abort; - entry.drainPromise ??= (async () => { - entry.draining = true; - try { - await entry.promise; - } catch { - return; - } - if (entry.abortOnDrain) this.abort(entry, reason); - if (entry.leases > 0) { - await new Promise<void>((resolve) => { - entry.releaseDrain = resolve; - }); - } - if (entry.disposed) return; - entry.disposed = true; - await entry.resource!.dispose(); - })(); - return entry.drainPromise; - } - - private abort(entry: ResourceEntry<Resource>, reason?: unknown): void { - if (entry.aborted || entry.resource?.abort === undefined) return; - entry.aborted = true; - try { - entry.resource.abort(reason); - } catch {} - } - - private unavailable(): Error { - return new Error( - `resource generation ${this.identity.owner}:${String(this.identity.generation)} is withdrawn`, - ); - } -} diff --git a/packages/agent-core-v2/src/_base/lifecycle/ledger.ts b/packages/agent-core-v2/src/_base/lifecycle/ledger.ts index d49c9ce07..ea79a628d 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/ledger.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/ledger.ts @@ -1,3 +1,15 @@ +/** + * `_base.lifecycle` — `Ledger`: an ordered book of rollbackable registrations. + * + * A Ledger records entries (disposers, effects, child ledgers) in registration + * order and tears them down in strict reverse order, awaiting each entry + * serially — never in parallel. Rollback is uninterruptible: a failing entry + * is logged (with its label) and teardown continues. Registering into a + * disposing/disposed ledger throws immediately. + * + * The Ledger knows nothing about DI; scopes and containers build on top of it. + */ + import { onUnexpectedError } from '../errors/unexpectedError'; import { isAsyncIterable, @@ -65,11 +77,6 @@ export class Ledger { return this._push({ label, kind: 'disposer', active: true, run: disposer }); } - registerFinalizer(disposer: Disposer, label: string = 'finalizer'): LedgerEntry { - this._assertActive('registerFinalizer'); - return this._push({ label, kind: 'disposer', active: true, run: disposer }, true); - } - effect(body: EffectBody, label: string = 'effect'): LedgerEntry { this._assertActive('effect'); const out = body(); @@ -156,15 +163,11 @@ export class Ledger { return infos; } - private _push(record: EntryRecord, front = false): LedgerEntry { + private _push(record: EntryRecord): LedgerEntry { if (Ledger.captureStacks) { record.stack = new Error('Ledger registration').stack; } - if (front) { - this._records.unshift(record); - } else { - this._records.push(record); - } + this._records.push(record); return { label: record.label, get disposed() { diff --git a/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts b/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts index 784aab797..0b5c6b401 100644 --- a/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts +++ b/packages/agent-core-v2/src/_base/lifecycle/lifecycleMachine.ts @@ -1,3 +1,11 @@ +/** + * `_base.lifecycle` — in-memory lifecycle transitions with guarded async transactions. + * + * Provides a domain-independent state holder that enters a transition state before + * asynchronous work begins and coordinates explicit commit, rollback, cleanup, and + * compensation actions. It has no persistence, event, DI, or scope dependencies. + */ + export type LifecycleTransitionErrorReason = | 'invalid_state' | 'transition_conflict' diff --git a/packages/agent-core-v2/src/_base/log/fileLog.ts b/packages/agent-core-v2/src/_base/log/fileLog.ts index e52c065ba..edf74a782 100644 --- a/packages/agent-core-v2/src/_base/log/fileLog.ts +++ b/packages/agent-core-v2/src/_base/log/fileLog.ts @@ -1,3 +1,15 @@ +/** + * `_base/log` — plain (non-DI) log sinks. + * + * Owns the `RotatingFileWriter` (size-rotated, async-serial, sync-flush on + * exit) and the `ILogWriter` implementations built on top of it (`FileLogWriter`), + * plus the in-memory and console sinks used by tests and debugging. All classes + * here are plain: constructed with an explicit options object, no `@IService` + * deps, never registered with the container — a `*LogService` creates and owns + * them. Uses `node:fs` rather than `kaos` because rotation needs atomic rename + * and synchronous append. + */ + import { appendFileSync, mkdirSync } from 'node:fs'; import { mkdir, open, rename, stat, unlink } from 'node:fs/promises'; import { dirname } from 'pathe'; @@ -270,15 +282,19 @@ export class ConsoleLogWriter implements ILogWriter { const { text } = formatEntry(entry, { ansi: process.stderr.isTTY === true }); switch (entry.level) { case 'error': + // eslint-disable-next-line no-console console.error(text); break; case 'warn': + // eslint-disable-next-line no-console console.warn(text); break; case 'debug': + // eslint-disable-next-line no-console console.debug(text); break; default: + // eslint-disable-next-line no-console console.log(text); } } diff --git a/packages/agent-core-v2/src/_base/log/formatter.ts b/packages/agent-core-v2/src/_base/log/formatter.ts index c2bb51e3e..409261575 100644 --- a/packages/agent-core-v2/src/_base/log/formatter.ts +++ b/packages/agent-core-v2/src/_base/log/formatter.ts @@ -1,3 +1,12 @@ +/** + * `log` domain — logfmt entry formatter. + * + * Renders a `LogEntry` as a single logfmt line (`ISO LEVEL msg k=v ...`), + * redacts secret-shaped keys and raw secret patterns, truncates oversized + * fields, optionally colorizes the level with ANSI, and indents error stacks. + * Pure — no I/O, no DI. + */ + import type { LogContext, LogEntry, LogEntryError } from './log'; export const MSG_MAX_CHARS = 200; diff --git a/packages/agent-core-v2/src/_base/log/log.ts b/packages/agent-core-v2/src/_base/log/log.ts index 58051c11a..5afd73e31 100644 --- a/packages/agent-core-v2/src/_base/log/log.ts +++ b/packages/agent-core-v2/src/_base/log/log.ts @@ -1,3 +1,15 @@ +/** + * `_base/log` — structured logging contract. + * + * Defines the public logging model shared by every scope: the `LogEntry` / + * `LogLevel` types, the `ILogger` / `ILogService` facade used by other domains + * to emit leveled entries, and the plain `ILogWriter` sink shape. There is a + * single `ILogService` DI token; each scope binds its own `*LogService` + * implementation to it, so consumers just inject `@ILogService` and the scope + * decides where entries land. `ILogWriter` is a plain (non-DI) interface — sinks + * are created by the `*LogService` implementations, not registered. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug'; diff --git a/packages/agent-core-v2/src/_base/log/logConfig.ts b/packages/agent-core-v2/src/_base/log/logConfig.ts index 34ae349ee..6be4bd0a4 100644 --- a/packages/agent-core-v2/src/_base/log/logConfig.ts +++ b/packages/agent-core-v2/src/_base/log/logConfig.ts @@ -1,3 +1,11 @@ +/** + * `log` domain — runtime logging configuration. + * + * Builds the `LoggingConfig` from `KIMI_LOG_*` environment variables plus + * defaults, resolves the global and per-session log paths, and exposes the + * `ILogOptions` seed used to inject the resolved config into a App scope. + */ + import { join } from 'pathe'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/_base/log/logService.ts b/packages/agent-core-v2/src/_base/log/logService.ts index 232a22075..f403edee4 100644 --- a/packages/agent-core-v2/src/_base/log/logService.ts +++ b/packages/agent-core-v2/src/_base/log/logService.ts @@ -1,3 +1,14 @@ +/** + * `_base/log` — `BoundLogger` base and the App-scope `ILogService`. + * + * `BoundLogger` filters entries by level, extracts the payload into ctx/error, + * merges bound context, and writes to a plain `ILogWriter`. It extends + * `Service` so scope implementations can flush synchronously when their + * scope is disposed. `AppLogService` is the App-scope binding of the single + * `ILogService` token: it owns the global rotating file sink and reads its + * level from `ILogOptions`. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -16,23 +27,6 @@ import { import { createFileLogWriter, type FileLogWriter } from './fileLog'; import { ILogOptions } from './logConfig'; -const pendingLogCloses = new Set<Promise<void>>(); - -export function trackLogClose(close: Promise<void>): void { - const tracked = close.then( - () => undefined, - () => undefined, - ); - pendingLogCloses.add(tracked); - void tracked.finally(() => pendingLogCloses.delete(tracked)); -} - -export async function drainLogCloses(): Promise<void> { - while (pendingLogCloses.size > 0) { - await Promise.all(pendingLogCloses); - } -} - interface ExtractedPayload { readonly ctx?: LogContext; readonly error?: LogEntryError; @@ -167,7 +161,7 @@ export class AppLogService extends BoundLogger implements ILogService { override dispose(): void { this.sink.flushSync(); - trackLogClose(this.sink.close()); + void this.sink.close(); super.dispose(); } } diff --git a/packages/agent-core-v2/src/_base/state/stateRegistry.ts b/packages/agent-core-v2/src/_base/state/stateRegistry.ts index 54fd1fbfb..190e8f0b2 100644 --- a/packages/agent-core-v2/src/_base/state/stateRegistry.ts +++ b/packages/agent-core-v2/src/_base/state/stateRegistry.ts @@ -1,11 +1,46 @@ -import { Disposable, type IDisposable, toDisposable } from '../di/lifecycle'; +/** + * `state` domain — scope-agnostic keyed state container primitives. + * + * Owns the typed `StateKey<T>` / `defineState(name, initial)` descriptor, the + * `IStateRegistry` base interface shared by the per-scope state services, and + * the `StateRegistry` implementation backing them: a `Map`-backed store + * where keys are declared + * up front (`register`), read and replaced (`get` / `set`), and observed + * (`onDidChange(key)` per key, `onDidChangeAny` globally). Two exports serve + * debugging: `entries()` returns the live key/value references for in-process + * readers, and `snapshot()` returns a JSON-safe deep copy for RPC / inspector + * export: Maps become plain objects or entry arrays, Sets become arrays, + * functions are dropped, circular references become `'(circular)'`, and + * instances with a custom prototype (service references, tools, Promises) + * collapse to a `'(ClassName)'` marker — plain data is recursed, resource + * graphs are not, so a value that reaches into the DI object graph cannot + * fan the copy out until the heap is exhausted. Misuse (duplicate registration, reading or writing an + * unregistered key) is a caller bug and raises `BugIndicatingError`. + * + * Cascading inspection: each scope's state service keeps a reference to the + * parent scope's registry (`inspectParent`, assigned from the injected + * parent-tier state service; App is the root) and declares its tier name + * (`inspectScope`). `inspect()` folds that chain into a `StateInspection` + * tree — this scope's `snapshot()` plus the ancestors' — so one RPC call + * from any scope tier exports the whole App → … → current-scope state path. + * + * Values are stored as-is — the container does not freeze or clone, so + * replacing the whole value via `set` is the recommended update style; + * mutating a held `Map` / `Set` in place bypasses change notification. + * Persistence and replay are out of scope here. Scope-agnostic. + */ + +import { Disposable } from '../di/lifecycle'; import { BugIndicatingError } from '../errors/errors'; import { Emitter, type Event } from '../event'; export interface StateKey<T> { readonly name: string; readonly initial: () => T; - readonly snapshotExcluded?: boolean; +} + +export function defineState<T>(name: string, initial: () => T): StateKey<T> { + return { name, initial }; } export interface StateChange { @@ -20,7 +55,7 @@ export interface StateInspection { } export interface IStateRegistry { - contributeState<T>(key: StateKey<T>): IDisposable; + register<T>(key: StateKey<T>): void; has(key: StateKey<unknown>): boolean; get<T>(key: StateKey<T>): T; set<T>(key: StateKey<T>, value: T): void; @@ -31,10 +66,9 @@ export interface IStateRegistry { inspect(): StateInspection; } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class StateRegistry extends Disposable implements IStateRegistry { private readonly values = new Map<string, unknown>(); - private readonly registrations = new Map<string, object>(); - private readonly excludedFromSnapshot = new Set<string>(); private readonly keyEmitters = new Map<string, Emitter<unknown>>(); private readonly anyEmitter = this._register(new Emitter<StateChange>()); readonly onDidChangeAny: Event<StateChange> = this.anyEmitter.event; @@ -42,34 +76,11 @@ export class StateRegistry extends Disposable implements IStateRegistry { protected readonly inspectScope: string = 'unknown'; protected inspectParent?: IStateRegistry; - contributeState<T>(key: StateKey<T>): IDisposable { - const replayable = (key as StateKey<T> & { readonly replayable?: unknown }).replayable; - if (typeof replayable === 'object' && replayable !== null) { - throw new BugIndicatingError( - `replayable state key '${key.name}' must be contributed to the Agent-scope state service`, - ); - } - return this.contributeKey(key); - } - - protected contributeKey<T>(key: StateKey<T>): IDisposable { + register<T>(key: StateKey<T>): void { if (this.values.has(key.name)) { throw new BugIndicatingError(`state key '${key.name}' is already registered`); } - const registration = {}; - this.registrations.set(key.name, registration); this.values.set(key.name, key.initial()); - if (key.snapshotExcluded === true) { - this.excludedFromSnapshot.add(key.name); - } - return toDisposable(() => { - if (this.registrations.get(key.name) !== registration) return; - this.registrations.delete(key.name); - this.values.delete(key.name); - this.excludedFromSnapshot.delete(key.name); - this.keyEmitters.get(key.name)?.dispose(); - this.keyEmitters.delete(key.name); - }); } has(key: StateKey<unknown>): boolean { @@ -108,7 +119,6 @@ export class StateRegistry extends Disposable implements IStateRegistry { snapshot(): Record<string, unknown> { const out: Record<string, unknown> = {}; for (const [key, value] of this.values) { - if (this.excludedFromSnapshot.has(key)) continue; out[key] = toJsonSafe(value, new WeakSet()); } return out; diff --git a/packages/agent-core-v2/src/_base/text/encoding.ts b/packages/agent-core-v2/src/_base/text/encoding.ts index 154e5bf17..714f05251 100644 --- a/packages/agent-core-v2/src/_base/text/encoding.ts +++ b/packages/agent-core-v2/src/_base/text/encoding.ts @@ -1,26 +1,67 @@ +/** + * `_base` text helpers — UTF text encoding detection and decoding. + * + * Detection algorithm derived from VS Code + * `src/vs/workbench/services/textfile/common/encoding.ts` + * (MIT License, Copyright (c) Microsoft Corporation): BOM sniffing plus a + * zero-byte parity heuristic that recognizes BOM-less UTF-16 LE/BE, so text + * files saved as UTF-16 (e.g. Windows Notepad `.txt`) can be transcoded to + * UTF-8 instead of being refused as binary. + * + * The parity heuristic deliberately deviates from VS Code in one way: VS + * Code requires *every* byte pair to conform (a single CJK character, whose + * UTF-16 unit carries no zero byte, falsifies the pattern and the file is + * deemed binary). Here, zero bytes must instead appear at least twice and at + * exactly one parity — odd indices mean UTF-16 LE (`0xAA 0x00`), even + * indices mean UTF-16 BE (`0x00 0xAA`) — which tolerates mixed Latin/CJK + * content while still rejecting real binaries (zeros at both parities, or + * an isolated zero byte). Legacy 8-bit encodings (GBK, Big5, Shift-JIS, …) + * are never guessed — a wrong silent guess is worse than a clear refusal. + * + * Pure functions over bytes; no io happens here. + */ + export type UtfTextEncoding = 'utf-8' | 'utf-16le' | 'utf-16be'; -export interface TextClassification { - readonly isBinary: boolean; - readonly encoding: UtfTextEncoding; -} - -export const FS_BINARY_NONPRINTABLE_FRACTION = 0.3; - export interface TextEncodingDetection { + /** + * Detected encoding. `'utf-8'` when no signal points elsewhere (also the + * placeholder when `seemsBinary` is true). + */ readonly encoding: UtfTextEncoding; + /** + * True when zero bytes appear but fit neither UTF-16 pattern — the sample + * should be treated as binary, not text. + */ readonly seemsBinary: boolean; } +/** Number of leading bytes inspected for the zero-byte heuristic. */ export const ENCODING_DETECTION_SAMPLE_BYTES = 512; +/** + * Minimum zero bytes (at a single parity) before the BOM-less UTF-16 + * heuristic commits. One isolated zero byte is too ambiguous — a short + * binary blob like `"plain prefix" + 00 01` would otherwise masquerade as + * UTF-16 BE. + */ const MIN_ZERO_BYTES_FOR_UTF16 = 2; const UTF16BE_BOM = [0xfe, 0xff] as const; const UTF16LE_BOM = [0xff, 0xfe] as const; const UTF8_BOM = [0xef, 0xbb, 0xbf] as const; -function sniffTextEncoding(sample: Uint8Array): TextEncodingDetection { +/** + * Detect the encoding of a text file from its leading bytes. + * + * Known limitation inherited from the reference implementation: a BOM-less + * UTF-16 file whose content carries no zero bytes at all (e.g. purely CJK + * text) is reported as `'utf-8'`; strict UTF-8 decoding of it will then fail + * or produce garbage. Notepad and most editors write a BOM, so this is rare + * in practice. + */ +export function detectTextEncoding(sample: Uint8Array): TextEncodingDetection { + // Always trust a BOM first. if (sample.length >= 2) { const b0 = sample[0]!; const b1 = sample[1]!; @@ -35,6 +76,10 @@ function sniffTextEncoding(sample: Uint8Array): TextEncodingDetection { } } + // BOM-less UTF-16: zero bytes cluster at one parity — odd indices for LE + // (`0xAA 0x00`), even for BE (`0x00 0xAA`). CJK units carry no zero byte, + // so only the *placement* of zeros is checked, not their density. Zeros + // at both parities, or fewer than the ambiguity threshold, mean binary. let zerosAtOdd = 0; let zerosAtEven = 0; const limit = Math.min(sample.length, ENCODING_DETECTION_SAMPLE_BYTES); @@ -56,58 +101,10 @@ function sniffTextEncoding(sample: Uint8Array): TextEncodingDetection { return { encoding: 'utf-8', seemsBinary: true }; } -export function classifyTextSample(sample: Uint8Array): TextClassification { - const sniffed = sniffTextEncoding(sample); - if (sniffed.seemsBinary || sniffed.encoding !== 'utf-8') { - return { isBinary: sniffed.seemsBinary, encoding: sniffed.encoding }; - } - if (sample.includes(0)) { - return { isBinary: true, encoding: 'utf-8' }; - } - let end = sample.length; - for (let i = Math.max(0, sample.length - 3); i < sample.length; i++) { - const b = sample[i]!; - const expected = - b >= 0xc2 && b <= 0xdf ? 2 : b >= 0xe0 && b <= 0xef ? 3 : b >= 0xf0 && b <= 0xf4 ? 4 : 0; - if (expected === 0 || i + expected <= sample.length) continue; - let validPrefix = true; - for (let j = i + 1; j < sample.length; j++) { - const cb = sample[j]!; - if (cb < 0x80 || cb > 0xbf) { - validPrefix = false; - break; - } - } - if (validPrefix) { - end = i; - break; - } - } - let text: string; - try { - text = new TextDecoder('utf-8', { fatal: true }).decode(sample.subarray(0, end)); - } catch { - return { isBinary: true, encoding: 'utf-8' }; - } - let nonPrintable = 0; - let total = 0; - for (const ch of text) { - const cp = ch.codePointAt(0)!; - total++; - if (cp === 9 || cp === 10 || cp === 13) continue; - if (cp < 32 || (cp >= 0x7f && cp <= 0x9f)) nonPrintable++; - } - if (total > 0 && nonPrintable / total > FS_BINARY_NONPRINTABLE_FRACTION) { - return { isBinary: true, encoding: 'utf-8' }; - } - return { isBinary: false, encoding: 'utf-8' }; -} - -export function detectTextEncoding(sample: Uint8Array): TextEncodingDetection { - const classification = classifyTextSample(sample); - return { encoding: classification.encoding, seemsBinary: classification.isBinary }; -} - +/** + * Decode bytes in a detected UTF encoding to a JS string. Malformed + * sequences are replaced (non-fatal) and a leading BOM is stripped. + */ export function decodeUtfText(bytes: Uint8Array, encoding: UtfTextEncoding): string { return new TextDecoder(encoding, { fatal: false }).decode(bytes); } diff --git a/packages/agent-core-v2/src/_base/text/frontmatter.ts b/packages/agent-core-v2/src/_base/text/frontmatter.ts index 601a0254c..16bb2b0fc 100644 --- a/packages/agent-core-v2/src/_base/text/frontmatter.ts +++ b/packages/agent-core-v2/src/_base/text/frontmatter.ts @@ -1,3 +1,12 @@ +/** + * `_base` text helpers — Markdown frontmatter parsing. + * + * Splits a Markdown document into its YAML frontmatter block and body. Pure + * text processing with no IO and no domain knowledge. A document without a + * leading `---` fence parses as all body with `data: null`; an unterminated + * fence is a `FrontmatterError`. + */ + import { load as loadYaml } from 'js-yaml'; export class FrontmatterError extends Error { diff --git a/packages/agent-core-v2/src/_base/text/line-endings.ts b/packages/agent-core-v2/src/_base/text/line-endings.ts index 09725d377..3f27470a8 100644 --- a/packages/agent-core-v2/src/_base/text/line-endings.ts +++ b/packages/agent-core-v2/src/_base/text/line-endings.ts @@ -1,3 +1,10 @@ +/** + * `_base` text helpers — model-text line-ending normalization. + * + * Normalizes CRLF → LF for display and re-materializes CRLF on write, so the + * model sees a consistent view while the on-disk bytes stay faithful. + */ + export type LineEndingStyle = 'lf' | 'crlf' | 'mixed'; export interface ModelTextView { @@ -50,6 +57,11 @@ export function makeCarriageReturnsVisible(text: string): string { return text.replaceAll('\r', '\\r'); } +/** + * Split text into lines, keeping each line's trailing `\n` (the final line + * may lack one). Same semantics as Python's `str.splitlines(keepends=True)` + * restricted to `\n` boundaries. + */ export function splitLinesKeepingTerminator(text: string): string[] { if (text.length === 0) return []; const lines: string[] = []; diff --git a/packages/agent-core-v2/src/_base/utils/abort.ts b/packages/agent-core-v2/src/_base/utils/abort.ts index 7662966b2..09b2860fb 100644 --- a/packages/agent-core-v2/src/_base/utils/abort.ts +++ b/packages/agent-core-v2/src/_base/utils/abort.ts @@ -1,3 +1,8 @@ +/** + * Abort-signal helpers — user-cancellation errors, abortable promises, signal + * linking, and deadline abort signals. + */ + export function abortError(message = 'Aborted'): Error { const error = new Error(message); error.name = 'AbortError'; diff --git a/packages/agent-core-v2/src/_base/utils/canonical-args.ts b/packages/agent-core-v2/src/_base/utils/canonical-args.ts index feca131c1..40661ed20 100644 --- a/packages/agent-core-v2/src/_base/utils/canonical-args.ts +++ b/packages/agent-core-v2/src/_base/utils/canonical-args.ts @@ -1,3 +1,7 @@ +/** + * `_base` utility — canonical JSON argument serialization for stable tool-call keys. + */ + export function canonicalTelemetryArgs(args: unknown): string { const json = JSON.stringify(sortJsonValue(args)); return json ?? String(args); diff --git a/packages/agent-core-v2/src/_base/utils/env.ts b/packages/agent-core-v2/src/_base/utils/env.ts index 12a62fc74..9412d448a 100644 --- a/packages/agent-core-v2/src/_base/utils/env.ts +++ b/packages/agent-core-v2/src/_base/utils/env.ts @@ -1,3 +1,7 @@ +/** + * Parse environment-variable string values into typed primitives. + */ + const TRUE_BOOLEAN_ENV_VALUES = new Set(['1', 'true', 'yes', 'on']); const FALSE_BOOLEAN_ENV_VALUES = new Set(['0', 'false', 'no', 'off']); diff --git a/packages/agent-core-v2/src/_base/utils/fileMeta.ts b/packages/agent-core-v2/src/_base/utils/fileMeta.ts index 4f76835b0..f4dced47b 100644 --- a/packages/agent-core-v2/src/_base/utils/fileMeta.ts +++ b/packages/agent-core-v2/src/_base/utils/fileMeta.ts @@ -1,10 +1,18 @@ +/** + * File content metadata helpers — binary detection, line counting, etag, and + * extension-based mime / language guessing. + * + * Pure functions over bytes, text, and stat-like shapes; no io happens here. + * Binary detection samples the leading `FS_BINARY_SAMPLE_BYTES` of a file and + * flags it as binary when the non-printable fraction exceeds + * `FS_BINARY_NONPRINTABLE_FRACTION`; etags are built from any stat-like shape + * carrying `size` / `mtimeMs` / `ino` (`FileMetaStat`). + */ + import { extname } from 'node:path'; -import { classifyTextSample } from '#/_base/text/encoding'; - -export { FS_BINARY_NONPRINTABLE_FRACTION } from '#/_base/text/encoding'; - export const FS_BINARY_SAMPLE_BYTES = 4096; +export const FS_BINARY_NONPRINTABLE_FRACTION = 0.3; export interface FileMetaStat { readonly size: number; @@ -13,7 +21,16 @@ export interface FileMetaStat { } export function detectBinary(buf: Uint8Array): boolean { - return classifyTextSample(buf).isBinary; + if (buf.length === 0) return false; + let nonPrintable = 0; + for (let i = 0; i < buf.length; i++) { + const b = buf[i]!; + if (b === 0) return true; + if (b === 9 || b === 10 || b === 13) continue; + if (b >= 32 && b <= 126) continue; + nonPrintable++; + } + return nonPrintable / buf.length > FS_BINARY_NONPRINTABLE_FRACTION; } export function countLines(text: string): number { diff --git a/packages/agent-core-v2/src/_base/utils/fs.ts b/packages/agent-core-v2/src/_base/utils/fs.ts index da9bacd1a..a6313013a 100644 --- a/packages/agent-core-v2/src/_base/utils/fs.ts +++ b/packages/agent-core-v2/src/_base/utils/fs.ts @@ -1,3 +1,8 @@ +/** + * Low-level durable file-write primitives — atomic writes plus file and + * directory fsync helpers. + */ + import { randomBytes } from 'node:crypto'; import { closeSync, fsyncSync, openSync } from 'node:fs'; import * as nodeFs from 'node:fs'; @@ -76,18 +81,14 @@ export async function atomicWrite( content: string | Uint8Array, _syncOverride?: (fd: number) => Promise<void>, mode?: number, - signal?: AbortSignal, ): Promise<void> { - signal?.throwIfAborted(); const hex = randomBytes(4).toString('hex'); const tmpPath = `${filePath}.tmp.${process.pid}.${hex}`; let renamed = false; try { const fh = await open(tmpPath, 'w', mode); try { - signal?.throwIfAborted(); await fh.writeFile(content); - signal?.throwIfAborted(); await (_syncOverride ?? syncFd)(fh.fd); } finally { await fh.close(); @@ -100,7 +101,6 @@ export async function atomicWrite( if (code !== 'ENOENT') throw error; } } - signal?.throwIfAborted(); await rename(tmpPath, filePath); renamed = true; } finally { @@ -117,30 +117,18 @@ export async function atomicWriteStream( filePath: string, source: AsyncIterable<Uint8Array>, mode?: number, - signal?: AbortSignal, ): Promise<void> { - signal?.throwIfAborted(); const hex = randomBytes(4).toString('hex'); const tmpPath = `${filePath}.tmp.${process.pid}.${hex}`; let renamed = false; - const destroyable = source as AsyncIterable<Uint8Array> & { - destroy?(error?: Error): void; - }; - const onAbort = (): void => { - const reason = signal?.reason instanceof Error ? signal.reason : undefined; - destroyable.destroy?.(reason); - }; - signal?.addEventListener('abort', onAbort, { once: true }); try { const fh = await open(tmpPath, 'w', mode); try { for await (const chunk of source) { - signal?.throwIfAborted(); if (chunk.byteLength > 0) { await fh.writeFile(chunk); } } - signal?.throwIfAborted(); await fh.sync(); } finally { await fh.close(); @@ -153,11 +141,9 @@ export async function atomicWriteStream( if (code !== 'ENOENT') throw error; } } - signal?.throwIfAborted(); await rename(tmpPath, filePath); renamed = true; } finally { - signal?.removeEventListener('abort', onAbort); if (!renamed) { try { await unlink(tmpPath); diff --git a/packages/agent-core-v2/src/_base/utils/hero-slug.ts b/packages/agent-core-v2/src/_base/utils/hero-slug.ts index a8099bccf..e4d78a174 100644 --- a/packages/agent-core-v2/src/_base/utils/hero-slug.ts +++ b/packages/agent-core-v2/src/_base/utils/hero-slug.ts @@ -1,3 +1,7 @@ +/** + * Hero-name slug generator for readable, memorable identifiers. + */ + import { randomInt } from 'node:crypto'; export const HERO_NAMES = [ diff --git a/packages/agent-core-v2/src/_base/utils/paths.ts b/packages/agent-core-v2/src/_base/utils/paths.ts index bf035216f..e6b230df7 100644 --- a/packages/agent-core-v2/src/_base/utils/paths.ts +++ b/packages/agent-core-v2/src/_base/utils/paths.ts @@ -1,56 +1,14 @@ -import nodePath from 'node:path'; - -import { isAbsolute, normalize, resolve } from 'pathe'; - -import { workspaceRootKey } from './workdir-slug'; +/** + * `_base/utils/paths` (cross-cutting) — pure path-filter predicates. + * + * Constrains filesystem watches to selected subtrees and scanner-visible + * entries. + */ function normalizeSlashes(p: string): string { return p.replaceAll('\\', '/'); } -export function isWindowsAbsolutePath(value: string): boolean { - return /^[A-Za-z]:[\\/]/.test(value) || /^[\\/]{2}[^\\/]+[\\/][^\\/]+/.test(value); -} - -export function resolvePath(base: string, value: string): string { - if (isWindowsAbsolutePath(base)) { - return nodePath.win32.resolve(base, value).replaceAll('\\', '/'); - } - if (isWindowsAbsolutePath(value)) { - return nodePath.win32.resolve(value).replaceAll('\\', '/'); - } - return isAbsolute(value) ? normalize(value) : resolve(base, value); -} - -export function canonicalWorkspaceRoot(cwd: string): string { - const resolved = isWindowsAbsolutePath(cwd) - ? nodePath.win32.resolve(cwd).replaceAll('\\', '/') - : resolve(cwd); - return workspaceRootKey(resolved) || resolved; -} - -export interface UpwardRootPathApi { - resolve(dir: string): string; - dirname(dir: string): string; - join(...segments: string[]): string; -} - -export async function findUpwardRoot( - workDir: string, - markerName: string, - hasMarker: (markerPath: string) => Promise<boolean>, - pathApi: UpwardRootPathApi = nodePath, -): Promise<string> { - const start = pathApi.resolve(workDir); - let current = start; - while (true) { - if (await hasMarker(pathApi.join(current, markerName))) return normalizeSlashes(current); - const parent = pathApi.dirname(current); - if (parent === current) return normalizeSlashes(start); - current = parent; - } -} - export interface SubtreeWatchFilterOptions { readonly maxDepth?: number; readonly skipEntry?: (entryName: string) => boolean; diff --git a/packages/agent-core-v2/src/_base/utils/promise.ts b/packages/agent-core-v2/src/_base/utils/promise.ts index 6a6e61099..3669a548c 100644 --- a/packages/agent-core-v2/src/_base/utils/promise.ts +++ b/packages/agent-core-v2/src/_base/utils/promise.ts @@ -1,3 +1,11 @@ +/** + * Timeout outcome promise — resolves with a fixed value after a delay. + * + * The timer goes through `setClampedTimeout`, so huge ("effectively + * unbounded") timeouts still mean a long wait instead of overflowing into an + * immediate fire. + */ + import { setClampedTimeout } from './timer'; const NEVER = new Promise<never>(() => {}); diff --git a/packages/agent-core-v2/src/_base/utils/proxy.ts b/packages/agent-core-v2/src/_base/utils/proxy.ts index 12570257a..7a4e06806 100644 --- a/packages/agent-core-v2/src/_base/utils/proxy.ts +++ b/packages/agent-core-v2/src/_base/utils/proxy.ts @@ -1,3 +1,8 @@ +/** + * Resolve and install proxy configuration for outbound `fetch` and spawned + * child processes (HTTP/HTTPS and SOCKS, honoring `NO_PROXY`). + */ + import { Agent, buildConnector, diff --git a/packages/agent-core-v2/src/_base/utils/render-prompt.ts b/packages/agent-core-v2/src/_base/utils/render-prompt.ts index 2d41956f0..9c49236e0 100644 --- a/packages/agent-core-v2/src/_base/utils/render-prompt.ts +++ b/packages/agent-core-v2/src/_base/utils/render-prompt.ts @@ -1,3 +1,15 @@ +/** + * Shared prompt-template renderer (`renderPrompt`). + * + * A single `${var}` substitution pass: every variable present in `vars` is + * replaced with its string value, unknown or non-string placeholders stay + * verbatim, and a bare `$` is never special. There is no conditional or loop + * syntax by design — call sites compose optional sections in code and pass + * them as pre-rendered blocks. This keeps user-facing templates (agent files, + * `SYSTEM.md`) safe to write: a literal `${...}` inside prose or a code + * snippet can never crash rendering. + */ + const PROMPT_VARIABLE = /\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g; export function renderPrompt(template: string, vars: Record<string, unknown>): string { diff --git a/packages/agent-core-v2/src/_base/utils/retry.ts b/packages/agent-core-v2/src/_base/utils/retry.ts index 120f0c1e1..8c46ace09 100644 --- a/packages/agent-core-v2/src/_base/utils/retry.ts +++ b/packages/agent-core-v2/src/_base/utils/retry.ts @@ -1,3 +1,10 @@ +/** + * `_base` retry helpers — exponential and server-directed backoff, abortable + * sleeps, and error-field extraction. The default budget is 10 attempts per + * step: the 500ms ×2 ramp capped at 32s waits out multi-minute provider + * overload (sustained 429s) before a turn fails. + */ + import { abortable } from '#/_base/utils/abort'; export const DEFAULT_MAX_RETRY_ATTEMPTS = 10; @@ -13,16 +20,12 @@ export interface RetryErrorFields { readonly statusCode?: number; } -export function retryBackoffDelay(attemptIndex: number): number { - const base = Math.min(BASE_DELAY_MS * Math.pow(RETRY_FACTOR, attemptIndex), MAX_DELAY_MS); - return base + Math.random() * JITTER_FACTOR * base; -} - export function retryBackoffDelays(maxAttempts: number): number[] { const count = Math.max(maxAttempts - 1, 0); const delays: number[] = []; for (let i = 0; i < count; i += 1) { - delays.push(retryBackoffDelay(i)); + const base = Math.min(BASE_DELAY_MS * Math.pow(RETRY_FACTOR, i), MAX_DELAY_MS); + delays.push(base + Math.random() * JITTER_FACTOR * base); } return delays; } diff --git a/packages/agent-core-v2/src/_base/utils/timer.ts b/packages/agent-core-v2/src/_base/utils/timer.ts index f6eee2496..08cfa4214 100644 --- a/packages/agent-core-v2/src/_base/utils/timer.ts +++ b/packages/agent-core-v2/src/_base/utils/timer.ts @@ -1,3 +1,20 @@ +/** + * Repeating timer primitive — a disposable `setInterval` wrapper. + * + * `IntervalTimer` owns a single `setInterval` handle: `cancelAndSet` (re)starts + * the loop (cancelling any previous handle first), `cancel` stops it, and + * `dispose` guarantees the handle is cleared — so it can be `_register`-ed on a + * `Disposable` owner and cleaned up for free. One instance is reused across + * start/stop cycles instead of juggling raw `ReturnType<typeof setInterval>` + * values. Mirrors VS Code's `IntervalTimer`. + * + * `setClampedTimeout` is a `setTimeout` whose delay is clamped to + * `MAX_TIMER_DELAY_MS`, the largest delay the host timer accepts: beyond it + * the delay overflows into an immediate (~1ms) fire, so huge ("effectively + * unbounded") timeouts would fire at once instead of waiting. Callers that + * outlive the clamp (~24.8 days) re-arm. + */ + import type { IDisposable } from '#/_base/di/lifecycle'; export const MAX_TIMER_DELAY_MS = 0x7fffffff; diff --git a/packages/agent-core-v2/src/_base/utils/typeEquality.ts b/packages/agent-core-v2/src/_base/utils/typeEquality.ts index 7c10c7dd8..006a717cd 100644 --- a/packages/agent-core-v2/src/_base/utils/typeEquality.ts +++ b/packages/agent-core-v2/src/_base/utils/typeEquality.ts @@ -1,3 +1,20 @@ +/** + * Compile-time type equality. + * + * Used to pin a hand-written type to the zod schema that re-derives it: a + * drift in either direction (added / removed field, changed field type, + * optionality flip) fails typecheck. + * + * `Equal` compares by mutual assignability through a contravariant + * function-type trick, so it is stricter than a one-way `A extends B` + * check. Both sides are flattened first (a homomorphic mapped type), so a + * schema-side intersection (e.g. the `{...} & { [k: string]: unknown }` + * that a passthrough object infers to) compares equal to the equivalent + * hand-written object type instead of failing on type-node shape. The + * comparison cannot see `readonly` modifiers (an inherent TS limitation), + * so hand-written types should match zod's mutable inference exactly. + */ + type Flatten<T> = { [K in keyof T]: T[K] } & {}; export type Equal<A, B> = diff --git a/packages/agent-core-v2/src/_base/utils/types.ts b/packages/agent-core-v2/src/_base/utils/types.ts index 45a0d1c9d..9d50459d7 100644 --- a/packages/agent-core-v2/src/_base/utils/types.ts +++ b/packages/agent-core-v2/src/_base/utils/types.ts @@ -1,3 +1,7 @@ +/** + * Promise-aware utility types for function and method signatures. + */ + export type Promisify<T> = [T] extends [Promise<any>] ? T : Promise<T>; export type PromisifyMethods<T> = { [K in keyof T]: T[K] extends (...args: infer Args) => infer Return diff --git a/packages/agent-core-v2/src/_base/utils/workdir-slug.ts b/packages/agent-core-v2/src/_base/utils/workdir-slug.ts index 15ea2d554..60efc3826 100644 --- a/packages/agent-core-v2/src/_base/utils/workdir-slug.ts +++ b/packages/agent-core-v2/src/_base/utils/workdir-slug.ts @@ -1,3 +1,15 @@ +/** + * Working-directory identity helpers. + * + * `slugifyWorkDirName` turns a directory name into a safe, bounded token; + * `encodeWorkDirKey` derives the stable, opaque `workspaceId` for a working + * directory (`wd_<slug>_<hash>`). The `workspaceId` is the backend-neutral + * identity used to group sessions and to key the workspace registry; backends + * never expose the raw working-directory path. `workspaceRootKey` is the + * comparison-only companion: it answers "is this the same directory?" without + * changing the id that was already minted for it. + */ + import { createHash } from 'node:crypto'; const MAX_WORKDIR_SLUG_LENGTH = 40; diff --git a/packages/agent-core-v2/src/_base/utils/xml-escape.ts b/packages/agent-core-v2/src/_base/utils/xml-escape.ts index 6e5cb49ce..832645aa7 100644 --- a/packages/agent-core-v2/src/_base/utils/xml-escape.ts +++ b/packages/agent-core-v2/src/_base/utils/xml-escape.ts @@ -1,3 +1,7 @@ +/** + * XML escaping helpers for content, attribute values, and tag delimiters. + */ + export function escapeXml(input: string): string { return input .replaceAll('&', '&') diff --git a/packages/agent-core-v2/src/_base/version.ts b/packages/agent-core-v2/src/_base/version.ts index baff62759..dfa8a6a94 100644 --- a/packages/agent-core-v2/src/_base/version.ts +++ b/packages/agent-core-v2/src/_base/version.ts @@ -1,3 +1,7 @@ +/** + * agent-core-v2 version helper — exposes the package version to integrations. + */ + export function getCoreVersion(): string { return '0.0.0'; } diff --git a/packages/agent-core-v2/src/agent/activityView/activityView.ts b/packages/agent-core-v2/src/agent/activityView/activityView.ts index c05d56ba2..706915b12 100644 --- a/packages/agent-core-v2/src/agent/activityView/activityView.ts +++ b/packages/agent-core-v2/src/agent/activityView/activityView.ts @@ -1,8 +1,20 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `activityView` domain — the agent's one-way activity projection. + * + * Defines `IAgentActivityView`: a per-agent, read-only, event-folded read + * model of "what this agent is doing" — the current turn with its live + * phase/stream/step/retry/pending-approval/tool-call detail and the latest + * turn outcome, published on the agent's event bus as + * `agent.activity.updated`. The view OWNS NO authoritative state: every fact + * is folded from the agent's own event bus (loop turn/step/delta/tool/retry, + * permission approval, task, and full-compaction events) and seeded once from + * the owning services; it can be discarded and rebuilt at any time. Bound at + * Agent scope — one instance per agent, dying with it. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { PromptOrigin } from '#/agent/contextMemory/types'; import type { TurnEndReason } from '#/agent/loop/turnEvents'; -import { AgentEvent2, type AgentDomainTrait } from '#/app/event/event2'; export type TurnPhase = 'running' | 'streaming' | 'tool_call' | 'retrying'; @@ -72,10 +84,8 @@ export interface IAgentActivityView { export const IAgentActivityView: ServiceIdentifier<IAgentActivityView> = createDecorator<IAgentActivityView>('agentActivityView'); -export class AgentActivityUpdated extends AgentEvent2<AgentActivityState & AgentDomainTrait> { - static override readonly type = 'agent.activity.updated'; - static override readonly observable = true; -} -export interface AgentActivityUpdated extends AgentActivityState { - readonly agentId: string; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'agent.activity.updated': AgentActivityState & { readonly type: 'agent.activity.updated' }; + } } diff --git a/packages/agent-core-v2/src/agent/activityView/activityViewService.ts b/packages/agent-core-v2/src/agent/activityView/activityViewService.ts index 04b663ba5..7b6dab3fd 100644 --- a/packages/agent-core-v2/src/agent/activityView/activityViewService.ts +++ b/packages/agent-core-v2/src/agent/activityView/activityViewService.ts @@ -1,39 +1,37 @@ +/** + * `activityView` domain — `IAgentActivityView` implementation. + * + * A pure fold of the agent's own event bus: turn boundaries drive the turn + * slice (active → detail updates → ended → `lastTurn`), step/delta/tool/retry + * events drive the live phase/stream/retry detail, permission approval events + * drive the pending-approval list, while task and full-compaction events drive + * the background-work slice. The view seeds once from `IAgentLoopService`, + * `IAgentTaskService`, and `IAgentFullCompactionService`, and recovers the + * last turn's outcome from the wire `TurnModel` through `IWireService`, so + * a cold-resumed agent still reports how its previous turn ended (reads, + * never writes). Otherwise the view holds only derived state, so it can be + * discarded and rebuilt at any time. The mutable view state (`lifecycle`, + * `turn`, `lastTurn`, `background`, `current`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it; the + * event-bus subscription handles stay mechanism held by the `Disposable` + * base, and `MutableTurn`'s in-place-mutated Maps stay instance fields of + * that per-turn class. Bound at Agent scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IEventBus } from '#/app/event/eventBus'; import { IAgentLoopService } from '#/agent/loop/loop'; -import { - AssistantDelta, - ThinkingDelta, - ToolCallDelta, - TurnStarted, - TurnStepStarted, - TurnStepCompleted, - TurnStepInterrupted, -} from '#/agent/loop/turnEvents'; -import { TurnEnded, turnKey } from '#/agent/loop/turnOps'; -import { TurnStepRetrying } from '#/agent/stepRetry/stepRetryService'; -import { ToolCallStarted, ToolResultEvent } from '#/agent/toolExecutor/toolExecutorEvents'; -import { - PermissionApprovalRequested, - PermissionApprovalResolved, -} from '#/agent/toolApproval/toolApprovalService'; -import { TaskStarted, TaskTerminatedNotice } from '#/agent/task/taskOps'; -import { - CompactionCancelled, - CompactionCompleted, - CompactionStarted, -} from '#/agent/fullCompaction/compactionOps'; +import { TurnModel } from '#/agent/loop/turnOps'; import { IAgentStateService } from '#/agent/state/agentState'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentTaskService } from '#/agent/task/task'; import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; import { USER_PROMPT_ORIGIN } from '#/agent/contextMemory/types'; import type { PromptOrigin } from '#/agent/contextMemory/types'; import type { TurnEndReason } from '#/agent/loop/turnEvents'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import type { ActivityLastTurnState, @@ -46,7 +44,7 @@ import type { ToolCallRef, TurnPhase, } from './activityView'; -import { AgentActivityUpdated, IAgentActivityView } from './activityView'; +import { IAgentActivityView } from './activityView'; type EndingReason = NonNullable<ActivityTurnState['endingReason']>; const FULL_COMPACTION_BACKGROUND_ID = 'full-compaction'; @@ -72,6 +70,7 @@ export const activityViewCurrentKey = defineState<AgentActivityState>('activityV background: [], })); +// NOTE: stays Disposable — its own 'state' collides with the Fiber export class AgentActivityView extends Disposable implements IAgentActivityView { declare readonly _serviceBrand: undefined; @@ -81,36 +80,35 @@ export class AgentActivityView extends Disposable implements IAgentActivityView @IAgentTaskService private readonly tasks: IAgentTaskService, @IAgentFullCompactionService private readonly fullCompaction: IAgentFullCompactionService, @IAgentStateService private readonly states: IAgentStateService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IWireService private readonly wire: IWireService, ) { super(); - this.states.contributeState(activityViewLifecycleKey); - this.states.contributeState(activityViewTurnKey); - this.states.contributeState(activityViewLastTurnKey); - this.states.contributeState(activityViewBackgroundKey); - this.states.contributeState(activityViewCurrentKey); + this.states.register(activityViewLifecycleKey); + this.states.register(activityViewTurnKey); + this.states.register(activityViewLastTurnKey); + this.states.register(activityViewBackgroundKey); + this.states.register(activityViewCurrentKey); this.seedFromLoop(); this.seedFromTasks(); this.seedFromFullCompaction(); this._register( - this.dispatcher.hooks.onDidRestore.register('activityView', async (_ctx, next) => { + this.wire.hooks.onDidRestore.register('activityView', async (_ctx, next) => { this.seedLastTurnFromWire(); await next(); }), ); - this._register(this.eventBus.subscribe(TurnStarted, (e) => this.onTurnStarted(e.turnId, e.origin))); - this._register(this.eventBus.subscribe(TurnStepStarted, (e) => this.onStepStarted(e.step))); - this._register(this.eventBus.subscribe(AssistantDelta, () => this.onDelta('assistant'))); - this._register(this.eventBus.subscribe(ThinkingDelta, () => this.onDelta('thinking'))); - this._register(this.eventBus.subscribe(ToolCallDelta, () => this.onDelta('tool_call'))); + this._register(this.eventBus.subscribe('turn.started', (e) => this.onTurnStarted(e.turnId, e.origin))); + this._register(this.eventBus.subscribe('turn.step.started', (e) => this.onStepStarted(e.step))); + this._register(this.eventBus.subscribe('assistant.delta', () => this.onDelta('assistant'))); + this._register(this.eventBus.subscribe('thinking.delta', () => this.onDelta('thinking'))); + this._register(this.eventBus.subscribe('tool.call.delta', () => this.onDelta('tool_call'))); this._register( - this.eventBus.subscribe(ToolCallStarted, (e) => this.onToolCallStarted(e.toolCallId, e.name)), + this.eventBus.subscribe('tool.call.started', (e) => this.onToolCallStarted(e.toolCallId, e.name)), ); - this._register(this.eventBus.subscribe(ToolResultEvent, (e) => this.onToolResult(e.toolCallId))); + this._register(this.eventBus.subscribe('tool.result', (e) => this.onToolResult(e.toolCallId))); this._register( - this.eventBus.subscribe(TurnStepRetrying, (e) => { + this.eventBus.subscribe('turn.step.retrying', (e) => { this.mutateTurn((t) => { t.phase = 'retrying'; t.stream = undefined; @@ -126,7 +124,7 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }), ); this._register( - this.eventBus.subscribe(TurnStepCompleted, () => { + this.eventBus.subscribe('turn.step.completed', () => { this.mutateTurn((t) => { t.phase = 'running'; t.stream = undefined; @@ -135,25 +133,23 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }), ); this._register( - this.eventBus.subscribe(TurnStepInterrupted, (e) => this.onStepInterrupted(e.turnId, e.reason)), + this.eventBus.subscribe('turn.step.interrupted', (e) => this.onStepInterrupted(e.turnId, e.reason)), ); this._register( - this.eventBus.subscribe(TurnEnded, (e) => this.onTurnEnded(e.turnId, e.reason)), + this.eventBus.subscribe('turn.ended', (e) => this.onTurnEnded(e.turnId, e.reason)), ); this._register( - this.eventBus.subscribe(PermissionApprovalRequested, (e) => - this.onApprovalRequested(e.id ?? e.toolCallId, e.toolCallId), - + this.eventBus.subscribe('permission.approval.requested', (e) => + this.onApprovalRequested(e.toolCallId), ), ); this._register( - this.eventBus.subscribe(PermissionApprovalResolved, (e) => - this.onApprovalResolved(e.id ?? e.toolCallId), - + this.eventBus.subscribe('permission.approval.resolved', (e) => + this.onApprovalResolved(e.toolCallId), ), ); this._register( - this.eventBus.subscribe(TaskStarted, (e) => { + this.eventBus.subscribe('task.started', (e) => { this.background.set(e.info.taskId, { kind: e.info.kind, id: e.info.taskId, @@ -163,12 +159,12 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }), ); this._register( - this.eventBus.subscribe(TaskTerminatedNotice, (e) => { + this.eventBus.subscribe('task.terminated', (e) => { if (this.background.delete(e.info.taskId)) this.publish(); }), ); this._register( - this.eventBus.subscribe(CompactionStarted, () => { + this.eventBus.subscribe('compaction.started', () => { this.background.set(FULL_COMPACTION_BACKGROUND_ID, { kind: 'compaction', id: FULL_COMPACTION_BACKGROUND_ID, @@ -178,12 +174,12 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }), ); this._register( - this.eventBus.subscribe(CompactionCompleted, () => { + this.eventBus.subscribe('compaction.completed', () => { this.onFullCompactionEnded(); }), ); this._register( - this.eventBus.subscribe(CompactionCancelled, () => { + this.eventBus.subscribe('compaction.cancelled', () => { this.onFullCompactionEnded(); }), ); @@ -247,7 +243,7 @@ export class AgentActivityView extends Disposable implements IAgentActivityView private seedLastTurnFromWire(): void { if (this.turn !== undefined || this.lastTurn !== undefined) return; - const lastEnded = this.states.get(turnKey).lastEnded; + const lastEnded = this.wire.getModel(TurnModel).lastEnded; if (lastEnded === undefined) return; this.lastTurn = { turnId: lastEnded.turnId, @@ -340,15 +336,15 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }); } - private onApprovalRequested(approvalId: string, toolCallId: string): void { + private onApprovalRequested(toolCallId: string): void { this.mutateTurn((t) => { - t.pendingApprovals.set(approvalId, { approvalId, toolCallId, since: Date.now() }); + t.pendingApprovals.set(toolCallId, { approvalId: toolCallId, toolCallId, since: Date.now() }); }); } - private onApprovalResolved(approvalId: string): void { + private onApprovalResolved(toolCallId: string): void { this.mutateTurn((t) => { - t.pendingApprovals.delete(approvalId); + t.pendingApprovals.delete(toolCallId); }); } @@ -368,9 +364,7 @@ export class AgentActivityView extends Disposable implements IAgentActivityView }; if (activityEqual(this.current, next)) return; this.current = next; - void this.dispatcher.dispatch( - new AgentActivityUpdated({ ...next, agentId: this.scopeContext.agentId }), - ); + this.eventBus.publish({ type: 'agent.activity.updated', ...next }); } } diff --git a/packages/agent-core-v2/src/agent/agentContext/agentContext.ts b/packages/agent-core-v2/src/agent/agentContext/agentContext.ts deleted file mode 100644 index 4c667450f..000000000 --- a/packages/agent-core-v2/src/agent/agentContext/agentContext.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { AgentSpace } from './agentSpace'; - -export interface AgentContext { - readonly agentId: string; - readonly generation: number; - readonly space: AgentSpace; -} diff --git a/packages/agent-core-v2/src/agent/agentContext/agentSpace.ts b/packages/agent-core-v2/src/agent/agentContext/agentSpace.ts deleted file mode 100644 index db963e274..000000000 --- a/packages/agent-core-v2/src/agent/agentContext/agentSpace.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { BugIndicatingError } from '#/_base/errors/errors'; -import { onUnexpectedError } from '#/_base/errors/unexpectedError'; -import type { StateKey } from '#/_base/state/stateRegistry'; -import type { Event2 } from '#/app/event/event2'; -import { - type AgentModel, - type AgentModelBridge, - type AgentModelDefinition, -} from '#/state/agentModel'; - -import type { AgentContext } from './agentContext'; - -export type AgentModelInstanceOf<D> = D extends AgentModelDefinition<any, infer M> ? M : never; - -export interface AgentSpace { - use<D extends AgentModelDefinition<any, any>, R>( - definition: D, - run: (model: AgentModelInstanceOf<D>) => R, - ): R; -} - -export interface AgentSpaceHost { - isActiveModelDefinition(definition: AgentModelDefinition<any, any>): boolean; - registerModel(definition: AgentModelDefinition<any, any>, model: AgentModel<any>): void; - dispatchModelEvent(event: Event2<any>): Promise<void>; - readLegacyState(key: StateKey<any>): unknown; -} - -interface ModelEntry { - readonly definition: AgentModelDefinition<any, any>; - readonly model: AgentModel<any>; - leases: number; - retired: boolean; - disposed: boolean; -} - -export class AgentSpaceImpl implements AgentSpace { - private readonly instances = new Map<AgentModelDefinition<any, any>, ModelEntry>(); - private host: AgentSpaceHost | undefined; - private context: AgentContext | undefined; - private dead = false; - - constructor(private readonly agentId: string) {} - - _bindContext(context: AgentContext): void { - this.context = context; - } - - _attachHost(host: AgentSpaceHost): void { - this.host = host; - } - - _detachHost(host: AgentSpaceHost): void { - if (this.host === host) this.host = undefined; - } - - use<D extends AgentModelDefinition<any, any>, R>( - definition: D, - run: (model: AgentModelInstanceOf<D>) => R, - ): R { - const entry = this.ensureModel(definition); - entry.leases += 1; - let result: R; - try { - result = run(entry.model as AgentModelInstanceOf<D>); - } catch (error) { - this.release(entry); - throw error; - } - if (result instanceof Promise) { - return result.finally(() => { - this.release(entry); - }) as R; - } - this.release(entry); - return result; - } - - ensureModel(definition: AgentModelDefinition<any, any>): ModelEntry { - const existing = this.instances.get(definition); - if (existing !== undefined) return existing; - if (this.dead) { - throw new Error(`Agent ${this.agentId} space is disposed`); - } - const host = this.host; - if (host === undefined) { - throw new BugIndicatingError(`Agent ${this.agentId} space has no model host`); - } - if (!host.isActiveModelDefinition(definition)) { - throw new Error(`Model definition '${definition.id}' is unavailable`); - } - const context = this.context; - if (context === undefined) { - throw new BugIndicatingError(`Agent ${this.agentId} space is not bound to a context`); - } - const bridge: AgentModelBridge = { - dispatch: (event) => host.dispatchModelEvent(event), - readLegacy: (key) => host.readLegacyState(key), - initialState: () => Object.freeze(definition.state.initial()), - }; - const model = new definition.model({ agent: context, bridge }); - model._seal(); - validateApplierCoverage(definition, model); - const entry: ModelEntry = { definition, model, leases: 0, retired: false, disposed: false }; - this.instances.set(definition, entry); - host.registerModel(definition, model); - return entry; - } - - retireModel(definition: AgentModelDefinition<any, any>): void { - const entry = this.instances.get(definition); - if (entry === undefined) return; - this.instances.delete(definition); - entry.retired = true; - if (entry.leases === 0) this.disposeEntry(entry); - } - - _kill(): void { - if (this.dead) return; - this.dead = true; - const entries = [...this.instances.values()]; - this.instances.clear(); - for (const entry of entries) { - entry.retired = true; - if (entry.leases === 0) this.disposeEntry(entry); - } - } - - private release(entry: ModelEntry): void { - entry.leases -= 1; - if (entry.leases === 0 && entry.retired) this.disposeEntry(entry); - } - - private disposeEntry(entry: ModelEntry): void { - if (entry.disposed) return; - entry.disposed = true; - try { - const result = entry.model.dispose(); - if (result instanceof Promise) { - result.catch((error: unknown) => onUnexpectedError(error)); - } - } catch (error) { - onUnexpectedError(error); - } - } -} - -function validateApplierCoverage( - definition: AgentModelDefinition<any, any>, - model: AgentModel<any>, -): void { - const registered = model._appliersTable(); - for (const cls of definition.events) { - if (!registered.has(cls)) { - throw new BugIndicatingError( - `Agent model '${definition.id}' does not apply declared event '${cls.type}'`, - ); - } - } - for (const cls of registered.keys()) { - if (!definition.events.includes(cls)) { - throw new BugIndicatingError( - `Agent model '${definition.id}' applies undeclared event '${cls.type}'`, - ); - } - } -} - -export function agentSpaceOf(agent: AgentContext): AgentSpace { - const space = (agent as { readonly space?: AgentSpace }).space; - if (space === undefined) { - throw new Error( - `Agent ${agent.agentId}:${String(agent.generation)} is not a lifecycle-issued context`, - ); - } - return space; -} diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts index db0eba9e4..a7efdff13 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminder.ts @@ -1,3 +1,14 @@ +/** + * `agentsMdReminder` domain — AGENTS.md discovery-reminder contract. + * + * Defines the `IAgentAgentsMdReminderService`, the seed side of the domain: + * `profile` reports the AGENTS.md paths it injected into the system prompt + * (on every profile apply, with the agent's effective cwd), and `sessionInit` + * re-seeds after `/init` regenerates the file, so the reminder hook can tell + * "already injected" apart from newly discovered instruction files. Bound at + * Agent scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IAgentAgentsMdReminderService { diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts index 444014476..0076f8560 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/agentsMdReminderService.ts @@ -1,18 +1,80 @@ +/** + * `agentsMdReminder` domain — `IAgentAgentsMdReminderService` + * implementation. + * + * Self-wiring plugin: registers an `onDidExecuteTool` hook on `toolExecutor` + * that probes the directories a tool call touches for AGENTS.md files the + * system prompt did not inject, and prepends a once-per-agent + * `<system-reminder>` to the result suggesting the model read them (head + * insertion on purpose: oversized results are truncated to a short head + * preview later in the execution pipeline, and a tail reminder would be + * silently dropped after the file was already counted as reminded). + * `Read`/`Edit`/`Write` consume the canonical file access declared by their + * resolved execution (a successful touch landing on an AGENTS.md itself marks + * just that file known), `Glob`/`Grep` consume their canonical search root, + * and `Bash` contributes its explicit `cwd` plus the literal directory + * operands extracted from the command's syntax tree (see `./bashTargets`), + * resolved against the frozen + * `sessionContext.cwd` exactly like the Bash tool itself (`args.cwd ?? + * sessionContext.cwd` — a base that deliberately differs from the live agent + * cwd after a chdir). Only calls whose `ToolDidExecuteContext.outcome` is + * `executed` are probed: preflight rejects, resolution failures, aborts, + * permission vetoes, and synthetic/duplicate results have not touched the + * requested resource and are left unchanged. The hook is ordered before + * `toolDedupe` so an executed original carries the reminder into the + * deferred result returned for a duplicate; no dedupe implementation state is + * needed here. The ordered registration throws when its target is absent, so + * scopes without `toolDedupe` fall back to plain append-order registration, + * which still lands ahead of a `toolDedupe` hook constructed later. + * + * Known-set discipline: candidates are claimed synchronously per discovered + * file into an in-memory `claimed` set (parallel calls can never duplicate a + * reminder and a failed attempt releases the claim), while `agentState` + * (`agentsMdReminder.known`) is only ever whole-value replaced after the + * reminder text is attached and the telemetry emitted — never mutated in + * place, and never ahead of the reminder it records. Probing anchors at the + * nearest existing ancestor (so `Write` into a not-yet-created directory + * still resolves), walks `findProjectRoot → touched dir`, skips chain + * directories whose candidates are all known, and applies the same + * per-directory candidate rules as the init-time load (shared through + * `profile/context`'s `findAgentsMdInDir`; blank files are included in + * neither). Directories with unknown candidates are re-statted on every + * qualifying call — deliberate, so an AGENTS.md created mid-session is + * picked up on the next touch; there is no negative cache. Probing is + * lexical like the tools' own path policy: a symlinked directory's AGENTS.md + * is discovered through the link at its lexical address, never by realpath. + * The hook never throws — a probe failure yields the untouched result. + * + * Seeding: `profile` reports the injected paths after every successful + * bind/apply/refresh and `sessionInit` re-seeds after `/init`. A prompt can + * also commit without any of those entry points — session resume and forks + * restore the already-rendered system prompt (AGENTS.md content included) + * from the wire journal or a binding snapshot. The wire restore hook seeds + * the exact persisted paths (legacy prompts recover their source annotations), + * so the first qualifying call of a never-seeded agent does not confuse the + * current filesystem with the restored prompt. The seeded cwd lives in + * `agentState` as well; restored provenance comes from `wire`/`profile`; fs + * probes go through the os `IHostFileSystem`, the home directory through + * `IHostEnvironment`, the brand home through `bootstrap`, syntax + * trees through `bashParser`, and the shown-event + * through `telemetry`. Bound at Agent scope. + */ + import { basename, dirname, isAbsolute, join, normalize } from 'pathe'; import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IBashParserService } from '#/app/bashParser/bashParser'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import type { AgentsMdReminderShownEvent } from '#/app/telemetry/events'; import { ITelemetryService } from '#/app/telemetry/telemetry'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { HostFsChange } from '#/os/interface/hostFsWatch'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; +import type { ContentPart } from '#/kosong/contract/message'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; +import type { ExecutableToolOutput, ExecutableToolResult } from '#/tool/toolContract'; import { normalizeUserPath } from '#/tool/path-access'; import { AGENTS_MD_PLAIN_NAMES, @@ -23,14 +85,11 @@ import { extractAgentsMdPathsFromSystemPrompt, loadAgentsMdDetailed, } from '#/agent/profile/context'; -import { profileKey } from '#/agent/profile/profileOps'; +import { ProfileModel } from '#/agent/profile/profileOps'; import { IAgentStateService } from '#/agent/state/agentState'; -import { AgentReminder, type ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; import type { ToolDidExecuteContext } from '#/agent/toolExecutor/toolHooks'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { IAgentAgentsMdReminderService } from './agentsMdReminder'; import { extractBashTargetDirs } from './bashTargets'; @@ -60,30 +119,22 @@ export class AgentAgentsMdReminderService constructor( @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentStateService private readonly states: IAgentStateService, @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, @IBootstrapService private readonly bootstrap: IBootstrapService, @IBashParserService private readonly bashParser: IBashParserService, @ITelemetryService private readonly telemetry: ITelemetryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentStateService private readonly agentState: IAgentStateService, - @ISessionInstructionsProvider private readonly instructions: ISessionInstructionsProvider, + @IWireService private readonly wire: IWireService, ) { super(); - this.states.contributeState(agentsMdReminderKnownKey); - this.states.contributeState(agentsMdReminderCwdKey); - this.states.contributeState(agentsMdReminderSeededKey); + this.states.register(agentsMdReminderKnownKey); + this.states.register(agentsMdReminderCwdKey); + this.states.register(agentsMdReminderSeededKey); this._register( - this.instructions.onDidChange((changes) => { - this.announceChanged(changes); - }), - ); - this._register( - this.dispatcher.hooks.onDidRestore.register('agentsMdReminder', async (_ctx, next) => { - const profile = this.agentState.get(profileKey); + this.wire.hooks.onDidRestore.register('agentsMdReminder', async (_ctx, next) => { + const profile = this.wire.getModel(ProfileModel); const paths = profile.agentsMdPaths ?? extractAgentsMdPathsFromSystemPrompt(profile.systemPrompt); this.seedInjected(paths, this.sessionContext.cwd); @@ -91,10 +142,14 @@ export class AgentAgentsMdReminderService }), ); const handler = async (ctx: ToolDidExecuteContext, next: () => Promise<void>): Promise<void> => { - await this.probeAndRemind(ctx); + ctx.result = await this.augmentWithReminder(ctx); await next(); }; - this._register(toolExecutor.hooks.onDidExecuteTool.register('agentsMdReminder', handler)); + try { + this._register(toolExecutor.hooks.onDidExecuteTool.register('agentsMdReminder', handler, { before: 'toolDedupe' })); + } catch { + this._register(toolExecutor.hooks.onDidExecuteTool.register('agentsMdReminder', handler)); + } } seedInjected(paths: readonly string[], cwd: string): void { @@ -105,23 +160,6 @@ export class AgentAgentsMdReminderService this.states.set(agentsMdReminderSeededKey, true); } - private announceChanged(changes: readonly HostFsChange[]): void { - if (!this.states.get(agentsMdReminderSeededKey)) return; - const entries = new Map<string, HostFsChange>(); - for (const change of changes) { - const path = normalize(change.path); - entries.set(path, { ...change, path }); - } - if (entries.size === 0) return; - const list = [...entries.values()]; - this.reminder().notify(changeReminderText(list), { - variant: 'agents_md_change', - }); - this.publishKnown( - list.filter((change) => change.action !== 'deleted').map((change) => change.path), - ); - } - private readonly claimed = new Set<string>(); private get known(): Set<string> { @@ -134,21 +172,16 @@ export class AgentAgentsMdReminderService private async ensureSeeded(): Promise<void> { if (this.states.get(agentsMdReminderSeededKey)) return; - const lease = this.runtime.acquire(['fs']); - try { - const { paths } = await loadAgentsMdDetailed( - { fs: lease.runtime.fs!, homeDir: lease.runtime.environment.homeDir }, - this.agentCwd, - this.bootstrap.homeDir, - ); - this.seedInjected(paths, this.agentCwd); - } finally { - lease.dispose(); - } + const { paths } = await loadAgentsMdDetailed( + { fs: this.fs, homeDir: this.env.homeDir }, + this.agentCwd, + this.bootstrap.homeDir, + ); + this.seedInjected(paths, this.agentCwd); } - private async probeAndRemind(ctx: ToolDidExecuteContext): Promise<void> { - if (ctx.outcome !== 'executed') return; + private async augmentWithReminder(ctx: ToolDidExecuteContext): Promise<ExecutableToolResult> { + if (ctx.outcome !== 'executed') return ctx.result; const discovered: string[] = []; try { await this.ensureSeeded(); @@ -163,8 +196,9 @@ export class AgentAgentsMdReminderService } if (discovered.length === 0) { this.publishKnown(selfKnown); - return; + return ctx.result; } + const result = prependReminder(ctx.result, reminderText(discovered)); const properties: AgentsMdReminderShownEvent = { turn_id: ctx.turnId, tool_name: ctx.toolCall.name, @@ -172,19 +206,15 @@ export class AgentAgentsMdReminderService trace_id: ctx.trace?.traceId, }; this.telemetry.track2('agents_md_reminder_shown', properties); - this.reminder().notify(reminderText(discovered), { - variant: 'agents_md', - }); this.publishKnown([...selfKnown, ...discovered]); - } catch {} finally { + return result; + } catch { + return ctx.result; + } finally { for (const path of discovered) this.claimed.delete(path); } } - private reminder(): ReminderRuntime { - return this.agentLifecycle.resolve(this.scopeContext.agentContext, AgentReminder); - } - private publishKnown(paths: readonly string[]): void { if (paths.length === 0) return; const merged = new Set(this.known); @@ -194,9 +224,6 @@ export class AgentAgentsMdReminderService private targetDirs(ctx: ToolDidExecuteContext): { dirs: string[]; selfKnown: string[] } { const selfKnown: string[] = []; - const lease = this.runtime.acquire(); - const env = lease.runtime.environment; - lease.dispose(); switch (ctx.toolCall.name) { case 'Read': case 'Edit': @@ -209,9 +236,9 @@ export class AgentAgentsMdReminderService const command = stringArg(args, 'command'); if (command === undefined) return { dirs: [], selfKnown }; const cwdArg = stringArg(args, 'cwd'); - const base = hostPath(this.sessionContext.cwd, env.pathClass); + const base = hostPath(this.sessionContext.cwd, this.env.pathClass); const normalizedCwdArg = - cwdArg === undefined ? undefined : normalizeUserPath(cwdArg, env.pathClass); + cwdArg === undefined ? undefined : normalizeUserPath(cwdArg, this.env.pathClass); const effectiveCwd = normalizedCwdArg === undefined ? base @@ -229,8 +256,8 @@ export class AgentAgentsMdReminderService const targets = extractBashTargetDirs( parsed.root, effectiveCwd, - env.homeDir, - ).map((target) => hostPath(target, env.pathClass)); + this.env.homeDir, + ).map((target) => hostPath(target, this.env.pathClass)); if (normalizedCwdArg !== undefined && !targets.includes(effectiveCwd)) { targets.unshift(effectiveCwd); } @@ -266,32 +293,26 @@ export class AgentAgentsMdReminderService } private async probeDir(dir: string): Promise<string[]> { - const lease = this.runtime.acquire(['fs']); - try { - const fs = lease.runtime.fs!; - const anchor = await this.nearestExistingDir(fs, dir); - if (anchor === undefined) return []; - const deps = { fs }; - const projectRoot = await findProjectRoot(deps, anchor); - const chain = dirsRootToLeaf(anchor, projectRoot); - const found: string[] = []; - for (const chainDir of chain) { - const candidates = agentsMdCandidatePaths(chainDir); - if (candidates.every((candidate) => this.known.has(normalize(candidate)))) continue; - for (const path of await findAgentsMdInDir(deps, chainDir)) { - found.push(normalize(path)); - } + const anchor = await this.nearestExistingDir(dir); + if (anchor === undefined) return []; + const deps = { fs: this.fs }; + const projectRoot = await findProjectRoot(deps, anchor); + const chain = dirsRootToLeaf(anchor, projectRoot); + const found: string[] = []; + for (const chainDir of chain) { + const candidates = agentsMdCandidatePaths(chainDir); + if (candidates.every((candidate) => this.known.has(normalize(candidate)))) continue; + for (const path of await findAgentsMdInDir(deps, chainDir)) { + found.push(normalize(path)); } - return found; - } finally { - lease.dispose(); } + return found; } - private async nearestExistingDir(fs: IHostFileSystem, path: string): Promise<string | undefined> { + private async nearestExistingDir(path: string): Promise<string | undefined> { let current = path; for (;;) { - const stat = await fs.stat(current).catch(() => undefined); + const stat = await this.fs.stat(current).catch(() => undefined); if (stat?.isDirectory === true) return current; const parent = dirname(current); if (parent === current) return undefined; @@ -312,20 +333,32 @@ function stringArg(args: unknown, key: string): string | undefined { function reminderText(paths: readonly string[]): string { return ( - 'The path(s) touched by a recent tool call are covered by AGENTS.md instruction file(s) that were not part of the injected instructions:\n' + + '<system-reminder>\n' + + 'The path(s) touched by this call are covered by AGENTS.md instruction file(s) that were not part of the injected instructions:\n' + paths.map((path) => `- ${path}`).join('\n') + - '\nRead them before making changes in those directories. Each file is suggested at most once per agent.' + '\nRead them before making changes in those directories. Each file is suggested at most once per agent.' + + '\n</system-reminder>\n\n' ); } -function changeReminderText(changes: readonly HostFsChange[]): string { - return ( - 'The AGENTS.md instruction file(s) below changed on disk after they were injected into the system prompt:\n' + - changes - .map((change) => `- ${change.path}${change.action === 'deleted' ? ' (deleted)' : ''}`) - .join('\n') + - '\nRead the current file(s) and follow the latest contents; the copies injected in the system prompt are stale.' - ); +function prependReminder(result: ExecutableToolResult, text: string): ExecutableToolResult { + const output = result.output; + let newOutput: ExecutableToolOutput; + if (typeof output === 'string') { + newOutput = text + output; + } else { + const parts: ContentPart[] = [...output]; + const first = parts[0]; + if (first !== undefined && first.type === 'text') { + parts[0] = { type: 'text', text: text + first.text }; + } else { + parts.unshift({ type: 'text', text }); + } + newOutput = parts; + } + return result.isError === true + ? { ...result, output: newOutput, isError: true } + : { ...result, output: newOutput }; } registerScopedService( diff --git a/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts b/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts index 418057bbe..eed1b7727 100644 --- a/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts +++ b/packages/agent-core-v2/src/agent/agentsMdReminder/bashTargets.ts @@ -1,3 +1,26 @@ +/** + * `agentsMdReminder` domain — Bash-command directory extraction. + * + * Statically extracts the directories a Bash tool call is going to inspect, + * walking the `bashParser` syntax tree: the literal operands of + * directory-listing commands (`ls` / `tree` / `find` / `dir` / `exa` / `eza` / + * `lsd`), with literal `cd` commands rebasing relative resolution as they + * appear (`cd packages && ls kap-server`) and a genuinely operand-less + * listing command listing the current base (one whose operands all failed + * resolution is skipped instead). Only top-level simple commands are read — + * anything not statically resolvable (expansions, command + * substitution, glob characters (quoted or not), `~`, quoting mixes, compound + * constructs, `cd -`, a `cd` inside a pipeline, or a listing command invoked + * through a path prefix like `./ls` whose semantics are unknown) is skipped, + * and a `cd` whose operand cannot be resolved poisons relative resolution + * (never guesses a base) until an absolute `cd` re-anchors. Flags are dropped + * together with the arguments of the known argument-taking options + * (`ls --sort size`), and `find` collects leading paths past its no-argument + * global options (`find -L packages`) before stopping at the expression. + * A missed directory is recovered by the later Read/Edit/Write + * probes; a wrong one is not, so skipping always wins over guessing. + */ + import { isAbsolute, join, normalize } from 'pathe'; import type { BashSyntaxNode } from '#/app/bashParser/bashParser'; diff --git a/packages/agent-core-v2/src/agent/blob/agentBlobService.ts b/packages/agent-core-v2/src/agent/blob/agentBlobService.ts index 94bfd6a7b..1524e7cab 100644 --- a/packages/agent-core-v2/src/agent/blob/agentBlobService.ts +++ b/packages/agent-core-v2/src/agent/blob/agentBlobService.ts @@ -1,3 +1,10 @@ +/** + * `blob` domain — `IAgentBlobService` contract. + * + * Offloads large inline media payloads to content-addressed blob storage and + * loads them back on read. Bound at Agent scope. + */ + import type { ContentPart } from '#/kosong/contract/message'; import { createDecorator } from "#/_base/di/instantiation"; diff --git a/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts b/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts index 2ad64a8a2..d3e13057c 100644 --- a/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts +++ b/packages/agent-core-v2/src/agent/blob/agentBlobServiceImpl.ts @@ -1,3 +1,12 @@ +/** + * `blob` domain — `IAgentBlobService` implementation. + * + * Offloads large inline media payloads into content-addressed blobs and + * loads them back on read; persists bytes through `IBlobStore` under the + * agent's `scope('blobs')` root, matching the v1 `<agentDir>/blobs/<sha256>` + * layout. Bound at Agent scope. + */ + import { createHash } from 'node:crypto'; import type { ContentPart } from '#/kosong/contract/message'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/agent/blob/byteLruCache.ts b/packages/agent-core-v2/src/agent/blob/byteLruCache.ts index 0a182d959..06b18477d 100644 --- a/packages/agent-core-v2/src/agent/blob/byteLruCache.ts +++ b/packages/agent-core-v2/src/agent/blob/byteLruCache.ts @@ -1,3 +1,16 @@ +/** + * `blob` domain — byte-bounded LRU cache. + * + * A small, dependency-free cache whose capacity is measured in **bytes** rather + * than entries. Hits refresh an entry to most-recently-used; inserts evict the + * least-recently-used entries until the payload fits. A single payload larger + * than `maxBytes` is never cached. + * + * Module-private helper; not part of the package surface. Owned as a value + * (not a DI service) so each agent keeps its own cache. Promote to a shared + * util only when a second caller appears. + */ + export class ByteLruCache { private readonly map = new Map<string, Buffer>(); private currentBytes = 0; diff --git a/packages/agent-core-v2/src/agent/command/agentCommand.ts b/packages/agent-core-v2/src/agent/command/agentCommand.ts index 16ece5924..5fe6db25f 100644 --- a/packages/agent-core-v2/src/agent/command/agentCommand.ts +++ b/packages/agent-core-v2/src/agent/command/agentCommand.ts @@ -1,3 +1,12 @@ +/** + * `command` domain — the `IAgentCommandService` contract. + * + * The agent-scope registry over the `CommandContribution` collection: lists + * the contributed executable commands (name-level dedup, last record wins, + * `source` = provider unit name) and runs one by name with an args string. + * Bound at Agent scope. + */ + import type { Event } from '#/_base/event'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/command/agentCommandService.ts b/packages/agent-core-v2/src/agent/command/agentCommandService.ts index 33fde5a27..27379d570 100644 --- a/packages/agent-core-v2/src/agent/command/agentCommandService.ts +++ b/packages/agent-core-v2/src/agent/command/agentCommandService.ts @@ -1,3 +1,15 @@ +/** + * `command` domain — `IAgentCommandService` implementation. + * + * The fold over the `CommandContribution` collection (`command`): `list()` + * dedupes the live records by name (a later record shadows an earlier one of + * the same name), and `run` invokes the contribution's callback inside an + * `invokeFunction` so its `ctx.get` resolves through the agent container. + * Unknown names fail with a coded `REQUEST_INVALID` error. Bound at Agent + * scope; constructed on demand — nothing pushes to a command registry, every + * consumer pulls. + */ + import { Emitter, type Event } from '#/_base/event'; import { type CollectionRecord, type CollectionView } from '#/_base/di/collection'; import { diff --git a/packages/agent-core-v2/src/agent/command/commandContribution.ts b/packages/agent-core-v2/src/agent/command/commandContribution.ts index f902c3a6f..73a63da3c 100644 --- a/packages/agent-core-v2/src/agent/command/commandContribution.ts +++ b/packages/agent-core-v2/src/agent/command/commandContribution.ts @@ -1,3 +1,15 @@ +/** + * `command` domain — the `CommandContribution` collection token and payload. + * + * An executable command a Feature (or any unit) contributes into the + * agent-scope registry (`IAgentCommandService`) — unlike plugin commands, + * which are prompt templates, a contributed command runs engine-side with DI + * access. `run` receives a `CommandRunContext` whose `get` resolves services + * from the target agent's container; the records carry the provider unit's + * name as `source`, and a record is withdrawn when its provider dies. No + * scoped state — pure payload + token. + */ + import { collection } from '#/_base/di/collection'; import type { ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/contextInjector/contextInjector.ts b/packages/agent-core-v2/src/agent/contextInjector/contextInjector.ts new file mode 100644 index 000000000..e0114977f --- /dev/null +++ b/packages/agent-core-v2/src/agent/contextInjector/contextInjector.ts @@ -0,0 +1,42 @@ +import { createDecorator } from "#/_base/di/instantiation"; +import type { IDisposable } from "#/_base/di/lifecycle"; +import type { ContentPart } from "#/kosong/contract/message"; +import type { ContextInjectionDisclosure, ContextMessage } from '#/agent/contextMemory/types'; + +export interface ContextInjectionContext { + readonly injectedPositions: readonly number[]; + readonly lastInjectedAt: number | null; + readonly lastInjection?: ContextMessage; + readonly lastDisclosure?: ContextInjectionDisclosure; + readonly isNewTurn: boolean; +} + +export type ContextInjectionContent = string | readonly ContentPart[]; + +export interface ContextInjectionResult { + readonly content: ContextInjectionContent; + readonly disclosure?: ContextInjectionDisclosure; +} + +export type ContextInjectionProvider = ( + context: ContextInjectionContext, +) => + | ContextInjectionContent + | ContextInjectionResult + | undefined + | Promise<ContextInjectionContent | ContextInjectionResult | undefined>; + +export interface IAgentContextInjectorService { + readonly _serviceBrand: undefined; + + register( + name: string, + provider: ContextInjectionProvider, + ): IDisposable; + + injectAfterCompaction(): Promise<void>; +} + +export const IAgentContextInjectorService = createDecorator<IAgentContextInjectorService>( + 'agentContextInjectorService', +); diff --git a/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts b/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts new file mode 100644 index 000000000..0bb8cc085 --- /dev/null +++ b/packages/agent-core-v2/src/agent/contextInjector/contextInjectorService.ts @@ -0,0 +1,223 @@ +/** + * `contextInjector` domain — `IAgentContextInjectorService` implementation. + * + * Injects registered context providers through `loop` and `systemReminder`, + * tracks their positions in `contextMemory` through `eventBus`, and reconciles + * those positions after `wire` restoration. Each provider call receives the + * newest surviving injection of its own variant (`lastInjection`) and the + * typed disclosure recorded on it (`lastDisclosure`), so providers never read + * context layout or position indexes themselves. The plain-data `isNewTurn` + * flag is registered into `agentState` (`IAgentStateService`) and read/written + * through it; `entries` stays a plain instance field (its values hold provider + * functions, not plain data). Bound at Agent scope. + */ + +import { toDisposable } from "#/_base/di/lifecycle"; +import { Service } from "#/_base/di/service"; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; + +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import { IAgentLoopService } from '#/agent/loop/loop'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { IEventBus } from '#/app/event/eventBus'; +import type { ContextMessage } from '#/agent/contextMemory/types'; +import { IWireService } from '#/wire/wire'; +import { + IAgentContextInjectorService, + type ContextInjectionContent, + type ContextInjectionProvider, + type ContextInjectionResult, +} from './contextInjector'; + +interface ContextInjectionEntry { + readonly provider: ContextInjectionProvider; + readonly name: string; + readonly positions: number[]; +} + +export const contextInjectorIsNewTurnKey = defineState<boolean>( + 'contextInjector.isNewTurn', + () => true, +); + +export class AgentContextInjectorService extends Service implements IAgentContextInjectorService { + declare readonly _serviceBrand: undefined; + private readonly entries = new Set<ContextInjectionEntry>(); + + constructor( + @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, + @IAgentLoopService loopService: IAgentLoopService, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, + @IEventBus private readonly eventBus: IEventBus, + @IWireService wire: IWireService, + @IAgentStateService private readonly states: IAgentStateService, + ) { + super(); + this.states.register(contextInjectorIsNewTurnKey); + this._register( + loopService.hooks.onWillBeginStep.register('context-injector', async (_ctx, next) => { + await next(); + await this.inject(); + }), + ); + this._register( + this.eventBus.subscribe('turn.started', () => { + this.isNewTurn = true; + }), + ); + this._register( + this.eventBus.subscribe('context.spliced', (e) => { + this.handleSplice(e); + }), + ); + this._register( + wire.hooks.onDidRestore.register('context-injector', async (_ctx, next) => { + this.resyncPositions(); + await next(); + }), + ); + } + + private get isNewTurn(): boolean { + return this.states.get(contextInjectorIsNewTurnKey); + } + + private set isNewTurn(value: boolean) { + this.states.set(contextInjectorIsNewTurnKey, value); + } + + register( + name: string, + provider: ContextInjectionProvider, + ) { + const positions = findInjections(this.context.get(), name); + const entry: ContextInjectionEntry = { + provider, + name, + positions, + }; + this.entries.add(entry); + return toDisposable(() => { + this.entries.delete(entry); + }); + } + + async injectAfterCompaction(): Promise<void> { + this.isNewTurn = true; + await this.inject(); + } + + private async inject(): Promise<void> { + const isNewTurn = this.isNewTurn; + this.isNewTurn = false; + const history = this.context.get(); + for (const entry of this.entries) { + const injectedPositions: readonly number[] = [...entry.positions]; + const lastInjectedAt = injectedPositions.at(-1) ?? null; + const lastInjection = lastInjectedAt === null ? undefined : history[lastInjectedAt]; + const content = await entry.provider({ + injectedPositions, + lastInjectedAt, + lastInjection, + lastDisclosure: + lastInjection?.origin?.kind === 'injection' + ? lastInjection.origin.disclosure + : undefined, + isNewTurn, + }); + if (!this.entries.has(entry)) continue; + if (content === undefined) continue; + const result: ContextInjectionResult = + typeof content === 'object' && content !== null && !Array.isArray(content) + ? (content as ContextInjectionResult) + : { content: content as ContextInjectionContent }; + const origin = { + kind: 'injection' as const, + variant: entry.name, + disclosure: result.disclosure, + }; + if (typeof result.content === 'string') { + if (result.content.trim().length === 0) continue; + this.reminders.appendSystemReminder(result.content, origin); + continue; + } + if (result.content.length === 0) continue; + this.context.append({ + role: 'user', + content: [...result.content], + toolCalls: [], + origin, + }); + } + } + + private resyncPositions(): void { + const history = this.context.get(); + for (const entry of this.entries) { + const found = findInjections(history, entry.name); + entry.positions.length = 0; + entry.positions.push(...found); + } + } + + private handleSplice(splice: ContextSplice): void { + let insertedInjections: Map<string, number[]> | undefined; + splice.messages.forEach((message, offset) => { + if (message.origin?.kind !== 'injection') return; + insertedInjections ??= new Map(); + const positions = insertedInjections.get(message.origin.variant); + if (positions === undefined) { + insertedInjections.set(message.origin.variant, [splice.start + offset]); + } else { + positions.push(splice.start + offset); + } + }); + if (insertedInjections === undefined && splice.deleteCount === 0) return; + + const deletedEnd = splice.start + splice.deleteCount; + const delta = splice.messages.length - splice.deleteCount; + for (const entry of this.entries) { + const adopted = insertedInjections?.get(entry.name) ?? []; + const positions = entry.positions; + if (adopted.length === 0 && positions.length === 0) continue; + let lo = 0; + while (lo < positions.length && positions[lo]! < splice.start) lo++; + let hi = lo; + while (hi < positions.length && positions[hi]! < deletedEnd) hi++; + for (let index = hi; index < positions.length; index++) { + positions[index] = positions[index]! + delta; + } + positions.splice(lo, hi - lo, ...adopted); + } + } +} + +type ContextSplice = { + readonly start: number; + readonly deleteCount: number; + readonly messages: readonly ContextMessage[]; +}; + +function findInjections( + history: readonly ContextMessage[], + variant: string, +): number[] { + const positions: number[] = []; + history.forEach((message, index) => { + if (message.origin?.kind === 'injection' && message.origin.variant === variant) { + positions.push(index); + } + }); + return positions; +} + +registerScopedService( + LifecycleScope.Agent, + IAgentContextInjectorService, + AgentContextInjectorService, + ScopeActivation.OnScopeCreated, + 'contextInjector', +); diff --git a/packages/agent-core-v2/src/agent/contextInjector/disclosureBaseline.ts b/packages/agent-core-v2/src/agent/contextInjector/disclosureBaseline.ts new file mode 100644 index 000000000..ceff302ca --- /dev/null +++ b/packages/agent-core-v2/src/agent/contextInjector/disclosureBaseline.ts @@ -0,0 +1,38 @@ +/** + * `contextInjector` domain (L4) — disclosure-baseline helpers for reminder + * providers (currently `date_change`). + * + * A provider's baseline answers "what has the model already seen" from up to + * three sources, compared by render generation with ties won by the earlier + * argument: the typed disclosure on the provider's newest surviving + * in-context injection (newest in time on a tie, since the persisted floor + * never advances when a reminder fires), the persisted render-time floor, and + * a runtime seed recorded on first observation. Internal to the package; not + * part of the barrel export. + */ + +import type { ContextInjectionDisclosure } from '#/agent/contextMemory/types'; + +export function disclosureOfKind<K extends ContextInjectionDisclosure['kind']>( + disclosure: ContextInjectionDisclosure | undefined, + kind: K, +): Extract<ContextInjectionDisclosure, { kind: K }> | undefined { + return disclosure?.kind === kind + ? (disclosure as Extract<ContextInjectionDisclosure, { kind: K }>) + : undefined; +} + +export function pickDisclosureBaseline<T extends { readonly renderGeneration: number }>( + ...candidates: readonly (T | undefined)[] +): T | undefined { + let winner: T | undefined; + for (const candidate of candidates) { + if ( + candidate !== undefined && + (winner === undefined || candidate.renderGeneration > winner.renderGeneration) + ) { + winner = candidate; + } + } + return winner; +} diff --git a/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts b/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts index 11a6a9f73..63a8af0e4 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/compactionHandoff.ts @@ -1,6 +1,18 @@ +/** + * `contextMemory` domain helper — derives the v1-compatible full-compaction + * handoff shape for live rewrites, wire replay, and snapshot reducers. + * + * Token budgeting runs through an injectable {@link TokenEstimate}: the live + * path (`AgentContextMemoryService.applyCompaction`) passes the estimator + * from `IAgentTokenCountingService` (the raw heuristics — the + * `[token_counting]` strategy never gates internal estimates); the pure + * wire-replay / reducer paths keep the same heuristics — their estimate + * fallback only fires when a record lacks `tokensAfter`, so the measured + * chain is unaffected. + */ + import { estimateTokens, estimateTokensForMessage, estimateTokensForMessages } from '#/kosong/contract/tokens'; import type { ContentPart } from '#/kosong/contract/message'; -import { wrapSystemReminder } from '#/features/reminder/systemReminder'; import summaryPrefixTemplate from './compaction-summary-prefix.md?raw'; import type { ContextMessage, PromptOrigin } from './types'; @@ -11,6 +23,7 @@ export const COMPACTION_ELISION_VARIANT = 'compaction_elision'; type MessageLike = ContextMessage; +/** Injectable token-count estimates; see the file header for who passes what. */ export interface TokenEstimate { readonly text: (text: string) => number; readonly message: (message: MessageLike) => number; @@ -37,7 +50,15 @@ export interface ContextCompactionShapeInput { readonly compactedCount: number; readonly tokensBefore: number; readonly tokensAfter?: number; + /** Measured output tokens of the compaction LLM exchange — the REAL size of + * the generated summary. Preferred over the summary-text estimate in the + * `tokensAfter` fallback when present. */ readonly summaryOutputTokens?: number; + /** Estimated fixed request overhead (system prompt + non-deferred tool + * schemas) surviving the compaction; counted into the `tokensAfter` + * fallback so the result stays on the same full-request basis as the + * measured exchange anchors. Live path only — replay reads the persisted + * `tokensAfter` verbatim. */ readonly requestOverheadTokens?: number; readonly keptUserMessageCount?: number; readonly keptHeadUserMessageCount?: number; @@ -141,9 +162,11 @@ export function createCompactionElisionMessage(omittedTokens: number): ContextMe } export function buildCompactionElisionText(omittedTokens: number): string { - return wrapSystemReminder( + return [ + '<system-reminder>', `Some of this conversation's user messages were omitted here during compaction: the messages above this note are the oldest user input, the messages below are the most recent, and roughly ${String(omittedTokens)} tokens in between were dropped. The omitted content is covered by the compaction summary at the end of the conversation.`, - ); + '</system-reminder>', + ].join('\n'); } export function collectCompactableUserMessages<T extends MessageLike>(messages: readonly T[]): T[] { diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts b/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts deleted file mode 100644 index 2021c8bd7..000000000 --- a/packages/agent-core-v2/src/agent/contextMemory/contextEvents.ts +++ /dev/null @@ -1,124 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; - -import type { LoopRecordedEvent } from './loopEventFold'; -import type { ContextMessage } from './types'; - -const contextMessageSchema = z.custom<ContextMessage>(); -const loopRecordedEventSchema = z.custom<LoopRecordedEvent>(); - -const contextAppendMessageSchema = z.object({ - agentId: z.string(), - message: contextMessageSchema, -}); - -export class ContextAppendMessage extends AgentEvent2< - z.infer<typeof contextAppendMessageSchema> -> { - static override readonly type = 'context.append_message'; - static override readonly durable = true; - static override readonly schema = contextAppendMessageSchema; -} -export interface ContextAppendMessage { - readonly agentId: string; - readonly message: ContextMessage; -} - -const contextAppendLoopEventSchema = z.object({ - agentId: z.string(), - event: loopRecordedEventSchema, -}); - -export class ContextAppendLoopEvent extends AgentEvent2< - z.infer<typeof contextAppendLoopEventSchema> -> { - static override readonly type = 'context.append_loop_event'; - static override readonly durable = true; - static override readonly schema = contextAppendLoopEventSchema; -} -export interface ContextAppendLoopEvent { - readonly agentId: string; - readonly event: LoopRecordedEvent; -} - -const contextClearSchema = z.object({ agentId: z.string() }); - -export class ContextClear extends AgentEvent2<z.infer<typeof contextClearSchema>> { - static override readonly type = 'context.clear'; - static override readonly durable = true; - static override readonly schema = contextClearSchema; -} -export interface ContextClear { - readonly agentId: string; -} - -const contextCompactionBaseShape = { - agentId: z.string(), - tokensBefore: z.number().optional(), - tokensAfter: z.number().optional(), - summaryOutputTokens: z.number().optional(), - keptUserMessageCount: z.number().optional(), - keptHeadUserMessageCount: z.number().optional(), - droppedCount: z.number().optional(), - legacyTail: z.boolean().optional(), -}; - -const contextApplyCompactionSchema = z.union([ - z.object({ - ...contextCompactionBaseShape, - summary: z.string(), - compactedCount: z.number(), - contextSummary: z.string().optional(), - }), - z.object({ - ...contextCompactionBaseShape, - contextSummary: z.string(), - compactedCount: z.number(), - summary: z.string().optional(), - }), - z.object({ - ...contextCompactionBaseShape, - summary: contextMessageSchema, - count: z.number(), - compactedCount: z.number().optional(), - }), -]); - -export type ContextApplyCompactionPayload = z.infer<typeof contextApplyCompactionSchema>; - -export class ContextApplyCompaction extends AgentEvent2<ContextApplyCompactionPayload> { - static override readonly type = 'context.apply_compaction'; - static override readonly durable = true; - static override readonly schema = contextApplyCompactionSchema; -} - -const contextUndoSchema = z.object({ - agentId: z.string(), - count: z.number().int().positive().max(Number.MAX_SAFE_INTEGER), -}); - -export class ContextUndo extends AgentEvent2<z.infer<typeof contextUndoSchema>> { - static override readonly type = 'context.undo'; - static override readonly durable = true; - static override readonly schema = contextUndoSchema; -} -export interface ContextUndo { - readonly agentId: string; - readonly count: number; -} - -export interface ContextSplicedPayload { - readonly agentId: string; - start: number; - deleteCount: number; - messages: readonly ContextMessage[]; - tokens?: number; -} - -export class ContextSpliced extends AgentEvent2<ContextSplicedPayload> { - static override readonly type = 'context.spliced'; - static override readonly observable = true; -} -export interface ContextSpliced extends ContextSplicedPayload {} diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextMemory.ts b/packages/agent-core-v2/src/agent/contextMemory/contextMemory.ts index 1e7162b96..89b5be4f6 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextMemory.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextMemory.ts @@ -10,7 +10,14 @@ export interface ContextCompactionInput { readonly compactedCount: number; readonly tokensBefore: number; readonly tokensAfter?: number; + /** Measured output tokens of the compaction LLM exchange (the REAL summary + * size); preferred over the summary-text estimate in the `tokensAfter` + * fallback when present. */ readonly summaryOutputTokens?: number; + /** Estimated fixed request overhead (system prompt + non-deferred tool + * schemas) that every post-compaction exchange still carries. Counted into + * the `tokensAfter` fallback so the result stays on the same full-request + * basis as the measured exchange anchors. */ readonly requestOverheadTokens?: number; readonly keptUserMessageCount?: number; readonly keptHeadUserMessageCount?: number; @@ -37,8 +44,6 @@ export interface IAgentContextMemoryService { appendLoopEvent(event: LoopRecordedEvent): void; - publishTrailingRemoval(previous: readonly ContextMessage[]): boolean; - clear(): void; undo(count: number): UndoCut; diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts b/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts index a2ccddc31..fb5e00e7e 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextMemoryService.ts @@ -1,10 +1,27 @@ +/** + * `contextMemory` domain — `IAgentContextMemoryService` implementation. + * + * Owns per-agent conversation history through `wire`, maintains measurements + * with `tokenCounting`, and broadcasts live mutations through `event`. Every + * splice-shaped mutation (`clear` / `applyCompaction` / `undo`) publishes + * `context.spliced` from the live path only — replay rebuilds silently — and + * `undo` additionally truncates the measured-anchor ledger when the cut + * crosses an anchor, letting `tokenCounting` restore the surviving prefix's + * REAL size from the remaining anchors. Bound at Agent scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IEventBus } from '#/app/event/eventBus'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; +import { + TokenCountingModel, + tokenCountingRebased, + tokenCountingTruncated, +} from '#/agent/tokenCounting/tokenCountingOps'; +import { IWireService } from '#/wire/wire'; +import type { Op } from '#/wire/op'; import { IAgentContextMemoryService, @@ -12,35 +29,41 @@ import { type ContextCompactionResult, } from './contextMemory'; import { buildContextCompactionShape, type TokenEstimate } from './compactionHandoff'; -import { - ContextApplyCompaction, - ContextAppendLoopEvent, - ContextAppendMessage, - ContextClear, - ContextSpliced, - ContextUndo, - type ContextSplicedPayload, -} from './contextEvents'; import { computeUndoCut, - contextMemoryKey, + ContextModel, + contextAppendLoopEvent, + contextAppendMessage, + contextApplyCompaction, + contextClear, + contextUndo, isFullyUndoable, type UndoCut, } from './contextOps'; import type { LoopRecordedEvent } from './loopEventFold'; import type { ContextMessage } from './types'; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'context.spliced': { + start: number; + deleteCount: number; + messages: readonly ContextMessage[]; + tokens?: number; + }; + } +} + +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class AgentContextMemoryService extends Disposable implements IAgentContextMemoryService { declare readonly _serviceBrand: undefined; constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @ISessionTokenCountingService private readonly tokenCounting: ISessionTokenCountingService, - @IAgentStateService private readonly agentState: IAgentStateService, + @IWireService private readonly wire: IWireService, + @IEventBus private readonly eventBus: IEventBus, + @IAgentTokenCountingService private readonly tokenCounting: IAgentTokenCountingService, ) { super(); - this.agentState.contributeState(contextMemoryKey); } private get tokenEstimateFns(): TokenEstimate { @@ -52,50 +75,27 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte } get(): readonly ContextMessage[] { - return this.agentState.get(contextMemoryKey) as readonly ContextMessage[]; + return this.wire.getModel(ContextModel) as readonly ContextMessage[]; } append(...messages: readonly ContextMessage[]): void { if (messages.length === 0) return; const start = this.get().length; - for (const message of messages) { - void this.dispatcher.dispatch( - new ContextAppendMessage({ agentId: this.scopeContext.agentId, message }), - ); - } + this.wire.dispatch(...messages.map((message) => contextAppendMessage({ message }))); this.publishSplice({ start, deleteCount: 0, messages: [...messages] }); } appendLoopEvent(event: LoopRecordedEvent): void { - void this.dispatcher.dispatch( - new ContextAppendLoopEvent({ agentId: this.scopeContext.agentId, event }), - ); - } - - publishTrailingRemoval(previous: readonly ContextMessage[]): boolean { - const cutIndex = previous.length - 1; - if (cutIndex < 0) return false; - const current = this.get(); - if ( - current.length !== cutIndex || - current.some((message, index) => message !== previous[index]) - ) { - return false; - } - this.dispatchCutEvents(cutIndex); - this.publishSplice({ start: cutIndex, deleteCount: 1, messages: [] }); - return true; + this.wire.dispatch(contextAppendLoopEvent({ event })); } clear(): void { const deleteCount = this.get().length; if (deleteCount === 0) return; - void this.dispatcher.dispatch(new ContextClear({ agentId: this.scopeContext.agentId })); - this.tokenCounting.rebase(this.scopeContext.agentContext, { - length: 0, - tokens: 0, - measured: true, - }); + this.wire.dispatch( + contextClear({}), + tokenCountingRebased({ length: 0, tokens: 0, measured: true }), + ); this.publishSplice({ start: 0, deleteCount, messages: [] }); } @@ -103,10 +103,7 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte const history = this.get(); const cut = computeUndoCut(history, count); if (isFullyUndoable(cut, count)) { - void this.dispatcher.dispatch( - new ContextUndo({ agentId: this.scopeContext.agentId, count }), - ); - this.dispatchCutEvents(cut.cutIndex); + this.wire.dispatch(contextUndo({ count }), ...this.sizeOpsForCut(cut.cutIndex)); this.publishSplice({ start: cut.cutIndex, deleteCount: history.length - cut.cutIndex, @@ -119,9 +116,8 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte applyCompaction(input: ContextCompactionInput): ContextCompactionResult { const history = this.get(); const result = buildContextCompactionShape(history, input, this.tokenEstimateFns); - void this.dispatcher.dispatch( - new ContextApplyCompaction({ - agentId: this.scopeContext.agentId, + this.wire.dispatch( + contextApplyCompaction({ summary: result.summary, contextSummary: result.contextSummary, compactedCount: result.compactedCount, @@ -132,12 +128,12 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte keptHeadUserMessageCount: result.keptHeadUserMessageCount, droppedCount: result.droppedCount, }), + tokenCountingRebased({ + length: result.messages.length, + tokens: result.tokensAfter, + measured: false, + }), ); - this.tokenCounting.rebase(this.scopeContext.agentContext, { - length: result.messages.length, - tokens: result.tokensAfter, - measured: false, - }); this.publishSplice({ start: 0, deleteCount: history.length, @@ -149,14 +145,27 @@ export class AgentContextMemoryService extends Disposable implements IAgentConte return publicResult; } - private publishSplice(input: Omit<ContextSplicedPayload, 'agentId'>): void { - void this.dispatcher.dispatch( - new ContextSpliced({ agentId: this.scopeContext.agentId, ...input }), - ); + private publishSplice(input: { + start: number; + deleteCount: number; + messages: readonly ContextMessage[]; + tokens?: number; + }): void { + this.eventBus.publish({ type: 'context.spliced', ...input }); } - private dispatchCutEvents(cutIndex: number): void { - this.tokenCounting.recordTruncation(this.scopeContext.agentContext, cutIndex); + private sizeOpsForCut(cutIndex: number): Op[] { + const model = this.wire.getModel(TokenCountingModel); + if (!model.anchors.some((anchor) => anchor.length > cutIndex)) return []; + // The display tokens are the post-cut size computed from the CURRENT + // ledger — anchors at or below the cut are identical before and after + // the truncation, so the pre-dispatch read is exact. + return [ + tokenCountingTruncated({ + length: cutIndex, + tokens: this.tokenCounting.get(0, cutIndex).size, + }), + ]; } } diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts b/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts index 80186c277..7c9610cdb 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextOps.ts @@ -1,9 +1,47 @@ +/** + * `contextMemory` domain — wire Model (`ContextModel`) and the wire-protocol + * 1.4 Ops `context.append_message` (`contextAppendMessage`) / `context.clear` + * (`contextClear`) / `context.apply_compaction` (`contextApplyCompaction`) / + * `context.undo` (`contextUndo`) / `context.append_loop_event` + * (`contextAppendLoopEvent`) for the per-agent conversation history. + * + * Declares the history as `ContextMessage[]` (initial `[]`); every Op's `apply` + * is a pure array transform that returns a NEW reference on change and the SAME + * reference on a no-op (so the wire's reference-equality gate stays quiet), and + * carries no non-determinism. + * + * The live write path emits the v1 Ops: non-loop appends (user prompts, + * injections, hook/task notices) go on the wire as `append_message` (persisted + * without local ids — the on-disk record matches v1's field set), while the + * agent loop streams each turn as `context.append_loop_event` records — the + * same on-disk shape the v1 loop writes — and `contextAppendLoopEvent` folds + * them into assistant / tool messages both at live dispatch time and on + * replay, so v1- and v2-written sessions reduce + * identically. The swarm-mode exit reminder removal is a cross-model fold: + * `ContextModel` registers a reducer on `swarm_mode.exit` (see + * `popSwarmModeReminder`) so the pop replays from the `swarm_mode.exit` record + * itself. + * + * `context.undo` counts conversation ticks with the single `isUndoAnchor` + * predicate — the same definition the checkpoint + * protocol pushes with, so anchor counting and checkpoint pushing can never + * drift apart. + * + * Blob handling is declared as a `ModelBlobCodec` on `ContextModel.blobs`: + * - `dehydrate(record, transform)`: at dispatch time, traverses message content + * in `context.append_message` and `context.append_loop_event` records, + * passing each `ContentPart[]` through `transform` to offload oversized data + * URIs. + * - `rehydrate(state, transform)`: after replay, traverses the surviving final + * state and loads `blobref:` URLs back to inline data — skipping I/O for + * data that was compacted away during the session. + */ + import { z } from 'zod'; import { ErrorCodes, Error2 } from '#/errors'; import type { ContentPart } from '#/kosong/contract/message'; -import { defineState } from '#/state/state'; -import type { PartsTransformer } from '#/wire/record'; +import { defineModel, type PartsTransformer } from '#/wire/model'; import type { WireRecord } from '#/wire/record'; import { @@ -12,13 +50,10 @@ import { type ContextCompactionShapeInput, } from './compactionHandoff'; import { - ContextAppendLoopEvent, - ContextAppendMessage, - ContextApplyCompaction, - ContextClear, - type ContextApplyCompactionPayload, -} from './contextEvents'; -import { isPromptOwnedInjection, isUndoAnchor } from './conversationTime'; + isPromptOwnedInjection, + isUndoAnchor, + isValidUndoCount, +} from './conversationTime'; import { foldAppendMessage, foldLoopEvent, @@ -76,47 +111,101 @@ async function dehydrateRecord( return record; } -export const contextMemoryKey = defineState('contextMemory', (): ContextMessage[] => []) - .replayable({ - schema: z.custom<ContextMessage[]>(), - blobs: { - dehydrate: dehydrateRecord, - rehydrate: async (state, transform) => { - const { changed, result } = await dehydrateMessages(state, transform); - return changed ? result : state; - }, +export const ContextModel = defineModel<ContextMessage[]>('contextMemory', () => [], { + blobs: { + dehydrate: dehydrateRecord, + rehydrate: async (state, transform) => { + const { changed, result } = await dehydrateMessages(state, transform); + return changed ? result : state; }, - }) - .undoable({ - onUndo: (s, count) => { - if (s.length === 0) return; - const cut = computeUndoCut(s, count); - if (!isFullyUndoable(cut, count)) return; - return resetFold(s.slice(0, cut.cutIndex)) as ContextMessage[]; - }, - }) - .on(ContextAppendMessage, (s, e) => foldAppendMessage(s, e.message) as ContextMessage[]) - .on(ContextAppendLoopEvent, (s, e) => foldLoopEvent(s, e.event) as ContextMessage[]) - .on(ContextClear, (s) => (s.length === 0 ? undefined : (resetFold([]) as ContextMessage[]))) - .on(ContextApplyCompaction, (s, e) => { - const result = buildContextCompactionShape( - s, - readContextCompactionShapeInput(e as unknown as ContextApplyCompactionPayload), - ); - return resetFold([...result.messages]) as ContextMessage[]; - }); + }, + reducers: { + 'swarm_mode.exit': popSwarmModeReminder, + }, +}); -export function popSwarmModeReminder(state: ContextMessage[]): ContextMessage[] { - const last = state.at(-1); - if (last?.origin?.kind !== 'injection' || last.origin.variant !== 'swarm_mode') return state; +function popSwarmModeReminder(state: ContextMessage[], _payload: unknown): ContextMessage[] { + const last = state[state.length - 1]; + if (last === undefined) return state; + const origin = last.origin; + if (origin?.kind !== 'injection' || origin.variant !== 'swarm_mode') return state; return resetFold(state.slice(0, -1)) as ContextMessage[]; } +declare module '#/wire/types' { + interface PersistedOpMap { + 'context.append_message': typeof contextAppendMessage; + 'context.append_loop_event': typeof contextAppendLoopEvent; + 'context.clear': typeof contextClear; + 'context.apply_compaction': typeof contextApplyCompaction; + 'context.undo': typeof contextUndo; + } +} + +const contextMessageSchema = z.custom<ContextMessage>(); +const loopRecordedEventSchema = z.custom<LoopRecordedEvent>(); + +export const contextAppendMessage = ContextModel.defineOp('context.append_message', { + schema: z.object({ message: contextMessageSchema }), + apply: (state, p) => foldAppendMessage(state, p.message) as ContextMessage[], +}); + +export const contextAppendLoopEvent = ContextModel.defineOp('context.append_loop_event', { + schema: z.object({ event: loopRecordedEventSchema }), + apply: (state, p) => foldLoopEvent(state, p.event) as ContextMessage[], +}); + +export const contextClear = ContextModel.defineOp('context.clear', { + schema: z.object({}), + apply: (state) => (state.length === 0 ? state : (resetFold([]) as ContextMessage[])), +}); + +const contextCompactionBaseShape = { + tokensBefore: z.number().optional(), + tokensAfter: z.number().optional(), + summaryOutputTokens: z.number().optional(), + keptUserMessageCount: z.number().optional(), + keptHeadUserMessageCount: z.number().optional(), + droppedCount: z.number().optional(), + legacyTail: z.boolean().optional(), +}; + +const contextApplyCompactionSchema = z.union([ + z.object({ + ...contextCompactionBaseShape, + summary: z.string(), + compactedCount: z.number(), + contextSummary: z.string().optional(), + }), + z.object({ + ...contextCompactionBaseShape, + contextSummary: z.string(), + compactedCount: z.number(), + summary: z.string().optional(), + }), + z.object({ + ...contextCompactionBaseShape, + summary: contextMessageSchema, + count: z.number(), + compactedCount: z.number().optional(), + }), +]); + +type ContextCompactionPayload = z.infer<typeof contextApplyCompactionSchema>; + +export const contextApplyCompaction = ContextModel.defineOp('context.apply_compaction', { + schema: contextApplyCompactionSchema, + apply: (state, p) => { + const result = buildContextCompactionShape(state, readContextCompactionShapeInput(p)); + return resetFold([...result.messages]) as ContextMessage[]; + }, +}); + interface UnknownRecord { readonly [key: string]: unknown; } -type ContextCompactionRecord = ContextApplyCompactionPayload | UnknownRecord; +type ContextCompactionRecord = ContextCompactionPayload | UnknownRecord; export function applyContextCompactionRecord( state: readonly ContextMessage[], @@ -317,3 +406,15 @@ export function formatUndoUnavailableMessage( return 'Nothing to undo: conversation state checkpoints are incomplete'; } } + +export const contextUndo = ContextModel.defineOp('context.undo', { + schema: z.object({ + count: z.number().int().positive().max(Number.MAX_SAFE_INTEGER), + }), + apply: (state, p) => { + if (!isValidUndoCount(p.count) || state.length === 0) return state; + const cut = computeUndoCut(state, p.count); + if (!isFullyUndoable(cut, p.count)) return state; + return resetFold(state.slice(0, cut.cutIndex)) as ContextMessage[]; + }, +}); diff --git a/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts b/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts index 75df69068..773378317 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/contextTranscript.ts @@ -1,3 +1,10 @@ +/** + * `contextMemory` domain — rebuilds display history from the wire journal. + * + * Supplies transcript consumers with full pre-compaction history and folded + * context length while preserving undo/clear semantics. Scope-agnostic. + */ + import { type ContentPart, type ToolCall } from '#/kosong/contract/message'; import type { WireRecord } from '#/wire/record'; @@ -7,8 +14,12 @@ import { selectRecentUserMessages, } from './compactionHandoff'; import { isPromptOwnedInjection, isUndoAnchor } from './conversationTime'; -import { createLoopEventFold, type LoopRecordedEvent } from './loopEventFold'; +import type { LoopRecordedEvent } from './loopEventFold'; import type { ContextMessage } from './types'; +import { isVacuousContentPart } from './vacuousContent'; + +const TOOL_INTERRUPTED_ON_RESUME_OUTPUT = + 'Tool execution was interrupted before its result was recorded. Do not assume the tool completed successfully.'; export interface ContextTranscript { readonly entries: readonly ContextMessage[]; @@ -28,7 +39,6 @@ interface MutableMessage { toolCalls: ToolCall[]; toolCallId?: string; isError?: boolean; - note?: string; origin?: ContextMessage['origin']; } @@ -47,46 +57,111 @@ export function createContextTranscriptReducer(): ContextTranscriptReducer { const transcript: MutableEntry[] = []; let foldedLength = 0; let clearFloor = 0; - let openEntry: MutableEntry | undefined; + const openSteps = new Map<string, MutableEntry>(); + const pendingToolResultIds = new Set<string>(); + let deferred: MutableEntry[] = []; + let lastOpenStepUuid: string | undefined; const push = (...entries: MutableEntry[]): void => { transcript.push(...entries); foldedLength += entries.length; }; - - const fold = createLoopEventFold({ - openAssistant: (time) => { - openEntry = { message: { role: 'assistant', content: [], toolCalls: [] }, time }; - push(openEntry); - }, - appendOpenContent: (part) => { - openEntry?.message.content.push(part); - }, - appendOpenToolCall: (call) => { - openEntry?.message.toolCalls.push(call); - }, - dropOpenAssistant: () => { - if (openEntry === undefined) return; - const index = transcript.indexOf(openEntry); - openEntry = undefined; - if (index === -1) return; - transcript.splice(index, 1); - foldedLength = Math.max(0, foldedLength - 1); - }, - sealOpenAssistant: () => { - openEntry = undefined; - }, - pushToolMessage: (message, time) => { - push({ message: message as MutableMessage, time }); - }, - pushMessage: (message, time) => { - push(toMutableEntry(message, time)); - }, - }); - + const flushDeferredIfToolExchangeClosed = (): void => { + if (pendingToolResultIds.size > 0 || deferred.length === 0) return; + push(...deferred); + deferred = []; + }; + const closePendingToolResults = (time: number | undefined): void => { + if (pendingToolResultIds.size === 0) return; + const interruptedToolCallIds = [...pendingToolResultIds]; + for (const toolCallId of interruptedToolCallIds) { + push({ + message: { + role: 'tool', + content: [{ type: 'text', text: TOOL_INTERRUPTED_ON_RESUME_OUTPUT }], + toolCalls: [], + toolCallId, + isError: true, + }, + time, + }); + pendingToolResultIds.delete(toolCallId); + } + flushDeferredIfToolExchangeClosed(); + }; const resetOpenState = (): void => { - fold.reset(); - openEntry = undefined; + openSteps.clear(); + pendingToolResultIds.clear(); + deferred = []; + lastOpenStepUuid = undefined; + }; + const settleStep = (uuid: string): void => { + const entry = openSteps.get(uuid); + if (entry === undefined) return; + openSteps.delete(uuid); + if (entry.message.toolCalls.length > 0) return; + if (!entry.message.content.every(isVacuousContentPart)) return; + const index = transcript.indexOf(entry); + if (index === -1) return; + transcript.splice(index, 1); + foldedLength = Math.max(0, foldedLength - 1); + }; + + const applyLoopEvent = (event: LoopRecordedEvent, time: number | undefined): void => { + switch (event.type) { + case 'step.begin': { + closePendingToolResults(time); + if (lastOpenStepUuid !== undefined) settleStep(lastOpenStepUuid); + const entry: MutableEntry = { + message: { role: 'assistant', content: [], toolCalls: [] }, + time, + }; + push(entry); + openSteps.set(event.uuid, entry); + lastOpenStepUuid = event.uuid; + return; + } + case 'step.end': { + settleStep(event.uuid); + if (lastOpenStepUuid === event.uuid) lastOpenStepUuid = undefined; + flushDeferredIfToolExchangeClosed(); + return; + } + case 'content.part': { + openSteps.get(event.stepUuid)?.message.content.push(event.part); + return; + } + case 'tool.call': { + const openStep = openSteps.get(event.stepUuid); + if (openStep === undefined) return; + const call: ToolCall = { + type: 'function', + id: event.toolCallId, + name: event.name, + arguments: event.args === undefined ? null : JSON.stringify(event.args), + ...(event.extras !== undefined ? { extras: event.extras } : {}), + }; + openStep.message.toolCalls.push(call); + pendingToolResultIds.add(event.toolCallId); + return; + } + case 'tool.result': { + if (!pendingToolResultIds.has(event.toolCallId)) return; + push({ + message: { + role: 'tool', + content: rawToolResultContent(event.result.output), + toolCalls: [], + toolCallId: event.toolCallId, + isError: event.result.isError, + }, + time, + }); + pendingToolResultIds.delete(event.toolCallId); + flushDeferredIfToolExchangeClosed(); + return; + } + } }; const applyUndo = (count: number): void => { @@ -100,15 +175,17 @@ export function createContextTranscriptReducer(): ContextTranscriptReducer { foldedLength = Math.max(0, foldedLength - 1); if (isUndoAnchor(message)) { removedUserCount++; - while ( - i > clearFloor && - isPromptOwnedInjection(transcript[i - 1]!.message, message) - ) { - transcript.splice(i - 1, 1); - i--; - foldedLength = Math.max(0, foldedLength - 1); + if (removedUserCount >= count) { + while ( + i > clearFloor && + isPromptOwnedInjection(transcript[i - 1]!.message, message) + ) { + transcript.splice(i - 1, 1); + i--; + foldedLength = Math.max(0, foldedLength - 1); + } + break; } - if (removedUserCount >= count) break; } } resetOpenState(); @@ -117,19 +194,15 @@ export function createContextTranscriptReducer(): ContextTranscriptReducer { const add = (record: WireRecord): void => { switch (record.type) { case 'context.append_message': { - fold.appendMessage(record['message'] as ContextMessage, record.time); + const entry = toMutableEntry(record['message'] as ContextMessage, record.time); + if (pendingToolResultIds.size > 0) deferred.push(entry); + else push(entry); break; } - case 'context.append_loop_event': { - fold.loopEvent(record['event'] as LoopRecordedEvent, record.time); + case 'context.append_loop_event': + applyLoopEvent(record['event'] as LoopRecordedEvent, record.time); break; - } case 'context.apply_compaction': { - if (readNumber(record, 'keptUserMessageCount') !== undefined) { - fold.settle(record.time); - } else { - resetOpenState(); - } transcript.push({ message: { role: 'user', @@ -140,6 +213,7 @@ export function createContextTranscriptReducer(): ContextTranscriptReducer { time: record.time, }); foldedLength = recoverFoldedLength(record, transcript, clearFloor, foldedLength); + resetOpenState(); break; } case 'context.undo': @@ -229,3 +303,7 @@ function readNumber(record: WireRecord, key: string): number | undefined { const value = record[key]; return typeof value === 'number' ? value : undefined; } + +function rawToolResultContent(output: string | readonly ContentPart[]): ContentPart[] { + return typeof output === 'string' ? [{ type: 'text', text: output }] : [...output]; +} diff --git a/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts b/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts index ca1edd089..5cc735999 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/conversationTime.ts @@ -1,11 +1,16 @@ -import { registerUndoableProtocol } from '#/state/state'; +/** + * `contextMemory` domain — shared conversation clock and checkpointed + * wire-Model factory. + * + * Defines the undo anchor vocabulary and registers conversation-time Models + * for undo validation. `CHECKPOINTED_MODELS` stays the undo domain's read + * path; the `WireModelContribution` fold also drains it into the built-in + * layer so the checkpointed list is part of the folded wire vocabulary. + * Scope-agnostic. + */ + +import { defineModel, type ModelDef } from '#/wire/model'; -import { - ContextAppendMessage, - ContextApplyCompaction, - ContextClear, - ContextUndo, -} from './contextEvents'; import type { ContextMessage } from './types'; export function isUndoAnchor(message: ContextMessage): boolean { @@ -34,13 +39,50 @@ export function isValidUndoCount(count: number): boolean { return Number.isSafeInteger(count) && count > 0; } -registerUndoableProtocol({ - events: { - appendMessage: ContextAppendMessage, - applyCompaction: ContextApplyCompaction, - clear: ContextClear, - undo: ContextUndo, - }, - isUndoAnchor: (message) => isUndoAnchor(message as ContextMessage), - isValidUndoCount, -}); +export interface Checkpointed<T> { + readonly current: T; + readonly checkpoints: readonly T[]; +} + +export const CHECKPOINTED_MODELS: ModelDef<Checkpointed<unknown>>[] = []; + +export interface CheckpointModelOptions<T> { + readonly onAppendMessage?: (current: T, message: ContextMessage) => T; +} + +export function defineCheckpointedModel<T>( + name: string, + initial: () => T, + opts?: CheckpointModelOptions<T>, +): ModelDef<Checkpointed<T>> { + const def = defineModel<Checkpointed<T>>( + name, + () => ({ current: initial(), checkpoints: [] }), + { + reducers: { + 'context.append_message': (state, { message }) => { + if (isUndoAnchor(message)) { + return { ...state, checkpoints: [...state.checkpoints, state.current] }; + } + if (opts?.onAppendMessage === undefined) return state; + const current = opts.onAppendMessage(state.current, message); + return current === state.current ? state : { ...state, current }; + }, + 'context.apply_compaction': (state) => + state.checkpoints.length === 0 ? state : { ...state, checkpoints: [] }, + 'context.clear': (state) => + state.checkpoints.length === 0 ? state : { ...state, checkpoints: [] }, + 'context.undo': (state, { count }) => { + if (!isValidUndoCount(count) || state.checkpoints.length < count) return state; + const checkpointIndex = state.checkpoints.length - count; + return { + current: state.checkpoints[checkpointIndex]!, + checkpoints: state.checkpoints.slice(0, checkpointIndex), + }; + }, + }, + }, + ); + CHECKPOINTED_MODELS.push(def as ModelDef<Checkpointed<unknown>>); + return def; +} diff --git a/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts b/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts index 22a07edbf..6d152f138 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/conversationUndoParticipants.ts @@ -1,3 +1,10 @@ +/** + * `contextMemory` domain — Agent-scoped post-undo reconciliation registry. + * + * Hosts state-repair participants for the undo coordinator. Bound at Agent + * scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts b/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts index cf68b8c9f..325b94ba9 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/loopEventFold.ts @@ -1,4 +1,42 @@ -import { isDraft, original } from 'immer'; +/** + * `contextMemory` loop-event fold — reduction of `context.append_loop_event` + * records into folded `ContextMessage`s. + * + * The agent loop streams a turn as `context.append_loop_event` records + * (`step.begin` / `content.part` / `tool.call` / `tool.result` / `step.end`) + * and never writes a folded assistant message, keeping the on-disk shape + * byte-compatible with v1. This fold turns them into assistant / tool + * messages — at live dispatch time and again when `WireService.restore` + * restores an Agent. Without it, restore would skip those records (no Op is + * registered for the type) and the restored `ContextModel` — and every + * consumer built on it — would show only the user prompts. + * + * Semantics mirror the v1 fold exactly: + * - `step.begin` → open an assistant message (`partial: true`); first settle + * the step left open by a failed attempt + * - `content.part`→ append to the open assistant's content + * - `tool.call` → append to the open assistant's `toolCalls`, mark pending + * - `tool.result` → push a `tool` message (with the v1 output + * wrapping), clear its pending id + * - `step.end` → settle the assistant + * "Settle" closes any tool exchange left open (interrupted result messages), + * then drops the partial assistant when nothing sendable was recorded (no + * tool calls; every content part vacuous — an output-free assistant only + * trips provider message validation) and seals it (`partial: undefined`) + * when it carries output. v1 never produced + * `step.begin` without `step.end` (its retries stayed inside one request), so + * the drop/seal rule is the v2 extension that makes loop-level retries — a + * retried attempt is its own `step.begin` — replay to the same history the + * live loop folded. + * A `context.append_message` reduced while a tool exchange is still open is + * deferred and flushed once the exchange closes, so strict-provider + * assistant↔tool adjacency is preserved. + * + * The fold is stateful across records within one replay. State is carried in a + * `WeakMap` keyed by each evolving state array, so the public + * `wire.getModel(ContextModel)` view stays a plain `ContextMessage[]` and + * concurrent replays of different agent scopes never share fold state. + */ import type { FinishReason } from '#/kosong/contract/provider'; import { createToolMessage, type ContentPart, type ToolCall } from '#/kosong/contract/message'; @@ -64,246 +102,122 @@ export type LoopRecordedEvent = readonly parentUuid?: string; }; -export interface LoopEventFoldSink { - openAssistant(time: number | undefined): void; - appendOpenContent(part: ContentPart): void; - appendOpenToolCall(call: ToolCall): void; - dropOpenAssistant(): void; - sealOpenAssistant(): void; - pushToolMessage(message: ContextMessage, time: number | undefined): void; - pushMessage(message: ContextMessage, time: number | undefined): void; +interface FoldCtx { + openStepUuid: string | undefined; + pending: Set<string>; + deferred: ContextMessage[]; } -export interface LoopEventFold { - appendMessage(message: ContextMessage, time?: number): void; - loopEvent(event: LoopRecordedEvent, time?: number): void; - settle(time?: number): void; - reset(): void; +const foldCtxMap = new WeakMap<object, FoldCtx>(); + +function ctxOf(state: readonly ContextMessage[]): FoldCtx { + let ctx = foldCtxMap.get(state); + if (ctx === undefined) { + ctx = { openStepUuid: undefined, pending: new Set(), deferred: [] }; + foldCtxMap.set(state, ctx); + } + return ctx; } -export function createLoopEventFold(sink: LoopEventFoldSink): LoopEventFold { - return createLoopEventFoldWithState(sink); +function bind(state: readonly ContextMessage[], ctx: FoldCtx): readonly ContextMessage[] { + foldCtxMap.set(state, ctx); + return state; } -interface InitialFoldState { - readonly openHasToolCalls: boolean; - readonly openVacuous: boolean; - readonly pendingToolCallIds: readonly string[]; -} - -function createLoopEventFoldWithState( - sink: LoopEventFoldSink, - initial?: InitialFoldState, -): LoopEventFold { - let openStepUuid: string | null | undefined = initial === undefined ? undefined : null; - let openHasToolCalls = initial?.openHasToolCalls ?? false; - let openVacuous = initial?.openVacuous ?? true; - const pending = new Set(initial?.pendingToolCallIds); - let deferred: { message: ContextMessage; time: number | undefined }[] = []; - - const flushDeferred = (): void => { - if (pending.size > 0 || deferred.length === 0) return; - for (const entry of deferred) sink.pushMessage(entry.message, entry.time); - deferred = []; - }; - const closePending = (time: number | undefined): void => { - if (pending.size === 0) return; - for (const toolCallId of pending) { - sink.pushToolMessage(interruptedToolMessage(toolCallId), time); - } - pending.clear(); - flushDeferred(); - }; - const settleOpen = (time: number | undefined): void => { - if (openStepUuid === undefined) return; - closePending(time); - if (!openHasToolCalls && openVacuous) { - sink.dropOpenAssistant(); - } else { - sink.sealOpenAssistant(); - } - openStepUuid = undefined; - }; - const acceptsOpenStep = (stepUuid: string): boolean => { - if (openStepUuid === undefined) return false; - if (openStepUuid === null) { - openStepUuid = stepUuid; - return true; - } - return stepUuid === openStepUuid; - }; - - return { - appendMessage(message, time) { - if (pending.size > 0) { - deferred.push({ message, time }); - return; - } - sink.pushMessage(message, time); - }, - loopEvent(event, time) { - switch (event.type) { - case 'step.begin': { - settleOpen(time); - sink.openAssistant(time); - openStepUuid = event.uuid; - openHasToolCalls = false; - openVacuous = true; - return; - } - case 'step.end': { - if (event.finishReason === 'interrupted' || event.finishReason === 'error') return; - settleOpen(time); - flushDeferred(); - return; - } - case 'content.part': { - if (!acceptsOpenStep(event.stepUuid)) return; - sink.appendOpenContent(event.part); - openVacuous = openVacuous && isVacuousContentPart(event.part); - return; - } - case 'tool.call': { - if (!acceptsOpenStep(event.stepUuid)) return; - const call: ToolCall = { - type: 'function', - id: event.toolCallId, - name: event.name, - arguments: event.args === undefined ? null : JSON.stringify(event.args), - ...(event.extras !== undefined ? { extras: event.extras } : {}), - }; - sink.appendOpenToolCall(call); - pending.add(event.toolCallId); - openHasToolCalls = true; - return; - } - case 'tool.result': { - if (!pending.has(event.toolCallId)) return; - pending.delete(event.toolCallId); - const output = event.result.output; - sink.pushToolMessage( - { - ...createToolMessage( - event.toolCallId, - typeof output === 'string' ? output : [...output], - ), - isError: event.result.isError, - note: event.result.note, - }, - time, - ); - flushDeferred(); - return; - } - } - }, - settle(time) { - settleOpen(time); - flushDeferred(); - }, - reset() { - openStepUuid = undefined; - openHasToolCalls = false; - openVacuous = true; - pending.clear(); - deferred = []; - }, - }; -} - -interface ImmutableFoldSink extends LoopEventFoldSink { - current(): readonly ContextMessage[]; -} - -interface BoundFold { - readonly fold: LoopEventFold; - readonly sink: ImmutableFoldSink; -} - -const boundFoldMap = new WeakMap<object, BoundFold>(); - export function foldAppendMessage( state: readonly ContextMessage[], message: ContextMessage, ): readonly ContextMessage[] { - const bound = boundOf(state); - bound.fold.appendMessage(message, undefined); - return bind(bound, bound.sink.current()); + const ctx = ctxOf(state); + if (ctx.pending.size > 0) { + ctx.deferred.push(message); + return state; + } + return bind([...state, message], ctx); } export function foldLoopEvent( state: readonly ContextMessage[], event: LoopRecordedEvent, ): readonly ContextMessage[] { - const bound = boundOf(state); - bound.fold.loopEvent(event, undefined); - return bind(bound, bound.sink.current()); + const ctx = ctxOf(state); + switch (event.type) { + case 'step.begin': { + const settled = settleOpenStep(state, ctx); + const assistant: ContextMessage = { role: 'assistant', content: [], toolCalls: [], partial: true }; + ctx.openStepUuid = event.uuid; + return bind([...settled, assistant], ctx); + } + case 'step.end': { + ctx.openStepUuid = undefined; + const s = settleOpenStep(state, ctx); + return bind(flushDeferred(s, ctx), ctx); + } + case 'content.part': + return bind(appendToOpenAssistant(state, (message) => ({ + ...message, + content: [...message.content, event.part], + })), ctx); + case 'tool.call': { + const call: ToolCall = { + type: 'function', + id: event.toolCallId, + name: event.name, + arguments: event.args === undefined ? null : JSON.stringify(event.args), + ...(event.extras !== undefined ? { extras: event.extras } : {}), + }; + ctx.pending.add(event.toolCallId); + return bind(appendToOpenAssistant(state, (message) => ({ + ...message, + toolCalls: [...message.toolCalls, call], + })), ctx); + } + case 'tool.result': { + if (!ctx.pending.has(event.toolCallId)) return state; + const output = event.result.output; + const toolMessage: ContextMessage = { + ...createToolMessage(event.toolCallId, typeof output === 'string' ? output : [...output]), + isError: event.result.isError, + note: event.result.note, + }; + ctx.pending.delete(event.toolCallId); + return bind(flushDeferred([...state, toolMessage], ctx), ctx); + } + default: + return state; + } } export function resetFold(state: readonly ContextMessage[]): readonly ContextMessage[] { - const sink = createImmutableFoldSink(state); - boundFoldMap.set(state, { fold: createLoopEventFold(sink), sink }); + foldCtxMap.set(state, { openStepUuid: undefined, pending: new Set(), deferred: [] }); return state; } -function boundOf(state: readonly ContextMessage[]): BoundFold { - const key = keyOf(state); - let bound = boundFoldMap.get(key); - if (bound === undefined || bound.sink.current() !== key) { - const sink = createImmutableFoldSink(key); - bound = { fold: createLoopEventFoldWithState(sink, recoverFoldState(key)), sink }; - boundFoldMap.set(key, bound); +function appendToOpenAssistant( + state: readonly ContextMessage[], + update: (message: ContextMessage) => ContextMessage, +): readonly ContextMessage[] { + const index = findOpenAssistantIndex(state); + if (index === -1) return state; + const next = state.slice(); + next[index] = update(next[index]!); + return next; +} + +function settleOpenStep( + state: readonly ContextMessage[], + ctx: FoldCtx, +): readonly ContextMessage[] { + const closed = closePending(state, ctx); + const index = findOpenAssistantIndex(closed); + if (index === -1) return closed; + const open = closed[index]!; + if (open.toolCalls.length === 0 && open.content.every(isVacuousContentPart)) { + return [...closed.slice(0, index), ...closed.slice(index + 1)]; } - return bound; -} - -function bind(bound: BoundFold, state: readonly ContextMessage[]): readonly ContextMessage[] { - boundFoldMap.set(state, bound); - return state; -} - -function keyOf(state: readonly ContextMessage[]): readonly ContextMessage[] { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - return (isDraft(state) ? original(state as any) : state) as readonly ContextMessage[]; -} - -function createImmutableFoldSink(initial: readonly ContextMessage[]): ImmutableFoldSink { - let current = initial; - let openIndex = findOpenAssistantIndex(initial); - const updateOpen = (update: (message: ContextMessage) => ContextMessage): void => { - if (openIndex === -1) return; - const next = current.slice(); - next[openIndex] = update(next[openIndex]!); - current = next; - }; - return { - current: () => current, - openAssistant: () => { - current = [...current, { role: 'assistant', content: [], toolCalls: [], partial: true }]; - openIndex = current.length - 1; - }, - appendOpenContent: (part) => { - updateOpen((message) => ({ ...message, content: [...message.content, part] })); - }, - appendOpenToolCall: (call) => { - updateOpen((message) => ({ ...message, toolCalls: [...message.toolCalls, call] })); - }, - dropOpenAssistant: () => { - if (openIndex === -1) return; - current = [...current.slice(0, openIndex), ...current.slice(openIndex + 1)]; - openIndex = -1; - }, - sealOpenAssistant: () => { - updateOpen((message) => ({ ...message, partial: undefined })); - openIndex = -1; - }, - pushToolMessage: (message) => { - current = [...current, message]; - }, - pushMessage: (message) => { - current = [...current, message]; - }, - }; + const next = closed.slice(); + next[index] = { ...open, partial: undefined }; + return next; } function findOpenAssistantIndex(state: readonly ContextMessage[]): number { @@ -313,24 +227,21 @@ function findOpenAssistantIndex(state: readonly ContextMessage[]): number { return -1; } -function recoverFoldState(state: readonly ContextMessage[]): InitialFoldState | undefined { - const openIndex = findOpenAssistantIndex(state); - if (openIndex === -1) return undefined; - const open = state[openIndex]!; - const resolvedToolCallIds = new Set<string>(); - for (let i = openIndex + 1; i < state.length; i++) { - const message = state[i]!; - if (message.role === 'tool' && message.toolCallId !== undefined) { - resolvedToolCallIds.add(message.toolCallId); - } +function closePending(state: readonly ContextMessage[], ctx: FoldCtx): readonly ContextMessage[] { + if (ctx.pending.size === 0) return state; + const next = state.slice(); + for (const toolCallId of ctx.pending) { + next.push(interruptedToolMessage(toolCallId)); } - return { - openHasToolCalls: open.toolCalls.length > 0, - openVacuous: open.content.every(isVacuousContentPart), - pendingToolCallIds: open.toolCalls - .map((call) => call.id) - .filter((toolCallId) => !resolvedToolCallIds.has(toolCallId)), - }; + ctx.pending.clear(); + return flushDeferred(next, ctx); +} + +function flushDeferred(state: readonly ContextMessage[], ctx: FoldCtx): readonly ContextMessage[] { + if (ctx.pending.size > 0 || ctx.deferred.length === 0) return state; + const next = [...state, ...ctx.deferred]; + ctx.deferred.length = 0; + return next; } function interruptedToolMessage(toolCallId: string): ContextMessage { diff --git a/packages/agent-core-v2/src/agent/contextMemory/messageId.ts b/packages/agent-core-v2/src/agent/contextMemory/messageId.ts index 6518caed9..b764549d6 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/messageId.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/messageId.ts @@ -1,3 +1,16 @@ +/** + * `contextMemory` message id helpers. + * + * Local message ids (`msg_<ulid>`) are process-lifetime identifiers only — + * they are NOT persisted: the on-disk `context.append_message` record carries + * exactly v1's field set, and public message ids are derived from the + * transcript index (by the server layer's `ContextMessage → wire Message` + * projection), which stays stable across live reads and resume. + * `newMessageId` remains for callers that need an opaque per-process id. + * Provider-assigned ids live on the separate `providerMessageId` field and + * never collide with this namespace. + */ + import { ulid } from 'ulid'; export function newMessageId(): string { diff --git a/packages/agent-core-v2/src/agent/contextMemory/openToolExchange.ts b/packages/agent-core-v2/src/agent/contextMemory/openToolExchange.ts deleted file mode 100644 index 425d4c4fa..000000000 --- a/packages/agent-core-v2/src/agent/contextMemory/openToolExchange.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { createToolMessage } from '#/kosong/contract/message'; - -import type { ContextMessage } from './types'; - -export const INHERITED_IN_FLIGHT_TOOL_OUTPUT = - 'This tool call was still executing when this conversation snapshot was inherited from the source agent, so its result is not part of this context. The outcome is unknown — do not assume it succeeded or failed, and do not wait for it.'; - -export function closeTrailingOpenToolExchange( - history: readonly ContextMessage[], -): ContextMessage[] { - let lastNonToolIndex = history.length - 1; - while (lastNonToolIndex >= 0 && history[lastNonToolIndex]?.role === 'tool') { - lastNonToolIndex -= 1; - } - - const assistant = history[lastNonToolIndex]; - if (assistant === undefined) return []; - if (assistant.role !== 'assistant' || assistant.toolCalls.length === 0) return [...history]; - - const answeredToolCallIds = new Set( - history - .slice(lastNonToolIndex + 1) - .map((message) => message.toolCallId) - .filter((toolCallId): toolCallId is string => typeof toolCallId === 'string'), - ); - const openCalls = assistant.toolCalls.filter( - (toolCall) => !answeredToolCallIds.has(toolCall.id), - ); - if (openCalls.length === 0) return [...history]; - const settledAssistant = - assistant.partial === true ? { ...assistant, partial: undefined } : assistant; - return [ - ...history.slice(0, lastNonToolIndex), - settledAssistant, - ...history.slice(lastNonToolIndex + 1), - ...openCalls.map((toolCall) => - createToolMessage(toolCall.id, INHERITED_IN_FLIGHT_TOOL_OUTPUT), - ), - ]; -} diff --git a/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts b/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts index 26e4969f1..683cd465f 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/toolResultRender.ts @@ -1,3 +1,12 @@ +/** + * `contextMemory` domain helper — projects stored tool result facts into + * model-visible content. + * + * Tool messages keep the raw tool output plus structured status fields in + * context. The LLM projection is the only boundary that turns those facts into + * system status text or appends model-only notes. + */ + import type { ContentPart } from '#/kosong/contract/message'; const TOOL_ERROR_STATUS = '<system>ERROR: Tool execution failed.</system>'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/types.ts b/packages/agent-core-v2/src/agent/contextMemory/types.ts index 6907ddc18..5b8c59cdb 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/types.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/types.ts @@ -6,20 +6,10 @@ export type SkillSource = 'project' | 'user' | 'extra' | 'builtin'; export interface UserPromptOrigin { readonly kind: 'user'; - readonly skillActivations?: readonly BundledSkillActivation[]; } export const USER_PROMPT_ORIGIN: UserPromptOrigin = { kind: 'user' }; -export interface BundledSkillActivation { - readonly activationId: string; - readonly skillName: string; - readonly skillArgs?: string; - readonly skillType?: string; - readonly skillPath?: string; - readonly skillSource?: SkillSource; -} - export interface SkillActivationOrigin { readonly kind: 'skill_activation'; readonly activationId: string; @@ -44,9 +34,16 @@ export interface InjectionOrigin { readonly kind: 'injection'; readonly variant: string; readonly ownerPromptId?: string; - readonly disclosure?: unknown; + readonly disclosure?: ContextInjectionDisclosure; } +export type ContextInjectionDisclosure = { + readonly kind: 'date'; + readonly renderGeneration: number; + readonly localDate: string; + readonly timeZone: string; +}; + export interface ShellCommandOrigin { readonly kind: 'shell_command'; readonly phase: 'input' | 'output'; diff --git a/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts b/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts index e0e1f9e46..293d26559 100644 --- a/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts +++ b/packages/agent-core-v2/src/agent/contextMemory/vacuousContent.ts @@ -1,19 +1,16 @@ +/** + * `contextMemory` vacuous-content predicate — shared test for content parts + * that carry nothing the provider wire can represent. Vacuous means an empty + * or whitespace-only text block, or an empty thinking block with no provider + * signature; a signed thinking block (`encrypted`) is never vacuous — + * reasoning providers require it back verbatim — and media parts always + * carry content. + */ + import type { ContentPart } from '#/kosong/contract/message'; export function isVacuousContentPart(part: ContentPart): boolean { - switch (part.type) { - case 'text': - return part.text.trim().length === 0; - case 'think': - return part.encrypted === undefined && part.think.trim().length === 0; - case 'image_url': - case 'audio_url': - case 'video_url': - return false; - default: { - const exhaustive: never = part; - void exhaustive; - return false; - } - } + if (part.type === 'text') return part.text.trim().length === 0; + if (part.type === 'think') return part.encrypted === undefined && part.think.trim().length === 0; + return false; } diff --git a/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts b/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts index 46e1bbacd..48987f673 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/contextProjector.ts @@ -1,3 +1,11 @@ +/** + * `contextProjector` domain — Agent-scope context projection contract. + * + * Defines wire-safe history projections and an opaque snapshot of the media + * identities that a provider rejected, allowing later steps to strip only + * that content while preserving newly generated recovery media. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { Message } from '#/kosong/contract/message'; @@ -9,19 +17,17 @@ export interface MediaStripSnapshot { readonly [mediaStripSnapshotBrand]: undefined; } -export interface ProjectionPolicy { - readonly structure?: 'strict'; - readonly media?: 'degraded' | { readonly strip: MediaStripSnapshot }; -} - export interface IAgentContextProjectorService { readonly _serviceBrand: undefined; - project( - messages: readonly ContextMessage[], - policy?: ProjectionPolicy, - ): readonly Message[]; + project(messages: readonly ContextMessage[]): readonly Message[]; + projectStrict(messages: readonly ContextMessage[]): readonly Message[]; + projectMediaDegraded(messages: readonly ContextMessage[]): readonly Message[]; captureMediaStripSnapshot(messages: readonly ContextMessage[]): MediaStripSnapshot; + projectMediaStripped( + messages: readonly ContextMessage[], + snapshot?: MediaStripSnapshot, + ): readonly Message[]; } export const IAgentContextProjectorService = createDecorator<IAgentContextProjectorService>( diff --git a/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts b/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts index 82bab0a2e..ca92b6205 100644 --- a/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts +++ b/packages/agent-core-v2/src/agent/contextProjector/contextProjectorService.ts @@ -1,29 +1,46 @@ +/** + * `contextProjector` domain — projects stored context history into the wire + * messages sent to the model, and surfaces every repair it had to apply. + * + * `AgentContextProjectorService` is the Agent-scope binding. The projection + * itself stays a pure transform over the history; repairs that keep the + * outgoing wire valid (a displaced result moved back to its call, a synthetic + * result invented for a lost one, an orphan/duplicate dropped, leading + * non-user messages dropped, consecutive assistants merged, blank text + * dropped, wholly-vacuous messages — nothing sendable was recorded, e.g. an + * assistant step that kept only an empty thinking part — dropped whole) are + * reported through an optional sink and surfaced once here as a + * single deduped warning plus a `context_projection_repaired` telemetry event, + * so a silently-mangled history always leaves a trace. The mutable + * repair-dedup signature (`lastRepairSignature`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it. + * + * `projectMediaDegraded` / `projectMediaStripped` are the fallback + * projections for the two deterministic provider rejections: media-degraded + * (all but the most recent media replaced by text markers) resends after an + * HTTP 413 body-size rejection; media-stripped captures every media identity + * present when degraded media is still too large or an image format is + * rejected, then replaces only that snapshot on later steps so a newly + * generated recovery image remains visible. Both are read-side only — the + * history keeps its media. + */ + +import { createHash } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; +import { renderToolResultForModel } from '#/agent/contextMemory/toolResultRender'; import type { ContextMessage } from '#/agent/contextMemory/types'; +import { isVacuousContentPart } from '#/agent/contextMemory/vacuousContent'; import { IAgentStateService } from '#/agent/state/agentState'; -import type { Message } from '#/kosong/contract/message'; +import { ErrorCodes, Error2 } from '#/errors'; +import type { ContentPart, Message } from '#/kosong/contract/message'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { IAgentContextProjectorService, type MediaStripSnapshot, - type ProjectionPolicy, } from './contextProjector'; -import { - MEDIA_DEGRADE_KEEP_RECENT, - captureMediaStripSnapshot, - degradeOlderMediaParts, - stripMediaPartsBySnapshot, -} from './mediaProjection'; -import { - project, - projectStrict, - summarizeProjectionRepairs, - type OnAnomaly, - type ProjectionAnomaly, -} from './projection'; export const contextProjectorLastRepairSignatureKey = defineState<string | null>( 'contextProjector.lastRepairSignature', @@ -38,7 +55,7 @@ export class AgentContextProjectorService implements IAgentContextProjectorServi @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentStateService private readonly states: IAgentStateService, ) { - this.states.contributeState(contextProjectorLastRepairSignatureKey); + this.states.register(contextProjectorLastRepairSignatureKey); } private get lastRepairSignature(): string | null { @@ -49,27 +66,39 @@ export class AgentContextProjectorService implements IAgentContextProjectorServi this.states.set(contextProjectorLastRepairSignatureKey, value); } - project( - messages: readonly ContextMessage[], - policy: ProjectionPolicy = {}, - ): readonly Message[] { - const projected = this.projectWithTrace( - messages, - policy.structure === 'strict' ? projectStrict : project, + project(messages: readonly ContextMessage[]): readonly Message[] { + return this.projectWithTrace(messages, project); + } + + projectStrict(messages: readonly ContextMessage[]): readonly Message[] { + return this.projectWithTrace(messages, projectStrict); + } + + projectMediaDegraded(messages: readonly ContextMessage[]): readonly Message[] { + return degradeOlderMediaParts( + this.projectWithTrace(messages, project), + MEDIA_DEGRADE_KEEP_RECENT, ); - const media = policy.media; - if (media === undefined) return projected; - if (media === 'degraded') return degradeOlderMediaParts(projected, MEDIA_DEGRADE_KEEP_RECENT); - return stripMediaPartsBySnapshot(projected, media.strip); } captureMediaStripSnapshot(messages: readonly ContextMessage[]): MediaStripSnapshot { return captureMediaStripSnapshot(this.projectWithTrace(messages, project)); } + projectMediaStripped( + messages: readonly ContextMessage[], + snapshot?: MediaStripSnapshot, + ): readonly Message[] { + const projected = this.projectWithTrace(messages, project); + return stripMediaPartsBySnapshot( + projected, + snapshot ?? captureMediaStripSnapshot(projected), + ); + } + private projectWithTrace( messages: readonly ContextMessage[], - fn: (history: readonly ContextMessage[], onAnomaly?: OnAnomaly) => Message[], + fn: (history: readonly ContextMessage[], onAnomaly?: (anomaly: ProjectionAnomaly) => void) => Message[], ): readonly Message[] { const anomalies: ProjectionAnomaly[] = []; const result = fn(messages, (anomaly) => anomalies.push(anomaly)); @@ -92,17 +121,26 @@ export class AgentContextProjectorService implements IAgentContextProjectorServi if (signature === this.lastRepairSignature) return; this.lastRepairSignature = signature; - const { - reordered, - synthesized, - droppedOrphan, - duplicateCallsDropped, - duplicateResultsDropped, - leadingDropped, - assistantsMerged, - whitespaceDropped, - vacuousDropped, - } = summarizeProjectionRepairs(notable); + let reordered = 0; + let synthesized = 0; + let droppedOrphan = 0; + let duplicateCallsDropped = 0; + let duplicateResultsDropped = 0; + let leadingDropped = 0; + let assistantsMerged = 0; + let whitespaceDropped = 0; + let vacuousDropped = 0; + for (const anomaly of notable) { + if (anomaly.kind === 'tool_result_reordered') reordered += 1; + else if (anomaly.kind === 'tool_result_synthesized') synthesized += 1; + else if (anomaly.kind === 'orphan_tool_result_dropped') droppedOrphan += 1; + else if (anomaly.kind === 'duplicate_tool_call_dropped') duplicateCallsDropped += 1; + else if (anomaly.kind === 'duplicate_tool_result_dropped') duplicateResultsDropped += 1; + else if (anomaly.kind === 'leading_non_user_dropped') leadingDropped += 1; + else if (anomaly.kind === 'consecutive_assistants_merged') assistantsMerged += 1; + else if (anomaly.kind === 'vacuous_message_dropped') vacuousDropped += 1; + else whitespaceDropped += 1; + } const toolCallIds = [ ...new Set( notable.flatMap((anomaly) => ('toolCallId' in anomaly ? [anomaly.toolCallId] : [])), @@ -134,6 +172,459 @@ export class AgentContextProjectorService implements IAgentContextProjectorServi } } +type ProjectionAnomaly = + | { readonly kind: 'tool_result_reordered'; readonly toolCallId: string } + | { readonly kind: 'tool_result_synthesized'; readonly toolCallId: string; readonly trailing: boolean } + | { readonly kind: 'orphan_tool_result_dropped'; readonly toolCallId: string } + | { readonly kind: 'duplicate_tool_call_dropped'; readonly toolCallId: string } + | { readonly kind: 'duplicate_tool_result_dropped'; readonly toolCallId: string } + | { readonly kind: 'leading_non_user_dropped'; readonly role: string } + | { readonly kind: 'consecutive_assistants_merged' } + | { readonly kind: 'whitespace_text_dropped'; readonly role: string } + | { readonly kind: 'vacuous_message_dropped'; readonly role: string }; + +type OnAnomaly = (anomaly: ProjectionAnomaly) => void; + +export const MEDIA_DEGRADE_KEEP_RECENT = 2; + +const MEDIA_DEGRADED_PLACEHOLDERS = { + image_url: + '[image omitted: dropped to fit the provider request size limit; re-read the file to view it]', + audio_url: + '[audio omitted: dropped to fit the provider request size limit; re-read the file to hear it]', + video_url: + '[video omitted: dropped to fit the provider request size limit; re-read the file to view it]', +} as const; + +export const MEDIA_STRIPPED_PLACEHOLDERS = { + image_url: + '[image omitted for provider compatibility; re-read the file to view it or get conversion guidance]', + audio_url: + '[audio omitted for provider compatibility; re-read the file to hear it]', + video_url: + '[video omitted for provider compatibility; re-read the file to view it]', +} as const; + +type MediaPlaceholderSet = typeof MEDIA_DEGRADED_PLACEHOLDERS | typeof MEDIA_STRIPPED_PLACEHOLDERS; + +type DegradableMediaPart = Extract< + ContentPart, + { readonly type: keyof MediaPlaceholderSet } +>; + +interface MediaContainer { + readonly url: string; + readonly id?: string; +} + +interface MediaStripSnapshotData { + readonly keys: ReadonlySet<string>; +} + +type MediaContainerKeyCache = Partial<Record<DegradableMediaPart['type'], string>>; + +const MEDIA_CONTAINER_KEY_CACHE = new WeakMap<MediaContainer, MediaContainerKeyCache>(); + +function isDegradableMediaPart( + part: ContentPart, +): part is DegradableMediaPart { + return part.type in MEDIA_DEGRADED_PLACEHOLDERS; +} + +function mediaContainer(part: DegradableMediaPart): MediaContainer { + if (part.type === 'image_url') return part.imageUrl; + if (part.type === 'audio_url') return part.audioUrl; + return part.videoUrl; +} + +function mediaStripKey(part: DegradableMediaPart): string { + const container = mediaContainer(part); + let cache = MEDIA_CONTAINER_KEY_CACHE.get(container); + const cached = cache?.[part.type]; + if (cached !== undefined) return cached; + + const key = createHash('sha256') + .update(part.type) + .update('\0') + .update(container.id ?? '') + .update('\0') + .update(container.url) + .digest('hex'); + if (cache === undefined) { + cache = {}; + MEDIA_CONTAINER_KEY_CACHE.set(container, cache); + } + cache[part.type] = key; + return key; +} + +function mediaStripSnapshotKeys(snapshot: MediaStripSnapshot): ReadonlySet<string> { + return (snapshot as unknown as MediaStripSnapshotData).keys; +} + +export function captureMediaStripSnapshot( + messages: readonly Message[], +): MediaStripSnapshot { + const keys = new Set<string>(); + for (const message of messages) { + for (const part of message.content) { + if (isDegradableMediaPart(part)) keys.add(mediaStripKey(part)); + } + } + return Object.freeze({ keys }) as unknown as MediaStripSnapshot; +} + +export function stripMediaPartsBySnapshot( + messages: readonly Message[], + snapshot: MediaStripSnapshot, +): readonly Message[] { + const keys = mediaStripSnapshotKeys(snapshot); + let changed = false; + const result = messages.map((message) => { + let messageChanged = false; + const content = message.content.map((part): ContentPart => { + if (!isDegradableMediaPart(part) || !keys.has(mediaStripKey(part))) return part; + changed = true; + messageChanged = true; + return { type: 'text', text: MEDIA_STRIPPED_PLACEHOLDERS[part.type] }; + }); + return messageChanged ? { ...message, content } : message; + }); + return changed ? result : messages; +} + +export function degradeOlderMediaParts( + messages: readonly Message[], + keepRecent: number, + placeholders: MediaPlaceholderSet = MEDIA_DEGRADED_PLACEHOLDERS, +): readonly Message[] { + const mediaCount = messages.reduce( + (count, message) => count + message.content.filter(isDegradableMediaPart).length, + 0, + ); + let toDegrade = Math.max(0, mediaCount - keepRecent); + if (toDegrade === 0) return messages; + + return messages.map((message) => { + if (toDegrade === 0 || !message.content.some(isDegradableMediaPart)) return message; + const content = message.content.map((part): ContentPart => { + if (toDegrade === 0 || !isDegradableMediaPart(part)) return part; + toDegrade -= 1; + return { type: 'text', text: placeholders[part.type] }; + }); + return { ...message, content }; + }); +} + +function projectStrict(history: readonly ContextMessage[], onAnomaly?: OnAnomaly): Message[] { + const projected = project(history, onAnomaly); + return dropLeadingNonUserMessages( + mergeConsecutiveAssistantMessages(dedupeDuplicateToolCalls(projected, onAnomaly), onAnomaly), + onAnomaly, + ); +} + +function dedupeDuplicateToolCalls(messages: readonly Message[], onAnomaly?: OnAnomaly): Message[] { + const seenToolCallIds = new Set<string>(); + const keptToolResultIndexes = new Map<string, number>(); + const out: Message[] = []; + for (const message of messages) { + if (message.role === 'assistant' && message.toolCalls.length > 0) { + const kept = message.toolCalls.filter((toolCall) => { + if (seenToolCallIds.has(toolCall.id)) { + onAnomaly?.({ kind: 'duplicate_tool_call_dropped', toolCallId: toolCall.id }); + return false; + } + seenToolCallIds.add(toolCall.id); + return true; + }); + if (kept.length === message.toolCalls.length) { + out.push(message); + } else if (kept.length > 0 || !message.content.every(isVacuousContentPart)) { + out.push({ ...message, toolCalls: kept }); + } else if (message.content.length > 0) { + onAnomaly?.({ kind: 'vacuous_message_dropped', role: message.role }); + } + continue; + } + if (message.role === 'tool' && message.toolCallId !== undefined) { + const previousIndex = keptToolResultIndexes.get(message.toolCallId); + if (previousIndex !== undefined) { + if (isInterruptedToolResult(out[previousIndex]) && !isInterruptedToolResult(message)) { + out[previousIndex] = message; + } else { + onAnomaly?.({ kind: 'duplicate_tool_result_dropped', toolCallId: message.toolCallId }); + } + continue; + } + keptToolResultIndexes.set(message.toolCallId, out.length); + } + out.push(message); + } + return out; +} + +function mergeConsecutiveAssistantMessages( + messages: readonly Message[], + onAnomaly?: OnAnomaly, +): Message[] { + const out: Message[] = []; + for (const message of messages) { + const previous = out.at(-1); + if (previous !== undefined && previous.role === 'assistant' && message.role === 'assistant') { + out[out.length - 1] = { + ...previous, + content: [...previous.content, ...message.content], + toolCalls: [...previous.toolCalls, ...message.toolCalls], + }; + onAnomaly?.({ kind: 'consecutive_assistants_merged' }); + continue; + } + out.push(message); + } + return out; +} + +function dropLeadingNonUserMessages(messages: readonly Message[], onAnomaly?: OnAnomaly): Message[] { + let start = 0; + while (start < messages.length && messages[start]?.role !== 'user') { + onAnomaly?.({ kind: 'leading_non_user_dropped', role: messages[start]!.role }); + start += 1; + } + return start === 0 ? [...messages] : messages.slice(start); +} + +function project(history: readonly ContextMessage[], onAnomaly?: OnAnomaly): Message[] { + const hasAssistant = history.some( + (message) => message.partial !== true && message.role === 'assistant', + ); + + let lastNonToolIndex = history.length - 1; + while ( + lastNonToolIndex >= 0 && + (history[lastNonToolIndex]?.role === 'tool' || history[lastNonToolIndex]?.partial === true) + ) { + lastNonToolIndex -= 1; + } + + const out: Message[] = []; + const openSlots = new Map<string, OpenSlot>(); + let merge: MergeGroup | undefined; + + const flushMerge = (): void => { + if (merge === undefined) return; + if (merge.singleContent === undefined) { + const text = merge.texts.join('\n\n'); + const content: ContentPart[] = text === '' ? [] : [{ type: 'text', text }]; + content.push(...merge.parts); + out[merge.index] = { + role: 'user', + name: undefined, + content, + toolCalls: [], + toolCallId: undefined, + partial: undefined, + }; + } + merge = undefined; + }; + + const markForeignBetween = (): void => { + for (const slot of openSlots.values()) slot.foreignBetween = true; + }; + + const emit = (source: ContextMessage): void => { + const content = projectedContent(source, onAnomaly); + if (source.toolCalls.length === 0 && !hasDeclaredTools(source)) { + if (content.length === 0) return; + if (content.every(isVacuousContentPart)) { + onAnomaly?.({ kind: 'vacuous_message_dropped', role: source.role }); + return; + } + } + + if (openSlots.size > 0) markForeignBetween(); + + if (canMergeUserMessage(source)) { + if (merge === undefined) { + out.push(toWireMessage(source, content)); + merge = { index: out.length - 1, singleContent: content, texts: [], parts: [] }; + } else { + if (merge.singleContent !== undefined) { + appendMergeContent(merge, merge.singleContent); + merge.singleContent = undefined; + } + appendMergeContent(merge, content); + } + return; + } + flushMerge(); + out.push(toWireMessage(source, content)); + }; + + for (const [index, message] of history.entries()) { + if (message.partial === true) continue; + if (message.role === 'tool') { + if (!hasAssistant) { + emit(message); + continue; + } + if (message.toolCallId === undefined) continue; + const slot = openSlots.get(message.toolCallId); + if (slot === undefined) { + if (openSlots.size > 0) markForeignBetween(); + onAnomaly?.({ kind: 'orphan_tool_result_dropped', toolCallId: message.toolCallId }); + continue; + } + openSlots.delete(message.toolCallId); + if (slot.foreignBetween) { + onAnomaly?.({ kind: 'tool_result_reordered', toolCallId: message.toolCallId }); + } + out[slot.index] = toWireMessage(message, projectedContent(message, onAnomaly)); + continue; + } + emit(message); + for (const call of message.toolCalls) { + const reopened = openSlots.get(call.id); + if (reopened !== undefined) { + out[reopened.index] = createInterruptedToolResult(call.id); + onAnomaly?.({ + kind: 'tool_result_synthesized', + toolCallId: call.id, + trailing: reopened.ownerIndex >= lastNonToolIndex, + }); + } + openSlots.set(call.id, { index: out.length, ownerIndex: index, foreignBetween: false }); + out.push(TOOL_RESULT_SLOT); + } + } + for (const [id, slot] of openSlots) { + out[slot.index] = createInterruptedToolResult(id); + onAnomaly?.({ + kind: 'tool_result_synthesized', + toolCallId: id, + trailing: slot.ownerIndex >= lastNonToolIndex, + }); + } + flushMerge(); + return out; +} + +interface OpenSlot { + index: number; + ownerIndex: number; + foreignBetween: boolean; +} + +interface MergeGroup { + index: number; + singleContent: readonly ContentPart[] | undefined; + texts: string[]; + parts: ContentPart[]; +} + +function appendMergeContent(group: MergeGroup, content: readonly ContentPart[]): void { + let text = ''; + for (const part of content) { + if (part.type === 'text') text += part.text; + else group.parts.push(part); + } + if (text.length > 0) group.texts.push(text); +} + +function projectedContent(source: ContextMessage, onAnomaly?: OnAnomaly): ContentPart[] { + const content = + source.role === 'tool' + ? renderToolResultForModel({ + output: outputFromToolContent(source.content), + isError: source.isError, + note: source.note, + }) + : source.content; + return cleanContent(source, content, onAnomaly); +} + +function cleanContent( + source: ContextMessage, + rawContent: readonly ContentPart[], + onAnomaly?: OnAnomaly, +): ContentPart[] { + const hasBlank = rawContent.some(isBlankText); + let content: readonly ContentPart[] = rawContent; + if (hasBlank) { + const filtered: ContentPart[] = []; + for (const part of rawContent) { + if (isBlankText(part)) { + if (part.type === 'text' && part.text.length > 0) { + onAnomaly?.({ kind: 'whitespace_text_dropped', role: source.role }); + } + } else { + filtered.push(part); + } + } + content = filtered; + } + if (source.role === 'tool' && content.length === 0) { + throw new Error2( + ErrorCodes.REQUEST_INVALID, + 'Tool result message content cannot be empty after removing empty text blocks.', + { details: { toolCallId: source.toolCallId } }, + ); + } + return [...content]; +} + +function outputFromToolContent(content: readonly ContentPart[]): string | readonly ContentPart[] { + const only = content[0]; + return content.length === 1 && only?.type === 'text' ? only.text : content; +} + +const TOOL_INTERRUPTED_TEXT = + 'Tool result is not available in the current context. Do not assume the tool completed successfully.'; + +const TOOL_RESULT_SLOT: Message = createInterruptedToolResult(''); + +function createInterruptedToolResult(toolCallId: string): Message { + return { + role: 'tool', + name: undefined, + content: [{ type: 'text', text: TOOL_INTERRUPTED_TEXT }], + toolCalls: [], + toolCallId, + partial: undefined, + }; +} + +function isInterruptedToolResult(message: Message | undefined): boolean { + if (message?.role !== 'tool') return false; + const [part] = message.content; + return part?.type === 'text' && part.text === TOOL_INTERRUPTED_TEXT; +} + +function isBlankText(part: ContentPart): boolean { + return part.type === 'text' && part.text.trim().length === 0; +} + +function canMergeUserMessage(message: ContextMessage): boolean { + return message.role === 'user' && message.origin?.kind === 'user'; +} + +function hasDeclaredTools(message: ContextMessage): boolean { + return message.tools !== undefined && message.tools.length > 0; +} + +function toWireMessage(message: ContextMessage, content: ContentPart[]): Message { + return { + role: message.role, + name: message.name, + content, + toolCalls: message.toolCalls, + toolCallId: message.toolCallId, + partial: message.partial, + tools: message.tools, + }; +} + registerScopedService( LifecycleScope.Agent, IAgentContextProjectorService, diff --git a/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts b/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts deleted file mode 100644 index 741465ce9..000000000 --- a/packages/agent-core-v2/src/agent/contextProjector/mediaProjection.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { createHash } from 'node:crypto'; - -import type { ContentPart, Message } from '#/kosong/contract/message'; - -import type { MediaStripSnapshot } from './contextProjector'; - -export const MEDIA_DEGRADE_KEEP_RECENT = 2; - -const MEDIA_DEGRADED_PLACEHOLDERS = { - image_url: - '[image omitted: dropped to fit the provider request size limit; re-read the file to view it]', - audio_url: - '[audio omitted: dropped to fit the provider request size limit; re-read the file to hear it]', - video_url: - '[video omitted: dropped to fit the provider request size limit; re-read the file to view it]', -} as const; - -export const MEDIA_STRIPPED_PLACEHOLDERS = { - image_url: - '[image omitted for provider compatibility; re-read the file to view it or get conversion guidance]', - audio_url: - '[audio omitted for provider compatibility; re-read the file to hear it]', - video_url: - '[video omitted for provider compatibility; re-read the file to view it]', -} as const; - -type MediaPlaceholderSet = typeof MEDIA_DEGRADED_PLACEHOLDERS | typeof MEDIA_STRIPPED_PLACEHOLDERS; - -type DegradableMediaPart = Extract< - ContentPart, - { readonly type: keyof MediaPlaceholderSet } ->; - -interface MediaContainer { - readonly url: string; - readonly id?: string; -} - -interface MediaStripSnapshotData { - readonly keys: ReadonlySet<string>; -} - -type MediaContainerKeyCache = Partial<Record<DegradableMediaPart['type'], string>>; - -const MEDIA_CONTAINER_KEY_CACHE = new WeakMap<MediaContainer, MediaContainerKeyCache>(); - -function isDegradableMediaPart( - part: ContentPart, -): part is DegradableMediaPart { - return part.type in MEDIA_DEGRADED_PLACEHOLDERS; -} - -function mediaContainer(part: DegradableMediaPart): MediaContainer { - if (part.type === 'image_url') return part.imageUrl; - if (part.type === 'audio_url') return part.audioUrl; - return part.videoUrl; -} - -function mediaStripKey(part: DegradableMediaPart): string { - const container = mediaContainer(part); - let cache = MEDIA_CONTAINER_KEY_CACHE.get(container); - const cached = cache?.[part.type]; - if (cached !== undefined) return cached; - - const key = createHash('sha256') - .update(part.type) - .update('\0') - .update(container.id ?? '') - .update('\0') - .update(container.url) - .digest('hex'); - if (cache === undefined) { - cache = {}; - MEDIA_CONTAINER_KEY_CACHE.set(container, cache); - } - cache[part.type] = key; - return key; -} - -function mediaStripSnapshotKeys(snapshot: MediaStripSnapshot): ReadonlySet<string> { - return (snapshot as unknown as MediaStripSnapshotData).keys; -} - -export function captureMediaStripSnapshot( - messages: readonly Message[], -): MediaStripSnapshot { - const keys = new Set<string>(); - for (const message of messages) { - for (const part of message.content) { - if (isDegradableMediaPart(part)) keys.add(mediaStripKey(part)); - } - } - return Object.freeze({ keys }) as unknown as MediaStripSnapshot; -} - -export function stripMediaPartsBySnapshot( - messages: readonly Message[], - snapshot: MediaStripSnapshot, -): readonly Message[] { - const keys = mediaStripSnapshotKeys(snapshot); - let changed = false; - const result = messages.map((message) => { - let messageChanged = false; - const content = message.content.map((part): ContentPart => { - if (!isDegradableMediaPart(part) || !keys.has(mediaStripKey(part))) return part; - changed = true; - messageChanged = true; - return { type: 'text', text: MEDIA_STRIPPED_PLACEHOLDERS[part.type] }; - }); - return messageChanged ? { ...message, content } : message; - }); - return changed ? result : messages; -} - -export function degradeOlderMediaParts( - messages: readonly Message[], - keepRecent: number, - placeholders: MediaPlaceholderSet = MEDIA_DEGRADED_PLACEHOLDERS, -): readonly Message[] { - const mediaCount = messages.reduce( - (count, message) => count + message.content.filter(isDegradableMediaPart).length, - 0, - ); - let toDegrade = Math.max(0, mediaCount - keepRecent); - if (toDegrade === 0) return messages; - - return messages.map((message) => { - if (toDegrade === 0 || !message.content.some(isDegradableMediaPart)) return message; - const content = message.content.map((part): ContentPart => { - if (toDegrade === 0 || !isDegradableMediaPart(part)) return part; - toDegrade -= 1; - return { type: 'text', text: placeholders[part.type] }; - }); - return { ...message, content }; - }); -} diff --git a/packages/agent-core-v2/src/agent/contextProjector/projection.ts b/packages/agent-core-v2/src/agent/contextProjector/projection.ts deleted file mode 100644 index c4cd5f726..000000000 --- a/packages/agent-core-v2/src/agent/contextProjector/projection.ts +++ /dev/null @@ -1,427 +0,0 @@ -import { ErrorCodes, Error2 } from '#/errors'; -import { renderToolResultForModel } from '#/agent/contextMemory/toolResultRender'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import { isVacuousContentPart } from '#/agent/contextMemory/vacuousContent'; -import type { ContentPart, Message } from '#/kosong/contract/message'; - -export type ProjectionAnomaly = - | { readonly kind: 'tool_result_reordered'; readonly toolCallId: string } - | { readonly kind: 'tool_result_synthesized'; readonly toolCallId: string; readonly trailing: boolean } - | { readonly kind: 'orphan_tool_result_dropped'; readonly toolCallId: string } - | { readonly kind: 'duplicate_tool_call_dropped'; readonly toolCallId: string } - | { readonly kind: 'duplicate_tool_result_dropped'; readonly toolCallId: string } - | { readonly kind: 'leading_non_user_dropped'; readonly role: string } - | { readonly kind: 'consecutive_assistants_merged' } - | { readonly kind: 'whitespace_text_dropped'; readonly role: string } - | { readonly kind: 'vacuous_message_dropped'; readonly role: string }; - -export type OnAnomaly = (anomaly: ProjectionAnomaly) => void; - -export interface ProjectionRepairSummary { - readonly reordered: number; - readonly synthesized: number; - readonly droppedOrphan: number; - readonly duplicateCallsDropped: number; - readonly duplicateResultsDropped: number; - readonly leadingDropped: number; - readonly assistantsMerged: number; - readonly whitespaceDropped: number; - readonly vacuousDropped: number; -} - -export function summarizeProjectionRepairs( - anomalies: readonly ProjectionAnomaly[], -): ProjectionRepairSummary { - const summary = { - reordered: 0, - synthesized: 0, - droppedOrphan: 0, - duplicateCallsDropped: 0, - duplicateResultsDropped: 0, - leadingDropped: 0, - assistantsMerged: 0, - whitespaceDropped: 0, - vacuousDropped: 0, - }; - for (const anomaly of anomalies) { - if (anomaly.kind === 'tool_result_reordered') summary.reordered += 1; - else if (anomaly.kind === 'tool_result_synthesized') summary.synthesized += 1; - else if (anomaly.kind === 'orphan_tool_result_dropped') summary.droppedOrphan += 1; - else if (anomaly.kind === 'duplicate_tool_call_dropped') summary.duplicateCallsDropped += 1; - else if (anomaly.kind === 'duplicate_tool_result_dropped') summary.duplicateResultsDropped += 1; - else if (anomaly.kind === 'leading_non_user_dropped') summary.leadingDropped += 1; - else if (anomaly.kind === 'consecutive_assistants_merged') summary.assistantsMerged += 1; - else if (anomaly.kind === 'vacuous_message_dropped') summary.vacuousDropped += 1; - else summary.whitespaceDropped += 1; - } - return summary; -} - -export function project(history: readonly ContextMessage[], onAnomaly?: OnAnomaly): Message[] { - const layout = sliceLayout(history); - return flattenBlocks(pairBlocks(history, layout, onAnomaly), layout, onAnomaly); -} - -export function projectStrict( - history: readonly ContextMessage[], - onAnomaly?: OnAnomaly, -): Message[] { - const projected = project(history, onAnomaly); - return dropLeadingNonUserMessages( - mergeConsecutiveAssistantMessages(dedupeDuplicateToolCalls(projected, onAnomaly), onAnomaly), - onAnomaly, - ); -} - -interface SliceLayout { - readonly sizing: boolean; - readonly lastNonToolIndex: number; -} - -function sliceLayout(history: readonly ContextMessage[]): SliceLayout { - let sizing = true; - let lastNonToolIndex = -1; - for (const [index, message] of history.entries()) { - if (message.partial === true || message.role === 'tool') continue; - lastNonToolIndex = index; - if (message.role === 'assistant') sizing = false; - } - return { sizing, lastNonToolIndex }; -} - -interface AttachedResult { - readonly source: ContextMessage; - readonly content: ContentPart[]; -} - -const INTERRUPTED_RESULT = Symbol('interruptedResult'); - -interface PendingCall { - readonly callId: string; - result: AttachedResult | typeof INTERRUPTED_RESULT | undefined; - foreignBetween: boolean; -} - -interface Exchange { - readonly source: ContextMessage; - readonly content: ContentPart[]; - readonly ownerIndex: number; - readonly pending: PendingCall[]; -} - -type Block = - | { - readonly kind: 'message'; - readonly source: ContextMessage; - readonly content: ContentPart[]; - } - | { readonly kind: 'exchange'; readonly exchange: Exchange }; - -function pairBlocks( - history: readonly ContextMessage[], - layout: SliceLayout, - onAnomaly?: OnAnomaly, -): Block[] { - const blocks: Block[] = []; - const openCalls = new Map<string, { exchange: Exchange; pending: PendingCall }>(); - - const markForeignBetween = (): void => { - for (const { pending } of openCalls.values()) pending.foreignBetween = true; - }; - - for (const [index, message] of history.entries()) { - if (message.partial === true) continue; - if (message.role === 'tool' && !layout.sizing) { - if (message.toolCallId === undefined) continue; - const open = openCalls.get(message.toolCallId); - if (open === undefined) { - markForeignBetween(); - onAnomaly?.({ kind: 'orphan_tool_result_dropped', toolCallId: message.toolCallId }); - continue; - } - openCalls.delete(message.toolCallId); - open.pending.result = { source: message, content: projectedContent(message, onAnomaly) }; - if (open.pending.foreignBetween) { - onAnomaly?.({ kind: 'tool_result_reordered', toolCallId: message.toolCallId }); - } - continue; - } - - const content = projectedContent(message, onAnomaly); - if (message.toolCalls.length === 0 && !hasDeclaredTools(message)) { - if (content.length === 0) continue; - if (content.every(isVacuousContentPart)) { - onAnomaly?.({ kind: 'vacuous_message_dropped', role: message.role }); - continue; - } - } - markForeignBetween(); - if (message.toolCalls.length === 0) { - blocks.push({ kind: 'message', source: message, content }); - continue; - } - - const exchange: Exchange = { source: message, content, ownerIndex: index, pending: [] }; - blocks.push({ kind: 'exchange', exchange }); - for (const call of message.toolCalls) { - const superseded = openCalls.get(call.id); - if (superseded !== undefined) { - superseded.pending.result = INTERRUPTED_RESULT; - onAnomaly?.({ - kind: 'tool_result_synthesized', - toolCallId: call.id, - trailing: superseded.exchange.ownerIndex >= layout.lastNonToolIndex, - }); - } - const pending: PendingCall = { callId: call.id, result: undefined, foreignBetween: false }; - exchange.pending.push(pending); - openCalls.set(call.id, { exchange, pending }); - } - } - return blocks; -} - -interface MergeState { - single: { readonly source: ContextMessage; readonly content: ContentPart[] } | undefined; - readonly texts: string[]; - readonly parts: ContentPart[]; -} - -function flattenBlocks( - blocks: readonly Block[], - layout: SliceLayout, - onAnomaly?: OnAnomaly, -): Message[] { - const out: Message[] = []; - let merge: MergeState | undefined; - - const flushMerge = (): void => { - if (merge === undefined) return; - if (merge.single !== undefined) { - out.push(toWireMessage(merge.single.source, merge.single.content)); - } else { - const text = merge.texts.join('\n\n'); - const content: ContentPart[] = text === '' ? [] : [{ type: 'text', text }]; - content.push(...merge.parts); - out.push({ - role: 'user', - name: undefined, - content, - toolCalls: [], - toolCallId: undefined, - partial: undefined, - }); - } - merge = undefined; - }; - - for (const block of blocks) { - if (block.kind === 'message') { - if (canMergeUserMessage(block.source)) { - if (merge === undefined) { - merge = { single: block, texts: [], parts: [] }; - } else { - if (merge.single !== undefined) { - appendMergeContent(merge, merge.single.content); - merge.single = undefined; - } - appendMergeContent(merge, block.content); - } - continue; - } - flushMerge(); - out.push(toWireMessage(block.source, block.content)); - continue; - } - - flushMerge(); - const { exchange } = block; - out.push(toWireMessage(exchange.source, exchange.content)); - for (const pending of exchange.pending) { - if (pending.result === undefined) { - out.push(createInterruptedToolResult(pending.callId)); - onAnomaly?.({ - kind: 'tool_result_synthesized', - toolCallId: pending.callId, - trailing: exchange.ownerIndex >= layout.lastNonToolIndex, - }); - } else if (pending.result === INTERRUPTED_RESULT) { - out.push(createInterruptedToolResult(pending.callId)); - } else { - out.push(toWireMessage(pending.result.source, pending.result.content)); - } - } - } - flushMerge(); - return out; -} - -function dedupeDuplicateToolCalls(messages: readonly Message[], onAnomaly?: OnAnomaly): Message[] { - const seenToolCallIds = new Set<string>(); - const keptToolResultIndexes = new Map<string, number>(); - const out: Message[] = []; - for (const message of messages) { - if (message.role === 'assistant' && message.toolCalls.length > 0) { - const kept = message.toolCalls.filter((toolCall) => { - if (seenToolCallIds.has(toolCall.id)) { - onAnomaly?.({ kind: 'duplicate_tool_call_dropped', toolCallId: toolCall.id }); - return false; - } - seenToolCallIds.add(toolCall.id); - return true; - }); - if (kept.length === message.toolCalls.length) { - out.push(message); - } else if (kept.length > 0 || !message.content.every(isVacuousContentPart)) { - out.push({ ...message, toolCalls: kept }); - } else if (message.content.length > 0) { - onAnomaly?.({ kind: 'vacuous_message_dropped', role: message.role }); - } - continue; - } - if (message.role === 'tool' && message.toolCallId !== undefined) { - const previousIndex = keptToolResultIndexes.get(message.toolCallId); - if (previousIndex !== undefined) { - if (isInterruptedToolResult(out[previousIndex]) && !isInterruptedToolResult(message)) { - out[previousIndex] = message; - } else { - onAnomaly?.({ kind: 'duplicate_tool_result_dropped', toolCallId: message.toolCallId }); - } - continue; - } - keptToolResultIndexes.set(message.toolCallId, out.length); - } - out.push(message); - } - return out; -} - -function mergeConsecutiveAssistantMessages( - messages: readonly Message[], - onAnomaly?: OnAnomaly, -): Message[] { - const out: Message[] = []; - for (const message of messages) { - const previous = out.at(-1); - if (previous !== undefined && previous.role === 'assistant' && message.role === 'assistant') { - out[out.length - 1] = { - ...previous, - content: [...previous.content, ...message.content], - toolCalls: [...previous.toolCalls, ...message.toolCalls], - }; - onAnomaly?.({ kind: 'consecutive_assistants_merged' }); - continue; - } - out.push(message); - } - return out; -} - -function dropLeadingNonUserMessages(messages: readonly Message[], onAnomaly?: OnAnomaly): Message[] { - let start = 0; - while (start < messages.length && messages[start]?.role !== 'user') { - onAnomaly?.({ kind: 'leading_non_user_dropped', role: messages[start]!.role }); - start += 1; - } - return start === 0 ? [...messages] : messages.slice(start); -} - -function appendMergeContent(group: MergeState, content: readonly ContentPart[]): void { - let text = ''; - for (const part of content) { - if (part.type === 'text') text += part.text; - else group.parts.push(part); - } - if (text.length > 0) group.texts.push(text); -} - -function projectedContent(source: ContextMessage, onAnomaly?: OnAnomaly): ContentPart[] { - const content = - source.role === 'tool' - ? renderToolResultForModel({ - output: outputFromToolContent(source.content), - isError: source.isError, - note: source.note, - }) - : source.content; - return cleanContent(source, content, onAnomaly); -} - -function cleanContent( - source: ContextMessage, - rawContent: readonly ContentPart[], - onAnomaly?: OnAnomaly, -): ContentPart[] { - const hasBlank = rawContent.some(isBlankText); - let content: readonly ContentPart[] = rawContent; - if (hasBlank) { - const filtered: ContentPart[] = []; - for (const part of rawContent) { - if (isBlankText(part)) { - if (part.type === 'text' && part.text.length > 0) { - onAnomaly?.({ kind: 'whitespace_text_dropped', role: source.role }); - } - } else { - filtered.push(part); - } - } - content = filtered; - } - if (source.role === 'tool' && content.length === 0) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - 'Tool result message content cannot be empty after removing empty text blocks.', - { details: { toolCallId: source.toolCallId } }, - ); - } - return [...content]; -} - -function outputFromToolContent(content: readonly ContentPart[]): string | readonly ContentPart[] { - const only = content[0]; - return content.length === 1 && only?.type === 'text' ? only.text : content; -} - -const TOOL_INTERRUPTED_TEXT = - 'Tool result is not available in the current context. Do not assume the tool completed successfully.'; - -function createInterruptedToolResult(toolCallId: string): Message { - return { - role: 'tool', - name: undefined, - content: [{ type: 'text', text: TOOL_INTERRUPTED_TEXT }], - toolCalls: [], - toolCallId, - partial: undefined, - }; -} - -function isInterruptedToolResult(message: Message | undefined): boolean { - if (message?.role !== 'tool') return false; - const [part] = message.content; - return part?.type === 'text' && part.text === TOOL_INTERRUPTED_TEXT; -} - -function isBlankText(part: ContentPart): boolean { - return part.type === 'text' && part.text.trim().length === 0; -} - -function canMergeUserMessage(message: ContextMessage): boolean { - return message.role === 'user' && message.origin?.kind === 'user'; -} - -function hasDeclaredTools(message: ContextMessage): boolean { - return message.tools !== undefined && message.tools.length > 0; -} - -function toWireMessage(message: ContextMessage, content: ContentPart[]): Message { - return { - role: message.role, - name: message.name, - content, - toolCalls: message.toolCalls, - toolCallId: message.toolCallId, - partial: message.partial, - tools: message.tools, - }; -} diff --git a/packages/agent-core-v2/src/agent/dateChange/dateChange.ts b/packages/agent-core-v2/src/agent/dateChange/dateChange.ts new file mode 100644 index 000000000..cccb3396e --- /dev/null +++ b/packages/agent-core-v2/src/agent/dateChange/dateChange.ts @@ -0,0 +1,16 @@ +/** + * `dateChange` domain (L4) — `IAgentDateChangeService` contract. + * + * Defines the Agent-scope marker service that announces calendar-date changes + * through a `date_change` context-injection reminder when a session outlives + * the date rendered into its system prompt. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +export interface IAgentDateChangeService { + readonly _serviceBrand: undefined; +} + +export const IAgentDateChangeService: ServiceIdentifier<IAgentDateChangeService> = + createDecorator<IAgentDateChangeService>('agentDateChangeService'); diff --git a/packages/agent-core-v2/src/agent/dateChange/dateChangeService.ts b/packages/agent-core-v2/src/agent/dateChange/dateChangeService.ts new file mode 100644 index 000000000..dda955440 --- /dev/null +++ b/packages/agent-core-v2/src/agent/dateChange/dateChangeService.ts @@ -0,0 +1,145 @@ +/** + * `dateChange` domain (L4) — `IAgentDateChangeService` implementation. + * + * Owns the `date_change` context-injection provider. The system prompt is only + * re-rendered at profile (re)bind and after compaction, so a session that runs + * past midnight keeps a stale date; this provider appends a system-reminder at + * the next step boundary instead. The provider runs only while the profile's + * rendered snapshot exists and matches the live cwd (an empty recorded cwd + * means the render did not know it and never blocks), and reads current time + * through the App-scoped `hostClock`. The baseline prefers the + * typed disclosure on the newest surviving `date_change` injection, then the + * persisted rendered snapshot, then a runtime seed kept in `agentState`: a + * profile whose snapshot declares no date disclosure is seeded with the first + * observed date (quietly), so a crossed midnight still announces afterwards. + * Bound at Agent scope. + */ + +import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; +import { + IAgentContextInjectorService, + type ContextInjectionContext, + type ContextInjectionResult, +} from '#/agent/contextInjector/contextInjector'; +import { + disclosureOfKind, + pickDisclosureBaseline, +} from '#/agent/contextInjector/disclosureBaseline'; +import { IAgentProfileService } from '#/agent/profile/profile'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { IHostClock } from '#/os/interface/hostClock'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; + +import { IAgentDateChangeService } from './dateChange'; + +const DATE_CHANGE_INJECTION_VARIANT = 'date_change'; + +export const dateChangeSeedKey = defineState<DateDisclosure | undefined>( + 'dateChange.seed', + () => undefined, +); + +export class AgentDateChangeService extends Disposable implements IAgentDateChangeService { + declare readonly _serviceBrand: undefined; + + constructor( + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, + @IAgentProfileService private readonly profile: IAgentProfileService, + @IAgentStateService private readonly states: IAgentStateService, + @IHostClock private readonly clock: IHostClock, + @ISessionContext private readonly sessionContext: ISessionContext, + ) { + super(); + this.states.register(dateChangeSeedKey); + this._register( + dynamicInjector.register(DATE_CHANGE_INJECTION_VARIANT, (ctx) => this.reminder(ctx)), + ); + } + + private reminder({ + lastDisclosure, + }: ContextInjectionContext): ContextInjectionResult | undefined { + const profileData = this.profile.data(); + const environment = profileData.environmentDisclosure; + if ( + environment !== undefined && + environment.cwd !== '' && + environment.cwd !== this.sessionContext.cwd + ) { + return undefined; + } + const renderGeneration = profileData.renderGeneration ?? 0; + const current = currentDateDisclosure(this.clock); + const baseline = pickDisclosureBaseline<DateDisclosure>( + disclosureOfKind(lastDisclosure, 'date'), + this.dateFromProfile(), + this.states.get(dateChangeSeedKey), + ); + if (baseline === undefined) { + this.states.set(dateChangeSeedKey, { ...current, renderGeneration }); + return undefined; + } + if (baseline.localDate === current.localDate) return undefined; + return { + content: `The date has changed. Today's date is now ${current.localDate}. The date and time stated in your system prompt are stale; rely on this reminder for the current date. DO NOT mention this to the user explicitly.`, + disclosure: { + kind: 'date', + renderGeneration, + localDate: current.localDate, + timeZone: current.timeZone, + }, + }; + } + + private dateFromProfile(): DateDisclosure | undefined { + const profileData = this.profile.data(); + const environment = profileData.environmentDisclosure; + if ( + environment !== undefined && + environment.cwd !== '' && + environment.cwd !== this.sessionContext.cwd + ) { + return undefined; + } + const date = environment?.date; + if (!date?.disclosed) return undefined; + return { + ...date.value, + renderGeneration: profileData.renderGeneration ?? 0, + }; + } +} + +interface DateDisclosure { + readonly localDate: string; + readonly timeZone: string; + readonly renderGeneration: number; +} + +function currentDateDisclosure(clock: IHostClock): Omit<DateDisclosure, 'renderGeneration'> { + const date = clock.now(); + const timeZone = clock.timeZone(); + const parts = new Intl.DateTimeFormat('en-US', { + timeZone, + year: 'numeric', + month: '2-digit', + day: '2-digit', + }).formatToParts(date); + const part = (type: Intl.DateTimeFormatPartTypes): string => + parts.find((candidate) => candidate.type === type)?.value ?? ''; + return { + localDate: `${part('year')}-${part('month')}-${part('day')}`, + timeZone, + }; +} + +registerScopedService( + LifecycleScope.Agent, + IAgentDateChangeService, + AgentDateChangeService, + ScopeActivation.OnScopeCreated, + 'dateChange', +); diff --git a/packages/agent-core-v2/src/features/externalHooks/configSection.ts b/packages/agent-core-v2/src/agent/externalHooks/configSection.ts similarity index 76% rename from packages/agent-core-v2/src/features/externalHooks/configSection.ts rename to packages/agent-core-v2/src/agent/externalHooks/configSection.ts index 8e397d549..a84b322fc 100644 --- a/packages/agent-core-v2/src/features/externalHooks/configSection.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/configSection.ts @@ -1,9 +1,18 @@ +/** + * `externalHooks` domain — `hooks` config-section schema and TOML + * transforms. + * + * Owns the `[[hooks]]` configuration section (external hook definitions), + * including the snake_case ↔ camelCase TOML transforms for each hook entry. + * Registered at module load via `registerConfigSection`. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; import { isPlainObject, plainObjectToToml, transformPlainObject } from '#/app/config/toml'; -import { HOOK_EVENT_TYPES } from './internal/types'; +import { HOOK_EVENT_TYPES } from './types'; export const HOOKS_SECTION = 'hooks'; diff --git a/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts b/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts new file mode 100644 index 000000000..f56571ea1 --- /dev/null +++ b/packages/agent-core-v2/src/agent/externalHooks/externalHooks.ts @@ -0,0 +1,23 @@ +/** + * `externalHooks` domain — contract for configured external hook + * commands. + * + * The service is intentionally observer-shaped: business domains expose their + * own minimal hook contexts, and the L6 implementation listens to those hooks + * to invoke configured external commands. + */ + +import { createDecorator } from '#/_base/di/instantiation'; + +export interface RenderedExternalHookResult { + readonly event: string; + readonly message: string; + readonly text: string; +} + +export interface IAgentExternalHooksService { + readonly _serviceBrand: undefined; +} + +export const IAgentExternalHooksService = + createDecorator<IAgentExternalHooksService>('agentExternalHooksService'); diff --git a/packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooksService.ts b/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts similarity index 80% rename from packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooksService.ts rename to packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts index 81d257991..56ddf2aa0 100644 --- a/packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooksService.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/externalHooksService.ts @@ -1,9 +1,32 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `externalHooks` domain — Agent-scope adapter for external + * hook commands. + * + * Listens to hook slots and agent events owned by the agent behavior/lifecycle + * domains (`toolExecutor`, `permissionGate`, `prompt`, `turn`, `loop`, + * `fullCompaction`, and `task`) and translates those minimal contexts into the + * configured external hook commands, run through the shared App-scope + * `IExternalHooksRunnerService` (so this adapter never owns an engine lifecycle + * of its own). This includes the bus-driven lifecycle signals + * `turn.started` → `TurnStarted`, `prompt.queued` → `UserPromptQueued`, and + * `task.started` → `TaskStarted`. Every payload it sends is enriched with the + * cached session title (seeded from and kept fresh by `ISessionMetadata`). + * Appends + * UserPromptSubmit hook results through `contextMemory`, drives Stop hook + * continuations by enqueueing a mergeable `StepRequest` onto `loop`, and + * passes the current session id from `sessionContext` + * into hook runner payloads. The one mutable latch + * (`stopHookContinuationUsed`, the Stop-hook re-entry guard) is registered + * into `agentState` (`IAgentStateService`) and read/written through it; the + * hook listener registrations stay ordinary disposables on the instance. + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import { Service } from '#/_base/di/service'; -import { defineState } from '#/state/state'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; import { isPlainRecord } from '#/_base/utils/canonical-args'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentTaskService, type AgentTaskInfo, type AgentTaskNotificationContext } from '#/agent/task/task'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; @@ -15,20 +38,12 @@ import { import type { CompactionResult } from '#/agent/fullCompaction/types'; import { IAgentLoopService, type AfterStepContext } from '#/agent/loop/loop'; import { ContinuationStepRequest } from '#/agent/loop/stepRequest'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { TurnEnded } from '#/agent/loop/turnOps'; import { IAgentPromptService, type PromptSubmitContext, } from '#/agent/prompt/prompt'; -import { PromptQueued } from '#/agent/prompt/promptService'; -import { TaskNotified, TaskStarted } from '#/agent/task/taskOps'; -import { - PermissionApprovalRequested, - PermissionApprovalResolved, -} from '#/agent/toolApproval/toolApprovalService'; +import type { TurnEndedEvent, TurnStartedEvent } from '#/agent/loop/turnEvents'; import { IEventBus } from '#/app/event/eventBus'; -import { AgentEvent2 } from '#/app/event/event2'; import type { ExecutableToolResult } from '#/tool/toolContract'; import type { ResolvedToolExecutionHookContext, ToolDidExecuteContext } from '#/agent/toolExecutor/toolHooks'; import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; @@ -36,29 +51,28 @@ import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; import { toKimiErrorPayload } from '#/errors'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { IAgentExternalHooksService } from './agentExternalHooks'; -import { IExternalHooksRunnerService } from '../app/externalHooksRunner'; -import type { HookMatcherValue } from '../internal/types'; +import { IAgentExternalHooksService } from './externalHooks'; +import { IExternalHooksRunnerService } from '#/app/externalHooksRunner/externalHooksRunner'; +import type { HookMatcherValue } from './types'; import { renderUserPromptHookBlockResult, renderUserPromptHookResult, -} from '../internal/userPrompt'; +} from './user-prompt'; -export interface HookResultPayload { - readonly agentId: string; +export interface HookResultEvent { + readonly type: 'hook.result'; readonly turnId?: number; readonly hookEvent: string; readonly content: string; readonly blocked?: boolean; } -export class HookResult extends AgentEvent2<HookResultPayload> { - static override readonly type = 'hook.result'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'hook.result': HookResultEvent; + } } -export interface HookResult extends HookResultPayload {} export const externalHooksStopHookContinuationUsedKey = defineState<boolean>( 'externalHooks.stopHookContinuationUsed', @@ -76,11 +90,9 @@ export class AgentExternalHooksService extends Service implements IAgentExternal @ISessionContext private readonly sessionContext: ISessionContext, @ISessionMetadata private readonly sessionMetadata: ISessionMetadata, @IAgentStateService private readonly states: IAgentStateService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, ) { super(); - this.states.contributeState(externalHooksStopHookContinuationUsedKey); + this.states.register(externalHooksStopHookContinuationUsedKey); void this.sessionMetadata .read() .then((meta) => { @@ -176,14 +188,14 @@ export class AgentExternalHooksService extends Service implements IAgentExternal private registerPermissionHooks(): void { this._register( - this.eventBus.subscribe(PermissionApprovalRequested, (e) => { - const { type: _type, time: _time, ...inputData } = e; + this.eventBus.subscribe('permission.approval.requested', (e) => { + const { type: _type, ...inputData } = e; this.fireAndForget('PermissionRequest', inputData, e.toolName); }), ); this._register( - this.eventBus.subscribe(PermissionApprovalResolved, (e) => { - const { type: _type, time: _time, ...inputData } = e; + this.eventBus.subscribe('permission.approval.resolved', (e) => { + const { type: _type, ...inputData } = e; this.fireAndForget('PermissionResult', inputData, e.toolName); }), ); @@ -200,7 +212,7 @@ export class AgentExternalHooksService extends Service implements IAgentExternal }), ); this._register( - this.eventBus.subscribe(PromptQueued, (e) => { + this.eventBus.subscribe('prompt.queued', (e) => { this.fireAndForget( 'UserPromptQueued', { promptId: e.promptId, prompt: e.content, queueLength: e.queueLength }, @@ -212,14 +224,14 @@ export class AgentExternalHooksService extends Service implements IAgentExternal private registerTurnHooks(): void { this._register( - this.eventBus.subscribe(TurnStarted, (e) => this.notifyTurnStarted(e)), + this.eventBus.subscribe('turn.started', (e) => this.notifyTurnStarted(e)), ); this._register( - this.eventBus.subscribe(TurnEnded, (e) => this.notifyTurnEnded(e)), + this.eventBus.subscribe('turn.ended', (e) => this.notifyTurnEnded(e)), ); } - private notifyTurnStarted(event: TurnStarted): void { + private notifyTurnStarted(event: TurnStartedEvent): void { this.fireAndForget( 'TurnStarted', { @@ -279,13 +291,13 @@ export class AgentExternalHooksService extends Service implements IAgentExternal private registerTaskHooks(_tasks: IAgentTaskService): void { this._register( - this.eventBus.subscribe(TaskNotified, (e) => { - const { type: _type, time: _time, ...ctx } = e; + this.eventBus.subscribe('task.notified', (e) => { + const { type: _type, ...ctx } = e; this.notifyTaskNotification(ctx); }), ); this._register( - this.eventBus.subscribe(TaskStarted, (e) => this.notifyTaskStarted(e.info)), + this.eventBus.subscribe('task.started', (e) => this.notifyTaskStarted(e.info)), ); } @@ -362,14 +374,12 @@ export class AgentExternalHooksService extends Service implements IAgentExternal toolCalls: [], origin: { kind: 'hook_result', event: block.event, blocked: true }, }); - void this.dispatcher.dispatch( - new HookResult({ - agentId: this.scopeContext.agentId, - hookEvent: block.event, - content: block.message, - blocked: true, - }), - ); + this.eventBus.publish({ + type: 'hook.result', + hookEvent: block.event, + content: block.message, + blocked: true, + }); return true; } @@ -381,18 +391,16 @@ export class AgentExternalHooksService extends Service implements IAgentExternal toolCalls: [], origin: { kind: 'hook_result', event: append.event }, }); - void this.dispatcher.dispatch( - new HookResult({ - agentId: this.scopeContext.agentId, - hookEvent: append.event, - content: append.message, - }), - ); + this.eventBus.publish({ + type: 'hook.result', + hookEvent: append.event, + content: append.message, + }); } return false; } - private notifyTurnEnded(event: TurnEnded): void { + private notifyTurnEnded(event: Pick<TurnEndedEvent, 'turnId' | 'reason' | 'error'>): void { this.stopHookContinuationUsed = false; if (event.reason === 'failed' && event.error !== undefined) { this.notifyStopFailure(event.error, new AbortController().signal); @@ -474,3 +482,11 @@ function toolOutputText(output: ExecutableToolResult['output']): string { .map((part) => part.text) .join(''); } + +registerScopedService( + LifecycleScope.Agent, + IAgentExternalHooksService, + AgentExternalHooksService, + ScopeActivation.OnScopeCreated, + 'externalHooks', +); diff --git a/packages/agent-core-v2/src/features/externalHooks/internal/runHook.ts b/packages/agent-core-v2/src/agent/externalHooks/runner.ts similarity index 99% rename from packages/agent-core-v2/src/features/externalHooks/internal/runHook.ts rename to packages/agent-core-v2/src/agent/externalHooks/runner.ts index c25de9fa6..7f50380e1 100644 --- a/packages/agent-core-v2/src/features/externalHooks/internal/runHook.ts +++ b/packages/agent-core-v2/src/agent/externalHooks/runner.ts @@ -103,11 +103,11 @@ export async function runHook( const stderrDone = new Promise<void>((done) => proc.stderr.once('end', done)); void Promise.all([proc.wait(), stdoutDone, stderrDone]).then( ([code]) => { - void proc.dispose(); + proc.dispose(); settle(resultFromExitCode(code, stdout, stderr)); }, (error) => { - void proc.dispose(); + proc.dispose(); settle(allowResult({ stdout, stderr: stderr + errorMessage(error) })); }, ); diff --git a/packages/agent-core-v2/src/features/externalHooks/internal/types.ts b/packages/agent-core-v2/src/agent/externalHooks/types.ts similarity index 100% rename from packages/agent-core-v2/src/features/externalHooks/internal/types.ts rename to packages/agent-core-v2/src/agent/externalHooks/types.ts diff --git a/packages/agent-core-v2/src/features/externalHooks/internal/userPrompt.ts b/packages/agent-core-v2/src/agent/externalHooks/user-prompt.ts similarity index 100% rename from packages/agent-core-v2/src/features/externalHooks/internal/userPrompt.ts rename to packages/agent-core-v2/src/agent/externalHooks/user-prompt.ts diff --git a/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts b/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts index c58165945..a910cf788 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/compactionOps.ts @@ -1,10 +1,63 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `fullCompaction` domain — wire Model (`CompactionModel`) and the + * `full_compaction.begin` (`fullCompactionBegin`) / `full_compaction.cancel` + * (`fullCompactionCancel`) / `full_compaction.complete` + * (`fullCompactionComplete`) Ops that mirror the full-compaction lifecycle into + * a persisted, replayable phase, plus the `compaction.*` edge events + * (`started` / `blocked` / `cancelled` / `completed`) declared on `DomainEventMap` + * (`compaction.started` is derived from the `full_compaction.begin` Op's + * `toEvent`; the rest publish directly from the service). + * + * The Model is intentionally phase-only — `{ phase }` (initial `idle`). The + * richer per-compaction data is NOT resume state: `instruction` is only needed + * by the live worker (which does not survive a restart) and by telemetry, so it + * rides the `begin` payload (and is persisted on the record for audit) but is + * not stored in the Model; result numbers are consumed live by the + * `compaction.completed` signal and their durable effect (the summary message + * plus compaction metrics) already lives in the context history. The live + * `complete` payload is empty to match the v1 wire shape; legacy logs may still + * carry result numbers, and `apply` accepts and ignores them while collapsing + * to `idle`. Each `apply` returns the same reference on a no-op so the wire's + * reference-equality gate stays quiet; it carries no non-determinism. + * + * The runtime orchestration — `ActiveCompaction`, its `AbortController`, and + * the in-flight worker promise — stays OUT of the Model (live-only service + * members): none of it can be resumed, and a session never restores mid-flight. + * A `running` phase stranded by a crash is reset to `idle` by the service's + * `wire.hooks.onDidRestore` hook. + * + * The `compaction.*` events publish to `IEventBus` (`compaction.started` via the + * `begin` Op's `toEvent`; the rest directly from the service); they are + * declared here via interface-merge. The `full_compaction.*` record shapes are registered in + * `PersistedOpMap` (below) because the records still + * ride the per-agent `wire.jsonl` journal restored by `IWireService`. + */ + import { z } from 'zod'; -import { AgentEvent2, type AgentDomainTrait } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; -import type { CompactionBeginData, CompactionResult, CompactionSource } from './types'; +import type { CompactionBeginData, CompactionResult } from './types'; + +export interface CompactionStartedEvent { + readonly type: 'compaction.started'; + readonly trigger: 'manual' | 'auto'; + readonly instruction?: string; +} + +export interface CompactionBlockedEvent { + readonly type: 'compaction.blocked'; + readonly turnId?: number; +} + +export interface CompactionCancelledEvent { + readonly type: 'compaction.cancelled'; +} + +export interface CompactionCompletedEvent { + readonly type: 'compaction.completed'; + readonly result: CompactionResult; +} export type CompactionPhase = 'idle' | 'running' | 'cancelled' | 'completed'; @@ -12,114 +65,43 @@ export interface CompactionState { readonly phase: CompactionPhase; } -const fullCompactionBeginSchema = z.object({ - agentId: z.string(), - instruction: z.string().optional(), - source: z.custom<CompactionSource>(), +export const CompactionModel = defineModel<CompactionState>('fullCompaction', () => ({ + phase: 'idle', +})); + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'compaction.started': CompactionStartedEvent; + 'compaction.blocked': CompactionBlockedEvent; + 'compaction.cancelled': CompactionCancelledEvent; + 'compaction.completed': CompactionCompletedEvent; + } +} + +declare module '#/wire/types' { + interface PersistedOpMap { + 'full_compaction.begin': typeof fullCompactionBegin; + 'full_compaction.cancel': typeof fullCompactionCancel; + 'full_compaction.complete': typeof fullCompactionComplete; + } +} + +export const fullCompactionBegin = CompactionModel.defineOp('full_compaction.begin', { + schema: z.custom<CompactionBeginData>(), + apply: (s) => (s.phase === 'running' ? s : { phase: 'running' }), + toEvent: (p) => ({ + type: 'compaction.started' as const, + trigger: p.source, + instruction: p.instruction, + }), }); -export class FullCompactionBegin extends AgentEvent2< - z.infer<typeof fullCompactionBeginSchema> -> { - static override readonly type = 'full_compaction.begin'; - static override readonly durable = true; - static override readonly schema = fullCompactionBeginSchema; -} -export interface FullCompactionBegin extends CompactionBeginData { - readonly agentId: string; -} +export const fullCompactionCancel = CompactionModel.defineOp('full_compaction.cancel', { + schema: z.object({}), + apply: (s) => (s.phase === 'idle' ? s : { phase: 'idle' }), +}); -const fullCompactionCancelSchema = z.object({ agentId: z.string() }); - -export class FullCompactionCancel extends AgentEvent2< - z.infer<typeof fullCompactionCancelSchema> -> { - static override readonly type = 'full_compaction.cancel'; - static override readonly durable = true; - static override readonly schema = fullCompactionCancelSchema; -} -export interface FullCompactionCancel { - readonly agentId: string; -} - -const fullCompactionCompleteSchema = z.object({ agentId: z.string() }); - -export class FullCompactionComplete extends AgentEvent2< - z.infer<typeof fullCompactionCompleteSchema> -> { - static override readonly type = 'full_compaction.complete'; - static override readonly durable = true; - static override readonly schema = fullCompactionCompleteSchema; -} -export interface FullCompactionComplete { - readonly agentId: string; -} - -export interface CompactionStartedPayload { - readonly agentId: string; - readonly trigger: CompactionSource; - readonly instruction?: string; -} - -export class CompactionStarted extends AgentEvent2<CompactionStartedPayload> { - static override readonly type = 'compaction.started'; - static override readonly observable = true; -} -export interface CompactionStarted extends CompactionStartedPayload {} - -export interface CompactionBlockedPayload { - readonly agentId: string; - readonly turnId?: number; -} - -export class CompactionBlocked extends AgentEvent2<CompactionBlockedPayload> { - static override readonly type = 'compaction.blocked'; - static override readonly observable = true; -} -export interface CompactionBlocked extends CompactionBlockedPayload {} - -export class CompactionCancelled extends AgentEvent2<AgentDomainTrait> { - static override readonly type = 'compaction.cancelled'; - static override readonly observable = true; -} -export interface CompactionCancelled { - readonly agentId: string; -} - -export interface CompactionCompletedPayload { - readonly agentId: string; - readonly result: CompactionResult; -} - -export class CompactionCompleted extends AgentEvent2<CompactionCompletedPayload> { - static override readonly type = 'compaction.completed'; - static override readonly observable = true; -} -export interface CompactionCompleted extends CompactionCompletedPayload {} - -export const fullCompactionKey = defineState( - 'fullCompaction', - (): CompactionState => ({ phase: 'idle' }), -).replayable({ schema: z.custom<CompactionState>() }) - .on(FullCompactionBegin, (s, e, ctx) => { - if (s.phase !== 'running') { - s.phase = 'running'; - } - ctx.emit( - new CompactionStarted({ - agentId: e.agentId, - trigger: e.source, - instruction: e.instruction, - }), - ); - }) - .on(FullCompactionCancel, (s) => { - if (s.phase !== 'idle') { - s.phase = 'idle'; - } - }) - .on(FullCompactionComplete, (s) => { - if (s.phase !== 'idle') { - s.phase = 'idle'; - } - }); +export const fullCompactionComplete = CompactionModel.defineOp('full_compaction.complete', { + schema: z.object({}), + apply: (s) => (s.phase === 'idle' ? s : { phase: 'idle' }), +}); diff --git a/packages/agent-core-v2/src/agent/fullCompaction/errors.ts b/packages/agent-core-v2/src/agent/fullCompaction/errors.ts index 554374ae3..0aa153ce7 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/errors.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/errors.ts @@ -1,3 +1,7 @@ +/** + * `fullCompaction` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const FullCompactionErrors = { diff --git a/packages/agent-core-v2/src/agent/fullCompaction/fullCompaction.ts b/packages/agent-core-v2/src/agent/fullCompaction/fullCompaction.ts index 88c70d194..5a005ea28 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/fullCompaction.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/fullCompaction.ts @@ -24,7 +24,6 @@ export interface IAgentFullCompactionService { readonly compacting: FullCompactionTask | null; begin(input: FullCompactionInput): boolean; - cancel(): void; readonly hooks: Hooks<{ onWillCompact: FullCompactionTask; diff --git a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts index 4aaa0a287..27cd51d08 100644 --- a/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts +++ b/packages/agent-core-v2/src/agent/fullCompaction/fullCompactionService.ts @@ -1,33 +1,47 @@ -import type { IDisposable } from '#/_base/di/lifecycle'; +/** + * `fullCompaction` domain — `IAgentFullCompactionService` implementation. + * + * Runs full-history compaction: reserves the per-turn compaction slot, drives + * the compaction LLM round (with overflow / truncation shrink retries), + * applies the summary back into context memory, and recovers the loop from + * context-overflow failures by blocking the turn on the in-flight job. The + * mutable plain-data state (`compactionCountInTurn`, + * `observedMaxContextTokensByModel`, `lastCompactedTokenCount`, + * `consecutiveOverflowCompactions`, `activeTurnId`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it; + * `_compacting` (the in-flight job — AbortController / Promise / trace), the + * `hooks.onWillCompact` slot, the `_onDidFinishCompaction` Emitter, the + * `strategy`, and the lazily-resolved `contextInjectorService` stay instance + * fields (mechanism, not plain data). Bound at Agent scope and constructed with + * the scope so the overflow recovery handler registers before the first turn + * runs. + */ + import { Service } from "#/_base/di/service"; +import { IInstantiationService } from '#/_base/di/instantiation'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { ILogService } from '#/_base/log/log'; +import { defineState } from '#/_base/state/stateRegistry'; import { renderPrompt } from "#/_base/utils/render-prompt"; import { estimateTokensForMessage } from "#/kosong/contract/tokens"; import { buildCompactionSummaryText, isRealUserInput } from '#/agent/contextMemory/compactionHandoff'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; import { IAgentLLMRequesterService, type AgentLLMRequestFinish } from '#/agent/llmRequester/llmRequester'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; import { retryBackoffDelays, sleepForRetry } from '#/_base/utils/retry'; import { IAgentLoopService, type LoopErrorContext } from '#/agent/loop/loop'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { TurnEnded } from '#/agent/loop/turnOps'; import { isAbortError } from '#/_base/utils/abort'; import { IAgentProfileService, type ProfileModelContext } from '#/agent/profile/profile'; -import { - agentContextOfScope, - IAgentScopeContext, -} from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { stripDynamicToolContext } from '#/agent/toolSelect/dynamicTools'; import { IAgentToolSelectService } from '#/agent/toolSelect/toolSelect'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { AgentTodo, type TodoRuntime } from '#/features/todo/todoAgentRuntime'; -import { renderTodoList } from '#/features/todo/todoItem'; +import { ISessionTodoService } from '#/session/todo/sessionTodo'; +import { renderTodoList, type TodoItem } from '#/session/todo/todoItem'; import { APIContextOverflowError, APIEmptyResponseError, @@ -41,8 +55,7 @@ import { IEventBus } from '#/app/event/eventBus'; import type { CompactionFailedEvent, CompactionFinishedEvent } from '#/app/telemetry/events'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { ErrorCodes, Error2, isCodedError, isError2, toKimiErrorPayload, unwrapErrorCause } from "#/errors"; -import { AgentErrorEvent } from '#/agent/mcp/mcpEvents'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import compactionInstructionTemplate from './compaction-instruction.md?raw'; import { IAgentFullCompactionService, @@ -54,13 +67,10 @@ import { type CompactionStrategy, } from './strategy'; import { - CompactionBlocked, - CompactionCancelled, - CompactionCompleted, - fullCompactionKey, - FullCompactionBegin, - FullCompactionCancel, - FullCompactionComplete, + CompactionModel, + fullCompactionBegin, + fullCompactionCancel, + fullCompactionComplete, } from './compactionOps'; import { type CompactionBeginData, @@ -87,7 +97,6 @@ type CompactionTelemetryProperties = Pick< interface ActiveCompaction extends FullCompactionTask { readonly originTurnId?: number; - readonly quiescence?: IDisposable; trace?: LLMRequestTrace; blockedByTurn: boolean; } @@ -135,47 +144,46 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom readonly onDidFinishCompaction: Event<FullCompactionTask> = this._onDidFinishCompaction.event; private readonly strategy: CompactionStrategy; - private readonly todo: TodoRuntime; private _compacting: ActiveCompaction | null = null; + private contextInjectorService: IAgentContextInjectorService | undefined; constructor( @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @ISessionTokenCountingService private readonly tokenCounting: ISessionTokenCountingService, + @IAgentTokenCountingService private readonly tokenCounting: IAgentTokenCountingService, @IAgentLLMRequesterService private readonly llmRequester: IAgentLLMRequesterService, @IAgentProfileService private readonly profile: IAgentProfileService, @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, @IAgentToolSelectService private readonly toolSelect: IAgentToolSelectService, - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext private readonly agent: IAgentScopeContext, + @IInstantiationService private readonly instantiation: IInstantiationService, + @ISessionTodoService private readonly todo: ISessionTodoService, @ITelemetryService private readonly telemetry: ITelemetryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IWireService private readonly wire: IWireService, @IEventBus private readonly eventBus: IEventBus, + @ILogService private readonly log: ILogService, @IAgentLoopService private readonly loopService: IAgentLoopService, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.todo = manager.resolve(agent.agentContext, AgentTodo); - this.states.contributeState(fullCompactionKey); - this.states.contributeState(fullCompactionCompactionCountInTurnKey); - this.states.contributeState(fullCompactionObservedMaxContextTokensByModelKey); - this.states.contributeState(fullCompactionLastCompactedTokenCountKey); - this.states.contributeState(fullCompactionConsecutiveOverflowCompactionsKey); - this.states.contributeState(fullCompactionActiveTurnIdKey); + this.states.register(fullCompactionCompactionCountInTurnKey); + this.states.register(fullCompactionObservedMaxContextTokensByModelKey); + this.states.register(fullCompactionLastCompactedTokenCountKey); + this.states.register(fullCompactionConsecutiveOverflowCompactionsKey); + this.states.register(fullCompactionActiveTurnIdKey); this.strategy = new RuntimeCompactionStrategy( () => this.resolveModelContextWithEffectiveMax(), (message) => this.tokenCounting.estimateMessage(message), ); this._register( - this.dispatcher.hooks.onDidRestore.register('full-compaction', async (_ctx, next) => { + this.wire.hooks.onDidRestore.register('full-compaction', async (_ctx, next) => { this.normalizeAfterReplay(); await next(); }), ); this._register( - this.eventBus.subscribe(TurnStarted, () => this.resetForTurn()), + this.eventBus.subscribe('turn.started', () => this.resetForTurn()), ); this._register( - this.eventBus.subscribe(TurnEnded, () => { + this.eventBus.subscribe('turn.ended', () => { this.activeTurnId = undefined; }), ); @@ -240,17 +248,6 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom return this._compacting; } - cancel(): void { - const active = this._compacting; - if (active !== null) { - this.telemetry.track2('cancel', { - from: 'compacting', - trace_id: active.traceId, - }); - } - active?.abortController.abort(); - } - private getEffectiveMaxContextTokens(): number { const capability = this.profile.data().modelCapabilities; const configured = capability.max_input_tokens ?? capability.max_context_tokens; @@ -332,39 +329,22 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom if (!this.reserveCompactionSlot(data.source)) return false; const tokenCount = this.validateCompactionStart(data.source); - const quiescence = data.source === 'manual' - ? this.loopService.tryAcquireQuiescence() - : undefined; - if (data.source === 'manual' && quiescence === undefined) { - throw new Error2( - ErrorCodes.COMPACTION_UNABLE, - 'Cannot compact while a turn is active or another context change is running. Wait for it to finish, then retry.', - ); - } - try { - void this.dispatcher.dispatch( - new FullCompactionBegin({ ...data, agentId: this.agent.agentId }), - ); + this.wire.dispatch(fullCompactionBegin(data)); - const active = this.createActiveCompaction( - data.source, - tokenCount, - data.source === 'auto' ? this.activeTurnId : undefined, - quiescence, - ); - this._compacting = active.task; - active.task.abortController.signal.addEventListener( - 'abort', - () => this.cancelActive(active.task), - { once: true }, - ); - void this.compactionWorker(active.task, data).then(active.resolve, active.reject); - void active.task.promise.catch(() => undefined); - return true; - } catch (error) { - quiescence?.dispose(); - throw error; - } + const active = this.createActiveCompaction( + data.source, + tokenCount, + data.source === 'auto' ? this.activeTurnId : undefined, + ); + this._compacting = active.task; + active.task.abortController.signal.addEventListener( + 'abort', + () => this.cancelActive(active.task), + { once: true }, + ); + void this.compactionWorker(active.task, data).then(active.resolve, active.reject); + void active.task.promise.catch(() => undefined); + return true; } private reserveCompactionSlot(source: CompactionBeginData['source']): boolean { @@ -394,7 +374,6 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom trigger: CompactionBeginData['source'], tokenCount: number, originTurnId: number | undefined, - quiescence: IDisposable | undefined, ): { readonly task: ActiveCompaction; readonly resolve: (result: CompactionResult) => void; @@ -414,7 +393,6 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom trigger, tokenCount, originTurnId, - quiescence, get traceId() { return this.trace?.traceId; }, @@ -434,25 +412,25 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom private cancelActive(active: ActiveCompaction): boolean { if (this._compacting !== active) return false; - void this.dispatcher.dispatch(new FullCompactionCancel({ agentId: this.agent.agentId })); + this.wire.dispatch(fullCompactionCancel({})); this._compacting = null; if (!active.abortController.signal.aborted) { active.abortController.abort(); } - void this.dispatcher.dispatch(new CompactionCancelled({ agentId: this.agent.agentId })); + this.eventBus.publish({ type: 'compaction.cancelled' }); return true; } private markCompleted(active: ActiveCompaction): boolean { if (this._compacting !== active) return false; - void this.dispatcher.dispatch(new FullCompactionComplete({ agentId: this.agent.agentId })); + this.wire.dispatch(fullCompactionComplete({})); this._compacting = null; return true; } private normalizeAfterReplay(): void { - if (this.states.get(fullCompactionKey).phase !== 'running') return; - void this.dispatcher.dispatch(new FullCompactionCancel({ agentId: this.agent.agentId })); + if (this.wire.getModel(CompactionModel).phase !== 'running') return; + this.wire.dispatch(fullCompactionCancel({})); } private resetForTurn(): void { @@ -537,9 +515,7 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom if (active === null) return; active.blockedByTurn = true; this.propagateBlockingAbort(active, signal); - void this.dispatcher.dispatch( - new CompactionBlocked({ agentId: this.agent.agentId, turnId }), - ); + this.eventBus.publish({ type: 'compaction.blocked', turnId }); try { await active.promise; } catch (error) { @@ -576,15 +552,20 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom try { const result = await this.compactionRound(active, data); if (this._compacting !== active) throw compactionCancelledReason(active); + try { + await this.profile.refreshSystemPrompt(); + } catch (error) { + this.log.error('failed to refresh system prompt after compaction', { error }); + } this.lastCompactedTokenCount = result.tokensAfter; + await this.contextInjector.injectAfterCompaction(); + this.lastCompactedTokenCount = this.tokenCountWithPending(); if (!this.markCompleted(active)) { throw compactionCancelledReason(active); } const { contextSummary: _contextSummary, ...eventResult } = result; void _contextSummary; - void this.dispatcher.dispatch( - new CompactionCompleted({ agentId: this.agent.agentId, result: eventResult }), - ); + this.eventBus.publish({ type: 'compaction.completed', result: eventResult }); return result; } catch (error) { if (active.abortController.signal.aborted || isAbortError(error)) { @@ -598,16 +579,13 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom if (blockedByTurn) { throw error; } - void this.dispatcher.dispatch( - new AgentErrorEvent({ ...toKimiErrorPayload(error), agentId: this.agent.agentId }), - ); + this.eventBus.publish({ + type: 'error', + ...toKimiErrorPayload(error), + }); throw error; } finally { - try { - this._onDidFinishCompaction.fire(active); - } finally { - active.quiescence?.dispose(); - } + this._onDidFinishCompaction.fire(active); } } @@ -695,11 +673,8 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom retryCount = 0; continue; } - const unwrappedError = unwrapErrorCause(error); if ( - (error instanceof CompactionTruncatedError || - (unwrappedError instanceof APIEmptyResponseError && - unwrappedError.finishReason !== 'filtered')) && + (error instanceof CompactionTruncatedError || unwrapErrorCause(error) instanceof APIEmptyResponseError) && messagesToCompact.length > 1 ) { emptyOrTruncatedShrinkCount += 1; @@ -712,7 +687,7 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom retryCount = 0; continue; } - if (!isRetryableGenerateError(unwrappedError)) { + if (!isRetryableGenerateError(unwrapErrorCause(error))) { throw error; } if (retryCount + 1 >= MAX_COMPACTION_RETRY_ATTEMPTS) { @@ -737,7 +712,7 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom throw compactionCancelledReason(active); } - const summary = await this.postProcessSummary(attempt.summary); + const summary = this.postProcessSummary(attempt.summary); const result = this.context.applyCompaction({ summary, contextSummary: buildCompactionSummaryText(summary), @@ -789,16 +764,29 @@ export class AgentFullCompactionService extends Service implements IAgentFullCom } } - private async postProcessSummary(summary: string): Promise<string> { - const todos = this.todo.get(); + private postProcessSummary(summary: string): string { + const todos = this.currentTodos(); if (todos.length === 0) { return summary; } return `${summary.trim()}\n\n${renderTodoList(todos, '## TODO List')}`; } + private currentTodos(): readonly TodoItem[] { + return this.todo.getTodos(); + } + private tokenCountWithPending(): number { - return this.tokenCounting.get(agentContextOfScope(this.agent)).size; + return this.tokenCounting.get().size; + } + + private get contextInjector(): IAgentContextInjectorService { + if (this.contextInjectorService === undefined) { + this.contextInjectorService = this.instantiation.invokeFunction((accessor) => + accessor.get(IAgentContextInjectorService), + ); + } + return this.contextInjectorService; } } diff --git a/packages/agent-core-v2/src/features/goal/errors.ts b/packages/agent-core-v2/src/agent/goal/errors.ts similarity index 98% rename from packages/agent-core-v2/src/features/goal/errors.ts rename to packages/agent-core-v2/src/agent/goal/errors.ts index ec0bc2837..ff59b94e9 100644 --- a/packages/agent-core-v2/src/features/goal/errors.ts +++ b/packages/agent-core-v2/src/agent/goal/errors.ts @@ -1,3 +1,7 @@ +/** + * `goal` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const GoalErrors = { diff --git a/packages/agent-core-v2/src/agent/goal/goal.ts b/packages/agent-core-v2/src/agent/goal/goal.ts new file mode 100644 index 000000000..e88c5952c --- /dev/null +++ b/packages/agent-core-v2/src/agent/goal/goal.ts @@ -0,0 +1,43 @@ +/** + * `goal` domain — main-agent goal lifecycle contract. + * + * Defines the commands and snapshots used to create, inspect, update, and clear + * the durable goal state. Bound at Agent scope; subagent callers are rejected + * with `goal.unsupported_agent`. + */ +import { createDecorator } from "#/_base/di/instantiation"; +import type { + CreateGoalInput, + GoalActor, + GoalBudgetLimits, + GoalSnapshot, + GoalToolResult, +} from './types'; + +export interface GoalReasonInput { + readonly reason?: string; +} + +export interface ResumeGoalInput extends GoalReasonInput { + readonly continueIfPaused?: boolean; + readonly continueIfBlocked?: boolean; +} + +export interface IAgentGoalService { + readonly _serviceBrand: undefined; + + getGoal(): GoalToolResult; + isGoalToolTarget(turnId: number, goalId: string): boolean; + createGoal(input: CreateGoalInput, actor?: GoalActor): Promise<GoalSnapshot>; + pauseGoal(input?: GoalReasonInput, actor?: GoalActor): Promise<GoalSnapshot>; + resumeGoal(input?: ResumeGoalInput, actor?: GoalActor): Promise<GoalSnapshot>; + cancelGoal(input?: GoalReasonInput, actor?: GoalActor): Promise<GoalSnapshot>; + setBudgetLimits( + input: { readonly budgetLimits: GoalBudgetLimits }, + actor?: GoalActor, + ): Promise<GoalSnapshot>; + markComplete(input?: GoalReasonInput, actor?: GoalActor): Promise<GoalSnapshot | null>; + markBlocked(input?: GoalReasonInput, actor?: GoalActor): Promise<GoalSnapshot | null>; +} + +export const IAgentGoalService = createDecorator<IAgentGoalService>('agentGoalService'); diff --git a/packages/agent-core-v2/src/features/goal/goalDeadlineScheduler.ts b/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts similarity index 69% rename from packages/agent-core-v2/src/features/goal/goalDeadlineScheduler.ts rename to packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts index 5ae6a80bd..6d460f6e8 100644 --- a/packages/agent-core-v2/src/features/goal/goalDeadlineScheduler.ts +++ b/packages/agent-core-v2/src/agent/goal/goalDeadlineScheduler.ts @@ -1,3 +1,10 @@ +/** + * `goal` domain — wall-clock deadline scheduling contract. + * + * Defines the App-scoped `IGoalDeadlineScheduler` for measuring active time + * and arming hard wall-clock budget deadlines. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/features/goal/goalDeadlineSchedulerService.ts b/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts similarity index 60% rename from packages/agent-core-v2/src/features/goal/goalDeadlineSchedulerService.ts rename to packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts index 44d4b2b24..8e63f1199 100644 --- a/packages/agent-core-v2/src/features/goal/goalDeadlineSchedulerService.ts +++ b/packages/agent-core-v2/src/agent/goal/goalDeadlineSchedulerService.ts @@ -1,4 +1,13 @@ +/** + * `goal` domain — `IGoalDeadlineScheduler` implementation. + * + * Measures monotonic elapsed time and schedules disposable one-shot deadlines + * with the host timer API. Bound at App scope. + */ + import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IGoalDeadlineScheduler } from './goalDeadlineScheduler'; @@ -21,3 +30,11 @@ export class GoalDeadlineSchedulerService implements IGoalDeadlineScheduler { }); } } + +registerScopedService( + LifecycleScope.App, + IGoalDeadlineScheduler, + GoalDeadlineSchedulerService, + ScopeActivation.OnDemand, + 'goal', +); diff --git a/packages/agent-core-v2/src/agent/goal/goalOps.ts b/packages/agent-core-v2/src/agent/goal/goalOps.ts new file mode 100644 index 000000000..e623d27aa --- /dev/null +++ b/packages/agent-core-v2/src/agent/goal/goalOps.ts @@ -0,0 +1,169 @@ +/** + * `goal` domain — wire Model (`GoalModel`) and the `goal.create` + * (`createGoal`) / `goal.update` (`updateGoal`) / `goal.clear` (`clearGoal`) + * Ops for the per-agent goal lifecycle. + * + * Declares the current goal as `GoalState | null` (initial `null`); `GoalState` + * holds the persistent, replayable fields — identity, objective, status, + * `turnsUsed` / `tokensUsed`, the accumulated `wallClockMs`, the current + * active interval's epoch-ms `wallClockResumedAt`, `budgetLimits`, and + * `terminalReason`. The persistence contract charges an active interval from + * its persisted create/resume anchor through the first recovery clock read, + * then folds that interval into `wallClockMs` while recovery pauses the goal. + * This intentionally includes unobservable crash downtime: a monotonic clock + * cannot span processes, while learning the crash instant would require + * periodic durable writes. System-clock rollback is clamped to zero. The + * 1.4 -> 1.5 compatibility transform (also applied before sealing + * envelope-less logs) derives missing create/resume/checkpoint anchors from + * those records' existing epoch-ms `time` stamps. The + * non-deterministic values stay OUT of `apply`: `goalId` and the wall-clock + * anchor/totals are computed by the live service and carried in Op payloads. + * Each `apply` returns the same reference when nothing changes so the wire's + * reference-equality gate stays quiet. The `goal.updated` fact is + * published live to `IEventBus` by the service (declared here via + * interface-merge); `wire.restore` rebuilds the Model silently and the + * service's `wire.hooks.onDidRestore` + * forces a replayed `active` goal back to `paused`. + */ + +import { z } from 'zod'; + +import { defineModel } from '#/wire/model'; + +import type { + GoalBudgetLimits, + GoalChange, + GoalSnapshot, + GoalStatus, +} from './types'; + +export interface GoalState { + readonly goalId: string; + readonly objective: string; + readonly completionCriterion?: string; + readonly status: GoalStatus; + readonly turnsUsed: number; + readonly tokensUsed: number; + readonly wallClockMs: number; + readonly wallClockResumedAt?: number; + readonly budgetLimits: GoalBudgetLimits; + readonly terminalReason?: string; +} + +export type GoalModelState = GoalState | null; + +export const GoalModel = defineModel<GoalModelState>('goal', () => null); + +const GoalStatusSchema = z.enum(['active', 'paused', 'blocked', 'complete']); + +const GoalActorSchema = z.enum(['user', 'model', 'runtime', 'system']); + +const GoalBudgetLimitsSchema = z + .object({ + tokenBudget: z.number().finite().nonnegative().optional(), + turnBudget: z.number().finite().nonnegative().optional(), + wallClockBudgetMs: z.number().finite().nonnegative().optional(), + }) + .strict(); + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'goal.updated': { + snapshot: GoalSnapshot | null; + change?: GoalChange; + }; + } +} + +declare module '#/wire/types' { + interface PersistedOpMap { + 'goal.create': typeof createGoal; + 'goal.update': typeof updateGoal; + 'goal.clear': typeof clearGoal; + forked: typeof forkGoal; + } +} + +export const createGoal = GoalModel.defineOp('goal.create', { + schema: z + .object({ + goalId: z.string(), + objective: z.string(), + completionCriterion: z.string().optional(), + wallClockResumedAt: z.number().finite().nonnegative().optional(), + status: GoalStatusSchema.optional(), + actor: GoalActorSchema.optional(), + budgetLimits: GoalBudgetLimitsSchema.optional(), + }) + .strip(), + apply: (_s, p) => ({ + goalId: p.goalId, + objective: p.objective, + completionCriterion: p.completionCriterion, + status: 'active', + turnsUsed: 0, + tokensUsed: 0, + wallClockMs: 0, + wallClockResumedAt: p.wallClockResumedAt, + budgetLimits: {}, + }), +}); + +export const updateGoal = GoalModel.defineOp('goal.update', { + schema: z + .object({ + goalId: z.string().optional(), + status: GoalStatusSchema.optional(), + reason: z.string().optional(), + turnsUsed: z.number().finite().nonnegative().optional(), + tokensUsed: z.number().finite().nonnegative().optional(), + wallClockMs: z.number().finite().nonnegative().optional(), + wallClockResumedAt: z.number().finite().nonnegative().optional(), + budgetLimits: GoalBudgetLimitsSchema.optional(), + actor: GoalActorSchema.optional(), + }) + .strip(), + apply: (s, p) => { + if (s === null) return null; + let next: GoalState | undefined; + if (p.status !== undefined && p.status !== s.status) { + next = { + ...(next ?? s), + status: p.status, + terminalReason: p.status === 'active' ? undefined : p.reason, + wallClockResumedAt: + p.status === 'active' ? p.wallClockResumedAt : undefined, + }; + } + if (p.turnsUsed !== undefined && p.turnsUsed !== s.turnsUsed) { + next = { ...(next ?? s), turnsUsed: p.turnsUsed }; + } + if (p.tokensUsed !== undefined && p.tokensUsed !== s.tokensUsed) { + next = { ...(next ?? s), tokensUsed: p.tokensUsed }; + } + if (p.wallClockMs !== undefined && p.wallClockMs !== s.wallClockMs) { + next = { ...(next ?? s), wallClockMs: p.wallClockMs }; + } + if ( + p.wallClockResumedAt !== undefined && + (p.status ?? s.status) === 'active' && + p.wallClockResumedAt !== s.wallClockResumedAt + ) { + next = { ...(next ?? s), wallClockResumedAt: p.wallClockResumedAt }; + } + if (p.budgetLimits !== undefined && p.budgetLimits !== s.budgetLimits) { + next = { ...(next ?? s), budgetLimits: p.budgetLimits }; + } + return next ?? s; + }, +}); + +export const clearGoal = GoalModel.defineOp('goal.clear', { + schema: z.object({}), + apply: () => null, +}); + +export const forkGoal = GoalModel.defineOp('forked', { + schema: z.object({}), + apply: () => null, +}); diff --git a/packages/agent-core-v2/src/agent/goal/goalService.ts b/packages/agent-core-v2/src/agent/goal/goalService.ts new file mode 100644 index 000000000..ae56369e3 --- /dev/null +++ b/packages/agent-core-v2/src/agent/goal/goalService.ts @@ -0,0 +1,1330 @@ +/** + * `goal` domain — `IAgentGoalService` implementation. + * + * Owns the main-agent goal lifecycle; persists the goal in the `wire` + * `GoalModel` (`GoalState | null`) through the `goal.create` / `goal.update` / + * `goal.clear` Ops (`wire.dispatch`), reads it through `wire.getModel`, + * publishes `goal.updated` live to `IEventBus`, and forces a replayed `active` + * goal back to `paused` via `wire.hooks.onDidRestore`. The accumulated + * `wallClockMs` lives in the Model (set from each Op payload, never by + * `Date.now()` inside `apply`); the active interval's epoch-ms + * `wallClockResumedAt` anchor is + * persisted at create/resume boundaries so recovery can settle crash-spanning + * elapsed time without periodic writes. A `forked` wire Op clears the Model + * at a fork boundary. Injects reminders through + * `contextInjector`, drives continuation turns by enqueueing `newTurn` + * `StepRequest`s onto `loop` (the continuation message materializes when the + * loop pops it), accounts live + * turn usage through `usage`, observes terminal goal tool results through + * `toolExecutor`, writes system reminders through `systemReminder`, reports + * telemetry through `telemetry`, and checks main-agent eligibility through + * `scopeContext`. Measures time and arms hard deadlines through `goal`'s + * App-scoped deadline scheduler. Two `onBeforeExecuteTool` veto listeners + * guard the goal lifecycle: stale or budget-exhausted goal tool calls are + * vetoed with synthetic results, and a `CreateGoal` call carrying a + * `goal_start` display outside `auto` mode defers to a cold `waitUntil` + * factory that runs the goal-start review through `toolApproval` under the + * origin `goal-start-review-ask` — including the permission-mode switch + * picked on the approval surface. The mutable turn-tracking and wall-clock + * state (`liveTurnId`, `goalDrivenTurns`, `countedGoalTurns`, + * `goalStarterTurns`, `goalOutcomeToolResultTurns`, + * `goalOutcomeContinuationTurns`, `budgetGraceTurns`, + * `pendingContinuationGoals`, `goalTurnTargets`, `exhaustedTurnBudgetGoals`, + * `liveWallClockStartedAt`, `resumeContinuation`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it; the + * `pendingContinuation` promise lock and the `wallClockDeadline` disposable + * slot stay plain fields. Bound at Agent scope. + * Subagent instances reject every goal command and do not install goal + * injection, accounting, budget, or continuation hooks. + */ + +import { randomUUID } from 'node:crypto'; + +import type { TurnEndedEvent, TurnStartedEvent } from '#/agent/loop/turnEvents'; +import { Disposable, MutableDisposable, type IDisposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; +import { abortError } from '#/_base/utils/abort'; +import { isPlainRecord } from '#/_base/utils/canonical-args'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; +import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; +import { GoalInjection } from '#/agent/goal/injection/goalInjection'; +import { + IAgentLoopService, + type AfterStepContext, + type BeforeStepContext, + type EnqueueReceipt, +} from '#/agent/loop/loop'; +import { LOOP_CONTROL_SECTION, type LoopControl } from '#/agent/loop/configSection'; +import { LoopErrors } from '#/agent/loop/errors'; +import { ContinuationStepRequest, MessageStepRequest } from '#/agent/loop/stepRequest'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; +import { IAgentStateService } from '#/agent/state/agentState'; +import type { ExecutableToolResult } from '#/tool/toolContract'; +import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; +import type { PermissionMode } from '#/agent/permissionPolicy/types'; +import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; +import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; +import type { BeforeToolExecuteEvent } from '#/agent/toolExecutor/toolHooks'; +import { IAgentUsageService, type UsageRecordedContext } from '#/agent/usage/usage'; +import type { GoalBudgetProperties } from '#/app/telemetry/events'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import { IConfigService } from '#/app/config/config'; +import { + ErrorCodes, + Error2, + toKimiErrorPayload, + type KimiErrorPayload, +} from '#/errors'; +import { IWireService } from '#/wire/wire'; +import { defineModel } from '#/wire/model'; +import { IEventBus } from '#/app/event/eventBus'; + +import { IAgentGoalService, type GoalReasonInput, type ResumeGoalInput } from './goal'; +import { IGoalDeadlineScheduler } from './goalDeadlineScheduler'; +import { clearGoal, createGoal, GoalModel, updateGoal, type GoalState } from './goalOps'; +import type { + CreateGoalInput, + GoalActor, + GoalBudgetLimits, + GoalBudgetReport, + GoalChange, + GoalChangeStats, + GoalSnapshot, + GoalStatus, + GoalToolResult, +} from './types'; + +const MAX_GOAL_OBJECTIVE_LENGTH = 4000; + +const MAX_GOAL_COMPLETION_CRITERION_LENGTH = MAX_GOAL_OBJECTIVE_LENGTH; + +const GOAL_CANCELLED_REMINDER = [ + 'The user cancelled the current goal.', + 'Ignore earlier active-goal reminders for that goal.', + 'Handle the next user request normally unless the user starts or resumes a goal.', +].join(' '); + +const GOAL_FORK_CLEARED_REMINDER = [ + 'This fork does not have a current goal.', + 'Ignore earlier active-goal reminders from the source session.', + 'Handle requests normally unless the user starts a new goal.', +].join(' '); + +const GOAL_FORK_CLEARED_REMINDER_NAME = 'goal_fork_cleared'; + +const GOAL_CONTINUATION_ORIGIN: PromptOrigin = { + kind: 'system_trigger', + name: 'goal_continuation', +}; +const GOAL_RATE_LIMIT_PAUSE_REASON = 'Paused after provider rate limit'; +const GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX = 'Paused after provider connection error'; +const GOAL_PROVIDER_AUTH_PAUSE_PREFIX = 'Paused after provider authentication error'; +const GOAL_PROVIDER_API_PAUSE_PREFIX = 'Paused after provider API error'; +const GOAL_MODEL_CONFIG_PAUSE_PREFIX = 'Paused after model configuration error'; +const GOAL_RUNTIME_PAUSE_PREFIX = 'Paused after runtime error'; +const GOAL_CONTINUATION_FAILURE_PAUSE_PREFIX = 'Paused after goal continuation failure'; +const GOAL_PROVIDER_FILTERED_PAUSE_REASON = 'Paused after provider safety policy block'; +const GOAL_BUDGET_BLOCK_PREFIX = 'Blocked after goal budget reached'; +const LLM_NOT_SET_MESSAGE = 'LLM not set, send "/login" to login'; + +const GOAL_BUDGET_STOP_REMINDER_NAME = 'goal_budget_stop'; + +const GOAL_BUDGET_STOP_REMINDER = [ + "The goal's hard budget was reached and the goal is now blocked; the user can resume it with /goal resume.", + 'Stop immediately.', + 'Do not call any more tools: they will be rejected.', + 'Write a brief final status message summarizing the progress so far.', +].join(' '); + +const GOAL_BUDGET_TOOLS_REJECTED_MESSAGE = + 'Goal budget exhausted; tool calls are rejected. Write your final message.'; +const GOAL_STALE_TOOL_RESULT = + 'Goal changed since this turn started; ignored stale goal tool call.'; + +const GOAL_CONTINUATION_PROMPT = [ + 'Continue working toward the active goal.', + 'Keep the self-audit brief. Do not explore unrelated interpretations once the goal can be', + 'decided. If the objective is simple, already answered, impossible, unsafe, or contradictory,', + 'do not run another goal turn. Explain briefly if useful, then call UpdateGoal with `complete`', + 'or `blocked` in the same turn. Otherwise, weigh the objective and any completion criteria', + 'against the work done so far, choose one bounded, useful slice of work, and use the existing', + 'conversation context and your tools. Do not try to finish a broad goal in one turn unless the', + 'whole goal is genuinely small. Most goal turns should not call UpdateGoal: after completing a', + 'useful slice, if material work remains, end the turn normally without calling UpdateGoal so', + 'the runtime can continue the goal in the next turn. Call UpdateGoal with `complete` only when', + 'all required work is done, any stated validation has passed, and there is no useful next', + 'action. Completion audit: before calling `complete`, verify the current state against the', + 'actual objective and every explicit requirement. Treat weak or indirect evidence as not', + 'complete. Do not mark complete after only producing a plan, summary, first pass, or partial', + 'result. Do not mark complete merely because a budget is nearly exhausted or you want to stop.', + 'Blocked audit: do not call UpdateGoal with `blocked` the first time you hit a blocker. Use', + '`blocked` only for a genuine impasse: an external condition, required user input, missing', + 'credentials or permissions, or a persistent technical failure. For those non-terminal', + 'blockers, the same blocking condition must repeat for at least 3 consecutive goal turns before', + 'you call `blocked`, counting the original/user-triggered turn and automatic continuations.', + 'If a previously blocked goal is resumed, treat the resumed run as a fresh blocked audit.', + 'Exception: if the objective itself is impossible, unsafe, or contradictory, call UpdateGoal', + 'with `blocked` in the same turn; do not run more goal turns just to satisfy the audit. Do not', + 'use `blocked` because the work is large, hard, slow, uncertain, incomplete, still needs', + 'validation, would benefit from clarification, or needs more goal turns. Once the 3-turn', + 'threshold is met and you cannot make meaningful progress without user input or an', + 'external-state change, call UpdateGoal with `blocked`; do not keep reporting the blocker while', + 'leaving the goal active. Do not ask the user for input unless a real blocker prevents progress.', +].join(' '); + +const GOAL_STEP_CAP_CONTINUATION_PROMPT = [ + 'The previous goal turn reached the per-turn step limit before finishing its work,', + 'so a new turn was started for you. Pick up where that turn stopped and keep each', + 'slice of work small enough to fit the limit.', + GOAL_CONTINUATION_PROMPT, +].join(' '); + +interface GoalForkNoticeState { + readonly goalPresent: boolean; + readonly reminderPending: boolean; +} + +interface PendingContinuation { + readonly receipt: EnqueueReceipt; + readonly goalId: string; + turnId?: number; +} + +interface ResumeContinuation { + readonly turnId: number; + readonly goalId: string; +} + +const GoalForkNoticeModel = defineModel<GoalForkNoticeState>( + 'goalForkNotice', + () => ({ goalPresent: false, reminderPending: false }), + { + reducers: { + 'goal.create': (state) => ({ ...state, goalPresent: true }), + 'goal.clear': (state) => ({ ...state, goalPresent: false }), + forked: (state) => ({ + goalPresent: false, + reminderPending: state.goalPresent || state.reminderPending, + }), + 'context.append_message': (state, payload: { message?: ContextMessage }) => + state.reminderPending && isGoalForkClearedReminder(payload.message) + ? { ...state, reminderPending: false } + : state, + }, + }, +); + +function isGoalForkClearedReminder(message: ContextMessage | undefined): boolean { + return ( + message?.origin?.kind === 'system_trigger' && + message.origin.name === GOAL_FORK_CLEARED_REMINDER_NAME + ); +} + +function isGoalContinuationOrigin(origin: TurnStartedEvent['origin']): boolean { + return origin.kind === 'system_trigger' && origin.name === 'goal_continuation'; +} + +export const goalLiveTurnIdKey = defineState<number | undefined>( + 'goal.liveTurnId', + () => undefined as number | undefined, +); +export const goalGoalDrivenTurnsKey = defineState<Map<number, string>>( + 'goal.goalDrivenTurns', + () => new Map(), +); +export const goalCountedGoalTurnsKey = defineState<Set<number>>( + 'goal.countedGoalTurns', + () => new Set(), +); +export const goalGoalStarterTurnsKey = defineState<Set<number>>( + 'goal.goalStarterTurns', + () => new Set(), +); +export const goalGoalOutcomeToolResultTurnsKey = defineState<Map<number, string>>( + 'goal.goalOutcomeToolResultTurns', + () => new Map(), +); +export const goalGoalOutcomeContinuationTurnsKey = defineState<Set<number>>( + 'goal.goalOutcomeContinuationTurns', + () => new Set(), +); +export const goalBudgetGraceTurnsKey = defineState<Set<number>>( + 'goal.budgetGraceTurns', + () => new Set(), +); +export const goalPendingContinuationGoalsKey = defineState<Map<number, string>>( + 'goal.pendingContinuationGoals', + () => new Map(), +); +export const goalGoalTurnTargetsKey = defineState<Map<number, string>>( + 'goal.goalTurnTargets', + () => new Map(), +); +export const goalExhaustedTurnBudgetGoalsKey = defineState<Map<number, string>>( + 'goal.exhaustedTurnBudgetGoals', + () => new Map(), +); +export const goalLiveWallClockStartedAtKey = defineState<number | undefined>( + 'goal.liveWallClockStartedAt', + () => undefined as number | undefined, +); +export const goalResumeContinuationKey = defineState<ResumeContinuation | undefined>( + 'goal.resumeContinuation', + () => undefined as ResumeContinuation | undefined, +); + +// NOTE: stays Disposable — its own 'config' collides with the Fiber +export class AgentGoalService extends Disposable implements IAgentGoalService { + declare readonly _serviceBrand: undefined; + + private readonly wallClockDeadline = this._register(new MutableDisposable<IDisposable>()); + private pendingContinuation?: PendingContinuation; + + constructor( + @IWireService private readonly wire: IWireService, + @IEventBus private readonly eventBus: IEventBus, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, + @ITelemetryService private readonly telemetry: ITelemetryService, + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, + @IAgentLoopService private readonly loopService: IAgentLoopService, + @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, + @IAgentToolApprovalService private readonly toolApproval: IAgentToolApprovalService, + @IAgentPermissionModeService private readonly permissionMode: IAgentPermissionModeService, + @IAgentUsageService usageService: IAgentUsageService, + @IConfigService private readonly config: IConfigService, + @IGoalDeadlineScheduler private readonly deadlineScheduler: IGoalDeadlineScheduler, + @IAgentScopeContext private readonly agentContext: IAgentScopeContext, + @IAgentStateService private readonly states: IAgentStateService, + ) { + super(); + this.states.register(goalLiveTurnIdKey); + this.states.register(goalGoalDrivenTurnsKey); + this.states.register(goalCountedGoalTurnsKey); + this.states.register(goalGoalStarterTurnsKey); + this.states.register(goalGoalOutcomeToolResultTurnsKey); + this.states.register(goalGoalOutcomeContinuationTurnsKey); + this.states.register(goalBudgetGraceTurnsKey); + this.states.register(goalPendingContinuationGoalsKey); + this.states.register(goalGoalTurnTargetsKey); + this.states.register(goalExhaustedTurnBudgetGoalsKey); + this.states.register(goalLiveWallClockStartedAtKey); + this.states.register(goalResumeContinuationKey); + if (!this.isSupportedAgent) return; + this._register( + new GoalInjection( + { + getGoal: () => this.getGoal().goal, + }, + dynamicInjector, + ), + ); + this._register( + this.wire.hooks.onDidRestore.register('goal', async (_ctx, next) => { + this.normalizeAfterReplay(); + await next(); + }), + ); + this._register( + this.eventBus.subscribe('turn.started', (e) => { + this.handleTurnLaunched(e.turnId, e.origin); + }), + ); + this._register( + usageService.onDidRecord((ctx) => this.handleUsageRecorded(ctx)), + ); + this._register( + loopService.hooks.onWillBeginStep.register('goal-count-turn', async (ctx, next) => { + await this.handleBeforeStep(ctx); + await next(); + }), + ); + this._register( + loopService.hooks.onDidFinishStep.register('goal-outcome-continuation', async (ctx, next) => { + this.handleAfterStep(ctx); + await next(); + }), + ); + this._register( + toolExecutor.onBeforeExecuteTool((event) => { + if ( + event.toolCall.name !== 'CreateGoal' || + this.permissionMode.mode === 'auto' || + event.execution.display?.kind !== 'goal_start' + ) { + return; + } + event.waitUntil(async () => + this.toolApproval.requestToolApproval( + event, + { + kind: 'ask', + resolveApproval: (approval) => { + if (approval.decision !== 'approved') return undefined; + const mode = toGoalStartReviewPermissionMode(approval.selectedLabel); + if (mode !== undefined && mode !== this.permissionMode.mode) { + this.permissionMode.setMode(mode); + } + return undefined; + }, + }, + 'goal-start-review-ask', + ), + ); + }), + ); + this._register( + toolExecutor.onBeforeExecuteTool((event) => { + if (this.isStaleGoalToolCall(event)) { + event.veto({ output: GOAL_STALE_TOOL_RESULT }); + return; + } + if (this.budgetGraceTurns.has(event.turnId)) { + event.veto({ output: GOAL_BUDGET_TOOLS_REJECTED_MESSAGE }); + } + }), + ); + this._register( + toolExecutor.hooks.onDidExecuteTool.register('goal-outcome-tool-result', async (ctx, next) => { + const goalId = this.goalTurnTarget(ctx.turnId); + if ( + goalId !== undefined && + isTerminalUpdateGoalResult(ctx.toolCall.name, ctx.args, ctx.result) + ) { + this.goalOutcomeToolResultTurns.set(ctx.turnId, goalId); + } + await next(); + }), + ); + this._register( + this.eventBus.subscribe('turn.ended', (e) => { + const goalId = this.goalTurnTarget(e.turnId); + void this.handleTurnEnded(e.turnId, { reason: e.reason, error: e.error }).catch((error) => + this.settleGoalAfterContinuationFailure(error, goalId), + ); + }), + ); + } + + private get liveTurnId(): number | undefined { + return this.states.get(goalLiveTurnIdKey); + } + + private set liveTurnId(value: number | undefined) { + this.states.set(goalLiveTurnIdKey, value); + } + + private get goalDrivenTurns(): Map<number, string> { + return this.states.get(goalGoalDrivenTurnsKey); + } + + private get countedGoalTurns(): Set<number> { + return this.states.get(goalCountedGoalTurnsKey); + } + + private get goalStarterTurns(): Set<number> { + return this.states.get(goalGoalStarterTurnsKey); + } + + private get goalOutcomeToolResultTurns(): Map<number, string> { + return this.states.get(goalGoalOutcomeToolResultTurnsKey); + } + + private get goalOutcomeContinuationTurns(): Set<number> { + return this.states.get(goalGoalOutcomeContinuationTurnsKey); + } + + private get budgetGraceTurns(): Set<number> { + return this.states.get(goalBudgetGraceTurnsKey); + } + + private get pendingContinuationGoals(): Map<number, string> { + return this.states.get(goalPendingContinuationGoalsKey); + } + + private get goalTurnTargets(): Map<number, string> { + return this.states.get(goalGoalTurnTargetsKey); + } + + private get exhaustedTurnBudgetGoals(): Map<number, string> { + return this.states.get(goalExhaustedTurnBudgetGoalsKey); + } + + private get liveWallClockStartedAt(): number | undefined { + return this.states.get(goalLiveWallClockStartedAtKey); + } + + private set liveWallClockStartedAt(value: number | undefined) { + this.states.set(goalLiveWallClockStartedAtKey, value); + } + + private get resumeContinuation(): ResumeContinuation | undefined { + return this.states.get(goalResumeContinuationKey); + } + + private set resumeContinuation(value: ResumeContinuation | undefined) { + this.states.set(goalResumeContinuationKey, value); + } + + private get isSupportedAgent(): boolean { + return this.agentContext.agentId === 'main'; + } + + private assertSupportedAgent(): void { + if (this.isSupportedAgent) return; + throw new Error2( + ErrorCodes.GOAL_UNSUPPORTED_AGENT, + 'Goals are only supported by the main agent', + { details: { agentId: this.agentContext.agentId } }, + ); + } + + private get goalState(): GoalState | null { + return this.wire.getModel(GoalModel) as GoalState | null; + } + + getGoal(): GoalToolResult { + this.assertSupportedAgent(); + const state = this.goalState; + return { goal: state === null ? null : this.toSnapshot(state) }; + } + + isGoalToolTarget(turnId: number, goalId: string): boolean { + this.assertSupportedAgent(); + return this.goalTurnTargets.get(turnId) === goalId; + } + + async createGoal(input: CreateGoalInput, actor: GoalActor = 'user'): Promise<GoalSnapshot> { + this.assertSupportedAgent(); + const objective = this.validateObjective(input.objective); + this.prepareForGoalCreation(input.replace === true); + const wallClockResumedAt = Date.now(); + this.wire.dispatch( + createGoal({ + goalId: randomUUID(), + objective, + completionCriterion: normalizeCompletionCriterion(input.completionCriterion), + wallClockResumedAt, + }), + ); + this.liveWallClockStartedAt = this.deadlineScheduler.now(); + this.adoptStarterTurn(actor); + const state = this.requireState(); + this.refreshWallClockDeadline(state); + this.emitGoalUpdated(this.toSnapshot(state)); + this.telemetry.track2('goal_created', { actor, replace: input.replace === true }); + return this.toSnapshot(state); + } + + private validateObjective(value: string): string { + const objective = value.trim(); + if (objective.length === 0) { + throw new Error2(ErrorCodes.GOAL_OBJECTIVE_EMPTY, 'Goal objective cannot be empty'); + } + if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { + throw new Error2( + ErrorCodes.GOAL_OBJECTIVE_TOO_LONG, + `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters`, + ); + } + return objective; + } + + private prepareForGoalCreation(replace: boolean): void { + if (this.goalState === null) return; + if (!replace) { + throw new Error2( + ErrorCodes.GOAL_ALREADY_EXISTS, + 'A goal already exists; use replace to start a new one', + ); + } + this.clearInternal('system'); + } + + async pauseGoal(input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { + this.assertSupportedAgent(); + const state = this.requireState(); + if (state.status === 'paused') return this.toSnapshot(state); + if (state.status !== 'active') { + throw new Error2( + ErrorCodes.GOAL_STATUS_INVALID, + `Cannot pause a goal in status "${state.status}"`, + ); + } + return this.applyLifecycle(state, 'paused', input.reason, actor); + } + + async pauseActiveGoal( + input: GoalReasonInput = {}, + actor: GoalActor = 'runtime', + ): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + const state = this.goalState; + if (state === null || state.status !== 'active') return null; + return this.applyLifecycle(state, 'paused', input.reason, actor); + } + + async resumeGoal(input: ResumeGoalInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { + this.assertSupportedAgent(); + const state = this.requireState(); + if (state.status === 'active') return this.toSnapshot(state); + if (state.status !== 'paused' && state.status !== 'blocked') { + throw new Error2( + ErrorCodes.GOAL_NOT_RESUMABLE, + `Cannot resume a goal in status "${state.status}"`, + ); + } + const continuePaused = + actor === 'user' && state.status === 'paused' && input.continueIfPaused === true; + const shouldContinue = + continuePaused || + (actor === 'user' && state.status === 'blocked' && input.continueIfBlocked === true); + const snapshot = this.applyLifecycle(state, 'active', input.reason, actor); + if (!shouldContinue) return snapshot; + const budgetBlocked = this.blockIfBudgetReached(this.requireState()); + if (budgetBlocked !== null) return budgetBlocked; + if (this.canLaunchContinuation()) { + try { + this.launchContinuationTurn(state.goalId); + } catch (error) { + await this.settleGoalAfterContinuationFailure(error, state.goalId); + throw error; + } + } else if (continuePaused && this.liveTurnId !== undefined) { + this.resumeContinuation = { turnId: this.liveTurnId, goalId: state.goalId }; + } + return snapshot; + } + + async setBudgetLimits( + input: { readonly budgetLimits: GoalBudgetLimits }, + actor: GoalActor = 'user', + ): Promise<GoalSnapshot> { + this.assertSupportedAgent(); + const state = this.requireState(); + const budgetLimits = { ...state.budgetLimits, ...input.budgetLimits }; + this.wire.dispatch(updateGoal({ budgetLimits })); + const next = this.requireState(); + this.emitGoalUpdated(this.toSnapshot(next)); + this.telemetry.track2('goal_budget_set', { + actor, + ...budgetTelemetryProperties(input.budgetLimits), + }); + const blocked = this.blockIfBudgetReached(next); + if (blocked !== null) return blocked; + this.refreshWallClockDeadline(next); + return this.toSnapshot(next); + } + + async cancelGoal(_input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { + this.assertSupportedAgent(); + const state = this.requireState(); + const snapshot = this.toSnapshot(state); + if (state.status === 'active' && this.liveTurnId !== undefined) { + this.loopService.cancel(this.liveTurnId, abortError('Goal cancelled')); + } + this.clearInternal(actor); + if (actor === 'user') { + this.reminders.appendSystemReminder(GOAL_CANCELLED_REMINDER, { + kind: 'system_trigger', + name: 'goal_cancelled', + }); + } + return snapshot; + } + + async markBlocked( + input: GoalReasonInput = {}, + actor: GoalActor = 'runtime', + ): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + const state = this.goalState; + if (state === null || state.status !== 'active') return null; + const snapshot = this.applyLifecycle(state, 'blocked', input.reason, actor, { + preserveLiveContinuation: true, + }); + return snapshot; + } + + async markComplete( + input: GoalReasonInput = {}, + actor: GoalActor = 'model', + ): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + const state = this.goalState; + if (state === null || state.status !== 'active') return null; + this.dispatchCompletion(state, input.reason, actor); + const completed = this.requireState(); + const snapshot = this.toSnapshot(completed); + this.emitCompletion(completed, snapshot, input.reason, actor); + this.trackStatusChanged(completed, actor); + this.clearInternal(actor, { preserveLiveContinuation: true }); + return snapshot; + } + + private dispatchCompletion(state: GoalState, reason: string | undefined, actor: GoalActor): void { + const wallClockMs = this.settleWallClock(state); + this.wire.dispatch(updateGoal({ status: 'complete', reason, wallClockMs, actor })); + } + + private emitCompletion( + state: GoalState, + snapshot: GoalSnapshot, + reason: string | undefined, + actor: GoalActor, + ): void { + this.emitGoalUpdated(snapshot, { + kind: 'completion', + status: 'complete', + reason, + stats: this.statsOf(state), + actor, + }); + } + + async pauseOnInterrupt(input: GoalReasonInput = {}): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + return this.pauseActiveGoal(input, 'user'); + } + + async recordTokenUsage(tokenDelta: number): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + return this.accountTokenUsage(tokenDelta); + } + + private accountTokenUsage(tokenDelta: number, goalId?: string): GoalSnapshot | null { + const state = this.goalState; + if (state === null || state.status !== 'active' || !matchesGoal(state, goalId)) return null; + const tokensUsed = state.tokensUsed + Math.max(0, tokenDelta); + this.wire.dispatch(updateGoal({ tokensUsed })); + const next = this.requireState(); + return this.blockIfBudgetReached(next) ?? this.toSnapshot(next); + } + + async incrementTurn(): Promise<GoalSnapshot | null> { + this.assertSupportedAgent(); + return this.incrementGoalTurn(); + } + + private incrementGoalTurn(goalId?: string): GoalSnapshot | null { + const state = this.goalState; + if (state === null || state.status !== 'active' || !matchesGoal(state, goalId)) return null; + const turnsUsed = state.turnsUsed + 1; + this.wire.dispatch(updateGoal({ turnsUsed })); + const next = this.requireState(); + this.emitGoalUpdated(this.toSnapshot(next)); + this.telemetry.track2('goal_continued', { turns_used: next.turnsUsed }); + return this.toSnapshot(next); + } + + private handleTurnLaunched(turnId: number, origin: TurnStartedEvent['origin']): void { + this.liveTurnId = turnId; + this.goalTurnTargets.delete(turnId); + this.exhaustedTurnBudgetGoals.delete(turnId); + if (!this.goalDrivenTurns.has(turnId)) { + const state = this.goalState; + const continuationGoalId = isGoalContinuationOrigin(origin) + ? this.pendingContinuationGoals.get(turnId) + : undefined; + if (continuationGoalId !== undefined && state?.goalId !== continuationGoalId) { + this.goalDrivenTurns.set(turnId, continuationGoalId); + } else if (state?.status === 'active' && this.blockIfBudgetReached(state) === null) { + this.goalDrivenTurns.set(turnId, state.goalId); + } + } + this.pendingContinuationGoals.delete(turnId); + this.goalOutcomeToolResultTurns.delete(turnId); + this.goalOutcomeContinuationTurns.delete(turnId); + } + + private adoptStarterTurn(actor: GoalActor): void { + const turnId = this.liveTurnId; + if (turnId === undefined) return; + const state = this.goalState; + if (state === null || state.status !== 'active') return; + const goalId = this.goalDrivenTurns.get(turnId); + if (actor === 'model') this.goalTurnTargets.set(turnId, state.goalId); + if (this.toSnapshot(state).budget.turnBudgetReached) { + this.exhaustedTurnBudgetGoals.set(turnId, state.goalId); + } else { + this.exhaustedTurnBudgetGoals.delete(turnId); + } + if (goalId !== undefined) return; + this.goalDrivenTurns.set(turnId, state.goalId); + this.countedGoalTurns.add(turnId); + this.goalStarterTurns.add(turnId); + } + + private async handleBeforeStep(ctx: BeforeStepContext): Promise<void> { + const goalId = this.goalDrivenTurns.get(ctx.turnId); + if (goalId === undefined) return; + if (this.countedGoalTurns.has(ctx.turnId)) return; + this.countedGoalTurns.add(ctx.turnId); + this.incrementGoalTurn(goalId); + } + + private handleUsageRecorded(ctx: UsageRecordedContext): void { + const source = ctx.source; + if (source?.type !== 'turn') return; + const goalId = this.goalDrivenTurns.get(source.turnId); + if (goalId === undefined) return; + this.accountTokenUsage(ctx.usage.output, goalId); + } + + private handleAfterStep(ctx: AfterStepContext): void { + if (this.stopAfterBudgetReached(ctx)) return; + this.enqueueGoalOutcomeContinuation(ctx); + } + + private stopAfterBudgetReached(ctx: AfterStepContext): boolean { + const goalId = this.goalTurnTarget(ctx.turnId); + const state = this.goalState; + const budget = state === null ? null : this.toSnapshot(state).budget; + const turnBudgetBlocksCurrentTurn = + budget?.turnBudgetReached === true && + (this.exhaustedTurnBudgetGoals.get(ctx.turnId) === goalId || + (state?.status === 'blocked' && + state.terminalReason?.startsWith(GOAL_BUDGET_BLOCK_PREFIX) === true)); + if ( + goalId === undefined || + state === null || + state.goalId !== goalId || + budget === null || + (!budget.tokenBudgetReached && + !budget.wallClockBudgetReached && + !turnBudgetBlocksCurrentTurn) + ) { + return false; + } + const maxSteps = this.config.get<LoopControl>(LOOP_CONTROL_SECTION)?.maxStepsPerTurn; + if ( + ctx.finishReason === 'tool_calls' && + !this.budgetGraceTurns.has(ctx.turnId) && + hasStepBudgetRemaining(maxSteps, ctx.step) + ) { + this.budgetGraceTurns.add(ctx.turnId); + this.reminders.appendSystemReminder(GOAL_BUDGET_STOP_REMINDER, { + kind: 'system_trigger', + name: GOAL_BUDGET_STOP_REMINDER_NAME, + }); + return true; + } + ctx.stopTurn = true; + return true; + } + + private enqueueGoalOutcomeContinuation(ctx: AfterStepContext): void { + if (this.goalOutcomeContinuationTurns.has(ctx.turnId)) return; + const goalId = this.goalTurnTarget(ctx.turnId); + const outcomeGoalId = this.goalOutcomeToolResultTurns.get(ctx.turnId); + this.goalOutcomeToolResultTurns.delete(ctx.turnId); + if (goalId === undefined || outcomeGoalId !== goalId) return; + const state = this.goalState; + if (state !== null && state.goalId !== goalId) return; + this.goalOutcomeContinuationTurns.add(ctx.turnId); + const maxSteps = this.config.get<LoopControl>(LOOP_CONTROL_SECTION)?.maxStepsPerTurn; + if (!hasStepBudgetRemaining(maxSteps, ctx.step)) return; + this.loopService.enqueue(new ContinuationStepRequest()); + } + + private async handleTurnEnded( + turnId: number, + result: Pick<TurnEndedEvent, 'reason' | 'error'>, + ): Promise<void> { + const { goalId, lifecycleGoalId, starterTurn } = this.clearTurnTracking(turnId); + const resumeContinuation = this.resumeContinuation; + if (resumeContinuation?.turnId === turnId) this.resumeContinuation = undefined; + if (resumeContinuation?.turnId === turnId && result.reason === 'cancelled') { + const state = this.goalState; + if (state === null || state.status !== 'active' || state.goalId !== resumeContinuation.goalId) { + return; + } + if (this.blockIfBudgetReached(state) !== null) return; + this.launchContinuationTurn(resumeContinuation.goalId); + return; + } + if (goalId === undefined || lifecycleGoalId === undefined) return; + const stepCapped = isMaxStepsTurnFailure(result); + if ( + !stepCapped && + (result.reason === 'blocked' || + result.reason === 'cancelled' || + result.reason === 'failed') + ) { + await this.settleAbnormalTurn(result, lifecycleGoalId); + return; + } + if (starterTurn) this.incrementGoalTurn(goalId); + + const state = this.goalState; + if (state === null || state.status !== 'active' || state.goalId !== lifecycleGoalId) return; + if (this.blockIfBudgetReached(state) !== null) return; + this.launchContinuationTurn(lifecycleGoalId, stepCapped); + } + + private clearTurnTracking( + turnId: number, + ): { + readonly goalId?: string; + readonly lifecycleGoalId?: string; + readonly starterTurn: boolean; + } { + if (this.pendingContinuation?.turnId === turnId) this.pendingContinuation = undefined; + if (this.liveTurnId === turnId) this.liveTurnId = undefined; + const goalId = this.goalDrivenTurns.get(turnId); + const lifecycleGoalId = this.goalTurnTarget(turnId); + const starterTurn = this.goalStarterTurns.delete(turnId); + this.goalDrivenTurns.delete(turnId); + this.countedGoalTurns.delete(turnId); + this.goalOutcomeToolResultTurns.delete(turnId); + this.goalOutcomeContinuationTurns.delete(turnId); + this.budgetGraceTurns.delete(turnId); + this.pendingContinuationGoals.delete(turnId); + this.goalTurnTargets.delete(turnId); + this.exhaustedTurnBudgetGoals.delete(turnId); + return { goalId, lifecycleGoalId, starterTurn }; + } + + private async settleAbnormalTurn( + result: Pick<TurnEndedEvent, 'reason' | 'error'>, + goalId: string, + ): Promise<boolean> { + if (!this.isActiveGoal(goalId)) return false; + if (result.reason === 'blocked') { + await this.markBlocked({ reason: 'Blocked by UserPromptSubmit hook' }); + return true; + } + if (result.reason === 'cancelled') { + await this.pauseOnInterrupt({ reason: 'Paused after interruption' }); + return true; + } + if (result.reason === 'failed') { + await this.pauseActiveGoal({ reason: goalFailurePauseReason(result.error) }); + return true; + } + return false; + } + + private async settleGoalAfterContinuationFailure( + error: unknown, + goalId: string | undefined, + ): Promise<void> { + if (goalId === undefined || !this.isActiveGoal(goalId)) return; + try { + const reason = pauseReasonWithMessage( + GOAL_CONTINUATION_FAILURE_PAUSE_PREFIX, + normalizeGoalErrorPayload(error).message, + ); + await this.pauseActiveGoal({ reason }, 'system'); + } catch {} + } + + private launchContinuationTurn(goalId: string, stepCapped = false): void { + if (!this.isActiveGoal(goalId)) return; + if (this.pendingContinuation !== undefined) return; + const message: ContextMessage = { + role: 'user', + content: [ + { + type: 'text', + text: stepCapped ? GOAL_STEP_CAP_CONTINUATION_PROMPT : GOAL_CONTINUATION_PROMPT, + }, + ], + toolCalls: [], + origin: GOAL_CONTINUATION_ORIGIN, + }; + const request = new MessageStepRequest(message, { + kind: 'goal_continuation', + admission: 'newTurn', + }); + const receipt = this.loopService.enqueue(request); + const pending: PendingContinuation = { receipt, goalId }; + this.pendingContinuation = pending; + void receipt.assigned + .then(({ turn }) => { + pending.turnId = turn.id; + if (!this.goalDrivenTurns.has(turn.id)) { + this.pendingContinuationGoals.set(turn.id, pending.goalId); + } + return turn.result; + }) + .finally(() => { + if (pending.turnId !== undefined) this.pendingContinuationGoals.delete(pending.turnId); + if (this.pendingContinuation === pending) this.pendingContinuation = undefined; + }); + } + + private canLaunchContinuation(): boolean { + if (this.liveTurnId !== undefined || this.pendingContinuation !== undefined) return false; + const status = this.loopService.status(); + return status.state === 'idle' && !status.hasPendingRequests; + } + + private isActiveGoal(goalId: string): boolean { + const state = this.goalState; + return state?.status === 'active' && state.goalId === goalId; + } + + private isStaleGoalToolCall(ctx: BeforeToolExecuteEvent): boolean { + const toolName = ctx.toolCall.name; + if (!isGoalMutationTool(toolName)) return false; + const goalId = this.goalTurnTarget(ctx.turnId); + if (goalId === undefined) return false; + return this.goalState?.goalId !== goalId; + } + + private goalTurnTarget(turnId: number): string | undefined { + return this.goalTurnTargets.get(turnId) ?? this.goalDrivenTurns.get(turnId); + } + + private cancelPendingContinuation( + preserveLiveContinuation = false, + reason?: unknown, + ): void { + const pending = this.pendingContinuation; + if (preserveLiveContinuation && pending?.turnId === this.liveTurnId) return; + this.pendingContinuation = undefined; + const cancellation = reason ?? abortError('Goal continuation cancelled'); + const aborted = pending?.receipt.abort(cancellation); + if (pending !== undefined && !aborted && pending.turnId !== undefined) { + this.loopService.cancel(pending.turnId, cancellation); + } + } + + private normalizeAfterReplay(): void { + this.appendForkClearedReminder(); + this.wallClockDeadline.clear(); + this.liveWallClockStartedAt = undefined; + const state = this.goalState; + if (state === null) return; + if (state.status === 'complete') { + this.clearInternal('runtime', { emit: false, track: false }); + return; + } + if (state.status !== 'active') return; + + const reason = 'Paused after agent resume'; + this.wire.dispatch( + updateGoal({ + status: 'paused', + reason, + wallClockMs: this.settleWallClock(state), + actor: 'runtime', + }), + ); + this.trackStatusChanged(this.requireState(), 'runtime'); + } + + private appendForkClearedReminder(): void { + if (!this.wire.getModel(GoalForkNoticeModel).reminderPending) return; + this.reminders.appendSystemReminder(GOAL_FORK_CLEARED_REMINDER, { + kind: 'system_trigger', + name: GOAL_FORK_CLEARED_REMINDER_NAME, + }); + } + + private clearInternal( + actor: GoalActor, + opts: { readonly emit?: boolean; readonly track?: boolean; readonly preserveLiveContinuation?: boolean } = {}, + ): void { + if (this.goalState === null) return; + this.resumeContinuation = undefined; + this.cancelPendingContinuation(opts.preserveLiveContinuation === true); + this.wallClockDeadline.clear(); + this.liveWallClockStartedAt = undefined; + this.wire.dispatch(clearGoal({})); + if (opts.emit !== false) this.emitGoalUpdated(null); + if (opts.track !== false) this.telemetry.track2('goal_cleared', { actor }); + } + + private applyLifecycle( + state: GoalState, + status: GoalStatus, + reason: string | undefined, + actor: GoalActor, + opts: { + readonly preserveLiveContinuation?: boolean; + readonly cancellationReason?: unknown; + } = {}, + ): GoalSnapshot { + const wallClockMs = this.settleWallClock(state); + const wallClockResumedAt = status === 'active' ? Date.now() : undefined; + if (status === 'active') { + this.liveWallClockStartedAt = this.deadlineScheduler.now(); + } else if (state.status === 'active') { + this.resumeContinuation = undefined; + this.cancelPendingContinuation( + opts.preserveLiveContinuation === true, + opts.cancellationReason, + ); + this.wallClockDeadline.clear(); + this.liveWallClockStartedAt = undefined; + } + this.wire.dispatch( + updateGoal({ status, reason, wallClockMs, wallClockResumedAt, actor }), + ); + const next = this.requireState(); + if (status === 'active') this.adoptStarterTurn(actor); + if (status === 'active') this.refreshWallClockDeadline(next); + this.emitGoalUpdated(this.toSnapshot(next), { kind: 'lifecycle', status, reason, actor }); + this.trackStatusChanged(next, actor); + return this.toSnapshot(next); + } + + private trackStatusChanged(state: GoalState, actor: GoalActor): void { + this.telemetry.track2('goal_status_changed', { + actor, + status: state.status, + turns_used: state.turnsUsed, + tokens_used: state.tokensUsed, + wall_clock_ms: this.liveWallClockMs(state), + ...budgetTelemetryProperties(state.budgetLimits), + }); + } + + private requireState(): GoalState { + const state = this.goalState; + if (state === null) { + throw new Error2(ErrorCodes.GOAL_NOT_FOUND, 'No current goal'); + } + return state; + } + + private emitGoalUpdated(snapshot: GoalSnapshot | null, change?: GoalChange): void { + this.eventBus.publish({ type: 'goal.updated', snapshot, change }); + } + + private settleWallClock(state: GoalState): number { + if (state.status === 'active' && this.liveWallClockStartedAt !== undefined) { + return ( + state.wallClockMs + + Math.max(0, this.deadlineScheduler.now() - this.liveWallClockStartedAt) + ); + } + if (state.status === 'active' && state.wallClockResumedAt !== undefined) { + return state.wallClockMs + Math.max(0, Date.now() - state.wallClockResumedAt); + } + return state.wallClockMs; + } + + private liveWallClockMs(state: GoalState): number { + if (state.status === 'active' && this.liveWallClockStartedAt !== undefined) { + return ( + state.wallClockMs + + Math.max(0, this.deadlineScheduler.now() - this.liveWallClockStartedAt) + ); + } + if (state.status === 'active' && state.wallClockResumedAt !== undefined) { + return state.wallClockMs + Math.max(0, Date.now() - state.wallClockResumedAt); + } + return state.wallClockMs; + } + + private statsOf(state: GoalState): GoalChangeStats { + return { + turnsUsed: state.turnsUsed, + tokensUsed: state.tokensUsed, + wallClockMs: this.liveWallClockMs(state), + }; + } + + private toSnapshot(state: GoalState): GoalSnapshot { + const wallClockMs = this.liveWallClockMs(state); + return { + goalId: state.goalId, + objective: state.objective, + completionCriterion: state.completionCriterion, + status: state.status, + turnsUsed: state.turnsUsed, + tokensUsed: state.tokensUsed, + wallClockMs, + budget: computeBudgetReport(state, wallClockMs), + terminalReason: state.terminalReason, + }; + } + + private blockIfBudgetReached(state: GoalState): GoalSnapshot | null { + if (state.status !== 'active') return null; + const reason = goalBudgetBlockReason(this.toSnapshot(state).budget); + if (reason === undefined) return null; + return this.applyLifecycle(state, 'blocked', reason, 'runtime', { + preserveLiveContinuation: true, + }); + } + + private refreshWallClockDeadline(state: GoalState): void { + this.wallClockDeadline.clear(); + const budgetMs = state.budgetLimits.wallClockBudgetMs; + if ( + state.status !== 'active' || + budgetMs === undefined || + this.liveWallClockStartedAt === undefined + ) { + return; + } + const remainingMs = Math.max(0, budgetMs - this.liveWallClockMs(state)); + this.wallClockDeadline.value = this.deadlineScheduler.schedule(remainingMs, () => { + this.handleWallClockDeadline(); + }); + } + + private handleWallClockDeadline(): void { + this.wallClockDeadline.clear(); + const state = this.goalState; + if (state === null || state.status !== 'active') return; + const budgetMs = state.budgetLimits.wallClockBudgetMs; + if (budgetMs === undefined) return; + if (this.liveWallClockMs(state) < budgetMs) { + this.refreshWallClockDeadline(state); + return; + } + const reason = goalBudgetBlockReason(this.toSnapshot(state).budget); + if (reason === undefined) return; + const cancellation = abortError(reason); + const liveTurnId = this.liveTurnId; + const pendingTurnId = this.pendingContinuation?.turnId; + this.applyLifecycle(state, 'blocked', reason, 'runtime', { + cancellationReason: cancellation, + }); + if (liveTurnId !== undefined && liveTurnId !== pendingTurnId) { + this.loopService.cancel(liveTurnId, cancellation); + } + } +} + +function computeBudgetReport(state: GoalState, wallClockMs: number): GoalBudgetReport { + const tokenBudget = state.budgetLimits.tokenBudget ?? null; + const turnBudget = state.budgetLimits.turnBudget ?? null; + const wallClockBudgetMs = state.budgetLimits.wallClockBudgetMs ?? null; + + const tokenBudgetReached = tokenBudget !== null && state.tokensUsed >= tokenBudget; + const turnBudgetReached = turnBudget !== null && state.turnsUsed >= turnBudget; + const wallClockBudgetReached = wallClockBudgetMs !== null && wallClockMs >= wallClockBudgetMs; + + return { + tokenBudget, + turnBudget, + wallClockBudgetMs, + remainingTokens: tokenBudget === null ? null : Math.max(0, tokenBudget - state.tokensUsed), + remainingTurns: turnBudget === null ? null : Math.max(0, turnBudget - state.turnsUsed), + remainingWallClockMs: + wallClockBudgetMs === null ? null : Math.max(0, wallClockBudgetMs - wallClockMs), + tokenBudgetReached, + turnBudgetReached, + wallClockBudgetReached, + overBudget: tokenBudgetReached || turnBudgetReached || wallClockBudgetReached, + }; +} + +function matchesGoal(state: GoalState, goalId: string | undefined): boolean { + return goalId === undefined || state.goalId === goalId; +} + +function isGoalMutationTool(toolName: string): boolean { + return toolName === 'CreateGoal' || toolName === 'UpdateGoal' || toolName === 'SetGoalBudget'; +} + +function toGoalStartReviewPermissionMode(label: string | undefined): PermissionMode | undefined { + if (label === 'auto' || label === 'yolo' || label === 'manual') return label; + return undefined; +} + +function goalBudgetBlockReason(budget: GoalBudgetReport): string | undefined { + const reached: string[] = []; + if (budget.turnBudgetReached) { + reached.push(`turn budget ${budget.turnBudget ?? ''}`.trim()); + } + if (budget.tokenBudgetReached) { + reached.push(`token budget ${budget.tokenBudget ?? ''}`.trim()); + } + if (budget.wallClockBudgetReached) { + reached.push(`wall-clock budget ${budget.wallClockBudgetMs ?? ''}ms`.trim()); + } + return reached.length === 0 ? undefined : `${GOAL_BUDGET_BLOCK_PREFIX}: ${reached.join(', ')}`; +} + +function budgetTelemetryProperties(limits: GoalBudgetLimits): GoalBudgetProperties { + return { + has_token_budget: limits.tokenBudget !== undefined, + has_turn_budget: limits.turnBudget !== undefined, + has_wall_clock_budget: limits.wallClockBudgetMs !== undefined, + }; +} + +function normalizeCompletionCriterion(value: string | undefined): string | undefined { + const trimmed = value?.trim(); + if (!trimmed?.length) return undefined; + return trimmed.length > MAX_GOAL_COMPLETION_CRITERION_LENGTH + ? trimmed.slice(0, MAX_GOAL_COMPLETION_CRITERION_LENGTH) + : trimmed; +} + +function hasStepBudgetRemaining(maxSteps: number | undefined, currentStep: number): boolean { + return maxSteps === undefined || maxSteps <= 0 || currentStep < maxSteps; +} + +function isTerminalUpdateGoalResult( + toolName: string, + args: unknown, + result: ExecutableToolResult, +): boolean { + if (toolName !== 'UpdateGoal' || result.isError === true || result.stopTurn !== true) { + return false; + } + if (!isPlainRecord(args)) return false; + const status = args['status']; + return status === 'complete' || status === 'blocked'; +} + +function isMaxStepsTurnFailure(result: Pick<TurnEndedEvent, 'reason' | 'error'>): boolean { + return ( + result.reason === 'failed' && + normalizeGoalErrorPayload(result.error).code === LoopErrors.codes.LOOP_MAX_STEPS_EXCEEDED + ); +} + +function goalFailurePauseReason(error: unknown): string { + const payload = normalizeGoalErrorPayload(error); + switch (payload.code) { + case ErrorCodes.PROVIDER_RATE_LIMIT: + return GOAL_RATE_LIMIT_PAUSE_REASON; + case ErrorCodes.PROVIDER_CONNECTION_ERROR: + return pauseReasonWithMessage(GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, payload.message); + case ErrorCodes.PROVIDER_AUTH_ERROR: + return pauseReasonWithMessage(GOAL_PROVIDER_AUTH_PAUSE_PREFIX, payload.message); + case ErrorCodes.PROVIDER_FILTERED: + return GOAL_PROVIDER_FILTERED_PAUSE_REASON; + case ErrorCodes.PROVIDER_API_ERROR: + return pauseReasonWithMessage(GOAL_PROVIDER_API_PAUSE_PREFIX, payload.message); + case ErrorCodes.MODEL_NOT_CONFIGURED: + return pauseReasonWithMessage(GOAL_MODEL_CONFIG_PAUSE_PREFIX, LLM_NOT_SET_MESSAGE); + case ErrorCodes.MODEL_CONFIG_INVALID: + return pauseReasonWithMessage(GOAL_MODEL_CONFIG_PAUSE_PREFIX, payload.message); + default: + return pauseReasonWithMessage(GOAL_RUNTIME_PAUSE_PREFIX, payload.message); + } +} + +function normalizeGoalErrorPayload(error: unknown): KimiErrorPayload { + const payload = toKimiErrorPayload(error); + if (payload.code === ErrorCodes.MODEL_NOT_CONFIGURED) { + return { ...payload, message: LLM_NOT_SET_MESSAGE }; + } + return payload; +} + +function pauseReasonWithMessage(prefix: string, message: string | undefined): string { + const trimmed = message?.trim(); + return trimmed === undefined || trimmed.length === 0 ? prefix : `${prefix}: ${trimmed}`; +} + +registerScopedService( + LifecycleScope.Agent, + IAgentGoalService, + AgentGoalService, + ScopeActivation.OnScopeCreated, + 'goal', +); diff --git a/packages/agent-core-v2/src/features/goal/injection/goal-active-reminder.md b/packages/agent-core-v2/src/agent/goal/injection/goal-active-reminder.md similarity index 99% rename from packages/agent-core-v2/src/features/goal/injection/goal-active-reminder.md rename to packages/agent-core-v2/src/agent/goal/injection/goal-active-reminder.md index a15375571..527367f56 100644 --- a/packages/agent-core-v2/src/features/goal/injection/goal-active-reminder.md +++ b/packages/agent-core-v2/src/agent/goal/injection/goal-active-reminder.md @@ -11,4 +11,4 @@ ${budgets_block}${budget_guidance} Before doing any goal work, check the objective and latest request for a clear hard budget limit. If one is present and the current goal does not already record that limit, call SetGoalBudget first. Do not invent budgets. If a requested budget is not reasonable, do not set it; tell the user it is not reasonable. -Goal mode is iterative. Keep the self-audit brief each turn. Do not explore unrelated interpretations once the goal can be decided. If the objective is simple, already answered, impossible, unsafe, or contradictory, do not run another goal turn. Explain briefly if useful, then call UpdateGoal with `complete` or `blocked` in the same turn. Otherwise, choose one bounded, useful slice of work toward the objective. Do not try to finish a broad goal in one turn unless the whole goal is genuinely small. Most goal turns should not call UpdateGoal: after completing a useful slice, if material work remains, end the turn normally without calling UpdateGoal so the runtime can continue the goal in the next turn. Call UpdateGoal with `complete` only when all required work is done, any stated validation has passed, and there is no useful next action. Completion audit: before calling `complete`, verify the current state against the actual objective and every explicit requirement. Treat weak or indirect evidence as not complete. Do not mark complete after only producing a plan, summary, first pass, or partial result. Do not mark complete merely because a budget is nearly exhausted or you want to stop. Blocked audit: do not call UpdateGoal with `blocked` the first time you hit a blocker. Use `blocked` only for a genuine impasse: an external condition, required user input, missing credentials or permissions, or a persistent technical failure. For those non-terminal blockers, the same blocking condition must repeat for at least 3 consecutive goal turns before you call `blocked`, counting the original/user-triggered turn and automatic continuations. If a previously blocked goal is resumed, treat the resumed run as a fresh blocked audit. Exception: if the objective itself is impossible, unsafe, or contradictory, call UpdateGoal with `blocked` in the same turn; do not run more goal turns just to satisfy the audit. Do not use `blocked` because the work is large, hard, slow, uncertain, incomplete, still needs validation, would benefit from clarification, or needs more goal turns. Once the 3-turn threshold is met and you cannot make meaningful progress without user input or an external-state change, call UpdateGoal with `blocked`; do not keep reporting the blocker while leaving the goal active.${wait_for_guidance} +Goal mode is iterative. Keep the self-audit brief each turn. Do not explore unrelated interpretations once the goal can be decided. If the objective is simple, already answered, impossible, unsafe, or contradictory, do not run another goal turn. Explain briefly if useful, then call UpdateGoal with `complete` or `blocked` in the same turn. Otherwise, choose one bounded, useful slice of work toward the objective. Do not try to finish a broad goal in one turn unless the whole goal is genuinely small. Most goal turns should not call UpdateGoal: after completing a useful slice, if material work remains, end the turn normally without calling UpdateGoal so the runtime can continue the goal in the next turn. Call UpdateGoal with `complete` only when all required work is done, any stated validation has passed, and there is no useful next action. Completion audit: before calling `complete`, verify the current state against the actual objective and every explicit requirement. Treat weak or indirect evidence as not complete. Do not mark complete after only producing a plan, summary, first pass, or partial result. Do not mark complete merely because a budget is nearly exhausted or you want to stop. Blocked audit: do not call UpdateGoal with `blocked` the first time you hit a blocker. Use `blocked` only for a genuine impasse: an external condition, required user input, missing credentials or permissions, or a persistent technical failure. For those non-terminal blockers, the same blocking condition must repeat for at least 3 consecutive goal turns before you call `blocked`, counting the original/user-triggered turn and automatic continuations. If a previously blocked goal is resumed, treat the resumed run as a fresh blocked audit. Exception: if the objective itself is impossible, unsafe, or contradictory, call UpdateGoal with `blocked` in the same turn; do not run more goal turns just to satisfy the audit. Do not use `blocked` because the work is large, hard, slow, uncertain, incomplete, still needs validation, would benefit from clarification, or needs more goal turns. Once the 3-turn threshold is met and you cannot make meaningful progress without user input or an external-state change, call UpdateGoal with `blocked`; do not keep reporting the blocker while leaving the goal active. diff --git a/packages/agent-core-v2/src/features/goal/injection/goal-blocked-reminder.md b/packages/agent-core-v2/src/agent/goal/injection/goal-blocked-reminder.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/injection/goal-blocked-reminder.md rename to packages/agent-core-v2/src/agent/goal/injection/goal-blocked-reminder.md diff --git a/packages/agent-core-v2/src/features/goal/injection/goal-paused-reminder.md b/packages/agent-core-v2/src/agent/goal/injection/goal-paused-reminder.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/injection/goal-paused-reminder.md rename to packages/agent-core-v2/src/agent/goal/injection/goal-paused-reminder.md diff --git a/packages/agent-core-v2/src/features/goal/injection/goalInjection.ts b/packages/agent-core-v2/src/agent/goal/injection/goalInjection.ts similarity index 82% rename from packages/agent-core-v2/src/features/goal/injection/goalInjection.ts rename to packages/agent-core-v2/src/agent/goal/injection/goalInjection.ts index 2ded29fff..bc39fd260 100644 --- a/packages/agent-core-v2/src/features/goal/injection/goalInjection.ts +++ b/packages/agent-core-v2/src/agent/goal/injection/goalInjection.ts @@ -1,36 +1,30 @@ -import type { GoalSnapshot } from '#/features/goal/types'; +import type { GoalSnapshot } from '#/agent/goal/types'; import { Service } from "#/_base/di/service"; import { renderPrompt } from "#/_base/utils/render-prompt"; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import GOAL_ACTIVE_REMINDER from './goal-active-reminder.md?raw'; import GOAL_BLOCKED_REMINDER from './goal-blocked-reminder.md?raw'; import GOAL_PAUSED_REMINDER from './goal-paused-reminder.md?raw'; export interface GoalInjectionOptions { readonly getGoal: () => GoalSnapshot | null; - readonly isWaitForEnabled?: () => boolean; } -export const GOAL_WAIT_FOR_GUIDANCE = - 'If you are waiting for background sub-agents or bash tasks to finish, call WaitFor to wait for them inside this turn instead of ending the turn; ending the turn just gets you re-invoked again and again. You can also use the waiting time to do useful parallel work. Either way, make sure every goal turn is productive.'; - export class GoalInjection extends Service { constructor( private readonly options: GoalInjectionOptions, - injector: ReminderRuntime, + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, ) { super(); this._register( - injector.register('goal', ({ isNewTurn }) => (isNewTurn ? this.reminder() : undefined)), + dynamicInjector.register('goal', ({ isNewTurn }) => (isNewTurn ? this.reminder() : undefined)), ); } private reminder(): string | undefined { const goal = this.options.getGoal(); if (goal === null) return undefined; - if (goal.status === 'active') { - return buildGoalReminder(goal, this.options.isWaitForEnabled?.() === true); - } + if (goal.status === 'active') return buildGoalReminder(goal); if (goal.status === 'blocked') return buildBlockedNote(goal); if (goal.status === 'paused') return buildPausedNote(goal); return undefined; @@ -58,7 +52,7 @@ function buildPausedNote(goal: GoalSnapshot): string { }); } -function buildGoalReminder(goal: GoalSnapshot, waitForEnabled: boolean): string { +function buildGoalReminder(goal: GoalSnapshot): string { const budgets = formatBudgets(goal); return renderPrompt(GOAL_ACTIVE_REMINDER, { objective: escapeUntrustedText(goal.objective), @@ -67,7 +61,6 @@ function buildGoalReminder(goal: GoalSnapshot, waitForEnabled: boolean): string progress: `${goal.turnsUsed} continuation turns, ${goal.tokensUsed} tokens, ${formatElapsed(goal.wallClockMs)} elapsed`, budgets_block: budgets.length > 0 ? `Budgets: ${budgets}.\n` : '', budget_guidance: isNearingBudget(goal) ? BUDGET_GUIDANCE_NEARING : BUDGET_GUIDANCE_WITHIN, - wait_for_guidance: waitForEnabled ? ` ${GOAL_WAIT_FOR_GUIDANCE}` : '', }); } diff --git a/packages/agent-core-v2/src/features/goal/tools/outcome-prompts.ts b/packages/agent-core-v2/src/agent/goal/tools/outcome-prompts.ts similarity index 97% rename from packages/agent-core-v2/src/features/goal/tools/outcome-prompts.ts rename to packages/agent-core-v2/src/agent/goal/tools/outcome-prompts.ts index 84957f3fe..9deb07b76 100644 --- a/packages/agent-core-v2/src/features/goal/tools/outcome-prompts.ts +++ b/packages/agent-core-v2/src/agent/goal/tools/outcome-prompts.ts @@ -1,4 +1,4 @@ -import type { GoalSnapshot } from '#/features/goal/types'; +import type { GoalSnapshot } from '#/agent/goal/types'; export function buildGoalCompletionSummaryPrompt(goal: GoalSnapshot): string { return [ diff --git a/packages/agent-core-v2/src/features/goal/tools/serialize.ts b/packages/agent-core-v2/src/agent/goal/tools/serialize.ts similarity index 81% rename from packages/agent-core-v2/src/features/goal/tools/serialize.ts rename to packages/agent-core-v2/src/agent/goal/tools/serialize.ts index 8325b2ceb..da40ab9c9 100644 --- a/packages/agent-core-v2/src/features/goal/tools/serialize.ts +++ b/packages/agent-core-v2/src/agent/goal/tools/serialize.ts @@ -1,4 +1,4 @@ -import type { GoalSnapshot, GoalToolResult } from '#/features/goal/types'; +import type { GoalSnapshot, GoalToolResult } from '#/agent/goal/types'; export function goalForModel(goal: GoalSnapshot): Omit<GoalSnapshot, 'goalId'> { const { goalId: _goalId, ...rest } = goal; diff --git a/packages/agent-core-v2/src/features/goal/types.ts b/packages/agent-core-v2/src/agent/goal/types.ts similarity index 95% rename from packages/agent-core-v2/src/features/goal/types.ts rename to packages/agent-core-v2/src/agent/goal/types.ts index 48d0e2de4..ea20af32b 100644 --- a/packages/agent-core-v2/src/features/goal/types.ts +++ b/packages/agent-core-v2/src/agent/goal/types.ts @@ -1,3 +1,7 @@ +/** + * `goal` domain — public goal lifecycle and budget models. + */ + export type GoalStatus = 'active' | 'paused' | 'blocked' | 'complete'; export type GoalActor = 'user' | 'model' | 'runtime' | 'system'; diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts index 5dfb78d60..619accfcf 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminder.ts @@ -1,3 +1,10 @@ +/** + * `interruptionReminder` domain (L4) — user-interruption reminder contract. + * + * Defines the Agent-scoped aspect that records a model-visible reminder after + * a user-cancelled turn. Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; export interface IAgentInterruptionReminderService { diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts index 2ff8efcb7..0c7a39e13 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderOps.ts @@ -1,33 +1,43 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `interruptionReminder` domain (L4) — persists and restores pending + * user-interruption reminders. + * + * Projects the `loop` domain's `turn.cancel` fact into the set of turns whose + * interruption reminder still has to reach the conversation, and owns the op + * that records a reminder's delivery. Consumed by the Agent-scope + * `interruptionReminderService`. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; -export const INTERRUPTION_REMINDER_VARIANT = 'interruption'; - -export type InterruptionReminderState = null; - -const interruptionReminderRecordedSchema = z.object({ - agentId: z.string(), - turnId: z.number().int().nonnegative(), -}); - -export class InterruptionReminderRecorded extends AgentEvent2< - z.infer<typeof interruptionReminderRecordedSchema> -> { - static override readonly type = 'interruptionReminder.recorded'; - static override readonly durable = true; - static override readonly schema = interruptionReminderRecordedSchema; -} -export interface InterruptionReminderRecorded { - readonly agentId: string; - readonly turnId: number; -} - -export const interruptionReminderKey = defineState( +export const InterruptionReminderModel = defineModel<readonly number[]>( 'interruptionReminder', - (): InterruptionReminderState => null, -) - .replayable({ schema: z.custom<InterruptionReminderState>() }) - .on(InterruptionReminderRecorded, () => {}); + () => [], + { + reducers: { + 'turn.cancel': (state, { turnId, target, reason }) => { + if (target !== 'active' || reason !== 'user_cancelled' || turnId === undefined) { + return state; + } + if (state.includes(turnId)) return state; + return [...state, turnId].toSorted((a, b) => a - b); + }, + }, + }, +); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'interruptionReminder.recorded': typeof interruptionReminderRecorded; + } +} + +export const interruptionReminderRecorded = InterruptionReminderModel.defineOp( + 'interruptionReminder.recorded', + { + schema: z.object({ turnId: z.number().int().nonnegative() }), + apply: (state, { turnId }) => state.filter((pendingTurnId) => pendingTurnId !== turnId), + }, +); diff --git a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts index d5348bb69..e3dadecb0 100644 --- a/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts +++ b/packages/agent-core-v2/src/agent/interruptionReminder/interruptionReminderService.ts @@ -1,18 +1,26 @@ -import { Disposable } from '#/_base/di/lifecycle'; +/** + * `interruptionReminder` domain (L4) — `IAgentInterruptionReminderService` implementation. + * + * Observes turn completion through `event`, persists reminder completion through + * its own wire model, reads conversation history through `contextMemory`, and + * appends model-visible notices through `systemReminder`. Reconciles reminders + * left pending by an interrupted restore. Bound at Agent scope. + */ + +import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import type { ContextMessage } from '#/agent/contextMemory/types'; import { isVacuousContentPart } from '#/agent/contextMemory/vacuousContent'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentStateService } from '#/agent/state/agentState'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; import { IEventBus } from '#/app/event/eventBus'; +import { IWireService } from '#/wire/wire'; import { IAgentInterruptionReminderService } from './interruptionReminder'; -import { INTERRUPTION_REMINDER_VARIANT, interruptionReminderKey } from './interruptionReminderOps'; +import { interruptionReminderRecorded, InterruptionReminderModel } from './interruptionReminderOps'; + +export const INTERRUPTION_REMINDER_VARIANT = 'interruption'; const INTERRUPTION_REMINDER = [ 'The previous turn was interrupted by the user before completion;', @@ -21,7 +29,7 @@ const INTERRUPTION_REMINDER = [ ].join(' '); export class AgentInterruptionReminderService - extends Disposable + extends Service implements IAgentInterruptionReminderService { declare readonly _serviceBrand: undefined; @@ -29,28 +37,56 @@ export class AgentInterruptionReminderService constructor( @IEventBus eventBus: IEventBus, @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - @IAgentScopeContext scopeContext: IAgentScopeContext, - @IAgentStateService agentState: IAgentStateService, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, + @IWireService private readonly wire: IWireService, ) { super(); - agentState.contributeState(interruptionReminderKey); this._register( - eventBus.subscribe(TurnEnded, (event) => { + this.wire.hooks.onDidRestore.register('interruption-reminder', async (_ctx, next) => { + this.reconcilePendingReminders(); + await next(); + }), + ); + this._register( + eventBus.subscribe('turn.ended', (event) => { if (event.reason !== 'cancelled' || event.interruptReason !== 'user_cancelled') return; - const origin = lastComparableMessage(this.context.get())?.origin; - if (origin?.kind === 'injection' && origin.variant === INTERRUPTION_REMINDER_VARIANT) return; - agentLifecycle.resolve(scopeContext.agentContext, AgentReminder).notify(INTERRUPTION_REMINDER, { - variant: INTERRUPTION_REMINDER_VARIANT, - }); + this.recordReminder(event.turnId, true); }), ); } + + private reconcilePendingReminders(): void { + const pending = this.wire.getModel(InterruptionReminderModel); + for (const turnId of pending) this.recordReminder(turnId); + } + + private recordReminder(turnId: number, allowUntracked = false): void { + const pending = this.wire.getModel(InterruptionReminderModel).includes(turnId); + if (!pending && !allowUntracked) return; + if (!this.appendInterruptionReminder()) return; + if (pending) this.wire.dispatch(interruptionReminderRecorded({ turnId })); + } + + private appendInterruptionReminder(): boolean { + const before = this.context.get(); + const origin = lastDurableMessageOrigin(before); + if (origin?.kind === 'injection' && origin.variant === INTERRUPTION_REMINDER_VARIANT) return true; + this.reminders.appendSystemReminder(INTERRUPTION_REMINDER, { + kind: 'injection', + variant: INTERRUPTION_REMINDER_VARIANT, + }); + const after = this.context.get(); + if (after === before) return false; + const appended = lastDurableMessageOrigin(after); + return appended?.kind === 'injection' && appended.variant === INTERRUPTION_REMINDER_VARIANT; + } } -function lastComparableMessage(messages: readonly ContextMessage[]): ContextMessage | undefined { - for (let index = messages.length - 1; index >= 0; index--) { - const message = messages[index]!; +function lastDurableMessageOrigin( + messages: readonly ContextMessage[], +): ContextMessage['origin'] | undefined { + for (let i = messages.length - 1; i >= 0; i--) { + const message = messages[i]!; if ( message.role === 'assistant' && message.partial === true && @@ -59,7 +95,7 @@ function lastComparableMessage(messages: readonly ContextMessage[]): ContextMess ) { continue; } - return message; + return message.origin; } return undefined; } diff --git a/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts b/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts index 0f60cc009..4975c7063 100644 --- a/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts +++ b/packages/agent-core-v2/src/agent/llmRequester/llmRequestOps.ts @@ -1,9 +1,14 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `llmRequester` domain — durable request-trace wire Model and Ops. + * + * Defines `llm.tools_snapshot` snapshots and `llm.request` outbound request + * traces, with replay restoring only the snapshot de-dup cursor. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; import type { ThinkingEffort } from '#/kosong/contract/provider'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; export interface LlmRequestToolSchema { readonly name: string; @@ -15,93 +20,56 @@ export interface LlmRequestTraceState { readonly seenToolsHashes: readonly string[]; } +export const LlmRequestTraceModel = defineModel<LlmRequestTraceState>( + 'llm.requestTrace', + () => ({ seenToolsHashes: [] }), +); + const llmToolEntrySchema = z.object({ name: z.string(), description: z.string(), parameters: z.record(z.string(), z.unknown()), }); -const llmToolsSnapshotSchema = z.object({ - agentId: z.string(), - hash: z.string(), - tools: z.array(llmToolEntrySchema).readonly(), +declare module '#/wire/types' { + interface PersistedOpMap { + 'llm.tools_snapshot': typeof llmToolsSnapshot; + 'llm.request': typeof llmRequest; + } +} + +export const llmToolsSnapshot = LlmRequestTraceModel.defineOp('llm.tools_snapshot', { + schema: z.object({ + hash: z.string(), + tools: z.array(llmToolEntrySchema).readonly(), + }), + apply: (s, p) => { + if (s.seenToolsHashes.includes(p.hash)) return s; + return { seenToolsHashes: [...s.seenToolsHashes, p.hash] }; + }, }); -export class LlmToolsSnapshot extends AgentEvent2<z.infer<typeof llmToolsSnapshotSchema>> { - static override readonly type = 'llm.tools_snapshot'; - static override readonly durable = true; - static override readonly schema = llmToolsSnapshotSchema; -} -export interface LlmToolsSnapshot { - readonly agentId: string; - readonly hash: string; - readonly tools: readonly LlmRequestToolSchema[]; -} - -const llmRequestSchema = z.object({ - agentId: z.string(), - kind: z.enum(['loop', 'compaction']), - provider: z.string(), - model: z.string(), - modelAlias: z.string().optional(), - thinkingEffort: z.custom<ThinkingEffort>().optional(), - thinkingKeep: z.string().optional(), - temperature: z.number().optional(), - topP: z.number().optional(), - maxTokens: z.number().optional(), - betaApi: z.boolean().optional(), - toolSelect: z.boolean(), - systemPromptHash: z.string(), - systemPrompt: z.string().optional(), - toolsHash: z.string(), - messageCount: z.number(), - turnStep: z.string().optional(), - attempt: z.string().optional(), - projection: z.enum(['strict', 'media-degraded', 'media-stripped', 'strict-media-degraded', 'strict-media-stripped']).optional(), - droppedCount: z.number().optional(), +export const llmRequest = LlmRequestTraceModel.defineOp('llm.request', { + schema: z.object({ + kind: z.enum(['loop', 'compaction']), + provider: z.string(), + model: z.string(), + modelAlias: z.string().optional(), + thinkingEffort: z.custom<ThinkingEffort>().optional(), + thinkingKeep: z.string().optional(), + temperature: z.number().optional(), + topP: z.number().optional(), + maxTokens: z.number().optional(), + betaApi: z.boolean().optional(), + toolSelect: z.boolean(), + systemPromptHash: z.string(), + systemPrompt: z.string().optional(), + toolsHash: z.string(), + messageCount: z.number(), + turnStep: z.string().optional(), + attempt: z.string().optional(), + projection: z.enum(['strict', 'media-degraded', 'media-stripped']).optional(), + droppedCount: z.number().optional(), + }), + apply: (s) => s, }); - -export type LlmRequestPayload = z.infer<typeof llmRequestSchema>; - -export class LlmRequest extends AgentEvent2<LlmRequestPayload> { - static override readonly type = 'llm.request'; - static override readonly durable = true; - static override readonly schema = llmRequestSchema; -} -export interface LlmRequest { - readonly agentId: string; - readonly kind: 'loop' | 'compaction'; - readonly provider: string; - readonly model: string; - readonly modelAlias?: string; - readonly thinkingEffort?: ThinkingEffort; - readonly thinkingKeep?: string; - readonly temperature?: number; - readonly topP?: number; - readonly maxTokens?: number; - readonly betaApi?: boolean; - readonly toolSelect: boolean; - readonly systemPromptHash: string; - readonly systemPrompt?: string; - readonly toolsHash: string; - readonly messageCount: number; - readonly turnStep?: string; - readonly attempt?: string; - readonly projection?: - | 'strict' - | 'media-degraded' - | 'media-stripped' - | 'strict-media-degraded' - | 'strict-media-stripped'; - readonly droppedCount?: number; -} - -export const llmRequestTraceKey = defineState( - 'llm.requestTrace', - (): LlmRequestTraceState => ({ seenToolsHashes: [] }), -).replayable({ schema: z.custom<LlmRequestTraceState>() }) - .on(LlmToolsSnapshot, (s, e) => { - if (s.seenToolsHashes.includes(e.hash)) return; - s.seenToolsHashes = [...s.seenToolsHashes, e.hash]; - }) - .on(LlmRequest, () => {}); diff --git a/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts b/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts index 3cbe2176b..92339a83d 100644 --- a/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts +++ b/packages/agent-core-v2/src/agent/llmRequester/llmRequesterService.ts @@ -1,23 +1,53 @@ +/** + * `llmRequester` domain — `IAgentLLMRequesterService` implementation. + * + * Assembles per-turn `ModelRequestInput` from `profile` (system prompt), + * `contextMemory` + `contextProjector` (history), `toolRegistry` (tools), and + * `toolSelect` (progressive-disclosure shaping of the tool and history views), + * folds the completion-token budget into the profile's dialect-free intent + * params, then drives a bounded request chain through the `ModelRequester` + * resolved from `IModelCatalog`: one primary `requester.request(input, signal, + * params)` attempt plus projection rebuilds for request structure or media + * compatibility. Before each request the projected messages pass through `media`'s + * video resolver, which rewrites every `kimi-file://` prompt-video reference + * to a provider-acceptable part (uploaded `ms://`, inline base64, or a + * `<video path>` tag) so the internal reference never reaches the wire. When a + * model is configured, `prepareTurnConfig` snapshots the + * model, effective thinking effort, and system prompt at the turn boundary + * so loop telemetry and every request in that turn share one configuration. + * Forwards streamed `part` events to the caller's `onPart` + * handler, records `usage` through `IAgentUsageService`, resolves to an + * `AgentLLMRequestFinish` on the `finish` event, logs the request lifecycle + * (config deduplicated by content, request/response/failure lines, plus + * per-request fields) through `log`, publishes advisory model-capability + * warnings through `eventBus`, records durable request-trace Ops + * through `wire`, reports each request's `x-trace-id` to its caller, and + * reports provider failures through `telemetry`. The mutable request state + * (`lastConfigLogSignature`, `turnConfigs`, `mediaDegradedTurns`, + * `mediaStrippedTurns`, `emittedThinkingEffortWarnings`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it. Bound at + * Agent scope. + */ + import { createHash } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import { IAgentContextProjectorService, type MediaStripSnapshot, - type ProjectionPolicy, } from '#/agent/contextProjector/contextProjector'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; import { IAgentProfileService, type ProfileModelContext } from '#/agent/profile/profile'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { IAgentToolSelectService } from '#/agent/toolSelect/toolSelect'; -import { IAgentMediaResolverService } from '#/agent/media/mediaResolver'; -import { ISessionUsageService } from '#/session/usage/sessionUsage'; +import { IAgentVideoResolverService } from '#/agent/media/videoResolver'; +import { IAgentUsageService } from '#/agent/usage/usage'; import { IConfigService } from '#/app/config/config'; +import { IEventBus } from '#/app/event/eventBus'; import { - APIContextOverflowError, APIRequestTooLargeError, APIStatusError, classifyApiError, @@ -25,7 +55,7 @@ import { isRecoverableRequestStructureError, isRetryableGenerateError, } from '#/kosong/contract/errors'; -import { isToolCall, type Message, type StreamedMessagePart } from '#/kosong/contract/message'; +import { type Message } from '#/kosong/contract/message'; import { type ThinkingEffort } from '#/kosong/contract/provider'; import { type Tool } from '#/kosong/contract/tool'; import { emptyUsage, inputTotal, type TokenUsage } from '#/kosong/contract/usage'; @@ -46,9 +76,8 @@ import { THINKING_SECTION } from '#/app/kosongConfig/configSection'; import type { Protocol } from '#/kosong/protocol/protocol'; import type { ApiErrorEvent } from '#/app/telemetry/events'; import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { WarningIssued } from '#/agent/profile/profileOps'; +import { IWireService } from '#/wire/wire'; +import type { PayloadOf } from '#/wire/types'; import { IAgentLLMRequesterService, @@ -62,26 +91,14 @@ import { } from './llmRequester'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; import { - ToolCallIdNormalizer, - type ToolCallIdResponseNormalizer, -} from './toolCallIdNormalizer'; -import { - LlmRequest, - llmRequestTraceKey, - LlmToolsSnapshot, - type LlmRequestPayload, + LlmRequestTraceModel, + llmRequest, + llmToolsSnapshot, type LlmRequestToolSchema, } from './llmRequestOps'; import { isAbortError } from '#/_base/utils/abort'; -import { parseBooleanEnv } from '#/_base/utils/env'; import { ErrorCodes, Error2, unwrapErrorCause } from '#/errors'; -import { - readRetryAfterMs, - retryBackoffDelay, - retryErrorFields, - sleepForRetry, -} from '#/_base/utils/retry'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; +import { retryErrorFields } from '#/_base/utils/retry'; const EMPTY_TOOL_PARAMETERS: Record<string, unknown> = { type: 'object', @@ -90,8 +107,6 @@ const EMPTY_TOOL_PARAMETERS: Record<string, unknown> = { const noopOnPart: AgentLLMRequestPartHandler = () => {}; -export const KIMI_CODE_INFINITE_RETRY_ENV = 'KIMI_CODE_INFINITE_RETRY'; - interface ResolvedLLMRequest { readonly requester: ModelRequester; readonly model: Model; @@ -105,6 +120,8 @@ interface ResolvedLLMRequest { readonly logFields: AgentLLMRequestLogFields; } +type RequestProjection = 'normal' | 'strict' | 'media-degraded' | 'media-stripped'; + interface LLMRequestLogInput { readonly protocol: Protocol; readonly providerType?: string; @@ -148,33 +165,29 @@ export const llmRequesterEmittedThinkingEffortWarningsKey = defineState<Set<stri export class AgentLLMRequesterService implements IAgentLLMRequesterService { declare readonly _serviceBrand: undefined; - private readonly toolCallIdNormalizer = new ToolCallIdNormalizer(); - constructor( @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IAgentContextProjectorService private readonly projector: IAgentContextProjectorService, - @ISessionTokenCountingService private readonly tokenCounting: ISessionTokenCountingService, + @IAgentTokenCountingService private readonly tokenCounting: IAgentTokenCountingService, @IAgentToolRegistryService private readonly tools: IAgentToolRegistryService, @IAgentToolSelectService private readonly toolSelect: IAgentToolSelectService, - @IAgentMediaResolverService private readonly mediaResolver: IAgentMediaResolverService, + @IAgentVideoResolverService private readonly videoResolver: IAgentVideoResolverService, @IAgentProfileService private readonly profile: IAgentProfileService, - @ISessionUsageService private readonly usage: ISessionUsageService, + @IAgentUsageService private readonly usage: IAgentUsageService, @IConfigService private readonly config: IConfigService, @IModelService private readonly modelService: IModelService, @IModelCatalog private readonly modelCatalog: IModelCatalog, @ILogService private readonly log: ILogService, @ITelemetryService private readonly telemetry: ITelemetryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IWireService private readonly wire: IWireService, + @IEventBus private readonly eventBus: IEventBus, @IAgentStateService private readonly states: IAgentStateService, - @IBootstrapService private readonly bootstrap: IBootstrapService, ) { - this.states.contributeState(llmRequestTraceKey); - this.states.contributeState(llmRequesterLastConfigLogSignatureKey); - this.states.contributeState(llmRequesterTurnConfigsKey); - this.states.contributeState(llmRequesterMediaDegradedTurnsKey); - this.states.contributeState(llmRequesterMediaStrippedTurnsKey); - this.states.contributeState(llmRequesterEmittedThinkingEffortWarningsKey); + this.states.register(llmRequesterLastConfigLogSignatureKey); + this.states.register(llmRequesterTurnConfigsKey); + this.states.register(llmRequesterMediaDegradedTurnsKey); + this.states.register(llmRequesterMediaStrippedTurnsKey); + this.states.register(llmRequesterEmittedThinkingEffortWarningsKey); } private get lastConfigLogSignature(): string | undefined { @@ -295,7 +308,7 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { } const statusCode = apiStatusCode(error); if (statusCode !== undefined) properties['status_code'] = statusCode; - const currentTurn = this.usage.status(this.scopeContext.agentContext).currentTurn; + const currentTurn = this.usage.status().currentTurn; if (currentTurn !== undefined) properties['input_tokens'] = inputTotal(currentTurn); this.telemetry.track2('api_error', properties); return traceId; @@ -317,36 +330,42 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { signal: AbortSignal | undefined, onRequestTrace: (traceId: string | undefined) => void, ): Promise<AgentLLMRequestFinish> { - this.toolCallIdNormalizer.seedFrom(this.context.get()); const shaped = this.toolSelect.shapeHistory(request.messages); - const recoveredStrip = this.mediaStripSnapshotForTurn(request.source); - let policy: ProjectionPolicy | undefined = - recoveredStrip !== undefined - ? { media: { strip: recoveredStrip } } - : this.isRecoveryTurn(this.mediaDegradedTurns, request.source) - ? { media: 'degraded' } - : undefined; - const captureMediaStripPolicy = (): { readonly strip: MediaStripSnapshot } => { - const snapshot = this.projector.captureMediaStripSnapshot(shaped); - this.markMediaStrippedRecoveryTurn(snapshot, request.source); - return { strip: snapshot }; - }; - const run = async ( - policy: ProjectionPolicy | undefined, - ): Promise<AgentLLMRequestFinish> => { - onRequestTrace(undefined); - const projection = projectionNameOf(policy); - const fields = - projection === undefined ? request.logFields : { ...request.logFields, projection }; - const input = { + let mediaStripSnapshot = this.mediaStripSnapshotForTurn(request.source); + const requestInput = (projection: RequestProjection) => { + return { systemPrompt: request.systemPrompt, tools: request.tools, - messages: await this.mediaResolver.resolve( - this.projector.project(shaped, policy), + messages: + projection === 'strict' + ? this.projector.projectStrict(shaped) + : projection === 'media-degraded' + ? this.projector.projectMediaDegraded(shaped) + : projection === 'media-stripped' + ? this.projector.projectMediaStripped( + shaped, + (mediaStripSnapshot ??= + this.projector.captureMediaStripSnapshot(shaped)), + ) + : this.projector.project(shaped), + }; + }; + + const run = async (projection: RequestProjection): Promise<AgentLLMRequestFinish> => { + onRequestTrace(undefined); + const projected = requestInput(projection); + const input = { + ...projected, + messages: await this.videoResolver.resolve( + projected.messages, request.requester, signal, ), }; + const fields = + projection === 'normal' + ? request.logFields + : { ...request.logFields, projection }; this.warnAboutAnthropicThinkingEffort(request); const logInput: LLMRequestLogInput = { protocol: request.model.protocol, @@ -367,69 +386,49 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { let usage: TokenUsage | undefined; let timing: ModelRequestTiming | undefined; let finish: Extract<ModelRequestEvent, { type: 'finish' }> | undefined; - const toolCallIds = this.toolCallIdNormalizer.beginResponse(); const setTraceId = (traceId: string | null | undefined): void => { const normalized = traceId ?? undefined; onRequestTrace(normalized); }; - try { - for await (const event of request.requester.request(input, signal, { - ...request.params, - onTraceId: setTraceId, - })) { - switch (event.type) { - case 'part': - await onPart(this.normalizeStreamPart(toolCallIds, event.part)); - break; - case 'usage': - usage = event.usage; - break; - case 'finish': - finish = event; - message = event.message; - setTraceId(event.traceId); - break; - case 'timing': { - const { type: _type, ...streamTiming } = event; - timing = streamTiming; - break; - } + for await (const event of request.requester.request(input, signal, { + ...request.params, + onTraceId: setTraceId, + })) { + switch (event.type) { + case 'part': + await onPart(event.part); + break; + case 'usage': + usage = event.usage; + break; + case 'finish': + finish = event; + message = event.message; + setTraceId(event.traceId); + break; + case 'timing': { + const { type: _type, ...streamTiming } = event; + timing = streamTiming; + break; } } - - if (message === undefined || finish === undefined) { - throw new Error2( - ErrorCodes.PROVIDER_API_ERROR, - 'LLM request stream ended without a finish event.', - ); - } - - const finalizedCalls = toolCallIds.remapFinalizedCalls(message.toolCalls); - if (finalizedCalls !== message.toolCalls) { - message = { ...message, toolCalls: finalizedCalls }; - } - for (const { raw, assigned } of toolCallIds.remapped) { - this.log.warn('Rewrote a duplicate provider tool call id into an agent-unique one.', { - raw, - assigned, - model: request.modelAlias, - }); - } - } catch (error) { - toolCallIds.rollback(); - throw error; } - void this.usage.record( - this.scopeContext.agentContext, - request.modelAlias, - usage ?? emptyUsage(), - request.source, - ); + if (message === undefined || finish === undefined) { + throw new Error2( + ErrorCodes.PROVIDER_API_ERROR, + 'LLM request stream ended without a finish event.', + ); + } + + this.usage.record(request.modelAlias, usage ?? emptyUsage(), request.source); + // Only a stream that actually reported usage may write a measured + // anchor — recording emptyUsage() zeros would zero the context size and + // silence compaction for providers without usage reporting. if (usage !== undefined) { - this.tokenCounting.measured(this.scopeContext.agentContext, request.messages, [message], usage); + this.tokenCounting.measured(request.messages, [message], usage); } this.logResponse(request.logFields, usage ?? emptyUsage(), timing); @@ -445,114 +444,75 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { }; }; - let infiniteRetryAttempt = 0; + const initialProjection: RequestProjection = mediaStripSnapshot !== undefined + ? 'media-stripped' + : this.isRecoveryTurn(this.mediaDegradedTurns, request.source) + ? 'media-degraded' + : 'normal'; + let projection: RequestProjection = initialProjection; for (;;) { try { - return await run(policy); + return await run(projection); } catch (error) { - const nextPolicy = this.nextProjectionPolicyForError( - error, - policy, - request, - signal, - captureMediaStripPolicy, - ); - if (nextPolicy !== undefined) { - policy = nextPolicy; - continue; - } + if (signal?.aborted === true) throw error; const raw = unwrapErrorCause(error); if ( - !this.infiniteRetryEnabled || - isAbortError(error) || - signal?.aborted === true || - raw instanceof APIContextOverflowError + raw instanceof APIRequestTooLargeError && + (projection === 'normal' || projection === 'media-degraded') ) { - throw error; + signal?.throwIfAborted(); + if (projection === 'normal') { + this.log.warn( + 'provider rejected request as too large; resending with degraded media', + { + model: request.model.name, + ...request.logFields, + }, + ); + this.markRecoveryTurn(this.mediaDegradedTurns, request.source); + projection = 'media-degraded'; + } else { + this.log.warn( + 'provider rejected degraded-media request as too large; resending with rejected media stripped', + { + model: request.model.name, + ...request.logFields, + }, + ); + mediaStripSnapshot = this.projector.captureMediaStripSnapshot(shaped); + this.markMediaStrippedRecoveryTurn(mediaStripSnapshot, request.source); + projection = 'media-stripped'; + } + continue; } - infiniteRetryAttempt += 1; - const delayMs = - readRetryAfterMs(raw) ?? - retryBackoffDelay(infiniteRetryAttempt - 1); - this.log.warn('llm request failed; retrying indefinitely (KIMI_CODE_INFINITE_RETRY)', { - model: request.model.name, - ...request.logFields, - attempt: infiniteRetryAttempt, - delayMs, - ...retryErrorFields(error), - }); - await sleepForRetry(delayMs, signal); + if (projection !== 'media-stripped' && isImageFormatError(raw)) { + signal?.throwIfAborted(); + this.log.warn( + 'provider rejected an image in the request; resending with rejected media stripped', + { + model: request.model.name, + ...request.logFields, + }, + ); + mediaStripSnapshot = this.projector.captureMediaStripSnapshot(shaped); + this.markMediaStrippedRecoveryTurn(mediaStripSnapshot, request.source); + projection = 'media-stripped'; + continue; + } + if (projection === 'normal' && isRecoverableRequestStructureError(raw)) { + signal?.throwIfAborted(); + this.log.warn('provider rejected request structure; resending with strict projection', { + model: request.model.name, + ...request.logFields, + }); + projection = 'strict'; + continue; + } + throw error; } } } - private get infiniteRetryEnabled(): boolean { - return parseBooleanEnv(this.bootstrap.getEnv(KIMI_CODE_INFINITE_RETRY_ENV)) === true; - } - - private nextProjectionPolicyForError( - error: unknown, - policy: ProjectionPolicy | undefined, - request: ResolvedLLMRequest, - signal: AbortSignal | undefined, - captureMediaStripPolicy: () => { readonly strip: MediaStripSnapshot }, - ): ProjectionPolicy | undefined { - if (signal?.aborted === true) return undefined; - const raw = unwrapErrorCause(error); - const media = policy?.media; - if ( - raw instanceof APIRequestTooLargeError && - (media === undefined || media === 'degraded') - ) { - signal?.throwIfAborted(); - if (media === undefined) { - this.log.warn('provider rejected request as too large; resending with degraded media', { - model: request.model.name, - ...request.logFields, - }); - this.markRecoveryTurn(this.mediaDegradedTurns, request.source); - return { ...policy, media: 'degraded' }; - } - this.log.warn( - 'provider rejected degraded-media request as too large; resending with rejected media stripped', - { - model: request.model.name, - ...request.logFields, - }, - ); - return { ...policy, media: captureMediaStripPolicy() }; - } - if (typeof media !== 'object' && isImageFormatError(raw)) { - signal?.throwIfAborted(); - this.log.warn( - 'provider rejected an image in the request; resending with rejected media stripped', - { - model: request.model.name, - ...request.logFields, - }, - ); - return { ...policy, media: captureMediaStripPolicy() }; - } - if (policy?.structure === undefined && isRecoverableRequestStructureError(raw)) { - signal?.throwIfAborted(); - this.log.warn('provider rejected request structure; resending with strict projection', { - model: request.model.name, - ...request.logFields, - }); - return { ...policy, structure: 'strict' }; - } - return undefined; - } - - private normalizeStreamPart( - toolCallIds: ToolCallIdResponseNormalizer, - part: StreamedMessagePart, - ): StreamedMessagePart { - if (!isToolCall(part)) return part; - const assigned = toolCallIds.remapStreamedId(part.id, part._streamIndex); - return assigned === part.id ? part : { ...part, id: assigned }; - } - private warnAboutAnthropicThinkingEffort(request: ResolvedLLMRequest): void { if (request.model.protocol !== 'anthropic') return; const effort = request.thinkingEffort; @@ -581,9 +541,7 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { } catch { } try { - void this.dispatcher.dispatch( - new WarningIssued({ agentId: this.scopeContext.agentId, code, message }), - ); + this.eventBus.publish({ type: 'warning', code, message }); } catch { } } @@ -633,7 +591,7 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { capability: resolved.modelCapabilities, usedContextTokens: overrides.messages === undefined - ? this.tokenCounting.get(this.scopeContext.agentContext).measured + ? this.tokenCounting.get().measured : undefined, }); const requester = this.modelCatalog.getRequester(resolved.modelAlias); @@ -706,10 +664,8 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { const wireTools = providerVisibleTools(input.tools); const tools = toolSignature(wireTools); const toolsHash = fingerprint(JSON.stringify(tools)); - if (!this.states.get(llmRequestTraceKey).seenToolsHashes.includes(toolsHash)) { - void this.dispatcher.dispatch( - new LlmToolsSnapshot({ agentId: this.scopeContext.agentId, hash: toolsHash, tools }), - ); + if (!this.wire.getModel(LlmRequestTraceModel).seenToolsHashes.includes(toolsHash)) { + this.wire.dispatch(llmToolsSnapshot({ hash: toolsHash, tools })); } const systemPromptHash = fingerprint(input.systemPrompt); @@ -717,8 +673,7 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { const thinkingConfig = this.config.get<ThinkingConfig>(THINKING_SECTION); const modelConfig = input.modelAlias === undefined ? undefined : this.modelService.get(input.modelAlias); - const payload: LlmRequestPayload = { - agentId: this.scopeContext.agentId, + const payload: PayloadOf<typeof llmRequest> = { kind: requestKindForRecord(fields), provider: input.protocol, model: input.modelName, @@ -746,7 +701,7 @@ export class AgentLLMRequesterService implements IAgentLLMRequesterService { projection: projectionField(fields), droppedCount: numberField(fields, 'droppedCount'), }; - void this.dispatcher.dispatch(new LlmRequest(payload)); + this.wire.dispatch(llmRequest(payload)); } private logResponse( @@ -824,7 +779,7 @@ function toolSignature(tools: readonly Tool[]): readonly LlmRequestToolSchema[] return tools.map(({ name, description, parameters }) => ({ name, description, parameters })); } -function requestKindForRecord(fields: AgentLLMRequestLogFields): LlmRequestPayload['kind'] { +function requestKindForRecord(fields: AgentLLMRequestLogFields): PayloadOf<typeof llmRequest>['kind'] { if (fields['kind'] === 'compaction') return 'compaction'; if (fields['requestKind'] === 'full_compaction') return 'compaction'; return 'loop'; @@ -840,32 +795,13 @@ function numberField(fields: AgentLLMRequestLogFields, key: string): number | un return typeof value === 'number' ? value : undefined; } -type LlmRequestProjection = NonNullable<LlmRequestPayload['projection']>; - -function projectionNameOf(policy: ProjectionPolicy | undefined): LlmRequestProjection | undefined { - if (policy?.structure === 'strict') { - if (policy.media === 'degraded') return 'strict-media-degraded'; - if (typeof policy.media === 'object') return 'strict-media-stripped'; - return 'strict'; - } - if (policy === undefined) return undefined; - if (policy.media === 'degraded') return 'media-degraded'; - if (typeof policy.media === 'object') return 'media-stripped'; - return undefined; -} - -function projectionField(fields: AgentLLMRequestLogFields): LlmRequestProjection | undefined { +function projectionField( + fields: AgentLLMRequestLogFields, +): 'strict' | 'media-degraded' | 'media-stripped' | undefined { const value = fields['projection']; - switch (value) { - case 'strict': - case 'media-degraded': - case 'media-stripped': - case 'strict-media-degraded': - case 'strict-media-stripped': - return value; - default: - return undefined; - } + return value === 'strict' || value === 'media-degraded' || value === 'media-stripped' + ? value + : undefined; } function fingerprint(content: string): string { diff --git a/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts b/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts deleted file mode 100644 index e8eb0e3ff..000000000 --- a/packages/agent-core-v2/src/agent/llmRequester/toolCallIdNormalizer.ts +++ /dev/null @@ -1,78 +0,0 @@ -import type { Message, ToolCall } from '#/kosong/contract/message'; - -export class ToolCallIdNormalizer { - private readonly seen = new Set<string>(); - private seeded = false; - - seedFrom(messages: readonly Message[]): void { - if (this.seeded) return; - this.seeded = true; - for (const message of messages) { - for (const call of message.toolCalls) this.seen.add(call.id); - if (message.toolCallId !== undefined) this.seen.add(message.toolCallId); - } - } - - beginResponse(): ToolCallIdResponseNormalizer { - return new ToolCallIdResponseNormalizer(this.seen); - } -} - -export class ToolCallIdResponseNormalizer { - private readonly assignedByIndex = new Map<number | string, string>(); - private readonly occurrencesByRawId = new Map<string, string[]>(); - private readonly claimed: string[] = []; - readonly remapped: { raw: string; assigned: string }[] = []; - - constructor(private readonly seen: Set<string>) {} - - remapStreamedId(rawId: string, streamIndex: number | string | undefined): string { - if (streamIndex !== undefined) { - const existing = this.assignedByIndex.get(streamIndex); - if (existing !== undefined) return existing; - } - const occurrences = this.occurrencesByRawId.get(rawId) ?? []; - const assigned = this.claim(rawId, occurrences.length); - this.occurrencesByRawId.set(rawId, [...occurrences, assigned]); - if (streamIndex !== undefined) this.assignedByIndex.set(streamIndex, assigned); - return assigned; - } - - remapFinalizedCalls(toolCalls: ToolCall[]): ToolCall[] { - if (toolCalls.length === 0) return toolCalls; - const counts = new Map<string, number>(); - let changed = false; - const result = toolCalls.map((call) => { - const occurrence = counts.get(call.id) ?? 0; - counts.set(call.id, occurrence + 1); - const assigned = - this.occurrencesByRawId.get(call.id)?.[occurrence] ?? this.claim(call.id, occurrence); - if (assigned === call.id) return call; - changed = true; - return { ...call, id: assigned }; - }); - return changed ? result : toolCalls; - } - - rollback(): void { - for (const id of this.claimed) this.seen.delete(id); - } - - private claim(rawId: string, occurrence: number): string { - if (occurrence === 0 && !this.seen.has(rawId)) { - this.seen.add(rawId); - this.claimed.push(rawId); - return rawId; - } - let n = Math.max(occurrence + 1, 2); - let candidate = `${rawId}__${n}`; - while (this.seen.has(candidate)) { - n += 1; - candidate = `${rawId}__${n}`; - } - this.seen.add(candidate); - this.claimed.push(candidate); - this.remapped.push({ raw: rawId, assigned: candidate }); - return candidate; - } -} diff --git a/packages/agent-core-v2/src/agent/loop/configSection.ts b/packages/agent-core-v2/src/agent/loop/configSection.ts index e7345af97..d169a4830 100644 --- a/packages/agent-core-v2/src/agent/loop/configSection.ts +++ b/packages/agent-core-v2/src/agent/loop/configSection.ts @@ -1,3 +1,25 @@ +/** + * `loop` domain — `loopControl` config-section schema, env bindings, and + * TOML transforms. + * + * Owns the `[loop_control]` configuration section (step / retry / context-size + * limits). Renamed keys are declared through the config domain's deprecation + * mechanism (`deprecations`): a deprecated key in `config.toml` no longer + * applies and reports a warning pointing at its replacement — this covers the + * `max_retries_per_step` → `max_attempts_per_step` rename and the older + * `max_steps_per_run` → `max_steps_per_turn` one. The step and retry budgets + * also accept operational env overrides (`KIMI_LOOP_MAX_STEPS_PER_TURN` / + * `KIMI_LOOP_MAX_ATTEMPTS_PER_STEP`; the former + * `KIMI_LOOP_MAX_RETRIES_PER_STEP` still resolves as a deprecated fallback + * with a warning); `config` resolves each field as `env > config.toml > + * default` and re-applies the env binding on every read. Self-registered at + * module load via `registerConfigSection`. + * + * While a field's env var is set, `stripEnvBoundFields` restores its env-free + * raw value before `set`/`replace` persists, so an env override echoed + * back through a config write can never leak into `config.toml`. + */ + import { z } from 'zod'; import { type EnvBindings, envBindings, stripEnvBoundFields } from '#/app/config/config'; @@ -8,6 +30,7 @@ export const LOOP_CONTROL_SECTION = 'loopControl'; export const LOOP_MAX_STEPS_PER_TURN_ENV = 'KIMI_LOOP_MAX_STEPS_PER_TURN'; export const LOOP_MAX_ATTEMPTS_PER_STEP_ENV = 'KIMI_LOOP_MAX_ATTEMPTS_PER_STEP'; +/** Deprecated former name of {@link LOOP_MAX_ATTEMPTS_PER_STEP_ENV}. */ export const LOOP_MAX_RETRIES_PER_STEP_ENV = 'KIMI_LOOP_MAX_RETRIES_PER_STEP'; export const LoopControlSchema = z.object({ diff --git a/packages/agent-core-v2/src/agent/loop/errors.ts b/packages/agent-core-v2/src/agent/loop/errors.ts index 662b4ee5f..ace59d6fb 100644 --- a/packages/agent-core-v2/src/agent/loop/errors.ts +++ b/packages/agent-core-v2/src/agent/loop/errors.ts @@ -1,3 +1,10 @@ +/** + * `loop` domain error codes. + * + * `turn.agent_busy` is the legacy turn-domain code; the wire string is + * unchanged. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const LoopErrors = { diff --git a/packages/agent-core-v2/src/agent/loop/loop.ts b/packages/agent-core-v2/src/agent/loop/loop.ts index 3fcc68993..d13c066c6 100644 --- a/packages/agent-core-v2/src/agent/loop/loop.ts +++ b/packages/agent-core-v2/src/agent/loop/loop.ts @@ -32,7 +32,6 @@ export function isMaxStepsExceededError(error: unknown): boolean { export interface BeforeStepContext { readonly turnId: number; readonly step: number; - readonly firstStepOfTurn: boolean; readonly signal: AbortSignal; } @@ -147,8 +146,6 @@ export interface IAgentLoopService { cancel(turnId?: number, reason?: unknown): boolean; - cancelFromUser(turnId?: number): void; - tryAcquireQuiescence(): IDisposable | undefined; settled(): Promise<void>; diff --git a/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts b/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts index bd0e5aea8..8564f317c 100644 --- a/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts +++ b/packages/agent-core-v2/src/agent/loop/loopContinuationService.ts @@ -1,3 +1,18 @@ +/** + * `loop` domain — tool-step continuation aspect. + * + * A step that executed tools must drive one more step so the model consumes + * the tool results: this service watches the loop's `onDidFinishStep` and enqueues + * a `ContinuationStepRequest` whenever a step ends with `tool_calls` — which + * is exactly when the step ran tools without a stopTurn tool result (the + * loop maps that combination onto the `tool_calls` finish reason). The loop + * itself only drains the queue and dispatches errors; it never enqueues. A + * hook-set `stopTurn` still wins over the continuation: the turn ends at the + * step boundary and the turn-scoped request is discarded by the run-end + * cleanup. Bound at Agent scope and constructed with the scope so the hook + * registers before the first turn runs. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/loop/loopService.ts b/packages/agent-core-v2/src/agent/loop/loopService.ts index d0a7e312a..a6940a27b 100644 --- a/packages/agent-core-v2/src/agent/loop/loopService.ts +++ b/packages/agent-core-v2/src/agent/loop/loopService.ts @@ -1,19 +1,49 @@ +/** + * `loop` domain — `IAgentLoopService` implementation. + * + * Owns a FIFO of Turn jobs, each with its own `StepRequestQueue`. Admission + * reserves a stable Turn handle immediately; the head job alone books the + * agent's work span with the session lifecycle, records `turn.prompt`, + * publishes `turn.started`, and drains its Steps. Ending unbooks the work span, + * then publishes `turn.ended` and pumps the next queued Turn. Requests without + * an active Turn remain in the Loop-owned pending-input queue and bind to the + * next admitted Turn. + * + * The run drains the queue one batch per step: each batch's driver request + * (plus any mergeable requests folded into it) materializes its context + * messages, then one LLM step runs (`onWillBeginStep` → streamed request → content + * parts → tool execution → `step.end` → `onDidFinishStep`). The loop itself never + * enqueues — it only runs requests and dispatches errors. A failed step is + * dispatched to the registered error handlers (first match wins); a handler + * that claims and catches the error has already enqueued the turn's + * continuation itself, so the loop only learns caught-or-not, while an + * unclaimed or uncaught error fails the turn. Emits `turn.*` / delta + * events through `event`, persists loop events through `contextMemory`, and + * reads the step budget from `config`. The plain-data loop state + * (`nextReservedTurnId`, `lastRequestTraceId`, `disposing`) is registered + * into `agentState` (`IAgentStateService`) and read/written through it; + * `pendingTurns` and `activeTurnJob` stay plain fields because a `TurnJob` + * holds resources (`AbortController`, controlled promises, a + * `StepRequestQueue`) that must not be snapshotted, alongside the mechanism + * resources (`standaloneStepQueue`, `pendingAssignments`, `errorHandlers`, + * `settleWaiters`, `activeRequestTrace`). Bound at Agent scope. + */ + import { randomUUID } from 'node:crypto'; -import { EventEmitter } from 'node:events'; import { createControlledPromise } from '@antfu/utils'; import { Disposable, toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { abortError, isAbortError, isUserCancellation, userCancellationReason } from '#/_base/utils/abort'; import { toErrorMessage } from '#/_base/errors/errorMessage'; import { IAgentLLMRequesterService, type AgentLLMRequestFinish } from '#/agent/llmRequester/llmRequester'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; import { IConfigService } from '#/app/config/config'; -import { AgentErrorEvent } from '#/agent/mcp/mcpEvents'; +import { IEventBus } from '#/app/event/eventBus'; import { type FinishReason } from '#/kosong/contract/provider'; import { mergeInPlace, type ContentPart, type StreamedMessagePart } from '#/kosong/contract/message'; import { type TokenUsage } from '#/kosong/contract/usage'; @@ -22,7 +52,6 @@ import { OrderedHookSlot } from '#/hooks'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import { isVacuousContentPart } from '#/agent/contextMemory/vacuousContent'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentTelemetryContextService } from '#/app/telemetry/agentTelemetryContext'; import type { @@ -31,7 +60,7 @@ import type { TurnStartedEvent as TurnStartedTelemetryEvent, } from '#/app/telemetry/events'; import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { LOOP_CONTROL_SECTION, type LoopControl } from './configSection'; import { createMaxStepsExceededError, @@ -56,20 +85,8 @@ import { type TurnSeed, } from './stepRequest'; import { StepRequestQueue, type StepRequestBatch } from './stepRequestQueue'; -import { - AssistantDelta, - isDisplayablePromptOrigin, - ThinkingDelta, - ToolCallDelta, - turnPromptAttachments, - turnPromptText, - TurnStarted, - TurnStepCompleted, - TurnStepInterrupted, - TurnStepStarted, - type TurnInterruptReason, -} from './turnEvents'; -import { TurnCancel, TurnEnded, turnKey, TurnPrompt } from './turnOps'; +import { isDisplayablePromptOrigin, turnPromptText, type TurnInterruptReason } from './turnEvents'; +import { cancelTurn, endTurn, promptTurn, TurnModel } from './turnOps'; export type LoopInterruptReason = 'aborted' | 'max_steps' | 'error'; @@ -83,8 +100,7 @@ export const loopLastRequestTraceIdKey = defineState<string | undefined>( ); export const loopDisposingKey = defineState<boolean>('loop.disposing', () => false); -const MAX_STEP_SIGNAL_LISTENERS = 64; - +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentLoopService extends Disposable implements IAgentLoopService { declare readonly _serviceBrand: undefined; @@ -106,19 +122,18 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { constructor( @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IAgentLLMRequesterService private readonly llmRequester: IAgentLLMRequesterService, + @IEventBus private readonly eventBus: IEventBus, @IAgentToolExecutorService private readonly toolExecutor: IAgentToolExecutorService, @IConfigService private readonly config: IConfigService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IWireService private readonly wire: IWireService, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentTelemetryContextService private readonly telemetryContext: IAgentTelemetryContextService, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(turnKey); - this.states.contributeState(loopNextReservedTurnIdKey); - this.states.contributeState(loopLastRequestTraceIdKey); - this.states.contributeState(loopDisposingKey); + this.states.register(loopNextReservedTurnIdKey); + this.states.register(loopLastRequestTraceIdKey); + this.states.register(loopDisposingKey); } private get nextReservedTurnId(): number | undefined { @@ -235,26 +250,9 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { ); } - cancelFromUser(turnId?: number): void { - const status = this.status(); - if (status.state === 'running') { - this.telemetry.track2('cancel', { - from: 'streaming', - trace_id: status.activeTraceId, - }); - } - this.cancel(turnId); - } - tryAcquireQuiescence(): IDisposable | undefined { if (this.disposing) throw abortError('Agent loop disposed'); - if ( - this.quiescenceDepth > 0 || - this.activeTurnJob !== undefined || - this.hasPendingRequests() - ) { - return undefined; - } + if (this.activeTurnJob !== undefined || this.hasPendingRequests()) return undefined; this.quiescenceDepth += 1; return toDisposable(() => this.releaseQuiescence()); } @@ -280,13 +278,8 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { const job = this.activeTurnJob; if (job === undefined || (turnId !== undefined && job.turn.id !== turnId)) return false; if (job.controller.signal.aborted) return true; - void this.dispatcher.dispatch( - new TurnCancel({ - agentId: this.scopeContext.agentId, - turnId: job.turn.id, - target: 'active', - reason: cancelReasonFor(cancellation), - }), + this.wire.dispatch( + cancelTurn({ turnId: job.turn.id, target: 'active', reason: cancelReasonFor(cancellation) }), ); job.controller.abort(cancellation); return true; @@ -297,14 +290,7 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { if (index < 0) return false; const [job] = this.pendingTurns.splice(index, 1); if (job === undefined || job.turn.state !== 'queued') return false; - void this.dispatcher.dispatch( - new TurnCancel({ - agentId: this.scopeContext.agentId, - turnId, - target: 'queued', - reason: cancelReasonFor(cancellation), - }), - ); + this.wire.dispatch(cancelTurn({ turnId, target: 'queued', reason: cancelReasonFor(cancellation) })); for (const step of job.steps.values()) step.cancel(cancellation); job.controller.abort(cancellation); job.turn.state = 'cancelled'; @@ -370,7 +356,7 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { } private reserveTurnId(): number { - const modelNextId = this.states.get(turnKey).nextTurnId; + const modelNextId = this.wire.getModel(TurnModel).nextTurnId; const id = Math.max(modelNextId, this.nextReservedTurnId ?? modelNextId); this.nextReservedTurnId = id + 1; return id; @@ -464,20 +450,15 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { private startTurn(job: TurnJob): void { const origin = job.seed.origin; - void this.dispatcher.dispatch( - new TurnPrompt({ agentId: this.scopeContext.agentId, input: job.seed.input, origin }), - ); + this.wire.dispatch(promptTurn({ input: job.seed.input, origin })); job.turn.state = 'running'; this.activeTurnJob = job; - void this.dispatcher.dispatch( - new TurnStarted({ - agentId: this.scopeContext.agentId, - turnId: job.turn.id, - origin, - prompt: isDisplayablePromptOrigin(origin) ? turnPromptText(job.seed.input, origin) : undefined, - promptAttachments: turnPromptAttachments(job.seed.input), - }), - ); + this.eventBus.publish({ + type: 'turn.started', + turnId: job.turn.id, + origin, + prompt: isDisplayablePromptOrigin(origin) ? turnPromptText(job.seed.input) : undefined, + }); void this.runTurn(job.turn, job.ready).then(job.result.resolve, job.result.reject); } @@ -523,21 +504,16 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { const interruptReason = result.type === 'completed' ? undefined : interruptReasonFor(result); const durationMs = Date.now() - startedAt; - void this.dispatcher.dispatch( - new TurnEnded({ - agentId: this.scopeContext.agentId, - turnId: turn.id, - reason: result.type, - error, - durationMs, - interruptReason, - }), - ); - if (error !== undefined) { - void this.dispatcher.dispatch( - new AgentErrorEvent({ ...error, agentId: this.scopeContext.agentId }), - ); - } + this.wire.dispatch(endTurn({ turnId: turn.id, reason: result.type, error, durationMs })); + this.eventBus.publish({ + type: 'turn.ended', + turnId: turn.id, + reason: result.type, + error, + durationMs, + interruptReason, + }); + if (error !== undefined) this.eventBus.publish({ type: 'error', ...error }); if (interruptReason !== undefined) { const interrupted: TurnInterruptedEvent = { turn_id: turn.id, @@ -644,7 +620,6 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { begun.step.signal, runtime.turnSignal, begun.step.number, - runtime.job !== undefined && begun.step.number === 1, begun.step.uuid, options.onStarted, ); @@ -705,7 +680,6 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { ? runtime.turnSignal : AbortSignal.any([runtime.turnSignal, mutableStep.controller.signal]), }; - EventEmitter.setMaxListeners(MAX_STEP_SIGNAL_LISTENERS, step.signal); this.materializeBatch(batch); return { step }; } @@ -830,63 +804,45 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { signal: AbortSignal, turnSignal: AbortSignal, currentStep: number, - firstStepOfTurn: boolean, stepUuid: string, onStarted: ((step: number) => void) | undefined, ): Promise<StepExecutionResult> { this.activeRequestTrace = undefined; - await this.hooks.onWillBeginStep.run({ turnId, step: currentStep, firstStepOfTurn, signal }); + await this.hooks.onWillBeginStep.run({ turnId, step: currentStep, signal }); const markStepStarted = this.beginStep(turnId, signal, currentStep, stepUuid, onStarted); - let stepEndAppended = false; + const streamParts = this.createStreamPartHandler(turnId, markStepStarted); + const request = this.llmRequester.start( + { source: { type: 'turn', turnId, step: currentStep } }, + streamParts.handle, + signal, + ); + this.activeRequestTrace = request.trace; + let response: AgentLLMRequestFinish; try { - const streamParts = this.createStreamPartHandler(turnId, markStepStarted); - const request = this.llmRequester.start( - { source: { type: 'turn', turnId, step: currentStep } }, - streamParts.handle, - signal, - ); - this.activeRequestTrace = request.trace; - let response: AgentLLMRequestFinish; - try { - response = await request.result; - } catch (error) { - this.appendInterruptedStreamContent(turnId, currentStep, stepUuid, streamParts, turnSignal); - throw error; - } - this.lastRequestTraceId = request.trace.traceId; - this.appendResponseContent(turnId, currentStep, stepUuid, response); - const finishReason = await this.executeStepTools( - turnId, - signal, - currentStep, - stepUuid, - response, - request.trace, - ); - this.finishStep(turnId, signal, currentStep, stepUuid, response, finishReason, markStepStarted); - stepEndAppended = true; - const hookStopTurn = await this.runAfterStep( - turnId, - signal, - currentStep, - firstStepOfTurn, - response.usage, - finishReason, - ); - return { stopReason: finishReason, hookStopTurn }; + response = await request.result; } catch (error) { - if (!stepEndAppended) { - this.context.appendLoopEvent({ - type: 'step.end', - uuid: stepUuid, - turnId: String(turnId), - step: currentStep, - finishReason: - isAbortError(error) || signal.aborted || turnSignal.aborted ? 'interrupted' : 'error', - }); - } + this.appendInterruptedStreamContent(turnId, currentStep, stepUuid, streamParts, turnSignal); throw error; } + this.lastRequestTraceId = request.trace.traceId; + this.appendResponseContent(turnId, currentStep, stepUuid, response); + const finishReason = await this.executeStepTools( + turnId, + signal, + currentStep, + stepUuid, + response, + request.trace, + ); + this.finishStep(turnId, signal, currentStep, stepUuid, response, finishReason, markStepStarted); + const hookStopTurn = await this.runAfterStep( + turnId, + signal, + currentStep, + response.usage, + finishReason, + ); + return { stopReason: finishReason, hookStopTurn }; } private beginStep( @@ -897,14 +853,7 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { onStarted: ((step: number) => void) | undefined, ): () => void { signal.throwIfAborted(); - void this.dispatcher.dispatch( - new TurnStepStarted({ - agentId: this.scopeContext.agentId, - turnId, - step: currentStep, - stepId: stepUuid, - }), - ); + this.eventBus.publish({ type: 'turn.step.started', turnId, step: currentStep, stepId: stepUuid }); this.context.appendLoopEvent({ type: 'step.begin', uuid: stepUuid, @@ -978,7 +927,6 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { onToolCall: ({ toolCallId, name, args }) => { const callUuid = randomUUID(); toolCallUuids.set(toolCallId, callUuid); - const extras = response.message.toolCalls.find((t) => t.id === toolCallId)?.extras; this.context.appendLoopEvent({ type: 'tool.call', uuid: callUuid, @@ -988,7 +936,6 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { toolCallId, name, args, - extras, }); }, })) { @@ -1049,14 +996,12 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { turnId: number, signal: AbortSignal, currentStep: number, - firstStepOfTurn: boolean, usage: TokenUsage, finishReason: FinishReason, ): Promise<boolean> { const context: AfterStepContext = { turnId, step: currentStep, - firstStepOfTurn, signal, usage, finishReason, @@ -1078,24 +1023,22 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { finishReason: string, response: AgentLLMRequestFinish, ): void { - void this.dispatcher.dispatch( - new TurnStepCompleted({ - agentId: this.scopeContext.agentId, - turnId, - step, - stepId, - usage, - finishReason, - llmFirstTokenLatencyMs: response.timing?.firstTokenLatencyMs, - llmStreamDurationMs: response.timing?.streamDurationMs, - llmRequestBuildMs: response.timing?.requestBuildMs, - llmServerFirstTokenMs: response.timing?.serverFirstTokenMs, - llmServerDecodeMs: response.timing?.serverDecodeMs, - llmClientConsumeMs: response.timing?.clientConsumeMs, - providerFinishReason: response.providerFinishReason, - rawFinishReason: response.rawFinishReason, - }), - ); + this.eventBus.publish({ + type: 'turn.step.completed', + turnId, + step, + stepId, + usage, + finishReason, + llmFirstTokenLatencyMs: response.timing?.firstTokenLatencyMs, + llmStreamDurationMs: response.timing?.streamDurationMs, + llmRequestBuildMs: response.timing?.requestBuildMs, + llmServerFirstTokenMs: response.timing?.serverFirstTokenMs, + llmServerDecodeMs: response.timing?.serverDecodeMs, + llmClientConsumeMs: response.timing?.clientConsumeMs, + providerFinishReason: response.providerFinishReason, + rawFinishReason: response.rawFinishReason, + }); } private emitStepInterrupted( @@ -1105,15 +1048,13 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { message?: string, ): void { if (activeStep === undefined) return; - void this.dispatcher.dispatch( - new TurnStepInterrupted({ - agentId: this.scopeContext.agentId, - turnId, - step: activeStep, - reason, - message, - }), - ); + this.eventBus.publish({ + type: 'turn.step.interrupted', + turnId, + step: activeStep, + reason, + message, + }); } private createStreamPartHandler( @@ -1136,16 +1077,12 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { case 'text': onResponseEvent(); accumulate(part); - void this.dispatcher.dispatch( - new AssistantDelta({ agentId: this.scopeContext.agentId, turnId, delta: part.text }), - ); + this.eventBus.publish({ type: 'assistant.delta', turnId, delta: part.text }); return; case 'think': onResponseEvent(); accumulate(part); - void this.dispatcher.dispatch( - new ThinkingDelta({ agentId: this.scopeContext.agentId, turnId, delta: part.think }), - ); + this.eventBus.publish({ type: 'thinking.delta', turnId, delta: part.think }); return; case 'image_url': case 'audio_url': @@ -1155,15 +1092,13 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { onResponseEvent(); forceContentPartBoundary = true; callsByIndex.set(part._streamIndex, { id: part.id, name: part.name }); - void this.dispatcher.dispatch( - new ToolCallDelta({ - agentId: this.scopeContext.agentId, - turnId, - toolCallId: part.id, - name: part.name, - argumentsPart: part.arguments ?? undefined, - }), - ); + this.eventBus.publish({ + type: 'tool.call.delta', + turnId, + toolCallId: part.id, + name: part.name, + argumentsPart: part.arguments ?? undefined, + }); return; } case 'tool_call_part': { @@ -1171,15 +1106,13 @@ export class AgentLoopService extends Disposable implements IAgentLoopService { const toolCall = callsByIndex.get(part.index); if (toolCall === undefined) return; onResponseEvent(); - void this.dispatcher.dispatch( - new ToolCallDelta({ - agentId: this.scopeContext.agentId, - turnId, - toolCallId: toolCall.id, - name: toolCall.name, - argumentsPart: part.argumentsPart, - }), - ); + this.eventBus.publish({ + type: 'tool.call.delta', + turnId, + toolCallId: toolCall.id, + name: toolCall.name, + argumentsPart: part.argumentsPart, + }); return; } default: { diff --git a/packages/agent-core-v2/src/agent/loop/stepRequest.ts b/packages/agent-core-v2/src/agent/loop/stepRequest.ts index 6cbd92955..f66490a5e 100644 --- a/packages/agent-core-v2/src/agent/loop/stepRequest.ts +++ b/packages/agent-core-v2/src/agent/loop/stepRequest.ts @@ -1,3 +1,18 @@ +/** + * `loop` domain — `StepRequest` contracts for the loop's step queue. + * + * A `StepRequest` is one queued unit of step work. Senders create plain + * request objects and hand them to `IAgentLoopService.enqueue`; requests + * carry no DI identity of their own, so + * constructing them with `new` is expected. Each request describes the context + * message(s) it contributes — computed lazily at pop time through + * `resolveContextMessages` — plus its queue semantics (`mergeable`, + * `turnScoped`). Because the message only materializes when the loop pops the + * request, an aborted request is discarded without ever touching the context: + * removal needs no compensating undo. Runtime types only; not registered with + * the container. + */ + import { randomUUID } from 'node:crypto'; import type { ContentPart } from '#/kosong/contract/message'; @@ -14,7 +29,6 @@ export type StepRequestAdmission = export interface TurnSeed { readonly input: readonly ContentPart[]; readonly origin: PromptOrigin; - readonly promptId?: string; } export interface StepRequestOptions { diff --git a/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts b/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts index b8aa03ae4..383f22668 100644 --- a/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts +++ b/packages/agent-core-v2/src/agent/loop/stepRequestQueue.ts @@ -1,3 +1,18 @@ +/** + * `loop` domain — the step queue held by `AgentLoopService`. + * + * Turn-owned FIFO with head insertion: senders enqueue `StepRequest`s (tail + * for ordered work, head for retries of a failed step), and one Turn drains + * its queue one batch per step. A batch is one *driver* (the first + * non-mergeable request) plus every *mergeable* request folded into the + * driver's step — this is how steers land in the same LLM request as pending + * tool results or a fresh prompt instead of each costing its own step. Extra + * non-mergeable requests stay queued and drive later steps. Aborted requests + * are discarded when reached, leaving the context untouched. When a run ends, + * turn-scoped requests are aborted while agent-scoped requests (steers) carry + * into the next turn. + */ + import type { StepRequest } from './stepRequest'; export interface StepRequestBatch { diff --git a/packages/agent-core-v2/src/agent/loop/turnEvents.ts b/packages/agent-core-v2/src/agent/loop/turnEvents.ts index 4994ea4a0..fed477dd9 100644 --- a/packages/agent-core-v2/src/agent/loop/turnEvents.ts +++ b/packages/agent-core-v2/src/agent/loop/turnEvents.ts @@ -1,7 +1,19 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `loop` domain — the `turn.*` / delta event payloads published through + * `IEventBus` as a turn runs. These are the loop's share of the agent event + * stream; consumers subscribe by `type`. + * `turn.started` additionally carries the text extracted from the turn's + * input parts (absent when the turn opened with no text part): consumers + * that render the user's prompt must take it from there, because the context + * append carrying the same text is not a bus event and lands later. The + * prompt rides the event only for displayable user origins + * ({@link isDisplayablePromptOrigin}) — a system-triggered turn (goal + * continuation, subagent run, cron…) has internal steering text as its input, + * which must never surface in transcripts. + */ + +import type { KimiErrorPayload } from '#/_base/errors/serialize'; import type { PromptOrigin } from '#/agent/contextMemory/types'; -import { parseDaemonFileUrl } from '#/agent/media/mediaRef'; -import { AgentEvent2 } from '#/app/event/event2'; import type { FinishReason } from '#/kosong/contract/provider'; import type { ContentPart, TextPart } from '#/kosong/contract/message'; import type { TokenUsage } from '#/kosong/contract/usage'; @@ -16,56 +28,21 @@ export type TurnInterruptReason = | 'filtered' | 'blocked'; -export interface TurnStartedPayload { - readonly agentId: string; +export interface TurnStartedEvent { + readonly type: 'turn.started'; readonly turnId: number; readonly origin: PromptOrigin; readonly prompt?: string; - readonly promptAttachments?: readonly { kind: 'image' | 'video' | 'audio'; fileId: string }[]; } -export class TurnStarted extends AgentEvent2<TurnStartedPayload> { - static override readonly type = 'turn.started'; - static override readonly observable = true; -} -export interface TurnStarted extends TurnStartedPayload {} - -export function turnPromptText( - input: readonly ContentPart[], - origin?: PromptOrigin, -): string | undefined { - const bundledBlocks = origin?.kind === 'user' ? (origin.skillActivations?.length ?? 0) : 0; +export function turnPromptText(input: readonly ContentPart[]): string | undefined { const text = input .filter((part): part is TextPart => part.type === 'text') - .slice(bundledBlocks) .map((part) => part.text) .join(''); return text.length > 0 ? text : undefined; } -export function turnPromptAttachments( - input: readonly ContentPart[], -): TurnStartedPayload['promptAttachments'] { - const attachments: { kind: 'image' | 'video' | 'audio'; fileId: string }[] = []; - const sessionMediaFileId = (url: string, id: string | undefined): string | undefined => { - if (id === undefined) return undefined; - return parseDaemonFileUrl(url)?.fileId === id ? id : undefined; - }; - for (const part of input) { - if (part.type === 'image_url') { - const fileId = sessionMediaFileId(part.imageUrl.url, part.imageUrl.id); - if (fileId !== undefined) attachments.push({ kind: 'image', fileId }); - } else if (part.type === 'video_url') { - const fileId = sessionMediaFileId(part.videoUrl.url, part.videoUrl.id); - if (fileId !== undefined) attachments.push({ kind: 'video', fileId }); - } else if (part.type === 'audio_url') { - const fileId = sessionMediaFileId(part.audioUrl.url, part.audioUrl.id); - if (fileId !== undefined) attachments.push({ kind: 'audio', fileId }); - } - } - return attachments.length > 0 ? attachments : undefined; -} - export function isDisplayablePromptOrigin(origin: PromptOrigin): boolean { if (origin.kind === 'user') return true; return ( @@ -74,21 +51,24 @@ export function isDisplayablePromptOrigin(origin: PromptOrigin): boolean { ); } -export interface TurnStepStartedPayload { - readonly agentId: string; +export interface TurnEndedEvent { + readonly type: 'turn.ended'; + readonly turnId: number; + readonly reason: TurnEndReason; + readonly error?: KimiErrorPayload; + readonly durationMs?: number; + readonly interruptReason?: TurnInterruptReason; +} + +export interface TurnStepStartedEvent { + readonly type: 'turn.step.started'; readonly turnId: number; readonly step: number; readonly stepId?: string; } -export class TurnStepStarted extends AgentEvent2<TurnStepStartedPayload> { - static override readonly type = 'turn.step.started'; - static override readonly observable = true; -} -export interface TurnStepStarted extends TurnStepStartedPayload {} - -export interface TurnStepCompletedPayload { - readonly agentId: string; +export interface TurnStepCompletedEvent { + readonly type: 'turn.step.completed'; readonly turnId: number; readonly step: number; readonly stepId?: string; @@ -104,14 +84,8 @@ export interface TurnStepCompletedPayload { readonly rawFinishReason?: string; } -export class TurnStepCompleted extends AgentEvent2<TurnStepCompletedPayload> { - static override readonly type = 'turn.step.completed'; - static override readonly observable = true; -} -export interface TurnStepCompleted extends TurnStepCompletedPayload {} - -export interface TurnStepInterruptedPayload { - readonly agentId: string; +export interface TurnStepInterruptedEvent { + readonly type: 'turn.step.interrupted'; readonly turnId: number; readonly step: number; readonly stepId?: string; @@ -119,46 +93,35 @@ export interface TurnStepInterruptedPayload { readonly message?: string; } -export class TurnStepInterrupted extends AgentEvent2<TurnStepInterruptedPayload> { - static override readonly type = 'turn.step.interrupted'; - static override readonly observable = true; -} -export interface TurnStepInterrupted extends TurnStepInterruptedPayload {} - -export interface AssistantDeltaPayload { - readonly agentId: string; +export interface AssistantDeltaEvent { + readonly type: 'assistant.delta'; readonly turnId: number; readonly delta: string; } -export class AssistantDelta extends AgentEvent2<AssistantDeltaPayload> { - static override readonly type = 'assistant.delta'; - static override readonly observable = true; -} -export interface AssistantDelta extends AssistantDeltaPayload {} - -export interface ThinkingDeltaPayload { - readonly agentId: string; +export interface ThinkingDeltaEvent { + readonly type: 'thinking.delta'; readonly turnId: number; readonly delta: string; } -export class ThinkingDelta extends AgentEvent2<ThinkingDeltaPayload> { - static override readonly type = 'thinking.delta'; - static override readonly observable = true; -} -export interface ThinkingDelta extends ThinkingDeltaPayload {} - -export interface ToolCallDeltaPayload { - readonly agentId: string; +export interface ToolCallDeltaEvent { + readonly type: 'tool.call.delta'; readonly turnId: number; readonly toolCallId: string; readonly name?: string; readonly argumentsPart?: string; } -export class ToolCallDelta extends AgentEvent2<ToolCallDeltaPayload> { - static override readonly type = 'tool.call.delta'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'turn.started': TurnStartedEvent; + 'turn.ended': TurnEndedEvent; + 'turn.step.started': TurnStepStartedEvent; + 'turn.step.completed': TurnStepCompletedEvent; + 'turn.step.interrupted': TurnStepInterruptedEvent; + 'assistant.delta': AssistantDeltaEvent; + 'thinking.delta': ThinkingDeltaEvent; + 'tool.call.delta': ToolCallDeltaEvent; + } } -export interface ToolCallDelta extends ToolCallDeltaPayload {} diff --git a/packages/agent-core-v2/src/agent/loop/turnOps.ts b/packages/agent-core-v2/src/agent/loop/turnOps.ts index c209e9356..9901b077e 100644 --- a/packages/agent-core-v2/src/agent/loop/turnOps.ts +++ b/packages/agent-core-v2/src/agent/loop/turnOps.ts @@ -1,14 +1,21 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `loop` domain — persists and restores monotonically increasing turn + * identity. + * + * Owns the next available turn id, including cancelled queued reservations and + * legacy loop-event observations. Also persists the terminal `turn.ended` + * record (reason / error / durationMs) so downstream history rebuilds and + * cold-resumed read models (e.g. the activity view) can recover how the last + * turn ended. Consumed by the Agent-scope `loopService`; the + * `interruptionReminder` domain projects `turn.cancel` into its own model. + */ + import { z } from 'zod'; +import { defineModel } from '#/wire/model'; import type { KimiErrorPayload } from '#/_base/errors/serialize'; -import { ContextAppendLoopEvent } from '#/agent/contextMemory/contextEvents'; -import type { PromptOrigin } from '#/agent/contextMemory/types'; -import { AgentEvent2, type SerializedEvent2 } from '#/app/event/event2'; import type { ContentPart } from '#/kosong/contract/message'; -import { defineState } from '#/state/state'; - -import type { TurnInterruptReason } from './turnEvents'; +import type { PromptOrigin } from '#/agent/contextMemory/types'; export interface TurnModelState { readonly nextTurnId: number; @@ -20,122 +27,78 @@ export interface TurnModelState { }; } +export const TurnModel = defineModel<TurnModelState>( + 'turn', + () => ({ nextTurnId: 0, cancelledTurnIds: [] }), + { + reducers: { + 'context.append_loop_event': (state, { event }) => { + if (event.type === 'tool.result' || event.turnId === undefined) { + return state; + } + + const turnId = Number.parseInt(event.turnId, 10); + if (!Number.isInteger(turnId)) return state; + let next = state; + if (turnId >= state.nextTurnId) next = advanceTurnClock(state, turnId + 1); + if (next.lastEnded !== undefined && turnId > next.lastEnded.turnId) { + next = { ...next, lastEnded: undefined }; + } + return next; + }, + }, + }, +); + const turnInputShape = { - agentId: z.string(), input: z.custom<readonly ContentPart[]>(), origin: z.custom<PromptOrigin>(), }; -const turnPromptSchema = z.object(turnInputShape); - -export class TurnPrompt extends AgentEvent2<z.infer<typeof turnPromptSchema>> { - static override readonly type = 'turn.prompt'; - static override readonly durable = true; - static override readonly schema = turnPromptSchema; -} -export interface TurnPrompt { - readonly agentId: string; - readonly input: readonly ContentPart[]; - readonly origin: PromptOrigin; -} - -const turnSteerSchema = z.object(turnInputShape); - -export class TurnSteer extends AgentEvent2<z.infer<typeof turnSteerSchema>> { - static override readonly type = 'turn.steer'; - static override readonly durable = true; - static override readonly schema = turnSteerSchema; -} -export interface TurnSteer { - readonly agentId: string; - readonly input: readonly ContentPart[]; - readonly origin: PromptOrigin; -} - -const turnCancelSchema = z.object({ - agentId: z.string(), - turnId: z.number().optional(), - target: z.enum(['active', 'queued']).optional(), - reason: z.enum(['user_cancelled', 'aborted']).optional(), -}); - -export class TurnCancel extends AgentEvent2<z.infer<typeof turnCancelSchema>> { - static override readonly type = 'turn.cancel'; - static override readonly durable = true; - static override readonly schema = turnCancelSchema; -} -export interface TurnCancel { - readonly agentId: string; - readonly turnId?: number; - readonly target?: 'active' | 'queued'; - readonly reason?: 'user_cancelled' | 'aborted'; -} - -const turnEndedSchema = z.object({ - agentId: z.string(), - turnId: z.number(), - reason: z.enum(['completed', 'cancelled', 'failed', 'blocked']), - error: z.custom<KimiErrorPayload>().optional(), - durationMs: z.number().optional(), -}); - -export interface TurnEndedPayload { - readonly agentId: string; - readonly turnId: number; - readonly reason: 'completed' | 'cancelled' | 'failed' | 'blocked'; - readonly error?: KimiErrorPayload; - readonly durationMs?: number; - readonly interruptReason?: TurnInterruptReason; -} - -export class TurnEnded extends AgentEvent2<TurnEndedPayload> { - static override readonly type = 'turn.ended'; - static override readonly durable = true; - static override readonly observable = true; - static override readonly schema = turnEndedSchema; - - override serialize(): SerializedEvent2 { - const record: Record<string, unknown> = { - type: this.type, - agentId: this.agentId, - turnId: this.turnId, - reason: this.reason, - }; - if (this.error !== undefined) record['error'] = this.error; - if (this.durationMs !== undefined) record['durationMs'] = this.durationMs; - record['time'] = this.time; - return record as SerializedEvent2; +declare module '#/wire/types' { + interface PersistedOpMap { + 'turn.prompt': typeof promptTurn; + 'turn.steer': typeof steerTurn; + 'turn.cancel': typeof cancelTurn; + 'turn.ended': typeof endTurn; } } -export interface TurnEnded extends TurnEndedPayload {} -export const turnKey = defineState( - 'turn', - (): TurnModelState => ({ nextTurnId: 0, cancelledTurnIds: [] }), -).replayable({ schema: z.custom<TurnModelState>() }) - .on(ContextAppendLoopEvent, (s, e) => { - const { event } = e; - if (event.type === 'tool.result' || event.turnId === undefined) return; - const turnId = Number.parseInt(event.turnId, 10); - if (!Number.isInteger(turnId)) return; - let next: TurnModelState = s; - if (turnId >= next.nextTurnId) next = advanceTurnClock(next, turnId + 1); - if (next.lastEnded !== undefined && turnId > next.lastEnded.turnId) { - next = { ...next, lastEnded: undefined }; - } - if (next !== s) return next; - }) - .on(TurnPrompt, (s) => advanceTurnClock(s, s.nextTurnId + 1)) - .on(TurnSteer, () => {}) - .on(TurnCancel, (s, e) => { - if (e.target === undefined || e.turnId === undefined) return; - if (e.turnId < s.nextTurnId) return; - return advanceTurnClock(s, s.nextTurnId, [...s.cancelledTurnIds, e.turnId]); - }) - .on(TurnEnded, (s, e) => ({ +export const promptTurn = TurnModel.defineOp('turn.prompt', { + schema: z.object(turnInputShape), + apply: (s) => advanceTurnClock(s, s.nextTurnId + 1), +}); + +export const steerTurn = TurnModel.defineOp('turn.steer', { + schema: z.object(turnInputShape), + apply: (s) => s, +}); + +export const cancelTurn = TurnModel.defineOp('turn.cancel', { + schema: z.object({ + turnId: z.number().optional(), + target: z.enum(['active', 'queued']).optional(), + reason: z.enum(['user_cancelled', 'aborted']).optional(), + }), + apply: (s, { turnId, target }) => { + if (target === undefined || turnId === undefined) return s; + if (turnId < s.nextTurnId) return s; + return advanceTurnClock(s, s.nextTurnId, [...s.cancelledTurnIds, turnId]); + }, +}); + +export const endTurn = TurnModel.defineOp('turn.ended', { + schema: z.object({ + turnId: z.number(), + reason: z.enum(['completed', 'cancelled', 'failed', 'blocked']), + error: z.custom<KimiErrorPayload>().optional(), + durationMs: z.number().optional(), + }), + apply: (s, { turnId, reason, durationMs }) => ({ ...s, - lastEnded: { turnId: e.turnId, reason: e.reason, durationMs: e.durationMs }, - })); + lastEnded: { turnId, reason, durationMs }, + }), +}); function advanceTurnClock( state: TurnModelState, diff --git a/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts b/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts index 2a4458967..cd2583129 100644 --- a/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts +++ b/packages/agent-core-v2/src/agent/mcp/mcpDiscoveryOps.ts @@ -1,9 +1,14 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `mcp` domain — MCP tool-discovery wire state. + * + * Restores the per-agent de-dup cursor for durable MCP discovery records, + * keyed by `${serverName}\n${hash}` entries already present in this log. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; +import { defineModel } from '#/wire/model'; import type { MCPToolDefinition } from '#/mcpCore/types'; -import { defineState } from '#/state/state'; export interface McpToolCollision { readonly qualified: string; @@ -17,6 +22,10 @@ export interface McpDiscoveryState { readonly seen: readonly string[]; } +export const McpDiscoveryModel = defineModel<McpDiscoveryState>('mcp.discovery', () => ({ + seen: [], +})); + const mcpToolCollisionSchema = z.object({ qualified: z.string(), toolName: z.string(), @@ -26,33 +35,23 @@ const mcpToolCollisionSchema = z.object({ ]), }); -const mcpToolsDiscoveredSchema = z.object({ - agentId: z.string(), - serverName: z.string(), - hash: z.string(), - tools: z.custom<readonly MCPToolDefinition[]>(), - enabledNames: z.array(z.string()).readonly(), - collisions: z.array(mcpToolCollisionSchema).readonly().optional(), -}); - -export class McpToolsDiscovered extends AgentEvent2<z.infer<typeof mcpToolsDiscoveredSchema>> { - static override readonly type = 'mcp.tools_discovered'; - static override readonly durable = true; - static override readonly schema = mcpToolsDiscoveredSchema; -} -export interface McpToolsDiscovered { - readonly agentId: string; - readonly serverName: string; - readonly hash: string; - readonly tools: readonly MCPToolDefinition[]; - readonly enabledNames: readonly string[]; - readonly collisions?: readonly McpToolCollision[]; +declare module '#/wire/types' { + interface PersistedOpMap { + 'mcp.tools_discovered': typeof mcpToolsDiscovered; + } } -export const mcpDiscoveryKey = defineState('mcp.discovery', (): McpDiscoveryState => ({ seen: [] })) - .replayable({ schema: z.custom<McpDiscoveryState>() }) - .on(McpToolsDiscovered, (s, e) => { - const key = `${e.serverName}\n${e.hash}`; - if (s.seen.includes(key)) return; - s.seen = [...s.seen, key]; +export const mcpToolsDiscovered = McpDiscoveryModel.defineOp('mcp.tools_discovered', { + schema: z.object({ + serverName: z.string(), + hash: z.string(), + tools: z.custom<readonly MCPToolDefinition[]>(), + enabledNames: z.array(z.string()).readonly(), + collisions: z.array(mcpToolCollisionSchema).readonly().optional(), + }), + apply: (s, p) => { + const key = `${p.serverName}\n${p.hash}`; + if (s.seen.includes(key)) return s; + return { seen: [...s.seen, key] }; + }, }); diff --git a/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts b/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts deleted file mode 100644 index b76053115..000000000 --- a/packages/agent-core-v2/src/agent/mcp/mcpEvents.ts +++ /dev/null @@ -1,44 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import type { KimiErrorPayload } from '#/_base/errors/serialize'; -import { AgentEvent2, type AgentDomainTrait } from '#/app/event/event2'; - -export interface McpServerStatusPayload { - readonly name: string; - readonly transport: 'stdio' | 'http' | 'sse'; - readonly status: 'pending' | 'connected' | 'failed' | 'disabled' | 'needs-auth' | 'removed'; - readonly toolCount: number; - readonly error?: string; -} - -export interface McpServerStatusEventPayload { - readonly agentId: string; - readonly server: McpServerStatusPayload; -} - -export class McpServerStatus extends AgentEvent2<McpServerStatusEventPayload> { - static override readonly type = 'mcp.server.status'; - static override readonly observable = true; -} -export interface McpServerStatus extends McpServerStatusEventPayload {} - -export type ToolListUpdatedReason = 'mcp.connected' | 'mcp.disconnected' | 'mcp.failed'; - -export interface ToolListUpdatedPayload { - readonly agentId: string; - readonly reason: ToolListUpdatedReason; - readonly serverName: string; -} - -export class ToolListUpdated extends AgentEvent2<ToolListUpdatedPayload> { - static override readonly type = 'tool.list.updated'; - static override readonly observable = true; -} -export interface ToolListUpdated extends ToolListUpdatedPayload {} - -export class AgentErrorEvent extends AgentEvent2<KimiErrorPayload & AgentDomainTrait> { - static override readonly type = 'error'; - static override readonly observable = true; -} -export interface AgentErrorEvent extends KimiErrorPayload { - readonly agentId: string; -} diff --git a/packages/agent-core-v2/src/agent/mcp/mcpService.ts b/packages/agent-core-v2/src/agent/mcp/mcpService.ts index bded747b1..8d9d79c41 100644 --- a/packages/agent-core-v2/src/agent/mcp/mcpService.ts +++ b/packages/agent-core-v2/src/agent/mcp/mcpService.ts @@ -1,18 +1,48 @@ +/** + * `mcp` domain — `IAgentMcpService` implementation. + * + * Mirrors the workspace-level shared MCP connection manager's server set + * into the agent's tool registry (the manager arrives through the seeded + * `ISessionMcpHandle` — one manager per workspace handler, shared by every + * session and agent): registers qualified tools for connected servers, + * keeps them registered across reconnects, keeps them registered (with + * calls short-circuited to a removal notice) when the server is tombstoned + * as `removed`, swaps in the OAuth tool for + * `needs-auth` servers, journals tool discoveries on the wire (queued until + * restore finishes), and publishes `mcp.server.status` / `tool.list.updated` + * events. Only the session's baseline servers take part + * (`ISessionMcpHandle.isBaselineServer`, checked on every replayed and + * live status change): a server that appears mid-session — a plugin + * install or a config edit — is ignored here, so its tools, status events, + * and discoveries never reach a live agent; it joins on the next session + * materialization (`/new`, `/reload`, resume), while a tombstoned baseline + * server reconnecting under the same name (a re-enabled plugin) registers + * again. Sessions and agents construct without awaiting the manager's + * initial connect; each LLM step instead waits for it through a `loop` + * onWillBeginStep hook (a no-op once settled), with the per-execution + * `toolExecutor` onWillExecuteTool wait as the backstop. The plain-data state (`mcpToolsByServer`, `discoveryWritesReady`) + * is registered into `agentState` (`IAgentStateService`) and read/written + * through it; `mcpTools` stays a plain instance field (its values hold + * disposable resource handles, not plain data), as does `pendingDiscoveries` + * (a closure queue of deferred discovery writes). Bound at Agent scope. + */ + import { createHash } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import type { Tool as KosongTool } from '#/kosong/contract/tool'; import { type IDisposable } from "#/_base/di/lifecycle"; import { Service } from "#/_base/di/service"; +import type { KimiErrorPayload } from '#/_base/errors/serialize'; import { ErrorCodes, makeErrorPayload } from "#/errors"; import { abortable } from '#/_base/utils/abort'; import { IAgentStateService } from '#/agent/state/agentState'; +import { IEventBus } from '#/app/event/eventBus'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { sessionMediaOriginalsDir } from '#/agent/media/image-originals'; import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { IAgentLoopService } from '#/agent/loop/loop'; import { createMcpAuthTool } from '#/agent/mcp/tools/auth'; @@ -23,13 +53,45 @@ import type { McpServerEntry } from '#/mcpCore/connection-manager'; import { IAgentMcpService } from './mcp'; import { qualifyMcpToolName } from '#/mcpCore/tool-naming'; import type { MCPClient, MCPToolDefinition } from '#/mcpCore/types'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { - mcpDiscoveryKey, - McpToolsDiscovered, + McpDiscoveryModel, + mcpToolsDiscovered, type McpToolCollision, } from './mcpDiscoveryOps'; -import { AgentErrorEvent, McpServerStatus, ToolListUpdated } from './mcpEvents'; + +export interface ErrorEvent extends KimiErrorPayload { + readonly type: 'error'; +} + +export interface McpServerStatusPayload { + readonly name: string; + readonly transport: 'stdio' | 'http' | 'sse'; + readonly status: 'pending' | 'connected' | 'failed' | 'disabled' | 'needs-auth' | 'removed'; + readonly toolCount: number; + readonly error?: string; +} + +export interface McpServerStatusEvent { + readonly type: 'mcp.server.status'; + readonly server: McpServerStatusPayload; +} + +export type ToolListUpdatedReason = 'mcp.connected' | 'mcp.disconnected' | 'mcp.failed'; + +export interface ToolListUpdatedEvent { + readonly type: 'tool.list.updated'; + readonly reason: ToolListUpdatedReason; + readonly serverName: string; +} + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'mcp.server.status': McpServerStatusEvent; + 'tool.list.updated': ToolListUpdatedEvent; + error: ErrorEvent; + } +} interface McpToolRegistration { readonly disposable: IDisposable; @@ -54,17 +116,16 @@ export class AgentMcpService extends Service implements IAgentMcpService { @ISessionMcpHandle private readonly mcpHandle: ISessionMcpHandle, @ISessionContext private readonly sessionContext: ISessionContext, @IAgentToolRegistryService private readonly registry: IAgentToolRegistryService, + @IEventBus private readonly eventBus: IEventBus, @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, @IAgentLoopService loop: IAgentLoopService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IWireService private readonly wire: IWireService, @ITelemetryService private readonly telemetry: ITelemetryService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(mcpDiscoveryKey); - this.states.contributeState(mcpMcpToolsByServerKey); - this.states.contributeState(mcpDiscoveryWritesReadyKey); + this.states.register(mcpMcpToolsByServerKey); + this.states.register(mcpDiscoveryWritesReadyKey); this.attachMcpTools(); loop.hooks.onWillBeginStep.register('mcp', async (ctx, next) => { await this.waitForInitialLoad(ctx.signal); @@ -76,7 +137,7 @@ export class AgentMcpService extends Service implements IAgentMcpService { }), ); this._register( - this.dispatcher.hooks.onDidRestore.register('mcp', async (_ctx, next) => { + this.wire.hooks.onDidRestore.register('mcp', async (_ctx, next) => { this.flushPendingDiscoveries(); await next(); }), @@ -166,18 +227,16 @@ export class AgentMcpService extends Service implements IAgentMcpService { private handleMcpServerStatusChange(entry: McpServerEntry): void { if (!this.mcpHandle.isBaselineServer(entry.name)) return; - void this.dispatcher.dispatch( - new McpServerStatus({ - agentId: this.scopeContext.agentId, - server: { - name: entry.name, - transport: entry.transport, - status: entry.status, - toolCount: entry.toolCount, - error: entry.error, - }, - }), - ); + this.eventBus.publish({ + type: 'mcp.server.status', + server: { + name: entry.name, + transport: entry.transport, + status: entry.status, + toolCount: entry.toolCount, + error: entry.error, + }, + }); if (entry.status === 'connected') { this.registerConnectedMcpServer(entry); return; @@ -192,13 +251,11 @@ export class AgentMcpService extends Service implements IAgentMcpService { if (entry.status === 'disabled') { const removed = this.unregisterMcpServer(entry.name); if (removed) { - void this.dispatcher.dispatch( - new ToolListUpdated({ - agentId: this.scopeContext.agentId, - reason: 'mcp.disconnected', - serverName: entry.name, - }), - ); + this.eventBus.publish({ + type: 'tool.list.updated', + reason: 'mcp.disconnected', + serverName: entry.name, + }); } } } @@ -214,13 +271,11 @@ export class AgentMcpService extends Service implements IAgentMcpService { ); this.emitMcpToolCollisions(entry.name, result.collisions); this.recordDiscovery(entry.name, resolved.rawTools, resolved.enabledNames, result.collisions); - void this.dispatcher.dispatch( - new ToolListUpdated({ - agentId: this.scopeContext.agentId, - reason: 'mcp.connected', - serverName: entry.name, - }), - ); + this.eventBus.publish({ + type: 'tool.list.updated', + reason: 'mcp.connected', + serverName: entry.name, + }); } private registerNeedsAuthMcpServer(entry: McpServerEntry): void { @@ -237,13 +292,11 @@ export class AgentMcpService extends Service implements IAgentMcpService { const disposable = this._register(this.registry.register(tool, { source: 'mcp' })); this.mcpTools.set(tool.name, { disposable, serverName: entry.name }); this.mcpToolsByServer.set(entry.name, [tool.name]); - void this.dispatcher.dispatch( - new ToolListUpdated({ - agentId: this.scopeContext.agentId, - reason: 'mcp.connected', - serverName: entry.name, - }), - ); + this.eventBus.publish({ + type: 'tool.list.updated', + reason: 'mcp.connected', + serverName: entry.name, + }); } private registerMcpServer( @@ -324,10 +377,9 @@ export class AgentMcpService extends Service implements IAgentMcpService { .update(JSON.stringify({ tools: rawTools, enabledNames: enabledNamesSnapshot, collisions })) .digest('hex'); const key = `${serverName}\n${hash}`; - if (this.states.get(mcpDiscoveryKey).seen.includes(key)) return; - void this.dispatcher.dispatch( - new McpToolsDiscovered({ - agentId: this.scopeContext.agentId, + if (this.wire.getModel(McpDiscoveryModel).seen.includes(key)) return; + this.wire.dispatch( + mcpToolsDiscovered({ serverName, hash, tools: rawTools, @@ -363,18 +415,16 @@ export class AgentMcpService extends Service implements IAgentMcpService { : `"${collision.toolName}" -> ${collision.qualified} (collides with server "${collision.collidesWith.serverName}")`, ) .join('; '); - void this.dispatcher.dispatch( - new AgentErrorEvent({ - ...makeErrorPayload( - ErrorCodes.MCP_TOOL_NAME_COLLISION, - `MCP server "${serverName}" registered ${collisions.length} tool name` + - `${collisions.length === 1 ? '' : 's'} ` + - `that collide with existing qualified names; the losing tools were dropped: ${summary}`, - { details: { serverName, collisions: collisions as readonly unknown[] } }, - ), - agentId: this.scopeContext.agentId, - }), - ); + this.eventBus.publish({ + type: 'error', + ...makeErrorPayload( + ErrorCodes.MCP_TOOL_NAME_COLLISION, + `MCP server "${serverName}" registered ${collisions.length} tool name` + + `${collisions.length === 1 ? '' : 's'} ` + + `that collide with existing qualified names; the losing tools were dropped: ${summary}`, + { details: { serverName, collisions: collisions as readonly unknown[] } }, + ), + }); } } diff --git a/packages/agent-core-v2/src/agent/mcp/output.ts b/packages/agent-core-v2/src/agent/mcp/output.ts index 996ca4ae2..d2af05e44 100644 --- a/packages/agent-core-v2/src/agent/mcp/output.ts +++ b/packages/agent-core-v2/src/agent/mcp/output.ts @@ -1,3 +1,45 @@ +/** + * MCP tool-call result → ExecutableTool output pipeline. + * + * Owns the full path from "MCP protocol content blocks" to "what the agent + * loop feeds back to the model": + * 1. Convert each {@link MCPContentBlock} to a kosong `ContentPart` + * (dropping unsupported shapes). + * 2. Wrap media-only outputs in `<mcp_tool_result name="…">` tags so the + * model can attribute binary output when several tools return media. + * 3. Serialize `structuredContent` and server `_meta` into a trailing + * `<mcp-structured-result>` text part — appended after the media wrap so + * a media-only result keeps its attribution tags, and before the text + * budget so oversized payloads stay bounded. Literal closing tags inside + * the serialized payload are stripped so server data cannot fake an + * early end of the block. `_meta` keys with a protocol-reserved prefix + * (per the spec's key-name rules: a `modelcontextprotocol` or `mcp` + * label followed by at least one more label, as in + * `modelcontextprotocol.io/…` or `tools.mcp.com/…`, but not a vendor + * namespace like `com.example.mcp/…`) are dropped first: they carry + * host/protocol plumbing rather than model-facing data, while unprefixed + * and vendor-prefixed keys pass through because their semantics belong + * to the server. Non-serialisable payloads drop the whole block rather + * than failing the call. + * 4. Apply the 100K text/think character budget to the tool's own text. + * This runs BEFORE captions exist, so a chatty tool (page text + a + * screenshot) can never evict or slice the compression caption — that + * would silently reintroduce the very degradation the caption reports. + * 5. Compress oversized inline images, announcing each compression with a + * caption (original vs. sent size, readback path to the persisted + * original) so downsampling is never silent. The captions ride the + * result's `note` side channel — projected to the model at fold time, but + * kept out of `output` so UIs never render them. + * 6. Apply the per-part 10 MB binary cap: oversized binary parts + * (image/audio/video URLs) collapse to a notice, so a single + * screenshot cannot evict every text part. + * 7. Collapse a single-text-part result to a plain string output; otherwise + * emit the `ContentPart[]` as-is. + * + * `mcpResultToExecutableOutput` is the single entry point; the per-step + * helpers stay private so callers cannot bypass the limits. + */ + import type { ContentPart } from '#/kosong/contract/message'; import type { ITelemetryService } from '#/app/telemetry/telemetry'; diff --git a/packages/agent-core-v2/src/agent/mcp/tools/auth.ts b/packages/agent-core-v2/src/agent/mcp/tools/auth.ts index 0426a71c6..4464a90a3 100644 --- a/packages/agent-core-v2/src/agent/mcp/tools/auth.ts +++ b/packages/agent-core-v2/src/agent/mcp/tools/auth.ts @@ -1,3 +1,29 @@ +/** + * Synthetic `mcp__<server>__authenticate` tool. + * + * When a remote MCP server lands in the `needs-auth` state — i.e. its + * initial connection failed with a 401 / `UnauthorizedError` and no static + * bearer token is configured — the {@link ToolManager} swaps the real MCP + * tool list for this single tool. Calling it: + * + * 1. Asks {@link McpOAuthService} to perform RFC 9728 / RFC 8414 / RFC 7591 + * discovery and produce an authorization URL. + * 2. Streams that URL back to the model via `onUpdate({kind:'status'})` + * and returns it in the tool output so the model can hand it to the + * human user. + * 3. Blocks (up to {@link DEFAULT_AUTH_TIMEOUT_MS}) on the one-shot + * localhost callback listener owned by the OAuth service. + * 4. Drives a manager-level `reconnect(name)` once tokens have been + * persisted, which flips the entry to `connected` and lets + * `ToolManager` swap the synthetic tool out for the real MCP tools. + * + * The blocking shape keeps the implementation + * simple at the cost of holding one tool call open for the duration of + * the human's browser flow. If the model ends up re-invoking the tool + * mid-flow we just start a fresh flow; the new callback server supersedes + * the old one. + */ + import { z } from 'zod'; import { diff --git a/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts b/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts index 1067f5774..3f527c3f2 100644 --- a/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts +++ b/packages/agent-core-v2/src/agent/mcp/tools/mcp.ts @@ -1,3 +1,32 @@ +/** + * MCP tool adapter — wraps a remote MCP tool as an `ExecutableTool`. + * + * Each tool exposed by a connected MCP server is adapted into an + * `ExecutableTool` whose `resolveExecution` forwards the call to the client + * and normalizes the result. When a call fails, the adapter picks one of + * three recoveries based on why it failed: + * + * - The server answered (a JSON-RPC error, or a response that failed + * client-side schema validation) → the error is rethrown; reconnecting + * would not change the answer. + * - The failure is ambiguous (a raw fetch/socket error) → the client is + * probed with a ping: alive means a transient blip and the call is + * retried once in place; dead means the transport is gone. + * - The transport is provably dead (the SDK fired `onclose`, or the probe + * failed) → the server is reconnected once through `options.reconnect` + * and the call retried on the fresh client, so a dropped connection + * surfaces as a slow call instead of a failed turn. + * + * Retries are at-least-once: if the transport died after the server + * processed the call but before the response arrived, the retry may + * duplicate side effects. There is no protocol-level dedup across + * reconnects, so this trade-off is accepted deliberately. + * + * When the server has been tombstoned as removed (`options.isRemoved`), + * the call short-circuits to an error result telling the model to stop + * calling the tool — no client call, no reconnect. + */ + import type { Tool as KosongTool } from '#/kosong/contract/tool'; import type { ITelemetryService } from '#/app/telemetry/telemetry'; import { Error2, ErrorCodes, toErrorMessage } from '#/errors'; diff --git a/packages/agent-core-v2/src/agent/media/configSection.ts b/packages/agent-core-v2/src/agent/media/configSection.ts index ef9c75bfb..cd87e17ca 100644 --- a/packages/agent-core-v2/src/agent/media/configSection.ts +++ b/packages/agent-core-v2/src/agent/media/configSection.ts @@ -1,3 +1,19 @@ +/** + * `media` domain — `image` config-section schema and env bindings. + * + * Owns the `[image]` section: the longest-edge ceiling (`max_edge_px`) applied + * when compressing images for the model, and the raw-byte budget + * (`read_byte_budget`) for images the model reads for itself (ReadMediaFile's + * default path). Both are persisted user preferences that also accept an + * operational env override (`KIMI_IMAGE_MAX_EDGE_PX` / + * `KIMI_IMAGE_READ_BYTE_BUDGET`); `config` resolves each field as + * `env > config.toml > default` and re-applies the env binding on every read. + * + * While a field's env var is set, `stripEnvBoundFields` restores its env-free + * raw value before `set`/`replace` persists, so an env override echoed + * back through a config write can never leak into `config.toml`. + */ + import { z } from 'zod'; import { type EnvBindings, envBindings, stripEnvBoundFields } from '#/app/config/config'; diff --git a/packages/agent-core-v2/src/agent/media/file-type.ts b/packages/agent-core-v2/src/agent/media/file-type.ts index d729c6823..809462aed 100644 --- a/packages/agent-core-v2/src/agent/media/file-type.ts +++ b/packages/agent-core-v2/src/agent/media/file-type.ts @@ -1,10 +1,10 @@ -import { - AUDIO_MIME_BY_SUFFIX, - IMAGE_MIME_BY_SUFFIX, - VIDEO_MIME_BY_SUFFIX, -} from './mediaRef'; - -export { AUDIO_MIME_BY_SUFFIX, IMAGE_MIME_BY_SUFFIX, VIDEO_MIME_BY_SUFFIX }; +/** + * `media` domain — magic-byte + extension file-type detection. + * + * Classifies a file as text / image / video from its first bytes and + * extension, and resolves a MIME type, with no npm dependency. Pure helper; + * no scoped service. + */ export const MEDIA_SNIFF_BYTES = 512; @@ -15,6 +15,38 @@ export interface FileType { export type DetectFileTypeMode = 'text' | 'media'; +export const IMAGE_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ + '.png': 'image/png', + '.jpg': 'image/jpeg', + '.jpeg': 'image/jpeg', + '.gif': 'image/gif', + '.bmp': 'image/bmp', + '.tif': 'image/tiff', + '.tiff': 'image/tiff', + '.webp': 'image/webp', + '.ico': 'image/x-icon', + '.heic': 'image/heic', + '.heif': 'image/heif', + '.avif': 'image/avif', + '.svgz': 'image/svg+xml', +}); + +export const VIDEO_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ + '.mp4': 'video/mp4', + '.mpg': 'video/mpeg', + '.mpeg': 'video/mpeg', + '.mkv': 'video/x-matroska', + '.avi': 'video/x-msvideo', + '.mov': 'video/quicktime', + '.ogv': 'video/ogg', + '.wmv': 'video/x-ms-wmv', + '.webm': 'video/webm', + '.m4v': 'video/x-m4v', + '.flv': 'video/x-flv', + '.3gp': 'video/3gpp', + '.3g2': 'video/3gpp2', +}); + const TEXT_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ '.svg': 'image/svg+xml', }); diff --git a/packages/agent-core-v2/src/agent/media/image-compress.ts b/packages/agent-core-v2/src/agent/media/image-compress.ts index 9622de623..f3961d199 100644 --- a/packages/agent-core-v2/src/agent/media/image-compress.ts +++ b/packages/agent-core-v2/src/agent/media/image-compress.ts @@ -1,3 +1,39 @@ +/** + * `media` domain — image compression for model ingestion. + * + * Shrink oversized images before they reach the model. + * + * A multimodal request carries each image as a base64 data URL; an unbounded + * screenshot or photo wastes context tokens and can blow past the provider's + * per-image byte ceiling. This module downsamples and re-encodes such images + * so they fit a pixel + byte budget, while leaving already-small images + * untouched — the common case is a fast, codec-free pass-through. + * + * Design notes: + * - Pure JS (jimp + a wasm WebP decoder), imported lazily so the codecs are + * only paid for when an image actually needs work; startup and the fast + * path stay cheap. + * - Best effort: any decode/encode failure returns the original bytes + * unchanged (`changed: false`). Callers must verify that this unchanged + * result satisfies their delivery limits before forwarding it. + * - Format gate first: content-part lists pass through + * {@link gateImageFormatParts} before any compression, so images outside + * the provider-accepted set are never decoded or forwarded — one + * unsupported image in the session history would make every subsequent + * request fail. + * - PNG, JPEG, and (non-animated) WebP are re-encoded; WebP re-encodes + * through the PNG/JPEG ladder after a wasm decode. GIF and animated WebP + * are passed through to preserve animation. Formats outside the + * provider-accepted set never reach this module from the content-part + * paths (the format gate drops them first); direct callers get a + * passthrough. + * - Compression must never be silent to the model: results carry the + * original dimensions, {@link buildImageCompressionCaption} renders the + * shared "what was compressed, where is the original" note every ingestion + * point can place next to the image, and {@link cropImageForModel} lets a + * caller read a region of the original back at full fidelity. + */ + import type { ContentPart } from '#/kosong/contract/message'; import { sniffImageDimensions } from './file-type'; @@ -380,6 +416,7 @@ export interface CompressAnnotateOptions { readonly persistOriginal?: (bytes: Uint8Array, mimeType: string) => Promise<string | null>; } + export interface ImageCropRegion { readonly x: number; readonly y: number; @@ -540,6 +577,7 @@ export async function cropImageForModel( } } + export interface ImageVariantDescription { readonly width: number; readonly height: number; @@ -604,6 +642,7 @@ export function formatByteSize(bytes: number): string { return `${(bytes / (1024 * 1024)).toFixed(1)} MB`; } + type JimpImage = Awaited<ReturnType<(typeof import('jimp'))['Jimp']['fromBuffer']>>; interface EncodedImage { @@ -699,6 +738,7 @@ function fitWithinEdge(image: JimpImage, edge: number): boolean { return true; } + type CropErrorKind = | 'empty' | 'unsupported_format' diff --git a/packages/agent-core-v2/src/agent/media/image-format-policy.ts b/packages/agent-core-v2/src/agent/media/image-format-policy.ts index 0d470a897..3c7451412 100644 --- a/packages/agent-core-v2/src/agent/media/image-format-policy.ts +++ b/packages/agent-core-v2/src/agent/media/image-format-policy.ts @@ -1,3 +1,32 @@ +/** + * `media` domain — provider-accepted image formats, the single source + * of truth. + * + * Model providers accept only PNG, JPEG, GIF, and WebP image blocks. An + * `image_url` part carrying any other MIME (AVIF, HEIC, BMP, TIFF, ICO, …) + * is rejected by the API — and because prompts and tool results persist in + * the session history, that one part makes every subsequent request fail + * too ("session poisoning"). Every ingestion point therefore refuses + * unsupported formats instead of passing the bytes through. + * + * The policy is deliberately a closed set, not a denylist: a format is only + * ever sent when it is known to be accepted. Supporting a new format means + * adding it to {@link MODEL_ACCEPTED_IMAGE_MIMES}; tailoring the refusal + * guidance for a newly-seen unsupported format means adding one row to + * {@link UNSUPPORTED_IMAGE_FORMATS}. + * + * Inbound MIME strings are normalized for the DECISION + * ({@link normalizeImageMime}: case, whitespace, `image/jpg`), but every + * call site must forward the CANONICAL MIME into the session — strict + * provider whitelists (e.g. Anthropic's) reject the raw alias, which would + * re-create the very session poisoning this module exists to prevent. + * + * Scope: only inline `data:` images can be gated. A remote http(s) image URL + * (an MCP `resource_link`, a REST `source.kind: 'url'` part) carries no + * bytes to inspect, and providers that support URL images fetch them + * server-side; those pass through unchanged. + */ + import { IMAGE_MIME_BY_SUFFIX, sniffMediaFromMagic } from './file-type'; export const MODEL_ACCEPTED_IMAGE_MIMES: ReadonlySet<string> = new Set([ diff --git a/packages/agent-core-v2/src/agent/media/image-originals.ts b/packages/agent-core-v2/src/agent/media/image-originals.ts index 534e47905..71b56b5bb 100644 --- a/packages/agent-core-v2/src/agent/media/image-originals.ts +++ b/packages/agent-core-v2/src/agent/media/image-originals.ts @@ -1,3 +1,30 @@ +/** + * `media` domain — content-addressed store for pre-compression image originals. + * + * When an ingestion point (MCP tool result, pasted image, inline base64 + * upload) compresses an image that exists only in memory, the original bytes + * would be gone for good — the model could never zoom into a detail the + * downsampled copy lost. This module persists those originals so the + * compression caption can point at a real path the model can read back with + * `ReadMediaFile` (typically with `region`). + * + * Placement: callers that know their session pass + * `{ dir: sessionMediaOriginalsDir(sessionDir) }` so originals live at + * `<sessionDir>/media-originals/` — owned by the session, cleaned up with it, + * and immune to OS temp reaping. The shared temp-dir cache + * ({@link originalImageCacheDir}) is only the fallback for call sites with no + * session context. + * + * Design notes: + * - Content-addressed (sha256): duplicate pastes/results reuse one file and + * repeated writes are idempotent. + * - Best effort: any filesystem failure returns null; callers then emit a + * caption without a readback path. Persistence must never block a prompt. + * - Size-capped: after each write the store is swept oldest-first (mtime) + * until it fits {@link DEFAULT_MAX_TOTAL_BYTES}, so long sessions cannot + * fill the disk. + */ + import { createHash } from 'node:crypto'; import { mkdir, readdir, stat, unlink, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; diff --git a/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts b/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts index a8ee4a3fb..4b930b3e2 100644 --- a/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts +++ b/packages/agent-core-v2/src/agent/media/imageConfigBridge.ts @@ -1,3 +1,22 @@ +/** + * `media` domain — bridge from the `image` config section into the + * compression support module's resolver seam. + * + * The compression module is deliberately config-agnostic so foundational + * code never imports the config domain: it exposes + * `setConfiguredMaxImageEdgePx` / `setConfiguredReadImageByteBudget` and + * resolves its defaults as `configured ?? built-in`. This bridge is the + * single owner that populates that seam from the env-resolved `[image]` + * section — env (`KIMI_IMAGE_MAX_EDGE_PX` / `KIMI_IMAGE_READ_BYTE_BUDGET`) is + * already folded into `config.get('image')` by the config layer, so nothing + * here reads `process.env`. + * + * Constructed eagerly at Agent scope (before the first turn) and kept in + * sync via `onDidSectionChange`, so every compression call site honors + * config/env. Pushes are idempotent (one global config), so multiple agents + * are harmless. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; @@ -17,6 +36,7 @@ export interface IImageConfigBridge { export const IImageConfigBridge: ServiceIdentifier<IImageConfigBridge> = createDecorator<IImageConfigBridge>('imageConfigBridge'); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class ImageConfigBridge extends Disposable implements IImageConfigBridge { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts b/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts index 0edb6ef5f..7615648aa 100644 --- a/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts +++ b/packages/agent-core-v2/src/agent/media/kimiFileUrl.ts @@ -1,6 +1,50 @@ -export { - buildDaemonFileUrl as buildKimiFileUrl, - isDaemonFileUrl as isKimiFileUrl, - parseDaemonFileUrl as parseKimiFileUrl, - type DaemonFileRef as KimiFileRef, -} from './mediaRef'; +/** + * `media` domain — the `kimi-file://` internal video reference. + * + * A prompt video uploaded to `/files` enters context memory as a `video_url` + * part carrying `kimi-file://<fileId>?path=<encoded absolute path>`: `fileId` + * addresses the daemon upload the request-time resolver reads bytes from, and + * the optional `?path=` names the edge-materialized copy the model opens with + * `ReadMediaFile` when the video cannot be uploaded or inlined. The reference + * never reaches the provider wire — the resolver rewrites it first. Pure + * helpers; no scoped service. + */ + +const KIMI_FILE_SCHEME = 'kimi-file://'; +const PATH_QUERY = '?path='; + +export interface KimiFileRef { + readonly fileId: string; + readonly path?: string; +} + +export function isKimiFileUrl(url: string): boolean { + return url.startsWith(KIMI_FILE_SCHEME); +} + +export function buildKimiFileUrl(fileId: string, path?: string): string { + const base = `${KIMI_FILE_SCHEME}${fileId}`; + return path === undefined || path.length === 0 + ? base + : `${base}${PATH_QUERY}${encodeURIComponent(path)}`; +} + +export function parseKimiFileUrl(url: string): KimiFileRef | undefined { + if (!url.startsWith(KIMI_FILE_SCHEME)) return undefined; + const rest = url.slice(KIMI_FILE_SCHEME.length); + const queryAt = rest.indexOf(PATH_QUERY); + if (queryAt === -1) { + return rest.length > 0 ? { fileId: rest } : undefined; + } + const fileId = rest.slice(0, queryAt); + if (fileId.length === 0) return undefined; + const encoded = rest.slice(queryAt + PATH_QUERY.length); + if (encoded.length === 0) return { fileId }; + let path: string; + try { + path = decodeURIComponent(encoded); + } catch { + return { fileId }; + } + return { fileId, path }; +} diff --git a/packages/agent-core-v2/src/agent/media/mediaRef.ts b/packages/agent-core-v2/src/agent/media/mediaRef.ts deleted file mode 100644 index c3460988c..000000000 --- a/packages/agent-core-v2/src/agent/media/mediaRef.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { join } from 'node:path'; - -import type { ContentPart } from '#/kosong/contract/message'; - -export type MediaKind = 'image' | 'video' | 'audio' | 'file'; - -export const IMAGE_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ - '.png': 'image/png', - '.jpg': 'image/jpeg', - '.jpeg': 'image/jpeg', - '.gif': 'image/gif', - '.bmp': 'image/bmp', - '.tif': 'image/tiff', - '.tiff': 'image/tiff', - '.webp': 'image/webp', - '.ico': 'image/x-icon', - '.heic': 'image/heic', - '.heif': 'image/heif', - '.avif': 'image/avif', - '.svgz': 'image/svg+xml', -}); - -export const VIDEO_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ - '.mp4': 'video/mp4', - '.mpg': 'video/mpeg', - '.mpeg': 'video/mpeg', - '.mkv': 'video/x-matroska', - '.avi': 'video/x-msvideo', - '.mov': 'video/quicktime', - '.ogv': 'video/ogg', - '.wmv': 'video/x-ms-wmv', - '.webm': 'video/webm', - '.m4v': 'video/x-m4v', - '.flv': 'video/x-flv', - '.3gp': 'video/3gpp', - '.3g2': 'video/3gpp2', -}); - -export const AUDIO_MIME_BY_SUFFIX: Readonly<Record<string, string>> = Object.freeze({ - '.mp3': 'audio/mpeg', - '.wav': 'audio/wav', - '.m4a': 'audio/mp4', - '.ogg': 'audio/ogg', - '.oga': 'audio/ogg', - '.flac': 'audio/flac', - '.aac': 'audio/aac', - '.opus': 'audio/opus', - '.weba': 'audio/webm', - '.wma': 'audio/x-ms-wma', -}); - -const IMAGE_EXT_BY_MIME = invertMimeBySuffix(IMAGE_MIME_BY_SUFFIX); -const VIDEO_EXT_BY_MIME = invertMimeBySuffix(VIDEO_MIME_BY_SUFFIX); -const AUDIO_EXT_BY_MIME = invertMimeBySuffix(AUDIO_MIME_BY_SUFFIX); - -function invertMimeBySuffix(table: Readonly<Record<string, string>>): Readonly<Record<string, string>> { - const out: Record<string, string> = {}; - for (const [suffix, mime] of Object.entries(table)) { - out[mime] ??= suffix; - } - return Object.freeze(out); -} - -export function mediaExtensionForMime(mimeType: string): string | undefined { - const semi = mimeType.indexOf(';'); - const base = (semi === -1 ? mimeType : mimeType.slice(0, semi)).trim().toLowerCase(); - return VIDEO_EXT_BY_MIME[base] ?? IMAGE_EXT_BY_MIME[base] ?? AUDIO_EXT_BY_MIME[base]; -} - -function mediaSuffix(path: string): string { - const idx = path.lastIndexOf('.'); - if (idx === -1) return ''; - const lastSep = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\')); - if (idx <= lastSep + 1) return ''; - return path.slice(idx).toLowerCase(); -} - -export function mediaKindForPath(path: string): 'image' | 'video' | 'audio' | undefined { - const suffix = mediaSuffix(path); - if (suffix in IMAGE_MIME_BY_SUFFIX) return 'image'; - if (suffix in VIDEO_MIME_BY_SUFFIX) return 'video'; - if (suffix in AUDIO_MIME_BY_SUFFIX) return 'audio'; - return undefined; -} - -export function mediaKindForMime(mimeType: string): 'image' | 'video' | 'audio' | undefined { - const semi = mimeType.indexOf(';'); - const base = (semi === -1 ? mimeType : mimeType.slice(0, semi)).trim().toLowerCase(); - if (base.startsWith('image/')) return 'image'; - if (base.startsWith('video/')) return 'video'; - if (base.startsWith('audio/')) return 'audio'; - return undefined; -} - -export function mediaKindOfPart(part: ContentPart): 'image' | 'video' | 'audio' | undefined { - if (part.type === 'image_url') return 'image'; - if (part.type === 'video_url') return 'video'; - if (part.type === 'audio_url') return 'audio'; - return undefined; -} - -const KIMI_FILE_SCHEME = 'kimi-file://'; - -export interface DaemonFileRef { - readonly fileId: string; -} - -export function isDaemonFileUrl(url: string): boolean { - return url.startsWith(KIMI_FILE_SCHEME); -} - -export function buildDaemonFileUrl(fileId: string): string { - return `${KIMI_FILE_SCHEME}${fileId}`; -} - -export function parseDaemonFileUrl(url: string): DaemonFileRef | undefined { - if (!url.startsWith(KIMI_FILE_SCHEME)) return undefined; - const rest = url.slice(KIMI_FILE_SCHEME.length); - const queryAt = rest.indexOf('?'); - const fileId = queryAt === -1 ? rest : rest.slice(0, queryAt); - return fileId.length > 0 ? { fileId } : undefined; -} - -export function daemonFileRefFromPart( - part: ContentPart, -): { readonly kind: 'image' | 'video'; readonly ref: DaemonFileRef } | undefined { - if (part.type === 'image_url') { - const ref = parseDaemonFileUrl(part.imageUrl.url); - return ref === undefined ? undefined : { kind: 'image', ref }; - } - if (part.type === 'video_url') { - const ref = parseDaemonFileUrl(part.videoUrl.url); - return ref === undefined ? undefined : { kind: 'video', ref }; - } - return undefined; -} - -export const SESSION_MEDIA_DIR = 'media'; - -export function sessionMediaFilePath(sessionDir: string, fileId: string, ext: string): string { - return join(sessionDir, SESSION_MEDIA_DIR, `${fileId}${ext}`); -} - -const MEDIA_PATH_TAG_RE = /<(image|video|audio|file)\b[^>]*?\bpath="([^"]*)"[^>]*>(?:<\/\1>)?/g; - -export interface MediaPathTag { - readonly kind: MediaKind; - readonly path: string; - readonly index: number; - readonly text: string; -} - -export function escapeMediaAttribute(value: string): string { - return value - .replaceAll('&', '&') - .replaceAll('"', '"') - .replaceAll('<', '<') - .replaceAll('>', '>'); -} - -export function unescapeMediaAttribute(value: string): string { - return value - .replaceAll('"', '"') - .replaceAll('<', '<') - .replaceAll('>', '>') - .replaceAll('&', '&'); -} - -export function buildMediaPathTag(kind: MediaKind, path: string): string { - return `<${kind} path="${escapeMediaAttribute(path)}"></${kind}>`; -} - -export function matchMediaPathTags(text: string): MediaPathTag[] { - const tags: MediaPathTag[] = []; - for (const match of text.matchAll(MEDIA_PATH_TAG_RE)) { - tags.push({ - kind: match[1] as MediaKind, - path: unescapeMediaAttribute(match[2]!), - index: match.index, - text: match[0], - }); - } - return tags; -} - -export function matchSingleMediaPathTag(text: string): MediaPathTag | undefined { - const trimmed = text.trim(); - if (trimmed.length === 0) return undefined; - const tags = matchMediaPathTags(trimmed); - if (tags.length !== 1) return undefined; - const tag = tags[0]!; - return tag.index === 0 && tag.text.length === trimmed.length ? tag : undefined; -} diff --git a/packages/agent-core-v2/src/agent/media/mediaResolver.ts b/packages/agent-core-v2/src/agent/media/mediaResolver.ts deleted file mode 100644 index b459db931..000000000 --- a/packages/agent-core-v2/src/agent/media/mediaResolver.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; -import type { Message } from '#/kosong/contract/message'; -import type { ModelRequester } from '#/kosong/model/modelRequester'; - -export interface IAgentMediaResolverService { - readonly _serviceBrand: undefined; - - resolve( - messages: readonly Message[], - requester: ModelRequester, - signal?: AbortSignal, - ): Promise<readonly Message[]>; -} - -export const IAgentMediaResolverService = createDecorator<IAgentMediaResolverService>( - 'agentVideoResolverService', -); diff --git a/packages/agent-core-v2/src/agent/media/mediaResolverService.ts b/packages/agent-core-v2/src/agent/media/mediaResolverService.ts deleted file mode 100644 index 55f640f9a..000000000 --- a/packages/agent-core-v2/src/agent/media/mediaResolverService.ts +++ /dev/null @@ -1,350 +0,0 @@ -import { createHash } from 'node:crypto'; - -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IFileService } from '#/app/file/fileService'; -import { LifecycleScope } from '#/app/scopes'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import type { ContentPart, Message } from '#/kosong/contract/message'; -import type { ModelRequester } from '#/kosong/model/modelRequester'; -import { IBlobStore } from '#/persistence/interface/blobStore'; - -import { detectFileType, MEDIA_SNIFF_BYTES } from './file-type'; -import { isModelAcceptedImageMime, normalizeImageMime } from './image-format-policy'; -import { - buildMediaPathTag, - type DaemonFileRef, - daemonFileRefFromPart, - matchSingleMediaPathTag, -} from './mediaRef'; -import { ISessionMediaStore } from './sessionMediaStore'; -import { IAgentMediaResolverService } from './mediaResolver'; -import { createVideoUploader } from './registerMediaTools'; -import { - inlineVideoPart, - inlineVideoSupportedForProtocol, - isVideoUploadAuthError, - isVideoUploadUnsupportedError, -} from './videoUpload'; - -const CACHE_SCOPE = 'video-upload-cache'; -const PROVIDER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/; -const VIDEO_UNAVAILABLE_TEXT = - '[video omitted: the uploaded file is no longer available]'; -const IMAGE_UNAVAILABLE_TEXT = - '[image omitted: the uploaded file is no longer available]'; -const IMAGE_MEMO_MAX_BYTES = 8 * 1024 * 1024; -const IMAGE_MEMO_MAX_TOTAL_BYTES = 64 * 1024 * 1024; - -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder(); - -export const mediaResolvedKey = defineState<Map<string, ContentPart>>( - 'media.resolved', - () => new Map(), -); - -export class AgentMediaResolverService implements IAgentMediaResolverService { - declare readonly _serviceBrand: undefined; - - constructor( - @IFileService private readonly files: IFileService, - @IBlobStore private readonly blobs: IBlobStore, - @ITelemetryService private readonly telemetry: ITelemetryService, - @IAgentStateService private readonly states: IAgentStateService, - @ISessionMediaStore private readonly mediaStore: ISessionMediaStore, - ) { - this.states.contributeState(mediaResolvedKey); - } - - private get resolved(): Map<string, ContentPart> { - return this.states.get(mediaResolvedKey); - } - - private readonly imageMemo = new Map<string, { part: ContentPart; bytes: number }>(); - private imageMemoBytes = 0; - - async resolve( - messages: readonly Message[], - requester: ModelRequester, - signal?: AbortSignal, - ): Promise<readonly Message[]> { - if (!messages.some(hasDaemonFileMediaPart)) return messages; - - let changed = false; - const out: Message[] = []; - for (const message of messages) { - if (!hasDaemonFileMediaPart(message)) { - out.push(message); - continue; - } - const content: ContentPart[] = []; - let sawVideoRef = false; - for (const part of message.content) { - const daemonPart = daemonFileRefFromPart(part); - if (daemonPart === undefined) { - content.push(part); - continue; - } - sawVideoRef ||= daemonPart.kind === 'video'; - const resolved = - daemonPart.kind === 'video' - ? await this.resolveVideoPart(daemonPart.ref, requester, signal) - : await this.resolveImagePart(daemonPart.ref, requester, signal); - content.push(resolved); - } - out.push({ - ...message, - content: - content.length > 0 - ? content - : [unavailableMediaText(sawVideoRef ? 'video' : 'image')], - }); - changed = true; - } - return changed ? out : messages; - } - - private displayPath(ref: DaemonFileRef): Promise<string | undefined> { - return this.mediaStore.resolveDisplayPath(ref.fileId); - } - - private async resolveImagePart( - ref: DaemonFileRef, - requester: ModelRequester, - signal: AbortSignal | undefined, - ): Promise<ContentPart> { - if (!requester.model.capabilities.image_in) { - return degradedImage(await this.displayPath(ref)); - } - const cacheKey = `image\0${ref.fileId}`; - const memoed = this.memoedImage(cacheKey); - if (memoed !== undefined) return memoed; - const path = await this.displayPath(ref); - - let source: { readonly bytes: Buffer; readonly filename: string }; - try { - source = await this.readMedia(ref, signal); - } catch { - signal?.throwIfAborted(); - return degradedImage(path); - } - - const fileType = detectFileType( - source.filename, - source.bytes.subarray(0, MEDIA_SNIFF_BYTES), - 'media', - ); - if (fileType.kind !== 'image') return degradedImage(path); - if (!isModelAcceptedImageMime(fileType.mimeType)) return degradedImage(path); - - const part: ContentPart = { - type: 'image_url', - imageUrl: { - url: `data:${normalizeImageMime(fileType.mimeType)};base64,${source.bytes.toString('base64')}`, - }, - }; - if (source.bytes.length <= IMAGE_MEMO_MAX_BYTES) { - this.memoizeImage(cacheKey, part, source.bytes.length); - } - return part; - } - - private memoedImage(cacheKey: string): ContentPart | undefined { - const entry = this.imageMemo.get(cacheKey); - if (entry === undefined) return undefined; - this.imageMemo.delete(cacheKey); - this.imageMemo.set(cacheKey, entry); - return entry.part; - } - - private memoizeImage(cacheKey: string, part: ContentPart, bytes: number): void { - this.imageMemo.set(cacheKey, { part, bytes }); - this.imageMemoBytes += bytes; - for (const [key, entry] of this.imageMemo) { - if (this.imageMemoBytes <= IMAGE_MEMO_MAX_TOTAL_BYTES) return; - this.imageMemo.delete(key); - this.imageMemoBytes -= entry.bytes; - } - } - - private async resolveVideoPart( - ref: DaemonFileRef, - requester: ModelRequester, - signal: AbortSignal | undefined, - ): Promise<ContentPart> { - const model = requester.model; - if (!model.capabilities.video_in) return videoTag(await this.displayPath(ref)); - const providerKey = model.providerType ?? model.protocol; - const cacheKey = `${ref.fileId}\0${providerKey}`; - - const memoed = this.resolved.get(cacheKey); - if (memoed !== undefined) return this.memoedOutcome(ref, memoed); - - const { part, memoize } = await this.resolveVideoUncached(ref, requester, cacheKey, signal); - if (memoize) this.resolved.set(cacheKey, part); - return part; - } - - private async memoedOutcome(ref: DaemonFileRef, memoed: ContentPart): Promise<ContentPart> { - if (memoed.type !== 'text') return memoed; - const tag = matchSingleMediaPathTag(memoed.text); - if (tag === undefined) return memoed; - const path = await this.displayPath(ref); - if (path === undefined || path === tag.path) return memoed; - return { type: 'text', text: buildMediaPathTag(tag.kind, path) }; - } - - private async resolveVideoUncached( - ref: DaemonFileRef, - requester: ModelRequester, - cacheKey: string, - signal: AbortSignal | undefined, - ): Promise<{ part: ContentPart; memoize: boolean }> { - const cachedLlmFileId = await this.readCachedUpload(cacheKey); - if (cachedLlmFileId !== undefined) { - return { - part: { type: 'video_url', videoUrl: { url: `ms://${cachedLlmFileId}`, id: cachedLlmFileId } }, - memoize: true, - }; - } - const tagPath = await this.displayPath(ref); - - let source: { readonly bytes: Buffer; readonly filename: string }; - try { - source = await this.readMedia(ref, signal); - } catch { - signal?.throwIfAborted(); - return { part: videoTag(tagPath), memoize: true }; - } - - const { bytes, filename } = source; - const fileType = detectFileType(filename, bytes.subarray(0, MEDIA_SNIFF_BYTES), 'media'); - if (fileType.kind !== 'video') return { part: videoTag(tagPath), memoize: true }; - const mimeType = fileType.mimeType; - - const model = requester.model; - const inlineSupported = inlineVideoSupportedForProtocol(model.protocol); - - const uploader = createVideoUploader(requester, { - client: this.telemetry, - props: { - model: model.name, - provider_type: model.providerType ?? model.protocol, - protocol: model.protocol, - }, - }); - if (uploader === undefined) { - return { - part: inlineSupported ? inlineVideoPart(bytes, mimeType) : videoTag(tagPath), - memoize: true, - }; - } - - try { - const uploaded = await uploader({ data: bytes, mimeType, filename }, { signal }); - const llmFileId = uploaded.videoUrl.id ?? msFileIdFromUrl(uploaded.videoUrl.url); - if (llmFileId !== undefined) await this.writeCachedUpload(cacheKey, llmFileId); - return { part: uploaded, memoize: true }; - } catch (error) { - if (signal?.aborted) throw error; - if (isVideoUploadAuthError(error)) throw error; - if (isVideoUploadUnsupportedError(error)) { - return { - part: inlineSupported ? inlineVideoPart(bytes, mimeType) : videoTag(tagPath), - memoize: true, - }; - } - return { part: videoTag(tagPath), memoize: false }; - } - } - - private async readMedia( - ref: DaemonFileRef, - signal: AbortSignal | undefined, - ): Promise<{ readonly bytes: Buffer; readonly filename: string }> { - try { - signal?.throwIfAborted(); - const file = await this.files.get(ref.fileId); - const bytes = await readStream(file.stream(), signal); - return { bytes, filename: file.meta.name }; - } catch { - signal?.throwIfAborted(); - const canonical = await this.mediaStore.read(ref.fileId); - if (canonical === undefined) throw new Error(`media ${ref.fileId} is unavailable`); - return { bytes: Buffer.from(canonical.data), filename: canonical.name }; - } - } - - private async readCachedUpload(cacheKey: string): Promise<string | undefined> { - const data = await this.blobs.get(CACHE_SCOPE, blobKey(cacheKey)).catch(() => undefined); - if (data === undefined) return undefined; - const llmFileId = textDecoder.decode(data); - return PROVIDER_ID_RE.test(llmFileId) ? llmFileId : undefined; - } - - private async writeCachedUpload(cacheKey: string, llmFileId: string): Promise<void> { - if (!PROVIDER_ID_RE.test(llmFileId)) return; - await this.blobs.put(CACHE_SCOPE, blobKey(cacheKey), textEncoder.encode(llmFileId)).catch( - () => undefined, - ); - } -} - -function hasDaemonFileMediaPart(message: Message): boolean { - return message.content.some((part) => daemonFileRefFromPart(part) !== undefined); -} - -function degradedImage(path: string | undefined): ContentPart { - if (path === undefined) return unavailableMediaText('image'); - return { type: 'text', text: buildMediaPathTag('image', path) }; -} - -function unavailableMediaText(kind: 'image' | 'video'): ContentPart { - return { type: 'text', text: kind === 'video' ? VIDEO_UNAVAILABLE_TEXT : IMAGE_UNAVAILABLE_TEXT }; -} - -function videoTag(path: string | undefined): ContentPart { - if (path === undefined) { - return { type: 'text', text: VIDEO_UNAVAILABLE_TEXT }; - } - return { type: 'text', text: buildMediaPathTag('video', path) }; -} - -function msFileIdFromUrl(url: string): string | undefined { - if (!url.startsWith('ms://')) return undefined; - const id = url.slice('ms://'.length); - return id.length > 0 ? id : undefined; -} - -function blobKey(cacheKey: string): string { - return createHash('sha256').update(cacheKey).digest('hex'); -} - -async function readStream(stream: NodeJS.ReadableStream, signal?: AbortSignal): Promise<Buffer> { - const onAbort = (): void => { - const reason = signal?.reason instanceof Error ? signal.reason : undefined; - (stream as NodeJS.ReadableStream & { destroy?(error?: Error): void }).destroy?.(reason); - }; - signal?.addEventListener('abort', onAbort, { once: true }); - const chunks: Buffer[] = []; - try { - signal?.throwIfAborted(); - for await (const chunk of stream) { - signal?.throwIfAborted(); - chunks.push(Buffer.from(chunk as string | Uint8Array)); - } - return Buffer.concat(chunks); - } finally { - signal?.removeEventListener('abort', onAbort); - } -} - -registerScopedService( - LifecycleScope.Agent, - IAgentMediaResolverService, - AgentMediaResolverService, - ScopeActivation.OnScopeCreated, - 'media', -); diff --git a/packages/agent-core-v2/src/agent/media/mediaTools.ts b/packages/agent-core-v2/src/agent/media/mediaTools.ts index 9d5e2e628..d0615d8c0 100644 --- a/packages/agent-core-v2/src/agent/media/mediaTools.ts +++ b/packages/agent-core-v2/src/agent/media/mediaTools.ts @@ -1,3 +1,10 @@ +/** + * `media` domain — media-tools registrar contract. + * + * Identifier-only module, so consumers that need the service identifier do + * not pull the implementation's scoped registration into their module graph. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IAgentMediaToolsRegistrar { diff --git a/packages/agent-core-v2/src/agent/media/mediaToolsRegistrar.ts b/packages/agent-core-v2/src/agent/media/mediaToolsRegistrar.ts index fb8e4fa2b..df70906c6 100644 --- a/packages/agent-core-v2/src/agent/media/mediaToolsRegistrar.ts +++ b/packages/agent-core-v2/src/agent/media/mediaToolsRegistrar.ts @@ -1,16 +1,44 @@ +/** + * Media tool production registration — the Agent-scope service that keeps + * `ReadMediaFile` in the tool registry in sync with the bound model. + * + * Media tools cannot ride the module-level `registerAgentToolService(...)` + * contribution table: its activation runs when the Agent is created, and at + * that point no model is bound yet — the capabilities are still + * `UNKNOWN_CAPABILITY`, so a capability gate would permanently skip the + * tool. Registration instead re-runs whenever the resolved model changes: + * every profile/model update publishes `agent.status.updated`, and this + * service re-invokes {@link registerMediaTools} when the model alias or its + * media capabilities differ from what it last registered (rebinding the + * video uploader to the new model, and dropping the tool when the model + * loses media input). The `inlineVideoSupported` flag rides the same + * refresh: it is derived from the model's protocol because only the OpenAI + * family drops inline video on the wire — every other protocol that + * converts `video_url` takes the inline fallback when no upload hook + * exists. + * + * The plain-data state (`registeredKey`) is registered into `agentState` + * (`IAgentStateService`) and read/written through it; `registration` stays an + * instance field (the live `IDisposable` tool-registration handle, not plain + * data). + * + * Agent scope creation instantiates this service before any `opts.binding` + * bind runs, so the first `agent.status.updated` is always observed. + */ + import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IAgentStateService } from '#/agent/state/agentState'; import { IEventBus } from '#/app/event/eventBus'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { IModelCatalog, type Model } from '#/kosong/model/catalog'; import { type ModelRequester } from '#/kosong/model/modelRequester'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { IAgentProfileService } from '#/agent/profile/profile'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; @@ -34,17 +62,17 @@ export class AgentMediaToolsRegistrar extends Service implements IAgentMediaTool @IAgentProfileService private readonly profile: IAgentProfileService, @IModelCatalog private readonly modelCatalog: IModelCatalog, @IEventBus eventBus: IEventBus, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentStateService private readonly states: IAgentStateService, @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, ) { super(); - this.states.contributeState(mediaRegisteredKeyKey); + this.states.register(mediaRegisteredKeyKey); this.refresh(); - this._register(eventBus.subscribe(AgentStatusUpdated, () => this.refresh())); - this._register(this.runtime.onDidChange(() => this.refresh())); + this._register(eventBus.subscribe('agent.status.updated', () => this.refresh())); this._register(toDisposable(() => this.registration?.dispose())); } @@ -58,55 +86,27 @@ export class AgentMediaToolsRegistrar extends Service implements IAgentMediaTool private refresh(): void { const capabilities = this.profile.getModelCapabilities(); - const modelAlias = this.profile.getModel(); - if (!this.runtime.isAvailable(['fs'])) { - const key = [ - modelAlias, - String(capabilities.image_in), - String(capabilities.video_in), - 'runtime-unavailable', - ].join('|'); - if (key === this.registeredKey) return; - this.registeredKey = key; - this.registration?.dispose(); - this.registration = undefined; - return; - } - const inspected = this.runtime.inspect(); - const identityKey = [ - inspected.identity.workspaceId, - inspected.identity.runtimeId, - inspected.identity.generation, - ].join('|'); const key = [ - modelAlias, + this.profile.getModel(), String(capabilities.image_in), String(capabilities.video_in), - identityKey, - inspected.status, - inspected.environment.pathClass, - String(inspected.capabilities.has('fs')), ].join('|'); if (key === this.registeredKey) return; this.registeredKey = key; this.registration?.dispose(); const workspaceCtx = this.workspaceCtx; const skillCatalog = this.skillCatalog; - const runtime = this.runtime; - const pathClass = inspected.environment.pathClass; + const env = this.env; + const modelAlias = this.profile.getModel(); let requester: ModelRequester | undefined; let model: Model | undefined; if (modelAlias !== '') { - try { - requester = this.modelCatalog.getRequester(modelAlias); - model = requester.model; - } catch { - requester = undefined; - model = undefined; - } + requester = this.modelCatalog.getRequester(modelAlias); + model = requester.model; } this.registration = registerMediaTools(this.toolRegistry, { - runtime, + fs: this.fs, + env: this.env, workspace: { get workspaceDir() { return workspaceCtx.workDir; @@ -115,7 +115,7 @@ export class AgentMediaToolsRegistrar extends Service implements IAgentMediaTool return extendWorkspaceWithSkillRoots( { workspaceDir: workspaceCtx.workDir, additionalDirs: workspaceCtx.additionalDirs }, skillCatalog?.catalog.getSkillRoots() ?? [], - pathClass, + env.pathClass, ).additionalDirs; }, }, diff --git a/packages/agent-core-v2/src/agent/media/promptMediaIntake.ts b/packages/agent-core-v2/src/agent/media/promptMediaIntake.ts deleted file mode 100644 index 03971728e..000000000 --- a/packages/agent-core-v2/src/agent/media/promptMediaIntake.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { IFileService } from '#/app/file/fileService'; -import { abortable } from '#/_base/utils/abort'; -import type { ContentPart } from '#/kosong/contract/message'; - -import { daemonFileRefFromPart } from './mediaRef'; -import { ISessionMediaStore } from './sessionMediaStore'; - -export interface PromptMediaIntakeDeps { - readonly files: IFileService; - readonly mediaStore: ISessionMediaStore; - readonly signal?: AbortSignal; -} - -export async function materializePromptDaemonRefs( - content: readonly ContentPart[], - deps: PromptMediaIntakeDeps, -): Promise<void> { - for (const part of content) { - deps.signal?.throwIfAborted(); - const daemonPart = daemonFileRefFromPart(part); - if (daemonPart === undefined) continue; - await materializeRef(deps, daemonPart.ref.fileId).catch((_error: unknown) => { - deps.signal?.throwIfAborted(); - return undefined; - }); - } -} - -async function materializeRef(deps: PromptMediaIntakeDeps, fileId: string): Promise<void> { - const file = - deps.signal === undefined - ? await deps.files.get(fileId) - : await abortable(deps.files.get(fileId), deps.signal); - try { - await deps.mediaStore.materialize({ - fileId, - size: file.meta.size, - name: file.meta.name, - mimeType: file.meta.media_type, - stream: () => file.stream(), - signal: deps.signal, - }); - } catch { - deps.signal?.throwIfAborted(); - } -} diff --git a/packages/agent-core-v2/src/agent/media/registerMediaTools.ts b/packages/agent-core-v2/src/agent/media/registerMediaTools.ts index 976568794..23a4040ef 100644 --- a/packages/agent-core-v2/src/agent/media/registerMediaTools.ts +++ b/packages/agent-core-v2/src/agent/media/registerMediaTools.ts @@ -1,3 +1,15 @@ +/** + * Media tool registration. + * + * `ReadMediaFile` is only useful when the active model can consume image or + * video input, so registration is capability-gated here instead of inside the + * tool (v1 threw a `SkipThisTool` sentinel from the constructor). + * + * `createVideoUploader` is a thin binder over a `ModelRequester`'s optional + * `uploadVideo`. Auth is already resolved via the requester's auth-provider + * closure; media tooling doesn't need to know about tokens. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { ModelRequester } from '#/kosong/model/modelRequester'; import type { VideoUploadEvent } from '#/app/telemetry/events'; @@ -5,13 +17,15 @@ import type { ITelemetryService } from '#/app/telemetry/telemetry'; import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import type { WorkspaceConfig } from '#/tool/path-access'; -import type { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; +import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import type { IHostEnvironment } from '#/os/interface/hostEnvironment'; import type { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { ReadMediaFileTool } from '#/agent/tools/read-media-file/readMediaFileTool'; import type { VideoUploader } from '#/agent/tools/read-media-file/read-media-file'; export interface RegisterMediaToolsDeps { - readonly runtime: IAgentRuntimeService; + readonly fs: IHostFileSystem; + readonly env: IHostEnvironment; readonly workspace: WorkspaceConfig; readonly capabilities: ModelCapability; readonly videoUploader?: VideoUploader; @@ -23,15 +37,13 @@ export function registerMediaTools( toolRegistry: IAgentToolRegistryService, deps: RegisterMediaToolsDeps, ): IDisposable { - if ( - !deps.runtime.isAvailable(['fs']) || - (!deps.capabilities.image_in && !deps.capabilities.video_in) - ) { + if (!deps.capabilities.image_in && !deps.capabilities.video_in) { return toDisposable(() => {}); } return toolRegistry.register( new ReadMediaFileTool( - deps.runtime, + deps.fs, + deps.env, deps.workspace, deps.capabilities, deps.videoUploader, diff --git a/packages/agent-core-v2/src/agent/media/sessionMediaStore.ts b/packages/agent-core-v2/src/agent/media/sessionMediaStore.ts deleted file mode 100644 index 4cfb1f7dd..000000000 --- a/packages/agent-core-v2/src/agent/media/sessionMediaStore.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface SessionMediaMaterializeInput { - readonly fileId: string; - readonly size: number; - readonly name: string; - readonly mimeType: string; - readonly stream: () => NodeJS.ReadableStream; - readonly signal?: AbortSignal; -} - -export interface SessionMediaReadRange { - readonly start: number; - readonly end: number; -} - -export interface SessionMediaFile { - readonly path?: string; - readonly name: string; - readonly mediaType: string; - readonly size: number; - readonly stream: (range?: SessionMediaReadRange) => AsyncIterable<Uint8Array>; -} - -export interface ISessionMediaStore { - readonly _serviceBrand: undefined; - - pathFor(fileId: string, ext: string): string | undefined; - - resolveDisplayPath(fileId: string): Promise<string | undefined>; - - read(fileId: string): Promise<{ readonly data: Uint8Array; readonly name: string } | undefined>; - - open(fileId: string): Promise<SessionMediaFile | undefined>; - - materialize(input: SessionMediaMaterializeInput): Promise<string | undefined>; -} - -export const ISessionMediaStore: ServiceIdentifier<ISessionMediaStore> = - createDecorator<ISessionMediaStore>('sessionMediaStore'); diff --git a/packages/agent-core-v2/src/agent/media/sessionMediaStoreService.ts b/packages/agent-core-v2/src/agent/media/sessionMediaStoreService.ts deleted file mode 100644 index 2f538dbd8..000000000 --- a/packages/agent-core-v2/src/agent/media/sessionMediaStoreService.ts +++ /dev/null @@ -1,153 +0,0 @@ -import { extname } from 'node:path'; - -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { isFileId } from '#/app/file/fileService'; -import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import { IFileSystemStorageService } from '#/persistence/interface/storage'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; - -import { - AUDIO_MIME_BY_SUFFIX, - IMAGE_MIME_BY_SUFFIX, - mediaExtensionForMime, - VIDEO_MIME_BY_SUFFIX, -} from './mediaRef'; -import { - ISessionMediaStore, - type SessionMediaFile, - type SessionMediaMaterializeInput, -} from './sessionMediaStore'; - -interface SessionMediaMetadata { - readonly version: 1; - readonly key: string; - readonly name: string; - readonly mediaType: string; -} - -export class SessionMediaStoreService implements ISessionMediaStore { - declare readonly _serviceBrand: undefined; - private readonly scope: string; - - constructor( - @ISessionContext sessionContext: ISessionContext, - @IFileSystemStorageService private readonly storage: IFileSystemStorageService, - @IAtomicDocumentStore private readonly documents: IAtomicDocumentStore, - ) { - this.scope = sessionContext.scope('media'); - } - - pathFor(fileId: string, ext: string): string | undefined { - if (!isFileId(fileId)) return undefined; - return this.storage.pathFor(this.scope, this.keyFor(fileId, ext)); - } - - async resolveDisplayPath(fileId: string): Promise<string | undefined> { - if (!isFileId(fileId)) return undefined; - const key = await this.findKey(fileId); - if (key === undefined) return undefined; - return this.storage.pathFor(this.scope, key); - } - - async read( - fileId: string, - ): Promise<{ readonly data: Uint8Array; readonly name: string } | undefined> { - if (!isFileId(fileId)) return undefined; - const key = await this.findKey(fileId); - if (key === undefined) return undefined; - const data = await this.storage.read(this.scope, key); - return data === undefined ? undefined : { data, name: key }; - } - - async open(fileId: string): Promise<SessionMediaFile | undefined> { - if (!isFileId(fileId)) return undefined; - const storedMetadata = await this.documents.get<unknown>(this.scope, this.metadataKey(fileId)); - const metadata = this.isMetadataFor(storedMetadata, fileId) ? storedMetadata : undefined; - const key = - metadata !== undefined && (await this.storage.size(this.scope, metadata.key)) !== undefined - ? metadata.key - : await this.findKey(fileId); - if (key === undefined) return undefined; - const size = await this.storage.size(this.scope, key); - if (size === undefined) return undefined; - return { - path: this.storage.pathFor(this.scope, key), - name: metadata?.name ?? key, - mediaType: metadata?.mediaType ?? this.mediaTypeForKey(key), - size, - stream: (range) => this.storage.readStream(this.scope, key, range), - }; - } - - async materialize(input: SessionMediaMaterializeInput): Promise<string | undefined> { - if (!isFileId(input.fileId)) return undefined; - const ext = extname(input.name) || (mediaExtensionForMime(input.mimeType) ?? '.bin'); - const key = this.keyFor(input.fileId, ext); - const existingSize = await this.storage.size(this.scope, key); - if (existingSize !== input.size) { - const source = input.stream() as NodeJS.ReadableStream & AsyncIterable<Uint8Array>; - await this.storage.writeStream(this.scope, key, source, { - atomic: true, - signal: input.signal, - }); - } - await this.documents.set(this.scope, this.metadataKey(input.fileId), { - version: 1, - key, - name: input.name, - mediaType: input.mimeType, - }); - return this.storage.pathFor(this.scope, key); - } - - private keyFor(fileId: string, ext: string): string { - return `${fileId}${ext}`; - } - - private metadataKey(fileId: string): string { - return `meta/${fileId}.json`; - } - - private isMetadataFor(value: unknown, fileId: string): value is SessionMediaMetadata { - if (typeof value !== 'object' || value === null) return false; - const candidate = value as Partial<SessionMediaMetadata>; - return ( - candidate.version === 1 && - typeof candidate.key === 'string' && - (candidate.key === fileId || candidate.key.startsWith(`${fileId}.`)) && - !candidate.key.includes('/') && - !candidate.key.includes('\\') && - typeof candidate.name === 'string' && - candidate.name.length > 0 && - typeof candidate.mediaType === 'string' && - candidate.mediaType.length > 0 - ); - } - - private mediaTypeForKey(key: string): string { - const ext = extname(key).toLowerCase(); - return ( - IMAGE_MIME_BY_SUFFIX[ext] ?? - VIDEO_MIME_BY_SUFFIX[ext] ?? - AUDIO_MIME_BY_SUFFIX[ext] ?? - 'application/octet-stream' - ); - } - - private async findKey(fileId: string): Promise<string | undefined> { - const keys = await this.storage.list(this.scope, fileId); - return keys.find( - (key) => - key === fileId || (key.startsWith(`${fileId}.`) && !key.includes('.tmp.')), - ); - } -} - -registerScopedService( - LifecycleScope.Session, - ISessionMediaStore, - SessionMediaStoreService, - ScopeActivation.OnScopeCreated, - 'media', -); diff --git a/packages/agent-core-v2/src/agent/media/videoResolver.ts b/packages/agent-core-v2/src/agent/media/videoResolver.ts new file mode 100644 index 000000000..efbdefb8e --- /dev/null +++ b/packages/agent-core-v2/src/agent/media/videoResolver.ts @@ -0,0 +1,27 @@ +/** + * `media` domain — request-time video reference resolver contract. + * + * Rewrites the `kimi-file://` video references a prompt carries in the + * projected wire messages into a provider-acceptable form (an uploaded + * `ms://` reference, an inline base64 `data:` part, or a `<video path>` text + * tag) right before the messages reach the provider — so a `kimi-file://` url + * never touches the wire. Bound at Agent scope. + */ + +import { createDecorator } from '#/_base/di/instantiation'; +import type { Message } from '#/kosong/contract/message'; +import type { ModelRequester } from '#/kosong/model/modelRequester'; + +export interface IAgentVideoResolverService { + readonly _serviceBrand: undefined; + + resolve( + messages: readonly Message[], + requester: ModelRequester, + signal?: AbortSignal, + ): Promise<readonly Message[]>; +} + +export const IAgentVideoResolverService = createDecorator<IAgentVideoResolverService>( + 'agentVideoResolverService', +); diff --git a/packages/agent-core-v2/src/agent/media/videoResolverService.ts b/packages/agent-core-v2/src/agent/media/videoResolverService.ts new file mode 100644 index 000000000..1aafe624d --- /dev/null +++ b/packages/agent-core-v2/src/agent/media/videoResolverService.ts @@ -0,0 +1,245 @@ +/** + * `media` domain — `IAgentVideoResolverService` implementation. + * + * Resolves each `kimi-file://` video reference in the projected wire messages + * to a provider-acceptable part right before the request leaves for the wire. + * Reads the uploaded bytes through the `file` domain (`IFileService`), uploads + * them through the bound model's `ModelRequester.uploadVideo` (wrapped for + * `video_upload` telemetry through `createVideoUploader`), and persists the + * `(file, provider) → llmFileId` mapping through the `blobStore` + * access-pattern store so the upload happens once across a turn's steps, + * retries, and media-recovery reprojections. Falls back to an inline base64 + * `video_url` (protocols that carry it) or a `<video path>` text tag (the + * model then opens the edge-materialized copy with `ReadMediaFile`); auth + * failures surface so they drive credential refresh instead of masking a bad + * token, and an upload interrupted by the step's aborted signal re-throws — + * shape-agnostic, since abort rejections vary by provider — so cancellation + * ends the request instead of memoizing a degraded fallback for the rest of + * the agent's lifetime. Resolution outcomes are memoized per (file, provider) + * for step/retry stability — except a transient upload failure, which + * degrades only the current request to the tag form so a later step retries + * the upload instead of freezing the fallback. The plain-data state + * (`resolved`) is registered into `agentState` (`IAgentStateService`) and + * read/written through it. Bound at Agent scope. + */ + +import { createHash } from 'node:crypto'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { IFileService } from '#/app/file/fileService'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import type { ContentPart, Message } from '#/kosong/contract/message'; +import type { ModelRequester } from '#/kosong/model/modelRequester'; +import { IBlobStore } from '#/persistence/interface/blobStore'; + +import { detectFileType, MEDIA_SNIFF_BYTES } from './file-type'; +import { type KimiFileRef, isKimiFileUrl, parseKimiFileUrl } from './kimiFileUrl'; +import { createVideoUploader } from './registerMediaTools'; +import { + inlineVideoPart, + inlineVideoSupportedForProtocol, + isVideoUploadAuthError, + isVideoUploadUnsupportedError, +} from './videoUpload'; +import { IAgentVideoResolverService } from './videoResolver'; + +const CACHE_SCOPE = 'video-upload-cache'; +const PROVIDER_ID_RE = /^[A-Za-z0-9][A-Za-z0-9._-]*$/; +const VIDEO_UNAVAILABLE_TEXT = + '[video omitted: the uploaded file is no longer available]'; + +const textEncoder = new TextEncoder(); +const textDecoder = new TextDecoder(); + +export const mediaResolvedKey = defineState<Map<string, ContentPart>>( + 'media.resolved', + () => new Map(), +); + +export class AgentVideoResolverService implements IAgentVideoResolverService { + declare readonly _serviceBrand: undefined; + + constructor( + @IFileService private readonly files: IFileService, + @IBlobStore private readonly blobs: IBlobStore, + @ITelemetryService private readonly telemetry: ITelemetryService, + @IAgentStateService private readonly states: IAgentStateService, + ) { + this.states.register(mediaResolvedKey); + } + + private get resolved(): Map<string, ContentPart> { + return this.states.get(mediaResolvedKey); + } + + async resolve( + messages: readonly Message[], + requester: ModelRequester, + signal?: AbortSignal, + ): Promise<readonly Message[]> { + if (!messages.some(hasKimiFileVideoPart)) return messages; + + let changed = false; + const out: Message[] = []; + for (const message of messages) { + if (!hasKimiFileVideoPart(message)) { + out.push(message); + continue; + } + const content: ContentPart[] = []; + for (const part of message.content) { + const ref = + part.type === 'video_url' ? parseKimiFileUrl(part.videoUrl.url) : undefined; + content.push(ref === undefined ? part : await this.resolvePart(ref, requester, signal)); + } + out.push({ ...message, content }); + changed = true; + } + return changed ? out : messages; + } + + private async resolvePart( + ref: KimiFileRef, + requester: ModelRequester, + signal: AbortSignal | undefined, + ): Promise<ContentPart> { + const model = requester.model; + const providerKey = model.providerType ?? model.protocol; + const cacheKey = `${ref.fileId}\0${providerKey}`; + + const memoed = this.resolved.get(cacheKey); + if (memoed !== undefined) return memoed; + + const { part, memoize } = await this.resolveUncached(ref, requester, cacheKey, signal); + if (memoize) this.resolved.set(cacheKey, part); + return part; + } + + private async resolveUncached( + ref: KimiFileRef, + requester: ModelRequester, + cacheKey: string, + signal: AbortSignal | undefined, + ): Promise<{ part: ContentPart; memoize: boolean }> { + const cachedLlmFileId = await this.readCachedUpload(cacheKey); + if (cachedLlmFileId !== undefined) { + return { + part: { type: 'video_url', videoUrl: { url: `ms://${cachedLlmFileId}`, id: cachedLlmFileId } }, + memoize: true, + }; + } + + let bytes: Buffer; + let filename: string; + try { + const file = await this.files.get(ref.fileId); + bytes = await readStream(file.stream()); + filename = file.meta.name; + } catch { + return { part: tag(ref), memoize: true }; + } + + const fileType = detectFileType(filename, bytes.subarray(0, MEDIA_SNIFF_BYTES), 'media'); + if (fileType.kind !== 'video') return { part: tag(ref), memoize: true }; + const mimeType = fileType.mimeType; + + const model = requester.model; + if (!model.capabilities.video_in) return { part: tag(ref), memoize: true }; + const inlineSupported = inlineVideoSupportedForProtocol(model.protocol); + + const uploader = createVideoUploader(requester, { + client: this.telemetry, + props: { + model: model.name, + provider_type: model.providerType ?? model.protocol, + protocol: model.protocol, + }, + }); + if (uploader === undefined) { + return { + part: inlineSupported ? inlineVideoPart(bytes, mimeType) : tag(ref), + memoize: true, + }; + } + + try { + const uploaded = await uploader({ data: bytes, mimeType, filename }, { signal }); + const llmFileId = uploaded.videoUrl.id ?? msFileIdFromUrl(uploaded.videoUrl.url); + if (llmFileId !== undefined) await this.writeCachedUpload(cacheKey, llmFileId); + return { part: uploaded, memoize: true }; + } catch (error) { + if (signal?.aborted) throw error; + if (isVideoUploadAuthError(error)) throw error; + if (isVideoUploadUnsupportedError(error)) { + return { + part: inlineSupported ? inlineVideoPart(bytes, mimeType) : tag(ref), + memoize: true, + }; + } + return { part: tag(ref), memoize: false }; + } + } + + private async readCachedUpload(cacheKey: string): Promise<string | undefined> { + const data = await this.blobs.get(CACHE_SCOPE, blobKey(cacheKey)).catch(() => undefined); + if (data === undefined) return undefined; + const llmFileId = textDecoder.decode(data); + return PROVIDER_ID_RE.test(llmFileId) ? llmFileId : undefined; + } + + private async writeCachedUpload(cacheKey: string, llmFileId: string): Promise<void> { + if (!PROVIDER_ID_RE.test(llmFileId)) return; + await this.blobs.put(CACHE_SCOPE, blobKey(cacheKey), textEncoder.encode(llmFileId)).catch( + () => undefined, + ); + } +} + +function hasKimiFileVideoPart(message: Message): boolean { + return message.content.some( + (part) => part.type === 'video_url' && isKimiFileUrl(part.videoUrl.url), + ); +} + +function tag(ref: KimiFileRef): ContentPart { + if (ref.path === undefined || ref.path.length === 0) { + return { type: 'text', text: VIDEO_UNAVAILABLE_TEXT }; + } + return { type: 'text', text: `<video path="${escapeAttribute(ref.path)}"></video>` }; +} + +function msFileIdFromUrl(url: string): string | undefined { + if (!url.startsWith('ms://')) return undefined; + const id = url.slice('ms://'.length); + return id.length > 0 ? id : undefined; +} + +function blobKey(cacheKey: string): string { + return createHash('sha256').update(cacheKey).digest('hex'); +} + +async function readStream(stream: NodeJS.ReadableStream): Promise<Buffer> { + const chunks: Buffer[] = []; + for await (const chunk of stream) { + chunks.push(Buffer.from(chunk as string | Uint8Array)); + } + return Buffer.concat(chunks); +} + +function escapeAttribute(value: string): string { + return value + .replaceAll('&', '&') + .replaceAll('"', '"') + .replaceAll('<', '<') + .replaceAll('>', '>'); +} + +registerScopedService( + LifecycleScope.Agent, + IAgentVideoResolverService, + AgentVideoResolverService, + ScopeActivation.OnScopeCreated, + 'media', +); diff --git a/packages/agent-core-v2/src/agent/media/videoUpload.ts b/packages/agent-core-v2/src/agent/media/videoUpload.ts index dfda40592..2a17bab2a 100644 --- a/packages/agent-core-v2/src/agent/media/videoUpload.ts +++ b/packages/agent-core-v2/src/agent/media/videoUpload.ts @@ -1,3 +1,12 @@ +/** + * `media` domain — shared video-upload fallback helpers. + * + * The provider video-upload attempt and its graceful fallbacks must agree on + * which failures are auth failures (surfaced, never masked into a fallback) + * and which protocols carry inline `video_url` on the wire. Pure helpers; no + * scoped service. + */ + import { VideoUploadUnsupportedError } from '#/kosong/contract/errors'; import type { VideoURLPart } from '#/kosong/contract/message'; import type { Protocol } from '#/kosong/protocol/protocol'; diff --git a/packages/agent-core-v2/src/agent/media/webp-dec-wasm.ts b/packages/agent-core-v2/src/agent/media/webp-dec-wasm.ts index e793f5076..e6280c4f7 100644 --- a/packages/agent-core-v2/src/agent/media/webp-dec-wasm.ts +++ b/packages/agent-core-v2/src/agent/media/webp-dec-wasm.ts @@ -1,2 +1,6 @@ +// GENERATED FILE — do not edit by hand. +// WebP decoder wasm from @jsquash/webp@1.5.0 (codec/dec/webp_dec.wasm), +// base64-encoded so the bundled CLI needs no on-disk wasm asset. + export const WEBP_DECODER_WASM_BASE64 = 'AGFzbQEAAAABhQESYAF/AGAEf39/fwBgBX9/f39/AGACf38AYAF/AX9gAn9/AX9gA39/fwF/YAZ/f39/f38Bf2AJf39/f39/f39/AGADf39/AGAAAGAHf39/f39/fwBgBn9/f39/fwBgBH9/f38Bf2AFf39/f38Bf2AAAX9gCH9/f39/f39/AX9gBH9/fn4AAm0SAWEBYQAJAWEBYgACAWEBYwALAWEBZAAAAWEBZQAEAWEBZgAJAWEBZwADAWEBaAANAWEBaQAAAWEBagAKAWEBawAJAWEBbAACAWEBbQADAWEBbgAJAWEBbwALAWEBcAAEAWEBcQAJAWEBcgADA54BnAEABQYGBAUFBgsNDQAFCwMDBA4EAAACDgIHAwoFCQUDCwYEEBEACQQBBQAECg0CAQEBAQEBAQEBAQEBAQEBAQcDAQEBAAYGBgICAgICAgIFBgUDAwAABgYGBQUFAgICAgICAggICAgICAgEBAQAAAQEBAwCAQECDAYGAA8KBAAAAAAAAAQAAAAAAAAAAAAAAwAAAAAAAAAAAwMFAwoEBQFwAXd3BQcBAYACgIACBggBfwFB8OcECwckCAFzAgABdAAsAXUAFgF2ABIBdwCOAQF4AI0BAXkBAAF6AIIBCacBAQBBAQt2rQGrAaABlQGMAX9+VXx9e1BPTk1MS0pJSEdGRURDQmZlZGOsAS+qAakBqAGnAaYBpQGkAaMBogGhAZ8BngGdAZwBmwGaAZkBmAGXAZYBlAGTAZIBkQGQAY8BiwEzenl4d3Z1dHNycXBvbm1sa2ppaGdiYWBfXl1cW1pZWFdWVFNSUT08JTs7igE2gAE2JYkBgwGEAYUBJYgBhwGGATwlgQEK0N8HnAHuCwEHfwJAIABFDQAgAEEIayICIABBBGsoAgAiAUF4cSIAaiEFAkAgAUEBcQ0AIAFBA3FFDQEgAiACKAIAIgFrIgJBsNsAKAIASQ0BIAAgAWohAEG02wAoAgAgAkcEQCABQf8BTQRAIAFBA3YhASACKAIMIgMgAigCCCIERgRAQaDbAEGg2wAoAgBBfiABd3E2AgAMAwsgBCADNgIMIAMgBDYCCAwCCyACKAIYIQYCQCACIAIoAgwiAUcEQCACKAIIIgMgATYCDCABIAM2AggMAQsCQCACQRRqIgQoAgAiAw0AIAJBEGoiBCgCACIDDQBBACEBDAELA0AgBCEHIAMiAUEUaiIEKAIAIgMNACABQRBqIQQgASgCECIDDQALIAdBADYCAAsgBkUNAQJAIAIoAhwiBEECdEHQ3QBqIgMoAgAgAkYEQCADIAE2AgAgAQ0BQaTbAEGk2wAoAgBBfiAEd3E2AgAMAwsgBkEQQRQgBigCECACRhtqIAE2AgAgAUUNAgsgASAGNgIYIAIoAhAiAwRAIAEgAzYCECADIAE2AhgLIAIoAhQiA0UNASABIAM2AhQgAyABNgIYDAELIAUoAgQiAUEDcUEDRw0AQajbACAANgIAIAUgAUF+cTYCBCACIABBAXI2AgQgACACaiAANgIADwsgAiAFTw0AIAUoAgQiAUEBcUUNAAJAIAFBAnFFBEBBuNsAKAIAIAVGBEBBuNsAIAI2AgBBrNsAQazbACgCACAAaiIANgIAIAIgAEEBcjYCBCACQbTbACgCAEcNA0Go2wBBADYCAEG02wBBADYCAA8LQbTbACgCACAFRgRAQbTbACACNgIAQajbAEGo2wAoAgAgAGoiADYCACACIABBAXI2AgQgACACaiAANgIADwsgAUF4cSAAaiEAAkAgAUH/AU0EQCABQQN2IQEgBSgCDCIDIAUoAggiBEYEQEGg2wBBoNsAKAIAQX4gAXdxNgIADAILIAQgAzYCDCADIAQ2AggMAQsgBSgCGCEGAkAgBSAFKAIMIgFHBEBBsNsAKAIAGiAFKAIIIgMgATYCDCABIAM2AggMAQsCQCAFQRRqIgQoAgAiAw0AIAVBEGoiBCgCACIDDQBBACEBDAELA0AgBCEHIAMiAUEUaiIEKAIAIgMNACABQRBqIQQgASgCECIDDQALIAdBADYCAAsgBkUNAAJAIAUoAhwiBEECdEHQ3QBqIgMoAgAgBUYEQCADIAE2AgAgAQ0BQaTbAEGk2wAoAgBBfiAEd3E2AgAMAgsgBkEQQRQgBigCECAFRhtqIAE2AgAgAUUNAQsgASAGNgIYIAUoAhAiAwRAIAEgAzYCECADIAE2AhgLIAUoAhQiA0UNACABIAM2AhQgAyABNgIYCyACIABBAXI2AgQgACACaiAANgIAIAJBtNsAKAIARw0BQajbACAANgIADwsgBSABQX5xNgIEIAIgAEEBcjYCBCAAIAJqIAA2AgALIABB/wFNBEAgAEF4cUHI2wBqIQECf0Gg2wAoAgAiA0EBIABBA3Z0IgBxRQRAQaDbACAAIANyNgIAIAEMAQsgASgCCAshACABIAI2AgggACACNgIMIAIgATYCDCACIAA2AggPC0EfIQQgAEH///8HTQRAIABBJiAAQQh2ZyIBa3ZBAXEgAUEBdGtBPmohBAsgAiAENgIcIAJCADcCECAEQQJ0QdDdAGohBwJAAkACQEGk2wAoAgAiA0EBIAR0IgFxRQRAQaTbACABIANyNgIAIAcgAjYCACACIAc2AhgMAQsgAEEZIARBAXZrQQAgBEEfRxt0IQQgBygCACEBA0AgASIDKAIEQXhxIABGDQIgBEEddiEBIARBAXQhBCADIAFBBHFqIgdBEGooAgAiAQ0ACyAHIAI2AhAgAiADNgIYCyACIAI2AgwgAiACNgIIDAELIAMoAggiACACNgIMIAMgAjYCCCACQQA2AhggAiADNgIMIAIgADYCCAtBwNsAQcDbACgCAEEBayIAQX8gABs2AgALC9cCAQh/IAAoAgAhBCAAKAIIIQIgACgCBCEGA0ACQCACQQBODQAgACgCDCIFIAAoAhRJBEAgBSgAACEDIAAgBUEDajYCDCAAIARBGHQgA0EIdkGA/gNxIANBGHQgA0GA/gNxQQh0cnJBCHZyIgQ2AgAgAkEYaiECDAELIAAoAhAgBUsEQCAAIAVBAWo2AgwgACACQQhqIgI2AgggACAFLQAAIARBCHRyIgQ2AgAMAQsgACgCGARAQQAhAgwBCyAAQQE2AhggACAEQQh0IgQ2AgAgAkEIaiECCyABQQFrIQUgACACAn8gBCACdiIIIAZBAXZB////B3EiA0sEQCAAIANBf3MgAnQgBGoiBDYCACAGIANrDAELIANBAWoLIgZnQRhzIglrIgI2AgggACAGIAl0QQFrIgY2AgQgAyAISSAFdCAHciEHIAFBAUshAyAFIQEgAw0ACyAHC4AEAQN/IAJBgARPBEAgACABIAIQECAADwsgACACaiEDAkAgACABc0EDcUUEQAJAIABBA3FFBEAgACECDAELIAJFBEAgACECDAELIAAhAgNAIAIgAS0AADoAACABQQFqIQEgAkEBaiICQQNxRQ0BIAIgA0kNAAsLAkAgA0F8cSIEQcAASQ0AIAIgBEFAaiIFSw0AA0AgAiABKAIANgIAIAIgASgCBDYCBCACIAEoAgg2AgggAiABKAIMNgIMIAIgASgCEDYCECACIAEoAhQ2AhQgAiABKAIYNgIYIAIgASgCHDYCHCACIAEoAiA2AiAgAiABKAIkNgIkIAIgASgCKDYCKCACIAEoAiw2AiwgAiABKAIwNgIwIAIgASgCNDYCNCACIAEoAjg2AjggAiABKAI8NgI8IAFBQGshASACQUBrIgIgBU0NAAsLIAIgBE8NAQNAIAIgASgCADYCACABQQRqIQEgAkEEaiICIARJDQALDAELIANBBEkEQCAAIQIMAQsgACADQQRrIgRLBEAgACECDAELIAAhAgNAIAIgAS0AADoAACACIAEtAAE6AAEgAiABLQACOgACIAIgAS0AAzoAAyABQQRqIQEgAkEEaiICIARNDQALCyACIANJBEADQCACIAEtAAA6AAAgAUEBaiEBIAJBAWoiAiADRw0ACwsgAAvyAgICfwF+AkAgAkUNACAAIAE6AAAgACACaiIDQQFrIAE6AAAgAkEDSQ0AIAAgAToAAiAAIAE6AAEgA0EDayABOgAAIANBAmsgAToAACACQQdJDQAgACABOgADIANBBGsgAToAACACQQlJDQAgAEEAIABrQQNxIgRqIgMgAUH/AXFBgYKECGwiATYCACADIAIgBGtBfHEiBGoiAkEEayABNgIAIARBCUkNACADIAE2AgggAyABNgIEIAJBCGsgATYCACACQQxrIAE2AgAgBEEZSQ0AIAMgATYCGCADIAE2AhQgAyABNgIQIAMgATYCDCACQRBrIAE2AgAgAkEUayABNgIAIAJBGGsgATYCACACQRxrIAE2AgAgBCADQQRxQRhyIgRrIgJBIEkNACABrUKBgICAEH4hBSADIARqIQEDQCABIAU3AxggASAFNwMQIAEgBTcDCCABIAU3AwAgAUEgaiEBIAJBIGsiAkEfSw0ACwsgAAuXKQELfyMAQRBrIgskAAJAAkACQAJAAkACQAJAAkACQCAAQfQBTQRAQaDbACgCACIGQRAgAEELakF4cSAAQQtJGyIFQQN2IgB2IgFBA3EEQAJAIAFBf3NBAXEgAGoiAkEDdCIBQcjbAGoiACABQdDbAGooAgAiASgCCCIERgRAQaDbACAGQX4gAndxNgIADAELIAQgADYCDCAAIAQ2AggLIAFBCGohACABIAJBA3QiAkEDcjYCBCABIAJqIgEgASgCBEEBcjYCBAwKCyAFQajbACgCACIHTQ0BIAEEQAJAQQIgAHQiAkEAIAJrciABIAB0cSIAQQAgAGtxaCIBQQN0IgBByNsAaiICIABB0NsAaigCACIAKAIIIgRGBEBBoNsAIAZBfiABd3EiBjYCAAwBCyAEIAI2AgwgAiAENgIICyAAIAVBA3I2AgQgACAFaiIIIAFBA3QiASAFayIEQQFyNgIEIAAgAWogBDYCACAHBEAgB0F4cUHI2wBqIQFBtNsAKAIAIQICfyAGQQEgB0EDdnQiA3FFBEBBoNsAIAMgBnI2AgAgAQwBCyABKAIICyEDIAEgAjYCCCADIAI2AgwgAiABNgIMIAIgAzYCCAsgAEEIaiEAQbTbACAINgIAQajbACAENgIADAoLQaTbACgCACIKRQ0BIApBACAKa3FoQQJ0QdDdAGooAgAiAigCBEF4cSAFayEDIAIhAQNAAkAgASgCECIARQRAIAEoAhQiAEUNAQsgACgCBEF4cSAFayIBIAMgASADSSIBGyEDIAAgAiABGyECIAAhAQwBCwsgAigCGCEJIAIgAigCDCIERwRAQbDbACgCABogAigCCCIAIAQ2AgwgBCAANgIIDAkLIAJBFGoiASgCACIARQRAIAIoAhAiAEUNAyACQRBqIQELA0AgASEIIAAiBEEUaiIBKAIAIgANACAEQRBqIQEgBCgCECIADQALIAhBADYCAAwIC0F/IQUgAEG/f0sNACAAQQtqIgBBeHEhBUGk2wAoAgAiCEUNAEEAIAVrIQMCQAJAAkACf0EAIAVBgAJJDQAaQR8gBUH///8HSw0AGiAFQSYgAEEIdmciAGt2QQFxIABBAXRrQT5qCyIHQQJ0QdDdAGooAgAiAUUEQEEAIQAMAQtBACEAIAVBGSAHQQF2a0EAIAdBH0cbdCECA0ACQCABKAIEQXhxIAVrIgYgA08NACABIQQgBiIDDQBBACEDIAEhAAwDCyAAIAEoAhQiBiAGIAEgAkEddkEEcWooAhAiAUYbIAAgBhshACACQQF0IQIgAQ0ACwsgACAEckUEQEEAIQRBAiAHdCIAQQAgAGtyIAhxIgBFDQMgAEEAIABrcWhBAnRB0N0AaigCACEACyAARQ0BCwNAIAAoAgRBeHEgBWsiAiADSSEBIAIgAyABGyEDIAAgBCABGyEEIAAoAhAiAQR/IAEFIAAoAhQLIgANAAsLIARFDQAgA0Go2wAoAgAgBWtPDQAgBCgCGCEHIAQgBCgCDCICRwRAQbDbACgCABogBCgCCCIAIAI2AgwgAiAANgIIDAcLIARBFGoiASgCACIARQRAIAQoAhAiAEUNAyAEQRBqIQELA0AgASEGIAAiAkEUaiIBKAIAIgANACACQRBqIQEgAigCECIADQALIAZBADYCAAwGCyAFQajbACgCACIETQRAQbTbACgCACEAAkAgBCAFayIBQRBPBEAgACAFaiICIAFBAXI2AgQgACAEaiABNgIAIAAgBUEDcjYCBAwBCyAAIARBA3I2AgQgACAEaiIBIAEoAgRBAXI2AgRBACECQQAhAQtBqNsAIAE2AgBBtNsAIAI2AgAgAEEIaiEADAgLIAVBrNsAKAIAIgJJBEBBrNsAIAIgBWsiATYCAEG42wBBuNsAKAIAIgAgBWoiAjYCACACIAFBAXI2AgQgACAFQQNyNgIEIABBCGohAAwIC0EAIQAgBUEvaiIDAn9B+N4AKAIABEBBgN8AKAIADAELQYTfAEJ/NwIAQfzeAEKAoICAgIAENwIAQfjeACALQQxqQXBxQdiq1aoFczYCAEGM3wBBADYCAEHc3gBBADYCAEGAIAsiAWoiBkEAIAFrIghxIgEgBU0NB0HY3gAoAgAiBARAQdDeACgCACIHIAFqIgkgB00NCCAEIAlJDQgLAkBB3N4ALQAAQQRxRQRAAkACQAJAAkBBuNsAKAIAIgQEQEHg3gAhAANAIAQgACgCACIHTwRAIAcgACgCBGogBEsNAwsgACgCCCIADQALC0EAECIiAkF/Rg0DIAEhBkH83gAoAgAiAEEBayIEIAJxBEAgASACayACIARqQQAgAGtxaiEGCyAFIAZPDQNB2N4AKAIAIgAEQEHQ3gAoAgAiBCAGaiIIIARNDQQgACAISQ0ECyAGECIiACACRw0BDAULIAYgAmsgCHEiBhAiIgIgACgCACAAKAIEakYNASACIQALIABBf0YNASAGIAVBMGpPBEAgACECDAQLQYDfACgCACICIAMgBmtqQQAgAmtxIgIQIkF/Rg0BIAIgBmohBiAAIQIMAwsgAkF/Rw0CC0Hc3gBB3N4AKAIAQQRyNgIACyABECIhAkEAECIhACACQX9GDQUgAEF/Rg0FIAAgAk0NBSAAIAJrIgYgBUEoak0NBQtB0N4AQdDeACgCACAGaiIANgIAQdTeACgCACAASQRAQdTeACAANgIACwJAQbjbACgCACIDBEBB4N4AIQADQCACIAAoAgAiASAAKAIEIgRqRg0CIAAoAggiAA0ACwwEC0Gw2wAoAgAiAEEAIAAgAk0bRQRAQbDbACACNgIAC0EAIQBB5N4AIAY2AgBB4N4AIAI2AgBBwNsAQX82AgBBxNsAQfjeACgCADYCAEHs3gBBADYCAANAIABBA3QiAUHQ2wBqIAFByNsAaiIENgIAIAFB1NsAaiAENgIAIABBAWoiAEEgRw0AC0Gs2wAgBkEoayIAQXggAmtBB3FBACACQQhqQQdxGyIBayIENgIAQbjbACABIAJqIgE2AgAgASAEQQFyNgIEIAAgAmpBKDYCBEG82wBBiN8AKAIANgIADAQLIAAtAAxBCHENAiABIANLDQIgAiADTQ0CIAAgBCAGajYCBEG42wAgA0F4IANrQQdxQQAgA0EIakEHcRsiAGoiATYCAEGs2wBBrNsAKAIAIAZqIgIgAGsiADYCACABIABBAXI2AgQgAiADakEoNgIEQbzbAEGI3wAoAgA2AgAMAwtBACEEDAULQQAhAgwDC0Gw2wAoAgAgAksEQEGw2wAgAjYCAAsgAiAGaiEBQeDeACEAAkACQAJAAkACQAJAA0AgASAAKAIARwRAIAAoAggiAA0BDAILCyAALQAMQQhxRQ0BC0Hg3gAhAANAIAMgACgCACIBTwRAIAEgACgCBGoiBCADSw0DCyAAKAIIIQAMAAsACyAAIAI2AgAgACAAKAIEIAZqNgIEIAJBeCACa0EHcUEAIAJBCGpBB3EbaiIHIAVBA3I2AgQgAUF4IAFrQQdxQQAgAUEIakEHcRtqIgYgBSAHaiIFayEAIAMgBkYEQEG42wAgBTYCAEGs2wBBrNsAKAIAIABqIgA2AgAgBSAAQQFyNgIEDAMLQbTbACgCACAGRgRAQbTbACAFNgIAQajbAEGo2wAoAgAgAGoiADYCACAFIABBAXI2AgQgACAFaiAANgIADAMLIAYoAgQiA0EDcUEBRgRAIANBeHEhCQJAIANB/wFNBEAgBigCDCIBIAYoAggiAkYEQEGg2wBBoNsAKAIAQX4gA0EDdndxNgIADAILIAIgATYCDCABIAI2AggMAQsgBigCGCEIAkAgBiAGKAIMIgJHBEAgBigCCCIBIAI2AgwgAiABNgIIDAELAkAgBkEUaiIDKAIAIgENACAGQRBqIgMoAgAiAQ0AQQAhAgwBCwNAIAMhBCABIgJBFGoiAygCACIBDQAgAkEQaiEDIAIoAhAiAQ0ACyAEQQA2AgALIAhFDQACQCAGKAIcIgFBAnRB0N0AaiIEKAIAIAZGBEAgBCACNgIAIAINAUGk2wBBpNsAKAIAQX4gAXdxNgIADAILIAhBEEEUIAgoAhAgBkYbaiACNgIAIAJFDQELIAIgCDYCGCAGKAIQIgEEQCACIAE2AhAgASACNgIYCyAGKAIUIgFFDQAgAiABNgIUIAEgAjYCGAsgBiAJaiIGKAIEIQMgACAJaiEACyAGIANBfnE2AgQgBSAAQQFyNgIEIAAgBWogADYCACAAQf8BTQRAIABBeHFByNsAaiEBAn9BoNsAKAIAIgJBASAAQQN2dCIAcUUEQEGg2wAgACACcjYCACABDAELIAEoAggLIQAgASAFNgIIIAAgBTYCDCAFIAE2AgwgBSAANgIIDAMLQR8hAyAAQf///wdNBEAgAEEmIABBCHZnIgFrdkEBcSABQQF0a0E+aiEDCyAFIAM2AhwgBUIANwIQIANBAnRB0N0AaiEBAkBBpNsAKAIAIgJBASADdCIEcUUEQEGk2wAgAiAEcjYCACABIAU2AgAMAQsgAEEZIANBAXZrQQAgA0EfRxt0IQMgASgCACECA0AgAiIBKAIEQXhxIABGDQMgA0EddiECIANBAXQhAyABIAJBBHFqIgQoAhAiAg0ACyAEIAU2AhALIAUgATYCGCAFIAU2AgwgBSAFNgIIDAILQazbACAGQShrIgBBeCACa0EHcUEAIAJBCGpBB3EbIgFrIgg2AgBBuNsAIAEgAmoiATYCACABIAhBAXI2AgQgACACakEoNgIEQbzbAEGI3wAoAgA2AgAgAyAEQScgBGtBB3FBACAEQSdrQQdxG2pBL2siACAAIANBEGpJGyIBQRs2AgQgAUHo3gApAgA3AhAgAUHg3gApAgA3AghB6N4AIAFBCGo2AgBB5N4AIAY2AgBB4N4AIAI2AgBB7N4AQQA2AgAgAUEYaiEAA0AgAEEHNgIEIABBCGohAiAAQQRqIQAgAiAESQ0ACyABIANGDQMgASABKAIEQX5xNgIEIAMgASADayICQQFyNgIEIAEgAjYCACACQf8BTQRAIAJBeHFByNsAaiEAAn9BoNsAKAIAIgFBASACQQN2dCICcUUEQEGg2wAgASACcjYCACAADAELIAAoAggLIQEgACADNgIIIAEgAzYCDCADIAA2AgwgAyABNgIIDAQLQR8hACACQf///wdNBEAgAkEmIAJBCHZnIgBrdkEBcSAAQQF0a0E+aiEACyADIAA2AhwgA0IANwIQIABBAnRB0N0AaiEBAkBBpNsAKAIAIgRBASAAdCIGcUUEQEGk2wAgBCAGcjYCACABIAM2AgAMAQsgAkEZIABBAXZrQQAgAEEfRxt0IQAgASgCACEEA0AgBCIBKAIEQXhxIAJGDQQgAEEddiEEIABBAXQhACABIARBBHFqIgYoAhAiBA0ACyAGIAM2AhALIAMgATYCGCADIAM2AgwgAyADNgIIDAMLIAEoAggiACAFNgIMIAEgBTYCCCAFQQA2AhggBSABNgIMIAUgADYCCAsgB0EIaiEADAULIAEoAggiACADNgIMIAEgAzYCCCADQQA2AhggAyABNgIMIAMgADYCCAtBrNsAKAIAIgAgBU0NAEGs2wAgACAFayIBNgIAQbjbAEG42wAoAgAiACAFaiICNgIAIAIgAUEBcjYCBCAAIAVBA3I2AgQgAEEIaiEADAMLQdDiAEEwNgIAQQAhAAwCCwJAIAdFDQACQCAEKAIcIgBBAnRB0N0AaiIBKAIAIARGBEAgASACNgIAIAINAUGk2wAgCEF+IAB3cSIINgIADAILIAdBEEEUIAcoAhAgBEYbaiACNgIAIAJFDQELIAIgBzYCGCAEKAIQIgAEQCACIAA2AhAgACACNgIYCyAEKAIUIgBFDQAgAiAANgIUIAAgAjYCGAsCQCADQQ9NBEAgBCADIAVqIgBBA3I2AgQgACAEaiIAIAAoAgRBAXI2AgQMAQsgBCAFQQNyNgIEIAQgBWoiAiADQQFyNgIEIAIgA2ogAzYCACADQf8BTQRAIANBeHFByNsAaiEAAn9BoNsAKAIAIgFBASADQQN2dCIDcUUEQEGg2wAgASADcjYCACAADAELIAAoAggLIQEgACACNgIIIAEgAjYCDCACIAA2AgwgAiABNgIIDAELQR8hACADQf///wdNBEAgA0EmIANBCHZnIgBrdkEBcSAAQQF0a0E+aiEACyACIAA2AhwgAkIANwIQIABBAnRB0N0AaiEBAkACQCAIQQEgAHQiBnFFBEBBpNsAIAYgCHI2AgAgASACNgIADAELIANBGSAAQQF2a0EAIABBH0cbdCEAIAEoAgAhBQNAIAUiASgCBEF4cSADRg0CIABBHXYhBiAAQQF0IQAgASAGQQRxaiIGKAIQIgUNAAsgBiACNgIQCyACIAE2AhggAiACNgIMIAIgAjYCCAwBCyABKAIIIgAgAjYCDCABIAI2AgggAkEANgIYIAIgATYCDCACIAA2AggLIARBCGohAAwBCwJAIAlFDQACQCACKAIcIgBBAnRB0N0AaiIBKAIAIAJGBEAgASAENgIAIAQNAUGk2wAgCkF+IAB3cTYCAAwCCyAJQRBBFCAJKAIQIAJGG2ogBDYCACAERQ0BCyAEIAk2AhggAigCECIABEAgBCAANgIQIAAgBDYCGAsgAigCFCIARQ0AIAQgADYCFCAAIAQ2AhgLAkAgA0EPTQRAIAIgAyAFaiIAQQNyNgIEIAAgAmoiACAAKAIEQQFyNgIEDAELIAIgBUEDcjYCBCACIAVqIgQgA0EBcjYCBCADIARqIAM2AgAgBwRAIAdBeHFByNsAaiEAQbTbACgCACEBAn9BASAHQQN2dCIFIAZxRQRAQaDbACAFIAZyNgIAIAAMAQsgACgCCAshBiAAIAE2AgggBiABNgIMIAEgADYCDCABIAY2AggLQbTbACAENgIAQajbACADNgIACyACQQhqIQALIAtBEGokACAAC7wCAQV/IAAgARATIQUgACgCACECIAAoAgQhBgJAIAAoAggiAUEATg0AIAAoAgwiAyAAKAIUSQRAIAMoAAAhBCAAIANBA2o2AgwgACACQRh0IARBCHZBgP4DcSAEQRh0IARBgP4DcUEIdHJyQQh2ciICNgIAIAFBGGohAQwBCyAAKAIQIANLBEAgACADQQFqNgIMIAAgAUEIaiIBNgIIIAAgAy0AACACQQh0ciICNgIADAELIAAoAhgEQEEAIQEMAQsgAEEBNgIYIAAgAkEIdCICNgIAIAFBCGohAQsgACABAn8gAiABdiIEIAZBAXZB////B3EiA0sEQCAAIANBf3MgAXQgAmo2AgAgBiADawwBCyADQQFqCyICZ0EYcyIBazYCCCAAIAIgAXRBAWs2AgRBACAFayAFIAMgBEkbC10BA39BBCECAn8gACABckEDcUUEQEEAIAAoAgAgASgCAEYNARoLAkADQCAALQAAIgMgAS0AACIERw0BIAFBAWohASAAQQFqIQAgAkEBayICDQALQQAPCyADIARrCwt0AQF/IAJFBEAgACgCBCABKAIERg8LIAAgAUYEQEEBDwsgASgCBCICLQAAIQECQCAAKAIEIgMtAAAiAEUNACAAIAFHDQADQCACLQABIQEgAy0AASIARQ0BIAJBAWohAiADQQFqIQMgACABRg0ACwsgACABRgv/AwERfyABQQNsIQ5BACABayEPIAFBfWwhEEEAIAFBAnRrIRFBACABQQF0IhJrIRMgBEEBdEEBciEUA0AgAyEEAkAgACATaiIKLQAAIgggACABaiIMLQAAIgtrIhVB78kAai0AACAAIA9qIg0tAAAiAyAALQAAIglrQe/JAGotAABBAnRqIBRKDQAgACARai0AACAAIBBqLQAAIgdrQe/JAGotAAAgBUoNACAHIAhrQe/JAGotAAAgBUoNACAIIANrQe/JAGotAAAiFiAFSg0AIAAgDmotAAAgACASai0AACIHa0HvyQBqLQAAIAVKDQAgByALa0HvyQBqLQAAIAVKDQAgCyAJa0HvyQBqLQAAIhcgBUoNACAJIANrQQNsIQcCfyAGIBZOIAYgF05xRQRAIA0gAyAHIBVB/DdqLAAAaiIDQQNqQQN1QfDAAGosAABqQe/DAGotAAA6AAAgACEMIAkgA0EEakEDdUHwwABqLAAAawwBCyAKIAggB0EEakEDdUHwwABqLAAAIghBAWpBAXUiCmpB78MAai0AADoAACANIAdBA2pBA3VB8MAAaiwAACADakHvwwBqLQAAOgAAIAAgCSAIa0HvwwBqLQAAOgAAIAsgCmsLIQMgDCADQe/DAGotAAA6AAALIARBAWshAyAAIAJqIQAgBEEBSw0ACwv0AQEHfwJAIAFBAEwNACAAQUBrIQYDQCAGKAIAIAAoAjhIBEAgACgCGEEATA0CCyAAKAIEBEAgACAAKQJMQiCJNwJMCyAAIAJBhOEAQYDhACAAKAIAGygCABEDAAJAIAAoAgQNACAAKAI0IAAoAghsQQBMDQAgACgCTCEHIAAoAlAhCEEAIQUDQCAHIAVBAnQiCWoiCiAKKAIAIAggCWooAgBqNgIAIAVBAWoiBSAAKAI0IAAoAghsSA0ACwsgACAAKAI8QQFqNgI8IAAgACgCGCAAKAIgazYCGCACIANqIQIgBEEBaiIEIAFHDQALIAEhBAsgBAvqGAIPfwN+IwBB0AxrIg8kAAJAIAEoAjBFBEAgASABKAIsIgVBAWoiBDYCLCABKQMYIhMgBUE/ca2Ip0EBcSEIIAVBB0gNASABKAIoIgYgASgCJCIMIAYgDEsbIQkgBiEFA0AgBSAJRwRAIAEgE0IIiCITNwMYIAEoAiAgBWoxAAAhFCABIARBCGsiBzYCLCABIAVBAWoiBTYCKCABIBRCOIYgE4QiEzcDGCAEQQ9KIQsgByEEIAsNAQwDCwsgBiAMSw0BIARBwQBJDQELIAFCgICAgBA3AiwLQQAhCSACQQAgAEECdBAVIQwCQAJAAkACQAJAAkACQCAIBEAgASgCMEUEQCABIAEoAiwiAkEBaiIENgIsIAEpAxgiEyACQT9xrYinQQFxIQkgAkEHSARAIAQhBwwDCyABKAIoIgIgASgCJCIGIAIgBksbIQggAiEFA0AgBSAIRwRAIAEgE0IIiCITNwMYIAEoAiAgBWoxAAAhFCABIARBCGsiBzYCLCABIAVBAWoiBTYCKCABIBRCOIYgE4QiEzcDGCAEQQ9KIQsgByEEIAsNAQwECwsgAiAGSwRAIAQhBwwDCyAEIgdBwQBJDQILIAFBATYCMAwCCyAPQQBBzAAQFSELQQAhCAJAIAEoAjBFBEAgASABKAIsIgJBBGoiBDYCLCABKQMYIhMgAkE/ca2Ip0EPcSEIIAJBBEgNASABKAIoIgIgASgCJCIHIAIgB0sbIQogAiEFAkADQCAFIApGDQEgASATQgiIIhM3AxggASgCICAFajEAACEUIAEgBEEIayIGNgIsIAEgBUEBaiIFNgIoIAEgFEI4hiAThCITNwMYIARBD0ohDSAGIQQgDQ0ACwwCCyACIAdLDQEgBEHBAEkNAQtBASEJIAFBATYCMEEAIQQLIAhBA2ohDUEAIQUDQCAFIQdBACECAkAgCUUEQCABIARBA2oiBjYCLCABKQMYIhMgBEE/ca2Ip0EHcSECQQAhCSAEQQVIBEAgBiEEDAILIAEoAigiCCABKAIkIgogCCAKSxshDiAIIQUgBiEEAkADQCAFIA5GDQEgASATQgiIIhM3AxggASgCICAFajEAACEUIAEgBEEIayIGNgIsIAEgBUEBaiIFNgIoIAEgFEI4hiAThCITNwMYIARBD0ohECAGIQQgEA0ACwwCCyAIIApLDQEgBEHBAEkNAQsgAUKAgICAEDcCLEEBIQlBACEECyALIAdB0C5qLQAAQQJ0aiACNgIAIAdBAWohBSAHIA1HDQALIAtB0ABqQQcgC0ETIAtB0ARqEChFDQUCQCABKAIwBEAgAUKAgICAEDcCLCAAIQIMAQsgASABKAIsIgJBAWoiBDYCLCABKQMYIhMgAkE/ca2Ip0EBcSEGAkACQAJAAkACQAJAIAJBB0gEQCAEIQcMAQsgASgCKCICIAEoAiQiCCACIAhLGyEJIAIhBQNAIAUgCUcEQCABIBNCCIgiEzcDGCABKAIgIAVqMQAAIRQgASAEQQhrIgc2AiwgASAFQQFqIgU2AiggASAUQjiGIBOEIhM3AxggBEEPSiEKIAchBCAKDQEMAgsLIAIgCEsEQCAEIQcMAQsgBCIHQcAASw0BCyAAIQIgBkUNBSABIAdBA2oiBDYCLCABKQMYIRQgB0EFSARAIAQhBgwDCyABKAIoIgIgASgCJCIIIAIgCEsbIQkgFCETIAIhBQNAIAUgCUcEQCABIBNCCIgiEzcDGCABKAIgIAVqMQAAIRUgASAEQQhrIgY2AiwgASAFQQFqIgU2AiggASAVQjiGIBOEIhM3AxggBEEPSiEKIAYhBCAKDQEMBAsLIAIgCEsEQCAEIQYMAwsgBCIGQcEASQ0CDAELIAFCgICAgBA3AiwgACECIAZFDQQLIAFBATYCMEEAIQgMAQsgASAGIBQgB0E/ca2Ip0EHcUEBdEECaiICaiIENgIsIAJBAnRB8MsAaigCACABKQMYIhMgBkE/ca2Ip3EhCCAEQQhIDQEgASgCKCICIAEoAiQiByACIAdLGyEJIAIhBQNAIAUgCUcEQCABIBNCCIgiEzcDGCABKAIgIAVqMQAAIRQgASAEQQhrIgY2AiwgASAFQQFqIgU2AiggASAUQjiGIBOEIhM3AxggBEEPSiEKIAYhBCAKDQEMAwsLIAIgB0sNASAEQcEASQ0BCyABQoCAgIAQNwIsCyAIQQJqIgIgAEoNBgsgAEEATA0EQQghCkEAIQcDQCACRQ0FAkAgASgCLCIEQSBIBEAgBCEGDAELIAEoAigiBSABKAIkIgYgBSAGSxshCANAAkAgBSAIRgRAIAQhBgwBCyABIAEpAxhCCIgiEzcDGCABKAIgIAVqMQAAIRQgASAEQQhrIgY2AiwgASAFQQFqIgU2AiggASAUQjiGIBOENwMYIARBD0ohCSAGIQQgCQ0BCwsgASgCMEUEQCABKAIoIAEoAiRHDQEgBkHBAEgNAQsgAUEBNgIwQQAhBgsgASAGIAtB0ABqIAEpAxgiEyAGQT9xrYinQf8AcUECdGoiBC0AAGoiBTYCLAJAIAQvAQIiCUEPTQRAIAwgB0ECdGogCTYCACAJIAogCRshCiAHQQFqIQcMAQsgCUHWLmotAAAhEEEAIQ0CQCABKAIwRQRAIAEgBSAJQdMuai0AACIGaiIENgIsIAZBAnRB8MsAaigCACATIAVBP3GtiKdxIQ0gBEEISA0BIAEoAigiBiABKAIkIg4gBiAOSxshESAGIQUDQCAFIBFHBEAgASATQgiIIhM3AxggASgCICAFajEAACEUIAEgBEEIayIINgIsIAEgBUEBaiIFNgIoIAEgFEI4hiAThCITNwMYIARBD0ohEiAIIQQgEg0BDAMLCyAGIA5LDQEgBEHBAEkNAQsgAUKAgICAEDcCLAsgDSAQaiIIIAdqIgUgAEoNByAIQQBMDQAgCkEAIAlBEEYbIQZBACEEIAhBB3EiCQRAA0AgDCAHQQJ0aiAGNgIAIAdBAWohByAEQQFqIgQgCUcNAAsLIAhBAWtBB08EQANAIAwgB0ECdGoiBCAGNgIAIAQgBjYCHCAEIAY2AhggBCAGNgIUIAQgBjYCECAEIAY2AgwgBCAGNgIIIAQgBjYCBCAHQQhqIgcgBUcNAAsLIAUhBwsgAkEBayECIAAgB0oNAAsMBAsgASAHQQFqIgQ2AiwgASkDGCEUAkAgB0EHSARAIAQhBgwBCyABKAIoIgIgASgCJCIIIAIgCEsbIQsgFCETIAIhBQNAIAUgC0cEQCABIBNCCIgiEzcDGCABKAIgIAVqMQAAIRUgASAEQQhrIgY2AiwgASAFQQFqIgU2AiggASAVQjiGIBOEIhM3AxggBEEPSiEKIAYhBCAKDQEMAgsLIAIgCEsEQCAEIQYMAQsgBCIGQcAASw0BCyABQSxqIgIgBkEIQQEgFCAHQT9xrYinQQFxGyIFaiIENgIAIAVBAnRB8MsAaigCACABKQMYIhMgBkE/ca2Ip3EhCCAEQQhIDQIgASgCKCIGIAEoAiQiCyAGIAtLGyEKIAYhBQNAIAUgCkcEQCABIBNCCIgiEzcDGCABKAIgIAVqMQAAIRQgASAEQQhrIgc2AiwgASAFQQFqIgU2AiggASAUQjiGIBOEIhM3AxggBEEPSiENIAchBCANDQEMBAsLIAYgC0sNAiAEQcEASQ0CIAFBATYCMAwBCyABQQE2AjAgAUEsaiECQQAhCAsgAkEANgIACyAMIAhBAnRqQQE2AgAgCUUNAEEAIQgCQCABKAIwRQRAIAEgASgCLCICQQhqIgQ2AiwgASkDGCITIAJBP3GtiKdB/wFxIQggAkEASA0BIAEoAigiAiABKAIkIgcgAiAHSxshCSACIQUDQCAFIAlHBEAgASATQgiIIhM3AxggASgCICAFajEAACEUIAEgBEEIayIGNgIsIAEgBUEBaiIFNgIoIAEgFEI4hiAThCITNwMYIARBD0ohCyAGIQQgCw0BDAMLCyACIAdLDQEgBEHBAEkNAQsgAUKAgICAEDcCLAsgDCAIQQJ0akEBNgIACyABKAIwDQACQCADRQRAQQBBCCAMIABBABAoIQUMAQsgAEGABEwEQCADQQggDCAAIA9B0ARqECghBQwBCyAAQYCA/v8DSw0BIABBAXQQFiICRQ0BIANBCCAMIAAgAhAoIQUgAhASCyAFDQELIAFBAzYCAEEAIQULIA9B0AxqJAAgBQvjAQECfyAAKAKgARASIAAoAqwBEBIgACgCqAEiAQRAIAEQEgsgACgCfBASQQAhASAAQQA2AnwgACgCiAEQEiAAQgA3AqgBIABCADcCoAEgAEIANwKYASAAQgA3ApABIABCADcCiAEgAEIANwKAASAAQgA3AnggACgCEBASIABBADYCECAAKAKwAUEASgRAA0AgACABQRRsaiICQcQBaigCABASIAJBADYCxAEgAUEBaiIBIAAoArABSA0ACwsgAEEANgKEAiAAQQA2ArABIAAoAogCEBIgAEEANgIMIABBADYCiAILWgIBfwF+AkACf0EAIABFDQAaIACtIAGtfiIDpyICIAAgAXJBgIAESQ0AGkF/IAIgA0IgiKcbCyICEBYiAEUNACAAQQRrLQAAQQNxRQ0AIABBACACEBUaCyAAC6kEARR/IAFBA2whD0EAIAFrIRAgAUF9bCERQQAgAUECdGshEkEAIAFBAXQiE2shFCAEQQF0QQFyIRUDQCADIQQCQCAAIBRqIhYtAAAiCCAAIAFqIhctAAAiC2siB0HvyQBqLQAAIAAgEGoiDC0AACIDIAAtAAAiCWtB78kAai0AAEECdGogFUoNACAAIBJqLQAAIAAgEWoiGC0AACIKa0HvyQBqLQAAIAVKDQAgCiAIa0HvyQBqLQAAIAVKDQAgCCADa0HvyQBqLQAAIhkgBUoNACAAIA9qLQAAIAAgE2oiDS0AACIOa0HvyQBqLQAAIAVKDQAgDiALa0HvyQBqLQAAIAVKDQAgCyAJa0HvyQBqLQAAIhogBUoNACAHQfw3aiwAACAJIANrQQNsaiEHAn8gBiAZTiAGIBpOcUUEQCAMIAdBA2pBA3VB8MAAaiwAACADakHvwwBqLQAAOgAAIAAhDSAJIAdBBGpBA3VB8MAAaiwAAGsMAQsgGCAKIAdB/DdqLAAAIgdBCWxBP2pBB3UiCmpB78MAai0AADoAACAWIAggB0ESbEE/akEHdSIIakHvwwBqLQAAOgAAIAwgAyAHQRtsQT9qQQd1IgNqQe/DAGotAAA6AAAgACAJIANrQe/DAGotAAA6AAAgFyALIAhrQe/DAGotAAA6AAAgDiAKawshAyANIANB78MAai0AADoAAAsgBEEBayEDIAAgAmohACAEQQFLDQALC70EAQF/IAFB/wEgAMFBBGpBA3UiACABLQAAaiICQQAgAkEAShsiAiACQf8BThs6AAAgAUH/ASAAIAEtAAFqIgJBACACQQBKGyICIAJB/wFOGzoAASABQf8BIAAgAS0AAmoiAkEAIAJBAEobIgIgAkH/AU4bOgACIAFB/wEgACABLQADaiICQQAgAkEAShsiAiACQf8BThs6AAMgAUH/ASAAIAEtACBqIgJBACACQQBKGyICIAJB/wFOGzoAICABQf8BIAAgAS0AIWoiAkEAIAJBAEobIgIgAkH/AU4bOgAhIAFB/wEgACABLQAiaiICQQAgAkEAShsiAiACQf8BThs6ACIgAUH/ASAAIAEtACNqIgJBACACQQBKGyICIAJB/wFOGzoAIyABQf8BIAAgAS0AQGoiAkEAIAJBAEobIgIgAkH/AU4bOgBAIAFB/wEgACABLQBBaiICQQAgAkEAShsiAiACQf8BThs6AEEgAUH/ASAAIAEtAEJqIgJBACACQQBKGyICIAJB/wFOGzoAQiABQf8BIAAgAS0AQ2oiAkEAIAJBAEobIgIgAkH/AU4bOgBDIAFB/wEgACABLQBgaiICQQAgAkEAShsiAiACQf8BThs6AGAgAUH/ASAAIAEtAGFqIgJBACACQQBKGyICIAJB/wFOGzoAYSABQf8BIAAgAS0AYmoiAkEAIAJBAEobIgIgAkH/AU4bOgBiIAFB/wEgACABLQBjaiIAQQAgAEEAShsiACAAQf8BThs6AGMLkAoBHn8gAUH/ASABLQAAIAAuAQoiA0H7nAFsQRB1IANqIAAuARoiBUGMlQJsQRB1aiIRIAAuARIiCCAALgECIg5qIhJqIgJB+5wBbEEQdSACaiAALgEOIgZB+5wBbEEQdSAGaiAALgEeIgdBjJUCbEEQdWoiEyAALgEWIg8gAC4BBiIJaiIUaiIEQYyVAmxBEHVqIhUgAC4BCCIKQfucAWxBEHUgCmogAC4BGCILQYyVAmxBEHVqIhYgAC4BECIXIAAuAQAiGGoiGWpBBGoiGiAALgEMIgxB+5wBbEEQdSAMaiAALgEcIg1BjJUCbEEQdWoiGyAALgEUIhwgAC4BBCIdaiIeaiIAaiIfakEDdWoiEEEAIBBBAEobIhAgEEH/AU4bOgAAIAFB/wEgAS0AASACQYyVAmxBEHUgBCAEQfucAWxBEHVqayICIBogAGsiAGpBA3VqIgRBACAEQQBKGyIEIARB/wFOGzoAASABQf8BIAEtAAIgACACa0EDdWoiAEEAIABBAEobIgAgAEH/AU4bOgACIAFB/wEgAS0AAyAfIBVrQQN1aiIAQQAgAEEAShsiACAAQf8BThs6AAMgAUH/ASABLQAgIANBjJUCbEEQdSAFIAVB+5wBbEEQdWprIgUgDiAIayICaiIAQfucAWxBEHUgAGogBkGMlQJsQRB1IAcgB0H7nAFsQRB1amsiBiAJIA9rIgdqIgNBjJUCbEEQdWoiBCAKQYyVAmxBEHUgCyALQfucAWxBEHVqayIKIBggF2siC2pBBGoiCCAMQYyVAmxBEHUgDSANQfucAWxBEHVqayIMIB0gHGsiDWoiDmoiD2pBA3VqIglBACAJQQBKGyIJIAlB/wFOGzoAICABQf8BIAEtACEgAEGMlQJsQRB1IAMgA0H7nAFsQRB1amsiACAIIA5rIgNqQQN1aiIIQQAgCEEAShsiCCAIQf8BThs6ACEgAUH/ASABLQAiIAMgAGtBA3VqIgBBACAAQQBKGyIAIABB/wFOGzoAIiABQf8BIAEtACMgDyAEa0EDdWoiAEEAIABBAEobIgAgAEH/AU4bOgAjIAFB/wEgAS0AQCACIAVrIgBB+5wBbEEQdSAAaiAHIAZrIgNBjJUCbEEQdWoiBSALIAprQQRqIgIgDSAMayIGaiIHakEDdWoiBEEAIARBAEobIgQgBEH/AU4bOgBAIAFB/wEgAS0AQSAAQYyVAmxBEHUgAyADQfucAWxBEHVqayIAIAIgBmsiA2pBA3VqIgJBACACQQBKGyICIAJB/wFOGzoAQSABQf8BIAEtAEIgAyAAa0EDdWoiAEEAIABBAEobIgAgAEH/AU4bOgBCIAFB/wEgAS0AQyAHIAVrQQN1aiIAQQAgAEEAShsiACAAQf8BThs6AEMgAUH/ASABLQBgIBIgEWsiAEH7nAFsQRB1IABqIBQgE2siA0GMlQJsQRB1aiIFIBkgFmtBBGoiAiAeIBtrIgZqIgdqQQN1aiIEQQAgBEEAShsiBCAEQf8BThs6AGAgAUH/ASABLQBhIABBjJUCbEEQdSADIANB+5wBbEEQdWprIgAgAiAGayIDakEDdWoiAkEAIAJBAEobIgIgAkH/AU4bOgBhIAFB/wEgAS0AYiADIABrQQN1aiIAQQAgAEEAShsiACAAQf8BThs6AGIgAUH/ASABLQBjIAcgBWtBA3VqIgBBACAAQQBKGyIAIABB/wFOGzoAYwtSAQJ/QfDaACgCACIBIABBB2pBeHEiAmohAAJAIAJBACAAIAFNGw0AIAA/AEEQdEsEQCAAEA9FDQELQfDaACAANgIAIAEPC0HQ4gBBMDYCAEF/C60nAiB/An4jAEEQayIZJAAgA0EwaiEVAkACfwJAAkACQAJAAkACfwJAAkACQCACBEADQAJAAkACQAJAAkAgAygCMARAIANCgICAgBA3AiwMAQsgAyADKAIsIgVBAWoiBzYCLCADKQMYIiUgBUE/ca2Ip0EBcSEKAkACQCAFQQdIBEAgByEIDAELIAMoAigiBSADKAIkIgkgBSAJSxshCyAFIQYDQCAGIAtHBEAgAyAlQgiIIiU3AxggAygCICAGajEAACEmIAMgB0EIayIINgIsIAMgBkEBaiIGNgIoIAMgJkI4hiAlhCIlNwMYIAdBD0ohDCAIIQcgDA0BDAILCyAFIAlLBEAgByEIDAELIAciCEHAAEsNAQsgCg0DIANBLGohCiADQTBqIRUMCAsgA0KAgICAEDcCLCAKDQELIANBLGohCiADQTBqIRUMBwsgAygCsAEhCUEAIQoMAQsgAyAIQQJqIgc2AiwgAykDGCIlIAhBP3GtiKdBA3EhCiADKAKwASEJQQEhCyAIQQZIDQEgAygCKCIFIAMoAiQiDCAFIAxLGyENIAUhBgJAA0AgBiANRg0BIAMgJUIIiCIlNwMYIAMoAiAgBmoxAAAhJiADIAdBCGsiCDYCLCADIAZBAWoiBjYCKCADICZCOIYgJYQiJTcDGCAHQQ9KIQ4gCCEHIA4NAAsMAgsgBSAMSw0BIAdBwQBJDQELIANCgICAgBA3AixBACELQQAhBwtBAyEMIAMoAoQCIgVBASAKdCIGcQ0JIAMgBSAGcjYChAIgAyAJQRRsaiINQcQBaiIWQQA2AgAgDSABNgLAASANIAA2ArwBIA0gCjYCtAFBASEOIAMgCUEBajYCsAECQAJAAkAgCg4EAAACAQILQQAhCQJAIAsEQCADIAdBA2oiCDYCLCADKQMYIiUgB0E/ca2Ip0EHcSEJIAdBBUgNASADKAIoIgcgAygCJCIKIAcgCksbIQsgByEGA0AgBiALRwRAIAMgJUIIiCIlNwMYIAMoAiAgBmoxAAAhJiADIAhBCGsiBTYCLCADIAZBAWoiBjYCKCADICZCOIYgJYQiJTcDGCAIQQ9KIQ4gBSEIIA4NAQwDCwsgByAKSw0BIAhBwQBJDQELIANCgICAgBA3AiwLIA0gCUECaiIHNgK4ASAAQXwgCXRBf3MiBWogB3YgASAFaiAHdkEAIAMgFhAjIQ4MAQtBACEJAkAgCwRAIAMgB0EIaiIINgIsIAMpAxgiJSAHQT9xrYinQf8BcSEJIAdBAEgNASADKAIoIgcgAygCJCIKIAcgCksbIQsgByEGA0AgBiALRwRAIAMgJUIIiCIlNwMYIAMoAiAgBmoxAAAhJiADIAhBCGsiBTYCLCADIAZBAWoiBjYCKCADICZCOIYgJYQiJTcDGCAIQQ9KIQ8gBSEIIA8NAQwDCwsgByAKSw0BIAhBwQBJDQELIANCgICAgBA3AiwLIAlBAWohByANAn9BACAJQQ9KDQAaQQEgCUEDSg0AGkEDQQIgCUECSBsLIgs2ArgBIAdBAUEAIAMgFhAjRQ0KQQRBCCANKAK4AXZ0Ig0QFiIFRQ0KIABBASALdGohDyAFIBYoAgAiCCgCADYCAAJAIAlBAEwEQEEEIQAMAQtBBSAHQQJ0IgAgAEEFTBsiAEH8D3FBBmshCUEAIQdBBCEGA0AgBSAGaiIKIApBBGstAAAgBiAIai0AAGo6AAAgBSAGQQFyIhBqIApBA2stAAAgCCAQai0AAGo6AAAgBkECaiEGIAcgCUYhECAHQQJqIQcgEEUNAAsgAEEBcUUNACAFIAZqIApBAmstAAAgBiAIai0AAGo6AAALIAAgDUkEQCAAIAVqQQAgDSAAaxAVGgsgD0EBayALdiEAIAgQEiAWIAU2AgALIA4NAAwJCwALIANBLGohCiADKAIwDQELIAMgAygCLCIFQQFqIgc2AiwgAykDGCIlIAVBP3GtiKdBAXEhCQJAAkACQAJAAkACQCAFQQdIBEAgByEFDAELIAMoAigiCCADKAIkIgsgCCALSxshDCAIIQYDQCAGIAxHBEAgAyAlQgiIIiU3AxggAygCICAGajEAACEmIAMgB0EIayIFNgIsIAMgBkEBaiIGNgIoIAMgJkI4hiAlhCIlNwMYIAdBD0ohDSAFIQcgDQ0BDAILCyAIIAtLBEAgByEFDAELIAciBUHAAEsNAQtBACEKIAkNASAFIQdBACEQDAQLIBVBATYCAEEAIRAgCkEANgIAIAlFDQUgA0EsaiEODAELIANBLGoiDiAFQQRqIgc2AgAgAykDGCIlIAVBP3GtiKdBD3EhECAFQQRIDQEgAygCKCIFIAMoAiQiCSAFIAlLGyELIAUhBgJAA0AgBiALRg0BIAMgJUIIiCIlNwMYIAMoAiAgBmoxAAAhJiADIAdBCGsiCDYCLCADIAZBAWoiBjYCKCADICZCOIYgJYQiJTcDGCAHQQ9KIQwgCCEHIAwNAAsMAgsgBSAJSw0BIAdBwQBJDQELQQEhCiAVQQE2AgBBACEHIA5BADYCAAtBAyEMIBBBAWtBCksNBwsgGUEANgIMQQEhDCAQQQF0QbAuai8BACEIIAJFBEBBASEKDAQLIANBLGogCg0CGiADIAdBAWoiBTYCLCADKQMYIiUgB0E/ca2Ip0EBcSEJAkACQAJAAkACQCAHQQdIBEAgBSEHDAELIAMoAigiCiADKAIkIgsgCiALSxshDSAKIQYDQCAGIA1HBEAgAyAlQgiIIiU3AxggAygCICAGajEAACEmIAMgBUEIayIHNgIsIAMgBkEBaiIGNgIoIAMgJkI4hiAlhCIlNwMYIAVBD0ohDiAHIQUgDg0BDAILCyAKIAtLBEAgBSEHDAELIAUiB0HAAEsNAQsgCQ0BQQEhCgwHCyAVQQE2AgAgA0EANgIsIAlFBEBBASEKDAcLIANBLGohC0EAIQkMAQsgA0EsaiILIAdBA2oiBTYCACADKQMYIiUgB0E/ca2Ip0EHcSEJIAdBBUgNASADKAIoIgcgAygCJCIMIAcgDEsbIQ0gByEGA0AgBiANRwRAIAMgJUIIiCIlNwMYIAMoAiAgBmoxAAAhJiADIAVBCGsiCjYCLCADIAZBAWoiBjYCKCADICZCOIYgJYQiJTcDGCAFQQ9KIQ4gCiEFIA4NAQwDCwsgByAMSw0BIAVBwQBJDQELIBVBATYCACALQQA2AgALQQAhBwJAIABBBCAJdCIGakEBayAJQQJqIgV2IgogASAGakEBayAFdiIGQQAgAyAZQQxqECNFBEBBASEGDAELIAMgBTYCmAFBASEMAkAgBiAKbCIFQQBKBEBBACEGIBkoAgwhCgJAIAVBAUcEQCAFQQFxIQ0gBUF+cSEOA0AgCiAGQQJ0IgtqIgkgCS8AASIJNgIAIAogC0EEcmoiCyALLwABIgs2AgAgDCAJQQFqIAkgDEgbIgkgC0EBaiAJIAtKGyEMIAZBAmoiBiAORw0ACyANRQ0BCyAKIAZBAnRqIgYgBi8AASIGNgIAIAwgBkEBaiAGIAxIGyEMCyAMQegHSg0BIAwgACABbEoNASAMIQoMBgsgACABbEEATA0AQQEhCgwFCyAMQQJ0IgYQFiISRQRAQQEhBiADQQE2AgAMAQsgEkH/ASAGEBUhCiAFQQBMBEBBACEKDAULIBkoAgwhC0EAIQYCQCAFQQFGDQAgBUEBcSENIAVBfnEhDgNAIAogCyAGQQJ0IhZqIg8oAgBBAnRqIgUoAgAiCUF/RwR/IAcFIAUgBzYCACAHIQkgB0EBagshBSAPIAk2AgAgCiALIBZBBHJqIhYoAgBBAnRqIgcoAgAiCUF/RwR/IAUFIAcgBTYCACAFIQkgBUEBagshByAWIAk2AgAgBkECaiIGIA5HDQALIA0NACAHIQoMBQsgCiALIAZBAnRqIgUoAgBBAnRqIgooAgAiBkF/RwR/IAcFIAogBzYCACAHIQYgB0EBagshCiAFIAY2AgAMBAtBACESDAQLIBVBATYCACAKQQA2AgALQQAhECAZQQA2AgwgAkUEQEEBIQxBihchCEEBIQoMAgtBihchCCADQSxqCyEJQQEhDCAVQQE2AgAgCUEANgIAQQEhCgsgFSgCAARAQQAhB0EBIQYMAQtBACENQYACQQEgEHRBmAJqQZgCIBAbIh0gHUGAAkwbQQQQHiEHAkAgCCAKbCIFBEAgBaxCgICAgPz///8/g0IAUg0BIAVBgID//wFLDQELIAVBAnQQFiENCwJAIAoEQCAKrEKkBH5C/////w9WDQEgCkG2lu8BSw0BCyAKQaQEbBAWIhxFDQAgB0UNACANRQ0AIB1BAWsiBUF8cSEiIAVBA3EhISAdQQVrQXxxQQVqIRZBACEOIA0hCwNAIA4hBgJAAkAgEkUNACASIA5BAnRqKAIAIgZBf0cNAEEBIQYgHSADIAdBABAcRQ0FQYACIAMgB0EAEBxFDQVBgAIgAyAHQQAQHEUNBUGAAiADIAdBABAcRQ0FQSggAyAHQQAQHA0BDAULIBwgBkGkBGxqIg8gCzYCACAdIAMgByALEBwiGkUEQEEBIQYMBQsgBygCACEGIAstAAAhF0EAIQlBASEIA0AgByAIQQJ0aiIFKAIMIhMgBSgCCCIRIAUoAgQiGCAFKAIAIgUgBiAFIAZKGyIFIAUgGEgbIgUgBSARSBsiBSAFIBNIGyEGIAhBBGohCCAJQQRqIgkgIkcNAAtBACEIIBYhBSAhBEADQCAHIAVBAnRqKAIAIgkgBiAGIAlIGyEGIAVBAWohBSAIQQFqIgggIUcNAAsLIA8gCyAaQQJ0aiIaNgIEQYACIAMgByAaEBwiE0UEQEEBIQYMBQsgFyAaLQAAIhFqIRggBygCACEIQQEhCQNAIAcgCUECdGoiBSgCECIXIAUoAgwiFCAFKAIIIhsgBSgCBCIeIAUoAgAiBSAIIAUgCEobIgUgBSAeSBsiBSAFIBtIGyIFIAUgFEgbIgUgBSAXSBshCCAJQQVqIglBgAJHDQALIA8gGiATQQJ0aiIXNgIIQYACIAMgByAXEBwiCUUEQEEBIQYMBQsgBiAIaiEUIBggFy0AACIbaiEYIAcoAgAhBUEBIQgDQCAHIAhBAnRqIgYoAhAiEyAGKAIMIh4gBigCCCIfIAYoAgQiICAGKAIAIgYgBSAFIAZIGyIFIAUgIEgbIgUgBSAfSBsiBSAFIB5IGyIFIAUgE0gbIQUgCEEFaiIIQYACRw0ACyAPIBcgCUECdGoiEzYCDEGAAiADIAcgExAcIglFBEBBASEGDAULIAUgFGohFCAYIBMtAAAiHmohGCAHKAIAIQVBASEIA0AgByAIQQJ0aiIGKAIQIh8gBigCDCIgIAYoAggiIyAGKAIEIiQgBigCACIGIAUgBSAGSBsiBSAFICRIGyIFIAUgI0gbIgUgBSAgSBsiBSAFIB9IGyEFIAhBBWoiCEGAAkcNAAsgDyATIAlBAnRqIgY2AhBBKCADIAcgBhAcIghFBEBBASEGDAULAkACQCAeIBEgG3JyBEAgD0EANgIcIA9BADYCFCAGIAhBAnRqIQkMAQsgBi0AACERIA9BADYCHCAPQQE2AhQgDyAXLwECIBovAQJBEHRyIBMvAQJBGHRyIhs2AhggBiAIQQJ0aiEJIBhBACARa0cNACALLwECIgZB/wFLDQAgD0EBNgIcIA8gBkEIdCAbcjYCGCAPQQA2AiAMAQsgDyAFIBRqIgVBBkg2AiBBACEGIAVBBUoNAANAIAsgBkECdGooAQAiEUH/AXEhBSARQRB2IQggDyAGQQN0aiIYIBFBgICACE8EfyAFQYACcgUgGiAGIAV2IhFBAnRqIhQvAQJBEHQgCEEIdHIgFyARIBQtAAAiEXYiCEECdGoiFC8BAnIgEyAIIBQtAAAiFHZBAnRqIhsvAQJBGHRyIQggGy0AACAFIBFqIBRqags2AiQgGCAINgIoIAZBAWoiBkHAAEcNAAsLIAkhCwsgDkEBaiIOIAxHDQALIBkoAgwhBSADIA02AqwBIAMgHDYCqAEgAyAKNgKkASADIAU2AqABQQAhBgwCC0EBIQYgA0EBNgIADAELQQAhDQsgBxASIBIQEiAGBEAgGSgCDBASIA0QEiAcBEAgHBASC0EDIQwMAQtBASEMAkAgEARAIANBASAQdCIHNgJ4IAMgB0EEEB4iBzYCfCAHRQ0CIAMgEDYChAEgA0EgIBBrNgKAAQwBCyADQQA2AngLIAMgATYCaCADIAA2AmQgA0F/IAMoApgBIgd0QX9zQX8gBxs2ApQBIAMgAEEBIAd0akEBayAHdjYCnAECQCACBEAgA0EBNgIEQQAhBgwBCyAArCABrH4iJUIAUgRAICVCgICAgPz///8/g0IAUg0CICVCgID//wFWDQILICWnQQJ0EBYiBkUEQAwCCyADIAYgACABIAFBABAqRQ0CIBUoAgANAgsgBARAIAQgBjYCAAsgA0EANgJwQQEiBiACRQ0CGgwDCyADIAw2AgBBACEGCyAGEBJBAAshBiADKAKgARASIAMoAqwBEBIgAygCqAEiAARAIAAQEgsgAygCfBASIANBADYCfCADKAKIARASIANCADcCqAEgA0IANwKgASADQgA3ApgBIANCADcCkAEgA0IANwKIASADQgA3AoABIANCADcCeAsgGUEQaiQAIAYL9AEBBX8CQCAAQUBrIgQoAgAgACgCOE4NACAAKAIYIQEDQCABQQBKDQFBiOEAIQECQAJAIAAoAgQNAEGM4QAhASAAKAIUDQAgACgCNCAAKAIIbEEATA0BIAAoAkwhA0EAIQEDQCAAKAJEIAFqIAMgAUECdCIFaigCADoAACAAKAJMIgMgBWpBADYCACABQQFqIgEgACgCNCAAKAIIbEgNAAsMAQsgACABKAIAEQAACyAAIAAoAhggACgCHGoiATYCGCAAIAAoAkQgACgCSGo2AkQgBCAEKAIAQQFqIgM2AgAgAkEBaiECIAMgACgCOEgNAAsLIAILBgAgABASC+gBAQJ/QeDnAC0AAEUEQAJ/A0AgAUHg4gBqLQAARQRAIAFB4OIAakEBOgAAIAFBAnRB4OMAakEANgIAQeTnACABNgIAQQAMAgsgAUEBaiIBQYABRw0AC0EGCwRAEAkAC0Hg5wBBAToAAAsCQEHh5wAtAABFBEBBHCEBAkBB5OcAKAIAIgJB/wBLDQAgAkHg4gBqLQAARQ0AIAJBAnRB4OMAakHk5wA2AgBBACEBCyABDQFB4ecAQQE6AAALQQwQFiIBRQ0AIAFBADYCBCABIAA2AgAgAUHo5wAoAgA2AghB6OcAIAE2AgALC+IXARJ/IAAoAgghCgJAAkACQAJAAkAgACgCAA4EAQIAAwQLIAogAiABa2wiAEEATA0DIABBAUcEQCAAQQFxIQIgAEF+cSEGA0AgBCAFQQJ0IgBqIAAgA2ooAgAiAUEIdiIHQf8BcSABQf+B/AdxaiAHQRB0akH/gfwHcSABQYD+g3hxcjYCACAEIABBBHIiAGogACADaigCACIAQQh2IgFB/wFxIABB/4H8B3FqIAFBEHRqQf+B/AdxIABBgP6DeHFyNgIAIAVBAmoiBSAGRw0ACyACRQ0ECyAEIAVBAnQiAGogACADaigCACIAQQh2IgFB/wFxIABB/4H8B3FqIAFBEHRqQf+B/AdxIABBgP6DeHFyNgIADwsCQAJ/IAEEQCAEIQcgAQwBCyAEIAMoAgBBgICACGsiBTYCAAJAIApBAkgNACAEQQRqIQcgA0EEaiEJIApBAkcEQCAKQQFrIghBAXEhCyAIQX5xIQwDQCAHIAZBAnQiCGogCCAJaigCACINQYD+g3hxIAVBgP6DeHFqQYD+g3hxIg4gDUH/gfwHcSAFQf+B/AdxakH/gfwHcSIFcjYCACAHIAhBBHIiCGogCCAJaigCACIIQYD+g3hxIA5qQYD+g3hxIAhB/4H8B3EgBWpB/4H8B3FyIgU2AgAgBkECaiIGIAxHDQALIAtFDQELIAcgBkECdCIGaiAGIAlqKAIAIgZBgP6DeHEgBUGA/oN4cWpBgP6DeHEgBkH/gfwHcSAFQf+B/AdxakH/gfwHcXI2AgALIAQgCkECdCIFaiEHIAMgBWohA0EBCyILIAJODQBBACAKayEMIApBAkgEQANAIAcgAygCACIFQYD+g3hxIAcgDEECdGooAgAiBkGA/oN4cWpBgP6DeHEgBUH/gfwHcSAGQf+B/AdxakH/gfwHcXI2AgAgByAKQQJ0IgVqIQcgAyAFaiEDIAtBAWoiCyACRw0ADAILAAtBAEEBIAAoAgQiBXQiDWshDiAAKAIQIA1BAWsiEyAKaiAFdiIPIAsgBXVsQQJ0aiEJA0AgByADKAIAIgVBgP6DeHEgByAMQQJ0IhBqKAIAIgZBgP6DeHFqQYD+g3hxIAVB/4H8B3EgBkH/gfwHcWpB/4H8B3FyNgIAQQEhBSAJIQYDQCADIAVBAnQiCGogByAIaiIRIBBqIAUgDnEgDWoiCCAKIAggCkgiEhsiCCAFayARIAYoAgBBBnZBPHFBwOAAaigCABEBACAGQQRqIQYgCCEFIBINAAsgByAKQQJ0IgVqIQcgAyAFaiEDIAlBACAPIAtBAWoiCyATcRtBAnRqIQkgAiALRw0ACwsgACgCDCACRg0CIAQgCkECdCIAayAEIAogAUF/cyACamxBAnRqIAAQFBoPCyABIAJODQEgCiAKQQBBASAAKAIEIgV0IgdrcSILayEJIAAoAhAgB0EBayIMIApqIAV2Ig0gASAFdWxBAnRqIQAgC0EATCEOIAVBH0YhEwNAIAMgCkECdGohDwJAIA4EQCAAIQUMAQsgAyALQQJ0aiEQIAAhBQNAIBNFBEAgBSgCACIGQQh0QRh1IREgBkEQdEEYdSESIAbAIRRBACEGA0AgBCAGQQJ0IghqIAMgCGooAgAiCEEQdEEYdSIVIBRsQQV1IAhBEHZqIhZBEHRBgID8B3EgCEGA/oN4cXIgEiAVbEEFdiAIaiAWwCARbEEFdmpB/wFxcjYCACAGQQFqIgYgB0cNAAsLIAVBBGohBSAEIAdBAnQiBmohBCADIAZqIgMgEEkNAAsLIAMgD0kEQCAJQQBKBEAgBSgCACIFQQh0QRh1IQggBUEQdEEYdSEPIAXAIRBBACEGA0AgBCAGQQJ0IgVqIAMgBWooAgAiBUEQdEEYdSIRIBBsQQV1IAVBEHZqIhJBEHRBgID8B3EgBUGA/oN4cXIgDyARbEEFdiAFaiASwCAIbEEFdmpB/wFxcjYCACAGQQFqIgYgCUcNAAsLIAQgCUECdCIFaiEEIAMgBWohAwsgAEEAIA0gAUEBaiIBIAxxG0ECdGohACABIAJHDQALDAELIAAoAgQhBQJAIAMgBEcNACAFQQBMDQACQCADIAogAiABayIEbEECdGogCkEBIAV0akEBayAFdiAEbEECdCIEayIFIgcgAyIGRg0AIAYgBCAHaiIIa0EAIARBAXRrTQRAIAcgBiAEEBQaDAELIAYgB3NBA3EhCQJAAkAgBiAHSwRAIAkNAiAHQQNxRQ0BA0AgBEUNBCAHIAYtAAA6AAAgBkEBaiEGIARBAWshBCAHQQFqIgdBA3ENAAsMAQsCQCAJDQAgCEEDcQRAA0AgBEUNBSAHIARBAWsiBGoiCSAEIAZqLQAAOgAAIAlBA3ENAAsLIARBA00NAANAIAcgBEEEayIEaiAEIAZqKAIANgIAIARBA0sNAAsLIARFDQIDQCAHIARBAWsiBGogBCAGai0AADoAACAEDQALDAILIARBA00NAANAIAcgBigCADYCACAGQQRqIQYgB0EEaiEHIARBBGsiBEEDSw0ACwsgBEUNAANAIAcgBi0AADoAACAHQQFqIQcgBkEBaiEGIARBAWsiBA0ACwsgACgCECEJIAAoAgghCCAAKAIEIgAEQCABIAJODQIgCEEATA0CQX9BCCAAdiIMdEF/cyEKQX8gAHRBf3MhCyAIQX5xIQYgCEEBcSENA0BBACEHQQAhAEEAIQQCQCAIQQFHBEADQCAHIAtxBH8gBQUgBS0AASEAIAVBBGoLIQQgAyAJIAAgCnFBAnRqKAIANgIAIAMgCSAKAn8gB0EBciALcQRAIAQhBSAAIAx2DAELIARBBGohBSAELQABCyIAcUECdGooAgA2AgQgACAMdiEAIANBCGohAyAHQQJqIgcgBkcNAAsgACEHIAYhBCANRQ0BCyAEIAtxRQRAIAUtAAEhByAFQQRqIQULIAMgCSAHIApxQQJ0aigCADYCACADQQRqIQMLIAFBAWoiASACRw0ACwwCCyABIAJODQEgCEEATA0BIAhBfHEhBCAIQQNxIQAgCEEESSEGA0BBACEHIAZFBEADQCADIAkgBSgCAEEGdkH8B3FqKAIANgIAIAMgCSAFKAIEQQZ2QfwHcWooAgA2AgQgAyAJIAUoAghBBnZB/AdxaigCADYCCCADIAkgBSgCDEEGdkH8B3FqKAIANgIMIANBEGohAyAFQRBqIQUgB0EEaiIHIARHDQALC0EAIQcgAARAA0AgAyAJIAUoAgBBBnZB/AdxaigCADYCACADQQRqIQMgBUEEaiEFIAdBAWoiByAARw0ACwsgAUEBaiIBIAJHDQALDAELIAAoAhAhCSAFBEAgASACTg0BIApBAEwNAUF/QQggBXYiDHRBf3MhCEF/IAV0QX9zIQsgCkF+cSEFIApBAXEhDQNAQQAhBkEAIQdBACEAAkAgCkEBRwRAA0AgBiALcUUEQCADLQABIQcgA0EEaiEDCyAEIAkgByAIcUECdGooAgA2AgACfyAGQQFyIAtxBEAgByAMdiEHIAMMAQsgAy0AASEHIANBBGoLIQMgBCAJIAcgCHFBAnRqKAIANgIEIAcgDHYhByAEQQhqIQQgBkECaiIGIAVHDQALIAchBiAFIQAgDUUNAQsgACALcUUEQCADLQABIQYgA0EEaiEDCyAEIAkgBiAIcUECdGooAgA2AgAgBEEEaiEECyABQQFqIgEgAkcNAAsMAQsgASACTg0AIApBAEwNACAKQXxxIQUgCkEDcSEAIApBBEkhBwNAQQAhBiAHRQRAA0AgBCAJIAMoAgBBBnZB/AdxaigCADYCACAEIAkgAygCBEEGdkH8B3FqKAIANgIEIAQgCSADKAIIQQZ2QfwHcWooAgA2AgggBCAJIAMoAgxBBnZB/AdxaigCADYCDCAEQRBqIQQgA0EQaiEDIAZBBGoiBiAFRw0ACwtBACEGIAAEQANAIAQgCSADKAIAQQZ2QfwHcWooAgA2AgAgBEEEaiEEIANBBGohAyAGQQFqIgYgAEcNAAsLIAFBAWoiASACRw0ACwsL+A8BE38jAEGAAWsiBkIANwN4IAZCADcDcCAGQgA3A2ggBkIANwNgIAZCADcDWCAGQgA3A1AgBkIANwNIIAZCADcDQAJAIANBAEoEfwNAIAIgBUECdGooAgAiB0EPSg0CIAZBQGsgB0ECdGoiByAHKAIAQQFqNgIAIAVBAWoiBSADRw0ACyAGKAJABUEACyADRg0AIAZBADYCBCAGKAJEIgVBAkoNACAGIAU2AgggBigCSCIHQQRKDQAgBiAFIAdqIgU2AgwgBigCTCIHQQhKDQAgBiAFIAdqIgU2AhAgBigCUCIHQRBKDQAgBiAFIAdqIgU2AhQgBigCVCIHQSBKDQAgBiAFIAdqIgU2AhggBigCWCIHQcAASg0AIAYgBSAHaiIFNgIcIAYoAlwiB0GAAUoNACAGIAUgB2oiBTYCICAGKAJgIgdBgAJKDQAgBiAFIAdqIgU2AiQgBigCZCIHQYAESg0AIAYgBSAHaiIFNgIoIAYoAmgiB0GACEoNACAGIAUgB2oiBTYCLCAGKAJsIgdBgBBKDQAgBiAFIAdqIgU2AjAgBigCcCIHQYAgSg0AIAYgBSAHaiIFNgI0IAYoAnQiB0GAwABKDQAgBiAFIAdqIgU2AjggBigCeCIHQYCAAUoNACAGIAUgB2oiDjYCPCADQQBKBEAgA0EBcSEHAkAgBARAQQAhBSADQQFHBEAgA0F+cSEDA0AgAiAFQQJ0aigCACIIQQBKBEAgBiAIQQJ0aiIIIAgoAgAiCEEBajYCACAEIAhBAXRqIAU7AQALIAIgBUEBciIIQQJ0aigCACIJQQBKBEAgBiAJQQJ0aiIJIAkoAgAiCUEBajYCACAEIAlBAXRqIAg7AQALIAVBAmoiBSADRw0ACyAHRQ0CCyACIAVBAnRqKAIAIgJBAEwNASAGIAJBAnRqIgIgAigCACICQQFqNgIAIAQgAkEBdGogBTsBAAwBC0EAIQUgA0EBRwRAIANBfnEhAwNAIAIgBUECdCIIaigCACIJQQBKBEAgBiAJQQJ0aiIJIAkoAgBBAWo2AgALIAIgCEEEcmooAgAiCEEASgRAIAYgCEECdGoiCCAIKAIAQQFqNgIACyAFQQJqIgUgA0cNAAsgB0UNAQsgAiAFQQJ0aigCACICQQBMDQAgBiACQQJ0aiICIAIoAgBBAWo2AgALIAYoAjwhDgtBASABdCEHQQEhECAOQQFGBEAgBEUEQCAHDwsgBC8BAEEQdCECIAchBQNAIAAgBUEBayIBQQJ0aiACNgEAIAVBAUohAyABIQUgAw0ACyAHDwsCQCAARQRAQQEhDUEBIQUDQCAQQQF0IgIgBkFAayAFQQJ0aigCAGsiEEEASA0DIAIgDWohDSABIAVHIQIgBUEBaiEFIAINAAtBACEDDAELQQIhDEEAIQNBASENQQEhCwNAIBBBAXQiFCAGQUBrIAtBAnRqIg8oAgAiAmsiEEEASA0CIAJBAEoEQCACIApqIQkgC0H/AXEhE0EBIAtBAWt0IREDQCAAIANBAnRqIQIgBCAKQQF0ai8BAEEQdCATciEIIAchBQNAIAIgBSAMayIFQQJ0aiAINgEAIAVBAEoNAAsgESEIA0AgCCICQQF2IQggAiADcQ0ACyACQQFrIANxIAJqIAMgAhshAyAKQQFqIgogCUcNAAsgD0EANgIAIAkhCgsgDSAUaiENIAxBAXQhDCABIAtGIQIgC0EBaiELIAJFDQALCyABQQFqIQUCQCAARQRAA0AgEEEBdCIAIAZBQGsgBUECdGooAgBrIhBBAEgNAyAAIA1qIQ0gBUEBaiIFQRBHDQALIAchCwwBCyAHQQFrIRVBAiECQX8hCSAAIQ8gASERIAchCwNAIBEhCCAQQQF0IhcgBkFAayAFIhFBAnRqIhMoAgAiBWsiEEEASA0CAkAgBUEATA0AQQEgCHQhFCARIAFrIgVB/wFxIRZBASAFdCEOIAhBDUwEQCAJIQUDQAJAIAUgAyAVcSIJRgRAIAUhCQwBCyAPIAdBAnRqIQ8gDiEIIBEhBQNAAkAgCCAGQUBrIAVBAnRqKAIAayIHQQBMBEAgBSEMDAELIAdBAXQhCEEPIQwgBUEBaiIFQQ9HDQELCyAAIAlBAnRqIgUgDDoAACAFIA8gAGtBAnYgCWs7AQJBASAMIAFrdCIHIAtqIQsLIA8gAyABdkECdGohCCAEIApBAXRqLwEAQRB0IBZyIQwgByEFA0AgCCAFIAJrIgVBAnRqIAw2AQAgBUEASg0ACyAUIQgDQCAIIgVBAXYhCCADIAVxDQALIBMgEygCACIIQQFrNgIAIAVBAWsgA3EgBWogAyAFGyEDIApBAWohCiAJIQUgCEEBSg0ACwwBCwNAIAkgAyAVcSIFRwRAIAAgBUECdGoiCCAROgAAIAggDyAHQQJ0aiIPIABrQQJ2IAVrOwECIAsgDmohCyAFIQkgDiEHCyAPIAMgAXZBAnRqIQggBCAKQQF0ai8BAEEQdCAWciEMIAchBQNAIAggBSACayIFQQJ0aiAMNgEAIAVBAEoNAAsgFCEIA0AgCCIFQQF2IQggAyAFcQ0ACyATIBMoAgAiCEEBazYCACAFQQFrIANxIAVqIAMgBRshAyAKQQFqIQogCEEBSg0ACwsgDSAXaiENIAJBAXQhAiARQQFqIgVBEEcNAAsgBigCPCEOCyALQQAgDkEBdEEBayANRhshEgsgEguzBAEJfyAAKAIQIQcgACgCCCEIAkAgACgCBCIABEAgASACTg0BIAhBAEwNAUF/QQggAHYiDHRBf3MhCkF/IAB0QX9zIQsgCEF+cSEJIAhBAXEhDQNAQQAhAEEAIQVBACEGAkAgCEEBRwRAA0AgACALcQR/IAMFIAMtAAAhBSADQQFqCyEGIAQgByAFIApxQQJ0aigCAEEIdjoAAAJ/IABBAXIgC3EEQCAFIAx2IQUgBgwBCyAGLQAAIQUgBkEBagshAyAEIAcgBSAKcUECdGooAgBBCHY6AAEgBSAMdiEFIARBAmohBCAAQQJqIgAgCUcNAAsgBSEAIAkhBiANRQ0BCyAGIAtxRQRAIAMtAAAhACADQQFqIQMLIAQgByAAIApxQQJ0aigCAEEIdjoAACAEQQFqIQQLIAFBAWoiASACRw0ACwwBCyABIAJODQAgCEEATA0AIAhBfHEhBSAIQQNxIQYgCEEESSEJA0BBACEAIAlFBEADQCAEIAcgAy0AAEECdGooAgBBCHY6AAAgBCAHIAMtAAFBAnRqKAIAQQh2OgABIAQgByADLQACQQJ0aigCAEEIdjoAAiAEIAcgAy0AA0ECdGooAgBBCHY6AAMgBEEEaiEEIANBBGohAyAAQQRqIgAgBUcNAAsLQQAhACAGBEADQCAEIAcgAy0AAEECdGooAgBBCHY6AAAgBEEBaiEEIANBAWohAyAAQQFqIgAgBkcNAAsLIAFBAWoiASACRw0ACwsL4RwCF38CfiAAKAJwIgkgAm0hDiABIAIgA2xBAnRqIRggASAJQQJ0aiEDAn8CQAJAIAkgAiAEbCIHTg0AIAkgAiAObGshECAAQfwAakEAIAAoAngiFkEAShshFCAOQYCAgAggACgCOBshFyAWQZgCaiEbIAdBAnQgAWohHCAAKAKUASEZIAAoAqgBIAAoApgBIgkEfyAAKAKgASAAKAKcASAOIAl1bCAQIAl1akECdGooAgAFQQALQaQEbGohESAAQUBrIRUgAyEPA0AgDiAXTgRAIBUgACkDGDcDACAVIAApAzA3AxggFSAAKQMoNwMQIBUgACkDIDcDCCAAIAMgAWtBAnU2AmAgACgCeEEASgRAIAAoAogBIAAoAnxBBCAAKAKQAXQQFBoLIA5BCGohFwsCQAJAAn8gECAZcUUEQCAAKAKoASAAKAKYASIGBH8gACgCoAEgACgCnAEgDiAGdWwgECAGdWpBAnRqKAIABUEAC0GkBGxqIRELIBEoAhwEQCARKAIYDAELAkAgACgCLCIIQSBIBEAgCCEGDAELIAAoAigiByAAKAIkIgYgBiAHSRshCwNAAkAgByALRgRAIAghBgwBCyAAIAApAxhCCIgiHjcDGCAAKAIgIAdqMQAAIR0gACAIQQhrIgY2AiwgACAHQQFqIgc2AiggACAdQjiGIB6ENwMYIAhBD0ohCSAGIQggCQ0BCwsgACgCMEUEQCAAKAIoIAAoAiRHDQEgBkHBAEgNAQsgAEKAgICAEDcCLEEAIQYLAkAgESgCIARAIAYgESAAKQMYIh0gBkE/ca2Ip0E/cUEDdGoiCCgCJCIGaiEHIAgoAighCAJAIAZB/wFMBEAgACAHNgIsIAMgCDYCAEEAIQgMAQsgACAHQYACazYCLAsgACgCMA0GIAAoAigiByAAKAIkIgxGBEAgACgCLEHAAEoNBwsgCA0BDAMLIAAgESgCACAAKQMYIh0gBkE/ca2Ip0H/AXFBAnRqIggtAAAiB0EJTwR/IAggCC8BAkECdGogHSAGQQhqIgZBP3GtiKdBfyAHQQhrdEF/c3FBAnRqIggtAAAFIAcLQf8BcSAGajYCLCAAKAIwDQUgACgCJCEMIAAoAighByAILwECIQgLIAcgDEYEQCAAKAIsQcAASg0FCwJAAkACQCAIQf8BTARAIBEoAhQEQCARKAIYIAhBCHRyDAULIBEoAgQgHSAAKAIsIgZBP3GtiKdB/wFxQQJ0aiIJLQAAIgpBCU8EQCAJIAkvAQJBAnRqIB0gBkEIaiIGQT9xrYinQX8gCkEIa3RBf3NxQQJ0aiIJLQAAIQoLIAAgBiAKaiIGNgIsIAkvAQIhEyAGQSBIDQIgByAMIAcgDEsbIQsDQCAHIAtHBEAgACAdQgiIIh43AxggACgCICAHajEAACEdIAAgBkEIayIJNgIsQQEhDSAAIAdBAWoiBzYCKCAAIB1COIYgHoQiHTcDGCAGQQ9KIQogCSEGIAoNAQwFCwsgCyAMRw0BIAZBwQBIDQEgAEEBNgIwQQAhDSALIQdBACEJDAMLAkACQCAIQZcCTQRAAkAgCEGAAmsiCkEDTQRAIAAoAiwhBkEAIRIMAQsgACAAKAIsIgkgCEGCAmtBAXYiC2oiBjYCLCAIQQFxQQJyIAt0IQ0gC0ECdEHwywBqKAIAIB0gCUE/ca2Ip3EhE0EAIRICQCAGQQhIDQAgByAMIAcgDEsbIQsgByEIAkADQCAIIAtGDQEgACAdQgiIIh43AxggACgCICAIajEAACEdIAAgBkEIayIJNgIsIAAgCEEBaiIINgIoIAAgHUI4hiAehCIdNwMYIAZBD0ohCiAJIQYgCg0ACyAIIQcMAQsCQCAHIAxLDQAgBkHBAEkNAEEBIRIgAEEBNgIwQQAhBgsgCyEHCyANIBNqIQoLIAAgESgCECAdIAZBP3GtiKdB/wFxQQJ0aiIJLQAAIghBCU8EfyAJIAkvAQJBAnRqIB0gBkEIaiIGQT9xrYinQX8gCEEIa3RBf3NxQQJ0aiIJLQAABSAIC0H/AXEgBmoiCDYCLCAJLwECIQ0CQCAIQSBIDQAgByAMIAcgDEsbIQkDQAJAIAcgCUYEQCAJIQcgCCEGDAELIAAgHUIIiCIeNwMYIAAoAiAgB2oxAAAhHSAAIAhBCGsiBjYCLCAAIAdBAWoiBzYCKCAAIB1COIYgHoQiHTcDGCAIQQ9KIQsgBiEIIAsNAQsLAkAgEg0AQQAhEiAHIAxHBEAgBiEIDAILIAZBwQBODQAgBiEIDAELIABCgICAgBA3AixBACEIQQEhEgsCQCANQQRJBEAgCCEGIAchCQwBCyANQQFxQQJyIA1BAmsiBkEBdiIJdCENQQAhGgJAAkAgBkExSwRAIAchCQwBCyASBEAgByEJDAELIAAgCCAJaiIGNgIsIAlBAnRB8MsAaigCACAdIAhBP3GtiKdxIRpBACESIAZBCEgEQCAHIQkMAgsgByAMIAcgDEsbIQkgByEIAkADQCAIIAlGDQEgACAdQgiIIh43AxggACgCICAIajEAACEdIAAgBkEIayILNgIsIAAgCEEBaiIINgIoIAAgHUI4hiAehCIdNwMYIAZBD0ohEyALIQYgEw0ACyAIIQkMAgsgByAMSw0BIAZBwQBJDQELIABCgICAgBA3AixBASESQQAhBgsgDSAaaiENCyANQQFqQfkATgR/IA1B9wBrBUEBIA1B8C5qLQAAIghBBHYgAmwgCEEPcWtBCGoiCCAIQQFMGwshByASDQogCSAMRiAGQcAASnENCiADIAFrQQJ1IAdIDQsgCkEBaiILIBggA2tBAnVKDQsgAyAHQQJ0ayEMAkAgA0EDcQ0AIAdBAkoNACALQQRIDQACQCAHQQFGBEAgDCgCACIHrSIdQiCGIB2EIR0MAQsgDCkCACIdpyEHCwJ/IANBBHFFBEAgCyEKIAMMAQsgAyAHNgIAIB1CIIkhHSAMQQRqIQwgA0EEagshByAKQQF2IghBB3EhE0EAIQlBACEGIAhBAWtBB08EQCAIQfj///8HcSEIA0AgByAGQQN0Ig1qIB03AwAgByANQQhyaiAdNwMAIAcgDUEQcmogHTcDACAHIA1BGHJqIB03AwAgByANQSByaiAdNwMAIAcgDUEocmogHTcDACAHIA1BMHJqIB03AwAgByANQThyaiAdNwMAIAZBCGoiBiAIRw0ACwsgEwRAA0AgByAGQQN0aiAdNwMAIAZBAWohBiAJQQFqIgkgE0cNAAsLIApBAXFFDQMgByAKQQJ0QXhxIgZqIAYgDGooAgA2AgAMAwsgByALTg0BIApB/v///wdLDQJBACEGQQAhByALQQRPBEAgC0F8cSEJA0AgAyAHQQJ0IgpqIAogDGooAgA2AgAgAyAKQQRyIghqIAggDGooAgA2AgAgAyAKQQhyIghqIAggDGooAgA2AgAgAyAKQQxyIghqIAggDGooAgA2AgAgB0EEaiIHIAlHDQALCyALQQNxIglFDQIDQCADIAdBAnQiCGogCCAMaigCADYCACAHQQFqIQcgBkEBaiIGIAlHDQALDAILIAggG04NCiAUKAIAIQcgAyAPSwRAA0AgByAPKAIAIgZBvc/W8QFsIBQoAgR2QQJ0aiAGNgIAIA9BBGoiDyADSQ0ACwsgByAIQZgCa0ECdGooAgAMBQsgAyAMIAtBAnQQFBoLAkAgCyAQaiIQIAJIDQAgBUUEQANAIA5BAWohDiAQIAJrIhAgAk4NAAwCCwALA0AgECACayEQIA4iBkEBaiEOAkAgBCAGTA0AIA5BD3ENACAAIA4gBREDAAsgAiAQTA0ACwsgECAZcQRAIAAoAqgBIAAoApgBIgYEfyAAKAKgASAAKAKcASAOIAZ1bCAQIAZ1akECdGooAgAFQQALQaQEbGohEQsgC0ECdCADaiEDIBZBAEwNBSADIA9NDQUgFCgCACEIA0AgCCAPKAIAIgZBvc/W8QFsIBQoAgR2QQJ0aiAGNgIAIA9BBGoiDyADSQ0ACwwFCyALIQcLQQEhDSAGIQkLIBEoAgggHSAJQT9xrYinQf8BcUECdGoiBi0AACIKQQlPBEAgBiAGLwECQQJ0aiAdIAlBCGoiCUE/ca2Ip0F/IApBCGt0QX9zcUECdGoiBi0AACEKCyAGLwECIQsgESgCDCAdIAkgCmoiCUE/ca2Ip0H/AXFBAnRqIgYtAAAiCkEJTwRAIAYgBi8BAkECdGogHSAJQQhqIglBP3GtiKdBfyAKQQhrdEF/c3FBAnRqIgYtAAAhCgsgACAJIApqIgk2AiwgDUUNBCAGLwECIQYgByAMRiAJQcAASnENBCATQRB0IAhBCHRyIAtyIAZBGHRyCyEHIAMgBzYCAAsgA0EEaiEGIAIgEEEBaiIQSgRAIAYhAwwBCyAOQQFqIQgCQCAFRQ0AIAQgDkwNACAIQQ9xDQAgACAIIAURAwALQQAhEAJAIBZBAEwNACAGIA9NDQAgFCgCACEJA0AgCSAPKAIAIgdBvc/W8QFsIBQoAgR2QQJ0aiAHNgIAIAMgD0shByAPQQRqIQ8gBw0ACwsgBiEDIAghDgsgAyAcSQ0ACwsgAAJ/QQEgACgCMA0AGkEAIAAoAiggACgCJEcNABogACgCLEHAAEoLIg82AjACQCAAKAI4RQ0AIA9FDQAgAyAYTw0AIABBBTYCACAAIAApA0A3AxggACAAKQNYNwMwIAAgACkDUDcDKCAAIAApA0g3AyAgACAAKAJgNgJwQQEgACgCeEEATA0CGiAAKAJ8IAAoAogBQQQgACgChAF0EBQaQQEPCyAPDQAgBQRAIAAgDiAEIAQgDkobIAURAwALIABBADYCACAAIAMgAWtBAnU2AnBBAQ8LIABBAzYCAEEACwvwEwESfyABKAIAIQMgASgCBCEKIAAoAtgRIgJBgQE6ALcGIAJBgQE6AKcGIAJBgQE6AJcGIAJBgQE6AIcGIAJBgQE6APcFIAJBgQE6AOcFIAJBgQE6ANcFIAJBgQE6AMcFIAJBgQE6ALcFIAJBgQE6AKcFIAJBgQE6AJcFIAJBgQE6AIcFIAJBgQE6APcEIAJBgQE6AOcEIAJBgQE6ANcEIAJBgQE6AMcEIAJBgQE6AIcEIAJBgQE6AOcDIAJBgQE6AMcDIAJBgQE6AKcDIAJBgQE6AIcDIAJBgQE6AOcCIAJBgQE6AMcCIAJBgQE6AKcCIAJBgQE6AIcCIAJBgQE6AOcBIAJBgQE6AMcBIAJBgQE6AKcBIAJBgQE6AIcBIAJBgQE6AGcgAkGBAToARyACQYEBOgAnAkAgCkEASgRAIAJBgQE6AKcEIAJBgQE6ALcEIAJBgQE6AAcMAQsgAkL//v379+/fv/8ANwAHIAJC//79+/fv37//ADcAFCACQv/+/fv379+//wA3AA8gAkH/ADoArwQgAkL//v379+/fv/8ANwCnBCACQf8AOgC/BCACQv/+/fv379+//wA3ALcECyAAKAKgAkEASgRAIAJB2ARqIQwgAkHIBGohDSACQShqIQtBBUEGIAobIQ4gA0EDdCERIANBBHQhEiAKRUECdCEPIApBAEwhEwNAIAEoAhAgCEGgBmxqIQUgCARAIAIgAigAFDYABCACIAIoADQ2ACQgAiACKABUNgBEIAIgAigAdDYAZCACIAIoAJQBNgCEASACIAIoALQBNgCkASACIAIoANQBNgDEASACIAIoAPQBNgDkASACIAIoAJQCNgCEAiACIAIoALQCNgCkAiACIAIoANQCNgDEAiACIAIoAPQCNgDkAiACIAIoAJQDNgCEAyACIAIoALQDNgCkAyACIAIoANQDNgDEAyACIAIoAPQDNgDkAyACIAIoAJQENgCEBCACIAIoAKwENgCkBCACIAIoALwENgC0BCACIAIoAMwENgDEBCACIAIoANwENgDUBCACIAIoAOwENgDkBCACIAIoAPwENgD0BCACIAIoAIwFNgCEBSACIAIoAJwFNgCUBSACIAIoAKwFNgCkBSACIAIoALwFNgC0BSACIAIoAMwFNgDEBSACIAIoANwFNgDUBSACIAIoAOwFNgDkBSACIAIoAPwFNgD0BSACIAIoAIwGNgCEBiACIAIoAJwGNgCUBiACIAIoAKwGNgCkBiACIAIoALwGNgC0BgsgACgCzBEgCEEFdGohByAFKAKUBiEGAkACQAJAAkAgE0UEQCACIAcpAAA3AAggAiAHKQAINwAQIAIgBykAEDcAqAQgAiAHKQAYNwC4BCAFLQCABg0BDAMLIAUtAIAGRQ0CIAIoAhghAwwBCyAAKAKgAkEBayAITARAIAIgBy0ADyIDQYGChAhsNgIYIAMgA0EIdHIiAyADQRB0ciEDDAELIAIgBygAICIDNgIYCyACIAM2ApgCIAIgAzYCmAMgAiADNgKYAUEAIQMDQCALIANBAXRB0C1qLwEAaiIEIAMgBWotAIEGQQJ0QdDfAGooAgARAAAgBSADQQV0aiEJAkACQAJAAkAgBkEedkEBaw4DAgEAAwsgCSAEECEMAgsgCSAEEDAMAQsgCS8BACAEECALIAZBAnQhBiADQQFqIgNBEEcNAAsgDyAOIAgbIRAMAQsgCyAFLQCBBiIDIA8gDiAIGyIQIAMbQQJ0QbDfAGooAgARAABBACEDIAZFDQADQCAFIANBBXRqIQQgCyADQQF0QdAtai8BAGohCQJAAkACQAJAIAZBHnZBAWsOAwIBAAMLIAQgCRAhDAILIAQgCRAwDAELIAQvAQAgCRAgCyAGQQJ0IQYgA0EBaiIDQRBHDQALCyAFKAKYBiEDIA0gBS0AkQYiBiAQIAYbQQJ0QYDgAGoiBigCABEAACAMIAYoAgARAAAgA0H/AXEEQCAFQYAEaiANQZzgAEGg4AAgA0GqAXEbKAIAEQMACyADQYD+A3EEQCAFQYAFaiAMQZzgAEGg4AAgA0GA1AJxGygCABEDAAsgACgCpAJBAWsgCkoEQCAHIAIpAIgENwAAIAcgAikAkAQ3AAggByACKQCoBjcAECAHIAIpALgGNwAYCyAAKALkESEFIAAoAuARIQcgACgC7BEhBiAAKALcESAIQQR0aiASIAAoAugRbGoiAyALKQAANwAAIAMgCykACDcACCADIAAoAugRaiIEIAIpAEg3AAAgBCACKQBQNwAIIAMgACgC6BFBAXRqIgQgAikAaDcAACAEIAIpAHA3AAggAyAAKALoEUEDbGoiBCACKQCIATcAACAEIAIpAJABNwAIIAMgACgC6BFBAnRqIgQgAikAqAE3AAAgBCACKQCwATcACCADIAAoAugRQQVsaiIEIAIpAMgBNwAAIAQgAikA0AE3AAggAyAAKALoEUEGbGoiBCACKQDoATcAACAEIAIpAPABNwAIIAMgACgC6BFBB2xqIgQgAikAiAI3AAAgBCACKQCQAjcACCADIAAoAugRQQN0aiIEIAIpAKgCNwAAIAQgAikAsAI3AAggAyAAKALoEUEJbGoiBCACKQDIAjcAACAEIAIpANACNwAIIAMgACgC6BFBCmxqIgQgAikA6AI3AAAgBCACKQDwAjcACCADIAAoAugRQQtsaiIEIAIpAIgDNwAAIAQgAikAkAM3AAggAyAAKALoEUEMbGoiBCACKQCoAzcAACAEIAIpALADNwAIIAMgACgC6BFBDWxqIgQgAikAyAM3AAAgBCACKQDQAzcACCADIAAoAugRQQ5saiIEIAIpAOgDNwAAIAQgAikA8AM3AAggAyAAKALoEUEPbGoiAyACKQCIBDcAACADIAIpAJAENwAIIAYgEWwiBiAHIAhBA3QiBGpqIgMgAikAyAQ3AAAgBCAFaiAGaiIFIAIpANgENwAAIAMgACgC7BFqIAIpAOgENwAAIAUgACgC7BFqIAIpAPgENwAAIAMgACgC7BFBAXRqIAIpAIgFNwAAIAUgACgC7BFBAXRqIAIpAJgFNwAAIAMgACgC7BFBA2xqIAIpAKgFNwAAIAUgACgC7BFBA2xqIAIpALgFNwAAIAMgACgC7BFBAnRqIAIpAMgFNwAAIAUgACgC7BFBAnRqIAIpANgFNwAAIAMgACgC7BFBBWxqIAIpAOgFNwAAIAUgACgC7BFBBWxqIAIpAPgFNwAAIAMgACgC7BFBBmxqIAIpAIgGNwAAIAUgACgC7BFBBmxqIAIpAJgGNwAAIAMgACgC7BFBB2xqIAIpAKgGNwAAIAUgACgC7BFBB2xqIAIpALgGNwAAIAhBAWoiCCAAKAKgAkgNAAsLC4EBAEGY3wBBATYCAEGc3wBBADYCAEHQCkECQagSQbASQQJBA0EAEAJBxQlBAUG0EkG4EkEEQQVBABACQZzfAEHE4gAoAgA2AgBBxOIAQZjfADYCAEHI4gBB4gA2AgBBzOIAQQA2AgAQPUHM4gBBxOIAKAIANgIAQcTiAEHI4gA2AgAL3iYBD38gAEGWCzYCCCAAQQA2AgACQAJAIAFFBEAgAEH8ETYCCCAAQQI2AgAMAQsgASgCPCIHQQNNBEAgAEGiEDYCCCAAQQc2AgAMAQsgASgCQCIJLQABIQUgCS0AAiEEIAAgCS0AACIIQQR2QQFxIgI6ACogACAIQQF2QQdxIgM6ACkgACAIQQFxIgZFOgAoIAAgCCAFQQh0IARBEHRyciIEQQV2IgU2AiwgA0EETwRAIABBgxA2AgggAEEDNgIADAELIAJFBEAgAEHsEDYCCCAAQQQ2AgAMAQsgB0EDayEIIAlBA2ohAiAGRQRAIAhBBk0EQCAAQYwJNgIIIABBBzYCAAwCCwJAAkAgAi0AAEGdAUcNACAJLQAEQQFHDQAgCS0ABUEqRg0BCyAAQdcKNgIIIABBAzYCAAwCCyAAIAktAAYgCS0AB0EIdEGA/gBxciIIOwEwIAAgCS0AB0EGdjoANCAAIAktAAggCS0ACUEIdEGA/gBxciICOwEyIAktAAkhAyAAIAJBD2pBBHY2AqQCIAAgCEEPakEEdjYCoAIgACADQQZ2OgA1IAFBADYCVCABIAI2AgQgASAINgIAIAEgAjYCZCABIAg2AmAgAUEANgJcIAEgAjYCWCABIAg2AlAgAUIANwJIIAEgAjYCECABIAg2AgwgAEH/AToAigcgAEH//wM7AYgHIABBADYCeCAAQgE3AnAgAEIANwJoIAdBCmshCCAJQQpqIQILIAUgCEsEQCAAQeIJNgIIIABBBzYCAAwBCyAAQoCAgIDgHzcCDCAAQQA2AiQgAEF4NgIUIAAgAiAFaiIBNgIcIAAgAjYCGCAAIAFBA2sgAiAEQf8ASxsiAzYCIAJAIAIgA0kEQCACKAAAIQMgAEEQNgIUIAAgAkEDajYCGCAAIANBCHZBgP4DcSADQRh0IANBgP4DcUEIdHJyQQh2NgIMDAELIABBADYCFCAEQSBPBEAgACACQQFqNgIYIAAgAi0AADYCDAwBCyAAQQE2AiQLIABBDGohAyAGRQRAIAAgA0EBEBM6ADYgACADQQEQEzoANwsgACADQQEQEyICNgJoAkAgAgRAIAAgA0EBEBM2AmwgA0EBEBMEQCAAIANBARATNgJwIAAgA0EBEBMEfyADQQcQFwVBAAs6AHQgACADQQEQEwR/IANBBxAXBUEACzoAdSAAIANBARATBH8gA0EHEBcFQQALOgB2IAAgA0EBEBMEfyADQQcQFwVBAAs6AHcgACADQQEQEwR/IANBBhAXBUEACzoAeCAAIANBARATBH8gA0EGEBcFQQALOgB5IAAgA0EBEBMEfyADQQYQFwVBAAs6AHogACADQQEQEwR/IANBBhAXBUEACzoAewsgACgCbEUNASAAIANBARATBH8gA0EIEBMFQf8BCzoAiAcgACADQQEQEwR/IANBCBATBUH/AQs6AIkHIAAgA0EBEBMEfyADQQgQEwVB/wELOgCKBwwBCyAAQQA2AmwLIAAoAiQEQCAAKAIADQIgAEHVCDYCCCAAQQM2AgAMAQsgACADQQEQEzYCOCAAIANBBhATNgI8IABBQGsgA0EDEBM2AgAgACADQQEQEyICNgJEAkAgAkUNACADQQEQE0UNACADQQEQEwRAIAAgA0EGEBc2AkgLIANBARATBEAgACADQQYQFzYCTAsgA0EBEBMEQCAAIANBBhAXNgJQCyADQQEQEwRAIAAgA0EGEBc2AlQLIANBARATBEAgACADQQYQFzYCWAsgA0EBEBMEQCAAIANBBhAXNgJcCyADQQEQEwRAIAAgA0EGEBc2AmALIANBARATRQ0AIAAgA0EGEBc2AmQLIAAgACgCPAR/QQFBAiAAKAI4GwVBAAs2AoQSIAMoAhgEQCAAKAIADQIgAEHxCDYCCCAAQQM2AgAMAQsgAEF/IABBDGpBAhATIgJ0QX9zIgw2ArgCIAxBA2wiBCAIIAVrIg5NBH8gDiAEayEQIAEgBGohBSACBEBBASAMIAxBAU0bIQkgAEG8AmohCCABIQIDQCACLwAAIQcgAi0AAiEGIAggCkEcbGoiC0EANgIYIAtBeDYCCCALQoCAgIDgHzcCACALIAUiBDYCDCALIAQgByAGQRB0ciIFIBAgBSAQSRsiB2oiBTYCECALIAVBA2sgBCAHQQNLGyIGNgIUAkAgBCAGSQRAIAQoAAAhBiALIARBA2o2AgwgCyAGQQh2QYD+A3EgBkEYdCAGQYD+A3FBCHRyckEIdjYCACALQRA2AggMAQsgC0EANgIIIAcEQCALIARBAWo2AgwgCyAELQAANgIADAELIAtBATYCGAsgAkEDaiECIBAgB2shECAKQQFqIgogCUcNAAsLIAEgDmohBCAAIAxBHGxqIgZBADYC1AIgBkF4NgLEAiAGQoCAgIDgHzcCvAIgBiAFIBBqIgJBA2sgBSAQQQNLGyIBNgLQAiAGIAI2AswCIAYgBTYCyAICQCABIAVLBEAgBSgAACEBIAYgBUEDajYCyAIgBiABQQh2QYD+A3EgAUEYdCABQYD+A3FBCHRyckEIdjYCvAIgBkEQNgLEAgwBCyAGQQA2AsQCIBBBAEoEQCAGIAVBAWo2AsgCIAYgBS0AADYCvAIMAQsgBkEBNgLUAgtBBUEAIAQgBU0bBUEHCyIBBEAgACgCAA0CIABBvQg2AgggACABNgIADAELQQAhCkEAIQ5BACEJQQAhCCAAQQxqIgJBBxATIQEgAkEBEBMEQCACQQQQFyEOCyACQQEQEwRAIAJBBBAXIQoLIAJBARATBEAgAkEEEBchCAsgAkEBEBMEQCACQQQQFyEJCyACQQEQEwR/IAJBBBAXBUEACyEHIAEhAiAAKAJoIgUEQCAALAB0QQAgASAAKAJwG2ohAgsgACACIAdqIgY2AqAGIABB9QAgAiAJaiIEIARB9QBOGyIEQQAgBEEAShtBwCpqLQAANgKYBiAAQf8AIAIgAkH/AE4bIgRBACAEQQBKG0EBdEHAK2ovAQA2AowGIABB/wAgAiAOaiIEIARB/wBOGyIEQQAgBEEAShtBwCpqLQAANgKIBiAAQf8AIAYgBkH/AE4bIgRBACAEQQBKG0EBdEHAK2ovAQA2ApwGIABB/wAgAiAKaiIEIARB/wBOGyIEQQAgBEEAShtBwCpqLQAAQQF0NgKQBiAAQQhB/wAgAiAIaiICIAJB/wBOGyICQQAgAkEAShtBAXRBwCtqLwEAQc2ZBmwiAkEQdiACQYCAIEkbNgKUBgJAIAVFBEAgACAAKQKIBjcCqAYgACAAKQKgBjcCwAYgACAAKQKYBjcCuAYgACAAKQKQBjcCsAYgACAAKQKIBjcCyAYgACAAKQKQBjcC0AYgACAAKQKYBjcC2AYgACAAKQKgBjcC4AYgACAAKQKIBjcC6AYgACAAKQKQBjcC8AYgACAAKQKYBjcC+AYgACAAKQKgBjcCgAcMAQsgAEEAIAEgACgCcBsiBSAALAB1aiIMIAdqIgQ2AsAGIAAgBSAALAB2aiIGIAdqIgI2AuAGIABB9QAgCSAMaiIBIAFB9QBOGyIBQQAgAUEAShtBwCpqLQAANgK4BiAAQf8AIAwgDEH/AE4bIgFBACABQQBKG0EBdEHAK2ovAQA2AqwGIABB/wAgDCAOaiIBIAFB/wBOGyIBQQAgAUEAShtBwCpqLQAANgKoBiAAQfUAIAYgCWoiASABQfUAThsiAUEAIAFBAEobQcAqai0AADYC2AYgAEH/ACAGIAZB/wBOGyIBQQAgAUEAShtBAXRBwCtqLwEANgLMBiAAQf8AIAYgDmoiASABQf8AThsiAUEAIAFBAEobQcAqai0AADYCyAYgAEH/ACAEIARB/wBOGyIBQQAgAUEAShtBAXRBwCtqLwEANgK8BiAAQf8AIAogDGoiASABQf8AThsiAUEAIAFBAEobQcAqai0AAEEBdDYCsAYgAEH/ACACIAJB/wBOGyIBQQAgAUEAShtBAXRBwCtqLwEANgLcBiAAQf8AIAYgCmoiASABQf8AThsiAUEAIAFBAEobQcAqai0AAEEBdDYC0AYgAEEIQf8AIAggDGoiASABQf8AThsiAUEAIAFBAEobQQF0QcArai8BAEHNmQZsIgFBEHYgAUGAgCBJGzYCtAYgAEEIQf8AIAYgCGoiASABQf8AThsiAUEAIAFBAEobQQF0QcArai8BAEHNmQZsIgFBEHYgAUGAgCBJGzYC1AYgACAFIAAsAHdqIgIgB2oiATYCgAcgAEH/ACABIAFB/wBOGyIBQQAgAUEAShtBAXRBwCtqLwEANgL8BiAAQfUAIAIgCWoiASABQfUAThsiAUEAIAFBAEobQcAqai0AADYC+AYgAEEIQf8AIAIgCGoiASABQf8AThsiAUEAIAFBAEobQQF0QcArai8BAEHNmQZsIgFBEHYgAUGAgCBJGzYC9AYgAEH/ACACIApqIgEgAUH/AE4bIgFBACABQQBKG0HAKmotAABBAXQ2AvAGIABB/wAgAiACQf8AThsiAUEAIAFBAEobQQF0QcArai8BADYC7AYgAEH/ACACIA5qIgEgAUH/AE4bIgFBACABQQBKG0HAKmotAAA2AugGCyAALQAoRQRAIAAoAgANAiAAQdsQNgIIIABBBDYCAAwBC0EBIQ8gA0EBEBMaIAMhAkEAIQsgAEGIB2ohDgNAQQAhEANAIBBBIWwiBiAAIAtBiAJsIglqakGLB2ohDEEAIQ0DQCAGIAlqIgggDWoiBUHQEmotAAAhBCACKAIEIQcCQCACKAIIIgNBAE4EQCADIQEMAQsgAigCDCIKIAIoAhRJBEAgCigAACEBIAIgCkEDajYCDCACIAIoAgBBGHQgAUEIdkGA/gNxIAFBGHQgAUGA/gNxQQh0cnJBCHZyNgIAIANBGGohAQwBCyACKAIQIApLBEAgAiAKQQFqNgIMIAIgA0EIaiIBNgIIIAIgCi0AACACKAIAQQh0cjYCAAwBC0EAIQEgAigCGA0AIAJBATYCGCACIAIoAgBBCHQ2AgAgA0EIaiEBCyACIAECfyAEIAdsQQh2IgogAigCACIDIAF2TyIERQRAIAIgCkF/cyABdCADajYCACAHIAprDAELIApBAWoLIgNnQRhzIgFrNgIIIAIgAyABdEEBazYCBCAMIA1qAn8gBEUEQCACQQgQEwwBCyAFQfAaai0AAAs6AAAgDUEBaiINQQtHDQALQQAhDQNAIAggDWoiBUHbEmotAAAhBCACKAIEIQYCQCACKAIIIgNBAE4EQCADIQEMAQsgAigCDCIHIAIoAhRPBEAgAigCECAHSwRAIAIgB0EBajYCDCACIANBCGoiATYCCCACIActAAAgAigCAEEIdHI2AgAMAgtBACEBIAIoAhgNASACQQE2AhggAiACKAIAQQh0NgIAIANBCGohAQwBCyAHKAAAIQEgAiAHQQNqNgIMIAIgAigCAEEYdCABQQh2QYD+A3EgAUEYdCABQYD+A3FBCHRyckEIdnI2AgAgA0EYaiEBCyACIAECfyAEIAZsQQh2IgcgAigCACIDIAF2SSIERQRAIAdBAWoMAQsgAiAHQX9zIAF0IANqNgIAIAYgB2sLIgNnQRhzIgFrNgIIIAIgAyABdEEBazYCBCAMIA1qAn8gBEUEQCAFQfsaai0AAAwBCyACQQgQEws6AAsgDUEBaiINQQtHDQALQQAhDQNAIAggDWoiBUHmEmotAAAhBCACKAIEIQYCQCACKAIIIgNBAE4EQCADIQEMAQsgAigCDCIHIAIoAhRPBEAgAigCECAHSwRAIAIgB0EBajYCDCACIANBCGoiATYCCCACIActAAAgAigCAEEIdHI2AgAMAgtBACEBIAIoAhgNASACQQE2AhggAiACKAIAQQh0NgIAIANBCGohAQwBCyAHKAAAIQEgAiAHQQNqNgIMIAIgAigCAEEYdCABQQh2QYD+A3EgAUEYdCABQYD+A3FBCHRyckEIdnI2AgAgA0EYaiEBCyACIAECfyAEIAZsQQh2IgcgAigCACIDIAF2SSIERQRAIAdBAWoMAQsgAiAHQX9zIAF0IANqNgIAIAYgB2sLIgNnQRhzIgFrNgIIIAIgAyABdEEBazYCBCAMIA1qAn8gBEUEQCAFQYYbai0AAAwBCyACQQgQEws6ABYgDUEBaiINQQtHDQALIBBBAWoiEEEIRw0ACyAOIAtBxABsaiIFQeQIaiAJIA5qIgNBA2oiATYCACAFQeAIaiADQeoBajYCACAFQdwIaiADQckBaiIENgIAIAVB2AhqIAQ2AgAgBUHUCGogBDYCACAFQdAIaiAENgIAIAVBzAhqIAQ2AgAgBUHICGogBDYCACAFQcQIaiAENgIAIAVBwAhqIAQ2AgAgBUG8CGogA0GoAWo2AgAgBUG4CGogA0GHAWo2AgAgBUG0CGogBDYCACAFQbAIaiADQeYAajYCACAFQawIaiADQcUAajYCACAFQagIaiADQSRqNgIAIAVBpAhqIAE2AgAgC0EBaiILQQRHDQALIAAgAkEBEBMiATYCvBEgAQRAIAAgAkEIEBM6AMARCwsgACAPNgIECyAPC7MGAQN/AkAgAkEBRwRAA0AgAUH/ASABLQAAIAAtAABB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAAgAUH/ASABLQABIAAtAAFB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAEgAUH/ASABLQACIAAtAAJB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAIgAUH/ASABLQADIAAtAANB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAMgAUH/ASABLQAEIAAtAARB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAQgAUH/ASABLQAFIAAtAAVB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAUgAUH/ASABLQAGIAAtAAZB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAYgAUH/ASABLQAHIAAtAAdB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAcgAEEIaiEAIAEgAmohASAFQQFqIgVBCEcNAAsMAQsgAS0ABiEFIAEtAAAhA0EAIQIDQCABQf8BIANB/wFxIAAtAABB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThs6AAAgAUH/ASABLQABIAAtAAFB+ABrQQR1aiIDQQAgA0EAShsiAyADQf8BThsiAzoAASABQf8BIAEtAAIgAC0AAkH4AGtBBHVqIgRBACAEQQBKGyIEIARB/wFOGzoAAiABQf8BIAEtAAMgAC0AA0H4AGtBBHVqIgRBACAEQQBKGyIEIARB/wFOGzoAAyABQf8BIAEtAAQgAC0ABEH4AGtBBHVqIgRBACAEQQBKGyIEIARB/wFOGzoABCABQf8BIAEtAAUgAC0ABUH4AGtBBHVqIgRBACAEQQBKGyIEIARB/wFOGzoABSABQf8BIAVB/wFxIAAtAAZB+ABrQQR1aiIFQQAgBUEAShsiBSAFQf8BThs6AAYgAUH/ASABLQAHIAAtAAdB+ABrQQR1aiIFQQAgBUEAShsiBSAFQf8BThsiBToAByAAQQhqIQAgAUEBaiEBIAJBAWoiAkEIRw0ACwsL0lICL38CfiMAQYACayIeJAAgACgC6BEhAiAAKAKgASElIAAoAtwRIR8gACgC7BEhAyAAKAKEEkHMLWotAAAiE0EBdiEEIAAoAuQRIRIgACgC4BEhCiAAKAK0AiERIAAoAqQBISMgACgClAFBAkYEQCAAIABBoAFqECsLIAIgJWwhECACIBNsISYgAyAlbCEUIAMgBGwhIQJAIAAoAqgBRQ0AIAAoAqgCIgwgACgCsAJODQAgACgCpAEhBgNAAkAgACgCrAEgDEECdGoiCS0AACIFRQ0AIAAoAtwRIAAoAqABIgMgACgC6BEiBGxBBHRqIAxBBHRqIQggACgChBJBAUYEQCAMQQBKBEAgBUEBdEEJaiELQQAhAgNAIAsgCCACIARsaiIDQQFrIg8tAAAiByADLQAAIg1rQe/JAGotAABBAnQgA0ECay0AACADLQABayIOQe/JAGotAABqTwRAIA8gByAOQfw3aiwAACANIAdrQQNsaiIPQQNqQQN1QfDAAGosAABqQe/DAGotAAA6AAAgAyANIA9BBGpBA3VB8MAAaiwAAGtB78MAai0AADoAAAsgAkEBaiICQRBHDQALCyAJLQACBEAgCEEEaiEPIAVBAXRBAXIhB0EAIQMDQCAHIA8gAyAEbGoiAkEBayIOLQAAIg0gAi0AACILa0HvyQBqLQAAQQJ0IAJBAmstAAAgAi0AAWsiFUHvyQBqLQAAak8EQCAOIA0gFUH8N2osAAAgCyANa0EDbGoiDkEDakEDdUHwwABqLAAAakHvwwBqLQAAOgAAIAIgCyAOQQRqQQN1QfDAAGosAABrQe/DAGotAAA6AAALIANBAWoiA0EQRw0ACyAIQQhqIQ9BACEDA0AgByAPIAMgBGxqIgJBAWsiDi0AACINIAItAAAiC2tB78kAai0AAEECdCACQQJrLQAAIAItAAFrIhVB78kAai0AAGpPBEAgDiANIBVB/DdqLAAAIAsgDWtBA2xqIg5BA2pBA3VB8MAAaiwAAGpB78MAai0AADoAACACIAsgDkEEakEDdUHwwABqLAAAa0HvwwBqLQAAOgAACyADQQFqIgNBEEcNAAsgCEEMaiEPQQAhAwNAIAcgDyADIARsaiICQQFrIg4tAAAiDSACLQAAIgtrQe/JAGotAABBAnQgAkECay0AACACLQABayIVQe/JAGotAABqTwRAIA4gDSAVQfw3aiwAACALIA1rQQNsaiIOQQNqQQN1QfDAAGosAABqQe/DAGotAAA6AAAgAiALIA5BBGpBA3VB8MAAaiwAAGtB78MAai0AADoAAAsgA0EBaiIDQRBHDQALCyAGQQBKBEBBACECQQAgBGshC0EAIARBAXRrIQ8gBUEBdEEJaiEOA0AgDiACIAhqIgMgC2oiFS0AACIHIAMtAAAiDWtB78kAai0AAEECdCADIA9qLQAAIAMgBGotAABrIhZB78kAai0AAGpPBEAgFSAHIBZB/DdqLAAAIA0gB2tBA2xqIhVBA2pBA3VB8MAAaiwAAGpB78MAai0AADoAACADIA0gFUEEakEDdUHwwABqLAAAa0HvwwBqLQAAOgAACyACQQFqIgJBEEcNAAsLIAktAAJFDQFBACECQQAgBGshByAIIARBAnQiCWohDUEAIARBAXRrIQggBUEBdEEBciEFA0AgBSACIA1qIgMgB2oiDi0AACILIAMtAAAiD2tB78kAai0AAEECdCADIAhqLQAAIAMgBGotAABrIhVB78kAai0AAGpPBEAgDiALIBVB/DdqLAAAIA8gC2tBA2xqIg5BA2pBA3VB8MAAaiwAAGpB78MAai0AADoAACADIA8gDkEEakEDdUHwwABqLAAAa0HvwwBqLQAAOgAACyACQQFqIgJBEEcNAAsgCSANaiENQQAhAgNAIAUgAiANaiIDIAdqIg4tAAAiCyADLQAAIg9rQe/JAGotAABBAnQgAyAIai0AACADIARqLQAAayIVQe/JAGotAABqTwRAIA4gCyAVQfw3aiwAACAPIAtrQQNsaiIOQQNqQQN1QfDAAGosAABqQe/DAGotAAA6AAAgAyAPIA5BBGpBA3VB8MAAaiwAAGtB78MAai0AADoAAAsgAkEBaiICQRBHDQALIAkgDWohC0EAIQIDQCAFIAIgC2oiAyAHaiIPLQAAIgkgAy0AACINa0HvyQBqLQAAQQJ0IAMgCGotAAAgAyAEai0AAGsiDkHvyQBqLQAAak8EQCAPIAkgDkH8N2osAAAgDSAJa0EDbGoiD0EDakEDdUHwwABqLAAAakHvwwBqLQAAOgAAIAMgDSAPQQRqQQN1QfDAAGosAABrQe/DAGotAAA6AAALIAJBAWoiAkEQRw0ACwwBCyAJLQABIQIgDEEDdCILIAMgACgC7BEiB2xBA3QiAyAAKALkEWpqIQ0gACgC4BEgA2ogC2ohCyAJLQADIQMgDEEASgRAIAhBASAEQRAgBUEEaiIPIAIgAxAfIAtBASAHQQggDyACIAMQHyANQQEgB0EIIA8gAiADEB8LIAktAAIEQCAIQQRqQQEgBEEQIAUgAiADEBogCEEIakEBIARBECAFIAIgAxAaIAhBDGpBASAEQRAgBSACIAMQGiALQQRqQQEgB0EIIAUgAiADEBogDUEEakEBIAdBCCAFIAIgAxAaCyAGQQBKBEAgCCAEQQFBECAFQQRqIg8gAiADEB8gCyAHQQFBCCAPIAIgAxAfIA0gB0EBQQggDyACIAMQHwsgCS0AAkUNACAIIARBAnQiCWoiCCAEQQFBECAFIAIgAxAaIAggCWoiCCAEQQFBECAFIAIgAxAaIAggCWogBEEBQRAgBSACIAMQGiALIAdBAnQiBGogB0EBQQggBSACIAMQGiAEIA1qIAdBAUEIIAUgAiADEBoLIAxBAWoiDCAAKAKwAkgNAAsLIBBBBHQhCSAfICZrIQsgFEEDdCEEIBIgIWshBiAKICFrIR8CQCAAKAKcBEUNACAAKAKoAiIFIAAoArACIg1ODQAgAEGoBGohCANAIAAoArABIAVBoAZsaiIPLQCcBiISQQRPBEAgACgCoAFBA3QhCiAAKALkESEMIAAoAuARIRAgACgC7BEhByAAKAKkBCECIAAoAqAEIQNBACENA0AgCCADQQJ0aiIDIAMoAgAgCCACQQJ0aigCAGsiFEH/////B3E2AgAgACAAKAKgBEEBaiICQQAgAkE3RxsiAzYCoAQgACAAKAKkBEEBaiICQQAgAkE3RxsiAjYCpAQgDSAeaiAUQQF0QRh1IBJsQQh2QYABczoAACANQQFqIg1BwABHDQALIB4gBUEDdCISIBAgByAKbCIKamogBxAuIA8tAJwGIQ8gACgCpAQhAiAAKAKgBCEDQQAhDQNAIAggA0ECdGoiAyADKAIAIAggAkECdGooAgBrIhBB/////wdxNgIAIAAgACgCoARBAWoiAkEAIAJBN0cbIgM2AqAEIAAgACgCpARBAWoiAkEAIAJBN0cbIgI2AqQEIA0gHmogEEEBdEEYdSAPbEEIdkGAAXM6AAAgDUEBaiINQcAARw0ACyAeIAogDGogEmogBxAuIAAoArACIQ0LIAVBAWoiBSANSA0ACwsgCSALaiEoIAQgBmohDyAEIB9qIR8gEUEBayEpAkACQAJAAkACf0EBIAEoAixFDQAaICNBBHQiAkEQaiEIAn8gIwRAIAIgE2shDSAfIQMgDyEFICgMAQsgACgC5BEgBGohBSAAKALgESAEaiEDQQAhDSAAKALcESAJagshAiABIAU2AhwgASADNgIYIAEgAjYCFEEAIQIgAUEANgJoIAggE0EAICMgKUgbayIDIAEoAlgiCCADIAhIGyEkAkAgACgCrBIiBUUNACANICRODQAgDUEASA0DICQgDWsiDEEATA0DIAEoAgAhFQJAIAAoArQSDQACQCAAKAKoEiIKDQAgAEEBQZABEB4iAjYCqBIgAkUNBSAIrCAVrH4iMUKBgPz/B1oEQCAAQQA2ArgSDAULIAAgMacQFiIDNgK4EiADRQ0EIABBADYCwBIgACADNgK8EiAAKAKwEiEEQYDbACgCAEELRwRAQbzgAEHeADYCAEG44ABB3wA2AgBBtOAAQeAANgIAQYDbAEELNgIAQbDgAEEANgIACyACIBU2AgAgAiADNgKIASACIAEoAgQiBzYCBCAEQQJJDQQgAiAFLQAAQQNxIgk2AgggAiAFLQAAQQJ2QQNxNgIMIAIgBS0AAEEEdkEDcSIDNgIQIAlBAUsNBCADQQFLDQQgBS0AAEE/Sw0EIARBAWshAyACQSBqQQBB5AAQFRogAkEINgJMIAJBCTYCSCACQQo2AkQgAkFAayACNgIAIAIgBzYCHCACIBU2AhggAiABKAJINgJgIAIgASgCTDYCZCACIAEoAlA2AmggASgCVCEEIAIgCDYCcCACIAQ2AmwgCQR/An8gBUEBaiELQQBBAUGQAhAeIgRFDQAaIARBAjYCBEGE2wAoAgBBC0cEQEH84ABBDTYCAEH44ABBDTYCAEH04ABBDjYCAEHw4ABBDzYCAEHs4ABBEDYCAEHo4ABBETYCAEHk4ABBEjYCAEHg4ABBEzYCAEHc4ABBFDYCAEHY4ABBFTYCAEHU4ABBFjYCAEHQ4ABBFzYCAEHM4ABBGDYCAEHI4ABBGTYCAEHE4ABBGjYCAEHA4ABBDTYCAEGE2wBBCzYCAAsgBCACKAIAIgk2AmQgAigCBCEHIAQgAkEYajYCCCAEIAc2AmggAiAHNgIcIAIgCTYCGCACQUBrIAI2AgAgBCADNgIkIAQCfkIAQQggAyADQQhPGyIDRQ0AGiAFMQABIjEgA0EBRg0AGiAFMQACQgiGIDGEIjEgA0ECRg0AGiAFMQADQhCGIDGEIjEgA0EDRg0AGiAFMQAEQhiGIDGEIjEgA0EERg0AGiAFMQAFQiCGIDGEIjEgA0EFRg0AGiAFMQAGQiiGIDGEIjEgA0EGRg0AGiAFMQAHQjCGIDGEIjEgA0EHRg0AGiAFMQAIQjiGIDGECzcDGCAEIAM2AiggBCALNgIgAkAgCSAHQQEgBEEAECNFDQACQAJAAkACQAJAAkAgBCgCsAFBAUcNACAEKAK0AUEDRw0AIAQoAnhBAEoNACAEKAKkASIHQQBMDQEgBCgCqAEhCUEAIQMDQCAJIANBpARsaiIFKAIELQAADQEgBSgCCC0AAA0BIAUoAgwtAAANASAHIANBAWoiA0cNAAsMAQsgAkEANgKEASAENAJoIAQ0AmR+IjIgAigCACIDrEIEhiADQf//A3EiBa18fCIxUA0BIDFCgICAgPz///8/g1AgMUKBgP//AVRxDQEgBEEANgIQDAILIAJBATYChAEgBEEANgIUAkAgBDQCaCAENAJkfiIxQoGA/P8HWgRAIARBADYCEAwBCyAEIDGnEBYiAzYCECADDQQLIARBATYCAAwECyAEIDGnQQJ0EBYiAzYCECADDQELIARBADYCFCAEQQE2AgAMAgsgBCADIDKnQQJ0aiAFQQJ0ajYCFAsgAiAENgIUQQEMAQsgBBAdIAQQEkEACwUgAyAHIBVsTwtFDQQgACgCqBIiCigCEEEBRwRAIABBADYCxBIMAQsgCCANayEMCyAKKAJwIRgCQCAKKAIIRQRAIAooAgAiBCANbCICIAAoArwSaiEDIAAoAqwSIAJqQQFqIQIgACgCwBIhBQJAIAooAgwiCwRAIAxBAEwNASAMQQFHBEAgDEEBcSEIIAxBfnEhB0EAIQsDQCAFIAIgAyAEIAooAgxBAnRBsOAAaigCABEBACADIAIgBGoiAiADIARqIgUgBCAKKAIMQQJ0QbDgAGooAgARAQAgAiAEaiECIAQgBWohAyALQQJqIgsgB0cNAAsgCEUNAiAKKAIMIQsLIAUgAiADIgUgBCALQQJ0QbDgAGooAgARAQAMAQsgDEEATA0AIAxBBE8EQCAMQXxxIQhBACEKA0AgAyACIAQQFCEDIAIgBGoiBSAEaiIHIARqIgkgBGohAiADIARqIAUgBBAUIARqIAcgBBAUIARqIgUgCSAEEBQgBGohAyAKQQRqIgogCEcNAAsLIAxBA3EiCEUNAEEAIQoDQCADIgUgAiAEEBQhAyACIARqIQIgAyAEaiEDIApBAWoiCiAIRw0ACwsgACAFNgLAEiAMIA1qIREMAQsgDCANaiIRIAooAhQiBigCbEwNACAKKAKEAUUEQEH42gAoAgBBC0cEQEH42gBBCzYCAAsgBiAGKAIQIAYoAmQgBigCaCARQeEAECpFDQUMAQsgBkHsAGohFiAGKAJkIhAgBigCaGwhGSAGKAJwIhMgEG0hCAJAAkAgECARbCIbIBNMBEAgBkEwaiEXDAELIBMgCCAQbGshEiAGKAKYASICBH8gBigCoAEgBigCnAEgCCACdWwgEiACdWpBAnRqKAIABUEACyECIAZBMGoiFygCAA0AIAYoApQBISIgBigCECEcIAYoAqgBIAJBpARsaiEUIAZBtAFqIRoDQCASICJxRQRAIAYoAqgBIAYoApgBIgIEfyAGKAKgASAGKAKcASAIIAJ1bCASIAJ1akECdGooAgAFQQALQaQEbGohFAtBACELQQEhBwJAIAYoAiwiA0EgSA0AIAYoAigiAiAGKAIkIgQgAiAESxshBQJAA0AgAiAFRg0BIAYgBikDGEIIiCIxNwMYIAYoAiAgAmoxAAAhMiAGIANBCGsiBDYCLCAGIAJBAWoiAjYCKCAGIDJCOIYgMYQ3AxggA0EPSiEJIAQhAyAJDQALDAELIAYoAiggBigCJEcNACADQcEASA0AQQEhCyAGQQE2AjBBACEHQQAhAwsgBiAUKAIAIAYpAxgiMSADQT9xrYinQf8BcUECdGoiAi0AACIEQQlPBH8gAiACLwECQQJ0aiAxIANBCGoiA0E/ca2Ip0F/IARBCGt0QX9zcUECdGoiAi0AAAUgBAtB/wFxIANqIgM2AiwCQCACLwECIgJB/wFNBEAgEyAcaiACOgAAIBNBAWohEyAQIBJBAWoiEkoEQCAIIQcMAgsgCEEBaiEHQQAhEiAIIBFODQEgB0EPcQ0BAkAgBigCbCIDIAYoAggiAkHUAGogFiACKAIoIgUoAgxBAkkbKAIAIgQgAyAEShsiCiAISg0AIBogCiAHIAYoAhAgBigCZCAKbGogBSgCiAEgAigCACIJIApsaiIEECkgBSgCDCIDRQ0AIAUoAowBIQIgByAKayILQQFxBH8gAiAEIAQgCSADQQJ0QbDgAGooAgARAQAgCkEBaiEKIAkgBCICagUgBAshAyALQQFHBEADQCACIAMgAyAJIAUoAgxBAnRBsOAAaigCABEBACADIAMgCWoiAiACIAkgBSgCDEECdEGw4ABqKAIAEQEAIAIgCWohAyAKQQFqIQsgCkECaiEKIAIhBCAIIAtHDQALCyAFIAQ2AowBCyAGIAc2AmwgBiAHNgJ0DAELQQEhDiACQZcCSw0DAkAgAkGAAmsiBEEESQRAIAMhAgwBCyACQQFxQQJyIAJBggJrIgJBAXYiBXQhCkEAIQQCQCAHQQFzIAJBMUtyRQRAIAYgAyAFaiICNgIsIAVBAnRB8MsAaigCACAxIANBP3GtiKdxIQRBACELIAJBCEgNASAGKAIoIgUgBigCJCIJIAUgCUsbIQwgBSEDAkADQCADIAxGDQEgBiAxQgiIIjE3AxggBigCICADajEAACEyIAYgAkEIayIHNgIsIAYgA0EBaiIDNgIoIAYgMkI4hiAxhCIxNwMYIAJBD0ohICAHIQIgIA0ACwwCCyAFIAlLDQEgAkHBAEkNAQtBASELIAZBATYCMEEAIQILIAQgCmohBAsgBiAUKAIQIDEgAkE/ca2Ip0H/AXFBAnRqIgUtAAAiA0EJTwR/IAUgBS8BAkECdGogMSACQQhqIgJBP3GtiKdBfyADQQhrdEF/c3FBAnRqIgUtAAAFIAMLQf8BcSACaiIDNgIsIAUvAQIhBwJAIANBIEgNACAGKAIoIgIgBigCJCIFIAIgBUsbIQkDQAJAIAIgCUYEQCADIQUMAQsgBiAxQgiIIjE3AxggBigCICACajEAACEyIAYgA0EIayIFNgIsIAYgAkEBaiICNgIoIAYgMkI4hiAxhCIxNwMYIANBD0ohCiAFIQMgCg0BCwsCQCALDQBBACELIAYoAiggBigCJEcEQCAFIQMMAgsgBUHBAE4NACAFIQMMAQsgBkKAgICAEDcCLEEAIQNBASELCwJ/IAdBBE8EQCAHQQFxQQJyIAdBAmsiBUEBdiICdCEMQQAhBwJAAkAgBUExSw0AIAsNACAGIAIgA2oiBTYCLCACQQJ0QfDLAGooAgAgMSADQT9xrYincSEHQQAhCyAFQQhIDQEgBigCKCIDIAYoAiQiCiADIApLGyEgIAMhAgNAIAIgIEcEQCAGIDFCCIgiMTcDGCAGKAIgIAJqMQAAITIgBiAFQQhrIgk2AiwgBiACQQFqIgI2AiggBiAyQjiGIDGEIjE3AxggBUEPSiEnIAkhBSAnDQEMAwsLIAMgCksNASAFQcEASQ0BCyAGQoCAgIAQNwIsQQEhCwsgByAMaiEHCyAHQfcAayAHQQFqQfkATg0AGkEBIAdB8C5qLQAAIgJBBHYgEGwgAkEPcWtBCGoiAiACQQFMGwsiAyATSg0DIARBAWoiByAZIBNrSg0DIBMgHGoiAiADayEMAkACQAJAIAdBCEgNAAJ/AkACQAJAIANBAWsOBAABBAIECyAMLQAAIgVBgYKECGwMAgsgDC8AACIFQYGABGwMAQsgDCgAACIFCyEDIAJBA3FFBEAgByEEDAILIAIgBToAACADQRh3IQMgDEEBaiEMIAJBAWoiAkEDcUUNASACIAwtAAA6AAAgA0EYdyEDIAxBAWohDCACQQFqIgJBA3FFBEAgBEEBayEEDAILIAIgDC0AADoAACADQRh3IQMgDEEBaiEMIAJBAWoiAkEDcUUEQCAEQQJrIQQMAgsgAiAMLQAAOgAAIARBA2shBCADQRh3IQMgAkEBaiECIAxBAWohDAwBCyADIAdIBEAgBEH+////B0sNAkEAIQVBACEDIARBA08EQCAHQXxxIQQDQCACIANqIAMgDGotAAA6AAAgAiADQQFyIglqIAkgDGotAAA6AAAgAiADQQJyIglqIAkgDGotAAA6AAAgAiADQQNyIglqIAkgDGotAAA6AAAgA0EEaiIDIARHDQALCyAHQQNxIgRFDQIDQCACIANqIAMgDGotAAA6AAAgA0EBaiEDIAVBAWoiBSAERw0ACwwCCyACIAwgBxAUGgwBCyAEQQJ2IgVBB3EhCUEAIQtBACEKIAVBAWtBB08EQCAFQfj///8DcSEOA0AgAiAKQQJ0IgVqIAM2AgAgAiAFQQRyaiADNgIAIAIgBUEIcmogAzYCACACIAVBDHJqIAM2AgAgAiAFQRByaiADNgIAIAIgBUEUcmogAzYCACACIAVBGHJqIAM2AgAgAiAFQRxyaiADNgIAIApBCGoiCiAORw0ACwsgCQRAA0AgAiAKQQJ0aiADNgIAIApBAWohCiALQQFqIgsgCUcNAAsLIAQgBEF8cSIDTA0AIAQgA0F/c2ohCUEAIQUgBEEDcSILBEADQCACIANqIAMgDGotAAA6AAAgA0EBaiEDIAVBAWoiBSALRw0ACwsgCUEDSQ0AA0AgAiADaiADIAxqLQAAOgAAIAIgA0EBaiIFaiAFIAxqLQAAOgAAIAIgA0ECaiIFaiAFIAxqLQAAOgAAIAIgA0EDaiIFaiAFIAxqLQAAOgAAIANBBGoiAyAERw0ACwsgByATaiETAkAgECAHIBJqIhJKBEAgCCEHDAELIAhBAWohC0EAIQ4gCCEHA0AgEiAQayESIAciBUEBaiEHAkAgBSARTg0AIAdBD3ENAAJAIAYoAmwiAyAGKAIIIgJB1ABqIBYgAigCKCIIKAIMQQJJGygCACIEIAMgBEobIgogBUoNACAaIAogByAGKAIQIAYoAmQgCmxqIAgoAogBIAIoAgAiCSAKbGoiBBApIAgoAgwiA0UNACAIKAKMASECIAsgDmogCmsiDEEBcQR/IAIgBCAEIAkgA0ECdEGw4ABqKAIAEQEAIApBAWohCiAJIAQiAmoFIAQLIQMgDEEBRwRAA0AgAiADIAMgCSAIKAIMQQJ0QbDgAGooAgARAQAgAyADIAlqIgIgAiAJIAgoAgxBAnRBsOAAaigCABEBACACIAlqIQMgCkEBaiEMIApBAmohCiACIQQgBSAMRw0ACwsgCCAENgKMAQsgBiAHNgJsIAYgBzYCdAsgDkEBaiEOIBAgEkwNAAsLIBMgG04NACASICJxRQ0AIAYoAqgBIAYoApgBIgIEfyAGKAKgASAGKAKcASAHIAJ1bCASIAJ1akECdGooAgAFQQALQaQEbGohFAsCQCAGKAIwBEAgBkEBNgIwDAELQQAhAiAGKAIoIAYoAiRGBEAgBigCLEHAAEohAgsgBiACNgIwIAINACAHIQggEyAbSA0BCwsgByEICwJAIAggESAIIBFIGyIHIAYoAmwiAyAGKAIIIgJB1ABqIBYgAigCKCIEKAIMQQJJGygCACIFIAMgBUobIgpMDQAgBkG0AWogCiAHIAYoAhAgBigCZCAKbGogBCgCiAEgAigCACIFIApsaiIDECkgBCgCDCICRQ0AIAQoAowBIQggByAKayIJQQFxBH8gCCADIAMgBSACQQJ0QbDgAGooAgARAQAgCkEBaiEKIAMhCCADIAVqBSADCyECIAlBAUcEQCAIIQMDQCADIAIgAiAFIAQoAgxBAnRBsOAAaigCABEBACACIAIgBWoiAyADIAUgBCgCDEECdEGw4ABqKAIAEQEAIAMgBWohAiAKQQJqIgogB0cNAAsLIAQgAzYCjAELIAYgBzYCbCAGIAc2AnQgBigCMCELQQAhDgsgFwJ/QQEgCw0AGkEAIAYoAiggBigCJEcNABogBigCLEHAAEoLIgI2AgACQCAORQRAIAJFDQEgEyAZTg0BCyAGQQVBAyACGzYCAAwFCyAGIBM2AnALAkAgESAYTgRAIABBATYCtBIMAQsgACgCtBJFDQELIAAoAqgSIgIEQCACKAIUIgMEQCADEB0gAxASCyACEBILIABBADYCqBIgACgCxBIiAkEATA0AIAJB5ABLDQMgACgCvBIiA0UNAyABKAJQIAEoAkwiBGsiFEEATA0DIAEoAlggASgCVCIFayIbQQBMDQMgG0EBayInQQF2IBRBAWsiIkEBdiACQRluIgIgAkEBdEEBciAUShsiAiACQQF0QQFyIBtKGyIQRQ0AIBRBAXQiCSAJIBBBAXQiHEECamwiAmpB/h9qIghBgID8/wdLDQMgCBAWIgZFDQNBACAQayEZQQAhCiAGIBxBAXIiFyAUbEEBdGoiESAUQQF0ayITQQAgCRAVGiAeQQBBgAIQFSESIAIgBmohFkH/ASEMQQAhCEH/ASEHQQAhGiADIAUgFWxqIARqIgshDgNAIAghAiAHIQNBACEFA0AgEiAFIA5qLQAAIgRqQQE6AAAgBCAIIAIgBEgiGBshCCAEIAogGBshCiAEIAcgAyAESiIYGyEHIAQgDCAYGyEMIAIgBCACIARKGyECIAMgBCADIARIGyEDIAVBAWoiBSAURw0ACyAOIBVqIQ4gGkEBaiIaIBtHDQALIAggB2shAyAXIBdsIQdBfyECQQAhBUEAIQQDQCAEIBJqLQAABH8gBUEBaiEFIAJBAE4EQCAEIAJrIgIgAyACIANIGyEDCyAEBSACCyEIAkAgEiAEQQFyIgJqLQAARQRAIAghAgwBCyAFQQFqIQUgCEEASA0AIAIgCGsiCCADIAMgCEobIQMLIARBAmoiBEGAAkcNAAsgA0ECdCIIIANBDGxBAnUiA2shEiAJIBZqQf4PaiEXQQEhBANAAkAgAyAEIgJODQBBACECIAQgCE4NACAIIARrIANsIBJtIQILIBcgBEEBdCIOaiACQQJ2IgI7AQAgFyAOa0EAIAJrOwEAIARBAWoiBEGACEcNAAsgF0EAOwEAQYCAECAHbiEOIAVBA04EQCAQQQJqIRIgFEF+cSEqIBRBAXEhGiAJQQJrISsgEEF/cyEYIBQgEGshCSAQQQFrISAgEEEBaiIDQX5xISwgA0EBcSEtIBEgIkEBdGohLiAWIANBAXRqIS8gESADIBBqQQF0aiEwIBRBAmsgHEYhHCAGIQUgCyEIA0BBACEHQQAhBEEAIQICQCAiBEADQCARIARBAXQiAmogBCAIai0AACAHQf//A3FqIgcgAiATai8BAGoiHSACIAVqIgIvAQBrOwEAIAIgHTsBACARIARBAXIiHUEBdCICaiAIIB1qLQAAIAdB//8DcWoiByACIBNqLwEAaiIdIAIgBWoiAi8BAGs7AQAgAiAdOwEAIARBAmoiBCAqRw0ACyAEIQIgGkUNAQsgESACQQF0IgRqIAQgE2ovAQAgByACIAhqLQAAamoiAiAEIAVqIgQvAQBrOwEAIAQgAjsBAAsgBSAUQQF0aiIHIBFGIR1BACEEIBAgGUwEQANAIBYgBEEBdGogDiARIBAgBGtBAXRqLwEAIBEgBCAgakEBdGovAQBqQf//A3FsQRB2OwEAIBYgBEEBciICQQF0aiAOIBEgECACa0EBdGovAQAgESAEIBBqQQF0ai8BAGpB//8DcWxBEHY7AQAgBEECaiIEICxHDQALIC0EQCAWIARBAXRqIA4gESAQIARrQQF0ai8BACARIAQgIGpBAXRqLwEAakH//wNxbEEQdjsBAAsCQCADIgIgCU4NACADIQQgGkUEQCAvIA4gMC8BACARLwEAa0H//wNxbEEQdjsBACASIQQLIAkhAiAcDQADQCAWIARBAXRqIA4gESAEIBBqQQF0ai8BACARIAQgGGpBAXRqLwEAa0H//wNxbEEQdjsBACAWIARBAWoiAkEBdGogDiARIAIgEGpBAXRqLwEAIBEgBCAQa0EBdGovAQBrQf//A3FsQRB2OwEAIARBAmoiBCAJRw0ACyAJIQILQQAhBCACIBRIBEADQCAWIAJBAXRqIA4gLi8BAEEBdCARICsgAiAQamtBAXRqLwEAIBEgAiAYakEBdGovAQBqa0H//wNxbEEQdjsBACACQQFqIgIgFEcNAAsLA0ACQCAKIAQgC2oiEy0AACICTA0AIAIgDEwNACATQf8BIBcgFiAEQQF0ai8BACACQQJ0a0EBdGouAQAgAmoiAkEAIAJBAEobIgIgAkH/AU4bOgAACyAEQQFqIgQgFEcNAAsgCyAVaiELCyAVQQAgGSAnSBtBACAZQQBOGyAIaiEIIAUhEyAGIAcgHRshBSAZQQFqIhkgG0cNAAsLIAYQEgsgASAAKAK8EiIDIA0gFWxqIgI2AmggA0UNBAsgDSABKAJUIgNIBEAgASABKAIUIAMgDWsiBCAAKALoEWxqNgIUIAEgACgC7BEgBEEBdWwiBSABKAIYajYCGCABIAEoAhwgBWo2AhwCQCACRQRAQQAhAgwBCyABIAIgASgCACAEbGoiAjYCaAsgAyENC0EBIA0gJE4NABogASABKAJMIgQgASgCFGo2AhQgASAEQQF1IgUgASgCGGo2AhggASABKAIcIAVqNgIcIAIEQCABIAIgBGo2AmgLIAEgDSADazYCCCABICQgDWs2AhAgASABKAJQIARrNgIMIAEgASgCLBEEAAshBCAAKAKcASAlQQFqRw0DICMgKU4NAyAAKALcESAmayAoIAAoAugRQQR0aiAmEBQaQQAgIWsiASAAKALgEWogHyAAKALsEUEDdGogIRAUGiAAKALkESABaiAPIAAoAuwRQQN0aiAhEBQaDAMLIAAoArgSEBIgAEIANwK4EiAAKAKoEiICBEAgAigCFCIDBEAgAxAdIAMQEgsgAhASCyAAQQA2AqgSCyABQQA2AmgLQQAhBCAAKAIADQAgAEHfETYCCCAAQgM3AgALIB5BgAJqJAAgBAvoBQEGfyABQf8BIAEtACAgAC4BAiIEQfucAWxBEHUgBGoiBSAALgEIIgNBjJUCbEEQdSIHIAAuAQBBBGoiBmoiAmpBA3VqIgBBACAAQQBKGyIAIABB/wFOGzoAICABQf8BIAEtACEgAiAEQYyVAmxBEHUiAGpBA3VqIgRBACAEQQBKGyIEIARB/wFOGzoAISABQf8BIAEtACIgAiAAa0EDdWoiBEEAIARBAEobIgQgBEH/AU4bOgAiIAFB/wEgAS0AIyACIAVrQQN1aiICQQAgAkEAShsiAiACQf8BThs6ACMgAUH/ASABLQAAIAMgA0H7nAFsQRB1aiIEIAZqIgIgBWpBA3VqIgNBACADQQBKGyIDIANB/wFOGzoAACABQf8BIAEtAAEgACACakEDdWoiA0EAIANBAEobIgMgA0H/AU4bOgABIAFB/wEgAS0AAiACIABrQQN1aiIDQQAgA0EAShsiAyADQf8BThs6AAIgAUH/ASABLQADIAIgBWtBA3VqIgJBACACQQBKGyICIAJB/wFOGzoAAyABQf8BIAEtAEAgBSAGIAdrIgJqQQN1aiIDQQAgA0EAShsiAyADQf8BThs6AEAgAUH/ASABLQBBIAAgAmpBA3VqIgNBACADQQBKGyIDIANB/wFOGzoAQSABQf8BIAEtAEIgAiAAa0EDdWoiA0EAIANBAEobIgMgA0H/AU4bOgBCIAFB/wEgAS0AQyACIAVrQQN1aiICQQAgAkEAShsiAiACQf8BThs6AEMgAUH/ASABLQBgIAYgBGsiBiAFakEDdWoiAkEAIAJBAEobIgIgAkH/AU4bOgBgIAFB/wEgAS0AYSAAIAZqQQN1aiICQQAgAkEAShsiAiACQf8BThs6AGEgAUH/ASABLQBiIAYgAGtBA3VqIgBBACAAQQBKGyIAIABB/wFOGzoAYiABQf8BIAEtAGMgBiAFa0EDdWoiAEEAIABBAEobIgAgAEH/AU4bOgBjC5QFAQh/AkAgBUEATA0AIAVBAUcEQCAFQQFxIQwgBUF+cSENIARBAEwhDgNAAkAgDg0AQQAhBQJAIAZFBEADQAJAIAIgBWotAAAiB0H/AUYNACAHRQRAIAAgBWpBADoAAAwBCyAAIAVqIgggByAILQAAbEGBggRsQYCAgARqQRh2OgAACyAFQQFqIgUgBEcNAAwCCwALA0ACQCACIAVqLQAAIgdB/wFGDQAgB0UEQCAAIAVqQQA6AAAMAQsgACAFaiIIIAgtAABBgICAeCAHbmxBgICABGpBGHY6AAALIAVBAWoiBSAERw0ACwsgAiADaiEIIAAgAWohB0EAIQUgBkUEQANAAkAgBSAIai0AACIJQf8BRg0AIAlFBEAgBSAHakEAOgAADAELIAUgB2oiCiAJIAotAABsQYGCBGxBgICABGpBGHY6AAALIAVBAWoiBSAERw0ADAILAAsDQAJAIAUgCGotAAAiCUH/AUYNACAJRQRAIAUgB2pBADoAAAwBCyAFIAdqIgogCi0AAEGAgIB4IAlubEGAgIAEakEYdjoAAAsgBUEBaiIFIARHDQALCyACIANqIANqIQIgACABaiABaiEAIAtBAmoiCyANRw0ACyAMRQ0BCyAEQQBMDQBBACEFIAZFBEADQAJAIAIgBWotAAAiAUH/AUYNACABRQRAIAAgBWpBADoAAAwBCyAAIAVqIgMgASADLQAAbEGBggRsQYCAgARqQRh2OgAACyAFQQFqIgUgBEcNAAwCCwALA0ACQCACIAVqLQAAIgFB/wFGDQAgAUUEQCAAIAVqQQA6AAAMAQsgACAFaiIDIAMtAABBgICAeCABbmxBgICABGpBGHY6AAALIAVBAWoiBSAERw0ACwsL7gMCB38BfiABKAIEIQggASgCACEJAkACQAJAIAAEQCABIAAoAggiB0EASjYCSCAJIQQgCCEGIAdBAEwNAUEAIQcgACgCDCIEQX5xIAQgAkEKSyICGyIDQQBIDQIgACgCECIEQX5xIAQgAhsiBUEASA0CIAAoAhQiBEEATA0CIAAoAhgiBkEATA0CIAMgBGogCUoNAiAFIAZqIAhMDQEMAgsgAUEANgJIIAkhBCAIIQYLIAEgBTYCVCABIAM2AkwgASAGNgIQIAEgBDYCDCABIAUgBmo2AlggASADIARqNgJQIABFDQEgASAAKAIcIgJBAEo2AlxBASEDIAJBAEoEQCAAKAIkIQUgACgCICEDAkAgBkEATA0AIAMNACAGrSIKIAWsIASsfnxCAX0gCoCnIQMLAkAgBEEATA0AIAUNACAErSIKIAOsIAasfnxCAX0gCoCnIQULQQAhByADQQBMDQEgBUEATA0BIAEgBTYCZCABIAM2AmAgAkEATCEDCyABIAAoAgBBAEc2AkQgASAAKAIERTYCOCADRQRAQQAhACABKAJgIAlBA2xBBG1IBEAgASgCZCAIQQNsQQRtSCEACyABQQA2AjggASAANgJEC0EBIQcLIAcPCyABQQA2AkQgAUEANgJcIAFBATYCOEEBCzIBAn8gAEGQ2QA2AgAgACgCBEEMayIBIAEoAghBAWsiAjYCCCACQQBIBEAgARASCyAAC54QAhV/An4jAEEQayIQJAAgBwR/IAcoAggFQQALIQsCQCABQQxJBEBBByENDAELIAEhCQJ/IAAiDkGeCxAYIg9FBEBBAyENIABBCGpBjAsQGA0CIAAoAAQiE0EJakEVSQ0CIAtBAEcgEyABQQhrS3EEQEEHIQ0MAwsgAUEMayIJQQhJBEBBByENDAMLIABBDGohDgsgDkGHCxAYIhUEQEEAIQ0gDgwBC0EDIQ0gDigABEEKRw0BIAlBEkkEQEEHIQ0MAgsgDi8ADCAOLQAOQRB0ckEBaiIYrSAOLwAPIA4tABFBEHRyQQFqIhmtfkIgiKcNASAPDQEgCUESayEJIA4oAAgiDUECcUEBdiEMIA5BEmoLIQggBARAIAQgDUEEdkEBcTYCAAsgBQRAIAUgDDYCAAsgBgRAIAZBADYCAAsgECAZNgIIIBAgGDYCDEEAIQUCQCAHRSAMcQ0AAkAgCUEESQ0AAn8CfwJAAkAgDyAVckUNAEEAIQ4gD0UNASAVRQ0BIAhBmQsQGEUNAEEADAILIAlBCEkNAwJAIBNFBEBBACEOA0AgCCgABCIPQXZLBEBBAyENDAkLIAhBoRIQGEUNAiAIQZELEBhFDQMgCSAPQQlqQX5xIgpJDQYgBSAIQQhqIAhBmQsQGCINGyEFIA4gDyANGyEOIAggCmohCCAJIAprIglBCE8NAAsMBQtBFiEPQQAhDgNAQQMhDSAIKAAEIhFBdksNByARQQlqQX5xIgogD2oiDyATSw0HIAhBoRIQGEUNASAIQZELEBhFDQIgCSAKSQ0FIAUgCEEIaiAIQZkLEBgiDRshBSAOIBEgDRshDiAIIApqIQggCSAKayIJQQhPDQALDAQLIBMhCiAIQZELEBhFDAILIBMLIQogCEGRCxAYIQ8gCUEISQ0BIA9FCyERAkBBACAIQaESEBggERtFBEAgCCgABCEPIApBDE8EQEEDIQ0gDyAKQQxrSw0FCyALQQAgDyAJQQhrIglLGw0CIAhBCGohCAwBC0EAIREgCC0AAEEvRgRAIAgtAARBIEkhEQsgCSEPC0EDIQ0gD0F2Sw0CAkAgBkUNACAMDQAgBkECQQEgERs2AgALAkAgEUUEQCAJQQpJDQIgEEEMaiEGIBBBCGohCUEAIQoCQCAIRQ0AIAgtAANBnQFHDQAgCC0ABEEBRw0AIAgtAAVBKkcNACAILQAAIgxBGXFBEEcNACAILQABQQh0IAgtAAJBEHRyIAxyQQV2IA9PDQAgCC0ABiAILQAHQQh0QYD+AHFyIgxFDQAgCC0ACCAILQAJQQh0QYD+AHFyIgtFDQAgBgRAIAYgDDYCAAtBASEKIAlFDQAgCSALNgIACyAKDQEMBAsgCUEFSQ0BAn8gEEEMaiEaIBBBCGohGwJAIAhFDQAgCC0AAEEvRw0AIAgxAAQiHkIfVg0AQQghCwJAAkACQEEIIAkgCUEITxsiCg4CAgEACyAIMQABQgiGQi+EIR0gCkECRg0BIAgxAAJCEIYgHYQhHSAKQQNGDQEgCDEAA0IYhiAdhCEdIApBBEYNASAeQiCGIB2EIR0gCkEFRg0BIAgxAAVCKIYgHYQhHSAKQQZGDQEgCDEABkIwhiAdhCEdIApBB0YNASAIMQAHQjiGIB2EIR0MAQtCLyEdCyAdIR4gCSIGQQlPBEAgCCAKajEAAEI4hiAdQgiIhCEeQQAhCyAKQQFqIQYLIB1C/wGDQi9SDQAgBiAJIAYgCUsiFhshCiALQQ5qIQwgHiALrYinQf//AHEhFAJAAn8CQANAIAYgCkYNASAGIAhqMQAAQjiGIB5CCIiEIR4gBkEBaiEGIAxBD0ohEiAMQQhrIgshDCASDQALIAtBDmohDCAeIAtBP3GtiKdB//8AcSEWIBRBAWoiFCALQXpODQEaDAILQQAgFiAMQcEASXIiBkUNAxogDEEAIAYbIgZBDmohDCAeIAZBP3GtiKdB//8AcSEWIAohBiAUQQFqCyEUIAYgCSAGIAlLIgsbIQoCQANAIAYgCkYNASAGIAhqMQAAQjiGIB5CCIiEIR4gBkEBaiEGIAxBD0ohEiAMQQhrIQwgEg0ACwwBCyALBEAgCiEGDAELIAohBiAMQcAASw0BCyAMQQFqIQsCQAJ/AkACQCAMQQdIBEAgHiEdDAELIAYgCSAGIAlLIhIbIQogHiEdA0AgBiAKRg0CIAYgCGoxAABCOIYgHUIIiIQhHSAGQQFqIQYgC0EPSiEXIAtBCGshCyAXDQALCyAdIAtBP3GtiKdBB3EiCiALQQVODQEaDAILIBJFIAtBwABLcQ0CIAohBiAdIAtBP3GtiKdBB3ELIQogBiAJIAYgCUsiEhshFyALQQNqIQkDQCAGIBdHBEAgBkEBaiEGIAlBD0ohCyAJQQhrIQkgCw0BDAILCyASDQAgCUHAAEsNAQsgCg0AIBoEQCAaIBQ2AgALIBsEQCAbIBZBAWo2AgALQQEhHCAERQ0AIAQgHiAMQT9xrYinQQFxNgIACyAcC0UNAwsgFUUEQCAYIBAoAgxHDQMgGSAQKAIIRw0DCyAHRQ0BIAcgETYCICAHIBM2AhwgByAPNgIYIAcgDjYCFCAHIAU2AhAgB0EANgIIIAcgATYCBCAHIAA2AgAgByAIIABrNgIMDAELIAcEQEEHIQ0MAgtBByENIBUNAQsgBARAIAQgBCgCACAFQQBHcjYCAAsgAgRAIAIgECgCDDYCAAtBACENIANFDQAgAyAQKAIINgIACyAQQRBqJAAgDQscACAAIAFBCCACpyACQiCIpyADpyADQiCIpxAOCwgAIAAQMxASC10BAX8gACgCECIDRQRAIABBATYCJCAAIAI2AhggACABNgIQDwsCQCABIANGBEAgACgCGEECRw0BIAAgAjYCGA8LIABBAToANiAAQQI2AhggACAAKAIkQQFqNgIkCws2AQF/QQEgACAAQQFNGyEAAkADQCAAEBYiAQ0BQdTiACgCACIBBEAgAREKAAwBCwsQCQALIAELmgEAIABBAToANQJAIAAoAgQgAkcNACAAQQE6ADQCQCAAKAIQIgJFBEAgAEEBNgIkIAAgAzYCGCAAIAE2AhAgA0EBRw0CIAAoAjBBAUYNAQwCCyABIAJGBEAgACgCGCICQQJGBEAgACADNgIYIAMhAgsgACgCMEEBRw0CIAJBAUYNAQwCCyAAIAAoAiRBAWo2AiQLIABBAToANgsLugIBBH8jAEFAaiICJAAgACgCACIDQQRrKAIAIQQgA0EIaygCACEFIAJCADcCHCACQgA3AiQgAkIANwIsIAJCADcCNEEAIQMgAkEANgA7IAJCADcCFCACQaTVADYCECACIAA2AgwgAiABNgIIIAAgBWohAAJAIAQgAUEAEBkEQCACQQE2AjggBCACQQhqIAAgAEEBQQAgBCgCACgCFBEMACAAQQAgAigCIEEBRhshAwwBCyAEIAJBCGogAEEBQQAgBCgCACgCGBECAAJAAkAgAigCLA4CAAECCyACKAIcQQAgAigCKEEBRhtBACACKAIkQQFGG0EAIAIoAjBBAUYbIQMMAQsgAigCIEEBRwRAIAIoAjANASACKAIkQQFHDQEgAigCKEEBRw0BCyACKAIYIQMLIAJBQGskACADCwMAAQsEACAAC/UDAEGU1wBB5QoQDEGg1wBBzQlBAUEBQQAQC0Gs1wBBsQlBAUGAf0H/ABABQcTXAEGqCUEBQYB/Qf8AEAFBuNcAQagJQQFBAEH/ARABQdDXAEGbCEECQYCAfkH//wEQAUHc1wBBkghBAkEAQf//AxABQejXAEGqCEEEQYCAgIB4Qf////8HEAFB9NcAQaEIQQRBAEF/EAFBgNgAQYAKQQRBgICAgHhB/////wcQAUGM2ABB9wlBBEEAQX8QAUGY2ABBtQhCgICAgICAgICAf0L///////////8AEDVBpNgAQbQIQgBCfxA1QbDYAEGuCEEEEApBvNgAQckKQQgQCkH8zgBBnwoQBkHEzwBB2A4QBkGM0ABBBEGFChAFQdjQAEECQasKEAVBpNEAQQRBugoQBUHA0QBB0gkQEUHo0QBBAEGTDhAAQZDSAEEAQfkOEABBuNIAQQFBsQ4QAEHg0gBBAkGjCxAAQYjTAEEDQcILEABBsNMAQQRB6gsQAEHY0wBBBUGHDBAAQYDUAEEEQZ4PEABBqNQAQQVBvA8QAEGQ0gBBAEHtDBAAQbjSAEEBQcwMEABB4NIAQQJBrw0QAEGI0wBBA0GNDRAAQbDTAEEEQfINEABB2NMAQQVB0A0QAEHQ1ABBBkGtDBAAQfjUAEEHQeMPEAALrAkCCH8FfkECIQYCQCABQQBMDQAgAEEATA0AIANFDQACQCACRQ0AAkAgAigCCEUEQCABIQQgACEFDAELIAIoAgxBfnEiCUEASA0CIAIoAhBBfnEiB0EASA0CIAIoAhQiBUEATA0CIAIoAhgiBEEATA0CIAUgCWogAEoNAiAEIAdqIAFKDQILIAIoAhxFBEAgBCEBIAUhAAwBCyACKAIkIQEgAigCICEAAkAgBEEATA0AIAANACAErSIMIAGsIAWsfnxCAX0gDICnIQALAkAgBUEATA0AIAENACAFrSIMIACsIASsfnxCAX0gDICnIQELIABBAEwNASABQQBMDQELIAMgATYCCCADIAA2AgQgAEEATA0AIAFBAEwNACADKAIAIgVBDEsNAAJAAkACfwJAAkACQCADKAIMQQBKDQAgAygCUA0AIACtIgwgBUHoL2otAAAiBK1+QiCIpw0GIAGtIg0gACAEbCIIrH4hDgJ/IAVBC0kEQEIAIQxCACENQQAhBEEADAELIAwgDX5CACAFQQxGIgYbIQwgAEEBakEBdiIErSABQQFqQQF2rX4hDSAAQQAgBhsLIQlBASEGIA1CAYYiDyAMIA58fCIQQoCA/P8HVg0GIBCnEBYiB0UNBiADIAc2AhAgAyAHNgJQIA6nIQYgBUELSQ0CIAMgBjYCMCADIAg2AiAgAyANpyIINgI0IAMgBDYCJCADIAYgB2oiBjYCFCADIAg2AjggAyAENgIoIAMgBiAIajYCGCAFQQxGBEAgAyAGIA+najYCHAsgAyAJNgIsIAMgDD4CPCADQRBqIQkgBUEKSyEIDAELIAVBCkshCCADQRBqIgkgBUELSQ0CGgtBAiEGIAMoAigiBCAEQR91IgRzIARrIgcgAEEBakECbSIETiADKAIkIgogCkEfdSIKcyAKayIKIAROIAMoAiAiCyALQR91IgtzIAtrIgsgAE4gAzUCMCAArCIMIAFBAWusIg0gC61+fFogAzUCNCAErCIOIAFBAWpBAm1BAWusIg8gCq1+fFpxIAM1AjggB60gD34gDnxacXFxcSADKAIQIgdBAEdxIAMoAhQiBEEAR3EgAygCGCIKQQBHcSELIAVBDEcNAiAAIAMoAiwiACAAQR91IgBzIABrIgBMIAM1AjwgAK0gDX4gDHxacSADKAIcQQBHcSALcQ0DDAQLIAMgBjYCGCADIAg2AhQgBUEKSyEIIANBEGoLIQlBAiEGIAMoAhQiBCAEQR91IgdzIAdrIgcgACAFQegvai0AAGwiAE4gAygCGCIKrSAArCABQQFrrCAHrX58WnEgAygCECIHQQBHcQ0BDAILIAtFDQELQQAhBiACRQ0AIAIoAjBFDQAgAUEBayEAIAgEfyADQSBqQQAgAygCICIBazYCACADQSRqQQAgAygCJCICazYCACADQShqQQAgAygCKCIFazYCACADIAcgACABbGo2AhAgAyAEIAIgAEEBdSIBbGo2AhQgAyAKIAEgBWxqNgIYIANBHGoiCSgCACIHRQ0BIANBLGoFIANBFGoLIQMgCSAHIAAgAygCACIAbGo2AgAgA0EAIABrNgIACyAGC9oEAQZ/AkAgA0ECSA0AQQEgA0EBdiIFIAVBAU0bIQhBACEFIARFBEADQCABIAVqIgYgBi0AACAAIAVBA3RqIgcoAgQiBkEPdkH+A3EgBygCACIHQQ92Qf4DcWoiCUGJtH9sIAZBB3ZB/gNxIAdBB3ZB/gNxaiIKQffqfmxqIAZBAXRB/gNxIAdBAXRB/gNxaiIGQYDhAWxqQYCAiBBqQRJ2akEBakEBdjoAACACIAVqIgcgBy0AACAJQYDhAWwgCkHMw35saiAGQbRbbGpBgICIEGpBEnZqQQFqQQF2OgAAIAVBAWoiBSAIRw0ADAILAAsDQCABIAVqIAAgBUEDdGoiBygCBCIGQQ92Qf4DcSAHKAIAIgdBD3ZB/gNxaiIJQYm0/x9sIAZBB3ZB/gNxIAdBB3ZB/gNxaiIKQffq/h9saiAGQQF0Qf4DcSAHQQF0Qf4DcWoiBkGA4QFsakGAgIgQakESdjoAACACIAVqIAlBgOEBbCAKQczD/h9saiAGQbTb/x9sakGAgIgQakESdjoAACAFQQFqIgUgCEcNAAsLIANBAXEEQCAAIAhBA3RqKAIAIgBBDnZB/AdxIgNBgOEBbCAAQQZ2QfwHcSIFQczDfmxqIABBAnRB/AdxIgZBtFtsakGAgIgQakESdiEAIANBibR/bCAFQffqfmxqIAZBgOEBbGpBgICIEGpBEnYhAyAEBEAgASAIaiADOgAAIAIgCGogADoAAA8LIAEgCGoiASADIAEtAABqQQFqQQF2OgAAIAIgCGoiASAAIAEtAABqQQFqQQF2OgAACwvDCgEDfwJAAkACQAJAAkACQAJAAkACQAJAAkACQCACDgsAAQMEBggKAgUHCQsLIAFBAEwNCiAAIAFBAnRqIQIDQCADIAAoAgAiAToAAiADIAFBCHY6AAEgAyABQRB2OgAAIANBA2ohAyAAQQRqIgAgAkkNAAsMCgsgAUEATA0JIAAgAUECdGohAgNAIAMgACgCACIBOgACIAMgAUEYdjoAAyADIAFBCHY6AAEgAyABQRB2OgAAIANBBGohAyAAQQRqIgAgAkkNAAsMCQsgAUEATA0IIAAgAUECdGohBSADIQIDQCACIAAoAgAiBDoAAiACIARBGHY6AAMgAiAEQQh2OgABIAIgBEEQdjoAACACQQRqIQIgAEEEaiIAIAVJDQALIANBA2ohBUEAIQADQCAFIABBAnQiAmotAAAiBEH/AUcEQCACIANqIgYgBEGBgQJsIgQgBi0AAGxBF3Y6AAAgAyACQQFyaiIGIAQgBi0AAGxBF3Y6AAAgAyACQQJyaiICIAQgAi0AAGxBF3Y6AAALIABBAWoiACABRw0ACwwICyABQQBMDQcgACABQQJ0aiECA0AgAyAAKAIAIgE6AAAgAyABQRB2OgACIAMgAUEIdjoAASADQQNqIQMgAEEEaiIAIAJJDQALDAcLIAMgACABQQJ0EBQaDwsgAyAAIAFBAnQQFCEAIAFBAEwNBSAAQQNqIQVBACEDA0AgBSADQQJ0IgJqLQAAIgRB/wFHBEAgACACaiIGIARBgYECbCIEIAYtAABsQRd2OgAAIAAgAkEBcmoiBiAEIAYtAABsQRd2OgAAIAAgAkECcmoiAiAEIAItAABsQRd2OgAACyADQQFqIgMgAUcNAAsMBQsgAUEATA0EIAAgAUECdGohAgNAIAMgACgCACIBQRh0IAFBgP4DcUEIdHIgAUEIdkGA/gNxIAFBGHZycjYAACADQQRqIQMgAEEEaiIAIAJJDQALDAQLIAFBAEwNAyAAIAFBAnRqIQUgAyECA0AgAiAAKAIAIgRBGHQgBEGA/gNxQQh0ciAEQQh2QYD+A3EgBEEYdnJyNgAAIAJBBGohAiAAQQRqIgAgBUkNAAsgA0EBaiECQQAhAANAIAMgAEECdCIEai0AACIFQf8BRwRAIAIgBGoiBiAFQYGBAmwiBSAGLQAAbEEXdjoAACACIARBAXJqIgYgBSAGLQAAbEEXdjoAACACIARBAnJqIgQgBSAELQAAbEEXdjoAAAsgAEEBaiIAIAFHDQALDAMLIAFBAEwNAiAAIAFBAnRqIQIDQCADIAAoAgAiAUHwAXEgAUEcdnI6AAEgAyABQRB2QfABcSABQQx2QQ9xcjoAACADQQJqIQMgAEEEaiIAIAJJDQALDAILIAFBAEwNASAAIAFBAnRqIQUgAyECA0AgAiAAKAIAIgRB8AFxIARBHHZyOgABIAIgBEEQdkHwAXEgBEEMdkEPcXI6AAAgAkECaiECIABBBGoiACAFSQ0AC0EAIQIDQCADIAJBAXRqIgBBAWogAC0AASIEQQ9xIgZBkSJsIgUgBEHwAXEgBEEEdnJsQRB2QfABcSAGcjoAACAAIAUgAC0AACIAQfABcSAAQQR2cmxBEHZB8AFxIAUgAEEPcSAAQQR0ckH/AXFsQRR2cjoAACACQQFqIgIgAUcNAAsMAQsgAUEATA0AIAAgAUECdGohAgNAIAMgACgCACIBQQV2QeABcSABQQN2QR9xcjoAASADIAFBEHZB+AFxIAFBDXZBB3FyOgAAIANBAmohAyAAQQRqIgAgAkkNAAsLC6cHAQh/AkAgA0EATA0AIANBA3EhCiADQQRPBEAgA0F8cSEJIAJBAEwhCwNAQQAhAyALRQRAA0AgACADQQJ0aiIGKAIAIgRB////d00EQEEAIQUgBiAEQYCAgAhPBH8gBEGAgIB4cSAEQRh2QYGCBGwiBSAEQf8BcWxBgICABGpBGHZyIAUgBEEIdkH/AXFsQYCAgARqQRB2QYD+A3FyIAUgBEEQdkH/AXFsQYCAgARqQQh2QYCA/AdxcgVBAAs2AgALIANBAWoiAyACRw0ACyAAIAFqIQZBACEDA0AgBiADQQJ0aiIIKAIAIgRB////d00EQEEAIQUgCCAEQYCAgAhPBH8gBEGAgIB4cSAEQRh2QYGCBGwiBSAEQf8BcWxBgICABGpBGHZyIAUgBEEIdkH/AXFsQYCAgARqQRB2QYD+A3FyIAUgBEEQdkH/AXFsQYCAgARqQQh2QYCA/AdxcgVBAAs2AgALIANBAWoiAyACRw0ACyABIAZqIQZBACEDA0AgBiADQQJ0aiIIKAIAIgRB////d00EQEEAIQUgCCAEQYCAgAhPBH8gBEGAgIB4cSAEQRh2QYGCBGwiBSAEQf8BcWxBgICABGpBGHZyIAUgBEEIdkH/AXFsQYCAgARqQRB2QYD+A3FyIAUgBEEQdkH/AXFsQYCAgARqQQh2QYCA/AdxcgVBAAs2AgALIANBAWoiAyACRw0ACyABIAZqIQZBACEDA0AgBiADQQJ0aiIIKAIAIgRB////d00EQEEAIQUgCCAEQYCAgAhPBH8gBEGAgIB4cSAEQRh2QYGCBGwiBSAEQf8BcWxBgICABGpBGHZyIAUgBEEIdkH/AXFsQYCAgARqQRB2QYD+A3FyIAUgBEEQdkH/AXFsQYCAgARqQQh2QYCA/AdxcgVBAAs2AgALIANBAWoiAyACRw0ACwsgACABaiABaiABaiABaiEAIAdBBGoiByAJRw0ACwsgCkUNAEEAIQcgAkEATCEGA0BBACEDIAZFBEADQCAAIANBAnRqIgkoAgAiBEH///93TQRAQQAhBSAJIARBgICACE8EfyAEQYCAgHhxIARBGHZBgYIEbCIFIARB/wFxbEGAgIAEakEYdnIgBSAEQQh2Qf8BcWxBgICABGpBEHZBgP4DcXIgBSAEQRB2Qf8BcWxBgICABGpBCHZBgID8B3FyBUEACzYCAAsgA0EBaiIDIAJHDQALCyAAIAFqIQAgB0EBaiIHIApHDQALCwuIAgEFfwJAIAJBAEwNACADQQRrKAIAIQEgAkEBRwRAIAJBAXEhBSACQX5xIQYDQCADIARBAnQiAmogACACaigCACIHQYD+g3hxIAFBgP6DeHFqQYD+g3hxIgggB0H/gfwHcSABQf+B/AdxakH/gfwHcSIBcjYCACADIAJBBHIiAmogACACaigCACICQYD+g3hxIAhqQYD+g3hxIAJB/4H8B3EgAWpB/4H8B3FyIgE2AgAgBEECaiIEIAZHDQALIAVFDQELIAMgBEECdCICaiAAIAJqKAIAIgBBgP6DeHEgAUGA/oN4cWpBgP6DeHEgAEH/gfwHcSABQf+B/AdxakH/gfwHcXI2AgALC2cBA38gAkEASgRAA0AgAyAFQQJ0IgRqIAAgBGooAgAiBkGA/oN4cSABIARqKAIAIgRBgP6DeHFqQYD+g3hxIAZB/4H8B3EgBEH/gfwHcWpB/4H8B3FyNgIAIAVBAWoiBSACRw0ACwsLcgEDfyACQQBKBEAgAUEEaiEFQQAhAQNAIAMgAUECdCIEaiAAIARqKAIAIgZBgP6DeHEgBCAFaigCACIEQYD+g3hxakGA/oN4cSAGQf+B/AdxIARB/4H8B3FqQf+B/AdxcjYCACABQQFqIgEgAkcNAAsLC3IBA38gAkEASgRAIAFBBGshBUEAIQEDQCADIAFBAnQiBGogACAEaigCACIGQYD+g3hxIAQgBWooAgAiBEGA/oN4cWpBgP6DeHEgBkH/gfwHcSAEQf+B/AdxakH/gfwHcXI2AgAgAUEBaiIBIAJHDQALCwukAQEFfyACQQBKBEAgA0EEaygCACEEA0AgAyAGQQJ0IgVqIAEgBWoiBygCBCIIIARzQQF2Qf/+/fsHcSAEIAhxaiIEIAcoAgAiB3NBAXZB//79+wdxIAQgB3FqIgRBgP6DeHEgACAFaigCACIFQYD+g3hxakGA/oN4cSAEQf+B/AdxIAVB/4H8B3FqQf+B/AdxciIENgIAIAZBAWoiBiACRw0ACwsLjwEBBH8gAkEASgRAIAFBBGshBiADQQRrKAIAIQEDQCADIAVBAnQiBGogBCAGaigCACIHIAFzQQF2Qf/+/fsHcSABIAdxaiIBQYD+g3hxIAAgBGooAgAiBEGA/oN4cWpBgP6DeHEgAUH/gfwHcSAEQf+B/AdxakH/gfwHcXIiATYCACAFQQFqIgUgAkcNAAsLC4gBAQR/IAJBAEoEQCADQQRrKAIAIQQDQCADIAZBAnQiBWogASAFaigCACIHIARzQQF2Qf/+/fsHcSAEIAdxaiIEQYD+g3hxIAAgBWooAgAiBUGA/oN4cWpBgP6DeHEgBEH/gfwHcSAFQf+B/AdxakH/gfwHcXIiBDYCACAGQQFqIgYgAkcNAAsLC4YBAQR/IAJBAEoEQANAIAMgBkECdCIFaiABIAVqIgQoAgAiByAEQQRrKAIAIgRzQQF2Qf/+/fsHcSAEIAdxaiIEQYD+g3hxIAAgBWooAgAiBUGA/oN4cWpBgP6DeHEgBEH/gfwHcSAFQf+B/AdxakH/gfwHcXI2AgAgBkEBaiIGIAJHDQALCwuDAQEEfyACQQBKBEADQCADIAZBAnQiBWogASAFaiIEKAIEIgcgBCgCACIEc0EBdkH//v37B3EgBCAHcWoiBEGA/oN4cSAAIAVqKAIAIgVBgP6DeHFqQYD+g3hxIARB/4H8B3EgBUH/gfwHcWpB/4H8B3FyNgIAIAZBAWoiBiACRw0ACwsLwQEBBn8gAkEASgRAIANBBGsoAgAhBANAIAMgB0ECdCIFaiABIAVqIgYoAgQiCCAGKAIAIglzQQF2Qf/+/fsHcSAIIAlxaiIIIAZBBGsoAgAiBiAEc0EBdkH//v37B3EgBCAGcWoiBHNBAXZB//79+wdxIAQgCHFqIgRBgP6DeHEgACAFaigCACIFQYD+g3hxakGA/oN4cSAEQf+B/AdxIAVB/4H8B3FqQf+B/AdxciIENgIAIAdBAWoiByACRw0ACwsL4wIBCX8gAkEASgRAIANBBGsoAgAhBQNAIAMgCkECdCIMaiABIAxqIgYoAgAiByAFIAVB/wFxIAZBBGsoAgAiBkH/AXEiBGsiCCAIQR91IghzIAhrIAVBGHYgBkEYdiIIayIJIAlBH3UiCXMgCWtqIAVBCHZB/wFxIAZBCHZB/wFxIglrIgsgC0EfdSILcyALa2ogB0H/AXEgBGsiBCAEQR91IgRzIARrIAdBGHYgCGsiBCAEQR91IgRzIARraiAHQQh2Qf8BcSAJayIEIARBH3UiBHMgBGtqIAdBEHZB/wFxIAZBEHZB/wFxIgdrIgYgBkEfdSIGcyAGa2prIAVBEHZB/wFxIAdrIgUgBUEfdSIFcyAFa2pBAEwbIgVBgP6DeHEgACAMaigCACIHQYD+g3hxakGA/oN4cSAFQf+B/AdxIAdB/4H8B3FqQf+B/AdxciIFNgIAIApBAWoiCiACRw0ACwsLrAIBBn8gAkEASgRAIANBBGsoAgAhBANAIAMgCEECdCIJaiABIAlqIgYoAgAiB0EYdiAEQRh2aiAGQQRrKAIAIgZBGHZrIgUgBUF/c0EYdiAFQYACSRtBGHQgB0H/AXEgBEH/AXFqIAZB/wFxayIFIAVBf3NBGHYgBUGAAkkbciAHQRB2Qf8BcSAEQRB2Qf8BcWogBkEQdkH/AXFrIgUgBUF/c0EYdiAFQYACSRtBEHRyIAdBCHZB/wFxIARBCHZB/wFxaiAGQQh2Qf8BcWsiBCAEQX9zQRh2IARBgAJJG0EIdHIiBEGA/oN4cSAAIAlqKAIAIgdBgP6DeHFqQYD+g3hxIARB/4H8B3EgB0H/gfwHcWpB/4H8B3FyIgQ2AgAgCEEBaiIIIAJHDQALCwvEAgEFfyACQQBKBEAgA0EEaygCACEFA0AgAyAHQQJ0IghqIAEgCGoiBigCACIEIAVzQQF2Qf/+/fsHcSAEIAVxaiIFQRh2IgQgBCAGQQRrKAIAIgZBGHZrQQJtwWoiBCAEQX9zQRh2IARBgAJJG0EYdCAFQf8BcSIEIAQgBkH/AXFrQQJtwWoiBCAEQX9zQRh2IARBgAJJG3IgBUEQdkH/AXEiBCAEIAZBEHZB/wFxa0ECbcFqIgQgBEF/c0EYdiAEQYACSRtBEHRyIAVBCHZB/wFxIgUgBSAGQQh2Qf8BcWtBAm3BaiIFIAVBf3NBGHYgBUGAAkkbQQh0ciIFQYD+g3hxIAAgCGooAgAiBkGA/oN4cWpBgP6DeHEgBUH/gfwHcSAGQf+B/AdxakH/gfwHcXIiBTYCACAHQQFqIgcgAkcNAAsLC40BAQJ/AkAgAkEATA0AQQAhASACQQFHBEAgAkEBcSEEIAJBfnEhBQNAIAMgAUECdCICaiAAIAJqKAIAQYCAgAhrNgIAIAMgAkEEciICaiAAIAJqKAIAQYCAgAhrNgIAIAFBAmoiASAFRw0ACyAERQ0BCyADIAFBAnQiAWogACABaigCAEGAgIAIazYCAAsLrSQBDH8CfyAEQQ9MBEAgASAEQQJ0aigCACACQQtsaiEKIAAoAgghByAAKAIEIQgDQCAKLQAAIQkCQCAHQQBOBEAgByECDAELIAAoAgwiDCAAKAIUSQRAIAwoAAAhAiAAIAxBA2o2AgwgACAAKAIAQRh0IAJBCHZBgP4DcSACQRh0IAJBgP4DcUEIdHJyQQh2cjYCACAHQRhqIQIMAQsgACgCECAMSwRAIAAgDEEBajYCDCAAIAdBCGoiAjYCCCAAIAwtAAAgACgCAEEIdHI2AgAMAQtBACECIAAoAhgNACAAQQE2AhggACAAKAIAQQh0NgIAIAdBCGohAgsgACACAn8gACgCACIGIAJ2IgsgCCAJbEEIdiIJSwRAIAAgCUF/cyACdCAGaiIGNgIAIAggCWsMAQsgCUEBagsiAmdBGHMiDGsiBzYCCCAAIAIgDHRBAWsiCDYCBCAGIQIgBCIMIAkgC08NAhoDQCAKLQABIQsCfwJ/IAdBAE4EQCAHIQQgAgwBCwJAIAAoAgwiCSAAKAIUSQRAIAkoAAAhBCAAIAlBA2o2AgwgACACQRh0IARBCHZBgP4DcSAEQRh0IARBgP4DcUEIdHJyQQh2ciIGNgIAIAdBGGohBAwBCyAAKAIQIAlLBEAgACAJQQFqNgIMIAAgB0EIaiIENgIIIAAgCS0AACACQQh0ciIGNgIADAELQQAhBCAGIAAoAhgNARogAEEBNgIYIAAgAkEIdCIGNgIAIAdBCGohBAsgBgsiAiAEdiINIAggC2xBCHYiCUsEQCAAIAlBf3MgBHQgAmoiBjYCACAIIAlrIQggBgwBCyAJQQFqIQggAgshAiAAIAQgCGdBGHMiBGsiBzYCCCAAIAggBHRBAWsiCDYCBCAMQQFqIQQgCSANTwRAQRAgBEEQRg0EGiABIARBAnRqKAIAIQogBCEMDAELCyABIARBAnRqKAIAIQ8gCi0AAiELAkAgB0EATg0AIAAoAgwiCSAAKAIUSQRAIAkoAAAhBiAAIAlBA2o2AgwgACACQRh0IAZBCHZBgP4DcSAGQRh0IAZBgP4DcUEIdHJyQQh2ciICNgIAIAdBGGohBwwBCyAAKAIQIAlLBEAgACAJQQFqNgIMIAAgB0EIaiIHNgIIIAAgCS0AACAGQQh0ciICNgIADAELIAAoAhgEQCAGIQJBACEHDAELIABBATYCGCAAIAZBCHQiAjYCACAHQQhqIQcLIAAgBwJ/IAIgB3YiCSAIIAtsQQh2IgZLBEAgACAGQX9zIAd0IAJqNgIAIAggBmsMAQsgBkEBagsiAmdBGHMiCGsiBzYCCCAAIAIgCHRBAWs2AgQCfyAGIAlPBEBBASEGIA9BC2oMAQsCf0EAIQIgACgCBCEIIAotAAMhCQJAIAAoAggiB0EATgRAIAchAgwBCyAAKAIMIgYgACgCFEkEQCAGKAAAIQIgACAGQQNqNgIMIAAgACgCAEEYdCACQQh2QYD+A3EgAkEYdCACQYD+A3FBCHRyckEIdnI2AgAgB0EYaiECDAELIAAoAhAgBksEQCAAIAZBAWo2AgwgACAHQQhqIgI2AgggACAGLQAAIAAoAgBBCHRyNgIADAELIAAoAhgNACAAQQE2AhggACAAKAIAQQh0NgIAIAdBCGohAgsgACACAn8gACgCACIHIAJ2IgsgCCAJbEEIdiIGSwRAIAAgBkF/cyACdCAHaiIHNgIAIAggBmsMAQsgBkEBagsiCGdBGHMiCWsiAjYCCCAAIAggCXRBAWsiCDYCBAJAAn8gBiALTwRAIAotAAQhCwJAIAJBAE4NACAAKAIMIgYgACgCFEkEQCAGKAAAIQkgACAGQQNqNgIMIAAgB0EYdCAJQQh2QYD+A3EgCUEYdCAJQYD+A3FBCHRyckEIdnIiBzYCACACQRhqIQIMAQsgACgCECAGSwRAIAAgBkEBajYCDCAAIAJBCGoiAjYCCCAAIAYtAAAgB0EIdHIiBzYCAAwBCyAAKAIYBEBBACECDAELIABBATYCGCAAIAdBCHQiBzYCACACQQhqIQILIAAgAgJ/IAggC2xBCHYiBiAHIAJ2TyIJRQRAIAAgBkF/cyACdCAHaiIHNgIAIAggBmsMAQsgBkEBagsiBmdBGHMiCGsiAjYCCCAAIAYgCHRBAWsiCDYCBEECIAkNARogCi0ABSEJAkAgAkEATg0AIAAoAgwiBiAAKAIUSQRAIAYoAAAhCiAAIAZBA2o2AgwgACAHQRh0IApBCHZBgP4DcSAKQRh0IApBgP4DcUEIdHJyQQh2ciIHNgIAIAJBGGohAgwBCyAAKAIQIAZLBEAgACAGQQFqNgIMIAAgAkEIaiICNgIIIAAgBi0AACAHQQh0ciIHNgIADAELIAAoAhgEQEEAIQIMAQsgAEEBNgIYIAAgB0EIdCIHNgIAIAJBCGohAgsgACACAn8gCCAJbEEIdiIGIAcgAnZJBEAgACAGQX9zIAJ0IAdqNgIAQQQhCSAIIAZrDAELQQMhCSAGQQFqCyIKZ0EYcyIHazYCCAwCCyAKLQAGIQsCQCACQQBODQAgACgCDCIGIAAoAhRJBEAgBigAACEJIAAgBkEDajYCDCAAIAdBGHQgCUEIdkGA/gNxIAlBGHQgCUGA/gNxQQh0cnJBCHZyIgc2AgAgAkEYaiECDAELIAAoAhAgBksEQCAAIAZBAWo2AgwgACACQQhqIgI2AgggACAGLQAAIAdBCHRyIgc2AgAMAQsgACgCGARAQQAhAgwBCyAAQQE2AhggACAHQQh0Igc2AgAgAkEIaiECCyAAIAICfyAHIAJ2IgkgCCALbEEIdiIGSwRAIAAgBkF/cyACdCAHaiIHNgIAIAggBmsMAQsgBkEBagsiCGdBGHMiC2siAjYCCCAAIAggC3RBAWsiCDYCBCAGIAlPBEAgCi0AByEJAkAgAkEATg0AIAAoAgwiBiAAKAIUSQRAIAYoAAAhCiAAIAZBA2o2AgwgACAHQRh0IApBCHZBgP4DcSAKQRh0IApBgP4DcUEIdHJyQQh2ciIHNgIAIAJBGGohAgwBCyAAKAIQIAZLBEAgACAGQQFqNgIMIAAgAkEIaiICNgIIIAAgBi0AACAHQQh0ciIHNgIADAELIAAoAhgEQEEAIQIMAQsgAEEBNgIYIAAgB0EIdCIHNgIAIAJBCGohAgsgACACAn8gByACdiILIAggCWxBCHYiBksEQCAAIAZBf3MgAnQgB2oiBzYCACAIIAZrDAELIAZBAWoLIgpnQRhzIghrIgI2AgggACAKIAh0QQFrIgo2AgQgBiALTwRAAkAgAkEATg0AIAAoAgwiBiAAKAIUSQRAIAYoAAAhCCAAIAZBA2o2AgwgACAHQRh0IAhBCHZBgP4DcSAIQRh0IAhBgP4DcUEIdHJyQQh2ciIHNgIAIAJBGGohAgwBCyAAKAIQIAZLBEAgACAGQQFqNgIMIAAgAkEIaiICNgIIIAAgBi0AACAHQQh0ciIHNgIADAELIAAoAhgEQEEAIQIMAQsgAEEBNgIYIAAgB0EIdCIHNgIAIAJBCGohAgsgACACAn8gCkGfAWxBCHYiBiAHIAJ2SQRAIAAgBkF/cyACdCAHajYCAEEGIQkgCiAGawwBC0EFIQkgBkEBagsiCmdBGHMiB2s2AggMAwsCQCACQQBODQAgACgCDCIGIAAoAhRJBEAgBigAACEIIAAgBkEDajYCDCAAIAdBGHQgCEEIdkGA/gNxIAhBGHQgCEGA/gNxQQh0cnJBCHZyIgc2AgAgAkEYaiECDAELIAAoAhAgBksEQCAAIAZBAWo2AgwgACACQQhqIgI2AgggACAGLQAAIAdBCHRyIgc2AgAMAQsgACgCGARAQQAhAgwBCyAAQQE2AhggACAHQQh0Igc2AgAgAkEIaiECCyAAIAICfyAKQaUBbEEIdiIGIAcgAnZJBEAgACAGQX9zIAJ0IAdqIgc2AgBBCSEIIAogBmsMAQtBByEIIAZBAWoLIgZnQRhzIgprIgI2AgggACAGIAp0QQFrIgk2AgQCQCACQQBODQAgACgCDCIGIAAoAhRJBEAgBigAACEKIAAgBkEDajYCDCAAIAdBGHQgCkEIdkGA/gNxIApBGHQgCkGA/gNxQQh0cnJBCHZyIgc2AgAgAkEYaiECDAELIAAoAhAgBksEQCAAIAZBAWo2AgwgACACQQhqIgI2AgggACAGLQAAIAdBCHRyIgc2AgAMAQsgACgCGARAQQAhAgwBCyAAQQE2AhggACAHQQh0Igc2AgAgAkEIaiECCyAAIAICfyAHIAJ2IgogCUGRAWxBCHYiBksEQCAAIAZBf3MgAnQgB2o2AgAgCSAGawwBCyAGQQFqCyICZ0EYcyIHazYCCCAAIAIgB3RBAWs2AgQgCCAGIApJagwDCyAKLQAIIQsCQCACQQBODQAgACgCDCIGIAAoAhRJBEAgBigAACEJIAAgBkEDajYCDCAAIAdBGHQgCUEIdkGA/gNxIAlBGHQgCUGA/gNxQQh0cnJBCHZyIgc2AgAgAkEYaiECDAELIAAoAhAgBksEQCAAIAZBAWo2AgwgACACQQhqIgI2AgggACAGLQAAIAdBCHRyIgc2AgAMAQsgACgCGARAQQAhAgwBCyAAQQE2AhggACAHQQh0Igc2AgAgAkEIaiECCyAAIAICfyAHIAJ2Ig0gCCALbEEIdiIJSwRAIAAgCUF/cyACdCAHaiIHNgIAQQohBiAIIAlrDAELQQkhBiAJQQFqCyIIZ0EYcyILayICNgIIIAAgCCALdEEBayIINgIEIAYgCmotAAAhCwJAIAJBAE4NACAAKAIMIgYgACgCFEkEQCAGKAAAIQogACAGQQNqNgIMIAAgB0EYdCAKQQh2QYD+A3EgCkEYdCAKQYD+A3FBCHRyckEIdnIiBzYCACACQRhqIQIMAQsgACgCECAGSwRAIAAgBkEBajYCDCAAIAJBCGoiAjYCCCAAIAYtAAAgB0EIdHIiBzYCAAwBCyAAKAIYBEBBACECDAELIABBATYCGCAAIAdBCHQiBzYCACACQQhqIQILIAAgAgJ/IAcgAnYiDiAIIAtsQQh2IgpLBEAgACAKQX9zIAJ0IAdqIgc2AgAgCCAKawwBCyAKQQFqCyICZ0EYcyIIayIGNgIIIAAgAiAIdEEBayIINgIEAkAgCSANSUEBdCAKIA5JciIOQQJ0QYAuaigCACIJLQAAIgJFBEBBACENDAELQQAhDSAHIQoDQCACQf8BcSEQAn8CfyAGQQBOBEAgBiECIAoMAQsCQCAAKAIMIgsgACgCFEkEQCALKAAAIQIgACALQQNqNgIMIAAgCkEYdCACQQh2QYD+A3EgAkEYdCACQYD+A3FBCHRyckEIdnIiBzYCACAGQRhqIQIMAQsgACgCECALSwRAIAAgC0EBajYCDCAAIAZBCGoiAjYCCCAAIAstAAAgCkEIdHIiBzYCAAwBC0EAIQIgByAAKAIYDQEaIABBATYCGCAAIApBCHQiBzYCACAGQQhqIQILIAcLIgYgAnYiESAIIBBsQQh2IgtLBEAgACALQX9zIAJ0IAZqIgc2AgAgCCALayEIIAcMAQsgC0EBaiEIIAYLIQogACACIAhnQRhzIgJrIgY2AgggACAIIAJ0QQFrIgg2AgQgDUEBdCALIBFJciENIAktAAEhAiAJQQFqIQkgAg0ACwsgDUEIIA50akEDagsMAQsgACAKIAd0QQFrNgIEIAkLIQYgACgCCCEHIA9BFmoLIQoCQCAHQQBOBEAgByECDAELIAAoAgwiCCAAKAIUSQRAIAgoAAAhAiAAIAhBA2o2AgwgACAAKAIAQRh0IAJBCHZBgP4DcSACQRh0IAJBgP4DcUEIdHJyQQh2cjYCACAHQRhqIQIMAQsgACgCECAISwRAIAAgCEEBajYCDCAAIAdBCGoiAjYCCCAAIAgtAAAgACgCAEEIdHI2AgAMAQtBACECIAAoAhgNACAAQQE2AhggACAAKAIAQQh0NgIAIAdBCGohAgsgACACQQFrIgc2AgggACAAKAIEIghBAXYiCyAAKAIAIg0gAnZrQR91IgkgCGpBAXIiCDYCBCAAIA0gCSALQQFqcSACdGs2AgAgBSAMQfAtai0AAEEBdGogAyAMQQBKQQJ0aigCACAGIAlzIAlrbDsBACAMQQ9IDQALC0EQCwuRBQEPfyABIAAoAmwiBWsiDEEASgRAIAAoAhAgACgCZCIJIAVsQQJ0aiEKA0BBECAMIAxBEE4bIgggBWohDSAAKAIIIgMoAgAiByAIbCEOIAUgB2whECADKAIoIgsoAogBIQ8gACgCFCEGAkAgACgCsAEiA0EASgRAIAAgA0EBayICQRRsakG0AWogBSANIAogBhAnIANBAUYNAQNAIAAgAkEBayIDQRRsakG0AWogBSANIAYgBhAnIAJBAUshBCADIQIgBA0ACwwBCyAGIApGDQAgBiAKIAggCWxBAnQQFBoLIA8gEGohAwJAIA5BAEwNAEEAIQlBACECIA5BBE8EQCAOQXxxIQ8DQCACIANqIAYgAkECdGooAgBBCHY6AAAgAyACQQFyIgRqIAYgBEECdGooAgBBCHY6AAAgAyACQQJyIgRqIAYgBEECdGooAgBBCHY6AAAgAyACQQNyIgRqIAYgBEECdGooAgBBCHY6AAAgAkEEaiICIA9HDQALCyAOQQNxIgRFDQADQCACIANqIAYgAkECdGooAgBBCHY6AAAgAkEBaiECIAlBAWoiCSAERw0ACwsgCygCDCIEBEAgCygCjAEhAiAIQQFxBH8gAiADIAMgByAEQQJ0QbDgAGooAgARAQAgBUEBaiEFIAMiAiAHagUgAwshBCAIQQFHBEADQCACIAQgBCAHIAsoAgxBAnRBsOAAaigCABEBACAEIAQgB2oiAiACIAcgCygCDEECdEGw4ABqKAIAEQEAIAIgB2ohBCACIQMgBUECaiIFIA1HDQALCyALIAM2AowBCyAKIAAoAmQiCSAIbEECdGohCiANIQUgDCAIayIMQQBKDQALCyAAIAE2AmwgACABNgJ0C+IBAQR/IAAEfyAALQAABUEACyEAAkAgA0EATA0AIANBA3EhBQJAIANBBEkEQEEAIQMMAQsgA0F8cSEHQQAhAwNAIAIgA2ogASADai0AACAAaiIAOgAAIAIgA0EBciIEaiABIARqLQAAIABqIgA6AAAgAiADQQJyIgRqIAEgBGotAAAgAGoiADoAACACIANBA3IiBGogASAEai0AACAAaiIAOgAAIANBBGoiAyAHRw0ACwsgBUUNAANAIAIgA2ogASADai0AACAAaiIAOgAAIANBAWohAyAGQQFqIgYgBUcNAAsLC88CAQR/AkAgAARAIANBAEwNASADQQFHBEAgA0EBcSEFIANBfnEhBwNAIAIgBGogASAEai0AACAAIARqLQAAajoAACACIARBAXIiA2ogASADai0AACAAIANqLQAAajoAACAEQQJqIgQgB0cNAAsgBUUNAgsgAiAEaiABIARqLQAAIAAgBGotAABqOgAADwsgA0EATA0AQQAhACADQQRPBEAgA0F8cSEHA0AgAiAEaiABIARqLQAAIAVqIgU6AAAgAiAEQQFyIgZqIAEgBmotAAAgBWoiBToAACACIARBAnIiBmogASAGai0AACAFaiIFOgAAIAIgBEEDciIGaiABIAZqLQAAIAVqIgU6AAAgBEEEaiIEIAdHDQALCyADQQNxIgNFDQADQCACIARqIAEgBGotAAAgBWoiBToAACAEQQFqIQQgAEEBaiIAIANHDQALCwusAgEEfwJAIABFBEAgA0EATA0BIANBBE8EQCADQXxxIQADQCACIARqIAEgBGotAAAgBWoiBToAACACIARBAXIiB2ogASAHai0AACAFaiIFOgAAIAIgBEECciIHaiABIAdqLQAAIAVqIgU6AAAgAiAEQQNyIgdqIAEgB2otAAAgBWoiBToAACAEQQRqIgQgAEcNAAsLIANBA3EiAEUNAQNAIAIgBGogASAEai0AACAFaiIFOgAAIARBAWohBCAGQQFqIgYgAEcNAAsMAQsgA0EATA0AIAAtAAAiBSEGA0AgAiAEaiABIARqLQAAQf8BIAVB/wFxIAZB/wFxayAAIARqLQAAIgZqIgVBACAFQQBKGyIFIAVB/wFOG2oiBToAACAEQQFqIgQgA0cNAAsLCxUAIAAoAigiACgCKBASIABBADYCKAuhBgETfwJAIAAoAiQiA0FAaygCACADKAI4Tg0AIAMoAhhBAEoNACACQQBMDQAgACgCACIIKAIAIgZBB2shESAIKAIQIAgoAhQgAWxqIgpBAEEDIAZBBEYgBkEJRnIiEhsiE2ohASADKAI0IglBfHEhFCAJQQNxIRAgCUEESSEVQQAhBgNAQYjhACEEAkACQCADKAIEDQBBjOEAIQQgAygCFA0AIAMoAjQgAygCCGxBAEwNASADKAJMIQVBACEEA0AgAygCRCAEaiAFIARBAnQiC2ooAgA6AAAgAygCTCIFIAtqQQA2AgAgBEEBaiIEIAMoAjQgAygCCGxIDQALDAELIAMgBCgCABEAAAsgAyADKAIYIAMoAhxqNgIYIAMgAygCRCADKAJIajYCRCADIAMoAkBBAWo2AkAgACgCJCEDIAZBAWohBiAJQQBMBH9BAAUgAygCRCEEQf8BIQVBACELQQAhAyAVRQRAA0AgASADQQJ0aiADIARqLQAAIgw6AAAgASADQQFyIg1BAnRqIAQgDWotAAAiDToAACABIANBAnIiDkECdGogBCAOai0AACIOOgAAIAEgA0EDciIPQQJ0aiAEIA9qLQAAIg86AAAgDyAOIA0gBSAMcXFxcSEFIANBBGoiAyAURw0ACwsgEARAA0AgASADQQJ0aiADIARqLQAAIgw6AAAgA0EBaiEDIAUgDHEhBSALQQFqIgsgEEcNAAsLIAAoAiQhAyAFQf8BRwsgB3IhByAIKAIUIQQCQCADQUBrKAIAIAMoAjhODQAgAygCGEEASg0AIAEgBGohASACIAZKDQELCyARQQNLDQAgB0UNACAJQQBMDQAgBiEAA0AgCiATaiEIIAogEmohAUEAIQMDQCAIIANBAnQiAmotAAAiBUH/AUcEQCABIAJqIgcgBUGBgQJsIgUgBy0AAGxBF3Y6AAAgASACQQFyaiIHIAUgBy0AAGxBF3Y6AAAgASACQQJyaiICIAUgAi0AAGxBF3Y6AAALIANBAWoiAyAJRw0ACyAEIApqIQogAEEBSiEBIABBAWshACABDQALCyAGC6gHAQx/AkAgACgCJCIDQUBrKAIAIAMoAjhODQAgAygCNCIIQQBMBEADQCADKAIYQQBKDQIgAiAGTA0CQYjhACEBAkACQCADKAIEDQBBjOEAIQEgAygCFA0AIAMoAjQgAygCCGxBAEwNASADKAJMIQdBACEBA0AgAygCRCABaiAHIAFBAnQiBGooAgA6AAAgAygCTCIHIARqQQA2AgAgAUEBaiIBIAMoAjQgAygCCGxIDQALDAELIAMgASgCABEAAAsgAyADKAIYIAMoAhxqNgIYIAMgAygCRCADKAJIajYCRCADIAMoAkBBAWo2AkAgBkEBaiEGIAAoAiQiA0FAaygCACADKAI4SA0ACwwBCyAAKAIAIgkoAgBBB2shDCAIQX5xIQ0gCEEBcSEOIAkoAhAgCSgCFCIFIAFsaiIKQQFqIQFBDyEHA0ACQCADKAIYQQBKDQAgAiAGTA0AQYjhACEFAkACQCADKAIEDQBBjOEAIQUgAygCFA0AIAMoAjQgAygCCGxBAEwNASADKAJMIQRBACEFA0AgAygCRCAFaiAEIAVBAnQiC2ooAgA6AAAgAygCTCIEIAtqQQA2AgAgBUEBaiIFIAMoAjQgAygCCGxIDQALDAELIAMgBSgCABEAAAsgAyADKAIYIAMoAhxqNgIYIAMgAygCRCADKAJIajYCRCADIAMoAkBBAWo2AkBBACEDAkAgCEEBRwRAA0AgASADQQF0aiIEIAAoAiQoAkQgA2otAABBBHYiBSAELQAAQfABcXI6AAAgASADQQFyIgRBAXRqIgsgACgCJCgCRCAEai0AAEEEdiIEIAstAABB8AFxcjoAACAFIAdxIARxIQcgA0ECaiIDIA1HDQALIA5FDQELIAEgA0EBdGoiBCAAKAIkKAJEIANqLQAAQQR2IgMgBC0AAEHwAXFyOgAAIAMgB3EhBwsgBkEBaiEGIAEgCSgCFCIFaiEBIAAoAiQiA0FAaygCACADKAI4SA0BCwsgDEEDSw0AIAdBD0YNACAGQQBMDQAgBiEEA0BBACEAA0AgCiAAQQF0aiIBQQFqIAEtAAEiAkEPcSIHQZEibCIDIAJB8AFxIAJBBHZybEEQdkHwAXEgB3I6AAAgASADIAEtAAAiAUHwAXEgAUEEdnJsQRB2QfABcSADIAFBD3EgAUEEdHJB/wFxbEEUdnI6AAAgAEEBaiIAIAhHDQALIAUgCmohCiAEQQFKIQAgBEEBayEEIAANAAsLIAYLdgEFfwJAIAAoAmhFDQAgAkEATA0AIAEoAhAgAmohBCABKAIkIQMDQCADIAAoAhAgACgCCCIFIAMoAjwiBmtqIAAoAmggACgCACIHIAYgBWtsaiAHEBsaIAIgASAEIAJrIAIgASgCNBEGAGsiAkEASg0ACwtBAAvoAQEHfyAEQQBKBEADQCACIAVqLQAAIQYgAyAFQQNsaiIHIAAgBWotAABBhZUBbEEIdiIKIAEgBWotAAAiC0GaggJsQQh2aiIIQZWKAWsiCUEGdkH/AUEAIAhBlYoBTxsgCUGAgAFJGzoAAiAHIAZBpcwBbEEIdiAKaiIIQZrvAGsiCUEGdkH/AUEAIAhBmu8ATxsgCUGAgAFJGzoAACAHIAogC0GTMmxBCHYgBkGI6ABsQQh2amsiBkGExABqIgdBBnZB/wFBACAGQfy7f04bIAdBgIABSRs6AAEgBUEBaiIFIARHDQALCwvoAQEHfyAEQQBKBEADQCABIAVqLQAAIQYgAyAFQQNsaiIHIAAgBWotAABBhZUBbEEIdiIKIAIgBWotAAAiC0GlzAFsQQh2aiIIQZrvAGsiCUEGdkH/AUEAIAhBmu8ATxsgCUGAgAFJGzoAAiAHIAZBmoICbEEIdiAKaiIIQZWKAWsiCUEGdkH/AUEAIAhBlYoBTxsgCUGAgAFJGzoAACAHIAogBkGTMmxBCHYgC0GI6ABsQQh2amsiBkGExABqIgdBBnZB/wFBACAGQfy7f04bIAdBgIABSRs6AAEgBUEBaiIFIARHDQALCwv0AQEGfyAEQQBKBEADQCADIAVBAXRqIgggACAFai0AAEGFlQFsQQh2IgcgAiAFai0AACIGQaXMAWxBCHZqIglBmu8AayIKQQZ2QfgBQQAgCUGa7wBPGyAKQYCAAUkbQfgBcSAHIAEgBWotAAAiCUGTMmxBCHYgBkGI6ABsQQh2amsiBkGExABqIgpBBnZB/wFBACAGQfy7f04bIApBgIABSRsiBkEFdnI6AAAgCCAGQQN0QeABcSAJQZqCAmxBCHYgB2oiB0GVigFrIghBCXZBH0EAIAdBlYoBTxsgCEGAgAFJG3I6AAEgBUEBaiIFIARHDQALCwv2AQEHfyAEQQBKBEADQCACIAVqLQAAIQcgASAFai0AACELIAAgBWotAAAhCCADIAVBAnRqIgZB/wE6AAAgBiAIQYWVAWxBCHYiCCALQZqCAmxBCHZqIglBlYoBayIKQQZ2Qf8BQQAgCUGVigFPGyAKQYCAAUkbOgADIAYgB0GlzAFsQQh2IAhqIglBmu8AayIKQQZ2Qf8BQQAgCUGa7wBPGyAKQYCAAUkbOgABIAYgCCALQZMybEEIdiAHQYjoAGxBCHZqayIGQYTEAGoiB0EGdkH/AUEAIAZB/Lt/ThsgB0GAgAFJGzoAAiAFQQFqIgUgBEcNAAsLC+oBAQd/IARBAEoEQANAIAIgBWotAAAhBiADIAVBAXRqIgggACAFai0AAEGFlQFsQQh2IgcgASAFai0AACIKQZqCAmxBCHZqIglBlYoBayILQQZ2QfABQQAgCUGVigFPGyALQYCAAUkbQQ9yOgABIAggBkGlzAFsQQh2IAdqIghBmu8AayIJQQZ2QfABQQAgCEGa7wBPGyAJQYCAAUkbQfABcSAHIApBkzJsQQh2IAZBiOgAbEEIdmprIgZBhMQAaiIHQQp2QQ9BACAGQfy7f04bIAdBgIABSRtyOgAAIAVBAWoiBSAERw0ACwsL9gEBB38gBEEASgRAA0AgAiAFai0AACEHIAEgBWotAAAhCyAAIAVqLQAAIQggAyAFQQJ0aiIGQf8BOgADIAYgCEGFlQFsQQh2IgggC0GaggJsQQh2aiIJQZWKAWsiCkEGdkH/AUEAIAlBlYoBTxsgCkGAgAFJGzoAAiAGIAdBpcwBbEEIdiAIaiIJQZrvAGsiCkEGdkH/AUEAIAlBmu8ATxsgCkGAgAFJGzoAACAGIAggC0GTMmxBCHYgB0GI6ABsQQh2amsiBkGExABqIgdBBnZB/wFBACAGQfy7f04bIAdBgIABSRs6AAEgBUEBaiIFIARHDQALCwv2AQEHfyAEQQBKBEADQCABIAVqLQAAIQcgAiAFai0AACELIAAgBWotAAAhCCADIAVBAnRqIgZB/wE6AAMgBiAIQYWVAWxBCHYiCCALQaXMAWxBCHZqIglBmu8AayIKQQZ2Qf8BQQAgCUGa7wBPGyAKQYCAAUkbOgACIAYgB0GaggJsQQh2IAhqIglBlYoBayIKQQZ2Qf8BQQAgCUGVigFPGyAKQYCAAUkbOgAAIAYgCCAHQZMybEEIdiALQYjoAGxBCHZqayIGQYTEAGoiB0EGdkH/AUEAIAZB/Lt/ThsgB0GAgAFJGzoAASAFQQFqIgUgBEcNAAsLC8EHAQ1/IAAoAhAiCkEATARAQQAPCyAKQQFqQQF1IQ0gASgCGCECA0AgAiAKIAdrIAAoAhQgACgCICICIAdsaiACEBshBCABKAIcIgMoAhggAygCICICakEBayACbSIGIA0gBWsiAiACIAZKGwRAIAMgAiAAKAIYIAAoAiQiAyAFbGogAxAbIQMgASgCICACIAAoAhwgACgCJCICIAVsaiACEBsaIAMgBWohBQsgBCAHaiEHQQAhBgJAIAEoAhgiAkFAaygCACACKAI4Tg0AIAEoAgAiCygCAEECdEHQ4QBqKAIAIQ4gCygCECALKAIUIAEoAhAgCWpsaiEMA0AgAigCGEEASg0BIAEoAhwiA0FAaygCACADKAI4Tg0BIAMoAhhBAEoNAUGI4QAhAwJAAkAgAigCBA0AQYzhACEDIAIoAhQNACACKAI0IAIoAghsQQBMDQEgAigCTCEEQQAhAwNAIAIoAkQgA2ogBCADQQJ0IghqKAIAOgAAIAIoAkwiBCAIakEANgIAIANBAWoiAyACKAI0IAIoAghsSA0ACwwBCyACIAMoAgARAAALIAIgAigCGCACKAIcajYCGCACIAIoAkQgAigCSGo2AkQgAiACKAJAQQFqNgJAIAEoAhwiAigCGEEATARAQYjhACEDAkACQCACKAIEDQBBjOEAIQMgAigCFA0AIAIoAjQgAigCCGxBAEwNASACKAJMIQRBACEDA0AgAigCRCADaiAEIANBAnQiCGooAgA6AAAgAigCTCIEIAhqQQA2AgAgA0EBaiIDIAIoAjQgAigCCGxIDQALDAELIAIgAygCABEAAAsgAiACKAIYIAIoAhxqNgIYIAIgAigCRCACKAJIajYCRCACIAIoAkBBAWo2AkALIAEoAiAiAigCGEEATARAQYjhACEDAkACQCACKAIEDQBBjOEAIQMgAigCFA0AIAIoAjQgAigCCGxBAEwNASACKAJMIQRBACEDA0AgAigCRCADaiAEIANBAnQiCGooAgA6AAAgAigCTCIEIAhqQQA2AgAgA0EBaiIDIAIoAjQgAigCCGxIDQALDAELIAIgAygCABEAAAsgAiACKAIYIAIoAhxqNgIYIAIgAigCRCACKAJIajYCRCACIAIoAkBBAWo2AkAgASgCICECCyABKAIYIgMoAkQgASgCHCgCRCACKAJEIAwgAygCNCAOEQIAIAZBAWohBiAMIAsoAhRqIQwgASgCGCICQUBrKAIAIAIoAjhIDQALCyAGIAlqIQkgByAKSA0ACyAJC+kCAQl/IAEoAgAiBCgCHCIGIAQoAiwiAyABKAIQIghsaiEFAkAgACgCaCIHBEAgACgCECICQQBMDQEgBCgCICEJIAEoAiQhAyAAKAIAIQYgBCgCECEKQQAhAANAIAcgAyACIAcgBhAbIgsgBmxqIQcgAxAkIABqIQAgAiALayICQQBKDQALIABBAEwNASAKIAggCWxqIAQoAiAgBSAEKAIsIAEoAiQoAjQgAEEBEDFBAA8LIAZFDQAgAkEATA0AIAAoAmAhASACQQhPBEAgAkF4cSEEQQAhAANAIAVB/wEgARAVIANqQf8BIAEQFSADakH/ASABEBUgA2pB/wEgARAVIANqQf8BIAEQFSADakH/ASABEBUgA2pB/wEgARAVIANqQf8BIAEQFSADaiEFIABBCGoiACAERw0ACwsgAkEHcSICRQ0AQQAhAANAIAVB/wEgARAVIANqIQUgAEEBaiIAIAJHDQALC0EAC7MCAQd/IAEoAhghBCAAKAIQIQMCQCABKAIAKAIAIgJBDE1BAEEBIAJ0QbogcRtFIAJBC2tBfElxDQAgACgCaCICRQ0AIAAoAhQgACgCICACIAAoAgAgACgCDCADQQAQMQsgA0EATARAQQAPCyADQQFqQQF1IQYgACgCICEFIAAoAhQhAgNAIAIgBCADIAIgBRAbIgcgBWxqIQIgBBAkIAhqIQggAyAHayIDQQBKDQALIAAoAhghAyABKAIcIQQgACgCJCEFIAYhAgNAIAQgAiADIAUQGyEHIAQQJBogAyAFIAdsaiEDIAIgB2siAkEASg0ACyAAKAIcIQMgASgCICEBIAAoAiQhAANAIAEgBiADIAAQGyECIAEQJBogAyAAIAJsaiEDIAYgAmsiBkEASg0ACyAIC8cBAQp/IAAoAggiA0EASgRAIAAoAjQgA2whCQNAIAQgCUgEQCAAKAJQIQtBACECQQAhBSAEIgchCANAIAAoAighCkEAIQYgACgCJCACaiICQQBKBEADQCAFIAEgCGotAAAiBmohBSADIAhqIQggAiAKayICQQBKDQALCyALIAdBAnRqIAIgBmwiBiAFIApsajYCACAANQIMQQAgBmutfkKAgICACHxCIIinIQUgAyAHaiIHIAlIDQALCyAEQQFqIgQgA0cNAAsLC98BAQp/IAAoAggiBUEASgRAIAAoAjQgBWwhCCAAKAJQIQkDQCAFIAZqIQIgACgCJCEDIAEgBmotAAAiByEEIAAoAixBAk4EQCABIAJqLQAAIQQLIAkgBkECdGogAyAHbDYCACACIQogAiAISARAA0ACQCADIAAoAihrIgNBAE4EQCAAKAIkIQsMAQsgACgCJCILIANqIQMgBCEHIAEgBSAKaiIKai0AACEECyAJIAJBAnRqIAQgC2wgByAEayADbGo2AgAgAiAFaiICIAhIDQALCyAGQQFqIgYgBUcNAAsLC4QDAgZ/An4gACgCCCAAKAI0bCEDIAAoAlAhBSAAKAJEIQYCQCAAKAIYIgRFBEAgA0EATA0BIANBAUcEQCADQQFxIQQgA0F+cSEDA0AgASAGakF/IAA1AhAgBSABQQJ0ajUCAH5CgICAgAh8QiCIpyICIAJB/wFKGzoAACAGIAFBAXIiAmpBfyAANQIQIAUgAkECdGo1AgB+QoCAgIAIfEIgiKciAiACQf8BShs6AAAgAUECaiIBIANHDQALIARFDQILIAEgBmpBfyAANQIQIAUgAUECdGo1AgB+QoCAgIAIfEIgiKciACAAQf8BShs6AAAPC0EAIARrrUIghiAANAIggCEHIANBAEwNACAAKAJMIQQgB0L/////D4MhCEIAIAd9Qv////8PgyEHA0AgASAGakF/IAA1AhAgByAFIAFBAnQiAmo1AgB+IAggAiAEajUCAH58QoCAgIAIfEIgiH5CgICAgAh8QiCIpyICIAJB/wFKGzoAACABQQFqIgEgA0cNAAsLC44DAgh/AX4gACgCCCAAKAI0bCEDIAAoAkwhBSAAKAJEIQYCQCAAKAIYIAAoAhBsIgEEQCADQQBMDQEgACgCUCEHQQAgAWutIQlBACEBA0AgASAGakF/IAA1AhQgBSABQQJ0IgJqIgQoAgAgAiAHajUCACAJfkIgiKciAmutfkKAgICACHxCIIinIgggCEH/AUobOgAAIAQgAjYCACABQQFqIgEgA0cNAAsMAQsgA0EATA0AQQAhASADQQFHBEAgA0EBcSEHIANBfnEhAwNAIAEgBmpBfyAANQIUIAUgAUECdGoiAjUCAH5CgICAgAh8QiCIpyIEIARB/wFKGzoAACACQQA2AgAgBiABQQFyIgJqQX8gADUCFCAFIAJBAnRqIgI1AgB+QoCAgIAIfEIgiKciBCAEQf8BShs6AAAgAkEANgIAIAFBAmoiASADRw0ACyAHRQ0BCyABIAZqQX8gADUCFCAFIAFBAnRqIgA1AgB+QoCAgIAIfEIgiKciASABQf8BShs6AAAgAEEANgIACwuYBQESfwJAIAAoAmgiBEUNACABKAIAIg0oAgAiDkEERiAOQQlGciEPIAAoAhAhASAAKAIIIQUgACgCDCEJAkAgACgCOEUEQCAFIQMMAQsgBQR/IAVBAWshAyAEIAAoAgBrIQQgAQUgAUEBawshAiAAKAJUIgogASAFamoiASAAKAJYRwRAIAIhAQwBCyABIAMgCmprIQELIAAoAgAhEiANKAIQIA0oAhQiACADbGoiAkEAQQMgDxsiE2ohCAJAIAFBAEwNACAJQQBMDQAgCUF8cSEUIAlBA3EhEUH/ASEHIAlBBEkhCwNAQQAhBiALRQRAA0AgCCAGQQJ0aiAEIAZqLQAAIgw6AAAgCCAGQQFyIgNBAnRqIAMgBGotAAAiCjoAACAIIAZBAnIiA0ECdGogAyAEai0AACIFOgAAIAggBkEDciIDQQJ0aiADIARqLQAAIgM6AAAgAyAFIAogByAMcXFxcSEHIAZBBGoiBiAURw0ACwtBACEFIBEEQANAIAggBkECdGogBCAGai0AACIDOgAAIAZBAWohBiADIAdxIQcgBUEBaiIFIBFHDQALCyAAIAhqIQggBCASaiEEIBBBAWoiECABRw0ACyAHQf8BRyEHCyAHRQ0AIA5BC2tBfEkNACABQQBMDQAgCUEATA0AIA0oAhQhCgNAIAIgE2ohBSACIA9qIQtBACEAA0AgBSAAQQJ0IgxqLQAAIgRB/wFHBEAgCyAMaiIDIARBgYECbCIEIAMtAABsQRd2OgAAIAsgDEEBcmoiAyAEIAMtAABsQRd2OgAAIAsgDEECcmoiAyAEIAMtAABsQRd2OgAACyAAQQFqIgAgCUcNAAsgAiAKaiECIAFBAUohACABQQFrIQEgAA0ACwtBAAvZAgEFfyABKAIAIgYoAhwiByAGKAIsIgMgACgCCGxqIQUgACgCECEEIAAoAgwhAQJAIAAoAmgiAgRAIARBAEwNASAEQQFHBEAgBEEBcSEHIARBfnEhBEEAIQMDQCAFIAIgARAUIAYoAixqIAIgACgCAGoiAiABEBQgBigCLGohBSACIAAoAgBqIQIgA0ECaiIDIARHDQALIAdFDQILIAUgAiABEBQaQQAPCyAHRQ0AIARBAEwNACAEQQhPBEAgBEF4cSEAQQAhAgNAIAVB/wEgARAVIANqQf8BIAEQFSADakH/ASABEBUgA2pB/wEgARAVIANqQf8BIAEQFSADakH/ASABEBUgA2pB/wEgARAVIANqQf8BIAEQFSADaiEFIAJBCGoiAiAARw0ACwsgBEEHcSIARQ0AQQAhAgNAIAVB/wEgARAVIANqIQUgAkEBaiICIABHDQALC0EAC78EAQ1/AkAgACgCaCIFRQ0AIAAoAhAhAyAAKAIIIQYCQCAAKAI4RQRAIAYhBAwBCwJ/IAZFBEAgA0EBawwBCyAGQQFrIQQgBSAAKAIAayEFIAMLIQIgACgCVCIIIAMgBmpqIgMgACgCWEcEQCACIQMMAQsgAyAEIAhqayEDCyADQQBMDQAgACgCDCIGQQBMDQAgASgCACIIKAIAIQsgBkF+cSEMIAZBAXEhDSAIKAIQIAgoAhQgBGxqIglBAWohAUEPIQQDQEEAIQICQCAGQQFHBEADQCABIAJBAXRqIgcgAiAFai0AAEEEdiIOIActAABB8AFxcjoAACABIAJBAXIiB0EBdGoiDyAFIAdqLQAAQQR2IgcgDy0AAEHwAXFyOgAAIAQgDnEgB3EhBCACQQJqIgIgDEcNAAsgDUUNAQsgASACQQF0aiIHIAIgBWotAABBBHYiAiAHLQAAQfABcXI6AAAgAiAEcSEECyABIAgoAhQiB2ohASAFIAAoAgBqIQUgCkEBaiIKIANHDQALIARBD0YNACALQQtrQXxJDQADQEEAIQUDQCAJIAVBAXRqIgBBAWogAC0AASIBQQ9xIgRBkSJsIgIgAUHwAXEgAUEEdnJsQRB2QfABcSAEcjoAACAAIAIgAC0AACIAQfABcSAAQQR2cmxBEHZB8AFxIAIgAEEPcSAAQQR0ckH/AXFsQRR2cjoAACAFQQFqIgUgBkcNAAsgByAJaiEJIANBAUohACADQQFrIQMgAA0ACwtBAAuSBQEQfyAAKAIQIgVBAWpBAm0hCCAAKAIMIgxBAWpBAm0hBwJAIAVBAEwNACAAKAIIIgJBAXUhDyABKAIAIgooAighECAKKAIYIREgCigCJCEGIAooAhQhCyAAKAIgIQ0gCigCECAKKAIgIg4gAmxqIQIgACgCFCEBAkAgBUEDcSIDRQRAIAUhBAwBCyAFQXxxIQQDQCACIAEgDBAUIA5qIQIgASANaiEBIAlBAWoiCSADRw0ACwsgBUEETwRAA0AgAiABIAwQFCAOaiABIA1qIgEgDBAUIA5qIAEgDWoiASAMEBQgDmogASANaiIBIAwQFCAOaiECIAEgDWohASAEQQVrIQUgBEEEayEEIAVBfkkNAAsLIAYgD2wgC2ohBiAAKAIYIQEgCigCJCELIAAoAiQhAwJAIAhBA3EiBUUEQCAIIQIMAQsgCEF8cSECQQAhCQNAIAYgASAHEBQgC2ohBiABIANqIQEgCUEBaiIJIAVHDQALCyAIQQRPBEADQCAGIAEgBxAUIAtqIAEgA2oiASAHEBQgC2ogASADaiIBIAcQFCALaiABIANqIgEgBxAUIAtqIQYgASADaiEBIAJBBWshBCACQQRrIQIgBEF+SQ0ACwsgDyAQbCARaiEGIAAoAhwhASAKKAIoIQMgACgCJCEEAkAgBUUEQCAIIQIMAQsgCEF8cSECQQAhCQNAIAYgASAHEBQgA2ohBiABIARqIQEgCUEBaiIJIAVHDQALCyAIQQRJDQADQCAGIAEgBxAUIANqIAEgBGoiASAHEBQgA2ogASAEaiIBIAcQFCADaiABIARqIgEgBxAUIANqIQYgASAEaiEBIAJBBWshCCACQQRrIQIgCEF+SQ0ACwsgACgCEAuDAwEMfyAAKAIQIQIgACgCDCIIQQFqQQJtIQ0gASgCACIJKAIQIAkoAhQiCiAAKAIIIgNsaiEGIAkoAgBBAnRBkOEAaigCACELIAAoAhwhBCAAKAIYIQUgACgCFCEHAn8gA0UEQCAHQQAgBSAEIAUgBCAGQQAgCCALEQgAIAIMAQsgASgCBCAHIAEoAgggASgCDCAFIAQgBiAKayAGIAggCxEIACACQQFqCyEKIAIgA2ohDCACQQNOBEAgA0ECaiECA0AgByAAKAIgIgNBAXRqIgcgA2sgByAFIAQgBSAAKAIkIgNqIgUgAyAEaiIEIAYgCSgCFCIDQQF0aiIGIANrIAYgCCALEQgAIAJBAmoiAiAMSA0ACwsgByAAKAIgaiECIAAoAlggACgCVCAMakoEQCABKAIEIAIgCBAUGiABKAIIIAUgDRAUGiABKAIMIAQgDRAUGiAKQQFrDwsgDEEBcUUEQCACQQAgBSAEIAUgBCAGIAkoAhRqQQAgCCALEQgACyAKC+8BAQt/AkAgACgCECICQQBMDQAgASgCACIBKAIQIAEoAhQiCCAAKAIIbGohAyABKAIAQQJ0QZDiAGooAgAhBiAAKAIMIQcgACgCHCEBIAAoAhghBSAAKAIUIQQgAkEBRwRAIAAoAiQhCSAAKAIgIQogAkEBcSELIAJBfnEhDEEAIQIDQCAEIAUgASADIAcgBhECACAEIApqIgQgBSABIAMgCGoiAyAHIAYRAgAgBSAJaiEFIAEgCWohASADIAhqIQMgBCAKaiEEIAJBAmoiAiAMRw0ACyALRQ0BCyAEIAUgASADIAcgBhECAAsgACgCEAv8BAEGfyAEQX5xIgcEQCADIAdBA2xqIQcDQCACLQAAIQUgAyAALQAAQYWVAWxBCHYiBiABLQAAIgpBmoICbEEIdmoiCEGVigFrIglBBnZB/wFBACAIQZWKAU8bIAlBgIABSRs6AAIgAyAFQaXMAWxBCHYgBmoiCEGa7wBrIglBBnZB/wFBACAIQZrvAE8bIAlBgIABSRs6AAAgAyAGIApBkzJsQQh2IAVBiOgAbEEIdmprIgVBhMQAaiIGQQZ2Qf8BQQAgBUH8u39OGyAGQYCAAUkbOgABIAItAAAhBSADIAAtAAFBhZUBbEEIdiIGIAEtAAAiCkGaggJsQQh2aiIIQZWKAWsiCUEGdkH/AUEAIAhBlYoBTxsgCUGAgAFJGzoABSADIAVBpcwBbEEIdiAGaiIIQZrvAGsiCUEGdkH/AUEAIAhBmu8ATxsgCUGAgAFJGzoAAyADIAYgCkGTMmxBCHYgBUGI6ABsQQh2amsiBUGExABqIgZBBnZB/wFBACAFQfy7f04bIAZBgIABSRs6AAQgAkEBaiECIAFBAWohASAAQQJqIQAgA0EGaiIDIAdHDQALIAchAwsgBEEBcQRAIAItAAAhAiADIAAtAABBhZUBbEEIdiIAIAEtAAAiAUGaggJsQQh2aiIEQZWKAWsiB0EGdkH/AUEAIARBlYoBTxsgB0GAgAFJGzoAAiADIAJBpcwBbEEIdiAAaiIEQZrvAGsiB0EGdkH/AUEAIARBmu8ATxsgB0GAgAFJGzoAACADIAAgAUGTMmxBCHYgAkGI6ABsQQh2amsiAEGExABqIgFBBnZB/wFBACAAQfy7f04bIAFBgIABSRs6AAELC/wEAQZ/IARBfnEiBwRAIAMgB0EDbGohBwNAIAEtAAAhBSADIAAtAABBhZUBbEEIdiIGIAItAAAiCkGlzAFsQQh2aiIIQZrvAGsiCUEGdkH/AUEAIAhBmu8ATxsgCUGAgAFJGzoAAiADIAVBmoICbEEIdiAGaiIIQZWKAWsiCUEGdkH/AUEAIAhBlYoBTxsgCUGAgAFJGzoAACADIAYgBUGTMmxBCHYgCkGI6ABsQQh2amsiBUGExABqIgZBBnZB/wFBACAFQfy7f04bIAZBgIABSRs6AAEgAS0AACEFIAMgAC0AAUGFlQFsQQh2IgYgAi0AACIKQaXMAWxBCHZqIghBmu8AayIJQQZ2Qf8BQQAgCEGa7wBPGyAJQYCAAUkbOgAFIAMgBUGaggJsQQh2IAZqIghBlYoBayIJQQZ2Qf8BQQAgCEGVigFPGyAJQYCAAUkbOgADIAMgBiAFQZMybEEIdiAKQYjoAGxBCHZqayIFQYTEAGoiBkEGdkH/AUEAIAVB/Lt/ThsgBkGAgAFJGzoABCACQQFqIQIgAUEBaiEBIABBAmohACADQQZqIgMgB0cNAAsgByEDCyAEQQFxBEAgAS0AACEBIAMgAC0AAEGFlQFsQQh2IgAgAi0AACICQaXMAWxBCHZqIgRBmu8AayIHQQZ2Qf8BQQAgBEGa7wBPGyAHQYCAAUkbOgACIAMgAUGaggJsQQh2IABqIgRBlYoBayIHQQZ2Qf8BQQAgBEGVigFPGyAHQYCAAUkbOgAAIAMgACABQZMybEEIdiACQYjoAGxBCHZqayIAQYTEAGoiAUEGdkH/AUEAIABB/Lt/ThsgAUGAgAFJGzoAAQsLoAUBBX8gBEEBdEF8cSIJBEAgAyAJaiEJA0AgAyAALQAAQYWVAWxBCHYiBiACLQAAIgVBpcwBbEEIdmoiB0Ga7wBrIghBBnZB+AFBACAHQZrvAE8bIAhBgIABSRtB+AFxIAYgAS0AACIHQZMybEEIdiAFQYjoAGxBCHZqayIFQYTEAGoiCEEGdkH/AUEAIAVB/Lt/ThsgCEGAgAFJGyIFQQV2cjoAACADIAVBA3RB4AFxIAdBmoICbEEIdiAGaiIGQZWKAWsiBUEJdkEfQQAgBkGVigFPGyAFQYCAAUkbcjoAASADIAAtAAFBhZUBbEEIdiIGIAItAAAiBUGlzAFsQQh2aiIHQZrvAGsiCEEGdkH4AUEAIAdBmu8ATxsgCEGAgAFJG0H4AXEgBiABLQAAIgdBkzJsQQh2IAVBiOgAbEEIdmprIgVBhMQAaiIIQQZ2Qf8BQQAgBUH8u39OGyAIQYCAAUkbIgVBBXZyOgACIAMgBUEDdEHgAXEgB0GaggJsQQh2IAZqIgZBlYoBayIFQQl2QR9BACAGQZWKAU8bIAVBgIABSRtyOgADIAJBAWohAiABQQFqIQEgAEECaiEAIANBBGoiAyAJRw0ACyAJIQMLIARBAXEEQCADIAAtAABBhZUBbEEIdiIAIAItAAAiAkGlzAFsQQh2aiIEQZrvAGsiCUEGdkH4AUEAIARBmu8ATxsgCUGAgAFJG0H4AXEgACABLQAAIgFBkzJsQQh2IAJBiOgAbEEIdmprIgJBhMQAaiIEQQZ2Qf8BQQAgAkH8u39OGyAEQYCAAUkbIgJBBXZyOgAAIAMgAkEDdEHgAXEgAUGaggJsQQh2IABqIgBBlYoBayIBQQl2QR9BACAAQZWKAU8bIAFBgIABSRtyOgABCwumBQEGfyAEQQJ0QXhxIggEQCADIAhqIQgDQCACLQAAIQUgAS0AACEGIAAtAAAhByADQf8BOgADIAMgB0GFlQFsQQh2IgcgBkGaggJsQQh2aiIJQZWKAWsiCkEGdkH/AUEAIAlBlYoBTxsgCkGAgAFJGzoAAiADIAVBpcwBbEEIdiAHaiIJQZrvAGsiCkEGdkH/AUEAIAlBmu8ATxsgCkGAgAFJGzoAACADIAcgBkGTMmxBCHYgBUGI6ABsQQh2amsiBUGExABqIgZBBnZB/wFBACAFQfy7f04bIAZBgIABSRs6AAEgAi0AACEFIAEtAAAhBiAALQABIQcgA0H/AToAByADIAdBhZUBbEEIdiIHIAZBmoICbEEIdmoiCUGVigFrIgpBBnZB/wFBACAJQZWKAU8bIApBgIABSRs6AAYgAyAFQaXMAWxBCHYgB2oiCUGa7wBrIgpBBnZB/wFBACAJQZrvAE8bIApBgIABSRs6AAQgAyAHIAZBkzJsQQh2IAVBiOgAbEEIdmprIgVBhMQAaiIGQQZ2Qf8BQQAgBUH8u39OGyAGQYCAAUkbOgAFIAJBAWohAiABQQFqIQEgAEECaiEAIANBCGoiAyAIRw0ACyAIIQMLIARBAXEEQCACLQAAIQIgAS0AACEBIAAtAAAhACADQf8BOgADIAMgAEGFlQFsQQh2IgAgAUGaggJsQQh2aiIEQZWKAWsiCEEGdkH/AUEAIARBlYoBTxsgCEGAgAFJGzoAAiADIAJBpcwBbEEIdiAAaiIEQZrvAGsiCEEGdkH/AUEAIARBmu8ATxsgCEGAgAFJGzoAACADIAAgAUGTMmxBCHYgAkGI6ABsQQh2amsiAEGExABqIgFBBnZB/wFBACAAQfy7f04bIAFBgIABSRs6AAELC6YFAQZ/IARBAnRBeHEiCARAIAMgCGohCANAIAEtAAAhBSACLQAAIQYgAC0AACEHIANB/wE6AAMgAyAHQYWVAWxBCHYiByAGQaXMAWxBCHZqIglBmu8AayIKQQZ2Qf8BQQAgCUGa7wBPGyAKQYCAAUkbOgACIAMgBUGaggJsQQh2IAdqIglBlYoBayIKQQZ2Qf8BQQAgCUGVigFPGyAKQYCAAUkbOgAAIAMgByAFQZMybEEIdiAGQYjoAGxBCHZqayIFQYTEAGoiBkEGdkH/AUEAIAVB/Lt/ThsgBkGAgAFJGzoAASABLQAAIQUgAi0AACEGIAAtAAEhByADQf8BOgAHIAMgB0GFlQFsQQh2IgcgBkGlzAFsQQh2aiIJQZrvAGsiCkEGdkH/AUEAIAlBmu8ATxsgCkGAgAFJGzoABiADIAVBmoICbEEIdiAHaiIJQZWKAWsiCkEGdkH/AUEAIAlBlYoBTxsgCkGAgAFJGzoABCADIAcgBUGTMmxBCHYgBkGI6ABsQQh2amsiBUGExABqIgZBBnZB/wFBACAFQfy7f04bIAZBgIABSRs6AAUgAkEBaiECIAFBAWohASAAQQJqIQAgA0EIaiIDIAhHDQALIAghAwsgBEEBcQRAIAEtAAAhASACLQAAIQIgAC0AACEAIANB/wE6AAMgAyAAQYWVAWxBCHYiACACQaXMAWxBCHZqIgRBmu8AayIIQQZ2Qf8BQQAgBEGa7wBPGyAIQYCAAUkbOgACIAMgAUGaggJsQQh2IABqIgRBlYoBayIIQQZ2Qf8BQQAgBEGVigFPGyAIQYCAAUkbOgAAIAMgACABQZMybEEIdiACQYjoAGxBCHZqayIAQYTEAGoiAUEGdkH/AUEAIABB/Lt/ThsgAUGAgAFJGzoAAQsLpgUBBn8gBEECdEF4cSIIBEAgAyAIaiEIA0AgAi0AACEFIAEtAAAhBiAALQAAIQcgA0H/AToAACADIAdBhZUBbEEIdiIHIAZBmoICbEEIdmoiCUGVigFrIgpBBnZB/wFBACAJQZWKAU8bIApBgIABSRs6AAMgAyAFQaXMAWxBCHYgB2oiCUGa7wBrIgpBBnZB/wFBACAJQZrvAE8bIApBgIABSRs6AAEgAyAHIAZBkzJsQQh2IAVBiOgAbEEIdmprIgVBhMQAaiIGQQZ2Qf8BQQAgBUH8u39OGyAGQYCAAUkbOgACIAItAAAhBSABLQAAIQYgAC0AASEHIANB/wE6AAQgAyAHQYWVAWxBCHYiByAGQZqCAmxBCHZqIglBlYoBayIKQQZ2Qf8BQQAgCUGVigFPGyAKQYCAAUkbOgAHIAMgBUGlzAFsQQh2IAdqIglBmu8AayIKQQZ2Qf8BQQAgCUGa7wBPGyAKQYCAAUkbOgAFIAMgByAGQZMybEEIdiAFQYjoAGxBCHZqayIFQYTEAGoiBkEGdkH/AUEAIAVB/Lt/ThsgBkGAgAFJGzoABiACQQFqIQIgAUEBaiEBIABBAmohACADQQhqIgMgCEcNAAsgCCEDCyAEQQFxBEAgAi0AACECIAEtAAAhASAALQAAIQAgA0H/AToAACADIABBhZUBbEEIdiIAIAFBmoICbEEIdmoiBEGVigFrIghBBnZB/wFBACAEQZWKAU8bIAhBgIABSRs6AAMgAyACQaXMAWxBCHYgAGoiBEGa7wBrIghBBnZB/wFBACAEQZrvAE8bIAhBgIABSRs6AAEgAyAAIAFBkzJsQQh2IAJBiOgAbEEIdmprIgBBhMQAaiIBQQZ2Qf8BQQAgAEH8u39OGyABQYCAAUkbOgACCwuCBQEGfyAEQQF0QXxxIgkEQCADIAlqIQkDQCACLQAAIQUgAyAALQAAQYWVAWxBCHYiBiABLQAAIgpBmoICbEEIdmoiB0GVigFrIghBBnZB8AFBACAHQZWKAU8bIAhBgIABSRtBD3I6AAEgAyAFQaXMAWxBCHYgBmoiB0Ga7wBrIghBBnZB8AFBACAHQZrvAE8bIAhBgIABSRtB8AFxIAYgCkGTMmxBCHYgBUGI6ABsQQh2amsiBUGExABqIgZBCnZBD0EAIAVB/Lt/ThsgBkGAgAFJG3I6AAAgAi0AACEFIAMgAC0AAUGFlQFsQQh2IgYgAS0AACIKQZqCAmxBCHZqIgdBlYoBayIIQQZ2QfABQQAgB0GVigFPGyAIQYCAAUkbQQ9yOgADIAMgBUGlzAFsQQh2IAZqIgdBmu8AayIIQQZ2QfABQQAgB0Ga7wBPGyAIQYCAAUkbQfABcSAGIApBkzJsQQh2IAVBiOgAbEEIdmprIgVBhMQAaiIGQQp2QQ9BACAFQfy7f04bIAZBgIABSRtyOgACIAJBAWohAiABQQFqIQEgAEECaiEAIANBBGoiAyAJRw0ACyAJIQMLIARBAXEEQCACLQAAIQIgAyAALQAAQYWVAWxBCHYiACABLQAAIgFBmoICbEEIdmoiBEGVigFrIglBBnZB8AFBACAEQZWKAU8bIAlBgIABSRtBD3I6AAEgAyACQaXMAWxBCHYgAGoiA0Ga7wBrIgRBBnZB8AFBACADQZrvAE8bIARBgIABSRtB8AFxIAAgAUGTMmxBCHYgAkGI6ABsQQh2amsiAEGExABqIgFBCnZBD0EAIABB/Lt/ThsgAUGAgAFJG3I6AAALC9sOARJ/IAYgAC0AAEGFlQFsQQh2IgogBC0AACAFLQAAQRB0ciIMIAItAAAgAy0AAEEQdHIiCUEDbGpBgoAIaiILQRJ2Ig9BpcwBbEEIdmoiEUGa7wBrIg1BBnZB/wFBACARQZrvAE8bIA1BgIABSRs6AAAgBiALQQJ2Qf8BcSILQZqCAmxBCHYgCmoiEUGVigFrIg1BBnZB/wFBACARQZWKAU8bIA1BgIABSRs6AAIgBiAKIA9BiOgAbEEIdiALQZMybEEIdmprIgpBhMQAaiILQQZ2Qf8BQQAgCkH8u39OGyALQYCAAUkbOgABIAEEQCAHIAEtAABBhZUBbEEIdiIKIAkgDEEDbGpBgoAIaiILQRJ2Ig9BpcwBbEEIdmoiEUGa7wBrIg1BBnZB/wFBACARQZrvAE8bIA1BgIABSRs6AAAgByAKIAtBAnZB/wFxIgtBmoICbEEIdmoiEUGVigFrIg1BBnZB/wFBACARQZWKAU8bIA1BgIABSRs6AAIgByAKIAtBkzJsQQh2IA9BiOgAbEEIdmprIgpBhMQAaiILQQZ2Qf8BQQAgCkH8u39OGyALQYCAAUkbOgABCyAIQQFrIRECQCAIQQNIBEAgDCEKIAkhCwwBC0EBIBFBAXUiCiAKQQFMGyEaQQEhDwNAIAYgD0EBdCINQQFrIhJBA2wiFGoiDiAAIBJqLQAAQYWVAWxBCHYiECAEIA9qLQAAIAUgD2otAABBEHRyIgogAiAPai0AACADIA9qLQAAQRB0ciILIAxqIhggCWpqQYiAIGoiGSAYQQF0akEDdiIYIAlqIhVBEXYiFkGlzAFsQQh2aiITQZrvAGsiF0EGdkH/AUEAIBNBmu8ATxsgF0GAgAFJGzoAACAOIBVBAXZB/wFxIhVBmoICbEEIdiAQaiITQZWKAWsiF0EGdkH/AUEAIBNBlYoBTxsgF0GAgAFJGzoAAiAOIBAgFkGI6ABsQQh2IBVBkzJsQQh2amsiDkGExABqIhBBBnZB/wFBACAOQfy7f04bIBBBgIABSRs6AAEgBiAPQQZsIhVqIg4gACANai0AAEGFlQFsQQh2IhAgGSAJIApqQQF0akEDdiIZIAtqIglBAXZB/wFxIhZBmoICbEEIdmoiE0GVigFrIhdBBnZB/wFBACATQZWKAU8bIBdBgIABSRs6AAIgDiAQIAlBEXYiCUGI6ABsQQh2IBZBkzJsQQh2amsiFkGExABqIhNBBnZB/wFBACAWQfy7f04bIBNBgIABSRs6AAEgDiAJQaXMAWxBCHYgEGoiCUGa7wBrIg5BBnZB/wFBACAJQZrvAE8bIA5BgIABSRs6AAAgAQRAIAcgFGoiCSABIBJqLQAAQYWVAWxBCHYiEiAMIBlqIgxBEXYiDkGlzAFsQQh2aiIQQZrvAGsiFEEGdkH/AUEAIBBBmu8ATxsgFEGAgAFJGzoAACAJIBIgDEEBdkH/AXEiDEGaggJsQQh2aiIQQZWKAWsiFEEGdkH/AUEAIBBBlYoBTxsgFEGAgAFJGzoAAiAJIBIgDEGTMmxBCHYgDkGI6ABsQQh2amsiCUGExABqIgxBBnZB/wFBACAJQfy7f04bIAxBgIABSRs6AAEgByAVaiIJIAEgDWotAABBhZUBbEEIdiIMIAogGGoiDUEBdkH/AXEiEkGaggJsQQh2aiIOQZWKAWsiEEEGdkH/AUEAIA5BlYoBTxsgEEGAgAFJGzoAAiAJIAwgEkGTMmxBCHYgDUERdiINQYjoAGxBCHZqayISQYTEAGoiDkEGdkH/AUEAIBJB/Lt/ThsgDkGAgAFJGzoAASAJIAwgDUGlzAFsQQh2aiIJQZrvAGsiDEEGdkH/AUEAIAlBmu8ATxsgDEGAgAFJGzoAAAsgDyAaRyENIA9BAWohDyALIQkgCiEMIA0NAAsLAkAgCEEBcQ0AIAYgEUEDbCIDaiICIAAgEWotAABBhZUBbEEIdiIAIAogC0EDbGpBgoAIaiIEQRJ2IgVBpcwBbEEIdmoiBkGa7wBrIghBBnZB/wFBACAGQZrvAE8bIAhBgIABSRs6AAAgAiAAIARBAnZB/wFxIgRBmoICbEEIdmoiBkGVigFrIghBBnZB/wFBACAGQZWKAU8bIAhBgIABSRs6AAIgAiAAIARBkzJsQQh2IAVBiOgAbEEIdmprIgBBhMQAaiICQQZ2Qf8BQQAgAEH8u39OGyACQYCAAUkbOgABIAFFDQAgAyAHaiIAIAEgEWotAABBhZUBbEEIdiIBIAsgCkEDbGpBgoAIaiICQRJ2IgNBpcwBbEEIdmoiBEGa7wBrIgVBBnZB/wFBACAEQZrvAE8bIAVBgIABSRs6AAAgACABIAJBAnZB/wFxIgJBmoICbEEIdmoiBEGVigFrIgVBBnZB/wFBACAEQZWKAU8bIAVBgIABSRs6AAIgACABIAJBkzJsQQh2IANBiOgAbEEIdmprIgBBhMQAaiIBQQZ2Qf8BQQAgAEH8u39OGyABQYCAAUkbOgABCwvbDgESfyAGIAAtAABBhZUBbEEIdiIKIAQtAAAgBS0AAEEQdHIiDCACLQAAIAMtAABBEHRyIglBA2xqQYKACGoiC0ESdiIPQaXMAWxBCHZqIhFBmu8AayINQQZ2Qf8BQQAgEUGa7wBPGyANQYCAAUkbOgACIAYgC0ECdkH/AXEiC0GaggJsQQh2IApqIhFBlYoBayINQQZ2Qf8BQQAgEUGVigFPGyANQYCAAUkbOgAAIAYgCiAPQYjoAGxBCHYgC0GTMmxBCHZqayIKQYTEAGoiC0EGdkH/AUEAIApB/Lt/ThsgC0GAgAFJGzoAASABBEAgByABLQAAQYWVAWxBCHYiCiAJIAxBA2xqQYKACGoiC0ESdiIPQaXMAWxBCHZqIhFBmu8AayINQQZ2Qf8BQQAgEUGa7wBPGyANQYCAAUkbOgACIAcgCiALQQJ2Qf8BcSILQZqCAmxBCHZqIhFBlYoBayINQQZ2Qf8BQQAgEUGVigFPGyANQYCAAUkbOgAAIAcgCiALQZMybEEIdiAPQYjoAGxBCHZqayIKQYTEAGoiC0EGdkH/AUEAIApB/Lt/ThsgC0GAgAFJGzoAAQsgCEEBayERAkAgCEEDSARAIAwhCiAJIQsMAQtBASARQQF1IgogCkEBTBshGkEBIQ8DQCAGIA9BAXQiDUEBayISQQNsIhRqIg4gACASai0AAEGFlQFsQQh2IhAgBCAPai0AACAFIA9qLQAAQRB0ciIKIAIgD2otAAAgAyAPai0AAEEQdHIiCyAMaiIYIAlqakGIgCBqIhkgGEEBdGpBA3YiGCAJaiIVQRF2IhZBpcwBbEEIdmoiE0Ga7wBrIhdBBnZB/wFBACATQZrvAE8bIBdBgIABSRs6AAIgDiAVQQF2Qf8BcSIVQZqCAmxBCHYgEGoiE0GVigFrIhdBBnZB/wFBACATQZWKAU8bIBdBgIABSRs6AAAgDiAQIBZBiOgAbEEIdiAVQZMybEEIdmprIg5BhMQAaiIQQQZ2Qf8BQQAgDkH8u39OGyAQQYCAAUkbOgABIAYgD0EGbCIVaiIOIAAgDWotAABBhZUBbEEIdiIQIBkgCSAKakEBdGpBA3YiGSALaiIJQRF2IhZBpcwBbEEIdmoiE0Ga7wBrIhdBBnZB/wFBACATQZrvAE8bIBdBgIABSRs6AAIgDiAQIBZBiOgAbEEIdiAJQQF2Qf8BcSIJQZMybEEIdmprIhZBhMQAaiITQQZ2Qf8BQQAgFkH8u39OGyATQYCAAUkbOgABIA4gCUGaggJsQQh2IBBqIglBlYoBayIOQQZ2Qf8BQQAgCUGVigFPGyAOQYCAAUkbOgAAIAEEQCAHIBRqIgkgASASai0AAEGFlQFsQQh2IhIgDCAZaiIMQRF2Ig5BpcwBbEEIdmoiEEGa7wBrIhRBBnZB/wFBACAQQZrvAE8bIBRBgIABSRs6AAIgCSASIAxBAXZB/wFxIgxBmoICbEEIdmoiEEGVigFrIhRBBnZB/wFBACAQQZWKAU8bIBRBgIABSRs6AAAgCSASIAxBkzJsQQh2IA5BiOgAbEEIdmprIglBhMQAaiIMQQZ2Qf8BQQAgCUH8u39OGyAMQYCAAUkbOgABIAcgFWoiCSABIA1qLQAAQYWVAWxBCHYiDCAKIBhqIg1BEXYiEkGlzAFsQQh2aiIOQZrvAGsiEEEGdkH/AUEAIA5Bmu8ATxsgEEGAgAFJGzoAAiAJIAwgDUEBdkH/AXEiDUGTMmxBCHYgEkGI6ABsQQh2amsiEkGExABqIg5BBnZB/wFBACASQfy7f04bIA5BgIABSRs6AAEgCSAMIA1BmoICbEEIdmoiCUGVigFrIgxBBnZB/wFBACAJQZWKAU8bIAxBgIABSRs6AAALIA8gGkchDSAPQQFqIQ8gCyEJIAohDCANDQALCwJAIAhBAXENACAGIBFBA2wiA2oiAiAAIBFqLQAAQYWVAWxBCHYiACAKIAtBA2xqQYKACGoiBEESdiIFQaXMAWxBCHZqIgZBmu8AayIIQQZ2Qf8BQQAgBkGa7wBPGyAIQYCAAUkbOgACIAIgACAEQQJ2Qf8BcSIEQZqCAmxBCHZqIgZBlYoBayIIQQZ2Qf8BQQAgBkGVigFPGyAIQYCAAUkbOgAAIAIgACAEQZMybEEIdiAFQYjoAGxBCHZqayIAQYTEAGoiAkEGdkH/AUEAIABB/Lt/ThsgAkGAgAFJGzoAASABRQ0AIAMgB2oiACABIBFqLQAAQYWVAWxBCHYiASALIApBA2xqQYKACGoiAkESdiIDQaXMAWxBCHZqIgRBmu8AayIFQQZ2Qf8BQQAgBEGa7wBPGyAFQYCAAUkbOgACIAAgASACQQJ2Qf8BcSICQZqCAmxBCHZqIgRBlYoBayIFQQZ2Qf8BQQAgBEGVigFPGyAFQYCAAUkbOgAAIAAgASACQZMybEEIdiADQYjoAGxBCHZqayIAQYTEAGoiAUEGdkH/AUEAIABB/Lt/ThsgAUGAgAFJGzoAAQsLyw8BEn8gBiAALQAAQYWVAWxBCHYiCyAELQAAIAUtAABBEHRyIg0gAi0AACADLQAAQRB0ciIJQQNsakGCgAhqIgxBEnYiCkGI6ABsQQh2IAxBAnZB/wFxIgxBkzJsQQh2amsiEUGExABqIg9BBnZB/wFBACARQfy7f04bIA9BgIABSRsiEUEFdiAKQaXMAWxBCHYgC2oiCkGa7wBrIg9BBnZB+AFBACAKQZrvAE8bIA9BgIABSRtB+AFxcjoAACAGIBFBA3RB4AFxIAxBmoICbEEIdiALaiILQZWKAWsiDEEJdkEfQQAgC0GVigFPGyAMQYCAAUkbcjoAASABBEAgByABLQAAQYWVAWxBCHYiCyAJIA1BA2xqQYKACGoiDEESdiIKQaXMAWxBCHZqIhFBmu8AayIPQQZ2QfgBQQAgEUGa7wBPGyAPQYCAAUkbQfgBcSALIAxBAnZB/wFxIgxBkzJsQQh2IApBiOgAbEEIdmprIgpBhMQAaiIRQQZ2Qf8BQQAgCkH8u39OGyARQYCAAUkbIgpBBXZyOgAAIAcgCkEDdEHgAXEgCyAMQZqCAmxBCHZqIgtBlYoBayIMQQl2QR9BACALQZWKAU8bIAxBgIABSRtyOgABCyAIQQFrIRECQCAIQQNIBEAgDSELIAkhDAwBC0EBIBFBAXUiCyALQQFMGyEaQQEhCgNAIAYgCkEBdCIPQQFrIhBBAXQiEmoiFiAAIBBqLQAAQYWVAWxBCHYiDiAEIApqLQAAIAUgCmotAABBEHRyIgsgAiAKai0AACADIApqLQAAQRB0ciIMIA1qIhkgCWpqQYiAIGoiFyAZQQF0akEDdiIZIAlqIhhBEXYiE0GI6ABsQQh2IBhBAXZB/wFxIhhBkzJsQQh2amsiFEGExABqIhVBBnZB/wFBACAUQfy7f04bIBVBgIABSRsiFEEFdiATQaXMAWxBCHYgDmoiE0Ga7wBrIhVBBnZB+AFBACATQZrvAE8bIBVBgIABSRtB+AFxcjoAACAWIBRBA3RB4AFxIBhBmoICbEEIdiAOaiIOQZWKAWsiFkEJdkEfQQAgDkGVigFPGyAWQYCAAUkbcjoAASAGIApBAnQiFmoiGCAAIA9qLQAAQYWVAWxBCHYiDiAXIAkgC2pBAXRqQQN2IhcgDGoiCUERdiITQYjoAGxBCHYgCUEBdkH/AXEiCUGTMmxBCHZqayIUQYTEAGoiFUEGdkH/AUEAIBRB/Lt/ThsgFUGAgAFJGyIUQQV2IBNBpcwBbEEIdiAOaiITQZrvAGsiFUEGdkH4AUEAIBNBmu8ATxsgFUGAgAFJG0H4AXFyOgAAIBggFEEDdEHgAXEgCUGaggJsQQh2IA5qIglBlYoBayIOQQl2QR9BACAJQZWKAU8bIA5BgIABSRtyOgABIAEEQCAHIBJqIg4gASAQai0AAEGFlQFsQQh2IgkgDSAXaiINQRF2IhBBpcwBbEEIdmoiEkGa7wBrIhdBBnZB+AFBACASQZrvAE8bIBdBgIABSRtB+AFxIAkgDUEBdkH/AXEiDUGTMmxBCHYgEEGI6ABsQQh2amsiEEGExABqIhJBBnZB/wFBACAQQfy7f04bIBJBgIABSRsiEEEFdnI6AAAgDiAQQQN0QeABcSAJIA1BmoICbEEIdmoiCUGVigFrIg1BCXZBH0EAIAlBlYoBTxsgDUGAgAFJG3I6AAEgByAWaiINIAEgD2otAABBhZUBbEEIdiIJIAsgGWoiD0ERdiIQQaXMAWxBCHZqIg5Bmu8AayISQQZ2QfgBQQAgDkGa7wBPGyASQYCAAUkbQfgBcSAJIA9BAXZB/wFxIg9BkzJsQQh2IBBBiOgAbEEIdmprIhBBhMQAaiIOQQZ2Qf8BQQAgEEH8u39OGyAOQYCAAUkbIhBBBXZyOgAAIA0gEEEDdEHgAXEgCSAPQZqCAmxBCHZqIglBlYoBayINQQl2QR9BACAJQZWKAU8bIA1BgIABSRtyOgABCyAKIBpHIQ8gCkEBaiEKIAwhCSALIQ0gDw0ACwsCQCAIQQFxDQAgBiARQQF0IgJqIgMgACARai0AAEGFlQFsQQh2IgAgCyAMQQNsakGCgAhqIgRBEnYiBUGlzAFsQQh2aiIGQZrvAGsiCEEGdkH4AUEAIAZBmu8ATxsgCEGAgAFJG0H4AXEgACAEQQJ2Qf8BcSIEQZMybEEIdiAFQYjoAGxBCHZqayIFQYTEAGoiBkEGdkH/AUEAIAVB/Lt/ThsgBkGAgAFJGyIFQQV2cjoAACADIAVBA3RB4AFxIAAgBEGaggJsQQh2aiIAQZWKAWsiA0EJdkEfQQAgAEGVigFPGyADQYCAAUkbcjoAASABRQ0AIAIgB2oiAiABIBFqLQAAQYWVAWxBCHYiACAMIAtBA2xqQYKACGoiAUESdiIDQaXMAWxBCHZqIgRBmu8AayIFQQZ2QfgBQQAgBEGa7wBPGyAFQYCAAUkbQfgBcSAAIAFBAnZB/wFxIgFBkzJsQQh2IANBiOgAbEEIdmprIgNBhMQAaiIEQQZ2Qf8BQQAgA0H8u39OGyAEQYCAAUkbIgNBBXZyOgAAIAIgA0EDdEHgAXEgACABQZqCAmxBCHZqIgBBlYoBayIBQQl2QR9BACAAQZWKAU8bIAFBgIABSRtyOgABCwv7DwESfyAALQAAIQogAi0AACEMIAMtAAAhDiAELQAAIQ0gBS0AACEQIAZB/wE6AAAgBiAKQYWVAWxBCHYiCyANIBBBEHRyIg0gDCAOQRB0ciIKQQNsakGCgAhqIgxBAnZB/wFxIg5BmoICbEEIdmoiEEGVigFrIglBBnZB/wFBACAQQZWKAU8bIAlBgIABSRs6AAMgBiAMQRJ2Qf8BcSIMQaXMAWxBCHYgC2oiEEGa7wBrIglBBnZB/wFBACAQQZrvAE8bIAlBgIABSRs6AAEgBiALIAxBiOgAbEEIdiAOQZMybEEIdmprIgtBhMQAaiIMQQZ2Qf8BQQAgC0H8u39OGyAMQYCAAUkbOgACIAEEQCABLQAAIQsgB0H/AToAACAHIAtBhZUBbEEIdiILIAogDUEDbGpBgoAIaiIMQQJ2Qf8BcSIOQZqCAmxBCHZqIhBBlYoBayIJQQZ2Qf8BQQAgEEGVigFPGyAJQYCAAUkbOgADIAcgCyAMQRJ2Qf8BcSIMQaXMAWxBCHZqIhBBmu8AayIJQQZ2Qf8BQQAgEEGa7wBPGyAJQYCAAUkbOgABIAcgCyAOQZMybEEIdiAMQYjoAGxBCHZqayILQYTEAGoiDEEGdkH/AUEAIAtB/Lt/ThsgDEGAgAFJGzoAAgsgCEEBayEQAkAgCEEDSARAIA0hCyAKIQwMAQtBASAQQQF1IgsgC0EBTBshGUEBIQ4DQCAAIA5BAXQiFUEBayISai0AACELIAIgDmotAAAhDCADIA5qLQAAIRYgBCAOai0AACERIAUgDmotAAAhEyAGIBJBAnQiGmoiCUH/AToAACAJIAtBhZUBbEEIdiIPIBEgE0EQdHIiCyAMIBZBEHRyIgwgDWoiFiAKampBiIAgaiIRIBZBAXRqQQN2IhYgCmoiE0EBdkH/AXEiF0GaggJsQQh2aiIUQZWKAWsiGEEGdkH/AUEAIBRBlYoBTxsgGEGAgAFJGzoAAyAJIBNBEXZB/wFxIhNBpcwBbEEIdiAPaiIUQZrvAGsiGEEGdkH/AUEAIBRBmu8ATxsgGEGAgAFJGzoAASAJIA8gE0GI6ABsQQh2IBdBkzJsQQh2amsiCUGExABqIg9BBnZB/wFBACAJQfy7f04bIA9BgIABSRs6AAIgACAVai0AACEPIAYgDkEDdCITaiIJQf8BOgAAIAkgD0GFlQFsQQh2Ig8gESAKIAtqQQF0akEDdiIRIAxqIgpBAXZB/wFxIhdBmoICbEEIdmoiFEGVigFrIhhBBnZB/wFBACAUQZWKAU8bIBhBgIABSRs6AAMgCSAPIApBEXZB/wFxIgpBiOgAbEEIdiAXQZMybEEIdmprIhdBhMQAaiIUQQZ2Qf8BQQAgF0H8u39OGyAUQYCAAUkbOgACIAkgCkGlzAFsQQh2IA9qIgpBmu8AayIJQQZ2Qf8BQQAgCkGa7wBPGyAJQYCAAUkbOgABIAEEQCABIBJqLQAAIQkgByAaaiIKQf8BOgAAIAogCUGFlQFsQQh2IgkgDSARaiINQQF2Qf8BcSISQZqCAmxBCHZqIg9BlYoBayIRQQZ2Qf8BQQAgD0GVigFPGyARQYCAAUkbOgADIAogCSANQRF2Qf8BcSINQaXMAWxBCHZqIg9Bmu8AayIRQQZ2Qf8BQQAgD0Ga7wBPGyARQYCAAUkbOgABIAogCSASQZMybEEIdiANQYjoAGxBCHZqayIKQYTEAGoiDUEGdkH/AUEAIApB/Lt/ThsgDUGAgAFJGzoAAiABIBVqLQAAIQ0gByATaiIKQf8BOgAAIAogDUGFlQFsQQh2Ig0gCyAWaiIJQQF2Qf8BcSIVQZqCAmxBCHZqIhJBlYoBayIPQQZ2Qf8BQQAgEkGVigFPGyAPQYCAAUkbOgADIAogDSAVQZMybEEIdiAJQRF2Qf8BcSIJQYjoAGxBCHZqayIVQYTEAGoiEkEGdkH/AUEAIBVB/Lt/ThsgEkGAgAFJGzoAAiAKIA0gCUGlzAFsQQh2aiIKQZrvAGsiDUEGdkH/AUEAIApBmu8ATxsgDUGAgAFJGzoAAQsgDiAZRyEJIA5BAWohDiAMIQogCyENIAkNAAsLAkAgCEEBcQ0AIAAgEGotAAAhAiAGIBBBAnQiA2oiAEH/AToAACAAIAJBhZUBbEEIdiICIAsgDEEDbGpBgoAIaiIEQQJ2Qf8BcSIFQZqCAmxBCHZqIgZBlYoBayIIQQZ2Qf8BQQAgBkGVigFPGyAIQYCAAUkbOgADIAAgAiAEQRJ2Qf8BcSIEQaXMAWxBCHZqIgZBmu8AayIIQQZ2Qf8BQQAgBkGa7wBPGyAIQYCAAUkbOgABIAAgAiAFQZMybEEIdiAEQYjoAGxBCHZqayIAQYTEAGoiAkEGdkH/AUEAIABB/Lt/ThsgAkGAgAFJGzoAAiABRQ0AIAEgEGotAAAhASADIAdqIgBB/wE6AAAgACABQYWVAWxBCHYiASAMIAtBA2xqQYKACGoiAkECdkH/AXEiA0GaggJsQQh2aiIEQZWKAWsiBUEGdkH/AUEAIARBlYoBTxsgBUGAgAFJGzoAAyAAIAEgAkESdkH/AXEiAkGlzAFsQQh2aiIEQZrvAGsiBUEGdkH/AUEAIARBmu8ATxsgBUGAgAFJGzoAASAAIAEgA0GTMmxBCHYgAkGI6ABsQQh2amsiAEGExABqIgFBBnZB/wFBACAAQfy7f04bIAFBgIABSRs6AAILC+sOARJ/IAYgAC0AAEGFlQFsQQh2IgogBC0AACAFLQAAQRB0ciILIAItAAAgAy0AAEEQdHIiCUEDbGpBgoAIaiIMQQJ2Qf8BcSIPQZqCAmxBCHZqIhBBlYoBayIOQQZ2QfABQQAgEEGVigFPGyAOQYCAAUkbQQ9yOgABIAYgDEESdiIMQaXMAWxBCHYgCmoiEEGa7wBrIg5BBnZB8AFBACAQQZrvAE8bIA5BgIABSRtB8AFxIAogDEGI6ABsQQh2IA9BkzJsQQh2amsiCkGExABqIgxBCnZBD0EAIApB/Lt/ThsgDEGAgAFJG3I6AAAgAQRAIAcgAS0AAEGFlQFsQQh2IgogCSALQQNsakGCgAhqIgxBAnZB/wFxIg9BmoICbEEIdmoiEEGVigFrIg5BBnZB8AFBACAQQZWKAU8bIA5BgIABSRtBD3I6AAEgByAKIAxBEnYiDEGlzAFsQQh2aiIQQZrvAGsiDkEGdkHwAUEAIBBBmu8ATxsgDkGAgAFJG0HwAXEgCiAPQZMybEEIdiAMQYjoAGxBCHZqayIKQYTEAGoiDEEKdkEPQQAgCkH8u39OGyAMQYCAAUkbcjoAAAsgCEEBayEQAkAgCEEDSARAIAshCiAJIQwMAQtBASAQQQF1IgogCkEBTBshGkEBIQ8DQCAGIA9BAXQiDkEBayIVQQF0IhFqIhIgACAVai0AAEGFlQFsQQh2Ig0gBCAPai0AACAFIA9qLQAAQRB0ciIKIAIgD2otAAAgAyAPai0AAEEQdHIiDCALaiIXIAlqakGIgCBqIhYgF0EBdGpBA3YiFyAJaiITQQF2Qf8BcSIYQZqCAmxBCHZqIhRBlYoBayIZQQZ2QfABQQAgFEGVigFPGyAZQYCAAUkbQQ9yOgABIBIgE0ERdiISQaXMAWxBCHYgDWoiE0Ga7wBrIhRBBnZB8AFBACATQZrvAE8bIBRBgIABSRtB8AFxIA0gEkGI6ABsQQh2IBhBkzJsQQh2amsiDUGExABqIhJBCnZBD0EAIA1B/Lt/ThsgEkGAgAFJG3I6AAAgBiAPQQJ0IhJqIhMgACAOai0AAEGFlQFsQQh2Ig0gFiAJIApqQQF0akEDdiIWIAxqIglBAXZB/wFxIhhBmoICbEEIdmoiFEGVigFrIhlBBnZB8AFBACAUQZWKAU8bIBlBgIABSRtBD3I6AAEgEyAJQRF2IglBpcwBbEEIdiANaiITQZrvAGsiFEEGdkHwAUEAIBNBmu8ATxsgFEGAgAFJG0HwAXEgDSAJQYjoAGxBCHYgGEGTMmxBCHZqayIJQYTEAGoiDUEKdkEPQQAgCUH8u39OGyANQYCAAUkbcjoAACABBEAgByARaiINIAEgFWotAABBhZUBbEEIdiIJIAsgFmoiC0EBdkH/AXEiFUGaggJsQQh2aiIRQZWKAWsiFkEGdkHwAUEAIBFBlYoBTxsgFkGAgAFJG0EPcjoAASANIAkgC0ERdiILQaXMAWxBCHZqIg1Bmu8AayIRQQZ2QfABQQAgDUGa7wBPGyARQYCAAUkbQfABcSAJIBVBkzJsQQh2IAtBiOgAbEEIdmprIglBhMQAaiILQQp2QQ9BACAJQfy7f04bIAtBgIABSRtyOgAAIAcgEmoiCyABIA5qLQAAQYWVAWxBCHYiCSAKIBdqIg5BAXZB/wFxIhVBmoICbEEIdmoiDUGVigFrIhFBBnZB8AFBACANQZWKAU8bIBFBgIABSRtBD3I6AAEgCyAJIA5BEXYiC0GlzAFsQQh2aiIOQZrvAGsiDUEGdkHwAUEAIA5Bmu8ATxsgDUGAgAFJG0HwAXEgCSAVQZMybEEIdiALQYjoAGxBCHZqayIJQYTEAGoiC0EKdkEPQQAgCUH8u39OGyALQYCAAUkbcjoAAAsgDyAaRyEOIA9BAWohDyAMIQkgCiELIA4NAAsLAkAgCEEBcQ0AIAYgEEEBdCICaiIDIAAgEGotAABBhZUBbEEIdiIAIAogDEEDbGpBgoAIaiIEQQJ2Qf8BcSIFQZqCAmxBCHZqIgZBlYoBayIIQQZ2QfABQQAgBkGVigFPGyAIQYCAAUkbQQ9yOgABIAMgACAEQRJ2IgNBpcwBbEEIdmoiBEGa7wBrIgZBBnZB8AFBACAEQZrvAE8bIAZBgIABSRtB8AFxIAAgBUGTMmxBCHYgA0GI6ABsQQh2amsiAEGExABqIgNBCnZBD0EAIABB/Lt/ThsgA0GAgAFJG3I6AAAgAUUNACACIAdqIgIgASAQai0AAEGFlQFsQQh2IgAgDCAKQQNsakGCgAhqIgFBAnZB/wFxIgNBmoICbEEIdmoiBEGVigFrIgVBBnZB8AFBACAEQZWKAU8bIAVBgIABSRtBD3I6AAEgAiAAIAFBEnYiAUGlzAFsQQh2aiICQZrvAGsiBEEGdkHwAUEAIAJBmu8ATxsgBEGAgAFJG0HwAXEgACADQZMybEEIdiABQYjoAGxBCHZqayIAQYTEAGoiAUEKdkEPQQAgAEH8u39OGyABQYCAAUkbcjoAAAsL+w8BEn8gAC0AACEKIAItAAAhDCADLQAAIQ4gBC0AACENIAUtAAAhECAGQf8BOgADIAYgCkGFlQFsQQh2IgsgDSAQQRB0ciINIAwgDkEQdHIiCkEDbGpBgoAIaiIMQQJ2Qf8BcSIOQZqCAmxBCHZqIhBBlYoBayIJQQZ2Qf8BQQAgEEGVigFPGyAJQYCAAUkbOgACIAYgDEESdkH/AXEiDEGlzAFsQQh2IAtqIhBBmu8AayIJQQZ2Qf8BQQAgEEGa7wBPGyAJQYCAAUkbOgAAIAYgCyAMQYjoAGxBCHYgDkGTMmxBCHZqayILQYTEAGoiDEEGdkH/AUEAIAtB/Lt/ThsgDEGAgAFJGzoAASABBEAgAS0AACELIAdB/wE6AAMgByALQYWVAWxBCHYiCyAKIA1BA2xqQYKACGoiDEECdkH/AXEiDkGaggJsQQh2aiIQQZWKAWsiCUEGdkH/AUEAIBBBlYoBTxsgCUGAgAFJGzoAAiAHIAsgDEESdkH/AXEiDEGlzAFsQQh2aiIQQZrvAGsiCUEGdkH/AUEAIBBBmu8ATxsgCUGAgAFJGzoAACAHIAsgDkGTMmxBCHYgDEGI6ABsQQh2amsiC0GExABqIgxBBnZB/wFBACALQfy7f04bIAxBgIABSRs6AAELIAhBAWshEAJAIAhBA0gEQCANIQsgCiEMDAELQQEgEEEBdSILIAtBAUwbIRlBASEOA0AgACAOQQF0IhVBAWsiEmotAAAhCyACIA5qLQAAIQwgAyAOai0AACEWIAQgDmotAAAhESAFIA5qLQAAIRMgBiASQQJ0IhpqIglB/wE6AAMgCSALQYWVAWxBCHYiDyARIBNBEHRyIgsgDCAWQRB0ciIMIA1qIhYgCmpqQYiAIGoiESAWQQF0akEDdiIWIApqIhNBAXZB/wFxIhdBmoICbEEIdmoiFEGVigFrIhhBBnZB/wFBACAUQZWKAU8bIBhBgIABSRs6AAIgCSATQRF2Qf8BcSITQaXMAWxBCHYgD2oiFEGa7wBrIhhBBnZB/wFBACAUQZrvAE8bIBhBgIABSRs6AAAgCSAPIBNBiOgAbEEIdiAXQZMybEEIdmprIglBhMQAaiIPQQZ2Qf8BQQAgCUH8u39OGyAPQYCAAUkbOgABIAAgFWotAAAhDyAGIA5BA3QiE2oiCUH/AToAAyAJIA9BhZUBbEEIdiIPIBEgCiALakEBdGpBA3YiESAMaiIKQQF2Qf8BcSIXQZqCAmxBCHZqIhRBlYoBayIYQQZ2Qf8BQQAgFEGVigFPGyAYQYCAAUkbOgACIAkgDyAKQRF2Qf8BcSIKQYjoAGxBCHYgF0GTMmxBCHZqayIXQYTEAGoiFEEGdkH/AUEAIBdB/Lt/ThsgFEGAgAFJGzoAASAJIApBpcwBbEEIdiAPaiIKQZrvAGsiCUEGdkH/AUEAIApBmu8ATxsgCUGAgAFJGzoAACABBEAgASASai0AACEJIAcgGmoiCkH/AToAAyAKIAlBhZUBbEEIdiIJIA0gEWoiDUEBdkH/AXEiEkGaggJsQQh2aiIPQZWKAWsiEUEGdkH/AUEAIA9BlYoBTxsgEUGAgAFJGzoAAiAKIAkgDUERdkH/AXEiDUGlzAFsQQh2aiIPQZrvAGsiEUEGdkH/AUEAIA9Bmu8ATxsgEUGAgAFJGzoAACAKIAkgEkGTMmxBCHYgDUGI6ABsQQh2amsiCkGExABqIg1BBnZB/wFBACAKQfy7f04bIA1BgIABSRs6AAEgASAVai0AACENIAcgE2oiCkH/AToAAyAKIA1BhZUBbEEIdiINIAsgFmoiCUEBdkH/AXEiFUGaggJsQQh2aiISQZWKAWsiD0EGdkH/AUEAIBJBlYoBTxsgD0GAgAFJGzoAAiAKIA0gFUGTMmxBCHYgCUERdkH/AXEiCUGI6ABsQQh2amsiFUGExABqIhJBBnZB/wFBACAVQfy7f04bIBJBgIABSRs6AAEgCiANIAlBpcwBbEEIdmoiCkGa7wBrIg1BBnZB/wFBACAKQZrvAE8bIA1BgIABSRs6AAALIA4gGUchCSAOQQFqIQ4gDCEKIAshDSAJDQALCwJAIAhBAXENACAAIBBqLQAAIQIgBiAQQQJ0IgNqIgBB/wE6AAMgACACQYWVAWxBCHYiAiALIAxBA2xqQYKACGoiBEECdkH/AXEiBUGaggJsQQh2aiIGQZWKAWsiCEEGdkH/AUEAIAZBlYoBTxsgCEGAgAFJGzoAAiAAIAIgBEESdkH/AXEiBEGlzAFsQQh2aiIGQZrvAGsiCEEGdkH/AUEAIAZBmu8ATxsgCEGAgAFJGzoAACAAIAIgBUGTMmxBCHYgBEGI6ABsQQh2amsiAEGExABqIgJBBnZB/wFBACAAQfy7f04bIAJBgIABSRs6AAEgAUUNACABIBBqLQAAIQEgAyAHaiIAQf8BOgADIAAgAUGFlQFsQQh2IgEgDCALQQNsakGCgAhqIgJBAnZB/wFxIgNBmoICbEEIdmoiBEGVigFrIgVBBnZB/wFBACAEQZWKAU8bIAVBgIABSRs6AAIgACABIAJBEnZB/wFxIgJBpcwBbEEIdmoiBEGa7wBrIgVBBnZB/wFBACAEQZrvAE8bIAVBgIABSRs6AAAgACABIANBkzJsQQh2IAJBiOgAbEEIdmprIgBBhMQAaiIBQQZ2Qf8BQQAgAEH8u39OGyABQYCAAUkbOgABCwv7DwESfyAALQAAIQogAi0AACEMIAMtAAAhDiAELQAAIQ0gBS0AACEQIAZB/wE6AAMgBiAKQYWVAWxBCHYiCyANIBBBEHRyIg0gDCAOQRB0ciIKQQNsakGCgAhqIgxBEnZB/wFxIg5BpcwBbEEIdmoiEEGa7wBrIglBBnZB/wFBACAQQZrvAE8bIAlBgIABSRs6AAIgBiAMQQJ2Qf8BcSIMQZqCAmxBCHYgC2oiEEGVigFrIglBBnZB/wFBACAQQZWKAU8bIAlBgIABSRs6AAAgBiALIA5BiOgAbEEIdiAMQZMybEEIdmprIgtBhMQAaiIMQQZ2Qf8BQQAgC0H8u39OGyAMQYCAAUkbOgABIAEEQCABLQAAIQsgB0H/AToAAyAHIAtBhZUBbEEIdiILIAogDUEDbGpBgoAIaiIMQRJ2Qf8BcSIOQaXMAWxBCHZqIhBBmu8AayIJQQZ2Qf8BQQAgEEGa7wBPGyAJQYCAAUkbOgACIAcgCyAMQQJ2Qf8BcSIMQZqCAmxBCHZqIhBBlYoBayIJQQZ2Qf8BQQAgEEGVigFPGyAJQYCAAUkbOgAAIAcgCyAMQZMybEEIdiAOQYjoAGxBCHZqayILQYTEAGoiDEEGdkH/AUEAIAtB/Lt/ThsgDEGAgAFJGzoAAQsgCEEBayEQAkAgCEEDSARAIA0hCyAKIQwMAQtBASAQQQF1IgsgC0EBTBshGUEBIQ4DQCAAIA5BAXQiFUEBayISai0AACELIAIgDmotAAAhDCADIA5qLQAAIRYgBCAOai0AACERIAUgDmotAAAhEyAGIBJBAnQiGmoiCUH/AToAAyAJIAtBhZUBbEEIdiIPIBEgE0EQdHIiCyAMIBZBEHRyIgwgDWoiFiAKampBiIAgaiIRIBZBAXRqQQN2IhYgCmoiE0ERdkH/AXEiF0GlzAFsQQh2aiIUQZrvAGsiGEEGdkH/AUEAIBRBmu8ATxsgGEGAgAFJGzoAAiAJIBNBAXZB/wFxIhNBmoICbEEIdiAPaiIUQZWKAWsiGEEGdkH/AUEAIBRBlYoBTxsgGEGAgAFJGzoAACAJIA8gF0GI6ABsQQh2IBNBkzJsQQh2amsiCUGExABqIg9BBnZB/wFBACAJQfy7f04bIA9BgIABSRs6AAEgACAVai0AACEPIAYgDkEDdCITaiIJQf8BOgADIAkgD0GFlQFsQQh2Ig8gESAKIAtqQQF0akEDdiIRIAxqIgpBEXZB/wFxIhdBpcwBbEEIdmoiFEGa7wBrIhhBBnZB/wFBACAUQZrvAE8bIBhBgIABSRs6AAIgCSAPIBdBiOgAbEEIdiAKQQF2Qf8BcSIKQZMybEEIdmprIhdBhMQAaiIUQQZ2Qf8BQQAgF0H8u39OGyAUQYCAAUkbOgABIAkgCkGaggJsQQh2IA9qIgpBlYoBayIJQQZ2Qf8BQQAgCkGVigFPGyAJQYCAAUkbOgAAIAEEQCABIBJqLQAAIQkgByAaaiIKQf8BOgADIAogCUGFlQFsQQh2IgkgDSARaiINQRF2Qf8BcSISQaXMAWxBCHZqIg9Bmu8AayIRQQZ2Qf8BQQAgD0Ga7wBPGyARQYCAAUkbOgACIAogCSANQQF2Qf8BcSINQZqCAmxBCHZqIg9BlYoBayIRQQZ2Qf8BQQAgD0GVigFPGyARQYCAAUkbOgAAIAogCSANQZMybEEIdiASQYjoAGxBCHZqayIKQYTEAGoiDUEGdkH/AUEAIApB/Lt/ThsgDUGAgAFJGzoAASABIBVqLQAAIQ0gByATaiIKQf8BOgADIAogDUGFlQFsQQh2Ig0gCyAWaiIJQRF2Qf8BcSIVQaXMAWxBCHZqIhJBmu8AayIPQQZ2Qf8BQQAgEkGa7wBPGyAPQYCAAUkbOgACIAogDSAJQQF2Qf8BcSIJQZMybEEIdiAVQYjoAGxBCHZqayIVQYTEAGoiEkEGdkH/AUEAIBVB/Lt/ThsgEkGAgAFJGzoAASAKIA0gCUGaggJsQQh2aiIKQZWKAWsiDUEGdkH/AUEAIApBlYoBTxsgDUGAgAFJGzoAAAsgDiAZRyEJIA5BAWohDiAMIQogCyENIAkNAAsLAkAgCEEBcQ0AIAAgEGotAAAhAiAGIBBBAnQiA2oiAEH/AToAAyAAIAJBhZUBbEEIdiICIAsgDEEDbGpBgoAIaiIEQRJ2Qf8BcSIFQaXMAWxBCHZqIgZBmu8AayIIQQZ2Qf8BQQAgBkGa7wBPGyAIQYCAAUkbOgACIAAgAiAEQQJ2Qf8BcSIEQZqCAmxBCHZqIgZBlYoBayIIQQZ2Qf8BQQAgBkGVigFPGyAIQYCAAUkbOgAAIAAgAiAEQZMybEEIdiAFQYjoAGxBCHZqayIAQYTEAGoiAkEGdkH/AUEAIABB/Lt/ThsgAkGAgAFJGzoAASABRQ0AIAEgEGotAAAhASADIAdqIgBB/wE6AAMgACABQYWVAWxBCHYiASAMIAtBA2xqQYKACGoiAkESdkH/AXEiA0GlzAFsQQh2aiIEQZrvAGsiBUEGdkH/AUEAIARBmu8ATxsgBUGAgAFJGzoAAiAAIAEgAkECdkH/AXEiAkGaggJsQQh2aiIEQZWKAWsiBUEGdkH/AUEAIARBlYoBTxsgBUGAgAFJGzoAACAAIAEgAkGTMmxBCHYgA0GI6ABsQQh2amsiAEGExABqIgFBBnZB/wFBACAAQfy7f04bIAFBgIABSRs6AAELCwQAQQALqyACGH8BfgJ/AkAgACgCKCIHKAIAKAIAIgRBDEsNAEEBIAR0QbogcUUNACAHQgA3AiggB0IANwIwQQshASAHQShqDAELIAdCADcCKCAHQgA3AjBBDEELIARBC2tBfEkiCRshASAHQShqCyEDAkAgBygCFCAAIAEQMkUNAAJAIARBC2tBfEkgCXINAEGQ2wAoAgBBC0YNAEGw4QBBPTYCAEGs4QBBPjYCAEGc4QBBPTYCAEGU4QBBPjYCAEG44QBBPzYCAEG04QBBwAA2AgBBqOEAQcEANgIAQaThAEE/NgIAQaDhAEHAADYCAEGY4QBBwgA2AgBBkOEAQcMANgIAQZDbAEELNgIACwJAAkACQAJAAkACQAJAIAAoAlwEQCAHKAIAIgwoAgAiAkEBayEBIARBCk0EQCABQQxPDQRBACEJQZ0QIAF2QQFxRQ0EDAULIAFBDE8NAUEAIQRBnRAgAXZBAXFFDQEMAgsCQCAEQQpNBEBBlNsAKAIAQQtHBEBBuOIAQcQANgIAQbTiAEHFADYCAEGw4gBBxgA2AgBBrOIAQccANgIAQajiAEHIADYCAEGk4gBBxAA2AgBBoOIAQcUANgIAQZziAEHGADYCAEGY4gBByQA2AgBBlOIAQccANgIAQZDiAEHKADYCAEGU2wBBCzYCAAsgB0HLADYCLCAAKAI4RQ0BIAAoAgwiBUEBaiIBQX5xIAVqIgBBgYD8/wdPDQYgAyAAEBYiADYCACAARQRAQQAPCyAHQcwANgIsIAcgADYCBCAHIAAgBWoiADYCCCAHIAAgAUEBdWo2AgxBkNsAKAIAQQtGDQFBsOEAQT02AgBBrOEAQT42AgBBnOEAQT02AgBBlOEAQT42AgBBuOEAQT82AgBBtOEAQcAANgIAQajhAEHBADYCAEGk4QBBPzYCAEGg4QBBwAA2AgBBmOEAQcIANgIAQZDhAEHDADYCAEGQ2wBBCzYCAAwBCyAHQc0ANgIsC0EBIQUgCQ0HAkACQCAEQQVrDgYAAQEBAQABCyAHQc4ANgIwDAcLIAdBzwBB0AAgBEEKSyIAGzYCMCAADQcMBgsgAkELa0F8SSEECyAAKAJgIghBAWoiDkF+cSIVQQF0IhYgCEEBdCIQakECdEEAIAhBA3QiFCAEG2oiAUGbAkHvAiAEG2oiAkGBgPz/B08NAiAAKAIQIQ0gACgCDCEJIAAoAmQhCiADIAIQFiIGNgIAIAZFDQUgByABIAZqQR9qQWBxIgI2AhggByACQagBajYCICAHIAJB1ABqNgIcIAdBACACQfwBaiAEGzYCJCAMKAIQIQMgAiAMKAIgNgJIIAIgAzYCRCACQgA3AjwgAiAKNgI4IAIgCDYCNCACIA02AjAgAiAJNgIsIAIgCiANSiILNgIEIAIgCCAJSiIDNgIAIAIgCUEBayAIIAMbIgU2AiggAiAIQQFrIhcgCSADGyIBNgIkIAJBATYCCCADRQRAIAJCgICAgBAgBayAPgIMCyACIAogC2siAzYCICACIA0gC2siBTYCHAJAIAsEQCADIQUgASEDDAELIAJCgICAgBAgCq1CIIYgASAFbKyAIhkgGUKAgICAEFobPgIUCyACIAY2AkwgAiAFNgIYIAIgBiAIQQJ0ajYCUCACQoCAgIAQIAOsgD4CECAGQQAgFBAVIRhBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAwoAhQhAyAHKAIcIgYgDCgCJDYCSCAGIAM2AkQgBkIANwI8IAYgCkEBakEBdSIPNgI4IAYgDkEBdSILNgI0IAYgDUEBakEBdSISNgIwIAYgCUEBakEBdSIRNgIsIAYgDyASSiINNgIEIAYgCyARSiIONgIAIAYgEUEBayALIA4bIhM2AiggBiALQQFrIBEgDhsiATYCJCAGQQE2AgggDkUEQCAGQoCAgIAQIBOsgD4CDAsgBiAPIA1rIgU2AiAgBiASIA1rIgM2AhwgBSECIAEhCSANRQRAIAZCgICAgBAgD61CIIYgASADbKyAIhkgGUKAgICAEFobPgIUIAUhCSADIQILIAYgEEECdCAYaiIQNgJMIAYgAjYCGCAGIBAgC0ECdGo2AlAgBkKAgICAECAJrIA+AhAgEEEAIAtBA3QiEBAVIQZBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAwoAhghCSAHKAIgIgIgDCgCKDYCSCACIAk2AkQgAkIANwI8IAIgDzYCOCACIAs2AjQgAiASNgIwIAIgETYCLCACIA02AgQgAiAONgIAIAIgEzYCKCACIAE2AiQgAkEBNgIIIA5FBEAgAkKAgICAECATrIA+AgwLIBVBAnQgBmohCSACIAU2AiAgAiADNgIcAkAgDQRAIAUhAyABIQUMAQsgAkKAgICAECAPrUIghiABIANsrIAiGSAZQoCAgIAQWhs+AhQLIAIgCTYCTCACIAM2AhggAiAJIAtBAnRqNgJQIAJCgICAgBAgBayAPgIQIAlBACAQEBUaQYjbACgCAEELRwRAQYzhAEEbNgIAQYjhAEEcNgIAQYThAEEdNgIAQYDhAEEeNgIAQYjbAEELNgIACyAHQdEANgIsQQEhBSAEDQUgDCgCHCEBIAAoAgwhAyAAKAIQIQUgBygCJCIEIAwoAiw2AkggBCABNgJEIARCADcCPCAEIAo2AjggBCAINgI0IAQgBTYCMCAEIAM2AiwgBCAFIApIIgE2AgQgBCADIAhIIgI2AgAgBEEBNgIIIAQgA0EBayAIIAIbIgk2AiggBCAXIAMgAhsiADYCJCACRQRAIARCgICAgBAgCayAPgIMCyAWQQJ0IAZqIQIgBCAKIAFrIgM2AiAgBCAFIAFrIgU2AhwCQCABBEAgAyEFIAAhAwwBCyAEQoCAgIAQIAqtQiCGIAAgBWysgCIZIBlCgICAgBBaGz4CFAsgBCACNgJMIAQgBTYCGCAEIAIgCEECdGo2AlAgBEKAgICAECADrIA+AhAgAkEAIBQQFRpBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAdB0gA2AjAMBAsgAkELa0F8SSEJCyAAKAJgIgZBBmwiFSAGQQN0Ig8gCRsiBEECdCAGQQNsIhYgBkECdCIXIAkbaiIBQZsCQe8CIAkbaiICQYGA/P8HSQ0BCyADQQA2AgBBAA8LIAAoAhAhCyAAKAIMIQwgACgCZCEKIAMgAhAWIgI2AgAgAkUNASAHIAEgAmpBH2pBYHEiATYCGCAHIAFBqAFqNgIgIAcgAUHUAGo2AhwgB0EAIAFB/AFqIAkbNgIkIAFBADYCSCABIAIgBEECdGoiDjYCRCABQgA3AjwgASAKNgI4IAEgBjYCNCABIAs2AjAgASAMNgIsIAEgCiALSiIINgIEIAEgBiAMSiIDNgIAIAEgDEEBayAGIAMbIgU2AiggASAGQQFrIhQgDCADGyIENgIkIAFBATYCCCADRQRAIAFCgICAgBAgBayAPgIMCyABIAogCGsiBTYCICABIAsgCGsiAzYCHAJAIAgEQCAFIQMgBCEFDAELIAFCgICAgBAgCq1CIIYgAyAEbKyAIhkgGUKAgICAEFobPgIUCyABIAI2AkwgASADNgIYIAEgAiAGQQJ0ajYCUCABQoCAgIAQIAWsgD4CECACQQAgDxAVIRFBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAcoAhwiCEEANgJIIAggBiAOajYCRCAIQgA3AjwgCCAKNgI4IAggBjYCNCAIIAtBAWpBAXUiEjYCMCAIIAxBAWpBAXUiDTYCLCAIIAogEkoiDDYCBCAIIAYgDUoiCzYCACAIQQE2AgggCCANQQFrIAYgCxsiEzYCKCAIIBQgDSALGyIENgIkIAtFBEAgCEKAgICAECATrIA+AgwLIAggCiAMayIDNgIgIAggEiAMayIFNgIcIAMhASAEIQIgDEUEQCAIQoCAgIAQIAqtQiCGIAQgBWysgCIZIBlCgICAgBBaGz4CFCADIQIgBSEBCyAIIAZBAXQiGEECdCARaiIQNgJMIAggATYCGCAIIBAgBkECdGo2AlAgCEKAgICAECACrIA+AhAgEEEAIA8QFRpBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAcoAiAiAUEANgJIIAEgDiAYajYCRCABQgA3AjwgASAKNgI4IAEgBjYCNCABIBI2AjAgASANNgIsIAEgDDYCBCABIAs2AgAgASATNgIoIAEgBDYCJCABQQE2AgggC0UEQCABQoCAgIAQIBOsgD4CDAsgF0ECdCARaiECIAEgAzYCICABIAU2AhwCQCAMBEAgAyEFIAQhAwwBCyABQoCAgIAQIAqtQiCGIAQgBWysgCIZIBlCgICAgBBaGz4CFAsgASACNgJMIAEgBTYCGCABIAIgBkECdGo2AlAgAUKAgICAECADrIA+AhAgAkEAIA8QFRpBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAdB0wA2AixBjNsAKAIAQQtHBEBB3OEAQdQANgIAQdThAEHVADYCAEH44QBB1gA2AgBB9OEAQdcANgIAQfDhAEHUADYCAEHs4QBB1QA2AgBB6OEAQdgANgIAQeThAEHWADYCAEHg4QBB1wA2AgBB2OEAQdkANgIAQdDhAEHaADYCAEGM2wBBCzYCAAtBASEFIAkNASAAKAIMIQUgACgCECEBIAcoAiQiA0EANgJIIAMgDiAWajYCRCADQgA3AjwgAyAKNgI4IAMgBjYCNCADIAE2AjAgAyAFNgIsIANBATYCCCADIAEgCkgiAjYCBCADIAUgBkgiBDYCACADIAVBAWsgBiAEGyIJNgIoIAMgFCAFIAQbIgA2AiQgBEUEQCADQoCAgIAQIAmsgD4CDAsgFUECdCARaiEFIAMgCiACayIENgIgIAMgASACayIJNgIcAkAgAgRAIAQhCSAAIQQMAQsgA0KAgICAECAKrUIghiAAIAlsrIAiGSAZQoCAgIAQWhs+AhQLIAMgBTYCTCADIAk2AhggAyAFIAZBAnRqNgJQIANCgICAgBAgBKyAPgIQIAVBACAPEBUaQYjbACgCAEELRwRAQYzhAEEbNgIAQYjhAEEcNgIAQYThAEEdNgIAQYDhAEEeNgIAQYjbAEELNgIACyAHQdsANgIwIAdB3ABB3ABB3QAgBygCACgCACIAQQpGGyAAQQVGGzYCNAtBASEFQfjaACgCAEELRg0AQfjaAEELNgIACyAFC1cBA38CQCAAKAIMQQBMDQAgACgCEEEATA0AIAAgACgCKCIBIAEoAiwRBQAhAiABKAIwIgMEQCAAIAEgAiADEQYAGgsgASABKAIQIAJqNgIQQQEhAQsgAQsLAEGU3wAoAgAQAwsLAEGQ3wAoAgAQAwsHACAAKAIECwUAQbYJCxYAIABFBEBBAA8LIABBtNYAEDpBAEcLGgAgACABKAIIIAUQGQRAIAEgAiADIAQQOQsLpwEAIAAgASgCCCAEEBkEQAJAIAEoAgQgAkcNACABKAIcQQFGDQAgASADNgIcCw8LAkAgACABKAIAIAQQGUUNAAJAIAIgASgCEEcEQCABKAIUIAJHDQELIANBAUcNASABQQE2AiAPCyABIAI2AhQgASADNgIgIAEgASgCKEEBajYCKAJAIAEoAiRBAUcNACABKAIYQQJHDQAgAUEBOgA2CyABQQQ2AiwLCxgAIAAgASgCCEEAEBkEQCABIAIgAxA3CwsxACAAIAEoAghBABAZBEAgASACIAMQNw8LIAAoAggiACABIAIgAyAAKAIAKAIcEQEAC4gCACAAIAEoAgggBBAZBEACQCABKAIEIAJHDQAgASgCHEEBRg0AIAEgAzYCHAsPCwJAIAAgASgCACAEEBkEQAJAIAIgASgCEEcEQCABKAIUIAJHDQELIANBAUcNAiABQQE2AiAPCyABIAM2AiACQCABKAIsQQRGDQAgAUEAOwE0IAAoAggiACABIAIgAkEBIAQgACgCACgCFBEMACABLQA1BEAgAUEDNgIsIAEtADRFDQEMAwsgAUEENgIsCyABIAI2AhQgASABKAIoQQFqNgIoIAEoAiRBAUcNASABKAIYQQJHDQEgAUEBOgA2DwsgACgCCCIAIAEgAiADIAQgACgCACgCGBECAAsLNwAgACABKAIIIAUQGQRAIAEgAiADIAQQOQ8LIAAoAggiACABIAIgAyAEIAUgACgCACgCFBEMAAudAQEBfyMAQUBqIgMkAAJ/QQEgACABQQAQGQ0AGkEAIAFFDQAaQQAgAUHU1QAQOiIBRQ0AGiADQQxqQQBBNBAVGiADQQE2AjggA0F/NgIUIAMgADYCECADIAE2AgggASADQQhqIAIoAgBBASABKAIAKAIcEQEAIAMoAiAiAEEBRgRAIAIgAygCGDYCAAsgAEEBRgshACADQUBrJAAgAAsKACAAIAFBABAZCzkAA0BB6OcAKAIAIgAEQEHo5wAgACgCCDYCACAAKAIEIAAoAgARAAAgABASDAELC0Hh5wBBADoAAAsGAEGAggQLJAEBf0HE4gAoAgAiAARAA0AgACgCABEKACAAKAIEIgANAAsLC4UBAQN/AkAgACgCBCICIgBBA3EEQANAIAAtAABFDQIgAEEBaiIAQQNxDQALCwNAIAAiAUEEaiEAIAEoAgAiA0F/cyADQYGChAhrcUGAgYKEeHFFDQALA0AgASIAQQFqIQEgAC0AAA0ACwsgACACa0EBaiIAEBYiAQR/IAEgAiAAEBQFQQALC9MBAQF+IAAgAC0A3wEgAEEZay0AACAALQC/ASAAQRprLQAAIAAtAJ8BIABBG2stAAAgAC0AfyAAQRxrLQAAIAAtAF8gAEEday0AACAALQA/IABBHmstAAAgAC0AHyAAQR9rLQAAIABBIGstAAAgAEEBay0AAGpqampqampqampqampqakEIakEEdq1C/wGDQoGChIiQoMCAAX4iATcA4AEgACABNwDAASAAIAE3AKABIAAgATcAgAEgACABNwBgIAAgATcAQCAAIAE3ACAgACABNwAAC9cIARJ/IABB78MAIABBIWstAABrIgIgAEEBay0AAGoiASAAQSBrIgstAAAiA2otAAA6AAAgACABIABBH2siDC0AACIEai0AADoAASAAIAEgAEEeayINLQAAIgVqLQAAOgACIAAgASAAQR1rIg4tAAAiBmotAAA6AAMgACABIABBHGsiDy0AACIHai0AADoABCAAIAEgAEEbayIQLQAAIghqLQAAOgAFIAAgASAAQRprIhEtAAAiCWotAAA6AAYgACABIABBGWsiEi0AACIKai0AADoAByAAIAogAiAALQAfaiIBai0AADoAJyAAIAEgCWotAAA6ACYgACABIAhqLQAAOgAlIAAgASAHai0AADoAJCAAIAEgBmotAAA6ACMgACABIAVqLQAAOgAiIAAgASAEai0AADoAISAAIAEgA2otAAA6ACAgACAKIAIgAC0AP2oiAWotAAA6AEcgACABIAlqLQAAOgBGIAAgASAIai0AADoARSAAIAEgB2otAAA6AEQgACABIAZqLQAAOgBDIAAgASAFai0AADoAQiAAIAEgBGotAAA6AEEgACABIANqLQAAOgBAIAAgAiAALQBfaiIBIAstAAAiA2otAAA6AGAgACABIAwtAAAiBGotAAA6AGEgACABIA0tAAAiBWotAAA6AGIgACABIA4tAAAiBmotAAA6AGMgACABIA8tAAAiB2otAAA6AGQgACABIBAtAAAiCGotAAA6AGUgACABIBEtAAAiCWotAAA6AGYgACABIBItAAAiCmotAAA6AGcgACAKIAIgAC0Af2oiAWotAAA6AIcBIAAgASAJai0AADoAhgEgACABIAhqLQAAOgCFASAAIAEgB2otAAA6AIQBIAAgASAGai0AADoAgwEgACABIAVqLQAAOgCCASAAIAEgBGotAAA6AIEBIAAgASADai0AADoAgAEgACAKIAIgAC0AnwFqIgFqLQAAOgCnASAAIAEgCWotAAA6AKYBIAAgASAIai0AADoApQEgACABIAdqLQAAOgCkASAAIAEgBmotAAA6AKMBIAAgASAFai0AADoAogEgACABIARqLQAAOgChASAAIAEgA2otAAA6AKABIAAgAiAALQC/AWoiASALLQAAIgtqLQAAOgDAASAAIAEgDC0AACIDai0AADoAwQEgACABIA0tAAAiDGotAAA6AMIBIAAgASAOLQAAIgRqLQAAOgDDASAAIAEgDy0AACINai0AADoAxAEgACABIBAtAAAiBWotAAA6AMUBIAAgASARLQAAIg5qLQAAOgDGASAAIAEgEi0AACIGai0AADoAxwEgACAGIAIgAC0A3wFqIgJqLQAAOgDnASAAIAIgDmotAAA6AOYBIAAgAiAFai0AADoA5QEgACACIA1qLQAAOgDkASAAIAIgBGotAAA6AOMBIAAgAiAMai0AADoA4gEgACACIANqLQAAOgDhASAAIAIgC2otAAA6AOABC0gBAX4gACAAQSBrKQAAIgE3AOABIAAgATcAwAEgACABNwCgASAAIAE3AIABIAAgATcAYCAAIAE3AEAgACABNwAgIAAgATcAAAu0AQAgACAAMQAfQoGChIiQoMCAAX43ACAgACAAMQA/QoGChIiQoMCAAX43AEAgACAAMQBfQoGChIiQoMCAAX43AGAgACAAMQB/QoGChIiQoMCAAX43AIABIAAgADEAnwFCgYKEiJCgwIABfjcAoAEgACAAMQC/AUKBgoSIkKDAgAF+NwDAASAAIAAxAN8BQoGChIiQoMCAAX43AOABIAAgAEEBazEAAEKBgoSIkKDAgAF+NwAAC4sBAQF+IAAgAC0A3wEgAC0AvwEgAC0AnwEgAC0AfyAALQBfIAAtAD8gAEEBay0AACAALQAfampqampqakEEakEDdq1C/wGDQoGChIiQoMCAAX4iATcA4AEgACABNwDAASAAIAE3AKABIAAgATcAgAEgACABNwBgIAAgATcAQCAAIAE3ACAgACABNwAAC50BAQF+IAAgAEEZay0AACAAQRprLQAAIABBG2stAAAgAEEcay0AACAAQR1rLQAAIABBHmstAAAgAEEgay0AACAAQR9rLQAAampqampqakEEakEDdq1C/wGDQoGChIiQoMCAAX4iATcA4AEgACABNwDAASAAIAE3AKABIAAgATcAgAEgACABNwBgIAAgATcAQCAAIAE3ACAgACABNwAACwcAIAARDwALhgEAIABCgIGChIiQoMCAfzcA4AEgAEKAgYKEiJCgwIB/NwDAASAAQoCBgoSIkKDAgH83AKABIABCgIGChIiQoMCAfzcAgAEgAEKAgYKEiJCgwIB/NwBgIABCgIGChIiQoMCAfzcAQCAAQoCBgoSIkKDAgH83ACAgAEKAgYKEiJCgwIB/NwAAC48EAQF+IAAgAEERay0AACAALQDfAyAAQRJrLQAAIAAtAL8DIABBE2stAAAgAC0AnwMgAEEUay0AACAALQD/AiAAQRVrLQAAIAAtAN8CIABBFmstAAAgAC0AvwIgAEEXay0AACAALQCfAiAAQRhrLQAAIAAtAP8BIABBGWstAAAgAC0A3wEgAEEaay0AACAALQC/ASAAQRtrLQAAIAAtAJ8BIABBHGstAAAgAC0AfyAAQR1rLQAAIAAtAF8gAEEeay0AACAALQA/IABBH2stAAAgAC0AHyAAQQFrLQAAIABBIGstAABqampqampqampqampqampqampqampqampqampqampqQRBqQQV2rUL/AYNCgYKEiJCgwIABfiIBNwAIIAAgATcAACAAIAE3ACAgACABNwAoIAAgATcAQCAAIAE3AEggACABNwBgIAAgATcAaCAAIAE3AIABIAAgATcAiAEgACABNwCgASAAIAE3AKgBIAAgATcAwAEgACABNwDIASAAIAE3AOgBIAAgATcA4AEgACABNwCIAiAAIAE3AIACIAAgATcAqAIgACABNwCgAiAAIAE3AMgCIAAgATcAwAIgACABNwDoAiAAIAE3AOACIAAgATcAiAMgACABNwCAAyAAIAE3AKgDIAAgATcAoAMgACABNwDIAyAAIAE3AMADIAAgATcA6AMgACABNwDgAwukAwETfyAAQRFrIQMgAEESayEEIABBE2shBSAAQRRrIQYgAEEVayEHIABBFmshCCAAQRdrIQkgAEEYayEKIABBGWshCyAAQRprIQwgAEEbayENIABBHGshDiAAQR1rIQ8gAEEeayEQIABBH2shESAAQSBrIRJB78MAIABBIWstAABrIRMDQCAAIBMgAEEBay0AAGoiASASLQAAai0AADoAACAAIAEgES0AAGotAAA6AAEgACABIBAtAABqLQAAOgACIAAgASAPLQAAai0AADoAAyAAIAEgDi0AAGotAAA6AAQgACABIA0tAABqLQAAOgAFIAAgASAMLQAAai0AADoABiAAIAEgCy0AAGotAAA6AAcgACABIAotAABqLQAAOgAIIAAgASAJLQAAai0AADoACSAAIAEgCC0AAGotAAA6AAogACABIActAABqLQAAOgALIAAgASAGLQAAai0AADoADCAAIAEgBS0AAGotAAA6AA0gACABIAQtAABqLQAAOgAOIAAgASADLQAAai0AADoADyAAQSBqIQAgAkEBaiICQRBHDQALC5cCAgJ+AX8gACAAQSBrIgMpAAAiATcAACAAIAE3ACAgACABNwBAIAAgATcAYCAAIAE3AIABIAAgATcAoAEgACABNwDAASAAIAE3AOABIAAgAykACCIBNwAIIAAgATcAKCAAIAE3AEggACABNwBoIAAgATcAiAEgACABNwCoASAAIAE3AMgBIAAgATcA6AEgACADKQAIIgE3AIgCIAAgAykAACICNwCAAiAAIAE3AKgCIAAgAjcAoAIgACABNwDIAiAAIAI3AMACIAAgATcA6AIgACACNwDgAiAAIAI3AIADIAAgATcAiAMgACABNwCoAyAAIAI3AKADIAAgAjcAwAMgACABNwDIAyAAIAE3AOgDIAAgAjcA4AMLigQBAX4gACAAMQAfQoGChIiQoMCAAX4iATcAICAAIAE3ACggACAAMQA/QoGChIiQoMCAAX4iATcAQCAAIAE3AEggACAAMQBfQoGChIiQoMCAAX4iATcAYCAAIAE3AGggACAAMQB/QoGChIiQoMCAAX4iATcAgAEgACABNwCIASAAIAAxAJ8BQoGChIiQoMCAAX4iATcAqAEgACABNwCgASAAIABBAWsxAABCgYKEiJCgwIABfiIBNwAAIAAgATcACCAAIAAxAL8BQoGChIiQoMCAAX4iATcAyAEgACABNwDAASAAIAAxAN8BQoGChIiQoMCAAX4iATcA6AEgACABNwDgASAAIAAxAP8BQoGChIiQoMCAAX4iATcAiAIgACABNwCAAiAAIAAxAJ8CQoGChIiQoMCAAX4iATcAqAIgACABNwCgAiAAIAAxAL8CQoGChIiQoMCAAX4iATcAyAIgACABNwDAAiAAIAAxAN8CQoGChIiQoMCAAX4iATcA6AIgACABNwDgAiAAIAAxAP8CQoGChIiQoMCAAX4iATcAiAMgACABNwCAAyAAIAAxAJ8DQoGChIiQoMCAAX4iATcAqAMgACABNwCgAyAAIAAxAL8DQoGChIiQoMCAAX4iATcAyAMgACABNwDAAyAAIAAxAN8DQoGChIiQoMCAAX4iATcA6AMgACABNwDgAwv/AgEBfiAAIAAtAN8DIAAtAL8DIAAtAJ8DIAAtAP8CIAAtAN8CIAAtAL8CIAAtAJ8CIAAtAP8BIAAtAN8BIAAtAL8BIAAtAJ8BIAAtAH8gAC0AXyAALQA/IABBAWstAAAgAC0AH2pqampqampqampqampqakEIakEEdq1C/wGDQoGChIiQoMCAAX4iATcAACAAIAE3AAggACABNwAoIAAgATcAICAAIAE3AEggACABNwBAIAAgATcAaCAAIAE3AGAgACABNwCIASAAIAE3AIABIAAgATcAqAEgACABNwCgASAAIAE3AMgBIAAgATcAwAEgACABNwDoASAAIAE3AOABIAAgATcAiAIgACABNwCAAiAAIAE3AKgCIAAgATcAoAIgACABNwDIAiAAIAE3AMACIAAgATcA6AIgACABNwDgAiAAIAE3AIgDIAAgATcAgAMgACABNwCoAyAAIAE3AKADIAAgATcAyAMgACABNwDAAyAAIAE3AOgDIAAgATcA4AMLoQMBAX4gACAAQRFrLQAAIABBEmstAAAgAEETay0AACAAQRRrLQAAIABBFWstAAAgAEEWay0AACAAQRdrLQAAIABBGGstAAAgAEEZay0AACAAQRprLQAAIABBG2stAAAgAEEcay0AACAAQR1rLQAAIABBHmstAAAgAEEgay0AACAAQR9rLQAAampqampqampqampqampqQQhqQQR2rUL/AYNCgYKEiJCgwIABfiIBNwAAIAAgATcACCAAIAE3ACggACABNwAgIAAgATcASCAAIAE3AEAgACABNwBoIAAgATcAYCAAIAE3AIgBIAAgATcAgAEgACABNwCoASAAIAE3AKABIAAgATcAyAEgACABNwDAASAAIAE3AOgBIAAgATcA4AEgACABNwCIAiAAIAE3AIACIAAgATcAqAIgACABNwCgAiAAIAE3AMgCIAAgATcAwAIgACABNwDoAiAAIAE3AOACIAAgATcAiAMgACABNwCAAyAAIAE3AKgDIAAgATcAoAMgACABNwDIAyAAIAE3AMADIAAgATcA6AMgACABNwDgAwuaBAAgAEKAgYKEiJCgwIB/NwAAIABCgIGChIiQoMCAfzcAICAAQoCBgoSIkKDAgH83AEAgAEKAgYKEiJCgwIB/NwBgIABCgIGChIiQoMCAfzcAgAEgAEKAgYKEiJCgwIB/NwCgASAAQoCBgoSIkKDAgH83AMABIABCgIGChIiQoMCAfzcA4AEgAEKAgYKEiJCgwIB/NwCAAiAAQoCBgoSIkKDAgH83AAggAEKAgYKEiJCgwIB/NwAoIABCgIGChIiQoMCAfzcASCAAQoCBgoSIkKDAgH83AGggAEKAgYKEiJCgwIB/NwCIASAAQoCBgoSIkKDAgH83AKgBIABCgIGChIiQoMCAfzcAyAEgAEKAgYKEiJCgwIB/NwDoASAAQoCBgoSIkKDAgH83AIgCIABCgIGChIiQoMCAfzcAqAIgAEKAgYKEiJCgwIB/NwCgAiAAQoCBgoSIkKDAgH83AMgCIABCgIGChIiQoMCAfzcAwAIgAEKAgYKEiJCgwIB/NwDoAiAAQoCBgoSIkKDAgH83AOACIABCgIGChIiQoMCAfzcAiAMgAEKAgYKEiJCgwIB/NwCAAyAAQoCBgoSIkKDAgH83AKgDIABCgIGChIiQoMCAfzcAoAMgAEKAgYKEiJCgwIB/NwDIAyAAQoCBgoSIkKDAgH83AMADIABCgIGChIiQoMCAfzcA6AMgAEKAgYKEiJCgwIB/NwDgAwuPAQEFfyAAIAAtAD8iAkECaiIDIAAtAF8iAWogAUEBdGpBAnZBgYKECGw2AGAgACABIAAtAB8iBEECaiIFIAJBAXRqakECdkGBgoQIbDYAQCAAIAMgAEEBay0AACIBaiAEQQF0akECdkGBgoQIbDYAICAAIAUgAEEhay0AAGogAUEBdGpBAnZBgYKECGw2AAALswIBCH8gACAAQSBrLQAAIgJBAWoiAyAAQSFrLQAAIgFqQQF2IgQ6AEEgACADIABBH2stAAAiBWpBAXYiBjoAQiAAIAQ6AAAgACAFIABBHmstAAAiA2pBAWpBAXYiBDoAQyAAIAY6AAEgACADIABBHWstAAAiBmpBAWpBAXY6AAMgACAEOgACIAAgAEEBay0AACIEQQJqIgcgAC0AP2ogAC0AHyIIQQF0akECdjoAYCAAIAIgByABQQF0ampBAnYiBzoAYSAAIAggAUECaiIBaiAEQQF0akECdjoAQCAAIAUgASACQQF0ampBAnYiAToAYiAAIAc6ACAgACADIAIgBUEBdGpqQQJqQQJ2IgI6AGMgACABOgAhIAAgBiAFIANBAXRqakECakECdjoAIyAAIAI6ACILm30CNH8DfiMAQcABayIMJAAgASgCACEEIAEoAgQhBiABLQALIQMgDEEMakEAQdAAEBUaIAxBADYClAEgDEIANwKMASAMQgA3AoQBIAxCADcCfCAMQgA3AnQgDEIANwJsIAxCADcCZCAMQQE2AgggDCAMQQhqNgJgAkACQCAEIAEgA8BBAEgiBBsiAUUNACAMQgA3A7gBIAxCADcDsAEgDEGoAWoiCEIANwMAIAxBoAFqIgpCADcDACAMQgA3A5gBIAEgBiADIAQbIgMgDEGYAWoiBCAEQQRyIAogDEGkAWogCEEAEDQNACAMIAwoApgBIio2AgwgDCAMKAKcASIrNgIQIAxB4ABqIQQjAEGwAWsiCSQAIAlBATYCCCAJIAM2AgQgCSABNgIAIAlBADYCkAEgCSABIANBAEEAQQAgCUGQAWpBACAJEDQ2AiQCQAJAIAkoAiQEQCAJKAIkQQdHDQIgCSgCkAENAQwCCyAJKAKQAUUNAQsgCUEENgIkCwJAIAkoAiQiAQ0AIAlBJGpBAEHsABAVGiAJQQg2AlggCUEJNgJUIAlBCjYCUCAJIAQ2AkwgCSAJKAIMIgEgCSgCAGoiBzYCZCAJIAkoAgQgAWsiBTYCYAJAAkACQAJAAkACQAJAAkACQAJAAkAgCSgCIEUEQEEBIQFBAUHIEhAeIgJFDQwgAkIANwJ8IAJBlgs2AgggAkIANwIAIAJBADYCuAIgAkIANwKEASACQgA3AowBQfTaACgCAEELRwRAQaTfAEEMNgIAQfTaAEELNgIACyACIAkoAhA2AqwSIAIgCSgCFDYCsBIgAiAJQSRqEC1FDQggCSgCJCAJKAIoIAwoAnQgDCgCYBA+IgENCiACQQA2ApQBAkAgDCgCdCIDRQ0AAkAgAygCLCIBQQBIDQBB/wEhByABQeQATQRAIAFB/wFsQf//A3FB5ABuIQcgAUH//wNxRQ0BCwJAIAIoAqAGIgFBDE4EQCACKAKkBiEFDAELIAIgByABQQAgAUEAShtBwC1qLQAAbEEDdiIFNgKkBgsCQCACKALABiIBQQxOBEAgAigCxAYhBAwBCyACIAcgAUEAIAFBAEobQcAtai0AAGxBA3YiBDYCxAYLIAQgBXIhBgJAIAIoAuAGIgFBDE4EQCACKALkBiEEDAELIAIgByABQQAgAUEAShtBwC1qLQAAbEEDdiIENgLkBgsgBCAGciEEAkAgAigCgAciAUEMTgRAIAIoAoQHIQcMAQsgAiAHIAFBACABQQBKG0HALWotAABsQQN2Igc2AoQHCyAEIAdyRQ0AIAJBqARqQeDMAEHcARAUGiACQYACNgKEBiACQR82AqQEIAJCATcCnAQLIAIgAygCNCIBNgLEEiACIAFB5ABMBH8gAUEATg0BQQAFQeQACzYCxBILIAIoAgRFBEAgAiAJQSRqEC1FDQkLAkAgCSgCVCIBRQ0AIAlBJGogAREEAA0AIAIoAgANCCACQeoKNgIIIAJCBjcCAAwICwJ/IAkoAmgEQEEAIQEgAkEANgKEEkEADAELQQIhCCACKAKEEiIDQcwtai0AACEBIANBAkYNAiADCyEIIAIgCSgCcCABayIDQQR1NgKoAiACIAkoAnggAWsiBEEEdTYCrAIgA0EASARAIAJBADYCqAILIARBAE4NBgwFC0EBIQFBAUGQAhAeIgJFDQsgAkECNgIEQYTbACgCAEELRwRAQfzgAEENNgIAQfjgAEENNgIAQfTgAEEONgIAQfDgAEEPNgIAQezgAEEQNgIAQejgAEERNgIAQeTgAEESNgIAQeDgAEETNgIAQdzgAEEUNgIAQdjgAEEVNgIAQdTgAEEWNgIAQdDgAEEXNgIAQczgAEEYNgIAQcjgAEEZNgIAQcTgAEEaNgIAQcDgAEENNgIAQYTbAEELNgIACyACQQA2AgAgAiAFNgIkIAJCADcCLCACQgA3AxggAiAJQSRqNgIIQQghAyACAn5CAEEIIAUgBUEITxsiAUUNABogBzEAACI3IAFBAUYNABogBzEAAUIIhiA3hCI3IAFBAkYNABogBzEAAkIQhiA3hCI3IAFBA0YNABogBzEAA0IYhiA3hCI3IAFBBEYNABogBzEABEIghiA3hCI3IAFBBUYNABogBzEABUIohiA3hCI3IAFBBkYNABogBzEABkIwhiA3hCI3IAFBB0YNABogBzEAB0I4hiA3hAsiNjcDGCACIAE2AiggAkEINgIsIAIgBzYCICA2ITcgBSIEQQlPBEAgAiA2QgiIIjc3AxggASAHajEAACE4IAJBADYCLCACIAFBAWoiBDYCKCACIDhCOIYgN4QiNzcDGEEAIQMLAkACQCA2Qv8Bg0IvUg0AIAIgA0EOaiIINgIsIAQgBSAEIAVLGyEBAkAgBCAFTwRAIDchNgwBCyACIDdCCIgiNjcDGCAEIAdqMQAAITggAiADQQZyIgg2AiwgAiAEQQFqIgY2AiggAiA4QjiGIDaEIjY3AxggBUEISwRAIAYhAQwBCyABIAZGDQAgAiA2QgiIIjY3AxggBiAHajEAACE4IAIgA0ECayIINgIsIAIgBEECaiIBNgIoIAIgOEI4hiA2hCI2NwMYCyACIAhBDmoiCzYCLCABIAUgASAFSxshCiA2IAhBP3GtiKdB//8AcSENAkACQCABIAVPDQAgAiA2QgiIIjY3AxggASAHajEAACE4IAIgCEEGaiILNgIsIAIgAUEBaiIGNgIoIAIgOEI4hiA2hCI2NwMYAkAgCEECSA0AIAYgCkYNASACIDZCCIgiNjcDGCAGIAdqMQAAITggAiAIQQJrIgs2AiwgAiABQQJqIgY2AiggAiA4QjiGIDaEIjY3AxggCEEKSA0AIAYgCkYNASACIDZCCIgiNjcDGCAGIAdqMQAAITggAiAIQQprIgs2AiwgAiABQQNqIgY2AiggAiA4QjiGIDaEIjY3AxggCEESSA0AIAYgCkYNASACIDZCCIgiNjcDGCAGIAdqMQAAITggAiAIQRFrIgQ2AiwgAiABQQRqIgo2AiggAiA4QjiGIDaEIjY3AxggDUEBaiEIDAILIAIgC0EBaiIENgIsIA1BAWohCCALQQdIBEAgBiEKDAILIAUgBk0EQCAGIAUgBSAGSRshCgwCCyACIDZCCIgiNjcDGCAGIAdqMQAAITggAiALQQdrIgQ2AiwgAiAGQQFqIgo2AiggAiA4QjiGIDaEIjY3AxgMAQsgAiALQQFqIgQ2AiwgDUEBaiEICyACIARBA2o2AiwgNiAEQT9xrYinQQdxIQ0CQCAEQQVIDQAgBSAKTQ0AIAIgNkIIiCI2NwMYIAcgCmoxAAAhOCACIARBBWs2AiwgAiAKQQFqIgY2AiggAiA4QjiGIDaEIjY3AxggBEENSA0AIAYgCiAFIAUgCkkbIgFGDQAgAiA2QgiIIjY3AxggBiAHajEAACE4IAIgBEENazYCLCACIApBAmoiBjYCKCACIDhCOIYgNoQiNjcDGCAEQRVIDQAgASAGRg0AIAIgNkIIiCI2NwMYIAYgB2oxAAAhOCACIARBFWs2AiwgAiAKQQNqIgY2AiggAiA4QjiGIDaEIjY3AxggBEEdSA0AIAEgBkYNACACIDZCCIgiNjcDGCAGIAdqMQAAITggAiAEQR1rNgIsIAIgCkEEaiIGNgIoIAIgOEI4hiA2hCI2NwMYIARBJUgNACABIAZGDQAgAiA2QgiIIjY3AxggBiAHajEAACE4IAIgBEElazYCLCACIApBBWo2AiggAiA4QjiGIDaENwMYCyANDQAMAQsgAkEDNgIADAMLIAJBAjYCBCAJIAg2AiggCSA3IAOtiKdB//8AcUEBaiIBNgIkIAEgCEEBIAJBABAjRQ0CIAkoAiQgCSgCKCAMKAJ0IAwoAmAQPiIBDQMgAigCCCIFKAIoIRECQCACKAIERQRAIAIoAmghBCACKAJkIQMgAigCECEHDAELIAIgESgCADYCDCARKAIUIAVBAxAyRQRAIAJBAjYCAAwECwJAAkACQCACKAJoIgSsIAIoAmQiA6x+IjYgBSgCACIBrEIEhiABQf//A3EiAa18fCI3UA0AIDdCgICAgPz///8/g1AgN0KBgP//AVRxDQAgAkEANgIQDAELIAIgN6dBAnQQFiIHNgIQIAcNAQsgAkEANgIUIAJBATYCAAwECyACIAcgNqdBAnRqIAFBAnRqNgIUAkACQCAFKAJcBEACQCAFKAJgIg2sIjdCBYYiNiA3QgKGfELUAHwiN0KAgPz/B1gEQCAFKAJkIRQgBSgCECEGIAUoAgwhASA3pxAWIggNAQsgAkEBNgIADAcLIAIgCDYCjAIgAiAINgKIAiAIQQA2AkggCEIANwI8IAggFDYCOCAIIA02AjQgCCAGNgIwIAggATYCLCAIIAYgFEgiCzYCBCAIIAEgDUgiCjYCACAIQQQ2AgggCCAIQdQAaiISIDanajYCRCAIIAFBAWsgDSAKGyIQNgIoIAggDUEBayABIAobIgE2AiQgCkUEQCAIQoCAgIAQIBCsgD4CDAsgCCAUIAtrIgo2AiAgCCAGIAtrIgY2AhwCQCALBEAgCiEGIAEhCgwBCyAIQoCAgIAQIBStQiCGIAEgBmysgCI3IDdCgICAgBBaGz4CFAsgCCASNgJMIAggBjYCGCAIIBIgDUEEdGo2AlAgCEKAgICAECAKrIA+AhAgEkEAIA1BBXQQFRpBiNsAKAIAQQtHBEBBjOEAQRs2AgBBiOEAQRw2AgBBhOEAQR02AgBBgOEAQR42AgBBiNsAQQs2AgALIAUoAlwNAQsgAigCDCILKAIAIghBC2tBfEkNAQtB+NoAKAIAQQtHBEBB+NoAQQs2AgALIAIoAgwiCygCACEICwJAIAhBC0kNAEGY2wAoAgBBC0cEQEGY2wBBCzYCAAsgCygCHEUNAEH42gAoAgBBC0YNAEH42gBBCzYCAAsCQCACKAI4RQ0AIAIoAnhBAEwNACACKAKIAQ0AQQEgAigChAEiAXQiBqxCgICAgPz///8/g1AgAUEdSXFFBEAgAkEANgKIAQwECyACIAZBBBAeIgY2AogBIAZFDQMgAiABNgKQASACQSAgAWs2AowBCyACQQA2AgQLIAIgByADIAQgBSgCWEEfECpFDQIgESACKAJ0NgIQQQAhAQwDCyACQQA2AqgCDAMLIAJBATYCAAsgAhAdIAIoAgAhAQsgAhAdDAYLIAJBADYCrAILIAIgAUEPaiIBIAkoAnxqQQR1IgM2ArQCIAIgASAJKAJ0akEEdSIBIAIoAqACIgogASAKSBs2ArACIAIoAqQCIgEgA0gEQCACIAE2ArQCC0EBIQsCQCAIQQBMDQAgAigCaCEBAkACQCACKAJERQRAQT8CfyABBEAgAiwAeCIDIAIoAnANARogAigCPCADagwBCyACKAI8CyIDIANBP04bIgNBAEoiBEUEQCACQQA6AIgSIAJBjBJqQQA6AAAgAkGKEmpBADoAAAwCC0ECIANBACAEGyIGQQ5LIAZBJ0sbIQQgBkEBdCEFIAIoAkAiB0EATARAIAJBixJqIAQ6AAAgAiADIAVqIgY6AIgSIAJBiRJqIAM6AAAgAkGNEmogAzoAACACQYoSakEAOgAAIAJBjxJqIAQ6AAAgAkGMEmogBjoAAAwCCyACQYsSaiAEOgAAIAJBihJqQQA6AAAgAkGPEmogBDoAACACQYkSakEBIAZBAkEBIAdBBEsbdiIDQQkgB2siBCADIARIGyIDIANBAUwbIgM6AAAgAkGNEmogAzoAACACIAMgBWoiAzoAiBIgAkGMEmogAzoAAAwBCyACKAJIIQYgAUUEQEE/IAIoAjwgBmoiAyADQT9OGyIGQQAgBkEASiIEGyEBAkAgBARAIAEhBCACKAJAIgVBAEoEQCABQQJBASAFQQRLG3YiBEEJIAVrIgUgBCAFSBshBAsgAkGLEmpBAiABQQ5LIAFBJ0sbOgAAIAJBiRJqQQEgBCAEQQFMGyIEOgAAIAIgBCABQQF0ajoAiBIMAQsgAkEAOgCIEgsgAkGKEmpBADoAAEE/IAIoAlggA2oiAyADQT9OGyIFQQAgBUEASiIDGyEEAkAgAwRAIAQhAyACKAJAIgdBAEoEQCAEQQJBASAHQQRLG3YiA0EJIAdrIgcgAyAHSBshAwsgAkGPEmpBAiAEQQ5LIARBJ0sbOgAAIAJBjRJqQQEgAyADQQFMGyIDOgAAIAIgAyAEQQF0ajoAjBIMAQsgAkEAOgCMEgsgAkGOEmpBAToAAAJAIAZBAEoEQCABIQMgAigCQCIHQQBKBEAgAUECQQEgB0EESxt2IgNBCSAHayIHIAMgB0gbIQMLIAJBkxJqQQIgAUEOSyABQSdLGzoAACACQZESakEBIAMgA0EBTBsiAzoAACACIAMgAUEBdGo6AJASDAELIAJBADoAkBILIAJBkhJqQQA6AAACQCAFQQBKBEAgBCEDIAIoAkAiB0EASgRAIARBAkEBIAdBBEsbdiIDQQkgB2siByADIAdIGyEDCyACQZcSakECIARBDksgBEEnSxs6AAAgAkGVEmpBASADIANBAUwbIgM6AAAgAiADIARBAXRqOgCUEgwBCyACQQA6AJQSCyACQZYSakEBOgAAAkAgBkEASgRAIAEhAyACKAJAIgdBAEoEQCABQQJBASAHQQRLG3YiA0EJIAdrIgcgAyAHSBshAwsgAkGbEmpBAiABQQ5LIAFBJ0sbOgAAIAJBmRJqQQEgAyADQQFMGyIDOgAAIAIgAyABQQF0ajoAmBIMAQsgAkEAOgCYEgsgAkGaEmpBADoAAAJAIAVBAEoEQCAEIQMgAigCQCIHQQBKBEAgBEECQQEgB0EESxt2IgNBCSAHayIHIAMgB0gbIQMLIAJBnxJqQQIgBEEOSyAEQSdLGzoAACACQZ0SakEBIAMgA0EBTBsiAzoAACACIAMgBEEBdGo6AJwSDAELIAJBADoAnBILIAJBnhJqQQE6AAACQCAGQQBKBEAgASEHIAIoAkAiA0EASgRAIAFBAkEBIANBBEsbdiIGQQkgA2siAyADIAZKGyEHCyACQaMSakECIAFBDksgAUEnSxs6AAAgAkGhEmpBASAHIAdBAUwbIgM6AAAgAiADIAFBAXRqOgCgEgwBCyACQQA6AKASCyACQaISakEAOgAAIAVBAEoEQCAEIQEgAigCQCIDQQBKBEAgBEECQQEgA0EESxt2IgFBCSADayIDIAEgA0gbIQELIAJBpxJqQQIgBEEOSyAEQSdLGzoAACACQaUSakEBIAEgAUEBTBsiAToAACACIAEgBEEBdGo6AKQSDAMLIAJBADoApBIMAgsgAigCWCERIAIoAnAhEkEAIQUDQCACIAVqLAB4IQMgAiAFQQN0aiIBQYgSaiEHAkBBPyASBH8gAwUgAigCPCADagsgBmoiDSANQT9OGyIDQQBKBEAgA0EAIANBAEobIgQhAyACKAJAIhRBAEoEQCAEQQJBASAUQQRLG3YiA0EJIBRrIhQgAyAUSBshAwsgAUGJEmpBASADIANBAUwbIgM6AAAgByADIARBAXRqOgAAIAFBixJqQQIgBEEOSyAEQSdLGzoAAAwBCyAHQQA6AAALIAFBihJqQQA6AAAgAUGMEmohBwJAQT8gDSARaiIDIANBP04bIgNBAEoEQCADQQAgA0EAShsiAyEEIAIoAkAiDUEASgRAIANBAkEBIA1BBEsbdiIEQQkgDWsiDSAEIA1IGyEECyABQY0SakEBIAQgBEEBTBsiBDoAACAHIAQgA0EBdGo6AAAgAUGPEmpBAiADQQ5LIANBJ0sbOgAADAELIAdBADoAAAsgAUGOEmpBAToAACAFQQFqIgVBBEcNAAsMAgsgAkGOEmpBAToAAAJAQT8CfyABBEAgAiwAeSIDIAIoAnANARogAigCPCADagwBCyACKAI8CyIDIANBP04bIgNBAEoEQEECIANBACADQQBKGyIGQQ5LIAZBJ0sbIQQgBkEBdCEFIAIoAkAiB0EATARAIAJBkxJqIAQ6AAAgAkGQEmogAyAFaiIGOgAAIAJBkRJqIAM6AAAgAkGVEmogAzoAACACQZISakEAOgAAIAJBlxJqIAQ6AAAgAkGUEmogBjoAAAwCCyACQZMSaiAEOgAAIAJBkhJqQQA6AAAgAkGXEmogBDoAACACQZESakEBIAZBAkEBIAdBBEsbdiIDQQkgB2siBCADIARIGyIDIANBAUwbIgM6AAAgAkGVEmogAzoAACACQZASaiADIAVqIgM6AAAgAkGUEmogAzoAAAwBCyACQZQSakEAOgAAIAJBkhJqQQA6AAAgAkGQEmpBADoAAAsgAkGWEmpBAToAAAJAQT8CfyABBEAgAiwAeiIDIAIoAnANARogAigCPCADagwBCyACKAI8CyIDIANBP04bIgNBAEoEQEECIANBACADQQBKGyIGQQ5LIAZBJ0sbIQQgBkEBdCEFIAIoAkAiB0EATARAIAJBmxJqIAQ6AAAgAkGYEmogAyAFaiIGOgAAIAJBmRJqIAM6AAAgAkGdEmogAzoAACACQZoSakEAOgAAIAJBnxJqIAQ6AAAgAkGcEmogBjoAAAwCCyACQZsSaiAEOgAAIAJBmhJqQQA6AAAgAkGfEmogBDoAACACQZkSakEBIAZBAkEBIAdBBEsbdiIDQQkgB2siBCADIARIGyIDIANBAUwbIgM6AAAgAkGdEmogAzoAACACQZgSaiADIAVqIgM6AAAgAkGcEmogAzoAAAwBCyACQZwSakEAOgAAIAJBmhJqQQA6AAAgAkGYEmpBADoAAAsgAkGeEmpBAToAAAJAQT8CfyABBEAgAiwAeyIBIAIoAnANARogAigCPCABagwBCyACKAI8CyIBIAFBP04bIgFBAEoEQEECIAFBACABQQBKGyIEQQ5LIARBJ0sbIQMgBEEBdCEGIAIoAkAiBUEASg0BIAJBoxJqIAM6AAAgAkGgEmogASAGaiIEOgAAIAJBoRJqIAE6AAAgAkGlEmogAToAACACQaISakEAOgAAIAJBpxJqIAM6AAAgAkGkEmogBDoAAAwCCyACQaQSakEAOgAAIAJBohJqQQA6AAAgAkGgEmpBADoAAAwBCyACQaMSaiADOgAAIAJBohJqQQA6AAAgAkGnEmogAzoAACACQaESakEBIARBAkEBIAVBBEsbdiIBQQkgBWsiAyABIANIGyIBIAFBAUwbIgE6AAAgAkGlEmogAToAACACQaASaiABIAZqIgE6AAAgAkGkEmogAToAAAsgAkGmEmpBAToAAAsgAkEANgKYASACKAKUASIBQQBKBEAgAkEANgKQASACKAKAAUUEQCACQQE2AoABCyACIAJBtAFqNgKMASACIAI2AogBIAJBIDYChAFBA0ECIAhBAEobIQsLIAIgCzYCnAEgCkECdCIEQQFBAiABQQBMG2xBACAIQQBKGyEGIApBBXQiByALQQR0IhEgCEHMLWotAABqQQNsQQF2bCENIApBAXRBAmohBSAKQQJBASABQQJGG2xBoAZsIRRBACEDAkAgAigCrBIEfiACMwEyIAIzATB+BUIACyI3IA2tIAatIBStIAWtIAetIAStfHx8fHx8IjZCwAZ8IjhC4P///w9WDQAgAigC8BEhAwJAIDZC3wZ8IjYgAjUC9BFWBEAgAxASIAJBADYC9BEgOELi//v/B1oEQCACQQA2AvARDAILIAIgNqciARAWIgM2AvARIANFDQEgAiABNgL0ESACKAKEEiEIIAIoApQBIQELIAIgAzYCxBEgAkEANgKgASACIAMgBGoiAzYCzBEgAiADIAdqIgNBAmoiEjYC0BEgAiADIAVqIgdBACAGGyIDNgLUESACIAM2AqwBIAYgB2ohBgJAIAhBAEoEQCABQQBMBEAgAiAGQR9qQWBxIgc2AtgRIAIgB0HABmoiBjYCgBIMAgsgAiADIApBAnRqNgKsAQsgAiAGQR9qQWBxIgc2AtgRIAIgB0HABmoiAzYCgBIgAyAKQQAgAUECRhtBoAZsaiEGCyACQQA2ApgBIAIgCkEDdCIBNgLsESACIApBBHQiAzYC6BEgAiAGNgKwASACIAcgFGpBwAZqIgYgAyAIQcwtai0AACIIbGoiCjYC3BEgAkEAIAYgDWogN1AbNgK8EiACIAhBAXYgAWwiBiAKIAMgEWxqaiIDNgLgESACIAMgASALbEEDdGogBmo2AuQRIBJBAmtBACAFEBUaIAIoAtARQQJrQQA7AAAgAkEANgL4ESACQQA2AsgRIAIoAsQRQQAgBBAVGiAJQQA2AiwgCSACKALcETYCOCAJIAIoAuARNgI8IAkgAigC5BE2AkAgCSACKALoETYCRCACKALsESEBIAlBADYCjAEgCSABNgJIQfzaACgCAEELRwRAQaDgAEEhNgIAQZzgAEEiNgIAQejfAEEjNgIAQeDfAEEkNgIAQdjfAEElNgIAQdTfAEEmNgIAQdDfAEEnNgIAQfTfAEEoNgIAQfDfAEEpNgIAQezfAEEqNgIAQeTfAEErNgIAQdzfAEEsNgIAQcjfAEEtNgIAQcTfAEEuNgIAQcDfAEEvNgIAQbzfAEEwNgIAQbjfAEExNgIAQbTfAEEyNgIAQbDfAEEzNgIAQZjgAEE0NgIAQZTgAEE1NgIAQZDgAEE2NgIAQYzgAEE3NgIAQYjgAEE4NgIAQYTgAEE5NgIAQYDgAEE6NgIAQfzaAEELNgIACyACQQA2AvwRAkAgAigCtAJBAEoEQCACQaABaiEsIAJByBFqIS0gAkG0AWohLiACQbQQaiERIAJB8A9qIS8gAkH4EGohDSACQawPaiEUA0AgAigCuAIhHEEAIRAgAigCoAIiAUEASgRAA0AgAigCxBEhCCACKAKAEiEKAkAgAigCbEUEQEEAIQUMAQsgAigCECEGIAItAIgHIQcCQCACKAIUIgNBAE4EQCADIQEMAQsgAigCGCIEIAIoAiBJBEAgBCgAACEBIAIgBEEDajYCGCACIAIoAgxBGHQgAUEIdkGA/gNxIAFBGHQgAUGA/gNxQQh0cnJBCHZyNgIMIANBGGohAQwBCyACKAIcIARLBEAgAiADQQhqIgE2AhQgAiAEQQFqNgIYIAIgBC0AACACKAIMQQh0cjYCDAwBC0EAIQEgAigCJA0AIAIgAigCDEEIdDYCDCACQQE2AiQgA0EIaiEBCyACIAECfyACKAIMIgUgAXYiCyAGIAdsQQh2IgNLBEAgAiADQX9zIAF0IAVqIgU2AgwgBiADawwBCyADQQFqCyIEZ0EYcyIGayIBNgIUIAIgBCAGdEEBayIENgIQAn8gAyALTwRAIAItAIkHIQcCQCABQQBODQAgAigCGCIDIAIoAiBJBEAgAygAACEGIAIgA0EDajYCGCACIAVBGHQgBkEIdkGA/gNxIAZBGHQgBkGA/gNxQQh0cnJBCHZyIgU2AgwgAUEYaiEBDAELIAIoAhwgA0sEQCACIAFBCGoiATYCFCACIANBAWo2AhggAiADLQAAIAVBCHRyIgU2AgwMAQsgAigCJEUEQCACIAVBCHQiBTYCDCACIAFBCGoiATYCFCACQQE2AiQMAQtBACEBIAJBADYCFAsCfyAFIAF2IgYgBCAHbEEIdiIDSwRAIAIgA0F/cyABdCAFajYCDCAEIANrDAELIANBAWoLIQQgAyAGSSEFIAEgBGdBGHMiA2shASAEIAN0DAELIAItAIoHIQcCQCABQQBODQAgAigCGCIDIAIoAiBJBEAgAygAACEGIAIgA0EDajYCGCACIAVBGHQgBkEIdkGA/gNxIAZBGHQgBkGA/gNxQQh0cnJBCHZyIgU2AgwgAUEYaiEBDAELIAIoAhwgA0sEQCACIAFBCGoiATYCFCACIANBAWo2AhggAiADLQAAIAVBCHRyIgU2AgwMAQsgAigCJEUEQCACIAVBCHQiBTYCDCACIAFBCGoiATYCFCACQQE2AiQMAQtBACEBIAJBADYCFAsCfyAEIAdsQQh2IgMgBSABdkkEQCACIANBf3MgAXQgBWo2AgwgBCADayEHQQMMAQsgA0EBaiEHQQILIQUgASAHZ0EYcyIDayEBIAcgA3QLIQMgAiABNgIUIAIgA0EBazYCEAsgCiAQQaAGbGoiCyAFOgCeBgJAIAIoArwRRQRAIAIoAhQhASACKAIQIQMMAQsgAigCECEGIAItAMARIQoCQCACKAIUIgNBAE4EQCADIQEMAQsgAigCGCIEIAIoAiBJBEAgBCgAACEBIAIgBEEDajYCGCACIAIoAgxBGHQgAUEIdkGA/gNxIAFBGHQgAUGA/gNxQQh0cnJBCHZyNgIMIANBGGohAQwBCyACKAIcIARLBEAgAiADQQhqIgE2AhQgAiAEQQFqNgIYIAIgBC0AACACKAIMQQh0cjYCDAwBC0EAIQEgAigCJA0AIAIgAigCDEEIdDYCDCACQQE2AiQgA0EIaiEBCyACIAECfyACKAIMIgMgAXYiBSAGIApsQQh2IgRLBEAgAiAEQX9zIAF0IANqNgIMIAYgBGsMAQsgBEEBagsiA2dBGHMiBmsiATYCFCACIAMgBnRBAWsiAzYCECALIAQgBUk6AJ0GCwJAIAFBAE4NACACKAIYIgQgAigCIEkEQCAEKAAAIQYgAiAEQQNqNgIYIAIgAigCDEEYdCAGQQh2QYD+A3EgBkEYdCAGQYD+A3FBCHRyckEIdnI2AgwgAUEYaiEBDAELIAIoAhwgBEsEQCACIAFBCGoiATYCFCACIARBAWo2AhggAiAELQAAIAIoAgxBCHRyNgIMDAELIAIoAiRFBEAgAiACKAIMQQh0NgIMIAJBATYCJCABQQhqIQEMAQtBACEBIAJBADYCFAsgEEECdCAIaiEVIAIgAQJ/IANBkQFsQQh2IgQgAigCDCIFIAF2TyIGRQRAIAIgBEF/cyABdCAFaiIFNgIMIAMgBGsMAQsgBEEBagsiA2dBGHMiBGsiATYCFCACIAMgBHRBAWsiCDYCECALIAY6AIAGAkAgBkUEQAJAIAFBAE4NACACKAIYIgMgAigCIEkEQCADKAAAIQQgAiADQQNqNgIYIAIgBUEYdCAEQQh2QYD+A3EgBEEYdCAEQYD+A3FBCHRyckEIdnIiBTYCDCABQRhqIQEMAQsgAigCHCADSwRAIAIgAUEIaiIBNgIUIAIgA0EBajYCGCACIAMtAAAgBUEIdHIiBTYCDAwBCyACKAIkBEBBACEBDAELIAIgBUEIdCIFNgIMIAJBATYCJCABQQhqIQELIAIgAQJ/IAhBnAFsQQh2IgMgBSABdk8iBkUEQCACIANBf3MgAXQgBWoiBTYCDCAIIANrDAELIANBAWoLIgNnQRhzIgRrIgE2AhQgAiADIAR0QQFrIgQ2AhACfyAGRQRAAkAgAUEATg0AIAIoAhgiAyACKAIgSQRAIAMoAAAhBiACIANBA2o2AhggAiAFQRh0IAZBCHZBgP4DcSAGQRh0IAZBgP4DcUEIdHJyQQh2ciIFNgIMIAFBGGohAQwBCyACKAIcIANLBEAgAiABQQhqIgE2AhQgAiADQQFqNgIYIAIgAy0AACAFQQh0ciIFNgIMDAELIAIoAiRFBEAgAiAFQQh0IgU2AgwgAiABQQhqIgE2AhQgAkEBNgIkDAELQQAhASACQQA2AhQLAn8gBEEBdkH///8HcSIDIAUgAXZJBEAgAiADQX9zIAF0IAVqNgIMIAQgA2shB0EBDAELIANBAWohB0EDCyEFIAEgB2dBGHMiA2shASAHIAN0DAELAkAgAUEATg0AIAIoAhgiAyACKAIgSQRAIAMoAAAhBiACIANBA2o2AhggAiAFQRh0IAZBCHZBgP4DcSAGQRh0IAZBgP4DcUEIdHJyQQh2ciIFNgIMIAFBGGohAQwBCyACKAIcIANLBEAgAiABQQhqIgE2AhQgAiADQQFqNgIYIAIgAy0AACAFQQh0ciIFNgIMDAELIAIoAiRFBEAgAiAFQQh0IgU2AgwgAiABQQhqIgE2AhQgAkEBNgIkDAELQQAhASACQQA2AhQLAn8gBEGjAWxBCHYiAyAFIAF2SQRAIAIgA0F/cyABdCAFajYCDCAEIANrIQdBAgwBCyADQQFqIQdBAAshBSABIAdnQRhzIgNrIQEgByADdAshAyACIAE2AhQgAiADQQFrNgIQIAsgBToAgQYgFSAFQYGChAhsIgE2AAAgLSABNgAADAELIAtBgQZqIQdBACESA0AgEiAtaiIdLQAAIQFBACEKA0AgCiAVaiIOLQAAQdoAbCABQQlsakGQI2oiDy0AACEIIAIoAhAhBQJAIAIoAhQiA0EATgRAIAMhAQwBCyACKAIYIgQgAigCIEkEQCAEKAAAIQEgAiAEQQNqNgIYIAIgAigCDEEYdCABQQh2QYD+A3EgAUEYdCABQYD+A3FBCHRyckEIdnI2AgwgA0EYaiEBDAELIAIoAhwgBEsEQCACIANBCGoiATYCFCACIARBAWo2AhggAiAELQAAIAIoAgxBCHRyNgIMDAELQQAhASACKAIkDQAgAiACKAIMQQh0NgIMIAJBATYCJCADQQhqIQELIAIgAQJ/IAIoAgwiBiABdiITIAUgCGxBCHYiCEsEQCACIAhBf3MgAXQgBmoiBjYCDCAFIAhrDAELIAhBAWoLIgFnQRhzIgNrIgQ2AhQgAiABIAN0QQFrIgM2AhAgCCATSSIFQaAqai0AACEBIAYhCEHqxQIgBXZBAXEEQANAIA8gAcAiAWotAAAhEyABQQF0ISECfwJ/IARBAE4EQCAEIQEgCAwBCwJAIAIoAhgiBSACKAIgSQRAIAUoAAAhASACIAVBA2o2AhggAiAIQRh0IAFBCHZBgP4DcSABQRh0IAFBgP4DcUEIdHJyQQh2ciIGNgIMIARBGGohAQwBCyACKAIcIAVLBEAgAiAEQQhqIgE2AhQgAiAFQQFqNgIYIAIgBS0AACAIQQh0ciIGNgIMDAELQQAhASAGIAIoAiQNARogAiAIQQh0IgY2AgwgAkEBNgIkIARBCGohAQsgBgsiCCABdiIiIAMgE2xBCHYiBUsEQCACIAVBf3MgAXQgCGoiBjYCDCAGIQggAyAFawwBCyAFQQFqCyEDIAIgASADZ0EYcyIBayIENgIUIAIgAyABdEEBayIDNgIQICEgBSAiSXIiBUGgKmotAAAhAUHqxQIgBXZBAXENAAsLIA5BACABwGsiAToAACAKQQFqIgpBBEcNAAsgByAVKAAANgAAIB0gAToAACAHQQRqIQcgEkEBaiISQQRHDQALCyACKAIQIQYCQCACKAIUIgFBAE4NACACKAIYIgMgAigCIEkEQCADKAAAIQQgAiADQQNqNgIYIAIgAigCDEEYdCAEQQh2QYD+A3EgBEEYdCAEQYD+A3FBCHRyckEIdnI2AgwgAUEYaiEBDAELIAIoAhwgA0sEQCACIAFBCGoiATYCFCACIANBAWo2AhggAiADLQAAIAIoAgxBCHRyNgIMDAELIAIoAiRFBEAgAiACKAIMQQh0NgIMIAIgAUEIaiIBNgIUIAJBATYCJAwBC0EAIQEgAkEANgIUCyACIAECfyAGQY4BbEEIdiIDIAIoAgwiBSABdk8iBEUEQCACIANBf3MgAXQgBWoiBTYCDCAGIANrDAELIANBAWoLIgNnQRhzIgZrIgE2AhQgAiADIAZ0QQFrIgY2AhBBACEHAkAgBA0AAkAgAUEATg0AIAIoAhgiAyACKAIgSQRAIAMoAAAhBCACIANBA2o2AhggAiAFQRh0IARBCHZBgP4DcSAEQRh0IARBgP4DcUEIdHJyQQh2ciIFNgIMIAFBGGohAQwBCyACKAIcIANLBEAgAiABQQhqIgE2AhQgAiADQQFqNgIYIAIgAy0AACAFQQh0ciIFNgIMDAELIAIoAiQEQEEAIQEMAQsgAiAFQQh0IgU2AgwgAkEBNgIkIAFBCGohAQsgAiABAn8gBkHyAGxBCHYiAyAFIAF2TyIERQRAIAIgA0F/cyABdCAFaiIFNgIMIAYgA2sMAQsgA0EBagsiA2dBGHMiBmsiATYCFCACIAMgBnRBAWsiBjYCEEECIQcgBA0AAkAgAUEATg0AIAIoAhgiAyACKAIgSQRAIAMoAAAhBCACIANBA2o2AhggAiAFQRh0IARBCHZBgP4DcSAEQRh0IARBgP4DcUEIdHJyQQh2ciIFNgIMIAFBGGohAQwBCyACKAIcIANLBEAgAiABQQhqIgE2AhQgAiADQQFqNgIYIAIgAy0AACAFQQh0ciIFNgIMDAELIAIoAiQEQEEAIQEMAQsgAiAFQQh0IgU2AgwgAkEBNgIkIAFBCGohAQsgAiABAn8gBkG3AWxBCHYiAyAFIAF2SQRAIAIgA0F/cyABdCAFajYCDEEBIQcgBiADawwBC0EDIQcgA0EBagsiAWdBGHMiA2s2AhQgAiABIAN0QQFrNgIQCyALIAc6AJEGIBBBAWoiECACKAKgAiIBSA0ACwsgAigCJA0CIAEgAigC+BEiFUoEQCACIBkgHHFBHGxqIiFBvAJqIQcDQCACKALQESIBIBVBAXRqIRAgAUECayEZIAIoAoASIRwCfwJAIAIoArwRBEAgHCAVQaAGbGoiAy0AnQYNAQtBACESIAIgHCAVQaAGbCIiaiIILQCeBkEFdGohHUEAIQUgDSEEIAhBAEGABhAVIgYtAIAGRQRAIAlCADcDqAEgCUIANwOgASAJQgA3A5gBIAlCADcDkAEgAUEBayIBIAcgLyABLQAAIBAtAAFqIB1BkAZqQQAgCUGQAWpBpN8AKAIAEQcAIgNBAEoiAToAACAQIAE6AAEgCS4BkAEhAQJAIANBAk4EQCAGIAkuAaoBIgMgCS4BkgEiBGoiCiAJLgGiASIFIAkuAZoBIgtqIg5rIg8gCS4BrAEiEyAJLgGUASIWaiIXIAkuAaQBIhggCS4BnAEiGmoiI2siHmsiJCAJLgGoASIbIAFqIiUgCS4BoAEiHyAJLgGYASIgaiIma0EDaiInIAkuAa4BIiggCS4BlgEiKWoiMCAJLgGmASIxIAkuAZ4BIjJqIjNrIjRrIjVqQQN2OwGgAiAGIA8gHmoiDyAnIDRqIh5qQQN2OwGAAiAGICAgH2siHyABIBtrIgFqQQNqIhsgMiAxayIgICkgKGsiJ2oiKGsiKSALIAVrIgUgBCADayIDaiIEIBogGGsiCyAWIBNrIhNqIhZrIhhrQQN2OwHgASAGIBsgKGoiGiAEIBZqIgRrQQN2OwHAASAGIBggKWpBA3Y7AaABIAYgBCAaakEDdjsBgAEgBiAlICZqQQNqIgQgMCAzaiIWayIYIAogDmoiCiAXICNqIg5rIhdrQQN2OwFgIAYgBCAWaiIEIAogDmoiCmtBA3Y7AUAgBiAXIBhqQQN2OwEgIAYgBCAKakEDdjsBACABIB9rQQNqIgEgJyAgayIKayIOIAMgBWsiAyATIAtrIgVrIgtrQQN2IQQgASAKaiIBIAMgBWoiCmtBA3YhAyALIA5qQQN2IQsgASAKakEDdiEKIDUgJGtBA3YhASAeIA9rQQN2IQUMAQsgBiABQQNqQQN1IgU7AaACIAYgBTsBgAIgBiAFOwHgASAGIAU7AcABIAYgBTsBoAEgBiAFOwGAASAGIAU7AWAgBiAFOwFAIAYgBTsBICAGIAU7AQAgBSIBIgoiCyIDIQQLIAYgBDsB4AMgBiADOwHAAyAGIAs7AaADIAYgCjsBgAMgBiABOwHgAiAGIAU7AcACQQEhBSAUIQQLIB1BiAZqIQMgGS0AAEEPcSEGIBAtAABBD3EhC0EAIQoDQCAHIAQgBkEBcSALQQFxaiADIAUgCCIBQaTfACgCABEHACEIIAEvAQAhEyAHIAQgBSAISCIOIAtBAXYiD0EBcWogAyAFIAFBIGpBpN8AKAIAEQcAIQsgAS8BICEWIAcgBCAFIAtIIhcgD0H+AHEgDkEHdHJBAXYiD0EBcWogAyAFIAFBQGtBpN8AKAIAEQcAIQ4gAS8BQCEYIAcgBCAFIA5IIhogF0EHdCAPckEBdiIXQQFxaiADIAUgAUHgAGpBpN8AKAIAEQcAIQ9BA0ECIBZBAEcgC0ECThsgC0EDShtBDEEIIBNBAEdBAnQgCEECThsgCEEDShtyQQR0QQxBCCAYQQBHQQJ0IA5BAk4bIA5BA0obckEDQQIgAS8BYEEARyAPQQJOGyAPQQNKG3IgEkEIdHIhEiAFIA9IIghBA3QgGkEHdCAXckEFdnIhCyAIQQd0IAZB/gFxQQF2ciEGIAFBgAFqIQggCkEBaiIKQQRHDQALIAcgESAZLQAAIgpBBHZBAXEgEC0AACIFQQR2QQFxaiAdQZgGaiIDQQAgCEGk3wAoAgARBwAhBCABLwGAASEWIAcgESAEQQBKIg4gBUEFdkEBcWogA0EAIAFBoAFqQaTfACgCABEHACEIIAEvAaABIRcgByARIApBBXZBAXEgDmogA0EAIAFBwAFqQaTfACgCABEHACEKIAEvAcABIRggByARIApBAEoiGiAIQQBKIiNqIANBACABQeABakGk3wAoAgARBwAhBSABLwHgASEeIAcgESAZLQAAIhNBBnZBAXEgEC0AACIPQQZ2QQFxaiADQQAgAUGAAmpBpN8AKAIAEQcAIQ4gAS8BgAIhJCAHIBEgDkEASiIbIA9BB3ZqIANBACABQaACakGk3wAoAgARBwAhDyABLwGgAiElIAcgESATQQd2IBtqIANBACABQcACakGk3wAoAgARBwAhEyABLwHAAiEbIAcgESATQQBKIh8gD0EASiIgaiADQQAgAUHgAmpBpN8AKAIAEQcAIQMgAS8B4AIhJiAQIAsgA0EASkEHdCIBIB9BBnRyIAVBAEpBBXQiECAaQQR0cnJyOgAAIBkgI0EEdCAGQQR2ciAQciAgQQZ0ciABcjoAACAcICJqIgFBA0ECIBdBAEcgCEECThsgCEEDShtBDEEIIBZBAEdBAnQgBEECThsgBEEDShtyQQR0QQxBCCAYQQBHQQJ0IApBAk4bIApBA0obckEDQQIgHkEARyAFQQJOGyAFQQNKG3JBA0ECICVBAEcgD0ECThsgD0EDShtBDEEIICRBAEdBAnQgDkECThsgDkEDShtyQQR0QQxBCCAbQQBHQQJ0IBNBAk4bIBNBA0obckEDQQIgJkEARyADQQJOGyADQQNKG3JBCHRyIgM2ApgGIAEgEjYClAYgASADQarVAnEEf0EABSAdKAKkBgs6AJwGIAMgEnJFDAELIBBBADoAACAZQQA6AAAgAy0AgAZFBEAgEEEAOgABIAFBAWtBADoAAAsgA0IANwKUBiADQQA6AJwGQQELIQMgAigChBJBAEoEQCACKALUESACKAL4EUECdGoiASACIBwgFUGgBmxqIgQtAJ4GQQN0aiAELQCABkECdGpBiBJqKAIANgAAIAEgAS0AAiADRXI6AAILICEoAtQCBEBBACEDIAIoAgANByACQZMRNgIIIAJCBzcCAAwHCyACIAIoAvgRQQFqIhU2AvgRIBUgAigCoAJIDQALC0EAIQEgAigC0BFBAmtBADsAACACQQA2AvgRIAJBADYCyBECQCACKAKEEkEATA0AIAIoAvwRIgMgAigCrAJIDQAgAyACKAK0AkwhAQsCQAJAIAIoApQBIgMEQCACKAKQAQ0BIC4gCUEkakHsABAUGiACIAE2AqgBIAIgAigCmAE2AqABIAIgAigC/BE2AqQBAkAgA0ECRgRAIAIoAoASIQMgAiACKAKwATYCgBIgAiADNgKwAQwBCyACICwQKwsgAQRAIAIoAtQRIQEgAiACKAKsATYC1BEgAiABNgKsAQsgAigChAEiAQRAIAIoAogBIAIoAowBIAERBQAhASACIAIoApABIAFFcjYCkAELIAIgAigCmAFBAWoiAUEAIAEgAigCnAFHGzYCmAEMAgsgAiABNgKoASACIAIoAvwRNgKkASACICwQKyACIAlBJGoQLw0BC0EAIQMgAigCAA0FIAJBgxE2AgggAkIGNwIADAULIAIgAigC/BFBAWoiGTYC/BEgGSACKAK0AkgNAAsLIAIoApQBQQBKBEBBACEDIAIoApABDQMLQQEhAwwCC0EAIQMgAigCAA0BIAJBthE2AgggAkIHNwIADAELQQAhAyACKAIADQAgAkG0EDYCCCACQgE3AgALQQEhASACKAKUAUEASgRAIAIoApABRSEBCyAJKAJYIgQEQCAJQSRqIAQRAAALIAEgA3ENAgsgAkEANgKAASACKAK4EhASIAJCADcCuBIgAigCqBIiAQRAIAEoAhQiAwRAIAMQHSADEBILIAEQEgsgAkEANgKoEiACKALwERASIAJCADcCDCACQgA3AvARIAJCADcCFCACQgA3AhwgAkEANgIkIAJBADYCBAsgAigCACEBDAELQQAhASACQQA2AgQLIAJBADYCgAEgAigCuBIQEiACQgA3ArgSIAIoAqgSIgMEQCADKAIUIgQEQCAEEB0gBBASCyADEBILIAJBADYCqBIgAigC8BEQEgsgAhASIAEEQCAMKAJgIgNFDQEgAygCDEEATARAIAMoAlAQEgsgA0EANgJQDAELQQAhASAMKAJ0IgNFDQAgAygCMEUNACAMKAJgIgNFBEBBAiEBDAELIAMoAghBAWshBiADKAIQIQgCQCADKAIAQQpNBEAgAyAIIAYgA0EUaiIEKAIAIgNsajYCEAwBCyADQQAgAygCICIEazYCICADQQAgAygCJCIKazYCJCADQQAgAygCKCIFazYCKCADIAggBCAGbGo2AhAgAyADKAIUIAogBkEBdSIEbGo2AhQgAyADKAIYIAQgBWxqNgIYIAMoAhwiCEUNASADIAggA0EsaiIEKAIAIgMgBmxqNgIcCyAEQQAgA2s2AgALIAlBsAFqJAAgAQ0AIAwoAhgiAUUNAAJAQaDfAC0AAA0AQaDfAEEBOgAAQZDfAEGACBAENgIAQQYQJkGU3wBB/QoQBDYCAEEHECZBoN8ALQAADQBBoN8AQQE6AABBkN8AQYAIEAQ2AgBBBhAmQZTfAEH9ChAENgIAQQcQJgsgDCABNgIMIAwgKiArbEECdDYCCEGQ3wAoAgBBAUG8EiAMQQhqIgQQByIDEAggDCArNgIYIAwgKjYCECAMIAM2AgggAEGU3wAoAgBBA0HAEiAEEAc2AgAgAxADIAEQEgwBCyAAQQI2AgALIAxBwAFqJAALvwIBB38gACAAQR9rLQAAIgVBAWoiASAAQR5rLQAAIgJqQQF2IgM6AEAgACABIABBIGstAAAiBmpBAXY6AAAgACACIABBHWstAAAiAWpBAWpBAXYiBDoAQSAAIAM6AAEgACABIABBHGstAAAiA2pBAWpBAXYiBzoAQiAAIAQ6AAIgACAHOgADIAAgBSABQQJqIgRqIAJBAXRqQQJ2Igc6AGAgACAGIAJBAmoiAmogBUEBdGpBAnY6ACAgACADIAIgAUEBdGpqQQJ2IgU6AGEgACAHOgAhIABBGWstAAAhBiAAQRprLQAAIQIgACAAQRtrLQAAIgEgBCADQQF0ampBAnYiBDoAYiAAIAU6ACIgACAGIAEgAkEBdGpqQQJqQQJ2OgBjIAAgAiADIAFBAXRqakECakECdjoAQyAAIAQ6ACMLsAIBCX8gACAALQAfIgMgAC0APyIEakEBakEBdiICOgBiIAAgBCAALQBfIgdqQQFqQQF2OgBgIAAgAjoAQCAAIABBAWstAAAiBkEBaiIBIABBIWstAAAiAmpBAXYiBToAIiAAIAEgA2pBAXYiAToAQiAAIAU6AAAgACABOgAgIAAgAEEgay0AACIBIAZBAmoiBSACQQF0ampBAnYiCDoAIyAAIABBHmstAAAgASAAQR9rLQAAIglBAXRqakECakECdjoAAyAAIAkgAiABQQF0ampBAmpBAnY6AAIgACACIANBAmoiASAGQQF0ampBAnYiAjoAQyAAIAg6AAEgACAEIAVqIANBAXRqQQJ2IgM6AGMgACACOgAhIAAgASAHaiAEQQF0akECdjoAYSAAIAM6AEEL2QEBBn8gACAALQBfIgE6AGMgACABOgBiIAAgAToAYSAAIAE6AGAgACAALQAfIgRBAWoiAyAALQA/IgJqQQF2IgU6ACAgACADIABBAWstAAAiBmpBAXY6AAAgACABIAJqQQFqQQF2IgM6AEAgACAFOgACIAAgAzoAIiAAIAEgBGogAkEBdGpBAmpBAnYiAzoAISAAIAYgAkECaiICaiAEQQF0akECdjoAASAAIAEgAmogAUEBdGpBAnYiAjoAQSAAIAM6AAMgACACOgAjIAAgAToAQyAAIAE6AEILbgEBfyAAIAAtAF8gAEEday0AACAALQA/IABBHmstAAAgAC0AHyAAQR9rLQAAIABBIGstAAAgAEEBay0AAGpqampqampBBGpBA3ZB/wFxQYGChAhsIgE2AGAgACABNgBAIAAgATYAICAAIAE2AAALpAIBBn8gAEHvwwAgAEEhay0AAGsiAiAAQQFrLQAAaiIBIABBIGstAAAiA2otAAA6AAAgACABIABBH2stAAAiBGotAAA6AAEgACABIABBHmstAAAiBWotAAA6AAIgACABIABBHWstAAAiBmotAAA6AAMgACAGIAIgAC0AH2oiAWotAAA6ACMgACABIAVqLQAAOgAiIAAgASAEai0AADoAISAAIAEgA2otAAA6ACAgACAGIAIgAC0AP2oiAWotAAA6AEMgACABIAVqLQAAOgBCIAAgASAEai0AADoAQSAAIAEgA2otAAA6AEAgACAGIAIgAC0AX2oiAmotAAA6AGMgACACIAVqLQAAOgBiIAAgAiAEai0AADoAYSAAIAIgA2otAAA6AGAL4gEBBn8gACAAQRxrLQAAIABBHmstAAAiAkECaiIDIABBHWstAAAiAUEBdGpqQQJ2IgQ6AGMgACABIABBH2stAAAiBUECaiIGIAJBAXRqakECdiICOgBiIAAgAyAAQSBrLQAAIgFqIAVBAXRqQQJ2IgM6AGEgACAGIABBIWstAABqIAFBAXRqQQJ2IgE6AGAgACAEOgBDIAAgAjoAQiAAIAM6AEEgACABOgBAIAAgBDoAIyAAIAI6ACIgACADOgAhIAAgAToAICAAIAQ6AAMgACACOgACIAAgAzoAASAAIAE6AAALpgIBBX8gACAALQBfIAAtAB8iAUECaiIDIAAtAD8iAkEBdGpqQQJ2OgBgIAAgAiAAQQFrLQAAIgRBAmoiBSABQQF0ampBAnYiAToAYSAAIAE6AEAgACAAQSFrLQAAIgIgAyAEQQF0ampBAnYiAToAYiAAIAE6AEEgACABOgAgIAAgBSAAQSBrLQAAIgNqIAJBAXRqQQJ2IgE6AGMgACABOgBCIAAgAToAISAAIAE6AAAgAEEday0AACEFIABBHmstAAAhASAAIAIgAEEfay0AACIEaiADQQF0akECakECdiICOgBDIAAgAjoAIiAAIAI6AAEgACABIANqIARBAXRqQQJqQQJ2IgI6ACMgACACOgACIAAgBCAFaiABQQF0akECakECdjoAAwujAgEFfyAAIABBHWstAAAiAkECaiIFIABBH2stAAAiA2ogAEEeay0AACIBQQF0akECdiIEOgAgIAAgAUECaiIBIABBIGstAABqIANBAXRqQQJ2OgAAIAAgAEEcay0AACIDIAEgAkEBdGpqQQJ2IgE6AEAgACAEOgABIAAgAToAISAAIABBG2stAAAiBCAFIANBAXRqakECdiICOgBgIAAgAToAAiAAIAI6AEEgACACOgAiIAAgAjoAAyAAIABBGmstAAAiAiADIARBAXRqakECakECdiIDOgBhIAAgAEEZay0AACIBIAQgAkEBdGpqQQJqQQJ2IgQ6AGIgACADOgAjIAAgAzoAQiAAIAEgAmogAUEBdGpBAmpBAnY6AGMgACAEOgBDCy8AIAAgARAhIABBIGogAUEEahAhIABBQGsgAUGAAWoQISAAQeAAaiABQYQBahAhC08BAX8gAC8BACICBEAgAiABECALIAAvASAiAgRAIAIgAUEEahAgCyAALwFAIgIEQCACIAFBgAFqECALIAAvAWAiAARAIAAgAUGEAWoQIAsLqQIBBH8jAEEQayICJAAgASgCACIEQfD///8HSQRAAkACQCAEQQtPBEAgBEEPckEBaiIFEDghAyACIAVBgICAgHhyNgIIIAIgAzYCACACIAQ2AgQgAyAEaiEFDAELIAIgBDoACyACIARqIQUgAiEDIARFDQELIAMgAUEEaiAEEBQaCyAFQQA6AAAgAkEMaiACIAARAwAgAigCDBAIIAIoAgwiABADIAIsAAtBAEgEQCACKAIAEBILIAJBEGokACAADwtB2AAQFkHQAGoiA0Hk2gA2AgAgA0GQ2QA2AgBBGRA4IgFBADYCCCABQoyAgIDAATcCACABQQxqIgBBlwopAAA3AAUgAUGSCikAADcADCADIAA2AgQgA0HA2QA2AgAgA0Hg2QBBPBANAAvkEgETfwJAIAEgACgCbCIDayICQQBMDQAgACgCCCIIKAIAIQsgACgCECAAKAJkIgUgA2xBAnRqIQYgACgCFCEJAkAgACgCsAEiBEEASgRAIAAgBEEBayICQRRsakG0AWogAyABIAYgCRAnIARBAUYNAQNAIAAgAkEBayIGQRRsakG0AWogAyABIAkgCRAnIAJBAUshBCAGIQIgBA0ACwwBCyAGIAlGDQAgCSAGIAIgBWxBAnQQFBoLIAgoAlgiBiABIAEgBkobIgYgCCgCVCICIAAoAmwiAyACIANKIgUbIgRMDQAgCCAGIARrIgY2AhAgCCAEIAJrNgIIIAggCCgCUCAIKAJMIgprIgQ2AgwgCSALQQJ0IhAgAiADa2xBACAFG2ogCkECdGohCyAAKAIMIgIoAgAiEUEKTQRAIAIoAhAgAigCFCINIAAoAnRsaiEKAkAgCCgCXARAIAZBAEwEQEEAIQgMAgtBACEJQQAhCANAIAsgCSAQbGoiAyAQIAAoAowCIgIoAiwgAigCICIEIAIoAhhqQQFrIARtIgQgBiAJayICIAIgBEobEEEgACgCjAIgAiADIBAQGyAJaiEJQQAhBQJAIAAoAowCIgNBQGsiDigCACADKAI4Tg0AIAogCCANbGohEyADKAI0IQwgAygCRCESA0AgAygCGEEASg0BQYjhACECAkACQCADKAIEDQBBjOEAIQIgAygCFA0AIAMoAjQgAygCCGxBAEwNASADKAJMIQdBACECA0AgAygCRCACaiAHIAJBAnQiBGooAgA6AAAgAygCTCIHIARqQQA2AgAgAkEBaiICIAMoAjQgAygCCGxIDQALDAELIAMgAigCABEAAAsgAyADKAIYIAMoAhxqNgIYIAMgAygCRCADKAJIajYCRCAOIA4oAgBBAWo2AgBBACECIAxBAEoEQANAIBIgAkECdGoiFCgCACIEQf///3dNBEBBACEHIBQgBEGAgIAITwR/IARBgICAeHFBgICAeCAEQRh2biIHIARB/wFxbEGAgIAEakEYdnIgByAEQQh2Qf8BcWxBgICABGpBEHZBgP4DcXIgByAEQRB2Qf8BcWxBgICABGpBCHZBgID8B3FyBUEACzYCAAsgAkEBaiICIAxHDQALCyASIAwgESAFIA1sIBNqEEAgBUEBaiEFIA4oAgAgAygCOEgNAAsLIAUgCGohCCAGIAlKDQALDAELIAZBAEoEQCAGIQIDQCALIAQgESAKEEAgCiANaiEKIAsgEGohCyACQQFLIQkgAkEBayECIAkNAAsLIAYhCAsgACAAKAJ0IAhqNgJ0IAAgATYCbA8LIAAoAnQhCQJAIAgoAlwEQCAGQQBMDQFBACEIA0AgCyAQIAAoAowCIgIoAiwgAigCICIDIAIoAhhqQQFrIANtIgMgBiAIayICIAIgA0obIgMQQSADIBBsIRMgACgCjAIgAiALIBAQGyAIaiEIQQAhDgJAIAAoAowCIgRBQGsiDCgCACAEKAI4Tg0AIAQoAjQiCkF8cSEUIApBA3EhEiAEKAJEIhFBA2ohDSAJIQMDQCAEKAIYQQBKDQFBiOEAIQICQAJAIAQoAgQNAEGM4QAhAiAEKAIUDQAgBCgCNCAEKAIIbEEATA0BIAQoAkwhB0EAIQIDQCAEKAJEIAJqIAcgAkECdCIFaigCADoAACAEKAJMIgcgBWpBADYCACACQQFqIgIgBCgCNCAEKAIIbEgNAAsMAQsgBCACKAIAEQAACyAEIAQoAhggBCgCHGo2AhggBCAEKAJEIAQoAkhqNgJEIAwgDCgCAEEBajYCAEEAIQICQCAKQQBMBEAgACgCDCEFDAELA0AgESACQQJ0aiIPKAIAIgdB////d00EQEEAIQUgDyAHQYCAgAhPBH8gB0GAgIB4cUGAgIB4IAdBGHZuIgUgB0H/AXFsQYCAgARqQRh2ciAFIAdBCHZB/wFxbEGAgIAEakEQdkGA/gNxciAFIAdBEHZB/wFxbEGAgIAEakEIdkGAgPwHcXIFQQALNgIACyACQQFqIgIgCkcNAAsgACgCDCIFKAIQIAUoAiAgA2xqIQ9BACECA0AgAiAPaiARIAJBAnRqKAIAIgdB/wFxQZQybCAHQRB2Qf8BcUHHgwFsaiAHQQh2Qf8BcUGjggJsakGAgMIAakEQdjoAACACQQFqIgIgCkcNAAsLIBEgBSgCFCADQQF1IgIgBSgCJGxqIAUoAhggBSgCKCACbGogCiADQX9zQQFxED8CQCAFKAIcIgJFDQAgCkEATA0AIAIgBSgCLCADbGohBUEAIQdBACECIApBBE8EQANAIAIgBWogDSACQQJ0ai0AADoAACAFIAJBAXIiD2ogDSAPQQJ0ai0AADoAACAFIAJBAnIiD2ogDSAPQQJ0ai0AADoAACAFIAJBA3IiD2ogDSAPQQJ0ai0AADoAACACQQRqIgIgFEcNAAsLIBJFDQADQCACIAVqIA0gAkECdGotAAA6AAAgAkEBaiECIAdBAWoiByASRw0ACwsgDkEBaiEOIANBAWohAyAMKAIAIAQoAjhIDQALCyALIBNqIQsgCSAOaiEJIAYgCEoNAAsMAQsgBkEATA0AIARBfHEhDSAEQQNxIQUgBEEATCEKIARBBEkhDgNAIAAoAgwhAyAKRQRAIAMoAhAgAygCICAJbGohB0EAIQIDQCACIAdqIAsgAkECdGooAgAiCEH/AXFBlDJsIAhBEHZB/wFxQceDAWxqIAhBCHZB/wFxQaOCAmxqQYCAwgBqQRB2OgAAIAJBAWoiAiAERw0ACwsgBiEIIAsgAygCFCAJQQF1IgYgAygCJGxqIAMoAhggAygCKCAGbGogBCAJQX9zQQFxED8CQCADKAIcIgJFDQAgCg0AIAtBA2ohBiACIAMoAiwgCWxqIQNBACEHQQAhAiAORQRAA0AgAiADaiAGIAJBAnRqLQAAOgAAIAMgAkEBciIMaiAGIAxBAnRqLQAAOgAAIAMgAkECciIMaiAGIAxBAnRqLQAAOgAAIAMgAkEDciIMaiAGIAxBAnRqLQAAOgAAIAJBBGoiAiANRw0ACwsgBUUNAANAIAIgA2ogBiACQQJ0ai0AADoAACACQQFqIQIgB0EBaiIHIAVHDQALCyAIQQFrIQYgCUEBaiEJIAsgEGohCyAIQQFLDQALCyAAIAk2AnQLIAAgATYCbAsoAEHQCkECQagSQbASQQJBA0EAEAJBxQlBAUG0EkG4EkEEQQVBABACCwuHUQcAQYAIC5QiVWludDhDbGFtcGVkQXJyYXkAdW5zaWduZWQgc2hvcnQAdW5zaWduZWQgaW50AGZsb2F0AHVpbnQ2NF90AGNhbm5vdCBwYXJzZSBwYXJ0aXRpb25zAGNhbm5vdCBwYXJzZSBzZWdtZW50IGhlYWRlcgBjYW5ub3QgcGFyc2UgZmlsdGVyIGhlYWRlcgBjYW5ub3QgcGFyc2UgcGljdHVyZSBoZWFkZXIAdW5zaWduZWQgY2hhcgBzdGQ6OmV4Y2VwdGlvbgB2ZXJzaW9uAGJvb2wAZW1zY3JpcHRlbjo6dmFsAGJhZCBwYXJ0aXRpb24gbGVuZ3RoAHVuc2lnbmVkIGxvbmcAc3RkOjp3c3RyaW5nAGJhc2ljX3N0cmluZwBzdGQ6OnN0cmluZwBzdGQ6OnUxNnN0cmluZwBzdGQ6OnUzMnN0cmluZwBkb3VibGUAZGVjb2RlAEJhZCBjb2RlIHdvcmQAdm9pZABGcmFtZSBzZXR1cCBmYWlsZWQASW1hZ2VEYXRhAFZQOFgAV0VCUABWUDhMAE9LAEFMUEgAUklGRgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxzaG9ydD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgc2hvcnQ+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dW5zaWduZWQgaW50PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxmbG9hdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDhfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50OF90PgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8aW50MTZfdD4AZW1zY3JpcHRlbjo6bWVtb3J5X3ZpZXc8dWludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGludDMyX3Q+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHVuc2lnbmVkIGNoYXI+AHN0ZDo6YmFzaWNfc3RyaW5nPHVuc2lnbmVkIGNoYXI+AGVtc2NyaXB0ZW46Om1lbW9yeV92aWV3PHNpZ25lZCBjaGFyPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxsb25nPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzx1bnNpZ25lZCBsb25nPgBlbXNjcmlwdGVuOjptZW1vcnlfdmlldzxkb3VibGU+AEluY29ycmVjdCBrZXlmcmFtZSBwYXJhbWV0ZXJzLgBUcnVuY2F0ZWQgaGVhZGVyLgBubyBtZW1vcnkgZHVyaW5nIGZyYW1lIGluaXRpYWxpemF0aW9uLgBOb3QgYSBrZXkgZnJhbWUuAEZyYW1lIG5vdCBkaXNwbGF5YWJsZS4AT3V0cHV0IGFib3J0ZWQuAFByZW1hdHVyZSBlbmQtb2YtZmlsZSBlbmNvdW50ZXJlZC4AUHJlbWF0dXJlIGVuZC1vZi1wYXJ0aXRpb24wIGVuY291bnRlcmVkLgBDb3VsZCBub3QgZGVjb2RlIGFscGhhIGRhdGEuAG51bGwgVlA4SW8gcGFzc2VkIHRvIFZQOEdldEhlYWRlcnMoKQBWUDggAAAAwCgAAHwnAABpaWkA6CsAAGlpAAA4KQAAwCgAAOgrAADoKwAAAAAAAP///////////////////////////////////////////7D2////////////3/H8///////////5/f3////////////0/P//////////6v7+///////////9///////////////2/v//////////7/3+///////////+//7////////////4/v//////////+//+///////////////////////////9/v//////////+/7+///////////+//7////////////+/f/+////////+v/+//7////////+/////////////////////////////////////////////////////////9n/////////////4fzx/f///v/////q+vH6/f/9/v/////+////////////3/7+///////////u/f7+///////////4/v//////////+f7////////////////////////////9////////////9/7////////////////////////////9/v///////////P/////////////////////////////+/v///////////f/////////////////////////////+/f//////////+v/////////////+/////////////////////////////////////////////////////////7r7+v//////////6vv0/v/////////7+/P9/v/+///////9/v//////////7P3+///////////7/f3+/v/////////+/v///////////v7+///////////////////////////+/////////////v7////////////+/////////////////////////////v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////j/////////////+v78/v/////////4/vn9///////////9/f//////////9v39///////////8/vv+/v/////////+/P//////////+P79///////////9//7+///////////7/v//////////9fv+///////////9/f7////////////7/f///////////P3+/////////////v/////////////8////////////+f/+//////////////7//////////////f//////////+v///////////////////////////////////////////v///////////////////////////4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgP2I/v/k24CAgICAvYHy/+PV/9uAgIBqfuP81tH//4CAgAFi+P/s4v//gICAtYXu/t3q/5qAgIBOhsr3xrT/24CAgAG5+f/z/4CAgICAuJb3/+zggICAgIBNbtj/7OaAgICAgAFl+//x/4CAgICAqovx/OzR//+AgIAldMTz5P///4CAgAHM/v/1/4CAgICAz6D6/+6AgICAgIBmZ+f/06uAgICAgAGY/P/w/4CAgICAsYfz/+rhgICAgIBQgdP/wuCAgICAgAEB/4CAgICAgICA9gH/gICAgICAgID/gICAgICAgICAgMYj7d/Bu6KgkZs+gy3G3ayw3J383QFEL5LQlafdov/fgAGV8f/d4P//gICAuI3q/d7c/8eAgIBRY7XysL75yv//gAGB6P3WxfLE//+AY3nS+snG/8qAgIAXW6Pyqrv30v//gAHI9v/q/4CAgICAbbLx/+f1//+AgIAsgsn9zcD//4CAgAGE7/vb0f+lgICAXojh+9q+//+AgIAWZK71uqH/x4CAgAG2+f/o64CAgICAfI/x/+PqgICAgIAjTbX7wdP/zYCAgAGd9//s5///gICAeY3r/+Hj//+AgIAtY7z7w9n/4ICAgAEB+//V/4CAgICAywH4//+AgICAgICJAbH/4P+AgICAgP0J+PvP0P/AgICArw3g88G5+cb//4BJEavdobPsp//qgAFf9/3Ut///gICA71r0+tPR//+AgICbTcP4vMP//4CAgAEY7/va2//NgICAyTPb/8S6gICAgIBFLr7vydr/5ICAgAG/+///gICAgICA36X5/9X/gICAgICNfPj//4CAgICAgAEQ+P//gICAgICAviTm/+z/gICAgICVAf+AgICAgICAgAHi/4CAgICAgICA98D/gICAgICAgIDwgP+AgICAgICAgAGG/P//gICAgICA1T76//+AgICAgIA3Xf+AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMoY1eu6v9yg8K//fia26Km45K7/u4A9Lorbl7Lwqv/YgAFw5vrHv/ef//+Apm3k/NPX/66AgIAnTaLorLT1sv//gAE03PbGx/nc//+AfEq/87fB+t3//4AYR4Lbmqrztv//gAG24fnb8P/ggICAlZbi/NjN/6uAgIAcbKryt8L+3///gAFR5vzMy//AgICAe2bR97zE/+mAgIAUX5nzpK3/y4CAgAHe+P/Y1YCAgICAqK/2/OvN//+AgIAvdNf/09T//4CAgAF57P3U1v//gICAjVTV/MnK/9uAgIAqUKDworn/zYCAgAEB/4CAgICAgICA9AH/gICAgICAgIDuAf+AgICAgICAgOd4MFlzcXiYcJizQH6qdi5GX69Fj1BVUkibZzg6CqvavRENmHIaEaMswxUKrXkYUMMaPixAVZBHCiar1ZAiGqouNxOIoCHORz8UCHJy0AwJ4lEoC2C2VB0QJIa3WYliZWqllEi7ZIKdbyBLUEJmp2NKPijqgCk1CbLxjRoIa0orGpJJpjEXnUEmaaAzNB9zgGhPDBvZ/1cRB1dERyxyMw+6Fy8pDm62txURwkItGWbFvRcSFlhYk5YqLi3EzStht3VVJiOzPSc1yFcaFSvoqzgiM2hyZh1dTSccVas6pVpiQCIWdM4XIiumSWs2IBozAVErH0QZahZAqyThciITFWaEvBBMfD4STl9VOTIwM8FlI5/Xb1kubzyUH6zb5BUSb3BxTVWz/yZ4cigqAcT10QoZbVgrHYym1SUrmj0/HptDLUQB0WRQCCuaATMaR45OThD/gCLFqykoBWbTtwQB3TMyEajRwBcZUoofJKsbpiYs5UNXOqlScxo7sz87WrQ7pl1JmigoFXSP0SInry8PELci3zEtty4RIbcGYg8gtzkuFhiAATYRJUEgSXMcgBeAzSgDCXMzwBIG31clCXM7TUAVL2g3LNoJNjWC4kBaRs0oKRcaOTY5cLgFKSam1R4iGoWYdAoghicTNd0aciBJ/x8JQeoCDwF2SUsgDDPA/6ArM1gfI0NmVTe6VTgVF287zS0lwDcmRnxJZgEiYn1iKlhoVXWvUl9UNVmAZHFlLUtPey8zgFGrATkRBUdmOTUpMSYhDXk5SRoBVSkKQ4pNblovcnMVAgpm/6YXBmUdEApVgGXEGjkSCmZm1SIUK3UUDySjgEQBGmY9RyUiNR/zwEU8RyZJdxzeJUQtgCIBLwv1qz4RE0aSVTc+RiUrJZpko1WgAT8JXIgcQCDJVUsPCQlA/7h3EFYGHAVA/xn4ATgIEYSJ/zd0gDoPFFKHORp5KKQyH4mahRkj2jNnLIODex8GnlYoQIeU4C23gBYaEYPwmg4B0S0QFVtA3gcBxTgVJ5s8ihdm1VMMDTbA/0QvHFUaVVWAgCCSqxILBz+QqwQE9iMbCpKuqwwagL5QI2O0UH42LVV+L1ewMykUIGVLgIt2knSAVTgpD7DsVSUJPkceEXd2/xESimUmPIo3RisajpIkEx6r/2EbFIotPT7bAVG8QCApFHWXjhQVo3ATDD3DgDAEGABBoSoLEQH/Av4DBAb9Bfz7+gf5CPj3AEHAKgu1BQQFBgcICQoKCwwNDg8QERESExQUFRUWFhcXGBkZGhscHR4fICEiIyQlJSYnKCkqKywtLi4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xMTU5PUFFSU1RVVldYWVtdX2BiZGVmaGpsbnBydHZ6fH6AgoSGiIqMj5GUl5qdBAAFAAYABwAIAAkACgALAAwADQAOAA8AEAARABIAEwAUABUAFgAXABgAGQAaABsAHAAdAB4AHwAgACEAIgAjACQAJQAmACcAKAApACoAKwAsAC0ALgAvADAAMQAyADMANAA1ADYANwA4ADkAOgA8AD4AQABCAEQARgBIAEoATABOAFAAUgBUAFYAWABaAFwAXgBgAGIAZABmAGgAagBsAG4AcAByAHQAdwB6AH0AgACDAIYAiQCMAI8AkgCVAJgAmwCeAKEApACnAKoArQCxALUAuQC9AMEAxQDJAM0A0QDVANkA3QDhAOUA6gDvAPUA+QD+AAMBCAENARIBFwEcAQgHBgQEAgICAQEBAQACCAAAAAQACAAMAIAAhACIAIwAAAEEAQgBDAGAAYQBiAGMAQABBAgFAgMGCQwNCgcLDg8QFwAAFBcAABkXAAAfFwAArZSMALCbjIcAtJ2NhoIA/v7z5sSxmYyFgoEAAAAAAACKC4wLjguSC5oLqgvKCwoMjAyMDYwPjBMAAAAAAAAAABESAAECAwQFEAYHCAkKCwwNDg8CAwcDAwsAAAAAAAAAGAcXGSgGJykWGiYqOAU3ORUbNjolK0gER0kUHDU7RkokLFhFSzQ8A1dZEx1WWiMtRExVWzM9aAJnaRIeZmoiLlRcQ01lazI+eAF3eVNdER9kbEJOdnohL3V7MT9jbVJeAHR8QU8QIGJuMHN9UV9Acn5hb1Bxf2BwAwQDBAQCAgQEBAIBAQBBgDAL4BGAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2Nzg5Ojs8PT4/QEFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38AAAAAAAAAAPDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDx8vP09fb3+Pn6+/z9/v8AAQIDBAUGBwgJCgsMDQ4PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PAEHwwwAL4wgBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AAP/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKuqqainpqWko6KhoJ+enZybmpmYl5aVlJOSkZCPjo2Mi4qJiIeGhYSDgoGAf359fHt6eXh3dnV0c3JxcG9ubWxramloZ2ZlZGNiYWBfXl1cW1pZWFdWVVRTUlFQT05NTEtKSUhHRkVEQ0JBQD8+PTw7Ojk4NzY1NDMyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gIGCg4SFhoeIiYqLjI2Oj5CRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6vsLGys7S1tre4ubq7vL2+v8DBwsPExcbHyMnKy8zNzs/Q0dLT1NXW19jZ2tvc3d7f4OHi4+Tl5ufo6err7O3u7/Dx8vP09fb3+Pn6+/z9/v8AAAAAAAEAAAADAAAABwAAAA8AAAAfAAAAPwAAAH8AAAD/AAAA/wEAAP8DAAD/BwAA/w8AAP8fAAD/PwAA/38AAP//AAD//wEA//8DAP//BwD//w8A//8fAP//PwD//38A////AEHgzAALjQ4wUuENhhizA8usX3dqYogcVVw4aCi4sxT4/oVKS7jdSZfz/GSJAlVcAAApStrBfg2rt0BZfVeSVHLKGU5pjNM4Ze4BDF91oTJS9jdUMiy7WrFXqg/nM/Vz2u5faOLMY3WDDplu7acwR8bZwE88FWtJ+gMUTwz7GlQyC5lzHMvXJgY3zG/Yd7ssKi92dd3MJWRhVLMkFYd9CqgUBCJnvx4UgxW0VuMC5XNvscpEQk0mKPuuunPt61AK+7ZqHQvUOg1oO9s1gx4IK5Vrznfw5YFRvDuFeJSUnwA87eUnTlN0M19fMjEyYmFzaWNfc3RyaW5nSWNOU18xMWNoYXJfdHJhaXRzSWNFRU5TXzlhbGxvY2F0b3JJY0VFRUUAAPQsAAA8JwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSWhOU18xMWNoYXJfdHJhaXRzSWhFRU5TXzlhbGxvY2F0b3JJaEVFRUUAAPQsAACEJwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSXdOU18xMWNoYXJfdHJhaXRzSXdFRU5TXzlhbGxvY2F0b3JJd0VFRUUAAPQsAADMJwAATlN0M19fMjEyYmFzaWNfc3RyaW5nSURzTlNfMTFjaGFyX3RyYWl0c0lEc0VFTlNfOWFsbG9jYXRvcklEc0VFRUUAAAD0LAAAFCgAAE5TdDNfXzIxMmJhc2ljX3N0cmluZ0lEaU5TXzExY2hhcl90cmFpdHNJRGlFRU5TXzlhbGxvY2F0b3JJRGlFRUVFAAAA9CwAAGAoAABOMTBlbXNjcmlwdGVuM3ZhbEUAAPQsAACsKAAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJY0VFAAD0LAAAyCgAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWFFRQAA9CwAAPAoAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0loRUUAAPQsAAAYKQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJc0VFAAD0LAAAQCkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SXRFRQAA9CwAAGgpAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0lpRUUAAPQsAACQKQAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJakVFAAD0LAAAuCkAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWxFRQAA9CwAAOApAABOMTBlbXNjcmlwdGVuMTFtZW1vcnlfdmlld0ltRUUAAPQsAAAIKgAATjEwZW1zY3JpcHRlbjExbWVtb3J5X3ZpZXdJZkVFAAD0LAAAMCoAAE4xMGVtc2NyaXB0ZW4xMW1lbW9yeV92aWV3SWRFRQAA9CwAAFgqAABOMTBfX2N4eGFiaXYxMTZfX3NoaW1fdHlwZV9pbmZvRQAAAAA0LQAAgCoAACQtAABOMTBfX2N4eGFiaXYxMTdfX2NsYXNzX3R5cGVfaW5mb0UAAAA0LQAAsCoAAKQqAABOMTBfX2N4eGFiaXYxMTdfX3BiYXNlX3R5cGVfaW5mb0UAAAA0LQAA4CoAAKQqAABOMTBfX2N4eGFiaXYxMTlfX3BvaW50ZXJfdHlwZV9pbmZvRQA0LQAAECsAAAQrAAAAAAAAhCsAAGMAAABkAAAAZQAAAGYAAABnAAAATjEwX19jeHhhYml2MTIzX19mdW5kYW1lbnRhbF90eXBlX2luZm9FADQtAABcKwAApCoAAHYAAABIKwAAkCsAAGIAAABIKwAAnCsAAGMAAABIKwAAqCsAAGgAAABIKwAAtCsAAGEAAABIKwAAwCsAAHMAAABIKwAAzCsAAHQAAABIKwAA2CsAAGkAAABIKwAA5CsAAGoAAABIKwAA8CsAAGwAAABIKwAA/CsAAG0AAABIKwAACCwAAHgAAABIKwAAFCwAAHkAAABIKwAAICwAAGYAAABIKwAALCwAAGQAAABIKwAAOCwAAE4xMF9fY3h4YWJpdjEyMF9fc2lfY2xhc3NfdHlwZV9pbmZvRQAAAAA0LQAARCwAANQqAABTdDlleGNlcHRpb24AAAAAAAAAAKwsAAA8AAAAaAAAAGkAAABTdDExbG9naWNfZXJyb3IANC0AAJwsAABULQAAAAAAAOAsAAA8AAAAagAAAGkAAABTdDEybGVuZ3RoX2Vycm9yAAAAADQtAADMLAAArCwAAAAAAADUKgAAYwAAAGsAAABlAAAAZgAAAGwAAABtAAAAbgAAAG8AAABTdDl0eXBlX2luZm8AAAAA9CwAABQtAAAAAAAAbCwAAGMAAABwAAAAZQAAAGYAAABsAAAAcQAAAHIAAABzAAAA9CwAAHgsAAAAAAAAVC0AAHQAAAB1AAAAdgBB8NoACyrwMwEAdC0AAHgtAAB8LQAAgC0AAIQtAACILQAAjC0AAJAtAACULQAAmC0='; diff --git a/packages/agent-core-v2/src/agent/media/webp-decode.ts b/packages/agent-core-v2/src/agent/media/webp-decode.ts index 253c07425..811fdcbc6 100644 --- a/packages/agent-core-v2/src/agent/media/webp-decode.ts +++ b/packages/agent-core-v2/src/agent/media/webp-decode.ts @@ -1,3 +1,23 @@ +/** + * `media` domain — WebP decoding for the image-compression pipeline. + * + * The default jimp build ships no WebP codec, so WebP is decoded with + * `@jsquash/webp`'s wasm decoder instead. The decoder wasm is compiled from a + * base64 string committed to the repo: the published + * CLI bundles every dependency into a single file with no runtime + * node_modules, so a file-path or fetch lookup for the .wasm (what the + * emscripten glue would do on its own) cannot work there — the module is + * compiled and injected manually via the codec's `init()` hook. Only the + * decoder is bundled: re-encoding runs through the existing PNG/JPEG ladder, + * so the (larger) WebP encoder wasm is never needed. + * + * The repo's tsconfig carries no DOM lib, so the global `WebAssembly` and + * `ImageData` names are unavailable at the type level — the wasm namespace is + * reached through a structurally-typed `globalThis` and the decoder's RGBA + * output is described by the local {@link DecodedWebp} shape. + */ + +/** Decoded RGBA bitmap in the shape `Jimp.fromBitmap` accepts. */ export interface DecodedWebp { readonly data: Uint8ClampedArray; readonly width: number; diff --git a/packages/agent-core-v2/src/agent/permissionGate/permissionGateService.ts b/packages/agent-core-v2/src/agent/permissionGate/permissionGateService.ts index c89d7f739..99e12990b 100644 --- a/packages/agent-core-v2/src/agent/permissionGate/permissionGateService.ts +++ b/packages/agent-core-v2/src/agent/permissionGate/permissionGateService.ts @@ -1,3 +1,16 @@ +/** + * `permissionGate` domain — `IAgentPermissionGate` implementation. + * + * Runs the `permissionPolicy` chain for every tool execution as an + * `onBeforeExecuteTool` veto listener: `deny` / `result` resolutions veto, + * `approve` passes with its `executionMetadata`, and `ask` defers to a cold + * `waitUntil` factory so the approval round-trip only starts once no other + * listener vetoed or allowed the call. Reports `permission_policy_decision` + * through `telemetry`, and delegates the ask round-trip (broker, events, + * session-rule recording) to `toolApproval`. This gate only adjudicates + * risk. Bound at Agent scope. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/permissionMode/configSection.ts b/packages/agent-core-v2/src/agent/permissionMode/configSection.ts index 7a6eb46b6..ff2dc104d 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/configSection.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/configSection.ts @@ -1,3 +1,16 @@ +/** + * `permissionMode` domain — registers the `defaultPermissionMode` config + * section into `config`. + * + * Owns the schema for the user's default permission posture — the mode a fresh + * main agent starts at — resolved through + * `IConfigService.get('defaultPermissionMode')`. This section is only the + * persisted default applied at main-agent creation; the live mode is + * Agent-scope wire state. Self-registers at module load via + * `registerConfigSection`, so the `config` domain never imports this domain's + * types. Bound at App scope. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/agent/permissionMode/injection/permissionModeInjection.ts b/packages/agent-core-v2/src/agent/permissionMode/injection/permissionModeInjection.ts index caf0c7647..ab415d49a 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/injection/permissionModeInjection.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/injection/permissionModeInjection.ts @@ -1,7 +1,21 @@ +/** + * `permissionMode` domain — permission-mode context injection. + * + * Owns the `permission_mode` context-injection provider. It reads the live mode + * from `IAgentPermissionModeService` and registers reminders through + * `contextInjector`. Dedup is history-derived: the framework mirrors this + * variant's live positions across splices, so a reminder folded away by + * compaction (or undo) is re-announced on the next inject, matching v1's + * compaction behavior. The plain-data state (`lastMode`) is registered into + * `agentState` (`IAgentStateService`) and read/written through it. + */ + import { Service } from '#/_base/di/service'; -import { defineState } from '#/state/state'; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import type { ContextInjectionContext } from '#/features/reminder/types'; +import { defineState } from '#/_base/state/stateRegistry'; +import { + IAgentContextInjectorService, + type ContextInjectionContext, +} from '#/agent/contextInjector/contextInjector'; import type { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import type { PermissionMode } from '#/agent/permissionPolicy/types'; import { IAgentStateService } from '#/agent/state/agentState'; @@ -18,13 +32,13 @@ export const permissionModeLastModeKey = defineState<PermissionMode | undefined> export class PermissionModeInjection extends Service { constructor( private readonly permissionMode: Pick<IAgentPermissionModeService, 'mode'>, - injector: ReminderRuntime, + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(permissionModeLastModeKey); + this.states.register(permissionModeLastModeKey); this._register( - injector.register(PERMISSION_MODE_INJECTION_VARIANT, (ctx) => this.reminder(ctx)), + dynamicInjector.register(PERMISSION_MODE_INJECTION_VARIANT, (ctx) => this.reminder(ctx)), ); } diff --git a/packages/agent-core-v2/src/agent/permissionMode/permissionMode.ts b/packages/agent-core-v2/src/agent/permissionMode/permissionMode.ts index aaae86387..1d0475874 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/permissionMode.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/permissionMode.ts @@ -12,7 +12,6 @@ export interface IAgentPermissionModeService { readonly mode: PermissionMode; setMode(mode: PermissionMode): void; - setModeAndBroadcast(mode: PermissionMode): void; readonly onDidChangeMode: Event<PermissionModeChangedContext>; } diff --git a/packages/agent-core-v2/src/agent/permissionMode/permissionModeOps.ts b/packages/agent-core-v2/src/agent/permissionMode/permissionModeOps.ts index efceeb8fe..2f3d2892d 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/permissionModeOps.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/permissionModeOps.ts @@ -1,32 +1,31 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `permissionMode` domain — wire Model (`PermissionModeModel`) and the + * `permission.set_mode` Op (`setMode`) for the agent's permission mode. + * + * Declares the mode as a scalar `wire` Model (initial `manual`) plus a replay + * marker that distinguishes an explicit persisted mode from the default. The + * single Op replaces the mode and sets that marker. + */ + import { z } from 'zod'; import type { PermissionMode } from '#/agent/permissionPolicy/types'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; -const permissionSetModeSchema = z.object({ - agentId: z.string(), - mode: z.custom<PermissionMode>(), -}); - -export class PermissionSetMode extends AgentEvent2<z.infer<typeof permissionSetModeSchema>> { - static override readonly type = 'permission.set_mode'; - static override readonly durable = true; - static override readonly schema = permissionSetModeSchema; -} -export interface PermissionSetMode { - readonly agentId: string; - readonly mode: PermissionMode; -} - -export const permissionModeKey = defineState('permissionMode', (): PermissionMode => 'manual') - .replayable({ schema: z.custom<PermissionMode>() }) - .on(PermissionSetMode, (_s, e) => e.mode); - -export const permissionModeConfiguredKey = defineState( +export const PermissionModeModel = defineModel<PermissionMode>('permissionMode', () => 'manual'); +export const PermissionModeConfiguredModel = defineModel<boolean>( 'permissionMode.configured', - (): boolean => false, -) - .replayable({ schema: z.custom<boolean>() }) - .on(PermissionSetMode, () => true); + () => false, + { reducers: { 'permission.set_mode': () => true } }, +); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'permission.set_mode': typeof setMode; + } +} + +export const setMode = PermissionModeModel.defineOp('permission.set_mode', { + schema: z.object({ mode: z.custom<PermissionMode>() }), + apply: (_s, p) => p.mode, +}); diff --git a/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts b/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts index 0f0f7a7d3..b556bfd9e 100644 --- a/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts +++ b/packages/agent-core-v2/src/agent/permissionMode/permissionModeService.ts @@ -1,23 +1,27 @@ +/** + * `permissionMode` domain — `IAgentPermissionModeService` implementation. + * + * Holds the agent's permission mode (`manual` / `yolo` / `auto`) in the `wire` + * `PermissionModeModel`, mutating it only through the `permission.set_mode` Op + * (`wire.dispatch(setMode({ mode }))`) and reading it through `wire.getModel`. + * `setMode` emits `onDidChangeMode` after an actual change, and mode-aware + * reminders are registered through the permission-mode injection helper. Bound + * at Agent scope. + */ + import type { PermissionMode } from '#/agent/permissionPolicy/types'; +import { IInstantiationService } from '#/_base/di/instantiation'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; import { PermissionModeInjection } from '#/agent/permissionMode/injection/permissionModeInjection'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { - IAgentLifecycleService, - MAIN_AGENT_ID, -} from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { IAgentPermissionModeService, type PermissionModeChangedContext } from './permissionMode'; import { - permissionModeConfiguredKey, - permissionModeKey, - PermissionSetMode, + PermissionModeConfiguredModel, + PermissionModeModel, + setMode, } from './permissionModeOps'; export class AgentPermissionModeService extends Service implements IAgentPermissionModeService { @@ -27,52 +31,24 @@ export class AgentPermissionModeService extends Service implements IAgentPermiss readonly onDidChangeMode: Event<PermissionModeChangedContext> = this._onDidChangeMode.event; constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, - @ITelemetryService private readonly telemetry: ITelemetryService, - @IAgentStateService private readonly agentState: IAgentStateService, + @IWireService private readonly wire: IWireService, + @IInstantiationService instantiation: IInstantiationService, ) { super(); - this.agentState.contributeState(permissionModeKey); - this.agentState.contributeState(permissionModeConfiguredKey); - this._register( - activateReminderWhenReady(this.agentLifecycle, this.scopeContext, (reminder) => - new PermissionModeInjection(this, reminder, this.agentState), - ), - ); + this._register(instantiation.createInstance(PermissionModeInjection, this)); } get mode(): PermissionMode { - return this.agentState.get(permissionModeKey); + return this.wire.getModel(PermissionModeModel); } setMode(mode: PermissionMode): void { const previousMode = this.mode; const changed = mode !== previousMode; - if (!changed && this.agentState.get(permissionModeConfiguredKey)) return; - void this.dispatcher.dispatch( - new PermissionSetMode({ agentId: this.scopeContext.agentId, mode }), - ); + if (!changed && this.wire.getModel(PermissionModeConfiguredModel)) return; + this.wire.dispatch(setMode({ mode })); if (changed) this._onDidChangeMode.fire({ mode, previousMode }); } - - setModeAndBroadcast(mode: PermissionMode): void { - const wasYolo = this.mode === 'yolo'; - const wasAuto = this.mode === 'auto'; - this.setMode(mode); - if (this.scopeContext.agentId === MAIN_AGENT_ID) { - this.agentLifecycle.broadcastPermissionMode(mode); - } - const yoloEnabled = this.mode === 'yolo'; - if (yoloEnabled !== wasYolo) { - this.telemetry.track2('yolo_toggle', { enabled: yoloEnabled }); - } - const afkEnabled = this.mode === 'auto'; - if (afkEnabled !== wasAuto) { - this.telemetry.track2('afk_toggle', { enabled: afkEnabled }); - } - } } registerScopedService( diff --git a/packages/agent-core-v2/src/agent/permissionPolicy/permissionPolicyService.ts b/packages/agent-core-v2/src/agent/permissionPolicy/permissionPolicyService.ts index bec50a293..c687fa19c 100644 --- a/packages/agent-core-v2/src/agent/permissionPolicy/permissionPolicyService.ts +++ b/packages/agent-core-v2/src/agent/permissionPolicy/permissionPolicyService.ts @@ -1,3 +1,12 @@ +/** + * `permissionPolicy` domain — `IAgentPermissionPolicyService` implementation. + * + * Runs the static, ordered permission chain: every node adjudicates the *risk* + * of a tool call (mode posture, user rules, session approval memory, sensitive + * paths, intrinsic tool risk, workspace write trust, fallback). Bound at + * Agent scope. + */ + import { IInstantiationService } from "#/_base/di/instantiation"; import { Service } from "#/_base/di/service"; import type { ResolvedToolExecutionHookContext } from '#/agent/toolExecutor/toolHooks'; diff --git a/packages/agent-core-v2/src/agent/permissionPolicy/policies/default-tool-approve.ts b/packages/agent-core-v2/src/agent/permissionPolicy/policies/default-tool-approve.ts index a2b79a22b..4867b0e00 100644 --- a/packages/agent-core-v2/src/agent/permissionPolicy/policies/default-tool-approve.ts +++ b/packages/agent-core-v2/src/agent/permissionPolicy/policies/default-tool-approve.ts @@ -13,7 +13,6 @@ const DEFAULT_APPROVE_TOOLS = new Set([ 'TodoList', 'TaskList', 'TaskOutput', - 'WaitFor', 'CronList', 'WebSearch', 'FetchURL', diff --git a/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-control-path-access-ask.ts b/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-control-path-access-ask.ts index c9df3bf7e..a2d8f132e 100644 --- a/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-control-path-access-ask.ts +++ b/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-control-path-access-ask.ts @@ -1,7 +1,8 @@ import type { ResolvedToolExecutionHookContext } from '#/agent/toolExecutor/toolHooks'; import { IGitService } from '#/app/git/git'; import type { IGitService as GitService } from '#/app/git/git'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import type { IHostEnvironment as HostEnvironment } from '#/os/interface/hostEnvironment'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import type { ISessionWorkspaceContext as WorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import type { @@ -18,7 +19,7 @@ export class GitControlPathAccessAskPermissionPolicyService implements Permissio readonly name = 'git-control-path-access-ask'; constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostEnvironment private readonly env: HostEnvironment, @ISessionWorkspaceContext private readonly workspace: WorkspaceContext, @IGitService private readonly git: GitService, ) {} @@ -28,9 +29,7 @@ export class GitControlPathAccessAskPermissionPolicyService implements Permissio ): Promise<PermissionPolicyResult | undefined> { const cwd = this.workspace.workDir; if (cwd.length === 0) return undefined; - const lease = this.runtime.acquire(); - const pathClass = lease.runtime.environment.pathClass; - lease.dispose(); + const pathClass = this.env.pathClass; const accesses = fileAccesses(context); if (accesses.length === 0) return undefined; diff --git a/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-cwd-write-approve.ts b/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-cwd-write-approve.ts index b48d71cf7..5b55977fb 100644 --- a/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-cwd-write-approve.ts +++ b/packages/agent-core-v2/src/agent/permissionPolicy/policies/git-cwd-write-approve.ts @@ -2,7 +2,8 @@ import type { ResolvedToolExecutionHookContext } from '#/agent/toolExecutor/tool import { isWithinWorkspace } from '#/tool/path-access'; import { IGitService } from '#/app/git/git'; import type { IGitService as GitService } from '#/app/git/git'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import type { IHostEnvironment as HostEnvironment } from '#/os/interface/hostEnvironment'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import type { ISessionWorkspaceContext as WorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import type { @@ -15,7 +16,7 @@ export class GitCwdWriteApprovePermissionPolicyService implements PermissionPoli readonly name = 'git-cwd-write-approve'; constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostEnvironment private readonly env: HostEnvironment, @ISessionWorkspaceContext private readonly workspace: WorkspaceContext, @IGitService private readonly git: GitService, ) {} @@ -25,10 +26,7 @@ export class GitCwdWriteApprovePermissionPolicyService implements PermissionPoli ): Promise<PermissionPolicyResult | undefined> { const toolName = context.toolCall.name; if (toolName !== 'Write' && toolName !== 'Edit') return undefined; - const lease = this.runtime.acquire(); - const pathClass = lease.runtime.environment.pathClass; - lease.dispose(); - if (pathClass !== 'posix') return undefined; + if (this.env.pathClass !== 'posix') return undefined; const cwd = this.workspace.workDir; if (cwd.length === 0) return undefined; diff --git a/packages/agent-core-v2/src/agent/permissionPolicy/types.ts b/packages/agent-core-v2/src/agent/permissionPolicy/types.ts index 57cdec848..07c8f5fdc 100644 --- a/packages/agent-core-v2/src/agent/permissionPolicy/types.ts +++ b/packages/agent-core-v2/src/agent/permissionPolicy/types.ts @@ -7,7 +7,6 @@ export type PermissionMode = 'manual' | 'yolo' | 'auto'; export interface ApprovalRequest { - id?: string; toolCallId: string; toolName: string; action: string; diff --git a/packages/agent-core-v2/src/agent/permissionRules/configSection.ts b/packages/agent-core-v2/src/agent/permissionRules/configSection.ts index 8598901b4..f842c9b3f 100644 --- a/packages/agent-core-v2/src/agent/permissionRules/configSection.ts +++ b/packages/agent-core-v2/src/agent/permissionRules/configSection.ts @@ -1,3 +1,15 @@ +/** + * `permissionRules` domain — `permission` config-section schema and TOML + * transforms. + * + * Owns the `[permission]` configuration section (the persisted permission + * rules), including the snake_case ↔ camelCase TOML transforms that reshape the + * on-disk `deny` / `allow` / `ask` lists and the `tool`/`match` shorthand into + * the in-memory `rules` array. Self-registered at module load via + * `registerConfigSection`, so the `config` domain never imports this domain's + * types. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/agent/permissionRules/permissionRulesOps.ts b/packages/agent-core-v2/src/agent/permissionRules/permissionRulesOps.ts index bf32582e7..2863c363e 100644 --- a/packages/agent-core-v2/src/agent/permissionRules/permissionRulesOps.ts +++ b/packages/agent-core-v2/src/agent/permissionRules/permissionRulesOps.ts @@ -1,8 +1,26 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `permissionRules` domain — wire Model (`PermissionRulesModel`) and the + * `permission.rules.add` (`addPermissionRules`) / `permission.record_approval_result` + * (`recordApprovalResult`) Ops for the agent's permission rules and session-scoped + * approval patterns. + * + * Declares the rules list and the deduped session-approval patterns as one wire + * Model (the full approval records are persisted as the log itself, not held as + * model state — only the derived `sessionApprovalRulePatterns` are), plus the two + * Ops whose `apply` functions are the pure extraction of the former live + * `applyAddRules` / `applyApprovalResult` and their `record.define(...resume...)` + * facets (their common transition). Each returns the same reference when nothing + * changes (empty rules / duplicate or non-session approval) so the wire's + * reference-equality gate stays quiet. `permission.rules.add` is live-only + * because v1 does not persist permission rules; hosts re-supply them on resume, + * while only `permission.record_approval_result` rides the wire log. The + * legacy `toReplay: approval_result` projection is dropped — only `message` + * records feed the transcript. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; import type { PermissionApprovalResultRecord, PermissionRule } from './permissionRules'; @@ -11,60 +29,45 @@ export interface PermissionRulesModelState { readonly sessionApprovalRulePatterns: readonly string[]; } -const permissionRulesAddSchema = z.object({ - agentId: z.string(), - rules: z.custom<readonly PermissionRule[]>(), +export const PermissionRulesModel = defineModel<PermissionRulesModelState>('permissionRules', () => ({ + rules: [], + sessionApprovalRulePatterns: [], +})); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'permission.record_approval_result': typeof recordApprovalResult; + } + + interface TransientOpMap { + 'permission.rules.add': typeof addPermissionRules; + } +} + +export const addPermissionRules = PermissionRulesModel.defineOp('permission.rules.add', { + schema: z.object({ rules: z.custom<readonly PermissionRule[]>() }), + persist: false, + apply: (s, p) => { + if (p.rules.length === 0) return s; + return { ...s, rules: [...s.rules, ...p.rules] }; + }, }); -export class PermissionRulesAdd extends AgentEvent2<z.infer<typeof permissionRulesAddSchema>> { - static override readonly type = 'permission.rules.add'; -} -export interface PermissionRulesAdd { - readonly agentId: string; - readonly rules: readonly PermissionRule[]; -} - -const permissionRecordApprovalResultSchema = z.object({ - agentId: z.string(), - turnId: z.number(), - toolCallId: z.string(), - toolName: z.string(), - action: z.string(), - sessionApprovalRule: z.string().optional(), - result: z.custom<PermissionApprovalResultRecord['result']>(), -}); - -export class PermissionRecordApprovalResult extends AgentEvent2< - z.infer<typeof permissionRecordApprovalResultSchema> -> { - static override readonly type = 'permission.record_approval_result'; - static override readonly durable = true; - static override readonly schema = permissionRecordApprovalResultSchema; -} -export interface PermissionRecordApprovalResult extends PermissionApprovalResultRecord { - readonly agentId: string; -} - -export const permissionRulesKey = defineState( - 'permissionRules', - (): PermissionRulesModelState => ({ - rules: [], - sessionApprovalRulePatterns: [], - }), -).replayable({ schema: z.custom<PermissionRulesModelState>() }) - .on(PermissionRulesAdd, (s, e) => { - if (e.rules.length === 0) return; - s.rules = [...s.rules, ...e.rules]; - }) - .on(PermissionRecordApprovalResult, (s, e) => { - const pattern = e.sessionApprovalRule; - if ( - e.result.decision !== 'approved' || - e.result.scope !== 'session' || - pattern === undefined || - s.sessionApprovalRulePatterns.includes(pattern) - ) { - return; - } - s.sessionApprovalRulePatterns = [...s.sessionApprovalRulePatterns, pattern]; - }); +export const recordApprovalResult = PermissionRulesModel.defineOp( + 'permission.record_approval_result', + { + schema: z.custom<PermissionApprovalResultRecord>(), + apply: (s, p) => { + const pattern = p.sessionApprovalRule; + if ( + p.result.decision !== 'approved' || + p.result.scope !== 'session' || + pattern === undefined || + s.sessionApprovalRulePatterns.includes(pattern) + ) { + return s; + } + return { ...s, sessionApprovalRulePatterns: [...s.sessionApprovalRulePatterns, pattern] }; + }, + }, +); diff --git a/packages/agent-core-v2/src/agent/permissionRules/permissionRulesService.ts b/packages/agent-core-v2/src/agent/permissionRules/permissionRulesService.ts index 046ed8c96..d60f18ffe 100644 --- a/packages/agent-core-v2/src/agent/permissionRules/permissionRulesService.ts +++ b/packages/agent-core-v2/src/agent/permissionRules/permissionRulesService.ts @@ -1,54 +1,49 @@ +/** + * `permissionRules` domain — `IAgentPermissionRulesService` implementation. + * + * Holds the agent's permission rules and deduped session-approval patterns in the + * `wire` `PermissionRulesModel`, mutating it only through the `permission.rules.add` + * / `permission.record_approval_result` Ops (`wire.dispatch(...)`) and reading it + * through `wire.getModel`. `wire.replay` rebuilds the model silently and + * consumers read the getters instead. Bound at Agent scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { IAgentPermissionRulesService, type PermissionApprovalResultRecord, type PermissionRule, } from './permissionRules'; import { - PermissionRecordApprovalResult, - PermissionRulesAdd, - permissionRulesKey, + addPermissionRules, + PermissionRulesModel, + recordApprovalResult as recordApprovalResultOp, } from './permissionRulesOps'; export class AgentPermissionRulesService implements IAgentPermissionRulesService { declare readonly _serviceBrand: undefined; - constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IAgentStateService private readonly agentState: IAgentStateService, - ) { - this.agentState.contributeState(permissionRulesKey); - } + constructor(@IWireService private readonly wire: IWireService) {} get rules(): readonly PermissionRule[] { - return [...this.agentState.get(permissionRulesKey).rules]; + return [...this.wire.getModel(PermissionRulesModel).rules]; } get sessionApprovalRulePatterns(): readonly string[] { - return [...this.agentState.get(permissionRulesKey).sessionApprovalRulePatterns]; + return [...this.wire.getModel(PermissionRulesModel).sessionApprovalRulePatterns]; } addRules(rules: readonly PermissionRule[]): void { if (rules.length === 0) return; - void this.dispatcher.dispatch( - new PermissionRulesAdd({ agentId: this.scopeContext.agentId, rules: [...rules] }), - ); + this.wire.dispatch(addPermissionRules({ rules: [...rules] })); } recordApprovalResult(record: PermissionApprovalResultRecord): void { - void this.dispatcher.dispatch( - new PermissionRecordApprovalResult({ - ...record, - agentId: this.scopeContext.agentId, - }), - ); + this.wire.dispatch(recordApprovalResultOp(record)); } } diff --git a/packages/agent-core-v2/src/agent/plugin/agentPlugin.ts b/packages/agent-core-v2/src/agent/plugin/agentPlugin.ts index a5a64de2a..512f1a565 100644 --- a/packages/agent-core-v2/src/agent/plugin/agentPlugin.ts +++ b/packages/agent-core-v2/src/agent/plugin/agentPlugin.ts @@ -1,9 +1,14 @@ +/** + * `agentPlugin` domain — Agent-scope plugin integration contract. + * + * Bridges App-scope plugin declarations into the main agent's runtime context. + * Bound at Agent scope and instantiated only for the main agent. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IAgentPluginService { readonly _serviceBrand: undefined; - - refreshSessionStart(): Promise<void>; } export const IAgentPluginService: ServiceIdentifier<IAgentPluginService> = diff --git a/packages/agent-core-v2/src/agent/plugin/agentPluginOps.ts b/packages/agent-core-v2/src/agent/plugin/agentPluginOps.ts deleted file mode 100644 index c689731b4..000000000 --- a/packages/agent-core-v2/src/agent/plugin/agentPluginOps.ts +++ /dev/null @@ -1,37 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -export interface PluginSessionStartSnapshotState { - readonly initialized: boolean; - readonly content?: string; -} - -const pluginSessionStartSchema = z.object({ - agentId: z.string(), - content: z.string().nullable(), -}); - -export class PluginSessionStartEvent extends AgentEvent2< - z.infer<typeof pluginSessionStartSchema> -> { - static override readonly type = 'plugin.session_start'; - static override readonly durable = true; - static override readonly schema = pluginSessionStartSchema; -} -export interface PluginSessionStartEvent { - readonly agentId: string; - readonly content: string | null; -} - -export const pluginSessionStartSnapshotKey = defineState( - 'pluginSessionStartSnapshot', - (): PluginSessionStartSnapshotState => ({ initialized: false }), -) - .replayable({ schema: z.custom<PluginSessionStartSnapshotState>() }) - .on(PluginSessionStartEvent, (_s, e) => ({ - initialized: true, - content: e.content ?? undefined, - })); diff --git a/packages/agent-core-v2/src/agent/plugin/agentPluginService.ts b/packages/agent-core-v2/src/agent/plugin/agentPluginService.ts index 23dfc16ab..bfc29c438 100644 --- a/packages/agent-core-v2/src/agent/plugin/agentPluginService.ts +++ b/packages/agent-core-v2/src/agent/plugin/agentPluginService.ts @@ -1,30 +1,40 @@ +/** + * `agentPlugin` domain — `IAgentPluginService` implementation. + * + * Renders session-start skills from `plugin` and `sessionSkillCatalog`, injects + * them through `contextInjector` and `systemReminder`, and uses `contextMemory` + * to neutralize stale guidance. The session-start refresh on plugin-source + * catalog changes fires only for an explicit plugin reload: a mutation-driven + * reload (install / enable / disable / remove) skips it — the live session + * keeps the guidance it started with — and instead appends a `plugin_change` + * system reminder through `systemReminder` (`plugin` `onDidMutate` — never on + * an explicit reload, whose resumed session would otherwise inherit a stale + * notice), naming the mutated plugin and telling the model the live session + * keeps its original prompt and tool set until `/new` or `/reload`. + * Main-agent-only (v1 parity): the service + * self-gates on `agentId === 'main'`; Agent scope creation instantiates it for + * every agent, so other agents construct it as a no-op. Resolves + * session prompt context through `sessionContext` and reports missing skills + * through `log`. Bound at Agent scope. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; import { escapeXmlAttr } from '#/_base/utils/xml-escape'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { AgentReminder, type ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import type { ContextInjectionContext } from '#/features/reminder/types'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { systemReminderContent } from '#/features/reminder/systemReminder'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; import { IPluginService } from '#/app/plugin/plugin'; import type { EnabledPluginSessionStart, PluginMutation } from '#/app/plugin/types'; -import { PLUGIN_SKILL_SOURCE_ID } from '#/features/skill/catalog/skillSource'; -import type { SkillCatalog, SkillDefinition } from '#/features/skill/catalog/types'; +import { PLUGIN_SKILL_SOURCE_ID } from '#/app/skillCatalog/skillSource'; +import type { SkillCatalog, SkillDefinition } from '#/app/skillCatalog/types'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { IAgentPluginService } from './agentPlugin'; -import { - PluginSessionStartEvent, - pluginSessionStartSnapshotKey, -} from './agentPluginOps'; const SESSION_START_INJECTION_VARIANT = 'plugin_session_start'; @@ -48,84 +58,63 @@ function renderPluginChangeReminder(mutation: PluginMutation): string { const MAIN_AGENT_ID = 'main'; -const SUPERSEDES_SUFFIX = - 'This supersedes any earlier plugin_session_start reminder in this session.'; - -const NO_ACTIVE_SESSION_STARTS = - `There are currently no active plugin session starts. ${SUPERSEDES_SUFFIX}`; - -export const pluginSessionStartRefreshPendingKey = defineState<boolean>( - 'agentPlugin.sessionStartRefreshPending', - () => false, -); - export class AgentPluginService extends Service implements IAgentPluginService { declare readonly _serviceBrand: undefined; - private readonly warnedMissingSessionStartSkills = new Set<string>(); + // Count of mutation-driven plugin reloads whose catalog change has not + // reached this agent yet. `reloadAndNotify` fires `onDidMutate` + // synchronously within every mutation's `onDidReload`, while the catalog + // re-scan completes asynchronously, so the count is always positive by the + // time a mutation-driven catalog change arrives. private pendingMutationCatalogChanges = 0; constructor( - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentScopeContext scopeContext: IAgentScopeContext, + @IAgentContextInjectorService injector: IAgentContextInjectorService, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IPluginService private readonly plugins: IPluginService, @ISessionSkillCatalog private readonly skillCatalog: ISessionSkillCatalog, @ISessionContext private readonly sessionContext: ISessionContext, @ILogService private readonly log: ILogService, - @IAgentStateService private readonly states: IAgentStateService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, ) { super(); - this.states.contributeState(pluginSessionStartSnapshotKey); if (scopeContext.agentId !== MAIN_AGENT_ID) return; - this.states.contributeState(pluginSessionStartRefreshPendingKey); this._register( - activateReminderWhenReady(this.agentLifecycle, this.scopeContext, (reminder) => - reminder.register(SESSION_START_INJECTION_VARIANT, (injection) => - this.reconcileSessionStartReminder(injection), - ), + injector.register( + SESSION_START_INJECTION_VARIANT, + async ({ injectedPositions }) => { + if (injectedPositions.length > 0) return undefined; + return this.renderSessionStartReminder(); + }, ), ); this._register( this.skillCatalog.onDidChange((sourceId) => { if (sourceId !== PLUGIN_SKILL_SOURCE_ID) return; if (this.pendingMutationCatalogChanges > 0) { + // Mutation-driven reload: the live session keeps the session-start + // guidance it started with — the plugin_change reminder is the only + // notice it gets. A failed mutation reload produces no catalog + // change, so a later explicit-reload refresh may be skipped once; + // that only keeps the frozen guidance longer, which is safe. this.pendingMutationCatalogChanges--; return; } - this.refreshPending = true; + void this.appendFreshSessionStartReminder(); }), ); this._register( this.plugins.onDidMutate(({ mutation }) => { this.pendingMutationCatalogChanges++; - this.reminder().notify(renderPluginChangeReminder(mutation), { + this.reminders.appendSystemReminder(renderPluginChangeReminder(mutation), { + kind: 'injection', variant: PLUGIN_CHANGE_INJECTION_VARIANT, }); }), ); } - private reminder(): ReminderRuntime { - return this.agentLifecycle.resolve(this.scopeContext.agentContext, AgentReminder); - } - - private get refreshPending(): boolean { - return this.states.get(pluginSessionStartRefreshPendingKey); - } - - private set refreshPending(value: boolean) { - this.states.set(pluginSessionStartRefreshPendingKey, value); - } - - async refreshSessionStart(): Promise<void> { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) return; - this.refreshPending = true; - await this.skillCatalog.ready; - await this.reminder().reconcileWhenIdle(SESSION_START_INJECTION_VARIANT); - } - private async renderSessionStartReminder(): Promise<string | undefined> { const sessionStarts = await this.plugins.enabledSessionStarts(); if (sessionStarts.length === 0) return undefined; @@ -135,73 +124,24 @@ export class AgentPluginService extends Service implements IAgentPluginService { catalog: this.skillCatalog.catalog, log: this.log, sessionId: this.sessionContext.sessionId, - warnedSkills: this.warnedMissingSessionStartSkills, }); } - private async reconcileSessionStartReminder( - injection: ContextInjectionContext, - ): Promise<string | undefined> { - const forceRefresh = this.refreshPending; - const desired = await this.resolveDesiredSessionStart(injection, forceRefresh); - this.refreshPending = false; - const latest = injection.lastInjection; - if (desired === undefined) { - if ( - latest === undefined && - (!forceRefresh || !shouldNeutralizePluginSessionStart(this.context.get())) - ) { - return undefined; - } - if (latest !== undefined && systemReminderContent(latest) === NO_ACTIVE_SESSION_STARTS) { - return undefined; - } - return NO_ACTIVE_SESSION_STARTS; + async appendFreshSessionStartReminder(): Promise<void> { + const reminder = await this.renderSessionStartReminder(); + if (reminder !== undefined) { + this.reminders.appendSystemReminder( + `${reminder}\n\nThis supersedes any earlier plugin_session_start reminder in this session.`, + { kind: 'injection', variant: SESSION_START_INJECTION_VARIANT }, + ); + } else if (shouldNeutralizePluginSessionStart(this.context.get())) { + this.reminders.appendSystemReminder( + 'There are currently no active plugin session starts. ' + + 'This supersedes any earlier plugin_session_start reminder in this session.', + { kind: 'injection', variant: SESSION_START_INJECTION_VARIANT }, + ); } - if (latest === undefined) return desired; - const rendered = systemReminderContent(latest); - if ( - !forceRefresh && - (rendered === desired.trim() || rendered === `${desired}\n\n${SUPERSEDES_SUFFIX}`.trim()) - ) { - return undefined; - } - return `${desired}\n\n${SUPERSEDES_SUFFIX}`; } - - private async resolveDesiredSessionStart( - injection: ContextInjectionContext, - forceRefresh: boolean, - ): Promise<string | undefined> { - const snapshot = this.states.get(pluginSessionStartSnapshotKey); - if (!forceRefresh && snapshot.initialized) return snapshot.content; - if (!forceRefresh && injection.lastInjection !== undefined) { - const rendered = systemReminderContent(injection.lastInjection); - if (rendered !== undefined) { - const content = frozenSessionStartContent(rendered); - this.recordSessionStartSnapshot(content); - return content; - } - } - const content = await this.renderSessionStartReminder(); - this.recordSessionStartSnapshot(content); - return content; - } - - private recordSessionStartSnapshot(content: string | undefined): void { - void this.dispatcher.dispatch( - new PluginSessionStartEvent({ - agentId: this.scopeContext.agentId, - content: content ?? null, - }), - ); - } -} - -function frozenSessionStartContent(rendered: string): string | undefined { - if (rendered === NO_ACTIVE_SESSION_STARTS) return undefined; - const suffix = `\n\n${SUPERSEDES_SUFFIX}`; - return rendered.endsWith(suffix) ? rendered.slice(0, -suffix.length) : rendered; } interface RenderPluginSessionStartReminderInput { @@ -209,27 +149,22 @@ interface RenderPluginSessionStartReminderInput { readonly catalog: SkillCatalog | undefined; readonly log?: { warn(message: string, payload?: unknown): void }; readonly sessionId?: string; - readonly warnedSkills: Set<string>; } function renderPluginSessionStartReminder( input: RenderPluginSessionStartReminderInput, ): string | undefined { - const { sessionStarts, catalog, log, sessionId, warnedSkills } = input; + const { sessionStarts, catalog, log, sessionId } = input; if (sessionStarts.length === 0) return undefined; if (catalog === undefined) return undefined; const blocks: string[] = []; for (const sessionStart of sessionStarts) { const skill = catalog.getPluginSkill(sessionStart.pluginId, sessionStart.skillName); if (skill === undefined) { - const key = `${sessionStart.pluginId}:${sessionStart.skillName}`; - if (!warnedSkills.has(key)) { - warnedSkills.add(key); - log?.warn('plugin sessionStart skill not found', { - pluginId: sessionStart.pluginId, - skillName: sessionStart.skillName, - }); - } + log?.warn('plugin sessionStart skill not found', { + pluginId: sessionStart.pluginId, + skillName: sessionStart.skillName, + }); continue; } blocks.push( diff --git a/packages/agent-core-v2/src/agent/pluginCommand/pluginCommand.ts b/packages/agent-core-v2/src/agent/pluginCommand/pluginCommand.ts deleted file mode 100644 index 486cca667..000000000 --- a/packages/agent-core-v2/src/agent/pluginCommand/pluginCommand.ts +++ /dev/null @@ -1,33 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { AgentEvent2 } from '#/app/event/event2'; - -export interface ActivatePluginCommandPayload { - readonly pluginId: string; - readonly commandName: string; - readonly args?: string | undefined; -} - -export interface PluginCommandActivatedPayload { - readonly agentId: string; - readonly activationId: string; - readonly pluginId: string; - readonly commandName: string; - readonly commandArgs?: string; - readonly trigger: 'user-slash'; -} - -export class PluginCommandActivated extends AgentEvent2<PluginCommandActivatedPayload> { - static override readonly type = 'plugin_command.activated'; - static override readonly observable = true; -} -export interface PluginCommandActivated extends PluginCommandActivatedPayload {} - -export interface IAgentPluginCommandService { - readonly _serviceBrand: undefined; - - activate(payload: ActivatePluginCommandPayload): Promise<void>; -} - -export const IAgentPluginCommandService: ServiceIdentifier<IAgentPluginCommandService> = - createDecorator<IAgentPluginCommandService>('agentPluginCommandService'); diff --git a/packages/agent-core-v2/src/agent/pluginCommand/pluginCommandService.ts b/packages/agent-core-v2/src/agent/pluginCommand/pluginCommandService.ts deleted file mode 100644 index bae8680f8..000000000 --- a/packages/agent-core-v2/src/agent/pluginCommand/pluginCommandService.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { randomUUID } from 'node:crypto'; - -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IEventService } from '#/app/event/event'; -import { ErrorCodes, Error2 } from '#/errors'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { expandCommandArguments } from '#/app/plugin/commands'; -import { IPluginService } from '#/app/plugin/plugin'; -import { IAgentPromptService } from '#/agent/prompt/prompt'; -import { promptMetadataTextFromText } from '#/agent/prompt/promptMetadataText'; -import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { applyPromptMetadataUpdate } from '#/session/sessionMetadata/promptMetadata'; -import { IEventDispatcher } from '#/state/eventDispatcher'; - -import { - IAgentPluginCommandService, - PluginCommandActivated, - type ActivatePluginCommandPayload, -} from './pluginCommand'; - -export class AgentPluginCommandService implements IAgentPluginCommandService { - declare readonly _serviceBrand: undefined; - - constructor( - @IPluginService private readonly plugins: IPluginService, - @IAgentPromptService private readonly promptService: IAgentPromptService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @ISessionMetadata private readonly metadata: ISessionMetadata, - @IEventService private readonly eventService: IEventService, - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) { } - - async activate(payload: ActivatePluginCommandPayload): Promise<void> { - const commands = await this.plugins.listPluginCommands(); - const def = commands.find( - (command) => command.pluginId === payload.pluginId && command.name === payload.commandName, - ); - if (def === undefined) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `Plugin command "${payload.pluginId}:${payload.commandName}" was not found`, - ); - } - const commandArgs = payload.args ?? ''; - const expanded = expandCommandArguments(def.body, commandArgs); - const origin = { - kind: 'plugin_command' as const, - activationId: randomUUID(), - pluginId: payload.pluginId, - commandName: payload.commandName, - commandArgs: payload.args, - trigger: 'user-slash' as const, - }; - await this.dispatcher.dispatch( - new PluginCommandActivated({ - agentId: this.scopeContext.agentId, - activationId: origin.activationId, - pluginId: origin.pluginId, - commandName: origin.commandName, - commandArgs: origin.commandArgs, - trigger: origin.trigger, - }), - ); - await this.promptService.enqueue({ message: { - role: 'user', - content: [{ type: 'text', text: expanded }], - toolCalls: [], - origin, - } }); - if (this.scopeContext.agentId === MAIN_AGENT_ID) { - await applyPromptMetadataUpdate( - { - metadata: this.metadata, - eventService: this.eventService, - sessionId: this.sessionContext.sessionId, - }, - promptMetadataTextFromPluginCommand(payload), - ); - } - } -} - -function promptMetadataTextFromPluginCommand( - payload: ActivatePluginCommandPayload, -): string | undefined { - const args = payload.args?.trim(); - const command = `/${payload.pluginId}:${payload.commandName}`; - return promptMetadataTextFromText( - args === undefined || args.length === 0 ? command : `${command} ${args}`, - ); -} - -registerScopedService( - LifecycleScope.Agent, - IAgentPluginCommandService, - AgentPluginCommandService, - ScopeActivation.OnScopeCreated, - 'pluginCommand', -); diff --git a/packages/agent-core-v2/src/agent/profile/context.ts b/packages/agent-core-v2/src/agent/profile/context.ts index f6455f9f0..d649c56da 100644 --- a/packages/agent-core-v2/src/agent/profile/context.ts +++ b/packages/agent-core-v2/src/agent/profile/context.ts @@ -1,3 +1,31 @@ +/** + * `profile` domain — system-prompt context assembly. + * + * Loads the AGENTS.md instruction hierarchy (user-level brand + generic files, + * then project-level files from the project root down to the cwd — the root + * discovered through a git work-tree probe) and assembles + * the {@link SystemPromptContext} bag. + * `agentsMdWatchRoots` exposes the watch plan for the probed file set, and + * `prepareSystemPromptContext` accepts a `preloadedAgentsMd` snapshot so the + * caller can inject an already-read snapshot instead of re-reading the files. + * + * Runs on top of the os `IHostFileSystem` (for `readText` / `stat` / `readdir`) + * plus the host's `homeDir` — supplied together as a small `ProfileContextDeps` + * bag threaded through the helpers. + * + * The combined AGENTS.md content is injected in full; when it exceeds the + * soft {@link AGENTS_MD_RECOMMENDED_MAX_BYTES} budget a visible + * `agentsMdWarning` is produced instead of silently truncating. + * + * The discovered-file list is returned alongside the content as `paths` + * (surfaced as `agentsMdPaths`), and the per-directory candidate rules + * (`AGENTS_MD_PLAIN_NAMES` / `dotKimiAgentsMdPath` / `findAgentsMdInDir`) + * plus the root→leaf chain helpers (`findProjectRoot` / `dirsRootToLeaf`) + * are exported so discovery probes and injection never drift apart. Legacy + * restored prompts can recover their exact injected paths from the same + * rendered source annotations. + */ + import { basename, dirname, join, normalize } from 'pathe'; import { findGitWorkTree } from '#/app/git/workTree'; @@ -344,6 +372,7 @@ function dedupeDirs(dirs: readonly string[]): string[] { return result; } + interface ListDirectoryOptions { readonly collapseHiddenDirs?: boolean; } diff --git a/packages/agent-core-v2/src/agent/profile/errors.ts b/packages/agent-core-v2/src/agent/profile/errors.ts index 0f84b876f..2fd364a23 100644 --- a/packages/agent-core-v2/src/agent/profile/errors.ts +++ b/packages/agent-core-v2/src/agent/profile/errors.ts @@ -1,3 +1,7 @@ +/** + * `profile` domain error codes — model/provider configuration failures. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const ProfileErrors = { diff --git a/packages/agent-core-v2/src/agent/profile/profile.ts b/packages/agent-core-v2/src/agent/profile/profile.ts index 1fdbbc24f..88a45e18f 100644 --- a/packages/agent-core-v2/src/agent/profile/profile.ts +++ b/packages/agent-core-v2/src/agent/profile/profile.ts @@ -1,3 +1,20 @@ +/** + * `profile` domain — `IAgentProfileService` contract. + * + * Owns the active agent's identity: bound profile, model alias, thinking + * level, system prompt, and active-tool set. `bind()` takes an optional + * `model`, falling back to the configured `defaultModel` so edges don't each + * re-implement the fallback (a missing model everywhere throws + * `model.not_configured`), and an optional `thinking`; `strictThinking` marks + * `thinking` as an explicit user request (edge input) rather than inherited + * state, so the effort is validated against the model's supported efforts and + * the bind rejects up front when unsupported — internal spawns pass inherited + * thinking without the flag, and a persisted effort that drifted out of the + * model's support list clamps instead of breaking the spawn. The profile + * contract also owns live status re-publication for consumers that attach to + * an agent after its initial model binding. + */ + import type { AgentProfile, AgentProfileContext, @@ -122,6 +139,7 @@ export interface IAgentProfileService { getModel(): string; useProfile(profile: ResolvedAgentProfile, context: SystemPromptContext): void; applyProfile(profile: ResolvedAgentProfile, options?: ApplyProfileOptions): Promise<void>; + refreshSystemPrompt(): Promise<void>; getAgentsMdWarning(): string | undefined; data(): ProfileData; getEffectiveThinkingLevel(): ThinkingEffort; diff --git a/packages/agent-core-v2/src/agent/profile/profileOps.ts b/packages/agent-core-v2/src/agent/profile/profileOps.ts index a03f90c33..78a91d1fe 100644 --- a/packages/agent-core-v2/src/agent/profile/profileOps.ts +++ b/packages/agent-core-v2/src/agent/profile/profileOps.ts @@ -1,11 +1,54 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { nothing, original } from 'immer'; +/** + * `profile` domain — wire Model (`ProfileModel`) and the `config.update` + * Op (`configUpdate`) for the agent's persistent configuration slice. + * + * Declares the persistent profile config — `modelAlias`, `profileName`, + * the resolved base thinking effort, `systemPrompt`, its injected AGENTS.md + * path provenance, the profile `disallowedTools` denylist and `subagents` + * delegation allowlist, and the environment disclosure snapshot associated + * with the rendered prompt — as a wire Model (initial `defaultProfileModel()`), + * plus the single Op whose `apply` is a pure merge of an already-resolved + * payload. `renderGeneration` advances on accepted system-prompt writes; on + * the live path an Op's `apply` is the only place that increments it (render + * callers omit it). The optional payload field is deprecated for new writes: + * legacy `config.update` records and live `profile.bind` snapshot/fork + * transfers may carry an explicit value, and `apply` then honors the recorded + * value verbatim so a replay or resumed binding rebuilds the exact generation + * the record was written with. Live records carry + * `thinkingEffort` (matching the v1 wire field); legacy replay still accepts + * `thinkingLevel`. The value is + * resolved to a `ThinkingEffort` at the call site and carried in the + * payload, so `apply` stays + * pure and a resumed agent restores the persisted base value rather than + * re-resolving against a possibly-drifted config. Runtime-only Kimi env + * forcing is intentionally kept out of this Model so the Kimi-only value + * cannot leak through model switches or agent forks. + * `modelCapabilities` is intentionally NOT in the Model — it is + * derived live at runtime so resume never pins stale capabilities. + * Each `apply` returns the same reference when nothing changes so the wire's + * reference-equality gate stays quiet. The `agent.status.updated` emission is + * NOT part of `apply`: it runs after + * `wire.dispatch` on the live path only, so `wire.replay` rebuilds the Model + * silently. The agent's working directory is deliberately NOT part of the + * binding: it is always the session's frozen cwd, read from `sessionContext` + * at render time rather than persisted here. Legacy `profile.bind` records + * that still carry a `cwd` field replay fine — the schema strips it. + * + * Also declares `ActiveToolsModel` (`readonly string[] | undefined`, initial + * `undefined` = every tool active), the `tools.set_active_tools` whole-set + * replace, and the v2-only `tools.reset_active_tools` transition back to the + * unrestricted default. Both persisted transitions replay the base set. The + * ephemeral per-tool + * `addActiveTool` / `removeActiveTool` deltas are NOT Ops — they are + * intentionally not persisted and are re-derived on resume. + */ + import { z } from 'zod'; import type { EnvironmentDisclosureSnapshot } from '#/app/agentProfileCatalog/agentProfileCatalog'; -import { AgentEvent2 } from '#/app/event/event2'; import type { ThinkingEffort } from '#/kosong/contract/provider'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; +import type { PayloadOf } from '#/wire/types'; import { ProfileError, ProfileErrors } from './profile'; @@ -21,162 +64,90 @@ export interface ProfileModelState { readonly subagents?: readonly string[]; } -const profileBindSchema = z.object({ - agentId: z.string(), - modelAlias: z.string().optional(), - profileName: z.string().optional(), - thinkingEffort: z.custom<ThinkingEffort>(), - systemPrompt: z.string(), - environmentDisclosure: z.custom<EnvironmentDisclosureSnapshot>().optional(), - renderGeneration: z.number().optional(), - agentsMdPaths: z.array(z.string()).readonly().optional(), - activeToolNames: z.array(z.string()).readonly().optional(), - disallowedTools: z.array(z.string()).readonly(), - subagents: z.array(z.string()).readonly().optional(), -}); +export const ProfileModel = defineModel<ProfileModelState>('profile', () => ({ + thinkingLevel: 'off', + systemPrompt: '', + renderGeneration: 0, +})); -export class ProfileBind extends AgentEvent2<z.infer<typeof profileBindSchema>> { - static override readonly type = 'profile.bind'; - static override readonly durable = true; - static override readonly schema = profileBindSchema; -} -export interface ProfileBind { - readonly agentId: string; - readonly modelAlias?: string; - readonly profileName?: string; - readonly thinkingEffort: ThinkingEffort; - readonly systemPrompt: string; - readonly environmentDisclosure?: EnvironmentDisclosureSnapshot; - readonly renderGeneration?: number; - readonly agentsMdPaths?: readonly string[]; - readonly activeToolNames?: readonly string[]; - readonly disallowedTools: readonly string[]; - readonly subagents?: readonly string[]; -} - -const configUpdateSchema = z.object({ - agentId: z.string(), - modelAlias: z.string().optional(), - profileName: z.string().optional(), - thinkingEffort: z.custom<ThinkingEffort>().optional(), - thinkingLevel: z.custom<ThinkingEffort>().optional(), - systemPrompt: z.string().optional(), - environmentDisclosure: z.custom<EnvironmentDisclosureSnapshot>().optional(), - renderGeneration: z.number().optional(), - agentsMdPaths: z.array(z.string()).readonly().optional(), - disallowedTools: z.array(z.string()).readonly().optional(), -}); - -export type ConfigUpdatePayload = z.infer<typeof configUpdateSchema>; - -export class ConfigUpdate extends AgentEvent2<ConfigUpdatePayload> { - static override readonly type = 'config.update'; - static override readonly durable = true; - static override readonly schema = configUpdateSchema; -} -export interface ConfigUpdate { - readonly agentId: string; - readonly modelAlias?: string; - readonly profileName?: string; - readonly thinkingEffort?: ThinkingEffort; - readonly thinkingLevel?: ThinkingEffort; - readonly systemPrompt?: string; - readonly environmentDisclosure?: EnvironmentDisclosureSnapshot; - readonly renderGeneration?: number; - readonly agentsMdPaths?: readonly string[]; - readonly disallowedTools?: readonly string[]; -} - -const toolsSetActiveToolsSchema = z.object({ - agentId: z.string(), - names: z.array(z.string()).readonly(), -}); - -export class ToolsSetActiveTools extends AgentEvent2<z.infer<typeof toolsSetActiveToolsSchema>> { - static override readonly type = 'tools.set_active_tools'; - static override readonly durable = true; - static override readonly schema = toolsSetActiveToolsSchema; -} -export interface ToolsSetActiveTools { - readonly agentId: string; - readonly names: readonly string[]; -} - -const toolsResetActiveToolsSchema = z.object({ agentId: z.string() }); - -export class ToolsResetActiveTools extends AgentEvent2< - z.infer<typeof toolsResetActiveToolsSchema> -> { - static override readonly type = 'tools.reset_active_tools'; - static override readonly durable = true; - static override readonly schema = toolsResetActiveToolsSchema; -} -export interface ToolsResetActiveTools { - readonly agentId: string; -} - -export interface WarningIssuedPayload { - readonly agentId: string; - readonly message: string; - readonly code?: string; -} - -export class WarningIssued extends AgentEvent2<WarningIssuedPayload> { - static override readonly type = 'warning'; - static override readonly observable = true; -} -export interface WarningIssued extends WarningIssuedPayload {} - -export const profileKey = defineState( - 'profile', - (): ProfileModelState => ({ - thinkingLevel: 'off', - systemPrompt: '', - renderGeneration: 0, +export const profileBind = ProfileModel.defineOp('profile.bind', { + schema: z.object({ + modelAlias: z.string().optional(), + profileName: z.string().optional(), + thinkingEffort: z.custom<ThinkingEffort>(), + systemPrompt: z.string(), + environmentDisclosure: z.custom<EnvironmentDisclosureSnapshot>().optional(), + renderGeneration: z.number().optional(), + agentsMdPaths: z.array(z.string()).readonly().optional(), + activeToolNames: z.array(z.string()).readonly().optional(), + disallowedTools: z.array(z.string()).readonly(), + subagents: z.array(z.string()).readonly().optional(), }), -).replayable({ schema: z.custom<ProfileModelState>() }) - .on(ProfileBind, (s, e) => ({ - modelAlias: e.modelAlias ?? s.modelAlias, - profileName: e.profileName ?? s.profileName, - thinkingLevel: e.thinkingEffort, - systemPrompt: e.systemPrompt, - environmentDisclosure: e.environmentDisclosure, - renderGeneration: e.renderGeneration ?? s.renderGeneration + 1, - agentsMdPaths: e.agentsMdPaths ?? s.agentsMdPaths, - disallowedTools: e.disallowedTools, - subagents: e.subagents, - })) - .on(ConfigUpdate, (s, e) => { - if (e.modelAlias !== undefined && e.modelAlias !== s.modelAlias) { - s.modelAlias = e.modelAlias; + apply: (s, p) => ({ + modelAlias: p.modelAlias ?? s.modelAlias, + profileName: p.profileName ?? s.profileName, + thinkingLevel: p.thinkingEffort, + systemPrompt: p.systemPrompt, + environmentDisclosure: p.environmentDisclosure, + renderGeneration: p.renderGeneration ?? s.renderGeneration + 1, + agentsMdPaths: p.agentsMdPaths ?? s.agentsMdPaths, + disallowedTools: p.disallowedTools, + subagents: p.subagents, + }), +}); + +export const configUpdate = ProfileModel.defineOp('config.update', { + schema: z.object({ + modelAlias: z.string().optional(), + profileName: z.string().optional(), + thinkingEffort: z.custom<ThinkingEffort>().optional(), + thinkingLevel: z.custom<ThinkingEffort>().optional(), + systemPrompt: z.string().optional(), + environmentDisclosure: z.custom<EnvironmentDisclosureSnapshot>().optional(), + renderGeneration: z.number().optional(), + agentsMdPaths: z.array(z.string()).readonly().optional(), + disallowedTools: z.array(z.string()).readonly().optional(), + }), + apply: (s, p) => { + let next: ProfileModelState | undefined; + if (p.modelAlias !== undefined && p.modelAlias !== s.modelAlias) { + next = { ...(next ?? s), modelAlias: p.modelAlias }; } - if (e.profileName !== undefined && e.profileName !== s.profileName) { - s.profileName = e.profileName; + if (p.profileName !== undefined && p.profileName !== s.profileName) { + next = { ...(next ?? s), profileName: p.profileName }; } - const thinkingLevel = configUpdateThinkingLevel(e); + const thinkingLevel = configUpdateThinkingLevel(p); if (thinkingLevel !== undefined && thinkingLevel !== s.thinkingLevel) { - s.thinkingLevel = thinkingLevel; + next = { ...(next ?? s), thinkingLevel }; } if ( - e.systemPrompt !== undefined && - (e.systemPrompt !== s.systemPrompt || - e.environmentDisclosure !== undefined || - e.renderGeneration !== undefined) + p.systemPrompt !== undefined && + (p.systemPrompt !== s.systemPrompt || + p.environmentDisclosure !== undefined || + p.renderGeneration !== undefined) ) { - s.systemPrompt = e.systemPrompt; - s.environmentDisclosure = e.environmentDisclosure; - s.renderGeneration = e.renderGeneration ?? s.renderGeneration + 1; - } - if (e.agentsMdPaths !== undefined && !stringArrayEqual(e.agentsMdPaths, s.agentsMdPaths)) { - s.agentsMdPaths = e.agentsMdPaths as string[]; + next = { + ...(next ?? s), + systemPrompt: p.systemPrompt, + environmentDisclosure: p.environmentDisclosure, + renderGeneration: p.renderGeneration ?? s.renderGeneration + 1, + }; } if ( - e.disallowedTools !== undefined && - !stringArrayEqual(e.disallowedTools, s.disallowedTools) + p.agentsMdPaths !== undefined && + !stringArrayEqual(p.agentsMdPaths, s.agentsMdPaths) ) { - s.disallowedTools = e.disallowedTools as string[]; + next = { ...(next ?? s), agentsMdPaths: p.agentsMdPaths }; } - }); + if ( + p.disallowedTools !== undefined && + !stringArrayEqual(p.disallowedTools, s.disallowedTools) + ) { + next = { ...(next ?? s), disallowedTools: p.disallowedTools }; + } + return next ?? s; + }, +}); function stringArrayEqual( a: readonly string[] | undefined, @@ -187,41 +158,50 @@ function stringArrayEqual( return a.length === b.length && a.every((value, index) => value === b[index]); } -function configUpdateThinkingLevel(e: ConfigUpdatePayload): ThinkingEffort | undefined { - if (e.thinkingEffort !== undefined && e.thinkingLevel !== undefined) { - if (e.thinkingEffort !== e.thinkingLevel) { +function configUpdateThinkingLevel( + p: PayloadOf<typeof configUpdate>, +): ThinkingEffort | undefined { + if (p.thinkingEffort !== undefined && p.thinkingLevel !== undefined) { + if (p.thinkingEffort !== p.thinkingLevel) { throw new ProfileError( ProfileErrors.codes.THINKING_ALIAS_CONFLICT, - `config.update has conflicting thinkingEffort (${e.thinkingEffort}) and legacy thinkingLevel (${e.thinkingLevel})`, + `config.update has conflicting thinkingEffort (${p.thinkingEffort}) and legacy thinkingLevel (${p.thinkingLevel})`, { type: 'config.update', - thinkingEffort: e.thinkingEffort, - thinkingLevel: e.thinkingLevel, + thinkingEffort: p.thinkingEffort, + thinkingLevel: p.thinkingLevel, }, ); } - return e.thinkingEffort; + return p.thinkingEffort; } - if (e.thinkingEffort !== undefined) return e.thinkingEffort; - return e.thinkingLevel; + if (p.thinkingEffort !== undefined) return p.thinkingEffort; + return p.thinkingLevel; } export type ActiveToolsState = readonly string[] | undefined; -export const profileActiveToolsKey = defineState( +export const ActiveToolsModel = defineModel<ActiveToolsState>( 'profile.activeTools', - (): ActiveToolsState => undefined, -).replayable({ schema: z.custom<ActiveToolsState>() }) - .on(ToolsSetActiveTools, (s, e) => { - if (s !== undefined && e.names === original(s)) return; - return e.names; - }) - .on(ToolsResetActiveTools, (s) => { - if (s === undefined) return; - return nothing as unknown as ActiveToolsState; - }) - .on(ProfileBind, (s, e) => - e.activeToolNames === undefined && s !== undefined - ? (nothing as unknown as ActiveToolsState) - : e.activeToolNames, - ); + () => undefined, + { reducers: { 'profile.bind': (_state, payload) => payload.activeToolNames } }, +); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'profile.bind': typeof profileBind; + 'config.update': typeof configUpdate; + 'tools.set_active_tools': typeof setActiveTools; + 'tools.reset_active_tools': typeof resetActiveTools; + } +} + +export const setActiveTools = ActiveToolsModel.defineOp('tools.set_active_tools', { + schema: z.object({ names: z.array(z.string()).readonly() }), + apply: (s, p) => (p.names === s ? s : p.names), +}); + +export const resetActiveTools = ActiveToolsModel.defineOp('tools.reset_active_tools', { + schema: z.object({}), + apply: (s) => (s === undefined ? s : undefined), +}); diff --git a/packages/agent-core-v2/src/agent/profile/profileService.ts b/packages/agent-core-v2/src/agent/profile/profileService.ts index 67e1d8c87..5642e036e 100644 --- a/packages/agent-core-v2/src/agent/profile/profileService.ts +++ b/packages/agent-core-v2/src/agent/profile/profileService.ts @@ -1,7 +1,95 @@ +/** + * `profile` domain — `IAgentProfileService` implementation. + * + * Owns the active agent's model alias, thinking level, system prompt, and + * active-tool set; reads the bound model's pure data through the App-scope + * `IModelCatalog` and produces the dialect-free per-turn intent + * (`resolveRequestParams`: cache key / sampling / thinking effort+keep — + * wire encoding is each dialect's own hook), persists the profile binding + * (`cwd` / `modelAlias` / `profileName` / resolved base `thinkingLevel` / + * `systemPrompt` / injected AGENTS.md paths / `activeToolNames` / profile + * `disallowedTools` / profile `subagents`) in the `wire` `ProfileModel` through + * the `profile.bind` Op + * (later slice updates ride the `config.update` Op) and the persisted + * active-tool set in the `wire` `ActiveToolsModel` through the + * `tools.set_active_tools` / `tools.reset_active_tools` Ops (`wire.dispatch`), + * and reads both through + * `wire.getModel`. The effective active-tool set read by consumers is the + * persisted base (`ActiveToolsModel`, rebuilt by `wire.replay`) overlaid with + * the ephemeral per-tool deltas from `addActiveTool` / `removeActiveTool` + * (intentionally not persisted, re-derived on resume); the + * live overlay is held in `agentState` and falls back to the Model when unset, + * so no restore-ordering coupling arises. Profile and client + * policy are persisted independently. The `agent.status.updated` + * / `warning` events ride `IEventBus`. `emitStatusUpdated` runs live-only + * after the dispatch, so + * `wire.replay` rebuilds the Models silently; the same live-only path mirrors + * the resolved + * model protocol into the ambient telemetry context (`provider_type` / + * `protocol`) whenever the model alias changes. + * `bind()` is first-bind only — a profile is the session's identity: the + * guard runs before name resolution so `already bound` fails fast, and again + * in the synchronous segment before the first dispatch, so concurrent binds + * cannot both pass (an edge-level guard always leaves an interleaving + * window); a same-name rebind keeps the persisted thinking effort unless the + * caller explicitly overrides it. The AGENTS.md portion of the system-prompt + * context comes from the seeded `ISessionInstructionsProvider` (the + * workspace handler's shared, watch-refreshed snapshot — the working + * directory is always the session's frozen cwd, so the snapshot always + * applies), and the provider's change event drives a `refreshSystemPrompt`. Prompt builds inject the enabled plugins' + * system-prompt sections (budget-capped, see `PLUGIN_SECTIONS_MAX_BYTES`) and + * the model skill listing; both are snapshotted at the agent's first + * successful build and frozen for the agent's lifetime, so plugin install / + * enable / disable / remove / reload never rewrites a live agent's prompt — + * the same keep-live-sessions-stable philosophy as the MCP tombstone. New + * agents (new sessions, new subagents) snapshot the then-current state. The + * Workspace-scope catalog still re-pulls its plugin source on plugin reload + * (new agents and runtime skill lookups read it), but its change event no + * longer drives `refreshSystemPrompt`: with the plugin-derived inputs + * frozen, such a rebuild could never pick up new content and would only + * churn `${now}`, rewriting the prompt and invalidating the provider's + * prompt cache on every plugin mutation. The prompt only moves when + * non-plugin inputs change (AGENTS.md, the + * `[tools]` section, session tool policy, compaction, the builtin-source + * config toggle). A side effect of the + * freeze: skills added mid-session to file-backed sources, and builtin-source + * config toggles, no longer ride an unrelated refresh into a live agent's + * prompt. `refreshSystemPrompt` never rejects: a + * failed context build keeps the current prompt and surfaces a warning, + * because the `[tools]` config watcher fires it voided (an unhandled + * rejection would crash kap-server) and the Session tool-policy fan-out + * awaits it across agents. Tool-policy entries that can never activate + * anything (typo'd names, wildcards without the `mcp__` prefix, incomplete + * `mcp__` literals) surface as `warning` events instead of silently shrinking + * the tool set; the known-name vocabulary is the live registry plus + * builtin-profile literal names — deliberately not the session catalog, so a + * typo in one agent file cannot legitimize the same typo in another, and + * flag-gated tools (which every builtin profile lists) stay "known" even when + * unregistered. + * The mutable plain-data state (`activeToolNamesOverlay` / `agentsMdWarning` + * / the three emitted-warning dedupe sets) is registered into `agentState` + * (`IAgentStateService`) and read/written through it; `optionsValue` (holds + * the `cwd` / `emitStatusUpdated` callbacks), `activeProfile` + * (a `ResolvedAgentProfile` carrying the `systemPrompt` function), and the + * frozen plugin-derived prompt inputs (`frozenSkillListing` / + * `frozenPluginSections` — one-shot snapshots, so there is nothing to + * restore) stay plain + * fields because the container only holds pure data structures. After every + * successful bind / apply / refresh (never before the new prompt commits, + * so a failed build cannot poison the set), the injected AGENTS.md paths are + * seeded into `agentsMdReminder`'s known-set with the effective cwd. Fills the + * prompt's product-name slot from the `agentIdentity` snapshot — frozen for + * the process, so no `[identity]` subscription belongs here; the template's + * own default applies when nothing is configured. `bind` gates on the freeze + * before materializing the model, whose resolution reads the identity through + * the host-headers port — a fast bootstrap must wait, not trip the pre-freeze + * guard. Bound at Agent scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { UNKNOWN_CAPABILITY, type ModelCapability } from '#/kosong/contract/capability'; import { type SamplingOptions, type ThinkingEffort } from '#/kosong/contract/provider'; import { IModelCatalog, type Model } from '#/kosong/model/catalog'; @@ -26,26 +114,29 @@ import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; import type { LoopControl } from '#/agent/loop/configSection'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { IHostClock } from '#/os/interface/hostClock'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import type { ToolSource } from '#/tool/toolContract'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; +import { subagentDisplayModel } from '#/session/subagent/configSection'; import { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; +import { BUILTIN_SKILL_SOURCE_ID } from '#/app/skillCatalog/skillSource'; import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; import { ISessionToolPolicy } from '#/session/sessionToolPolicy/sessionToolPolicy'; import { ISessionToolPolicyGate } from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; import { IPluginService } from '#/app/plugin/plugin'; import type { ResolvedAgentProfile, SystemPromptContext } from '#/agent/profile/profile'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentAgentsMdReminderService } from '#/agent/agentsMdReminder/agentsMdReminder'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { IAgentTelemetryContextService } from '#/app/telemetry/agentTelemetryContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; +import type { PayloadOf } from '#/wire/types'; +import { IEventBus } from '#/app/event/eventBus'; import { extractAgentsMdPathsFromSystemPrompt, prepareSystemPromptContext, @@ -67,26 +158,28 @@ import { isToolActiveComposed, findInactiveToolPatterns, literalToolNames, type import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { getAgentToolContributions } from '#/agent/toolRegistry/toolContribution'; import { - profileActiveToolsKey, - ConfigUpdate, - ProfileBind, - profileKey, - ToolsResetActiveTools, - ToolsSetActiveTools, - WarningIssued, + ActiveToolsModel, + configUpdate, + profileBind, + ProfileModel, + setActiveTools, + resetActiveTools, type ActiveToolsState, - type ConfigUpdatePayload, type ProfileModelState, } from './profileOps'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; - export interface WarningEvent { readonly type: 'warning'; readonly message: string; readonly code?: string; } +declare module '#/app/event/eventBus' { + interface DomainEventMap { + warning: WarningEvent; + } +} + function describeInactiveToolPattern( context: string, field: string, @@ -125,6 +218,7 @@ export const profileEmittedPluginBudgetWarningsKey = defineState<Set<string>>( () => new Set(), ); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentProfileService extends Disposable implements IAgentProfileService { declare readonly _serviceBrand: undefined; @@ -133,24 +227,31 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ private get activeToolNames(): ActiveToolsState { return ( this.activeToolNamesOverlay ?? - (this.states.get(profileActiveToolsKey) as ActiveToolsState) + (this.wire.getModel(ActiveToolsModel) as ActiveToolsState) ); } private activeProfile: ResolvedAgentProfile | undefined; + // Plugin-derived prompt inputs, snapshotted on first successful build and + // frozen for the agent's lifetime (see the file header): a live agent's + // prompt must not move when plugins are installed / enabled / disabled / + // removed / reloaded. Never reset by applyProfile / useProfile / + // applyBindingSnapshot / refreshSystemPrompt. private frozenSkillListing: string | undefined; private frozenPluginSections: string | undefined; constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IWireService private readonly wire: IWireService, + @IEventBus private readonly eventBus: IEventBus, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentTelemetryContextService private readonly telemetryContext: IAgentTelemetryContextService, @IConfigService private readonly config: IConfigService, @IModelCatalog private readonly modelCatalog: IModelCatalog, @IProtocolAdapterRegistry private readonly protocolAdapters: IProtocolAdapterRegistry, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostEnvironment private readonly env: IHostEnvironment, @IHostClock private readonly clock: IHostClock, + @IHostFileSystem private readonly fs: IHostFileSystem, @ISessionContext private readonly sessionContext: ISessionContext, @IBootstrapService private readonly bootstrap: IBootstrapService, @ISessionWorkspaceContext private readonly workspace: ISessionWorkspaceContext, @@ -161,25 +262,44 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ @ISessionToolPolicyGate private readonly toolPolicyGate: ISessionToolPolicyGate, @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, @IBuiltinAgentProfileLoader private readonly builtinProfiles: IBuiltinAgentProfileLoader, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentStateService private readonly states: IAgentStateService, @IPluginService private readonly plugins: IPluginService, @IAgentIdentity private readonly identity: IAgentIdentity, @IAgentAgentsMdReminderService private readonly agentsMdReminder: IAgentAgentsMdReminderService, ) { super(); - this.states.contributeState(profileKey); - this.states.contributeState(profileActiveToolsKey); - this.states.contributeState(profileActiveToolNamesOverlayKey); - this.states.contributeState(profileAgentsMdWarningKey); - this.states.contributeState(profileEmittedThinkingEffortWarningsKey); - this.states.contributeState(profileEmittedToolPatternWarningsKey); - this.states.contributeState(profileEmittedPluginBudgetWarningsKey); + this.states.register(profileActiveToolNamesOverlayKey); + this.states.register(profileAgentsMdWarningKey); + this.states.register(profileEmittedThinkingEffortWarningsKey); + this.states.register(profileEmittedToolPatternWarningsKey); + this.states.register(profileEmittedPluginBudgetWarningsKey); this.configure({}); + this._register( + this.sessionToolPolicy.onDidChange((event) => { + event.waitUntil(this.refreshSystemPrompt()); + }), + ); + this._register( + this.instructions.onDidChange(() => { + void this.refreshSystemPrompt(); + }), + ); this._register( this.config.onDidSectionChange(({ domain }) => { if (domain === TOOLS_SECTION) { this.publishToolPatternWarnings(); + void this.refreshSystemPrompt(); + } + }), + ); + this._register( + this.skillCatalog.onDidChange((sourceId) => { + // Only the builtin source drives a rebuild: plugin-derived prompt + // inputs are frozen for the agent's lifetime, so rebuilding on a + // plugin-source change could never pick up new content — it would + // only churn `${now}` and invalidate the provider's prompt cache. + if (sourceId === BUILTIN_SKILL_SOURCE_ID) { + void this.refreshSystemPrompt(); } }), ); @@ -228,7 +348,7 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ this.activeProfile = undefined; } if (Object.keys(configChanged).length > 0) { - void this.dispatcher.dispatch(new ConfigUpdate(this.resolveConfigPayload(configChanged))); + this.wire.dispatch(configUpdate(this.resolveConfigPayload(configChanged))); this.afterConfigDispatch(configChanged); } if (activeToolNames !== undefined) { @@ -241,9 +361,8 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ this.activeToolNamesOverlay = undefined; const agentsMdPaths = snapshot.agentsMdPaths ?? extractAgentsMdPathsFromSystemPrompt(snapshot.systemPrompt); - void this.dispatcher.dispatch( - new ProfileBind({ - agentId: this.scopeContext.agentId, + this.wire.dispatch( + profileBind({ modelAlias: snapshot.modelAlias, profileName: snapshot.profileName, thinkingEffort: snapshot.thinkingLevel, @@ -311,8 +430,7 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ ); this.activeToolNamesOverlay = undefined; - await this.dispatcher.dispatch(new ProfileBind({ - agentId: this.scopeContext.agentId, + this.wire.dispatch(profileBind({ modelAlias: alias, profileName: profile.name, thinkingEffort: thinkingLevel, @@ -407,6 +525,34 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ this.publishToolPatternWarnings(profile); } + async refreshSystemPrompt(): Promise<void> { + const profile = this.resolveActiveProfile(); + if (profile === undefined) return; + + let context: SystemPromptContext; + try { + context = await this.buildSystemPromptContext(profile); + } catch (error) { + this.eventBus.publish({ + type: 'warning', + message: `System prompt refresh skipped: ${error instanceof Error ? error.message : String(error)}`, + code: 'system-prompt-refresh-failed', + }); + return; + } + this.activeProfile = profile; + const rendered = profile.renderSystemPrompt(context); + this.update({ + profileName: profile.name, + systemPrompt: rendered.text, + environmentDisclosure: rendered.environment, + agentsMdPaths: context.agentsMdPaths ?? [], + }); + this.seedAgentsMdReminder(context); + this.cacheAgentsMdWarning(context); + this.publishAgentsMdWarning(); + } + private seedAgentsMdReminder(context: SystemPromptContext): void { this.agentsMdReminder.seedInjected( context.agentsMdPaths ?? [], @@ -519,8 +665,10 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ private resolveConfigPayload( changed: Omit<ProfileUpdateData, 'activeToolNames'>, - ): ConfigUpdatePayload { - const payload: ConfigUpdatePayload = { agentId: this.scopeContext.agentId }; + ): PayloadOf<typeof configUpdate> { + const payload: { + -readonly [K in keyof PayloadOf<typeof configUpdate>]: PayloadOf<typeof configUpdate>[K]; + } = {}; if (changed.modelAlias !== undefined) payload.modelAlias = changed.modelAlias; if (changed.profileName !== undefined) payload.profileName = changed.profileName; if (changed.thinkingLevel !== undefined || changed.modelAlias !== undefined) { @@ -579,7 +727,7 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ const key = [code, model.id, model.name, effort, knownEfforts].join('\u0000'); if (this.emittedThinkingEffortWarnings.has(key)) return; this.emittedThinkingEffortWarnings.add(key); - void this.dispatcher.dispatch(new WarningIssued({ agentId: this.scopeContext.agentId, code, message })); + this.eventBus.publish({ type: 'warning', code, message }); } catch { } } @@ -587,12 +735,10 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ private setActiveTools(names: readonly string[] | undefined): void { this.activeToolNamesOverlay = undefined; if (names === undefined) { - void this.dispatcher.dispatch(new ToolsResetActiveTools({ agentId: this.scopeContext.agentId })); + this.wire.dispatch(resetActiveTools({})); return; } - void this.dispatcher.dispatch( - new ToolsSetActiveTools({ agentId: this.scopeContext.agentId, names: [...names] }), - ); + this.wire.dispatch(setActiveTools({ names: [...names] })); } private emitStatusUpdated(includeThinkingEffort = false): void { @@ -603,19 +749,20 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ } const modelAlias = this.modelAlias; if (modelAlias === undefined) return; + // An alias that no longer resolves (e.g. the model entry was removed from + // config) yields UNKNOWN_CAPABILITY whose max_context_tokens is 0 — the + // "unknown" marker, not a real limit. Omit the field instead of pushing 0. const capabilities = this.tryResolveRawModel()?.capabilities; const maxContextTokens = capabilities?.max_input_tokens ?? capabilities?.max_context_tokens; - void this.dispatcher.dispatch( - new AgentStatusUpdated({ - agentId: this.scopeContext.agentId, - model: modelAlias, - thinkingEffort: includeThinkingEffort - ? this.getEffectiveThinkingLevel() - : undefined, - maxContextTokens: - maxContextTokens !== undefined && maxContextTokens > 0 ? maxContextTokens : undefined, - }), - ); + this.eventBus.publish({ + type: 'agent.status.updated', + model: subagentDisplayModel(this.config, modelAlias), + thinkingEffort: includeThinkingEffort + ? this.getEffectiveThinkingLevel() + : undefined, + maxContextTokens: + maxContextTokens !== undefined && maxContextTokens > 0 ? maxContextTokens : undefined, + }); } republishStatus(): void { @@ -623,7 +770,7 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ } private get profileState(): ProfileModelState { - return this.states.get(profileKey); + return this.wire.getModel(ProfileModel); } private get model(): string { @@ -721,6 +868,13 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ } } + private resolveActiveProfile(): ResolvedAgentProfile | undefined { + if (this.activeProfile !== undefined) return this.activeProfile; + const profileName = this.profileName; + if (profileName === undefined) return undefined; + return this.catalog.get(profileName); + } + private cacheAgentsMdWarning(context: Pick<SystemPromptContext, 'agentsMdWarning'>): void { this.agentsMdWarning = context.agentsMdWarning; } @@ -728,13 +882,11 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ private publishAgentsMdWarning(): void { const warning = this.agentsMdWarning; if (warning === undefined) return; - void this.dispatcher.dispatch( - new WarningIssued({ - agentId: this.scopeContext.agentId, - message: warning, - code: 'agents-md-oversized', - }), - ); + this.eventBus.publish({ + type: 'warning', + message: warning, + code: 'agents-md-oversized', + }); } private publishToolPatternWarnings(profile?: ResolvedAgentProfile): void { @@ -775,13 +927,11 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ const key = `${context}|${field}|${issue.pattern}`; if (this.emittedToolPatternWarnings.has(key)) continue; this.emittedToolPatternWarnings.add(key); - void this.dispatcher.dispatch( - new WarningIssued({ - agentId: this.scopeContext.agentId, - code: 'tool-pattern-no-match', - message: describeInactiveToolPattern(context, field, issue), - }), - ); + this.eventBus.publish({ + type: 'warning', + code: 'tool-pattern-no-match', + message: describeInactiveToolPattern(context, field, issue), + }); } } } @@ -791,39 +941,25 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ options?: ApplyProfileOptions, ): Promise<SystemPromptContext> { const preloadedAgentsMd = await this.workspaceInstructionsSnapshot(); - const fsAvailable = this.runtime.isAvailable(['fs']); - const lease = this.runtime.acquire(fsAvailable ? ['fs'] : []); - const env = lease.runtime.environment; - const view = new RuntimeWorkspaceView(lease.runtime, { - workDir: this.sessionContext.cwd, - additionalDirs: options?.additionalDirs ?? this.workspace.additionalDirs, - }); - let base: SystemPromptContext; - try { - base = !fsAvailable - ? {} - : await prepareSystemPromptContext( - { fs: lease.runtime.fs!, homeDir: env.homeDir }, - view.workDir, - this.bootstrap.homeDir, - { - additionalDirs: view.additionalDirs, - preloadedAgentsMd, - }, - ); - } finally { - lease.dispose(); - } + const base = await prepareSystemPromptContext( + { fs: this.fs, homeDir: this.env.homeDir }, + this.sessionContext.cwd, + this.bootstrap.homeDir, + { + additionalDirs: options?.additionalDirs ?? this.workspace.additionalDirs, + preloadedAgentsMd, + }, + ); const skills = await this.resolveSkillListing(); const pluginSections = await this.resolvePluginSections(); const now = this.clock.now(); const timeZone = this.clock.timeZone(); return { ...base, - cwd: view.workDir, - osKind: env.osKind, - shellName: env.shellName, - shellPath: env.shellPath, + cwd: this.sessionContext.cwd, + osKind: this.env.osKind, + shellName: this.env.shellName, + shellPath: this.env.shellPath, now: now.toISOString(), timeZone, skills, @@ -865,6 +1001,8 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ try { await this.skillCatalog.ready; const listing = this.skillCatalog.catalog.getModelSkillListing(); + // Freeze only on success — a not-yet-ready catalog must not pin an + // empty listing for the agent's lifetime. this.frozenSkillListing = listing; return listing; } catch { @@ -892,18 +1030,20 @@ export class AgentProfileService extends Disposable implements IAgentProfileServ const newlySkipped = skipped.filter((id) => !this.emittedPluginBudgetWarnings.has(id)); if (newlySkipped.length > 0) { for (const id of newlySkipped) this.emittedPluginBudgetWarnings.add(id); - void this.dispatcher.dispatch( - new WarningIssued({ - agentId: this.scopeContext.agentId, - message: - `Plugin system-prompt contributions from ${newlySkipped.map((id) => `"${id}"`).join(', ')} ` + - `were skipped: the aggregate ${PLUGIN_SECTIONS_MAX_BYTES / 1024} KB budget is exhausted.`, - code: 'plugin-sections-oversized', - }), - ); + this.eventBus.publish({ + type: 'warning', + message: + `Plugin system-prompt contributions from ${newlySkipped.map((id) => `"${id}"`).join(', ')} ` + + `were skipped: the aggregate ${PLUGIN_SECTIONS_MAX_BYTES / 1024} KB budget is exhausted.`, + code: 'plugin-sections-oversized', + }); } } const resolved = parts.join('\n\n'); + // Freeze only on a real snapshot: while the initial plugin load has + // failed, `enabledSystemPrompts()` resolves to its consumption fallback + // instead of rejecting, and pinning that empty read would lock plugin + // sections out of the live agent even after a later successful reload. if (this.plugins.hasLoadedSnapshot()) this.frozenPluginSections = resolved; return resolved; } diff --git a/packages/agent-core-v2/src/agent/prompt/errors.ts b/packages/agent-core-v2/src/agent/prompt/errors.ts index 9259a5627..a3e6b1436 100644 --- a/packages/agent-core-v2/src/agent/prompt/errors.ts +++ b/packages/agent-core-v2/src/agent/prompt/errors.ts @@ -1,3 +1,7 @@ +/** + * `prompt` domain error codes — request/input validation failures. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const PromptErrors = { @@ -5,7 +9,6 @@ export const PromptErrors = { REQUEST_INVALID: 'request.invalid', REQUEST_WORK_DIR_REQUIRED: 'request.work_dir_required', REQUEST_PROMPT_INPUT_EMPTY: 'request.prompt_input_empty', - PROMPT_ID_CONFLICT: 'prompt.id_conflict', PROMPT_NOT_FOUND: 'prompt.not_found', PROMPT_ALREADY_COMPLETED: 'prompt.already_completed', SESSION_BUSY: 'session.busy', diff --git a/packages/agent-core-v2/src/agent/prompt/prompt.ts b/packages/agent-core-v2/src/agent/prompt/prompt.ts index 4eb7136d2..d5045dd02 100644 --- a/packages/agent-core-v2/src/agent/prompt/prompt.ts +++ b/packages/agent-core-v2/src/agent/prompt/prompt.ts @@ -1,8 +1,6 @@ import { createDecorator } from '#/_base/di/instantiation'; -import type { IDisposable } from '#/_base/di/lifecycle'; import type { ContextMessage } from '#/agent/contextMemory/types'; import type { Turn, TurnResult } from '#/agent/loop/loop'; -import type { ContentPart } from '#/kosong/contract/message'; import type { Hooks } from '#/hooks'; export interface PromptSubmitContext { @@ -49,44 +47,12 @@ export interface PromptQueueSnapshot { readonly pending: readonly PromptSnapshot[]; } -export interface PromptPayload { - readonly input: readonly ContentPart[]; - readonly disabledTools?: readonly string[]; - readonly promptId?: string; -} - -export interface SteerPayload { - readonly input: readonly ContentPart[]; -} - -export interface PromptLaunchResult { - readonly turn_id: number; -} - -export interface PromptReservation extends IDisposable { - readonly id: string; - submit(message: ContextMessage): Promise<PromptHandle>; -} - -export const promptAdmission = Symbol('promptAdmission'); - -type PromptAdmissionHook = (promptId?: string) => PromptReservation; - -export function reservePrompt(service: IAgentPromptService, promptId?: string): PromptReservation { - return (service as IAgentPromptService & { [promptAdmission]: PromptAdmissionHook })[ - promptAdmission - ](promptId); -} - export interface IAgentPromptService { readonly _serviceBrand: undefined; enqueue(input: PromptInput): Promise<PromptHandle>; - submit(payload: PromptPayload): Promise<PromptLaunchResult | undefined>; - submitSteer(payload: SteerPayload): Promise<PromptLaunchResult | undefined>; list(): PromptQueueSnapshot; steer(promptIds: readonly string[]): Promise<readonly PromptHandle[]>; abort(promptId: string, reason?: Error): boolean; - drain(reason?: Error): Promise<void>; inject(message: ContextMessage): Promise<Turn | undefined>; retry(): Promise<Turn | undefined>; clear(): void; diff --git a/packages/agent-core-v2/src/agent/prompt/promptMetadataText.ts b/packages/agent-core-v2/src/agent/prompt/promptMetadataText.ts index 78f31415b..631c7c5d3 100644 --- a/packages/agent-core-v2/src/agent/prompt/promptMetadataText.ts +++ b/packages/agent-core-v2/src/agent/prompt/promptMetadataText.ts @@ -1,5 +1,12 @@ +/** + * `prompt` domain — safe, displayable metadata text derived from prompts. + * + * Shared by prompt submission and undo projection so `lastPrompt` uses one + * normalization, redaction, and length limit, with image captions supplied by + * the `media` domain. + */ + import type { ContentPart } from '#/kosong/contract/message'; -import { matchSingleMediaPathTag } from '#/agent/media/mediaRef'; import { extractImageCompressionCaptions } from '#/agent/media/image-compress'; const MAX_TITLE_LENGTH = 200; @@ -44,7 +51,6 @@ export function promptMetadataTextFromText(text: string): string | undefined { function promptPartText(part: ContentPart): string | undefined { switch (part.type) { case 'text': { - if (matchSingleMediaPathTag(part.text) !== undefined) return undefined; const { text } = extractImageCompressionCaptions(part.text); return text.trim().length === 0 ? undefined : text; } diff --git a/packages/agent-core-v2/src/agent/prompt/promptOps.ts b/packages/agent-core-v2/src/agent/prompt/promptOps.ts deleted file mode 100644 index fcae4febf..000000000 --- a/packages/agent-core-v2/src/agent/prompt/promptOps.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -const promptAcceptedSchema = z.object({ - agentId: z.string(), - promptId: z.string().min(1), - content: z.unknown().optional(), -}); - -export class PromptAccepted extends AgentEvent2<z.infer<typeof promptAcceptedSchema>> { - static override readonly type = 'prompt.accepted'; - static override readonly durable = true; - static override readonly observable = true; - static override readonly schema = promptAcceptedSchema; -} -export interface PromptAccepted { - readonly agentId: string; - readonly promptId: string; - readonly content?: unknown; -} - -export const promptAdmissionKey = defineState('promptAdmission', (): Map<string, true> => new Map()) - .replayable({ schema: z.map(z.string(), z.literal(true)) }) - .on(PromptAccepted, (state, event) => { - if (state.has(event.promptId)) return state; - state.set(event.promptId, true); - }); diff --git a/packages/agent-core-v2/src/agent/prompt/promptService.ts b/packages/agent-core-v2/src/agent/prompt/promptService.ts index 7bfb1308b..efd40bac1 100644 --- a/packages/agent-core-v2/src/agent/prompt/promptService.ts +++ b/packages/agent-core-v2/src/agent/prompt/promptService.ts @@ -1,8 +1,21 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `prompt` domain — owns the per-agent prompt scheduler. + * + * Assigns prompt and message identities, serializes user prompts through an + * active slot and FIFO, converts selected pending prompts into active-turn + * steers, settles lifecycle handles, and keeps system input outside the prompt + * resource model. The pure-data `launching` flag is registered into + * `agentState` (`IAgentStateService`) and read/written through it; the + * `active` / `pending` / `steered` records stay plain fields because their + * `Record` values carry Deferred promise handles (the container only holds + * pure data structures), as do the lazily-resolved `fullCompactionService` + * reference and the `hooks` slot. Bound at Agent scope. + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { extractImageCompressionCaptions } from '#/agent/media/image-compress'; import { userCancellationReason } from '#/_base/utils/abort'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; @@ -10,128 +23,39 @@ import { newMessageId } from '#/agent/contextMemory/messageId'; import { USER_PROMPT_ORIGIN, type ContextMessage } from '#/agent/contextMemory/types'; import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; import { IAgentLoopService, type Turn, type TurnResult } from '#/agent/loop/loop'; -import { TurnSteer } from '#/agent/loop/turnOps'; +import { steerTurn } from '#/agent/loop/turnOps'; import { IAgentStateService } from '#/agent/state/agentState'; -import { AgentReminder, type ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; import type { ExecutableToolResult } from '#/tool/toolContract'; import type { ToolDidExecuteContext } from '#/agent/toolExecutor/toolHooks'; import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; -import { IFileService } from '#/app/file/fileService'; import type { ContentPart } from '#/kosong/contract/message'; -import { IEventService } from '#/app/event/event'; -import { AgentEvent2 } from '#/app/event/event2'; -import { ErrorCodes, Error2, isError2 } from '#/errors'; +import { IEventBus } from '#/app/event/eventBus'; +import { ErrorCodes, Error2 } from '#/errors'; import { OrderedHookSlot } from '#/hooks'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { applyPromptMetadataUpdate } from '#/session/sessionMetadata/promptMetadata'; +import { IWireService } from '#/wire/wire'; import { IAgentPromptService, - promptAdmission, type PromptCompletion, type PromptHandle, type PromptInput, - type PromptLaunchResult, - type PromptPayload, type PromptQueueSnapshot, - type PromptReservation, type PromptSnapshot, type PromptState, type PromptSubmitContext, - type SteerPayload, } from './prompt'; -import { promptMetadataTextFromContentParts } from './promptMetadataText'; import { PromptStepRequest, RetryStepRequest, SteerStepRequest } from './promptStepRequests'; -import { PromptAccepted, promptAdmissionKey } from './promptOps'; -import { daemonFileRefFromPart } from '#/agent/media/mediaRef'; -import { materializePromptDaemonRefs } from '#/agent/media/promptMediaIntake'; -import { ISessionMediaStore } from '#/agent/media/sessionMediaStore'; -export interface PromptCompletedPayload { - readonly agentId: string; - readonly promptId: string; - readonly finishedAt: string; - readonly reason: 'completed' | 'failed' | 'blocked'; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'prompt.completed': { type: 'prompt.completed'; promptId: string; finishedAt: string; reason: 'completed' | 'failed' | 'blocked' }; + 'prompt.aborted': { type: 'prompt.aborted'; promptId: string; abortedAt: string }; + 'prompt.steered': { type: 'prompt.steered'; activePromptId: string; promptIds: string[]; content: ContentPart[]; steeredAt: string }; + 'prompt.queued': { type: 'prompt.queued'; promptId: string; content: ContentPart[]; queueLength: number }; + } } -export class PromptCompleted extends AgentEvent2<PromptCompletedPayload> { - static override readonly type = 'prompt.completed'; - static override readonly observable = true; -} -export interface PromptCompleted extends PromptCompletedPayload {} - -export interface PromptAbortedPayload { - readonly agentId: string; - readonly promptId: string; - readonly abortedAt: string; -} - -export class PromptAborted extends AgentEvent2<PromptAbortedPayload> { - static override readonly type = 'prompt.aborted'; - static override readonly observable = true; -} -export interface PromptAborted extends PromptAbortedPayload {} - -export interface PromptSteeredPayload { - readonly agentId: string; - readonly activePromptId: string; - readonly promptIds: string[]; - readonly content: ContentPart[]; - readonly steeredAt: string; -} - -export class PromptSteered extends AgentEvent2<PromptSteeredPayload> { - static override readonly type = 'prompt.steered'; - static override readonly observable = true; -} -export interface PromptSteered extends PromptSteeredPayload {} - -export interface PromptQueuedPayload { - readonly agentId: string; - readonly promptId: string; - readonly content: ContentPart[]; - readonly queueLength: number; -} - -export class PromptQueued extends AgentEvent2<PromptQueuedPayload> { - static override readonly type = 'prompt.queued'; - static override readonly observable = true; -} -export interface PromptQueued extends PromptQueuedPayload {} - -export interface PromptSubmittedPayload { - readonly agentId: string; - readonly promptId: string; - readonly userMessageId: string; - readonly status: 'running' | 'queued'; - readonly content: ContentPart[]; - readonly createdAt: string; -} - -export class PromptSubmitted extends AgentEvent2<PromptSubmittedPayload> { - static override readonly type = 'prompt.submitted'; - static override readonly observable = true; -} -export interface PromptSubmitted extends PromptSubmittedPayload {} - -export interface PromptStartedPayload { - readonly agentId: string; - readonly promptId: string; -} - -export class PromptStarted extends AgentEvent2<PromptStartedPayload> { - static override readonly type = 'prompt.started'; - static override readonly observable = true; -} -export interface PromptStarted extends PromptStartedPayload {} - interface Deferred<T> { readonly promise: Promise<T>; resolve(value: T): void; reject(reason: unknown): void } interface Record extends PromptSnapshot { state: PromptState; @@ -140,29 +64,6 @@ interface Record extends PromptSnapshot { handle: PromptHandle; } -function bundledSkillBlockCount(message: ContextMessage): number { - return message.origin?.kind === 'user' ? (message.origin.skillActivations?.length ?? 0) : 0; -} - -function stripBundledSkillBlocks(message: ContextMessage): ContentPart[] { - return message.content.slice(bundledSkillBlockCount(message)); -} - -function mergeSteerMessages(records: readonly Record[]): ContextMessage { - const skillActivations = records.flatMap((item) => - item.message.origin?.kind === 'user' ? (item.message.origin.skillActivations ?? []) : [], - ); - return { - role: 'user', - content: [ - ...records.flatMap((item) => item.message.content.slice(0, bundledSkillBlockCount(item.message))), - ...records.flatMap((item) => stripBundledSkillBlocks(item.message)), - ], - toolCalls: [], - origin: skillActivations.length === 0 ? USER_PROMPT_ORIGIN : { kind: 'user', skillActivations }, - }; -} - export const promptLaunchingKey = defineState<boolean>('prompt.launching', () => false); export class AgentPromptService implements IAgentPromptService { @@ -170,38 +71,26 @@ export class AgentPromptService implements IAgentPromptService { private active: (Record & { turn: Turn }) | undefined; private readonly pending: Record[] = []; private readonly steered = new Map<string, Record[]>(); - private readonly reservedPromptIds = new Set<string>(); - private steering = 0; private fullCompactionService: IAgentFullCompactionService | undefined; readonly hooks = { onBeforeSubmitPrompt: new OrderedHookSlot<PromptSubmitContext>() }; constructor( @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, @IInstantiationService private readonly instantiation: IInstantiationService, @IAgentLoopService private readonly loop: IAgentLoopService, @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, - @IAgentToolPolicyService private readonly toolPolicy: IAgentToolPolicyService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IWireService private readonly wire: IWireService, + @IEventBus private readonly eventBus: IEventBus, @IAgentStateService private readonly states: IAgentStateService, - @ITelemetryService private readonly telemetry: ITelemetryService, - @ISessionMetadata private readonly metadata: ISessionMetadata, - @IEventService private readonly eventService: IEventService, - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, ) { - this.states.contributeState(promptLaunchingKey); - this.states.contributeState(promptAdmissionKey); + this.states.register(promptLaunchingKey); toolExecutor.hooks.onDidExecuteTool.register('prompt-service-delivery', async (ctx, next) => { await this.deliverToolResult(ctx); await next(); }); } - private reminder(): ReminderRuntime { - return this.agentLifecycle.resolve(this.scopeContext.agentContext, AgentReminder); - } - private get launching(): boolean { return this.states.get(promptLaunchingKey); } @@ -210,41 +99,6 @@ export class AgentPromptService implements IAgentPromptService { this.states.set(promptLaunchingKey, value); } - [promptAdmission](promptId?: string): PromptReservation { - if (promptId !== undefined && promptId.length === 0) { - throw new Error2(ErrorCodes.REQUEST_INVALID, 'prompt_id must not be empty'); - } - const accepted = this.states.get(promptAdmissionKey); - let id = promptId ?? newMessageId(); - while (accepted.has(id) || this.reservedPromptIds.has(id)) { - if (promptId !== undefined) { - throw new Error2(ErrorCodes.PROMPT_ID_CONFLICT, `prompt_id '${id}' is already in use`); - } - id = newMessageId(); - } - this.reservedPromptIds.add(id); - let submitted = false; - return { - id, - submit: async (message) => { - if (submitted) throw new Error2(ErrorCodes.REQUEST_INVALID, 'prompt reservation already submitted'); - submitted = true; - this.reservedPromptIds.delete(id); - await this.dispatcher.dispatch( - new PromptAccepted({ - agentId: this.scopeContext.agentId, - promptId: id, - content: stripBundledSkillBlocks(message), - }), - ); - return this.enqueue({ id, message }); - }, - dispose: () => { - this.reservedPromptIds.delete(id); - }, - }; - } - async enqueue(input: PromptInput): Promise<PromptHandle> { const id = input.id ?? input.message.id ?? newMessageId(); const message = { ...input.message, id }; @@ -262,78 +116,17 @@ export class AgentPromptService implements IAgentPromptService { completion: completionDeferred.promise, }; this.pending.push(record); - const idle = this.active === undefined && !this.launching; - const queued = !idle || (this.fullCompaction.compacting !== null && this.loop.status().state !== 'running'); - this.publishSubmitted(record, queued ? 'queued' : 'running'); - if (queued) { - this.publishQueued(record); - return record.handle; - } - void this.startNext(); - await Promise.race([record.launchedDeferred.promise, record.completionDeferred.promise]); - return record.handle; - } - - async submit(payload: PromptPayload): Promise<PromptLaunchResult | undefined> { - const reservation = this[promptAdmission](payload.promptId); - try { - if (payload.disabledTools !== undefined) { - try { - await this.toolPolicy.setSessionDisabledTools(payload.disabledTools); - } catch (error) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - error instanceof Error ? error.message : String(error), - ); - } + if (this.active === undefined && !this.launching) { + if (this.fullCompaction.compacting !== null && this.loop.status().state !== 'running') { + this.publishQueued(record); + return record.handle; } - await this.updatePromptMetadata(promptMetadataTextFromContentParts(payload.input)); - const handle = await reservation.submit({ - role: 'user', - content: [...payload.input], - toolCalls: [], - origin: { kind: 'user' }, - }); - if (handle.state === 'pending') return undefined; - const turn = await handle.launched; - return turn === undefined ? undefined : { turn_id: turn.id }; - } finally { - reservation.dispose(); + void this.startNext(); + await Promise.race([record.launchedDeferred.promise, record.completionDeferred.promise]); + } else { + this.publishQueued(record); } - } - - async submitSteer(payload: SteerPayload): Promise<PromptLaunchResult | undefined> { - this.telemetry.track2('input_steer', { parts: payload.input.length }); - await this.updatePromptMetadata(promptMetadataTextFromContentParts(payload.input)); - const queued = await this.enqueue({ message: { - role: 'user', - content: [...payload.input], - toolCalls: [], - } }); - if (queued.state !== 'pending') { - const turn = await queued.launched; - return turn === undefined ? undefined : { turn_id: turn.id }; - } - try { - const [steered] = await this.steer([queued.id]); - const turn = await steered?.launched; - return turn === undefined ? undefined : { turn_id: turn.id }; - } catch (error) { - if (isError2(error) && error.code === ErrorCodes.PROMPT_NOT_FOUND) return undefined; - throw error; - } - } - - private async updatePromptMetadata(text: string | undefined): Promise<void> { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) return; - await applyPromptMetadataUpdate( - { - metadata: this.metadata, - eventService: this.eventService, - sessionId: this.sessionContext.sessionId, - }, - text, - ); + return record.handle; } list(): PromptQueueSnapshot { @@ -348,46 +141,19 @@ export class AgentPromptService implements IAgentPromptService { throw new Error2(ErrorCodes.PROMPT_NOT_FOUND, 'one or more prompts are not pending'); } const selected = this.pending.filter((item) => ids.has(item.id)); - const activeAtEntry = this.active; - const { message: rerouted, captions } = this.extractCompressionCaptions(mergeSteerMessages(selected)); - await this.materializeDaemonRefs(rerouted); - if (selected.some((item) => !this.pending.includes(item)) || this.active !== activeAtEntry) { - throw new Error2(ErrorCodes.PROMPT_NOT_FOUND, 'one or more prompts are no longer pending'); - } - this.steering++; - const removed: { readonly item: Record; readonly index: number }[] = []; - for (const item of selected) { - const index = this.pending.indexOf(item); - removed.push({ item, index }); - this.pending.splice(index, 1); - } - const request = new SteerStepRequest(rerouted, captions, this.reminder(), (materialized) => { - void this.dispatcher.dispatch( - new TurnSteer({ - agentId: this.scopeContext.agentId, - input: materialized.content, - origin: materialized.origin ?? USER_PROMPT_ORIGIN, - }), - ); + for (const item of selected) this.pending.splice(this.pending.indexOf(item), 1); + const message: ContextMessage = { + role: 'user', content: selected.flatMap((item) => item.message.content), toolCalls: [], origin: USER_PROMPT_ORIGIN, + }; + const { message: rerouted, captions } = this.extractCompressionCaptions(message); + const request = new SteerStepRequest(rerouted, captions, this.reminders, (materialized) => { + this.wire.dispatch(steerTurn({ input: materialized.content, origin: materialized.origin ?? USER_PROMPT_ORIGIN })); }, () => {}); - let turn: Turn | undefined; - try { - turn = (await this.loop.enqueue(request).assigned).turn; - } catch { - turn = undefined; - } finally { - this.steering--; - } - if (turn === undefined || this.active !== activeAtEntry) { - for (const { item, index } of removed.reverse()) this.pending.splice(index, 0, item); - if (this.active === undefined) void this.startNext(); - throw new Error2(ErrorCodes.PROMPT_NOT_FOUND, 'no active turn to steer into'); - } + const turn = (await this.loop.enqueue(request).assigned).turn; + if (turn === undefined) throw new Error2(ErrorCodes.PROMPT_NOT_FOUND, 'no active turn to steer into'); for (const item of selected) { item.state = 'steered'; item.launchedDeferred.resolve(turn); } this.steered.set(this.active.id, [...(this.steered.get(this.active.id) ?? []), ...selected]); - void this.dispatcher.dispatch( - new PromptSteered({ agentId: this.scopeContext.agentId, activePromptId: this.active.id, promptIds: selected.map((x) => x.id), content: selected.flatMap((item) => stripBundledSkillBlocks(item.message)), steeredAt: new Date().toISOString() }), - ); + this.eventBus.publish({ type: 'prompt.steered', activePromptId: this.active.id, promptIds: selected.map((x) => x.id), content: rerouted.content as ContentPart[], steeredAt: new Date().toISOString() }); return selected.map((item) => item.handle); } @@ -402,22 +168,10 @@ export class AgentPromptService implements IAgentPromptService { return true; } - async drain(reason: Error = userCancellationReason()): Promise<void> { - for (const item of this.pending.slice()) this.abort(item.id, reason); - if (this.active !== undefined) this.abort(this.active.id, reason); - } - async inject(message: ContextMessage): Promise<Turn | undefined> { const { message: rerouted, captions } = this.extractCompressionCaptions(message); - await this.materializeDaemonRefs(rerouted); - const request = new SteerStepRequest(rerouted, captions, this.reminder(), (materialized) => { - void this.dispatcher.dispatch( - new TurnSteer({ - agentId: this.scopeContext.agentId, - input: materialized.content, - origin: materialized.origin ?? USER_PROMPT_ORIGIN, - }), - ); + const request = new SteerStepRequest(rerouted, captions, this.reminders, (materialized) => { + this.wire.dispatch(steerTurn({ input: materialized.content, origin: materialized.origin ?? USER_PROMPT_ORIGIN })); }, () => {}, 'activeOrNewTurn'); return (await this.loop.enqueue(request).assigned).turn; } @@ -431,22 +185,20 @@ export class AgentPromptService implements IAgentPromptService { } private async startNext(): Promise<void> { - if (this.active !== undefined || this.launching || this.steering > 0) return; + if (this.active !== undefined || this.launching) return; const item = this.pending.shift(); if (item === undefined) return; this.launching = true; try { if (this.fullCompaction.compacting !== null && this.loop.status().state !== 'running') { this.pending.unshift(item); return; } const { message, captions } = this.extractCompressionCaptions(item.message); - await this.materializeDaemonRefs(message); if (await this.blockedByHook(message, false)) { this.appendPrompt(message, captions); item.state = 'blocked'; item.launchedDeferred.resolve(undefined); item.completionDeferred.resolve({ promptId: item.id, result: undefined, state: 'blocked' }); this.publishCompleted(item.id, 'blocked'); return; } - const turn = (await this.loop.enqueue(new PromptStepRequest(message, captions, this.reminder())).assigned).turn; + const turn = (await this.loop.enqueue(new PromptStepRequest(message, captions, this.reminders)).assigned).turn; if (turn === undefined) { this.pending.unshift(item); return; } item.state = 'running'; item.launchedDeferred.resolve(turn); this.active = Object.assign(item, { turn }); - this.publishStarted(item); void turn.result.then((result) => this.settle(item, result)); } catch { item.state = 'failed'; @@ -470,13 +222,6 @@ export class AgentPromptService implements IAgentPromptService { void this.startNext(); } - private async materializeDaemonRefs(message: ContextMessage): Promise<void> { - if (!message.content.some((part) => daemonFileRefFromPart(part) !== undefined)) return; - const files = this.instantiation.invokeFunction((accessor) => accessor.get(IFileService)); - const mediaStore = this.instantiation.invokeFunction((accessor) => accessor.get(ISessionMediaStore)); - await materializePromptDaemonRefs(message.content, { files, mediaStore }); - } - private async blockedByHook(promptMessage: ContextMessage, isSteer: boolean): Promise<boolean> { const ctx = { promptMessage, isSteer, block: false }; await this.hooks.onBeforeSubmitPrompt.run(ctx); return ctx.block; } @@ -500,7 +245,8 @@ export class AgentPromptService implements IAgentPromptService { private appendPrompt(message: ContextMessage, captions: readonly string[]): void { const ownerPromptId = message.id ?? newMessageId(); for (const caption of captions) { - this.reminder().notify(caption, { + this.reminders.appendSystemReminder(caption, { + kind: 'injection', variant: 'image_compression', ownerPromptId, }); @@ -512,20 +258,12 @@ export class AgentPromptService implements IAgentPromptService { const { delivery: _delivery, ...rest } = ctx.result; ctx.result = rest as ExecutableToolResult; if (delivery.kind === 'steer') await this.inject(delivery.message as ContextMessage); } - private publishCompleted(promptId: string, reason: 'completed' | 'failed' | 'blocked'): void { void this.dispatcher.dispatch(new PromptCompleted({ agentId: this.scopeContext.agentId, promptId, finishedAt: new Date().toISOString(), reason })); } + private publishCompleted(promptId: string, reason: 'completed' | 'failed' | 'blocked'): void { this.eventBus.publish({ type: 'prompt.completed', promptId, finishedAt: new Date().toISOString(), reason }); } private publishQueued(record: Record): void { if ((record.message.origin ?? USER_PROMPT_ORIGIN).kind !== 'user') return; - void this.dispatcher.dispatch(new PromptQueued({ agentId: this.scopeContext.agentId, promptId: record.id, content: stripBundledSkillBlocks(record.message), queueLength: this.pending.length })); + this.eventBus.publish({ type: 'prompt.queued', promptId: record.id, content: record.message.content, queueLength: this.pending.length }); } - private publishSubmitted(record: Record, status: 'running' | 'queued'): void { - if ((record.message.origin ?? USER_PROMPT_ORIGIN).kind !== 'user') return; - void this.dispatcher.dispatch(new PromptSubmitted({ agentId: this.scopeContext.agentId, promptId: record.id, userMessageId: record.userMessageId, status, content: stripBundledSkillBlocks(record.message), createdAt: record.createdAt })); - } - private publishStarted(record: Record): void { - if ((record.message.origin ?? USER_PROMPT_ORIGIN).kind !== 'user') return; - void this.dispatcher.dispatch(new PromptStarted({ agentId: this.scopeContext.agentId, promptId: record.id })); - } - private publishAborted(promptId: string): void { void this.dispatcher.dispatch(new PromptAborted({ agentId: this.scopeContext.agentId, promptId, abortedAt: new Date().toISOString() })); } + private publishAborted(promptId: string): void { this.eventBus.publish({ type: 'prompt.aborted', promptId, abortedAt: new Date().toISOString() }); } } function snapshot(item: Record): PromptSnapshot { return { id: item.id, userMessageId: item.userMessageId, createdAt: item.createdAt, state: item.state, message: item.message }; } diff --git a/packages/agent-core-v2/src/agent/prompt/promptStepRequests.ts b/packages/agent-core-v2/src/agent/prompt/promptStepRequests.ts index a432d33e4..f84ede987 100644 --- a/packages/agent-core-v2/src/agent/prompt/promptStepRequests.ts +++ b/packages/agent-core-v2/src/agent/prompt/promptStepRequests.ts @@ -1,8 +1,26 @@ +/** + * `prompt` domain — the `StepRequest` types for prompt, steer, and retry + * steps. + * + * `PromptStepRequest` / `SteerStepRequest` carry an already-built user + * `ContextMessage` (image-compression captions pre-split), apply the image + * format gate as the last funnel before the history, and materialize it + * at pop time — caption reminders first, message second, mirroring the old + * `appendPrompt` ordering. `PromptStepRequest` uses `newTurn`, seeding the + * `turn.prompt` record from its message. `SteerStepRequest` uses + * `activeOrNewTurn`, is mergeable, and survives turn boundaries; it records + * the `turn.steer` wire op on materialization and unregisters itself from the + * service's pending-steer set once settled. `RetryStepRequest` uses `newTurn`: + * it contributes no message and simply drives one more step over the + * existing context. Each is constructed with its collaborators captured — + * these are plain runtime objects, not DI services. + */ + import { USER_PROMPT_ORIGIN, type ContextMessage } from '#/agent/contextMemory/types'; import { newMessageId } from '#/agent/contextMemory/messageId'; import { StepRequest, type StepRequestOptions, type TurnSeed } from '#/agent/loop/stepRequest'; import { gateImageFormatParts } from '#/agent/media/image-compress'; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; +import type { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; abstract class UserMessageStepRequest extends StepRequest { protected readonly message: ContextMessage; @@ -11,7 +29,7 @@ abstract class UserMessageStepRequest extends StepRequest { constructor( message: ContextMessage, private readonly captions: readonly string[], - private readonly reminders: ReminderRuntime, + private readonly reminders: IAgentSystemReminderService, options?: StepRequestOptions, ) { super(options); @@ -29,7 +47,8 @@ abstract class UserMessageStepRequest extends StepRequest { override onWillMaterialize(): void { for (const caption of this.captions) { - this.reminders.notify(caption, { + this.reminders.appendSystemReminder(caption, { + kind: 'injection', variant: 'image_compression', ownerPromptId: this.ownerPromptId, }); @@ -47,17 +66,13 @@ export class PromptStepRequest extends UserMessageStepRequest { constructor( message: ContextMessage, captions: readonly string[], - reminders: ReminderRuntime, + reminders: IAgentSystemReminderService, ) { super(message, captions, reminders, { admission: 'newTurn' }); } override get turnSeed(): TurnSeed { - return { - input: this.message.content, - origin: this.message.origin ?? USER_PROMPT_ORIGIN, - promptId: this.message.id, - }; + return { input: this.message.content, origin: this.message.origin ?? USER_PROMPT_ORIGIN }; } } @@ -67,7 +82,7 @@ export class SteerStepRequest extends UserMessageStepRequest { constructor( message: ContextMessage, captions: readonly string[], - reminders: ReminderRuntime, + reminders: IAgentSystemReminderService, private readonly recordSteer: (message: ContextMessage) => void, private readonly forgetSteer: (request: SteerStepRequest) => void, admission: 'activeTurnOnly' | 'activeOrNewTurn' = 'activeTurnOnly', diff --git a/packages/agent-core-v2/src/agent/replayBuilder/types.ts b/packages/agent-core-v2/src/agent/replayBuilder/types.ts index 97b5ac802..8d4b6b49a 100644 --- a/packages/agent-core-v2/src/agent/replayBuilder/types.ts +++ b/packages/agent-core-v2/src/agent/replayBuilder/types.ts @@ -2,31 +2,15 @@ import type { AgentTaskInfo } from '#/agent/task/task'; import type { CompactionResult } from '#/agent/fullCompaction/types'; import type { AgentConfigData, AgentConfigUpdateData } from '#/agent/profile/profile'; import type { AgentContextData, ContextMessage } from '#/agent/contextMemory/types'; -import type { GoalChange, GoalSnapshot } from '#/features/goal/types'; +import type { GoalChange, GoalSnapshot } from '#/agent/goal/types'; import type { PermissionApprovalResultRecord } from '#/agent/permissionRules/permissionRules'; import type { PermissionData, PermissionMode } from '#/agent/permissionPolicy/types'; import type { PlanData } from '#/features/plan/plan'; import type { ToolInfo } from '#/tool/toolContract'; +import type { SessionSummary } from '#/agent/rpc/core-api'; import type { UsageStatus } from '#/agent/usage/usage'; import type { SessionMeta } from '#/session/sessionMetadata/sessionMetadata'; -export type JsonPrimitive = string | number | boolean | null; -export type JsonValue = JsonPrimitive | JsonValue[] | { readonly [key: string]: JsonValue }; -export type JsonObject = { readonly [key: string]: JsonValue }; - -export interface SessionSummary { - readonly id: string; - readonly title?: string | undefined; - readonly lastPrompt?: string; - readonly workDir: string; - readonly sessionDir: string; - readonly createdAt: number; - readonly updatedAt: number; - readonly archived?: boolean | undefined; - readonly metadata?: JsonObject | undefined; - readonly additionalDirs?: readonly string[]; -} - type AgentType = 'main' | 'sub'; export type AgentReplayRecordPayload = diff --git a/packages/agent-core-v2/src/agent/rpc/core-api.ts b/packages/agent-core-v2/src/agent/rpc/core-api.ts new file mode 100644 index 000000000..f1c68603c --- /dev/null +++ b/packages/agent-core-v2/src/agent/rpc/core-api.ts @@ -0,0 +1,357 @@ +/** + * `rpc` domain — v2 native RPC contract. + * + * Request/response payloads and event types for the engine's native RPC + * surface. `PromptPayload.disabledTools` is the client-managed session + * denylist, applied before the prompt is enqueued: full-replace semantics, the profile's own + * `disallowedTools` always survive, omitting the field keeps the persisted + * value, and `[]` clears the client portion. It is ignored by engines without + * profile support. + */ + +import type { AgentContextData } from '#/agent/contextMemory/types'; +import type { AgentCommandInfo } from '#/agent/command/agentCommand'; +import type { + GoalBudgetLimits, + GoalBudgetReport, + GoalChange, + GoalChangeStats, + GoalSnapshot, + GoalStatus, + GoalToolResult, +} from '#/agent/goal/types'; +import type { PermissionMode } from '#/agent/permissionPolicy/types'; +import type { SwarmModeTrigger } from '#/agent/swarm/swarm'; +import type { ToolDisclosure, ToolInfo } from '#/tool/toolContract'; +import type { ResolvedConfig } from '#/app/config/config'; +import type { ExperimentalFeatureState } from '#/app/flag/flag'; +import type { ResumeSessionResult } from '#/agent/replayBuilder/types'; +import type { SessionMeta } from '#/session/sessionMetadata/sessionMetadata'; +import type { ContentPart } from '#/kosong/contract/message'; +import type { SessionWarning } from '#/app/sessionLegacy/sessionProtocol'; + +import type { ExportSessionPayload, ExportSessionResult } from '#/app/sessionExport/sessionExport'; +import type { PluginCommandDef, PluginInfo, PluginSummary, ReloadSummary } from '#/app/plugin/types'; +import type { WithAgentId, WithSessionId } from './types'; + +export type { ExportSessionManifest, ExportSessionPayload, ExportSessionResult, ShellEnvironment } from '#/app/sessionExport/sessionExport'; + +export type JsonPrimitive = string | number | boolean | null; +export type JsonValue = JsonPrimitive | JsonValue[] | { readonly [key: string]: JsonValue }; +export type JsonObject = { readonly [key: string]: JsonValue }; + +export type Unsubscribe = () => void; + +export type TextPromptPart = Extract<ContentPart, { type: 'text' }>; +export type PromptPart = Extract<ContentPart, { type: 'text' | 'image_url' | 'video_url' }>; + +export type PromptInput = readonly PromptPart[]; + +export type EmptyPayload = {}; +export type SessionMetadataPatch = Partial<Omit<SessionMeta, 'agents'>>; + +export interface ClientTelemetryInfo { + readonly id?: string | undefined; + readonly name?: string | undefined; + readonly version?: string | undefined; + readonly uiMode?: string | undefined; +} + +export interface CreateSessionPayload { + readonly id?: string | undefined; + readonly workDir: string; + readonly model?: string | undefined; + readonly thinking?: string | undefined; + readonly permission?: PermissionMode | undefined; + readonly metadata?: JsonObject | undefined; + readonly additionalDirs?: readonly string[]; + readonly client?: ClientTelemetryInfo | undefined; +} + +export interface CloseSessionPayload { + readonly sessionId: string; +} + +export interface ArchiveSessionPayload { + readonly sessionId: string; +} + +export interface ResumeSessionPayload { + readonly sessionId: string; + readonly additionalDirs?: readonly string[]; +} + +export interface ReloadSessionPayload { + readonly sessionId: string; + readonly forcePluginSessionStartReminder?: boolean | undefined; +} + +export interface ForkSessionPayload { + readonly sessionId: string; + readonly id?: string; + readonly title?: string; + readonly metadata?: JsonObject; +} + +export interface ListSessionsPayload { + readonly workDir?: string; + readonly sessionId?: string; + readonly includeArchive?: boolean; +} + +export interface CoreInfo { + readonly version: string; +} + +export interface SessionSummary { + readonly id: string; + readonly title?: string | undefined; + readonly lastPrompt?: string; + readonly workDir: string; + readonly sessionDir: string; + readonly createdAt: number; + readonly updatedAt: number; + readonly archived?: boolean | undefined; + readonly metadata?: JsonObject | undefined; + readonly additionalDirs?: readonly string[]; +} + +export interface PromptPayload { + readonly input: readonly ContentPart[]; + readonly disabledTools?: readonly string[]; +} +export interface RunShellCommandPayload { + readonly command: string; + readonly commandId?: string; +} +export interface ShellCommandResult { + readonly stdout: string; + readonly stderr: string; + readonly isError?: boolean; + readonly backgrounded?: boolean; +} +export interface CancelShellCommandPayload { + readonly commandId: string; +} +export interface SteerPayload { + readonly input: readonly ContentPart[]; +} +export interface CancelPayload { + readonly turnId?: number; +} +export interface SetThinkingPayload { + readonly level: string; +} +export interface SetPermissionPayload { + readonly mode: PermissionMode; +} +export interface SetModelPayload { + readonly model: string; +} +export interface SetModelResult { + readonly model: string; + readonly providerName?: string | undefined; +} +export interface CancelPlanPayload { + readonly id?: string; +} +export interface EnterSwarmPayload { + readonly trigger: SwarmModeTrigger; +} +export interface BeginCompactionPayload { + readonly instruction?: string; +} +export interface UndoHistoryPayload { + readonly count: number; +} +export interface RegisterToolPayload { + readonly name: string; + readonly description: string; + readonly parameters: Record<string, unknown>; + readonly disclosure?: ToolDisclosure; +} +export interface UnregisterToolPayload { + readonly name: string; +} +export interface SetActiveToolsPayload { + readonly names: readonly string[]; +} +export interface StopTaskPayload { + readonly taskId: string; + readonly reason?: string; +} +export interface DetachTaskPayload { + readonly taskId: string; +} +export interface GetTaskOutputPayload { + readonly taskId: string; + readonly tail?: number; +} +export interface GetTasksPayload { + readonly activeOnly?: boolean; + readonly limit?: number; +} +export interface SkillSummary { + readonly name: string; + readonly description: string; + readonly path: string; + readonly source: 'builtin' | 'user' | 'extra' | 'project'; + readonly type?: string | undefined; + readonly disableModelInvocation?: boolean | undefined; + readonly isSubSkill?: boolean | undefined; +} + +export interface ActivateSkillPayload { + readonly name: string; + readonly args?: string | undefined; +} + +export interface ActivatePluginCommandPayload { + readonly pluginId: string; + readonly commandName: string; + readonly args?: string | undefined; +} + +export interface RunCommandPayload { + readonly name: string; + readonly args?: string | undefined; +} + +export interface McpServerInfo { + readonly name: string; + readonly transport: 'stdio' | 'http' | 'sse'; + readonly status: 'pending' | 'connected' | 'failed' | 'disabled' | 'needs-auth' | 'removed'; + readonly toolCount: number; + readonly error?: string; +} + +export interface McpStartupMetrics { + readonly durationMs: number; +} + +export interface ReconnectMcpServerPayload { + readonly name: string; +} + +export interface InstallPluginPayload { + readonly source: string; +} + +export interface SetPluginEnabledPayload { + readonly id: string; + readonly enabled: boolean; +} + +export interface SetPluginMcpServerEnabledPayload { + readonly id: string; + readonly server: string; + readonly enabled: boolean; +} + +export interface RemovePluginPayload { + readonly id: string; +} + +export interface GetPluginInfoPayload { + readonly id: string; +} + +export type ReloadPluginsResult = ReloadSummary; +export type { PluginSummary, PluginInfo }; + +export interface RenameSessionPayload { + readonly title: string; +} + +export interface UpdateSessionMetadataPayload { + readonly metadata: SessionMetadataPatch; +} + +export type { + GoalBudgetLimits, + GoalBudgetReport, + GoalChange, + GoalChangeStats, + GoalSnapshot, + GoalStatus, + GoalToolResult, +}; + +export interface CreateGoalPayload { + readonly objective: string; + readonly replace?: boolean; +} + +export interface GetKimiConfigPayload { + readonly reload?: boolean; +} + +export interface ConfigDiagnostics { + readonly warnings: readonly string[]; +} + +export type SetKimiConfigPayload = ResolvedConfig; + +export interface RemoveKimiProviderPayload { + readonly providerId: string; +} + +export interface PromptLaunchResult { + readonly turn_id: number; +} + +export interface AgentAPI { + prompt: (payload: PromptPayload) => PromptLaunchResult | undefined; + steer: (payload: SteerPayload) => PromptLaunchResult | undefined; + cancel: (payload: CancelPayload) => void; + undoHistory: (payload: UndoHistoryPayload) => Promise<number>; + setPermission: (payload: SetPermissionPayload) => void; + cancelCompaction: (payload: EmptyPayload) => void; + activateSkill: (payload: ActivateSkillPayload) => PromptLaunchResult | undefined; + activatePluginCommand: (payload: ActivatePluginCommandPayload) => void; + listCommands: (payload: EmptyPayload) => readonly AgentCommandInfo[]; + runCommand: (payload: RunCommandPayload) => Promise<void>; + getContext: (payload: EmptyPayload) => AgentContextData; + getTools: (payload: EmptyPayload) => readonly ToolInfo[]; +} + +type AgentAPIWithId = WithAgentId<AgentAPI>; + +export interface SessionAPI extends AgentAPIWithId { + renameSession: (payload: RenameSessionPayload) => void; + updateSessionMetadata: (payload: UpdateSessionMetadataPayload) => void; + getSessionMetadata: (payload: EmptyPayload) => SessionMeta; + listSkills: (payload: EmptyPayload) => readonly SkillSummary[]; + listPluginCommands: (payload: EmptyPayload) => readonly PluginCommandDef[]; + listMcpServers: (payload: EmptyPayload) => readonly McpServerInfo[]; + getMcpStartupMetrics: (payload: EmptyPayload) => McpStartupMetrics; + reconnectMcpServer: (payload: ReconnectMcpServerPayload) => void; + generateAgentsMd: (payload: EmptyPayload) => void; + getSessionWarnings: (payload: EmptyPayload) => readonly SessionWarning[]; +} + +type SessionAPIWithId = WithSessionId<SessionAPI>; + +export interface CoreAPI extends SessionAPIWithId { + getCoreInfo: (payload: EmptyPayload) => CoreInfo; + getExperimentalFeatures: (payload: EmptyPayload) => readonly ExperimentalFeatureState[]; + getKimiConfig: (payload: GetKimiConfigPayload) => ResolvedConfig; + getConfigDiagnostics: (payload: EmptyPayload) => ConfigDiagnostics; + setKimiConfig: (payload: SetKimiConfigPayload) => ResolvedConfig; + removeKimiProvider: (payload: RemoveKimiProviderPayload) => ResolvedConfig; + createSession: (payload: CreateSessionPayload) => SessionSummary; + closeSession: (payload: CloseSessionPayload) => void; + archiveSession: (payload: ArchiveSessionPayload) => void; + resumeSession: (payload: ResumeSessionPayload) => ResumeSessionResult; + reloadSession: (payload: ReloadSessionPayload) => ResumeSessionResult; + forkSession: (payload: ForkSessionPayload) => ResumeSessionResult; + listSessions: (payload: ListSessionsPayload) => readonly SessionSummary[]; + exportSession: (payload: ExportSessionPayload) => ExportSessionResult; + listPlugins: (payload: EmptyPayload) => readonly PluginSummary[]; + installPlugin: (payload: InstallPluginPayload) => PluginSummary; + setPluginEnabled: (payload: SetPluginEnabledPayload) => void; + setPluginMcpServerEnabled: (payload: SetPluginMcpServerEnabledPayload) => void; + removePlugin: (payload: RemovePluginPayload) => void; + reloadPlugins: (payload: EmptyPayload) => ReloadPluginsResult; + getPluginInfo: (payload: GetPluginInfoPayload) => PluginInfo; +} diff --git a/packages/agent-core-v2/src/agent/rpc/prompt-metadata.ts b/packages/agent-core-v2/src/agent/rpc/prompt-metadata.ts new file mode 100644 index 000000000..519e2a440 --- /dev/null +++ b/packages/agent-core-v2/src/agent/rpc/prompt-metadata.ts @@ -0,0 +1,84 @@ +/** + * `rpc` domain (Agent) — v1-compatible prompt metadata helpers. + * + * Derives title and last-prompt text from native and legacy prompt payloads, + * persists metadata through `sessionMetadata`, and publishes live updates + * through `event`. + */ + +import type { IEventService } from '#/app/event/event'; +import type { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; + +import { + promptMetadataTextFromContentParts, + promptMetadataTextFromText, + titleFromPromptMetadataText, +} from '#/agent/prompt/promptMetadataText'; + +import type { + ActivatePluginCommandPayload, + ActivateSkillPayload, + PromptPayload, +} from './core-api'; + +export { promptMetadataTextFromContentParts, titleFromPromptMetadataText }; + +export function promptMetadataTextFromPayload(payload: PromptPayload): string | undefined { + return promptMetadataTextFromContentParts(payload.input); +} + +export function promptMetadataTextFromSkill(payload: ActivateSkillPayload): string | undefined { + const args = payload.args?.trim(); + return promptMetadataTextFromText( + args === undefined || args.length === 0 ? `/${payload.name}` : `/${payload.name} ${args}`, + ); +} + +export function promptMetadataTextFromPluginCommand( + payload: ActivatePluginCommandPayload, +): string | undefined { + const args = payload.args?.trim(); + const command = `/${payload.pluginId}:${payload.commandName}`; + return promptMetadataTextFromText( + args === undefined || args.length === 0 ? command : `${command} ${args}`, + ); +} + +export function isUntitled(title: string | undefined): boolean { + return title === undefined || title.trim().length === 0 || title === 'New Session'; +} + +export interface PromptMetadataUpdateTarget { + readonly metadata: ISessionMetadata; + readonly eventService: IEventService; + readonly sessionId: string; +} + +export async function applyPromptMetadataUpdate( + target: PromptMetadataUpdateTarget, + text: string | undefined, +): Promise<void> { + if (text === undefined) return; + const current = await target.metadata.read(); + const patch: { lastPrompt: string; title?: string; isCustomTitle?: boolean } = { + lastPrompt: text, + }; + if (!current.isCustomTitle && isUntitled(current.title)) { + patch.title = titleFromPromptMetadataText(text); + patch.isCustomTitle = false; + } + await target.metadata.update(patch); + target.eventService.publish({ + type: 'session.meta.updated', + payload: { + agentId: 'main', + sessionId: target.sessionId, + title: patch.title, + patch: { + title: patch.title, + isCustomTitle: patch.isCustomTitle, + lastPrompt: text, + }, + }, + }); +} diff --git a/packages/agent-core-v2/src/agent/rpc/rpc.ts b/packages/agent-core-v2/src/agent/rpc/rpc.ts new file mode 100644 index 000000000..66115e906 --- /dev/null +++ b/packages/agent-core-v2/src/agent/rpc/rpc.ts @@ -0,0 +1,20 @@ +import { createDecorator } from "#/_base/di/instantiation"; +import type { + AgentAPI, + SessionAPI, +} from './core-api'; +import type { PromisableMethods } from "#/_base/utils/types"; + +export interface IAgentRPCService extends PromisableMethods<AgentAPI> { + readonly _serviceBrand: undefined; +} + +export interface ISessionRPCService extends PromisableMethods<SessionAPI> { + readonly _serviceBrand: undefined; +} + +export const IAgentRPCService = + createDecorator<IAgentRPCService>('agentRPCService'); + +export const ISessionRPCService = + createDecorator<ISessionRPCService>('agentSessionRPCService'); diff --git a/packages/agent-core-v2/src/agent/rpc/rpcService.ts b/packages/agent-core-v2/src/agent/rpc/rpcService.ts new file mode 100644 index 000000000..87e8005ac --- /dev/null +++ b/packages/agent-core-v2/src/agent/rpc/rpcService.ts @@ -0,0 +1,281 @@ +import { randomUUID } from 'node:crypto'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; +import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; +import { IEventBus } from '#/app/event/eventBus'; +import { IEventService } from '#/app/event/event'; +import { ErrorCodes, Error2, isError2 } from '#/errors'; +import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; +import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; +import { + IAgentLifecycleService, + MAIN_AGENT_ID, +} from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentCommandService } from '#/agent/command/agentCommand'; +import { expandCommandArguments } from '#/app/plugin/commands'; +import { IPluginService } from '#/app/plugin/plugin'; +import { ProfileError } from '#/agent/profile/profile'; +import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; +import { IAgentPromptService } from '#/agent/prompt/prompt'; +import { IAgentConversationUndoService } from '#/agent/undo/undo'; +import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; +import { IAgentSkillService } from '#/agent/skill/skill'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; +import { IAgentLoopService } from '#/agent/loop/loop'; +import type { + ActivatePluginCommandPayload, + ActivateSkillPayload, + CancelPayload, + EmptyPayload, + PromptLaunchResult, + PromptPayload, + RunCommandPayload, + SetPermissionPayload, + SteerPayload, + UndoHistoryPayload, +} from './core-api'; +import { IAgentRPCService } from './rpc'; +import { + applyPromptMetadataUpdate, + promptMetadataTextFromPayload, + promptMetadataTextFromPluginCommand, + promptMetadataTextFromSkill, +} from './prompt-metadata'; + +export interface PluginCommandActivatedEvent { + readonly type: 'plugin_command.activated'; + readonly activationId: string; + readonly pluginId: string; + readonly commandName: string; + readonly commandArgs?: string; + readonly trigger: 'user-slash'; +} + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'plugin_command.activated': PluginCommandActivatedEvent; + } +} + +export class AgentRPCService implements IAgentRPCService { + declare readonly _serviceBrand: undefined; + + constructor( + @IAgentPromptService private readonly promptService: IAgentPromptService, + @IAgentConversationUndoService + private readonly conversationUndo: IAgentConversationUndoService, + @IAgentLoopService private readonly loop: IAgentLoopService, + @IAgentToolPolicyService private readonly toolPolicy: IAgentToolPolicyService, + @IAgentPermissionModeService private readonly permissionMode: IAgentPermissionModeService, + @IAgentFullCompactionService private readonly fullCompaction: IAgentFullCompactionService, + @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, + @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, + @IAgentTokenCountingService private readonly tokenCounting: IAgentTokenCountingService, + @IAgentSkillService private readonly skills: IAgentSkillService, + @ITelemetryService private readonly telemetry: ITelemetryService, + @IEventBus private readonly eventBus: IEventBus, + @IEventService private readonly eventService: IEventService, + @IPluginService private readonly plugins: IPluginService, + @ISessionMetadata private readonly metadata: ISessionMetadata, + @ISessionContext private readonly sessionContext: ISessionContext, + @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentCommandService private readonly commands: IAgentCommandService, + ) { } + + async prompt(payload: PromptPayload): Promise<PromptLaunchResult | undefined> { + if (payload.disabledTools !== undefined) { + try { + await this.toolPolicy.setSessionDisabledTools(payload.disabledTools); + } catch (error) { + if (error instanceof ProfileError) { + throw new Error2(ErrorCodes.REQUEST_INVALID, error.message); + } + throw error; + } + } + await this.updatePromptMetadata(promptMetadataTextFromPayload(payload)); + const handle = await this.promptService.enqueue({ message: { + role: 'user', + content: [...payload.input], + toolCalls: [], + origin: { kind: 'user' }, + } }); + if (handle.state === 'pending') return undefined; + const turn = await handle.launched; + return turn === undefined ? undefined : { turn_id: turn.id }; + } + + async steer(payload: SteerPayload): Promise<PromptLaunchResult | undefined> { + this.telemetry.track2('input_steer', { parts: payload.input.length }); + if (this.scopeContext.agentId === MAIN_AGENT_ID) { + // A steer is user input like a prompt — and can even launch the + // session's first turn (e.g. goal mode) — so keep title/lastPrompt in + // sync the same way, matching v1. + await this.updatePromptMetadata(promptMetadataTextFromPayload(payload)); + } + const queued = await this.promptService.enqueue({ message: { + role: 'user', + content: [...payload.input], + toolCalls: [], + } }); + if (queued.state !== 'pending') { + // No active prompt at enqueue time, so the enqueue itself already + // launched this input as its own turn (idle session, or a goal-turn + // boundary where the previous turn just ended) — v1's + // steer-degrades-to-launch end state. Return that turn instead of + // rejecting on a steer-by-id that can never find the record pending. + const turn = await queued.launched; + return turn === undefined ? undefined : { turn_id: turn.id }; + } + try { + const [steered] = await this.promptService.steer([queued.id]); + const turn = await steered?.launched; + return turn === undefined ? undefined : { turn_id: turn.id }; + } catch (error) { + // Pending but nothing active to steer into (a manual compaction holds + // the context): the message stays queued and launches once compaction + // finishes, so report it as queued rather than failing the steer. + if (isError2(error) && error.code === ErrorCodes.PROMPT_NOT_FOUND) return undefined; + throw error; + } + } + + cancel({ turnId }: CancelPayload): void { + if (this.loop.status().state === 'running') { + this.telemetry.track2('cancel', { + from: 'streaming', + trace_id: this.loop.status().activeTraceId, + }); + } + this.loop.cancel(turnId); + } + + async undoHistory(payload: UndoHistoryPayload): Promise<number> { + return this.conversationUndo.undo(payload.count); + } + + setPermission(payload: SetPermissionPayload): void { + const wasYolo = this.permissionMode.mode === 'yolo'; + const wasAuto = this.permissionMode.mode === 'auto'; + this.permissionMode.setMode(payload.mode); + if (this.scopeContext.agentId === MAIN_AGENT_ID) { + this.agentLifecycle.broadcastPermissionMode(payload.mode); + } + const enabled = this.permissionMode.mode === 'yolo'; + if (enabled !== wasYolo) { + this.telemetry.track2('yolo_toggle', { enabled }); + } + const afkEnabled = this.permissionMode.mode === 'auto'; + if (afkEnabled !== wasAuto) { + this.telemetry.track2('afk_toggle', { enabled: afkEnabled }); + } + } + + cancelCompaction(_payload: EmptyPayload): void { + const active = this.fullCompaction.compacting; + if (active !== null) { + this.telemetry.track2('cancel', { + from: 'compacting', + trace_id: active.traceId, + }); + } + active?.abortController.abort(); + } + + async activateSkill(payload: ActivateSkillPayload): Promise<PromptLaunchResult | undefined> { + // Awaited (not fire-and-forget): the caller gets the launched turn id and + // activation failures (unknown skill, busy) surface instead of vanishing. + const turn = await this.skills.activate(payload); + await this.updatePromptMetadata(promptMetadataTextFromSkill(payload)); + return { turn_id: turn.id }; + } + + async activatePluginCommand(payload: ActivatePluginCommandPayload): Promise<void> { + const commands = await this.plugins.listPluginCommands(); + const def = commands.find( + (command) => command.pluginId === payload.pluginId && command.name === payload.commandName, + ); + if (def === undefined) { + throw new Error2( + ErrorCodes.REQUEST_INVALID, + `Plugin command "${payload.pluginId}:${payload.commandName}" was not found`, + ); + } + const commandArgs = payload.args ?? ''; + const expanded = expandCommandArguments(def.body, commandArgs); + const origin = { + kind: 'plugin_command' as const, + activationId: randomUUID(), + pluginId: payload.pluginId, + commandName: payload.commandName, + commandArgs: payload.args, + trigger: 'user-slash' as const, + }; + this.eventBus.publish({ + type: 'plugin_command.activated', + activationId: origin.activationId, + pluginId: origin.pluginId, + commandName: origin.commandName, + commandArgs: origin.commandArgs, + trigger: origin.trigger, + }); + await this.promptService.enqueue({ message: { + role: 'user', + content: [{ type: 'text', text: expanded }], + toolCalls: [], + origin, + } }); + await this.updatePromptMetadata(promptMetadataTextFromPluginCommand(payload)); + } + + private async updatePromptMetadata(text: string | undefined): Promise<void> { + await applyPromptMetadataUpdate( + { + metadata: this.metadata, + eventService: this.eventService, + sessionId: this.sessionContext.sessionId, + }, + text, + ); + } + + getContext(_payload: EmptyPayload) { + return { + history: this.context.get(), + // The externally reported context size, resolved by the + // `[token_counting]` strategy inside the service — matching the v1 + // `context.tokenCount` semantics. + tokenCount: this.tokenCounting.statusSize(), + }; + } + + listCommands(_payload: EmptyPayload) { + return this.commands.list(); + } + + async runCommand(payload: RunCommandPayload): Promise<void> { + return this.commands.run(payload.name, payload.args); + } + + getTools(_payload: EmptyPayload) { + return this.toolRegistry.list().map((tool) => ({ + name: tool.name, + description: tool.description, + active: this.toolPolicy.isToolActive(tool.name, tool.source), + source: tool.source, + })); + } +} + +registerScopedService( + LifecycleScope.Agent, + IAgentRPCService, + AgentRPCService, + ScopeActivation.OnScopeCreated, + 'rpc', +); diff --git a/packages/agent-core-v2/src/agent/rpc/types.ts b/packages/agent-core-v2/src/agent/rpc/types.ts new file mode 100644 index 000000000..fb661f597 --- /dev/null +++ b/packages/agent-core-v2/src/agent/rpc/types.ts @@ -0,0 +1,11 @@ +/** + * `rpc` domain (L8) — shared request wrapper types. + */ + +export type WithSessionId<T = {}> = T & { + readonly sessionId: string; +}; + +export type WithAgentId<T = {}> = T & { + readonly agentId: string; +}; diff --git a/packages/agent-core-v2/src/agent/runtime/agentRuntime.ts b/packages/agent-core-v2/src/agent/runtime/agentRuntime.ts deleted file mode 100644 index d559a82c7..000000000 --- a/packages/agent-core-v2/src/agent/runtime/agentRuntime.ts +++ /dev/null @@ -1,156 +0,0 @@ -import type { - ActorLogic, - AnyActorRef, - Snapshot, -} from 'xstate'; - -import { collection } from '#/_base/di/collection'; -import type { ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { registerEvent2Class, type Event2, type Event2Class } from '#/app/event/event2'; -import type { StateFold } from '#/state/state'; - -export type AgentRuntimeStatus = 'registered' | 'materialized' | 'done' | 'failed' | 'retired'; - -export interface AgentRuntimeIdentity { - readonly agentId: string; - readonly generation: number; -} - -export interface AgentRuntimeContext<State> { - readonly agent: AgentContext; - get<T>(id: ServiceIdentifier<T>): T; - getState(): State; - getLogicState<T>(): T; - dispatch(event: Event2<any>): Promise<void>; - send(event: unknown): void; - readonly onDidChange: Event<State>; -} - -export interface AgentRuntimeRestoreEvent { - readonly type: 'runtime.restore'; - waitUntil(work: Promise<unknown>): void; -} - -export interface AgentRuntimeDurableDefinition<State> { - readonly events: readonly Event2Class<any, any>[]; - readonly undoable: boolean; - readonly transition: StateFold<State>; - read(snapshot: Snapshot<unknown>): State; - commit(actor: AnyActorRef, state: State): void; -} - -const runtimeType = Symbol('agentRuntimeType'); - -export interface AgentRuntimeDefinition<StateOrRuntime, Runtime = StateOrRuntime> { - readonly [runtimeType]: Runtime; -} - -export interface AgentRuntimeDescriptor<State, Runtime> { - readonly id: string; - readonly logic?: ActorLogic<any, any, any>; - readonly input?: unknown; - readonly durable?: AgentRuntimeDurableDefinition<State>; - readonly eager?: boolean; - readonly createApi: (context: AgentRuntimeContext<State>) => Runtime; - readonly inspect?: (snapshot: Snapshot<unknown>) => unknown; -} - -export interface AgentRuntimeProvider<Runtime> { - readonly contract: AgentRuntimeDefinition<Runtime>; -} - -const descriptors = new WeakMap<object, AgentRuntimeDescriptor<any, any>>(); -const definitionIds = new WeakMap<object, string>(); - -export type RuntimeOf<Definition> = - Definition extends AgentRuntimeDefinition<any, infer Runtime> ? Runtime : never; - -export function defineAgentRuntimeContract<Runtime>(id: string): AgentRuntimeDefinition<Runtime> { - const definition = Object.freeze({}) as AgentRuntimeDefinition<Runtime>; - definitionIds.set(definition, id); - return definition; -} - -export function defineAgentRuntimeProvider<State, Runtime>( - contract: AgentRuntimeDefinition<Runtime>, - descriptor: AgentRuntimeDescriptor<State, Runtime>, -): AgentRuntimeProvider<Runtime> { - assertLogicPresent(descriptor); - for (const cls of descriptor.durable?.events ?? []) registerEvent2Class(cls); - const provider = Object.freeze({ contract }) as AgentRuntimeProvider<Runtime>; - descriptors.set(provider, descriptor); - return provider; -} - -function assertLogicPresent(descriptor: AgentRuntimeDescriptor<any, any>): void { - if (descriptor.durable !== undefined && descriptor.logic === undefined) { - throw new Error(`Agent runtime '${descriptor.id}' declares durable state without logic`); - } -} - -export function getAgentRuntimeDefinitionId( - definition: AgentRuntimeDefinition<any>, -): string { - const id = definitionIds.get(definition); - if (id === undefined) throw new Error('Unknown agent runtime definition'); - return id; -} - -export function getAgentRuntimeDescriptor( - provider: AgentRuntimeProvider<any>, -): AgentRuntimeDescriptor<any, any> { - const descriptor = descriptors.get(provider); - if (descriptor === undefined) throw new Error('Unknown agent runtime provider'); - return descriptor; -} - -export type AgentRuntimeContribution = AgentRuntimeProvider<any>; - -const validateRuntimeContribution = (value: AgentRuntimeContribution, existing: readonly AgentRuntimeContribution[]): void => { - const id = getAgentRuntimeDefinitionId(value.contract); - if (existing.some((item) => getAgentRuntimeDefinitionId(item.contract) === id)) { - throw new Error(`Agent runtime '${id}' already has an active provider`); - } -}; - -export const AgentRuntimeContributionPoint = collection<AgentRuntimeContribution>( - 'agent-runtime', - { validate: validateRuntimeContribution }, -); - -export const AgentRuntimeOverrideContributionPoint = collection<AgentRuntimeContribution>( - 'agent-runtime-override', - { validate: validateRuntimeContribution }, -); - -export interface AgentRuntimeDefinitionRecord { - readonly definition: AgentRuntimeDefinition<any>; - readonly provider: AgentRuntimeProvider<any>; - readonly generation: number; - readonly providerGeneration?: number; - active: boolean; -} - -export interface AgentRuntimeContributionSnapshot { - readonly id: string; - readonly generation: number; - readonly status: AgentRuntimeStatus; - readonly state?: unknown; - readonly error?: string; -} - -export interface AgentRuntimeSnapshot { - readonly identity: AgentRuntimeIdentity; - readonly contributions: readonly AgentRuntimeContributionSnapshot[]; -} - -export interface DurableAgentRuntimeParticipant<State = any> { - readonly id: string; - readonly events: readonly Event2Class<any, any>[]; - readonly undoable: boolean; - readonly transition: StateFold<State>; - getState(): State; - commit(state: State): void; -} diff --git a/packages/agent-core-v2/src/agent/runtime/agentRuntimeSet.ts b/packages/agent-core-v2/src/agent/runtime/agentRuntimeSet.ts deleted file mode 100644 index 374a3de27..000000000 --- a/packages/agent-core-v2/src/agent/runtime/agentRuntimeSet.ts +++ /dev/null @@ -1,327 +0,0 @@ -import { createActor, type AnyActorRef } from 'xstate'; - -import type { ServicesAccessor } from '#/_base/di/instantiation'; -import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import { BugIndicatingError } from '#/_base/errors/errors'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { IEventDispatcher, type DurableRuntimeParticipantHost } from '#/state/eventDispatcher'; - -import { - type AgentRuntimeContext, - type AgentRuntimeContributionSnapshot, - type AgentRuntimeDefinition, - type AgentRuntimeDefinitionRecord, - type AgentRuntimeDescriptor, - type AgentRuntimeRestoreEvent, - type AgentRuntimeStatus, - type DurableAgentRuntimeParticipant, - getAgentRuntimeDefinitionId, - getAgentRuntimeDescriptor, - type RuntimeOf, -} from './agentRuntime'; - -interface RuntimeEntry { - record: AgentRuntimeDefinitionRecord; - descriptor: AgentRuntimeDescriptor<any, any>; - status: AgentRuntimeStatus; - actor?: AnyActorRef; - runtime?: unknown; - listeners?: Set<(state: any) => void>; - subscription?: { unsubscribe(): void }; - attachment?: IDisposable; - retiring: boolean; - retired: boolean; - error?: unknown; - context?: AgentRuntimeContext<any>; - restored: boolean; - restorePromise?: Promise<void>; -} - -export class AgentRuntimeSet { - private readonly entries = new Map<string, RuntimeEntry>(); - private readonly graveyard = new Set<RuntimeEntry>(); - private durableHost: DurableRuntimeParticipantHost | undefined; - private restored = false; - private closed = false; - - constructor( - private readonly agent: AgentContext, - private readonly accessor: ServicesAccessor, - ) {} - - apply(record: AgentRuntimeDefinitionRecord): void { - if (this.closed) return; - const descriptor = getAgentRuntimeDescriptor(record.provider); - const existing = this.entries.get(descriptor.id); - if (existing !== undefined) { - if (existing.record === record) return; - this.entries.delete(descriptor.id); - this.graveyard.add(existing); - this.retireEntry(existing); - } - const entry: RuntimeEntry = { - record, - descriptor, - status: 'registered', - retiring: false, - retired: false, - restored: false, - }; - this.entries.set(descriptor.id, entry); - if (this.durableHost === undefined) return; - if (descriptor.durable !== undefined) { - this.attachDurableEntry(entry, this.durableHost); - } else if (descriptor.eager === true) { - this.runtime(entry); - } - } - - retireDefinition(record: AgentRuntimeDefinitionRecord): void { - const id = getAgentRuntimeDefinitionId(record.definition); - const entry = this.entries.get(id); - if (entry === undefined || entry.record !== record) return; - this.entries.delete(id); - this.graveyard.add(entry); - this.retireEntry(entry); - } - - resolve<Definition extends AgentRuntimeDefinition<any, any>>( - definition: Definition, - ): RuntimeOf<Definition> { - if (this.closed) { - throw new Error( - `Agent ${this.agent.agentId}:${String(this.agent.generation)} runtime set is closed`, - ); - } - const id = getAgentRuntimeDefinitionId(definition); - const entry = this.entries.get(id); - if (entry === undefined || entry.record.definition !== definition || !entry.record.active) { - throw new Error(`Agent runtime '${id}' is unavailable`); - } - if (entry.status === 'failed') throw entry.error; - return this.runtime(entry) as RuntimeOf<Definition>; - } - - attachDurable(host: DurableRuntimeParticipantHost): void { - if (this.closed) return; - this.durableHost = host; - for (const entry of this.entries.values()) { - if (entry.descriptor.durable === undefined) { - if (entry.descriptor.eager === true) this.runtime(entry); - continue; - } - this.attachDurableEntry(entry, host); - } - } - - async restore(): Promise<void> { - if (this.closed) return; - this.restored = true; - await Promise.all( - [...this.entries.values()] - .filter((entry) => entry.actor !== undefined) - .map((entry) => this.restoreEntry(entry)), - ); - } - - private restoreEntry(entry: RuntimeEntry): Promise<void> { - if (entry.restored) return entry.restorePromise ?? Promise.resolve(); - const readiness: Promise<unknown>[] = []; - const event: AgentRuntimeRestoreEvent = { - type: 'runtime.restore', - waitUntil: (work) => { readiness.push(work); }, - }; - try { - entry.actor!.send(event); - entry.restorePromise = Promise.all(readiness).then(() => undefined).catch((error: unknown) => { - entry.status = 'failed'; - entry.error = error; - throw error; - }); - } catch (error) { - entry.status = 'failed'; - entry.error = error; - entry.restorePromise = Promise.reject(error); - void entry.restorePromise.catch(() => undefined); - } - entry.restored = true; - return entry.restorePromise; - } - - inspect(): readonly AgentRuntimeContributionSnapshot[] { - const out: AgentRuntimeContributionSnapshot[] = []; - for (const entry of this.entries.values()) out.push(this.line(entry)); - for (const entry of this.graveyard) { - if (this.entries.has(entry.descriptor.id)) continue; - out.push(this.line(entry)); - } - return out; - } - - close(): Promise<void> { - this.closed = true; - for (const entry of this.entries.values()) this.retireEntry(entry); - return Promise.resolve(); - } - - private runtime(entry: RuntimeEntry): unknown { - if (entry.runtime !== undefined) return entry.runtime; - this.materialize(entry); - const context = entry.context!; - try { - const runtime = entry.descriptor.createApi(context); - entry.runtime = runtime; - return runtime; - } catch (error) { - entry.status = 'failed'; - entry.error = error; - this.disposeRuntimeResources(entry); - throw error; - } - } - - private materialize(entry: RuntimeEntry): void { - if (entry.actor !== undefined) return; - if (this.closed || entry.retiring) { - throw new Error(`Agent runtime '${entry.descriptor.id}' is unavailable`); - } - const descriptor = entry.descriptor; - const listeners = new Set<(state: any) => void>(); - entry.listeners = listeners; - entry.context = { - agent: this.agent, - get: (id) => this.accessor.get(id), - getState: () => { - if (descriptor.durable === undefined) { - throw new BugIndicatingError(`Agent runtime '${entry.descriptor.id}' has no durable state`); - } - return descriptor.durable.read(entry.actor!.getSnapshot()); - }, - getLogicState: <T>() => entry.actor!.getSnapshot().context as T, - dispatch: (event) => this.accessor.get(IEventDispatcher).dispatch(event), - send: (event) => { entry.actor!.send(event); }, - onDidChange: (listener) => { - listeners.add(listener); - return toDisposable(() => { listeners.delete(listener); }); - }, - }; - try { - const logic = descriptor.logic; - if (logic === undefined) { - if (entry.status === 'registered') entry.status = 'materialized'; - return; - } - const actor = createActor(logic, { input: descriptor.input ?? entry.context }); - entry.actor = actor; - entry.listeners = listeners; - let previous: unknown; - entry.subscription = actor.subscribe({ - next: (snapshot) => { - if (snapshot.status === 'done') entry.status = 'done'; - if (snapshot.status === 'error') { - entry.status = 'failed'; - entry.error = snapshot.error; - } - if (descriptor.durable === undefined) return; - const next = descriptor.durable.read(snapshot); - if (Object.is(previous, next)) return; - if (previous !== undefined) { - for (const listener of listeners) listener(next); - } - previous = next; - }, - error: (error) => { - entry.status = 'failed'; - entry.error = error; - }, - }); - actor.start(); - previous = descriptor.durable?.read(actor.getSnapshot()); - if (entry.status === 'registered') entry.status = 'materialized'; - if (this.restored) { - void this.restoreEntry(entry).catch((error: unknown) => { - entry.status = 'failed'; - entry.error = error; - }); - } - } catch (error) { - entry.status = 'failed'; - entry.error = error; - entry.subscription?.unsubscribe(); - entry.actor?.stop(); - entry.subscription = undefined; - entry.actor = undefined; - throw error; - } - } - - private attachDurableEntry(entry: RuntimeEntry, host: DurableRuntimeParticipantHost): void { - if (entry.attachment !== undefined) return; - this.materialize(entry); - const descriptor = entry.descriptor; - const durable = descriptor.durable!; - const actor = entry.actor!; - const participant: DurableAgentRuntimeParticipant = { - id: entry.descriptor.id, - events: durable.events, - undoable: durable.undoable, - transition: durable.transition, - getState: () => durable.read(actor.getSnapshot()), - commit: (state) => { durable.commit(actor, state); }, - }; - entry.attachment = host.attach(participant); - if (descriptor.eager === true) this.runtime(entry); - } - - private retireEntry(entry: RuntimeEntry): void { - if (entry.retiring) return; - entry.retiring = true; - this.stopEntry(entry); - } - - private stopEntry(entry: RuntimeEntry): void { - if (entry.retired) return; - entry.retired = true; - entry.status = 'retired'; - this.disposeRuntimeResources(entry); - } - - private disposeRuntimeResources(entry: RuntimeEntry): void { - entry.attachment?.dispose(); - entry.attachment = undefined; - entry.subscription?.unsubscribe(); - entry.actor?.stop(); - entry.subscription = undefined; - entry.actor = undefined; - entry.runtime = undefined; - entry.listeners = undefined; - entry.context = undefined; - entry.restored = false; - } - - private line(entry: RuntimeEntry): AgentRuntimeContributionSnapshot { - return { - id: entry.descriptor.id, - generation: entry.record.generation, - status: entry.status, - state: entry.actor === undefined ? undefined : this.project(entry.descriptor, entry.actor), - error: serializeError(entry.error), - }; - } - - private project( - descriptor: AgentRuntimeDescriptor<any, any>, - actor: AnyActorRef, - ): unknown { - const snapshot = actor.getSnapshot(); - if (descriptor.inspect !== undefined) return descriptor.inspect(snapshot); - return descriptor.durable?.read(snapshot); - } -} - -function serializeError(error: unknown): string | undefined { - if (error === undefined) return undefined; - if (error instanceof Error) return error.message; - if (typeof error === 'string') return error; - return 'Unknown runtime error'; -} diff --git a/packages/agent-core-v2/src/agent/runtimeBinding/agentRuntime.ts b/packages/agent-core-v2/src/agent/runtimeBinding/agentRuntime.ts deleted file mode 100644 index 8fe5b7714..000000000 --- a/packages/agent-core-v2/src/agent/runtimeBinding/agentRuntime.ts +++ /dev/null @@ -1,126 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { Emitter, type Event } from '#/_base/event'; -import type { IDisposable } from '#/_base/di/lifecycle'; -import { LifecycleScope } from '#/app/scopes'; -import type { Runtime, RuntimeBinding, RuntimeCapability, RuntimeLease } from '#/runtime/runtime'; -import { runtimeStatusAllows, type RuntimeGenerationSnapshot } from '#/runtime/runtimeRegistry'; -import { - IRuntimeResolver, - IWorkspaceInstanceManager, -} from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import { IAgentRuntimeBindingService } from './runtimeBinding'; - -export interface AgentRuntimeBindingSnapshot { - readonly binding: RuntimeBinding; - readonly available: boolean; - readonly runtime?: RuntimeGenerationSnapshot; -} - -export interface IAgentRuntimeService { - readonly _serviceBrand: undefined; - readonly onDidChange: Event<void>; - inspect(): Runtime; - isAvailable(required?: readonly RuntimeCapability[]): boolean; - acquire(required?: readonly RuntimeCapability[]): RuntimeLease; -} - -export const IAgentRuntimeService: ServiceIdentifier<IAgentRuntimeService> = - createDecorator<IAgentRuntimeService>('agentRuntimeService'); - -export function inspectAgentRuntime(service: IAgentRuntimeService): Runtime { - return service.inspect(); -} - -export function snapshotAgentRuntimeBinding( - bindingService: IAgentRuntimeBindingService, - runtimeService: IAgentRuntimeService, -): AgentRuntimeBindingSnapshot { - const binding = bindingService.current; - try { - const runtime = runtimeService.inspect(); - return { - binding, - available: runtimeService.isAvailable(), - runtime: { - runtimeId: runtime.identity.runtimeId, - generation: runtime.identity.generation, - status: runtime.status, - capabilities: [...runtime.capabilities], - }, - }; - } catch { - return { binding, available: false }; - } -} - -export class AgentRuntimeService implements IAgentRuntimeService { - declare readonly _serviceBrand: undefined; - private readonly changeEmitter = new Emitter<void>(); - readonly onDidChange = this.changeEmitter.event; - private readonly bindingSubscription: IDisposable; - private readonly workspaceSubscription: IDisposable; - private registrySubscription: IDisposable | undefined; - - constructor( - @IAgentRuntimeBindingService private readonly binding: IAgentRuntimeBindingService, - @IRuntimeResolver private readonly resolver: IRuntimeResolver, - @IWorkspaceInstanceManager private readonly workspaces: IWorkspaceInstanceManager, - ) { - this.bindingSubscription = this.binding.onDidChange(() => this.rebind()); - this.workspaceSubscription = this.workspaces.onDidChange((change) => { - if (change.workspaceId === this.binding.current.workspaceId) this.rebind(); - }); - this.bindRegistry(); - } - - inspect(): Runtime { - return this.resolver.inspect(this.binding.current); - } - - isAvailable(required: readonly RuntimeCapability[] = []): boolean { - try { - const runtime = this.inspect(); - return runtimeStatusAllows(runtime, required) && required.every((capability) => runtime.capabilities.has(capability)); - } catch { - return false; - } - } - - acquire(required: readonly RuntimeCapability[] = []): RuntimeLease { - return this.resolver.acquire(this.binding.current, required); - } - - dispose(): void { - this.registrySubscription?.dispose(); - this.workspaceSubscription.dispose(); - this.bindingSubscription.dispose(); - this.changeEmitter.dispose(); - } - - private rebind(): void { - this.bindRegistry(); - this.changeEmitter.fire(); - } - - private bindRegistry(): void { - this.registrySubscription?.dispose(); - const binding = this.binding.current; - const workspace = this.workspaces.get(binding.workspaceId); - this.registrySubscription = workspace?.runtimes.onDidChange((change) => { - if (change.runtimeId !== this.binding.current.runtimeId) return; - const current = workspace.runtimes.current(change.runtimeId); - if (change.current !== undefined && change.current !== current) return; - this.changeEmitter.fire(); - }); - } -} - -registerScopedService( - LifecycleScope.Agent, - IAgentRuntimeService, - AgentRuntimeService, - ScopeActivation.OnDemand, - 'agentRuntimeBinding', -); diff --git a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBinding.ts b/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBinding.ts deleted file mode 100644 index 4af970a4e..000000000 --- a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBinding.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; -import type { RuntimeBinding } from '#/runtime/runtime'; - -export interface IAgentRuntimeBindingService { - readonly _serviceBrand: undefined; - readonly current: RuntimeBinding; - readonly onDidChange: Event<RuntimeBinding>; - get(): RuntimeBinding; - set(binding: RuntimeBinding): RuntimeBinding; - switch(runtimeId: string): RuntimeBinding; -} - -export const IAgentRuntimeBindingService: ServiceIdentifier<IAgentRuntimeBindingService> = createDecorator<IAgentRuntimeBindingService>('agentRuntimeBindingService'); - -export interface IAgentRuntimeBindingSeed { - readonly _serviceBrand: undefined; - readonly binding: RuntimeBinding; -} - -export const IAgentRuntimeBindingSeed: ServiceIdentifier<IAgentRuntimeBindingSeed> = createDecorator<IAgentRuntimeBindingSeed>('agentRuntimeBindingSeed'); diff --git a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingOps.ts b/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingOps.ts deleted file mode 100644 index 62245a875..000000000 --- a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingOps.ts +++ /dev/null @@ -1,29 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; -import type { RuntimeBinding } from '#/runtime/runtime'; -import { defineState } from '#/state/state'; - -const runtimeSetBindingSchema = z.object({ - agentId: z.string(), - workspaceId: z.string(), - runtimeId: z.string(), -}); - -export class RuntimeSetBinding extends AgentEvent2<z.infer<typeof runtimeSetBindingSchema>> { - static override readonly type = 'runtime.set_binding'; - static override readonly durable = true; - static override readonly schema = runtimeSetBindingSchema; -} -export interface RuntimeSetBinding { - readonly agentId: string; - readonly workspaceId: string; - readonly runtimeId: string; -} - -export const runtimeBindingKey = defineState( - 'runtimeBinding', - (): RuntimeBinding | undefined => undefined, -).replayable({ schema: z.custom<RuntimeBinding | undefined>() }) - .on(RuntimeSetBinding, (_s, e) => ({ workspaceId: e.workspaceId, runtimeId: e.runtimeId })); diff --git a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingService.ts b/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingService.ts deleted file mode 100644 index ce369f014..000000000 --- a/packages/agent-core-v2/src/agent/runtimeBinding/runtimeBindingService.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; -import type { IDisposable } from '#/_base/di/lifecycle'; -import { Emitter } from '#/_base/event'; -import { LifecycleScope } from '#/app/scopes'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; -import type { RuntimeBinding } from '#/runtime/runtime'; -import { RuntimeError } from '#/runtime/runtimeRegistry'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import { IAgentRuntimeBindingSeed, IAgentRuntimeBindingService } from './runtimeBinding'; -import { RuntimeSetBinding, runtimeBindingKey } from './runtimeBindingOps'; - -export const agentRuntimeBindingKey = defineState<RuntimeBinding>('runtime.binding', () => ({ workspaceId: '', runtimeId: 'local' })); - -export class AgentRuntimeBindingService implements IAgentRuntimeBindingService { - declare readonly _serviceBrand: undefined; - private readonly changeEmitter = new Emitter<RuntimeBinding>(); - readonly onDidChange = this.changeEmitter.event; - private readonly restoreHook: IDisposable; - - constructor( - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IAgentStateService private readonly state: IAgentStateService, - @IAgentRuntimeBindingSeed seed: IAgentRuntimeBindingSeed, - @ISessionContext private readonly session: ISessionContext, - @IRuntimeResolver private readonly resolver: IRuntimeResolver, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - ) { - this.state.contributeState(agentRuntimeBindingKey); - this.state.contributeState(runtimeBindingKey); - const initial = this.state.get(runtimeBindingKey) ?? seed.binding; - this.assertSessionWorkspace(initial); - this.state.set(agentRuntimeBindingKey, initial); - this.restoreHook = dispatcher.hooks.onDidRestore.register('agent-runtime-binding', async (_ctx, next) => { - const replayed = this.state.get(runtimeBindingKey); - if (replayed === undefined) { - void this.dispatcher.dispatch( - new RuntimeSetBinding({ ...this.current, agentId: this.scopeContext.agentId }), - ); - } else { - this.assertSessionWorkspace(replayed); - this.state.set(agentRuntimeBindingKey, replayed); - } - await next(); - }); - } - - private assertSessionWorkspace(binding: RuntimeBinding): void { - if (binding.workspaceId !== this.session.workspaceId) { - throw new RuntimeError( - 'runtime.not_found', - `runtime binding workspace ${binding.workspaceId} does not match session workspace ${this.session.workspaceId}`, - ); - } - } - - get current(): RuntimeBinding { - return this.state.get(agentRuntimeBindingKey); - } - - get(): RuntimeBinding { - return this.current; - } - - set(binding: RuntimeBinding): RuntimeBinding { - this.assertSessionWorkspace(binding); - const lease = this.resolver.acquire(binding, []); - lease.dispose(); - if (binding.workspaceId === this.current.workspaceId && binding.runtimeId === this.current.runtimeId) { - return this.current; - } - const next = { workspaceId: binding.workspaceId, runtimeId: binding.runtimeId }; - void this.dispatcher.dispatch( - new RuntimeSetBinding({ ...next, agentId: this.scopeContext.agentId }), - ); - this.state.set(agentRuntimeBindingKey, next); - this.changeEmitter.fire(next); - return next; - } - - switch(runtimeId: string): RuntimeBinding { - return this.set({ workspaceId: this.session.workspaceId, runtimeId }); - } - - dispose(): void { - this.restoreHook.dispose(); - this.changeEmitter.dispose(); - } -} - -registerScopedService(LifecycleScope.Agent, IAgentRuntimeBindingService, AgentRuntimeBindingService, ScopeActivation.OnScopeCreated, 'agentRuntimeBinding'); diff --git a/packages/agent-core-v2/src/agent/scopeContext/scopeContext.ts b/packages/agent-core-v2/src/agent/scopeContext/scopeContext.ts index 04f10f641..55c86c4da 100644 --- a/packages/agent-core-v2/src/agent/scopeContext/scopeContext.ts +++ b/packages/agent-core-v2/src/agent/scopeContext/scopeContext.ts @@ -1,14 +1,21 @@ +/** + * `scopeContext` domain — agent-scope identity token. + * + * Exposes `IAgentScopeContext`, the identity of the current agent scope (its + * `agentId`) plus a `scope(subKey?)` helper that returns the agent's + * persistence scope (or a child under it, e.g. `scope('cron')`). Seeded into + * every agent scope at creation so Agent-scoped consumers + * can refer to themselves and address their per-agent storage without any + * path arithmetic. Bound at Agent scope via a per-agent seed, not the scoped + * registry. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { IAgentScopeHandle } from '#/_base/di/scope'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { AgentSpaceImpl } from '#/agent/agentContext/agentSpace'; export interface IAgentScopeContext { readonly _serviceBrand: undefined; readonly agentId: string; - readonly forkedFrom?: string; - readonly agentContext: AgentContext; scope(subKey?: string): string; } @@ -18,22 +25,11 @@ export const IAgentScopeContext: ServiceIdentifier<IAgentScopeContext> = export function makeAgentScopeContext(input: { readonly agentId: string; readonly agentScope: string; - readonly forkedFrom?: string; - readonly generation?: number; }): IAgentScopeContext { const { agentScope } = input; - const space = new AgentSpaceImpl(input.agentId); - const agentContext: AgentContext = Object.freeze({ - agentId: input.agentId, - generation: input.generation ?? 0, - space, - }); - space._bindContext(agentContext); return { _serviceBrand: undefined, agentId: input.agentId, - forkedFrom: input.forkedFrom, - agentContext, scope: (subKey?: string): string => { if (subKey === undefined || subKey === '') return agentScope; if (agentScope === '') return subKey; @@ -41,15 +37,3 @@ export function makeAgentScopeContext(input: { }, }; } - -export function agentContextOfScope(scope: IAgentScopeContext): AgentContext { - return scope.agentContext; -} - -export function agentContextOf(handle: IAgentScopeHandle): AgentContext { - return agentContextOfScope(handle.accessor.get(IAgentScopeContext)); -} - -export function tryAgentContextOf(handle: IAgentScopeHandle): AgentContext | undefined { - return handle.accessor.get(IAgentScopeContext)?.agentContext; -} diff --git a/packages/agent-core-v2/src/agent/shellCommand/shellCommand.ts b/packages/agent-core-v2/src/agent/shellCommand/shellCommand.ts index 0007e1b00..54054ccf0 100644 --- a/packages/agent-core-v2/src/agent/shellCommand/shellCommand.ts +++ b/packages/agent-core-v2/src/agent/shellCommand/shellCommand.ts @@ -1,3 +1,12 @@ +/** + * `shellCommand` domain — shell command contract. + * + * Defines the Agent-scoped `IAgentShellCommandService` used to run user-initiated + * `!` commands: resolves the builtin Bash tool, records the command and its + * output into context, and notifies the model when a command is detached to + * background. Bound at Agent scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface RunShellCommandInput { diff --git a/packages/agent-core-v2/src/agent/shellCommand/shellCommandService.ts b/packages/agent-core-v2/src/agent/shellCommand/shellCommandService.ts index 2d7837f36..df90eb2cf 100644 --- a/packages/agent-core-v2/src/agent/shellCommand/shellCommandService.ts +++ b/packages/agent-core-v2/src/agent/shellCommand/shellCommandService.ts @@ -1,19 +1,39 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `shellCommand` domain — `IAgentShellCommandService` implementation. + * + * Runs user-initiated `!` commands through the builtin `Bash` tool from + * `toolRegistry`, records the command and output as `shell_command`-origin + * context messages via `contextMemory`, streams live `shell.output` / + * `shell.started` / `shell.completed` events through `eventBus`, and steers + * the model through `promptService` when a command is detached to background. + * Bound at Agent scope. + * + * `shell.completed` fires once when a foreground command settles (success or + * failure); runs detached to background do NOT fire it — they report through + * the task lifecycle instead. `shell.output` / `shell.completed` carry the + * foreground process `taskId` once that task is registered, so consumers that + * missed `shell.started` can still route the chunk. A failure text that was + * never streamed (empty stdout/stderr) is emitted as a `shell.output` chunk + * before `shell.completed`, so live consumers see the output too. + * + * The plain-data state (`shellCommandTasks`) is registered into `agentState` + * (`IAgentStateService`) and read/written through it; `shellCommandControllers` + * stays an instance field (per-command `AbortController`s, not plain data). + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { userCancellationReason } from '#/_base/utils/abort'; import { escapeXml } from '#/_base/utils/xml-escape'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import { IAgentPromptService } from '#/agent/prompt/prompt'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import type { ToolUpdate } from '#/tool/toolContract'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; -import { AgentEvent2 } from '#/app/event/event2'; +import { IEventBus } from '#/app/event/eventBus'; import { Error2, ErrorCodes } from '#/errors'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import { IAgentShellCommandService, @@ -21,43 +41,33 @@ import { type RunShellCommandResult, } from './shellCommand'; -export interface ShellOutputPayload { - readonly agentId: string; +export interface ShellOutputEvent { + readonly type: 'shell.output'; readonly commandId: string; readonly update: ToolUpdate; readonly taskId?: string; } -export class ShellOutput extends AgentEvent2<ShellOutputPayload> { - static override readonly type = 'shell.output'; - static override readonly observable = true; -} -export interface ShellOutput extends ShellOutputPayload {} - -export interface ShellStartedPayload { - readonly agentId: string; +export interface ShellStartedEvent { + readonly type: 'shell.started'; readonly commandId: string; readonly taskId: string; } -export class ShellStarted extends AgentEvent2<ShellStartedPayload> { - static override readonly type = 'shell.started'; - static override readonly observable = true; -} -export interface ShellStarted extends ShellStartedPayload {} - -export interface ShellCompletedPayload { - readonly agentId: string; +export interface ShellCompletedEvent { + readonly type: 'shell.completed'; readonly commandId: string; readonly isError: boolean; readonly taskId?: string; } -export class ShellCompleted extends AgentEvent2<ShellCompletedPayload> { - static override readonly type = 'shell.completed'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'shell.output': ShellOutputEvent; + 'shell.started': ShellStartedEvent; + 'shell.completed': ShellCompletedEvent; + } } -export interface ShellCompleted extends ShellCompletedPayload {} const SHELL_FOREGROUND_TIMEOUT_S = 2 * 60; @@ -74,11 +84,10 @@ export class AgentShellCommandService implements IAgentShellCommandService { @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IAgentPromptService private readonly promptService: IAgentPromptService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IEventBus private readonly eventBus: IEventBus, @IAgentStateService private readonly states: IAgentStateService, ) { - this.states.contributeState(shellCommandTasksKey); + this.states.register(shellCommandTasksKey); } private get shellCommandTasks(): Map<string, string> { @@ -116,26 +125,18 @@ export class AgentShellCommandService implements IAgentShellCommandService { else if (update.kind === 'stderr') stderr += update.text ?? ''; else return; if (input.commandId !== undefined) { - void this.dispatcher.dispatch( - new ShellOutput({ - agentId: this.scopeContext.agentId, - commandId: input.commandId, - update, - taskId: this.shellCommandTasks.get(input.commandId), - }), - ); + this.eventBus.publish({ + type: 'shell.output', + commandId: input.commandId, + update, + taskId: this.shellCommandTasks.get(input.commandId), + }); } }, onForegroundTaskStart: (taskId: string) => { if (input.commandId !== undefined) { this.shellCommandTasks.set(input.commandId, taskId); - void this.dispatcher.dispatch( - new ShellStarted({ - agentId: this.scopeContext.agentId, - commandId: input.commandId, - taskId, - }), - ); + this.eventBus.publish({ type: 'shell.started', commandId: input.commandId, taskId }); } }, }); @@ -148,25 +149,21 @@ export class AgentShellCommandService implements IAgentShellCommandService { if (isError && stdout.length === 0 && stderr.length === 0) { stderr = typeof result.output === 'string' ? result.output : 'Command failed.'; if (input.commandId !== undefined && stderr.length > 0) { - void this.dispatcher.dispatch( - new ShellOutput({ - agentId: this.scopeContext.agentId, - commandId: input.commandId, - update: { kind: 'stderr', text: stderr }, - taskId: this.shellCommandTasks.get(input.commandId), - }), - ); + this.eventBus.publish({ + type: 'shell.output', + commandId: input.commandId, + update: { kind: 'stderr', text: stderr }, + taskId: this.shellCommandTasks.get(input.commandId), + }); } } if (input.commandId !== undefined) { - void this.dispatcher.dispatch( - new ShellCompleted({ - agentId: this.scopeContext.agentId, - commandId: input.commandId, - isError, - taskId: this.shellCommandTasks.get(input.commandId), - }), - ); + this.eventBus.publish({ + type: 'shell.completed', + commandId: input.commandId, + isError, + taskId: this.shellCommandTasks.get(input.commandId), + }); } this.appendShellOutput(stdout, stderr, isError); return { stdout, stderr, isError }; @@ -175,23 +172,19 @@ export class AgentShellCommandService implements IAgentShellCommandService { stderr += message; if (input.commandId !== undefined) { if (message.length > 0) { - void this.dispatcher.dispatch( - new ShellOutput({ - agentId: this.scopeContext.agentId, - commandId: input.commandId, - update: { kind: 'stderr', text: message }, - taskId: this.shellCommandTasks.get(input.commandId), - }), - ); - } - void this.dispatcher.dispatch( - new ShellCompleted({ - agentId: this.scopeContext.agentId, + this.eventBus.publish({ + type: 'shell.output', commandId: input.commandId, - isError: true, + update: { kind: 'stderr', text: message }, taskId: this.shellCommandTasks.get(input.commandId), - }), - ); + }); + } + this.eventBus.publish({ + type: 'shell.completed', + commandId: input.commandId, + isError: true, + taskId: this.shellCommandTasks.get(input.commandId), + }); } this.appendShellOutput(stdout, stderr, true); return { stdout, stderr, isError: true }; diff --git a/packages/agent-core-v2/src/features/skill/prompt.ts b/packages/agent-core-v2/src/agent/skill/prompt.ts similarity index 80% rename from packages/agent-core-v2/src/features/skill/prompt.ts rename to packages/agent-core-v2/src/agent/skill/prompt.ts index abeaa2c04..1cbb50362 100644 --- a/packages/agent-core-v2/src/features/skill/prompt.ts +++ b/packages/agent-core-v2/src/agent/skill/prompt.ts @@ -1,15 +1,5 @@ import { escapeXml } from '#/_base/utils/xml-escape'; -import { promptMetadataTextFromText } from '#/agent/prompt/promptMetadataText'; -import type { SkillSource } from '#/features/skill/catalog/types'; - -import type { SkillActivationInput } from './skill'; - -export function promptMetadataTextFromSkill(input: SkillActivationInput): string | undefined { - const args = input.args?.trim(); - return promptMetadataTextFromText( - args === undefined || args.length === 0 ? `/${input.name}` : `/${input.name} ${args}`, - ); -} +import type { SkillSource } from '#/app/skillCatalog/types'; export type SkillPromptTrigger = 'user-slash' | 'model-tool' | 'nested-skill'; diff --git a/packages/agent-core-v2/src/agent/skill/skill.ts b/packages/agent-core-v2/src/agent/skill/skill.ts new file mode 100644 index 000000000..ed4eb3e93 --- /dev/null +++ b/packages/agent-core-v2/src/agent/skill/skill.ts @@ -0,0 +1,30 @@ +/** + * `skill` domain — user-slash skill activation contract. + * + * `SkillActivationInput` carries the slash name and raw args, plus optional + * edge-resolved attachment parts (`content`) that the activation appends after + * the rendered skill prompt in its user message. `IAgentSkillService` starts + * the activation turn (`activate`) and records model-tool activations without + * a turn (`recordModelToolActivation`). Bound at Agent scope. + */ + +import { createDecorator } from "#/_base/di/instantiation"; +import type { SkillActivationOrigin } from '#/agent/contextMemory/types'; +import type { Turn } from '#/agent/loop/loop'; +import type { ContentPart } from '#/kosong/contract/message'; + +export interface SkillActivationInput { + readonly name: string; + readonly args?: string; + readonly content?: readonly ContentPart[]; +} + +export interface IAgentSkillService { + readonly _serviceBrand: undefined; + + activate(input: SkillActivationInput): Promise<Turn>; + recordModelToolActivation(origin: SkillActivationOrigin): void; +} + +export const IAgentSkillService = + createDecorator<IAgentSkillService>('agentSkillService'); diff --git a/packages/agent-core-v2/src/agent/skill/skillOps.ts b/packages/agent-core-v2/src/agent/skill/skillOps.ts new file mode 100644 index 000000000..47a611891 --- /dev/null +++ b/packages/agent-core-v2/src/agent/skill/skillOps.ts @@ -0,0 +1,54 @@ +/** + * `skill` domain — wire Model (`SkillModel`) and the `skill.activate` Op + * (`skillActivate`) for the agent's skill-activation fact log. + * + * Skill carries no state: the Model is a `null` placeholder and the Op's + * `apply` is the identity function. `skill.activate` is live-only because it + * is not a v1 record type; it exists to derive the `skill.activated` event and + * carries no replayable state. The `randomUUID()` activation id is generated at + * the dispatch call site and carried inside `origin`, keeping `apply` free + * of non-determinism. Also augments + * `DomainEventMap` with `skill.activated`, derived from the Op via `toEvent`. + */ + +import { z } from 'zod'; + +import { defineModel } from '#/wire/model'; + +import type { SkillActivationOrigin, SkillSource } from '#/agent/contextMemory/types'; + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'skill.activated': { + activationId: string; + skillName: string; + trigger: string; + skillArgs?: string; + skillPath?: string; + skillSource?: SkillSource; + }; + } +} + +export const SkillModel = defineModel<null>('skill', () => null); + +declare module '#/wire/types' { + interface TransientOpMap { + 'skill.activate': typeof skillActivate; + } +} + +export const skillActivate = SkillModel.defineOp('skill.activate', { + schema: z.object({ origin: z.custom<SkillActivationOrigin>() }), + persist: false, + apply: (s) => s, + toEvent: (p) => ({ + type: 'skill.activated' as const, + activationId: p.origin.activationId, + skillName: p.origin.skillName, + trigger: p.origin.trigger, + skillArgs: p.origin.skillArgs, + skillPath: p.origin.skillPath, + skillSource: p.origin.skillSource, + }), +}); diff --git a/packages/agent-core-v2/src/agent/skill/skillService.ts b/packages/agent-core-v2/src/agent/skill/skillService.ts new file mode 100644 index 000000000..aed7efba2 --- /dev/null +++ b/packages/agent-core-v2/src/agent/skill/skillService.ts @@ -0,0 +1,145 @@ +/** + * `skill` domain — `IAgentSkillService` implementation. + * + * Resolves skills from the session catalog, renders the activation prompt, + * records the activation as a `skill.activate` fact through `wire.dispatch` + * (a stateless, identity-apply Op), derives the `skill.activated` event + * through the Op's `toEvent`, drives user-slash activations into a new turn via + * `prompt` (attachment parts from the caller ride the same user message after + * the rendered prompt), and reports `skill_invoked` / `flow_invoked` through + * `telemetry`. `wire.replay` reapplies the fact as a no-op, so neither the + * event nor telemetry fires on resume (matching the former `restoring` guard). + * Bound at Agent scope. + */ + +import { randomUUID } from 'node:crypto'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; + +import type { ContentPart } from '#/kosong/contract/message'; + +import type { ContextMessage, SkillActivationOrigin } from '#/agent/contextMemory/types'; +import { renderUserSlashSkillPrompt } from './prompt'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; +import { Service } from '#/_base/di/service'; +import { ErrorCodes, Error2 } from '#/errors'; +import { isUserActivatableSkillType, type SkillDefinition } from '#/app/skillCatalog/types'; +import { IAgentPromptService } from '#/agent/prompt/prompt'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import type { Turn } from '#/agent/loop/loop'; +import { IWireService } from '#/wire/wire'; +import { IAgentSkillService, type SkillActivationInput } from './skill'; +import { skillActivate } from './skillOps'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; + +export class AgentSkillService extends Service implements IAgentSkillService { + declare readonly _serviceBrand: undefined; + + constructor( + @ISessionSkillCatalog private readonly skillCatalog: ISessionSkillCatalog, + @IAgentPromptService private readonly prompt: IAgentPromptService, + @IWireService private readonly wire: IWireService, + @ITelemetryService private readonly telemetry: ITelemetryService, + @ISessionContext private readonly sessionContext: ISessionContext, + ) { + super(); + } + + async activate(input: SkillActivationInput): Promise<Turn> { + await this.skillCatalog.ready; + const skill = this.skillCatalog.catalog.getSkill(input.name); + if (skill === undefined) { + throw new Error2(ErrorCodes.SKILL_NOT_FOUND, `Skill "${input.name}" was not found`); + } + if (!isUserActivatableSkillType(skill.metadata.type)) { + throw new Error2( + ErrorCodes.SKILL_TYPE_UNSUPPORTED, + `Skill "${skill.name}" cannot be activated by the user`, + ); + } + + const skillArgs = input.args ?? ''; + const skillContent = this.renderSkillPrompt(skill, skillArgs); + const content: ContentPart[] = [ + { + type: 'text', + text: renderUserSlashSkillPrompt({ + skillName: skill.name, + skillArgs, + skillContent, + skillSource: skill.source, + skillDir: skill.dir, + }), + }, + ...(input.content ?? []), + ]; + + const turn = await this.recordActivation( + { + kind: 'skill_activation', + activationId: randomUUID(), + skillName: skill.name, + trigger: 'user-slash', + skillType: skill.metadata.type, + skillPath: skill.path, + skillSource: skill.source, + skillArgs: input.args, + }, + content, + ); + if (turn === undefined) { + throw new Error2( + ErrorCodes.TURN_AGENT_BUSY, + 'Cannot activate skill while another turn is active', + ); + } + return turn; + } + + recordModelToolActivation(origin: SkillActivationOrigin): void { + void this.recordActivation(origin); + } + + private async recordActivation( + origin: SkillActivationOrigin, + input?: readonly ContentPart[], + ): Promise<Turn | undefined> { + this.wire.dispatch(skillActivate({ origin })); + this.publishActivation(origin); + + if (input === undefined) return undefined; + const message: ContextMessage = { + role: 'user', + content: [...input], + toolCalls: [], + origin, + }; + return (await this.prompt.enqueue({ message })).launched; + } + + private renderSkillPrompt(skill: SkillDefinition, rawArgs: string): string { + return this.skillCatalog.catalog.renderSkillPrompt(skill, rawArgs, { + sessionId: this.sessionContext.sessionId, + }); + } + + private publishActivation(origin: SkillActivationOrigin): void { + this.telemetry.track2('skill_invoked', { + skill_name: origin.skillName, + trigger: origin.trigger, + }); + if (origin.skillType === 'flow') { + this.telemetry.track2('flow_invoked', { + flow_name: origin.skillName, + }); + } + } +} + +registerScopedService( + LifecycleScope.Agent, + IAgentSkillService, + AgentSkillService, + ScopeActivation.OnScopeCreated, + 'skill', +); diff --git a/packages/agent-core-v2/src/agent/state/agentState.ts b/packages/agent-core-v2/src/agent/state/agentState.ts index d25e00c64..c94049f25 100644 --- a/packages/agent-core-v2/src/agent/state/agentState.ts +++ b/packages/agent-core-v2/src/agent/state/agentState.ts @@ -1,17 +1,20 @@ +/** + * `state` domain — Agent-scope keyed state container contract. + * + * Defines `IAgentStateService`, the Agent-scope state service: Agent-tier + * services declare their plain-data state as typed keys (`defineState` from + * `_base`) and read/write them through this container, so per-agent shared + * state lives in one observable place and dies with the agent. Shares the + * `IStateRegistry` method set with its App/Workspace/Session counterparts; + * its `inspect()` cascade continues into the Session tier. Bound at Agent + * scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { IDisposable } from '#/_base/di/lifecycle'; import type { IStateRegistry } from '#/_base/state/stateRegistry'; -import type { ReplayableStateKey } from '#/state/state'; export interface IAgentStateService extends IStateRegistry { readonly _serviceBrand: undefined; - replayableKeys(): readonly ReplayableStateKey<any>[]; - onDidContributeReplayable( - listener: (key: ReplayableStateKey<any>) => void, - ): IDisposable; - onDidWithdrawReplayable( - listener: (key: ReplayableStateKey<any>) => void, - ): IDisposable; } export const IAgentStateService: ServiceIdentifier<IAgentStateService> = diff --git a/packages/agent-core-v2/src/agent/state/agentStateService.ts b/packages/agent-core-v2/src/agent/state/agentStateService.ts index 6463b0b4f..682e43860 100644 --- a/packages/agent-core-v2/src/agent/state/agentStateService.ts +++ b/packages/agent-core-v2/src/agent/state/agentStateService.ts @@ -1,10 +1,18 @@ +/** + * `state` domain — `IAgentStateService` implementation. + * + * Thin per-scope binding over the `_base` `StateRegistry`; the container owns + * construction and disposal, so registered state dies with the scope. Injects + * the Session-tier state service as its `inspect()` cascade parent (the + * parameter is optional so tests can construct a bare container; DI always + * injects). Bound at Agent scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { type IDisposable, toDisposable } from '#/_base/di/lifecycle'; -import { StateRegistry, type StateKey } from '#/_base/state/stateRegistry'; +import { StateRegistry } from '#/_base/state/stateRegistry'; import { ISessionStateService } from '#/session/state/sessionState'; -import type { ReplayableStateKey } from '#/state/state'; import { IAgentStateService } from './agentState'; @@ -12,67 +20,10 @@ export class AgentStateService extends StateRegistry implements IAgentStateServi declare readonly _serviceBrand: undefined; protected override readonly inspectScope = 'agent'; - private readonly replayables: ReplayableStateKey<any>[] = []; - private readonly contributeListeners = new Set<(key: ReplayableStateKey<any>) => void>(); - private readonly withdrawListeners = new Set<(key: ReplayableStateKey<any>) => void>(); - constructor(@ISessionStateService sessionState?: ISessionStateService) { super(); this.inspectParent = sessionState; } - - override contributeState<T>(key: StateKey<T>): IDisposable { - const meta = (key as Partial<ReplayableStateKey<any>>).replayable; - if (typeof meta !== 'object' || meta === null) { - return super.contributeState(key); - } - const replayableKey = key as unknown as ReplayableStateKey<any>; - const registration = this.contributeKey(key); - this.replayables.push(replayableKey); - try { - for (const listener of this.contributeListeners) { - listener(replayableKey); - } - } catch (error) { - registration.dispose(); - const index = this.replayables.indexOf(replayableKey); - if (index !== -1) this.replayables.splice(index, 1); - for (const listener of this.withdrawListeners) { - listener(replayableKey); - } - throw error; - } - return toDisposable(() => { - registration.dispose(); - const index = this.replayables.indexOf(replayableKey); - if (index !== -1) this.replayables.splice(index, 1); - for (const listener of this.withdrawListeners) { - listener(replayableKey); - } - }); - } - - replayableKeys(): readonly ReplayableStateKey<any>[] { - return [...this.replayables]; - } - - onDidContributeReplayable( - listener: (key: ReplayableStateKey<any>) => void, - ): IDisposable { - this.contributeListeners.add(listener); - return toDisposable(() => { - this.contributeListeners.delete(listener); - }); - } - - onDidWithdrawReplayable( - listener: (key: ReplayableStateKey<any>) => void, - ): IDisposable { - this.withdrawListeners.add(listener); - return toDisposable(() => { - this.withdrawListeners.delete(listener); - }); - } } registerScopedService( diff --git a/packages/agent-core-v2/src/agent/stepRetry/stepRetryService.ts b/packages/agent-core-v2/src/agent/stepRetry/stepRetryService.ts index 3c2eac8a0..990f1daec 100644 --- a/packages/agent-core-v2/src/agent/stepRetry/stepRetryService.ts +++ b/packages/agent-core-v2/src/agent/stepRetry/stepRetryService.ts @@ -1,8 +1,24 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `stepRetry` domain — `IAgentStepRetryService` implementation. + * + * Loop error-recovery plugin: claims retryable provider failures (HTTP 429 / + * 5xx, connection, timeout, empty response — `isRetryableGenerateError`) from + * the loop's error-handler registry and re-enqueues the failed step's driver + * at the head of the queue after exponential backoff (`retryBackoffDelays`). + * The loop only learns that the error was caught; the retry rides the normal + * step numbering and consumes `maxSteps` budget like any other step. Each + * claimed failure publishes `turn.step.retrying`. Consecutive attempts are + * counted per failed driver and reset when any step succeeds (`onDidFinishStep`) + * or a new turn starts. The mutable retry state (`lastFailedDriverId`, + * `failedAttempts`) is registered into `agentState` (`IAgentStateService`) and + * read/written through it. Bound at Agent scope and constructed with the scope + * so the handler registers before the first turn runs. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { DEFAULT_MAX_RETRY_ATTEMPTS, readRetryAfterMs, @@ -13,22 +29,18 @@ import { import { isRetryableGenerateError } from '#/kosong/contract/errors'; import { IConfigService } from '#/app/config/config'; import { IEventBus } from '#/app/event/eventBus'; -import { AgentEvent2 } from '#/app/event/event2'; import { unwrapErrorCause } from '#/errors'; import { IAgentLoopService, type LoopErrorContext, } from '#/agent/loop/loop'; import { LOOP_CONTROL_SECTION, type LoopControl } from '#/agent/loop/configSection'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import { IAgentStepRetryService } from './stepRetry'; -export interface TurnStepRetryingPayload { - readonly agentId: string; +export interface TurnStepRetryingEvent { + readonly type: 'turn.step.retrying'; readonly turnId: number; readonly step: number; readonly stepId?: string; @@ -41,11 +53,11 @@ export interface TurnStepRetryingPayload { readonly statusCode?: number; } -export class TurnStepRetrying extends AgentEvent2<TurnStepRetryingPayload> { - static override readonly type = 'turn.step.retrying'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'turn.step.retrying': TurnStepRetryingEvent; + } } -export interface TurnStepRetrying extends TurnStepRetryingPayload {} export const stepRetryLastFailedDriverIdKey = defineState<string | undefined>( 'stepRetry.lastFailedDriverId', @@ -56,6 +68,7 @@ export const stepRetryFailedAttemptsKey = defineState<number>( () => 0, ); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentStepRetryService extends Disposable implements IAgentStepRetryService { declare readonly _serviceBrand: undefined; @@ -63,13 +76,11 @@ export class AgentStepRetryService extends Disposable implements IAgentStepRetry @IAgentLoopService private readonly loopService: IAgentLoopService, @IConfigService private readonly config: IConfigService, @IEventBus private readonly eventBus: IEventBus, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(stepRetryLastFailedDriverIdKey); - this.states.contributeState(stepRetryFailedAttemptsKey); + this.states.register(stepRetryLastFailedDriverIdKey); + this.states.register(stepRetryFailedAttemptsKey); this._register( this.loopService.registerLoopErrorHandler({ id: 'step-retry', @@ -83,7 +94,7 @@ export class AgentStepRetryService extends Disposable implements IAgentStepRetry await next(); }), ); - this._register(this.eventBus.subscribe(TurnStarted, () => this.resetAttempts())); + this._register(this.eventBus.subscribe('turn.started', () => this.resetAttempts())); } private get lastFailedDriverId(): string | undefined { @@ -130,19 +141,17 @@ export class AgentStepRetryService extends Disposable implements IAgentStepRetry const error = unwrapErrorCause(context.error); const delayMs = readRetryAfterMs(error) ?? retryBackoffDelays(maxAttempts)[this.failedAttempts - 1] ?? 0; - void this.dispatcher.dispatch( - new TurnStepRetrying({ - agentId: this.scopeContext.agentId, - turnId: context.turnId, - step: context.step, - stepId: context.stepId, - failedAttempt: this.failedAttempts, - nextAttempt: this.failedAttempts + 1, - maxAttempts, - delayMs, - ...retryErrorFields(error), - }), - ); + this.eventBus.publish({ + type: 'turn.step.retrying', + turnId: context.turnId, + step: context.step, + stepId: context.stepId, + failedAttempt: this.failedAttempts, + nextAttempt: this.failedAttempts + 1, + maxAttempts, + delayMs, + ...retryErrorFields(error), + }); await sleepForRetry(delayMs, context.signal); if (context.currentStep?.signal.aborted === true) return false; diff --git a/packages/agent-core-v2/src/features/swarm/agent/enter-reminder.md b/packages/agent-core-v2/src/agent/swarm/enter-reminder.md similarity index 100% rename from packages/agent-core-v2/src/features/swarm/agent/enter-reminder.md rename to packages/agent-core-v2/src/agent/swarm/enter-reminder.md diff --git a/packages/agent-core-v2/src/features/swarm/agent/exit-reminder.md b/packages/agent-core-v2/src/agent/swarm/exit-reminder.md similarity index 100% rename from packages/agent-core-v2/src/features/swarm/agent/exit-reminder.md rename to packages/agent-core-v2/src/agent/swarm/exit-reminder.md diff --git a/packages/agent-core-v2/src/features/swarm/agent/swarm.ts b/packages/agent-core-v2/src/agent/swarm/swarm.ts similarity index 100% rename from packages/agent-core-v2/src/features/swarm/agent/swarm.ts rename to packages/agent-core-v2/src/agent/swarm/swarm.ts diff --git a/packages/agent-core-v2/src/agent/swarm/swarmOps.ts b/packages/agent-core-v2/src/agent/swarm/swarmOps.ts new file mode 100644 index 000000000..d222a5751 --- /dev/null +++ b/packages/agent-core-v2/src/agent/swarm/swarmOps.ts @@ -0,0 +1,37 @@ +/** + * `swarm` domain — wire Model (`SwarmModel`) and the `swarm_mode.enter` / + * `swarm_mode.exit` Ops (`swarmEnter` / `swarmExit`) for the agent's swarm mode. + * + * Declares swarm mode as a `SwarmModeTrigger | null` wire Model (the trigger is + * retained, not collapsed to a boolean, so `shouldAutoExit` can still + * distinguish `task` / `tool`) plus the two Ops that set and clear it; the + * `apply` functions are the pure extraction of the former live `applyEnter` / + * `applyExit` and `resume` facets. + */ + +import { z } from 'zod'; + +import { defineModel } from '#/wire/model'; + +import type { SwarmModeTrigger } from './swarm'; + +export const SwarmModel = defineModel<SwarmModeTrigger | null>('swarm', () => null); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'swarm_mode.enter': typeof swarmEnter; + 'swarm_mode.exit': typeof swarmExit; + } +} + +export const swarmEnter = SwarmModel.defineOp('swarm_mode.enter', { + schema: z.object({ trigger: z.custom<SwarmModeTrigger>() }), + apply: (_s, p) => p.trigger, + toEvent: () => ({ type: 'agent.status.updated' as const, swarmMode: true }), +}); + +export const swarmExit = SwarmModel.defineOp('swarm_mode.exit', { + schema: z.object({}), + apply: () => null, + toEvent: () => ({ type: 'agent.status.updated' as const, swarmMode: false }), +}); diff --git a/packages/agent-core-v2/src/agent/swarm/swarmService.ts b/packages/agent-core-v2/src/agent/swarm/swarmService.ts new file mode 100644 index 000000000..fde33429b --- /dev/null +++ b/packages/agent-core-v2/src/agent/swarm/swarmService.ts @@ -0,0 +1,145 @@ +/** + * `swarm` domain — `IAgentSwarmService` implementation. + * + * Tracks swarm-mode enter/exit in the `wire` `SwarmModel` (mutated only through + * the `swarm_mode.enter` / `swarm_mode.exit` Ops, read through `wire.getModel`), + * mirrors it into `systemReminder` as live-only side effects, derives + * `agent.status.updated` from the Ops' `toEvent`, and auto-exits on turn end via + * `turn`. The enter-reminder removal on exit is a cross-model fold on + * `ContextModel`: dispatching `swarm_mode.exit` pops the + * reminder when it is the last message, both live and on replay — exactly like + * v1's restore-time `popMatchedMessage`. The service only publishes the + * live-only `context.spliced` event for that pop (so injector bookkeeping + * stays in step) and appends the exit reminder when nothing was + * popped. Bound at Agent scope. The service also guards AgentSwarm batch + * exclusivity through an `onBeforeExecuteTool` veto + * listener: an AgentSwarm call must be the only tool call in its batch, + * anything else is vetoed with a `toolApproval.formatDenyMessage`-formatted + * reason. + */ + +import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; +import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; +import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; +import { IEventBus } from '#/app/event/eventBus'; +import { IWireService } from '#/wire/wire'; +import SWARM_MODE_ENTER_REMINDER from './enter-reminder.md?raw'; +import SWARM_MODE_EXIT_REMINDER from './exit-reminder.md?raw'; +import { IAgentSwarmService, type SwarmModeTrigger } from './swarm'; +import { swarmEnter, swarmExit, SwarmModel } from './swarmOps'; + +export class AgentSwarmService extends Service implements IAgentSwarmService { + declare readonly _serviceBrand: undefined; + + constructor( + @IWireService private readonly wire: IWireService, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, + @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, + @IEventBus private readonly eventBus: IEventBus, + @IAgentToolApprovalService private readonly toolApproval: IAgentToolApprovalService, + @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, + ) { + super(); + this._register( + this.eventBus.subscribe('turn.ended', () => { + if (this.shouldAutoExit) { + this.exit(); + } + }), + ); + this._register( + toolExecutor.onBeforeExecuteTool((event) => { + const agentSwarmCount = event.toolCalls.filter( + (toolCall) => toolCall.name === 'AgentSwarm', + ).length; + if (agentSwarmCount === 0 || (agentSwarmCount === 1 && event.toolCalls.length === 1)) { + return; + } + event.veto( + denyToolExecution( + this.toolApproval.formatDenyMessage( + agentSwarmCount > 1 + ? multipleAgentSwarmDeniedMessage(event.toolCalls.length > agentSwarmCount) + : mixedAgentSwarmDeniedMessage(), + ), + ), + ); + }), + ); + } + + enter(trigger: SwarmModeTrigger): void { + if (this.wire.getModel(SwarmModel) !== null) return; + this.wire.dispatch(swarmEnter({ trigger })); + if (trigger !== 'tool') { + this.reminders.appendSystemReminder(SWARM_MODE_ENTER_REMINDER, { + kind: 'injection', + variant: 'swarm_mode', + }); + } + } + + exit(): void { + const trigger = this.wire.getModel(SwarmModel); + if (trigger === null) return; + const history = this.context.get(); + const last = history[history.length - 1]; + const willPop = + last?.origin?.kind === 'injection' && last.origin.variant === 'swarm_mode'; + this.wire.dispatch(swarmExit({})); + if (trigger === 'tool') return; + if (willPop) { + this.eventBus.publish({ + type: 'context.spliced', + start: history.length - 1, + deleteCount: 1, + messages: [], + }); + return; + } + this.reminders.appendSystemReminder(SWARM_MODE_EXIT_REMINDER, { + kind: 'injection', + variant: 'swarm_mode_exit', + }); + } + + get isActive(): boolean { + return this.wire.getModel(SwarmModel) !== null; + } + + private get shouldAutoExit(): boolean { + const trigger = this.wire.getModel(SwarmModel); + return trigger === 'task' || trigger === 'tool'; + } +} + +registerScopedService( + LifecycleScope.Agent, + IAgentSwarmService, + AgentSwarmService, + ScopeActivation.OnScopeCreated, + 'swarm', +); + +function multipleAgentSwarmDeniedMessage(hasOtherToolCalls: boolean): string { + const suffix = hasOtherToolCalls + ? ' AgentSwarm also must not be combined with other tools in the same response.' + : ''; + return ( + 'AgentSwarm must be called one swarm at a time. Multiple AgentSwarm calls are not forbidden, ' + + 'but issue them sequentially: call one AgentSwarm, wait for its result, then call the next; ' + + `or merge the work into a single AgentSwarm when one swarm can cover it.${suffix}` + ); +} + +function mixedAgentSwarmDeniedMessage(): string { + return ( + 'AgentSwarm must be the only tool call in a model response. Retry with a single AgentSwarm ' + + 'call by itself, then call any other tools after it returns.' + ); +} diff --git a/packages/agent-core-v2/src/agent/systemReminder/systemReminder.ts b/packages/agent-core-v2/src/agent/systemReminder/systemReminder.ts new file mode 100644 index 000000000..3ecf30eae --- /dev/null +++ b/packages/agent-core-v2/src/agent/systemReminder/systemReminder.ts @@ -0,0 +1,11 @@ +import { createDecorator } from "#/_base/di/instantiation"; + +import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; + +export interface IAgentSystemReminderService { + readonly _serviceBrand: undefined; + + appendSystemReminder(content: string, origin: PromptOrigin): ContextMessage; +} + +export const IAgentSystemReminderService = createDecorator<IAgentSystemReminderService>('agentSystemReminderService'); diff --git a/packages/agent-core-v2/src/agent/systemReminder/systemReminderService.ts b/packages/agent-core-v2/src/agent/systemReminder/systemReminderService.ts new file mode 100644 index 000000000..317fa17a9 --- /dev/null +++ b/packages/agent-core-v2/src/agent/systemReminder/systemReminderService.ts @@ -0,0 +1,41 @@ +import { Service } from "#/_base/di/service"; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; + +import { IAgentSystemReminderService } from './systemReminder'; + +export class AgentSystemReminderService extends Service implements IAgentSystemReminderService { + declare readonly _serviceBrand: undefined; + + constructor( + @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, + ) { + super(); + } + + appendSystemReminder(content: string, origin: PromptOrigin): ContextMessage { + const message: ContextMessage = { + role: 'user', + content: [ + { + type: 'text', + text: `<system-reminder>\n${content.trim()}\n</system-reminder>`, + }, + ], + toolCalls: [], + origin, + }; + this.context.append(message); + return message; + } +} + +registerScopedService( + LifecycleScope.Agent, + IAgentSystemReminderService, + AgentSystemReminderService, + ScopeActivation.OnScopeCreated, + 'systemReminder', +); diff --git a/packages/agent-core-v2/src/agent/task/configSection.ts b/packages/agent-core-v2/src/agent/task/configSection.ts index 85f2d632c..e92f5f603 100644 --- a/packages/agent-core-v2/src/agent/task/configSection.ts +++ b/packages/agent-core-v2/src/agent/task/configSection.ts @@ -1,3 +1,21 @@ +/** + * `task` domain — task config-section schema and env bindings. + * + * Owns the `[task]` configuration section (task limits and lifecycle tuning). + * The legacy `[background]` section is registered with the same schema so old + * configs continue to load while callers migrate; effective values use legacy + * fields as the base and let `[task]` override matching fields. + * `keepAliveOnExit` and `maxRunningTasks` also + * accept the v1 env overrides `KIMI_CODE_BACKGROUND_KEEP_ALIVE_ON_EXIT` / + * `KIMI_CODE_BACKGROUND_MAX_RUNNING_TASKS` + * (applied live by the config env overlay; while a field's env var is set, + * `stripEnvBoundFields` restores its env-free raw value before persistence, so + * env values never leak into `config.toml`). Also owns the + * `kimi -p` print-mode background policy (`printBackgroundMode` / + * `printWaitCeilingS` / `printMaxTurns`), resolved with v1 semantics. + * Self-registered at module load via `registerConfigSection`. + */ + import { z } from 'zod'; import { parseBooleanEnv } from '#/_base/utils/env'; diff --git a/packages/agent-core-v2/src/agent/task/errors.ts b/packages/agent-core-v2/src/agent/task/errors.ts index 64e8161a4..f2e43ace2 100644 --- a/packages/agent-core-v2/src/agent/task/errors.ts +++ b/packages/agent-core-v2/src/agent/task/errors.ts @@ -1,3 +1,7 @@ +/** + * `task` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const TaskErrors = { diff --git a/packages/agent-core-v2/src/agent/task/notificationXml.ts b/packages/agent-core-v2/src/agent/task/notificationXml.ts index bc71d99a2..9e66fc863 100644 --- a/packages/agent-core-v2/src/agent/task/notificationXml.ts +++ b/packages/agent-core-v2/src/agent/task/notificationXml.ts @@ -1,3 +1,13 @@ +/** + * `task` domain — renders task terminal notification XML for context injection. + * + * Produces the model-visible `<notification ...>` block inserted through + * `contextMemory` for detached task settlement. The opening tag name is + * load-bearing for notification consumers, and `agent_id` stays separate from + * `source_id` because subagent resume ids and task ids live in different + * namespaces. + */ + import { escapeXmlAttr } from '#/_base/utils/xml-escape'; export function renderNotificationXml(data: Record<string, unknown>): string { diff --git a/packages/agent-core-v2/src/agent/task/persist.ts b/packages/agent-core-v2/src/agent/task/persist.ts index 66bc5860d..9a58e131e 100644 --- a/packages/agent-core-v2/src/agent/task/persist.ts +++ b/packages/agent-core-v2/src/agent/task/persist.ts @@ -1,3 +1,22 @@ +/** + * `task` domain — `AgentTaskPersistence`, the per-agent task + * persistence helper. + * + * Persists task state (`<taskId>.json`) and raw task output (`output.log`) + * through the `storage` access-pattern stores (`IAtomicDocumentStore` for + * atomic whole-document state, `IFileSystemStorageService` byte primitives for ordered + * output append), addressed under the owning agent's storage scope + * (`<sessionScope>/agents/<agentId>/tasks/…`) so the domain never touches the + * filesystem and each agent reads back exactly its own records — v1's + * per-agent `<sessionDir>/agents/<id>/tasks/` layout. An optional read-only + * fallback keeps the previous v2 session-level task root readable during the + * layout transition; primary agent keys and output files always win, while + * every write remains rooted at the owning agent. Task ids are validated + * against the `{prefix}-{8 hex}` shape before use as path segments + * (path-traversal and legacy `bg_<hex>` guard), and legacy snake_case records + * are normalized to the current shape on read. Not scope-bound. + */ + import { join } from 'pathe'; import { BugIndicatingError } from '#/errors'; diff --git a/packages/agent-core-v2/src/agent/task/printDefaults.ts b/packages/agent-core-v2/src/agent/task/printDefaults.ts index 96458cba0..23fb69fa1 100644 --- a/packages/agent-core-v2/src/agent/task/printDefaults.ts +++ b/packages/agent-core-v2/src/agent/task/printDefaults.ts @@ -1,7 +1,26 @@ +/** + * `task` domain — print-mode (`kimi -p`) config-section defaults. + * + * A headless run should not be cut short by limits meant for interactive use, so every filled value + * is "effectively unbounded". Fills land in the config memory layer via + * `IConfigService.set(…, ConfigTarget.Memory)`, never on disk. + * + * Only keys the user left unset are filled. A key counts as set when it has a + * user-config value (for `bashTaskTimeoutS`, in either `[task]` or the legacy + * `[background]` section), a memory-layer value, or an env-overlay value (an + * effective value with no user/memory source and different from the section + * default). Because the memory layer shadows a whole section on read, each + * patch spreads the section's current effective value so sibling user keys + * stay visible. Explicit user config always wins over these defaults. + * + * The wait ceiling defaults to the host timer's maximum delay + * (`MAX_TIMER_DELAY_MS`, ~24.8 days) expressed in seconds: effectively + * unbounded, while `ceilingS * 1000` can never overflow a timer. + */ + import { MAX_TIMER_DELAY_MS } from '#/_base/utils/timer'; import { ConfigTarget, type ConfigInspectValue, type IConfigService } from '#/app/config/config'; import { LOOP_CONTROL_SECTION } from '#/agent/loop/configSection'; -import { SWARM_SECTION } from '#/features/swarm/configSection'; import { SUBAGENT_SECTION } from '#/session/subagent/configSection'; import { LEGACY_BACKGROUND_SECTION, TASK_SECTION } from './configSection'; @@ -14,8 +33,6 @@ export const PRINT_BASH_TASK_TIMEOUT_S_DEFAULT = 0; export const PRINT_SUBAGENT_TIMEOUT_MS_DEFAULT = 0; -export const PRINT_SWARM_TIMEOUT_MS_DEFAULT = 0; - type SectionValue = Record<string, unknown>; function isUnset(inspected: ConfigInspectValue<SectionValue>, key: string): boolean { @@ -54,5 +71,4 @@ export async function applyPrintModeConfigDefaults(config: IConfigService): Prom 'timeoutMs', PRINT_SUBAGENT_TIMEOUT_MS_DEFAULT, ); - await fillSectionDefault(config, SWARM_SECTION, 'timeoutMs', PRINT_SWARM_TIMEOUT_MS_DEFAULT); } diff --git a/packages/agent-core-v2/src/agent/task/task.ts b/packages/agent-core-v2/src/agent/task/task.ts index 631f417af..9395f0875 100644 --- a/packages/agent-core-v2/src/agent/task/task.ts +++ b/packages/agent-core-v2/src/agent/task/task.ts @@ -1,3 +1,14 @@ +/** + * `task` domain — Agent-scope task manager contract. + * + * Defines the Agent-scoped task manager surface used for both foreground and + * detached work. Task execution adapters implement the generic `AgentTask` + * contract; this service owns registration, + * output retention, persistence, detach/stop/wait, terminal notifications, + * and session-close task teardown with a `keepAliveOnExit` opt-out. + * Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { ITaskHandle } from '#/app/task/task'; import type { @@ -57,7 +68,6 @@ export interface IAgentTaskEntry { } export interface AgentTaskNotificationContext { - readonly agentId: string; readonly notificationType: string; readonly title: string; readonly body: string; @@ -66,11 +76,6 @@ export interface AgentTaskNotificationContext { readonly sourceId: string; } -export interface AgentTaskWaitDelivery { - readonly taskId: string; - readonly status: AgentTaskStatus; -} - export interface IAgentTaskService { readonly _serviceBrand: undefined; @@ -85,7 +90,6 @@ export interface IAgentTaskService { ): Promise<AgentTaskOutputSnapshot>; readOutput(taskId: string, tail?: number): Promise<string>; suppressTerminalNotification(taskId: string): Promise<void>; - markTasksDeliveredViaWait(tasks: readonly AgentTaskWaitDelivery[]): void; detach(taskId: string): AgentTaskInfo | undefined; stop(taskId: string, reason?: string): Promise<AgentTaskInfo | undefined>; stopByUser(taskId: string): Promise<AgentTaskInfo | undefined>; diff --git a/packages/agent-core-v2/src/agent/task/taskOps.ts b/packages/agent-core-v2/src/agent/task/taskOps.ts index cc6aebc15..4eeb28075 100644 --- a/packages/agent-core-v2/src/agent/task/taskOps.ts +++ b/packages/agent-core-v2/src/agent/task/taskOps.ts @@ -1,88 +1,76 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `task` domain — wire Model (`TaskModel`) and the persisted + * `task.started` (`taskStarted`) / `task.terminated` (`taskTerminated`) Ops + * that record the durable task-info registry, plus the `task.started` / + * `task.terminated` edge events declared on `DomainEventMap` and derived from + * the Ops via `toEvent`. + * + * The Model is the replayable map of `taskId -> AgentTaskInfo` (initial empty) + * that rebuilds the restored "ghost" tasks from the persisted `task.*` records + * on `wire.replay`. Each Op folds one lifecycle event into the map by task id + * (a later `task.terminated` overwrites an earlier `task.started` for the same + * id, so the final state is the last known info). `apply` returns a new `Map` + * on every change — task records are inherently events (never a no-op) — and + * carries no non-determinism. The live `ManagedTask` (the running process, its + * `AbortController`, output ring, timers) stays OUT of the Model (live-only); + * the Model is the restore seed for `ghosts`, applied by the service's single + * `wire.hooks.onDidRestore` hook before disk load + reconcile. The Ops persist + * so the wire journal carries the full task lifecycle: replay rebuilds the + * Model as the ghost seed, and a cold transcript fold can rebuild task + * entities straight from the records. `task.terminated` additionally carries + * an optional bounded `outputTail` snapshot of the task's retained output for + * that fold; the tail is fold-only and never enters the Model. + * `AgentTaskPersistence` (per-task JSON documents + output logs) stays the + * full-fidelity registry and is reconciled on resume. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; -import type { AgentTaskNotificationContext } from './task'; import type { AgentTaskInfo } from './types'; export type TaskModelState = Map<string, AgentTaskInfo>; -const taskStartedSchema = z.object({ - agentId: z.string(), - info: z.custom<AgentTaskInfo>(), -}); +export const TaskModel = defineModel<TaskModelState>('task', () => new Map()); -export class TaskStarted extends AgentEvent2<z.infer<typeof taskStartedSchema>> { - static override readonly type = 'task.started'; - static override readonly durable = true; - static override readonly observable = true; - static override readonly schema = taskStartedSchema; -} -export interface TaskStarted { - readonly agentId: string; - readonly info: AgentTaskInfo; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'task.started': { readonly info: AgentTaskInfo }; + 'task.terminated': { readonly info: AgentTaskInfo }; + } } +const taskStartedSchema = z.object({ info: z.custom<AgentTaskInfo>() }); + const taskTerminatedSchema = z.object({ - agentId: z.string(), info: z.custom<AgentTaskInfo>(), outputTail: z.string().optional(), }); -export class TaskTerminated extends AgentEvent2<z.infer<typeof taskTerminatedSchema>> { - static override readonly type = 'task.terminated'; - static override readonly durable = true; - static override readonly schema = taskTerminatedSchema; -} -export interface TaskTerminated { - readonly agentId: string; - readonly info: AgentTaskInfo; - readonly outputTail?: string; +declare module '#/wire/types' { + interface PersistedOpMap { + 'task.started': typeof taskStarted; + 'task.terminated': typeof taskTerminated; + } } -export interface TaskTerminatedNoticePayload { - readonly agentId: string; - readonly info: AgentTaskInfo; -} - -export class TaskTerminatedNotice extends AgentEvent2<TaskTerminatedNoticePayload> { - static override readonly type = 'task.terminated'; - static override readonly observable = true; -} -export interface TaskTerminatedNotice extends TaskTerminatedNoticePayload {} - -export class TaskNotified extends AgentEvent2<AgentTaskNotificationContext> { - static override readonly type = 'task.notified'; - static override readonly observable = true; -} -export interface TaskNotified extends AgentTaskNotificationContext {} - -const taskWaitDeliveredSchema = z.object({ - agentId: z.string(), - keys: z.array(z.string()), +export const taskStarted = TaskModel.defineOp('task.started', { + schema: taskStartedSchema, + apply: (s, p) => { + const next = new Map(s); + next.set(p.info.taskId, p.info); + return next; + }, + toEvent: (p) => ({ type: 'task.started' as const, info: p.info }), }); -export class TaskWaitDelivered extends AgentEvent2<z.infer<typeof taskWaitDeliveredSchema>> { - static override readonly type = 'task.waitDelivered'; - static override readonly durable = true; - static override readonly schema = taskWaitDeliveredSchema; -} -export interface TaskWaitDelivered { - readonly agentId: string; - readonly keys: string[]; -} - -export const taskKey = defineState('task', (): TaskModelState => new Map()).replayable({ - schema: z.custom<TaskModelState>(), -}) - .on(TaskStarted, (s, e) => { - s.set(e.info.taskId, e.info); - }) - .on(TaskTerminated, (s, e, ctx) => { - s.set(e.info.taskId, e.info); - if (e instanceof TaskTerminated) { - ctx.emit(new TaskTerminatedNotice({ agentId: e.agentId, info: e.info })); - } - }); +export const taskTerminated = TaskModel.defineOp('task.terminated', { + schema: taskTerminatedSchema, + apply: (s, p) => { + const next = new Map(s); + next.set(p.info.taskId, p.info); + return next; + }, + toEvent: (p) => ({ type: 'task.terminated' as const, info: p.info }), +}); diff --git a/packages/agent-core-v2/src/agent/task/taskService.ts b/packages/agent-core-v2/src/agent/task/taskService.ts index 34806a7c7..8a733d883 100644 --- a/packages/agent-core-v2/src/agent/task/taskService.ts +++ b/packages/agent-core-v2/src/agent/task/taskService.ts @@ -1,3 +1,43 @@ +/** + * `task` domain — `AgentTaskService` implementation. + * + * Owns the agent's registry of running and restored tasks: + * registers and drives tasks to completion, retains a bounded output ring, + * persists task state and output through task persistence rooted at the + * agent's own scope (v1's per-agent `<sessionDir>/agents/<id>/tasks/` + * layout), lets only the main agent read through the previous v2 + * session-level task root without writing back to it, reads + * limits through `config`, records lifecycle and broadcasts through `wire` + * (persisted `task.started` / `task.terminated` Ops into `TaskModel`, the + * terminated record carrying a bounded tail of the task's retained output as + * `outputTail`, plus the matching signals), restores ghosts through a single + * `wire.hooks.onDidRestore` hook + * (wire replay -> disk load -> reconcile, in that order), delivers live + * terminal notifications by enqueueing `TaskNotificationStepRequest`s onto + * `loop` with `activeOrNewTurn` admission (mid-turn ones fold into the active turn's + * following step; idle ones launch a fresh turn themselves, matching v1's + * `turn.steer`, so the model consumes the notification without waiting for + * the user), silently appends restored notifications through `contextMemory`, + * re-surfaces active tasks through `contextInjector` after compaction, and + * requests every owned task to stop on session close (`stopAllOnExit` — v1's + * `stopBackgroundTasksOnExit`) with configurable SIGTERM grace and SIGKILL + * escalation. `keepAliveOnExit` skips task-manager teardown so independently + * living external work such as processes can continue; Session-scoped agents + * remain governed by the Session lifecycle. Scope disposal paths that bypass + * graceful close synchronously cancel/abort work and immediately attempt a + * best-effort force-stop to reduce the risk of surviving child processes. + * The plain-data task state (`ghosts`, `scheduledNotificationKeys`, + * `deliveredNotificationKeys`, `activeTaskReminderPending`) is registered + * into `agentState` (`IAgentStateService`) and read/written through it; the + * live `tasks` registry stays a plain field because a `ManagedTask` holds + * resources (promise chains, an `AbortController`, task handles) that must + * not be snapshotted, as do the `persistence` construction-time helper and + * the notification delivery machinery (`buildingNotificationKeys`, + * `pendingNotificationRequests`, `notificationRestoreQueue`). + * Notification delivery follows conversation undo through the checkpoint and + * reconciliation contracts. Bound at Agent scope. + */ + import { randomBytes } from 'node:crypto'; import { join } from 'pathe'; import { LifecycleScope } from '#/app/scopes'; @@ -7,7 +47,7 @@ import type { ContentPart } from '#/kosong/contract/message'; import { Disposable } from '#/_base/di/lifecycle'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { abortable, userCancellationReason, @@ -16,17 +56,10 @@ import { setClampedTimeout } from '#/_base/utils/timer'; import { escapeXml, escapeXmlAttr } from '#/_base/utils/xml-escape'; import { IEventBus } from '#/app/event/eventBus'; import { Error2, ErrorCodes } from '#/errors'; -import { z } from 'zod'; -import { - ContextAppendMessage, - ContextSpliced, -} from '#/agent/contextMemory/contextEvents'; -import '#/agent/contextMemory/conversationTime'; +import { defineCheckpointedModel } from '#/agent/contextMemory/conversationTime'; import { IAgentConversationUndoParticipantRegistry } from '#/agent/contextMemory/conversationUndoParticipants'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import type { ContextMessage, TaskOrigin } from '#/agent/contextMemory/types'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import { IAgentLoopService } from '#/agent/loop/loop'; import { MessageStepRequest } from '#/agent/loop/stepRequest'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; @@ -45,26 +78,26 @@ import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; import { ITelemetryService } from '#/app/telemetry/telemetry'; +import { IWireService } from '#/wire/wire'; import { IAgentTaskService, + type AgentTaskNotificationContext, type AgentTaskLoadOptions, type AgentTask, type AgentTaskInfo, type AgentTaskOutputSnapshot, type AgentTaskStatus, type AgentTaskTrackOptions, - type AgentTaskWaitDelivery, type ForegroundTaskReleaseReason, type IAgentTaskEntry, type RegisterAgentTaskOptions, } from './task'; import { resolveAgentTaskConfig } from './configSection'; import { AgentTaskPersistence } from './persist'; -import { taskKey, TaskNotified, TaskStarted, TaskTerminated, TaskWaitDelivered } from './taskOps'; +import { TaskModel, taskStarted, taskTerminated } from './taskOps'; import { formatTaskList } from '#/agent/tools/task/task-list/taskListTool'; import '#/agent/tools/task/task-output/taskOutputTool'; import '#/agent/tools/task/task-stop/taskStopTool'; -import '#/agent/tools/task/task-wait/taskWaitTool'; interface ForegroundRelease { readonly promise: Promise<ForegroundTaskReleaseReason>; @@ -90,27 +123,18 @@ interface AgentTaskNotificationBuildContext { readonly notification: AgentTaskNotification; } -export const taskNotificationDeliveryKey = defineState( +const TaskNotificationDeliveryModel = defineCheckpointedModel( 'task.notificationDelivery', (): readonly string[] => [], -) - .replayable({ schema: z.custom<readonly string[]>() }) - .undoable() - .on(ContextAppendMessage, (s, e) => { - const origin = taskOriginFromMessage(e.message); - if (origin === undefined) return; - const key = notificationKey(origin); - if (!s.includes(key)) { - s.push(key); - } - }) - .on(TaskWaitDelivered, (s, e) => { - for (const key of e.keys) { - if (!s.includes(key)) { - s.push(key); - } - } - }); + { + onAppendMessage: (current, message) => { + const origin = taskOriginFromMessage(message); + if (origin === undefined) return current; + const key = notificationKey(origin); + return current.includes(key) ? current : [...current, key]; + }, + }, +); interface ManagedTask { readonly taskId: string; @@ -184,6 +208,12 @@ function coerceTimeoutSettlement( return settlement; } +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'task.notified': AgentTaskNotificationContext; + } +} + export class TaskNotificationStepRequest extends MessageStepRequest { constructor( message: ContextMessage, @@ -219,6 +249,7 @@ export const taskActiveTaskReminderPendingKey = defineState<boolean>( () => false, ); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentTaskService extends Disposable implements IAgentTaskService { declare readonly _serviceBrand: undefined; @@ -235,11 +266,11 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { @IAtomicDocumentStore atomicDocs: IAtomicDocumentStore, @IFileSystemStorageService byteStore: IFileSystemStorageService, @ISessionContext session: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IAgentScopeContext scopeContext: IAgentScopeContext, @ITaskService private readonly taskService: ITaskService, + @IWireService private readonly wire: IWireService, @IEventBus private readonly eventBus: IEventBus, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, + @IAgentContextInjectorService injector: IAgentContextInjectorService, @IAgentLoopService private readonly loop: IAgentLoopService, @IAgentConversationUndoParticipantRegistry undoParticipants: IAgentConversationUndoParticipantRegistry, @@ -247,19 +278,17 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(taskKey); - this.states.contributeState(taskNotificationDeliveryKey); - this.states.contributeState(taskGhostsKey); - this.states.contributeState(taskScheduledNotificationKeysKey); - this.states.contributeState(taskDeliveredNotificationKeysKey); - this.states.contributeState(taskActiveTaskReminderPendingKey); + this.states.register(taskGhostsKey); + this.states.register(taskScheduledNotificationKeysKey); + this.states.register(taskDeliveredNotificationKeysKey); + this.states.register(taskActiveTaskReminderPendingKey); const fallbackRoot = - this.scopeContext.agentId === 'main' + scopeContext.agentId === 'main' ? { dir: session.sessionDir, scope: session.scope() } : undefined; this.persistence = new AgentTaskPersistence( - join(session.sessionDir, 'agents', this.scopeContext.agentId), - this.scopeContext.scope(), + join(session.sessionDir, 'agents', scopeContext.agentId), + scopeContext.scope(), atomicDocs, byteStore, fallbackRoot, @@ -271,8 +300,8 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { }), ); this._register( - this.dispatcher.hooks.onDidRestore.register('task', async (_ctx, next) => { - for (const key of this.states.get(taskNotificationDeliveryKey)) { + this.wire.hooks.onDidRestore.register('task', async (_ctx, next) => { + for (const key of this.wire.getModel(TaskNotificationDeliveryModel).current) { this.deliveredNotificationKeys.add(key); } await this.restoreAfterReplay(); @@ -280,7 +309,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { }), ); this._register( - this.eventBus.subscribe(ContextSpliced, (e) => { + this.eventBus.subscribe('context.spliced', (e) => { if (isCompactionSplice(e)) { this.activeTaskReminderPending = true; } @@ -292,10 +321,8 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { }), ); this._register( - activateReminderWhenReady(agentLifecycle, this.scopeContext, (reminder) => - reminder.register(ACTIVE_BACKGROUND_TASK_INJECTION_VARIANT, () => - this.activeBackgroundTaskReminder(), - ), + injector.register(ACTIVE_BACKGROUND_TASK_INJECTION_VARIANT, () => + this.activeBackgroundTaskReminder(), ), ); } @@ -335,7 +362,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { } private restoreGhostsFromWire(): void { - for (const [taskId, info] of this.states.get(taskKey)) { + for (const [taskId, info] of this.wire.getModel(TaskModel)) { if (this.tasks.has(taskId)) continue; this.ghosts.set(taskId, info); } @@ -518,7 +545,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { } private async reconcileNotificationDeliveryAfterUndo(): Promise<void> { - const restoredKeys = new Set(this.states.get(taskNotificationDeliveryKey)); + const restoredKeys = new Set(this.wire.getModel(TaskNotificationDeliveryModel).current); for (const [key, request] of this.pendingNotificationRequests) { if (request.aborted) this.clearPendingNotification(key, request); } @@ -616,25 +643,6 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { if (ghost !== undefined) return; } - markTasksDeliveredViaWait(tasks: readonly AgentTaskWaitDelivery[]): void { - if (tasks.length === 0) return; - const keys: string[] = []; - for (const { taskId, status } of tasks) { - const origin: TaskNotificationOrigin = { - taskId, - status, - notificationId: taskNotificationId(taskId, status), - }; - const key = notificationKey(origin); - this.pendingNotificationRequests.get(key)?.abort(); - this.markDeliveredNotification(origin); - keys.push(key); - } - void this.dispatcher.dispatch( - new TaskWaitDelivered({ agentId: this.scopeContext.agentId, keys }), - ); - } - detach(taskId: string): AgentTaskInfo | undefined { const entry = this.tasks.get(taskId); if (entry === undefined) return this.ghosts.get(taskId); @@ -865,6 +873,9 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { entry.waiters.push(resolve); }), new Promise<void>((resolve) => { + // A clamped early return just makes callers (e.g. the print drain + // loop) re-poll — the task may still be running, which the caller + // observes from the returned info. timeout = setClampedTimeout(resolve, timeoutMs); timeout.unref?.(); }), @@ -1073,9 +1084,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { } private recordTaskStarted(info: AgentTaskInfo): void { - void this.dispatcher.dispatch( - new TaskStarted({ agentId: this.scopeContext.agentId, info }), - ); + this.wire.dispatch(taskStarted({ info })); this.telemetry.track2('background_task_created', { task_id: info.taskId, kind: info.kind === 'process' ? 'bash' : info.kind, @@ -1083,9 +1092,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { } private recordTaskTerminated(info: AgentTaskInfo, outputTail?: string): void { - void this.dispatcher.dispatch( - new TaskTerminated({ agentId: this.scopeContext.agentId, info, outputTail }), - ); + this.wire.dispatch(taskTerminated({ info, outputTail })); this.telemetry.track2('background_task_completed', { task_id: info.taskId, kind: info.kind, @@ -1098,7 +1105,6 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { const context = await this.buildAgentTaskNotificationContext(info); if (context === undefined) return; const key = notificationKey(context.origin); - if (this.deliveredNotificationKeys.has(key)) return; const request = new TaskNotificationStepRequest( { role: 'user', @@ -1161,7 +1167,7 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { kind: 'task', taskId: info.taskId, status: info.status, - notificationId: taskNotificationId(info.taskId, info.status), + notificationId: `task:${info.taskId}:${info.status}`, }; const key = notificationKey(origin); if (this.buildingNotificationKeys.has(key)) return undefined; @@ -1212,17 +1218,15 @@ export class AgentTaskService extends Disposable implements IAgentTaskService { } private fireNotificationHook(notification: AgentTaskNotification): void { - void this.dispatcher.dispatch( - new TaskNotified({ - agentId: this.scopeContext.agentId, - notificationType: notification.type, - title: notification.title, - body: notification.body, - severity: notification.severity, - sourceKind: notification.source_kind, - sourceId: notification.source_id, - }), - ); + this.eventBus.publish({ + type: 'task.notified', + notificationType: notification.type, + title: notification.title, + body: notification.body, + severity: notification.severity, + sourceKind: notification.source_kind, + sourceId: notification.source_id, + }); } private isTerminalNotificationSuppressed(taskId: string): boolean { @@ -1382,10 +1386,6 @@ function isTaskOrigin(origin: unknown): origin is TaskNotificationOrigin { ); } -function taskNotificationId(taskId: string, status: string): string { - return `task:${taskId}:${status}`; -} - function notificationKey(origin: TaskNotificationOrigin): string { return `${origin.taskId}\0${origin.status}\0${origin.notificationId}`; } diff --git a/packages/agent-core-v2/src/agent/tokenCounting/configSection.ts b/packages/agent-core-v2/src/agent/tokenCounting/configSection.ts index e1e0d382e..e41d8e386 100644 --- a/packages/agent-core-v2/src/agent/tokenCounting/configSection.ts +++ b/packages/agent-core-v2/src/agent/tokenCounting/configSection.ts @@ -1,3 +1,23 @@ +/** + * `tokenCounting` domain — `tokenCounting` config-section schema and env binding. + * + * Owns the `[token_counting]` section: the `strategy` switch selecting which + * context token count is EXTERNALLY reported (status events, REST status, + * RPC reads) — `measured+estimated` (default; the live size floored by the + * last measured total), `measured` (the latest measured anchor alone), or + * `estimated` (a pure estimate with anchors ignored — the escape hatch for + * providers with absent or unreliable usage reporting). Both tracks are + * always recorded and always feed internal logic (triggers, budgets, + * overflow backoff); the strategy never gates them. + * Persisted user preference with an operational env override + * (`KIMI_TOKEN_COUNTING_STRATEGY`); `config` resolves it as + * `env > config.toml > default` on every read. + * + * While the env var is set, `stripEnvBoundFields` restores the env-free raw + * value before `set`/`replace` persists, so an echoed override never leaks + * into `config.toml`. + */ + import { z } from 'zod'; import { diff --git a/packages/agent-core-v2/src/agent/tokenCounting/tokenCounting.ts b/packages/agent-core-v2/src/agent/tokenCounting/tokenCounting.ts index 05659efaf..97150c992 100644 --- a/packages/agent-core-v2/src/agent/tokenCounting/tokenCounting.ts +++ b/packages/agent-core-v2/src/agent/tokenCounting/tokenCounting.ts @@ -1,5 +1,25 @@ +/** + * `tokenCounting` domain — `IAgentTokenCountingService` contract. + * + * The single owner of every token count the agent reasons about: the context + * size (measured anchors + estimated tail), the full request size (system + * prompt + tools + messages) used by overflow heuristics, and the raw + * character-based estimate primitives consumed by compaction budgets. Both + * tracks — measured anchors and heuristic estimates — are ALWAYS recorded and + * always feed internal logic (triggers, budgets, overflow backoff); the + * `[token_counting]` strategy is resolved HERE and nowhere else, and selects + * only the externally reported reading (`statusSize`): + * - `measured+estimated` (default): the live size, floored by the last + * measured total; + * - `measured`: the latest measured anchor alone — estimates never reported; + * - `estimated`: a pure estimate with anchors ignored (the escape hatch for + * providers whose usage reporting is absent or unreliable). + */ + +import { createDecorator } from '#/_base/di/instantiation'; import type { Message } from '#/kosong/contract/message'; import type { Tool } from '#/kosong/contract/tool'; +import type { TokenUsage } from '#/kosong/contract/usage'; export type TokenCountingStrategy = 'measured+estimated' | 'measured' | 'estimated'; @@ -14,3 +34,31 @@ export interface TokenCountingRequest { readonly tools: readonly Tool[]; readonly messages: readonly Message[]; } + +export interface IAgentTokenCountingService { + readonly _serviceBrand: undefined; + + readonly strategy: TokenCountingStrategy; + + get(start?: number, end?: number): ContextSize; + measured(input: readonly Message[], output: readonly Message[], usage: TokenUsage): void; + /** Tokens of the most recent measured anchor (0 when none) — a real reading + * that stays valid across transient uncascaded context rewrites. */ + latestMeasured(): number; + /** The externally reported context size — the ONLY reading the + * `[token_counting]` strategy selects: `measured` reports the latest + * measured anchor alone, `estimated` reports a pure estimate with anchors + * ignored, and the default reports the live size floored by the last + * measured total. Internal logic (triggers, budgets, overflow backoff) + * must use `get()` / the estimate primitives, never this method. */ + statusSize(): number; + requestSize(request: TokenCountingRequest): number; + + estimateText(text: string): number; + estimateMessage(message: Message): number; + estimateMessages(messages: readonly Message[]): number; + estimateTools(tools: readonly Tool[]): number; +} + +export const IAgentTokenCountingService = + createDecorator<IAgentTokenCountingService>('agentTokenCountingService'); diff --git a/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingOps.ts b/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingOps.ts index 06dbf7aa7..6b08a935b 100644 --- a/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingOps.ts +++ b/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingOps.ts @@ -1,7 +1,25 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `tokenCounting` domain — wire Model (`TokenCountingModel`) and the transient + * Ops maintaining the measured-anchor ledger. + * + * State is `{ anchors, tokens }`: `anchors` is the live history of measured + * context sizes — one entry per measured LLM exchange (`measured: true`), or a + * single rebased entry after clear / compaction (`measured` marks whether the + * value is fully LLM-reported). Folding the ledger lets undo restore the REAL + * size of a surviving prefix instead of re-estimating it. `tokens` is the + * display value carried by the most recent Op, kept for `toEvent` / status + * emission because Ops are pure and cannot estimate. + * + * All three Ops are live-only (`persist: false`): the ledger is not a v1 + * record type, so resume starts empty and reads estimates until the next + * measured exchange — same contract as the previous single-anchor model. + * `apply` functions are pure and return the SAME reference on a no-op so the + * wire's reference-equality gate stays quiet. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; +import { defineModel } from '#/wire/model'; export interface TokenAnchor { readonly length: number; @@ -14,67 +32,80 @@ export interface TokenCountingState { readonly tokens: number; } -const sizeSchema = z.object({ - agentId: z.string(), - length: z.number(), - tokens: z.number(), -}); +export const TokenCountingModel = defineModel<TokenCountingState>('tokenCounting', () => ({ + anchors: [], + tokens: 0, +})); -export class TokenCountingMeasured extends AgentEvent2<z.infer<typeof sizeSchema>> { - static override readonly type = 'token_counting.measured'; - static override readonly durable = true; - static override readonly schema = sizeSchema; -} -export interface TokenCountingMeasured { - readonly agentId: string; - readonly length: number; - readonly tokens: number; +declare module '#/wire/types' { + interface TransientOpMap { + 'token_counting.measured': typeof tokenCountingMeasured; + 'token_counting.truncated': typeof tokenCountingTruncated; + 'token_counting.rebased': typeof tokenCountingRebased; + } } -export class TokenCountingTruncated extends AgentEvent2<z.infer<typeof sizeSchema>> { - static override readonly type = 'token_counting.truncated'; - static override readonly durable = true; - static override readonly schema = sizeSchema; -} -export interface TokenCountingTruncated { - readonly agentId: string; - readonly length: number; - readonly tokens: number; +const sizeSchema = z.object({ length: z.number(), tokens: z.number() }); + +function statusEvent(state: TokenCountingState) { + return { type: 'agent.status.updated' as const, contextTokens: state.tokens }; } -const rebaseSchema = sizeSchema.extend({ measured: z.boolean() }); - -export class TokenCountingRebased extends AgentEvent2<z.infer<typeof rebaseSchema>> { - static override readonly type = 'token_counting.rebased'; - static override readonly durable = true; - static override readonly schema = rebaseSchema; -} -export interface TokenCountingRebased { - readonly agentId: string; - readonly length: number; - readonly tokens: number; - readonly measured: boolean; -} - -const turnRecordedSchema = sizeSchema.extend({ turnId: z.number() }); - -export class TokenCountingTurnRecorded extends AgentEvent2<z.infer<typeof turnRecordedSchema>> { - static override readonly type = 'token_counting.turn_recorded'; - static override readonly durable = true; - static override readonly schema = turnRecordedSchema; -} -export interface TokenCountingTurnRecorded { - readonly agentId: string; - readonly length: number; - readonly tokens: number; - readonly turnId: number; -} - -export function anchorsEqual(a: readonly TokenAnchor[], b: readonly TokenAnchor[]): boolean { +function anchorsEqual(a: readonly TokenAnchor[], b: readonly TokenAnchor[]): boolean { return a.length === b.length && a.every((anchor, i) => anchor === b[i]); } -export function normalizeAnchorLength(length: number): number { +/** Exchange anchor: a true LLM-reported count for the whole live context. */ +export const tokenCountingMeasured = TokenCountingModel.defineOp('token_counting.measured', { + schema: sizeSchema, + persist: false, + apply: (s, p) => { + const length = normalizeAnchorLength(p.length); + const tokens = Math.max(0, p.tokens); + const anchor: TokenAnchor = { length, tokens, measured: true }; + // Non-monotonic guard: a stale/future anchor can never outlive a newer + // exchange at a shorter context (e.g. after an uncascaded rewrite). + const anchors = [...s.anchors.filter((a) => a.length < length), anchor]; + if (s.tokens === tokens && anchorsEqual(s.anchors, anchors)) return s; + return { anchors, tokens }; + }, + toEvent: (_p, state) => statusEvent(state), +}); + +/** Undo cut: drop anchors beyond the cut; `tokens` is the dispatcher's + * precomputed post-cut size, carried for status display only. */ +export const tokenCountingTruncated = TokenCountingModel.defineOp('token_counting.truncated', { + schema: sizeSchema, + persist: false, + apply: (s, p) => { + const length = normalizeAnchorLength(p.length); + const tokens = Math.max(0, p.tokens); + const anchors = s.anchors.filter((a) => a.length <= length); + if (s.tokens === tokens && anchorsEqual(s.anchors, anchors)) return s; + return { anchors, tokens }; + }, + toEvent: (_p, state) => statusEvent(state), +}); + +/** Clear / compaction: reset the ledger to a single anchor. Compaction passes + * `measured: false` — its `tokensAfter` blends a measured summary with + * estimated kept messages and the estimated request overhead (system prompt + * + tools), keeping the anchor on the same full-request basis as measured + * exchange anchors. */ +export const tokenCountingRebased = TokenCountingModel.defineOp('token_counting.rebased', { + schema: sizeSchema.extend({ measured: z.boolean() }), + persist: false, + apply: (s, p) => { + const length = normalizeAnchorLength(p.length); + const tokens = Math.max(0, p.tokens); + const anchors: readonly TokenAnchor[] = [{ length, tokens, measured: p.measured }]; + if (s.tokens === tokens && anchorsEqual(s.anchors, anchors)) return s; + return { anchors, tokens }; + }, + toEvent: (_p, state) => statusEvent(state), +}); + +function normalizeAnchorLength(length: number): number { if (!Number.isFinite(length)) return 0; return Math.max(0, Math.floor(length)); } diff --git a/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingService.ts b/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingService.ts new file mode 100644 index 000000000..4feb38200 --- /dev/null +++ b/packages/agent-core-v2/src/agent/tokenCounting/tokenCountingService.ts @@ -0,0 +1,177 @@ +/** + * `tokenCounting` domain — `IAgentTokenCountingService` implementation. + * + * Folds the `TokenCountingModel` anchor ledger with strategy-gated estimates. + * `get(start?, end?)` resolves the range like `Array.prototype.slice`: the + * latest anchor valid for the live context (anchors beyond it are stale — a + * rewrite that did not cascade — and skipped) supplies the REAL prefix + * count, and the not-yet-anchored tail is estimated per message; sub-ranges + * of the anchored prefix fall back to per-message estimates (the exact + * aggregate is only known at anchor boundaries). Both tracks always feed + * internal logic; the `[token_counting]` strategy only selects the externally + * reported reading (`statusSize`) — `measured` reports anchors alone, + * `estimated` reports a pure estimate, the default floors the live size by + * the last measured total. + * `measured(input, output, usage)` writes the exchange anchor through + * `wire.dispatch(tokenCountingMeasured(...))` after each measured LLM + * exchange. The context is read from the wire `ContextModel` directly (not + * via `IAgentContextMemoryService`) so `contextMemory` can depend on this + * service without a constructor cycle. Bound at Agent scope. + */ + +import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { IConfigService } from '#/app/config/config'; +import { ContextModel } from '#/agent/contextMemory/contextOps'; +import type { ContextMessage } from '#/agent/contextMemory/types'; +import type { Message } from '#/kosong/contract/message'; +import type { Tool } from '#/kosong/contract/tool'; +import { + estimateTokens, + estimateTokensForMessage, + estimateTokensForMessages, + estimateTokensForTools, +} from '#/kosong/contract/tokens'; +import type { TokenUsage } from '#/kosong/contract/usage'; +import { IWireService } from '#/wire/wire'; + +import { TOKEN_COUNTING_SECTION, type TokenCountingConfig } from './configSection'; +import { + IAgentTokenCountingService, + type ContextSize, + type TokenCountingRequest, + type TokenCountingStrategy, +} from './tokenCounting'; +import { TokenCountingModel, tokenCountingMeasured, type TokenAnchor } from './tokenCountingOps'; + +const ZERO_ANCHOR: TokenAnchor = { length: 0, tokens: 0, measured: true }; + +export class AgentTokenCountingService extends Disposable implements IAgentTokenCountingService { + declare readonly _serviceBrand: undefined; + + constructor( + @IWireService private readonly wire: IWireService, + @IConfigService private readonly config: IConfigService, + ) { + super(); + } + + get strategy(): TokenCountingStrategy { + // `?? default`: unregistered / stubbed config reads (test harnesses) keep + // the default; the registered section default is 'measured+estimated'. + return ( + this.config.get<TokenCountingConfig>(TOKEN_COUNTING_SECTION)?.strategy ?? + 'measured+estimated' + ); + } + + get(start?: number, end?: number): ContextSize { + const context = this.context(); + const from = normalizeSliceIndex(start ?? 0, context.length); + const to = normalizeSliceIndex(end ?? context.length, context.length); + const anchor = this.latestAnchor(context.length); + const measuredEnd = Math.min(to, anchor.length); + const estimatedStart = Math.max(from, anchor.length); + const measured = + from === 0 && measuredEnd === anchor.length + ? anchor.tokens + : this.estimateMessages(context.slice(from, measuredEnd)); + const estimated = this.estimateMessages(context.slice(estimatedStart, to)); + return { size: measured + estimated, measured, estimated }; + } + + measured(input: readonly Message[], _output: readonly Message[], usage: TokenUsage): void { + const context = this.context(); + if (!matchesContext(input, context)) return; + const length = context.length; + const tokens = tokenUsageTotal(usage); + this.wire.dispatch(tokenCountingMeasured({ length, tokens })); + } + + latestMeasured(): number { + const anchors = this.wire.getModel(TokenCountingModel).anchors; + for (let i = anchors.length - 1; i >= 0; i--) { + if (anchors[i]!.measured) return anchors[i]!.tokens; + } + return 0; + } + + statusSize(): number { + if (this.strategy === 'measured') return this.latestMeasured(); + if (this.strategy === 'estimated') return this.estimateMessages(this.context()); + // The live size can transiently dip below the last measured total while a + // post-step fold/rewrite leaves the context shorter than the measured + // prefix (the estimate then excludes the system prompt); the measured + // total is the better reading there. Every REAL shrink (undo / clear / + // compaction) rebases the measured model first, so the max only wins in + // that window. + return Math.max(this.get().size, this.latestMeasured()); + } + + requestSize(request: TokenCountingRequest): number { + return ( + this.estimateText(request.systemPrompt) + + this.estimateTools(request.tools) + + this.estimateMessages(request.messages) + ); + } + + estimateText(text: string): number { + return estimateTokens(text); + } + + estimateMessage(message: Message): number { + return estimateTokensForMessage(message); + } + + estimateMessages(messages: readonly Message[]): number { + return estimateTokensForMessages(messages); + } + + estimateTools(tools: readonly Tool[]): number { + return estimateTokensForTools(tools); + } + + private context(): readonly ContextMessage[] { + return this.wire.getModel(ContextModel) as readonly ContextMessage[]; + } + + /** Latest anchor still valid for the live context: anchors beyond it are + * stale (a rewrite that did not cascade) and skipped. An anchor longer + * than the queried range still certifies the range as measured — the + * caller clamps with `min(to, anchor.length)`. */ + private latestAnchor(contextLength: number): TokenAnchor { + const anchors = this.wire.getModel(TokenCountingModel).anchors; + for (let i = anchors.length - 1; i >= 0; i--) { + const anchor = anchors[i]!; + if (anchor.length <= contextLength) return anchor; + } + return ZERO_ANCHOR; + } +} + +function matchesContext(input: readonly Message[], context: readonly ContextMessage[]): boolean { + if (input.length !== context.length) return false; + for (let index = 0; index < input.length; index += 1) { + if (input[index] !== context[index]) return false; + } + return true; +} + +function tokenUsageTotal(usage: TokenUsage): number { + return usage.inputCacheRead + usage.inputCacheCreation + usage.inputOther + usage.output; +} + +function normalizeSliceIndex(index: number, length: number): number { + if (index < 0) return Math.max(length + index, 0); + return Math.min(index, length); +} + +registerScopedService( + LifecycleScope.Agent, + IAgentTokenCountingService, + AgentTokenCountingService, + ScopeActivation.OnScopeCreated, + 'tokenCounting', +); diff --git a/packages/agent-core-v2/src/agent/toolActivation/toolActivation.ts b/packages/agent-core-v2/src/agent/toolActivation/toolActivation.ts index f13afca20..07a911037 100644 --- a/packages/agent-core-v2/src/agent/toolActivation/toolActivation.ts +++ b/packages/agent-core-v2/src/agent/toolActivation/toolActivation.ts @@ -1,3 +1,18 @@ +/** + * `toolActivation` domain — `IAgentToolActivationService` contract. + * + * Owns the fold that turns the `AgentToolContribution` collection records + * (`toolRegistry`, L3 — built-in ones provided once by the App-scope + * assembly, dynamic ones provided by live units) into entries of the + * per-agent runtime registry: a record activates only when its `when` + * predicate holds, the workspace os-level veto (`sessionToolPolicyGate`) + * does not disable it, and its declared `name` is allowed by the bound + * Profile's tool policy (`profile`, L4); a withdrawn record unregisters its + * tool again. One full activation pass runs after restore and profile + * binding, so an Agent's tools reflect the Profile before the first turn. + * Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; export interface IAgentToolActivationService { diff --git a/packages/agent-core-v2/src/agent/toolActivation/toolActivationService.ts b/packages/agent-core-v2/src/agent/toolActivation/toolActivationService.ts index 83e041ebb..886f646fc 100644 --- a/packages/agent-core-v2/src/agent/toolActivation/toolActivationService.ts +++ b/packages/agent-core-v2/src/agent/toolActivation/toolActivationService.ts @@ -1,3 +1,35 @@ +/** + * `toolActivation` domain — `IAgentToolActivationService` implementation. + * + * The fold over the `AgentToolContribution` collection (`toolRegistry`, L3): + * folds `view.items` into the per-agent runtime registry — for each record + * allowed by the workspace os-level veto (the seeded `sessionToolPolicyGate`) + * AND the bound Profile's tool policy (`profile`), it resolves the + * Agent-scope service through the container — nothing constructs the tool + * before this `accessor.get` — and registers the real instance into the + * runtime registry. + * + * The fold is incremental: `view.onDidChange` re-folds deltas — an `added` + * record walks the same activation judgment, a `removed` record (provider + * unit disposed) withdraws the tool from the runtime registry through the + * registration handle kept per record. Re-folding never gates the fold + * itself: collection edges never join a cascade contagion set. + * + * One full pass also runs explicitly (after restore and profile binding) and + * re-runs on every `agent.status.updated` event, so tools newly allowed by a + * runtime re-bind or `setActiveTools` are activated without a restart. + * Already-registered names are skipped, and besides withdrawn records + * nothing is ever unregistered here: restricting visibility remains the + * request-time tool policy's job. + * + * Resolving contributions lazily inside `activate()` / the change + * subscription — never from this service's own constructor — keeps the + * historical cycle broken: some tools (SkillTool → `prompt` → `loop` → + * `toolRegistry`) transitively depend on the tool registry, which by + * activation time has long finished constructing. Bound at Agent scope; the + * lifecycle's explicit `activate()` is the only full-resolution path. + */ + import { type CollectionView } from '#/_base/di/collection'; import { IInstantiationService } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; @@ -6,12 +38,10 @@ import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IEventBus } from '#/app/event/eventBus'; import { IAgentProfileService } from '#/agent/profile/profile'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; import { isToolActive } from '#/agent/toolPolicy/evaluate'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { AgentToolContribution } from '#/agent/toolRegistry/toolContribution'; import { ISessionToolPolicyGate } from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; import { IAgentToolActivationService } from './toolActivation'; @@ -25,17 +55,15 @@ export class AgentToolActivationService extends Service implements IAgentToolAct @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, @IAgentProfileService private readonly profile: IAgentProfileService, @ISessionToolPolicyGate private readonly toolPolicyGate: ISessionToolPolicyGate, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, @IEventBus eventBus: IEventBus, @AgentToolContribution private readonly contributions: CollectionView<AgentToolContribution>, ) { super(); this._register( - eventBus.subscribe(AgentStatusUpdated, () => { + eventBus.subscribe('agent.status.updated', () => { void this.activate(); }), ); - this._register(this.runtime.onDidChange(() => this.refreshRuntimeRecords())); this._register( this.contributions.onDidChange((change) => { this.activateRecords(change.added); @@ -61,7 +89,6 @@ export class AgentToolActivationService extends Service implements IAgentToolAct const { id, options } = record; const source = options.source ?? 'builtin'; if (this.toolRegistry.resolve(options.name) !== undefined) continue; - if (!this.runtimeAllows(record)) continue; if (!isToolActive(workspaceVeto, options.name, source)) continue; if (!isToolActive(policy, options.name, source)) continue; if (options.when !== undefined && !options.when(accessor)) continue; @@ -76,18 +103,6 @@ export class AgentToolActivationService extends Service implements IAgentToolAct }); } - private refreshRuntimeRecords(): void { - for (const record of this.contributions.items) { - if (!this.runtimeAllows(record)) this.deactivateRecord(record); - } - this.activateRecords(this.contributions.items); - } - - private runtimeAllows(record: AgentToolContribution): boolean { - const required = record.options.requiredRuntimeCapabilities; - return required === undefined || this.runtime.isAvailable(required); - } - private deactivateRecord(record: AgentToolContribution): void { const registration = this.registrations.get(record); if (registration === undefined) return; diff --git a/packages/agent-core-v2/src/agent/toolApproval/toolApproval.ts b/packages/agent-core-v2/src/agent/toolApproval/toolApproval.ts index 7caf10be5..cb6d485b6 100644 --- a/packages/agent-core-v2/src/agent/toolApproval/toolApproval.ts +++ b/packages/agent-core-v2/src/agent/toolApproval/toolApproval.ts @@ -1,3 +1,12 @@ +/** + * `toolApproval` domain — `IAgentToolApprovalService` contract. + * + * Shared approval round-trip for tool executions: builds the approval request, + * drives the session approval broker, emits the `permission.approval.*` + * events, records session-scope approval rules through `permissionRules`, and + * resolves ask continuations. Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { ApprovalResponse, diff --git a/packages/agent-core-v2/src/agent/toolApproval/toolApprovalService.ts b/packages/agent-core-v2/src/agent/toolApproval/toolApprovalService.ts index 3270517c5..354d0bfc6 100644 --- a/packages/agent-core-v2/src/agent/toolApproval/toolApprovalService.ts +++ b/packages/agent-core-v2/src/agent/toolApproval/toolApprovalService.ts @@ -1,5 +1,13 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { randomUUID } from 'node:crypto'; +/** + * `toolApproval` domain — `IAgentToolApprovalService` implementation. + * + * Owns the approval round-trip: publishes + * `permission.approval.requested/resolved` through `eventBus`, awaits the + * session approval broker (absent broker = auto-approve), records + * session-scope approval rules through `permissionRules`, reports + * `permission_approval_result` through `telemetry`, and folds ask + * continuations back into authorize results. Bound at Agent scope. + */ import { IInstantiationService } from '#/_base/di/instantiation'; import { Service } from '#/_base/di/service'; @@ -8,6 +16,7 @@ import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { abortable, isUserCancellation } from '#/_base/utils/abort'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import type { + ApprovalRequest, ApprovalResponse, PermissionPolicyResolution, PermissionPolicyResult, @@ -19,47 +28,37 @@ import type { BeforeExecuteDecision, ResolvedToolExecutionHookContext, } from '#/agent/toolExecutor/toolHooks'; -import { AgentEvent2 } from '#/app/event/event2'; +import { IEventBus } from '#/app/event/eventBus'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { ISessionApprovalService } from '#/session/approval/approval'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import type { ToolInputDisplay } from '#/tool/toolInputDisplay'; import { IAgentToolApprovalService } from './toolApproval'; -export interface PermissionApprovalRequestedPayload { - readonly id?: string; +export type PermissionApprovalRequestContext = ApprovalRequest & { readonly sessionId?: string; - readonly agentId: string; + readonly agentId?: string; readonly turnId: number; - readonly toolCallId: string; - readonly toolName: string; - readonly action: string; - readonly display: ToolInputDisplay; readonly toolInput: unknown; -} +}; -export class PermissionApprovalRequested extends AgentEvent2<PermissionApprovalRequestedPayload> { - static override readonly type = 'permission.approval.requested'; - static override readonly observable = true; -} -export interface PermissionApprovalRequested extends PermissionApprovalRequestedPayload {} +export type PermissionApprovalResultContext = PermissionApprovalRequestContext & + ( + | ApprovalResponse + | { + readonly decision: 'error'; + readonly error: string; + } + ); -export interface PermissionApprovalResolvedPayload extends PermissionApprovalRequestedPayload { - readonly decision: 'approved' | 'rejected' | 'cancelled' | 'error'; - readonly scope?: 'session'; - readonly feedback?: string; - readonly selectedLabel?: string; - readonly error?: string; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'permission.approval.requested': PermissionApprovalRequestContext; + 'permission.approval.resolved': PermissionApprovalResultContext; + } } -export class PermissionApprovalResolved extends AgentEvent2<PermissionApprovalResolvedPayload> { - static override readonly type = 'permission.approval.resolved'; - static override readonly observable = true; -} -export interface PermissionApprovalResolved extends PermissionApprovalResolvedPayload {} - export class AgentToolApprovalService extends Service implements IAgentToolApprovalService { declare readonly _serviceBrand: undefined; @@ -70,7 +69,7 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro @ISessionContext private readonly session: ISessionContext, @IInstantiationService private readonly instantiation: IInstantiationService, @ITelemetryService private readonly telemetry: ITelemetryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IEventBus private readonly eventBus: IEventBus, ) { super(); } @@ -115,7 +114,6 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro detail: context.args, } as ToolInputDisplay); const approvalRequest = { - id: `approval_${randomUUID()}`, sessionId: this.session.sessionId, agentId: this.scopeContext.agentId, turnId: context.turnId, @@ -127,7 +125,7 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro const approvalContext = { ...approvalRequest, toolInput: context.args, - } satisfies PermissionApprovalRequestedPayload; + } satisfies PermissionApprovalRequestContext; const startedAt = Date.now(); let response: ApprovalResponse; @@ -135,7 +133,7 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro if (approvalService === undefined) { response = { decision: 'approved' }; } else { - void this.dispatcher.dispatch(new PermissionApprovalRequested(approvalContext)); + this.eventBus.publish({ type: 'permission.approval.requested', ...approvalContext }); try { response = await abortable( approvalService.request(approvalRequest), @@ -157,13 +155,12 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro has_feedback: false, trace_id: context.trace?.traceId, }); - void this.dispatcher.dispatch( - new PermissionApprovalResolved({ - ...approvalContext, - decision: 'error', - error: error instanceof Error ? error.message : String(error), - }), - ); + this.eventBus.publish({ + type: 'permission.approval.resolved', + ...approvalContext, + decision: 'error', + error: error instanceof Error ? error.message : String(error), + }); const resolved = result.resolveError?.(error); if (resolved !== undefined) { return this.resolvePermissionResolution(resolved, context, origin); @@ -177,12 +174,11 @@ export class AgentToolApprovalService extends Service implements IAgentToolAppro ? context.execution.approvalRule : undefined; if (approvalService !== undefined) { - void this.dispatcher.dispatch( - new PermissionApprovalResolved({ - ...approvalContext, - ...response, - }), - ); + this.eventBus.publish({ + type: 'permission.approval.resolved', + ...approvalContext, + ...response, + }); } this.rulesService.recordApprovalResult({ turnId: context.turnId, diff --git a/packages/agent-core-v2/src/agent/toolDedupe/toolDedupe.ts b/packages/agent-core-v2/src/agent/toolDedupe/toolDedupe.ts index 95dccc8a0..affffa7f3 100644 --- a/packages/agent-core-v2/src/agent/toolDedupe/toolDedupe.ts +++ b/packages/agent-core-v2/src/agent/toolDedupe/toolDedupe.ts @@ -1,3 +1,13 @@ +/** + * `toolDedupe` domain — per-turn tool-call deduplication. + * + * A self-wiring plugin: it participates in `turn` step boundaries and + * `IAgentToolExecutorService`'s will/did hooks to suppress same-step duplicates and inject + * cross-step repeat reminders. No other service injects it — the container + * constructs it eagerly at Agent scope so its constructor registers the hooks. + * Agent-scoped — one instance per agent. + */ + import type { ContentPart } from '#/kosong/contract/message'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/toolDedupe/toolDedupeService.ts b/packages/agent-core-v2/src/agent/toolDedupe/toolDedupeService.ts index 756bdc044..617336bd9 100644 --- a/packages/agent-core-v2/src/agent/toolDedupe/toolDedupeService.ts +++ b/packages/agent-core-v2/src/agent/toolDedupe/toolDedupeService.ts @@ -1,55 +1,62 @@ +/** + * `toolDedupe` domain — `IAgentToolDedupeService` implementation. + * + * Self-wiring plugin: its constructor registers `loop` onWillBeginStep/onDidFinishStep + * hooks, an `onBeforeExecuteTool` veto listener (same-step duplicates are + * vetoed with a placeholder synthetic result), and an `onDidExecuteTool` + * hook to drive same-step suppression and cross-step repeat reminders, and + * reports repeat telemetry through `telemetry`. The mutable dedupe state + * (`stepCalls`, `originalCallIndex`, `syntheticCallIds`, `callKeyByCallId`, + * `consecutiveKey`, `consecutiveCount`, `activeTurnId`, `activeStep`) is + * registered into `agentState` (`IAgentStateService`) and read/written + * through it; the `stepDeferreds` promise locks stay plain fields. + * Constructed eagerly at + * Agent scope so the hooks are installed without any other service + * injecting it. + */ + import { createHash } from 'node:crypto'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { canonicalTelemetryArgs } from '#/_base/utils/canonical-args'; -import type { - ToolCallDedupDetectedEvent, - ToolCallRepeatEvent, - ToolCallTurnRepeatEvent, -} from '#/app/telemetry/events'; +import type { ToolCallDedupDetectedEvent, ToolCallRepeatEvent } from '#/app/telemetry/events'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; import { parseToolCallArguments } from '#/tool/tool-args-parse'; import { IAgentLoopService } from '#/agent/loop/loop'; import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventBus } from '#/app/event/eventBus'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { wrapSystemReminder } from '#/features/reminder/systemReminder'; import { IAgentToolExecutorService, type ToolCallDupType } from '#/agent/toolExecutor/toolExecutor'; import type { ContentPart } from '#/kosong/contract/message'; import { IAgentToolDedupeService, type ToolDedupeResult } from './toolDedupe'; const REMINDER_TEXT_1 = - '\n\n' + - wrapSystemReminder( - 'The same tool call has been repeated several times in a row. ' + - 'Before making your next call, write one sentence stating what new information you expect it to produce. ' + - 'Then act on that sentence: if it names something this result does not already give you, choose the action that best provides it; otherwise, continue with the evidence you already have.', - ); + '\n\n<system-reminder>\n' + + 'The same tool call has been repeated several times in a row. ' + + 'Before making your next call, write one sentence stating what new information you expect it to produce. ' + + 'Then act on that sentence: if it names something this result does not already give you, choose the action that best provides it; otherwise, continue with the evidence you already have.' + + '\n</system-reminder>'; function makeReminderText2(repeatCount: number): string { return ( - '\n\n' + - wrapSystemReminder( - `The same tool call has now been issued ${String(repeatCount)} times in a row. ` + - 'Choose exactly one of the following and state your choice before acting:\n' + - '(1) Falsification check: run the cheapest test that could conclusively disprove your current approach, if such a test exists.\n' + - '(2) Missing input: tell the user precisely what information or decision you need to proceed, and ask for it.\n' + - '(3) Conclude: deliver your best result based on the evidence already gathered, listing anything that remains uncertain.', - ) + '\n\n<system-reminder>\n' + + `The same tool call has now been issued ${String(repeatCount)} times in a row. ` + + 'Choose exactly one of the following and state your choice before acting:\n' + + '(1) Falsification check: run the cheapest test that could conclusively disprove your current approach, if such a test exists.\n' + + '(2) Missing input: tell the user precisely what information or decision you need to proceed, and ask for it.\n' + + '(3) Conclude: deliver your best result based on the evidence already gathered, listing anything that remains uncertain.' + + '\n</system-reminder>' ); } const REMINDER_TEXT_3 = - '\n\n' + - wrapSystemReminder( - 'Write your final response now, without any further tool calls. ' + - 'Cover: the current blocker, each approach you have tried and what it established, and the specific information or decision you need from the user to unblock progress. ' + - 'Text only.', - ); + '\n\n<system-reminder>\n' + + 'Write your final response now, without any further tool calls. ' + + 'Cover: the current blocker, each approach you have tried and what it established, and the specific information or decision you need from the user to unblock progress. ' + + 'Text only.' + + '\n</system-reminder>'; const REPEAT_REMINDER_1_START = 3; const REPEAT_REMINDER_2_START = 5; @@ -77,19 +84,10 @@ function argsHash(args: unknown): string { return createHash('sha256').update(canonicalTelemetryArgs(args)).digest('hex').slice(0, 8); } -function callSignature(key: string): string { - return createHash('sha256').update(key).digest('hex'); -} - interface CheckedToolCall { readonly syntheticResult: ToolDedupeResult | null; } -interface TurnCallRecord { - count: number; - lastStep: number; -} - function appendReminder(result: ToolDedupeResult, reminderText: string): ToolDedupeResult { const output = result.output; let newOutput: string | ContentPart[]; @@ -143,14 +141,6 @@ export const toolDedupeActiveTurnIdKey = defineState<number | undefined>( () => undefined as number | undefined, ); export const toolDedupeActiveStepKey = defineState<number>('toolDedupe.activeStep', () => 0); -export const toolDedupeTurnCallRecordsKey = defineState<Map<string, TurnCallRecord>>( - 'toolDedupe.turnCallRecords', - () => new Map(), -); -export const toolDedupeTurnRepeatCountKey = defineState<number>( - 'toolDedupe.turnRepeatCount', - () => 0, -); export class AgentToolDedupeService extends Service implements IAgentToolDedupeService { declare readonly _serviceBrand: undefined; @@ -161,20 +151,16 @@ export class AgentToolDedupeService extends Service implements IAgentToolDedupeS @IAgentLoopService loop: IAgentLoopService, @IAgentToolExecutorService private readonly toolExecutor: IAgentToolExecutorService, @IAgentStateService private readonly states: IAgentStateService, - @IEventBus eventBus: IEventBus, ) { super(); - this.states.contributeState(toolDedupeStepCallsKey); - this.states.contributeState(toolDedupeOriginalCallIndexKey); - this.states.contributeState(toolDedupeSyntheticCallIdsKey); - this.states.contributeState(toolDedupeCallKeyByCallIdKey); - this.states.contributeState(toolDedupeConsecutiveKeyKey); - this.states.contributeState(toolDedupeConsecutiveCountKey); - this.states.contributeState(toolDedupeActiveTurnIdKey); - this.states.contributeState(toolDedupeActiveStepKey); - this.states.contributeState(toolDedupeTurnCallRecordsKey); - this.states.contributeState(toolDedupeTurnRepeatCountKey); - this._register(eventBus.subscribe(TurnEnded, () => this.clearTurnRecords())); + this.states.register(toolDedupeStepCallsKey); + this.states.register(toolDedupeOriginalCallIndexKey); + this.states.register(toolDedupeSyntheticCallIdsKey); + this.states.register(toolDedupeCallKeyByCallIdKey); + this.states.register(toolDedupeConsecutiveKeyKey); + this.states.register(toolDedupeConsecutiveCountKey); + this.states.register(toolDedupeActiveTurnIdKey); + this.states.register(toolDedupeActiveStepKey); loop.hooks.onWillBeginStep.register('toolDedupe', async (ctx, next) => { this.beginStep(ctx.turnId, ctx.step); await next(); @@ -268,29 +254,11 @@ export class AgentToolDedupeService extends Service implements IAgentToolDedupeS this.states.set(toolDedupeActiveStepKey, value); } - private get turnCallRecords(): Map<string, TurnCallRecord> { - return this.states.get(toolDedupeTurnCallRecordsKey); - } - - private get turnRepeatCount(): number { - return this.states.get(toolDedupeTurnRepeatCountKey); - } - - private set turnRepeatCount(value: number) { - this.states.set(toolDedupeTurnRepeatCountKey, value); - } - - private clearTurnRecords(): void { - this.turnCallRecords.clear(); - this.turnRepeatCount = 0; - } - private beginStep(turnId?: number, step?: number): void { if (turnId !== undefined && turnId !== this.activeTurnId) { this.activeTurnId = turnId; this.consecutiveKey = null; this.consecutiveCount = 0; - this.clearTurnRecords(); } if (step !== undefined) { this.activeStep = step; @@ -320,36 +288,6 @@ export class AgentToolDedupeService extends Service implements IAgentToolDedupeS } } - private recordTurnRepeat( - toolCallId: string, - toolName: string, - args: unknown, - key: string, - trace: LLMRequestTrace | undefined, - ): void { - const signature = callSignature(key); - const record = this.turnCallRecords.get(signature); - if (record === undefined) { - this.turnCallRecords.set(signature, { count: 0, lastStep: this.activeStep }); - return; - } - if (record.lastStep === this.activeStep) return; - - record.count += 1; - record.lastStep = this.activeStep; - this.turnRepeatCount += 1; - const properties: ToolCallTurnRepeatEvent = { - turn_id: this.activeTurnId, - step_no: this.activeStep, - tool_call_id: toolCallId, - tool_name: toolName, - turn_repeat_count: this.turnRepeatCount, - args_hash: argsHash(args), - trace_id: trace?.traceId, - }; - this.telemetry.track2('tool_call_turn_repeat', properties); - } - private checkToolCall( toolCallId: string, toolName: string, @@ -367,7 +305,6 @@ export class AgentToolDedupeService extends Service implements IAgentToolDedupeS this.recordDupType(toolCallId, toolName, args, 'same_step', trace); return { syntheticResult: DEDUPE_PLACEHOLDER_RESULT }; } - this.recordTurnRepeat(toolCallId, toolName, args, key, trace); this.stepDeferreds.set(key, makeDeferred<ToolDedupeResult>()); this.originalCallIndex.set(toolCallId, index); if (this.consecutiveKey === key && this.consecutiveCount > 0) { diff --git a/packages/agent-core-v2/src/agent/toolExecutor/beforeToolExecuteEvent.ts b/packages/agent-core-v2/src/agent/toolExecutor/beforeToolExecuteEvent.ts index 32fa99dc2..7f2f27807 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/beforeToolExecuteEvent.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/beforeToolExecuteEvent.ts @@ -1,3 +1,27 @@ +/** + * `toolExecutor` domain — `onBeforeExecuteTool` veto-event machinery. + * + * `BeforeToolExecuteEventImpl` is the per-fire event object listeners + * adjudicate through; `BeforeToolExecuteEmitter` owns the listener registry + * and the two-pass fire: + * + * 1. immediate statements — each listener is awaited in registration order; + * `veto(result)` wins on the spot (first come, first served) and + * `allow()` ends adjudication outright, both before any later listener + * runs; + * 2. deferred adjudications — only when pass 1 produced no decision, the + * cold factories registered via `waitUntil(factory)` are invoked one at a + * time; the first returned `veto` decides the call, while a returned + * `executionMetadata` joins the pass trace. + * + * Because the factories stay cold through pass 1, an approval round-trip + * (the only side-effecting adjudication) can never start while another + * listener would have denied the call. All four statements throw once the + * statement window closes (mirroring `AsyncEmitter`'s "waitUntil can NOT be + * called asynchronously" rule): a late veto would otherwise be silently + * ignored. + */ + import { Emitter } from '#/_base/event'; import { BugIndicatingError } from '#/errors'; import type { ToolCall } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutor.ts b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutor.ts index f4bd72b2e..c992c6d7d 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutor.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutor.ts @@ -1,3 +1,12 @@ +/** + * `toolExecutor` domain — Agent-scope tool execution contract. + * + * Defines the public execution surface for provider tool calls, the + * before/will execution-interception events, the did execution hook, + * tool-call result settlement, duplicate-call tagging for telemetry, and + * preflight description extension points. Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorEvents.ts b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorEvents.ts index b72c15825..e0c858c31 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorEvents.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorEvents.ts @@ -1,10 +1,13 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { AgentEvent2 } from '#/app/event/event2'; +/** + * `toolExecutor` domain — the `tool.call.*` / `tool.progress` / `tool.result` + * event payloads published through `IEventBus` as tool calls execute. + */ + import type { ToolUpdate } from '#/tool/toolContract'; import type { ToolInputDisplay } from '#/tool/toolInputDisplay'; -export interface ToolCallStartedPayload { - readonly agentId: string; +export interface ToolCallStartedEvent { + readonly type: 'tool.call.started'; readonly turnId: number; readonly toolCallId: string; readonly name: string; @@ -13,27 +16,15 @@ export interface ToolCallStartedPayload { readonly display?: ToolInputDisplay; } -export class ToolCallStarted extends AgentEvent2<ToolCallStartedPayload> { - static override readonly type = 'tool.call.started'; - static override readonly observable = true; -} -export interface ToolCallStarted extends ToolCallStartedPayload {} - -export interface ToolProgressPayload { - readonly agentId: string; +export interface ToolProgressEvent { + readonly type: 'tool.progress'; readonly turnId: number; readonly toolCallId: string; readonly update: ToolUpdate; } -export class ToolProgress extends AgentEvent2<ToolProgressPayload> { - static override readonly type = 'tool.progress'; - static override readonly observable = true; -} -export interface ToolProgress extends ToolProgressPayload {} - -export interface ToolResultEventPayload { - readonly agentId: string; +export interface ToolResultEvent { + readonly type: 'tool.result'; readonly turnId: number; readonly toolCallId: string; readonly output: unknown; @@ -41,8 +32,10 @@ export interface ToolResultEventPayload { readonly synthetic?: boolean; } -export class ToolResultEvent extends AgentEvent2<ToolResultEventPayload> { - static override readonly type = 'tool.result'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'tool.call.started': ToolCallStartedEvent; + 'tool.result': ToolResultEvent; + 'tool.progress': ToolProgressEvent; + } } -export interface ToolResultEvent extends ToolResultEventPayload {} diff --git a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorService.ts b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorService.ts index cd6534193..8f5680650 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorService.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/toolExecutorService.ts @@ -1,8 +1,24 @@ +/** + * `toolExecutor` domain — `IAgentToolExecutorService` implementation. + * + * Resolves executable tools through `toolRegistry`, adjudicates tool calls + * through the `onBeforeExecuteTool` veto event, awaits readiness work + * through the `onWillExecuteTool` participation event, finalizes results + * through the ordered `onDidExecuteTool` hook, publishes tool lifecycle + * events through `event`, records telemetry through `telemetry`, truncates + * oversized outputs through `toolResultTruncation`, and logs parse + * diagnostics through `log`. The mutable dup-type tracking state + * (`toolCallDupTypes`, `dupTypeTurnId`) is registered into `agentState` + * (`IAgentStateService`) and read/written through it; the emitters, the hook + * slot, and the describer/guard registration slots stay plain fields. Bound + * at Agent scope. + */ + import { toDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { AsyncEmitter, type Event } from '#/_base/event'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import type { ContentPart, ToolCall } from '#/kosong/contract/message'; import type { ToolInputDisplay } from '@moonshot-ai/protocol'; @@ -15,7 +31,7 @@ import { import { parseToolCallArguments } from '#/tool/tool-args-parse'; import { PathSecurityError } from '#/tool/path-access'; import { isAbortError, isUserCancellation } from '#/_base/utils/abort'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IEventBus } from '#/app/event/eventBus'; import { ToolAccesses, type ExecutableTool, @@ -33,7 +49,6 @@ import type { WillExecuteToolEvent, } from '#/agent/toolExecutor/toolHooks'; import { IAgentStateService } from '#/agent/state/agentState'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { ILogService } from '#/_base/log/log'; import type { ToolCallEvent } from '#/app/telemetry/events'; @@ -50,17 +65,14 @@ import { type ToolExecutorExecuteOptions, type UnavailableToolDescriber, } from './toolExecutor'; -import { ToolCallStarted, ToolProgress, ToolResultEvent } from './toolExecutorEvents'; import { ToolScheduler } from './toolScheduler'; +import './toolExecutorEvents'; const ABORT_GRACE_MS = 2_000; const TOOL_OUTPUT_EMPTY = 'Tool output is empty.'; const TOOL_OUTPUT_NON_TEXT = 'Tool returned non-text content.'; -const validators = new WeakMap< - ExecutableTool, - { schema: Record<string, unknown>; validator: ToolArgsValidator } ->(); +const validators = new WeakMap<ExecutableTool, ToolArgsValidator>(); export interface ToolExecutionTask { readonly accesses: ToolAccesses; @@ -149,17 +161,16 @@ export class AgentToolExecutorService implements IAgentToolExecutorService { } constructor( - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IEventBus private readonly eventBus: IEventBus, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentToolResultTruncationService private readonly resultTruncation: IAgentToolResultTruncationService, @IAgentStateService private readonly states: IAgentStateService, @ILogService private readonly log?: ILogService, ) { - this.states.contributeState(toolExecutorToolCallDupTypesKey); - this.states.contributeState(toolExecutorDupTypeTurnIdKey); + this.states.register(toolExecutorToolCallDupTypesKey); + this.states.register(toolExecutorDupTypeTurnIdKey); } private get toolCallDupTypes(): Map<string, ToolCallDupType> { @@ -572,17 +583,15 @@ export class AgentToolExecutorService implements IAgentToolExecutorService { options: ToolExecutorExecuteOptions, displayFields?: ToolCallDisplayFields, ): void { - void this.dispatcher.dispatch( - new ToolCallStarted({ - agentId: this.scopeContext.agentId, - turnId: options.turnId, - toolCallId: call.toolCall.id, - name: call.toolName, - args, - description: displayFields?.description, - display: displayFields?.display, - }), - ); + this.eventBus.publish({ + type: 'tool.call.started', + turnId: options.turnId, + toolCallId: call.toolCall.id, + name: call.toolName, + args, + description: displayFields?.description, + display: displayFields?.display, + }); options.onToolCall?.({ toolCallId: call.toolCall.id, name: call.toolName, @@ -595,15 +604,13 @@ export class AgentToolExecutorService implements IAgentToolExecutorService { result: ToolResult, options: ToolExecutorExecuteOptions, ): void { - void this.dispatcher.dispatch( - new ToolResultEvent({ - agentId: this.scopeContext.agentId, - turnId: options.turnId, - toolCallId: call.toolCall.id, - output: result.output, - isError: result.isError, - }), - ); + this.eventBus.publish({ + type: 'tool.result', + turnId: options.turnId, + toolCallId: call.toolCall.id, + output: result.output, + isError: result.isError, + }); } private dispatchToolProgress( @@ -611,14 +618,12 @@ export class AgentToolExecutorService implements IAgentToolExecutorService { update: ToolUpdate, options: ToolExecutorExecuteOptions, ): void { - void this.dispatcher.dispatch( - new ToolProgress({ - agentId: this.scopeContext.agentId, - turnId: options.turnId, - toolCallId: call.toolCall.id, - update, - }), - ); + this.eventBus.publish({ + type: 'tool.progress', + turnId: options.turnId, + toolCallId: call.toolCall.id, + update, + }); } private async finalizeToolResult( @@ -788,17 +793,16 @@ function preflightToolCall( } function validateExecutableToolArgs(tool: ExecutableTool, args: unknown): string | null { - const schema = tool.parameters; - let cached = validators.get(tool); - if (cached === undefined || cached.schema !== schema) { + let validator = validators.get(tool); + if (validator === undefined) { try { - cached = { schema, validator: compileToolArgsValidator(schema) }; - validators.set(tool, cached); + validator = compileToolArgsValidator(tool.parameters); + validators.set(tool, validator); } catch (error) { return error instanceof Error ? error.message : String(error); } } - return validateToolArgs(cached.validator, args as JsonType); + return validateToolArgs(validator, args as JsonType); } function toolCallDisplayFieldsFromExecution( diff --git a/packages/agent-core-v2/src/agent/toolExecutor/toolHooks.ts b/packages/agent-core-v2/src/agent/toolExecutor/toolHooks.ts index c14472af0..5e86954f3 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/toolHooks.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/toolHooks.ts @@ -1,3 +1,32 @@ +/** + * `toolExecutor` domain — tool-execution event and hook contexts. + * + * Defines the event objects and context records carried by + * `IAgentToolExecutorService`'s execution-interception surface: + * + * - `onBeforeExecuteTool` (veto event, `BeforeToolExecuteEvent`): listeners + * answer with `veto(result)` (replace the execution with the given tool + * result — an `isError: true` result reads as a denial, anything else as a + * short-circuit; first one wins), `allow()` (final pass, ends all + * adjudication), `pass(metadata)` (pass with an `executionMetadata` trace, + * ends nothing), or `waitUntil(factory)` (defer an adjudication that needs + * external input — the fire side invokes the cold factory only when no + * listener vetoed or allowed outright, so an ask round-trip can never start + * while another listener would have denied). No ids, no ordering contract. + * - `onWillExecuteTool` (waitUntil participation event, + * `WillExecuteToolEvent`): listeners attach hot promises via + * `waitUntil(promise)`; the executor awaits all of them before dispatching + * an allowed call (e.g. MCP initial load). + * - `hooks.onDidExecuteTool` (ordered hook slot, `ToolDidExecuteContext`): + * post-execution result finalization with the resolved execution's canonical + * resource accesses and an outcome describing whether the execution callback + * actually ran, kept as an `OrderedHookSlot`. Every call reaches it — + * including preflight-rejected ones (missing/unavailable tool, guard denial, + * invalid args), which arrive without `tool` or `accesses` set. + * + * Pure contract (types only); no scoped service. + */ + import type { IWaitUntil } from '#/_base/event'; import type { ToolCall } from '#/kosong/contract/message'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; diff --git a/packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts b/packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts index 64be16d2a..cdae83bfa 100644 --- a/packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts +++ b/packages/agent-core-v2/src/agent/toolExecutor/toolScheduler.ts @@ -1,5 +1,15 @@ +/** + * Stateful execution scheduler for tool calls in one model step. + * + * The scheduler owns only execution ordering: + * - tasks with non-conflicting resource accesses may overlap + * - tasks with conflicting resource accesses wait for the conflicting active tasks + * - callers decide whether to drain results in provider order or completion order + */ + import { ToolAccesses } from '#/tool/toolContract'; + export interface ToolCallTask<Result> { readonly accesses: ToolAccesses; readonly start: () => Promise<{ readonly result: Promise<Result> }>; diff --git a/packages/agent-core-v2/src/agent/toolPolicy/configSection.ts b/packages/agent-core-v2/src/agent/toolPolicy/configSection.ts index 61df6360d..774a04792 100644 --- a/packages/agent-core-v2/src/agent/toolPolicy/configSection.ts +++ b/packages/agent-core-v2/src/agent/toolPolicy/configSection.ts @@ -1,3 +1,11 @@ +/** + * `toolPolicy` domain — the global `tools` tool-activation section. + * + * The `tools` section is the global tool switch: `enabled` is an allowlist + * (when non-empty, only listed tools are active) and `disabled` a denylist, + * applied on top of every profile's own `tools` / `disallowedTools` policy. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/agent/toolPolicy/evaluate.ts b/packages/agent-core-v2/src/agent/toolPolicy/evaluate.ts index ae5631415..5e2af5e49 100644 --- a/packages/agent-core-v2/src/agent/toolPolicy/evaluate.ts +++ b/packages/agent-core-v2/src/agent/toolPolicy/evaluate.ts @@ -1,3 +1,28 @@ +/** + * `toolPolicy` domain — pure tool-activation policy evaluation. + * + * Applies allowlists and denylists with builtin/MCP matching semantics shared + * by Agent authorization, profile prompt construction, and child-agent setup. + * `isToolActiveComposed` intersects the policy layers (workspace os-level + * veto, profile, global `[tools]` config, Session denylist — the workspace + * veto first, outranking the rest) so every consumer evaluates the same + * combination instead of re-implementing it. An empty/absent global `enabled` + * list means unconstrained — an explicit empty list must never disable + * everything. + * + * `findInactiveToolPatterns` statically inspects policy entries so + * misconfigurations surface as warnings instead of silently shrinking the + * active tool set. Three entry shapes are dead on arrival under + * `isToolActive`: `wildcard-not-mcp` (non-MCP entries match builtin/user + * tools by exact name only, and the MCP branch filters entries without the + * `mcp__` prefix, so a wildcard outside `mcp__…` patterns can never match — a + * bare `*` in an allowlist disables everything, in a denylist it is a + * no-op), `incomplete-mcp-name` (an `mcp__…` literal without glob magic must + * be a full `mcp__<server>__<tool>` name; `mcp__github__*` is the working + * form for a whole server), and `unknown-tool` (a literal naming no + * registered tool and no builtin-profile tool is almost always a typo). + */ + import picomatch from 'picomatch'; import { isMcpToolName, type ToolSource } from '#/tool/toolContract'; diff --git a/packages/agent-core-v2/src/agent/toolPolicy/toolPolicy.ts b/packages/agent-core-v2/src/agent/toolPolicy/toolPolicy.ts index 5843db376..20fd721f1 100644 --- a/packages/agent-core-v2/src/agent/toolPolicy/toolPolicy.ts +++ b/packages/agent-core-v2/src/agent/toolPolicy/toolPolicy.ts @@ -1,3 +1,10 @@ +/** + * `toolPolicy` domain — Agent-scope tool authorization contract. + * + * Combines profile, global configuration, and Session-owned restrictions into + * one policy used by both provider schema projection and executor preflight. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { ToolSource } from '#/tool/toolContract'; diff --git a/packages/agent-core-v2/src/agent/toolPolicy/toolPolicyService.ts b/packages/agent-core-v2/src/agent/toolPolicy/toolPolicyService.ts index 3c16c69f3..ff7fb53c8 100644 --- a/packages/agent-core-v2/src/agent/toolPolicy/toolPolicyService.ts +++ b/packages/agent-core-v2/src/agent/toolPolicy/toolPolicyService.ts @@ -1,3 +1,16 @@ +/** + * `toolPolicy` domain — Agent-scope tool authorization service. + * + * Intersects the workspace os-level veto (the seeded `sessionToolPolicyGate`, + * which outranks everything below it), the bound profile policy, global + * `[tools]` configuration, and Session denylist (composed by + * `isToolActiveComposed`), and installs the resulting + * authorization check into the L3 executor preflight so direct tool calls + * cannot bypass schema filtering. Disclosure entries retain their implicit + * availability when a profile allowlist omits them, while explicit deny + * layers still apply. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -13,6 +26,7 @@ import type { ToolSource } from '#/tool/toolContract'; import { isToolActiveComposed, type ToolActivationPolicy } from './evaluate'; import { IAgentToolPolicyService } from './toolPolicy'; +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class AgentToolPolicyService extends Disposable implements IAgentToolPolicyService { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/agent/toolRegistry/builtinToolAssemblyService.ts b/packages/agent-core-v2/src/agent/toolRegistry/builtinToolAssemblyService.ts index 16a558a9e..38f1de552 100644 --- a/packages/agent-core-v2/src/agent/toolRegistry/builtinToolAssemblyService.ts +++ b/packages/agent-core-v2/src/agent/toolRegistry/builtinToolAssemblyService.ts @@ -1,3 +1,17 @@ +/** + * `toolRegistry` domain — the built-in tool assembly unit. + * + * The one bridge from the static contribution table into the collection + * world: constructed once at App-scope creation, it provides every + * module-level `registerAgentToolService` contribution (import = register) + * into the `AgentToolContribution` collection. Ancestor visibility lets + * every Agent scope's fold (`AgentToolActivationService`) see these + * records; withdrawing is not a built-in concept (the table is static), so + * the records live as long as this unit. The table itself stays the static + * data channel for the readers that only need names (profile typo + * warnings, agent-tool descriptions). Bound at App scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/agent/toolRegistry/toolContribution.ts b/packages/agent-core-v2/src/agent/toolRegistry/toolContribution.ts index b7e850620..2ccc8481e 100644 --- a/packages/agent-core-v2/src/agent/toolRegistry/toolContribution.ts +++ b/packages/agent-core-v2/src/agent/toolRegistry/toolContribution.ts @@ -1,16 +1,49 @@ +/** + * `toolRegistry` domain — module-level agent-tool contribution registry. + * + * Tools contribute themselves at module load via + * `registerAgentToolService(identifier, ctor, options?)` — a double registration: + * the tool is registered as an Agent-scope DI service + * (`registerScopedService`) and recorded in this contribution table. The DI + * registration explicitly uses `OnDemand` scope activation, so no tool + * constructor runs at scope creation — constructors may legitimately throw + * when their host capability is absent (e.g. `WebSearchTool` without a + * configured provider), and the runtime registry always holds real instances, + * never proxies. + * The App-scope built-in assembly (`builtinToolAssemblyService`) provides + * the table into the `AgentToolContribution` collection once at App-scope + * creation; the fold (`AgentToolActivationService`) consumes the collection + * view when an Agent is created: for each record whose `when` predicate + * holds and whose `name` the bound Profile's tool policy allows, it + * resolves the service through the container (`accessor.get`, triggering + * construction) and registers it into the per-agent runtime registry. The + * declared `name` is what lets activation filter without instantiating. + * + * `registerAgentToolService` is deliberately not "builtin"-scoped: the same API is + * what external contributors (plugins, SDK consumers) will use once the + * surface is public. The tool's origin is carried by `options.source` + * (`'builtin'` / `'user'` / `'mcp'` / …), not by the registration API. + * + * Tools are always Agent-scoped services (each Agent has its own tool + * registry, and tool constructors inject Agent-scope services), so no `scope` + * parameter is exposed. If tools at other scopes are ever needed, add it + * optionally without breaking existing callers. + */ + import type { ServiceIdentifier, ServicesAccessor } from '#/_base/di/instantiation'; import { collection } from '#/_base/di/collection'; import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, overrideScopedService, registerScopedService } from '#/_base/di/scope'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import type { AgentTool, ToolDisclosure, ToolSource, } from '#/tool/toolContract'; -import type { RuntimeCapability } from '#/runtime/runtime'; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type AnyAgentTool = AgentTool<any>; +// eslint-disable-next-line @typescript-eslint/no-explicit-any export type AgentToolCtor<T extends AnyAgentTool = AnyAgentTool> = new (...args: any[]) => T; export interface AgentToolContributionOptions { @@ -18,7 +51,6 @@ export interface AgentToolContributionOptions { readonly source?: ToolSource; readonly disclosure?: ToolDisclosure; readonly when?: (accessor: ServicesAccessor) => boolean; - readonly requiredRuntimeCapabilities?: readonly RuntimeCapability[]; readonly domain?: string; } @@ -47,26 +79,6 @@ export function registerAgentToolService<T extends AnyAgentTool>( _agentToolContributions.push({ id, ctor, options }); } -export function overrideAgentToolService<T extends AnyAgentTool>( - id: ServiceIdentifier<T>, - ctor: AgentToolCtor<T>, - options: AgentToolContributionOptions, -): void { - overrideScopedService( - LifecycleScope.Agent, - id, - ctor, - ScopeActivation.OnDemand, - options.domain ?? 'unknown', - ); - const index = _agentToolContributions.findIndex((contribution) => contribution.id === id); - if (index === -1) { - _agentToolContributions.push({ id, ctor, options }); - } else { - _agentToolContributions[index] = { id, ctor, options }; - } -} - export function getAgentToolContributions(): readonly AgentToolContribution[] { return _agentToolContributions; } diff --git a/packages/agent-core-v2/src/agent/toolRegistry/toolRegistry.ts b/packages/agent-core-v2/src/agent/toolRegistry/toolRegistry.ts index 10276a785..f0bf0565d 100644 --- a/packages/agent-core-v2/src/agent/toolRegistry/toolRegistry.ts +++ b/packages/agent-core-v2/src/agent/toolRegistry/toolRegistry.ts @@ -1,3 +1,11 @@ +/** + * `toolRegistry` domain — `IAgentToolRegistryService` contract. + * + * Per-agent registry of the tools an agent can resolve and run: `register` / + * `unregister` / `list` / `resolve`, plus `onRegistered` / `onUnregistered` + * hooks. Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; import type { diff --git a/packages/agent-core-v2/src/agent/toolRegistry/toolRegistryService.ts b/packages/agent-core-v2/src/agent/toolRegistry/toolRegistryService.ts index a643d9921..3ad9704bd 100644 --- a/packages/agent-core-v2/src/agent/toolRegistry/toolRegistryService.ts +++ b/packages/agent-core-v2/src/agent/toolRegistry/toolRegistryService.ts @@ -1,3 +1,11 @@ +/** + * `toolRegistry` domain — `IAgentToolRegistryService` implementation. + * + * The per-agent tool table (`tools`) stays a plain instance field: its values + * hold `ExecutableTool` class instances, not plain data, so it is not + * registered into `agentState` (`IAgentStateService`). Bound at Agent scope. + */ + import { toDisposable, type IDisposable } from "#/_base/di/lifecycle"; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts b/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts index 4fac7ffe0..a36b0df33 100644 --- a/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts +++ b/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncation.ts @@ -1,3 +1,13 @@ +/** + * `toolResultTruncation` domain — model-context truncation contract for tool results. + * + * Defines the Agent-scoped service that runs after tool execution hooks and + * before a result is recorded into model-visible context. It preserves complete + * oversized text results through agent-scoped storage, replacing the inline + * payload with a recoverable preview and `output_path`. Pure contract; the + * implementation owns persistence through the storage backend. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ExecutableToolResult } from '#/tool/toolContract'; diff --git a/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncationService.ts b/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncationService.ts index d0631b533..54435cd27 100644 --- a/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncationService.ts +++ b/packages/agent-core-v2/src/agent/toolResultTruncation/toolResultTruncationService.ts @@ -1,3 +1,12 @@ +/** + * `toolResultTruncation` domain — `IAgentToolResultTruncationService` implementation. + * + * Persists complete oversized text tool results through `storage`, addressed + * under the current `scopeContext` agent root, and renders a model-visible + * preview with an absolute file path rooted at `bootstrap.homeDir`. Bound at + * Agent scope. + */ + import { randomUUID } from 'node:crypto'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/agent/toolSelect/dynamicTools.ts b/packages/agent-core-v2/src/agent/toolSelect/dynamicTools.ts index ab4871bd4..b3535f399 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/dynamicTools.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/dynamicTools.ts @@ -1,17 +1,45 @@ +/** + * `toolSelect` domain — predicates and shaping helpers for the + * select_tools progressive-disclosure protocol context. + * + * Exposes pure helpers for recognizing injected tool-schema messages, + * folding loadable-tool announcements, rendering announcement text, and + * stripping dynamic-tool protocol context from an outgoing history view. + * + * Two kinds of messages carry the protocol state in the history: + * - dynamic tool schema messages: `role: 'system'` messages whose `tools` + * field holds full tool definitions (origin + * `{kind: 'injection', variant: 'dynamic_tool_schema'}`) — tool loading is + * protocol context, not conversation. v2's undo cuts histories at the + * first real user prompt it finds regardless of origin: schema messages + * survive only when the cut lands before them. + * - loadable-tools announcements: `<tools_added>/<tools_removed>` system + * reminders (origin `{kind: 'system_trigger', name: 'loadable-tools'}`) — + * undo removes them (they are not `injection`-origin), and the next + * turn-boundary diff self-heals by re-announcing the folded delta. + * + * The loaded-tool ledger is the history itself: there is deliberately no + * separate persisted ledger, so undo/compaction/resume all self-heal by + * re-folding. Everything here anchors on `origin` or the `tools` field, so + * callers that need to filter MUST run before `project()` — projection + * strips `origin`. + */ + import type { ContextMessage } from '#/agent/contextMemory/types'; export const DYNAMIC_TOOL_SCHEMA_VARIANT = 'dynamic_tool_schema'; -export const LOADABLE_TOOLS_VARIANT = 'loadable-tools'; +export const LOADABLE_TOOLS_TRIGGER = 'loadable-tools'; export function isDynamicToolSchemaMessage(message: ContextMessage): boolean { return message.tools !== undefined && message.tools.length > 0; } export function isLoadableToolsAnnouncement(message: ContextMessage): boolean { - const origin = message.origin; - if (origin?.kind === 'injection') return origin.variant === LOADABLE_TOOLS_VARIANT; - return origin?.kind === 'system_trigger' && origin.name === LOADABLE_TOOLS_VARIANT; + return ( + message.origin?.kind === 'system_trigger' && + message.origin.name === LOADABLE_TOOLS_TRIGGER + ); } export function stripDynamicToolContext( diff --git a/packages/agent-core-v2/src/agent/toolSelect/flag.ts b/packages/agent-core-v2/src/agent/toolSelect/flag.ts index 7178e3ec3..d8da33f80 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/flag.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/flag.ts @@ -1,3 +1,14 @@ +/** + * `toolSelect` domain — registers the `tool-select` experimental flag into + * `flag`. + * + * Gates progressive tool disclosure: MCP tool schemas stay out of the + * immutable top-level tools[] and are loaded on demand through the + * `select_tools` tool. Off by default; enable via + * `KIMI_CODE_EXPERIMENTAL_TOOL_SELECT`, the master + * `KIMI_CODE_EXPERIMENTAL_FLAG`, or the `[experimental]` config section. + */ + import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; export const TOOL_SELECT_FLAG_ID = 'tool-select'; diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelect.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelect.ts index 36d6458a7..e3ce761ab 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelect.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/toolSelect.ts @@ -1,6 +1,13 @@ +/** + * `toolSelect` domain — progressive tool disclosure contract. + * + * Defines the Agent-scope service that shapes provider-visible tool/history + * views, loads selected dynamic schemas, and reports loadable-tool + * announcements. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import type { Tool } from '#/kosong/contract/tool'; import type { ToolInfo } from '#/tool/toolContract'; export const SELECT_TOOLS_TOOL_NAME = 'select_tools'; @@ -26,8 +33,6 @@ export interface IAgentToolSelectService { load(names: readonly string[]): LoadToolsResult; - drainPendingToolSchemas(): readonly Tool[] | undefined; - loadableToolsAnnouncement(): string | undefined; } diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncements.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncements.ts index fffa24b16..6be3c1f1a 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncements.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncements.ts @@ -1,3 +1,10 @@ +/** + * `toolSelect` domain — `IAgentToolSelectAnnouncementsService` contract. + * + * Defines the Agent-scope marker service that appends v1-compatible + * loadable-tools announcements through `systemReminder` at loop boundaries. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IAgentToolSelectAnnouncementsService { diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncementsService.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncementsService.ts index 390ad68ef..3338fbdc2 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncementsService.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/toolSelectAnnouncementsService.ts @@ -1,30 +1,76 @@ +/** + * `toolSelect` domain — `IAgentToolSelectAnnouncementsService` + * implementation. + * + * Appends v1-compatible loadable-tools diff announcements at turn boundaries + * through `systemReminder`, hooks into `loop` before each step, reads + * announcement text from `IAgentToolSelectService`, and observes compaction + * boundaries from `event`. Turn boundaries need no state: every turn starts + * at loop step 1, which always evaluates injection. The compaction-boundary + * flag (`needsBoundaryInjection`) is registered into `agentState` + * (`IAgentStateService`) and read/written through it. Bound at Agent scope. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { defineState } from '#/_base/state/stateRegistry'; +import { IAgentLoopService } from '#/agent/loop/loop'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { IEventBus } from '#/app/event/eventBus'; -import { LOADABLE_TOOLS_VARIANT } from './dynamicTools'; +import { LOADABLE_TOOLS_TRIGGER } from './dynamicTools'; import { IAgentToolSelectService } from './toolSelect'; import { IAgentToolSelectAnnouncementsService } from './toolSelectAnnouncements'; +export const toolSelectNeedsBoundaryInjectionKey = defineState<boolean>( + 'toolSelect.needsBoundaryInjection', + () => false, +); + export class AgentToolSelectAnnouncementsService extends Service implements IAgentToolSelectAnnouncementsService { declare readonly _serviceBrand: undefined; constructor( @IAgentToolSelectService toolSelect: IAgentToolSelectService, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - @IAgentScopeContext scopeContext: IAgentScopeContext, + @IAgentSystemReminderService private readonly reminders: IAgentSystemReminderService, + @IEventBus eventBus: IEventBus, + @IAgentLoopService loopService: IAgentLoopService, + @IAgentStateService private readonly states: IAgentStateService, ) { super(); + this.states.register(toolSelectNeedsBoundaryInjectionKey); this._register( - activateReminderWhenReady(agentLifecycle, scopeContext, (reminder) => - reminder.register(LOADABLE_TOOLS_VARIANT, ({ isNewTurn }) => - isNewTurn ? toolSelect.loadableToolsAnnouncement() : undefined, - ), - ), + eventBus.subscribe('compaction.completed', () => { + this.needsBoundaryInjection = true; + }), ); + this._register( + loopService.hooks.onWillBeginStep.register('toolSelectAnnouncements', async (ctx, next) => { + await next(); + if (ctx.step !== 1 && !this.needsBoundaryInjection) return; + this.needsBoundaryInjection = false; + this.inject(toolSelect); + }), + ); + } + + private get needsBoundaryInjection(): boolean { + return this.states.get(toolSelectNeedsBoundaryInjectionKey); + } + + private set needsBoundaryInjection(value: boolean) { + this.states.set(toolSelectNeedsBoundaryInjectionKey, value); + } + + private inject(toolSelect: IAgentToolSelectService): void { + const announcement = toolSelect.loadableToolsAnnouncement(); + if (announcement === undefined) return; + this.reminders.appendSystemReminder(announcement, { + kind: 'system_trigger', + name: LOADABLE_TOOLS_TRIGGER, + }); } } diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemas.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemas.ts deleted file mode 100644 index c673e67c5..000000000 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemas.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface IAgentToolSelectSchemasService { - readonly _serviceBrand: undefined; -} - -export const IAgentToolSelectSchemasService: ServiceIdentifier<IAgentToolSelectSchemasService> = - createDecorator<IAgentToolSelectSchemasService>('agentToolSelectSchemasService'); diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemasService.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemasService.ts deleted file mode 100644 index bf9cdf85b..000000000 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelectSchemasService.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { Service } from '#/_base/di/service'; -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; - -import { DYNAMIC_TOOL_SCHEMA_VARIANT } from './dynamicTools'; -import { IAgentToolSelectService } from './toolSelect'; -import { IAgentToolSelectSchemasService } from './toolSelectSchemas'; - -export class AgentToolSelectSchemasService extends Service implements IAgentToolSelectSchemasService { - declare readonly _serviceBrand: undefined; - - constructor( - @IAgentToolSelectService toolSelect: IAgentToolSelectService, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - @IAgentScopeContext scopeContext: IAgentScopeContext, - ) { - super(); - this._register( - activateReminderWhenReady(agentLifecycle, scopeContext, (reminder) => - reminder.register(DYNAMIC_TOOL_SCHEMA_VARIANT, () => { - const tools = toolSelect.drainPendingToolSchemas(); - if (tools === undefined) return undefined; - return { message: { role: 'system', content: [], tools } }; - }), - ), - ); - } -} - -registerScopedService( - LifecycleScope.Agent, - IAgentToolSelectSchemasService, - AgentToolSelectSchemasService, - ScopeActivation.OnScopeCreated, - 'toolSelect', -); diff --git a/packages/agent-core-v2/src/agent/toolSelect/toolSelectService.ts b/packages/agent-core-v2/src/agent/toolSelect/toolSelectService.ts index 208e3cefd..fa4c3489e 100644 --- a/packages/agent-core-v2/src/agent/toolSelect/toolSelectService.ts +++ b/packages/agent-core-v2/src/agent/toolSelect/toolSelectService.ts @@ -1,14 +1,25 @@ +/** + * `toolSelect` domain — `IAgentToolSelectService` implementation. + * + * Shapes the provider-visible tool and history views for progressive tool + * disclosure, loads dynamic schemas into `contextMemory`, and exposes + * loadable-tools announcement text. Reads live tools from `toolRegistry`, + * active-tool and capability state from `profile`, gates through `flag`, + * hooks into `toolExecutor`, and listens to context lifecycle events through + * `event`. The mutable load-tracking state (`pendingLoaded`) is registered + * into `agentState` (`IAgentStateService`) and read/written through it. Bound + * at Agent scope. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IEventBus } from '#/app/event/eventBus'; import { IFlagService } from '#/app/flag/flag'; import type { Tool } from '#/kosong/contract/tool'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { ContextSpliced } from '#/agent/contextMemory/contextEvents'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { CompactionCompleted } from '#/agent/fullCompaction/compactionOps'; import { IAgentProfileService } from '#/agent/profile/profile'; import { IAgentStateService } from '#/agent/state/agentState'; import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; @@ -18,6 +29,7 @@ import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; import { collectLoadedDynamicToolNames, + DYNAMIC_TOOL_SCHEMA_VARIANT, foldAnnouncedToolNames, renderLoadableToolsAnnouncement, stripDynamicToolContext, @@ -49,7 +61,7 @@ export class AgentToolSelectService extends Service implements IAgentToolSelectS @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(toolSelectPendingLoadedKey); + this.states.register(toolSelectPendingLoadedKey); this._register( toolExecutor.registerUnavailableToolDescriber((name) => this.describeUnavailableTool(name)), ); @@ -57,13 +69,13 @@ export class AgentToolSelectService extends Service implements IAgentToolSelectS toolExecutor.registerMissingToolDescriber((name) => this.describeMissingTool(name)), ); this._register( - eventBus.subscribe(CompactionCompleted, () => { + eventBus.subscribe('compaction.completed', () => { this.pendingLoaded.clear(); }), ); this._register( - eventBus.subscribe(ContextSpliced, (splice) => { - if (splice.deleteCount === 0 || splice.messages.length > 0) return; + eventBus.subscribe('context.spliced', (splice) => { + if (splice.deleteCount === 0 || this.pendingLoaded.size === 0) return; this.dropPendingLoadedNotLanded(); }), ); @@ -132,24 +144,22 @@ export class AgentToolSelectService extends Service implements IAgentToolSelectS } } if (toLoad.length > 0) { + toLoad.sort((a, b) => a.localeCompare(b)); + const tools = toLoad + .map((name) => this.schemaOf(name)) + .filter((tool): tool is Tool => tool !== undefined); + this.context.append({ + role: 'system', + content: [], + toolCalls: [], + tools, + origin: { kind: 'injection', variant: DYNAMIC_TOOL_SCHEMA_VARIANT }, + }); for (const name of toLoad) this.pendingLoaded.add(name); } return { toLoad, alreadyAvailable, unknown }; } - drainPendingToolSchemas(): readonly Tool[] | undefined { - if (!this.enabled() || this.pendingLoaded.size === 0) return undefined; - const names = [...this.pendingLoaded].toSorted((a, b) => a.localeCompare(b)); - const tools: Tool[] = []; - for (const name of names) { - const tool = this.schemaOf(name); - if (tool === undefined) continue; - this.pendingLoaded.delete(name); - tools.push(tool); - } - return tools.length === 0 ? undefined : tools; - } - loadableToolsAnnouncement(): string | undefined { if (!this.enabled()) return undefined; const loadable = this.loadableToolNames(); diff --git a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm.md b/packages/agent-core-v2/src/agent/tools/agent-swarm/agent-swarm.md similarity index 100% rename from packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm.md rename to packages/agent-core-v2/src/agent/tools/agent-swarm/agent-swarm.md diff --git a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm.ts b/packages/agent-core-v2/src/agent/tools/agent-swarm/agent-swarm.ts similarity index 66% rename from packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm.ts rename to packages/agent-core-v2/src/agent/tools/agent-swarm/agent-swarm.ts index 0cc0aca8e..f1a7349ab 100644 --- a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm.ts +++ b/packages/agent-core-v2/src/agent/tools/agent-swarm/agent-swarm.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `IAgentSwarmTool` contract (the `AgentSwarm` tool). + * + * Public contract of the `AgentSwarm` collaboration tool: the input zod + * schema the model-facing parameters are derived from, the tool-owned + * constants the schema is built around (prompt template placeholder, maximum + * subagent count), and the `IAgentSwarmTool` DI decorator that the + * implementation registers against via `registerAgentToolService`. Bound at + * Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -36,12 +47,6 @@ export const AgentSwarmToolInputSchema = z .describe( `Values used to fill ${PROMPT_TEMPLATE_PLACEHOLDER}. Each item launches one new subagent.`, ), - fork: z - .boolean() - .optional() - .describe( - 'Fork the current context for every item-spawned subagent: each starts with a snapshot of this agent\'s completed conversation history instead of zero context, inheriting this agent\'s agent type, tool set, and model. A non-empty resume_agent_ids map is rejected. If subagent_type is provided, it must match this agent\'s type; if model is provided, it must be this agent\'s model or "primary". Different types and model overrides are rejected. Use it only when every item builds on this conversation; keep independent tasks zero-context.', - ), resume_agent_ids: z .record(z.string().trim().min(1), z.string().trim().min(1)) .optional() @@ -49,15 +54,16 @@ export const AgentSwarmToolInputSchema = z 'Map of existing subagent agent_id to the prompt used to resume that subagent. These resumed subagents are launched before new item-based subagents.', ), model: z - .string() + .enum(['secondary', 'primary']) .optional() .describe( - 'Which model to run the item-spawned subagents on: one of the aliases listed under "Available models" in this tool description, or "primary" for the main model you are running on (for hard, quality-sensitive tasks). When omitted, the configured default model is used. Resumed subagents always keep their own model.', + 'Which model to run the item-spawned subagents on: "secondary" = the configured secondary model; "primary" = the main model you are running on (for hard, quality-sensitive tasks). This explicit choice overrides the selected agent type\'s model_preference; without either, secondary is the default when configured. Only effective when a secondary model is configured; otherwise subagents inherit your model. Resumed subagents always keep their own model.', ), }) .strict(); export type AgentSwarmToolInput = z.infer<typeof AgentSwarmToolInputSchema>; + export interface IAgentSwarmTool extends AgentTool<AgentSwarmToolInput> { readonly _serviceBrand: undefined } export const IAgentSwarmTool = createDecorator<IAgentSwarmTool>('agentSwarmTool'); diff --git a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agentSwarmTool.ts b/packages/agent-core-v2/src/agent/tools/agent-swarm/agentSwarmTool.ts similarity index 72% rename from packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agentSwarmTool.ts rename to packages/agent-core-v2/src/agent/tools/agent-swarm/agentSwarmTool.ts index 997fd2754..b7d1a0b58 100644 --- a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agentSwarmTool.ts +++ b/packages/agent-core-v2/src/agent/tools/agent-swarm/agentSwarmTool.ts @@ -1,3 +1,28 @@ +/** + * `tools` domain — `AgentSwarmTool` implementation (the `AgentSwarm` + * tool). + * + * Launches a batch of child agents (an ordinary Agent scope each) through the + * session swarm coordinator (`ISessionSwarmService`) and renders the + * per-subagent XML result. Reads persisted swarm item labels through the + * Session-scoped coordinator so later `resume_agent_ids` calls relabel + * resumed subagents like v1. When the caller has a model bound, the tool + * resolves the explicit or target-profile model preference up front via + * `resolveSubagentBinding` (against `IConfigService`, `IFlagService`, + * `ISessionAgentProfileCatalog`, and the caller's `IAgentProfileService`) and + * threads it through the swarm tasks; otherwise binding is left to the + * service, which keeps its own "no model bound" check and inherit-caller + * fallback. The advertised `model` parameter lists the secondary/primary + * pair via `buildSubagentModelDescriptions`, suffixing each line with the + * entry's capability flags resolved through `IModelCatalog`. Swarm mode is + * entered through `IAgentSwarmService`; the caller's agent id comes from + * `IAgentScopeContext`. Pure tool — owns no scoped state. + * + * Registered via the module-level `registerAgentToolService(IAgentSwarmTool, + * AgentSwarmTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { ToolAccesses, type ExecutableToolContext, @@ -5,28 +30,27 @@ import { type ToolExecution, } from '#/tool/toolContract'; import { Error2, ErrorCodes } from '#/errors'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; import { toInputJsonSchema } from '#/tool/input-schema'; import { IConfigService } from '#/app/config/config'; import { IFlagService } from '#/app/flag/flag'; -import { ISessionSwarmService, type SessionSwarmTask } from '#/features/swarm/session/sessionSwarm'; +import { IModelCatalog } from '#/kosong/model/catalog'; +import { ISessionSwarmService, type SessionSwarmTask } from '#/session/swarm/sessionSwarm'; +import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; import { IAgentProfileService } from '#/agent/profile/profile'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentSwarmService } from '#/features/swarm/agent/swarm'; -import { resolveSwarmTimeoutMs } from '#/features/swarm/configSection'; -import { ISessionSubagentService } from '#/session/subagent/subagent'; import { - FORK_EXPERIMENTAL_UNAVAILABLE, - FORK_WITH_RESUME_UNAVAILABLE, - forkIncompatibility, - type SubagentSpawnPlan, -} from '#/session/subagent/spawn'; -import { SUBAGENT_FORK_FLAG_ID } from '#/session/subagent/flag'; + subagentAllowlistFor, + subagentTypeNotAllowedMessage, +} from '#/app/agentProfileCatalog/profile-shared'; +import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; +import { IAgentSwarmService } from '#/agent/swarm/swarm'; import { buildSubagentModelDescriptions, - exposesSubagentModelChoice, - stripSubagentForkParameter, + resolveSubagentBinding, + resolveSubagentTimeoutMs, stripSubagentModelParameter, } from '#/session/subagent/configSection'; +import { SECONDARY_MODEL_FLAG_ID } from '#/session/subagent/flag'; import { AgentSwarmToolInputSchema, IAgentSwarmTool, @@ -35,7 +59,6 @@ import { type AgentSwarmToolInput, } from './agent-swarm'; import AGENT_SWARM_DESCRIPTION from './agent-swarm.md?raw'; -import AGENT_SWARM_FORK_DESCRIPTION from './agent-swarm-fork.md?raw'; const DEFAULT_SUBAGENT_TYPE = 'coder'; @@ -73,12 +96,9 @@ export class AgentSwarmTool implements IAgentSwarmTool { readonly name = 'AgentSwarm' as const; get parameters(): Record<string, unknown> { - const parameters = exposesSubagentModelChoice(this.config, this.flags) + return this.flags.enabled(SECONDARY_MODEL_FLAG_ID) ? AGENT_SWARM_PARAMETERS : AGENT_SWARM_PARAMETERS_NO_MODEL; - return this.flags.enabled(SUBAGENT_FORK_FLAG_ID) - ? parameters - : stripSubagentForkParameter(parameters); } private readonly callerAgentId: string; @@ -89,23 +109,23 @@ export class AgentSwarmTool implements IAgentSwarmTool { @IAgentSwarmService private readonly swarmMode: IAgentSwarmService, @IConfigService private readonly config: IConfigService, @IFlagService private readonly flags: IFlagService, - @ISessionSubagentService private readonly subagents: ISessionSubagentService, + @ISessionAgentProfileCatalog private readonly catalog: ISessionAgentProfileCatalog, @IAgentProfileService private readonly profile: IAgentProfileService, + @IModelCatalog private readonly modelCatalog: IModelCatalog, ) { this.callerAgentId = scopeContext.agentId; } get description(): string { - let description = AGENT_SWARM_DESCRIPTION; - if (this.flags.enabled(SUBAGENT_FORK_FLAG_ID)) { - description += `\n\n${AGENT_SWARM_FORK_DESCRIPTION}`; - } const modelLines = buildSubagentModelDescriptions( this.config, this.flags, this.profile.data().modelAlias, + this.modelCatalog, ); - return modelLines === undefined ? description : `${description}\n\n${modelLines}`; + return modelLines === undefined + ? AGENT_SWARM_DESCRIPTION + : `${AGENT_SWARM_DESCRIPTION}\n\n${modelLines}`; } resolveExecution(args: AgentSwarmToolInput): ToolExecution { @@ -146,33 +166,36 @@ export class AgentSwarmTool implements IAgentSwarmTool { signal: AbortSignal, toolCallId: string, ): Promise<string> { - const fork = args.fork === true; - if (fork && !this.flags.enabled(SUBAGENT_FORK_FLAG_ID)) { - throw new Error2(ErrorCodes.VALIDATION_FAILED, FORK_EXPERIMENTAL_UNAVAILABLE); - } - if (fork && Object.keys(args.resume_agent_ids ?? {}).length > 0) { - throw new Error2(ErrorCodes.VALIDATION_FAILED, FORK_WITH_RESUME_UNAVAILABLE); - } - let plan: SubagentSpawnPlan | undefined; + const profileName = normalizeOptionalString(args.subagent_type) ?? DEFAULT_SUBAGENT_TYPE; + let binding: { model: string; thinking?: string } | undefined; if ((args.items?.length ?? 0) > 0) { - if (fork) { - const incompatible = forkIncompatibility( - { subagent_type: args.subagent_type, model: args.model }, - this.profile.data(), + await this.catalog.ready; + const own = this.profile.data(); + const allowlist = subagentAllowlistFor(this.catalog, own); + if (allowlist !== undefined && !allowlist.includes(profileName)) { + throw new Error2( + ErrorCodes.AGENT_TYPE_NOT_ALLOWED, + subagentTypeNotAllowedMessage(profileName, allowlist), + { details: { profileName, allowlist } }, ); - if (incompatible !== undefined) { - throw new Error2(ErrorCodes.VALIDATION_FAILED, incompatible); - } } - plan = await this.subagents.planSpawn({ - callerAgentId: this.callerAgentId, - profileName: args.subagent_type, - model: args.model, - fork, - }); + const targetProfile = this.catalog.get(profileName); + if (targetProfile === undefined) { + throw new Error2(ErrorCodes.PROFILE_UNKNOWN, `Unknown agent type: "${profileName}"`, { + details: { profileName }, + }); + } + if (own.modelAlias !== undefined) { + const resolved = resolveSubagentBinding( + this.config, + this.flags, + { modelAlias: own.modelAlias, thinkingLevel: own.thinkingLevel }, + args.model ?? targetProfile.modelPreference, + ); + binding = { model: resolved.model, thinking: resolved.thinking }; + } } - const profileName = plan?.profileName ?? DEFAULT_SUBAGENT_TYPE; - const timeoutMs = resolveSwarmTimeoutMs(this.config); + const timeoutMs = resolveSubagentTimeoutMs(this.config); const specs = await createAgentSwarmSpecs(args, (agentId) => this.swarmService.getSwarmItem({ callerAgentId: this.callerAgentId, agentId }), ); @@ -200,7 +223,7 @@ export class AgentSwarmTool implements IAgentSwarmTool { return { ...common, kind: 'spawn' as const, - plan: plan!, + binding, }; }); const results = await this.swarmService.run({ @@ -208,11 +231,13 @@ export class AgentSwarmTool implements IAgentSwarmTool { tasks, }); return renderSwarmResults( - results.map(({ task, ...result }) => ({ spec: task.data, ...result })), + results.map(({ task, ...result }) => ({ spec: task.data as AgentSwarmSpec, ...result })), ); } } +registerAgentToolService(IAgentSwarmTool, AgentSwarmTool, { name: 'AgentSwarm', domain: 'swarm' }); + async function createAgentSwarmSpecs( args: AgentSwarmToolInput, getResumeItem: (agentId: string) => Promise<string | undefined>, diff --git a/packages/agent-core-v2/src/agent/tools/agent/agent-fork.md b/packages/agent-core-v2/src/agent/tools/agent/agent-fork.md deleted file mode 100644 index e2aa82ee1..000000000 --- a/packages/agent-core-v2/src/agent/tools/agent/agent-fork.md +++ /dev/null @@ -1 +0,0 @@ -Context forking: when the task builds on this conversation, pass `fork: true` instead of briefing from scratch — the subagent then starts with a snapshot of your completed history (inheriting your own agent type, tool set, and model), so the prompt only needs the task itself. A non-empty `resume` is rejected with `fork`; `subagent_type` must match your own agent type; `model` must be your own model or `primary`. \ No newline at end of file diff --git a/packages/agent-core-v2/src/agent/tools/agent/agent.ts b/packages/agent-core-v2/src/agent/tools/agent/agent.ts index 76fc5d132..7bc0bda0f 100644 --- a/packages/agent-core-v2/src/agent/tools/agent/agent.ts +++ b/packages/agent-core-v2/src/agent/tools/agent/agent.ts @@ -1,10 +1,19 @@ +/** + * `tools` domain — `ISubagentTool` contract (the `Agent` tool). + * + * Public contract of the `Agent` collaboration tool: the input/output zod + * schemas the model-facing parameters are derived from, the tool-owned + * constants (default profile name, resumed-agent label, fixed output + * messages), and the `ISubagentTool` DI decorator that the implementation + * registers against via `registerAgentToolService`. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; import { type AgentTool } from '#/tool/toolContract'; -import { DEFAULT_PROFILE_NAME } from '#/session/subagent/spawn'; -export { DEFAULT_PROFILE_NAME }; +export const DEFAULT_PROFILE_NAME = 'coder'; export const RESUMED_LABEL = 'subagent'; export const SubagentToolInputSchema = z.preprocess( @@ -18,8 +27,7 @@ export const SubagentToolInputSchema = z.preprocess( typeof normalized['resume'] === 'string' && normalized['resume'].trim().length > 0; const hasSubagentType = typeof normalized['subagent_type'] === 'string' && normalized['subagent_type'].length > 0; - const hasFork = normalized['fork'] === true; - if (!hasSubagentType && !hasResumeId && !hasFork) { + if (!hasSubagentType && !hasResumeId) { normalized['subagent_type'] = DEFAULT_PROFILE_NAME; } else if (!hasSubagentType) { delete normalized['subagent_type']; @@ -47,23 +55,18 @@ export const SubagentToolInputSchema = z.preprocess( .describe( 'If true, return immediately without waiting for completion. Prefer false unless the task can run independently and there is a clear benefit to not waiting.', ), - fork: z - .boolean() - .optional() - .describe( - 'Fork the current context: the subagent starts with a snapshot of this agent\'s completed conversation history instead of zero context, inheriting this agent\'s agent type, tool set, and model. A non-empty resume is rejected. If subagent_type is provided, it must match this agent\'s type; if model is provided, it must be this agent\'s model or "primary". Different types and model overrides are rejected.', - ), model: z - .string() + .enum(['secondary', 'primary']) .optional() .describe( - 'Which model to run the subagent on: one of the aliases listed under "Available models" in this tool description, or "primary" for the main model you are running on (for hard, quality-sensitive tasks). When omitted, the configured default model is used. Ignored when resuming — resumed subagents keep their own model.', + 'Which model to run the subagent on: "secondary" = the configured secondary model; "primary" = the main model you are running on (for hard, quality-sensitive tasks). This explicit choice overrides the selected agent type\'s model_preference; without either, secondary is the default when configured. Only effective when a secondary model is configured; otherwise the subagent inherits your model. Ignored when resuming — resumed subagents keep their own model.', ), }), ); export type SubagentToolInput = z.infer<typeof SubagentToolInputSchema>; + export const SubagentToolOutputSchema = z.object({ result: z.string().describe('Aggregated text output from the subagent'), usage: z @@ -86,6 +89,7 @@ export const USER_INTERRUPTED_SUBAGENT_MESSAGE = 'The subagent was stopped before it finished by user.'; export const SUBAGENT_STOPPED_MESSAGE = 'The subagent was stopped before it finished.'; + export interface ISubagentTool extends AgentTool<SubagentToolInput> { readonly _serviceBrand: undefined; } diff --git a/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts b/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts index 714400af0..330549a1f 100644 --- a/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts +++ b/packages/agent-core-v2/src/agent/tools/agent/agentTool.ts @@ -1,4 +1,37 @@ -import { type CollectionView } from '#/_base/di/collection'; +/** + * `tools` domain — `SubagentTool` implementation (the `Agent` tool). + * + * The LLM-facing wrapper over the `subagent` domain: translates the tool args + * into a Profile + Model binding, creates (or resumes) an agent through + * `IAgentLifecycleService`, drives one turn via `ISessionSubagentService.run`, + * and mirrors the run onto the calling agent's record stream + * (`mirrorAgentRun`). The tool also owns the JSON schema + description, + * approval rule, background-task registration (so the LLM can see the run + * under TaskList/TaskOutput/TaskStop when `run_in_background=true` or after + * detach), and terminal text formatting. + * + * Spawn bindings use an explicit tool choice first, then the target profile's + * symbolic model preference, before `resolveSubagentBinding` falls back to the + * configured secondary model or the caller's model. The selected alias is + * resolved through the model catalog before lifecycle allocation. A resumed + * agent keeps the model recorded in its own wire journal — with per-subagent + * models there is no "child follows the parent's current model" invariant to + * enforce. + * + * Registered via the module-level `registerAgentToolService(ISubagentTool, + * SubagentTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. The per-profile tool listings in the + * description read the full contribution table (not the runtime registry, + * which only holds tools the caller's own Profile activated), plus any + * dynamically registered tools. The description's catalog profile list is + * snapshotted once the session catalog has loaded and frozen for the agent's + * lifetime: plugin install / enable / disable / remove re-contributes + * profiles mid-session, and a live read would rewrite the tools payload of + * every later request — breaking the provider's prompt cache for a change a + * live agent must not see (new profiles take effect on `/new` or `/reload`). + * Bound at Agent scope. + */ + import type { IAgentScopeHandle } from '#/_base/di/scope'; import { isAbortError, @@ -18,8 +51,10 @@ import { resolveActiveToolNames, } from '#/agent/toolPolicy/evaluate'; import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; +import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentLoopService } from '#/agent/loop/loop'; +import { IAgentUserToolService } from '#/agent/userTool/userTool'; import { ToolAccesses, type ExecutableToolContext, @@ -27,37 +62,39 @@ import { type ToolExecution, } from '#/tool/toolContract'; import { - AgentToolContribution, + getAgentToolContributions, registerAgentToolService, } from '#/agent/toolRegistry/toolContribution'; import { IAgentToolRegistryService, type ToolReference } from '#/agent/toolRegistry/toolRegistry'; import { type AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; +import { applyProfilePromptPrefix } from '#/app/agentProfileCatalog/promptPrefix'; import { - rootDelegationExtras, subagentAllowlistFor, - withoutDelegatingTargets, + subagentTypeNotAllowedMessage, } from '#/app/agentProfileCatalog/profile-shared'; import { ILogService } from '#/_base/log/log'; import { IConfigService } from '#/app/config/config'; import { IFlagService } from '#/app/flag/flag'; +import { IModelCatalog } from '#/kosong/model/catalog'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { isSubagentMeta, subagentLabels, subagentParentAgentId } from '#/session/agentLifecycle/subagentMetadata'; +import { ISessionProcessRunner } from '#/session/process/processRunner'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; +import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; -import { emitAgentRunSpawned, mirrorAgentRun, SubagentStarted } from '#/session/subagent/mirrorAgentRun'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { emitAgentRunSpawned, mirrorAgentRun } from '#/session/subagent/mirrorAgentRun'; import { ISessionSubagentService } from '#/session/subagent/subagent'; -import { FORK_EXPERIMENTAL_UNAVAILABLE, forkIncompatibility } from '#/session/subagent/spawn'; -import { SUBAGENT_FORK_FLAG_ID } from '#/session/subagent/flag'; import { buildSubagentModelDescriptions, - exposesSubagentModelChoice, formatSubagentTimeoutDescription, + resolveSubagentBinding, resolveSubagentTimeoutMs, - stripSubagentForkParameter, stripSubagentModelParameter, + subagentDisplayModel, + wrapSubagentModelError, } from '#/session/subagent/configSection'; +import { SECONDARY_MODEL_FLAG_ID } from '#/session/subagent/flag'; import { BACKGROUND_AGENT_UNAVAILABLE, DEFAULT_PROFILE_NAME, @@ -74,7 +111,6 @@ import { SubagentTask, type SubagentHandle } from './subagent-task'; import AGENT_BACKGROUND_DISABLED_DESCRIPTION from './agent-background-disabled.md?raw'; import AGENT_BACKGROUND_DESCRIPTION from './agent-background-enabled.md?raw'; import AGENT_DESCRIPTION_BASE from './agent.md?raw'; -import AGENT_FORK_DESCRIPTION from './agent-fork.md?raw'; const SUBAGENT_TOOL_PARAMETERS = toInputJsonSchema(SubagentToolInputSchema); const SUBAGENT_TOOL_PARAMETERS_NO_MODEL = stripSubagentModelParameter(SUBAGENT_TOOL_PARAMETERS); @@ -84,12 +120,9 @@ export class SubagentTool implements ISubagentTool { readonly name: string = 'Agent'; get parameters(): Record<string, unknown> { - const parameters = exposesSubagentModelChoice(this.config, this.flags) + return this.flags.enabled(SECONDARY_MODEL_FLAG_ID) ? SUBAGENT_TOOL_PARAMETERS : SUBAGENT_TOOL_PARAMETERS_NO_MODEL; - return this.flags.enabled(SUBAGENT_FORK_FLAG_ID) - ? parameters - : stripSubagentForkParameter(parameters); } private readonly callerAgentId: string; @@ -98,7 +131,7 @@ export class SubagentTool implements ISubagentTool { private frozenCatalogProfiles: readonly AgentProfile[] | undefined; constructor( - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentLifecycleService private readonly lifecycle: IAgentLifecycleService, @ISessionSubagentService private readonly subagents: ISessionSubagentService, @ISessionAgentProfileCatalog private readonly catalog: ISessionAgentProfileCatalog, @IAgentScopeContext scopeContext: IAgentScopeContext, @@ -106,11 +139,14 @@ export class SubagentTool implements ISubagentTool { @IAgentProfileService private readonly profile: IAgentProfileService, @IAgentToolPolicyService private readonly toolPolicy: IAgentToolPolicyService, @IAgentToolRegistryService private readonly toolRegistry: IAgentToolRegistryService, + @ISessionWorkspaceContext private readonly workspace: ISessionWorkspaceContext, + @ISessionProcessRunner private readonly processRunner: ISessionProcessRunner, @ISessionMetadata private readonly sessionMetadata: ISessionMetadata, @ILogService private readonly log: ILogService, + @IAgentPermissionModeService private readonly permissionMode: IAgentPermissionModeService, @IConfigService private readonly config: IConfigService, @IFlagService private readonly flags: IFlagService, - @AgentToolContribution private readonly contributions: CollectionView<AgentToolContribution>, + @IModelCatalog private readonly modelCatalog: IModelCatalog, ) { this.callerAgentId = scopeContext.agentId; this.canRunInBackground = () => @@ -127,12 +163,8 @@ export class SubagentTool implements ISubagentTool { ? AGENT_BACKGROUND_DESCRIPTION : AGENT_BACKGROUND_DISABLED_DESCRIPTION; let description = `${AGENT_DESCRIPTION_BASE}\n\n${backgroundDescription}`; - if (this.flags.enabled(SUBAGENT_FORK_FLAG_ID)) { - description += `\n\n${AGENT_FORK_DESCRIPTION}`; - } - const own = this.profile.data(); + const allowlist = subagentAllowlistFor(this.catalog, this.profile.data()); const catalogProfiles = this.catalogProfiles(); - const allowlist = this.effectiveAllowlist(own, catalogProfiles); const profiles = allowlist === undefined ? catalogProfiles @@ -142,6 +174,7 @@ export class SubagentTool implements ISubagentTool { this.knownToolReferences(), (profile, name, source) => this.toolPolicy.isToolActiveForProfile(profile, name, source), + this.flags.enabled(SECONDARY_MODEL_FLAG_ID), ); if (typeLines) { description += `\n\nAvailable agent types (pass via subagent_type):\n${typeLines}`; @@ -150,6 +183,7 @@ export class SubagentTool implements ISubagentTool { this.config, this.flags, this.profile.data().modelAlias, + this.modelCatalog, ); if (modelLines !== undefined) { description += `\n\n${modelLines}`; @@ -160,40 +194,15 @@ export class SubagentTool implements ISubagentTool { private catalogProfiles(): readonly AgentProfile[] { if (this.frozenCatalogProfiles !== undefined) return this.frozenCatalogProfiles; const profiles = this.catalog.list(); + // Freeze only on a loaded catalog — a pre-ready read could pin a partial + // listing for the agent's lifetime. if (this.catalogReady) this.frozenCatalogProfiles = profiles; return profiles; } - private delegationExtras( - own: { - readonly profileName?: string; - readonly subagents?: readonly string[]; - }, - profiles: readonly AgentProfile[], - ): readonly string[] | undefined { - if (this.callerAgentId !== 'main') return undefined; - return rootDelegationExtras(this.catalog, own, profiles); - } - - private effectiveAllowlist( - own: { - readonly profileName?: string; - readonly subagents?: readonly string[]; - }, - profiles: readonly AgentProfile[], - ): readonly string[] | undefined { - const allowlist = subagentAllowlistFor( - this.catalog, - own, - this.delegationExtras(own, profiles), - ); - if (allowlist === undefined || own.subagents !== undefined) return allowlist; - return withoutDelegatingTargets(this.catalog, allowlist); - } - private knownToolReferences(): ToolReference[] { const refs = new Map<string, ToolReference>(); - for (const contribution of this.contributions.items) { + for (const contribution of getAgentToolContributions()) { refs.set(contribution.options.name, { name: contribution.options.name, source: contribution.options.source ?? 'builtin', @@ -217,23 +226,10 @@ export class SubagentTool implements ISubagentTool { return { output: RESUME_WITH_TYPE_UNAVAILABLE, isError: true }; } - if (args.fork === true) { - if (!this.flags.enabled(SUBAGENT_FORK_FLAG_ID)) { - return { output: FORK_EXPERIMENTAL_UNAVAILABLE, isError: true }; - } - const forkError = forkIncompatibility(args, this.profile.data()); - if (forkError !== undefined) { - return { output: forkError, isError: true }; - } - } - const profileNameForDisplay = resumeAgentId !== undefined && resumeAgentId.length > 0 ? this.resumeProfileName(resumeAgentId) ?? RESUMED_LABEL - : (requestedProfileName ?? - (args.fork === true - ? (this.profile.data().profileName ?? DEFAULT_PROFILE_NAME) - : DEFAULT_PROFILE_NAME)); + : requestedProfileName ?? DEFAULT_PROFILE_NAME; const prefix = args.run_in_background === true ? 'Launching background' : 'Launching'; return { description: `${prefix} ${profileNameForDisplay} agent: ${args.description}`, @@ -251,7 +247,7 @@ export class SubagentTool implements ISubagentTool { } private resumeProfileName(agentId: string): string | undefined { - const target = this.agentLifecycle.handleOf(agentId); + const target = this.lifecycle.get(agentId); if (target === undefined) return undefined; return target.accessor.get(IAgentProfileService).data().profileName; } @@ -261,7 +257,7 @@ export class SubagentTool implements ISubagentTool { toolCallId: string, controller: AbortController, ): Promise<SubagentHandle> { - const requester = this.agentLifecycle.handleOf(this.callerAgentId); + const requester = this.lifecycle.get(this.callerAgentId); if (requester === undefined) { throw new Error2( ErrorCodes.AGENT_NOT_FOUND, @@ -278,7 +274,7 @@ export class SubagentTool implements ISubagentTool { let displayModel: string | undefined; let promptText = args.prompt; if (isResume) { - const target = this.agentLifecycle.handleOf(resumeAgentId); + const target = this.lifecycle.get(resumeAgentId); if (target === undefined) { throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Agent instance "${resumeAgentId}" does not exist`, { details: { agentId: resumeAgentId }, @@ -288,30 +284,80 @@ export class SubagentTool implements ISubagentTool { agentId = target.id; const resumed = target.accessor.get(IAgentProfileService).data(); profileName = resumed.profileName ?? RESUMED_LABEL; - displayModel = resumed.modelAlias; + displayModel = + resumed.modelAlias === undefined + ? undefined + : subagentDisplayModel(this.config, resumed.modelAlias); } else { - const plan = await this.subagents.planSpawn({ - callerAgentId: this.callerAgentId, - profileName: args.subagent_type, - model: args.model, - fork: args.fork === true, + const requestedProfileName = args.subagent_type?.length + ? args.subagent_type + : DEFAULT_PROFILE_NAME; + await this.catalog.ready; + const own = this.profile.data(); + const allowlist = subagentAllowlistFor(this.catalog, own); + if (allowlist !== undefined && !allowlist.includes(requestedProfileName)) { + throw new Error2( + ErrorCodes.AGENT_TYPE_NOT_ALLOWED, + subagentTypeNotAllowedMessage(requestedProfileName, allowlist), + { details: { profileName: requestedProfileName, allowlist } }, + ); + } + const profile = this.catalog.get(requestedProfileName); + if (profile === undefined) { + throw new Error2(ErrorCodes.PROFILE_UNKNOWN, `Unknown agent type: "${requestedProfileName}"`, { + details: { profileName: requestedProfileName }, + }); + } + if (own.modelAlias === undefined) { + throw new Error2(ErrorCodes.MODEL_NOT_CONFIGURED, 'Caller agent has no model bound', { + details: { agentId: this.callerAgentId }, + }); + } + const binding = resolveSubagentBinding( + this.config, + this.flags, + { modelAlias: own.modelAlias, thinkingLevel: own.thinkingLevel }, + args.model ?? profile.modelPreference, + ); + let created: IAgentScopeHandle; + try { + this.modelCatalog.get(binding.model); + created = await this.lifecycle.create({ + binding: { + profile: profile.name, + model: binding.model, + thinking: binding.thinking, + }, + labels: subagentLabels(this.callerAgentId), + }); + } catch (error) { + throw wrapSubagentModelError(error, binding.model, own.modelAlias); + } + created.accessor.get(IAgentPermissionModeService).setMode(this.permissionMode.mode); + created.accessor + .get(IAgentUserToolService) + .inheritUserTools(requester.accessor.get(IAgentUserToolService)); + agentId = created.id; + profileName = profile.name; + displayModel = binding.displayModel; + promptText = await applyProfilePromptPrefix(profile, args.prompt, { + cwd: this.workspace.workDir, + runner: this.processRunner, + log: this.log, }); - const spawned = await this.subagents.spawn({ - callerAgentId: this.callerAgentId, - plan, - labels: subagentLabels(this.callerAgentId), - prompt: args.prompt, - }); - agentId = spawned.agentId; - profileName = spawned.profileName; - displayModel = spawned.model; - promptText = spawned.promptText; } - const target = this.agentLifecycle.handleOf(agentId); - if (target === undefined) throw new Error(`Agent "${agentId}" does not exist`); + const runInBackground = args.run_in_background === true; + emitAgentRunSpawned(requester, agentId, { + profileName, + parentToolCallId: toolCallId, + description: args.description, + runInBackground, + model: displayModel, + }); + const run = await this.subagents.run( - target.accessor.get(IAgentScopeContext).agentContext, + agentId, { kind: 'prompt', prompt: promptText }, { signal: controller.signal }, ); @@ -319,7 +365,6 @@ export class SubagentTool implements ISubagentTool { profileName, prompt: promptText, signal: controller.signal, - deferStarted: true, cancel: (reason) => { controller.abort(reason); }, @@ -327,9 +372,9 @@ export class SubagentTool implements ISubagentTool { return { agentId, profileName, - parentToolCallId: toolCallId, model: displayModel, - thinkingEffort: this.agentLifecycle.handleOf(agentId) + thinkingEffort: this.lifecycle + .get(agentId) ?.accessor.get(IAgentProfileService) .getEffectiveThinkingLevel(), completion: mirrored.then((r) => ({ result: r.summary, usage: r.usage })), @@ -377,16 +422,6 @@ export class SubagentTool implements ISubagentTool { return { output: RESUME_WITH_TYPE_UNAVAILABLE, isError: true }; } - if (args.fork === true) { - if (!this.flags.enabled(SUBAGENT_FORK_FLAG_ID)) { - return { output: FORK_EXPERIMENTAL_UNAVAILABLE, isError: true }; - } - const forkError = forkIncompatibility(args, this.profile.data()); - if (forkError !== undefined) { - return { output: forkError, isError: true }; - } - } - const allowBackground = this.canRunInBackground(); if (runInBackground && !allowBackground) { return { output: BACKGROUND_AGENT_UNAVAILABLE, isError: true }; @@ -449,22 +484,6 @@ export class SubagentTool implements ISubagentTool { }; } - const requester = this.agentLifecycle.handleOf(this.callerAgentId); - if (requester !== undefined) { - emitAgentRunSpawned(requester, handle.agentId, { - profileName: handle.profileName, - parentToolCallId: toolCallId, - description: args.description, - runInBackground, - fork: args.fork === true, - model: handle.model, - taskId, - }); - void requester.accessor - .get(IEventDispatcher) - ?.dispatch(new SubagentStarted({ subagentId: handle.agentId })); - } - if (runInBackground) { return { output: formatBackgroundAgentResult(taskId, handle, args.description, allowBackground), @@ -505,11 +524,8 @@ export class SubagentTool implements ISubagentTool { } } -registerAgentToolService(ISubagentTool, SubagentTool, { - name: 'Agent', - domain: 'subagent', - requiredRuntimeCapabilities: ['process'], -}); +registerAgentToolService(ISubagentTool, SubagentTool, { name: 'Agent', domain: 'subagent' }); + function buildProfileDescriptions( profiles: readonly AgentProfile[], @@ -519,6 +535,7 @@ function buildProfileDescriptions( name: string, source: ToolReference['source'], ) => boolean, + showModelPreferences: boolean, ): string { return profiles .map((profile) => { @@ -526,6 +543,10 @@ function buildProfileDescriptions( (part): part is string => part !== undefined && part.length > 0, ); const header = details.length === 0 ? `- ${profile.name}` : `- ${profile.name}: ${details.join(' ')}`; + const headerLines = + !showModelPreferences || profile.modelPreference === undefined + ? header + : `${header}\n Model preference: ${profile.modelPreference}`; const activeTools = resolveActiveToolNames(profile); const externallyRestricted = tools.some( (tool) => @@ -537,20 +558,20 @@ function buildProfileDescriptions( .filter((tool) => isToolActive(profile, tool.name, tool.source)) .map((tool) => tool.name); if (effectiveTools.length === 0) { - return `${header}\n Tools: none`; + return `${headerLines}\n Tools: none`; } - return `${header}\n Tools: ${effectiveTools.join(', ')}`; + return `${headerLines}\n Tools: ${effectiveTools.join(', ')}`; } if (activeTools === undefined) { if ((profile.disallowedTools?.length ?? 0) > 0) { - return `${header}\n Tools: all except ${profile.disallowedTools!.join(', ')}`; + return `${headerLines}\n Tools: all except ${profile.disallowedTools!.join(', ')}`; } - return `${header}\n Tools: all`; + return `${headerLines}\n Tools: all`; } if (activeTools.length === 0) { - return `${header}\n Tools: none`; + return `${headerLines}\n Tools: none`; } - return `${header}\n Tools: ${activeTools.join(', ')}`; + return `${headerLines}\n Tools: ${activeTools.join(', ')}`; }) .join('\n'); } diff --git a/packages/agent-core-v2/src/agent/tools/agent/subagent-task.ts b/packages/agent-core-v2/src/agent/tools/agent/subagent-task.ts index 863647c69..38cb41e0f 100644 --- a/packages/agent-core-v2/src/agent/tools/agent/subagent-task.ts +++ b/packages/agent-core-v2/src/agent/tools/agent/subagent-task.ts @@ -1,3 +1,15 @@ +/** + * `agent/tools/agent` — the background-task embodiment of a subagent run. + * + * Wraps a `SubagentHandle` as an `AgentTask` so the run registers in the + * owning agent's task store (a foreground run may detach into it later): + * aborts flow through the task signal, completion settles the task and + * appends the result as its output. `toInfo` also carries the display-facing + * facts (subagent type, normalized model alias, effective thinking effort) + * onto the task record, which the spawned-event / snapshot / REST surfaces + * read back after a client reload. + */ + import type { TokenUsage } from '#/kosong/contract/usage'; import { isAbortError } from '#/_base/utils/abort'; @@ -15,7 +27,6 @@ type SubagentCompletion = { export type SubagentHandle = { readonly agentId: string; readonly profileName: string; - readonly parentToolCallId?: string; readonly model?: string; readonly thinkingEffort?: string; readonly completion: Promise<SubagentCompletion>; @@ -25,7 +36,6 @@ export interface SubagentTaskInfo extends AgentTaskInfoBase { readonly kind: 'agent'; readonly agentId?: string; readonly subagentType?: string; - readonly parentToolCallId?: string; readonly model?: string; readonly thinkingEffort?: string; } @@ -74,7 +84,6 @@ export class SubagentTask implements AgentTask { readonly idPrefix: string = 'agent'; readonly agentId: string; readonly subagentType: string; - readonly parentToolCallId?: string; readonly model?: string; readonly thinkingEffort?: string; @@ -85,7 +94,6 @@ export class SubagentTask implements AgentTask { ) { this.agentId = handle.agentId; this.subagentType = handle.profileName; - this.parentToolCallId = handle.parentToolCallId; this.model = handle.model; this.thinkingEffort = handle.thinkingEffort; } @@ -121,7 +129,6 @@ export class SubagentTask implements AgentTask { kind: 'agent', agentId: this.agentId, subagentType: this.subagentType, - parentToolCallId: this.parentToolCallId, model: this.model, thinkingEffort: this.thinkingEffort, }; diff --git a/packages/agent-core-v2/src/agent/tools/ask-user-question/ask-user-question.ts b/packages/agent-core-v2/src/agent/tools/ask-user-question/ask-user-question.ts index cf3b6dd50..f44a41151 100644 --- a/packages/agent-core-v2/src/agent/tools/ask-user-question/ask-user-question.ts +++ b/packages/agent-core-v2/src/agent/tools/ask-user-question/ask-user-question.ts @@ -1,3 +1,15 @@ +/** + * `tools` domain — `IAskUserQuestionTool` contract (the + * `AskUserQuestion` tool). + * + * Public contract of the `AskUserQuestion` structured user question tool: + * the input zod schemas the model-facing parameters are derived from + * (including the background-asking variant and the uniqueness validation + * shared by both the schema refinement and the runtime re-check) and the + * `IAskUserQuestionTool` DI decorator that the implementation registers + * against via `registerAgentToolService`. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -88,6 +100,7 @@ export const AskUserQuestionInputSchema: z.ZodType<AskUserQuestionInput> = { message: QUESTION_UNIQUENESS_MESSAGE }, ); + export interface IAskUserQuestionTool extends AgentTool<AskUserQuestionInput> { readonly _serviceBrand: undefined; } diff --git a/packages/agent-core-v2/src/agent/tools/ask-user-question/askUserQuestionTool.ts b/packages/agent-core-v2/src/agent/tools/ask-user-question/askUserQuestionTool.ts index 38375003c..2ff2a4cb4 100644 --- a/packages/agent-core-v2/src/agent/tools/ask-user-question/askUserQuestionTool.ts +++ b/packages/agent-core-v2/src/agent/tools/ask-user-question/askUserQuestionTool.ts @@ -1,10 +1,32 @@ +/** + * `tools` domain — `AskUserQuestionTool` implementation (the + * `AskUserQuestion` tool). + * + * The LLM calls this tool when it needs structured input from the user + * (multiple-choice, preference selection, disambiguation). The tool delegates + * to `ISessionQuestionService` (the Session-scoped question service backed by + * the `interaction` kernel), which owns the actual UI interaction. Requests + * record the owning agent (`IAgentScopeContext.agentId`) on the interaction + * origin, so question events and transcript frames route to the asking + * agent's surfaces instead of falling back to 'main' (a subagent's question + * must not land there). Answers and dismissals are tracked through + * `ITelemetryService`; `background: true` registers a + * `QuestionBackgroundTask` on + * `IAgentTaskService` so the call returns immediately with a `task_id`. + * + * Registered via the module-level `registerAgentToolService(IAskUserQuestionTool, + * AskUserQuestionTool)` at the bottom of this file — the same "import = + * register" pattern used by every agent tool. Bound at Agent scope. + */ + +import { z } from 'zod'; + import { CoreErrors } from '#/_base/errors/codes'; import { Error2 } from '#/_base/errors/errors'; import { toInputJsonSchema } from '#/tool/input-schema'; import { isAbortError } from '#/_base/utils/abort'; import { IAgentTaskService } from '#/agent/task/task'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import type { QuestionAnsweredEvent, QuestionDismissedEvent } from '#/app/telemetry/events'; import type { @@ -22,7 +44,6 @@ import type { QuestionResult, } from '#/session/question/question'; import { - AskUserQuestionInputSchema, AskUserQuestionInputSchemaWithBackground, IAskUserQuestionTool, questionUniquenessError, @@ -31,38 +52,27 @@ import { import DESCRIPTION from './ask-user.md?raw'; import { QuestionBackgroundTask } from './question-background-task'; + const QUESTION_DISMISSED_MESSAGE = 'User dismissed the question without answering.'; const QUESTION_UNSUPPORTED_FAILURE_MESSAGE = 'The connected client does not support interactive questions. Do NOT call this tool again. Ask the user directly in your text response instead.'; -const BACKGROUND_DESCRIPTION = - '- Set background=true when you can keep working without the answer. This starts a background question task and returns a task_id immediately. The answer arrives automatically in a later turn — you do not need to poll, sleep, or check on it. Continue with other work; never fabricate or predict the answer.'; - -const BACKGROUND_UNAVAILABLE_MESSAGE = - 'Background questions are not available for this agent because TaskList, TaskOutput, and TaskStop are not enabled.'; - -const PARAMETERS_WITH_BACKGROUND = toInputJsonSchema(AskUserQuestionInputSchemaWithBackground); -const PARAMETERS_FOREGROUND_ONLY = toInputJsonSchema(AskUserQuestionInputSchema); export class AskUserQuestionTool implements IAskUserQuestionTool { declare readonly _serviceBrand: undefined; readonly name = 'AskUserQuestion' as const; + readonly description: string; + readonly parameters: Record<string, unknown>; constructor( @ISessionQuestionService private readonly question: ISessionQuestionService, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentTaskService private readonly tasks: IAgentTaskService, @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @IAgentToolPolicyService private readonly toolPolicy: IAgentToolPolicyService, - ) {} - - get description(): string { - return `${DESCRIPTION}${this.allowBackground() ? BACKGROUND_DESCRIPTION : ''}`; - } - - get parameters(): Record<string, unknown> { - return this.allowBackground() ? PARAMETERS_WITH_BACKGROUND : PARAMETERS_FOREGROUND_ONLY; + ) { + this.description = `${DESCRIPTION}- Set background=true when you can keep working without the answer. This starts a background question task and returns a task_id immediately. The answer arrives automatically in a later turn — you do not need to poll, sleep, or check on it. Continue with other work; never fabricate or predict the answer.`; + this.parameters = toInputJsonSchema(this.inputSchema()); } resolveExecution(args: AskUserQuestionInput): ToolExecution { @@ -80,10 +90,6 @@ export class AskUserQuestionTool implements IAskUserQuestionTool { args: AskUserQuestionInput, { toolCallId, signal, turnId, trace }: ExecutableToolContext, ): Promise<ExecutableToolResult> { - if (args.background === true && !this.allowBackground()) { - return { isError: true, output: BACKGROUND_UNAVAILABLE_MESSAGE }; - } - const uniquenessError = questionUniquenessError(args.questions); if (uniquenessError !== null) { return { isError: true, output: uniquenessError }; @@ -96,12 +102,8 @@ export class AskUserQuestionTool implements IAskUserQuestionTool { return this.executeQuestion(args, { toolCallId, turnId, signal, trace }); } - private allowBackground(): boolean { - return ( - this.toolPolicy.isToolActive('TaskList') && - this.toolPolicy.isToolActive('TaskOutput') && - this.toolPolicy.isToolActive('TaskStop') - ); + private inputSchema(): z.ZodType<AskUserQuestionInput> { + return AskUserQuestionInputSchemaWithBackground; } private executeInBackground( diff --git a/packages/agent-core-v2/src/agent/tools/ask-user-question/question-background-task.ts b/packages/agent-core-v2/src/agent/tools/ask-user-question/question-background-task.ts index f52745871..965ff476c 100644 --- a/packages/agent-core-v2/src/agent/tools/ask-user-question/question-background-task.ts +++ b/packages/agent-core-v2/src/agent/tools/ask-user-question/question-background-task.ts @@ -1,3 +1,14 @@ +/** + * `questionTools` domain — `QuestionBackgroundTask`, the background-execution + * handle for `AskUserQuestionTool` (`background: true`). + * + * Mirrors v1's `QuestionBackgroundTask`: runs the question request on a + * detached task so the tool call can return immediately with a `task_id`, + * while the user's answer (parked in `ISessionQuestionService`) settles the + * task later. The task service fires the terminal notification on settle, + * which delivers the answer to the agent in a later turn. + */ + import { isAbortError } from '#/_base/utils/abort'; import { type AgentTask, diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-create/cron-create.md b/packages/agent-core-v2/src/agent/tools/cron/cron-create/cron-create.md similarity index 100% rename from packages/agent-core-v2/src/features/cron/tools/cron-create/cron-create.md rename to packages/agent-core-v2/src/agent/tools/cron/cron-create/cron-create.md diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-create/cron-create.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-create/cron-create.ts similarity index 74% rename from packages/agent-core-v2/src/features/cron/tools/cron-create/cron-create.ts rename to packages/agent-core-v2/src/agent/tools/cron/cron-create/cron-create.ts index 8d023bbf5..c94e8ab64 100644 --- a/packages/agent-core-v2/src/features/cron/tools/cron-create/cron-create.ts +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-create/cron-create.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `ICronCreateTool` contract. + * + * Public contract of the CronCreate tool: the input zod schema (5-field cron + * expression + prompt + recurring flag), the output record shape reported + * back to the model, and the per-session job cap shared with the session cron + * service. The tool schedules a prompt to be re-injected into this session at + * a future wall-clock time, either once (`recurring: false`) or on a cron + * cadence (`recurring: true`, the default). Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-create/cronCreateTool.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-create/cronCreateTool.ts similarity index 68% rename from packages/agent-core-v2/src/features/cron/tools/cron-create/cronCreateTool.ts rename to packages/agent-core-v2/src/agent/tools/cron/cron-create/cronCreateTool.ts index 21254f2eb..0a844ef0b 100644 --- a/packages/agent-core-v2/src/features/cron/tools/cron-create/cronCreateTool.ts +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-create/cronCreateTool.ts @@ -1,11 +1,45 @@ -import { type ToolExecution } from '#/tool/toolContract'; +/** + * `tools` domain — `ICronCreateTool` implementation. + * + * CronCreateTool — schedule a prompt to be re-injected into this session + * at a future wall-clock time, either once (`recurring: false`) or on a + * cron cadence (`recurring: true`, the default). + * + * Tasks live in `ISessionCronService` (Session scope) and are persisted + * through the App-scoped `ICronTaskPersistence` under the project's cron + * scope, so resuming the same session reloads them and the + * scheduler picks up where it left off (fires that fell during downtime + * are collapsed into a single delivery with `coalescedCount`). Tasks do + * NOT carry over into a brand-new session. + * + * The tool itself is pure validation + bookkeeping; the firing / + * coalesce / jitter / persistence is delegated to `ISessionCronService`. + * This file only knows how to: + * + * 1. validate the request (killswitch, cron parse, 5-year window, + * session cap, byte-length cap); + * 2. add it to the service (which writes through to the store); + * 3. report back the post-jitter `nextFireAt` and a human-readable + * schedule for the model's benefit; + * 4. emit `cron_scheduled` telemetry through the service (the tool + * does **not** reach into `ITelemetryService` directly). + * + * Collaborators: `ISessionCronService` for task storage, + * scheduling state and telemetry emission, `IAgentScopeContext` for the + * emitting agent id, and the App-scope cron helpers for + * expression parsing and timestamp formatting. Bound at Agent scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import type { ToolExecution } from '#/tool/toolContract'; import { toInputJsonSchema } from '#/tool/input-schema'; import { literalRulePattern } from '#/tool/rule-match'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { AgentCron, type CronRuntime } from '#/features/cron/cronAgentRuntime'; -import { computeNextCronRun, cronToHuman, hasFireWithinYears, parseCronExpression, type ParsedCronExpression } from '#/features/cron/internal/cron-expr'; -import { formatLocalIsoWithOffset } from '#/features/cron/internal/format'; +import { ISessionCronService } from '#/session/cron/sessionCronService'; +import { computeNextCronRun, cronToHuman, hasFireWithinYears, parseCronExpression, type ParsedCronExpression } from '#/app/cron/cron-expr'; +import { formatLocalIsoWithOffset } from '#/app/cron/format'; import { ICronCreateTool, @@ -15,9 +49,9 @@ import { type CronCreateInput, type CronCreateOutput, } from './cron-create'; -import { CRON_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; import CRON_CREATE_DESCRIPTION from './cron-create.md?raw'; + const ONE_SHOT_MAX_FUTURE_MS = 350 * 24 * 60 * 60 * 1000; export class CronCreateTool implements ICronCreateTool { @@ -30,17 +64,11 @@ export class CronCreateTool implements ICronCreateTool { ); constructor( - @IAgentLifecycleService private readonly manager: IAgentLifecycleService, + @ISessionCronService private readonly cron: ISessionCronService, @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, ) {} - private get cron(): CronRuntime { - return this.manager.resolve(this.scopeContext.agentContext, AgentCron); - } - resolveExecution(args: CronCreateInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, CRON_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; if (this.cron.isDisabled()) { return { isError: true, @@ -177,3 +205,11 @@ function formatOutput(o: CronCreateOutput): string { ]; return lines.join('\n'); } + +registerScopedService( + LifecycleScope.Agent, + ICronCreateTool, + CronCreateTool, + ScopeActivation.OnScopeCreated, + 'cron', +); diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-delete/cron-delete.md b/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cron-delete.md similarity index 100% rename from packages/agent-core-v2/src/features/cron/tools/cron-delete/cron-delete.md rename to packages/agent-core-v2/src/agent/tools/cron/cron-delete/cron-delete.md diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-delete/cron-delete.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cron-delete.ts similarity index 58% rename from packages/agent-core-v2/src/features/cron/tools/cron-delete/cron-delete.ts rename to packages/agent-core-v2/src/agent/tools/cron/cron-delete/cron-delete.ts index 19d9886e4..58b21342c 100644 --- a/packages/agent-core-v2/src/features/cron/tools/cron-delete/cron-delete.ts +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cron-delete.ts @@ -1,3 +1,13 @@ +/** + * `tools` domain — `ICronDeleteTool` contract. + * + * Public contract of the CronDelete tool: cancel a scheduled cron job by id. + * The input is the cron job id (a ULID) returned by CronCreate / CronList; a + * miss is reported as an error so the model corrects itself (typically by + * calling CronList again) instead of learning that deletes are idempotent. + * Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cronDeleteTool.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cronDeleteTool.ts new file mode 100644 index 000000000..76c08f919 --- /dev/null +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-delete/cronDeleteTool.ts @@ -0,0 +1,111 @@ +/** + * `tools` domain — `ICronDeleteTool` implementation. + * + * CronDeleteTool — cancel a scheduled cron job by id. + * + * The tool's job is intentionally narrow: validate the id shape, ask the + * service to drop the entry, and report whether anything was actually + * removed. The scheduler picks up the deletion on its next `tick()` + * automatically because the task set is re-read every pass — there is no + * separate "unsubscribe" handshake to keep in sync. + * + * Why "not found" is reported as an error: + * + * - The model uses the result string to decide whether to follow up + * (e.g. confirm to the user, retry, or move on). Returning a + * success-shaped message for a no-op would silently teach the model + * that CronDelete is idempotent against missing ids, which it is + * not — the next `CronList` would still show whatever id the model + * thought it deleted. Surfacing `isError: true` lets the model + * correct itself (typically by calling `CronList` again). + * + * Why the service is not consulted for telemetry on the not-found + * branch: + * + * - `cron_deleted` records an actual state change. Emitting it on a + * miss would inflate the metric and break parity with `cron_create` + * (which never fires on a rejected schedule). The branch is fully + * observable through tool-call telemetry already. + * + * Refresh-cron pattern this tool participates in: + * + * When `CronList` (or a fired job's origin) reports `stale: true`, the + * documented "refresh" flow is `CronDelete(id)` followed by a fresh + * `CronCreate` with the same cron + prompt. That resets `createdAt`, + * clears the stale flag, and rejoins the herd-avoidance jitter draw + * with a new task id. The doc string spells this out so the model can + * reach for it without prompting from a system message. + * + * Collaborators: `ISessionCronService` for task removal + * and telemetry emission, and `IAgentScopeContext` for the emitting agent + * id. Bound at Agent scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import type { ToolExecution } from '#/tool/toolContract'; +import { toInputJsonSchema } from '#/tool/input-schema'; +import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; +import { ISessionCronService } from '#/session/cron/sessionCronService'; + +import { ICronDeleteTool, CronDeleteInputSchema, type CronDeleteInput } from './cron-delete'; +import CRON_DELETE_DESCRIPTION from './cron-delete.md?raw'; + + +const ID_PATTERN = /^(?:[0-9a-f]{8}|[0-9A-HJKMNP-TV-Z]{26})$/i; + +export class CronDeleteTool implements ICronDeleteTool { + declare readonly _serviceBrand: undefined; + + readonly name = 'CronDelete' as const; + readonly description = CRON_DELETE_DESCRIPTION; + readonly parameters: Record<string, unknown> = toInputJsonSchema( + CronDeleteInputSchema, + ); + + constructor( + @ISessionCronService private readonly cron: ISessionCronService, + @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + ) {} + + resolveExecution(args: CronDeleteInput): ToolExecution { + if (!ID_PATTERN.test(args.id)) { + return { + isError: true, + output: `Invalid cron job id ${JSON.stringify( + args.id, + )} — must be a ULID.`, + }; + } + + return { + description: `Deleting cron ${args.id}`, + approvalRule: this.name, + execute: async () => { + const removed = this.cron.removeTasks([args.id]); + if (removed.length === 0) { + return { + isError: true, + output: `No cron job with id ${args.id}.`, + }; + } + + this.cron.emitDeleted(args.id, this.scopeContext.agentId); + + return { + output: `Deleted cron job ${args.id}.`, + isError: false, + }; + }, + }; + } +} + +registerScopedService( + LifecycleScope.Agent, + ICronDeleteTool, + CronDeleteTool, + ScopeActivation.OnScopeCreated, + 'cron', +); diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-list/cron-list.md b/packages/agent-core-v2/src/agent/tools/cron/cron-list/cron-list.md similarity index 100% rename from packages/agent-core-v2/src/features/cron/tools/cron-list/cron-list.md rename to packages/agent-core-v2/src/agent/tools/cron/cron-list/cron-list.md diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-list/cron-list.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-list/cron-list.ts similarity index 51% rename from packages/agent-core-v2/src/features/cron/tools/cron-list/cron-list.ts rename to packages/agent-core-v2/src/agent/tools/cron/cron-list/cron-list.ts index 5a20d91f9..5e5cc2c13 100644 --- a/packages/agent-core-v2/src/features/cron/tools/cron-list/cron-list.ts +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-list/cron-list.ts @@ -1,3 +1,13 @@ +/** + * `tools` domain — `ICronListTool` contract. + * + * Public contract of the CronList tool: a read-only, side-effect-free tool + * that enumerates the cron tasks currently scheduled in this session. Takes + * no arguments; each output record carries the task id, verbatim cron + * expression, human-readable schedule, post-jitter next fire time, recurring + * flag, age, and stale marker. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/cron/cron-list/cronListTool.ts b/packages/agent-core-v2/src/agent/tools/cron/cron-list/cronListTool.ts new file mode 100644 index 000000000..85a19cbb1 --- /dev/null +++ b/packages/agent-core-v2/src/agent/tools/cron/cron-list/cronListTool.ts @@ -0,0 +1,146 @@ +/** + * `tools` domain — `ICronListTool` implementation. + * + * CronListTool — enumerate the cron tasks currently scheduled in this + * session. + * + * Read-only and side-effect-free. The output uses a + * `key: value\n---\n` record layout so the LLM sees a consistent + * layout across the "list scheduled work" tools. + * + * What each record carries: + * + * - `id` — the task id (a ULID) (also accepted by CronDelete). + * - `cron` — verbatim 5-field expression as scheduled. + * - `humanSchedule` — best-effort plain-English rendering via + * `cronToHuman`; falls back to the raw `cron` + * string if the expression can't be parsed. + * - `nextFireAt` — post-jitter local ISO timestamp with offset, + * or the literal + * string `null` when there is no fire in the + * 5-year window (or the expression is malformed). + * This is the same jittered value `CronCreate` + * reports, so the LLM can reason about herd- + * avoidance offsets without surprise. + * - `recurring` — `true` unless the task was explicitly created + * with `recurring: false`. + * - `ageDays` — `(wallNow - createdAt) / day`, formatted to two + * decimal places. Useful context for the `stale` + * flag and for the LLM's "should I still be + * running?" judgement. + * - `stale` — mirrors `ISessionCronService.isStale(task)` + * (`recurring && age >= 7 days`, gated by + * `KIMI_CRON_NO_STALE`). + * + * The tool never throws on malformed cron strings. A defensive + * try/catch around the parse path lets the record render with the raw + * `cron`, a `humanSchedule` fallback equal to `cron`, and + * `nextFireAt: null` — that should never happen for tasks that went + * through `CronCreate` (which validates), but guards against future + * direct `store.add(...)` inserts. + * + * Collaborators: `ISessionCronService` for the task list, + * staleness and per-task next-fire reads, plus the App-scope cron helpers + * for expression parsing and timestamp formatting. Bound at Agent scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import type { ToolExecution } from '#/tool/toolContract'; +import { toInputJsonSchema } from '#/tool/input-schema'; +import { ISessionCronService } from '#/session/cron/sessionCronService'; +import { cronToHuman, parseCronExpression } from '#/app/cron/cron-expr'; +import { type CronTask } from '#/app/cron/cronTask'; +import { formatLocalIsoWithOffset } from '#/app/cron/format'; + +import { ICronListTool, CronListInputSchema, type CronListInput } from './cron-list'; +import CRON_LIST_DESCRIPTION from './cron-list.md?raw'; + + +const MS_PER_DAY = 24 * 60 * 60 * 1000; + +const PROMPT_PREVIEW_BYTES = 200; + +function previewPrompt(prompt: string): string { + const buf = Buffer.from(prompt, 'utf8'); + if (buf.byteLength <= PROMPT_PREVIEW_BYTES) return prompt; + let end = PROMPT_PREVIEW_BYTES; + while (end > 0 && (buf[end]! & 0b1100_0000) === 0b1000_0000) end--; + return `${buf.subarray(0, end).toString('utf8')}…(truncated)`; +} + +export class CronListTool implements ICronListTool { + declare readonly _serviceBrand: undefined; + + readonly name = 'CronList' as const; + readonly description = CRON_LIST_DESCRIPTION; + readonly parameters: Record<string, unknown> = toInputJsonSchema( + CronListInputSchema, + ); + + constructor(@ISessionCronService private readonly cron: ISessionCronService) {} + + resolveExecution(_args: CronListInput): ToolExecution { + return { + description: 'Listing scheduled cron jobs', + approvalRule: this.name, + execute: async () => { + const tasks = this.cron.list(); + const nowMs = this.cron.now(); + const records = tasks.map((t) => this.renderRecord(t, nowMs)); + const header = `cron_jobs: ${String(tasks.length)}`; + if (records.length === 0) { + return { + output: `${header}\nNo cron jobs scheduled.`, + isError: false, + }; + } + return { + output: `${header}\n${records.join('\n---\n')}`, + isError: false, + }; + }, + }; + } + + private renderRecord(task: CronTask, nowMs: number): string { + const recurring = task.recurring !== false; + + const ageMs = nowMs - task.createdAt; + const ageDays = Number.isFinite(ageMs) ? ageMs / MS_PER_DAY : 0; + + const stale = this.cron.isStale(task); + + let humanSchedule = task.cron; + let nextFireAtIso = 'null'; + try { + const parsed = parseCronExpression(task.cron); + humanSchedule = cronToHuman(parsed); + const nextFireMs = this.cron.getNextFireForTask(task.id); + if (nextFireMs !== null) { + nextFireAtIso = formatLocalIsoWithOffset(nextFireMs); + } + } catch { + } + + return [ + `id: ${task.id}`, + `cron: ${task.cron}`, + `humanSchedule: ${humanSchedule}`, + `prompt: ${JSON.stringify(previewPrompt(task.prompt))}`, + `nextFireAt: ${nextFireAtIso}`, + `recurring: ${String(recurring)}`, + `ageDays: ${ageDays.toFixed(2)}`, + `stale: ${String(stale)}`, + ].join('\n'); + } +} + +registerScopedService( + LifecycleScope.Agent, + ICronListTool, + CronListTool, + ScopeActivation.OnScopeCreated, + 'cron', +); diff --git a/packages/agent-core-v2/src/agent/tools/edit/edit.ts b/packages/agent-core-v2/src/agent/tools/edit/edit.ts index 8a5d3acce..3ed654a86 100644 --- a/packages/agent-core-v2/src/agent/tools/edit/edit.ts +++ b/packages/agent-core-v2/src/agent/tools/edit/edit.ts @@ -1,3 +1,17 @@ +/** + * `tools` domain — `IEditTool` contract. + * + * Public contract of Edit, the model's exact-string-replacement editor for + * text files. Line endings are preserved by the model view: the raw file is + * normalized to LF for matching (so pure CRLF files can be edited with LF + * `old_string`), then re-materialized to the original style on write — pure + * CRLF files round-trip to CRLF, mixed/lone-CR files stay on the exact raw + * path. + * + * Owns the `EditInput` zod schema and the Agent-scope service identifier. + * Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/edit/editTool.ts b/packages/agent-core-v2/src/agent/tools/edit/editTool.ts index a3ef1f35c..44de0ce3a 100644 --- a/packages/agent-core-v2/src/agent/tools/edit/editTool.ts +++ b/packages/agent-core-v2/src/agent/tools/edit/editTool.ts @@ -1,15 +1,34 @@ +/** + * `tools` domain — `EditTool` implementation, the Agent entry for exact + * string replacement in a text file. + * + * Agent-scope adapter over the App-scope {@link IFileEditService} capability. + * Keeps only the Agent-facing responsibilities: path resolution, the file + * access declaration, the diff display, the approval rule, the no-op + * pre-check, and mapping the domain-neutral `FileEditResult` into an + * `ExecutableToolResult`. The actual read/edit/write is delegated to + * {@link IFileEditService} (os-backed adapter over `IHostFileSystem`), which + * runs the pure `TextModel` / `EditService` logic. + * + * Path semantics (home expansion, path class) come from the + * `hostEnvironment` domain; the workspace and skill roots come from + * `ISessionWorkspaceContext` / `ISessionSkillCatalog`. + * + * Ported from v1. + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + import { + extendWorkspaceWithSkillRoots, resolvePathAccessPath, type WorkspaceConfig, } from '#/tool/path-access'; import { toInputJsonSchema } from '#/tool/input-schema'; import { literalRulePattern, matchesPathRuleSubject } from '#/tool/rule-match'; import { IFileEditService } from '#/app/edit/fileEdit'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { Runtime } from '#/runtime/runtime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { ToolAccesses, @@ -29,29 +48,26 @@ export class EditTool implements IEditTool { constructor( @IFileEditService private readonly editor: IFileEditService, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, ) {} - private workspaceConfig(runtime: Runtime): WorkspaceConfig { - const view = new RuntimeWorkspaceView(runtime, { - workDir: this.workspaceCtx.workDir, - additionalDirs: [ - ...this.workspaceCtx.additionalDirs, - ...(this.skillCatalog?.catalog.getSkillRoots() ?? []), - ], - }); - return { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; + private get workspaceConfig(): WorkspaceConfig { + return extendWorkspaceWithSkillRoots( + { + workspaceDir: this.workspaceCtx.workDir, + additionalDirs: this.workspaceCtx.additionalDirs, + }, + this.skillCatalog?.catalog.getSkillRoots() ?? [], + this.env.pathClass, + ); } resolveExecution(args: EditInput): ToolExecution { - const inspected = inspectAgentRuntime(this.runtime); - const env = inspected.environment; - const workspace = this.workspaceConfig(inspected); const path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspaceConfig, operation: 'write', }); return { @@ -67,29 +83,15 @@ export class EditTool implements IEditTool { approvalRule: literalRulePattern(this.name, path), matchesRule: (ruleArgs) => matchesPathRuleSubject(ruleArgs, path, { - cwd: workspace.workspaceDir, - pathClass: env.pathClass, - homeDir: env.homeDir, + cwd: this.workspaceConfig.workspaceDir, + pathClass: this.env.pathClass, + homeDir: this.env.homeDir, }), - execute: async () => { - const lease = this.runtime.acquire(['fs']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution(args, path, lease.runtime.fs!); - } finally { - lease.dispose(); - } - }, + execute: () => this.execution(args, path), }; } - private async execution( - args: EditInput, - safePath: string, - fs: IHostFileSystem, - ): Promise<ExecutableToolResult> { + private async execution(args: EditInput, safePath: string): Promise<ExecutableToolResult> { if (args.old_string === args.new_string) { return { isError: true, @@ -103,7 +105,7 @@ export class EditTool implements IEditTool { old_string: args.old_string, new_string: args.new_string, replace_all: args.replace_all ?? false, - }, fs); + }); if (!result.ok) { return { isError: true, output: result.error }; } @@ -112,8 +114,4 @@ export class EditTool implements IEditTool { } } -registerAgentToolService(IEditTool, EditTool, { - name: 'Edit', - domain: 'edit', - requiredRuntimeCapabilities: ['fs'], -}); +registerAgentToolService(IEditTool, EditTool, { name: 'Edit', domain: 'edit' }); diff --git a/packages/agent-core-v2/src/agent/tools/fetch-url/fetch-url.ts b/packages/agent-core-v2/src/agent/tools/fetch-url/fetch-url.ts index d4a25bed8..4039df9a4 100644 --- a/packages/agent-core-v2/src/agent/tools/fetch-url/fetch-url.ts +++ b/packages/agent-core-v2/src/agent/tools/fetch-url/fetch-url.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `IFetchURLTool` contract. + * + * Public contract of FetchURL, the model's URL content fetcher. Only + * fully-formed public `http`/`https` URLs are supported. The tool receives + * the App-scope `IWebFetchService` via DI. + * + * Owns the `FetchURLInput` zod schema and the Agent-scope service identifier. + * Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/fetch-url/fetchUrlTool.ts b/packages/agent-core-v2/src/agent/tools/fetch-url/fetchUrlTool.ts index 937e0afd2..865dae671 100644 --- a/packages/agent-core-v2/src/agent/tools/fetch-url/fetchUrlTool.ts +++ b/packages/agent-core-v2/src/agent/tools/fetch-url/fetchUrlTool.ts @@ -1,3 +1,16 @@ +/** + * `tools` domain — `FetchURLTool` implementation. + * + * Receives the App-scope `IWebFetchService` via DI and resolves its + * host-injected `UrlFetcher` per invocation — the service re-reads config and + * login state on each `getUrlFetcher()` call, and composing the fetcher at + * tool construction would both pin that state for the agent's lifetime and + * race the identity freeze during a fast bootstrap. The default service falls + * back to the built-in `LocalFetchURLProvider`, so `FetchURL` is always + * available without OAuth. Bound at Agent scope; self-registers via + * `registerAgentToolService(...)` at module load. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { literalRulePattern, matchesGlobRuleSubject } from '#/tool/rule-match'; import { diff --git a/packages/agent-core-v2/src/features/goal/tools/create-goal/create-goal.md b/packages/agent-core-v2/src/agent/tools/goal/create-goal/create-goal.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/tools/create-goal/create-goal.md rename to packages/agent-core-v2/src/agent/tools/goal/create-goal/create-goal.md diff --git a/packages/agent-core-v2/src/features/goal/tools/create-goal/create-goal.ts b/packages/agent-core-v2/src/agent/tools/goal/create-goal/create-goal.ts similarity index 65% rename from packages/agent-core-v2/src/features/goal/tools/create-goal/create-goal.ts rename to packages/agent-core-v2/src/agent/tools/goal/create-goal/create-goal.ts index 64a52f72b..e57238496 100644 --- a/packages/agent-core-v2/src/features/goal/tools/create-goal/create-goal.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/create-goal/create-goal.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `ICreateGoalTool` contract. + * + * Public contract of the CreateGoal tool: the input schema the model calls + * with and the Agent-scope identifier used to resolve the implementation + * through the container. The tool lets the main agent start an explicit goal + * on the user's behalf; the goal becomes durable, structured state owned by + * the agent's goal service, not text parsed from a slash command. Bound at + * Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/goal/tools/create-goal/createGoalTool.ts b/packages/agent-core-v2/src/agent/tools/goal/create-goal/createGoalTool.ts similarity index 69% rename from packages/agent-core-v2/src/features/goal/tools/create-goal/createGoalTool.ts rename to packages/agent-core-v2/src/agent/tools/goal/create-goal/createGoalTool.ts index 8d97d245d..00d917f15 100644 --- a/packages/agent-core-v2/src/features/goal/tools/create-goal/createGoalTool.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/create-goal/createGoalTool.ts @@ -1,14 +1,24 @@ +/** + * `tools` domain — `ICreateGoalTool` implementation. + * + * Resolves a CreateGoal call against the goal service (`goal`): guards + * against the current goal changing between resolution and execution, then + * creates the goal and returns its serialized snapshot. The approval display + * carries a `goal_start` card unless the permission mode (`permissionMode`) + * is `auto`. Registered for the main agent only, mirroring v1's + * `agent.type === 'main'` gate. Bound at Agent scope. + */ + import type { ToolInputDisplay } from '#/tool/toolInputDisplay'; import { toInputJsonSchema } from '#/tool/input-schema'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { GOAL_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; import { type ToolExecution } from '#/tool/toolContract'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; -import { AgentGoal, type GoalRuntime } from '#/features/goal/goalAgentRuntime'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { goalForModel } from '#/features/goal/tools/serialize'; +import { IAgentGoalService } from '#/agent/goal/goal'; +import { goalForModel } from '#/agent/goal/tools/serialize'; import DESCRIPTION from './create-goal.md?raw'; import { @@ -23,19 +33,12 @@ export class CreateGoalTool implements ICreateGoalTool { readonly description: string = DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(CreateGoalToolInputSchema); - private readonly goal: GoalRuntime; - constructor( - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, + @IAgentGoalService private readonly goal: IAgentGoalService, @IAgentPermissionModeService private readonly permissionMode: IAgentPermissionModeService, - ) { - this.goal = manager.resolve(scopeContext.agentContext, AgentGoal); - } + ) {} resolveExecution(args: CreateGoalToolInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, GOAL_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; const goalAtResolution = this.goal.getGoal().goal; return { description: 'Creating a goal', @@ -74,3 +77,8 @@ export class CreateGoalTool implements ICreateGoalTool { } } +registerAgentToolService(ICreateGoalTool, CreateGoalTool, { + name: 'CreateGoal', + domain: 'goal', + when: (accessor) => accessor.get(IAgentScopeContext).agentId === 'main', +}); diff --git a/packages/agent-core-v2/src/features/goal/tools/get-goal/get-goal.md b/packages/agent-core-v2/src/agent/tools/goal/get-goal/get-goal.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/tools/get-goal/get-goal.md rename to packages/agent-core-v2/src/agent/tools/goal/get-goal/get-goal.md diff --git a/packages/agent-core-v2/src/agent/tools/goal/get-goal/get-goal.ts b/packages/agent-core-v2/src/agent/tools/goal/get-goal/get-goal.ts new file mode 100644 index 000000000..da89155dd --- /dev/null +++ b/packages/agent-core-v2/src/agent/tools/goal/get-goal/get-goal.ts @@ -0,0 +1,21 @@ +/** + * `tools` domain — `IGetGoalTool` contract. + * + * Public contract of the GetGoal tool: the (empty) input schema and the + * Agent-scope identifier used to resolve the implementation through the + * container. The tool returns the current goal snapshot — objective, status, + * budgets, and usage counters — so the model can decide whether to continue, + * report completion via UpdateGoal, report a blocker, or respect a pause. + * Bound at Agent scope. + */ + +import { z } from 'zod'; + +import { createDecorator } from '#/_base/di/instantiation'; +import { type AgentTool } from '#/tool/toolContract'; + +export const GetGoalToolInputSchema = z.object({}).strict(); +export type GetGoalToolInput = z.infer<typeof GetGoalToolInputSchema>; + +export interface IGetGoalTool extends AgentTool<GetGoalToolInput> { readonly _serviceBrand: undefined } +export const IGetGoalTool = createDecorator<IGetGoalTool>('getGoalTool'); diff --git a/packages/agent-core-v2/src/features/goal/tools/get-goal/getGoalTool.ts b/packages/agent-core-v2/src/agent/tools/goal/get-goal/getGoalTool.ts similarity index 52% rename from packages/agent-core-v2/src/features/goal/tools/get-goal/getGoalTool.ts rename to packages/agent-core-v2/src/agent/tools/goal/get-goal/getGoalTool.ts index 4e5ec5622..fefe5697e 100644 --- a/packages/agent-core-v2/src/features/goal/tools/get-goal/getGoalTool.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/get-goal/getGoalTool.ts @@ -1,11 +1,20 @@ +/** + * `tools` domain — `IGetGoalTool` implementation. + * + * Reads the current goal snapshot from the goal service (`goal`) and returns + * it serialized for the model, so the model can decide whether to continue, + * report completion via UpdateGoal, report a blocker, or respect a pause. + * Registered for the main agent only, mirroring v1's `agent.type === 'main'` + * gate. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { GOAL_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; import { type ToolExecution } from '#/tool/toolContract'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; -import { AgentGoal, type GoalRuntime } from '#/features/goal/goalAgentRuntime'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { goalResultForModel } from '#/features/goal/tools/serialize'; +import { IAgentGoalService } from '#/agent/goal/goal'; +import { goalResultForModel } from '#/agent/goal/tools/serialize'; import DESCRIPTION from './get-goal.md?raw'; import { GetGoalToolInputSchema, IGetGoalTool, type GetGoalToolInput } from './get-goal'; @@ -16,18 +25,9 @@ export class GetGoalTool implements IGetGoalTool { readonly description: string = DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(GetGoalToolInputSchema); - private readonly goal: GoalRuntime; - - constructor( - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) { - this.goal = manager.resolve(scopeContext.agentContext, AgentGoal); - } + constructor(@IAgentGoalService private readonly goal: IAgentGoalService) {} resolveExecution(_args: GetGoalToolInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, GOAL_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; return { description: 'Reading the current goal', approvalRule: this.name, @@ -39,3 +39,8 @@ export class GetGoalTool implements IGetGoalTool { } } +registerAgentToolService(IGetGoalTool, GetGoalTool, { + name: 'GetGoal', + domain: 'goal', + when: (accessor) => accessor.get(IAgentScopeContext).agentId === 'main', +}); diff --git a/packages/agent-core-v2/src/features/goal/tools/set-goal-budget/set-goal-budget.md b/packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/set-goal-budget.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/tools/set-goal-budget/set-goal-budget.md rename to packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/set-goal-budget.md diff --git a/packages/agent-core-v2/src/features/goal/tools/set-goal-budget/set-goal-budget.ts b/packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/set-goal-budget.ts similarity index 64% rename from packages/agent-core-v2/src/features/goal/tools/set-goal-budget/set-goal-budget.ts rename to packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/set-goal-budget.ts index 267929807..155909bbb 100644 --- a/packages/agent-core-v2/src/features/goal/tools/set-goal-budget/set-goal-budget.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/set-goal-budget.ts @@ -1,3 +1,13 @@ +/** + * `tools` domain — `ISetGoalBudgetTool` contract. + * + * Public contract of the SetGoalBudget tool: the budget-unit enum backing the + * input schema the model calls with, plus the Agent-scope identifier used to + * resolve the implementation through the container. The tool records a + * user-stated hard runtime limit for the current goal, one limit at a time. + * Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/goal/tools/set-goal-budget/setGoalBudgetTool.ts b/packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/setGoalBudgetTool.ts similarity index 82% rename from packages/agent-core-v2/src/features/goal/tools/set-goal-budget/setGoalBudgetTool.ts rename to packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/setGoalBudgetTool.ts index 62399afdd..0dced7fdb 100644 --- a/packages/agent-core-v2/src/features/goal/tools/set-goal-budget/setGoalBudgetTool.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/set-goal-budget/setGoalBudgetTool.ts @@ -1,11 +1,21 @@ +/** + * `tools` domain — `ISetGoalBudgetTool` implementation. + * + * Normalizes the model's budget input, converts supported time units to + * milliseconds, and rejects obviously unreasonable time limits before writing + * the limit through the goal service (`goal`). Stops the batch when the goal + * has already reached the new budget, and guards against the goal changing + * between resolution and execution. Registered for the main agent only, + * mirroring v1's `agent.type === 'main'` gate. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { GOAL_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; import { type ToolExecution } from '#/tool/toolContract'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; -import { AgentGoal, type GoalRuntime } from '#/features/goal/goalAgentRuntime'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import type { GoalBudgetLimits, GoalSnapshot } from '#/features/goal/types'; +import { IAgentGoalService } from '#/agent/goal/goal'; +import type { GoalBudgetLimits, GoalSnapshot } from '#/agent/goal/types'; import DESCRIPTION from './set-goal-budget.md?raw'; import { @@ -23,18 +33,9 @@ export class SetGoalBudgetTool implements ISetGoalBudgetTool { readonly description: string = DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(SetGoalBudgetToolInputSchema); - private readonly goal: GoalRuntime; - - constructor( - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) { - this.goal = manager.resolve(scopeContext.agentContext, AgentGoal); - } + constructor(@IAgentGoalService private readonly goal: IAgentGoalService) {} resolveExecution(args: SetGoalBudgetToolInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, GOAL_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; const normalizedArgs = normalizeBudgetInput(args); const budget = budgetLimitsFromInput(normalizedArgs); const goalAtResolution = this.goal.getGoal().goal; @@ -96,6 +97,11 @@ export class SetGoalBudgetTool implements ISetGoalBudgetTool { } } +registerAgentToolService(ISetGoalBudgetTool, SetGoalBudgetTool, { + name: 'SetGoalBudget', + domain: 'goal', + when: (accessor) => accessor.get(IAgentScopeContext).agentId === 'main', +}); function normalizeBudgetInput(input: SetGoalBudgetToolInput): SetGoalBudgetToolInput { switch (input.unit) { diff --git a/packages/agent-core-v2/src/features/goal/tools/update-goal/update-goal.md b/packages/agent-core-v2/src/agent/tools/goal/update-goal/update-goal.md similarity index 100% rename from packages/agent-core-v2/src/features/goal/tools/update-goal/update-goal.md rename to packages/agent-core-v2/src/agent/tools/goal/update-goal/update-goal.md diff --git a/packages/agent-core-v2/src/features/goal/tools/update-goal/update-goal.ts b/packages/agent-core-v2/src/agent/tools/goal/update-goal/update-goal.ts similarity index 63% rename from packages/agent-core-v2/src/features/goal/tools/update-goal/update-goal.ts rename to packages/agent-core-v2/src/agent/tools/goal/update-goal/update-goal.ts index 2819c24b9..6da6abd6d 100644 --- a/packages/agent-core-v2/src/features/goal/tools/update-goal/update-goal.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/update-goal/update-goal.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `IUpdateGoalTool` contract. + * + * Public contract of the UpdateGoal tool — the model's single lever over the + * goal lifecycle: the input schema and the Agent-scope identifier used to + * resolve the implementation through the container. The argument is + * intentionally just a status enum — no reason or evidence. The model + * explains itself in its own reply; the status is the machine-readable + * signal. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/goal/tools/update-goal/updateGoalTool.ts b/packages/agent-core-v2/src/agent/tools/goal/update-goal/updateGoalTool.ts similarity index 77% rename from packages/agent-core-v2/src/features/goal/tools/update-goal/updateGoalTool.ts rename to packages/agent-core-v2/src/agent/tools/goal/update-goal/updateGoalTool.ts index b84d1f957..ddf1a5bc2 100644 --- a/packages/agent-core-v2/src/features/goal/tools/update-goal/updateGoalTool.ts +++ b/packages/agent-core-v2/src/agent/tools/goal/update-goal/updateGoalTool.ts @@ -1,14 +1,25 @@ +/** + * `tools` domain — `IUpdateGoalTool` implementation. + * + * Updates the current goal's status through the goal service (`goal`); the + * turn driver reads the status at each turn boundary and stops (`complete` / + * `blocked`) or keeps going (`active`). Guards against the goal changing or + * disappearing between resolution and execution, and ends the turn with the + * completion-summary / blocked-reason prompts (`goal` outcome prompts) on + * terminal statuses. Registered for the main agent only, mirroring v1's + * `agent.type === 'main'` gate. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { GOAL_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; import { type ToolExecution } from '#/tool/toolContract'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; -import { AgentGoal, type GoalRuntime } from '#/features/goal/goalAgentRuntime'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentGoalService } from '#/agent/goal/goal'; import { buildGoalBlockedReasonPrompt, buildGoalCompletionSummaryPrompt, -} from '#/features/goal/tools/outcome-prompts'; +} from '#/agent/goal/tools/outcome-prompts'; import DESCRIPTION from './update-goal.md?raw'; import { @@ -23,18 +34,9 @@ export class UpdateGoalTool implements IUpdateGoalTool { readonly description: string = DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(UpdateGoalToolInputSchema); - private readonly goal: GoalRuntime; - - constructor( - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) { - this.goal = manager.resolve(scopeContext.agentContext, AgentGoal); - } + constructor(@IAgentGoalService private readonly goal: IAgentGoalService) {} resolveExecution(args: UpdateGoalToolInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, GOAL_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; if (!isUpdateGoalStatus(args.status)) { return { isError: true, @@ -104,3 +106,8 @@ function changedGoalOutput(status: UpdateGoalToolInput['status']): string { return 'Goal not blocked: the current goal changed.'; } +registerAgentToolService(IUpdateGoalTool, UpdateGoalTool, { + name: 'UpdateGoal', + domain: 'goal', + when: (accessor) => accessor.get(IAgentScopeContext).agentId === 'main', +}); diff --git a/packages/agent-core-v2/src/agent/tools/mainAgentOnly.ts b/packages/agent-core-v2/src/agent/tools/mainAgentOnly.ts deleted file mode 100644 index 77dccbe4d..000000000 --- a/packages/agent-core-v2/src/agent/tools/mainAgentOnly.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ToolExecution } from '#/tool/toolContract'; -import type { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; - -export const CRON_MAIN_AGENT_ONLY = 'Cron tools are only supported by the main agent.'; - -export const GOAL_MAIN_AGENT_ONLY = 'Goal tools are only supported by the main agent.'; - -export function mainAgentOnlyExecution( - scopeContext: IAgentScopeContext, - output: string, -): ToolExecution | undefined { - if (scopeContext.agentId === MAIN_AGENT_ID) return undefined; - return { isError: true, output }; -} diff --git a/packages/agent-core-v2/src/agent/tools/os/bash/bash.ts b/packages/agent-core-v2/src/agent/tools/os/bash/bash.ts index 975fa8672..c2157a580 100644 --- a/packages/agent-core-v2/src/agent/tools/os/bash/bash.ts +++ b/packages/agent-core-v2/src/agent/tools/os/bash/bash.ts @@ -1,3 +1,18 @@ +/** + * `tools` domain — `IBashTool` contract. + * + * Public contract of Bash, the model's shell command runner: the command runs + * as `cd <cwd> && <command>` inside the session's working directory, with a + * manager-owned timeout deadline — a foreground command whose deadline fires + * is moved to the background instead of being killed, and background tasks + * report completion automatically in a later turn. + * + * Owns the `BashInput` / `BashOutput` zod schemas, the foreground/background + * timeout constants the schema descriptions and validation share with the + * implementation, and the Agent-scope service identifier. Bound at Agent + * scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts b/packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts index ed0fe9908..2454af736 100644 --- a/packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts +++ b/packages/agent-core-v2/src/agent/tools/os/bash/bashTool.ts @@ -1,14 +1,52 @@ +/** + * `tools` domain — `BashTool` implementation, the model's shell command + * runner. + * + * Invokes the execution-environment shell (POSIX bash; Git Bash on Windows) + * through the injected `ISessionProcessRunner`. The command runs as + * `cd <cwd> && <command>` inside the environment's working directory. + * + * Collaborators injected via constructor: + * - `runner` — `ISessionProcessRunner`, spawns the shell process + * - `env` — `IHostEnvironment`, host OS / shell probe (osKind / shellName / shellPath) + * - `ctx` — `ISessionContext`, session cwd used to render the shell prompt + * - `tasks` — `IAgentTaskService`, owns foreground/detached task + * lifecycle (timeouts, detach, user interrupt) + * - `toolPolicy` — `IAgentToolPolicyService`, gates background execution on + * the Task* tools being active + * - `config` — `IConfigService`, task config (auto-background on + * timeout, detach timeout) + * + * Execution goes through `ISessionProcessRunner`, never directly via + * `node:child_process`. + * + * Hardening: + * - `args.timeout` (seconds) arms the manager-owned deadline; a foreground + * command whose deadline fires is moved to the background instead of + * being killed (unless disabled via config), while the ambient `signal` + * always stops the task. + * - stdin is closed immediately so interactive commands (`cat`, `read`, + * `python -c 'input()'`) receive EOF instead of hanging. + * - Two-phase kill is owned by `IAgentTaskService`: SIGTERM → grace → SIGKILL. + * - stdout/stderr are captured by `ProcessTask` for task output; + * foreground runs pass a callback to collect chunks for this call. + * + * Ported from v1. The + * v1 `process.env` spread is intentionally dropped: v2's `ISessionProcessRunner.exec` + * already overlays the per-call `env` on `process.env`, so only the + * noninteractive knobs are passed here. + * + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + import { IAgentTaskService } from '#/agent/task/task'; import { resolveAgentTaskConfig } from '#/agent/task/configSection'; import { IConfigService } from '#/app/config/config'; -import type { HostEnvironmentInfo } from '#/os/interface/hostEnvironment'; -import type { IHostProcess, IHostProcessService } from '#/os/interface/hostProcess'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; +import { ISessionProcessRunner, type IProcess } from '#/session/process/processRunner'; import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; -import { getShellPathBridge } from '#/_base/execEnv/shellPathBridge'; import type { ExecutableToolResult, ToolExecution, ToolUpdate } from '#/tool/toolContract'; import { type ExecutableToolResultBuilderResult, @@ -50,7 +88,7 @@ function normalizeTimeoutMs(timeout: number | undefined, isBackground: boolean): return Math.min(value, timeoutCapS(isBackground)) * MS_PER_SECOND; } -async function disposeProcess(proc: IHostProcess): Promise<void> { +async function disposeProcess(proc: IProcess): Promise<void> { try { await proc.dispose(); } catch { @@ -89,14 +127,21 @@ export class BashTool implements IBashTool { readonly name = 'Bash' as const; readonly parameters: Record<string, unknown> = toInputJsonSchema(BashInputSchema); + private readonly isWindowsBash: boolean; + + private readonly renderedDescription: string; + constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @ISessionProcessRunner private readonly runner: ISessionProcessRunner, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionContext private readonly ctx: ISessionContext, - @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @IAgentTaskService private readonly tasks: IAgentTaskService, @IAgentToolPolicyService private readonly toolPolicy: IAgentToolPolicyService, @IConfigService private readonly config: IConfigService, - ) {} + ) { + this.isWindowsBash = this.env.osKind === 'Windows'; + this.renderedDescription = renderBashDescription(this.env.shellName); + } private allowBackground(): boolean { return ( @@ -117,12 +162,11 @@ export class BashTool implements IBashTool { } get description(): string { - const renderedDescription = renderBashDescription(inspectAgentRuntime(this.runtime).environment.shellName); - if (!this.allowBackground()) return withoutBackgroundDescription(renderedDescription); + if (!this.allowBackground()) return withoutBackgroundDescription(this.renderedDescription); if (!this.autoBackgroundOnTimeout()) { - return withoutAutoBackgroundOnTimeout(renderedDescription); + return withoutAutoBackgroundOnTimeout(this.renderedDescription); } - return renderedDescription; + return this.renderedDescription; } resolveExecution(args: BashInput): ToolExecution { @@ -145,22 +189,22 @@ export class BashTool implements IBashTool { }; } - private spawn( - processService: IHostProcessService, - env: HostEnvironmentInfo, - effectiveCwd: string, - command: string, - ): Promise<IHostProcess> { - const shellCwd = getShellPathBridge(env).toShellPath(effectiveCwd); - const shellCommand = `cd ${shellQuote(shellCwd)} && ${command}`; + private spawn(effectiveCwd: string, command: string): Promise<IProcess> { + const shellCwd = this.isWindowsBash ? windowsPathToPosixPath(effectiveCwd) : effectiveCwd; + const shellArgs = [ + this.env.shellPath, + '-c', + `cd ${shellQuote(shellCwd)} && ${command}`, + ]; + const noninteractiveEnv: Record<string, string> = { NO_COLOR: '1', TERM: 'dumb', GIT_TERMINAL_PROMPT: process.env['GIT_TERMINAL_PROMPT'] ?? '0', - SHELL: env.shellPath, + SHELL: this.env.shellPath, }; - return processService.spawn(env.shellPath, ['-c', shellCommand], { env: noninteractiveEnv }); + return this.runner.exec(shellArgs, { env: noninteractiveEnv }); } private async execution( @@ -174,11 +218,8 @@ export class BashTool implements IBashTool { const startsInBackground = args.run_in_background === true; const foregroundTimeoutMs = normalizeTimeoutMs(args.timeout, false); - const lease = this.runtime.acquire(['process']); - const view = new RuntimeWorkspaceView(lease.runtime, this.workspaceCtx); - const env = lease.runtime.environment; - const command = env.osKind === 'Windows' ? rewriteWindowsNullRedirect(args.command) : args.command; - const effectiveCwd = view.resolve(args.cwd ?? view.workDir); + const command = this.isWindowsBash ? rewriteWindowsNullRedirect(args.command) : args.command; + const effectiveCwd = args.cwd ?? this.ctx.cwd; const description = startsInBackground ? args.description!.trim() : foregroundDescription(args); const timeoutMs = startsInBackground ? args.disable_timeout @@ -187,11 +228,10 @@ export class BashTool implements IBashTool { : foregroundTimeoutMs; const builder = new ToolResultBuilder(); - let proc: IHostProcess; + let proc: IProcess; try { - proc = lease.track(await this.spawn(lease.runtime.process!, env, effectiveCwd, command)); + proc = await this.spawn(effectiveCwd, command); } catch (error) { - lease.dispose(); return { isError: true, output: error instanceof Error ? error.message : String(error), @@ -217,7 +257,7 @@ export class BashTool implements IBashTool { let taskId: string; try { taskId = this.tasks.registerTask( - new ProcessTask(proc, command, description, onProcessOutput, () => lease.dispose()), + new ProcessTask(proc, command, description, onProcessOutput), { detached: startsInBackground, timeoutMs, @@ -230,7 +270,6 @@ export class BashTool implements IBashTool { } catch (error) { collectForegroundOutput = false; await killSpawnedProcess(proc); - lease.dispose(); return { isError: true, output: error instanceof Error ? error.message : String(error), @@ -301,7 +340,7 @@ export class BashTool implements IBashTool { private async foregroundCompletionResult( taskId: string, - proc: IHostProcess, + proc: IProcess, builder: ToolResultBuilder, foregroundTimeoutMs: number, ): Promise<ExecutableToolResult> { @@ -356,7 +395,7 @@ export class BashTool implements IBashTool { private backgroundStartedResult( taskId: string, - proc: IHostProcess, + proc: IProcess, description: string, labels: { title: string; brief: string }, builder = new ToolResultBuilder(), @@ -412,11 +451,7 @@ export class BashTool implements IBashTool { } } -registerAgentToolService(IBashTool, BashTool, { - name: 'Bash', - domain: 'os/backends', - requiredRuntimeCapabilities: ['process'], -}); +registerAgentToolService(IBashTool, BashTool, { name: 'Bash', domain: 'os/backends' }); function formatTimeoutLabel(timeoutMs: number): string { return timeoutMs % 1000 === 0 ? `${String(timeoutMs / 1000)}s` : `${String(timeoutMs)}ms`; @@ -429,14 +464,14 @@ function foregroundDescription(args: BashInput): string { return `Bash: ${preview}`; } -function closeProcessStdin(proc: IHostProcess): void { +function closeProcessStdin(proc: IProcess): void { try { proc.stdin.end(); } catch { } } -async function killSpawnedProcess(proc: IHostProcess): Promise<void> { +async function killSpawnedProcess(proc: IProcess): Promise<void> { try { await proc.kill('SIGTERM'); } catch { @@ -449,6 +484,21 @@ function shellQuote(s: string): string { return `'${s.replaceAll("'", "'\\''")}'`; } +function windowsPathToPosixPath(path: string): string { + if (path.startsWith('\\\\')) { + return path.replaceAll('\\', '/'); + } + + const driveMatch = /^([A-Za-z]):(?:[\\/]|$)/.exec(path); + if (driveMatch !== null) { + const drive = driveMatch[1]!.toLowerCase(); + const rest = path.slice(2).replaceAll('\\', '/'); + return `/${drive}${rest.startsWith('/') ? rest : `/${rest}`}`; + } + + return path.replaceAll('\\', '/'); +} + const WINDOWS_NUL_REDIRECT = /(\d?&?>+\s*)[Nn][Uu][Ll](?=\s|$|[|&;)\n])/g; function rewriteWindowsNullRedirect(command: string): string { diff --git a/packages/agent-core-v2/src/agent/tools/os/bash/process-task.ts b/packages/agent-core-v2/src/agent/tools/os/bash/process-task.ts index bddf4c160..3615a7f6f 100644 --- a/packages/agent-core-v2/src/agent/tools/os/bash/process-task.ts +++ b/packages/agent-core-v2/src/agent/tools/os/bash/process-task.ts @@ -1,8 +1,6 @@ import type { Readable } from 'node:stream'; -import type { IHostProcess } from '#/os/interface/hostProcess'; - -type ProcessHandle = Omit<IHostProcess, '_serviceBrand'>; +import type { IProcess } from '#/session/process/processRunner'; import type { AgentTask, @@ -39,11 +37,10 @@ export class ProcessTask implements AgentTask { private exitCode: number | null = null; constructor( - readonly proc: ProcessHandle, + readonly proc: IProcess, readonly command: string, readonly description: string, private readonly onOutput?: ProcessTaskOutputCallback, - private release?: () => void, ) {} async start(sink: AgentTaskSink): Promise<void> { @@ -108,9 +105,6 @@ export class ProcessTask implements AgentTask { try { await this.proc.dispose(); } catch { - } finally { - this.release?.(); - this.release = undefined; } } } @@ -200,7 +194,7 @@ export interface ProcessTaskResult { } export function createProcessExecutor( - proc: ProcessHandle, + proc: IProcess, onOutput?: ProcessTaskOutputCallback, ): (signal: AbortSignal, output: (data: string) => void) => Promise<ProcessTaskResult> { return async (signal, output) => { @@ -289,7 +283,7 @@ function observeProcessStreamRaw( }); } -async function disposeProcess(proc: ProcessHandle): Promise<void> { +async function disposeProcess(proc: IProcess): Promise<void> { try { await proc.dispose(); } catch { } } diff --git a/packages/agent-core-v2/src/agent/tools/os/glob/glob.ts b/packages/agent-core-v2/src/agent/tools/os/glob/glob.ts index 5043a2e68..1eb7de337 100644 --- a/packages/agent-core-v2/src/agent/tools/os/glob/glob.ts +++ b/packages/agent-core-v2/src/agent/tools/os/glob/glob.ts @@ -1,3 +1,17 @@ +/** + * `tools` domain — `IGlobTool` contract. + * + * Public contract of Glob, the model's ripgrep-backed file pattern matcher. + * Finds files matching a glob pattern, returned sorted by modification time + * (most recent first). `.gitignore` / `.ignore` / `.rgignore` are respected by + * default; sensitive files (such as `.env`) are always filtered out. Results + * are files-only — directories are never listed. + * + * Owns the `GlobInput` zod schema, the tool-owned constants (`MAX_MATCHES`, + * `WINDOWS_PATH_HINT`), and the Agent-scope service identifier. Bound at Agent + * scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/os/glob/globTool.ts b/packages/agent-core-v2/src/agent/tools/os/glob/globTool.ts index 75110f802..591165af5 100644 --- a/packages/agent-core-v2/src/agent/tools/os/glob/globTool.ts +++ b/packages/agent-core-v2/src/agent/tools/os/glob/globTool.ts @@ -1,3 +1,64 @@ +/** + * `tools` domain — `GlobTool` implementation, file pattern matching via + * ripgrep. + * + * Finds files matching a glob pattern, returned sorted by modification time + * (most recent first). Implemented by shelling out to `rg --files` through the + * host `IHostProcessService` — sharing the ripgrep subprocess plumbing, + * gitignore handling, and sensitive-file filtering with the Grep tool. + * + * Collaborators injected via constructor: + * - `fs` — `IHostFileSystem`, search-root existence/type + * pre-check + * - `env` — `IHostEnvironment`, path class for display + * relativization + * - `processService` — `IHostProcessService`, spawns the rg subprocess + * - `workspaceCtx` — `ISessionWorkspaceContext`, workspace roots for path + * safety and display + * - `telemetry` — `ITelemetryService`, rg fallback outcome tracking + * - `skillCatalog` — `ISessionSkillCatalog` (optional), extends the + * workspace with skill roots + * + * Ported from v1 onto the v2 os domains: + * - Search: v1 `kaos.exec(rgPath, ...)` maps to + * `this.processService.spawn(rgPath, [...], { cwd: searchRoot })`. Pinning + * the subprocess cwd to the search root so `--glob` patterns match paths + * relative to that root. + * - Binary resolution: `ensureRgPath` probes the execution environment for + * a working `rg` (system PATH, then the cached bootstrap binary) so a + * missing `rg` surfaces an actionable message instead of a naked + * `spawn rg ENOENT`. + * - Subprocess plumbing: `runRgOnce` / `shouldRetryRipgrepEagain` own + * spawn, capped draining, abort/timeout, two-phase kill, and the + * single-threaded EAGAIN retry shared with v1's run-rg. + * - Directory pre-check: `fs.stat(searchRoot)` surfaces a missing or + * non-directory root as "does not exist" / "is not a directory" instead of + * a misleading "No matches found" (or, for a file root, rg listing the + * file itself as its own match). + * - Path safety / home expansion / path class: `resolvePathAccessPath` over + * the `hostEnvironment` domain, identical to Read/Write/Edit/Grep. + * + * Behaviour: + * - `.gitignore` / `.ignore` / `.rgignore` are respected by default + * (ripgrep native). Pass `include_ignored` to also surface ignored files + * (e.g. build outputs, `node_modules`). Sensitive files such as `.env` are + * always filtered out (authoritative post-filter via + * {@link isSensitiveFile}). + * - Results are files-only — `rg --files` never lists directories. + * `include_dirs` is accepted but deprecated and ignored. + * - Brace expansion (`*.{ts,tsx}`, `{src,test}/**`) is handled by ripgrep's + * glob engine; the pattern is passed through to a single `--glob`. + * - Match count is capped at `MAX_MATCHES`. Callers are expected to add + * an anchor (extension, subdirectory) when that would not be enough. + * + * Output convention: paths shown to the LLM are relativized to the search + * base only when that base sits inside the primary workspace. External roots + * stay absolute so downstream Read/Edit calls keep targeting the same file. + * + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + import { normalize, resolve } from 'pathe'; import { ensureRgPath, rgUnavailableMessage, type RgProbe } from '#/os/backends/node-local/tools/rgLocator'; @@ -7,13 +68,11 @@ import { runRgOnce, shouldRetryRipgrepEagain, } from '#/os/backends/node-local/tools/runRg'; -import type { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { IHostProcessService } from '#/os/interface/hostProcess'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import { IHostProcessService } from '#/os/interface/hostProcess'; import { unwrapErrorCause } from '#/_base/errors/errors'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { @@ -23,6 +82,7 @@ import { } from '#/tool/toolContract'; import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; import { + extendWorkspaceWithSkillRoots, isWithinDirectory, resolvePathAccessPath, type PathClass, @@ -60,45 +120,42 @@ const SENSITIVE_GLOBS_TO_EXCLUDE: readonly string[] = [ export class GlobTool implements IGlobTool { declare readonly _serviceBrand: undefined; readonly name = 'Glob' as const; + readonly description: string; readonly parameters: Record<string, unknown> = toInputJsonSchema(GlobInputSchema); constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, + @IHostProcessService private readonly processService: IHostProcessService, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @ITelemetryService private readonly telemetry: ITelemetryService, @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, - ) {} - - get description(): string { - return inspectAgentRuntime(this.runtime).environment.pathClass === 'win32' - ? globDescription + WINDOWS_PATH_HINT - : globDescription; + ) { + this.description = + this.env.pathClass === 'win32' ? globDescription + WINDOWS_PATH_HINT : globDescription; } - private workspaceConfig(view: RuntimeWorkspaceView): WorkspaceConfig { - return { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; + private get workspaceConfig(): WorkspaceConfig { + return extendWorkspaceWithSkillRoots( + { + workspaceDir: this.workspaceCtx.workDir, + additionalDirs: this.workspaceCtx.additionalDirs, + }, + this.skillCatalog?.catalog.getSkillRoots() ?? [], + this.env.pathClass, + ); } resolveExecution(args: GlobInput): ToolExecution { - const inspected = inspectAgentRuntime(this.runtime); - const view = new RuntimeWorkspaceView(inspected, { - workDir: this.workspaceCtx.workDir, - additionalDirs: [ - ...this.workspaceCtx.additionalDirs, - ...(this.skillCatalog?.catalog.getSkillRoots() ?? []), - ], - }); - const env = { _serviceBrand: undefined, ...inspected.environment, ready: Promise.resolve() }; - const workspace = this.workspaceConfig(view); let path: string | undefined; if (args.path !== undefined) { path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspaceConfig, operation: 'search', policy: { guardMode: 'absolute-outside-allowed', checkSensitive: false }, }); } - const searchRoots = [path ?? workspace.workspaceDir]; + const searchRoots = [path ?? this.workspaceConfig.workspaceDir]; const detailParts: string[] = [`pattern: ${args.pattern}`]; if (args.path !== undefined) { @@ -119,41 +176,19 @@ export class GlobTool implements IGlobTool { }, approvalRule: literalRulePattern(this.name, args.pattern), matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.pattern), - execute: async ({ signal }) => { - const lease = this.runtime.acquire(['fs', 'process']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution( - lease.runtime.fs!, - lease.runtime.process!, - env, - workspace, - args, - signal, - searchRoots, - ); - } finally { - lease.dispose(); - } - }, + execute: ({ signal }) => this.execution(args, signal, searchRoots), }; } private async execution( - fs: IHostFileSystem, - processService: IHostProcessService, - env: IHostEnvironment, - workspace: WorkspaceConfig, args: GlobInput, signal: AbortSignal, searchRoots: readonly string[], ): Promise<ExecutableToolResult> { - const searchRoot = searchRoots[0] ?? workspace.workspaceDir; + const searchRoot = searchRoots[0] ?? this.workspaceConfig.workspaceDir; try { - const st = await fs.stat(searchRoot); + const st = await this.fs.stat(searchRoot); if (!st.isDirectory) { return { isError: true, output: `${searchRoot} is not a directory` }; } @@ -170,7 +205,7 @@ export class GlobTool implements IGlobTool { let rgPath: string; try { - const resolution = await ensureRgPath(createRgProbe(processService), { + const resolution = await ensureRgPath(createRgProbe(this.processService), { signal, allowCachedFallback: true, }); @@ -191,7 +226,7 @@ export class GlobTool implements IGlobTool { let run; try { - run = await runRgOnce(processService, buildRgArgs(rgPath, args), signal, { cwd: searchRoot }); + run = await runRgOnce(this.processService, buildRgArgs(rgPath, args), signal, { cwd: searchRoot }); } catch (error) { return { isError: true, output: formatSpawnError(error) }; } @@ -201,7 +236,7 @@ export class GlobTool implements IGlobTool { if (shouldRetryRipgrepEagain(run)) { try { - run = await runRgOnce(processService, buildRgArgs(rgPath, args, true), signal, { cwd: searchRoot }); + run = await runRgOnce(this.processService, buildRgArgs(rgPath, args, true), signal, { cwd: searchRoot }); } catch (error) { return { isError: true, output: formatSpawnError(error) }; } @@ -250,8 +285,8 @@ export class GlobTool implements IGlobTool { return { output: 'No matches found' }; } - const pathClass = env.pathClass; - const shouldRelativize = isWithinDirectory(searchRoot, workspace.workspaceDir, pathClass); + const pathClass = this.env.pathClass; + const shouldRelativize = isWithinDirectory(searchRoot, this.workspaceConfig.workspaceDir, pathClass); const displayLines = limited.map((p) => shouldRelativize ? relativizeIfUnder(p, searchRoot, pathClass) : p, ); @@ -285,11 +320,7 @@ export class GlobTool implements IGlobTool { } } -registerAgentToolService(IGlobTool, GlobTool, { - name: 'Glob', - domain: 'os/backends', - requiredRuntimeCapabilities: ['fs', 'process'], -}); +registerAgentToolService(IGlobTool, GlobTool, { name: 'Glob', domain: 'os/backends' }); function createRgProbe(processService: IHostProcessService): RgProbe { return { @@ -305,7 +336,7 @@ function createRgProbe(processService: IHostProcessService): RgProbe { proc.stderr.resume(); const exitCode = await proc.wait(); try { - void proc.dispose(); + proc.dispose(); } catch { } return { exitCode }; diff --git a/packages/agent-core-v2/src/agent/tools/os/grep/grep.ts b/packages/agent-core-v2/src/agent/tools/os/grep/grep.ts index 3941bb12d..e6a08d00c 100644 --- a/packages/agent-core-v2/src/agent/tools/os/grep/grep.ts +++ b/packages/agent-core-v2/src/agent/tools/os/grep/grep.ts @@ -1,3 +1,15 @@ +/** + * `tools` domain — `IGrepTool` contract. + * + * Public contract of Grep, the model's ripgrep-backed content search. Supports + * glob/type filtering, context lines, output modes, pagination, multiline, + * and case-insensitive search. Hidden files are searched, but VCS metadata + * and sensitive files (such as `.env`) are always filtered out. + * + * Owns the `GrepInput` / `GrepOutput` zod schemas and the Agent-scope service + * identifier. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/os/grep/grepTool.ts b/packages/agent-core-v2/src/agent/tools/os/grep/grepTool.ts index 243825b5f..c709326c4 100644 --- a/packages/agent-core-v2/src/agent/tools/os/grep/grepTool.ts +++ b/packages/agent-core-v2/src/agent/tools/os/grep/grepTool.ts @@ -1,3 +1,37 @@ +/** + * `tools` domain — `GrepTool` implementation, content search via ripgrep. + * + * Shells out to `rg` through the host process service. The ripgrep binary + * resolution and subprocess plumbing are shared with the Glob tool. + * + * Collaborators injected via constructor: + * - `processService` — `IHostProcessService`, spawns the rg subprocess + * - `fs` — `IHostFileSystem`, mtime stat used to order + * files_with_matches results (most recent first) + * - `env` — `IHostEnvironment`, path class for display + * relativization + * - `workspaceCtx` — `ISessionWorkspaceContext`, workspace roots for path + * safety and display + * - `telemetry` — `ITelemetryService`, rg fallback outcome tracking + * - `skillCatalog` — `ISessionSkillCatalog` (optional), extends the + * workspace with skill roots + * + * Path safety is enforced before any host I/O. Explicit absolute paths outside + * the workspace are allowed; relative paths that escape the workspace are + * rejected. + * + * Output is bounded and post-processed before it reaches the model: + * - timeout and ambient abort both terminate the rg subprocess; + * - stdout/stderr are capped while streams continue draining; + * - hidden files are searched, but VCS metadata and common sensitive glob + * patterns are prefiltered where possible; + * - parsed path records are filtered again after rg returns, using the active + * backend path class. + * + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + import { normalize } from 'pathe'; import { ToolResultBuilder } from '#/tool/result-builder'; @@ -8,15 +42,14 @@ import { } from '#/tool/toolContract'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; -import type { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { IHostProcessService } from '#/os/interface/hostProcess'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import { IHostProcessService } from '#/os/interface/hostProcess'; import { unwrapErrorCause } from '#/_base/errors/errors'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { + extendWorkspaceWithSkillRoots, resolvePathAccessPath, type PathClass, isSensitiveFile, @@ -68,63 +101,48 @@ export class GrepTool implements IGrepTool { readonly description = GREP_DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(GrepInputSchema); constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostProcessService private readonly processService: IHostProcessService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @ITelemetryService private readonly telemetry: ITelemetryService, @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, ) {} - private workspace(view: RuntimeWorkspaceView): WorkspaceConfig { - return { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; + private get workspace(): WorkspaceConfig { + return extendWorkspaceWithSkillRoots( + { + workspaceDir: this.workspaceCtx.workDir, + additionalDirs: this.workspaceCtx.additionalDirs, + }, + this.skillCatalog?.catalog.getSkillRoots() ?? [], + this.env.pathClass, + ); } resolveExecution(args: GrepInput): ToolExecution { - const inspected = inspectAgentRuntime(this.runtime); - const view = new RuntimeWorkspaceView(inspected, { - workDir: this.workspaceCtx.workDir, - additionalDirs: [ - ...this.workspaceCtx.additionalDirs, - ...(this.skillCatalog?.catalog.getSkillRoots() ?? []), - ], - }); - const env = { _serviceBrand: undefined, ...inspected.environment, ready: Promise.resolve() }; - const workspace = this.workspace(view); let path: string | undefined; if (args.path !== undefined) { path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspace, operation: 'search', policy: { guardMode: 'absolute-outside-allowed', checkSensitive: false }, }); } - const searchPaths = [path ?? workspace.workspaceDir]; - const searchPath = args.path ?? workspace.workspaceDir; + const searchPaths = [path ?? this.workspace.workspaceDir]; + const searchPath = args.path ?? this.workspace.workspaceDir; return { accesses: ToolAccesses.searchTree(searchPaths[0]!), description: `Searching for '${args.pattern}' in ${searchPath}`, display: { kind: 'file_io', operation: 'grep', path: searchPaths[0]! }, approvalRule: literalRulePattern(this.name, args.pattern), matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.pattern), - execute: async ({ signal }) => { - const lease = this.runtime.acquire(['fs', 'process']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution(lease.runtime.process!, lease.runtime.fs!, env, workspace, args, signal, searchPaths); - } finally { - lease.dispose(); - } - }, + execute: ({ signal }) => this.execution(args, signal, searchPaths), }; } private async execution( - processService: IHostProcessService, - fs: IHostFileSystem, - env: IHostEnvironment, - workspace: WorkspaceConfig, args: GrepInput, signal: AbortSignal, searchPaths: string[], @@ -133,10 +151,10 @@ export class GrepTool implements IGrepTool { return { isError: true, output: 'Aborted before search started' }; } - const pathClass = env.pathClass; + const pathClass = this.env.pathClass; let rgPath: string; try { - const resolution = await ensureRgPath(this.createRgProbe(processService), { + const resolution = await ensureRgPath(this.createRgProbe(), { signal, allowCachedFallback: true, }); @@ -158,7 +176,7 @@ export class GrepTool implements IGrepTool { let runResult: RunRgResult; try { const firstRun = await runRgOnce( - processService, + this.processService, buildRgArgs(rgPath, args, searchPaths), signal, ); @@ -169,7 +187,7 @@ export class GrepTool implements IGrepTool { if (shouldRetryRipgrepEagain(runResult)) { const retryRun = await runRgOnce( - processService, + this.processService, buildRgArgs(rgPath, args, searchPaths, true), signal, ); @@ -214,7 +232,7 @@ export class GrepTool implements IGrepTool { try { orderedLines = mode === 'files_with_matches' && !timedOut - ? await this.sortFilesWithMatchesByMtime(fs, keptLines, signal) + ? await this.sortFilesWithMatchesByMtime(keptLines, signal) : keptLines; } catch (error) { if (error instanceof GrepAbortedError) { @@ -234,7 +252,7 @@ export class GrepTool implements IGrepTool { const messages: string[] = []; if (filteredSensitive.size > 0) { const displayedFilteredPaths = [...filteredSensitive].map((path) => - relativizeIfUnder(path, workspace.workspaceDir, pathClass), + relativizeIfUnder(path, this.workspace.workspaceDir, pathClass), ); messages.push( `Filtered ${String(filteredSensitive.size)} sensitive file(s): ${displayedFilteredPaths.join(', ')}`, @@ -269,7 +287,7 @@ export class GrepTool implements IGrepTool { formatDisplayLine( line, mode, - workspace.workspaceDir, + this.workspace.workspaceDir, pathClass, contentIncludesLineNumbers, ), @@ -292,12 +310,12 @@ export class GrepTool implements IGrepTool { return builder.ok(); } - private createRgProbe(processService: IHostProcessService): RgProbe { + private createRgProbe(): RgProbe { return { exec: async (args) => { const [command, ...rest] = args; if (command === undefined) return { exitCode: -1 }; - const proc = await processService.spawn(command, rest); + const proc = await this.processService.spawn(command, rest); try { proc.stdin.end(); } catch { @@ -306,7 +324,7 @@ export class GrepTool implements IGrepTool { proc.stderr.resume(); const exitCode = await proc.wait(); try { - void proc.dispose(); + proc.dispose(); } catch { } return { exitCode }; @@ -315,7 +333,6 @@ export class GrepTool implements IGrepTool { } private async sortFilesWithMatchesByMtime( - fs: IHostFileSystem, lines: readonly ParsedGrepLine[], signal: AbortSignal, ): Promise<ParsedGrepLine[]> { @@ -329,7 +346,7 @@ export class GrepTool implements IGrepTool { let mtime = 0; if (path !== undefined) { try { - const mtimeMs = (await fs.stat(path)).mtimeMs ?? 0; + const mtimeMs = (await this.fs.stat(path)).mtimeMs ?? 0; mtime = Math.trunc(mtimeMs / 1000); } catch { } @@ -342,11 +359,7 @@ export class GrepTool implements IGrepTool { } } -registerAgentToolService(IGrepTool, GrepTool, { - name: 'Grep', - domain: 'os/backends', - requiredRuntimeCapabilities: ['fs', 'process'], -}); +registerAgentToolService(IGrepTool, GrepTool, { name: 'Grep', domain: 'os/backends' }); function formatSpawnError(error: unknown): string { return errorCode(error) === 'ENOENT' diff --git a/packages/agent-core-v2/src/agent/tools/os/read/read.md b/packages/agent-core-v2/src/agent/tools/os/read/read.md index 8597a6647..8cfab273b 100644 --- a/packages/agent-core-v2/src/agent/tools/os/read/read.md +++ b/packages/agent-core-v2/src/agent/tools/os/read/read.md @@ -8,7 +8,7 @@ When you need several files, prefer to read them in parallel: emit multiple `Rea - Returns up to ${MAX_LINES} lines or ${MAX_BYTES_KB} KB per call, whichever comes first; lines longer than ${MAX_LINE_LENGTH} chars are truncated mid-line. - Page larger files with `line_offset` (1-based start line) and `n_lines`. Omit `n_lines` to read up to the ${MAX_LINES}-line cap. - Sensitive files (`.env` files, credential stores, SSH private keys, and similar secrets) are refused to protect secrets; do not attempt to read them. Templates and public keys are exempt: `.env.example` / `.env.sample` / `.env.template` and public SSH keys such as `id_rsa.pub` read normally. -- UTF-8 text files are read directly. UTF-16 LE/BE text files (with or without a BOM) are detected automatically and transcoded to UTF-8 for display; the status block notes the detected encoding, and Edit/Write on such a file still expect UTF-8 — convert its encoding first (e.g. with `iconv`). Other encodings (e.g. GBK), binary files, and files containing NUL bytes are refused. +- UTF-8 text files are read directly. UTF-16 LE/BE text files (with or without a BOM) are detected automatically and transcoded to UTF-8 for display; the status block notes the detected encoding, and Edit/Write on such a file still expect UTF-8 — convert its encoding first (e.g. `iconv` via Bash). Other encodings (e.g. GBK), binary files, and files containing NUL bytes are refused; use `ReadMediaFile` for images or video, and Bash or an MCP tool for other binary formats. - Negative line_offset reads from the end of the file (for example, -100 reads the last 100 lines); the absolute value cannot exceed ${MAX_LINES}. - Output format: `<line-number>\t<content>` per line. - A `<system>...</system>` status block is appended after the file content; it summarizes how much was read (line and byte counts, truncation, line-ending notes) and is not part of the file itself. diff --git a/packages/agent-core-v2/src/agent/tools/os/read/read.ts b/packages/agent-core-v2/src/agent/tools/os/read/read.ts index 881b20182..9f4b1dea5 100644 --- a/packages/agent-core-v2/src/agent/tools/os/read/read.ts +++ b/packages/agent-core-v2/src/agent/tools/os/read/read.ts @@ -1,3 +1,26 @@ +/** + * `tools` domain — `IReadTool` contract. + * + * Public contract of Read, the model's UTF-8 text file reader. Renders a + * text file as `<line-number>\t<content>` per line as `output`, and rides a + * `<system>…</system>` status block on the `note` side channel (rendered to + * the model at projection time, never to UIs) summarizing how much was read + * (line and byte counts, truncation, and line-ending notes). Pure CRLF files + * are displayed with LF line endings; mixed or lone carriage returns are + * shown as `\r` so the model can reproduce them exactly. + * + * UTF-16 LE/BE text files (with a BOM, or recognized via the zero-byte + * parity heuristic) are transparently transcoded to UTF-8 for display, up to + * `TRANSCODE_MAX_BYTES`. Binary, other non-UTF encodings, NUL-containing, + * image and video files are refused; images/videos are redirected to + * ReadMediaFile. Supports one-based + * `line_offset` / `n_lines` pagination and a negative `line_offset` tail + * mode, bounded by the per-call caps owned here (`MAX_LINES`, + * `MAX_LINE_LENGTH`, `MAX_BYTES`). + * + * Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -7,6 +30,11 @@ export const MAX_LINES: number = 1000; export const MAX_LINE_LENGTH: number = 2000; export const MAX_BYTES: number = 100 * 1024; +/** + * Largest file the Read tool transcodes from UTF-16 in memory. Unlike the + * streaming UTF-8 path, transcoding needs the whole file decoded at once; + * 10 MiB mirrors kap-server's `FS_READ_MAX_BYTES`. + */ export const TRANSCODE_MAX_BYTES: number = 10 * 1024 * 1024; const PositiveLineOffsetSchema = z.number().int().min(1); diff --git a/packages/agent-core-v2/src/agent/tools/os/read/readTool.ts b/packages/agent-core-v2/src/agent/tools/os/read/readTool.ts index 6b849fa15..9d4b5ba49 100644 --- a/packages/agent-core-v2/src/agent/tools/os/read/readTool.ts +++ b/packages/agent-core-v2/src/agent/tools/os/read/readTool.ts @@ -1,8 +1,31 @@ -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; +/** + * `tools` domain — `ReadTool` implementation. + * + * Streams the file through `IHostFileSystem.readLines`, enforces the + * line/byte budgets from the contract, normalizes line endings for display + * (pure CRLF shown as LF, mixed or lone carriage returns made visible as + * `\r`), refuses binary / media files up front, and composes the `<system>` + * finish note on the `note` side channel. UTF-16 LE/BE text (with a BOM or + * the zero-byte parity heuristic) is decoded whole via `readBytes` and + * transcoded to UTF-8, bounded by `TRANSCODE_MAX_BYTES`. + * + * Path safety goes through the shared path access resolver used by + * Read/Write/Edit. Read access flows through the os `hostFs` domain + * (`IHostFileSystem`); path semantics (home expansion, path class) come from + * the `hostEnvironment` domain; the workspace and skill roots come from + * `ISessionWorkspaceContext` / `ISessionSkillCatalog`. + * + * Ported from v1. The + * optional `scanTextFile` / `readLineRange` / `readTailLines` fast-paths are + * intentionally dropped: `IHostFileSystem` streams through `readLines` only. + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { unwrapErrorCause } from '#/_base/errors/errors'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { ToolAccesses, @@ -11,6 +34,7 @@ import { } from '#/tool/toolContract'; import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; import { + extendWorkspaceWithSkillRoots, resolvePathAccessPath, type WorkspaceConfig, } from '#/tool/path-access'; @@ -181,14 +205,18 @@ async function* decodedLines(lines: readonly string[]): AsyncGenerator<string> { } function notReadableFileOutput(path: string): string { - return `"${path}" is not readable as UTF-8 text. Only text files can be read.`; + return ( + `"${path}" is not readable as UTF-8 text. ` + + 'If it is an image or video, use ReadMediaFile. ' + + 'For other binary formats, use Bash or an MCP tool if available.' + ); } function notUtf8DecodableFileOutput(path: string): string { return ( `"${path}" is not valid UTF-8 or UTF-16 text. ` + 'Only UTF-8 and UTF-16 text files can be read; ' + - 'for other encodings (e.g. GBK), convert the file to UTF-8 first (e.g. with `iconv`).' + 'for other encodings (e.g. GBK), convert the file to UTF-8 first (e.g. `iconv` via Bash).' ); } @@ -204,26 +232,27 @@ export class ReadTool implements IReadTool { readonly description = READ_DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(ReadInputSchema); constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, - @ISessionSkillCatalog private readonly skillCatalog: ISessionSkillCatalog, + @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, ) {} - private workspaceConfig(view: RuntimeWorkspaceView): WorkspaceConfig { - return { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; + private get workspaceConfig(): WorkspaceConfig { + return extendWorkspaceWithSkillRoots( + { + workspaceDir: this.workspaceCtx.workDir, + additionalDirs: this.workspaceCtx.additionalDirs, + }, + this.skillCatalog?.catalog.getSkillRoots() ?? [], + this.env.pathClass, + ); } resolveExecution(args: ReadInput): ToolExecution { - const inspected = inspectAgentRuntime(this.runtime); - const view = new RuntimeWorkspaceView(inspected, { - workDir: this.workspaceCtx.workDir, - additionalDirs: [...this.workspaceCtx.additionalDirs, ...this.skillCatalog.catalog.getSkillRoots()], - }); - const env = { _serviceBrand: undefined, ...inspected.environment, ready: Promise.resolve() }; - const workspace = this.workspaceConfig(view); const path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspaceConfig, operation: 'read', }); return { @@ -233,29 +262,19 @@ export class ReadTool implements IReadTool { approvalRule: literalRulePattern(this.name, path), matchesRule: (ruleArgs) => matchesPathRuleSubject(ruleArgs, path, { - cwd: workspace.workspaceDir, - pathClass: env.pathClass, - homeDir: env.homeDir, + cwd: this.workspaceConfig.workspaceDir, + pathClass: this.env.pathClass, + homeDir: this.env.homeDir, }), - execute: async () => { - const lease = this.runtime.acquire(['fs']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution(lease.runtime.fs!, args, path); - } finally { - lease.dispose(); - } - }, + execute: () => this.execution(args, path), }; } - private async execution(fs: IHostFileSystem, args: ReadInput, safePath: string): Promise<ExecutableToolResult> { + private async execution(args: ReadInput, safePath: string): Promise<ExecutableToolResult> { try { let stat: Awaited<ReturnType<IHostFileSystem['stat']>>; try { - stat = await fs.stat(safePath); + stat = await this.fs.stat(safePath); } catch (error) { if (isFileNotFoundError(error)) { return { isError: true, output: `"${args.path}" does not exist.` }; @@ -266,29 +285,34 @@ export class ReadTool implements IReadTool { return { isError: true, output: `"${args.path}" is not a file.` }; } - const header = await fs.readBytes(safePath, MEDIA_SNIFF_BYTES); + const header = await this.fs.readBytes(safePath, MEDIA_SNIFF_BYTES); const fileType = detectFileType(safePath, header); if (fileType.kind === 'image' || fileType.kind === 'video') { return { isError: true, - output: `"${args.path}" is ${fileType.kind === 'image' ? 'an' : 'a'} ${fileType.kind} file. Only text files can be read.`, + output: `"${args.path}" is a ${fileType.kind} file. Use ReadMediaFile to read image or video files.`, }; } + // A BOM marks UTF-16 even when the header carries no NUL bytes (e.g. + // CJK-only content reads as printable ASCII), so detect the encoding + // before falling through to the strict UTF-8 text path. const detection = detectTextEncoding(header); let lines: AsyncIterable<string>; let detectedEncoding: UtfTextEncoding | undefined; if (!detection.seemsBinary && detection.encoding !== 'utf-8') { + // UTF-16 LE/BE text (BOM or zero-byte parity heuristic): decode the + // whole file and transcode to UTF-8 for display. if (stat.size > TRANSCODE_MAX_BYTES) { return { isError: true, output: `"${args.path}" is ${encodingDisplayName(detection.encoding)} text but too large to transcode ` + `(${String(stat.size)} bytes > ${String(TRANSCODE_MAX_BYTES)}). ` + - 'Convert it to UTF-8 first (e.g. with `iconv`).', + 'Convert it to UTF-8 first (e.g. `iconv` via Bash).', }; } - const decoded = decodeUtfText(await fs.readBytes(safePath), detection.encoding); + const decoded = decodeUtfText(await this.fs.readBytes(safePath), detection.encoding); detectedEncoding = detection.encoding; lines = decodedLines(splitLinesKeepingTerminator(decoded)); } else if (fileType.kind === 'unknown') { @@ -297,7 +321,7 @@ export class ReadTool implements IReadTool { output: notReadableFileOutput(args.path), }; } else { - lines = fs.readLines(safePath, { errors: 'strict' }); + lines = this.fs.readLines(safePath, { errors: 'strict' }); } const lineOffset = args.line_offset ?? 1; @@ -528,8 +552,4 @@ export class ReadTool implements IReadTool { } } -registerAgentToolService(IReadTool, ReadTool, { - name: 'Read', - domain: 'os/backends', - requiredRuntimeCapabilities: ['fs'], -}); +registerAgentToolService(IReadTool, ReadTool, { name: 'Read', domain: 'os/backends' }); diff --git a/packages/agent-core-v2/src/agent/tools/os/write/write.ts b/packages/agent-core-v2/src/agent/tools/os/write/write.ts index 6c20e0589..5378d35ad 100644 --- a/packages/agent-core-v2/src/agent/tools/os/write/write.ts +++ b/packages/agent-core-v2/src/agent/tools/os/write/write.ts @@ -1,3 +1,18 @@ +/** + * `tools` domain — `IWriteTool` contract. + * + * Public contract of Write, the model's UTF-8 text file writer. Overwrites a + * file entirely or appends content to its end. Creates the file if it does + * not exist, and creates missing parent directories automatically (mirroring + * `mkdir(parents=True, exist_ok=True)`). Path access policy is resolved + * before any filesystem I/O. + * + * Append semantics never read or rewrite existing content, keeping appends + * atomic with respect to concurrent writers and safe against mid-write + * crashes. Owns the `WriteInput` / `WriteOutput` zod schemas and the + * Agent-scope service identifier. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/os/write/writeTool.ts b/packages/agent-core-v2/src/agent/tools/os/write/writeTool.ts index e9cc37ddb..1f166213e 100644 --- a/packages/agent-core-v2/src/agent/tools/os/write/writeTool.ts +++ b/packages/agent-core-v2/src/agent/tools/os/write/writeTool.ts @@ -1,10 +1,29 @@ +/** + * `tools` domain — `WriteTool` implementation. + * + * Resolves path access policy before any filesystem I/O, creates missing + * parent directories (`mkdir(recursive)`), and writes through + * `IHostFileSystem.writeText` / `appendText`. Append uses a native + * `O_APPEND`-style append, so existing content is never read or rewritten — + * keeping appends atomic with respect to concurrent writers and safe against + * mid-write crashes. + * + * Write access flows through the os `hostFs` domain (`IHostFileSystem`); path + * semantics (home expansion, path class) come from the `hostEnvironment` + * domain; the workspace and skill roots come from `ISessionWorkspaceContext` + * / `ISessionSkillCatalog`. + * + * Ported from v1. + * Bound at Agent scope; self-registers via `registerAgentToolService(...)` at module + * load. + */ + import { dirname } from 'pathe'; -import type { HostFileStat, IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IAgentRuntimeService, inspectAgentRuntime } from '#/agent/runtimeBinding/agentRuntime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { type HostFileStat, IHostFileSystem } from '#/os/interface/hostFileSystem'; import { unwrapErrorCause } from '#/_base/errors/errors'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; import { ToolAccesses, @@ -13,6 +32,7 @@ import { } from '#/tool/toolContract'; import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; import { + extendWorkspaceWithSkillRoots, resolvePathAccessPath, type WorkspaceConfig, } from '#/tool/path-access'; @@ -28,29 +48,27 @@ export class WriteTool implements IWriteTool { readonly parameters: Record<string, unknown> = toInputJsonSchema(WriteInputSchema); constructor( - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, + @IHostFileSystem private readonly fs: IHostFileSystem, + @IHostEnvironment private readonly env: IHostEnvironment, @ISessionWorkspaceContext private readonly workspaceCtx: ISessionWorkspaceContext, @ISessionSkillCatalog private readonly skillCatalog?: ISessionSkillCatalog, ) {} - private workspaceConfig(view: RuntimeWorkspaceView): WorkspaceConfig { - return { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; + private get workspaceConfig(): WorkspaceConfig { + return extendWorkspaceWithSkillRoots( + { + workspaceDir: this.workspaceCtx.workDir, + additionalDirs: this.workspaceCtx.additionalDirs, + }, + this.skillCatalog?.catalog.getSkillRoots() ?? [], + this.env.pathClass, + ); } resolveExecution(args: WriteInput): ToolExecution { - const inspected = inspectAgentRuntime(this.runtime); - const view = new RuntimeWorkspaceView(inspected, { - workDir: this.workspaceCtx.workDir, - additionalDirs: [ - ...this.workspaceCtx.additionalDirs, - ...(this.skillCatalog?.catalog.getSkillRoots() ?? []), - ], - }); - const env = { _serviceBrand: undefined, ...inspected.environment, ready: Promise.resolve() }; - const workspace = this.workspaceConfig(view); const path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspaceConfig, operation: 'write', }); return { @@ -60,26 +78,16 @@ export class WriteTool implements IWriteTool { approvalRule: literalRulePattern(this.name, path), matchesRule: (ruleArgs) => matchesPathRuleSubject(ruleArgs, path, { - cwd: workspace.workspaceDir, - pathClass: env.pathClass, - homeDir: env.homeDir, + cwd: this.workspaceConfig.workspaceDir, + pathClass: this.env.pathClass, + homeDir: this.env.homeDir, }), - execute: async () => { - const lease = this.runtime.acquire(['fs']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution(lease.runtime.fs!, args, path); - } finally { - lease.dispose(); - } - }, + execute: () => this.execution(args, path), }; } - private async execution(fs: IHostFileSystem, args: WriteInput, safePath: string): Promise<ExecutableToolResult> { - const parentError = await this.ensureParentDirectory(fs, safePath); + private async execution(args: WriteInput, safePath: string): Promise<ExecutableToolResult> { + const parentError = await this.ensureParentDirectory(safePath); if (parentError !== undefined) { return { isError: true, output: parentError }; } @@ -87,9 +95,9 @@ export class WriteTool implements IWriteTool { try { const mode = args.mode ?? 'overwrite'; if (mode === 'append') { - await fs.appendText(safePath, args.content); + await this.fs.appendText(safePath, args.content); } else { - await fs.writeText(safePath, args.content); + await this.fs.writeText(safePath, args.content); } const bytesWritten = Buffer.byteLength(args.content, 'utf8'); return { @@ -110,15 +118,15 @@ export class WriteTool implements IWriteTool { } } - private async ensureParentDirectory(fs: IHostFileSystem, safePath: string): Promise<string | undefined> { + private async ensureParentDirectory(safePath: string): Promise<string | undefined> { const parent = dirname(safePath); let stat: HostFileStat; try { - stat = await fs.stat(parent); + stat = await this.fs.stat(parent); } catch (error) { if ((unwrapErrorCause(error) as { code?: unknown } | null)?.code === 'ENOENT') { try { - await fs.mkdir(parent, { recursive: true }); + await this.fs.mkdir(parent, { recursive: true }); return undefined; } catch (mkdirError) { return mkdirError instanceof Error ? mkdirError.message : String(mkdirError); @@ -133,8 +141,4 @@ export class WriteTool implements IWriteTool { } } -registerAgentToolService(IWriteTool, WriteTool, { - name: 'Write', - domain: 'os/backends', - requiredRuntimeCapabilities: ['fs'], -}); +registerAgentToolService(IWriteTool, WriteTool, { name: 'Write', domain: 'os/backends' }); diff --git a/packages/agent-core-v2/src/agent/tools/read-media-file/read-media-file.ts b/packages/agent-core-v2/src/agent/tools/read-media-file/read-media-file.ts index 9df67d0e8..1c885f522 100644 --- a/packages/agent-core-v2/src/agent/tools/read-media-file/read-media-file.ts +++ b/packages/agent-core-v2/src/agent/tools/read-media-file/read-media-file.ts @@ -1,3 +1,13 @@ +/** + * `tools` domain — `ReadMediaFileTool` contract. + * + * Public contract of the `ReadMediaFile` tool: the input zod schema the + * model-facing parameters are derived from, the tool-owned size constants, + * and the `VideoUploader` channel type for the provider's upload hook. This + * tool has no DI decorator — it is a deliberate exception to the + * `registerAgentToolService` contribution table. + */ + import { z } from 'zod'; import type { VideoURLPart } from '#/kosong/contract/message'; @@ -13,6 +23,7 @@ export type VideoUploader = ( options?: { readonly signal?: AbortSignal }, ) => Promise<VideoURLPart>; + export const ReadMediaFileInputSchema = z.object({ path: z .string() diff --git a/packages/agent-core-v2/src/agent/tools/read-media-file/readMediaFileTool.ts b/packages/agent-core-v2/src/agent/tools/read-media-file/readMediaFileTool.ts index cbb7e00e0..b7fee3211 100644 --- a/packages/agent-core-v2/src/agent/tools/read-media-file/readMediaFileTool.ts +++ b/packages/agent-core-v2/src/agent/tools/read-media-file/readMediaFileTool.ts @@ -1,13 +1,67 @@ +/** + * `tools` domain — `ReadMediaFileTool` implementation. + * + * Reads image/video files as multi-modal content. + * + * Returns a 3-part wrap as `output`: + * `[TextPart('<image|video path="…">'), ImageContent|VideoContent, + * TextPart('</image|video>')]` + * plus a `note` side channel (rendered to the model, never to UIs), and + * adapts its description and per-call behavior to the model's + * `image_in` / `video_in` capability. + * + * The note — this tool wraps it in a `<system>` block as its own wording + * choice — summarizes mime type, byte size and (for images) original pixel + * dimensions, states exactly how the image was delivered (untouched, + * downsampled, cropped, or native resolution) so compression is never + * silent, guides the model to derive absolute coordinates from the original + * size, and reminds it to re-read any media it generates or edits. + * + * Images support two opt-in delivery controls: `region` cuts a rectangle + * (original-image pixel coordinates) out of the file so fine detail survives + * at full fidelity, and `full_resolution` skips the default downscale when + * the payload fits the per-image byte budget (refusing explicitly when it + * does not, instead of silently degrading). Explicit region/native reads + * refuse before loading a source that exceeds the safe decode allocation. + * Default image reads also fail closed when compression cannot meet the + * configured byte and longest-edge delivery budgets: the original bytes are + * not emitted, and the tool result tells the model to create and re-read a + * smaller copy. + * + * Path safety: goes through the shared path access resolver used by + * Read/Write/Edit. + * + * Videos are delivered through the provider's upload channel when one is + * bound, falling back to an inline base64 part when the channel exists but + * fails at runtime (no files endpoint, network/server failure) — a failed + * upload must not turn the whole read into an error. The same fallback + * covers providers with no upload hook at all, as long as their protocol + * converts `video_url` (`inlineVideoSupported`, computed from the model's + * protocol at registration); when the wire would drop the inline payload + * anyway (the OpenAI family), the by-design no-hook error + * (`VideoUploadUnsupportedError`) surfaces instead. Auth rejections + * (`provider.auth_error` / 401 / 403) always surface, because they drive + * credential refresh rather than mask a bad token. + * + * Registration is capability-gated: this tool is + * only registered when the active model supports image or video input. + * + * This tool is a deliberate exception to the `registerAgentToolService` contribution + * table: its constructor depends on runtime model capabilities (capability + * profile, video uploader, protocol flags), so it cannot be a static + * Agent-scope Service and is instead instantiated + * whenever the bound model changes. It still satisfies the `AgentTool` + * contract. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { ContentPart } from '#/kosong/contract/message'; import { VideoUploadUnsupportedError } from '#/kosong/contract/errors'; import { inlineVideoPart, isVideoUploadAuthError } from '#/agent/media/videoUpload'; import type { ITelemetryService } from '#/app/telemetry/telemetry'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; -import type { HostEnvironmentInfo } from '#/os/interface/hostEnvironment'; -import { inspectAgentRuntime, type IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; +import { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { ToolAccesses, type AgentTool, @@ -47,6 +101,7 @@ import { } from './read-media-file'; import readMediaDescriptionHead from './read-media.md?raw'; + function buildDescription(capabilities: ModelCapability): string { const head = renderPrompt(readMediaDescriptionHead, { MAX_MEDIA_MEGABYTES }); const lines: string[] = [head]; @@ -70,6 +125,7 @@ function buildDescription(capabilities: ModelCapability): string { return lines.join('\n'); } + interface ImageDelivery { readonly kind: 'untouched' | 'downsampled' | 'crop' | 'full'; readonly width: number; @@ -180,7 +236,8 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { private readonly compressTelemetry: ImageCompressionTelemetry | undefined; private readonly inlineVideoSupported: boolean; constructor( - private readonly runtime: IAgentRuntimeService, + private readonly fs: IHostFileSystem, + private readonly env: IHostEnvironment, private readonly workspace: WorkspaceConfig, private readonly capabilities: ModelCapability, private readonly videoUploader?: VideoUploader, @@ -216,16 +273,9 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { if (!args.path) { return { isError: true, output: 'File path cannot be empty.' }; } - const inspected = inspectAgentRuntime(this.runtime); - const env = inspected.environment; - const view = new RuntimeWorkspaceView(inspected, { - workDir: this.workspace.workspaceDir, - additionalDirs: this.workspace.additionalDirs, - }); - const workspace = { workspaceDir: view.workDir, additionalDirs: view.additionalDirs }; const path = resolvePathAccessPath(args.path, { - env, - workspace, + env: this.env, + workspace: this.workspace, operation: 'read', }); return { @@ -236,35 +286,23 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { matchesRule: (ruleArgs) => matchesPathRuleSubject(ruleArgs, path, { cwd: this.workspace.workspaceDir, - pathClass: env.pathClass, - homeDir: env.homeDir, + pathClass: this.env.pathClass, + homeDir: this.env.homeDir, }), - execute: async () => { - const lease = this.runtime.acquire(['fs']); - try { - if (lease.runtime.identity.generation !== inspected.identity.generation) { - return { isError: true, output: 'Runtime changed before execution. Retry the tool call.' }; - } - return await this.execution(args, path, lease.runtime.fs!, env); - } finally { - lease.dispose(); - } - }, + execute: () => this.execution(args, path), }; } private async execution( args: ReadMediaFileInput, safePath: string, - fs: IHostFileSystem, - env: HostEnvironmentInfo, ): Promise<ExecutableToolResult> { if (!args.path) { return { isError: true, output: 'File path cannot be empty.' }; } try { - const header = await fs.readBytes(safePath, MEDIA_SNIFF_BYTES); + const header = await this.fs.readBytes(safePath, MEDIA_SNIFF_BYTES); const fileType = detectFileType(safePath, header, 'media'); if (fileType.kind === 'text') { @@ -293,7 +331,7 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { if (fileType.kind === 'image' && !isModelAcceptedImageMime(fileType.mimeType)) { return { isError: true, - output: buildImageConversionGuidance(args.path, fileType.mimeType, env.osKind), + output: buildImageConversionGuidance(args.path, fileType.mimeType, this.env.osKind), }; } if (fileType.kind === 'video' && !this.capabilities.video_in) { @@ -305,7 +343,7 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { }; } - const stat = await fs.stat(safePath); + const stat = await this.fs.stat(safePath); if (stat.size === 0) { return { isError: true, output: `"${args.path}" is empty.` }; } @@ -368,7 +406,7 @@ export class ReadMediaFileTool implements AgentTool<ReadMediaFileInput> { }; } - const data = Buffer.from(await fs.readBytes(safePath)); + const data = Buffer.from(await this.fs.readBytes(safePath)); let dimensions = fileType.kind === 'image' ? sniffImageDimensions(data) : null; let mediaPart: ContentPart; let delivery: ImageDelivery | undefined; diff --git a/packages/agent-core-v2/src/agent/tools/select-tools/select-tools.ts b/packages/agent-core-v2/src/agent/tools/select-tools/select-tools.ts index ad8610c23..fb0221e01 100644 --- a/packages/agent-core-v2/src/agent/tools/select-tools/select-tools.ts +++ b/packages/agent-core-v2/src/agent/tools/select-tools/select-tools.ts @@ -1,3 +1,12 @@ +/** + * `tools` domain — `ISelectToolsTool` contract (the `select_tools` tool). + * + * Public contract of `select_tools`, the load-by-exact-name primitive of + * progressive tool disclosure: the model-facing `SelectToolsInputSchema` / + * `SelectToolsInput` and the `ISelectToolsTool` DI decorator. Bound at + * Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/agent/tools/select-tools/selectToolsTool.ts b/packages/agent-core-v2/src/agent/tools/select-tools/selectToolsTool.ts index c12ce617f..568b0db3c 100644 --- a/packages/agent-core-v2/src/agent/tools/select-tools/selectToolsTool.ts +++ b/packages/agent-core-v2/src/agent/tools/select-tools/selectToolsTool.ts @@ -1,3 +1,17 @@ +/** + * `tools` domain — `SelectToolsTool` implementation (the `select_tools` + * tool). + * + * The built-in tool that lets the model load dynamic schemas named in + * loadable-tools announcements. Delegates loading to + * `IAgentToolSelectService` (`toolSelect` domain); offered by the shaped tool + * view only while the disclosure gate is open. + * + * Registered via the module-level `registerAgentToolService(ISelectToolsTool, + * SelectToolsTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import type { ToolExecution } from '#/tool/toolContract'; import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; diff --git a/packages/agent-core-v2/src/features/skill/tools/skill.md b/packages/agent-core-v2/src/agent/tools/skill/skill.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/tools/skill.md rename to packages/agent-core-v2/src/agent/tools/skill/skill.md diff --git a/packages/agent-core-v2/src/features/skill/tools/skill.ts b/packages/agent-core-v2/src/agent/tools/skill/skill.ts similarity index 75% rename from packages/agent-core-v2/src/features/skill/tools/skill.ts rename to packages/agent-core-v2/src/agent/tools/skill/skill.ts index c844b3b0e..6dfaa2bd6 100644 --- a/packages/agent-core-v2/src/features/skill/tools/skill.ts +++ b/packages/agent-core-v2/src/agent/tools/skill/skill.ts @@ -1,3 +1,15 @@ +/** + * `tools` domain — `ISkillTool` contract (the `Skill` tool). + * + * Public contract of the `Skill` collaboration tool that lets the LLM + * proactively invoke an inline registered skill: the model-facing + * `SkillToolInputSchema` / `SkillToolInput`, the tool-owned anti-loop + * constants — `MAX_SKILL_QUERY_DEPTH` caps Skill→Skill recursion so a skill + * that re-invokes itself (or chains into another) cannot recurse without + * bound, and `NestedSkillTooDeepError` is raised when a chain exceeds it — + * and the `ISkillTool` DI decorator. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/skill/tools/skillTool.ts b/packages/agent-core-v2/src/agent/tools/skill/skillTool.ts similarity index 70% rename from packages/agent-core-v2/src/features/skill/tools/skillTool.ts rename to packages/agent-core-v2/src/agent/tools/skill/skillTool.ts index f2feca02d..fd11e9f3c 100644 --- a/packages/agent-core-v2/src/features/skill/tools/skillTool.ts +++ b/packages/agent-core-v2/src/agent/tools/skill/skillTool.ts @@ -1,13 +1,32 @@ +/** + * `tools` domain — `SkillTool` implementation (the `Skill` tool). + * + * The model-facing wrapping lives here on purpose: resolving the skill from + * the catalog, the inline-only / `disableModelInvocation` gates, the `isError` + * tool result, and the declared `delivery: 'steer'` into the *current* turn all + * assume the caller is already inside a turn — which is exactly the edge a + * tool runs at. The tool only declares the `delivery`; the agent layer + * performs the actual steer, so the tool never reaches into + * `IAgentPromptService`. `IAgentSkillService` keeps only the user-slash + * `activate` primitive (it opens a fresh turn) and the shared activation + * recording. `executeModelSkill` is the exported execution body behind + * `SkillTool.execution`. + * + * Registered via the module-level `registerAgentToolService(ISkillTool, SkillTool)` + * at the bottom of this file — the same "import = register" pattern used by + * every agent tool. Collaborators: `ISessionSkillCatalog`, + * `IAgentSkillService`, `ISessionContext`. Bound at Agent scope. + */ + import { randomUUID } from 'node:crypto'; import type { SkillActivationOrigin } from '#/agent/contextMemory/types'; -import { renderModelToolSkillPrompt } from '#/features/skill/prompt'; -import { AgentSkill, type SkillRuntime } from '#/features/skill/skillAgentRuntime'; +import { IAgentSkillService } from '#/agent/skill/skill'; +import { renderModelToolSkillPrompt } from '#/agent/skill/prompt'; import type { ExecutableToolResult, ToolDeliveryMessage, ToolExecution } from '#/tool/toolContract'; -import { isInlineSkillType } from '#/features/skill/catalog/types'; -import { ISessionSkillCatalog } from '#/features/skill/session/skillCatalog'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; +import { isInlineSkillType } from '#/app/skillCatalog/types'; +import { ISessionSkillCatalog } from '#/session/sessionSkillCatalog/skillCatalog'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { renderPrompt } from '#/_base/utils/render-prompt'; import { toInputJsonSchema } from '#/tool/input-schema'; @@ -32,16 +51,11 @@ export class SkillTool implements ISkillTool { private queryDepth: number = 0; - private readonly skill: SkillRuntime; - constructor( @ISessionSkillCatalog private readonly catalog: ISessionSkillCatalog, - @IAgentLifecycleService private readonly manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scope: IAgentScopeContext, + @IAgentSkillService private readonly skill: IAgentSkillService, @ISessionContext private readonly sessionContext: ISessionContext, - ) { - this.skill = manager.resolve(scope.agentContext, AgentSkill); - } + ) {} resolveExecution(args: SkillToolInput): ToolExecution { return { @@ -54,7 +68,7 @@ export class SkillTool implements ISkillTool { } withInitialQueryDepth(initialQueryDepth: number): SkillTool { - const clone = new SkillTool(this.catalog, this.manager, this.scope, this.sessionContext); + const clone = new SkillTool(this.catalog, this.skill, this.sessionContext); clone.queryDepth = initialQueryDepth; return clone; } @@ -70,9 +84,11 @@ export class SkillTool implements ISkillTool { } } +registerAgentToolService(ISkillTool, SkillTool, { name: 'Skill', domain: 'skill' }); + export async function executeModelSkill( catalog: ISessionSkillCatalog, - skillService: SkillRuntime, + skillService: IAgentSkillService, args: SkillToolInput, queryDepth: number, sessionId: string, diff --git a/packages/agent-core-v2/src/agent/tools/task/task-list/task-list.ts b/packages/agent-core-v2/src/agent/tools/task/task-list/task-list.ts index d70560e8b..6d0cfc054 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-list/task-list.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-list/task-list.ts @@ -1,3 +1,11 @@ +/** + * `tools` domain — `ITaskListTool` contract (the `TaskList` tool). + * + * Public contract of the `TaskList` tool (list background tasks): the input + * zod schema the model-facing parameters are derived from and the + * `ITaskListTool` DI decorator. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -21,5 +29,6 @@ export const TaskListInputSchema = z.object({ export type TaskListInput = z.infer<typeof TaskListInputSchema>; + export interface ITaskListTool extends AgentTool<TaskListInput> { readonly _serviceBrand: undefined } export const ITaskListTool = createDecorator<ITaskListTool>('taskListTool'); diff --git a/packages/agent-core-v2/src/agent/tools/task/task-list/taskListTool.ts b/packages/agent-core-v2/src/agent/tools/task/task-list/taskListTool.ts index fd2a6e841..7d41c6cc6 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-list/taskListTool.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-list/taskListTool.ts @@ -1,3 +1,14 @@ +/** + * `tools` domain — `TaskListTool` implementation (the `TaskList` tool). + * + * Reads the agent's background tasks from `IAgentTaskService` (`agentTask` + * domain) and renders them as a plain `key: value` list. + * + * Registered via the module-level `registerAgentToolService(ITaskListTool, + * TaskListTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { matchesGlobRuleSubject } from '#/tool/rule-match'; import { type ToolExecution } from '#/tool/toolContract'; @@ -9,6 +20,7 @@ import { formatPlainObject } from '#/agent/task/tools/format'; import { ITaskListTool, TaskListInputSchema, type TaskListInput } from './task-list'; import TASK_LIST_DESCRIPTION from './task-list.md?raw'; + export function formatTaskList(tasks: readonly AgentTaskInfo[], activeOnly: boolean): string { const label = activeOnly ? 'active_background_tasks' : 'background_tasks'; const header = `${label}: ${String(tasks.length)}`; diff --git a/packages/agent-core-v2/src/agent/tools/task/task-output/task-output.ts b/packages/agent-core-v2/src/agent/tools/task/task-output/task-output.ts index ae6784936..e491b87b2 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-output/task-output.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-output/task-output.ts @@ -1,3 +1,11 @@ +/** + * `tools` domain — `ITaskOutputTool` contract (the `TaskOutput` tool). + * + * Public contract of the `TaskOutput` tool (read output from a managed + * task): the input zod schema the model-facing parameters are derived from + * and the `ITaskOutputTool` DI decorator. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -9,5 +17,6 @@ export const TaskOutputInputSchema = z.object({ export type TaskOutputInput = z.infer<typeof TaskOutputInputSchema>; + export interface ITaskOutputTool extends AgentTool<TaskOutputInput> { readonly _serviceBrand: undefined } export const ITaskOutputTool = createDecorator<ITaskOutputTool>('taskOutputTool'); diff --git a/packages/agent-core-v2/src/agent/tools/task/task-output/taskOutputTool.ts b/packages/agent-core-v2/src/agent/tools/task/task-output/taskOutputTool.ts index ebf691ff4..a1c729847 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-output/taskOutputTool.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-output/taskOutputTool.ts @@ -1,3 +1,22 @@ +/** + * `tools` domain — `TaskOutputTool` implementation (the `TaskOutput` + * tool). + * + * Returns structured task metadata plus a fixed-size tail preview of the + * task's output, read through `IAgentTaskService` (`agentTask` domain). The + * full, never-truncated output lives on disk at `output_path`; the caller is + * always pointed at the `Read` tool to page through the complete log, and + * the preview also carries a banner when it has been truncated to a tail. + * + * For terminal tasks the output also surfaces why the task ended: + * `stop_reason` records the concrete reason; `terminal_reason` classifies + * timeout vs. explicit stop vs. failure for callers that need stable labels. + * + * Registered via the module-level `registerAgentToolService(ITaskOutputTool, + * TaskOutputTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { matchesGlobRuleSubject } from '#/tool/rule-match'; import { type ExecutableToolResult, type ToolExecution } from '#/tool/toolContract'; @@ -17,6 +36,7 @@ const OUTPUT_PREVIEW_BYTES = 32 * 1024; const PAGING_HINT_LINES = 300; + function retrievalStatus(status: AgentTaskStatus): 'success' | 'not_ready' { return TERMINAL_STATUSES.has(status) ? 'success' : 'not_ready'; } diff --git a/packages/agent-core-v2/src/agent/tools/task/task-stop/task-stop.ts b/packages/agent-core-v2/src/agent/tools/task/task-stop/task-stop.ts index e153deb02..5fce17e06 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-stop/task-stop.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-stop/task-stop.ts @@ -1,3 +1,11 @@ +/** + * `tools` domain — `ITaskStopTool` contract (the `TaskStop` tool). + * + * Public contract of the `TaskStop` tool (stop a running task): the input + * zod schema the model-facing parameters are derived from and the + * `ITaskStopTool` DI decorator. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -14,5 +22,6 @@ export const TaskStopInputSchema = z.object({ export type TaskStopInput = z.infer<typeof TaskStopInputSchema>; + export interface ITaskStopTool extends AgentTool<TaskStopInput> { readonly _serviceBrand: undefined } export const ITaskStopTool = createDecorator<ITaskStopTool>('taskStopTool'); diff --git a/packages/agent-core-v2/src/agent/tools/task/task-stop/taskStopTool.ts b/packages/agent-core-v2/src/agent/tools/task/task-stop/taskStopTool.ts index 40f873c65..1c61e8c1c 100644 --- a/packages/agent-core-v2/src/agent/tools/task/task-stop/taskStopTool.ts +++ b/packages/agent-core-v2/src/agent/tools/task/task-stop/taskStopTool.ts @@ -1,3 +1,16 @@ +/** + * `tools` domain — `TaskStopTool` implementation (the `TaskStop` tool). + * + * Stops a running background task through `IAgentTaskService` + * (`agentTask` domain): terminal tasks report their recorded stop reason + * untouched; live tasks are stopped after suppressing the terminal + * notification, so the tool result is the only answer the agent sees. + * + * Registered via the module-level `registerAgentToolService(ITaskStopTool, + * TaskStopTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { matchesGlobRuleSubject } from '#/tool/rule-match'; import { type ToolExecution } from '#/tool/toolContract'; @@ -8,6 +21,7 @@ import { TERMINAL_STATUSES } from '#/agent/task/types'; import { ITaskStopTool, TaskStopInputSchema, type TaskStopInput } from './task-stop'; import TASK_STOP_DESCRIPTION from './task-stop.md?raw'; + export class TaskStopTool implements ITaskStopTool { declare readonly _serviceBrand: undefined; readonly name = 'TaskStop' as const; diff --git a/packages/agent-core-v2/src/agent/tools/task/task-wait/flag.ts b/packages/agent-core-v2/src/agent/tools/task/task-wait/flag.ts deleted file mode 100644 index dd42774b7..000000000 --- a/packages/agent-core-v2/src/agent/tools/task/task-wait/flag.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; - -export const WAIT_FOR_FLAG_ID = 'wait_for'; -export const WAIT_FOR_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_WAIT_FOR'; - -export const waitForFlag: FlagDefinitionInput = { - id: WAIT_FOR_FLAG_ID, - title: 'WaitFor tool', - description: - 'Give the model the WaitFor tool so it can wait for background tasks inside the current turn instead of ending the turn and being re-invoked.', - env: WAIT_FOR_FLAG_ENV, - default: true, - surface: 'core', -}; - -registerFlagDefinition(waitForFlag); diff --git a/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.md b/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.md deleted file mode 100644 index 30ebbc8fa..000000000 --- a/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.md +++ /dev/null @@ -1,16 +0,0 @@ -Wait for background tasks to finish without ending the current turn. - -Use this when your next step depends on the result of a running background task (a sub-agent, a background bash command, or a background AskUserQuestion). The call suspends inside the current turn until the task finishes or the timeout elapses, then returns the outcome so you can keep working in the same turn. While waiting, no LLM requests are made. - -Guidelines: - -- Do not call WaitFor right after dispatching work whose result you do not need yet — finished background tasks notify you automatically. WaitFor is for the moment you genuinely cannot proceed without a result. -- `timeout` is required, in seconds, capped at 600. To wait longer, call WaitFor again; waking up periodically also lets you re-evaluate the situation. -- A timeout is not an error: the result lists the tasks that are still running, and you decide whether to wait again or do other work meanwhile. -- Without `task_id`, the wait ends as soon as any background task that was running at call time finishes. Tasks started during the wait are not covered by it; their completion arrives via the usual automatic notification. -- With `task_id`, the wait ends when that task finishes. An unknown `task_id` is an error; a task that has already finished returns immediately. -- When no background tasks are running, WaitFor returns immediately without waiting. -- When the wait ends because a task finished, the result also lists other tasks that finished during the wait window, so failures surface with context. -- Waiting has no side effects on the waited tasks: WaitFor never stops a task, and interrupting the wait (for example, a user interruption) leaves every task running. -- A finished task's result is delivered exactly once: tasks reported by WaitFor do not also produce an automatic completion notification. -- You can only wait for background tasks started by this agent; task IDs belonging to other agents are unknown here. diff --git a/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.ts b/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.ts deleted file mode 100644 index 69b001414..000000000 --- a/packages/agent-core-v2/src/agent/tools/task/task-wait/task-wait.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; -import { DEFAULT_BACKGROUND_TIMEOUT_S } from '#/agent/tools/os/bash/bash'; - -export const WAIT_FOR_MAX_TIMEOUT_S = DEFAULT_BACKGROUND_TIMEOUT_S; - -export const WaitForInputSchema = z.object({ - timeout: z - .number() - .int() - .positive() - .max(WAIT_FOR_MAX_TIMEOUT_S) - .describe( - `Maximum time to wait, in seconds (1-${String(WAIT_FOR_MAX_TIMEOUT_S)}). A timeout is not an error: the tool returns the tasks that are still running, and you can call it again to keep waiting.`, - ), - task_id: z - .string() - .optional() - .describe( - 'The background task ID to wait for. When omitted, the wait ends as soon as any background task that was running at call time finishes.', - ), -}); - -export type WaitForInput = z.infer<typeof WaitForInputSchema>; - -export interface IWaitForTool extends AgentTool<WaitForInput> { readonly _serviceBrand: undefined } -export const IWaitForTool = createDecorator<IWaitForTool>('waitForTool'); diff --git a/packages/agent-core-v2/src/agent/tools/task/task-wait/taskWaitTool.ts b/packages/agent-core-v2/src/agent/tools/task/task-wait/taskWaitTool.ts deleted file mode 100644 index 498054b24..000000000 --- a/packages/agent-core-v2/src/agent/tools/task/task-wait/taskWaitTool.ts +++ /dev/null @@ -1,338 +0,0 @@ -import { toInputJsonSchema } from '#/tool/input-schema'; -import { matchesGlobRuleSubject } from '#/tool/rule-match'; -import { - type ExecutableToolContext, - type ExecutableToolResult, - type ToolExecution, - type ToolUpdate, -} from '#/tool/toolContract'; -import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; - -import { IAgentTaskService } from '#/agent/task/task'; -import type { AgentTaskInfo, AgentTaskOutputSnapshot } from '#/agent/task/task'; -import { TERMINAL_STATUSES } from '#/agent/task/types'; -import { formatPlainObject } from '#/agent/task/tools/format'; -import { formatTaskList } from '#/agent/tools/task/task-list/taskListTool'; -import { IFlagService } from '#/app/flag/flag'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { abortError, linkAbortSignal } from '#/_base/utils/abort'; -import { WAIT_FOR_FLAG_ID } from './flag'; -import { IWaitForTool, WaitForInputSchema, type WaitForInput } from './task-wait'; -import WAIT_FOR_DESCRIPTION from './task-wait.md?raw'; - -const OUTPUT_PREVIEW_BYTES = 32 * 1024; - -const PAGING_HINT_LINES = 300; - -const PROGRESS_INTERVAL_MS = 1_000; - -type WaitForOutcome = 'completed' | 'timed_out' | 'task_not_found' | 'aborted'; - -function terminalReason(info: AgentTaskInfo): 'timed_out' | 'stopped' | 'failed' | undefined { - if (info.status === 'timed_out') return 'timed_out'; - if (info.status === 'killed' && info.stopReason !== undefined) return 'stopped'; - if (info.status === 'failed' && info.stopReason !== undefined) return 'failed'; - return undefined; -} - -function fullOutputHint(output: AgentTaskOutputSnapshot): string | undefined { - if (!output.fullOutputAvailable || output.outputPath === undefined) return undefined; - if (output.truncated) { - return ( - `Only the last ${String(OUTPUT_PREVIEW_BYTES)} bytes are shown above. ` + - 'Use the Read tool with the output_path to page through the full log ' + - `(parameters: path, line_offset, n_lines; read about ${String(PAGING_HINT_LINES)} ` + - 'lines per page).' - ); - } - return ( - 'The preview above is the complete output. Use the Read tool with the output_path ' + - 'if you need to re-read the full log later ' + - `(parameters: path, line_offset, n_lines; read about ${String(PAGING_HINT_LINES)} ` + - 'lines per page).' - ); -} - -export function waitForProgressUpdate( - args: WaitForInput, - runningCount: number, - startedAt: number, - now: number, -): ToolUpdate { - const elapsedS = Math.max(0, Math.round((now - startedAt) / 1000)); - return { - kind: 'status', - text: - `Waiting ${formatWaitSeconds(elapsedS)} / ${formatWaitSeconds(args.timeout)} · ` + - `${String(runningCount)} background task${runningCount === 1 ? '' : 's'} still running`, - replace: true, - }; -} - -function formatWaitSeconds(totalSeconds: number): string { - if (totalSeconds < 60) return `${String(totalSeconds)}s`; - const minutes = Math.floor(totalSeconds / 60); - const seconds = totalSeconds % 60; - if (minutes < 60) { - return seconds === 0 - ? `${String(minutes)}m` - : `${String(minutes)}m ${seconds.toString().padStart(2, '0')}s`; - } - const hours = Math.floor(minutes / 60); - const remainingMinutes = minutes % 60; - return remainingMinutes === 0 - ? `${String(hours)}h` - : `${String(hours)}h ${remainingMinutes.toString().padStart(2, '0')}m`; -} - -export interface WaitForProgressHandle { - readonly stop: () => void; - readonly tick: () => void; -} - -export function startWaitProgress( - args: WaitForInput, - tasks: Pick<IAgentTaskService, 'list'>, - onUpdate: ((update: ToolUpdate) => void) | undefined, - startedAt: number, -): WaitForProgressHandle { - if (onUpdate === undefined) return { stop: () => {}, tick: () => {} }; - const tick = (): void => { - onUpdate(waitForProgressUpdate(args, tasks.list(true).length, startedAt, Date.now())); - }; - tick(); - const interval = setInterval(tick, PROGRESS_INTERVAL_MS); - interval.unref?.(); - return { - stop: () => { - clearInterval(interval); - }, - tick, - }; -} - -export class WaitForTool implements IWaitForTool { - declare readonly _serviceBrand: undefined; - readonly name = 'WaitFor' as const; - readonly description: string = WAIT_FOR_DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(WaitForInputSchema); - - constructor( - @IAgentTaskService private readonly tasks: IAgentTaskService, - @ITelemetryService private readonly telemetry: ITelemetryService, - @IFlagService private readonly flags: IFlagService, - ) {} - - resolveExecution(args: WaitForInput): ToolExecution { - return { - description: - args.task_id === undefined - ? `Waiting up to ${String(args.timeout)}s for any background task` - : `Waiting up to ${String(args.timeout)}s for task ${args.task_id}`, - approvalRule: this.name, - matchesRule: (ruleArgs) => matchesGlobRuleSubject(ruleArgs, args.task_id ?? 'any'), - execute: (ctx) => this.execute(args, ctx), - }; - } - - private async execute( - args: WaitForInput, - ctx: ExecutableToolContext, - ): Promise<ExecutableToolResult> { - if (!this.flags.enabled(WAIT_FOR_FLAG_ID)) { - return { - isError: true, - output: 'WaitFor is disabled: the wait_for experimental flag is off.', - }; - } - const startedAt = Date.now(); - const timeoutMs = args.timeout * 1000; - const runningAtStart = this.tasks.list(true); - - if (args.task_id === undefined) { - if (runningAtStart.length === 0) { - this.track(args, startedAt, timeoutMs, 'completed', 0); - return { - output: [ - formatPlainObject({ waitStatus: 'no_tasks', waitedMs: 0, timeoutMs }), - 'No background tasks are running, so there is nothing to wait for. Finished tasks report back via automatic notification.', - ].join('\n\n'), - isError: false, - }; - } - } else if (this.tasks.getTask(args.task_id) === undefined) { - this.track(args, startedAt, timeoutMs, 'task_not_found', 0); - return { isError: true, output: `Task not found: ${args.task_id}` }; - } - - let waited: AgentTaskInfo | undefined; - const progress = startWaitProgress(args, this.tasks, ctx.onUpdate, startedAt); - try { - waited = - args.task_id === undefined - ? await this.waitAny(runningAtStart, timeoutMs, ctx.signal) - : await this.tasks.wait(args.task_id, timeoutMs, ctx.signal); - } catch (error) { - this.track(args, startedAt, timeoutMs, 'aborted', 0); - throw error; - } finally { - progress.stop(); - } - - if (waited === undefined) { - this.track(args, startedAt, timeoutMs, 'task_not_found', 0); - return { isError: true, output: `Task not found: ${args.task_id ?? ''}` }; - } - - if (!TERMINAL_STATUSES.has(waited.status)) { - this.track(args, startedAt, timeoutMs, 'timed_out', 0); - return { output: this.formatTimeout(args, startedAt, timeoutMs), isError: false }; - } - - const extras = this.collectExtras(runningAtStart, waited.taskId); - const output = await this.formatCompleted(waited, extras, startedAt, timeoutMs); - this.tasks.markTasksDeliveredViaWait( - [waited, ...extras].map((info) => ({ taskId: info.taskId, status: info.status })), - ); - this.track(args, startedAt, timeoutMs, 'completed', extras.length); - return { output, isError: false }; - } - - private async waitAny( - running: readonly AgentTaskInfo[], - timeoutMs: number, - signal: AbortSignal, - ): Promise<AgentTaskInfo | undefined> { - const controller = new AbortController(); - const unlink = linkAbortSignal(signal, controller); - try { - const outcomes = running.map((task) => - this.tasks.wait(task.taskId, timeoutMs, controller.signal).then( - (info) => ({ info, error: undefined }), - (error: unknown) => ({ - info: undefined, - error: error instanceof Error ? error : new Error(String(error)), - }), - ), - ); - const first = await Promise.race(outcomes); - if (first.error !== undefined) throw first.error; - return first.info; - } finally { - unlink(); - controller.abort(abortError()); - } - } - - private collectExtras( - runningAtStart: readonly AgentTaskInfo[], - finishedTaskId: string, - ): AgentTaskInfo[] { - const extras: AgentTaskInfo[] = []; - for (const task of runningAtStart) { - if (task.taskId === finishedTaskId) continue; - const current = this.tasks.getTask(task.taskId); - if (current !== undefined && TERMINAL_STATUSES.has(current.status)) extras.push(current); - } - return extras; - } - - private formatTimeout(args: WaitForInput, startedAt: number, timeoutMs: number): string { - const lines = [ - formatPlainObject({ - waitStatus: 'timed_out', - taskId: args.task_id, - waitedMs: Date.now() - startedAt, - timeoutMs, - }), - 'The wait ended before the task finished — a timeout is not an error. Call WaitFor again to keep waiting, or continue with other work; completion also arrives via automatic notification.', - ]; - const running = this.tasks.list(true); - if (running.length > 0) { - lines.push('', '[still_running]', formatTaskList(running, true)); - } - return lines.join('\n'); - } - - private async formatCompleted( - finished: AgentTaskInfo, - extras: readonly AgentTaskInfo[], - startedAt: number, - timeoutMs: number, - ): Promise<string> { - const lines = [ - formatPlainObject({ - waitStatus: 'completed', - taskId: finished.taskId, - waitedMs: Date.now() - startedAt, - timeoutMs, - }), - '', - '[finished]', - ...(await this.formatFinishedTask(finished)), - ]; - if (extras.length > 0) { - lines.push( - '', - '[completed_during_wait]', - extras.map((extra) => formatPlainObject(extra)).join('\n---\n'), - 'Use TaskOutput with one of the task_id values above to read the full output.', - ); - } - const running = this.tasks.list(true); - if (running.length > 0) { - lines.push('', '[still_running]', formatTaskList(running, true)); - } - return lines.join('\n'); - } - - private async formatFinishedTask(info: AgentTaskInfo): Promise<string[]> { - const output = await this.tasks.getOutputSnapshot(info.taskId, OUTPUT_PREVIEW_BYTES); - const lines = [ - formatPlainObject({ - ...info, - outputPath: output.outputPath, - terminalReason: terminalReason(info), - outputSizeBytes: output.outputSizeBytes, - outputPreviewBytes: output.previewBytes, - outputTruncated: output.truncated, - fullOutputAvailable: output.fullOutputAvailable, - fullOutputTool: - output.fullOutputAvailable && output.outputPath !== undefined ? 'Read' : undefined, - fullOutputHint: fullOutputHint(output), - }), - '', - ]; - if (output.truncated) { - lines.push( - output.fullOutputAvailable && output.outputPath !== undefined - ? `[Truncated. Full output: ${output.outputPath}]` - : '[Truncated. No persisted full log is available for this task.]', - ); - } - lines.push('[output]', output.preview || '[no output available]'); - return lines; - } - - private track( - args: WaitForInput, - startedAt: number, - timeoutMs: number, - outcome: WaitForOutcome, - extraCompletedCount: number, - ): void { - this.telemetry.track2('wait_for_completed', { - outcome, - timeout_ms: timeoutMs, - waited_ms: Date.now() - startedAt, - has_task_id: args.task_id !== undefined, - extra_completed_count: extraCompletedCount, - }); - } -} - -registerAgentToolService(IWaitForTool, WaitForTool, { - name: 'WaitFor', - domain: 'agentTask', - when: (accessor) => accessor.get(IFlagService).enabled(WAIT_FOR_FLAG_ID), -}); diff --git a/packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list-write-reminder.md b/packages/agent-core-v2/src/agent/tools/todo-list/todo-list-write-reminder.md similarity index 100% rename from packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list-write-reminder.md rename to packages/agent-core-v2/src/agent/tools/todo-list/todo-list-write-reminder.md diff --git a/packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.md b/packages/agent-core-v2/src/agent/tools/todo-list/todo-list.md similarity index 100% rename from packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.md rename to packages/agent-core-v2/src/agent/tools/todo-list/todo-list.md diff --git a/packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.ts b/packages/agent-core-v2/src/agent/tools/todo-list/todo-list.ts similarity index 62% rename from packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.ts rename to packages/agent-core-v2/src/agent/tools/todo-list/todo-list.ts index 75c1ca51a..ef0ba6709 100644 --- a/packages/agent-core-v2/src/features/todo/tools/todo-list/todo-list.ts +++ b/packages/agent-core-v2/src/agent/tools/todo-list/todo-list.ts @@ -1,8 +1,22 @@ +/** + * `tools` domain — `ITodoListTool` contract (the `TodoList` tool). + * + * Public contract of the structured TODO list tool. A single input schema + * serves both reads and writes: + * + * - `{ todos: [...] }` — replace the full list + * - `{ todos: [] }` — clear the list + * - `{}` — query the current list + * + * Exports the model-facing `TodoListInputSchema` / `TodoListInput` and the + * `ITodoListTool` DI decorator. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; import { type AgentTool } from '#/tool/toolContract'; -import { type TodoStatus } from '#/features/todo/todoItem'; +import { type TodoStatus } from '#/session/todo/todoItem'; const TodoItemSchema = z.object({ title: z.string().min(1).describe('Short, actionable title for the todo.'), diff --git a/packages/agent-core-v2/src/features/todo/tools/todo-list/todoListTool.ts b/packages/agent-core-v2/src/agent/tools/todo-list/todoListTool.ts similarity index 55% rename from packages/agent-core-v2/src/features/todo/tools/todo-list/todoListTool.ts rename to packages/agent-core-v2/src/agent/tools/todo-list/todoListTool.ts index 03a2bc1af..6d0b0e36c 100644 --- a/packages/agent-core-v2/src/features/todo/tools/todo-list/todoListTool.ts +++ b/packages/agent-core-v2/src/agent/tools/todo-list/todoListTool.ts @@ -1,14 +1,29 @@ +/** + * `tools` domain — `TodoListTool` implementation (the `TodoList` tool). + * + * The list is session-shared: the tool reads/writes `ISessionTodoService` + * (`todo` domain), which persists every change as a `tools.update_store` + * (`key: 'todo'`) wire record on the main agent. + * + * Registered via the module-level `registerAgentToolService(ITodoListTool, + * TodoListTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. `AgentToolActivationService` activates it + * per agent when the profile allows (resolving the Session-scope + * `ISessionTodoService` from the parent scope) — never from a service + * constructor, which would re-enter `ISessionTodoService` while it is still + * being constructed. Bound at Agent scope. + */ + import type { ToolExecution } from '#/tool/toolContract'; +import { registerAgentToolService } from '#/agent/toolRegistry/toolContribution'; import { toInputJsonSchema } from '#/tool/input-schema'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { AgentTodo, type TodoRuntime } from '#/features/todo/todoAgentRuntime'; +import { ISessionTodoService } from '#/session/todo/sessionTodo'; import { TODO_LIST_TOOL_NAME, renderTodoList, type TodoItem, -} from '#/features/todo/todoItem'; +} from '#/session/todo/todoItem'; import { ITodoListTool, @@ -24,14 +39,7 @@ export class TodoListTool implements ITodoListTool { readonly description: string = DESCRIPTION; readonly parameters: Record<string, unknown> = toInputJsonSchema(TodoListInputSchema); - private readonly todo: TodoRuntime; - - constructor( - @IAgentLifecycleService manager: IAgentLifecycleService, - @IAgentScopeContext scope: IAgentScopeContext, - ) { - this.todo = manager.resolve(scope.agentContext, AgentTodo); - } + constructor(@ISessionTodoService private readonly todo: ISessionTodoService) {} resolveExecution(args: TodoListInput): ToolExecution { const description = @@ -45,15 +53,15 @@ export class TodoListTool implements ITodoListTool { approvalRule: this.name, execute: async () => { if (args.todos === undefined) { - return { isError: false, output: renderTodoList(this.todo.get()) }; + return { isError: false, output: renderTodoList(this.todo.getTodos()) }; } const next: readonly TodoItem[] = args.todos.map((todo) => ({ title: todo.title, status: todo.status, })); - await this.todo.replace(next); - const stored = this.todo.get(); + this.todo.setTodos(next); + const stored = this.todo.getTodos(); const output = stored.length === 0 ? 'Todo list cleared.' @@ -63,3 +71,5 @@ export class TodoListTool implements ITodoListTool { }; } } + +registerAgentToolService(ITodoListTool, TodoListTool, { name: 'TodoList', domain: 'todo' }); diff --git a/packages/agent-core-v2/src/agent/tools/web-search/web-search.ts b/packages/agent-core-v2/src/agent/tools/web-search/web-search.ts index 9acb3068f..326ec7e4a 100644 --- a/packages/agent-core-v2/src/agent/tools/web-search/web-search.ts +++ b/packages/agent-core-v2/src/agent/tools/web-search/web-search.ts @@ -1,3 +1,15 @@ +/** + * `tools` domain — `IWebSearchTool` contract (the `WebSearch` tool). + * + * Public contract of the `WebSearch` builtin tool: the model-facing + * `WebSearchInputSchema` / `WebSearchInput`, the host-injected + * `WebSearchProvider` interface (plus `WebSearchResult`) the tool delegates + * the actual search to, and the `IWebSearchTool` DI decorator. Web search + * needs an authenticated Moonshot backend, so the provider is wired in from + * the App-scope `IWebSearchProviderService` (`auth` domain) at activation + * time. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; @@ -21,12 +33,14 @@ export interface WebSearchProvider { ): Promise<WebSearchResult[]>; } + export const WebSearchInputSchema = z.object({ query: z.string().describe('The query text to search for.'), }); export type WebSearchInput = z.infer<typeof WebSearchInputSchema>; + export interface IWebSearchTool extends AgentTool<WebSearchInput> { readonly _serviceBrand: undefined; } diff --git a/packages/agent-core-v2/src/agent/tools/web-search/webSearchTool.ts b/packages/agent-core-v2/src/agent/tools/web-search/webSearchTool.ts index d0a4f51a7..9f720adcb 100644 --- a/packages/agent-core-v2/src/agent/tools/web-search/webSearchTool.ts +++ b/packages/agent-core-v2/src/agent/tools/web-search/webSearchTool.ts @@ -1,3 +1,21 @@ +/** + * `tools` domain — `WebSearchTool` implementation (the `WebSearch` tool). + * + * Resolves the host-injected `WebSearchProvider` from the App-scope + * `IWebSearchProviderService` (`auth` domain) per invocation — the activation + * gate checks presence alone, and the provider (which embeds the frozen + * identity headers) only composes once a call needs it, so tool construction + * during a fast bootstrap cannot race the identity freeze and a mid-session + * login or config edit reaches the next call. The tool only activates when a + * provider is configured, because there is no local search backend; results + * render through `ToolResultBuilder`, and provider errors classify into + * model-readable output. + * + * Registered via the module-level `registerAgentToolService(IWebSearchTool, + * WebSearchTool)` at the bottom of this file — the same "import = register" + * pattern used by every agent tool. Bound at Agent scope. + */ + import { toInputJsonSchema } from '#/tool/input-schema'; import { literalRulePattern, matchesGlobRuleSubject } from '#/tool/rule-match'; import { @@ -17,6 +35,7 @@ import { } from './web-search'; import DESCRIPTION from './web-search.md?raw'; + export class WebSearchTool implements IWebSearchTool { declare readonly _serviceBrand: undefined; readonly name = 'WebSearch' as const; @@ -86,6 +105,7 @@ export class WebSearchTool implements IWebSearchTool { } } + function classifySearchError(error: unknown): string { const name = error instanceof Error ? error.name : ''; const message = error instanceof Error ? error.message : String(error); diff --git a/packages/agent-core-v2/src/agent/undo/undo.ts b/packages/agent-core-v2/src/agent/undo/undo.ts index 09f690161..62ec15e72 100644 --- a/packages/agent-core-v2/src/agent/undo/undo.ts +++ b/packages/agent-core-v2/src/agent/undo/undo.ts @@ -1,3 +1,10 @@ +/** + * `undo` domain — Agent-scoped conversation undo contract. + * + * Defines the availability and idle-only execution surface shared by every + * undo entry point. Bound at Agent scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface UndoAvailability { diff --git a/packages/agent-core-v2/src/agent/undo/undoService.ts b/packages/agent-core-v2/src/agent/undo/undoService.ts index 11c870c0f..e92233318 100644 --- a/packages/agent-core-v2/src/agent/undo/undoService.ts +++ b/packages/agent-core-v2/src/agent/undo/undoService.ts @@ -1,4 +1,12 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `undo` domain — `IAgentConversationUndoService` implementation. + * + * Owns idle conversation undo coordination and restored observable state. + * Coordinates `contextMemory`, undo participants, `fullCompaction`, + * `loop`, `prompt`, Agent and Session identity, `sessionMetadata`, `event`, + * `eventBus`, `telemetry`, and `wire`. Bound at Agent scope. + */ + import { type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; @@ -12,35 +20,31 @@ import { precheckUndo, } from '#/agent/contextMemory/contextOps'; import { + CHECKPOINTED_MODELS, isUndoAnchor, isValidUndoCount, + type Checkpointed, } from '#/agent/contextMemory/conversationTime'; import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; import { IAgentLoopService } from '#/agent/loop/loop'; import { IAgentPromptService } from '#/agent/prompt/prompt'; import { promptMetadataTextFromContentParts } from '#/agent/prompt/promptMetadataText'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; import { IEventService } from '#/app/event/event'; -import { AgentEvent2 } from '#/app/event/event2'; +import { IEventBus } from '#/app/event/eventBus'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { ErrorCodes, Error2 } from '#/errors'; import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { SessionMetaUpdated } from '#/session/sessionMetadata/sessionMetaEvents'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { keepsUndoCheckpoints } from '#/state/state'; +import { IWireService } from '#/wire/wire'; import { IAgentConversationUndoService, type UndoAvailability } from './undo'; -export class ContextUndone extends AgentEvent2<{ readonly agentId: string; readonly turns: number }> { - static override readonly type = 'context.undone'; - static override readonly observable = true; -} -export interface ContextUndone { - readonly agentId: string; - readonly turns: number; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'context.undone': { turns: number }; + } } export class AgentConversationUndoService @@ -62,9 +66,9 @@ export class AgentConversationUndoService @ISessionContext private readonly session: ISessionContext, @ISessionMetadata private readonly metadata: ISessionMetadata, @IEventService private readonly eventService: IEventService, + @IEventBus private readonly eventBus: IEventBus, @ITelemetryService private readonly telemetry: ITelemetryService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentStateService private readonly agentState: IAgentStateService, + @IWireService private readonly wire: IWireService, @ILogService private readonly log: ILogService, ) { super(); @@ -112,9 +116,7 @@ export class AgentConversationUndoService await this.flushAfterCommit('state reconciliation'); await this.reconcileLastPromptSafely(); this.telemetry.track2('conversation_undo', { count: turns }); - await this.dispatcher.dispatch( - new ContextUndone({ agentId: this.agentCtx.agentId, turns }), - ); + this.eventBus.publish({ type: 'context.undone', turns }); return turns; } finally { quiescence?.dispose(); @@ -124,18 +126,11 @@ export class AgentConversationUndoService private checkpointDepth(): { depth: number; model: string } { let depth = Number.POSITIVE_INFINITY; let model = ''; - for (const key of this.agentState.replayableKeys()) { - if (!keepsUndoCheckpoints(key)) continue; - const stateDepth = this.dispatcher.checkpointDepth(key); - if (stateDepth < depth) { - depth = stateDepth; - model = key.name; - } - } - for (const entry of this.dispatcher.modelCheckpointDepths()) { - if (entry.depth < depth) { - depth = entry.depth; - model = entry.id; + for (const def of CHECKPOINTED_MODELS) { + const state = this.wire.getModel(def) as Checkpointed<unknown>; + if (state.checkpoints.length < depth) { + depth = state.checkpoints.length; + model = def.name; } } return { depth, model }; @@ -210,7 +205,7 @@ export class AgentConversationUndoService private async flushAfterCommit(stage: string): Promise<void> { try { - await this.dispatcher.flush(); + await this.wire.flush(); } catch (error) { this.log.error('undo wire flush failed after in-memory commit', { stage, error }); throw error; @@ -233,15 +228,14 @@ export class AgentConversationUndoService } } await this.metadata.update({ lastPrompt }); - this.eventService.publish( - new SessionMetaUpdated({ - payload: { - agentId: MAIN_AGENT_ID, - sessionId: this.session.sessionId, - patch: { lastPrompt }, - }, - }), - ); + this.eventService.publish({ + type: 'session.meta.updated', + payload: { + agentId: MAIN_AGENT_ID, + sessionId: this.session.sessionId, + patch: { lastPrompt }, + }, + }); } } diff --git a/packages/agent-core-v2/src/agent/usage/cacheProbe.ts b/packages/agent-core-v2/src/agent/usage/cacheProbe.ts deleted file mode 100644 index cd5906273..000000000 --- a/packages/agent-core-v2/src/agent/usage/cacheProbe.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface IAgentCacheProbeService { - readonly _serviceBrand: undefined; -} - -export const IAgentCacheProbeService: ServiceIdentifier<IAgentCacheProbeService> = - createDecorator<IAgentCacheProbeService>('agentCacheProbeService'); diff --git a/packages/agent-core-v2/src/agent/usage/cacheProbeService.ts b/packages/agent-core-v2/src/agent/usage/cacheProbeService.ts deleted file mode 100644 index 9065defcd..000000000 --- a/packages/agent-core-v2/src/agent/usage/cacheProbeService.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { Service } from '#/_base/di/service'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { inputTotal } from '#/kosong/contract/usage'; -import { IModelCatalog } from '#/kosong/model/catalog'; -import { ISessionUsageService } from '#/session/usage/sessionUsage'; - -import { IAgentCacheProbeService } from './cacheProbe'; -import { type UsageRecordedContext } from './usage'; - -export class AgentCacheProbeService extends Service implements IAgentCacheProbeService { - declare readonly _serviceBrand: undefined; - - constructor( - @ISessionUsageService usage: ISessionUsageService, - @IAgentScopeContext scopeContext: IAgentScopeContext, - @ITelemetryService private readonly telemetry: ITelemetryService, - @IModelCatalog private readonly models: IModelCatalog, - ) { - super(); - if (scopeContext.forkedFrom === undefined) return; - this._register( - usage.onDidRecord((e) => { - if (e.agent.agentId === scopeContext.agentId) this.probe(e); - }), - ); - } - - private probe(e: UsageRecordedContext): void { - if (!e.firstRecord || e.source?.type !== 'turn') return; - let providerType: string | undefined; - let protocol: string | undefined; - try { - const model = this.models.get(e.model); - providerType = model.providerType ?? model.protocol; - protocol = model.protocol; - } catch { } - this.telemetry.track2('prompt_cache_probe', { - source: 'fork', - turn_id: e.source.turnId, - provider_type: providerType, - protocol, - input_tokens: inputTotal(e.usage), - input_cache_read: e.usage.inputCacheRead, - input_cache_creation: e.usage.inputCacheCreation, - output_tokens: e.usage.output, - }); - } -} - -registerScopedService( - LifecycleScope.Agent, - IAgentCacheProbeService, - AgentCacheProbeService, - ScopeActivation.OnScopeCreated, - 'cacheProbe', -); diff --git a/packages/agent-core-v2/src/agent/usage/errors.ts b/packages/agent-core-v2/src/agent/usage/errors.ts index e9717eaa3..bf1f230d1 100644 --- a/packages/agent-core-v2/src/agent/usage/errors.ts +++ b/packages/agent-core-v2/src/agent/usage/errors.ts @@ -1,3 +1,7 @@ +/** + * `usage` domain error codes — invalid persisted usage records. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const UsageErrors = { diff --git a/packages/agent-core-v2/src/agent/usage/usage.ts b/packages/agent-core-v2/src/agent/usage/usage.ts index f47e96abd..bd99c9989 100644 --- a/packages/agent-core-v2/src/agent/usage/usage.ts +++ b/packages/agent-core-v2/src/agent/usage/usage.ts @@ -1,8 +1,17 @@ -import type { AgentContext } from '#/agent/agentContext/agentContext'; +/** + * `usage` domain — per-agent token usage accounting contract. + * + * Exposes accumulated status, live usage recording, and an `onDidRecord` event + * for agent-scoped consumers that react to newly recorded usage. Bound at Agent + * scope. + */ + import type { AgentLLMRequestSource } from '#/agent/llmRequester/llmRequester'; import type { TokenUsage } from '#/kosong/contract/usage'; -import { type ErrorCode } from '#/errors'; +import { createDecorator } from '#/_base/di/instantiation'; +import type { Event } from '#/_base/event'; +import type { ErrorCode } from '#/errors'; import { Error2 } from '#/_base/errors/errors'; import { UsageErrors } from './errors'; @@ -25,9 +34,18 @@ export interface UsageStatus { } export interface UsageRecordedContext { - readonly agent: AgentContext; readonly model: string; readonly usage: Readonly<TokenUsage>; readonly source?: AgentLLMRequestSource; - readonly firstRecord: boolean; } + +export interface IAgentUsageService { + readonly _serviceBrand: undefined; + + record(model: string, usage: TokenUsage, source?: AgentLLMRequestSource): void; + status(): UsageStatus; + + readonly onDidRecord: Event<UsageRecordedContext>; +} + +export const IAgentUsageService = createDecorator<IAgentUsageService>('agentUsageService'); diff --git a/packages/agent-core-v2/src/agent/usage/usageEvents.ts b/packages/agent-core-v2/src/agent/usage/usageEvents.ts deleted file mode 100644 index b608a58b5..000000000 --- a/packages/agent-core-v2/src/agent/usage/usageEvents.ts +++ /dev/null @@ -1,22 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { AgentEvent2 } from '#/app/event/event2'; - -import type { UsageStatus } from './usage'; - -export interface AgentStatusUpdatedPayload { - readonly agentId: string; - usage?: UsageStatus; - swarmMode?: boolean; - towerMode?: boolean; - planMode?: boolean; - model?: string; - thinkingEffort?: string; - maxContextTokens?: number; - contextTokens?: number; -} - -export class AgentStatusUpdated extends AgentEvent2<AgentStatusUpdatedPayload> { - static override readonly type = 'agent.status.updated'; - static override readonly observable = true; -} -export interface AgentStatusUpdated extends AgentStatusUpdatedPayload {} diff --git a/packages/agent-core-v2/src/agent/usage/usageOps.ts b/packages/agent-core-v2/src/agent/usage/usageOps.ts index d44ca844a..069e756b4 100644 --- a/packages/agent-core-v2/src/agent/usage/usageOps.ts +++ b/packages/agent-core-v2/src/agent/usage/usageOps.ts @@ -1,34 +1,98 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `usage` domain — wire Model (`UsageModel`) and the `usage.record` Op + * (`recordUsage`) for the agent's accumulated token usage. + * + * Declares usage as a wire Model (`byModel` totals) plus the single Op that + * folds one `record` call into it. The persisted record carries exactly v1's + * field set (`{ model, usage, usageScope }`); the per-turn accumulator is NOT + * in the Model — it is live-only service state, reset on + * resume like v1 (v1 restore folds every `usage.record` as `session` scope and + * never rebuilds `currentTurn`). `apply` is pure and ignores any extra fields + * found on replayed legacy records (early v2 logs carried `turnId` / `context`). + * Also declares the canonical `agent.status.updated` event shape on + * `DomainEventMap`; the usage slice is published live after + * each dispatch (never on replay). + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; -import { type TokenUsage } from '#/kosong/contract/usage'; +import { addUsage, type TokenUsage } from '#/kosong/contract/usage'; +import { defineModel } from '#/wire/model'; + +import type { UsageStatus } from './usage'; export type UsageRecordScope = 'session' | 'turn'; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'agent.status.updated': { + usage?: UsageStatus; + swarmMode?: boolean; + planMode?: boolean; + model?: string; + thinkingEffort?: string; + maxContextTokens?: number; + contextTokens?: number; + }; + } +} + export interface UsageModelState { readonly byModel: Record<string, TokenUsage>; } -const usageRecordSchema = z.object({ - agentId: z.string(), - model: z.string(), - usage: z.custom<TokenUsage>(), - usageScope: z.custom<UsageRecordScope>().optional(), -}); +export const UsageModel = defineModel<UsageModelState>('usage', () => ({ byModel: {} })); -export class UsageRecord extends AgentEvent2<z.infer<typeof usageRecordSchema>> { - static override readonly type = 'usage.record'; - static override readonly durable = true; - static override readonly schema = usageRecordSchema; -} -export interface UsageRecord { - readonly agentId: string; - readonly model: string; - readonly usage: TokenUsage; - readonly usageScope?: UsageRecordScope; +declare module '#/wire/types' { + interface PersistedOpMap { + 'usage.record': typeof recordUsage; + } } +export const recordUsage = UsageModel.defineOp('usage.record', { + schema: z.object({ + model: z.string(), + usage: z.custom<TokenUsage>(), + usageScope: z.custom<UsageRecordScope>().optional(), + }), + apply: (s, p) => { + const current = s.byModel[p.model]; + return { + byModel: { + ...s.byModel, + [p.model]: current === undefined ? copyUsage(p.usage) : addUsage(current, p.usage), + }, + }; + }, +}); + export function copyUsage(usage: TokenUsage): TokenUsage { return { ...usage }; } + +export function usageStatusFromState( + model: UsageModelState, + currentTurn?: TokenUsage, +): UsageStatus { + const byModel = byModelSnapshot(model.byModel); + const hasByModel = Object.keys(byModel).length > 0; + return { + byModel: hasByModel ? byModel : undefined, + total: hasByModel ? totalUsage(byModel) : undefined, + currentTurn: currentTurn === undefined ? undefined : copyUsage(currentTurn), + }; +} + +function byModelSnapshot(byModel: Record<string, TokenUsage>): Record<string, TokenUsage> { + return Object.fromEntries( + Object.entries(byModel).map(([model, usage]) => [model, copyUsage(usage)]), + ); +} + +function totalUsage(byModel: Record<string, TokenUsage>): TokenUsage | undefined { + let total: TokenUsage | undefined; + for (const usage of Object.values(byModel)) { + total = total === undefined ? copyUsage(usage) : addUsage(total, usage); + } + return total; +} diff --git a/packages/agent-core-v2/src/agent/usage/usageService.ts b/packages/agent-core-v2/src/agent/usage/usageService.ts new file mode 100644 index 000000000..aa8342238 --- /dev/null +++ b/packages/agent-core-v2/src/agent/usage/usageService.ts @@ -0,0 +1,108 @@ +/** + * `usage` domain — `IAgentUsageService` implementation. + * + * Accumulates the agent's token usage in the `wire` `UsageModel`, mutating it + * only through the `usage.record` Op (`wire.dispatch(recordUsage(...))`) and + * deriving `status()` snapshots from `wire.getModel`. The per-turn accumulator + * (`currentTurnId` / `currentTurn`) is live-only service state — it is not + * persisted and resets on resume, matching v1 — and is registered into + * `agentState` (`IAgentStateService`) and read/written through it. The usage + * slice of `agent.status.updated` is + * published here after each live record (replay stays silent, like v1's + * restore), and the `onDidRecord` event notifies agent-scoped consumers of the + * live record. Bound at Agent scope. + */ + +import { addUsage, type TokenUsage } from '#/kosong/contract/usage'; +import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { Emitter, type Event } from '#/_base/event'; +import { defineState } from '#/_base/state/stateRegistry'; + +import type { AgentLLMRequestSource } from '#/agent/llmRequester/llmRequester'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { IEventBus } from '#/app/event/eventBus'; +import { IWireService } from '#/wire/wire'; +import type { UsageRecordedContext, UsageStatus } from './usage'; +import { IAgentUsageService } from './usage'; +import { + copyUsage, + recordUsage, + UsageModel, + usageStatusFromState, + type UsageRecordScope, +} from './usageOps'; + +export const usageCurrentTurnIdKey = defineState<number | undefined>( + 'usage.currentTurnId', + () => undefined as number | undefined, +); +export const usageCurrentTurnKey = defineState<TokenUsage | undefined>( + 'usage.currentTurn', + () => undefined as TokenUsage | undefined, +); + +export class AgentUsageService extends Service implements IAgentUsageService { + declare readonly _serviceBrand: undefined; + + private readonly _onDidRecord = this._register(new Emitter<UsageRecordedContext>()); + readonly onDidRecord: Event<UsageRecordedContext> = this._onDidRecord.event; + + constructor( + @IWireService private readonly wire: IWireService, + @IAgentStateService private readonly states: IAgentStateService, + @IEventBus private readonly eventBus?: IEventBus, + ) { + super(); + this.states.register(usageCurrentTurnIdKey); + this.states.register(usageCurrentTurnKey); + } + + private get currentTurnId(): number | undefined { + return this.states.get(usageCurrentTurnIdKey); + } + + private set currentTurnId(value: number | undefined) { + this.states.set(usageCurrentTurnIdKey, value); + } + + private get currentTurn(): TokenUsage | undefined { + return this.states.get(usageCurrentTurnKey); + } + + private set currentTurn(value: TokenUsage | undefined) { + this.states.set(usageCurrentTurnKey, value); + } + + record(model: string, usage: TokenUsage, source?: AgentLLMRequestSource): void { + const usageScope: UsageRecordScope = source?.type === 'turn' ? 'turn' : 'session'; + this.wire.dispatch(recordUsage({ model, usage, usageScope })); + + const turnId = source?.type === 'turn' ? source.turnId : undefined; + if (turnId !== undefined) { + if (this.currentTurnId !== turnId) { + this.currentTurnId = turnId; + this.currentTurn = copyUsage(usage); + } else { + this.currentTurn = + this.currentTurn === undefined ? copyUsage(usage) : addUsage(this.currentTurn, usage); + } + } + + this.eventBus?.publish({ type: 'agent.status.updated', usage: this.status() }); + this._onDidRecord.fire({ model, usage: copyUsage(usage), source }); + } + + status(): UsageStatus { + return usageStatusFromState(this.wire.getModel(UsageModel), this.currentTurn); + } +} + +registerScopedService( + LifecycleScope.Agent, + IAgentUsageService, + AgentUsageService, + ScopeActivation.OnScopeCreated, + 'usage', +); diff --git a/packages/agent-core-v2/src/agent/userTool/userTool.ts b/packages/agent-core-v2/src/agent/userTool/userTool.ts index d16d17a30..a838cdaa4 100644 --- a/packages/agent-core-v2/src/agent/userTool/userTool.ts +++ b/packages/agent-core-v2/src/agent/userTool/userTool.ts @@ -12,10 +12,7 @@ export interface IAgentUserToolService { readonly _serviceBrand: undefined; list(): readonly UserToolRegistration[]; - inheritUserTools( - parent: IAgentUserToolService, - activeToolNames?: readonly string[], - ): void; + inheritUserTools(parent: IAgentUserToolService): void; register(input: UserToolRegistration): void; unregister(name: string): void; } diff --git a/packages/agent-core-v2/src/agent/userTool/userToolOps.ts b/packages/agent-core-v2/src/agent/userTool/userToolOps.ts index 7fb6e991b..bdd5c40ef 100644 --- a/packages/agent-core-v2/src/agent/userTool/userToolOps.ts +++ b/packages/agent-core-v2/src/agent/userTool/userToolOps.ts @@ -1,48 +1,38 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { original } from 'immer'; +/** + * `userTool` domain — wire Model (`UserToolModel`) and the + * `tools.register_user_tool` (`registerUserTool`) / `tools.unregister_user_tool` + * (`unregisterUserTool`) Ops for the set of user-defined tools registered by the + * host. + * + * Declares the registered user tools as a `Map<string, UserToolRegistration>` + * wire Model (initial empty), plus the two Ops whose `apply` functions are the + * pure extraction of the former live `applyRegister` / `applyUnregister` Map + * mutations and their `record.define(...resume...)` facets (their common + * transition). Each returns the same reference when nothing changes (registering + * an already-equal tool / unregistering an unknown name) so the wire's + * reference-equality gate stays quiet. The side effects — `registry.register` + * and `profile.addActiveTool` (and the matching dispose / `removeActiveTool`) — + * are NOT part of `apply`: they run after `wire.dispatch` on the live path and + * are re-derived from the rebuilt Model by `wire.hooks.onDidRestore` after + * restore, so a resumed agent re-registers exactly the tools the persisted ops + * describe. + */ + import { z } from 'zod'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; +import { defineModel } from '#/wire/model'; import type { UserToolRegistration } from './userTool'; export type UserToolModelState = Map<string, UserToolRegistration>; -const toolsRegisterUserToolSchema = z.object({ - agentId: z.string(), - name: z.string(), - description: z.string(), - parameters: z.custom<UserToolRegistration['parameters']>(), - disclosure: z.custom<UserToolRegistration['disclosure']>().optional(), -}); +export const UserToolModel = defineModel<UserToolModelState>('userTool', () => new Map()); -export class ToolsRegisterUserTool extends AgentEvent2< - z.infer<typeof toolsRegisterUserToolSchema> -> { - static override readonly type = 'tools.register_user_tool'; - static override readonly durable = true; - static override readonly schema = toolsRegisterUserToolSchema; -} -export interface ToolsRegisterUserTool extends UserToolRegistration { - readonly agentId: string; -} - -const toolsUnregisterUserToolSchema = z.object({ - agentId: z.string(), - name: z.string(), -}); - -export class ToolsUnregisterUserTool extends AgentEvent2< - z.infer<typeof toolsUnregisterUserToolSchema> -> { - static override readonly type = 'tools.unregister_user_tool'; - static override readonly durable = true; - static override readonly schema = toolsUnregisterUserToolSchema; -} -export interface ToolsUnregisterUserTool { - readonly agentId: string; - readonly name: string; +declare module '#/wire/types' { + interface PersistedOpMap { + 'tools.register_user_tool': typeof registerUserTool; + 'tools.unregister_user_tool': typeof unregisterUserTool; + } } function equalRegistration(a: UserToolRegistration, b: UserToolRegistration): boolean { @@ -54,20 +44,23 @@ function equalRegistration(a: UserToolRegistration, b: UserToolRegistration): bo ); } -export const userToolKey = defineState('userTool', (): UserToolModelState => new Map()).replayable({ - schema: z.custom<UserToolModelState>(), -}) - .on(ToolsRegisterUserTool, (s, e) => { - const existing = s.get(e.name); - if (existing !== undefined && equalRegistration(original(existing), e)) return; - s.set(e.name, { - name: e.name, - description: e.description, - parameters: e.parameters, - disclosure: e.disclosure, - }); - }) - .on(ToolsUnregisterUserTool, (s, e) => { - if (!s.has(e.name)) return; - s.delete(e.name); - }); +export const registerUserTool = UserToolModel.defineOp('tools.register_user_tool', { + schema: z.custom<UserToolRegistration>(), + apply: (s, p) => { + const existing = s.get(p.name); + if (existing !== undefined && equalRegistration(existing, p)) return s; + const next = new Map(s); + next.set(p.name, p); + return next; + }, +}); + +export const unregisterUserTool = UserToolModel.defineOp('tools.unregister_user_tool', { + schema: z.object({ name: z.string() }), + apply: (s, p) => { + if (!s.has(p.name)) return s; + const next = new Map(s); + next.delete(p.name); + return next; + }, +}); diff --git a/packages/agent-core-v2/src/agent/userTool/userToolService.ts b/packages/agent-core-v2/src/agent/userTool/userToolService.ts index cafeb2096..9719a7b8d 100644 --- a/packages/agent-core-v2/src/agent/userTool/userToolService.ts +++ b/packages/agent-core-v2/src/agent/userTool/userToolService.ts @@ -1,4 +1,21 @@ -import { randomUUID } from 'node:crypto'; +/** + * `userTool` domain — `IAgentUserToolService` implementation. + * + * Holds the set of host-registered user tools in the `wire` `UserToolModel` + * (`Map<string, UserToolRegistration>`), mutating it only through the + * `tools.register_user_tool` / `tools.unregister_user_tool` Ops + * (`wire.dispatch(...)`). The live side effects — `registry.register` + + * `profile.addActiveTool` (and the matching dispose / `removeActiveTool`) — run + * after the dispatch, and are re-derived from the rebuilt Model by + * `wire.hooks.onDidRestore` after `wire.restore`, so a resumed agent re-registers + * exactly the tools the persisted ops describe without re-firing any live + * notification. + * The restore re-registers into the tool registry only: the active-tool set is + * owned by the persisted `ActiveToolsModel`, so the ephemeral `addActiveTool` + * overlay is not rebuilt (it is live-only by design). The per-tool + * `IDisposable` handles stay live-only (they cannot be persisted). + * Bound at Agent scope. + */ import { type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; @@ -12,21 +29,11 @@ import type { ExecutableToolResult, } from '#/tool/toolContract'; import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { - AgentInteraction, - type InteractionRuntime, -} from '#/features/interaction/interactionAgentRuntime'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { ISessionInteractionService } from '#/session/interaction/interaction'; +import { IWireService } from '#/wire/wire'; import { IAgentUserToolService, type UserToolRegistration } from './userTool'; -import { - ToolsRegisterUserTool, - ToolsUnregisterUserTool, - userToolKey, -} from './userToolOps'; +import { registerUserTool, unregisterUserTool, UserToolModel } from './userToolOps'; interface UserToolExecutionRequest { readonly turnId?: number; @@ -39,21 +46,16 @@ export class AgentUserToolService extends Service implements IAgentUserToolServi declare readonly _serviceBrand: undefined; private readonly registrations = new Map<string, IDisposable>(); - private readonly interaction: InteractionRuntime; constructor( - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, @IAgentToolRegistryService private readonly registry: IAgentToolRegistryService, @IAgentProfileService private readonly profile: IAgentProfileService, - @IAgentLifecycleService manager: IAgentLifecycleService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentStateService private readonly agentState: IAgentStateService, + @ISessionInteractionService private readonly interaction: ISessionInteractionService, + @IWireService private readonly wire: IWireService, ) { super(); - this.interaction = manager.resolve(scopeContext.agentContext, AgentInteraction); - this.agentState.contributeState(userToolKey); this._register( - this.dispatcher.hooks.onDidRestore.register('user-tool', async (_ctx, next) => { + this.wire.hooks.onDidRestore.register('user-tool', async (_ctx, next) => { this.restoreRegisteredTools(); await next(); }), @@ -61,40 +63,28 @@ export class AgentUserToolService extends Service implements IAgentUserToolServi } list(): readonly UserToolRegistration[] { - return [...this.agentState.get(userToolKey).values()]; + return [...this.wire.getModel(UserToolModel).values()]; } - inheritUserTools( - parent: IAgentUserToolService, - activeToolNames?: readonly string[], - ): void { + inheritUserTools(parent: IAgentUserToolService): void { for (const registration of parent.list()) { - void this.dispatcher.dispatch( - new ToolsRegisterUserTool({ ...registration, agentId: this.scopeContext.agentId }), - ); - const activate = - activeToolNames === undefined || activeToolNames.includes(registration.name); - this.applyRegister(registration, { activate }); + this.register(registration); } } register(input: UserToolRegistration): void { - void this.dispatcher.dispatch( - new ToolsRegisterUserTool({ ...input, agentId: this.scopeContext.agentId }), - ); + this.wire.dispatch(registerUserTool(input)); this.applyRegister(input); } unregister(name: string): void { - void this.dispatcher.dispatch( - new ToolsUnregisterUserTool({ agentId: this.scopeContext.agentId, name }), - ); + this.wire.dispatch(unregisterUserTool({ name })); this.applyUnregister(name); } private restoreRegisteredTools(): void { const persistedActive = this.profile.getActiveToolNames(); - for (const registration of this.agentState.get(userToolKey).values()) { + for (const registration of this.wire.getModel(UserToolModel).values()) { const activate = persistedActive === undefined || persistedActive.includes(registration.name); this.applyRegister(registration, { activate }); @@ -136,9 +126,8 @@ export class AgentUserToolService extends Service implements IAgentUserToolServi name: string, args: unknown, ): Promise<ExecutableToolResult> { - const id = `user_tool_${randomUUID()}`; const request = this.interaction.request<UserToolExecutionRequest, ExecutableToolResult>({ - id, + id: context.toolCallId, kind: 'user_tool', payload: { turnId: context.turnId, @@ -154,7 +143,7 @@ export class AgentUserToolService extends Service implements IAgentUserToolServi return await abortable(request, context.signal); } catch (error) { if (context.signal.aborted) { - this.interaction.respond(id, { + this.interaction.respond(context.toolCallId, { output: `User tool "${name}" was aborted.`, isError: true, }); diff --git a/packages/agent-core-v2/src/app/agentIdentity/agentIdentity.ts b/packages/agent-core-v2/src/app/agentIdentity/agentIdentity.ts index f84a99fa9..08b25260e 100644 --- a/packages/agent-core-v2/src/app/agentIdentity/agentIdentity.ts +++ b/packages/agent-core-v2/src/app/agentIdentity/agentIdentity.ts @@ -1,3 +1,25 @@ +/** + * `agentIdentity` domain — resolved identity contract. + * + * The identity the agent uses for itself, resolved from the `[identity]` + * config section over the host's declared display name and frozen for the + * life of the process: the identity is announced outward (MCP initialize, + * OAuth registration, provider request logs) and cannot be re-announced, so + * restart-to-change is the one coherent semantic — and consumers may bake the + * snapshot into caches, prompts, and connections with no invalidation + * obligations. `resolved()` awaits the freeze; `current()` throws before it, + * so an early materialization fails loudly instead of caching a pre-config + * value. Bound at App scope. + * + * The snapshot carries finished products, never raw material for call sites + * to compose: the prompt display name, the protocol slug (`undefined` on + * either means no custom identity — consumers keep their built-in behavior), + * and the outbound `User-Agent` projections, which rewrite only the product + * token of what the host already sends (the key located case-insensitively, + * the host's spelling kept) — except toward directories this process chooses + * to call, where a header is always presented. + */ + import { replaceUserAgentProduct } from '@moonshot-ai/kimi-code-oauth'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/app/agentIdentity/agentIdentityService.ts b/packages/agent-core-v2/src/app/agentIdentity/agentIdentityService.ts index 9926e1943..1aa2340b8 100644 --- a/packages/agent-core-v2/src/app/agentIdentity/agentIdentityService.ts +++ b/packages/agent-core-v2/src/app/agentIdentity/agentIdentityService.ts @@ -1,3 +1,16 @@ +/** + * `agentIdentity` domain — `IAgentIdentity` implementation. + * + * Builds the process-lifetime snapshot from the `[identity]` config section + * (which already layers `env > config.toml`) and the host's declared display + * name and request headers in `IBootstrapService.args`, once config has first + * loaded; later `[identity]` edits take effect on the next start. Bound at + * App scope, activated eagerly so the freeze is armed before any consumer can + * observe config readiness — a config load failure still freezes, from + * whatever the config service then serves, matching what every other section + * consumer would read. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { CoreErrors } from '#/_base/errors/codes'; diff --git a/packages/agent-core-v2/src/app/agentIdentity/configSection.ts b/packages/agent-core-v2/src/app/agentIdentity/configSection.ts index 6011727eb..83f6aca20 100644 --- a/packages/agent-core-v2/src/app/agentIdentity/configSection.ts +++ b/packages/agent-core-v2/src/app/agentIdentity/configSection.ts @@ -1,3 +1,20 @@ +/** + * `agentIdentity` domain — the `[identity]` config section. + * + * Owns the user-facing custom-identity preference: `name`, the display name in + * the system prompt, and the optional `slug` that goes into protocol fields. + * Both bind to `KIMI_CODE_IDENTITY_NAME` / `KIMI_CODE_IDENTITY_SLUG` so a + * container or CI run can state an identity without writing `config.toml`; an + * env override never persists back into the file. Leaving the section unset + * means no custom identity, and every consumer keeps its current behavior. + * + * Unlike most sections this one is read exactly once: `agentIdentity` freezes + * its snapshot when config first loads, so edits apply on the next start — + * see the domain contract for why mid-process changes cannot be honored. + * + * Self-registered at module load via `registerConfigSection`. + */ + import { z } from 'zod'; import { diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts index 1e13f5f12..9f2044652 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileCatalog.ts @@ -1,11 +1,53 @@ +/** + * `agentProfileCatalog` domain — the agent-profile domain types and the + * App-scope extension point (`IAgentProfileRegistry`). + * + * A profile is "how an Agent runs": the full system prompt it renders for a + * given context, the tool set it may use, plus optional per-invocation and + * summary-distillation behavior for child agents. A profile is model-agnostic: + * the same profile can be bound to any Model. Together with a bound Model, a + * profile uniquely determines an Agent's behavior (`Profile + Model ⇒ Agent`). + * + * Every profile is self-contained: `renderSystemPrompt(context)` returns the + * complete prompt (base + role overlay are merged at definition time, not at + * spawn time) together with the environment facts disclosed by that render. + * `systemPrompt(context)` is the same render's text only — it is derived from + * `renderSystemPrompt` at registration, so the two can never drift apart. + * Profiles stay + * independent of concrete model aliases, but may declare + * a symbolic primary/secondary preference used as the default when spawned as + * a subagent. The builtin {@link DEFAULT_AGENT_PROFILE_NAME} (`agent`) is the + * default profile used when an Agent is bound to a Model without naming a + * profile. + * + * `tools` is an allowlist of exact builtin names plus `mcp__` globs + * (`undefined` = every tool active); `disallowedTools` denies with the same + * matching semantics, applied on top of the allowlist result. `subagents` is + * an allowlist of subagent profile names the agent may delegate to + * (`undefined` = any type). + * + * Profiles reach agents through the Contribution / Registry / Catalog + * extension point: loaders (builtin code contributions via + * `registerAgentProfile(...)`, plugin / user file scans at App scope, + * workspace / extra / explicit file scans at Workspace scope) contribute + * `AgentProfileContribution` records to the collection, keyed by source id; + * the App-scope `IAgentProfileRegistry` fold projects them into its read + * surface, and the Session-scope `ISessionAgentProfileCatalog` projects the + * registry into the merged, name-deduped read view that consumers (the + * `Agent` tool, the swarm scheduler, the per-agent profile binding) resolve + * profiles through. + */ + import type { ILogger } from '#/_base/log/log'; -import type { IHostProcessService } from '#/os/interface/hostProcess'; +import type { ISessionProcessRunner } from '#/session/process/processRunner'; export const DEFAULT_AGENT_PROFILE_NAME = 'agent'; +export type AgentModelPreference = 'primary' | 'secondary'; + export interface AgentProfilePromptPrefixContext { readonly cwd: string; - readonly process: IHostProcessService; + readonly runner: ISessionProcessRunner; readonly log?: ILogger; } @@ -53,12 +95,27 @@ export interface AgentProfile { readonly tools?: readonly string[]; readonly disallowedTools?: readonly string[]; readonly subagents?: readonly string[]; + readonly modelPreference?: AgentModelPreference; readonly systemPrompt: (context: AgentProfileContext) => string; readonly renderSystemPrompt: (context: AgentProfileContext) => SystemPromptRenderResult; readonly promptPrefix?: (ctx: AgentProfilePromptPrefixContext) => Promise<string>; readonly summaryPolicy?: AgentProfileSummaryPolicy; } +/** + * The profile shape accepted at registration ({@link registerAgentProfile}, + * file-based profile factories): authors provide at least one render entry — + * the structured `renderSystemPrompt`, the legacy text-only `systemPrompt`, + * or both (the structured renderer is then authoritative). The union + * statically requires at least one entry; {@link normalizeAgentProfile} still + * throws on inputs that escaped the type check (plain JS, casts). + * {@link normalizeAgentProfile} derives the other method, so a registered + * {@link AgentProfile} always carries both and its `systemPrompt` text always + * comes from the same render as its disclosure metadata. A text-only input + * renders with no disclosed environment facts. Callbacks are bound to the + * input object at runtime, so method-style definitions relying on `this` + * keep working. + */ export type AgentProfileInput = Omit<AgentProfile, 'systemPrompt' | 'renderSystemPrompt'> & ( | { diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileContribution.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileContribution.ts index 8bcb22753..e64cc76ee 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileContribution.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileContribution.ts @@ -1,3 +1,21 @@ +/** + * `agentProfileCatalog` domain — the agent-profile Contribution shape and + * source priorities. + * + * `AgentProfileContribution` is the Contribution of the agent-profile + * extension point: the plain data structure a loader contributes to the + * `AgentProfileContribution` collection under its source id. It is pure + * payload — the source id and priority are record metadata carried alongside + * it, never part of the contribution. Name-level dedup is NOT done here or in + * the registry fold; it is the Session catalog's projection job. + * + * `AGENT_PROFILE_SOURCE_PRIORITY` orders the sources for that projection + * (higher wins name collisions), with one deliberate deviation from the skill + * system: `explicit` outranks every other source (in the skill system it + * aliases `user`) because `--agent-file` is a one-shot command-line intent + * that must always win. + */ + import { collection } from '#/_base/di/collection'; import type { AgentProfile } from './agentProfileCatalog'; diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistry.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistry.ts index cc437795b..d3ae51453 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistry.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistry.ts @@ -1,5 +1,30 @@ +/** + * `agentProfileCatalog` domain — `IAgentProfileRegistry` contract. + * + * The Registry of the Contribution / Registry / Catalog extension-point + * pattern for agent profiles, surfaced as a fold over the + * `AgentProfileContribution` collection (D12): loaders contribute records + * with `this.provide(AgentProfileContribution, …)` — there is no register + * API — and the App-scope fold projects the live collection view into this + * read surface. The fold keeps at most one contribution per (`sourceId`, + * `workspaceKey`) pair — a later record for the same pair shadows the + * earlier one, the old re-register-replaces semantics — which is the only + * dedup this layer performs. Name-level dedup, priority ordering, and the + * builtin-override rule are the Catalog's projection job + * (`ISessionAgentProfileCatalog`), never the registry's. + * + * Bound at App scope so records from ANY scope land in the projection: App + * loaders (builtin) contribute global records (`workspaceKey` absent), while + * each Workspace-scope loader contributes its workspace-local record tagged + * with the handler's `workspaceKey`, and multiple workspaces never collide. + * A record dies with its providing unit — a reload replaces it, a dead + * workspace handler withdraws its records — and withdrawing a shadowed + * record stays silent: a stale contribution can never evict the current + * one. Every projection change fires `onDidChange` with the affected + * (sourceId, workspaceKey) so session catalogs can re-project. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { IDisposable } from '#/_base/di/lifecycle'; import type { Event } from '#/_base/event'; import type { AgentProfileContribution } from './agentProfileContribution'; @@ -21,7 +46,6 @@ export interface IAgentProfileRegistry { readonly onDidChange: Event<AgentProfileRegistryChange>; entries(): readonly AgentProfileRegistration[]; - register(registration: AgentProfileRegistration): IDisposable; } export const IAgentProfileRegistry: ServiceIdentifier<IAgentProfileRegistry> = diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistryService.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistryService.ts index 5cd58efb0..f719e1e47 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistryService.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/agentProfileRegistryService.ts @@ -1,5 +1,20 @@ +/** + * `agentProfileCatalog` domain — `IAgentProfileRegistry` impl: the fold of + * the agent-profile contribution point. + * + * App-scope singleton projecting the live `AgentProfileContribution` + * collection view: storage keys encode the (sourceId, workspaceKey) pair so a + * workspace-local source id (`workspace`, `extra`, `explicit`) coexists + * across handlers, while global sources (`builtin`) appear once; a later + * record for the same pair shadows the earlier one (the old + * re-register-replaces semantics). The fold is pure storage — merging, name + * dedup, and override rules live in the Session-scope catalog projection. + * Change events reproduce the old registry's exactly: a pair fires only when + * its winning record actually changes, so a reload's record swap fires once + * while a shadowed record's withdrawal stays silent. + */ + import { type CollectionChange, type CollectionView } from '#/_base/di/collection'; -import type { IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; import { LifecycleScope } from '#/app/scopes'; @@ -37,7 +52,6 @@ export class AgentProfileRegistryService readonly onDidChange: Event<AgentProfileRegistryChange> = this.onDidChangeEmitter.event; private folded: ReadonlyMap<string, AgentProfileContributionRecord> = new Map(); - private readonly direct = new Map<string, AgentProfileRegistration>(); constructor( @AgentProfileContribution @@ -53,32 +67,12 @@ export class AgentProfileRegistryService } entries(): readonly AgentProfileRegistration[] { - const entries = new Map<string, AgentProfileRegistration>(); - for (const record of this.folded.values()) { - entries.set(encodeKey(record.sourceId, record.workspaceKey), { - sourceId: record.sourceId, - priority: record.priority ?? 0, - workspaceKey: record.workspaceKey, - contribution: record.contribution, - }); - } - for (const [key, registration] of this.direct) entries.set(key, registration); - return [...entries.values()]; - } - - register(registration: AgentProfileRegistration): IDisposable { - const key = encodeKey(registration.sourceId, registration.workspaceKey); - this.direct.set(key, registration); - this.onDidChangeEmitter.fire(decodeKey(key)); - let active = true; - return { - dispose: () => { - if (!active || this.direct.get(key) !== registration) return; - active = false; - this.direct.delete(key); - this.onDidChangeEmitter.fire(decodeKey(key)); - }, - }; + return [...this.folded.values()].map((record) => ({ + sourceId: record.sourceId, + priority: record.priority ?? 0, + workspaceKey: record.workspaceKey, + contribution: record.contribution, + })); } private onViewChange(change: CollectionChange<AgentProfileContributionRecord>): void { diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoader.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoader.ts index 6148fa581..92309c9f1 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoader.ts @@ -1,3 +1,14 @@ +/** + * `agentProfileCatalog` domain — `IBuiltinAgentProfileLoader` contract. + * + * The builtin loader of the agent-profile extension point: owns the global + * `builtin` record (priority 0) of the `AgentProfileContribution` collection + * — the code-defined profiles accumulated at module load via + * `registerAgentProfile(...)`. Also exposes the static `get` / `getDefault` / + * `list` read view for loader-time consumers that need the builtin default + * before any session catalog exists. App-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { AgentProfile } from './agentProfileCatalog'; diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoaderService.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoaderService.ts index 7f90d53e7..81fb522ab 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/builtinAgentProfileLoaderService.ts @@ -1,3 +1,17 @@ +/** + * `agentProfileCatalog` domain — `IBuiltinAgentProfileLoader` implementation. + * + * Snapshots the module-level contributions (`registerAgentProfile`, the + * "import = register" pattern) on construction and contributes them to the + * `AgentProfileContribution` collection as the global `builtin` record. + * Register-after-construction is not supported: like + * `IAgentToolRegistryService`, contributions are expected to accumulate at + * import time before the container resolves the service. `getDefault()` + * throws a `BugIndicatingError` when the builtin default profile is missing — a + * programming-time invariant violation, not a request failure. Bound at App + * scope. + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; @@ -18,6 +32,7 @@ import { } from './builtinAgentProfileLoader'; import { getAgentProfileContributions } from './contribution'; +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class BuiltinAgentProfileLoaderService extends Disposable implements IBuiltinAgentProfileLoader diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/contribution.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/contribution.ts index ab3ae7d27..ec7e32721 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/contribution.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/contribution.ts @@ -1,3 +1,16 @@ +/** + * `agentProfileCatalog` domain — module-level profile contribution registry. + * + * Profiles contribute themselves at module load via `registerAgentProfile(def)`, + * the same "import = register" pattern used by `registerAgentToolService` for tools + * and `registerScopedService` for DI. Uniqueness is enforced by `name`: + * later-registered profiles with the same name replace earlier ones, so tests + * can override built-ins by re-registering. Registration normalizes each + * definition through `normalizeAgentProfile`, so authors write at least one + * render entry (the structured renderer wins when both are given) while + * consumers always see both. + */ + import { normalizeAgentProfile, type AgentProfile, diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/profile-shared.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/profile-shared.ts index 5321d24c1..e0584de8f 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/profile-shared.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/profile-shared.ts @@ -1,13 +1,41 @@ +/** + * `agentProfileCatalog` domain — shared prompt helpers for builtin profiles. + * + * Keeps the base system-prompt template and the task-agent role prefix in the + * agent-profile domain. + * + * All system-prompt rendering — the builtin template, `SYSTEM.md`, and agent + * files — shares one `${var}` substitution pass over one variable table + * ({@link systemPromptVars}); unknown placeholders stay verbatim. Conditional + * sections (Windows notes, additional directories, skills, plugin + * instructions) are composed here + * as pre-rendered blocks because the renderer has no conditional syntax. Raw + * context fields render as empty strings when missing and the composed + * `*_section` / `windows_notes` blocks are empty unless their content exists, + * so templates can place them on their own line without leaving stray + * headings behind. Host-identity blocks (`product_name`, `reply_style_guide`) + * work the same way: the context may carry overrides seeded by the embedding + * host (e.g. a desktop app), and the table falls back to the CLI defaults + * ({@link DEFAULT_PRODUCT_NAME}, {@link DEFAULT_REPLY_STYLE_GUIDE}) when it + * does not. `renderPromptTemplateResult` renders a user-owned template (an + * agent-file body or `SYSTEM.md`) against the table; `${base_prompt}` is + * bound to the default profile's prompt when a `basePrompt` is given, + * resolved lazily and only when the template actually references it. Also + * shared: `skillActiveFor` (whether the Skill tool survives a profile's tool + * list — drives skills injection) and the `subagents`-allowlist helpers + * (`subagentAllowlistFor`, `subagentTypeNotAllowedMessage`). Structured + * renderers also carry disclosure metadata so runtime reminders never need to + * parse the rendered text. + */ + import { renderPrompt } from '#/_base/utils/render-prompt'; import { - DEFAULT_AGENT_PROFILE_NAME, type AgentProfile, type AgentProfileContext, type EnvironmentDisclosureSnapshot, type SystemPromptRenderResult, } from './agentProfileCatalog'; -import { BUILTIN_AGENT_PROFILE_SOURCE_ID } from './builtinAgentProfileLoader'; import SYSTEM_PROMPT_TEMPLATE from './system.md?raw'; @@ -29,68 +57,8 @@ export function subagentAllowlistFor( readonly profileName?: string; readonly subagents?: readonly string[]; }, - extras?: readonly string[], ): readonly string[] | undefined { - const declared = caller.subagents ?? catalog.getDefault().subagents; - if (declared?.length === 1 && declared[0] === '*') return undefined; - if (extras === undefined || extras.length === 0) return declared; - return [...new Set([...(declared ?? []), ...extras])]; -} - -export function isDiscoveredAgentProfileSource(sourceId: string | undefined): boolean { - return ( - sourceId !== undefined && - sourceId !== BUILTIN_AGENT_PROFILE_SOURCE_ID && - !sourceId.startsWith('feature:') - ); -} - -export function rootDelegationExtras( - catalog: { - inspect(name: string): { readonly sourceId: string } | undefined; - }, - caller: { - readonly profileName?: string; - readonly subagents?: readonly string[]; - }, - profiles: readonly { readonly name: string }[], -): readonly string[] | undefined { - if ( - caller.profileName !== undefined && - caller.profileName !== DEFAULT_AGENT_PROFILE_NAME && - caller.subagents !== undefined - ) { - return undefined; - } - const discovered = profiles - .filter( - (profile) => - profile.name !== DEFAULT_AGENT_PROFILE_NAME && - isDiscoveredAgentProfileSource(catalog.inspect(profile.name)?.sourceId), - ) - .map((profile) => profile.name); - return discovered.length === 0 ? undefined : discovered; -} - -export function profileCanDelegate( - profile: Pick<AgentProfile, 'tools' | 'disallowedTools'>, -): boolean { - const possesses = (name: string) => - (profile.tools === undefined || profile.tools.includes(name)) && - !(profile.disallowedTools ?? []).includes(name); - return possesses('Agent') || possesses('AgentSwarm'); -} - -export function withoutDelegatingTargets( - catalog: { - get(name: string): Pick<AgentProfile, 'tools' | 'disallowedTools'> | undefined; - }, - allowlist: readonly string[], -): readonly string[] { - return allowlist.filter((name) => { - const target = catalog.get(name); - return target === undefined || !profileCanDelegate(target); - }); + return caller.profileName === undefined ? catalog.getDefault().subagents : caller.subagents; } export function subagentTypeNotAllowedMessage( diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/promptPrefix.ts b/packages/agent-core-v2/src/app/agentProfileCatalog/promptPrefix.ts index 11e5a365e..233e3ef4e 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/promptPrefix.ts +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/promptPrefix.ts @@ -1,3 +1,11 @@ +/** + * `agentProfileCatalog` domain — profile prompt-prefix helper. + * + * Applies a profile's optional per-invocation `promptPrefix` (e.g. `explore`'s + * `<git-context>` block) to a caller-supplied prompt. Best-effort: a thrown + * error or empty prefix leaves the prompt unchanged. + */ + import type { AgentProfile, AgentProfilePromptPrefixContext, diff --git a/packages/agent-core-v2/src/app/agentProfileCatalog/system.md b/packages/agent-core-v2/src/app/agentProfileCatalog/system.md index 3e6b56cf9..b8553cad9 100644 --- a/packages/agent-core-v2/src/app/agentProfileCatalog/system.md +++ b/packages/agent-core-v2/src/app/agentProfileCatalog/system.md @@ -1,6 +1,6 @@ You are ${product_name}, an interactive general AI agent running on a user's computer. -Your primary goal is to help users with software engineering tasks. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. +Your primary goal is to help users with software engineering tasks by taking action — use the tools available to you to make real changes on the user's system. You should also answer questions when asked. Always adhere strictly to the following system instructions and the user's requirements. ${role_additional} @@ -12,7 +12,9 @@ Keep code, commands, identifiers, file paths, and technical terms in their origi # Prompt and Tool Use -When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. +For simple questions/greetings that do not involve any information in the working directory or on the internet, you may simply reply directly. For anything else, default to taking action with tools. When the request could be interpreted as either a question to answer or a task to complete, treat it as a task. For instance, "change `methodName` to snake_case" is a task, not a question — locate the method in the code and edit it; do not just reply with `method_name`. + +When handling the user's request, if it involves creating, modifying, or running code or files, you MUST use the appropriate tools available to you to make actual changes — do not just describe the solution in text. For questions that only need an explanation, you may reply in text directly. When calling tools, do not provide detailed explanations or chain-of-thought. For simple requests, call tools directly. For non-trivial or multi-step tasks, first emit one short user-visible sentence describing what you will do next, then call the tool(s). Keep that sentence to roughly 8–10 words, plain and concrete — for example, "Next, I'll patch the config and update the related tests." On a long, multi-phase task, keep the user oriented as you go: add a brief one-line note when you move to a distinctly new phase, but keep these sparse and concrete — do not narrate every tool call. When a dedicated tool fits the job, reach for it before raw shell: `Read` a known path, `Glob` to find files by name, and `Grep` to search file contents. These resolve paths through the workspace access policy and cap their output, so they keep large raw dumps out of the conversation. @@ -80,7 +82,7 @@ The operating environment is not in a sandbox. Any actions you do will immediate ## Date and Time -The current date is disclosed through reminders: one appears at the start of the conversation, and another whenever the date changes. Rely on the latest such reminder rather than any earlier date statement. Reminders carry only the date — whenever the precise current time matters (web-result freshness, age or expiry checks, anything time-sensitive), get it fresh from the environment, for example by running `date` if you have a shell tool. +The current date and time in ISO format is `${now}`. This was captured when the session started and does not update as the session continues, so in a long or resumed session it may be hours or days stale. Treat it only as a rough reference; whenever the real current time matters (web-result freshness, age or expiry checks, anything time-sensitive), get it fresh from the environment — for example by running `date` if you have a shell tool — instead of trusting this value. ## Working Directory @@ -117,10 +119,13 @@ At any time, you should be HELPFUL, CONCISE, ACCURATE, and CANDID. Be thorough i - Try your best to avoid any hallucination. Do fact checking before providing any factual information. - Think about the best approach, then take action decisively. - Do not give up too early. +- Default to making progress, not to asking: once the goal is clear and you have the user's go-ahead to act on it, carry it through and work blockers yourself; ask only when the user's answer would actually change your next step. This never overrides the rule to stop and discuss when the goal is unclear, or to wait for explicit instruction before writing code. - ALWAYS, keep it stupidly simple. Do not overcomplicate things. - Talk like a seasoned engineer, not a cheerleader. Skip flattery, motivational filler, and hollow reassurance — the user wants the work done, not to be impressed. A correct, plainly-stated answer respects them more than praise does. - Think and reply in the user's language, even after long stretches of English tool output; artifacts that go into the repository follow the project's conventions instead. - When you have evidence the user is wrong, say so and show the evidence — agreeing to be agreeable wastes their time and can break their code. Defer once they've decided; until then, an honest objection is the helpful answer. +- When the task requires creating or modifying files, always use tools to do so. Never treat displaying code in your response as a substitute for actually writing it to the file system. +- Deliver the complete change. Never stub out code with placeholders like `// ... rest unchanged` or leave the user to fill in the gaps; write out every line you mean to change. - After a change, sweep for comments and docstrings that now describe the old behavior, and bring them in line with what the code actually does. - Before calling a task done, verify it: run the checks that cover your change and look at the result instead of assuming. Don't mark work complete while tests are red or the implementation is still partial — this holds whether or not you are tracking the work in a todo list. - When the context fills up it is compacted automatically, so you may suddenly see a summary of the work so far in place of the full thread. Assume compaction happened while you were working: continue naturally from the summary instead of restarting, and make reasonable assumptions about anything it omits rather than redoing settled work. Treat any "done" it reports as unverified until you re-check. diff --git a/packages/agent-core-v2/src/app/auth/auth.ts b/packages/agent-core-v2/src/app/auth/auth.ts index 19e6dedb2..812b32677 100644 --- a/packages/agent-core-v2/src/app/auth/auth.ts +++ b/packages/agent-core-v2/src/app/auth/auth.ts @@ -1,3 +1,15 @@ +/** + * `auth` domain (cross-cutting) — app-scope OAuth + auth summary contracts. + * + * Defines the public contracts of authentication: the `AuthStatus` model, the + * `IOAuthService` used to drive device-code login / logout / flow inspection, + * to resolve a per-provider `BearerTokenProvider`, and to refresh a managed + * OAuth provider's server-side model configuration, the `IOAuthToolkit` + * device-code client that `IOAuthService` delegates the OAuth protocol to, and + * the `IAuthSummaryService` used to summarize auth state and provide the + * prompt auth-readiness gate. App-scoped — shared across the application. + */ + import type { AuthManagedUserInfoResult, AuthManagedUsageResult, @@ -6,7 +18,6 @@ import type { KimiOAuthLoginResult, KimiOAuthLogoutResult, KimiOAuthTokenRef, - KimiRegion, } from '@moonshot-ai/kimi-code-oauth'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Error2 } from '#/_base/errors/errors'; @@ -27,14 +38,10 @@ export interface AuthStatus { readonly provider?: string; } -export interface OAuthLoginOptions { - readonly region?: KimiRegion; -} - export interface IOAuthService { readonly _serviceBrand: undefined; - startLogin(provider?: string, options?: OAuthLoginOptions): Promise<OAuthFlowStart>; + startLogin(provider?: string): Promise<OAuthFlowStart>; getFlow(provider?: string): OAuthFlowSnapshot | undefined; cancelLogin(provider?: string): Promise<OAuthLoginCancelResponse>; logout(provider?: string): Promise<OAuthLogoutResponse>; @@ -44,7 +51,6 @@ export interface IOAuthService { getManagedUserInfo(provider?: string): Promise<AuthManagedUserInfoResult>; resolveTokenProvider(provider: string, oauthRef?: OAuthRef): BearerTokenProvider | undefined; getCachedAccessToken(provider: string, oauthRef?: OAuthRef): Promise<string | undefined>; - getRegion(): KimiRegion; } export const IOAuthService: ServiceIdentifier<IOAuthService> = diff --git a/packages/agent-core-v2/src/app/auth/authService.ts b/packages/agent-core-v2/src/app/auth/authService.ts index 7960271da..ebffcea60 100644 --- a/packages/agent-core-v2/src/app/auth/authService.ts +++ b/packages/agent-core-v2/src/app/auth/authService.ts @@ -1,3 +1,17 @@ +/** + * `auth` domain (cross-cutting) — `IOAuthService` / `IAuthSummaryService` + * implementation. + * + * Owns the device-code OAuth flows and the auth readiness view; reads and + * writes provider configuration through `provider`, refreshes the managed + * OAuth provider's server-side model configuration through `config`, publishes + * model-catalog changes through `event`, reports through `telemetry`, + * logs through `log`, and delegates + * the device-code protocol, token storage, and token refresh to `IOAuthToolkit` + * (provided by `OAuthToolkitService` over `@moonshot-ai/kimi-code-oauth`, + * which locates token storage through `bootstrap`). Bound at App scope. + */ + import { randomUUID } from 'node:crypto'; import { @@ -6,7 +20,6 @@ import { KIMI_CODE_PROVIDER_NAME, KimiOAuthToolkit, kimiCodeBaseUrl, - kimiRegionLoginHosts, OAuthError, applyManagedKimiCodeConfig, clearManagedKimiCodeConfig, @@ -14,12 +27,10 @@ import { resolveKimiCodeLoginAuth, resolveKimiCodeOAuthRef, resolveKimiCodeRuntimeAuth, - resolveKimiRegion, type AuthManagedUserInfoResult, type AuthManagedUsageResult, type BearerTokenProvider, type DeviceAuthorization, - type KimiRegion, type ManagedKimiConfigShape, } from '@moonshot-ai/kimi-code-oauth'; import type { @@ -53,7 +64,6 @@ import { PROVIDERS_SECTION, THINKING_SECTION, } from '#/app/kosongConfig/configSection'; -import { ModelCatalogChanged } from '#/app/kosongConfig/discovery'; import { IProviderService, type OAuthRef, @@ -71,7 +81,6 @@ import { IAuthSummaryService, IOAuthService, IOAuthToolkit, - type OAuthLoginOptions, } from './auth'; const TERMINAL_RETENTION_MS = 5 * 60 * 1000; @@ -92,6 +101,7 @@ interface FlowState { resolvedAt: string | undefined; } +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class OAuthService extends Disposable implements IOAuthService { declare readonly _serviceBrand: undefined; private readonly flows = new Map<string, FlowState>(); @@ -105,7 +115,6 @@ export class OAuthService extends Disposable implements IOAuthService { @ITelemetryService private readonly telemetry: ITelemetryService, @ILogService private readonly log: ILogService, @IEventService private readonly events: IEventService, - @IBootstrapService private readonly bootstrap: IBootstrapService, ) { super(); this._register(providerService.onDidChangeProviders((event) => { @@ -113,12 +122,9 @@ export class OAuthService extends Disposable implements IOAuthService { })); } - async startLogin( - provider = KIMI_CODE_PROVIDER_NAME, - options: OAuthLoginOptions = {}, - ): Promise<OAuthFlowStart> { + async startLogin(provider = KIMI_CODE_PROVIDER_NAME): Promise<OAuthFlowStart> { this.log.info('oauth startLogin: enter', { provider }); - const loginAuth = this.resolveLoginAuth(provider, options.region); + const loginAuth = this.resolveLoginAuth(provider); this.log.info('oauth startLogin: resolved login auth', { provider, hasOAuthRef: loginAuth.oauthRef !== undefined, @@ -375,7 +381,7 @@ export class OAuthService extends Disposable implements IOAuthService { const result = { changed, unchanged, failed }; if (result.changed.length > 0) { - this.events.publish(new ModelCatalogChanged({ payload: result })); + this.events.publish({ type: 'event.model_catalog.changed', payload: result }); } return result; } @@ -398,22 +404,7 @@ export class OAuthService extends Disposable implements IOAuthService { }; } - getRegion(): KimiRegion { - const oauth = this.providerService.get(KIMI_CODE_PROVIDER_NAME)?.oauth; - return resolveKimiRegion({ - configuredOAuthHost: oauth?.oauthHost, - configuredOAuthKey: oauth?.key, - readMarker: - (this.bootstrap.getEnv('KIMI_CODE_REGION_MARKER') ?? - process.env['KIMI_CODE_REGION_MARKER']) !== 'off', - homeDir: this.bootstrap.homeDir, - }); - } - - private resolveLoginAuth( - provider: string, - region?: KimiRegion, - ): { + private resolveLoginAuth(provider: string): { readonly oauthRef: OAuthRef | undefined; readonly baseUrl: string | undefined; readonly oauthHost: string | undefined; @@ -422,12 +413,9 @@ export class OAuthService extends Disposable implements IOAuthService { if (provider !== KIMI_CODE_PROVIDER_NAME) { return { oauthRef: config?.oauth, baseUrl: undefined, oauthHost: undefined }; } - const hosts = region === undefined ? undefined : kimiRegionLoginHosts(region); const loginAuth = resolveKimiCodeLoginAuth({ configuredBaseUrl: config?.baseUrl, configuredOAuthRef: config?.oauth, - requestedBaseUrl: hosts?.baseUrl, - requestedOAuthHost: hosts?.oauthHost, }); const oauthRef = loginAuth.oauthRef ?? diff --git a/packages/agent-core-v2/src/app/auth/configSection.ts b/packages/agent-core-v2/src/app/auth/configSection.ts index 9c035298a..bc63c9eb0 100644 --- a/packages/agent-core-v2/src/app/auth/configSection.ts +++ b/packages/agent-core-v2/src/app/auth/configSection.ts @@ -1,3 +1,26 @@ +/** + * `auth` domain — `services` config-section schema, TOML transforms, and + * env bindings. + * + * Owns the `[services]` configuration section (`moonshot_search` / + * `moonshot_fetch`), mirroring v1's `ServicesConfigSchema`: the schema, and the + * snake_case ↔ camelCase TOML transforms (including the nested `oauth` and + * `custom_headers` normalization, with `custom_headers` record keys preserved + * verbatim). Both entries' `base_url` / `api_key` are env-overridable + * (`KIMI_WEB_SEARCH_*` / `KIMI_WEB_FETCH_*`, env wins over the file). Its + * effective overlay treats an env base URL as a new credential boundary and + * prevents persisted API keys, OAuth refs, or custom headers from crossing + * into that endpoint; the composed `stripEnv` keeps env-derived values from + * being persisted. + * Self-registered at module load via `registerConfigSection`, so the + * `config` domain never imports this domain's types. + * + * The `auth` domain owns this section because its OAuth login/logout flows + * provision and clear it, and its `WebSearchProviderService` + * consumes `moonshot_search`; the `web` domain reads `moonshot_fetch` from the + * same section. Bound at App scope. + */ + import { z } from 'zod'; import { diff --git a/packages/agent-core-v2/src/app/auth/errors.ts b/packages/agent-core-v2/src/app/auth/errors.ts index 331503db0..e6d1a5812 100644 --- a/packages/agent-core-v2/src/app/auth/errors.ts +++ b/packages/agent-core-v2/src/app/auth/errors.ts @@ -1,3 +1,7 @@ +/** + * `auth` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const AuthErrors = { diff --git a/packages/agent-core-v2/src/app/auth/oauthProtocol.ts b/packages/agent-core-v2/src/app/auth/oauthProtocol.ts index cb31534da..7c48107aa 100644 --- a/packages/agent-core-v2/src/app/auth/oauthProtocol.ts +++ b/packages/agent-core-v2/src/app/auth/oauthProtocol.ts @@ -1,7 +1,16 @@ +/** + * `auth` domain — the v1 OAuth wire DTO schemas. + * + * Request/response shapes of the v1 `/oauth/*` endpoints plus the managed + * OAuth provider model-refresh response, defined as zod schemas so the + * transports validate against a shared contract. New endpoints use the + * camelCase domain contract owned by the oauth package (re-exported below); + * legacy snake_case schemas stay local. + */ + import { z } from 'zod'; import { isoDateTimeSchema } from '#/_base/utils/isoDateTime'; -import { kimiRegionSchema } from '@moonshot-ai/kimi-code-oauth'; export const oauthFlowStatusEnum = z.enum([ 'pending', @@ -65,11 +74,6 @@ export const oauthLogoutResponseSchema = z.object({ }); export type OAuthLogoutResponse = z.infer<typeof oauthLogoutResponseSchema>; -export const oauthRegionResultSchema = z.object({ - region: kimiRegionSchema, -}); -export type OAuthRegionResult = z.infer<typeof oauthRegionResultSchema>; - const providerRefreshChangeSchema = z.object({ provider_id: z.string().min(1), provider_name: z.string().min(1), @@ -91,6 +95,7 @@ export type RefreshOAuthProviderModelsResponse = z.infer< typeof refreshOAuthProviderModelsResponseSchema >; + export const usageWindowSchema = z.object({ duration: z.number().int(), unit: z.enum(['minute', 'hour', 'day', 'week']), @@ -137,6 +142,7 @@ export const managedUsageResultSchema = z.discriminatedUnion('kind', [ ]); export type ManagedUsageResult = z.infer<typeof managedUsageResultSchema>; + export { managedUserInfoResultSchema, type ManagedUserInfoResult, diff --git a/packages/agent-core-v2/src/app/auth/webSearch/webSearch.ts b/packages/agent-core-v2/src/app/auth/webSearch/webSearch.ts index e3b56f368..73dbdf500 100644 --- a/packages/agent-core-v2/src/app/auth/webSearch/webSearch.ts +++ b/packages/agent-core-v2/src/app/auth/webSearch/webSearch.ts @@ -1,3 +1,15 @@ +/** + * `auth` domain (cross-cutting) — OAuth-backed web search seam. + * + * Owns the seam for the `WebSearch` backend, which needs an authenticated + * Moonshot search provider. `IWebSearchProviderService` exposes the + * configured `WebSearchProvider` (or `undefined` when search is not + * configured), and `hasWebSearchProvider` answers presence alone — for tool + * activation gates, which may run before the identity snapshot the composed + * provider embeds has frozen. Tests and hosts that need a custom backend bind + * `IWebSearchProviderService` directly. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { WebSearchProvider } from '#/agent/tools/web-search/web-search'; diff --git a/packages/agent-core-v2/src/app/auth/webSearch/webSearchService.ts b/packages/agent-core-v2/src/app/auth/webSearch/webSearchService.ts index 39960ac16..087ac2714 100644 --- a/packages/agent-core-v2/src/app/auth/webSearch/webSearchService.ts +++ b/packages/agent-core-v2/src/app/auth/webSearch/webSearchService.ts @@ -1,3 +1,26 @@ +/** + * `auth` domain (cross-cutting) — `IWebSearchProviderService` implementation. + * + * Resolves the `WebSearch` backend from two sources, in precedence order: + * (1) an explicit `[services.moonshot_search]` config section (read through + * `config`) — built with its `apiKey` and/or an `oauth` ref resolved + * through `IOAuthService.resolveTokenProvider(...)`; and (2) the managed Kimi + * OAuth provider (`managed:kimi-code`) when it carries an `oauth` ref (the + * state after a successful Kimi login), whose bearer token comes from + * `IOAuthService.resolveTokenProvider(...)` and whose base URL is derived from + * the provider's `baseUrl`. The explicit config wins over the managed + * derivation. When neither source is configured it yields `undefined`. + * Tests and hosts that need a custom backend bind `IWebSearchProviderService` + * directly. Bound at App scope. + * + * Default headers split by who chose the endpoint: a `[services]` entry names + * its own, so that path sends `agentIdentity`'s frozen `requestHeaders` — the + * host header set with the `User-Agent` product token rewritten to the + * configured identity — while the managed OAuth path sends the host's own + * headers (`IBootstrapService.args.requestHeaders`) verbatim, being the + * endpoint the session authenticated against. + */ + import { KIMI_CODE_PROVIDER_NAME, kimiCodeBaseUrl, diff --git a/packages/agent-core-v2/src/app/authLegacy/authLegacy.ts b/packages/agent-core-v2/src/app/authLegacy/authLegacy.ts index fafcef373..7cb1e101a 100644 --- a/packages/agent-core-v2/src/app/authLegacy/authLegacy.ts +++ b/packages/agent-core-v2/src/app/authLegacy/authLegacy.ts @@ -1,3 +1,13 @@ +/** + * `authLegacy` domain (L7 edge adapter) — v1-compatible auth readiness summary. + * + * Implements the `GET /api/v1/auth` `AuthSummary` wire contract on top of the + * native v2 services (`IProviderService`, `IConfigService`, `IOAuthService`). + * This adapter exists only so v1 clients keep working against server-v2. + * Bound at App scope — it is a stateless projector over the global provider / + * model / credential state. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/app/authLegacy/authLegacyService.ts b/packages/agent-core-v2/src/app/authLegacy/authLegacyService.ts index b80e2c9d0..1adede3e5 100644 --- a/packages/agent-core-v2/src/app/authLegacy/authLegacyService.ts +++ b/packages/agent-core-v2/src/app/authLegacy/authLegacyService.ts @@ -1,3 +1,14 @@ +/** + * `authLegacy` domain — `IAuthLegacyService` implementation. + * + * Stateless App-scope projector: reads the configured providers through + * `provider`, the global default-model selection through `model` (the + * kosong registry is the runtime source of truth; config is only its + * persistence), and the managed OAuth provider's cached-token state through + * `auth`, then assembles the v1 `AuthSummary` so the `/api/v1/auth` envelope + * is byte-compatible. + */ + import { KIMI_CODE_PROVIDER_NAME } from '@moonshot-ai/kimi-code-oauth'; import type { AuthSummary } from './authLegacy'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/app/bashParser/bashParser.ts b/packages/agent-core-v2/src/app/bashParser/bashParser.ts index 467c29f06..83a4f1503 100644 --- a/packages/agent-core-v2/src/app/bashParser/bashParser.ts +++ b/packages/agent-core-v2/src/app/bashParser/bashParser.ts @@ -1,3 +1,17 @@ +/** + * `bashParser` domain — bash source parsing capability. + * + * Defines the `IBashParserService` that parses a bash source string into a + * syntax tree through the pure `@moonshot-ai/tree-sitter-bash` package, plus + * the wire-safe DTO types it returns: `BashSyntaxNode` drops the cyclic + * `parent` link so results can cross the RPC boundary, and offsets are + * UTF-16 code units (`text` always equals `source.slice(start, end)`). The + * parse runs under a deterministic budget — budget exhaustion yields + * `{ ok: false, reason: 'aborted' }` and malformed input yields + * `hasError: true`, never a throw; callers that cannot analyze a command + * must degrade on either signal. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface BashSyntaxNode { diff --git a/packages/agent-core-v2/src/app/bashParser/bashParserService.ts b/packages/agent-core-v2/src/app/bashParser/bashParserService.ts index a99bae49c..52ac2b969 100644 --- a/packages/agent-core-v2/src/app/bashParser/bashParserService.ts +++ b/packages/agent-core-v2/src/app/bashParser/bashParserService.ts @@ -1,3 +1,17 @@ +/** + * `bashParser` domain — `IBashParserService` implementation. + * + * Thin adapter over the pure `@moonshot-ai/tree-sitter-bash` package: runs + * its budgeted `parse` and snapshots the returned tree into the wire-safe + * `BashSyntaxNode` DTO (source-ordered children including anonymous tokens, + * `parent` links dropped). The snapshot is iterative (explicit stack): a + * long left-associative chain (e.g. `$((1+1+...))` with thousands of + * operands) produces a tree + * thousands of levels deep, and a recursive walk would overflow the call + * stack and throw `RangeError`, breaking the never-throws contract. Owns no + * state and injects no services. Bound at App scope. + */ + import { parse } from '@moonshot-ai/tree-sitter-bash'; import type { SyntaxNode } from '@moonshot-ai/tree-sitter-bash'; import { LifecycleScope } from '#/app/scopes'; diff --git a/packages/agent-core-v2/src/app/bootstrap/bootstrap.ts b/packages/agent-core-v2/src/app/bootstrap/bootstrap.ts index 9b43c978c..f80aff2e1 100644 --- a/packages/agent-core-v2/src/app/bootstrap/bootstrap.ts +++ b/packages/agent-core-v2/src/app/bootstrap/bootstrap.ts @@ -1,3 +1,22 @@ +/** + * `bootstrap` domain — frozen startup snapshot and composition root. + * + * Defines the `IBootstrapService`, the snapshot of the world the process runs + * in, resolved once at startup and frozen for the process: observed host facts + * (`platform`, `arch`, `cwd`, `osHomeDir`, `getEnv`, `clientIdentity`), the + * app path layout (`homeDir`, `configPath`, …), and the host's process-level + * invocation arguments (`args` — mirroring VS Code's `NativeParsedArgs` + * carried on the environment service: the host states them once in + * `BootstrapInput`; downstream services read them here instead of through + * per-domain runtime-options services). `resolveBootstrapOptions` is + * the single place that reads `process.env` / `os.homedir()` / invocation + * input to resolve the snapshot; everything downstream reads from + * `IBootstrapService` instead of touching `process` directly. Bound at App + * scope. Also seeds the `IFileSystemStorageService` with a `FileStorageService` + * rooted at `homeDir` so the byte layer (and every Store above it) persists + * to disk. + */ + import { mkdirSync } from 'node:fs'; import { homedir } from 'node:os'; @@ -12,8 +31,8 @@ import { IFileSystemStorageService, } from '#/persistence/interface/storage'; import { FileStorageService } from '#/persistence/backends/node-fs/fileStorageService'; -import { FileSkillDiscovery } from '#/features/skill/catalog/fileSkillDiscovery'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; +import { FileSkillDiscovery } from '#/app/skillCatalog/fileSkillDiscovery'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; export interface HostArgs { readonly agentFiles?: readonly string[]; @@ -63,7 +82,8 @@ export type PersistenceScopeName = | 'store' | 'logs' | 'cache' - | 'credentials'; + | 'credentials' + | 'cron'; export interface IBootstrapService { readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/app/bootstrap/bootstrapService.ts b/packages/agent-core-v2/src/app/bootstrap/bootstrapService.ts index 440a087cb..711e67c1b 100644 --- a/packages/agent-core-v2/src/app/bootstrap/bootstrapService.ts +++ b/packages/agent-core-v2/src/app/bootstrap/bootstrapService.ts @@ -1,3 +1,14 @@ +/** + * `bootstrap` domain — `IBootstrapService` implementation. + * + * Holds the resolved startup snapshot from the seeded `IBootstrapOptions` and + * exposes the host facts, app path layout, and top-level scope mapping. All + * `scope(name)` values and `configKey` are computed once at construction so + * business code can read them synchronously. + * + * Bound at App scope. + */ + import { basename, join, relative } from 'pathe'; import type { KimiHostIdentity } from '@moonshot-ai/kimi-code-oauth'; @@ -56,6 +67,7 @@ export class BootstrapService implements IBootstrapService { logs: relative(options.homeDir, this.logsDir), cache: relative(options.homeDir, this.cacheDir), credentials: 'credentials', + cron: 'cron', }; } diff --git a/packages/agent-core-v2/src/app/capability/capability.ts b/packages/agent-core-v2/src/app/capability/capability.ts index 19d266cfc..15056fe0a 100644 --- a/packages/agent-core-v2/src/app/capability/capability.ts +++ b/packages/agent-core-v2/src/app/capability/capability.ts @@ -1,15 +1,19 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; +/** + * `capability` domain (L3) — `ICapabilityService` contract. + * + * Manages the built-in product capabilities (`kimi-cu`, `kimi-webbridge`): + * layered readiness detection and idempotent install orchestration. Entries + * are hardcoded in a closed registry — install sources are fixed official + * CDN URLs, never client-supplied. + */ -import type { CapabilityDescriptor, CapabilityInstallChange, CapabilityStatus } from './types'; +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +import type { CapabilityStatus } from './types'; export interface ICapabilityService { readonly _serviceBrand: undefined; - readonly onDidChangeInstall: Event<CapabilityInstallChange>; - - describeCapabilities(): readonly CapabilityDescriptor[]; - listCapabilities(): Promise<readonly CapabilityStatus[]>; getCapability(id: string): Promise<CapabilityStatus>; diff --git a/packages/agent-core-v2/src/app/capability/capabilityEvents.ts b/packages/agent-core-v2/src/app/capability/capabilityEvents.ts deleted file mode 100644 index f152a4c96..000000000 --- a/packages/agent-core-v2/src/app/capability/capabilityEvents.ts +++ /dev/null @@ -1,16 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -import type { CapabilityId, CapabilityInstallProgress } from './types'; - -export interface CapabilityChangedPayload { - readonly capability_id: CapabilityId; - readonly install: CapabilityInstallProgress; -} - -export class CapabilityChanged extends Event2<{ readonly payload: CapabilityChangedPayload }> { - static override readonly type = 'event.capability.changed'; -} -export interface CapabilityChanged { - readonly payload: CapabilityChangedPayload; -} diff --git a/packages/agent-core-v2/src/app/capability/capabilityService.ts b/packages/agent-core-v2/src/app/capability/capabilityService.ts index c89afba60..8c42563ac 100644 --- a/packages/agent-core-v2/src/app/capability/capabilityService.ts +++ b/packages/agent-core-v2/src/app/capability/capabilityService.ts @@ -1,16 +1,22 @@ -import { homedir } from 'node:os'; +/** + * `capability` domain (L3) — `ICapabilityService` implementation. + * + * Holds the closed registry of built-in capability entries and serializes + * install runs per entry. Install progress lives in memory only and is + * polled by clients; a failed attempt leaves its error in the progress state + * until the next attempt starts and logs the failure through `log`. Listing + * degrades a single entry's failing detection to a failed step on that entry + * instead of rejecting the whole list. Bound at App scope. + */ -import { KIMI_CODE_PROVIDER_NAME, resolveKimiRegion } from '@moonshot-ai/kimi-code-oauth'; +import { homedir } from 'node:os'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { Disposable } from '#/_base/di/lifecycle'; -import { Emitter, type Event } from '#/_base/event'; import { ILogService } from '#/_base/log/log'; import { Error2 } from '#/errors'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IPluginService } from '#/app/plugin/plugin'; -import { IProviderService } from '#/kosong/provider/provider'; import { IHostProcessService } from '#/os/interface/hostProcess'; import { ICapabilityService } from './capability'; @@ -20,8 +26,6 @@ import { createKimiWebbridgeEntry } from './entries/kimiWebbridge'; import type { CapabilityEntry, CapabilityId, - CapabilityDescriptor, - CapabilityInstallChange, CapabilityInstallProgress, CapabilityReadiness, CapabilityStatus, @@ -29,33 +33,20 @@ import type { const IDLE_PROGRESS: CapabilityInstallProgress = { running: false }; -export class CapabilityService extends Disposable implements ICapabilityService { +export class CapabilityService implements ICapabilityService { declare readonly _serviceBrand: undefined; - private readonly onDidChangeInstallEmitter = this._register( - new Emitter<CapabilityInstallChange>(), - ); - readonly onDidChangeInstall: Event<CapabilityInstallChange> = - this.onDidChangeInstallEmitter.event; - private readonly entries: ReadonlyMap<CapabilityId, CapabilityEntry>; private readonly installProgress = new Map<CapabilityId, CapabilityInstallProgress>(); private readonly runningInstalls = new Set<CapabilityId>(); - private setInstallProgress(id: CapabilityId, progress: CapabilityInstallProgress): void { - this.installProgress.set(id, progress); - this.onDidChangeInstallEmitter.fire({ id, install: progress }); - } - constructor( @IBootstrapService bootstrap: IBootstrapService, @IPluginService plugins: IPluginService, @IHostProcessService hostProcess: IHostProcessService, @ILogService private readonly log: ILogService, - @IProviderService providers: IProviderService, entriesOverride?: readonly CapabilityEntry[], ) { - super(); if (entriesOverride !== undefined) { this.entries = new Map(entriesOverride.map((entry) => [entry.id, entry])); } else { @@ -66,17 +57,6 @@ export class CapabilityService extends Disposable implements ICapabilityService userHomeDir: homedir(), plugins, hostProcess, - resolveRegion: () => { - const oauth = providers.get(KIMI_CODE_PROVIDER_NAME)?.oauth; - return resolveKimiRegion({ - configuredOAuthHost: oauth?.oauthHost, - configuredOAuthKey: oauth?.key, - readMarker: - (bootstrap.getEnv('KIMI_CODE_REGION_MARKER') ?? - process.env['KIMI_CODE_REGION_MARKER']) !== 'off', - homeDir: bootstrap.homeDir, - }); - }, }; this.entries = new Map<CapabilityId, CapabilityEntry>([ ['kimi-cu', createKimiCuEntry(ctx)], @@ -85,16 +65,6 @@ export class CapabilityService extends Disposable implements ICapabilityService } } - describeCapabilities(): readonly CapabilityDescriptor[] { - return [...this.entries.values()].map((entry) => ({ - id: entry.id, - pluginId: entry.pluginId, - displayName: entry.displayName, - description: entry.description, - supported: entry.supported, - })); - } - listCapabilities(): Promise<readonly CapabilityStatus[]> { return Promise.all([...this.entries.values()].map((entry) => this.statusOfSafe(entry))); } @@ -120,16 +90,16 @@ export class CapabilityService extends Disposable implements ICapabilityService } this.runningInstalls.add(entry.id); - this.setInstallProgress(entry.id, { running: true }); + this.installProgress.set(entry.id, { running: true }); void (async () => { try { - const note = await entry.install((step, percent) => { - this.setInstallProgress( + await entry.install((step, percent) => { + this.installProgress.set( entry.id, percent === undefined ? { running: true, step } : { running: true, step, percent }, ); }); - this.setInstallProgress(entry.id, { running: false, note }); + this.installProgress.set(entry.id, { running: false }); } catch (error) { const step = this.installProgress.get(entry.id)?.step; this.log.warn('capability install failed', { @@ -137,7 +107,7 @@ export class CapabilityService extends Disposable implements ICapabilityService step, error, }); - this.setInstallProgress(entry.id, { + this.installProgress.set(entry.id, { running: false, error: error instanceof Error ? error.message : String(error), }); diff --git a/packages/agent-core-v2/src/app/capability/entries/context.ts b/packages/agent-core-v2/src/app/capability/entries/context.ts index cee186399..55d01fa36 100644 --- a/packages/agent-core-v2/src/app/capability/entries/context.ts +++ b/packages/agent-core-v2/src/app/capability/entries/context.ts @@ -1,4 +1,9 @@ -import type { KimiRegion } from '@moonshot-ai/kimi-code-oauth'; +/** + * Shared context injected into capability entries. Every field is + * constructor-wired by `CapabilityService`; tests substitute fakes + * (temp dirs, fake fetch, fake plugin service) rather than touching the + * host. + */ import type { IPluginService } from '#/app/plugin/plugin'; import type { IHostProcessService } from '#/os/interface/hostProcess'; @@ -15,5 +20,4 @@ export interface CapabilityEntryContext { readonly webbridgeBaseUrl?: string; readonly detectProbeTimeoutMs?: number; readonly commandTimeoutMs?: number; - readonly resolveRegion?: () => KimiRegion | Promise<KimiRegion>; } diff --git a/packages/agent-core-v2/src/app/capability/entries/kimiCu.ts b/packages/agent-core-v2/src/app/capability/entries/kimiCu.ts index 7d44d8a01..af1c418ea 100644 --- a/packages/agent-core-v2/src/app/capability/entries/kimiCu.ts +++ b/packages/agent-core-v2/src/app/capability/entries/kimiCu.ts @@ -1,10 +1,34 @@ +/** + * `kimi-cu` capability entry (macOS and Windows). + * + * Both platforms share the same product capability and plugin wiring flow. + * macOS adds KimiCU.app + launchd + TCC permissions; Windows uses the + * official signed runtime installer and its built-in `doctor` command. + * + * The macOS path replicates the official `setup_macos.sh` step-for-step + * (stop old processes → ditto into /Applications → register service → + * request permissions) with structured progress and errors instead of a + * shell pipe. Elevation when /Applications is not writable goes through + * `osascript ... with administrator privileges` (native auth dialog). + * Installs are detect-first and idempotent: setup always refreshes the wiring + * plugin, only unsatisfied runtime layers are redone, and setup re-enables a + * previously disabled wiring plugin (and its + * MCP servers), the app step requires an executable binary with bundle + * metadata, the archive is staged and unpacked before the old service is + * stopped, and cleanup of old processes is best-effort — a wedged old + * binary turns CLI probes into failed steps or is skipped past, never + * blocking the replacement. + * The Windows path downloads and runs the official `setup_windows.ps1`, so + * its signature verification, rollback, and agent autostart stay upstream. + * It selects a trusted PowerShell installation that satisfies the script's + * command requirements before changing plugin wiring. + */ + import { constants } from 'node:fs'; import { access, mkdtemp, readFile, rename, rm, stat, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import path from 'node:path'; -import { kimiCdnContentUrl } from '@moonshot-ai/kimi-code-oauth'; - import { downloadToFile, runCommand } from '../host'; import type { CapabilityDetectResult, @@ -14,8 +38,18 @@ import type { } from '../types'; import type { CapabilityEntryContext } from './context'; -const MAC_PLUGIN_ID = 'kimi-cu'; -const WINDOWS_PLUGIN_ID = 'kimi-cu-win'; +const MAC_PLUGIN = { + id: 'kimi-cu', + zipUrl: 'https://cdn.kimi.com/kimi-computer-use/latest/kimi-cu-plugin.zip', +} as const; +const WINDOWS_PLUGIN = { + id: 'kimi-cu-win', + zipUrl: + 'https://cdn.kimi.com/kimi-computer-use-windows/latest/kimi-cu-win-plugin.zip', +} as const; +const APP_ZIP_URL = 'https://cdn.kimi.com/kimi-computer-use/latest/KimiCU.app.zip'; +const WINDOWS_SETUP_URL = + 'https://cdn.kimi.com/kimi-computer-use-windows/latest/setup_windows.ps1'; const APP_BUNDLE = 'KimiCU.app'; const LAUNCHD_LABEL = 'ai.kimi.cu.service'; const COMMAND_TIMEOUT_MS = 30_000; @@ -46,20 +80,6 @@ interface PluginLayerConfig { readonly zipUrl: string; } -function macPlugin(): PluginLayerConfig { - return { - id: MAC_PLUGIN_ID, - zipUrl: kimiCdnContentUrl('kimi-computer-use/latest/kimi-cu-plugin.zip'), - }; -} - -function windowsPlugin(): PluginLayerConfig { - return { - id: WINDOWS_PLUGIN_ID, - zipUrl: kimiCdnContentUrl('kimi-computer-use-windows/latest/kimi-cu-win-plugin.zip'), - }; -} - interface PermissionStatus { readonly accessibility: boolean; readonly screenRecording: boolean; @@ -308,7 +328,7 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { async function detect(): Promise<CapabilityDetectResult> { const steps: CapabilityStep[] = []; - const plugin = await detectPluginLayer(ctx, macPlugin()); + const plugin = await detectPluginLayer(ctx, MAC_PLUGIN); steps.push(plugin.step); if ((await legacyMcpFile()) !== undefined) { @@ -381,6 +401,9 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { await bestEffort(appBin, ['uninstall']); } await bestEffort('launchctl', ['bootout', `gui/${uid}/${LAUNCHD_LABEL}`]); + // Keep connected MCP frontends alive while the app bundle is replaced. + // Their work is delegated to the service below; killing them makes the + // client report an installation-driven restart as an unexpected failure. for (const mode of ['service', 'overlay']) { await bestEffort('pkill', ['-f', `${APP_BUNDLE}/Contents/MacOS/kimi-cu[[:space:]]+${mode}`]); } @@ -410,7 +433,7 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { } } - async function install(report: CapabilityInstallReporter): Promise<string | undefined> { + async function install(report: CapabilityInstallReporter): Promise<void> { if (!supported) { throw new Error(`kimi-cu is only supported on macOS (current: ${ctx.platform})`); } @@ -423,8 +446,11 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { .every((step) => step.state === 'ok'); report('plugin'); - await installPluginLayer(ctx, macPlugin()); + await installPluginLayer(ctx, MAC_PLUGIN); + // A read-only or concurrently edited user config must not block the app + // installation. Detection keeps the duplicate as an optional warning so + // clients can record it in logs and a later install can retry migration. if (await removeLegacyMcpRegistration(legacyMcpBefore).catch(() => false)) { report('mcp-config'); } @@ -436,7 +462,7 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { report('download', 0); const zipPath = path.join(workDir, 'KimiCU.app.zip'); await downloadToFile( - kimiCdnContentUrl('kimi-computer-use/latest/KimiCU.app.zip'), + APP_ZIP_URL, zipPath, (percent) => { report('download', percent); @@ -488,12 +514,11 @@ function createMacKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry { { timeout: PERMISSIONS_TIMEOUT_MS }, ).catch(() => undefined); } - return undefined; } return { id: 'kimi-cu', - pluginId: MAC_PLUGIN_ID, + pluginId: MAC_PLUGIN.id, displayName: 'Kimi Computer Use', description: 'macOS GUI automation in the background — read app UIs and click, type, scroll, and drag without taking over your mouse or foregrounding apps.', @@ -596,7 +621,7 @@ function createWindowsKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry async function detect(): Promise<CapabilityDetectResult> { const [plugin, runtime] = await Promise.all([ - detectPluginLayer(ctx, windowsPlugin()), + detectPluginLayer(ctx, WINDOWS_PLUGIN), detectRuntimeStep(), ]); return { @@ -605,7 +630,7 @@ function createWindowsKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry }; } - async function install(report: CapabilityInstallReporter): Promise<string | undefined> { + async function install(report: CapabilityInstallReporter): Promise<void> { if (!supported) { throw new Error( `kimi-cu is only supported on macOS or Windows x64 (current: ${ctx.platform}/${ctx.arch})`, @@ -622,7 +647,7 @@ function createWindowsKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry if (installPlugin) { report('plugin'); try { - await installPluginLayer(ctx, windowsPlugin()); + await installPluginLayer(ctx, WINDOWS_PLUGIN); } catch (error) { if ( typeof error !== 'object' || @@ -645,7 +670,7 @@ function createWindowsKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry const setupPath = path.join(workDir, 'setup_windows.ps1'); report('download', 0); await downloadToFile( - kimiCdnContentUrl('kimi-computer-use-windows/latest/setup_windows.ps1'), + WINDOWS_SETUP_URL, setupPath, (percent) => { report('download', percent); @@ -685,12 +710,11 @@ function createWindowsKimiCuEntry(ctx: CapabilityEntryContext): CapabilityEntry ); } } - return undefined; } return { id: 'kimi-cu', - pluginId: WINDOWS_PLUGIN_ID, + pluginId: WINDOWS_PLUGIN.id, displayName: 'Kimi Computer Use for Windows', description: 'Windows GUI automation — read app UIs and click, type, scroll, and drag in desktop apps.', diff --git a/packages/agent-core-v2/src/app/capability/entries/kimiWebbridge.ts b/packages/agent-core-v2/src/app/capability/entries/kimiWebbridge.ts index ebf2b47ea..5405a2dee 100644 --- a/packages/agent-core-v2/src/app/capability/entries/kimiWebbridge.ts +++ b/packages/agent-core-v2/src/app/capability/entries/kimiWebbridge.ts @@ -1,14 +1,27 @@ +/** + * `kimi-webbridge` capability entry (macOS / Linux / Windows). + * + * Layers: daemon binary (`~/.kimi-webbridge/bin/`, local HTTP daemon on + * 127.0.0.1:10086) + agent wiring (the official `kimi-webbridge` plugin — + * skills only, installed through `IPluginService`) + browser extension + * (soft gate, user installs from the webstore or the manual zip). + * + * A running daemon is left untouched (start-if-down only, Kimi Work + * coexistence). Reinstall replaces the on-disk binary from the latest + * channel, which takes effect the next time the daemon starts. Installs + * are detect-first and idempotent: only unsatisfied layers are redone, + * setup re-enables a previously disabled wiring plugin, the binary step + * requires the executable bit on POSIX (an interrupted install reads as + * missing and re-downloads). Legacy standalone skill copies are moved into + * a Kimi Code backup after the managed plugin has been refreshed, so plugin + * updates become authoritative without deleting user files. + */ + import { constants } from 'node:fs'; import { access, chmod, mkdir, mkdtemp, rename, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import path from 'node:path'; -import { - kimiCdnContentUrl, - kimiRegionProfile, - resolveKimiRegion, -} from '@moonshot-ai/kimi-code-oauth'; - import { downloadToFile, runCommand } from '../host'; import type { CapabilityDetectResult, @@ -19,8 +32,9 @@ import type { import type { CapabilityEntryContext } from './context'; const PLUGIN_ID = 'kimi-webbridge'; -const PLUGIN_ZIP_PATH = 'plugins/official/kimi-webbridge.zip'; -const BINARY_CDN_PATH = 'webbridge/latest/releases'; +const PLUGIN_ZIP_URL = + 'https://code.kimi.com/kimi-code/plugins/official/kimi-webbridge.zip'; +const BINARY_CDN_BASE = 'https://cdn.kimi.com/webbridge/latest/releases'; const DEFAULT_DAEMON_BASE_URL = 'http://127.0.0.1:10086'; const STATUS_TIMEOUT_MS = 1_500; const START_TIMEOUT_MS = 30_000; @@ -192,7 +206,7 @@ export function createKimiWebbridgeEntry(ctx: CapabilityEntryContext): Capabilit throw new Error(`WebBridge daemon did not come up on ${baseUrl} — check ~/.kimi-webbridge/logs`); } - async function install(report: CapabilityInstallReporter): Promise<string | undefined> { + async function install(report: CapabilityInstallReporter): Promise<void> { const asset = binaryAssetName(ctx.platform, ctx.arch); if (asset === undefined) { throw new Error(`kimi-webbridge is not supported on ${ctx.platform}/${ctx.arch}`); @@ -222,10 +236,7 @@ export function createKimiWebbridgeEntry(ctx: CapabilityEntryContext): Capabilit } report('skill'); - const region = (await ctx.resolveRegion?.()) ?? resolveKimiRegion(); - const summary = await ctx.plugins.installPlugin({ - source: `${kimiRegionProfile(region).cdnBase}/${PLUGIN_ZIP_PATH}`, - }); + const summary = await ctx.plugins.installPlugin({ source: PLUGIN_ZIP_URL }); if (!summary.enabled) { await ctx.plugins.setPluginEnabled({ id: PLUGIN_ID, enabled: true }); } @@ -240,9 +251,6 @@ export function createKimiWebbridgeEntry(ctx: CapabilityEntryContext): Capabilit `Could not back up the standalone kimi-webbridge skill: ${error instanceof Error ? error.message : String(error)}`; } } - return standaloneSkillMigrationPending && standaloneSkillMigrationError === undefined - ? 'user-skill-migrated' - : undefined; } async function installBinary( @@ -250,7 +258,7 @@ export function createKimiWebbridgeEntry(ctx: CapabilityEntryContext): Capabilit asset: string, ): Promise<void> { report('download', 0); - const url = kimiCdnContentUrl(`${BINARY_CDN_PATH}/${asset}`); + const url = `${BINARY_CDN_BASE}/${asset}`; const staging = path.join( tmpdir(), `kimi-webbridge-${Date.now()}-${Math.random().toString(36).slice(2, 8)}${ctx.platform === 'win32' ? '.exe' : ''}`, diff --git a/packages/agent-core-v2/src/app/capability/errors.ts b/packages/agent-core-v2/src/app/capability/errors.ts index d88d5ce4d..4b06b1908 100644 --- a/packages/agent-core-v2/src/app/capability/errors.ts +++ b/packages/agent-core-v2/src/app/capability/errors.ts @@ -1,3 +1,7 @@ +/** + * `capability` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const CapabilityErrors = { diff --git a/packages/agent-core-v2/src/app/capability/host.ts b/packages/agent-core-v2/src/app/capability/host.ts index 2d1f4c8bb..04c5633fa 100644 --- a/packages/agent-core-v2/src/app/capability/host.ts +++ b/packages/agent-core-v2/src/app/capability/host.ts @@ -1,3 +1,15 @@ +/** + * Shared host helpers for capability entries: process execution with + * captured output, and streaming downloads with progress reporting. + * + * `runCommand` never throws for an expected failure — a spawn failure or a + * non-zero exit resolves into the result (`code: -1` for spawn failures), + * while a timeout kills the process and rejects. `downloadToFile` bounds + * both the response-header wait (fetch abort signal) and stream inactivity + * (a watchdog reset per chunk, 30s by default), so a stalled CDN connection + * fails the background install instead of wedging it. + */ + import { createWriteStream } from 'node:fs'; import { mkdir } from 'node:fs/promises'; import path from 'node:path'; @@ -60,7 +72,7 @@ export async function runCommand( if (timer !== undefined) clearTimeout(timer); } } finally { - void proc.dispose(); + proc.dispose(); } } @@ -71,7 +83,7 @@ export type FetchLike = ( ok: boolean; status: number; headers: { get(name: string): string | null }; - body: object | null; + body: import('node:stream/web').ReadableStream | null; }>; export async function downloadToFile( @@ -126,11 +138,7 @@ export async function downloadToFile( } armIdleWatchdog(); try { - await pipeline( - Readable.fromWeb(resp.body as import('node:stream/web').ReadableStream), - meter, - createWriteStream(destPath), - ); + await pipeline(Readable.fromWeb(resp.body), meter, createWriteStream(destPath)); } finally { if (idleTimer !== undefined) clearTimeout(idleTimer); } diff --git a/packages/agent-core-v2/src/app/capability/types.ts b/packages/agent-core-v2/src/app/capability/types.ts index e6072b051..7497a2063 100644 --- a/packages/agent-core-v2/src/app/capability/types.ts +++ b/packages/agent-core-v2/src/app/capability/types.ts @@ -1,3 +1,14 @@ +/** + * `capability` domain types — built-in product capabilities (kimi-cu, + * kimi-webbridge) that bundle a binary runtime + agent wiring + manual + * user steps. A capability is NOT a plugin: plugins are declarative + * contributions to a session, while capabilities own imperative install + * orchestration and a layered readiness state machine for product-specific + * runtimes (macOS app + launchd service + TCC permissions; Windows signed + * runtime; local HTTP daemon + browser extension). Steps marked `optional` + * never block `ready`; `install.note` is a machine key clients localize. + */ + export type CapabilityId = 'kimi-cu' | 'kimi-webbridge'; export type CapabilityReadiness = 'not_installed' | 'partial' | 'ready' | 'unsupported'; @@ -16,7 +27,6 @@ export interface CapabilityInstallProgress { readonly step?: string; readonly percent?: number; readonly error?: string; - readonly note?: string; } export interface CapabilityDetectResult { @@ -26,6 +36,7 @@ export interface CapabilityDetectResult { export interface CapabilityStatus { readonly id: CapabilityId; + /** Plugin identifier used to provide this capability's agent wiring. */ readonly pluginId?: string; readonly displayName: string; readonly description: string; @@ -38,19 +49,6 @@ export interface CapabilityStatus { export type CapabilityInstallReporter = (step: string, percent?: number) => void; -export interface CapabilityDescriptor { - readonly id: CapabilityId; - readonly pluginId?: string; - readonly displayName: string; - readonly description: string; - readonly supported: boolean; -} - -export interface CapabilityInstallChange { - readonly id: CapabilityId; - readonly install: CapabilityInstallProgress; -} - export interface CapabilityEntry { readonly id: CapabilityId; readonly pluginId?: string; @@ -58,5 +56,5 @@ export interface CapabilityEntry { readonly description: string; readonly supported: boolean; detect(): Promise<CapabilityDetectResult>; - install(report: CapabilityInstallReporter): Promise<string | undefined>; + install(report: CapabilityInstallReporter): Promise<void>; } diff --git a/packages/agent-core-v2/src/app/config/config.ts b/packages/agent-core-v2/src/app/config/config.ts index 9003c1d36..24eca8029 100644 --- a/packages/agent-core-v2/src/app/config/config.ts +++ b/packages/agent-core-v2/src/app/config/config.ts @@ -1,3 +1,33 @@ +/** + * `config` domain — configuration registry and layered global config service. + * + * Defines the config service identifiers and section models: the + * `IConfigRegistry` for section schemas, and the App-scoped `IConfigService` + * that resolves a value by precedence across layers (defaults → user config → + * per-run memory overrides) and writes through a `ConfigTarget`. Owners react + * to edits through two change events — `onDidChangeConfiguration` (a domain was touched) and + * `onDidSectionChange` (the delivered value actually changed, deep-diffed) — + * each carrying the delivered `value` and `previousValue`. + * + * Sections may bind fields to env vars (`envBindings`), resolved as + * env > user config > default on every read; an env value that fails its + * binding's `parse` is ignored. `stripEnvBoundFields` builds the matching + * write guard for persistable env-bound fields: while a field's env var + * resolves to a value, `set`/`replace` restores the field's value from the + * env-free raw base (already `fromToml`-normalized) — or drops it when absent + * there — instead of persisting an echoed env value; otherwise writes pass + * through untouched. When nothing + * persistable remains, the write is a no-op for the section — the env-free + * raw base is kept as-is (unknown forward-compatible fields survive repeated + * stripped writes) — and the section is cleared only when the base is empty, + * so registered defaults keep applying. + * + * Sections declare key renames through `deprecations` and env-var renames + * through a binding's `deprecatedEnv`: a deprecated TOML key is ignored (its + * value no longer applies) and a deprecated env var still resolves as a + * fallback; both surface warning `ConfigDiagnostic`s while in use. + */ + import type { Event } from '#/_base/event'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; @@ -13,14 +43,26 @@ export type EnvBinding = | string | { readonly env: string; + /** + * Deprecated former name of `env`. Still honored (with a deprecation + * warning) when `env` itself is absent or fails to parse, so existing + * setups keep working until the user renames the variable. + */ readonly deprecatedEnv?: string; readonly parse?: (raw: string) => unknown; readonly default?: unknown; }; +/** + * A declared config-key rename: `key` (snake_case, as written on disk) is + * deprecated in favor of `replacement`. While the old key is present in the + * user's config file the service reports a warning diagnostic; the old value + * is NOT honored — only `replacement` (or the section default) applies. + */ export interface ConfigKeyDeprecation { readonly key: string; readonly replacement: string; + /** Optional extra guidance appended to the generated warning message. */ readonly message?: string; } @@ -64,6 +106,11 @@ export function stripEnvBoundFields<T>(bindings: EnvBindings<T>): ConfigStripEnv }; } +/** + * Whether a leaf binding currently resolves from the environment: the primary + * var wins when set and parseable, then the deprecated fallback (same rule as + * the read path in `configService`'s `resolveBinding`). + */ function resolvesFromEnv(binding: EnvBinding, getEnv: (name: string) => string | undefined): boolean { const parse = typeof binding === 'string' ? undefined : binding.parse; const names = @@ -195,6 +242,11 @@ export interface IConfigService { readonly ready: Promise<void>; readonly onDidChangeConfiguration: Event<ConfigChangedEvent>; readonly onDidSectionChange: Event<ConfigSectionChangedEvent>; + /** + * Fired when the diagnostics list changes (load / reload / env overlay + * re-application), carrying the full current list — including an empty + * list when the last diagnostic clears. + */ readonly onDidChangeDiagnostics: Event<readonly ConfigDiagnostic[]>; get<T = unknown>(domain: string): T; inspect<T = unknown>(domain: string): ConfigInspectValue<T>; diff --git a/packages/agent-core-v2/src/app/config/configEvents.ts b/packages/agent-core-v2/src/app/config/configEvents.ts deleted file mode 100644 index 91f6d01af..000000000 --- a/packages/agent-core-v2/src/app/config/configEvents.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -export interface ConfigWarningItem { - readonly domain?: string; - readonly message: string; -} - -export interface ConfigWarningPayload { - readonly warnings: readonly ConfigWarningItem[]; -} - -export class ConfigWarning extends Event2<{ readonly payload: ConfigWarningPayload }> { - static override readonly type = 'event.config.warning'; -} -export interface ConfigWarning { - readonly payload: ConfigWarningPayload; -} - -export interface ConfigChangedPayload { - readonly changedFields: readonly string[]; - readonly config: unknown; -} - -export class ConfigChanged extends Event2<{ readonly payload: ConfigChangedPayload }> { - static override readonly type = 'event.config.changed'; -} -export interface ConfigChanged { - readonly payload: ConfigChangedPayload; -} diff --git a/packages/agent-core-v2/src/app/config/configOverlayContributions.ts b/packages/agent-core-v2/src/app/config/configOverlayContributions.ts index 75eec4d64..0f3316b3d 100644 --- a/packages/agent-core-v2/src/app/config/configOverlayContributions.ts +++ b/packages/agent-core-v2/src/app/config/configOverlayContributions.ts @@ -1,3 +1,18 @@ +/** + * `config` domain — module-level config-overlay contribution collector. + * + * An owner domain calls `registerConfigOverlay(...)` at the top level of the + * module that defines the overlay; `ConfigRegistry` drains the collected + * overlays when it is constructed. Pure data — no DI, no container — so + * `config` never imports any owner domain, and an overlay becomes active as + * soon as its owning module is imported, regardless of whether the consuming + * Service is instantiated. + * + * This decouples overlay registration from Service lifetime: an overlay must + * not depend on a Service being constructed, because top-level contributions + * are available before any scope activation. + */ + import type { ConfigEffectiveOverlay } from './config'; const _overlays: ConfigEffectiveOverlay[] = []; diff --git a/packages/agent-core-v2/src/app/config/configPure.ts b/packages/agent-core-v2/src/app/config/configPure.ts index 9a927001a..c718b158e 100644 --- a/packages/agent-core-v2/src/app/config/configPure.ts +++ b/packages/agent-core-v2/src/app/config/configPure.ts @@ -1,3 +1,11 @@ +/** + * `config` domain — pure helper functions for config values. + * + * Provides side-effect-free helpers used by config services, including plain + * object detection, deep equality, deep merge, undefined stripping, and error + * formatting. + */ + export function isPlainObject(value: unknown): value is Record<string, unknown> { return typeof value === 'object' && value !== null && !Array.isArray(value); } diff --git a/packages/agent-core-v2/src/app/config/configSectionContributions.ts b/packages/agent-core-v2/src/app/config/configSectionContributions.ts index c409ac19b..8dda4ecb2 100644 --- a/packages/agent-core-v2/src/app/config/configSectionContributions.ts +++ b/packages/agent-core-v2/src/app/config/configSectionContributions.ts @@ -1,3 +1,15 @@ +/** + * `config` domain — module-level config-section contribution collector. + * + * Lets each owning domain self-register its config section at module load time + * ("import = register"). An owner domain calls `registerConfigSection(...)` + * at the top level of its config-section module; `ConfigRegistry` drains the + * collected contributions when it is constructed. Pure data — no DI, no + * container — so `config` never imports any owner domain, and a section + * becomes available as soon as its domain barrel is imported, regardless of + * whether the consuming Service is instantiated. + */ + import { collection } from '#/_base/di/collection'; import type { ConfigSchema, RegisterSectionOptions } from './config'; diff --git a/packages/agent-core-v2/src/app/config/configService.ts b/packages/agent-core-v2/src/app/config/configService.ts index 057aeb52c..9f2bda8c8 100644 --- a/packages/agent-core-v2/src/app/config/configService.ts +++ b/packages/agent-core-v2/src/app/config/configService.ts @@ -1,9 +1,45 @@ +/** + * `config` domain — `IConfigRegistry` and `IConfigService` implementations. + * + * Owns the section registry and the layered global config state: resolves a + * value by precedence across defaults, the user config file, and per-run memory + * overrides (highest, never persisted), and persists writes only for the `User` + * target — validating the merged patch and re-validating the stripped result, + * so a strip can never smuggle an unvalidated raw value (e.g. an env-masked + * invalid field) to disk. Maintains five layered views of a domain — `rawSnake` (snake_case + * write base keyed by the on-disk section key, kept for lossless round-trip), + * `raw` (camelCase, env-free), `validated` (validated `raw`, env-free — the + * base every live env re-application starts from and never mutates, so a + * degraded or removed env value falls back to the file instead of a stale + * overlay), `effective` + * (`validated` plus the env overlay, recomputed on load/set), and `memory` + * (per-run overrides) + * — plus a `delivered` snapshot per domain used as the diff base for + * `onDidSectionChange`. Reads config paths and the environment overlay through + * `bootstrap`, persists the TOML document through the `storage` TOML + * atomic-document store (reloading when the document changes on disk), and logs + * through `log`. Late section / overlay registration re-validates the + * already-loaded raw value and re-runs overlays. Section-declared key + * `deprecations` are detected from the on-disk document on every load and + * reported as warning diagnostics (the deprecated value is NOT applied, and + * the file is never rewritten); env-var renames declared via a binding's + * `deprecatedEnv` still resolve as a fallback, likewise with a warning. + * Diagnostics changes are published through `onDidChangeDiagnostics`. + * `ConfigRegistry` is also the + * fold of the `ConfigSectionContribution` collection token (D12): records + * provided by live units register sections incrementally through the same + * path as the module drain (identical = silent, conflict = logged), and a + * withdrawn record unregisters its section — the domain falls back to + * unknown-section semantics, its TOML user values preserved but no longer + * validated/effective. Bound at App scope. + */ + import { type CollectionView } from '#/_base/di/collection'; import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; -import { BugIndicatingError, Error2, ErrorCodes, onUnexpectedError } from '#/errors'; +import { BugIndicatingError, onUnexpectedError } from '#/errors'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { ILogService } from '#/_base/log/log'; import { @@ -53,6 +89,7 @@ const CONFIG_SCOPE = ''; type GetEnv = (name: string) => string | undefined; +/** Reports a deprecated env var actually supplying a value: (oldName, newName). */ type OnDeprecatedEnv = (oldName: string, newName: string) => void; function isEnvBinding(value: unknown): value is EnvBinding { @@ -285,6 +322,7 @@ export class ConfigRegistry extends Disposable implements IConfigRegistry { } } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ConfigService extends Disposable implements IConfigService { declare readonly _serviceBrand: undefined; private readonly _onDidChangeConfiguration = this._register(new Emitter<ConfigChangedEvent>()); @@ -309,7 +347,6 @@ export class ConfigService extends Disposable implements IConfigService { private readonly diagnosticsList: ConfigDiagnostic[] = []; private lastDiagnosticsSnapshot = '[]'; private readonly configKey: string; - private tainted = false; constructor( @IConfigRegistry private readonly registry: IConfigRegistry, @@ -367,6 +404,7 @@ export class ConfigService extends Disposable implements IConfigService { return [...this.diagnosticsList]; } + /** Append a diagnostic, skipping exact duplicates (rebuilds re-run the same checks). */ private pushDiagnostic(diagnostic: ConfigDiagnostic): void { const duplicate = this.diagnosticsList.some( (existing) => @@ -402,18 +440,17 @@ export class ConfigService extends Disposable implements IConfigService { return; } await this.enqueueStateTransition(async () => { - this.assertPersistable(); - await this.persist(domain, (stagedRaw, stagedRawSnake) => { - const next = this.registry.merge(domain, stagedRaw[domain], patch); - const validated = this.registry.validate(domain, next); - const stripped = this.stripEnv(domain, validated, stagedRaw, stagedRawSnake); - if (stripped === undefined) { - delete stagedRaw[domain]; - } else { - this.registry.validate(domain, stripped); - stagedRaw[domain] = stripped; - } - }); + const base = this.raw[domain]; + const next = this.registry.merge(domain, base, patch); + const validated = this.registry.validate(domain, next); + const stripped = this.stripEnv(domain, validated); + if (stripped === undefined) { + delete this.raw[domain]; + } else { + this.registry.validate(domain, stripped); + this.raw[domain] = stripped; + } + await this.persist(domain); this.rebuildEffective('set', [domain]); }); } @@ -435,15 +472,13 @@ export class ConfigService extends Disposable implements IConfigService { return; } await this.enqueueStateTransition(async () => { - this.assertPersistable(); - await this.persist(domain, (stagedRaw, stagedRawSnake) => { - const stripped = this.stripEnv(domain, effectiveValue, stagedRaw, stagedRawSnake); - if (stripped === undefined) { - delete stagedRaw[domain]; - } else { - stagedRaw[domain] = this.registry.validate(domain, stripped); - } - }); + const stripped = this.stripEnv(domain, effectiveValue); + if (stripped === undefined) { + delete this.raw[domain]; + } else { + this.raw[domain] = this.registry.validate(domain, stripped); + } + await this.persist(domain); this.rebuildEffective('set', [domain]); }); } @@ -470,38 +505,33 @@ export class ConfigService extends Disposable implements IConfigService { return; } await this.enqueueStateTransition(async () => { - this.assertPersistable(); - await this.persistDomains(domains, (stagedRaw, stagedRawSnake) => { - for (const domain of domains) { - const value = sections[domain] === null ? undefined : sections[domain]; - const stripped = this.stripEnv(domain, value, stagedRaw, stagedRawSnake); - if (stripped === undefined) { - delete stagedRaw[domain]; - } else { - stagedRaw[domain] = this.registry.validate(domain, stripped); - } + const staged: ResolvedConfig = { ...this.raw }; + for (const domain of domains) { + const value = sections[domain] === null ? undefined : sections[domain]; + const stripped = this.stripEnv(domain, value); + if (stripped === undefined) { + delete staged[domain]; + } else { + staged[domain] = this.registry.validate(domain, stripped); } - }); + } + this.raw = staged; + await this.persistDomains(domains); this.rebuildEffective('set', domains); }); } - private stripEnv( - domain: string, - value: unknown, - raw: ResolvedConfig, - rawSnake: ResolvedConfig, - ): unknown { + private stripEnv(domain: string, value: unknown): unknown { let result = value; const section = this.registry.getSection(domain); if (section?.stripEnv !== undefined) { const getEnv = (name: string): string | undefined => this.bootstrap.getEnv(name); - result = section.stripEnv(result, raw[domain], getEnv); + result = section.stripEnv(result, this.raw[domain], getEnv); } if (result === undefined) return result; for (const overlay of this.registry.listEffectiveOverlays()) { if (overlay.strip === undefined) continue; - result = overlay.strip(domain, result, rawSnake); + result = overlay.strip(domain, result, this.rawSnake); if (result === undefined) return result; } return result; @@ -524,30 +554,29 @@ export class ConfigService extends Disposable implements IConfigService { private async load(source: ConfigChangeSource): Promise<void> { this.diagnosticsList.length = 0; let fileData: ResolvedConfig = {}; - let failed = false; try { const data = await this.documentStore.get<ResolvedConfig>(CONFIG_SCOPE, this.configKey); fileData = data !== undefined && isPlainObject(data) ? data : {}; } catch (error) { - failed = true; const message = error instanceof TomlError ? `Failed to parse ${this.bootstrap.configPath}: ${describeTomlSyntaxError(error)}` : describeUnknownError(error); this.pushDiagnostic({ severity: 'error', message }); this.log.warn('config load failed', { error: describeUnknownError(error) }); - if (source !== 'load') { - this.tainted = true; - this.emitDiagnosticsIfChanged(); - return; - } } - this.tainted = failed; const nextRawSnake = cloneRecord(fileData); + // Key-deprecation warnings derive from the on-disk document, so collect + // them before the unchanged-file early return — the list was just cleared + // above and a no-op reload must not drop them. for (const diagnostic of collectKeyDeprecations(nextRawSnake, this.registry.listSections())) { this.pushDiagnostic(diagnostic); } if (source !== 'load' && JSON.stringify(nextRawSnake) === JSON.stringify(this.rawSnake)) { + // The file is unchanged, so values and change events stay as they are — + // but env-derived diagnostics (deprecated env fallbacks, overlay + // failures) were cleared above and must be recollected over a scratch + // copy, or a no-op reload would silently drop them. const scratch = { ...this.validated }; this.applySectionEnvBindings(scratch, true); this.applyEnvOverlay(scratch); @@ -748,56 +777,15 @@ export class ConfigService extends Disposable implements IConfigService { this.commit('reload', [domain]); } - private assertPersistable(): void { - if (!this.tainted) return; - throw new Error2( - ErrorCodes.CONFIG_PERSIST_BLOCKED, - `Refusing to persist config: ${this.bootstrap.configPath} could not be read; fix the file and reload before writing.`, - ); + private async persist(domain: string): Promise<void> { + await this.persistDomains([domain]); } - private async persist( - domain: string, - rebase: (stagedRaw: ResolvedConfig, stagedRawSnake: ResolvedConfig) => void, - ): Promise<void> { - await this.persistDomains([domain], rebase); - } - - private async persistDomains( - domains: readonly string[], - rebase: (stagedRaw: ResolvedConfig, stagedRawSnake: ResolvedConfig) => void, - ): Promise<void> { - this.assertPersistable(); - let onDisk: ResolvedConfig = {}; - try { - const data = await this.documentStore.get<ResolvedConfig>(CONFIG_SCOPE, this.configKey); - onDisk = data !== undefined && isPlainObject(data) ? data : {}; - } catch (error) { - const message = - error instanceof TomlError - ? `Failed to parse ${this.bootstrap.configPath}: ${describeTomlSyntaxError(error)}` - : describeUnknownError(error); - this.pushDiagnostic({ severity: 'error', message }); - this.emitDiagnosticsIfChanged(); - this.log.warn('config persist aborted: re-read failed', { - error: describeUnknownError(error), - }); - this.tainted = true; - throw new Error2( - ErrorCodes.CONFIG_PERSIST_BLOCKED, - `Refusing to persist config: ${this.bootstrap.configPath} could not be read; fix the file and reload before writing.`, - { cause: error }, - ); - } - const stagedRawSnake = cloneRecord(onDisk); - const stagedRaw = transformTomlData(onDisk, this.registry); - rebase(stagedRaw, stagedRawSnake); + private async persistDomains(domains: readonly string[]): Promise<void> { for (const domain of domains) { - applySectionToToml(stagedRawSnake, domain, stagedRaw[domain], this.registry); + applySectionToToml(this.rawSnake, domain, this.raw[domain], this.registry); } - await this.documentStore.set(CONFIG_SCOPE, this.configKey, stagedRawSnake); - this.rawSnake = stagedRawSnake; - this.raw = stagedRaw; + await this.documentStore.set(CONFIG_SCOPE, this.configKey, this.rawSnake); } } diff --git a/packages/agent-core-v2/src/app/config/deprecations.ts b/packages/agent-core-v2/src/app/config/deprecations.ts index c1296daa0..fa42847d8 100644 --- a/packages/agent-core-v2/src/app/config/deprecations.ts +++ b/packages/agent-core-v2/src/app/config/deprecations.ts @@ -1,3 +1,14 @@ +/** + * `config` domain — declarative config-key deprecation detection. + * + * A section declares its renames once (`RegisterSectionOptions.deprecations`, + * snake_case keys as written on disk) and this module turns the presence of a + * deprecated key in the on-disk document into a warning `ConfigDiagnostic`. + * Detection is read-only: the old value is never mapped onto the new key (the + * section schema no longer knows the old key, so it is dropped at validation), + * and the user's file is left untouched — the warning is the migration guide. + */ + import type { ConfigDiagnostic, ConfigSection } from './config'; import { isPlainObject } from './configPure'; import { camelToSnake } from './toml'; diff --git a/packages/agent-core-v2/src/app/config/errors.ts b/packages/agent-core-v2/src/app/config/errors.ts index 63c01cb81..9823743fb 100644 --- a/packages/agent-core-v2/src/app/config/errors.ts +++ b/packages/agent-core-v2/src/app/config/errors.ts @@ -1,10 +1,16 @@ +/** + * `config` domain error codes. + * + * The `config.invalid` code string is owned by the kosong L0 wire contract; + * this module only registers it. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; import { CONFIG_INVALID_ERROR_CODE } from '#/kosong/contract/errors'; export const ConfigErrors = { codes: { CONFIG_INVALID: CONFIG_INVALID_ERROR_CODE, - CONFIG_PERSIST_BLOCKED: 'config.persist_blocked', }, } as const satisfies ErrorDomain; diff --git a/packages/agent-core-v2/src/app/config/migrations.ts b/packages/agent-core-v2/src/app/config/migrations.ts index 6b69d30b2..dfba378d9 100644 --- a/packages/agent-core-v2/src/app/config/migrations.ts +++ b/packages/agent-core-v2/src/app/config/migrations.ts @@ -1,3 +1,10 @@ +/** + * One-shot config migrations. Each migration runs at most once per kimi + * home: a marker in `<home>/migrations-effort.json` records completion (ISO + * timestamp), so a value the user re-sets by hand afterwards is never + * migrated again. Best-effort and never throws — a migration must never + * block startup. + */ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'; import { join } from 'pathe'; diff --git a/packages/agent-core-v2/src/app/config/sectionDiff.ts b/packages/agent-core-v2/src/app/config/sectionDiff.ts index 210843d23..7590cb41f 100644 --- a/packages/agent-core-v2/src/app/config/sectionDiff.ts +++ b/packages/agent-core-v2/src/app/config/sectionDiff.ts @@ -1,3 +1,11 @@ +/** + * `config` domain — record-level config-section diffing. + * + * `diffRecords` computes the added/removed/changed keys between two snapshots + * of a record-shaped config section, `deepEqual` is the value comparison it + * uses. Pure functions. + */ + export interface RecordDiff { readonly added: readonly string[]; readonly removed: readonly string[]; diff --git a/packages/agent-core-v2/src/app/config/toml.ts b/packages/agent-core-v2/src/app/config/toml.ts index a78770628..cd5c5a2e7 100644 --- a/packages/agent-core-v2/src/app/config/toml.ts +++ b/packages/agent-core-v2/src/app/config/toml.ts @@ -1,3 +1,16 @@ +/** + * `config` domain — TOML read/write transforms. + * + * Generic snake_case ↔ camelCase machinery plus the registry-aware entry points + * (`transformTomlData` / `applySectionToToml`) that dispatch to a section's + * registered `fromToml` / `toToml` hook; this module stays free of any + * per-domain semantics. + * + * Files store keys in snake_case; in-memory values are camelCase. Unknown + * top-level keys are preserved by the caller (which keeps a raw snake_case + * clone for round-trip). + */ + import { TomlError } from 'smol-toml'; import type { IConfigRegistry } from './config'; diff --git a/packages/agent-core-v2/src/features/cron/internal/clock.ts b/packages/agent-core-v2/src/app/cron/clock.ts similarity index 56% rename from packages/agent-core-v2/src/features/cron/internal/clock.ts rename to packages/agent-core-v2/src/app/cron/clock.ts index 9765322f9..43105a75e 100644 --- a/packages/agent-core-v2/src/features/cron/internal/clock.ts +++ b/packages/agent-core-v2/src/app/cron/clock.ts @@ -1,3 +1,32 @@ +/** + * Clock sources for the cron scheduler. + * + * Two distinct notions of time are kept apart on purpose: + * + * 1. wall-clock — what the user perceives as "the current time". Used + * for cron expression matching, `createdAt`, and the 7-day stale + * judgment. May be overridden in tests / multi-process benches so + * that scenarios can run in simulated time without `setTimeout`. + * + * 2. monotonic ms — a strictly non-decreasing counter that never + * jumps backwards across NTP adjustments, suspend/resume, or + * simulated-clock injection. Used for the poll cadence and the + * lock heartbeat — anything where "did 5 seconds elapse since we + * last looked" must hold even when the wall clock is frozen. + * + * Mixing the two pollutes test reproducibility: a heartbeat tied to + * `wallNow()` will appear stuck when the test clock is frozen; a cron + * fire tied to `monoNowMs()` will not advance when the bench rewinds + * the simulated day. Every component in the cron domain MUST take a + * `ClockSources` and route every time read through it. + * + * `monoNowMs` is ALWAYS `process.hrtime.bigint()` (converted to ms). + * It is not overridable — accepting an external monotonic clock would + * defeat the safety net the lock heartbeat depends on. + * + * `wallNow` resolution is driven by the `KIMI_CRON_CLOCK` env var; see + * `resolveClockSources` below. Defaults to `Date.now()`. + */ import { closeSync, openSync, readSync } from 'node:fs'; export interface ClockSources { diff --git a/packages/agent-core-v2/src/features/cron/configSection.ts b/packages/agent-core-v2/src/app/cron/configSection.ts similarity index 84% rename from packages/agent-core-v2/src/features/cron/configSection.ts rename to packages/agent-core-v2/src/app/cron/configSection.ts index 8576a75d8..c25db4b61 100644 --- a/packages/agent-core-v2/src/features/cron/configSection.ts +++ b/packages/agent-core-v2/src/app/cron/configSection.ts @@ -1,3 +1,12 @@ +/** + * `cron` domain — cron operational-config section env bindings. + * + * Declares the `KIMI_CRON_*` environment bindings for the cron operational + * toggles (debug / jitter / stale / killswitch / manual tick / clock / + * poll interval). Applied to the effective `cron` value by `config`; never + * persisted to `config.toml`. + */ + import { type ConfigStripEnv, type EnvBindings, envBindings } from '#/app/config/config'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/features/cron/internal/cron-expr.ts b/packages/agent-core-v2/src/app/cron/cron-expr.ts similarity index 93% rename from packages/agent-core-v2/src/features/cron/internal/cron-expr.ts rename to packages/agent-core-v2/src/app/cron/cron-expr.ts index 406bbe4e3..54863a7ad 100644 --- a/packages/agent-core-v2/src/features/cron/internal/cron-expr.ts +++ b/packages/agent-core-v2/src/app/cron/cron-expr.ts @@ -1,3 +1,22 @@ +/** + * 5-field cron expression parsing and "next fire time" computation, in + * local time. Self-contained — no external cron library is used because + * upstream `claude-code` mirrors the same semantics and we need exact + * lock-step behaviour with their implementation. + * + * Two flavours of correctness we care about: + * + * 1. **Semantics.** Standard 5 fields (minute hour day-of-month month + * day-of-week). Day-of-month and day-of-week combine with cron's + * OR rule when both are restricted (POSIX/Vixie tradition). dow + * accepts 0..7 with 7 folded to 0 (Sunday). + * + * 2. **Termination.** Computing `next` for a legal-but-never-fires + * expression like `0 0 31 2 *` must not spin. We bound the search + * at a fixed window (5 years by default) and return `null` past + * that. + */ + import { Error2, ErrorCodes } from '#/errors'; export interface ParsedCronExpression { diff --git a/packages/agent-core-v2/src/features/cron/cronTask.ts b/packages/agent-core-v2/src/app/cron/cronTask.ts similarity index 51% rename from packages/agent-core-v2/src/features/cron/cronTask.ts rename to packages/agent-core-v2/src/app/cron/cronTask.ts index 134fa66e8..b204fd289 100644 --- a/packages/agent-core-v2/src/features/cron/cronTask.ts +++ b/packages/agent-core-v2/src/app/cron/cronTask.ts @@ -1,3 +1,11 @@ +/** + * `cron` domain — shared `CronTask` data record. + * + * The authoritative definition of a cron task's persistent shape. The `tags` + * map carries arbitrary metadata (e.g. `sessionId`) so tasks can be filtered + * to the session they belong to. + */ + export interface CronTask { readonly id: string; readonly cron: string; @@ -9,3 +17,5 @@ export interface CronTask { } export type CronTaskInit = Omit<CronTask, 'id' | 'createdAt'>; + +export const CRON_SESSION_TAG = 'sessionId'; diff --git a/packages/agent-core-v2/src/app/cron/cronTaskPersistence.ts b/packages/agent-core-v2/src/app/cron/cronTaskPersistence.ts new file mode 100644 index 000000000..99d6e62cb --- /dev/null +++ b/packages/agent-core-v2/src/app/cron/cronTaskPersistence.ts @@ -0,0 +1,28 @@ +/** + * `cron` domain — `ICronTaskPersistence` contract. + * + * Project-level persistence for cron tasks. Persists tasks under + * `bootstrap.scope('cron')` as atomic documents keyed by + * `<workspaceId>/<taskId>.json`. Provides CRUD and query-by-workspace. + * A pure data layer — scheduling, timers, and fire delivery are out of + * scope. Bound at App scope. + */ + +import { createDecorator } from '#/_base/di/instantiation'; + +import type { CronTask } from './cronTask'; + +export interface CronTaskQuery { + readonly workspaceId: string; +} + +export interface ICronTaskPersistence { + readonly _serviceBrand: undefined; + + get(workspaceId: string, taskId: string): Promise<CronTask | undefined>; + list(query: CronTaskQuery): Promise<readonly CronTask[]>; + save(workspaceId: string, task: CronTask): Promise<void>; + delete(workspaceId: string, taskId: string): Promise<void>; +} + +export const ICronTaskPersistence = createDecorator<ICronTaskPersistence>('cronTaskPersistence'); diff --git a/packages/agent-core-v2/src/app/cron/cronTaskPersistenceService.ts b/packages/agent-core-v2/src/app/cron/cronTaskPersistenceService.ts new file mode 100644 index 000000000..ec776131b --- /dev/null +++ b/packages/agent-core-v2/src/app/cron/cronTaskPersistenceService.ts @@ -0,0 +1,101 @@ +/** + * `cron` domain — `ICronTaskPersistence` implementation. + * + * Persists cron tasks as atomic JSON documents under the `cron` persistence + * scope (`bootstrap.scope('cron')`), laid out as `<workspaceId>/<id>.json`. + * Pure CRUD — no scheduling logic. Bound at App scope. + */ + +import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; +import { IBootstrapService } from '#/app/bootstrap/bootstrap'; + +import { ICronTaskPersistence, type CronTaskQuery } from './cronTaskPersistence'; +import type { CronTask } from './cronTask'; + +export const CRON_ID_REGEX: RegExp = /^(?:[0-9a-f]{8}|[0-9A-HJKMNP-TV-Z]{26})$/i; +const JSON_SUFFIX = '.json'; + +export function isValidCronTask(obj: unknown): obj is CronTask { + if (typeof obj !== 'object' || obj === null) return false; + const o = obj as Record<string, unknown>; + if (typeof o['id'] !== 'string' || !CRON_ID_REGEX.test(o['id'])) return false; + if (typeof o['cron'] !== 'string') return false; + if (typeof o['prompt'] !== 'string') return false; + if (typeof o['createdAt'] !== 'number') return false; + if (o['recurring'] !== undefined && typeof o['recurring'] !== 'boolean') return false; + if ( + o['lastFiredAt'] !== undefined && + (typeof o['lastFiredAt'] !== 'number' || !Number.isFinite(o['lastFiredAt'])) + ) { + return false; + } + if (o['tags'] !== undefined) { + if (typeof o['tags'] !== 'object' || o['tags'] === null) return false; + for (const v of Object.values(o['tags'] as Record<string, unknown>)) { + if (typeof v !== 'string') return false; + } + } + return true; +} + +// NOTE: stays Disposable — its own 'get' collides with the Fiber +export class CronTaskPersistenceService extends Disposable implements ICronTaskPersistence { + declare readonly _serviceBrand: undefined; + + private readonly cronScope: string; + + constructor( + @IBootstrapService private readonly bootstrap: IBootstrapService, + @IAtomicDocumentStore private readonly atomicDocs: IAtomicDocumentStore, + ) { + super(); + this.cronScope = this.bootstrap.scope('cron'); + } + + private workspaceScope(workspaceId: string): string { + return `${this.cronScope}/${workspaceId}`; + } + + async get(workspaceId: string, taskId: string): Promise<CronTask | undefined> { + const scope = this.workspaceScope(workspaceId); + const value = await this.atomicDocs.get<CronTask>(scope, `${taskId}${JSON_SUFFIX}`); + if (value === undefined || !isValidCronTask(value)) return undefined; + return value; + } + + async list(query: CronTaskQuery): Promise<readonly CronTask[]> { + const scope = this.workspaceScope(query.workspaceId); + const keys = await this.atomicDocs.list(scope); + const tasks: CronTask[] = []; + for (const key of keys) { + if (!key.endsWith(JSON_SUFFIX)) continue; + const id = key.slice(0, -JSON_SUFFIX.length); + if (!CRON_ID_REGEX.test(id)) continue; + const value = await this.atomicDocs.get<CronTask>(scope, key); + if (value === undefined || !isValidCronTask(value)) continue; + tasks.push(value); + } + return tasks; + } + + async save(workspaceId: string, task: CronTask): Promise<void> { + const scope = this.workspaceScope(workspaceId); + await this.atomicDocs.set(scope, `${task.id}${JSON_SUFFIX}`, task); + } + + async delete(workspaceId: string, taskId: string): Promise<void> { + const scope = this.workspaceScope(workspaceId); + await this.atomicDocs.delete(scope, `${taskId}${JSON_SUFFIX}`); + } +} + +registerScopedService( + LifecycleScope.App, + ICronTaskPersistence, + CronTaskPersistenceService, + ScopeActivation.OnScopeCreated, + 'cron', +); diff --git a/packages/agent-core-v2/src/features/cron/errors.ts b/packages/agent-core-v2/src/app/cron/errors.ts similarity index 86% rename from packages/agent-core-v2/src/features/cron/errors.ts rename to packages/agent-core-v2/src/app/cron/errors.ts index fc8af76db..02730b446 100644 --- a/packages/agent-core-v2/src/features/cron/errors.ts +++ b/packages/agent-core-v2/src/app/cron/errors.ts @@ -1,3 +1,7 @@ +/** + * `cron` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const CronErrors = { diff --git a/packages/agent-core-v2/src/features/cron/internal/format.ts b/packages/agent-core-v2/src/app/cron/format.ts similarity index 82% rename from packages/agent-core-v2/src/features/cron/internal/format.ts rename to packages/agent-core-v2/src/app/cron/format.ts index 19f854262..c2089a9e5 100644 --- a/packages/agent-core-v2/src/features/cron/internal/format.ts +++ b/packages/agent-core-v2/src/app/cron/format.ts @@ -1,3 +1,12 @@ +/** + * LLM-facing text rendering for the cron domain: local-time timestamps for + * tool output, and the `<cron-fire>` injection the scheduler hands to the model + * when a task fires. + * + * Both renderers stay dependency-free so they can be imported without + * pulling in the rest of the cron stack. + */ + import type { CronJobOrigin } from '#/agent/contextMemory/types'; export function formatLocalIsoWithOffset(ms: number): string { diff --git a/packages/agent-core-v2/src/features/cron/internal/jitter.ts b/packages/agent-core-v2/src/app/cron/jitter.ts similarity index 62% rename from packages/agent-core-v2/src/features/cron/internal/jitter.ts rename to packages/agent-core-v2/src/app/cron/jitter.ts index ef565e6d0..9b5548928 100644 --- a/packages/agent-core-v2/src/features/cron/internal/jitter.ts +++ b/packages/agent-core-v2/src/app/cron/jitter.ts @@ -1,3 +1,32 @@ +/** + * Per-task deterministic jitter for cron fire times. + * + * Why this exists: if every user writes `0 9 * * *` ("every day at 9 + * am") then every CLI fires at the same instant and the upstream API + * sees a thundering herd at :00. We soften that by shifting each + * task's ideal fire time by a small, **deterministic** per-task + * offset so a given task always lands at the same jittered point — + * reschedules and restarts don't drift, and bench reproducibility + * stays intact when {@link KIMI_CRON_NO_JITTER} is set. + * + * Two flavours: + * + * - **Recurring**: shift *forward* by a fraction of the period + * (cap 10% of period, hard cap 15 min). Long-period jobs (`0 9 * + * * *`, period 1 day) hit the 15-minute cap; short-period jobs + * (`*` /5 * * * *`, period 5 min) are bounded by the 10% rule. + * + * - **One-shot**: shift *earlier* (negative), but only when the + * ideal lands on `:00` or `:30` — that's the signal the model + * picked a round number with no specific intent. Cap 90 s + * earlier. Any other minute (`:07`, `:23`, …) passes through + * unchanged because the model presumably meant that exact time. + * + * The function is pure given its inputs — no module-level cache; the + * hash is recomputed from `task.id` each call. That trades a handful + * of cheap arithmetic ops for a guarantee that there is no hidden + * state to invalidate when a task is rescheduled. + */ import type { ParsedCronExpression } from './cron-expr'; import { computeNextCronRun } from './cron-expr'; diff --git a/packages/agent-core-v2/src/app/edit/editService.ts b/packages/agent-core-v2/src/app/edit/editService.ts index 3c261d4c9..2ed5cd6cd 100644 --- a/packages/agent-core-v2/src/app/edit/editService.ts +++ b/packages/agent-core-v2/src/app/edit/editService.ts @@ -1,3 +1,12 @@ +/** + * `edit` domain — {@link EditService}, the business rules of an edit. + * + * Owns the `old_string` uniqueness rule, the `replace_all` path, and the + * user-facing error messages. Operates on a {@link TextModel} (pure text) and + * returns a discriminated result: either the re-materialized raw content plus + * the replacement count, or a ready-to-surface error message. No IO. + */ + import type { TextModel } from './textModel'; export interface EditApplyInput { diff --git a/packages/agent-core-v2/src/app/edit/fileEdit.ts b/packages/agent-core-v2/src/app/edit/fileEdit.ts index b2b10cc72..3893d3dc2 100644 --- a/packages/agent-core-v2/src/app/edit/fileEdit.ts +++ b/packages/agent-core-v2/src/app/edit/fileEdit.ts @@ -1,5 +1,14 @@ +/** + * `edit` domain — `IFileEditService` contract. + * + * App-scope general edit capability: reads a file through the os `hostFs` + * domain (`IHostFileSystem`), applies the exact-string edit rules, and writes + * the re-materialized content back. Returns a domain-neutral result (the + * replacement count, or a ready-to-surface error) so consumers at any scope + * can adapt it to their own shape. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; export interface FileEditInput { readonly path: string; @@ -16,7 +25,7 @@ export type FileEditResult = export interface IFileEditService { readonly _serviceBrand: undefined; - edit(input: FileEditInput, fs?: IHostFileSystem): Promise<FileEditResult>; + edit(input: FileEditInput): Promise<FileEditResult>; } export const IFileEditService: ServiceIdentifier<IFileEditService> = diff --git a/packages/agent-core-v2/src/app/edit/fileEditService.ts b/packages/agent-core-v2/src/app/edit/fileEditService.ts index 79e851024..ffaefebca 100644 --- a/packages/agent-core-v2/src/app/edit/fileEditService.ts +++ b/packages/agent-core-v2/src/app/edit/fileEditService.ts @@ -1,3 +1,12 @@ +/** + * `edit` domain — `IFileEditService` implementation. + * + * Reads the file through the os `hostFs` domain (`IHostFileSystem`), runs the + * pure edit logic (`TextModel` + `EditService`), and writes the re-materialized + * content back. Maps host-level failures (e.g. `EISDIR`) to the domain-neutral + * `FileEditResult`; it owns no tool-facing message. Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -17,9 +26,9 @@ export class FileEditService implements IFileEditService { this.editor = new EditService(); } - async edit(input: FileEditInput, fs: IHostFileSystem = this.fs): Promise<FileEditResult> { + async edit(input: FileEditInput): Promise<FileEditResult> { try { - const raw = await fs.readText(input.path, { errors: 'strict' }); + const raw = await this.fs.readText(input.path, { errors: 'strict' }); const model = new TextModel(raw); const result = this.editor.apply(model, { path: input.displayPath, @@ -30,7 +39,7 @@ export class FileEditService implements IFileEditService { if (!result.ok) { return { ok: false, error: result.error }; } - await fs.writeText(input.path, result.rawContent); + await this.fs.writeText(input.path, result.rawContent); return { ok: true, count: result.count }; } catch (error) { const code = (unwrapErrorCause(error) as { code?: unknown } | null)?.code; diff --git a/packages/agent-core-v2/src/app/edit/textModel.ts b/packages/agent-core-v2/src/app/edit/textModel.ts index ab6611d73..ce9a2f81c 100644 --- a/packages/agent-core-v2/src/app/edit/textModel.ts +++ b/packages/agent-core-v2/src/app/edit/textModel.ts @@ -1,3 +1,12 @@ +/** + * `edit` domain — {@link TextModel}, the pure text/line-ending/match-replace + * core of an edit. + * + * Wraps a raw file's text and exposes a normalized LF "model view" for matching + * (so a pure CRLF file can be edited with an LF `old_string`), plus the + * mechanical replace primitives. No IO, no business rules. + */ + import { type LineEndingStyle, materializeModelText, diff --git a/packages/agent-core-v2/src/app/event/errors.ts b/packages/agent-core-v2/src/app/event/errors.ts deleted file mode 100644 index b5b87f4d4..000000000 --- a/packages/agent-core-v2/src/app/event/errors.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; -import { Error2, type Error2Options } from '#/_base/errors/errors'; - -export const EventErrors = { - codes: { - EVENT_DUPLICATE_EVENT: 'event.duplicate_event', - EVENT_SCHEMA_MISSING: 'event.schema_missing', - }, - info: { - 'event.duplicate_event': { - title: 'Duplicate event type', - retryable: false, - public: true, - action: - 'Two event classes registered the same type; rename one. This is a build-time bug.', - }, - 'event.schema_missing': { - title: 'Durable event without schema', - retryable: false, - public: true, - action: 'A durable event class must declare a zod payload schema for replay.', - }, - }, -} as const satisfies ErrorDomain; - -registerErrorDomain(EventErrors); - -export type EventErrorCode = (typeof EventErrors.codes)[keyof typeof EventErrors.codes]; - -export class EventError extends Error2 { - constructor(code: EventErrorCode, message: string, options?: Error2Options) { - super(code, message, options); - this.name = 'EventError'; - } -} diff --git a/packages/agent-core-v2/src/app/event/event.ts b/packages/agent-core-v2/src/app/event/event.ts index cbdbe24ce..14641c740 100644 --- a/packages/agent-core-v2/src/app/event/event.ts +++ b/packages/agent-core-v2/src/app/event/event.ts @@ -1,15 +1,26 @@ +/** + * `event` domain — process-wide pub/sub event bus contract. + * + * Defines `IEventService`, a minimal type-tagged event bus used by business + * domains to broadcast facts (for example session lifecycle changes) to an + * unknown set of consumers. Bound at App scope; a single global instance. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; import type { Event } from '#/_base/event'; -import type { Event2 } from './event2'; +export interface DomainEvent { + readonly type: string; + readonly payload: unknown; +} export interface IEventService { readonly _serviceBrand: undefined; - readonly onDidPublish: Event<Event2<any>>; - publish(event: Event2<any>): void; - subscribe(handler: (event: Event2<any>) => void): IDisposable; + readonly onDidPublish: Event<DomainEvent>; + publish(event: DomainEvent): void; + subscribe(handler: (event: DomainEvent) => void): IDisposable; } export const IEventService: ServiceIdentifier<IEventService> = diff --git a/packages/agent-core-v2/src/app/event/event2.ts b/packages/agent-core-v2/src/app/event/event2.ts deleted file mode 100644 index 62dcfb099..000000000 --- a/packages/agent-core-v2/src/app/event/event2.ts +++ /dev/null @@ -1,95 +0,0 @@ -import type { z } from 'zod'; - -import { EventError, EventErrors } from './errors'; - -export interface SerializedEvent2 { - readonly type: string; - readonly time: number; - readonly [key: string]: unknown; -} - -export class DuplicateEventError extends EventError { - constructor(readonly eventType: string) { - super( - EventErrors.codes.EVENT_DUPLICATE_EVENT, - `Duplicate event type registered: '${eventType}'`, - { details: { type: eventType } }, - ); - this.name = 'DuplicateEventError'; - } -} - -export abstract class Event2<P = Record<string, unknown>> { - declare static readonly type: string; - static readonly durable: boolean = false; - static readonly observable: boolean = false; - static readonly agentDomain: boolean = false; - declare static readonly schema: z.ZodType<any> | undefined; - - readonly type: string; - readonly time: number; - - constructor(payload: P, time?: number) { - Object.assign(this, payload); - this.type = (this.constructor as Event2Class).type; - this.time = time ?? Date.now(); - } - - serialize(): SerializedEvent2 { - const record: Record<string, unknown> = { type: this.type }; - for (const key of Object.keys(this)) { - if (key === 'type' || key === 'time') continue; - record[key] = (this as unknown as Record<string, unknown>)[key]; - } - record['time'] = this.time; - return record as SerializedEvent2; - } -} - -export interface AgentDomainTrait { - readonly agentId: string; -} - -export abstract class AgentEvent2<P extends AgentDomainTrait> extends Event2<P> { - static override readonly agentDomain = true; - - declare readonly agentId: string; -} - -export interface Event2Class<P = any, E extends Event2<P> = Event2<P>> { - new (payload: P, time?: number): E; - readonly type: string; - readonly durable: boolean; - readonly observable: boolean; - readonly agentDomain: boolean; - readonly schema: z.ZodType<P> | undefined; -} - -export const EVENT2_REGISTRY = new Map<string, Event2Class<any, any>>(); - -export function registerEvent2Class(cls: Event2Class<any, any>): void { - if (!cls.durable) return; - if (cls.schema === undefined) { - throw new EventError( - EventErrors.codes.EVENT_SCHEMA_MISSING, - `Durable event '${cls.type}' must declare a payload schema`, - { details: { type: cls.type } }, - ); - } - const existing = EVENT2_REGISTRY.get(cls.type); - if (existing === cls) return; - if (existing !== undefined) { - throw new DuplicateEventError(cls.type); - } - EVENT2_REGISTRY.set(cls.type, cls); -} - -export function event2FromRecord<P>( - cls: Event2Class<P, any>, - record: { readonly type: string; readonly time?: number } & Record<string, unknown>, -): Event2<any> | undefined { - const { type: _type, time: _time, ...payload } = record; - const parsed = cls.schema?.safeParse(payload); - if (parsed === undefined || !parsed.success) return undefined; - return new cls(parsed.data, record.time); -} diff --git a/packages/agent-core-v2/src/app/event/eventBus.ts b/packages/agent-core-v2/src/app/event/eventBus.ts index 99fdadd12..36d179e4a 100644 --- a/packages/agent-core-v2/src/app/event/eventBus.ts +++ b/packages/agent-core-v2/src/app/event/eventBus.ts @@ -1,35 +1,41 @@ +/** + * `event` domain — augmentable `DomainEventMap`, the `DomainEvent` + * discriminated union, and the `IEventBus` contract (the per-agent "what + * happened" channel) plus its DI token. + * + * `IEventBus` is the canonical fact bus for agent events: producers + * `publish(event)` and consumers `subscribe(handler)` (all events) or + * `subscribe(type, handler)` (one type). It is bound at Agent scope — one + * instance per agent — so a subscription sees only that agent's events (the + * server fans out per agent and tags `agentId` / `sessionId`). Process-global + * events (model catalog, session lifecycle, auth) stay on the legacy + * `IEventService`, which is retained as the global channel. Domains declare + * their agent-event shapes by augmenting `DomainEventMap` via + * `declare module '#/app/event/eventBus'`; `DomainEvent` resolves to the map + * entry intersected with the key-derived `{ type }`, so domains can register + * either payload-only shapes or complete protocol event types. Agent-scope; + * scope-agnostic contract. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import type { AgentDomainTrait, Event2, Event2Class } from './event2'; +// eslint-disable-next-line @typescript-eslint/no-empty-object-type +export interface DomainEventMap {} + +export type DomainEvent<K extends keyof DomainEventMap = keyof DomainEventMap> = { + [T in K]: Readonly<{ readonly type: T } & DomainEventMap[T]>; +}[K]; export interface IEventBus { readonly _serviceBrand: undefined; - publish(event: Event2<any>, agent?: AgentContext): void; - subscribe(handler: (event: Event2<any>) => void): IDisposable; - subscribe<P, E extends Event2<P>>(cls: Event2Class<P, E>, handler: (event: E) => void): IDisposable; - subscribe(type: string, handler: (event: Event2<any>) => void): IDisposable; + publish(event: DomainEvent): void; + subscribe(handler: (event: DomainEvent) => void): IDisposable; + subscribe<K extends keyof DomainEventMap>( + type: K, + handler: (event: DomainEvent<K>) => void, + ): IDisposable; } export const IEventBus: ServiceIdentifier<IEventBus> = createDecorator<IEventBus>('eventBus'); - -export interface ISessionEventBus extends IEventBus { - activateAgent(agent: AgentContext): void; - deactivateAgent(agent: AgentContext): void; - sourceOf(event: Event2<any>): AgentContext | undefined; - onAgent<P extends AgentDomainTrait, E extends Event2<P>>( - agent: AgentContext, - cls: Event2Class<P, E>, - handler: (event: E) => void, - ): IDisposable; - onAgent( - agent: AgentContext, - type: string, - handler: (event: Event2<any> & AgentDomainTrait) => void, - ): IDisposable; -} - -export const ISessionEventBus: ServiceIdentifier<ISessionEventBus> = - createDecorator<ISessionEventBus>('sessionEventBus'); diff --git a/packages/agent-core-v2/src/app/event/eventBusService.ts b/packages/agent-core-v2/src/app/event/eventBusService.ts index 340bdb16f..a9e6b26d1 100644 --- a/packages/agent-core-v2/src/app/event/eventBusService.ts +++ b/packages/agent-core-v2/src/app/event/eventBusService.ts @@ -1,196 +1,68 @@ +/** + * `event` domain — `IEventBus` implementation. + * + * Delivers published events through the `Emitter` primitive: one + * full-stream emitter for `subscribe(handler)` and a lazily-created per-type + * emitter for `subscribe(type, handler)`, so a type with no subscribers costs + * nothing on `publish`. `publish` fires the full stream first, then the + * per-type emitter (if any), preserving producer order within a single + * synchronous dispatch. Bound at Agent scope and constructed when the scope is + * created. + */ + import { type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter } from '#/_base/event'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import type { AgentDomainTrait, Event2, Event2Class } from './event2'; -import { IEventBus, ISessionEventBus } from './eventBus'; +import { type DomainEvent, type DomainEventMap, IEventBus } from './eventBus'; -export class EventBusService extends Service implements ISessionEventBus { +export class EventBusService extends Service implements IEventBus { declare readonly _serviceBrand: undefined; - private readonly allEmitter = this._register(new Emitter<Event2<any>>('*')); - private readonly perType = new Map<string, Emitter<Event2<any>>>(); - private readonly agents = new Map<string, AgentContext>(); - private readonly sources = new WeakMap<Event2<any>, AgentContext>(); + private readonly allEmitter = this._register(new Emitter<DomainEvent>('*')); + private readonly perType = new Map<keyof DomainEventMap, Emitter<DomainEvent>>(); - activateAgent(agent: AgentContext): void { - this.agents.set(agent.agentId, agent); - } - - deactivateAgent(agent: AgentContext): void { - if (this.agents.get(agent.agentId) === agent) this.agents.delete(agent.agentId); - } - - publish(event: Event2<any>, agent?: AgentContext): void { - const cls = event.constructor as Event2Class; - if (cls.agentDomain) { - if ( - agent === undefined || - this.agents.get(agent.agentId) !== agent || - (event as Event2<any> & AgentDomainTrait).agentId !== agent.agentId - ) { - throw new Error(`Agent event '${event.type}' has no active lifecycle context`); - } - } - if (agent !== undefined) this.sources.set(event, agent); + publish(event: DomainEvent): void { this.allEmitter.fire(event); this.perType.get(event.type)?.fire(event); } - sourceOf(event: Event2<any>): AgentContext | undefined { - return this.sources.get(event); - } - - onAgent<P extends AgentDomainTrait, E extends Event2<P>>( - agent: AgentContext, - cls: Event2Class<P, E>, - handler: (event: E) => void, - ): IDisposable; - onAgent( - agent: AgentContext, - type: string, - handler: (event: Event2<any> & AgentDomainTrait) => void, - ): IDisposable; - onAgent( - agent: AgentContext, - typeOrClass: string | Event2Class<any, any>, - handler: (event: any) => void, - ): IDisposable { - if (this.agents.get(agent.agentId) !== agent) { - throw new Error( - `Agent ${agent.agentId}:${String(agent.generation)} is not the active lifecycle context`, - ); - } - return this.subscribe(typeOrClass as string, (event) => { - if ( - this.agents.get(agent.agentId) === agent && - (event as Event2<any> & AgentDomainTrait).agentId === agent.agentId - ) { - handler(event); - } - }); - } - listenerCounts(): { all: number; perType: Record<string, number> } { const perType: Record<string, number> = {}; for (const [type, emitter] of this.perType) { - perType[type] = emitter.listenerCount; + perType[String(type)] = emitter.listenerCount; } return { all: this.allEmitter.listenerCount, perType }; } - subscribe(handler: (event: Event2<any>) => void): IDisposable; - subscribe<P, E extends Event2<P>>( - cls: Event2Class<P, E>, - handler: (event: E) => void, + subscribe(handler: (event: DomainEvent) => void): IDisposable; + subscribe<K extends keyof DomainEventMap>( + type: K, + handler: (event: DomainEvent<K>) => void, ): IDisposable; - subscribe(type: string, handler: (event: Event2<any>) => void): IDisposable; - subscribe( - typeOrHandler: string | Event2Class<any, any> | ((event: Event2<any>) => void), - handler?: (event: Event2<any>) => void, + subscribe<K extends keyof DomainEventMap>( + typeOrHandler: K | ((event: DomainEvent) => void), + handler?: (event: DomainEvent<K>) => void, ): IDisposable { - if (typeof typeOrHandler === 'function' && !('type' in typeOrHandler)) { - return this.allEmitter.event(typeOrHandler as (event: Event2<any>) => void); + if (typeof typeOrHandler === 'function') { + return this.allEmitter.event(typeOrHandler); } - const type = typeof typeOrHandler === 'string' ? typeOrHandler : typeOrHandler.type; + const type = typeOrHandler; let emitter = this.perType.get(type); if (emitter === undefined) { - emitter = this._register(new Emitter<Event2<any>>(type)); + emitter = this._register(new Emitter<DomainEvent>(String(type))); this.perType.set(type, emitter); } - return emitter.event(handler!); + return emitter.event(handler as unknown as (event: DomainEvent) => void); } } -export class AgentEventBusView extends Service implements IEventBus { - declare readonly _serviceBrand: undefined; - private readonly agent: AgentContext; - - constructor( - @ISessionEventBus private readonly bus: ISessionEventBus, - @IAgentScopeContext scope: IAgentScopeContext, - ) { - super(); - this.agent = scope.agentContext; - } - - activateAgent(agent: AgentContext): void { - this.bus.activateAgent(agent); - } - - deactivateAgent(agent: AgentContext): void { - this.bus.deactivateAgent(agent); - } - - publish(event: Event2<any>, agent: AgentContext = this.agent): void { - if (agent !== this.agent) throw new Error('Agent event bus view received a foreign context'); - this.bus.publish(event, this.agent); - } - - onAgent<P extends AgentDomainTrait, E extends Event2<P>>( - agent: AgentContext, - cls: Event2Class<P, E>, - handler: (event: E) => void, - ): IDisposable; - onAgent( - agent: AgentContext, - type: string, - handler: (event: Event2<any> & AgentDomainTrait) => void, - ): IDisposable; - onAgent( - agent: AgentContext, - typeOrClass: string | Event2Class<any, any>, - handler: (event: Event2<any> & AgentDomainTrait) => void, - ): IDisposable { - if (agent !== this.agent) throw new Error('Agent event bus view received a foreign context'); - return this.bus.onAgent(agent, typeOrClass as string, handler); - } - - subscribe(handler: (event: Event2<any>) => void): IDisposable; - subscribe<P, E extends Event2<P>>( - cls: Event2Class<P, E>, - handler: (event: E) => void, - ): IDisposable; - subscribe(type: string, handler: (event: Event2<any>) => void): IDisposable; - subscribe( - typeOrHandler: string | Event2Class<any, any> | ((event: Event2<any>) => void), - handler?: (event: Event2<any>) => void, - ): IDisposable { - if ((this.bus as unknown) === undefined) return { dispose: () => {} }; - const matches = (event: Event2<any>): boolean => { - const cls = event.constructor as Event2Class; - if (cls.agentDomain) { - return (event as Event2<any> & AgentDomainTrait).agentId === this.agent.agentId; - } - return this.bus.sourceOf(event) === this.agent; - }; - if (typeof typeOrHandler === 'function' && !('type' in typeOrHandler)) { - return this.bus.subscribe((event) => { - if (matches(event)) typeOrHandler(event); - }); - } - return this.bus.subscribe(typeOrHandler as string, (event) => { - if (matches(event)) handler!(event); - }); - } -} - -registerScopedService( - LifecycleScope.Session, - ISessionEventBus, - EventBusService, - ScopeActivation.OnScopeCreated, - 'event', -); - registerScopedService( LifecycleScope.Agent, IEventBus, - AgentEventBusView, - ScopeActivation.OnDemand, - 'eventView', + EventBusService, + ScopeActivation.OnScopeCreated, + 'event', ); diff --git a/packages/agent-core-v2/src/app/event/eventService.ts b/packages/agent-core-v2/src/app/event/eventService.ts index 03d5b18de..062a51e3e 100644 --- a/packages/agent-core-v2/src/app/event/eventService.ts +++ b/packages/agent-core-v2/src/app/event/eventService.ts @@ -1,27 +1,33 @@ +/** + * `event` domain — `IEventService` implementation. + * + * Delivers published events to subscribers through the `Emitter` primitive. + * Bound at App scope. + */ + import { type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; -import { IEventService } from './event'; -import type { Event2 } from './event2'; +import { type DomainEvent, IEventService } from './event'; export class EventService extends Service implements IEventService { declare readonly _serviceBrand: undefined; - private readonly emitter = this._register(new Emitter<Event2<any>>('publish')); - readonly onDidPublish: Event<Event2<any>> = this.emitter.event; + private readonly emitter = this._register(new Emitter<DomainEvent>('publish')); + readonly onDidPublish: Event<DomainEvent> = this.emitter.event; get listenerCount(): number { return this.emitter.listenerCount; } - publish(event: Event2<any>): void { + publish(event: DomainEvent): void { this.emitter.fire(event); } - subscribe(handler: (event: Event2<any>) => void): IDisposable { + subscribe(handler: (event: DomainEvent) => void): IDisposable { return this.emitter.event(handler); } } diff --git a/packages/agent-core-v2/src/app/event/fiberEventResolver.ts b/packages/agent-core-v2/src/app/event/fiberEventResolver.ts index 758cf82fb..d7bd32b4f 100644 --- a/packages/agent-core-v2/src/app/event/fiberEventResolver.ts +++ b/packages/agent-core-v2/src/app/event/fiberEventResolver.ts @@ -1,8 +1,19 @@ +/** + * `event` domain — the production `FiberEventResolver` backing the string + * form of the unit `on(...)` capability (`this.on('turn.ended', …)`). + * + * Resolves string event names against the unit scope's `IEventBus`: the + * subscription attaches as soon as the bus is materialized in the scope (or + * an ancestor), waits through a `liveRef` when it is not there yet, and + * detaches with the unit's book. Scopes without an `IEventBus` (App) simply + * never attach — per-agent domain events only exist under an Agent scope. + * Imported for the registration side effect. + */ + import { setFiberEventResolver } from '#/_base/di/fiber'; import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import type { Event2 } from './event2'; -import { IEventBus } from './eventBus'; +import { type DomainEvent, type DomainEventMap, IEventBus } from './eventBus'; setFiberEventResolver((host, event, handler) => { const busRef = host.liveRef(IEventBus); @@ -11,7 +22,10 @@ setFiberEventResolver((host, event, handler) => { if (subscription !== undefined) return; const bus = busRef.current; if (bus === undefined) return; - subscription = bus.subscribe(event, handler as (e: Event2<any>) => void); + subscription = bus.subscribe( + event as keyof DomainEventMap, + handler as (e: DomainEvent) => void, + ); }; attach(); const onChange = busRef.onDidChange(attach); diff --git a/packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunner.ts b/packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunner.ts similarity index 65% rename from packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunner.ts rename to packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunner.ts index 7f1dabdf4..95d273dde 100644 --- a/packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunner.ts +++ b/packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunner.ts @@ -1,6 +1,17 @@ +/** + * `externalHooksRunner` domain — App-scope contract for executing + * configured external hooks. + * + * A single App-scope executor owns the configured-hook lifecycle (load from + * `IConfigService` + `IPluginService`, reload on plugin change) and runs + * matching hooks. Per-scope observers inject this runner and pass per-call + * caller facts (`cwd`, `sessionId`, `signal`, matcher/payload) at trigger + * time, so the runner itself holds no per-scope state. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; -import type { HookBlockDecision, HookMatcherValue, HookResult } from '../internal/types'; +import type { HookBlockDecision, HookMatcherValue, HookResult } from '#/agent/externalHooks/types'; export interface ExternalHooksRunnerTriggerArgs { readonly matcherValue?: HookMatcherValue; @@ -13,6 +24,7 @@ export interface ExternalHooksRunnerTriggerArgs { export interface IExternalHooksRunnerService { readonly _serviceBrand: undefined; readonly ready: Promise<void>; + /** Fired after the hook index is (re)built — initial load and plugin reloads. */ readonly onDidReload: Event<void>; trigger(event: string, args?: ExternalHooksRunnerTriggerArgs): Promise<HookResult[]>; triggerBlock( diff --git a/packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunnerService.ts b/packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunnerService.ts similarity index 67% rename from packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunnerService.ts rename to packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunnerService.ts index cf0188c49..6bacea0fd 100644 --- a/packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunnerService.ts +++ b/packages/agent-core-v2/src/app/externalHooksRunner/externalHooksRunnerService.ts @@ -1,19 +1,38 @@ +/** + * `externalHooksRunner` domain — `IExternalHooksRunnerService` impl. + * + * Owns the configured-hook lifecycle: builds the event→hooks index from + * `IConfigService` (`[[hooks]]`) + `IPluginService.enabledHooks()`, reloads it + * on `plugin.onDidReload`, and dispatches each trigger through the pure + * `runMatchedHooks`. The App-scope `IHostProcessService` is injected here and + * threaded down to `runHook`, so hook commands spawn through the shared host + * process service (cross-platform kill, hidden console on Windows) rather than + * `node:child_process` directly. Per-call caller facts (`cwd` defaulting to + * bootstrap cwd, `sessionId`, `signal`, payload) flow in through the args, so + * this service keeps no per-scope state; the one payload field it contributes + * itself is `clientType` (the host platform from bootstrap client identity), + * merged under the caller's `inputData`. Bound at App scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; import { IPluginService } from '#/app/plugin/plugin'; +import { HOOKS_SECTION, type HookDefConfig } from '#/agent/externalHooks/configSection'; +import type { HookBlockDecision, HookDef, HookResult } from '#/agent/externalHooks/types'; import { IHostProcessService } from '#/os/interface/hostProcess'; -import { HOOKS_SECTION, type HookDefConfig } from '../configSection'; import { IExternalHooksRunnerService, type ExternalHooksRunnerTriggerArgs, } from './externalHooksRunner'; -import { blockDecision, indexHooks, runMatchedHooks } from '../internal/matchHooks'; -import type { HookRunCallbacks } from '../internal/matchHooks'; -import type { HookBlockDecision, HookDef, HookResult } from '../internal/types'; +import { blockDecision, indexHooks, runMatchedHooks } from './runner'; +import type { HookRunCallbacks } from './runner'; +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class ExternalHooksRunnerService extends Disposable implements IExternalHooksRunnerService { declare readonly _serviceBrand: undefined; @@ -118,3 +137,11 @@ export class ExternalHooksRunnerService extends Disposable implements IExternalH this._onDidReload.fire(); } } + +registerScopedService( + LifecycleScope.App, + IExternalHooksRunnerService, + ExternalHooksRunnerService, + ScopeActivation.OnScopeCreated, + 'externalHooksRunner', +); diff --git a/packages/agent-core-v2/src/app/externalHooksRunner/index.ts b/packages/agent-core-v2/src/app/externalHooksRunner/index.ts new file mode 100644 index 000000000..e747fee31 --- /dev/null +++ b/packages/agent-core-v2/src/app/externalHooksRunner/index.ts @@ -0,0 +1,9 @@ +/** + * `externalHooksRunner` domain barrel — re-exports the App-scope + * `IExternalHooksRunnerService` contract and its implementation, plus the + * argument shape shared by callers. Importing this barrel registers the + * App-scope runner binding into the scope registry. + */ + +export * from './externalHooksRunner'; +export * from './externalHooksRunnerService'; diff --git a/packages/agent-core-v2/src/features/externalHooks/internal/matchHooks.ts b/packages/agent-core-v2/src/app/externalHooksRunner/runner.ts similarity index 83% rename from packages/agent-core-v2/src/features/externalHooks/internal/matchHooks.ts rename to packages/agent-core-v2/src/app/externalHooksRunner/runner.ts index 4266078c8..745846065 100644 --- a/packages/agent-core-v2/src/features/externalHooks/internal/matchHooks.ts +++ b/packages/agent-core-v2/src/app/externalHooksRunner/runner.ts @@ -1,14 +1,25 @@ -import type { IHostProcessService } from '#/os/interface/hostProcess'; +/** + * `externalHooksRunner` domain — pure hook matching/dispatch logic. + * + * Owns deciding *which* hooks run for an event and executing them: building + * the event→hooks index, + * regex matching by matcher value, de-duplication per `(cwd, command)`, and + * spawning each matched command via the shared `runHook` spawner (which runs + * through the App-scope `IHostProcessService` passed in by the service). Holds + * no config/plugin state and no per-scope facts — those come in per call. Pure + * helper module, not a scoped Service. + */ -import { runHook } from './runHook'; +import { runHook } from '#/agent/externalHooks/runner'; import type { HookBlockDecision, HookDef, HookMatcherValue, HookResult, -} from './types'; +} from '#/agent/externalHooks/types'; +import type { IHostProcessService } from '#/os/interface/hostProcess'; -import type { ExternalHooksRunnerTriggerArgs } from '../app/externalHooksRunner'; +import type { ExternalHooksRunnerTriggerArgs } from './externalHooksRunner'; const DEFAULT_HOOK_TIMEOUT_SECONDS = 30; diff --git a/packages/agent-core-v2/src/app/feature/featureManager.ts b/packages/agent-core-v2/src/app/feature/featureManager.ts index 248ab0aa8..6694d6bb3 100644 --- a/packages/agent-core-v2/src/app/feature/featureManager.ts +++ b/packages/agent-core-v2/src/app/feature/featureManager.ts @@ -1,3 +1,22 @@ +/** + * `feature` domain — `IFeatureManager`: dynamic unit assembly at App scope. + * + * The FeatureManager is the slim business-layer owner of "everything is a + * service" at runtime (§5.10 of the plan): it assembles feature recipes into + * live units through the SAME provide path the kernel uses statically + * (`this.provide`), tracks them for introspection (kimi-inspect), and + * retracts them on demand. Units it assembles hang on its own book — manager + * death retracts every managed unit. + * + * Deliberately NOT here (by design, Phase 3): + * - external package management (install / marketplace metadata) stays with + * `IPluginService` — "plugin" is the external world's word; the kernel and + * this manager only know recipes; + * - the enablement-set persistence for dynamic features lands with the + * per-domain flipping of Phase 5 (no external recipe sources exist yet); + * - per-domain flipping of built-in domains is Phase 5. + */ + import type { Event } from '#/_base/event'; import type { FiberHandle, @@ -7,13 +26,11 @@ import type { ServiceRecipe, } from '#/_base/di/fiber'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { ContributedFeatureService } from './featureServiceContribution'; export interface ManagedUnitInfo { readonly name: string; readonly state: FiberState; readonly uid: number | undefined; - readonly meta: Record<string, unknown>; } export interface IFeatureManager { @@ -29,7 +46,6 @@ export interface IFeatureManager { updateUnit(name: string, config?: unknown): Promise<void>; units(): readonly ManagedUnitInfo[]; - contributedServices(): readonly ContributedFeatureService[]; readonly onDidChangeUnits: Event<void>; } diff --git a/packages/agent-core-v2/src/app/feature/featureManagerService.ts b/packages/agent-core-v2/src/app/feature/featureManagerService.ts index f44514976..7e521c720 100644 --- a/packages/agent-core-v2/src/app/feature/featureManagerService.ts +++ b/packages/agent-core-v2/src/app/feature/featureManagerService.ts @@ -1,9 +1,17 @@ -import type { CollectionView } from '#/_base/di/collection'; +/** + * `feature` domain — `FeatureManagerService`: the App-scope unit manager. + * + * See `featureManager.ts` for the domain contract. Implementation notes: + * managed units are assembled through this unit's own `this.provide`, so + * they anchor on its book (manager death retracts them all); the managed set + * is keyed by unit name — a second `provideUnit` of the same name replaces + * the previous handle (retract-then-assemble is the caller's cascade). + */ + import { Emitter, type Event } from '#/_base/event'; import type { FiberHandle, FiberProvideOptions, - RecipeStatics, ServiceClassRecipe, ServiceRecipe, } from '#/_base/di/fiber'; @@ -15,25 +23,15 @@ import { IFeatureManager, type ManagedUnitInfo, } from './featureManager'; -import { - FeatureServiceContribution, - type ContributedFeatureService, -} from './featureServiceContribution'; export class FeatureManagerService extends Service implements IFeatureManager { declare readonly _serviceBrand: undefined; - private readonly _units = new Map< - string, - { handle: FiberHandle; meta: Record<string, unknown> } - >(); + private readonly _units = new Map<string, FiberHandle>(); private readonly _onDidChangeUnits = new Emitter<void>(); readonly onDidChangeUnits: Event<void> = this._onDidChangeUnits.event; - constructor( - @FeatureServiceContribution - private readonly _contributedServices: CollectionView<ContributedFeatureService>, - ) { + constructor() { super(); this._register(this._onDidChangeUnits); } @@ -45,7 +43,9 @@ export class FeatureManagerService extends Service implements IFeatureManager { opts?: FiberProvideOptions, ): FiberHandle<T>; provideUnit( + // eslint-disable-next-line @typescript-eslint/no-explicit-any first: ServiceRecipe | ServiceIdentifier<any>, + // eslint-disable-next-line @typescript-eslint/no-explicit-any second?: any, third?: FiberProvideOptions, ): FiberHandle { @@ -54,54 +54,49 @@ export class FeatureManagerService extends Service implements IFeatureManager { : this.provide(first as ServiceRecipe, second as FiberProvideOptions | undefined); const name = handle.name; const previous = this._units.get(name); - if (previous !== undefined && previous.handle !== handle) { - void previous.handle.dispose(); + if (previous !== undefined && previous !== handle) { + void previous.dispose(); } - const statics = (isServiceIdentifier(first) ? second : first) as RecipeStatics; - this._units.set(name, { handle, meta: Object.freeze({ ...statics.meta }) }); + this._units.set(name, handle); this._onDidChangeUnits.fire(); return handle; } async unprovideUnit(name: string): Promise<void> { - const entry = this._units.get(name); - if (entry === undefined) { + const handle = this._units.get(name); + if (handle === undefined) { return; } this._units.delete(name); try { - await entry.handle.dispose(); + await handle.dispose(); } finally { this._onDidChangeUnits.fire(); } } async updateUnit(name: string, config?: unknown): Promise<void> { - const entry = this._units.get(name); - if (entry === undefined) { + const handle = this._units.get(name); + if (handle === undefined) { throw new Error(`feature unit '${name}' is not managed by this FeatureManager`); } - await entry.handle.update(config); + await handle.update(config); this._onDidChangeUnits.fire(); } units(): readonly ManagedUnitInfo[] { const infos: ManagedUnitInfo[] = []; - for (const [name, entry] of this._units) { + for (const [name, handle] of this._units) { let uid: number | undefined; try { - uid = entry.handle.uid; + uid = handle.uid; } catch { uid = undefined; } - infos.push({ name, state: entry.handle.state, uid, meta: entry.meta }); + infos.push({ name, state: handle.state, uid }); } return infos; } - - contributedServices(): readonly ContributedFeatureService[] { - return this._contributedServices.items; - } } registerScopedService( diff --git a/packages/agent-core-v2/src/app/feature/featureServiceContribution.ts b/packages/agent-core-v2/src/app/feature/featureServiceContribution.ts deleted file mode 100644 index 635b152a4..000000000 --- a/packages/agent-core-v2/src/app/feature/featureServiceContribution.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { collection } from '#/_base/di/collection'; -import type { ServiceIdentifier } from '#/_base/di/instantiation'; -import type { LifecycleScope } from '#/app/scopes'; - -export interface ContributedFeatureService { - readonly scope: LifecycleScope; - readonly id: ServiceIdentifier<unknown>; -} - -export const FeatureServiceContribution = collection<ContributedFeatureService>( - 'feature-service', - { - validate(value, existing) { - if (existing.some((entry) => entry.scope === value.scope && entry.id === value.id)) { - throw new Error( - `Service ${String(value.id)} is already contributed at scope ${value.scope}`, - ); - } - }, - }, -); diff --git a/packages/agent-core-v2/src/app/file/fileService.ts b/packages/agent-core-v2/src/app/file/fileService.ts index 71ee5ef64..2dbab3643 100644 --- a/packages/agent-core-v2/src/app/file/fileService.ts +++ b/packages/agent-core-v2/src/app/file/fileService.ts @@ -1,3 +1,11 @@ +/** + * `file` domain — `IFileService` contract and error helpers. + * + * Process-global upload store: persists uploaded bytes via `IBlobStore` and + * their `FileMeta` index in the same store, then hands callers a stream back + * on download. Bound at App scope. + */ + import type { Readable } from 'node:stream'; import { z } from 'zod'; @@ -43,11 +51,6 @@ export interface IFileService { export const IFileService: ServiceIdentifier<IFileService> = createDecorator<IFileService>('fileService'); -export const FILE_ID_REGEX = /^f_[A-Za-z0-9][A-Za-z0-9_-]*$/; - -export function isFileId(value: string): boolean { - return FILE_ID_REGEX.test(value); -} export const FileErrors = { codes: { diff --git a/packages/agent-core-v2/src/app/file/fileServiceImpl.ts b/packages/agent-core-v2/src/app/file/fileServiceImpl.ts index dacab17c0..d3de270f0 100644 --- a/packages/agent-core-v2/src/app/file/fileServiceImpl.ts +++ b/packages/agent-core-v2/src/app/file/fileServiceImpl.ts @@ -1,14 +1,25 @@ +/** + * `file` domain — `IFileService` implementation. + * + * Streams uploads into the `IBlobStore` under the `files` scope and keeps a + * JSON `FileMeta` index in the same store under the `file` scope. Uploads are + * written incrementally (`putStream`), so their size is bounded by disk, not + * memory; the service counts bytes as they flow through to record + * `FileMeta.size`. Prunes the index when a referenced blob is missing, and + * hands downloads back as a lazy `Readable` over `getStream`. Bound at App + * scope. + */ + import { randomUUID } from 'node:crypto'; import { Readable } from 'node:stream'; +import type { FileMeta } from './fileService'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IBlobStore } from '#/persistence/interface/blobStore'; import { IFileService, fileNotFoundError, - isFileId, - type FileMeta, type FileReadRange, type GetResult, type SaveOptions, @@ -17,6 +28,7 @@ import { const BLOB_SCOPE = 'files'; const INDEX_SCOPE = 'file'; const INDEX_KEY = 'index.json'; +const FILE_ID_REGEX = /^f_[A-Za-z0-9][A-Za-z0-9_-]*$/; const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); @@ -26,6 +38,10 @@ interface IndexFile { readonly files: FileMeta[]; } +function isFileId(value: string): boolean { + return FILE_ID_REGEX.test(value); +} + function isFileMeta(value: unknown): value is FileMeta { if (typeof value !== 'object' || value === null || Array.isArray(value)) return false; const meta = value as Record<string, unknown>; @@ -47,13 +63,11 @@ export class FileServiceImpl implements IFileService { private indexCache: Map<string, FileMeta> | undefined; private indexLoadPromise: Promise<void> | undefined; - private indexWritePromise: Promise<void> = Promise.resolve(); constructor(@IBlobStore private readonly blobs: IBlobStore) {} async save(source: Readable, filename: string, options: SaveOptions = {}): Promise<FileMeta> { await this.ensureIndex(); - await this.pruneExpired(); const id = `f_${randomUUID()}`; let size = 0; @@ -78,10 +92,9 @@ export class FileServiceImpl implements IFileService { media_type: options.mimeType ?? 'application/octet-stream', size, created_at: new Date(now).toISOString(), - expires_at: - options.expiresInSec === undefined - ? undefined - : new Date(now + options.expiresInSec * 1000).toISOString(), + ...(options.expiresInSec !== undefined + ? { expires_at: new Date(now + options.expiresInSec * 1000).toISOString() } + : {}), }; this.indexCache!.set(id, meta); @@ -94,7 +107,6 @@ export class FileServiceImpl implements IFileService { throw fileNotFoundError(fileId); } await this.ensureIndex(); - await this.pruneExpired(); const meta = this.indexCache!.get(fileId); if (meta === undefined) { throw fileNotFoundError(fileId); @@ -153,36 +165,16 @@ export class FileServiceImpl implements IFileService { } } this.indexCache = map; - await this.pruneExpired(); } catch { this.indexCache = new Map(); } } - private async pruneExpired(): Promise<void> { + private async writeIndex(): Promise<void> { const cache = this.indexCache; if (cache === undefined) return; - const now = Date.now(); - const expired = [...cache.values()].filter( - (meta) => meta.expires_at !== undefined && Date.parse(meta.expires_at) <= now, - ); - if (expired.length === 0) return; - for (const meta of expired) { - cache.delete(meta.id); - await this.blobs.delete(BLOB_SCOPE, meta.id).catch(() => undefined); - } - await this.writeIndex().catch(() => undefined); - } - - private async writeIndex(): Promise<void> { - const write = this.indexWritePromise.catch(() => undefined).then(async () => { - const cache = this.indexCache; - if (cache === undefined) return; - const payload: IndexFile = { version: 1, files: Array.from(cache.values()) }; - await this.blobs.put(INDEX_SCOPE, INDEX_KEY, textEncoder.encode(JSON.stringify(payload))); - }); - this.indexWritePromise = write; - await write; + const payload: IndexFile = { version: 1, files: Array.from(cache.values()) }; + await this.blobs.put(INDEX_SCOPE, INDEX_KEY, textEncoder.encode(JSON.stringify(payload))); } } diff --git a/packages/agent-core-v2/src/app/flag/flag.ts b/packages/agent-core-v2/src/app/flag/flag.ts index 9faef65be..c321397bb 100644 --- a/packages/agent-core-v2/src/app/flag/flag.ts +++ b/packages/agent-core-v2/src/app/flag/flag.ts @@ -1,3 +1,15 @@ +/** + * `flag` domain — experimental-flag resolution contract. + * + * Defines the `IFlagService` used to check whether a flag is enabled, snapshot + * and explain flag state, and apply config overrides, together with the + * flag-resolution types (`ExperimentalFeatureState`, `ExperimentalFlagConfig`, + * `ExperimentalFlagSource`). Owns the `[experimental]` config section, whose + * keys are flag ids and are preserved verbatim (no snake ↔ camel conversion) by + * its TOML read/write transforms. App-scoped — one instance shared across the + * process. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/app/flag/flagRegistry.ts b/packages/agent-core-v2/src/app/flag/flagRegistry.ts index 68f6eccf7..b3059242e 100644 --- a/packages/agent-core-v2/src/app/flag/flagRegistry.ts +++ b/packages/agent-core-v2/src/app/flag/flagRegistry.ts @@ -1,3 +1,13 @@ +/** + * `flag` domain — flag-definition registry contract. + * + * `IFlagRegistry` is the writable catalog that `IFlagService` reads flag + * definitions from. Definitions are contributed **decentrally**: each domain + * calls `registerFlagDefinition` from its own module's top level, and + * `FlagRegistryService` drains those contributions when it is instantiated. + * There is no central catalog to edit by hand. App-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/app/flag/flagRegistryService.ts b/packages/agent-core-v2/src/app/flag/flagRegistryService.ts index 174b295d6..7f48e814d 100644 --- a/packages/agent-core-v2/src/app/flag/flagRegistryService.ts +++ b/packages/agent-core-v2/src/app/flag/flagRegistryService.ts @@ -1,3 +1,11 @@ +/** + * `flag` domain — `IFlagRegistry` implementation. + * + * In-memory catalog of flag definitions. Seeds itself from the import-time + * contributions (`getContributedFlags`) on construction, and also accepts + * runtime `register` calls (used by tests). Bound at App scope. + */ + import { Disposable, type IDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -10,6 +18,7 @@ import { IFlagRegistry, } from './flagRegistry'; +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class FlagRegistryService extends Disposable implements IFlagRegistry { declare readonly _serviceBrand: undefined; private readonly byId = new Map<FlagId, FlagDefinitionInput>(); diff --git a/packages/agent-core-v2/src/app/flag/flagService.ts b/packages/agent-core-v2/src/app/flag/flagService.ts index b8264b7bd..e2dcd1aa9 100644 --- a/packages/agent-core-v2/src/app/flag/flagService.ts +++ b/packages/agent-core-v2/src/app/flag/flagService.ts @@ -1,3 +1,11 @@ +/** + * `flag` domain — `IFlagService` implementation. + * + * Resolves experimental flags from the environment, the `[experimental]` + * config section, and defaults; reads flag definitions from the registry, and + * reads/watches config. Bound at App scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -17,6 +25,7 @@ import { type FlagDefinitionInput, type FlagId, IFlagRegistry } from './flagRegi export const MASTER_ENV = 'KIMI_CODE_EXPERIMENTAL_FLAG'; +// NOTE: stays Disposable — its own 'state' and 'config' collide with the Fiber export class FlagService extends Disposable implements IFlagService { declare readonly _serviceBrand: undefined; readonly registry: IFlagRegistry; diff --git a/packages/agent-core-v2/src/app/gateway/gateway.ts b/packages/agent-core-v2/src/app/gateway/gateway.ts index 3240555ae..f4cc0bfa7 100644 --- a/packages/agent-core-v2/src/app/gateway/gateway.ts +++ b/packages/agent-core-v2/src/app/gateway/gateway.ts @@ -1,3 +1,10 @@ +/** + * `gateway` domain — REST/WS gateways. + * + * Defines the public contracts of the gateway layer: the `IRestGateway` / + * `IWSGateway` entry points. App-scoped — shared across the application. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IRestGateway { diff --git a/packages/agent-core-v2/src/app/gateway/gatewayService.ts b/packages/agent-core-v2/src/app/gateway/gatewayService.ts index 7b3e28dc6..fd6cedf50 100644 --- a/packages/agent-core-v2/src/app/gateway/gatewayService.ts +++ b/packages/agent-core-v2/src/app/gateway/gatewayService.ts @@ -1,3 +1,14 @@ +/** + * `gateway` domain — `IRestGateway` / `IWSGateway` implementations. + * + * Owns the REST/WS entry points; resolves sessions through the live workspace + * handler registry and agents through the agent lifecycle, drives turns, and + * flushes logs. Bound at App scope. + * + * WS event fan-out (sequencing, journaling, replay, per-connection dispatch) + * is a transport concern of the edge server, not of this module. + */ + import { LifecycleScope } from '#/app/scopes'; import { @@ -8,7 +19,8 @@ import { import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { Error2, ErrorCodes } from '#/errors'; import { ILogService } from '#/_base/log/log'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; +import { IWorkspaceLifecycleService } from '#/app/workspaceLifecycle/workspaceLifecycle'; +import { ISessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycle'; import { IAgentPromptService } from '#/agent/prompt/prompt'; import { IAgentLoopService } from '#/agent/loop/loop'; @@ -18,7 +30,7 @@ export class RestGateway implements IRestGateway { declare readonly _serviceBrand: undefined; constructor( - @ISessionManager private readonly sessions: ISessionManager, + @IWorkspaceLifecycleService private readonly workspaceLifecycle: IWorkspaceLifecycleService, @ILogService private readonly log: ILogService, ) { } @@ -30,7 +42,7 @@ export class RestGateway implements IRestGateway { }); } const agents = session.accessor.get(IAgentLifecycleService); - const agent = agents.handleOf(agentId); + const agent = agents.get(agentId); if (agent === undefined) { throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `unknown agent '${agentId}'`, { details: { agentId, sessionId }, @@ -40,7 +52,11 @@ export class RestGateway implements IRestGateway { } private liveSession(sessionId: string) { - return this.sessions.get(sessionId); + for (const handler of this.workspaceLifecycle.handlers.list()) { + const handle = handler.accessor.get(ISessionLifecycleService).get(sessionId); + if (handle !== undefined) return handle; + } + return undefined; } async prompt( diff --git a/packages/agent-core-v2/src/app/git/git.ts b/packages/agent-core-v2/src/app/git/git.ts index c4291df5d..2ac47dd5b 100644 --- a/packages/agent-core-v2/src/app/git/git.ts +++ b/packages/agent-core-v2/src/app/git/git.ts @@ -1,3 +1,15 @@ +/** + * `git` domain — git integration for a repository on the local disk. + * + * Defines the `IGitService` that runs `git status` / `git diff` (plus `gh pr + * view`) against a repository identified by an absolute `cwd`, and discovers + * the enclosing git work tree of a directory (`findWorkTree`). App-scoped; it + * spawns `git` / `gh` through the host process service rather than a + * Session's execution environment, so it never depends on a Session. Path + * confinement is the caller's responsibility — the service receives + * already-resolved absolute `cwd` and repo-relative paths. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/app/git/gitParsers.ts b/packages/agent-core-v2/src/app/git/gitParsers.ts index c23f254a8..a3a1f0862 100644 --- a/packages/agent-core-v2/src/app/git/gitParsers.ts +++ b/packages/agent-core-v2/src/app/git/gitParsers.ts @@ -1,3 +1,11 @@ +/** + * `git` domain — pure git-output parsers. + * + * Parses `git status --porcelain=v1 --branch`, `git diff --numstat`, and + * `gh pr view --json` output into the protocol `FsGitStatusResponse` shape. + * No IO, no DI — plain functions so they can be unit-tested directly. + */ + import type { FsGitStatus, FsGitStatusResponse, FsPullRequest } from './git'; export function parsePorcelain( diff --git a/packages/agent-core-v2/src/app/git/gitService.ts b/packages/agent-core-v2/src/app/git/gitService.ts index f2c100bf7..2ccb7714c 100644 --- a/packages/agent-core-v2/src/app/git/gitService.ts +++ b/packages/agent-core-v2/src/app/git/gitService.ts @@ -1,9 +1,21 @@ +/** + * `git` domain — `IGitService` implementation. + * + * Runs `git status` / `git diff` (and `gh pr view`) against a repository on + * the local disk, and discovers the enclosing git work tree of a directory + * (`findWorkTree`). Process spawning goes through the App-scope + * `IHostProcessService`, and the single path-existence probe in `diff` goes + * through `IHostFileSystem`; no Node platform API is imported directly. Bound + * at App scope — it owns no Session dependency, so the caller supplies an + * absolute `cwd` and already-confined repo-relative paths. + */ + import type { FsDiffResponse, FsGitStatusResponse, FsPullRequest } from './git'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ErrorCodes, Error2 } from '#/errors'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IRuntimeResolver, IWorkspaceInstanceManager } from '#/workspace/workspaceInstance/workspaceInstanceManager'; +import { IHostProcessService } from '#/os/interface/hostProcess'; import { IGitService } from './git'; import { parseNumstat, parsePorcelain, parsePullRequest } from './gitParsers'; @@ -23,8 +35,7 @@ export class GitService implements IGitService { >(); constructor( - @IRuntimeResolver private readonly resolver: IRuntimeResolver, - @IWorkspaceInstanceManager private readonly workspaces: IWorkspaceInstanceManager, + @IHostProcessService private readonly hostProcess: IHostProcessService, @IHostFileSystem private readonly fs: IHostFileSystem, ) {} @@ -144,9 +155,7 @@ export class GitService implements IGitService { cwd: string, options: RunOptions = {}, ): Promise<RunResult> { - const workspaceId = this.resolveWorkspaceId(cwd); - const lease = this.resolver.acquire({ workspaceId, runtimeId: 'local' }, ['process']); - const spawned = await lease.runtime.process! + const spawned = await this.hostProcess .spawn(cmd, args, { cwd, env: options.env }) .then( (proc) => ({ ok: true as const, proc }), @@ -191,19 +200,10 @@ export class GitService implements IGitService { return { exitCode: -1, stdout, stderr }; } finally { if (timer !== undefined) clearTimeout(timer); - void proc.dispose(); - lease.dispose(); + proc.dispose(); } } - private resolveWorkspaceId(cwd: string): string { - const workspace = this.workspaces.findByRoot(cwd); - if (workspace === undefined) { - throw new Error(`workspace for root ${cwd} is not materialized`); - } - return workspace.id; - } - private gitUnavailable(cwd: string, detail: string): Error2 { return new Error2(ErrorCodes.FS_GIT_UNAVAILABLE, `git unavailable at ${cwd}: ${detail}`, { details: { cwd, detail }, diff --git a/packages/agent-core-v2/src/app/git/workTree.ts b/packages/agent-core-v2/src/app/git/workTree.ts index 42b30154d..b34d7345b 100644 --- a/packages/agent-core-v2/src/app/git/workTree.ts +++ b/packages/agent-core-v2/src/app/git/workTree.ts @@ -1,3 +1,15 @@ +/** + * `git` domain — git work-tree discovery. + * + * Walks up from a directory to find the enclosing git work tree: the nearest + * ancestor containing a `.git` entry, either a directory (plain repository) + * or a file holding a `gitdir:` pointer (linked worktree / submodule) whose + * target is resolved into `controlDirPath`. Entries that are neither — or + * files without a parseable pointer — do not count and the walk continues. + * All filesystem access goes through the os `IHostFileSystem` and paths are + * pathe-normalized (Windows-aware, forward slashes). Pure functions. + */ + import { dirname, isAbsolute, join, normalize } from 'pathe'; import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; diff --git a/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowser.ts b/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowser.ts index 35890582f..6db7396fd 100644 --- a/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowser.ts +++ b/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowser.ts @@ -1,3 +1,15 @@ +/** + * `hostFolderBrowser` domain — host-side folder picker. + * + * Defines the `IHostFolderBrowser` used by the program side (TUI / server) to + * let the user browse the real local filesystem when choosing a workspace + * folder. App-scoped. + * + * The wire shapes (`FsBrowseResponse` / `FsHomeResponse`) are defined here as + * zod schemas. Domain errors (`HostFolder*Error`) carry the failing path and + * are translated to wire error codes at the transport boundary. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowserService.ts b/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowserService.ts index 148436a7a..c262ca37f 100644 --- a/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowserService.ts +++ b/packages/agent-core-v2/src/app/hostFolderBrowser/hostFolderBrowserService.ts @@ -1,3 +1,12 @@ +/** + * `hostFolderBrowser` domain — `IHostFolderBrowser` implementation. + * + * Browses the real local filesystem through `node:fs/promises` and derives + * `recent_roots` from the process-wide `IWorkspaceService`. Bound at App + * scope. Preserves the legacy wire behaviour: realpath resolution, + * directory-only entries, dot-last sorting, and `parent` resolution. + */ + import { readdir, realpath } from 'node:fs/promises'; import { homedir } from 'node:os'; import { dirname, isAbsolute, join } from 'node:path'; diff --git a/packages/agent-core-v2/src/app/kosongConfig/builtInModelsDev.ts b/packages/agent-core-v2/src/app/kosongConfig/builtInModelsDev.ts index 36b213139..05f32af74 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/builtInModelsDev.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/builtInModelsDev.ts @@ -1,3 +1,6 @@ +// Filled by tsdown define in release builds: the final bundler injects the +// generated models.dev snapshot. Source stays empty so the snapshot is not +// committed. declare const __KIMI_CODE_BUILT_IN_CATALOG__: string | undefined; export const BUILT_IN_MODELS_DEV_JSON: string | undefined = diff --git a/packages/agent-core-v2/src/app/kosongConfig/configSection.ts b/packages/agent-core-v2/src/app/kosongConfig/configSection.ts index b7870ca0a..7af26196b 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/configSection.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/configSection.ts @@ -1,8 +1,31 @@ +/** + * `kosongConfig` domain — config-section declarations for kosong. + * + * The persistence wrapper for kosong's provider/model registries and the + * thinking / model-catalog / secondary-model preferences: declares every + * kosong-owned section constant and its zod schema, plus the env bindings / + * write-path strips and the snake_case ↔ camelCase TOML transforms. Where + * kosong owns a pure type (`providers` / `models` / `thinking`), the schema + * is re-derived from it and pinned by an `AssertExact` assertion (schema ≡ + * type at compile time); `modelCatalog` and `secondaryModel` have no + * kosong-side type — theirs derive from the local schemas. Self-registered + * at module load via `registerConfigSection`. + * + * `ProviderTypeSchema` is deliberately free-form text: vendor identity is + * NOT enumerated at parse time. Validation happens at resolve time against + * kosong's provider-definition registry, which is what allows external + * packages to register new vendors without touching this schema. + * + * Side-effect module: production imports it for the registration side + * effects; tests import it on demand. + */ + import { z } from 'zod'; import { type ConfigStripEnv, envBindings, + stripEnvBoundFields, } from '#/app/config/config'; import { registerConfigSection } from '#/app/config/configSectionContributions'; import { @@ -20,6 +43,7 @@ import type { ThinkingConfig } from '#/kosong/model/thinking'; import type { OAuthRef, ProviderConfig, ProvidersSection } from '#/kosong/provider/provider'; import { ProtocolSchema } from '#/kosong/protocol/protocol'; + export const PROVIDERS_SECTION = 'providers'; export const DEFAULT_PROVIDER_SECTION = 'defaultProvider'; @@ -137,6 +161,7 @@ registerConfigSection(PROVIDERS_SECTION, ProvidersSectionSchema, { toToml: providersToToml, }); + export const MODELS_SECTION = 'models'; export const DEFAULT_MODEL_SECTION = 'defaultModel'; @@ -257,6 +282,7 @@ registerConfigSection(MODELS_SECTION, ModelsSectionSchema, { toToml: modelsToToml, }); + export const THINKING_SECTION = 'thinking'; export const ThinkingConfigSchema = z.object({ @@ -285,6 +311,33 @@ registerConfigSection(THINKING_SECTION, ThinkingConfigSchema, { stripEnv: stripThinkingEnv, }); +export const SECONDARY_MODEL_SECTION = 'secondaryModel'; + +export const SECONDARY_MODEL_ENV = 'KIMI_SECONDARY_MODEL'; +export const SECONDARY_MODEL_EFFORT_ENV = 'KIMI_SECONDARY_EFFORT'; + +export const SecondaryModelConfigSchema = ModelOverrideSchema.extend({ + model: z.string().min(1).optional(), +}); + +export type SecondaryModelConfig = z.infer<typeof SecondaryModelConfigSchema>; + +function parseNonEmptyEnv(raw: string): string | undefined { + const trimmed = raw.trim(); + return trimmed.length > 0 ? trimmed : undefined; +} + +export const secondaryModelEnvBindings = envBindings(SecondaryModelConfigSchema, { + model: { env: SECONDARY_MODEL_ENV, parse: parseNonEmptyEnv }, + defaultEffort: { env: SECONDARY_MODEL_EFFORT_ENV, parse: parseNonEmptyEnv }, +}); + +registerConfigSection(SECONDARY_MODEL_SECTION, SecondaryModelConfigSchema, { + env: secondaryModelEnvBindings, + stripEnv: stripEnvBoundFields(secondaryModelEnvBindings), +}); + + export const MODEL_CATALOG_SECTION = 'modelCatalog'; export const ModelCatalogConfigSchema = z.object({ diff --git a/packages/agent-core-v2/src/app/kosongConfig/discovery.ts b/packages/agent-core-v2/src/app/kosongConfig/discovery.ts index fcb499fd8..2e2062a7b 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/discovery.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/discovery.ts @@ -1,8 +1,18 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `kosongConfig` domain — `IProviderDiscoveryService`: remote model + * discovery and config sync. + * + * Refreshes the `[models.*]` / `[providers.*]` configuration from what each + * provider actually serves (managed OAuth catalogs, open platforms, custom + * registries) through the shared OAuth orchestrator, applies the result to + * kosong's in-memory registries (the persistence bridge writes it back to + * config), and publishes `event.model_catalog.changed` on change. This is a + * WRITE path (external world → kosong → config). + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { Event2 } from '#/app/event/event2'; export const providerRefreshChangeSchema = z.object({ provider_id: z.string().min(1), @@ -29,15 +39,6 @@ export type RefreshProviderModelsResponse = z.infer< export type RefreshProviderModelsScope = 'all' | 'oauth'; -export class ModelCatalogChanged extends Event2<{ - readonly payload: RefreshProviderModelsResponse; -}> { - static override readonly type = 'event.model_catalog.changed'; -} -export interface ModelCatalogChanged { - readonly payload: RefreshProviderModelsResponse; -} - export interface RefreshProviderModelsOptions { readonly scope?: RefreshProviderModelsScope; readonly providerId?: string; diff --git a/packages/agent-core-v2/src/app/kosongConfig/discoveryService.ts b/packages/agent-core-v2/src/app/kosongConfig/discoveryService.ts index ef5815b82..76ffe7b5a 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/discoveryService.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/discoveryService.ts @@ -1,3 +1,44 @@ +/** + * `kosongConfig` domain — `IProviderDiscoveryService` implementation. + * + * Owns the all-provider model refresh: delegates to the shared OAuth + * orchestrator (managed OAuth + open platforms + custom registries), writes + * the discovered providers/models into config through ONE atomic + * `replaceSections` transition (the persistence bridge then syncs them into + * kosong's in-memory registries), and publishes `event.model_catalog.changed` + * on change. Bound at App scope. + * + * Custom registries are third-party endpoints, so the refresh User-Agent + * carries the configured custom identity's product token, matching what chat + * requests send. + * + * `modelSource: 'static'` short-circuits refresh: a provider whose effective + * model source is `static` (config-declared, or declared by its vendor + * definition) serves its models from the static `[models.*]` section, so + * discovery must not touch it. A statically-sourced target of a scoped + * refresh answers `unchanged` without any network I/O; for an unscoped + * refresh the static entries are hidden from the orchestrator's config view + * and merged back verbatim on every write, so the orchestrator can neither + * refresh them nor drop them (or a default model pointing at them). + * + * Two write-path details preserve the legacy semantics exactly: + * - The orchestrator's two-phase host contract (removeProvider, then + * setConfig) is absorbed into a single atomic write: the removal is + * computed in memory only (`shapeWithoutProvider`), because the patch's + * full providers/models records already express it. The runtime + * registries therefore never pass through a halfway-removed state — that + * intermediate state was the source of the "provider/model not + * configured" startup race against profile binding. + * - The env-synthesized `__kimi_env__` slice is never written to config: + * it lives in the effective overlay, and the bridge's event-driven sync + * carries it into the registries on its own. `defaultModel` / `thinking` + * also go through config (like the OAuth flows), since the env overlay + * may pin the runtime default and only the config effective view knows. + * + * Credential detection goes through the provider-definition registry, not a + * per-protocol env table. + */ + import { refreshProviderModels, type ManagedKimiConfigShape, @@ -29,14 +70,8 @@ import { PROVIDERS_SECTION, THINKING_SECTION, } from './configSection'; -import { - SECONDARY_MODEL_SECTION, - cascadeSubagentModelPool, - type SecondaryModelConfig, -} from '#/session/subagent/configSection'; import { IProviderDiscoveryService, - ModelCatalogChanged, type RefreshProviderModelsOptions, type RefreshProviderModelsResponse, } from './discovery'; @@ -99,7 +134,7 @@ export class ProviderDiscoveryService implements IProviderDiscoveryService { }); const response = mapRefreshResult(result); if (response.changed.length > 0) { - this.events.publish(new ModelCatalogChanged({ payload: response })); + this.events.publish({ type: 'event.model_catalog.changed', payload: response }); } return response; } @@ -219,16 +254,6 @@ export class ProviderDiscoveryService implements IProviderDiscoveryService { if ('thinking' in patch) { sections[THINKING_SECTION] = restoreDefault ? exclusion.thinking : patch.thinking; } - const nextModels = sections[MODELS_SECTION] as Record<string, ModelRecord> | undefined; - if (nextModels !== undefined) { - const cascadedPool = cascadeSubagentModelPool( - this.config.inspect<SecondaryModelConfig>(SECONDARY_MODEL_SECTION).userValue, - nextModels, - ); - if (cascadedPool !== undefined) { - sections[SECONDARY_MODEL_SECTION] = cascadedPool ?? undefined; - } - } await this.config.replaceSections(sections); return { providers: diff --git a/packages/agent-core-v2/src/app/kosongConfig/envOverlay.ts b/packages/agent-core-v2/src/app/kosongConfig/envOverlay.ts index 79afbb21b..fca2edf77 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/envOverlay.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/envOverlay.ts @@ -1,3 +1,22 @@ +/** + * `kosongConfig` domain — `KIMI_MODEL_*` effective-config overlay. + * + * When `KIMI_MODEL_NAME` is set, synthesizes one model id (bound to the + * reserved `__kimi_env__` provider whose schema kosong owns) from the + * `KIMI_MODEL_*` environment variables and overlays it onto the resolved + * `effective` config: the reserved model entry, `defaultModel`, and the request + * `modelOverrides`. The overlay is applied ONLY to the in-memory `effective` + * view; its `strip` removes the synthesized values on the write path so they + * never reach `config.toml`. Self-registered into `IConfigRegistry` at module + * load, so the overlay takes effect even when the kosong registry services + * are never instantiated. + * + * The env provider's default `baseUrl` is resolved through kosong's + * provider-definition registry, not from a hardcoded vendor table — for Kimi + * that is the `KIMI_BASE_URL` → `https://api.moonshot.ai/v1` chain declared + * by the vendor's traits. + */ + import { parseBooleanEnv } from '#/_base/utils/env'; import { Error2 } from '#/_base/errors/errors'; diff --git a/packages/agent-core-v2/src/app/kosongConfig/errors.ts b/packages/agent-core-v2/src/app/kosongConfig/errors.ts index 19c8ea6ff..c76b481a8 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/errors.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/errors.ts @@ -1,3 +1,10 @@ +/** + * `kosongConfig` domain — models.dev import error codes. + * + * The edge server branches on these codes to map them onto its numeric + * protocol envelope, so the code strings are part of the wire contract. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const ModelsDevImportErrors = { diff --git a/packages/agent-core-v2/src/app/kosongConfig/hostRequestHeadersAdapter.ts b/packages/agent-core-v2/src/app/kosongConfig/hostRequestHeadersAdapter.ts index 52c931256..c439ada55 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/hostRequestHeadersAdapter.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/hostRequestHeadersAdapter.ts @@ -1,3 +1,19 @@ +/** + * `kosongConfig` domain — `IHostRequestHeaders` implementation. + * + * Bridges kosong's host-headers port to the host invocation args: `headers` + * is what the host stated in `BootstrapInput.args.requestHeaders` (usually + * built through `createKimiDefaultHeaders`), verbatim; `thirdPartyHeaders` is + * the `User-Agent`-only layer with the product token taken from the frozen + * identity snapshot. kosong's model catalog only sees the port. Bound at App + * scope. + * + * The third-party layer reads `agentIdentity.current()`, which throws until + * config has first loaded — so a model materialized too early fails loudly + * instead of caching headers that misstate the configured identity. Vendors + * on the full-headers path never touch it. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; diff --git a/packages/agent-core-v2/src/app/kosongConfig/kosongConfig.ts b/packages/agent-core-v2/src/app/kosongConfig/kosongConfig.ts index 1326cf4ff..92d71f1ed 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/kosongConfig.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/kosongConfig.ts @@ -1,3 +1,23 @@ +/** + * `kosongConfig` domain — the kosong persistence bridge contract. + * + * `IKosongConfigService` is the two-way sync between the config service + * (persistence) and kosong's in-memory provider/model registries: + * + * - **Startup / config → kosong**: once config is ready, the registries are + * hydrated from the effective config view; later config section changes + * (TOML edits, `config.reload`, direct `config.set/replace` writes such as + * the OAuth flows) are pushed into kosong the same way. + * - **kosong → config**: mutations that land in kosong (provider additions, + * discovery refresh results, default-pointer changes) fire kosong change + * events, which the bridge persists back through `config.replace`. + * + * Kosong itself never sees the config service — this bridge is the only + * component that knows both sides. Bound at App scope; instantiated by the + * composition root so hydration is guaranteed before any consumer can await + * the kosong registries' `ready`. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IKosongConfigService { diff --git a/packages/agent-core-v2/src/app/kosongConfig/kosongConfigService.ts b/packages/agent-core-v2/src/app/kosongConfig/kosongConfigService.ts index 774f1755f..8c7a16814 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/kosongConfigService.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/kosongConfigService.ts @@ -1,3 +1,32 @@ +/** + * `kosongConfig` domain — `IKosongConfigService` implementation. + * + * The two-way persistence bridge between `IConfigService` and kosong's + * in-memory provider/model registries. + * + * Both sync directions are idempotent by deep comparison, which is what + * makes the loop terminate without any reentrancy flags: + * + * - config → kosong: the registries' writes are silent when the value is + * equal, so a config-originated push never echoes back as a persist. + * - kosong → config: the persist handlers skip the write when the config + * value already matches the registry state (the case for every + * config-originated push), so a persist never echoes back as a sync. + * - env-pinned pointers: a registry-originated default-pointer write lands + * in the user layer even when an effective overlay pins the section + * (`KIMI_MODEL_NAME` → `defaultModel`); the bridge then re-asserts the + * pinned effective value into the registry, so a registry read can never + * diverge from the effective config view. + * + * Persists are serialized through a promise chain so rapid mutation bursts + * reach the disk in event order, and each persist is hooked into the + * registry's change event through `waitUntil` — so an awaited registry + * mutation (`providers.set(...)`, `models.setDefaultModel(...)`, ...) only + * resolves once the write has actually landed in config. A failed persist is + * retried with backoff before the failure is logged; the mutation's caller is + * never rejected (the in-memory change stands either way). + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -20,6 +49,7 @@ import { const PERSIST_MAX_ATTEMPTS = 3; +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class KosongConfigService extends Disposable implements IKosongConfigService { declare readonly _serviceBrand: undefined; @@ -85,6 +115,7 @@ export class KosongConfigService extends Disposable implements IKosongConfigServ ); } + private onConfigSectionChanged(e: ConfigSectionChangedEvent): void { switch (e.domain) { case PROVIDERS_SECTION: @@ -112,6 +143,7 @@ export class KosongConfigService extends Disposable implements IKosongConfigServ } } + private enqueuePersistProviders(): Promise<void> { return this.enqueue(async () => { const next = this.providers.list(); diff --git a/packages/agent-core-v2/src/app/kosongConfig/modelsDev.ts b/packages/agent-core-v2/src/app/kosongConfig/modelsDev.ts index 8d15f95be..321ef5d48 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/modelsDev.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/modelsDev.ts @@ -1,3 +1,18 @@ +/** + * `kosongConfig` domain — the third-party models.dev directory: its + * api.json schema mirrored as types, plus the normalization that turns a + * directory entry into an import decision. + * + * models.dev is an EXTERNAL schema that evolves on its own, so its mirror + * lives here in the app layer, NOT in kosong — kosong's type surface stays + * limited to the engine's own built-in vocabulary. The translation boundary + * is this file: its output (`ModelsDevModel`) is already expressed in kosong + * terms (`ModelCapability` / `ProviderType`), and nothing models.dev-shaped + * leaks further into the engine. Callers consume a directory snapshot to + * populate provider + model configuration without hand-writing context + * windows or capabilities. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { ProviderType } from '#/kosong/provider/provider'; diff --git a/packages/agent-core-v2/src/app/kosongConfig/modelsDevImport.ts b/packages/agent-core-v2/src/app/kosongConfig/modelsDevImport.ts index 621c36755..3c2ec1b34 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/modelsDevImport.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/modelsDevImport.ts @@ -1,6 +1,22 @@ +/** + * `kosongConfig` domain — `IModelsDevImportService`: import providers + * from the third-party models.dev directory and models.dev-shaped private + * registries. + * + * Browses the models.dev directory, imports a directory entry as a + * configured provider, and imports a private registry (api.json, the same + * document shape as models.dev) — owned here so edge servers never touch the + * underlying directory/registry packages directly. This is a WRITE path + * (external world → config → kosong registries via the persistence bridge); + * the global default_provider/default_model pointers are never modified by + * an import — except that a default_model is seeded from the first imported + * model when none is configured at all (fresh setup). + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ProviderCatalogItem } from '#/kosong/model/catalog'; + export interface ModelsDevModelItem { readonly id: string; readonly name?: string; @@ -21,6 +37,7 @@ export interface ModelsDevProviderItem { readonly models: readonly ModelsDevModelItem[]; } + export const PROVIDER_ID_PATTERN = /^[\p{L}\p{N}][\p{L}\p{N}\-_ ]*$/u; export interface ImportModelsDevProviderOptions { diff --git a/packages/agent-core-v2/src/app/kosongConfig/modelsDevImportService.ts b/packages/agent-core-v2/src/app/kosongConfig/modelsDevImportService.ts index 2d864dbef..bf56aac77 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/modelsDevImportService.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/modelsDevImportService.ts @@ -1,3 +1,37 @@ +/** + * `kosongConfig` domain — `IModelsDevImportService` implementation. + * + * Owns the models.dev directory import and the custom-registry (api.json) + * import. Both are multi-step config writes (inspect → build → replace × N), + * serialized through an internal chain so two interleaved imports cannot + * lose each other's section rebuilds. Custom registries reuse the shared + * OAuth primitives' exact remove-then-apply sequence, split into TWO + * persisted passes so deletions really reach the disk (the TOML transform is + * a raw overlay that only honors entry-level deletes; applying in the same + * pass would let stale fields of kept ids survive on disk). The in-memory + * shapes + * deliberately omit the default pointers so the removal logic can never + * clamp them: imports never move default_provider/default_model — aside + * from seeding a default_model from the first imported model when none is + * configured at all (a fresh setup must become usable). + * + * One subtlety shapes all the write code below: the providers/models TOML + * transforms rebuild each section's entries but overlay each entry's fields + * onto the old on-disk raw — so an entry id absent from the replacement + * truly disappears, while a FIELD absent from a kept entry would silently + * survive on disk (and resurrect on the next boot). Field-level clears + * therefore always assign an explicit `undefined` (the transform's + * `setDefined` drops those), and the models.dev import swaps aliases in two + * passes (drop, then re-add onto clean slots). The kosong persistence + * bridge then pushes the change into the registries, which is also what + * invalidates the runtime model catalog. + * + * Both third-party fetches — the models.dev directory and the custom-registry + * import — send the identity snapshot's `outboundUserAgent`, matching what + * the scheduled refresh of the same registry sends: these are directories + * this service chooses to call, so a header is always sent. + */ + import { applyCustomRegistryProvider, fetchCustomRegistry, @@ -19,11 +53,6 @@ import { modelsDevProviderModels, resolveModelsDevImport } from './modelsDev'; import { DEFAULT_MODEL_SECTION, MODELS_SECTION, PROVIDERS_SECTION } from './configSection'; import { ModelsDevImportErrors } from './errors'; import { IKosongConfigService } from './kosongConfig'; -import { - SECONDARY_MODEL_SECTION, - cascadeSubagentModelPool, - type SecondaryModelConfig, -} from '#/session/subagent/configSection'; import { IModelsDevImportService, PROVIDER_ID_PATTERN, @@ -104,19 +133,6 @@ export class ModelsDevImportService implements IModelsDevImportService { return this.config; } - private async cascadePool( - config: IConfigService, - nextModels: Record<string, unknown>, - ): Promise<void> { - const cascaded = cascadeSubagentModelPool( - config.inspect<SecondaryModelConfig>(SECONDARY_MODEL_SECTION).userValue, - nextModels, - ); - if (cascaded !== undefined) { - await config.replace(SECONDARY_MODEL_SECTION, cascaded); - } - } - private async doImportModelsDevProvider( options: ImportModelsDevProviderOptions, ): Promise<ImportModelsDevProviderResult> { @@ -185,7 +201,6 @@ export class ModelsDevImportService implements IModelsDevImportService { nextModels[`${targetId}/${model.id}`] = modelsDevModelToRecord(targetId, model); } await config.replace(MODELS_SECTION, nextModels); - await this.cascadePool(config, nextModels); const firstModel = models[0]; if (firstModel !== undefined) { @@ -274,7 +289,6 @@ export class ModelsDevImportService implements IModelsDevImportService { } await config.replace(PROVIDERS_SECTION, applied.providers as ProvidersSection); await config.replace(MODELS_SECTION, (applied.models ?? {}) as ModelsSection); - await this.cascadePool(config, applied.models ?? {}); const firstEntry = Object.values(entries)[0]; const firstModelKey = firstEntry === undefined ? undefined : Object.keys(firstEntry.models)[0]; diff --git a/packages/agent-core-v2/src/app/kosongConfig/modelsDevUpstream.ts b/packages/agent-core-v2/src/app/kosongConfig/modelsDevUpstream.ts index 3b385ab11..1cb9a5e8b 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/modelsDevUpstream.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/modelsDevUpstream.ts @@ -1,3 +1,15 @@ +/** + * `kosongConfig` domain — models.dev upstream: fetch the third-party + * directory, in-memory cache, built-in snapshot fallback, and the pruned + * item mapping behind the import service's browse methods. + * + * The caller states the outbound `User-Agent`: this module is plain + * module-level state with no container access, and the value depends on the + * host and the configured identity, which only the calling service can see. + * The cached catalog does not vary by caller, so a later call with a different + * value still reuses it. + */ + import { CoreErrors } from '#/_base/errors/codes'; import { BugIndicatingError, Error2 } from '#/_base/errors/errors'; import type { ModelCapability } from '#/kosong/contract/capability'; @@ -111,6 +123,7 @@ export function modelsDevEntry( return Object.prototype.hasOwnProperty.call(catalog, id) ? catalog[id] : undefined; } + function capabilityToStrings(capability: ModelCapability): string[] | undefined { const caps: string[] = []; if (capability.image_in) caps.push('image_in'); @@ -179,6 +192,7 @@ export function toModelsDevProviderItem( ); } + export function modelsDevModelToRecord(providerId: string, model: ModelsDevModel): ModelRecord { const caps = capabilityToStrings(model.capability); const capabilities = diff --git a/packages/agent-core-v2/src/app/kosongConfig/oauthTokenAdapter.ts b/packages/agent-core-v2/src/app/kosongConfig/oauthTokenAdapter.ts index 1cf5c8ea4..54a12878b 100644 --- a/packages/agent-core-v2/src/app/kosongConfig/oauthTokenAdapter.ts +++ b/packages/agent-core-v2/src/app/kosongConfig/oauthTokenAdapter.ts @@ -1,3 +1,11 @@ +/** + * `kosongConfig` domain — `IModelOAuthTokens` implementation. + * + * Delegates kosong's OAuth token port to `IOAuthService` and owns the + * `auth.login_required` error contract: kosong's model catalog only sees + * the port. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/kosongConfig/secondaryModelOverlay.ts b/packages/agent-core-v2/src/app/kosongConfig/secondaryModelOverlay.ts new file mode 100644 index 000000000..899fc387f --- /dev/null +++ b/packages/agent-core-v2/src/app/kosongConfig/secondaryModelOverlay.ts @@ -0,0 +1,102 @@ +/** + * `kosongConfig` domain — `[secondary_model]` derived-entry overlay. + * + * When the secondary-model recipe carries patch fields, synthesizes the + * derived registry entry (`SECONDARY_DERIVED_MODEL_ID`) into the effective + * `models` view: a copy of the pointed entry with the patch merged into its + * `overrides` block (patch wins conflicts) and `aliases` dropped, so the + * derived entry never competes in name/alias routing. Subagent binding then + * resolves it by name through the standard catalog path, and the patch rides + * the same `effectiveModelConfig` merge as any `models.*.overrides` + * (including its supportEfforts/defaultEffort pruning and input clamping). + * + * Like the env overlay, the synthesized entry lives ONLY in the in-memory + * effective view: `strip` removes it from `models` writes so it never + * reaches `config.toml`, and the persistence bridge's deep-equal guards keep + * the two-way sync silent. `strip` also rolls back a `defaultModel` pointer + * set to the derived id (restoring the raw value, mirroring the env + * overlay's pinned-pointer handling) — the pointer can never dangle on disk + * after the recipe is removed. Nothing is synthesized when the recipe has no + * patch fields (subagents bind the pointed entry directly), when + * `secondary.model` is unset, or when the pointed entry does not exist (the + * warning service reports the dangling pointer; spawn fails with the wrapped + * error). The id is reserved: a user-configured entry under it is stripped + * on write all the same. + * + * Self-registered at module load via `registerConfigOverlay`; it is imported + * for side effects after the env overlay, so a `secondary.model` pointing at + * the env-synthesized entry sees the already-applied env view. + */ + +import type { ConfigEffectiveOverlay } from '#/app/config/config'; +import { registerConfigOverlay } from '#/app/config/configOverlayContributions'; +import { isPlainObject } from '#/app/config/toml'; +import type { ModelOverride } from '#/kosong/model/model'; + +import { + DEFAULT_MODEL_SECTION, + MODELS_SECTION, + SECONDARY_MODEL_SECTION, + type SecondaryModelConfig, +} from './configSection'; + +export const SECONDARY_DERIVED_MODEL_ID = '__secondary__'; + +export function secondaryModelPatch( + secondary: SecondaryModelConfig | undefined, +): ModelOverride | undefined { + if (secondary === undefined) return undefined; + const { model: _model, ...patch } = secondary; + return Object.keys(patch).length > 0 ? patch : undefined; +} + +function asRecord(value: unknown): Record<string, unknown> { + return isPlainObject(value) ? value : {}; +} + +function withoutKey(value: unknown, key: string): unknown { + if (!isPlainObject(value) || !(key in value)) return value; + const out: Record<string, unknown> = { ...value }; + delete out[key]; + return out; +} + +export const secondaryModelOverlay: ConfigEffectiveOverlay = { + apply(effective, _getEnv, validate) { + const secondary = effective[SECONDARY_MODEL_SECTION] as SecondaryModelConfig | undefined; + const patch = secondaryModelPatch(secondary); + const baseId = secondary?.model; + if (patch === undefined || baseId === undefined || baseId === SECONDARY_DERIVED_MODEL_ID) { + return []; + } + const models = asRecord(effective[MODELS_SECTION]); + const base = models[baseId]; + if (!isPlainObject(base)) return []; + const { overrides: baseOverrides, aliases: _aliases, ...baseFields } = base; + const derived: Record<string, unknown> = { + ...baseFields, + overrides: { ...asRecord(baseOverrides), ...patch }, + }; + effective[MODELS_SECTION] = validate(MODELS_SECTION, { + ...models, + [SECONDARY_DERIVED_MODEL_ID]: derived, + }); + return [MODELS_SECTION]; + }, + + strip(domain, value, rawSnake) { + switch (domain) { + case MODELS_SECTION: + return withoutKey(value, SECONDARY_DERIVED_MODEL_ID); + case DEFAULT_MODEL_SECTION: + if (value !== SECONDARY_DERIVED_MODEL_ID) return value; + return typeof rawSnake['default_model'] === 'string' + ? rawSnake['default_model'] + : undefined; + default: + return value; + } + }, +}; + +registerConfigOverlay(secondaryModelOverlay); diff --git a/packages/agent-core-v2/src/app/mcpConfig/configLoader.ts b/packages/agent-core-v2/src/app/mcpConfig/configLoader.ts deleted file mode 100644 index 93879a95c..000000000 --- a/packages/agent-core-v2/src/app/mcpConfig/configLoader.ts +++ /dev/null @@ -1,188 +0,0 @@ -import { dirname, join, normalize } from 'pathe'; - -import { resolveKimiHome } from '#/app/bootstrap/bootstrap'; -import { findGitWorkTree } from '#/app/git/workTree'; -import { resolvePath } from '#/_base/utils/paths'; -import { ErrorCodes, Error2 } from '#/errors'; -import { McpServerConfigSchema, type McpServerConfig } from '#/mcpCore/config-schema'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { OsFsErrors, HostFsError } from '#/os/interface/hostFsErrors'; - -export interface McpJsonPaths { - readonly user: string; - readonly projectRoot: string; - readonly project: string; -} - -export interface ResolveMcpJsonPathsInput { - readonly fs: IHostFileSystem; - readonly cwd: string; - readonly homeDir?: string; -} - -export async function resolveMcpJsonPaths(input: ResolveMcpJsonPathsInput): Promise<McpJsonPaths> { - const start = normalize(input.cwd); - const projectRoot = (await findGitWorkTree(input.fs, start))?.root ?? start; - - return { - user: join(resolveKimiHome(input.homeDir), 'mcp.json'), - projectRoot: join(projectRoot, '.mcp.json'), - project: join(input.cwd, '.kimi-code', 'mcp.json'), - }; -} - -export interface LoadMcpServersInput { - readonly fs: IHostFileSystem; - readonly cwd: string; - readonly homeDir?: string; - readonly includeProject?: boolean; -} - -export interface LoadMcpServersDetailedResult { - readonly servers: Record<string, McpServerConfig>; - readonly origins: Record<string, string>; -} - -export async function loadMcpServers( - input: LoadMcpServersInput, -): Promise<Record<string, McpServerConfig>> { - return (await loadMcpServersDetailed(input)).servers; -} - -export async function loadMcpServersDetailed( - input: LoadMcpServersInput, -): Promise<LoadMcpServersDetailedResult> { - const paths = await resolveMcpJsonPaths(input); - if (input.includeProject === false) { - const user = await readMcpJson(input.fs, paths.user); - return { servers: user, origins: mapValuesToPath(user, paths.user) }; - } - const layers: readonly [path: string, servers: Record<string, McpServerConfig>][] = - await Promise.all([ - readMcpJson(input.fs, paths.user), - readMcpJson(input.fs, paths.projectRoot, { stdioCwdBase: dirname(paths.projectRoot) }), - readMcpJson(input.fs, paths.project), - ]).then(([user, projectRoot, project]) => [ - [paths.user, user], - [paths.projectRoot, projectRoot], - [paths.project, project], - ]); - const servers: Record<string, McpServerConfig> = Object.create(null); - const origins: Record<string, string> = Object.create(null); - for (const [path, layer] of layers) { - for (const [name, config] of Object.entries(layer)) { - servers[name] = config; - origins[name] = path; - } - } - return { servers, origins }; -} - -interface ReadMcpJsonOptions { - readonly stdioCwdBase?: string; -} - -async function readMcpJson( - fs: IHostFileSystem, - filePath: string, - options: ReadMcpJsonOptions = {}, -): Promise<Record<string, McpServerConfig>> { - let text: string; - try { - text = await fs.readText(filePath); - } catch (error: unknown) { - if (isFileNotFound(error)) return {}; - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Failed to read ${filePath}: ${describeError(error)}`, - { - cause: error, - }, - ); - } - - if (text.trim().length === 0) return {}; - - let data: unknown; - try { - data = JSON.parse(text); - } catch (error: unknown) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid JSON in ${filePath}: ${describeError(error)}`, - { - cause: error, - }, - ); - } - - try { - return normalizeMcpServers(parseMcpJsonServers(data), options); - } catch (error: unknown) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid MCP server config in ${filePath}: ${describeError(error)}`, - { - cause: error, - }, - ); - } -} - -function parseMcpJsonServers(data: unknown): Record<string, McpServerConfig> { - if (!isRecord(data)) { - throw new Error('expected a JSON object'); - } - if (!('mcpServers' in data)) return {}; - const raw = data['mcpServers']; - if (!isRecord(raw)) { - throw new Error('"mcpServers" must be an object'); - } - return Object.fromEntries( - Object.entries(raw).map(([name, value]) => [name, McpServerConfigSchema.parse(value)]), - ); -} - -function normalizeMcpServers( - servers: Record<string, McpServerConfig>, - options: ReadMcpJsonOptions, -): Record<string, McpServerConfig> { - const stdioCwdBase = options.stdioCwdBase; - if (stdioCwdBase === undefined) return servers; - - return Object.fromEntries( - Object.entries(servers).map(([name, config]) => [ - name, - normalizeStdioCwd(config, stdioCwdBase), - ]), - ); -} - -function normalizeStdioCwd(config: McpServerConfig, cwdBase: string): McpServerConfig { - if (config.transport !== 'stdio') return config; - const cwd = config.cwd === undefined ? cwdBase : resolvePath(cwdBase, config.cwd); - return { ...config, cwd }; -} - -function mapValuesToPath( - servers: Record<string, McpServerConfig>, - path: string, -): Record<string, string> { - const origins: Record<string, string> = Object.create(null); - for (const name of Object.keys(servers)) { - origins[name] = path; - } - return origins; -} - -function isRecord(value: unknown): value is Record<string, unknown> { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function isFileNotFound(error: unknown): boolean { - return error instanceof HostFsError && error.code === OsFsErrors.codes.OS_FS_NOT_FOUND; -} - -function describeError(error: unknown): string { - return error instanceof Error ? error.message : String(error); -} diff --git a/packages/agent-core-v2/src/app/mcpConfig/configSection.ts b/packages/agent-core-v2/src/app/mcpConfig/configSection.ts index 366f3e012..6e2752d50 100644 --- a/packages/agent-core-v2/src/app/mcpConfig/configSection.ts +++ b/packages/agent-core-v2/src/app/mcpConfig/configSection.ts @@ -1,3 +1,11 @@ +/** + * `mcpConfig` domain — registers MCP timeout preferences into `config`. + * + * Owns the global MCP startup and tool-call timeout preferences, including + * their environment bindings and persistence guard. Registered into `config` + * at module load. Bound at App scope. + */ + import { z } from 'zod'; import { type EnvBindings, envBindings, stripEnvBoundFields } from '#/app/config/config'; diff --git a/packages/agent-core-v2/src/app/mcpConfig/configStore.ts b/packages/agent-core-v2/src/app/mcpConfig/configStore.ts deleted file mode 100644 index eaa150faf..000000000 --- a/packages/agent-core-v2/src/app/mcpConfig/configStore.ts +++ /dev/null @@ -1,225 +0,0 @@ -import { join } from 'pathe'; - -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { Disposable } from '#/_base/di/lifecycle'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { AsyncEmitter, type Event, type IWaitUntil } from '#/_base/event'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { LifecycleScope } from '#/app/scopes'; -import { ErrorCodes, Error2 } from '#/errors'; -import { McpServerConfigSchema, type McpServerConfig } from '#/mcpCore/config-schema'; -import { IFileSystemStorageService } from '#/persistence/interface/storage'; - -export type GlobalMcpServerConfig = McpServerConfig & { readonly name: string }; - -export type McpConfigWriteEvent = IWaitUntil; - -export interface IMcpConfigStore { - readonly _serviceBrand: undefined; - readonly path: string; - readonly onDidWrite: Event<McpConfigWriteEvent>; - list(): Promise<readonly GlobalMcpServerConfig[]>; - get(name: string): Promise<GlobalMcpServerConfig>; - add(server: GlobalMcpServerConfig): Promise<readonly GlobalMcpServerConfig[]>; - update(server: GlobalMcpServerConfig): Promise<readonly GlobalMcpServerConfig[]>; - remove(name: string): Promise<readonly GlobalMcpServerConfig[]>; -} - -export const IMcpConfigStore: ServiceIdentifier<IMcpConfigStore> = - createDecorator<IMcpConfigStore>('mcpConfigStore'); - -interface McpConfigFile { - readonly raw: Record<string, unknown>; - readonly rawServers: Record<string, unknown>; - readonly servers: readonly GlobalMcpServerConfig[]; -} - -const CONFIG_SCOPE = ''; -const MCP_CONFIG_KEY = 'mcp.json'; - -const textEncoder = new TextEncoder(); -const textDecoder = new TextDecoder('utf-8', { ignoreBOM: true }); - -export class McpConfigStore extends Disposable implements IMcpConfigStore { - declare readonly _serviceBrand: undefined; - - readonly path: string; - - private readonly writeEmitter = this._register(new AsyncEmitter<McpConfigWriteEvent>()); - readonly onDidWrite: Event<McpConfigWriteEvent> = this.writeEmitter.event; - private mutationTail: Promise<void> = Promise.resolve(); - private writePending = false; - - constructor( - @IFileSystemStorageService private readonly storage: IFileSystemStorageService, - @IBootstrapService bootstrap: IBootstrapService, - ) { - super(); - this.path = join(bootstrap.homeDir, MCP_CONFIG_KEY); - } - - async list(): Promise<readonly GlobalMcpServerConfig[]> { - return (await this.read()).servers; - } - - async get(name: string): Promise<GlobalMcpServerConfig> { - const normalizedName = normalizeServerName(name); - const server = (await this.read()).servers.find((entry) => entry.name === normalizedName); - if (server !== undefined) return server; - throw serverNotFound(normalizedName); - } - - add(server: GlobalMcpServerConfig): Promise<readonly GlobalMcpServerConfig[]> { - return this.mutate(async () => { - const normalized = parseServerInput(server); - const file = await this.read(); - if (Object.hasOwn(file.rawServers, normalized.name)) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP server "${normalized.name}" already exists`, - ); - } - await this.write(file, { - ...file.rawServers, - [normalized.name]: persistedEntry(normalized), - }); - return this.list(); - }); - } - - update(server: GlobalMcpServerConfig): Promise<readonly GlobalMcpServerConfig[]> { - return this.mutate(async () => { - const normalized = parseServerInput(server); - const file = await this.read(); - if (!Object.hasOwn(file.rawServers, normalized.name)) { - throw serverNotFound(normalized.name); - } - await this.write(file, { - ...file.rawServers, - [normalized.name]: persistedEntry(normalized), - }); - return this.list(); - }); - } - - remove(name: string): Promise<readonly GlobalMcpServerConfig[]> { - return this.mutate(async () => { - const normalizedName = normalizeServerName(name); - const file = await this.read(); - if (!Object.hasOwn(file.rawServers, normalizedName)) return file.servers; - const nextServers = Object.fromEntries( - Object.entries(file.rawServers).filter(([entryName]) => entryName !== normalizedName), - ); - await this.write(file, nextServers); - return this.list(); - }); - } - - private mutate<T>(work: () => Promise<T>): Promise<T> { - const tail = this.mutationTail.catch(() => undefined).then(work); - this.mutationTail = tail.then( - () => undefined, - () => undefined, - ); - return tail.then(async (result) => { - if (!this.writePending) return result; - this.writePending = false; - await this.writeEmitter.fireAsyncConcurrent({}, NO_ABORT); - return result; - }); - } - - private async read(): Promise<McpConfigFile> { - let bytes: Uint8Array | undefined; - try { - bytes = await this.storage.read(CONFIG_SCOPE, MCP_CONFIG_KEY); - } catch (error: unknown) { - throw configError(`Failed to read ${this.path}: ${describeError(error)}`, error); - } - if (bytes === undefined) { - return { raw: {}, rawServers: {}, servers: [] }; - } - - const text = textDecoder.decode(bytes); - if (text.trim().length === 0) { - return { raw: {}, rawServers: {}, servers: [] }; - } - - let parsed: unknown; - try { - parsed = JSON.parse(text) as unknown; - } catch (error: unknown) { - throw configError(`Invalid JSON in ${this.path}: ${describeError(error)}`, error); - } - if (!isRecord(parsed)) { - throw configError(`Invalid MCP config in ${this.path}: expected a JSON object`); - } - const rawServersValue = parsed['mcpServers']; - if (rawServersValue !== undefined && !isRecord(rawServersValue)) { - throw configError(`Invalid MCP config in ${this.path}: "mcpServers" must be an object`); - } - const rawServers = rawServersValue ?? {}; - const servers = Object.entries(rawServers).map(([name, value]) => parseServer(name, value)); - return { raw: parsed, rawServers, servers }; - } - - private async write(file: McpConfigFile, rawServers: Record<string, unknown>): Promise<void> { - const text = `${JSON.stringify({ ...file.raw, mcpServers: rawServers }, null, 2)}\n`; - await this.storage.write(CONFIG_SCOPE, MCP_CONFIG_KEY, textEncoder.encode(text), { - atomic: true, - }); - this.writePending = true; - } -} - -const NO_ABORT = new AbortController().signal; - -function parseServerInput(server: GlobalMcpServerConfig): GlobalMcpServerConfig { - return parseServer(normalizeServerName(server.name), server); -} - -function parseServer(name: string, value: unknown): GlobalMcpServerConfig { - const result = McpServerConfigSchema.safeParse(value); - if (!result.success) { - throw configError( - `Invalid MCP server "${name}" in global config: ${result.error.message}`, - result.error, - ); - } - return { name, ...result.data }; -} - -function persistedEntry(server: GlobalMcpServerConfig): McpServerConfig { - const { name: _name, ...entry } = server; - return entry; -} - -export function normalizeServerName(name: string): string { - const normalized = name.trim(); - if (normalized.length > 0) return normalized; - throw new Error2(ErrorCodes.REQUEST_INVALID, 'MCP server name cannot be empty'); -} - -function serverNotFound(name: string): Error2 { - return new Error2(ErrorCodes.MCP_SERVER_NOT_FOUND, `MCP server "${name}" was not found`); -} - -function configError(message: string, cause?: unknown): Error2 { - return new Error2(ErrorCodes.CONFIG_INVALID, message, { cause }); -} - -function describeError(error: unknown): string { - return error instanceof Error ? error.message : String(error); -} - -function isRecord(value: unknown): value is Record<string, unknown> { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -registerScopedService( - LifecycleScope.App, - IMcpConfigStore, - McpConfigStore, - ScopeActivation.OnDemand, - 'mcpConfig', -); diff --git a/packages/agent-core-v2/src/app/mcpConfig/oauthService.ts b/packages/agent-core-v2/src/app/mcpConfig/oauthService.ts deleted file mode 100644 index 732f8fd0e..000000000 --- a/packages/agent-core-v2/src/app/mcpConfig/oauthService.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { ILogService } from '#/_base/log/log'; -import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; -import { LifecycleScope } from '#/app/scopes'; -import { McpOAuthService } from '#/mcpCore/oauth/service'; - -import { IMcpOAuthStore } from './oauthStore'; - -export const IMcpOAuthService: ServiceIdentifier<McpOAuthService> = - createDecorator<McpOAuthService>('mcpOAuthService'); - -export class AppMcpOAuthService extends McpOAuthService { - constructor( - @IMcpOAuthStore store: IMcpOAuthStore, - @IAgentIdentity identity: IAgentIdentity, - @ILogService log: ILogService, - ) { - super({ - store, - resolveClientName: () => identity.current().slug, - log, - }); - void identity - .resolved() - .then(() => { - const sweep = this.sweepProactiveRefresh(); - this.trackBackgroundTask(sweep); - return sweep; - }) - .catch((error: unknown) => { - log.warn(`mcp oauth proactive-refresh sweep failed: ${String(error)}`); - }); - } -} - -registerScopedService( - LifecycleScope.App, - IMcpOAuthService, - AppMcpOAuthService, - ScopeActivation.OnDemand, - 'mcpConfig', -); diff --git a/packages/agent-core-v2/src/app/mcpConfig/oauthStore.ts b/packages/agent-core-v2/src/app/mcpConfig/oauthStore.ts index aa4480934..5a8768411 100644 --- a/packages/agent-core-v2/src/app/mcpConfig/oauthStore.ts +++ b/packages/agent-core-v2/src/app/mcpConfig/oauthStore.ts @@ -1,3 +1,21 @@ +/** + * `mcpConfig` domain — `IMcpOAuthStore`, the App-scope persistence + * adapter for MCP OAuth credentials. + * + * Implements the `mcp` domain's `McpOAuthStore` port over the `persistence` + * access-pattern store (`IAtomicDocumentStore`) under the `credentials/mcp` + * scope (`<homeDir>/credentials/mcp/<key>-*.json`). One App-scope instance is + * shared by every workspace handler's `McpOAuthService`, replacing the + * per-handler stores they used to build ad hoc; the on-disk layout is + * unchanged, so credentials stay shared with out-of-engine readers. The + * {@link createMcpOAuthStore} factory remains exported for those + * out-of-engine callers, which run an `McpOAuthService` outside the DI + * container. + * + * Read semantics: missing or corrupt JSON resolves to `undefined` (never + * throws). The provider treats `undefined` as "not stored". + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -29,9 +47,6 @@ export function createMcpOAuthStore(docs: IAtomicDocumentStore): McpOAuthStore { remove(key) { return docs.delete(CREDENTIALS_SCOPE, key); }, - list(prefix) { - return docs.list(CREDENTIALS_SCOPE, prefix); - }, }; } @@ -55,10 +70,6 @@ export class McpOAuthStoreAdapter implements IMcpOAuthStore { remove(key: string): Promise<void> { return this.delegate.remove(key); } - - list(prefix?: string): Promise<readonly string[]> { - return this.delegate.list(prefix); - } } registerScopedService( diff --git a/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts b/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts deleted file mode 100644 index 8755b2683..000000000 --- a/packages/agent-core-v2/src/app/mcpManagement/mcpManagement.ts +++ /dev/null @@ -1,130 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -import type { McpServerConfig } from '#/mcpCore/config-schema'; -import type { McpServerConfigView } from '#/mcpCore/configView'; -import type { - McpRegistryPluginOrigin, - McpRegistryQuery, - McpServerSource, -} from '#/app/mcpRegistry/mcpRegistry'; - -export type GlobalMcpServerConfig = McpServerConfig & { readonly name: string }; - -export interface McpManagedServer { - readonly name: string; - readonly config: McpServerConfig | McpServerConfigView; - readonly source: McpServerSource; - readonly origin: string; - readonly mutable: boolean; - readonly plugin?: McpRegistryPluginOrigin; -} - -export interface McpServerTestTarget { - readonly name?: string; - readonly server?: GlobalMcpServerConfig; - readonly cwd?: string; -} - -export interface McpServerTestResult { - readonly success: boolean; - readonly output: string; -} - -export type McpServerLocator = - | { readonly source: 'global'; readonly name: string } - | { readonly source: 'plugin'; readonly pluginId: string; readonly serverName: string }; - -export interface McpServerDescriptor { - readonly serverId: string; - readonly locator: McpServerLocator; - readonly runtimeName: string; - readonly canonicalUrl?: string; - readonly origin: McpServerSource; - readonly config: McpServerConfigView; - readonly enabled: boolean; - readonly editable: boolean; -} - -export type McpServerAuthState = - | 'not-applicable' - | 'bearer-token' - | 'oauth-required' - | 'oauth-authorized' - | 'oauth-expired' - | 'unavailable'; - -export interface McpServerInspection extends McpServerDescriptor { - readonly authStatus: McpServerAuthState; - readonly checkedAt?: number; - readonly error?: string; -} - -export interface McpServerAuthStatus { - readonly name: string; - readonly authStatus: McpServerAuthState; -} - -export type McpServerAuthBeginResult = - | { - readonly status: 'authorization-required'; - readonly flowId: string; - readonly authorizationUrl: string; - } - | { readonly status: 'already-authorized' }; - -export interface McpServerAuthFlowHandle { - readonly flowId: string; - readonly timeoutMs?: number; -} - -export interface McpAuthStatusQuery extends McpRegistryQuery { - readonly verify?: boolean; -} - -export interface IMcpManagementService { - readonly _serviceBrand: undefined; - - listServers(query?: McpRegistryQuery): Promise<readonly McpManagedServer[]>; - - getServer(name: string, query?: McpRegistryQuery): Promise<McpManagedServer>; - - addServer( - server: GlobalMcpServerConfig, - query?: McpRegistryQuery, - ): Promise<readonly McpManagedServer[]>; - - updateServer( - server: GlobalMcpServerConfig, - query?: McpRegistryQuery, - ): Promise<readonly McpManagedServer[]>; - - removeServer(name: string, query?: McpRegistryQuery): Promise<readonly McpManagedServer[]>; - - testServer(target: McpServerTestTarget): Promise<McpServerTestResult>; - - listAuthStatuses(query?: McpAuthStatusQuery): Promise<readonly McpServerAuthStatus[]>; - - inspectServers( - targets?: readonly McpServerLocator[], - query?: McpRegistryQuery, - ): Promise<readonly McpServerInspection[]>; - - resolveServerByName(name: string, query?: McpRegistryQuery): Promise<McpServerLocator>; - - beginServerAuth( - locator: McpServerLocator, - query?: McpRegistryQuery, - ): Promise<McpServerAuthBeginResult>; - - completeServerAuth( - handle: McpServerAuthFlowHandle, - options?: { readonly signal?: AbortSignal }, - ): Promise<void>; - - cancelServerAuth(handle: Pick<McpServerAuthFlowHandle, 'flowId'>): Promise<void>; - - resetServerAuth(locator: McpServerLocator, query?: McpRegistryQuery): Promise<void>; -} - -export const IMcpManagementService: ServiceIdentifier<IMcpManagementService> = - createDecorator<IMcpManagementService>('mcpManagementService'); diff --git a/packages/agent-core-v2/src/app/mcpManagement/mcpManagementService.ts b/packages/agent-core-v2/src/app/mcpManagement/mcpManagementService.ts deleted file mode 100644 index 6ba92d970..000000000 --- a/packages/agent-core-v2/src/app/mcpManagement/mcpManagementService.ts +++ /dev/null @@ -1,652 +0,0 @@ -import { randomUUID } from 'node:crypto'; - -import { normalize } from 'pathe'; - -import { Disposable } from '#/_base/di/lifecycle'; -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { ILogService } from '#/_base/log/log'; - -import { ErrorCodes, Error2 } from '#/errors'; -import { McpConnectionManager } from '#/mcpCore/connection-manager'; -import { McpServerConfigSchema, type McpServerConfig } from '#/mcpCore/config-schema'; -import { toMcpServerConfigView } from '#/mcpCore/configView'; -import { - AlreadyAuthorizedError, - type BeginAuthorizationResult, - type McpOAuthService, - type McpOAuthTokenState, -} from '#/mcpCore/oauth/service'; -import { canonicalMcpOAuthResource } from '#/mcpCore/oauth/store'; -import { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import { IHostProcessService } from '#/os/interface/hostProcess'; -import { LocalRuntime } from '#/runtime/localRuntime'; -import { RuntimeRegistry } from '#/runtime/runtimeRegistry'; -import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; -import { IConfigService } from '#/app/config/config'; -import { MCP_SECTION, type McpSection } from '#/app/mcpConfig/configSection'; -import { IMcpConfigStore, normalizeServerName } from '#/app/mcpConfig/configStore'; -import { IMcpOAuthService } from '#/app/mcpConfig/oauthService'; -import { - IMcpRegistryService, - type McpRegistryEntry, - type McpRegistryQuery, -} from '#/app/mcpRegistry/mcpRegistry'; -import { - IRuntimeResolver, - IWorkspaceInstanceManager, -} from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import { - IMcpManagementService, - type GlobalMcpServerConfig, - type McpAuthStatusQuery, - type McpManagedServer, - type McpServerAuthBeginResult, - type McpServerAuthFlowHandle, - type McpServerAuthState, - type McpServerAuthStatus, - type McpServerDescriptor, - type McpServerInspection, - type McpServerLocator, - type McpServerTestResult, - type McpServerTestTarget, -} from './mcpManagement'; - -const DEFAULT_AUTH_TIMEOUT_MS = 15 * 60_000; -const AUTH_FLOW_IDLE_TIMEOUT_MS = 15 * 60_000; -const MAX_AUTH_TIMEOUT_MS = 2 ** 31 - 1; - -export class McpManagementService extends Disposable implements IMcpManagementService { - declare readonly _serviceBrand: undefined; - - private readonly authFlows = new Map< - string, - { flow: BeginAuthorizationResult; idleTimer: NodeJS.Timeout } - >(); - - constructor( - @IMcpRegistryService private readonly registry: IMcpRegistryService, - @IMcpConfigStore private readonly store: IMcpConfigStore, - @IMcpOAuthService private readonly oauth: McpOAuthService, - @IConfigService private readonly config: IConfigService, - @IAgentIdentity private readonly identity: IAgentIdentity, - @IRuntimeResolver private readonly runtimeResolver: IRuntimeResolver, - @IWorkspaceInstanceManager private readonly workspaceInstances: IWorkspaceInstanceManager, - @IHostEnvironment private readonly hostEnvironment: IHostEnvironment, - @IHostProcessService private readonly hostProcess: IHostProcessService, - @ILogService private readonly log: ILogService, - ) { - super(); - } - - async listServers(query: McpRegistryQuery = {}): Promise<readonly McpManagedServer[]> { - return (await this.registry.list(query)).map(toManagedServer); - } - - async getServer(name: string, query: McpRegistryQuery = {}): Promise<McpManagedServer> { - return toManagedServer(await this.registry.get(name, query)); - } - - async addServer( - server: GlobalMcpServerConfig, - query: McpRegistryQuery = {}, - ): Promise<readonly McpManagedServer[]> { - const name = normalizeServerName(server.name); - await this.guardMutation(name, query); - await this.store.add({ ...server, name }); - return this.listServers(query); - } - - async updateServer( - server: GlobalMcpServerConfig, - query: McpRegistryQuery = {}, - ): Promise<readonly McpManagedServer[]> { - const name = normalizeServerName(server.name); - await this.guardMutation(name, query); - await this.store.update({ ...server, name }); - return this.listServers(query); - } - - async removeServer( - name: string, - query: McpRegistryQuery = {}, - ): Promise<readonly McpManagedServer[]> { - const normalized = normalizeServerName(name); - await this.guardMutation(normalized, query); - await this.store.remove(normalized); - return this.listServers(query); - } - - async testServer(target: McpServerTestTarget): Promise<McpServerTestResult> { - await this.waitForReadiness(); - const resolved = await this.resolveTestTarget(target); - return this.withProbe(resolved, target.cwd, (manager) => - standaloneTestResult(resolved.name, manager), - ); - } - - private async guardMutation(name: string, query: McpRegistryQuery): Promise<void> { - const matches = (await this.registry.list(query)).filter((entry) => entry.name === name); - for (const entry of matches) { - if (entry.source === 'global' && !entry.mutable) throwReadOnlyMcpServer(entry); - } - } - - private async resolveTestTarget(target: McpServerTestTarget): Promise<GlobalMcpServerConfig> { - const { name, server, cwd } = target; - if (server !== undefined) { - if (name !== undefined && name !== server.name) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - 'Pass either an MCP server name or an inline server config, not both', - ); - } - const parsed = McpServerConfigSchema.safeParse(server); - if (!parsed.success) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid MCP server "${server.name}": ${parsed.error.message}`, - ); - } - return { name: server.name, ...parsed.data }; - } - if (name === undefined) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - 'Pass an MCP server name or an inline server config', - ); - } - const matches = (await this.registry.list({ cwd })).filter((entry) => entry.name === name); - if (matches.length === 0) { - throw new Error2(ErrorCodes.MCP_SERVER_NOT_FOUND, `MCP server "${name}" was not found`); - } - const enabled = matches.filter((entry) => entry.config.enabled !== false); - if (enabled.length > 1) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP runtime name "${name}" is shared by multiple enabled servers`, - ); - } - const entry = enabled[0] ?? matches[0]!; - return { name: entry.name, ...entry.config }; - } - - private async withProbe<T>( - server: GlobalMcpServerConfig, - cwd: string | undefined, - inspect: (manager: McpConnectionManager) => T, - ): Promise<T> { - await this.waitForReadiness(); - const section = this.config.get<McpSection | undefined>(MCP_SECTION); - let workspaceId: string | undefined; - let stdioCwd = cwd; - let runtimeResolver = this.runtimeResolver; - let transientRuntimes: RuntimeRegistry | undefined; - if (server.transport === 'stdio') { - stdioCwd = normalize(cwd ?? process.cwd()); - const workspace = this.workspaceInstances.findContaining(stdioCwd); - if (workspace !== undefined) { - workspaceId = workspace.id; - } else { - const runtimeId = server.runtime_id; - if (runtimeId !== undefined && runtimeId !== 'local') { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `Cannot probe MCP server "${server.name}" with runtime_id "${runtimeId}": no materialized workspace contains ${stdioCwd}, and an out-of-workspace probe only supports the local runtime`, - ); - } - await this.hostEnvironment.ready; - workspaceId = `mcp-probe-${randomUUID()}`; - transientRuntimes = new RuntimeRegistry(workspaceId); - transientRuntimes.register( - new LocalRuntime( - workspaceId, - this.hostEnvironment, - undefined, - this.hostProcess, - undefined, - undefined, - ), - ); - runtimeResolver = { - _serviceBrand: undefined, - inspect: (binding) => transientRuntimes!.inspect(binding), - acquire: (binding, required) => transientRuntimes!.acquire(binding, required), - }; - } - } - const manager = new McpConnectionManager({ - log: this.log, - stdioCwd, - runtimeResolver, - workspaceId, - runtimeId: workspaceId === undefined ? undefined : 'local', - oauthService: this.oauth, - resolveClientName: () => this.identity.current().slug, - resolveDefaultTimeouts: () => ({ - startupTimeoutMs: section?.startupTimeoutMs, - toolTimeoutMs: section?.toolTimeoutMs, - }), - }); - try { - await manager.connectAll({ [server.name]: mcpConfigWithoutName(server) }); - return inspect(manager); - } finally { - try { - await manager.shutdown(); - } finally { - await transientRuntimes?.dispose(); - } - } - } - - async listAuthStatuses(query: McpAuthStatusQuery = {}): Promise<readonly McpServerAuthStatus[]> { - await this.waitForReadiness(); - const entries = await this.registry.list({ cwd: query.cwd }); - return Promise.all( - entries.map(async (entry) => ({ - name: entry.name, - authStatus: await this.serverAuthState(entry, query.cwd, query.verify), - })), - ); - } - - async inspectServers( - targets?: readonly McpServerLocator[], - query: McpRegistryQuery = {}, - ): Promise<readonly McpServerInspection[]> { - await this.waitForReadiness(); - const catalog = await this.serverDescriptors(query); - const descriptors = selectServerDescriptors(catalog, targets); - const inspections = await this.inspectServerDescriptors(descriptors, catalog); - return inspections.map((inspection) => ({ - ...inspection, - config: toMcpServerConfigView(inspection.config), - })); - } - - async resolveServerByName(name: string, query: McpRegistryQuery = {}): Promise<McpServerLocator> { - await this.registry.get(name, query); - const catalog = await this.serverDescriptors(query); - const matches = catalog.filter((candidate) => candidate.runtimeName === name); - const descriptor = matches.find((candidate) => candidate.enabled) ?? matches[0]!; - this.requireUnambiguousRuntimeName(catalog, descriptor); - return descriptor.locator; - } - - async beginServerAuth( - locator: McpServerLocator, - query: McpRegistryQuery = {}, - ): Promise<McpServerAuthBeginResult> { - await this.waitForReadiness(); - const server = await this.resolveServer(locator, query); - const config = requireOAuthMcpConfig(server.runtimeName, server.config); - try { - const flow = await this.oauth.beginAuthorization(server.runtimeName, config.url); - const flowId = randomUUID(); - const idleTimer = setTimeout(() => { - const expired = this.authFlows.get(flowId); - this.authFlows.delete(flowId); - void expired?.flow.cancel(); - }, AUTH_FLOW_IDLE_TIMEOUT_MS); - idleTimer.unref(); - this.authFlows.set(flowId, { flow, idleTimer }); - return { - status: 'authorization-required', - flowId, - authorizationUrl: flow.authorizationUrl.toString(), - }; - } catch (error) { - if (error instanceof AlreadyAuthorizedError) { - return { status: 'already-authorized' }; - } - throw error; - } - } - - async completeServerAuth( - handle: McpServerAuthFlowHandle, - options?: { readonly signal?: AbortSignal }, - ): Promise<void> { - if ( - handle.timeoutMs !== undefined && - (!Number.isInteger(handle.timeoutMs) || - handle.timeoutMs < 1 || - handle.timeoutMs > MAX_AUTH_TIMEOUT_MS) - ) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP OAuth timeoutMs must be an integer between 1 and ${MAX_AUTH_TIMEOUT_MS}`, - ); - } - const active = this.authFlows.get(handle.flowId); - if (active === undefined) { - throw new Error2(ErrorCodes.REQUEST_INVALID, `Unknown MCP OAuth flow: ${handle.flowId}`); - } - clearTimeout(active.idleTimer); - try { - await active.flow.complete({ - signal: options?.signal, - timeoutMs: handle.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS, - }); - } finally { - this.authFlows.delete(handle.flowId); - } - } - - async cancelServerAuth(handle: Pick<McpServerAuthFlowHandle, 'flowId'>): Promise<void> { - const active = this.authFlows.get(handle.flowId); - if (active === undefined) return; - clearTimeout(active.idleTimer); - this.authFlows.delete(handle.flowId); - await active.flow.cancel(); - } - - override dispose(): void { - for (const active of this.authFlows.values()) { - clearTimeout(active.idleTimer); - void active.flow.cancel(); - } - this.authFlows.clear(); - super.dispose(); - } - - async resetServerAuth(locator: McpServerLocator, query: McpRegistryQuery = {}): Promise<void> { - await this.waitForReadiness(); - const server = await this.resolveServer(locator, query); - const config = requireRemoteMcpConfig(server.runtimeName, server.config); - await this.oauth.invalidate(server.runtimeName, config.url); - } - - private async serverDescriptors( - query: McpRegistryQuery = {}, - ): Promise<readonly McpServerRuntimeDescriptor[]> { - return (await this.registry.list(query)).map((entry) => serverDescriptor(entry)); - } - - private async resolveServer( - locator: McpServerLocator, - query: McpRegistryQuery, - ): Promise<McpServerRuntimeDescriptor> { - const catalog = await this.serverDescriptors(query); - const server = selectServerDescriptors(catalog, [locator])[0]!; - this.requireUnambiguousRuntimeName(catalog, server); - return server; - } - - private requireUnambiguousRuntimeName( - catalog: readonly McpServerRuntimeDescriptor[], - server: McpServerRuntimeDescriptor, - ): void { - const conflict = catalog.find( - (candidate) => - candidate.serverId !== server.serverId && - candidate.enabled && - candidate.runtimeName === server.runtimeName, - ); - if (conflict !== undefined) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP runtime name "${server.runtimeName}" is shared by multiple enabled servers; use the locator-addressed RPC instead`, - ); - } - } - - private async serverAuthState( - entry: McpRegistryEntry, - cwd: string | undefined, - verify: boolean | undefined, - ): Promise<McpServerAuthState> { - const server = entry.config; - if (server.enabled === false) return 'not-applicable'; - if (server.transport === 'stdio') return 'not-applicable'; - if (server.bearerTokenEnvVar !== undefined) return 'bearer-token'; - if (server.headers !== undefined && server.auth !== 'oauth') return 'not-applicable'; - if (server.transport !== 'http' && server.auth !== 'oauth') return 'not-applicable'; - const tokens = await this.oauth.tokenState(entry.name, server.url); - const offline = (): McpServerAuthState => { - if (tokens.hasTokens) { - return !tokens.expired || tokens.hasRefreshToken ? 'oauth-authorized' : 'oauth-expired'; - } - return server.auth === 'oauth' ? 'oauth-required' : 'not-applicable'; - }; - - const probe = async (): Promise<McpServerAuthState> => - this.withProbe({ name: entry.name, ...server }, cwd, (manager) => { - const status = manager.get(entry.name)?.status; - if (status === 'connected') return tokens.hasTokens ? 'oauth-authorized' : 'not-applicable'; - if (status === 'needs-auth') return tokens.hasTokens ? 'oauth-expired' : 'oauth-required'; - return offline(); - }); - - if (verify === true) return probe(); - if (verify === false || tokens.hasTokens || server.auth === 'oauth') return offline(); - return probe(); - } - - private async inspectServerDescriptors( - descriptors: readonly McpServerRuntimeDescriptor[], - catalog: readonly McpServerRuntimeDescriptor[], - ): Promise<readonly McpServerRuntimeInspection[]> { - const runtimeNameCounts = new Map<string, number>(); - for (const server of new Map(catalog.map((item) => [item.serverId, item])).values()) { - if (!server.enabled) continue; - runtimeNameCounts.set(server.runtimeName, (runtimeNameCounts.get(server.runtimeName) ?? 0) + 1); - } - const credentialStates = new Map<string, McpOAuthTokenState>(); - const probeConfigs = Object.create(null) as Record<string, McpServerConfig>; - for (const server of descriptors) { - if (configuredMcpAuthState(server) !== undefined) continue; - if (runtimeNameCounts.get(server.runtimeName) !== 1) continue; - const config = requireRemoteMcpConfig(server.runtimeName, server.config); - credentialStates.set( - server.serverId, - await this.oauth.tokenState(server.runtimeName, config.url), - ); - probeConfigs[server.runtimeName] = server.config; - } - let manager: McpConnectionManager | undefined; - try { - if (Object.keys(probeConfigs).length > 0) { - const section = this.config.get<McpSection | undefined>(MCP_SECTION); - manager = new McpConnectionManager({ - log: this.log, - oauthService: this.oauth, - resolveClientName: () => this.identity.current().slug, - resolveDefaultTimeouts: () => ({ - startupTimeoutMs: section?.startupTimeoutMs, - toolTimeoutMs: section?.toolTimeoutMs, - }), - }); - await manager.connectAll(probeConfigs); - } - const checkedAt = Date.now(); - return descriptors.map((server) => { - const configured = configuredMcpAuthState(server); - if (configured !== undefined) return { ...server, authStatus: configured }; - if (runtimeNameCounts.get(server.runtimeName) !== 1) { - return { - ...server, - authStatus: 'unavailable' as const, - checkedAt, - error: `MCP runtime name "${server.runtimeName}" is not unique`, - }; - } - const tokens = credentialStates.get(server.serverId); - const entry = manager?.get(server.runtimeName); - if (entry?.status === 'connected') { - return { - ...server, - authStatus: tokens?.hasTokens === true ? 'oauth-authorized' : 'not-applicable', - checkedAt, - }; - } - if (entry?.status === 'needs-auth') { - return { - ...server, - authStatus: tokens?.hasTokens === true ? 'oauth-expired' : 'oauth-required', - checkedAt, - }; - } - return { - ...server, - authStatus: 'unavailable' as const, - checkedAt, - error: entry?.error ?? `MCP server finished with status ${entry?.status ?? 'unknown'}`, - }; - }); - } finally { - await manager?.shutdown(); - } - } - - private async waitForReadiness(): Promise<void> { - await this.config.ready; - await this.identity.resolved(); - } -} - -function throwReadOnlyMcpServer(entry: McpRegistryEntry): void { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP server "${entry.name}" is read-only: it is defined in ${entry.origin} — edit that file instead`, - ); -} - -function toManagedServer(entry: McpRegistryEntry): McpManagedServer { - return { - name: entry.name, - config: entry.mutable ? entry.config : toMcpServerConfigView(entry.config), - source: entry.source, - origin: entry.origin, - mutable: entry.mutable, - plugin: entry.plugin, - }; -} - -function mcpConfigWithoutName(server: GlobalMcpServerConfig): McpServerConfig { - const { name: _name, ...config } = server; - return config; -} - -type McpRemoteServerConfig = Exclude<McpServerConfig, { readonly transport: 'stdio' }>; - -function requireRemoteMcpConfig(name: string, config: McpServerConfig): McpRemoteServerConfig { - if (config.transport !== 'stdio') return config; - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP server "${name}" does not use a remote transport`, - ); -} - -function requireOAuthMcpConfig(name: string, input: McpServerConfig): McpRemoteServerConfig { - const config = requireRemoteMcpConfig(name, input); - if (config.bearerTokenEnvVar !== undefined) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP server "${name}" uses a static bearer token`, - ); - } - if (config.headers !== undefined && config.auth !== 'oauth') { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `MCP server "${name}" uses static headers and is not marked for OAuth`, - ); - } - return config; -} - -export function mcpServerId(locator: McpServerLocator): string { - if (locator.source === 'global') return `global:${encodeURIComponent(locator.name)}`; - return `plugin:${encodeURIComponent(locator.pluginId)}:${encodeURIComponent(locator.serverName)}`; -} - -export function describeMcpServerLocator(locator: McpServerLocator): string { - if (locator.source === 'global') return locator.name; - return `${locator.pluginId}/${locator.serverName}`; -} - -type McpServerRuntimeDescriptor = Omit<McpServerDescriptor, 'config'> & { - readonly config: McpServerConfig; -}; - -type McpServerRuntimeInspection = McpServerRuntimeDescriptor & - Pick<McpServerInspection, 'authStatus' | 'checkedAt' | 'error'>; - -function serverDescriptor(entry: McpRegistryEntry): McpServerRuntimeDescriptor { - const locator: McpServerLocator = - entry.source === 'plugin' && entry.plugin !== undefined - ? { source: 'plugin', pluginId: entry.plugin.id, serverName: entry.plugin.name } - : { source: 'global', name: entry.name }; - return { - serverId: mcpServerId(locator), - locator, - runtimeName: entry.name, - canonicalUrl: - entry.config.transport === 'stdio' - ? undefined - : canonicalMcpOAuthResource(entry.config.url), - origin: entry.source, - config: entry.config, - enabled: entry.config.enabled !== false, - editable: entry.mutable, - }; -} - -function selectServerDescriptors( - catalog: readonly McpServerRuntimeDescriptor[], - targets?: readonly McpServerLocator[], -): readonly McpServerRuntimeDescriptor[] { - const effectiveTargets = targets === null ? undefined : targets; - if (effectiveTargets === undefined) return catalog; - const byId = new Map(catalog.map((server) => [server.serverId, server])); - return effectiveTargets.map((target) => { - const server = byId.get(mcpServerId(target)); - if (server !== undefined) return server; - throw new Error2( - ErrorCodes.MCP_SERVER_NOT_FOUND, - `MCP server "${describeMcpServerLocator(target)}" was not found`, - ); - }); -} - -function configuredMcpAuthState( - server: McpServerRuntimeDescriptor, -): McpServerAuthState | undefined { - if (!server.enabled || server.config.enabled === false) return 'not-applicable'; - if (server.config.transport === 'stdio') return 'not-applicable'; - if (server.config.bearerTokenEnvVar !== undefined) return 'bearer-token'; - if (server.config.headers !== undefined && server.config.auth !== 'oauth') { - return 'not-applicable'; - } - return undefined; -} - -function standaloneTestResult( - name: string, - manager: McpConnectionManager, -): McpServerTestResult { - const entry = manager.get(name); - if (entry?.status !== 'connected') { - return { - success: false, - output: entry?.error ?? `MCP server "${name}" finished with status ${entry?.status ?? 'unknown'}`, - }; - } - const tools = manager.resolved(name)?.rawTools ?? []; - const lines = [ - `Connected to MCP server "${name}".`, - `Available tools: ${tools.length}`, - ...tools.map((tool) => `- ${tool.name}${tool.description ? `: ${tool.description}` : ''}`), - ]; - return { success: true, output: lines.join('\n') }; -} - -registerScopedService( - LifecycleScope.App, - IMcpManagementService, - McpManagementService, - ScopeActivation.OnDemand, - 'mcpManagement', -); diff --git a/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistry.ts b/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistry.ts deleted file mode 100644 index b3d25b916..000000000 --- a/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistry.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -import type { McpServerConfig } from '#/mcpCore/config-schema'; - -export type McpServerSource = 'global' | 'plugin' | 'caller'; - -export interface McpRegistryPluginOrigin { - readonly id: string; - readonly name: string; -} - -export interface McpRegistryEntry { - readonly name: string; - readonly config: McpServerConfig; - readonly source: McpServerSource; - readonly origin: string; - readonly mutable: boolean; - readonly plugin?: McpRegistryPluginOrigin; -} - -export interface McpRegistryQuery { - readonly cwd?: string; -} - -export interface IMcpRegistryService { - readonly _serviceBrand: undefined; - - list(query?: McpRegistryQuery): Promise<readonly McpRegistryEntry[]>; - - get(name: string, query?: McpRegistryQuery): Promise<McpRegistryEntry>; - - resolveRuntimeTarget(name: string, query?: McpRegistryQuery): Promise<McpRegistryEntry | undefined>; -} - -export const IMcpRegistryService: ServiceIdentifier<IMcpRegistryService> = - createDecorator<IMcpRegistryService>('mcpRegistryService'); - -export { mcpServerConfigsEqual } from '#/mcpCore/connection-manager'; diff --git a/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistryService.ts b/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistryService.ts deleted file mode 100644 index 2398c1904..000000000 --- a/packages/agent-core-v2/src/app/mcpRegistry/mcpRegistryService.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { canonicalWorkspaceRoot } from '#/_base/utils/paths'; - -import { ErrorCodes, Error2 } from '#/errors'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { loadMcpServersDetailed } from '#/app/mcpConfig/configLoader'; -import { IMcpConfigStore } from '#/app/mcpConfig/configStore'; -import { IPluginService } from '#/app/plugin/plugin'; -import { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import { readWorkspaceTrust } from '#/workspace/workspaceTrust/trustRecord'; - -import { - IMcpRegistryService, - type McpRegistryEntry, - type McpRegistryQuery, -} from './mcpRegistry'; - -export class McpRegistryService implements IMcpRegistryService { - declare readonly _serviceBrand: undefined; - - constructor( - @IMcpConfigStore private readonly store: IMcpConfigStore, - @IPluginService private readonly plugins: IPluginService, - @IHostFileSystem private readonly fs: IHostFileSystem, - @IBootstrapService private readonly bootstrap: IBootstrapService, - @IAtomicDocumentStore private readonly docs: IAtomicDocumentStore, - ) {} - - async list(query: McpRegistryQuery = {}): Promise<readonly McpRegistryEntry[]> { - const out: McpRegistryEntry[] = []; - - if (query.cwd === undefined) { - const userEntries = await this.store.list(); - for (const server of userEntries) { - const { name, ...config } = server; - out.push({ - name, - config, - source: 'global', - origin: this.store.path, - mutable: true, - }); - } - } else { - const cwd = canonicalWorkspaceRoot(query.cwd); - if (!(await readWorkspaceTrust(this.docs, cwd))) { - const userEntries = await this.store.list(); - for (const server of userEntries) { - const { name, ...config } = server; - out.push({ - name, - config, - source: 'global', - origin: this.store.path, - mutable: true, - }); - } - } else { - const detailed = await loadMcpServersDetailed({ - fs: this.fs, - cwd, - homeDir: this.bootstrap.homeDir, - }); - for (const [name, config] of Object.entries(detailed.servers)) { - const origin = detailed.origins[name] ?? this.store.path; - out.push({ - name, - config, - source: 'global', - origin, - mutable: origin === this.store.path, - }); - } - } - } - - for (const entry of await this.plugins.mcpServerEntries()) { - out.push({ - name: entry.name, - config: entry.config, - source: 'plugin', - origin: entry.pluginId, - mutable: false, - plugin: { id: entry.pluginId, name: entry.serverName }, - }); - } - - return out; - } - - async get(name: string, query: McpRegistryQuery = {}): Promise<McpRegistryEntry> { - const entry = (await this.list(query)).find((candidate) => candidate.name === name); - if (entry !== undefined) return entry; - throw new Error2(ErrorCodes.MCP_SERVER_NOT_FOUND, `MCP server "${name}" was not found`); - } - - async resolveRuntimeTarget( - name: string, - query: McpRegistryQuery = {}, - ): Promise<McpRegistryEntry | undefined> { - const matches = (await this.list(query)).filter((entry) => entry.name === name); - const file = matches.find((entry) => entry.source === 'global'); - if (file !== undefined) return file; - return matches.find((entry) => entry.source === 'plugin' && entry.config.enabled !== false); - } -} - -registerScopedService( - LifecycleScope.App, - IMcpRegistryService, - McpRegistryService, - ScopeActivation.OnDemand, - 'mcpRegistry', -); diff --git a/packages/agent-core-v2/src/app/plugin/errors.ts b/packages/agent-core-v2/src/app/plugin/errors.ts index b8d2f7ca3..7d66166e8 100644 --- a/packages/agent-core-v2/src/app/plugin/errors.ts +++ b/packages/agent-core-v2/src/app/plugin/errors.ts @@ -1,3 +1,7 @@ +/** + * `plugin` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const PluginErrors = { diff --git a/packages/agent-core-v2/src/app/plugin/github-resolver.ts b/packages/agent-core-v2/src/app/plugin/github-resolver.ts index c3cca4490..450c6078e 100644 --- a/packages/agent-core-v2/src/app/plugin/github-resolver.ts +++ b/packages/agent-core-v2/src/app/plugin/github-resolver.ts @@ -1,3 +1,10 @@ +/** + * `plugin` domain — resolves GitHub plugin sources without the REST API. + * + * Selects release or ref tarballs and resolves movable refs to commit SHAs + * through GitHub's Atom feed so installs and update checks use exact content. + */ + import { Error2, ErrorCodes } from '#/errors'; import type { GithubRef } from './source'; diff --git a/packages/agent-core-v2/src/app/plugin/manager.ts b/packages/agent-core-v2/src/app/plugin/manager.ts index f917017e1..2b6fae854 100644 --- a/packages/agent-core-v2/src/app/plugin/manager.ts +++ b/packages/agent-core-v2/src/app/plugin/manager.ts @@ -1,21 +1,28 @@ +/** + * `plugin` domain — manages installed plugin state and consumption metadata. + * + * Installs, reloads, persists, and summarizes plugins, counting loadable + * plugin skills through skill discovery. + */ + import { cp, mkdir, mkdtemp, realpath, rename, rm, stat } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import path from 'node:path'; -import type { HookDef } from '#/features/externalHooks/internal/types'; -import { discoverFileSkills } from '#/features/skill/catalog/fileSkillDiscovery'; -import type { SkillDiscoveryResult } from '#/features/skill/catalog/skillDiscovery'; -import type { SkillRoot } from '#/features/skill/catalog/types'; import { BugIndicatingError, Error2, ErrorCodes, PluginErrors } from '#/errors'; +import type { HookDef } from '#/agent/externalHooks/types'; import type { McpServerConfig } from '#/mcpCore/config-schema'; +import type { PluginAgentRoot } from './types'; +import { discoverFileSkills } from '#/app/skillCatalog/fileSkillDiscovery'; +import type { SkillDiscoveryResult } from '#/app/skillCatalog/skillDiscovery'; +import type { SkillRoot } from '#/app/skillCatalog/types'; import { downloadZip, extractZip } from './archive'; import { loadPluginCommand } from './commands'; import { resolveGithubCommitSha, resolveGithubSource } from './github-resolver'; -import { parseManifest, type ParsedManifestResult } from './manifest'; import { resolveInstallSource } from './source'; +import { parseManifest, type ParsedManifestResult } from './manifest'; import { readInstalled, writeInstalled, type InstalledRecord } from './store'; -import type { PluginAgentRoot } from './types'; import { normalizePluginId, type EnabledPluginSessionStart, @@ -24,7 +31,6 @@ import { type PluginCommandDef, type PluginGithubMetadata, type PluginInfo, - type PluginMcpServerEntry, type PluginMcpServerInfo, type PluginRecord, type PluginSource, @@ -45,7 +51,9 @@ interface ManagedPluginCopy { export class PluginManager { private readonly kimiHomeDir: string; - private readonly discoverSkills: (roots: readonly SkillRoot[]) => Promise<SkillDiscoveryResult>; + private readonly discoverSkills: ( + roots: readonly SkillRoot[], + ) => Promise<SkillDiscoveryResult>; private records = new Map<string, PluginRecord>(); constructor(options: PluginManagerOptions) { @@ -116,8 +124,7 @@ export class PluginManager { const parsed = await parseManifest(sourceRoot); if (parsed.manifest === undefined) { - const msg = - parsed.diagnostics.find((d) => d.severity === 'error')?.message ?? 'no manifest'; + const msg = parsed.diagnostics.find((d) => d.severity === 'error')?.message ?? 'no manifest'; throw new Error2( ErrorCodes.PLUGIN_LOAD_FAILED, sourceType === 'local-path' @@ -313,7 +320,6 @@ export class PluginManager { path: dir, source: 'extra', plugin: { id: record.id, instructions: record.skillInstructions }, - scanMode: record.manifest.rootSkillFallback ? 'root-skill-only' : undefined, }); } } @@ -369,28 +375,6 @@ export class PluginManager { return out; } - mcpServerEntries(): readonly PluginMcpServerEntry[] { - const out: PluginMcpServerEntry[] = []; - for (const record of this.records.values()) { - if (record.state !== 'ok' || record.manifest === undefined) continue; - for (const [name, config] of Object.entries(record.manifest.mcpServers ?? {})) { - const enabled = record.enabled && isMcpServerEnabled(record, name, config); - const effective = withPluginMcpRuntime( - withMcpServerEnabled(config, enabled), - record.root, - this.kimiHomeDir, - ); - out.push({ - name: pluginMcpRuntimeName(record.id, name), - config: effective, - pluginId: record.id, - serverName: name, - }); - } - } - return out; - } - summaries(): readonly PluginSummary[] { return this.list().map((record) => recordToSummary(record)); } @@ -605,7 +589,11 @@ async function recordFrom(input: { originalSource: input.originalSource, capabilities: input.capabilities, github: input.github, - skillCount: await countDiscoveredPluginSkills(input.id, parsed.manifest, input.discoverSkills), + skillCount: await countDiscoveredPluginSkills( + input.id, + parsed.manifest, + input.discoverSkills, + ), manifest: parsed.manifest, manifestKind: parsed.manifestKind, manifestPath: parsed.manifestPath, @@ -751,7 +739,6 @@ async function countDiscoveredPluginSkills( path: dir, source: 'extra', plugin: { id: pluginId, instructions: manifest?.skillInstructions }, - scanMode: manifest?.rootSkillFallback ? 'root-skill-only' : undefined, })); const result = await discoverSkills(roots); return result.skills.length; diff --git a/packages/agent-core-v2/src/app/plugin/manifest.ts b/packages/agent-core-v2/src/app/plugin/manifest.ts index cc5ca205a..3a3a7bae0 100644 --- a/packages/agent-core-v2/src/app/plugin/manifest.ts +++ b/packages/agent-core-v2/src/app/plugin/manifest.ts @@ -1,7 +1,7 @@ import { readdir, readFile, realpath, stat } from 'node:fs/promises'; import path from 'node:path'; -import { HookDefSchema, type HookDefConfig } from '#/features/externalHooks/configSection'; +import { HookDefSchema, type HookDefConfig } from '#/agent/externalHooks/configSection'; import { McpServerConfigSchema, type McpServerConfig } from '#/mcpCore/config-schema'; import { @@ -98,12 +98,10 @@ export async function parseManifest(pluginRoot: string): Promise<ParsedManifestR } let skills = await resolveDirListField(pluginRoot, 'skills', raw['skills'], diagnostics); - let rootSkillFallback: boolean | undefined; if (raw['skills'] === undefined) { const rootSkillMd = path.join(pluginRoot, 'SKILL.md'); if (await isFile(rootSkillMd)) { skills = [pluginRoot]; - rootSkillFallback = true; } } @@ -131,7 +129,6 @@ export async function parseManifest(pluginRoot: string): Promise<ParsedManifestR license: stringField(raw, 'license'), author: readAuthor(raw['author']), skills, - rootSkillFallback, agents, sessionStart: readSessionStart(raw['sessionStart'], diagnostics), mcpServers: await readMcpServers(pluginRoot, raw['mcpServers'], diagnostics), diff --git a/packages/agent-core-v2/src/app/plugin/marketplace.ts b/packages/agent-core-v2/src/app/plugin/marketplace.ts deleted file mode 100644 index 2d2af1fd8..000000000 --- a/packages/agent-core-v2/src/app/plugin/marketplace.ts +++ /dev/null @@ -1,365 +0,0 @@ -import { readFile } from 'node:fs/promises'; -import { homedir } from 'node:os'; -import { dirname, isAbsolute, join, resolve } from 'node:path'; -import { fileURLToPath } from 'node:url'; - -import { gt, valid } from 'semver'; - -export const KIMI_CODE_PLUGIN_MARKETPLACE_URL = - 'https://code.kimi.com/kimi-code/plugins/marketplace.json'; -export const KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV = 'KIMI_CODE_PLUGIN_MARKETPLACE_URL'; - -export const PLUGIN_MARKETPLACE_TIERS = ['official', 'curated'] as const; - -export type PluginMarketplaceTier = (typeof PLUGIN_MARKETPLACE_TIERS)[number]; - -export interface PluginMarketplaceEntry { - readonly id: string; - readonly displayName: string; - readonly source: string; - readonly tier?: PluginMarketplaceTier; - readonly version?: string; - readonly description?: string; - readonly homepage?: string; - readonly keywords?: readonly string[]; - readonly builtIn?: boolean; -} - -export interface PluginMarketplace { - readonly source: string; - readonly version?: string; - readonly plugins: readonly PluginMarketplaceEntry[]; -} - -export type MarketplaceUpdateStatus = - | { readonly kind: 'not-installed' } - | { readonly kind: 'up-to-date'; readonly version?: string } - | { readonly kind: 'update'; readonly local: string; readonly latest: string }; - -export interface MarketplaceLocation { - readonly raw: string; - readonly kind: 'remote' | 'local'; - readonly resolved: string; -} - -export interface ReadPluginMarketplaceOptions { - readonly source: string; - readonly workDir: string; - readonly fetchImpl?: typeof fetch; - readonly sourceCheckoutLocation?: () => Promise<MarketplaceLocation | undefined>; -} - -export function computeUpdateStatus( - latest: string | undefined, - local: string | undefined, - installed: boolean, -): MarketplaceUpdateStatus { - if (!installed) return { kind: 'not-installed' }; - if ( - latest !== undefined && - local !== undefined && - valid(latest) !== null && - valid(local) !== null && - gt(latest, local) - ) { - return { kind: 'update', local, latest }; - } - return { kind: 'up-to-date', version: local }; -} - -export function resolveMarketplaceLocation(source: string, workDir: string): MarketplaceLocation { - const trimmed = source.trim(); - if (trimmed.length === 0) { - throw new Error(`${KIMI_CODE_PLUGIN_MARKETPLACE_URL_ENV} cannot be empty.`); - } - if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) { - return { raw: trimmed, kind: 'remote', resolved: trimmed }; - } - if (trimmed.startsWith('file://')) { - const path = fileURLToPath(trimmed); - return { raw: trimmed, kind: 'local', resolved: path }; - } - return { raw: trimmed, kind: 'local', resolved: resolveLocalPath(trimmed, workDir) }; -} - -export async function readPluginMarketplace( - options: ReadPluginMarketplaceOptions, -): Promise<{ raw: string; location: MarketplaceLocation }> { - const location = resolveMarketplaceLocation(options.source, options.workDir); - const fetchImpl = options.fetchImpl ?? fetch; - try { - return { raw: await readMarketplaceText(location, fetchImpl), location }; - } catch (error) { - const fallback = - options.sourceCheckoutLocation !== undefined - ? await options.sourceCheckoutLocation() - : undefined; - if (fallback === undefined) throw error; - return { raw: await readMarketplaceText(fallback, fetchImpl), location: fallback }; - } -} - -export function parsePluginMarketplace(raw: string, location: MarketplaceLocation): PluginMarketplace { - let parsed: unknown; - try { - parsed = JSON.parse(raw); - } catch (error) { - throw new Error(`Plugin marketplace is not valid JSON: ${formatParseError(error)}`, { - cause: error, - }); - } - - if (!isRecord(parsed)) { - throw new TypeError('Plugin marketplace must be an object.'); - } - const rawPlugins = parsed['plugins']; - if (!Array.isArray(rawPlugins)) { - throw new TypeError('Plugin marketplace must contain a "plugins" array.'); - } - - return { - source: location.resolved, - version: stringField(parsed, 'version'), - plugins: rawPlugins.map((entry, index) => parseMarketplaceEntry(entry, index, location)), - }; -} - -export function withBuiltInEntries( - marketplace: PluginMarketplace, - builtIns: readonly PluginMarketplaceEntry[], -): PluginMarketplace { - const builtInIds = new Set(builtIns.map((entry) => entry.id)); - const catalogById = new Map(marketplace.plugins.map((entry) => [entry.id, entry])); - const catalog = marketplace.plugins.filter((entry) => !builtInIds.has(entry.id)); - const enrichedBuiltIns = builtIns.map((entry) => { - const version = catalogById.get(entry.id)?.version; - return version === undefined ? entry : { ...entry, version }; - }); - return { ...marketplace, plugins: [...catalog, ...enrichedBuiltIns] }; -} - -export async function withLatestVersions( - marketplace: PluginMarketplace, - fetchImpl: typeof fetch, -): Promise<PluginMarketplace> { - const plugins = await Promise.all( - marketplace.plugins.map(async (entry) => { - if (entry.version !== undefined) return entry; - const latest = await resolveLatestGithubRelease(entry.source, fetchImpl); - return latest === undefined ? entry : { ...entry, version: latest }; - }), - ); - return { ...marketplace, plugins }; -} - -async function readMarketplaceText( - location: MarketplaceLocation, - fetchImpl: typeof fetch, -): Promise<string> { - if (location.kind === 'local') { - return readFile(location.resolved, 'utf8'); - } - const response = await fetchImpl(location.resolved); - if (!response.ok) { - throw new Error(`Plugin marketplace returned HTTP ${response.status}`); - } - return response.text(); -} - -function parseMarketplaceEntry( - value: unknown, - index: number, - location: MarketplaceLocation, -): PluginMarketplaceEntry { - if (!isRecord(value)) { - throw new TypeError(`Plugin marketplace entry ${index + 1} must be an object.`); - } - const id = requiredString(value, 'id', index); - validateMarketplaceEntryType(value, id); - const source = stringField(value, 'source') ?? - stringField(value, 'url') ?? - stringField(value, 'downloadUrl'); - if (source === undefined) { - throw new Error(`Plugin marketplace entry ${id} must define "source".`); - } - const resolvedSource = resolveEntrySource(source, location); - return { - id, - displayName: stringField(value, 'displayName') ?? stringField(value, 'name') ?? id, - source: resolvedSource, - tier: parseMarketplaceTier(value, id), - version: stringField(value, 'version') ?? deriveVersionFromGithubSource(resolvedSource), - description: stringField(value, 'description') ?? stringField(value, 'shortDescription'), - homepage: stringField(value, 'homepage') ?? stringField(value, 'websiteURL'), - keywords: stringArrayField(value, 'keywords'), - }; -} - -function validateMarketplaceEntryType(value: Record<string, unknown>, id: string): void { - const raw = value['type']; - if (raw === undefined) return; - if (typeof raw !== 'string') { - throw new TypeError(`Plugin marketplace entry ${id} "type" must be a string.`); - } - const type = raw.trim(); - if (type === 'plugin' || type === 'managed' || type === 'guide') return; - throw new Error( - `Plugin marketplace entry ${id} "type" must be "plugin". Legacy aliases "managed" and "guide" are also accepted.`, - ); -} - -function parseMarketplaceTier( - value: Record<string, unknown>, - id: string, -): PluginMarketplaceTier | undefined { - const raw = value['tier']; - if (raw === undefined) return undefined; - if (typeof raw !== 'string') { - throw new TypeError(`Plugin marketplace entry ${id} "tier" must be a string.`); - } - const tier = raw.trim(); - if (tier.length === 0) return undefined; - if ((PLUGIN_MARKETPLACE_TIERS as readonly string[]).includes(tier)) { - return tier as PluginMarketplaceTier; - } - throw new Error( - `Plugin marketplace entry ${id} "tier" must be one of: ${PLUGIN_MARKETPLACE_TIERS.join(', ')}.`, - ); -} - -function resolveEntrySource(source: string, location: MarketplaceLocation): string { - const trimmed = source.trim(); - if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) { - return trimmed; - } - if (trimmed.startsWith('file://')) return fileURLToPath(trimmed); - if (trimmed === '~' || trimmed.startsWith('~/')) { - return resolveLocalPath(trimmed, ''); - } - if (isAbsolute(trimmed)) return trimmed; - if (location.kind === 'remote') { - return new URL(trimmed, location.resolved).toString(); - } - return resolve(dirname(location.resolved), trimmed); -} - -function deriveVersionFromGithubSource(source: string): string | undefined { - let url: URL; - try { - url = new URL(source); - } catch { - return undefined; - } - if (url.hostname !== 'github.com' && url.hostname !== 'www.github.com') { - return undefined; - } - const [, , kind, a, b] = url.pathname.split('/').filter(Boolean); - const ref = - kind === 'releases' && a === 'tag' ? b : kind === 'tree' || kind === 'commit' ? a : undefined; - if (ref === undefined) return undefined; - let decoded: string; - try { - decoded = decodeURIComponent(ref); - } catch { - decoded = ref; - } - const candidate = decoded.replace(/^v/i, ''); - return valid(candidate) !== null ? candidate : undefined; -} - -async function resolveLatestGithubRelease( - source: string, - fetchImpl: typeof fetch, -): Promise<string | undefined> { - const repo = parseGithubRepo(source); - if (repo === undefined) return undefined; - try { - const tag = await fetchLatestReleaseTag(repo.owner, repo.repo, fetchImpl); - if (tag === undefined) return undefined; - const candidate = tag.replace(/^v/i, ''); - return valid(candidate) !== null ? candidate : undefined; - } catch { - return undefined; - } -} - -function parseGithubRepo(source: string): { owner: string; repo: string } | undefined { - let url: URL; - try { - url = new URL(source); - } catch { - return undefined; - } - if (url.hostname !== 'github.com' && url.hostname !== 'www.github.com') return undefined; - const segments = url.pathname.split('/').filter(Boolean); - if (segments.length !== 2) return undefined; - const [owner, repo] = segments; - return { owner: owner!, repo: repo! }; -} - -async function fetchLatestReleaseTag( - owner: string, - repo: string, - fetchImpl: typeof fetch, -): Promise<string | undefined> { - const url = `https://github.com/${owner}/${repo}/releases/latest`; - const resp = await fetchImpl(url, { redirect: 'manual' }); - if (resp.status === 404) return undefined; - if (resp.status !== 301 && resp.status !== 302) { - throw new Error( - `Could not look up latest release of ${owner}/${repo}: HTTP ${resp.status} (${url}).`, - ); - } - const location = resp.headers.get('location'); - if (location === null) return undefined; - const match = /\/releases\/tag\/([^/?#]+)/.exec(location); - const tag = match?.[1]; - if (tag === undefined) return undefined; - try { - return decodeURIComponent(tag); - } catch { - return tag; - } -} - -function resolveLocalPath(input: string, workDir: string): string { - if (input === '~') return homedir(); - if (input.startsWith('~/')) return join(homedir(), input.slice(2)); - return isAbsolute(input) ? input : resolve(workDir, input); -} - -function requiredString(value: Record<string, unknown>, field: string, index: number): string { - const result = stringField(value, field); - if (result === undefined) { - throw new Error(`Plugin marketplace entry ${index + 1} must define "${field}".`); - } - return result; -} - -function stringField(value: Record<string, unknown>, field: string): string | undefined { - const raw = value[field]; - if (typeof raw !== 'string') return undefined; - const trimmed = raw.trim(); - return trimmed.length > 0 ? trimmed : undefined; -} - -function stringArrayField( - value: Record<string, unknown>, - field: string, -): readonly string[] | undefined { - const raw = value[field]; - if (!Array.isArray(raw)) return undefined; - const out = raw - .filter((item): item is string => typeof item === 'string') - .map((item) => item.trim()) - .filter((item) => item.length > 0); - return out.length > 0 ? out : undefined; -} - -function isRecord(value: unknown): value is Record<string, unknown> { - return typeof value === 'object' && value !== null && !Array.isArray(value); -} - -function formatParseError(error: unknown): string { - return error instanceof Error ? error.message : String(error); -} diff --git a/packages/agent-core-v2/src/app/plugin/plugin.ts b/packages/agent-core-v2/src/app/plugin/plugin.ts index 7d362c9bd..3cfad9f88 100644 --- a/packages/agent-core-v2/src/app/plugin/plugin.ts +++ b/packages/agent-core-v2/src/app/plugin/plugin.ts @@ -1,8 +1,17 @@ +/** + * `plugin` domain — App-scoped plugin management and consumption contract. + * + * Defines `IPluginService`, which manages installed plugins and exposes their + * enabled commands, skills, session-start content, system-prompt sections, + * MCP servers, and hooks. Successful reloads are announced through + * `onDidReload`. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; -import type { HookDef } from '#/features/externalHooks/internal/types'; -import type { SkillRoot } from '#/features/skill/catalog/types'; +import type { HookDef } from '#/agent/externalHooks/types'; import type { McpServerConfig } from '#/mcpCore/config-schema'; +import type { SkillRoot } from '#/app/skillCatalog/types'; import type { EnabledPluginSessionStart, @@ -10,9 +19,7 @@ import type { PluginAgentRoot, PluginCommandDef, PluginInfo, - PluginMcpServerEntry, PluginMutationSummary, - PluginReloadEvent, PluginSummary, PluginUpdateStatus, ReloadSummary, @@ -58,10 +65,16 @@ export interface IPluginService { enabledSessionStarts(): Promise<readonly EnabledPluginSessionStart[]>; enabledSystemPrompts(): Promise<readonly EnabledPluginSystemPrompt[]>; enabledMcpServers(): Promise<Record<string, McpServerConfig>>; - mcpServerEntries(): Promise<readonly PluginMcpServerEntry[]>; enabledHooks(): Promise<readonly HookDef[]>; + // Consumption reads resolve to a per-method fallback (never reject) while + // no snapshot has loaded; consumers pinning a read use this to tell a real + // empty snapshot from the fallback. hasLoadedSnapshot(): boolean; - readonly onDidReload: Event<PluginReloadEvent>; + readonly onDidReload: Event<ReloadSummary>; + // Fires only after a mutation (install / enable / disable / remove) has + // reloaded and notified — unlike `onDidReload`, an explicit + // `reloadPlugins()` does not raise it, so live-session consumers can tell + // "the plugin set changed under you" apart from a deliberate reload. readonly onDidMutate: Event<PluginMutationSummary>; } diff --git a/packages/agent-core-v2/src/app/plugin/pluginEvents.ts b/packages/agent-core-v2/src/app/plugin/pluginEvents.ts deleted file mode 100644 index db3daaca3..000000000 --- a/packages/agent-core-v2/src/app/plugin/pluginEvents.ts +++ /dev/null @@ -1,9 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -export class PluginChanged extends Event2<{ readonly payload: Record<string, never> }> { - static override readonly type = 'event.plugin.changed'; -} -export interface PluginChanged { - readonly payload: Record<string, never>; -} diff --git a/packages/agent-core-v2/src/app/plugin/pluginService.ts b/packages/agent-core-v2/src/app/plugin/pluginService.ts index 4469bfcb8..0a8d6901c 100644 --- a/packages/agent-core-v2/src/app/plugin/pluginService.ts +++ b/packages/agent-core-v2/src/app/plugin/pluginService.ts @@ -1,16 +1,34 @@ +/** + * `plugin` domain — `IPluginService` implementation. + * + * Manages the App-wide plugin catalog through a filesystem-backed manager, + * roots plugin storage at the bootstrap paths, counts plugin skills through + * skill discovery, and resolves managed endpoint settings through the + * provider service plus the startup snapshot. Exposes plugin contributions + * through the hook, MCP, skill, and system-prompt contracts. Mutations + * serialize through a queue and consumption reads wait on it; while no + * snapshot has loaded, a consumption read resolves to its per-method + * fallback instead of rejecting (`hasLoadedSnapshot` exposes the state). + * Every mutation (install / enable / disable / remove) re-fires + * `onDidReload` so workspace-scoped consumers refresh their contributions + * immediately, and additionally fires `onDidMutate` so live-session + * consumers can react to the plugin set changing under them (an explicit + * `reloadPlugins()` raises only `onDidReload`). Bound at App scope. + */ + import { KIMI_CODE_PROVIDER_NAME } from '@moonshot-ai/kimi-code-oauth'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Service } from '#/_base/di/service'; -import { AsyncEmitter, Emitter, type Event } from '#/_base/event'; -import type { HookDef } from '#/features/externalHooks/internal/types'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; +import { Emitter, type Event } from '#/_base/event'; import { LifecycleScope } from '#/app/scopes'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; -import type { SkillRoot } from '#/features/skill/catalog/types'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { BugIndicatingError, Error2, PluginErrors } from '#/errors'; +import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IProviderService } from '#/kosong/provider/provider'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; +import type { HookDef } from '#/agent/externalHooks/types'; import type { McpServerConfig } from '#/mcpCore/config-schema'; +import type { SkillRoot } from '#/app/skillCatalog/types'; import { PluginManager } from './manager'; import { @@ -27,10 +45,8 @@ import type { PluginCommandDef, PluginInfo, PluginAgentRoot, - PluginMcpServerEntry, PluginMutation, PluginMutationSummary, - PluginReloadEvent, PluginSummary, PluginUpdateStatus, ReloadSummary, @@ -39,17 +55,6 @@ import type { const KIMI_CODE_BASE_URL_ENV = 'KIMI_CODE_BASE_URL'; const KIMI_CODE_OAUTH_HOST_ENV = 'KIMI_CODE_OAUTH_HOST'; const KIMI_OAUTH_HOST_ENV = 'KIMI_OAUTH_HOST'; -const NO_ABORT = new AbortController().signal; - -interface PluginReloadNotification { - readonly summary: ReloadSummary; - readonly delivery: Promise<void>; -} - -interface PluginMutationOutcome<T> { - readonly result: T; - readonly notification: PluginReloadNotification; -} export class PluginService extends Service implements IPluginService { declare readonly _serviceBrand: undefined; @@ -62,10 +67,10 @@ export class PluginService extends Service implements IPluginService { private snapshotLoaded = false; private loadError: Error | undefined; private mutationQueue: Promise<void> = Promise.resolve(); - private readonly onDidReloadEmitter = this._register(new AsyncEmitter<PluginReloadEvent>()); + private readonly onDidReloadEmitter = this._register(new Emitter<ReloadSummary>()); private readonly onDidMutateEmitter = this._register(new Emitter<PluginMutationSummary>()); - readonly onDidReload: Event<PluginReloadEvent> = this.onDidReloadEmitter.event; + readonly onDidReload: Event<ReloadSummary> = this.onDidReloadEmitter.event; readonly onDidMutate: Event<PluginMutationSummary> = this.onDidMutateEmitter.event; constructor( @@ -89,64 +94,52 @@ export class PluginService extends Service implements IPluginService { } installPlugin(input: InstallPluginInput): Promise<PluginSummary> { - return this.runNotifiedMutation(async () => { + return this.runSerializedOperation(async () => { const record = await this.manager.install(input.source); const info = this.manager.info(record.id); if (info === undefined) throw new BugIndicatingError(`Plugin "${record.id}" missing right after install`); - const notification = await this.reloadAndNotify({ - mutation: { kind: 'install', id: record.id }, - }); - return { result: info, notification }; + await this.reloadAndNotify({ mutation: { kind: 'install', id: record.id } }); + return info; }); } setPluginEnabled(input: SetPluginEnabledInput): Promise<void> { - return this.runNotifiedMutation(async () => { + return this.runSerializedOperation(async () => { await this.manager.setEnabled(input.id, input.enabled); - const notification = await this.reloadAndNotify({ + await this.reloadAndNotify({ mutation: { kind: input.enabled ? 'enable' : 'disable', id: input.id }, }); - return { result: undefined, notification }; }); } setPluginMcpServerEnabled(input: SetPluginMcpServerEnabledInput): Promise<void> { - return this.runNotifiedMutation(async () => { + return this.runSerializedOperation(async () => { await this.manager.setMcpServerEnabled(input.id, input.server, input.enabled); - const notification = await this.reloadAndNotify({ - mutation: { kind: 'mcp-server', id: input.id }, - }); - return { result: undefined, notification }; + await this.reloadAndNotify({ mutation: { kind: 'mcp-server', id: input.id } }); }); } removePlugin(input: RemovePluginInput): Promise<void> { - return this.runNotifiedMutation(async () => { + return this.runSerializedOperation(async () => { await this.manager.remove(input.id); - const notification = await this.reloadAndNotify({ - mutation: { kind: 'remove', id: input.id }, - }); - return { result: undefined, notification }; + await this.reloadAndNotify({ mutation: { kind: 'remove', id: input.id } }); }); } reloadPlugins(): Promise<ReloadSummary> { - const reload = this.awaitReloadDelivery( - this.enqueueMutation(async () => { - try { - const notification = await this.reloadAndNotify(); - return { result: notification.summary, notification }; - } catch (error) { - this.loadError = error instanceof Error ? error : new Error(String(error)); - throw new Error2( - PluginErrors.codes.PLUGIN_LOAD_FAILED, - `Failed to reload plugins: ${this.loadError.message}`, - { cause: this.loadError, details: { kimiHomeDir: this.homeDir } }, - ); - } - }), - ); + const reload = this.enqueueMutation(async () => { + try { + return await this.reloadAndNotify(); + } catch (error) { + this.loadError = error instanceof Error ? error : new Error(String(error)); + throw new Error2( + PluginErrors.codes.PLUGIN_LOAD_FAILED, + `Failed to reload plugins: ${this.loadError.message}`, + { cause: this.loadError, details: { kimiHomeDir: this.homeDir } }, + ); + } + }); this.initialLoadPromise ??= reload.then( () => undefined, () => undefined, @@ -156,24 +149,14 @@ export class PluginService extends Service implements IPluginService { private async reloadAndNotify(options?: { readonly mutation: PluginMutation; - }): Promise<PluginReloadNotification> { + }): Promise<ReloadSummary> { const summary = await this.manager.reload(); this.snapshotLoaded = true; this.loadError = undefined; - const delivery = this.onDidReloadEmitter.fireAsyncConcurrent(summary, NO_ABORT); + this.onDidReloadEmitter.fire(summary); if (options?.mutation !== undefined) this.onDidMutateEmitter.fire({ ...summary, mutation: options.mutation }); - return { summary, delivery }; - } - - private runNotifiedMutation<T>(operation: () => Promise<PluginMutationOutcome<T>>): Promise<T> { - return this.awaitReloadDelivery(this.runSerializedOperation(operation)); - } - - private async awaitReloadDelivery<T>(operation: Promise<PluginMutationOutcome<T>>): Promise<T> { - const { result, notification } = await operation; - await notification.delivery; - return result; + return summary; } getPluginInfo(input: GetPluginInfoInput): Promise<PluginInfo> { @@ -225,17 +208,6 @@ export class PluginService extends Service implements IPluginService { }); } - mcpServerEntries(): Promise<readonly PluginMcpServerEntry[]> { - return this.runManagementRead(async () => { - const entries = this.manager.mcpServerEntries(); - if (!entries.some((entry) => entry.config.transport === 'stdio')) { - return entries; - } - const managedEnv = await this.managedKimiCodeEnvForPlugins(); - return withManagedKimiPluginEnvOnEntries(entries, managedEnv); - }); - } - enabledHooks(): Promise<readonly HookDef[]> { return this.runConsumptionRead([], async () => this.manager.enabledHooks()); } @@ -311,7 +283,8 @@ export class PluginService extends Service implements IPluginService { const envBaseUrl = this.envBaseUrl; const envOAuthHost = this.envOAuthHost; const hasEnvOverride = envBaseUrl !== undefined || envOAuthHost !== undefined; - const baseUrl = envBaseUrl !== undefined ? envBaseUrl.replace(/\/+$/, '') : provider?.baseUrl; + const baseUrl = + envBaseUrl !== undefined ? envBaseUrl.replace(/\/+$/, '') : provider?.baseUrl; const oauthHost = hasEnvOverride ? envOAuthHost : provider?.oauth?.oauthHost; const env: Record<string, string> = {}; if (baseUrl !== undefined) env[KIMI_CODE_BASE_URL_ENV] = baseUrl; @@ -328,23 +301,13 @@ function withManagedKimiPluginEnv( const out: Record<string, McpServerConfig> = {}; for (const [name, server] of Object.entries(pluginServers)) { out[name] = - server.transport === 'stdio' ? { ...server, env: { ...server.env, ...managedEnv } } : server; + server.transport === 'stdio' + ? { ...server, env: { ...server.env, ...managedEnv } } + : server; } return out; } -function withManagedKimiPluginEnvOnEntries( - entries: readonly PluginMcpServerEntry[], - managedEnv: Record<string, string>, -): readonly PluginMcpServerEntry[] { - if (Object.keys(managedEnv).length === 0) return entries; - return entries.map((entry) => - entry.config.transport === 'stdio' - ? { ...entry, config: { ...entry.config, env: { ...entry.config.env, ...managedEnv } } } - : entry, - ); -} - registerScopedService( LifecycleScope.App, IPluginService, diff --git a/packages/agent-core-v2/src/app/plugin/types.ts b/packages/agent-core-v2/src/app/plugin/types.ts index 3a7375fed..ad426972e 100644 --- a/packages/agent-core-v2/src/app/plugin/types.ts +++ b/packages/agent-core-v2/src/app/plugin/types.ts @@ -1,5 +1,4 @@ -import type { IWaitUntil } from '#/_base/event'; -import type { HookDefConfig } from '#/features/externalHooks/configSection'; +import type { HookDefConfig } from '#/agent/externalHooks/configSection'; import type { McpServerConfig } from '#/mcpCore/config-schema'; export type PluginDiagnosticSeverity = 'error' | 'warn' | 'info'; @@ -40,7 +39,6 @@ export interface PluginManifest { readonly homepage?: string; readonly license?: string; readonly skills?: readonly string[]; - readonly rootSkillFallback?: boolean; readonly agents?: readonly string[]; readonly sessionStart?: PluginSessionStart; readonly mcpServers?: Readonly<Record<string, McpServerConfig>>; @@ -72,13 +70,6 @@ export interface PluginMcpServerInfo { readonly headerKeys?: readonly string[]; } -export interface PluginMcpServerEntry { - readonly name: string; - readonly config: McpServerConfig; - readonly pluginId: string; - readonly serverName: string; -} - export interface PluginCommandDef { readonly pluginId: string; readonly name: string; @@ -173,8 +164,6 @@ export interface ReloadSummary { readonly errors: ReadonlyArray<{ readonly id: string; readonly message: string }>; } -export type PluginReloadEvent = ReloadSummary & IWaitUntil; - export interface PluginMutation { readonly kind: 'install' | 'enable' | 'disable' | 'remove' | 'mcp-server'; readonly id: string; diff --git a/packages/agent-core-v2/src/app/projectLocalConfig/projectLocalConfig.ts b/packages/agent-core-v2/src/app/projectLocalConfig/projectLocalConfig.ts index 5a566760d..66ce21d7c 100644 --- a/packages/agent-core-v2/src/app/projectLocalConfig/projectLocalConfig.ts +++ b/packages/agent-core-v2/src/app/projectLocalConfig/projectLocalConfig.ts @@ -1,3 +1,13 @@ +/** + * `projectLocalConfig` domain — project-local config access. + * + * Defines the App-scoped `IProjectLocalConfigService` contract for + * project-local `.kimi-code/local.toml` access. The service works purely by + * path: it discovers the project root (the nearest `.git` ancestor) from a + * working directory and reads/writes the project-local TOML there — it never + * touches the workspace catalog or a `workspaceId`. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface ProjectAdditionalDirsLoadResult { diff --git a/packages/agent-core-v2/src/app/remoteControl/flag.ts b/packages/agent-core-v2/src/app/remoteControl/flag.ts deleted file mode 100644 index 5d999c208..000000000 --- a/packages/agent-core-v2/src/app/remoteControl/flag.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; - -export const REMOTE_CONTROL_FLAG_ID = 'remote-control'; -export const REMOTE_CONTROL_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_REMOTE_CONTROL'; - -export const remoteControlFlag: FlagDefinitionInput = { - id: REMOTE_CONTROL_FLAG_ID, - title: 'Remote Control', - description: - 'Expose the local web UI through Kimi Remote Control (`kimi web --remote-control`, `/remote-control`).', - env: REMOTE_CONTROL_FLAG_ENV, - default: false, - surface: 'both', -}; - -registerFlagDefinition(remoteControlFlag); diff --git a/packages/agent-core-v2/src/app/scopes.ts b/packages/agent-core-v2/src/app/scopes.ts index d5d23c534..3185913aa 100644 --- a/packages/agent-core-v2/src/app/scopes.ts +++ b/packages/agent-core-v2/src/app/scopes.ts @@ -1,13 +1,24 @@ +/** + * `app` domain — the business scope tier set and its topology declaration. + * + * The DI kernel (`_base/di/scope`) only knows the scope tree and opaque + * `ScopeKind` strings; the four tiers and their parent → child order are a + * business concept, declared here as a module side effect so importing the + * package (or this module) installs the topology. + */ + import { setScopeTopology } from '#/_base/di/scope'; export enum LifecycleScope { App = 'app', + Workspace = 'workspace', Session = 'session', Agent = 'agent', } export const SCOPE_TOPOLOGY: readonly LifecycleScope[] = [ LifecycleScope.App, + LifecycleScope.Workspace, LifecycleScope.Session, LifecycleScope.Agent, ]; diff --git a/packages/agent-core-v2/src/app/sessionExport/errors.ts b/packages/agent-core-v2/src/app/sessionExport/errors.ts index 7efc95d07..43d3a9ed8 100644 --- a/packages/agent-core-v2/src/app/sessionExport/errors.ts +++ b/packages/agent-core-v2/src/app/sessionExport/errors.ts @@ -1,3 +1,7 @@ +/** + * `sessionExport` domain error codes — export precondition failures. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const SessionExportErrors = { diff --git a/packages/agent-core-v2/src/app/sessionExport/file-source.ts b/packages/agent-core-v2/src/app/sessionExport/file-source.ts index eaf3c636e..49494d460 100644 --- a/packages/agent-core-v2/src/app/sessionExport/file-source.ts +++ b/packages/agent-core-v2/src/app/sessionExport/file-source.ts @@ -1,3 +1,10 @@ +/** + * `sessionExport` domain — bounded file source ownership. + * + * Opens one stable file handle, snapshots its current size, and exposes an + * idempotent close operation shared by normal completion and failure cleanup. + */ + import { open, type FileHandle } from 'node:fs/promises'; import { Readable } from 'node:stream'; import { finished } from 'node:stream/promises'; diff --git a/packages/agent-core-v2/src/app/sessionExport/manifest.ts b/packages/agent-core-v2/src/app/sessionExport/manifest.ts index 19889912a..52c9f138d 100644 --- a/packages/agent-core-v2/src/app/sessionExport/manifest.ts +++ b/packages/agent-core-v2/src/app/sessionExport/manifest.ts @@ -1,3 +1,11 @@ +/** + * `sessionExport` domain — export manifest builder. + * + * Produces the diagnostic `manifest.json` included in every exported session + * archive. The manifest combines persisted session metadata, host/runtime + * version facts, and wire-log activity timestamps discovered during export. + */ + import { WIRE_PROTOCOL_VERSION } from '#/wire/migration/migration'; import type { diff --git a/packages/agent-core-v2/src/app/sessionExport/sessionExport.ts b/packages/agent-core-v2/src/app/sessionExport/sessionExport.ts index 1f782dca1..4b84bfe1f 100644 --- a/packages/agent-core-v2/src/app/sessionExport/sessionExport.ts +++ b/packages/agent-core-v2/src/app/sessionExport/sessionExport.ts @@ -1,3 +1,12 @@ +/** + * `sessionExport` domain — session diagnostic export contract. + * + * Defines the App-scope `ISessionExportService`, which packages a persisted + * session directory plus optional global diagnostics into a zip archive. The + * service coordinates live Session/Agent scope flushing before reading the + * on-disk state, while the export manifest stays a JSON data contract. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface ShellEnvironment { @@ -49,6 +58,7 @@ export interface ExportSessionResult { export interface ExportSessionOptions { readonly webLog?: string; readonly signal?: AbortSignal; + readonly maxArchiveBytes?: number; } export interface ISessionExportService { diff --git a/packages/agent-core-v2/src/app/sessionExport/sessionExportService.ts b/packages/agent-core-v2/src/app/sessionExport/sessionExportService.ts index ca1ff369b..561d3c558 100644 --- a/packages/agent-core-v2/src/app/sessionExport/sessionExportService.ts +++ b/packages/agent-core-v2/src/app/sessionExport/sessionExportService.ts @@ -1,3 +1,12 @@ +/** + * `sessionExport` domain — `ISessionExportService` implementation. + * + * Coordinates live session flushing through the live workspace handler + * registry, derives session paths from the handler-chain addressing, reads + * persisted summaries through the session index, and packages diagnostic + * files through the local zip writer. Bound at App scope. + */ + import { join, resolve } from 'pathe'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -7,12 +16,13 @@ import { resolveGlobalLogPath } from '#/_base/log/logConfig'; import { IWireService } from '#/wire/wire'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { ISessionIndex, type SessionSummary } from '#/app/sessionIndex/sessionIndex'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; +import { IWorkspaceLifecycleService } from '#/app/workspaceLifecycle/workspaceLifecycle'; import { IWorkspaceService } from '#/app/workspace/workspace'; import { sessionDirOf, workspacePersistenceScope, } from '#/workspace/sessionLifecycle/internal/addressing'; +import { ISessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycle'; import { ErrorCodes, Error2 } from '#/errors'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; @@ -44,7 +54,7 @@ export class SessionExportService implements ISessionExportService { constructor( @IBootstrapService private readonly bootstrap: IBootstrapService, @ISessionIndex private readonly index: ISessionIndex, - @ISessionManager private readonly sessions: ISessionManager, + @IWorkspaceLifecycleService private readonly workspaceLifecycle: IWorkspaceLifecycleService, @IWorkspaceService private readonly workspaces: IWorkspaceService, @ILogService private readonly log: ILogService, ) {} @@ -89,6 +99,7 @@ export class SessionExportService implements ISessionExportService { : undefined, webLog: options.webLog, signal: options.signal, + maxArchiveBytes: options.maxArchiveBytes, }); } @@ -129,10 +140,8 @@ export class SessionExportService implements ISessionExportService { ); const agents = handle.accessor.get(IAgentLifecycleService); for (const agent of agents.list()) { - const agentHandle = agents.handleOf(agent.agentId); - if (agentHandle === undefined) continue; await this.warnIfFails('export agent wire flush failed', () => - agentHandle.accessor.get(IWireService).flush(), + agent.accessor.get(IWireService).flush(), ); } @@ -140,7 +149,11 @@ export class SessionExportService implements ISessionExportService { } private liveSession(sessionId: string): ISessionScopeHandle | undefined { - return this.sessions.get(sessionId); + for (const handler of this.workspaceLifecycle.handlers.list()) { + const handle = handler.accessor.get(ISessionLifecycleService).get(sessionId); + if (handle !== undefined) return handle; + } + return undefined; } private async warnIfFails( @@ -172,6 +185,7 @@ export async function exportSessionDirectory(input: { readonly desktopLogPath?: string | undefined; readonly webLog?: string; readonly signal?: AbortSignal; + readonly maxArchiveBytes?: number; }): Promise<ExportSessionResult> { input.signal?.throwIfAborted(); const sessionDir = input.summary.sessionDir; @@ -251,6 +265,7 @@ export async function exportSessionDirectory(input: { sessionFiles: selectedSessionFiles, extraEntries: extras, signal: input.signal, + maxArchiveBytes: input.maxArchiveBytes, }); sessionLogSourceTransferred = sessionLogSource !== undefined; globalSourceTransferred = globalSource !== undefined; diff --git a/packages/agent-core-v2/src/app/sessionExport/wire-scan.ts b/packages/agent-core-v2/src/app/sessionExport/wire-scan.ts index 11cd45b8b..bb4d48cc2 100644 --- a/packages/agent-core-v2/src/app/sessionExport/wire-scan.ts +++ b/packages/agent-core-v2/src/app/sessionExport/wire-scan.ts @@ -1,3 +1,11 @@ +/** + * `sessionExport` domain — persisted wire activity scanner. + * + * Reads both legacy root `wire.jsonl` logs and v2 per-agent + * `agents/<agentId>/wire.jsonl` logs to derive activity timestamps for the + * export manifest without depending on live Agent services. + */ + import { open, readdir, type FileHandle } from 'node:fs/promises'; import { createInterface } from 'node:readline'; import { Readable } from 'node:stream'; diff --git a/packages/agent-core-v2/src/app/sessionExport/zip.ts b/packages/agent-core-v2/src/app/sessionExport/zip.ts index 19503e43b..7dbc97ae7 100644 --- a/packages/agent-core-v2/src/app/sessionExport/zip.ts +++ b/packages/agent-core-v2/src/app/sessionExport/zip.ts @@ -1,6 +1,14 @@ +/** + * `sessionExport` domain — export zip writer. + * + * Collects the session directory's regular files and writes a diagnostic zip + * archive with a generated manifest plus optional extra entries. This module + * owns the byte packaging detail; callers provide already-resolved paths. + */ + import { createWriteStream } from 'node:fs'; import { mkdir, mkdtemp, readdir, rename, rm, stat } from 'node:fs/promises'; -import { Readable } from 'node:stream'; +import { Readable, Transform } from 'node:stream'; import { pipeline } from 'node:stream/promises'; import { dirname, join, relative, resolve } from 'pathe'; @@ -41,6 +49,7 @@ export async function writeExportZip(args: { readonly sessionFiles: readonly SessionZipEntry[]; readonly extraEntries?: readonly ExtraZipEntry[]; readonly signal?: AbortSignal; + readonly maxArchiveBytes?: number; }): Promise<readonly string[]> { const unusedSources = new Set<ZipSource>([ ...args.sessionFiles.flatMap((entry) => (typeof entry === 'string' ? [] : [entry.source])), @@ -101,7 +110,12 @@ export async function writeExportZip(args: { args.signal?.addEventListener('abort', onAbort, { once: true }); const destination = createWriteStream(tempOutputPath, { flags: 'wx' }); - writing = pipeline(output, destination, { signal: args.signal }); + writing = + args.maxArchiveBytes === undefined + ? pipeline(output, destination, { signal: args.signal }) + : pipeline(output, createArchiveLimit(args.maxArchiveBytes), destination, { + signal: args.signal, + }); const activate = (source: ZipSource): Readable => { unusedSources.delete(source); @@ -249,6 +263,26 @@ function abortReason(signal: AbortSignal): Error { : new DOMException('The operation was aborted.', 'AbortError'); } +function createArchiveLimit(maxArchiveBytes: number): Transform { + let archiveBytes = 0; + return new Transform({ + transform(chunk: Buffer, _encoding, callback) { + archiveBytes += chunk.length; + if (archiveBytes > maxArchiveBytes) { + callback( + new Error2( + ErrorCodes.SESSION_EXPORT_TOO_LARGE, + `Session export exceeds the ${maxArchiveBytes} byte archive limit.`, + { details: { archiveBytes, maxArchiveBytes } }, + ), + ); + return; + } + callback(null, chunk); + }, + }); +} + async function findConflictingSource(args: { readonly outputPath: string; readonly sessionFiles: readonly SessionZipEntry[]; diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndex.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndex.ts index 58a182a8b..10ddf32b6 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndex.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndex.ts @@ -1,3 +1,36 @@ +/** + * `sessionIndex` domain (L2) — session index contract. + * + * `ISessionIndex` is a domain-specific persistence Store: a backend-neutral + * query facade over the set of persisted sessions (open or closed). It serves + * recency-ordered pages, point lookups, and counts (`SessionSummary` data or + * numbers — never filesystem paths or live handles). Writes (create / + * archive) live in `sessionLifecycle` / `session`; the index is a read model. + * Backends are deployment-specific (local filesystem today; database / query + * store on a server). `remove` is the one write: it evicts a deleted + * session's derived/cached state so `get` stops answering for the id — the + * authoritative record (the session directory) is deleted by the caller + * (`sessionLifecycle.delete`). + * + * Listings follow a canonical order — `updatedAt` descending, `id` + * descending as the tie-break — and page with keyset cursors: `before` / + * `after` take a session id and return the page strictly older / newer than + * it; `Page.nextCursor` carries the id to pass as `before` for the next + * older page. An unknown cursor id yields an empty, terminal page. + * + * Lifecycle (flag `persistence_minidb_readmodel`): the read model has an + * explicit `prepare()` — `uninitialized → preparing → ready`, or `degraded` + * when it must fall back to the authoritative store. `prepare()` is called + * once by the composition root; read paths kick it lazily (single-flight) + * when a host never did. `status()` exposes the state machine, the published + * generation, and the cumulative degraded count. + * + * `ISessionIndexMirror` is the write side of the read model: `SessionMetadata` + * records fresh summaries into a bounded, coalescing queue after the + * authoritative document is durable, so user mutations never wait on the + * derived store. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Page } from '#/persistence/interface/queryStore'; @@ -16,18 +49,26 @@ export interface SessionSummary { readonly createdAt: number; readonly updatedAt: number; readonly archived: boolean; - readonly archivedAt?: number; readonly custom?: Record<string, unknown>; readonly lastTurnReason?: 'completed' | 'cancelled' | 'failed'; } export interface SessionListQuery { + /** + * Restrict to sessions persisted under any of these workspace ids. A single + * workspace is `[id]`; callers resolving a legacy split bucket (one + * directory, several id spellings — see `IWorkspaceAliases.resolveAliasIds`) + * pass the whole alias set and get one merged listing. Absent lists every + * bucket. + */ readonly workspaceIds?: readonly string[]; readonly sessionId?: string; readonly includeArchived?: boolean; readonly limit?: number; readonly childOf?: string; + /** Keyset cursor: the page strictly older than this session id. */ readonly before?: string; + /** Keyset cursor: the page strictly newer than this session id. */ readonly after?: string; } @@ -40,19 +81,35 @@ export type SessionIndexState = 'uninitialized' | 'preparing' | 'ready' | 'degra export interface SessionIndexStatus { readonly state: SessionIndexState; + /** Published read-model generation; absent until the first projection. */ readonly generation?: number; + /** Why the index last entered `degraded` (authoritative fallback). */ readonly reason?: string; + /** How many times the index entered `degraded` in this process. */ readonly degradedCount: number; } export interface ISessionIndex { readonly _serviceBrand: undefined; + /** + * Open the read model and make it servable: open the query store, create + * the schema, restore the published generation (running the initial + * projection when none exists), and start background reconciliation. + * Single-flight; a no-op when the read-model flag is off. + */ prepare(options?: { deadlineMs?: number }): Promise<SessionIndexStatus>; status(): SessionIndexStatus; get(id: string): Promise<SessionSummary | undefined>; + /** Recency-ordered keyset page over the persisted session set. */ listRecent(query: SessionListQuery): Promise<Page<SessionSummary>>; + /** Materialized count over the given workspace-id set. */ count(query: SessionCountQuery): Promise<number>; + /** + * The one write: evict a deleted session's derived/cached state so `get` + * stops answering for the id — the authoritative record (the session + * directory) is deleted by the caller (`sessionLifecycle.delete`). + */ remove(id: string): Promise<void>; } @@ -62,9 +119,22 @@ export const ISessionIndex: ServiceIdentifier<ISessionIndex> = export interface ISessionIndexMirror { readonly _serviceBrand: undefined; + /** + * Enqueue the latest summary of a session for mirroring into the read + * model. Synchronous, bounded, and coalescing (only the newest summary per + * session is kept); never throws — failures stay dirty and are healed by + * reconciliation. + */ record(summary: SessionSummary): void; + /** Summaries accepted but not yet flushed (read-your-writes window). */ pending(): readonly SessionSummary[]; + /** + * Forget a session on the delete path: drop any queued summary and wait + * out an in-flight flush that may still carry it, so the caller's + * follow-up query-store delete is not resurrected by the mirror. + */ evict(id: string): Promise<void>; + /** Flush everything currently queued; resolves with the queue empty. */ drain(): Promise<void>; } diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexMirrorService.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexMirrorService.ts index 8bfe60daf..0070d6d05 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexMirrorService.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexMirrorService.ts @@ -1,3 +1,31 @@ +/** + * `sessionIndex` domain (L2) — `ISessionIndexMirror` implementation. + * + * The write side of the session read model. `SessionMetadata` (Session scope) + * records the freshest `SessionSummary` here once the authoritative + * `state.json` is durable; this App-scoped queue then mirrors it into the + * `IQueryStore` read model *off the user completion path*. Updates coalesce + * per session (only the newest summary is kept) and flush in chunks — on a + * short timer or as soon as a batch fills — writing summaries (with the + * recency column declared) and per-workspace counter deltas into the + * currently published generation. `evict()` forgets a deleted session (the + * `ISessionIndex.remove` path): reads fold the queue in for + * read-your-writes, so a queued creation must be dropped — and an in-flight + * flush waited out — before the store delete, or the entry is resurrected. + * + * Everything here is best-effort: a flush failure keeps the entries queued, + * backs off, and after repeated failures gives up until the next `record` — + * the failed entries stay dirty and the domain's reconciliation heals them + * from the authoritative documents. A queue overflow drops incoming summaries + * (logged) rather than growing memory without bound. `drain()` is the + * explicit shutdown path — the composition root awaits it before the query + * store closes; DI disposal additionally fires a best-effort drain into a + * module-level set so hosts without explicit wiring can await it via + * `drainSessionIndexMirror()`. + * + * Bound at App scope. + */ + import { Disposable, toDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -23,6 +51,12 @@ const FLUSH_BATCH_SIZE = 500; const MAX_PENDING = 10_000; const MAX_CONSECUTIVE_FAILURES = 5; +/** + * Best-effort drains fired by DI disposal (which is synchronous). The server + * shutdown path awaits the service's own `drain()` explicitly before the + * query store closes; this set is the backstop for hosts that only tear the + * scope down. + */ const pendingDrains = new Set<Promise<void>>(); export async function drainSessionIndexMirror(): Promise<void> { @@ -81,6 +115,8 @@ export class SessionIndexMirror extends Disposable implements ISessionIndexMirro async evict(id: string): Promise<void> { this.pendingMap.delete(id); + // A flush that already snapshotted this id may still be writing it; + // wait it out so the caller's store delete lands after that batch. await this.flushing; this.pendingMap.delete(id); } @@ -91,6 +127,7 @@ export class SessionIndexMirror extends Disposable implements ISessionIndexMirro const before = this.pendingMap.size; await this.flush(); if (this.pendingMap.size >= before) { + // No progress — the store is down; the next reconciliation heals. this.log.warn('session index mirror drain made no progress; leaving the rest dirty', { pending: this.pendingMap.size, }); @@ -115,6 +152,8 @@ export class SessionIndexMirror extends Disposable implements ISessionIndexMirro try { const manifest = await this.queryStore.getCheckpoint(SESSION_INDEX_MANIFEST); if (manifest === undefined) { + // No published generation yet — the running projection reads the + // authoritative documents and covers these sessions; retry shortly. this.consecutiveFailures += 1; return; } diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexModel.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexModel.ts index 6d0509927..c3c21a4e1 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexModel.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexModel.ts @@ -1,3 +1,20 @@ +/** + * `sessionIndex` domain (L2) — read-model layout shared by the index, the + * mirror, and the projector. + * + * The derived read model is versioned by *generation*: every projection + * writes a fresh `session:g<N>` collection (summaries, keyed by session id, + * with the generation's recency column declared) plus a + * `sessionCounters:g<N>` collection (per-workspace materialized + * active/archived counts), then publishes `N` with one atomic checkpoint + * write. Readers only ever read the published generation, so a projection + * that dies midway leaves the previous generation fully intact; orphaned + * halves of crashed generations are dropped before reuse and the previous + * generation is dropped after a successful publish. The collections are + * plain `IQueryStore` collections — no backend-specific type escapes into + * the domain. + */ + import type { SessionSummary } from './sessionIndex'; export const SESSION_INDEX_MANIFEST = 'sessionIndex'; @@ -17,14 +34,25 @@ export function sessionCountersCollection(generation: number): string { return `sessionCounters:g${generation}`; } +/** + * The ordered recency column for a generation. Column names are store-wide, + * so the column is namespaced per generation: two coexisting generations + * (one published, one being projected) then walk disjoint ordered + * structures and can never interleave into each other's pages. The stored + * record carries the same-named field — the engine orders by the column and + * its cross-shard merge compares by the value field of that name — and the + * index strips it again on every read. + */ export function recencyColumn(generation: number): string { return `g${generation}:updatedAt`; } +/** Attach the generation's recency field to a summary for storage. */ export function withRecencyField(generation: number, summary: SessionSummary): SessionSummary { return { ...summary, [recencyColumn(generation)]: summary.updatedAt }; } +/** Remove the generation's recency field from a stored record. */ export function stripRecencyField(generation: number, record: SessionSummary): SessionSummary { const key = recencyColumn(generation); if (!(key in record)) return record; diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexProjector.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexProjector.ts index fc50863f2..385b962e8 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexProjector.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexProjector.ts @@ -1,3 +1,40 @@ +/** + * `sessionIndex` domain (L2) — projector and reconciliation for the read + * model. + * + * The projector materializes the authoritative session metadata + * (`state.json` documents) into a fresh read-model generation: a full scan + * with bounded concurrency, chunked `batch` writes (no cross-shard atomicity + * required), per-workspace counters recomputed exactly, and finally one + * atomic checkpoint publish that makes the generation readable. A projector + * that dies midway never publishes, so readers keep serving the previous + * generation; the next run clears its own stragglers before writing. + * Publishing also schedules the previous generation's drop. + * + * The initial projection coincides with the first list request (read paths + * kick `prepare()` single-flight and fall back to the authoritative scan + * while unprepared). `sharedScan()` makes that ONE scan serve both: the + * projection joins a running scan — or reuses one that just settled within + * a short window — instead of enumerating every session directory a second + * time. Fallback reads use `sharedScanForRead()`: they join only a scan + * that is still in flight and otherwise drive a fresh one, so a read never + * serves a settled snapshot that could predate a just-created session. (A + * joined scan may still have started before the read; the index folds the + * mirror's pending queue into the result to cover that window.) A + * projection run consumes the slot on settle, so a later re-projection + * always scans fresh. + * + * Reconciliation runs against the *published* generation: it re-scans the + * authoritative set (always fresh — a stale snapshot could regress counters + * the mirror just updated), upserts summaries that drifted (mirror loss, + * external edits), deletes entries whose document disappeared, and rewrites + * every counter from the authoritative scan — bounding counter drift to one + * reconcile interval. + * + * This is an internal collaborator of `FileSessionIndex`, not a DI service: + * the index drives it single-flight and owns the state machine around it. + */ + import { ILogService } from '#/_base/log/log'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; import { IQueryStore, type WriteOp } from '#/persistence/interface/queryStore'; @@ -23,6 +60,14 @@ import { const WRITE_CHUNK = 500; const SCAN_CONCURRENCY = 16; +/** + * How long a settled shared scan stays reusable BY A PROJECTION. The window + * only needs to cover the gap between a fallback read finishing its scan and + * the kicked projection reaching its own scan call (query-store open + + * collection housekeeping in between); a projection never reuses a slot + * older than this. Fallback reads never reuse a settled scan at all (see + * `sharedScanForRead`). + */ const SHARED_SCAN_REUSE_MS = 30_000; export interface SessionIndexProjectorDeps { @@ -44,6 +89,7 @@ export interface ReconcileResult { readonly removed: number; } +/** One consistent pass over the authoritative session metadata set. */ export interface AuthoritativeScan { readonly summaries: SessionSummary[]; readonly counts: Map<string, { active: number; archived: number }>; @@ -60,6 +106,14 @@ export class SessionIndexProjector { constructor(private readonly deps: SessionIndexProjectorDeps) {} + /** + * The projection's scan: joins a running shared scan, reuses one that + * settled within the reuse window, or starts a fresh one. The projection + * publishes a point-in-time derived model by design, so a just-finished + * snapshot is safe for it (the mirror queue and reconciliation heal the + * gap) — and this is what keeps a fast first read + kicked projection + * from scanning the directory tree twice. + */ sharedScan(): Promise<AuthoritativeScan> { const slot = this.scanSlot; if (slot !== undefined && (!slot.settled || Date.now() < slot.reusableUntil)) { @@ -68,6 +122,15 @@ export class SessionIndexProjector { return this.startScan(); } + /** + * A fallback read's scan: joins a scan that is still in flight or starts a + * fresh one. A settled snapshot is NEVER served to a read — it could + * predate a session this process just created, breaking read-your-writes. + * Joining an in-flight scan is NOT the same freshness as enumerating here + * and now: the scan may have started (and passed a directory) before this + * call, so the caller folds the mirror's pending queue into the result — + * every pending entry is known to be durable on disk. + */ sharedScanForRead(): Promise<AuthoritativeScan> { const slot = this.scanSlot; if (slot !== undefined && !slot.settled) return slot.promise; @@ -88,11 +151,17 @@ export class SessionIndexProjector { return slot.promise; } + /** Scan the authoritative set into a fresh generation and publish it. */ async project(generation: number): Promise<ProjectionResult> { + // Captured BEFORE the housekeeping below: the scan overlaps it, and the + // finally invalidates exactly the slot this run consumed — never a newer + // scan a concurrent fallback read started meanwhile. const scan = this.sharedScan(); try { return await this.doProject(generation, scan); } finally { + // The consumed slot must not serve a LATER projection: a re-projection + // always scans the authoritative set fresh. if (this.scanSlot?.promise === scan) this.scanSlot = undefined; } } @@ -104,6 +173,7 @@ export class SessionIndexProjector { const { queryStore, log } = this.deps; const collection = sessionCollection(generation); const counters = sessionCountersCollection(generation); + // Clear stragglers of a crashed earlier attempt at this generation. await queryStore.dropCollection(collection); await queryStore.dropCollection(counters); await queryStore.ensureIndex(collection, { @@ -145,6 +215,7 @@ export class SessionIndexProjector { return { generation, sessions: summaries.length }; } + /** Re-scan the authoritative set and repair the published generation. */ async reconcile(generation: number): Promise<ReconcileResult> { const { queryStore, log } = this.deps; const collection = sessionCollection(generation); @@ -215,6 +286,7 @@ export class SessionIndexProjector { key: workspaceId, value: { active: value.active, archived: value.archived } satisfies SessionWorkspaceCounts, })); + // Workspaces that vanished entirely lose their counter document. const existing = await queryStore.listKeys(counters); for (const key of existing) { if (!counts.has(key)) ops.push({ kind: 'delete', collection: counters, key }); diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexService.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexService.ts index e29823349..012e997db 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexService.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexService.ts @@ -1,3 +1,54 @@ +/** + * `sessionIndex` domain (L2) — `FileSessionIndex` implementation. + * + * Serves session listings, point lookups, and counts. Two read paths exist: + * + * - **Authoritative (legacy) path** — enumerates the directory tree and reads + * every `state.json` (see `sessionIndexSource`). Always correct, linear in + * the number of sessions. This is the flag-off behavior and the fallback + * whenever the read model cannot serve. + * - **Read-model path** (flag `persistence_minidb_readmodel`) — queries the + * derived `IQueryStore` read model. Recency pages walk the published + * generation's ordered recency column with keyset cursors (`O(log N + + * limit)`, no directory enumeration, no per-session document reads), point + * lookups are single gets, and counts read materialized per-workspace + * counters. + * + * The read model follows the lifecycle `uninitialized → preparing → ready`, + * with `degraded` whenever it cannot serve and the authoritative path takes + * over (the reason and the cumulative count are published via `status()` and + * logged — never a silent permanent fallback). `prepare()` opens the store, + * restores the published generation, runs the initial projection when none + * exists, and starts background reconciliation; read paths kick it + * single-flight when the composition root never called it. A lost manifest + * (query-store corruption rebuild) triggers an automatic reprojection — the + * model is never healed by per-request backfill. Degraded reads retry + * `prepare()` after a short backoff. + * + * The first list request coincides with the initial projection: the read is + * served by the authoritative fallback AND kicks `prepare()`. To keep that + * request from paying two full directory scans, the uninitialized/preparing + * fallback joins the projector's in-flight shared scan — or drives the one + * the projection will reuse (`SessionIndexProjector.sharedScanForRead`) — so + * one authoritative pass serves both, and the mirror's pending queue is + * folded into the result so a session created or mutated after the scan + * passed its directory still shows up. Flag-off hosts and the `degraded` + * fallback keep the targeted per-workspace enumeration (with the same + * pending fold). + * + * Keyset pagination is canonical (`updatedAt` desc, `id` desc): a cursor is a + * session id resolved by point lookup, and the window's boundary tie group is + * re-fetched and merged so same-millisecond ties never lose or duplicate an + * item across pages. `get` falls back to the authoritative document on a + * read-model miss (mirror lag) and re-records it, and every page folds in the + * mirror's not-yet-flushed summaries (range-filtered by the cursor on cursor + * pages) — reads always see recent writes of this process. + * + * This is the local-deployment backend of `ISessionIndex`; a server + * deployment would substitute a database-backed implementation. Bound at App + * scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -99,12 +150,16 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { }); } + /** The reconcile loop runs only while the read model is in play — starting + * it unconditionally would spin an interval for every flag-off host. */ private ensureReconcileTimer(): void { if (!this.reconcileTimer.isSet()) { this.reconcileTimer.cancelAndSet(() => void this.tick(), RECONCILE_INTERVAL_MS); } } + // ---- lifecycle ------------------------------------------------------------ + async prepare(options?: { deadlineMs?: number }): Promise<SessionIndexStatus> { if (!this.readModelEnabled()) return this.status(); this.prepareFlight ??= this.doPrepare(options?.deadlineMs).finally(() => { @@ -169,6 +224,9 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { this.generation = result.generation; this.markReady(); } catch (error) { + // A failed projection never publishes. When a previous generation is + // still published, readers keep flowing from it — a crashed re-projection + // must not take the read model down. const published = await this.queryStore .getCheckpoint(SESSION_INDEX_MANIFEST) .catch(() => undefined); @@ -185,6 +243,7 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { } } + /** Test/ops hook: reconcile the published generation against disk now. */ async reconcileNow(): Promise<void> { if (!this.readModelEnabled()) return; const manifest = await this.queryStore.getCheckpoint(SESSION_INDEX_MANIFEST); @@ -193,11 +252,14 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { await this.projector.reconcile(manifest.seq); } + /** Test/ops hook: project a fresh generation now (single-flight). */ async reprojectNow(): Promise<void> { if (!this.readModelEnabled()) return; await this.ensureProjection(); } + /** Test hook: stop the background reconcile loop, so measurement windows + * contain only the operations under test. */ stopReconcileLoop(): void { this.reconcileTimer.cancel(); } @@ -219,6 +281,7 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { this.generation = manifest.seq; await this.projector.reconcile(manifest.seq); } catch (error) { + // A failed reconcile leaves reads intact; it retries on the next tick. this.log.warn('session index reconciliation failed', { error: String(error) }); } } @@ -252,6 +315,8 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { }); } + // ---- reads ------------------------------------------------------------------ + async get(id: string): Promise<SessionSummary | undefined> { return this.withReadModel( (generation) => this.getFromReadModel(generation, id), @@ -273,6 +338,16 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { ); } + /** + * Evict a deleted session's derived state so `get` / `listRecent` stop + * answering for the id immediately: the authoritative directory is deleted + * by the caller (`sessionLifecycle.delete`), and the next projection would + * drop the entry anyway — this closes the stale-read window in between. The + * mirror queue is evicted first (waiting out an in-flight flush): reads + * fold the queue in for read-your-writes, and a late flush would otherwise + * resurrect the entry after the store delete. With the read model off + * there is no derived state to evict beyond the queue. + */ async remove(id: string): Promise<void> { await this.mirror.evict(id); await this.withReadModel( @@ -283,6 +358,12 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { ); } + /** + * Serve `op` from the read model when possible, else from the authoritative + * path: flag off, not prepared yet (kicked here single-flight), preparing, + * or degraded (with a throttled re-prepare). Any read-model failure demotes + * to `degraded` — logged and counted — and falls back immediately. + */ private async withReadModel<T>( op: (generation: number) => Promise<T>, legacy: () => Promise<T>, @@ -305,6 +386,8 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return legacy(); } if (manifest === undefined) { + // The store lost the published generation (corruption rebuild): + // reproject automatically instead of healing by per-request backfill. this.markDegraded('published generation lost'); void this.prepare(); return legacy(); @@ -322,10 +405,10 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { generation: number, id: string, ): Promise<SessionSummary | undefined> { - const queued = this.mirror.pending().find((summary) => summary.id === id); - if (queued !== undefined) return queued; const cached: unknown = await this.queryStore.get(sessionCollection(generation), id); if (isSessionSummaryShape(cached)) return stripRecencyField(generation, cached); + // Mirror lag or a not-yet-projected session: probe the authoritative + // document and re-record it so the next read is warm. const summary = await this.getLegacy(id); if (summary !== undefined) this.mirror.record(summary); return summary; @@ -357,6 +440,9 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { query.childOf !== undefined ? await this.windowedPage( (bounds, fetchLimit) => { + // The equality candidates (few children per parent) drive this + // path; only bound the column when the cursor actually constrains + // it — an unbounded column range would materialize per shard. const base = this.queryStore .query<SessionSummary>(collection) .where(filter) @@ -398,6 +484,9 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { for (const entry of counts.values()) { total += query.includeArchived === true ? entry.active + entry.archived : entry.active; } + // Fold in the mirror queue (read-your-writes): queued creations count + // immediately, queued archive flips re-bucket, and queued updates to an + // already-counted session are a no-op. const pending = this.mirror .pending() .filter((summary) => restricted === undefined || restricted.includes(summary.workspaceId)); @@ -415,6 +504,14 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return total; } + /** + * Canonical keyset window: fetch `limit + 1` rows under `bounds`; when the + * window is full, re-fetch the boundary tie group (`updatedAt` equal to the + * window's minimum) and merge, so a page cut inside a same-millisecond tie + * group never drops or duplicates an item across pages. Rows are re-sorted + * into the canonical (`updatedAt` desc, `id` desc) order — the engine's + * cross-shard tie order is deterministic but not canonical. + */ private async windowedPage( fetch: (bounds: ColumnBounds, limit: number) => Promise<SessionSummary[]>, bounds: ColumnBounds, @@ -435,6 +532,12 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return { items: kept, nextCursor: hasMore ? kept.at(-1)!.id : undefined }; } + /** + * Read-your-writes merge: pages fold in the mirror's queued summaries so a + * just-mutated session shows up before the flush lands. Cursor pages merge + * only the queued summaries that fall inside the page's canonical range + * (the queue is a tiny, transient window). + */ private mergePending( page: Page<SessionSummary>, query: SessionListQuery, @@ -467,6 +570,13 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return { items: kept, nextCursor: hasMore ? kept.at(-1)!.id : undefined }; } + /** + * Resolve a keyset cursor id to its column bounds plus the exact + * tie-exclusion filter, in canonical order: strictly older (`before`) is + * `(updatedAt, id)` lexicographically below the cursor, strictly newer + * (`after`) is above. An unknown cursor id yields `undefined` — the caller + * answers an empty, terminal page. + */ private async resolveCursor( generation: number, query: SessionListQuery, @@ -476,6 +586,8 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { > { const id = query.before ?? query.after; if (id === undefined) return { filter: {}, bounds: {} }; + // The mirror queue is consulted too: a cursor pointing at a session whose + // latest mutation has not been flushed yet must still resolve. const storedValue: unknown = await this.queryStore.get(sessionCollection(generation), id); const stored = isSessionSummaryShape(storedValue) ? storedValue : undefined; const cursor = stored ?? this.mirror.pending().find((summary) => summary.id === id); @@ -521,6 +633,8 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return filter; } + // ---- authoritative (legacy) path -------------------------------------------- + private get sessionsScope(): string { return this.bootstrap.scope('sessions'); } @@ -578,6 +692,20 @@ export class FileSessionIndex extends Disposable implements ISessionIndex { return count; } + /** + * Collect the authoritative summaries behind a legacy read. While the read + * model is enabled but not yet ready, the kicked initial projection is + * scanning the same authoritative set, so the read joins that in-flight + * scan (or drives the one the projection will reuse) instead of running a + * second full directory scan. Flag-off hosts and the degraded fallback + * keep the targeted per-workspace enumeration. + * + * Either way the mirror's pending queue is folded in by id (pending + * entries win): every queued summary was recorded only after its + * `state.json` is durable, and a scan/enumeration that started before the + * write may legitimately have passed the directory already — the fold is + * what keeps read-your-writes on this path too. + */ private async collectAuthoritative( workspaceIds: readonly string[] | undefined, ): Promise<SessionSummary[]> { diff --git a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexSource.ts b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexSource.ts index 698265881..9bd1d4f6f 100644 --- a/packages/agent-core-v2/src/app/sessionIndex/sessionIndexSource.ts +++ b/packages/agent-core-v2/src/app/sessionIndex/sessionIndexSource.ts @@ -1,3 +1,25 @@ +/** + * `sessionIndex` domain (L2) — authoritative session-metadata scanning. + * + * Reads the persisted session set through the `storage` access-pattern + * stores, rooted at the `sessionsDir` path layout fact from `bootstrap`. The + * directory tree `<sessionsDir>/<workspaceId>/<sessionId>/` is the + * authoritative index: workspace and session ids are enumerated via + * `IFileSystemStorageService.list`, and each session's metadata document is + * read via `IAtomicDocumentStore` to build its summary. + * + * The session metadata document lives at `<sessionDir>/state.json`, a layout + * shared by v1 and v2; the `version` field distinguishes them (`2` = v2, + * epoch-ms timestamps; absent = v1, ISO-string timestamps). The reader also + * falls back to the legacy `<sessionDir>/session-meta/state.json` path for v2 + * sessions written before the layouts were unified. Both timestamp + * representations are normalized to epoch ms. + * + * These helpers serve the index's authoritative fallback (legacy path), the + * projector's full scans, and reconciliation — pure functions over injected + * stores, owning no state themselves. + */ + import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; @@ -32,6 +54,9 @@ export function recoverCwd(meta: Record<string, unknown>): string | undefined { return undefined; } +/** The single construction path for summaries — field order is fixed so a + * stored summary deep-compares equal to a fresh projection of the same + * metadata document. */ export function buildSessionSummary(fields: { id: string; workspaceId: string; @@ -41,7 +66,6 @@ export function buildSessionSummary(fields: { createdAt: number; updatedAt: number; archived: boolean; - archivedAt?: number; custom?: Record<string, unknown>; lastTurnReason?: 'completed' | 'cancelled' | 'failed'; }): SessionSummary { @@ -54,7 +78,6 @@ export function buildSessionSummary(fields: { createdAt: fields.createdAt, updatedAt: fields.updatedAt, archived: fields.archived, - archivedAt: fields.archivedAt, custom: fields.custom, lastTurnReason: fields.lastTurnReason, }; @@ -72,6 +95,9 @@ export function summaryMatchesChildOf( ); } +/** Deep-enough equality for reconciliation: the projection-relevant fields, + * with `custom` compared structurally (both sides are JSON-round-tripped + * values built by `buildSessionSummary`, so key order is stable). */ export function summaryEquals(a: SessionSummary, b: SessionSummary): boolean { return ( a.id === b.id && @@ -82,7 +108,6 @@ export function summaryEquals(a: SessionSummary, b: SessionSummary): boolean { a.createdAt === b.createdAt && a.updatedAt === b.updatedAt && a.archived === b.archived && - a.archivedAt === b.archivedAt && a.lastTurnReason === b.lastTurnReason && JSON.stringify(a.custom) === JSON.stringify(b.custom) ); @@ -134,7 +159,6 @@ export async function readSessionSummary( createdAt: parseTime(meta['createdAt']), updatedAt: parseTime(meta['updatedAt']), archived: meta['archived'] === true, - archivedAt: meta['archivedAt'] === undefined ? undefined : parseTime(meta['archivedAt']), custom, lastTurnReason: parseTurnOutcome(meta['lastTurnReason']), }); @@ -151,6 +175,8 @@ async function readMeta( } } +/** Bounded-concurrency map: resolves every item through `fn`, dropping + * `undefined` results, with at most `concurrency` calls in flight. */ export async function mapBounded<T, R>( items: readonly T[], concurrency: number, diff --git a/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacy.ts b/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacy.ts index 71b34ae53..1a6cffccd 100644 --- a/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacy.ts +++ b/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacy.ts @@ -1,8 +1,23 @@ -import type { GoalSnapshot } from '#/features/goal/types'; +/** + * `sessionLegacy` domain (L7 edge adapter) — v1-compatible session actions. + * + * Implements `POST /sessions/{id}/profile` (`updateProfile` — title rename, + * metadata merge, and the cross-domain `agent_config` patch), + * `GET /sessions/{id}/status` (`status`), and `GET /sessions/{id}/goal` + * (`goal`). The thin pass-through actions (`fork` / `compact` / `abort` / + * `archive`), the `:undo` action, and the `/sessions/{id}/children` endpoints + * are deliberately NOT wrapped here because none of them carries v1-only + * projection worth centralizing; only `updateProfile`, `status`, and `goal` + * stay in this adapter (the `agent_config` patch, the best-effort status + * rollup, and the current-goal read). Bound at App scope — it is a stateless + * dispatcher that resolves the target session/agent per call. + */ + +import type { GoalSnapshot } from '#/agent/goal/types'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { SessionStatusResponse } from './sessionProtocol'; +import type { SessionStatusResponse, UpdateSessionProfileRequest } from './sessionProtocol'; export interface SessionWireFields { readonly id: string; @@ -13,13 +28,13 @@ export interface SessionWireFields { readonly createdAt: number; readonly updatedAt: number; readonly archived: boolean; - readonly archivedAt?: number; readonly custom?: Record<string, unknown>; } export interface ISessionLegacyService { readonly _serviceBrand: undefined; + updateProfile(sessionId: string, body: UpdateSessionProfileRequest): Promise<SessionWireFields>; status(sessionId: string): Promise<SessionStatusResponse>; goal(sessionId: string): Promise<GoalSnapshot | null>; } diff --git a/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacyService.ts b/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacyService.ts index 664449e08..1ec77c346 100644 --- a/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacyService.ts +++ b/packages/agent-core-v2/src/app/sessionLegacy/sessionLegacyService.ts @@ -1,6 +1,16 @@ -import type { GoalSnapshot } from '#/features/goal/types'; +/** + * `sessionLegacy` domain — `ISessionLegacyService` implementation. + * + * Stateless App-scope dispatcher: each method resolves the target session (and + * its main agent) per call, delegates to the native v2 services, and projects + * the result into the v1 wire shape. Only `updateProfile` (the cross-domain + * `agent_config` patch), `status` (the best-effort status rollup), and `goal` + * (the current-goal read) live here. No business logic is duplicated here. + */ -import type { SessionStatusResponse } from './sessionProtocol'; +import type { GoalSnapshot } from '#/agent/goal/types'; + +import type { SessionStatusResponse, UpdateSessionProfileRequest } from './sessionProtocol'; import { LifecycleScope } from '#/app/scopes'; import { type IAgentScopeHandle, @@ -12,26 +22,27 @@ import { IInstantiationService, type ServicesAccessor, } from '#/_base/di/instantiation'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; -import { AgentGoal } from '#/features/goal/goalAgentRuntime'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; +import { IAgentGoalService } from '#/agent/goal/goal'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; +import type { PermissionMode } from '#/agent/permissionPolicy/types'; import { IAgentPlanService } from '#/features/plan/plan'; import { IAgentProfileService } from '#/agent/profile/profile'; -import { IAgentSwarmService } from '#/features/swarm/agent/swarm'; -import { IAgentTowerService } from '#/features/tower/tower'; -import { agentContextOf } from '#/agent/scopeContext/scopeContext'; +import { IAgentSwarmService } from '#/agent/swarm/swarm'; import { getLiveSessionById, resumeSessionById, -} from '#/app/sessionManager/sessionLookup'; +} from '#/app/workspaceLifecycle/sessionLookup'; import { IModelCatalog } from '#/kosong/model/catalog'; import { IModelService } from '#/kosong/model/model'; import { ErrorCodes, Error2 } from '#/errors'; import { ensureMainAgent } from '#/session/agentLifecycle/mainAgent'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { IAgentActivityView } from '#/agent/activityView/activityView'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; +import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { ISessionLegacyService } from './sessionLegacy'; +import { ISessionLegacyService, type SessionWireFields } from './sessionLegacy'; export class SessionLegacyService implements ISessionLegacyService { declare readonly _serviceBrand: undefined; @@ -48,17 +59,105 @@ export class SessionLegacyService implements ISessionLegacyService { return resumeSessionById(this.services, sessionId); } + async updateProfile( + sessionId: string, + body: UpdateSessionProfileRequest, + ): Promise<SessionWireFields> { + const session = await this.resume(sessionId); + if (session === undefined) { + throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`); + } + const metadata = session.accessor.get(ISessionMetadata); + + if (typeof body.title === 'string') { + await metadata.setTitle(body.title); + } + + const metadataPatch = body.metadata; + if (metadataPatch !== undefined && Object.keys(metadataPatch).length > 0) { + await metadata.update({ custom: { ...(metadataPatch as Record<string, unknown>) } }); + } + + const agentConfig = body.agent_config; + if (agentConfig !== undefined) { + const agent = await this.resolveMainAgent(sessionId); + await this.applyAgentConfig(agent, agentConfig); + } + + const meta = await metadata.read(); + const ctx = session.accessor.get(ISessionContext); + return { + id: meta.id, + workspaceId: ctx.workspaceId, + root: ctx.cwd, + title: meta.title, + lastPrompt: meta.lastPrompt, + createdAt: meta.createdAt, + updatedAt: meta.updatedAt, + archived: meta.archived, + custom: meta.custom, + }; + } + + + private async applyAgentConfig( + agent: IAgentScopeHandle, + agentConfig: NonNullable<UpdateSessionProfileRequest['agent_config']>, + ): Promise<void> { + const profile = agent.accessor.get(IAgentProfileService); + if (agentConfig.model !== undefined && agentConfig.model !== '') { + await profile.setModel(agentConfig.model); + } + if (agentConfig.thinking !== undefined) { + profile.setThinking(agentConfig.thinking); + } + if (agentConfig.permission_mode !== undefined) { + agent.accessor + .get(IAgentLifecycleService) + .broadcastPermissionMode(agentConfig.permission_mode as PermissionMode); + } + if (agentConfig.plan_mode !== undefined) { + const plan = agent.accessor.get(IAgentPlanService); + const active = (await plan.status()) !== null; + if (active !== agentConfig.plan_mode) { + if (agentConfig.plan_mode) await plan.enter(); + else plan.exit(); + } + } + if (agentConfig.swarm_mode !== undefined) { + const swarm = agent.accessor.get(IAgentSwarmService); + if (swarm.isActive !== agentConfig.swarm_mode) { + if (agentConfig.swarm_mode) swarm.enter('manual'); + else swarm.exit(); + } + } + if (agentConfig.goal_objective !== undefined) { + await agent.accessor + .get(IAgentGoalService) + .createGoal({ objective: agentConfig.goal_objective }); + } + if (agentConfig.goal_control !== undefined) { + const goal = agent.accessor.get(IAgentGoalService); + switch (agentConfig.goal_control) { + case 'pause': + await goal.pauseGoal({}); + break; + case 'resume': + await goal.resumeGoal({ continueIfPaused: true, continueIfBlocked: true }); + break; + case 'cancel': + await goal.cancelGoal({}); + break; + } + } + } + private async resolveMainAgent(sessionId: string): Promise<IAgentScopeHandle> { const session = await this.resume(sessionId); if (session === undefined) { throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`); } - const context = await ensureMainAgent(session); - const handle = session.accessor.get(IAgentLifecycleService).handleOf(context.agentId); - if (handle === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found'); - } - return handle; + return ensureMainAgent(session); } async status(sessionId: string): Promise<SessionStatusResponse> { @@ -71,19 +170,23 @@ export class SessionLegacyService implements ISessionLegacyService { agent: IAgentScopeHandle, ): Promise<SessionStatusResponse> { const profile = agent.accessor.get(IAgentProfileService); - const tokenCounting = agent.accessor.get(ISessionTokenCountingService); + const tokenCounting = agent.accessor.get(IAgentTokenCountingService); const permission = agent.accessor.get(IAgentPermissionModeService); const plan = agent.accessor.get(IAgentPlanService); const swarm = agent.accessor.get(IAgentSwarmService); - const tower = agent.accessor.get(IAgentTowerService); const model = profile.getModel(); const capabilities = profile.getModelCapabilities(); + // An alias that no longer resolves yields UNKNOWN_CAPABILITY whose + // max_context_tokens is 0 — the "unknown" marker, not a real limit. Only + // an unbound session falls back to the default model's limit; when the + // limit stays unknown the field is omitted (never 0), mirroring the WS + // status push (`readLegacyStatus`). let maxTokens = capabilities.max_input_tokens ?? capabilities.max_context_tokens; if (maxTokens === 0 && model === '') { maxTokens = resolveDefaultModelContextTokens(agent) ?? 0; } - const tokens = tokenCounting.statusSize(agentContextOf(agent)); + const tokens = tokenCounting.statusSize(); const planData = await plan.status(); return { @@ -93,21 +196,17 @@ export class SessionLegacyService implements ISessionLegacyService { permission: permission.mode, plan_mode: planData !== null, swarm_mode: swarm.isActive, - tower_mode: tower.isActive, context_tokens: tokens, max_context_tokens: maxTokens > 0 ? maxTokens : undefined, - context_usage: maxTokens > 0 ? Math.min(1, tokens / maxTokens) : undefined, + context_usage: maxTokens > 0 ? Math.min(1, tokens / maxTokens) : 0, }; } private readBusy(sessionId: string): boolean { const handle = getLiveSessionById(this.services, sessionId); if (handle === undefined) return false; - const agents = handle.accessor.get(IAgentLifecycleService); - for (const agent of agents.list()) { - const agentHandle = agents.handleOf(agent.agentId); - if (agentHandle === undefined) continue; - const state = agentHandle.accessor.get(IAgentActivityView).state(); + for (const agent of handle.accessor.get(IAgentLifecycleService).list()) { + const state = agent.accessor.get(IAgentActivityView).state(); if (state.turn !== undefined || state.background.length > 0) return true; } return false; @@ -115,13 +214,14 @@ export class SessionLegacyService implements ISessionLegacyService { async goal(sessionId: string): Promise<GoalSnapshot | null> { const agent = await this.resolveMainAgent(sessionId); - return agent.accessor - .get(IAgentLifecycleService) - .resolve(agentContextOf(agent), AgentGoal) - .getGoal().goal; + return agent.accessor.get(IAgentGoalService).getGoal().goal; } } +/** + * Context limit of the configured default model, or `undefined` when no + * default model is configured or it does not resolve. + */ function resolveDefaultModelContextTokens(agent: IAgentScopeHandle): number | undefined { const defaultModel = agent.accessor.get(IModelService).getDefaultModel(); if (defaultModel === undefined || defaultModel.length === 0) return undefined; diff --git a/packages/agent-core-v2/src/app/sessionLegacy/sessionProtocol.ts b/packages/agent-core-v2/src/app/sessionLegacy/sessionProtocol.ts index 7d18b4667..b1c041016 100644 --- a/packages/agent-core-v2/src/app/sessionLegacy/sessionProtocol.ts +++ b/packages/agent-core-v2/src/app/sessionLegacy/sessionProtocol.ts @@ -1,3 +1,12 @@ +/** + * `sessionLegacy` domain — the v1 session wire DTO schemas. + * + * These zod schemas define the request/response shapes of the v1 session + * endpoints this adapter backs (`POST /sessions/{id}/profile`, + * `GET /sessions/{id}/status`, session warnings). Field-level changes here + * are wire breaks. + */ + import { z } from 'zod'; import { isoDateTimeSchema } from '#/_base/utils/isoDateTime'; @@ -36,7 +45,6 @@ export const sessionAgentConfigSchema = z.object({ permission_mode: promptPermissionModeSchema.optional(), plan_mode: z.boolean().optional(), swarm_mode: z.boolean().optional(), - tower_mode: z.boolean().optional(), goal_objective: z.string().optional(), goal_control: z.enum(['pause', 'resume', 'cancel']).optional(), }); @@ -76,9 +84,8 @@ export const sessionStatusResponseSchema = z.object({ permission: z.string(), plan_mode: z.boolean(), swarm_mode: z.boolean(), - tower_mode: z.boolean().optional(), context_tokens: z.number().int().nonnegative(), max_context_tokens: z.number().int().nonnegative().optional(), - context_usage: z.number().min(0).max(1).optional(), + context_usage: z.number().min(0).max(1), }); export type SessionStatusResponse = z.infer<typeof sessionStatusResponseSchema>; diff --git a/packages/agent-core-v2/src/app/sessionManager/sessionLookup.ts b/packages/agent-core-v2/src/app/sessionManager/sessionLookup.ts deleted file mode 100644 index 1d6b4d2f6..000000000 --- a/packages/agent-core-v2/src/app/sessionManager/sessionLookup.ts +++ /dev/null @@ -1,77 +0,0 @@ -import type { ServicesAccessor } from '#/_base/di/instantiation'; -import type { IDisposable } from '#/_base/di/lifecycle'; -import type { ISessionScopeHandle } from '#/_base/di/scope'; -import { ISessionIndex } from '#/app/sessionIndex/sessionIndex'; -import { ISessionManager, type ISessionManager as SessionManager } from '#/app/sessionManager/sessionManager'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { isError2 } from '#/errors'; -import type { Program } from '#/program/program'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import type { ResumeSessionOptions } from '#/workspace/sessionLifecycle/sessionLifecycle'; -import { IWorkspaceInstanceManager } from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -export async function programForSession( - accessor: ServicesAccessor, - sessionId: string, -): Promise<Program | undefined> { - const manager = accessor.get(ISessionManager); - const live = manager.get(sessionId); - if (live !== undefined) { - const workspaceId = live.accessor.get(ISessionContext).workspaceId; - return accessor.get(IWorkspaceInstanceManager).get(workspaceId)?.program; - } - const summary = await accessor.get(ISessionIndex).get(sessionId); - if (summary === undefined) return undefined; - const workspace = await accessor.get(IWorkspaceInstanceManager).getOrCreate({ - workspaceId: summary.workspaceId, - root: summary.cwd, - }); - return workspace.program; -} - -export async function resumeSessionById( - accessor: ServicesAccessor, - sessionId: string, - opts?: ResumeSessionOptions, -): Promise<ISessionScopeHandle | undefined> { - try { - return await accessor.get(ISessionManager).resume(sessionId, opts); - } catch (error) { - accessor - .get(ITelemetryService) - .withContext({ sessionId }) - .track2('session_load_failed', { - reason: isError2(error) ? error.code : error instanceof Error ? error.name : 'unknown', - }); - throw error; - } -} - -export function getLiveSessionById( - accessor: ServicesAccessor, - sessionId: string, -): ISessionScopeHandle | undefined { - return accessor.get(ISessionManager).get(sessionId); -} - -export async function closeSessionById( - accessor: ServicesAccessor, - sessionId: string, -): Promise<void> { - await accessor.get(ISessionManager).close(sessionId); -} - -type SessionLifecycleEvents = Required< - Pick<SessionManager, 'onDidCloseSession' | 'onDidArchiveSession'> ->; - -export function followSessionLifecycles( - accessor: ServicesAccessor, - follow: (service: SessionLifecycleEvents) => IDisposable, -): IDisposable { - const manager = accessor.get(ISessionManager); - if (manager.onDidCloseSession === undefined || manager.onDidArchiveSession === undefined) { - return { dispose: () => {} }; - } - return follow(manager as SessionLifecycleEvents); -} diff --git a/packages/agent-core-v2/src/app/sessionManager/sessionManager.ts b/packages/agent-core-v2/src/app/sessionManager/sessionManager.ts deleted file mode 100644 index 8e01daf9e..000000000 --- a/packages/agent-core-v2/src/app/sessionManager/sessionManager.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { ISessionScopeHandle } from '#/_base/di/scope'; -import type { Event, IWaitUntil } from '#/_base/event'; -import type { SessionSummary } from '#/app/sessionIndex/sessionIndex'; -import type { - CreateChildSessionOptions, - CreateSessionOptions, - ForkSessionOptions, - ResumeSessionOptions, - SessionArchivedEvent, - SessionClosedEvent, - SessionCreatedEvent, - SessionForkedEvent, - SessionWillCloseEvent, - SessionWillCreateEvent, -} from '#/workspace/sessionLifecycle/sessionLifecycle'; - -export interface CreateManagedSessionOptions extends CreateSessionOptions { - readonly workspaceId?: string; -} - -export interface UnguardedSessionLifecycle { - archive(): Promise<void>; - restore(): Promise<ISessionScopeHandle | undefined>; -} - -export interface ISessionManager { - readonly _serviceBrand: undefined; - readonly onWillCreateSession?: Event<SessionWillCreateEvent>; - readonly onDidCreateSession?: Event<SessionCreatedEvent & IWaitUntil>; - readonly onWillCloseSession?: Event<SessionWillCloseEvent & IWaitUntil>; - readonly onDidCloseSession?: Event<SessionClosedEvent>; - readonly onDidArchiveSession?: Event<SessionArchivedEvent>; - readonly onDidForkSession?: Event<SessionForkedEvent>; - create(options: CreateManagedSessionOptions): Promise<ISessionScopeHandle>; - resume(sessionId: string, options?: ResumeSessionOptions): Promise<ISessionScopeHandle | undefined>; - get(sessionId: string): ISessionScopeHandle | undefined; - status(sessionId: string): Promise<SessionSummary | undefined>; - whenResumeSettled(sessionId: string): Promise<void>; - withLifecycleSerialization<T>( - sessionId: string, - work: (unguarded: UnguardedSessionLifecycle) => Promise<T>, - ): Promise<T>; - list(): readonly ISessionScopeHandle[]; - close(sessionId: string): Promise<void>; - archive(sessionId: string): Promise<void>; - restore(sessionId: string, options?: ResumeSessionOptions): Promise<ISessionScopeHandle | undefined>; - delete(sessionId: string): Promise<void>; - fork(options: ForkSessionOptions): Promise<ISessionScopeHandle>; - createChild(options: CreateChildSessionOptions): Promise<ISessionScopeHandle>; -} - -export const ISessionManager: ServiceIdentifier<ISessionManager> = createDecorator<ISessionManager>('sessionManager'); diff --git a/packages/agent-core-v2/src/app/sessionManager/sessionManagerService.ts b/packages/agent-core-v2/src/app/sessionManager/sessionManagerService.ts deleted file mode 100644 index 263beeb25..000000000 --- a/packages/agent-core-v2/src/app/sessionManager/sessionManagerService.ts +++ /dev/null @@ -1,280 +0,0 @@ - -import { DisposableStore } from '#/_base/di/lifecycle'; -import { Emitter, type Event, type IWaitUntil } from '#/_base/event'; -import { ScopeActivation, registerScopedService, type ISessionScopeHandle } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { Error2, ErrorCodes } from '#/errors'; -import { ISessionIndex, type SessionSummary } from '#/app/sessionIndex/sessionIndex'; -import { - type CreateChildSessionOptions, - type ForkSessionOptions, - type ResumeSessionOptions, - type SessionArchivedEvent, - type SessionClosedEvent, - type SessionCreatedEvent, - type SessionForkedEvent, - type SessionWillCloseEvent, - type SessionWillCreateEvent, -} from '#/workspace/sessionLifecycle/sessionLifecycle'; -import type { SessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycleService'; -import { IWorkspaceInstanceManager } from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import { - ISessionManager, - type CreateManagedSessionOptions, - type UnguardedSessionLifecycle, -} from './sessionManager'; - -interface SessionControllerEntry { - readonly generation: string; - readonly controller: SessionLifecycleService; - readonly subscriptions: DisposableStore; - sessionCount: number; -} - -export class SessionManager implements ISessionManager { - declare readonly _serviceBrand: undefined; - private readonly sessions = new Map<string, ISessionScopeHandle>(); - private readonly owners = new Map<string, SessionLifecycleService>(); - private readonly pendingResumes = new Map<string, Promise<ISessionScopeHandle | undefined>>(); - private readonly resumeFailures = new Map<string, Error>(); - private readonly lifecycleChains = new Map<string, Promise<void>>(); - private readonly controllers = new Map<string, SessionControllerEntry>(); - private readonly controllerEntries = new Set<SessionControllerEntry>(); - private readonly willCreateEmitter = new Emitter<SessionWillCreateEvent>(); - readonly onWillCreateSession: Event<SessionWillCreateEvent> = this.willCreateEmitter.event; - private readonly didCreateEmitter = new Emitter<SessionCreatedEvent & IWaitUntil>(); - readonly onDidCreateSession = this.didCreateEmitter.event; - private readonly willCloseEmitter = new Emitter<SessionWillCloseEvent & IWaitUntil>(); - readonly onWillCloseSession = this.willCloseEmitter.event; - private readonly didCloseEmitter = new Emitter<SessionClosedEvent>(); - readonly onDidCloseSession = this.didCloseEmitter.event; - private readonly didArchiveEmitter = new Emitter<SessionArchivedEvent>(); - readonly onDidArchiveSession = this.didArchiveEmitter.event; - private readonly didForkEmitter = new Emitter<SessionForkedEvent>(); - readonly onDidForkSession = this.didForkEmitter.event; - - constructor( - @IWorkspaceInstanceManager private readonly workspaces: IWorkspaceInstanceManager, - @ISessionIndex private readonly index: ISessionIndex, - ) {} - - async create(options: CreateManagedSessionOptions): Promise<ISessionScopeHandle> { - const workspace = await this.workspaces.getOrCreate( - options.workspaceId === undefined - ? { root: options.workDir } - : { workspaceId: options.workspaceId, root: options.workDir }, - ); - const controller = this.controllerForWorkspace(workspace.id); - if (options.sessionId === undefined) return controller.create(options); - return this.serializeLifecycle(options.sessionId, () => controller.create(options)); - } - - async resume(sessionId: string, options?: ResumeSessionOptions): Promise<ISessionScopeHandle | undefined> { - const inflight = this.pendingResumes.get(sessionId); - if (inflight !== undefined) return inflight; - this.resumeFailures.delete(sessionId); - const promise = this.serializeLifecycle(sessionId, async () => - (await this.controllerForSession(sessionId))?.resume(sessionId, options), - ).finally(() => this.pendingResumes.delete(sessionId)); - this.pendingResumes.set(sessionId, promise); - void promise.catch((error: unknown) => { - this.resumeFailures.set(sessionId, error instanceof Error ? error : new Error('session resume failed')); - }); - return promise; - } - - get(sessionId: string): ISessionScopeHandle | undefined { - return this.sessions.get(sessionId); - } - - status(sessionId: string): Promise<SessionSummary | undefined> { - return this.index.get(sessionId); - } - - async whenResumeSettled(sessionId: string): Promise<void> { - await this.pendingResumes.get(sessionId); - const failure = this.resumeFailures.get(sessionId); - if (failure !== undefined) throw failure; - await this.owners.get(sessionId)?.whenResumeSettled(sessionId); - } - - private serializeLifecycle<T>(sessionId: string, work: () => Promise<T>): Promise<T> { - const prev = this.lifecycleChains.get(sessionId) ?? Promise.resolve(); - const run = prev.then(work, work); - const next = run.then( - () => undefined, - () => undefined, - ); - this.lifecycleChains.set(sessionId, next); - void next.finally(() => { - if (this.lifecycleChains.get(sessionId) === next) this.lifecycleChains.delete(sessionId); - }); - return run; - } - - private serializeLifecycleForKeys<T>(keys: readonly string[], work: () => Promise<T>): Promise<T> { - const [first, ...rest] = keys; - if (first === undefined) return work(); - return this.serializeLifecycle(first, () => this.serializeLifecycleForKeys(rest, work)); - } - - private lifecycleKeys(...ids: (string | undefined)[]): string[] { - return [...new Set(ids.filter((id): id is string => id !== undefined))].sort(); - } - - withLifecycleSerialization<T>( - sessionId: string, - work: (unguarded: UnguardedSessionLifecycle) => Promise<T>, - ): Promise<T> { - return this.serializeLifecycle(sessionId, () => - work({ - archive: () => this.archiveInner(sessionId), - restore: () => this.restoreInner(sessionId), - }), - ); - } - - list(): readonly ISessionScopeHandle[] { - return [...this.sessions.values()]; - } - - async close(sessionId: string): Promise<void> { - await this.serializeLifecycle(sessionId, async () => this.owners.get(sessionId)?.close(sessionId)); - } - - private async archiveInner(sessionId: string): Promise<void> { - await (await this.controllerForSession(sessionId))?.archive(sessionId); - } - - async archive(sessionId: string): Promise<void> { - await this.serializeLifecycle(sessionId, () => this.archiveInner(sessionId)); - } - - private async restoreInner( - sessionId: string, - options?: ResumeSessionOptions, - ): Promise<ISessionScopeHandle | undefined> { - return (await this.controllerForSession(sessionId))?.restore(sessionId, options); - } - - async restore(sessionId: string, options?: ResumeSessionOptions): Promise<ISessionScopeHandle | undefined> { - return this.serializeLifecycle(sessionId, () => this.restoreInner(sessionId, options)); - } - - async delete(sessionId: string): Promise<void> { - await this.serializeLifecycle(sessionId, async () => { - const controller = await this.controllerForSession(sessionId); - if (controller === undefined) { - throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sessionId} does not exist`); - } - await controller.delete(sessionId); - }); - } - - async fork(options: ForkSessionOptions): Promise<ISessionScopeHandle> { - return this.serializeLifecycleForKeys( - this.lifecycleKeys(options.sourceSessionId, options.newSessionId), - async () => { - const controller = await this.controllerForSession(options.sourceSessionId); - if (controller === undefined) { - throw new Error2( - ErrorCodes.SESSION_NOT_FOUND, - `session ${options.sourceSessionId} does not exist`, - ); - } - return controller.fork(options); - }, - ); - } - - async createChild(options: CreateChildSessionOptions): Promise<ISessionScopeHandle> { - return this.serializeLifecycleForKeys( - this.lifecycleKeys(options.sourceSessionId, options.newSessionId), - async () => { - const controller = await this.controllerForSession(options.sourceSessionId); - if (controller === undefined) { - throw new Error2( - ErrorCodes.SESSION_NOT_FOUND, - `session ${options.sourceSessionId} does not exist`, - ); - } - return controller.createChild(options); - }, - ); - } - - dispose(): void { - for (const { controller, subscriptions } of [...this.controllerEntries].reverse()) { - subscriptions.dispose(); - controller.dispose(); - } - this.controllerEntries.clear(); - this.controllers.clear(); - this.sessions.clear(); - this.owners.clear(); - this.willCreateEmitter.dispose(); - this.didCreateEmitter.dispose(); - this.willCloseEmitter.dispose(); - this.didCloseEmitter.dispose(); - this.didArchiveEmitter.dispose(); - this.didForkEmitter.dispose(); - } - - private controllerForWorkspace(workspaceId: string): SessionLifecycleService { - const workspace = this.workspaces.get(workspaceId); - if (workspace === undefined) throw new Error(`workspace ${workspaceId} is not materialized`); - const generation = workspace.program.sessionControllerGeneration; - const existing = this.controllers.get(workspaceId); - if (existing?.generation === generation) return existing.controller; - const controller = workspace.program.createSessionController(); - const subscriptions = new DisposableStore(); - const entry: SessionControllerEntry = { generation, controller, subscriptions, sessionCount: 0 }; - subscriptions.add(controller.onWillCreateSession((event) => this.willCreateEmitter.fire(event))); - subscriptions.add(controller.onDidCreateSession((event) => { - entry.sessionCount += 1; - this.sessions.set(event.sessionId, event.handle); - this.owners.set(event.sessionId, controller); - this.didCreateEmitter.fire(event); - })); - subscriptions.add(controller.onWillCloseSession((event) => this.willCloseEmitter.fire(event))); - subscriptions.add(controller.onDidCloseSession((event) => { - entry.sessionCount -= 1; - this.sessions.delete(event.sessionId); - this.owners.delete(event.sessionId); - this.didCloseEmitter.fire(event); - this.retireEntryIfIdle(workspaceId, entry); - })); - subscriptions.add(controller.onDidArchiveSession((event) => { - entry.sessionCount -= 1; - this.sessions.delete(event.sessionId); - this.owners.delete(event.sessionId); - this.didArchiveEmitter.fire(event); - this.retireEntryIfIdle(workspaceId, entry); - })); - subscriptions.add(controller.onDidForkSession((event) => this.didForkEmitter.fire(event))); - this.controllerEntries.add(entry); - this.controllers.set(workspaceId, entry); - if (existing !== undefined) this.retireEntryIfIdle(workspaceId, existing); - return controller; - } - - private retireEntryIfIdle(workspaceId: string, entry: SessionControllerEntry): void { - if (entry.sessionCount !== 0 || !this.controllerEntries.has(entry)) return; - this.controllerEntries.delete(entry); - if (this.controllers.get(workspaceId) === entry) this.controllers.delete(workspaceId); - entry.subscriptions.dispose(); - entry.controller.dispose(); - } - - private async controllerForSession(sessionId: string): Promise<SessionLifecycleService | undefined> { - const live = this.owners.get(sessionId); - if (live !== undefined) return live; - const summary = await this.index.get(sessionId); - if (summary === undefined) return undefined; - const workspace = await this.workspaces.getOrCreate({ workspaceId: summary.workspaceId, root: summary.cwd }); - return this.controllerForWorkspace(workspace.id); - } -} - -registerScopedService(LifecycleScope.App, ISessionManager, SessionManager, ScopeActivation.OnScopeCreated, 'sessionManager'); diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/builtin.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/builtin.ts similarity index 51% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/builtin.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/builtin.ts index 67237bac6..dbbb9dad4 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/builtin.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/builtin.ts @@ -1,11 +1,22 @@ -import type { IFlagService } from '#/app/flag/flag'; -import type { SkillDefinition } from '#/features/skill/catalog/types'; +/** + * `skillCatalog` domain — builtin skill registration. + * + * Code-defined builtin skills are constants (not discovered from storage), so + * they bypass `ISkillDiscovery`: `BUILTIN_SKILLS` feeds the builtin + * `ISkillSource`. + * + * `visibleBuiltinSkills` is the one place that decides which of them the + * `builtin_product_skills` switch excludes. Every consumer goes through it — the + * session-scoped source and the session-less workspace listings alike — so a + * skill marked `productSpecific` cannot stay advertised on one surface while + * being filtered on another. + */ +import type { SkillDefinition } from '#/app/skillCatalog/types'; import { CHECK_KIMI_CODE_DOCS_SKILL } from './check-kimi-code-docs'; import { CUSTOM_THEME_SKILL } from './custom-theme'; import { IMPORT_FROM_CC_CODEX_SKILL } from './import-from-cc-codex'; import { MCP_CONFIG_SKILL } from './mcp-config'; -import { getBuiltinSkillContributions } from './registry'; import { SUB_SKILL_CONSOLIDATE, SUB_SKILL_PARENT, @@ -26,18 +37,9 @@ export const BUILTIN_SKILLS: readonly SkillDefinition[] = [ SUB_SKILL_CONSOLIDATE, ]; -export function visibleBuiltinSkills( - productSkillsEnabled: boolean, - flags?: IFlagService, -): readonly SkillDefinition[] { - const all = [...BUILTIN_SKILLS, ...getBuiltinSkillContributions()]; - const visible = productSkillsEnabled - ? all - : all.filter((skill) => skill.productSpecific !== true); - if (flags === undefined) return visible; - return visible.filter( - (skill) => skill.experimentalFlag === undefined || flags.enabled(skill.experimentalFlag), - ); +export function visibleBuiltinSkills(productSkillsEnabled: boolean): readonly SkillDefinition[] { + if (productSkillsEnabled) return BUILTIN_SKILLS; + return BUILTIN_SKILLS.filter((skill) => skill.productSpecific !== true); } export { diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/check-kimi-code-docs.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/check-kimi-code-docs.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/check-kimi-code-docs.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/check-kimi-code-docs.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/check-kimi-code-docs.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/check-kimi-code-docs.ts similarity index 72% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/check-kimi-code-docs.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/check-kimi-code-docs.ts index 1bcbda7f9..6d66d8ebf 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/check-kimi-code-docs.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/check-kimi-code-docs.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `check-kimi-code-docs` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import CHECK_KIMI_CODE_DOCS_BODY from './check-kimi-code-docs.md?raw'; const PSEUDO_PATH = 'builtin://check-kimi-code-docs'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/custom-theme.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/custom-theme.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/custom-theme.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/custom-theme.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/custom-theme.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/custom-theme.ts similarity index 72% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/custom-theme.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/custom-theme.ts index f58affbc3..566e71188 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/custom-theme.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/custom-theme.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `custom-theme` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import CUSTOM_THEME_BODY from './custom-theme.md?raw'; const PSEUDO_PATH = 'builtin://custom-theme'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/import-from-cc-codex.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/import-from-cc-codex.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/import-from-cc-codex.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/import-from-cc-codex.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/import-from-cc-codex.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/import-from-cc-codex.ts similarity index 73% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/import-from-cc-codex.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/import-from-cc-codex.ts index 483a0f942..58d6d90ef 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/import-from-cc-codex.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/import-from-cc-codex.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `import-from-cc-codex` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import IMPORT_FROM_CC_CODEX_BODY from './import-from-cc-codex.md?raw'; const PSEUDO_PATH = 'builtin://import-from-cc-codex'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/mcp-config.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/mcp-config.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/mcp-config.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/mcp-config.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/mcp-config.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/mcp-config.ts similarity index 71% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/mcp-config.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/mcp-config.ts index f4b1fb25a..7b2f77f67 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/mcp-config.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/mcp-config.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `mcp-config` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import MCP_CONFIG_BODY from './mcp-config.md?raw'; const PSEUDO_PATH = 'builtin://mcp-config'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill.ts similarity index 84% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill.ts index 7b8c72364..0c32d3864 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `sub-skill` bundle (parent + review + consolidate). + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import CONSOLIDATE_BODY from './sub-skill/consolidate/SKILL.md?raw'; import REVIEW_BODY from './sub-skill/review/SKILL.md?raw'; import PARENT_BODY from './sub-skill/SKILL.md?raw'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/SKILL.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/SKILL.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/SKILL.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/SKILL.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/consolidate/SKILL.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/consolidate/SKILL.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/consolidate/SKILL.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/consolidate/SKILL.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/review/SKILL.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/review/SKILL.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/sub-skill/review/SKILL.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/sub-skill/review/SKILL.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.md similarity index 96% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.md index 9fcdddb4b..155838774 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.md +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.md @@ -20,7 +20,7 @@ echo "$HOME/.kimi-code" Use the first line when it is non-empty; otherwise use the second line. In the rest of this skill, `<KIMI_CODE_HOME>` means that resolved root — **never assume `~/.kimi-code`**. -- **`config.toml`** — agent / runtime settings: `default_model`, `[secondary_model]` (experimental `secondary-model` flag: `default_model` / `[secondary_model.models]` subagent model pool / `force` to pin subagents to `default_model`; a lone legacy v1 `model` key is honored as a fallback default), `[subagent]` (`timeout_ms`), `providers`, `models`, `thinking`, `permission`, `hooks`, `loop_control`, etc. +- **`config.toml`** — agent / runtime settings: `default_model`, `secondary_model` (subagent model), `providers`, `models`, `thinking`, `permission`, `hooks`, `loop_control`, etc. - **`tui.toml`** — terminal-UI / client preferences: `theme`, `[editor].command`, `[notifications]`, `[upgrade].auto_install` (auto-update). These can usually also be changed with the interactive commands `/config`, `/theme`, `/editor`, which is easier — prefer pointing the user at those. The "read → copy → Edit → validate → back up → overwrite" flow below applies to both files; only **which reload command applies** differs (see Capability 4). diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.ts similarity index 70% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.ts index b42edce74..00d0dbec9 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/update-config.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/update-config.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `update-config` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import UPDATE_CONFIG_BODY from './update-config.md?raw'; const PSEUDO_PATH = 'builtin://update-config'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/write-goal.md b/packages/agent-core-v2/src/app/skillCatalog/builtin/write-goal.md similarity index 100% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/write-goal.md rename to packages/agent-core-v2/src/app/skillCatalog/builtin/write-goal.md diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/write-goal.ts b/packages/agent-core-v2/src/app/skillCatalog/builtin/write-goal.ts similarity index 69% rename from packages/agent-core-v2/src/features/skill/catalog/builtin/write-goal.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtin/write-goal.ts index 5a88d351a..6fdd6ba88 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/write-goal.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtin/write-goal.ts @@ -1,5 +1,9 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; -import { parseSkillText } from '#/features/skill/catalog/parser'; +/** + * `skillCatalog` domain — builtin `write-goal` skill definition. + */ + +import type { SkillDefinition } from '#/app/skillCatalog/types'; +import { parseSkillText } from '#/app/skillCatalog/parser'; import WRITE_GOAL_BODY from './write-goal.md?raw'; const PSEUDO_PATH = 'builtin://write-goal'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtinSkillSource.ts b/packages/agent-core-v2/src/app/skillCatalog/builtinSkillSource.ts similarity index 67% rename from packages/agent-core-v2/src/features/skill/catalog/builtinSkillSource.ts rename to packages/agent-core-v2/src/app/skillCatalog/builtinSkillSource.ts index faf76c668..81d4ed444 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/builtinSkillSource.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/builtinSkillSource.ts @@ -1,10 +1,23 @@ +/** + * `skillCatalog` domain — builtin `ISkillSource` producer. + * + * Yields the code-defined `BUILTIN_SKILLS` as the lowest-priority contribution + * (`builtin`, priority 0) so extra / user / workspace / plugin skills override + * it on name collision. Bound at App scope. + * + * Product-documentation skills are filtered here rather than downstream: their + * names sit in the system prompt for the whole session, and being the + * lowest-priority source this one loads first and is kept for the life of the + * handler — hence the wait for config readiness, and the change event that + * lets the catalog reload it when the switch is toggled. + */ + import { Emitter, type Event } from '#/_base/event'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IConfigService } from '#/app/config/config'; -import { IFlagService } from '#/app/flag/flag'; import { visibleBuiltinSkills } from './builtin/builtin'; import { @@ -33,10 +46,7 @@ export class BuiltinSkillSource extends Disposable implements IBuiltinSkillSourc private readonly onDidChangeEmitter = this._register(new Emitter<void>()); readonly onDidChange: Event<void> = this.onDidChangeEmitter.event; - constructor( - @IConfigService private readonly config: IConfigService, - @IFlagService private readonly flags: IFlagService, - ) { + constructor(@IConfigService private readonly config: IConfigService) { super(); this._register( this.config.onDidSectionChange((event) => { @@ -47,9 +57,7 @@ export class BuiltinSkillSource extends Disposable implements IBuiltinSkillSourc async load(): Promise<SkillContribution> { await this.config.ready; - return { - skills: visibleBuiltinSkills(builtinProductSkillsEnabled(this.config), this.flags), - }; + return { skills: visibleBuiltinSkills(builtinProductSkillsEnabled(this.config)) }; } } diff --git a/packages/agent-core-v2/src/features/skill/catalog/configSection.ts b/packages/agent-core-v2/src/app/skillCatalog/configSection.ts similarity index 59% rename from packages/agent-core-v2/src/features/skill/catalog/configSection.ts rename to packages/agent-core-v2/src/app/skillCatalog/configSection.ts index 63fd7d095..a9948829f 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/configSection.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/configSection.ts @@ -1,3 +1,29 @@ +/** + * `skillCatalog` domain — skill config sections. + * + * Registers the v1-compatible top-level config domains `extraSkillDirs` and + * `mergeAllAvailableSkills`, plus `builtinProductSkills`. Values stay camelCase + * in memory; TOML uses the snake_case keys `extra_skill_dirs`, + * `merge_all_available_skills`, and `builtin_product_skills`. + * + * `builtinProductSkills` decides whether the builtin skills documenting this + * CLI itself — its `config.toml` / `tui.toml` settings, custom themes, MCP + * setup, the official docs lookup, and the Claude Code / Codex import — are + * offered to the model. On by default; turning it off trims their names and + * descriptions from the system prompt, where they otherwise sit on every turn, + * at the cost of the guided flows for those tasks. Useful for unattended runs, + * or deployments where nobody reconfigures the CLI mid-task. + * + * That section is a whole-section scalar rather than an object of fields, so + * the env binding covers it directly and it needs its own strip: + * `stripEnvBoundFields` only walks object fields, so an env override would + * otherwise be written back into `config.toml`. The strip restores the + * env-free file value while the env var resolves, and drops the field when the + * file held anything but a boolean. `builtinProductSkillsEnabled` reads the + * resolved switch; only an explicit opt-out disables, so a missing or + * not-yet-registered section behaves like the shipped default. + */ + import { z } from 'zod'; import { parseBooleanEnv } from '#/_base/utils/env'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/errors.ts b/packages/agent-core-v2/src/app/skillCatalog/errors.ts similarity index 90% rename from packages/agent-core-v2/src/features/skill/catalog/errors.ts rename to packages/agent-core-v2/src/app/skillCatalog/errors.ts index 526f1a006..fda774c4c 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/errors.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/errors.ts @@ -1,3 +1,7 @@ +/** + * `skillCatalog` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const SkillErrors = { diff --git a/packages/agent-core-v2/src/features/skill/catalog/fileSkillDiscovery.ts b/packages/agent-core-v2/src/app/skillCatalog/fileSkillDiscovery.ts similarity index 95% rename from packages/agent-core-v2/src/features/skill/catalog/fileSkillDiscovery.ts rename to packages/agent-core-v2/src/app/skillCatalog/fileSkillDiscovery.ts index 95ce5c01d..a73077ba8 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/fileSkillDiscovery.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/fileSkillDiscovery.ts @@ -1,3 +1,11 @@ +/** + * `skillCatalog` domain — filesystem `ISkillDiscovery` backend. + * + * Discovers skill bundles by walking caller-supplied roots and parsing each + * SKILL.md. Exposes discovery through the App-scoped service and a stateless + * filesystem entry point. + */ + import { promises as fs } from 'node:fs'; import path from 'pathe'; @@ -43,21 +51,6 @@ export async function discoverFileSkills( ): Promise<void> { if (depth > MAX_SKILL_SCAN_DEPTH) return; - if (root.scanMode === 'root-skill-only') { - const rootSkillMd = path.join(dirPath, 'SKILL.md'); - if (await isFile(rootSkillMd)) { - await parseAndRegister({ - byDiscoveryKey, - skipped, - warn, - skillMdPath: rootSkillMd, - skillDirName: path.basename(dirPath), - root, - }); - } - return; - } - let entries: readonly string[]; try { entries = [...(await fs.readdir(dirPath))].toSorted(); diff --git a/packages/agent-core-v2/src/features/skill/catalog/inMemorySkillDiscovery.ts b/packages/agent-core-v2/src/app/skillCatalog/inMemorySkillDiscovery.ts similarity index 72% rename from packages/agent-core-v2/src/features/skill/catalog/inMemorySkillDiscovery.ts rename to packages/agent-core-v2/src/app/skillCatalog/inMemorySkillDiscovery.ts index 1e5f74d89..7d4edc8ad 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/inMemorySkillDiscovery.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/inMemorySkillDiscovery.ts @@ -1,3 +1,17 @@ +/** + * `skillCatalog` domain — in-memory `ISkillDiscovery` backend. + * + * Returns preset skill lists for discovery without any IO, so tests and scopes + * work without a filesystem. A call seeded with project roots returns the + * project skills, one seeded with user roots returns the user skills, one + * seeded with extra roots returns the extra skills, one seeded with plugin + * roots returns the plugin skills, and an empty root list (the common test + * case where the resolved directories do not exist on disk) returns the user + * and project skills the double holds — user skills first, project skills + * last, so project entries win the within-list collision resolution. + * App-scoped. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/parser.ts b/packages/agent-core-v2/src/app/skillCatalog/parser.ts similarity index 95% rename from packages/agent-core-v2/src/features/skill/catalog/parser.ts rename to packages/agent-core-v2/src/app/skillCatalog/parser.ts index 0d3c7b810..3a99a4a52 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/parser.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/parser.ts @@ -1,3 +1,11 @@ +/** + * `skillCatalog` domain — SKILL.md parsing primitives. + * + * Parses a SKILL.md (frontmatter + body) into a `SkillDefinition` and extracts + * flowchart blocks. Pure functions with no IO: callers read bytes however they + * like and pass the decoded text in. + */ + import path from 'pathe'; import { Error2 } from '#/_base/errors/errors'; diff --git a/packages/agent-core-v2/src/features/skill/catalog/registry.ts b/packages/agent-core-v2/src/app/skillCatalog/registry.ts similarity index 96% rename from packages/agent-core-v2/src/features/skill/catalog/registry.ts rename to packages/agent-core-v2/src/app/skillCatalog/registry.ts index 8e29bbb91..19386a84a 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/registry.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/registry.ts @@ -1,3 +1,12 @@ +/** + * `skillCatalog` domain — concrete in-memory skill catalog. + * + * Owns registered skill lookup, plugin-scoped skill lookup, prompt rendering, + * and model-facing skill listings for `skill`, plus the skipped-skill / + * scanned-root diagnostics accumulated from discovery results. It is not a + * scoped service. + */ + import { escapeXmlAttr, escapeXmlTags } from '#/_base/utils/xml-escape'; import type { diff --git a/packages/agent-core-v2/src/app/skillCatalog/skillDiscovery.ts b/packages/agent-core-v2/src/app/skillCatalog/skillDiscovery.ts new file mode 100644 index 000000000..7a30a5cfd --- /dev/null +++ b/packages/agent-core-v2/src/app/skillCatalog/skillDiscovery.ts @@ -0,0 +1,30 @@ +/** + * `skillCatalog` domain — catalog discovery contract. + * + * `ISkillDiscovery` is the single generic filesystem primitive that hides how + * skill bundles are discovered: a backend walks the caller-supplied skill + * roots, reads each SKILL.md, and parses it into `SkillDefinition`s. Global vs + * project discovery differ only by which roots are passed in — there is one + * `discover(roots)`, not per-kind methods. The skill domain depends on this + * interface only and never touches `node:fs` / `hostFs`; the backend is chosen + * at the composition root (file locally, in-memory for tests, object storage or + * a DB on a server). App-scoped. + */ + +import { createDecorator } from '#/_base/di/instantiation'; + +import type { SkillDefinition, SkillRoot, SkippedSkill } from './types'; + +export interface SkillDiscoveryResult { + readonly skills: readonly SkillDefinition[]; + readonly skipped: readonly SkippedSkill[]; + readonly scannedRoots: readonly string[]; + readonly scannedDirectories: readonly string[]; +} + +export interface ISkillDiscovery { + readonly _serviceBrand: undefined; + discover(roots: readonly SkillRoot[]): Promise<SkillDiscoveryResult>; +} + +export const ISkillDiscovery = createDecorator<ISkillDiscovery>('skillDiscovery'); diff --git a/packages/agent-core-v2/src/features/skill/catalog/skillRoots.ts b/packages/agent-core-v2/src/app/skillCatalog/skillRoots.ts similarity index 85% rename from packages/agent-core-v2/src/features/skill/catalog/skillRoots.ts rename to packages/agent-core-v2/src/app/skillCatalog/skillRoots.ts index 3db2239db..8c9d4a5f7 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/skillRoots.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/skillRoots.ts @@ -1,8 +1,16 @@ +/** + * `skillCatalog` domain — skill-root resolution primitives. + * + * Resolves the ordered `SkillRoot` list a discovery backend should scan for the + * user (home) and project (workspace) skill locations. Brand directories are + * preferred over generic ones (`.kimi-code/skills` before `.agents/skills`), + * and the project root is found by walking up to `.git`. Pure path/fs probes; + * no scoped state. + */ + import { promises as fs } from 'node:fs'; import path from 'pathe'; -import { findUpwardRoot } from '#/_base/utils/paths'; - import type { SkillRoot, SkillSource } from './types'; const USER_BRAND_DIRS = ['skills'] as const; @@ -70,7 +78,14 @@ export async function configuredRoots( } async function findProjectRoot(workDir: string): Promise<string> { - return findUpwardRoot(workDir, '.git', exists); + const start = path.resolve(workDir); + let current = start; + while (true) { + if (await exists(path.join(current, '.git'))) return current; + const parent = path.dirname(current); + if (parent === current) return start; + current = parent; + } } async function pushFirstExisting( diff --git a/packages/agent-core-v2/src/app/skillCatalog/skillSource.ts b/packages/agent-core-v2/src/app/skillCatalog/skillSource.ts new file mode 100644 index 000000000..5388ce384 --- /dev/null +++ b/packages/agent-core-v2/src/app/skillCatalog/skillSource.ts @@ -0,0 +1,42 @@ +/** + * `skillCatalog` domain — skill-source contract. + * + * `ISkillSource` is the producer half of the skill subsystem: each source loads + * a `SkillContribution` and advertises a `priority` so the Session sink can + * ordered-merge contributions (higher priority wins name collisions). Sources + * PUSH into the sink; the sink is a dumb ordered-merge table. File-backed + * sources additionally carry the load diagnostics (`skipped`, `scannedRoots`) + * produced by `ISkillDiscovery`, which the sink folds into the merged catalog; + * ad-hoc contributions omit them. Concrete sources (builtin/user at App scope, + * extra/workspace/plugin at Session scope) each bind their own DI token + * extending this contract. + */ + +import type { Event } from '#/_base/event'; + +import type { SkillDefinition, SkippedSkill } from './types'; + +export interface SkillContribution { + readonly skills: readonly SkillDefinition[]; + readonly skipped?: readonly SkippedSkill[]; + readonly scannedRoots?: readonly string[]; +} + +export const SKILL_SOURCE_PRIORITY = { + builtin: 0, + plugin: 5, + extra: 10, + user: 20, + workspace: 30, +} as const; + +export const PLUGIN_SKILL_SOURCE_ID = 'plugin'; +export const BUILTIN_SKILL_SOURCE_ID = 'builtin'; + +export interface ISkillSource { + readonly _serviceBrand: undefined; + readonly id: string; + readonly priority: number; + readonly onDidChange?: Event<void>; + load(): Promise<SkillContribution>; +} diff --git a/packages/agent-core-v2/src/features/skill/catalog/types.ts b/packages/agent-core-v2/src/app/skillCatalog/types.ts similarity index 86% rename from packages/agent-core-v2/src/features/skill/catalog/types.ts rename to packages/agent-core-v2/src/app/skillCatalog/types.ts index 5bb3a55ef..9ee2a86a1 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/types.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/types.ts @@ -1,3 +1,13 @@ +/** + * `skillCatalog` domain — skill data types. + * + * The shapes every skill source produces and the catalog stores. A definition + * marked `productSpecific` documents this CLI itself — its configuration, + * themes, MCP setup — rather than a capability the agent applies to the user's + * work, which is what the `builtin_product_skills` switch excludes; those + * names and descriptions otherwise sit in the system prompt every turn. + */ + export type SkillSource = 'project' | 'user' | 'extra' | 'builtin'; export interface SkillMetadata { @@ -24,7 +34,6 @@ export interface SkillDefinition { readonly mermaid?: string | undefined; readonly d2?: string; readonly productSpecific?: boolean; - readonly experimentalFlag?: string; } export interface SkillSummary { @@ -41,7 +50,6 @@ export interface SkillRoot { readonly path: string; readonly source: SkillSource; readonly plugin?: SkillPluginContext; - readonly scanMode?: 'directory' | 'root-skill-only'; } export interface SkillPluginContext { diff --git a/packages/agent-core-v2/src/features/skill/catalog/userFileSkillSource.ts b/packages/agent-core-v2/src/app/skillCatalog/userFileSkillSource.ts similarity index 87% rename from packages/agent-core-v2/src/features/skill/catalog/userFileSkillSource.ts rename to packages/agent-core-v2/src/app/skillCatalog/userFileSkillSource.ts index d705059ed..308bba3de 100644 --- a/packages/agent-core-v2/src/features/skill/catalog/userFileSkillSource.ts +++ b/packages/agent-core-v2/src/app/skillCatalog/userFileSkillSource.ts @@ -1,3 +1,11 @@ +/** + * `skillCatalog` domain — user/brand `ISkillSource` producer. + * + * Discovers user skills from the bootstrap home directories through + * `ISkillDiscovery`, contributing them at priority 20 (above extra / plugin / + * builtin, below workspace). Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { Emitter, type Event } from '#/_base/event'; @@ -21,6 +29,7 @@ export interface IUserFileSkillSource extends ISkillSource { export const IUserFileSkillSource: ServiceIdentifier<IUserFileSkillSource> = createDecorator<IUserFileSkillSource>('userFileSkillSource'); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class UserFileSkillSource extends Disposable implements IUserFileSkillSource { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/app/state/appState.ts b/packages/agent-core-v2/src/app/state/appState.ts index cc938ad51..d754559cf 100644 --- a/packages/agent-core-v2/src/app/state/appState.ts +++ b/packages/agent-core-v2/src/app/state/appState.ts @@ -1,3 +1,15 @@ +/** + * `state` domain — App-scope keyed state container contract. + * + * Defines `IAppStateService`, the App-scope state service: App-tier services + * declare their plain-data state as typed keys (via `defineState`) + * and read/write them through this container, so process-wide shared state + * lives in one observable place instead of scattering across private fields. + * Shares the `IStateRegistry` method set with its Workspace/Session/Agent + * counterparts and is the root of the four-tier `inspect()` cascade (no + * parent). Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IStateRegistry } from '#/_base/state/stateRegistry'; diff --git a/packages/agent-core-v2/src/app/state/appStateService.ts b/packages/agent-core-v2/src/app/state/appStateService.ts index 466fae5cf..e7ea6bfc0 100644 --- a/packages/agent-core-v2/src/app/state/appStateService.ts +++ b/packages/agent-core-v2/src/app/state/appStateService.ts @@ -1,3 +1,12 @@ +/** + * `state` domain — `IAppStateService` implementation. + * + * Thin per-scope binding over the `_base` `StateRegistry`; the container owns + * construction and disposal, so registered state dies with the scope. The + * root of the four-tier `inspect()` cascade — the only tier without an + * `inspectParent`. Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/task/task.ts b/packages/agent-core-v2/src/app/task/task.ts index 6ba8eafee..23e02b10b 100644 --- a/packages/agent-core-v2/src/app/task/task.ts +++ b/packages/agent-core-v2/src/app/task/task.ts @@ -1,3 +1,18 @@ +/** + * `task` domain — managed concurrent execution primitive. + * + * Two creation modes: + * + * - `run(fn)` — active execution: wraps an async function with + * `AbortSignal`, output stream, state machine, and disposal. + * - `defer()` — passive wait: the caller controls when the handle + * settles via `resolve` / `reject`. + * + * Consumers that need to track handles across turns compose on top of these + * primitives; `ITaskService` itself is stateless beyond the set of live + * handles. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/app/task/taskService.ts b/packages/agent-core-v2/src/app/task/taskService.ts index d40c1b03a..08373e358 100644 --- a/packages/agent-core-v2/src/app/task/taskService.ts +++ b/packages/agent-core-v2/src/app/task/taskService.ts @@ -1,3 +1,11 @@ +/** + * `task` domain — `ITaskService` implementation. + * + * Manages task handles: each handle owns a state machine, an optional + * `AbortController` (for `run()`), and `Emitter` pairs for state changes + * and output. App-scoped — one instance per process. + */ + import { Emitter, type Event } from '#/_base/event'; import { markAsDisposed, trackDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; diff --git a/packages/agent-core-v2/src/app/telemetry/agentTelemetryContext.ts b/packages/agent-core-v2/src/app/telemetry/agentTelemetryContext.ts index 7e298e0b3..f677f37ec 100644 --- a/packages/agent-core-v2/src/app/telemetry/agentTelemetryContext.ts +++ b/packages/agent-core-v2/src/app/telemetry/agentTelemetryContext.ts @@ -1,3 +1,11 @@ +/** + * `telemetry` domain — `IAgentTelemetryContextService` contract. + * + * Agent-scoped mutable request context holding `mode`, `provider_type` / + * `protocol`, `turn_id`, and `trace_id`, snapshotted by turn telemetry at + * launch. Bound at Agent scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; export type AgentTelemetryContext = { diff --git a/packages/agent-core-v2/src/app/telemetry/agentTelemetryContextService.ts b/packages/agent-core-v2/src/app/telemetry/agentTelemetryContextService.ts index 33ee7acf2..f2a30a4bc 100644 --- a/packages/agent-core-v2/src/app/telemetry/agentTelemetryContextService.ts +++ b/packages/agent-core-v2/src/app/telemetry/agentTelemetryContextService.ts @@ -1,3 +1,11 @@ +/** + * `telemetry` domain — `IAgentTelemetryContextService` implementation. + * + * Holds mutable request context (defaulting to `mode: 'agent'`) that turn + * telemetry snapshots at launch. Bound at Agent scope; has no cross-domain + * collaborators. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/telemetry/cloudAppender.ts b/packages/agent-core-v2/src/app/telemetry/cloudAppender.ts index 4b7313739..860065e1e 100644 --- a/packages/agent-core-v2/src/app/telemetry/cloudAppender.ts +++ b/packages/agent-core-v2/src/app/telemetry/cloudAppender.ts @@ -1,3 +1,14 @@ +/** + * `telemetry` domain — `CloudAppender`, an `ITelemetryAppender` that + * batches events, drops non-primitive properties, redacts PII from string + * values, enriches events with common context, and posts them to the + * telemetry endpoint through `CloudTransport`, which persists failed events + * through the `storage` byte layer. Reads host facts (`clientIdentity`, env, + * platform/arch) from `IBootstrapService`; `createCloudAppender` assembles + * one from a `ServicesAccessor` so hosts only supply identity facts. + * App-scoped; independent of `@moonshot-ai/kimi-telemetry`. + */ + import { randomUUID } from 'node:crypto'; import { release } from 'node:os'; @@ -84,10 +95,6 @@ export class CloudAppender implements ITelemetryAppender { storage: options.storage, deviceId: options.deviceId, endpoint: options.endpoint, - homeDir: options.bootstrap.homeDir, - readMarker: - (options.bootstrap.getEnv('KIMI_CODE_REGION_MARKER') ?? - process.env['KIMI_CODE_REGION_MARKER']) !== 'off', getAccessToken: options.getAccessToken, fetchImpl: options.fetchImpl, retryBackoffsMs: options.retryBackoffsMs, diff --git a/packages/agent-core-v2/src/app/telemetry/cloudTransport.ts b/packages/agent-core-v2/src/app/telemetry/cloudTransport.ts index 59ac07bd3..1c740e90d 100644 --- a/packages/agent-core-v2/src/app/telemetry/cloudTransport.ts +++ b/packages/agent-core-v2/src/app/telemetry/cloudTransport.ts @@ -1,10 +1,12 @@ -import { randomBytes } from 'node:crypto'; +/** + * `telemetry` domain — `CloudTransport`, the HTTP transport for cloud + * telemetry. Posts enriched events to the telemetry endpoint with Bearer + * auth, retry, and a byte-store fallback for failed events, persisted through + * the `storage` byte layer (`IFileSystemStorageService`) under the `telemetry` scope. + * App-scoped; independent of `@moonshot-ai/kimi-telemetry`. + */ -import { - KIMI_REGION_PROFILES, - kimiRegionProfile, - resolveKimiRegion, -} from '@moonshot-ai/kimi-code-oauth'; +import { randomBytes } from 'node:crypto'; import { isAbortError } from '#/_base/utils/abort'; import type { IFileSystemStorageService } from '#/persistence/interface/storage'; @@ -37,8 +39,6 @@ export interface CloudTransportOptions { readonly storage: IFileSystemStorageService; readonly deviceId: string; readonly endpoint?: string; - readonly homeDir?: string; - readonly readMarker?: boolean; readonly getAccessToken?: () => string | null | Promise<string | null>; readonly fetchImpl?: typeof fetch; readonly retryBackoffsMs?: readonly number[]; @@ -47,7 +47,7 @@ export interface CloudTransportOptions { readonly now?: () => number; } -export const TELEMETRY_ENDPOINT = KIMI_REGION_PROFILES['mainland-cn'].telemetryEndpoint; +export const TELEMETRY_ENDPOINT = 'https://telemetry-logs.kimi.com/v1/event'; export const SERVER_EVENT_PREFIX = 'kfc_'; export const USER_ID_PREFIX = 'kfc_device_id_'; export const DISK_EVENT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1000; @@ -61,12 +61,6 @@ const JSONL_SUFFIX = '.jsonl'; const textEncoder = new TextEncoder(); const textDecoder = new TextDecoder(); -function defaultTelemetryEndpoint(homeDir?: string, readMarker = true): string { - return kimiRegionProfile( - resolveKimiRegion({ readMarker, homeDir }), - ).telemetryEndpoint; -} - export class CloudTransport { private readonly storage: IFileSystemStorageService; private readonly deviceId: string; @@ -81,12 +75,7 @@ export class CloudTransport { constructor(options: CloudTransportOptions) { this.storage = options.storage; this.deviceId = options.deviceId; - this.endpoint = - options.endpoint ?? - defaultTelemetryEndpoint( - options.homeDir, - options.readMarker ?? process.env['KIMI_CODE_REGION_MARKER'] !== 'off', - ); + this.endpoint = options.endpoint ?? TELEMETRY_ENDPOINT; this.getAccessToken = options.getAccessToken ?? null; this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis); this.retryBackoffsMs = options.retryBackoffsMs ?? RETRY_BACKOFFS_MS; diff --git a/packages/agent-core-v2/src/app/telemetry/consoleAppender.ts b/packages/agent-core-v2/src/app/telemetry/consoleAppender.ts index 6ac9a8117..17fc7f001 100644 --- a/packages/agent-core-v2/src/app/telemetry/consoleAppender.ts +++ b/packages/agent-core-v2/src/app/telemetry/consoleAppender.ts @@ -1,3 +1,9 @@ +/** + * `telemetry` domain — `ConsoleAppender`, an `ITelemetryAppender` that + * echoes events to a log function for development and debugging. App-scoped; + * has no cross-domain collaborators. + */ + import type { ITelemetryAppender, TelemetryProperties } from './telemetry'; export interface ConsoleAppenderOptions { @@ -34,5 +40,6 @@ function stringifyProperties(properties: TelemetryProperties, pretty: boolean): } function defaultLog(message: string): void { + // eslint-disable-next-line no-console console.log(message); } diff --git a/packages/agent-core-v2/src/app/telemetry/coreVersion.ts b/packages/agent-core-v2/src/app/telemetry/coreVersion.ts index 351cbfece..2b064fe66 100644 --- a/packages/agent-core-v2/src/app/telemetry/coreVersion.ts +++ b/packages/agent-core-v2/src/app/telemetry/coreVersion.ts @@ -1,3 +1,14 @@ +/** + * `telemetry` domain — agent-core-v2 package version resolution. + * + * Resolves the engine's own package version at runtime by walking up from + * this module's location to the nearest `package.json` named + * `@moonshot-ai/agent-core-v2`. Works whenever the package runs from its own + * directory layout (workspace installs); falls back to + * `'unknown'` when the code is bundled into another package's artifact. + * App-scoped, no collaborators. + */ + import { existsSync, readFileSync } from 'node:fs'; import { dirname, resolve } from 'node:path'; import { fileURLToPath } from 'node:url'; diff --git a/packages/agent-core-v2/src/app/telemetry/events.ts b/packages/agent-core-v2/src/app/telemetry/events.ts index bcdf23067..f9cd96f0d 100644 --- a/packages/agent-core-v2/src/app/telemetry/events.ts +++ b/packages/agent-core-v2/src/app/telemetry/events.ts @@ -1,3 +1,20 @@ +/** + * `telemetry` domain — telemetry event registry. + * + * Central registry of every business event emitted through + * `ITelemetryService.track2`: each entry pairs the event's property type + * (the compile-time contract enforced at call sites) with review metadata + * (owner, purpose, per-property comment) whose keys must match the property + * type exactly. Agent-scoped entries compose their payload with the centrally + * declared Agent telemetry context, keeping ambient identity out of business + * payloads while preserving the effective wire schema. Registered names are + * the raw event names, before the transport's `kfc_` server prefix. Naming + * conventions: events and properties are snake_case; durations/counts/sizes + * carry a unit suffix (`_ms` / `_count` / `_bytes`); never register user + * content or file paths as properties. App-scoped, self-contained — property + * unions are declared locally instead of imported from business domains. + */ + import type { TelemetryPrimitive } from './telemetry'; export interface TelemetryEventMeta { @@ -76,17 +93,6 @@ export interface TurnEndedEvent { trace_id?: string; } -export interface PromptCacheProbeEvent { - source: 'fork'; - turn_id: number; - provider_type?: string; - protocol?: string; - input_tokens: number; - input_cache_read: number; - input_cache_creation: number; - output_tokens: number; -} - export type ToolCallOutcome = 'success' | 'error' | 'cancelled'; export interface ToolCallEvent { @@ -246,14 +252,6 @@ export interface BackgroundTaskCompletedEvent { status: 'running' | 'completed' | 'failed' | 'timed_out' | 'killed' | 'lost'; } -export interface WaitForCompletedEvent { - outcome: 'completed' | 'timed_out' | 'task_not_found' | 'aborted'; - timeout_ms: number; - waited_ms: number; - has_task_id: boolean; - extra_completed_count: number; -} - export interface ModelSwitchEvent { model: string; } @@ -325,16 +323,6 @@ export interface ToolCallRepeatEvent { trace_id?: string; } -export interface ToolCallTurnRepeatEvent { - turn_id?: number; - step_no: number; - tool_call_id: string; - tool_name: string; - turn_repeat_count: number; - args_hash: string; - trace_id?: string; -} - export interface AgentsMdReminderShownEvent { turn_id: number; tool_name: string; @@ -356,18 +344,12 @@ export interface FsGrepNodeFallbackEvent { reason: 'rg_missing'; } -export interface FsSuggestNodeFallbackEvent { - reason: 'rg_missing' | 'rg_error'; -} - export interface SubagentCreatedEvent { subagent_name: string; run_in_background: boolean; - fork: boolean; agent_id: string; parent_agent_id: string; parent_tool_call_id: string; - model?: string; } export interface McpConnectedEvent { @@ -508,21 +490,6 @@ export const telemetryEventDefinitions = { 'Trace id of the most recent LLM request in this turn; absent for non-Kimi protocols', }, }), - prompt_cache_probe: defineAgentTelemetryEvent<PromptCacheProbeEvent>({ - owner: 'kimi-code', - comment: - 'An agent whose first request is expected to hit the prompt cache reports that request\'s cache usage.', - properties: { - source: 'Why a cache hit was expected for this request', - turn_id: 'Per-agent turn index of the probed request', - provider_type: 'Provider protocol type', - protocol: 'Request protocol', - input_tokens: 'Total input tokens of the probed request (other + cache read + cache creation)', - input_cache_read: 'Cache-read input tokens of the probed request', - input_cache_creation: 'Cache-creation input tokens of the probed request', - output_tokens: 'Output tokens of the probed request', - }, - }), tool_call: defineAgentTelemetryEvent<ToolCallEvent>({ owner: 'kimi-code', comment: 'A tool call finishes execution.', @@ -728,18 +695,6 @@ export const telemetryEventDefinitions = { status: 'Terminal task status', }, }), - wait_for_completed: defineAgentTelemetryEvent<WaitForCompletedEvent>({ - owner: 'kimi-code', - comment: 'A WaitFor tool call returns.', - properties: { - outcome: - 'How the wait ended: the waited task finished, the wait timed out, the task id was unknown, or the wait was aborted', - timeout_ms: 'Timeout argument in milliseconds', - waited_ms: 'Actual wall-clock wait time in milliseconds', - has_task_id: 'Whether a specific task id was given', - extra_completed_count: 'Number of additional tasks that finished within the wait window', - }, - }), model_switch: defineAgentTelemetryEvent<ModelSwitchEvent>({ owner: 'kimi-code', comment: 'The active model is bound or switched.', @@ -840,20 +795,6 @@ export const telemetryEventDefinitions = { 'Trace id of the LLM request that produced the repeated tool call; absent for non-Kimi protocols', }, }), - tool_call_turn_repeat: defineAgentTelemetryEvent<ToolCallTurnRepeatEvent>({ - owner: 'kimi-code', - comment: 'A tool call reappears within the same turn.', - properties: { - turn_id: 'Per-agent turn index (main or subagent); pair with agent_id to locate a turn within a session; omitted when no turn is active', - step_no: 'Step index within the turn', - tool_call_id: 'Provider-assigned tool call id', - tool_name: 'Registered tool name', - turn_repeat_count: 'Number of prior-step tool-call reappearances counted in the turn', - args_hash: 'Hash of the tool call arguments', - trace_id: - 'Trace id of the LLM request that produced the repeated tool call; absent for non-Kimi protocols', - }, - }), agents_md_reminder_shown: defineAgentTelemetryEvent<AgentsMdReminderShownEvent>({ owner: 'kimi-code', comment: 'An AGENTS.md discovery reminder is appended to a tool result.', @@ -886,22 +827,15 @@ export const telemetryEventDefinitions = { comment: 'The fs grep path falls back to the node implementation.', properties: { reason: 'Why the fallback was taken' }, }), - fs_suggest_node_fallback: defineTelemetryEvent<FsSuggestNodeFallbackEvent>({ - owner: 'kimi-code', - comment: 'The fs suggest path falls back to the node implementation.', - properties: { reason: 'Why the fallback was taken' }, - }), subagent_created: defineTelemetryEvent<SubagentCreatedEvent>({ owner: 'kimi-code', comment: 'A subagent run is created.', properties: { subagent_name: 'Profile name of the subagent', run_in_background: 'Whether the subagent runs in the background', - fork: 'Whether the subagent was forked with a snapshot of the parent conversation history', agent_id: 'Child agent id', parent_agent_id: 'Parent (caller) agent id', parent_tool_call_id: "Tool call id of the launching call in the parent agent; '' when not launched from a tool call", - model: 'Model alias the subagent binds to (secondary-model choice or inherited caller model); omitted when no binding was resolved', }, }), mcp_connected: defineTelemetryEvent<McpConnectedEvent>({ diff --git a/packages/agent-core-v2/src/app/telemetry/privacy.ts b/packages/agent-core-v2/src/app/telemetry/privacy.ts index f5ba4bb23..a408105c7 100644 --- a/packages/agent-core-v2/src/app/telemetry/privacy.ts +++ b/packages/agent-core-v2/src/app/telemetry/privacy.ts @@ -1,3 +1,13 @@ +/** + * `telemetry` domain — outbound PII cleaning for telemetry properties. + * + * Redacts user-identifying content from string property values before events + * leave the process: URLs, emails, common token formats, and absolute file + * paths become labeled `<REDACTED: ...>` placeholders, while `node_modules/` + * path tails are kept because they carry diagnostic value without user data. + * App-scoped, no collaborators. + */ + const REDACTED_PATH = '<REDACTED: user-file-path>'; const NODE_MODULES_MARKER = 'node_modules/'; diff --git a/packages/agent-core-v2/src/app/telemetry/telemetry.ts b/packages/agent-core-v2/src/app/telemetry/telemetry.ts index ba6e61549..210d4dce4 100644 --- a/packages/agent-core-v2/src/app/telemetry/telemetry.ts +++ b/packages/agent-core-v2/src/app/telemetry/telemetry.ts @@ -1,3 +1,14 @@ +/** + * `telemetry` domain — `ITelemetryService` contract and appender types. + * + * Layer-1 root service: merges bound context into tracked events and fans + * them out to one or more `ITelemetryAppender` destinations. App-scoped — + * stateless beyond its appender set and bound context; enrichment, batching, + * and transport are owned by the appenders, not by this layer. Defines the + * `ITelemetryAppender` contract, the `ITelemetryService` facade, the service + * options, and the null appender. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/app/telemetry/telemetryService.ts b/packages/agent-core-v2/src/app/telemetry/telemetryService.ts index 609d896b8..4425e44d4 100644 --- a/packages/agent-core-v2/src/app/telemetry/telemetryService.ts +++ b/packages/agent-core-v2/src/app/telemetry/telemetryService.ts @@ -1,3 +1,12 @@ +/** + * `telemetry` domain — `ITelemetryService` implementation. + * + * Owns the appender set, enabled flag, and root context, and creates forwarding + * context views that merge scoped properties at emission time. Views retain no + * transport state, so appender and enablement changes remain controlled by the + * App-scoped root. Has no cross-domain collaborators. + */ + import { type IDisposable, toDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/web/errors.ts b/packages/agent-core-v2/src/app/web/errors.ts index 0698c17b0..ad66e25aa 100644 --- a/packages/agent-core-v2/src/app/web/errors.ts +++ b/packages/agent-core-v2/src/app/web/errors.ts @@ -1,3 +1,7 @@ +/** + * `web` domain error codes — URL fetching and SSRF guard failures. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const WebErrors = { diff --git a/packages/agent-core-v2/src/app/web/providers/local-fetch-url.ts b/packages/agent-core-v2/src/app/web/providers/local-fetch-url.ts index ff7afe754..403f2efe0 100644 --- a/packages/agent-core-v2/src/app/web/providers/local-fetch-url.ts +++ b/packages/agent-core-v2/src/app/web/providers/local-fetch-url.ts @@ -1,3 +1,17 @@ +/** + * `web` domain — local `UrlFetcher` used when no managed fetch service + * is configured. GETs URLs with a Chrome-like UA and SSRF hardening: http(s) + * schemes only; unless `allowPrivateAddresses` is set, IP literals and + * DNS-resolved addresses in loopback / RFC1918 / link-local / CGNAT / ULA + * ranges are refused, including IPv4-mapped IPv6 forms; redirects are + * followed manually with the same validation re-run on every hop; and each + * request's connection is pinned to the DNS answers validation approved, so + * a connect-time re-resolution cannot be rebound elsewhere (pinning is + * skipped for IP literals and for requests a proxy will carry — NO_PROXY + * bypasses still pin). Oversized bodies are refused; plain texts pass + * through verbatim and HTML is reduced to its main text. + */ + import { lookup as callbackLookup, type LookupAddress, type LookupOptions } from 'node:dns'; import { lookup } from 'node:dns/promises'; import { BlockList, isIP, type LookupFunction } from 'node:net'; diff --git a/packages/agent-core-v2/src/app/web/tools/fetch-url-types.ts b/packages/agent-core-v2/src/app/web/tools/fetch-url-types.ts index f727fffa2..a5ba788e7 100644 --- a/packages/agent-core-v2/src/app/web/tools/fetch-url-types.ts +++ b/packages/agent-core-v2/src/app/web/tools/fetch-url-types.ts @@ -1,3 +1,7 @@ +/** + * `web` domain — host-injected `UrlFetcher` contract. + */ + import { Error2 } from '#/_base/errors/errors'; import { WebErrors } from '../errors'; diff --git a/packages/agent-core-v2/src/app/web/web.ts b/packages/agent-core-v2/src/app/web/web.ts index a4eb98951..9b1dd2c8f 100644 --- a/packages/agent-core-v2/src/app/web/web.ts +++ b/packages/agent-core-v2/src/app/web/web.ts @@ -1,3 +1,11 @@ +/** + * `web` domain — URL fetching with an optional OAuth-backed backend. + * + * Declares the `IWebFetchService` seam that yields the `UrlFetcher` behind + * the built-in `FetchURL` tool, so `FetchURL` works both with and without + * OAuth. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { UrlFetcher } from './tools/fetch-url-types'; diff --git a/packages/agent-core-v2/src/app/web/webService.ts b/packages/agent-core-v2/src/app/web/webService.ts index 135e2e92c..3dcb45813 100644 --- a/packages/agent-core-v2/src/app/web/webService.ts +++ b/packages/agent-core-v2/src/app/web/webService.ts @@ -1,3 +1,26 @@ +/** + * `web` domain — `IWebFetchService` implementation. + * + * Yields the `UrlFetcher` the `FetchURL` tool uses, resolving the backend in + * precedence order: (1) an explicit `[services.moonshot_fetch]` config + * section with a `baseUrl` — built with its `apiKey` and/or an `oauth` ref + * resolved through `IOAuthService.resolveTokenProvider(...)`; (2) the managed + * Kimi OAuth provider when it carries an `oauth` ref (the state after a + * successful Kimi login), routing fetches through the Moonshot fetch service + * (`${provider.baseUrl}/fetch`); and (3) the built-in `LocalFetchURLProvider`, + * so `FetchURL` keeps working without any configuration. The first two fall + * back to the local fetcher on failure. Reads config and the managed provider + * lazily on each `getUrlFetcher()` call so it tracks edits and login state. + * Bound at App scope. + * + * Default headers split by who chose the endpoint: a `[services]` entry names + * its own, so that path sends `agentIdentity`'s frozen `requestHeaders` — the + * host header set with the `User-Agent` product token rewritten to the + * configured identity — while the managed OAuth path sends the host's own + * headers (`IBootstrapService.args.requestHeaders`) verbatim, being the + * endpoint the session authenticated against. + */ + import { KIMI_CODE_PROVIDER_NAME, kimiCodeBaseUrl, diff --git a/packages/agent-core-v2/src/app/workspace/fileWorkspacePersistence.ts b/packages/agent-core-v2/src/app/workspace/fileWorkspacePersistence.ts index 920412fe8..01a2def20 100644 --- a/packages/agent-core-v2/src/app/workspace/fileWorkspacePersistence.ts +++ b/packages/agent-core-v2/src/app/workspace/fileWorkspacePersistence.ts @@ -1,3 +1,15 @@ +/** + * `workspace` domain — `FileWorkspacePersistence` implementation. + * + * File backend of `IWorkspacePersistence`. Persists the catalog as a single + * v1-compatible `workspaces.json` document at the storage root + * (`<homeDir>/workspaces.json`, via `scope = ''`) through the + * `IAtomicDocumentStore` access-pattern Store. The `deleted_workspace_ids` + * tombstone list round-trips with the catalog so soft deletions survive + * regardless of which engine (v1 or v2) last wrote the file. Bound at App + * scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/workspace/workspace.ts b/packages/agent-core-v2/src/app/workspace/workspace.ts index a901392c5..11cfd5877 100644 --- a/packages/agent-core-v2/src/app/workspace/workspace.ts +++ b/packages/agent-core-v2/src/app/workspace/workspace.ts @@ -1,3 +1,12 @@ +/** + * `workspace` domain — process-wide catalog of known workspaces. + * + * Defines the `IWorkspaceService` used by the program side to remember the + * folders the user has opened (backed by the app's own persistence). This is + * a host-side catalog, not a session-scoped description of one Agent's active + * work directory. App-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface Workspace { diff --git a/packages/agent-core-v2/src/app/workspace/workspaceAlias.ts b/packages/agent-core-v2/src/app/workspace/workspaceAlias.ts index 9545bb7c4..112e13e18 100644 --- a/packages/agent-core-v2/src/app/workspace/workspaceAlias.ts +++ b/packages/agent-core-v2/src/app/workspace/workspaceAlias.ts @@ -1,3 +1,15 @@ +/** + * `workspace` domain — alias-folding pure helpers. + * + * One physical folder can arrive under several id spellings (Windows + * drive-letter casing, slash direction, typed-vs-realpath variants, legacy + * `encodeWorkDirKey` outputs). These helpers enumerate or collapse those + * spellings without owning any state: `collectAliasIds` expands one root to + * every id that addresses it, `dedupeByRoot` collapses a catalog to one + * representative per directory, and the session-index readers parse the + * legacy v1 `session_index.jsonl`. + */ + import { isAbsolute } from 'pathe'; import { encodeWorkDirKey, workspaceRootKey } from '#/_base/utils/workdir-slug'; diff --git a/packages/agent-core-v2/src/app/workspace/workspaceEvents.ts b/packages/agent-core-v2/src/app/workspace/workspaceEvents.ts deleted file mode 100644 index e726f5fd4..000000000 --- a/packages/agent-core-v2/src/app/workspace/workspaceEvents.ts +++ /dev/null @@ -1,38 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -import type { Workspace } from './workspace'; - -export interface WorkspaceCreatedPayload { - readonly workspace: Workspace; -} - -export class WorkspaceCreated extends Event2<{ readonly payload: WorkspaceCreatedPayload }> { - static override readonly type = 'event.workspace.created'; -} -export interface WorkspaceCreated { - readonly payload: WorkspaceCreatedPayload; -} - -export interface WorkspaceUpdatedPayload { - readonly workspace: Workspace; -} - -export class WorkspaceUpdated extends Event2<{ readonly payload: WorkspaceUpdatedPayload }> { - static override readonly type = 'event.workspace.updated'; -} -export interface WorkspaceUpdated { - readonly payload: WorkspaceUpdatedPayload; -} - -export interface WorkspaceDeletedPayload { - readonly workspaceId: string; - readonly root: string; -} - -export class WorkspaceDeleted extends Event2<{ readonly payload: WorkspaceDeletedPayload }> { - static override readonly type = 'event.workspace.deleted'; -} -export interface WorkspaceDeleted { - readonly payload: WorkspaceDeletedPayload; -} diff --git a/packages/agent-core-v2/src/app/workspace/workspacePersistence.ts b/packages/agent-core-v2/src/app/workspace/workspacePersistence.ts index 4c96e4d6a..3d8517f67 100644 --- a/packages/agent-core-v2/src/app/workspace/workspacePersistence.ts +++ b/packages/agent-core-v2/src/app/workspace/workspacePersistence.ts @@ -1,3 +1,24 @@ +/** + * `workspace` domain — `IWorkspacePersistence` contract. + * + * Domain-specific persistence Store for the known-workspaces catalog. It hides + * the on-disk document layout (`<homeDir>/workspaces.json`, the v1-compatible + * `{ version, workspaces: { [id]: entry }, deleted_workspace_ids: string[] }` + * shape) and its serialization concerns (ISO ↔ epoch-ms, record ↔ array) + * from the workspace service. The generic `IAtomicDocumentStore` it builds on stays + * schema-agnostic. + * + * `deleted_workspace_ids` is the soft-delete tombstone list: ids the user + * explicitly removed. Tombstoned entries are absent from `workspaces`, but + * their ids must survive load/save round-trips so the session-index merge + * never resurrects them. + * + * `load()` returns `undefined` to mean "no usable catalog" so the workspace + * service can trigger a one-shot rebuild from the legacy session index; an + * empty catalog is a valid, already-materialized state and must NOT trigger a + * rebuild. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Workspace } from './workspace'; diff --git a/packages/agent-core-v2/src/app/workspace/workspaceService.ts b/packages/agent-core-v2/src/app/workspace/workspaceService.ts index dfd4daa35..a9e741ab9 100644 --- a/packages/agent-core-v2/src/app/workspace/workspaceService.ts +++ b/packages/agent-core-v2/src/app/workspace/workspaceService.ts @@ -1,18 +1,66 @@ +/** + * `workspace` domain — `IWorkspaceService` implementation. + * + * Process-wide catalog of known workspaces, durable in + * `<homeDir>/workspaces.json` (the v1-compatible file). The service keeps NO + * in-memory write cache: every operation is a fresh read-modify-write + * against the file, serialized through a promise-chain mutex. This is + * required, not just tidy — the same file is written concurrently by other + * processes, so a write-through cache would clobber external additions and + * tombstones with stale state. Atomic renames at the persistence layer plus fresh + * read-modify-write on both engines shrink the lost-update window to a + * single read-modify-write, and the next session-index merge heals anything + * still lost there. + * + * Once per process, the first operation triggers the startup sync with the + * legacy `<homeDir>/session_index.jsonl`: + * + * 1. No usable catalog file → one-shot rebuild (one workspace per distinct + * absolute `workDir`), persisted. + * 2. Catalog loaded → only workDirs the file does not know about yet are + * added (e.g. sessions created by the v1 TUI since the last sync), + * persisted if anything changed. + * + * Deletion is soft: `delete` drops the entry but records the id in + * `deleted_workspace_ids`, and the merge never resurrects a tombstoned id. + * An explicit `createOrTouch` clears the tombstone — the user opening the + * folder again is a stronger signal than the historical index. + * + * `createOrTouch` is the single choke point every workspace/session creation + * funnels through, so it owns the root-existence contract: the root must be + * an existing directory on the host filesystem, otherwise it throws + * `fs.path_not_found`. The directory probe follows symlinks + * (`IHostFileSystem.stat` is lstat-based, so a symlink-form root is + * re-checked through `realpath`), while the workspace identity stays lexical. + * The rebuild and merge paths bypass the check on purpose — they catalog + * where sessions *were*, not where new ones may open. Bound at App scope. + * + * One physical folder can arrive under several spellings — most visibly on + * Windows, where drive-letter casing, slash direction, and typed-vs-realpath + * casing all differ for one directory. Every "same directory?" judgment + * (`createOrTouch` reuse, the session-index rebuild, and the `list` merge in + * `dedupeByRoot`) therefore goes through the `workspaceRootKey` identity key + * rather than the raw root string, while the minted `workspaceId` stays the + * case-sensitive `encodeWorkDirKey` so already-persisted session buckets, + * `workspaces.json` entries, and session metadata keep resolving with zero + * data migration. + * + * Legacy data may still be split: two registry entries (or a registry entry + * plus session-index-only spellings) for one physical folder, with sessions + * bucketed per id. `delete` folds the same alias set inside the op mutex so a + * sibling spelling cannot resurface as this directory's representative on the + * next `list()`. + */ + import { basename, isAbsolute } from 'pathe'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { encodeWorkDirKey, workspaceRootKey } from '#/_base/utils/workdir-slug'; -import { IEventService } from '#/app/event/event'; import { ErrorCodes, Error2, unwrapErrorCause } from '#/errors'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; import { IWorkspaceService, type Workspace, type WorkspaceUpdate } from './workspace'; -import { - WorkspaceCreated, - WorkspaceDeleted, - WorkspaceUpdated, -} from './workspaceEvents'; import { collectAliasIds, dedupeByRoot, @@ -31,7 +79,6 @@ export class WorkspaceService implements IWorkspaceService { @IWorkspacePersistence private readonly store: IWorkspacePersistence, @IFileSystemStorageService private readonly storage: IFileSystemStorageService, @IHostFileSystem private readonly hostFs: IHostFileSystem, - @IEventService private readonly event: IEventService, ) {} list(): Promise<readonly Workspace[]> { @@ -101,11 +148,6 @@ export class WorkspaceService implements IWorkspaceService { byId.set(ws.id, ws); deletedIds.delete(ws.id); await this.store.save({ workspaces: [...byId.values()], deletedIds: [...deletedIds] }); - this.event.publish( - existing === undefined - ? new WorkspaceCreated({ payload: { workspace: ws } }) - : new WorkspaceUpdated({ payload: { workspace: ws } }), - ); return ws; }); } @@ -124,7 +166,6 @@ export class WorkspaceService implements IWorkspaceService { workspaces: catalog.workspaces.map((ws) => (ws.id === id ? updated : ws)), deletedIds: catalog.deletedIds, }); - this.event.publish(new WorkspaceUpdated({ payload: { workspace: updated } })); return updated; }); } @@ -156,7 +197,6 @@ export class WorkspaceService implements IWorkspaceService { workspaces: catalog.workspaces.filter((ws) => workspaceRootKey(ws.root) !== rootKey), deletedIds: [...new Set([...catalog.deletedIds, ...aliasIds])], }); - this.event.publish(new WorkspaceDeleted({ payload: { workspaceId: id, root } })); }); } diff --git a/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliases.ts b/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliases.ts index 8683a09da..a959b29e1 100644 --- a/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliases.ts +++ b/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliases.ts @@ -1,3 +1,12 @@ +/** + * `workspaceAliases` domain — workspace id-spelling resolution contract. + * + * Defines the App-scoped `IWorkspaceAliases`: the read-side counterpart to the + * workspace write-path folding. One physical folder may be addressable by + * several id spellings (legacy split buckets); this service enumerates them so + * readers can query every sibling session bucket at once. App-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IWorkspaceAliases { diff --git a/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliasesService.ts b/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliasesService.ts index 8fc84bccc..e49763172 100644 --- a/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliasesService.ts +++ b/packages/agent-core-v2/src/app/workspaceAliases/workspaceAliasesService.ts @@ -1,3 +1,18 @@ +/** + * `workspaceAliases` domain — `IWorkspaceAliases` implementation. + * + * Resolves every id spelling of one physical directory by folding the + * registered catalog (by `workspaceRootKey`) together with `workDir` + * spellings recorded only in the legacy `session_index.jsonl`. The catalog + * is reached through + * `IWorkspaceService.get` first — its once-per-process session-index sync + * (`ensureMerged`) must have run before the raw catalog is read from + * `IWorkspacePersistence` — and the raw (un-deduped) catalog is required + * because `IWorkspaceService.list` collapses sibling spellings to one + * representative, which would defeat the alias enumeration. Read-only: no id + * or bucket is ever rewritten here. Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/app/workspaceLifecycle/sessionLookup.ts b/packages/agent-core-v2/src/app/workspaceLifecycle/sessionLookup.ts new file mode 100644 index 000000000..e164f1af7 --- /dev/null +++ b/packages/agent-core-v2/src/app/workspaceLifecycle/sessionLookup.ts @@ -0,0 +1,111 @@ +/** + * `workspaceLifecycle` domain — pure session-lookup helpers over the handler chain. + * + * The explicit `sessionIndex` → `IWorkspaceLifecycleService.handlerFor` → + * handler `ISessionLifecycleService` composition, shared by every caller + * that addresses a session by id from outside the Workspace scope (edge + * routes, in-process SDKs). These are plain functions over a STABLE + * accessor (a `Scope` / scope-handle `accessor`, never a transient + * `invokeFunction` one) — they are not an App-scope session lifecycle + * facade: the live registry and every lifecycle method stay on the + * handler's own service. Own no scoped state. + */ + +import type { ServicesAccessor } from '#/_base/di/instantiation'; +import { DisposableStore, type IDisposable } from '#/_base/di/lifecycle'; +import type { ISessionScopeHandle, IWorkspaceScopeHandle } from '#/_base/di/scope'; +import { ISessionIndex } from '#/app/sessionIndex/sessionIndex'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import { ErrorCodes, isError2 } from '#/errors'; +import { + ISessionLifecycleService, + type ResumeSessionOptions, +} from '#/workspace/sessionLifecycle/sessionLifecycle'; + +import { IWorkspaceLifecycleService } from './workspaceLifecycle'; + +export async function handlerForSession( + accessor: ServicesAccessor, + sessionId: string, +): Promise<IWorkspaceScopeHandle | undefined> { + const summary = await accessor.get(ISessionIndex).get(sessionId); + if (summary === undefined) return undefined; + try { + return await accessor + .get(IWorkspaceLifecycleService) + .handlerFor({ workspaceId: summary.workspaceId, root: summary.cwd }); + } catch (error) { + if (isError2(error) && error.code === ErrorCodes.WORKSPACE_NOT_FOUND) return undefined; + throw error; + } +} + +export async function resumeSessionById( + accessor: ServicesAccessor, + sessionId: string, + opts?: ResumeSessionOptions, +): Promise<ISessionScopeHandle | undefined> { + let handler: IWorkspaceScopeHandle | undefined; + try { + handler = await handlerForSession(accessor, sessionId); + } catch (error) { + accessor + .get(ITelemetryService) + .withContext({ sessionId }) + .track2('session_load_failed', { + reason: isError2(error) ? error.code : error instanceof Error ? error.name : 'unknown', + }); + throw error; + } + if (handler === undefined) return undefined; + return handler.accessor.get(ISessionLifecycleService).resume(sessionId, opts); +} + +export function liveHandlerForSession( + accessor: ServicesAccessor, + sessionId: string, +): IWorkspaceScopeHandle | undefined { + for (const handler of accessor.get(IWorkspaceLifecycleService).handlers.list()) { + if (handler.accessor.get(ISessionLifecycleService).get(sessionId) !== undefined) { + return handler; + } + } + return undefined; +} + +export function getLiveSessionById( + accessor: ServicesAccessor, + sessionId: string, +): ISessionScopeHandle | undefined { + return liveHandlerForSession(accessor, sessionId)?.accessor + .get(ISessionLifecycleService) + .get(sessionId); +} + +export async function closeSessionById( + accessor: ServicesAccessor, + sessionId: string, +): Promise<void> { + const handler = liveHandlerForSession(accessor, sessionId); + if (handler === undefined) return; + await handler.accessor.get(ISessionLifecycleService).close(sessionId); +} + +export function followWorkspaceHandlers( + accessor: ServicesAccessor, + follow: (service: ISessionLifecycleService) => IDisposable, +): IDisposable { + const lifecycle = accessor.get(IWorkspaceLifecycleService); + const store = new DisposableStore(); + for (const handler of lifecycle.handlers.list()) { + store.add(follow(handler.accessor.get(ISessionLifecycleService))); + } + store.add( + lifecycle.onDidMaterializeHandler((handler) => { + if (!store.isDisposed) { + store.add(follow(handler.accessor.get(ISessionLifecycleService))); + } + }), + ); + return store; +} diff --git a/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycle.ts b/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycle.ts new file mode 100644 index 000000000..303696ec2 --- /dev/null +++ b/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycle.ts @@ -0,0 +1,47 @@ +/** + * `workspaceLifecycle` domain — workspace handler lifecycle contract. + * + * Defines the `IWorkspaceLifecycleService`, the App-scope owner of the live + * workspace handler registry: one `IWorkspaceScopeHandle` per workspaceId, + * materialized on demand through `handlerFor` (create-or-get with an + * in-flight join, so concurrent sessions of one workspace never duplicate a + * handler) and never closed afterwards — handlers die with the App scope. + * A handler is addressed by `workspaceId` or by `root` (folded through the + * `workspace` catalog, which is also the local runtime's metadata source); + * the remote-runtime keying (`osBackendId` × `persistenceBackendId`) rides + * on the handler's `workspaceContext` seed as an internal abstraction only. + * Read side: `handlers.list()` and `sessions.list(workspaceId)`, plus + * `onDidMaterializeHandler` for App-scope observers that must follow every + * handler's per-handler services. There is deliberately NO App-scope + * session lifecycle entry point — session create/resume/fork lives on the + * handler's `ISessionLifecycleService`; callers compose `sessionIndex` → + * `handlerFor` → handler. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { IWorkspaceScopeHandle } from '#/_base/di/scope'; +import type { Event } from '#/_base/event'; + +export type WorkspaceRef = + | { readonly workspaceId: string; readonly root?: string } + | { readonly root: string }; + +export interface WorkspaceHandlerRegistry { + list(): readonly IWorkspaceScopeHandle[]; +} + +export interface WorkspaceSessionRegistry { + list(workspaceId: string): readonly string[]; +} + +export interface IWorkspaceLifecycleService { + readonly _serviceBrand: undefined; + + readonly onDidMaterializeHandler: Event<IWorkspaceScopeHandle>; + handlerFor(ref: WorkspaceRef): Promise<IWorkspaceScopeHandle>; + readonly handlers: WorkspaceHandlerRegistry; + readonly sessions: WorkspaceSessionRegistry; +} + +export const IWorkspaceLifecycleService: ServiceIdentifier<IWorkspaceLifecycleService> = + createDecorator<IWorkspaceLifecycleService>('workspaceLifecycleService'); diff --git a/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycleService.ts b/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycleService.ts new file mode 100644 index 000000000..16f7f7270 --- /dev/null +++ b/packages/agent-core-v2/src/app/workspaceLifecycle/workspaceLifecycleService.ts @@ -0,0 +1,151 @@ +/** + * `workspaceLifecycle` domain — `IWorkspaceLifecycleService` implementation. + * + * Holds the live handler registry (`Map<workspaceId, IWorkspaceScopeHandle>`) + * and materializes handlers through the DI scope tree, seeding each + * Workspace scope with its `workspaceContext` (identity, catalog metadata, + * the `sessions/{wd_id}` persistence scope, and the local runtime keying + * pair). `handlerFor` is create-or-get with an in-flight join keyed by + * workspaceId, so concurrent materializations of one workspace — by id or + * by any alias spelling of its root — converge on a single handler; a + * failed materialization only drops its own in-flight entry and never + * disturbs live handlers. Materialization refreshes the catalog record + * through `workspace.createOrTouch` (the same write the old per-session + * materialization performed, now once per handler) — only local workspaces + * are ever written to `workspaces.json`. Handlers are never closed: they + * die with the App scope's disposal cascade. Bound at App scope. + */ + +import { IInstantiationService } from '#/_base/di/instantiation'; +import { Service } from '#/_base/di/service'; +import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { + createScopedChildHandle, + type IWorkspaceScopeHandle, + ScopeActivation, + registerScopedService, +} from '#/_base/di/scope'; +import { IBootstrapService } from '#/app/bootstrap/bootstrap'; +import { IWorkspaceService, type Workspace } from '#/app/workspace/workspace'; +import { ErrorCodes, Error2 } from '#/errors'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; +import { + LOCAL_OS_BACKEND_ID, + LOCAL_PERSISTENCE_BACKEND_ID, + workspaceContextSeed, + type IWorkspaceContext, +} from '#/workspace/workspaceContext/workspaceContext'; +import { ISessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycle'; +import { workspacePersistenceScope } from '#/workspace/sessionLifecycle/internal/addressing'; + +import { + IWorkspaceLifecycleService, + type WorkspaceHandlerRegistry, + type WorkspaceRef, + type WorkspaceSessionRegistry, +} from './workspaceLifecycle'; + +export class WorkspaceLifecycleService extends Service implements IWorkspaceLifecycleService { + declare readonly _serviceBrand: undefined; + private readonly live = new Map<string, IWorkspaceScopeHandle>(); + private readonly materializing = new Map<string, Promise<IWorkspaceScopeHandle>>(); + private readonly _onDidMaterializeHandler = this._register( + new Emitter<IWorkspaceScopeHandle>(), + ); + readonly onDidMaterializeHandler: Event<IWorkspaceScopeHandle> = + this._onDidMaterializeHandler.event; + + readonly handlers: WorkspaceHandlerRegistry = { + list: () => [...this.live.values()], + }; + + readonly sessions: WorkspaceSessionRegistry = { + list: (workspaceId: string) => { + const handler = this.live.get(workspaceId); + if (handler === undefined) return []; + return handler.accessor + .get(ISessionLifecycleService) + .list() + .map((session) => session.id); + }, + }; + + constructor( + @IInstantiationService private readonly instantiation: IInstantiationService, + @IBootstrapService private readonly bootstrap: IBootstrapService, + @IWorkspaceService private readonly workspaces: IWorkspaceService, + @IHostEnvironment private readonly hostEnv: IHostEnvironment, + ) { + super(); + } + + async handlerFor(ref: WorkspaceRef): Promise<IWorkspaceScopeHandle> { + if ('workspaceId' in ref) { + const existing = this.live.get(ref.workspaceId); + if (existing !== undefined) return existing; + const root = ref.root ?? (await this.workspaces.get(ref.workspaceId))?.root; + if (root === undefined) { + throw new Error2( + ErrorCodes.WORKSPACE_NOT_FOUND, + `workspace ${ref.workspaceId} does not exist`, + ); + } + return this.joinMaterialization(ref.workspaceId, root); + } + const workspace = await this.workspaces.createOrTouch(ref.root); + const existing = this.live.get(workspace.id); + if (existing !== undefined) return existing; + return this.joinMaterialization(workspace.id, workspace.root, workspace); + } + + private joinMaterialization( + workspaceId: string, + root: string, + known?: Workspace, + ): Promise<IWorkspaceScopeHandle> { + const inflight = this.materializing.get(workspaceId); + if (inflight !== undefined) return inflight; + const promise = this.doMaterialize(workspaceId, root, known).finally(() => + this.materializing.delete(workspaceId), + ); + this.materializing.set(workspaceId, promise); + return promise; + } + + private async doMaterialize( + workspaceId: string, + root: string, + known?: Workspace, + ): Promise<IWorkspaceScopeHandle> { + const workspace = known ?? (await this.workspaces.createOrTouch(root)); + const ctx: IWorkspaceContext = { + _serviceBrand: undefined, + workspaceId, + cwd: workspace.root, + source: 'local', + meta: workspace, + persistenceScope: workspacePersistenceScope(this.bootstrap.scope('sessions'), workspaceId), + osBackendId: LOCAL_OS_BACKEND_ID, + persistenceBackendId: LOCAL_PERSISTENCE_BACKEND_ID, + }; + await this.hostEnv.ready; + const handle = createScopedChildHandle( + this.instantiation, + LifecycleScope.Workspace, + workspaceId, + { seeds: workspaceContextSeed(ctx) }, + ) as IWorkspaceScopeHandle; + this.live.set(workspaceId, handle); + this._onDidMaterializeHandler.fire(handle); + return handle; + } +} + +registerScopedService( + LifecycleScope.App, + IWorkspaceLifecycleService, + WorkspaceLifecycleService, + ScopeActivation.OnScopeCreated, + 'workspaceLifecycle', +); diff --git a/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessions.ts b/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessions.ts index b7c195d96..77698a652 100644 --- a/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessions.ts +++ b/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessions.ts @@ -1,3 +1,14 @@ +/** + * `workspaceSessions` domain — workspace ↔ session query contract. + * + * Defines `IWorkspaceSessions`, an App-scope read facade answering + * workspace-centric queries over the session index: the most recent sessions + * of a workspace and its total session count. Every query first folds the + * workspace id through `IWorkspaceAliases` so legacy split buckets (one + * directory, several id spellings) answer as one workspace. Read-only and + * JSON-in/JSON-out so it is directly exposable over the wire. App-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { SessionSummary } from '#/app/sessionIndex/sessionIndex'; diff --git a/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessionsService.ts b/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessionsService.ts index 5531f8d7d..fd9b9fca1 100644 --- a/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessionsService.ts +++ b/packages/agent-core-v2/src/app/workspaceSessions/workspaceSessionsService.ts @@ -1,3 +1,14 @@ +/** + * `workspaceSessions` domain — `IWorkspaceSessions` implementation. + * + * Answers workspace-centric read queries by composing the alias resolver + * (`workspaceAliases`) with the persisted session index (`sessionIndex`): + * every query expands the workspace id to its full alias set first, so legacy + * split buckets count once for the workspace, not per bucket. The + * recent-sessions list is capped at `RECENT_SESSIONS_LIMIT`; the count covers + * archived sessions too. Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -21,6 +32,9 @@ export class WorkspaceSessionsService implements IWorkspaceSessions { } async count(workspaceId: string): Promise<number> { + // One set-query over the alias set (legacy split buckets): a single merged + // count cannot double-count, and a singleton set behaves exactly as + // before. const workspaceIds = await this.aliases.resolveAliasIds(workspaceId); return this.index.count({ workspaceIds, includeArchived: true }); } diff --git a/packages/agent-core-v2/src/debug/debugCascade.ts b/packages/agent-core-v2/src/debug/debugCascade.ts index be4eef72d..0cac70b67 100644 --- a/packages/agent-core-v2/src/debug/debugCascade.ts +++ b/packages/agent-core-v2/src/debug/debugCascade.ts @@ -1,7 +1,32 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `debug` domain — `IDebugCascadeService`: cascade history, waiting area, and + * triggers (L5 debug surface, plan §5.11). + * + * Public contract. `history()` folds every engine's history ring of the scope + * tree (each entry tagged with its orchestrating scope's path); `pending()` + * reports the waiting area and the sticky-failed units per scope. The + * triggers address a unit by `(scopePath, token)` and drive the kernel's + * public cascade entries: + * + * - `unprovide` — registration removal through the container's + * registry-level `unprovide` (the same entry business code calls); + * - `update` — restart: `cascade.update` without a config, or a config + * patch + reload through the fiber host when `config` is given; + * - `dispose` — the plan §5.11 `dispose(handle)` spelling: an awaited + * cascade `unprovide` submission. The kernel exposes no retire-only entry, + * so `dispose` and `unprovide` reach the same end state (registration + * removed, dependents cascaded to the waiting area); they differ only in + * the entry exercised. Both settle the cascade before returning. + * + * The service is also the producer of the `event.di.unit_changed` global + * event: while active it watches every engine of the tree (including + * late-joined scopes) and republishes unit state transitions on + * `IEventService`. Bound at App scope. All payloads are JSON-serializable + * wire data. + */ + import type { CascadeAction, UnitState } from '#/_base/di/cascadeEngine'; import { createDecorator } from '#/_base/di/instantiation'; -import { Event2 } from '#/app/event/event2'; export interface DebugCascadeEntry { readonly scopePath: string; @@ -33,6 +58,8 @@ export interface DebugPendingGroup { readonly failed: DebugFailedUnit[]; } +export const DI_UNIT_CHANGED_EVENT = 'event.di.unit_changed'; + export interface DiUnitChangedPayload { readonly scope: string; readonly token: string; @@ -40,15 +67,6 @@ export interface DiUnitChangedPayload { readonly error?: string; } -export class DiUnitChanged extends Event2<{ readonly payload: DiUnitChangedPayload }> { - static override readonly type = 'event.di.unit_changed'; -} -export interface DiUnitChanged { - readonly payload: DiUnitChangedPayload; -} - -export const DI_UNIT_CHANGED_EVENT = DiUnitChanged.type; - export interface IDebugCascadeService { readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/debug/debugCascadeService.ts b/packages/agent-core-v2/src/debug/debugCascadeService.ts index ad01fa20e..e34e9c9bd 100644 --- a/packages/agent-core-v2/src/debug/debugCascadeService.ts +++ b/packages/agent-core-v2/src/debug/debugCascadeService.ts @@ -1,3 +1,20 @@ +/** + * `debug` domain — `IDebugCascadeService` implementation. + * + * Read paths fold the kernel's debug accessors (`cascadeTree.engines` / + * `history` / `pendingSnapshot` / `unitsSnapshot`); the triggers only call the + * kernel's public entries (`unprovide` / `cascade.update` / `cascade.submit`) + * after resolving `(scopePath, token)` to a live container and identifier. + * Publishes `event.di.unit_changed` through `event` (`IEventService`) for + * every unit state transition of the tree. Bound at App scope, activated with + * the scope so the event feed is always on. + * + * NOTE: does not extend `Disposable` — the wire trigger `dispose(scopePath, + * token)` collides with `IDisposable.dispose`; the no-arg overload below is + * the framework teardown (the container retires this unit by calling + * `dispose()`), the two-arg overload is the trigger. + */ + import type { CascadeEngine } from '#/_base/di/cascadeEngine'; import { IInstantiationService, @@ -11,7 +28,7 @@ import { LifecycleScope } from '#/app/scopes'; import { Error2, ErrorCodes } from '#/errors'; import { - DiUnitChanged, + DI_UNIT_CHANGED_EVENT, IDebugCascadeService, type DebugCascadeEntry, type DebugFailedUnit, @@ -163,7 +180,7 @@ export class DebugCascadeService implements IDebugCascadeService { state: change.state, error: change.error, }; - this.events.publish(new DiUnitChanged({ payload })); + this.events.publish({ type: DI_UNIT_CHANGED_EVENT, payload }); }), ); } diff --git a/packages/agent-core-v2/src/debug/debugGraph.ts b/packages/agent-core-v2/src/debug/debugGraph.ts index 02c98fe2b..dcb23d15c 100644 --- a/packages/agent-core-v2/src/debug/debugGraph.ts +++ b/packages/agent-core-v2/src/debug/debugGraph.ts @@ -1,3 +1,14 @@ +/** + * `debug` domain — `IDebugGraphService`: the persistent dependency DAG (L5 + * debug surface, plan §5.11). + * + * Public contract. `graph()` renders the tree-global dependency graph: nodes + * are every registered token of every container (union the edge endpoints, so + * collection tokens that own no registration still appear), edges are the live + * instance edges (cross-tree) and collection edges, told apart by `kind`. + * Bound at App scope. All payloads are JSON-serializable wire data. + */ + import type { UnitState } from '#/_base/di/cascadeEngine'; import type { DependencyEdgeKind } from '#/_base/di/dependencyGraph'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/debug/debugGraphService.ts b/packages/agent-core-v2/src/debug/debugGraphService.ts index 1bd2e49d0..5b1f6af6a 100644 --- a/packages/agent-core-v2/src/debug/debugGraphService.ts +++ b/packages/agent-core-v2/src/debug/debugGraphService.ts @@ -1,3 +1,12 @@ +/** + * `debug` domain — `IDebugGraphService` implementation. + * + * Read-only introspection over the kernel's debug accessors (`children` / + * `servicesSnapshot` / `unitsSnapshot` / `dependencyGraph.edges`); no kernel + * state is mutated. Bound at App scope; the injected container is the tree + * root (the dependency graph is shared by the whole tree). + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import type { InstantiationService } from '#/_base/di/instantiationService'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/debug/debugLedger.ts b/packages/agent-core-v2/src/debug/debugLedger.ts index da61a7b85..bbcbd8681 100644 --- a/packages/agent-core-v2/src/debug/debugLedger.ts +++ b/packages/agent-core-v2/src/debug/debugLedger.ts @@ -1,3 +1,14 @@ +/** + * `debug` domain — `IDebugLedgerService`: the unit tree = ledger tree (L5 + * debug surface, plan §5.11). + * + * Public contract. `tree()` walks the whole container tree under the App + * root; every node carries the container's scope path and label, its units + * (the service registrations joined with the cascade engine's five-state + * unit snapshots) and its ledger entries verbatim (child ledgers already + * recurse). Bound at App scope. All payloads are JSON-serializable wire data. + */ + import type { UnitState } from '#/_base/di/cascadeEngine'; import { createDecorator } from '#/_base/di/instantiation'; import type { LedgerEntryInfo } from '#/_base/lifecycle/ledger'; diff --git a/packages/agent-core-v2/src/debug/debugLedgerService.ts b/packages/agent-core-v2/src/debug/debugLedgerService.ts index 6499e14cd..ad4b988c7 100644 --- a/packages/agent-core-v2/src/debug/debugLedgerService.ts +++ b/packages/agent-core-v2/src/debug/debugLedgerService.ts @@ -1,3 +1,11 @@ +/** + * `debug` domain — `IDebugLedgerService` implementation. + * + * Read-only introspection over the kernel's debug accessors (`children` / + * `servicesSnapshot` / `unitsSnapshot` / `ledger.entries`); no kernel state is + * mutated. Bound at App scope; the injected container is the tree root. + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import type { InstantiationService } from '#/_base/di/instantiationService'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/debug/errors.ts b/packages/agent-core-v2/src/debug/errors.ts index a7d832e03..d5a1dd24a 100644 --- a/packages/agent-core-v2/src/debug/errors.ts +++ b/packages/agent-core-v2/src/debug/errors.ts @@ -1,3 +1,7 @@ +/** + * `debug` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const DebugErrors = { diff --git a/packages/agent-core-v2/src/debug/index.ts b/packages/agent-core-v2/src/debug/index.ts index e7809d003..6d40dd821 100644 --- a/packages/agent-core-v2/src/debug/index.ts +++ b/packages/agent-core-v2/src/debug/index.ts @@ -1,3 +1,8 @@ +/** + * `debug` domain barrel — L5 debug surface (plan §5.11): ledger tree, + * dependency graph, and cascade history / waiting area / triggers. + */ + export * from './debugLedger'; export * from './debugGraph'; export * from './debugCascade'; diff --git a/packages/agent-core-v2/src/debug/scopeTree.ts b/packages/agent-core-v2/src/debug/scopeTree.ts index a25a6af39..d490564c4 100644 --- a/packages/agent-core-v2/src/debug/scopeTree.ts +++ b/packages/agent-core-v2/src/debug/scopeTree.ts @@ -1,3 +1,14 @@ +/** + * `debug` domain — container-tree traversal helpers shared by the debug + * services. + * + * Scope paths join `debugLabel` segments from the tree root + * (`app` / `app/workspace:<id>` / …); an unlabeled container falls back to its + * tree sequence (`#n`). Resolution walks the live tree and compares whole + * paths, so labels never need to be separator-safe, and a path re-resolves to + * the same container for the process lifetime. + */ + import type { CascadeEngine } from '#/_base/di/cascadeEngine'; import type { InstantiationService } from '#/_base/di/instantiationService'; diff --git a/packages/agent-core-v2/src/env.d.ts b/packages/agent-core-v2/src/env.d.ts index 88d404d0a..1fcde7169 100644 --- a/packages/agent-core-v2/src/env.d.ts +++ b/packages/agent-core-v2/src/env.d.ts @@ -1,3 +1,5 @@ +// Raw-string imports for prompt sources. Vite/Vitest handles `?raw` natively. + declare module '*?raw' { const content: string; export default content; diff --git a/packages/agent-core-v2/src/errors.ts b/packages/agent-core-v2/src/errors.ts index 54018cf97..82cc6a58f 100644 --- a/packages/agent-core-v2/src/errors.ts +++ b/packages/agent-core-v2/src/errors.ts @@ -1,3 +1,9 @@ +/** + * Error facade — aggregates every domain's error contribution into the unified + * `ErrorCodes` const and re-exports the error primitives. Importing this + * module registers every domain's codes. + */ + import { CoreErrors } from '#/_base/errors/codes'; import { AgentLifecycleErrors } from '#/session/agentLifecycle/errors'; import { AuthErrors } from '#/app/auth/errors'; @@ -5,13 +11,12 @@ import { TaskErrors } from '#/agent/task/errors'; import { ProtocolErrors } from '#/kosong/protocol/errors'; import { ConfigErrors } from '#/app/config/errors'; import { CapabilityErrors } from '#/app/capability/errors'; -import { CronErrors } from '#/features/cron/errors'; +import { CronErrors } from '#/app/cron/errors'; import { DebugErrors } from '#/debug/errors'; -import { EventErrors } from '#/app/event/errors'; import { FileErrors } from '#/app/file/fileService'; import { FsErrors } from '#/workspace/workspaceFs/internal/errors'; import { FullCompactionErrors } from '#/agent/fullCompaction/errors'; -import { GoalErrors } from '#/features/goal/errors'; +import { GoalErrors } from '#/agent/goal/errors'; import { LoopErrors } from '#/agent/loop/errors'; import { McpErrors } from '#/mcpCore/errors'; import { ModelCatalogErrors } from '#/kosong/model/errors'; @@ -23,8 +28,7 @@ import { PromptErrors } from '#/agent/prompt/errors'; import { ModelsDevImportErrors } from '#/app/kosongConfig/errors'; import { SessionExportErrors } from '#/app/sessionExport/errors'; import { SessionErrors } from '#/session/errors'; -import { SkillErrors } from '#/features/skill/catalog/errors'; -import { StateErrors } from '#/state/errors'; +import { SkillErrors } from '#/app/skillCatalog/errors'; import { StorageErrors } from '#/persistence/interface/storage'; import { TerminalErrors } from '#/os/interface/terminalErrors'; import { UsageErrors } from '#/agent/usage/errors'; @@ -43,12 +47,12 @@ export { TaskErrors } from '#/agent/task/errors'; export { ProtocolErrors } from '#/kosong/protocol/errors'; export { ConfigErrors } from '#/app/config/errors'; export { CapabilityErrors } from '#/app/capability/errors'; -export { CronErrors } from '#/features/cron/errors'; +export { CronErrors } from '#/app/cron/errors'; export { DebugErrors } from '#/debug/errors'; export { FileErrors } from '#/app/file/fileService'; export { FsErrors } from '#/workspace/workspaceFs/internal/errors'; export { FullCompactionErrors } from '#/agent/fullCompaction/errors'; -export { GoalErrors } from '#/features/goal/errors'; +export { GoalErrors } from '#/agent/goal/errors'; export { LoopErrors } from '#/agent/loop/errors'; export { McpErrors } from '#/mcpCore/errors'; export { ModelCatalogErrors } from '#/kosong/model/errors'; @@ -60,15 +64,13 @@ export { PromptErrors } from '#/agent/prompt/errors'; export { ModelsDevImportErrors } from '#/app/kosongConfig/errors'; export { SessionExportErrors } from '#/app/sessionExport/errors'; export { SessionErrors } from '#/session/errors'; -export { SkillErrors } from '#/features/skill/catalog/errors'; +export { SkillErrors } from '#/app/skillCatalog/errors'; export { StorageErrors } from '#/persistence/interface/storage'; export { TerminalErrors } from '#/os/interface/terminalErrors'; export { UsageErrors } from '#/agent/usage/errors'; export { WebErrors } from '#/app/web/errors'; export { WireErrors } from '#/wire/errors'; export { WorkspaceErrors } from '#/app/workspace/errors'; -export { EventErrors } from '#/app/event/errors'; -export { StateErrors } from '#/state/errors'; export const ErrorCodes = { ...CoreErrors.codes, @@ -102,8 +104,6 @@ export const ErrorCodes = { ...WebErrors.codes, ...WireErrors.codes, ...WorkspaceErrors.codes, - ...EventErrors.codes, - ...StateErrors.codes, } as const; export type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes]; diff --git a/packages/agent-core-v2/src/features/btw/btw.ts b/packages/agent-core-v2/src/features/btw/btw.ts index 00a09e751..85620d347 100644 --- a/packages/agent-core-v2/src/features/btw/btw.ts +++ b/packages/agent-core-v2/src/features/btw/btw.ts @@ -1,3 +1,12 @@ +/** + * `btw` domain — side-question ("by the way") child agent contract. + * + * A `btw` agent is a lightweight fork of the main agent used for a side-channel + * conversation: it inherits the parent's profile and context, but all tool calls + * are disabled and a side-channel system reminder is appended so it answers with + * text only. Follow-up turns reuse the same child agent. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export const TOOL_CALL_DISABLED_MESSAGE = diff --git a/packages/agent-core-v2/src/features/btw/btwFeature.ts b/packages/agent-core-v2/src/features/btw/btwFeature.ts index 1127b786a..c47d509f4 100644 --- a/packages/agent-core-v2/src/features/btw/btwFeature.ts +++ b/packages/agent-core-v2/src/features/btw/btwFeature.ts @@ -1,3 +1,12 @@ +/** + * `btw` domain — `BtwFeature`: the side-question ("by the way") capability + * assembled as one App-scope Feature unit. + * + * Contributes the per-Session `ISessionBtwService` through the `features` + * base-class seams; retracting the unit withdraws it across the scope tree. + * Registered into the feature table at import. + */ + import { LifecycleScope } from '#/app/scopes'; import { Feature } from '#/features/feature'; import { registerFeature } from '#/features/featureRegistry'; diff --git a/packages/agent-core-v2/src/features/btw/btwService.ts b/packages/agent-core-v2/src/features/btw/btwService.ts index d91901d1a..74f45a0d1 100644 --- a/packages/agent-core-v2/src/features/btw/btwService.ts +++ b/packages/agent-core-v2/src/features/btw/btwService.ts @@ -1,10 +1,23 @@ -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; +/** + * `btw` domain — `ISessionBtwService` implementation. + * + * Forks the main agent into a side-question child: inherits profile/context via + * `IAgentLifecycleService.fork`, then disables tool calls via an + * `onBeforeExecuteTool` veto listener (blocks every tool call with the + * `toolApproval.formatDenyMessage`-formatted TOOL_CALL_DISABLED_MESSAGE) and + * appends the side-channel system reminder. Contributed at Session scope by + * `BtwFeature` (`features/btw/btwFeature`) — `fork('main')` is a + * session-level operation, so the service injects the session's + * `IAgentLifecycleService` directly rather than resolving it through the main + * agent's accessor. Callers materialize the main agent first; forking a + * missing source throws. + */ + +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ErrorCodes, Error2 } from '#/errors'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { ISessionBtwService, SIDE_QUESTION_SYSTEM_REMINDER, TOOL_CALL_DISABLED_MESSAGE } from './btw'; @@ -12,19 +25,17 @@ export class SessionBtwService implements ISessionBtwService { declare readonly _serviceBrand: undefined; constructor( - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentLifecycleService private readonly lifecycle: IAgentLifecycleService, ) {} async start(): Promise<string> { - const main = this.agentLifecycle.handleOf(MAIN_AGENT_ID); - if (main === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found'); - } - const childContext = await this.agentLifecycle.fork(main.accessor.get(IAgentScopeContext).agentContext); - const child = this.agentLifecycle.handleOf(childContext.agentId)!; - this.agentLifecycle - .resolve(childContext, AgentReminder) - .notify(SIDE_QUESTION_SYSTEM_REMINDER, { variant: 'btw' }); + const child = await this.lifecycle.fork('main'); + child.accessor + .get(IAgentSystemReminderService) + ?.appendSystemReminder(SIDE_QUESTION_SYSTEM_REMINDER, { + kind: 'system_trigger', + name: 'btw', + }); const reason = child.accessor.get(IAgentToolApprovalService)?.formatDenyMessage( TOOL_CALL_DISABLED_MESSAGE, @@ -34,6 +45,6 @@ export class SessionBtwService implements ISessionBtwService { ?.onBeforeExecuteTool((event) => { event.veto(denyToolExecution(reason)); }); - return childContext.agentId; + return child.id; } } diff --git a/packages/agent-core-v2/src/features/cron/cronAgentRuntime.ts b/packages/agent-core-v2/src/features/cron/cronAgentRuntime.ts deleted file mode 100644 index bc0b6c9fa..000000000 --- a/packages/agent-core-v2/src/features/cron/cronAgentRuntime.ts +++ /dev/null @@ -1,533 +0,0 @@ -import { ulid } from 'ulid'; -import { assign, fromCallback, sendTo, setup, type Snapshot } from 'xstate'; - -import { IntervalTimer } from '#/_base/utils/timer'; -import type { CronJobOrigin, CronMissedOrigin, ContextMessage } from '#/agent/contextMemory/types'; -import { IAgentLoopService, type Turn } from '#/agent/loop/loop'; -import { IAgentPromptService } from '#/agent/prompt/prompt'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, - type AgentRuntimeRestoreEvent, -} from '#/agent/runtime/agentRuntime'; -import { IConfigService } from '#/app/config/config'; -import { type ClockSources, resolveClockSources, SYSTEM_CLOCKS } from '#/features/cron/internal/clock'; -import { type CronConfig, CRON_SECTION, DEFAULT_CRON_CONFIG } from '#/features/cron/configSection'; -import { computeNextCronRun, parseCronExpression, type ParsedCronExpression } from '#/features/cron/internal/cron-expr'; -import type { CronTask, CronTaskInit } from '#/features/cron/cronTask'; -import { renderCronFireXml } from '#/features/cron/internal/format'; -import { jitteredNextCronRunMs, oneShotJitteredNextCronRunMs } from '#/features/cron/internal/jitter'; -import type { CronDeletedEvent, CronScheduledEvent } from '#/app/telemetry/events'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { BugIndicatingError } from '#/errors'; -import type { ContentPart } from '#/kosong/contract/message'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; - -import { CronAdd, CronCursor, CronDelete, CronFired, type CronModelState } from './cronOps'; - -const STALE_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1000; -const DEFAULT_POLL_INTERVAL_MS = 1_000; -const MAX_COALESCE_ITERATIONS = 10_000; -const CRON_ID_REGEX: RegExp = /^(?:[0-9a-f]{8}|[0-9A-HJKMNP-TV-Z]{26})$/i; -const MAX_ID_ATTEMPTS = 8; - -export const CRON_SCHEDULED = 'cron_scheduled' as const; -export const CRON_FIRED = 'cron_fired' as const; -export const CRON_MISSED = 'cron_missed' as const; -export const CRON_DELETED = 'cron_deleted' as const; - -interface CronActorContext { - readonly tasks: CronModelState; - readonly runtime: AgentRuntimeContext<CronModelState>; -} - -interface CronCommitEvent { - readonly type: 'cron.commit'; - readonly tasks: CronModelState; -} - -interface CronTickEvent { - readonly type: 'cron.tick'; - readonly resolve?: () => void; - readonly reject?: (error: unknown) => void; -} - -type CronActorEvent = CronCommitEvent | AgentRuntimeRestoreEvent | CronTickEvent; -type CronActorSnapshot = Snapshot<unknown> & { readonly context: CronActorContext }; - -interface CronEffectState { - clocks: ClockSources; - readonly parsedCache: Map<string, ParsedCronExpression>; - readonly lastSeenAt: Map<string, number>; - readonly seededFromStore: Set<string>; - readonly inFlight: Set<string>; -} - -function configOf(runtime: AgentRuntimeContext<CronModelState>): IConfigService { - return runtime.get(IConfigService); -} - -function cronConfigOf(runtime: AgentRuntimeContext<CronModelState>): CronConfig { - return configOf(runtime).get<CronConfig>(CRON_SECTION) ?? DEFAULT_CRON_CONFIG; -} - -function clocksOf(runtime: AgentRuntimeContext<CronModelState>): ClockSources { - const config = cronConfigOf(runtime); - return resolveClockSources(config.clock, config.debug) ?? SYSTEM_CLOCKS; -} - -function telemetryOf(runtime: AgentRuntimeContext<CronModelState>): ITelemetryService { - return runtime.get(ITelemetryService); -} - -function debugLog(runtime: AgentRuntimeContext<CronModelState>, message: string): void { - if (cronConfigOf(runtime).debug) process.stderr.write(`[cron/session] ${message}\n`); -} - -function isStaleAt( - runtime: AgentRuntimeContext<CronModelState>, - task: CronTask, - now: number, -): boolean { - if (cronConfigOf(runtime).noStale) return false; - if (task.recurring === false) return false; - const age = now - task.createdAt; - return Number.isFinite(age) && age >= STALE_THRESHOLD_MS; -} - -function computeJitteredNext( - runtime: AgentRuntimeContext<CronModelState>, - task: CronTask, - parsed: ParsedCronExpression, - baseMs: number, -): number | null { - const ideal = computeNextCronRun(parsed, baseMs); - if (ideal === null) return null; - const noJitter = cronConfigOf(runtime).noJitter; - if (task.recurring === false) { - return oneShotJitteredNextCronRunMs(task, ideal, undefined, noJitter); - } - return jitteredNextCronRunMs(task, parsed, ideal, undefined, noJitter); -} - -function parsedCron(state: CronEffectState, expression: string): ParsedCronExpression { - const cached = state.parsedCache.get(expression); - if (cached !== undefined) return cached; - const parsed = parseCronExpression(expression); - state.parsedCache.set(expression, parsed); - return parsed; -} - -function countCoalesced( - runtime: AgentRuntimeContext<CronModelState>, - task: CronTask, - parsed: ParsedCronExpression, - firstFireMs: number, - nowMs: number, -): { count: number; lastDueMs: number } { - let count = 1; - let cursor = firstFireMs; - let lastDueMs = firstFireMs; - const noJitter = cronConfigOf(runtime).noJitter; - while (count < MAX_COALESCE_ITERATIONS) { - const next = computeNextCronRun(parsed, cursor); - if (next === null || next > nowMs) break; - const jitteredNext = task.recurring === false - ? oneShotJitteredNextCronRunMs(task, next, undefined, noJitter) - : jitteredNextCronRunMs(task, parsed, next, undefined, noJitter); - if (jitteredNext > nowMs) break; - count += 1; - cursor = next; - lastDueMs = next; - } - return { count, lastDueMs }; -} - -function removeTasks( - runtime: AgentRuntimeContext<CronModelState>, - ids: readonly string[], -): readonly string[] { - const removed = ids.filter((id) => runtime.getState().has(id)); - if (removed.length > 0) void runtime.dispatch(new CronDelete({ ids: removed })); - return removed; -} - -function deliverFire( - runtime: AgentRuntimeContext<CronModelState>, - task: CronTask, - context: { readonly coalescedCount: number; readonly firedAt: number }, -): Promise<boolean> { - const origin: CronJobOrigin = { - kind: 'cron_job', - jobId: task.id, - cron: task.cron, - recurring: task.recurring !== false, - coalescedCount: context.coalescedCount, - stale: isStaleAt(runtime, task, context.firedAt), - }; - const message: ContextMessage = { - role: 'user', - content: [{ type: 'text', text: renderCronFireXml(origin, task.prompt) }], - toolCalls: [], - origin, - }; - const buffered = runtime.get(IAgentLoopService).status().state === 'running'; - let launched: Promise<unknown>; - try { - launched = runtime.get(IAgentPromptService).inject(message); - } catch (error) { - debugLog(runtime, `steer threw for task ${task.id}: ${error instanceof Error ? error.message : String(error)}`); - return Promise.resolve(false); - } - return launched.then( - () => { - void runtime.dispatch(new CronFired({ origin, prompt: task.prompt })); - telemetryOf(runtime).track2(CRON_FIRED, { - recurring: task.recurring !== false, - coalesced_count: context.coalescedCount, - stale: origin.stale, - buffered, - }); - return true; - }, - (error: unknown) => { - debugLog(runtime, `steer launch rejected for task ${task.id}: ${error instanceof Error ? error.message : String(error)}`); - return false; - }, - ); -} - -async function processDue( - runtime: AgentRuntimeContext<CronModelState>, - state: CronEffectState, - task: CronTask, - now: number, -): Promise<void> { - if (state.inFlight.has(task.id)) return; - let parsed: ParsedCronExpression; - try { - parsed = parsedCron(state, task.cron); - } catch (error) { - debugLog(runtime, `tick failed to parse cron for task ${task.id}: ${error instanceof Error ? error.message : String(error)}`); - return; - } - if ( - !state.seededFromStore.has(task.id) && - task.lastFiredAt !== undefined && - Number.isFinite(task.lastFiredAt) && - task.lastFiredAt <= now && - !state.lastSeenAt.has(task.id) - ) { - state.lastSeenAt.set(task.id, task.lastFiredAt); - } - state.seededFromStore.add(task.id); - const seen = state.lastSeenAt.get(task.id); - const baseFromMs = seen !== undefined && seen > task.createdAt ? seen : task.createdAt; - const nextFireAt = computeJitteredNext(runtime, task, parsed, baseFromMs); - if (nextFireAt === null || now < nextFireAt) return; - const ideal = computeNextCronRun(parsed, baseFromMs); - let coalescedCount = 1; - let lastDueMs: number | null = null; - if (task.recurring !== false && ideal !== null) { - const result = countCoalesced(runtime, task, parsed, ideal, now); - coalescedCount = Math.max(1, result.count); - lastDueMs = result.lastDueMs; - } - state.inFlight.add(task.id); - const firedAt = state.clocks.wallNow(); - let delivered = false; - try { - delivered = await deliverFire(runtime, task, { coalescedCount, firedAt }); - } catch (error) { - debugLog(runtime, `deliverDue threw for task ${task.id}: ${error instanceof Error ? error.message : String(error)}`); - } finally { - state.inFlight.delete(task.id); - } - if (!delivered) return; - if (task.recurring === false || isStaleAt(runtime, task, firedAt)) { - const removed = removeTasks(runtime, [task.id]); - state.lastSeenAt.delete(task.id); - state.seededFromStore.delete(task.id); - if (task.recurring !== false && removed.length > 0) { - const properties: CronDeletedEvent = { task_id: task.id, agent_id: undefined }; - telemetryOf(runtime).track2(CRON_DELETED, properties); - } - return; - } - const advancedTo = lastDueMs ?? now; - state.lastSeenAt.set(task.id, advancedTo); - if (runtime.getState().has(task.id)) { - void runtime.dispatch(new CronCursor({ id: task.id, lastFiredAt: advancedTo })); - } -} - -async function tickCron( - runtime: AgentRuntimeContext<CronModelState>, - state: CronEffectState, -): Promise<void> { - await configOf(runtime).ready; - if (cronConfigOf(runtime).disabled || runtime.getState().size === 0) return; - if (runtime.get(IAgentLoopService).status().state === 'running') return; - const now = state.clocks.wallNow(); - await Promise.all([...runtime.getState().values()].map((task) => processDue(runtime, state, task, now))); -} - -const cronEffects = fromCallback(({ - input, - receive, - sendBack, -}: { - input: { - readonly runtime: AgentRuntimeContext<CronModelState>; - readonly restore: AgentRuntimeRestoreEvent; - }; - receive: (listener: (event: CronTickEvent) => void) => void; - sendBack: (event: CronActorEvent) => void; -}) => { - if (input.runtime.agent.agentId !== MAIN_AGENT_ID) return; - const timer = new IntervalTimer({ unref: true }); - const state: CronEffectState = { - clocks: SYSTEM_CLOCKS, - parsedCache: new Map(), - lastSeenAt: new Map(), - seededFromStore: new Set(), - inFlight: new Set(), - }; - let disposed = false; - let signalHandler: NodeJS.SignalsListener | undefined; - receive((event) => { - void tickCron(input.runtime, state).then(event.resolve, event.reject); - }); - input.restore.waitUntil(configOf(input.runtime).ready.then(() => { - if (disposed) return; - const config = cronConfigOf(input.runtime); - state.clocks = resolveClockSources(config.clock, config.debug) ?? SYSTEM_CLOCKS; - const poll = config.manualTick ? null : config.pollIntervalMs; - const interval = poll === undefined ? DEFAULT_POLL_INTERVAL_MS : poll; - if (interval !== null && interval !== 0) { - timer.cancelAndSet(() => { sendBack({ type: 'cron.tick' }); }, interval); - } - if (process.platform !== 'win32' && config.manualTick) { - signalHandler = () => { sendBack({ type: 'cron.tick' }); }; - process.on('SIGUSR1', signalHandler); - } - })); - return () => { - disposed = true; - timer.dispose(); - if (signalHandler !== undefined) process.off('SIGUSR1', signalHandler); - state.inFlight.clear(); - state.lastSeenAt.clear(); - state.seededFromStore.clear(); - state.parsedCache.clear(); - }; -}); - -function nextFireFor( - runtime: AgentRuntimeContext<CronModelState>, - task: CronTask, -): number | null { - try { - const clocks = clocksOf(runtime); - const parsed = parseCronExpression(task.cron); - const persistedCursor = - task.lastFiredAt !== undefined && - Number.isFinite(task.lastFiredAt) && - task.lastFiredAt <= clocks.wallNow() - ? task.lastFiredAt - : undefined; - const baseFromMs = - persistedCursor !== undefined && persistedCursor > task.createdAt - ? persistedCursor - : task.createdAt; - return computeJitteredNext(runtime, task, parsed, baseFromMs); - } catch (error) { - debugLog(runtime, `nextFireFor skipping task ${task.id}: ${error instanceof Error ? error.message : String(error)}`); - return null; - } -} - -export class CronRuntime { - readonly isEnabled = true; - - constructor(private readonly runtime: AgentRuntimeContext<CronModelState>) {} - - now(): number { - return clocksOf(this.runtime).wallNow(); - } - - isDisabled(): boolean { - return cronConfigOf(this.runtime).disabled; - } - - addTask(init: CronTaskInit): CronTask { - const tasks = this.runtime.getState(); - let id: string | undefined; - for (let attempt = 0; attempt < MAX_ID_ATTEMPTS; attempt += 1) { - const candidate = ulid(); - if (CRON_ID_REGEX.test(candidate) && !tasks.has(candidate)) { - id = candidate; - break; - } - } - if (id === undefined) { - throw new BugIndicatingError(`SessionCronService: failed to generate a unique ULID after ${MAX_ID_ATTEMPTS} attempts`); - } - const task: CronTask = { ...init, id, createdAt: this.now() }; - void this.runtime.dispatch(new CronAdd({ task })); - return task; - } - - removeTasks(ids: readonly string[]): readonly string[] { - return removeTasks(this.runtime, ids); - } - - getTask(id: string): CronTask | undefined { - return this.runtime.getState().get(id); - } - - list(): readonly CronTask[] { - return [...this.runtime.getState().values()]; - } - - isStale(task: CronTask): boolean { - return isStaleAt(this.runtime, task, this.now()); - } - - getNextFireTime(): number | null { - let min: number | null = null; - for (const task of this.runtime.getState().values()) { - const next = nextFireFor(this.runtime, task); - if (next !== null && (min === null || next < min)) min = next; - } - return min; - } - - getNextFireForTask(taskId: string): number | null { - const task = this.runtime.getState().get(taskId); - return task === undefined ? null : nextFireFor(this.runtime, task); - } - - computeDisplayNextFire( - task: CronTask, - parsed: ParsedCronExpression, - idealMs: number, - ): number | null { - const noJitter = cronConfigOf(this.runtime).noJitter; - if (task.recurring === false) { - return oneShotJitteredNextCronRunMs(task, idealMs, undefined, noJitter); - } - return jitteredNextCronRunMs(task, parsed, idealMs, undefined, noJitter); - } - - handleMissed( - tasks: readonly CronTask[], - renderMissedNotification: (tasks: readonly CronTask[]) => readonly ContentPart[], - ): Turn | undefined { - if (tasks.length === 0) return undefined; - const origin: CronMissedOrigin = { kind: 'cron_missed', count: tasks.length }; - const message: ContextMessage = { - role: 'user', - content: [...renderMissedNotification(tasks)], - toolCalls: [], - origin, - }; - void this.runtime.get(IAgentPromptService).inject(message).catch(() => {}); - telemetryOf(this.runtime).track2(CRON_MISSED, { count: tasks.length }); - return undefined; - } - - emitScheduled(task: CronTask, agentId?: string): void { - const properties: CronScheduledEvent = { recurring: task.recurring !== false, agent_id: agentId }; - telemetryOf(this.runtime).track2(CRON_SCHEDULED, properties); - } - - emitDeleted(taskId: string, agentId?: string): void { - const properties: CronDeletedEvent = { task_id: taskId, agent_id: agentId }; - telemetryOf(this.runtime).track2(CRON_DELETED, properties); - } - - tick(): Promise<void> { - return new Promise<void>((resolve, reject) => { - this.runtime.send({ type: 'cron.tick', resolve, reject }); - }); - } -} - -const cronActorLogic = setup({ - types: {} as { - context: CronActorContext; - input: AgentRuntimeContext<CronModelState>; - events: CronActorEvent; - }, - actors: { cronEffects }, -}).createMachine({ - context: ({ input }) => ({ tasks: new Map(), runtime: input }), - initial: 'beforeRestore', - states: { - beforeRestore: { - on: { - 'runtime.restore': 'active', - 'cron.tick': { - actions: ({ event }) => { event.reject?.(new Error('Cron runtime is not restored')); }, - }, - }, - }, - active: { - invoke: { - id: 'cronEffects', - src: 'cronEffects', - input: ({ context, event }) => ({ - runtime: context.runtime, - restore: event as AgentRuntimeRestoreEvent, - }), - }, - on: { - 'cron.tick': { actions: sendTo('cronEffects', ({ event }) => event) }, - }, - }, - }, - on: { - 'cron.commit': { - actions: assign({ tasks: ({ event }) => event.tasks }), - }, - }, -}); - -export const AgentCron = defineAgentRuntimeContract<CronRuntime>('cron'); - -export const cronAgentRuntimeProvider = defineAgentRuntimeProvider<CronModelState, CronRuntime>(AgentCron, { - id: 'cron', - logic: cronActorLogic, - eager: true, - durable: { - events: [CronAdd, CronDelete, CronCursor], - undoable: false, - transition: (state, event) => { - if (event instanceof CronAdd) { - state.set(event.task.id, event.task); - return; - } - if (event instanceof CronDelete) { - for (const id of event.ids) state.delete(id); - return; - } - if (event instanceof CronCursor) { - const task = state.get(event.id); - if (task !== undefined) state.set(event.id, { ...task, lastFiredAt: event.lastFiredAt }); - } - }, - read: (snapshot) => (snapshot as CronActorSnapshot).context.tasks, - commit: (actor, tasks) => { actor.send({ type: 'cron.commit', tasks }); }, - }, - createApi: (context) => new CronRuntime(context), - inspect: (snapshot) => - [...(snapshot as CronActorSnapshot).context.tasks.values()].map((task) => ({ - id: task.id, - cron: task.cron, - recurring: task.recurring !== false, - createdAt: task.createdAt, - lastFiredAt: task.lastFiredAt, - })), -}); diff --git a/packages/agent-core-v2/src/features/cron/cronFeature.ts b/packages/agent-core-v2/src/features/cron/cronFeature.ts deleted file mode 100644 index 7cb640f9a..000000000 --- a/packages/agent-core-v2/src/features/cron/cronFeature.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; -import { cronAgentRuntimeProvider } from '#/features/cron/cronAgentRuntime'; -import { ICronCreateTool } from '#/features/cron/tools/cron-create/cron-create'; -import { CronCreateTool } from '#/features/cron/tools/cron-create/cronCreateTool'; -import { ICronDeleteTool } from '#/features/cron/tools/cron-delete/cron-delete'; -import { CronDeleteTool } from '#/features/cron/tools/cron-delete/cronDeleteTool'; -import { ICronListTool } from '#/features/cron/tools/cron-list/cron-list'; -import { CronListTool } from '#/features/cron/tools/cron-list/cronListTool'; - -export class CronFeature extends Feature { - static override readonly name = 'cron'; - - constructor() { - super(); - this.contributeAgentRuntime(cronAgentRuntimeProvider); - this.contributeTool(ICronCreateTool, CronCreateTool, { name: 'CronCreate', domain: 'cron' }); - this.contributeTool(ICronListTool, CronListTool, { name: 'CronList', domain: 'cron' }); - this.contributeTool(ICronDeleteTool, CronDeleteTool, { name: 'CronDelete', domain: 'cron' }); - } -} - -registerFeature(CronFeature); diff --git a/packages/agent-core-v2/src/features/cron/cronOps.ts b/packages/agent-core-v2/src/features/cron/cronOps.ts deleted file mode 100644 index 34b6dc367..000000000 --- a/packages/agent-core-v2/src/features/cron/cronOps.ts +++ /dev/null @@ -1,67 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import type { CronJobOrigin } from '#/agent/contextMemory/types'; -import type { CronTask } from '#/features/cron/cronTask'; -import { Event2 } from '#/app/event/event2'; - -export type CronModelState = Map<string, CronTask>; - -const cronTaskSchema = z.object({ - id: z.string(), - cron: z.string(), - prompt: z.string(), - createdAt: z.number(), - recurring: z.boolean().optional(), - lastFiredAt: z.number().optional(), - tags: z.record(z.string(), z.string()).optional(), -}); - -const cronAddSchema = z.object({ task: cronTaskSchema }); -const cronDeleteSchema = z.object({ ids: z.array(z.string()) }); -const cronCursorSchema = z.object({ id: z.string(), lastFiredAt: z.number() }); - -export interface CronAddPayload { - readonly task: CronTask; -} - -export class CronAdd extends Event2<CronAddPayload> { - static override readonly type = 'cron.add'; - static override readonly durable = true; - static override readonly schema = cronAddSchema; -} -export interface CronAdd extends CronAddPayload {} - -export interface CronDeletePayload { - readonly ids: readonly string[]; -} - -export class CronDelete extends Event2<CronDeletePayload> { - static override readonly type = 'cron.delete'; - static override readonly durable = true; - static override readonly schema = cronDeleteSchema; -} -export interface CronDelete extends CronDeletePayload {} - -export interface CronCursorPayload { - readonly id: string; - readonly lastFiredAt: number; -} - -export class CronCursor extends Event2<CronCursorPayload> { - static override readonly type = 'cron.cursor'; - static override readonly durable = true; - static override readonly schema = cronCursorSchema; -} -export interface CronCursor extends CronCursorPayload {} - -export interface CronFiredPayload { - readonly origin: CronJobOrigin; - readonly prompt: string; -} - -export class CronFired extends Event2<CronFiredPayload> { - static override readonly type = 'cron.fired'; - static override readonly observable = true; -} -export interface CronFired extends CronFiredPayload {} diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-delete/cronDeleteTool.ts b/packages/agent-core-v2/src/features/cron/tools/cron-delete/cronDeleteTool.ts deleted file mode 100644 index 3546912b6..000000000 --- a/packages/agent-core-v2/src/features/cron/tools/cron-delete/cronDeleteTool.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { type ToolExecution } from '#/tool/toolContract'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { AgentCron, type CronRuntime } from '#/features/cron/cronAgentRuntime'; - -import { CRON_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; -import { ICronDeleteTool, CronDeleteInputSchema, type CronDeleteInput } from './cron-delete'; -import CRON_DELETE_DESCRIPTION from './cron-delete.md?raw'; - -const ID_PATTERN = /^(?:[0-9a-f]{8}|[0-9A-HJKMNP-TV-Z]{26})$/i; - -export class CronDeleteTool implements ICronDeleteTool { - declare readonly _serviceBrand: undefined; - - readonly name = 'CronDelete' as const; - readonly description = CRON_DELETE_DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema( - CronDeleteInputSchema, - ); - - constructor( - @IAgentLifecycleService private readonly manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - private get cron(): CronRuntime { - return this.manager.resolve(this.scopeContext.agentContext, AgentCron); - } - - resolveExecution(args: CronDeleteInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scopeContext, CRON_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; - if (!ID_PATTERN.test(args.id)) { - return { - isError: true, - output: `Invalid cron job id ${JSON.stringify( - args.id, - )} — must be a ULID.`, - }; - } - - return { - description: `Deleting cron ${args.id}`, - approvalRule: this.name, - execute: async () => { - const removed = this.cron.removeTasks([args.id]); - if (removed.length === 0) { - return { - isError: true, - output: `No cron job with id ${args.id}.`, - }; - } - - this.cron.emitDeleted(args.id, this.scopeContext.agentId); - - return { - output: `Deleted cron job ${args.id}.`, - isError: false, - }; - }, - }; - } -} diff --git a/packages/agent-core-v2/src/features/cron/tools/cron-list/cronListTool.ts b/packages/agent-core-v2/src/features/cron/tools/cron-list/cronListTool.ts deleted file mode 100644 index 23c66db96..000000000 --- a/packages/agent-core-v2/src/features/cron/tools/cron-list/cronListTool.ts +++ /dev/null @@ -1,100 +0,0 @@ -import type { ToolExecution } from '#/tool/toolContract'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { AgentCron, type CronRuntime } from '#/features/cron/cronAgentRuntime'; -import { cronToHuman, parseCronExpression } from '#/features/cron/internal/cron-expr'; -import { type CronTask } from '#/features/cron/cronTask'; -import { formatLocalIsoWithOffset } from '#/features/cron/internal/format'; - -import { CRON_MAIN_AGENT_ONLY, mainAgentOnlyExecution } from '#/agent/tools/mainAgentOnly'; -import { ICronListTool, CronListInputSchema, type CronListInput } from './cron-list'; -import CRON_LIST_DESCRIPTION from './cron-list.md?raw'; - -const MS_PER_DAY = 24 * 60 * 60 * 1000; - -const PROMPT_PREVIEW_BYTES = 200; - -function previewPrompt(prompt: string): string { - const buf = Buffer.from(prompt, 'utf8'); - if (buf.byteLength <= PROMPT_PREVIEW_BYTES) return prompt; - let end = PROMPT_PREVIEW_BYTES; - while (end > 0 && (buf[end]! & 0b1100_0000) === 0b1000_0000) end--; - return `${buf.subarray(0, end).toString('utf8')}…(truncated)`; -} - -export class CronListTool implements ICronListTool { - declare readonly _serviceBrand: undefined; - - readonly name = 'CronList' as const; - readonly description = CRON_LIST_DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema( - CronListInputSchema, - ); - - constructor( - @IAgentLifecycleService private readonly manager: IAgentLifecycleService, - @IAgentScopeContext private readonly scope: IAgentScopeContext, - ) {} - - private get cron(): CronRuntime { - return this.manager.resolve(this.scope.agentContext, AgentCron); - } - - resolveExecution(_args: CronListInput): ToolExecution { - const denied = mainAgentOnlyExecution(this.scope, CRON_MAIN_AGENT_ONLY); - if (denied !== undefined) return denied; - return { - description: 'Listing scheduled cron jobs', - approvalRule: this.name, - execute: async () => { - const tasks = this.cron.list(); - const nowMs = this.cron.now(); - const records = tasks.map((t) => this.renderRecord(t, nowMs)); - const header = `cron_jobs: ${String(tasks.length)}`; - if (records.length === 0) { - return { - output: `${header}\nNo cron jobs scheduled.`, - isError: false, - }; - } - return { - output: `${header}\n${records.join('\n---\n')}`, - isError: false, - }; - }, - }; - } - - private renderRecord(task: CronTask, nowMs: number): string { - const recurring = task.recurring !== false; - - const ageMs = nowMs - task.createdAt; - const ageDays = Number.isFinite(ageMs) ? ageMs / MS_PER_DAY : 0; - - const stale = this.cron.isStale(task); - - let humanSchedule = task.cron; - let nextFireAtIso = 'null'; - try { - const parsed = parseCronExpression(task.cron); - humanSchedule = cronToHuman(parsed); - const nextFireMs = this.cron.getNextFireForTask(task.id); - if (nextFireMs !== null) { - nextFireAtIso = formatLocalIsoWithOffset(nextFireMs); - } - } catch { - } - - return [ - `id: ${task.id}`, - `cron: ${task.cron}`, - `humanSchedule: ${humanSchedule}`, - `prompt: ${JSON.stringify(previewPrompt(task.prompt))}`, - `nextFireAt: ${nextFireAtIso}`, - `recurring: ${String(recurring)}`, - `ageDays: ${ageDays.toFixed(2)}`, - `stale: ${String(stale)}`, - ].join('\n'); - } -} diff --git a/packages/agent-core-v2/src/features/dateChange/dateChange.ts b/packages/agent-core-v2/src/features/dateChange/dateChange.ts deleted file mode 100644 index b5f5cbbb6..000000000 --- a/packages/agent-core-v2/src/features/dateChange/dateChange.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface DateInjectionDisclosure { - readonly kind: 'date'; - readonly renderGeneration: number; - readonly localDate: string; - readonly timeZone: string; -} diff --git a/packages/agent-core-v2/src/features/dateChange/dateChangeAgentRuntime.ts b/packages/agent-core-v2/src/features/dateChange/dateChangeAgentRuntime.ts deleted file mode 100644 index 833a145f9..000000000 --- a/packages/agent-core-v2/src/features/dateChange/dateChangeAgentRuntime.ts +++ /dev/null @@ -1,177 +0,0 @@ -import { assign, fromCallback, setup } from 'xstate'; - -import { IAgentProfileService } from '#/agent/profile/profile'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, - type AgentRuntimeRestoreEvent, -} from '#/agent/runtime/agentRuntime'; -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; -import type { - ContextInjectionContext, - ContextInjectionResult, -} from '#/features/reminder/types'; -import { IHostClock } from '#/os/interface/hostClock'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; - -import type { DateInjectionDisclosure } from './dateChange'; -import { pickDisclosureBaseline } from './disclosureBaseline'; - -const DATE_CHANGE_INJECTION_VARIANT = 'date_change'; - -interface DateDisclosure { - readonly localDate: string; - readonly timeZone: string; - readonly renderGeneration: number; -} - -interface DateChangeActorContext { - readonly seed: DateDisclosure | undefined; - readonly runtime: AgentRuntimeContext<null>; -} - -interface DateChangeDiscloseEvent { - readonly type: 'dateChange.disclose'; - readonly seed: DateDisclosure; -} - -function currentDateDisclosure(clock: IHostClock): Omit<DateDisclosure, 'renderGeneration'> { - const date = clock.now(); - const timeZone = clock.timeZone(); - const parts = new Intl.DateTimeFormat('en-US', { - timeZone, - year: 'numeric', - month: '2-digit', - day: '2-digit', - }).formatToParts(date); - const part = (type: Intl.DateTimeFormatPartTypes): string => - parts.find((candidate) => candidate.type === type)?.value ?? ''; - return { - localDate: `${part('year')}-${part('month')}-${part('day')}`, - timeZone, - }; -} - -const dateChangeInjection = fromCallback(({ - input, -}: { - input: { - readonly runtime: AgentRuntimeContext<null>; - }; -}) => { - const runtime = input.runtime; - const reminder = runtime - .get(IAgentLifecycleService) - .resolve(runtime.agent, AgentReminder); - const profile = runtime.get(IAgentProfileService); - const clock = runtime.get(IHostClock); - const sessionContext = runtime.get(ISessionContext); - const belongsToCurrentCwd = (): boolean => { - const environment = profile.data().environmentDisclosure; - return !( - environment !== undefined && - environment.cwd !== '' && - environment.cwd !== sessionContext.cwd - ); - }; - const dateFromProfile = (): DateDisclosure | undefined => { - if (!belongsToCurrentCwd()) return undefined; - const profileData = profile.data(); - const date = profileData.environmentDisclosure?.date; - if (!date?.disclosed) return undefined; - return { - ...date.value, - renderGeneration: profileData.renderGeneration ?? 0, - }; - }; - const registration = reminder.register<DateInjectionDisclosure>( - DATE_CHANGE_INJECTION_VARIANT, - ({ - lastDisclosure, - }: ContextInjectionContext<DateInjectionDisclosure>): ContextInjectionResult<DateInjectionDisclosure> | undefined => { - const profileData = profile.data(); - if (!belongsToCurrentCwd()) return undefined; - const renderGeneration = profileData.renderGeneration ?? 0; - const current = currentDateDisclosure(clock); - const profileDate = dateFromProfile(); - const seed = runtime.getLogicState<DateChangeActorContext>().seed; - const baseline = pickDisclosureBaseline<DateDisclosure>( - lastDisclosure, - profileDate, - seed, - ); - if (baseline !== undefined && baseline.localDate !== current.localDate) { - return { - content: `The date has changed. Today's date is now ${current.localDate}. Rely on this reminder over any earlier date statement for the current date. DO NOT mention this to the user explicitly.`, - disclosure: { - kind: 'date', - renderGeneration, - localDate: current.localDate, - timeZone: current.timeZone, - }, - }; - } - if (lastDisclosure !== undefined || profileDate !== undefined) return undefined; - if (seed === undefined) { - runtime.send({ - type: 'dateChange.disclose', - seed: { ...current, renderGeneration }, - }); - } - return { - content: `Today's date is ${current.localDate}. The current date is restated in a reminder whenever it changes; rely on the latest such reminder for the current date. DO NOT mention this to the user explicitly.`, - disclosure: { - kind: 'date', - renderGeneration, - localDate: current.localDate, - timeZone: current.timeZone, - }, - }; - }, - ); - return () => { registration.dispose(); }; -}); - -const dateChangeActorLogic = setup({ - types: {} as { - context: DateChangeActorContext; - input: AgentRuntimeContext<null>; - events: DateChangeDiscloseEvent | AgentRuntimeRestoreEvent; - }, - actors: { dateChangeInjection }, -}).createMachine({ - context: ({ input }) => ({ seed: undefined, runtime: input }), - initial: 'beforeRestore', - states: { - beforeRestore: { - on: { 'runtime.restore': 'active' }, - }, - active: { - invoke: { - src: 'dateChangeInjection', - input: ({ context }) => ({ runtime: context.runtime }), - }, - }, - }, - on: { - 'dateChange.disclose': { - actions: assign({ seed: ({ event }) => event.seed }), - }, - }, -}); - -export class DateChangeRuntime {} - -export const AgentDateChange = defineAgentRuntimeContract<DateChangeRuntime>('dateChange'); - -export const dateChangeAgentRuntimeProvider = defineAgentRuntimeProvider<null, DateChangeRuntime>( - AgentDateChange, - { - id: 'dateChange', - logic: dateChangeActorLogic, - eager: true, - createApi: () => new DateChangeRuntime(), - }, -); diff --git a/packages/agent-core-v2/src/features/dateChange/dateChangeFeature.ts b/packages/agent-core-v2/src/features/dateChange/dateChangeFeature.ts deleted file mode 100644 index 4461c0493..000000000 --- a/packages/agent-core-v2/src/features/dateChange/dateChangeFeature.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { dateChangeAgentRuntimeProvider } from './dateChangeAgentRuntime'; - -export class DateChangeFeature extends Feature { - static override readonly name = 'dateChange'; - - constructor() { - super(); - this.contributeAgentRuntime(dateChangeAgentRuntimeProvider); - } -} - -registerFeature(DateChangeFeature); diff --git a/packages/agent-core-v2/src/features/dateChange/disclosureBaseline.ts b/packages/agent-core-v2/src/features/dateChange/disclosureBaseline.ts deleted file mode 100644 index 44f897e9e..000000000 --- a/packages/agent-core-v2/src/features/dateChange/disclosureBaseline.ts +++ /dev/null @@ -1,14 +0,0 @@ -export function pickDisclosureBaseline<T extends { readonly renderGeneration: number }>( - ...candidates: readonly (T | undefined)[] -): T | undefined { - let winner: T | undefined; - for (const candidate of candidates) { - if ( - candidate !== undefined && - (winner === undefined || candidate.renderGeneration > winner.renderGeneration) - ) { - winner = candidate; - } - } - return winner; -} diff --git a/packages/agent-core-v2/src/features/debugEvents/debugEvents.ts b/packages/agent-core-v2/src/features/debugEvents/debugEvents.ts index e526d5ab0..698c42b35 100644 --- a/packages/agent-core-v2/src/features/debugEvents/debugEvents.ts +++ b/packages/agent-core-v2/src/features/debugEvents/debugEvents.ts @@ -1,3 +1,21 @@ +/** + * `debugEvents` domain — `IDebugEventsService`: event-subscription + * introspection. + * + * Public contract. `subscriptions()` merges two sides: the precise unit-book + * side (every materialized unit's ledger entries whose label marks an event + * subscription — `on:<name>` from a named `Emitter` or the fiber `on` + * capability, `disposable:EventSubscription` from an unnamed emitter) and the + * emitter-side fallback (listener counts of every materialized `IEventBus` + * instance and the global `IEventService`), which also covers subscriptions + * the caller never registered on a unit book. Unmaterialized on-demand units + * and anonymous fiber units are not enumerable and are simply absent. + * Contributed at App scope through `DebugEventsFeature` — reachable over the + * debug RPC surface by decorator name, but absent from the static scoped + * registry (`GET /api/v1/debug/channels`). All payloads are JSON-serializable + * wire data. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { LedgerEntryInfo } from '#/_base/lifecycle/ledger'; diff --git a/packages/agent-core-v2/src/features/debugEvents/debugEventsFeature.ts b/packages/agent-core-v2/src/features/debugEvents/debugEventsFeature.ts index 3ca4423ce..f5ab880bb 100644 --- a/packages/agent-core-v2/src/features/debugEvents/debugEventsFeature.ts +++ b/packages/agent-core-v2/src/features/debugEvents/debugEventsFeature.ts @@ -1,3 +1,14 @@ +/** + * `debugEvents` domain — `DebugEventsFeature`: the event-subscription + * introspection capability assembled as one App-scope Feature unit. + * + * Contributes the App-scope `IDebugEventsService` (OnDemand) through the + * `features` base-class seam; retracting the unit withdraws the service + * across the scope tree. The service is intentionally absent from the static + * scoped registry — the debug RPC dispatcher reaches it by decorator-name + * fallback. Registered into the feature table at import. + */ + import { ScopeActivation } from '#/_base/di/instantiation'; import { LifecycleScope } from '#/app/scopes'; import { Feature } from '#/features/feature'; diff --git a/packages/agent-core-v2/src/features/debugEvents/debugEventsService.ts b/packages/agent-core-v2/src/features/debugEvents/debugEventsService.ts index 9f0d4a495..08bdc74a3 100644 --- a/packages/agent-core-v2/src/features/debugEvents/debugEventsService.ts +++ b/packages/agent-core-v2/src/features/debugEvents/debugEventsService.ts @@ -1,3 +1,16 @@ +/** + * `debugEvents` domain — `IDebugEventsService` implementation. + * + * Read-only introspection over the kernel's debug accessors (`children` / + * `servicesSnapshot` / `fiberHost.materializedInstance` / unit-book + * `ledger.entries`), plus listener counters on the `event` domain's bus + * implementations; no kernel state is mutated. Instances resolve up the parent + * chain, so each is attributed to the first container that reaches it and + * deduplicated by identity; unmaterialized on-demand units read as `undefined` + * and are skipped. Contributed at App scope through `DebugEventsFeature`; the + * injected container is the tree root. + */ + import { IInstantiationService } from '#/_base/di/instantiation'; import type { InstantiationService } from '#/_base/di/instantiationService'; import type { LedgerEntryInfo } from '#/_base/lifecycle/ledger'; diff --git a/packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooks.ts b/packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooks.ts deleted file mode 100644 index 6df416a69..000000000 --- a/packages/agent-core-v2/src/features/externalHooks/agent/agentExternalHooks.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; - -export interface IAgentExternalHooksService { - readonly _serviceBrand: undefined; -} - -export const IAgentExternalHooksService = - createDecorator<IAgentExternalHooksService>('agentExternalHooksService'); diff --git a/packages/agent-core-v2/src/features/externalHooks/externalHooksFeature.ts b/packages/agent-core-v2/src/features/externalHooks/externalHooksFeature.ts deleted file mode 100644 index 5c4204e5c..000000000 --- a/packages/agent-core-v2/src/features/externalHooks/externalHooksFeature.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import './configSection'; -import { IAgentExternalHooksService } from './agent/agentExternalHooks'; -import { AgentExternalHooksService } from './agent/agentExternalHooksService'; -import { IExternalHooksRunnerService } from './app/externalHooksRunner'; -import { ExternalHooksRunnerService } from './app/externalHooksRunnerService'; -import { ISessionExternalHooksService } from './session/sessionExternalHooks'; -import { SessionExternalHooksService } from './session/sessionExternalHooksService'; - -export class ExternalHooksFeature extends Feature { - static override readonly name = 'externalHooks'; - - constructor() { - super(); - this.contributeService( - LifecycleScope.App, - IExternalHooksRunnerService, - ExternalHooksRunnerService, - ); - this.contributeService( - LifecycleScope.Session, - ISessionExternalHooksService, - SessionExternalHooksService, - ); - this.contributeAgentService(IAgentExternalHooksService, AgentExternalHooksService); - } -} - -registerFeature(ExternalHooksFeature); diff --git a/packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooks.ts b/packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooks.ts deleted file mode 100644 index d65f208d3..000000000 --- a/packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooks.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface ISessionExternalHooksService { - readonly _serviceBrand: undefined; -} - -export const ISessionExternalHooksService: ServiceIdentifier<ISessionExternalHooksService> = - createDecorator<ISessionExternalHooksService>('sessionExternalHooksService'); diff --git a/packages/agent-core-v2/src/features/feature.ts b/packages/agent-core-v2/src/features/feature.ts index f56d231cb..f3bd956dc 100644 --- a/packages/agent-core-v2/src/features/feature.ts +++ b/packages/agent-core-v2/src/features/feature.ts @@ -1,3 +1,18 @@ +/** + * `features` domain — the `Feature` base class: one self-contained built-in + * capability (plan, mcp, …) authored as a single App-scope unit recipe. + * + * A subclass declares its contributions inside its constructor through the + * `contribute*` helpers — thin compositions over the unit capabilities and + * the existing collection seams: config sections (`config`), per-scope + * service materialization (`ScopeUnits` — the kernel folds one live unit per + * present and future scope of that kind), agent tools (`toolRegistry`), and + * agent profiles (`agentProfileCatalog`). Everything a Feature provides hangs + * on its own book, so retracting the Feature unit withdraws every + * contribution across the scope tree (连坐). Recipes declare a stable + * `static readonly name`; the assembly keys managed units by it. + */ + import { type CollectionToken } from '#/_base/di/collection'; import { ScopeUnits, @@ -13,7 +28,6 @@ import { AgentProfileContribution, AGENT_PROFILE_SOURCE_PRIORITY, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import { FeatureServiceContribution } from '#/app/feature/featureServiceContribution'; import type { AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; import type { ConfigSchema, RegisterSectionOptions } from '#/app/config/config'; import { ConfigSectionContribution } from '#/app/config/configSectionContributions'; @@ -28,41 +42,12 @@ import { type AgentToolCtor, type AnyAgentTool, } from '#/agent/toolRegistry/toolContribution'; -import { - AgentRuntimeContributionPoint, - AgentRuntimeOverrideContributionPoint, - type AgentRuntimeProvider, -} from '#/agent/runtime/agentRuntime'; -import type { - AgentModel, - AgentModelDefinition, - SessionModelDefinition, -} from '#/state/agentModel'; -import { AgentModelContribution, SessionModelContribution } from '#/state/agentModel'; export abstract class Feature extends Service { contribute<T>(token: CollectionToken<T>, value: T): FiberHandle { return this.provide(token, value); } - contributeSessionModel<State>(definition: SessionModelDefinition<State>): FiberHandle { - return this.provide(SessionModelContribution, definition as SessionModelDefinition); - } - - contributeAgentModel<S, M extends AgentModel<S>>( - definition: AgentModelDefinition<S, M>, - ): FiberHandle { - return this.provide(AgentModelContribution, definition as AgentModelDefinition<any, any>); - } - - contributeAgentRuntime<Runtime>(provider: AgentRuntimeProvider<Runtime>): FiberHandle { - return this.provide(AgentRuntimeContributionPoint, provider); - } - - overrideAgentRuntime<Runtime>(provider: AgentRuntimeProvider<Runtime>): FiberHandle { - return this.provide(AgentRuntimeOverrideContributionPoint, provider); - } - contributeConfig<T>( domain: string, schema: ConfigSchema<T>, @@ -81,7 +66,6 @@ export abstract class Feature extends Service { ctor: ServiceClassRecipe, opts?: FiberProvideOptions, ): FiberHandle { - this.provide(FeatureServiceContribution, { scope, id }); return this.provide(ScopeUnits(scope), { name: `${this.name}:${String(id)}`, apply(fiber: Fiber): void { diff --git a/packages/agent-core-v2/src/features/featureAssembly.ts b/packages/agent-core-v2/src/features/featureAssembly.ts index a8e2c9786..50ef072d0 100644 --- a/packages/agent-core-v2/src/features/featureAssembly.ts +++ b/packages/agent-core-v2/src/features/featureAssembly.ts @@ -1,3 +1,12 @@ +/** + * `features` domain — the `IFeatureAssemblyService` contract. + * + * The assembly drains the module-level feature recipe table + * (`featureRegistry`) into managed units at App-scope creation; it owns no + * state of its own and exists so feature assembly runs through the same + * provide path as every other unit. Bound at App scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IFeatureAssemblyService { diff --git a/packages/agent-core-v2/src/features/featureAssemblyService.ts b/packages/agent-core-v2/src/features/featureAssemblyService.ts index 376064e6c..1b7b1f634 100644 --- a/packages/agent-core-v2/src/features/featureAssemblyService.ts +++ b/packages/agent-core-v2/src/features/featureAssemblyService.ts @@ -1,3 +1,12 @@ +/** + * `features` domain — `IFeatureAssemblyService` implementation. + * + * Assembles every registered feature recipe through `feature` + * (`IFeatureManager`), so each built-in capability becomes a named, + * introspectable (`units()`), individually retractable managed unit hanging + * on the manager's book. Bound at App scope. + */ + import { IFeatureManager } from '#/app/feature/featureManager'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/features/featureRegistry.ts b/packages/agent-core-v2/src/features/featureRegistry.ts index 96e715837..4a22b5af6 100644 --- a/packages/agent-core-v2/src/features/featureRegistry.ts +++ b/packages/agent-core-v2/src/features/featureRegistry.ts @@ -1,3 +1,12 @@ +/** + * `features` domain — the module-level feature recipe table ("import = + * register"). + * + * Each feature module calls `registerFeature(Recipe)` at its top level; the + * assembly drains the table once at App-scope creation. Pure data — no DI, no + * container — so feature modules stay importable in any bootstrap order. + */ + import type { ServiceClassRecipe } from '#/_base/di/fiber'; const _featureRecipes: ServiceClassRecipe[] = []; diff --git a/packages/agent-core-v2/src/features/goal/goal.ts b/packages/agent-core-v2/src/features/goal/goal.ts deleted file mode 100644 index aaf64ec0a..000000000 --- a/packages/agent-core-v2/src/features/goal/goal.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface GoalReasonInput { - readonly reason?: string; -} - -export interface ResumeGoalInput extends GoalReasonInput { - readonly continueIfPaused?: boolean; - readonly continueIfBlocked?: boolean; -} - diff --git a/packages/agent-core-v2/src/features/goal/goalAgentRuntime.ts b/packages/agent-core-v2/src/features/goal/goalAgentRuntime.ts deleted file mode 100644 index 597f5623b..000000000 --- a/packages/agent-core-v2/src/features/goal/goalAgentRuntime.ts +++ /dev/null @@ -1,1428 +0,0 @@ -import { randomUUID } from 'node:crypto'; - -import { assign, fromCallback, sendTo, setup, type Snapshot } from 'xstate'; - -import { MutableDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import { abortError } from '#/_base/utils/abort'; -import { isPlainRecord } from '#/_base/utils/canonical-args'; -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; -import { ContextAppendMessage } from '#/agent/contextMemory/contextEvents'; -import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; -import { GoalInjection, GOAL_WAIT_FOR_GUIDANCE } from '#/features/goal/injection/goalInjection'; -import { LOOP_CONTROL_SECTION, type LoopControl } from '#/agent/loop/configSection'; -import { LoopErrors } from '#/agent/loop/errors'; -import { - IAgentLoopService, - type AfterStepContext, - type BeforeStepContext, - type EnqueueReceipt, -} from '#/agent/loop/loop'; -import { ContinuationStepRequest, MessageStepRequest } from '#/agent/loop/stepRequest'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; -import type { PermissionMode } from '#/agent/permissionPolicy/types'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, - type AgentRuntimeRestoreEvent, -} from '#/agent/runtime/agentRuntime'; -import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; -import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import type { BeforeToolExecuteEvent } from '#/agent/toolExecutor/toolHooks'; -import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; -import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; -import { WAIT_FOR_FLAG_ID } from '#/agent/tools/task/task-wait/flag'; -import { type UsageRecordedContext } from '#/agent/usage/usage'; -import { IConfigService } from '#/app/config/config'; -import { IEventBus } from '#/app/event/eventBus'; -import { IFlagService } from '#/app/flag/flag'; -import type { GoalBudgetProperties } from '#/app/telemetry/events'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { - ErrorCodes, - Error2, - toKimiErrorPayload, - type KimiErrorPayload, -} from '#/errors'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionUsageService } from '#/session/usage/sessionUsage'; -import type { ExecutableToolResult } from '#/tool/toolContract'; - -import type { GoalReasonInput, ResumeGoalInput } from './goal'; -import { IGoalDeadlineScheduler } from './goalDeadlineScheduler'; -import { - GoalClear, - GoalCreate, - GoalForked, - GoalUpdate, - GoalUpdated, - type GoalModelState, - type GoalState, -} from './goalOps'; -import type { - CreateGoalInput, - GoalActor, - GoalBudgetLimits, - GoalBudgetReport, - GoalChange, - GoalChangeStats, - GoalSnapshot, - GoalStatus, - GoalToolResult, -} from './types'; - -const MAX_GOAL_OBJECTIVE_LENGTH = 4000; - -const MAX_GOAL_COMPLETION_CRITERION_LENGTH = MAX_GOAL_OBJECTIVE_LENGTH; - -const GOAL_CANCELLED_REMINDER = [ - 'The user cancelled the current goal.', - 'Ignore earlier active-goal reminders for that goal.', - 'Handle the next user request normally unless the user starts or resumes a goal.', -].join(' '); - -const GOAL_FORK_CLEARED_REMINDER = [ - 'This fork does not have a current goal.', - 'Ignore earlier active-goal reminders from the source session.', - 'Handle requests normally unless the user starts a new goal.', -].join(' '); - -const GOAL_FORK_CLEARED_REMINDER_NAME = 'goal_fork_cleared'; - -const GOAL_CONTINUATION_ORIGIN: PromptOrigin = { - kind: 'system_trigger', - name: 'goal_continuation', -}; -const GOAL_RATE_LIMIT_PAUSE_REASON = 'Paused after provider rate limit'; -const GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX = 'Paused after provider connection error'; -const GOAL_PROVIDER_AUTH_PAUSE_PREFIX = 'Paused after provider authentication error'; -const GOAL_PROVIDER_API_PAUSE_PREFIX = 'Paused after provider API error'; -const GOAL_MODEL_CONFIG_PAUSE_PREFIX = 'Paused after model configuration error'; -const GOAL_RUNTIME_PAUSE_PREFIX = 'Paused after runtime error'; -const GOAL_CONTINUATION_FAILURE_PAUSE_PREFIX = 'Paused after goal continuation failure'; -const GOAL_PROVIDER_FILTERED_PAUSE_REASON = 'Paused after provider safety policy block'; -const GOAL_BUDGET_BLOCK_PREFIX = 'Blocked after goal budget reached'; -const LLM_NOT_SET_MESSAGE = 'LLM not set, send "/login" to login'; - -const GOAL_BUDGET_STOP_REMINDER_NAME = 'goal_budget_stop'; - -const GOAL_BUDGET_STOP_REMINDER = [ - "The goal's hard budget was reached and the goal is now blocked; the user can resume it with /goal resume.", - 'Stop immediately.', - 'Do not call any more tools: they will be rejected.', - 'Write a brief final status message summarizing the progress so far.', -].join(' '); - -const GOAL_BUDGET_TOOLS_REJECTED_MESSAGE = - 'Goal budget exhausted; tool calls are rejected. Write your final message.'; -const GOAL_STALE_TOOL_RESULT = - 'Goal changed since this turn started; ignored stale goal tool call.'; - -const GOAL_CONTINUATION_PROMPT = [ - 'Continue working toward the active goal.', - 'Keep the self-audit brief. Do not explore unrelated interpretations once the goal can be', - 'decided. If the objective is simple, already answered, impossible, unsafe, or contradictory,', - 'do not run another goal turn. Explain briefly if useful, then call UpdateGoal with `complete`', - 'or `blocked` in the same turn. Otherwise, weigh the objective and any completion criteria', - 'against the work done so far, choose one bounded, useful slice of work, and use the existing', - 'conversation context and your tools. Do not try to finish a broad goal in one turn unless the', - 'whole goal is genuinely small. Most goal turns should not call UpdateGoal: after completing a', - 'useful slice, if material work remains, end the turn normally without calling UpdateGoal so', - 'the runtime can continue the goal in the next turn. Call UpdateGoal with `complete` only when', - 'all required work is done, any stated validation has passed, and there is no useful next', - 'action. Completion audit: before calling `complete`, verify the current state against the', - 'actual objective and every explicit requirement. Treat weak or indirect evidence as not', - 'complete. Do not mark complete after only producing a plan, summary, first pass, or partial', - 'result. Do not mark complete merely because a budget is nearly exhausted or you want to stop.', - 'Blocked audit: do not call UpdateGoal with `blocked` the first time you hit a blocker. Use', - '`blocked` only for a genuine impasse: an external condition, required user input, missing', - 'credentials or permissions, or a persistent technical failure. For those non-terminal', - 'blockers, the same blocking condition must repeat for at least 3 consecutive goal turns before', - 'you call `blocked`, counting the original/user-triggered turn and automatic continuations.', - 'If a previously blocked goal is resumed, treat the resumed run as a fresh blocked audit.', - 'Exception: if the objective itself is impossible, unsafe, or contradictory, call UpdateGoal', - 'with `blocked` in the same turn; do not run more goal turns just to satisfy the audit. Do not', - 'use `blocked` because the work is large, hard, slow, uncertain, incomplete, still needs', - 'validation, would benefit from clarification, or needs more goal turns. Once the 3-turn', - 'threshold is met and you cannot make meaningful progress without user input or an', - 'external-state change, call UpdateGoal with `blocked`; do not keep reporting the blocker while', - 'leaving the goal active. Do not ask the user for input unless a real blocker prevents progress.', -].join(' '); - -const GOAL_STEP_CAP_CONTINUATION_PROMPT = [ - 'The previous goal turn reached the per-turn step limit before finishing its work,', - 'so a new turn was started for you. Pick up where that turn stopped and keep each', - 'slice of work small enough to fit the limit.', - GOAL_CONTINUATION_PROMPT, -].join(' '); - -export interface GoalForkNoticeState { - readonly goalPresent: boolean; - readonly reminderPending: boolean; -} - -export interface GoalRuntimeState { - readonly goal: GoalModelState; - readonly forkNotice: GoalForkNoticeState; -} - -interface PendingContinuation { - readonly receipt: EnqueueReceipt; - readonly goalId: string; - turnId?: number; -} - -interface ResumeContinuation { - readonly turnId: number; - readonly goalId: string; -} - -interface GoalEffectState { - pendingContinuation?: PendingContinuation; - liveTurnId?: number; - readonly goalDrivenTurns: Map<number, string>; - readonly countedGoalTurns: Set<number>; - readonly goalStarterTurns: Set<number>; - readonly goalOutcomeToolResultTurns: Map<number, string>; - readonly goalOutcomeContinuationTurns: Set<number>; - readonly budgetGraceTurns: Set<number>; - readonly pendingContinuationGoals: Map<number, string>; - readonly goalTurnTargets: Map<number, string>; - readonly exhaustedTurnBudgetGoals: Map<number, string>; - liveWallClockStartedAt?: number; - resumeContinuation?: ResumeContinuation; -} - -interface GoalActorContext { - readonly durable: GoalRuntimeState; - readonly effects: GoalEffectState; - readonly runtime: AgentRuntimeContext<GoalRuntimeState>; -} - -interface GoalCommitEvent { - readonly type: 'goal.commit'; - readonly durable: GoalRuntimeState; -} - -interface GoalDeadlineRefreshEvent { - readonly type: 'goal.deadline.refresh'; -} - -interface GoalDeadlineClearEvent { - readonly type: 'goal.deadline.clear'; -} - -type GoalEffectEvent = GoalDeadlineRefreshEvent | GoalDeadlineClearEvent; -type GoalActorEvent = GoalCommitEvent | AgentRuntimeRestoreEvent | GoalEffectEvent; -type GoalActorSnapshot = Snapshot<unknown> & { readonly context: GoalActorContext; }; - -function isGoalForkClearedReminder(message: ContextMessage | undefined): boolean { - const origin = message?.origin; - if (origin?.kind === 'injection') return origin.variant === GOAL_FORK_CLEARED_REMINDER_NAME; - return origin?.kind === 'system_trigger' && origin.name === GOAL_FORK_CLEARED_REMINDER_NAME; -} - -function isGoalContinuationOrigin(origin: TurnStarted['origin']): boolean { - return origin.kind === 'system_trigger' && origin.name === 'goal_continuation'; -} - -interface GoalOperationContext { - readonly runtime: AgentRuntimeContext<GoalRuntimeState>; - readonly effects: GoalEffectState; -} - -function goalOperationContext(runtime: AgentRuntimeContext<GoalRuntimeState>): GoalOperationContext { - return { runtime, effects: runtime.getLogicState<GoalActorContext>().effects }; -} - -function reminderOf(runtime: AgentRuntimeContext<GoalRuntimeState>) { - return runtime.get(IAgentLifecycleService).resolve(runtime.agent, AgentReminder); -} - -export class GoalRuntime { - constructor(private readonly runtime: AgentRuntimeContext<GoalRuntimeState>) {} - - getGoal(): GoalToolResult { - return getGoal(goalOperationContext(this.runtime)); - } - - isGoalToolTarget(turnId: number, goalId: string): boolean { - return isGoalToolTarget(goalOperationContext(this.runtime), turnId, goalId); - } - - async createGoal(input: CreateGoalInput, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - return createGoal(goalOperationContext(this.runtime), input, actor); - } - - async pauseGoal(input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - return pauseGoal(goalOperationContext(this.runtime), input, actor); - } - - async resumeGoal(input: ResumeGoalInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - return resumeGoal(goalOperationContext(this.runtime), input, actor); - } - - async setBudgetLimits( - input: { readonly budgetLimits: GoalBudgetLimits }, - actor: GoalActor = 'user', - ): Promise<GoalSnapshot> { - return setBudgetLimits(goalOperationContext(this.runtime), input, actor); - } - - async cancelGoal(_input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - return cancelGoal(goalOperationContext(this.runtime), _input, actor); - } - - async markBlocked( - input: GoalReasonInput = {}, - actor: GoalActor = 'runtime', - ): Promise<GoalSnapshot | null> { - return markBlocked(goalOperationContext(this.runtime), input, actor); - } - - async markComplete( - input: GoalReasonInput = {}, - actor: GoalActor = 'model', - ): Promise<GoalSnapshot | null> { - return markComplete(goalOperationContext(this.runtime), input, actor); - } - - async pauseOnInterrupt(input: GoalReasonInput = {}): Promise<GoalSnapshot | null> { - return pauseOnInterrupt(goalOperationContext(this.runtime), input); - } - - async recordTokenUsage(tokenDelta: number): Promise<GoalSnapshot | null> { - return recordTokenUsage(goalOperationContext(this.runtime), tokenDelta); - } - - async incrementTurn(): Promise<GoalSnapshot | null> { - return incrementTurn(goalOperationContext(this.runtime)); - } -} - -function assertSupportedAgent(context: GoalOperationContext): void { - if (context.runtime.agent.agentId === MAIN_AGENT_ID) return; - throw new Error2( - ErrorCodes.GOAL_UNSUPPORTED_AGENT, - 'Goals are only supported by the main agent', - { details: { agentId: context.runtime.agent.agentId } }, - ); -} - -function getGoal(context: GoalOperationContext): GoalToolResult { - assertSupportedAgent(context); - const state = context.runtime.getState().goal; - return { goal: state === null ? null : toSnapshot(context, state) }; -} - -function isGoalToolTarget(context: GoalOperationContext, turnId: number, goalId: string): boolean { - assertSupportedAgent(context); - return context.effects.goalTurnTargets.get(turnId) === goalId; -} - -async function createGoal(context: GoalOperationContext, input: CreateGoalInput, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - assertSupportedAgent(context); - const objective = validateObjective(context, input.objective); - prepareForGoalCreation(context, input.replace === true); - const wallClockResumedAt = Date.now(); - void context.runtime.dispatch( - new GoalCreate({ - agentId: context.runtime.agent.agentId, - goalId: randomUUID(), - objective, - completionCriterion: normalizeCompletionCriterion(input.completionCriterion), - wallClockResumedAt, - }), - ); - context.effects.liveWallClockStartedAt = context.runtime.get(IGoalDeadlineScheduler).now(); - adoptStarterTurn(context, actor); - const state = requireState(context); - refreshWallClockDeadline(context, state); - emitGoalUpdated(context, toSnapshot(context, state)); - context.runtime.get(ITelemetryService).track2('goal_created', { actor, replace: input.replace === true }); - return toSnapshot(context, state); -} - -function validateObjective(context: GoalOperationContext, value: string): string { - const objective = value.trim(); - if (objective.length === 0) { - throw new Error2(ErrorCodes.GOAL_OBJECTIVE_EMPTY, 'Goal objective cannot be empty'); - } - if (objective.length > MAX_GOAL_OBJECTIVE_LENGTH) { - throw new Error2( - ErrorCodes.GOAL_OBJECTIVE_TOO_LONG, - `Goal objective cannot exceed ${MAX_GOAL_OBJECTIVE_LENGTH} characters. Put long content in a file and reference the file path.`, - ); - } - return objective; -} - -function prepareForGoalCreation(context: GoalOperationContext, replace: boolean): void { - if (context.runtime.getState().goal === null) return; - if (!replace) { - throw new Error2( - ErrorCodes.GOAL_ALREADY_EXISTS, - 'A goal already exists; use replace to start a new one', - ); - } - clearInternal(context, 'system'); -} - -async function pauseGoal(context: GoalOperationContext, input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - assertSupportedAgent(context); - const state = requireState(context); - if (state.status === 'paused') return toSnapshot(context, state); - if (state.status !== 'active') { - throw new Error2( - ErrorCodes.GOAL_STATUS_INVALID, - `Cannot pause a goal in status "${state.status}"`, - ); - } - return applyLifecycle(context, state, 'paused', input.reason, actor); -} - -async function pauseActiveGoal(context: GoalOperationContext, - input: GoalReasonInput = {}, - actor: GoalActor = 'runtime', -): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active') return null; - return applyLifecycle(context, state, 'paused', input.reason, actor); -} - -async function resumeGoal(context: GoalOperationContext, input: ResumeGoalInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - assertSupportedAgent(context); - const state = requireState(context); - if (state.status === 'active') return toSnapshot(context, state); - if (state.status !== 'paused' && state.status !== 'blocked') { - throw new Error2( - ErrorCodes.GOAL_NOT_RESUMABLE, - `Cannot resume a goal in status "${state.status}"`, - ); - } - const continuePaused = - actor === 'user' && state.status === 'paused' && input.continueIfPaused === true; - const shouldContinue = - continuePaused || - (actor === 'user' && state.status === 'blocked' && input.continueIfBlocked === true); - const snapshot = applyLifecycle(context, state, 'active', input.reason, actor); - if (!shouldContinue) return snapshot; - const budgetBlocked = blockIfBudgetReached(context, requireState(context)); - if (budgetBlocked !== null) return budgetBlocked; - if (canLaunchContinuation(context)) { - try { - launchContinuationTurn(context, state.goalId); - } catch (error) { - await settleGoalAfterContinuationFailure(context, error, state.goalId); - throw error; - } - } else if (continuePaused && context.effects.liveTurnId !== undefined) { - context.effects.resumeContinuation = { turnId: context.effects.liveTurnId, goalId: state.goalId }; - } - return snapshot; -} - -async function setBudgetLimits(context: GoalOperationContext, - input: { readonly budgetLimits: GoalBudgetLimits; }, - actor: GoalActor = 'user', -): Promise<GoalSnapshot> { - assertSupportedAgent(context); - const state = requireState(context); - const budgetLimits = { ...state.budgetLimits, ...input.budgetLimits }; - void context.runtime.dispatch(new GoalUpdate({ agentId: context.runtime.agent.agentId, budgetLimits })); - const next = requireState(context); - emitGoalUpdated(context, toSnapshot(context, next)); - context.runtime.get(ITelemetryService).track2('goal_budget_set', { - actor, - ...budgetTelemetryProperties(input.budgetLimits), - }); - const blocked = blockIfBudgetReached(context, next); - if (blocked !== null) return blocked; - refreshWallClockDeadline(context, next); - return toSnapshot(context, next); -} - -async function cancelGoal(context: GoalOperationContext, _input: GoalReasonInput = {}, actor: GoalActor = 'user'): Promise<GoalSnapshot> { - assertSupportedAgent(context); - const state = requireState(context); - const snapshot = toSnapshot(context, state); - if (state.status === 'active' && context.effects.liveTurnId !== undefined) { - context.runtime.get(IAgentLoopService).cancel(context.effects.liveTurnId, abortError('Goal cancelled')); - } - clearInternal(context, actor); - if (actor === 'user') { - reminderOf(context.runtime).notify(GOAL_CANCELLED_REMINDER, { - variant: 'goal_cancelled', - }); - } - return snapshot; -} - -async function markBlocked(context: GoalOperationContext, - input: GoalReasonInput = {}, - actor: GoalActor = 'runtime', -): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active') return null; - const snapshot = applyLifecycle(context, state, 'blocked', input.reason, actor, { - preserveLiveContinuation: true, - }); - return snapshot; -} - -async function markComplete(context: GoalOperationContext, - input: GoalReasonInput = {}, - actor: GoalActor = 'model', -): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active') return null; - dispatchCompletion(context, state, input.reason, actor); - const completed = requireState(context); - const snapshot = toSnapshot(context, completed); - emitCompletion(context, completed, snapshot, input.reason, actor); - trackStatusChanged(context, completed, actor); - clearInternal(context, actor, { preserveLiveContinuation: true }); - return snapshot; -} - -function dispatchCompletion(context: GoalOperationContext, state: GoalState, reason: string | undefined, actor: GoalActor): void { - const wallClockMs = settleWallClock(context, state); - void context.runtime.dispatch( - new GoalUpdate({ agentId: context.runtime.agent.agentId, status: 'complete', reason, wallClockMs, actor }), - ); -} - -function emitCompletion(context: GoalOperationContext, - state: GoalState, - snapshot: GoalSnapshot, - reason: string | undefined, - actor: GoalActor, -): void { - emitGoalUpdated(context, snapshot, { - kind: 'completion', - status: 'complete', - reason, - stats: statsOf(context, state), - actor, - }); -} - -async function pauseOnInterrupt(context: GoalOperationContext, input: GoalReasonInput = {}): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - return pauseActiveGoal(context, input, 'user'); -} - -async function recordTokenUsage(context: GoalOperationContext, tokenDelta: number): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - return accountTokenUsage(context, tokenDelta); -} - -async function incrementTurn(context: GoalOperationContext): Promise<GoalSnapshot | null> { - assertSupportedAgent(context); - return incrementGoalTurn(context); -} - -function accountTokenUsage(context: GoalOperationContext, tokenDelta: number, goalId?: string): GoalSnapshot | null { - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active' || !matchesGoal(state, goalId)) return null; - const tokensUsed = state.tokensUsed + Math.max(0, tokenDelta); - void context.runtime.dispatch(new GoalUpdate({ agentId: context.runtime.agent.agentId, tokensUsed })); - const next = requireState(context); - return blockIfBudgetReached(context, next) ?? toSnapshot(context, next); -} - -function incrementGoalTurn(context: GoalOperationContext, goalId?: string): GoalSnapshot | null { - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active' || !matchesGoal(state, goalId)) return null; - const turnsUsed = state.turnsUsed + 1; - void context.runtime.dispatch(new GoalUpdate({ agentId: context.runtime.agent.agentId, turnsUsed })); - const next = requireState(context); - emitGoalUpdated(context, toSnapshot(context, next)); - context.runtime.get(ITelemetryService).track2('goal_continued', { turns_used: next.turnsUsed }); - return toSnapshot(context, next); -} - -function handleTurnLaunched(context: GoalOperationContext, turnId: number, origin: TurnStarted['origin']): void { - context.effects.liveTurnId = turnId; - context.effects.goalTurnTargets.delete(turnId); - context.effects.exhaustedTurnBudgetGoals.delete(turnId); - if (!context.effects.goalDrivenTurns.has(turnId)) { - const state = context.runtime.getState().goal; - const continuationGoalId = isGoalContinuationOrigin(origin) - ? context.effects.pendingContinuationGoals.get(turnId) - : undefined; - if (continuationGoalId !== undefined && state?.goalId !== continuationGoalId) { - context.effects.goalDrivenTurns.set(turnId, continuationGoalId); - } else if (state?.status === 'active' && blockIfBudgetReached(context, state) === null) { - context.effects.goalDrivenTurns.set(turnId, state.goalId); - } - } - context.effects.pendingContinuationGoals.delete(turnId); - context.effects.goalOutcomeToolResultTurns.delete(turnId); - context.effects.goalOutcomeContinuationTurns.delete(turnId); -} - -function adoptStarterTurn(context: GoalOperationContext, actor: GoalActor): void { - const turnId = context.effects.liveTurnId; - if (turnId === undefined) return; - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active') return; - const goalId = context.effects.goalDrivenTurns.get(turnId); - if (actor === 'model') context.effects.goalTurnTargets.set(turnId, state.goalId); - if (toSnapshot(context, state).budget.turnBudgetReached) { - context.effects.exhaustedTurnBudgetGoals.set(turnId, state.goalId); - } else { - context.effects.exhaustedTurnBudgetGoals.delete(turnId); - } - if (goalId !== undefined) return; - context.effects.goalDrivenTurns.set(turnId, state.goalId); - context.effects.countedGoalTurns.add(turnId); - context.effects.goalStarterTurns.add(turnId); -} - -async function handleBeforeStep(context: GoalOperationContext, ctx: BeforeStepContext): Promise<void> { - const goalId = context.effects.goalDrivenTurns.get(ctx.turnId); - if (goalId === undefined) return; - if (context.effects.countedGoalTurns.has(ctx.turnId)) return; - context.effects.countedGoalTurns.add(ctx.turnId); - incrementGoalTurn(context, goalId); -} - -function handleUsageRecorded(context: GoalOperationContext, ctx: UsageRecordedContext): void { - const source = ctx.source; - if (source?.type !== 'turn') return; - const goalId = context.effects.goalDrivenTurns.get(source.turnId); - if (goalId === undefined) return; - accountTokenUsage(context, ctx.usage.output, goalId); -} - -function handleAfterStep(context: GoalOperationContext, ctx: AfterStepContext): void { - if (stopAfterBudgetReached(context, ctx)) return; - enqueueGoalOutcomeContinuation(context, ctx); -} - -function stopAfterBudgetReached(context: GoalOperationContext, ctx: AfterStepContext): boolean { - const goalId = goalTurnTarget(context, ctx.turnId); - const state = context.runtime.getState().goal; - const budget = state === null ? null : toSnapshot(context, state).budget; - const turnBudgetBlocksCurrentTurn = - budget?.turnBudgetReached === true && - (context.effects.exhaustedTurnBudgetGoals.get(ctx.turnId) === goalId || - (state?.status === 'blocked' && - state.terminalReason?.startsWith(GOAL_BUDGET_BLOCK_PREFIX) === true)); - if ( - goalId === undefined || - state === null || - state.goalId !== goalId || - budget === null || - (!budget.tokenBudgetReached && - !budget.wallClockBudgetReached && - !turnBudgetBlocksCurrentTurn) - ) { - return false; - } - const maxSteps = context.runtime.get(IConfigService).get<LoopControl>(LOOP_CONTROL_SECTION)?.maxStepsPerTurn; - if ( - ctx.finishReason === 'tool_calls' && - !context.effects.budgetGraceTurns.has(ctx.turnId) && - hasStepBudgetRemaining(maxSteps, ctx.step) - ) { - context.effects.budgetGraceTurns.add(ctx.turnId); - reminderOf(context.runtime).notify(GOAL_BUDGET_STOP_REMINDER, { - variant: GOAL_BUDGET_STOP_REMINDER_NAME, - }); - return true; - } - ctx.stopTurn = true; - return true; -} - -function enqueueGoalOutcomeContinuation(context: GoalOperationContext, ctx: AfterStepContext): void { - if (context.effects.goalOutcomeContinuationTurns.has(ctx.turnId)) return; - const goalId = goalTurnTarget(context, ctx.turnId); - const outcomeGoalId = context.effects.goalOutcomeToolResultTurns.get(ctx.turnId); - context.effects.goalOutcomeToolResultTurns.delete(ctx.turnId); - if (goalId === undefined || outcomeGoalId !== goalId) return; - const state = context.runtime.getState().goal; - if (state !== null && state.goalId !== goalId) return; - context.effects.goalOutcomeContinuationTurns.add(ctx.turnId); - const maxSteps = context.runtime.get(IConfigService).get<LoopControl>(LOOP_CONTROL_SECTION)?.maxStepsPerTurn; - if (!hasStepBudgetRemaining(maxSteps, ctx.step)) return; - context.runtime.get(IAgentLoopService).enqueue(new ContinuationStepRequest()); -} - -async function handleTurnEnded(context: GoalOperationContext, - turnId: number, - result: Pick<TurnEnded, 'reason' | 'error'>, -): Promise<void> { - const { goalId, lifecycleGoalId, starterTurn } = clearTurnTracking(context, turnId); - const resumeContinuation = context.effects.resumeContinuation; - if (resumeContinuation?.turnId === turnId) context.effects.resumeContinuation = undefined; - if (resumeContinuation?.turnId === turnId && result.reason === 'cancelled') { - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active' || state.goalId !== resumeContinuation.goalId) { - return; - } - if (blockIfBudgetReached(context, state) !== null) return; - launchContinuationTurn(context, resumeContinuation.goalId); - return; - } - if (goalId === undefined || lifecycleGoalId === undefined) return; - const stepCapped = isMaxStepsTurnFailure(result); - if ( - !stepCapped && - (result.reason === 'blocked' || - result.reason === 'cancelled' || - result.reason === 'failed') - ) { - await settleAbnormalTurn(context, result, lifecycleGoalId); - return; - } - if (starterTurn) incrementGoalTurn(context, goalId); - - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active' || state.goalId !== lifecycleGoalId) return; - if (blockIfBudgetReached(context, state) !== null) return; - launchContinuationTurn(context, lifecycleGoalId, stepCapped); -} - -function clearTurnTracking( - context: GoalOperationContext, - turnId: number, -): { - readonly goalId?: string; - readonly lifecycleGoalId?: string; - readonly starterTurn: boolean; -} { - if (context.effects.pendingContinuation?.turnId === turnId) { - context.effects.pendingContinuation = undefined; - } - if (context.effects.liveTurnId === turnId) context.effects.liveTurnId = undefined; - const goalId = context.effects.goalDrivenTurns.get(turnId); - const lifecycleGoalId = goalTurnTarget(context, turnId); - const starterTurn = context.effects.goalStarterTurns.delete(turnId); - context.effects.goalDrivenTurns.delete(turnId); - context.effects.countedGoalTurns.delete(turnId); - context.effects.goalOutcomeToolResultTurns.delete(turnId); - context.effects.goalOutcomeContinuationTurns.delete(turnId); - context.effects.budgetGraceTurns.delete(turnId); - context.effects.pendingContinuationGoals.delete(turnId); - context.effects.goalTurnTargets.delete(turnId); - context.effects.exhaustedTurnBudgetGoals.delete(turnId); - return { goalId, lifecycleGoalId, starterTurn }; -} - -async function settleAbnormalTurn(context: GoalOperationContext, - result: Pick<TurnEnded, 'reason' | 'error'>, - goalId: string, -): Promise<boolean> { - if (!isActiveGoal(context, goalId)) return false; - if (result.reason === 'blocked') { - await markBlocked(context, { reason: 'Blocked by UserPromptSubmit hook' }); - return true; - } - if (result.reason === 'cancelled') { - await pauseOnInterrupt(context, { reason: 'Paused after interruption' }); - return true; - } - if (result.reason === 'failed') { - await pauseActiveGoal(context, { reason: goalFailurePauseReason(result.error) }); - return true; - } - return false; -} - -async function settleGoalAfterContinuationFailure(context: GoalOperationContext, - error: unknown, - goalId: string | undefined, -): Promise<void> { - if (goalId === undefined || !isActiveGoal(context, goalId)) return; - try { - const reason = pauseReasonWithMessage( - GOAL_CONTINUATION_FAILURE_PAUSE_PREFIX, - normalizeGoalErrorPayload(error).message, - ); - await pauseActiveGoal(context, { reason }, 'system'); - } catch { } -} - -function isWaitForAvailable(context: GoalOperationContext): boolean { - return ( - context.runtime.get(IFlagService).enabled(WAIT_FOR_FLAG_ID) && - context.runtime.get(IAgentToolRegistryService).resolve('WaitFor') !== undefined && - context.runtime.get(IAgentToolPolicyService).isToolActive('WaitFor') - ); -} - -function launchContinuationTurn(context: GoalOperationContext, goalId: string, stepCapped = false): void { - if (!isActiveGoal(context, goalId)) return; - if (context.effects.pendingContinuation !== undefined) return; - const prompt = stepCapped ? GOAL_STEP_CAP_CONTINUATION_PROMPT : GOAL_CONTINUATION_PROMPT; - const message: ContextMessage = { - role: 'user', - content: [ - { - type: 'text', - text: isWaitForAvailable(context) - ? `${prompt} ${GOAL_WAIT_FOR_GUIDANCE}` - : prompt, - }, - ], - toolCalls: [], - origin: GOAL_CONTINUATION_ORIGIN, - }; - const request = new MessageStepRequest(message, { - kind: 'goal_continuation', - admission: 'newTurn', - }); - const receipt = context.runtime.get(IAgentLoopService).enqueue(request); - const pending: PendingContinuation = { receipt, goalId }; - context.effects.pendingContinuation = pending; - void receipt.assigned - .then(({ turn }) => { - pending.turnId = turn.id; - if (!context.effects.goalDrivenTurns.has(turn.id)) { - context.effects.pendingContinuationGoals.set(turn.id, pending.goalId); - } - return turn.result; - }) - .finally(() => { - if (pending.turnId !== undefined) context.effects.pendingContinuationGoals.delete(pending.turnId); - if (context.effects.pendingContinuation === pending) context.effects.pendingContinuation = undefined; - }); -} - -function canLaunchContinuation(context: GoalOperationContext): boolean { - if (context.effects.liveTurnId !== undefined || context.effects.pendingContinuation !== undefined) return false; - const status = context.runtime.get(IAgentLoopService).status(); - return status.state === 'idle' && !status.hasPendingRequests; -} - -function isActiveGoal(context: GoalOperationContext, goalId: string): boolean { - const state = context.runtime.getState().goal; - return state?.status === 'active' && state.goalId === goalId; -} - -function isStaleGoalToolCall(context: GoalOperationContext, ctx: BeforeToolExecuteEvent): boolean { - const toolName = ctx.toolCall.name; - if (!isGoalMutationTool(toolName)) return false; - const goalId = goalTurnTarget(context, ctx.turnId); - if (goalId === undefined) return false; - return context.runtime.getState().goal?.goalId !== goalId; -} - -function goalTurnTarget(context: GoalOperationContext, turnId: number): string | undefined { - return context.effects.goalTurnTargets.get(turnId) ?? context.effects.goalDrivenTurns.get(turnId); -} - -function cancelPendingContinuation(context: GoalOperationContext, - preserveLiveContinuation = false, - reason?: unknown, -): void { - const pending = context.effects.pendingContinuation; - if (preserveLiveContinuation && pending?.turnId === context.effects.liveTurnId) return; - context.effects.pendingContinuation = undefined; - const cancellation = reason ?? abortError('Goal continuation cancelled'); - const aborted = pending?.receipt.abort(cancellation); - if (pending !== undefined && !aborted && pending.turnId !== undefined) { - context.runtime.get(IAgentLoopService).cancel(pending.turnId, cancellation); - } -} - -function normalizeAfterReplay(context: GoalOperationContext): void { - appendForkClearedReminder(context); - context.runtime.send({ type: 'goal.deadline.clear' }); - context.effects.liveWallClockStartedAt = undefined; - const state = context.runtime.getState().goal; - if (state === null) return; - if (state.status === 'complete') { - clearInternal(context, 'runtime', { emit: false, track: false }); - return; - } - if (state.status !== 'active') return; - - const reason = 'Paused after agent resume'; - void context.runtime.dispatch( - new GoalUpdate({ - agentId: context.runtime.agent.agentId, - status: 'paused', - reason, - wallClockMs: settleWallClock(context, state), - actor: 'runtime', - }), - ); - trackStatusChanged(context, requireState(context), 'runtime'); -} - -function appendForkClearedReminder(context: GoalOperationContext): void { - if (!context.runtime.getState().forkNotice.reminderPending) return; - reminderOf(context.runtime).notify(GOAL_FORK_CLEARED_REMINDER, { - variant: GOAL_FORK_CLEARED_REMINDER_NAME, - }); -} - -function clearInternal(context: GoalOperationContext, - actor: GoalActor, - opts: { readonly emit?: boolean; readonly track?: boolean; readonly preserveLiveContinuation?: boolean; } = {}, -): void { - if (context.runtime.getState().goal === null) return; - context.effects.resumeContinuation = undefined; - cancelPendingContinuation(context, opts.preserveLiveContinuation === true); - context.runtime.send({ type: 'goal.deadline.clear' }); - context.effects.liveWallClockStartedAt = undefined; - void context.runtime.dispatch(new GoalClear({ agentId: context.runtime.agent.agentId })); - if (opts.emit !== false) emitGoalUpdated(context, null); - if (opts.track !== false) context.runtime.get(ITelemetryService).track2('goal_cleared', { actor }); -} - -function applyLifecycle(context: GoalOperationContext, - state: GoalState, - status: GoalStatus, - reason: string | undefined, - actor: GoalActor, - opts: { - readonly preserveLiveContinuation?: boolean; - readonly cancellationReason?: unknown; - } = {}, -): GoalSnapshot { - const wallClockMs = settleWallClock(context, state); - const wallClockResumedAt = status === 'active' ? Date.now() : undefined; - if (status === 'active') { - context.effects.liveWallClockStartedAt = context.runtime.get(IGoalDeadlineScheduler).now(); - } else if (state.status === 'active') { - context.effects.resumeContinuation = undefined; - cancelPendingContinuation(context, - opts.preserveLiveContinuation === true, - opts.cancellationReason, - ); - context.runtime.send({ type: 'goal.deadline.clear' }); - context.effects.liveWallClockStartedAt = undefined; - } - void context.runtime.dispatch( - new GoalUpdate({ agentId: context.runtime.agent.agentId, status, reason, wallClockMs, wallClockResumedAt, actor }), - ); - const next = requireState(context); - if (status === 'active') adoptStarterTurn(context, actor); - if (status === 'active') refreshWallClockDeadline(context, next); - emitGoalUpdated(context, toSnapshot(context, next), { kind: 'lifecycle', status, reason, actor }); - trackStatusChanged(context, next, actor); - return toSnapshot(context, next); -} - -function trackStatusChanged(context: GoalOperationContext, state: GoalState, actor: GoalActor): void { - context.runtime.get(ITelemetryService).track2('goal_status_changed', { - actor, - status: state.status, - turns_used: state.turnsUsed, - tokens_used: state.tokensUsed, - wall_clock_ms: liveWallClockMs(context, state), - ...budgetTelemetryProperties(state.budgetLimits), - }); -} - -function requireState(context: GoalOperationContext): GoalState { - const state = context.runtime.getState().goal; - if (state === null) { - throw new Error2(ErrorCodes.GOAL_NOT_FOUND, 'No current goal'); - } - return state; -} - -function emitGoalUpdated(context: GoalOperationContext, snapshot: GoalSnapshot | null, change?: GoalChange): void { - void context.runtime.dispatch( - new GoalUpdated({ agentId: context.runtime.agent.agentId, snapshot, change }), - ); -} - -function settleWallClock(context: GoalOperationContext, state: GoalState): number { - if (state.status === 'active' && context.effects.liveWallClockStartedAt !== undefined) { - return ( - state.wallClockMs + - Math.max(0, context.runtime.get(IGoalDeadlineScheduler).now() - context.effects.liveWallClockStartedAt) - ); - } - if (state.status === 'active' && state.wallClockResumedAt !== undefined) { - return state.wallClockMs + Math.max(0, Date.now() - state.wallClockResumedAt); - } - return state.wallClockMs; -} - -function liveWallClockMs(context: GoalOperationContext, state: GoalState): number { - if (state.status === 'active' && context.effects.liveWallClockStartedAt !== undefined) { - return ( - state.wallClockMs + - Math.max(0, context.runtime.get(IGoalDeadlineScheduler).now() - context.effects.liveWallClockStartedAt) - ); - } - if (state.status === 'active' && state.wallClockResumedAt !== undefined) { - return state.wallClockMs + Math.max(0, Date.now() - state.wallClockResumedAt); - } - return state.wallClockMs; -} - -function statsOf(context: GoalOperationContext, state: GoalState): GoalChangeStats { - return { - turnsUsed: state.turnsUsed, - tokensUsed: state.tokensUsed, - wallClockMs: liveWallClockMs(context, state), - }; -} - -function toSnapshot(context: GoalOperationContext, state: GoalState): GoalSnapshot { - const wallClockMs = liveWallClockMs(context, state); - return { - goalId: state.goalId, - objective: state.objective, - completionCriterion: state.completionCriterion, - status: state.status, - turnsUsed: state.turnsUsed, - tokensUsed: state.tokensUsed, - wallClockMs, - budget: computeBudgetReport(state, wallClockMs), - terminalReason: state.terminalReason, - }; -} - -function blockIfBudgetReached(context: GoalOperationContext, state: GoalState): GoalSnapshot | null { - if (state.status !== 'active') return null; - const reason = goalBudgetBlockReason(toSnapshot(context, state).budget); - if (reason === undefined) return null; - return applyLifecycle(context, state, 'blocked', reason, 'runtime', { - preserveLiveContinuation: true, - }); -} - -function refreshWallClockDeadline(context: GoalOperationContext, _state: GoalState): void { - context.runtime.send({ type: 'goal.deadline.refresh' }); -} - -function wallClockDeadlineDelay(context: GoalOperationContext): number | undefined { - const state = context.runtime.getState().goal; - const budgetMs = state?.budgetLimits.wallClockBudgetMs; - if ( - state === null || - state.status !== 'active' || - budgetMs === undefined || - context.effects.liveWallClockStartedAt === undefined - ) return undefined; - return Math.max(0, budgetMs - liveWallClockMs(context, state)); -} - -function handleWallClockDeadline(context: GoalOperationContext): void { - context.runtime.send({ type: 'goal.deadline.clear' }); - const state = context.runtime.getState().goal; - if (state === null || state.status !== 'active') return; - const budgetMs = state.budgetLimits.wallClockBudgetMs; - if (budgetMs === undefined) return; - if (liveWallClockMs(context, state) < budgetMs) { - refreshWallClockDeadline(context, state); - return; - } - const reason = goalBudgetBlockReason(toSnapshot(context, state).budget); - if (reason === undefined) return; - const cancellation = abortError(reason); - const liveTurnId = context.effects.liveTurnId; - const pendingTurnId = context.effects.pendingContinuation?.turnId; - applyLifecycle(context, state, 'blocked', reason, 'runtime', { - cancellationReason: cancellation, - }); - if (liveTurnId !== undefined && liveTurnId !== pendingTurnId) { - context.runtime.get(IAgentLoopService).cancel(liveTurnId, cancellation); - } -} - -function computeBudgetReport(state: GoalState, wallClockMs: number): GoalBudgetReport { - const tokenBudget = state.budgetLimits.tokenBudget ?? null; - const turnBudget = state.budgetLimits.turnBudget ?? null; - const wallClockBudgetMs = state.budgetLimits.wallClockBudgetMs ?? null; - - const tokenBudgetReached = tokenBudget !== null && state.tokensUsed >= tokenBudget; - const turnBudgetReached = turnBudget !== null && state.turnsUsed >= turnBudget; - const wallClockBudgetReached = wallClockBudgetMs !== null && wallClockMs >= wallClockBudgetMs; - - return { - tokenBudget, - turnBudget, - wallClockBudgetMs, - remainingTokens: tokenBudget === null ? null : Math.max(0, tokenBudget - state.tokensUsed), - remainingTurns: turnBudget === null ? null : Math.max(0, turnBudget - state.turnsUsed), - remainingWallClockMs: - wallClockBudgetMs === null ? null : Math.max(0, wallClockBudgetMs - wallClockMs), - tokenBudgetReached, - turnBudgetReached, - wallClockBudgetReached, - overBudget: tokenBudgetReached || turnBudgetReached || wallClockBudgetReached, - }; -} - -function matchesGoal(state: GoalState, goalId: string | undefined): boolean { - return goalId === undefined || state.goalId === goalId; -} - -function isGoalMutationTool(toolName: string): boolean { - return toolName === 'CreateGoal' || toolName === 'UpdateGoal' || toolName === 'SetGoalBudget'; -} - -function toGoalStartReviewPermissionMode(label: string | undefined): PermissionMode | undefined { - if (label === 'auto' || label === 'yolo' || label === 'manual') return label; - return undefined; -} - -function goalBudgetBlockReason(budget: GoalBudgetReport): string | undefined { - const reached: string[] = []; - if (budget.turnBudgetReached) { - reached.push(`turn budget ${budget.turnBudget ?? ''}`.trim()); - } - if (budget.tokenBudgetReached) { - reached.push(`token budget ${budget.tokenBudget ?? ''}`.trim()); - } - if (budget.wallClockBudgetReached) { - reached.push(`wall-clock budget ${budget.wallClockBudgetMs ?? ''}ms`.trim()); - } - return reached.length === 0 ? undefined : `${GOAL_BUDGET_BLOCK_PREFIX}: ${reached.join(', ')}`; -} - -function budgetTelemetryProperties(limits: GoalBudgetLimits): GoalBudgetProperties { - return { - has_token_budget: limits.tokenBudget !== undefined, - has_turn_budget: limits.turnBudget !== undefined, - has_wall_clock_budget: limits.wallClockBudgetMs !== undefined, - }; -} - -function normalizeCompletionCriterion(value: string | undefined): string | undefined { - const trimmed = value?.trim(); - if (!trimmed?.length) return undefined; - return trimmed.length > MAX_GOAL_COMPLETION_CRITERION_LENGTH - ? trimmed.slice(0, MAX_GOAL_COMPLETION_CRITERION_LENGTH) - : trimmed; -} - -function hasStepBudgetRemaining(maxSteps: number | undefined, currentStep: number): boolean { - return maxSteps === undefined || maxSteps <= 0 || currentStep < maxSteps; -} - -function isTerminalUpdateGoalResult( - toolName: string, - args: unknown, - result: ExecutableToolResult, -): boolean { - if (toolName !== 'UpdateGoal' || result.isError === true || result.stopTurn !== true) { - return false; - } - if (!isPlainRecord(args)) return false; - const status = args['status']; - return status === 'complete' || status === 'blocked'; -} - -function isMaxStepsTurnFailure(result: Pick<TurnEnded, 'reason' | 'error'>): boolean { - return ( - result.reason === 'failed' && - normalizeGoalErrorPayload(result.error).code === LoopErrors.codes.LOOP_MAX_STEPS_EXCEEDED - ); -} - -function goalFailurePauseReason(error: unknown): string { - const payload = normalizeGoalErrorPayload(error); - switch (payload.code) { - case ErrorCodes.PROVIDER_RATE_LIMIT: - return GOAL_RATE_LIMIT_PAUSE_REASON; - case ErrorCodes.PROVIDER_CONNECTION_ERROR: - return pauseReasonWithMessage(GOAL_PROVIDER_CONNECTION_PAUSE_PREFIX, payload.message); - case ErrorCodes.PROVIDER_AUTH_ERROR: - return pauseReasonWithMessage(GOAL_PROVIDER_AUTH_PAUSE_PREFIX, payload.message); - case ErrorCodes.PROVIDER_FILTERED: - return GOAL_PROVIDER_FILTERED_PAUSE_REASON; - case ErrorCodes.PROVIDER_API_ERROR: - return pauseReasonWithMessage(GOAL_PROVIDER_API_PAUSE_PREFIX, payload.message); - case ErrorCodes.MODEL_NOT_CONFIGURED: - return pauseReasonWithMessage(GOAL_MODEL_CONFIG_PAUSE_PREFIX, LLM_NOT_SET_MESSAGE); - case ErrorCodes.MODEL_CONFIG_INVALID: - return pauseReasonWithMessage(GOAL_MODEL_CONFIG_PAUSE_PREFIX, payload.message); - default: - return pauseReasonWithMessage(GOAL_RUNTIME_PAUSE_PREFIX, payload.message); - } -} - -function normalizeGoalErrorPayload(error: unknown): KimiErrorPayload { - const payload = toKimiErrorPayload(error); - if (payload.code === ErrorCodes.MODEL_NOT_CONFIGURED) { - return { ...payload, message: LLM_NOT_SET_MESSAGE }; - } - return payload; -} - -function pauseReasonWithMessage(prefix: string, message: string | undefined): string { - const trimmed = message?.trim(); - return trimmed === undefined || trimmed.length === 0 ? prefix : `${prefix}: ${trimmed}`; -} - -function createGoalEffectHandlers(runtime: AgentRuntimeContext<GoalRuntimeState>) { - const context = goalOperationContext(runtime); - return { - deadlineDelay: () => wallClockDeadlineDelay(context), - deadlineFired: () => { handleWallClockDeadline(context); }, - injection: { - getGoal: () => getGoal(context).goal, - isWaitForEnabled: () => isWaitForAvailable(context), - }, - normalize: () => { normalizeAfterReplay(context); }, - turnStarted: (event: TurnStarted) => { handleTurnLaunched(context, event.turnId, event.origin); }, - usageRecorded: (usage: UsageRecordedContext) => { - if (usage.agent === runtime.agent) handleUsageRecorded(context, usage); - }, - beforeStep: (step: BeforeStepContext) => handleBeforeStep(context, step), - afterStep: (step: AfterStepContext) => { handleAfterStep(context, step); }, - approval: (event: BeforeToolExecuteEvent) => { - const permissionMode = runtime.get(IAgentPermissionModeService); - if ( - event.toolCall.name !== 'CreateGoal' || - permissionMode.mode === 'auto' || - event.execution.display?.kind !== 'goal_start' - ) return; - event.waitUntil(async () => runtime.get(IAgentToolApprovalService).requestToolApproval( - event, - { - kind: 'ask', - resolveApproval: (approval) => { - if (approval.decision !== 'approved') return undefined; - const mode = toGoalStartReviewPermissionMode(approval.selectedLabel); - if (mode !== undefined && mode !== permissionMode.mode) permissionMode.setMode(mode); - return undefined; - }, - }, - 'goal-start-review-ask', - )); - }, - veto: (event: BeforeToolExecuteEvent) => { - if (isStaleGoalToolCall(context, event)) { - event.veto({ output: GOAL_STALE_TOOL_RESULT }); - return; - } - if (context.effects.budgetGraceTurns.has(event.turnId)) { - event.veto({ output: GOAL_BUDGET_TOOLS_REJECTED_MESSAGE }); - } - }, - toolCompleted: (tool: Parameters<Parameters<IAgentToolExecutorService['hooks']['onDidExecuteTool']['register']>[1]>[0]) => { - const goalId = goalTurnTarget(context, tool.turnId); - if ( - goalId !== undefined && - isTerminalUpdateGoalResult(tool.toolCall.name, tool.args, tool.result) - ) context.effects.goalOutcomeToolResultTurns.set(tool.turnId, goalId); - }, - turnEnded: (event: TurnEnded) => { - const goalId = goalTurnTarget(context, event.turnId); - void handleTurnEnded(context, event.turnId, { reason: event.reason, error: event.error }).catch( - (error) => settleGoalAfterContinuationFailure(context, error, goalId), - ); - }, - }; -} - -const goalEffects = fromCallback(({ - input, - receive, -}: { - input: { - readonly runtime: AgentRuntimeContext<GoalRuntimeState>; - readonly restore: AgentRuntimeRestoreEvent; - }; - receive: (listener: (event: GoalEffectEvent) => void) => void; -}) => { - const handlers = createGoalEffectHandlers(input.runtime); - const deadline = new MutableDisposable<IDisposable>(); - receive((event) => { - deadline.clear(); - if (event.type === 'goal.deadline.refresh') { - const delay = handlers.deadlineDelay(); - if (delay !== undefined) { - deadline.value = input.runtime.get(IGoalDeadlineScheduler).schedule(delay, handlers.deadlineFired); - } - } - }); - const disposables: IDisposable[] = [deadline]; - if (input.runtime.agent.agentId === MAIN_AGENT_ID) { - disposables.push(new GoalInjection(handlers.injection, reminderOf(input.runtime))); - disposables.push(input.runtime.get(IEventBus).subscribe(TurnStarted, handlers.turnStarted)); - disposables.push(input.runtime.get(ISessionUsageService).onDidRecord(handlers.usageRecorded)); - const loop = input.runtime.get(IAgentLoopService); - disposables.push(loop.hooks.onWillBeginStep.register('goal-count-turn', async (context, next) => { - await handlers.beforeStep(context); - await next(); - })); - disposables.push(loop.hooks.onDidFinishStep.register('goal-outcome-continuation', async (context, next) => { - handlers.afterStep(context); - await next(); - })); - const tools = input.runtime.get(IAgentToolExecutorService); - disposables.push(tools.onBeforeExecuteTool(handlers.approval)); - disposables.push(tools.onBeforeExecuteTool(handlers.veto)); - disposables.push(tools.hooks.onDidExecuteTool.register( - 'goal-outcome-tool-result', - async (context, next) => { - handlers.toolCompleted(context); - await next(); - }, - )); - disposables.push(input.runtime.get(IEventBus).subscribe(TurnEnded, handlers.turnEnded)); - handlers.normalize(); - } - input.restore.waitUntil(Promise.resolve()); - return () => { - for (let index = disposables.length - 1; index >= 0; index -= 1) { - disposables[index]!.dispose(); - } - }; -}); - -const goalActorLogic = setup({ - types: {} as { - context: GoalActorContext; - input: AgentRuntimeContext<GoalRuntimeState>; - events: GoalActorEvent; - }, - actors: { goalEffects }, -}).createMachine({ - context: ({ input }) => ({ - durable: { - goal: null, - forkNotice: { goalPresent: false, reminderPending: false }, - }, - effects: { - goalDrivenTurns: new Map(), - countedGoalTurns: new Set(), - goalStarterTurns: new Set(), - goalOutcomeToolResultTurns: new Map(), - goalOutcomeContinuationTurns: new Set(), - budgetGraceTurns: new Set(), - pendingContinuationGoals: new Map(), - goalTurnTargets: new Map(), - exhaustedTurnBudgetGoals: new Map(), - }, - runtime: input, - }), - initial: 'beforeRestore', - states: { - beforeRestore: { - on: { 'runtime.restore': 'active' }, - }, - active: { - invoke: { - id: 'goalEffects', - src: 'goalEffects', - input: ({ context, event }) => ({ - runtime: context.runtime, - restore: event as AgentRuntimeRestoreEvent, - }), - }, - on: { - 'goal.deadline.refresh': { actions: sendTo('goalEffects', ({ event }) => event) }, - 'goal.deadline.clear': { actions: sendTo('goalEffects', ({ event }) => event) }, - }, - }, - }, - on: { - 'goal.commit': { - actions: assign({ durable: ({ event }) => event.durable }), - }, - }, -}); - -export const AgentGoal = defineAgentRuntimeContract<GoalRuntime>('goal'); - -export const goalAgentRuntimeProvider = defineAgentRuntimeProvider<GoalRuntimeState, GoalRuntime>(AgentGoal, { - id: 'goal', - logic: goalActorLogic, - eager: true, - durable: { - events: [GoalCreate, GoalUpdate, GoalClear, GoalForked, ContextAppendMessage], - undoable: false, - transition: (state, event) => { - if (event instanceof GoalCreate) { - state.goal = { - goalId: event.goalId, - objective: event.objective, - completionCriterion: event.completionCriterion, - status: 'active', - turnsUsed: 0, - tokensUsed: 0, - wallClockMs: 0, - wallClockResumedAt: event.wallClockResumedAt, - budgetLimits: {}, - }; - state.forkNotice.goalPresent = true; - return; - } - if (event instanceof GoalUpdate) { - const s = state.goal; - if (s !== null) { - if (event.status !== undefined && event.status !== s.status) { - s.status = event.status; - s.terminalReason = event.status === 'active' ? undefined : event.reason; - s.wallClockResumedAt = event.status === 'active' ? event.wallClockResumedAt : undefined; - } - if (event.turnsUsed !== undefined && event.turnsUsed !== s.turnsUsed) { - s.turnsUsed = event.turnsUsed; - } - if (event.tokensUsed !== undefined && event.tokensUsed !== s.tokensUsed) { - s.tokensUsed = event.tokensUsed; - } - if (event.wallClockMs !== undefined && event.wallClockMs !== s.wallClockMs) { - s.wallClockMs = event.wallClockMs; - } - if ( - event.wallClockResumedAt !== undefined && - (event.status ?? s.status) === 'active' && - event.wallClockResumedAt !== s.wallClockResumedAt - ) { - s.wallClockResumedAt = event.wallClockResumedAt; - } - if (event.budgetLimits !== undefined && event.budgetLimits !== s.budgetLimits) { - s.budgetLimits = event.budgetLimits; - } - } - return; - } - if (event instanceof GoalClear) { - state.goal = null; - state.forkNotice.goalPresent = false; - return; - } - if (event instanceof GoalForked) { - state.goal = null; - state.forkNotice.reminderPending = - state.forkNotice.goalPresent || state.forkNotice.reminderPending; - state.forkNotice.goalPresent = false; - return; - } - if (event instanceof ContextAppendMessage) { - if (state.forkNotice.reminderPending && isGoalForkClearedReminder(event.message)) { - state.forkNotice.reminderPending = false; - } - } - }, - read: (snapshot) => (snapshot as GoalActorSnapshot).context.durable, - commit: (actor, durable) => { actor.send({ type: 'goal.commit', durable }); }, - }, - createApi: (context) => new GoalRuntime(context), - inspect: (snapshot) => { - const goal = (snapshot as GoalActorSnapshot).context.durable.goal; - if (goal === null) return null; - return { - goalId: goal.goalId, - objective: goal.objective, - status: goal.status, - turnsUsed: goal.turnsUsed, - tokensUsed: goal.tokensUsed, - wallClockMs: goal.wallClockMs, - budgetLimits: goal.budgetLimits, - terminalReason: goal.terminalReason, - }; - }, -}); - diff --git a/packages/agent-core-v2/src/features/goal/goalFeature.ts b/packages/agent-core-v2/src/features/goal/goalFeature.ts deleted file mode 100644 index 0d2e337ff..000000000 --- a/packages/agent-core-v2/src/features/goal/goalFeature.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { ScopeActivation } from '#/_base/di/instantiation'; -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { goalAgentRuntimeProvider } from './goalAgentRuntime'; -import { IGoalDeadlineScheduler } from './goalDeadlineScheduler'; -import { GoalDeadlineSchedulerService } from './goalDeadlineSchedulerService'; -import { ICreateGoalTool } from './tools/create-goal/create-goal'; -import { CreateGoalTool } from './tools/create-goal/createGoalTool'; -import { IGetGoalTool } from './tools/get-goal/get-goal'; -import { GetGoalTool } from './tools/get-goal/getGoalTool'; -import { ISetGoalBudgetTool } from './tools/set-goal-budget/set-goal-budget'; -import { SetGoalBudgetTool } from './tools/set-goal-budget/setGoalBudgetTool'; -import { IUpdateGoalTool } from './tools/update-goal/update-goal'; -import { UpdateGoalTool } from './tools/update-goal/updateGoalTool'; - -export class GoalFeature extends Feature { - static override readonly name = 'goal'; - - constructor() { - super(); - this.contributeAgentRuntime(goalAgentRuntimeProvider); - this.contributeService(LifecycleScope.App, IGoalDeadlineScheduler, GoalDeadlineSchedulerService, { - activation: ScopeActivation.OnDemand, - }); - this.contributeTool(ICreateGoalTool, CreateGoalTool, { - name: 'CreateGoal', - domain: 'goal', - }); - this.contributeTool(IGetGoalTool, GetGoalTool, { - name: 'GetGoal', - domain: 'goal', - }); - this.contributeTool(ISetGoalBudgetTool, SetGoalBudgetTool, { - name: 'SetGoalBudget', - domain: 'goal', - }); - this.contributeTool(IUpdateGoalTool, UpdateGoalTool, { - name: 'UpdateGoal', - domain: 'goal', - }); - } -} - -registerFeature(GoalFeature); diff --git a/packages/agent-core-v2/src/features/goal/goalOps.ts b/packages/agent-core-v2/src/features/goal/goalOps.ts deleted file mode 100644 index c8a22262d..000000000 --- a/packages/agent-core-v2/src/features/goal/goalOps.ts +++ /dev/null @@ -1,135 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; - -import type { - GoalActor, - GoalBudgetLimits, - GoalChange, - GoalSnapshot, - GoalStatus, -} from './types'; - -export interface GoalState { - readonly goalId: string; - readonly objective: string; - readonly completionCriterion?: string; - readonly status: GoalStatus; - readonly turnsUsed: number; - readonly tokensUsed: number; - readonly wallClockMs: number; - readonly wallClockResumedAt?: number; - readonly budgetLimits: GoalBudgetLimits; - readonly terminalReason?: string; -} - -export type GoalModelState = GoalState | null; - -const GoalStatusSchema = z.enum(['active', 'paused', 'blocked', 'complete']); - -const GoalActorSchema = z.enum(['user', 'model', 'runtime', 'system']); - -const GoalBudgetLimitsSchema = z - .object({ - tokenBudget: z.number().finite().nonnegative().optional(), - turnBudget: z.number().finite().nonnegative().optional(), - wallClockBudgetMs: z.number().finite().nonnegative().optional(), - }) - .strict(); - -const goalCreateSchema = z - .object({ - agentId: z.string(), - goalId: z.string(), - objective: z.string(), - completionCriterion: z.string().optional(), - wallClockResumedAt: z.number().finite().nonnegative().optional(), - status: GoalStatusSchema.optional(), - actor: GoalActorSchema.optional(), - budgetLimits: GoalBudgetLimitsSchema.optional(), - }) - .strip(); - -export class GoalCreate extends AgentEvent2<z.infer<typeof goalCreateSchema>> { - static override readonly type = 'goal.create'; - static override readonly durable = true; - static override readonly schema = goalCreateSchema; -} -export interface GoalCreate { - readonly agentId: string; - readonly goalId: string; - readonly objective: string; - readonly completionCriterion?: string; - readonly wallClockResumedAt?: number; - readonly status?: GoalStatus; - readonly actor?: GoalActor; - readonly budgetLimits?: GoalBudgetLimits; -} - -const goalUpdateSchema = z - .object({ - agentId: z.string(), - goalId: z.string().optional(), - status: GoalStatusSchema.optional(), - reason: z.string().optional(), - turnsUsed: z.number().finite().nonnegative().optional(), - tokensUsed: z.number().finite().nonnegative().optional(), - wallClockMs: z.number().finite().nonnegative().optional(), - wallClockResumedAt: z.number().finite().nonnegative().optional(), - budgetLimits: GoalBudgetLimitsSchema.optional(), - actor: GoalActorSchema.optional(), - }) - .strip(); - -export class GoalUpdate extends AgentEvent2<z.infer<typeof goalUpdateSchema>> { - static override readonly type = 'goal.update'; - static override readonly durable = true; - static override readonly schema = goalUpdateSchema; -} -export interface GoalUpdate { - readonly agentId: string; - readonly goalId?: string; - readonly status?: GoalStatus; - readonly reason?: string; - readonly turnsUsed?: number; - readonly tokensUsed?: number; - readonly wallClockMs?: number; - readonly wallClockResumedAt?: number; - readonly budgetLimits?: GoalBudgetLimits; - readonly actor?: GoalActor; -} - -const goalClearSchema = z.object({ agentId: z.string() }); - -export class GoalClear extends AgentEvent2<z.infer<typeof goalClearSchema>> { - static override readonly type = 'goal.clear'; - static override readonly durable = true; - static override readonly schema = goalClearSchema; -} -export interface GoalClear { - readonly agentId: string; -} - -const goalForkedSchema = z.object({ agentId: z.string() }); - -export class GoalForked extends AgentEvent2<z.infer<typeof goalForkedSchema>> { - static override readonly type = 'forked'; - static override readonly durable = true; - static override readonly schema = goalForkedSchema; -} -export interface GoalForked { - readonly agentId: string; -} - -export interface GoalUpdatedPayload { - readonly agentId: string; - snapshot: GoalSnapshot | null; - change?: GoalChange; -} - -export class GoalUpdated extends AgentEvent2<GoalUpdatedPayload> { - static override readonly type = 'goal.updated'; - static override readonly observable = true; -} -export interface GoalUpdated extends GoalUpdatedPayload {} diff --git a/packages/agent-core-v2/src/features/goal/tools/get-goal/get-goal.ts b/packages/agent-core-v2/src/features/goal/tools/get-goal/get-goal.ts deleted file mode 100644 index a7bb6438f..000000000 --- a/packages/agent-core-v2/src/features/goal/tools/get-goal/get-goal.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const GetGoalToolInputSchema = z.object({}).strict(); -export type GetGoalToolInput = z.infer<typeof GetGoalToolInputSchema>; - -export interface IGetGoalTool extends AgentTool<GetGoalToolInput> { readonly _serviceBrand: undefined } -export const IGetGoalTool = createDecorator<IGetGoalTool>('getGoalTool'); diff --git a/packages/agent-core-v2/src/features/interaction/interaction.ts b/packages/agent-core-v2/src/features/interaction/interaction.ts deleted file mode 100644 index 02ca59dee..000000000 --- a/packages/agent-core-v2/src/features/interaction/interaction.ts +++ /dev/null @@ -1,31 +0,0 @@ -export type InteractionKind = 'approval' | 'question' | 'user_tool'; - -export interface InteractionOrigin { - readonly agentId?: string; - readonly turnId?: number; -} - -export interface InteractionRequest<TPayload = unknown> { - readonly id?: string; - readonly kind: InteractionKind; - readonly payload: TPayload; - readonly origin?: InteractionOrigin; -} - -export interface Interaction<TPayload = unknown> { - readonly id: string; - readonly kind: InteractionKind; - readonly payload: TPayload; - readonly origin: InteractionOrigin; - readonly createdAt: number; -} - -export interface InteractionResolution { - readonly id: string; - readonly response: unknown; -} - -export interface InteractionPendingChangedEvent { - readonly pending: readonly string[]; -} - diff --git a/packages/agent-core-v2/src/features/interaction/interactionAgentRuntime.ts b/packages/agent-core-v2/src/features/interaction/interactionAgentRuntime.ts deleted file mode 100644 index 81b572658..000000000 --- a/packages/agent-core-v2/src/features/interaction/interactionAgentRuntime.ts +++ /dev/null @@ -1,273 +0,0 @@ -import { assign, fromCallback, setup, type Snapshot } from 'xstate'; - -import { Emitter, type Event } from '#/_base/event'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, -} from '#/agent/runtime/agentRuntime'; -import { IEventBus } from '#/app/event/eventBus'; - -import { - type Interaction, - type InteractionKind, - type InteractionPendingChangedEvent, - type InteractionRequest, - type InteractionResolution, -} from './interaction'; -import { - InteractionRequestEvent, - InteractionResolvedEvent, - type InteractionModelState, -} from './interactionOps'; - -const RECENTLY_RESOLVED_TTL_MS = 60_000; -const RECENTLY_RESOLVED_MAX = 256; - -interface PendingEntry { - readonly interaction: Interaction; - readonly resolve: (response: unknown) => void; -} - -interface InteractionEffectState { - readonly pending: Map<string, PendingEntry>; - readonly recentlyResolved: Map<string, number>; - nextId: number; - readonly changeEmitter: Emitter<InteractionPendingChangedEvent>; - readonly resolveEmitter: Emitter<InteractionResolution>; -} - -interface InteractionActorContext { - readonly records: InteractionModelState; - readonly effects: InteractionEffectState; - readonly runtime: AgentRuntimeContext<InteractionModelState>; -} - -interface InteractionCommitEvent { - readonly type: 'interaction.commit'; - readonly records: InteractionModelState; -} - -type InteractionActorSnapshot = Snapshot<unknown> & { readonly context: InteractionActorContext }; - -function rememberResolved(effects: InteractionEffectState, id: string): void { - const now = Date.now(); - for (const [key, resolvedAt] of effects.recentlyResolved) { - if (now - resolvedAt > RECENTLY_RESOLVED_TTL_MS) effects.recentlyResolved.delete(key); - } - while (effects.recentlyResolved.size >= RECENTLY_RESOLVED_MAX) { - const oldest = effects.recentlyResolved.keys().next().value; - if (oldest === undefined) break; - effects.recentlyResolved.delete(oldest); - } - effects.recentlyResolved.set(id, now); -} - -function recordResolved(runtime: AgentRuntimeContext<InteractionModelState>, id: string, response: unknown): void { - void runtime.dispatch( - new InteractionResolvedEvent({ - agentId: runtime.agent.agentId, - id, - response, - }), - ); -} - -function cancelTurnPending( - runtime: AgentRuntimeContext<InteractionModelState>, - effects: InteractionEffectState, - turnId: number, -): void { - let changed = false; - for (const [id, entry] of effects.pending) { - if (entry.interaction.origin?.turnId !== turnId) continue; - effects.pending.delete(id); - rememberResolved(effects, id); - const response = { cancelled: true, reason: 'turn_ended' }; - entry.resolve(response); - recordResolved(runtime, id, response); - effects.resolveEmitter.fire({ id, response }); - changed = true; - } - if (changed) effects.changeEmitter.fire({ pending: [...effects.pending.keys()] }); -} - -export class InteractionRuntime { - private readonly effects: InteractionEffectState; - - readonly onDidChangePending: Event<InteractionPendingChangedEvent>; - readonly onDidResolve: Event<InteractionResolution>; - - constructor(private readonly runtime: AgentRuntimeContext<InteractionModelState>) { - this.effects = runtime.getLogicState<InteractionActorContext>().effects; - this.onDidChangePending = this.effects.changeEmitter.event; - this.onDidResolve = this.effects.resolveEmitter.event; - } - - request<TPayload, TResponse>(req: InteractionRequest<TPayload>): Promise<TResponse> { - return new Promise<TResponse>((resolve) => { - this.park(req, resolve as (response: unknown) => void); - }); - } - - enqueue<TPayload>(req: InteractionRequest<TPayload>): Interaction { - return this.park(req, () => {}); - } - - respond(id: string, response: unknown): boolean { - const entry = this.effects.pending.get(id); - if (entry === undefined) return false; - this.effects.pending.delete(id); - rememberResolved(this.effects, id); - entry.resolve(response); - recordResolved(this.runtime, id, response); - this.effects.changeEmitter.fire({ pending: [...this.effects.pending.keys()] }); - this.effects.resolveEmitter.fire({ id, response }); - return true; - } - - listPending(kind?: InteractionKind): readonly Interaction[] { - const all = [...this.effects.pending.values()].map((p) => p.interaction); - return kind === undefined ? all : all.filter((i) => i.kind === kind); - } - - isRecentlyResolved(id: string): boolean { - const resolvedAt = this.effects.recentlyResolved.get(id); - if (resolvedAt === undefined) return false; - if (Date.now() - resolvedAt > RECENTLY_RESOLVED_TTL_MS) { - this.effects.recentlyResolved.delete(id); - return false; - } - return true; - } - - cancelPendingForTurn(turnId: number): void { - cancelTurnPending(this.runtime, this.effects, turnId); - } - - private park<TPayload>( - req: InteractionRequest<TPayload>, - resolve: (response: unknown) => void, - ): Interaction { - const id = req.id ?? `${this.runtime.agent.agentId}:interaction-${this.effects.nextId++}`; - if (this.effects.pending.has(id)) throw new Error(`Interaction "${id}" is already pending`); - const interaction: Interaction<TPayload> = { - id, - kind: req.kind, - payload: req.payload, - origin: req.origin ?? {}, - createdAt: Date.now(), - }; - this.effects.pending.set(id, { interaction, resolve }); - void this.runtime.dispatch( - new InteractionRequestEvent({ - agentId: this.runtime.agent.agentId, - id: interaction.id, - kind: interaction.kind, - toolCallId: readPayloadToolCallId(interaction.payload), - request: interaction.payload, - }), - ); - this.effects.changeEmitter.fire({ pending: [...this.effects.pending.keys()] }); - return interaction; - } -} - -function readPayloadToolCallId(payload: unknown): string | undefined { - if (typeof payload !== 'object' || payload === null) return undefined; - const value = (payload as Record<string, unknown>)['toolCallId']; - return typeof value === 'string' ? value : undefined; -} - -const interactionEffects = fromCallback(({ - input, -}: { - input: { - readonly runtime: AgentRuntimeContext<InteractionModelState>; - readonly effects: InteractionEffectState; - }; -}) => { - const subscription = input.runtime.get(IEventBus).subscribe(TurnEnded, (e) => { - cancelTurnPending(input.runtime, input.effects, e.turnId); - }); - return () => { - subscription.dispose(); - for (const entry of input.effects.pending.values()) { - entry.resolve({ cancelled: true, reason: 'agent_closed' }); - } - input.effects.pending.clear(); - input.effects.changeEmitter.dispose(); - input.effects.resolveEmitter.dispose(); - }; -}); - -const interactionActorLogic = setup({ - types: {} as { - context: InteractionActorContext; - input: AgentRuntimeContext<InteractionModelState>; - events: InteractionCommitEvent; - }, - actors: { interactionEffects }, -}).createMachine({ - context: ({ input }) => ({ - records: new Map(), - effects: { - pending: new Map(), - recentlyResolved: new Map(), - nextId: 0, - changeEmitter: new Emitter(), - resolveEmitter: new Emitter(), - }, - runtime: input, - }), - invoke: { - src: 'interactionEffects', - input: ({ context }) => ({ runtime: context.runtime, effects: context.effects }), - }, - on: { - 'interaction.commit': { - actions: assign({ records: ({ event }) => event.records }), - }, - }, -}); - -export const AgentInteraction = defineAgentRuntimeContract<InteractionRuntime>('interaction'); - -export const interactionAgentRuntimeProvider = defineAgentRuntimeProvider<InteractionModelState, InteractionRuntime>(AgentInteraction, { - id: 'interaction', - logic: interactionActorLogic, - durable: { - events: [InteractionRequestEvent, InteractionResolvedEvent], - undoable: false, - transition: (state, event) => { - if (event instanceof InteractionRequestEvent) { - state.set(event.id, { - id: event.id, - kind: event.kind, - toolCallId: event.toolCallId, - agentId: event.agentId, - request: event.request, - resolved: false, - }); - return; - } - if (event instanceof InteractionResolvedEvent) { - const existing = state.get(event.id); - if (existing === undefined) return; - state.set(event.id, { ...existing, resolved: true, response: event.response }); - } - }, - read: (snapshot) => (snapshot as InteractionActorSnapshot).context.records, - commit: (actor, records) => { actor.send({ type: 'interaction.commit', records }); }, - }, - createApi: (context) => new InteractionRuntime(context), - inspect: (snapshot) => { - const records = (snapshot as InteractionActorSnapshot).context.records; - return [...records.values()].map((record) => ({ - id: record.id, - kind: record.kind, - resolved: record.resolved, - })); - }, -}); diff --git a/packages/agent-core-v2/src/features/interaction/interactionFeature.ts b/packages/agent-core-v2/src/features/interaction/interactionFeature.ts deleted file mode 100644 index 36ebc1ca7..000000000 --- a/packages/agent-core-v2/src/features/interaction/interactionFeature.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; -import { interactionAgentRuntimeProvider } from '#/features/interaction/interactionAgentRuntime'; - -export class InteractionFeature extends Feature { - static override readonly name = 'interaction'; - - constructor() { - super(); - this.contributeAgentRuntime(interactionAgentRuntimeProvider); - } -} - -registerFeature(InteractionFeature); diff --git a/packages/agent-core-v2/src/features/interaction/interactionOps.ts b/packages/agent-core-v2/src/features/interaction/interactionOps.ts deleted file mode 100644 index e777d1375..000000000 --- a/packages/agent-core-v2/src/features/interaction/interactionOps.ts +++ /dev/null @@ -1,60 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; - -import type { InteractionKind } from './interaction'; - -export interface InteractionRecord { - readonly id: string; - readonly kind: InteractionKind; - readonly toolCallId?: string; - readonly agentId: string; - readonly request: unknown; - readonly resolved: boolean; - readonly response?: unknown; -} - -export type InteractionModelState = Map<string, InteractionRecord>; - -const interactionRequestSchema = z.object({ - agentId: z.string(), - id: z.string(), - kind: z.enum(['approval', 'question', 'user_tool']), - toolCallId: z.string().optional(), - request: z.unknown(), -}); - -export class InteractionRequestEvent extends AgentEvent2< - z.infer<typeof interactionRequestSchema> -> { - static override readonly type = 'interaction.request'; - static override readonly durable = true; - static override readonly schema = interactionRequestSchema; -} -export interface InteractionRequestEvent { - readonly agentId: string; - readonly id: string; - readonly kind: InteractionKind; - readonly toolCallId?: string; - readonly request: unknown; -} - -const interactionResolvedSchema = z.object({ - agentId: z.string(), - id: z.string(), - response: z.unknown(), -}); - -export class InteractionResolvedEvent extends AgentEvent2< - z.infer<typeof interactionResolvedSchema> -> { - static override readonly type = 'interaction.resolved'; - static override readonly durable = true; - static override readonly schema = interactionResolvedSchema; -} -export interface InteractionResolvedEvent { - readonly agentId: string; - readonly id: string; - readonly response: unknown; -} diff --git a/packages/agent-core-v2/src/features/interaction/sessionInteractions.ts b/packages/agent-core-v2/src/features/interaction/sessionInteractions.ts deleted file mode 100644 index 476e81db5..000000000 --- a/packages/agent-core-v2/src/features/interaction/sessionInteractions.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { DisposableStore, type IDisposable } from '#/_base/di/lifecycle'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { Error2, ErrorCodes } from '#/errors'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; - -import { AgentInteraction, type InteractionRuntime } from './interactionAgentRuntime'; -import { - type Interaction, - type InteractionKind, - type InteractionOrigin, - type InteractionPendingChangedEvent, - type InteractionRequest, - type InteractionResolution, -} from './interaction'; - -function runtimeFor(manager: IAgentLifecycleService, origin: InteractionOrigin | undefined): InteractionRuntime { - const agentId = origin?.agentId ?? MAIN_AGENT_ID; - const context = manager.get(agentId); - if (context === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Agent "${agentId}" does not exist`, { - details: { agentId }, - }); - } - return manager.resolve(context, AgentInteraction); -} - -export function requestSessionInteraction<TPayload, TResponse>( - manager: IAgentLifecycleService, - req: InteractionRequest<TPayload>, -): Promise<TResponse> { - assertAvailableId(manager, req.id); - return runtimeFor(manager, req.origin).request(req); -} - -export function enqueueSessionInteraction<TPayload>( - manager: IAgentLifecycleService, - req: InteractionRequest<TPayload>, -): Interaction { - assertAvailableId(manager, req.id); - return runtimeFor(manager, req.origin).enqueue(req); -} - -function assertAvailableId(manager: IAgentLifecycleService, id: string | undefined): void { - if (id === undefined) return; - if (listSessionPendingInteractions(manager).some((interaction) => interaction.id === id)) { - throw new Error(`Interaction "${id}" is already pending`); - } -} - -export function respondSessionInteraction( - manager: IAgentLifecycleService, - id: string, - response: unknown, -): void { - for (const context of manager.list()) { - if (manager.resolve(context, AgentInteraction).respond(id, response)) return; - } -} - -export function listSessionPendingInteractions( - manager: IAgentLifecycleService, - kind?: InteractionKind, -): readonly Interaction[] { - return manager - .list() - .flatMap((context) => manager.resolve(context, AgentInteraction).listPending(kind)); -} - -export function isSessionInteractionRecentlyResolved(manager: IAgentLifecycleService, id: string): boolean { - for (const context of manager.list()) { - if (manager.resolve(context, AgentInteraction).isRecentlyResolved(id)) return true; - } - return false; -} - -export function onSessionInteractionDidChangePending( - manager: IAgentLifecycleService, - listener: (event: InteractionPendingChangedEvent) => void, -): IDisposable { - const store = new DisposableStore(); - const subscriptions = new Map<string, IDisposable>(); - const attach = (context: AgentContext): void => { - const subscription = manager.resolve(context, AgentInteraction).onDidChangePending(listener); - subscriptions.set(context.agentId, subscription); - store.add(subscription); - }; - const detach = (context: AgentContext): void => { - subscriptions.get(context.agentId)?.dispose(); - subscriptions.delete(context.agentId); - }; - for (const context of manager.list()) attach(context); - store.add(manager.onDidCreate((context) => attach(context))); - store.add(manager.onDidClose(detach)); - return store; -} - -export function onSessionInteractionDidResolve( - manager: IAgentLifecycleService, - listener: (event: InteractionResolution) => void, -): IDisposable { - const store = new DisposableStore(); - const subscriptions = new Map<string, IDisposable>(); - const attach = (context: AgentContext): void => { - const subscription = manager.resolve(context, AgentInteraction).onDidResolve(listener); - subscriptions.set(context.agentId, subscription); - store.add(subscription); - }; - const detach = (context: AgentContext): void => { - subscriptions.get(context.agentId)?.dispose(); - subscriptions.delete(context.agentId); - }; - for (const context of manager.list()) attach(context); - store.add(manager.onDidCreate((context) => attach(context))); - store.add(manager.onDidClose(detach)); - return store; -} diff --git a/packages/agent-core-v2/src/features/plan/configSection.ts b/packages/agent-core-v2/src/features/plan/configSection.ts index 6381e0980..1da8b802b 100644 --- a/packages/agent-core-v2/src/features/plan/configSection.ts +++ b/packages/agent-core-v2/src/features/plan/configSection.ts @@ -1,3 +1,15 @@ +/** + * `plan` domain — registers the `defaultPlanMode` config section into + * `config`. + * + * Top-level boolean preference (`default_plan_mode` on disk, v1-compatible): + * when `true`, every freshly created session starts in plan mode. Resumed / + * forked sessions restore plan state from wire records and ignore this. + * Stays on the static import=register channel (not the Feature's runtime + * contribution) so the section remains statically discoverable — the config + * manifest generator drains the module-level table. Bound at App scope. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/features/plan/exitPlanModeReview.ts b/packages/agent-core-v2/src/features/plan/exitPlanModeReview.ts index 548c68aeb..8b277625d 100644 --- a/packages/agent-core-v2/src/features/plan/exitPlanModeReview.ts +++ b/packages/agent-core-v2/src/features/plan/exitPlanModeReview.ts @@ -1,3 +1,16 @@ +/** + * `plan` domain — ExitPlanMode plan review. + * + * Owns the user-facing review that intercepts an `ExitPlanMode` call carrying + * a non-empty `plan_review` display: emits `plan_submitted` / `plan_resolved` + * through `telemetry`, drives the approval round-trip through `toolApproval` + * (origin `exit-plan-mode-review-ask`, matching the legacy permission + * policy's telemetry), and folds every approval outcome (approve with or + * without a selected option, Revise with feedback, Reject and Exit, dismiss) + * into a synthetic tool result, exiting plan mode through `plan` when the + * outcome deactivates it. + */ + import type { ApprovalResponse, PermissionPolicyResolution, diff --git a/packages/agent-core-v2/src/features/plan/injection/planModeInjection.ts b/packages/agent-core-v2/src/features/plan/injection/planModeInjection.ts index 6456a8e65..951c99320 100644 --- a/packages/agent-core-v2/src/features/plan/injection/planModeInjection.ts +++ b/packages/agent-core-v2/src/features/plan/injection/planModeInjection.ts @@ -1,6 +1,18 @@ +/** + * `plan` domain — plan-mode context injection. + * + * Owns the `plan_mode` context-injection provider: while plan mode is active it + * emits the full / sparse / re-entry reminders (deduped against recent history), + * and on the first inject after deactivation it emits the exit reminder. It reads + * the live plan state through `IAgentPlanService.status()` and the recent history + * through `IAgentContextMemoryService`, so no derived-state closures are needed. + * The plain-data state (`wasActive`) is registered into `agentState` + * (`IAgentStateService`) and read/written through it. + */ + import { Service } from '#/_base/di/service'; -import { defineState } from '#/state/state'; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; +import { defineState } from '#/_base/state/stateRegistry'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import type { ContextMessage } from '#/agent/contextMemory/types'; import { IAgentPlanService } from '#/features/plan/plan'; @@ -22,16 +34,16 @@ export const planWasActiveKey = defineState<boolean>('plan.wasActive', () => fal export class PlanModeInjection extends Service { constructor( - injector: ReminderRuntime, + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, @IAgentPlanService private readonly plan: IAgentPlanService, @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IAgentStateService private readonly states: IAgentStateService, ) { super(); - this.states.contributeState(planWasActiveKey); + this.states.register(planWasActiveKey); this._register( - injector.register(PLAN_MODE_INJECTION_VARIANT, async ({ lastInjectedAt: injectedAt }) => { + dynamicInjector.register(PLAN_MODE_INJECTION_VARIANT, async ({ lastInjectedAt: injectedAt }) => { const data = await this.plan.status(); if (data === null) { if (!this.states.get(planWasActiveKey)) return undefined; diff --git a/packages/agent-core-v2/src/features/plan/planFeature.ts b/packages/agent-core-v2/src/features/plan/planFeature.ts index 002c3fff7..f659ec877 100644 --- a/packages/agent-core-v2/src/features/plan/planFeature.ts +++ b/packages/agent-core-v2/src/features/plan/planFeature.ts @@ -1,3 +1,19 @@ +/** + * `plan` domain — `PlanFeature`: the plan-mode capability assembled as one + * App-scope Feature unit. + * + * Contributes the per-Agent `IAgentPlanService` and the `EnterPlanMode` / + * `ExitPlanMode` agent tools through the `features` base-class seams; + * retracting the unit withdraws all of them across the scope tree. The + * `defaultPlanMode` config section (`features/plan/configSection`), the + * `plan` agent profile (`features/plan/profile`), and the `plan_mode.*` / + * `plan.revision` wire vocabulary (`features/plan/planOps`) stay on their + * static import=register channels — user-facing contracts must remain + * statically discoverable (config manifest) and wire records replayable even + * when the feature unit is retracted. Registered into the feature table at + * import. + */ + import { Feature } from '#/features/feature'; import { registerFeature } from '#/features/featureRegistry'; diff --git a/packages/agent-core-v2/src/features/plan/planOps.ts b/packages/agent-core-v2/src/features/plan/planOps.ts index 3cdda71af..6b20653bb 100644 --- a/packages/agent-core-v2/src/features/plan/planOps.ts +++ b/packages/agent-core-v2/src/features/plan/planOps.ts @@ -1,11 +1,43 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `plan` domain — wire Model (`PlanModel`) and the `plan_mode.enter` + * (`planModeEnter`) / `plan_mode.cancel` (`planModeCancel`) / `plan_mode.exit` + * (`planModeExit`) Ops that mirror the plan-mode lifecycle into a persisted, + * replayable `{ active, id }` state, plus the `plan.revision` + * (`planRevision`) Op that records a submitted plan revision as a + * reference-only fact. + * + * The Model holds the persistent, replayable fields — whether plan mode is + * active, the plan id, and the last recorded revision version per plan id — + * wrapped in `contextMemory`'s checkpoint protocol so plan mode stays aligned + * with conversation undo. The lifecycle records keep exactly v1's field set + * (`{ id }`); the plan file path is NOT persisted — it is derived from the id + * at read time, matching v1's `restoreEnter`. + * Plan content is recorded separately: every ExitPlanMode submit snapshots + * the plan file into blob storage and persists a `plan.revision` record + * carrying only the reference (`{ id, version, path, sha256, bytes }`, `path` + * homeDir-relative) — never the content. `revisionCount` tracks the latest + * version per plan id so `recordRevision` can mint the next version + * replay-consistently; it is kept across enter/exit so a re-entered plan id + * continues its counter instead of overwriting earlier blobs. Each `apply` + * returns the same reference on a no-op (re-entering the same plan, or + * cancelling/exiting while already inactive) so the wire's + * reference-equality gate stays quiet. The side effects — `telemetryContext` + * mode, plan-directory/file fs I/O, the blob write, and the + * `agent.status.updated` planMode slice — are NOT part of `apply`: they run + * after `wire.dispatch` on the live path, and `wire.replay` rebuilds the + * Model silently from the persisted `plan_mode.*` / `plan.revision` records. + * The legacy `toReplay: plan_updated` projection is dropped (inert — nothing + * reads it). `plan.revision` carries a `toEvent` so the live transcript + * projector can map it onto a marker plus the plan badge; replay never emits + * it. + */ + import { z } from 'zod'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -import '#/agent/contextMemory/conversationTime'; +import { + defineCheckpointedModel, + type Checkpointed, +} from '#/agent/contextMemory/conversationTime'; export interface PlanState { readonly active: boolean; @@ -13,50 +45,47 @@ export interface PlanState { readonly revisionCount?: Readonly<Record<string, number>>; } -const planModeEnterSchema = z.object({ agentId: z.string(), id: z.string() }); +export type PlanModelState = Checkpointed<PlanState>; -export class PlanModeEnter extends AgentEvent2<z.infer<typeof planModeEnterSchema>> { - static override readonly type = 'plan_mode.enter'; - static override readonly durable = true; - static override readonly schema = planModeEnterSchema; -} -export interface PlanModeEnter { - readonly agentId: string; - readonly id: string; -} +export const PlanModel = defineCheckpointedModel('plan', (): PlanState => ({ active: false })); -const planModeCancelSchema = z.object({ - agentId: z.string(), - id: z.string().optional(), +export const planModeEnter = PlanModel.defineOp('plan_mode.enter', { + schema: z.object({ id: z.string() }), + apply: (s, p) => + s.current.active && s.current.id === p.id + ? s + : { ...s, current: { active: true, id: p.id, revisionCount: s.current.revisionCount } }, + toEvent: () => ({ type: 'agent.status.updated' as const, planMode: true }), }); -export class PlanModeCancel extends AgentEvent2<z.infer<typeof planModeCancelSchema>> { - static override readonly type = 'plan_mode.cancel'; - static override readonly durable = true; - static override readonly schema = planModeCancelSchema; -} -export interface PlanModeCancel { - readonly agentId: string; - readonly id?: string; +declare module '#/wire/types' { + interface PersistedOpMap { + 'plan_mode.enter': typeof planModeEnter; + 'plan_mode.cancel': typeof planModeCancel; + 'plan_mode.exit': typeof planModeExit; + 'plan.revision': typeof planRevision; + } } -const planModeExitSchema = z.object({ - agentId: z.string(), - id: z.string().optional(), +export const planModeCancel = PlanModel.defineOp('plan_mode.cancel', { + schema: z.object({ id: z.string().optional() }), + apply: (s) => + s.current.active + ? { ...s, current: { active: false, revisionCount: s.current.revisionCount } } + : s, + toEvent: () => ({ type: 'agent.status.updated' as const, planMode: false }), }); -export class PlanModeExit extends AgentEvent2<z.infer<typeof planModeExitSchema>> { - static override readonly type = 'plan_mode.exit'; - static override readonly durable = true; - static override readonly schema = planModeExitSchema; -} -export interface PlanModeExit { - readonly agentId: string; - readonly id?: string; -} +export const planModeExit = PlanModel.defineOp('plan_mode.exit', { + schema: z.object({ id: z.string().optional() }), + apply: (s) => + s.current.active + ? { ...s, current: { active: false, revisionCount: s.current.revisionCount } } + : s, + toEvent: () => ({ type: 'agent.status.updated' as const, planMode: false }), +}); export interface PlanRevisionRecordedEvent { - readonly agentId: string; readonly id: string; readonly version: number; readonly path: string; @@ -64,47 +93,33 @@ export interface PlanRevisionRecordedEvent { readonly bytes: number; } -const planRevisionSchema = z.object({ - agentId: z.string(), - id: z.string(), - version: z.number(), - path: z.string(), - sha256: z.string(), - bytes: z.number(), -}); - -export class PlanRevision extends AgentEvent2<PlanRevisionRecordedEvent> { - static override readonly type = 'plan.revision'; - static override readonly durable = true; - static override readonly observable = true; - static override readonly schema = planRevisionSchema; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'plan.revision': PlanRevisionRecordedEvent; + } } -export interface PlanRevision extends PlanRevisionRecordedEvent {} -export const planKey = defineState('plan', (): PlanState => ({ active: false })) - .replayable({ schema: z.custom<PlanState>() }) - .undoable() - .on(PlanModeEnter, (s, e, ctx) => { - if (!(s.active && s.id === e.id)) { - s.active = true; - s.id = e.id; - } - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, planMode: true })); - }) - .on(PlanModeCancel, (s, e, ctx) => { - if (s.active) { - s.active = false; - delete s.id; - } - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, planMode: false })); - }) - .on(PlanModeExit, (s, e, ctx) => { - if (s.active) { - s.active = false; - delete s.id; - } - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, planMode: false })); - }) - .on(PlanRevision, (s, e) => { - s.revisionCount = { ...s.revisionCount, [e.id]: e.version }; - }); +export const planRevision = PlanModel.defineOp('plan.revision', { + schema: z.object({ + id: z.string(), + version: z.number(), + path: z.string(), + sha256: z.string(), + bytes: z.number(), + }), + apply: (s, p) => ({ + ...s, + current: { + ...s.current, + revisionCount: { ...s.current.revisionCount, [p.id]: p.version }, + }, + }), + toEvent: (p) => ({ + type: 'plan.revision' as const, + id: p.id, + version: p.version, + path: p.path, + sha256: p.sha256, + bytes: p.bytes, + }), +}); diff --git a/packages/agent-core-v2/src/features/plan/planService.ts b/packages/agent-core-v2/src/features/plan/planService.ts index 8c2173998..80aa641d4 100644 --- a/packages/agent-core-v2/src/features/plan/planService.ts +++ b/packages/agent-core-v2/src/features/plan/planService.ts @@ -1,3 +1,27 @@ +/** + * `plan` domain — `IAgentPlanService` implementation. + * + * Manages plan-mode state through `wire`, injects plan-mode context through + * `contextInjector`, writes optional plan files through `hostFileSystem`, + * and tags mode telemetry through `telemetry`. Also snapshots submitted plan + * revisions: `recordRevision` reads the current plan file, writes it + * atomically through `IBlobStore` under the agent's own persistence scope + * (`agentCtx.scope()`, i.e. the homeDir-relative + * `sessions/<ws>/<sid>/agents/<agentId>` root) with the key + * `plan/<id>/v<N>.md`, and dispatches a reference-only `plan.revision` op + * carrying the homeDir-relative path, sha256 and byte length. N comes from + * the Model's replayed per-id `revisionCount`, starting at 1. Also carries + * the plan-mode Harness constraints as an `onBeforeExecuteTool` veto + * listener: while a plan is active, Write/Edit calls targeting only the + * current plan file are allowed outright (`allow()`, ending all other + * adjudication), any other Write/Edit and every TaskStop/CronCreate/ + * CronDelete call is vetoed with a `toolApproval.formatDenyMessage`- + * formatted reason, and an `ExitPlanMode` call outside `auto` mode defers + * to a cold `waitUntil` factory running the `exitPlanModeReview` user + * review. Bound at Agent scope — contributed into every Agent scope by + * `PlanFeature` (`features/plan/planFeature`). + */ + import { createHash, randomUUID } from 'node:crypto'; import { dirname, join } from 'pathe'; @@ -7,8 +31,7 @@ import { unwrapErrorCause } from '#/_base/errors/errors'; import { Error2, ErrorCodes } from '#/errors'; import { generateHeroSlug } from '#/_base/utils/hero-slug'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { PlanModeInjection } from '#/features/plan/injection/planModeInjection'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; @@ -20,15 +43,13 @@ import type { BeforeToolExecuteEvent, ResolvedToolExecutionHookContext, } from '#/agent/toolExecutor/toolHooks'; -import { IAgentTelemetryContextService } from '#/app/telemetry/agentTelemetryContext'; import { IEventBus } from '#/app/event/eventBus'; +import { IAgentTelemetryContextService } from '#/app/telemetry/agentTelemetryContext'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { IBlobStore } from '#/persistence/interface/blobStore'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { ContextUndone } from '#/agent/undo/undoService'; +import { IWireService } from '#/wire/wire'; import type { ToolFileAccess } from '#/tool/toolContract'; import { IAgentPlanService, @@ -37,11 +58,11 @@ import { } from './plan'; import { ExitPlanModeReview } from './exitPlanModeReview'; import { - PlanModeCancel, - PlanModeEnter, - PlanModeExit, - planKey, - PlanRevision, + PlanModel, + planModeCancel, + planModeEnter, + planModeExit, + planRevision, } from './planOps'; export class AgentPlanService extends Service implements IAgentPlanService { @@ -53,43 +74,39 @@ export class AgentPlanService extends Service implements IAgentPlanService { @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, @IHostFileSystem private readonly hostFs: IHostFileSystem, @IBlobStore private readonly blobs: IBlobStore, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, + @IAgentContextInjectorService dynamicInjector: IAgentContextInjectorService, @IAgentTelemetryContextService private readonly telemetryContext: IAgentTelemetryContextService, @IEventBus eventBus: IEventBus, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, + @IWireService private readonly wire: IWireService, @ISessionContext private readonly sessionCtx: ISessionContext, @IAgentScopeContext private readonly agentCtx: IAgentScopeContext, @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, @IAgentToolApprovalService private readonly toolApproval: IAgentToolApprovalService, @IAgentPermissionModeService private readonly modeService: IAgentPermissionModeService, @ITelemetryService telemetry: ITelemetryService, - @IAgentStateService private readonly agentState: IAgentStateService, + @IAgentStateService states: IAgentStateService, ) { super(); - this.agentState.contributeState(planKey); this.review = new ExitPlanModeReview(this, this.toolApproval, telemetry); this._register( - this.dispatcher.hooks.onDidRestore.register('plan', async (_ctx, next) => { + this.wire.hooks.onDidRestore.register('plan', async (_ctx, next) => { this.restoreTelemetryMode(); await next(); }), ); this._register( - eventBus.subscribe(ContextUndone, () => { + eventBus.subscribe('context.undone', () => { this.restoreTelemetryMode(); - void this.dispatcher.dispatch( - new AgentStatusUpdated({ agentId: this.agentCtx.agentId, planMode: this.isActive }), - ); + eventBus.publish({ + type: 'agent.status.updated', + planMode: this.isActive, + }); }), ); - this._register( - activateReminderWhenReady(agentLifecycle, this.agentCtx, (reminder) => - new PlanModeInjection(reminder, this, this.context, agentState), - ), - ); + this._register(new PlanModeInjection(dynamicInjector, this, this.context, states)); this._register(this.registerPlanGuard(toolExecutor)); } @@ -147,11 +164,11 @@ export class AgentPlanService extends Service implements IAgentPlanService { } private get isActive(): boolean { - return this.agentState.get(planKey).active; + return this.wire.getModel(PlanModel).current.active; } private currentPlanFilePath(): PlanFilePath { - const state = this.agentState.get(planKey); + const state = this.wire.getModel(PlanModel).current; if (!state.active || state.id === undefined) return null; return this.planFilePathFor(state.id); } @@ -173,7 +190,7 @@ export class AgentPlanService extends Service implements IAgentPlanService { let enterRecorded = false; try { await this.ensurePlanDirectory(planFilePath); - await this.dispatcher.dispatch(new PlanModeEnter({ agentId: this.agentCtx.agentId, id })); + this.wire.dispatch(planModeEnter({ id })); this.telemetryContext.set({ mode: 'plan' }); enterRecorded = true; if (createFile) { @@ -188,7 +205,7 @@ export class AgentPlanService extends Service implements IAgentPlanService { } cancel(id?: string): void { - void this.dispatcher.dispatch(new PlanModeCancel({ agentId: this.agentCtx.agentId, id })); + this.wire.dispatch(planModeCancel({ id })); this.telemetryContext.set({ mode: 'agent' }); } @@ -199,12 +216,12 @@ export class AgentPlanService extends Service implements IAgentPlanService { } exit(id?: string): void { - void this.dispatcher.dispatch(new PlanModeExit({ agentId: this.agentCtx.agentId, id })); + this.wire.dispatch(planModeExit({ id })); this.telemetryContext.set({ mode: 'agent' }); } async recordRevision(): Promise<void> { - const state = this.agentState.get(planKey); + const state = this.wire.getModel(PlanModel).current; if (!state.active || state.id === undefined) return; const id = state.id; const content = await this.hostFs.readText(this.planFilePathFor(id)); @@ -213,9 +230,8 @@ export class AgentPlanService extends Service implements IAgentPlanService { const scope = this.agentCtx.scope(); const key = `plan/${id}/v${version}.md`; await this.blobs.put(scope, key, bytes); - await this.dispatcher.dispatch( - new PlanRevision({ - agentId: this.agentCtx.agentId, + this.wire.dispatch( + planRevision({ id, version, path: `${scope}/${key}`, @@ -226,7 +242,7 @@ export class AgentPlanService extends Service implements IAgentPlanService { } async status(): Promise<PlanData> { - const state = this.agentState.get(planKey); + const state = this.wire.getModel(PlanModel).current; if (!state.active || state.id === undefined) return null; const path = this.planFilePathFor(state.id); let content = ''; diff --git a/packages/agent-core-v2/src/features/plan/profile/plan.ts b/packages/agent-core-v2/src/features/plan/profile/plan.ts index 1c29497bf..b8996bed2 100644 --- a/packages/agent-core-v2/src/features/plan/profile/plan.ts +++ b/packages/agent-core-v2/src/features/plan/profile/plan.ts @@ -1,3 +1,12 @@ +/** + * `plan` domain — builtin `plan` profile contribution. + * + * Registers the read-only planning task-agent profile. The profile is + * self-contained: its structured `renderSystemPrompt` merges the shared base + * template with the planning role text at call time, so a child agent no + * longer inherits the parent's prompt through a runtime overlay. + */ + import { registerAgentProfile } from '#/app/agentProfileCatalog/contribution'; import { renderSystemPromptResult, @@ -22,8 +31,8 @@ const PLAN_ROLE = '1. What you already know from the information provided\n' + '2. What questions remain unanswered that would benefit from explore agent investigation\n' + '3. Your implementation plan (either preliminary if questions remain, or final if sufficient context exists)\n\n' + - 'You are a read-only planning agent: you can read and search files ' + - 'and consult the web, but you have no shell and no file-editing tools. ' + + 'You are a read-only planning agent: you can read and search files (Read, Glob, Grep, ReadMediaFile) ' + + 'and consult the web (WebSearch, FetchURL), but you have no shell and no file-editing tools. ' + 'Where the general instructions tell you to make changes with tools, that does not apply to you — ' + 'do not attempt to run commands or modify files. Your deliverable is the plan itself, returned as ' + 'your final message.'; diff --git a/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enter-plan-mode.ts b/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enter-plan-mode.ts index 171cc50d8..fcd299d40 100644 --- a/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enter-plan-mode.ts +++ b/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enter-plan-mode.ts @@ -1,3 +1,13 @@ +/** + * `plan` domain — `IEnterPlanModeTool` contract. + * + * Public contract of the EnterPlanMode tool — the plan-mode entry tool the + * LLM calls to enter plan mode directly: the (empty) input schema and the + * Agent-scope identifier used to resolve the implementation through the + * container. Entering plan mode does not require approval in any permission + * mode. Bound at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enterPlanModeTool.ts b/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enterPlanModeTool.ts index 981e667e6..eaf1b1c39 100644 --- a/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enterPlanModeTool.ts +++ b/packages/agent-core-v2/src/features/plan/tools/enter-plan-mode/enterPlanModeTool.ts @@ -1,3 +1,13 @@ +/** + * `plan` domain — `IEnterPlanModeTool` implementation. + * + * Enters plan mode through the plan service (`plan`), reporting an error when + * plan mode is already active, and tracks the `plan_enter_resolved` + * `auto_approved` outcome (`telemetry`). The result message walks the model + * through the plan-mode workflow, including the plan file path when the host + * provides one. Bound at Agent scope. + */ + import type { ToolExecution } from '#/tool/toolContract'; import { toInputJsonSchema } from '#/tool/input-schema'; import { ITelemetryService } from '#/app/telemetry/telemetry'; diff --git a/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exit-plan-mode.ts b/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exit-plan-mode.ts index 6a70ddc07..90f4ed0ff 100644 --- a/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exit-plan-mode.ts +++ b/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exit-plan-mode.ts @@ -1,3 +1,14 @@ +/** + * `plan` domain — `IExitPlanModeTool` contract. + * + * Public contract of the ExitPlanMode tool — the plan-mode exit tool the LLM + * calls to surface a finalised plan to the user and exit plan mode: the input + * schema (including the alternative-approach options, whose labels must be + * unique and must not reuse the reserved approval labels) and the Agent-scope + * identifier used to resolve the implementation through the container. Bound + * at Agent scope. + */ + import { z } from 'zod'; import { createDecorator } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exitPlanModeTool.ts b/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exitPlanModeTool.ts index 56bddc517..3d3357420 100644 --- a/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exitPlanModeTool.ts +++ b/packages/agent-core-v2/src/features/plan/tools/exit-plan-mode/exitPlanModeTool.ts @@ -1,3 +1,22 @@ +/** + * `plan` domain — `IExitPlanModeTool` implementation. + * + * Reads the plan file tracked by the plan service (`plan`) and flips plan + * mode off. Every submission — the moment the final content is read for the + * `plan_review` display — records a plan revision through + * `planMode.recordRevision()` (blob snapshot + `plan.revision` wire record), + * so a Revise → resubmit archives each reviewed version. + * + * `execute` runs only when no interactive review ask intercepted the call. In + * auto permission mode (`permissionMode`) the auto-mode-approve policy lets + * every call through before any ask can fire, so the result is worded as + * auto-approved (not user-reviewed), matching the `auto_approved` telemetry + * outcome (`telemetry`). In manual / yolo modes the review-ask policy owns + * the user-facing result; the only way `execute` still runs there is a + * configured or session allow/ask rule — an explicit user decision that keeps + * the user-approved output and the `approved` outcome. Bound at Agent scope. + */ + import type { ToolInputDisplay } from '#/tool/toolInputDisplay'; import type { ExecutableToolResult, ToolExecution } from '#/tool/toolContract'; diff --git a/packages/agent-core-v2/src/features/reminder/internal/reminderActivation.ts b/packages/agent-core-v2/src/features/reminder/internal/reminderActivation.ts deleted file mode 100644 index 94d91adeb..000000000 --- a/packages/agent-core-v2/src/features/reminder/internal/reminderActivation.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import type { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { AgentReminder, type ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import type { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; - -export function activateReminderWhenReady( - lifecycle: IAgentLifecycleService, - scope: IAgentScopeContext, - activate: (runtime: ReminderRuntime) => IDisposable, -): IDisposable { - let active: IDisposable | undefined; - const tryActivate = (): void => { - if (active !== undefined || lifecycle.handleOf(scope.agentId) === undefined) return; - active = activate(lifecycle.resolve(scope.agentContext, AgentReminder)); - }; - const created = lifecycle.onDidCreateScope(({ context }) => { - if (context === scope.agentContext) tryActivate(); - }); - tryActivate(); - return toDisposable(() => { - created.dispose(); - active?.dispose(); - }); -} diff --git a/packages/agent-core-v2/src/features/reminder/reminderAgentRuntime.ts b/packages/agent-core-v2/src/features/reminder/reminderAgentRuntime.ts deleted file mode 100644 index ed4eb67ee..000000000 --- a/packages/agent-core-v2/src/features/reminder/reminderAgentRuntime.ts +++ /dev/null @@ -1,308 +0,0 @@ -import { fromCallback, setup } from 'xstate'; - -import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import { ILogService } from '#/_base/log/log'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { isCompactionSummaryMessage } from '#/agent/contextMemory/compactionHandoff'; -import { ContextSpliced } from '#/agent/contextMemory/contextEvents'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import { IAgentLoopService, type BeforeStepContext } from '#/agent/loop/loop'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, - type AgentRuntimeRestoreEvent, -} from '#/agent/runtime/agentRuntime'; -import { IEventBus } from '#/app/event/eventBus'; - -import { wrapSystemReminder } from './systemReminder'; -import type { - ContextInjectionContent, - ContextInjectionContext, - ContextInjectionMessage, - ContextInjectionProvider, - ContextInjectionResult, - ReminderNotification, - ReminderRegistration, -} from './types'; - -interface ReminderEntry { - readonly provider: ContextInjectionProvider<unknown>; - readonly variant: string; -} - -const REMINDER_VARIANT_PRIORITY = new Map<string, number>([['date_change', -1]]); - -interface ReminderActorContext { - readonly entries: Set<ReminderEntry>; - readonly runtime: AgentRuntimeContext<null>; -} - -interface ReminderRegisterEvent { - readonly type: 'reminder.register'; - readonly entry: ReminderEntry; -} - -interface ReminderUnregisterEvent { - readonly type: 'reminder.unregister'; - readonly entry: ReminderEntry; -} - -type ReminderActorEvent = AgentRuntimeRestoreEvent | ReminderRegisterEvent | ReminderUnregisterEvent; - -function actorContext(runtime: AgentRuntimeContext<null>): ReminderActorContext { - return runtime.getLogicState<ReminderActorContext>(); -} - -function appendReminder( - runtime: AgentRuntimeContext<null>, - content: string, - notification: ReminderNotification, -): void { - runtime.get(IAgentContextMemoryService).append({ - role: 'user', - content: [{ type: 'text', text: wrapSystemReminder(content) }], - toolCalls: [], - origin: { - kind: 'injection', - variant: notification.variant, - ownerPromptId: notification.ownerPromptId, - }, - }); -} - -function providerContext( - runtime: AgentRuntimeContext<null>, - entry: ReminderEntry, - isNewTurn: boolean, -): ContextInjectionContext<unknown> { - const history = runtime.get(IAgentContextMemoryService).get(); - const injectedPositions = findInjections(history, entry.variant); - const lastInjectedAt = injectedPositions.at(-1) ?? null; - const lastInjection = lastInjectedAt === null ? undefined : history[lastInjectedAt]; - return { - injectedPositions, - lastInjectedAt, - lastInjection, - lastDisclosure: - lastInjection?.origin?.kind === 'injection' - ? lastInjection.origin.disclosure - : undefined, - isNewTurn, - }; -} - -async function injectEntry( - runtime: AgentRuntimeContext<null>, - entry: ReminderEntry, - isNewTurn: boolean, -): Promise<void> { - let content: Awaited<ReturnType<ContextInjectionProvider>>; - try { - content = await entry.provider(providerContext(runtime, entry, isNewTurn)); - } catch (error) { - runtime.get(ILogService).error('context provider failed; skipping it', { - name: entry.variant, - error, - }); - return; - } - if (!actorContext(runtime).entries.has(entry)) return; - appendResult(runtime, entry, content); -} - -function appendResult( - runtime: AgentRuntimeContext<null>, - entry: ReminderEntry, - content: ContextInjectionContent | ContextInjectionResult<unknown> | undefined, -): void { - if (content === undefined) return; - const result: ContextInjectionResult<unknown> = isInjectionResult(content) - ? content - : { content }; - const origin = { - kind: 'injection' as const, - variant: entry.variant, - disclosure: result.disclosure, - }; - const resolved = result.content; - if (typeof resolved === 'string') { - if (resolved.trim().length === 0) return; - runtime.get(IAgentContextMemoryService).append({ - role: 'user', - content: [{ type: 'text', text: wrapSystemReminder(resolved) }], - toolCalls: [], - origin, - }); - return; - } - if (isRawInjectionMessage(resolved)) { - const message = resolved.message; - if (message.content.length === 0 && (message.tools === undefined || message.tools.length === 0)) { - return; - } - runtime.get(IAgentContextMemoryService).append({ - role: message.role, - content: [...message.content], - toolCalls: [], - tools: message.tools, - origin, - }); - return; - } - if (resolved.length === 0) return; - runtime.get(IAgentContextMemoryService).append({ - role: 'user', - content: [...resolved], - toolCalls: [], - origin, - }); -} - -async function inject(runtime: AgentRuntimeContext<null>, isNewTurn: boolean): Promise<void> { - const entries = [...actorContext(runtime).entries].sort( - (left, right) => - (REMINDER_VARIANT_PRIORITY.get(left.variant) ?? 0) - - (REMINDER_VARIANT_PRIORITY.get(right.variant) ?? 0), - ); - for (const entry of entries) await injectEntry(runtime, entry, isNewTurn); -} - -const reminderEffects = fromCallback(({ input }: { input: { readonly runtime: AgentRuntimeContext<null> } }) => { - let compactionRearmPending = false; - const loop = input.runtime.get(IAgentLoopService); - const takeCompactionRearm = (): boolean => { - const pending = compactionRearmPending; - compactionRearmPending = false; - return pending; - }; - const reconcileAroundStep = async ( - context: BeforeStepContext, - next: (context?: BeforeStepContext) => Promise<void>, - ): Promise<void> => { - const rearmed = takeCompactionRearm(); - await inject(input.runtime, context.firstStepOfTurn || rearmed); - await next(); - if (takeCompactionRearm()) await inject(input.runtime, true); - }; - let hook: IDisposable; - try { - hook = loop.hooks.onWillBeginStep.register('context-injector', reconcileAroundStep, { - before: 'full-compaction', - }); - } catch { - hook = loop.hooks.onWillBeginStep.register('context-injector', reconcileAroundStep); - } - const splice = input.runtime.get(IEventBus).subscribe(ContextSpliced, (event) => { - if (isCompactionSplice(event)) compactionRearmPending = true; - }); - return () => { - splice.dispose(); - hook.dispose(); - actorContext(input.runtime).entries.clear(); - }; -}); - -const reminderActorLogic = setup({ - types: {} as { - context: ReminderActorContext; - input: AgentRuntimeContext<null>; - events: ReminderActorEvent; - }, - actors: { reminderEffects }, -}).createMachine({ - context: ({ input }) => ({ entries: new Set(), runtime: input }), - initial: 'beforeRestore', - states: { - beforeRestore: { - on: { 'runtime.restore': 'active' }, - }, - active: { - invoke: { - src: 'reminderEffects', - input: ({ context }) => ({ runtime: context.runtime }), - }, - }, - }, - on: { - 'reminder.register': { - actions: ({ context, event }) => { context.entries.add(event.entry); }, - }, - 'reminder.unregister': { - actions: ({ context, event }) => { context.entries.delete(event.entry); }, - }, - }, -}); - -export class ReminderRuntime { - constructor(private readonly runtime: AgentRuntimeContext<null>) {} - - register<D = unknown>(variant: string, provider: ContextInjectionProvider<D>): ReminderRegistration { - const entry: ReminderEntry = { - provider: provider as ContextInjectionProvider<unknown>, - variant, - }; - this.runtime.send({ type: 'reminder.register', entry }); - return toDisposable(() => { - try { - this.runtime.send({ type: 'reminder.unregister', entry }); - } catch {} - }); - } - - notify(content: string, notification: ReminderNotification): void { - appendReminder(this.runtime, content, notification); - } - - async reconcileWhenIdle(variant: string): Promise<void> { - const loop = this.runtime.get(IAgentLoopService); - const quiescence = loop.tryAcquireQuiescence(); - if (quiescence === undefined) return; - try { - for (const entry of actorContext(this.runtime).entries) { - if (entry.variant === variant) await injectEntry(this.runtime, entry, false); - } - } finally { - quiescence.dispose(); - } - } -} - -export const AgentReminder = defineAgentRuntimeContract<ReminderRuntime>('reminder'); - -export const reminderAgentRuntimeProvider = defineAgentRuntimeProvider<null, ReminderRuntime>( - AgentReminder, - { - id: 'reminder', - logic: reminderActorLogic, - eager: true, - createApi: (context) => new ReminderRuntime(context), - }, -); - -function isCompactionSplice(splice: { - readonly deleteCount: number; - readonly messages: readonly ContextMessage[]; -}): boolean { - return splice.deleteCount > 0 && splice.messages.some(isCompactionSummaryMessage); -} - -function isRawInjectionMessage( - content: Exclude<ContextInjectionContent, string>, -): content is { readonly message: ContextInjectionMessage } { - return !Array.isArray(content); -} - -function isInjectionResult( - content: ContextInjectionContent | ContextInjectionResult<unknown>, -): content is ContextInjectionResult<unknown> { - return typeof content === 'object' && content !== null && !Array.isArray(content) && 'content' in content; -} - -function findInjections(history: readonly ContextMessage[], variant: string): number[] { - const positions: number[] = []; - history.forEach((message, index) => { - if (message.origin?.kind === 'injection' && message.origin.variant === variant) positions.push(index); - }); - return positions; -} diff --git a/packages/agent-core-v2/src/features/reminder/reminderFeature.ts b/packages/agent-core-v2/src/features/reminder/reminderFeature.ts deleted file mode 100644 index 71b65f412..000000000 --- a/packages/agent-core-v2/src/features/reminder/reminderFeature.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { reminderAgentRuntimeProvider } from './reminderAgentRuntime'; - -export class ReminderFeature extends Feature { - static override readonly name = 'reminder'; - - constructor() { - super(); - this.contributeAgentRuntime(reminderAgentRuntimeProvider); - } -} - -registerFeature(ReminderFeature); diff --git a/packages/agent-core-v2/src/features/reminder/systemReminder.ts b/packages/agent-core-v2/src/features/reminder/systemReminder.ts deleted file mode 100644 index 2272a9962..000000000 --- a/packages/agent-core-v2/src/features/reminder/systemReminder.ts +++ /dev/null @@ -1,16 +0,0 @@ -import type { ContextMessage } from '#/agent/contextMemory/types'; - -const SYSTEM_REMINDER_PREFIX = '<system-reminder>\n'; -const SYSTEM_REMINDER_SUFFIX = '\n</system-reminder>'; - -export function wrapSystemReminder(content: string): string { - return `${SYSTEM_REMINDER_PREFIX}${content.trim()}${SYSTEM_REMINDER_SUFFIX}`; -} - -export function systemReminderContent(message: ContextMessage): string | undefined { - const text = message.content.map((part) => (part.type === 'text' ? part.text : '')).join(''); - if (!text.startsWith(SYSTEM_REMINDER_PREFIX) || !text.endsWith(SYSTEM_REMINDER_SUFFIX)) { - return undefined; - } - return text.slice(SYSTEM_REMINDER_PREFIX.length, text.length - SYSTEM_REMINDER_SUFFIX.length); -} diff --git a/packages/agent-core-v2/src/features/reminder/types.ts b/packages/agent-core-v2/src/features/reminder/types.ts deleted file mode 100644 index 0bb66679f..000000000 --- a/packages/agent-core-v2/src/features/reminder/types.ts +++ /dev/null @@ -1,43 +0,0 @@ -import type { IDisposable } from '#/_base/di/lifecycle'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import type { ContentPart } from '#/kosong/contract/message'; -import type { Tool } from '#/kosong/contract/tool'; - -export interface ContextInjectionContext<D = unknown> { - readonly injectedPositions: readonly number[]; - readonly lastInjectedAt: number | null; - readonly lastInjection?: ContextMessage; - readonly lastDisclosure?: D; - readonly isNewTurn: boolean; -} - -export interface ContextInjectionMessage { - readonly role: 'user' | 'system'; - readonly content: readonly ContentPart[]; - readonly tools?: readonly Tool[]; -} - -export type ContextInjectionContent = - | string - | readonly ContentPart[] - | { readonly message: ContextInjectionMessage }; - -export interface ContextInjectionResult<D = unknown> { - readonly content: ContextInjectionContent; - readonly disclosure?: D; -} - -export type ContextInjectionProvider<D = unknown> = ( - context: ContextInjectionContext<D>, -) => - | ContextInjectionContent - | ContextInjectionResult<D> - | undefined - | Promise<ContextInjectionContent | ContextInjectionResult<D> | undefined>; - -export interface ReminderRegistration extends IDisposable {} - -export interface ReminderNotification { - readonly variant: string; - readonly ownerPromptId?: string; -} diff --git a/packages/agent-core-v2/src/features/sessionInit/sessionInit.ts b/packages/agent-core-v2/src/features/sessionInit/sessionInit.ts deleted file mode 100644 index e441768c6..000000000 --- a/packages/agent-core-v2/src/features/sessionInit/sessionInit.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface ISessionInitService { - readonly _serviceBrand: undefined; - - generateAgentsMd(): Promise<void>; - - cancelInit(): void; -} - -export const ISessionInitService: ServiceIdentifier<ISessionInitService> = - createDecorator<ISessionInitService>('sessionInitService'); diff --git a/packages/agent-core-v2/src/features/sessionInit/sessionInitFeature.ts b/packages/agent-core-v2/src/features/sessionInit/sessionInitFeature.ts deleted file mode 100644 index 30d9f7c7c..000000000 --- a/packages/agent-core-v2/src/features/sessionInit/sessionInitFeature.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { ISessionInitService } from './sessionInit'; -import { SessionInitService } from './sessionInitService'; - -export class SessionInitFeature extends Feature { - static override readonly name = 'sessionInit'; - - constructor() { - super(); - this.contributeService( - LifecycleScope.Session, - ISessionInitService, - SessionInitService, - ); - } -} - -registerFeature(SessionInitFeature); diff --git a/packages/agent-core-v2/src/features/skill/catalog/builtin/registry.ts b/packages/agent-core-v2/src/features/skill/catalog/builtin/registry.ts deleted file mode 100644 index 93c094fae..000000000 --- a/packages/agent-core-v2/src/features/skill/catalog/builtin/registry.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { SkillDefinition } from '#/features/skill/catalog/types'; - -const _builtinSkillContributions: SkillDefinition[] = []; - -export function registerBuiltinSkill(skill: SkillDefinition): void { - const existingIndex = _builtinSkillContributions.findIndex( - (candidate) => candidate.name === skill.name, - ); - if (existingIndex >= 0) { - _builtinSkillContributions.splice(existingIndex, 1); - } - _builtinSkillContributions.push(skill); -} - -export function getBuiltinSkillContributions(): readonly SkillDefinition[] { - return _builtinSkillContributions; -} - -export function _clearBuiltinSkillContributionsForTests(): void { - _builtinSkillContributions.length = 0; -} diff --git a/packages/agent-core-v2/src/features/skill/catalog/skillDiscovery.ts b/packages/agent-core-v2/src/features/skill/catalog/skillDiscovery.ts deleted file mode 100644 index ab762323a..000000000 --- a/packages/agent-core-v2/src/features/skill/catalog/skillDiscovery.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; - -import type { SkillDefinition, SkillRoot, SkippedSkill } from './types'; - -export interface SkillDiscoveryResult { - readonly skills: readonly SkillDefinition[]; - readonly skipped: readonly SkippedSkill[]; - readonly scannedRoots: readonly string[]; - readonly scannedDirectories: readonly string[]; -} - -export interface ISkillDiscovery { - readonly _serviceBrand: undefined; - discover(roots: readonly SkillRoot[]): Promise<SkillDiscoveryResult>; -} - -export const ISkillDiscovery = createDecorator<ISkillDiscovery>('skillDiscovery'); diff --git a/packages/agent-core-v2/src/features/skill/catalog/skillSource.ts b/packages/agent-core-v2/src/features/skill/catalog/skillSource.ts deleted file mode 100644 index 9357e989f..000000000 --- a/packages/agent-core-v2/src/features/skill/catalog/skillSource.ts +++ /dev/null @@ -1,28 +0,0 @@ -import type { Event } from '#/_base/event'; - -import type { SkillDefinition, SkippedSkill } from './types'; - -export interface SkillContribution { - readonly skills: readonly SkillDefinition[]; - readonly skipped?: readonly SkippedSkill[]; - readonly scannedRoots?: readonly string[]; -} - -export const SKILL_SOURCE_PRIORITY = { - builtin: 0, - plugin: 5, - extra: 10, - user: 20, - workspace: 30, -} as const; - -export const PLUGIN_SKILL_SOURCE_ID = 'plugin'; -export const BUILTIN_SKILL_SOURCE_ID = 'builtin'; - -export interface ISkillSource { - readonly _serviceBrand: undefined; - readonly id: string; - readonly priority: number; - readonly onDidChange?: Event<void>; - load(): Promise<SkillContribution>; -} diff --git a/packages/agent-core-v2/src/features/skill/skill.ts b/packages/agent-core-v2/src/features/skill/skill.ts deleted file mode 100644 index 5bbb71a25..000000000 --- a/packages/agent-core-v2/src/features/skill/skill.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type { ContentPart } from '#/kosong/contract/message'; - -export interface SkillActivationInput { - readonly name: string; - readonly args?: string; - readonly content?: readonly ContentPart[]; -} - -export interface PromptSkillActivation { - readonly name: string; - readonly args?: string; -} - -export interface PromptWithSkillsInput { - readonly input: readonly ContentPart[]; - readonly skills: readonly PromptSkillActivation[]; -} - -export interface PromptWithSkillsResult { - readonly turn_id?: number; - readonly prompt_id: string; - readonly created_at: string; - readonly state: 'running' | 'queued' | 'blocked'; -} diff --git a/packages/agent-core-v2/src/features/skill/skillAgentRuntime.ts b/packages/agent-core-v2/src/features/skill/skillAgentRuntime.ts deleted file mode 100644 index 9dfb2b915..000000000 --- a/packages/agent-core-v2/src/features/skill/skillAgentRuntime.ts +++ /dev/null @@ -1,269 +0,0 @@ -import { randomUUID } from 'node:crypto'; - -import type { - BundledSkillActivation, - ContextMessage, - SkillActivationOrigin, -} from '#/agent/contextMemory/types'; -import { IAgentLoopService, type Turn } from '#/agent/loop/loop'; -import { IAgentPromptService, reservePrompt, type PromptLaunchResult } from '#/agent/prompt/prompt'; -import { promptMetadataTextFromContentParts } from '#/agent/prompt/promptMetadataText'; -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, -} from '#/agent/runtime/agentRuntime'; -import { IEventService } from '#/app/event/event'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { ErrorCodes, Error2 } from '#/errors'; -import type { ContentPart } from '#/kosong/contract/message'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { applyPromptMetadataUpdate } from '#/session/sessionMetadata/promptMetadata'; - -import { isUserActivatableSkillType, type SkillDefinition } from './catalog/types'; -import { promptMetadataTextFromSkill, renderUserSlashSkillPrompt } from './prompt'; -import { ISessionSkillCatalog } from './session/skillCatalog'; -import type { - PromptSkillActivation, - PromptWithSkillsInput, - PromptWithSkillsResult, - SkillActivationInput, -} from './skill'; -import { SkillActivated } from './skillOps'; - -export class SkillRuntime { - constructor(private readonly context: AgentRuntimeContext<null>) {} - - async activate(input: SkillActivationInput): Promise<PromptLaunchResult> { - const catalog = this.context.get(ISessionSkillCatalog); - await catalog.ready; - const skill = catalog.catalog.getSkill(input.name); - if (skill === undefined) { - throw new Error2(ErrorCodes.SKILL_NOT_FOUND, `Skill "${input.name}" was not found`); - } - if (!isUserActivatableSkillType(skill.metadata.type)) { - throw new Error2( - ErrorCodes.SKILL_TYPE_UNSUPPORTED, - `Skill "${skill.name}" cannot be activated by the user`, - ); - } - - const skillArgs = input.args ?? ''; - const skillContent = this.renderSkillPrompt(skill, skillArgs); - const content: ContentPart[] = [ - { - type: 'text', - text: renderUserSlashSkillPrompt({ - skillName: skill.name, - skillArgs, - skillContent, - skillSource: skill.source, - skillDir: skill.dir, - }), - }, - ...(input.content ?? []), - ]; - - const turn = await this.recordActivation( - { - kind: 'skill_activation', - activationId: randomUUID(), - skillName: skill.name, - trigger: 'user-slash', - skillType: skill.metadata.type, - skillPath: skill.path, - skillSource: skill.source, - skillArgs: input.args, - }, - content, - ); - if (turn === undefined) { - throw new Error2( - ErrorCodes.TURN_AGENT_BUSY, - 'Cannot activate skill while another turn is active', - ); - } - if (this.context.agent.agentId === MAIN_AGENT_ID) { - await applyPromptMetadataUpdate( - { - metadata: this.context.get(ISessionMetadata), - eventService: this.context.get(IEventService), - sessionId: this.context.get(ISessionContext).sessionId, - }, - promptMetadataTextFromSkill(input), - ); - } - return { turn_id: turn.id }; - } - - async promptWithSkills(input: PromptWithSkillsInput): Promise<PromptWithSkillsResult> { - if (input.input.length === 0) { - throw new Error2(ErrorCodes.REQUEST_INVALID, 'promptWithSkills requires a non-empty prompt'); - } - if (input.skills.length === 0) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - 'promptWithSkills requires at least one skill', - ); - } - const catalog = this.context.get(ISessionSkillCatalog); - await catalog.ready; - const prepared = input.skills.map((skill) => this.prepareBundled(skill)); - if (this.context.agent.agentId === MAIN_AGENT_ID) { - await applyPromptMetadataUpdate( - { - metadata: this.context.get(ISessionMetadata), - eventService: this.context.get(IEventService), - sessionId: this.context.get(ISessionContext).sessionId, - }, - promptMetadataTextFromContentParts(input.input), - ); - } - for (const activation of prepared) { - void this.recordActivation(activation.origin); - } - const prompt = this.context.get(IAgentPromptService); - const reservation = reservePrompt(prompt); - try { - const handle = await reservation.submit({ - role: 'user', - content: [...prepared.map((activation) => activation.part), ...input.input], - toolCalls: [], - origin: { - kind: 'user', - skillActivations: prepared.map((activation) => activation.entry), - }, - }); - if (handle.state === 'pending') { - return { prompt_id: handle.id, created_at: handle.createdAt, state: 'queued' }; - } - const turn = await handle.launched; - if (turn === undefined && handle.state !== 'blocked') { - throw new Error2(ErrorCodes.INTERNAL, 'promptWithSkills failed to launch a turn'); - } - return { - turn_id: turn?.id, - prompt_id: handle.id, - created_at: handle.createdAt, - state: handle.state === 'blocked' ? 'blocked' : 'running', - }; - } finally { - reservation.dispose(); - } - } - - recordModelToolActivation(origin: SkillActivationOrigin): void { - void this.recordActivation(origin); - } - - private prepareBundled(input: PromptSkillActivation): { - readonly origin: SkillActivationOrigin; - readonly part: ContentPart; - readonly entry: BundledSkillActivation; - } { - const catalog = this.context.get(ISessionSkillCatalog); - const skill = catalog.catalog.getSkill(input.name); - if (skill === undefined) { - throw new Error2(ErrorCodes.SKILL_NOT_FOUND, `Skill "${input.name}" was not found`); - } - if (!isUserActivatableSkillType(skill.metadata.type)) { - throw new Error2( - ErrorCodes.SKILL_TYPE_UNSUPPORTED, - `Skill "${skill.name}" cannot be activated by the user`, - ); - } - - const skillArgs = input.args ?? ''; - const skillContent = this.renderSkillPrompt(skill, skillArgs); - const origin: SkillActivationOrigin = { - kind: 'skill_activation', - activationId: randomUUID(), - skillName: skill.name, - trigger: 'user-slash', - skillType: skill.metadata.type, - skillPath: skill.path, - skillSource: skill.source, - skillArgs: input.args, - }; - return { - origin, - part: { - type: 'text', - text: renderUserSlashSkillPrompt({ - skillName: skill.name, - skillArgs, - skillContent, - skillSource: skill.source, - skillDir: skill.dir, - }), - }, - entry: { - activationId: origin.activationId, - skillName: origin.skillName, - skillArgs: origin.skillArgs, - skillType: origin.skillType, - skillPath: origin.skillPath, - skillSource: origin.skillSource, - }, - }; - } - - private async recordActivation( - origin: SkillActivationOrigin, - input?: readonly ContentPart[], - ): Promise<Turn | undefined> { - await this.context.dispatch( - new SkillActivated({ - agentId: this.context.agent.agentId, - activationId: origin.activationId, - skillName: origin.skillName, - trigger: origin.trigger, - skillArgs: origin.skillArgs, - skillPath: origin.skillPath, - skillSource: origin.skillSource, - }), - ); - this.publishActivation(origin); - - if (input === undefined) return undefined; - const message: ContextMessage = { - role: 'user', - content: [...input], - toolCalls: [], - origin, - }; - const prompt = this.context.get(IAgentPromptService); - if (this.context.get(IAgentLoopService).status().state === 'running') { - return prompt.inject(message); - } - return (await prompt.enqueue({ message })).launched; - } - - private renderSkillPrompt(skill: SkillDefinition, rawArgs: string): string { - return this.context.get(ISessionSkillCatalog).catalog.renderSkillPrompt(skill, rawArgs, { - sessionId: this.context.get(ISessionContext).sessionId, - }); - } - - private publishActivation(origin: SkillActivationOrigin): void { - const telemetry = this.context.get(ITelemetryService); - telemetry.track2('skill_invoked', { - skill_name: origin.skillName, - trigger: origin.trigger, - }); - if (origin.skillType === 'flow') { - telemetry.track2('flow_invoked', { - flow_name: origin.skillName, - }); - } - } -} - -export const AgentSkill = defineAgentRuntimeContract<SkillRuntime>('skill'); - -export const skillAgentRuntimeProvider = defineAgentRuntimeProvider<null, SkillRuntime>(AgentSkill, { - id: 'skill', - createApi: (context) => new SkillRuntime(context), -}); diff --git a/packages/agent-core-v2/src/features/skill/skillFeature.ts b/packages/agent-core-v2/src/features/skill/skillFeature.ts deleted file mode 100644 index 2d6a77a37..000000000 --- a/packages/agent-core-v2/src/features/skill/skillFeature.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { skillAgentRuntimeProvider } from './skillAgentRuntime'; -import { ISkillTool } from './tools/skill'; -import { SkillTool } from './tools/skillTool'; - -export class SkillFeature extends Feature { - static override readonly name = 'skill'; - - constructor() { - super(); - this.contributeAgentRuntime(skillAgentRuntimeProvider); - this.contributeTool(ISkillTool, SkillTool, { name: 'Skill', domain: 'skill' }); - } -} - -registerFeature(SkillFeature); diff --git a/packages/agent-core-v2/src/features/skill/skillOps.ts b/packages/agent-core-v2/src/features/skill/skillOps.ts deleted file mode 100644 index ca5e15ca9..000000000 --- a/packages/agent-core-v2/src/features/skill/skillOps.ts +++ /dev/null @@ -1,19 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import type { SkillSource } from '#/agent/contextMemory/types'; -import { AgentEvent2 } from '#/app/event/event2'; - -export interface SkillActivatedPayload { - readonly agentId: string; - readonly activationId: string; - readonly skillName: string; - readonly trigger: string; - readonly skillArgs?: string; - readonly skillPath?: string; - readonly skillSource?: SkillSource; -} - -export class SkillActivated extends AgentEvent2<SkillActivatedPayload> { - static override readonly type = 'skill.activated'; - static override readonly observable = true; -} -export interface SkillActivated extends SkillActivatedPayload {} diff --git a/packages/agent-core-v2/src/features/skill/workspace/runtimeSkillDiscovery.ts b/packages/agent-core-v2/src/features/skill/workspace/runtimeSkillDiscovery.ts deleted file mode 100644 index 602ff185a..000000000 --- a/packages/agent-core-v2/src/features/skill/workspace/runtimeSkillDiscovery.ts +++ /dev/null @@ -1,194 +0,0 @@ -import path from 'pathe'; - -import type { ILogService, LogPayload } from '#/_base/log/log'; -import type { ISkillDiscovery, SkillDiscoveryResult } from '#/features/skill/catalog/skillDiscovery'; -import { SkillParseError, UnsupportedSkillTypeError, parseSkillText } from '#/features/skill/catalog/parser'; -import type { SkillDefinition, SkillRoot, SkippedSkill } from '#/features/skill/catalog/types'; -import { normalizeSkillName } from '#/features/skill/catalog/types'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; - -const MAX_SKILL_SCAN_DEPTH = 8; - -export class RuntimeSkillDiscovery implements ISkillDiscovery { - declare readonly _serviceBrand: undefined; - - constructor( - private readonly log: ILogService, - private readonly fs: IHostFileSystem, - ) {} - - async discover(roots: readonly SkillRoot[]): Promise<SkillDiscoveryResult> { - return discoverRuntimeSkills(this.fs, roots, (message, payload) => this.log.warn(message, payload)); - } -} - -async function discoverRuntimeSkills( - fs: IHostFileSystem, - roots: readonly SkillRoot[], - warn?: (message: string, payload?: LogPayload) => void, -): Promise<SkillDiscoveryResult> { - const byDiscoveryKey = new Map<string, SkillDefinition>(); - const skipped: SkippedSkill[] = []; - const scannedDirectories: string[] = []; - - const register = async (input: { - readonly skillMdPath: string; - readonly skillDirName: string; - readonly root: SkillRoot; - readonly subSkillParentName?: string; - }): Promise<SkillDefinition | undefined> => { - try { - const text = await fs.readText(input.skillMdPath); - const parsed = parseSkillText({ - skillMdPath: input.skillMdPath, - skillDirName: input.skillDirName, - source: input.root.source, - text, - }); - const skill = input.subSkillParentName === undefined - ? parsed - : { - ...parsed, - name: qualifySubSkillName(input.subSkillParentName, parsed.name), - metadata: { ...parsed.metadata, isSubSkill: true }, - }; - const discovered = input.root.plugin === undefined ? skill : { ...skill, plugin: input.root.plugin }; - const key = input.root.plugin === undefined - ? normalizeSkillName(discovered.name) - : `${input.root.plugin.id}\0${normalizeSkillName(discovered.name)}`; - if (!byDiscoveryKey.has(key)) byDiscoveryKey.set(key, discovered); - return discovered; - } catch (error) { - if (error instanceof UnsupportedSkillTypeError) { - skipped.push({ - path: input.skillMdPath, - type: error.skillType, - reason: `unsupported skill type "${error.skillType}"`, - }); - } else if (error instanceof SkillParseError) { - warn?.(`Skipping invalid skill at ${input.skillMdPath}: ${error.message}`, error); - } else { - warn?.(`Skipping skill at ${input.skillMdPath} due to unexpected error`, error); - } - return undefined; - } - }; - - const isFile = async (value: string): Promise<boolean> => { - try { - return (await fs.stat(value)).isFile; - } catch { - return false; - } - }; - - const isDirectory = async (value: string): Promise<boolean> => { - try { - return (await fs.stat(value)).isDirectory; - } catch { - return false; - } - }; - - const walk = async ( - dirPath: string, - root: SkillRoot, - isTopLevel: boolean, - depth: number, - subSkillParentName?: string, - ): Promise<void> => { - if (depth > MAX_SKILL_SCAN_DEPTH) return; - if (root.scanMode === 'root-skill-only') { - const skillMdPath = path.join(dirPath, 'SKILL.md'); - if (await isFile(skillMdPath)) { - await register({ skillMdPath, skillDirName: path.basename(dirPath), root }); - } - return; - } - - let entries; - try { - entries = [...await fs.readdir(dirPath)].toSorted((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0); - } catch { - return; - } - scannedDirectories.push(dirPath); - - const directorySkills = new Set<string>(); - const subdirs: string[] = []; - for (const entry of entries) { - const entryPath = path.join(dirPath, entry.name); - const directory = entry.isDirectory || (entry.isSymbolicLink === true && await isDirectory(entryPath)); - if (directory && await isFile(path.join(entryPath, 'SKILL.md'))) { - directorySkills.add(entry.name); - } - if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue; - if (directory) subdirs.push(entry.name); - } - - const allowedSubSkillBundles = new Map<string, string>(); - for (const entry of directorySkills) { - const skill = await register({ - skillMdPath: path.join(dirPath, entry, 'SKILL.md'), - skillDirName: entry, - root, - subSkillParentName, - }); - if (skill !== undefined && hasSubSkillEnabled(skill)) { - allowedSubSkillBundles.set(entry, skill.name); - } - } - - if (isTopLevel) { - if (root.plugin !== undefined) { - const skillMdPath = path.join(dirPath, 'SKILL.md'); - if (await isFile(skillMdPath)) { - await register({ skillMdPath, skillDirName: path.basename(dirPath), root }); - } - } - for (const entry of entries) { - if (!entry.isFile || !entry.name.endsWith('.md') || entry.name === 'SKILL.md') continue; - const skillName = entry.name.slice(0, -'.md'.length); - if (directorySkills.has(skillName)) continue; - await register({ - skillMdPath: path.join(dirPath, entry.name), - skillDirName: skillName, - root, - }); - } - } - - for (const entry of subdirs) { - if (directorySkills.has(entry) && !allowedSubSkillBundles.has(entry)) continue; - await walk( - path.join(dirPath, entry), - root, - false, - depth + 1, - allowedSubSkillBundles.get(entry) ?? subSkillParentName, - ); - } - }; - - for (const root of roots) await walk(root.path, root, true, 0); - return { - skills: [...byDiscoveryKey.values()].toSorted((a, b) => a.name.localeCompare(b.name)), - skipped, - scannedRoots: roots.map((root) => root.path), - scannedDirectories, - }; -} - -function qualifySubSkillName(parentName: string, skillName: string): string { - if (skillName === parentName || skillName.startsWith(`${parentName}.`)) return skillName; - return `${parentName}.${skillName}`; -} - -function hasSubSkillEnabled(skill: SkillDefinition): boolean { - const nested = skill.metadata['metadata']; - const nestedFlag = typeof nested === 'object' && nested !== null - ? (nested as Record<string, unknown>)['has-sub-skill'] === true || - (nested as Record<string, unknown>)['hasSubSkill'] === true - : false; - return skill.metadata['has-sub-skill'] === true || skill.metadata['hasSubSkill'] === true || nestedFlag; -} diff --git a/packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalog.ts b/packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalog.ts deleted file mode 100644 index 1a41c8af2..000000000 --- a/packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalog.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; - -import type { SkillCatalog } from '#/features/skill/catalog/types'; -import type { ISessionSkillCatalogData } from '#/features/skill/session/skillCatalogData'; - -export interface IWorkspaceSkillCatalog { - readonly _serviceBrand: undefined; - - readonly ready: Promise<void>; - readonly catalog: SkillCatalog; - readonly onDidChange: Event<string>; - load(): Promise<void>; - reload(): Promise<void>; - reloadSources(ids: readonly string[]): Promise<void>; - sessionData(): ISessionSkillCatalogData; -} - -export const IWorkspaceSkillCatalog: ServiceIdentifier<IWorkspaceSkillCatalog> = - createDecorator<IWorkspaceSkillCatalog>('workspaceSkillCatalog'); diff --git a/packages/agent-core-v2/src/features/staleGuard/staleGuard.ts b/packages/agent-core-v2/src/features/staleGuard/staleGuard.ts deleted file mode 100644 index 83c05e900..000000000 --- a/packages/agent-core-v2/src/features/staleGuard/staleGuard.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface IStaleGuardService { - readonly _serviceBrand: undefined; - - recordedMtimeMs(path: string): number | undefined; -} - -export const IStaleGuardService: ServiceIdentifier<IStaleGuardService> = - createDecorator<IStaleGuardService>('staleGuardService'); diff --git a/packages/agent-core-v2/src/features/staleGuard/staleGuardFeature.ts b/packages/agent-core-v2/src/features/staleGuard/staleGuardFeature.ts deleted file mode 100644 index 46f323e41..000000000 --- a/packages/agent-core-v2/src/features/staleGuard/staleGuardFeature.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { ScopeActivation } from '#/_base/di/instantiation'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { IStaleGuardService } from './staleGuard'; -import { StaleGuardService } from './staleGuardService'; - -export class StaleGuardFeature extends Feature { - static override readonly name = 'staleGuard'; - - constructor() { - super(); - this.contributeAgentService(IStaleGuardService, StaleGuardService, { - activation: ScopeActivation.OnScopeCreated, - }); - } -} - -registerFeature(StaleGuardFeature); diff --git a/packages/agent-core-v2/src/features/staleGuard/staleGuardOps.ts b/packages/agent-core-v2/src/features/staleGuard/staleGuardOps.ts deleted file mode 100644 index 3016deb53..000000000 --- a/packages/agent-core-v2/src/features/staleGuard/staleGuardOps.ts +++ /dev/null @@ -1,41 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { Event2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -export type StaleGuardModelState = Map<string, number>; - -const staleGuardRecordedSchema = z.object({ - path: z.string(), - mtimeMs: z.number(), -}); - -export class StaleGuardRecorded extends Event2<z.infer<typeof staleGuardRecordedSchema>> { - static override readonly type = 'staleGuard.recorded'; - static override readonly durable = true; - static override readonly schema = staleGuardRecordedSchema; -} -export interface StaleGuardRecorded extends z.infer<typeof staleGuardRecordedSchema> {} - -const staleGuardClearedSchema = z.object({}); - -export class StaleGuardCleared extends Event2<z.infer<typeof staleGuardClearedSchema>> { - static override readonly type = 'staleGuard.cleared'; - static override readonly durable = true; - static override readonly schema = staleGuardClearedSchema; -} -export interface StaleGuardCleared extends z.infer<typeof staleGuardClearedSchema> {} - -export const staleGuardKey = defineState( - 'staleGuard', - (): StaleGuardModelState => new Map(), -).replayable({ - schema: z.custom<StaleGuardModelState>(), -}) - .on(StaleGuardRecorded, (s, e) => { - s.set(e.path, e.mtimeMs); - }) - .on(StaleGuardCleared, (s) => { - s.clear(); - }); diff --git a/packages/agent-core-v2/src/features/staleGuard/staleGuardService.ts b/packages/agent-core-v2/src/features/staleGuard/staleGuardService.ts deleted file mode 100644 index 3946e4c93..000000000 --- a/packages/agent-core-v2/src/features/staleGuard/staleGuardService.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Disposable } from '#/_base/di/lifecycle'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; -import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; -import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import type { - BeforeToolExecuteEvent, - ToolDidExecuteContext, -} from '#/agent/toolExecutor/toolHooks'; -import type { ToolCall } from '#/kosong/contract/message'; -import type { HostFileStat } from '#/os/interface/hostFileSystem'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import type { ToolAccesses, ToolFileAccessOperation } from '#/tool/toolContract'; - -import { IStaleGuardService } from './staleGuard'; -import { StaleGuardCleared, StaleGuardRecorded, staleGuardKey } from './staleGuardOps'; - -const WRITE_OPERATIONS: readonly ToolFileAccessOperation[] = ['write', 'readwrite']; -const READ_OPERATIONS: readonly ToolFileAccessOperation[] = ['read']; - -function accessedFilePath( - accesses: ToolAccesses | undefined, - operations: readonly ToolFileAccessOperation[], -): string | undefined { - for (const access of accesses ?? []) { - if (access.kind === 'file' && operations.includes(access.operation)) return access.path; - } - return undefined; -} - -function stringArg(args: unknown, key: string): string | undefined { - if (typeof args !== 'object' || args === null) return undefined; - const value = (args as Record<string, unknown>)[key]; - return typeof value === 'string' ? value : undefined; -} - -function callPathArg(call: ToolCall): string | undefined { - if (typeof call.arguments !== 'string') return undefined; - try { - return stringArg(JSON.parse(call.arguments), 'path'); - } catch { - return undefined; - } -} - -export class StaleGuardService extends Disposable implements IStaleGuardService { - declare readonly _serviceBrand: undefined; - - constructor( - @IAgentStateService private readonly states: IAgentStateService, - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentRuntimeService private readonly runtime: IAgentRuntimeService, - @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, - ) { - super(); - this.states.contributeState(staleGuardKey); - this._register(toolExecutor.onBeforeExecuteTool((event) => this.guardWrite(event))); - this._register( - toolExecutor.hooks.onDidExecuteTool.register('staleGuard', async (ctx, next) => { - await this.observeExecution(ctx); - await next(); - }), - ); - this._register( - this.runtime.onDidChange(() => { - void this.dispatcher.dispatch(new StaleGuardCleared({})); - }), - ); - } - - recordedMtimeMs(path: string): number | undefined { - return this.states.get(staleGuardKey).get(path); - } - - private guardWrite(event: BeforeToolExecuteEvent): void { - const name = event.toolCall.name; - if (name !== 'Edit' && name !== 'Write') return; - const path = accessedFilePath(event.execution.accesses, WRITE_OPERATIONS); - if (path === undefined) return; - const displayPath = stringArg(event.args, 'path') ?? path; - if (coveredByEarlierRead(event, displayPath)) return; - event.waitUntil(async () => { - const error = await this.checkWritable(path, displayPath); - return error === undefined ? undefined : { veto: denyToolExecution(error) }; - }); - } - - private async observeExecution(ctx: ToolDidExecuteContext): Promise<void> { - if (ctx.outcome !== 'executed' || ctx.result.isError === true) return; - const name = ctx.toolCall.name; - if (name === 'Read') { - const path = accessedFilePath(ctx.accesses, READ_OPERATIONS); - if (path !== undefined) await this.recordCurrentMtime(path); - return; - } - if (name === 'Edit' || name === 'Write') { - const path = accessedFilePath(ctx.accesses, WRITE_OPERATIONS); - if (path !== undefined) await this.recordCurrentMtime(path); - } - } - - private async checkWritable(path: string, displayPath: string): Promise<string | undefined> { - const stat = await this.statFile(path); - if (stat === undefined || stat.mtimeMs === undefined) return undefined; - const recorded = this.recordedMtimeMs(path); - if (recorded === undefined) { - return ( - `"${displayPath}" has not been read by this agent yet. ` + - 'Read the file before writing to it.' - ); - } - if (recorded !== stat.mtimeMs) { - return ( - `"${displayPath}" has been modified on disk since this agent last read it. ` + - 'Read the file again before writing to it.' - ); - } - return undefined; - } - - private async recordCurrentMtime(path: string): Promise<void> { - const stat = await this.statFile(path); - if (stat?.mtimeMs === undefined) return; - await this.dispatcher.dispatch(new StaleGuardRecorded({ path, mtimeMs: stat.mtimeMs })); - } - - private async statFile(path: string): Promise<HostFileStat | undefined> { - const lease = this.runtime.acquire(['fs']); - try { - const stat = await lease.runtime.fs!.stat(path); - return stat.isFile ? stat : undefined; - } catch { - return undefined; - } finally { - lease.dispose(); - } - } -} - -function coveredByEarlierRead(event: BeforeToolExecuteEvent, rawPath: string): boolean { - for (const call of event.toolCalls) { - if (call.id === event.toolCall.id) return false; - if (call.name === 'Read' && callPathArg(call) === rawPath) return true; - } - return false; -} diff --git a/packages/agent-core-v2/src/features/swarm/agent/injection/swarmInjection.ts b/packages/agent-core-v2/src/features/swarm/agent/injection/swarmInjection.ts deleted file mode 100644 index c07226ab3..000000000 --- a/packages/agent-core-v2/src/features/swarm/agent/injection/swarmInjection.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { Disposable } from '#/_base/di/lifecycle'; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import type { - ContextInjectionContext, - ContextInjectionResult, -} from '#/features/reminder/types'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; - -import SWARM_MODE_ENTER_REMINDER from '../enter-reminder.md?raw'; -import SWARM_MODE_EXIT_REMINDER from '../exit-reminder.md?raw'; -import type { SwarmModeTrigger } from '../swarm'; - -const SWARM_MODE_INJECTION_VARIANT = 'swarm_mode'; -const LEGACY_SWARM_MODE_EXIT_VARIANT = 'swarm_mode_exit'; - -interface SwarmModeInjectionDisclosure { - readonly kind: 'swarm_mode'; - readonly state: 'active' | 'inactive'; -} - -export interface SwarmInjectionOptions { - readonly getTrigger: () => SwarmModeTrigger | null; -} - -export class SwarmInjection extends Disposable { - constructor( - private readonly options: SwarmInjectionOptions, - injector: ReminderRuntime, - @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - ) { - super(); - this._register( - injector.register<SwarmModeInjectionDisclosure>( - SWARM_MODE_INJECTION_VARIANT, - (ctx) => this.reminder(ctx), - ), - ); - } - - private reminder( - ctx: ContextInjectionContext<SwarmModeInjectionDisclosure>, - ): ContextInjectionResult<SwarmModeInjectionDisclosure> | undefined { - const trigger = this.options.getTrigger(); - const active = trigger !== null && trigger !== 'tool'; - const rendered = this.renderedState(ctx); - if (active) { - return rendered === 'active' - ? undefined - : { - content: SWARM_MODE_ENTER_REMINDER, - disclosure: { kind: 'swarm_mode', state: 'active' }, - }; - } - return rendered === 'active' - ? { - content: SWARM_MODE_EXIT_REMINDER, - disclosure: { kind: 'swarm_mode', state: 'inactive' }, - } - : undefined; - } - - private renderedState( - ctx: ContextInjectionContext<SwarmModeInjectionDisclosure>, - ): 'active' | 'inactive' | undefined { - if (ctx.lastDisclosure !== undefined) return ctx.lastDisclosure.state; - const history = this.context.get(); - for (let i = history.length - 1; i >= 0; i--) { - const origin = history[i]!.origin; - if (origin?.kind !== 'injection') continue; - if (origin.variant === LEGACY_SWARM_MODE_EXIT_VARIANT) return 'inactive'; - if (origin.variant === SWARM_MODE_INJECTION_VARIANT) return 'active'; - } - return undefined; - } -} diff --git a/packages/agent-core-v2/src/features/swarm/agent/swarmService.ts b/packages/agent-core-v2/src/features/swarm/agent/swarmService.ts deleted file mode 100644 index ad7565228..000000000 --- a/packages/agent-core-v2/src/features/swarm/agent/swarmService.ts +++ /dev/null @@ -1,108 +0,0 @@ -import { Service } from '#/_base/di/service'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; -import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; -import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import { IEventBus } from '#/app/event/eventBus'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; - -import { SwarmInjection } from './injection/swarmInjection'; -import { IAgentSwarmService, type SwarmModeTrigger } from './swarm'; -import { SwarmModeEnter, SwarmModeExit, swarmKey } from '../swarmOps'; - -export class AgentSwarmService extends Service implements IAgentSwarmService { - declare readonly _serviceBrand: undefined; - - constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - @IEventBus eventBus: IEventBus, - @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @IAgentToolApprovalService private readonly toolApproval: IAgentToolApprovalService, - @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, - @IAgentScopeContext private readonly agentCtx: IAgentScopeContext, - @IAgentStateService private readonly agentState: IAgentStateService, - ) { - super(); - this.agentState.contributeState(swarmKey); - this._register( - activateReminderWhenReady(agentLifecycle, this.agentCtx, (reminder) => - new SwarmInjection( - { getTrigger: () => this.agentState.get(swarmKey) }, - reminder, - this.context, - ), - ), - ); - this._register( - eventBus.subscribe(TurnEnded, () => { - if (this.shouldAutoExit) { - this.exit(); - } - }), - ); - this._register( - toolExecutor.onBeforeExecuteTool((event) => { - const agentSwarmCount = event.toolCalls.filter( - (toolCall) => toolCall.name === 'AgentSwarm', - ).length; - if (agentSwarmCount === 0 || (agentSwarmCount === 1 && event.toolCalls.length === 1)) { - return; - } - event.veto( - denyToolExecution( - this.toolApproval.formatDenyMessage( - agentSwarmCount > 1 - ? multipleAgentSwarmDeniedMessage(event.toolCalls.length > agentSwarmCount) - : mixedAgentSwarmDeniedMessage(), - ), - ), - ); - }), - ); - } - - enter(trigger: SwarmModeTrigger): void { - if (this.agentState.get(swarmKey) !== null) return; - void this.dispatcher.dispatch(new SwarmModeEnter({ agentId: this.agentCtx.agentId, trigger })); - } - - exit(): void { - if (this.agentState.get(swarmKey) === null) return; - const history = this.context.get(); - void this.dispatcher.dispatch(new SwarmModeExit({ agentId: this.agentCtx.agentId })); - this.context.publishTrailingRemoval(history); - } - - get isActive(): boolean { - return this.agentState.get(swarmKey) !== null; - } - - private get shouldAutoExit(): boolean { - const trigger = this.agentState.get(swarmKey); - return trigger === 'task' || trigger === 'tool'; - } -} - -function multipleAgentSwarmDeniedMessage(hasOtherToolCalls: boolean): string { - const suffix = hasOtherToolCalls - ? ' AgentSwarm also must not be combined with other tools in the same response.' - : ''; - return ( - 'AgentSwarm must be called one swarm at a time. Multiple AgentSwarm calls are not forbidden, ' + - 'but issue them sequentially: call one AgentSwarm, wait for its result, then call the next; ' + - `or merge the work into a single AgentSwarm when one swarm can cover it.${suffix}` - ); -} - -function mixedAgentSwarmDeniedMessage(): string { - return ( - 'AgentSwarm must be the only tool call in a model response. Retry with a single AgentSwarm ' + - 'call by itself, then call any other tools after it returns.' - ); -} diff --git a/packages/agent-core-v2/src/features/swarm/configSection.ts b/packages/agent-core-v2/src/features/swarm/configSection.ts deleted file mode 100644 index 3d557aeb5..000000000 --- a/packages/agent-core-v2/src/features/swarm/configSection.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { z } from 'zod'; - -import { - type EnvBindings, - envBindings, - stripEnvBoundFields, - type IConfigService, -} from '#/app/config/config'; -import { registerConfigSection } from '#/app/config/configSectionContributions'; - -export const SWARM_SECTION = 'swarm'; - -export const SwarmConfigSchema = z.object({ - timeoutMs: z.number().int().min(0).optional(), -}); - -export type SwarmConfig = z.infer<typeof SwarmConfigSchema>; - -export const DEFAULT_SWARM_TIMEOUT_MS = 2 * 60 * 60 * 1000; - -export const SWARM_TIMEOUT_ENV = 'KIMI_CODE_SWARM_TIMEOUT_MS'; - -function parseTimeoutMsEnv(raw: string): number | undefined { - const parsed = Number(raw); - return Number.isInteger(parsed) && parsed >= 1 ? parsed : undefined; -} - -export const swarmEnvBindings: EnvBindings<SwarmConfig> = envBindings(SwarmConfigSchema, { - timeoutMs: { env: SWARM_TIMEOUT_ENV, parse: parseTimeoutMsEnv }, -}); - -export const stripSwarmEnv = stripEnvBoundFields(swarmEnvBindings); - -registerConfigSection(SWARM_SECTION, SwarmConfigSchema, { - defaultValue: { timeoutMs: DEFAULT_SWARM_TIMEOUT_MS }, - env: swarmEnvBindings, - stripEnv: stripSwarmEnv, -}); - -export function resolveSwarmTimeoutMs(config: IConfigService): number { - return ( - config.get<SwarmConfig | undefined>(SWARM_SECTION)?.timeoutMs ?? DEFAULT_SWARM_TIMEOUT_MS - ); -} diff --git a/packages/agent-core-v2/src/features/swarm/swarmFeature.ts b/packages/agent-core-v2/src/features/swarm/swarmFeature.ts deleted file mode 100644 index 80f7bb158..000000000 --- a/packages/agent-core-v2/src/features/swarm/swarmFeature.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { ScopeActivation } from '#/_base/di/instantiation'; -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { IAgentSwarmService } from './agent/swarm'; -import { AgentSwarmService } from './agent/swarmService'; -import { ISessionSwarmService } from './session/sessionSwarm'; -import { SessionSwarmService } from './session/sessionSwarmService'; -import { IAgentSwarmTool } from './tools/agent-swarm/agent-swarm'; -import { AgentSwarmTool } from './tools/agent-swarm/agentSwarmTool'; - -export class SwarmFeature extends Feature { - static override readonly name = 'swarm'; - - constructor() { - super(); - this.contributeAgentService(IAgentSwarmService, AgentSwarmService, { - activation: ScopeActivation.OnScopeCreated, - }); - this.contributeService(LifecycleScope.Session, ISessionSwarmService, SessionSwarmService, { - activation: ScopeActivation.OnScopeCreated, - }); - this.contributeTool(IAgentSwarmTool, AgentSwarmTool, { name: 'AgentSwarm', domain: 'swarm' }); - } -} - -registerFeature(SwarmFeature); diff --git a/packages/agent-core-v2/src/features/swarm/swarmOps.ts b/packages/agent-core-v2/src/features/swarm/swarmOps.ts deleted file mode 100644 index 46102c1dd..000000000 --- a/packages/agent-core-v2/src/features/swarm/swarmOps.ts +++ /dev/null @@ -1,49 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { contextMemoryKey, popSwarmModeReminder } from '#/agent/contextMemory/contextOps'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -import type { SwarmModeTrigger } from './agent/swarm'; - -const swarmModeEnterSchema = z.object({ - agentId: z.string(), - trigger: z.custom<SwarmModeTrigger>(), -}); - -export class SwarmModeEnter extends AgentEvent2<z.infer<typeof swarmModeEnterSchema>> { - static override readonly type = 'swarm_mode.enter'; - static override readonly durable = true; - static override readonly schema = swarmModeEnterSchema; -} -export interface SwarmModeEnter { - readonly agentId: string; - readonly trigger: SwarmModeTrigger; -} - -const swarmModeExitSchema = z.object({ agentId: z.string() }); - -export class SwarmModeExit extends AgentEvent2<z.infer<typeof swarmModeExitSchema>> { - static override readonly type = 'swarm_mode.exit'; - static override readonly durable = true; - static override readonly schema = swarmModeExitSchema; -} -export interface SwarmModeExit { - readonly agentId: string; -} - -export const swarmKey = defineState('swarm', (): SwarmModeTrigger | null => null).replayable({ - schema: z.custom<SwarmModeTrigger | null>(), -}) - .on(SwarmModeEnter, (_s, e, ctx) => { - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, swarmMode: true })); - return e.trigger; - }) - .on(SwarmModeExit, (_s, e, ctx) => { - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, swarmMode: false })); - return null; - }); - -contextMemoryKey.on(SwarmModeExit, (s) => popSwarmModeReminder(s)); diff --git a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm-fork.md b/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm-fork.md deleted file mode 100644 index 2db2c87b5..000000000 --- a/packages/agent-core-v2/src/features/swarm/tools/agent-swarm/agent-swarm-fork.md +++ /dev/null @@ -1 +0,0 @@ -Context forking: by default, each spawned subagent starts with zero context — brief it through the template. When every item builds on the current conversation, pass `fork: true` instead: each item-spawned subagent then starts with a snapshot of your completed history (inheriting your own agent type, tool set, and model), so the template only needs the task itself. A non-empty `resume_agent_ids` map is rejected with `fork`. If `subagent_type` is provided, it must match your own agent type; if `model` is provided, it must be your own model or `primary`. Different types and model overrides are rejected. Keep `fork` off for independent tasks — it copies the full history into every subagent. \ No newline at end of file diff --git a/packages/agent-core-v2/src/features/todo/todoAgentRuntime.ts b/packages/agent-core-v2/src/features/todo/todoAgentRuntime.ts deleted file mode 100644 index 7bd950967..000000000 --- a/packages/agent-core-v2/src/features/todo/todoAgentRuntime.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { assign, fromCallback, setup, type Snapshot } from 'xstate'; - -import { - defineAgentRuntimeContract, - defineAgentRuntimeProvider, - type AgentRuntimeContext, - type AgentRuntimeRestoreEvent, -} from '#/agent/runtime/agentRuntime'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; -import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; - -import { TODO_LIST_TOOL_NAME, readTodoItems, type TodoItem } from './todoItem'; -import { TODO_LIST_REMINDER_VARIANT, todoListStaleReminder } from './todoListReminder'; -import { ToolsUpdateStore, type TodoState } from './todoOps'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; - -import '#/agent/contextMemory/conversationTime'; - -interface TodoActorContext { - readonly todos: TodoState; - readonly runtime: AgentRuntimeContext<TodoState>; - readonly used: boolean; -} - -interface TodoCommitEvent { - readonly type: 'todo.commit'; - readonly todos: TodoState; -} - -interface TodoUsedEvent { - readonly type: 'todo.used'; -} - -type TodoActorSnapshot = Snapshot<unknown> & { readonly context: TodoActorContext }; - -const todoReminder = fromCallback(({ - input, -}: { - input: { - readonly runtime: AgentRuntimeContext<TodoState>; - }; -}) => { - if (input.runtime.agent.agentId !== MAIN_AGENT_ID) return; - const injector = input.runtime - .get(IAgentLifecycleService) - .resolve(input.runtime.agent, AgentReminder); - const memory = input.runtime.get(IAgentContextMemoryService); - const toolPolicy = input.runtime.get(IAgentToolPolicyService); - const registration = injector.register(TODO_LIST_REMINDER_VARIANT, () => - todoListStaleReminder({ - active: toolPolicy.isToolActive(TODO_LIST_TOOL_NAME, 'builtin'), - history: memory.get(), - todos: input.runtime.getState(), - }), - ); - return () => { registration.dispose(); }; -}); - -const todoActorLogic = setup({ - types: {} as { - context: TodoActorContext; - input: AgentRuntimeContext<TodoState>; - events: TodoCommitEvent | TodoUsedEvent | AgentRuntimeRestoreEvent; - }, - actors: { todoReminder }, -}).createMachine({ - context: ({ input }) => ({ todos: [], runtime: input, used: false }), - initial: 'beforeRestore', - states: { - beforeRestore: { - on: { - 'runtime.restore': [ - { target: 'reminding', guard: ({ context }) => context.used }, - { target: 'active' }, - ], - 'todo.used': { actions: assign({ used: true }) }, - }, - }, - active: { - on: { - 'todo.used': { target: 'reminding', actions: assign({ used: true }) }, - }, - }, - reminding: { - invoke: { - src: 'todoReminder', - input: ({ context }) => ({ runtime: context.runtime }), - }, - }, - }, - on: { - 'todo.commit': { - actions: assign({ todos: ({ event }) => event.todos }), - }, - }, -}); - -export class TodoRuntime { - readonly onDidChange: AgentRuntimeContext<TodoState>['onDidChange']; - - constructor(private readonly context: AgentRuntimeContext<TodoState>) { - this.onDidChange = context.onDidChange; - } - - get(): readonly TodoItem[] { - this.context.send({ type: 'todo.used' }); - return this.context.getState(); - } - - replace(todos: readonly TodoItem[]): Promise<void> { - this.context.send({ type: 'todo.used' }); - return this.context.dispatch(new ToolsUpdateStore({ - agentId: this.context.agent.agentId, - key: 'todo', - value: todos.map((todo) => ({ title: todo.title, status: todo.status })), - })); - } - - clear(): Promise<void> { - this.context.send({ type: 'todo.used' }); - return this.context.dispatch(new ToolsUpdateStore({ - agentId: this.context.agent.agentId, - key: 'todo', - value: [], - })); - } -} - -export const AgentTodo = defineAgentRuntimeContract<TodoRuntime>('todo'); - -export const todoAgentRuntimeProvider = defineAgentRuntimeProvider<TodoState, TodoRuntime>(AgentTodo, { - id: 'todo', - logic: todoActorLogic, - durable: { - events: [ToolsUpdateStore], - undoable: true, - transition: (_state, event) => { - if (!(event instanceof ToolsUpdateStore) || event.key !== 'todo') return; - return readTodoItems(event.value); - }, - read: (snapshot) => (snapshot as TodoActorSnapshot).context.todos, - commit: (actor, todos) => { actor.send({ type: 'todo.commit', todos }); }, - }, - createApi: (context) => new TodoRuntime(context), - inspect: (snapshot) => (snapshot as TodoActorSnapshot).context.todos.map((todo) => ({ - title: todo.title, - status: todo.status, - })), -}); diff --git a/packages/agent-core-v2/src/features/todo/todoFeature.ts b/packages/agent-core-v2/src/features/todo/todoFeature.ts deleted file mode 100644 index d558a31dc..000000000 --- a/packages/agent-core-v2/src/features/todo/todoFeature.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { ITodoListTool } from '#/features/todo/tools/todo-list/todo-list'; -import { TodoListTool } from '#/features/todo/tools/todo-list/todoListTool'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; -import { todoAgentRuntimeProvider } from '#/features/todo/todoAgentRuntime'; - -export class TodoFeature extends Feature { - static override readonly name = 'todo'; - - constructor() { - super(); - this.contributeAgentRuntime(todoAgentRuntimeProvider); - this.contributeTool(ITodoListTool, TodoListTool, { name: 'TodoList', domain: 'todo' }); - } -} - -registerFeature(TodoFeature); diff --git a/packages/agent-core-v2/src/features/todo/todoOps.ts b/packages/agent-core-v2/src/features/todo/todoOps.ts deleted file mode 100644 index db8f746e0..000000000 --- a/packages/agent-core-v2/src/features/todo/todoOps.ts +++ /dev/null @@ -1,25 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentEvent2 } from '#/app/event/event2'; - -import type { TodoItem } from './todoItem'; - -export type TodoState = readonly TodoItem[]; - -const toolsUpdateStoreSchema = z.object({ - agentId: z.string(), - key: z.string(), - value: z.unknown(), -}); - -export class ToolsUpdateStore extends AgentEvent2<z.infer<typeof toolsUpdateStoreSchema>> { - static override readonly type = 'tools.update_store'; - static override readonly durable = true; - static override readonly schema = toolsUpdateStoreSchema; -} -export interface ToolsUpdateStore { - readonly agentId: string; - readonly key: string; - readonly value: unknown; -} diff --git a/packages/agent-core-v2/src/features/tokenCounting/tokenCountingFeature.ts b/packages/agent-core-v2/src/features/tokenCounting/tokenCountingFeature.ts deleted file mode 100644 index bd88d6eff..000000000 --- a/packages/agent-core-v2/src/features/tokenCounting/tokenCountingFeature.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; -import { SessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCountingService'; -import { TokenCountingAgentModelDefinition } from '#/session/tokenCounting/tokenCountingAgentModel'; - -export class TokenCountingFeature extends Feature { - static override readonly name = 'tokenCounting'; - - constructor() { - super(); - this.contributeAgentModel(TokenCountingAgentModelDefinition); - this.contributeService( - LifecycleScope.Session, - ISessionTokenCountingService, - SessionTokenCountingService, - ); - } -} - -registerFeature(TokenCountingFeature); diff --git a/packages/agent-core-v2/src/features/tower/flag.ts b/packages/agent-core-v2/src/features/tower/flag.ts deleted file mode 100644 index d82ee2674..000000000 --- a/packages/agent-core-v2/src/features/tower/flag.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; - -import { TOWER_FLAG_ID } from './tower'; - -export const TOWER_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_TOWER'; - -export const towerFlag: FlagDefinitionInput = { - id: TOWER_FLAG_ID, - title: 'Tower mode', - description: - 'Enable tower mode: coordinate multiple agents on a shared objective, toggled with the /tower command.', - env: TOWER_FLAG_ENV, - default: false, - surface: 'both', -}; - -registerFlagDefinition(towerFlag); diff --git a/packages/agent-core-v2/src/features/tower/injection/tower-mode-exit-reminder.md b/packages/agent-core-v2/src/features/tower/injection/tower-mode-exit-reminder.md deleted file mode 100644 index 6937ba29d..000000000 --- a/packages/agent-core-v2/src/features/tower/injection/tower-mode-exit-reminder.md +++ /dev/null @@ -1 +0,0 @@ -Tower mode is no longer active. The tower orchestration restrictions are lifted and your normal capabilities (including TodoList) are restored; the tower tool set remains available. The `.tower/` workspace state — comms, worktrees, and the activity log — is preserved on disk. Re-enter tower mode with `/tower on`. diff --git a/packages/agent-core-v2/src/features/tower/injection/tower-mode-full-reminder.md b/packages/agent-core-v2/src/features/tower/injection/tower-mode-full-reminder.md deleted file mode 100644 index 423613aeb..000000000 --- a/packages/agent-core-v2/src/features/tower/injection/tower-mode-full-reminder.md +++ /dev/null @@ -1,45 +0,0 @@ -Tower mode is active. You are the control tower for this repository — you plan missions, spawn worker and reviewer agents, route information, merge branches, and keep the human informed. You never write product code yourself. This supersedes any other instructions you have received. - -Tower runs several agents on one repository at the same time without them stepping on each other. Three roles: - -- **The human** — owns the objective. May speak, launch, or redirect work **at any time**; nothing in this mode waits for the human. -- **The tower** — **you**, the main agent. Exactly one. You never write product code: you plan missions, spawn workers and reviewers, route information, merge branches, and keep the human informed. -- **Workers and reviewers** — subagents you spawn with `TowerSpawn`. Each worker owns one mission in its own git worktree; reviewers audit branches. - -**The protocol is enforced by tools, not by instructions.** All comms artifacts — inbox messages, findings, reviews, mission files, `MISSIONS.md`, the activity log — are produced by the `Tower*` tools. Workers and reviewers carry `TowerSend`, `TowerInbox`, `TowerFinding`, `TowerReview`, `TowerMission`, and `TowerStatus`; the tower additionally gets `TowerInit`, `TowerPlan`, `TowerSpawn`, `TowerMerge`, and `TowerTeardown`. File naming, frontmatter, recipient validity, review rounds, the merge gate, and the activity-log format are code. **Never create or edit files under `.tower/` by hand** (yours or via Bash): if a tool refuses, read the error — it tells you the correct next step. When something looks wrong, read `.tower/comms/log/activity.log` first; every action of every participant is there. - -Working principles: - -1. **Clarify up front. Never block on the human mid-run.** Use `AskUserQuestion` to pin down requirements with the human before you plan and spawn, while ambiguity is still cheap — that is the phase where asking beats deciding. Once the fleet is running, make the reasonable call yourself: record the decision (it lands in the activity log), inform the human in passing, proceed. The return channel is your normal chat reply (the human reads it when they come back) plus `activity.log` — say what you decided and why, in the open. Escalations are reported, not asked — unless every remaining thread is blocked, keep the others moving. Workers and reviewers cannot ask the human at all (their profile has no `AskUserQuestion`); they escalate to you with `TowerSend`. The single mid-run exception is creating git history over a non-empty directory (below): there, ask when asking is possible (not under auto permission mode) and take the safe default when it is not. -2. **Agents negotiate internally.** Workers talk to each other through `TowerSend` directly — questions, review requests, broadcasts (`to: "all"`). You are the coordinator and the only merger, not a content relay: you relay wake-ups (resume an idle agent with a pointer to what it should read), triage findings, untangle conflicts, and merge. -3. **Scope isolation is real.** `TowerPlan` rejects overlapping scopes, and `TowerMerge` refuses branches that changed files outside their mission scope. Plan scopes carefully; if a mission legitimately needs more, you widen it with `TowerMission` (scope patch — only you can, and it is logged). - -## Prepare (only when the directory is not a tower-ready git repo) - -`TowerInit` requires a git repository with at least one commit. If `git rev-parse --is-inside-work-tree` fails: - -- **Empty directory** → `git init` + `git commit --allow-empty -m "tower: init"`, then proceed. No confirmation needed. -- **Non-empty directory** → never `git add -A`: a blind initial commit can seal secrets, large binaries, or dependency directories into history irreversibly. Survey the directory (file count, largest files, secret-looking names like `.env` or `*.pem`), present the summary, and ask the human **exactly once** whether to initialize and commit the existing files — but only when asking is possible. Under auto permission mode `AskUserQuestion` is disabled: do not call it into a deny error. Default to the safe behavior instead — do NOT commit existing files; stop tower there and tell the human in your reply the two commands to run themselves (`git init` plus an initial commit of their choosing). If they agree to the commit, write a conservative `.gitignore` (dependencies, build output, secrets), show the staged list, commit, proceed. - -## Tower workflow - -1. **Init** — `TowerInit`. It creates `.tower/`, enables the tower tool set, and records the base branch. Workers and reviewers never prompt for tool approvals — they are pinned to the auto permission mode at spawn, whatever the session's mode. Your own orchestration calls still follow the session mode, so if it would interrupt you with constant prompts, tell the human once that a more autonomous mode fits tower better — then proceed regardless. When `TowerInit` reports carried-over open missions from a previous session, settle them **before planning**: continue the ones that belong to the current objective with fresh workers, and abandon the unrelated ones (`TowerMission status=abandoned`) — missions that are neither merged nor abandoned keep their scopes reserved, so `TowerPlan` rejects any new mission overlapping them. -2. **Plan** — break the objective into 2–4 missions and call `TowerPlan` with each mission's title, **disjoint** scope globs (picomatch: `**` crosses directories), tasks, and dependencies. Mark read-only investigation missions `kind: "survey"`: a survey's scope is informational (it reserves nothing, so surveys and builds may overlap the same paths), the worker must not change code, and it closes with a zero-diff `TowerMerge` — no reviewer needed. Shared files (lockfiles, central configs) belong to exactly one build mission or to your own integration work. Post the plan to the human in one compact message and launch immediately — their words are plan changes, never a gate. -3. **Spawn** — one `TowerSpawn` per mission (`kind: "worker"`, background, code-built briefing), and **spawn every dependency-unblocked mission right away**: fire the `TowerSpawn` calls back to back, never trickle them out one at a time and never wait for one worker before launching the next — the fleet exists to run in parallel. The tool refuses duplicate names — resume the existing agent with the `Agent` tool instead. Workers commit on their branch; their completion wakes you. Once the batch is running, **end your turn**: completions and inbox traffic arrive as notifications, so never poll `TowerInbox`/`TowerStatus` in a loop and never sit synchronously waiting on a worker. Workers bind the configured secondary model when the secondary-model experiment is on (they inherit your model otherwise); reviewers always bind your primary model — review quality is not where you save. The resolved model is shown in the spawn output and the `spawn` line of `activity.log`. -4. **Supervise** — on every wake (worker completion, human message): `TowerInbox` and `TowerStatus`, then act: - - Review request → `TowerSpawn` a reviewer (`kind: "reviewer"`, `review_target` the branch). Do not review mission code yourself. Survey missions skip review — close them with `TowerMerge` once their summary lands. - - Review verdict not clean → resume the author (Agent tool) pointing at the review file; the author fixes, pushes, and requests re-review. Round cap: at 5 rounds, or when two consecutive rounds report the same findings, stop the loop, inform the human, and redirect (reassign, split, descope). - - Blocker → answer or reassign if you can; if it genuinely needs the human, inform them and keep the rest moving. - - Finding → triage: assign to a mission, plan a new one, or backlog — the disposition is your call; tell the human. - - Completion report with a suspicious diff (🟢 claimed, zero changed files) → investigate before accepting. -5. **Merge** — `TowerMerge(branch)` in Dependency Flow order. The gate refuses when there is no clean review for the current tip, dependencies are unmerged, or files escaped the scope — the error message is your next step. After a merge, the result lists branches that now conflict: tell those workers (resume) to rebase onto the new base, resolve, push, and request re-review; their moved tip makes the gate demand a fresh clean review. -6. **Teardown promptly** — when `TowerStatus` shows every mission ✅ merged and no unactioned inbox items remain, call `TowerTeardown` **right away** and report the final summary (missions, merges, review rounds, findings and their disposition). Do not wait for the human to ask: branches and `.tower/comms/` (including the activity log) are kept and dirty worktrees are protected by the tool — only disk is freed. A `/tower teardown` from the human is the same instruction at any earlier point. - -## Hard rules for the tower - -- Exactly one tower. If a worker starts assigning work or merging, correct it on your next resume. -- Never write product code yourself; integration fixes at merge time are yours, everything else goes to a worker. -- Mission tracking lives in the tower protocol (`TowerPlan`/`TowerMission`/`TowerStatus`, `MISSIONS.md`), never in `TodoList` — it is code-denied in tower mode because todo semantics (one task in progress at a time) would serialize the fleet. -- Workers negotiate through `TowerSend`; you relay wake-ups and step in for conflicts, caps, findings, and merges. -- Never hand-edit `.tower/` files. The tools are the protocol. -- You perform every merge, through `TowerMerge` — never `git merge` by hand, never merge around a refusal. diff --git a/packages/agent-core-v2/src/features/tower/injection/tower-mode-sparse-reminder.md b/packages/agent-core-v2/src/features/tower/injection/tower-mode-sparse-reminder.md deleted file mode 100644 index 54f909313..000000000 --- a/packages/agent-core-v2/src/features/tower/injection/tower-mode-sparse-reminder.md +++ /dev/null @@ -1 +0,0 @@ -Tower mode still active (see full instructions earlier). You are the control tower: run the protocol only through the `Tower*` tools — never create or edit files under `.tower/` by hand. Mission tracking lives in `TowerPlan`/`TowerMission`/`TowerStatus` (`MISSIONS.md`); TodoList is code-denied in tower mode. When something looks wrong, read `.tower/comms/log/activity.log` first. Never write product code yourself — workers own missions; you coordinate, review-route, and merge. diff --git a/packages/agent-core-v2/src/features/tower/injection/towerModeInjection.ts b/packages/agent-core-v2/src/features/tower/injection/towerModeInjection.ts deleted file mode 100644 index c89bf855d..000000000 --- a/packages/agent-core-v2/src/features/tower/injection/towerModeInjection.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Service } from '#/_base/di/service'; -import type { ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import { IFlagService } from '#/app/flag/flag'; -import { IAgentTowerService, TOWER_FLAG_ID } from '#/features/tower/tower'; -import TOWER_MODE_EXIT_REMINDER from './tower-mode-exit-reminder.md?raw'; -import TOWER_MODE_FULL_REMINDER from './tower-mode-full-reminder.md?raw'; -import TOWER_MODE_SPARSE_REMINDER from './tower-mode-sparse-reminder.md?raw'; - -const TOWER_MODE_DEDUP_MIN_TURNS = 2; -const TOWER_MODE_FULL_REFRESH_TURNS = 5; -const TOWER_MODE_INJECTION_VARIANT = 'tower_mode'; -const TOWER_MODE_EXIT_DISCLOSURE = 'exit'; - -export class TowerModeInjection extends Service { - constructor( - injector: ReminderRuntime, - @IAgentTowerService private readonly tower: IAgentTowerService, - @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @IFlagService private readonly flags: IFlagService, - ) { - super(); - this._register( - injector.register<typeof TOWER_MODE_EXIT_DISCLOSURE>( - TOWER_MODE_INJECTION_VARIANT, - ({ injectedPositions, lastInjectedAt: injectedAt, lastDisclosure }) => { - if (!this.tower.isActive) { - if (injectedPositions.length === 0 || lastDisclosure === TOWER_MODE_EXIT_DISCLOSURE) { - return undefined; - } - return { content: TOWER_MODE_EXIT_REMINDER, disclosure: TOWER_MODE_EXIT_DISCLOSURE }; - } - if (!this.flags.enabled(TOWER_FLAG_ID)) return undefined; - if (injectedPositions.length === 0 || lastDisclosure === TOWER_MODE_EXIT_DISCLOSURE) { - return TOWER_MODE_FULL_REMINDER; - } - const variant = towerModeReminderVariant(injectedAt, this.context.get()); - if (variant === 'full') return TOWER_MODE_FULL_REMINDER; - if (variant === 'sparse') return TOWER_MODE_SPARSE_REMINDER; - return undefined; - }, - ), - ); - } -} - -type TowerModeReminderVariant = 'full' | 'sparse'; - -function towerModeReminderVariant( - injectedAt: number | null, - history: readonly ContextMessage[], -): TowerModeReminderVariant | null { - if (injectedAt === null) return 'full'; - let assistantTurnsSince = 0; - for (let i = injectedAt + 1; i < history.length; i++) { - const message = history[i]; - if (message === undefined) continue; - if (message.role === 'assistant') { - assistantTurnsSince += 1; - continue; - } - if (message.role === 'user' && assistantTurnsSince >= 1) return 'full'; - } - if (assistantTurnsSince >= TOWER_MODE_FULL_REFRESH_TURNS) return 'full'; - if (assistantTurnsSince >= TOWER_MODE_DEDUP_MIN_TURNS) return 'sparse'; - return null; -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/frontmatter.ts b/packages/agent-core-v2/src/features/tower/protocol/frontmatter.ts deleted file mode 100644 index 1940ae395..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/frontmatter.ts +++ /dev/null @@ -1,32 +0,0 @@ -const FENCE = '---'; - -export function renderFrontmatter(fields: Readonly<Record<string, string>>): string { - const lines = [FENCE]; - for (const [key, value] of Object.entries(fields)) { - if (/[\r\n]/.test(value)) { - throw new Error(`frontmatter value for "${key}" must be single-line`); - } - lines.push(`${key}: ${value}`); - } - lines.push(FENCE); - return lines.join('\n'); -} - -export function parseFrontmatter(text: string): { - readonly fields: Record<string, string>; - readonly body: string; -} { - const lines = text.split(/\r?\n/); - if (lines[0]?.trim() !== FENCE) return { fields: {}, body: text }; - const close = lines.findIndex((line, index) => index > 0 && line.trim() === FENCE); - if (close === -1) return { fields: {}, body: text }; - - const fields: Record<string, string> = {}; - for (const line of lines.slice(1, close)) { - const separator = line.indexOf(':'); - if (separator <= 0) continue; - const key = line.slice(0, separator).trim(); - fields[key] = line.slice(separator + 1).trim(); - } - return { fields, body: lines.slice(close + 1).join('\n').trim() }; -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/git.ts b/packages/agent-core-v2/src/features/tower/protocol/git.ts deleted file mode 100644 index b446de79a..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/git.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { execFile } from 'node:child_process'; - -const GIT_TIMEOUT_MS = 60_000; - -export class GitError extends Error { - constructor( - readonly args: readonly string[], - readonly stderr: string, - ) { - super(`git ${args.join(' ')} failed: ${stderr.trim() || 'unknown error'}`); - this.name = 'GitError'; - } -} - -export async function git(cwd: string, args: readonly string[]): Promise<string> { - return new Promise((resolve, reject) => { - execFile( - 'git', - [...args], - { cwd, timeout: GIT_TIMEOUT_MS, maxBuffer: 16 * 1024 * 1024 }, - (error, stdout, stderr) => { - if (error !== null) { - reject(new GitError(args, stderr || error.message)); - return; - } - resolve(stdout.trimEnd()); - }, - ); - }); -} - -export async function tryGit(cwd: string, args: readonly string[]): Promise<string | null> { - try { - return await git(cwd, args); - } catch { - return null; - } -} - -export async function isInsideRepo(cwd: string): Promise<boolean> { - return (await tryGit(cwd, ['rev-parse', '--is-inside-work-tree'])) === 'true'; -} - -export async function hasAnyCommit(cwd: string): Promise<boolean> { - return (await tryGit(cwd, ['rev-list', '-n', '1', '--all'])) !== null; -} - -export async function currentBranch(cwd: string): Promise<string> { - const branch = await git(cwd, ['rev-parse', '--abbrev-ref', 'HEAD']); - if (branch === 'HEAD') throw new Error('cannot determine base branch from a detached HEAD'); - return branch; -} - -export async function branchTip(cwd: string, ref: string): Promise<string> { - return git(cwd, ['rev-parse', ref]); -} - -export async function branchExists(cwd: string, branch: string): Promise<boolean> { - return ( - (await tryGit(cwd, ['show-ref', '--verify', '--quiet', `refs/heads/${branch}`])) !== null - ); -} - -export async function worktreeAdd( - cwd: string, - path: string, - branch: string, - base: string, -): Promise<void> { - if (await branchExists(cwd, branch)) { - await git(cwd, ['worktree', 'add', path, branch]); - return; - } - await git(cwd, ['worktree', 'add', path, '-b', branch, base]); -} - -export async function worktreeRemove(cwd: string, path: string): Promise<void> { - await git(cwd, ['worktree', 'remove', '--force', path]); -} - -export async function isWorktreeDirty(path: string): Promise<boolean> { - const status = await tryGit(path, ['status', '--porcelain']); - return status !== null && status.trim().length > 0; -} - -export async function mergeNoFf(cwd: string, branch: string): Promise<string> { - await git(cwd, ['merge', '--no-ff', branch]); - return branchTip(cwd, 'HEAD'); -} - -export async function diffNameOnly( - cwd: string, - base: string, - ref: string, -): Promise<readonly string[]> { - const out = await git(cwd, ['diff', '--name-only', `${base}...${ref}`]); - return out.length === 0 ? [] : out.split('\n').filter((line) => line.trim().length > 0); -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/index.ts b/packages/agent-core-v2/src/features/tower/protocol/index.ts deleted file mode 100644 index a58bf65f3..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export * from './frontmatter'; -export * from './git'; -export * from './paths'; -export * from './repoRoot'; -export * from './store'; -export * from './types'; diff --git a/packages/agent-core-v2/src/features/tower/protocol/paths.ts b/packages/agent-core-v2/src/features/tower/protocol/paths.ts deleted file mode 100644 index 9c3aa6b85..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/paths.ts +++ /dev/null @@ -1,72 +0,0 @@ -export const TOWER_ROOT = '.tower'; -export const COMMS_DIR = `${TOWER_ROOT}/comms`; -export const INBOX_DIR = `${COMMS_DIR}/inbox`; -export const FINDINGS_DIR = `${COMMS_DIR}/findings`; -export const REVIEWS_DIR = `${COMMS_DIR}/reviews`; -export const MISSIONS_DIR = `${COMMS_DIR}/missions`; -export const LOG_DIR = `${COMMS_DIR}/log`; -export const WORKTREES_DIR = `${TOWER_ROOT}/worktrees`; - -export const STATE_FILE = `${COMMS_DIR}/state.json`; -export const ACTIVITY_LOG = `${LOG_DIR}/activity.log`; -export const MISSIONS_INDEX = `${COMMS_DIR}/MISSIONS.md`; - -export const TOWER_NAME = 'tower'; -export const BROADCAST_NAME = 'all'; - -export function dateStamp(now = new Date()): string { - const y = now.getFullYear(); - const m = String(now.getMonth() + 1).padStart(2, '0'); - const d = String(now.getDate()).padStart(2, '0'); - return `${y}${m}${d}`; -} - -export function dateDash(now = new Date()): string { - const stamp = dateStamp(now); - return `${stamp.slice(0, 4)}-${stamp.slice(4, 6)}-${stamp.slice(6, 8)}`; -} - -export function slugify(text: string, maxLength = 60): string { - const slug = text - .toLowerCase() - .replaceAll(/[^a-z0-9]+/g, '-') - .replaceAll(/^-+|-+$/g, '') - .slice(0, maxLength) - .replaceAll(/-+$/g, ''); - return slug.length > 0 ? slug : 'item'; -} - -export function targetSlug(target: string): string { - const cleaned = target.trim().replace(/^#/, 'pr'); - return slugify(cleaned.replaceAll(/[/#]+/g, '-')); -} - -export function inboxFileName(input: { - readonly from: string; - readonly to: string; - readonly subject: string; - readonly now?: Date; -}): string { - return `${dateStamp(input.now)}-${slugify(input.from, 30)}-${slugify(input.to, 30)}-${slugify(input.subject)}.md`; -} - -export function findingFileName(input: { - readonly agent: string; - readonly type: string; - readonly slug: string; - readonly now?: Date; -}): string { - return `${dateStamp(input.now)}-${slugify(input.agent, 30)}-${slugify(input.type, 12)}-${slugify(input.slug)}.md`; -} - -export function reviewFileName(input: { - readonly target: string; - readonly reviewer: string; - readonly round: number; -}): string { - return `review-${targetSlug(input.target)}-${slugify(input.reviewer, 30)}-r${input.round}.md`; -} - -export function missionFileName(id: string, slug: string): string { - return `${id}-${slugify(slug)}.md`; -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/repoRoot.ts b/packages/agent-core-v2/src/features/tower/protocol/repoRoot.ts deleted file mode 100644 index 7539fd4bb..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/repoRoot.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { WORKTREES_DIR } from './paths'; - -export function resolveTowerRepoRoot(cwd: string): string { - const normalized = cwd.replaceAll('\\', '/'); - const marker = `/${WORKTREES_DIR}/`; - const index = normalized.indexOf(marker); - if (index === -1) return cwd; - return cwd.slice(0, index); -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/store.ts b/packages/agent-core-v2/src/features/tower/protocol/store.ts deleted file mode 100644 index fa996ccf5..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/store.ts +++ /dev/null @@ -1,984 +0,0 @@ -import { randomUUID } from 'node:crypto'; -import { appendFile, mkdir, open, readFile, readdir, rename, writeFile } from 'node:fs/promises'; -import { dirname, join } from 'node:path'; - -import picomatch from 'picomatch'; - -import { parseFrontmatter, renderFrontmatter } from './frontmatter'; -import { - branchExists, - branchTip, - currentBranch, - diffNameOnly, - hasAnyCommit, - isInsideRepo, - isWorktreeDirty, - mergeNoFf, - tryGit, - worktreeAdd, - worktreeRemove, -} from './git'; -import { - ACTIVITY_LOG, - BROADCAST_NAME, - FINDINGS_DIR, - INBOX_DIR, - LOG_DIR, - MISSIONS_DIR, - MISSIONS_INDEX, - REVIEWS_DIR, - STATE_FILE, - TOWER_NAME, - WORKTREES_DIR, - dateDash, - findingFileName, - inboxFileName, - missionFileName, - reviewFileName, - slugify, - targetSlug, -} from './paths'; -import type { - TowerFindingSeverity, - TowerFindingType, - TowerInboxItem, - TowerMission, - TowerMissionKind, - TowerMissionStatus, - TowerReviewInfo, - TowerRosterEntry, - TowerState, -} from './types'; - -export class TowerProtocolError extends Error { - constructor(message: string) { - super(message); - this.name = 'TowerProtocolError'; - } -} - -export interface TowerInitResult { - readonly base: string; - readonly created: boolean; - readonly retiredAgents: readonly string[]; - readonly checkout: string; - readonly ignoredBase?: string; - readonly openMissions: readonly string[]; -} - -export interface TowerPlanInput { - readonly title: string; - readonly scope: readonly string[]; - readonly tasks?: readonly string[]; - readonly deps?: readonly string[]; - readonly kind?: TowerMissionKind; -} - -export interface TowerSendInput { - readonly to: string; - readonly subject: string; - readonly body: string; - readonly scope?: string; - readonly action?: string; - readonly consentRef?: string; -} - -export interface TowerFindingInput { - readonly type: TowerFindingType; - readonly title: string; - readonly severity?: TowerFindingSeverity; - readonly summary: string; - readonly location?: string; - readonly details: string; - readonly suggestedFix: string; -} - -export interface TowerReviewInput { - readonly target: string; - readonly status: string; - readonly merge: string; - readonly findings: string; - readonly checks?: readonly string[]; - readonly decision: string; -} - -export interface TowerMissionPatch { - readonly status?: TowerMissionStatus; - readonly note?: string; - readonly blocker?: string; - readonly clearBlockers?: boolean; - readonly taskDone?: string; - readonly owner?: string; - readonly scope?: readonly string[]; -} - -const FINDING_TYPES: readonly TowerFindingType[] = ['bug', 'improve', 'vuln', 'idea']; -const STATUS_EMOJI: Record<TowerMissionStatus, string> = { - planned: '🟡', - active: '🔵', - completed: '🟢', - blocked: '🔴', - paused: '⏸️', - merged: '✅', - abandoned: '🚫', -}; - -function isOpenMission(mission: Pick<TowerMission, 'status'>): boolean { - return mission.status !== 'merged' && mission.status !== 'abandoned'; -} - -export class TowerStore { - constructor(readonly repoRoot: string) {} - - async isInitialized(): Promise<boolean> { - try { - await readFile(this.abs(STATE_FILE), 'utf8'); - return true; - } catch { - return false; - } - } - - async init(sessionId?: string, base?: string): Promise<TowerInitResult> { - if (!(await isInsideRepo(this.repoRoot))) { - throw new TowerProtocolError( - 'tower needs a git repository (the session working directory is not inside one)', - ); - } - if (!(await hasAnyCommit(this.repoRoot))) { - throw new TowerProtocolError( - 'the repository has no commits yet — create an initial commit first', - ); - } - if (await this.isInitialized()) { - const state = await this.load(); - const retiredAgents = await this.adoptForeignRoster(state, sessionId); - return { - base: state.base, - created: false, - retiredAgents, - checkout: await this.checkedOutBranch(), - ignoredBase: base !== undefined && base !== state.base ? base : undefined, - openMissions: state.missions.filter(isOpenMission).map((m) => m.id), - }; - } - - const checkout = await this.checkedOutBranch(); - let resolvedBase: string; - if (base !== undefined) { - if (!(await branchExists(this.repoRoot, base))) { - throw new TowerProtocolError( - `base branch "${base}" does not exist as a local branch — merges land on a local branch, so remote-tracking refs and tags are not accepted; create a local branch first`, - ); - } - resolvedBase = base; - } else { - if (checkout === 'HEAD') { - throw new TowerProtocolError( - 'cannot determine the base branch from a detached HEAD — pass the base branch explicitly', - ); - } - resolvedBase = checkout; - } - - for (const dir of [INBOX_DIR, FINDINGS_DIR, REVIEWS_DIR, MISSIONS_DIR, LOG_DIR, WORKTREES_DIR]) { - await mkdir(this.abs(dir), { recursive: true }); - } - await this.ensureGitExclude(); - - const state: TowerState = { - version: 1, - base: resolvedBase, - mode: 'branch', - createdAt: new Date().toISOString(), - sessionId, - roster: { agents: [] }, - missions: [], - }; - await this.save(state); - await writeFile(this.abs(ACTIVITY_LOG), '', 'utf8'); - await this.renderMissionsIndex(state); - await this.appendLog(TOWER_NAME, 'init', { mode: state.mode, base: resolvedBase }, MISSIONS_INDEX); - return { base: resolvedBase, created: true, retiredAgents: [], checkout, openMissions: [] }; - } - - private async checkedOutBranch(): Promise<string> { - return (await tryGit(this.repoRoot, ['rev-parse', '--abbrev-ref', 'HEAD'])) ?? 'HEAD'; - } - - private async adoptForeignRoster( - state: TowerState, - sessionId: string | undefined, - ): Promise<readonly string[]> { - if (sessionId === undefined || state.sessionId === sessionId) return []; - const previous = state.sessionId; - const stale = state.roster.agents.filter((agent) => agent.sessionId !== sessionId); - state.roster.agents.splice( - 0, - state.roster.agents.length, - ...state.roster.agents.filter((agent) => agent.sessionId === sessionId), - ); - state.sessionId = sessionId; - await this.save(state); - await this.appendLog(TOWER_NAME, 'adopt', { - session: sessionId, - previous: previous ?? 'unknown', - retired: stale.length > 0 ? stale.map((agent) => agent.name).join(',') : undefined, - }); - return stale.map((agent) => agent.name); - } - - private async ensureGitExclude(): Promise<void> { - const gitDir = (await readGitDir(this.repoRoot)) ?? join(this.repoRoot, '.git'); - const excludePath = join(gitDir, 'info', 'exclude'); - await mkdir(dirname(excludePath), { recursive: true }); - let existing = ''; - try { - existing = await readFile(excludePath, 'utf8'); - } catch { - } - if (existing.split(/\r?\n/).some((line) => line.trim() === '.tower/')) return; - await appendFile(excludePath, `${existing.endsWith('\n') || existing.length === 0 ? '' : '\n'}.tower/\n`, 'utf8'); - } - - async load(): Promise<TowerState> { - let raw: string; - try { - raw = await readFile(this.abs(STATE_FILE), 'utf8'); - } catch { - throw new TowerProtocolError( - 'tower is not initialized in this repository — run TowerInit first', - ); - } - const state = JSON.parse(raw) as TowerState; - for (const mission of state.missions) { - mission.kind ??= 'build'; - } - return state; - } - - private async save(state: TowerState): Promise<void> { - const file = this.abs(STATE_FILE); - const tmp = `${file}.tmp`; - await writeFile(tmp, `${JSON.stringify(state, null, 2)}\n`, 'utf8'); - await rename(tmp, file); - } - - async appendLog( - actor: string, - action: string, - details: Readonly<Record<string, string | number | undefined>> = {}, - ref?: string, - ): Promise<void> { - const kv = Object.entries(details) - .filter((entry): entry is [string, string | number] => entry[1] !== undefined) - .map(([key, value]) => `${key}=${value}`) - .join(' '); - const parts = [new Date().toISOString(), actor, action]; - if (kv.length > 0) parts.push(kv); - if (ref !== undefined) parts.push(`ref=${ref}`); - await appendFile(this.abs(ACTIVITY_LOG), `${parts.join(' ')}\n`, 'utf8'); - } - - async recentLog(lines: number): Promise<readonly string[]> { - let content = ''; - try { - content = await readFile(this.abs(ACTIVITY_LOG), 'utf8'); - } catch { - return []; - } - const all = content.split('\n').filter((line) => line.trim().length > 0); - return all.slice(-lines); - } - - resolveCallerName(state: TowerState, agentId: string): string { - if (agentId === 'main') return TOWER_NAME; - const entry = state.roster.agents.find((agent) => agent.agentId === agentId); - if (entry === undefined) { - throw new TowerProtocolError( - `agent "${agentId}" is not a tower participant — only spawned workers/reviewers and the tower can use tower tools`, - ); - } - return entry.name; - } - - findAgent(state: TowerState, name: string): TowerRosterEntry | undefined { - return state.roster.agents.find((agent) => agent.name === name); - } - - findByName(state: TowerState, name: string): TowerRosterEntry | undefined { - return this.findAgent(state, name); - } - - async registerAgent(entry: TowerRosterEntry): Promise<void> { - const state = await this.load(); - if (this.findAgent(state, entry.name) !== undefined) { - throw new TowerProtocolError(`tower agent name "${entry.name}" is already registered`); - } - state.roster.agents.push(entry); - await this.save(state); - } - - async plan(input: readonly TowerPlanInput[]): Promise<readonly TowerMission[]> { - if (input.length === 0) { - throw new TowerProtocolError('TowerPlan needs at least one mission'); - } - const state = await this.load(); - const startIndex = state.missions.length; - - const missions: TowerMission[] = input.map((item, index) => { - const n = startIndex + index + 1; - const slug = slugify(item.title, 40); - return { - id: `M${n}`, - title: item.title, - slug, - kind: item.kind ?? 'build', - scope: [...item.scope], - branch: `feat/${slug}`, - worktree: `wt-${n}`, - deps: item.deps ?? [], - status: 'planned', - tasks: (item.tasks ?? []).map((text) => ({ text, done: false })), - notes: [], - blockers: [], - }; - }); - - const knownIds = new Set([...state.missions.map((m) => m.id), ...missions.map((m) => m.id)]); - for (const mission of missions) { - for (const dep of mission.deps) { - if (!knownIds.has(dep)) { - throw new TowerProtocolError(`mission ${mission.id} depends on unknown mission "${dep}"`); - } - } - } - this.assertScopesDisjoint([ - ...state.missions.filter(isOpenMission), - ...missions, - ]); - - state.missions.push(...missions); - await this.save(state); - await this.renderMissionsIndex(state); - for (const mission of missions) { - await this.renderMissionFile(mission); - } - await this.appendLog( - TOWER_NAME, - 'plan', - { missions: missions.map((m) => m.id).join(',') }, - MISSIONS_INDEX, - ); - return missions; - } - - private assertScopesDisjoint(missions: readonly TowerMission[]): void { - const scopes: Array<{ readonly id: string; readonly raw: string; readonly stem: string }> = []; - for (const mission of missions) { - if (mission.kind === 'survey') continue; - for (const raw of mission.scope) { - const stem = raw.replace(/\/\*\*?$/, '').replace(/\*$/, '').replace(/\/+$/, ''); - if (stem.length === 0) { - throw new TowerProtocolError( - `mission ${mission.id} scope "${raw}" covers the whole repo — narrow it down`, - ); - } - scopes.push({ id: mission.id, raw, stem }); - } - } - for (let i = 0; i < scopes.length; i++) { - for (let j = i + 1; j < scopes.length; j++) { - const a = scopes[i]!; - const b = scopes[j]!; - if (a.id === b.id) continue; - if (a.stem === b.stem || a.stem.startsWith(`${b.stem}/`) || b.stem.startsWith(`${a.stem}/`)) { - throw new TowerProtocolError( - `mission scopes overlap: ${a.id} ("${a.raw}") vs ${b.id} ("${b.raw}") — split the shared files into exactly one mission; if one of them is stale finished work, abandon it first (TowerMission status=abandoned)`, - ); - } - } - } - } - - async updateMission( - callerName: string, - id: string, - patch: TowerMissionPatch, - options: { readonly silent?: boolean } = {}, - ): Promise<TowerMission> { - const state = await this.load(); - const mission = state.missions.find((m) => m.id === id); - if (mission === undefined) { - throw new TowerProtocolError(`unknown mission "${id}"`); - } - if (callerName !== TOWER_NAME) { - const caller = this.findAgent(state, callerName); - if (caller?.kind !== 'worker' || caller.missionId !== id) { - throw new TowerProtocolError( - `agent "${callerName}" does not own mission ${id} — workers update only their own mission file`, - ); - } - } - - const isNoOp = - patch.status === mission.status && - patch.note === undefined && - patch.blocker === undefined && - patch.clearBlockers === undefined && - patch.taskDone === undefined && - patch.owner === undefined && - patch.scope === undefined; - if (isNoOp) return mission; - - if (patch.owner !== undefined) { - if (callerName !== TOWER_NAME) { - throw new TowerProtocolError( - `agent "${callerName}" cannot assign mission ownership — only the tower sets owner`, - ); - } - mission.owner = patch.owner; - } - if (patch.scope !== undefined) { - if (callerName !== TOWER_NAME) { - throw new TowerProtocolError( - `agent "${callerName}" cannot change mission scope — only the tower widens a scope, and every change is logged`, - ); - } - this.assertScopesDisjoint([ - ...state.missions.filter((m) => m.id !== id && isOpenMission(m)), - { ...mission, scope: [...patch.scope] }, - ]); - mission.scope = [...patch.scope]; - } - if (patch.status !== undefined) { - if (patch.status === 'abandoned' && callerName !== TOWER_NAME) { - throw new TowerProtocolError( - `agent "${callerName}" cannot abandon mission ${id} — abandoning releases the mission scope, so only the tower does it`, - ); - } - mission.status = patch.status; - } - if (patch.note !== undefined) mission.notes.push(patch.note); - if (patch.blocker !== undefined) { - mission.blockers.push(patch.blocker); - mission.status = 'blocked'; - } - if (patch.clearBlockers === true) mission.blockers = []; - if (patch.taskDone !== undefined) { - const task = mission.tasks.find((t) => !t.done && t.text.includes(patch.taskDone!)); - if (task === undefined) { - throw new TowerProtocolError( - `mission ${id} has no open task matching "${patch.taskDone}"`, - ); - } - task.done = true; - } - - await this.save(state); - await this.renderMissionsIndex(state); - await this.renderMissionFile(mission); - const taskTickOnly = - patch.taskDone !== undefined && - patch.status === undefined && - patch.note === undefined && - patch.blocker === undefined && - patch.clearBlockers === undefined && - patch.owner === undefined && - patch.scope === undefined; - if (!taskTickOnly && options.silent !== true) { - await this.appendLog(callerName, 'mission.update', { - id, - status: patch.status, - note: patch.note !== undefined ? 'added' : undefined, - blocker: patch.blocker !== undefined ? 'added' : undefined, - owner: patch.owner, - scope: patch.scope?.join(','), - }); - } - return mission; - } - - async send(callerName: string, input: TowerSendInput): Promise<string> { - const state = await this.load(); - const to = input.to.trim(); - if ( - to !== TOWER_NAME && - to !== BROADCAST_NAME && - this.findAgent(state, to) === undefined - ) { - const known = [TOWER_NAME, BROADCAST_NAME, ...state.roster.agents.map((a) => a.name)]; - throw new TowerProtocolError( - `unknown recipient "${to}" — address a roster agent, ${TOWER_NAME}, or ${BROADCAST_NAME} (known: ${known.join(', ')})`, - ); - } - if (to === callerName) { - throw new TowerProtocolError('cannot send an inbox message to yourself'); - } - - const frontmatter = renderFrontmatter({ - type: 'inbox', - message_id: randomUUID(), - from: callerName, - to, - subject: input.subject, - sent_at: new Date().toISOString(), - ...(input.scope !== undefined ? { scope: input.scope } : {}), - ...(input.action !== undefined ? { action: input.action } : {}), - ...(input.consentRef !== undefined ? { consent_ref: input.consentRef } : {}), - }); - const content = `${frontmatter}\n\n${input.body.trim()}\n`; - const baseName = inboxFileName({ from: callerName, to, subject: input.subject }); - const rel = await this.writeUnique(join(INBOX_DIR, baseName), content); - await this.appendLog(callerName, 'inbox.send', { to, subject: slugify(input.subject) }, rel); - return rel; - } - - async readInbox(callerName: string, limit: number): Promise<readonly TowerInboxItem[]> { - let files: string[]; - try { - files = await readdir(this.abs(INBOX_DIR)); - } catch { - return []; - } - const items: TowerInboxItem[] = []; - for (const file of files.filter((f) => f.endsWith('.md'))) { - const rel = join(INBOX_DIR, file); - let text: string; - try { - text = await readFile(this.abs(rel), 'utf8'); - } catch { - continue; - } - const { fields, body } = parseFrontmatter(text); - if (fields['type'] !== 'inbox') continue; - const to = fields['to'] ?? ''; - if (callerName !== TOWER_NAME && to !== callerName && to !== BROADCAST_NAME) continue; - items.push({ - file: rel, - from: fields['from'] ?? 'unknown', - to, - subject: fields['subject'] ?? '', - sentAt: fields['sent_at'] ?? '', - scope: fields['scope'], - action: fields['action'], - consentRef: fields['consent_ref'], - body, - }); - } - items.sort((a, b) => b.sentAt.localeCompare(a.sentAt)); - return items.slice(0, Math.max(1, limit)); - } - - async fileFinding(callerName: string, input: TowerFindingInput): Promise<string> { - if (!FINDING_TYPES.includes(input.type)) { - throw new TowerProtocolError( - `finding type must be one of ${FINDING_TYPES.join(' | ')}`, - ); - } - const state = await this.load(); - const caller = this.findAgent(state, callerName); - const mission = - caller?.missionId !== undefined - ? state.missions.find((m) => m.id === caller.missionId) - : undefined; - - const lines = [ - `# Finding: ${input.title}`, - '', - `**Date**: ${dateDash().replaceAll('-', '')}`, - `**Agent**: ${callerName}`, - `**Type**: ${input.type}`, - `**Severity**: ${input.severity ?? 'medium'}`, - `**Mission**: ${mission === undefined ? '(none)' : `${mission.id} — ${mission.title}`}`, - '', - '---', - '', - '## Summary', - input.summary.trim(), - '', - '## Location', - (input.location ?? '(not specified)').trim(), - '', - '## Details', - input.details.trim(), - '', - '## Suggested Fix / Action', - input.suggestedFix.trim(), - '', - '## Why Not Fixed Directly', - mission === undefined - ? 'This finding is outside the reporting agent’s assignment. Assigning to the control tower for routing.' - : `This finding is outside the scope of mission ${mission.id} (${mission.scope.join(', ')}). Fixing it directly would violate scope isolation. Assigning to the control tower for routing.`, - '', - '---', - '', - `*Filed by tower agent ${callerName} via \`${FINDINGS_DIR}/\`*`, - '', - ]; - const baseName = findingFileName({ - agent: callerName, - type: input.type, - slug: input.title, - }); - const rel = await this.writeUnique(join(FINDINGS_DIR, baseName), lines.join('\n')); - await this.appendLog(callerName, 'finding.file', { type: input.type, slug: slugify(input.title) }, rel); - return rel; - } - - async submitReview(callerName: string, input: TowerReviewInput): Promise<string> { - const state = await this.load(); - if (callerName !== TOWER_NAME) { - const caller = this.findAgent(state, callerName); - if (caller?.kind !== 'reviewer' || caller.reviewTarget !== input.target) { - throw new TowerProtocolError( - `agent "${callerName}" is not an assigned reviewer for "${input.target}"`, - ); - } - } - if (!/^(clean|p[12]-\d+items)$/.test(input.status)) { - throw new TowerProtocolError( - `review status must be clean | p1-Nitems | p2-Nitems, got "${input.status}"`, - ); - } - if (!['merge', 'fix-then-merge', 'hold'].includes(input.merge)) { - throw new TowerProtocolError( - `review merge verdict must be merge | fix-then-merge | hold, got "${input.merge}"`, - ); - } - - const existing = await this.reviewsFor(input.target); - const myRounds = existing.filter((r) => r.reviewer === callerName).length; - const round = myRounds + 1; - const reviewedCommit = await branchTip(this.repoRoot, input.target); - - const frontmatter = renderFrontmatter({ - date: dateDash(), - reviewer: callerName, - target: input.target, - round: String(round), - status: input.status, - merge: input.merge, - reviewed_commit: reviewedCommit, - }); - const checks = (input.checks ?? []).map((c) => `- [x] ${c}`).join('\n'); - const content = [ - frontmatter, - '', - '## Findings', - '', - input.findings.trim(), - '', - '## Checks', - checks.length > 0 ? checks : '- [x] (reviewer reported no formal checks)', - '', - '## Decision', - input.decision.trim(), - '', - ].join('\n'); - - const rel = await this.writeUnique( - join(REVIEWS_DIR, reviewFileName({ target: input.target, reviewer: callerName, round })), - content, - ); - await this.appendLog( - callerName, - 'review.write', - { target: input.target, round, verdict: input.status, reviewed: reviewedCommit.slice(0, 7) }, - rel, - ); - return rel; - } - - async reviewsFor(target: string): Promise<readonly TowerReviewInfo[]> { - let files: string[]; - try { - files = await readdir(this.abs(REVIEWS_DIR)); - } catch { - return []; - } - const prefix = `review-${targetSlug(target)}-`; - const reviews: TowerReviewInfo[] = []; - for (const file of files.filter((f) => f.startsWith(prefix) && f.endsWith('.md'))) { - const rel = join(REVIEWS_DIR, file); - let text: string; - try { - text = await readFile(this.abs(rel), 'utf8'); - } catch { - continue; - } - const { fields } = parseFrontmatter(text); - const round = Number.parseInt(fields['round'] ?? '', 10); - if (Number.isNaN(round)) continue; - reviews.push({ - reviewer: fields['reviewer'] ?? 'unknown', - target: fields['target'] ?? target, - round, - status: fields['status'] ?? '', - merge: fields['merge'] ?? '', - reviewedCommit: fields['reviewed_commit'] ?? '', - date: fields['date'] ?? '', - file: rel, - }); - } - reviews.sort((a, b) => a.round - b.round); - return reviews; - } - - async latestReview(target: string): Promise<TowerReviewInfo | undefined> { - const reviews = await this.reviewsFor(target); - return reviews.at(-1); - } - - async merge(branch: string): Promise<{ - readonly mergeCommit: string; - readonly conflictsWith: ReadonlyArray<{ readonly branch: string; readonly files: readonly string[] }>; - readonly noop?: boolean; - }> { - const state = await this.load(); - const mission = state.missions.find((m) => m.branch === branch); - if (mission === undefined) { - throw new TowerProtocolError(`no tower mission owns branch "${branch}"`); - } - const block = async (reason: string, message: string): Promise<TowerProtocolError> => { - await this.appendLog(TOWER_NAME, 'merge.blocked', { branch, reason }); - return new TowerProtocolError(message); - }; - - const unmergedDeps = mission.deps.filter((dep) => { - const depMission = state.missions.find((m) => m.id === dep); - return depMission !== undefined && isOpenMission(depMission); - }); - if (unmergedDeps.length > 0) { - throw await block( - 'deps-unmerged', - `merge blocked: dependencies not merged yet (${unmergedDeps.join(', ')}) — merge in Dependency Flow order`, - ); - } - - if (mission.kind === 'survey') { - const changed = await diffNameOnly(this.repoRoot, state.base, branch); - if (changed.length > 0) { - throw await block( - 'read-only-survey', - `merge blocked: survey mission ${mission.id} is read-only but ${branch} has ${String(changed.length)} changed file(s): ${changed.slice(0, 5).join(', ')} — investigate the worker; if the changes are worth keeping, move them onto a build mission's branch`, - ); - } - mission.status = 'merged'; - await this.save(state); - await this.renderMissionsIndex(state); - await this.renderMissionFile(mission); - const tip = await branchTip(this.repoRoot, state.base); - await this.appendLog(TOWER_NAME, 'merge.noop', { branch, kind: 'survey' }); - return { mergeCommit: tip, conflictsWith: [], noop: true }; - } - - const review = await this.latestReview(branch); - if (review === undefined) { - throw await block( - 'no-review', - `merge blocked: ${branch} has no review — assign a reviewer first`, - ); - } - if (review.status !== 'clean') { - throw await block( - 'not-clean', - `merge blocked: latest review (round ${review.round} by ${review.reviewer}) is "${review.status}" — a clean round is required`, - ); - } - const tip = await branchTip(this.repoRoot, branch); - if (review.reviewedCommit !== tip) { - throw await block( - 'tip-moved', - `merge blocked: ${branch} moved since the clean review (reviewed ${review.reviewedCommit.slice(0, 7)}, tip ${tip.slice(0, 7)}) — re-review required`, - ); - } - - const changed = await diffNameOnly(this.repoRoot, state.base, branch); - const outOfScope = changed.filter( - (file) => !mission.scope.some((glob) => picomatch.isMatch(file, glob)), - ); - if (outOfScope.length > 0) { - throw await block( - 'out-of-scope', - `merge blocked: ${branch} changed files outside mission ${mission.id} scope (${mission.scope.join(', ')}): ${outOfScope.join(', ')} — the tower must widen the mission scope (TowerMission scope patch) or revert those changes`, - ); - } - - let checkedOut: string; - try { - checkedOut = await currentBranch(this.repoRoot); - } catch { - throw await block( - 'base-mismatch', - `merge blocked: the main checkout is in a detached HEAD state — check out the recorded base branch "${state.base}" before merging; nothing was merged`, - ); - } - if (checkedOut !== state.base) { - throw await block( - 'base-mismatch', - `merge blocked: the main checkout is on "${checkedOut}", not the recorded base "${state.base}" — switch it back (\`git checkout ${state.base}\`) and retry; nothing was merged`, - ); - } - - const mergeCommit = await mergeNoFf(this.repoRoot, branch); - mission.status = 'merged'; - - const changedSet = new Set(changed); - const conflictsWith: Array<{ readonly branch: string; readonly files: readonly string[] }> = []; - for (const other of state.missions) { - if (other.branch === branch || !isOpenMission(other)) continue; - if (!(await branchExists(this.repoRoot, other.branch))) continue; - const otherChanged = await diffNameOnly(this.repoRoot, state.base, other.branch); - const overlap = otherChanged.filter((file) => changedSet.has(file)); - if (overlap.length > 0) { - conflictsWith.push({ branch: other.branch, files: overlap }); - } - } - - await this.save(state); - await this.renderMissionsIndex(state); - await this.renderMissionFile(mission); - await this.appendLog(TOWER_NAME, 'merge', { branch, base: state.base, merge_commit: mergeCommit.slice(0, 7) }); - return { mergeCommit, conflictsWith }; - } - - async addWorktree(worktree: string, branch: string, base: string): Promise<string> { - const rel = join(WORKTREES_DIR, worktree); - await worktreeAdd(this.repoRoot, this.abs(rel), branch, base); - await this.appendLog(TOWER_NAME, 'worktree.add', { worktree, branch, base }); - return rel; - } - - async teardown(options: { readonly force?: boolean } = {}): Promise<readonly string[]> { - const state = await this.load(); - const report: string[] = []; - for (const mission of state.missions) { - const rel = join(WORKTREES_DIR, mission.worktree); - const absPath = this.abs(rel); - if (await isWorktreeDirty(absPath)) { - if (options.force !== true) { - report.push(`kept ${rel} (uncommitted changes — rerun with force to remove)`); - await this.appendLog(TOWER_NAME, 'worktree.keep', { - worktree: mission.worktree, - reason: 'uncommitted-changes', - }); - continue; - } - } - try { - await worktreeRemove(this.repoRoot, absPath); - report.push(`removed ${rel}`); - await this.appendLog(TOWER_NAME, 'worktree.remove', { worktree: mission.worktree }); - } catch (error) { - const reason = error instanceof Error ? error.message : String(error); - report.push(`failed to remove ${rel}: ${reason}`); - await this.appendLog(TOWER_NAME, 'worktree.remove.failed', { - worktree: mission.worktree, - reason, - }); - } - } - await this.appendLog(TOWER_NAME, 'teardown', { force: options.force === true ? 'yes' : undefined }); - return report; - } - - private async renderMissionsIndex(state: TowerState): Promise<void> { - const rows = state.missions.map( - (m) => - `| ${m.id} | ${m.title} | ${m.branch} | ${m.worktree} | ${STATUS_EMOJI[m.status]} | ${m.owner ?? '—'} |`, - ); - const deps = state.missions - .flatMap((m) => m.deps.map((dep) => `${dep} → ${m.id}`)) - .join('\n'); - const scopes = state.missions - .map((m) => `- ${m.id}${m.kind === 'survey' ? ' (survey — informational, reserves nothing)' : ''}: ${m.scope.join(', ')}`) - .join('\n'); - const content = [ - '# MISSIONS', - '', - '<!-- Generated by tower tools from state.json — do not edit by hand. -->', - '', - '| ID | Mission | Branch | Worktree | Status | Owner |', - '| -- | ------- | ------ | -------- | ------ | ----- |', - ...rows, - '', - 'Status: 🟡 planned · 🔵 active · 🟢 completed · 🔴 blocked · ⏸️ paused · ✅ merged · 🚫 abandoned', - `Mode: ${state.mode} — Base: ${state.base}`, - '', - '## Dependency Flow', - deps.length > 0 ? deps : '(none)', - '', - '## Scope Map', - scopes.length > 0 ? scopes : '(none)', - '', - ].join('\n'); - await writeFile(this.abs(MISSIONS_INDEX), content, 'utf8'); - } - - private async renderMissionFile(mission: TowerMission): Promise<void> { - const rel = join(MISSIONS_DIR, missionFileName(mission.id, mission.slug)); - const content = [ - `# Mission ${mission.id}: ${mission.title}${mission.kind === 'survey' ? ' 🔍 (read-only survey)' : ''}`, - '', - '<!-- Generated by tower tools from state.json — update via the TowerMission tool. -->', - '', - '| Branch | Worktree | Status | Scope | Owner |', - '| ------ | -------- | ------ | ----- | ----- |', - `| ${mission.branch} | ${mission.worktree} | ${STATUS_EMOJI[mission.status]} | ${mission.scope.join(', ')} | ${mission.owner ?? '—'} |`, - '', - '## Tasks', - ...(mission.tasks.length > 0 - ? mission.tasks.map((t) => `- [${t.done ? 'x' : ' '}] ${t.text}`) - : ['- [ ] (no tasks recorded)']), - '', - '## Dependencies', - mission.deps.length > 0 ? mission.deps.join(', ') : '(none)', - '', - '## Blockers', - ...(mission.blockers.length > 0 ? mission.blockers.map((b) => `- ${b}`) : ['- (none)']), - '', - '## Notes', - ...(mission.notes.length > 0 ? mission.notes.map((n) => `- ${n}`) : ['- (none)']), - '', - ].join('\n'); - await writeFile(this.abs(rel), content, 'utf8'); - } - - abs(rel: string): string { - return join(this.repoRoot, rel); - } - - private async writeUnique(rel: string, content: string): Promise<string> { - const dot = rel.lastIndexOf('.'); - const stem = dot === -1 ? rel : rel.slice(0, dot); - const ext = dot === -1 ? '' : rel.slice(dot); - for (let attempt = 0; attempt < 100; attempt++) { - const candidate = attempt === 0 ? rel : `${stem}-${attempt + 1}${ext}`; - try { - const handle = await open(this.abs(candidate), 'wx'); - try { - await handle.writeFile(content, 'utf8'); - } finally { - await handle.close(); - } - return candidate; - } catch (error) { - if ((error as NodeJS.ErrnoException).code === 'EEXIST') continue; - throw error; - } - } - throw new TowerProtocolError(`could not create a unique file for ${rel}`); - } -} - -async function readGitDir(cwd: string): Promise<string | null> { - try { - const raw = await readFile(join(cwd, '.git'), 'utf8'); - const match = /^gitdir:\s*(.+)$/m.exec(raw.trim()); - if (match?.[1] !== undefined) return match[1]; - return null; - } catch { - return null; - } -} diff --git a/packages/agent-core-v2/src/features/tower/protocol/types.ts b/packages/agent-core-v2/src/features/tower/protocol/types.ts deleted file mode 100644 index d351e7252..000000000 --- a/packages/agent-core-v2/src/features/tower/protocol/types.ts +++ /dev/null @@ -1,88 +0,0 @@ -export type TowerAgentKind = 'worker' | 'reviewer'; - -export interface TowerRosterEntry { - readonly name: string; - readonly agentId: string; - readonly sessionId?: string; - readonly kind: TowerAgentKind; - readonly missionId?: string; - readonly reviewTarget?: string; - readonly worktree?: string; - readonly branch?: string; - readonly spawnedAt: string; -} - -export interface TowerRoster { - readonly agents: TowerRosterEntry[]; -} - -export type TowerMissionStatus = - | 'planned' - | 'active' - | 'completed' - | 'blocked' - | 'paused' - | 'merged' - | 'abandoned'; - -export type TowerMissionKind = 'build' | 'survey'; - -export interface TowerMissionTask { - text: string; - done: boolean; -} - -export interface TowerMission { - readonly id: string; - readonly title: string; - readonly slug: string; - kind: TowerMissionKind; - scope: string[]; - readonly branch: string; - readonly worktree: string; - readonly deps: readonly string[]; - status: TowerMissionStatus; - owner?: string; - tasks: TowerMissionTask[]; - notes: string[]; - blockers: string[]; -} - -export interface TowerState { - readonly version: 1; - readonly base: string; - readonly mode: 'branch' | 'pr'; - readonly createdAt: string; - sessionId?: string; - roster: TowerRoster; - missions: TowerMission[]; -} - -export type TowerFindingType = 'bug' | 'improve' | 'vuln' | 'idea'; -export type TowerFindingSeverity = 'low' | 'medium' | 'high' | 'critical'; - -export type TowerReviewStatus = 'clean' | `p1-${number}items` | `p2-${number}items`; -export type TowerReviewMerge = 'merge' | 'fix-then-merge' | 'hold'; - -export interface TowerReviewInfo { - readonly reviewer: string; - readonly target: string; - readonly round: number; - readonly status: string; - readonly merge: string; - readonly reviewedCommit: string; - readonly date: string; - readonly file: string; -} - -export interface TowerInboxItem { - readonly file: string; - readonly from: string; - readonly to: string; - readonly subject: string; - readonly sentAt: string; - readonly scope?: string; - readonly action?: string; - readonly consentRef?: string; - readonly body: string; -} diff --git a/packages/agent-core-v2/src/features/tower/tools/finding/finding.md b/packages/agent-core-v2/src/features/tower/tools/finding/finding.md deleted file mode 100644 index e198a5522..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/finding/finding.md +++ /dev/null @@ -1,3 +0,0 @@ -File a structured finding (bug / improve / vuln / idea) into .tower/comms/findings/ for the tower to route. - -Use this for anything notable OUTSIDE your mission scope — fixing it directly would violate scope isolation. Include enough detail that another agent can act on it without re-discovering the context. diff --git a/packages/agent-core-v2/src/features/tower/tools/finding/finding.ts b/packages/agent-core-v2/src/features/tower/tools/finding/finding.ts deleted file mode 100644 index 52e44adc9..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/finding/finding.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerFindingToolInputSchema = z - .object({ - type: z.enum(['bug', 'improve', 'vuln', 'idea']).describe('Finding category'), - title: z.string().describe('Short finding title'), - severity: z.enum(['low', 'medium', 'high', 'critical']).optional(), - summary: z.string().describe('What was found, in a sentence or two'), - location: z.string().optional().describe('File/symbol the finding concerns'), - details: z.string().describe('Full details: evidence, reproduction, impact'), - suggested_fix: z.string().describe('What you would do about it'), - }) - .strict(); - -export type TowerFindingToolInput = z.infer<typeof TowerFindingToolInputSchema>; - -export interface ITowerFindingTool extends AgentTool<TowerFindingToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerFindingTool = createDecorator<ITowerFindingTool>('towerFindingTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/finding/findingTool.ts b/packages/agent-core-v2/src/features/tower/tools/finding/findingTool.ts deleted file mode 100644 index 2866bbe49..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/finding/findingTool.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './finding.md?raw'; -import { - ITowerFindingTool, - TowerFindingToolInputSchema, - type TowerFindingToolInput, -} from './finding'; - -export class TowerFindingTool implements ITowerFindingTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerFinding' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerFindingToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerFindingToolInput): ToolExecution { - return { - description: `Filing tower ${args.type} finding: ${args.title}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - const rel = await store.fileFinding(caller, { - type: args.type, - title: args.title, - severity: args.severity, - summary: args.summary, - location: args.location, - details: args.details, - suggestedFix: args.suggested_fix, - }); - return { - output: `finding filed: ${rel}\nThe tower will route it — do not fix out-of-scope issues yourself.`, - }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.md b/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.md deleted file mode 100644 index 71c4e7b98..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.md +++ /dev/null @@ -1 +0,0 @@ -Read your tower inbox: messages addressed to you plus broadcasts, newest first. The tower sees all messages. Full bodies are included — reply with TowerSend. diff --git a/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.ts b/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.ts deleted file mode 100644 index 87b7958de..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/inbox/inbox.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerInboxToolInputSchema = z - .object({ - limit: z - .number() - .int() - .positive() - .optional() - .describe('Max messages to return (default 20), newest first'), - }) - .strict(); - -export type TowerInboxToolInput = z.infer<typeof TowerInboxToolInputSchema>; - -export interface ITowerInboxTool extends AgentTool<TowerInboxToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerInboxTool = createDecorator<ITowerInboxTool>('towerInboxTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/inbox/inboxTool.ts b/packages/agent-core-v2/src/features/tower/tools/inbox/inboxTool.ts deleted file mode 100644 index 5c7155549..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/inbox/inboxTool.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './inbox.md?raw'; -import { ITowerInboxTool, TowerInboxToolInputSchema, type TowerInboxToolInput } from './inbox'; - -const DEFAULT_LIMIT = 20; - -export class TowerInboxTool implements ITowerInboxTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerInbox' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerInboxToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerInboxToolInput): ToolExecution { - return { - description: 'Reading tower inbox', - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - const items = await store.readInbox(caller, args.limit ?? DEFAULT_LIMIT); - if (items.length === 0) { - return { output: `inbox empty for ${caller}` }; - } - const sections = items.map((item) => - [ - `file: ${item.file}`, - `from: ${item.from}`, - `to: ${item.to}`, - `subject: ${item.subject}`, - `sent_at: ${item.sentAt}`, - ...(item.scope !== undefined ? [`scope: ${item.scope}`] : []), - ...(item.action !== undefined ? [`action: ${item.action}`] : []), - '', - item.body, - ].join('\n'), - ); - return { - output: [ - `${String(items.length)} message(s) for ${caller} (newest first):`, - '', - sections.join('\n\n---\n\n'), - ].join('\n'), - }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/init/init.md b/packages/agent-core-v2/src/features/tower/tools/init/init.md deleted file mode 100644 index 77c780ee7..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/init/init.md +++ /dev/null @@ -1,7 +0,0 @@ -Initialize a tower multi-agent workspace in the current repository. - -Creates the .tower/ directory (comms state, inbox, findings, reviews, missions, activity log, worktree slots), enters tower mode, and activates the full tower tool set (TowerPlan/TowerSpawn/TowerMerge/TowerTeardown plus the shared TowerSend/TowerInbox/TowerFinding/TowerReview/TowerMission/TowerStatus). - -Use this when a task is large enough to split across multiple parallel agents with isolated git worktrees and a review-gated merge protocol. Safe to call again — an existing workspace is reported, never reset. Re-entering from a new CLI session adopts the workspace: roster entries the previous session spawned are retired (their agent ids cannot be resumed across sessions), while missions, worktrees, and the activity log carry over. - -Takes an optional `base`: the local branch that every mission forks from and merges back into (default: the branch currently checked out in the main worktree). It is recorded for the workspace's lifetime — missions, reviews, and the merge gate all evaluate against it — so choose it at init time; a re-init reporting an existing workspace keeps the recorded base. Only local branches are accepted: a remote-tracking ref such as "origin/main" cannot receive merges, so create a local branch for it first. When the base differs from the main checkout (or the checkout is detached), work proceeds normally but merges stay blocked until the checkout is switched to the base. diff --git a/packages/agent-core-v2/src/features/tower/tools/init/init.ts b/packages/agent-core-v2/src/features/tower/tools/init/init.ts deleted file mode 100644 index 5e1931e79..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/init/init.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerInitToolInputSchema = z - .object({ - base: z - .string() - .min(1) - .optional() - .describe( - 'Local branch that missions fork from and merge back into (e.g. "develop"). Defaults to the branch currently checked out in the main worktree. Remote-tracking refs (e.g. "origin/main") and tags are not accepted — create a local branch first.', - ), - }) - .strict(); - -export type TowerInitToolInput = z.infer<typeof TowerInitToolInputSchema>; - -export interface ITowerInitTool extends AgentTool<TowerInitToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerInitTool = createDecorator<ITowerInitTool>('towerInitTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/init/initTool.ts b/packages/agent-core-v2/src/features/tower/tools/init/initTool.ts deleted file mode 100644 index a671247fa..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/init/initTool.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { IAgentTowerService } from '#/features/tower/tower'; -import { TowerProtocolError } from '#/features/tower/protocol/index'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { newTowerStore, runTowerTool, TOWER_MAIN_AGENT_ONLY } from '../support'; -import DESCRIPTION from './init.md?raw'; -import { ITowerInitTool, TowerInitToolInputSchema, type TowerInitToolInput } from './init'; - -export class TowerInitTool implements ITowerInitTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerInit' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerInitToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentTowerService private readonly tower: IAgentTowerService, - @ISessionManager private readonly sessions: ISessionManager, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerInitToolInput): ToolExecution { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) { - return { - isError: true, - output: TOWER_MAIN_AGENT_ONLY, - }; - } - return { - description: 'Initializing tower workspace', - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const priorOwner = await store.load().then( - (state) => state.sessionId, - () => undefined, - ); - if ( - priorOwner !== undefined && - priorOwner !== this.sessionContext.sessionId && - this.sessions.get(priorOwner) !== undefined - ) { - throw new TowerProtocolError( - `tower workspace is owned by a live session (${priorOwner}) — adopting it would retire that session's roster. Use the tower from that session, or close it first.`, - ); - } - const result = await store.init(this.sessionContext.sessionId, args.base); - await this.tower.enter(); - return { - output: [ - result.created - ? 'tower workspace initialized' - : 'tower workspace already initialized — existing state preserved', - `base branch: ${result.base}`, - ...(result.ignoredBase !== undefined - ? [ - `requested base "${result.ignoredBase}" ignored — the existing workspace already records base "${result.base}"; tear it down first to rebase the tower`, - ] - : []), - ...(result.checkout !== result.base - ? [ - result.checkout === 'HEAD' - ? `note: the main checkout is in a detached HEAD state — merges stay blocked until the base is checked out (git checkout ${result.base})` - : `note: the main checkout is on "${result.checkout}", not base "${result.base}" — merges stay blocked until it is switched over (git checkout ${result.base})`, - ] - : []), - 'workspace: .tower/ (comms under .tower/comms/, worktrees under .tower/worktrees/)', - ...(result.openMissions.length > 0 - ? [ - `carried-over open missions: ${result.openMissions.join(', ')} — their scopes are still reserved. Continue them (TowerSpawn fresh workers), or — when they belong to an unrelated earlier task — abandon them first (TowerMission status=abandoned) so a new plan can use those files.`, - ] - : []), - ...(result.retiredAgents.length > 0 - ? [ - `adopted from a previous session — retired its stale roster entries: ${result.retiredAgents.join(', ')}. ` + - 'Their agents belong to the dead session and cannot be resumed; missions and worktrees are preserved — TowerSpawn fresh workers to continue them.', - ] - : []), - '', - 'Tower mode is active and the tower tool set is enabled.', - 'Next: split the work with TowerPlan (one mission per disjoint file scope), then TowerSpawn a worker per mission. Assign reviewers for their branches, and merge with TowerMerge only after a clean review.', - ].join('\n'), - }; - }), - }; - } -} diff --git a/packages/agent-core-v2/src/features/tower/tools/merge/merge.md b/packages/agent-core-v2/src/features/tower/tools/merge/merge.md deleted file mode 100644 index afaeaab40..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/merge/merge.md +++ /dev/null @@ -1,3 +0,0 @@ -Merge a tower mission branch into the base branch (--no-ff). - -Hard gate, enforced by the store — the merge is refused unless: the branch's latest review is "clean" and was written against the current branch tip, all dependency missions are already merged, and every changed file falls inside the mission's declared scope. On refusal, the error message tells you exactly what to do next (assign a reviewer, wait for fixes, re-review a moved tip, merge deps first, widen the scope or revert the extra changes). After a merge, branches reported as conflicting must rebase onto the new base and be re-reviewed before they can merge. diff --git a/packages/agent-core-v2/src/features/tower/tools/merge/merge.ts b/packages/agent-core-v2/src/features/tower/tools/merge/merge.ts deleted file mode 100644 index 1f20ca90d..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/merge/merge.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerMergeToolInputSchema = z - .object({ - branch: z - .string() - .describe('The mission branch to merge into the base branch (e.g. "feat/vulkan-build")'), - }) - .strict(); - -export type TowerMergeToolInput = z.infer<typeof TowerMergeToolInputSchema>; - -export interface ITowerMergeTool extends AgentTool<TowerMergeToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerMergeTool = createDecorator<ITowerMergeTool>('towerMergeTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/merge/mergeTool.ts b/packages/agent-core-v2/src/features/tower/tools/merge/mergeTool.ts deleted file mode 100644 index 5438694eb..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/merge/mergeTool.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { newTowerStore, runTowerTool, TOWER_MAIN_AGENT_ONLY } from '../support'; -import DESCRIPTION from './merge.md?raw'; -import { ITowerMergeTool, TowerMergeToolInputSchema, type TowerMergeToolInput } from './merge'; - -export class TowerMergeTool implements ITowerMergeTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerMerge' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerMergeToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerMergeToolInput): ToolExecution { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) { - return { - isError: true, - output: TOWER_MAIN_AGENT_ONLY, - }; - } - return { - description: `Merging tower branch: ${args.branch}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const { mergeCommit, conflictsWith, noop } = await store.merge(args.branch); - if (noop === true) { - return { - output: [ - `${args.branch} is a read-only survey with a zero-diff branch — mission marked merged, no git merge needed.`, - 'Continue with the remaining missions in Dependency Flow order.', - ].join('\n'), - }; - } - const lines = [ - `merged ${args.branch} (merge commit ${mergeCommit.slice(0, 7)})`, - `full commit: ${mergeCommit}`, - ]; - if (conflictsWith.length > 0) { - lines.push( - '', - 'These unmerged branches changed the same files and now likely conflict with the base:', - ...conflictsWith.map( - (conflict) => `- ${conflict.branch}: ${conflict.files.join(', ')}`, - ), - 'Tell each affected worker (Agent resume) to rebase onto the updated base, resolve, push, and request a re-review.', - ); - } else { - lines.push('The mission is now marked merged. Continue with the remaining missions in Dependency Flow order.'); - } - return { output: lines.join('\n') }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/mission/mission.md b/packages/agent-core-v2/src/features/tower/tools/mission/mission.md deleted file mode 100644 index b8a605307..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/mission/mission.md +++ /dev/null @@ -1,5 +0,0 @@ -Read or update a tower mission. - -With only an id, returns the mission view (status, tasks, blockers, notes). With patch fields, applies them: workers may only update the mission they own — the store rejects anything else. Use task_done to tick checklist items, note to log decisions, blocker when stuck (the tower watches for blocked missions). - -Tower only: status=abandoned gives a mission up without merging — its scope stops reserving files for TowerPlan, its dependents may merge, and its branch drops out of conflict checks. Use it for stale missions carried over from a previous session, or for work that will not land; abandoned missions stay in MISSIONS.md (🚫) as the audit trail. diff --git a/packages/agent-core-v2/src/features/tower/tools/mission/mission.ts b/packages/agent-core-v2/src/features/tower/tools/mission/mission.ts deleted file mode 100644 index 61a8ac5a5..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/mission/mission.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerMissionToolInputSchema = z - .object({ - id: z.string().describe('Mission id (e.g. "M1")'), - status: z - .enum(['planned', 'active', 'completed', 'blocked', 'paused', 'merged', 'abandoned']) - .optional() - .describe( - 'New lifecycle status. "abandoned" is tower-only: it gives the mission up without merging — releasing its scope, satisfying its dependents, and excluding its branch from conflict checks.', - ), - note: z.string().optional().describe('Append a decision-log note'), - blocker: z.string().optional().describe('Report a blocker (also sets status to blocked)'), - clear_blockers: z.boolean().optional().describe('Clear all recorded blockers'), - task_done: z - .string() - .optional() - .describe('Mark the first open task containing this text as done'), - scope: z - .array(z.string()) - .optional() - .describe( - 'Tower only: replace the mission scope globs (picomatch — `**` crosses directories). Logged; widens what the merge gate accepts.', - ), - }) - .strict(); - -export type TowerMissionToolInput = z.infer<typeof TowerMissionToolInputSchema>; - -export interface ITowerMissionTool extends AgentTool<TowerMissionToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerMissionTool = createDecorator<ITowerMissionTool>('towerMissionTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/mission/missionTool.ts b/packages/agent-core-v2/src/features/tower/tools/mission/missionTool.ts deleted file mode 100644 index 6f386bb81..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/mission/missionTool.ts +++ /dev/null @@ -1,85 +0,0 @@ -import { readFile } from 'node:fs/promises'; -import { join } from 'node:path'; - -import { MISSIONS_DIR, missionFileName } from '#/features/tower/protocol/index'; -import type { TowerMission, TowerStore } from '#/features/tower/protocol/index'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './mission.md?raw'; -import { - ITowerMissionTool, - TowerMissionToolInputSchema, - type TowerMissionToolInput, -} from './mission'; - -export class TowerMissionTool implements ITowerMissionTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerMission' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerMissionToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerMissionToolInput): ToolExecution { - const hasPatch = - args.status !== undefined || - args.note !== undefined || - args.blocker !== undefined || - args.clear_blockers !== undefined || - args.task_done !== undefined || - args.scope !== undefined; - return { - description: hasPatch - ? `Updating tower mission ${args.id}` - : `Reading tower mission ${args.id}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - if (!hasPatch) { - const mission = state.missions.find((m) => m.id === args.id); - if (mission === undefined) { - const known = state.missions.map((m) => m.id).join(', '); - return { - output: `unknown mission "${args.id}" — known missions: ${known.length > 0 ? known : '(none planned yet)'}`, - isError: true, - }; - } - return { output: await renderMission(store, mission) }; - } - const mission = await store.updateMission(caller, args.id, { - status: args.status, - note: args.note, - blocker: args.blocker, - clearBlockers: args.clear_blockers, - taskDone: args.task_done, - scope: args.scope, - }); - return { - output: [ - `mission ${mission.id} updated — status: ${mission.status}, open tasks: ${String(mission.tasks.filter((t) => !t.done).length)}, blockers: ${String(mission.blockers.length)}`, - '', - await renderMission(store, mission), - ].join('\n'), - }; - }), - }; - } -} - -async function renderMission(store: TowerStore, mission: TowerMission): Promise<string> { - return readFile( - store.abs(join(MISSIONS_DIR, missionFileName(mission.id, mission.slug))), - 'utf8', - ); -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/plan/plan.md b/packages/agent-core-v2/src/features/tower/tools/plan/plan.md deleted file mode 100644 index 8b837abf4..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/plan/plan.md +++ /dev/null @@ -1,3 +0,0 @@ -Split the tower goal into missions. Each mission gets an id (M1, M2, …), a branch (feat/<slug>), and an isolated git worktree (.tower/worktrees/wt-N). - -Rules enforced by the store: scopes of build missions must be pairwise disjoint (survey missions are read-only and reserve no scope), and deps must reference existing mission ids. Plan once, then spawn one worker per mission with TowerSpawn. Requires an active tower workspace (run TowerInit first). diff --git a/packages/agent-core-v2/src/features/tower/tools/plan/plan.ts b/packages/agent-core-v2/src/features/tower/tools/plan/plan.ts deleted file mode 100644 index 1ce510963..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/plan/plan.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerPlanToolInputSchema = z - .object({ - missions: z - .array( - z - .object({ - title: z.string().describe('Short mission title; becomes the branch/worktree slug'), - scope: z - .array(z.string()) - .min(1) - .describe( - 'Files/globs this mission may touch (e.g. "src/build/**"). Scopes of different missions must not overlap.', - ), - tasks: z - .array(z.string()) - .optional() - .describe('Checklist the worker will tick off via TowerMission task_done'), - deps: z - .array(z.string()) - .optional() - .describe('Mission ids (e.g. "M1") that must merge before this one can merge'), - kind: z - .enum(['build', 'survey']) - .optional() - .describe( - '"survey" = read-only investigation: the scope is informational and reserves nothing (other missions may overlap it), the worker must not change code, and closing it needs no review or git merge. Default "build".', - ), - }) - .strict(), - ) - .min(1), - }) - .strict(); - -export type TowerPlanToolInput = z.infer<typeof TowerPlanToolInputSchema>; - -export interface ITowerPlanTool extends AgentTool<TowerPlanToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerPlanTool = createDecorator<ITowerPlanTool>('towerPlanTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/plan/planTool.ts b/packages/agent-core-v2/src/features/tower/tools/plan/planTool.ts deleted file mode 100644 index f38d2ba8b..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/plan/planTool.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentTowerService } from '#/features/tower/tower'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { newTowerStore, runTowerTool, TOWER_MAIN_AGENT_ONLY } from '../support'; -import DESCRIPTION from './plan.md?raw'; -import { ITowerPlanTool, TowerPlanToolInputSchema, type TowerPlanToolInput } from './plan'; - -export class TowerPlanTool implements ITowerPlanTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerPlan' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerPlanToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentTowerService private readonly tower: IAgentTowerService, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerPlanToolInput): ToolExecution { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) { - return { - isError: true, - output: TOWER_MAIN_AGENT_ONLY, - }; - } - return { - description: `Planning ${String(args.missions.length)} tower mission(s)`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - if (!this.tower.isActive) { - return { - output: 'tower mode is not active — run TowerInit first', - isError: true, - }; - } - const store = newTowerStore(this.sessionContext); - const missions = await store.plan(args.missions); - const rows = missions.map( - (m) => - `| ${m.id} | ${m.title} | ${m.kind} | ${m.branch} | ${m.worktree} | ${m.scope.join(', ')} |`, - ); - return { - output: [ - `planned ${String(missions.length)} mission(s):`, - '', - '| ID | Mission | Kind | Branch | Worktree | Scope |', - '| -- | ------- | ---- | ------ | -------- | ----- |', - ...rows, - '', - 'Next: TowerSpawn one worker per mission (workers get their worktree path and mission briefing automatically), plus reviewers for the branches. Survey missions need no reviewer — they close with a zero-diff TowerMerge.', - ].join('\n'), - }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/review/review.md b/packages/agent-core-v2/src/features/tower/tools/review/review.md deleted file mode 100644 index 35cf7c0be..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/review/review.md +++ /dev/null @@ -1,3 +0,0 @@ -Submit a review verdict for a branch you were assigned to review (via TowerSpawn review_target). - -The review is stamped with the current branch tip — if the branch moves afterwards, the tower must ask for a re-review before merging. Only reviewers assigned to the target (or the tower) may submit; the round number is assigned automatically. diff --git a/packages/agent-core-v2/src/features/tower/tools/review/review.ts b/packages/agent-core-v2/src/features/tower/tools/review/review.ts deleted file mode 100644 index e0ea57cc5..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/review/review.ts +++ /dev/null @@ -1,32 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerReviewToolInputSchema = z - .object({ - target: z.string().describe('The branch you were assigned to review'), - status: z - .string() - .regex(/^(clean|p[12]-\d+items)$/) - .describe( - 'Verdict: "clean", or "p1-Nitems" / "p2-Nitems" with the number of findings at that priority', - ), - merge: z - .enum(['merge', 'fix-then-merge', 'hold']) - .describe('Merge recommendation for the tower'), - findings: z.string().describe('Full findings text (markdown); write "none" when clean'), - checks: z - .array(z.string()) - .optional() - .describe('Checklist items you verified (e.g. "tests pass", "no secrets")'), - decision: z.string().describe('The reasoning behind your verdict'), - }) - .strict(); - -export type TowerReviewToolInput = z.infer<typeof TowerReviewToolInputSchema>; - -export interface ITowerReviewTool extends AgentTool<TowerReviewToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerReviewTool = createDecorator<ITowerReviewTool>('towerReviewTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/review/reviewTool.ts b/packages/agent-core-v2/src/features/tower/tools/review/reviewTool.ts deleted file mode 100644 index fc94b42b8..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/review/reviewTool.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './review.md?raw'; -import { - ITowerReviewTool, - TowerReviewToolInputSchema, - type TowerReviewToolInput, -} from './review'; - -export class TowerReviewTool implements ITowerReviewTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerReview' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerReviewToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerReviewToolInput): ToolExecution { - return { - description: `Submitting tower review for ${args.target}: ${args.status}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - const rel = await store.submitReview(caller, { - target: args.target, - status: args.status, - merge: args.merge, - findings: args.findings, - checks: args.checks, - decision: args.decision, - }); - return { - output: `review submitted: ${rel}\nAlso notify the branch author (or the tower) with TowerSend so the verdict is seen.`, - }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/send/send.md b/packages/agent-core-v2/src/features/tower/tools/send/send.md deleted file mode 100644 index d6ff90723..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/send/send.md +++ /dev/null @@ -1,3 +0,0 @@ -Send an inbox message to a tower participant: a roster agent by name, "tower" (the control tower), or "all" (broadcast). - -Recipients read it with TowerInbox. Sending to yourself or to an unknown name is rejected — the error lists the known names. diff --git a/packages/agent-core-v2/src/features/tower/tools/send/send.ts b/packages/agent-core-v2/src/features/tower/tools/send/send.ts deleted file mode 100644 index 05006b0d8..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/send/send.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerSendToolInputSchema = z - .object({ - to: z - .string() - .describe('Recipient: a roster agent name, "tower", or "all" (broadcast)'), - subject: z.string().describe('One-line subject; keep it greppable'), - body: z.string().describe('Full message body (markdown)'), - scope: z.string().optional().describe('Optional scope tag (e.g. the mission id)'), - action: z.string().optional().describe('Optional action tag for machine routing'), - consent_ref: z - .string() - .optional() - .describe('Optional reference to a consent/approval record this message relies on'), - }) - .strict(); - -export type TowerSendToolInput = z.infer<typeof TowerSendToolInputSchema>; - -export interface ITowerSendTool extends AgentTool<TowerSendToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerSendTool = createDecorator<ITowerSendTool>('towerSendTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/send/sendTool.ts b/packages/agent-core-v2/src/features/tower/tools/send/sendTool.ts deleted file mode 100644 index b125bf118..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/send/sendTool.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './send.md?raw'; -import { ITowerSendTool, TowerSendToolInputSchema, type TowerSendToolInput } from './send'; - -export class TowerSendTool implements ITowerSendTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerSend' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerSendToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerSendToolInput): ToolExecution { - return { - description: `Sending tower message to ${args.to}: ${args.subject}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - const rel = await store.send(caller, { - to: args.to, - subject: args.subject, - body: args.body, - scope: args.scope, - action: args.action, - consentRef: args.consent_ref, - }); - return { output: `message sent to ${args.to}\nfile: ${rel}` }; - }), - }; - } -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.md b/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.md deleted file mode 100644 index 425d2aed0..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.md +++ /dev/null @@ -1,5 +0,0 @@ -Spawn a tower worker or reviewer as a background subagent and register it in the tower roster. - -Workers: pass mission_id — the tool creates the mission worktree, marks the mission active with this worker as owner, and briefs the agent with the full mission text. Reviewers: pass review_target — the agent gets a review checklist and must submit its verdict via TowerReview. - -The briefing prompt is assembled by this tool (worktree path, scope, protocol rules); use instructions only for extra context. If the name is already registered, resume the existing agent with the Agent tool instead of spawning a duplicate. diff --git a/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.ts b/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.ts deleted file mode 100644 index aa002a0c8..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/spawn/spawn.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerSpawnToolInputSchema = z - .object({ - name: z - .string() - .describe( - 'Unique tower name for the agent (e.g. "agent-build", "reviewer-a"). Used for inbox addressing and mission ownership.', - ), - kind: z - .enum(['worker', 'reviewer']) - .describe('workers execute a mission in their worktree; reviewers review one branch'), - mission_id: z - .string() - .optional() - .describe('Required for workers: the mission id (e.g. "M1") from TowerPlan'), - review_target: z - .string() - .optional() - .describe('Required for reviewers: the branch to review (e.g. "feat/vulkan-build")'), - instructions: z - .string() - .optional() - .describe('Extra tower instructions appended to the generated briefing'), - }) - .strict() - .superRefine((value, ctx) => { - if (value.kind === 'worker' && (value.mission_id ?? '').trim().length === 0) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - path: ['mission_id'], - message: 'worker spawns require mission_id', - }); - } - if (value.kind === 'reviewer' && (value.review_target ?? '').trim().length === 0) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - path: ['review_target'], - message: 'reviewer spawns require review_target', - }); - } - }); - -export type TowerSpawnToolInput = z.infer<typeof TowerSpawnToolInputSchema>; - -export interface ITowerSpawnTool extends AgentTool<TowerSpawnToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerSpawnTool = createDecorator<ITowerSpawnTool>('towerSpawnTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/spawn/spawnTool.ts b/packages/agent-core-v2/src/features/tower/tools/spawn/spawnTool.ts deleted file mode 100644 index a50eb5c83..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/spawn/spawnTool.ts +++ /dev/null @@ -1,407 +0,0 @@ -import { readFile } from 'node:fs/promises'; -import { join } from 'node:path'; - -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { IAgentProfileService } from '#/agent/profile/profile'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; -import { IAgentTaskService } from '#/agent/task/task'; -import { - GitError, - MISSIONS_DIR, - TOWER_NAME, - TowerProtocolError, - TowerStore, - WORKTREES_DIR, - missionFileName, - resolveTowerRepoRoot, - type TowerMission, - type TowerState, -} from '#/features/tower/protocol/index'; -import { IAgentTowerService, TOWER_WORKER_PROFILE } from '#/features/tower/tower'; -import { ITowerRateLimitService } from '#/features/tower/towerRateLimit'; -import { IConfigService } from '#/app/config/config'; -import { IFlagService } from '#/app/flag/flag'; -import { IModelCatalog } from '#/kosong/model/catalog'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import { - type ExecutableToolContext, - type ExecutableToolResult, - type ToolExecution, -} from '#/tool/toolContract'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { subagentLabels } from '#/session/agentLifecycle/subagentMetadata'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { - DEFAULT_SUBAGENT_TIMEOUT_MS, - resolveSubagentBinding, - resolveSubagentThinking, - wrapSubagentModelError, -} from '#/session/subagent/configSection'; -import { emitAgentRunSpawned, mirrorAgentRun } from '#/session/subagent/mirrorAgentRun'; -import { ISessionSubagentService } from '#/session/subagent/subagent'; - -import { SubagentTask, type SubagentHandle } from '#/agent/tools/agent/subagent-task'; - -import { TOWER_MAIN_AGENT_ONLY } from '../support'; -import { ITowerSpawnTool, TowerSpawnToolInputSchema, type TowerSpawnToolInput } from './spawn'; -import DESCRIPTION from './spawn.md?raw'; - -type SubagentBinding = ReturnType<typeof resolveSubagentBinding>; - -export class TowerSpawnTool implements ITowerSpawnTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerSpawn' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerSpawnToolInputSchema); - - private readonly callerAgentId: string; - - constructor( - @IAgentTowerService private readonly tower: IAgentTowerService, - @ITowerRateLimitService private readonly rateLimit: ITowerRateLimitService, - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext scopeContext: IAgentScopeContext, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, - @ISessionSubagentService private readonly subagents: ISessionSubagentService, - @IAgentTaskService private readonly tasks: IAgentTaskService, - @IAgentProfileService private readonly profile: IAgentProfileService, - @IConfigService private readonly config: IConfigService, - @IFlagService private readonly flags: IFlagService, - @IModelCatalog private readonly modelCatalog: IModelCatalog, - ) { - this.callerAgentId = scopeContext.agentId; - } - - resolveExecution(args: TowerSpawnToolInput): ToolExecution { - if (this.callerAgentId !== MAIN_AGENT_ID) { - return { - isError: true, - output: TOWER_MAIN_AGENT_ONLY, - }; - } - return { - description: `Spawning tower ${args.kind} "${args.name}"`, - approvalRule: this.name, - execute: (ctx) => this.execution(args, ctx), - }; - } - - private newStore(): TowerStore { - return new TowerStore(resolveTowerRepoRoot(this.sessionContext.cwd)); - } - - private async execution( - args: TowerSpawnToolInput, - { toolCallId }: ExecutableToolContext, - ): Promise<ExecutableToolResult> { - try { - if (!this.tower.isActive) { - return { - output: 'tower mode is not active — run TowerInit first', - isError: true, - }; - } - const store = this.newStore(); - const state = await store.load(); - - const existing = store.findByName(state, args.name); - if (existing !== undefined) { - return { - output: - `tower agent "${args.name}" is already registered (agent_id: ${existing.agentId}, kind: ${existing.kind}) — ` + - `resume it instead of spawning a duplicate: Agent(resume="${existing.agentId}", prompt="...")`, - isError: true, - }; - } - - const notes: string[] = []; - let mission: TowerMission | undefined; - let reviewTarget: string | undefined; - if (args.kind === 'worker') { - const missionId = args.mission_id; - if (missionId === undefined) { - return { output: 'worker spawns require mission_id', isError: true }; - } - mission = state.missions.find((m) => m.id === missionId); - if (mission === undefined) { - const known = state.missions.map((m) => m.id).join(', '); - return { - output: `unknown mission "${missionId}" — known missions: ${known.length > 0 ? known : '(none planned yet)'}`, - isError: true, - }; - } - try { - await store.addWorktree(mission.worktree, mission.branch, state.base); - } catch (error) { - notes.push( - `worktree setup warning (continuing): ${error instanceof Error ? error.message : String(error)}`, - ); - } - } else { - reviewTarget = args.review_target; - if (reviewTarget === undefined) { - return { output: 'reviewer spawns require review_target', isError: true }; - } - } - - const prompt = await this.buildPrompt(args, store, state, mission, reviewTarget); - const description = - mission !== undefined - ? `tower worker ${args.name}: ${mission.title}` - : `tower reviewer ${args.name}: ${reviewTarget ?? ''}`; - - const gate = this.rateLimit.acquire(); - if (!gate.ok) { - return { output: gate.reason, isError: true }; - } - let slotHeld = true; - try { - const controller = new AbortController(); - const own = this.profile.data(); - const binding = - own.modelAlias === undefined - ? undefined - : resolveSubagentBinding( - this.config, - this.flags, - { modelAlias: own.modelAlias, thinkingLevel: own.thinkingLevel }, - args.kind === 'reviewer' ? 'primary' : undefined, - ); - let handle: SubagentHandle; - try { - handle = await this.launch(prompt, description, toolCallId, controller, binding); - } catch (error) { - return { - output: `tower spawn failed: ${error instanceof Error ? error.message : String(error)}`, - isError: true, - }; - } - - let taskId: string; - try { - taskId = this.tasks.registerTask(new SubagentTask(handle, description, controller), { - detached: true, - timeoutMs: DEFAULT_SUBAGENT_TIMEOUT_MS, - signal: undefined, - }); - } catch (error) { - controller.abort(); - void handle.completion.catch(() => {}); - return { - output: error instanceof Error ? error.message : String(error), - isError: true, - }; - } - void handle.completion - .catch(() => {}) - .finally(() => { - this.rateLimit.release(); - }); - slotHeld = false; - - await store.registerAgent({ - name: args.name, - agentId: handle.agentId, - sessionId: this.sessionContext.sessionId, - kind: args.kind, - missionId: mission?.id, - reviewTarget, - worktree: mission?.worktree, - branch: mission?.branch, - spawnedAt: new Date().toISOString(), - }); - if (mission !== undefined) { - await store.updateMission( - TOWER_NAME, - mission.id, - { status: 'active', owner: args.name }, - { silent: true }, - ); - } - await store.appendLog( - TOWER_NAME, - 'spawn', - { - name: args.name, - kind: args.kind, - agent: handle.agentId, - mission: mission?.id, - target: reviewTarget, - model: binding?.model, - }, - mission !== undefined - ? join(MISSIONS_DIR, missionFileName(mission.id, mission.slug)) - : undefined, - ); - - return { - output: [ - `name: ${args.name}`, - `kind: ${args.kind}`, - `agent_id: ${handle.agentId}`, - `task_id: ${taskId}`, - 'status: running', - ...(binding !== undefined ? [`model: ${binding.model}`] : []), - ...(mission !== undefined - ? [ - `mission: ${mission.id} — ${mission.title}`, - `branch: ${mission.branch}`, - `worktree: ${store.abs(join(WORKTREES_DIR, mission.worktree))}`, - ] - : [`review_target: ${reviewTarget ?? ''}`]), - ...notes, - '', - `The ${args.kind} runs detached in the background; its completion arrives as a notification. Track progress with TowerStatus / TowerInbox; recover a dead agent with Agent(resume="${handle.agentId}", prompt="...").`, - ].join('\n'), - }; - } finally { - if (slotHeld) this.rateLimit.release(); - } - } catch (error) { - if (error instanceof TowerProtocolError || error instanceof GitError) { - return { output: error.message, isError: true }; - } - throw error; - } - } - - private async launch( - prompt: string, - description: string, - toolCallId: string, - controller: AbortController, - binding: SubagentBinding | undefined, - ): Promise<SubagentHandle> { - const requester = this.agentLifecycle.handleOf(this.callerAgentId); - if (requester === undefined) { - throw new Error(`Caller agent "${this.callerAgentId}" does not exist`); - } - - let createdContext: AgentContext; - try { - const model = binding === undefined ? undefined : this.modelCatalog.get(binding.model); - createdContext = await this.agentLifecycle.create({ - binding: { - profile: TOWER_WORKER_PROFILE, - model: binding?.model, - thinking: resolveSubagentThinking(this.config, model, binding?.thinking), - }, - labels: subagentLabels(this.callerAgentId), - }); - } catch (error) { - throw binding === undefined - ? error - : wrapSubagentModelError(error, binding.model, this.profile.data().modelAlias); - } - const created = this.agentLifecycle.handleOf(createdContext.agentId)!; - created.accessor.get(IAgentPermissionModeService).setMode('auto'); - const agentId = createdContext.agentId; - - emitAgentRunSpawned(requester, agentId, { - profileName: TOWER_WORKER_PROFILE, - parentToolCallId: toolCallId, - description, - runInBackground: true, - }); - - const run = await this.subagents.run( - createdContext, - { kind: 'prompt', prompt }, - { signal: controller.signal }, - ); - const mirrored = mirrorAgentRun(requester, run, { - profileName: TOWER_WORKER_PROFILE, - prompt, - signal: controller.signal, - cancel: (reason) => { - controller.abort(reason); - }, - }); - return { - agentId, - profileName: TOWER_WORKER_PROFILE, - completion: mirrored.then((r) => ({ result: r.summary, usage: r.usage })), - }; - } - - private async buildPrompt( - args: TowerSpawnToolInput, - store: TowerStore, - state: TowerState, - mission: TowerMission | undefined, - reviewTarget: string | undefined, - ): Promise<string> { - const extra = - args.instructions !== undefined && args.instructions.trim().length > 0 - ? `\n\n# Additional instructions from the tower\n${args.instructions.trim()}` - : ''; - if (mission !== undefined) { - const missionText = await readFile( - store.abs(join(MISSIONS_DIR, missionFileName(mission.id, mission.slug))), - 'utf8', - ); - const worktreeAbs = store.abs(join(WORKTREES_DIR, mission.worktree)); - const workplace = - `# Your workplace\n` + - `- Your private git worktree: ${worktreeAbs}\n` + - `- Your branch: ${mission.branch} (base: ${state.base})\n` + - `- Your working directory is the main checkout, NOT your worktree — address the worktree explicitly: every Read/Write/Edit/Grep/Glob path must be absolute and under ${worktreeAbs}, and every Bash command must \`cd ${worktreeAbs}\` first. A permission guard hard-denies any Write/Edit outside it. Never touch the main checkout (${store.repoRoot}) or another agent's worktree slot.\n` + - (mission.kind === 'survey' - ? `- Scope — what you investigate (read-only; reserves nothing): ${mission.scope.join(', ')}\n\n` - : `- Scope — the only files you may change: ${mission.scope.join(', ')}\n\n`); - if (mission.kind === 'survey') { - return ( - `You are "${args.name}", a tower worker agent in a multi-agent workspace, assigned a READ-ONLY survey mission.\n\n` + - workplace + - `# Your mission\n\n${missionText.trim()}\n\n` + - `# Read-only discipline\n` + - '- Your scope marks what you investigate, not what you may change. You MUST NOT modify, add, or delete any file in the repo, and your branch must end with zero commits — a changed file makes the merge gate reject your mission as a read-only violation.\n' + - '- Your deliverables are knowledge: record findings as TowerMission notes, send summaries to the tower and to dependent agents with TowerSend, and file TowerFinding for out-of-scope discoveries.\n\n' + - `# Communication protocol\n` + - '- Coordinate through tower tools ONLY: TowerSend / TowerInbox / TowerFinding / TowerMission / TowerStatus. Reach the tower and sibling agents with TowerSend; check TowerInbox regularly.\n' + - '- NEVER create or edit files under `.tower/` by hand — the tools are the only writers.\n\n' + - `# When the survey is done\n` + - `1. Mark the mission completed: TowerMission(id="${mission.id}", status="completed").\n` + - '2. Send the tower your summary: TowerSend(to="tower", subject="survey-summary", body=the full survey result).\n' + - '3. Finish with a structured final summary: what you covered, key facts with file:line references, open questions.' + - extra - ); - } - return ( - `You are "${args.name}", a tower worker agent in a multi-agent workspace.\n\n` + - workplace + - `# Your mission\n\n${missionText.trim()}\n\n` + - `# Communication protocol\n` + - '- Coordinate through tower tools ONLY: TowerSend / TowerInbox / TowerFinding / TowerMission / TowerStatus. Reach the tower and sibling agents with TowerSend; check TowerInbox regularly.\n' + - '- NEVER create or edit files under `.tower/` by hand — the tools are the only writers; hand-written protocol files break the merge gate.\n' + - '- Found something notable outside your scope? File it with TowerFinding instead of fixing it.\n' + - '- Keep your mission current with TowerMission: task_done as you finish tasks, note for decisions, blocker when stuck.\n\n' + - `# When the mission is done\n` + - '1. `git add` + `git commit` everything in your worktree (and `git push` only if a remote is configured).\n' + - `2. Mark the mission completed: TowerMission(id="${mission.id}", status="completed").\n` + - '3. Request review: TowerSend(to="tower", subject="review-request", body=what you changed and why).\n' + - '4. Finish with a structured final summary: files changed, key decisions, open follow-ups.' + - extra - ); - } - const target = reviewTarget ?? ''; - const author = state.missions.find((m) => m.branch === target)?.owner; - return ( - `You are "${args.name}", a tower reviewer agent in a multi-agent workspace.\n\n` + - `# Your assignment\n` + - `Review branch "${target}" against base "${state.base}".\n` + - `- Work read-only in the main checkout (${store.repoRoot}): \`git diff ${state.base}...${target}\`, \`git log ${state.base}..${target}\`, and read files as needed.\n` + - '- Do NOT modify any code, and never create or edit files under `.tower/` by hand — protocol artifacts go through the tower tools.\n\n' + - `# Review checklist (in priority order)\n` + - '1. Security\n2. Data integrity\n3. Performance\n4. Error handling\n5. Code quality\n\n' + - `# When done — both steps are mandatory\n` + - `1. Submit your verdict with TowerReview: { target: "${target}", status: "clean" | "p1-Nitems" | "p2-Nitems", merge: "merge" | "fix-then-merge" | "hold", findings, checks, decision }. Only a "clean" review of the exact branch tip lets the tower merge.\n` + - (author !== undefined - ? `2. Notify the author with TowerSend(to="${author}", subject="review-result", ...).\n` - : '2. The author of this branch is not recorded — notify the tower instead: TowerSend(to="tower", subject="review-result", ...).\n') + - 'Then finish with a structured summary of the review.' + - extra - ); - } -} diff --git a/packages/agent-core-v2/src/features/tower/tools/status/status.md b/packages/agent-core-v2/src/features/tower/tools/status/status.md deleted file mode 100644 index 25ea7bb71..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/status/status.md +++ /dev/null @@ -1 +0,0 @@ -Show the tower dashboard: missions (status/owner), the agent roster, the review-gate state of every unmerged branch (latest review round/status and whether the reviewed commit still matches the branch tip), your inbox message count, and the last activity log lines. diff --git a/packages/agent-core-v2/src/features/tower/tools/status/status.ts b/packages/agent-core-v2/src/features/tower/tools/status/status.ts deleted file mode 100644 index eb51b74f9..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/status/status.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerStatusToolInputSchema = z.object({}).strict(); - -export type TowerStatusToolInput = z.infer<typeof TowerStatusToolInputSchema>; - -export interface ITowerStatusTool extends AgentTool<TowerStatusToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerStatusTool = createDecorator<ITowerStatusTool>('towerStatusTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/status/statusTool.ts b/packages/agent-core-v2/src/features/tower/tools/status/statusTool.ts deleted file mode 100644 index d94405b84..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/status/statusTool.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { branchExists, branchTip } from '#/features/tower/protocol/index'; -import type { TowerMission, TowerState, TowerStore } from '#/features/tower/protocol/index'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { - ITowerRateLimitService, - type TowerRateLimitSnapshot, -} from '#/features/tower/towerRateLimit'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { callerName, newTowerStore, runTowerTool } from '../support'; -import DESCRIPTION from './status.md?raw'; -import { - ITowerStatusTool, - TowerStatusToolInputSchema, - type TowerStatusToolInput, -} from './status'; - -const STATUS_EMOJI: Record<TowerMission['status'], string> = { - planned: '🟡', - active: '🔵', - completed: '🟢', - blocked: '🔴', - paused: '⏸️', - merged: '✅', - abandoned: '🚫', -}; - -const INBOX_COUNT_LIMIT = 1000; -const RECENT_LOG_LINES = 10; - -export class TowerStatusTool implements ITowerStatusTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerStatus' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerStatusToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - @ITowerRateLimitService private readonly rateLimit: ITowerRateLimitService, - ) {} - - resolveExecution(_args: TowerStatusToolInput): ToolExecution { - return { - description: 'Reading tower status', - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const state = await store.load(); - const caller = callerName(this.scopeContext.agentId, store, state); - - const sections: string[] = [ - `# Tower status — base: ${state.base} (mode: ${state.mode}), you are: ${caller}`, - '', - '## Missions', - '', - ...renderMissions(state), - '', - '## Roster', - '', - ...renderRoster(state), - '', - '## Review gate (unmerged branches)', - '', - ...(await this.renderReviewGate(store, state)), - ]; - - if ( - state.missions.length > 0 && - state.missions.every( - (mission) => mission.status === 'merged' || mission.status === 'abandoned', - ) - ) { - sections.push( - '', - '## Done', - '', - 'All missions are merged or abandoned. Free the worktree checkouts now: run TowerTeardown (branches and .tower/comms/ are kept; dirty worktrees are protected).', - ); - } - - const inbox = await store.readInbox(caller, INBOX_COUNT_LIMIT); - sections.push( - '', - '## Inbox', - '', - `${String(inbox.length)} message(s) visible to you — read with TowerInbox.`, - '', - '## Concurrency (adaptive)', - '', - renderConcurrency(this.rateLimit.snapshot()), - '', - '## Recent activity', - '', - ); - const log = await store.recentLog(RECENT_LOG_LINES); - sections.push(...(log.length > 0 ? log : ['(activity log is empty)'])); - return { output: sections.join('\n') }; - }), - }; - } - - private async renderReviewGate(store: TowerStore, state: TowerState): Promise<string[]> { - const pending = state.missions.filter( - (m) => m.status !== 'merged' && m.status !== 'abandoned', - ); - if (pending.length === 0) return ['(no open missions — or none planned yet)']; - const lines: string[] = []; - for (const mission of pending) { - const review = await store.latestReview(mission.branch); - if (review === undefined) { - lines.push(`- ${mission.branch} (${mission.id}): no review yet`); - continue; - } - const tip = (await branchExists(store.repoRoot, mission.branch)) - ? await branchTip(store.repoRoot, mission.branch) - : undefined; - const sync = - tip === undefined - ? 'branch not created yet' - : tip === review.reviewedCommit - ? 'reviewed commit matches tip' - : `STALE — tip moved to ${tip.slice(0, 7)}, re-review required`; - lines.push( - `- ${mission.branch} (${mission.id}): round ${String(review.round)} by ${review.reviewer} — ${review.status} (${sync})`, - ); - } - return lines; - } -} - -function renderConcurrency(snapshot: TowerRateLimitSnapshot): string { - const parts = [ - `budget: ${String(snapshot.budget)} agent(s) · inflight: ${String(snapshot.inflight)}`, - ]; - if (snapshot.blockedUntil !== null) { - const remainingMs = snapshot.blockedUntil - Date.now(); - parts.push( - remainingMs > 0 - ? `spawns PAUSED for ~${String(Math.ceil(remainingMs / 1000))}s (provider rate limit — successful requests lift the pause early)` - : 'spawn pause expired — budget probing resumes', - ); - } else { - parts.push('spawns open'); - } - return parts.join(' · '); -} - -function renderMissions(state: TowerState): string[] { - if (state.missions.length === 0) return ['(no missions planned — use TowerPlan)']; - return [ - '| ID | Mission | Branch | Worktree | Status | Owner |', - '| -- | ------- | ------ | -------- | ------ | ----- |', - ...state.missions.map( - (m) => - `| ${m.id} | ${m.title}${m.kind === 'survey' ? ' 🔍' : ''} | ${m.branch} | ${m.worktree} | ${STATUS_EMOJI[m.status]} ${m.status} | ${m.owner ?? '—'} |`, - ), - ]; -} - -function renderRoster(state: TowerState): string[] { - if (state.roster.agents.length === 0) { - return ['(no agents registered — spawn workers/reviewers with TowerSpawn)']; - } - return state.roster.agents.map((a) => { - const assignment = - a.kind === 'worker' - ? `mission ${a.missionId ?? '?'} (branch ${a.branch ?? '?'}, worktree ${a.worktree ?? '?'})` - : `reviewing ${a.reviewTarget ?? '?'}`; - return `- ${a.name} (${a.kind}) — agent ${a.agentId}, ${assignment}`; - }); -} - diff --git a/packages/agent-core-v2/src/features/tower/tools/support.ts b/packages/agent-core-v2/src/features/tower/tools/support.ts deleted file mode 100644 index 11aa7753b..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/support.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - GitError, - TowerProtocolError, - TowerStore, - resolveTowerRepoRoot, - type TowerState, -} from '#/features/tower/protocol/index'; -import type { ISessionContext } from '#/session/sessionContext/sessionContext'; -import type { ExecutableToolResult } from '#/tool/toolContract'; - -export function newTowerStore(sessionContext: ISessionContext): TowerStore { - return new TowerStore(resolveTowerRepoRoot(sessionContext.cwd)); -} - -export const TOWER_MAIN_AGENT_ONLY = - 'Tower orchestration tools are only supported by the main agent.'; - -export function callerName(agentId: string, store: TowerStore, state: TowerState): string { - return store.resolveCallerName(state, agentId); -} - -export async function runTowerTool( - execute: () => Promise<ExecutableToolResult>, -): Promise<ExecutableToolResult> { - try { - return await execute(); - } catch (error) { - if (error instanceof TowerProtocolError || error instanceof GitError) { - return { output: error.message, isError: true }; - } - throw error; - } -} diff --git a/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.md b/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.md deleted file mode 100644 index 9e9a6bfee..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.md +++ /dev/null @@ -1,3 +0,0 @@ -Tear down the tower workspace after all missions are merged (or abandoned). - -Removes the mission worktrees — worktrees with uncommitted changes are kept and listed unless force is set. Exits tower mode. The .tower/comms/ directory (state, inbox, findings, reviews, activity log) is always kept as the audit trail. diff --git a/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.ts b/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.ts deleted file mode 100644 index b26b5acf5..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/teardown/teardown.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { z } from 'zod'; - -import { createDecorator } from '#/_base/di/instantiation'; -import { type AgentTool } from '#/tool/toolContract'; - -export const TowerTeardownToolInputSchema = z - .object({ - force: z - .boolean() - .optional() - .describe('Remove worktrees even when they contain uncommitted changes'), - }) - .strict(); - -export type TowerTeardownToolInput = z.infer<typeof TowerTeardownToolInputSchema>; - -export interface ITowerTeardownTool extends AgentTool<TowerTeardownToolInput> { - readonly _serviceBrand: undefined; -} -export const ITowerTeardownTool = createDecorator<ITowerTeardownTool>('towerTeardownTool'); diff --git a/packages/agent-core-v2/src/features/tower/tools/teardown/teardownTool.ts b/packages/agent-core-v2/src/features/tower/tools/teardown/teardownTool.ts deleted file mode 100644 index 9572c863b..000000000 --- a/packages/agent-core-v2/src/features/tower/tools/teardown/teardownTool.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { IAgentTowerService } from '#/features/tower/tower'; -import { TowerProtocolError } from '#/features/tower/protocol/index'; -import { MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { toInputJsonSchema } from '#/tool/input-schema'; -import type { ToolExecution } from '#/tool/toolContract'; - -import { newTowerStore, runTowerTool, TOWER_MAIN_AGENT_ONLY } from '../support'; -import DESCRIPTION from './teardown.md?raw'; -import { - ITowerTeardownTool, - TowerTeardownToolInputSchema, - type TowerTeardownToolInput, -} from './teardown'; - -export class TowerTeardownTool implements ITowerTeardownTool { - declare readonly _serviceBrand: undefined; - readonly name = 'TowerTeardown' as const; - readonly description: string = DESCRIPTION; - readonly parameters: Record<string, unknown> = toInputJsonSchema(TowerTeardownToolInputSchema); - - constructor( - @ISessionContext private readonly sessionContext: ISessionContext, - @IAgentTowerService private readonly tower: IAgentTowerService, - @ISessionManager private readonly sessions: ISessionManager, - @IAgentScopeContext private readonly scopeContext: IAgentScopeContext, - ) {} - - resolveExecution(args: TowerTeardownToolInput): ToolExecution { - if (this.scopeContext.agentId !== MAIN_AGENT_ID) { - return { - isError: true, - output: TOWER_MAIN_AGENT_ONLY, - }; - } - return { - description: `Tearing down tower workspace${args.force === true ? ' (force)' : ''}`, - approvalRule: this.name, - execute: () => - runTowerTool(async () => { - const store = newTowerStore(this.sessionContext); - const priorOwner = await store.load().then( - (state) => state.sessionId, - () => undefined, - ); - if ( - priorOwner !== undefined && - priorOwner !== this.sessionContext.sessionId && - this.sessions.get(priorOwner) !== undefined - ) { - throw new TowerProtocolError( - `tower workspace is owned by a live session (${priorOwner}) — tearing it down would dismantle that session's fleet. Use TowerTeardown from that session, or close it first.`, - ); - } - const report = await store.teardown({ force: args.force }); - this.tower.exit(); - return { - output: [ - 'tower teardown:', - ...report.map((line) => `- ${line}`), - '', - 'Tower mode exited. .tower/comms/ (state, inbox, findings, reviews, activity log) is kept as the audit trail — remove it by hand only if you are sure.', - ].join('\n'), - }; - }), - }; - } -} diff --git a/packages/agent-core-v2/src/features/tower/tower-worker-overlay.md b/packages/agent-core-v2/src/features/tower/tower-worker-overlay.md deleted file mode 100644 index 9f3a0c8bd..000000000 --- a/packages/agent-core-v2/src/features/tower/tower-worker-overlay.md +++ /dev/null @@ -1 +0,0 @@ -You are a tower worker/reviewer in a multi-agent tower workspace. All collaboration protocol traffic (inbox messages, findings, reviews, mission updates) goes through the Tower* tools ONLY — never create, edit, or delete any file under `.tower/` by hand; the tools are the only writers, and hand-written protocol files break the merge gate. Your TowerSpawn briefing names your mission (worker) or review target (reviewer) — stay inside it. diff --git a/packages/agent-core-v2/src/features/tower/tower.ts b/packages/agent-core-v2/src/features/tower/tower.ts deleted file mode 100644 index 97a4bb2e8..000000000 --- a/packages/agent-core-v2/src/features/tower/tower.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createDecorator } from "#/_base/di/instantiation"; - -export const TOWER_TOOL_NAMES = [ - 'TowerPlan', - 'TowerSpawn', - 'TowerMerge', - 'TowerTeardown', - 'TowerSend', - 'TowerInbox', - 'TowerFinding', - 'TowerReview', - 'TowerMission', - 'TowerStatus', -] as const; - -export const TOWER_WORKER_PROFILE = 'tower-worker'; - -export const TOWER_FLAG_ID = 'tower'; - -export interface IAgentTowerService { - readonly _serviceBrand: undefined; - - readonly isActive: boolean; - enter(): Promise<void>; - exit(): void; -} - -export const IAgentTowerService = createDecorator<IAgentTowerService>('agentTowerService'); diff --git a/packages/agent-core-v2/src/features/tower/towerFeature.ts b/packages/agent-core-v2/src/features/tower/towerFeature.ts deleted file mode 100644 index e2007519c..000000000 --- a/packages/agent-core-v2/src/features/tower/towerFeature.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { ScopeActivation } from '#/_base/di/instantiation'; -import type { ServiceIdentifier } from '#/_base/di/instantiation'; -import type { - AgentToolCtor, - AnyAgentTool, -} from '#/agent/toolRegistry/toolContribution'; -import { IFlagService } from '#/app/flag/flag'; -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; - -import { TOWER_FLAG_ID } from './tower'; -import { ITowerRateLimitService } from './towerRateLimit'; -import { TowerRateLimitService } from './towerRateLimitService'; -import { ITowerFindingTool } from './tools/finding/finding'; -import { TowerFindingTool } from './tools/finding/findingTool'; -import { ITowerInboxTool } from './tools/inbox/inbox'; -import { TowerInboxTool } from './tools/inbox/inboxTool'; -import { ITowerInitTool } from './tools/init/init'; -import { TowerInitTool } from './tools/init/initTool'; -import { ITowerMergeTool } from './tools/merge/merge'; -import { TowerMergeTool } from './tools/merge/mergeTool'; -import { ITowerMissionTool } from './tools/mission/mission'; -import { TowerMissionTool } from './tools/mission/missionTool'; -import { ITowerPlanTool } from './tools/plan/plan'; -import { TowerPlanTool } from './tools/plan/planTool'; -import { ITowerReviewTool } from './tools/review/review'; -import { TowerReviewTool } from './tools/review/reviewTool'; -import { ITowerSendTool } from './tools/send/send'; -import { TowerSendTool } from './tools/send/sendTool'; -import { ITowerSpawnTool } from './tools/spawn/spawn'; -import { TowerSpawnTool } from './tools/spawn/spawnTool'; -import { ITowerStatusTool } from './tools/status/status'; -import { TowerStatusTool } from './tools/status/statusTool'; -import { ITowerTeardownTool } from './tools/teardown/teardown'; -import { TowerTeardownTool } from './tools/teardown/teardownTool'; -import { TOWER_WORKER_PROFILE_DEF } from './workerProfile'; - -interface TowerToolContribution { - readonly id: ServiceIdentifier<AnyAgentTool>; - readonly ctor: AgentToolCtor; - readonly name: string; -} - -export const TOWER_TOOL_CONTRIBUTIONS: readonly TowerToolContribution[] = [ - { id: ITowerInitTool, ctor: TowerInitTool, name: 'TowerInit' }, - { id: ITowerPlanTool, ctor: TowerPlanTool, name: 'TowerPlan' }, - { id: ITowerSpawnTool, ctor: TowerSpawnTool, name: 'TowerSpawn' }, - { id: ITowerMergeTool, ctor: TowerMergeTool, name: 'TowerMerge' }, - { id: ITowerTeardownTool, ctor: TowerTeardownTool, name: 'TowerTeardown' }, - { id: ITowerSendTool, ctor: TowerSendTool, name: 'TowerSend' }, - { id: ITowerInboxTool, ctor: TowerInboxTool, name: 'TowerInbox' }, - { id: ITowerFindingTool, ctor: TowerFindingTool, name: 'TowerFinding' }, - { id: ITowerReviewTool, ctor: TowerReviewTool, name: 'TowerReview' }, - { id: ITowerMissionTool, ctor: TowerMissionTool, name: 'TowerMission' }, - { id: ITowerStatusTool, ctor: TowerStatusTool, name: 'TowerStatus' }, -]; - -export class TowerFeature extends Feature { - static override readonly name = 'tower'; - - constructor(@IFlagService flags: IFlagService) { - super(); - if (!flags.enabled(TOWER_FLAG_ID)) return; - assembledFlagServices.add(flags); - this.onDispose(() => { - assembledFlagServices.delete(flags); - }); - this.contributeService(LifecycleScope.App, ITowerRateLimitService, TowerRateLimitService, { - activation: ScopeActivation.OnDemand, - }); - for (const tool of TOWER_TOOL_CONTRIBUTIONS) { - this.contributeTool(tool.id, tool.ctor, { - name: tool.name, - domain: 'tower', - }); - } - this.contributeProfiles([TOWER_WORKER_PROFILE_DEF]); - } -} - -const assembledFlagServices = new WeakSet<IFlagService>(); -let assembledOverrideForTests: boolean | undefined; - -export function isTowerFeatureAssembled(flags: IFlagService): boolean { - return assembledOverrideForTests ?? assembledFlagServices.has(flags); -} - -export function _setTowerFeatureAssembledForTests(value: boolean | undefined): void { - assembledOverrideForTests = value; -} - -registerFeature(TowerFeature); diff --git a/packages/agent-core-v2/src/features/tower/towerOps.ts b/packages/agent-core-v2/src/features/tower/towerOps.ts deleted file mode 100644 index 3d56c5c5d..000000000 --- a/packages/agent-core-v2/src/features/tower/towerOps.ts +++ /dev/null @@ -1,48 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { z } from 'zod'; - -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { AgentEvent2 } from '#/app/event/event2'; -import { defineState } from '#/state/state'; - -const towerModeEnterSchema = z.object({ agentId: z.string(), sessionId: z.string().optional() }); - -export class TowerModeEnter extends AgentEvent2<z.infer<typeof towerModeEnterSchema>> { - static override readonly type = 'tower_mode.enter'; - static override readonly durable = true; - static override readonly schema = towerModeEnterSchema; -} -export interface TowerModeEnter { - readonly agentId: string; - readonly sessionId?: string; -} - -const towerModeExitSchema = z.object({ agentId: z.string() }); - -export class TowerModeExit extends AgentEvent2<z.infer<typeof towerModeExitSchema>> { - static override readonly type = 'tower_mode.exit'; - static override readonly durable = true; - static override readonly schema = towerModeExitSchema; -} -export interface TowerModeExit { - readonly agentId: string; -} - -export const towerKey = defineState('tower', () => false).replayable({ - schema: z.boolean(), -}) - .on(TowerModeEnter, (_s, e, ctx) => { - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, towerMode: true })); - return true; - }) - .on(TowerModeExit, (_s, e, ctx) => { - ctx.emit(new AgentStatusUpdated({ agentId: e.agentId, towerMode: false })); - return false; - }); - -export const towerOwnerKey = defineState('tower.owner', () => undefined as string | undefined) - .replayable({ - schema: z.string().optional(), - }) - .on(TowerModeEnter, (_s, e) => e.sessionId) - .on(TowerModeExit, () => undefined); diff --git a/packages/agent-core-v2/src/features/tower/towerRateLimit.ts b/packages/agent-core-v2/src/features/tower/towerRateLimit.ts deleted file mode 100644 index aa2297419..000000000 --- a/packages/agent-core-v2/src/features/tower/towerRateLimit.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; - -export interface TowerRateLimitSnapshot { - readonly budget: number; - readonly inflight: number; - readonly blockedUntil: number | null; -} - -export interface ITowerRateLimitService { - readonly _serviceBrand: undefined; - - reportRateLimited(): void; - reportSuccess(): void; - budget(): number; - acquire(): { readonly ok: true } | { readonly ok: false; readonly reason: string }; - release(): void; - snapshot(): TowerRateLimitSnapshot; - reset(): void; -} - -export const ITowerRateLimitService = - createDecorator<ITowerRateLimitService>('towerRateLimitService'); diff --git a/packages/agent-core-v2/src/features/tower/towerRateLimitService.ts b/packages/agent-core-v2/src/features/tower/towerRateLimitService.ts deleted file mode 100644 index ec2159458..000000000 --- a/packages/agent-core-v2/src/features/tower/towerRateLimitService.ts +++ /dev/null @@ -1,146 +0,0 @@ -import { Disposable } from '#/_base/di/lifecycle'; -import { - ITowerRateLimitService, - type TowerRateLimitSnapshot, -} from './towerRateLimit'; - -export const RATE_LIMIT_CAPACITY_SHRINK_INTERVAL_MS = 2_000; -export const RATE_LIMIT_CAPACITY_RECOVERY_INTERVAL_MS = 180_000; -export const TOWER_SPAWN_PAUSE_MS = 60_000; -export const TOWER_MAX_BUDGET = 16; - -export class RateLimitCapacityGovernor { - private capacity = Number.POSITIVE_INFINITY; - private lastRateLimitAt: number | undefined; - private lastShrinkAt: number | undefined; - private lastRecoveryAt: number | undefined; - - constructor(private readonly now: () => number = Date.now) {} - - getCapacity(): number { - return this.capacity; - } - - get inBackoff(): boolean { - return this.lastRateLimitAt !== undefined; - } - - get lastRateLimitedAt(): number | undefined { - return this.lastRateLimitAt; - } - - noteRateLimited(activeCount: number): void { - const now = this.now(); - if (activeCount > 0) { - if (this.capacity === Number.POSITIVE_INFINITY) { - this.capacity = Math.max(1, activeCount - 1); - this.lastShrinkAt = now; - } else if ( - this.lastShrinkAt === undefined || - now - this.lastShrinkAt >= RATE_LIMIT_CAPACITY_SHRINK_INTERVAL_MS - ) { - this.capacity = Math.max(1, this.capacity - 1); - this.lastShrinkAt = now; - } - } - this.lastRateLimitAt = now; - } - - maybeRecover(): boolean { - const now = this.now(); - if (this.nextRecoveryAt() > now) return false; - this.capacity += 1; - this.lastRecoveryAt = now; - return true; - } - - nextRecoveryAt(): number { - if (this.lastRateLimitAt === undefined) return Number.POSITIVE_INFINITY; - return ( - Math.max(this.lastRateLimitAt, this.lastRecoveryAt ?? 0) + - RATE_LIMIT_CAPACITY_RECOVERY_INTERVAL_MS - ); - } - - reset(): void { - this.capacity = Number.POSITIVE_INFINITY; - this.lastRateLimitAt = undefined; - this.lastShrinkAt = undefined; - this.lastRecoveryAt = undefined; - } -} - -export class TowerRateLimitService extends Disposable implements ITowerRateLimitService { - declare readonly _serviceBrand: undefined; - - private readonly governor: RateLimitCapacityGovernor; - private readonly now: () => number; - private inflight = 0; - private blockedUntil: number | null = null; - - constructor(now: () => number = Date.now) { - super(); - this.now = now; - this.governor = new RateLimitCapacityGovernor(this.now); - } - - reportRateLimited(): void { - this.governor.noteRateLimited(this.inflight); - this.blockedUntil = this.now() + TOWER_SPAWN_PAUSE_MS; - } - - reportSuccess(): void { - this.blockedUntil = null; - this.governor.maybeRecover(); - } - - budget(): number { - this.governor.maybeRecover(); - return Math.max(1, Math.min(TOWER_MAX_BUDGET, this.governor.getCapacity())); - } - - acquire(): { readonly ok: true } | { readonly ok: false; readonly reason: string } { - const now = this.now(); - if (this.blockedUntil !== null) { - if (now < this.blockedUntil) { - const retryAfterS = Math.ceil((this.blockedUntil - now) / 1000); - return { - ok: false, - reason: - `provider rate limit hit — new tower spawns paused for ~${String(retryAfterS)}s. ` + - 'Successful requests lift the pause early; wait and retry, or let running agents finish first.', - }; - } - this.blockedUntil = null; - } - const budget = this.budget(); - if (this.inflight >= budget) { - return { - ok: false, - reason: - `tower concurrency budget exhausted (${String(this.inflight)}/${String(budget)} agents running). ` + - 'Wait for a running agent to complete, then retry.', - }; - } - this.inflight += 1; - return { ok: true }; - } - - release(): void { - this.inflight = Math.max(0, this.inflight - 1); - } - - snapshot(): TowerRateLimitSnapshot { - return { - budget: this.budget(), - inflight: this.inflight, - blockedUntil: this.blockedUntil, - }; - } - - reset(): void { - this.governor.reset(); - this.inflight = 0; - this.blockedUntil = null; - } -} diff --git a/packages/agent-core-v2/src/features/tower/towerService.ts b/packages/agent-core-v2/src/features/tower/towerService.ts deleted file mode 100644 index f0428cd6e..000000000 --- a/packages/agent-core-v2/src/features/tower/towerService.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { join } from 'node:path'; - -import { Disposable } from '#/_base/di/lifecycle'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { activateReminderWhenReady } from '#/features/reminder/internal/reminderActivation'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { IAgentProfileService } from '#/agent/profile/profile'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IAgentToolApprovalService } from '#/agent/toolApproval/toolApproval'; -import { denyToolExecution } from '#/agent/toolExecutor/beforeToolExecuteEvent'; -import { IAgentToolExecutorService } from '#/agent/toolExecutor/toolExecutor'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { IConfigService } from '#/app/config/config'; -import { IEventBus } from '#/app/event/eventBus'; -import { IFeatureManager } from '#/app/feature/featureManager'; -import { LifecycleScope } from '#/app/scopes'; -import { IFlagService } from '#/app/flag/flag'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { isWithinDirectory } from '#/tool/path-access'; -import type { ToolFileAccess } from '#/tool/toolContract'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { TowerModeInjection } from './injection/towerModeInjection'; -import { - TowerStore, - WORKTREES_DIR, - resolveTowerRepoRoot, -} from './protocol/index'; -import { - IAgentTowerService, - TOWER_FLAG_ID, - TOWER_TOOL_NAMES, - TOWER_WORKER_PROFILE, -} from './tower'; -import { isTowerFeatureAssembled } from './towerFeature'; -import { TowerModeEnter, TowerModeExit, towerKey, towerOwnerKey } from './towerOps'; - -export const TOWER_MODE_TOOLS: readonly string[] = ['TowerInit', ...TOWER_TOOL_NAMES]; - -export class AgentTowerService extends Disposable implements IAgentTowerService { - declare readonly _serviceBrand: undefined; - - constructor( - @IEventDispatcher private readonly dispatcher: IEventDispatcher, - @IAgentStateService private readonly agentState: IAgentStateService, - @IAgentToolApprovalService private readonly toolApproval: IAgentToolApprovalService, - @IAgentToolExecutorService toolExecutor: IAgentToolExecutorService, - @IAgentProfileService private readonly profile: IAgentProfileService, - @IAgentScopeContext private readonly agentCtx: IAgentScopeContext, - @ISessionContext private readonly sessionCtx: ISessionContext, - @IFlagService private readonly flags: IFlagService, - @ISessionManager private readonly sessions: ISessionManager, - @IFeatureManager featureManager: IFeatureManager, - @IConfigService config: IConfigService, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - @IAgentContextMemoryService context: IAgentContextMemoryService, - @IEventBus eventBus: IEventBus, - ) { - super(); - this.agentState.contributeState(towerKey); - this.agentState.contributeState(towerOwnerKey); - this._register( - this.dispatcher.hooks.onDidRestore.register('tower', async (_ctx, next) => { - await this.exitForeignTower(); - this.restoreTowerTools(); - this.reconcileTowerProjection(); - await next(); - }), - ); - if (featureManager !== undefined) { - this._register( - featureManager.onDidChangeUnits(() => { - this.reconcileTowerProjection(); - }), - ); - } - if (config !== undefined) { - this._register( - config.onDidChangeConfiguration(() => { - this.reconcileTowerProjection(); - }), - ); - } - this._register( - eventBus.subscribe(AgentStatusUpdated, () => { - if (this.agentCtx.agentId !== 'main') return; - if (!this.isActive) return; - const active = this.profile.getActiveToolNames(); - if (active === undefined) return; - if (TOWER_MODE_TOOLS.every((name) => active.includes(name))) return; - for (const name of TOWER_MODE_TOOLS) this.profile.addActiveTool(name); - void this.dispatcher.dispatch( - new AgentStatusUpdated({ agentId: this.agentCtx.agentId, towerMode: true }), - ); - }), - ); - this._register( - activateReminderWhenReady(agentLifecycle, this.agentCtx, (reminder) => - new TowerModeInjection(reminder, this, context, this.flags), - ), - ); - this._register( - toolExecutor.onBeforeExecuteTool((event) => { - if (this.flags.enabled(TOWER_FLAG_ID)) return; - if (!TOWER_MODE_TOOLS.includes(event.toolCall.name)) return; - event.veto( - denyToolExecution( - this.toolApproval.formatDenyMessage( - 'The tower experiment is disabled — tower tools are inert. Re-enable the experiment (a restart is required if it was just turned on) before driving the tower protocol.', - ), - ), - ); - }), - ); - this._register( - toolExecutor.onBeforeExecuteTool((event) => { - if (!this.flags.enabled(TOWER_FLAG_ID)) return; - if (!this.isActive) return; - if (event.toolCall.name !== 'TodoList') return; - event.veto( - denyToolExecution( - this.toolApproval.formatDenyMessage( - 'TodoList is not available while tower mode is active — mission state lives in the tower protocol (TowerPlan/TowerMission/TowerStatus, MISSIONS.md), and todo semantics would serialize the fleet. Spawn every dependency-unblocked mission now, then end your turn: worker completions wake you.', - ), - ), - ); - }), - ); - this._register( - toolExecutor.onBeforeExecuteTool(async (event) => { - if (this.profile.data().profileName !== TOWER_WORKER_PROFILE) return; - const toolName = event.toolCall.name; - if (toolName !== 'Write' && toolName !== 'Edit') return; - - const store = new TowerStore(resolveTowerRepoRoot(this.sessionCtx.cwd)); - const entry = await store - .load() - .then( - (state) => - state.roster.agents.find((agent) => agent.agentId === this.agentCtx.agentId), - () => undefined, - ); - const slot = entry?.worktree; - if (slot === undefined) return; - const worktree = store.abs(join(WORKTREES_DIR, slot)); - - const escapes = (event.execution.accesses ?? []) - .filter( - (access): access is ToolFileAccess => - access.kind === 'file' && - (access.operation === 'write' || access.operation === 'readwrite'), - ) - .filter((access) => !isWithinDirectory(access.path, worktree)); - if (escapes.length === 0) return; - event.veto( - denyToolExecution( - this.toolApproval.formatDenyMessage( - `tower workers may only write inside their own worktree (${worktree}) — denied: ` + - `${escapes.map((access) => access.path).join(', ')}. ` + - 'Out-of-scope changes are not yours to make: file them with TowerFinding or ask the tower via TowerSend.', - ), - ), - ); - }), - ); - } - - async enter(): Promise<void> { - if (this.agentCtx.agentId !== 'main') return; - if (!this.flags.enabled(TOWER_FLAG_ID)) return; - if (!isTowerFeatureAssembled(this.flags)) return; - if (this.isActive) return; - const owner = await this.resolveTowerOwner(); - if ( - owner !== undefined && - owner !== this.sessionCtx.sessionId && - this.sessions.get(owner) !== undefined - ) { - return; - } - for (const name of TOWER_MODE_TOOLS) this.profile.addActiveTool(name); - this.lastPublished = true; - void this.dispatcher.dispatch( - new TowerModeEnter({ agentId: this.agentCtx.agentId, sessionId: this.sessionCtx.sessionId }), - ); - } - - exit(): void { - if (!this.agentState.get(towerKey)) return; - this.lastPublished = false; - void this.dispatcher.dispatch(new TowerModeExit({ agentId: this.agentCtx.agentId })); - } - - get isActive(): boolean { - return ( - this.agentCtx.agentId === 'main' && - this.flags.enabled(TOWER_FLAG_ID) && - isTowerFeatureAssembled(this.flags) && - this.agentState.get(towerKey) - ); - } - - private async exitForeignTower(): Promise<void> { - if (this.agentCtx.agentId !== 'main') return; - if (!this.agentState.get(towerKey)) return; - const owner = await this.resolveTowerOwner(); - if (owner === undefined || owner === this.sessionCtx.sessionId) return; - if (this.sessions.get(owner) === undefined) return; - void this.dispatcher.dispatch(new TowerModeExit({ agentId: this.agentCtx.agentId })); - } - - private async resolveTowerOwner(): Promise<string | undefined> { - const store = new TowerStore(resolveTowerRepoRoot(this.sessionCtx.cwd)); - const storeOwner = await store.load().then( - (state) => state.sessionId, - () => undefined, - ); - return storeOwner ?? this.agentState.get(towerOwnerKey); - } - - private restoreTowerTools(): void { - if (!this.flags.enabled(TOWER_FLAG_ID)) return; - if (!this.isActive) return; - if (this.agentCtx.agentId !== 'main') return; - for (const name of TOWER_MODE_TOOLS) this.profile.addActiveTool(name); - this.lastPublished = true; - void this.dispatcher.dispatch(new AgentStatusUpdated({ agentId: this.agentCtx.agentId, towerMode: true })); - } - - private lastPublished: boolean | undefined; - - private reconcileTowerProjection(): void { - if (this.agentCtx.agentId !== 'main') return; - if (!this.agentState.get(towerKey)) { - this.lastPublished = false; - return; - } - const effective = this.isActive; - if (this.lastPublished === effective) return; - this.lastPublished = effective; - void this.dispatcher.dispatch( - new AgentStatusUpdated({ agentId: this.agentCtx.agentId, towerMode: effective }), - ); - } -} - -registerScopedService( - LifecycleScope.Agent, - IAgentTowerService, - AgentTowerService, - ScopeActivation.OnScopeCreated, - 'tower', -); diff --git a/packages/agent-core-v2/src/features/tower/workerProfile.ts b/packages/agent-core-v2/src/features/tower/workerProfile.ts deleted file mode 100644 index d5e35bb69..000000000 --- a/packages/agent-core-v2/src/features/tower/workerProfile.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { - normalizeAgentProfile, - type AgentProfile, -} from '#/app/agentProfileCatalog/agentProfileCatalog'; -import { - renderSystemPromptResult, - skillActiveFor, - TASK_AGENT_ROLE_PREFIX, -} from '#/app/agentProfileCatalog/profile-shared'; -import SUMMARY_CONTINUATION_PROMPT from '../../session/agentLifecycle/profile/summary-continuation.md?raw'; - -import { TOWER_WORKER_PROFILE } from './tower'; -import TOWER_WORKER_ROLE_OVERLAY from './tower-worker-overlay.md?raw'; - -const TOWER_WORKER_TOOLS = [ - 'Agent', - 'Bash', - 'TowerFinding', - 'TowerInbox', - 'TowerMission', - 'TowerReview', - 'TowerSend', - 'TowerStatus', - 'CronCreate', - 'CronDelete', - 'CronList', - 'Edit', - 'EnterPlanMode', - 'ExitPlanMode', - 'Glob', - 'Grep', - 'Read', - 'ReadMediaFile', - 'Skill', - 'TaskList', - 'TaskOutput', - 'TaskStop', - 'TodoList', - 'WaitFor', - 'WebSearch', - 'FetchURL', - 'Write', - 'mcp__*', -] as const; - -const CODER_ROLE = - `${TASK_AGENT_ROLE_PREFIX}\n\n` + - 'Your final message is the entire handoff — the parent sees nothing else from your run. ' + - 'Make it technically complete: what you changed and why, the path of every file you touched, ' + - 'how you verified the change (tests or commands run, with results), and anything left undone ' + - 'or worth follow-up. A final message of only a sentence or two is treated as too brief and ' + - 'sent back to you for expansion, costing an extra turn.'; - -const TOWER_WORKER_ROLE = `${CODER_ROLE}\n\n${TOWER_WORKER_ROLE_OVERLAY.trim()}`; - -const DEFAULT_SUMMARY_POLICY = { - minChars: 200, - continuationPrompt: SUMMARY_CONTINUATION_PROMPT, - retries: 1, -} as const; - -export const TOWER_WORKER_PROFILE_DEF: AgentProfile = normalizeAgentProfile({ - name: TOWER_WORKER_PROFILE, - description: - 'Tower worker/reviewer agent — executes one tower mission in its own git worktree (or reviews one branch), coordinating only through Tower* tools. Spawned via the TowerSpawn tool.', - whenToUse: - 'Use this agent for non-trivial software engineering work that may require reading files, editing code, running commands, and returning a compact but technically complete summary to the parent agent.', - tools: TOWER_WORKER_TOOLS, - subagents: ['explore', 'plan'], - renderSystemPrompt: (context) => - renderSystemPromptResult(TOWER_WORKER_ROLE, context, { - skillActive: skillActiveFor(TOWER_WORKER_TOOLS), - }), - summaryPolicy: DEFAULT_SUMMARY_POLICY, -}); diff --git a/packages/agent-core-v2/src/features/usage/usageFeature.ts b/packages/agent-core-v2/src/features/usage/usageFeature.ts deleted file mode 100644 index d22046eac..000000000 --- a/packages/agent-core-v2/src/features/usage/usageFeature.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { Feature } from '#/features/feature'; -import { registerFeature } from '#/features/featureRegistry'; -import { ISessionUsageService } from '#/session/usage/sessionUsage'; -import { SessionUsageService } from '#/session/usage/sessionUsageService'; -import { UsageAgentModelDefinition } from '#/session/usage/usageAgentModel'; - -export class UsageFeature extends Feature { - static override readonly name = 'usage'; - - constructor() { - super(); - this.contributeAgentModel(UsageAgentModelDefinition); - this.contributeService(LifecycleScope.Session, ISessionUsageService, SessionUsageService); - } -} - -registerFeature(UsageFeature); diff --git a/packages/agent-core-v2/src/hooks.ts b/packages/agent-core-v2/src/hooks.ts index 77e1202aa..dd97aede1 100644 --- a/packages/agent-core-v2/src/hooks.ts +++ b/packages/agent-core-v2/src/hooks.ts @@ -1,3 +1,9 @@ +/** + * `hooks` domain (cross-cutting) — ordered chain-of-responsibility hook slots. + * + * Provides typed extension points with repeatable chaining and isolated context + * forks. Bound as utility infrastructure, not a scoped Service. + */ import { toDisposable, type IDisposable } from "#/_base/di/lifecycle"; import { BugIndicatingError } from "#/errors"; diff --git a/packages/agent-core-v2/src/index.ts b/packages/agent-core-v2/src/index.ts index 48a14a09a..e41a76d8f 100644 --- a/packages/agent-core-v2/src/index.ts +++ b/packages/agent-core-v2/src/index.ts @@ -1,3 +1,8 @@ +/** + * agent-core-v2 public surface — re-exports every domain barrel (grouped by + * layer) so importing the package loads all scoped-registry registrations. + */ + export * from '#/_base/di/descriptors'; export * from '#/_base/di/errors'; export * from '#/_base/di/graph'; @@ -33,22 +38,6 @@ export { } from '#/_base/di/fiber'; export { Service } from '#/_base/di/service'; export * from './errors'; -export * from '#/runtime/runtime'; -export * from '#/runtime/runtimeRegistry'; -export * from '#/runtime/runtimeWorkspaceView'; -export * from '#/runtime/runtimeProvider'; -export * from '#/runtime/runtimeUnitHost'; -export * from '#/runtime/localRuntime'; -export * from '#/runtime/standaloneRuntime'; -export * from '#/program/program'; -export * from '#/workspace/workspaceInstance/workspaceInstance'; -export * from '#/workspace/workspaceInstance/workspaceInstanceManager'; -export * from '#/workspace/workspaceInstance/workspaceInstanceManagerService'; -export * from '#/agent/runtimeBinding/runtimeBinding'; -export * from '#/agent/runtimeBinding/runtimeBindingService'; -export * from '#/agent/runtimeBinding/agentRuntime'; -export * from '#/app/sessionManager/sessionManager'; -export * from '#/app/sessionManager/sessionManagerService'; export * from '#/_base/log/log'; export * from '#/_base/log/logConfig'; @@ -57,6 +46,7 @@ export * from '#/_base/log/fileLog'; export * from '#/_base/log/logService'; export * from '#/wire/wire'; export * from '#/wire/wireService'; +export * from '#/wire/wireContribution'; export * from '#/wire/record'; export * from '#/wire/migration/migration'; export * from '#/session/sessionLog/sessionLogService'; @@ -102,31 +92,8 @@ export { TaskService } from '#/app/task/taskService'; import '#/app/event/eventBusService'; import '#/app/event/eventService'; import '#/app/event/fiberEventResolver'; -export { IEventBus } from '#/app/event/eventBus'; -export { IEventService } from '#/app/event/event'; -export * from '#/app/event/errors'; -export * from '#/app/event/event2'; -export * from '#/state/errors'; -export * from '#/state/state'; -export * from '#/state/stateContribution'; -export * from '#/state/agentModel'; -export { - AgentRuntimeContributionPoint, - AgentRuntimeOverrideContributionPoint, - defineAgentRuntimeContract, - defineAgentRuntimeProvider, -} from '#/agent/runtime/agentRuntime'; -export type { - AgentRuntimeContributionSnapshot, - AgentRuntimeDefinition, - AgentRuntimeIdentity, - AgentRuntimeProvider, - AgentRuntimeSnapshot, - AgentRuntimeStatus, - RuntimeOf, -} from '#/agent/runtime/agentRuntime'; -export * from '#/state/eventDispatcher'; -import '#/state/eventDispatcherService'; +export { IEventBus, type DomainEvent } from '#/app/event/eventBus'; +export { IEventService, type DomainEvent as GlobalEvent } from '#/app/event/event'; export * from '#/_base/state/stateRegistry'; export * from '#/_base/contribution/registry'; export * from '#/app/state/appState'; @@ -157,20 +124,13 @@ export * from '#/app/sessionIndex/sessionIndexService'; export * from '#/app/sessionIndex/sessionIndexMirrorService'; export * from '#/session/sessionMetadata/sessionMetadata'; export * from '#/session/sessionMetadata/sessionMetadataService'; -export * from '#/session/sessionMetadata/promptMetadata'; export * from '#/session/sessionActivity/sessionActivity'; export * from '#/session/sessionActivity/sessionActivityService'; export * from '#/session/sessionActivity/sessionOutcomeMirror'; export * from '#/session/sessionActivity/sessionOutcomeMirrorService'; -export * from '#/session/sessionTitle/agentTitlePromptSource'; -import '#/session/sessionTitle/agentTitlePromptSourceService'; -export * from '#/session/sessionTitle/sessionTitle'; -export * from '#/session/sessionTitle/sessionTitleService'; -import '#/session/sessionTitle/flag'; export * from '#/session/sessionToolPolicy/sessionToolPolicy'; export * from '#/session/sessionToolPolicy/sessionToolPolicyService'; export * from '#/app/config/config'; -export * from '#/app/config/configEvents'; export * from '#/app/config/configService'; export * from '#/app/config/configSectionContributions'; import '#/app/kosongConfig/configSection'; @@ -178,8 +138,7 @@ export * from '#/kosong/provider/provider'; export * from '#/kosong/provider/providerService'; export * from '#/kosong/provider/providerDefinition'; export * from '#/kosong/provider/protocolAdapterRegistry'; -import '#/features/skill/catalog/configSection'; -import '#/app/remoteControl/flag'; +import '#/app/skillCatalog/configSection'; import '#/app/agentIdentity/configSection'; export * from '#/app/agentIdentity/configSection'; export * from '#/app/agentIdentity/agentIdentity'; @@ -190,6 +149,7 @@ export * from '#/kosong/protocol/protocol'; export * from '#/kosong/protocol/protocolBase'; export * from '#/kosong/protocol/protocolTrait'; import '#/app/kosongConfig/envOverlay'; +import '#/app/kosongConfig/secondaryModelOverlay'; export * from '#/kosong/model/completionBudget'; export * from '#/kosong/model/hostRequestHeaders'; export * from '#/kosong/model/model'; @@ -205,6 +165,12 @@ export { ModelCatalogConfigSchema, type ModelCatalogConfig, } from '#/app/kosongConfig/configSection'; +export type { SecondaryModelConfig } from '#/app/kosongConfig/configSection'; +export { + SECONDARY_DERIVED_MODEL_ID, + secondaryModelOverlay, + secondaryModelPatch, +} from '#/app/kosongConfig/secondaryModelOverlay'; export * from '#/app/kosongConfig/kosongConfig'; export * from '#/app/kosongConfig/kosongConfigService'; export * from '#/kosong/model/modelOAuth'; @@ -248,17 +214,13 @@ export * from '#/app/plugin/source'; export * from '#/app/plugin/github-resolver'; export * from '#/app/plugin/archive'; export * from '#/app/plugin/manager'; -export * from '#/app/plugin/marketplace'; export * from '#/app/plugin/plugin'; -export * from '#/app/plugin/pluginEvents'; export * from '#/app/plugin/pluginService'; export * from '#/app/capability/capability'; -export * from '#/app/capability/capabilityEvents'; export * from '#/app/capability/capabilityService'; export * from '#/app/capability/errors'; export * from '#/app/capability/types'; export * from '#/app/feature/featureManager'; -export * from '#/app/feature/featureServiceContribution'; import '#/app/feature/featureManagerService'; export * from '#/features/feature'; export * from '#/features/featureAssembly'; @@ -271,26 +233,26 @@ export * from '#/debug/index'; export * from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader'; export * from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService'; -export type { SkillSource } from '#/features/skill/catalog/types'; -export * from '#/features/skill/tools/skill'; -export * from '#/features/skill/skill'; -export * from '#/features/skill/skillAgentRuntime'; -import '#/features/skill/skillFeature'; -export * from '#/features/skill/catalog/types'; -export * from '#/features/skill/catalog/configSection'; -export * from '#/features/skill/catalog/parser'; -export * from '#/features/skill/catalog/registry'; -export * from '#/features/skill/catalog/errors'; -export * from '#/features/skill/catalog/skillDiscovery'; -export * from '#/features/skill/catalog/inMemorySkillDiscovery'; -export * from '#/features/skill/catalog/skillSource'; -export * from '#/features/skill/catalog/skillRoots'; -export * from '#/features/skill/catalog/builtin/builtin'; -export * from '#/features/skill/catalog/builtinSkillSource'; -export * from '#/features/skill/catalog/userFileSkillSource'; -export * from '#/features/skill/session/skillCatalog'; -export * from '#/features/skill/session/skillCatalogData'; -export * from '#/features/skill/session/skillCatalogService'; +export type { SkillSource } from '#/app/skillCatalog/types'; +export * from '#/agent/tools/skill/skill'; +import '#/agent/tools/skill/skillTool'; +export * from '#/agent/skill/skill'; +export * from '#/agent/skill/skillService'; +export * from '#/app/skillCatalog/types'; +export * from '#/app/skillCatalog/configSection'; +export * from '#/app/skillCatalog/parser'; +export * from '#/app/skillCatalog/registry'; +export * from '#/app/skillCatalog/errors'; +export * from '#/app/skillCatalog/skillDiscovery'; +export * from '#/app/skillCatalog/inMemorySkillDiscovery'; +export * from '#/app/skillCatalog/skillSource'; +export * from '#/app/skillCatalog/skillRoots'; +export * from '#/app/skillCatalog/builtin/builtin'; +export * from '#/app/skillCatalog/builtinSkillSource'; +export * from '#/app/skillCatalog/userFileSkillSource'; +export * from '#/session/sessionSkillCatalog/skillCatalog'; +export * from '#/session/sessionSkillCatalog/skillCatalogData'; +export * from '#/session/sessionSkillCatalog/skillCatalogService'; export * from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; export * from '#/session/sessionAgentProfileCatalog/agentProfileCatalogSeed'; export * from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalogService'; @@ -298,12 +260,12 @@ export * from '#/session/sessionInstructions/instructionsProvider'; export * from '#/session/workspaceInfo/workspaceInfo'; export * from '#/workspace/workspaceDirs/workspaceDirs'; export * from '#/workspace/workspaceDirs/workspaceDirsService'; -export * from '#/features/skill/workspace/workspaceSkillCatalog'; -export * from '#/features/skill/workspace/workspaceSkillCatalogService'; -export * from '#/features/skill/workspace/extraFileSkillSource'; -export * from '#/features/skill/workspace/explicitFileSkillSource'; -export * from '#/features/skill/workspace/rootFileSkillSource'; -export * from '#/features/skill/workspace/pluginSkillSource'; +export * from '#/workspace/workspaceSkillCatalog/workspaceSkillCatalog'; +export * from '#/workspace/workspaceSkillCatalog/workspaceSkillCatalogService'; +export * from '#/workspace/workspaceSkillCatalog/extraFileSkillSource'; +export * from '#/workspace/workspaceSkillCatalog/explicitFileSkillSource'; +export * from '#/workspace/workspaceSkillCatalog/rootFileSkillSource'; +export * from '#/workspace/workspaceSkillCatalog/pluginSkillSource'; export * from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader'; export * from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService'; export * from '#/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader'; @@ -339,68 +301,29 @@ export * from '#/features/plan/configSection'; export * from '#/features/plan/plan'; export * from '#/features/plan/planOps'; export * from '#/features/plan/planService'; -import '#/features/dateChange/dateChangeFeature'; import '#/features/plan/planFeature'; -export * from '#/features/externalHooks/configSection'; -export * from '#/features/externalHooks/app/externalHooksRunner'; -export * from '#/features/externalHooks/app/externalHooksRunnerService'; -export * from '#/features/externalHooks/session/sessionExternalHooks'; -export * from '#/features/externalHooks/session/sessionExternalHooksService'; -export * from '#/features/externalHooks/agent/agentExternalHooks'; -export * from '#/features/externalHooks/agent/agentExternalHooksService'; -import '#/features/externalHooks/externalHooksFeature'; export * from '#/features/debugEvents/debugEvents'; export * from '#/features/debugEvents/debugEventsService'; import '#/features/debugEvents/debugEventsFeature'; -export * from '#/features/swarm/configSection'; -export * from '#/features/swarm/agent/swarm'; -export * from '#/features/swarm/agent/swarmService'; -export * from '#/features/swarm/session/sessionSwarm'; -export * from '#/features/swarm/session/sessionSwarmService'; -export * from '#/features/swarm/tools/agent-swarm/agent-swarm'; -import '#/features/swarm/tools/agent-swarm/agentSwarmTool'; -import '#/features/swarm/swarmFeature'; -export * from '#/features/goal/tools/create-goal/create-goal'; -import '#/features/goal/tools/create-goal/createGoalTool'; -export * from '#/features/goal/tools/get-goal/get-goal'; -import '#/features/goal/tools/get-goal/getGoalTool'; -export * from '#/features/goal/tools/set-goal-budget/set-goal-budget'; -import '#/features/goal/tools/set-goal-budget/setGoalBudgetTool'; -export * from '#/features/goal/tools/update-goal/update-goal'; -import '#/features/goal/tools/update-goal/updateGoalTool'; -export * from '#/features/goal/goalDeadlineScheduler'; -export * from '#/features/goal/goal'; -export * from '#/features/goal/goalAgentRuntime'; -export * from '#/features/goal/goalOps'; -export * from '#/features/goal/types'; -import '#/features/goal/goalFeature'; -import '#/features/staleGuard/staleGuardFeature'; -export * from '#/features/tower/flag'; -export * from '#/features/tower/tower'; -export * from '#/features/tower/towerFeature'; -export * from '#/features/tower/towerService'; -export * from '#/features/tower/towerRateLimit'; -export * from '#/features/tower/towerRateLimitService'; -export * from '#/features/tower/tools/init/init'; -export * from '#/features/tower/tools/plan/plan'; -export * from '#/features/tower/tools/spawn/spawn'; -export * from '#/features/tower/tools/merge/merge'; -export * from '#/features/tower/tools/teardown/teardown'; -export * from '#/features/tower/tools/send/send'; -export * from '#/features/tower/tools/inbox/inbox'; -export * from '#/features/tower/tools/finding/finding'; -export * from '#/features/tower/tools/review/review'; -export * from '#/features/tower/tools/mission/mission'; -export * from '#/features/tower/tools/status/status'; -import '#/features/tower/flag'; -import '#/features/tower/towerFeature'; +export * from '#/agent/tools/goal/create-goal/create-goal'; +import '#/agent/tools/goal/create-goal/createGoalTool'; +export * from '#/agent/tools/goal/get-goal/get-goal'; +import '#/agent/tools/goal/get-goal/getGoalTool'; +export * from '#/agent/tools/goal/set-goal-budget/set-goal-budget'; +import '#/agent/tools/goal/set-goal-budget/setGoalBudgetTool'; +export * from '#/agent/tools/goal/update-goal/update-goal'; +import '#/agent/tools/goal/update-goal/updateGoalTool'; +export * from '#/agent/goal/goalDeadlineScheduler'; +import '#/agent/goal/goalDeadlineSchedulerService'; +export * from '#/agent/goal/goal'; +export * from '#/agent/goal/goalService'; +export * from '#/agent/goal/types'; +export * from '#/agent/tools/agent-swarm/agent-swarm'; +import '#/agent/tools/agent-swarm/agentSwarmTool'; +export * from '#/agent/swarm/swarm'; +export * from '#/agent/swarm/swarmService'; export * from '#/agent/usage/usage'; -export * from '#/agent/usage/cacheProbe'; -export * from '#/agent/usage/cacheProbeService'; -export * from '#/session/usage/sessionUsage'; -export * from '#/session/usage/usageAgentModel'; -export * from '#/session/usage/sessionUsageService'; -import '#/features/usage/usageFeature'; +export * from '#/agent/usage/usageService'; export * from '#/agent/toolDedupe/toolDedupe'; export * from '#/agent/toolDedupe/toolDedupeService'; export * from '#/agent/agentsMdReminder/agentsMdReminder'; @@ -413,8 +336,6 @@ export * from '#/agent/toolSelect/toolSelect'; export * from '#/agent/toolSelect/toolSelectService'; export * from '#/agent/toolSelect/toolSelectAnnouncements'; export * from '#/agent/toolSelect/toolSelectAnnouncementsService'; -export * from '#/agent/toolSelect/toolSelectSchemas'; -export * from '#/agent/toolSelect/toolSelectSchemasService'; import '#/agent/toolPolicy/configSection'; export * from '#/agent/toolPolicy/configSection'; export * from '#/agent/toolPolicy/evaluate'; @@ -435,20 +356,26 @@ export * from '#/agent/tools/task/task-output/task-output'; import '#/agent/tools/task/task-output/taskOutputTool'; export * from '#/agent/tools/task/task-stop/task-stop'; import '#/agent/tools/task/task-stop/taskStopTool'; -export * from '#/agent/tools/task/task-wait/task-wait'; -import '#/agent/tools/task/task-wait/taskWaitTool'; export * from '#/agent/task/task'; export * from '#/agent/task/taskOps'; export * from '#/agent/task/taskService'; -import '#/features/cron/configSection'; -export * from '#/features/cron/cronTask'; -export * from '#/features/cron/configSection'; -export * from '#/features/cron/cronAgentRuntime'; -export * from '#/features/cron/cronOps'; -import '#/features/cron/cronFeature'; -export * from '#/features/cron/tools/cron-create/cron-create'; -export * from '#/features/cron/tools/cron-list/cron-list'; -export * from '#/features/cron/tools/cron-delete/cron-delete'; +import '#/app/cron/configSection'; +export * from '#/app/cron/cronTask'; +export * from '#/app/cron/cronTaskPersistence'; +export * from '#/app/cron/cronTaskPersistenceService'; +export * from '#/app/cron/cron-expr'; +export * from '#/app/cron/format'; +export * from '#/app/cron/jitter'; +export * from '#/app/cron/clock'; +export * from '#/app/cron/configSection'; +export * from '#/session/cron/sessionCronService'; +export * from '#/session/cron/sessionCronServiceImpl'; +export * from '#/agent/tools/cron/cron-create/cron-create'; +import '#/agent/tools/cron/cron-create/cronCreateTool'; +export * from '#/agent/tools/cron/cron-list/cron-list'; +import '#/agent/tools/cron/cron-list/cronListTool'; +export * from '#/agent/tools/cron/cron-delete/cron-delete'; +import '#/agent/tools/cron/cron-delete/cronDeleteTool'; import '#/session/agentLifecycle/profile/profiles'; export * from '#/session/agentLifecycle/agentLifecycle'; @@ -462,37 +389,31 @@ export { type McpSection, } from '#/app/mcpConfig/configSection'; export * from '#/app/mcpConfig/oauthStore'; -export { IMcpConfigStore } from '#/app/mcpConfig/configStore'; -import '#/app/mcpConfig/configStore'; -export { IMcpOAuthService } from '#/app/mcpConfig/oauthService'; -import '#/app/mcpConfig/oauthService'; -export * from '#/app/mcpRegistry/mcpRegistry'; -import '#/app/mcpRegistry/mcpRegistryService'; -export * from '#/app/mcpManagement/mcpManagement'; -import '#/app/mcpManagement/mcpManagementService'; export * from '#/workspace/workspaceMcpConfig/workspaceMcpConfig'; export * from '#/workspace/workspaceMcpConfig/workspaceMcpConfigService'; export * from '#/workspace/workspaceMcp/workspaceMcp'; export * from '#/workspace/workspaceMcp/workspaceMcpService'; export * from '#/session/subagent/subagent'; export * from '#/session/subagent/subagentService'; -export * from '#/session/subagent/spawn'; import '#/session/subagent/flag'; -export * from '#/session/subagent/subagentModelsValidation'; -import '#/session/subagent/subagentModelsValidationService'; +export * from '#/session/subagent/secondaryModelWarning'; +export * from '#/session/subagent/secondaryModelWarningService'; export * from '#/agent/tools/agent/subagent-task'; export { AGENT_RUN_PROMPT_ORIGIN } from '#/session/subagent/runAgentTurn'; export * from '#/session/subagent/mirrorAgentRun'; import '#/session/subagent/configSection'; export * from '#/agent/tools/agent/agent'; import '#/agent/tools/agent/agentTool'; -export * from '#/app/sessionManager/sessionLookup'; +export * from '#/app/workspaceLifecycle/workspaceLifecycle'; +export * from '#/app/workspaceLifecycle/workspaceLifecycleService'; +export * from '#/app/workspaceLifecycle/sessionLookup'; export * from '#/workspace/workspaceContext/workspaceContext'; export * from '#/workspace/sessionLifecycle/sessionLifecycle'; -export * from '#/workspace/sessionLifecycle/sessionLifecycleEvents'; export * from '#/workspace/sessionLifecycle/sessionLifecycleService'; -export * from '#/workspace/sessionLifecycle/coldSessionArchive'; export * from '#/workspace/sessionLifecycle/internal/addressing'; +export * from '#/session/sessionLifecycleHooks/sessionLifecycleHooks'; +export * from '#/session/externalHooks/externalHooks'; +export * from '#/session/externalHooks/externalHooksService'; import '#/app/sessionExport/errors'; export * from '#/app/sessionExport/sessionExport'; export * from '#/app/sessionExport/sessionExportService'; @@ -501,11 +422,9 @@ export * from '#/app/sessionExport/wire-scan'; export * from '#/app/sessionExport/zip'; export * from '#/app/sessionLegacy/sessionLegacy'; export * from '#/app/sessionLegacy/sessionLegacyService'; -export * from '#/features/interaction/interaction'; -export * from '#/features/interaction/interactionAgentRuntime'; -export * from '#/features/interaction/interactionOps'; -export * from '#/features/interaction/sessionInteractions'; -import '#/features/interaction/interactionFeature'; +export * from '#/session/interaction/interaction'; +export * from '#/session/interaction/interactionOps'; +export * from '#/session/interaction/interactionService'; export * from '#/session/sessionContext/sessionContext'; import '#/session/approval/approval'; @@ -529,7 +448,6 @@ export * from '#/app/projectLocalConfig/projectLocalConfig'; export * from '#/app/workspace/workspace'; export * from '#/app/workspace/workspaceService'; export * from '#/app/workspace/workspaceAlias'; -export * from '#/app/workspace/workspaceEvents'; export * from '#/app/workspace/workspacePersistence'; export * from '#/app/workspace/fileWorkspacePersistence'; export * from '#/app/workspaceAliases/workspaceAliases'; @@ -539,6 +457,9 @@ import '#/app/workspaceSessions/workspaceSessionsService'; import '#/app/git/gitService'; export * from '#/app/bashParser/bashParser'; import '#/app/bashParser/bashParserService'; +export * from '#/session/process/processRunner'; +export * from '#/session/process/processRunnerService'; +export * from '#/workspace/workspaceProcess/workspaceProcessRunnerService'; export * from '#/workspace/workspaceFs/internal/errors'; export * from '#/workspace/workspaceFs/fs'; export * from '#/workspace/workspaceFs/fsService'; @@ -551,6 +472,8 @@ export * from '#/workspace/workspaceGit/workspaceGit'; export * from '#/workspace/workspaceGit/workspaceGitService'; export * from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; export * from '#/session/sessionToolPolicyGate/sessionToolPolicyGateService'; +export * from '#/workspace/workspaceToolPolicy/workspaceToolPolicy'; +export * from '#/workspace/workspaceToolPolicy/workspaceToolPolicyService'; export * from '#/workspace/workspaceTrust/workspaceTrust'; export * from '#/workspace/workspaceTrust/workspaceTrustService'; export * from '#/app/hostFolderBrowser/hostFolderBrowser'; @@ -613,6 +536,8 @@ export * from '#/app/edit/editService'; export * from '#/app/edit/textModel'; export * from '#/agent/tools/edit/edit'; import '#/agent/tools/edit/editTool'; +export * from '#/app/externalHooksRunner/externalHooksRunner'; +export * from '#/app/externalHooksRunner/externalHooksRunnerService'; export * from '#/agent/tools/fetch-url/fetch-url'; import '#/agent/tools/fetch-url/fetchUrlTool'; export * from '#/app/web/web'; @@ -632,24 +557,22 @@ export * from '#/agent/contextMemory/loopEventFold'; export * from '#/agent/contextMemory/messageId'; export * from '#/agent/contextMemory/contextTranscript'; export * from '#/agent/contextMemory/types'; -export { AgentReminder, ReminderRuntime } from '#/features/reminder/reminderAgentRuntime'; -export * from '#/features/reminder/systemReminder'; -export * from '#/features/reminder/types'; -import '#/features/reminder/reminderFeature'; -export * from '#/features/dateChange/dateChange'; -export * from '#/features/dateChange/dateChangeAgentRuntime'; +export * from '#/agent/systemReminder/systemReminder'; +export * from '#/agent/systemReminder/systemReminderService'; +export * from '#/agent/dateChange/dateChange'; +export * from '#/agent/dateChange/dateChangeService'; export * from '#/agent/contextProjector/contextProjector'; export * from '#/agent/contextProjector/contextProjectorService'; -export * from '#/agent/contextProjector/mediaProjection'; export * from '#/agent/tokenCounting/tokenCounting'; export * from '#/agent/tokenCounting/tokenCountingOps'; -export * from '#/session/tokenCounting/sessionTokenCounting'; -export * from '#/session/tokenCounting/tokenCountingAgentModel'; -export * from '#/session/tokenCounting/sessionTokenCountingService'; -import '#/features/tokenCounting/tokenCountingFeature'; +export * from '#/agent/tokenCounting/tokenCountingService'; +export * from '#/agent/contextInjector/contextInjector'; +export * from '#/agent/contextInjector/contextInjectorService'; export * from '#/agent/plugin/agentPlugin'; -export * from '#/agent/plugin/agentPluginOps'; export * from '#/agent/plugin/agentPluginService'; +import '#/agent/externalHooks/configSection'; +export * from '#/agent/externalHooks/externalHooks'; +export * from '#/agent/externalHooks/externalHooksService'; export * from '#/agent/fullCompaction/strategy'; export * from '#/agent/fullCompaction/fullCompaction'; export * from '#/agent/fullCompaction/fullCompactionService'; @@ -676,21 +599,10 @@ export * from '#/mcpCore/config-schema'; export * from '#/agent/media/mediaTools'; export * from '#/agent/media/mediaToolsRegistrar'; export * from '#/agent/media/registerMediaTools'; -export { - buildDaemonFileUrl, - buildMediaPathTag, - daemonFileRefFromPart, - mediaExtensionForMime, - matchSingleMediaPathTag, - parseDaemonFileUrl, -} from '#/agent/media/mediaRef'; -export type { DaemonFileRef, MediaKind } from '#/agent/media/mediaRef'; -export * from '#/agent/media/sessionMediaStore'; -import '#/agent/media/sessionMediaStoreService'; export * from '#/agent/media/kimiFileUrl'; export * from '#/agent/media/videoUpload'; -export * from '#/agent/media/mediaResolver'; -export * from '#/agent/media/mediaResolverService'; +export * from '#/agent/media/videoResolver'; +export * from '#/agent/media/videoResolverService'; import '#/agent/media/configSection'; export * from '#/agent/media/imageConfigBridge'; import '#/agent/permissionMode/configSection'; @@ -703,35 +615,33 @@ import '#/agent/permissionRules/configSection'; export * from '#/agent/permissionRules/permissionRules'; export * from '#/agent/permissionRules/matchesRule'; export * from '#/agent/permissionRules/permissionRulesService'; -export * from '#/agent/pluginCommand/pluginCommand'; -export * from '#/agent/pluginCommand/pluginCommandService'; export * from '#/agent/profile/profile'; export * from '#/agent/profile/profileService'; export * from '#/agent/profile/context'; export * from '#/agent/prompt/prompt'; -export * from '#/agent/prompt/promptOps'; export * from '#/agent/prompt/promptService'; -export * from '#/agent/prompt/promptMetadataText'; export * from '#/agent/replayBuilder/types'; -export { type SessionSummary } from '#/app/sessionIndex/sessionIndex'; export * from '#/agent/undo/undo'; export * from '#/agent/undo/undoService'; export * from '#/agent/shellCommand/shellCommand'; export * from '#/agent/shellCommand/shellCommandService'; -export * from '#/agent/agentContext/agentContext'; -export * from '#/agent/agentContext/agentSpace'; +export * from '#/agent/rpc/rpc'; +export * from '#/agent/rpc/rpcService'; +export * from '#/agent/rpc/prompt-metadata'; export * from '#/agent/scopeContext/scopeContext'; export * from '#/agent/stepRetry/stepRetry'; export * from '#/agent/stepRetry/stepRetryService'; -export * from '#/features/sessionInit/sessionInit'; -export * from '#/features/sessionInit/sessionInitService'; -export * from '#/features/sessionInit/profile/init'; -import '#/features/sessionInit/sessionInitFeature'; -export * from '#/features/todo/todoItem'; -export * from '#/features/todo/todoListReminder'; -export * from '#/features/todo/todoAgentRuntime'; -export * from '#/features/todo/tools/todo-list/todo-list'; -import '#/features/todo/todoFeature'; +export * from '#/session/sessionInit/sessionInit'; +export * from '#/session/sessionInit/sessionInitService'; +export * from '#/session/sessionInit/profile/init'; +export * from '#/session/swarm/sessionSwarm'; +export * from '#/session/swarm/sessionSwarmService'; +export * from '#/session/todo/todoItem'; +export * from '#/session/todo/todoListReminder'; +export * from '#/session/todo/sessionTodo'; +export * from '#/session/todo/sessionTodoService'; +export * from '#/agent/tools/todo-list/todo-list'; +import '#/agent/tools/todo-list/todoListTool'; export * from '#/tool/toolContract'; export * from '#/agent/toolExecutor/toolHooks'; export * from '#/agent/toolExecutor/toolExecutor'; diff --git a/packages/agent-core-v2/src/kosong/contract/capability.ts b/packages/agent-core-v2/src/kosong/contract/capability.ts index a8825fb60..5294634ca 100644 --- a/packages/agent-core-v2/src/kosong/contract/capability.ts +++ b/packages/agent-core-v2/src/kosong/contract/capability.ts @@ -1,3 +1,15 @@ +/** + * `kosong/contract` domain — declared model capabilities. + * + * `ModelCapability` describes the modalities and limits of a specific model + * so callers can gate requests against what the model accepts without + * dispatching the request and watching it fail upstream. + * + * `UNKNOWN_CAPABILITY` is the marker value returned when nothing is known + * about a model: `max_context_tokens: 0` means "unknown"; callers that do + * not gate on context length can ignore the field. + */ + export interface ModelCapability { readonly image_in: boolean; readonly video_in: boolean; diff --git a/packages/agent-core-v2/src/kosong/contract/errors.ts b/packages/agent-core-v2/src/kosong/contract/errors.ts index 3a6bafde1..bea23797a 100644 --- a/packages/agent-core-v2/src/kosong/contract/errors.ts +++ b/packages/agent-core-v2/src/kosong/contract/errors.ts @@ -1,3 +1,28 @@ +/** + * `kosong/contract` domain — the provider error taxonomy. + * + * The single authority on error classification for the LLM wire layer: + * the `API*Error` class family, the retry verdict (`isRetryableGenerateError`), + * the telemetry classification (`ApiErrorKind` / `classifyApiError`), and the + * status-error normalizer every dialect's error converter funnels through. + * Alongside the wire-status classes, `VideoUploadUnsupportedError` marks the + * by-design capability gap (provider has no video upload hook) so callers + * can tell it apart from an upload that failed at runtime. + * + * The family is born-coded: every class extends `Error2` and computes its + * wire code (`provider.*` / `context.overflow`) at construction from the + * status code / finish reason, so no boundary translation is needed — the + * code string constants live here (the L0 wire contract) and are registered + * by `kosong/protocol/errors.ts` (`ProtocolErrors`). `translateProviderError` + * only remains as the abort guard and the foreign-error fallback. + * + * Abort has exactly one standard shape here: the DOMException built by + * `createAbortError`. Provider error converters must run the `throwIfAbortError` + * guard FIRST in their classification chain — a user cancellation is thrown + * as the standard abort shape, never converted into (and never returned as) + * a retryable provider error. + */ + import { Error2, type Error2Options } from '#/_base/errors/errors'; import type { FinishReason } from './provider'; @@ -236,7 +261,7 @@ export function isRetryableGenerateError(error: unknown): boolean { return true; } if (error instanceof APIEmptyResponseError) { - return error.finishReason !== 'filtered'; + return true; } if (error instanceof APIProviderOverloadedError) { return true; diff --git a/packages/agent-core-v2/src/kosong/contract/generate.ts b/packages/agent-core-v2/src/kosong/contract/generate.ts index e23aa8404..3fbecb6e1 100644 --- a/packages/agent-core-v2/src/kosong/contract/generate.ts +++ b/packages/agent-core-v2/src/kosong/contract/generate.ts @@ -1,3 +1,14 @@ +/** + * `kosong/contract` domain — the generation driver. + * + * `generate()` is the single place that orchestrates "call + * `ChatProvider.generate` and normalize the event stream": it merges streamed + * deltas into a complete assistant `Message`, fires the caller's callbacks, + * enforces the abort contract (standard abort DOMException, stream cancelled + * on abort), and rejects empty or thinking-only responses with + * `APIEmptyResponseError`. + */ + import { APIEmptyResponseError, createAbortError } from './errors'; import { isContentPart, diff --git a/packages/agent-core-v2/src/kosong/contract/inspection.ts b/packages/agent-core-v2/src/kosong/contract/inspection.ts index 0cf0916ad..11fb23695 100644 --- a/packages/agent-core-v2/src/kosong/contract/inspection.ts +++ b/packages/agent-core-v2/src/kosong/contract/inspection.ts @@ -1,3 +1,16 @@ +/** + * `kosong/contract` domain — resolution-provenance annotations. + * + * Every settled field of a resolved `Model` has an origin: an explicit config + * entry, a model `overrides` block, a built-in registry (provider definition, + * Anthropic profile table, protocol base catalog), an env-bag fallback, a + * synthesized computation, or no source at all. `InspectionSource` is the + * L0 vocabulary for naming that origin; `ResolutionTrace` is the collector + * the model resolver records into while assembling a Model, so the on-demand + * inspection view can report *why* a value is what it is — never re-resolving, + * just reading the trace of that same resolution. + */ + export type InspectionSourceKind = | 'config' | 'override' diff --git a/packages/agent-core-v2/src/kosong/contract/message.ts b/packages/agent-core-v2/src/kosong/contract/message.ts index 2743c9e7d..0c44556e7 100644 --- a/packages/agent-core-v2/src/kosong/contract/message.ts +++ b/packages/agent-core-v2/src/kosong/contract/message.ts @@ -1,3 +1,15 @@ +/** + * `kosong/contract` domain — wire message shapes and their pure helpers. + * + * `Message` / `ContentPart` / `ToolCall` are the provider-agnostic wire + * content every protocol base encodes from and decodes into. The helpers + * cover the whole lifecycle: construction (`create*Message`), inspection + * (`is*` / `extractText`), and stream merge (`mergeInPlace` folds streamed + * deltas into the pending part). + * + * Pure types and pure functions only — no other domain, no I/O, no SDKs. + */ + import type { Tool } from './tool'; export type Role = 'system' | 'user' | 'assistant' | 'tool'; diff --git a/packages/agent-core-v2/src/kosong/contract/messageHelpers.ts b/packages/agent-core-v2/src/kosong/contract/messageHelpers.ts index c65713f77..33933b5a2 100644 --- a/packages/agent-core-v2/src/kosong/contract/messageHelpers.ts +++ b/packages/agent-core-v2/src/kosong/contract/messageHelpers.ts @@ -1,3 +1,15 @@ +/** + * `kosong/contract.messageHelpers` — runtime helpers for building and + * inspecting wire messages / content parts / tool calls. + * + * Constructors: `createAssistantMessage | createToolMessage | createUserMessage`. + * Utilities: `extractText | mergeInPlace` (in-place merge of streamed + * tool-call argument deltas). + * + * Re-exports the helper surface so callers can take it without pulling in the + * entire wire-type module. + */ + export { createAssistantMessage, createToolMessage, diff --git a/packages/agent-core-v2/src/kosong/contract/provider.ts b/packages/agent-core-v2/src/kosong/contract/provider.ts index 1690ff40d..3d79b1003 100644 --- a/packages/agent-core-v2/src/kosong/contract/provider.ts +++ b/packages/agent-core-v2/src/kosong/contract/provider.ts @@ -1,3 +1,21 @@ +/** + * `kosong/contract` domain — the ChatProvider wire contract. + * + * ⚠ Named `provider` but this is the L0 contract, not an implementation: + * the slimmed `ChatProvider` interface plus everything a single generation + * call needs. Two invariants hold here: + * + * - A ChatProvider is immutable after construction. The interface has no + * `with*` methods; every per-turn intent (prompt-cache key, sampling + * overrides, thinking effort/keep, completion-token budget) flows through + * `GenerateOptions` on each `generate` call instead of through morphs. + * - `GenerateOptions` is the per-turn intent carrier. Each wire dialect + * decides how — or whether — to encode an intent (e.g. a cache key may + * become `prompt_cache_key`, `metadata.user_id`, or be silently dropped). + * + * Pure types only — no other domain, no I/O, no SDKs. + */ + import type { Message, StreamedMessagePart, VideoURLPart } from './message'; import type { Tool } from './tool'; import type { TokenUsage } from './usage'; diff --git a/packages/agent-core-v2/src/kosong/contract/requestTrace.ts b/packages/agent-core-v2/src/kosong/contract/requestTrace.ts index fe60f0962..92cc370fb 100644 --- a/packages/agent-core-v2/src/kosong/contract/requestTrace.ts +++ b/packages/agent-core-v2/src/kosong/contract/requestTrace.ts @@ -1,3 +1,10 @@ +/** + * `kosong/contract` domain — live request provenance contract. + * + * Exposes the provider trace identifier of one logical LLM request while its + * result is still pending. Pure contract (types only); no scoped service. + */ + export interface LLMRequestTrace { readonly traceId: string | undefined; } diff --git a/packages/agent-core-v2/src/kosong/contract/tokens.ts b/packages/agent-core-v2/src/kosong/contract/tokens.ts index 046a91ee7..b6a0238e8 100644 --- a/packages/agent-core-v2/src/kosong/contract/tokens.ts +++ b/packages/agent-core-v2/src/kosong/contract/tokens.ts @@ -1,3 +1,13 @@ +/** + * `kosong/contract` domain — character-based token-count estimates for + * messages, tools, and content parts. + * + * Estimates are heuristic (ASCII ≈ 4 chars/token, non-ASCII ≈ 1 token/char, + * media parts a flat `MEDIA_TOKEN_ESTIMATE`); they size context windows and + * compaction budgets, never billing. Per-message results are memoized on the + * message object via a WeakMap. + */ + import type { ContentPart, Message } from './message'; import type { Tool } from './tool'; diff --git a/packages/agent-core-v2/src/kosong/contract/tool.ts b/packages/agent-core-v2/src/kosong/contract/tool.ts index b070862b4..1d9569e8c 100644 --- a/packages/agent-core-v2/src/kosong/contract/tool.ts +++ b/packages/agent-core-v2/src/kosong/contract/tool.ts @@ -1,3 +1,12 @@ +/** + * `kosong/contract` domain — the provider-agnostic tool definition. + * + * A tool that the model may invoke during generation. The definition is + * provider-agnostic; each provider implementation converts it to the + * appropriate wire format (e.g. OpenAI function-calling, Anthropic tool-use, + * Google function declarations). + */ + export interface Tool { name: string; description: string; diff --git a/packages/agent-core-v2/src/kosong/contract/usage.ts b/packages/agent-core-v2/src/kosong/contract/usage.ts index ad59bd6bc..58a313192 100644 --- a/packages/agent-core-v2/src/kosong/contract/usage.ts +++ b/packages/agent-core-v2/src/kosong/contract/usage.ts @@ -1,3 +1,11 @@ +/** + * `kosong/contract` domain — token usage wire shape and aggregations. + * + * `TokenUsage` is the common usage breakdown for a single LLM generation. + * Providers map their native usage counters into this shape so callers can + * aggregate costs without caring about the backend. + */ + export interface TokenUsage { inputOther: number; output: number; diff --git a/packages/agent-core-v2/src/kosong/model/catalog.ts b/packages/agent-core-v2/src/kosong/model/catalog.ts index 1ebf394b9..95a1b6ba5 100644 --- a/packages/agent-core-v2/src/kosong/model/catalog.ts +++ b/packages/agent-core-v2/src/kosong/model/catalog.ts @@ -1,3 +1,34 @@ +/** + * `kosong/model` domain — the pure-data `Model`, the auth-provider + * contract, and the `IModelCatalog` interface. + * + * A `Model` is exactly the configuration-derived data the rest of v2 needs to + * talk about one configured model: endpoint, auth closure, wire protocol, + * wire-facing name, headers, capability matrix, and budget knobs. It is NOT + * a request executor and carries no `with*` morphs — per-turn intent flows + * through `ModelRequestParams` on `ModelRequester.request(...)` instead. + * Construction happens exactly once per config generation, in `ModelCatalog` + * — the only place that assembles Models. + * + * `IModelCatalog` is the single lookup the edge layers consume, in one of + * two shapes: + * - want data → `get(id)` → the pure-data Model; + * - want requests → `getRequester(id)` → the ModelRequester; + * `findByName` is the reverse map for many-to-many name/alias routing. + * + * Enumeration (`listModels` / `listProviders` / `getProvider`) projects the + * SAME materialization `get` serves into the wire catalog shapes below, so + * the management surface can never drift from what the runtime resolves. + * `setDefaultModel` writes the global default-model pointer (through + * `IModelService`); it is the catalog's only write, validated against + * materialization so an unresolvable model can never become the default. + * + * The catalog caches assembled Models by id and invalidates on the + * model/provider config-change events. Tests that mutate config + * BEHIND the service's back (bypassing those events) must call + * `ModelCatalog.notifyConfigChanged()` to drop the cache. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/kosong/model/catalogService.ts b/packages/agent-core-v2/src/kosong/model/catalogService.ts index eec267316..d48875bc4 100644 --- a/packages/agent-core-v2/src/kosong/model/catalogService.ts +++ b/packages/agent-core-v2/src/kosong/model/catalogService.ts @@ -1,3 +1,59 @@ +/** + * `kosong/model` domain — `ModelCatalog`, the single place that builds + * Models. + * + * Reads Model / Provider config, resolves the auth closure (provider-level + * credential or Model-inline override), and assembles the pure-data + * `Model` plus its `ModelRequester` — cached together by model id. Bound at + * App scope; resolution is shared across sessions. + * + * Two config-driven paths (unchanged from the legacy resolver): + * - **Structured** — `Model.providerId` points at a `[providers.*]` entry. + * Auth comes from the Provider unless the Model carries an override + * (`apiKey` / `oauth`). + * - **Flat** — `Model.baseUrl` is inline; the catalog synthesizes a + * Provider record keyed by the URL's origin so multiple Models on the + * same host converge on the same Provider metadata. Auth comes from the + * Model itself. + * + * Everything vendor-shaped goes through the registries, never a hardcoded + * switch: the wire protocol falls back from an explicit `protocol` to the + * referenced provider vendor's declared `baseProtocol`; endpoint and + * credential env fallbacks resolve through `resolveProviderEndpoint` against + * the config env bag; host-header forwarding follows the vendor definition's + * `hostHeaders`; capability detection is `resolveCapability(protocol, name, + * providerType)`. + * + * Caching (load-bearing): assembled entries are invalidated ONLY by the + * model/provider config-change events. Tests that mutate config + * behind the services' backs (bypassing those events) must call + * `notifyConfigChanged()` to drop the cache — otherwise `get` keeps serving + * the previous generation's Model. The host-header layers baked into an + * entry need no invalidation: both are frozen for the process (bootstrap + * args, and the identity snapshot behind the third-party layer). + * + * Inspection: every assembly also captures a `ResolutionTraceCollector` + * (provenance records + intermediate artifacts, reference-only) alongside the + * Model in the same cache entry. `inspect(id)` assembles the god object from + * that trace on demand — same pass, same generation, never a re-resolution. + * + * Enumeration & default pointer: `listModels` projects every configured + * model from the SAME materialization `get` serves (falling back to the + * config-only projection for models that fail to materialize, so broken + * config stays visible); `listProviders` / `getProvider` project the + * provider registry plus credential state. `setDefaultModel` writes the + * global default-model pointer (through `IModelService`) after a + * materialization gate — the catalog's only write. + * + * Outbound headers: vendors declaring `hostHeaders: 'full'` receive the host + * headers port's complete set and stay consistent with it — that set is the + * host's to define, and backends key on the product token it carries (log + * filtering, rollout gating). Everyone else receives the port's third-party + * layer, already finished on the app side (at most a `User-Agent`, product + * token per the configured identity) — this catalog picks a layer, it never + * edits one. + */ + import { parseKimiCodeCustomHeaders } from '@moonshot-ai/kimi-code-oauth'; import { Disposable } from '#/_base/di/lifecycle'; @@ -77,6 +133,7 @@ interface CatalogEntry { readonly trace: ResolutionTraceCollector; } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ModelCatalog extends Disposable implements IModelCatalog { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/kosong/model/completionBudget.ts b/packages/agent-core-v2/src/kosong/model/completionBudget.ts index 49bfd515c..a43f5f532 100644 --- a/packages/agent-core-v2/src/kosong/model/completionBudget.ts +++ b/packages/agent-core-v2/src/kosong/model/completionBudget.ts @@ -1,3 +1,20 @@ +/** + * `kosong/model` domain — the completion-token budget, as pure functions. + * + * The budget no longer morphs a Model (there is no `applyCompletionBudget`): + * the caller resolves a `CompletionBudgetConfig`, folds it into a per-turn cap + * with `computeCompletionBudgetCap`, and passes the result through + * `ModelRequestParams` (`maxCompletionTokens` + the window-clamp companions). The + * wire base clamps the cap against the context window before any dialect + * ceiling applies. + * + * Load-bearing rule: `usedContextTokens` is the caller's MEASURED in-context + * tokens and is only folded in when the request did not explicitly override + * its messages — with explicit messages the budget is not tightened against + * the current context. `completionBudgetParams` is the single fold point that + * keeps this honest. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { CompletionBudgetConfig, CompletionBudgetParams } from './model.types'; diff --git a/packages/agent-core-v2/src/kosong/model/errors.ts b/packages/agent-core-v2/src/kosong/model/errors.ts index de8704103..588939d44 100644 --- a/packages/agent-core-v2/src/kosong/model/errors.ts +++ b/packages/agent-core-v2/src/kosong/model/errors.ts @@ -1,3 +1,13 @@ +/** + * `kosong/model` domain — catalog error codes. + * + * The codes are intentionally identical to the deleted legacy + * `app/modelCatalog` domain's (the wire contract branches on them). The + * error registry keys on the contributing `codes` OBJECT, so the legacy + * module could never be loaded together with this one — this domain is the + * sole owner of the codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const ModelCatalogErrors = { @@ -21,4 +31,4 @@ export const ModelCatalogErrors = { }, } as const satisfies ErrorDomain; -registerErrorDomain(ModelCatalogErrors); +registerErrorDomain(ModelCatalogErrors); \ No newline at end of file diff --git a/packages/agent-core-v2/src/kosong/model/hostRequestHeaders.ts b/packages/agent-core-v2/src/kosong/model/hostRequestHeaders.ts index 6e040271d..e334943ce 100644 --- a/packages/agent-core-v2/src/kosong/model/hostRequestHeaders.ts +++ b/packages/agent-core-v2/src/kosong/model/hostRequestHeaders.ts @@ -1,3 +1,24 @@ +/** + * `kosong/model` domain (L2) — host-provided default headers for outbound + * provider requests (port contract). + * + * Mirrors v1's `kimiRequestHeaders`: the host (CLI / server) states its Kimi + * identity headers (`User-Agent` + `X-Msh-*`) in + * `BootstrapInput.args.requestHeaders`; the app-side adapter + * (`app/kosongConfig/hostRequestHeadersAdapter`) bridges + * `IBootstrapService.args` to this port so kosong stays a pure abstraction + * layer. The port carries two finished layers and `ModelCatalog` picks one + * per vendor — `headers`, the full verbatim set, for vendors whose definition + * declares `hostHeaders: 'full'`; `thirdPartyHeaders`, at most the + * `User-Agent`, for everyone else (so device identity never leaks to + * third-party endpoints). Any custom-identity rewriting happens on the app + * side before the layers reach this port; kosong applies them as given. + * + * `identitySlug` is provenance metadata only — the configured custom + * identity's token, surfaced by `inspect` to label where the third-party + * `User-Agent`'s product token came from. No resolution logic reads it. + */ + import { createDecorator } from '#/_base/di/instantiation'; export interface IHostRequestHeaders { diff --git a/packages/agent-core-v2/src/kosong/model/inspection.ts b/packages/agent-core-v2/src/kosong/model/inspection.ts index aa426a420..e2d6c29d7 100644 --- a/packages/agent-core-v2/src/kosong/model/inspection.ts +++ b/packages/agent-core-v2/src/kosong/model/inspection.ts @@ -1,3 +1,22 @@ +/** + * `kosong/model` domain — the `IModelCatalog.inspect` payload and its + * assembly. + * + * The inspection is a *god object* for one configured model: the raw config + * layers (`[models.*]` record + effective record, `[providers.*]` config + + * provider-definition facts) beside the + * resolved runtime view — plus `sources`, a dot-path → provenance map that + * answers "where did this value come from" (`config` / `override` / + * `builtin` / `env` / `synthesized` / `none`). + * + * Everything here is on-demand: `ModelCatalog.entry` captures a + * `ResolutionTraceCollector` while resolving (reference-only, no copies), and + * `assembleModelInspection` builds the god object — including secret + * redaction — only when `inspect` is called. The trace and the resolved + * Model come from the SAME resolution pass, so the inspection can never + * drift from what `get` served (same config generation, same cache entry). + */ + import { parseKimiCodeCustomHeaders } from '@moonshot-ai/kimi-code-oauth'; import { BugIndicatingError } from '#/_base/errors/errors'; @@ -13,6 +32,7 @@ import { getProviderDefinition } from '../provider/providerDefinition'; import type { ModelRecord } from './model'; import type { ResolvedModelAuthMaterial } from './model.types'; + export interface InspectedAuth { readonly kind: 'apiKey' | 'oauth' | 'none'; readonly apiKey?: string; @@ -63,6 +83,7 @@ export interface ModelInspection { readonly sources: Readonly<Record<string, InspectionSource>>; } + export const TRACE = { configuredModel: 'configuredModel', effectiveModel: 'effectiveModel', @@ -99,6 +120,7 @@ export class ResolutionTraceCollector implements ResolutionTrace { } } + const SECRET_KEY_RE = /api[-_]?key|token|secret|password|authorization/i; export function maskSecret(value: string): string { @@ -118,6 +140,7 @@ export function redactSecrets<T>(value: T): T { return value; } + export function attributeEffectiveFields( trace: ResolutionTraceCollector, configured: ModelRecord, @@ -213,6 +236,7 @@ export function attributeProviderOptions( } } + interface ResolvedModelLike { readonly protocol: Protocol; readonly providerType?: string; diff --git a/packages/agent-core-v2/src/kosong/model/model.ts b/packages/agent-core-v2/src/kosong/model/model.ts index f5cff914c..a32ff5d3d 100644 --- a/packages/agent-core-v2/src/kosong/model/model.ts +++ b/packages/agent-core-v2/src/kosong/model/model.ts @@ -1,3 +1,32 @@ +/** + * `kosong/model` domain — model configuration registry contract. + * + * Owns the `ModelRecord` config record type (id → resolution recipe) and the + * in-memory model registry contract. App-scoped — model configuration is + * global and shared across sessions. Kosong has no persistence — it defines + * types only. Persisting mutations is the upper layer's job, not this + * domain's. + * + * Two configuration paths are supported: + * - **Structured**: `providerId` references an entry in `[providers.*]`. + * Multiple Models can share a Provider (and thus its base URL and auth). + * - **Flat**: `baseUrl` (+ optional inline `apiKey` / `oauth`) is set + * directly on the Model — no `providerId` required. The catalog + * synthesizes a Provider from the baseUrl's origin so multiple Models + * targeting the same host converge on one Provider record at runtime + * (auth comes from the Model itself). + * + * `name` is the wire-facing model identifier sent to the endpoint; `model` is + * the legacy spelling of the same field (at least one is required at resolve + * time). `aliases` is a free-form list of routing keys; callers may request + * "claude-sonnet-4" and the router picks any Model whose name or aliases + * match (many-to-many). + * + * `protocol` names one of the four real wire protocols (no vendor entries — + * a vendor such as `kimi` is expressed as the referenced provider's free-form + * `type`, never as a protocol). + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event, IWaitUntil } from '#/_base/event'; import type { Protocol } from '#/kosong/protocol/protocol'; diff --git a/packages/agent-core-v2/src/kosong/model/model.types.ts b/packages/agent-core-v2/src/kosong/model/model.types.ts index 816b59e1e..d7e8655ad 100644 --- a/packages/agent-core-v2/src/kosong/model/model.types.ts +++ b/packages/agent-core-v2/src/kosong/model/model.types.ts @@ -1,3 +1,25 @@ +/** + * `kosong/model` domain — shared pure-data types no single contract owns. + * + * One home for the small data interfaces that would otherwise each sit in a + * near-empty file: + * - `ModelOverrides` — the resolved `modelOverrides` effective config + * section (populated by the `KIMI_MODEL_*` env overlay). Consumers fold it + * into `ModelRequestParams`: `temperature`/`topP` into `sampling`, + * `thinkingKeep` into the thinking intent, `maxCompletionTokens` into the + * completion budget. Each wire dialect encodes (or drops) the resulting + * intent in its own hooks. + * - `CompletionBudgetConfig` / `CompletionBudgetParams` — the budget knobs + * resolved and folded by the domain's pure budget functions. + * - `ResolvedModelAuthMaterial` — the credential material resolved out of + * the Model → Provider precedence chain. + * - `ThinkingDefaults` / `ModelThinkingMetadata` — the inputs the effective + * thinking effort/keep is resolved from. + * + * Types only — the functions and services that produce or consume them stay + * in their own files. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { OAuthRef } from '../provider/provider'; diff --git a/packages/agent-core-v2/src/kosong/model/modelAuth.ts b/packages/agent-core-v2/src/kosong/model/modelAuth.ts index b53d9a021..e2a923edd 100644 --- a/packages/agent-core-v2/src/kosong/model/modelAuth.ts +++ b/packages/agent-core-v2/src/kosong/model/modelAuth.ts @@ -1,3 +1,25 @@ +/** + * `kosong/model` domain — shared auth-material resolution. + * + * Resolves Model / Provider credential precedence for runtime model + * resolution and auth-readiness probes. Pure computation, outside the + * service graph. + * + * Two deliberate differences from the legacy implementation: + * - The per-protocol env-var fallback table is gone: env-bag credential and + * endpoint resolution goes through the provider-definition registry + * (`resolveProviderEndpoint` against the config env bag). + * - The inferred Anthropic effort profile is reserved for providers whose + * thinking is NOT trait-driven; trait-driven providers — including + * managed models routed through protocol `anthropic` — keep only + * catalog-declared effort metadata. The verdict comes from the registry + * (`drivesThinkingThroughTraits`), not from a vendor string compare. + * The unknown-name fallback within that inference only applies to names + * that still carry a Claude marker (a `claude` substring or a bare family + * word like `sonnet-latest`); clearly non-Claude names served over the + * Anthropic protocol get no synthesized effort metadata. + */ + import { Error2 } from '#/_base/errors/errors'; import { CONFIG_INVALID_ERROR_CODE } from '#/kosong/contract/errors'; import type { ResolutionTrace } from '#/kosong/contract/inspection'; diff --git a/packages/agent-core-v2/src/kosong/model/modelOAuth.ts b/packages/agent-core-v2/src/kosong/model/modelOAuth.ts index 562d00219..eea3c4216 100644 --- a/packages/agent-core-v2/src/kosong/model/modelOAuth.ts +++ b/packages/agent-core-v2/src/kosong/model/modelOAuth.ts @@ -1,3 +1,14 @@ +/** + * `kosong/model` domain — the OAuth token port. + * + * Kosong needs OAuth tokens at model-assembly time: probing the cached + * credential state (catalog listings) and building the refreshable request + * auth closure. The port is owned here so kosong stays free of the + * `app/auth` service; the implementation lives in the upper layer, which + * delegates to `IOAuthService` and owns the `auth.login_required` error + * contract. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { OAuthRef } from '../provider/provider'; diff --git a/packages/agent-core-v2/src/kosong/model/modelRequester.ts b/packages/agent-core-v2/src/kosong/model/modelRequester.ts index c3cafa571..7d2949292 100644 --- a/packages/agent-core-v2/src/kosong/model/modelRequester.ts +++ b/packages/agent-core-v2/src/kosong/model/modelRequester.ts @@ -1,3 +1,16 @@ +/** + * `kosong/model` domain — the `ModelRequester` contract: per-turn input, + * streamed events, and the per-turn intent carrier `ModelRequestParams`. + * + * `ModelRequestParams` is how every per-turn intent reaches the wire: prompt-cache + * key, sampling overrides, thinking effort/keep, and the completion-token + * budget (with its window-clamp companions). It is deliberately dialect-free — + * each wire dialect encodes (or silently drops) an intent in its own hooks. + * The requester maps the params onto `GenerateOptions` 1:1; the fixed overlay + * order inside the bases is `cacheKey → sampling → thinking → + * maxCompletionTokens`. + */ + import type { Message, StreamedMessagePart, VideoURLPart } from '#/kosong/contract/message'; import type { FinishReason, diff --git a/packages/agent-core-v2/src/kosong/model/modelRequesterImpl.ts b/packages/agent-core-v2/src/kosong/model/modelRequesterImpl.ts index 2cc41870e..b22ed1eab 100644 --- a/packages/agent-core-v2/src/kosong/model/modelRequesterImpl.ts +++ b/packages/agent-core-v2/src/kosong/model/modelRequesterImpl.ts @@ -1,3 +1,25 @@ +/** + * `kosong/model` domain — `ModelRequesterImpl`, the request executor. + * + * This is the ONLY production code that calls + * `IProtocolAdapterRegistry.createChatProvider`: it lazily composes exactly + * one immutable ChatProvider per Model (on first use) and caches it for the + * Model's lifetime; every per-turn variation arrives as `ModelRequestParams` and + * is mapped onto `GenerateOptions` (overlay order inside the bases: + * `cacheKey → sampling → thinking → maxCompletionTokens`). + * + * The driver itself turns per-turn input (systemPrompt / tools / messages) + * into the `ModelRequestEvent` stream via the contract's `generate(...)`, measures + * stream timing (`buildStreamTiming`), and owns the auth-refresh replay: a + * 401 against a refreshable (OAuth) auth provider triggers one forced token + * refresh and exactly one replay; a 401 that survives the replay means the + * provider rejected the account itself, so it is surfaced through + * `translateProviderError` as `provider.auth_error` carrying the provider's + * message instead of a misleading re-login prompt. + * + * Constructed by `ModelCatalog` — plain constructor args, no DI. + */ + import { AsyncEventQueue } from '#/_base/asyncEventQueue'; import type { VideoURLPart } from '#/kosong/contract/message'; import { APIStatusError, isAbortError, VideoUploadUnsupportedError } from '#/kosong/contract/errors'; diff --git a/packages/agent-core-v2/src/kosong/model/modelService.ts b/packages/agent-core-v2/src/kosong/model/modelService.ts index e7ff8b75c..b676adafb 100644 --- a/packages/agent-core-v2/src/kosong/model/modelService.ts +++ b/packages/agent-core-v2/src/kosong/model/modelService.ts @@ -1,3 +1,11 @@ +/** + * `kosong/model` domain — `IModelService` implementation. + * + * The in-memory model registry plus the default-model pointer. Holds no + * config dependency: the persistence bridge hydrates it via `loadAll` and + * persists the change events it fires. Bound at App scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -15,6 +23,7 @@ import { const NO_ABORT = new AbortController().signal; +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ModelService extends Disposable implements IModelService { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/kosong/model/thinking.ts b/packages/agent-core-v2/src/kosong/model/thinking.ts index efbe1c57f..cd825044c 100644 --- a/packages/agent-core-v2/src/kosong/model/thinking.ts +++ b/packages/agent-core-v2/src/kosong/model/thinking.ts @@ -1,3 +1,34 @@ +/** + * `kosong/model` domain — the single authority on thinking semantics. + * + * Three kinds of knowledge live here, and nowhere else: + * + * 1. The `thinking` config-section type (`[thinking]`: enabled / effort / + * keep, plus the env-only `forcedEffort` field). Kosong owns only the + * type. + * 2. Effort/keep resolution: pure helpers that fold a requested effort, the + * config defaults, and the model's declared thinking metadata into the + * effective `ThinkingEffort`, and that resolve the thinking-keep value. + * 3. The registry-driven vendor verdicts: `drivesThinkingThroughTraits` + * (definition lookup: the vendor's traits take over thinking encoding) + * and `usesTraitDrivenThinking` (the resolved adapter identity for the + * (protocol, providerType) pair contains a `withThinking` hook). Neither + * hardcodes a vendor or protocol string — trait-driven thinking means + * "thinking is driven by traits", which the registry answers. + * `requiresStrictThinkingValidation` reads the same identity for the + * strict-validation flag. Strict gates only listed-effort validation + * and the `'on'` projection; the always-on clamp is UNCONDITIONAL — a + * model that declares `always_thinking` never resolves to `'off'` on + * any wire (a claimed off state would be a lie, since upstream keeps + * reasoning at its default when no off encoding exists). Unlisted + * concrete efforts stay lenient on compatible transports + * (warn-and-send, `anthropic-thinking-effort-not-listed`) because the + * backend may accept values the local catalog does not list. The + * strict flag is declared by `kimiOpenAITrait` — Kimi's native API + * rejects unlisted efforts — and deliberately NOT by + * `kimiAnthropicTrait`. + */ + import type { ThinkingEffort } from '#/kosong/contract/provider'; import type { IProtocolAdapterRegistry, Protocol } from '#/kosong/protocol/protocol'; @@ -5,6 +36,7 @@ import { getProviderDefinitions } from '../provider/providerDefinition'; import type { ModelThinkingMetadata, ThinkingDefaults } from './model.types'; + export interface ThinkingConfig { enabled?: boolean; effort?: string; @@ -12,6 +44,7 @@ export interface ThinkingConfig { keep?: string; } + export function drivesThinkingThroughTraits(providerType: string | undefined): boolean { if (providerType === undefined) return false; return getProviderDefinitions(providerType).some((definition) => @@ -49,6 +82,7 @@ export function wireHasProtocolThinkingDisable(protocol: string | undefined): bo return protocol === 'anthropic' || protocol === 'kimi'; } + function nonEmpty(value: string | undefined): string | undefined { const trimmed = value?.trim(); return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed; @@ -125,15 +159,6 @@ export function defaultThinkingEffortForModel( return 'on'; } -export function declaredDefaultEffortForModel( - model: ModelThinkingMetadata | undefined, -): ThinkingEffort | undefined { - if (!modelSupportsThinking(model)) return undefined; - const declared = nonEmpty(model?.defaultEffort); - if (declared === undefined) return undefined; - return effortsFor(model).includes(declared) ? (declared as ThinkingEffort) : undefined; -} - export function modelSupportsThinkingEffort( effort: ThinkingEffort, model: ModelThinkingMetadata | undefined, @@ -191,6 +216,7 @@ export function resolveThinkingEffortForModel( return normalizeThinkingEffortForModel(effort, model, strictValidation); } + const KEEP_OFF_VALUES = new Set(['0', 'false', 'no', 'off', 'none', 'null']); type KeepResolution = diff --git a/packages/agent-core-v2/src/kosong/protocol/errors.ts b/packages/agent-core-v2/src/kosong/protocol/errors.ts index 65982dc80..5e3c2c0e1 100644 --- a/packages/agent-core-v2/src/kosong/protocol/errors.ts +++ b/packages/agent-core-v2/src/kosong/protocol/errors.ts @@ -1,3 +1,21 @@ +/** + * `kosong/protocol` domain — wire API failure codes and the boundary + * translation from raw contract errors to coded `Error2`s. + * + * The `ChatProviderError` family is born-coded (see `kosong/contract/errors`): + * every instance already carries its wire code, so `translateProviderError`'s + * `isError2` guard passes it through untouched. What remains here is the + * abort guard and the fallback for errors foreign to the family (plain + * `Error` / unknown thrown values → `internal`). + * + * `translateProviderError`'s FIRST guard is the contract's + * `throwIfAbortError`: a user cancellation is thrown as the standard abort + * DOMException and can never be misclassified as a retryable provider + * failure. The guard throws rather than returns, by design. + * + * Side-effect module: importing registers the error domain. + */ + import { CoreErrors, registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; import { Error2, isError2 } from '#/_base/errors/errors'; import { diff --git a/packages/agent-core-v2/src/kosong/protocol/protocol.ts b/packages/agent-core-v2/src/kosong/protocol/protocol.ts index b0c38f90a..3e44e5ff5 100644 --- a/packages/agent-core-v2/src/kosong/protocol/protocol.ts +++ b/packages/agent-core-v2/src/kosong/protocol/protocol.ts @@ -1,3 +1,25 @@ +/** + * `kosong/protocol` domain — wire protocol identity and the adapter + * registry contract. + * + * A Protocol names a real wire encoding. There are exactly four: every + * vendor-specific behavior that used to pose as a protocol is now expressed + * as per-transport provider definitions (a base protocol plus declarative + * traits) registered with the L2 provider domain, so this enum can never + * grow a vendor entry again. (Vertex AI used to be the fifth entry; it is a + * mode of the `google-genai` base now, enabled through + * `ProtocolProviderOptions` — same wire encoding, different SDK client + * options.) + * + * `IProtocolAdapterRegistry` is the single resolution point for + * "(protocol, providerType) → which base + which traits" and the single + * construction point for composed ChatProviders. The interface speaks only + * L0/L1 types: vendor knowledge (the L2 definition registry) stays in L2 and + * reaches this layer only as resolved, context-bound traits (`ResolvedTrait`). + * + * Bound at App scope. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; diff --git a/packages/agent-core-v2/src/kosong/protocol/protocolBase.ts b/packages/agent-core-v2/src/kosong/protocol/protocolBase.ts index 199800346..72146fb05 100644 --- a/packages/agent-core-v2/src/kosong/protocol/protocolBase.ts +++ b/packages/agent-core-v2/src/kosong/protocol/protocolBase.ts @@ -1,3 +1,16 @@ +/** + * `kosong/protocol` domain — protocol base identity, definition, and + * the module-level base registry. + * + * A protocol base is the component that actually understands one wire + * format: it implements `ChatProvider` and exposes a `hooks?` option through + * which composed traits flow in. The base itself never knows this registry + * exists. + * + * This module only holds the data structures and the registry functions; it + * deliberately registers nothing on its own. + */ + import { BugIndicatingError } from '#/_base/errors/errors'; import type { ModelCapability } from '#/kosong/contract/capability'; import type { ChatProvider } from '#/kosong/contract/provider'; diff --git a/packages/agent-core-v2/src/kosong/protocol/protocolTrait.ts b/packages/agent-core-v2/src/kosong/protocol/protocolTrait.ts index 3670b4a4c..0c2010ef4 100644 --- a/packages/agent-core-v2/src/kosong/protocol/protocolTrait.ts +++ b/packages/agent-core-v2/src/kosong/protocol/protocolTrait.ts @@ -1,3 +1,36 @@ +/** + * `kosong/protocol` domain — the declarative trait surface. + * + * A `ProtocolTrait` is a stateless declaration of how one vendor deviates + * from a wire base: seventeen fully optional hooks plus rare metadata markers + * (non-function fields like `strictThinkingValidation` that qualify how a + * hook's behavior is governed, without adding a code path). A trait declares + * a deviation only where one exists; a hook returning `undefined` always + * means "keep the base default". + * + * Composition rules (the L2 compositors implement them; they are restated + * here because they are part of the trait contract): + * + * - Pipeline hooks (`convertMessage` / `mergeHistory` / `buildParams`) + * chain in trait order, each receiving the previous stage's output. + * `convertMessage` may additionally return `null` to drop the message. + * - Single-value hooks are overwritten in trait order: last declarer wins. + * - `convertError` is consulted by the bases with each RAW failure exactly + * once — the SDK error on HTTP paths, the raw event on in-stream paths — + * after the abort guard (a cancellation never reaches it) and after the + * already-converted `ChatProviderError` pass-through. The hook exists + * because base conversion drops vendor-parsed detail such as the body + * `error.type`/`error.code`; it is where a vendor declares what its own + * wire errors mean (e.g. which 429s are a non-retryable quota + * exhaustion rather than a transient rate limit). + * - `endpoint` / `defaultHeaders` / `provides` are construction-time + * declarations, not per-request hooks. + * + * `TraitContext` carries only `{ config, providerId? }` — never the vendor + * definition object. That is the detail that makes the L1↛L2 layering hold: + * traits see configuration, not registry state. + */ + import type { ModelCapability } from '#/kosong/contract/capability'; import type { ChatProviderError } from '#/kosong/contract/errors'; import type { Message, VideoURLPart } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic-profile.ts b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic-profile.ts index 3f73e9742..ef4a7b1f5 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic-profile.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic-profile.ts @@ -1,3 +1,9 @@ +/** + * `kosong/provider` domain — Anthropic model capability profiles and name + * matching. Matrix source: https://platform.claude.com/docs/en/build-with-claude/effort + * and https://platform.claude.com/docs/en/build-with-claude/extended-thinking. + */ + export type AnthropicThinkingMode = 'budget' | 'adaptive'; export interface AnthropicModelProfile { diff --git a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.contrib.ts b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.contrib.ts index 64fc2d70b..e0d87ecfe 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.contrib.ts @@ -1,3 +1,13 @@ +/** + * `kosong/provider` domain — side-effect module: registers the Anthropic + * Messages base (`id: 'anthropic'`). + * + * The factory aggregates construction-time trait declarations and composes + * the Anthropic hook set. No apiKey suppression is needed here: the + * Anthropic base never reads shell API-key environment variables, so there + * is no base env fallback to suppress. + */ + import { registerProtocolBase } from '#/kosong/protocol/protocolBase'; import { traitDefaultHeaders } from '#/kosong/protocol/protocolTrait'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.ts b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.ts index 77576d00f..5a0cab476 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropic.ts @@ -1,3 +1,27 @@ +/** + * `kosong/provider` domain — Anthropic Messages wire base. + * + * Speaks the Anthropic Messages wire format: system blocks with ephemeral + * cache control, tool-result user blocks, consecutive-user merging, beta + * headers vs the beta endpoint, and the thinking profile matrix (budget vs + * adaptive). + * + * The hook surface is `withThinking` plus `convertError`. `withThinking` + * lets a vendor dialect running over this transport re-encode the thinking + * intent; when the per-turn thinking intent carries `keep`, the BASE + * overlays the context-management edit uniformly on top of whatever + * thinking encoding happened (hook or base path), so a trait never handles + * `keep` itself. + * + * `convertAnthropicError`'s FIRST line is the contract's `throwIfAbortError` + * guard: a user cancellation is THROWN as the standard abort DOMException at + * the very front of the classification chain. After the guard, + * already-converted `ChatProviderError`s pass through untouched; only then is + * the trait-composed `convertError` hook consulted, so a vendor riding this + * transport classifies each RAW SDK failure exactly once before the base + * rules run. + */ + import Anthropic, { APIError as AnthropicAPIError, APIConnectionError as AnthropicConnectionError, @@ -689,6 +713,7 @@ class AnthropicStreamedMessage implements StreamedMessage { const blockEvt = evt as unknown as RawContentBlockStartEvent; const block = blockEvt.content_block; const blockIndex = blockEvt.index; + // eslint-disable-next-line typescript-eslint/switch-exhaustiveness-check switch (block.type) { case 'text': yield { type: 'text', text: block.text }; @@ -718,6 +743,7 @@ class AnthropicStreamedMessage implements StreamedMessage { const deltaEvt = evt as unknown as RawContentBlockDeltaEvent; const delta = deltaEvt.delta; const blockIndex = deltaEvt.index; + // eslint-disable-next-line typescript-eslint/switch-exhaustiveness-check switch (delta.type) { case 'text_delta': yield { type: 'text', text: delta.text }; @@ -1122,7 +1148,6 @@ export class AnthropicChatProvider implements ChatProvider { authToken: null, baseURL: this._baseUrl ?? null, defaultHeaders: this._buildDefaultHeaders(apiKey), - maxRetries: 0, }); } } @@ -1146,6 +1171,7 @@ function applyThinkingKeep( }; } + const CLAUDE_VISION_TOOL_PREFIXES = ['claude-3-', 'claude-3.5-', 'claude-3.7-'] as const; const CLAUDE_THINKING_VISION_TOOL_PREFIXES = [ diff --git a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropicHooks.ts b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropicHooks.ts index 1f266e102..2640f0ca7 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropicHooks.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/anthropicHooks.ts @@ -1,3 +1,14 @@ +/** + * `kosong/provider` domain — the ONLY composition point from resolved + * traits to the Anthropic hook set. + * + * The Anthropic base has two hooks. `withThinking` takes the LAST declarer + * and wraps it with a defensive kwargs copy — so a hook can never mutate base + * state, and a synthetic construction-headers trait (which never declares + * `withThinking`) can never shadow a real dialect hook. `convertError` is the + * shared single-value binding from `traitConvertError` (last declarer wins). + */ + import { traitConvertError, type ResolvedTrait } from '#/kosong/protocol/protocolTrait'; import type { AnthropicHooks } from './anthropic'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/index.ts b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/index.ts index 7c82d9fe9..fc7675f2c 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/anthropic/index.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/anthropic/index.ts @@ -1 +1,6 @@ +/** + * `kosong/provider` domain — registration barrel of the Anthropic wire + * base. Importing this module registers the `anthropic` transport. + */ + import './anthropic.contrib'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.contrib.ts b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.contrib.ts index b9d262469..0a8986c29 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.contrib.ts @@ -1,3 +1,16 @@ +/** + * `kosong/provider` domain — side-effect module: registers the Google + * GenAI base (`id: 'google-genai'`). + * + * The Gemini base carries no hook surface, so the factory only aggregates the + * construction-time declarations. Vertex AI is a mode of this base — not a + * protocol of its own — enabled through the adapter config's + * `providerOptions` (`vertexai` / `project` / `location`), which the factory + * forwards to the SDK client options. The `apiKey ?? ''` guard ensures that + * once a trait declared an endpoint, the base's `GOOGLE_API_KEY` environment + * fallback is suppressed. + */ + import { registerProtocolBase } from '#/kosong/protocol/protocolBase'; import { traitDefaultHeaders } from '#/kosong/protocol/protocolTrait'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.ts b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.ts index b6bc1d5c0..e838a8800 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/google-genai.ts @@ -1,3 +1,18 @@ +/** + * `kosong/provider` domain — Google GenAI (Gemini) wire base. + * + * Speaks the Gemini generateContent wire format (and Vertex AI through the + * same SDK options). This base carries no hook surface today — per-turn + * intents are encoded inline; a cache key has no native field here and is + * silently dropped, which is the intended "dialect decides whether to encode + * an intent" behavior. + * + * The local `createAbortError` copy is DELIBERATELY not deduplicated: this + * module's abort plumbing (abortPromise racing, + * per-chunk checks, the catch guard that rethrows DOMException aborts before + * error conversion) is self-contained by design. + */ + import { ApiError as GoogleApiError, GoogleGenAI as GenAIClient } from '@google/genai'; import { @@ -118,7 +133,9 @@ function applyResponseFormat( ): void { if (format === undefined) return; config['responseMimeType'] = 'application/json'; + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete config['responseSchema']; + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete config['responseJsonSchema']; if (format.type === 'json_schema') { config['responseJsonSchema'] = format.jsonSchema.schema; @@ -423,17 +440,7 @@ export function messagesToGoogleGenAIContents(messages: Message[]): GoogleConten isToolResultOnly: (content) => content.parts.length > 0 && content.parts.every((part) => part.functionResponse !== undefined), - merge: (last, next) => { - const lastStartsWithFunctionResponse = - last.parts[0]?.functionResponse !== undefined; - const nextHasFunctionResponse = next.parts.some( - (part) => part.functionResponse !== undefined, - ); - if (lastStartsWithFunctionResponse && !nextHasFunctionResponse) { - return { ...next, parts: [...next.parts, ...last.parts] }; - } - return { ...last, parts: [...last.parts, ...next.parts] }; - }, + merge: (last, next) => ({ ...last, parts: [...last.parts, ...next.parts] }), }); } @@ -619,12 +626,7 @@ const TIMEOUT_RE = /timed?\s*out|timeout|deadline/i; export function convertGoogleGenAIError(error: unknown): ChatProviderError { if (error instanceof GoogleApiError) { - return normalizeAPIStatusError( - error.status, - error.message, - undefined, - parseRetryInfoDelayMs(error.message), - ); + return normalizeAPIStatusError(error.status, error.message); } if (error instanceof Error) { const msg = error.message; @@ -643,32 +645,6 @@ export function convertGoogleGenAIError(error: unknown): ChatProviderError { return new ChatProviderError(`GoogleGenAI error: ${String(error)}`); } -function parseRetryInfoDelayMs(message: string): number | null { - const jsonStart = message.indexOf('{'); - if (jsonStart < 0) return null; - try { - const body: unknown = JSON.parse(message.slice(jsonStart)); - if (typeof body !== 'object' || body === null) return null; - const details = (body as { error?: { details?: unknown } }).error?.details; - if (!Array.isArray(details)) return null; - for (const detail of details) { - if (typeof detail !== 'object' || detail === null) continue; - const type = (detail as { '@type'?: unknown })['@type']; - if (typeof type !== 'string' || !type.endsWith('google.rpc.RetryInfo')) continue; - const retryDelay = (detail as { retryDelay?: unknown }).retryDelay; - if (typeof retryDelay !== 'string') continue; - const match = /^(\d+(?:\.\d+)?)s$/.exec(retryDelay.trim()); - if (match?.[1] === undefined) continue; - const seconds = Number.parseFloat(match[1]); - if (!Number.isFinite(seconds) || seconds < 0) continue; - return Math.round(seconds * 1000); - } - return null; - } catch { - return null; - } -} - export class GoogleGenAIChatProvider implements ChatProvider { readonly name: string = 'google_genai'; @@ -882,6 +858,7 @@ export class GoogleGenAIChatProvider implements ChatProvider { } } + const GEMINI_CATALOGUED_PREFIXES = [ 'gemini-1.5-pro', 'gemini-1.5-flash', diff --git a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/index.ts b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/index.ts index 47f0cef59..24fc62281 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/google-genai/index.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/google-genai/index.ts @@ -1 +1,6 @@ +/** + * `kosong/provider` domain — registration barrel of the Google GenAI + * wire base. Importing this module registers the `google-genai` transport. + */ + import './google-genai.contrib'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/merge-user-messages.ts b/packages/agent-core-v2/src/kosong/provider/bases/merge-user-messages.ts index 6a3fa5861..ea248a8e3 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/merge-user-messages.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/merge-user-messages.ts @@ -1,3 +1,11 @@ +/** + * `kosong/provider` domain — consecutive same-role history merging. + * + * Shared mechanics for bases whose wire format requires alternating roles: + * folds consecutive user messages into one, never merging a tool-result-only + * message into a following plain user message. + */ + export function mergeConsecutiveUserMessages<T>( messages: readonly T[], mergePolicy: { diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/chat-completions-stream.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/chat-completions-stream.ts index 287c7f9c0..47dbe17c2 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/chat-completions-stream.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/chat-completions-stream.ts @@ -1,3 +1,12 @@ +/** + * `kosong/provider` domain — Chat Completions stream tool-call buffering. + * + * Shared mechanics for the OpenAI-family bases: folds streamed + * `delta.tool_calls` entries into buffered per-index tool calls, emitting a + * `function` header once a concrete name arrives and `tool_call_part` deltas + * for subsequent argument chunks. + */ + import type { StreamedMessagePart, ToolCall } from '#/kosong/contract/message'; export interface ChatCompletionStreamToolFunctionDelta { diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/index.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/index.ts index 383da627d..8d04e9cbd 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/index.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/index.ts @@ -1,2 +1,8 @@ +/** + * `kosong/provider` domain — registration barrel of the OpenAI wire + * bases. Importing this module registers both OpenAI transports — `openai` + * (Chat Completions) and `openai_responses`. + */ + import './openai-legacy.contrib'; import './openai-responses.contrib'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-common.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-common.ts index ea99d7fd7..ac3ddeea1 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-common.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-common.ts @@ -1,3 +1,23 @@ +/** + * `kosong/provider` domain — shared OpenAI-family wire mechanics. + * + * The shared pieces: content-part and tool conversion, usage extraction, + * finish-reason normalization, the capability constants, and the error + * converter. + * + * `convertOpenAIError`'s FIRST line is the contract's `throwIfAbortError` + * guard: a user cancellation (SDK `APIUserAbortError`, bare `AbortError`, the + * standard abort DOMException) is THROWN as the standard abort shape at the + * very front of the classification chain — it can never be converted into, + * nor returned as, a retryable provider error. After the guard, + * already-converted `ChatProviderError`s pass through untouched; only then is + * the optional trait-composed `convertError` hook consulted, so a vendor + * classifies each RAW wire failure (e.g. quota 429s) exactly once before the + * base rules run. The base itself classifies only OpenAI's own documented + * `insufficient_quota` code as a non-retryable quota exhaustion — + * vendor-specific quota signals belong on the vendor's trait. + */ + import { APIConnectionError as OpenAIConnectionError, APIConnectionTimeoutError as OpenAITimeoutError, @@ -224,6 +244,7 @@ export function convertToolMessageContent( .filter((p): p is OpenAIContentPart => p !== null); } + export const OPENAI_REASONING_CAPABILITY = Object.freeze({ image_in: false, video_in: false, diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.contrib.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.contrib.ts index d89429a8e..9e46b197e 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.contrib.ts @@ -1,3 +1,18 @@ +/** + * `kosong/provider` domain — side-effect module: registers the OpenAI + * Chat Completions base (`id: 'openai'`). + * + * The factory is the base side's only contact with the registry world: it + * aggregates the construction-time trait declarations (endpoint, headers, + * `provides`), composes the hook set, and bakes both into the base's options. + * + * Load-bearing detail: when a trait declared an endpoint but neither config + * nor the env chain produced an apiKey, the factory passes `''` — NOT + * `undefined` — so the base constructor's own `OPENAI_API_KEY` environment + * fallback is suppressed. Composing a vendor over this transport can never + * silently pick up an unrelated OpenAI key. + */ + import { registerProtocolBase } from '#/kosong/protocol/protocolBase'; import { traitDefaultHeaders } from '#/kosong/protocol/protocolTrait'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.ts index f2b36111c..5d4bd99e3 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-legacy.ts @@ -1,3 +1,29 @@ +/** + * `kosong/provider` domain — OpenAI Chat Completions wire base. + * + * The base that actually speaks the Chat Completions wire format — and the + * vendor host with the widest hook surface. It knows NOTHING about vendors: + * every vendor deviation arrives as a composed `OpenAIChatCompletionsHooks` + * set baked into `options.hooks` at construction. The hook consumption style + * is uniform — "hook first, `undefined` falls back to the base default". + * + * Per-turn intent assembly (`_resolveRequestKwargs`) applies overlays in the + * fixed contract order: cacheKey → sampling → thinking → maxCompletionTokens. + * The context-window clamp on the completion budget (floor 1) runs BEFORE any + * hook and cannot be skipped; the 128k ceiling clamp can be taken over by the + * `withMaxCompletionTokens` hook. + * + * Two load-bearing behaviors: + * + * - When `hooks.withThinking` EXISTS, the history-scanning auto-enable of + * `reasoning_effort` (issue #1616) is disabled entirely — once a trait + * takes over thinking encoding the base must not interfere. + * - When `hooks.convertMessage` EXISTS ("trait mode"), the base's + * tool-result `extract_text` fallback and tool-declaration-only skip are + * handed over to the trait wholesale: every history message is + * base-converted, post-processed by the hook, and dropped on `null`. + */ + import OpenAI from 'openai'; import { parseTraceId, type ChatProviderError } from '#/kosong/contract/errors'; @@ -54,6 +80,7 @@ import { } from '../request-auth'; import { normalizeToolCallIdsForProvider, sanitizeToolCallId } from '../tool-call-id'; + const CHAT_COMPLETIONS_MAX_OUTPUT_TOKENS_CEILING = 128 * 1024; export const OPENAI_CHAT_TOOL_CALL_ID_POLICY: ToolCallIdPolicy = { @@ -119,7 +146,7 @@ export interface OpenAILegacyGenerationKwargs { interface OpenAIMessage { role: string; - content?: string | OpenAIContentPart[] | null | undefined; + content?: string | OpenAIContentPart[] | undefined; tool_calls?: OpenAIToolCallOut[] | undefined; tool_call_id?: string | undefined; name?: string | undefined; @@ -241,19 +268,6 @@ function convertMessage( result.tool_call_id = message.toolCallId; } - if ( - message.role === 'assistant' && - hasReasoningPart && - result.content === undefined && - result.tool_calls === undefined - ) { - result.content = ''; - } - - if (message.role === 'assistant' && result.content === undefined) { - result.content = null; - } - if (hasReasoningPart || (preserveThinking && message.role === 'assistant')) { result[reasoningKey] = reasoningContent; } @@ -716,6 +730,7 @@ export class OpenAILegacyChatProvider implements ChatProvider { for (const key of Object.keys(kwargs)) { if (kwargs[key] === undefined) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete kwargs[key]; } } @@ -736,7 +751,6 @@ export class OpenAILegacyChatProvider implements ChatProvider { const clientOpts: Record<string, unknown> = { apiKey, baseURL: this._baseUrl, - maxRetries: 0, }; const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, auth?.headers); if (defaultHeaders !== undefined) { @@ -749,6 +763,7 @@ export class OpenAILegacyChatProvider implements ChatProvider { } } + export function getOpenAILegacyModelCapability(modelName: string) { const normalized = modelName.toLowerCase(); if (isOpenAIReasoningModel(normalized)) { diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.contrib.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.contrib.ts index 6a12e1802..6ca01d883 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.contrib.ts @@ -1,3 +1,13 @@ +/** + * `kosong/provider` domain — side-effect module: registers the OpenAI + * Responses base (`id: 'openai_responses'`). + * + * The factory aggregates the endpoint, applies `provides` under explicit + * config, composes headers — and passes `apiKey ?? ''` to suppress the + * base's `OPENAI_API_KEY` environment fallback once a trait declared an + * endpoint. + */ + import { registerProtocolBase } from '#/kosong/protocol/protocolBase'; import { traitConvertError, traitDefaultHeaders } from '#/kosong/protocol/protocolTrait'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.ts index 19808bc2f..89e3219de 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openai-responses.ts @@ -1,3 +1,18 @@ +/** + * `kosong/provider` domain — OpenAI Responses API wire base. + * + * Speaks the Responses wire format: `input` items, `instructions`, + * `reasoning` blocks with encrypted content, and the native + * `prompt_cache_key` field (a cache key is encoded directly — no hook + * needed). Per-turn intents are encoded inline in the fixed contract order; + * the base's only hook surface is the trait-composed `convertError` option, + * consulted with each raw failure exactly once — the SDK error on HTTP + * paths, the raw event on in-stream error paths — before the base's own + * classification (already-converted errors crossing an outer catch pass + * through without re-consulting). The developer-role model detection lives + * here. + */ + import OpenAI from 'openai'; import { Error2 } from '#/_base/errors/errors'; @@ -1115,6 +1130,7 @@ export class OpenAIResponsesChatProvider implements ChatProvider { } const reasoningEffort = kwargs['reasoning_effort'] as string | undefined; + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete kwargs['reasoning_effort']; if (reasoningEffort !== undefined) { @@ -1127,6 +1143,7 @@ export class OpenAIResponsesChatProvider implements ChatProvider { for (const key of Object.keys(kwargs)) { if (kwargs[key] === undefined) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete kwargs[key]; } } @@ -1186,7 +1203,6 @@ export class OpenAIResponsesChatProvider implements ChatProvider { const clientOpts: Record<string, unknown> = { apiKey, baseURL: this._baseUrl, - maxRetries: 0, }; const defaultHeaders = mergeRequestHeaders(this._defaultHeaders, auth?.headers); if (defaultHeaders !== undefined) { @@ -1199,6 +1215,7 @@ export class OpenAIResponsesChatProvider implements ChatProvider { } } + export function getOpenAIResponsesModelCapability(modelName: string) { const normalized = modelName.toLowerCase(); if (isOpenAIReasoningModel(normalized)) { diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/openaiHooks.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/openaiHooks.ts index a1a512491..8c584db6e 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/openaiHooks.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/openaiHooks.ts @@ -1,3 +1,21 @@ +/** + * `kosong/provider` domain — the ONLY composition point from resolved + * traits to the OpenAI Chat Completions hook set, plus the construction-time + * declaration aggregators. + * + * Composition rules: + * + * - Pipeline hooks (`convertMessage` / `mergeHistory` / `buildParams`) chain + * in trait order, each stage receiving the previous stage's output; + * `convertMessage` returning `null` at any stage drops the message. + * - Single-value hooks are bound in trait order — last declarer wins. + * - `endpoint` / `provides` are construction-time declarations, aggregated + * separately (`traitEndpoint` / `traitProvides`); they never enter the + * hook set. + * - Zero declared per-request hooks → `undefined`, so the base bypasses all + * hook logic. + */ + import type { GenerateOptions, VideoUploadInput } from '#/kosong/contract/provider'; import type { Tool } from '#/kosong/contract/tool'; import type { ProtocolEndpoint, ResolvedTrait } from '#/kosong/protocol/protocolTrait'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/openai/reasoning-key.ts b/packages/agent-core-v2/src/kosong/provider/bases/openai/reasoning-key.ts index 064c4402c..86e6474fd 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/openai/reasoning-key.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/openai/reasoning-key.ts @@ -1,3 +1,21 @@ +/** + * The OpenAI-compatible Chat Completions ecosystem never standardized a wire + * field for reasoning/thinking content. Three names circulate in the wild: + * + * - `reasoning_content` — DeepSeek's original convention, used by the Moonshot + * Kimi API, pre-rename vLLM, and most OpenAI-compatible gateways. + * - `reasoning_details` — OpenRouter. + * - `reasoning` — OpenAI's GPT-OSS guidance; current vLLM renamed to this + * (vllm-project/vllm#27752) and its request side accepts ONLY this name + * (vllm-project/vllm#38488). + * + * Inbound we accept any of them via a priority scan; outbound we echo back the + * dialect the peer actually spoke, learned per endpoint by ReasoningKeyDialect. + */ + +// Inbound scan order; the first entry doubles as the default outbound dialect +// before any observation. Both arms can be pinned by an explicit key (see +// ReasoningKeyDialect). export const KNOWN_REASONING_KEYS = [ 'reasoning_content', 'reasoning_details', diff --git a/packages/agent-core-v2/src/kosong/provider/bases/request-auth.ts b/packages/agent-core-v2/src/kosong/provider/bases/request-auth.ts index 5d3495c98..aac18b0c7 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/request-auth.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/request-auth.ts @@ -1,3 +1,12 @@ +/** + * `kosong/provider` domain — per-request auth resolution for the bases. + * + * A base caches a construction-time client when an apiKey is available; a + * per-request `ProviderRequestAuth` (OAuth token, extra headers) rebuilds the + * client for that call. `requireProviderApiKey` is the single "no credential" + * failure — it never invents a key from a vendor-specific source. + */ + import { ChatProviderError } from '#/kosong/contract/errors'; import type { ProviderRequestAuth } from '#/kosong/contract/provider'; diff --git a/packages/agent-core-v2/src/kosong/provider/bases/tool-call-id.ts b/packages/agent-core-v2/src/kosong/provider/bases/tool-call-id.ts index d6b174bce..5a059a544 100644 --- a/packages/agent-core-v2/src/kosong/provider/bases/tool-call-id.ts +++ b/packages/agent-core-v2/src/kosong/provider/bases/tool-call-id.ts @@ -1,3 +1,11 @@ +/** + * `kosong/provider` domain — tool-call id rewrite machinery. + * + * The shared `ToolCallIdPolicy` implementation: id sanitization plus + * history-wide id normalization that rewrites every `toolCalls[].id` / + * `toolCallId` pair consistently and keeps rewritten ids unique. + */ + import { BugIndicatingError } from '#/_base/errors/errors'; import type { Message, ToolCall } from '#/kosong/contract/message'; import type { ToolCallIdPolicy } from '#/kosong/contract/provider'; diff --git a/packages/agent-core-v2/src/kosong/provider/protocolAdapterRegistry.ts b/packages/agent-core-v2/src/kosong/provider/protocolAdapterRegistry.ts index ef5f601ea..8309c6815 100644 --- a/packages/agent-core-v2/src/kosong/provider/protocolAdapterRegistry.ts +++ b/packages/agent-core-v2/src/kosong/provider/protocolAdapterRegistry.ts @@ -1,3 +1,29 @@ +/** + * `kosong/provider` domain — the single production implementation of + * `IProtocolAdapterRegistry`. + * + * This is the one resolution point for "(protocol, providerType) → which base + * + which traits" and the single construction point for composed + * ChatProviders: + * + * - `resolveAdapterIdentity` — the two branches: a `(providerType, + * protocol)` pair registration → the protocol as base with that + * registration's traits; no pair registration (unregistered vendor, no + * providerType, or the vendor does not run over this protocol) → the + * protocol itself as base with no vendor traits. The config + * `defaultHeaders` synthetic trait is ALWAYS appended last, so config + * headers win header aggregation; it declares no per-request hooks, so it + * can never shadow a real trait hook in composition. + * - `createChatProvider` — re-binds every resolved trait's context to the + * full adapter config (identity resolution knows only + * `(protocol, providerType)`; composition needs the real config) and + * delegates to the registered base's contrib factory. + * - `resolveCapability` — the fixed fallback chain: trait capability hooks + * (last declarer wins) → the base's own catalog → `UNKNOWN_CAPABILITY`. + * + * Bound at App scope, eager. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/kosong/provider/provider.ts b/packages/agent-core-v2/src/kosong/provider/provider.ts index e6436506d..5257a07a3 100644 --- a/packages/agent-core-v2/src/kosong/provider/provider.ts +++ b/packages/agent-core-v2/src/kosong/provider/provider.ts @@ -1,3 +1,22 @@ +/** + * `kosong/provider` domain — the provider configuration contract. + * + * A Provider is the "endpoint + model-enumeration mechanism" boundary: it + * carries the concrete `baseUrl`, any custom HTTP headers, and — through + * `modelSource` — declares how the runtime should discover the Models it + * serves (static list from `[models.*]`, `/v1/models` discovery, or an + * OAuth-managed catalog). + * + * `ProviderType` is deliberately free-form text: vendor identity is NOT + * enumerated at the type level. Validation happens at resolve time against + * the provider-definition registry, which is what allows external packages + * to register new vendors without touching this contract. + * + * Owns the `ProviderConfig` / `OAuthRef` types and the in-memory provider + * registry contract; App-scoped. Kosong has no persistence — it defines + * types only. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event, IWaitUntil } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/kosong/provider/providerDefinition.ts b/packages/agent-core-v2/src/kosong/provider/providerDefinition.ts index 4ad5dac46..2e9f99cca 100644 --- a/packages/agent-core-v2/src/kosong/provider/providerDefinition.ts +++ b/packages/agent-core-v2/src/kosong/provider/providerDefinition.ts @@ -1,3 +1,22 @@ +/** + * `kosong/provider` domain — the provider-definition registry. + * + * A `ProviderDefinition` is the declarative answer to "who is this vendor and + * where do its key/url come from": the protocol base this registration + * composes with, its deviation traits (applying to that protocol only), its + * endpoint fallback chain, how much of the host's request headers it + * receives, and how its models are discovered. Registration happens once per + * vendor × protocol pair: a vendor running over several transports registers + * one definition per protocol. Vendor-level facts (endpoint, host headers, + * model source) are declared identically on every registration of the same id + * via shared constants, so id-level queries can read any of them. + * + * `resolveProviderEndpoint` is the single authority on the endpoint fallback + * chain: definition-level `endpoint` first, otherwise the aggregation of the + * definition's trait endpoint hooks, resolved against a caller-supplied env + * bag (defaulting to `process.env`). + */ + import { BugIndicatingError } from '#/_base/errors/errors'; import type { Protocol, ProtocolAdapterConfig } from '#/kosong/protocol/protocol'; import type { diff --git a/packages/agent-core-v2/src/kosong/provider/providerService.ts b/packages/agent-core-v2/src/kosong/provider/providerService.ts index 1bfd4b61d..fb6a81590 100644 --- a/packages/agent-core-v2/src/kosong/provider/providerService.ts +++ b/packages/agent-core-v2/src/kosong/provider/providerService.ts @@ -1,3 +1,11 @@ +/** + * `kosong/provider` domain — `IProviderService` implementation. + * + * The in-memory provider registry plus the default-provider pointer. Holds no + * config dependency: the persistence bridge hydrates it via `loadAll` and + * persists the change events it fires. Bound at App scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -15,6 +23,7 @@ import { const NO_ABORT = new AbortController().signal; +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class ProviderService extends Disposable implements IProviderService { declare readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-errors.ts b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-errors.ts index aa3dbce5f..49d137e58 100644 --- a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-errors.ts +++ b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-errors.ts @@ -1,3 +1,25 @@ +/** + * `kosong/provider` domain — Kimi vendor error classification. + * + * This module owns the vendor-specific knowledge of how the Moonshot backend + * signals quota/balance exhaustion on a 429: the structured body + * `error.type`/`error.code` value `exceeded_current_quota_error`, and the + * observed billing wordings for gateways that flatten the body to text + * ("You exceeded your current token quota: … please check your account + * balance", "Your account … is suspended due to insufficient balance, please + * recharge your account …", and arrears phrasing). Every pattern is anchored + * to billing wording — deliberately no bare /quota/ or /balance/, so + * transient throttle messages like "token quota per minute" keep classifying + * as retryable rate limits. The classifier reads the raw SDK error + * structurally (status / code / type / message), so it works over both the + * OpenAI and Anthropic transports: the OpenAI SDK hoists + * the body's `error.code`/`error.type` to the top level, while the Anthropic + * SDK keeps the full body on `.error` (`{type: 'error', error: {type}}`), so + * candidate codes are collected from `error` → `.error` → `.error.error`. + * Anything not positively recognized answers `undefined`, keeping the base + * classification. + */ + import { APIProviderQuotaExhaustedError, parseRetryAfterMs, diff --git a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-files.ts b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-files.ts index 138068ee9..50a4ffa95 100644 --- a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-files.ts +++ b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-files.ts @@ -1,3 +1,13 @@ +/** + * `kosong/provider` domain — Kimi files API client. + * + * Uploads a video (from a filesystem path or in-memory bytes) to the Kimi + * files endpoint and returns the `ms://<file-id>` video URL part the wire + * messages reference. Upload failures classify through the Kimi quota + * classifier (this client runs outside any composed hook context), falling + * back to the base OpenAI conversion. + */ + import { Blob, File } from 'node:buffer'; import * as fs from 'node:fs'; import * as path from 'node:path'; diff --git a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-schema.ts b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-schema.ts index 74d1ed637..acc7645be 100644 --- a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-schema.ts +++ b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi-schema.ts @@ -1,3 +1,15 @@ +/** + * `kosong/provider` domain — Kimi tool-schema dialect normalization. + * + * Pure functions: dereference local `$ref` pointers by inlining definitions, + * then complete missing `type` fields from enum/const values or structural + * keys — the schema dialect the Kimi tool endpoint accepts. + * + * Circular references are detected and left as `$ref` to avoid infinite + * recursion; in that case the referenced definition bucket is preserved so the + * remaining local `$ref` pointers stay resolvable to a JSON Schema validator. + */ + import { Error2 } from '#/_base/errors/errors'; import { ProtocolErrors } from '#/kosong/protocol/errors'; diff --git a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi.contrib.ts b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi.contrib.ts index 7c609c92a..a2406817d 100644 --- a/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/providers/kimi/kimi.contrib.ts @@ -1,3 +1,84 @@ +/** + * `kosong/provider` domain — side-effect module: the Kimi vendor + * registration, one definition per transport Kimi runs over, each driven by + * a single trait object. + * + * Kimi is not a wire protocol — it is a set of vendor registrations: + * + * - `(kimi, openai)`, driven by `kimiOpenAITrait`, declaring every deviation + * from the OpenAI base on Kimi's native transport: + * - request params: the `KIMI_API_KEY` / `KIMI_BASE_URL` endpoint + * fallback chain and the default base URL; `cacheKey` → + * `prompt_cache_key`; `withThinking` → `extra_body.thinking` + * (`{ type: 'disabled' | 'enabled', effort? }`, carrying the per-turn + * `keep` when present); `withMaxCompletionTokens` → + * `max_completion_tokens` with NO 128k ceiling (the base's window + * clamp has already run; the trait takes over the ceiling); and + * `buildParams` (the last hook before send) backfills `max_tokens` → + * `max_completion_tokens`, drops `max_tokens`, and expands + * `extra_body` into the top-level params; + * - `strictThinkingValidation` (a metadata marker, not a hook — the v1 + * parity contract): Kimi's native API rejects thinking efforts the + * model metadata does not list, so client-side validation must be + * strict when this trait drives thinking; + * - tools: `convertTool` emits `$`-prefixed tool names as + * `builtin_function` declarations; every other tool goes through the + * base OpenAI conversion with its parameters normalized into the Kimi + * schema dialect (`normalizeKimiToolSchema`); + * - messages: `convertMessage` post-processes each base-converted wire + * message — assistant tool-call messages whose content is effectively + * empty drop the `content` field entirely, `tool_calls[].extras` + * round-trips from the contract message into the wire shape (the base + * conversion never emits `extras`), and message-level `tools` + * declarations are embedded into the message; + * - reasoning: the trait deliberately does NOT pin `reasoningKey` — the + * base auto-detects the endpoint's reasoning dialect from inbound + * responses (`reasoning_content` by default, `reasoning` on newer vLLM) + * and echoes that field on outbound replay; operator config + * (`reasoning_key`) or a trait declaration still pins when present. + * `preserveThinking` force-replays the field in a `keep: 'all'` session + * with thinking not disabled — it reads the already-seeded request + * kwargs (the thinking config `withThinking` just encoded), so it + * decides per request, not per instance; + * - usage: `extractUsage` finds the usage payload of a Kimi stream chunk + * either at the top level (the base's default location) or inside + * `choices[0].usage`; returning `undefined` defers to the base default + * when neither position carries one; + * - errors: `convertError` classifies Moonshot's quota/balance-exhausted + * 429s (structured `exceeded_current_quota_error` type/code, billing + * wordings) as the non-retryable `APIProviderQuotaExhaustedError` via + * `classifyKimiQuotaError`, before the base's own classification would + * mint a retryable rate limit; + * - video upload: `uploadVideo` uploads through the Kimi files API + * (`KimiFiles`), memoized per trait context with a + * WeakMap — one composition (one resolved ctx) gets one files client, + * derived from the same endpoint fallback chain the trait declares; + * - `(kimi, anthropic)`, driven by `kimiAnthropicTrait`: the thinking intent + * is encoded as `thinking: { type: 'enabled' }` plus + * `output_config.effort`, and the interleaved-thinking beta is stripped + * from the seeded beta list. The `keep` dimension needs no trait handling + * — the Anthropic base overlays the context-management edit itself. The + * trait declares the same `convertError` quota classification as the + * OpenAI registration (the classifier reads the SDK error structurally, + * so it is transport-agnostic). It deliberately does NOT declare + * `strictThinkingValidation`: over this foreign transport the backend may + * accept efforts the local catalog metadata does not list, so client-side + * validation stays lenient (warning + pass-through). + * + * Vendor-level facts — the endpoint fallback chain, full host-header + * forwarding, and OAuth-catalog model discovery — are shared constants + * declared identically on both registrations, so id-level queries read + * either one. Kimi declares no vendor-level capability: model capabilities + * come from the catalog, not from client-side tables (Kimi model ids never + * match the protocol bases' builtin catalogs, so the detected layer answers + * UNKNOWN on its own). + * + * Deliberately absent (do not reintroduce): a 64-char tool-call-id policy + * (the base default is identical), an extra-body deep-merge morph, and a + * vendor-specific provider `name` (the composed provider's name is the + * base's `'openai'`). + */ + import type { ContentPart } from '#/kosong/contract/message'; import type { Tool } from '#/kosong/contract/tool'; import type { @@ -156,6 +237,7 @@ export const kimiOpenAITrait: ProtocolTrait = { if (message.role === 'assistant' && message.toolCalls.length > 0) { const nonThinkParts = message.content.filter((part) => part.type !== 'think'); if (isEffectivelyEmptyContent(nonThinkParts)) { + // eslint-disable-next-line @typescript-eslint/no-dynamic-delete delete converted['content']; } } diff --git a/packages/agent-core-v2/src/kosong/provider/providers/standard.contrib.ts b/packages/agent-core-v2/src/kosong/provider/providers/standard.contrib.ts index 6e075737f..6f11a40f5 100644 --- a/packages/agent-core-v2/src/kosong/provider/providers/standard.contrib.ts +++ b/packages/agent-core-v2/src/kosong/provider/providers/standard.contrib.ts @@ -1,3 +1,34 @@ +/** + * ⚠ PHASE 4 GAP PATCH — additive lower-layer fill-in, clearly marked. + * + * `kosong/provider` domain — side-effect module: endpoint-only provider + * definitions for the four canonical vendors. + * + * Only the Kimi vendor definition existed before, so endpoint resolution + * answered for `kimi` alone and the legacy config-env-bag fallbacks + * (`[providers.x.env] OPENAI_API_KEY=…` etc.) had no registry home. Endpoint + * resolution now goes through the definition registry — hardcoded + * per-protocol env tables are abolished — so the four canonical vendors each + * need a definition that declares their env chain. These declarations change + * nothing else: each vendor's `baseProtocol` equals its protocol id and + * (Google GenAI aside, see below) the trait list is empty, so adapter + * identity, hook composition, and capability resolution are exactly as they + * were for an unregistered vendor. + * + * No `defaultBaseUrl` is declared: construction-time defaults stay where they + * always were (inside the bases / their SDKs), matching the legacy env-only + * fallback semantics precisely. + * + * Google GenAI is the one definition with non-empty traits: Vertex AI is a + * `providerOptions` mode of the `google-genai` base rather than a vendor of + * its own, and two one-line endpoint traits keep the legacy vertex chain + * precedence — `VERTEXAI_API_KEY` / `GOOGLE_VERTEX_BASE_URL` first, + * `GOOGLE_API_KEY` / `GOOGLE_GEMINI_BASE_URL` as fallback — while plain + * Gemini users without the vertex envs see exactly the old behavior. + * + * Like every contrib, this module is imported for effect only. + */ + import { registerProviderDefinition } from '../providerDefinition'; registerProviderDefinition({ diff --git a/packages/agent-core-v2/src/kosong/recordDiff.ts b/packages/agent-core-v2/src/kosong/recordDiff.ts index 60c697601..ddf9bce0b 100644 --- a/packages/agent-core-v2/src/kosong/recordDiff.ts +++ b/packages/agent-core-v2/src/kosong/recordDiff.ts @@ -1,3 +1,12 @@ +/** + * kosong internal — record-level diffing for the provider/model registries. + * + * `diffRecords` computes the added/removed/changed keys between two snapshots + * of a record-shaped registry state, `deepEqual` is the value comparison it + * uses. Pure functions, used to keep change events quiet when a write lands + * an equal value. + */ + export interface RecordDiff { readonly added: readonly string[]; readonly removed: readonly string[]; diff --git a/packages/agent-core-v2/src/mcpCore/client-http.ts b/packages/agent-core-v2/src/mcpCore/client-http.ts index cba0f9162..91971685e 100644 --- a/packages/agent-core-v2/src/mcpCore/client-http.ts +++ b/packages/agent-core-v2/src/mcpCore/client-http.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — Streamable HTTP transport MCP client. + */ + import { ErrorCodes, Error2 } from '#/errors'; import type { McpServerHttpConfig } from './config-schema'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; @@ -15,7 +19,6 @@ import { type UnexpectedCloseReason, } from './client-shared'; import { buildMcpRemoteHeaders } from './client-remote'; -import { createMcpOAuthFetch } from './oauth/provider'; import type { MCPClient, MCPToolDefinition, MCPToolResult } from './types'; export interface HttpMcpClientOptions { @@ -48,7 +51,7 @@ export class HttpMcpClient implements MCPClient { this.transport = new StreamableHTTPClientTransport(new URL(config.url), { requestInit: headers !== undefined ? { headers } : undefined, - fetch: createMcpOAuthFetch(options.oauthProvider, options.fetch), + fetch: options.fetch, authProvider: options.oauthProvider, }); this.client = new Client({ diff --git a/packages/agent-core-v2/src/mcpCore/client-remote.ts b/packages/agent-core-v2/src/mcpCore/client-remote.ts index 8ca292abd..80f271d73 100644 --- a/packages/agent-core-v2/src/mcpCore/client-remote.ts +++ b/packages/agent-core-v2/src/mcpCore/client-remote.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — remote (HTTP/SSE) server config guards and request-header builders. + */ + import type { McpRemoteServerConfig, McpServerConfig } from './config-schema'; import { ErrorCodes, Error2 } from '#/errors'; diff --git a/packages/agent-core-v2/src/mcpCore/client-shared.ts b/packages/agent-core-v2/src/mcpCore/client-shared.ts index 55937fa8d..6d2ead018 100644 --- a/packages/agent-core-v2/src/mcpCore/client-shared.ts +++ b/packages/agent-core-v2/src/mcpCore/client-shared.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — shared MCP client helpers — request options, liveness probes, result conversion. + */ + import { getCoreVersion } from '#/_base/version'; import { ErrorCode, McpError } from '@modelcontextprotocol/sdk/types.js'; diff --git a/packages/agent-core-v2/src/mcpCore/client-sse.ts b/packages/agent-core-v2/src/mcpCore/client-sse.ts index d490a09bf..0084e4b31 100644 --- a/packages/agent-core-v2/src/mcpCore/client-sse.ts +++ b/packages/agent-core-v2/src/mcpCore/client-sse.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — SSE transport MCP client. + */ + import { ErrorCodes, Error2 } from '#/errors'; import type { McpServerSseConfig } from './config-schema'; import { Client } from '@modelcontextprotocol/sdk/client/index.js'; @@ -15,7 +19,6 @@ import { type UnexpectedCloseReason, } from './client-shared'; import { buildMcpRemoteHeaders } from './client-remote'; -import { createMcpOAuthFetch } from './oauth/provider'; import type { MCPClient, MCPToolDefinition, MCPToolResult } from './types'; export interface SseMcpClientOptions { @@ -48,7 +51,7 @@ export class SseMcpClient implements MCPClient { this.transport = new SSEClientTransport(new URL(config.url), { requestInit: headers !== undefined ? { headers } : undefined, - fetch: createMcpOAuthFetch(options.oauthProvider, options.fetch), + fetch: options.fetch, authProvider: options.oauthProvider, }); this.client = new Client({ diff --git a/packages/agent-core-v2/src/mcpCore/client-stdio.ts b/packages/agent-core-v2/src/mcpCore/client-stdio.ts index 7a45e1ece..7f81f3964 100644 --- a/packages/agent-core-v2/src/mcpCore/client-stdio.ts +++ b/packages/agent-core-v2/src/mcpCore/client-stdio.ts @@ -1,12 +1,13 @@ -import { Client } from '@modelcontextprotocol/sdk/client/index.js'; -import { ReadBuffer, serializeMessage } from '@modelcontextprotocol/sdk/shared/stdio.js'; -import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js'; -import type { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js'; +/** + * `mcpCore` domain — stdio transport MCP client. + */ import { ErrorCodes, Error2 } from '#/errors'; -import type { IHostProcess } from '#/os/interface/hostProcess'; -import type { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; +import type { McpServerStdioConfig } from './config-schema'; import { proxyEnvForChild, reconcileChildNoProxy } from '#/_base/utils/proxy'; +import { Client } from '@modelcontextprotocol/sdk/client/index.js'; +import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js'; +import { isAbsolute, resolve } from 'pathe'; import { buildRequestOptions, @@ -18,7 +19,6 @@ import { type UnexpectedCloseListener, type UnexpectedCloseReason, } from './client-shared'; -import type { McpServerStdioConfig } from './config-schema'; import type { MCPClient, MCPToolDefinition, MCPToolResult } from './types'; export interface StdioMcpClientOptions { @@ -27,16 +27,13 @@ export interface StdioMcpClientOptions { readonly startupTimeoutMs?: number; readonly toolCallTimeoutMs?: number; readonly defaultCwd?: string; - readonly runtimeResolver: IRuntimeResolver; - readonly workspaceId: string; - readonly runtimeId: string; } const STDERR_BUFFER_CAPACITY = 4 * 1024; export class StdioMcpClient implements MCPClient { private readonly client: Client; - private readonly transport: RuntimeStdioTransport; + private readonly transport: StdioClientTransport; private readonly startupTimeoutMs?: number; private readonly toolCallTimeoutMs?: number; private readonly stderrBuffer = new BoundedTail(STDERR_BUFFER_CAPACITY); @@ -50,11 +47,20 @@ export class StdioMcpClient implements MCPClient { static readonly stderrBufferCapacity = STDERR_BUFFER_CAPACITY; - constructor(config: McpServerStdioConfig, options: StdioMcpClientOptions) { + constructor(config: McpServerStdioConfig, options: StdioMcpClientOptions = {}) { if (config.executor !== undefined && config.executor !== 'local') { throw new Error2(ErrorCodes.NOT_IMPLEMENTED, `MCP stdio executor '${config.executor}' is not yet implemented`); } - this.transport = new RuntimeStdioTransport(config, options, this.stderrBuffer); + this.transport = new StdioClientTransport({ + command: config.command, + args: config.args, + env: mergeStdioEnv(config.env), + cwd: resolveStdioCwd(config.cwd, options.defaultCwd), + stderr: 'pipe', + }); + this.transport.stderr?.on('data', (chunk: Buffer | string) => { + this.stderrBuffer.push(typeof chunk === 'string' ? chunk : chunk.toString('utf8')); + }); this.client = new Client({ name: options.clientName ?? KIMI_MCP_CLIENT_NAME, version: options.clientVersion ?? KIMI_MCP_CLIENT_VERSION, @@ -157,122 +163,6 @@ export class StdioMcpClient implements MCPClient { } } -class RuntimeStdioTransport implements Transport { - onclose?: () => void; - onerror?: (error: Error) => void; - onmessage?: <T extends JSONRPCMessage>(message: T) => void; - private readonly readBuffer = new ReadBuffer(); - private process: IHostProcess | undefined; - private lease: ReturnType<IRuntimeResolver['acquire']> | undefined; - private started = false; - private closed = false; - - constructor( - private readonly config: McpServerStdioConfig, - private readonly options: StdioMcpClientOptions, - private readonly stderr: BoundedTail, - ) {} - - async start(): Promise<void> { - if (this.started) throw new Error('Runtime stdio transport is already started'); - if (this.closed) throw new Error('Runtime stdio transport is closed'); - this.started = true; - const lease = this.options.runtimeResolver.acquire( - { workspaceId: this.options.workspaceId, runtimeId: this.options.runtimeId }, - ['process'], - ); - this.lease = lease; - try { - const base = lease.runtime.path.resolve(this.options.defaultCwd ?? lease.runtime.environment.homeDir); - const cwd = this.config.cwd === undefined ? base : lease.runtime.path.resolve(base, this.config.cwd); - const process = lease.track(await lease.runtime.process!.spawn( - this.config.command, - this.config.args, - { cwd, env: mergeStdioEnv(this.config.env) }, - )); - this.process = process; - lease.track(this); - process.stdin.on('error', (error: Error) => this.onerror?.(error)); - process.stdout.on('data', (chunk: Buffer | string) => this.onData(chunk)); - process.stdout.on('end', () => this.finish()); - process.stdout.on('error', (error: Error) => this.onerror?.(error)); - process.stderr.on('data', (chunk: Buffer | string) => { - this.stderr.push(typeof chunk === 'string' ? chunk : chunk.toString('utf8')); - }); - process.stderr.on('error', (error: Error) => this.onerror?.(error)); - void process.wait().then( - () => this.finish(), - (error: unknown) => { - this.onerror?.(error instanceof Error ? error : new Error(String(error))); - this.finish(); - }, - ); - } catch (error) { - this.lease = undefined; - lease.dispose(); - throw error; - } - } - - async send(message: JSONRPCMessage): Promise<void> { - const process = this.process; - if (process === undefined || this.closed) throw new Error('Runtime stdio transport is not running'); - const data = serializeMessage(message); - await new Promise<void>((resolve, reject) => { - process.stdin.write(data, (error) => { - if (error !== null && error !== undefined) reject(error); - else resolve(); - }); - }); - } - - dispose(): Promise<void> { - return this.close(); - } - - async close(): Promise<void> { - if (this.closed) return; - this.closed = true; - const process = this.process; - this.process = undefined; - if (process !== undefined) { - try { - await process.kill(); - } catch {} - void process.dispose(); - } - this.readBuffer.clear(); - const lease = this.lease; - this.lease = undefined; - lease?.dispose(); - this.onclose?.(); - } - - private onData(chunk: Buffer | string): void { - this.readBuffer.append(typeof chunk === 'string' ? Buffer.from(chunk) : chunk); - while (true) { - try { - const message = this.readBuffer.readMessage(); - if (message === null) return; - this.onmessage?.(message); - } catch (error) { - this.onerror?.(error instanceof Error ? error : new Error(String(error))); - } - } - } - - private finish(): void { - if (this.closed) return; - this.closed = true; - this.process = undefined; - this.readBuffer.clear(); - const lease = this.lease; - this.lease = undefined; - lease?.dispose(); - this.onclose?.(); - } -} - class BoundedTail { private buffer = ''; constructor(private readonly capacity: number) {} @@ -289,6 +179,12 @@ class BoundedTail { } } +function resolveStdioCwd(configCwd: string | undefined, defaultCwd: string | undefined): string | undefined { + if (configCwd === undefined) return defaultCwd; + if (defaultCwd !== undefined && !isAbsolute(configCwd)) return resolve(defaultCwd, configCwd); + return configCwd; +} + export function mergeStdioEnv( configEnv?: Record<string, string>, parentEnv: Readonly<Record<string, string | undefined>> = process.env, diff --git a/packages/agent-core-v2/src/mcpCore/config-schema.ts b/packages/agent-core-v2/src/mcpCore/config-schema.ts index 83afa8c70..d96f509e6 100644 --- a/packages/agent-core-v2/src/mcpCore/config-schema.ts +++ b/packages/agent-core-v2/src/mcpCore/config-schema.ts @@ -1,3 +1,17 @@ +/** + * `mcpCore` domain — MCP server configuration schemas. + * + * Owns the `McpServerConfig` schema and its transport variants. These describe + * the shape of MCP server entries as they appear in configuration (whether in + * `config.toml` or an MCP-specific config file). + * + * Remote variants accept `auth: "oauth"`, mirroring v1: OAuth is still + * discovered from a remote server's 401 response; the flag records that the + * user explicitly chose OAuth, so static `headers` on the same entry are + * treated as plain request headers (capability/identity declarations) rather + * than as the server's credentials. + */ + import { z } from 'zod'; const StringRecordSchema = z.record(z.string(), z.string()); @@ -20,7 +34,6 @@ export const McpServerStdioConfigSchema = z.object({ env: StringRecordSchema.optional(), cwd: z.string().optional(), executor: z.enum(['local', 'kaos']).optional(), - runtime_id: z.string().min(1).optional(), ...McpServerCommonFields, }); diff --git a/packages/agent-core-v2/src/mcpCore/configView.ts b/packages/agent-core-v2/src/mcpCore/configView.ts deleted file mode 100644 index f9dcd95ef..000000000 --- a/packages/agent-core-v2/src/mcpCore/configView.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type { McpServerConfig } from './config-schema'; - -export type McpServerConfigView = - | (Omit<Extract<McpServerConfig, { readonly transport: 'stdio' }>, 'env'> & { - readonly envKeys?: readonly string[]; - }) - | (Omit<Exclude<McpServerConfig, { readonly transport: 'stdio' }>, 'headers'> & { - readonly headerKeys?: readonly string[]; - }); - -export function toMcpServerConfigView(config: McpServerConfig): McpServerConfigView { - if (config.transport === 'stdio') { - const { env, ...safe } = config; - return env === undefined ? safe : { ...safe, envKeys: Object.keys(env).toSorted() }; - } - const { headers, ...safe } = config; - return headers === undefined ? safe : { ...safe, headerKeys: Object.keys(headers).toSorted() }; -} diff --git a/packages/agent-core-v2/src/mcpCore/connection-manager.ts b/packages/agent-core-v2/src/mcpCore/connection-manager.ts index 72a94554c..854d73e18 100644 --- a/packages/agent-core-v2/src/mcpCore/connection-manager.ts +++ b/packages/agent-core-v2/src/mcpCore/connection-manager.ts @@ -1,8 +1,28 @@ +/** + * `mcpCore` domain — `McpConnectionManager`, the workspace-shared MCP + * server connection orchestrator. + * + * Owns the configured MCP servers and their runtime clients: connects + * (stdio / SSE / HTTP), discovers and registers tools, attaches the OAuth + * provider when tokens are present, flips failing servers into `needs-auth` + * on 401, and reconnects after authentication. Applies per-server settings + * over the configured defaults and emits status changes to subscribers. + * + * `resolveClientName` supplies the name announced to servers during initialize + * (and the OAuth dynamic-registration label), consulted per connection so an + * identity configured after construction still applies; omitted, or resolving + * to `undefined`, keeps the built-in name. + * + * A server whose config disappears is tombstoned (`markRemoved`): the + * client is closed but the entry stays with status `removed` so consumers + * holding its tools can fail calls with a clear notice, until a same-named + * `connect` replaces it or `shutdown` clears everything. + */ + import { ErrorCodes, Error2 } from '#/errors'; import type { McpServerConfig } from './config-schema'; import type { ILogger as Logger } from '#/_base/log/log'; import type { Tool } from '#/kosong/contract/tool'; -import { HostProcessError, HostProcessErrorCode } from '#/os/interface/hostProcess'; import { abortable } from '#/_base/utils/abort'; import { HttpMcpClient } from './client-http'; @@ -37,6 +57,12 @@ interface InternalEntry { export type McpStatusListener = (entry: McpServerEntry) => void; +/** + * The consumer surface of a connection manager. `McpConnectionManager` + * implements it directly; the session domain's `MergedMcpConnectionView` + * implements it over a workspace manager plus a session overlay, so session + * and agent consumers never care which manager owns a server. + */ export interface McpConnectionView { readonly oauthService: McpOAuthService | undefined; list(): readonly McpServerEntry[]; @@ -78,10 +104,6 @@ export interface McpDefaultTimeouts { export interface McpConnectionManagerOptions { readonly envLookup?: (name: string) => string | undefined; readonly stdioCwd?: string; - readonly runtimeResolver?: import('#/workspace/workspaceInstance/workspaceInstanceManager').IRuntimeResolver; - readonly workspaceId?: string; - readonly runtimeId?: string; - readonly requireStdioRuntimeId?: boolean; readonly oauthService?: McpOAuthService; readonly log?: Logger; readonly resolveDefaultTimeouts?: () => McpDefaultTimeouts; @@ -179,12 +201,6 @@ export class McpConnectionManager implements McpConnectionView { async connect(name: string, config: McpServerConfig): Promise<void> { const previous = this.entries.get(name); if (previous !== undefined) { - if ( - (previous.status === 'pending' || previous.status === 'connected') && - mcpServerConfigsEqual(previous.config, config) - ) { - return; - } await this.closeClient(previous); } const disabled = config.enabled === false; @@ -291,12 +307,6 @@ export class McpConnectionManager implements McpConnectionView { return work; } - async reconnectAfterCurrent(name: string): Promise<void> { - const existing = this.inFlightReconnects.get(name); - if (existing !== undefined) await existing.catch(() => undefined); - await this.reconnectAndJoin(name); - } - async shutdown(): Promise<void> { const entries = Array.from(this.entries.values()); this.entries.clear(); @@ -387,20 +397,11 @@ export class McpConnectionManager implements McpConnectionView { config.toolTimeoutMs ?? this.options.resolveDefaultTimeouts?.().toolTimeoutMs; const clientName = this.options.resolveClientName?.(); if (config.transport === 'stdio') { - const runtimeResolver = this.options.runtimeResolver; - const workspaceId = this.options.workspaceId; - const runtimeId = config.runtime_id ?? this.options.runtimeId; - if (runtimeResolver === undefined || workspaceId === undefined || runtimeId === undefined || (this.options.requireStdioRuntimeId === true && config.runtime_id === undefined)) { - throw new Error('MCP stdio requires runtime_id and runtime binding'); - } return new StdioMcpClient(config, { startupTimeoutMs, toolCallTimeoutMs, defaultCwd: this.options.stdioCwd, clientName, - runtimeResolver, - workspaceId, - runtimeId, }); } if (config.transport === 'sse') { @@ -531,12 +532,7 @@ function isUnauthorizedLikeError(error: unknown): boolean { } function formatStartupError(error: unknown, client: RuntimeMcpClient | undefined): string { - const source = error instanceof HostProcessError && - error.code === HostProcessErrorCode.SpawnFailed && - error.cause instanceof Error - ? error.cause - : error; - const base = source instanceof Error ? source.message : String(source); + const base = error instanceof Error ? error.message : String(error); const tail = stderrTail(client); if (tail === undefined) return base; return `${base}\nstderr: ${tail}`; @@ -561,24 +557,6 @@ function stderrTail(client: RuntimeMcpClient | undefined): string | undefined { return snapshot.trimEnd(); } -export function mcpServerConfigsEqual(a: McpServerConfig, b: McpServerConfig): boolean { - return stableConfigJson(a) === stableConfigJson(b); -} - -function stableConfigJson(value: unknown): string { - if (Array.isArray(value)) { - return `[${value.map(stableConfigJson).join(',')}]`; - } - if (typeof value === 'object' && value !== null) { - const entries = Object.entries(value) - .filter(([, entryValue]) => entryValue !== undefined) - .map(([key, entryValue]) => `${JSON.stringify(key)}:${stableConfigJson(entryValue)}`) - .toSorted(); - return `{${entries.join(',')}}`; - } - return JSON.stringify(value) ?? 'undefined'; -} - async function withTimeout<T>( promise: Promise<T>, timeoutMs: number, diff --git a/packages/agent-core-v2/src/mcpCore/errors.ts b/packages/agent-core-v2/src/mcpCore/errors.ts index 6d987e9be..d8d32bd2d 100644 --- a/packages/agent-core-v2/src/mcpCore/errors.ts +++ b/packages/agent-core-v2/src/mcpCore/errors.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const McpErrors = { diff --git a/packages/agent-core-v2/src/mcpCore/oauth/callback-server.ts b/packages/agent-core-v2/src/mcpCore/oauth/callback-server.ts index 215ca3b14..5cbcf1467 100644 --- a/packages/agent-core-v2/src/mcpCore/oauth/callback-server.ts +++ b/packages/agent-core-v2/src/mcpCore/oauth/callback-server.ts @@ -1,3 +1,14 @@ +/** + * `mcpCore` domain — one-shot localhost OAuth callback listener. + * + * `startCallbackServer()` binds 127.0.0.1 on a random free port and returns a + * handle exposing the resulting `redirect_uri` and an awaitable + * `waitForCode()` that resolves with `{ code, state }` from the first + * `/callback` request. Any subsequent requests get a generic 404 and a + * non-callback path is ignored. The server is closed automatically once a + * code has been delivered (or `close()` is called explicitly). + */ + import { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http'; import type { AddressInfo } from 'node:net'; @@ -12,13 +23,6 @@ export interface CallbackServer { close(): Promise<void>; } -export class OAuthCallbackClosedError extends Error { - constructor() { - super('OAuth callback listener closed'); - this.name = 'OAuthCallbackClosedError'; - } -} - const SUCCESS_HTML = '<!doctype html><html><head><meta charset="utf-8"><title>Authorized' + '' + @@ -36,29 +40,12 @@ const ERROR_HTML = export async function startCallbackServer(): Promise { let resolveCode: ((value: CallbackResult) => void) | undefined; let rejectCode: ((reason: Error) => void) | undefined; - let cleanupWait: (() => void) | undefined; - let outcome: - | { readonly status: 'pending' } - | { readonly status: 'resolved'; readonly value: CallbackResult } - | { readonly status: 'rejected'; readonly reason: Error } = { status: 'pending' }; + let settled = false; - const settle = ( - next: - | { readonly status: 'resolved'; readonly value: CallbackResult } - | { readonly status: 'rejected'; readonly reason: Error }, - ) => { - if (outcome.status !== 'pending') return; - outcome = next; - cleanupWait?.(); - cleanupWait = undefined; - if (next.status === 'resolved') { - resolveCode?.(next.value); - } else { - rejectCode?.(next.reason); - } - resolveCode = undefined; - rejectCode = undefined; - void closeServer(); + const settle = (fn: () => void) => { + if (settled) return; + settled = true; + fn(); }; const server: Server = createServer((req, res) => { @@ -85,26 +72,26 @@ export async function startCallbackServer(): Promise { if (errorParam !== null) { const description = url.searchParams.get('error_description') ?? ''; res.writeHead(400, { 'content-type': 'text/html; charset=utf-8' }).end(ERROR_HTML); - settle({ - status: 'rejected', - reason: new Error( - `OAuth error: ${errorParam}${description ? ` — ${description}` : ''}`, - ), + settle(() => { + rejectCode?.( + new Error(`OAuth error: ${errorParam}${description ? ` — ${description}` : ''}`), + ); }); return; } const code = url.searchParams.get('code'); if (code === null || code.length === 0) { res.writeHead(400, { 'content-type': 'text/html; charset=utf-8' }).end(ERROR_HTML); - settle({ - status: 'rejected', - reason: new Error('OAuth callback missing authorization code'), + settle(() => { + rejectCode?.(new Error('OAuth callback missing authorization code')); }); return; } const state = url.searchParams.get('state') ?? undefined; res.writeHead(200, { 'content-type': 'text/html; charset=utf-8' }).end(SUCCESS_HTML); - settle({ status: 'resolved', value: { code, state } }); + settle(() => { + resolveCode?.({ code, state }); + }); } await new Promise((resolve, reject) => { @@ -117,49 +104,44 @@ export async function startCallbackServer(): Promise { const port = (server.address() as AddressInfo).port; const redirectUri = `http://127.0.0.1:${port}/callback`; - let closeServerPromise: Promise | undefined; - const closeServer = (): Promise => { - closeServerPromise ??= new Promise((resolve) => { + let closed = false; + const close = async () => { + if (closed) return; + closed = true; + await new Promise((resolve) => { server.close(() => { resolve(); }); }); - return closeServerPromise; - }; - const close = async () => { - settle({ status: 'rejected', reason: new OAuthCallbackClosedError() }); - await closeServer(); }; const waitForCode: CallbackServer['waitForCode'] = ({ signal, timeoutMs } = {}) => { return new Promise((resolve, reject) => { - if (outcome.status === 'resolved') { - resolve(outcome.value); - return; - } - if (outcome.status === 'rejected') { - reject(outcome.reason); - return; - } - let timer: NodeJS.Timeout | undefined; const onAbort = () => { - settle({ - status: 'rejected', - reason: + settle(() => + rejectCode?.( signal?.reason instanceof Error ? signal.reason : new Error('OAuth flow aborted'), - }); + ), + ); }; const cleanup = () => { if (timer !== undefined) clearTimeout(timer); signal?.removeEventListener('abort', onAbort); }; - cleanupWait = cleanup; - resolveCode = resolve; - rejectCode = reject; + resolveCode = (value) => { + cleanup(); + void close(); + resolve(value); + }; + rejectCode = (reason) => { + cleanup(); + void close(); + reject(reason); + }; if (timeoutMs !== undefined) { timer = setTimeout(() => { - settle({ status: 'rejected', reason: new Error('OAuth callback timed out') }); + settle(() => rejectCode?.(new Error('OAuth callback timed out'))); }, timeoutMs); } if (signal !== undefined) { diff --git a/packages/agent-core-v2/src/mcpCore/oauth/provider.ts b/packages/agent-core-v2/src/mcpCore/oauth/provider.ts index 08e7139ef..58b1928bf 100644 --- a/packages/agent-core-v2/src/mcpCore/oauth/provider.ts +++ b/packages/agent-core-v2/src/mcpCore/oauth/provider.ts @@ -1,19 +1,45 @@ +/** + * `mcpCore` domain — `McpOAuthClientProvider`, the `OAuthClientProvider` + * backed by the MCP OAuth credential store (`McpOAuthStore` over + * `IAtomicDocumentStore`). + * + * One provider instance per server/resource identity. It persists OAuth + * tokens, the registered DCR client info, and discovery state under + * `/credentials/mcp/-*.json` via the store; captures the + * authorization URL when the SDK calls `redirectToAuthorization`; and keeps + * the PKCE verifier and OAuth `state` in-memory. Persisted values are + * mirrored into in-memory caches loaded eagerly on construction (`ready`) so + * the SDK's synchronous `redirectUrl` / `clientMetadata` getters read without + * blocking, while the data methods `await ready` before reading or writing. + * The provider does not open browsers or run servers — it is the + * persistence + flow-state shim. + * + * `invalidateStaleRegistration` guards interactive flows: the callback + * listener binds a random port per flow while a DCR registration pins the + * redirect URIs of the flow that created it, so a reused registration whose + * URIs no longer cover the current callback would be rejected at the + * authorization endpoint ("invalid redirect URI", rendered only in the + * user's browser). Dropping it lets `auth()` re-register. + * + * `clientName` is the product token for the default label + * (` ()`), carrying the configured custom identity; it + * is ignored when `clientLabel` states the whole label explicitly. + */ + import { randomBytes } from 'node:crypto'; +import { BugIndicatingError } from '#/errors'; + import type { OAuthClientProvider, OAuthDiscoveryState, } from '@modelcontextprotocol/sdk/client/auth.js'; -import { - OAuthTokensSchema, - type OAuthClientInformationFull, - type OAuthClientInformationMixed, - type OAuthClientMetadata, - type OAuthTokens, +import type { + OAuthClientInformationFull, + OAuthClientInformationMixed, + OAuthClientMetadata, + OAuthTokens, } from '@modelcontextprotocol/sdk/shared/auth.js'; -import { OAuthTokenTransaction } from '@moonshot-ai/kimi-code-oauth'; - -import { BugIndicatingError } from '#/errors'; import { KIMI_MCP_CLIENT_NAME } from '../client-shared'; import { canonicalMcpOAuthResource, mcpOAuthStoreKey, type McpOAuthStore } from './store'; @@ -21,103 +47,49 @@ import { canonicalMcpOAuthResource, mcpOAuthStoreKey, type McpOAuthStore } from const TOKENS_SUFFIX = '-tokens.json'; const CLIENT_SUFFIX = '-client.json'; const DISCOVERY_SUFFIX = '-discovery.json'; -export const META_SUFFIX = '-meta.json'; const PASSIVE_REDIRECT_URI = 'http://127.0.0.1:3118/callback'; -export interface StoredMcpOAuthTokens extends OAuthTokens { - readonly obtained_at?: number; -} - -export interface McpOAuthStoreMeta { - readonly serverName: string; - readonly serverUrl: string; -} - export interface McpOAuthProviderOptions { readonly serverName: string; readonly serverUrl: string | URL; readonly store: McpOAuthStore; readonly clientLabel?: string; readonly clientName?: string; - readonly now?: () => number; - readonly onTokensSaved?: (tokens: StoredMcpOAuthTokens) => void; - readonly onCredentialsInvalidated?: ( - scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery', - ) => void; - readonly track?: (operation: Promise) => void; } export class McpOAuthClientProvider implements OAuthClientProvider { readonly storeKey: string; readonly serverUrl: string; readonly ready: Promise; - private readonly serverName: string; private readonly store: McpOAuthStore; private readonly clientLabel: string; - private readonly onTokensSaved: McpOAuthProviderOptions['onTokensSaved']; - private readonly onCredentialsInvalidated: McpOAuthProviderOptions['onCredentialsInvalidated']; - private readonly now: () => number; private _redirectUrl: URL | undefined; private _codeVerifier: string | undefined; private _state: string | undefined; private _lastAuthorizationUrl: URL | undefined; - private readonly tokenTransaction: OAuthTokenTransaction; private clientCache: OAuthClientInformationMixed | undefined; + private tokensCache: OAuthTokens | undefined; private discoveryCache: OAuthDiscoveryState | undefined; constructor(options: McpOAuthProviderOptions) { this.serverUrl = canonicalMcpOAuthResource(options.serverUrl); this.storeKey = mcpOAuthStoreKey(options.serverName, this.serverUrl); - this.serverName = options.serverName; this.store = options.store; this.clientLabel = options.clientLabel ?? `${options.clientName ?? KIMI_MCP_CLIENT_NAME} (${options.serverName})`; - this.onTokensSaved = options.onTokensSaved; - this.onCredentialsInvalidated = options.onCredentialsInvalidated; - this.now = options.now ?? Date.now; - const tokensFile = `${this.storeKey}${TOKENS_SUFFIX}`; - const metaFile = `${this.storeKey}${META_SUFFIX}`; - this.tokenTransaction = new OAuthTokenTransaction({ - key: this.storeKey, - read: async () => this.store.read(tokensFile), - write: async (tokens) => { - const incoming = tokens as StoredMcpOAuthTokens; - await this.store.write(tokensFile, { - ...incoming, - obtained_at: incoming.obtained_at ?? this.now(), - }); - }, - remove: async () => { - await this.store.remove(tokensFile); - }, - parse: (value) => OAuthTokensSchema.safeParse(value).data, - normalize: (tokens) => OAuthTokensSchema.safeParse(tokens).data ?? tokens, - track: options.track, - afterCommit: async (tokens) => { - if (tokens === undefined) { - await this.store.remove(metaFile); - return; - } - const meta: McpOAuthStoreMeta = { serverName: this.serverName, serverUrl: this.serverUrl }; - await this.store.write(metaFile, meta); - const stamped: StoredMcpOAuthTokens = { - ...tokens, - obtained_at: (tokens as StoredMcpOAuthTokens).obtained_at ?? this.now(), - }; - this.onTokensSaved?.(stamped); - }, - }); this.ready = this.load(); } private async load(): Promise { - const [client, discovery] = await Promise.all([ + const [client, tokens, discovery] = await Promise.all([ this.store.read(`${this.storeKey}${CLIENT_SUFFIX}`), + this.store.read(`${this.storeKey}${TOKENS_SUFFIX}`), this.store.read(`${this.storeKey}${DISCOVERY_SUFFIX}`), ]); this.clientCache = client; + this.tokensCache = tokens; this.discoveryCache = discovery; } @@ -167,20 +139,18 @@ export class McpOAuthClientProvider implements OAuthClientProvider { } async saveClientInformation(info: OAuthClientInformationMixed): Promise { - await this.store.write(`${this.storeKey}${CLIENT_SUFFIX}`, info); this.clientCache = info; + await this.store.write(`${this.storeKey}${CLIENT_SUFFIX}`, info); } async tokens(): Promise { - return this.store.read(`${this.storeKey}${TOKENS_SUFFIX}`); + await this.ready; + return this.tokensCache; } async saveTokens(tokens: OAuthTokens): Promise { - await this.tokenTransaction.save(tokens); - } - - createOAuthFetch(fetchFn: typeof fetch = globalThis.fetch): typeof fetch { - return this.tokenTransaction.createFetch(fetchFn); + this.tokensCache = tokens; + await this.store.write(`${this.storeKey}${TOKENS_SUFFIX}`, tokens); } redirectToAuthorization(url: URL): void { @@ -199,8 +169,8 @@ export class McpOAuthClientProvider implements OAuthClientProvider { } async saveDiscoveryState(state: OAuthDiscoveryState): Promise { - await this.store.write(`${this.storeKey}${DISCOVERY_SUFFIX}`, state); this.discoveryCache = state; + await this.store.write(`${this.storeKey}${DISCOVERY_SUFFIX}`, state); } async discoveryState(): Promise { @@ -215,50 +185,32 @@ export class McpOAuthClientProvider implements OAuthClientProvider { const uris = info.redirect_uris; if (!Array.isArray(uris) || uris.length === 0) return false; if (uris.includes(redirectUri)) return false; - await this.clearCredentials('client'); + await this.invalidateCredentials('client'); return true; } async invalidateCredentials( scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery', - ): Promise { - if (scope !== 'tokens' && scope !== 'all') { - await this.clearCredentials(scope); - return; - } - const tokensInvalidated = await this.tokenTransaction.invalidateFromSdk(scope); - if (!tokensInvalidated) return; - if (scope === 'all') { - await this.clearCredentials('client'); - await this.clearCredentials('discovery'); - this._codeVerifier = undefined; - } - this.onCredentialsInvalidated?.(scope); - } - - async clearCredentials( - scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery', ): Promise { if (scope === 'verifier') { this._codeVerifier = undefined; - this.onCredentialsInvalidated?.(scope); return; } if (scope === 'tokens' || scope === 'all') { - await this.tokenTransaction.clear(); + this.tokensCache = undefined; + await this.store.remove(`${this.storeKey}${TOKENS_SUFFIX}`); } if (scope === 'client' || scope === 'all') { - await this.store.remove(`${this.storeKey}${CLIENT_SUFFIX}`); this.clientCache = undefined; + await this.store.remove(`${this.storeKey}${CLIENT_SUFFIX}`); } if (scope === 'discovery' || scope === 'all') { - await this.store.remove(`${this.storeKey}${DISCOVERY_SUFFIX}`); this.discoveryCache = undefined; + await this.store.remove(`${this.storeKey}${DISCOVERY_SUFFIX}`); } if (scope === 'all') { this._codeVerifier = undefined; } - this.onCredentialsInvalidated?.(scope); } private effectiveRedirectUri(): string { @@ -275,10 +227,3 @@ function registeredRedirectUri(info: OAuthClientInformationMixed | undefined): s const [redirectUri] = info.redirect_uris; return redirectUri; } - -export function createMcpOAuthFetch( - provider: OAuthClientProvider | undefined, - fetchFn: typeof fetch | undefined, -): typeof fetch | undefined { - return provider instanceof McpOAuthClientProvider ? provider.createOAuthFetch(fetchFn) : fetchFn; -} diff --git a/packages/agent-core-v2/src/mcpCore/oauth/service.ts b/packages/agent-core-v2/src/mcpCore/oauth/service.ts index 0315485fe..0e27e0fbe 100644 --- a/packages/agent-core-v2/src/mcpCore/oauth/service.ts +++ b/packages/agent-core-v2/src/mcpCore/oauth/service.ts @@ -1,42 +1,43 @@ +/** + * `mcpCore` domain — `McpOAuthService`, the per-process OAuth orchestrator + * for MCP HTTP servers. + * + * Owns one {@link McpOAuthClientProvider} per server/resource and mediates the + * synthetic `mcp____authenticate` tool flow: + * + * 1. `getProvider(serverName, serverUrl)` returns the cached provider. It is + * only attached when the server has no static bearer token configured + * **and** the provider has stored tokens for that same server URL — + * first-time connections that lack tokens skip the provider entirely so a + * 401 surfaces as `UnauthorizedError` from the transport instead of being + * swallowed by an in-flight `auth()` attempt. + * 2. `beginAuthorization(serverName, serverUrl)` spins up a one-shot + * localhost callback listener, sets the redirect URL on the provider, + * and drives the SDK `auth()` orchestrator forward until it surfaces an + * authorization URL. It returns that URL plus a `complete()` callback + * that finishes the code exchange once the user finishes the browser + * flow. + * 3. After `complete()` resolves successfully the provider has tokens on + * disk; the caller (the synthetic tool) drives a manager-level + * `reconnect` to swap the synthetic tool out for the real MCP tools. + * + * `resolveClientName` supplies the product token for provider default labels, + * consulted per provider so an identity configured after this service is + * constructed still applies. + */ + import { auth, type OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js'; -import type { ILogger as Logger } from '#/_base/log/log'; import { ErrorCodes, Error2, isError2 } from '#/errors'; import { startCallbackServer, type CallbackServer } from './callback-server'; -import { - META_SUFFIX, - McpOAuthClientProvider, - type McpOAuthStoreMeta, - type StoredMcpOAuthTokens, -} from './provider'; -import { canonicalMcpOAuthResource, mcpOAuthStoreKey, type McpOAuthStore } from './store'; - -const defaultLog: Logger = { - error: () => {}, - warn: () => {}, - info: () => {}, - debug: () => {}, - child: () => defaultLog, -}; +import { McpOAuthClientProvider } from './provider'; +import { mcpOAuthStoreKey, type McpOAuthStore } from './store'; export interface McpOAuthServiceOptions { readonly store: McpOAuthStore; readonly clientLabel?: string; readonly resolveClientName?: () => string | undefined; - readonly log?: Logger; - readonly scheduler?: McpOAuthScheduler; - readonly authRequestTimeoutMs?: number; - readonly shutdownDrainTimeoutMs?: number; -} - -export interface McpOAuthScheduledTask { - cancel(): void; -} - -export interface McpOAuthScheduler { - now(): number; - schedule(delayMs: number, task: () => void | Promise): McpOAuthScheduledTask; } export interface BeginAuthorizationOptions { @@ -49,95 +50,29 @@ export interface BeginAuthorizationResult { cancel(): Promise; } -interface SharedAuthorizationFlow { - readonly attach: () => BeginAuthorizationResult; - readonly cancelUnderlying: () => Promise; -} - -interface ActiveAuthorization { - readonly started: Promise; - readonly controller: AbortController; - readonly serverRef: { current: CallbackServer | undefined }; -} - -export type McpOAuthEvent = - | { - readonly type: 'tokens-saved'; - readonly serverName: string; - readonly serverUrl: string; - } - | { - readonly type: 'tokens-invalidated'; - readonly serverName: string; - readonly serverUrl: string; - readonly scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'; - } - | { - readonly type: 'refresh-failed'; - readonly serverName: string; - readonly serverUrl: string; - readonly error: string; - }; - -export type McpOAuthEventListener = (event: McpOAuthEvent) => void; - -export interface McpOAuthTokenState { - readonly hasTokens: boolean; - readonly hasRefreshToken: boolean; - readonly expiresAt?: number; - readonly expired: boolean; -} - -const REFRESH_AHEAD_MS = 120_000; -const MAX_TIMER_DELAY_MS = 0x7fffffff; -const DEFAULT_AUTH_REQUEST_TIMEOUT_MS = 30_000; -const DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS = 30_000; - -const defaultScheduler: McpOAuthScheduler = { - now: () => Date.now(), - schedule: (delayMs, task) => { - const timer = setTimeout(() => void task(), delayMs); - timer.unref(); - return { cancel: () => clearTimeout(timer) }; - }, -}; - export class McpOAuthService { private readonly store: McpOAuthStore; private readonly clientLabel: string | undefined; private readonly resolveClientName: (() => string | undefined) | undefined; - private readonly log: Logger; - private readonly scheduler: McpOAuthScheduler; - private readonly authRequestTimeoutMs: number; - private readonly shutdownDrainTimeoutMs: number; private readonly providers = new Map(); - private readonly listeners = new Set(); - private readonly refreshes = new Map>(); - private readonly refreshTimers = new Map(); - private readonly activeAuthorizations = new Map(); - private readonly backgroundTasks = new Set>(); - private shuttingDown = false; - private shutdownPromise: Promise | undefined; constructor(options: McpOAuthServiceOptions) { this.store = options.store; this.clientLabel = options.clientLabel; this.resolveClientName = options.resolveClientName; - this.log = options.log ?? defaultLog; - this.scheduler = options.scheduler ?? defaultScheduler; - this.authRequestTimeoutMs = options.authRequestTimeoutMs ?? DEFAULT_AUTH_REQUEST_TIMEOUT_MS; - this.shutdownDrainTimeoutMs = options.shutdownDrainTimeoutMs ?? DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS; - } - - dispose(): Promise { - return this.shutdown(); } getProvider(serverName: string, serverUrl: string | URL): McpOAuthClientProvider { const storeKey = mcpOAuthStoreKey(serverName, serverUrl); let provider = this.providers.get(storeKey); if (provider === undefined) { - provider = this.createProvider(serverName, serverUrl); + provider = new McpOAuthClientProvider({ + serverName, + serverUrl, + store: this.store, + clientLabel: this.clientLabel, + clientName: this.resolveClientName?.(), + }); this.providers.set(provider.storeKey, provider); } return provider; @@ -147,199 +82,20 @@ export class McpOAuthService { return (await this.getProvider(serverName, serverUrl).tokens()) !== undefined; } - async tokenState(serverName: string, serverUrl: string | URL): Promise { - const tokens = (await this.getProvider(serverName, serverUrl).tokens()) as - | StoredMcpOAuthTokens - | undefined; - if (tokens === undefined) { - return { hasTokens: false, hasRefreshToken: false, expired: false }; - } - const expiresAt = - typeof tokens.obtained_at === 'number' && typeof tokens.expires_in === 'number' - ? tokens.obtained_at + tokens.expires_in * 1000 - : undefined; - return { - hasTokens: true, - hasRefreshToken: typeof tokens.refresh_token === 'string' && tokens.refresh_token.length > 0, - expiresAt, - expired: expiresAt !== undefined && this.scheduler.now() >= expiresAt, - }; - } - - onEvent(listener: McpOAuthEventListener): () => void { - this.listeners.add(listener); - return () => { - this.listeners.delete(listener); - }; - } - - protected trackBackgroundTask(task: Promise): void { - this.backgroundTasks.add(task); - void task.then( - () => this.backgroundTasks.delete(task), - () => this.backgroundTasks.delete(task), - ); - } - - async refresh(serverName: string, serverUrl: string | URL): Promise { - const storeKey = mcpOAuthStoreKey(serverName, serverUrl); - const existing = this.refreshes.get(storeKey); - if (existing !== undefined) return existing; - if (this.shuttingDown) { - throw new Error2(ErrorCodes.MCP_OAUTH_FAILED, 'MCP OAuth service is shutting down'); - } - const task = this.refreshNow(serverName, serverUrl).finally(() => { - this.refreshes.delete(storeKey); - }); - this.refreshes.set(storeKey, task); - return task; - } - - async sweepProactiveRefresh(): Promise { - if (this.shuttingDown) return; - const keys = await this.store.list(); - for (const key of keys) { - if (this.shuttingDown) return; - if (!key.endsWith(META_SUFFIX)) continue; - const meta = await readStoreMeta(this.store, key, this.log); - if (meta === undefined) continue; - try { - const state = await this.tokenState(meta.serverName, meta.serverUrl); - if (!state.hasTokens || !state.hasRefreshToken || state.expiresAt === undefined) continue; - this.scheduleRefresh(meta.serverName, meta.serverUrl, state.expiresAt); - } catch (error) { - this.log.warn('skipping MCP OAuth credential during proactive-refresh sweep', { - file: key, - error: error instanceof Error ? error : String(error), - }); - } - } - } - - stopProactiveRefresh(): void { - for (const timer of this.refreshTimers.values()) timer.cancel(); - this.refreshTimers.clear(); - } - - shutdown(): Promise { - if (this.shutdownPromise !== undefined) return this.shutdownPromise; - this.shuttingDown = true; - this.stopProactiveRefresh(); - const authorizations = [...this.activeAuthorizations.values()]; - const refreshes = [...this.refreshes.values()]; - this.activeAuthorizations.clear(); - const deadline = this.drainDeadline(); - this.shutdownPromise = (async () => { - try { - await Promise.race([ - Promise.all([ - Promise.all( - authorizations.map(async (active) => { - active.controller.abort(); - await active.serverRef.current?.close().catch(() => undefined); - const flow = await active.started.catch(() => undefined); - await flow?.cancelUnderlying(); - }), - ), - Promise.allSettled(refreshes), - this.drainBackgroundTasks(), - ]), - deadline.promise, - ]); - } finally { - deadline.cancel(); - this.listeners.clear(); - this.providers.clear(); - } - })(); - return this.shutdownPromise; - } - - private async drainBackgroundTasks(): Promise { - for (;;) { - await Promise.allSettled(this.backgroundTasks); - await new Promise((resolve) => { - setImmediate(resolve); - }); - if (this.backgroundTasks.size === 0) return; - } - } - - private drainDeadline(): { readonly promise: Promise; readonly cancel: () => void } { - let task: McpOAuthScheduledTask | undefined; - const promise = new Promise((resolve) => { - task = this.scheduler.schedule(this.shutdownDrainTimeoutMs, () => { - this.log.warn('mcp oauth shutdown drain timed out; continuing teardown'); - resolve(); - }); - }); - return { promise, cancel: () => task?.cancel() }; - } - - private authFetch( - provider: McpOAuthClientProvider, - signals: readonly AbortSignal[] = [], - ): typeof fetch { - const fetchFn = provider.createOAuthFetch(); - const timeoutMs = this.authRequestTimeoutMs; - return (async (input: Parameters[0], init?: Parameters[1]) => { - const combined: AbortSignal[] = [AbortSignal.timeout(timeoutMs), ...signals]; - if (init?.signal !== undefined && init.signal !== null) combined.push(init.signal); - return fetchFn(input, { ...init, signal: AbortSignal.any(combined) }); - }) as typeof fetch; - } - async beginAuthorization( serverName: string, serverUrl: string | URL, options: BeginAuthorizationOptions = {}, ): Promise { - if (this.shuttingDown) { - throw new Error2(ErrorCodes.MCP_OAUTH_FAILED, 'MCP OAuth service is shutting down'); - } - const storeKey = mcpOAuthStoreKey(serverName, serverUrl); - await this.refreshes.get(storeKey)?.catch(() => undefined); - if (this.shuttingDown) { - throw new Error2(ErrorCodes.MCP_OAUTH_FAILED, 'MCP OAuth service is shutting down'); - } - const inFlight = this.activeAuthorizations.get(storeKey); - if (inFlight !== undefined) { - const flow = await inFlight.started; - return flow.attach(); - } - - const controller = new AbortController(); - const serverRef: { current: CallbackServer | undefined } = { current: undefined }; - const started = this.startAuthorizationFlow( - serverName, - serverUrl, - options, - controller.signal, - serverRef, - ); - this.activeAuthorizations.set(storeKey, { started, controller, serverRef }); - let flow: SharedAuthorizationFlow; - try { - flow = await started; - } catch (error) { - this.activeAuthorizations.delete(storeKey); - throw error; - } - return flow.attach(); - } - - private async startAuthorizationFlow( - serverName: string, - serverUrl: string | URL, - options: BeginAuthorizationOptions, - signal: AbortSignal, - serverRef: { current: CallbackServer | undefined }, - ): Promise { - const storeKey = mcpOAuthStoreKey(serverName, serverUrl); - const provider = - options.clientLabel === undefined - ? this.getProvider(serverName, serverUrl) - : this.createProvider(serverName, serverUrl, options.clientLabel); + const provider = options.clientLabel === undefined + ? this.getProvider(serverName, serverUrl) + : new McpOAuthClientProvider({ + serverName, + serverUrl, + store: this.store, + clientLabel: options.clientLabel, + clientName: this.resolveClientName?.(), + }); if (options.clientLabel !== undefined) { this.providers.set(provider.storeKey, provider); } @@ -352,48 +108,24 @@ export class McpOAuthService { } catch (error) { throw wrapAuthError('failed to start OAuth callback listener', error); } - serverRef.current = callbackServer; + + provider.setRedirectUrl(new URL(callbackServer.redirectUri)); + await provider.ready; + await provider.invalidateStaleRegistration(callbackServer.redirectUri); let authorizationUrl: URL | undefined; try { - provider.setRedirectUrl(new URL(callbackServer.redirectUri)); - await provider.ready; - await provider.invalidateStaleRegistration(callbackServer.redirectUri); - let tokensSaved = false; - const unsubscribeTokensSaved = this.onEvent((event) => { - if ( - event.type === 'tokens-saved' && - event.serverName === serverName && - event.serverUrl === canonicalMcpOAuthResource(serverUrl) - ) { - tokensSaved = true; - } - }); - try { - const result = await auth(provider as OAuthClientProvider, { - serverUrl, - fetchFn: this.authFetch(provider, [signal]), - }); - if (result !== 'REDIRECT') { - await callbackServer.close(); - if (!tokensSaved) { - this.emit({ - type: 'tokens-saved', - serverName, - serverUrl: canonicalMcpOAuthResource(serverUrl), - }); - } - throw new AlreadyAuthorizedError(serverName); - } - authorizationUrl = provider.takeAuthorizationUrl(); - if (authorizationUrl === undefined) { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - 'OAuth provider did not capture an authorization URL', - ); - } - } finally { - unsubscribeTokensSaved(); + const result = await auth(provider as OAuthClientProvider, { serverUrl }); + if (result !== 'REDIRECT') { + await callbackServer.close(); + throw new AlreadyAuthorizedError(serverName); + } + authorizationUrl = provider.takeAuthorizationUrl(); + if (authorizationUrl === undefined) { + throw new Error2( + ErrorCodes.MCP_OAUTH_FAILED, + 'OAuth provider did not capture an authorization URL', + ); } } catch (error) { await callbackServer.close().catch(() => undefined); @@ -403,93 +135,50 @@ export class McpOAuthService { } let settled = false; - let completion: Promise | undefined; - let attachedHandles = 0; - const settle = async (): Promise => { + const cancel = async (): Promise => { if (settled) return; settled = true; - this.activeAuthorizations.delete(storeKey); - provider.resetFlow(); await callbackServer.close().catch(() => undefined); + provider.resetFlow(); }; - const startCompletion: BeginAuthorizationResult['complete'] = (opts = {}) => { - if (completion !== undefined) return completion; + const complete: BeginAuthorizationResult['complete'] = async (opts = {}) => { if (settled) { - return Promise.reject( - new Error2(ErrorCodes.MCP_OAUTH_FAILED, 'OAuth flow already completed or cancelled'), - ); + throw new Error2(ErrorCodes.MCP_OAUTH_FAILED, 'OAuth flow already completed or cancelled'); } - completion = (async () => { - try { - const { code, state } = await callbackServer.waitForCode({ - signal: opts.signal, - timeoutMs: opts.timeoutMs, - }); - const expectedState = provider.expectedState(); - if (expectedState !== undefined && state !== expectedState) { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - 'OAuth state mismatch — possible CSRF; refusing token exchange', - ); - } - const finalResult = await auth(provider as OAuthClientProvider, { - serverUrl, - authorizationCode: code, - fetchFn: this.authFetch( - provider, - opts.signal === undefined ? [signal] : [signal, opts.signal], - ), - }); - if (finalResult !== 'AUTHORIZED') { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - `OAuth code exchange returned "${finalResult}" instead of AUTHORIZED`, - { details: { result: finalResult } }, - ); - } - } catch (error) { - await settle(); - throw wrapAuthError(`OAuth flow for "${serverName}" failed`, error); + try { + const { code, state } = await callbackServer.waitForCode({ + signal: opts.signal, + timeoutMs: opts.timeoutMs, + }); + const expectedState = provider.expectedState(); + if (expectedState !== undefined && state !== expectedState) { + throw new Error2( + ErrorCodes.MCP_OAUTH_FAILED, + 'OAuth state mismatch — possible CSRF; refusing token exchange', + ); } - await settle(); - })(); - this.trackBackgroundTask(completion); - return completion; + const finalResult = await auth(provider as OAuthClientProvider, { + serverUrl, + authorizationCode: code, + }); + if (finalResult !== 'AUTHORIZED') { + throw new Error2( + ErrorCodes.MCP_OAUTH_FAILED, + `OAuth code exchange returned "${finalResult}" instead of AUTHORIZED`, + { details: { result: finalResult } }, + ); + } + } catch (error) { + await cancel(); + throw wrapAuthError(`OAuth flow for "${serverName}" failed`, error); + } + settled = true; + await callbackServer.close().catch(() => undefined); + provider.resetFlow(); }; - const attach = (): BeginAuthorizationResult => { - attachedHandles += 1; - let detached = false; - const detach = async (): Promise => { - if (detached) return; - detached = true; - attachedHandles -= 1; - if (attachedHandles === 0) await settle(); - }; - return { - authorizationUrl, - complete: async (opts = {}) => { - if (detached) { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - 'OAuth flow already completed or cancelled', - ); - } - try { - await startCompletion(opts); - } finally { - await detach(); - } - }, - cancel: detach, - }; - }; - - return { - attach, - cancelUnderlying: settle, - }; + return { authorizationUrl, complete, cancel }; } invalidate( @@ -497,127 +186,7 @@ export class McpOAuthService { serverUrl: string | URL, scope: 'all' | 'client' | 'tokens' | 'discovery' = 'all', ): Promise { - return this.getProvider(serverName, serverUrl).clearCredentials(scope); - } - - forgetProvider(serverName: string, serverUrl: string | URL): void { - this.providers.delete(mcpOAuthStoreKey(serverName, serverUrl)); - } - - private createProvider( - serverName: string, - serverUrl: string | URL, - clientLabel?: string, - ): McpOAuthClientProvider { - const canonicalUrl = canonicalMcpOAuthResource(serverUrl); - return new McpOAuthClientProvider({ - serverName, - serverUrl, - store: this.store, - clientLabel: clientLabel ?? this.clientLabel, - clientName: this.resolveClientName?.(), - now: () => this.scheduler.now(), - track: (task) => { - this.trackBackgroundTask(task); - }, - onTokensSaved: (tokens) => { - this.emit({ type: 'tokens-saved', serverName, serverUrl: canonicalUrl }); - if ( - typeof tokens.obtained_at === 'number' && - typeof tokens.expires_in === 'number' && - typeof tokens.refresh_token === 'string' && - tokens.refresh_token.length > 0 - ) { - this.scheduleRefresh( - serverName, - canonicalUrl, - tokens.obtained_at + tokens.expires_in * 1000, - ); - } - }, - onCredentialsInvalidated: (scope) => { - if (scope === 'tokens' || scope === 'all') { - this.cancelScheduledRefresh(serverName, canonicalUrl); - } - this.emit({ type: 'tokens-invalidated', serverName, serverUrl: canonicalUrl, scope }); - }, - }); - } - - private async refreshNow(serverName: string, serverUrl: string | URL): Promise { - if (this.activeAuthorizations.has(mcpOAuthStoreKey(serverName, serverUrl))) return; - const state = await this.tokenState(serverName, serverUrl); - if (this.activeAuthorizations.has(mcpOAuthStoreKey(serverName, serverUrl))) return; - if (!state.hasTokens || !state.hasRefreshToken) { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - `MCP server "${serverName}" has no refreshable OAuth grant`, - ); - } - const provider = this.getProvider(serverName, serverUrl); - provider.resetFlow(); - try { - const result = await auth(provider as OAuthClientProvider, { - serverUrl, - fetchFn: this.authFetch(provider), - }); - if (result !== 'AUTHORIZED') { - throw new Error2( - ErrorCodes.MCP_OAUTH_FAILED, - 'the stored OAuth grant requires an interactive login', - ); - } - } finally { - provider.resetFlow(); - } - } - - private scheduleRefresh(serverName: string, serverUrl: string | URL, expiresAt: number): void { - if (this.shuttingDown) return; - const canonicalUrl = canonicalMcpOAuthResource(serverUrl); - const storeKey = mcpOAuthStoreKey(serverName, canonicalUrl); - this.cancelScheduledRefresh(serverName, canonicalUrl); - const now = this.scheduler.now(); - if (expiresAt <= now) return; - const lifetimeMs = expiresAt - now; - const refreshAheadMs = Math.min(REFRESH_AHEAD_MS, lifetimeMs / 2); - const delay = lifetimeMs - refreshAheadMs; - let timer: McpOAuthScheduledTask; - if (delay > MAX_TIMER_DELAY_MS) { - timer = this.scheduler.schedule(MAX_TIMER_DELAY_MS, () => { - this.refreshTimers.delete(storeKey); - this.scheduleRefresh(serverName, canonicalUrl, expiresAt); - }); - } else { - timer = this.scheduler.schedule(delay, async () => { - this.refreshTimers.delete(storeKey); - await this.refresh(serverName, canonicalUrl).catch((error: unknown) => { - this.emit({ - type: 'refresh-failed', - serverName, - serverUrl: canonicalUrl, - error: error instanceof Error ? error.message : String(error), - }); - }); - }); - } - this.refreshTimers.set(storeKey, timer); - } - - private cancelScheduledRefresh(serverName: string, serverUrl: string | URL): void { - const storeKey = mcpOAuthStoreKey(serverName, serverUrl); - const timer = this.refreshTimers.get(storeKey); - timer?.cancel(); - this.refreshTimers.delete(storeKey); - } - - private emit(event: McpOAuthEvent): void { - for (const listener of this.listeners) { - try { - listener(event); - } catch { - } - } + return this.getProvider(serverName, serverUrl).invalidateCredentials(scope); } } @@ -631,29 +200,6 @@ export class AlreadyAuthorizedError extends Error2 { } } -async function readStoreMeta( - store: McpOAuthStore, - key: string, - log: Logger, -): Promise { - const raw: unknown = await store.read(key); - if (raw === undefined) return undefined; - if (typeof raw !== 'object' || raw === null) { - log.warn('ignoring malformed MCP OAuth meta file', { file: key }); - return undefined; - } - const { serverName, serverUrl } = raw as Record; - if (typeof serverName !== 'string' || serverName.length === 0 || typeof serverUrl !== 'string') { - log.warn('ignoring malformed MCP OAuth meta file', { file: key }); - return undefined; - } - if (URL.parse(serverUrl) === null) { - log.warn('ignoring MCP OAuth meta file with unparseable serverUrl', { file: key, serverUrl }); - return undefined; - } - return { serverName, serverUrl }; -} - function wrapAuthError(prefix: string, error: unknown): Error2 { if (isError2(error)) { return error; diff --git a/packages/agent-core-v2/src/mcpCore/oauth/store.ts b/packages/agent-core-v2/src/mcpCore/oauth/store.ts index a858debe8..00aee8cfc 100644 --- a/packages/agent-core-v2/src/mcpCore/oauth/store.ts +++ b/packages/agent-core-v2/src/mcpCore/oauth/store.ts @@ -1,3 +1,13 @@ +/** + * `mcpCore` domain — MCP OAuth credential store port and key addressing. + * + * Defines the {@link McpOAuthStore} port for reading and writing OAuth + * credentials, plus the store-key scheme: one logical record per + * `(serverName, serverUrl)` identity, addressed by {@link mcpOAuthStoreKey} + * (sanitized name prefix + a digest of name and canonicalized URL). This file + * holds no IO. + */ + import { createHash } from 'node:crypto'; import { basename } from 'pathe'; @@ -5,9 +15,7 @@ import { basename } from 'pathe'; import { ErrorCodes, Error2 } from '#/errors'; export function sanitizeStoreKey(name: string): string { - const safe = basename(name) - .replaceAll(/[^a-zA-Z0-9_-]/g, '_') - .replaceAll(/_+/g, '_'); + const safe = basename(name).replaceAll(/[^a-zA-Z0-9_-]/g, '_').replaceAll(/_+/g, '_'); if (safe.length === 0 || safe.startsWith('.')) { throw new Error2(ErrorCodes.CONFIG_INVALID, `Invalid MCP OAuth store key: "${name}"`); } @@ -36,5 +44,4 @@ export interface McpOAuthStore { read(key: string): Promise; write(key: string, data: unknown): Promise; remove(key: string): Promise; - list(prefix?: string): Promise; } diff --git a/packages/agent-core-v2/src/mcpCore/tool-naming.ts b/packages/agent-core-v2/src/mcpCore/tool-naming.ts index 47f66cf35..cb77ed5a8 100644 --- a/packages/agent-core-v2/src/mcpCore/tool-naming.ts +++ b/packages/agent-core-v2/src/mcpCore/tool-naming.ts @@ -1,3 +1,7 @@ +/** + * `mcpCore` domain — qualified `mcp__server__tool` name sanitizing and hashing. + */ + const MCP_NAME_PREFIX = 'mcp__'; const MCP_NAME_SEPARATOR = '__'; diff --git a/packages/agent-core-v2/src/mcpCore/types.ts b/packages/agent-core-v2/src/mcpCore/types.ts index e51b509f6..c38b7f4ca 100644 --- a/packages/agent-core-v2/src/mcpCore/types.ts +++ b/packages/agent-core-v2/src/mcpCore/types.ts @@ -1,3 +1,11 @@ +/** + * `mcpCore` domain — MCP protocol types and the minimal client contract. + * + * The wire-level surface: tool definitions returned by `tools/list`, the + * `tools/call` result shape, and the small interface that lets tests inject a + * fake transport without pulling in the MCP SDK type graph. + */ + import { ErrorCodes, Error2 } from '#/errors'; export interface MCPEmbeddedResourceContents { diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostClockService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostClockService.ts index 633431083..3c979c015 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostClockService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostClockService.ts @@ -1,3 +1,10 @@ +/** + * `hostClock` domain — `IHostClock` implementation. + * + * Reads wall-clock time and the host's resolved local time zone through the + * Node.js runtime. Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IHostClock } from '#/os/interface/hostClock'; diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostEnvironmentService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostEnvironmentService.ts index 5e91e2316..d90a61e0c 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostEnvironmentService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostEnvironmentService.ts @@ -1,3 +1,18 @@ +/** + * `hostEnvironment` domain — `IHostEnvironment` implementation. + * + * Kicks off the OS / shell probe (`probeHostEnvironmentFromNode`) and the + * login-shell PATH enrichment (`applyLoginShellPathFromNode`) at construction + * time; the sync fields become populated once `ready` resolves. Reads before + * `ready` throws with a clear message so misuse fails loudly instead of + * returning stale zeros. A failed probe is translated at this boundary — a + * missing Git Bash on Windows becomes `HostProcessError` + * (`shell.git_bash_not_found`) — and surfaces identically from `ready` and + * from sync field reads, while an internal no-op handler keeps the rejection + * from ever becoming an unhandledRejection during App-scope construction. + * Bound at App scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostFsService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostFsService.ts index 9591a2e5b..6cb12dcb8 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostFsService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostFsService.ts @@ -1,3 +1,10 @@ +/** + * `hostFs` domain — `IHostFileSystem` implementation. + * + * Reads and writes files on the real local disk through `node:fs/promises`. + * Bound at App scope. + */ + import { appendFile, lstat, @@ -72,17 +79,16 @@ export class HostFileSystem implements IHostFileSystem { } } - async readBytes(path: string, n?: number, offset = 0): Promise { + async readBytes(path: string, n?: number): Promise { try { - if (n === undefined && offset === 0) { + if (n === undefined) { const buf = await readFile(path); return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength); } const fh = await open(path, 'r'); try { - const length = n ?? Math.max(0, (await fh.stat()).size - offset); - const buf = Buffer.alloc(length); - const { bytesRead } = await fh.read(buf, 0, length, offset); + const buf = Buffer.alloc(n); + const { bytesRead } = await fh.read(buf, 0, n, 0); return buf.subarray(0, bytesRead); } finally { await fh.close(); diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostFsWatchService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostFsWatchService.ts index 17fc565b1..333f63149 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostFsWatchService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostFsWatchService.ts @@ -1,3 +1,10 @@ +/** + * `hostFsWatch` domain — `IHostFsWatchService` implementation. + * + * Reports precise or coarse host filesystem changes through platform + * watchers. Each handle owns and disposes its watcher. Bound at App scope. + */ + import { watch as fsWatch } from 'node:fs'; import { basename, isAbsolute, join, relative } from 'node:path'; diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostProcessService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostProcessService.ts index 54ce7a136..8d3aad955 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostProcessService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostProcessService.ts @@ -1,3 +1,12 @@ +/** + * `hostProcess` domain — `IHostProcessService` node-local implementation. + * + * Spawns child processes with `node:child_process.spawn`, wraps them in the + * domain-facing `IHostProcess` handle, and provides cross-platform process-tree + * termination. The service itself is stateless; each `spawn()` returns an + * independent handle that owns its streams and exit promise. Bound at App scope. + */ + import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process'; import type { Readable, Writable } from 'node:stream'; diff --git a/packages/agent-core-v2/src/os/backends/node-local/hostTerminalService.ts b/packages/agent-core-v2/src/os/backends/node-local/hostTerminalService.ts index 726f86e01..b87b14bb7 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/hostTerminalService.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/hostTerminalService.ts @@ -1,3 +1,15 @@ +/** + * `terminal` domain — `IHostTerminalService` implementation. + * + * App-scoped OS terminal process factory backed by `node-pty`. It spawns and + * tracks every `TerminalProcess` so the whole process-wide PTY layer can be + * torn down on disposal. It has no session, workspace, or buffering concerns. + * + * `node-pty` is loaded lazily so merely importing this module (for example in + * tests that override the service with a fake) does not require the native + * module to be built or resolvable. + */ + import type { IPty } from 'node-pty'; import { Service } from '#/_base/di/service'; diff --git a/packages/agent-core-v2/src/os/backends/node-local/tools/rgLocator.ts b/packages/agent-core-v2/src/os/backends/node-local/tools/rgLocator.ts index f70c175e6..6edac6f09 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/tools/rgLocator.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/tools/rgLocator.ts @@ -1,3 +1,13 @@ +/** + * `fileTools` domain — shared ripgrep (`rg`) binary locator. + * + * Resolves the `rg` command, preferring a file found on + * PATH, then the vendor hook, then the app cache, and finally bootstrapping a + * pinned ripgrep archive into `/bin` when the + * caller permits it. File lookup intentionally avoids spawning `rg --version` + * so tool resolution has the same observable shape as v1. + */ + import { createHash } from 'node:crypto'; import { createWriteStream, existsSync } from 'node:fs'; import { chmod, copyFile, mkdir, mkdtemp, readFile, rename, rm, stat } from 'node:fs/promises'; @@ -5,7 +15,6 @@ import { homedir, tmpdir } from 'node:os'; import { Readable } from 'node:stream'; import { pipeline } from 'node:stream/promises'; -import { kimiRegionProfile, resolveKimiRegion } from '@moonshot-ai/kimi-code-oauth'; import { extract as extractTar } from 'tar'; import { type Entry, fromBuffer as yauzlFromBuffer } from 'yauzl'; import { basename, join } from 'pathe'; @@ -14,6 +23,7 @@ import { abortable } from '#/_base/utils/abort'; import { ErrorCodes, Error2 } from '#/errors'; const RG_VERSION = '15.0.0'; +const RG_BASE_URL = 'https://code.kimi.com/kimi-code/rg'; const DOWNLOAD_TIMEOUT_MS = 600_000; const RG_ARCHIVE_SHA256: Record = { 'ripgrep-15.0.0-aarch64-apple-darwin.tar.gz': @@ -65,10 +75,6 @@ export function getShareBinRgPath(): string { return join(getShareDir(), 'bin', rgBinaryName()); } -function rgBaseUrl(): string { - return `${kimiRegionProfile(resolveKimiRegion()).cdnBase}/rg`; -} - function throwIfAborted(signal: AbortSignal | undefined): void { if (signal?.aborted === true) { throw new DOMException('Aborted', 'AbortError'); @@ -194,7 +200,7 @@ async function downloadAndInstallRg(shareDir: string): Promise { { details: { archiveName } }, ); } - const url = `${rgBaseUrl()}/${archiveName}`; + const url = `${RG_BASE_URL}/${archiveName}`; const binDir = join(shareDir, 'bin'); await mkdir(binDir, { recursive: true }); diff --git a/packages/agent-core-v2/src/os/backends/node-local/tools/runRg.ts b/packages/agent-core-v2/src/os/backends/node-local/tools/runRg.ts index de3700a8e..6b2b43d1f 100644 --- a/packages/agent-core-v2/src/os/backends/node-local/tools/runRg.ts +++ b/packages/agent-core-v2/src/os/backends/node-local/tools/runRg.ts @@ -1,3 +1,12 @@ +/** + * `fileTools` domain — shared ripgrep subprocess plumbing. + * + * Single place that knows how to spawn `rg` through the host + * `IHostProcessService`: timeout / abort handling, capped stdout / stderr + * draining, two-phase kill with process disposal, and the EAGAIN retry + * predicate. + */ + import type { Readable } from 'node:stream'; import { BugIndicatingError } from '#/errors'; @@ -21,7 +30,7 @@ export type RunRgOutcome = RunRgResult | { readonly kind: 'aborted' }; function disposeProcess(proc: IHostProcess): void { try { - void proc.dispose(); + proc.dispose(); } catch { } } diff --git a/packages/agent-core-v2/src/os/interface/hostClock.ts b/packages/agent-core-v2/src/os/interface/hostClock.ts index 161f5a34f..a726a47cc 100644 --- a/packages/agent-core-v2/src/os/interface/hostClock.ts +++ b/packages/agent-core-v2/src/os/interface/hostClock.ts @@ -1,3 +1,10 @@ +/** + * `hostClock` domain — current host time and local time-zone contract. + * + * Defines `IHostClock`, the App-scoped boundary used by time-sensitive + * domains to observe the current instant and the host's local IANA time zone. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IHostClock { diff --git a/packages/agent-core-v2/src/os/interface/hostEnvironment.ts b/packages/agent-core-v2/src/os/interface/hostEnvironment.ts index 0f056ddd8..8894a53cd 100644 --- a/packages/agent-core-v2/src/os/interface/hostEnvironment.ts +++ b/packages/agent-core-v2/src/os/interface/hostEnvironment.ts @@ -1,3 +1,23 @@ +/** + * `hostEnvironment` domain — the OS / shell / path-style facts of the + * host the Agent runs on. + * + * Defines `IHostEnvironment`, an immutable snapshot of the host OS + * (`osKind`/`osArch`/`osVersion`), the POSIX shell to spawn commands with + * (`shellName`/`shellPath`), the target path style (`pathClass`), and the + * user's home directory (`homeDir`). The snapshot is a pure function of the + * host and never changes during a process's lifetime; the service memoises + * the probe. + * + * Async initialization: probing (`ready`) discovers the shell path — on + * Windows this may run `git.exe --exec-path`. The composition root + * `await`s `ready` before creating + * any Session scope, so + * every Session/Agent-scope consumer reads the sync fields safely. + * + * App-scoped — one shared instance for the whole process. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { diff --git a/packages/agent-core-v2/src/os/interface/hostFileSystem.ts b/packages/agent-core-v2/src/os/interface/hostFileSystem.ts index cadd91538..40f0e13aa 100644 --- a/packages/agent-core-v2/src/os/interface/hostFileSystem.ts +++ b/packages/agent-core-v2/src/os/interface/hostFileSystem.ts @@ -1,3 +1,13 @@ +/** + * `hostFs` domain — local real-filesystem primitives. + * + * Defines the `IHostFileSystem` used to read and write files on + * the real local disk, plus the stat/entry models. `realpath` canonicalizes a + * path by resolving every symlink component (Node `fs.realpath` semantics) and + * rejects with `os.fs.not_found` for a missing path; consumers use it to make + * lexical path confinement symlink-aware. App-scoped — one shared instance. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { TextDecodeErrors } from '#/_base/execEnv/decodeText'; @@ -26,7 +36,7 @@ export interface IHostFileSystem { ): Promise; writeText(path: string, data: string): Promise; appendText(path: string, data: string): Promise; - readBytes(path: string, n?: number, offset?: number): Promise; + readBytes(path: string, n?: number): Promise; writeBytes(path: string, data: Uint8Array): Promise; readLines( path: string, diff --git a/packages/agent-core-v2/src/os/interface/hostFsErrors.ts b/packages/agent-core-v2/src/os/interface/hostFsErrors.ts index abbf34ac1..d2722acb0 100644 --- a/packages/agent-core-v2/src/os/interface/hostFsErrors.ts +++ b/packages/agent-core-v2/src/os/interface/hostFsErrors.ts @@ -1,3 +1,18 @@ +/** + * `hostFs` domain — error codes, `HostFsError`, and the `toHostFsError` + * boundary translator. + * + * Every `IHostFileSystem` backend translates raw OS failures (Node + * `ErrnoException`, and whatever a future non-Node backend throws) into a + * `HostFsError` at its boundary, so consumers branch on a stable `code` + * (`os.fs.*`) instead of platform errnos. `toHostFsError` is a pure function + * shared by all backends; it is idempotent — an error that is already a + * `HostFsError` passes through untouched. + * + * `os.fs.unavailable` covers non-errno resource failures (fs.watch unsupported, + * fd exhaustion, …); `os.fs.unknown` is the fallback for unrecognized errnos. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; import { Error2, type Error2Options } from '#/_base/errors/errors'; diff --git a/packages/agent-core-v2/src/os/interface/hostFsWatch.ts b/packages/agent-core-v2/src/os/interface/hostFsWatch.ts index bf59a2caa..162f78657 100644 --- a/packages/agent-core-v2/src/os/interface/hostFsWatch.ts +++ b/packages/agent-core-v2/src/os/interface/hostFsWatch.ts @@ -1,3 +1,18 @@ +/** + * `hostFsWatch` domain — local real-filesystem change notifications. + * + * Defines the `IHostFsWatchService`, a thin primitive over the host OS file + * watcher. It reports raw create/modify/delete events under an absolute path + * and knows nothing about sessions, connections, workspaces or wire frames. + * `HostFsWatchOptions.signal` marks callers that consume events as a mere + * "something changed" signal (ignoring action/kind); the backend may then + * pick a cheaper implementation (one native recursive watch instead of + * per-node watchers). Signal events may use the watched root as their path + * and report coarse action/kind values. A handle's `ready` promise resolves + * after its backend has installed the initial subscription and rejects when + * initialization fails. App-scoped — one shared instance. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; import type { IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/os/interface/hostProcess.ts b/packages/agent-core-v2/src/os/interface/hostProcess.ts index 6197026f7..d81aaee46 100644 --- a/packages/agent-core-v2/src/os/interface/hostProcess.ts +++ b/packages/agent-core-v2/src/os/interface/hostProcess.ts @@ -1,3 +1,13 @@ +/** + * `hostProcess` domain — the OS process-spawning contract. + * + * Defines `IHostProcessService`, the App-scope primitive used by any domain that + * needs to spawn a child process on the host, plus the `IHostProcess` handle it + * returns. The contract is deliberately close to Python `subprocess.Popen` / + * `os.spawn*`: a single `spawn()` call returns a handle exposing stdin/stdout/ + * stderr, the pid, the exit code, and lifecycle methods. Bound at App scope. + */ + import type { Readable, Writable } from 'node:stream'; import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; @@ -24,7 +34,7 @@ export interface IHostProcess { readonly stderr: Readable; wait(): Promise; kill(signal?: NodeJS.Signals): Promise; - dispose(): void | Promise; + dispose(): void; } export interface IHostProcessService { diff --git a/packages/agent-core-v2/src/os/interface/terminal.ts b/packages/agent-core-v2/src/os/interface/terminal.ts index 0dff5d7c8..09bcc29c5 100644 --- a/packages/agent-core-v2/src/os/interface/terminal.ts +++ b/packages/agent-core-v2/src/os/interface/terminal.ts @@ -1,3 +1,16 @@ +/** + * `terminal` domain — interactive terminal (PTY) contract. + * + * Defines the App-scoped `IHostTerminalService` that owns the actual OS terminal + * processes and the low-level process/stream primitives (`TerminalProcess`, + * `TerminalSpawnOptions`, `TerminalAttachSink`, `TerminalFrame`) used to wire + * terminal I/O to a transport. + * + * Wire types (`Terminal`, `CreateTerminalRequest`, frame messages) are defined + * here — the terminal REST schemas as zod, the attach-frame messages as plain + * types. + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; @@ -27,7 +40,6 @@ export const terminalSchema = z.object({ export type Terminal = z.infer; export const createTerminalRequestSchema = z.object({ - runtime_id: z.string().min(1), cwd: relativeCwdSchema.optional(), shell: z.string().min(1).optional(), cols: z.number().int().positive().optional(), diff --git a/packages/agent-core-v2/src/os/interface/terminalErrors.ts b/packages/agent-core-v2/src/os/interface/terminalErrors.ts index 002c9d1df..92208f7bb 100644 --- a/packages/agent-core-v2/src/os/interface/terminalErrors.ts +++ b/packages/agent-core-v2/src/os/interface/terminalErrors.ts @@ -1,3 +1,7 @@ +/** + * `terminal` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const TerminalErrors = { diff --git a/packages/agent-core-v2/src/persistence/backends/memory/inMemoryStorageService.ts b/packages/agent-core-v2/src/persistence/backends/memory/inMemoryStorageService.ts index 71043025c..b32ec029f 100644 --- a/packages/agent-core-v2/src/persistence/backends/memory/inMemoryStorageService.ts +++ b/packages/agent-core-v2/src/persistence/backends/memory/inMemoryStorageService.ts @@ -1,3 +1,16 @@ +/** + * `InMemoryStorageService` — `IFileSystemStorageService` backed by in-memory maps. + * + * Not auto-registered: the Storage-layer backend is a deployment choice that + * the composition root must provide. `bootstrap()` seeds a per-token + * `FileStorageService` (rooted at `bootstrap.homeDir`) for production; the + * test harness seeds this in-memory backend so tests keep a durable-enough + * default. A scope that seeds neither backend will fail to resolve the storage + * tokens on first use. + * + * `append` concatenates into the same key slot `write` replaces. + */ + import { DisposableStore, combinedDisposable, @@ -48,9 +61,8 @@ export class InMemoryStorageService implements IFileSystemStorageService { scope: string, key: string, data: Uint8Array, - options: StorageWriteOptions = {}, + _options: StorageWriteOptions = {}, ): Promise { - options.signal?.throwIfAborted(); this.bucket(scope).set(key, data); this.notifyWatchers(scope, key); } @@ -59,16 +71,14 @@ export class InMemoryStorageService implements IFileSystemStorageService { scope: string, key: string, source: AsyncIterable, - options: StorageWriteOptions = {}, + _options: StorageWriteOptions = {}, ): Promise { const chunks: Uint8Array[] = []; let total = 0; for await (const chunk of source) { - options.signal?.throwIfAborted(); chunks.push(chunk); total += chunk.byteLength; } - options.signal?.throwIfAborted(); const merged = new Uint8Array(total); let offset = 0; for (const chunk of chunks) { @@ -111,14 +121,6 @@ export class InMemoryStorageService implements IFileSystemStorageService { this.notifyWatchers(scope, key); } - async size(scope: string, key: string): Promise { - return this.scopes.get(scope)?.get(key)?.byteLength; - } - - pathFor(_scope: string, _key: string): undefined { - return undefined; - } - watch(scope: string, key: string): Event { const id = this.watchKey(scope, key); return (listener, thisArg, disposables) => { diff --git a/packages/agent-core-v2/src/persistence/backends/minidb/flag.ts b/packages/agent-core-v2/src/persistence/backends/minidb/flag.ts index 38d903f6f..1a1f2433f 100644 --- a/packages/agent-core-v2/src/persistence/backends/minidb/flag.ts +++ b/packages/agent-core-v2/src/persistence/backends/minidb/flag.ts @@ -1,3 +1,12 @@ +/** + * `minidb` persistence backend — flag contribution. + * + * Gates the minidb-backed derived read-model (`IQueryStore`) and the consumers + * that read through it. On by default; roll back to the legacy authoritative + * read path via `KIMI_CODE_EXPERIMENTAL_PERSISTENCE_MINIDB_READMODEL=false` or + * the `[experimental]` config section. + */ + import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; export const persistenceMiniDbReadModelFlag: FlagDefinitionInput = { diff --git a/packages/agent-core-v2/src/persistence/backends/minidb/miniDbQueryStore.ts b/packages/agent-core-v2/src/persistence/backends/minidb/miniDbQueryStore.ts index 08de31987..1545fbcbc 100644 --- a/packages/agent-core-v2/src/persistence/backends/minidb/miniDbQueryStore.ts +++ b/packages/agent-core-v2/src/persistence/backends/minidb/miniDbQueryStore.ts @@ -1,3 +1,64 @@ +/** + * `minidb` backend — `IQueryStore` implementation over `ClusterDb`. + * + * A rebuildable, in-process derived read-model. The store is a `ClusterDb` + * of 16 shards rooted at `/query-store`: keys are hash-routed over + * ordinary `MiniDb` directories, so multiple kimi processes can read and + * write the same read model concurrently (a single writer per shard, readers + * that never take write locks) instead of failing against a database-wide + * single-writer lock. Authoritative data lives elsewhere, never here, so + * losing the read model is always safe. + * + * Values are JSON (`valueCodec: 'json'`, required by secondary indexes and + * `query`) and held in memory (`valueMode: 'memory'`); durability is + * `everysec`, which is acceptable for a cache. Writes are atomic per shard; + * a `batch` spanning shards is best-effort across them — a projector can + * always replay from its checkpoint. `lockAcquireTimeoutMs` is lowered from + * the 30s default: a cache read must not hang behind a contended shard, and + * with `lockHoldMs` yields one second is ample for a live writer. + * + * The database is opened **lazily** on the first actual IO, not at + * construction. Construction therefore does no filesystem work — important + * because `MiniDbQueryStore` is resolved transitively whenever a consumer + * is constructed, including in tests that share a + * home dir and never read or write the read model. + * + * Corruption handling lifts `MiniDb.openOrRebuild`'s predicate + * (`SyntaxError` / `CorruptFrameError`) to the cluster: the first + * rebuildable failure triggers one process-lifetime rebuild — close, delete + * the directory, reopen empty, retry the operation once — and consumers' + * checkpoint-based reprojection repopulates the model. Every other error + * propagates as-is; in particular a per-shard `LockError` (a live process + * holding a shard beyond the acquire timeout) is transient and must NOT + * become `storage.locked`, which consumers would treat as a permanent + * read-model outage. + * + * A `collection` is encoded as a key prefix (`` + NUL + ``); index + * names are prefixed with the collection to keep them isolated in the + * cluster-wide registry, and value indexes are created `sparse` so documents + * from other collections (which lack the indexed field) are skipped. + * + * This store is a STRUCTURAL read model: stores, datetime/order columns, and + * secondary/compound indexes only. `ensureIndex` rejects text-index + * definitions — a text index would pull tokenizers, postings files, and + * full-text generation builds into the session-list critical path, which is + * exactly what the search-index separation forbids here; full-text search + * lives in the kap-server search-index database (`IGlobalSearchService`), + * never in this cluster. + * + * Ordered columns map to the engine's `dt` channels: `put`/`batch` forward + * `columns` as `SetOptions.dt`, and `pageByColumn` issues a dt-bounded, + * dt-sorted, limited query — which the engine serves by walking its ordered + * column structure with early stop instead of materializing and sorting all + * candidates. `pageByColumn` deliberately sends no key prefix (a key range + * would disqualify that walk); callers keep column names collection-unique + * per the `IQueryStore` contract. `listKeys`/`dropCollection` are prefix + * scans (deletes applied in chunks); `getMany` is the cluster `mget` (one + * reader call per touched shard). + * + * Bound at App scope as a peer of the other access-pattern stores. + */ + import { promises as fsp } from 'node:fs'; import { join } from 'pathe'; @@ -42,12 +103,20 @@ function isRebuildable(error: unknown): boolean { return error instanceof SyntaxError || (error as { name?: string }).name === 'CorruptFrameError'; } +/** + * Fire-and-forget close promises produced by DI disposal (which is + * synchronous). The server shutdown path awaits these via + * `drainQueryStoreDisposals()` before the homeDir is released, so a teardown + * `rm()` never races an in-flight ClusterDb open/close (a late shard open + * would recreate db.wal and fail the rm with ENOTEMPTY). + */ const pendingDisposals = new Set>(); export async function drainQueryStoreDisposals(): Promise { await Promise.all(pendingDisposals); } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class MiniDbQueryStore extends Disposable implements IQueryStore { declare readonly _serviceBrand: undefined; @@ -63,6 +132,9 @@ export class MiniDbQueryStore extends Disposable implements IQueryStore { super(); this.dir = join(this.bootstrap.cacheDir, STORE_SUBDIR); this._register(toDisposable(() => { + // DI disposal is synchronous, but closing a ClusterDb is not: track the + // close module-level so the shutdown path (`drainQueryStoreDisposals`) + // can await it before the homeDir is torn down. const pending = this.close().catch(() => {}); pendingDisposals.add(pending); void pending.finally(() => pendingDisposals.delete(pending)); @@ -82,6 +154,8 @@ export class MiniDbQueryStore extends Disposable implements IQueryStore { } private openFresh(): Promise { + // Answers "which database does a session-list read touch" from logs alone: + // the read model lives in this cluster, one MiniDb per shard directory. this.log.info('minidb query-store opening', { dir: this.dir, shardCount: SHARD_COUNT }); return ClusterDb.open({ dir: this.dir, @@ -171,6 +245,10 @@ export class MiniDbQueryStore extends Disposable implements IQueryStore { } async pageByColumn(collection: string, query: ColumnPageQuery): Promise> { + // No key prefix: a key-range disqualifies the engine's ordered-column + // walk, and the column is only ever declared by this collection's writes, + // so the walk visits no foreign rows. Cross-collection contamination is + // prevented by the contract (column names are store-wide). const dir = query.dir ?? 'asc'; const rows = (await this.withDb((db) => db.query({ diff --git a/packages/agent-core-v2/src/persistence/backends/node-fs/appendLogStore.ts b/packages/agent-core-v2/src/persistence/backends/node-fs/appendLogStore.ts index 31554bcf6..23e6b2e08 100644 --- a/packages/agent-core-v2/src/persistence/backends/node-fs/appendLogStore.ts +++ b/packages/agent-core-v2/src/persistence/backends/node-fs/appendLogStore.ts @@ -1,3 +1,19 @@ +/** + * `storage` domain — node-fs backend for `IAppendLogStore`. + * + * Sits on top of `IFileSystemStorageService` and turns a byte stream into an ordered + * sequence of typed JSON records. Owns the concerns the storage service + * deliberately ignores: line framing (one JSON value per line, a.k.a. JSONL), + * batching of appends into a single durable `append`, and crash-tolerant + * decoding (a torn final line is dropped; corruption anywhere else throws). + * Serializes whole-log rewrites with live appends, preserves queued or + * in-flight records across the atomic replacement, keeps ambiguous append and + * rewrite failures sticky, keeps the shared flush pending until the + * post-rewrite drain is durable, waits every key before a global flush reports + * an error, and preserves per-key storage ordering while acquired buffers + * retire and hand off to replacement owners. Bound at App scope. + */ + import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; @@ -11,14 +27,6 @@ import { const textEncoder = new TextEncoder(); -const pendingRetirements = new Set>(); - -export async function drainAppendLogRetirements(): Promise { - while (pendingRetirements.size > 0) { - await Promise.all(pendingRetirements); - } -} - interface LogState { pending: unknown[]; flushPromise: Promise | undefined; @@ -126,10 +134,6 @@ export class AppendLogStore implements IAppendLogStore { await this.flush(); } - drainRetirements(): Promise { - return drainAppendLogRetirements(); - } - acquire(scope: string, key: string): IDisposable { const state = this.state(scope, key); state.refCount++; @@ -183,10 +187,7 @@ export class AppendLogStore implements IAppendLogStore { state.refCount--; if (state.refCount > 0) return; state.retired = true; - const retirement = this.settleRetiredState(scope, key, state).catch(() => undefined); - state.retirement = retirement; - pendingRetirements.add(retirement); - void retirement.finally(() => pendingRetirements.delete(retirement)); + state.retirement = this.settleRetiredState(scope, key, state).catch(() => undefined); } private async settleRetiredState(scope: string, key: string, state: LogState): Promise { diff --git a/packages/agent-core-v2/src/persistence/backends/node-fs/atomicDocumentStore.ts b/packages/agent-core-v2/src/persistence/backends/node-fs/atomicDocumentStore.ts index db1eaccd9..bc18136ba 100644 --- a/packages/agent-core-v2/src/persistence/backends/node-fs/atomicDocumentStore.ts +++ b/packages/agent-core-v2/src/persistence/backends/node-fs/atomicDocumentStore.ts @@ -1,3 +1,12 @@ +/** + * `JsonAtomicDocumentStore` — node-fs backend for `IAtomicDocumentStore`. + * + * JSON and TOML codec implementations plus the `AtomicDocumentStoreBase`, + * `JsonAtomicDocumentStore`, and `TomlAtomicDocumentStore` classes. Reads and + * writes bytes through `IFileSystemStorageService`. Bound at + * App scope. + */ + import { parse as parseToml, stringify as stringifyToml } from 'smol-toml'; import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; diff --git a/packages/agent-core-v2/src/persistence/backends/node-fs/blobStoreService.ts b/packages/agent-core-v2/src/persistence/backends/node-fs/blobStoreService.ts index 4820de925..b99408f76 100644 --- a/packages/agent-core-v2/src/persistence/backends/node-fs/blobStoreService.ts +++ b/packages/agent-core-v2/src/persistence/backends/node-fs/blobStoreService.ts @@ -1,3 +1,11 @@ +/** + * `blobStore` domain — `IBlobStore` implementation. + * + * Delegates to the `IFileSystemStorageService` backend with atomic writes. Bound at App + * scope; child scopes (Session, Agent) inherit the same instance and use + * scope strings to namespace their data. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/persistence/backends/node-fs/fileStorageService.ts b/packages/agent-core-v2/src/persistence/backends/node-fs/fileStorageService.ts index 8e560eff6..e7ce6d995 100644 --- a/packages/agent-core-v2/src/persistence/backends/node-fs/fileStorageService.ts +++ b/packages/agent-core-v2/src/persistence/backends/node-fs/fileStorageService.ts @@ -1,5 +1,28 @@ +/** + * `FileStorageService` — `IFileSystemStorageService` backed by the local filesystem. + * + * Layout: a value addressed by `(scope, key)` lives at + * `//`. `scope` may contain slashes to form nested + * directories (e.g. `"agents/main"`). + * + * Primitives: + * - `write` → `atomicWrite` (tmp + fsync + rename) followed by a directory + * fsync, so the replacement is both atomic and durable. + * - `writeStream` → the streamed form of `write` (`atomicWriteStream`), for + * values too large to buffer in memory. + * - `append` → `open('a')` + write + `fh.sync()` (when `durable`), plus a + * one-time directory fsync per scope. + * - `watch` → chokidar on the parent directory, filtered to the exact key and + * debounced, so it survives atomic-replace renames and observes a + * file that does not exist yet at subscription time. + * + * It uses raw `node:fs` rather than `kaos`: the storage kernel needs direct + * control over append offsets, fsync, atomic rename and streaming, which the + * agent-execution-environment abstraction does not expose. + */ + import { createReadStream, mkdirSync } from 'node:fs'; -import { mkdir, open, readFile, readdir, stat, unlink } from 'node:fs/promises'; +import { mkdir, open, readFile, readdir, unlink } from 'node:fs/promises'; import { FSWatcher } from 'chokidar'; import { dirname, join, normalize } from 'pathe'; @@ -34,7 +57,7 @@ export class FileStorageService implements IFileSystemStorageService { ) {} async read(scope: string, key: string): Promise { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); try { return await readFile(filePath); } catch (error) { @@ -48,7 +71,7 @@ export class FileStorageService implements IFileSystemStorageService { key: string, range?: StorageReadRange, ): AsyncIterable { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); const stream = createReadStream( filePath, range === undefined ? undefined : { start: range.start, end: range.end }, @@ -67,15 +90,14 @@ export class FileStorageService implements IFileSystemStorageService { scope: string, key: string, data: Uint8Array, - options: StorageWriteOptions = {}, + _options: StorageWriteOptions = {}, ): Promise { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); try { await mkdir(dirname(filePath), { recursive: true, mode: this.dirMode }); - await atomicWrite(filePath, data, undefined, this.fileMode, options.signal); + await atomicWrite(filePath, data, undefined, this.fileMode); await this.syncDirOnce(dirname(filePath)); } catch (error) { - options.signal?.throwIfAborted(); throw toStorageIoError(error, { path: filePath, op: 'write' }); } } @@ -84,15 +106,14 @@ export class FileStorageService implements IFileSystemStorageService { scope: string, key: string, source: AsyncIterable, - options: StorageWriteOptions = {}, + _options: StorageWriteOptions = {}, ): Promise { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); try { await mkdir(dirname(filePath), { recursive: true, mode: this.dirMode }); - await atomicWriteStream(filePath, source, this.fileMode, options.signal); + await atomicWriteStream(filePath, source, this.fileMode); await this.syncDirOnce(dirname(filePath)); } catch (error) { - options.signal?.throwIfAborted(); throw toStorageIoError(error, { path: filePath, op: 'write' }); } } @@ -103,7 +124,7 @@ export class FileStorageService implements IFileSystemStorageService { data: Uint8Array, options: StorageAppendOptions = {}, ): Promise { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); const dir = dirname(filePath); try { await mkdir(dir, { recursive: true, mode: this.dirMode }); @@ -137,7 +158,7 @@ export class FileStorageService implements IFileSystemStorageService { } async delete(scope: string, key: string): Promise { - const filePath = this.pathFor(scope, key); + const filePath = this.path(scope, key); try { await unlink(filePath); } catch (error) { @@ -146,18 +167,8 @@ export class FileStorageService implements IFileSystemStorageService { } } - async size(scope: string, key: string): Promise { - const filePath = this.pathFor(scope, key); - try { - return (await stat(filePath)).size; - } catch (error) { - if (isEnoent(error)) return undefined; - throw toStorageIoError(error, { path: filePath, op: 'stat' }); - } - } - watch(scope: string, key: string): Event { - const target = this.pathFor(scope, key); + const target = this.path(scope, key); const dir = dirname(target); const normalizedTarget = normalize(target); const emitter = new Emitter(); @@ -225,7 +236,7 @@ export class FileStorageService implements IFileSystemStorageService { async close(): Promise {} - pathFor(scope: string, key: string): string { + private path(scope: string, key: string): string { return join(this.baseDir, scope, key); } diff --git a/packages/agent-core-v2/src/persistence/backends/node-fs/projectLocalConfigService.ts b/packages/agent-core-v2/src/persistence/backends/node-fs/projectLocalConfigService.ts index eccb04eaa..a7579c085 100644 --- a/packages/agent-core-v2/src/persistence/backends/node-fs/projectLocalConfigService.ts +++ b/packages/agent-core-v2/src/persistence/backends/node-fs/projectLocalConfigService.ts @@ -1,3 +1,14 @@ +/** + * `FileProjectLocalConfigService` — node-fs backend for `IProjectLocalConfigService`. + * + * Discovers project roots, parses and writes project-local + * `.kimi-code/local.toml`, resolves additional directories with + * v1-compatible OS-home expansion through `bootstrap`, and accesses the local + * filesystem through `hostFs`. Works purely by path (project-root discovery + * via the nearest `.git` ancestor); it never touches the workspace catalog or + * a `workspaceId`. Bound at App scope. + */ + import { dirname, isAbsolute, join, normalize, resolve } from 'pathe'; import { parse as parseToml, stringify as stringifyToml } from 'smol-toml'; import { z } from 'zod'; diff --git a/packages/agent-core-v2/src/persistence/interface/appendLogStore.ts b/packages/agent-core-v2/src/persistence/interface/appendLogStore.ts index c8f6b3fca..2a81bc2b7 100644 --- a/packages/agent-core-v2/src/persistence/interface/appendLogStore.ts +++ b/packages/agent-core-v2/src/persistence/interface/appendLogStore.ts @@ -1,3 +1,26 @@ +/** + * `persistence/interface` — `IAppendLogStore` contract. + * + * The append-log access-pattern store: turns a byte stream into an ordered + * sequence of typed JSON records on top of `IFileSystemStorageService`. Owns the + * concerns the storage service deliberately ignores: line framing, batching, + * and crash-tolerant decoding. Acquired handles share a keyed buffer; its final + * owner release starts a flush and retires that buffer once the flush settles, + * before a replacement buffer starts storage I/O for the same key. `rewrite` + * takes ownership at its call boundary: `records` replaces the history already + * durable before that cutover, while appends still queued or in flight remain + * a live tail that is drained after the atomic replacement. Callers must not + * also include those outstanding appends in `records`. An ambiguous append or + * rewrite failure remains sticky for that acquired buffer generation so a + * later flush cannot duplicate data by guessing whether storage committed it. + * A valid explicit `rewrite` is the recovery boundary: a successful atomic + * replacement clears that failure before the preserved live tail drains. + * `flush` and `close` wait for every keyed buffer to settle before reporting + * the first failure in stable key insertion order. + * + * This file ships the interface, error class, and DI token only. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; @@ -30,7 +53,6 @@ export interface IAppendLogStore { flush(): Promise; close(): Promise; acquire(scope: string, key: string): IDisposable; - drainRetirements(): Promise; } export const IAppendLogStore: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/persistence/interface/atomicDocumentStore.ts b/packages/agent-core-v2/src/persistence/interface/atomicDocumentStore.ts index c0e4f9f41..840dab03a 100644 --- a/packages/agent-core-v2/src/persistence/interface/atomicDocumentStore.ts +++ b/packages/agent-core-v2/src/persistence/interface/atomicDocumentStore.ts @@ -1,3 +1,13 @@ +/** + * `persistence/interface` — `IAtomicDocumentStore` contract. + * + * The atomic-document access-pattern store: one typed value per `(scope, + * key)`, replaced atomically on every write. Serialization is delegated to a + * `DocumentCodec` so the same access pattern serves different on-disk formats. + * + * This file ships the interface, codec contract, and DI tokens only. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { type IDisposable } from '#/_base/di/lifecycle'; import { type Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/persistence/interface/blobStore.ts b/packages/agent-core-v2/src/persistence/interface/blobStore.ts index 251f17874..f1a9c7bf0 100644 --- a/packages/agent-core-v2/src/persistence/interface/blobStore.ts +++ b/packages/agent-core-v2/src/persistence/interface/blobStore.ts @@ -1,3 +1,14 @@ +/** + * `persistence/interface` — `IBlobStore` contract. + * + * The blob access-pattern Store: write-once, key-addressed, potentially large + * objects. Sits alongside `IAppendLogStore` and `IAtomicDocumentStore` as the + * third generic access-pattern Store in the three-layer persistence model. + * + * Business services that need blob storage + * depend on this interface rather than on the raw `IFileSystemStorageService`. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IBlobStore { diff --git a/packages/agent-core-v2/src/persistence/interface/queryStore.ts b/packages/agent-core-v2/src/persistence/interface/queryStore.ts index 49b537ec5..5763f3bcf 100644 --- a/packages/agent-core-v2/src/persistence/interface/queryStore.ts +++ b/packages/agent-core-v2/src/persistence/interface/queryStore.ts @@ -1,3 +1,30 @@ +/** + * `IQueryStore` — the indexed, queryable read-model facade. + * + * A peer of `IAppendLogStore` and `IAtomicDocumentStore`. Where + * `IAppendLogStore` is the authoritative append-only write model and + * `IAtomicDocumentStore` holds atomic documents, `IQueryStore` serves fast, + * indexed, paginated reads over a *derived* dataset — typically materialized + * from an append log by a projector. + * + * This file intentionally ships the interface only. A concrete implementation + * (e.g. backed by `minidb`) and the projector that feeds it are a follow-up; + * the contract is fixed here so domains can depend on it without coupling to + * any specific engine. + * + * `collection` is a logical table (an engine may encode it as a key prefix). + * Values are plain JSON-shaped objects; indexes are declared over their fields. + * + * Ordered columns: a record may carry *columns* — numeric scalars declared at + * write time — that an engine keeps in an ordered structure so + * `pageByColumn` can serve bounded, sorted pages without scanning and + * re-sorting the whole collection. A column named `x` must duplicate a + * numeric field `x` present in the value (engines may order by either), and + * column names are store-wide: two collections must not reuse the same + * column name with different semantics. Sharding, WAL offsets, and engine + * generations stay backend-private and never appear here. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export type SortDir = 'asc' | 'desc'; @@ -25,6 +52,11 @@ export type QueryFilter = { export interface IQuery { where(filter: QueryFilter): IQuery; + /** + * Restrict to records whose ordered column `column` falls inside `bounds`. + * The column must have been declared at write time (`put`/`batch` with + * `columns`). + */ whereColumn(column: string, bounds: ColumnBounds): IQuery; orderBy(field: string, dir?: SortDir): IQuery; limit(n: number): IQuery; @@ -68,6 +100,7 @@ export interface Checkpoint { readonly seq: number; } +/** Numeric range bounds over an ordered column; every bound is optional. */ export interface ColumnBounds { readonly gt?: number; readonly gte?: number; @@ -75,6 +108,13 @@ export interface ColumnBounds { readonly lte?: number; } +/** + * A bounded page over an ordered column: rows whose column value falls inside + * `bounds` (all bounds optional), filtered by `filter`, ordered by the column + * in `dir` (default `'asc'`), at most `limit` rows. Rows sharing a column + * value come back in a deterministic but engine-specific order; a caller that + * needs a total order re-sorts the (bounded) page itself. + */ export interface ColumnPageQuery { readonly column: string; readonly dir?: SortDir; @@ -95,11 +135,19 @@ export interface IQueryStore { batch(ops: readonly WriteOp[]): Promise; delete(collection: string, key: string): Promise; get(collection: string, key: string): Promise; + /** Point reads for several keys; missing keys are absent from the result. */ getMany(collection: string, keys: readonly string[]): Promise>; query(collection: string): IQuery; + /** + * Bounded page over an ordered column (see `ColumnPageQuery`). This is the + * keyset-pagination primitive: it must stay cheap even over large + * collections (index walk, not a full scan + in-memory sort). + */ pageByColumn(collection: string, query: ColumnPageQuery): Promise>; ensureIndex(collection: string, def: IndexDef): Promise; + /** Every key currently in the collection (engine key decoding applied). */ listKeys(collection: string): Promise; + /** Delete the whole collection; a no-op when it does not exist. */ dropCollection(collection: string): Promise; getCheckpoint(source: string): Promise; setCheckpoint(source: string, checkpoint: Checkpoint): Promise; diff --git a/packages/agent-core-v2/src/persistence/interface/storage.ts b/packages/agent-core-v2/src/persistence/interface/storage.ts index 2bb68f4b9..1d55183cb 100644 --- a/packages/agent-core-v2/src/persistence/interface/storage.ts +++ b/packages/agent-core-v2/src/persistence/interface/storage.ts @@ -1,3 +1,34 @@ +/** + * `storage` domain — the filesystem persistence backend. + * + * `IFileSystemStorageService` is the filesystem-specific byte store. It + * exposes two irreducible durable primitives side by side: + * + * - `write` — atomic whole-value replacement (the `Config` access pattern). + * - `append` — ordered, durable byte extension (the `Record` access pattern). + * + * They are not interchangeable: building `append` on top of `write` is O(n) + * per append, and building `write` on top of `append` yields awkward "read + * the last value" semantics. Keeping both as first-class primitives lets each + * implementation implement them optimally (file: `open('a')` vs tmp+rename). + * + * `writeStream` is the streamed form of `write` for values too large to hold + * in memory: same whole-value replacement semantics (tmp + rename on the file + * backend), but the bytes arrive as an `AsyncIterable`. + * + * The service is byte-oriented and scope/key-addressed: `scope` maps to a + * directory, `key` maps to a filename. It knows nothing about JSON, records, + * configs, versions or framing. Those concerns live in the typed Store facades + * above it. + * + * Non-filesystem backends (Postgres, S3, Redis) do not implement this + * interface — they implement the Store interfaces directly via their own + * native clients. + * + * `scope`/`key` are trusted internal path segments for the file implementation + * (e.g. scope `"agents/main"`, key `"wire.jsonl"`); they are not user input. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; @@ -118,7 +149,6 @@ export function toStorageIoError(error: unknown, ctx: { path: string; op: string export interface StorageWriteOptions { readonly atomic?: boolean; - readonly signal?: AbortSignal; } export interface StorageAppendOptions { @@ -145,8 +175,6 @@ export interface IFileSystemStorageService { append(scope: string, key: string, data: Uint8Array, options?: StorageAppendOptions): Promise; list(scope: string, prefix?: string): Promise; delete(scope: string, key: string): Promise; - size(scope: string, key: string): Promise; - pathFor(scope: string, key: string): string | undefined; watch?(scope: string, key: string): Event; flush(): Promise; close(): Promise; diff --git a/packages/agent-core-v2/src/program/program.ts b/packages/agent-core-v2/src/program/program.ts deleted file mode 100644 index 56d3f3e82..000000000 --- a/packages/agent-core-v2/src/program/program.ts +++ /dev/null @@ -1,395 +0,0 @@ -import { Emitter, type Event } from '#/_base/event'; -import { UserFileSkillSource } from '#/features/skill/catalog/userFileSkillSource'; -import { FileProjectLocalConfigService } from '#/persistence/backends/node-fs/projectLocalConfigService'; -import type { RuntimeBinding, RuntimeLease } from '#/runtime/runtime'; -import { RuntimeError, type RuntimeGenerationSnapshot, type RuntimeRegistry, type RuntimeRegistryChange } from '#/runtime/runtimeRegistry'; -import type { SessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycleService'; -import { WorkspaceStateService } from '#/workspace/state/workspaceStateService'; -import type { IWorkspaceStateService } from '#/workspace/state/workspaceState'; -import type { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; -import type { IWorkspaceDirs } from '#/workspace/workspaceDirs/workspaceDirs'; -import { WorkspaceDirsService } from '#/workspace/workspaceDirs/workspaceDirsService'; -import type { IWorkspaceFsService } from '#/workspace/workspaceFs/fs'; -import { WorkspaceFsService } from '#/workspace/workspaceFs/fsService'; -import type { IWorkspaceFsWatchService } from '#/workspace/workspaceFs/fsWatch'; -import { WorkspaceFsWatchService } from '#/workspace/workspaceFs/fsWatchService'; -import type { IWorkspaceGitService } from '#/workspace/workspaceGit/workspaceGit'; -import { WorkspaceGitService } from '#/workspace/workspaceGit/workspaceGitService'; -import type { IWorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructions'; -import { WorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructionsService'; -import type { IWorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcp'; -import { WorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcpService'; -import type { IWorkspaceMcpConfigService } from '#/workspace/workspaceMcpConfig/workspaceMcpConfig'; -import { WorkspaceMcpConfigService } from '#/workspace/workspaceMcpConfig/workspaceMcpConfigService'; -import type { IWorkspaceTrust } from '#/workspace/workspaceTrust/workspaceTrust'; -import { WorkspaceTrustService } from '#/workspace/workspaceTrust/workspaceTrustService'; -import type { IExtraAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader'; -import { ExtraAgentProfileLoaderService } from '#/workspace/workspaceAgentProfileLoader/extraAgentProfileLoaderService'; -import type { IExplicitAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader'; -import { ExplicitAgentProfileLoaderService } from '#/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoaderService'; -import type { IPluginAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader'; -import { PluginAgentProfileLoaderService } from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService'; -import type { IUserAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoader'; -import { UserAgentProfileLoaderService } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoaderService'; -import type { IWorkspaceAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader'; -import { WorkspaceAgentProfileLoaderService } from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService'; -import { ExplicitFileSkillSource } from '#/features/skill/workspace/explicitFileSkillSource'; -import { ExtraFileSkillSource } from '#/features/skill/workspace/extraFileSkillSource'; -import { PluginSkillSource } from '#/features/skill/workspace/pluginSkillSource'; -import { WorkspaceRootSkillSource } from '#/features/skill/workspace/rootFileSkillSource'; -import { RuntimeSkillDiscovery } from '#/features/skill/workspace/runtimeSkillDiscovery'; -import type { IWorkspaceSkillCatalog } from '#/features/skill/workspace/workspaceSkillCatalog'; -import { WorkspaceSkillCatalogService } from '#/features/skill/workspace/workspaceSkillCatalogService'; -import type { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import type { ProgramDependencies } from './programDependencies'; - -export type ProgramStatus = 'preparing' | 'ready' | 'degraded'; - -export interface ProgramCatalogSnapshot { - readonly skills: { - readonly total: number; - readonly invocable: number; - readonly skipped: number; - }; - readonly agentProfiles: number; - readonly mcpServers: number; -} - -export interface ProgramSourceProvenanceSnapshot { - readonly skills: readonly { - readonly source: string; - readonly count: number; - }[]; - readonly skillRoots: readonly string[]; - readonly agentProfiles: readonly { - readonly sourceId: string; - readonly priority: number; - readonly profiles: readonly string[]; - }[]; - readonly instructionPaths: readonly string[]; - readonly mcpServers: readonly string[]; -} - -export interface ProgramSnapshot { - readonly workspaceId: string; - readonly binding: RuntimeBinding; - readonly status: ProgramStatus; - readonly ready: boolean; - readonly generation?: string; - readonly trusted?: boolean; - readonly catalog: ProgramCatalogSnapshot; - readonly sources: ProgramSourceProvenanceSnapshot; - readonly runtimes: readonly RuntimeGenerationSnapshot[]; -} - -interface ProgramGeneration { - readonly id: string; - readonly lease: RuntimeLease; - readonly state: IWorkspaceStateService; - readonly dirs: IWorkspaceDirs; - readonly fs: IWorkspaceFsService; - readonly watch: IWorkspaceFsWatchService; - readonly git: IWorkspaceGitService; - readonly instructions: IWorkspaceInstructionsService; - readonly mcpConfig: IWorkspaceMcpConfigService; - readonly mcp: IWorkspaceMcpService; - readonly trust: IWorkspaceTrust; - readonly skills: IWorkspaceSkillCatalog; - readonly agentProfiles: IWorkspaceAgentProfileLoader; - readonly userAgentProfiles: IUserAgentProfileLoader; - readonly pluginAgentProfiles: IPluginAgentProfileLoader; - readonly explicitAgentProfiles: IExplicitAgentProfileLoader; - readonly extraAgentProfiles: IExtraAgentProfileLoader; - readonly disposables: readonly { dispose(): void | Promise }[]; - ready: boolean; - failed: boolean; - references: number; - retired: boolean; -} - -const PROGRAM_CAPABILITIES = ['fs', 'process', 'watch'] as const; - -export class Program { - readonly binding: RuntimeBinding; - private currentStatus: ProgramStatus = 'preparing'; - private readonly changeEmitter = new Emitter(); - readonly onDidChange: Event = this.changeEmitter.event; - private readonly registrySubscription; - private readonly resolver: IRuntimeResolver; - private generation?: ProgramGeneration; - private generationFailed = false; - private disposed = false; - private resolveReady?: () => void; - readonly ready = new Promise((resolve) => { this.resolveReady = resolve; }); - - constructor( - readonly workspaceId: string, - private readonly runtimes: RuntimeRegistry, - private readonly context: IWorkspaceContext, - private readonly dependencies: ProgramDependencies, - ) { - this.binding = Object.freeze({ workspaceId, runtimeId: 'local' }); - this.resolver = { - _serviceBrand: undefined, - inspect: (binding) => this.runtimes.inspect(binding), - acquire: (binding, required) => this.runtimes.acquire(binding, required), - }; - this.registrySubscription = runtimes.onDidChange((change) => this.onRuntimeChange(change)); - this.reconcileGeneration(); - } - - get status(): ProgramStatus { return this.currentStatus; } - get state(): IWorkspaceStateService { return this.requireGeneration().state; } - get dirs(): IWorkspaceDirs { return this.requireGeneration().dirs; } - get fs(): IWorkspaceFsService { return this.requireGeneration().fs; } - get watch(): IWorkspaceFsWatchService { return this.requireGeneration().watch; } - get git(): IWorkspaceGitService { return this.requireGeneration().git; } - get instructions(): IWorkspaceInstructionsService { return this.requireGeneration().instructions; } - get mcpConfig(): IWorkspaceMcpConfigService { return this.requireGeneration().mcpConfig; } - get mcp(): IWorkspaceMcpService { return this.requireGeneration().mcp; } - get trust(): IWorkspaceTrust { return this.requireGeneration().trust; } - get skills(): IWorkspaceSkillCatalog { return this.requireGeneration().skills; } - get agentProfiles(): IWorkspaceAgentProfileLoader { return this.requireGeneration().agentProfiles; } - get sessionControllerGeneration(): string { return this.requireGeneration().id; } - - createSessionController(): SessionLifecycleService { - const generation = this.requireGeneration(); - generation.references += 1; - let released = false; - const release = (): void => { - if (released) return; - released = true; - this.releaseGeneration(generation); - }; - try { - const runtime = generation.lease.runtime; - return this.dependencies.createSessionController({ - context: this.context, - fs: runtime.fs!, - workspaceAgentProfiles: generation.agentProfiles, - extraAgentProfiles: generation.extraAgentProfiles, - explicitAgentProfiles: generation.explicitAgentProfiles, - userAgentProfiles: generation.userAgentProfiles, - pluginAgentProfiles: generation.pluginAgentProfiles, - dirs: generation.dirs, - skills: generation.skills, - instructions: generation.instructions, - mcp: generation.mcp, - onDispose: release, - }); - } catch (error) { - release(); - throw error; - } - } - - snapshot(): ProgramSnapshot { - const generation = this.generation; - const skills = generation?.skills.catalog.listSkills() ?? []; - const skillsBySource = new Map(); - for (const skill of skills) { - skillsBySource.set(skill.source, (skillsBySource.get(skill.source) ?? 0) + 1); - } - const agentProfiles = this.dependencies.agentProfiles.entries() - .filter((entry) => entry.workspaceKey === undefined || entry.workspaceKey === this.workspaceId) - .map((entry) => ({ - sourceId: entry.sourceId, - priority: entry.priority, - profiles: entry.contribution.profiles.map((profile) => profile.name), - })); - const mcpServers = Object.keys(generation?.mcpConfig.servers() ?? {}); - return { - workspaceId: this.workspaceId, - binding: this.binding, - status: this.currentStatus, - ready: generation?.ready === true, - generation: generation?.id, - trusted: generation?.trust.isTrusted(), - catalog: { - skills: { - total: skills.length, - invocable: generation?.skills.catalog.listInvocableSkills().length ?? 0, - skipped: generation?.skills.catalog.getSkippedByPolicy().length ?? 0, - }, - agentProfiles: agentProfiles.reduce((total, source) => total + source.profiles.length, 0), - mcpServers: mcpServers.length, - }, - sources: { - skills: [...skillsBySource].map(([source, count]) => ({ source, count })), - skillRoots: generation?.skills.catalog.getSkillRoots() ?? [], - agentProfiles, - instructionPaths: generation?.instructions.snapshot.agentsMdPaths ?? [], - mcpServers, - }, - runtimes: this.runtimes.snapshot().runtimes, - }; - } - - dispose(): void { - if (this.disposed) return; - this.disposed = true; - this.registrySubscription.dispose(); - const generation = this.generation; - this.generation = undefined; - if (generation !== undefined) this.retireGeneration(generation); - this.changeEmitter.dispose(); - } - - private requireGeneration(): ProgramGeneration { - if (this.generation === undefined) throw new Error(`program ${this.workspaceId} has no available local runtime generation`); - return this.generation; - } - - private onRuntimeChange(change: RuntimeRegistryChange): void { - if (change.runtimeId !== 'local' || this.disposed) return; - this.reconcileGeneration(); - } - - private reconcileGeneration(): void { - const local = this.runtimes.current('local'); - if (local === undefined) { - const previous = this.generation; - this.generation = undefined; - if (previous !== undefined) this.retireGeneration(previous); - this.refresh(); - return; - } - if (this.generation?.id !== local.identity.generation) { - const previous = this.generation; - this.generationFailed = false; - try { - const next = this.createGeneration(); - this.generation = next; - if (previous !== undefined) this.retireGeneration(previous); - this.observeReadiness(next); - } catch (error) { - if (!(error instanceof RuntimeError && error.code === 'runtime.unavailable')) { - this.generationFailed = true; - this.resolveProgramReady(); - } - } - } - this.refresh(); - } - - private createGeneration(): ProgramGeneration { - const lease = this.resolver.acquire(this.binding, PROGRAM_CAPABILITIES); - const runtime = lease.runtime; - const disposables: { dispose(): void | Promise }[] = []; - const own = }>(value: T): T => { - disposables.push(value); - return value; - }; - try { - const state = own(new WorkspaceStateService(this.dependencies.appState)); - const localConfig = new FileProjectLocalConfigService(this.dependencies.bootstrap, runtime.fs!); - const dirs = own(new WorkspaceDirsService(this.context, localConfig, runtime.watch!, this.dependencies.log, state)); - const git = new WorkspaceGitService(this.context, this.dependencies.git); - const fs = new WorkspaceFsService(this.context, dirs, runtime.fs!, this.resolver, this.dependencies.telemetry, git); - const watch = own(new WorkspaceFsWatchService(this.context, dirs, runtime.watch!, runtime.fs!)); - const instructions = own(new WorkspaceInstructionsService(this.context, runtime.fs!, runtime.environment, this.dependencies.bootstrap, runtime.watch!, this.dependencies.log, state)); - const trust = own(new WorkspaceTrustService(this.context, this.dependencies.docs, state)); - const mcpConfig = own(new WorkspaceMcpConfigService(this.context, this.dependencies.bootstrap, this.dependencies.plugins, this.dependencies.log, this.dependencies.config, runtime.watch!, runtime.fs!, trust, this.dependencies.configStore)); - const mcp = own(new WorkspaceMcpService(this.context, this.resolver, mcpConfig, this.dependencies.oauth, this.dependencies.log, this.dependencies.telemetry, this.dependencies.identity, this.dependencies.sessionManager)); - const userAgentProfiles = own(new UserAgentProfileLoaderService(this.dependencies.bootstrap, runtime.fs!, this.dependencies.log, this.dependencies.builtinAgentProfiles, this.context, this.dependencies.agentProfiles)); - const pluginAgentProfiles = own(new PluginAgentProfileLoaderService(this.dependencies.plugins, runtime.fs!, this.dependencies.log, userAgentProfiles, this.context, this.dependencies.agentProfiles)); - const explicitAgentProfiles = own(new ExplicitAgentProfileLoaderService(this.context, this.dependencies.bootstrap, runtime.fs!, this.dependencies.log, userAgentProfiles, this.dependencies.agentProfiles)); - const extraAgentProfiles = own(new ExtraAgentProfileLoaderService(this.dependencies.config, this.context, this.dependencies.bootstrap, runtime.fs!, this.dependencies.log, userAgentProfiles, this.dependencies.agentProfiles)); - const agentProfiles = own(new WorkspaceAgentProfileLoaderService(this.context, runtime.fs!, this.dependencies.log, userAgentProfiles, runtime.watch!, this.dependencies.agentProfiles)); - const skillDiscovery = new RuntimeSkillDiscovery(this.dependencies.log, runtime.fs!); - const userSkills = own(new UserFileSkillSource(skillDiscovery, this.dependencies.bootstrap, this.dependencies.config)); - const explicitSkills = new ExplicitFileSkillSource(skillDiscovery, this.context, this.dependencies.bootstrap); - const extraSkills = own(new ExtraFileSkillSource(skillDiscovery, this.dependencies.config, this.context, this.dependencies.bootstrap)); - const workspaceSkills = own(new WorkspaceRootSkillSource(skillDiscovery, this.context, this.dependencies.config, this.dependencies.bootstrap, runtime.watch!)); - const pluginSkills = new PluginSkillSource(skillDiscovery, this.dependencies.plugins); - const skills = own(new WorkspaceSkillCatalogService(this.dependencies.builtinSkills, userSkills, explicitSkills, extraSkills, workspaceSkills, pluginSkills, state)); - return { - id: runtime.identity.generation, - lease, - state, - dirs, - fs, - watch, - git, - instructions, - mcpConfig, - mcp, - trust, - skills, - agentProfiles, - userAgentProfiles, - pluginAgentProfiles, - explicitAgentProfiles, - extraAgentProfiles, - disposables, - ready: false, - failed: false, - references: 1, - retired: false, - }; - } catch (error) { - for (const disposable of disposables.reverse()) void disposable.dispose(); - lease.dispose(); - throw error; - } - } - - private observeReadiness(generation: ProgramGeneration): void { - void Promise.all([ - readiness(generation.dirs), - readiness(generation.instructions), - readiness(generation.mcpConfig), - readiness(generation.mcp), - readiness(generation.skills), - readiness(generation.agentProfiles), - ]).then( - () => { - if (this.generation !== generation) return; - generation.ready = true; - this.resolveProgramReady(); - this.refresh(); - }, - () => { - if (this.generation !== generation) return; - generation.failed = true; - this.resolveProgramReady(); - this.refresh(); - }, - ); - } - - private retireGeneration(generation: ProgramGeneration): void { - if (generation.retired) return; - generation.retired = true; - this.releaseGeneration(generation); - } - - private releaseGeneration(generation: ProgramGeneration): void { - generation.references -= 1; - if (generation.references !== 0 || !generation.retired) return; - for (const disposable of [...generation.disposables].reverse()) void disposable.dispose(); - generation.lease.dispose(); - } - - private resolveProgramReady(): void { - this.resolveReady?.(); - this.resolveReady = undefined; - } - - private refresh(): void { - const local = this.runtimes.current('local'); - if (local === undefined || local.status === 'connecting') this.currentStatus = 'preparing'; - else if (this.generationFailed || this.generation?.failed === true) this.currentStatus = 'degraded'; - else if (this.generation?.ready !== true) this.currentStatus = this.generation === undefined && local.status !== 'ready' ? 'degraded' : 'preparing'; - else this.currentStatus = local.status === 'ready' ? 'ready' : 'degraded'; - this.changeEmitter.fire(this.snapshot()); - } -} - -function readiness(value: unknown): Promise { - const ready = (value as { readonly ready?: unknown }).ready; - return ready !== null && typeof ready === 'object' && 'then' in ready - ? Promise.resolve(ready as PromiseLike).then(() => {}) - : Promise.resolve(); -} diff --git a/packages/agent-core-v2/src/program/programDependencies.ts b/packages/agent-core-v2/src/program/programDependencies.ts deleted file mode 100644 index 7ae41144d..000000000 --- a/packages/agent-core-v2/src/program/programDependencies.ts +++ /dev/null @@ -1,62 +0,0 @@ -import type { LiveRef } from '#/_base/di/instantiation'; -import type { ILogService } from '#/_base/log/log'; -import type { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; -import type { IBuiltinAgentProfileLoader } from '#/app/agentProfileCatalog/builtinAgentProfileLoader'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; -import type { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import type { IConfigService } from '#/app/config/config'; -import type { IGitService } from '#/app/git/git'; -import type { McpOAuthService } from '#/mcpCore/oauth/service'; -import type { IMcpConfigStore } from '#/app/mcpConfig/configStore'; -import type { IPluginService } from '#/app/plugin/plugin'; -import type { ISessionManager } from '#/app/sessionManager/sessionManager'; -import type { IBuiltinSkillSource } from '#/features/skill/catalog/builtinSkillSource'; -import type { IAppStateService } from '#/app/state/appState'; -import type { ITelemetryService } from '#/app/telemetry/telemetry'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import type { SessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycleService'; -import type { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; -import type { IExtraAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader'; -import type { IExplicitAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader'; -import type { IPluginAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader'; -import type { IUserAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoader'; -import type { IWorkspaceAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader'; -import type { IWorkspaceDirs } from '#/workspace/workspaceDirs/workspaceDirs'; -import type { IWorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructions'; -import type { IWorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcp'; -import type { IWorkspaceSkillCatalog } from '#/features/skill/workspace/workspaceSkillCatalog'; - -export interface ProgramSessionControllerInput { - readonly context: IWorkspaceContext; - readonly fs: IHostFileSystem; - readonly workspaceAgentProfiles: IWorkspaceAgentProfileLoader; - readonly extraAgentProfiles: IExtraAgentProfileLoader; - readonly explicitAgentProfiles: IExplicitAgentProfileLoader; - readonly userAgentProfiles: IUserAgentProfileLoader; - readonly pluginAgentProfiles: IPluginAgentProfileLoader; - readonly dirs: IWorkspaceDirs; - readonly skills: IWorkspaceSkillCatalog; - readonly instructions: IWorkspaceInstructionsService; - readonly mcp: IWorkspaceMcpService; - readonly onDispose: () => void; -} - -export interface ProgramDependencies { - readonly appState: IAppStateService; - readonly bootstrap: IBootstrapService; - readonly config: IConfigService; - readonly git: LiveRef; - readonly identity: IAgentIdentity; - readonly log: ILogService; - readonly oauth: McpOAuthService; - readonly configStore: IMcpConfigStore; - readonly plugins: IPluginService; - readonly sessionManager: LiveRef; - readonly agentProfiles: IAgentProfileRegistry; - readonly builtinAgentProfiles: IBuiltinAgentProfileLoader; - readonly builtinSkills: IBuiltinSkillSource; - readonly telemetry: ITelemetryService; - readonly docs: IAtomicDocumentStore; - createSessionController(input: ProgramSessionControllerInput): SessionLifecycleService; -} diff --git a/packages/agent-core-v2/src/runtime/fakeRuntime.ts b/packages/agent-core-v2/src/runtime/fakeRuntime.ts deleted file mode 100644 index 4b1c89253..000000000 --- a/packages/agent-core-v2/src/runtime/fakeRuntime.ts +++ /dev/null @@ -1,79 +0,0 @@ -import * as posixPath from 'node:path/posix'; -import * as win32Path from 'node:path/win32'; - -import { Emitter } from '#/_base/event'; - -import type { Runtime, RuntimeCapability, RuntimePath, RuntimeStatus } from './runtime'; - -export class FakeRuntime implements Runtime { - readonly capabilities: ReadonlySet; - readonly environment; - readonly path: RuntimePath; - readonly workspace; - readonly fs = undefined; - readonly process = undefined; - readonly watch = undefined; - readonly terminal = undefined; - private currentStatus: RuntimeStatus; - private readonly statusEmitter = new Emitter(); - readonly onDidChangeStatus = this.statusEmitter.event; - disposed = false; - - constructor( - readonly identity: Runtime['identity'], - options: { - readonly status?: RuntimeStatus; - readonly capabilities?: readonly RuntimeCapability[]; - readonly pathClass?: 'posix' | 'win32'; - readonly environment?: Partial; - readonly mapWorkspaceRoots?: Runtime['workspace']['mapRoots']; - } = {}, - ) { - this.currentStatus = options.status ?? 'ready'; - this.capabilities = new Set(options.capabilities ?? []); - const path = options.pathClass === 'win32' ? win32Path : posixPath; - this.environment = { - osKind: 'fake', - osArch: 'fake', - osVersion: 'fake', - shellName: 'sh' as const, - shellPath: '/bin/sh', - pathClass: options.pathClass ?? 'posix', - homeDir: options.pathClass === 'win32' ? 'C:\\Users\\fake' : '/home/fake', - ...options.environment, - }; - this.path = { - separator: path.sep as '/' | '\\', - delimiter: path.delimiter as ':' | ';', - isAbsolute: (p) => path.isAbsolute(p), - join: (...paths) => path.join(...paths), - relative: (from, to) => path.relative(from, to), - resolve: (...paths) => path.resolve(...paths), - basename: (p) => path.basename(p), - dirname: (p) => path.dirname(p), - }; - this.workspace = { - mapRoots: options.mapWorkspaceRoots ?? ((roots) => ({ - workDir: path.resolve(roots.workDir), - additionalDirs: roots.additionalDirs?.map((root) => path.resolve(root)), - })), - }; - } - - get status(): RuntimeStatus { - return this.currentStatus; - } - - setStatus(status: RuntimeStatus): void { - if (this.currentStatus === status) return; - this.currentStatus = status; - this.statusEmitter.fire(status); - } - - dispose(): void { - this.disposed = true; - this.currentStatus = 'disposed'; - this.statusEmitter.fire('disposed'); - this.statusEmitter.dispose(); - } -} diff --git a/packages/agent-core-v2/src/runtime/localRuntime.ts b/packages/agent-core-v2/src/runtime/localRuntime.ts deleted file mode 100644 index c86104361..000000000 --- a/packages/agent-core-v2/src/runtime/localRuntime.ts +++ /dev/null @@ -1,114 +0,0 @@ -import * as posixPath from 'node:path/posix'; -import * as win32Path from 'node:path/win32'; - -import { Emitter } from '#/_base/event'; -import { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IHostFsWatchService } from '#/os/interface/hostFsWatch'; -import { IHostProcessService } from '#/os/interface/hostProcess'; -import { IHostTerminalService } from '#/os/interface/terminal'; - -import type { Runtime, RuntimeCapability, RuntimePath, RuntimeStatus } from './runtime'; -import type { RuntimeProviderAttachment, RuntimeProviderContext, RuntimeProviderFactory } from './runtimeProvider'; -import type { RuntimeProviderHost } from './runtimeUnitHost'; - -let nextGeneration = 1; - -export class LocalRuntime implements Runtime { - readonly identity; - readonly capabilities: ReadonlySet; - readonly environment; - readonly path: RuntimePath; - readonly workspace: Runtime['workspace']; - readonly fs; - readonly process; - readonly watch; - readonly terminal; - private currentStatus: RuntimeStatus = 'ready'; - private readonly statusEmitter = new Emitter(); - readonly onDidChangeStatus = this.statusEmitter.event; - - constructor( - workspaceId: string, - environment: IHostEnvironment, - fs: IHostFileSystem | undefined, - process: IHostProcessService | undefined, - watch: IHostFsWatchService | undefined, - terminal: IHostTerminalService | undefined, - ) { - this.identity = { workspaceId, runtimeId: 'local', generation: `local-${nextGeneration++}` }; - const capabilities = new Set(); - if (fs !== undefined) capabilities.add('fs'); - if (process !== undefined) capabilities.add('process'); - if (watch !== undefined) capabilities.add('watch'); - if (terminal !== undefined) capabilities.add('terminal'); - this.capabilities = capabilities; - this.environment = { - osKind: environment.osKind, - osArch: environment.osArch, - osVersion: environment.osVersion, - shellName: environment.shellName, - shellPath: environment.shellPath, - pathClass: environment.pathClass, - homeDir: environment.homeDir, - }; - const path = environment.pathClass === 'win32' ? win32Path : posixPath; - this.path = { - separator: path.sep as '/' | '\\', - delimiter: path.delimiter as ':' | ';', - isAbsolute: (p) => path.isAbsolute(p), - join: (...paths) => path.join(...paths), - relative: (from, to) => path.relative(from, to), - resolve: (...paths) => path.resolve(...paths), - basename: (p) => path.basename(p), - dirname: (p) => path.dirname(p), - }; - this.workspace = { - mapRoots: (roots) => ({ - workDir: path.resolve(roots.workDir), - additionalDirs: roots.additionalDirs?.map((root) => path.resolve(root)), - }), - }; - this.fs = fs; - this.process = process; - this.watch = watch; - this.terminal = terminal; - } - - get status(): RuntimeStatus { - return this.currentStatus; - } - - dispose(): void { - this.currentStatus = 'disposed'; - this.statusEmitter.fire('disposed'); - this.statusEmitter.dispose(); - } -} - -export class LocalRuntimeProviderFactory implements RuntimeProviderFactory { - readonly id = 'local'; - readonly imports = { - root: [ - IHostEnvironment, - IHostFileSystem, - IHostProcessService, - IHostFsWatchService, - IHostTerminalService, - ], - imports: [], - local: [], - }; - - async attach(context: RuntimeProviderContext, host: RuntimeProviderHost): Promise { - const handle = host.registerRuntime(new LocalRuntime( - context.id, - host.get(IHostEnvironment), - host.get(IHostFileSystem), - host.get(IHostProcessService), - host.get(IHostFsWatchService), - host.get(IHostTerminalService), - )); - return { dispose: () => handle.remove() }; - } -} diff --git a/packages/agent-core-v2/src/runtime/runtime.ts b/packages/agent-core-v2/src/runtime/runtime.ts deleted file mode 100644 index cd2b3ecc4..000000000 --- a/packages/agent-core-v2/src/runtime/runtime.ts +++ /dev/null @@ -1,59 +0,0 @@ -import type { Event } from '#/_base/event'; -import type { HostEnvironmentInfo } from '#/os/interface/hostEnvironment'; -import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import type { IHostFsWatchService } from '#/os/interface/hostFsWatch'; -import type { IHostProcessService } from '#/os/interface/hostProcess'; -import type { IHostTerminalService } from '#/os/interface/terminal'; - -export type RuntimeStatus = 'connecting' | 'ready' | 'degraded' | 'disconnected' | 'draining' | 'disposed'; -export type RuntimeCapability = 'fs' | 'process' | 'watch' | 'terminal'; - -export interface RuntimeBinding { - readonly workspaceId: string; - readonly runtimeId: string; -} - -export interface RuntimeIdentity extends RuntimeBinding { - readonly generation: string; -} - -export interface RuntimePath { - readonly separator: '/' | '\\'; - readonly delimiter: ':' | ';'; - isAbsolute(path: string): boolean; - join(...paths: readonly string[]): string; - relative(from: string, to: string): string; - resolve(...paths: readonly string[]): string; - basename(path: string): string; - dirname(path: string): string; -} - -export interface RuntimeWorkspaceRoots { - readonly workDir: string; - readonly additionalDirs?: readonly string[]; -} - -export interface RuntimeWorkspaceMapper { - mapRoots(roots: RuntimeWorkspaceRoots): RuntimeWorkspaceRoots; -} - -export interface Runtime { - readonly identity: RuntimeIdentity; - readonly capabilities: ReadonlySet; - readonly environment: HostEnvironmentInfo; - readonly path: RuntimePath; - readonly workspace: RuntimeWorkspaceMapper; - readonly fs?: IHostFileSystem; - readonly process?: IHostProcessService; - readonly watch?: IHostFsWatchService; - readonly terminal?: IHostTerminalService; - readonly status: RuntimeStatus; - readonly onDidChangeStatus: Event; - dispose(): void | Promise; -} - -export interface RuntimeLease { - readonly runtime: Runtime; - track }>(resource: T): T; - dispose(): void; -} diff --git a/packages/agent-core-v2/src/runtime/runtimeProvider.ts b/packages/agent-core-v2/src/runtime/runtimeProvider.ts deleted file mode 100644 index 20b7ab0b9..000000000 --- a/packages/agent-core-v2/src/runtime/runtimeProvider.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { Workspace } from '#/app/workspace/workspace'; - -import type { RuntimeProviderHost, RuntimeUnitImports } from './runtimeUnitHost'; - -export interface RuntimeProviderAttachment { - dispose(): void | Promise; -} - -export interface RuntimeProviderContext { - readonly id: string; - readonly root: string; - readonly metadata: Workspace; -} - -export interface RuntimeProviderFactory { - readonly id: string; - readonly imports: RuntimeUnitImports; - attach(context: RuntimeProviderContext, host: RuntimeProviderHost): Promise; -} diff --git a/packages/agent-core-v2/src/runtime/runtimeRegistry.ts b/packages/agent-core-v2/src/runtime/runtimeRegistry.ts deleted file mode 100644 index 659acc5be..000000000 --- a/packages/agent-core-v2/src/runtime/runtimeRegistry.ts +++ /dev/null @@ -1,334 +0,0 @@ -import { Emitter, type Event } from '#/_base/event'; - -import type { Runtime, RuntimeBinding, RuntimeCapability, RuntimeLease } from './runtime'; - -export const RUNTIME_DRAIN_TIMEOUT_MS = 5_000; - -export type RuntimeErrorCode = 'runtime.not_found' | 'runtime.unavailable' | 'runtime.capability_unavailable' | 'runtime.conflict'; - -export class RuntimeError extends Error { - constructor(readonly code: RuntimeErrorCode, message: string) { - super(message); - this.name = 'RuntimeError'; - } -} - -export interface RuntimeResource { - dispose(): void | Promise; -} - -interface Generation { - readonly runtime: Runtime; - readonly resources: Set; - readonly statusSubscription: { dispose(): void }; - leases: number; - draining: boolean; - disposed: boolean; - drainPromise?: Promise; - releaseDrain?: () => void; -} - -export interface RuntimeRegistryChange { - readonly runtimeId: string; - readonly current?: Runtime; - readonly status?: Runtime['status'] | 'draining'; -} - -export interface RuntimeGenerationSnapshot { - readonly runtimeId: string; - readonly generation: string; - readonly status: Runtime['status']; - readonly capabilities: readonly RuntimeCapability[]; -} - -export interface RuntimeRegistrySnapshot { - readonly workspaceId: string; - readonly runtimes: readonly RuntimeGenerationSnapshot[]; -} - -export interface RuntimeRegistrationHandle { - readonly runtimeId: string; - replace(runtime: Runtime): Promise; - remove(): Promise; -} - -export interface RuntimeRegistryBatchEntry { - readonly runtime: Runtime; - readonly current?: Runtime; - readonly registration?: RuntimeRegistrationHandle; -} - -export interface RuntimeRegistryBatchResult { - readonly registrations: readonly RuntimeRegistrationHandle[]; - readonly cleanup: Promise; -} - -export class RuntimeRegistry { - private readonly currentGenerations = new Map(); - private readonly changeEmitter = new Emitter(); - readonly onDidChange: Event = this.changeEmitter.event; - private disposing = false; - - constructor( - readonly workspaceId: string, - private readonly drainTimeoutMs = RUNTIME_DRAIN_TIMEOUT_MS, - ) {} - - list(): readonly Runtime[] { - return [...this.currentGenerations.values()].map((value) => value.runtime); - } - - snapshot(): RuntimeRegistrySnapshot { - return { - workspaceId: this.workspaceId, - runtimes: this.list().map((runtime) => ({ - runtimeId: runtime.identity.runtimeId, - generation: runtime.identity.generation, - status: runtime.status, - capabilities: [...runtime.capabilities], - })), - }; - } - - current(runtimeId: string): Runtime | undefined { - return this.currentGenerations.get(runtimeId)?.runtime; - } - - inspect(binding: RuntimeBinding): Runtime { - if (binding.workspaceId !== this.workspaceId) { - throw new RuntimeError('runtime.not_found', `workspace ${binding.workspaceId} is not ${this.workspaceId}`); - } - const runtime = this.currentGenerations.get(binding.runtimeId)?.runtime; - if (runtime === undefined) { - throw new RuntimeError('runtime.not_found', `runtime ${binding.runtimeId} does not exist in workspace ${this.workspaceId}`); - } - return runtime; - } - - prepare(runtime: Runtime, expectedRuntimeId?: string): void { - if (this.disposing) throw new RuntimeError('runtime.unavailable', `runtime registry ${this.workspaceId} is disposing`); - this.assertPrepared(runtime, expectedRuntimeId); - } - - register(runtime: Runtime): RuntimeRegistrationHandle { - return this.publishBatch([{ runtime }]).registrations[0]!; - } - - publishBatch(entries: readonly RuntimeRegistryBatchEntry[]): RuntimeRegistryBatchResult { - if (this.disposing) throw new RuntimeError('runtime.unavailable', `runtime registry ${this.workspaceId} is disposing`); - const runtimeIds = new Set(); - const prepared = entries.map((entry) => { - const runtimeId = entry.runtime.identity.runtimeId; - if (runtimeIds.has(runtimeId)) { - throw new RuntimeError('runtime.conflict', `runtime ${runtimeId} appears twice in one registry batch`); - } - runtimeIds.add(runtimeId); - const replacement = entry.current !== undefined || entry.registration !== undefined; - if (replacement && (entry.current === undefined || entry.registration === undefined)) { - throw new Error(`runtime ${runtimeId} replacement requires its current runtime and registration`); - } - this.assertPrepared(entry.runtime, replacement ? runtimeId : undefined); - const previous = this.currentGenerations.get(runtimeId); - if (!replacement) { - if (previous !== undefined) { - throw new RuntimeError('runtime.conflict', `runtime ${runtimeId} already exists in workspace ${this.workspaceId}`); - } - } else { - if (entry.registration!.runtimeId !== runtimeId) { - throw new Error(`runtime registration ${entry.registration!.runtimeId} cannot replace ${runtimeId}`); - } - if (previous?.runtime !== entry.current) { - throw new RuntimeError('runtime.conflict', `runtime ${runtimeId} changed before registry batch publication`); - } - } - return { entry, previous }; - }); - const generations: Generation[] = []; - try { - for (const item of prepared) generations.push(this.createGeneration(item.entry.runtime)); - } catch (error) { - for (const generation of generations) generation.statusSubscription.dispose(); - throw error; - } - const registrations = prepared.map((item) => - item.entry.registration ?? this.createRegistration(item.entry.runtime.identity.runtimeId), - ); - for (let index = 0; index < prepared.length; index += 1) { - const runtimeId = prepared[index]!.entry.runtime.identity.runtimeId; - this.currentGenerations.set(runtimeId, generations[index]!); - } - for (const generation of generations) this.publish(generation); - const cleanup = Promise.all( - prepared.flatMap((item) => item.previous === undefined ? [] : [this.drain(item.previous)]), - ).then(() => {}); - return { registrations, cleanup }; - } - - acquire(binding: RuntimeBinding, required: readonly RuntimeCapability[] = []): RuntimeLease { - if (binding.workspaceId !== this.workspaceId) { - throw new RuntimeError('runtime.not_found', `workspace ${binding.workspaceId} is not ${this.workspaceId}`); - } - const generation = this.currentGenerations.get(binding.runtimeId); - if (generation === undefined) { - throw new RuntimeError('runtime.not_found', `runtime ${binding.runtimeId} does not exist in workspace ${this.workspaceId}`); - } - if (generation.draining || !runtimeStatusAllows(generation.runtime, required)) { - throw new RuntimeError('runtime.unavailable', `runtime ${binding.runtimeId} is ${generation.draining ? 'draining' : generation.runtime.status}`); - } - for (const capability of required) { - if (!generation.runtime.capabilities.has(capability)) { - throw new RuntimeError('runtime.capability_unavailable', `runtime ${binding.runtimeId} does not provide ${capability}`); - } - } - generation.leases += 1; - let active = true; - const release = (): void => { - if (!active) return; - active = false; - generation.leases -= 1; - if (generation.leases === 0) generation.releaseDrain?.(); - }; - return { - runtime: generation.runtime, - track: (resource: T): T => { - if (!active || generation.draining) throw new RuntimeError('runtime.unavailable', `runtime ${binding.runtimeId} is draining`); - const originalDispose = resource.dispose.bind(resource); - let disposed = false; - resource.dispose = function () { - if (disposed) return; - disposed = true; - generation.resources.delete(resource); - return originalDispose(); - } as T['dispose']; - generation.resources.add(resource); - return resource; - }, - dispose: release, - }; - } - - async dispose(): Promise { - if (this.disposing) return; - this.disposing = true; - const generations = [...this.currentGenerations.values()]; - this.currentGenerations.clear(); - for (const generation of generations.reverse()) await this.drain(generation); - this.changeEmitter.dispose(); - } - - private createRegistration(runtimeId: string): RuntimeRegistrationHandle { - let active = true; - let operation = Promise.resolve(); - const enqueue = (work: () => Promise): Promise => { - const next = operation.then(work, work); - operation = next.catch(() => {}); - return next; - }; - let handle: RuntimeRegistrationHandle; - handle = { - runtimeId, - replace: (replacement) => enqueue(async () => { - if (!active || this.disposing) { - await replacement.dispose(); - throw new Error(`runtime registration ${runtimeId} is disposed`); - } - const previous = this.currentGenerations.get(runtimeId); - if (previous === undefined) { - await replacement.dispose(); - throw new Error(`runtime ${runtimeId} is not registered`); - } - let publication: RuntimeRegistryBatchResult; - try { - publication = this.publishBatch([{ - runtime: replacement, - current: previous.runtime, - registration: handle, - }]); - } catch (error) { - await replacement.dispose(); - throw error; - } - await publication.cleanup; - }), - remove: () => enqueue(async () => { - if (!active) return; - active = false; - const previous = this.currentGenerations.get(runtimeId); - if (previous === undefined) return; - this.currentGenerations.delete(runtimeId); - this.changeEmitter.fire({ runtimeId }); - await this.drain(previous); - }), - }; - return handle; - } - - private createGeneration(runtime: Runtime): Generation { - const generation = { - runtime, - resources: new Set(), - leases: 0, - draining: false, - disposed: false, - statusSubscription: undefined as unknown as { dispose(): void }, - }; - generation.statusSubscription = runtime.onDidChangeStatus((status) => { - if (!generation.draining && !generation.disposed && this.currentGenerations.get(runtime.identity.runtimeId) === generation) { - this.changeEmitter.fire({ runtimeId: runtime.identity.runtimeId, current: runtime, status }); - } - }); - return generation; - } - - private publish(generation: Generation): void { - this.changeEmitter.fire({ - runtimeId: generation.runtime.identity.runtimeId, - current: generation.runtime, - status: generation.runtime.status, - }); - } - - private assertPrepared(runtime: Runtime, expectedRuntimeId?: string): void { - if (runtime.identity.workspaceId !== this.workspaceId) throw new Error(`runtime belongs to workspace ${runtime.identity.workspaceId}`); - if (expectedRuntimeId !== undefined && runtime.identity.runtimeId !== expectedRuntimeId) throw new Error(`replacement runtime id must remain ${expectedRuntimeId}`); - if (runtime.status === 'draining' || runtime.status === 'disposed') throw new RuntimeError('runtime.unavailable', `runtime ${runtime.identity.runtimeId} is ${runtime.status}`); - for (const capability of runtime.capabilities) { - if (runtime[capability] === undefined) throw new RuntimeError('runtime.capability_unavailable', `runtime ${runtime.identity.runtimeId} declares ${capability} without an implementation`); - } - } - - private drain(generation: Generation): Promise { - generation.drainPromise ??= (async () => { - generation.draining = true; - generation.statusSubscription.dispose(); - this.changeEmitter.fire({ - runtimeId: generation.runtime.identity.runtimeId, - current: generation.runtime, - status: 'draining', - }); - const resources = [...generation.resources].reverse(); - generation.resources.clear(); - for (const resource of resources) { - try { - await resource.dispose(); - } catch {} - } - if (generation.leases > 0) { - await Promise.race([ - new Promise((resolve) => { generation.releaseDrain = resolve; }), - new Promise((resolve) => setTimeout(resolve, this.drainTimeoutMs)), - ]); - } - if (!generation.disposed) { - generation.disposed = true; - await generation.runtime.dispose(); - } - })(); - return generation.drainPromise; - } -} - -export function runtimeStatusAllows(runtime: Runtime, required: readonly RuntimeCapability[]): boolean { - if (runtime.status === 'ready') return true; - return runtime.status === 'degraded' && required.every((capability) => runtime.capabilities.has(capability)); -} diff --git a/packages/agent-core-v2/src/runtime/runtimeUnitHost.ts b/packages/agent-core-v2/src/runtime/runtimeUnitHost.ts deleted file mode 100644 index 2d750f658..000000000 --- a/packages/agent-core-v2/src/runtime/runtimeUnitHost.ts +++ /dev/null @@ -1,432 +0,0 @@ -import { SyncDescriptor } from '#/_base/di/descriptors'; -import { _util, type IInstantiationService, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { ServiceCollection } from '#/_base/di/serviceCollection'; -import type { Runtime } from './runtime'; -import type { RuntimeRegistrationHandle, RuntimeRegistry } from './runtimeRegistry'; - -type RuntimeUnitConstructor = new (...args: never[]) => T; - -export interface RuntimeUnitImports { - readonly root: readonly ServiceIdentifier[]; - readonly imports: readonly ServiceIdentifier[]; - readonly local: readonly ServiceIdentifier[]; -} - -export interface RuntimeProviderRuntimeHandle { - readonly runtimeId: string; - update(prepare: () => Runtime | Promise): Promise; - remove(): Promise; -} - -export interface RuntimeProviderHost { - get(id: ServiceIdentifier): T; - provide(id: ServiceIdentifier, ctor: RuntimeUnitConstructor, ...staticArguments: unknown[]): T; - registerRuntime(runtime: Runtime): RuntimeProviderRuntimeHandle; -} - -export interface RuntimeUnitHandle { - update }>( - imports: RuntimeUnitImports, - prepare: (host: RuntimeProviderHost) => Promise, - ): Promise; - remove(): Promise; - dispose(): Promise; -} - -export interface RuntimeUnitHost { - provide }>( - imports: RuntimeUnitImports, - prepare: (host: RuntimeProviderHost) => Promise, - ): Promise; - update }>( - handle: RuntimeUnitHandle, - imports: RuntimeUnitImports, - prepare: (host: RuntimeProviderHost) => Promise, - ): Promise; - remove(handle: RuntimeUnitHandle): Promise; - dispose(): Promise; -} - -export interface RuntimeUnitHostFactory { - create(root: IInstantiationService, registry: RuntimeRegistry): RuntimeUnitHost; -} - -export class SharedRuntimeUnitHostFactory implements RuntimeUnitHostFactory { - create(root: IInstantiationService, registry: RuntimeRegistry): RuntimeUnitHost { - return new SharedRuntimeUnitHost(root, registry); - } -} - -interface LocalRegistration { - readonly id: ServiceIdentifier; - readonly value: unknown; -} - -interface RuntimeUnitTransaction { - readonly host: RuntimeProviderHost; - readonly units: Array<{ dispose(): void | Promise }>; - readonly local: LocalRegistration[]; - readonly runtimes: StagedRuntime[]; - dispose(): Promise; - commit(): { readonly cleanup: Promise }; -} - -interface StagedRuntime { - runtime: Runtime; - registration?: RuntimeRegistrationHandle; - active: boolean; -} - -interface RuntimeUnitRecord { - attachment: { dispose(): void | Promise }; - transaction: RuntimeUnitTransaction; - active: boolean; - handle?: RuntimeUnitHandle; -} - -class SharedRuntimeUnitHost implements RuntimeUnitHost { - private readonly records: RuntimeUnitRecord[] = []; - private readonly recordByHandle = new Map(); - private readonly locals = new Map, LocalRegistration>(); - private tail = Promise.resolve(); - private closing = false; - - constructor(private readonly root: IInstantiationService, private readonly registry: RuntimeRegistry) {} - - provide }>( - imports: RuntimeUnitImports, - prepare: (host: RuntimeProviderHost) => Promise, - ): Promise { - if (this.closing) return Promise.reject(new Error('runtime unit host is disposed')); - return this.enqueue(async () => { - this.assertOpen(); - const transaction = this.createTransaction(imports); - let attachment: T; - let cleanup: Promise; - try { - attachment = await prepare(transaction.host); - cleanup = transaction.commit().cleanup; - } catch (error) { - await transaction.dispose(); - throw error; - } - const record: RuntimeUnitRecord = { attachment, transaction, active: true }; - const handle = this.handle(record); - record.handle = handle; - this.records.push(record); - this.recordByHandle.set(handle, record); - await cleanup; - return handle; - }); - } - - update }>( - handle: RuntimeUnitHandle, - imports: RuntimeUnitImports, - prepare: (host: RuntimeProviderHost) => Promise, - ): Promise { - if (this.closing) return Promise.reject(new Error('runtime unit host is disposed')); - return this.enqueue(async () => { - this.assertOpen(); - const record = this.find(handle); - if (!record.active) throw new Error('runtime unit handle is disposed'); - const transaction = this.createTransaction(imports, record.transaction); - let attachment: T; - let cleanup: Promise; - try { - attachment = await prepare(transaction.host); - cleanup = transaction.commit().cleanup; - } catch (error) { - await transaction.dispose(); - throw error; - } - const previousAttachment = record.attachment; - const previousTransaction = record.transaction; - record.attachment = attachment; - record.transaction = transaction; - let failure: unknown; - let failed = false; - try { - await cleanup; - } catch (error) { - failure = error; - failed = true; - } - try { - await previousAttachment.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - try { - await previousTransaction.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - if (failed) throw failure; - }); - } - - remove(handle: RuntimeUnitHandle): Promise { - return this.enqueue(async () => { - const record = this.find(handle); - if (!record.active) return; - record.active = false; - let failure: unknown; - let failed = false; - try { - await record.attachment.dispose(); - } catch (error) { - failure = error; - failed = true; - } - try { - await record.transaction.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - const index = this.records.indexOf(record); - if (index >= 0) this.records.splice(index, 1); - this.recordByHandle.delete(handle); - if (failed) throw failure; - }); - } - - async dispose(): Promise { - if (this.closing) return this.tail; - this.closing = true; - await this.tail; - await this.enqueue(async () => { - let failure: unknown; - let failed = false; - for (const record of [...this.records].reverse()) { - if (!record.active) continue; - record.active = false; - try { - await record.attachment.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - try { - await record.transaction.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - if (record.handle !== undefined) this.recordByHandle.delete(record.handle); - } - this.records.length = 0; - if (failed) throw failure; - }); - await this.tail; - } - - private handle(_record: RuntimeUnitRecord): RuntimeUnitHandle { - const handle: RuntimeUnitHandle = { - update: (imports, prepare) => this.update(handle, imports, prepare), - remove: () => this.remove(handle), - dispose: () => this.remove(handle), - }; - return handle; - } - - private find(handle: RuntimeUnitHandle): RuntimeUnitRecord { - const record = this.recordByHandle.get(handle); - if (record === undefined) throw new Error('runtime unit handle is not owned by this host'); - return record; - } - - private enqueue(work: () => Promise): Promise { - const next = this.tail.then(work, work); - this.tail = next.then(() => {}, () => {}); - return next; - } - - private assertOpen(): void { - if (this.closing) throw new Error('runtime unit host is disposed'); - } - - private createTransaction(imports: RuntimeUnitImports, previous?: RuntimeUnitTransaction): RuntimeUnitTransaction { - const declared = new Set([...imports.root, ...imports.imports, ...imports.local]); - if (declared.size !== imports.root.length + imports.imports.length + imports.local.length) { - throw new Error('runtime unit dependency manifest contains duplicate declarations'); - } - const services = new ServiceCollection(); - const units: Array<{ dispose(): void | Promise }> = []; - const local: LocalRegistration[] = []; - const runtimes: StagedRuntime[] = []; - let active = true; - let committed = false; - for (const id of imports.root) { - services.set(id, this.root.invokeFunction((accessor) => accessor.get(id))); - } - for (const id of imports.imports) { - const registration = this.locals.get(id); - if (registration === undefined) throw new Error(`runtime unit import is not available ${id.toString()}`); - services.set(id, registration.value); - } - const child = this.root.createChild(services); - const host: RuntimeProviderHost = { - get: (id: ServiceIdentifier): T => { - if (!active || !declared.has(id)) throw new Error(`runtime unit dependency is not declared ${id.toString()}`); - if (imports.local.includes(id) && !local.some((registration) => registration.id === id)) { - throw new Error(`runtime unit local dependency is not available ${id.toString()}`); - } - return child.invokeFunction((accessor) => accessor.get(id)); - }, - provide: (id: ServiceIdentifier, ctor: RuntimeUnitConstructor, ...staticArguments: unknown[]): T => { - if (!active || !imports.local.includes(id)) throw new Error(`runtime unit local registration is not declared ${id.toString()}`); - if (local.some((registration) => registration.id === id)) throw new Error(`runtime unit local registration already exists ${id.toString()}`); - for (const dependency of _util.getInstanceDependencies(ctor as unknown as _util.DI_TARGET_OBJ)) { - if (!declared.has(dependency.id)) throw new Error(`runtime unit dependency is not declared ${dependency.id.toString()}`); - if (imports.local.includes(dependency.id) && !local.some((registration) => registration.id === dependency.id)) { - throw new Error(`runtime unit local dependency is not available ${dependency.id.toString()}`); - } - } - const unit = child.createInstance(new SyncDescriptor(ctor as never, staticArguments)) as T; - services.set(id, unit); - local.push({ id, value: unit }); - const disposable = unit as { dispose?: () => void | Promise }; - if (typeof disposable.dispose === 'function') units.push(disposable as { dispose(): void | Promise }); - return unit; - }, - registerRuntime: (runtime) => { - if (!active) throw new Error('runtime unit transaction is disposed'); - if (runtimes.some((entry) => entry.runtime.identity.runtimeId === runtime.identity.runtimeId)) { - throw new Error(`runtime ${runtime.identity.runtimeId} is registered twice in one transaction`); - } - const staged: StagedRuntime = { runtime, active: true }; - if (committed) staged.registration = this.registry.register(runtime); - runtimes.push(staged); - const handle: RuntimeProviderRuntimeHandle = { - runtimeId: runtime.identity.runtimeId, - update: (replacement) => this.updateRuntime(staged, replacement), - remove: async () => { - try { - await this.removeRuntime(staged); - } finally { - const index = runtimes.indexOf(staged); - if (index >= 0) runtimes.splice(index, 1); - } - }, - }; - return handle; - }, - }; - const transaction: RuntimeUnitTransaction = { - host, - units, - local, - runtimes, - commit: () => { - if (!active) throw new Error('runtime unit transaction is disposed'); - const previousRuntimes = new Map( - previous?.runtimes.map((staged) => [staged.runtime.identity.runtimeId, staged]) ?? [], - ); - const previousLocals = new Set(previous?.local.map((registration) => registration.id) ?? []); - for (const staged of runtimes) { - const current = this.registry.current(staged.runtime.identity.runtimeId); - const previousRuntime = previousRuntimes.get(staged.runtime.identity.runtimeId); - if (current !== undefined && previousRuntime === undefined) { - throw new Error(`runtime ${staged.runtime.identity.runtimeId} already exists`); - } - this.registry.prepare( - staged.runtime, - previousRuntime === undefined ? undefined : staged.runtime.identity.runtimeId, - ); - } - for (const registration of local) { - if (this.locals.has(registration.id) && !previousLocals.has(registration.id)) { - throw new Error(`runtime unit local registration already exists ${registration.id.toString()}`); - } - } - const publication = this.registry.publishBatch(runtimes.map((staged) => { - const previousRuntime = previousRuntimes.get(staged.runtime.identity.runtimeId); - if (previousRuntime?.registration === undefined) return { runtime: staged.runtime }; - return { - runtime: staged.runtime, - current: previousRuntime.runtime, - registration: previousRuntime.registration, - }; - })); - for (let index = 0; index < runtimes.length; index += 1) { - const staged = runtimes[index]!; - const previousRuntime = previousRuntimes.get(staged.runtime.identity.runtimeId); - if (previousRuntime !== undefined) previousRuntime.active = false; - staged.registration = publication.registrations[index]; - } - for (const registration of local) this.locals.set(registration.id, registration); - committed = true; - return { cleanup: publication.cleanup }; - }, - dispose: async () => { - if (!active) return; - active = false; - let failure: unknown; - let failed = false; - for (const staged of runtimes.reverse()) { - if (!staged.active) continue; - staged.active = false; - try { - if (staged.registration === undefined) await staged.runtime.dispose(); - else await staged.registration.remove(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - } - for (const registration of local.reverse()) { - if (this.locals.get(registration.id) === registration) this.locals.delete(registration.id); - } - for (const unit of units.reverse()) { - try { - await unit.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - } - try { - child.dispose(); - } catch (error) { - if (!failed) failure = error; - failed = true; - } - if (failed) throw failure; - }, - }; - return transaction; - } - - private updateRuntime(staged: StagedRuntime, prepare: () => Runtime | Promise): Promise { - if (this.closing) return Promise.reject(new Error('runtime unit host is disposed')); - return this.enqueue(async () => { - if (!staged.active || staged.registration === undefined) throw new Error('runtime registration is not active'); - const replacement = await prepare(); - let cleanup: Promise; - try { - this.registry.prepare(replacement, staged.runtime.identity.runtimeId); - cleanup = this.registry.publishBatch([{ - runtime: replacement, - current: staged.runtime, - registration: staged.registration, - }]).cleanup; - } catch (error) { - await replacement.dispose(); - throw error; - } - staged.runtime = replacement; - await cleanup; - }); - } - - private async removeRuntime(staged: StagedRuntime): Promise { - if (!staged.active) return; - staged.active = false; - if (staged.registration === undefined) await staged.runtime.dispose(); - else await staged.registration.remove(); - } -} diff --git a/packages/agent-core-v2/src/runtime/runtimeWorkspaceView.ts b/packages/agent-core-v2/src/runtime/runtimeWorkspaceView.ts deleted file mode 100644 index 03edbdba4..000000000 --- a/packages/agent-core-v2/src/runtime/runtimeWorkspaceView.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ErrorCodes, Error2 } from '#/errors'; -import { getShellPathBridge } from '#/_base/execEnv/shellPathBridge'; - -import type { Runtime, RuntimeBinding, RuntimeWorkspaceRoots } from './runtime'; - -export type { RuntimeWorkspaceRoots } from './runtime'; - -export class RuntimeWorkspaceView { - readonly binding: RuntimeBinding; - readonly generation: string; - readonly workDir: string; - readonly additionalDirs: readonly string[]; - readonly roots: readonly string[]; - - constructor( - readonly runtime: Runtime, - roots: RuntimeWorkspaceRoots, - ) { - this.binding = { - workspaceId: runtime.identity.workspaceId, - runtimeId: runtime.identity.runtimeId, - }; - this.generation = runtime.identity.generation; - const mapped = runtime.workspace.mapRoots(roots); - this.workDir = runtime.path.resolve(mapped.workDir); - this.additionalDirs = [...new Set((mapped.additionalDirs ?? []).map((root) => runtime.path.resolve(root)))]; - this.roots = [this.workDir, ...this.additionalDirs]; - } - - resolve(path: string, cwd = this.workDir): string { - const env = this.runtime.environment; - const bridged = env.pathClass === 'win32' ? getShellPathBridge(env).fromShellPath(path) : path; - const resolved = this.runtime.path.isAbsolute(bridged) - ? this.runtime.path.resolve(bridged) - : this.runtime.path.resolve(cwd, bridged); - this.assertAllowed(resolved); - return resolved; - } - - assertAllowed(path: string): void { - const resolved = this.runtime.path.resolve(path); - if (this.roots.some((root) => contains(this.runtime, root, resolved))) return; - throw new Error2( - ErrorCodes.FS_PATH_ESCAPES, - `path ${path} is outside runtime workspace ${this.binding.runtimeId}`, - { details: { path: resolved } }, - ); - } -} - -function contains(runtime: Runtime, root: string, candidate: string): boolean { - const relative = runtime.path.relative(root, candidate); - if (relative === '') return true; - return relative !== '..' && !relative.startsWith(`..${runtime.path.separator}`) && !runtime.path.isAbsolute(relative); -} diff --git a/packages/agent-core-v2/src/runtime/standaloneRuntime.ts b/packages/agent-core-v2/src/runtime/standaloneRuntime.ts deleted file mode 100644 index 02b65a2bf..000000000 --- a/packages/agent-core-v2/src/runtime/standaloneRuntime.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IHostFsWatchService } from '#/os/interface/hostFsWatch'; -import { IHostProcessService } from '#/os/interface/hostProcess'; -import { IHostTerminalService } from '#/os/interface/terminal'; - -import { LocalRuntime } from './localRuntime'; -import type { Runtime } from './runtime'; - -export interface IStandaloneRuntimeFactory { - readonly _serviceBrand: undefined; - createLocalRuntime(workspaceId: string): Runtime; -} - -export const IStandaloneRuntimeFactory: ServiceIdentifier = - createDecorator('standaloneRuntimeFactory'); - -export class StandaloneRuntimeFactory implements IStandaloneRuntimeFactory { - declare readonly _serviceBrand: undefined; - - constructor( - @IHostEnvironment private readonly environment: IHostEnvironment, - @IHostFileSystem private readonly fs: IHostFileSystem, - @IHostProcessService private readonly process: IHostProcessService, - @IHostFsWatchService private readonly watch: IHostFsWatchService, - @IHostTerminalService private readonly terminal: IHostTerminalService, - ) {} - - createLocalRuntime(workspaceId: string): Runtime { - return new LocalRuntime(workspaceId, this.environment, this.fs, this.process, this.watch, this.terminal); - } -} - -registerScopedService( - LifecycleScope.App, - IStandaloneRuntimeFactory, - StandaloneRuntimeFactory, - ScopeActivation.OnDemand, - 'standaloneRuntimeFactory', -); diff --git a/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycle.ts b/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycle.ts index 65dc724c8..a3039140f 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycle.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycle.ts @@ -1,26 +1,37 @@ +/** + * `agentLifecycle` domain — flat registry of the session's agents. + * + * Owns agent *existence* — the creation pipeline (`create` / `fork`), the + * registry (`get` / `list` / `remove`), and the lifecycle events — plus the + * session-wide fan-outs only the live registry can reach + * (`broadcastPermissionMode`). Session-scoped — one instance per session. + * + * Invariants: + * - The registry is flat: agents have no nesting. There is no parent/child or + * caller/callee relationship here; when a business domain needs such a + * relationship (e.g. the `Agent` tool's display events), that domain + * maintains it itself. + * - No agent id is special: the main agent is an ordinary agent whose only + * distinction is the conventional `MAIN_AGENT_ID`, and nothing in this + * domain branches on it. + * - Creation is single-flight per explicit agent id (concurrent creations + * join), an already-created agent is returned as-is, and a failed bootstrap + * drops the incomplete handle. + * - `forkedFrom` is provenance only (a recorded value); business logic must + * not branch on it. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IAgentScopeHandle } from '#/_base/di/scope'; import type { Event } from '#/_base/event'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import type { - AgentRuntimeDefinition, - AgentRuntimeSnapshot, - RuntimeOf, -} from '#/agent/runtime/agentRuntime'; import type { PermissionMode } from '#/agent/permissionPolicy/types'; import type { BindAgentInput } from '#/agent/profile/profile'; -export interface AgentScopeCreatedEvent { - readonly context: AgentContext; - readonly handle: IAgentScopeHandle; -} - export const MAIN_AGENT_ID = 'main'; export interface CreateAgentOptions { readonly agentId?: string; readonly binding?: BindAgentInput; - readonly runtimeId?: string; readonly forkedFrom?: string; readonly labels?: Readonly>; } @@ -28,7 +39,6 @@ export interface CreateAgentOptions { export interface ForkAgentOptions { readonly agentId?: string; readonly binding?: Partial; - readonly labels?: Readonly>; } export interface AgentListFilter { @@ -38,30 +48,17 @@ export interface AgentListFilter { export interface IAgentLifecycleService { readonly _serviceBrand: undefined; - readonly onDidCreate: Event; - readonly onDidCreateScope: Event; - readonly onWillClose: Event; - readonly onDidClose: Event; + readonly onDidCreate: Event; + readonly onDidDispose: Event; - create(opts?: CreateAgentOptions): Promise; + create(opts?: CreateAgentOptions): Promise; - fork(source: AgentContext, opts?: ForkAgentOptions): Promise; + fork(sourceAgentId: string, opts?: ForkAgentOptions): Promise; - get(agentId: string): AgentContext | undefined; - list(filter?: AgentListFilter): readonly AgentContext[]; - resolve>( - agent: AgentContext, - definition: Definition, - ): RuntimeOf; - inspect(agent: AgentContext): AgentRuntimeSnapshot; + get(agentId: string): IAgentScopeHandle | undefined; + list(filter?: AgentListFilter): readonly IAgentScopeHandle[]; broadcastPermissionMode(mode: PermissionMode): void; - remove(agent: AgentContext): Promise; - - handleOf(agentId: string): IAgentScopeHandle | undefined; - - adopt(handle: IAgentScopeHandle): AgentContext; - - attachRuntimes(agent: AgentContext): void; + remove(agentId: string): Promise; } export const IAgentLifecycleService: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycleService.ts b/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycleService.ts index 95842611c..4ccbbdd6f 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycleService.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/agentLifecycleService.ts @@ -1,11 +1,29 @@ -import { join } from 'pathe'; +/** + * `agentLifecycle` domain — `IAgentLifecycleService` implementation. + * + * Creates and tracks the session's agents as child scopes in a flat registry, + * serializing same-id bootstrap and dropping incomplete handles after startup + * failure. Seeds each agent's identity through `agent` scopeContext, wires + * per-agent wire records and the wire state machine, the blob store, and MCP, + * and registers the agent in the session registry. Binds the agent id into the + * Agent-scoped telemetry view. New logs receive a metadata + * envelope while non-empty unversioned logs are rejected. Removal awaits the + * agent task manager's graceful exit policy before draining turns and full + * compaction, then disposing the child scope. Fans session-level + * permission-mode switches out to every live agent. Bound at Session scope. + * + * No agent id is special here: the main agent is simply the agent created + * with the conventional `MAIN_AGENT_ID`, and `fork` requires its source to + * exist. MCP readiness is not awaited here: the workspace's shared manager + * connects in the background and the agent's LLM steps wait on it instead + * (see `AgentMcpService`). + */ import { IInstantiationService } from '#/_base/di/instantiation'; -import { Disposable, toDisposable } from '#/_base/di/lifecycle'; -import { type CollectionView } from '#/_base/di/collection'; +import { Disposable, type IDisposable } from '#/_base/di/lifecycle'; import { Emitter } from '#/_base/event'; -import { onUnexpectedError } from '#/_base/errors/unexpectedError'; import { Error2, ErrorCodes } from '#/errors'; +import { join } from 'pathe'; import { LifecycleScope } from '#/app/scopes'; import { createScopedChildHandle, @@ -15,51 +33,26 @@ import { } from '#/_base/di/scope'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; -import { ISessionEventBus } from '#/app/event/eventBus'; +import { IEventBus } from '#/app/event/eventBus'; import { DEFAULT_PERMISSION_MODE_SECTION } from '#/agent/permissionMode/configSection'; -import { permissionModeConfiguredKey } from '#/agent/permissionMode/permissionModeOps'; +import { PermissionModeConfiguredModel } from '#/agent/permissionMode/permissionModeOps'; import type { PermissionMode } from '#/agent/permissionPolicy/types'; -import { profileKey } from '#/agent/profile/profileOps'; -import { TOWER_WORKER_PROFILE } from '#/features/tower/tower'; import { IAgentTaskService } from '#/agent/task/task'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { - agentContextOf, - IAgentScopeContext, - makeAgentScopeContext, -} from '#/agent/scopeContext/scopeContext'; +import { IAgentScopeContext, makeAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentLoopService } from '#/agent/loop/loop'; import { IAgentProfileService } from '#/agent/profile/profile'; import { abortError } from '#/_base/utils/abort'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import { closeTrailingOpenToolExchange } from '#/agent/contextMemory/openToolExchange'; -import { IAgentRuntimeBindingSeed, IAgentRuntimeBindingService } from '#/agent/runtimeBinding/runtimeBinding'; -import '#/agent/runtimeBinding/runtimeBindingService'; import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; import { IAgentToolActivationService } from '#/agent/toolActivation/toolActivation'; -import { IAgentPromptService } from '#/agent/prompt/prompt'; +import { ISessionInteractionService } from '#/session/interaction/interaction'; import { IWireService } from '#/wire/wire'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { - AgentRuntimeContributionPoint, - AgentRuntimeOverrideContributionPoint, - type AgentRuntimeContribution, - type AgentRuntimeDefinition, - type AgentRuntimeDefinitionRecord, - type AgentRuntimeSnapshot, - getAgentRuntimeDefinitionId, - type RuntimeOf, -} from '#/agent/runtime/agentRuntime'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; - -import { ManagedAgent } from './managedAgent'; import { type AgentListFilter, - type AgentScopeCreatedEvent, type CreateAgentOptions, type ForkAgentOptions, IAgentLifecycleService, @@ -67,30 +60,20 @@ import { let nextAgentId = 0; +// NOTE: stays Disposable — its own 'get' and 'config' collide with the Fiber export class AgentLifecycleService extends Disposable implements IAgentLifecycleService { declare readonly _serviceBrand: undefined; - private readonly roster = new Map(); - private readonly creating = new Map>(); - private nextLifecycleGeneration = 0; - private readonly records = new Map(); - private readonly recordGenerations = new Map(); - private readonly contributions = new Map(); - private readonly onDidCreateEmitter = this._register(new Emitter()); - private readonly onDidCreateScopeEmitter = this._register(new Emitter()); - private readonly onWillCloseEmitter = this._register(new Emitter()); - private readonly onDidCloseEmitter = this._register(new Emitter()); + private readonly handles = new Map(); + private readonly onDidCreateEmitter = this._register(new Emitter()); + private readonly onDidDisposeEmitter = this._register(new Emitter()); + private readonly interactionBusDisposables = new Map(); + private readonly creating = new Map>(); get onDidCreate() { return this.onDidCreateEmitter.event; } - get onDidCreateScope() { - return this.onDidCreateScopeEmitter.event; - } - get onWillClose() { - return this.onWillCloseEmitter.event; - } - get onDidClose() { - return this.onDidCloseEmitter.event; + get onDidDispose() { + return this.onDidDisposeEmitter.event; } constructor( @@ -99,87 +82,42 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle @ISessionMetadata private readonly sessionMetadata: ISessionMetadata, @IBootstrapService private readonly bootstrap: IBootstrapService, @IConfigService private readonly config: IConfigService, + @ISessionInteractionService private readonly interaction: ISessionInteractionService, @ITelemetryService private readonly telemetry: ITelemetryService, - @AgentRuntimeContributionPoint contributionView: CollectionView, - @AgentRuntimeOverrideContributionPoint overrideView: CollectionView, ) { super(); - for (const contribution of contributionView.items) this.registerContribution(contribution, false); - for (const contribution of overrideView.items) this.registerContribution(contribution, true); + this._register(this.onDidCreate((handle) => this.subscribeInteractionBus(handle))); this._register( - contributionView.onDidChange(({ added, removed }) => { - for (const contribution of added) this.registerContribution(contribution, false); - for (const contribution of removed) this.withdrawContribution(contribution); - }), - ); - this._register( - overrideView.onDidChange(({ added, removed }) => { - for (const contribution of added) this.registerContribution(contribution, true); - for (const contribution of removed) this.withdrawContribution(contribution); - }), - ); - this._register( - toDisposable(() => { - for (const managed of this.roster.values()) { - void managed.runtimeSet.close().catch((error: unknown) => onUnexpectedError(error)); + this.onDidDispose((agentId) => { + const d = this.interactionBusDisposables.get(agentId); + if (d !== undefined) { + d.dispose(); + this.interactionBusDisposables.delete(agentId); } - this.roster.clear(); }), ); + this._register({ + dispose: () => { + for (const d of this.interactionBusDisposables.values()) d.dispose(); + this.interactionBusDisposables.clear(); + }, + }); } - private registerContribution(contribution: AgentRuntimeContribution, override: boolean): void { - if (this.contributions.has(contribution)) return; - const definition = contribution.contract; - const id = getAgentRuntimeDefinitionId(definition); - const generation = (this.recordGenerations.get(id) ?? 0) + 1; - this.recordGenerations.set(id, generation); - const record: AgentRuntimeDefinitionRecord = { - definition, - provider: contribution, - generation, - providerGeneration: generation, - active: true, - }; - this.contributions.set(contribution, record); - const current = this.records.get(id); - if (current !== undefined && !override) return; - this.records.set(id, record); - for (const managed of this.roster.values()) { - if (!managed.closing) managed.runtimeSet.apply(record); - } + private subscribeInteractionBus(handle: IAgentScopeHandle): void { + if (this.interactionBusDisposables.has(handle.id)) return; + const d = handle.accessor + .get(IEventBus) + .subscribe('turn.ended', (e) => this.interaction.cancelPendingForTurn(e.turnId)); + this.interactionBusDisposables.set(handle.id, d); } - private withdrawContribution(contribution: AgentRuntimeContribution): void { - const record = this.contributions.get(contribution); - if (record === undefined) return; - this.contributions.delete(contribution); - record.active = false; - const id = getAgentRuntimeDefinitionId(record.definition); - if (this.records.get(id) === record) { - const fallback = [...this.contributions.values()] - .filter((candidate) => candidate.active && getAgentRuntimeDefinitionId(candidate.definition) === id) - .sort((left, right) => (right.providerGeneration ?? right.generation) - (left.providerGeneration ?? left.generation))[0]; - if (fallback !== undefined) this.records.set(id, fallback); - else this.records.delete(id); - } - for (const managed of this.roster.values()) { - managed.runtimeSet.retireDefinition(record); - const fallback = this.records.get(id); - if (fallback !== undefined && fallback !== record && !managed.closing) managed.runtimeSet.apply(fallback); - } - } - - private activeRecords(): readonly AgentRuntimeDefinitionRecord[] { - return [...this.records.values()]; - } - - async create(opts: CreateAgentOptions = {}): Promise { + async create(opts: CreateAgentOptions = {}): Promise { if (opts.agentId !== undefined) { const inflight = this.creating.get(opts.agentId); if (inflight !== undefined) return inflight; - const existing = this.roster.get(opts.agentId); - if (existing !== undefined && !existing.closing) return existing.context; + const existing = this.handles.get(opts.agentId); + if (existing !== undefined) return existing; } const agentId = opts.agentId ?? (await this.nextAvailableAgentId()); const promise = this.doCreate(agentId, opts); @@ -197,7 +135,7 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle const match = /^agent-(\d+)$/.exec(id); if (match !== null) maxSuffix = Math.max(maxSuffix, Number(match[1])); }; - for (const id of this.roster.keys()) consider(id); + for (const id of this.handles.keys()) consider(id); const persisted = (await this.sessionMetadata.read()).agents ?? {}; for (const id of Object.keys(persisted)) consider(id); const candidate = Math.max(maxSuffix + 1, nextAgentId); @@ -205,58 +143,24 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle return `agent-${String(candidate)}`; } - private async doCreate(agentId: string, opts: CreateAgentOptions): Promise { + private async doCreate(agentId: string, opts: CreateAgentOptions): Promise { const agentScope = this.ctx.scope(`agents/${agentId}`); const agentHomedir = join(this.bootstrap.homeDir, agentScope); - const generation = ++this.nextLifecycleGeneration; - const scopeContext = makeAgentScopeContext({ + const handle = createScopedChildHandle( + this.instantiation, + LifecycleScope.Agent, agentId, - agentScope, - forkedFrom: opts.forkedFrom, - generation, - }); - const agent = scopeContext.agentContext; - const eventBus = this.instantiation.invokeFunction((accessor) => - accessor.get(ISessionEventBus) as ISessionEventBus | undefined, - ); - eventBus?.activateAgent(agent); - let managed: ManagedAgent | undefined; - let didCreate = false; - let finalizerArmed = false; + { + seeds: [ + [IAgentScopeContext, makeAgentScopeContext({ agentId, agentScope })], + [ITelemetryService, this.telemetry.withContext({ agent_id: agentId })], + ], + }, + ) as IAgentScopeHandle; + this.handles.set(agentId, handle); try { - const handle = createScopedChildHandle( - this.instantiation, - LifecycleScope.Agent, - agentId, - { - seeds: [ - [IAgentScopeContext, scopeContext], - [ITelemetryService, this.telemetry.withContext({ agent_id: agentId })], - [IAgentRuntimeBindingSeed, { - _serviceBrand: undefined, - binding: { workspaceId: this.ctx.workspaceId, runtimeId: opts.runtimeId ?? 'local' }, - }], - ], - configureContainer: (container) => { - container.anchorKernelFinalizer(() => { - eventBus?.deactivateAgent(agent); - }, 'agent-event-bus-deactivate'); - finalizerArmed = true; - this.adopt({ - id: agentId, - kind: LifecycleScope.Agent, - accessor: { - get: (id) => container.invokeFunction((accessor) => accessor.get(id)), - }, - dispose: () => container.disposeAsync(), - }); - managed = this.roster.get(agentId); - }, - }, - ) as IAgentScopeHandle; - managed!.active = true; - await handle.accessor.get(IWireService).seal(); - managed!.attachDurableRuntimes(); + const wire = handle.accessor.get(IWireService); + await wire.seal(); await this.sessionMetadata.registerAgent(agentId, { homedir: agentHomedir, type: agentId === 'main' ? 'main' : 'sub', @@ -264,26 +168,17 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle forkedFrom: opts.forkedFrom, labels: opts.labels, }); - this.onDidCreateEmitter.fire(agent); - didCreate = true; - this.onDidCreateScopeEmitter.fire({ context: agent, handle }); - await handle.accessor.get(IEventDispatcher).restore(); - await managed!.runtimeSet.restore(); + this.onDidCreateEmitter.fire(handle); + await wire.restore(); await this.bindBootstrap(handle, opts); await handle.accessor.get(IAgentToolActivationService).activate(); - return agent; + return handle; } catch (error) { - if (managed !== undefined) { - managed.closing = true; - if (this.roster.get(agentId) === managed) this.roster.delete(agentId); - await managed.runtimeSet.close().catch(() => undefined); - managed.killSpace(); - try { - await managed.handle.dispose(); - } catch { } - } - if (!finalizerArmed) eventBus?.deactivateAgent(agent); - if (didCreate) this.onDidCloseEmitter.fire(agent); + if (this.handles.get(agentId) === handle) this.handles.delete(agentId); + try { + handle.dispose(); + } catch { } + this.onDidDisposeEmitter.fire(agentId); throw error; } } @@ -295,37 +190,27 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle if (opts.binding !== undefined) { await handle.accessor.get(IAgentProfileService).bind(opts.binding); } + const wire = handle.accessor.get(IWireService); const permissionMode = this.config.get(DEFAULT_PERMISSION_MODE_SECTION); - const hasRestoredPermissionMode = handle.accessor - .get(IAgentStateService) - .get(permissionModeConfiguredKey); + const hasRestoredPermissionMode = wire.getModel(PermissionModeConfiguredModel); if (permissionMode !== undefined && !hasRestoredPermissionMode) { handle.accessor.get(IAgentPermissionModeService).setMode(permissionMode); } } - async fork(sourceContext: AgentContext, opts?: ForkAgentOptions): Promise { - const sourceManaged = this.managedFor(sourceContext); - if (sourceManaged === undefined) { - throw new Error2( - ErrorCodes.AGENT_NOT_FOUND, - `Source agent "${sourceContext.agentId}" does not exist`, - { details: { agentId: sourceContext.agentId } }, - ); + async fork(sourceAgentId: string, opts?: ForkAgentOptions): Promise { + const source = this.handles.get(sourceAgentId); + if (source === undefined) { + throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Source agent "${sourceAgentId}" does not exist`, { + details: { agentId: sourceAgentId }, + }); } - if (opts?.agentId !== undefined && this.get(opts.agentId) !== undefined) { + if (opts?.agentId !== undefined && this.handles.has(opts.agentId)) { throw new Error2(ErrorCodes.AGENT_ALREADY_EXISTS, `Agent "${opts.agentId}" already exists`, { details: { agentId: opts.agentId }, }); } - const source = sourceManaged.handle; - const childContext = await this.create({ - agentId: opts?.agentId, - runtimeId: source.accessor.get(IAgentRuntimeBindingService).current.runtimeId, - forkedFrom: source.id, - labels: opts?.labels, - }); - const child = this.requireManaged(childContext).handle; + const child = await this.create({ agentId: opts?.agentId, forkedFrom: source.id }); const sourceData = source.accessor.get(IAgentProfileService).data(); const childProfile = child.accessor.get(IAgentProfileService); @@ -344,103 +229,37 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle const sourceMessages = source.accessor.get(IAgentContextMemoryService)?.get(); if (sourceMessages !== undefined && sourceMessages.length > 0) { - child.accessor - .get(IAgentContextMemoryService) - ?.append(...closeTrailingOpenToolExchange(sourceMessages)); + child.accessor.get(IAgentContextMemoryService)?.append(...sourceMessages); } - return childContext; + return child; } - get(agentId: string): AgentContext | undefined { - const managed = this.roster.get(agentId); - if (managed === undefined || managed.closing || !managed.active) return undefined; - return managed.context; + get(agentId: string): IAgentScopeHandle | undefined { + return this.handles.get(agentId); } - list(filter?: AgentListFilter): readonly AgentContext[] { - const all = [...this.roster.values()] - .filter((managed) => managed.active && !managed.closing) - .map((managed) => managed.context); + list(filter?: AgentListFilter): readonly IAgentScopeHandle[] { + const all = [...this.handles.values()]; const prefix = filter?.prefix; if (prefix === undefined) return all; - return all.filter((context) => context.agentId.startsWith(prefix)); - } - - resolve>( - agent: AgentContext, - definition: Definition, - ): RuntimeOf { - return this.requireManaged(agent).runtimeSet.resolve(definition); - } - - restoreRuntimes(agent: AgentContext): Promise { - return this.requireManaged(agent).runtimeSet.restore(); - } - - inspect(agent: AgentContext): AgentRuntimeSnapshot { - const managed = this.requireManaged(agent); - return { - identity: { agentId: agent.agentId, generation: agent.generation }, - contributions: managed.runtimeSet.inspect(), - }; + return all.filter((handle) => handle.id.startsWith(prefix)); } broadcastPermissionMode(mode: PermissionMode): void { - for (const managed of this.roster.values()) { - if (managed.closing || !managed.active) continue; - const handle = managed.handle; - if ( - handle.accessor.get(IAgentStateService).get(profileKey).profileName === - TOWER_WORKER_PROFILE - ) { - continue; - } + for (const handle of this.handles.values()) { handle.accessor.get(IAgentPermissionModeService).setMode(mode); } } - handleOf(agentId: string): IAgentScopeHandle | undefined { - const managed = this.roster.get(agentId); - if (managed === undefined || managed.closing || !managed.active) return undefined; - return managed.handle; - } - - adopt(handle: IAgentScopeHandle): AgentContext { - const agent = agentContextOf(handle); - const existing = this.roster.get(agent.agentId); - if (existing !== undefined) { - if (!existing.closing && existing.context === agent) return existing.context; - if (!existing.closing) { - throw new Error(`Agent "${agent.agentId}" is already managed by a different context`); - } - } - const managed = new ManagedAgent(agent, handle, this.activeRecords()); - this.roster.set(agent.agentId, managed); - return agent; - } - - attachRuntimes(agent: AgentContext): void { - const managed = this.requireManaged(agent); - managed.attachDurableRuntimes(); - if (!managed.active) { - managed.active = true; - this.onDidCreateEmitter.fire(agent); - this.onDidCreateScopeEmitter.fire({ context: agent, handle: managed.handle }); - } - } - - async remove(agent: AgentContext): Promise { - const managed = this.roster.get(agent.agentId); - if (managed === undefined || managed.context !== agent || managed.closing) return; - managed.closing = true; - this.onWillCloseEmitter.fire(agent); - const handle = managed.handle; + async remove(agentId: string): Promise { + const handle = this.handles.get(agentId); + if (handle === undefined) return; + this.handles.delete(agentId); await handle.accessor.get(IAgentTaskService).stopAllOnExit('Session closed'); const loop = handle.accessor.get(IAgentLoopService); const compaction = handle.accessor.get(IAgentFullCompactionService).compacting; const compactionSettled = compaction?.promise.catch(() => undefined) ?? Promise.resolve(); const reason = abortError('Agent removed'); - const prompt = handle.accessor.get(IAgentPromptService); for (const turnId of loop.status().pendingTurnIds) { loop.cancel(turnId, reason); } @@ -448,28 +267,9 @@ export class AgentLifecycleService extends Disposable implements IAgentLifecycle if (compaction !== null && !compaction.abortController.signal.aborted) { compaction.abortController.abort(reason); } - await Promise.all([loop.settled(), compactionSettled, prompt.drain(reason)]); - await managed.runtimeSet.close(); - managed.killSpace(); - await handle.dispose(); - if (this.roster.get(agent.agentId) === managed) this.roster.delete(agent.agentId); - this.onDidCloseEmitter.fire(agent); - } - - private managedFor(agent: AgentContext): ManagedAgent | undefined { - const managed = this.roster.get(agent.agentId); - if (managed === undefined || managed.context !== agent || managed.closing) return undefined; - return managed; - } - - private requireManaged(agent: AgentContext): ManagedAgent { - const managed = this.managedFor(agent); - if (managed === undefined) { - throw new Error( - `Agent ${agent.agentId}:${String(agent.generation)} is not a lifecycle-issued context`, - ); - } - return managed; + await Promise.all([loop.settled(), compactionSettled]); + handle.dispose(); + this.onDidDisposeEmitter.fire(agentId); } } diff --git a/packages/agent-core-v2/src/session/agentLifecycle/errors.ts b/packages/agent-core-v2/src/session/agentLifecycle/errors.ts index e72baaf0d..1432ad72b 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/errors.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/errors.ts @@ -1,3 +1,7 @@ +/** + * `agentLifecycle` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const AgentLifecycleErrors = { diff --git a/packages/agent-core-v2/src/session/agentLifecycle/mainAgent.ts b/packages/agent-core-v2/src/session/agentLifecycle/mainAgent.ts index a74e64234..bbd9a4df7 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/mainAgent.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/mainAgent.ts @@ -1,12 +1,28 @@ -import type { ISessionScopeHandle } from '#/_base/di/scope'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; +/** + * `agentLifecycle` domain — main-agent bootstrap helper. + * + * The main agent is an ordinary agent whose only distinction is + * `agentId === 'main'`; `IAgentLifecycleService` itself knows nothing about + * it. `ensureMainAgent` is the single convenience entry point for the + * conventional id so edge callers do not repeat the + * `create({ agentId: MAIN_AGENT_ID })` incantation — and never misspell it. + * + * `create` is create-or-get for explicit ids — it joins an in-flight creation + * and returns an already-created main agent as-is — so concurrent + * bootstrappers always receive the same, fully-bootstrapped handle (activity + * lane `idle`). + * + * Not a Service: a pure composition helper over the session handle. + */ + +import type { ISessionScopeHandle, IAgentScopeHandle } from '#/_base/di/scope'; import { type CreateAgentOptions, IAgentLifecycleService, MAIN_AGENT_ID } from './agentLifecycle'; export async function ensureMainAgent( session: ISessionScopeHandle, opts?: Omit, -): Promise { +): Promise { return session.accessor.get(IAgentLifecycleService).create({ ...opts, agentId: MAIN_AGENT_ID, diff --git a/packages/agent-core-v2/src/session/agentLifecycle/managedAgent.ts b/packages/agent-core-v2/src/session/agentLifecycle/managedAgent.ts deleted file mode 100644 index 31735f1de..000000000 --- a/packages/agent-core-v2/src/session/agentLifecycle/managedAgent.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { IAgentScopeHandle } from '#/_base/di/scope'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { AgentSpaceImpl } from '#/agent/agentContext/agentSpace'; -import type { AgentRuntimeDefinitionRecord } from '#/agent/runtime/agentRuntime'; -import { AgentRuntimeSet } from '#/agent/runtime/agentRuntimeSet'; -import { IEventDispatcher } from '#/state/eventDispatcher'; - -export class ManagedAgent { - active = false; - closing = false; - readonly runtimeSet: AgentRuntimeSet; - - constructor( - readonly context: AgentContext, - readonly handle: IAgentScopeHandle, - records: readonly AgentRuntimeDefinitionRecord[], - ) { - this.runtimeSet = new AgentRuntimeSet(context, handle.accessor); - for (const record of records) this.runtimeSet.apply(record); - } - - attachDurableRuntimes(): void { - this.runtimeSet.attachDurable(this.handle.accessor.get(IEventDispatcher)); - } - - killSpace(): void { - const space = this.context.space; - if (space instanceof AgentSpaceImpl) space._kill(); - } -} diff --git a/packages/agent-core-v2/src/session/agentLifecycle/profile/gitContext.ts b/packages/agent-core-v2/src/session/agentLifecycle/profile/gitContext.ts index bf6a32e57..15daafc9a 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/profile/gitContext.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/profile/gitContext.ts @@ -1,7 +1,22 @@ +/** + * Git context collection for explore agents. + * + * `collectGitContext` produces a `` block that is prepended to a + * fresh explore agent's prompt so it can orient itself in the repository + * before searching. Every git probe is best-effort: probes fail in perfectly + * normal states (no `origin` remote, no commits yet, detached HEAD, older + * Git), so a failed probe is logged and its section omitted rather than + * dropping the whole block. The block is omitted entirely only when nothing + * useful was collected. The one explicit state surfaced to the agent is + * `reason="not-a-repo"`, so it doesn't waste turns probing git history in a + * non-repo directory. Remote URLs are sanitized so internal infrastructure + * is not surfaced to the model. + */ + import type { Readable } from 'node:stream'; import type { ILogger } from '#/_base/log/log'; -import type { IHostProcess, IHostProcessService } from '#/os/interface/hostProcess'; +import type { IProcess, ISessionProcessRunner } from '#/session/process/processRunner'; const GIT_TIMEOUT_MS = 5_000; const MAX_DIRTY_FILES = 20; @@ -28,12 +43,12 @@ type GitResult = type TaggedGitResult = { readonly args: readonly string[]; readonly result: GitResult }; export async function collectGitContext( - process: IHostProcessService, + runner: ISessionProcessRunner, cwd: string, log?: ILogger, ): Promise { const revParseArgs = ['rev-parse', '--is-inside-work-tree'] as const; - const revParse = await runGit(process, cwd, revParseArgs); + const revParse = await runGit(runner, cwd, revParseArgs); if (!revParse.ok) { if (revParse.kind === 'command-failed' && isNotARepo(revParse.stderr)) { return ``; @@ -49,7 +64,7 @@ export async function collectGitContext( ['log', '-3', '--format=%h %s'], ] as const; const [remote, branch, status, gitLog] = (await Promise.all( - commandArgs.map(async (args) => ({ args, result: await runGit(process, cwd, args) })), + commandArgs.map(async (args) => ({ args, result: await runGit(runner, cwd, args) })), )) as unknown as [TaggedGitResult, TaggedGitResult, TaggedGitResult, TaggedGitResult]; for (const { args, result } of [remote, branch, status, gitLog]) { @@ -166,13 +181,13 @@ function logGitFailure( } async function runGit( - process: IHostProcessService, + runner: ISessionProcessRunner, cwd: string, args: readonly string[], ): Promise { - let proc: IHostProcess | undefined; + let proc: IProcess | undefined; try { - proc = await process.spawn('git', ['-C', cwd, ...args], { cwd }); + proc = await runner.exec(['git', '-C', cwd, ...args]); } catch { return { ok: false, kind: 'spawn-error' }; } @@ -220,7 +235,7 @@ async function collectStream(stream: Readable): Promise { return Buffer.concat(chunks).toString('utf-8'); } -async function disposeProcess(proc: IHostProcess): Promise { +async function disposeProcess(proc: IProcess): Promise { try { await proc.dispose(); } catch { diff --git a/packages/agent-core-v2/src/session/agentLifecycle/profile/profiles.ts b/packages/agent-core-v2/src/session/agentLifecycle/profile/profiles.ts index c55af1164..5da3a73a5 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/profile/profiles.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/profile/profiles.ts @@ -1,3 +1,12 @@ +/** + * `agentLifecycle` domain — builtin agent profile contributions. + * + * Registers the default `agent` profile plus the `coder` / `explore` task-agent + * profiles. Each profile is self-contained: its structured `renderSystemPrompt` + * merges the shared base template with its own role text at call time, so a + * child agent no longer inherits the parent's prompt through a runtime overlay. + */ + import { collectGitContext } from './gitContext'; import { registerAgentProfile } from '#/app/agentProfileCatalog/contribution'; import { @@ -19,7 +28,6 @@ const AGENT_TOOLS = [ 'TaskList', 'TaskOutput', 'TaskStop', - 'WaitFor', 'CronCreate', 'CronList', 'CronDelete', @@ -37,9 +45,6 @@ const AGENT_TOOLS = [ 'GetGoal', 'SetGoalBudget', 'UpdateGoal', - 'TowerInit', - 'TowerStatus', - 'TowerTeardown', 'mcp__*', ] as const; @@ -60,7 +65,6 @@ const CODER_TOOLS = [ 'TaskOutput', 'TaskStop', 'TodoList', - 'WaitFor', 'WebSearch', 'FetchURL', 'Write', @@ -95,7 +99,6 @@ registerAgentProfile({ name: 'agent', description: 'Default agent', tools: AGENT_TOOLS, - subagents: ['coder', 'explore', 'plan'], renderSystemPrompt: (context) => renderSystemPromptResult('', context, { skillActive: skillActiveFor(AGENT_TOOLS) }), }); @@ -120,9 +123,9 @@ registerAgentProfile({ tools: EXPLORE_TOOLS, renderSystemPrompt: (context) => renderSystemPromptResult(EXPLORE_ROLE, context, { skillActive: skillActiveFor(EXPLORE_TOOLS) }), - promptPrefix: async ({ cwd, process, log }) => { + promptPrefix: async ({ cwd, runner, log }) => { try { - return await collectGitContext(process, cwd, log); + return await collectGitContext(runner, cwd, log); } catch { return ''; } diff --git a/packages/agent-core-v2/src/session/agentLifecycle/subagentMetadata.ts b/packages/agent-core-v2/src/session/agentLifecycle/subagentMetadata.ts index aa7b6000d..5bce35b4b 100644 --- a/packages/agent-core-v2/src/session/agentLifecycle/subagentMetadata.ts +++ b/packages/agent-core-v2/src/session/agentLifecycle/subagentMetadata.ts @@ -1,3 +1,11 @@ +/** + * `agentLifecycle` domain — persisted subagent relationship labels. + * + * Provides the label helpers that record and read the requester → subagent + * relationship without making the flat lifecycle registry interpret parentage + * itself. + */ + import type { AgentMeta } from '#/session/sessionMetadata/sessionMetadata'; export function subagentLabels( diff --git a/packages/agent-core-v2/src/session/approval/approval.ts b/packages/agent-core-v2/src/session/approval/approval.ts index f0db6ab55..0528d6f76 100644 --- a/packages/agent-core-v2/src/session/approval/approval.ts +++ b/packages/agent-core-v2/src/session/approval/approval.ts @@ -1,3 +1,12 @@ +/** + * `approval` domain — session-scope approval broker. + * + * Defines the public contract of approval brokering: the `ApprovalRequest` / + * `ApprovalDecision` models and the `ISessionApprovalService` used to request a + * decision, resolve it, and list pending approvals. Session-scoped — one + * broker per session. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ToolInputDisplay } from '#/tool/toolInputDisplay'; diff --git a/packages/agent-core-v2/src/session/approval/approvalService.ts b/packages/agent-core-v2/src/session/approval/approvalService.ts index dc980abda..27243377e 100644 --- a/packages/agent-core-v2/src/session/approval/approvalService.ts +++ b/packages/agent-core-v2/src/session/approval/approvalService.ts @@ -1,15 +1,14 @@ -import { randomUUID } from 'node:crypto'; +/** + * `approval` domain — `ISessionApprovalService` implementation. + * + * Typed facade over the `interaction` kernel for approval requests; owns no + * pending state of its own (the kernel holds it). Bound at Session scope. + */ import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { - enqueueSessionInteraction, - listSessionPendingInteractions, - requestSessionInteraction, - respondSessionInteraction, -} from '#/features/interaction/sessionInteractions'; +import { ISessionInteractionService } from '#/session/interaction/interaction'; import { type ApprovalRequest, @@ -20,10 +19,10 @@ import { export class SessionApprovalService implements ISessionApprovalService { declare readonly _serviceBrand: undefined; - constructor(@IAgentLifecycleService private readonly agents: IAgentLifecycleService) {} + constructor(@ISessionInteractionService private readonly interaction: ISessionInteractionService) {} request(req: ApprovalRequest): Promise { - return requestSessionInteraction(this.agents, { + return this.interaction.request({ id: requestId(req), kind: 'approval', payload: req, @@ -33,7 +32,7 @@ export class SessionApprovalService implements ISessionApprovalService { enqueue(req: ApprovalRequest): ApprovalRequest & { readonly id: string } { const id = requestId(req); - enqueueSessionInteraction(this.agents, { + this.interaction.enqueue({ id, kind: 'approval', payload: req, @@ -43,19 +42,18 @@ export class SessionApprovalService implements ISessionApprovalService { } decide(id: string, response: ApprovalResponse): void { - respondSessionInteraction(this.agents, id, response); + this.interaction.respond(id, response); } listPending(): readonly ApprovalRequest[] { - return listSessionPendingInteractions(this.agents, 'approval').map((i) => ({ - ...(i.payload as ApprovalRequest), - id: i.id, - })); + return this.interaction + .listPending('approval') + .map((i) => i.payload as ApprovalRequest); } } function requestId(req: ApprovalRequest): string { - return req.id ?? `approval_${randomUUID()}`; + return req.id ?? req.toolCallId ?? `${req.toolName}:${String(Date.now())}`; } registerScopedService(LifecycleScope.Session, ISessionApprovalService, SessionApprovalService, ScopeActivation.OnScopeCreated, 'approval'); diff --git a/packages/agent-core-v2/src/session/cron/cronOps.ts b/packages/agent-core-v2/src/session/cron/cronOps.ts new file mode 100644 index 000000000..ac3eae842 --- /dev/null +++ b/packages/agent-core-v2/src/session/cron/cronOps.ts @@ -0,0 +1,79 @@ +/** + * `cron` domain — wire Model (`CronModel`) and the `cron.add` + * (`cronAdd`) / `cron.delete` (`cronDelete`) / `cron.cursor` (`cronCursor`) + * Ops for the session-level scheduling engine, plus the `cron.fired` edge + * event declared on `DomainEventMap`. + * + * The Model is the replayable map of `taskId -> CronTask` (initial empty). The + * cursor (`lastFiredAt`) lives on the task itself, so there is no separate + * cursor map — `cron.cursor` folds into the same map by updating the matching + * task's `lastFiredAt`. Each `apply` returns a new `Map` on a real change and + * the same reference on a no-op (a `cron.delete` of absent ids, or a + * `cron.cursor` for an unknown id) so the wire's reference-equality gate stays + * quiet. The Ops are live-only because cron records are not v1 wire types; the + * authoritative store is the App-scoped `ICronTaskPersistence`, reloaded on + * resume. The Ops register into the global + * `OP_REGISTRY` at import time. + */ + +import type { CronJobOrigin } from '#/agent/contextMemory/types'; +import { z } from 'zod'; + +import { defineModel } from '#/wire/model'; + +import type { CronTask } from '#/app/cron/cronTask'; + +export type CronModelState = Map; + +export const CronModel = defineModel('cron', () => new Map()); + +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'cron.fired': { readonly origin: CronJobOrigin; readonly prompt: string }; + } +} + +declare module '#/wire/types' { + interface TransientOpMap { + 'cron.add': typeof cronAdd; + 'cron.delete': typeof cronDelete; + 'cron.cursor': typeof cronCursor; + } +} + +export const cronAdd = CronModel.defineOp('cron.add', { + schema: z.object({ task: z.custom() }), + persist: false, + apply: (s, p) => { + const next = new Map(s); + next.set(p.task.id, p.task); + return next; + }, +}); + +export const cronDelete = CronModel.defineOp('cron.delete', { + schema: z.object({ ids: z.array(z.string()).readonly() }), + persist: false, + apply: (s, p) => { + let next: Map | undefined; + for (const id of p.ids) { + if (s.has(id)) { + next = next ?? new Map(s); + next.delete(id); + } + } + return next ?? s; + }, +}); + +export const cronCursor = CronModel.defineOp('cron.cursor', { + schema: z.object({ id: z.string(), lastFiredAt: z.number() }), + persist: false, + apply: (s, p) => { + const task = s.get(p.id); + if (task === undefined) return s; + const next = new Map(s); + next.set(p.id, { ...task, lastFiredAt: p.lastFiredAt }); + return next; + }, +}); diff --git a/packages/agent-core-v2/src/session/cron/sessionCronService.ts b/packages/agent-core-v2/src/session/cron/sessionCronService.ts new file mode 100644 index 000000000..b009e6f4b --- /dev/null +++ b/packages/agent-core-v2/src/session/cron/sessionCronService.ts @@ -0,0 +1,53 @@ +/** + * `cron` domain — `ISessionCronService` contract. + * + * Session-level scheduling engine for cron tasks. Owns the live task set + * (filtered from `ICronTaskPersistence` by `sessionId` tag), the polling timer, + * and the fire/coalesce/jitter logic. On fire, borrows the main agent's + * `IAgentPromptService` via `IAgentLifecycleService` handle to steer a new + * turn. Bound at Session scope. + */ + +import type { ContentPart } from '#/kosong/contract/message'; + +import { createDecorator } from '#/_base/di/instantiation'; +import type { Turn } from '#/agent/loop/loop'; +import type { CronTask, CronTaskInit } from '#/app/cron/cronTask'; +import type { ParsedCronExpression } from '#/app/cron/cron-expr'; + +export interface CronLoadOptions { + readonly replace?: boolean; +} + +export interface ISessionCronService { + readonly _serviceBrand: undefined; + + readonly isEnabled: boolean; + isDisabled(): boolean; + addTask(init: CronTaskInit): CronTask; + removeTasks(ids: readonly string[]): readonly string[]; + getTask(id: string): CronTask | undefined; + list(): readonly CronTask[]; + now(): number; + isStale(task: CronTask): boolean; + getNextFireTime(): number | null; + getNextFireForTask(taskId: string): number | null; + computeDisplayNextFire( + task: CronTask, + parsed: ParsedCronExpression, + idealMs: number, + ): number | null; + loadFromStore(options?: CronLoadOptions): Promise; + start(): Promise; + stop(): Promise; + tick(): Promise; + flushPersist(): Promise; + handleMissed( + tasks: readonly CronTask[], + renderMissedNotification: (tasks: readonly CronTask[]) => readonly ContentPart[], + ): Turn | undefined; + emitScheduled(task: CronTask, agentId?: string): void; + emitDeleted(taskId: string, agentId?: string): void; +} + +export const ISessionCronService = createDecorator('sessionCronService'); diff --git a/packages/agent-core-v2/src/session/cron/sessionCronServiceImpl.ts b/packages/agent-core-v2/src/session/cron/sessionCronServiceImpl.ts new file mode 100644 index 000000000..74fb9c088 --- /dev/null +++ b/packages/agent-core-v2/src/session/cron/sessionCronServiceImpl.ts @@ -0,0 +1,727 @@ +/** + * `cron` domain — `SessionCronService` implementation. + * + * Session-level scheduling engine. Holds the in-memory task map (filtered + * from `ICronTaskPersistence` by `sessionId` tag), runs the polling timer + * (tick / coalesce / jitter / cursor), persists mutations through the + * App-scoped `ICronTaskPersistence`, mirrors mutations as `cron.add` / + * `cron.delete` / `cron.cursor` Ops on the main agent's `wire` (cross-scope + * borrow) so wire restore can rebuild the `CronModel`, publishes `cron.fired` + * to the main agent's `IEventBus`, steers the main agent + * through `IAgentPromptService` when a task fires, and registers the cron + * tools (`CronCreate` / `CronList` / `CronDelete`) into the main agent's + * `IAgentToolRegistryService` once `IAgentLifecycleService` signals + * `onDidCreateMain`. The plain-data state (`tasks`, `parsedCache`, + * `lastSeenAt`, `seededFromStore`, `inFlight`, `started`) is registered into + * `sessionState` (`ISessionStateService`) and read/written through it. Bound + * at Session scope. + */ + +import { ulid } from 'ulid'; + +import type { ContentPart } from '#/kosong/contract/message'; +import type { CronJobOrigin, CronMissedOrigin } from '#/agent/contextMemory/types'; + +import { Disposable, toDisposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { type IAgentScopeHandle, ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; +import { IntervalTimer } from '#/_base/utils/timer'; + +import { IConfigService } from '#/app/config/config'; +import type { CronDeletedEvent, CronScheduledEvent } from '#/app/telemetry/events'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; +import { type ClockSources, resolveClockSources, SYSTEM_CLOCKS } from '#/app/cron/clock'; +import { type CronConfig, CRON_SECTION } from '#/app/cron/configSection'; +import { computeNextCronRun, parseCronExpression, type ParsedCronExpression } from '#/app/cron/cron-expr'; +import { CRON_SESSION_TAG, type CronTask, type CronTaskInit } from '#/app/cron/cronTask'; +import { ICronTaskPersistence } from '#/app/cron/cronTaskPersistence'; +import { renderCronFireXml } from '#/app/cron/format'; +import { jitteredNextCronRunMs, oneShotJitteredNextCronRunMs } from '#/app/cron/jitter'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; +import { ISessionStateService } from '#/session/state/sessionState'; +import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import type { ContextMessage } from '#/agent/contextMemory/types'; +import { IAgentPromptService } from '#/agent/prompt/prompt'; +import type { Op } from '#/wire/op'; +import { IWireService } from '#/wire/wire'; +import { type DomainEvent, IEventBus } from '#/app/event/eventBus'; +import { IAgentToolRegistryService } from '#/agent/toolRegistry/toolRegistry'; +import { IAgentLoopService, type Turn } from '#/agent/loop/loop'; +import { BugIndicatingError } from '#/errors'; + +import { ICronCreateTool } from '#/agent/tools/cron/cron-create/cron-create'; +import { ICronListTool } from '#/agent/tools/cron/cron-list/cron-list'; +import { ICronDeleteTool } from '#/agent/tools/cron/cron-delete/cron-delete'; + +import { CronModel, cronAdd, cronDelete, cronCursor } from './cronOps'; +import { ISessionCronService, type CronLoadOptions } from './sessionCronService'; + +export const CRON_SCHEDULED = 'cron_scheduled' as const; +export const CRON_FIRED = 'cron_fired' as const; +export const CRON_MISSED = 'cron_missed' as const; +export const CRON_DELETED = 'cron_deleted' as const; + +export const cronTasksKey = defineState>('cron.tasks', () => new Map()); +export const cronParsedCacheKey = defineState>( + 'cron.parsedCache', + () => new Map(), +); +export const cronLastSeenAtKey = defineState>('cron.lastSeenAt', () => new Map()); +export const cronSeededFromStoreKey = defineState>('cron.seededFromStore', () => new Set()); +export const cronInFlightKey = defineState>('cron.inFlight', () => new Set()); +export const cronStartedKey = defineState('cron.started', () => false); + +const STALE_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1000; +const DEFAULT_POLL_INTERVAL_MS = 1_000; +const MAX_COALESCE_ITERATIONS = 10_000; +const CRON_ID_REGEX: RegExp = /^(?:[0-9a-f]{8}|[0-9A-HJKMNP-TV-Z]{26})$/i; +const MAX_ID_ATTEMPTS = 8; + +// NOTE: stays Disposable — its own 'config' collides with the Fiber +export class SessionCronServiceImpl extends Disposable implements ISessionCronService { + declare readonly _serviceBrand: undefined; + + private readonly timer = this._register(new IntervalTimer({ unref: true })); + private readonly persistQueues = new Map>(); + + private clocks: ClockSources = SYSTEM_CLOCKS; + readonly isEnabled: boolean = true; + + private sigusr1Handler: NodeJS.SignalsListener | null = null; + + constructor( + @ISessionStateService private readonly states: ISessionStateService, + @ISessionContext private readonly ctx: ISessionContext, + @ICronTaskPersistence private readonly store: ICronTaskPersistence, + @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @ITelemetryService private readonly telemetry: ITelemetryService, + @IConfigService private readonly config: IConfigService, + ) { + super(); + + this.states.register(cronTasksKey); + this.states.register(cronParsedCacheKey); + this.states.register(cronLastSeenAtKey); + this.states.register(cronSeededFromStoreKey); + this.states.register(cronInFlightKey); + this.states.register(cronStartedKey); + + this._register( + this.agentLifecycle.onDidCreate((handle) => { + if (handle.id !== 'main') return; + this.bindMainAgent(handle); + }), + ); + + const existingMain = this.agentLifecycle.get('main'); + if (existingMain) { + this.bindMainAgent(existingMain); + } + + this._register( + toDisposable(() => { + void this.stop(); + }), + ); + } + + private get tasks(): Map { + return this.states.get(cronTasksKey); + } + + private get parsedCache(): Map { + return this.states.get(cronParsedCacheKey); + } + + private get lastSeenAt(): Map { + return this.states.get(cronLastSeenAtKey); + } + + private get seededFromStore(): Set { + return this.states.get(cronSeededFromStoreKey); + } + + private get inFlight(): Set { + return this.states.get(cronInFlightKey); + } + + private get started(): boolean { + return this.states.get(cronStartedKey); + } + + private set started(value: boolean) { + this.states.set(cronStartedKey, value); + } + + private bindMainAgent(handle: IAgentScopeHandle): void { + const wire = handle.accessor.get(IWireService); + this._register( + wire.hooks.onDidRestore.register('cron', async (_ctx, next) => { + await this.config.ready; + this.resolveClocks(); + this.tasks.clear(); + for (const [id, task] of wire.getModel(CronModel)) { + this.tasks.set(id, task as CronTask); + } + await this.loadFromStore({ replace: false }); + await this.start(); + await next(); + }), + ); + + this.registerCronTools(handle); + } + + private registerCronTools(handle: IAgentScopeHandle): void { + const registry = handle.accessor.get(IAgentToolRegistryService); + const tools = [ + handle.accessor.get(ICronCreateTool), + handle.accessor.get(ICronListTool), + handle.accessor.get(ICronDeleteTool), + ]; + for (const tool of tools) { + this._register(registry.register(tool, { source: 'builtin' })); + } + } + + now(): number { + return this.clocks.wallNow(); + } + + private resolveClocks(): void { + const cfg = this.getCronConfig(); + this.clocks = resolveClockSources(cfg.clock, cfg.debug) ?? SYSTEM_CLOCKS; + } + + private getCronConfig(): CronConfig { + return this.config.get(CRON_SECTION); + } + + isDisabled(): boolean { + return this.getCronConfig().disabled; + } + + + addTask(init: CronTaskInit): CronTask { + const task: CronTask = { + ...init, + id: this.generateUniqueId(), + createdAt: this.clocks.wallNow(), + tags: { ...init.tags, [CRON_SESSION_TAG]: this.ctx.sessionId }, + }; + this.tasks.set(task.id, task); + this.dispatchCron(cronAdd({ task })); + this.persistEnqueue(task.id, () => + this.store.save(this.ctx.workspaceId, task), + ); + return task; + } + + removeTasks(ids: readonly string[]): readonly string[] { + const removed = this.removeByIds(ids); + if (removed.length === 0) return removed; + + this.dispatchCron(cronDelete({ ids: removed })); + for (const id of removed) { + this.persistEnqueue(id, () => + this.store.delete(this.ctx.workspaceId, id), + ); + } + return removed; + } + + getTask(id: string): CronTask | undefined { + return this.tasks.get(id); + } + + list(): readonly CronTask[] { + return Array.from(this.tasks.values()); + } + + + isStale(task: CronTask): boolean { + return this.isStaleAt(task, this.clocks.wallNow()); + } + + getNextFireTime(): number | null { + if (this.tasks.size === 0) return null; + let min: number | null = null; + for (const task of this.tasks.values()) { + const next = this.nextFireFor(task); + if (next === null) continue; + if (min === null || next < min) min = next; + } + return min; + } + + getNextFireForTask(taskId: string): number | null { + const task = this.tasks.get(taskId); + if (task === undefined) return null; + return this.nextFireFor(task); + } + + + async loadFromStore(options: CronLoadOptions = {}): Promise { + if (options.replace !== false) { + this.tasks.clear(); + } + const allTasks = await this.store.list({ workspaceId: this.ctx.workspaceId }); + for (const task of allTasks) { + const owner = task.tags?.[CRON_SESSION_TAG]; + if (owner !== undefined && owner !== this.ctx.sessionId) continue; + if (owner === undefined) { + const claimed: CronTask = { + ...task, + tags: { ...task.tags, [CRON_SESSION_TAG]: this.ctx.sessionId }, + }; + this.adopt(claimed); + this.persistEnqueue(claimed.id, () => + this.store.save(this.ctx.workspaceId, claimed), + ); + continue; + } + this.adopt(task); + } + } + + async start(): Promise { + if (this.started) return; + this.started = true; + + await this.config.ready; + const cfg = this.getCronConfig(); + const poll = cfg.manualTick ? null : cfg.pollIntervalMs; + const interval = poll === undefined ? DEFAULT_POLL_INTERVAL_MS : poll; + if (interval !== null && interval !== 0) { + this.timer.cancelAndSet(() => { void this.tick(); }, interval); + } + this.bindSigusr1(); + } + + async stop(): Promise { + this.unbindSigusr1(); + this.timer.cancel(); + this.inFlight.clear(); + this.lastSeenAt.clear(); + this.seededFromStore.clear(); + this.parsedCache.clear(); + await this.flushPersist(); + this.started = false; + } + + async tick(): Promise { + await this.config.ready; + if (this.getCronConfig().disabled) return; + if (this.tasks.size === 0) return; + + const mainHandle = this.agentLifecycle.get('main'); + if (!mainHandle) return; + + const loop = mainHandle.accessor.get(IAgentLoopService); + if (loop.status().state === 'running') return; + + const now = this.clocks.wallNow(); + + const work: Promise[] = []; + for (const task of this.list()) { + work.push(this.processDue(task, now)); + } + await Promise.all(work); + } + + private async processDue(task: CronTask, now: number): Promise { + if (this.inFlight.has(task.id)) return; + + let parsed: ParsedCronExpression; + try { + parsed = this.getParsed(task.cron); + } catch (error) { + this.debugLog( + `tick failed to parse cron for task ${task.id}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + return; + } + + if ( + !this.seededFromStore.has(task.id) && + task.lastFiredAt !== undefined && + Number.isFinite(task.lastFiredAt) && + task.lastFiredAt <= now && + !this.lastSeenAt.has(task.id) + ) { + this.lastSeenAt.set(task.id, task.lastFiredAt); + } + this.seededFromStore.add(task.id); + + const seen = this.lastSeenAt.get(task.id); + const baseFromMs = + seen !== undefined && seen > task.createdAt ? seen : task.createdAt; + + const nextFireAt = this.computeJitteredNext(task, parsed, baseFromMs); + if (nextFireAt === null) return; + if (now < nextFireAt) return; + + const ideal = computeNextCronRun(parsed, baseFromMs); + let coalescedCount = 1; + let lastDueMs: number | null = null; + if (task.recurring !== false && ideal !== null) { + const result = this.countCoalesced(task, parsed, ideal, now); + coalescedCount = Math.max(1, result.count); + lastDueMs = result.lastDueMs; + } + + this.inFlight.add(task.id); + let delivered = false; + try { + delivered = await this.deliverDue(task, coalescedCount); + } catch (error) { + this.debugLog( + `deliverDue threw for task ${task.id}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + } finally { + this.inFlight.delete(task.id); + } + if (!delivered) return; + + if (task.recurring === false) { + this.removeTasks([task.id]); + this.lastSeenAt.delete(task.id); + this.seededFromStore.delete(task.id); + } else { + const advancedTo = lastDueMs ?? now; + this.lastSeenAt.set(task.id, advancedTo); + this.advanceCursor(task.id, advancedTo); + } + } + + async flushPersist(): Promise { + const inFlight = Array.from(this.persistQueues.values()); + await Promise.allSettled(inFlight); + } + + handleMissed( + tasks: readonly CronTask[], + renderMissedNotification: (tasks: readonly CronTask[]) => readonly ContentPart[], + ): Turn | undefined { + if (tasks.length === 0) return undefined; + + const mainHandle = this.agentLifecycle.get('main'); + if (!mainHandle) return undefined; + + const promptService = mainHandle.accessor.get(IAgentPromptService); + + const origin: CronMissedOrigin = { + kind: 'cron_missed', + count: tasks.length, + }; + const message: ContextMessage = { + role: 'user', + content: [...renderMissedNotification(tasks)], + toolCalls: [], + origin, + }; + void promptService.inject(message).catch(() => {}); + this.telemetry.track2(CRON_MISSED, { count: tasks.length }); + return undefined; + } + + emitScheduled(task: CronTask, agentId?: string): void { + const properties: CronScheduledEvent = { + recurring: task.recurring !== false, + agent_id: agentId, + }; + this.telemetry.track2(CRON_SCHEDULED, properties); + } + + emitDeleted(taskId: string, agentId?: string): void { + const properties: CronDeletedEvent = { task_id: taskId, agent_id: agentId }; + this.telemetry.track2(CRON_DELETED, properties); + } + + + private async deliverDue(task: CronTask, coalescedCount: number): Promise { + const firedAt = this.clocks.wallNow(); + const stale = this.isStaleAt(task, firedAt); + const delivered = await this.deliverFire(task, { coalescedCount, firedAt }); + if (delivered && stale && task.recurring !== false) { + const removed = this.removeTasks([task.id]); + if (removed.length > 0) this.emitDeleted(task.id); + } + return delivered; + } + + private deliverFire( + task: CronTask, + ctx: { readonly coalescedCount: number; readonly firedAt: number }, + ): Promise { + const mainHandle = this.agentLifecycle.get('main'); + if (!mainHandle) return Promise.resolve(false); + + const promptService = mainHandle.accessor.get(IAgentPromptService); + + const origin: CronJobOrigin = { + kind: 'cron_job', + jobId: task.id, + cron: task.cron, + recurring: task.recurring !== false, + coalescedCount: ctx.coalescedCount, + stale: this.isStaleAt(task, ctx.firedAt), + }; + const message: ContextMessage = { + role: 'user', + content: [ + { + type: 'text', + text: renderCronFireXml(origin, task.prompt), + }, + ], + toolCalls: [], + origin, + }; + const buffered = mainHandle.accessor.get(IAgentLoopService).status().state === 'running'; + + let launched: Promise; + try { + launched = promptService.inject(message); + } catch (error) { + this.debugLog( + `steer threw for task ${task.id}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + return Promise.resolve(false); + } + + return launched.then( + () => { + this.signalCron({ type: 'cron.fired', origin, prompt: task.prompt }); + this.telemetry.track2(CRON_FIRED, { + recurring: task.recurring !== false, + coalesced_count: ctx.coalescedCount, + stale: origin.stale, + buffered, + }); + return true; + }, + (error: unknown) => { + this.debugLog( + `steer launch rejected for task ${task.id}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + return false; + }, + ); + } + + private advanceCursor(id: string, lastFiredAt: number): void { + const updated = this.markFired(id, lastFiredAt); + if (updated === undefined) return; + + this.dispatchCron(cronCursor({ id, lastFiredAt })); + this.persistEnqueue(id, () => + this.store.save(this.ctx.workspaceId, updated), + ); + } + + + private dispatchCron(op: Op): void { + const mainHandle = this.agentLifecycle.get('main'); + if (!mainHandle) return; + mainHandle.accessor.get(IWireService).dispatch(op); + } + + private signalCron(event: DomainEvent): void { + const mainHandle = this.agentLifecycle.get('main'); + if (!mainHandle) return; + mainHandle.accessor.get(IEventBus).publish(event); + } + + + private getParsed(expr: string): ParsedCronExpression { + const cached = this.parsedCache.get(expr); + if (cached !== undefined) return cached; + const parsed = parseCronExpression(expr); + this.parsedCache.set(expr, parsed); + return parsed; + } + + private computeJitteredNext( + task: CronTask, + parsed: ParsedCronExpression, + baseMs: number, + ): number | null { + const ideal = computeNextCronRun(parsed, baseMs); + if (ideal === null) return null; + if (task.recurring === false) { + return oneShotJitteredNextCronRunMs(task, ideal, undefined, this.getCronConfig().noJitter); + } + return jitteredNextCronRunMs(task, parsed, ideal, undefined, this.getCronConfig().noJitter); + } + + computeDisplayNextFire( + task: CronTask, + parsed: ParsedCronExpression, + idealMs: number, + ): number | null { + const noJitter = this.getCronConfig().noJitter; + if (task.recurring === false) { + return oneShotJitteredNextCronRunMs(task, idealMs, undefined, noJitter); + } + return jitteredNextCronRunMs(task, parsed, idealMs, undefined, noJitter); + } + + private countCoalesced( + task: CronTask, + parsed: ParsedCronExpression, + firstFireMs: number, + nowMs: number, + ): { count: number; lastDueMs: number } { + let count = 1; + let cursor = firstFireMs; + let lastDueMs = firstFireMs; + while (count < MAX_COALESCE_ITERATIONS) { + const next = computeNextCronRun(parsed, cursor); + if (next === null) break; + if (next > nowMs) break; + const jitteredNext = + task.recurring === false + ? oneShotJitteredNextCronRunMs(task, next, undefined, this.getCronConfig().noJitter) + : jitteredNextCronRunMs(task, parsed, next, undefined, this.getCronConfig().noJitter); + if (jitteredNext > nowMs) break; + count++; + cursor = next; + lastDueMs = next; + } + return { count, lastDueMs }; + } + + private nextFireFor(task: CronTask): number | null { + try { + const parsed = this.getParsed(task.cron); + const seen = this.lastSeenAt.get(task.id); + const persistedCursor = + task.lastFiredAt !== undefined && + Number.isFinite(task.lastFiredAt) && + task.lastFiredAt <= this.clocks.wallNow() + ? task.lastFiredAt + : undefined; + const cursor = + seen !== undefined + ? seen + : persistedCursor !== undefined + ? persistedCursor + : undefined; + const baseFromMs = + cursor !== undefined && cursor > task.createdAt ? cursor : task.createdAt; + return this.computeJitteredNext(task, parsed, baseFromMs); + } catch (error) { + this.debugLog( + `nextFireFor skipping task ${task.id}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + return null; + } + } + + private debugLog(message: string): void { + if (this.getCronConfig().debug) { + process.stderr.write(`[cron/session] ${message}\n`); + } + } + + + private adopt(task: CronTask): void { + this.tasks.set(task.id, task); + } + + private markFired(id: string, lastFiredAt: number): CronTask | undefined { + const existing = this.tasks.get(id); + if (existing === undefined) return undefined; + const updated: CronTask = { ...existing, lastFiredAt }; + this.tasks.set(id, updated); + return updated; + } + + private removeByIds(ids: readonly string[]): readonly string[] { + const removed: string[] = []; + for (const id of ids) { + if (this.tasks.delete(id)) { + removed.push(id); + } + } + return removed; + } + + private generateUniqueId(): string { + for (let attempt = 0; attempt < MAX_ID_ATTEMPTS; attempt++) { + const candidate = ulid(); + if (!CRON_ID_REGEX.test(candidate)) continue; + if (!this.tasks.has(candidate)) return candidate; + } + throw new BugIndicatingError( + `SessionCronService: failed to generate a unique ULID after ${MAX_ID_ATTEMPTS} attempts`, + ); + } + + private isStaleAt(task: CronTask, now: number): boolean { + if (this.getCronConfig().noStale) return false; + if (task.recurring === false) return false; + const age = now - task.createdAt; + return Number.isFinite(age) && age >= STALE_THRESHOLD_MS; + } + + + private persistEnqueue(id: string, work: () => Promise): void { + const prev = this.persistQueues.get(id) ?? Promise.resolve(); + const next = prev + .catch(() => {}) + .then(() => work()) + .catch(() => {}) + .finally(() => { + if (this.persistQueues.get(id) === next) { + this.persistQueues.delete(id); + } + }); + this.persistQueues.set(id, next); + } + + + private bindSigusr1(): void { + if (process.platform === 'win32') return; + if (!this.getCronConfig().manualTick) return; + if (this.sigusr1Handler !== null) return; + const handler: NodeJS.SignalsListener = () => { + try { + void this.tick(); + } catch (error) { + if (this.getCronConfig().debug) { + const msg = error instanceof Error ? error.message : String(error); + process.stderr.write(`[cron/session] SIGUSR1 tick threw: ${msg}\n`); + } + } + }; + this.sigusr1Handler = handler; + process.on('SIGUSR1', handler); + } + + private unbindSigusr1(): void { + if (this.sigusr1Handler === null) return; + process.off('SIGUSR1', this.sigusr1Handler); + this.sigusr1Handler = null; + } +} + +registerScopedService( + LifecycleScope.Session, + ISessionCronService, + SessionCronServiceImpl, + ScopeActivation.OnScopeCreated, + 'cron', +); diff --git a/packages/agent-core-v2/src/session/errors.ts b/packages/agent-core-v2/src/session/errors.ts index 2efaa4037..861518d47 100644 --- a/packages/agent-core-v2/src/session/errors.ts +++ b/packages/agent-core-v2/src/session/errors.ts @@ -1,3 +1,8 @@ +/** + * `session` domain error codes — shared across the session layer + * (`sessionLifecycle` / `sessionLegacy`). + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const SessionErrors = { @@ -10,7 +15,6 @@ export const SessionErrors = { SESSION_UNDO_UNAVAILABLE: 'session.undo_unavailable', SESSION_INIT_FAILED: 'session.init_failed', SESSION_PLAN_MODE_INVALID: 'session.plan_mode_invalid', - SESSION_TOWER_MODE_INVALID: 'session.tower_mode_invalid', }, retryable: ['session.fork_active_turn'], } as const satisfies ErrorDomain; diff --git a/packages/agent-core-v2/src/session/externalHooks/externalHooks.ts b/packages/agent-core-v2/src/session/externalHooks/externalHooks.ts new file mode 100644 index 000000000..b490d12b7 --- /dev/null +++ b/packages/agent-core-v2/src/session/externalHooks/externalHooks.ts @@ -0,0 +1,21 @@ +/** + * `externalHooks` domain — Session-scope external hook observer contract. + * + * The implementation registers session lifecycle callbacks from its + * constructor (for `SessionStart` / `SessionEnd`) and observes the + * requester-side agent-run hook slots hosted on `agentLifecycle`'s + * `IAgentLifecycleService` to translate them into `SubagentStart` / + * `SubagentStop` external hook commands. The slot host and its observer live + * in separate Session-scope services so the runner owns the + * slots it runs, matching the Agent-scope pattern where the behavior services + * own the slots and the external-hooks adapter only observes. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +export interface ISessionExternalHooksService { + readonly _serviceBrand: undefined; +} + +export const ISessionExternalHooksService: ServiceIdentifier = + createDecorator('sessionExternalHooksService'); diff --git a/packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooksService.ts b/packages/agent-core-v2/src/session/externalHooks/externalHooksService.ts similarity index 62% rename from packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooksService.ts rename to packages/agent-core-v2/src/session/externalHooks/externalHooksService.ts index 9b6aa2251..cd82ec7a6 100644 --- a/packages/agent-core-v2/src/features/externalHooks/session/sessionExternalHooksService.ts +++ b/packages/agent-core-v2/src/session/externalHooks/externalHooksService.ts @@ -1,24 +1,53 @@ +/** + * `externalHooks` domain — Session-scope adapter for external hook + * commands. + * + * Registers with the per-session `sessionLifecycleHooks` slots (seeded by + * the Workspace-scope `sessionLifecycle`, which runs them around + * create/close) to run `SessionStart` and `SessionEnd` external commands + * for the current `sessionContext`, and + * observes the requester-side agent-run hook slot (`onWillStartAgentTask`) and + * stop event (`onDidStopAgentTask`) hosted on the `subagent` domain's + * `ISessionSubagentService` to translate them into the `SubagentStart` / + * `SubagentStop` external commands. It also owns the periodic + * `SessionHeartbeat` command (one timer per session, ticking only when the + * event is configured), enriches every payload it sends with the cached + * session title (seeded from and kept fresh by `ISessionMetadata`), and + * resolves the SessionStart model/profile facts from `IModelService` / + * `ISessionAgentProfileCatalog`. The slot/event host lives on the service + * that owns the run; this adapter only registers its + * own listeners here, so the runner owns the slots it runs — the same pattern + * the Agent-scope adapter follows against the agent behavior services. The + * actual hook execution is delegated to the shared App-scope + * `IExternalHooksRunnerService`; all config/plugin loading and engine lifecycle + * live in the runner. Bound at Session scope. + */ + import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IntervalTimer } from '#/_base/utils/timer'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; +import { IExternalHooksRunnerService } from '#/app/externalHooksRunner/externalHooksRunner'; +import type { Hooks } from '#/hooks'; import { IModelService } from '#/kosong/model/model'; import { ISessionAgentProfileCatalog, } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; +import { + ISessionLifecycleHooks, + type SessionCloseReason, + type SessionCreateSource, + type SessionLifecycleHookSlots, +} from '#/session/sessionLifecycleHooks/sessionLifecycleHooks'; import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; import { type AgentTaskStartHookContext, type AgentTaskStopHookContext, ISessionSubagentService, } from '#/session/subagent/subagent'; -import { - type SessionCloseReason, - type SessionCreateSource, -} from '#/workspace/sessionLifecycle/sessionLifecycle'; -import { IExternalHooksRunnerService } from '../app/externalHooksRunner'; -import { ISessionExternalHooksService } from './sessionExternalHooks'; +import { ISessionExternalHooksService } from './externalHooks'; type SessionStartHookSource = Exclude; @@ -35,7 +64,7 @@ export class SessionExternalHooksService constructor( @ISessionContext private readonly context: ISessionContext, - @ISessionManager lifecycle: ISessionManager, + @ISessionLifecycleHooks lifecycleHooks: Hooks, @ISessionSubagentService subagents: ISessionSubagentService, @ISessionMetadata private readonly metadata: ISessionMetadata, @ISessionAgentProfileCatalog private readonly profiles: ISessionAgentProfileCatalog, @@ -60,26 +89,20 @@ export class SessionExternalHooksService .catch(() => undefined); }), ); - const onDidCreate = lifecycle.onDidCreateSession; - if (onDidCreate !== undefined) { - this._register( - onDidCreate((event) => { - if (event.sessionId !== this.context.sessionId) return; - if (event.source !== 'fork') { - event.waitUntil(this.triggerSessionStart(event.source)); - } - }), - ); - } - const onWillClose = lifecycle.onWillCloseSession; - if (onWillClose !== undefined) { - this._register( - onWillClose((event) => { - if (event.sessionId !== this.context.sessionId) return; - event.waitUntil(this.triggerSessionEnd(event.reason)); - }), - ); - } + this._register( + lifecycleHooks.onDidCreateSession.register('externalHooks', async (event, next) => { + if (event.source !== 'fork') { + await this.triggerSessionStart(event.source); + } + await next(); + }), + ); + this._register( + lifecycleHooks.onWillCloseSession.register('externalHooks', async (event, next) => { + await this.triggerSessionEnd(event.reason); + await next(); + }), + ); this._register( subagents.hooks.onWillStartAgentTask.register('externalHooks', async (ctx, next) => { await this.runSubagentStart(ctx); @@ -88,6 +111,11 @@ export class SessionExternalHooksService ); this._register(subagents.onDidStopAgentTask((ctx) => this.notifySubagentStop(ctx))); + // Arm the heartbeat only once the configured-hook index has loaded and + // only when the event has hooks at all, so sessions without a + // SessionHeartbeat hook never hold a recurring timer. Re-sync on every + // hook-index reload (plugin reload) so late-registered heartbeat hooks + // still arm, and removed ones disarm. void this.runner.ready .then(() => this.syncHeartbeat()) .catch(() => undefined); @@ -181,3 +209,11 @@ export class SessionExternalHooksService }); } } + +registerScopedService( + LifecycleScope.Session, + ISessionExternalHooksService, + SessionExternalHooksService, + ScopeActivation.OnScopeCreated, + 'externalHooks', +); diff --git a/packages/agent-core-v2/src/session/externalHooks/index.ts b/packages/agent-core-v2/src/session/externalHooks/index.ts new file mode 100644 index 000000000..0c7145dbc --- /dev/null +++ b/packages/agent-core-v2/src/session/externalHooks/index.ts @@ -0,0 +1,8 @@ +/** + * `externalHooks` domain barrel — re-exports the Session-scope external hooks + * contract and its scoped service. Importing this barrel registers the + * `ISessionExternalHooksService` binding into the scope registry. + */ + +export * from './externalHooks'; +export * from './externalHooksService'; diff --git a/packages/agent-core-v2/src/session/interaction/interaction.ts b/packages/agent-core-v2/src/session/interaction/interaction.ts new file mode 100644 index 000000000..6b3bf17c1 --- /dev/null +++ b/packages/agent-core-v2/src/session/interaction/interaction.ts @@ -0,0 +1,62 @@ +/** + * `interaction` domain — blocking human-in-the-loop request kernel. + * + * Defines the `Interaction` model and the `ISessionInteractionService` kernel that + * owns the session's pending interaction set: a unified, blocking request / + * response primitive (`request` → `respond`) with change notification + * (`onDidChangePending`), a non-blocking enqueue (`enqueue`) for callers that observe + * the outcome through the `onDidResolve` stream, and a `listPending` view. + * `approval`, `question`, and user-tool execution are typed specializations + * layered on top of this kernel; the kernel itself is domain-agnostic. + * Session-scoped — the pending set is keyed by session and dies with it. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { Event } from '#/_base/event'; + +export type InteractionKind = 'approval' | 'question' | 'user_tool'; + +export interface InteractionOrigin { + readonly agentId?: string; + readonly turnId?: number; +} + +export interface InteractionRequest { + readonly id?: string; + readonly kind: InteractionKind; + readonly payload: TPayload; + readonly origin?: InteractionOrigin; +} + +export interface Interaction { + readonly id: string; + readonly kind: InteractionKind; + readonly payload: TPayload; + readonly origin: InteractionOrigin; + readonly createdAt: number; +} + +export interface InteractionResolution { + readonly id: string; + readonly response: unknown; +} + +export interface InteractionPendingChangedEvent { + readonly pending: readonly string[]; +} + +export interface ISessionInteractionService { + readonly _serviceBrand: undefined; + + request(req: InteractionRequest): Promise; + enqueue(req: InteractionRequest): Interaction; + respond(id: string, response: unknown): void; + listPending(kind?: InteractionKind): readonly Interaction[]; + isRecentlyResolved(id: string): boolean; + cancelPendingForTurn(turnId: number): void; + readonly onDidChangePending: Event; + readonly onDidResolve: Event; +} + +export const ISessionInteractionService: ServiceIdentifier = + createDecorator('sessionInteractionService'); diff --git a/packages/agent-core-v2/src/session/interaction/interactionOps.ts b/packages/agent-core-v2/src/session/interaction/interactionOps.ts new file mode 100644 index 000000000..b0973b9c4 --- /dev/null +++ b/packages/agent-core-v2/src/session/interaction/interactionOps.ts @@ -0,0 +1,85 @@ +/** + * `interaction` domain — wire Model (`InteractionModel`) and the + * persisted `interaction.request` (`interactionRequest`) / + * `interaction.resolved` (`interactionResolved`) Ops that journal the + * session's human-in-the-loop lifecycle onto the owning agent's wire. + * + * The Model is the replayable map of `interactionId -> InteractionRecord` + * (initial empty): `interaction.request` opens an entry, `interaction.resolved` + * folds the terminal response into it (a resolution without a known request is + * a no-op so the wire's reference-equality gate stays quiet). The records exist + * so a cold transcript fold can rebuild interaction entities (kind, the + * `toolCallId` timeline anchor lifted from the request payload, the raw + * request, and the terminal response) straight from the journal; the kernel + * itself does NOT restore pending promises from them — a request left without + * a resolution means the process died with it pending and folds as cancelled + * downstream. These Ops are dispatched to the ORIGIN agent's wire + * (`origin.agentId ?? 'main'`), so each record lives in the journal of the + * agent the interaction belongs to. + */ + +import { z } from 'zod'; + +import { defineModel } from '#/wire/model'; + +import type { InteractionKind } from './interaction'; + +export interface InteractionRecord { + readonly id: string; + readonly kind: InteractionKind; + readonly toolCallId?: string; + readonly agentId?: string; + readonly request: unknown; + readonly resolved: boolean; + readonly response?: unknown; +} + +export type InteractionModelState = Map; + +export const InteractionModel = defineModel( + 'interaction', + () => new Map(), +); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'interaction.request': typeof interactionRequest; + 'interaction.resolved': typeof interactionResolved; + } +} + +export const interactionRequest = InteractionModel.defineOp('interaction.request', { + schema: z.object({ + id: z.string(), + kind: z.enum(['approval', 'question', 'user_tool']), + toolCallId: z.string().optional(), + agentId: z.string().optional(), + request: z.unknown(), + }), + apply: (s, p) => { + const next = new Map(s); + next.set(p.id, { + id: p.id, + kind: p.kind, + toolCallId: p.toolCallId, + agentId: p.agentId, + request: p.request, + resolved: false, + }); + return next; + }, +}); + +export const interactionResolved = InteractionModel.defineOp('interaction.resolved', { + schema: z.object({ + id: z.string(), + response: z.unknown(), + }), + apply: (s, p) => { + const existing = s.get(p.id); + if (existing === undefined) return s; + const next = new Map(s); + next.set(p.id, { ...existing, resolved: true, response: p.response }); + return next; + }, +}); diff --git a/packages/agent-core-v2/src/session/interaction/interactionService.ts b/packages/agent-core-v2/src/session/interaction/interactionService.ts new file mode 100644 index 000000000..2984c85f8 --- /dev/null +++ b/packages/agent-core-v2/src/session/interaction/interactionService.ts @@ -0,0 +1,228 @@ +/** + * `interaction` domain — `ISessionInteractionService` implementation. + * + * Owns the pending interaction set and resolves requests when a response + * arrives; announces add/remove through a typed `onDidChangePending`. Every + * request/resolution is also journaled as a persisted `interaction.request` / + * `interaction.resolved` Op on the ORIGIN agent's wire (`origin.agentId ?? + * 'main'`), so the journal can rebuild interaction entities on a cold + * transcript fold. The plain-data state (`pending`, `recentlyResolved`, + * `nextId`) is registered into `sessionState` (`ISessionStateService`) and + * read/written through it. `IAgentLifecycleService` is resolved lazily at dispatch + * time (via `IInstantiationService.invokeFunction`) — a constructor edge + * would close a DI cycle. Direct construction without a + * container (tests, embeddings) simply skips the journaling. The kernel's + * pending semantics stay memory-only: pending promises are never restored + * from the journal. Bound at Session scope. + */ + +import { Emitter, type Event } from '#/_base/event'; +import { IInstantiationService } from '#/_base/di/instantiation'; +import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; + +import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { ISessionStateService } from '#/session/state/sessionState'; +import { IWireService } from '#/wire/wire'; + +import { + type Interaction, + type InteractionKind, + type InteractionOrigin, + type InteractionPendingChangedEvent, + type InteractionRequest, + type InteractionResolution, + ISessionInteractionService, +} from './interaction'; +import { interactionRequest, interactionResolved } from './interactionOps'; + +interface Pending { + readonly interaction: Interaction; + readonly resolve: (response: unknown) => void; +} + +const RECENTLY_RESOLVED_TTL_MS = 60_000; +const RECENTLY_RESOLVED_MAX = 256; +const MAIN_AGENT_ID = 'main'; + +export const interactionPendingKey = defineState>( + 'interaction.pending', + () => new Map(), +); +export const interactionRecentlyResolvedKey = defineState>( + 'interaction.recentlyResolved', + () => new Map(), +); +export const interactionNextIdKey = defineState('interaction.nextId', () => 0); + +export class SessionInteractionService extends Service implements ISessionInteractionService { + declare readonly _serviceBrand: undefined; + + private readonly _onDidChangePending = this._register(new Emitter()); + readonly onDidChangePending: Event = this._onDidChangePending.event; + private readonly _onDidResolve = this._register(new Emitter()); + readonly onDidResolve: Event = this._onDidResolve.event; + + constructor( + @ISessionStateService private readonly states: ISessionStateService, + @IInstantiationService private readonly instantiation?: IInstantiationService, + ) { + super(); + this.states.register(interactionPendingKey); + this.states.register(interactionRecentlyResolvedKey); + this.states.register(interactionNextIdKey); + } + + private get pending(): Map { + return this.states.get(interactionPendingKey); + } + + private get recentlyResolved(): Map { + return this.states.get(interactionRecentlyResolvedKey); + } + + private get nextId(): number { + return this.states.get(interactionNextIdKey); + } + + private set nextId(value: number) { + this.states.set(interactionNextIdKey, value); + } + + cancelPendingForTurn(turnId: number): void { + let changed = false; + for (const [id, entry] of this.pending) { + if (entry.interaction.origin?.turnId !== turnId) continue; + this.pending.delete(id); + this.rememberResolved(id); + const response = { cancelled: true, reason: 'turn_ended' }; + entry.resolve(response); + this.recordResolved(id, response, entry.interaction.origin); + this._onDidResolve.fire({ id, response }); + changed = true; + } + if (changed) { + this._onDidChangePending.fire({ pending: [...this.pending.keys()] }); + } + } + + request(req: InteractionRequest): Promise { + return new Promise((resolve) => { + this.park(req, resolve as (response: unknown) => void); + }); + } + + enqueue(req: InteractionRequest): Interaction { + return this.park(req, () => {}); + } + + respond(id: string, response: unknown): void { + const entry = this.pending.get(id); + if (entry === undefined) return; + this.pending.delete(id); + this.rememberResolved(id); + entry.resolve(response); + this.recordResolved(id, response, entry.interaction.origin); + this._onDidChangePending.fire({ pending: [...this.pending.keys()] }); + this._onDidResolve.fire({ id, response }); + } + + listPending(kind?: InteractionKind): readonly Interaction[] { + const all = [...this.pending.values()].map((p) => p.interaction); + return kind === undefined ? all : all.filter((i) => i.kind === kind); + } + + isRecentlyResolved(id: string): boolean { + const resolvedAt = this.recentlyResolved.get(id); + if (resolvedAt === undefined) return false; + if (Date.now() - resolvedAt > RECENTLY_RESOLVED_TTL_MS) { + this.recentlyResolved.delete(id); + return false; + } + return true; + } + + private park( + req: InteractionRequest, + resolve: (response: unknown) => void, + ): Interaction { + const id = req.id ?? this.generateId(); + const origin: InteractionOrigin = req.origin ?? {}; + const interaction: Interaction = { + id, + kind: req.kind, + payload: req.payload, + origin, + createdAt: Date.now(), + }; + this.pending.set(id, { interaction, resolve }); + this.recordRequest(interaction); + this._onDidChangePending.fire({ pending: [...this.pending.keys()] }); + return interaction; + } + + private recordRequest(interaction: Interaction): void { + const wire = this.originWire(interaction.origin); + if (wire === undefined) return; + wire.dispatch( + interactionRequest({ + id: interaction.id, + kind: interaction.kind, + toolCallId: readPayloadToolCallId(interaction.payload), + agentId: interaction.origin.agentId, + request: interaction.payload, + }), + ); + } + + private recordResolved(id: string, response: unknown, origin: InteractionOrigin): void { + const wire = this.originWire(origin); + if (wire === undefined) return; + wire.dispatch(interactionResolved({ id, response })); + } + + private originWire(origin: InteractionOrigin): IWireService | undefined { + if (this.instantiation === undefined) return undefined; + const agentId = origin.agentId ?? MAIN_AGENT_ID; + try { + return this.instantiation.invokeFunction( + (accessor) => accessor.get(IAgentLifecycleService).get(agentId)?.accessor.get(IWireService), + ); + } catch { + return undefined; + } + } + + private rememberResolved(id: string): void { + const now = Date.now(); + for (const [key, resolvedAt] of this.recentlyResolved) { + if (now - resolvedAt > RECENTLY_RESOLVED_TTL_MS) this.recentlyResolved.delete(key); + } + while (this.recentlyResolved.size >= RECENTLY_RESOLVED_MAX) { + const oldest = this.recentlyResolved.keys().next().value; + if (oldest === undefined) break; + this.recentlyResolved.delete(oldest); + } + this.recentlyResolved.set(id, now); + } + + private generateId(): string { + return `interaction-${this.nextId++}`; + } +} + +function readPayloadToolCallId(payload: unknown): string | undefined { + if (typeof payload !== 'object' || payload === null) return undefined; + const value = (payload as Record)['toolCallId']; + return typeof value === 'string' ? value : undefined; +} + +registerScopedService( + LifecycleScope.Session, + ISessionInteractionService, + SessionInteractionService, + ScopeActivation.OnScopeCreated, + 'interaction', +); diff --git a/packages/agent-core-v2/src/session/mcp/ephemeralMcpServers.ts b/packages/agent-core-v2/src/session/mcp/ephemeralMcpServers.ts index ee18e5fb6..018adf7ac 100644 --- a/packages/agent-core-v2/src/session/mcp/ephemeralMcpServers.ts +++ b/packages/agent-core-v2/src/session/mcp/ephemeralMcpServers.ts @@ -1,3 +1,18 @@ +/** + * `mcp` domain — seeded ephemeral per-session MCP server configs. + * + * Defines `ISessionEphemeralMcpServers`, the pure-data injection contract + * carrying the session's ephemeral (caller-injected, never persisted) MCP + * server configs, copied verbatim from the session's creation options + * (`CreateSessionOptions.mcpServers` / `ResumeSessionOptions.mcpServers`). + * Always seeded into the Session scope by the session lifecycle (an empty + * record for ordinary sessions), so consumers can resolve it + * unconditionally. The contract carries no IO of its own — connecting the + * servers and projecting the resulting session handle is the + * Workspace-side MCP domain's concern, activated through the session + * lifecycle's `onWillCreateSession` event. Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { McpServerConfig } from '#/mcpCore/config-schema'; diff --git a/packages/agent-core-v2/src/session/mcp/mergedConnectionView.ts b/packages/agent-core-v2/src/session/mcp/mergedConnectionView.ts index 2affb4fc7..61d6cc3c9 100644 --- a/packages/agent-core-v2/src/session/mcp/mergedConnectionView.ts +++ b/packages/agent-core-v2/src/session/mcp/mergedConnectionView.ts @@ -1,3 +1,17 @@ +/** + * `mcp` domain — merged workspace + session MCP connection view. + * + * `MergedMcpConnectionView` presents one `McpConnectionView` over the + * workspace handler's shared manager (the base) and a session-owned overlay + * manager holding the session's ephemeral servers. The overlay owns the + * names it was created with: reads (`list` / `get` / `resolved` / + * `getRemoteServerUrl`) and mutations (`reconnect` / `reconnectAndJoin`) + * route overlay names to the overlay manager — an ephemeral server shadows a + * workspace server of the same name for this session — and base status + * events for shadowed names are filtered out so consumers see exactly one + * entry per name. Readiness and startup duration aggregate both managers. + */ + import type { McpConnectionManager, McpConnectionView, diff --git a/packages/agent-core-v2/src/session/mcp/sessionMcpHandle.ts b/packages/agent-core-v2/src/session/mcp/sessionMcpHandle.ts index 45b38b1de..308b539bb 100644 --- a/packages/agent-core-v2/src/session/mcp/sessionMcpHandle.ts +++ b/packages/agent-core-v2/src/session/mcp/sessionMcpHandle.ts @@ -1,3 +1,22 @@ +/** + * `mcp` domain — seeded MCP shared-handle contract. + * + * Defines `ISessionMcpHandle`, the pure-data injection contract carrying the + * session's MCP connection view plus the initial-connect readiness promise. + * The view is the workspace handler's shared `McpConnectionManager` for + * ordinary sessions, or a `MergedMcpConnectionView` over that manager and a + * session-owned overlay manager when the session was created with ephemeral + * MCP servers (`CreateSessionOptions.mcpServers`) — consumers never care + * which manager owns a server. `isBaselineServer` carries the session's + * server baseline: the names captured when the session materialized (open + * to additions until the initial connect settles, then closed). Servers + * that appear later — a plugin install or a config edit — are not part of + * the session, so live agents must not register their tools; a fresh + * baseline is captured on the next session materialization (`/new`, + * `/reload`, resume). The contract carries no IO of its own. + * Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { McpConnectionView } from '#/mcpCore/connection-manager'; diff --git a/packages/agent-core-v2/src/session/process/processRunner.ts b/packages/agent-core-v2/src/session/process/processRunner.ts new file mode 100644 index 000000000..de9466800 --- /dev/null +++ b/packages/agent-core-v2/src/session/process/processRunner.ts @@ -0,0 +1,38 @@ +/** + * `process` domain — the Agent's process runner. + * + * Defines the `ISessionProcessRunner` that business code injects to spawn processes + * inside the Agent's execution environment, plus the `IProcess` handle it + * returns. Session-scoped and defaults to the session's seeded `cwd` + * (`ISessionContext.cwd`); business code depends on `ISessionProcessRunner` + * only. + */ + +import type { Readable, Writable } from 'node:stream'; + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +export interface IProcess { + readonly stdin: Writable; + readonly stdout: Readable; + readonly stderr: Readable; + readonly pid: number; + readonly exitCode: number | null; + wait(): Promise; + kill(signal?: NodeJS.Signals): Promise; + dispose(): Promise | void; +} + +export interface ProcessExecOptions { + readonly cwd?: string; + readonly env?: Record; +} + +export interface ISessionProcessRunner { + readonly _serviceBrand: undefined; + + exec(args: readonly string[], options?: ProcessExecOptions): Promise; +} + +export const ISessionProcessRunner: ServiceIdentifier = + createDecorator('sessionProcessRunner'); diff --git a/packages/agent-core-v2/src/session/process/processRunnerService.ts b/packages/agent-core-v2/src/session/process/processRunnerService.ts new file mode 100644 index 000000000..b25160f66 --- /dev/null +++ b/packages/agent-core-v2/src/session/process/processRunnerService.ts @@ -0,0 +1,69 @@ +/** + * `process` domain — the default `ISessionProcessRunner` implementation. + * + * Resolves the default cwd from the session's `ISessionContext` and delegates + * the actual host spawn to the App-scope `IHostProcessService`. A per-call + * `options.cwd` wins over the seeded cwd. A per-call `options.env` is overlaid + * onto `process.env` and passed as the child's complete env bag (the host + * replaces the child env with what we pass); when `options.env` is omitted we + * pass `undefined` so the child inherits `process.env` verbatim. + * + * This Session-scope registration is the DEFAULT for scopes built without a + * workspace handler (test hosts, harness agents). Real sessions get the + * handler-shared Workspace-scope runner as a scope seed, which shadows this + * registration — same pattern as the other workspace-capability injection + * contracts. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { BugIndicatingError } from '#/errors'; +import { IHostProcessService } from '#/os/interface/hostProcess'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; + +import { type IProcess, ISessionProcessRunner, type ProcessExecOptions } from './processRunner'; + +export class SessionProcessRunner implements ISessionProcessRunner { + declare readonly _serviceBrand: undefined; + + constructor( + @ISessionContext private readonly ctx: ISessionContext, + @IHostProcessService private readonly hostProcess: IHostProcessService, + ) {} + + async exec(args: readonly string[], options?: ProcessExecOptions): Promise { + const command = args[0]; + if (command === undefined) { + throw new BugIndicatingError( + 'SessionProcessRunner.exec(): at least one argument (the command to run) is required.', + ); + } + const restArgs = args.slice(1); + + const cwd = options?.cwd ?? this.ctx.cwd; + const env = this._buildExecEnv(options?.env); + + return this.hostProcess.spawn(command, restArgs, { cwd, env }); + } + + private _buildExecEnv( + invocationEnv: Record | undefined, + ): Record | undefined { + if (invocationEnv === undefined) { + return undefined; + } + return { + ...(process.env as Record), + ...invocationEnv, + }; + } +} + +registerScopedService( + LifecycleScope.Session, + ISessionProcessRunner, + SessionProcessRunner, + ScopeActivation.OnScopeCreated, + 'process', +); diff --git a/packages/agent-core-v2/src/session/question/question.ts b/packages/agent-core-v2/src/session/question/question.ts index 349b13e89..2978d1755 100644 --- a/packages/agent-core-v2/src/session/question/question.ts +++ b/packages/agent-core-v2/src/session/question/question.ts @@ -1,3 +1,20 @@ +/** + * `question` domain — ask-user request broker. + * + * Defines the public contract of asking the user: the rich in-process + * `QuestionRequest` model (mirrors the `agent-core` SDK shape — a batch of + * `QuestionItem`s, each with its own options) and the `ISessionQuestionService` used + * to post a request, supply its answer, dismiss it, and list pending requests. + * + * The model is the **in-process** representation (camelCase, options carry no + * ids). The protocol wire shape (snake_case, synthesized item/option ids, + * 5-kind answer union) is produced at the edge. Session-scoped — one + * instance per session. + * `request` accepts the owning `agentId` so question events and transcript + * frames route to the asking agent's surfaces instead of falling back to + * 'main' (a subagent's question must not land there). + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface QuestionOption { diff --git a/packages/agent-core-v2/src/session/question/questionService.ts b/packages/agent-core-v2/src/session/question/questionService.ts index 771e00d7d..f9648b649 100644 --- a/packages/agent-core-v2/src/session/question/questionService.ts +++ b/packages/agent-core-v2/src/session/question/questionService.ts @@ -1,15 +1,14 @@ -import { randomUUID } from 'node:crypto'; +/** + * `question` domain — `ISessionQuestionService` implementation. + * + * Typed facade over the `interaction` kernel for ask-user requests; owns no + * pending state of its own (the kernel holds it). Bound at Session scope. + */ import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { - enqueueSessionInteraction, - listSessionPendingInteractions, - requestSessionInteraction, - respondSessionInteraction, -} from '#/features/interaction/sessionInteractions'; +import { ISessionInteractionService } from '#/session/interaction/interaction'; import { type QuestionRequest, @@ -20,11 +19,11 @@ import { export class SessionQuestionService implements ISessionQuestionService { declare readonly _serviceBrand: undefined; - constructor(@IAgentLifecycleService private readonly agents: IAgentLifecycleService) {} + constructor(@ISessionInteractionService private readonly interaction: ISessionInteractionService) {} request(req: QuestionRequest, options?: { signal?: AbortSignal; agentId?: string }): Promise { const id = requestId(req); - const pending = requestSessionInteraction(this.agents, { + const pending = this.interaction.request({ id, kind: 'question', payload: req, @@ -50,7 +49,7 @@ export class SessionQuestionService implements ISessionQuestionService { enqueue(req: QuestionRequest): QuestionRequest & { readonly id: string } { const id = requestId(req); - enqueueSessionInteraction(this.agents, { + this.interaction.enqueue({ id, kind: 'question', payload: req, @@ -60,21 +59,22 @@ export class SessionQuestionService implements ISessionQuestionService { } answer(id: string, result: QuestionResult): void { - respondSessionInteraction(this.agents, id, result); + this.interaction.respond(id, result); } dismiss(id: string): void { - respondSessionInteraction(this.agents, id, null); + this.interaction.respond(id, null); } listPending(): readonly QuestionRequest[] { - return listSessionPendingInteractions(this.agents, 'question') - .map((i) => ({ ...(i.payload as QuestionRequest), id: i.id })); + return this.interaction + .listPending('question') + .map((i) => i.payload as QuestionRequest); } } function requestId(req: QuestionRequest): string { - return req.id ?? `question_${randomUUID()}`; + return req.id ?? req.toolCallId ?? `question:${String(Date.now())}`; } registerScopedService(LifecycleScope.Session, ISessionQuestionService, SessionQuestionService, ScopeActivation.OnScopeCreated, 'question'); diff --git a/packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts b/packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts index 3b64a4e72..5dc1fe70d 100644 --- a/packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts +++ b/packages/agent-core-v2/src/session/sessionActivity/sessionActivity.ts @@ -1,3 +1,17 @@ +/** + * `sessionActivity` domain — the session's aggregated work projection. + * + * Defines `ISessionActivityView`: a Session-scoped, read-only, event-folded + * aggregate of "what this session is doing" — `busy` (any agent with an + * active turn or live background work), the main agent's turn activity and + * latest outcome, and the session's pending-interaction slice. The fold + * inputs are each agent's `activityView` projection (consumed through the + * agent event bus) and the session's `interaction` kernel; the view owns no + * authoritative state and can be discarded and rebuilt at any time. Change + * notifications carry the domain `cause` so consumers can schedule their own + * rendering around related facts. Bound at Session scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/session/sessionActivity/sessionActivityService.ts b/packages/agent-core-v2/src/session/sessionActivity/sessionActivityService.ts index 58f3adcb8..086d46038 100644 --- a/packages/agent-core-v2/src/session/sessionActivity/sessionActivityService.ts +++ b/packages/agent-core-v2/src/session/sessionActivity/sessionActivityService.ts @@ -1,3 +1,17 @@ +/** + * `sessionActivity` domain — `ISessionActivityView` implementation. + * + * Folds every agent's activity projection — borrowed through the agent + * handles from `agentLifecycle` (`IAgentActivityView.state()` seeded once at + * attach, `agent.activity.updated` over each agent's `event` bus afterwards) + * — together with the pending-interaction set from `interaction` into the + * session-level aggregate, and fires `onDidChange` with the domain cause + * only when the aggregate tuple actually changes. The plain-data state + * (`folds`, `current`) is registered into `sessionState` + * (`ISessionStateService`) and read/written through it. Bound at Session + * scope. + */ + import { Disposable, toDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { @@ -6,20 +20,12 @@ import { type IAgentScopeHandle, } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IEventBus } from '#/app/event/eventBus'; -import { - AgentActivityUpdated, - IAgentActivityView, - type AgentActivityState, -} from '#/agent/activityView/activityView'; +import { IAgentActivityView, type AgentActivityState } from '#/agent/activityView/activityView'; import type { TurnEndReason } from '#/agent/loop/turnEvents'; import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import type { Interaction } from '#/features/interaction/interaction'; -import { - listSessionPendingInteractions, - onSessionInteractionDidChangePending, -} from '#/features/interaction/sessionInteractions'; +import { ISessionInteractionService, type Interaction } from '#/session/interaction/interaction'; import { ISessionStateService } from '#/session/state/sessionState'; import { @@ -48,6 +54,7 @@ export const sessionActivityCurrentKey = defineState('sess lastTurnReason: undefined, })); +// NOTE: stays Disposable — its own 'state' collides with the Fiber export class SessionActivityView extends Disposable implements ISessionActivityView { declare readonly _serviceBrand: undefined; @@ -59,31 +66,27 @@ export class SessionActivityView extends Disposable implements ISessionActivityV constructor( @ISessionStateService private readonly states: ISessionStateService, @IAgentLifecycleService private readonly agents: IAgentLifecycleService, + @ISessionInteractionService private readonly interactions: ISessionInteractionService, ) { super(); - this.states.contributeState(sessionActivityFoldsKey); - this.states.contributeState(sessionActivityCurrentKey); - for (const agent of this.agents.list()) { - const handle = this.agents.handleOf(agent.agentId); - if (handle !== undefined) this.attachAgent(handle); - } + this.states.register(sessionActivityFoldsKey); + this.states.register(sessionActivityCurrentKey); + for (const handle of this.agents.list()) this.attachAgent(handle); this.current = this.aggregate(); this._register( - this.agents.onDidCreateScope(({ handle }) => { + this.agents.onDidCreate((handle) => { this.attachAgent(handle); this.recompute('agent_lifecycle'); }), ); this._register( - this.agents.onDidClose((agent) => { - this.agentSubscriptions.get(agent.agentId)?.dispose(); - this.agentSubscriptions.delete(agent.agentId); - if (this.folds.delete(agent.agentId)) this.recompute('agent_lifecycle'); + this.agents.onDidDispose((agentId) => { + this.agentSubscriptions.get(agentId)?.dispose(); + this.agentSubscriptions.delete(agentId); + if (this.folds.delete(agentId)) this.recompute('agent_lifecycle'); }), ); - this._register( - onSessionInteractionDidChangePending(this.agents, () => this.recompute('interaction')), - ); + this._register(this.interactions.onDidChangePending(() => this.recompute('interaction'))); this._register( toDisposable(() => { for (const subscription of this.agentSubscriptions.values()) subscription.dispose(); @@ -116,7 +119,7 @@ export class SessionActivityView extends Disposable implements ISessionActivityV if (bus === undefined) return; this.agentSubscriptions.set( handle.id, - bus.subscribe(AgentActivityUpdated, (event) => this.onActivity(handle.id, event)), + bus.subscribe('agent.activity.updated', (event) => this.onActivity(handle.id, event)), ); } @@ -156,7 +159,7 @@ export class SessionActivityView extends Disposable implements ISessionActivityV return { busy, mainTurnActive: this.folds.get(MAIN_AGENT_ID)?.turnActive ?? false, - pendingInteraction: resolvePendingInteraction(listSessionPendingInteractions(this.agents)), + pendingInteraction: resolvePendingInteraction(this.interactions.listPending()), lastTurnReason: this.folds.get(MAIN_AGENT_ID)?.lastTurnReason, }; } diff --git a/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirror.ts b/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirror.ts index 31fa6cae1..745c2b0eb 100644 --- a/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirror.ts +++ b/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirror.ts @@ -1,3 +1,14 @@ +/** + * `sessionActivity` domain — `ISessionOutcomeMirror` contract: persist the + * latest main-turn outcome into durable session metadata. + * + * The activity aggregate's `lastTurnReason` is live fold state, rebuilt per + * process; this mirror is the write side that lands terminal outcomes in + * the session's metadata document, so the session index (and therefore cold + * listings after a restart) keep reporting them. Session-scoped — one + * instance per session. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface ISessionOutcomeMirror { diff --git a/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirrorService.ts b/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirrorService.ts index 1ebd6a49c..475cdd9d0 100644 --- a/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirrorService.ts +++ b/packages/agent-core-v2/src/session/sessionActivity/sessionOutcomeMirrorService.ts @@ -1,10 +1,22 @@ +/** + * `sessionActivity` domain — `ISessionOutcomeMirror` implementation. + * + * Persists the main agent's terminal turn outcomes through `ISessionMetadata` + * (observed via `agentLifecycle` and the main agent's `eventBus`), so the + * session index keeps reporting them across restarts. Persisted on turn end + * (completed/failed, or a user's stop), cleared when a new turn starts, and + * backfilled from a cold resume's restored outcome — backfills never bump + * `updatedAt`, and programmatic aborts (including scope-teardown cancels) + * are deliberately never persisted live (a close-induced abort produces no + * write here), and backfills only apply to a pure resume (no turn started in + * this process — a live turn end owns its write, recency bump included). Writes are deduped against the last value this + * process persisted. Bound at Session scope. + */ + import { Disposable, DisposableStore } from '#/_base/di/lifecycle'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { LifecycleScope } from '#/app/scopes'; import { IEventBus } from '#/app/event/eventBus'; -import { AgentActivityUpdated } from '#/agent/activityView/activityView'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { TurnEnded } from '#/agent/loop/turnOps'; import { IAgentLifecycleService, MAIN_AGENT_ID, @@ -34,11 +46,11 @@ export class SessionOutcomeMirror extends Disposable implements ISessionOutcomeM }) .catch(() => {}); this.attachMain(); - this._register(this.agents.onDidCreate((agent) => { - if (agent.agentId === MAIN_AGENT_ID) this.attachMain(); + this._register(this.agents.onDidCreate((handle) => { + if (handle.id === MAIN_AGENT_ID) this.attachMain(); })); - this._register(this.agents.onDidClose((agent) => { - if (agent.agentId !== MAIN_AGENT_ID) return; + this._register(this.agents.onDidDispose((agentId) => { + if (agentId !== MAIN_AGENT_ID) return; this.mainSubscription?.dispose(); this.mainSubscription = undefined; })); @@ -52,38 +64,40 @@ export class SessionOutcomeMirror extends Disposable implements ISessionOutcomeM private attachMain(): void { if (this.mainSubscription !== undefined) return; - const bus = this.agents.handleOf(MAIN_AGENT_ID)?.accessor.get(IEventBus) as - | IEventBus - | undefined; + const bus = this.agents.get(MAIN_AGENT_ID)?.accessor.get(IEventBus) as IEventBus | undefined; if (bus === undefined) return; const subscription = new DisposableStore(); this.mainSubscription = subscription; subscription.add( - bus.subscribe(TurnEnded, (event) => { - if (event.reason === 'completed') { + bus.subscribe('turn.ended', (event) => { + if (event.type !== 'turn.ended') return; + const reason = (event as { reason?: unknown }).reason; + const interruptReason = (event as { interruptReason?: unknown }).interruptReason; + if (reason === 'completed') { this.write('completed'); return; } - if (event.reason === 'failed' || event.reason === 'blocked') { + if (reason === 'failed' || reason === 'blocked') { this.write('failed'); return; } - if (event.reason === 'cancelled' && event.interruptReason === 'user_cancelled') { + if (reason === 'cancelled' && interruptReason === 'user_cancelled') { this.write('cancelled'); } }), ); subscription.add( - bus.subscribe(TurnStarted, () => { + bus.subscribe('turn.started', () => { this.turnStartedHere = true; this.write(undefined); }), ); subscription.add( - bus.subscribe(AgentActivityUpdated, (event) => { + bus.subscribe('agent.activity.updated', (event) => { if (this.turnStartedHere) return; if (this.lastPersisted !== undefined) return; - const reason = event.lastTurn?.reason; + const lastTurn = (event as { lastTurn?: { reason?: unknown } }).lastTurn; + const reason = lastTurn?.reason; if (reason === 'completed' || reason === 'cancelled') { this.write(reason, { touchUpdatedAt: false }); } else if (reason === 'failed' || reason === 'blocked') { diff --git a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/agentProfileCatalogSeed.ts b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/agentProfileCatalogSeed.ts index 4f0e8e6b6..cb1b740f1 100644 --- a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/agentProfileCatalogSeed.ts +++ b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/agentProfileCatalogSeed.ts @@ -1,3 +1,13 @@ +/** + * `sessionAgentProfileCatalog` domain — seeded workspace-key contract. + * + * Defines `ISessionAgentProfileCatalogSeed`, the pure-data injection contract + * carrying ONLY the workspace handler's `workspaceId`. The key travels as a + * seed (rather than being recomputed from the session's workDir) because the + * handler's id may be folded from an alias spelling of the root. + * Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog.ts b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog.ts index b8e4d8be1..75b02b64e 100644 --- a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog.ts +++ b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog.ts @@ -1,3 +1,18 @@ +/** + * `sessionAgentProfileCatalog` domain — Session-scoped merged agent-profile + * catalog contract. + * + * The Catalog of the agent-profile extension point: a read-only projection + * over the App-scope `IAgentProfileRegistry`, scoped to THIS session — it + * merges the global contributions (builtin / plugin / user) with the ones the + * workspace loaders tagged with this session's seeded workspace key + * (workspace / extra / explicit). Name-level dedup happens HERE, in the + * projection: higher-priority sources win name collisions, while builtin + * names require an explicit `override: true` opt-in to be replaced. + * `inspect(name)` exposes the projection's adjudication (winning source, + * suppressed candidates) for debugging surfaces. Bound at Session scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; import type { AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; diff --git a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalogService.ts b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalogService.ts index 4e5a53a99..3b1ce50e6 100644 --- a/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalogService.ts +++ b/packages/agent-core-v2/src/session/sessionAgentProfileCatalog/sessionAgentProfileCatalogService.ts @@ -1,3 +1,22 @@ +/** + * `sessionAgentProfileCatalog` domain — `ISessionAgentProfileCatalog` + * implementation. + * + * Projects the App-scope `IAgentProfileRegistry` into this session's merged + * profile view. The relevant entries are the global ones (builtin) plus the + * ones tagged with the seeded workspace key (user / plugin / extra / + * workspace / explicit); they are re-merged on every registry change (the + * projection is a cheap full recompute — merge, never incremental patching). + * Merge rules, applied per profile name: candidates are collected from every + * relevant entry (deduped within an entry, highest priority first); the first + * candidate wins, except that replacing a same-name `builtin` profile + * requires `override: true` in the frontmatter — a non-override collision is + * warned about and skipped to the next candidate. `ready` resolves + * immediately: the registry is already populated when this service is + * constructed, and every later change arrives through `onDidChange`. Bound at + * Session scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { Emitter, type Event } from '#/_base/event'; import { LifecycleScope } from '#/app/scopes'; @@ -25,6 +44,7 @@ interface ProfileCandidate { readonly priority: number; } +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class SessionAgentProfileCatalogService extends Disposable implements ISessionAgentProfileCatalog @@ -151,15 +171,10 @@ export class SessionAgentProfileCatalogService }); continue; } - const replaced = merged.get(candidate.profile.name); - const effective = - candidate.profile.subagents === undefined && replaced?.subagents !== undefined - ? { ...candidate.profile, subagents: replaced.subagents } - : candidate.profile; - merged.set(candidate.profile.name, effective); + merged.set(candidate.profile.name, candidate.profile); inspections.set(candidate.profile.name, { name: candidate.profile.name, - profile: effective, + profile: candidate.profile, sourceId: candidate.sourceId, priority: candidate.priority, suppressed: [ diff --git a/packages/agent-core-v2/src/session/sessionContext/sessionContext.ts b/packages/agent-core-v2/src/session/sessionContext/sessionContext.ts index c79407d99..25e62f51e 100644 --- a/packages/agent-core-v2/src/session/sessionContext/sessionContext.ts +++ b/packages/agent-core-v2/src/session/sessionContext/sessionContext.ts @@ -1,12 +1,18 @@ +/** + * `sessionContext` domain — seeded per-session facts. + * + * Defines the `ISessionContext` carrying the session's identity, storage + * addressing (`sessionId`, `workspaceId`, `sessionDir`, `metaScope`), the + * session's working directory (`cwd`) — frozen at session creation — and a + * `scope(subKey?)` helper that returns the session's persistence scope (or a + * child under it, e.g. `scope('agents/main/cron')`). Seeded into the Session + * scope when the session is created. Pure facts — no store, no IO. + * Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; -export interface SessionWorkspaceAssociationSnapshot { - readonly sessionId: string; - readonly workspaceId: string; - readonly cwd: string; -} - export interface ISessionContext { readonly _serviceBrand: undefined; @@ -21,16 +27,6 @@ export interface ISessionContext { export const ISessionContext: ServiceIdentifier = createDecorator('sessionContext'); -export function snapshotSessionWorkspaceAssociation( - context: ISessionContext, -): SessionWorkspaceAssociationSnapshot { - return { - sessionId: context.sessionId, - workspaceId: context.workspaceId, - cwd: context.cwd, - }; -} - export function sessionContextSeed(ctx: ISessionContext): ScopeSeed { return [[ISessionContext as ServiceIdentifier, ctx]]; } diff --git a/packages/agent-core-v2/src/features/sessionInit/profile/init.md b/packages/agent-core-v2/src/session/sessionInit/profile/init.md similarity index 100% rename from packages/agent-core-v2/src/features/sessionInit/profile/init.md rename to packages/agent-core-v2/src/session/sessionInit/profile/init.md diff --git a/packages/agent-core-v2/src/features/sessionInit/profile/init.ts b/packages/agent-core-v2/src/session/sessionInit/profile/init.ts similarity index 53% rename from packages/agent-core-v2/src/features/sessionInit/profile/init.ts rename to packages/agent-core-v2/src/session/sessionInit/profile/init.ts index 08f605900..8b024b132 100644 --- a/packages/agent-core-v2/src/features/sessionInit/profile/init.ts +++ b/packages/agent-core-v2/src/session/sessionInit/profile/init.ts @@ -1,3 +1,13 @@ +/** + * `sessionInit` domain — `/init` brief and completion reminder. + * + * Verbatim brief handed to the `coder` subagent that generates `AGENTS.md` + * (`DEFAULT_INIT_PROMPT`), and the system reminder appended to the main agent + * once `/init` finishes (`initCompletionReminder`), which carries the freshly + * loaded AGENTS.md content back into the main conversation. Pure + * constants/functions — no scoped state. + */ + import initMd from './init.md?raw'; export const DEFAULT_INIT_PROMPT = initMd; diff --git a/packages/agent-core-v2/src/session/sessionInit/sessionInit.ts b/packages/agent-core-v2/src/session/sessionInit/sessionInit.ts new file mode 100644 index 000000000..aa8d26bf4 --- /dev/null +++ b/packages/agent-core-v2/src/session/sessionInit/sessionInit.ts @@ -0,0 +1,22 @@ +/** + * `sessionInit` domain — `/init` command contract. + * + * Drives the `/init` slash command: spawn a `coder` subagent that analyzes the + * codebase and writes `AGENTS.md`, then surface the freshly generated content + * back into the main agent as an `init`-variant system reminder. Bound at + * Session scope — the operation is one session-level action that reaches the + * session's main agent. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +export interface ISessionInitService { + readonly _serviceBrand: undefined; + + generateAgentsMd(): Promise; + + cancelInit(): void; +} + +export const ISessionInitService: ServiceIdentifier = + createDecorator('sessionInitService'); diff --git a/packages/agent-core-v2/src/features/sessionInit/sessionInitService.ts b/packages/agent-core-v2/src/session/sessionInit/sessionInitService.ts similarity index 65% rename from packages/agent-core-v2/src/features/sessionInit/sessionInitService.ts rename to packages/agent-core-v2/src/session/sessionInit/sessionInitService.ts index e714c64b2..613a1d847 100644 --- a/packages/agent-core-v2/src/features/sessionInit/sessionInitService.ts +++ b/packages/agent-core-v2/src/session/sessionInit/sessionInitService.ts @@ -1,3 +1,30 @@ +/** + * `sessionInit` domain — `ISessionInitService` implementation. + * + * Runs `/init` against the session's main agent: resolves `main` through + * `agentLifecycle`, spawns a `coder` subagent bound to the main agent's own + * model / thinking level (inheriting the main agent's permission mode), + * drives one init-brief turn via `subagents.run`, and mirrors the run onto the + * main agent's record stream so the UI shows the nested transcript and the + * `subagent.*` records fire. Once the + * subagent finishes, reloads `AGENTS.md` through the `profile` context helper + * (over the os `hostFs` + host home dir, with the `bootstrap` brand dir), + * re-seeds the main agent's `agentsMdReminder` known-set with the reloaded + * paths, and appends an `init`-variant system reminder to the main agent via + * `systemReminder`, then flushes the main agent's wire journal. Bound at + * Session scope. + * + * The main-agent lookup is a hard + * precondition (`AGENT_NOT_FOUND`); only the + * spawn / reload / reminder path is wrapped into `SESSION_INIT_FAILED`. + * `cancelInit` aborts the in-flight run through the same `AbortSignal` the + * run was launched with; user cancellations propagate unwrapped (never as + * `SESSION_INIT_FAILED`) so callers can tell "aborted" from "failed". + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { isAbortError, isUserCancellation, userCancellationReason } from '#/_base/utils/abort'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IHostEnvironment } from '#/os/interface/hostEnvironment'; @@ -6,9 +33,8 @@ import { IAgentProfileService } from '#/agent/profile/profile'; import { loadAgentsMdDetailed } from '#/agent/profile/context'; import { IAgentAgentsMdReminderService } from '#/agent/agentsMdReminder/agentsMdReminder'; import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; -import { agentContextOf } from '#/agent/scopeContext/scopeContext'; -import { AgentReminder } from '#/features/reminder/reminderAgentRuntime'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { IWireService } from '#/wire/wire'; import { ErrorCodes, Error2 } from '#/errors'; import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; @@ -28,7 +54,7 @@ export class SessionInitService implements ISessionInitService { private initRun: AbortController | undefined; constructor( - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentLifecycleService private readonly lifecycle: IAgentLifecycleService, @ISessionSubagentService private readonly subagents: ISessionSubagentService, @IHostFileSystem private readonly fs: IHostFileSystem, @IHostEnvironment private readonly env: IHostEnvironment, @@ -41,7 +67,7 @@ export class SessionInitService implements ISessionInitService { } async generateAgentsMd(): Promise { - const main = this.agentLifecycle.handleOf(MAIN_AGENT_ID); + const main = this.lifecycle.get(MAIN_AGENT_ID); if (main === undefined) { throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found'); } @@ -55,14 +81,13 @@ export class SessionInitService implements ISessionInitService { } const permissionMode = main.accessor.get(IAgentPermissionModeService).mode; - const childContext = await this.agentLifecycle.create({ + const child = await this.lifecycle.create({ binding: { profile: INIT_PROFILE_NAME, model: own.modelAlias, thinking: own.thinkingLevel, }, }); - const child = this.agentLifecycle.handleOf(childContext.agentId)!; child.accessor.get(IAgentPermissionModeService).setMode(permissionMode); emitAgentRunSpawned(main, child.id, { @@ -74,7 +99,7 @@ export class SessionInitService implements ISessionInitService { }); const run = await this.subagents.run( - agentContextOf(child), + child.id, { kind: 'prompt', prompt: DEFAULT_INIT_PROMPT }, { signal: controller.signal }, ); @@ -93,10 +118,13 @@ export class SessionInitService implements ISessionInitService { main.accessor .get(IAgentAgentsMdReminderService) .seedInjected(agentsMdPaths, this.sessionContext.cwd); - this.agentLifecycle - .resolve(agentContextOf(main), AgentReminder) - .notify(initCompletionReminder(agentsMd), { variant: 'init' }); - await main.accessor.get(IEventDispatcher).flush(); + main.accessor + .get(IAgentSystemReminderService) + .appendSystemReminder(initCompletionReminder(agentsMd), { + kind: 'injection', + variant: 'init', + }); + await main.accessor.get(IWireService).flush(); } catch (error) { if (isUserCancellation(error) || isAbortError(error)) { throw error; @@ -116,3 +144,11 @@ export class SessionInitService implements ISessionInitService { } } } + +registerScopedService( + LifecycleScope.Session, + ISessionInitService, + SessionInitService, + ScopeActivation.OnScopeCreated, + 'session-init', +); diff --git a/packages/agent-core-v2/src/session/sessionInstructions/instructionsProvider.ts b/packages/agent-core-v2/src/session/sessionInstructions/instructionsProvider.ts index fcc825c63..12aa9ff7a 100644 --- a/packages/agent-core-v2/src/session/sessionInstructions/instructionsProvider.ts +++ b/packages/agent-core-v2/src/session/sessionInstructions/instructionsProvider.ts @@ -1,7 +1,16 @@ +/** + * `sessionInstructions` domain — seeded AGENTS.md provider contract. + * + * Defines `ISessionInstructionsProvider`, the pure-data injection contract + * carrying the workspace's current AGENTS.md snapshot (combined content, the + * oversize/load warning, and the discovered-file list) and the change event + * fired when a watched instruction file invalidates the snapshot. The + * contract carries no IO. Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { Event } from '#/_base/event'; -import type { HostFsChange } from '#/os/interface/hostFsWatch'; export interface ISessionInstructionsProvider { readonly _serviceBrand: undefined; @@ -10,7 +19,7 @@ export interface ISessionInstructionsProvider { readonly agentsMd: string | undefined; readonly agentsMdWarning: string | undefined; readonly agentsMdPaths: readonly string[] | undefined; - readonly onDidChange: Event; + readonly onDidChange: Event; } export const ISessionInstructionsProvider: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/session/sessionLifecycleHooks/sessionLifecycleHooks.ts b/packages/agent-core-v2/src/session/sessionLifecycleHooks/sessionLifecycleHooks.ts new file mode 100644 index 000000000..dabb8a0cf --- /dev/null +++ b/packages/agent-core-v2/src/session/sessionLifecycleHooks/sessionLifecycleHooks.ts @@ -0,0 +1,36 @@ +/** + * `sessionLifecycleHooks` domain — per-session lifecycle hook slots. + * + * Defines the `ISessionLifecycleHooks` seed: one ordered hook-slots instance + * per session, with slots around the session's create (`onDidCreateSession`) + * and close (`onWillCloseSession`). Also owns the shared + * `SessionCreateSource` / `SessionCloseReason` vocabulary. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { ScopeSeed } from '#/_base/di/scope'; +import type { Hooks } from '#/hooks'; + +export type SessionCreateSource = 'startup' | 'resume' | 'fork'; + +export type SessionCloseReason = 'exit' | 'archive'; + +export interface SessionStartHookEvent { + readonly source: SessionCreateSource; +} + +export interface SessionEndHookEvent { + readonly reason: SessionCloseReason; +} + +export type SessionLifecycleHookSlots = { + readonly onDidCreateSession: SessionStartHookEvent; + readonly onWillCloseSession: SessionEndHookEvent; +}; + +export const ISessionLifecycleHooks: ServiceIdentifier> = + createDecorator>('sessionLifecycleHooks'); + +export function sessionLifecycleHooksSeed(hooks: Hooks): ScopeSeed { + return [[ISessionLifecycleHooks as ServiceIdentifier, hooks]]; +} diff --git a/packages/agent-core-v2/src/session/sessionLog/sessionLogService.ts b/packages/agent-core-v2/src/session/sessionLog/sessionLogService.ts index ca3d97eb6..479e498d4 100644 --- a/packages/agent-core-v2/src/session/sessionLog/sessionLogService.ts +++ b/packages/agent-core-v2/src/session/sessionLog/sessionLogService.ts @@ -1,21 +1,32 @@ +/** + * `sessionLog` domain — Session-scope `ILogService` implementation. + * + * Binds `sessionId` to every entry and writes to a rotating file under + * `/logs` (the `sessionId` key is omitted from each line since the + * path already identifies the session). Registered to the single `ILogService` + * token at Session scope. Flushes synchronously when the Session scope is + * disposed. The plain-data state (`rootLevel`) is registered into + * `sessionState` (`ISessionStateService`) and read/written through it. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionStateService } from '#/session/state/sessionState'; import { ILogService, type LogLevel } from '#/_base/log/log'; import { createFileLogWriter, type FileLogWriter } from '#/_base/log/fileLog'; import { ILogOptions, resolveSessionLogPath } from '#/_base/log/logConfig'; -import { BoundLogger, trackLogClose, type LogLevelState } from '#/_base/log/logService'; +import { BoundLogger, type LogLevelState } from '#/_base/log/logService'; export const sessionLogRootLevelKey = defineState('sessionLog.rootLevel', () => ({ level: 'info', })); function seedRootLevel(states: ISessionStateService, level: LogLevel): LogLevelState { - states.contributeState(sessionLogRootLevelKey); + states.register(sessionLogRootLevelKey); states.set(sessionLogRootLevelKey, { level }); return states.get(sessionLogRootLevelKey); } @@ -61,7 +72,7 @@ export class SessionLogService extends BoundLogger implements ILogService { override dispose(): void { this.sink.flushSync(); - trackLogClose(this.sink.close()); + void this.sink.close(); super.dispose(); } } diff --git a/packages/agent-core-v2/src/session/sessionMetadata/promptMetadata.ts b/packages/agent-core-v2/src/session/sessionMetadata/promptMetadata.ts deleted file mode 100644 index 88165c3fd..000000000 --- a/packages/agent-core-v2/src/session/sessionMetadata/promptMetadata.ts +++ /dev/null @@ -1,46 +0,0 @@ -import type { IEventService } from '#/app/event/event'; - -import { titleFromPromptMetadataText } from '#/agent/prompt/promptMetadataText'; - -import type { ISessionMetadata, SessionTitleKind } from './sessionMetadata'; -import { SessionMetaUpdated } from './sessionMetaEvents'; - -export function isUntitled(title: string | undefined): boolean { - return title === undefined || title.trim().length === 0 || title === 'New Session'; -} - -export interface PromptMetadataUpdateTarget { - readonly metadata: ISessionMetadata; - readonly eventService: IEventService; - readonly sessionId: string; -} - -export async function applyPromptMetadataUpdate( - target: PromptMetadataUpdateTarget, - text: string | undefined, -): Promise { - if (text === undefined) return; - const current = await target.metadata.read(); - const patch: { lastPrompt: string; title?: string; titleKind?: SessionTitleKind } = { - lastPrompt: text, - }; - if (current.titleKind !== 'custom' && isUntitled(current.title)) { - patch.title = titleFromPromptMetadataText(text); - patch.titleKind = 'replaceable'; - } - await target.metadata.update(patch); - target.eventService.publish( - new SessionMetaUpdated({ - payload: { - agentId: 'main', - sessionId: target.sessionId, - title: patch.title, - patch: { - title: patch.title, - isCustomTitle: patch.titleKind === undefined ? undefined : false, - lastPrompt: text, - }, - }, - }), - ); -} diff --git a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetaEvents.ts b/packages/agent-core-v2/src/session/sessionMetadata/sessionMetaEvents.ts deleted file mode 100644 index 1d8646634..000000000 --- a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetaEvents.ts +++ /dev/null @@ -1,20 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -export interface SessionMetaUpdatedPayload { - readonly agentId: string; - readonly sessionId: string; - readonly title?: string; - readonly patch: { - readonly title?: string; - readonly isCustomTitle?: boolean; - readonly lastPrompt?: string; - }; -} - -export class SessionMetaUpdated extends Event2<{ readonly payload: SessionMetaUpdatedPayload }> { - static override readonly type = 'session.meta.updated'; -} -export interface SessionMetaUpdated { - readonly payload: SessionMetaUpdatedPayload; -} diff --git a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadata.ts b/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadata.ts index ae9424594..11c75c7ff 100644 --- a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadata.ts +++ b/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadata.ts @@ -1,3 +1,15 @@ +/** + * `sessionMetadata` domain — typed session metadata. + * + * Defines the `SessionMeta` model and the `ISessionMetadata` used by upper + * layers to read and update the session's durable metadata (title, timestamps, + * archived flag, fork provenance, the latest main turn's terminal outcome). + * Owns the in-memory copy, persists it as a + * single atomic document through `storage`, and notifies changes via + * `onDidChangeMetadata`. Session-scoped — one instance per session. The initial + * document is materialized when the session is created. + */ + import type { Event } from '#/_base/event'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; @@ -12,18 +24,15 @@ export interface AgentMeta { export const SESSION_META_VERSION = 2; -export type SessionTitleKind = 'replaceable' | 'generated' | 'custom'; - export interface SessionMeta { readonly id: string; readonly version?: number; readonly title?: string; - readonly titleKind?: SessionTitleKind; + readonly isCustomTitle?: boolean; readonly lastPrompt?: string; readonly createdAt: number; readonly updatedAt: number; readonly archived: boolean; - readonly archivedAt?: number; readonly cwd?: string; readonly forkedFrom?: string; readonly agents?: Readonly>; @@ -45,10 +54,6 @@ export interface ISessionMetadata { read(): Promise; update(patch: SessionMetaPatch, opts?: { readonly touchUpdatedAt?: boolean }): Promise; setTitle(title: string): Promise; - setGeneratedTitleIfUncustomized( - title: string, - opts?: { force?: boolean }, - ): Promise; setArchived(archived: boolean): Promise; registerAgent(agentId: string, meta: AgentMeta): Promise; } diff --git a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadataService.ts b/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadataService.ts index e26aa4643..70505926e 100644 --- a/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadataService.ts +++ b/packages/agent-core-v2/src/session/sessionMetadata/sessionMetadataService.ts @@ -1,9 +1,43 @@ +/** + * `sessionMetadata` domain — `ISessionMetadata` implementation. + * + * Persists the session metadata document (`state.json`) through the `storage` + * access-pattern store (`IAtomicDocumentStore`), rooted at the `metaScope` + * namespace from `sessionContext`. Loads the existing document on + * construction (creating it on first run), and logs through `log`. The + * plain-data state (`data`) is registered into `sessionState` + * (`ISessionStateService`) and read/written through it. The + * document always carries the `agents` / `custom` maps — seeded at creation, + * backfilled and persisted on load for documents written before the seeding + * existed (without touching `updatedAt`, so a format heal never reorders + * session listings). Re-registering an agent whose metadata is unchanged is + * a no-op (no write, no mirror, no event), so resuming a session — which + * re-registers its agents as they materialize — never bumps `updatedAt` and + * never reorders session listings. Bound at Session scope. + * + * Read-model mirroring (flag `persistence_minidb_readmodel`): after a metadata + * update is persisted, the fresh summary is recorded into the App-scoped + * `ISessionIndexMirror` — a bounded, coalescing queue that flushes to the + * `IQueryStore` read model off the user completion path. The mutation + * completes with the authoritative `state.json` write; it never waits on the + * derived store (no mirror flush, no query-store lock), and a mirror failure + * is logged and swallowed — the read model heals by reconciliation, the + * session lifecycle never sees it. First-time creation in + * `load()` records too — a new session must appear in listings immediately + * (the mirror's pending queue feeds the index's read-your-writes merge); + * loading an *existing* document (session resume) stays silent. Queued writes + * are tracked in a module-level pending set, drained through + * `drainSessionMetadataWrites()` by hosts before the sessions root may be + * torn down (the query-store/mirror drain pattern); a patch still queued + * when the scope is disposed is dropped rather than written into a teardown. + */ + import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter, type Event } from '#/_base/event'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { ISessionIndexMirror } from '#/app/sessionIndex/sessionIndex'; import { buildSessionSummary } from '#/app/sessionIndex/sessionIndexSource'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; @@ -17,7 +51,6 @@ import { type SessionMeta, type SessionMetadataChangedEvent, type SessionMetaPatch, - type SessionTitleKind, } from './sessionMetadata'; const META_KEY = 'state.json'; @@ -59,7 +92,7 @@ export class SessionMetadata extends Service implements ISessionMetadata { this.disposed = true; }, }); - this.states.contributeState(sessionMetadataDataKey); + this.states.register(sessionMetadataDataKey); this.scope = ctx.metaScope; this.onDidChangeMetadata = this._onDidChangeMetadata.event; this.ready = this.load(); @@ -82,49 +115,31 @@ export class SessionMetadata extends Service implements ISessionMetadata { patch: SessionMetaPatch, opts?: { readonly touchUpdatedAt?: boolean }, ): Promise { - return this.enqueueUpdate(async () => { - await this.applyUpdate(patch, opts); - }); + return this.enqueueUpdate(() => this.applyUpdate(patch, opts)); } private async applyUpdate( patch: SessionMetaPatch, opts?: { readonly touchUpdatedAt?: boolean }, - ): Promise { + ): Promise { await this.ready; - if (this.disposed) return false; - const updatedAt = - patch.updatedAt ?? (opts?.touchUpdatedAt === false ? this.data.updatedAt : Date.now()); + if (this.disposed) return; + const updatedAt = opts?.touchUpdatedAt === false ? this.data.updatedAt : Date.now(); this.data = { ...this.data, ...patch, updatedAt }; - await this.store.set(this.scope, META_KEY, encodeSessionMeta(this.data)); - if (this.disposed) return false; + await this.store.set(this.scope, META_KEY, this.data); + if (this.disposed) return; this.mirrorToReadModel(); this._onDidChangeMetadata.fire({ changed: Object.keys(patch) as (keyof SessionMeta)[], }); - return true; } async setTitle(title: string): Promise { - await this.update({ title, titleKind: 'custom' }, { touchUpdatedAt: false }); - } - - async setGeneratedTitleIfUncustomized( - title: string, - opts?: { force?: boolean }, - ): Promise { - return this.enqueueUpdate(async () => { - await this.ready; - if (opts?.force !== true && this.data.titleKind === 'custom') return false; - return this.applyUpdate({ title, titleKind: 'generated' }, { touchUpdatedAt: false }); - }); + await this.update({ title, isCustomTitle: true }); } async setArchived(archived: boolean): Promise { - await this.update( - archived ? { archived: true, archivedAt: Date.now() } : { archived: false, archivedAt: undefined }, - { touchUpdatedAt: false }, - ); + await this.update({ archived }); } async registerAgent(agentId: string, meta: AgentMeta): Promise { @@ -133,16 +148,13 @@ export class SessionMetadata extends Service implements ISessionMetadata { const existing = this.data.agents?.[agentId]; if (existing !== undefined && agentMetaEquals(existing, meta)) return; const agents = { ...this.data.agents, [agentId]: meta }; - await this.applyUpdate({ agents }, { touchUpdatedAt: false }); + await this.applyUpdate({ agents }); }); } - private enqueueUpdate(work: () => Promise): Promise { + private enqueueUpdate(work: () => Promise): Promise { const run = this.updateQueue.then(work, work); - const tracked: Promise = run.then( - () => undefined, - () => undefined, - ); + const tracked = run.catch(() => {}); this.updateQueue = tracked; pendingWrites.add(tracked); void tracked.finally(() => pendingWrites.delete(tracked)); @@ -161,12 +173,14 @@ export class SessionMetadata extends Service implements ISessionMetadata { createdAt: this.data.createdAt, updatedAt: this.data.updatedAt, archived: this.data.archived === true, - archivedAt: this.data.archivedAt, custom: this.data.custom, lastTurnReason: this.data.lastTurnReason, }), ); } catch (error) { + // The authoritative document is already durable at this point; a mirror + // failure only degrades the read model (reconciliation heals it) and + // must never fail the session mutation itself. this.log.warn('session index mirror record failed; the read model heals by reconciliation', { sessionId: this.ctx.sessionId, error: error instanceof Error ? error.message : String(error), @@ -178,17 +192,13 @@ export class SessionMetadata extends Service implements ISessionMetadata { const existing = await this.store.get(this.scope, META_KEY); if (existing !== undefined) { this.data = normalizeSessionMeta(existing, this.ctx.sessionId); - if ( - this.data.agents === undefined || - this.data.custom === undefined || - sessionMetaTitleNeedsMigration(existing, this.data) - ) { + if (this.data.agents === undefined || this.data.custom === undefined) { this.data = { ...this.data, agents: this.data.agents ?? {}, custom: this.data.custom ?? {}, }; - await this.store.set(this.scope, META_KEY, encodeSessionMeta(this.data)); + await this.store.set(this.scope, META_KEY, this.data); } return; } @@ -203,7 +213,7 @@ export class SessionMetadata extends Service implements ISessionMetadata { agents: {}, custom: {}, }; - await this.store.set(this.scope, META_KEY, encodeSessionMeta(this.data)); + await this.store.set(this.scope, META_KEY, this.data); this.mirrorToReadModel(); this.log.debug('session metadata created', { sessionId: this.ctx.sessionId }); } @@ -229,84 +239,28 @@ function recordEquals(a: AgentMeta['labels'], b: AgentMeta['labels']): boolean { } export function normalizeSessionMeta(raw: SessionMeta, sessionId: string): SessionMeta { - const legacy = raw as unknown as LegacySessionMeta; - const normalizedTitle = normalizeSessionTitle(legacy); - const { - createdAt: legacyCreatedAt, - updatedAt: legacyUpdatedAt, - workDir: legacyWorkDir, - titleSource: _legacyTitleSource, - isCustomTitle: _legacyIsCustomTitle, - customTitle: _legacyCustomTitle, - ...clean - } = legacy; + const legacy = raw as unknown as { + createdAt?: unknown; + updatedAt?: unknown; + workDir?: unknown; + }; const cwd = - clean.cwd ?? (typeof legacyWorkDir === 'string' && legacyWorkDir.length > 0 - ? legacyWorkDir + raw.cwd ?? (typeof legacy.workDir === 'string' && legacy.workDir.length > 0 + ? legacy.workDir : undefined); - const { title, titleKind } = normalizedTitle; + if (raw.version === SESSION_META_VERSION) { + return cwd === raw.cwd ? raw : { ...raw, cwd }; + } return { - ...clean, - id: clean.version === SESSION_META_VERSION ? clean.id : sessionId, + ...raw, + id: sessionId, version: SESSION_META_VERSION, cwd, - title, - titleKind, - createdAt: toEpochMs(legacyCreatedAt), - updatedAt: toEpochMs(legacyUpdatedAt), - archived: clean.archived === true, + createdAt: toEpochMs(legacy.createdAt), + updatedAt: toEpochMs(legacy.updatedAt), }; } -type LegacySessionMeta = Omit & { - readonly createdAt?: unknown; - readonly updatedAt?: unknown; - readonly workDir?: unknown; - readonly titleSource?: unknown; - readonly isCustomTitle?: unknown; - readonly customTitle?: unknown; -}; - -function normalizeSessionTitle( - raw: LegacySessionMeta, -): Pick { - const title = typeof raw.title === 'string' ? raw.title : undefined; - if (title !== undefined && raw.isCustomTitle === true) { - return { title, titleKind: 'custom' }; - } - if (title !== undefined && isSessionTitleKind(raw.titleKind)) { - return { title, titleKind: raw.titleKind }; - } - if (title !== undefined && raw.isCustomTitle === false) { - return { title, titleKind: 'replaceable' }; - } - if (typeof raw.customTitle === 'string') { - return { title: raw.customTitle, titleKind: 'custom' }; - } - return title === undefined ? {} : { title, titleKind: 'replaceable' }; -} - -function isSessionTitleKind(value: unknown): value is SessionTitleKind { - return value === 'replaceable' || value === 'generated' || value === 'custom'; -} - -type PersistedSessionMeta = SessionMeta & { readonly isCustomTitle: boolean }; - -export function encodeSessionMeta(meta: SessionMeta): PersistedSessionMeta { - return { ...meta, isCustomTitle: meta.titleKind === 'custom' }; -} - -function sessionMetaTitleNeedsMigration(raw: SessionMeta, normalized: SessionMeta): boolean { - const record = raw as unknown as Record; - return ( - raw.title !== normalized.title || - raw.titleKind !== normalized.titleKind || - record['isCustomTitle'] !== (normalized.titleKind === 'custom') || - Object.hasOwn(record, 'titleSource') || - Object.hasOwn(record, 'customTitle') - ); -} - export function toEpochMs(value: unknown): number { if (typeof value === 'number' && Number.isFinite(value)) return value; if (typeof value === 'string') { diff --git a/packages/agent-core-v2/src/session/sessionSeed/sessionSeedAdapters.ts b/packages/agent-core-v2/src/session/sessionSeed/sessionSeedAdapters.ts new file mode 100644 index 000000000..bd1c7968d --- /dev/null +++ b/packages/agent-core-v2/src/session/sessionSeed/sessionSeedAdapters.ts @@ -0,0 +1,273 @@ +/** + * `sessionSeed` domain — the workspace → session seed adapter units. + * + * Each adapter projects one workspace-scoped resource service into its + * Session-scope pure-data injection contract (the seed tokens every session + * consumer resolves): the workspace's merged skill catalog, the AGENTS.md + * snapshot, the shared MCP connection handle, the additional-directory set, + * and the os-level tool veto. The projection object is built per upstream + * generation by the workspace service's own `sessionData()` / + * `sessionProvider()` / `sessionHandle()` / `sessionInfo()` / `sessionGate()` + * method; the adapter only owns the LIFETIME semantics the plain `extra` seed + * could not express: + * + * - live reads: the data object's getters delegate to the CURRENT backing + * projection, so an upstream rebuild (a new generation observed through + * `@ref`) never leaves consumers reading a stale closure; + * - change events: `onDidChange` is the adapter's own emitter — it forwards + * the backing projection's events and RE-FIRES when the backing view + * switches, telling consumers to re-pull; + * - hosts without a workspace layer (test hosts, harness agents): the + * observed upstream is absent and the adapter returns early, leaving the + * scope's default/extra registration (e.g. the Noop tool-policy gate) + * untouched. + * + * The units carry no DI token of their own: the session + * assembly point constructs them explicitly (`installSessionSeedAdapters`, + * the `configureContainer` hook of `createScopedChildHandle`) and anchors their + * disposal into the session container's ledger. Observation (`@ref`) is + * data-flow semantics — an upstream rebuild re-fires `onDidChange` instead + * of cascading this adapter down. A session created with ephemeral + * `mcpServers` (the `ISessionEphemeralMcpServers` seed) gets its + * `ISessionMcpHandle` from the `workspaceMcp` participant of the session + * lifecycle's `onWillCreateSession` event instead: its contribution lands + * after this adapter's provide and replaces the workspace projection. + */ + +import type { ServiceClassRecipe } from '#/_base/di/fiber'; +import { IInstantiationService, ref, type LiveRef } from '#/_base/di/instantiation'; +import type { InstantiationService } from '#/_base/di/instantiationService'; +import type { IDisposable } from '#/_base/di/lifecycle'; +import { Service } from '#/_base/di/service'; +import { Emitter } from '#/_base/event'; +import { ISessionMcpHandle } from '#/session/mcp/sessionMcpHandle'; +import { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; +import { ISessionSkillCatalogData } from '#/session/sessionSkillCatalog/skillCatalogData'; +import { ISessionToolPolicyGate } from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; +import { ISessionWorkspaceInfo } from '#/session/workspaceInfo/workspaceInfo'; +import { IWorkspaceDirs } from '#/workspace/workspaceDirs/workspaceDirs'; +import { IWorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructions'; +import { IWorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcp'; +import { IWorkspaceSkillCatalog } from '#/workspace/workspaceSkillCatalog/workspaceSkillCatalog'; +import { IWorkspaceToolPolicy } from '#/workspace/workspaceToolPolicy/workspaceToolPolicy'; + +export class SessionSkillCatalogDataAdapter extends Service { + constructor( + @IInstantiationService instantiation: IInstantiationService, + @ref(IWorkspaceSkillCatalog) upstream: LiveRef, + ) { + super(); + if (upstream.current === undefined) return; + const change = this._register(new Emitter()); + let backing = upstream.current.sessionData(); + let backingSubscription = backing.onDidChange((sourceId) => { + change.fire(sourceId); + }); + this._register({ + dispose: () => { + backingSubscription.dispose(); + }, + }); + this._register( + upstream.onDidChange(() => { + if (upstream.current !== undefined) { + backingSubscription.dispose(); + backing = upstream.current.sessionData(); + backingSubscription = backing.onDidChange((sourceId) => { + change.fire(sourceId); + }); + } + change.fire('catalog'); + }), + ); + const data: ISessionSkillCatalogData = { + _serviceBrand: undefined, + get ready() { + return backing.ready; + }, + get catalog() { + return backing.catalog; + }, + onDidChange: change.event, + }; + instantiation.provide(ISessionSkillCatalogData, data); + } +} + +export class SessionInstructionsProviderAdapter extends Service { + constructor( + @IInstantiationService instantiation: IInstantiationService, + @ref(IWorkspaceInstructionsService) upstream: LiveRef, + ) { + super(); + if (upstream.current === undefined) return; + const change = this._register(new Emitter()); + let backing = upstream.current.sessionProvider(); + let backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + this._register({ + dispose: () => { + backingSubscription.dispose(); + }, + }); + this._register( + upstream.onDidChange(() => { + if (upstream.current !== undefined) { + backingSubscription.dispose(); + backing = upstream.current.sessionProvider(); + backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + } + change.fire(); + }), + ); + const data: ISessionInstructionsProvider = { + _serviceBrand: undefined, + get ready() { + return backing.ready; + }, + get agentsMd() { + return backing.agentsMd; + }, + get agentsMdWarning() { + return backing.agentsMdWarning; + }, + get agentsMdPaths() { + return backing.agentsMdPaths; + }, + onDidChange: change.event, + }; + instantiation.provide(ISessionInstructionsProvider, data); + } +} + +export class SessionMcpHandleAdapter extends Service { + constructor( + @IInstantiationService instantiation: IInstantiationService, + @ref(IWorkspaceMcpService) upstream: LiveRef, + ) { + super(); + if (upstream.current === undefined) return; + let backing = upstream.current.sessionHandle(); + this._register( + upstream.onDidChange(() => { + if (upstream.current !== undefined) { + backing = upstream.current.sessionHandle(); + } + }), + ); + const handle: ISessionMcpHandle = { + _serviceBrand: undefined, + get ready() { + return backing.ready; + }, + get connectionManager() { + return backing.connectionManager; + }, + isBaselineServer: (name) => backing.isBaselineServer(name), + }; + instantiation.provide(ISessionMcpHandle, handle); + } +} + +export class SessionWorkspaceInfoAdapter extends Service { + constructor( + @IInstantiationService instantiation: IInstantiationService, + @ref(IWorkspaceDirs) upstream: LiveRef, + ) { + super(); + if (upstream.current === undefined) return; + const change = this._register(new Emitter()); + let backing = upstream.current.sessionInfo(); + let backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + this._register({ + dispose: () => { + backingSubscription.dispose(); + }, + }); + this._register( + upstream.onDidChange(() => { + if (upstream.current !== undefined) { + backingSubscription.dispose(); + backing = upstream.current.sessionInfo(); + backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + } + change.fire(); + }), + ); + const info: ISessionWorkspaceInfo = { + _serviceBrand: undefined, + get ready() { + return backing.ready; + }, + get additionalDirs() { + return backing.additionalDirs; + }, + onDidChange: change.event, + }; + instantiation.provide(ISessionWorkspaceInfo, info); + } +} + +export class SessionToolPolicyGateAdapter extends Service { + constructor( + @IInstantiationService instantiation: IInstantiationService, + @ref(IWorkspaceToolPolicy) upstream: LiveRef, + ) { + super(); + if (upstream.current === undefined) return; + const change = this._register(new Emitter()); + let backing = upstream.current.sessionGate(); + let backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + this._register({ + dispose: () => { + backingSubscription.dispose(); + }, + }); + this._register( + upstream.onDidChange(() => { + if (upstream.current !== undefined) { + backingSubscription.dispose(); + backing = upstream.current.sessionGate(); + backingSubscription = backing.onDidChange(() => { + change.fire(); + }); + } + change.fire(); + }), + ); + const gate: ISessionToolPolicyGate = { + _serviceBrand: undefined, + get disabledTools() { + return backing.disabledTools; + }, + onDidChange: change.event, + }; + instantiation.provide(ISessionToolPolicyGate, gate); + } +} + +const SESSION_SEED_ADAPTERS: readonly ServiceClassRecipe[] = [ + SessionSkillCatalogDataAdapter, + SessionInstructionsProviderAdapter, + SessionMcpHandleAdapter, + SessionWorkspaceInfoAdapter, + SessionToolPolicyGateAdapter, +]; + +export function installSessionSeedAdapters(container: InstantiationService): void { + for (const recipe of SESSION_SEED_ADAPTERS) { + const adapter = container.fiberHost.constructService(recipe, undefined) as Partial; + container.anchorKernelEntry(() => { + adapter.dispose?.(); + }, `sessionSeed:${recipe.name}`); + } +} diff --git a/packages/agent-core-v2/src/features/skill/session/skillCatalog.ts b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalog.ts similarity index 51% rename from packages/agent-core-v2/src/features/skill/session/skillCatalog.ts rename to packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalog.ts index 9df82ec01..ce03e16fd 100644 --- a/packages/agent-core-v2/src/features/skill/session/skillCatalog.ts +++ b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalog.ts @@ -1,8 +1,15 @@ +/** + * `sessionSkillCatalog` domain — Session-scoped skill catalog contract. + * + * Defines the merged session read view, source-specific change events, and the + * sink used by ad-hoc skill contributors. Bound at Session scope. + */ + import { createDecorator } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; -import type { SkillContribution } from '#/features/skill/catalog/skillSource'; -import type { SkillCatalog, SkillSummary } from '#/features/skill/catalog/types'; +import type { SkillContribution } from '#/app/skillCatalog/skillSource'; +import type { SkillCatalog, SkillSummary } from '#/app/skillCatalog/types'; export interface ISessionSkillCatalog { readonly _serviceBrand: undefined; @@ -12,6 +19,12 @@ export interface ISessionSkillCatalog { readonly onDidChange: Event; load(): Promise; reload(): Promise; + /** + * Wire-friendly snapshot of the merged catalog: every skill as a + * `SkillSummary`, resolved after `ready`. Unlike the `catalog` property + * (a live object whose methods do not cross a wire), the result is plain + * serializable data. + */ list(): Promise; } diff --git a/packages/agent-core-v2/src/features/skill/session/skillCatalogData.ts b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogData.ts similarity index 65% rename from packages/agent-core-v2/src/features/skill/session/skillCatalogData.ts rename to packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogData.ts index 5bf227f04..89190aed9 100644 --- a/packages/agent-core-v2/src/features/skill/session/skillCatalogData.ts +++ b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogData.ts @@ -1,8 +1,16 @@ +/** + * `sessionSkillCatalog` domain — seeded skill-catalog data contract. + * + * Defines `ISessionSkillCatalogData`, the pure-data injection contract + * carrying the workspace's merged skill catalog as a live read view plus the + * source-keyed change event. The contract carries no IO. Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { Event } from '#/_base/event'; -import type { SkillCatalog } from '#/features/skill/catalog/types'; +import type { SkillCatalog } from '#/app/skillCatalog/types'; export interface ISessionSkillCatalogData { readonly _serviceBrand: undefined; diff --git a/packages/agent-core-v2/src/features/skill/session/skillCatalogService.ts b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogService.ts similarity index 76% rename from packages/agent-core-v2/src/features/skill/session/skillCatalogService.ts rename to packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogService.ts index 07a7c50f2..18892e8d4 100644 --- a/packages/agent-core-v2/src/features/skill/session/skillCatalogService.ts +++ b/packages/agent-core-v2/src/session/sessionSkillCatalog/skillCatalogService.ts @@ -1,11 +1,27 @@ +/** + * `sessionSkillCatalog` domain — `ISessionSkillCatalog` sink + * implementation. + * + * The Session-scope business view over the workspace's merged skill catalog: + * the data arrives through the seeded `ISessionSkillCatalogData` read view — + * this service never scans the filesystem itself. It re-folds the data + * snapshot on every seeded change + * event (forwarding the source id) and merges session-local ad-hoc + * contributions (`ISkillCatalogSink`) on top by priority. `reload()` no + * longer re-scans: it re-folds the current seed and re-fires `catalog`. + * The plain-data state (`contributions`, `merged`) is registered into + * `sessionState` (`ISessionStateService`) and read/written through it. + * Bound at Session scope. + */ + import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; -import { InMemorySkillCatalog } from '#/features/skill/catalog/registry'; -import type { SkillContribution } from '#/features/skill/catalog/skillSource'; -import { summarizeSkill, type SkillCatalog, type SkillSummary } from '#/features/skill/catalog/types'; +import { defineState } from '#/_base/state/stateRegistry'; +import { InMemorySkillCatalog } from '#/app/skillCatalog/registry'; +import type { SkillContribution } from '#/app/skillCatalog/skillSource'; +import { summarizeSkill, type SkillCatalog, type SkillSummary } from '#/app/skillCatalog/types'; import { ISessionStateService } from '#/session/state/sessionState'; import { ISessionSkillCatalog, type ISkillCatalogSink } from './skillCatalog'; @@ -34,8 +50,8 @@ export class SessionSkillCatalogService @ISessionStateService private readonly states: ISessionStateService, ) { super(); - this.states.contributeState(skillCatalogContributionsKey); - this.states.contributeState(skillCatalogMergedKey); + this.states.register(skillCatalogContributionsKey); + this.states.register(skillCatalogMergedKey); this._register( this.data.onDidChange((sourceId) => { this.remerge(); diff --git a/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSource.ts b/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSource.ts deleted file mode 100644 index 540d89b71..000000000 --- a/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSource.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface TitleTurnExcerpt { - readonly user?: string | undefined; - readonly assistant?: string | undefined; -} - -export interface TitleDigestTurn { - readonly user: string; - readonly assistant?: string; -} - -export interface TitleDigestExcerpt { - readonly turns: readonly TitleDigestTurn[]; -} - -export interface IAgentTitlePromptSource { - readonly _serviceBrand: undefined; - - firstUserPrompts(limit: number): Promise; - - firstTurnExcerpt(): Promise; - - digestExcerpt(): Promise; -} - -export const IAgentTitlePromptSource: ServiceIdentifier = - createDecorator('agentTitlePromptSource'); diff --git a/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSourceService.ts b/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSourceService.ts deleted file mode 100644 index 2abd88f4c..000000000 --- a/packages/agent-core-v2/src/session/sessionTitle/agentTitlePromptSourceService.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import { IAgentPromptService } from '#/agent/prompt/prompt'; -import { - promptMetadataTextFromContentParts, - promptMetadataTextFromText, -} from '#/agent/prompt/promptMetadataText'; -import type { ContentPart } from '#/kosong/contract/message'; - -import { - IAgentTitlePromptSource, - type TitleDigestExcerpt, - type TitleDigestTurn, - type TitleTurnExcerpt, -} from './agentTitlePromptSource'; - -export class AgentTitlePromptSourceService implements IAgentTitlePromptSource { - declare readonly _serviceBrand: undefined; - - constructor( - @IAgentContextMemoryService private readonly context: IAgentContextMemoryService, - @IAgentPromptService private readonly prompt: IAgentPromptService, - ) {} - - async firstUserPrompts(limit: number): Promise { - if (!Number.isSafeInteger(limit) || limit <= 0) return []; - - const result: string[] = []; - const seenMessageIds = new Set(); - - const add = (message: ContextMessage): void => { - if (result.length >= limit || !isNaturalLanguagePrompt(message)) return; - if (message.id !== undefined) { - if (seenMessageIds.has(message.id)) return; - seenMessageIds.add(message.id); - } - const text = promptMetadataTextFromUserMessage(message); - if (text !== undefined) result.push(text); - }; - - for (const message of this.combinedMessages()) add(message); - return result; - } - - async firstTurnExcerpt(): Promise { - const all = this.combinedMessages(); - const firstUserIndex = all.findIndex(isNaturalLanguagePrompt); - if (firstUserIndex < 0) return {}; - const user = promptMetadataTextFromUserMessage(all[firstUserIndex]!); - const span: ContextMessage[] = []; - for (const message of all.slice(firstUserIndex + 1)) { - if (isNaturalLanguagePrompt(message)) break; - span.push(message); - } - return { user, assistant: finalAssistantText(span) }; - } - - async digestExcerpt(): Promise { - const all = this.combinedMessages(); - const seenMessageIds = new Set(); - const userIndexes: number[] = []; - for (let index = 0; index < all.length; index++) { - const message = all[index]!; - if (!isNaturalLanguagePrompt(message)) continue; - if (message.id !== undefined) { - if (seenMessageIds.has(message.id)) continue; - seenMessageIds.add(message.id); - } - userIndexes.push(index); - } - const turns: TitleDigestTurn[] = []; - for (let i = 0; i < userIndexes.length; i++) { - const userIndex = userIndexes[i]!; - const user = promptMetadataTextFromUserMessage(all[userIndex]!); - if (user === undefined) continue; - const spanEnd = i + 1 < userIndexes.length ? userIndexes[i + 1]! : all.length; - const assistant = finalAssistantText(all.slice(userIndex + 1, spanEnd)); - turns.push({ user, assistant }); - } - return { turns }; - } - - private combinedMessages(): ContextMessage[] { - const queue = this.prompt.list(); - const all = [...this.context.get()]; - if (queue.active !== undefined) all.push(queue.active.message); - for (const item of queue.pending) all.push(item.message); - return all; - } -} - -function isNaturalLanguagePrompt(message: ContextMessage): boolean { - if (message.role !== 'user') return false; - const origin = message.origin; - return origin === undefined || origin.kind === 'user'; -} - -function promptMetadataTextFromUserMessage(message: ContextMessage): string | undefined { - const bundled = message.origin?.kind === 'user' ? (message.origin.skillActivations?.length ?? 0) : 0; - return promptMetadataTextFromContentParts( - bundled === 0 ? message.content : message.content.slice(bundled), - ); -} - -function finalAssistantText(messages: readonly ContextMessage[]): string | undefined { - for (let index = messages.length - 1; index >= 0; index--) { - const message = messages[index]!; - if (message.role !== 'assistant') continue; - const text = assistantTextFromContentParts(message.content); - if (text !== undefined) return text; - } - return undefined; -} - -function assistantTextFromContentParts(parts: readonly ContentPart[]): string | undefined { - const texts: string[] = []; - for (const part of parts) { - if (part.type === 'text' && part.text.trim().length > 0) texts.push(part.text); - } - if (texts.length === 0) return undefined; - return promptMetadataTextFromText(texts.join('\n')); -} - -registerScopedService( - LifecycleScope.Agent, - IAgentTitlePromptSource, - AgentTitlePromptSourceService, - ScopeActivation.OnDemand, - 'sessionTitle', -); diff --git a/packages/agent-core-v2/src/session/sessionTitle/flag.ts b/packages/agent-core-v2/src/session/sessionTitle/flag.ts deleted file mode 100644 index 54f49d5a6..000000000 --- a/packages/agent-core-v2/src/session/sessionTitle/flag.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; - -export const AUTO_SESSION_TITLE_FLAG_ID = 'auto_session_title'; -export const AUTO_SESSION_TITLE_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_AUTO_SESSION_TITLE'; - -export const sessionTitleFlag: FlagDefinitionInput = { - id: AUTO_SESSION_TITLE_FLAG_ID, - title: 'AI session titles', - description: - 'Generate concise session titles from the conversation through the managed chat_title tool: clients auto-generate once the first turn completes and offer on-demand regeneration in the rename field.', - env: AUTO_SESSION_TITLE_FLAG_ENV, - default: false, - surface: 'core', -}; - -registerFlagDefinition(sessionTitleFlag); diff --git a/packages/agent-core-v2/src/session/sessionTitle/sessionTitle.ts b/packages/agent-core-v2/src/session/sessionTitle/sessionTitle.ts deleted file mode 100644 index 9281487b1..000000000 --- a/packages/agent-core-v2/src/session/sessionTitle/sessionTitle.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export type SessionTitleSource = 'user_prompts' | 'first_turn' | 'digest'; - -export interface ISessionTitleService { - readonly _serviceBrand: undefined; - - generateTitle(opts?: { - force?: boolean; - source?: SessionTitleSource; - }): Promise; -} - -export const ISessionTitleService: ServiceIdentifier = - createDecorator('sessionTitleService'); diff --git a/packages/agent-core-v2/src/session/sessionTitle/sessionTitleService.ts b/packages/agent-core-v2/src/session/sessionTitle/sessionTitleService.ts deleted file mode 100644 index 3f195e738..000000000 --- a/packages/agent-core-v2/src/session/sessionTitle/sessionTitleService.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { - KIMI_CODE_PROVIDER_NAME, - OAuthError, - fetchChatTitle, - kimiCodeToolsUrl, - parseKimiCodeCustomHeaders, - resolveKimiCodeRuntimeAuth, -} from '@moonshot-ai/kimi-code-oauth'; - -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { LifecycleScope } from '#/app/scopes'; -import { IFlagService } from '#/app/flag/flag'; -import { ILogService } from '#/_base/log/log'; -import { IOAuthService } from '#/app/auth/auth'; -import { IEventService } from '#/app/event/event'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { IHostRequestHeaders } from '#/kosong/model/hostRequestHeaders'; -import { IProviderService } from '#/kosong/provider/provider'; -import { isOAuthCatalogVendor } from '#/kosong/provider/providerDefinition'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionMetadata } from '#/session/sessionMetadata/sessionMetadata'; -import { SessionMetaUpdated } from '#/session/sessionMetadata/sessionMetaEvents'; - -import { IAgentTitlePromptSource } from './agentTitlePromptSource'; -import { AUTO_SESSION_TITLE_FLAG_ID } from './flag'; -import { ISessionTitleService, type SessionTitleSource } from './sessionTitle'; - -const MAX_GENERATED_TITLE_LENGTH = 200; - -const MAX_TITLE_INPUT_LENGTH = 1000; - -const MAX_TITLE_PROMPTS = 3; - -const MAX_TITLE_USER_SEGMENT = 400; - -const MAX_TITLE_FIRST_TURN_ASSISTANT = 300; - -const MAX_TITLE_DIGEST_USER_SEGMENT = 200; - -const MAX_TITLE_DIGEST_ASSISTANT = 200; - -const MAX_TITLE_DIGEST_INPUT_LENGTH = 3000; - -export class SessionTitleService implements ISessionTitleService { - declare readonly _serviceBrand: undefined; - - private _shared: Promise | undefined; - - constructor( - @ISessionContext private readonly ctx: ISessionContext, - @ISessionMetadata private readonly metadata: ISessionMetadata, - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, - @IEventService private readonly eventService: IEventService, - @IProviderService private readonly providers: IProviderService, - @IOAuthService private readonly oauth: IOAuthService, - @IHostRequestHeaders private readonly hostHeaders: IHostRequestHeaders, - @IFlagService private readonly flags: IFlagService, - @ILogService private readonly log: ILogService, - ) {} - - async generateTitle(opts?: { - force?: boolean; - source?: SessionTitleSource; - }): Promise { - const force = opts?.force === true; - const source = opts?.source ?? 'user_prompts'; - if (force) return this.generateTitleOnce(true, source); - if (this._shared !== undefined) return this._shared; - const tracked = this.generateTitleOnce(false, source).finally(() => { - if (this._shared === tracked) this._shared = undefined; - }); - this._shared = tracked; - return tracked; - } - - private async generateTitleOnce( - force: boolean, - source: SessionTitleSource, - ): Promise { - if (!this.flags.enabled(AUTO_SESSION_TITLE_FLAG_ID)) return undefined; - const current = await this.metadata.read(); - if (!force) { - if (current.titleKind === 'custom') return undefined; - if (current.titleKind === 'generated') return undefined; - } - const main = this.agentLifecycle.handleOf(MAIN_AGENT_ID); - if (main === undefined) return undefined; - const promptSource = main.accessor.get(IAgentTitlePromptSource); - const input = await composeTitleInput(promptSource, source); - if (input === undefined) return undefined; - return this.generateAndApply(input, force); - } - - private async generateAndApply( - chatContent: string, - force: boolean, - ): Promise { - const current = await this.metadata.read(); - if (!force && current.titleKind === 'custom') return undefined; - const provider = this.providers.get(KIMI_CODE_PROVIDER_NAME); - if ( - provider === undefined || - !isOAuthCatalogVendor(provider.type) || - provider.oauth === undefined - ) { - return undefined; - } - const runtimeAuth = resolveKimiCodeRuntimeAuth({ - configuredBaseUrl: provider.baseUrl, - configuredOAuthRef: provider.oauth, - }); - const tokenProvider = this.oauth.resolveTokenProvider( - KIMI_CODE_PROVIDER_NAME, - runtimeAuth.oauthRef, - ); - if (tokenProvider === undefined) return undefined; - let token: string; - try { - token = await tokenProvider.getAccessToken(); - } catch (error) { - if (!(error instanceof OAuthError)) throw error; - this.log.debug(`chat_title request unavailable: ${error.message}`); - return undefined; - } - const requestTitle = (accessToken: string) => - fetchChatTitle(kimiCodeToolsUrl(runtimeAuth.baseUrl), accessToken, chatContent, { - headers: { - ...parseKimiCodeCustomHeaders(), - ...this.hostHeaders.headers, - ...provider.customHeaders, - }, - }); - let result = await requestTitle(token); - if (result.kind === 'error' && result.status === 401) { - try { - token = await tokenProvider.getAccessToken({ force: true }); - } catch (error) { - if (!(error instanceof OAuthError)) throw error; - this.log.debug(`chat_title request unavailable: ${error.message}`); - return undefined; - } - result = await requestTitle(token); - } - if (result.kind !== 'ok') { - this.log.debug(`chat_title request failed: ${result.message}`); - return undefined; - } - const title = result.title.slice(0, MAX_GENERATED_TITLE_LENGTH); - const applied = await this.metadata.setGeneratedTitleIfUncustomized(title, { force }); - if (!applied) return undefined; - this.eventService.publish( - new SessionMetaUpdated({ - payload: { - agentId: 'main', - sessionId: this.ctx.sessionId, - title, - patch: { title, isCustomTitle: false }, - }, - }), - ); - return title; - } -} - -function titleInputFromPrompts(prompts: readonly string[]): string | undefined { - if (prompts.length === 0) return undefined; - return prompts - .map((prompt) => `user: ${prompt.slice(0, MAX_TITLE_USER_SEGMENT)}`) - .join('\n') - .slice(0, MAX_TITLE_INPUT_LENGTH); -} - -async function composeTitleInput( - promptSource: IAgentTitlePromptSource, - source: SessionTitleSource, -): Promise { - if (source === 'first_turn') { - const excerpt = await promptSource.firstTurnExcerpt(); - if (excerpt.user === undefined || excerpt.assistant === undefined) return undefined; - return [ - `user: ${excerpt.user.slice(0, MAX_TITLE_USER_SEGMENT)}`, - `assistant: ${excerpt.assistant.slice(0, MAX_TITLE_FIRST_TURN_ASSISTANT)}`, - ].join('\n'); - } - if (source === 'digest') { - const excerpt = await promptSource.digestExcerpt(); - const turns: string[][] = []; - for (const turn of excerpt.turns) { - const group = [`user: ${turn.user.slice(0, MAX_TITLE_DIGEST_USER_SEGMENT)}`]; - if (turn.assistant !== undefined) { - group.push(`assistant: ${turn.assistant.slice(0, MAX_TITLE_DIGEST_ASSISTANT)}`); - } - turns.push(group); - } - return elideTitleDigestTurns(turns); - } - return titleInputFromPrompts(await promptSource.firstUserPrompts(MAX_TITLE_PROMPTS)); -} - -const TITLE_DIGEST_ELISION_MARKER = '...'; - -function elideTitleDigestTurns(turns: readonly (readonly string[])[]): string | undefined { - if (turns.length === 0) return undefined; - const joined = turns.flat().join('\n'); - if (joined.length <= MAX_TITLE_DIGEST_INPUT_LENGTH) return joined; - let budget = MAX_TITLE_DIGEST_INPUT_LENGTH - TITLE_DIGEST_ELISION_MARKER.length - 2; - const head: string[] = []; - for (const line of turns[0]!) { - if (budget < line.length + 1) break; - head.push(line); - budget -= line.length + 1; - } - const tail: string[] = []; - for (let index = turns.length - 1; index >= 1; index--) { - const group = turns[index]!; - const cost = group.reduce((sum, line) => sum + line.length + 1, 0); - if (budget < cost) break; - tail.unshift(...group); - budget -= cost; - } - return [...head, TITLE_DIGEST_ELISION_MARKER, ...tail].join('\n'); -} - -registerScopedService( - LifecycleScope.Session, - ISessionTitleService, - SessionTitleService, - ScopeActivation.OnScopeCreated, - 'sessionTitle', -); diff --git a/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicy.ts b/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicy.ts index 4cc649d77..9d591c1c6 100644 --- a/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicy.ts +++ b/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicy.ts @@ -1,3 +1,13 @@ +/** + * `sessionToolPolicy` domain — session-wide client tool restrictions. + * + * Defines the Session-scoped policy shared by every Agent in a session. The + * client-managed denylist is persisted independently from each Agent's frozen + * profile policy, survives resume, and emits an awaitable change event so + * existing agents can refresh policy-derived system-prompt content before the + * mutating request continues. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event, IWaitUntil } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicyService.ts b/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicyService.ts index 12a1fbcfc..6b17a4fe4 100644 --- a/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicyService.ts +++ b/packages/agent-core-v2/src/session/sessionToolPolicy/sessionToolPolicyService.ts @@ -1,8 +1,18 @@ +/** + * `sessionToolPolicy` domain — persisted session tool-policy service. + * + * Stores the client-managed denylist as one atomic document below the session + * scope and serializes replacements. A successful replacement awaits all + * registered Agent prompt refreshes before returning. The plain-data state + * (`state`) is registered into `sessionState` (`ISessionStateService`) and + * read/written through it. Bound at Session scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { AsyncEmitter, type Event } from '#/_base/event'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionStateService } from '#/session/state/sessionState'; @@ -22,6 +32,7 @@ export const sessionToolPolicyStateKey = defineState('se const STATE_KEY = 'state.json'; +// NOTE: stays Disposable — its own 'state' collides with the Fiber export class SessionToolPolicyService extends Disposable implements ISessionToolPolicy { declare readonly _serviceBrand: undefined; readonly ready: Promise; @@ -39,7 +50,7 @@ export class SessionToolPolicyService extends Disposable implements ISessionTool @IAtomicDocumentStore private readonly store: IAtomicDocumentStore, ) { super(); - this.states.contributeState(sessionToolPolicyStateKey); + this.states.register(sessionToolPolicyStateKey); this.scope = sessionContext.scope('tool-policy'); this.onDidChange = this.changeEmitter.event; this.ready = this.load(); diff --git a/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGate.ts b/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGate.ts index 5a776945d..c659ef07b 100644 --- a/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGate.ts +++ b/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGate.ts @@ -1,3 +1,12 @@ +/** + * `sessionToolPolicyGate` domain — seeded workspace tool-veto contract. + * + * Defines `ISessionToolPolicyGate`, the pure-data injection contract carrying + * the workspace's os-level disabled-tool set as a live read view plus its + * change event — a veto that outranks every Agent-side policy layer. The + * contract carries no IO. Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGateService.ts b/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGateService.ts index 06d1a9e2d..264632b8b 100644 --- a/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGateService.ts +++ b/packages/agent-core-v2/src/session/sessionToolPolicyGate/sessionToolPolicyGateService.ts @@ -1,3 +1,13 @@ +/** + * `sessionToolPolicyGate` domain — no-op default `ISessionToolPolicyGate`. + * + * An empty gate (nothing vetoed, never changes) registered at Session scope + * so Session/Agent scopes materialized WITHOUT a workspace handler — test + * hosts, harness agents — still resolve the contract. The handler's seed + * shadows this registration for real sessions, the same way every other + * workspace-resource injection contract works. + */ + import { Event } from '#/_base/event'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; diff --git a/packages/agent-core-v2/src/session/state/sessionState.ts b/packages/agent-core-v2/src/session/state/sessionState.ts index 4c2d76a9c..99998e001 100644 --- a/packages/agent-core-v2/src/session/state/sessionState.ts +++ b/packages/agent-core-v2/src/session/state/sessionState.ts @@ -1,3 +1,15 @@ +/** + * `state` domain — Session-scope keyed state container contract. + * + * Defines `ISessionStateService`, the Session-scope state service: + * Session-tier services declare their plain-data state as typed keys + * (`defineState` from `_base`) and read/write them through this container, so + * per-session shared state lives in one observable place and dies with the + * session. Shares the `IStateRegistry` method set with its + * App/Workspace/Agent counterparts; its `inspect()` cascade continues into + * the Workspace tier. Bound at Session scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IStateRegistry } from '#/_base/state/stateRegistry'; diff --git a/packages/agent-core-v2/src/session/state/sessionStateService.ts b/packages/agent-core-v2/src/session/state/sessionStateService.ts index acfa7e9ca..aaa26e55e 100644 --- a/packages/agent-core-v2/src/session/state/sessionStateService.ts +++ b/packages/agent-core-v2/src/session/state/sessionStateService.ts @@ -1,7 +1,18 @@ +/** + * `state` domain — `ISessionStateService` implementation. + * + * Thin per-scope binding over the `_base` `StateRegistry`; the container owns + * construction and disposal, so registered state dies with the scope. Injects + * the Workspace-tier state service as its `inspect()` cascade parent (the + * parameter is optional so tests can construct a bare container; DI always + * injects). Bound at Session scope. + */ + import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { StateRegistry } from '#/_base/state/stateRegistry'; +import { IWorkspaceStateService } from '#/workspace/state/workspaceState'; import { ISessionStateService } from './sessionState'; @@ -9,8 +20,9 @@ export class SessionStateService extends StateRegistry implements ISessionStateS declare readonly _serviceBrand: undefined; protected override readonly inspectScope = 'session'; - constructor() { + constructor(@IWorkspaceStateService workspaceState?: IWorkspaceStateService) { super(); + this.inspectParent = workspaceState; } } diff --git a/packages/agent-core-v2/src/session/subagent/configSection.ts b/packages/agent-core-v2/src/session/subagent/configSection.ts index 59b2640d7..38c743ac3 100644 --- a/packages/agent-core-v2/src/session/subagent/configSection.ts +++ b/packages/agent-core-v2/src/session/subagent/configSection.ts @@ -1,8 +1,57 @@ +/** + * `subagent` domain — subagent config-section schema, env binding, and + * timeout / model resolution. + * + * Owns the `[subagent]` configuration section (`timeout_ms` on disk) together + * with the `KIMI_SUBAGENT_TIMEOUT_MS` env override (precedence: env > + * config.toml > 2h default). While + * the env var is set, `stripEnvBoundFields` restores the env-free raw value + * before persistence, so the override never leaks into `config.toml`. Per-run + * timeouts resolve through `resolveSubagentTimeoutMs`, and the timeout + * message renders with `formatSubagentTimeoutDescription`. + * + * The model half of the spawn binding is the secondary model (the + * `[secondary_model]` section on disk): when its + * experiment is enabled and the model is set, newly spawned subagents bind to + * it by default instead of inheriting the caller's model, and the + * `Agent`/`AgentSwarm` tools let the parent model pick per spawn via their + * `model` parameter. When unset, spawning behavior is unchanged (subagents + * inherit the caller's model). A recipe with patch fields binds the + * synthesized derived entry (`SECONDARY_DERIVED_MODEL_ID`); a pointer-only + * recipe binds the pointed entry directly. `default_effort` is passed as the + * explicit subagent thinking; without it the subagent resolves thinking + * naturally (global thinking config → the bound model's default effort) + * rather than inheriting the caller's level. Both tools resolve spawn + * bindings through `resolveSubagentBinding`, advertise the pair via + * `buildSubagentModelDescriptions` (each line suffixed with the entry's + * resolved capability flags, so the parent can route multimodal or + * thinking-heavy subagent tasks instead of guessing from the model id), + * and wrap spawn failures with + * `wrapSubagentModelError`; while the experiment is off they also strip the + * no-op `model` parameter from their advertised schemas via + * `stripSubagentModelParameter`. Spawn reporting reads the display-facing + * alias from `subagentDisplayModel`: the derived entry id means nothing to a + * user, so it resolves back to the recipe's base alias — flag-independent on + * purpose, since interpreting an already-persisted derived binding (resume) + * must keep working after the experiment is switched off. Self-registered + * at module load via `registerConfigSection`. + */ + import { z } from 'zod'; import { Error2, ErrorCodes, isError2 } from '#/errors'; +import type { AgentModelPreference } from '#/app/agentProfileCatalog/agentProfileCatalog'; import { isPlainObject } from '#/app/config/toml'; import type { IFlagService } from '#/app/flag/flag'; +import { + SECONDARY_MODEL_ENV, + SECONDARY_MODEL_SECTION, +} from '#/app/kosongConfig/configSection'; +import { + SECONDARY_DERIVED_MODEL_ID, + secondaryModelPatch, +} from '#/app/kosongConfig/secondaryModelOverlay'; +import { type SecondaryModelConfig } from '#/app/kosongConfig/configSection'; import { type EnvBindings, envBindings, @@ -10,17 +59,12 @@ import { type IConfigService, } from '#/app/config/config'; import { registerConfigSection } from '#/app/config/configSectionContributions'; -import { THINKING_SECTION } from '#/app/kosongConfig/configSection'; -import type { IModelCatalog, Model } from '#/kosong/model/catalog'; -import { - declaredDefaultEffortForModel, - type ThinkingConfig, -} from '#/kosong/model/thinking'; +import type { ModelCapability } from '#/kosong/contract/capability'; +import type { IModelCatalog } from '#/kosong/model/catalog'; import { SECONDARY_MODEL_FLAG_ID } from './flag'; export const SUBAGENT_SECTION = 'subagent'; -export const SECONDARY_MODEL_SECTION = 'secondaryModel'; export const SubagentConfigSchema = z.object({ timeoutMs: z.number().int().min(0).optional(), @@ -28,25 +72,6 @@ export const SubagentConfigSchema = z.object({ export type SubagentConfig = z.infer; -export const SecondaryModelConfigSchema = z.object({ - defaultModel: z.string().min(1).optional(), - models: z.record(z.string(), z.string()).optional(), - force: z.boolean().optional(), - model: z.string().min(1).optional(), - maxContextSize: z.number().int().min(1).optional(), - maxInputSize: z.number().int().min(1).optional(), - maxOutputSize: z.number().int().min(1).optional(), - capabilities: z.array(z.string()).optional(), - displayName: z.string().optional(), - reasoningKey: z.string().optional(), - adaptiveThinking: z.boolean().optional(), - supportEfforts: z.array(z.string()).optional(), - defaultEffort: z.string().optional(), - offEffort: z.string().optional(), -}); - -export type SecondaryModelConfig = z.infer; - export const DEFAULT_SUBAGENT_TIMEOUT_MS = 2 * 60 * 60 * 1000; export const SUBAGENT_TIMEOUT_ENV = 'KIMI_SUBAGENT_TIMEOUT_MS'; @@ -71,8 +96,6 @@ registerConfigSection(SUBAGENT_SECTION, SubagentConfigSchema, { stripEnv: stripSubagentEnv, }); -registerConfigSection(SECONDARY_MODEL_SECTION, SecondaryModelConfigSchema); - export function resolveSubagentTimeoutMs(config: IConfigService): number { return ( config.get(SUBAGENT_SECTION)?.timeoutMs ?? @@ -80,257 +103,91 @@ export function resolveSubagentTimeoutMs(config: IConfigService): number { ); } -export const PRIMARY_SUBAGENT_MODEL_CHOICE = 'primary'; +export type SubagentModelChoice = AgentModelPreference; -export interface SubagentModelPool { - readonly defaultModel?: string; - readonly models: Record; -} - -export function resolveSubagentModelPool(config: IConfigService): SubagentModelPool | undefined { - const section = config.get(SECONDARY_MODEL_SECTION); - if (section?.models !== undefined) { - return { defaultModel: section.defaultModel, models: section.models }; - } - if (section?.defaultModel !== undefined) { - return { defaultModel: section.defaultModel, models: { [section.defaultModel]: '' } }; - } - if (section?.model !== undefined) { - return { defaultModel: section.model, models: { [section.model]: '' } }; - } - return undefined; -} - -export const SECONDARY_MODEL_FORCE_REQUIRES_DEFAULT_MESSAGE = - '[secondary_model].default_model is required when [secondary_model].force is set'; - -export const SECONDARY_MODEL_FORCE_EXCLUDES_MODELS_MESSAGE = - '[secondary_model].force cannot be combined with [secondary_model.models]: the pool table only exists to offer the main agent a choice, and force removes that choice'; - -export function isSubagentModelForced(config: IConfigService): boolean { - return config.get(SECONDARY_MODEL_SECTION)?.force === true; -} - -export function exposesSubagentModelChoice(config: IConfigService, flags: IFlagService): boolean { - if (!flags.enabled(SECONDARY_MODEL_FLAG_ID)) return false; - if (isSubagentModelForced(config)) return false; - return resolveSubagentModelPool(config) !== undefined; -} - -export const SECONDARY_MODEL_DEFAULT_MODEL_REQUIRED_MESSAGE = - '[secondary_model].default_model is required when [secondary_model.models] is configured'; - -export const SECONDARY_MODEL_PRIMARY_MODEL_RESERVED_MESSAGE = `[secondary_model.models] key "${PRIMARY_SUBAGENT_MODEL_CHOICE}" is reserved: it always binds the caller's own model. Rename the pool entry.`; - -export function assertValidSubagentModelPool( - pool: SubagentModelPool, - modelCatalog: IModelCatalog, -): void { - if (Object.hasOwn(pool.models, PRIMARY_SUBAGENT_MODEL_CHOICE)) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_PRIMARY_MODEL_RESERVED_MESSAGE, { - details: { - section: SECONDARY_MODEL_SECTION, - field: 'models', - model: PRIMARY_SUBAGENT_MODEL_CHOICE, - }, - }); - } - const aliases = Object.keys(pool.models); - if (pool.defaultModel === undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_DEFAULT_MODEL_REQUIRED_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'defaultModel' }, - }); - } - if (!Object.hasOwn(pool.models, pool.defaultModel)) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `[secondary_model].default_model "${pool.defaultModel}" is not a [secondary_model.models] key. Available models: ${aliases.join(', ')}.`, - { details: { model: pool.defaultModel, availableModels: aliases } }, - ); - } - for (const alias of aliases) { - try { - modelCatalog.get(alias); - } catch (error) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `[secondary_model.models] entry "${alias}" could not be resolved: ${error instanceof Error ? error.message : String(error)}`, - { cause: error, details: { model: alias } }, - ); - } - } -} - -export function assertValidSubagentModelConfig( +export function resolveSecondaryModel( config: IConfigService, flags: IFlagService, - modelCatalog: IModelCatalog, -): void { - if (!flags.enabled(SECONDARY_MODEL_FLAG_ID)) return; - const section = config.get(SECONDARY_MODEL_SECTION); - if (section?.force === true) { - if (section.models !== undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_FORCE_EXCLUDES_MODELS_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'force' }, - }); - } - if (section.defaultModel === undefined && section.model === undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_FORCE_REQUIRES_DEFAULT_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'defaultModel' }, - }); - } - } - const pool = resolveSubagentModelPool(config); - if (pool !== undefined) assertValidSubagentModelPool(pool, modelCatalog); -} - -export function cascadeSubagentModelPool( - section: SecondaryModelConfig | undefined, - survivingModels: Record, - renamedAliases: ReadonlyMap = new Map(), -): SecondaryModelConfig | null | undefined { - if (section === undefined) return undefined; - const remap = (alias: string): string => renamedAliases.get(alias) ?? alias; - const nextDefault = section.defaultModel === undefined ? undefined : remap(section.defaultModel); - const nextLegacyDefault = section.model === undefined ? undefined : remap(section.model); - const effectiveDefault = nextDefault ?? nextLegacyDefault; - if (effectiveDefault !== undefined && !(effectiveDefault in survivingModels)) return null; - - let changed = nextDefault !== section.defaultModel || nextLegacyDefault !== section.model; - let nextPool: Record | undefined; - if (section.models !== undefined) { - nextPool = {}; - for (const [alias, description] of Object.entries(section.models)) { - const key = remap(alias); - if (!(key in survivingModels)) { - changed = true; - continue; - } - if (key !== alias) changed = true; - nextPool[key] = description; - } - if (Object.keys(nextPool).length === 0) { - nextPool = undefined; - changed = true; - } - } - if (!changed) return undefined; - return { ...section, defaultModel: nextDefault, model: nextLegacyDefault, models: nextPool }; +): SecondaryModelConfig | undefined { + if (!flags.enabled(SECONDARY_MODEL_FLAG_ID)) return undefined; + return config.get(SECONDARY_MODEL_SECTION); } export function resolveSubagentBinding( config: IConfigService, flags: IFlagService, own: { modelAlias: string; thinkingLevel: string }, - requested?: string, -): { model: string; thinking?: string } { - const enabled = flags.enabled(SECONDARY_MODEL_FLAG_ID); - const section = config.get(SECONDARY_MODEL_SECTION); - if (enabled && section?.force === true) { - if (section.models !== undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_FORCE_EXCLUDES_MODELS_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'force' }, - }); - } - const forcedModel = section.defaultModel ?? section.model; - if (forcedModel === undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_FORCE_REQUIRES_DEFAULT_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'defaultModel' }, - }); - } - if (requested !== undefined) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid model "${requested}": [secondary_model].force is set, so every subagent binds "${forcedModel}" (omit the model parameter).`, - { details: { model: requested } }, - ); - } - return { model: forcedModel, thinking: section.defaultEffort }; + requested?: SubagentModelChoice, +): { model: string; thinking?: string; displayModel: string } { + const secondary = resolveSecondaryModel(config, flags); + if (requested !== 'primary' && secondary?.model !== undefined) { + const model = + secondaryModelPatch(secondary) === undefined ? secondary.model : SECONDARY_DERIVED_MODEL_ID; + return { + model, + thinking: secondary.defaultEffort, + displayModel: subagentDisplayModel(config, model), + }; } - if (requested === PRIMARY_SUBAGENT_MODEL_CHOICE) { - return { model: own.modelAlias, thinking: own.thinkingLevel }; - } - const pool = enabled ? resolveSubagentModelPool(config) : undefined; - if (pool === undefined) { - if (requested !== undefined) { - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid model "${requested}": no [secondary_model.models] pool is configured, so subagents inherit the caller's model (pass "primary" or omit the model parameter).`, - { details: { model: requested } }, - ); - } - return { model: own.modelAlias, thinking: own.thinkingLevel }; - } - if (Object.hasOwn(pool.models, PRIMARY_SUBAGENT_MODEL_CHOICE)) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_PRIMARY_MODEL_RESERVED_MESSAGE, { - details: { - section: SECONDARY_MODEL_SECTION, - field: 'models', - model: PRIMARY_SUBAGENT_MODEL_CHOICE, - }, - }); - } - const choice = requested ?? pool.defaultModel; - if (choice === undefined) { - throw new Error2(ErrorCodes.CONFIG_INVALID, SECONDARY_MODEL_DEFAULT_MODEL_REQUIRED_MESSAGE, { - details: { section: SECONDARY_MODEL_SECTION, field: 'defaultModel' }, - }); - } - if (!Object.hasOwn(pool.models, choice)) { - const available = [...Object.keys(pool.models), PRIMARY_SUBAGENT_MODEL_CHOICE]; - throw new Error2( - ErrorCodes.CONFIG_INVALID, - `Invalid model "${choice}". Available models: ${available.join(', ')}.`, - { details: { model: choice, availableModels: available } }, - ); - } - return { model: choice, thinking: section?.defaultEffort }; + return { + model: own.modelAlias, + thinking: own.thinkingLevel, + displayModel: subagentDisplayModel(config, own.modelAlias), + }; } -export function resolveSubagentThinking( +export function subagentDisplayModel( config: IConfigService, - model: Model | undefined, - explicit: string | undefined, -): string | undefined { - if (explicit !== undefined) return explicit; - if (config.get(THINKING_SECTION)?.enabled === false) return undefined; - return declaredDefaultEffortForModel(model); + boundAlias: string, +): string { + if (boundAlias !== SECONDARY_DERIVED_MODEL_ID) return boundAlias; + return ( + config.get(SECONDARY_MODEL_SECTION)?.model ?? boundAlias + ); } export function buildSubagentModelDescriptions( config: IConfigService, flags: IFlagService, callerModelAlias: string | undefined, + modelCatalog: IModelCatalog, ): string | undefined { - if (!exposesSubagentModelChoice(config, flags)) return undefined; - const pool = resolveSubagentModelPool(config)!; - const lines = ['Available models (pass via model):']; - const defaultModel = pool.defaultModel; - const markersFor = (alias: string): string => { - const markers: string[] = []; - if (alias === defaultModel) markers.push('[default]'); - if (alias === callerModelAlias) markers.push('[main model]'); - return markers.length === 0 ? '' : ` ${markers.join(' ')}`; - }; - if (defaultModel !== undefined && Object.hasOwn(pool.models, defaultModel)) { - lines.push( - formatPoolLine(`${defaultModel}${markersFor(defaultModel)}`, pool.models[defaultModel]!), - ); - } - for (const [alias, description] of Object.entries(pool.models)) { - if (alias === defaultModel) continue; - lines.push(formatPoolLine(`${alias}${markersFor(alias)}`, description)); - } - const callerInPool = - callerModelAlias !== undefined && Object.hasOwn(pool.models, callerModelAlias); - lines.push( - `- ${PRIMARY_SUBAGENT_MODEL_CHOICE}${callerInPool ? ` (${callerModelAlias})` : ''}: the main model you are running on, bound with your current thinking level; use it for hard, quality-sensitive subagent tasks`, - ); - return lines.join('\n'); + const secondary = resolveSecondaryModel(config, flags); + const secondaryModel = secondary?.model; + if (secondaryModel === undefined || callerModelAlias === undefined) return undefined; + const boundSecondary = + secondaryModelPatch(secondary) === undefined ? secondaryModel : SECONDARY_DERIVED_MODEL_ID; + return [ + 'Available models (pass via model):', + `- secondary: ${secondaryModel} (default) — the configured secondary model; prefer it for routine subagent tasks${capabilitiesSuffix(resolvedCapabilities(modelCatalog, boundSecondary))}`, + `- primary: ${callerModelAlias} — the main model you are running on; use it for hard, quality-sensitive subagent tasks${capabilitiesSuffix(resolvedCapabilities(modelCatalog, callerModelAlias))}`, + ].join('\n'); } -function formatPoolLine(label: string, description: string): string { - return description === '' ? `- ${label}` : `- ${label}: ${description}`; +const ADVERTISED_CAPABILITY_FLAGS = [ + 'image_in', + 'video_in', + 'audio_in', + 'thinking', + 'tool_use', + 'dynamically_loaded_tools', +] as const satisfies readonly (keyof ModelCapability)[]; + +function capabilitiesSuffix(capability: ModelCapability | undefined): string { + if (capability === undefined) return ''; + const names = ADVERTISED_CAPABILITY_FLAGS.filter((flag) => capability[flag] === true); + return `; capabilities: ${names.length === 0 ? 'none' : names.join(', ')}`; +} + +function resolvedCapabilities( + modelCatalog: IModelCatalog, + model: string, +): ModelCapability | undefined { + try { + return modelCatalog.get(model).capabilities; + } catch { + return undefined; + } } export function stripSubagentModelParameter( @@ -348,21 +205,6 @@ export function stripSubagentModelParameter( return next; } -export function stripSubagentForkParameter( - parameters: Record, -): Record { - const properties = parameters['properties']; - if (!isPlainObject(properties) || !('fork' in properties)) return parameters; - const nextProperties = { ...properties }; - delete nextProperties['fork']; - const next: Record = { ...parameters, properties: nextProperties }; - const required = parameters['required']; - if (Array.isArray(required) && required.includes('fork')) { - next['required'] = required.filter((entry) => entry !== 'fork'); - } - return next; -} - export function wrapSubagentModelError( error: unknown, boundModel: string, @@ -371,17 +213,22 @@ export function wrapSubagentModelError( if (boundModel === callerModelAlias) return error; if (!isError2(error) || error.code !== ErrorCodes.CONFIG_INVALID) return error; if (error.details?.['model'] !== boundModel) return error; + const displayModel = + boundModel === SECONDARY_DERIVED_MODEL_ID + ? `the derived entry "${SECONDARY_DERIVED_MODEL_ID}"` + : `"${boundModel}"`; return new Error2( error.code, - `${error.message} (subagent model "${boundModel}" comes from [secondary_model.models] — check that it names a valid [models] entry)`, + `${error.message} (secondary model ${displayModel} comes from [secondary_model].model / ${SECONDARY_MODEL_ENV} — check that it names a valid [models] entry)`, { cause: error, name: error.name, details: { ...error.details, - subagentModel: boundModel, - subagentModelConfig: { - section: 'secondary_model.models', + secondaryModel: boundModel, + secondaryModelConfig: { + section: 'secondaryModel.model', + environment: SECONDARY_MODEL_ENV, }, }, }, diff --git a/packages/agent-core-v2/src/session/subagent/flag.ts b/packages/agent-core-v2/src/session/subagent/flag.ts index 4be94ff51..67ec3795c 100644 --- a/packages/agent-core-v2/src/session/subagent/flag.ts +++ b/packages/agent-core-v2/src/session/subagent/flag.ts @@ -1,3 +1,13 @@ +/** + * `subagent` domain — registers the `secondary-model` experimental flag + * into `flag`. + * + * Gates secondary-model selection for newly spawned subagents, including the + * agent-facing model choices and startup validation warning. Off by default; + * enable via `KIMI_CODE_EXPERIMENTAL_SECONDARY_MODEL`, the master + * `KIMI_CODE_EXPERIMENTAL_FLAG`, or the `[experimental]` config section. + */ + import { type FlagDefinitionInput, registerFlagDefinition } from '#/app/flag/flagRegistry'; export const SECONDARY_MODEL_FLAG_ID = 'secondary-model'; @@ -14,18 +24,3 @@ export const secondaryModelFlag: FlagDefinitionInput = { }; registerFlagDefinition(secondaryModelFlag); - -export const SUBAGENT_FORK_FLAG_ID = 'subagent_fork'; -export const SUBAGENT_FORK_FLAG_ENV = 'KIMI_CODE_EXPERIMENTAL_SUBAGENT_FORK'; - -export const subagentForkFlag: FlagDefinitionInput = { - id: SUBAGENT_FORK_FLAG_ID, - title: 'Fork context for subagents', - description: - 'Let the Agent and AgentSwarm tools start a subagent with a snapshot of the calling agent\'s conversation history via the fork parameter.', - env: SUBAGENT_FORK_FLAG_ENV, - default: false, - surface: 'core', -}; - -registerFlagDefinition(subagentForkFlag); diff --git a/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts b/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts index 77fcdd001..095a1cb70 100644 --- a/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts +++ b/packages/agent-core-v2/src/session/subagent/mirrorAgentRun.ts @@ -1,21 +1,42 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `subagent` domain — caller-side mirroring of an agent run. + * + * When one agent drives another through `ISessionSubagentService.run`, the + * *requesting* agent surfaces that run + * on its own record stream so the UI can nest the child transcript under the + * launching tool call, external hooks fire, and telemetry is tracked. That + * requester ↔ target association is business data of this wrapper layer — the + * lifecycle registry itself stays flat and knows nothing about it. + * + * External hooks (`SubagentStart` / `SubagentStop`) fire by observation, like + * every other external hook: this wrapper announces "a run is about to start" + * / "...has stopped" through the `ISessionSubagentService` agent-run hook + * slot and stop event. + * + * Wire shape note: the signals are still named `subagent.spawned / started / + * completed / failed` and telemetry still tracks `subagent_created` so existing + * session recordings and dashboards stay valid. The spawned signal also + * reports the child's display-normalized model alias (the derived secondary + * entry resolves to its base alias) and its effective thinking effort, so + * clients can render both at spawn instead of waiting for the first + * `agent.status.updated` frame. + */ + import type { IAgentScopeHandle } from '#/_base/di/scope'; import { userCancellationReason } from '#/_base/utils/abort'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; import { IAgentProfileService } from '#/agent/profile/profile'; -import { tryAgentContextOf } from '#/agent/scopeContext/scopeContext'; import { isProviderRateLimitError } from '#/kosong/contract/errors'; import { type TokenUsage } from '#/kosong/contract/usage'; import { ITelemetryService } from '#/app/telemetry/telemetry'; -import type { SubagentCreatedEvent } from '#/app/telemetry/events'; -import { Event2 } from '#/app/event/event2'; +import { IEventBus } from '#/app/event/eventBus'; import { isAbortError } from '#/_base/utils/abort'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { IEventDispatcher } from '#/state/eventDispatcher'; import { type AgentRunHandle, ISessionSubagentService } from './subagent'; -export interface SubagentSpawnedPayload { +export interface SubagentSpawnedEvent { + readonly type: 'subagent.spawned'; readonly subagentId: string; readonly subagentName: string; readonly parentToolCallId: string; @@ -27,48 +48,35 @@ export interface SubagentSpawnedPayload { readonly runInBackground: boolean; readonly model?: string; readonly thinkingEffort?: string; - readonly taskId?: string; } -export class SubagentSpawned extends Event2 { - static override readonly type = 'subagent.spawned'; - static override readonly observable = true; -} -export interface SubagentSpawned extends SubagentSpawnedPayload {} - -export interface SubagentStartedPayload { +export interface SubagentStartedEvent { + readonly type: 'subagent.started'; readonly subagentId: string; } -export class SubagentStarted extends Event2 { - static override readonly type = 'subagent.started'; - static override readonly observable = true; -} -export interface SubagentStarted extends SubagentStartedPayload {} - -export interface SubagentCompletedPayload { +export interface SubagentCompletedEvent { + readonly type: 'subagent.completed'; readonly subagentId: string; readonly resultSummary: string; readonly usage?: TokenUsage; readonly contextTokens?: number; } -export class SubagentCompleted extends Event2 { - static override readonly type = 'subagent.completed'; - static override readonly observable = true; -} -export interface SubagentCompleted extends SubagentCompletedPayload {} - -export interface SubagentFailedPayload { +export interface SubagentFailedEvent { + readonly type: 'subagent.failed'; readonly subagentId: string; readonly error: string; } -export class SubagentFailed extends Event2 { - static override readonly type = 'subagent.failed'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'subagent.spawned': SubagentSpawnedEvent; + 'subagent.started': SubagentStartedEvent; + 'subagent.completed': SubagentCompletedEvent; + 'subagent.failed': SubagentFailedEvent; + } } -export interface SubagentFailed extends SubagentFailedPayload {} export interface AgentRunSpawnedMeta { readonly profileName: string; @@ -77,9 +85,7 @@ export interface AgentRunSpawnedMeta { readonly description?: string; readonly swarmIndex?: number; readonly runInBackground?: boolean; - readonly fork?: boolean; readonly model?: string; - readonly taskId?: string; } export interface MirrorAgentRunOptions { @@ -88,7 +94,6 @@ export interface MirrorAgentRunOptions { readonly suppressRateLimitFailureEvent?: boolean; readonly signal: AbortSignal; readonly cancel?: (reason?: unknown) => void; - readonly deferStarted?: boolean; } export function emitAgentRunSpawned( @@ -98,35 +103,30 @@ export function emitAgentRunSpawned( ): void { const childProfile = requester.accessor .get(IAgentLifecycleService) - .handleOf(targetAgentId) + ?.get(targetAgentId) ?.accessor.get(IAgentProfileService); - void requester.accessor.get(IEventDispatcher)?.dispatch( - new SubagentSpawned({ - subagentId: targetAgentId, - subagentName: meta.profileName, - parentToolCallId: meta.parentToolCallId ?? '', - parentToolCallUuid: meta.parentToolCallUuid, - parentAgentId: requester.id, - callerAgentId: requester.id, - description: meta.description, - swarmIndex: meta.swarmIndex, - runInBackground: meta.runInBackground ?? false, - model: meta.model, - thinkingEffort: childProfile?.getEffectiveThinkingLevel(), - taskId: meta.taskId, - }), - ); + requester.accessor.get(IEventBus)?.publish({ + type: 'subagent.spawned', + subagentId: targetAgentId, + subagentName: meta.profileName, + parentToolCallId: meta.parentToolCallId ?? '', + parentToolCallUuid: meta.parentToolCallUuid, + parentAgentId: requester.id, + callerAgentId: requester.id, + description: meta.description, + swarmIndex: meta.swarmIndex, + runInBackground: meta.runInBackground ?? false, + model: meta.model, + thinkingEffort: childProfile?.getEffectiveThinkingLevel(), + }); childProfile?.republishStatus(); - const telemetryEvent: SubagentCreatedEvent = { + requester.accessor.get(ITelemetryService)?.track2('subagent_created', { subagent_name: meta.profileName, run_in_background: meta.runInBackground ?? false, - fork: meta.fork ?? false, agent_id: targetAgentId, parent_agent_id: requester.id, parent_tool_call_id: meta.parentToolCallId ?? '', - model: meta.model, - }; - requester.accessor.get(ITelemetryService)?.track2('subagent_created', telemetryEvent); + }); } export async function mirrorAgentRun( @@ -134,12 +134,10 @@ export async function mirrorAgentRun( run: AgentRunHandle, options: MirrorAgentRunOptions, ): Promise<{ summary: string; usage?: TokenUsage }> { - const dispatcher = requester.accessor.get(IEventDispatcher); + const eventBus = requester.accessor.get(IEventBus); const subagents = requester.accessor.get(ISessionSubagentService); const agentLifecycle = requester.accessor.get(IAgentLifecycleService); - if (options.deferStarted !== true) { - void dispatcher?.dispatch(new SubagentStarted({ subagentId: run.agentId })); - } + eventBus?.publish({ type: 'subagent.started', subagentId: run.agentId }); if (options.prompt !== undefined) { const cancelAndRethrow = (reason: unknown): never => { options.cancel?.(reason); @@ -162,14 +160,13 @@ export async function mirrorAgentRun( try { const result = await run.completion; const contextTokens = childContextTokens(agentLifecycle, run.agentId); - void dispatcher?.dispatch( - new SubagentCompleted({ - subagentId: run.agentId, - resultSummary: result.summary, - usage: result.usage, - contextTokens, - }), - ); + eventBus?.publish({ + type: 'subagent.completed', + subagentId: run.agentId, + resultSummary: result.summary, + usage: result.usage, + contextTokens, + }); subagents?.notifyAgentTaskStopped({ agentName: options.profileName, response: result.summary, @@ -177,12 +174,11 @@ export async function mirrorAgentRun( return result; } catch (error) { if (!isAbortError(error) && !shouldSuppressFailure(options, error)) { - void dispatcher?.dispatch( - new SubagentFailed({ - subagentId: run.agentId, - error: errorMessage(error), - }), - ); + eventBus?.publish({ + type: 'subagent.failed', + subagentId: run.agentId, + error: errorMessage(error), + }); } throw error; } @@ -202,9 +198,6 @@ function childContextTokens( agentLifecycle: IAgentLifecycleService, agentId: string, ): number | undefined { - const child = agentLifecycle.handleOf(agentId); - if (child === undefined) return undefined; - const context = tryAgentContextOf(child); - if (context === undefined) return undefined; - return child.accessor.get(ISessionTokenCountingService)?.statusSize(context); + const child = agentLifecycle.get(agentId); + return child?.accessor.get(IAgentTokenCountingService)?.statusSize(); } diff --git a/packages/agent-core-v2/src/session/subagent/runAgentTurn.ts b/packages/agent-core-v2/src/session/subagent/runAgentTurn.ts index bbd42b533..0c8c839ca 100644 --- a/packages/agent-core-v2/src/session/subagent/runAgentTurn.ts +++ b/packages/agent-core-v2/src/session/subagent/runAgentTurn.ts @@ -1,3 +1,18 @@ +/** + * `subagent` domain — helper that runs one prompt (or retry) turn on + * an agent and distills a summary from its context once the turn ends. + * + * Not a Service: `runAgentTurn` is a pure function that borrows + * `IAgentPromptService`, `IAgentContextMemoryService`, `IAgentUsageService`, + * and `IEventBus` from the target agent's scope. It has no notion of a caller: + * it emits no record signals, runs no hooks, and tracks no telemetry. + * + * The lifecycle is imperative — the caller awaits the returned `completion` + * promise. Turn hooks are not used because there is exactly one observer (the + * caller who requested the run); a hook indirection would only obscure the + * flow. + */ + import { APIProviderRateLimitError, isProviderRateLimitError } from '#/kosong/contract/errors'; import { type TokenUsage } from '#/kosong/contract/usage'; @@ -8,8 +23,7 @@ import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; import { Error2, ErrorCodes, toKimiErrorPayload, type KimiErrorPayload } from '#/errors'; import { IAgentPromptService } from '#/agent/prompt/prompt'; import { IAgentLoopService, type Turn, type TurnResult } from '#/agent/loop/loop'; -import { agentContextOf } from '#/agent/scopeContext/scopeContext'; -import { ISessionUsageService } from '#/session/usage/sessionUsage'; +import { IAgentUsageService } from '#/agent/usage/usage'; import type { AgentProfileSummaryPolicy } from '#/app/agentProfileCatalog/agentProfileCatalog'; import type { AgentRunHandle, AgentRunRequest } from './subagent'; @@ -78,7 +92,7 @@ async function awaitRun( }, cancelTurn, ); - const usage = target.accessor.get(ISessionUsageService)?.status(agentContextOf(target)).total; + const usage = target.accessor.get(IAgentUsageService)?.status().total; return { summary, usage }; } finally { unlink(); diff --git a/packages/agent-core-v2/src/session/subagent/secondaryModelWarning.ts b/packages/agent-core-v2/src/session/subagent/secondaryModelWarning.ts new file mode 100644 index 000000000..31017de14 --- /dev/null +++ b/packages/agent-core-v2/src/session/subagent/secondaryModelWarning.ts @@ -0,0 +1,32 @@ +/** + * `subagent` domain — `ISessionSecondaryModelWarningService` contract: + * early validation of the configured secondary model. + * + * The secondary-model pointer (`[secondary_model]` / `KIMI_SECONDARY_MODEL`) + * is otherwise validated lazily at spawn time, so a typo surfaces as a + * mid-conversation tool failure handed back to the parent model. This service + * front-loads the same resolution to session start (main-agent creation): an + * unresolvable model or an effort the model does not list becomes a `warning` + * event on the main agent's event bus, and stays cached for the edge to pull. + * A mid-session `[secondary_model]` change refreshes the cache through + * `recheckSecondaryModelWarning`. Session-scoped — one instance per session. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; + +export const SECONDARY_MODEL_INVALID_WARNING_CODE = 'secondary-model-invalid'; +export const SECONDARY_MODEL_EFFORT_WARNING_CODE = 'secondary-model-effort-not-listed'; + +export interface SecondaryModelWarning { + readonly code: string; + readonly message: string; +} + +export interface ISessionSecondaryModelWarningService { + readonly _serviceBrand: undefined; + getSecondaryModelWarning(): SecondaryModelWarning | undefined; + recheckSecondaryModelWarning(): SecondaryModelWarning | undefined; +} + +export const ISessionSecondaryModelWarningService: ServiceIdentifier = + createDecorator('sessionSecondaryModelWarningService'); diff --git a/packages/agent-core-v2/src/session/subagent/secondaryModelWarningService.ts b/packages/agent-core-v2/src/session/subagent/secondaryModelWarningService.ts new file mode 100644 index 000000000..16e8f4250 --- /dev/null +++ b/packages/agent-core-v2/src/session/subagent/secondaryModelWarningService.ts @@ -0,0 +1,160 @@ +/** + * `subagent` domain — `ISessionSecondaryModelWarningService` implementation. + * + * When enabled through `flag`, runs the secondary-model check once per session + * when the main agent appears (`agentLifecycle` onDidCreate, or an + * already-present main at construction): + * resolves the pointed entry through the kosong `modelCatalog` and, when the + * recipe carries patch fields, checks `default_effort` against the patched + * `supportEfforts` (what the derived entry will carry) — on failure, caches a + * warning and publishes it as a `warning` event on the main agent's + * `eventBus`, and stays cached for the edge to pull. + * `recheckSecondaryModelWarning` recomputes + * the cache after a mid-session `[secondary_model]` change, re-publishing + * only when the warning actually changed. Never throws: a broken secondary + * model demotes to a notice here, with spawn-time resolution staying as the + * backstop. Bound at Session scope. + */ + +import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { + type IAgentScopeHandle, + ScopeActivation, + registerScopedService, +} from '#/_base/di/scope'; +import { IConfigService } from '#/app/config/config'; +import { IEventBus } from '#/app/event/eventBus'; +import { IFlagService } from '#/app/flag/flag'; +import { + SECONDARY_MODEL_EFFORT_ENV, + SECONDARY_MODEL_ENV, +} from '#/app/kosongConfig/configSection'; +import { IModelCatalog, type Model } from '#/kosong/model/catalog'; +import { secondaryModelPatch } from '#/app/kosongConfig/secondaryModelOverlay'; +import { normalizeRequestedThinkingEffort } from '#/kosong/model/thinking'; +import { + IAgentLifecycleService, + MAIN_AGENT_ID, +} from '#/session/agentLifecycle/agentLifecycle'; + +import { resolveSecondaryModel } from './configSection'; +import { + ISessionSecondaryModelWarningService, + SECONDARY_MODEL_EFFORT_WARNING_CODE, + SECONDARY_MODEL_INVALID_WARNING_CODE, + type SecondaryModelWarning, +} from './secondaryModelWarning'; + +// NOTE: stays Disposable — its own 'config' collides with the Fiber +export class SessionSecondaryModelWarningService + extends Disposable + implements ISessionSecondaryModelWarningService +{ + declare readonly _serviceBrand: undefined; + + private warning: SecondaryModelWarning | undefined; + private checked = false; + + constructor( + @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IConfigService private readonly config: IConfigService, + @IFlagService private readonly flags: IFlagService, + @IModelCatalog private readonly modelCatalog: IModelCatalog, + ) { + super(); + this._register( + this.agentLifecycle.onDidCreate((handle) => { + if (handle.id === MAIN_AGENT_ID) this.check(handle); + }), + ); + const main = this.agentLifecycle.get(MAIN_AGENT_ID); + if (main !== undefined) this.check(main); + } + + getSecondaryModelWarning(): SecondaryModelWarning | undefined { + return this.warning; + } + + recheckSecondaryModelWarning(): SecondaryModelWarning | undefined { + const previous = this.warning; + this.warning = this.computeWarning(); + const changed = + previous?.code !== this.warning?.code || previous?.message !== this.warning?.message; + if (changed && this.warning !== undefined) { + this.agentLifecycle + .get(MAIN_AGENT_ID) + ?.accessor.get(IEventBus) + .publish({ + type: 'warning', + code: this.warning.code, + message: this.warning.message, + }); + } + return this.warning; + } + + private check(main: IAgentScopeHandle): void { + if (this.checked) return; + this.checked = true; + this.warning = this.computeWarning(); + if (this.warning !== undefined) { + main.accessor.get(IEventBus).publish({ + type: 'warning', + code: this.warning.code, + message: this.warning.message, + }); + } + } + + private computeWarning(): SecondaryModelWarning | undefined { + const secondary = resolveSecondaryModel(this.config, this.flags); + if (secondary?.model === undefined) return undefined; + let model: Model; + try { + model = this.modelCatalog.get(secondary.model); + } catch (error) { + return { + code: SECONDARY_MODEL_INVALID_WARNING_CODE, + message: + `Secondary model "${secondary.model}" (from [secondary_model].model / ${SECONDARY_MODEL_ENV}) ` + + `could not be resolved: ${error instanceof Error ? error.message : String(error)}. ` + + 'Subagent spawning will fail until this is fixed.', + }; + } + const patch = secondaryModelPatch(secondary); + return effortWarning( + secondary.model, + secondary.defaultEffort, + patch?.supportEfforts ?? model.supportEfforts, + ); + } +} + +function effortWarning( + alias: string, + effort: string | undefined, + supportEfforts: readonly string[] | undefined, +): SecondaryModelWarning | undefined { + const requested = normalizeRequestedThinkingEffort(effort); + if (requested === undefined || requested === 'off' || requested === 'on') return undefined; + const known = (supportEfforts ?? []) + .map((entry) => entry.trim()) + .filter((entry) => entry.length > 0); + if (known.length === 0 || known.includes(requested)) return undefined; + return { + code: SECONDARY_MODEL_EFFORT_WARNING_CODE, + message: + `Secondary model default effort "${requested}" (from [secondary_model].default_effort / ${SECONDARY_MODEL_EFFORT_ENV}) ` + + `is not listed for model "${alias}" (known: ${known.join(', ')}). ` + + 'Subagents may clamp or reject it.', + }; +} + +registerScopedService( + LifecycleScope.Session, + ISessionSecondaryModelWarningService, + SessionSecondaryModelWarningService, + ScopeActivation.OnScopeCreated, + 'subagent', +); diff --git a/packages/agent-core-v2/src/session/subagent/spawn.ts b/packages/agent-core-v2/src/session/subagent/spawn.ts deleted file mode 100644 index 38aba01af..000000000 --- a/packages/agent-core-v2/src/session/subagent/spawn.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { PRIMARY_SUBAGENT_MODEL_CHOICE } from './configSection'; - -export const DEFAULT_PROFILE_NAME = 'coder'; - -export const FORK_WITH_RESUME_UNAVAILABLE = - 'Cannot set resume when forking the current context. Fork creates a new agent; resume continues an existing one.'; -export const FORK_WITH_TYPE_UNAVAILABLE = - 'Cannot set a different subagent_type when forking the current context. A fork inherits this agent\'s own agent type.'; -export const FORK_WITH_MODEL_UNAVAILABLE = - 'Cannot override the model when forking the current context. A fork inherits this agent\'s model.'; -export const FORK_EXPERIMENTAL_UNAVAILABLE = - 'fork is disabled: the subagent_fork experimental flag is off.'; -export const FORK_CONTEXT_NOTICE = - 'The conversation above is not your own history: it is a one-time snapshot inherited from the agent that forked you. Treat it as reference material only — you are an independent subagent, not a continuation of that agent. Do the task below directly yourself, then report the result.'; - -export interface ForkCompatibilityArgs { - readonly resume?: string; - readonly subagent_type?: string; - readonly model?: string; -} - -export function forkIncompatibility( - args: ForkCompatibilityArgs, - own: { readonly profileName?: string; readonly modelAlias?: string }, -): string | undefined { - const resumeAgentId = args.resume?.trim(); - if (resumeAgentId !== undefined && resumeAgentId.length > 0) { - return FORK_WITH_RESUME_UNAVAILABLE; - } - const requestedProfileName = - args.subagent_type !== undefined && args.subagent_type.length > 0 - ? args.subagent_type - : undefined; - if (requestedProfileName !== undefined && requestedProfileName !== own.profileName) { - return FORK_WITH_TYPE_UNAVAILABLE; - } - if ( - args.model !== undefined && - args.model !== PRIMARY_SUBAGENT_MODEL_CHOICE && - args.model !== own.modelAlias - ) { - return FORK_WITH_MODEL_UNAVAILABLE; - } - return undefined; -} - -export interface SubagentSpawnPlanInput { - readonly callerAgentId: string; - readonly profileName?: string; - readonly model?: string; - readonly fork?: boolean; -} - -export interface SubagentSpawnPlan { - readonly profileName: string; - readonly model: string; - readonly thinking?: string; - readonly fork: boolean; -} - -export interface SpawnSubagentOptions { - readonly callerAgentId: string; - readonly plan: SubagentSpawnPlan; - readonly labels?: Readonly>; - readonly prompt: string; -} - -export interface SpawnedSubagent { - readonly agentId: string; - readonly profileName: string; - readonly model: string; - readonly promptText: string; -} diff --git a/packages/agent-core-v2/src/session/subagent/subagent.ts b/packages/agent-core-v2/src/session/subagent/subagent.ts index d3994abc5..5f0d185ee 100644 --- a/packages/agent-core-v2/src/session/subagent/subagent.ts +++ b/packages/agent-core-v2/src/session/subagent/subagent.ts @@ -1,18 +1,21 @@ +/** + * `subagent` domain — `ISessionSubagentService` contract: driving turns + * on other agents, plus the hook / event surface those runs announce. + * + * Owns *runs* — one agent driving a turn on another and the requester-side + * announcements that come with it. The `onWillStartAgentTask` hook slot and + * the `onDidStopAgentTask` event announce a run's start and stop so observers + * can translate them into the `SubagentStart` / `SubagentStop` external hook + * commands. Session-scoped — one instance per session. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; import type { TokenUsage } from '#/kosong/contract/usage'; import type { AgentProfileSummaryPolicy } from '#/app/agentProfileCatalog/agentProfileCatalog'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; import type { Turn } from '#/agent/loop/loop'; import type { Hooks } from '#/hooks'; -import type { - SpawnSubagentOptions, - SpawnedSubagent, - SubagentSpawnPlan, - SubagentSpawnPlanInput, -} from './spawn'; - export type AgentRunRequest = | { readonly kind: 'prompt'; readonly prompt: string } | { readonly kind: 'retry'; readonly trigger?: string }; @@ -51,11 +54,7 @@ export interface ISessionSubagentService { readonly onDidStopAgentTask: Event; - run(agent: AgentContext, request: AgentRunRequest, opts: RunAgentOptions): Promise; - - planSpawn(input: SubagentSpawnPlanInput): Promise; - - spawn(opts: SpawnSubagentOptions): Promise; + run(agentId: string, request: AgentRunRequest, opts: RunAgentOptions): Promise; notifyAgentTaskStopped(context: AgentTaskStopHookContext): void; } diff --git a/packages/agent-core-v2/src/session/subagent/subagentModelsValidation.ts b/packages/agent-core-v2/src/session/subagent/subagentModelsValidation.ts deleted file mode 100644 index e49035d6c..000000000 --- a/packages/agent-core-v2/src/session/subagent/subagentModelsValidation.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; - -export interface ISessionSubagentModelsValidationService { - readonly _serviceBrand: undefined; -} - -export const ISessionSubagentModelsValidationService: ServiceIdentifier = - createDecorator( - 'sessionSubagentModelsValidationService', - ); diff --git a/packages/agent-core-v2/src/session/subagent/subagentModelsValidationService.ts b/packages/agent-core-v2/src/session/subagent/subagentModelsValidationService.ts deleted file mode 100644 index cd19ad039..000000000 --- a/packages/agent-core-v2/src/session/subagent/subagentModelsValidationService.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { IConfigService } from '#/app/config/config'; -import { IFlagService } from '#/app/flag/flag'; -import { IModelCatalog } from '#/kosong/model/catalog'; - -import { assertValidSubagentModelConfig } from './configSection'; -import { ISessionSubagentModelsValidationService } from './subagentModelsValidation'; - -export class SessionSubagentModelsValidationService - implements ISessionSubagentModelsValidationService -{ - declare readonly _serviceBrand: undefined; - - constructor( - @IConfigService config: IConfigService, - @IFlagService flags: IFlagService, - @IModelCatalog modelCatalog: IModelCatalog, - ) { - assertValidSubagentModelConfig(config, flags, modelCatalog); - } -} - -registerScopedService( - LifecycleScope.Session, - ISessionSubagentModelsValidationService, - SessionSubagentModelsValidationService, - ScopeActivation.OnScopeCreated, - 'subagent', -); diff --git a/packages/agent-core-v2/src/session/subagent/subagentService.ts b/packages/agent-core-v2/src/session/subagent/subagentService.ts index f97b6c718..774cb05f4 100644 --- a/packages/agent-core-v2/src/session/subagent/subagentService.ts +++ b/packages/agent-core-v2/src/session/subagent/subagentService.ts @@ -1,5 +1,15 @@ +/** + * `subagent` domain — `ISessionSubagentService` implementation. + * + * Owns the "drive a turn on another agent" operation (`run`) and the + * requester-side announcement surface those runs share: the + * `onWillStartAgentTask` hook slot and the `onDidStopAgentTask` event fired + * around each mirrored run. The service resolves the target agent from the + * lifecycle registry and picks its summary policy from the profile catalog; + * turn driving itself is delegated to a pure helper. Bound at Session scope. + */ + import { Service } from '#/_base/di/service'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; import { Error2, ErrorCodes } from '#/errors'; import { LifecycleScope } from '#/app/scopes'; import { @@ -9,28 +19,10 @@ import { } from '#/_base/di/scope'; import { Emitter } from '#/_base/event'; import type { AgentProfileSummaryPolicy } from '#/app/agentProfileCatalog/agentProfileCatalog'; -import { applyProfilePromptPrefix } from '#/app/agentProfileCatalog/promptPrefix'; -import { - rootDelegationExtras, - subagentAllowlistFor, - subagentTypeNotAllowedMessage, - withoutDelegatingTargets, -} from '#/app/agentProfileCatalog/profile-shared'; import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; import { IAgentProfileService } from '#/agent/profile/profile'; -import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; -import { IAgentUserToolService } from '#/agent/userTool/userTool'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; -import type { Runtime } from '#/runtime/runtime'; -import { IConfigService } from '#/app/config/config'; -import { IFlagService } from '#/app/flag/flag'; -import { IModelCatalog, type Model } from '#/kosong/model/catalog'; -import { ILogService } from '#/_base/log/log'; -import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; import { createHooks } from '#/hooks'; -import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; -import { agentContextOf } from '#/agent/scopeContext/scopeContext'; +import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { type AgentRunHandle, @@ -41,19 +33,6 @@ import { type RunAgentOptions, } from './subagent'; import { runAgentTurn } from './runAgentTurn'; -import { - resolveSubagentBinding, - resolveSubagentThinking, - wrapSubagentModelError, -} from './configSection'; -import { - DEFAULT_PROFILE_NAME, - FORK_CONTEXT_NOTICE, - type SpawnSubagentOptions, - type SpawnedSubagent, - type SubagentSpawnPlan, - type SubagentSpawnPlanInput, -} from './spawn'; export class SessionSubagentService extends Service implements ISessionSubagentService { declare readonly _serviceBrand: undefined; @@ -70,20 +49,15 @@ export class SessionSubagentService extends Service implements ISessionSubagentS constructor( @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, @ISessionAgentProfileCatalog private readonly catalog: ISessionAgentProfileCatalog, - @IConfigService private readonly configService: IConfigService, - @IFlagService private readonly flags: IFlagService, - @IModelCatalog private readonly modelCatalog: IModelCatalog, - @ISessionContext private readonly sessionContext: ISessionContext, - @ILogService private readonly log: ILogService, ) { super(); } - run(agent: AgentContext, request: AgentRunRequest, opts: RunAgentOptions): Promise { - const handle = this.agentLifecycle.handleOf(agent.agentId); + run(agentId: string, request: AgentRunRequest, opts: RunAgentOptions): Promise { + const handle = this.agentLifecycle.get(agentId); if (handle === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Agent "${agent.agentId}" does not exist`, { - details: { agentId: agent.agentId }, + throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Agent "${agentId}" does not exist`, { + details: { agentId }, }); } return runAgentTurn(handle, request, { @@ -93,153 +67,10 @@ export class SessionSubagentService extends Service implements ISessionSubagentS }); } - async planSpawn(input: SubagentSpawnPlanInput): Promise { - const caller = this.requireCaller(input.callerAgentId); - const fork = input.fork === true; - await this.catalog.ready; - const own = caller.accessor.get(IAgentProfileService).data(); - const requested = input.profileName !== undefined && input.profileName.length > 0 - ? input.profileName - : undefined; - const requestedProfileName = - requested ?? (fork ? (own.profileName ?? DEFAULT_PROFILE_NAME) : DEFAULT_PROFILE_NAME); - const extras = - input.callerAgentId === MAIN_AGENT_ID - ? rootDelegationExtras(this.catalog, own, this.catalog.list()) - : undefined; - let allowlist = subagentAllowlistFor(this.catalog, own, extras); - if (allowlist !== undefined && own.subagents === undefined) { - allowlist = withoutDelegatingTargets(this.catalog, allowlist); - } - if (!fork && allowlist !== undefined && !allowlist.includes(requestedProfileName)) { - throw new Error2( - ErrorCodes.AGENT_TYPE_NOT_ALLOWED, - subagentTypeNotAllowedMessage(requestedProfileName, allowlist), - { details: { profileName: requestedProfileName, allowlist } }, - ); - } - const profile = this.catalog.get(requestedProfileName); - if (!fork && profile === undefined) { - throw new Error2(ErrorCodes.PROFILE_UNKNOWN, `Unknown agent type: "${requestedProfileName}"`, { - details: { profileName: requestedProfileName }, - }); - } - if (own.modelAlias === undefined) { - throw new Error2(ErrorCodes.MODEL_NOT_CONFIGURED, 'Caller agent has no model bound', { - details: { agentId: input.callerAgentId }, - }); - } - const binding = fork - ? { model: own.modelAlias, thinking: own.thinkingLevel } - : resolveSubagentBinding( - this.configService, - this.flags, - { modelAlias: own.modelAlias, thinkingLevel: own.thinkingLevel }, - input.model, - ); - let model: Model; - try { - model = this.modelCatalog.get(binding.model); - } catch (error) { - throw wrapSubagentModelError(error, binding.model, own.modelAlias); - } - return { - profileName: profile?.name ?? requestedProfileName, - model: binding.model, - thinking: resolveSubagentThinking(this.configService, model, binding.thinking), - fork, - }; - } - - async spawn(opts: SpawnSubagentOptions): Promise { - const caller = this.requireCaller(opts.callerAgentId); - const { plan } = opts; - const lease = plan.fork - ? undefined - : caller.accessor.get(IAgentRuntimeService).acquire(['process']); - try { - let created: IAgentScopeHandle; - try { - if (plan.fork) { - const forked = await this.agentLifecycle.fork(agentContextOf(caller), { - labels: opts.labels, - }); - created = this.agentLifecycle.handleOf(forked.agentId)!; - } else { - const createdContext = await this.agentLifecycle.create({ - binding: { - profile: plan.profileName, - model: plan.model, - thinking: plan.thinking, - }, - labels: opts.labels, - runtimeId: lease!.runtime.identity.runtimeId, - }); - created = this.agentLifecycle.handleOf(createdContext.agentId)!; - } - } catch (error) { - throw wrapSubagentModelError( - error, - plan.model, - caller.accessor.get(IAgentProfileService).data().modelAlias, - ); - } - created.accessor - .get(IAgentPermissionModeService) - .setMode(caller.accessor.get(IAgentPermissionModeService).mode); - const createdUserTools = created.accessor.get(IAgentUserToolService); - const callerUserTools = caller.accessor.get(IAgentUserToolService); - if (plan.fork) { - const activeToolNames = created.accessor.get(IAgentProfileService).getActiveToolNames(); - createdUserTools.inheritUserTools(callerUserTools, activeToolNames); - } else { - createdUserTools.inheritUserTools(callerUserTools); - } - const promptText = plan.fork - ? `${FORK_CONTEXT_NOTICE}\n\n${opts.prompt}` - : await this.applyPromptPrefix(plan.profileName, opts.prompt, lease!.runtime); - return { - agentId: created.id, - profileName: plan.profileName, - model: plan.model, - promptText, - }; - } finally { - lease?.dispose(); - } - } - notifyAgentTaskStopped(context: AgentTaskStopHookContext): void { this.onDidStopAgentTaskEmitter.fire(context); } - private async applyPromptPrefix( - profileName: string, - prompt: string, - runtime: Runtime, - ): Promise { - const profile = this.catalog.get(profileName); - if (profile?.promptPrefix === undefined) return prompt; - const view = new RuntimeWorkspaceView(runtime, { - workDir: this.sessionContext.cwd, - }); - return applyProfilePromptPrefix(profile, prompt, { - cwd: view.workDir, - process: runtime.process!, - log: this.log, - }); - } - - private requireCaller(agentId: string): IAgentScopeHandle { - const handle = this.agentLifecycle.handleOf(agentId); - if (handle === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `Caller agent "${agentId}" does not exist`, { - details: { agentId }, - }); - } - return handle; - } - private summaryPolicyFor(handle: IAgentScopeHandle): AgentProfileSummaryPolicy | undefined { const profileName = handle.accessor.get(IAgentProfileService).data().profileName; if (profileName === undefined) return undefined; diff --git a/packages/agent-core-v2/src/features/swarm/session/agentRunBatch.ts b/packages/agent-core-v2/src/session/swarm/agentRunBatch.ts similarity index 97% rename from packages/agent-core-v2/src/features/swarm/session/agentRunBatch.ts rename to packages/agent-core-v2/src/session/swarm/agentRunBatch.ts index dbc289997..48854287f 100644 --- a/packages/agent-core-v2/src/features/swarm/session/agentRunBatch.ts +++ b/packages/agent-core-v2/src/session/swarm/agentRunBatch.ts @@ -1,3 +1,12 @@ +/** + * `sessionSwarm` domain — internal concurrency / rate-limit scheduler. + * + * Owns the burst-then-throttle launch ramp and the provider-rate-limit recovery + * loop for swarm agent runs; drives each attempt through a + * `AgentRunBatchLauncher` and surfaces requeues via `suspended`. Pure scheduling + * logic — owns no scoped state. + */ + import { isProviderRateLimitError } from '#/kosong/contract/errors'; import { type TokenUsage } from '#/kosong/contract/usage'; import * as retry from 'retry'; @@ -5,9 +14,9 @@ import * as retry from 'retry'; import { isUserCancellation } from '#/_base/utils/abort'; import { setClampedTimeout } from '#/_base/utils/timer'; import { BugIndicatingError, Error2, ErrorCodes } from '#/errors'; -import type { SubagentSpawnPlan } from '#/session/subagent/spawn'; import type { SessionSwarmRunResult, SessionSwarmTask } from './sessionSwarm'; + export interface AgentRunAttemptOptions { readonly parentToolCallId: string; readonly parentToolCallUuid?: string; @@ -23,7 +32,7 @@ export interface AgentRunAttemptOptions { export interface AgentSpawnAttemptOptions extends AgentRunAttemptOptions { readonly profileName: string; readonly swarmItem?: string; - readonly plan: SubagentSpawnPlan; + readonly binding?: { readonly model: string; readonly thinking?: string }; } export type AgentRunAttemptHandle = { @@ -35,6 +44,7 @@ export type AgentRunAttemptHandle = { }>; }; + const INITIAL_LAUNCH_LIMIT = 5; const INITIAL_LAUNCH_INTERVAL_MS = 700; const RATE_LIMIT_RETRY_BASE_MS = 3000; @@ -293,7 +303,7 @@ export class AgentRunBatch { const spawnOptions: AgentSpawnAttemptOptions = { profileName: task.profileName, swarmItem: task.swarmItem, - plan: task.plan, + binding: task.binding, ...runOptions, }; handle = await this.launcher.spawn(spawnOptions); diff --git a/packages/agent-core-v2/src/features/swarm/session/sessionSwarm.ts b/packages/agent-core-v2/src/session/swarm/sessionSwarm.ts similarity index 83% rename from packages/agent-core-v2/src/features/swarm/session/sessionSwarm.ts rename to packages/agent-core-v2/src/session/swarm/sessionSwarm.ts index 986ada8da..30ed57ab1 100644 --- a/packages/agent-core-v2/src/features/swarm/session/sessionSwarm.ts +++ b/packages/agent-core-v2/src/session/swarm/sessionSwarm.ts @@ -1,7 +1,14 @@ +/** + * `sessionSwarm` domain — batch scheduler for swarm agent runs. + * + * Defines `ISessionSwarmService`, the Session-scoped service that runs a batch + * of agents on behalf of a caller agent. Owns the in-flight batch state so + * cancellation can reach every run. Bound at Session scope. + */ + import type { TokenUsage } from '#/kosong/contract/usage'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { SubagentSpawnPlan } from '#/session/subagent/spawn'; type SessionSwarmTaskBase = { readonly data: T; @@ -20,7 +27,7 @@ type SessionSwarmTaskBase = { export type SessionSwarmSpawnTask = SessionSwarmTaskBase & { readonly kind: 'spawn'; readonly resumeAgentId?: undefined; - readonly plan: SubagentSpawnPlan; + readonly binding?: { readonly model: string; readonly thinking?: string }; }; export type SessionSwarmResumeTask = SessionSwarmTaskBase & { diff --git a/packages/agent-core-v2/src/features/swarm/session/sessionSwarmService.ts b/packages/agent-core-v2/src/session/swarm/sessionSwarmService.ts similarity index 56% rename from packages/agent-core-v2/src/features/swarm/session/sessionSwarmService.ts rename to packages/agent-core-v2/src/session/swarm/sessionSwarmService.ts index a8c93c244..811cb21ee 100644 --- a/packages/agent-core-v2/src/features/swarm/session/sessionSwarmService.ts +++ b/packages/agent-core-v2/src/session/swarm/sessionSwarmService.ts @@ -1,12 +1,38 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ +/** + * `sessionSwarm` domain — `ISessionSwarmService` implementation. + * + * Runs a batch of agents on behalf of a caller agent: builds an + * `AgentRunBatchLauncher` on top of the `agentLifecycle` primitives + * (`create({ binding })`, `run`), drives the internal `AgentRunBatch` + * scheduler, and tracks one `AbortController` per caller so `cancel` can abort + * every in-flight run. The caller ↔ child association is this domain's own + * business data: requester-side display facts (`subagent.spawned` wire signals + * carrying the swarm's tool-call context, `subagent.suspended` when a task is + * requeued after a provider rate limit) are emitted from this layer; the + * lifecycle registry itself stays flat. Spawn tasks may carry a concrete + * `binding` resolved by the caller; without + * one, spawns inherit the caller agent's model and thinking level. Spawn + * bindings are resolved through the model catalog before lifecycle allocation. + * Resumed agents keep the model recorded in their own wire journal — with + * per-subagent models there is no "child follows the parent's current model" + * invariant to enforce. Bound at Session scope. + */ + import type { TokenUsage } from '#/kosong/contract/usage'; +import { IModelCatalog } from '#/kosong/model/catalog'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Error2, ErrorCodes } from '#/errors'; import { linkAbortSignal } from '#/_base/utils/abort'; import type { IAgentScopeHandle } from '#/_base/di/scope'; import { IAgentProfileService } from '#/agent/profile/profile'; +import { IAgentPermissionModeService } from '#/agent/permissionMode/permissionMode'; import { IAgentLoopService } from '#/agent/loop/loop'; -import { Event2 } from '#/app/event/event2'; -import { agentContextOf } from '#/agent/scopeContext/scopeContext'; +import { IAgentUserToolService } from '#/agent/userTool/userTool'; +import { IEventBus } from '#/app/event/eventBus'; +import { IConfigService } from '#/app/config/config'; +import { ISessionAgentProfileCatalog } from '#/session/sessionAgentProfileCatalog/sessionAgentProfileCatalog'; +import { applyProfilePromptPrefix } from '#/app/agentProfileCatalog/promptPrefix'; import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; import { isSubagentMeta, @@ -16,8 +42,14 @@ import { } from '#/session/agentLifecycle/subagentMetadata'; import { emitAgentRunSpawned, mirrorAgentRun } from '#/session/subagent/mirrorAgentRun'; import { ISessionSubagentService } from '#/session/subagent/subagent'; +import { + subagentDisplayModel, + wrapSubagentModelError, +} from '#/session/subagent/configSection'; +import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionMetadata, type AgentMeta } from '#/session/sessionMetadata/sessionMetadata'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { ISessionProcessRunner } from '#/session/process/processRunner'; +import { ILogService } from '#/_base/log/log'; import { ISessionSwarmService, @@ -34,16 +66,17 @@ import { type AgentRunAttemptHandle, } from './agentRunBatch'; -export interface SubagentSuspendedPayload { +export interface SubagentSuspendedEvent { + readonly type: 'subagent.suspended'; readonly subagentId: string; readonly reason: string; } -export class SubagentSuspended extends Event2 { - static override readonly type = 'subagent.suspended'; - static override readonly observable = true; +declare module '#/app/event/eventBus' { + interface DomainEventMap { + 'subagent.suspended': SubagentSuspendedEvent; + } } -export interface SubagentSuspended extends SubagentSuspendedPayload {} const RESUMED_PROFILE_FALLBACK = 'subagent'; @@ -53,9 +86,15 @@ export class SessionSwarmService implements ISessionSwarmService { private readonly inFlight = new Map(); constructor( - @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + @IAgentLifecycleService private readonly lifecycle: IAgentLifecycleService, @ISessionSubagentService private readonly subagents: ISessionSubagentService, + @ISessionAgentProfileCatalog private readonly catalog: ISessionAgentProfileCatalog, + @ISessionContext private readonly sessionContext: ISessionContext, @ISessionMetadata private readonly metadata: ISessionMetadata, + @ISessionProcessRunner private readonly processRunner: ISessionProcessRunner, + @ILogService private readonly log: ILogService, + @IModelCatalog private readonly modelCatalog: IModelCatalog, + @IConfigService private readonly config: IConfigService, ) {} async getSwarmItem(args: { @@ -82,13 +121,12 @@ export class SessionSwarmService implements ISessionSwarmService { resume: (agentId, options) => this.resumeAttempt(callerAgentId, agentId, options, false), retry: (agentId, options) => this.resumeAttempt(callerAgentId, agentId, options, true), suspended: (event) => { - const caller = this.agentLifecycle.handleOf(callerAgentId); - void caller?.accessor.get(IEventDispatcher)?.dispatch( - new SubagentSuspended({ - subagentId: event.agentId, - reason: event.reason, - }), - ); + const caller = this.lifecycle.get(callerAgentId); + caller?.accessor.get(IEventBus)?.publish({ + type: 'subagent.suspended', + subagentId: event.agentId, + reason: event.reason, + }); }, }; const maxConcurrency = resolveSwarmMaxConcurrency(); @@ -110,34 +148,61 @@ export class SessionSwarmService implements ISessionSwarmService { ): Promise { options.signal.throwIfAborted(); const caller = this.requireHandle(callerAgentId, 'Caller agent'); - const { plan } = options; - const spawned = await this.subagents.spawn({ - callerAgentId, - plan, - labels: subagentLabels(callerAgentId, { swarmItem: options.swarmItem }), - prompt: options.prompt, - }); - emitAgentRunSpawned(caller, spawned.agentId, { - profileName: plan.profileName, + await this.catalog.ready; + const profile = this.catalog.get(options.profileName); + if (profile === undefined) { + throw new Error2(ErrorCodes.PROFILE_UNKNOWN, `Unknown agent type: "${options.profileName}"`, { + details: { profileName: options.profileName }, + }); + } + const callerData = caller.accessor.get(IAgentProfileService).data(); + if (callerData.modelAlias === undefined) { + throw new Error2(ErrorCodes.MODEL_NOT_CONFIGURED, 'Caller agent has no model bound', { + details: { agentId: callerAgentId }, + }); + } + const binding = options.binding ?? { + model: callerData.modelAlias, + thinking: callerData.thinkingLevel, + }; + let child: IAgentScopeHandle; + try { + this.modelCatalog.get(binding.model); + child = await this.lifecycle.create({ + binding: { + profile: profile.name, + model: binding.model, + thinking: binding.thinking, + }, + labels: subagentLabels(callerAgentId, { swarmItem: options.swarmItem }), + }); + } catch (error) { + throw wrapSubagentModelError(error, binding.model, callerData.modelAlias); + } + child.accessor + .get(IAgentPermissionModeService) + .setMode(caller.accessor.get(IAgentPermissionModeService).mode); + child.accessor + .get(IAgentUserToolService) + .inheritUserTools(caller.accessor.get(IAgentUserToolService)); + emitAgentRunSpawned(caller, child.id, { + profileName: options.profileName, parentToolCallId: options.parentToolCallId, parentToolCallUuid: options.parentToolCallUuid, description: options.description, swarmIndex: options.swarmIndex, runInBackground: options.runInBackground, - fork: plan.fork, - model: plan.model, + model: subagentDisplayModel(this.config, binding.model), }); - const child = this.requireHandle(spawned.agentId, 'Agent instance'); - return this.observe( - caller, - child, - plan.profileName, - { - kind: 'prompt', - prompt: spawned.promptText, - }, - options, - ); + const promptText = await applyProfilePromptPrefix(profile, options.prompt, { + cwd: this.sessionContext.cwd, + runner: this.processRunner, + log: this.log, + }); + return this.observe(caller, child.id, options.profileName, { + kind: 'prompt', + prompt: promptText, + }, options); } private async resumeAttempt( @@ -162,24 +227,26 @@ export class SessionSwarmService implements ISessionSwarmService { description: options.description, swarmIndex: options.swarmIndex, runInBackground: options.runInBackground, - model: resumedModel, + model: + resumedModel === undefined + ? undefined + : subagentDisplayModel(this.config, resumedModel), }); } const request = retryTurn ? ({ kind: 'retry' } as const) : ({ kind: 'prompt', prompt: options.prompt } as const); - return this.observe(caller, child, profileName, request, options); + return this.observe(caller, child.id, profileName, request, options); } private async observe( caller: IAgentScopeHandle, - child: IAgentScopeHandle, + agentId: string, profileName: string, request: { kind: 'prompt'; prompt: string } | { kind: 'retry' }, options: AgentRunAttemptOptions, ): Promise { - const agentId = child.id; - const run = await this.subagents.run(agentContextOf(child), request, { + const run = await this.subagents.run(agentId, request, { signal: options.signal, onReady: options.onReady, }); @@ -197,7 +264,7 @@ export class SessionSwarmService implements ISessionSwarmService { } private requireHandle(agentId: string, label: string): IAgentScopeHandle { - const handle = this.agentLifecycle.handleOf(agentId); + const handle = this.lifecycle.get(agentId); if (handle === undefined) { throw new Error2(ErrorCodes.AGENT_NOT_FOUND, `${label} "${agentId}" does not exist`, { details: { agentId }, @@ -239,3 +306,11 @@ export class SessionSwarmService implements ISessionSwarmService { } export type _AgentRunUsage = TokenUsage; + +registerScopedService( + LifecycleScope.Session, + ISessionSwarmService, + SessionSwarmService, + ScopeActivation.OnScopeCreated, + 'sessionSwarm', +); diff --git a/packages/agent-core-v2/src/session/terminal/terminalService.ts b/packages/agent-core-v2/src/session/terminal/terminalService.ts index 048f29c6c..ec9556023 100644 --- a/packages/agent-core-v2/src/session/terminal/terminalService.ts +++ b/packages/agent-core-v2/src/session/terminal/terminalService.ts @@ -1,3 +1,12 @@ +/** + * `terminal` domain — Session-scoped terminal facade. + * + * Owns this session's terminal set and its per-terminal output buffers and + * attached sinks; spawns PTYs through the App-scoped `IHostTerminalService`, + * resolves the working directory through `workspaceContext`, and reads the + * session id through `sessionContext` to tag frames. Bound at Session scope. + */ + import { randomUUID } from 'node:crypto'; import { Disposable, type IDisposable } from '#/_base/di/lifecycle'; @@ -14,13 +23,10 @@ import type { TerminalOutputMessage, TerminalProcess, } from '#/os/interface/terminal'; +import { IHostTerminalService } from '#/os/interface/terminal'; import { ErrorCodes, Error2 } from '#/errors'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionWorkspaceContext } from '#/session/workspaceContext/workspaceContext'; -import { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; - -import type { RuntimeLease } from '#/runtime/runtime'; -import { RuntimeWorkspaceView } from '#/runtime/runtimeWorkspaceView'; const DEFAULT_COLS = 80; const DEFAULT_ROWS = 24; @@ -29,7 +35,6 @@ const DEFAULT_MAX_BUFFERED_FRAMES = 2000; interface TerminalRecord { terminal: Terminal; process: TerminalProcess; - lease: RuntimeLease; sinks: Map; buffer: TerminalFrame[]; nextSeq: number; @@ -58,13 +63,14 @@ export interface ISessionTerminalService { export const ISessionTerminalService: ServiceIdentifier = createDecorator('sessionTerminalService'); +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class SessionTerminalService extends Disposable implements ISessionTerminalService { declare readonly _serviceBrand: undefined; private readonly records = new Map(); constructor( - @IRuntimeResolver private readonly runtimeResolver: IRuntimeResolver, + @IHostTerminalService private readonly terminalService: IHostTerminalService, @ISessionWorkspaceContext private readonly workspace: ISessionWorkspaceContext, @ISessionContext private readonly sessionContext: ISessionContext, ) { @@ -72,23 +78,14 @@ export class SessionTerminalService extends Disposable implements ISessionTermin } async create(input: CreateTerminalRequest): Promise { + const cwd = + input.cwd === undefined + ? this.workspace.workDir + : this.workspace.assertAllowed(input.cwd, 'execute'); + const shell = input.shell ?? defaultShell(); const cols = input.cols ?? DEFAULT_COLS; const rows = input.rows ?? DEFAULT_ROWS; - const lease = this.runtimeResolver.acquire( - { workspaceId: this.sessionContext.workspaceId, runtimeId: input.runtime_id }, - ['terminal'], - ); - const view = new RuntimeWorkspaceView(lease.runtime, this.workspace); - const cwd = input.cwd === undefined ? view.workDir : view.resolve(input.cwd); - const shell = input.shell ?? lease.runtime.environment.shellPath; - let process: TerminalProcess; - try { - process = await lease.runtime.terminal!.spawn({ cwd, shell, cols, rows }); - lease.track({ dispose: () => process.kill() }); - } catch (error) { - lease.dispose(); - throw error; - } + const process = await this.terminalService.spawn({ cwd, shell, cols, rows }); const terminal: Terminal = { id: `term_${randomUUID()}`, session_id: this.sessionContext.sessionId, @@ -102,7 +99,6 @@ export class SessionTerminalService extends Disposable implements ISessionTermin const record: TerminalRecord = { terminal, process, - lease, sinks: new Map(), buffer: [], nextSeq: 0, @@ -176,7 +172,6 @@ export class SessionTerminalService extends Disposable implements ISessionTermin override dispose(): void { for (const record of this.records.values()) { disposeAll(record.disposables); - record.lease.dispose(); try { record.process.kill(); } catch { @@ -232,7 +227,6 @@ export class SessionTerminalService extends Disposable implements ISessionTermin this.pushFrame(record, frame); disposeAll(record.disposables); record.disposables = []; - record.lease.dispose(); } private pushFrame(record: TerminalRecord, frame: TerminalFrame): void { @@ -256,6 +250,10 @@ function frameSeq(frame: TerminalFrame): number { return frame.type === 'terminal_output' ? frame.seq : Number.MAX_SAFE_INTEGER; } +function defaultShell(): string { + return process.env['SHELL'] || '/bin/sh'; +} + registerScopedService( LifecycleScope.Session, ISessionTerminalService, diff --git a/packages/agent-core-v2/src/session/todo/sessionTodo.ts b/packages/agent-core-v2/src/session/todo/sessionTodo.ts new file mode 100644 index 000000000..4ebf94cbf --- /dev/null +++ b/packages/agent-core-v2/src/session/todo/sessionTodo.ts @@ -0,0 +1,24 @@ +/** + * `todo` domain — `ISessionTodoService` contract. + * + * The session-shared todo list: an in-memory list materialized from the main + * agent's `tools.update_store` (`key: 'todo'`) wire records, mutated through + * `setTodos` (which appends a fresh `tools.update_store` to the main agent's + * wire), and readable by every agent in the session. Bound at Session scope. + */ + +import { createDecorator } from '#/_base/di/instantiation'; +import type { Event } from '#/_base/event'; + +import type { TodoItem } from './todoItem'; + +export interface ISessionTodoService { + readonly _serviceBrand: undefined; + + getTodos(): readonly TodoItem[]; + setTodos(todos: readonly TodoItem[]): void; + clear(): void; + readonly onDidChange: Event; +} + +export const ISessionTodoService = createDecorator('sessionTodoService'); diff --git a/packages/agent-core-v2/src/session/todo/sessionTodoService.ts b/packages/agent-core-v2/src/session/todo/sessionTodoService.ts new file mode 100644 index 000000000..b5e38602a --- /dev/null +++ b/packages/agent-core-v2/src/session/todo/sessionTodoService.ts @@ -0,0 +1,163 @@ +/** + * `todo` domain — `ISessionTodoService` implementation. + * + * Provides session-wide todo access through the main agent's `wire`, binds + * todo capabilities into each agent, and publishes changes through its typed + * event. The main agent's wire owns the replayable state (including the + * undo-checkpointed `TodoModel`); this facade keeps no list copy of its own + * and there is deliberately no second session-level wire aggregate. Bound at + * Session scope. + */ + +import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; +import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { + type IAgentScopeHandle, + ScopeActivation, + registerScopedService, +} from '#/_base/di/scope'; +import { Emitter } from '#/_base/event'; + +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import { IAgentToolPolicyService } from '#/agent/toolPolicy/toolPolicy'; +import { IEventBus } from '#/app/event/eventBus'; +import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; +import { IWireService } from '#/wire/wire'; + +import { ISessionTodoService } from './sessionTodo'; +import { TodoModel, todoSet } from './todoOps'; +import { TODO_LIST_TOOL_NAME, type TodoItem } from './todoItem'; +import { TODO_LIST_REMINDER_VARIANT, todoListStaleReminder } from './todoListReminder'; + +const MAIN_AGENT_ID = 'main'; + +export class SessionTodoService extends Service implements ISessionTodoService { + declare readonly _serviceBrand: undefined; + + private readonly onDidChangeEmitter = this._register(new Emitter()); + readonly onDidChange = this.onDidChangeEmitter.event; + + private readonly agentBindings = new Map(); + private lastKnownTodos: readonly TodoItem[] = []; + + constructor( + @IAgentLifecycleService private readonly agentLifecycle: IAgentLifecycleService, + ) { + super(); + + this._register( + this.agentLifecycle.onDidCreate((handle) => { + this.bindAgent(handle); + }), + ); + this._register( + this.agentLifecycle.onDidDispose((agentId) => this.disposeAgentBindings(agentId)), + ); + + for (const handle of this.agentLifecycle.list()) { + this.bindAgent(handle); + } + + this._register( + toDisposable(() => { + for (const agentId of Array.from(this.agentBindings.keys())) { + this.disposeAgentBindings(agentId); + } + }), + ); + } + + getTodos(): readonly TodoItem[] { + const main = this.agentLifecycle.get(MAIN_AGENT_ID); + if (main === undefined) return []; + return main.accessor.get(IWireService).getModel(TodoModel).current; + } + + setTodos(todos: readonly TodoItem[]): void { + const next: readonly TodoItem[] = todos.map((todo) => ({ + title: todo.title, + status: todo.status, + })); + this.dispatchTodoSet(next); + } + + clear(): void { + this.setTodos([]); + } + + private dispatchTodoSet(todos: readonly TodoItem[]): void { + const main = this.agentLifecycle.get(MAIN_AGENT_ID); + if (main === undefined) return; + const wire = main.accessor.get(IWireService); + wire.dispatch(todoSet({ key: 'todo', value: todos })); + const current = wire.getModel(TodoModel).current; + this.lastKnownTodos = current; + this.onDidChangeEmitter.fire(current); + } + + private bindAgent(handle: IAgentScopeHandle): void { + const injector = handle.accessor.get(IAgentContextInjectorService); + this.trackAgentBinding( + handle.id, + injector.register(TODO_LIST_REMINDER_VARIANT, () => this.staleReminder(handle)), + ); + if (handle.id !== MAIN_AGENT_ID) return; + + this.lastKnownTodos = handle.accessor.get(IWireService).getModel(TodoModel).current; + this.trackAgentBinding( + handle.id, + handle.accessor.get(IEventBus).subscribe('context.undone', () => { + const current = handle.accessor.get(IWireService).getModel(TodoModel).current; + if (todoItemsEqual(current, this.lastKnownTodos)) return; + this.lastKnownTodos = current; + this.onDidChangeEmitter.fire(current); + }), + ); + } + + private staleReminder(handle: IAgentScopeHandle): string | undefined { + const memory = handle.accessor.get(IAgentContextMemoryService); + const toolPolicy = handle.accessor.get(IAgentToolPolicyService); + return todoListStaleReminder({ + active: toolPolicy.isToolActive(TODO_LIST_TOOL_NAME, 'builtin'), + history: memory.get(), + todos: this.getTodos(), + }); + } + + private trackAgentBinding(agentId: string, disposable: IDisposable): void { + const list = this.agentBindings.get(agentId); + if (list === undefined) { + this.agentBindings.set(agentId, [disposable]); + } else { + list.push(disposable); + } + } + + private disposeAgentBindings(agentId: string): void { + const bindings = this.agentBindings.get(agentId); + if (bindings === undefined) return; + for (const disposable of bindings) { + disposable.dispose(); + } + this.agentBindings.delete(agentId); + if (agentId === MAIN_AGENT_ID) this.lastKnownTodos = []; + } +} + +function todoItemsEqual(a: readonly TodoItem[], b: readonly TodoItem[]): boolean { + return ( + a.length === b.length && + a.every((item, index) => item.title === b[index]?.title && item.status === b[index]?.status) + ); +} + +registerScopedService( + LifecycleScope.Session, + ISessionTodoService, + SessionTodoService, + ScopeActivation.OnScopeCreated, + 'todo', +); diff --git a/packages/agent-core-v2/src/features/todo/todoItem.ts b/packages/agent-core-v2/src/session/todo/todoItem.ts similarity index 85% rename from packages/agent-core-v2/src/features/todo/todoItem.ts rename to packages/agent-core-v2/src/session/todo/todoItem.ts index d8a7f31fe..1b89d5ebc 100644 --- a/packages/agent-core-v2/src/features/todo/todoItem.ts +++ b/packages/agent-core-v2/src/session/todo/todoItem.ts @@ -1,3 +1,11 @@ +/** + * `todo` domain — todo item data shape and pure render helpers. + * + * `TodoItem` / `TodoStatus` are the persistent shape carried by the + * `tools.update_store` (`key: 'todo'`) wire record. Pure and scope-less — no + * scoped state lives here. + */ + export const TODO_LIST_TOOL_NAME = 'TodoList' as const; export type TodoStatus = 'pending' | 'in_progress' | 'done'; diff --git a/packages/agent-core-v2/src/features/todo/todoListReminder.ts b/packages/agent-core-v2/src/session/todo/todoListReminder.ts similarity index 92% rename from packages/agent-core-v2/src/features/todo/todoListReminder.ts rename to packages/agent-core-v2/src/session/todo/todoListReminder.ts index 8f9498ea9..76fe28626 100644 --- a/packages/agent-core-v2/src/features/todo/todoListReminder.ts +++ b/packages/agent-core-v2/src/session/todo/todoListReminder.ts @@ -1,3 +1,11 @@ +/** + * `todo` domain — pure stale-todo reminder logic. + * + * Computes the `todo_list_reminder` context injection from the agent's context + * history (turns since the last `TodoList` write / last reminder) and the + * current session todo list. Pure — no scoped state. + */ + import type { ContextMessage } from '#/agent/contextMemory/types'; import { TODO_LIST_TOOL_NAME, type TodoItem } from './todoItem'; diff --git a/packages/agent-core-v2/src/session/todo/todoOps.ts b/packages/agent-core-v2/src/session/todo/todoOps.ts new file mode 100644 index 000000000..9ae97f02d --- /dev/null +++ b/packages/agent-core-v2/src/session/todo/todoOps.ts @@ -0,0 +1,31 @@ +/** + * `todo` domain — persists the session's shared todo document. + * + * Validates todo state against the item contract and keeps it aligned with + * conversation undo. + */ + +import { z } from 'zod'; + +import { + defineCheckpointedModel, + type Checkpointed, +} from '#/agent/contextMemory/conversationTime'; + +import { readTodoItems, type TodoItem } from './todoItem'; + +export type TodoModelState = Checkpointed; + +export const TodoModel = defineCheckpointedModel('todo', (): readonly TodoItem[] => []); + +declare module '#/wire/types' { + interface PersistedOpMap { + 'tools.update_store': typeof todoSet; + } +} + +export const todoSet = TodoModel.defineOp('tools.update_store', { + schema: z.object({ key: z.string(), value: z.unknown() }), + apply: (s, p) => + p.key === 'todo' ? { ...s, current: readTodoItems(p.value) } : s, +}); diff --git a/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCounting.ts b/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCounting.ts deleted file mode 100644 index 616fac527..000000000 --- a/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCounting.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import type { - ContextSize, - TokenCountingRequest, - TokenCountingStrategy, -} from '#/agent/tokenCounting/tokenCounting'; -import type { Message } from '#/kosong/contract/message'; -import type { Tool } from '#/kosong/contract/tool'; -import type { TokenUsage } from '#/kosong/contract/usage'; - -export interface TokenCountingRebaseInput { - readonly length: number; - readonly tokens: number; - readonly measured: boolean; -} - -export interface ISessionTokenCountingService { - readonly _serviceBrand: undefined; - - readonly strategy: TokenCountingStrategy; - - get(agent: AgentContext, start?: number, end?: number): ContextSize; - measured( - agent: AgentContext, - input: readonly Message[], - output: readonly Message[], - usage: TokenUsage, - ): void; - latestMeasured(agent: AgentContext): number; - statusSize(agent: AgentContext): number; - recordTruncation(agent: AgentContext, cutIndex: number): void; - rebase(agent: AgentContext, input: TokenCountingRebaseInput): void; - requestSize(request: TokenCountingRequest): number; - - estimateText(text: string): number; - estimateMessage(message: Message): number; - estimateMessages(messages: readonly Message[]): number; - estimateTools(tools: readonly Tool[]): number; -} - -export const ISessionTokenCountingService = - createDecorator('sessionTokenCountingService'); diff --git a/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCountingService.ts b/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCountingService.ts deleted file mode 100644 index 2090a04b1..000000000 --- a/packages/agent-core-v2/src/session/tokenCounting/sessionTokenCountingService.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { Disposable } from '#/_base/di/lifecycle'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { agentSpaceOf } from '#/agent/agentContext/agentSpace'; -import { TurnEnded } from '#/agent/loop/turnOps'; -import { IConfigService } from '#/app/config/config'; -import { ISessionEventBus } from '#/app/event/eventBus'; -import { - TOKEN_COUNTING_SECTION, - type TokenCountingConfig, -} from '#/agent/tokenCounting/configSection'; -import type { - ContextSize, - TokenCountingRequest, - TokenCountingStrategy, -} from '#/agent/tokenCounting/tokenCounting'; -import type { Message } from '#/kosong/contract/message'; -import type { Tool } from '#/kosong/contract/tool'; -import { - estimateTokens, - estimateTokensForMessage, - estimateTokensForMessages, - estimateTokensForTools, -} from '#/kosong/contract/tokens'; -import type { TokenUsage } from '#/kosong/contract/usage'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; - -import { - ISessionTokenCountingService, - type TokenCountingRebaseInput, -} from './sessionTokenCounting'; -import { TokenCountingAgentModelDefinition } from './tokenCountingAgentModel'; - -export class SessionTokenCountingService extends Disposable implements ISessionTokenCountingService { - declare readonly _serviceBrand: undefined; - - constructor( - @IConfigService private readonly config: IConfigService, - @ISessionEventBus eventBus: ISessionEventBus, - @IAgentLifecycleService agentLifecycle: IAgentLifecycleService, - ) { - super(); - this._register( - eventBus.subscribe(TurnEnded, (event) => { - const agent = agentLifecycle.get(event.agentId); - if (agent === undefined) return; - void agentSpaceOf(agent).use( - TokenCountingAgentModelDefinition, - (model) => model.recordTurn(event.turnId, this.strategy), - ); - }), - ); - } - - get strategy(): TokenCountingStrategy { - return ( - this.config.get(TOKEN_COUNTING_SECTION)?.strategy ?? - 'measured+estimated' - ); - } - - get(agent: AgentContext, start?: number, end?: number): ContextSize { - return agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.get(start, end), - ); - } - - measured( - agent: AgentContext, - input: readonly Message[], - output: readonly Message[], - usage: TokenUsage, - ): void { - void agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.measured(input, output, usage), - ); - } - - latestMeasured(agent: AgentContext): number { - return agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.latestMeasured(), - ); - } - - statusSize(agent: AgentContext): number { - return agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.statusSize(this.strategy), - ); - } - - recordTruncation(agent: AgentContext, cutIndex: number): void { - void agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.recordTruncation(cutIndex), - ); - } - - rebase(agent: AgentContext, input: TokenCountingRebaseInput): void { - void agentSpaceOf(agent).use(TokenCountingAgentModelDefinition, (model) => - model.rebase(input), - ); - } - - requestSize(request: TokenCountingRequest): number { - return ( - this.estimateText(request.systemPrompt) + - this.estimateTools(request.tools) + - this.estimateMessages(request.messages) - ); - } - - estimateText(text: string): number { - return estimateTokens(text); - } - - estimateMessage(message: Message): number { - return estimateTokensForMessage(message); - } - - estimateMessages(messages: readonly Message[]): number { - return estimateTokensForMessages(messages); - } - - estimateTools(tools: readonly Tool[]): number { - return estimateTokensForTools(tools); - } -} diff --git a/packages/agent-core-v2/src/session/tokenCounting/tokenCountingAgentModel.ts b/packages/agent-core-v2/src/session/tokenCounting/tokenCountingAgentModel.ts deleted file mode 100644 index 3460d9ace..000000000 --- a/packages/agent-core-v2/src/session/tokenCounting/tokenCountingAgentModel.ts +++ /dev/null @@ -1,210 +0,0 @@ -import { z } from 'zod'; - -import { contextMemoryKey } from '#/agent/contextMemory/contextOps'; -import type { ContextMessage } from '#/agent/contextMemory/types'; -import type { ContextSize, TokenCountingStrategy } from '#/agent/tokenCounting/tokenCounting'; -import { - anchorsEqual, - normalizeAnchorLength, - TokenCountingMeasured, - TokenCountingRebased, - TokenCountingTruncated, - TokenCountingTurnRecorded, - type TokenAnchor, - type TokenCountingState, -} from '#/agent/tokenCounting/tokenCountingOps'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import type { Message } from '#/kosong/contract/message'; -import { estimateTokensForMessages } from '#/kosong/contract/tokens'; -import type { TokenUsage } from '#/kosong/contract/usage'; -import { AgentModel, defineAgentModel, type AgentModelContext } from '#/state/agentModel'; - -import type { TokenCountingRebaseInput } from './sessionTokenCounting'; - -const ZERO_ANCHOR: TokenAnchor = { length: 0, tokens: 0, measured: true }; - -export class TokenCountingAgentModel extends AgentModel { - constructor(context: AgentModelContext) { - super(context); - this.on(TokenCountingMeasured, (event) => { - const length = normalizeAnchorLength(event.length); - const tokens = Math.max(0, event.tokens); - const anchor: TokenAnchor = { length, tokens, measured: true }; - const anchors = [...this.state.anchors.filter((a) => a.length < length), anchor]; - if (!(this.state.tokens === tokens && anchorsEqual(this.state.anchors, anchors))) { - this.state.anchors = anchors; - this.state.tokens = tokens; - } - void this.emit( - new AgentStatusUpdated({ agentId: event.agentId, contextTokens: this.state.tokens }), - ); - }); - this.on(TokenCountingTruncated, (event) => { - const length = normalizeAnchorLength(event.length); - const tokens = Math.max(0, event.tokens); - const anchors = this.state.anchors.filter((a) => a.length <= length); - if (!(this.state.tokens === tokens && anchorsEqual(this.state.anchors, anchors))) { - this.state.anchors = anchors; - this.state.tokens = tokens; - } - void this.emit( - new AgentStatusUpdated({ agentId: event.agentId, contextTokens: this.state.tokens }), - ); - }); - this.on(TokenCountingRebased, (event) => { - const length = normalizeAnchorLength(event.length); - const tokens = Math.max(0, event.tokens); - const anchors: TokenAnchor[] = [{ length, tokens, measured: event.measured }]; - if (!(this.state.tokens === tokens && anchorsEqual(this.state.anchors, anchors))) { - this.state.anchors = anchors; - this.state.tokens = tokens; - } - void this.emit( - new AgentStatusUpdated({ agentId: event.agentId, contextTokens: this.state.tokens }), - ); - }); - this.on(TokenCountingTurnRecorded, (event) => { - const length = normalizeAnchorLength(event.length); - const tokens = Math.max(0, event.tokens); - const pinned = this.state.anchors.some((anchor) => anchor.length === length); - const anchors = pinned - ? this.state.anchors - : [ - ...this.state.anchors.filter((anchor) => anchor.length < length), - { length, tokens, measured: false }, - ]; - if (!(this.state.tokens === tokens && anchorsEqual(this.state.anchors, anchors))) { - this.state.anchors = anchors; - this.state.tokens = tokens; - } - void this.emit( - new AgentStatusUpdated({ agentId: event.agentId, contextTokens: this.state.tokens }), - ); - }); - } - - get(start?: number, end?: number): ContextSize { - const context = this.context(); - const from = normalizeSliceIndex(start ?? 0, context.length); - const to = normalizeSliceIndex(end ?? context.length, context.length); - const anchor = this.latestAnchor(context.length); - const measuredEnd = Math.min(to, anchor.length); - const estimatedStart = Math.max(from, anchor.length); - const measured = - from === 0 && measuredEnd === anchor.length - ? anchor.tokens - : estimateTokensForMessages(context.slice(from, measuredEnd)); - const estimated = estimateTokensForMessages(context.slice(estimatedStart, to)); - return { size: measured + estimated, measured, estimated }; - } - - measured( - input: readonly Message[], - _output: readonly Message[], - usage: TokenUsage, - ): Promise { - const context = this.context(); - if (!matchesContext(input, context)) return Promise.resolve(); - return this.emit( - new TokenCountingMeasured({ - agentId: this.agent.agentId, - length: context.length, - tokens: tokenUsageTotal(usage), - }), - ); - } - - latestMeasured(): number { - const anchors = this.state.anchors; - for (let i = anchors.length - 1; i >= 0; i--) { - if (anchors[i]!.measured) return anchors[i]!.tokens; - } - return 0; - } - - statusSize(strategy: TokenCountingStrategy): number { - if (strategy === 'measured') return this.latestMeasured(); - if (strategy === 'estimated') return estimateTokensForMessages(this.context()); - return Math.max(this.get().size, this.latestMeasured()); - } - - recordTruncation(cutIndex: number): Promise { - if (!this.state.anchors.some((anchor) => anchor.length > cutIndex)) { - return Promise.resolve(); - } - return this.emit( - new TokenCountingTruncated({ - agentId: this.agent.agentId, - length: cutIndex, - tokens: this.get(0, cutIndex).size, - }), - ); - } - - rebase(input: TokenCountingRebaseInput): Promise { - return this.emit( - new TokenCountingRebased({ - agentId: this.agent.agentId, - length: input.length, - tokens: input.tokens, - measured: input.measured, - }), - ); - } - - recordTurn(turnId: number, strategy: TokenCountingStrategy): Promise { - return this.emit( - new TokenCountingTurnRecorded({ - agentId: this.agent.agentId, - turnId, - length: this.context().length, - tokens: this.statusSize(strategy), - }), - ); - } - - private context(): readonly ContextMessage[] { - return this.readLegacy(contextMemoryKey) as readonly ContextMessage[]; - } - - private latestAnchor(contextLength: number): TokenAnchor { - const anchors = this.state.anchors; - for (let i = anchors.length - 1; i >= 0; i--) { - const anchor = anchors[i]!; - if (anchor.length <= contextLength) return anchor; - } - return ZERO_ANCHOR; - } -} - -export const TokenCountingAgentModelDefinition = defineAgentModel({ - id: 'tokenCounting', - model: TokenCountingAgentModel, - state: { - initial: (): TokenCountingState => ({ anchors: [], tokens: 0 }), - schema: z.custom(), - }, - events: [ - TokenCountingMeasured, - TokenCountingTruncated, - TokenCountingRebased, - TokenCountingTurnRecorded, - ], -}); - -function matchesContext(input: readonly Message[], context: readonly ContextMessage[]): boolean { - if (input.length !== context.length) return false; - for (let index = 0; index < input.length; index += 1) { - if (input[index] !== context[index]) return false; - } - return true; -} - -function tokenUsageTotal(usage: TokenUsage): number { - return usage.inputCacheRead + usage.inputCacheCreation + usage.inputOther + usage.output; -} - -function normalizeSliceIndex(index: number, length: number): number { - if (index < 0) return Math.max(length + index, 0); - return Math.min(index, length); -} diff --git a/packages/agent-core-v2/src/session/usage/sessionUsage.ts b/packages/agent-core-v2/src/session/usage/sessionUsage.ts deleted file mode 100644 index 37a8931ec..000000000 --- a/packages/agent-core-v2/src/session/usage/sessionUsage.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { createDecorator } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import type { AgentLLMRequestSource } from '#/agent/llmRequester/llmRequester'; -import type { UsageRecordedContext, UsageStatus } from '#/agent/usage/usage'; -import type { TokenUsage } from '#/kosong/contract/usage'; - -export interface ISessionUsageService { - readonly _serviceBrand: undefined; - - record( - agent: AgentContext, - model: string, - usage: TokenUsage, - source?: AgentLLMRequestSource, - ): Promise; - status(agent: AgentContext): UsageStatus; - - readonly onDidRecord: Event; -} - -export const ISessionUsageService = createDecorator('sessionUsageService'); diff --git a/packages/agent-core-v2/src/session/usage/sessionUsageService.ts b/packages/agent-core-v2/src/session/usage/sessionUsageService.ts deleted file mode 100644 index 1f20331ea..000000000 --- a/packages/agent-core-v2/src/session/usage/sessionUsageService.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Service } from '#/_base/di/service'; -import { Emitter, type Event } from '#/_base/event'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { agentSpaceOf } from '#/agent/agentContext/agentSpace'; -import type { AgentLLMRequestSource } from '#/agent/llmRequester/llmRequester'; -import type { UsageRecordedContext, UsageStatus } from '#/agent/usage/usage'; -import { copyUsage } from '#/agent/usage/usageOps'; -import type { TokenUsage } from '#/kosong/contract/usage'; - -import { ISessionUsageService } from './sessionUsage'; -import { UsageAgentModelDefinition } from './usageAgentModel'; - -export class SessionUsageService extends Service implements ISessionUsageService { - declare readonly _serviceBrand: undefined; - - private readonly onDidRecordEmitter = this._register(new Emitter()); - readonly onDidRecord: Event = this.onDidRecordEmitter.event; - - async record( - agent: AgentContext, - model: string, - usage: TokenUsage, - source?: AgentLLMRequestSource, - ): Promise { - const firstRecord = await agentSpaceOf(agent).use(UsageAgentModelDefinition, (m) => - m.record({ model, usage, source }), - ); - this.onDidRecordEmitter.fire({ agent, model, usage: copyUsage(usage), source, firstRecord }); - } - - status(agent: AgentContext): UsageStatus { - return agentSpaceOf(agent).use(UsageAgentModelDefinition, (m) => m.status()); - } -} diff --git a/packages/agent-core-v2/src/session/usage/usageAgentModel.ts b/packages/agent-core-v2/src/session/usage/usageAgentModel.ts deleted file mode 100644 index 60924e96d..000000000 --- a/packages/agent-core-v2/src/session/usage/usageAgentModel.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { z } from 'zod'; - -import type { AgentLLMRequestSource } from '#/agent/llmRequester/llmRequester'; -import type { UsageStatus } from '#/agent/usage/usage'; -import { AgentStatusUpdated } from '#/agent/usage/usageEvents'; -import { - copyUsage, - UsageRecord, - type UsageModelState, - type UsageRecordScope, -} from '#/agent/usage/usageOps'; -import { addUsage, type TokenUsage } from '#/kosong/contract/usage'; -import { AgentModel, defineAgentModel, type AgentModelContext } from '#/state/agentModel'; - -export interface UsageRecordInput { - readonly model: string; - readonly usage: TokenUsage; - readonly source?: AgentLLMRequestSource; -} - -export class UsageAgentModel extends AgentModel { - private currentTurnId: number | undefined; - private currentTurn: TokenUsage | undefined; - - constructor(context: AgentModelContext) { - super(context); - this.on(UsageRecord, (event) => { - const current = this.state.byModel[event.model]; - this.state.byModel[event.model] = - current === undefined ? copyUsage(event.usage) : addUsage(current, event.usage); - }); - } - - record(input: UsageRecordInput): Promise { - const firstRecord = Object.keys(this.state.byModel).length === 0; - const usageScope: UsageRecordScope = input.source?.type === 'turn' ? 'turn' : 'session'; - const recorded = this.emit( - new UsageRecord({ - agentId: this.agent.agentId, - model: input.model, - usage: input.usage, - usageScope, - }), - ); - const turnId = input.source?.type === 'turn' ? input.source.turnId : undefined; - if (turnId !== undefined) { - if (this.currentTurnId !== turnId) { - this.currentTurnId = turnId; - this.currentTurn = copyUsage(input.usage); - } else { - this.currentTurn = - this.currentTurn === undefined - ? copyUsage(input.usage) - : addUsage(this.currentTurn, input.usage); - } - } - const notified = this.emit( - new AgentStatusUpdated({ agentId: this.agent.agentId, usage: this.status() }), - ); - return recorded.then(() => notified).then(() => firstRecord); - } - - status(): UsageStatus { - const byModel = Object.fromEntries( - Object.entries(this.state.byModel).map(([model, usage]) => [model, copyUsage(usage)]), - ); - const hasByModel = Object.keys(byModel).length > 0; - let total: TokenUsage | undefined; - if (hasByModel) { - for (const usage of Object.values(byModel)) { - total = total === undefined ? copyUsage(usage) : addUsage(total, usage); - } - } - return { - byModel: hasByModel ? byModel : undefined, - total, - currentTurn: this.currentTurn === undefined ? undefined : copyUsage(this.currentTurn), - }; - } -} - -export const UsageAgentModelDefinition = defineAgentModel({ - id: 'usage', - model: UsageAgentModel, - state: { - initial: (): UsageModelState => ({ byModel: {} }), - schema: z.custom(), - }, - events: [UsageRecord], -}); diff --git a/packages/agent-core-v2/src/session/workspaceContext/workspaceContext.ts b/packages/agent-core-v2/src/session/workspaceContext/workspaceContext.ts index aa330b491..05a81ff7d 100644 --- a/packages/agent-core-v2/src/session/workspaceContext/workspaceContext.ts +++ b/packages/agent-core-v2/src/session/workspaceContext/workspaceContext.ts @@ -1,3 +1,15 @@ +/** + * `workspaceContext` domain — session workspace root and path access. + * + * Defines the `ISessionWorkspaceContext` used by the Agent side to resolve relative + * paths against the session work directory and to enforce that file/process + * operations stay within the workspace (plus any additional dirs). The view is + * read-only: `workDir` is fixed at session creation; `additionalDirs` mirrors + * the handler-shared set and refreshes when the workspace-level add-dir + * surface changes it. Pure configuration + boundary — it performs no IO. + * Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export type PathAccessOperation = 'read' | 'write' | 'execute'; diff --git a/packages/agent-core-v2/src/session/workspaceContext/workspaceContextService.ts b/packages/agent-core-v2/src/session/workspaceContext/workspaceContextService.ts index 0af648312..3336ac0fd 100644 --- a/packages/agent-core-v2/src/session/workspaceContext/workspaceContextService.ts +++ b/packages/agent-core-v2/src/session/workspaceContext/workspaceContextService.ts @@ -1,9 +1,21 @@ +/** + * `workspaceContext` domain — `ISessionWorkspaceContext` implementation. + * + * Holds the session work directory and additional dirs, resolves relative + * paths, and checks whether a path falls within the workspace. `workDir` is + * frozen at construction (`cwd`); the + * additional dirs are a live read view over the handler-shared set, refreshed + * through the seed's change event. The plain-data state (`workDir`, + * `additionalDirs`) is registered into the session-state container and read + * through it. Bound at Session scope. + */ + import { isAbsolute, relative, resolve } from 'node:path'; import { Service } from '#/_base/di/service'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { ErrorCodes, Error2 } from '#/errors'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { ISessionStateService } from '#/session/state/sessionState'; @@ -26,8 +38,8 @@ export class SessionWorkspaceContextService extends Service implements ISessionW @ISessionWorkspaceInfo workspaceInfo: ISessionWorkspaceInfo, ) { super(); - this.states.contributeState(workspaceContextWorkDirKey); - this.states.contributeState(workspaceContextAdditionalDirsKey); + this.states.register(workspaceContextWorkDirKey); + this.states.register(workspaceContextAdditionalDirsKey); this.states.set(workspaceContextWorkDirKey, resolve(ctx.cwd)); this.states.set(workspaceContextAdditionalDirsKey, [ ...new Set(workspaceInfo.additionalDirs.map((d) => resolve(d))), diff --git a/packages/agent-core-v2/src/session/workspaceInfo/workspaceInfo.ts b/packages/agent-core-v2/src/session/workspaceInfo/workspaceInfo.ts index e8fecf06c..ca979667c 100644 --- a/packages/agent-core-v2/src/session/workspaceInfo/workspaceInfo.ts +++ b/packages/agent-core-v2/src/session/workspaceInfo/workspaceInfo.ts @@ -1,3 +1,13 @@ +/** + * `workspaceInfo` domain — seeded workspace-directory data contract. + * + * Defines `ISessionWorkspaceInfo`, the pure-data injection contract for the + * workspace's additional directory set: a live read view plus its change + * event. The contract carries no IO — persistence, caller-dir merging and + * file watching all live on the workspace side. Seeded into the Session + * scope when the session is materialized. Session-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/state/agentModel.ts b/packages/agent-core-v2/src/state/agentModel.ts deleted file mode 100644 index fb51c3d87..000000000 --- a/packages/agent-core-v2/src/state/agentModel.ts +++ /dev/null @@ -1,196 +0,0 @@ -import type { z } from 'zod'; -import type { Draft } from 'immer'; - -import { collection } from '#/_base/di/collection'; -import { BugIndicatingError } from '#/_base/errors/errors'; -import type { StateKey } from '#/_base/state/stateRegistry'; -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { registerEvent2Class, type Event2, type Event2Class } from '#/app/event/event2'; - -import type { FoldContext } from './state'; - -export interface DomainResourceRuntime { - dispose(): void | Promise; - abort?(reason?: unknown): void; -} - -export interface AgentModelBridge { - dispatch(event: Event2): Promise; - readLegacy(key: StateKey): unknown; - initialState(): unknown; -} - -export interface AgentModelContext { - readonly agent: AgentContext; - readonly bridge: AgentModelBridge; -} - -interface ModelWindow { - readonly draft: unknown; - readonly ctx: FoldContext; - replaced: boolean; - replacement: unknown; -} - -export abstract class AgentModel implements DomainResourceRuntime { - private committedState: S; - private window: ModelWindow | undefined; - private readonly appliers = new Map, (event: any) => void>(); - private sealed = false; - - readonly agent: AgentContext; - private readonly bridge: AgentModelBridge; - - constructor(context: AgentModelContext) { - this.agent = context.agent; - this.bridge = context.bridge; - this.committedState = context.bridge.initialState() as S; - } - - protected get state(): Draft { - const window = this.window; - return (window !== undefined ? window.draft : this.committedState) as Draft; - } - - protected set state(value: S) { - if (this.window === undefined) { - throw new BugIndicatingError( - `Model '${this.constructor.name}' can only replace state inside an applier`, - ); - } - this.window.replaced = true; - this.window.replacement = value; - } - - protected on>(cls: Event2Class, applier: (event: E) => void): void { - if (this.sealed) { - throw new BugIndicatingError( - `Model '${this.constructor.name}' cannot register appliers after construction`, - ); - } - if (this.appliers.has(cls)) { - throw new BugIndicatingError( - `Model '${this.constructor.name}' already applies event '${cls.type}'`, - ); - } - this.appliers.set(cls, applier as (event: any) => void); - } - - protected emit(event: Event2): Promise { - const window = this.window; - if (window !== undefined) { - window.ctx.emit(event); - return Promise.resolve(); - } - return this.bridge.dispatch(event); - } - - protected readLegacy(key: StateKey): T { - return this.bridge.readLegacy(key) as T; - } - - onUndo?(count: number): void; - - dispose(): void | Promise {} - - _seal(): void { - this.sealed = true; - } - - _appliersTable(): ReadonlyMap, (event: any) => void> { - return this.appliers; - } - - _state(): S { - return this.committedState; - } - - _commitState(next: S): void { - this.committedState = next; - } - - _enterWindow(draft: S, ctx: FoldContext): void { - this.window = { draft, ctx, replaced: false, replacement: undefined }; - } - - _exitWindow(): { readonly replaced: boolean; readonly replacement: unknown } { - const window = this.window; - this.window = undefined; - return { replaced: window?.replaced ?? false, replacement: window?.replacement }; - } -} - -export interface AgentModelStateSpec { - readonly initial: () => S; - readonly schema: z.ZodType; -} - -export interface AgentModelDefinition = AgentModel> { - readonly id: string; - readonly model: new (context: AgentModelContext) => M; - readonly state: AgentModelStateSpec; - readonly events: readonly Event2Class[]; - readonly undoable: boolean; -} - -export interface AgentModelDefinitionInput> { - readonly id: string; - readonly model: new (context: AgentModelContext) => M; - readonly state: AgentModelStateSpec; - readonly events: readonly Event2Class[]; - readonly undoable?: boolean; -} - -const AGENT_MODEL_DEFINITIONS = new Map>(); - -export function defineAgentModel>( - input: AgentModelDefinitionInput, -): AgentModelDefinition { - if (AGENT_MODEL_DEFINITIONS.has(input.id)) { - throw new BugIndicatingError(`Agent model '${input.id}' is already defined`); - } - for (const cls of input.events) { - if (!cls.durable) { - throw new BugIndicatingError( - `Agent model '${input.id}' cannot apply non-durable event '${cls.type}'`, - ); - } - registerEvent2Class(cls); - } - const definition: AgentModelDefinition = Object.freeze({ - id: input.id, - model: input.model, - state: input.state, - events: Object.freeze([...input.events]), - undoable: input.undoable ?? false, - }); - AGENT_MODEL_DEFINITIONS.set(definition.id, definition); - return definition; -} - -export function agentModelDefinitions(): readonly AgentModelDefinition[] { - return [...AGENT_MODEL_DEFINITIONS.values()]; -} - -export const AgentModelContribution = collection>('agent-model', { - validate: (value, existing) => { - if (existing.some((definition) => definition.id === value.id)) { - throw new Error(`Agent model '${value.id}' already has an active provider`); - } - }, -}); - -export interface SessionModelDefinition { - readonly id: string; - readonly state: AgentModelStateSpec; - readonly events: readonly Event2Class[]; - readonly undoable: boolean; -} - -export const SessionModelContribution = collection('session-model', { - validate: (value, existing) => { - if (existing.some((definition) => definition.id === value.id)) { - throw new Error(`Session model '${value.id}' already has an active provider`); - } - }, -}); diff --git a/packages/agent-core-v2/src/state/errors.ts b/packages/agent-core-v2/src/state/errors.ts deleted file mode 100644 index eb2384c54..000000000 --- a/packages/agent-core-v2/src/state/errors.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; -import { Error2, type Error2Options } from '#/_base/errors/errors'; - -export const StateErrors = { - codes: { - STATE_DUPLICATE_FOLD: 'state.duplicate_fold', - STATE_DURABILITY_MISMATCH: 'state.durability_mismatch', - STATE_CYCLE: 'state.cycle', - }, - info: { - 'state.duplicate_fold': { - title: 'Duplicate state fold', - retryable: false, - public: true, - action: 'A state registered two folds for the same event; merge them.', - }, - 'state.durability_mismatch': { - title: 'Transient state folds durable event', - retryable: false, - public: true, - action: 'A non-durable state cannot fold a durable event; mark the state durable.', - }, - 'state.cycle': { - title: 'Event dispatch cycle', - retryable: false, - public: true, - action: 'A subscriber re-dispatches endlessly; break the event cycle.', - }, - }, -} as const satisfies ErrorDomain; - -registerErrorDomain(StateErrors); - -export type StateErrorCode = (typeof StateErrors.codes)[keyof typeof StateErrors.codes]; - -export class StateError extends Error2 { - constructor(code: StateErrorCode, message: string, options?: Error2Options) { - super(code, message, options); - this.name = 'StateError'; - } -} diff --git a/packages/agent-core-v2/src/state/eventDispatcher.ts b/packages/agent-core-v2/src/state/eventDispatcher.ts deleted file mode 100644 index caecbe00c..000000000 --- a/packages/agent-core-v2/src/state/eventDispatcher.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { IDisposable } from '#/_base/di/lifecycle'; -import type { DurableAgentRuntimeParticipant } from '#/agent/runtime/agentRuntime'; -import type { Event2 } from '#/app/event/event2'; -import type { Hooks } from '#/hooks'; - -import type { PatchEntry, ReplayableStateKey } from './state'; - -export type EventDispatcherHooks = { - readonly onDidRestore: Record; -}; - -export interface ModelCheckpointDepth { - readonly id: string; - readonly depth: number; -} - -export interface DurableRuntimeParticipantHost { - attach(participant: DurableAgentRuntimeParticipant): IDisposable; -} - -export interface IEventDispatcher extends DurableRuntimeParticipantHost { - readonly _serviceBrand: undefined; - - readonly hooks: Hooks; - - dispatch(event: Event2): Promise; - history(key: ReplayableStateKey): readonly PatchEntry[]; - checkpointDepth(key: ReplayableStateKey): number; - modelCheckpointDepths(): readonly ModelCheckpointDepth[]; - undo(key: ReplayableStateKey, patchId: number): void; - restore(): Promise; - flush(): Promise; -} - -export const IEventDispatcher: ServiceIdentifier = - createDecorator('eventDispatcher'); diff --git a/packages/agent-core-v2/src/state/eventDispatcherService.ts b/packages/agent-core-v2/src/state/eventDispatcherService.ts deleted file mode 100644 index 345e02837..000000000 --- a/packages/agent-core-v2/src/state/eventDispatcherService.ts +++ /dev/null @@ -1,797 +0,0 @@ -import { applyPatches, produceWithPatches } from 'immer'; - -import { BugIndicatingError } from '#/_base/errors/errors'; -import { onUnexpectedError } from '#/_base/errors/unexpectedError'; -import { Service } from '#/_base/di/service'; -import { toDisposable, type IDisposable } from '#/_base/di/lifecycle'; -import { type CollectionView } from '#/_base/di/collection'; -import { LifecycleScope } from '#/app/scopes'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { AgentSpaceImpl, type AgentSpaceHost } from '#/agent/agentContext/agentSpace'; -import { IAgentBlobService } from '#/agent/blob/agentBlobService'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; -import { type DurableAgentRuntimeParticipant } from '#/agent/runtime/agentRuntime'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { - event2FromRecord, - type AgentDomainTrait, - type Event2, - type Event2Class, -} from '#/app/event/event2'; -import { IEventBus } from '#/app/event/eventBus'; -import type { ContentPart } from '#/kosong/contract/message'; -import { OrderedHookSlot } from '#/hooks'; -import { IWireService } from '#/wire/wire'; -import { WireError, WireErrors } from '#/wire/errors'; -import type { PartsTransformer } from '#/wire/record'; - -import { - AgentModelContribution, - agentModelDefinitions, - type AgentModel, - type AgentModelDefinition, -} from './agentModel'; -import { IEventDispatcher, type ModelCheckpointDepth } from './eventDispatcher'; -import { StateError, StateErrors } from './errors'; -import { - expandedModelAppliers, - expandedRuntimeFolds, - keepsUndoCheckpoints, - type EventApplier, - type StateFold, - type FoldContext, - type PatchEntry, - type ReplayableStateKey, -} from './state'; -import { - EventStateContribution, - foldEventStateContributions, - type EventStateContributionRecord, - type FoldedEventStateRegistry, -} from './stateContribution'; - -const MAX_DRAIN = 100; -const HISTORY_TAIL = 500; - -export class CycleError extends StateError { - constructor(readonly depth: number, readonly eventTypes: readonly string[]) { - super( - StateErrors.codes.STATE_CYCLE, - `Event dispatch cascade exceeded MAX_DRAIN (${depth}); possible event cycle`, - { details: { depth, eventTypes: eventTypes.slice(0, 20) } }, - ); - this.name = 'CycleError'; - } -} - -interface StateMeta { - history: PatchEntry[]; - checkpoints: number[]; - nextPatchId: number; -} - -interface QueuedEvent { - readonly event: Event2; - readonly resolve: () => void; - readonly reject: (error: unknown) => void; -} - -interface PreparedFold { - readonly key: ReplayableStateKey; - readonly meta: StateMeta; - readonly ctx: FoldContextImpl; - readonly next: any; - readonly patches: PatchEntry['patches']; - readonly inversePatches: PatchEntry['inversePatches']; -} - -type ParticipantApplier = ( - state: any, - event: Event2, - ctx: FoldContextImpl, -) => unknown; - -interface ParticipantAttachment { - readonly id: string; - readonly appliers: ReadonlyMap, ParticipantApplier>; - readonly meta: StateMeta; - readonly undoable: boolean; - readonly keepsCheckpoints: boolean; - readonly getState: () => any; - readonly commit: (state: any) => void; -} - -interface PreparedParticipant { - readonly attachment: ParticipantAttachment; - readonly ctx: FoldContextImpl; - readonly next: any; - readonly patches: PatchEntry['patches']; - readonly inversePatches: PatchEntry['inversePatches']; -} - -type RestorePhase = 'new' | 'restoring' | 'ready' | 'failed'; - -class FoldContextImpl implements FoldContext { - pendingCheckpoint = false; - pendingClear = false; - pendingUndo: number | undefined; - - constructor( - private readonly owner: EventDispatcherService, - readonly silent: boolean, - ) {} - - checkpoint(): void { - this.pendingCheckpoint = true; - } - - clearCheckpoints(): void { - this.pendingClear = true; - } - - undoToCheckpoint(count: number): void { - this.pendingUndo = count; - } - - emit(event: Event2): void { - if (this.silent) return; - this.owner.enqueue(event); - } -} - -function sanitizePendingUndo(ctx: FoldContextImpl, meta: StateMeta): void { - if ( - ctx.pendingUndo !== undefined && - (!Number.isSafeInteger(ctx.pendingUndo) || - ctx.pendingUndo <= 0 || - meta.checkpoints.length < ctx.pendingUndo) - ) { - ctx.pendingUndo = undefined; - } -} - -export class EventDispatcherService extends Service implements IEventDispatcher { - declare readonly _serviceBrand: undefined; - - readonly hooks: IEventDispatcher['hooks'] = { - onDidRestore: new OrderedHookSlot(), - }; - - private readonly metas = new Map, StateMeta>(); - private folded: FoldedEventStateRegistry; - - private activeModelDefs = new Map>(); - private readonly withdrawnModelIds = new Set(); - private modelTargets = new Map[]>(); - private readonly modelAttachments = new Map< - AgentModelDefinition, - ParticipantAttachment - >(); - private readonly participantTargets = new Map(); - private readonly participantAttachments = new Map(); - - private readonly spaceHost: AgentSpaceHost = { - isActiveModelDefinition: (definition) => - this.activeModelDefs.get(definition.id) === definition, - registerModel: (definition, model) => this.registerModel(definition, model), - dispatchModelEvent: (event) => this.dispatch(event), - readLegacyState: (key) => this.agentState.get(key), - }; - - private restorePhase: RestorePhase = 'new'; - private dispatching = false; - private disposed = false; - private queue: QueuedEvent[] = []; - private drainDepth = 0; - - constructor( - @IWireService private readonly wire: IWireService, - @IEventBus private readonly eventBus: IEventBus, - @IAgentScopeContext private readonly agentScope: IAgentScopeContext | undefined, - @IAgentBlobService private readonly blobService: IAgentBlobService, - @IAgentStateService private readonly agentState: IAgentStateService, - @EventStateContribution view: CollectionView, - @AgentModelContribution modelView: CollectionView>, - ) { - super(); - this.folded = this.foldContributions(view); - this._register( - view.onDidChange(() => { - this.folded = this.foldContributions(view); - }), - ); - this._register( - this.agentState.onDidContributeReplayable((key) => { - if (this.restorePhase !== 'new') { - throw new BugIndicatingError( - `Replayable state '${key.name}' contributed while the event dispatcher is in phase '${this.restorePhase}'; replayable state owners must contribute before restore`, - ); - } - this.folded = this.foldContributions(view); - }), - ); - this._register( - this.agentState.onDidWithdrawReplayable((key) => { - this.metas.delete(key); - this.folded = this.foldContributions(view); - }), - ); - this.refoldModels(modelView.items); - this._register( - modelView.onDidChange(({ added, removed }) => { - for (const definition of removed) { - this.withdrawnModelIds.add(definition.id); - const attachment = this.modelAttachments.get(definition); - if (attachment !== undefined) { - this.modelAttachments.delete(definition); - this.detachParticipant(attachment); - this.space()?.retireModel(definition); - } - } - for (const definition of added) { - this.withdrawnModelIds.delete(definition.id); - } - this.refoldModels(modelView.items); - this.materializeUndoableModels(); - }), - ); - this.space()?._attachHost(this.spaceHost); - this.materializeUndoableModels(); - } - - private space(): AgentSpaceImpl | undefined { - const space = this.agentScope?.agentContext.space; - return space instanceof AgentSpaceImpl ? space : undefined; - } - - private foldContributions( - view: CollectionView, - ): FoldedEventStateRegistry { - return foldEventStateContributions(view.items, this.agentState.replayableKeys()); - } - - attach(participant: DurableAgentRuntimeParticipant): IDisposable { - if (this.restorePhase !== 'new') { - throw new BugIndicatingError( - `Agent runtime participant '${participant.id}' attached while the event dispatcher is in phase '${this.restorePhase}'; durable runtime owners must attach before restore`, - ); - } - const base = new Map, StateFold>(); - for (const cls of participant.events) base.set(cls, participant.transition); - const folds = expandedRuntimeFolds(participant.id, participant.undoable, base); - const appliers = new Map, ParticipantApplier>(); - for (const [cls, fold] of folds) { - appliers.set(cls, (state, event, ctx) => fold(state, event, ctx)); - } - const attachment: ParticipantAttachment = { - id: participant.id, - appliers, - meta: { history: [], checkpoints: [], nextPatchId: 1 }, - undoable: participant.undoable, - keepsCheckpoints: participant.undoable, - getState: () => participant.getState(), - commit: (state) => { participant.commit(state); }, - }; - this.attachParticipant(attachment); - return toDisposable(() => { this.detachParticipant(attachment); }); - } - - private attachParticipant(attachment: ParticipantAttachment): void { - if (this.participantAttachments.has(attachment.id)) { - throw new BugIndicatingError(`Durable participant '${attachment.id}' is already attached`); - } - this.participantAttachments.set(attachment.id, attachment); - for (const cls of attachment.appliers.keys()) { - const list = this.participantTargets.get(cls.type) ?? []; - list.push(attachment); - this.participantTargets.set(cls.type, list); - } - } - - private detachParticipant(attachment: ParticipantAttachment): void { - if (this.participantAttachments.get(attachment.id) !== attachment) return; - this.participantAttachments.delete(attachment.id); - for (const cls of attachment.appliers.keys()) { - const list = this.participantTargets.get(cls.type); - if (list === undefined) continue; - const next = list.filter((candidate) => candidate !== attachment); - if (next.length === 0) this.participantTargets.delete(cls.type); - else this.participantTargets.set(cls.type, next); - } - } - - private refoldModels(records: readonly AgentModelDefinition[]): void { - const defs = new Map>(); - for (const definition of agentModelDefinitions()) { - if (!this.withdrawnModelIds.has(definition.id)) defs.set(definition.id, definition); - } - for (const definition of records) defs.set(definition.id, definition); - this.activeModelDefs = defs; - this.rebuildModelTargets(); - } - - private rebuildModelTargets(): void { - const targets = new Map[]>(); - const add = (type: string, definition: AgentModelDefinition): void => { - const list = targets.get(type); - if (list === undefined) { - targets.set(type, [definition]); - return; - } - if (!list.includes(definition)) list.push(definition); - }; - const domainOwners = new Map>(); - for (const definition of this.activeModelDefs.values()) { - for (const cls of definition.events) { - const owner = domainOwners.get(cls.type); - if (owner !== undefined && owner !== definition) { - throw new BugIndicatingError( - `Event '${cls.type}' is applied by both agent models '${owner.id}' and '${definition.id}'`, - ); - } - domainOwners.set(cls.type, definition); - add(cls.type, definition); - } - } - for (const [definition, attachment] of this.modelAttachments) { - if (this.activeModelDefs.get(definition.id) !== definition) continue; - for (const cls of attachment.appliers.keys()) add(cls.type, definition); - } - this.modelTargets = targets; - } - - private materializeUndoableModels(): void { - const space = this.space(); - if (space === undefined) return; - for (const definition of this.activeModelDefs.values()) { - if (!definition.undoable || this.modelAttachments.has(definition)) continue; - space.ensureModel(definition); - } - } - - private registerModel( - definition: AgentModelDefinition, - model: AgentModel, - ): void { - if (this.modelAttachments.has(definition)) return; - const domainAppliers = new Map, EventApplier>(); - for (const [cls, applier] of model._appliersTable()) { - domainAppliers.set(cls, (event) => applier.call(model, event)); - } - const customUndo = - model.onUndo === undefined ? undefined : (count: number): void => model.onUndo!(count); - const expanded = expandedModelAppliers( - definition.id, - definition.undoable, - domainAppliers, - customUndo, - ); - const appliers = new Map, ParticipantApplier>(); - for (const [cls, applier] of expanded) { - appliers.set(cls, (state, event, ctx) => { - model._enterWindow(state, ctx); - let windowResult: ReturnType['_exitWindow']>; - try { - applier(event, ctx); - } finally { - windowResult = model._exitWindow(); - } - return windowResult.replaced ? windowResult.replacement : undefined; - }); - } - const attachment: ParticipantAttachment = { - id: definition.id, - appliers, - meta: { history: [], checkpoints: [], nextPatchId: 1 }, - undoable: definition.undoable, - keepsCheckpoints: definition.undoable && customUndo === undefined, - getState: () => model._state(), - commit: (state) => { model._commitState(state); }, - }; - this.attachParticipant(attachment); - this.modelAttachments.set(definition, attachment); - this.rebuildModelTargets(); - } - - private materializeModel(definition: AgentModelDefinition): ParticipantAttachment { - const space = this.space(); - if (space === undefined) { - throw new BugIndicatingError( - `Agent model '${definition.id}' cannot materialize without an agent space`, - ); - } - space.ensureModel(definition); - const attachment = this.modelAttachments.get(definition); - if (attachment === undefined) { - throw new BugIndicatingError(`Agent model '${definition.id}' failed to attach`); - } - return attachment; - } - - history(key: ReplayableStateKey): readonly PatchEntry[] { - return this.ensureMeta(key).history; - } - - checkpointDepth(key: ReplayableStateKey): number { - const meta = this.metas.get(key); - return meta?.checkpoints.length ?? 0; - } - - modelCheckpointDepths(): readonly ModelCheckpointDepth[] { - const depths: ModelCheckpointDepth[] = []; - for (const attachment of this.participantAttachments.values()) { - if (!attachment.keepsCheckpoints) continue; - depths.push({ id: attachment.id, depth: attachment.meta.checkpoints.length }); - } - return depths; - } - - undo(key: ReplayableStateKey, patchId: number): void { - const meta = this.ensureMeta(key); - const head = meta.history.at(-1); - if (head === undefined || patchId > head.id || patchId <= 0) { - throw new BugIndicatingError( - `undo patch id ${patchId} is outside the retained history of state '${key.name}'`, - ); - } - const firstRetained = meta.history[0]!.id; - if (patchId < firstRetained) { - throw new BugIndicatingError( - `undo patch id ${patchId} has been trimmed from the history of state '${key.name}'`, - ); - } - this.rollback(key, meta, patchId - 1); - meta.checkpoints = meta.checkpoints.filter((id) => id < patchId); - } - - dispatch(event: Event2): Promise { - const cls = event.constructor as Event2Class; - if ( - cls.agentDomain && - (this.agentScope === undefined || - (event as Event2 & AgentDomainTrait).agentId !== this.agentScope.agentId) - ) { - return Promise.reject( - new Error(`Agent event '${event.type}' does not match dispatcher lifecycle context`), - ); - } - if (this.dispatching) { - return new Promise((resolve, reject) => { - this.queue.push({ event, resolve, reject }); - }); - } - this.dispatching = true; - try { - this.runDispatch(event); - while (this.queue.length > 0) { - if (++this.drainDepth > MAX_DRAIN) { - throw new CycleError( - this.drainDepth, - this.queue.map((entry) => entry.event.type), - ); - } - const entry = this.queue.shift()!; - try { - this.runDispatch(entry.event); - entry.resolve(); - } catch (error) { - entry.reject(error); - throw error; - } - } - return Promise.resolve(); - } catch (error) { - for (const entry of this.queue.splice(0)) { - entry.reject(error); - } - return Promise.reject(error); - } finally { - this.queue.length = 0; - this.dispatching = false; - this.drainDepth = 0; - } - } - - enqueue(event: Event2): void { - this.queue.push({ - event, - resolve: () => {}, - reject: (error: unknown) => onUnexpectedError(error), - }); - } - - private runDispatch(event: Event2): void { - this.executeEvent(event, false); - } - - private executeEvent(event: Event2, silent: boolean): void { - const folds = this.folded.folds.get(event.type); - const prepared: PreparedFold[] = []; - if (folds !== undefined) { - for (const { key, fold } of folds) { - const meta = this.ensureMeta(key); - const ctx = new FoldContextImpl(this, silent); - const [next, patches, inversePatches] = produceWithPatches( - this.agentState.get(key), - (draft: any) => fold(draft, event, ctx) as any, - ); - if (ctx.pendingUndo !== undefined && patches.length > 0) { - throw new BugIndicatingError( - `Fold of event '${event.type}' on state '${key.name}' both mutates and undoes to a checkpoint`, - ); - } - sanitizePendingUndo(ctx, meta); - prepared.push({ key, meta, ctx, next, patches, inversePatches }); - } - } - const modelTargets = this.modelTargets.get(event.type); - if (modelTargets !== undefined) { - for (const definition of modelTargets) { - if (!this.modelAttachments.has(definition)) this.materializeModel(definition); - } - } - const participantTargets = this.participantTargets.get(event.type); - const preparedParticipants: PreparedParticipant[] = []; - if (participantTargets !== undefined) { - for (const attachment of participantTargets) { - const applier = attachment.appliers.get(event.constructor as Event2Class); - if (applier === undefined) continue; - const ctx = new FoldContextImpl(this, silent); - const [next, patches, inversePatches] = produceWithPatches( - attachment.getState(), - (draft: any) => applier(draft, event, ctx) as any, - ); - if (ctx.pendingUndo !== undefined && patches.length > 0) { - throw new BugIndicatingError( - `Fold of event '${event.type}' on durable participant '${attachment.id}' both mutates and undoes to a checkpoint`, - ); - } - sanitizePendingUndo(ctx, attachment.meta); - preparedParticipants.push({ attachment, ctx, next, patches, inversePatches }); - } - } - for (const p of prepared) { - this.commit(p.key, p.meta, p.ctx, event, p.next, p.patches, p.inversePatches); - } - for (const p of preparedParticipants) { - this.commitParticipant(p.attachment, p.ctx, event, p.next, p.patches, p.inversePatches); - } - if (silent) return; - const cls = event.constructor as Event2Class; - if (cls.durable) { - const dehydrator = folds?.find(({ key }) => key.replayable.blobs !== undefined)?.key - .replayable.blobs?.dehydrate; - this.wire.appendRecord(event.serialize(), dehydrator); - } - if (cls.observable && !this.disposed) { - this.eventBus.publish(event, this.agentScope?.agentContext); - } - } - - override dispose(): void { - this.disposed = true; - this.space()?._detachHost(this.spaceHost); - super.dispose(); - } - - private commit( - key: ReplayableStateKey, - meta: StateMeta, - ctx: FoldContextImpl, - event: Event2, - next: any, - patches: PatchEntry['patches'], - inversePatches: PatchEntry['inversePatches'], - ): void { - if (ctx.pendingUndo !== undefined) { - const targetIndex = meta.checkpoints.length - ctx.pendingUndo; - const targetId = meta.checkpoints[targetIndex]!; - this.rollback(key, meta, targetId); - meta.checkpoints = meta.checkpoints.slice(0, targetIndex); - return; - } - this.agentState.set(key, next); - if (ctx.pendingClear) { - meta.history = []; - meta.checkpoints = []; - } - let markerId = meta.history.at(-1)?.id ?? 0; - if (patches.length > 0 || inversePatches.length > 0) { - const entry: PatchEntry = { - id: meta.nextPatchId++, - eventType: event.type, - patches, - inversePatches, - }; - meta.history.push(entry); - markerId = entry.id; - } - if (ctx.pendingCheckpoint) { - meta.checkpoints.push(markerId); - } - this.trimHistory(key, meta); - } - - private commitParticipant( - attachment: ParticipantAttachment, - ctx: FoldContextImpl, - event: Event2, - next: any, - patches: PatchEntry['patches'], - inversePatches: PatchEntry['inversePatches'], - ): void { - const meta = attachment.meta; - if (ctx.pendingUndo !== undefined) { - const targetIndex = meta.checkpoints.length - ctx.pendingUndo; - const targetId = meta.checkpoints[targetIndex]!; - this.rollbackParticipant(attachment, targetId); - meta.checkpoints = meta.checkpoints.slice(0, targetIndex); - return; - } - attachment.commit(next); - if (ctx.pendingClear) { - meta.history = []; - meta.checkpoints = []; - } - let markerId = meta.history.at(-1)?.id ?? 0; - if (patches.length > 0 || inversePatches.length > 0) { - const entry: PatchEntry = { - id: meta.nextPatchId++, - eventType: event.type, - patches, - inversePatches, - }; - meta.history.push(entry); - markerId = entry.id; - } - if (ctx.pendingCheckpoint) meta.checkpoints.push(markerId); - this.trimParticipantHistory(attachment); - } - - private rollback(key: ReplayableStateKey, meta: StateMeta, targetEntryId: number): void { - let i = meta.history.length - 1; - let current = this.agentState.get(key); - while (i >= 0 && meta.history[i]!.id > targetEntryId) { - current = applyPatches(current, [...meta.history[i]!.inversePatches]); - i--; - } - this.agentState.set(key, current); - meta.history = meta.history.slice(0, i + 1); - } - - private rollbackParticipant( - attachment: ParticipantAttachment, - targetEntryId: number, - ): void { - const meta = attachment.meta; - let i = meta.history.length - 1; - let current = attachment.getState(); - while (i >= 0 && meta.history[i]!.id > targetEntryId) { - current = applyPatches(current, [...meta.history[i]!.inversePatches]); - i--; - } - attachment.commit(current); - meta.history = meta.history.slice(0, i + 1); - } - - private trimHistory(key: ReplayableStateKey, meta: StateMeta): void { - const oldest = meta.checkpoints[0]; - if (oldest !== undefined) { - const firstRetained = meta.history.findIndex((entry) => entry.id >= oldest); - if (firstRetained > 0) { - meta.history.splice(0, firstRetained); - } - return; - } - if (!keepsUndoCheckpoints(key) && meta.history.length > HISTORY_TAIL) { - meta.history.splice(0, meta.history.length - HISTORY_TAIL); - } - } - - private trimParticipantHistory(attachment: ParticipantAttachment): void { - const meta = attachment.meta; - const oldest = meta.checkpoints[0]; - if (oldest !== undefined) { - const firstRetained = meta.history.findIndex((entry) => entry.id >= oldest); - if (firstRetained > 0) meta.history.splice(0, firstRetained); - return; - } - if (!attachment.keepsCheckpoints && meta.history.length > HISTORY_TAIL) { - meta.history.splice(0, meta.history.length - HISTORY_TAIL); - } - } - - private ensureMeta(key: ReplayableStateKey): StateMeta { - let meta = this.metas.get(key); - if (meta === undefined) { - meta = { history: [], checkpoints: [], nextPatchId: 1 }; - this.metas.set(key, meta); - } - return meta; - } - - async restore(): Promise { - if (this.restorePhase !== 'new') { - throw new BugIndicatingError( - `Agent state restore called while phase is ${this.restorePhase}`, - ); - } - this.restorePhase = 'restoring'; - try { - let recordIndex = 0; - for await (const record of this.wire.readJournal()) { - if (record.type === 'metadata') continue; - const cls = this.folded.events.get(record.type); - if (cls === undefined) { - this.reportSkippedRecord(record.type, recordIndex, false); - recordIndex++; - continue; - } - let eventRecord = record; - if (cls.agentDomain) { - if (this.agentScope === undefined) { - this.reportSkippedRecord(record.type, recordIndex, true); - recordIndex++; - continue; - } - const recordAgentId = record['agentId']; - if (recordAgentId === undefined) { - eventRecord = { ...record, agentId: this.agentScope.agentId }; - } else if (recordAgentId !== this.agentScope.agentId) { - this.reportSkippedRecord(record.type, recordIndex, true); - recordIndex++; - continue; - } - } - const event = event2FromRecord(cls, eventRecord); - if (event === undefined) { - this.reportSkippedRecord(record.type, recordIndex, true); - recordIndex++; - continue; - } - this.executeEvent(event, true); - recordIndex++; - } - await this.rehydrateStates(); - this.restorePhase = 'ready'; - await this.hooks.onDidRestore.run({}); - } catch (error) { - this.restorePhase = 'failed'; - throw error; - } - } - - private reportSkippedRecord(type: string, index: number, malformed: boolean): void { - onUnexpectedError( - new WireError( - WireErrors.codes.WIRE_UNKNOWN_RECORD, - malformed - ? `Malformed wire record type '${type}' skipped during restore` - : `Unknown wire record type '${type}' skipped during restore`, - { details: { type, index } }, - ), - ); - } - - private async rehydrateStates(): Promise { - const transform: PartsTransformer = (parts) => - this.blobService.loadParts(parts as readonly ContentPart[]) as Promise; - for (const key of this.folded.states) { - const codec = key.replayable.blobs; - if (codec?.rehydrate === undefined) continue; - this.agentState.set(key, Object.freeze(await codec.rehydrate(this.agentState.get(key), transform))); - } - } - - async flush(): Promise { - await this.wire.flush(); - } -} - -registerScopedService( - LifecycleScope.Agent, - IEventDispatcher, - EventDispatcherService, - ScopeActivation.OnScopeCreated, - 'state', -); diff --git a/packages/agent-core-v2/src/state/state.ts b/packages/agent-core-v2/src/state/state.ts deleted file mode 100644 index 99fdd1bbe..000000000 --- a/packages/agent-core-v2/src/state/state.ts +++ /dev/null @@ -1,323 +0,0 @@ -import { enableMapSet, enablePatches, type Draft, type Patch } from 'immer'; -import type { z } from 'zod'; - -import { BugIndicatingError } from '#/_base/errors/errors'; -import type { StateKey } from '#/_base/state/stateRegistry'; -import { Event2, registerEvent2Class, type Event2Class } from '#/app/event/event2'; -import type { PartsTransformer, RecordDehydrator } from '#/wire/record'; - -import { StateError, StateErrors } from './errors'; - -enableMapSet(); -enablePatches(); - -export type { StateKey } from '#/_base/state/stateRegistry'; -export type { PartsTransformer } from '#/wire/record'; - -export interface StateBlobCodec { - dehydrate: RecordDehydrator; - rehydrate(state: S, transform: PartsTransformer): S | Promise; -} - -export interface FoldContext { - readonly silent: boolean; - checkpoint(): void; - clearCheckpoints(): void; - undoToCheckpoint(count: number): void; - emit(event: Event2): void; -} - -export type StateFold = Event2> = ( - state: Draft, - event: E, - ctx: FoldContext, -) => S | void; - -export interface PatchEntry { - readonly id: number; - readonly eventType: string; - readonly patches: readonly Patch[]; - readonly inversePatches: readonly Patch[]; -} - -export interface ReplayableOptions { - readonly schema: z.ZodType; - readonly durable?: boolean; - readonly blobs?: StateBlobCodec; -} - -export interface UndoableOptions { - readonly onUndo?: (state: Draft, count: number) => S | void; -} - -export interface ReplayableStateMeta { - readonly schema: z.ZodType; - readonly durable: boolean; - readonly blobs?: StateBlobCodec; - readonly undoable?: UndoableOptions; - readonly folds: ReadonlyMap, StateFold>; -} - -export interface ReplayableStateKey extends StateKey> { - readonly replayable: ReplayableStateMeta; - undoable(opts?: UndoableOptions): ReplayableStateKey; - on>(cls: Event2Class, fold: StateFold): ReplayableStateKey; -} - -export interface StateKeyBuilder extends StateKey { - replayable(opts: ReplayableOptions): ReplayableStateKey; -} - -class ReplayableStateKeyImpl implements ReplayableStateKey { - readonly snapshotExcluded = true; - readonly initial: () => DeepReadonly; - - private readonly meta: { - readonly schema: z.ZodType; - readonly durable: boolean; - readonly blobs?: StateBlobCodec; - undoable?: UndoableOptions; - readonly folds: Map, StateFold>; - }; - - constructor( - readonly name: string, - initial: () => S, - opts: ReplayableOptions, - ) { - this.initial = () => Object.freeze(initial()) as DeepReadonly; - this.meta = { - schema: opts.schema, - durable: opts.durable ?? true, - blobs: opts.blobs, - folds: new Map(), - }; - } - - get replayable(): ReplayableStateMeta { - return this.meta; - } - - undoable(opts?: UndoableOptions): ReplayableStateKey { - if (this.meta.undoable !== undefined) { - throw new BugIndicatingError(`State key '${this.name}' is already undoable`); - } - if (!this.meta.durable) { - throw new BugIndicatingError(`Transient state key '${this.name}' cannot be undoable`); - } - this.meta.undoable = opts ?? {}; - return this; - } - - on>(cls: Event2Class, fold: StateFold): ReplayableStateKey { - if (this.meta.folds.has(cls)) { - throw new StateError( - StateErrors.codes.STATE_DUPLICATE_FOLD, - `State '${this.name}' already folds event '${cls.type}'`, - { details: { state: this.name, type: cls.type } }, - ); - } - if (!this.meta.durable && cls.durable) { - throw new StateError( - StateErrors.codes.STATE_DURABILITY_MISMATCH, - `Transient state '${this.name}' cannot fold durable event '${cls.type}'`, - { details: { state: this.name, type: cls.type } }, - ); - } - registerEvent2Class(cls); - this.meta.folds.set(cls, fold as StateFold); - return this; - } -} - -class StateKeyBuilderImpl implements StateKeyBuilder { - constructor( - readonly name: string, - readonly initial: () => T, - ) {} - - replayable(opts: ReplayableOptions): ReplayableStateKey { - return new ReplayableStateKeyImpl(this.name, this.initial, opts); - } -} - -export function defineState(name: string, initial: () => T): StateKeyBuilder { - return new StateKeyBuilderImpl(name, initial); -} - -export interface UndoableProtocol { - readonly events: { - readonly appendMessage: Event2Class; - readonly applyCompaction: Event2Class; - readonly clear: Event2Class; - readonly undo: Event2Class; - }; - readonly isUndoAnchor: (message: unknown) => boolean; - readonly isValidUndoCount: (count: number) => boolean; -} - -let undoableProtocol: UndoableProtocol | undefined; - -export function registerUndoableProtocol(protocol: UndoableProtocol): void { - if (undoableProtocol !== undefined) { - throw new BugIndicatingError('The undoable protocol is already registered'); - } - undoableProtocol = protocol; - for (const cls of Object.values(protocol.events)) { - registerEvent2Class(cls); - } -} - -export function keepsUndoCheckpoints( - key: ReplayableStateKey, -): boolean { - const undoable = key.replayable.undoable; - return undoable !== undefined && undoable.onUndo === undefined; -} - -export function expandedStateFolds( - key: ReplayableStateKey, -): ReadonlyMap, StateFold> { - const meta = key.replayable; - if (meta.undoable === undefined) return meta.folds; - if (undoableProtocol === undefined) { - throw new BugIndicatingError( - `State key '${key.name}' is undoable but no undoable protocol is registered ` + - '(the contextMemory domain registers it at import time)', - ); - } - const protocol = undoableProtocol; - if (meta.folds.has(protocol.events.undo)) { - throw new BugIndicatingError( - `Undoable state key '${key.name}' must not fold the undo event itself; ` + - 'use .undoable({ onUndo }) to customize the rollback', - ); - } - const custom = meta.undoable.onUndo !== undefined; - const folds = new Map, StateFold>(meta.folds); - const domainAppend = folds.get(protocol.events.appendMessage); - folds.set(protocol.events.appendMessage, (state, event, ctx) => { - if (!custom && protocol.isUndoAnchor(event.message)) { - ctx.checkpoint(); - return; - } - return domainAppend?.(state, event, ctx); - }); - for (const cls of [protocol.events.applyCompaction, protocol.events.clear]) { - const domain = folds.get(cls); - folds.set(cls, (state, event, ctx) => { - ctx.clearCheckpoints(); - return domain?.(state, event, ctx); - }); - } - folds.set(protocol.events.undo, (state, event, ctx) => { - if (!protocol.isValidUndoCount(event.count)) return; - if (meta.undoable?.onUndo !== undefined) { - return meta.undoable.onUndo(state, event.count); - } - ctx.undoToCheckpoint(event.count); - }); - return folds; -} - -export type EventApplier = (event: any, ctx: FoldContext) => void; - -export function expandedModelAppliers( - owner: string, - undoable: boolean, - appliers: ReadonlyMap, EventApplier>, - onUndo: ((count: number) => void) | undefined, -): ReadonlyMap, EventApplier> { - if (!undoable) return appliers; - if (undoableProtocol === undefined) { - throw new BugIndicatingError( - `Agent model '${owner}' is undoable but no undoable protocol is registered ` + - '(the contextMemory domain registers it at import time)', - ); - } - const protocol = undoableProtocol; - if (appliers.has(protocol.events.undo)) { - throw new BugIndicatingError( - `Undoable agent model '${owner}' must not apply the undo event itself; ` + - 'override onUndo on the model to customize the rollback', - ); - } - const custom = onUndo !== undefined; - const expanded = new Map, EventApplier>(appliers); - const domainAppend = expanded.get(protocol.events.appendMessage); - expanded.set(protocol.events.appendMessage, (event, ctx) => { - if (!custom && protocol.isUndoAnchor(event.message)) { - ctx.checkpoint(); - return; - } - domainAppend?.(event, ctx); - }); - for (const cls of [protocol.events.applyCompaction, protocol.events.clear]) { - const domain = expanded.get(cls); - expanded.set(cls, (event, ctx) => { - ctx.clearCheckpoints(); - domain?.(event, ctx); - }); - } - expanded.set(protocol.events.undo, (event, ctx) => { - if (!protocol.isValidUndoCount(event.count)) return; - if (onUndo !== undefined) { - onUndo(event.count); - return; - } - ctx.undoToCheckpoint(event.count); - }); - return expanded; -} - -export function expandedRuntimeFolds( - owner: string, - undoable: boolean, - folds: ReadonlyMap, StateFold>, -): ReadonlyMap, StateFold> { - if (!undoable) return folds; - if (undoableProtocol === undefined) { - throw new BugIndicatingError( - `Agent runtime '${owner}' is undoable but no undoable protocol is registered ` + - '(the contextMemory domain registers it at import time)', - ); - } - const protocol = undoableProtocol; - if (folds.has(protocol.events.undo)) { - throw new BugIndicatingError( - `Undoable agent runtime '${owner}' must not fold the undo event itself`, - ); - } - const expanded = new Map(folds); - const domainAppend = expanded.get(protocol.events.appendMessage); - expanded.set(protocol.events.appendMessage, (state, event, ctx) => { - if (protocol.isUndoAnchor(event.message)) { - ctx.checkpoint(); - return; - } - return domainAppend?.(state, event, ctx); - }); - for (const cls of [protocol.events.applyCompaction, protocol.events.clear]) { - const domain = expanded.get(cls); - expanded.set(cls, (state, event, ctx) => { - ctx.clearCheckpoints(); - return domain?.(state, event, ctx); - }); - } - expanded.set(protocol.events.undo, (_state, event, ctx) => { - if (protocol.isValidUndoCount(event.count)) ctx.undoToCheckpoint(event.count); - }); - return expanded; -} - -export type DeepReadonly = T extends (...args: infer A) => infer R - ? (...args: A) => R - : T extends ReadonlyMap - ? ReadonlyMap, DeepReadonly> - : T extends ReadonlySet - ? ReadonlySet> - : T extends readonly (infer E)[] - ? ReadonlyArray> - : T extends object - ? { readonly [K in keyof T]: DeepReadonly } - : T; diff --git a/packages/agent-core-v2/src/state/stateContribution.ts b/packages/agent-core-v2/src/state/stateContribution.ts deleted file mode 100644 index 321d81c1e..000000000 --- a/packages/agent-core-v2/src/state/stateContribution.ts +++ /dev/null @@ -1,72 +0,0 @@ -import { collection } from '#/_base/di/collection'; -import { onUnexpectedError } from '#/_base/errors/unexpectedError'; -import { EventError, EventErrors } from '#/app/event/errors'; -import { EVENT2_REGISTRY, type Event2Class } from '#/app/event/event2'; - -import { - expandedStateFolds, - type ReplayableStateKey, - type StateFold, -} from './state'; - -export interface EventStateContributionRecord { - readonly events?: readonly Event2Class[]; -} - -export const EventStateContribution = collection('event-state'); - -export interface StateFoldRegistration { - readonly key: ReplayableStateKey; - readonly fold: StateFold; -} - -export interface FoldedEventStateRegistry { - readonly events: ReadonlyMap>; - readonly folds: ReadonlyMap; - readonly states: readonly ReplayableStateKey[]; -} - -export function foldEventStateContributions( - records: readonly EventStateContributionRecord[], - replayableKeys: readonly ReplayableStateKey[], -): FoldedEventStateRegistry { - const events = new Map>(); - const folds = new Map(); - const states: ReplayableStateKey[] = []; - const foldBuiltinLayer = (): void => { - for (const cls of EVENT2_REGISTRY.values()) { - events.set(cls.type, cls); - } - for (const key of replayableKeys) { - states.push(key); - for (const [cls, fold] of expandedStateFolds(key)) { - let list = folds.get(cls.type); - if (list === undefined) { - list = []; - folds.set(cls.type, list); - } - list.push({ key, fold }); - if (cls.durable && !events.has(cls.type)) { - events.set(cls.type, cls); - } - } - } - }; - foldBuiltinLayer(); - for (const record of records) { - for (const cls of record.events ?? []) { - if (events.has(cls.type)) { - onUnexpectedError( - new EventError( - EventErrors.codes.EVENT_DUPLICATE_EVENT, - `Duplicate event type contributed: '${cls.type}'; keeping the already-folded registration`, - { details: { type: cls.type } }, - ), - ); - continue; - } - events.set(cls.type, cls); - } - } - return { events, folds, states }; -} diff --git a/packages/agent-core-v2/src/tool/args-validator.ts b/packages/agent-core-v2/src/tool/args-validator.ts index 3585f03f7..c90342f07 100644 --- a/packages/agent-core-v2/src/tool/args-validator.ts +++ b/packages/agent-core-v2/src/tool/args-validator.ts @@ -1,3 +1,12 @@ +/** + * `tool` domain — runtime tool-args validation. + * + * Compiles tool-parameter JSON Schemas into AJV validators (draft-07 / + * 2019-09 / 2020-12 detected per schema) and formats validation failures + * into model-readable messages. The AJV instances are paid for once, at + * execution time. Pure helper; no scoped service. + */ + import Ajv, { type ErrorObject, type ValidateFunction } from 'ajv'; import Ajv2019 from 'ajv/dist/2019'; import Ajv2020 from 'ajv/dist/2020'; diff --git a/packages/agent-core-v2/src/tool/input-schema.ts b/packages/agent-core-v2/src/tool/input-schema.ts index 085ffad40..baeded96c 100644 --- a/packages/agent-core-v2/src/tool/input-schema.ts +++ b/packages/agent-core-v2/src/tool/input-schema.ts @@ -1,3 +1,22 @@ +/** + * `tool` domain — tool-parameter JSON Schema rendering. + * + * Shared helper for deriving the JSON Schema that a tool advertises to the + * model for its parameters. + * + * A tool's parameter schema describes the *input* the model is expected to + * supply. zod v4's `toJSONSchema` defaults to the *output* view, which marks + * any field carrying a chain-tail `.default()` as `required` — producing a + * schema that simultaneously declares a `default` and lists the field as + * required. That contradiction also makes the runtime AJV validator reject + * legal calls that omit the defaulted fields. + * + * Always render parameter schemas through this helper so the `io: 'input'` + * view is applied uniformly and defaulted fields remain optional, while the + * closed-object guard (`additionalProperties: false`) is kept so unknown + * arguments are still rejected. + */ + import { z } from 'zod'; export function toInputJsonSchema(schema: z.ZodType): Record { diff --git a/packages/agent-core-v2/src/tool/path-access.ts b/packages/agent-core-v2/src/tool/path-access.ts index 7e11c4631..d5362efc3 100644 --- a/packages/agent-core-v2/src/tool/path-access.ts +++ b/packages/agent-core-v2/src/tool/path-access.ts @@ -1,10 +1,25 @@ +/** + * `tool` domain — workspace path access policy for file tools. + * + * Owns `WorkspaceConfig` (the roots tools are allowed to access, injected + * through each tool's constructor), the lexical path guards used by + * Read/Write/Edit/Grep/Glob — canonicalization, workspace containment, + * sensitive-file detection (env / credential / SSH key patterns with + * explicit exemptions like `.env.example`) — and `PathSecurityError`. + * `extendWorkspaceWithSkillRoots` merges skill-catalog roots into a tool + * workspace so skill directories outside the cwd (e.g. `~/.kimi-code/skills`) + * stay reachable. + * Canonicalization is **lexical** only (no `realpath` / symlink following). + * The guard stays host-aware: callers pass the active `IHostEnvironment` + * path class so SSH paths stay POSIX even when the host Node process is + * running on Windows. Shared-prefix escapes (a path like `/workspace-evil` + * passing a naive `startswith('/workspace')` check) are blocked by + * requiring a path separator (or exact equality) after the base prefix in + * `isWithinDirectory`. Pure policy; no scoped service. + */ + import * as pathe from 'pathe'; -import { - getShellPathBridge, - translateShellDrivePath, - type ShellPathBridge, -} from '#/_base/execEnv/shellPathBridge'; import type { IHostEnvironment } from '#/os/interface/hostEnvironment'; export interface WorkspaceConfig { @@ -123,7 +138,29 @@ function isWin32DriveRelative(path: string): boolean { } export function normalizeUserPath(path: string, pathClass: PathClass = DEFAULT_PATH_CLASS): string { - return pathClass === 'win32' ? translateShellDrivePath(path) : path; + if (pathClass !== 'win32') return path; + + if (path === '/') return '/'; + + if (path.startsWith('//')) { + return path; + } + + const cygdriveMatch = /^\/cygdrive\/([A-Za-z])(?:\/|$)/.exec(path); + if (cygdriveMatch !== null) { + const drive = cygdriveMatch[1]!.toUpperCase(); + const rest = path.slice(`/cygdrive/${cygdriveMatch[1]!}`.length); + return `${drive}:${rest === '' ? '/' : rest}`; + } + + const driveMatch = /^\/([A-Za-z])(?:\/|$)/.exec(path); + if (driveMatch !== null) { + const drive = driveMatch[1]!.toUpperCase(); + const rest = path.slice(2); + return `${drive}:${rest === '' ? '/' : rest}`; + } + + return path; } function expandUserPath(path: string, homeDir: string | undefined, pathClass: PathClass): string { @@ -216,14 +253,10 @@ export interface ResolvePathAccessOptions { readonly policy?: WorkspaceAccessPolicy | undefined; readonly pathClass?: PathClass | undefined; readonly homeDir?: string; - readonly shellPathBridge?: ShellPathBridge; } export interface ResolvePathAccessPathOptions { - readonly env: Pick< - IHostEnvironment, - 'pathClass' | 'homeDir' | 'osKind' | 'shellName' | 'shellPath' - >; + readonly env: Pick; readonly workspace: WorkspaceConfig; readonly operation: PathAccessOperation; readonly policy?: WorkspaceAccessPolicy; @@ -250,8 +283,7 @@ export function resolvePathAccess( options: ResolvePathAccessOptions, ): PathAccess { const pathClass = options.pathClass ?? DEFAULT_PATH_CLASS; - const normalizedPath = - options.shellPathBridge?.fromShellPath(path) ?? normalizeUserPath(path, pathClass); + const normalizedPath = normalizeUserPath(path, pathClass); const expandedPath = expandUserPath(normalizedPath, options.homeDir, pathClass); const rawIsAbsolute = pathe.isAbsolute(expandedPath); const canonical = canonicalizePath(expandedPath, cwd, pathClass); @@ -298,7 +330,6 @@ export function resolvePathAccessPath( policy, pathClass: env.pathClass, homeDir: expandHome ? env.homeDir : undefined, - shellPathBridge: env.pathClass === 'win32' ? getShellPathBridge(env) : undefined, }).path; } diff --git a/packages/agent-core-v2/src/tool/result-builder.ts b/packages/agent-core-v2/src/tool/result-builder.ts index cd8bb710f..9debc6647 100644 --- a/packages/agent-core-v2/src/tool/result-builder.ts +++ b/packages/agent-core-v2/src/tool/result-builder.ts @@ -1,3 +1,11 @@ +/** + * `tool` domain — buffered tool-result builder. + * + * Shared helper for tools that stream text into a bounded output buffer with + * optional per-line and total-char truncation. Pure helper; no scoped + * service. + */ + import { BugIndicatingError } from '#/errors'; import type { ExecutableToolErrorResult, ExecutableToolSuccessResult } from './toolContract'; diff --git a/packages/agent-core-v2/src/tool/rule-match.ts b/packages/agent-core-v2/src/tool/rule-match.ts index 8f6dc1174..94cf3720f 100644 --- a/packages/agent-core-v2/src/tool/rule-match.ts +++ b/packages/agent-core-v2/src/tool/rule-match.ts @@ -1,3 +1,15 @@ +/** + * `tool` domain — permission rule-subject matching. + * + * Owns the glob / path matching primitives (`globMatch` / `pathGlobMatch`) + * and the rule-subject helpers (`literalRulePattern`, + * `escapeRuleSubjectLiteral`, `matchesGlobRuleSubject`, + * `matchesPathRuleSubject`) that tool implementations use to build their + * `matchesRule` closures and canonical rule strings. Path matching compares + * normalized path variants, so `./a`, `dir/../a`, and Windows separator or + * case variants can match the same rule. Pure functions; no scoped service. + */ + import { isAbsolute, join, parse } from 'pathe'; import picomatch from 'picomatch'; diff --git a/packages/agent-core-v2/src/tool/tool-args-parse.ts b/packages/agent-core-v2/src/tool/tool-args-parse.ts index b1a8d969a..aa70b8119 100644 --- a/packages/agent-core-v2/src/tool/tool-args-parse.ts +++ b/packages/agent-core-v2/src/tool/tool-args-parse.ts @@ -1,3 +1,12 @@ +/** + * `tool` domain — tool-call arguments parsing. + * + * Decodes the provider's raw `arguments` payload into a plain value. A + * payload that fails JSON parsing is normalized to `{}` and flagged with + * `parseFailed`, so callers can tell "the model sent an empty object" apart + * from "the model sent malformed text". Pure helper; no scoped service. + */ + export function parseToolCallArguments(raw: unknown): { readonly data: unknown; readonly parseFailed: boolean; diff --git a/packages/agent-core-v2/src/tool/toolContract.ts b/packages/agent-core-v2/src/tool/toolContract.ts index 552c708c2..559562194 100644 --- a/packages/agent-core-v2/src/tool/toolContract.ts +++ b/packages/agent-core-v2/src/tool/toolContract.ts @@ -1,3 +1,20 @@ +/** + * `tool` domain — foundational tool model contract. + * + * Owns the tool model shared by every tool domain: the static metadata + * (`ToolSource` / `ToolDefinition` / `ToolInfo`), the `ExecutableTool` + * contract every tool implements (`resolveExecution` → `ToolExecution` → + * `execute(ctx)`), the `ExecutableToolContext` it runs against, the raw and + * finalized results (`ExecutableToolResult` / `ToolResult`), the streaming + * `ToolUpdate`, and the `AgentTool` service interface every DI-registered + * agent tool implements. Also owns the `ToolAccesses` + * resource-access declarations an execution emits so the host scheduler can + * run non-conflicting calls concurrently (together with their conflict + * semantics), and the `isMcpToolName` name predicate. The `stopTurn` / + * `stopBatchAfterThis` fields are internal loop-control hints stripped + * before persistence. No scoped service. + */ + import type { ContentPart, ToolCall } from '#/kosong/contract/message'; import type { Tool } from '#/kosong/contract/tool'; import type { LLMRequestTrace } from '#/kosong/contract/requestTrace'; @@ -45,7 +62,6 @@ export interface ToolUpdate { percent?: number | undefined; customKind?: string | undefined; customData?: unknown; - replace?: boolean; } export interface ExecutableToolContext { diff --git a/packages/agent-core-v2/src/tool/toolInputDisplay.ts b/packages/agent-core-v2/src/tool/toolInputDisplay.ts index 70263161b..9ace28541 100644 --- a/packages/agent-core-v2/src/tool/toolInputDisplay.ts +++ b/packages/agent-core-v2/src/tool/toolInputDisplay.ts @@ -1,3 +1,8 @@ +/** + * `ToolInputDisplay` — structured UI hint describing a tool call's input, so + * approval panels and tool renderers can present it without re-deriving it + * from raw arguments. + */ export type ToolInputDisplay = | { kind: 'command'; diff --git a/packages/agent-core-v2/src/wire/errors.ts b/packages/agent-core-v2/src/wire/errors.ts index e1d515a5d..fa5f52499 100644 --- a/packages/agent-core-v2/src/wire/errors.ts +++ b/packages/agent-core-v2/src/wire/errors.ts @@ -1,13 +1,39 @@ +/** + * `wire` domain — error codes, the `WireError` base class, and the domain + * registration. + * + * Aggregates the wire domain's coded errors: `DuplicateOpError` and + * `CycleError` stay co-located with their throw sites but extend + * `WireError`; `wire.unknown_record` is constructed here for replay-time + * reporting of records whose Op type is absent from the wire runtime's + * folded op registry (unknown or withdrawn vocabulary — see + * `wireContribution.ts`). + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; import { Error2, type Error2Options } from '#/_base/errors/errors'; export const WireErrors = { codes: { + WIRE_DUPLICATE_OP: 'wire.duplicate_op', + WIRE_CYCLE: 'wire.cycle', WIRE_UNKNOWN_RECORD: 'wire.unknown_record', WIRE_MIGRATION_MISSING: 'wire.migration_missing', RECORDS_WRITE_FAILED: 'records.write_failed', }, info: { + 'wire.duplicate_op': { + title: 'Duplicate wire op type', + retryable: false, + public: true, + action: 'Two ops registered the same type; rename one. This is a build-time bug.', + }, + 'wire.cycle': { + title: 'Wire dispatch cycle', + retryable: false, + public: true, + action: 'An onChange handler re-dispatches endlessly; break the op cycle.', + }, 'wire.unknown_record': { title: 'Unknown wire record', retryable: false, diff --git a/packages/agent-core-v2/src/wire/migration/v1.5.ts b/packages/agent-core-v2/src/wire/migration/v1.5.ts index ebb7db9b3..8b18e7b07 100644 --- a/packages/agent-core-v2/src/wire/migration/v1.5.ts +++ b/packages/agent-core-v2/src/wire/migration/v1.5.ts @@ -1,3 +1,10 @@ +/** + * Wire protocol 1.5 persists an epoch-ms anchor at every goal create/resume + * boundary and wall-clock checkpoint. Version 1.4 records already carry an + * epoch-ms `time`, so the migration can recover that boundary without + * inventing a crash timestamp or adding periodic checkpoint writes. Existing + * anchors are authoritative. + */ import type { WireMigration, WireMigrationRecord } from './migration'; export const migrateV1_4ToV1_5: WireMigration = { diff --git a/packages/agent-core-v2/src/wire/model.ts b/packages/agent-core-v2/src/wire/model.ts new file mode 100644 index 000000000..d672a70ce --- /dev/null +++ b/packages/agent-core-v2/src/wire/model.ts @@ -0,0 +1,117 @@ +/** + * `wire` domain — Model definition primitive (`ModelDef` / `defineModel`), + * `DeepReadonly` (the compile-time half of immutability), and the + * `ModelBlobCodec` / `PartsTransformer` types that let a model declare how to + * dehydrate large inline media before persistence and rehydrate blob references + * in its state after replay. + * + * A `ModelDef` is a stateless descriptor: it names a model, manufactures its + * initial state via `initial`, and declares the model's Ops through + * `defineOp`. It never holds state itself — per-scope state instances are + * owned by the wire service. The optional `blobs` codec declares both directions + * of the blob offload pipeline: + * - `dehydrate(record, transform)`: called per-record at dispatch time; the + * model traverses its record structure, passes each `ContentPart[]` through + * `transform` (which offloads oversized data URIs to blob storage and returns + * parts with `blobref:` URLs), and returns the transformed record. + * - `rehydrate(state, transform)`: called once after replay; the model + * traverses the surviving final state, passes each `ContentPart[]` through + * `transform` (which loads blob references back to inline data URIs), and + * returns the transformed state. Only the *surviving* state is rehydrated, + * skipping data that was later removed by compaction. + * + * Both directions receive a `PartsTransformer` — the same function shape — so + * the model owns the traversal logic and the wire service owns the storage + * I/O. `PartsTransformer` uses `readonly unknown[]` rather than + * `ContentPart[]` so this file stays free of L3 contract imports (the + * L2 → L3 boundary). + * + * A primary Model may register cross-model reducers keyed by foreign op types: + * the wire service runs them on both dispatch and restore, so v1-derived + * restore effects can stay replayable without persisting extra records. + * + * `defineModel` also records every defined Model into `MODEL_REGISTRY`; + * together with `OP_REGISTRY`, `MODEL_CROSS_REDUCERS`, and + * `CHECKPOINTED_MODELS` these module tables are the static built-in channel + * ("import = register") that the `WireModelContribution` fold drains into the + * built-in layer whenever a `WireService` (re)folds its runtime lookups — + * registrations are append-only and never removed. + * `DeepReadonly` recursively maps a state type to its deeply-readonly view + * for the references returned by `getModel`: functions pass + * through, `Map` / `Set` widen to `ReadonlyMap` / `ReadonlySet`, arrays and + * tuples widen to `ReadonlyArray`, plain objects become a readonly mapped type, + * and primitives are unchanged. It pairs with the runtime `Object.freeze` + * applied by the wire service after every `apply`. Scope-agnostic. + */ + +import { bindDefineOp, type DefineOpFn } from '#/wire/op'; +import type { ModelReducers } from '#/wire/types'; +import type { WireRecord } from '#/wire/record'; + +export type PartsTransformer = (parts: readonly unknown[]) => Promise; + +export interface ModelBlobCodec { + dehydrate(record: WireRecord, transform: PartsTransformer): WireRecord | Promise; + rehydrate(state: S, transform: PartsTransformer): S | Promise; +} + +export interface ModelDef { + readonly name: string; + readonly initial: () => S; + readonly blobs?: ModelBlobCodec; + readonly defineOp: DefineOpFn; +} + +export interface ModelCrossReducerEntry { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly model: ModelDef; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly reducer: (state: any, payload: any) => any; +} + +export const MODEL_CROSS_REDUCERS = new Map(); + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const MODEL_REGISTRY: ModelDef[] = []; + +export function defineModel( + name: string, + initial: () => S, + opts?: { + blobs?: ModelBlobCodec; + reducers?: ModelReducers; + }, +): ModelDef { + const def: ModelDef = { + name, + initial, + blobs: opts?.blobs, + defineOp: bindDefineOp(() => def), + }; + if (opts?.reducers !== undefined) { + for (const [opType, reducer] of Object.entries(opts.reducers)) { + if (reducer === undefined) continue; + let list = MODEL_CROSS_REDUCERS.get(opType); + if (list === undefined) { + list = []; + MODEL_CROSS_REDUCERS.set(opType, list); + } + list.push({ model: def, reducer }); + } + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + MODEL_REGISTRY.push(def as ModelDef); + return def; +} + +export type DeepReadonly = T extends (...args: infer A) => infer R + ? (...args: A) => R + : T extends ReadonlyMap + ? ReadonlyMap, DeepReadonly> + : T extends ReadonlySet + ? ReadonlySet> + : T extends readonly (infer E)[] + ? ReadonlyArray> + : T extends object + ? { readonly [K in keyof T]: DeepReadonly } + : T; diff --git a/packages/agent-core-v2/src/wire/op.ts b/packages/agent-core-v2/src/wire/op.ts new file mode 100644 index 000000000..2ed858ca0 --- /dev/null +++ b/packages/agent-core-v2/src/wire/op.ts @@ -0,0 +1,126 @@ +/** + * `wire` domain — Op definition primitive (`Op`, `OpDescriptor`, + * `defineOp`, the global `OP_REGISTRY`) and the `DuplicateOpError` fail-fast + * guard. + * + * `defineOp` registers the descriptor into `OP_REGISTRY` at import time and + * returns the descriptor fused with a payload factory, so a declared Op is both + * callable (`goalCreate(payload)`) and inspectable (`goalCreate.apply`, + * `goalCreate.type`). Every Op carries a mandatory pure `apply` and may carry + * an optional `toEvent` that derives an `IEventBus` fact from the payload and + * the post-apply state (published on live `dispatch`, + * never during `restore`). A mandatory `schema` (zod, declared before `apply`) is the + * payload's single source of truth: `P` is inferred from it, so Op authors + * never restate payload interfaces, and it is stored on the descriptor for + * payload validation at wire boundaries; the runtime paths (`dispatch` / + * `restore`) never consult it. The descriptor's payload is erased + * to `any` on `Op.descriptor` (mirroring `OP_REGISTRY`) so `Op` stays + * covariant in `P` — a heterogeneous batch of Ops, each with a different + * payload type, stays assignable to the single `dispatch(...ops: Op[])` rest + * parameter, while the precise payload type survives on `Op.payload` for the + * Op's own caller. Registering a duplicate `type` throws `DuplicateOpError` so + * the global Op-type namespace stays unique. `OP_REGISTRY` is never consulted + * at runtime directly: it is the static built-in channel ("import = register") + * that the `WireModelContribution` fold drains into the built-in layer (see + * `wireContribution.ts`); runtime lookups read the folded result. + * Scope-agnostic. + */ + +import type { z } from 'zod'; + +import type { ConflictingOpType, OpPersistenceOptions, OpType } from '#/wire/types'; + +import { WireError, WireErrors } from './errors'; +import type { ModelDef } from './model'; + +export class DuplicateOpError extends WireError { + constructor(readonly type: string) { + super(WireErrors.codes.WIRE_DUPLICATE_OP, `Duplicate Op type registered: '${type}'`, { + details: { type }, + }); + this.name = 'DuplicateOpError'; + } +} + +export interface OpDescriptor { + readonly type: K; + readonly model: ModelDef; + readonly schema: z.ZodType

; + readonly apply: (state: S, payload: P) => S; + readonly toEvent?: (payload: P, state: S) => unknown; + readonly persist?: boolean; +} + +export interface Op { + readonly type: K; + readonly payload: P; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly descriptor: OpDescriptor; +} + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export const OP_REGISTRY = new Map>(); + +interface OpBehaviorOptions { + readonly schema: z.ZodType

; + readonly apply: (state: S, payload: P) => S; + readonly toEvent?: (payload: P, state: S) => unknown; +} + +type RegisteredOpConstraint = K extends ConflictingOpType + ? never + : K extends OpType + ? OpPersistenceOptions + : unknown; + +type DefineOpOptions = OpBehaviorOptions & { + readonly persist?: boolean; +} & RegisteredOpConstraint; + +type DefinedOp = OpDescriptor & + ((payload: P) => Op); + +export interface DefineOpFn { + ( + type: K & SingleStringLiteral, + opts: DefineOpOptions, S, P>, + ): DefinedOp; +} + +type SingleStringLiteral = {} extends Record + ? never + : K extends unknown + ? [Whole] extends [K] + ? K + : never + : never; + +export function bindDefineOp(getModel: () => ModelDef): DefineOpFn { + const bound = (type: string, opts: unknown): unknown => + defineOp(getModel(), type as never, opts as never); + return bound as DefineOpFn; +} + +export function defineOp( + model: ModelDef, + type: K & SingleStringLiteral, + opts: DefineOpOptions, S, P>, +): DefinedOp { + if (OP_REGISTRY.has(type)) { + throw new DuplicateOpError(type); + } + const behavior: OpBehaviorOptions & { + readonly persist?: boolean; + } = opts; + const descriptor: OpDescriptor = { + type, + model, + schema: behavior.schema, + apply: behavior.apply, + toEvent: behavior.toEvent, + persist: behavior.persist, + }; + OP_REGISTRY.set(type, descriptor); + const factory = (payload: P): Op => ({ type, payload, descriptor }); + return Object.assign(factory, descriptor); +} diff --git a/packages/agent-core-v2/src/wire/record.ts b/packages/agent-core-v2/src/wire/record.ts index 758f68bb1..e957999ae 100644 --- a/packages/agent-core-v2/src/wire/record.ts +++ b/packages/agent-core-v2/src/wire/record.ts @@ -1,14 +1,18 @@ +/** + * `wire` domain — the persisted journal record language. + * + * A `WireRecord` is the flat JSONL representation of one persisted Op. The + * first line of an Agent journal is a `WireMetadataRecord`; metadata is a + * journal envelope, not an Op, so it never enters the model reducer registry. + * This module owns only pure encoding and decoding. + */ + +import type { Op } from '#/wire/op'; + import { WIRE_PROTOCOL_VERSION } from './migration/migration'; export const AGENT_WIRE_RECORD_KEY = 'wire.jsonl'; -export type PartsTransformer = (parts: readonly unknown[]) => Promise; - -export type RecordDehydrator = ( - record: WireRecord, - transform: PartsTransformer, -) => WireRecord | Promise; - export interface WireRecord { readonly type: string; readonly time?: number; @@ -45,3 +49,20 @@ export function isWireMetadataRecord(record: WireRecord): record is WireMetadata typeof record['created_at'] === 'number' ); } + +export function opToWireRecord(op: Op, now = Date.now()): WireRecord { + const payload = op.payload; + const record: Record = + payload !== null && typeof payload === 'object' && !Array.isArray(payload) + ? { type: op.type, ...(payload as Record) } + : { type: op.type, payload }; + if (record['time'] === undefined) record['time'] = now; + return record as WireRecord; +} + +export function wireRecordToPayload(record: WireRecord): unknown { + const { type: _type, time: _time, ...payload } = record; + return Object.keys(payload).length === 1 && 'payload' in payload + ? payload['payload'] + : payload; +} diff --git a/packages/agent-core-v2/src/wire/types.ts b/packages/agent-core-v2/src/wire/types.ts new file mode 100644 index 000000000..f80affc73 --- /dev/null +++ b/packages/agent-core-v2/src/wire/types.ts @@ -0,0 +1,42 @@ +/** + * `wire` domain — augmentable Op registries and their derived + * compile-time vocabulary. + * + * Domains contribute their defined Ops to `PersistedOpMap` or `TransientOpMap` + * via module augmentation (`'my.op': typeof myOp`). The selected map + * classifies whether a live dispatch writes the Op, while `OpPayload` recovers + * each Op's payload from the Op's own type: the payload flows from the Op + * definition into the registry, never the reverse, so Op authoring stays free + * of registry cycles. Persisted input remains an open wire boundary so replay + * can continue to tolerate historical and newer record types. Scope-agnostic. + */ + +export interface PersistedOpMap {} + +export interface TransientOpMap {} + +type StringKey = Extract; + +type PersistedOpKey = StringKey; +type TransientOpKey = StringKey; + +export type ConflictingOpType = Extract; +export type PersistedOpType = Exclude; +export type TransientOpType = Exclude; +export type OpType = PersistedOpType | TransientOpType; + +export type PayloadOf = T extends (payload: infer P) => unknown ? P : never; + +export type OpPayload = K extends PersistedOpType + ? PayloadOf + : K extends TransientOpType + ? PayloadOf + : never; + +export type ModelReducers = { + [K in OpType]?: (state: S, payload: OpPayload) => S; +}; + +export type OpPersistenceOptions = K extends PersistedOpType + ? { readonly persist?: true } + : { readonly persist: false }; diff --git a/packages/agent-core-v2/src/wire/wire.ts b/packages/agent-core-v2/src/wire/wire.ts index 13d052786..0b04d365f 100644 --- a/packages/agent-core-v2/src/wire/wire.ts +++ b/packages/agent-core-v2/src/wire/wire.ts @@ -1,14 +1,35 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +/** + * `wire` domain — the single Agent-scoped wire aggregate contract. + * + * The service owns one Agent's replayable model state and its journal as one + * consistency boundary: restore reads, validates, migrates, rewrites, replays, + * rehydrates, and then runs the ordered restore hook. Seal initializes a fresh + * journal before session metadata makes the Agent visible to legacy readers. + * Live dispatch applies an Op and appends its record. Callers do not coordinate + * journal and model state through separate services. + */ -import type { RecordDehydrator, WireRecord } from './record'; +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { Hooks } from '#/hooks'; + +import type { DeepReadonly, ModelDef } from './model'; +import type { Op } from './op'; + +export type WireHooks = { + readonly onDidRestore: Record; +}; export interface IWireService { readonly _serviceBrand: undefined; + readonly hooks: Hooks; + + dispatch(...ops: Op[]): void; seal(): Promise; - appendRecord(record: WireRecord, dehydrate?: RecordDehydrator): void; - readJournal(): AsyncIterable; + restore(): Promise; flush(): Promise; + + getModel(model: ModelDef): DeepReadonly; } export const IWireService: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/wire/wireContribution.ts b/packages/agent-core-v2/src/wire/wireContribution.ts new file mode 100644 index 000000000..28cd5d3d8 --- /dev/null +++ b/packages/agent-core-v2/src/wire/wireContribution.ts @@ -0,0 +1,134 @@ +/** + * `wire` domain — the `WireModelContribution` collection token (D12), its + * per-domain record shape, and the fold that collapses the built-in layer + * plus live contribution records into the lookup structure the wire runtime + * consults. + * + * A unit contributes one bundle of wire vocabulary per domain with + * `this.provide(WireModelContribution, …)`: `models` (the `defineModel` + * products), `ops` (the `OpDescriptor`s), `crossReducers` (cross-model + * reducers keyed by foreign op type), and `checkpointedModels` (the + * `defineCheckpointedModel` products). The fold lives in `WireService` + * (Agent scope): it refolds from the built-in layer and the view's surviving + * records on every `onDidChange` — the collection edge enters the dependency + * graph for introspection but never rebuilds the service. A withdrawn record + * removes its vocabulary, so replaying that domain's historical wire records + * lands on the generic unknown-op path (skip + count): persisted facts stay + * readable when the contributing unit is long gone. + * + * The built-in layer is the module tables (`OP_REGISTRY`, `MODEL_REGISTRY`, + * `MODEL_CROSS_REDUCERS`, `CHECKPOINTED_MODELS`), drained at fold time: + * `defineOp` / `defineModel` / `defineCheckpointedModel` ("import = + * register") stay the static built-in data channel, every table is filled at + * module load — long before any scope constructs a `WireService` — and no op + * module is ever imported lazily, so draining at fold time is equivalent to + * the old live reads. (Routing the built-in layer through an App-scope + * assembly unit as just another collection record was considered and + * rejected: every bare-container `WireService` construction — unit tests + * included — would then have to materialize that assembly first. The sibling + * folds drain their module collectors at fold construction the same way.) + * + * Conflict semantics: `defineOp` keeps its module-load fail-fast + * (`DuplicateOpError`). The fold is an event path and never throws — a later + * record whose op type collides with an already-folded type is skipped and + * reported through `onUnexpectedError`, and the built-in layer always folds + * first so built-ins win every collision (a persistent conflict re-logs on + * each refold). Scope-agnostic. + */ + +import { collection } from '#/_base/di/collection'; +import { onUnexpectedError } from '#/_base/errors/unexpectedError'; +import { + CHECKPOINTED_MODELS, + type Checkpointed, +} from '#/agent/contextMemory/conversationTime'; + +import { WireError, WireErrors } from './errors'; +import { + MODEL_CROSS_REDUCERS, + MODEL_REGISTRY, + type ModelCrossReducerEntry, + type ModelDef, +} from './model'; +import { OP_REGISTRY, type OpDescriptor } from './op'; + +export interface WireModelContributionRecord { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly models?: readonly ModelDef[]; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly ops?: readonly OpDescriptor[]; + readonly crossReducers?: ReadonlyMap; + readonly checkpointedModels?: readonly ModelDef>[]; +} + +export const WireModelContribution = collection('wire-model'); + +export interface FoldedWireRegistry { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly ops: ReadonlyMap>; + readonly crossReducers: ReadonlyMap; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + readonly models: readonly ModelDef[]; + readonly checkpointedModels: readonly ModelDef>[]; +} + +export function builtinWireContribution(): WireModelContributionRecord { + return { + models: [...MODEL_REGISTRY], + ops: [...OP_REGISTRY.values()], + crossReducers: MODEL_CROSS_REDUCERS, + checkpointedModels: [...CHECKPOINTED_MODELS], + }; +} + +export function foldWireContributions( + records: readonly WireModelContributionRecord[], +): FoldedWireRegistry { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const ops = new Map>(); + const crossReducers = new Map(); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const models: ModelDef[] = []; + const checkpointedModels: ModelDef>[] = []; + for (const record of records) { + for (const op of record.ops ?? []) { + if (ops.has(op.type)) { + onUnexpectedError( + new WireError( + WireErrors.codes.WIRE_DUPLICATE_OP, + `Duplicate Op type contributed: '${op.type}'; keeping the already-folded registration`, + { details: { type: op.type } }, + ), + ); + continue; + } + ops.set(op.type, op); + } + for (const [opType, entries] of record.crossReducers ?? []) { + let list = crossReducers.get(opType); + if (list === undefined) { + list = []; + crossReducers.set(opType, list); + } + for (const entry of entries) { + const duplicate = list.some( + (existing) => existing.model === entry.model && existing.reducer === entry.reducer, + ); + if (!duplicate) { + list.push(entry); + } + } + } + for (const model of record.models ?? []) { + if (!models.includes(model)) { + models.push(model); + } + } + for (const model of record.checkpointedModels ?? []) { + if (!checkpointedModels.includes(model)) { + checkpointedModels.push(model); + } + } + } + return { ops, crossReducers, models, checkpointedModels }; +} diff --git a/packages/agent-core-v2/src/wire/wireService.ts b/packages/agent-core-v2/src/wire/wireService.ts index 5a40900c7..47d527d52 100644 --- a/packages/agent-core-v2/src/wire/wireService.ts +++ b/packages/agent-core-v2/src/wire/wireService.ts @@ -1,10 +1,37 @@ +/** + * `wire` domain — `IWireService` implementation. + * + * `WireService` is the sole runtime owner of an Agent wire aggregate. It + * combines the model reducer engine with the `wire.jsonl` journal protocol, + * including creation-time sealing, metadata, migrations, atomic healing + * rewrites, blob dehydration and rehydration plus an ordered post-restore hook. + * It is bound at Agent scope because the aggregate identity is the Agent + * identity. + * + * The runtime lookups — the op table behind `restore`, the cross-reducer + * table behind `execute`, and the model / checkpointed-model lists — are the + * fold of the `WireModelContribution` collection (see `wireContribution.ts`): + * the built-in layer drained from the module tables plus every live + * contribution record, refolded on each view change; the collection edge + * never rebuilds the service. Replay tolerance is the fold's unload + * counterpart: a record whose op type is absent from the fold is skipped and + * counted, so a journal stays readable after the unit that contributed its + * vocabulary is withdrawn. + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { BugIndicatingError } from '#/_base/errors/errors'; import { onUnexpectedError } from '#/_base/errors/unexpectedError'; import { Service } from '#/_base/di/service'; +import { type CollectionView } from '#/_base/di/collection'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IAgentBlobService } from '#/agent/blob/agentBlobService'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; +import { type DomainEvent, IEventBus } from '#/app/event/eventBus'; import type { ContentPart } from '#/kosong/contract/message'; +import { OrderedHookSlot } from '#/hooks'; import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; import { StorageError, StorageErrors } from '#/persistence/interface/storage'; @@ -18,30 +45,114 @@ import { resolveWireMigrations, type WireMigration, } from './migration/migration'; +import type { DeepReadonly, ModelDef, PartsTransformer } from './model'; +import type { Op } from './op'; import { AGENT_WIRE_RECORD_KEY, createWireMetadataRecord, isWireRecord, isWireMetadataRecord, - type PartsTransformer, - type RecordDehydrator, + opToWireRecord, + wireRecordToPayload, type WireRecord, } from './record'; +import { + builtinWireContribution, + foldWireContributions, + WireModelContribution, + type FoldedWireRegistry, + type WireModelContributionRecord, +} from './wireContribution'; + +const MAX_DRAIN = 100; + +export class CycleError extends WireError { + constructor(readonly depth: number, readonly opTypes: readonly string[]) { + super( + WireErrors.codes.WIRE_CYCLE, + `Wire dispatch cascade exceeded MAX_DRAIN (${depth}); possible op cycle`, + { details: { depth, opTypes: opTypes.slice(0, 20) } }, + ); + this.name = 'CycleError'; + } +} + +interface ModelInstance { + state: any; +} + +interface OpGroup { + readonly ops: readonly Op[]; + readonly silent: boolean; +} + +type RestorePhase = 'new' | 'restoring' | 'ready' | 'failed'; export class WireService extends Service implements IWireService { declare readonly _serviceBrand: undefined; + readonly hooks: IWireService['hooks'] = { + onDidRestore: new OrderedHookSlot(), + }; + + private readonly models = new Map, ModelInstance>(); private readonly wireScope: string; + private folded: FoldedWireRegistry; + + private restorePhase: RestorePhase = 'new'; + private dispatching = false; + private queue: Op[] = []; + private drainDepth = 0; private persistQueue: Promise | undefined; constructor( @IAgentScopeContext scopeContext: IAgentScopeContext, @IAppendLogStore private readonly log: IAppendLogStore, @IAgentBlobService private readonly blobService: IAgentBlobService, + @IEventBus private readonly eventBus: IEventBus, + @WireModelContribution view: CollectionView, ) { super(); this.wireScope = scopeContext.scope(); this._register(this.log.acquire(this.wireScope, AGENT_WIRE_RECORD_KEY)); + this.folded = this.foldContributions(view); + this._register( + view.onDidChange(() => { + this.folded = this.foldContributions(view); + }), + ); + } + + private foldContributions( + view: CollectionView, + ): FoldedWireRegistry { + return foldWireContributions([builtinWireContribution(), ...view.items]); + } + + getModel(model: ModelDef): DeepReadonly { + return this.ensureModel(model).state as DeepReadonly; + } + + dispatch(...ops: Op[]): void { + if (ops.length === 0) return; + if (this.dispatching) { + this.queue.push(...ops); + return; + } + this.dispatching = true; + try { + this.execute({ ops, silent: false }); + while (this.queue.length > 0) { + if (++this.drainDepth > MAX_DRAIN) { + throw new CycleError(this.drainDepth, this.queue.map((op) => op.type)); + } + this.execute({ ops: this.queue.splice(0), silent: false }); + } + } finally { + this.queue.length = 0; + this.dispatching = false; + this.drainDepth = 0; + } } async seal(): Promise { @@ -49,87 +160,79 @@ export class WireService extends Service implements IWireService { void record; return; } - this.appendRecordLow(createWireMetadataRecord()); + this.appendRecord(createWireMetadataRecord()); } - appendRecord(record: WireRecord, dehydrate?: RecordDehydrator): void { - if (dehydrate === undefined && this.persistQueue === undefined) { - try { - this.appendRecordLow(record); - } catch (error) { - onUnexpectedError(error); - } - return; + async restore(): Promise { + if ( + this.restorePhase === 'restoring' || + this.restorePhase === 'failed' || + this.restorePhase === 'ready' + ) { + throw new BugIndicatingError(`Agent wire restore called while phase is ${this.restorePhase}`); } - const transform: PartsTransformer = (parts) => - this.blobService.offloadParts( - parts as readonly ContentPart[], - ) as Promise; - const queued = (this.persistQueue ?? Promise.resolve()) - .then(async () => { - const output = dehydrate === undefined ? record : await dehydrate(record, transform); - this.appendRecordLow(output); - }) - .catch((error: unknown) => onUnexpectedError(error)); - this.persistQueue = queued; - void queued.then(() => { - if (this.persistQueue === queued) this.persistQueue = undefined; - }); - } + this.restorePhase = 'restoring'; + try { + const source = this.log.read(this.wireScope, AGENT_WIRE_RECORD_KEY); + let migrations: readonly WireMigration[] = []; + let rewrittenRecords: WireRecord[] | undefined; + let newerWireVersion = false; + let recordIndex = 0; + let hasRecords = false; - async *readJournal(): AsyncIterable { - const source = this.log.read(this.wireScope, AGENT_WIRE_RECORD_KEY); - let migrations: readonly WireMigration[] = []; - let rewrittenRecords: WireRecord[] | undefined; - let newerWireVersion = false; - let recordIndex = 0; - let hasRecords = false; - - for await (const candidate of source) { - const sourceRecord: unknown = candidate; - if (!isWireRecord(sourceRecord)) { - this.reportSkippedRecord(undefined, recordIndex, true); - recordIndex++; - continue; - } - if (!hasRecords) { - hasRecords = true; - if (sourceRecord.type !== 'metadata') { - rewrittenRecords = [createWireMetadataRecord()]; - migrations = [migrateV1_4ToV1_5]; - } else if (!isWireMetadataRecord(sourceRecord)) { - throw new StorageError( - StorageErrors.codes.STORAGE_CORRUPTED, - 'Agent wire metadata is malformed', - { details: { scope: this.wireScope, key: AGENT_WIRE_RECORD_KEY } }, - ); - } else if (isNewerWireVersion(sourceRecord.protocol_version)) { - newerWireVersion = true; - } else { - migrations = resolveWireMigrations(sourceRecord.protocol_version); - if (sourceRecord.protocol_version !== WIRE_PROTOCOL_VERSION) { - rewrittenRecords = []; + for await (const candidate of source) { + const sourceRecord: unknown = candidate; + if (!isWireRecord(sourceRecord)) { + this.reportSkippedRecord(undefined, recordIndex, true); + recordIndex++; + continue; + } + if (!hasRecords) { + hasRecords = true; + if (sourceRecord.type !== 'metadata') { + rewrittenRecords = [createWireMetadataRecord()]; + migrations = [migrateV1_4ToV1_5]; + } else if (!isWireMetadataRecord(sourceRecord)) { + throw new StorageError( + StorageErrors.codes.STORAGE_CORRUPTED, + 'Agent wire metadata is malformed', + { details: { scope: this.wireScope, key: AGENT_WIRE_RECORD_KEY } }, + ); + } else if (isNewerWireVersion(sourceRecord.protocol_version)) { + newerWireVersion = true; + } else { + migrations = resolveWireMigrations(sourceRecord.protocol_version); + if (sourceRecord.protocol_version !== WIRE_PROTOCOL_VERSION) { + rewrittenRecords = []; + } } } - } - const migratedRecord = migrateWireRecord(sourceRecord, migrations); - const record = - !newerWireVersion && migratedRecord.type === 'metadata' - ? { ...migratedRecord, protocol_version: WIRE_PROTOCOL_VERSION } - : migratedRecord; - rewrittenRecords?.push(record); - yield record; - if (record.type !== 'metadata') { + const migratedRecord = migrateWireRecord(sourceRecord, migrations); + const record = + !newerWireVersion && migratedRecord.type === 'metadata' + ? { ...migratedRecord, protocol_version: WIRE_PROTOCOL_VERSION } + : migratedRecord; + rewrittenRecords?.push(record); + if (record.type === 'metadata') continue; + + this.replayRecord(record, recordIndex); recordIndex++; } - } - if (!hasRecords) { - rewrittenRecords = [createWireMetadataRecord()]; - } - if (rewrittenRecords !== undefined) { - await this.log.rewrite(this.wireScope, AGENT_WIRE_RECORD_KEY, rewrittenRecords); + if (!hasRecords) { + rewrittenRecords = [createWireMetadataRecord()]; + } + if (rewrittenRecords !== undefined) { + await this.log.rewrite(this.wireScope, AGENT_WIRE_RECORD_KEY, rewrittenRecords); + } + + await this.rehydrateModels(); + this.restorePhase = 'ready'; + await this.hooks.onDidRestore.run({}); + } catch (error) { + this.restorePhase = 'failed'; + throw error; } } @@ -138,6 +241,23 @@ export class WireService extends Service implements IWireService { await this.log.flush(); } + private replayRecord(record: WireRecord, index: number): void { + const descriptor = this.folded.ops.get(record.type); + if (descriptor === undefined) { + this.reportSkippedRecord(record.type, index); + return; + } + const payload = descriptor.schema.safeParse(wireRecordToPayload(record)); + if (!payload.success) { + this.reportSkippedRecord(record.type, index, true); + return; + } + this.execute({ + ops: [{ type: record.type, payload: payload.data, descriptor }], + silent: true, + }); + } + private reportSkippedRecord(type: string | undefined, index: number, malformed = false): void { onUnexpectedError( new WireError( @@ -152,11 +272,88 @@ export class WireService extends Service implements IWireService { ); } - private appendRecordLow(record: WireRecord): void { + private execute(group: OpGroup): void { + for (const op of group.ops) { + const inst = this.ensureModel(op.descriptor.model); + const prev = inst.state; + inst.state = Object.freeze(op.descriptor.apply(prev, op.payload)); + if (!group.silent) { + if (op.descriptor.persist !== false) { + const record = opToWireRecord(op); + this.appendToJournal(record, op.descriptor.model); + } + const event = op.descriptor.toEvent?.(op.payload, inst.state); + if (event !== undefined) { + this.eventBus.publish(event as DomainEvent); + } + } + const crossReducers = this.folded.crossReducers.get(op.type); + if (crossReducers !== undefined) { + for (const entry of crossReducers) { + if (entry.model === op.descriptor.model) continue; + const crossInst = this.ensureModel(entry.model); + crossInst.state = Object.freeze(entry.reducer(crossInst.state, op.payload)); + } + } + } + } + + private ensureModel(def: ModelDef): ModelInstance { + let inst = this.models.get(def); + if (inst === undefined) { + inst = { state: Object.freeze(def.initial()) }; + this.models.set(def, inst); + } + return inst; + } + + private appendToJournal(record: WireRecord, model: ModelDef): void { + const dehydrate = model.blobs?.dehydrate?.bind(model.blobs); + if (dehydrate === undefined && this.persistQueue === undefined) { + try { + this.appendRecord(record); + } catch (error) { + onUnexpectedError(error); + } + return; + } + const transform: PartsTransformer = (parts) => + this.blobService.offloadParts( + parts as readonly ContentPart[], + ) as Promise; + const queued = (this.persistQueue ?? Promise.resolve()) + .then(async () => { + let output = record; + if (dehydrate !== undefined) { + const prepared = dehydrate(record, transform); + output = await prepared; + } + this.appendRecord(output); + }) + .catch((error: unknown) => onUnexpectedError(error)); + this.persistQueue = queued; + void queued.then(() => { + if (this.persistQueue === queued) this.persistQueue = undefined; + }); + } + + private appendRecord(record: WireRecord): void { this.log.append(this.wireScope, AGENT_WIRE_RECORD_KEY, record, { onError: onUnexpectedError, }); } + + private async rehydrateModels(): Promise { + const transform: PartsTransformer = (parts) => + this.blobService.loadParts( + parts as readonly ContentPart[], + ) as Promise; + for (const [def, inst] of this.models) { + if (def.blobs?.rehydrate === undefined) continue; + const result = def.blobs.rehydrate(inst.state, transform); + inst.state = Object.freeze(await result); + } + } } registerScopedService( diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/coldSessionArchive.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/coldSessionArchive.ts deleted file mode 100644 index 795709b18..000000000 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/coldSessionArchive.ts +++ /dev/null @@ -1,122 +0,0 @@ - -import type { ServicesAccessor } from '#/_base/di/instantiation'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { IEventService } from '#/app/event/event'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { getLiveSessionById } from '#/app/sessionManager/sessionLookup'; -import { ISessionIndex, ISessionIndexMirror } from '#/app/sessionIndex/sessionIndex'; -import { buildSessionSummary } from '#/app/sessionIndex/sessionIndexSource'; -import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import type { SessionMeta } from '#/session/sessionMetadata/sessionMetadata'; -import { normalizeSessionMeta, encodeSessionMeta } from '#/session/sessionMetadata/sessionMetadataService'; - -import { sessionScopeOf, legacySessionMetaScopeOf, workspacePersistenceScope } from './internal/addressing'; -import { SessionArchived } from './sessionLifecycleEvents'; - -export type ColdSessionArchiveOutcome = 'updated' | 'not_found'; - -export async function setColdSessionArchived( - accessor: ServicesAccessor, - sessionId: string, - archived: boolean, -): Promise { - const summary = await accessor.get(ISessionIndex).get(sessionId); - if (summary === undefined) return 'not_found'; - const docs = accessor.get(IAtomicDocumentStore); - const metaScope = sessionScopeOf( - workspacePersistenceScope( - accessor.get(IBootstrapService).scope('sessions'), - summary.workspaceId, - ), - sessionId, - ); - let raw = await docs.get(metaScope, 'state.json'); - let legacyMetaScope: string | undefined; - if (raw === undefined) { - legacyMetaScope = legacySessionMetaScopeOf(metaScope); - raw = await docs.get(legacyMetaScope, 'state.json'); - } - if (raw === undefined) return 'not_found'; - const persisted = normalizeSessionMeta(raw, sessionId); - const archivedAt = archived ? Date.now() : undefined; - const nextMeta: SessionMeta = { ...persisted, archived, archivedAt }; - await docs.set(metaScope, 'state.json', encodeSessionMeta(nextMeta)); - if (legacyMetaScope !== undefined) await docs.delete(legacyMetaScope, 'state.json'); - accessor.get(ISessionIndexMirror).record( - buildSessionSummary({ - id: sessionId, - workspaceId: summary.workspaceId, - cwd: nextMeta.cwd ?? summary.cwd, - title: nextMeta.title, - lastPrompt: nextMeta.lastPrompt, - createdAt: nextMeta.createdAt, - updatedAt: nextMeta.updatedAt, - archived, - archivedAt, - custom: nextMeta.custom, - lastTurnReason: nextMeta.lastTurnReason, - }), - ); - if (archived) { - accessor - .get(IEventService) - .publish(new SessionArchived({ payload: { sessionId, workspaceId: summary.workspaceId } })); - } - return 'updated'; -} - -export async function setSessionArchived( - accessor: ServicesAccessor, - sessionId: string, - archived: boolean, -): Promise { - const manager = accessor.get(ISessionManager); - return manager.withLifecycleSerialization(sessionId, async (unguarded) => { - await manager.whenResumeSettled(sessionId).catch(() => undefined); - const live = getLiveSessionById(accessor, sessionId); - if (live !== undefined) { - if (archived) await unguarded.archive(); - else await unguarded.restore(); - return 'updated'; - } - return setColdSessionArchived(accessor, sessionId, archived); - }); -} - -export type SessionArchiveBatchItemOutcome = - | { id: string; ok: true } - | { id: string; ok: false; reason: 'not_found' | 'error'; message: string }; - -export async function setSessionArchivedBatch( - accessor: ServicesAccessor, - ids: readonly string[], - archived: boolean, -): Promise { - const outcomes: (SessionArchiveBatchItemOutcome | undefined)[] = ids.map(() => undefined); - const applyOne = async (id: string): Promise => { - try { - const outcome = await setSessionArchived(accessor, id, archived); - return outcome === 'updated' - ? { id, ok: true } - : { id, ok: false, reason: 'not_found', message: `session ${id} does not exist` }; - } catch (error) { - return { - id, - ok: false, - reason: 'error', - message: error instanceof Error ? error.message : String(error), - }; - } - }; - - const BATCH_CONCURRENCY = 8; - let next = 0; - const workers = Array.from({ length: Math.min(BATCH_CONCURRENCY, ids.length) }, async () => { - while (next < ids.length) { - const index = next++; - outcomes[index] = await applyOne(ids[index] as string); - } - }); - await Promise.all(workers); - return outcomes as SessionArchiveBatchItemOutcome[]; -} diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/addressing.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/addressing.ts index f9c4876e6..5aa167b4c 100644 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/addressing.ts +++ b/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/addressing.ts @@ -1,3 +1,15 @@ +/** + * `sessionLifecycle` domain — persistence addressing along the handler chain. + * + * Pure functions deriving the persistence scope strings and on-disk + * directories from the handler's `persistenceScope` (`sessions/{wd_id}`): + * session = `{handlerScope}/{session_id}`, agent = + * `{sessionScope}/agents/{agent_id}`. Under the local/local runtime these + * are byte-identical to the layout the pre-Workspace engine wrote, so v1 + * readers (`session_index.jsonl`, snapshot readers) keep working unchanged. + * Own no scoped state. + */ + import { join } from 'pathe'; export function workspacePersistenceScope(sessionsScope: string, workspaceId: string): string { @@ -15,7 +27,3 @@ export function sessionDirOf(homeDir: string, handlerScope: string, sessionId: s export function agentScopeOf(sessionScope: string, agentId: string): string { return `${sessionScope}/agents/${agentId}`; } - -export function legacySessionMetaScopeOf(sessionScope: string): string { - return `${sessionScope}/session-meta`; -} diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/forkTurnSlice.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/forkTurnSlice.ts deleted file mode 100644 index 85d3450ac..000000000 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/internal/forkTurnSlice.ts +++ /dev/null @@ -1,221 +0,0 @@ -import { Error2, ErrorCodes } from '#/errors'; -import type { ContentPart } from '#/kosong/contract/message'; -import { - promptMetadataTextFromContentParts, - promptMetadataTextFromText, -} from '#/agent/prompt/promptMetadataText'; -import type { WireRecord } from '#/wire/record'; - -export interface MainTurnSlice { - readonly records: readonly WireRecord[]; - readonly cutoffTime?: number; - readonly lastPrompt?: string; -} - -export function assertForkTurnIndex(turnIndex: number | undefined): void { - if (turnIndex === undefined) return; - if (Number.isSafeInteger(turnIndex) && turnIndex >= 0) return; - throw new Error2( - ErrorCodes.REQUEST_INVALID, - 'forkSession turnIndex must be a non-negative safe integer', - { details: { turnIndex } }, - ); -} - -export function sliceMainRecordsAtTurn( - records: readonly WireRecord[], - sourceSessionId: string, - turnIndex: number, -): MainTurnSlice { - const turnStarts: number[] = []; - for (let index = 0; index < records.length; index += 1) { - if (isUserVisibleTurnRecord(records[index]!)) turnStarts.push(index); - } - const start = turnStarts[turnIndex]; - if (start === undefined) { - throw new Error2( - ErrorCodes.REQUEST_INVALID, - `Turn ${String(turnIndex)} was not found in session "${sourceSessionId}"`, - { details: { turnIndex, availableTurns: turnStarts.length } }, - ); - } - - const end = turnStarts[turnIndex + 1] ?? records.length; - const retainedTurnInputs = turnInputIndicesThrough(records, turnIndex); - const retained = records - .slice(0, end) - .filter( - (record, index) => !isUserVisibleTurnInputRecord(record) || retainedTurnInputs.has(index), - ); - const cutoffTimes = retained - .map(recordTime) - .filter((time): time is number => time !== undefined); - const lastPrompt = promptMetadataFromTurnRecord(records[start]!); - return { - records: retained, - cutoffTime: cutoffTimes.length === 0 ? undefined : Math.max(...cutoffTimes), - lastPrompt, - }; -} - -export function sliceSubagentRecordsAtTime( - records: readonly WireRecord[], - cutoffTime: number | undefined, -): readonly WireRecord[] { - if (cutoffTime === undefined) return []; - let end = records.length; - for (let index = 0; index < records.length; index += 1) { - const time = recordTime(records[index]!); - if (time !== undefined && time > cutoffTime) { - end = index; - break; - } - } - return records.slice(0, end); -} - -function isUserVisibleTurnRecord(record: WireRecord): boolean { - if (record.type !== 'context.append_message') return false; - const message = asRecord(record['message']); - if (message === undefined || message['role'] !== 'user') return false; - const origin = asRecord(message['origin']); - switch (origin?.['kind']) { - case undefined: - case 'user': - return true; - case 'skill_activation': - case 'plugin_command': - return origin?.['trigger'] === 'user-slash'; - case 'shell_command': - return origin?.['phase'] === 'input'; - default: - return false; - } -} - -function isUserVisibleTurnInputRecord(record: WireRecord): boolean { - if (record.type !== 'turn.prompt' && record.type !== 'turn.steer') return false; - const origin = asRecord(record['origin']); - switch (origin?.['kind']) { - case 'user': - return true; - case 'skill_activation': - case 'plugin_command': - return origin?.['trigger'] === 'user-slash'; - case 'shell_command': - return origin?.['phase'] === 'input'; - default: - return false; - } -} - -function turnInputIndicesThrough( - records: readonly WireRecord[], - turnIndex: number, -): ReadonlySet { - const pending: number[] = []; - const retained = new Set(); - let visibleTurnIndex = 0; - for (let index = 0; index < records.length; index += 1) { - const record = records[index]!; - if (isUserVisibleTurnInputRecord(record)) { - pending.push(index); - continue; - } - if (!isUserVisibleTurnRecord(record)) continue; - - const matchAt = findMatchingTurnInput(records, pending, record); - if (matchAt !== -1) { - const [inputIndex] = pending.splice(matchAt, 1); - if (visibleTurnIndex <= turnIndex && inputIndex !== undefined) { - retained.add(inputIndex); - } - } - visibleTurnIndex += 1; - } - return retained; -} - -function findMatchingTurnInput( - records: readonly WireRecord[], - pending: readonly number[], - turnRecord: WireRecord, -): number { - const exact = pending.findIndex((index) => - turnInputMatchesRecord(records[index]!, turnRecord, true), - ); - if (exact !== -1) return exact; - return pending.findIndex((index) => turnInputMatchesRecord(records[index]!, turnRecord, false)); -} - -function turnInputMatchesRecord( - inputRecord: WireRecord, - turnRecord: WireRecord, - compareContent: boolean, -): boolean { - if (inputRecord.type !== 'turn.prompt' && inputRecord.type !== 'turn.steer') return false; - if (turnRecord.type !== 'context.append_message') return false; - const message = asRecord(turnRecord['message']); - if (message === undefined || message['role'] !== 'user') return false; - const inputKind = asRecord(inputRecord['origin'])?.['kind']; - if (typeof inputKind !== 'string') return false; - const messageKind = asRecord(message['origin'])?.['kind']; - if (messageKind !== undefined && typeof messageKind !== 'string') return false; - if (!sameTurnOrigin(inputKind, messageKind)) return false; - return ( - !compareContent || - JSON.stringify(inputRecord['input']) === JSON.stringify(message['content']) - ); -} - -function sameTurnOrigin(inputKind: string, messageKind: string | undefined): boolean { - if (inputKind === 'user') return messageKind === undefined || messageKind === 'user'; - return inputKind === messageKind; -} - -function recordTime(record: WireRecord): number | undefined { - if (typeof record.time === 'number' && Number.isFinite(record.time)) return record.time; - if (record.type === 'metadata') { - const createdAt = record['created_at']; - if (typeof createdAt === 'number' && Number.isFinite(createdAt)) return createdAt; - } - return undefined; -} - -function promptMetadataFromTurnRecord(record: WireRecord): string | undefined { - if (record.type !== 'context.append_message') return undefined; - const message = asRecord(record['message']); - if (message === undefined || message['role'] !== 'user') return undefined; - const origin = asRecord(message['origin']); - if (origin?.['kind'] === 'skill_activation') { - const name = origin['skillName']; - if (typeof name !== 'string') return undefined; - return promptMetadataTextFromText(slashCommandText(`/${name}`, origin['skillArgs'])); - } - if (origin?.['kind'] === 'plugin_command') { - const pluginId = origin['pluginId']; - const commandName = origin['commandName']; - if (typeof pluginId !== 'string' || typeof commandName !== 'string') return undefined; - return promptMetadataTextFromText( - slashCommandText(`/${pluginId}:${commandName}`, origin['commandArgs']), - ); - } - const content = message['content']; - if (!Array.isArray(content)) return undefined; - const activations = origin?.['skillActivations']; - const bundled = origin?.['kind'] === 'user' && Array.isArray(activations) ? activations.length : 0; - return promptMetadataTextFromContentParts( - (bundled === 0 ? content : content.slice(bundled)) as readonly ContentPart[], - ); -} - -function slashCommandText(command: string, args: unknown): string { - const trimmed = typeof args === 'string' ? args.trim() : undefined; - return trimmed === undefined || trimmed.length === 0 ? command : `${command} ${trimmed}`; -} - -function asRecord(value: unknown): Record | undefined { - return typeof value === 'object' && value !== null && !Array.isArray(value) - ? (value as Record) - : undefined; -} diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycle.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycle.ts index 4ecad1040..6808b4678 100644 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycle.ts +++ b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycle.ts @@ -1,18 +1,50 @@ +/** + * `sessionLifecycle` domain — per-handler session lifecycle contract. + * + * Defines the public contract of one workspace handler: the + * `CreateSessionOptions`, `ForkSessionOptions`, `CreateChildSessionOptions`, + * `ResumeSessionOptions`, and the `ISessionLifecycleService` used to create + * sessions (`create`), look up the live ones (`get` / `list`), close them + * (`close`), archive/restore them, delete them (`delete` — closes a live + * session first, then removes its persisted data and its index entries; + * unknown ids raise `session.not_found`), fork them (`fork`), and + * fork-then-tag + * them as direct children (`createChild`) — always as child scopes of THIS + * handler's Workspace scope, so a handler owns exactly the sessions of one + * workspace and fork never crosses handlers. Announces lifecycle transitions + * through `onDidCreateSession` / `onDidCloseSession` / `onDidArchiveSession` + * / `onDidForkSession`; the ordered hook slots are per-session seeds. + * Workspace-scope services that must participate in a session's creation + * (read its seeded facts, contribute a session seed, attach teardown to its + * lifetime) subscribe to `onWillCreateSession` — the participation surface + * speaks the session domain's own vocabulary, so the lifecycle depends on + * neither its participants nor the DI kernel's assembly mechanics. + * Workspace-scoped — one instance per materialized handler. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ISessionScopeHandle } from '#/_base/di/scope'; -import { type Event, type IWaitUntil } from '#/_base/event'; +import type { Event } from '#/_base/event'; import type { BindAgentInput } from '#/agent/profile/profile'; import type { McpServerConfig } from '#/mcpCore/config-schema'; +import type { + SessionCloseReason, + SessionCreateSource, +} from '#/session/sessionLifecycleHooks/sessionLifecycleHooks'; -export type SessionCreateSource = 'startup' | 'resume' | 'fork'; - -export type SessionCloseReason = 'exit' | 'archive'; +export type { SessionCloseReason, SessionCreateSource }; export interface CreateSessionOptions { readonly sessionId?: string; readonly workDir: string; readonly additionalDirs?: readonly string[]; readonly mainAgentBinding?: BindAgentInput; + /** + * Ephemeral per-session MCP servers: connected only for this session, + * visible only to this session (an entry shadows a workspace server of the + * same name), never persisted to any MCP config file, and released when + * the session closes. Not carried over by fork or resume. + */ readonly mcpServers?: Readonly>; } @@ -21,11 +53,16 @@ export interface ForkSessionOptions { readonly newSessionId?: string; readonly title?: string; readonly metadata?: Record; - readonly turnIndex?: number; } export interface ResumeSessionOptions { readonly additionalDirs?: readonly string[]; + /** + * Ephemeral per-session MCP servers — the same semantics as + * `CreateSessionOptions.mcpServers`: a session-owned overlay connected for + * this session only, never persisted, released when the session closes. + * Ignored when the session is already live (resume passes through). + */ readonly mcpServers?: Readonly>; } @@ -62,6 +99,20 @@ export interface SessionForkedEvent { readonly handle: ISessionScopeHandle; } +/** + * Participation surface of `onWillCreateSession` — the business-lifecycle + * moment "a session is being created", fired synchronously before the new + * session's services activate (the `will` half of `onDidCreateSession`; + * resume and fork are creations too). Workspace-scope participants step + * into the creation through the session domain's own vocabulary — read the + * session's seeded facts (`readSeed`), contribute or replace a session seed + * (`contributeSeed`; a seed already projected by the workspace seed + * adapters is replaced), and attach teardown work to the session's lifetime + * (`onSessionDispose` — runs with the session's teardown on every path: + * close, archive, delete, a failed create, workspace teardown). The event + * carries only facts the lifecycle itself owns; anything a participant + * needs beyond them travels as a session-domain seed. + */ export interface SessionWillCreateEvent { readonly sessionId: string; readSeed(id: ServiceIdentifier): T; @@ -73,8 +124,7 @@ export interface ISessionLifecycleService { readonly _serviceBrand: undefined; readonly onWillCreateSession: Event; - readonly onDidCreateSession: Event; - readonly onWillCloseSession: Event; + readonly onDidCreateSession: Event; readonly onDidCloseSession: Event; readonly onDidArchiveSession: Event; readonly onDidForkSession: Event; diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleEvents.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleEvents.ts deleted file mode 100644 index d762ddd64..000000000 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleEvents.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* oxlint-disable typescript-eslint/no-unsafe-declaration-merging, eslint-plugin-import/namespace -- Event2 class+payload-interface declaration merging is the sanctioned event-declaration idiom. */ -import { Event2 } from '#/app/event/event2'; - -export interface SessionArchivedPayload { - readonly sessionId: string; - readonly workspaceId: string; -} - -export class SessionArchived extends Event2<{ readonly payload: SessionArchivedPayload }> { - static override readonly type = 'event.session.archived'; -} -export interface SessionArchived { - readonly payload: SessionArchivedPayload; -} - -export interface SessionCreatedPayload { - readonly agentId: string; - readonly sessionId: string; - readonly session: unknown; -} - -export class SessionCreated extends Event2<{ readonly payload: SessionCreatedPayload }> { - static override readonly type = 'event.session.created'; -} -export interface SessionCreated { - readonly payload: SessionCreatedPayload; -} diff --git a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts index b5ed990d8..2eecd65f3 100644 --- a/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts +++ b/packages/agent-core-v2/src/workspace/sessionLifecycle/sessionLifecycleService.ts @@ -1,20 +1,91 @@ +/** + * `sessionLifecycle` domain — `ISessionLifecycleService` implementation. + * + * Owns the registry of THIS handler's open Session child scopes, creating + * them through the DI scope tree (children of the handler's Workspace + * scope) and seeding each with its identity, storage addressing derived + * from the handler's persistence scope, and a per-session lifecycle-hooks + * slots instance it runs around create/close, + * tearing sessions down on close/archive — archiving flags the session's + * metadata, removes its agents, restoring clears + * the archived flag, and broadcasts the transition; deleting closes a live + * session through the same flow, then removes the session directory + * (metadata, agent wire records, plans, logs), evicts the index read-model + * entry, and appends a `deleted` tombstone to the shared + * `session_index.jsonl`, raising `session.not_found` for ids this handler + * never persisted. Pending metadata writes and the index mirror are + * drained before any teardown, so a listing right after close/archive/delete + * never reads a stale outcome. Session start and + * resume failures are reported through telemetry. Each Session scope + * receives a telemetry view bound to its session id, while failures before + * a scope is available use an ephemeral context view. Closing a session + * never touches the handler itself. + * Every Session scope is also seeded with the handler's shared workspace + * resources as pure-data read views (the injection contracts) — discovery, + * watching and connecting all live on the Workspace-scope services; session + * consumers read the seeds and refresh off their change events. The five + * workspace-projection seeds are provided by the seed-adapter units + * installed with the scope (`installSessionSeedAdapters`), not by `extra`. + * Materializes the session's initial metadata on + * creation. Bound at Workspace scope. + * Persisted sessions are discovered through the session-index read model. + * On create / fork the + * session is also appended to the shared `session_index.jsonl` so v1 clients + * (TUI, export) can discover sessions created by the v2 engine; the entry is + * indexed under the handler's workspace id — the same id seeding the + * session's storage scope — so an alias spelling of the workDir cannot split + * the session into a bucket v1 readers never look in. Fork flushes + * live Agent wire journals, normalizes a missing protocol envelope, and + * appends the fork boundary before restoring the target Agent; fork is + * confined to this handler (source and target share the workspace bucket). + * On + * materialize, the agent-profile loaders' `ready` is awaited + * before the handle is published — agent-file discovery is local- + * fs and cheap, and a resumed session's first turn must see file-defined + * agent types in the `Agent` tool description; only the `fatal` explicit + * loader rejects, exactly the case that should + * fail fast, and on that failure the half-materialized handle is disposed + * instead of poisoning the session cache, and the explicit loader is re-armed + * with a fire-and-forget `reload()` so a fixed agent file unblocks later + * creates + * (the workspace skill catalog, by contrast, is kicked fire-and-forget). + * The handler's shared MCP manager is NOT awaited before create/resume + * returns — it connects fire-and-forget at Workspace scope, and the seeded + * handle's `ready` promise lets the agent's LLM steps wait on it instead + * (see `AgentMcpService`). A session created with ephemeral `mcpServers` + * gets them seeded verbatim (`ISessionEphemeralMcpServers`); connecting + * them is the MCP domain's own concern — `workspaceMcp` subscribes to this + * service's `onWillCreateSession`, reads the session's seeds through the + * event's session-domain surface (`readSeed` / `contributeSeed` / + * `onSessionDispose`), contributes its session overlay handle, and attaches + * the overlay's shutdown to the session's teardown, so this service never + * depends on MCP. + * The session-level services whose subscriptions + * must exist before the first agent / turn (external hooks, cron, the + * secondary-model startup warning) opt into `OnScopeCreated` activation. + */ + import { randomUUID } from 'node:crypto'; import { join } from 'pathe'; +import { ulid } from 'ulid'; -import type { IInstantiationService } from '#/_base/di/instantiation'; +import { IInstantiationService } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; import { createScopedChildHandle, type ISessionScopeHandle, + ScopeActivation, + registerScopedService, } from '#/_base/di/scope'; import { unwrapErrorCause } from '#/_base/errors/errors'; -import { AsyncEmitter, Emitter, type Event, type IWaitUntil } from '#/_base/event'; -import { drainLogCloses } from '#/_base/log/logService'; +import { Emitter, type Event } from '#/_base/event'; import { DEFAULT_PLAN_MODE_SECTION } from '#/features/plan/configSection'; import { IAgentPlanService } from '#/features/plan/plan'; -import { LifecycleScope } from '#/app/scopes'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; +import { CRON_SESSION_TAG, type CronTask } from '#/app/cron/cronTask'; +import { ICronTaskPersistence } from '#/app/cron/cronTaskPersistence'; import { IConfigService } from '#/app/config/config'; import { IEventService } from '#/app/event/event'; import { @@ -26,36 +97,33 @@ import { } from '#/app/sessionIndex/sessionIndex'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { ErrorCodes, Error2, isError2 } from '#/errors'; +import { createHooks } from '#/hooks'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { IHostFileSystem, type HostDirEntry } from '#/os/interface/hostFileSystem'; import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import { - IAgentLifecycleService, - MAIN_AGENT_ID, -} from '#/session/agentLifecycle/agentLifecycle'; +import { IAgentLifecycleService, MAIN_AGENT_ID } from '#/session/agentLifecycle/agentLifecycle'; import { ensureMainAgent } from '#/session/agentLifecycle/mainAgent'; import { labelsFromAgentMeta } from '#/session/agentLifecycle/subagentMetadata'; import { ISessionContext, sessionContextSeed } from '#/session/sessionContext/sessionContext'; import { sessionEphemeralMcpServersSeed } from '#/session/mcp/ephemeralMcpServers'; import { sessionAgentProfileCatalogSeed } from '#/session/sessionAgentProfileCatalog/agentProfileCatalogSeed'; +import { installSessionSeedAdapters } from '#/session/sessionSeed/sessionSeedAdapters'; +import { + ISessionLifecycleHooks, + sessionLifecycleHooksSeed, + type SessionLifecycleHookSlots, +} from '#/session/sessionLifecycleHooks/sessionLifecycleHooks'; import { ISessionMetadata, type SessionMeta } from '#/session/sessionMetadata/sessionMetadata'; -import { ISessionSkillCatalogData } from '#/features/skill/session/skillCatalogData'; -import { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; -import { ISessionMcpHandle } from '#/session/mcp/sessionMcpHandle'; -import { ISessionWorkspaceInfo } from '#/session/workspaceInfo/workspaceInfo'; -import { drainSessionMetadataWrites, toEpochMs } from '#/session/sessionMetadata/sessionMetadataService'; +import { drainSessionMetadataWrites } from '#/session/sessionMetadata/sessionMetadataService'; +import { ISessionProcessRunner } from '#/session/process/processRunner'; import { ISessionToolPolicy } from '#/session/sessionToolPolicy/sessionToolPolicy'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { AGENT_WIRE_RECORD_KEY, createWireMetadataRecord, type WireRecord, } from '#/wire/record'; -import { IModelCatalog } from '#/kosong/model/catalog'; -import { IModelService } from '#/kosong/model/model'; -import { IProviderService } from '#/kosong/provider/provider'; -import { IFlagService } from '#/app/flag/flag'; -import { assertValidSubagentModelConfig } from '#/session/subagent/configSection'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; import { IUserAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoader'; import { IPluginAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader'; @@ -69,19 +137,8 @@ import { IWorkspaceAgentProfileLoader, } from '#/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader'; import { IWorkspaceDirs } from '#/workspace/workspaceDirs/workspaceDirs'; -import { IAgentActivityView } from '#/agent/activityView/activityView'; -import { IWorkspaceSkillCatalog } from '#/features/skill/workspace/workspaceSkillCatalog'; -import { IWorkspaceInstructionsService } from '#/workspace/workspaceInstructions/workspaceInstructions'; -import { IWorkspaceMcpService } from '#/workspace/workspaceMcp/workspaceMcp'; -import { PLUGIN_SKILL_SOURCE_ID } from '#/features/skill/catalog/skillSource'; import { agentScopeOf, sessionDirOf, sessionScopeOf } from './internal/addressing'; -import { SessionArchived } from './sessionLifecycleEvents'; -import { - assertForkTurnIndex, - sliceMainRecordsAtTurn, - sliceSubagentRecordsAtTime, -} from './internal/forkTurnSlice'; import { type CreateChildSessionOptions, type CreateSessionOptions, @@ -100,15 +157,7 @@ type MaterializeSessionOptions = Omit & { readonly sessionId: string; }; -const NO_ABORT = new AbortController().signal; - -const SESSION_CREATE_RELOAD_SKILL_SOURCES: readonly string[] = [ - 'user', - 'explicit', - 'extra', - PLUGIN_SKILL_SOURCE_ID, -]; - +// NOTE: stays Disposable — its own 'get' and 'config' collide with the Fiber export class SessionLifecycleService extends Disposable implements ISessionLifecycleService { declare readonly _serviceBrand: undefined; private readonly sessions = new Map(); @@ -117,16 +166,8 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec ); readonly onWillCreateSession: Event = this._onWillCreateSession.event; - private readonly _onDidCreateSession = this._register( - new AsyncEmitter(), - ); - readonly onDidCreateSession: Event = - this._onDidCreateSession.event; - private readonly _onWillCloseSession = this._register( - new AsyncEmitter(), - ); - readonly onWillCloseSession: Event = - this._onWillCloseSession.event; + private readonly _onDidCreateSession = this._register(new Emitter()); + readonly onDidCreateSession: Event = this._onDidCreateSession.event; private readonly _onDidCloseSession = this._register(new Emitter()); readonly onDidCloseSession: Event = this._onDidCloseSession.event; private readonly _onDidArchiveSession = this._register(new Emitter()); @@ -134,18 +175,19 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec private readonly _onDidForkSession = this._register(new Emitter()); readonly onDidForkSession: Event = this._onDidForkSession.event; private readonly resuming = new Map>(); - private readonly resumeFailures = new Map(); constructor( - private readonly instantiation: IInstantiationService, + @IInstantiationService private readonly instantiation: IInstantiationService, @IWorkspaceContext private readonly workspaceContext: IWorkspaceContext, @IBootstrapService private readonly bootstrap: IBootstrapService, @IConfigService private readonly config: IConfigService, + @IHostEnvironment private readonly hostEnv: IHostEnvironment, @ISessionIndex private readonly index: ISessionIndex, @ISessionIndexMirror private readonly indexMirror: ISessionIndexMirror, @IAppendLogStore private readonly appendLogStore: IAppendLogStore, @IAtomicDocumentStore private readonly docs: IAtomicDocumentStore, @IHostFileSystem private readonly hostFs: IHostFileSystem, + @ICronTaskPersistence private readonly cronStore: ICronTaskPersistence, @IEventService private readonly event: IEventService, @ITelemetryService private readonly telemetry: ITelemetryService, @IWorkspaceAgentProfileLoader @@ -159,17 +201,9 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec @IPluginAgentProfileLoader private readonly pluginAgentProfileLoader: IPluginAgentProfileLoader, @IWorkspaceDirs private readonly workspaceDirs: IWorkspaceDirs, - @IWorkspaceSkillCatalog private readonly workspaceSkillCatalog: IWorkspaceSkillCatalog, - @IWorkspaceInstructionsService private readonly workspaceInstructions: IWorkspaceInstructionsService, - @IWorkspaceMcpService private readonly workspaceMcp: IWorkspaceMcpService, - @IModelCatalog private readonly modelCatalog: IModelCatalog, - @IModelService private readonly models: IModelService, - @IProviderService private readonly providers: IProviderService, - @IFlagService private readonly flags: IFlagService, - onDispose?: () => void, + @ISessionProcessRunner private readonly processRunner: ISessionProcessRunner, ) { super(); - if (onDispose !== undefined) this._register({ dispose: onDispose }); } private get workspaceId(): string { @@ -182,33 +216,25 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec async create(opts: CreateSessionOptions): Promise { const sessionId = opts.sessionId ?? createSessionId(); - await this.workspaceSkillCatalog - .reloadSources(SESSION_CREATE_RELOAD_SKILL_SOURCES) - .catch(() => undefined); const handle = await this.materializeSession({ ...opts, sessionId }); try { - const agents = handle.accessor.get(IAgentLifecycleService); const main = opts.mainAgentBinding === undefined ? undefined - : await agents.create({ + : await handle.accessor.get(IAgentLifecycleService).create({ agentId: MAIN_AGENT_ID, binding: opts.mainAgentBinding, }); if (this.config.get(DEFAULT_PLAN_MODE_SECTION) === true) { const planAgent = main ?? (await ensureMainAgent(handle)); - const planHandle = agents.handleOf(planAgent.agentId); - if (planHandle === undefined) { - throw new Error2(ErrorCodes.AGENT_NOT_FOUND, 'Main agent was not found'); - } - await planHandle.accessor.get(IAgentPlanService).enter(); + await planAgent.accessor.get(IAgentPlanService).enter(); } await this.appendSessionIndexEntry(sessionId, opts.workDir); } catch (error) { const sessionDir = handle.accessor.get(ISessionContext).sessionDir; this.sessions.delete(sessionId); await this.drainAgents(handle).catch(() => {}); - void handle.dispose(); + handle.dispose(); await this.hostFs.remove(sessionDir).catch(() => {}); throw error; } @@ -216,17 +242,11 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec return handle; } - private async assertSubagentModelPoolPreFlight(): Promise { - await Promise.all([this.config.ready, this.models.ready, this.providers.ready]); - assertValidSubagentModelConfig(this.config, this.flags, this.modelCatalog); - } - private async materializeSession(opts: MaterializeSessionOptions): Promise { const workspaceId = this.workspaceId; const sessionScope = sessionScopeOf(this.handlerScope, opts.sessionId); const sessionDir = sessionDirOf(this.bootstrap.homeDir, this.handlerScope, opts.sessionId); const metaScope = sessionScope; - await this.assertSubagentModelPoolPreFlight(); await this.workspaceDirs.ready; await this.workspaceDirs.mergeAdditionalDirs(opts.workDir, opts.additionalDirs ?? []); const ctx: ISessionContext = { @@ -239,6 +259,11 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec scope: (subKey?: string): string => subKey === undefined || subKey === '' ? sessionScope : `${sessionScope}/${subKey}`, }; + const hooks = createHooks([ + 'onDidCreateSession', + 'onWillCloseSession', + ]); + await this.hostEnv.ready; const handle = createScopedChildHandle( this.instantiation, LifecycleScope.Session, @@ -246,18 +271,20 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec { seeds: [ ...sessionContextSeed(ctx), + ...sessionLifecycleHooksSeed(hooks), [ITelemetryService, this.telemetry.withContext({ sessionId: opts.sessionId })], ...sessionAgentProfileCatalogSeed({ _serviceBrand: undefined, workspaceKey: workspaceId, }), - [ISessionSkillCatalogData, this.workspaceSkillCatalog.sessionData()], - [ISessionInstructionsProvider, this.workspaceInstructions.sessionProvider()], - [ISessionMcpHandle, this.workspaceMcp.sessionHandle()], - [ISessionWorkspaceInfo, this.workspaceDirs.sessionInfo()], + [ISessionProcessRunner, this.processRunner], ...sessionEphemeralMcpServersSeed(opts.mcpServers ?? {}), ], configureContainer: (container) => { + installSessionSeedAdapters(container); + // The will-create moment is a business-lifecycle event; the DI + // container behind the participation surface stays this service's + // implementation detail. this._onWillCreateSession.fire({ sessionId: opts.sessionId, readSeed: (id) => container.invokeFunction((accessor) => accessor.get(id)), @@ -282,7 +309,7 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec this.pluginAgentProfileLoader.ready, ]); } catch (error) { - void handle.dispose(); + handle.dispose(); void this.explicitAgentProfileLoader.reload().catch(() => undefined); throw error; } @@ -301,7 +328,10 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec } private async announceCreated(event: SessionCreatedEvent): Promise { - await this._onDidCreateSession.fireAsync(event, NO_ABORT); + await event.handle.accessor + .get(ISessionLifecycleHooks) + .onDidCreateSession.run({ source: event.source }); + this._onDidCreateSession.fire(event); event.handle.accessor .get(ITelemetryService) .track2('session_started', { resumed: event.source === 'resume' }); @@ -317,7 +347,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec if (inflight !== undefined) return inflight; const live = this.sessions.get(sessionId); if (live !== undefined) return Promise.resolve(live); - this.resumeFailures.delete(sessionId); const promise = this.doResume(sessionId, opts) .catch((error: unknown) => { this.telemetry @@ -325,7 +354,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec .track2('session_load_failed', { reason: isError2(error) ? error.code : error instanceof Error ? error.name : 'unknown', }); - this.resumeFailures.set(sessionId, error instanceof Error ? error : new Error('session resume failed')); throw error; }) .finally(() => this.resuming.delete(sessionId)); @@ -333,12 +361,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec return promise; } - async whenResumeSettled(sessionId: string): Promise { - await this.resuming.get(sessionId); - const failure = this.resumeFailures.get(sessionId); - if (failure !== undefined) throw failure; - } - private async doResume( sessionId: string, opts?: ResumeSessionOptions, @@ -356,17 +378,11 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec additionalDirs: opts?.additionalDirs, mcpServers: opts?.mcpServers, }); - try { - const agents = handle.accessor.get(IAgentLifecycleService); - if (agents.get(MAIN_AGENT_ID) === undefined) { - await agents.create({ agentId: MAIN_AGENT_ID }); - } - await this.announceCreated({ sessionId, handle, source: 'resume' }); - } catch (error) { - this.sessions.delete(sessionId); - void handle.dispose(); - throw error; + const agents = handle.accessor.get(IAgentLifecycleService); + if (agents.get(MAIN_AGENT_ID) === undefined) { + await agents.create({ agentId: MAIN_AGENT_ID }); } + await this.announceCreated({ sessionId, handle, source: 'resume' }); return handle; } @@ -384,11 +400,9 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec await this.announceWillClose({ sessionId, handle, reason: 'exit' }); this.sessions.delete(sessionId); await this.drainAgents(handle); - await this.appendLogStore.drainRetirements(); await drainSessionMetadataWrites(); await this.indexMirror.drain(); - void handle.dispose(); - await drainLogCloses(); + handle.dispose(); this._onDidCloseSession.fire({ sessionId }); } @@ -398,18 +412,15 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec const meta = handle.accessor.get(ISessionMetadata); await meta.setArchived(true); await this.drainAgents(handle); - await this.appendLogStore.drainRetirements(); - this.event.publish( - new SessionArchived({ - payload: { sessionId, workspaceId: this.workspaceContext.workspaceId }, - }), - ); + this.event.publish({ + type: 'event.session.archived', + payload: { sessionId }, + }); await this.announceWillClose({ sessionId, handle, reason: 'archive' }); this.sessions.delete(sessionId); await drainSessionMetadataWrites(); await this.indexMirror.drain(); - void handle.dispose(); - await drainLogCloses(); + handle.dispose(); this._onDidArchiveSession.fire({ sessionId }); } @@ -444,13 +455,15 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec } private async announceWillClose(event: SessionWillCloseEvent): Promise { - await this._onWillCloseSession.fireAsync(event, NO_ABORT); + await event.handle.accessor + .get(ISessionLifecycleHooks) + .onWillCloseSession.run({ reason: event.reason }); } private async drainAgents(handle: ISessionScopeHandle): Promise { const agentLifecycle = handle.accessor.get(IAgentLifecycleService); for (const agent of agentLifecycle.list()) { - await agentLifecycle.remove(agent); + await agentLifecycle.remove(agent.id); } } @@ -465,27 +478,14 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec ) { throw new Error2(ErrorCodes.SESSION_NOT_FOUND, `session ${sourceId} does not exist`); } - if (sourceHandle !== undefined) { - const sourceAgents = sourceHandle.accessor.get(IAgentLifecycleService); - for (const agent of sourceAgents.list()) { - const agentHandle = sourceAgents.handleOf(agent.agentId); - if (agentHandle === undefined) continue; - if (agentHandle.accessor.get(IAgentActivityView).state().turn !== undefined) { - throw new Error2( - ErrorCodes.SESSION_FORK_ACTIVE_TURN, - `Session "${sourceId}" cannot be forked while a turn is running`, - { details: { sessionId: sourceId } }, - ); - } - } - } - assertForkTurnIndex(opts.turnIndex); let targetId: string | undefined; let target: ISessionScopeHandle | undefined; let targetSessionDir: string | undefined; try { - await this.assertSubagentModelPoolPreFlight(); + // A turn that just ended may still have its outcome write queued; + // settle pending metadata writes before reading the source for + // inheritance, or the fork could copy a stale (or absent) outcome. await drainSessionMetadataWrites(); const sourceMeta = sourceHandle !== undefined @@ -500,15 +500,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec ); } - const turnSlice = - opts.turnIndex === undefined - ? undefined - : sliceMainRecordsAtTurn( - await this.readSourceWireRecords(sourceHandle, sourceId, MAIN_AGENT_ID), - sourceId, - opts.turnIndex, - ); - targetSessionDir = sessionDirOf(this.bootstrap.homeDir, this.handlerScope, targetId); await this.copySessionFiles( sessionDirOf(this.bootstrap.homeDir, this.handlerScope, sourceId), @@ -524,38 +515,32 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec const sourceAgents = sourceMeta?.agents ?? {}; const agentIds = Object.keys(sourceAgents); - const retainedAgentIds: string[] = []; for (const agentId of agentIds) { - let slicedRecords: readonly WireRecord[] | undefined; - if (turnSlice !== undefined) { - if (agentId === MAIN_AGENT_ID) { - slicedRecords = turnSlice.records; - } else { - const subagentRecords = sliceSubagentRecordsAtTime( - await this.readSourceWireRecords(sourceHandle, sourceId, agentId), - turnSlice.cutoffTime, - ); - if (subagentRecords.length === 0) continue; - slicedRecords = subagentRecords; - } - } await this.copyAgentWire({ sourceHandle, sourceSessionId: sourceId, agentId, targetSessionId: targetCtx.sessionId, - records: slicedRecords, }); - retainedAgentIds.push(agentId); - } - - if (turnSlice !== undefined) { - await this.pruneTruncatedForkFiles(targetSessionDir, agentIds, retainedAgentIds); } const title = opts.title ?? `Fork: ${sourceMeta?.title || sourceId}`; + await targetMeta.update({ + title, + isCustomTitle: opts.title !== undefined ? true : sourceMeta?.isCustomTitle === true, + forkedFrom: sourceId, + archived: false, + lastPrompt: sourceMeta?.lastPrompt, + // The fork continues the source's conversation, so it inherits the + // last turn's outcome too — otherwise a restart would drop a failure + // the warm fork was still reporting. + lastTurnReason: sourceMeta?.lastTurnReason, + custom: forkCustomMetadata(sourceMeta?.custom, opts.metadata), + }); - for (const agentId of retainedAgentIds) { + await this.duplicateCronTasks(sourceId, targetId); + + for (const agentId of agentIds) { const sourceAgent = sourceAgents[agentId]!; await target.accessor.get(IAgentLifecycleService).create({ agentId, @@ -564,17 +549,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec }); } - await targetMeta.update({ - title, - titleKind: opts.title !== undefined ? 'custom' : 'replaceable', - forkedFrom: sourceId, - archived: false, - updatedAt: toEpochMs(sourceMeta?.updatedAt) || Date.now(), - lastPrompt: turnSlice === undefined ? sourceMeta?.lastPrompt : turnSlice.lastPrompt, - lastTurnReason: sourceMeta?.lastTurnReason, - custom: forkCustomMetadata(sourceMeta?.custom, opts.metadata), - }); - await this.appendSessionIndexEntry(targetId, this.workspaceContext.cwd); this._onDidForkSession.fire({ sourceSessionId: sourceId, @@ -589,7 +563,7 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec } if (target !== undefined) { try { - void target.dispose(); + target.dispose(); } catch { } } @@ -630,18 +604,28 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec readonly sourceSessionId: string; readonly agentId: string; readonly targetSessionId: string; - readonly records?: readonly WireRecord[]; }): Promise { - const records = [ - ...(args.records ?? - (await this.readSourceWireRecords(args.sourceHandle, args.sourceSessionId, args.agentId))), - ]; + if (args.sourceHandle !== undefined) { + const agentHandle = args.sourceHandle.accessor + .get(IAgentLifecycleService) + .get(args.agentId); + if (agentHandle !== undefined) { + await agentHandle.accessor.get(IWireService).flush(); + } + } + + const records = await collect( + this.appendLogStore.read( + agentScopeOf(sessionScopeOf(this.handlerScope, args.sourceSessionId), args.agentId), + AGENT_WIRE_RECORD_KEY, + ), + ); if (records.length === 0) { records.push(createWireMetadataRecord()); } else if (records[0]?.type !== 'metadata') { records.unshift(createWireMetadataRecord()); } - records.push(forkedRecord(args.agentId)); + records.push(forkedRecord()); await this.appendLogStore.rewrite( agentScopeOf(sessionScopeOf(this.handlerScope, args.targetSessionId), args.agentId), @@ -650,46 +634,6 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec ); } - private async readSourceWireRecords( - sourceHandle: ISessionScopeHandle | undefined, - sourceSessionId: string, - agentId: string, - ): Promise { - if (sourceHandle !== undefined) { - const agentHandle = sourceHandle.accessor - .get(IAgentLifecycleService) - .handleOf(agentId); - if (agentHandle !== undefined) { - await agentHandle.accessor.get(IEventDispatcher).flush(); - } - } - return collect( - this.appendLogStore.read( - agentScopeOf(sessionScopeOf(this.handlerScope, sourceSessionId), agentId), - AGENT_WIRE_RECORD_KEY, - ), - ); - } - - private async pruneTruncatedForkFiles( - targetSessionDir: string, - agentIds: readonly string[], - retainedAgentIds: readonly string[], - ): Promise { - const retained = new Set(retainedAgentIds); - const removals: Promise[] = []; - for (const agentId of agentIds) { - if (retained.has(agentId)) continue; - removals.push(this.hostFs.remove(join(targetSessionDir, 'agents', agentId))); - } - for (const agentId of retainedAgentIds) { - const agentDir = join(targetSessionDir, 'agents', agentId); - removals.push(this.hostFs.remove(join(agentDir, 'tasks'))); - removals.push(this.hostFs.remove(join(agentDir, 'cron'))); - } - await Promise.all(removals); - } - private async copySessionFiles(sourceDir: string, targetDir: string): Promise { let entries: readonly HostDirEntry[]; try { @@ -709,7 +653,7 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec ): Promise { for (const entry of entries) { const rel = relBase === '' ? entry.name : `${relBase}/${entry.name}`; - if (rel === 'state.json' || rel === 'logs' || rel === 'upcoming-goals.json' || entry.name === AGENT_WIRE_RECORD_KEY) { + if (rel === 'state.json' || rel === 'logs' || entry.name === AGENT_WIRE_RECORD_KEY) { continue; } if (entry.isSymbolicLink === true) continue; @@ -733,11 +677,32 @@ export class SessionLifecycleService extends Disposable implements ISessionLifec } } + private async duplicateCronTasks(sourceId: string, targetId: string): Promise { + const tasks = await this.cronStore.list({ workspaceId: this.workspaceId }); + for (const task of tasks) { + if (task.tags?.[CRON_SESSION_TAG] !== sourceId) continue; + const clone: CronTask = { + ...task, + id: ulid(), + tags: { ...task.tags, [CRON_SESSION_TAG]: targetId }, + }; + await this.cronStore.save(this.workspaceId, clone); + } + } + private async readMetaFromDisk(sessionId: string): Promise { return this.docs.get(sessionScopeOf(this.handlerScope, sessionId), 'state.json'); } } +registerScopedService( + LifecycleScope.Workspace, + ISessionLifecycleService, + SessionLifecycleService, + ScopeActivation.OnScopeCreated, + 'sessionLifecycle', +); + async function collect(iterable: AsyncIterable): Promise { const items: T[] = []; for await (const item of iterable) items.push(item); @@ -755,8 +720,8 @@ function createSessionId(): string { return `session_${randomUUID()}`; } -function forkedRecord(agentId: string): WireRecord { - return { type: 'forked', agentId, time: Date.now() }; +function forkedRecord(): WireRecord { + return { type: 'forked', time: Date.now() }; } function forkCustomMetadata( diff --git a/packages/agent-core-v2/src/workspace/state/workspaceState.ts b/packages/agent-core-v2/src/workspace/state/workspaceState.ts index 40c4cbaa4..cdff83c4e 100644 --- a/packages/agent-core-v2/src/workspace/state/workspaceState.ts +++ b/packages/agent-core-v2/src/workspace/state/workspaceState.ts @@ -1,3 +1,15 @@ +/** + * `state` domain — Workspace-scope keyed state container contract. + * + * Defines `IWorkspaceStateService`, the Workspace-scope state service: + * Workspace-tier services declare their plain-data state as typed keys + * (`defineState`) and read/write them through this container, so + * per-handler shared state lives in one observable place and dies with the + * workspace handler. Shares the `IStateRegistry` method set with its + * App/Session/Agent counterparts; its `inspect()` cascade continues into the + * App tier. Bound at Workspace scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IStateRegistry } from '#/_base/state/stateRegistry'; diff --git a/packages/agent-core-v2/src/workspace/state/workspaceStateService.ts b/packages/agent-core-v2/src/workspace/state/workspaceStateService.ts index 9466ad8cb..d58a27208 100644 --- a/packages/agent-core-v2/src/workspace/state/workspaceStateService.ts +++ b/packages/agent-core-v2/src/workspace/state/workspaceStateService.ts @@ -1,3 +1,16 @@ +/** + * `state` domain — `IWorkspaceStateService` implementation. + * + * Thin per-scope binding over the shared `StateRegistry`; the container owns + * construction and disposal, so registered state dies with the scope. Injects + * the App-tier state service as its `inspect()` cascade parent (the parameter + * is optional so tests can construct a bare container; DI always injects). + * Bound at Workspace scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { StateRegistry } from '#/_base/state/stateRegistry'; import { IAppStateService } from '#/app/state/appState'; @@ -13,3 +26,10 @@ export class WorkspaceStateService extends StateRegistry implements IWorkspaceSt } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceStateService, + WorkspaceStateService, + ScopeActivation.OnScopeCreated, + 'state', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/configSection.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/configSection.ts index ea05f7c26..6169a4c3c 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/configSection.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/configSection.ts @@ -1,3 +1,11 @@ +/** + * `workspaceAgentProfileLoader` domain — agent-file config sections. + * + * Registers the top-level config domain `extraAgentDirs`: additional + * directories scanned for agent Markdown files. Values stay camelCase in + * memory; TOML uses the snake_case key `extra_agent_dirs`. + */ + import { z } from 'zod'; import { registerConfigSection } from '#/app/config/configSectionContributions'; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader.ts index c58136a7c..6519ddec9 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoader.ts @@ -1,3 +1,15 @@ +/** + * `workspaceAgentProfileLoader` domain — `IExplicitAgentProfileLoader` contract. + * + * The explicit loader of the agent-profile extension point: owns the + * `explicit` record of the `AgentProfileContribution` collection — the + * runtime-selected agent files (`--agent-file`), tagged with this handler's `workspaceId`. + * The loader is `fatal`: an invalid explicit file is an explicit user intent + * that must not be silently dropped, so the rejection propagates into `ready` + * and session materialization fails fast; `reload()` re-arms it once the + * offending file is fixed. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IExplicitAgentProfileLoader { diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoaderService.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoaderService.ts index 971704720..59c0d52c2 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/explicitAgentProfileLoaderService.ts @@ -1,3 +1,14 @@ +/** + * `workspaceAgentProfileLoader` domain — `IExplicitAgentProfileLoader` implementation. + * + * Loads the runtime-selected agent files through `hostFs`, resolving paths + * against the workspace root (`workspaceContext`) and `bootstrap`. + * Bound at Workspace scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; import type { AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; import { parseAgentFileText } from '#/workspace/workspaceAgentProfileLoader/internal/agentFile'; @@ -7,7 +18,6 @@ import { AGENT_PROFILE_SOURCE_PRIORITY, type AgentProfileContribution, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; import { resolveAgentPath } from '#/workspace/workspaceAgentProfileLoader/internal/paths'; import { IUserAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoader'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; @@ -32,9 +42,8 @@ export class ExplicitAgentProfileLoaderService @IHostFileSystem private readonly fs: IHostFileSystem, @ILogService log: ILogService, @IUserAgentProfileLoader private readonly user: IUserAgentProfileLoader, - registry?: IAgentProfileRegistry, ) { - super(log, registry); + super(log); this.start(); } @@ -59,3 +68,10 @@ export class ExplicitAgentProfileLoaderService } } +registerScopedService( + LifecycleScope.Workspace, + IExplicitAgentProfileLoader, + ExplicitAgentProfileLoaderService, + ScopeActivation.OnScopeCreated, + 'workspaceAgentProfileLoader', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader.ts index d615d54e4..397657825 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoader.ts @@ -1,3 +1,15 @@ +/** + * `workspaceAgentProfileLoader` domain — `IExtraAgentProfileLoader` contract. + * + * The extra loader of the agent-profile extension point: owns the `extra` + * record of the `AgentProfileContribution` collection — the agent files + * discovered from the configured `extraAgentDirs`, tagged with this handler's + * `workspaceId` (relative configured paths resolve against the workspace + * root, so the record is workspace-local even though the config section + * is global). `ready` tracks the most recent discovery pass; `reload()` + * re-discovers and re-contributes. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IExtraAgentProfileLoader { diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoaderService.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoaderService.ts index 7abc342e2..eb30ed8cf 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/extraAgentProfileLoaderService.ts @@ -1,3 +1,15 @@ +/** + * `workspaceAgentProfileLoader` domain — `IExtraAgentProfileLoader` implementation. + * + * Resolves the configured `extraAgentDirs` through `configService`, + * `workspaceContext`, `bootstrap`, and `hostFs`, reporting skipped files + * through `log`. Reloads when the `extraAgentDirs` config section changes. + * Bound at Workspace scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; import { discoverAgentFiles } from '#/workspace/workspaceAgentProfileLoader/internal/agentFileDiscovery'; import { AgentProfileLoaderBase } from '#/workspace/workspaceAgentProfileLoader/internal/agentProfileLoader'; @@ -5,7 +17,6 @@ import { AGENT_PROFILE_SOURCE_PRIORITY, type AgentProfileContribution, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; import { profilesFromDiscovery } from './internal/agentProfileFromFile'; import { configuredAgentRoots } from '#/workspace/workspaceAgentProfileLoader/internal/agentRoots'; import { @@ -36,9 +47,8 @@ export class ExtraAgentProfileLoaderService @IHostFileSystem private readonly fs: IHostFileSystem, @ILogService log: ILogService, @IUserAgentProfileLoader private readonly user: IUserAgentProfileLoader, - registry?: IAgentProfileRegistry, ) { - super(log, registry); + super(log); this._register( this.configService.onDidSectionChange((event) => { if (event.domain === EXTRA_AGENT_DIRS_SECTION) { @@ -78,3 +88,10 @@ export class ExtraAgentProfileLoaderService } } +registerScopedService( + LifecycleScope.Workspace, + IExtraAgentProfileLoader, + ExtraAgentProfileLoaderService, + ScopeActivation.OnScopeCreated, + 'workspaceAgentProfileLoader', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFile.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFile.ts index 469420fe8..6d5eaba3a 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFile.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFile.ts @@ -1,3 +1,16 @@ +/** + * `workspaceAgentProfileLoader` domain — agent-file parsing primitives. + * + * Parses a single agent Markdown file (frontmatter + body) into an + * `AgentFileDefinition`. Pure functions with no IO: callers read bytes however + * they like and pass the decoded text in. Unknown frontmatter fields are + * ignored so later format extensions stay forward-compatible. Compatibility conventions match other agent CLIs: a + * missing `name` falls back to the file name (OpenCode), a lone `*` in + * `tools` / `subagents` means unrestricted like an omitted field, and list + * fields accept either a bare comma-separated string or the YAML list form + * (Claude Code). + */ + import { CoreErrors } from '#/_base/errors/codes'; import { Error2 } from '#/_base/errors/errors'; import { FrontmatterError, parseFrontmatter } from '#/_base/text/frontmatter'; @@ -79,7 +92,9 @@ export function parseAgentFileText(options: ParseAgentFileOptions): AgentFileDef options.path, ); const rawSubagents = parseStringList(frontmatter['subagents'], 'subagents', options.path); - const subagents = rawSubagents; + const subagents = + rawSubagents?.length === 1 && rawSubagents[0] === '*' ? undefined : rawSubagents; + const modelPreference = parseModelPreference(frontmatter['model_preference'], options.path); const prompt = parsed.body.trim(); if (prompt.length === 0) { @@ -94,12 +109,24 @@ export function parseAgentFileText(options: ParseAgentFileOptions): AgentFileDef tools, disallowedTools, subagents, + modelPreference, prompt, path: options.path, source: options.source, }; } +function parseModelPreference( + value: unknown, + filePath: string, +): AgentFileDefinition['modelPreference'] { + if (value === undefined || value === null) return undefined; + if (value === 'primary' || value === 'secondary') return value; + throw new AgentFileParseError( + `Frontmatter field "model_preference" in ${filePath} must be "primary" or "secondary"`, + ); +} + function parseBoolean(value: unknown, field: string, filePath: string): boolean { if (value === undefined || value === null) return false; if (typeof value === 'boolean') return value; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFileDiscovery.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFileDiscovery.ts index cc7549be6..69be09e41 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFileDiscovery.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentFileDiscovery.ts @@ -1,3 +1,21 @@ +/** + * `workspaceAgentProfileLoader` domain — filesystem agent-file discovery. + * + * Discovers and parses agent files through the `hostFs` filesystem boundary. + * Invalid files are isolated from the rest of the discovery pass. Failure + * policy: below a root, ANY readdir failure (notably EACCES) skips just that + * directory — one unreadable subdirectory must not zero the whole source; at + * a root, a missing directory is simply "no agents here", a transient + * whole-fs outage (`os.fs.unavailable`) propagates so an existing + * contribution is kept instead of replaced by a partial scan, and any other + * failure skips just that root. Skip warnings are capped + * (`MAX_SKIP_WARNINGS`) so a misconfigured root (e.g. an extra dir pointing + * at a docs-heavy tree) cannot spam one line per non-agent file; the returned + * `skipped` list keeps the full parse-failure detail regardless, and the + * capping summary names a few suppressed paths so the rest stay findable. No + * scoped state. + */ + import { join } from 'pathe'; import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileFromFile.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileFromFile.ts index 67453ddb3..66089adb5 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileFromFile.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileFromFile.ts @@ -1,3 +1,24 @@ +/** + * `workspaceAgentProfileLoader` domain — `AgentFileDefinition` → `AgentProfile` factory. + * + * The file body is a prompt template rendered against the shared variable + * table: `${var}` placeholders substitute live context, + * and `${base_prompt}` embeds the effective default profile's prompt so a file + * can wrap the builtin behavior instead of replacing it. Explicit files are + * marked as builtin overrides; directory files must opt in through frontmatter. + * `tools` passes through as the allowlist (`undefined` = every tool active); + * `disallowedTools` passes through as the tool denylist; `subagents` passes + * through as the delegation allowlist; `model_preference` becomes the + * symbolic default model used when the profile is delegated to. + * `profilesFromDiscovery` packs a whole discovery pass into an + * `AgentProfileContribution`, binding each profile's `${base_prompt}` + * placeholder lazily at render time so it always reflects the effective + * default profile (builtin, or the `SYSTEM.md` override) rather than any + * file-based definition. A structured base prompt also forwards its + * environment disclosure (e.g. the disclosed date) through + * `renderSystemPrompt`, so runtime reminders never parse rendered text. + */ + import { normalizeAgentProfile, type AgentProfile, @@ -24,6 +45,7 @@ export function agentProfileFromFile( tools: definition.tools, disallowedTools: definition.disallowedTools, subagents: definition.subagents, + modelPreference: definition.modelPreference, renderSystemPrompt: (context) => renderPromptTemplateResult(definition.prompt, context, { skillActive }, basePrompt), }); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileLoader.ts index 4337c31d2..1a4d4cde8 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentProfileLoader.ts @@ -1,8 +1,28 @@ +/** + * `workspaceAgentProfileLoader` domain — `AgentProfileLoaderBase`, the shared + * loader skeleton of the agent-profile extension point. + * + * A loader owns one source id: it loads an `AgentProfileContribution` payload + * and contributes it to the `AgentProfileContribution` collection under that + * id (workspace-local loaders additionally tag a `workspaceKey`); the + * App-scope registry fold picks the record up from there. The first load + * starts when the subclass constructor calls {@link start} — after its own + * fields are set, since `load()` is virtual. `ready` tracks the most recent + * load pass; `reload()` replaces it, so a `fatal` failure does not wedge the + * loader once the underlying problem is fixed. A rejecting `fatal` loader + * (an invalid `--agent-file`) propagates into `ready` so session + * materialization fails fast; a rejecting non-fatal loader degrades to a + * warning and keeps any previously contributed record, so directory problems + * never poison the projection. Loads are serialized per loader — a refresh + * never overlaps the previous pass — and the swallowed handler on `ready` + * keeps an un-awaited rejection from crashing the process. The record hangs + * on the loader unit's book, so disposing the loader withdraws it. + */ + import { MutableDisposable, type IDisposable } from '#/_base/di/lifecycle'; import { Service } from '#/_base/di/service'; import type { ILogService } from '#/_base/log/log'; import { AgentProfileContribution } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; export abstract class AgentProfileLoaderBase extends Service { protected abstract readonly sourceId: string; @@ -13,10 +33,7 @@ export abstract class AgentProfileLoaderBase extends Service { private tail: Promise = Promise.resolve(); private readonly contributionHandle = this._register(new MutableDisposable()); - constructor( - protected readonly log: ILogService, - private readonly registry?: IAgentProfileRegistry, - ) { + constructor(protected readonly log: ILogService) { super(); } @@ -50,18 +67,13 @@ export abstract class AgentProfileLoaderBase extends Service { private async loadAndContribute(): Promise { try { const contribution = await this.load(); - const registration = { + const handle = this.provide(AgentProfileContribution, { sourceId: this.sourceId, priority: this.priority, workspaceKey: this.workspaceKey, contribution, - }; - if (this.registry !== undefined) { - this.contributionHandle.value = this.registry.register(registration); - } else { - const handle = this.provide(AgentProfileContribution, registration); - this.contributionHandle.value = { dispose: () => void handle.dispose() }; - } + }); + this.contributionHandle.value = { dispose: () => void handle.dispose() }; } catch (error) { if (this.fatal) throw error; this.log.warn(`agent profile loader "${this.sourceId}" load failed: ${String(error)}`); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentRoots.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentRoots.ts index 503cd86a3..7d0a8ab48 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentRoots.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/agentRoots.ts @@ -1,6 +1,12 @@ -import { join } from 'pathe'; +/** + * `workspaceAgentProfileLoader` domain — agent-root resolution primitives. + * + * Resolves user, project, and configured discovery roots through the `hostFs` + * filesystem boundary. Pure path probes; no scoped state. + */ + +import { dirname, join, resolve } from 'pathe'; -import { findUpwardRoot } from '#/_base/utils/paths'; import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { HostFsError, OsFsErrors } from '#/os/interface/hostFsErrors'; @@ -80,15 +86,20 @@ async function findProjectRoot( workDir: string, warn?: AgentRootWarn, ): Promise { - return findUpwardRoot(workDir, '.git', async (marker) => { + const start = resolve(workDir); + let current = start; + while (true) { + const marker = join(current, '.git'); try { - return await pathExists(fs, marker); + if (await pathExists(fs, marker)) return current; } catch (error) { if (isUnavailable(error)) throw error; warn?.(`Skipping unreadable project marker ${marker}: ${errorMessage(error)}`, error); - return false; } - }); + const parent = dirname(current); + if (parent === current) return start; + current = parent; + } } async function pushFirstExisting( diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/paths.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/paths.ts index 92bb1a02c..9fc4e539c 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/paths.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/paths.ts @@ -1,3 +1,13 @@ +/** + * `workspaceAgentProfileLoader` domain — shared path primitives for agent-file + * discovery. + * + * `~` expansion, base-relative resolution, and `hostFs` type probes. Callers + * pick the resolution base: discovery roots resolve against the + * project root, explicit files against the session workDir. Pure helpers; no + * scoped state. + */ + import { isAbsolute, join, resolve } from 'pathe'; import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/systemFile.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/systemFile.ts index aeb29e31e..d9be9b724 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/systemFile.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/systemFile.ts @@ -1,3 +1,20 @@ +/** + * `workspaceAgentProfileLoader` domain — `SYSTEM.md` global main-agent prompt override. + * + * `/SYSTEM.md` (default `~/.kimi-code/SYSTEM.md`, moves with + * `KIMI_CODE_HOME`) permanently replaces the builtin default profile's system + * prompt while the file exists and is non-empty. Only the prompt is replaced — + * tools and description are copied from the builtin default — and explicit + * intent still wins: higher-priority sources (project `agent.md`, + * `--agent-file`) override it, and binding a different profile ignores it. + * The body is a prompt template rendered against the shared variable table: + * `${var}` placeholders substitute live context, and + * `${base_prompt}` embeds the builtin default prompt. A missing or empty file + * yields no profile; a read failure degrades to `warn` instead of rejecting, + * so a transient fs error never poisons a session. Pure logic; no scoped + * state. + */ + import { join } from 'pathe'; import { diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/types.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/types.ts index 8bfb5d2c3..729653f01 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/types.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/internal/types.ts @@ -1,3 +1,13 @@ +/** + * `workspaceAgentProfileLoader` domain — agent-file model types. + * + * Shared types for the agent-file primitives: the parsed single-file + * definition (`AgentFileDefinition`), scan roots (`AgentFileRoot`) tagged with + * their source, and the discovery result carrying per-file skip diagnostics. + * Pure data; no scoped state. + */ + +import type { AgentModelPreference } from '#/app/agentProfileCatalog/agentProfileCatalog'; import type { SkippedAgentFile } from '#/app/agentProfileCatalog/agentProfileContribution'; export type { SkippedAgentFile } from '#/app/agentProfileCatalog/agentProfileContribution'; @@ -17,6 +27,7 @@ export interface AgentFileDefinition { readonly tools?: readonly string[]; readonly disallowedTools?: readonly string[]; readonly subagents?: readonly string[]; + readonly modelPreference?: AgentModelPreference; readonly prompt: string; readonly path: string; readonly source: AgentFileSource; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader.ts index aeace0878..0f86121b1 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoader.ts @@ -1,3 +1,13 @@ +/** + * `workspaceAgentProfileLoader` domain — `IPluginAgentProfileLoader` contract. + * + * The plugin loader of the agent-profile extension point: owns the `plugin` + * record of the `AgentProfileContribution` collection — the agent files + * discovered from the enabled plugins' agent roots, tagged with this + * handler's `workspaceId`. `ready` tracks the most recent discovery pass; + * `reload()` re-discovers and re-contributes. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IPluginAgentProfileLoader { diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService.ts index d0500ea67..edb5af5fd 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/pluginAgentProfileLoaderService.ts @@ -1,3 +1,17 @@ +/** + * `workspaceAgentProfileLoader` domain — `IPluginAgentProfileLoader` implementation. + * + * Discovers agent profiles contributed by enabled plugins (roots from the + * App-scope `plugins.pluginAgentRoots()`) and contributes them via the shared + * loader skeleton. Reloads when plugins reload; install / enable / remove + * mutations deliberately do not re-contribute — those take effect on the next + * explicit reload. Bound at Workspace scope: agent-file discovery lives in + * the workspace layer alongside every other source. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; import { IPluginService } from '#/app/plugin/plugin'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; @@ -9,7 +23,6 @@ import { AGENT_PROFILE_SOURCE_PRIORITY, type AgentProfileContribution, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; import { profilesFromDiscovery } from './internal/agentProfileFromFile'; import { IUserAgentProfileLoader } from './userAgentProfileLoader'; import { IPluginAgentProfileLoader } from './pluginAgentProfileLoader'; @@ -29,9 +42,8 @@ export class PluginAgentProfileLoaderService @ILogService log: ILogService, @IUserAgentProfileLoader private readonly user: IUserAgentProfileLoader, @IWorkspaceContext private readonly workspace: IWorkspaceContext, - registry?: IAgentProfileRegistry, ) { - super(log, registry); + super(log); this._register( this.plugins.onDidReload(() => { void this.reload().catch((error) => { @@ -57,3 +69,10 @@ export class PluginAgentProfileLoaderService } } +registerScopedService( + LifecycleScope.Workspace, + IPluginAgentProfileLoader, + PluginAgentProfileLoaderService, + ScopeActivation.OnScopeCreated, + 'workspaceAgentProfileLoader', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoader.ts index 9ffafc06f..8e5522a48 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoader.ts @@ -1,3 +1,17 @@ +/** + * `workspaceAgentProfileLoader` domain — `IUserAgentProfileLoader` contract. + * + * The user loader of the agent-profile extension point: owns the `user` + * record of the `AgentProfileContribution` collection — the agent files + * discovered from the user agent roots under the os home, plus the + * `/SYSTEM.md` prompt-override profile appended after them — tagged + * with this handler's `workspaceId`. Also exposes the effective default + * profile (the `SYSTEM.md` override when present, else the builtin default, + * refreshed on each load pass) for backing `${base_prompt}`. `ready` tracks + * the most recent discovery pass; `reload()` re-discovers and re-contributes. + * Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoaderService.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoaderService.ts index d7d72a9c0..46566c1b7 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/userAgentProfileLoaderService.ts @@ -1,3 +1,18 @@ +/** + * `workspaceAgentProfileLoader` domain — `IUserAgentProfileLoader` implementation. + * + * Discovers user agent profiles through `bootstrap` home paths and `hostFs`, + * reports skipped files through `log`, and appends the `/SYSTEM.md` + * prompt-override profile (synthesized against the builtin default from the + * App builtin loader) after the scanned profiles so it wins same-name + * collisions within this contribution. The user roots are global os + * directories, but per-workspace contribution keeps every record flowing + * through the same workspace-tagged lane. Bound at Workspace scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; import type { AgentProfile } from '#/app/agentProfileCatalog/agentProfileCatalog'; import { IBuiltinAgentProfileLoader } from '#/app/agentProfileCatalog/builtinAgentProfileLoader'; @@ -11,7 +26,6 @@ import { AGENT_PROFILE_SOURCE_PRIORITY, type AgentProfileContribution, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; import { profilesFromDiscovery } from './internal/agentProfileFromFile'; import { userAgentRoots } from './internal/agentRoots'; import { loadSystemMdProfile } from './internal/systemFile'; @@ -34,9 +48,8 @@ export class UserAgentProfileLoaderService @ILogService log: ILogService, @IBuiltinAgentProfileLoader private readonly builtin: IBuiltinAgentProfileLoader, @IWorkspaceContext private readonly workspace: IWorkspaceContext, - registry?: IAgentProfileRegistry, ) { - super(log, registry); + super(log); this.defaultProfile = builtin.getDefault(); this.start(); } @@ -74,3 +87,10 @@ export class UserAgentProfileLoaderService } } +registerScopedService( + LifecycleScope.Workspace, + IUserAgentProfileLoader, + UserAgentProfileLoaderService, + ScopeActivation.OnScopeCreated, + 'workspaceAgentProfileLoader', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader.ts index b4214f678..702c477f4 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoader.ts @@ -1,3 +1,15 @@ +/** + * `workspaceAgentProfileLoader` domain — `IWorkspaceAgentProfileLoader` contract. + * + * The workspace loader of the agent-profile extension point: owns the + * `workspace` record of the `AgentProfileContribution` collection — the + * agent files discovered under this handler's project root, tagged with the + * handler's `workspaceId` so concurrent handlers never collide and the + * sessions of THIS workspace project exactly this entry. `ready` tracks the + * most recent discovery pass; `reload()` re-discovers and re-contributes. + * Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; export interface IWorkspaceAgentProfileLoader { diff --git a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService.ts b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService.ts index ceea60389..b36f72689 100644 --- a/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceAgentProfileLoader/workspaceAgentProfileLoaderService.ts @@ -1,3 +1,19 @@ +/** + * `workspaceAgentProfileLoader` domain — `IWorkspaceAgentProfileLoader` implementation. + * + * Discovers the workspace's agent files (`.kimi-code/agents`, `.agents/agents` + * under the project root, resolved through `workspaceContext` and `hostFs`) + * and contributes them via the shared loader skeleton. `${base_prompt}` is + * backed by the user loader's effective default profile. Watches the project + * agent-root candidates through `hostFsWatch` (watched whether or not they + * exist yet) and reloads debounced, so a project agent-file change + * re-contributes this record only. Bound at Workspace scope: the scan is + * per handler and the record dies with it. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; import { TimeoutTimer } from '#/_base/utils/timer'; import { subtreeWatchFilter } from '#/_base/utils/paths'; @@ -7,7 +23,6 @@ import { AGENT_PROFILE_SOURCE_PRIORITY, type AgentProfileContribution, } from '#/app/agentProfileCatalog/agentProfileContribution'; -import type { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; import { profilesFromDiscovery } from './internal/agentProfileFromFile'; import { projectAgentRootCandidates, projectAgentRoots } from '#/workspace/workspaceAgentProfileLoader/internal/agentRoots'; import { IUserAgentProfileLoader } from '#/workspace/workspaceAgentProfileLoader/userAgentProfileLoader'; @@ -37,9 +52,8 @@ export class WorkspaceAgentProfileLoaderService @ILogService log: ILogService, @IUserAgentProfileLoader private readonly user: IUserAgentProfileLoader, @IHostFsWatchService private readonly fsWatch: IHostFsWatchService, - registry?: IAgentProfileRegistry, ) { - super(log, registry); + super(log); this.watchReady = this.watchProjectAgentRoots(); this.start(); } @@ -81,3 +95,10 @@ export class WorkspaceAgentProfileLoaderService } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceAgentProfileLoader, + WorkspaceAgentProfileLoaderService, + ScopeActivation.OnScopeCreated, + 'workspaceAgentProfileLoader', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceContext/workspaceContext.ts b/packages/agent-core-v2/src/workspace/workspaceContext/workspaceContext.ts index d224537d5..804196559 100644 --- a/packages/agent-core-v2/src/workspace/workspaceContext/workspaceContext.ts +++ b/packages/agent-core-v2/src/workspace/workspaceContext/workspaceContext.ts @@ -1,8 +1,25 @@ +/** + * `workspaceContext` domain — seeded per-handler workspace facts. + * + * Defines the `IWorkspaceContext` carrying the workspace handler's identity + * and storage addressing (`workspaceId`, `persistenceScope` — the handler's + * persistence scope string `sessions/{wd_id}`), the workspace root (`cwd`) + * and catalog metadata (`meta`), plus the runtime keying pair (`osBackendId` + * × `persistenceBackendId`) that records which os/persistence backends the + * handler binds — both `'local'` until a remote runtime exists (`remoteCwd` + * reserves the remote root slot, never set by the local runtime). Seeded + * into the Workspace scope when the handler is materialized. Pure facts — + * no store, no IO. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { ScopeSeed } from '#/_base/di/scope'; export type WorkspaceSource = 'local'; +export const LOCAL_OS_BACKEND_ID = 'local'; +export const LOCAL_PERSISTENCE_BACKEND_ID = 'local'; + export interface WorkspaceMeta { readonly id: string; readonly root: string; @@ -20,6 +37,8 @@ export interface IWorkspaceContext { readonly remoteCwd?: string; readonly meta: WorkspaceMeta; readonly persistenceScope: string; + readonly osBackendId: string; + readonly persistenceBackendId: string; } export const IWorkspaceContext: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirs.ts b/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirs.ts index eac6f4614..051c97ea3 100644 --- a/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirs.ts +++ b/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirs.ts @@ -1,3 +1,18 @@ +/** + * `workspaceDirs` domain — Workspace-scoped additional-directory set + * contract. + * + * Defines `IWorkspaceDirs`, the handler-level owner of the workspace's + * `{root, additionalDirs[]}` set: at handler materialization it loads the + * project-local `.kimi-code/local.toml` set; afterwards `addDir` mutations + * (persisted appends or session-caller in-memory unions) and fs watch on + * `local.toml` (cross-process edits) refresh the set, fanning the change + * out to every session of the handler through the `ISessionWorkspaceInfo` + * seed (`sessionInfo()`). The set is shared by all sessions of the + * workspace and persisted entries survive restarts; non-persisted entries + * live in handler memory only. Bound at Workspace scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirsService.ts b/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirsService.ts index d50868c6e..116cad362 100644 --- a/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirsService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceDirs/workspaceDirsService.ts @@ -1,7 +1,28 @@ -import { Disposable } from '#/_base/di/lifecycle'; +/** + * `workspaceDirs` domain — `IWorkspaceDirs` implementation. + * + * Holds the handler-shared additional-directory set as + * `fileDirs ∪ ephemeralDirs`: `fileDirs` is the project-local + * `.kimi-code/local.toml` set (loaded once per handler through + * `projectLocalConfig`, reloaded debounced when the fs watch sees the file + * change — including writes from OTHER processes), `ephemeralDirs` is the + * in-memory union of non-persisted `addDir` calls and caller-provided dirs + * from session create/resume options (it dies with the handler). Every + * mutation serializes on one tail queue; the change event fires only when + * the combined list actually changed. The set reaches every session of the + * handler through the `ISessionWorkspaceInfo` seed (`sessionInfo()`), a + * live read view over this service. The plain-data state (`fileDirs`, + * `ephemeralDirs`) is registered into `workspaceState` + * (`IWorkspaceStateService`) and read/written through it. Bound at + * Workspace scope. + */ + +import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { TimeoutTimer } from '#/_base/utils/timer'; import { subtreeWatchFilter } from '#/_base/utils/paths'; import { IProjectLocalConfigService } from '#/app/projectLocalConfig/projectLocalConfig'; @@ -27,7 +48,7 @@ export const workspaceDirsEphemeralDirsKey = defineState( () => [], ); -export class WorkspaceDirsService extends Disposable implements IWorkspaceDirs { +export class WorkspaceDirsService extends Service implements IWorkspaceDirs { declare readonly _serviceBrand: undefined; private projectRoot: string; @@ -46,8 +67,8 @@ export class WorkspaceDirsService extends Disposable implements IWorkspaceDirs { @IWorkspaceStateService private readonly states: IWorkspaceStateService, ) { super(); - this.states.contributeState(workspaceDirsFileDirsKey); - this.states.contributeState(workspaceDirsEphemeralDirsKey); + this.states.register(workspaceDirsFileDirsKey); + this.states.register(workspaceDirsEphemeralDirsKey); this.projectRoot = workspace.cwd; this.configPath = ''; this.ready = this.enqueue(() => this.reloadFromDisk()); @@ -196,3 +217,10 @@ function sameStringList(a: readonly string[], b: readonly string[]): boolean { return a.length === b.length && a.every((value, index) => value === b[index]); } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceDirs, + WorkspaceDirsService, + ScopeActivation.OnScopeCreated, + 'workspaceDirs', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/fs.ts b/packages/agent-core-v2/src/workspace/workspaceFs/fs.ts index 36ab1c907..2725433e4 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/fs.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/fs.ts @@ -1,3 +1,15 @@ +/** + * `workspaceFs` domain — wire-shaped filesystem operations. + * + * Defines the `IWorkspaceFsService` contract — content search, content + * grep, and git status/diff — together with the zod DTO schemas the wire + * transports validate against. It orchestrates the os + * `IHostFileSystem` (file IO, resolved against the workspace root) plus the + * handler-shared `ISessionProcessRunner` (for `rg`). Workspace-scoped — one + * instance per handler, pinned to the handler root (chdir is gone, so the + * root never changes). + */ + import { z } from 'zod'; import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; @@ -182,31 +194,6 @@ export const fsSearchResponseSchema = z.object({ }); export type FsSearchResponse = z.infer; -export const fsSuggestItemSchema = z.object({ - path: z.string(), - name: z.string(), - kind: fsKindSchema, - score: z.number().min(0).max(1), - match_positions: z.array(z.number().int().nonnegative()), -}); -export type FsSuggestItem = z.infer; - -export const fsSuggestRequestSchema = z.object({ - query: z.string(), - limit: z.number().int().min(1).max(200).default(50), - follow_gitignore: z.boolean().default(true), - show_hidden: z.boolean().default(false), - include_globs: z.array(z.string()).optional(), - exclude_globs: z.array(z.string()).optional(), -}); -export type FsSuggestRequest = z.infer; - -export const fsSuggestResponseSchema = z.object({ - items: z.array(fsSuggestItemSchema), - truncated: z.boolean(), -}); -export type FsSuggestResponse = z.infer; - export const fsGrepRequestSchema = z.object({ pattern: z.string().min(1), regex: z.boolean().default(false), @@ -254,7 +241,6 @@ export interface IWorkspaceFsService { statMany(req: FsStatManyRequest): Promise; mkdir(req: FsMkdirRequest): Promise; search(req: FsSearchRequest): Promise; - suggest(req: FsSuggestRequest): Promise; grep(req: FsGrepRequest): Promise; gitStatus(req: FsGitStatusRequest): Promise; diff(req: FsDiffRequest): Promise; diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/fsService.ts b/packages/agent-core-v2/src/workspace/workspaceFs/fsService.ts index 82d1f2f9c..e440efe07 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/fsService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/fsService.ts @@ -1,3 +1,26 @@ +/** + * `workspaceFs` domain — `IWorkspaceFsService` implementation. + * + * Implements the fs operations (search / grep / git status / git diff) by + * orchestrating the os `IHostFileSystem` (file IO, resolved against the + * workspace root), the handler-shared `ISessionProcessRunner` (`rg`), and + * `IWorkspaceGitService` (git status/diff bound to the handler root; this + * service only confines paths and computes repo-relative paths before + * calling it). + * + * Path confinement applies a lexical within-workspace check first (the + * handler root plus the `workspaceDirs` additional-dir set), then + * re-verifies the candidate through `IHostFileSystem.realpath` (resolving + * the longest existing prefix, so not-yet-created paths still work): a + * symlink inside the workspace must not steer fs actions to files outside + * it. The small + * caches (`rgResolution`, `realRootsCache`) are plain per-handler fields. + * Bound at Workspace scope — one instance per handler, shared by every + * session of the workspace. + */ + +import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path'; + import { type FsDiffRequest, type FsDiffResponse, @@ -23,8 +46,6 @@ import { type FsStatManyResponse, type FsStatRequest, type FsStatResponse, - type FsSuggestRequest, - type FsSuggestResponse, } from './fs'; const FsWireErrorCode = { @@ -37,10 +58,13 @@ const FsWireErrorCode = { } as const; import ignore, { type Ignore } from 'ignore'; -import { classifyTextSample, decodeUtfText } from '#/_base/text/encoding'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { decodeUtfText, detectTextEncoding, type UtfTextEncoding } from '#/_base/text/encoding'; import { buildEtag, countLines, + detectBinary, FS_BINARY_SAMPLE_BYTES, guessLanguageId, guessMime, @@ -48,8 +72,7 @@ import { import { ErrorCodes, Error2, isError2, unwrapErrorCause } from '#/errors'; import { ITelemetryService } from '#/app/telemetry/telemetry'; import { IHostFileSystem, type HostDirEntry, type HostFileStat } from '#/os/interface/hostFileSystem'; -import type { RuntimePath } from '#/runtime/runtime'; -import { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; +import { ISessionProcessRunner } from '#/session/process/processRunner'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; import { IWorkspaceDirs } from '#/workspace/workspaceDirs/workspaceDirs'; import { IWorkspaceGitService } from '#/workspace/workspaceGit/workspaceGit'; @@ -61,30 +84,17 @@ import { compileGrepPattern, computeFuzzyScore, computeMatchPositions, - evaluateSuggestCandidate, matchesAnyGlob, type RgJsonRecord, rgPath, rgText, stripTrailingNewline, - SuggestTopHeap, - type SuggestCandidate, - type SuggestQuery, - VCS_METADATA_DIRS, } from './internal/fsSearch'; const SEARCH_HARD_CAP = 500; const GREP_TIMEOUT_MS = 30_000; -const SUGGEST_TIMEOUT_MS = 10_000; -const SUGGEST_WALK_ABORTED = new Error('suggest walk aborted'); const WALK_MAX_DEPTH = 64; -interface SuggestRoot { - readonly dir: string; - readonly real: string; - readonly primary: boolean; -} - const FS_READ_MAX_BYTES = 10 * 1024 * 1024; const HIDDEN_NAME_RE = /^\./; @@ -95,44 +105,38 @@ export class WorkspaceFsService implements IWorkspaceFsService { private readonly gitignoreCache = new Map(); private rgResolution: RgResolution | null | undefined = undefined; - private realRootsCache: - | { readonly key: string; readonly roots: readonly { dir: string; real: string }[] } - | undefined = undefined; + private realRootsCache: { readonly key: string; readonly roots: readonly string[] } | undefined = + undefined; private readonly workDir: string; - private readonly workspaceId: string; - private readonly path: RuntimePath; constructor( @IWorkspaceContext workspace: IWorkspaceContext, @IWorkspaceDirs private readonly workspaceDirs: IWorkspaceDirs, @IHostFileSystem private readonly hostFs: IHostFileSystem, - @IRuntimeResolver private readonly resolver: IRuntimeResolver, + @ISessionProcessRunner private readonly runner: ISessionProcessRunner, @ITelemetryService private readonly telemetry: ITelemetryService, @IWorkspaceGitService private readonly git: IWorkspaceGitService, - private readonly runtimeId = 'local', ) { - this.workspaceId = workspace.workspaceId; - this.path = resolver.inspect({ workspaceId: workspace.workspaceId, runtimeId }).path; - this.workDir = this.path.resolve(workspace.cwd); + this.workDir = resolve(workspace.cwd); } private resolvePathInput(rel: string): string { - return this.path.isAbsolute(rel) ? this.path.resolve(rel) : this.path.resolve(this.workDir, rel); + return isAbsolute(rel) ? resolve(rel) : resolve(this.workDir, rel); } private isWithinWorkspace(absPath: string): boolean { - const target = this.path.resolve(absPath); + const target = resolve(absPath); if (target === this.workDir) return true; - const rel = this.path.relative(this.workDir, target); - if (rel !== '' && !rel.startsWith('..') && !this.path.isAbsolute(rel)) return true; + const rel = relative(this.workDir, target); + if (rel !== '' && !rel.startsWith('..') && !isAbsolute(rel)) return true; return this.workspaceDirs.additionalDirs.some((dir) => { - const r = this.path.relative(this.path.resolve(dir), target); - return r === '' || (!r.startsWith('..') && !this.path.isAbsolute(r)); + const r = relative(resolve(dir), target); + return r === '' || (!r.startsWith('..') && !isAbsolute(r)); }); } private absOf(rel: string): string { - return rel === '' || rel === '.' ? this.workDir : this.path.join(this.workDir, rel); + return rel === '' || rel === '.' ? this.workDir : join(this.workDir, rel); } async list(req: FsListRequest): Promise { @@ -253,14 +257,20 @@ export class WorkspaceFsService implements IWorkspaceFsService { const sampleSize = Math.min(FS_BINARY_SAMPLE_BYTES, st.size); const sample = sampleSize === 0 ? new Uint8Array() : await this.hostFs.readBytes(abs, sampleSize); - const classification = classifyTextSample(sample); - const transcodeEncoding = - !classification.isBinary && classification.encoding !== 'utf-8' && req.encoding !== 'base64' - ? classification.encoding - : undefined; - const isBinary = - classification.isBinary || - (classification.encoding !== 'utf-8' && transcodeEncoding === undefined); + let isBinary = detectBinary(sample); + + // Trust encoding detection over the binary heuristic: a binary-looking + // sample can still be UTF-16 LE/BE text, and a BOM-marked UTF-16 file + // may not look binary at all (CJK-only content carries no zero bytes). + // Both are transcoded to UTF-8 so text clients can display them. + let transcodeEncoding: UtfTextEncoding | undefined; + if (req.encoding !== 'base64') { + const detection = detectTextEncoding(sample); + if (!detection.seemsBinary && detection.encoding !== 'utf-8') { + transcodeEncoding = detection.encoding; + isBinary = false; + } + } if (isBinary && req.encoding === 'utf-8') { throw new Error2(ErrorCodes.FS_IS_BINARY, `file is binary: ${req.path}`, { @@ -268,6 +278,8 @@ export class WorkspaceFsService implements IWorkspaceFsService { }); } + // When transcoding, the offset/length window applies to the decoded + // UTF-8 bytes — the representation the client actually paginates over. let totalLength = st.size; let decodedBytes: Uint8Array | undefined; if (transcodeEncoding !== undefined) { @@ -355,7 +367,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { } catch (err) { throw mapFsError(err, req.path); } - const name = rel === '.' ? this.path.basename(this.workDir) : this.path.basename(abs); + const name = rel === '.' ? basename(this.workDir) : basename(abs); return buildFsEntry(rel, name, st, true); } @@ -372,7 +384,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { resolved.map(async ({ raw, rel, abs }) => { try { const st = await this.hostFs.lstat(abs); - const name = rel === '.' ? this.path.basename(this.workDir) : this.path.basename(abs); + const name = rel === '.' ? basename(this.workDir) : basename(abs); entries[raw] = buildFsEntry(rel, name, st, false); } catch { entries[raw] = null; @@ -402,7 +414,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { throw err; } const st = await this.hostFs.lstat(abs); - return buildFsEntry(rel, this.path.basename(abs), st, false); + return buildFsEntry(rel, basename(abs), st, false); } async resolvePath(relPath: string): Promise { @@ -434,8 +446,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { const sampleSize = Math.min(FS_BINARY_SAMPLE_BYTES, st.size); const sample = sampleSize === 0 ? new Uint8Array() : await this.hostFs.readBytes(abs, sampleSize); - const classification = classifyTextSample(sample); - const isBinary = classification.isBinary || classification.encoding !== 'utf-8'; + const isBinary = detectBinary(sample); return { absolute: abs, relative: rel, @@ -477,7 +488,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { const candidates: FsSearchHit[] = []; const queryLower = req.query.toLowerCase(); - await this.walk(this.workDir, '', matcher, async (relPath, name, kind) => { + await this.walk('', matcher, async (relPath, name, kind) => { const score = computeFuzzyScore(name, queryLower); if (score <= 0) return; if (req.include_globs && !matchesAnyGlob(relPath, req.include_globs)) { @@ -505,337 +516,6 @@ export class WorkspaceFsService implements IWorkspaceFsService { return { items: candidates.slice(0, effectiveCap), truncated }; } - async suggest(req: FsSuggestRequest): Promise { - const roots = await this.suggestRoots(); - if (req.query === '') { - return this.suggestTopLevel(req, roots); - } - - const queryLower = req.query.toLowerCase(); - const pathSegments = queryLower.includes('/') - ? queryLower.split('/').filter((seg) => seg.length > 0) - : []; - if (queryLower.includes('/') && pathSegments.length === 0) { - return { items: [], truncated: false }; - } - const query: SuggestQuery = { - nameQuery: queryLower, - pathSegments, - showHidden: req.show_hidden, - followGitignore: req.follow_gitignore, - includeGlobs: req.include_globs, - excludeGlobs: req.exclude_globs, - }; - const cap = req.limit; - - const controller = new AbortController(); - const timer = setTimeout(() => controller.abort(), SUGGEST_TIMEOUT_MS); - timer.unref?.(); - try { - let resolution: RgResolution | null = null; - try { - resolution = await this.resolveRg(); - } catch { - resolution = null; - } - if (resolution !== null) { - try { - return await this.suggestWithRg(query, cap, controller.signal, resolution.path, roots); - } catch (err) { - if (controller.signal.aborted) throw err; - this.telemetry.track2('fs_suggest_node_fallback', { reason: 'rg_error' }); - return await this.suggestWithNode(query, cap, controller.signal, roots); - } - } - this.telemetry.track2('fs_suggest_node_fallback', { reason: 'rg_missing' }); - return await this.suggestWithNode(query, cap, controller.signal, roots); - } finally { - clearTimeout(timer); - } - } - - private async suggestRoots(): Promise { - const pairs = await this.realRootPairs(); - const roots: SuggestRoot[] = []; - for (let i = 0; i < pairs.length; i++) { - const pair = pairs[i]!; - if (roots.some((root) => isInsideOrEqual(this.path, pair.real, root.real))) continue; - roots.push({ dir: pair.dir, real: pair.real, primary: i === 0 }); - } - return roots; - } - - private suggestRootDirSlashes(root: SuggestRoot): string { - const sep = this.path.separator; - return sep === '/' ? root.dir : root.dir.split(sep).join('/'); - } - - private suggestDisplayPath(root: SuggestRoot, rel: string): string { - if (root.primary) return rel; - const dir = this.suggestRootDirSlashes(root); - return dir.endsWith('/') ? `${dir}${rel}` : `${dir}/${rel}`; - } - - private displayCandidate(root: SuggestRoot, candidate: SuggestCandidate): SuggestCandidate { - if (root.primary) return candidate; - const path = this.suggestDisplayPath(root, candidate.path); - const offset = path.length - candidate.path.length; - return { - ...candidate, - path, - positions: candidate.positions.map((position) => position + offset), - }; - } - - private async suggestTopLevel( - req: FsSuggestRequest, - roots: readonly SuggestRoot[], - ): Promise { - interface TopEntry { - readonly path: string; - readonly name: string; - readonly kind: 'file' | 'directory' | 'symlink'; - } - const all: TopEntry[] = []; - let capped = false; - for (const root of roots) { - const matcher = req.follow_gitignore ? await this.matcherFor(root.dir) : undefined; - let entries: readonly HostDirEntry[]; - try { - entries = await this.hostFs.readdir(root.dir); - } catch (err) { - throw mapFsError(err, root.dir); - } - const visible: { name: string; kind: TopEntry['kind'] }[] = []; - for (const entry of entries) { - const name = entry.name; - if (!req.show_hidden && isHidden(name)) continue; - if (matcher !== undefined && (matcher.ignores(name) || matcher.ignores(`${name}/`))) { - continue; - } - if (req.exclude_globs !== undefined && matchesAnyGlob(name, req.exclude_globs)) continue; - const kind: TopEntry['kind'] = entry.isSymbolicLink === true - ? 'symlink' - : entry.isDirectory - ? 'directory' - : 'file'; - visible.push({ name, kind }); - } - visible.sort((a, b) => { - const ad = a.kind === 'directory' ? 0 : 1; - const bd = b.kind === 'directory' ? 0 : 1; - if (ad !== bd) return ad - bd; - return a.name.localeCompare(b.name); - }); - if (visible.length > SEARCH_HARD_CAP) { - visible.length = SEARCH_HARD_CAP; - capped = true; - } - for (const entry of visible) { - if (VCS_METADATA_DIRS.has(entry.name)) continue; - if (req.include_globs !== undefined && !matchesAnyGlob(entry.name, req.include_globs)) { - continue; - } - all.push({ - path: this.suggestDisplayPath(root, entry.name), - name: entry.name, - kind: entry.kind, - }); - } - } - const items = all.slice(0, req.limit).map((entry) => ({ - path: entry.path, - name: entry.name, - kind: entry.kind, - score: 1, - match_positions: [], - })); - return { items, truncated: capped || all.length > req.limit }; - } - - private async suggestWithRg( - query: SuggestQuery, - cap: number, - signal: AbortSignal, - rgBinary: string, - roots: readonly SuggestRoot[], - ): Promise { - const args = ['--files']; - if (query.followGitignore) { - args.push('--no-require-git'); - } else { - args.push('--no-ignore'); - } - if (query.showHidden) args.push('--hidden'); - for (const dir of VCS_METADATA_DIRS) args.push('-g', `!${dir}`, '-g', `!${dir}/**`); - const multi = roots.length > 1; - if (multi) { - for (const root of roots) args.push(root.dir); - } - - const lease = this.resolver.acquire( - { workspaceId: this.workspaceId, runtimeId: this.runtimeId }, - ['process'], - ); - const proc = await lease.runtime.process!.spawn(rgBinary, args, { cwd: this.workDir }); - - const top = new SuggestTopHeap(cap); - const seenDirs = new Set(); - const seenPaths = new Set(); - let matched = 0; - let killed = false; - const kill = (): void => { - if (killed) return; - killed = true; - void proc.kill('SIGKILL'); - }; - const onAbort = (): void => kill(); - if (signal.aborted) kill(); - else signal.addEventListener('abort', onAbort, { once: true }); - - const sep = this.path.separator; - const rootMatchers = roots.map((root) => { - const dir = this.suggestRootDirSlashes(root); - return { root, prefix: dir.endsWith('/') ? dir : `${dir}/` }; - }); - - const matchRoot = (line: string): { root: SuggestRoot; rel: string } | undefined => { - let best: { root: SuggestRoot; prefix: string } | undefined; - for (const matcher of rootMatchers) { - if (line.startsWith(matcher.prefix) && (best === undefined || matcher.prefix.length > best.prefix.length)) { - best = matcher; - } - } - if (best === undefined) return undefined; - return { root: best.root, rel: line.slice(best.prefix.length) }; - }; - - const handleLine = (raw: string): void => { - let line = raw; - if (line.endsWith('\r')) line = line.slice(0, -1); - if (sep !== '/') line = line.split(sep).join('/'); - if (line.startsWith('./')) line = line.slice(2); - if (line.length === 0) return; - let root = roots[0]!; - let rel = line; - if (multi) { - const located = matchRoot(line); - if (located === undefined) return; - root = located.root; - rel = located.rel; - const pathKey = `${root.real}/${rel}`; - if (seenPaths.has(pathKey)) return; - seenPaths.add(pathKey); - } - const file = evaluateSuggestCandidate(rel, 'file', query); - if (file !== null) { - matched += 1; - top.push(this.displayCandidate(root, file)); - } - let slash = rel.lastIndexOf('/'); - while (slash > 0) { - const dir = rel.slice(0, slash); - const dirKey = multi ? `${root.real}/${dir}` : dir; - if (!seenDirs.has(dirKey)) { - seenDirs.add(dirKey); - const candidate = evaluateSuggestCandidate(dir, 'directory', query); - if (candidate !== null) { - matched += 1; - top.push(this.displayCandidate(root, candidate)); - } - } - slash = rel.lastIndexOf('/', slash - 1); - } - }; - - let stdoutBuf = ''; - const drainStdout = async (): Promise => { - proc.stdout.setEncoding('utf-8'); - try { - for await (const chunk of proc.stdout) { - stdoutBuf += chunk as string; - let nl = stdoutBuf.indexOf('\n'); - while (nl >= 0) { - handleLine(stdoutBuf.slice(0, nl)); - stdoutBuf = stdoutBuf.slice(nl + 1); - nl = stdoutBuf.indexOf('\n'); - } - } - if (stdoutBuf.length > 0) handleLine(stdoutBuf); - } catch (error) { - if (!(killed && isPrematureCloseError(error))) throw error; - } - }; - - let exitCode: number; - try { - [, , exitCode] = await Promise.all([ - drainStdout(), - readStream(proc.stderr), - proc.wait().catch(() => -1), - ]); - } finally { - signal.removeEventListener('abort', onAbort); - try { - void proc.dispose(); - } catch { - } - lease.dispose(); - } - - if (!killed && exitCode !== 0 && exitCode !== 1) { - throw new Error(`rg --files exited with code ${exitCode}`); - } - - const items = top.drain().map((candidate) => ({ - path: candidate.path, - name: candidate.name, - kind: candidate.kind, - score: candidate.score, - match_positions: [...candidate.positions], - })); - return { items, truncated: matched > cap || signal.aborted }; - } - - private async suggestWithNode( - query: SuggestQuery, - cap: number, - signal: AbortSignal, - roots: readonly SuggestRoot[], - ): Promise { - const multi = roots.length > 1; - const top = new SuggestTopHeap(cap); - const seenPaths = new Set(); - let matched = 0; - try { - for (const root of roots) { - const matcher = query.followGitignore ? await this.matcherFor(root.dir) : undefined; - await this.walk(root.dir, '', matcher, async (relPath, _name, kind) => { - if (signal.aborted) throw SUGGEST_WALK_ABORTED; - if (multi) { - const pathKey = `${root.real}/${relPath}`; - if (seenPaths.has(pathKey)) return; - seenPaths.add(pathKey); - } - const candidate = evaluateSuggestCandidate(relPath, kind, query); - if (candidate === null) return; - matched += 1; - top.push(this.displayCandidate(root, candidate)); - }); - } - } catch (err) { - if (err !== SUGGEST_WALK_ABORTED) throw err; - } - const items = top.drain().map((candidate) => ({ - path: candidate.path, - name: candidate.name, - kind: candidate.kind, - score: candidate.score, - match_positions: [...candidate.positions], - })); - return { items, truncated: matched > cap || signal.aborted }; - } - async grep(req: FsGrepRequest): Promise { const startedAt = Date.now(); const controller = new AbortController(); @@ -897,8 +577,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { args.push(req.pattern); args.push('.'); - const lease = this.resolver.acquire({ workspaceId: this.workspaceId, runtimeId: this.runtimeId }, ['process']); - const proc = await lease.runtime.process!.spawn(rgPath, args, { cwd: this.workDir }); + const proc = await this.runner.exec([rgPath, ...args], { cwd: this.workDir }); const acc = new RgJsonAccumulator(req); let killed = false; @@ -942,7 +621,6 @@ export class WorkspaceFsService implements IWorkspaceFsService { void proc.dispose(); } catch { } - lease.dispose(); } return acc.finish(signal.aborted, Date.now() - startedAt); @@ -962,7 +640,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { let truncated = false; const filePaths: string[] = []; - await this.walk(this.workDir, '', matcher, async (rel, _name, kind) => { + await this.walk('', matcher, async (rel, _name, kind) => { if (kind !== 'file') return; if (req.include_globs && !matchesAnyGlob(rel, req.include_globs)) return; if (req.exclude_globs && matchesAnyGlob(rel, req.exclude_globs)) return; @@ -1021,7 +699,6 @@ export class WorkspaceFsService implements IWorkspaceFsService { } private async walk( - baseAbs: string, rootRel: string, matcher: Ignore | undefined, visit: ( @@ -1034,7 +711,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { if (depth > WALK_MAX_DEPTH) return; let entries: readonly HostDirEntry[]; try { - entries = await this.hostFs.readdir(rootRel === '' ? baseAbs : this.path.join(baseAbs, rootRel)); + entries = await this.hostFs.readdir(this.absOf(rootRel)); } catch { return; } @@ -1054,77 +731,67 @@ export class WorkspaceFsService implements IWorkspaceFsService { : 'file'; await visit(childRel, name, kind); if (isDir) { - await this.walk(baseAbs, childRel, matcher, visit, depth + 1); + await this.walk(childRel, matcher, visit, depth + 1); } } } - private async matcherFor(rootDir: string): Promise { - const cached = this.gitignoreCache.get(rootDir); + private async matcher(): Promise { + const cwd = this.workDir; + const cached = this.gitignoreCache.get(cwd); if (cached !== undefined) return cached; const ig = ignore(); ig.add('.git/'); try { - const contents = await this.hostFs.readText(this.path.join(rootDir, '.gitignore')); + const contents = await this.hostFs.readText(join(this.workDir, '.gitignore')); ig.add(contents); } catch { } - this.gitignoreCache.set(rootDir, ig); + this.gitignoreCache.set(cwd, ig); return ig; } - private async matcher(): Promise { - return this.matcherFor(this.workDir); - } - private async resolveRg(): Promise { if (this.rgResolution !== undefined) return this.rgResolution; - const lease = this.resolver.acquire({ workspaceId: this.workspaceId, runtimeId: this.runtimeId }, ['process']); const probe: RgProbe = { - exec: (args) => runCommand(lease.runtime.process!, args, { cwd: this.workDir }), + exec: (args) => runCommand(this.runner, args, { cwd: this.workDir }), }; try { this.rgResolution = await ensureRgPath(probe); } catch { this.rgResolution = null; - } finally { - lease.dispose(); } return this.rgResolution; } - private async realRootPairs(): Promise { - const dirs = [this.workDir, ...this.workspaceDirs.additionalDirs.map((d) => this.path.resolve(d))]; + private async realRoots(): Promise { + const dirs = [this.workDir, ...this.workspaceDirs.additionalDirs.map((d) => resolve(d))]; const key = dirs.join('\n'); if (this.realRootsCache?.key === key) return this.realRootsCache.roots; - const roots: { dir: string; real: string }[] = []; + const roots: string[] = []; for (const dir of dirs) { try { - roots.push({ dir, real: await this.hostFs.realpath(dir) }); + roots.push(await this.hostFs.realpath(dir)); } catch { - roots.push({ dir, real: dir }); + roots.push(dir); } } this.realRootsCache = { key, roots }; return roots; } - private async realRoots(): Promise { - return (await this.realRootPairs()).map((pair) => pair.real); - } - private async realpathExistingPrefix(abs: string): Promise { const tail: string[] = []; let current = abs; for (let i = 0; i < 256; i++) { try { const real = await this.hostFs.realpath(current); - return tail.length === 0 ? real : this.path.join(real, ...tail.reverse()); + return tail.length === 0 ? real : join(real, ...tail.reverse()); } catch (err) { if (!isMissingPathError(err)) throw err; - const parent = this.path.dirname(current); + const parent = dirname(current); if (parent === current) return abs; - tail.push(this.path.basename(current)); + tail.push(basename(current)); current = parent; } } @@ -1137,7 +804,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { details: { path: inputPath, reason: 'empty' }, }); } - if (this.path.isAbsolute(inputPath)) { + if (isAbsolute(inputPath)) { throw new Error2(ErrorCodes.FS_PATH_ESCAPES, `path "${inputPath}" rejected (absolute)`, { details: { path: inputPath, reason: 'absolute' }, }); @@ -1156,7 +823,7 @@ export class WorkspaceFsService implements IWorkspaceFsService { } const resolved = await this.realpathExistingPrefix(abs); const roots = await this.realRoots(); - if (!roots.some((root) => isInsideOrEqual(this.path, resolved, root))) { + if (!roots.some((root) => isInsideOrEqual(resolved, root))) { throw new Error2( ErrorCodes.FS_PATH_ESCAPES, `path "${inputPath}" escapes workspace through a symlink`, @@ -1169,9 +836,9 @@ export class WorkspaceFsService implements IWorkspaceFsService { private toRel(abs: string): string { const cwd = this.workDir; if (abs === cwd) return '.'; - const rel = this.path.relative(cwd, abs); + const rel = relative(cwd, abs); if (rel === '') return '.'; - return rel.split(this.path.separator).join('/'); + return rel.split(sep).join('/'); } } @@ -1278,6 +945,7 @@ class RgJsonAccumulator { } } + function isHidden(name: string): boolean { return HIDDEN_NAME_RE.test(name) || MACOS_NOISE.has(name); } @@ -1356,11 +1024,11 @@ function isMissingPathError(err: unknown): boolean { return code === 'ENOENT' || code === 'ENOTDIR'; } -function isInsideOrEqual(path: RuntimePath, child: string, parent: string): boolean { - const rel = path.relative(parent, child); +function isInsideOrEqual(child: string, parent: string): boolean { + const rel = relative(parent, child); if (rel === '') return true; if (rel.startsWith('..')) return false; - if (path.isAbsolute(rel)) return false; + if (isAbsolute(rel)) return false; return true; } @@ -1395,3 +1063,10 @@ function toWireError(err: unknown): { code: number; msg: string } { }; } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceFsService, + WorkspaceFsService, + ScopeActivation.OnScopeCreated, + 'workspaceFs', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/fsWatch.ts b/packages/agent-core-v2/src/workspace/workspaceFs/fsWatch.ts index 16a3fabf6..160f38992 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/fsWatch.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/fsWatch.ts @@ -1,3 +1,19 @@ +/** + * `workspaceFs` domain — workspace-confined filesystem change feed. + * + * Defines the `IWorkspaceFsWatchService` that turns the os + * `IHostFsWatchService` raw events into a workspace-relative, debounced, + * `.gitignore`-aware change feed (`FsChangeEvent`) for the whole handler. + * One os watcher on the workspace root is shared by every subscriber — + * subscribers are the sessions of this workspace and any Workspace-scope + * service that wants change notifications. Each subscription declares the + * set of workspace-relative + * paths it cares about; events outside that subtree are dropped, and every + * subscription gets its own debounce window and truncation counters, so a + * per-session feed through a subscription is indistinguishable from the old + * per-session watch service. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { IDisposable } from '#/_base/di/lifecycle'; import type { Event } from '#/_base/event'; @@ -26,8 +42,6 @@ export interface IWorkspaceFsWatchSubscription extends IDisposable { readonly watchedPaths: readonly string[]; - readonly ready: Promise; - readonly onDidChangeFiles: Event; } diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/fsWatchService.ts b/packages/agent-core-v2/src/workspace/workspaceFs/fsWatchService.ts index 0ebc41155..6882f41a6 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/fsWatchService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/fsWatchService.ts @@ -1,9 +1,27 @@ +/** + * `workspaceFs` domain — `IWorkspaceFsWatchService` implementation. + * + * Keeps ONE os `IHostFsWatchService` subscription on the handler root and + * fans its raw events out to every `IWorkspaceFsWatchSubscription`: the + * shared leg (the os handle plus the `.gitignore` matcher) runs once per + * handler, the per-subscriber leg (subtree confinement, debounce window, + * overflow truncation) runs once per subscription, so two sessions of the + * same workspace never hang a second os watcher. The os handle starts + * lazily when the first subscription declares a non-empty path set and + * stops when no subscription watches anything. Path confinement is lexical + * (the handler root plus the `workspaceDirs` additional-dir set), matching + * the rest of `workspaceFs`. Bound at Workspace scope. + */ + import { isAbsolute, join, relative, resolve, sep } from 'node:path'; import ignore, { type Ignore } from 'ignore'; -import { Disposable, type IDisposable } from '#/_base/di/lifecycle'; +import { type IDisposable } from '#/_base/di/lifecycle'; +import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ErrorCodes, Error2 } from '#/errors'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { @@ -31,7 +49,7 @@ function readPositiveIntEnv(name: string, fallback: number): number { return Number.isFinite(n) && n > 0 ? n : fallback; } -export class WorkspaceFsWatchService extends Disposable implements IWorkspaceFsWatchService { +export class WorkspaceFsWatchService extends Service implements IWorkspaceFsWatchService { declare readonly _serviceBrand: undefined; private readonly subscriptions = new Set(); @@ -81,10 +99,6 @@ export class WorkspaceFsWatchService extends Disposable implements IWorkspaceFsW this.syncHandle(); } - watchHandleReady(): Promise { - return this.handle?.ready ?? Promise.resolve(); - } - private ensureHandle(): void { if (this.handle !== undefined) return; this.loadGitignore(); @@ -204,10 +218,6 @@ class WorkspaceFsWatchSubscription implements IWorkspaceFsWatchSubscription { return Array.from(this.watched); } - get ready(): Promise { - return this.owner.watchHandleReady(); - } - hasPaths(): boolean { return !this.disposed && this.watched.size > 0; } @@ -282,3 +292,10 @@ function isUnderAny(rel: string, parents: ReadonlySet): boolean { return false; } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceFsWatchService, + WorkspaceFsWatchService, + ScopeActivation.OnScopeCreated, + 'workspaceFs', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/internal/errors.ts b/packages/agent-core-v2/src/workspace/workspaceFs/internal/errors.ts index a347bcafc..dd5fe32d1 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/internal/errors.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/internal/errors.ts @@ -1,3 +1,7 @@ +/** + * `workspaceFs` domain error codes. + */ + import { registerErrorDomain, type ErrorDomain } from '#/_base/errors/codes'; export const FsErrors = { diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsProcess.ts b/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsProcess.ts index c51f795e8..75800d076 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsProcess.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsProcess.ts @@ -1,6 +1,15 @@ +/** + * `workspaceFs` domain — `runCommand` helper over `ISessionProcessRunner`. + * + * Collects a child process's full stdout/stderr and exit code through the + * Agent's backend-pluggable `ISessionProcessRunner`, with optional `AbortSignal` + * support (the caller decides timeout semantics). Kept as a standalone + * helper so it can be unit-tested with a fake runner. + */ + import { type Readable } from 'node:stream'; -import type { IHostProcess, IHostProcessService } from '#/os/interface/hostProcess'; +import { type IProcess, type ISessionProcessRunner } from '#/session/process/processRunner'; export interface RunResult { readonly exitCode: number; @@ -15,13 +24,11 @@ export interface RunCommandOptions { } export async function runCommand( - runner: IHostProcessService, + runner: ISessionProcessRunner, args: readonly string[], options: RunCommandOptions = {}, ): Promise { - const command = args[0]; - if (command === undefined) throw new Error('runCommand requires a command'); - const proc: IHostProcess = await runner.spawn(command, args.slice(1), { + const proc: IProcess = await runner.exec(args, { cwd: options.cwd, env: options.env, }); @@ -35,16 +42,12 @@ export async function runCommand( else signal.addEventListener('abort', onAbort, { once: true }); } - try { - const [stdout, stderr, exitCode] = await Promise.all([ - readStream(proc.stdout), - readStream(proc.stderr), - proc.wait().catch(() => -1), - ]); - return { exitCode, stdout, stderr }; - } finally { - signal?.removeEventListener('abort', onAbort); - } + const [stdout, stderr, exitCode] = await Promise.all([ + readStream(proc.stdout), + readStream(proc.stderr), + proc.wait().catch(() => -1), + ]); + return { exitCode, stdout, stderr }; } export function readStream(stream: Readable): Promise { diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsSearch.ts b/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsSearch.ts index 483022343..5c32e12e9 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsSearch.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/internal/fsSearch.ts @@ -1,3 +1,11 @@ +/** + * `workspaceFs` domain — pure search/grep helpers. + * + * Fuzzy filename scoring, glob matching, grep-pattern compilation, and + * ripgrep `--json` record parsing. No IO, no DI — plain functions so they can + * be unit-tested directly. Ported from v1. + */ + import type { FsGrepRequest } from '../fs'; export function computeFuzzyScore(name: string, queryLower: string): number { @@ -136,206 +144,3 @@ export function rgText(l: RgLinesField | undefined): string { } return ''; } - -export const VCS_METADATA_DIRS: ReadonlySet = new Set([ - '.git', - '.jj', - '.svn', - '.hg', - '.bzr', -]); - -export interface SuggestQuery { - readonly nameQuery: string; - readonly pathSegments: readonly string[]; - readonly showHidden: boolean; - readonly followGitignore: boolean; - readonly includeGlobs?: readonly string[]; - readonly excludeGlobs?: readonly string[]; -} - -export interface SuggestCandidate { - readonly path: string; - readonly name: string; - readonly kind: 'file' | 'directory' | 'symlink'; - readonly tier: number; - readonly depth: number; - readonly span: number; - readonly score: number; - readonly positions: readonly number[]; -} - -interface SuggestMatch { - readonly tier: number; - readonly span: number; - readonly positions: number[]; -} - -function subsequencePositions(segment: string, query: string): number[] | null { - const positions: number[] = []; - let idx = 0; - for (const ch of query) { - const found = segment.indexOf(ch, idx); - if (found < 0) return null; - positions.push(found); - idx = found + 1; - } - return positions; -} - -function matchSuggestName(name: string, queryLower: string): SuggestMatch | null { - const positions = subsequencePositions(name.toLowerCase(), queryLower); - if (positions === null) return null; - const nameLower = name.toLowerCase(); - const tier = nameLower === queryLower ? 3 : nameLower.startsWith(queryLower) ? 2 : 1; - const span = positions[positions.length - 1]! - positions[0]! + 1; - return { tier, span, positions }; -} - -function matchSuggestPath(path: string, querySegments: readonly string[]): SuggestMatch | null { - const pathLower = path.toLowerCase(); - const pathSegments = pathLower.split('/'); - const offsets: number[] = []; - let offset = 0; - for (const seg of pathSegments) { - offsets.push(offset); - offset += seg.length + 1; - } - const positions: number[] = []; - let nextSeg = 0; - let lastSeg = -1; - let lastSegPrefix = false; - for (const querySeg of querySegments) { - let matchedSeg = -1; - let segPositions: number[] | null = null; - for (let s = nextSeg; s < pathSegments.length; s++) { - segPositions = subsequencePositions(pathSegments[s]!, querySeg); - if (segPositions !== null) { - matchedSeg = s; - break; - } - } - if (matchedSeg < 0 || segPositions === null) return null; - for (const p of segPositions) positions.push(offsets[matchedSeg]! + p); - lastSegPrefix = pathSegments[matchedSeg]!.startsWith(querySeg); - lastSeg = matchedSeg; - nextSeg = matchedSeg + 1; - } - const tier = - pathLower === querySegments.join('/') - ? 3 - : lastSeg === pathSegments.length - 1 && lastSegPrefix - ? 2 - : 1; - const span = positions[positions.length - 1]! - positions[0]! + 1; - return { tier, span, positions }; -} - -export function evaluateSuggestCandidate( - relPath: string, - kind: 'file' | 'directory' | 'symlink', - query: SuggestQuery, -): SuggestCandidate | null { - const segments = relPath.split('/'); - if (segments.some((s) => VCS_METADATA_DIRS.has(s))) return null; - if (!query.showHidden && segments.some((s) => s.startsWith('.'))) return null; - const name = segments[segments.length - 1]!; - const pathMode = query.pathSegments.length > 0; - const match = pathMode - ? matchSuggestPath(relPath, query.pathSegments) - : matchSuggestName(name, query.nameQuery); - if (match === null) return null; - if (query.includeGlobs !== undefined && !matchesAnyGlob(relPath, query.includeGlobs)) return null; - if (query.excludeGlobs !== undefined && matchesAnyGlob(relPath, query.excludeGlobs)) return null; - const queryLength = pathMode - ? query.pathSegments.reduce((total, seg) => total + seg.length, 0) - : query.nameQuery.length; - const raw = - match.tier + - 0.5 / segments.length + - 0.25 * (queryLength / Math.max(name.length, 1)) + - 0.25 * (queryLength / Math.max(match.span, 1)); - const score = Math.min(1, raw / 4); - const base = relPath.length - name.length; - const positions = pathMode ? match.positions : match.positions.map((p) => base + p); - return { - path: relPath, - name, - kind, - tier: match.tier, - depth: segments.length, - span: match.span, - score, - positions, - }; -} - -export function compareSuggestCandidates(a: SuggestCandidate, b: SuggestCandidate): number { - if (a.tier !== b.tier) return b.tier - a.tier; - if (a.depth !== b.depth) return a.depth - b.depth; - if (a.name.length !== b.name.length) return a.name.length - b.name.length; - if (a.span !== b.span) return a.span - b.span; - if (a.path < b.path) return -1; - if (a.path > b.path) return 1; - return 0; -} - -export class SuggestTopHeap { - private readonly heap: SuggestCandidate[] = []; - - constructor(private readonly cap: number) {} - - get size(): number { - return this.heap.length; - } - - push(candidate: SuggestCandidate): void { - if (this.cap <= 0) return; - if (this.heap.length < this.cap) { - this.heap.push(candidate); - this.siftUp(this.heap.length - 1); - return; - } - if (compareSuggestCandidates(this.heap[0]!, candidate) <= 0) return; - this.heap[0] = candidate; - this.siftDown(0); - } - - drain(): SuggestCandidate[] { - return this.heap.slice().sort(compareSuggestCandidates); - } - - private siftUp(index: number): void { - let i = index; - while (i > 0) { - const parent = (i - 1) >> 1; - if (compareSuggestCandidates(this.heap[parent]!, this.heap[i]!) >= 0) break; - [this.heap[parent], this.heap[i]] = [this.heap[i]!, this.heap[parent]!]; - i = parent; - } - } - - private siftDown(index: number): void { - let i = index; - for (;;) { - const left = i * 2 + 1; - const right = left + 1; - let worst = i; - if ( - left < this.heap.length && - compareSuggestCandidates(this.heap[left]!, this.heap[worst]!) > 0 - ) { - worst = left; - } - if ( - right < this.heap.length && - compareSuggestCandidates(this.heap[right]!, this.heap[worst]!) > 0 - ) { - worst = right; - } - if (worst === i) break; - [this.heap[worst], this.heap[i]] = [this.heap[i]!, this.heap[worst]!]; - i = worst; - } - } -} diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/internal/rgLocator.ts b/packages/agent-core-v2/src/workspace/workspaceFs/internal/rgLocator.ts index 94986115c..057742c7a 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/internal/rgLocator.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/internal/rgLocator.ts @@ -1,3 +1,21 @@ +/** + * `workspaceFs` domain — shared ripgrep (`rg`) binary locator. + * + * Single place that decides which `rg` the fs search/grep paths run. The + * lookup mirrors v1's `ensureRgPath` intent (bundled-or-system, graceful + * degradation) but is driven through a caller-supplied {@link RgProbe} so it + * works against whatever execution environment the caller has. + * + * Lookup order (first hit wins): + * 1. System `rg` on the execution-environment PATH (`rg --version`). + * 2. Persistent cache at `/bin/rg` — where a + * previously bootstrapped or manually dropped static binary lives. Only + * attempted when `allowCachedFallback` is set. + * + * If nothing resolves, {@link ensureRgPath} throws and callers surface + * {@link rgUnavailableMessage} instead of a naked `spawn rg ENOENT`. + */ + import { homedir } from 'node:os'; import { join } from 'node:path'; diff --git a/packages/agent-core-v2/src/workspace/workspaceFs/internal/runRg.ts b/packages/agent-core-v2/src/workspace/workspaceFs/internal/runRg.ts index 8bdf33757..acac5afff 100644 --- a/packages/agent-core-v2/src/workspace/workspaceFs/internal/runRg.ts +++ b/packages/agent-core-v2/src/workspace/workspaceFs/internal/runRg.ts @@ -1,6 +1,16 @@ +/** + * `workspaceFs` domain — shared ripgrep subprocess plumbing. + * + * Timeout / abort handling, capped stdout / stderr draining, two-phase kill + * with process disposal, and the EAGAIN retry predicate for spawning `rg` + * through the handler-shared `ISessionProcessRunner`. Ported from v1. This + * helper is the reusable module for callers that want the simpler buffered + * shape. + */ + import type { Readable } from 'node:stream'; -import type { IHostProcess, IHostProcessService } from '#/os/interface/hostProcess'; +import type { IProcess, ISessionProcessRunner } from '#/session/process/processRunner'; export const DEFAULT_TIMEOUT_MS = 20_000; export const SIGTERM_GRACE_MS = 5_000; @@ -17,7 +27,7 @@ export interface RunRgResult { export type RunRgOutcome = RunRgResult | { readonly kind: 'aborted' }; -async function disposeProcess(proc: IHostProcess): Promise { +async function disposeProcess(proc: IProcess): Promise { try { await proc.dispose(); } catch { @@ -25,7 +35,7 @@ async function disposeProcess(proc: IHostProcess): Promise { } export async function runRgOnce( - runner: IHostProcessService, + runner: ISessionProcessRunner, rgArgs: readonly string[], signal: AbortSignal, options?: { readonly cwd?: string }, @@ -34,9 +44,7 @@ export async function runRgOnce( return { kind: 'aborted' }; } - const command = rgArgs[0]; - if (command === undefined) throw new Error('runRgOnce requires a command'); - const proc: IHostProcess = await runner.spawn(command, rgArgs.slice(1), { cwd: options?.cwd }); + const proc: IProcess = await runner.exec(rgArgs, { cwd: options?.cwd }); try { proc.stdin.end(); diff --git a/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGit.ts b/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGit.ts index 5aca9e3cf..ad2477801 100644 --- a/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGit.ts +++ b/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGit.ts @@ -1,3 +1,11 @@ +/** + * `workspaceGit` domain — handler-root-bound git facade contract. + * + * Defines the `IWorkspaceGitService`, a thin facade over the App-scope + * `IGitService` pinned to this handler's workspace root: callers pass + * repo-relative paths only, never a `cwd`. Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { FsDiffResponse, FsGitStatusResponse } from '#/app/git/git'; diff --git a/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGitService.ts b/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGitService.ts index 67a1f8d5f..c0ad3fcc6 100644 --- a/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGitService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceGit/workspaceGitService.ts @@ -1,4 +1,14 @@ -import { ref, type LiveRef } from '#/_base/di/instantiation'; +/** + * `workspaceGit` domain — `IWorkspaceGitService` implementation. + * + * Delegates every call to the App-scope `IGitService` with `cwd` pinned to + * the handler's workspace root (`IWorkspaceContext.cwd`). Owns no state. + * Bound at Workspace scope. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { type FsDiffResponse, type FsGitStatusResponse, IGitService } from '#/app/git/git'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; @@ -9,15 +19,22 @@ export class WorkspaceGitService implements IWorkspaceGitService { constructor( @IWorkspaceContext private readonly workspace: IWorkspaceContext, - @ref(IGitService) private readonly git: LiveRef, + @IGitService private readonly git: IGitService, ) {} status(pathFilter?: ReadonlySet): Promise { - return this.git.current!.status(this.workspace.cwd, pathFilter); + return this.git.status(this.workspace.cwd, pathFilter); } diff(relPath: string, absPath: string): Promise { - return this.git.current!.diff(this.workspace.cwd, relPath, absPath); + return this.git.diff(this.workspace.cwd, relPath, absPath); } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceGitService, + WorkspaceGitService, + ScopeActivation.OnScopeCreated, + 'workspaceGit', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstance.ts b/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstance.ts deleted file mode 100644 index 8dbfd14e9..000000000 --- a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstance.ts +++ /dev/null @@ -1,64 +0,0 @@ -import type { Workspace } from '#/app/workspace/workspace'; -import { Program, type ProgramSnapshot } from '#/program/program'; -import type { ProgramDependencies } from '#/program/programDependencies'; -import type { RuntimeRegistry, RuntimeRegistrySnapshot } from '#/runtime/runtimeRegistry'; -import type { RuntimeUnitHost } from '#/runtime/runtimeUnitHost'; -import type { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; - -export type WorkspaceInstanceLifecycle = 'materializing' | 'active' | 'closing' | 'disposed'; - -export interface WorkspaceInstanceSnapshot { - readonly metadata: Workspace; - readonly lifecycle: WorkspaceInstanceLifecycle; - readonly program: ProgramSnapshot; - readonly runtimes: RuntimeRegistrySnapshot; -} - -export class WorkspaceInstance { - readonly runtimes: RuntimeRegistry; - readonly unitHost: RuntimeUnitHost; - readonly program: Program; - private lifecycle: WorkspaceInstanceLifecycle = 'materializing'; - - constructor( - readonly metadata: Workspace, - runtimes: RuntimeRegistry, - unitHost: RuntimeUnitHost, - context: IWorkspaceContext, - dependencies: ProgramDependencies, - ) { - this.runtimes = runtimes; - this.unitHost = unitHost; - this.program = new Program(metadata.id, this.runtimes, context, dependencies); - } - - get id(): string { - return this.metadata.id; - } - - get root(): string { - return this.metadata.root; - } - - activate(): void { - if (this.lifecycle === 'materializing') this.lifecycle = 'active'; - } - - snapshot(): WorkspaceInstanceSnapshot { - return { - metadata: this.metadata, - lifecycle: this.lifecycle, - program: this.program.snapshot(), - runtimes: this.runtimes.snapshot(), - }; - } - - async dispose(): Promise { - if (this.lifecycle === 'disposed') return; - this.lifecycle = 'closing'; - this.program.dispose(); - await this.unitHost.dispose(); - await this.runtimes.dispose(); - this.lifecycle = 'disposed'; - } -} diff --git a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManager.ts b/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManager.ts deleted file mode 100644 index 55c263b7d..000000000 --- a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManager.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event } from '#/_base/event'; -import type { Runtime, RuntimeBinding, RuntimeCapability, RuntimeLease } from '#/runtime/runtime'; -import type { RuntimeProviderFactory } from '#/runtime/runtimeProvider'; - -import type { WorkspaceInstance, WorkspaceInstanceSnapshot } from './workspaceInstance'; - -export type WorkspaceInstanceRef = { readonly workspaceId: string; readonly root?: string } | { readonly root: string }; - -export interface WorkspaceInstanceChange { - readonly workspaceId: string; - readonly instance?: WorkspaceInstance; -} - -export interface WorkspaceInstancesSnapshot { - readonly workspaces: readonly WorkspaceInstanceSnapshot[]; -} - -export interface IWorkspaceInstanceManager { - readonly _serviceBrand: undefined; - readonly onDidChange: Event; - getOrCreate(ref: WorkspaceInstanceRef): Promise; - get(workspaceId: string): WorkspaceInstance | undefined; - findByRoot(root: string): WorkspaceInstance | undefined; - findContaining(cwd: string): WorkspaceInstance | undefined; - list(): readonly WorkspaceInstance[]; - snapshot(): WorkspaceInstancesSnapshot; - close(workspaceId: string): Promise; - addProvider(factory: RuntimeProviderFactory): Promise<{ dispose(): void | Promise }>; -} - -export const IWorkspaceInstanceManager: ServiceIdentifier = createDecorator('workspaceInstanceManager'); - -export interface IRuntimeResolver { - readonly _serviceBrand: undefined; - inspect(binding: RuntimeBinding): Runtime; - acquire(binding: RuntimeBinding, required?: readonly RuntimeCapability[]): RuntimeLease; -} - -export const IRuntimeResolver: ServiceIdentifier = createDecorator('runtimeResolver'); diff --git a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManagerService.ts b/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManagerService.ts deleted file mode 100644 index 053bfc35f..000000000 --- a/packages/agent-core-v2/src/workspace/workspaceInstance/workspaceInstanceManagerService.ts +++ /dev/null @@ -1,312 +0,0 @@ -import { IInstantiationService, ref, type LiveRef } from '#/_base/di/instantiation'; -import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; -import { Emitter } from '#/_base/event'; -import { ILogService } from '#/_base/log/log'; -import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; -import { IBuiltinAgentProfileLoader } from '#/app/agentProfileCatalog/builtinAgentProfileLoader'; -import { IAgentProfileRegistry } from '#/app/agentProfileCatalog/agentProfileRegistry'; -import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { IConfigService } from '#/app/config/config'; -import { IEventService } from '#/app/event/event'; -import { IFlagService } from '#/app/flag/flag'; -import { IGitService } from '#/app/git/git'; -import { IMcpOAuthService } from '#/app/mcpConfig/oauthService'; -import type { McpOAuthService } from '#/mcpCore/oauth/service'; -import { IMcpConfigStore } from '#/app/mcpConfig/configStore'; -import { IPluginService } from '#/app/plugin/plugin'; -import { ISessionIndex, ISessionIndexMirror } from '#/app/sessionIndex/sessionIndex'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { IBuiltinSkillSource } from '#/features/skill/catalog/builtinSkillSource'; -import { IAppStateService } from '#/app/state/appState'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; -import { LifecycleScope } from '#/app/scopes'; -import { IWorkspaceService, type Workspace } from '#/app/workspace/workspace'; -import { IModelCatalog } from '#/kosong/model/catalog'; -import { IModelService } from '#/kosong/model/model'; -import { IProviderService } from '#/kosong/provider/provider'; -import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; -import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; -import { Error2, ErrorCodes } from '#/errors'; -import { IHostEnvironment } from '#/os/interface/hostEnvironment'; -import { LocalRuntimeProviderFactory } from '#/runtime/localRuntime'; -import { canonicalWorkspaceRoot } from '#/_base/utils/paths'; -import type { Runtime, RuntimeBinding, RuntimeCapability, RuntimeLease } from '#/runtime/runtime'; -import { RuntimeError, RuntimeRegistry } from '#/runtime/runtimeRegistry'; -import type { RuntimeProviderFactory } from '#/runtime/runtimeProvider'; -import { SharedRuntimeUnitHostFactory, type RuntimeUnitHandle, type RuntimeUnitHostFactory } from '#/runtime/runtimeUnitHost'; -import { SessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycleService'; - -import { WorkspaceInstance } from './workspaceInstance'; -import { IRuntimeResolver, IWorkspaceInstanceManager, type WorkspaceInstanceRef } from './workspaceInstanceManager'; - -export class WorkspaceInstanceManager implements IWorkspaceInstanceManager { - declare readonly _serviceBrand: undefined; - private readonly instances = new Map(); - private readonly requests = new Map>(); - private readonly inflight = new Map>(); - private readonly providers = new Map(); - private readonly attachments = new Map>(); - private readonly changeEmitter = new Emitter<{ workspaceId: string; instance?: WorkspaceInstance }>(); - readonly onDidChange = this.changeEmitter.event; - - constructor( - @IInstantiationService private readonly instantiation: IInstantiationService, - @IBootstrapService private readonly bootstrap: IBootstrapService, - @IWorkspaceService private readonly workspaces: IWorkspaceService, - @IHostEnvironment private readonly environment: IHostEnvironment, - @IAppStateService private readonly appState: IAppStateService, - @IConfigService private readonly config: IConfigService, - @IEventService private readonly event: IEventService, - @IFlagService private readonly flags: IFlagService, - @ref(IGitService) private readonly git: LiveRef, - @IAgentIdentity private readonly identity: IAgentIdentity, - @ISessionIndex private readonly index: ISessionIndex, - @ISessionIndexMirror private readonly indexMirror: ISessionIndexMirror, - @ILogService private readonly log: ILogService, - @IModelCatalog private readonly modelCatalog: IModelCatalog, - @IModelService private readonly models: IModelService, - @IMcpOAuthService private readonly oauth: McpOAuthService, - @IMcpConfigStore private readonly configStore: IMcpConfigStore, - @IPluginService private readonly plugins: IPluginService, - @IProviderService private readonly modelProviders: IProviderService, - @ref(ISessionManager) private readonly sessionManager: LiveRef, - @IAgentProfileRegistry private readonly agentProfiles: IAgentProfileRegistry, - @IBuiltinAgentProfileLoader private readonly builtinAgentProfiles: IBuiltinAgentProfileLoader, - @IBuiltinSkillSource private readonly builtinSkills: IBuiltinSkillSource, - @ITelemetryService private readonly telemetry: ITelemetryService, - @IAppendLogStore private readonly appendLogStore: IAppendLogStore, - @IAtomicDocumentStore private readonly docs: IAtomicDocumentStore, - private readonly unitHostFactory: RuntimeUnitHostFactory = new SharedRuntimeUnitHostFactory(), - ) { - this.providers.set('local', new LocalRuntimeProviderFactory()); - } - - get(workspaceId: string): WorkspaceInstance | undefined { - return this.instances.get(workspaceId); - } - - findByRoot(root: string): WorkspaceInstance | undefined { - const normalized = root.replace(/[\\/]$/, ''); - return [...this.instances.values()].find((instance) => instance.root.replace(/[\\/]$/, '') === normalized); - } - - findContaining(cwd: string): WorkspaceInstance | undefined { - const probe = canonicalWorkspaceRoot(cwd); - let best: { readonly instance: WorkspaceInstance; readonly rootLength: number } | undefined; - for (const instance of this.instances.values()) { - const root = canonicalWorkspaceRoot(instance.root); - const prefix = root.endsWith('/') ? root : `${root}/`; - if (probe !== root && !probe.startsWith(prefix)) continue; - if (best === undefined || root.length > best.rootLength) { - best = { instance, rootLength: root.length }; - } - } - return best?.instance; - } - - list(): readonly WorkspaceInstance[] { - return [...this.instances.values()]; - } - - snapshot(): { readonly workspaces: readonly ReturnType[] } { - return { workspaces: this.list().map((instance) => instance.snapshot()) }; - } - - async getOrCreate(ref: WorkspaceInstanceRef): Promise { - const key = 'workspaceId' in ref - ? `id:${ref.workspaceId}` - : `root:${ref.root.replace(/[\\/]$/, '')}`; - const request = this.requests.get(key); - if (request !== undefined) return request; - const promise = (async () => { - let workspace: Workspace | undefined; - if ('workspaceId' in ref) { - workspace = await this.workspaces.get(ref.workspaceId); - if (workspace === undefined && ref.root !== undefined) workspace = await this.workspaces.createOrTouch(ref.root); - } else { - workspace = await this.workspaces.createOrTouch(ref.root); - } - if (workspace === undefined) throw new Error2(ErrorCodes.WORKSPACE_NOT_FOUND, `workspace ${'workspaceId' in ref ? ref.workspaceId : ref.root} does not exist`); - const existing = this.instances.get(workspace.id); - if (existing !== undefined) return existing; - const pending = this.inflight.get(workspace.id); - if (pending !== undefined) return pending; - const materialization = this.materialize(workspace).finally(() => this.inflight.delete(workspace.id)); - this.inflight.set(workspace.id, materialization); - return materialization; - })().finally(() => this.requests.delete(key)); - this.requests.set(key, promise); - return promise; - } - - async close(workspaceId: string): Promise { - const pending = this.requests.get(`id:${workspaceId}`) ?? this.inflight.get(workspaceId); - if (pending !== undefined) { - try { - await pending; - } catch { - return; - } - } - const instance = this.instances.get(workspaceId); - if (instance === undefined) return; - this.instances.delete(workspaceId); - const attachments = this.attachments.get(workspaceId); - this.attachments.delete(workspaceId); - if (attachments !== undefined) for (const attachment of [...attachments.values()].reverse()) await attachment.dispose(); - await instance.dispose(); - this.changeEmitter.fire({ workspaceId }); - } - - async addProvider(factory: RuntimeProviderFactory): Promise<{ dispose(): Promise }> { - if (this.providers.has(factory.id)) throw new Error(`runtime provider ${factory.id} already exists`); - this.providers.set(factory.id, factory); - const attached: WorkspaceInstance[] = []; - try { - for (const instance of this.instances.values()) { - await this.attach(instance, factory); - attached.push(instance); - } - } catch (error) { - this.providers.delete(factory.id); - for (const instance of attached.reverse()) await this.detach(instance.id, factory.id); - throw error; - } - return { dispose: async () => { - if (this.providers.get(factory.id) !== factory) return; - this.providers.delete(factory.id); - for (const workspaceId of [...this.attachments.keys()].reverse()) await this.detach(workspaceId, factory.id); - } }; - } - - async dispose(): Promise { - for (const workspaceId of [...this.instances.keys()].reverse()) await this.close(workspaceId); - this.changeEmitter.dispose(); - } - - private async materialize(workspace: Workspace): Promise { - await this.environment.ready; - const runtimes = new RuntimeRegistry(workspace.id); - const unitHost = this.unitHostFactory.create(this.instantiation, runtimes); - const instance = new WorkspaceInstance( - workspace, - runtimes, - unitHost, - { - _serviceBrand: undefined, - workspaceId: workspace.id, - cwd: workspace.root, - source: 'local', - meta: workspace, - persistenceScope: `${this.bootstrap.scope('sessions')}/${workspace.id}`, - }, - { - appState: this.appState, - bootstrap: this.bootstrap, - config: this.config, - git: this.git, - identity: this.identity, - log: this.log, - oauth: this.oauth, - configStore: this.configStore, - plugins: this.plugins, - sessionManager: this.sessionManager, - agentProfiles: this.agentProfiles, - builtinAgentProfiles: this.builtinAgentProfiles, - builtinSkills: this.builtinSkills, - telemetry: this.telemetry, - docs: this.docs, - createSessionController: (input) => new SessionLifecycleService( - this.instantiation, - input.context, - this.bootstrap, - this.config, - this.index, - this.indexMirror, - this.appendLogStore, - this.docs, - input.fs, - this.event, - this.telemetry, - input.workspaceAgentProfiles, - input.extraAgentProfiles, - input.explicitAgentProfiles, - input.userAgentProfiles, - input.pluginAgentProfiles, - input.dirs, - input.skills, - input.instructions, - input.mcp, - this.modelCatalog, - this.models, - this.modelProviders, - this.flags, - input.onDispose, - ), - }, - ); - try { - for (const provider of this.providers.values()) await this.attach(instance, provider); - if (instance.runtimes.current('local') === undefined) throw new Error(`workspace ${workspace.id} has no local runtime`); - instance.activate(); - this.instances.set(workspace.id, instance); - this.changeEmitter.fire({ workspaceId: workspace.id, instance }); - return instance; - } catch (error) { - const attachments = this.attachments.get(instance.id); - this.attachments.delete(instance.id); - if (attachments !== undefined) { - for (const attachment of [...attachments.values()].reverse()) await attachment.dispose(); - } - await instance.dispose(); - throw error; - } - } - - private async attach(instance: WorkspaceInstance, provider: RuntimeProviderFactory): Promise { - const existing = this.attachments.get(instance.id); - if (existing?.has(provider.id) === true) throw new Error(`runtime provider ${provider.id} is already attached to workspace ${instance.id}`); - const attachment = await instance.unitHost.provide(provider.imports, (host) => provider.attach({ - id: instance.id, - root: instance.root, - metadata: instance.metadata, - }, host)); - let attachments = this.attachments.get(instance.id); - if (attachments === undefined) { - attachments = new Map(); - this.attachments.set(instance.id, attachments); - } - attachments.set(provider.id, attachment); - } - - private async detach(workspaceId: string, providerId: string): Promise { - const attachments = this.attachments.get(workspaceId); - const attachment = attachments?.get(providerId); - if (attachments === undefined || attachment === undefined) return; - attachments.delete(providerId); - if (attachments.size === 0) this.attachments.delete(workspaceId); - await attachment.dispose(); - } -} - -export class RuntimeResolver implements IRuntimeResolver { - declare readonly _serviceBrand: undefined; - constructor(@IWorkspaceInstanceManager private readonly workspaces: IWorkspaceInstanceManager) {} - inspect(binding: RuntimeBinding): Runtime { - const workspace = this.workspaces.get(binding.workspaceId); - if (workspace === undefined) { - throw new RuntimeError('runtime.not_found', `workspace ${binding.workspaceId} is not materialized`); - } - return workspace.runtimes.inspect(binding); - } - acquire(binding: RuntimeBinding, required: readonly RuntimeCapability[] = []): RuntimeLease { - const workspace = this.workspaces.get(binding.workspaceId); - if (workspace === undefined) { - throw new RuntimeError('runtime.not_found', `workspace ${binding.workspaceId} is not materialized`); - } - return workspace.runtimes.acquire(binding, required); - } -} - -registerScopedService(LifecycleScope.App, IWorkspaceInstanceManager, WorkspaceInstanceManager, ScopeActivation.OnScopeCreated, 'workspaceInstanceManager'); -registerScopedService(LifecycleScope.App, IRuntimeResolver, RuntimeResolver, ScopeActivation.OnScopeCreated, 'runtimeResolver'); diff --git a/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructions.ts b/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructions.ts index 0727e857f..5315902f0 100644 --- a/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructions.ts +++ b/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructions.ts @@ -1,6 +1,20 @@ +/** + * `workspaceInstructions` domain — Workspace-scoped AGENTS.md service + * contract. + * + * Defines `IWorkspaceInstructionsService`, the handler-level owner of the + * workspace's AGENTS.md instruction snapshot: loaded once at handler + * materialization through the `profile` domain's pure loader, then + * invalidated by fs watch on every candidate instruction file and reloaded + * debounced. `sessionProvider()` projects the snapshot into the + * `ISessionInstructionsProvider` seed every Session scope of this handler + * receives, so agent system prompts read the shared snapshot and refresh off + * its change event instead of re-reading the files per prompt build. Bound + * at Workspace scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; -import type { HostFsChange } from '#/os/interface/hostFsWatch'; import type { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; export interface WorkspaceInstructionsSnapshot { @@ -14,7 +28,7 @@ export interface IWorkspaceInstructionsService { readonly ready: Promise; readonly snapshot: WorkspaceInstructionsSnapshot; - readonly onDidChange: Event; + readonly onDidChange: Event; reload(): Promise; sessionProvider(): ISessionInstructionsProvider; } diff --git a/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructionsService.ts b/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructionsService.ts index abbda9185..db0866784 100644 --- a/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructionsService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceInstructions/workspaceInstructionsService.ts @@ -1,14 +1,35 @@ -import { Disposable } from '#/_base/di/lifecycle'; +/** + * `workspaceInstructions` domain — `IWorkspaceInstructionsService` + * implementation. + * + * Loads the workspace root's AGENTS.md hierarchy at construction through the + * `profile` domain's pure loader (over the os `hostFs`, the host home dir, + * and the `bootstrap` brand dir), then watches the loader's probe set + * (`agentsMdWatchRoots` — brand / user-generic / project-root→leaf chain, + * each plan root watched recursively and pruned to its candidates so files + * created later inside not-yet-existing directories are still caught) + * through `hostFsWatch` and reloads debounced; the change event fires only + * when the combined content or warning actually changed. The snapshot is shared by every session of + * the handler through the `ISessionInstructionsProvider` seed + * (`sessionProvider()`), a live read view over this service. The plain-data + * state (`current`) is registered into `workspaceState` + * (`IWorkspaceStateService`) and read/written through it. Bound at + * Workspace scope. + */ + +import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; import { TimeoutTimer } from '#/_base/utils/timer'; import { subtreeWatchFilter } from '#/_base/utils/paths'; import { agentsMdWatchRoots, loadAgentsMdForRoots } from '#/agent/profile/context'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { IHostEnvironment, type HostEnvironmentInfo } from '#/os/interface/hostEnvironment'; +import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; -import { IHostFsWatchService, type HostFsChange } from '#/os/interface/hostFsWatch'; +import { IHostFsWatchService } from '#/os/interface/hostFsWatch'; import type { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; import { IWorkspaceStateService } from '#/workspace/state/workspaceState'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; @@ -26,30 +47,28 @@ export const workspaceInstructionsCurrentKey = defineState; - private readonly onDidChangeEmitter = this._register(new Emitter()); - readonly onDidChange: Event = this.onDidChangeEmitter.event; + private readonly onDidChangeEmitter = this._register(new Emitter()); + readonly onDidChange: Event = this.onDidChangeEmitter.event; private readonly watchDebounce = this._register(new TimeoutTimer()); private reloadTail: Promise = Promise.resolve(); - private loaded = false; - private readonly pendingChanges = new Map(); constructor( @IWorkspaceContext private readonly workspace: IWorkspaceContext, @IHostFileSystem private readonly fs: IHostFileSystem, - @IHostEnvironment private readonly env: HostEnvironmentInfo, + @IHostEnvironment private readonly env: IHostEnvironment, @IBootstrapService private readonly bootstrap: IBootstrapService, @IHostFsWatchService private readonly fsWatch: IHostFsWatchService, @ILogService private readonly log: ILogService, @IWorkspaceStateService private readonly states: IWorkspaceStateService, ) { super(); - this.states.contributeState(workspaceInstructionsCurrentKey); + this.states.register(workspaceInstructionsCurrentKey); this.ready = this.reload(); void this.watchCandidateFiles(); } @@ -82,12 +101,8 @@ export class WorkspaceInstructionsService next.agentsMd !== this.current.agentsMd || next.agentsMdWarning !== this.current.agentsMdWarning; this.current = next; - const changes = [...this.pendingChanges.values()]; - this.pendingChanges.clear(); - const loaded = this.loaded; - this.loaded = true; - if (changed && loaded) { - this.onDidChangeEmitter.fire(changes); + if (changed) { + this.onDidChangeEmitter.fire(); } }); this.reloadTail = tail; @@ -127,8 +142,7 @@ export class WorkspaceInstructionsService }); this._register(handle); this._register( - handle.onDidChange((change) => { - this.pendingChanges.set(change.path, change); + handle.onDidChange(() => { this.watchDebounce.cancelAndSet(() => { void this.reload().catch((error) => { this.log.warn(`AGENTS.md reload failed: ${String(error)}`); @@ -143,3 +157,10 @@ export class WorkspaceInstructionsService } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceInstructionsService, + WorkspaceInstructionsService, + ScopeActivation.OnScopeCreated, + 'workspaceInstructions', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcp.ts b/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcp.ts index 2b140261a..a95695a63 100644 --- a/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcp.ts +++ b/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcp.ts @@ -1,3 +1,24 @@ +/** + * `workspaceMcp` domain — Workspace-scoped MCP subsystem contract. + * + * Defines `IWorkspaceMcpService`, the handler-level owner of the workspace's + * ONE shared `McpConnectionManager`: connected at handler materialization + * from the `workspaceMcpConfig` domain's effective server snapshot and + * incrementally reconciled as its change events arrive. Every session of the + * handler receives the manager through the `ISessionMcpHandle` seed + * (`sessionHandle()`). A session created with ephemeral MCP servers + * (`CreateSessionOptions.mcpServers`) additionally gets a session overlay + * (`sessionOverlay()`): a session-owned manager for those servers — never + * persisted, never part of the config domain's effective set, invisible to + * the handler's other sessions — presented to the session through a merged + * view. The service activates overlays itself from the session lifecycle's + * `onWillCreateSession` event (keyed by the `ISessionEphemeralMcpServers` + * seed) and attaches each overlay's `shutdown()` to the session's teardown. + * Ephemeral servers are a caller-explicit injection channel + * (like the user-level `mcp.json`), so they are not gated by workspace + * trust — only the project-level config files are. Bound at Workspace scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { McpConnectionManager } from '#/mcpCore/connection-manager'; import type { McpServerConfig } from '#/mcpCore/config-schema'; diff --git a/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcpService.ts b/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcpService.ts index 1103949a4..efd515b62 100644 --- a/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcpService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceMcp/workspaceMcpService.ts @@ -1,24 +1,70 @@ -import { ref, type LiveRef } from '#/_base/di/instantiation'; -import { Disposable } from '#/_base/di/lifecycle'; +/** + * `workspaceMcp` domain — `IWorkspaceMcpService` implementation. + * + * Owns the handler-wide `McpConnectionManager` (built at construction, + * shared by every session of the workspace). This service drives the + * initial connect from the config domain's snapshot, applies its reconciled + * change events incrementally (serialized on a mutation tail, always after + * the initial connect settles — removals tombstone the server via + * `markRemoved` so live sessions keep the tool registrations but fail calls + * with a removal notice, while new sessions never see them), feeds the + * manager's global timeout defaults + * from the config domain's tunables at each (re)connect, and reports + * connection telemetry for the initial load. Every session handle it hands + * out (`sessionHandle` / `sessionOverlay`) captures a server baseline — the + * names present when the session materializes, open to additions until the + * initial connect settles, then closed — so servers that appear mid-session + * (a plugin install or a config edit, which always land after the initial + * connect via the mutation tail) never reach the live sessions' tool + * registries; the next session materialization (`/new`, `/reload`, resume) + * captures a fresh baseline. It also builds per-session + * overlays (`sessionOverlay`): a session-owned manager for a session's + * ephemeral (caller-injected, never persisted) servers — baseline members + * by construction — presented through a + * `MergedMcpConnectionView` over the shared manager. Overlay activation is + * event-driven: this service subscribes to the session lifecycle's + * `onWillCreateSession`, and a session created with an + * `ISessionEphemeralMcpServers` seed gets its overlay created there — the + * merged handle contributed as the session's `ISessionMcpHandle` (replacing + * the seed adapter's workspace projection), the overlay's shutdown attached + * to the session's teardown, so the session lifecycle never depends on MCP. + * The overlay's stdio cwd is read from the session's own `ISessionContext`. + * An overlay handle's + * baseline still freezes on the workspace manager's initial load — never on + * the overlay's own connect — so a slow ephemeral connect cannot reopen the + * window for mid-session workspace additions. + * An outright initial-load or change-apply failure is logged (per-server + * failures are status entries). The manager (and its stdio child processes, + * whose cwd is the handler root) lives as long as the handler — i.e. the + * process — so a stateful stdio server is shared by concurrent sessions of + * the workspace rather than owned by one session. Bound at Workspace scope. + * + * The client name announced to MCP servers — on initialize and on OAuth + * dynamic registration — is the identity snapshot's slug. Every manager it + * builds, the shared one and each session overlay, gates its connects on + * `identity.resolved()`, so the callback handed to the managers always reads + * the frozen snapshot: a connection (and the OAuth provider a remote server + * materializes, cached on the shared service) can never carry a pre-config + * name. + */ + +import { Service } from '#/_base/di/service'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { ILogService } from '#/_base/log/log'; -import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; -import { IMcpOAuthService } from '#/app/mcpConfig/oauthService'; -import { ISessionManager } from '#/app/sessionManager/sessionManager'; -import { ITelemetryService } from '#/app/telemetry/telemetry'; + +import { McpConnectionManager, type McpConnectionView } from '#/mcpCore/connection-manager'; import type { McpServerConfig } from '#/mcpCore/config-schema'; -import { - McpConnectionManager, - type McpConnectionView, - type McpServerEntry, -} from '#/mcpCore/connection-manager'; -import type { McpOAuthEvent, McpOAuthService } from '#/mcpCore/oauth/service'; -import { canonicalMcpOAuthResource } from '#/mcpCore/oauth/store'; +import { McpOAuthService } from '#/mcpCore/oauth/service'; +import { IAgentIdentity } from '#/app/agentIdentity/agentIdentity'; +import { IMcpOAuthStore } from '#/app/mcpConfig/oauthStore'; +import { ITelemetryService } from '#/app/telemetry/telemetry'; import { ISessionEphemeralMcpServers } from '#/session/mcp/ephemeralMcpServers'; import { MergedMcpConnectionView } from '#/session/mcp/mergedConnectionView'; import { ISessionMcpHandle } from '#/session/mcp/sessionMcpHandle'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; -import { IRuntimeResolver } from '#/workspace/workspaceInstance/workspaceInstanceManager'; +import { ISessionLifecycleService } from '#/workspace/sessionLifecycle/sessionLifecycle'; import { IWorkspaceMcpConfigService, type McpServersChange, @@ -30,66 +76,46 @@ import { type SessionMcpOverlayOptions, } from './workspaceMcp'; -export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpService { +export class WorkspaceMcpService extends Service implements IWorkspaceMcpService { declare readonly _serviceBrand: undefined; private readonly manager: McpConnectionManager; private readonly oauthService: McpOAuthService; private readonly stdioCwd: string; - private readonly workspaceId: string; readonly ready: Promise; private mutationTail: Promise = Promise.resolve(); private readonly resolveClientName = (): string | undefined => this.identity.current().slug; - private readonly sessionLifecycle: LiveRef; - private sessionLifecycleAttached = false; constructor( @IWorkspaceContext workspace: IWorkspaceContext, - @IRuntimeResolver private readonly runtimeResolver: IRuntimeResolver, @IWorkspaceMcpConfigService private readonly mcpConfig: IWorkspaceMcpConfigService, - @IMcpOAuthService oauthService: McpOAuthService, + @IMcpOAuthStore oauthStore: IMcpOAuthStore, @ILogService private readonly log: ILogService, @ITelemetryService private readonly telemetry: ITelemetryService, @IAgentIdentity private readonly identity: IAgentIdentity, - @ref(ISessionManager) sessionLifecycle: LiveRef, + @ISessionLifecycleService sessionLifecycle: ISessionLifecycleService, ) { super(); - this.sessionLifecycle = sessionLifecycle; this.stdioCwd = workspace.cwd; - this.workspaceId = workspace.workspaceId; - this.oauthService = oauthService; + this.oauthService = new McpOAuthService({ + store: oauthStore, + resolveClientName: this.resolveClientName, + }); this.manager = new McpConnectionManager({ log: this.log, oauthService: this.oauthService, stdioCwd: this.stdioCwd, - runtimeResolver: this.runtimeResolver, - workspaceId: workspace.workspaceId, - runtimeId: 'local', resolveDefaultTimeouts: () => this.mcpConfig.tunables(), resolveClientName: this.resolveClientName, }); this._register({ dispose: () => void this.manager.shutdown() }); this._register( this.mcpConfig.onDidChange((change) => { - change.waitUntil(this.scheduleApply(change)); + this.scheduleApply(change); }), ); - this._register({ dispose: this.oauthEventSubscription(this.manager) }); - this.attachSessionLifecycle(); - this._register(sessionLifecycle.onDidChange(() => this.attachSessionLifecycle())); - this.ready = this.initialize().catch((error: unknown) => { - this.log.error('mcp initial load failed', { error }); - }); - } - - private attachSessionLifecycle(): void { - if (this.sessionLifecycleAttached) return; - const lifecycle = this.sessionLifecycle.current; - if (lifecycle?.onWillCreateSession === undefined) return; - this.sessionLifecycleAttached = true; this._register( - lifecycle.onWillCreateSession((event) => { - if (event.readSeed(ISessionContext).workspaceId !== this.workspaceId) return; + sessionLifecycle.onWillCreateSession((event) => { const servers = event.readSeed(ISessionEphemeralMcpServers); if (Object.keys(servers).length === 0) return; const overlay = this.sessionOverlay(servers, { @@ -101,6 +127,9 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ }); }), ); + this.ready = this.initialize().catch((error: unknown) => { + this.log.error('mcp initial load failed', { error }); + }); } connectionManager(): McpConnectionManager { @@ -124,10 +153,6 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ log: this.log, oauthService: this.oauthService, stdioCwd: opts?.stdioCwd ?? this.stdioCwd, - runtimeResolver: this.runtimeResolver, - workspaceId: this.workspaceId, - runtimeId: 'local', - requireStdioRuntimeId: true, resolveDefaultTimeouts: () => this.mcpConfig.tunables(), resolveClientName: this.resolveClientName, }); @@ -136,7 +161,6 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ .catch((error: unknown) => { this.log.error('session mcp overlay initial load failed', { error }); }); - const unsubscribeOAuth = this.oauthEventSubscription(sessionManager); const view = new MergedMcpConnectionView( this.manager, sessionManager, @@ -148,104 +172,41 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ _serviceBrand: undefined, ready, connectionManager: view, + // The baseline's lazy window tracks only the workspace manager's + // initial load: freezing on the combined `ready` would keep it open + // while a slow ephemeral server connects, and a workspace server + // added in that window (plugin install, config edit) would leak into + // the live session through the merged view. Overlay names are known + // at construction, so they need no window at all. isBaselineServer: this.sessionBaseline(this.manager, this.ready, Object.keys(servers)), }, - shutdown: () => { - unsubscribeOAuth(); - return sessionManager.shutdown(); - }, + shutdown: () => sessionManager.shutdown(), }; } - private oauthEventSubscription(manager: McpConnectionManager): () => void { - return this.oauthService.onEvent((event) => { - void this.handleMcpOAuthEvent(manager, event).catch((error: unknown) => { - this.log.warn(`mcp oauth event handling failed: ${String(error)}`); - }); - }); - } - - private async handleMcpOAuthEvent( - manager: McpConnectionManager, - event: McpOAuthEvent, - ): Promise { - if (event.type === 'tokens-invalidated' && event.scope !== 'tokens' && event.scope !== 'all') { - return; - } - const entry = manager.get(event.serverName); - if (entry === undefined) return; - const serverUrl = manager.getRemoteServerUrl(event.serverName); - if (serverUrl === undefined || canonicalMcpOAuthResource(serverUrl) !== event.serverUrl) return; - if (event.type === 'tokens-invalidated') { - this.oauthService.forgetProvider(event.serverName, event.serverUrl); - } - if (entry.status === 'disabled' || entry.status === 'removed') return; - if (entry.status === 'pending') { - await new Promise((resolve, reject) => { - let unsubscribe = (): void => {}; - let settled = false; - const reconnect = (next: McpServerEntry | undefined): void => { - if (settled) return; - if (next !== undefined && (next.name !== event.serverName || next.status === 'pending')) { - return; - } - settled = true; - unsubscribe(); - if (next === undefined || next.status === 'disabled' || next.status === 'removed') { - resolve(); - return; - } - void manager.reconnectAfterCurrent(event.serverName).then(resolve, reject); - }; - unsubscribe = manager.onStatusChange(reconnect); - if (settled) unsubscribe(); - else reconnect(manager.get(event.serverName)); - }); - return; - } - if ( - event.type === 'tokens-saved' && - entry.status !== 'needs-auth' && - entry.status !== 'failed' - ) { - return; - } - if (event.type === 'refresh-failed' && entry.status !== 'connected') return; - await manager.reconnectAndJoin(event.serverName); - } - private sessionBaseline( view: McpConnectionView, ready: Promise, extra?: readonly string[], ): (name: string) => boolean { - let baseline: Set | undefined; + const baseline = new Set(extra); + for (const entry of view.list()) { + baseline.add(entry.name); + } let frozen = false; - const snapshot = (): Set => { - if (baseline === undefined) { - baseline = new Set(extra); - for (const entry of view.list()) { - baseline.add(entry.name); - } - } - return baseline; - }; void ready.then( () => { - snapshot(); frozen = true; }, () => { - snapshot(); frozen = true; }, ); return (name) => { - const names = snapshot(); - if (names.has(name)) return true; + if (baseline.has(name)) return true; if (frozen) return false; if (view.get(name) === undefined) return false; - names.add(name); + baseline.add(name); return true; }; } @@ -265,8 +226,8 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ this.trackMcpInitialLoad(); } - private scheduleApply(change: McpServersChange): Promise { - return this.ready + private scheduleApply(change: McpServersChange): void { + void this.ready .then(() => this.mutate(() => this.apply(change))) .catch((error) => { this.log.warn(`mcp server change apply failed: ${String(error)}`); @@ -304,3 +265,11 @@ export class WorkspaceMcpService extends Disposable implements IWorkspaceMcpServ } } } + +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceMcpService, + WorkspaceMcpService, + ScopeActivation.OnScopeCreated, + 'workspaceMcp', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceMcpConfig/internal/config-loader.ts b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/internal/config-loader.ts new file mode 100644 index 000000000..2e0106587 --- /dev/null +++ b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/internal/config-loader.ts @@ -0,0 +1,142 @@ +/** + * `workspaceMcpConfig` domain — MCP JSON config discovery and loading. + * + * Resolves the three MCP config files for a cwd (user `mcp.json` under the + * kimi home, project-root `.mcp.json` — the root discovered through the + * `git` domain's work-tree probe — and `.kimi-code/mcp.json` under the cwd) + * and loads them with user < project-root < project precedence, normalizing + * relative stdio `cwd` entries against the project-root file's directory. + * `includeProject: false` skips the two project-level files and loads the + * user file only — the workspace-trust gate: the project files ship with + * the checkout, so an untrusted workspace must never see them. All + * filesystem access goes through the os `IHostFileSystem`, supplied by + * the caller. Pure functions — no scoped state. + */ + +import { dirname, isAbsolute, join, normalize, resolve } from 'pathe'; + +import { findGitWorkTree } from '#/app/git/workTree'; +import { resolveKimiHome } from '#/app/bootstrap/bootstrap'; +import { OsFsErrors, HostFsError } from '#/os/interface/hostFsErrors'; +import type { IHostFileSystem } from '#/os/interface/hostFileSystem'; +import { McpServerConfigSchema, type McpServerConfig } from '#/mcpCore/config-schema'; +import { ErrorCodes, Error2 } from '#/errors'; +import { z } from 'zod'; + +const McpJsonFileSchema = z.object({ + mcpServers: z.record(z.string(), McpServerConfigSchema).default({}), +}); + +export interface McpJsonPaths { + readonly user: string; + readonly projectRoot: string; + readonly project: string; +} + +export interface ResolveMcpJsonPathsInput { + readonly fs: IHostFileSystem; + readonly cwd: string; + readonly homeDir?: string; +} + +export async function resolveMcpJsonPaths(input: ResolveMcpJsonPathsInput): Promise { + const start = normalize(input.cwd); + const projectRoot = (await findGitWorkTree(input.fs, start))?.root ?? start; + + return { + user: join(resolveKimiHome(input.homeDir), 'mcp.json'), + projectRoot: join(projectRoot, '.mcp.json'), + project: join(input.cwd, '.kimi-code', 'mcp.json'), + }; +} + +export interface LoadMcpServersInput { + readonly fs: IHostFileSystem; + readonly cwd: string; + readonly homeDir?: string; + readonly includeProject?: boolean; +} + +export async function loadMcpServers( + input: LoadMcpServersInput, +): Promise> { + const paths = await resolveMcpJsonPaths(input); + if (input.includeProject === false) { + return readMcpJson(input.fs, paths.user); + } + const [user, projectRoot, project] = await Promise.all([ + readMcpJson(input.fs, paths.user), + readMcpJson(input.fs, paths.projectRoot, { stdioCwdBase: dirname(paths.projectRoot) }), + readMcpJson(input.fs, paths.project), + ]); + return { ...user, ...projectRoot, ...project }; +} + +interface ReadMcpJsonOptions { + readonly stdioCwdBase?: string; +} + +async function readMcpJson( + fs: IHostFileSystem, + filePath: string, + options: ReadMcpJsonOptions = {}, +): Promise> { + let text: string; + try { + text = await fs.readText(filePath); + } catch (error: unknown) { + if (isFileNotFound(error)) return {}; + throw new Error2(ErrorCodes.CONFIG_INVALID, `Failed to read ${filePath}: ${describeError(error)}`, { + cause: error, + }); + } + + if (text.trim().length === 0) return {}; + + let data: unknown; + try { + data = JSON.parse(text); + } catch (error: unknown) { + throw new Error2(ErrorCodes.CONFIG_INVALID, `Invalid JSON in ${filePath}: ${describeError(error)}`, { + cause: error, + }); + } + + try { + return normalizeMcpServers(McpJsonFileSchema.parse(data).mcpServers, options); + } catch (error: unknown) { + throw new Error2(ErrorCodes.CONFIG_INVALID, `Invalid MCP server config in ${filePath}: ${describeError(error)}`, { + cause: error, + }); + } +} + +function normalizeMcpServers( + servers: Record, + options: ReadMcpJsonOptions, +): Record { + const stdioCwdBase = options.stdioCwdBase; + if (stdioCwdBase === undefined) return servers; + + return Object.fromEntries( + Object.entries(servers).map(([name, config]) => [name, normalizeStdioCwd(config, stdioCwdBase)]), + ); +} + +function normalizeStdioCwd(config: McpServerConfig, cwdBase: string): McpServerConfig { + if (config.transport !== 'stdio') return config; + const cwd = config.cwd === undefined ? cwdBase : resolvePath(cwdBase, config.cwd); + return { ...config, cwd }; +} + +function resolvePath(base: string, value: string): string { + return isAbsolute(value) ? normalize(value) : resolve(base, value); +} + +function isFileNotFound(error: unknown): boolean { + return error instanceof HostFsError && error.code === OsFsErrors.codes.OS_FS_NOT_FOUND; +} + +function describeError(error: unknown): string { + return error instanceof Error ? error.message : String(error); +} diff --git a/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfig.ts b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfig.ts index 783a4c7f3..6098a26c3 100644 --- a/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfig.ts +++ b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfig.ts @@ -1,5 +1,26 @@ +/** + * `workspaceMcpConfig` domain — Workspace-scoped MCP server-config owner + * contract. + * + * Defines `IWorkspaceMcpConfigService`, the single source of truth for "which + * MCP servers should this workspace run": it resolves the MCP config files + * (user `mcp.json`, project-root `.mcp.json`, `.kimi-code/mcp.json`) and the + * enabled plugins' contributions — on a name collision the file config wins — + * with the two project-level files gated by `workspaceTrust` (an untrusted + * workspace gets the user file and plugin contributions only), then tracks + * both sources (fs watch on the config files, + * `plugins.onDidReload`) and publishes the reconciled effective set as a + * snapshot plus already-diffed change events. Consumers never read config + * files, the plugin registry, or the `[mcp]` config section themselves: the + * global timeout preferences are exposed here as {@link tunables} too, so the + * connection side has exactly one configuration dependency. The domain holds + * no connection state and never talks to an MCP server; writing config files + * stays out of the engine. Bound at Workspace scope. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; -import type { Event, IWaitUntil } from '#/_base/event'; +import type { Event } from '#/_base/event'; + import type { McpServerConfig } from '#/mcpCore/config-schema'; export interface McpServersChange { @@ -7,8 +28,6 @@ export interface McpServersChange { readonly remove: readonly string[]; } -export type McpServersChangeEvent = McpServersChange & IWaitUntil; - export interface McpTunables { readonly startupTimeoutMs?: number; readonly toolTimeoutMs?: number; @@ -23,7 +42,7 @@ export interface IWorkspaceMcpConfigService { tunables(): McpTunables; - readonly onDidChange: Event; + readonly onDidChange: Event; } export const IWorkspaceMcpConfigService: ServiceIdentifier = diff --git a/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfigService.ts b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfigService.ts index 706f80e05..6a26807cc 100644 --- a/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfigService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceMcpConfig/workspaceMcpConfigService.ts @@ -1,30 +1,57 @@ -import { dirname } from 'pathe'; +/** + * `workspaceMcpConfig` domain — `IWorkspaceMcpConfigService` + * implementation. + * + * Resolves the handler's effective MCP server set from exactly two sources — + * the MCP config files (`resolveMcpJsonPaths`: user `mcp.json`, project-root + * `.mcp.json`, `.kimi-code/mcp.json` — read through the os `hostFs`) and the + * enabled plugins; on a name collision the file config wins, and when one + * source's server vanishes the same-named entry from the other source takes + * over. The two project-level files are gated by `workspaceTrust`: while the + * workspace is untrusted they are skipped (the user file and plugin + * contributions still load), and a trust flip triggers the same reload path + * as a file edit, so trusting connects the project servers and untrusting + * drops them. The config files are watched (the user file directly, the + * project root recursively pruned to the two project candidates) and plugin + * contributions follow `plugins.onDidReload`; every re-resolve recomputes the + * merged view and publishes the fingerprint diff through `onDidChange`, so a + * config edit or a plugin installed, enabled or reloaded AFTER the handler + * materialized still reaches the connection side. Reloads are debounced and + * serialized on a mutation tail; an outright initial-load or reload failure + * is logged, leaving the last published snapshot in place. The initial + * resolve waits for `config.ready` so the file/plugin read and the `[mcp]` + * section read are deterministic. Bound at Workspace scope. + */ import { Disposable } from '#/_base/di/lifecycle'; -import { AsyncEmitter } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { Emitter } from '#/_base/event'; import { ILogService } from '#/_base/log/log'; -import { subtreeWatchFilter } from '#/_base/utils/paths'; import { TimeoutTimer } from '#/_base/utils/timer'; +import { subtreeWatchFilter } from '#/_base/utils/paths'; +import { dirname } from 'pathe'; + +import type { McpServerConfig } from '#/mcpCore/config-schema'; +import { MCP_SECTION, type McpSection } from '#/app/mcpConfig/configSection'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; -import { loadMcpServers, resolveMcpJsonPaths } from '#/app/mcpConfig/configLoader'; -import { MCP_SECTION, type McpSection } from '#/app/mcpConfig/configSection'; -import { IMcpConfigStore } from '#/app/mcpConfig/configStore'; import { IPluginService } from '#/app/plugin/plugin'; -import type { McpServerConfig } from '#/mcpCore/config-schema'; import { IHostFileSystem } from '#/os/interface/hostFileSystem'; import { IHostFsWatchService } from '#/os/interface/hostFsWatch'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; import { IWorkspaceTrust } from '#/workspace/workspaceTrust/workspaceTrust'; +import { loadMcpServers, resolveMcpJsonPaths } from './internal/config-loader'; import { IWorkspaceMcpConfigService, - type McpServersChangeEvent, + type McpServersChange, type McpTunables, } from './workspaceMcpConfig'; const WATCH_DEBOUNCE_MS = 200; +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceMcpConfigService { declare readonly _serviceBrand: undefined; @@ -34,7 +61,7 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM private pluginServers = new Map(); private current: Readonly> = {}; private readonly watchDebounce = this._register(new TimeoutTimer()); - private readonly changeEmitter = this._register(new AsyncEmitter()); + private readonly changeEmitter = this._register(new Emitter()); readonly onDidChange = this.changeEmitter.event; constructor( @@ -46,19 +73,16 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM @IHostFsWatchService private readonly fsWatch: IHostFsWatchService, @IHostFileSystem private readonly fs: IHostFileSystem, @IWorkspaceTrust private readonly trust: IWorkspaceTrust, - @IMcpConfigStore mcpConfigStore: IMcpConfigStore, ) { super(); this.ready = this.initialize().catch((error: unknown) => { this.log.error('mcp config initial load failed', { error }); }); this._register( - this.plugins.onDidReload((event) => { - event.waitUntil( - this.reloadPluginServers().catch((error) => { - this.log.warn(`mcp plugin reload failed: ${String(error)}`); - }), - ); + this.plugins.onDidReload(() => { + void this.reloadPluginServers().catch((error) => { + this.log.warn(`mcp plugin reload failed: ${String(error)}`); + }); }), ); this._register( @@ -68,15 +92,6 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM }); }), ); - this._register( - mcpConfigStore.onDidWrite((event) => { - event.waitUntil( - this.reloadFileServers().catch((error) => { - this.log.warn(`mcp config reload after management write failed: ${String(error)}`); - }), - ); - }), - ); void this.watchConfigFiles(); } @@ -168,7 +183,7 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM includeProject: this.trust.isTrusted(), }); this.fileServers = new Map(Object.entries(fresh)); - await this.publishIfChanged(); + this.publishIfChanged(); }); } @@ -177,13 +192,13 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM await this.mutate(async () => { const fresh = await this.plugins.enabledMcpServers(); this.pluginServers = new Map(Object.entries(fresh)); - await this.publishIfChanged(); + this.publishIfChanged(); }); } - private async publishIfChanged(): Promise { + private publishIfChanged(): void { const next = this.merged(); - const upsert: Record = Object.create(null); + const upsert: Record = {}; const remove: string[] = []; for (const [name, config] of Object.entries(next)) { const previous = this.current[name]; @@ -196,12 +211,10 @@ export class WorkspaceMcpConfigService extends Disposable implements IWorkspaceM } this.current = next; if (Object.keys(upsert).length === 0 && remove.length === 0) return; - await this.changeEmitter.fireAsync({ upsert, remove }, NO_ABORT); + this.changeEmitter.fire({ upsert, remove }); } } -const NO_ABORT = new AbortController().signal; - function fingerprintConfig(config: McpServerConfig): string { return JSON.stringify(sortKeysDeep(config)); } @@ -217,3 +230,11 @@ function sortKeysDeep(value: unknown): unknown { } return value; } + +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceMcpConfigService, + WorkspaceMcpConfigService, + ScopeActivation.OnScopeCreated, + 'workspaceMcpConfig', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceProcess/workspaceProcessRunnerService.ts b/packages/agent-core-v2/src/workspace/workspaceProcess/workspaceProcessRunnerService.ts new file mode 100644 index 000000000..7407f8ebb --- /dev/null +++ b/packages/agent-core-v2/src/workspace/workspaceProcess/workspaceProcessRunnerService.ts @@ -0,0 +1,66 @@ +/** + * `workspaceProcess` domain — `ISessionProcessRunner` implementation. + * + * Resolves the default cwd from the handler's `IWorkspaceContext` (chdir is + * gone, so the workspace root is the one fixed default) and delegates the + * actual host spawn to the App-scope `IHostProcessService`. A per-call + * `options.cwd` wins over the handler root. A per-call `options.env` is + * overlaid onto `process.env` and passed as the child's complete env bag (the + * host replaces the child env with what we pass); when `options.env` is + * omitted we pass `undefined` so the child inherits `process.env` verbatim. + * + * Bound at Workspace scope — one runner per handler, shared by every session + * of the workspace. + */ + +import { LifecycleScope } from '#/app/scopes'; + +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { BugIndicatingError } from '#/errors'; +import { IHostProcessService } from '#/os/interface/hostProcess'; +import { type IProcess, ISessionProcessRunner, type ProcessExecOptions } from '#/session/process/processRunner'; +import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; + +export class WorkspaceProcessRunnerService implements ISessionProcessRunner { + declare readonly _serviceBrand: undefined; + + constructor( + @IWorkspaceContext private readonly ctx: IWorkspaceContext, + @IHostProcessService private readonly hostProcess: IHostProcessService, + ) {} + + async exec(args: readonly string[], options?: ProcessExecOptions): Promise { + const command = args[0]; + if (command === undefined) { + throw new BugIndicatingError( + 'WorkspaceProcessRunnerService.exec(): at least one argument (the command to run) is required.', + ); + } + const restArgs = args.slice(1); + + const cwd = options?.cwd ?? this.ctx.cwd; + const env = this._buildExecEnv(options?.env); + + return this.hostProcess.spawn(command, restArgs, { cwd, env }); + } + + private _buildExecEnv( + invocationEnv: Record | undefined, + ): Record | undefined { + if (invocationEnv === undefined) { + return undefined; + } + return { + ...(process.env as Record), + ...invocationEnv, + }; + } +} + +registerScopedService( + LifecycleScope.Workspace, + ISessionProcessRunner, + WorkspaceProcessRunnerService, + ScopeActivation.OnScopeCreated, + 'workspaceProcess', +); diff --git a/packages/agent-core-v2/src/features/skill/workspace/explicitFileSkillSource.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/explicitFileSkillSource.ts similarity index 58% rename from packages/agent-core-v2/src/features/skill/workspace/explicitFileSkillSource.ts rename to packages/agent-core-v2/src/workspace/workspaceSkillCatalog/explicitFileSkillSource.ts index 353c74e0c..e3ef7ce08 100644 --- a/packages/agent-core-v2/src/features/skill/workspace/explicitFileSkillSource.ts +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/explicitFileSkillSource.ts @@ -1,12 +1,25 @@ +/** + * `workspaceSkillCatalog` domain — explicit `ISkillSource` producer. + * + * Mirrors v1 SDK `skillDirs`: when the host invocation args provide + * `skillDirs`, this source contributes those directories as the user source, + * resolving relative paths against the workspace root. When no explicit dirs + * are configured, it yields nothing so default user / project discovery + * remains active. Bound at Workspace scope so every session of the handler + * shares one scan. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; -import { configuredRoots } from '#/features/skill/catalog/skillRoots'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; +import { configuredRoots } from '#/app/skillCatalog/skillRoots'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; import { SKILL_SOURCE_PRIORITY, type ISkillSource, type SkillContribution, -} from '#/features/skill/catalog/skillSource'; +} from '#/app/skillCatalog/skillSource'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; export interface IExplicitFileSkillSource extends ISkillSource { @@ -39,3 +52,10 @@ export class ExplicitFileSkillSource implements IExplicitFileSkillSource { } } +registerScopedService( + LifecycleScope.Workspace, + IExplicitFileSkillSource, + ExplicitFileSkillSource, + ScopeActivation.OnScopeCreated, + 'workspaceSkillCatalog', +); diff --git a/packages/agent-core-v2/src/features/skill/workspace/extraFileSkillSource.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/extraFileSkillSource.ts similarity index 62% rename from packages/agent-core-v2/src/features/skill/workspace/extraFileSkillSource.ts rename to packages/agent-core-v2/src/workspace/workspaceSkillCatalog/extraFileSkillSource.ts index 064ed893d..b3d30f68c 100644 --- a/packages/agent-core-v2/src/features/skill/workspace/extraFileSkillSource.ts +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/extraFileSkillSource.ts @@ -1,19 +1,33 @@ +/** + * `workspaceSkillCatalog` domain — extra `ISkillSource` producer. + * + * Discovers user-configured extra skill directories (`extraSkillDirs`) through + * `ISkillDiscovery`, contributing them at priority 10 (above plugin / builtin, + * below user / workspace). Relative paths resolve against the workspace root; + * `~` and `~/...` resolve against the bootstrap home dir. Re-fires + * `onDidChange` when the `extraSkillDirs` config section changes so the + * catalog re-scans THIS source only. Bound at Workspace scope so every + * session of the handler shares one scan. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable } from '#/_base/di/lifecycle'; import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; import { EXTRA_SKILL_DIRS_SECTION, type ExtraSkillDirsConfig, -} from '#/features/skill/catalog/configSection'; -import { configuredRoots } from '#/features/skill/catalog/skillRoots'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; +} from '#/app/skillCatalog/configSection'; +import { configuredRoots } from '#/app/skillCatalog/skillRoots'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; import { SKILL_SOURCE_PRIORITY, type ISkillSource, type SkillContribution, -} from '#/features/skill/catalog/skillSource'; +} from '#/app/skillCatalog/skillSource'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; export interface IExtraFileSkillSource extends ISkillSource { @@ -23,6 +37,7 @@ export interface IExtraFileSkillSource extends ISkillSource { export const IExtraFileSkillSource: ServiceIdentifier = createDecorator('extraFileSkillSource'); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class ExtraFileSkillSource extends Disposable implements IExtraFileSkillSource { declare readonly _serviceBrand: undefined; @@ -54,3 +69,10 @@ export class ExtraFileSkillSource extends Disposable implements IExtraFileSkillS } } +registerScopedService( + LifecycleScope.Workspace, + IExtraFileSkillSource, + ExtraFileSkillSource, + ScopeActivation.OnScopeCreated, + 'workspaceSkillCatalog', +); diff --git a/packages/agent-core-v2/src/features/skill/workspace/pluginSkillSource.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/pluginSkillSource.ts similarity index 57% rename from packages/agent-core-v2/src/features/skill/workspace/pluginSkillSource.ts rename to packages/agent-core-v2/src/workspace/workspaceSkillCatalog/pluginSkillSource.ts index a20d2747b..82092fe46 100644 --- a/packages/agent-core-v2/src/features/skill/workspace/pluginSkillSource.ts +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/pluginSkillSource.ts @@ -1,12 +1,25 @@ +/** + * `workspaceSkillCatalog` domain — plugin `ISkillSource` producer. + * + * Discovers skills contributed by enabled plugins through `ISkillDiscovery` + * (roots from `plugin.pluginSkillRoots()`), contributing them at priority 5 + * (above builtin, below extra / user / workspace, so project, user and extra + * skills win name collisions). Re-emits `plugin.onDidReload` as `onDidChange` + * so the catalog re-pulls plugin skills when plugins reload. Bound at + * Workspace scope so every session of the handler shares one scan. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; import { PLUGIN_SKILL_SOURCE_ID, SKILL_SOURCE_PRIORITY, type ISkillSource, type SkillContribution, -} from '#/features/skill/catalog/skillSource'; +} from '#/app/skillCatalog/skillSource'; import { IPluginService } from '#/app/plugin/plugin'; export interface IPluginSkillSource extends ISkillSource { @@ -40,3 +53,10 @@ export class PluginSkillSource implements IPluginSkillSource { } } +registerScopedService( + LifecycleScope.Workspace, + IPluginSkillSource, + PluginSkillSource, + ScopeActivation.OnScopeCreated, + 'workspaceSkillCatalog', +); diff --git a/packages/agent-core-v2/src/features/skill/workspace/rootFileSkillSource.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/rootFileSkillSource.ts similarity index 80% rename from packages/agent-core-v2/src/features/skill/workspace/rootFileSkillSource.ts rename to packages/agent-core-v2/src/workspace/workspaceSkillCatalog/rootFileSkillSource.ts index c36aaf6ad..725ef367c 100644 --- a/packages/agent-core-v2/src/features/skill/workspace/rootFileSkillSource.ts +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/rootFileSkillSource.ts @@ -1,6 +1,19 @@ +/** + * `workspaceSkillCatalog` domain — workspace-root `ISkillSource` + * producer. + * + * Discovers project skills from the handler's workspace root + * (`workspaceContext.cwd`) through `ISkillDiscovery`, contributing them at + * priority 30. Watches project skill-root candidates through `hostFsWatch` + * and emits debounced invalidations for source reloads. Bound at Workspace + * scope so every session of the handler shares one scan. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import { Disposable, DisposableStore } from '#/_base/di/lifecycle'; import { Emitter, type Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { TimeoutTimer } from '#/_base/utils/timer'; import { subtreeWatchFilter } from '#/_base/utils/paths'; import { IConfigService } from '#/app/config/config'; @@ -8,14 +21,14 @@ import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { MERGE_ALL_AVAILABLE_SKILLS_SECTION, type MergeAllAvailableSkillsConfig, -} from '#/features/skill/catalog/configSection'; -import { ISkillDiscovery } from '#/features/skill/catalog/skillDiscovery'; -import { projectRoots, projectSkillRootCandidates } from '#/features/skill/catalog/skillRoots'; +} from '#/app/skillCatalog/configSection'; +import { ISkillDiscovery } from '#/app/skillCatalog/skillDiscovery'; +import { projectRoots, projectSkillRootCandidates } from '#/app/skillCatalog/skillRoots'; import { SKILL_SOURCE_PRIORITY, type ISkillSource, type SkillContribution, -} from '#/features/skill/catalog/skillSource'; +} from '#/app/skillCatalog/skillSource'; import { IHostFsWatchService } from '#/os/interface/hostFsWatch'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; @@ -30,6 +43,7 @@ export interface IWorkspaceRootSkillSource extends ISkillSource { export const IWorkspaceRootSkillSource: ServiceIdentifier = createDecorator('workspaceRootSkillSource'); +// NOTE: stays Disposable — its own 'config' collides with the Fiber export class WorkspaceRootSkillSource extends Disposable implements IWorkspaceRootSkillSource { declare readonly _serviceBrand: undefined; @@ -113,3 +127,10 @@ export class WorkspaceRootSkillSource extends Disposable implements IWorkspaceRo } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceRootSkillSource, + WorkspaceRootSkillSource, + ScopeActivation.OnScopeCreated, + 'workspaceSkillCatalog', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalog.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalog.ts new file mode 100644 index 000000000..1ef214a36 --- /dev/null +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalog.ts @@ -0,0 +1,33 @@ +/** + * `workspaceSkillCatalog` domain — Workspace-scoped skill catalog + * contract. + * + * Defines `IWorkspaceSkillCatalog`, the handler-level owner of skill + * discovery and merging: at handler materialization it loads every source + * (builtin / user / explicit / extra / workspace-root / plugin) and merges by + * priority; afterwards single sources refresh incrementally (fs watch on the + * project skill dirs, config section changes, plugin reloads) — never a full + * rescan. `sessionData()` projects the merged view into the + * `ISessionSkillCatalogData` seed every Session scope of this handler + * receives. Bound at Workspace scope. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { Event } from '#/_base/event'; + +import type { SkillCatalog } from '#/app/skillCatalog/types'; +import type { ISessionSkillCatalogData } from '#/session/sessionSkillCatalog/skillCatalogData'; + +export interface IWorkspaceSkillCatalog { + readonly _serviceBrand: undefined; + + readonly ready: Promise; + readonly catalog: SkillCatalog; + readonly onDidChange: Event; + load(): Promise; + reload(): Promise; + sessionData(): ISessionSkillCatalogData; +} + +export const IWorkspaceSkillCatalog: ServiceIdentifier = + createDecorator('workspaceSkillCatalog'); diff --git a/packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalogService.ts b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts similarity index 69% rename from packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalogService.ts rename to packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts index a1ce0f5a5..f60b19fbe 100644 --- a/packages/agent-core-v2/src/features/skill/workspace/workspaceSkillCatalogService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceSkillCatalog/workspaceSkillCatalogService.ts @@ -1,12 +1,30 @@ -import { Disposable } from '#/_base/di/lifecycle'; +/** + * `workspaceSkillCatalog` domain — `IWorkspaceSkillCatalog` + * implementation. + * + * Merges builtin, user, explicit, extra, workspace-root, and plugin skill + * sources by priority ONCE per handler, serializing refreshes for each + * source; afterwards a source's `onDidChange` (fs watch / config section / + * plugin reload) re-scans that source alone and re-fires the merged change + * event — no full rescan ever leaves the build-time load. The merged view is + * shared by every session of the handler through the + * `ISessionSkillCatalogData` seed (`sessionData()`), a live read view over + * this service. The plain-data state (`contributions`, `merged`) is + * registered into `workspaceState` (`IWorkspaceStateService`) and + * read/written through it. Bound at Workspace scope. + */ + +import { Service } from '#/_base/di/service'; import { Emitter, type Event } from '#/_base/event'; -import { defineState } from '#/state/state'; -import { IBuiltinSkillSource } from '#/features/skill/catalog/builtinSkillSource'; -import { InMemorySkillCatalog } from '#/features/skill/catalog/registry'; -import type { ISkillSource, SkillContribution } from '#/features/skill/catalog/skillSource'; -import type { SkillCatalog } from '#/features/skill/catalog/types'; -import { IUserFileSkillSource } from '#/features/skill/catalog/userFileSkillSource'; -import type { ISessionSkillCatalogData } from '#/features/skill/session/skillCatalogData'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import { defineState } from '#/_base/state/stateRegistry'; +import { IBuiltinSkillSource } from '#/app/skillCatalog/builtinSkillSource'; +import { InMemorySkillCatalog } from '#/app/skillCatalog/registry'; +import type { ISkillSource, SkillContribution } from '#/app/skillCatalog/skillSource'; +import type { SkillCatalog } from '#/app/skillCatalog/types'; +import { IUserFileSkillSource } from '#/app/skillCatalog/userFileSkillSource'; +import type { ISessionSkillCatalogData } from '#/session/sessionSkillCatalog/skillCatalogData'; import { IWorkspaceStateService } from '#/workspace/state/workspaceState'; import { IExplicitFileSkillSource } from './explicitFileSkillSource'; @@ -23,7 +41,7 @@ export const workspaceSkillCatalogMergedKey = defineState( () => new InMemorySkillCatalog(), ); -export class WorkspaceSkillCatalogService extends Disposable implements IWorkspaceSkillCatalog { +export class WorkspaceSkillCatalogService extends Service implements IWorkspaceSkillCatalog { declare readonly _serviceBrand: undefined; private readonly sources: readonly ISkillSource[]; @@ -42,8 +60,8 @@ export class WorkspaceSkillCatalogService extends Disposable implements IWorkspa @IWorkspaceStateService private readonly states: IWorkspaceStateService, ) { super(); - this.states.contributeState(workspaceSkillCatalogContributionsKey); - this.states.contributeState(workspaceSkillCatalogMergedKey); + this.states.register(workspaceSkillCatalogContributionsKey); + this.states.register(workspaceSkillCatalogMergedKey); this.sources = [builtin, user, explicit, extra, workspace, plugin].toSorted( (a, b) => a.priority - b.priority, ); @@ -82,10 +100,6 @@ export class WorkspaceSkillCatalogService extends Disposable implements IWorkspa this.onDidChangeEmitter.fire('catalog'); } - async reloadSources(ids: readonly string[]): Promise { - await Promise.all(ids.map((id) => this.reloadSource(id))); - } - async load(): Promise { await this.ready; } @@ -147,3 +161,10 @@ export class WorkspaceSkillCatalogService extends Disposable implements IWorkspa } } +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceSkillCatalog, + WorkspaceSkillCatalogService, + ScopeActivation.OnScopeCreated, + 'workspaceSkillCatalog', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicy.ts b/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicy.ts new file mode 100644 index 000000000..54bafd7c4 --- /dev/null +++ b/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicy.ts @@ -0,0 +1,30 @@ +/** + * `workspaceToolPolicy` domain — os-level tool enable/disable contract. + * + * Defines the `IWorkspaceToolPolicy`, the Workspace-scope owner of the + * tool-veto set that outranks every Agent-side policy layer (profile × + * `[tools]` config × session denylist): a tool the workspace disables never + * activates and can never execute, no matter what the upper layers allow. + * The set derives from the handler's runtime capabilities — the + * `IWorkspaceContext.osBackendId` keying pair records which os backend the + * handler binds; a runtime whose backend lacks a capability (e.g. no PTY) + * contributes the dependent tool names here. The set reaches every session + * of the handler through the `ISessionToolPolicyGate` seed + * (`sessionGate()`), a live read view over this service. Workspace-scoped. + */ + +import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; +import type { Event } from '#/_base/event'; +import type { ISessionToolPolicyGate } from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; + +export interface IWorkspaceToolPolicy { + readonly _serviceBrand: undefined; + + disabledTools(): readonly string[]; + readonly onDidChange: Event; + + sessionGate(): ISessionToolPolicyGate; +} + +export const IWorkspaceToolPolicy: ServiceIdentifier = + createDecorator('workspaceToolPolicy'); diff --git a/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicyService.ts b/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicyService.ts new file mode 100644 index 000000000..b84ef320c --- /dev/null +++ b/packages/agent-core-v2/src/workspace/workspaceToolPolicy/workspaceToolPolicyService.ts @@ -0,0 +1,63 @@ +/** + * `workspaceToolPolicy` domain — `IWorkspaceToolPolicy` implementation. + * + * Computes the os-level disabled-tool set from the runtime capabilities the + * handler binds (`IWorkspaceContext.osBackendId`). The local runtime carries + * the full node os backend (fs / process / PTY / watch), so it vetoes + * nothing; runtimes with a reduced os backend land their own capability + * mapping (or seed their own `IWorkspaceToolPolicy`) when they arrive. A + * workspace-level tools config does not exist yet — when one does, it joins + * the capability set here and fires `onDidChange`. Bound at Workspace scope. + */ + +import { Service } from '#/_base/di/service'; +import { Event } from '#/_base/event'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; +import type { ISessionToolPolicyGate } from '#/session/sessionToolPolicyGate/sessionToolPolicyGate'; +import { + IWorkspaceContext, + LOCAL_OS_BACKEND_ID, +} from '#/workspace/workspaceContext/workspaceContext'; + +import { IWorkspaceToolPolicy } from './workspaceToolPolicy'; + +export function computeCapabilityDisabledTools(osBackendId: string): readonly string[] { + if (osBackendId === LOCAL_OS_BACKEND_ID) return []; + return []; +} + +export class WorkspaceToolPolicyService extends Service implements IWorkspaceToolPolicy { + declare readonly _serviceBrand: undefined; + + private readonly disabled: readonly string[]; + readonly onDidChange = Event.None as Event; + + constructor(@IWorkspaceContext workspace: IWorkspaceContext) { + super(); + this.disabled = computeCapabilityDisabledTools(workspace.osBackendId); + } + + disabledTools(): readonly string[] { + return this.disabled; + } + + sessionGate(): ISessionToolPolicyGate { + const current = (): readonly string[] => this.disabledTools(); + return { + _serviceBrand: undefined, + onDidChange: this.onDidChange, + get disabledTools() { + return current(); + }, + }; + } +} + +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceToolPolicy, + WorkspaceToolPolicyService, + ScopeActivation.OnScopeCreated, + 'workspaceToolPolicy', +); diff --git a/packages/agent-core-v2/src/workspace/workspaceTrust/trustRecord.ts b/packages/agent-core-v2/src/workspace/workspaceTrust/trustRecord.ts deleted file mode 100644 index be6622f95..000000000 --- a/packages/agent-core-v2/src/workspace/workspaceTrust/trustRecord.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { encodeWorkDirKey } from '#/_base/utils/workdir-slug'; -import { canonicalWorkspaceRoot } from '#/_base/utils/paths'; -import type { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; - -const TRUST_SCOPE = 'workspace-trust'; - -interface TrustRecord { - readonly root: string; - readonly trustedAt: number; -} - -export async function readWorkspaceTrust( - docs: IAtomicDocumentStore, - root: string, -): Promise { - try { - const canonicalKey = trustKey(root); - if ((await docs.get(TRUST_SCOPE, canonicalKey)) !== undefined) return true; - - const legacyKey = encodeWorkDirKey(root); - if (legacyKey === canonicalKey) return false; - const legacy = await docs.get(TRUST_SCOPE, legacyKey); - if (legacy === undefined) return false; - try { - await docs.set(TRUST_SCOPE, canonicalKey, legacy); - await docs.delete(TRUST_SCOPE, legacyKey); - } catch {} - return true; - } catch { - return false; - } -} - -export function writeWorkspaceTrust( - docs: IAtomicDocumentStore, - root: string, - trustedAt: number, -): Promise { - return docs.set(TRUST_SCOPE, trustKey(root), { root, trustedAt }); -} - -export function deleteWorkspaceTrust( - docs: IAtomicDocumentStore, - root: string, -): Promise { - const canonicalKey = trustKey(root); - const legacyKey = encodeWorkDirKey(root); - return (async () => { - await docs.delete(TRUST_SCOPE, canonicalKey); - if (legacyKey !== canonicalKey) await docs.delete(TRUST_SCOPE, legacyKey); - })(); -} - -function trustKey(root: string): string { - return encodeWorkDirKey(canonicalWorkspaceRoot(root)); -} diff --git a/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrust.ts b/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrust.ts index 8f7744a75..2862b3e4f 100644 --- a/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrust.ts +++ b/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrust.ts @@ -1,3 +1,19 @@ +/** + * `workspaceTrust` domain — per-workspace trust-state contract. + * + * Defines `IWorkspaceTrust`, the Workspace-scope owner of one yes/no fact: + * has the user trusted this workspace. Trust gates everything the + * workspace's own files may ask the engine to run before those files are + * read as instructions — for example the project-level MCP config files + * (project-root `.mcp.json` and `.kimi-code/mcp.json`) are skipped while + * the workspace is untrusted, so a freshly cloned repo cannot auto-start + * MCP servers. The marker is recorded OUTSIDE the workspace so a malicious + * checkout cannot mark itself trusted, and every handler of the same root + * resolves to the same record. Trust flips only through the explicit + * `trust()` / `untrust()` calls — the engine has no interactive prompt. + * Workspace-scoped. + */ + import { createDecorator, type ServiceIdentifier } from '#/_base/di/instantiation'; import type { Event } from '#/_base/event'; diff --git a/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrustService.ts b/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrustService.ts index ed489d0c7..03f0f9aed 100644 --- a/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrustService.ts +++ b/packages/agent-core-v2/src/workspace/workspaceTrust/workspaceTrustService.ts @@ -1,23 +1,52 @@ +/** + * `workspaceTrust` domain — `IWorkspaceTrust` implementation. + * + * Persists the trust marker through the `persistence` domain's + * `IAtomicDocumentStore` under the `workspace-trust` scope, one document per + * workspace keyed by `encodeWorkDirKey(root)`, with the raw root kept in the + * value for inspection. The document's presence IS the trusted state: `trust()` + * writes it, `untrust()` deletes it. The record lives under the kimi home, + * never inside the workspace, so a checked-out tree cannot pre-trust + * itself. The flag is read once through `ready` and every later mutation + * goes through this service, so the view is in-process: another process + * flipping the same record is picked up only on restart (a `docs.watch` + * sync can join when a second writer exists). A read failure resolves to + * untrusted. The plain-data state (`trusted`) is registered into + * `workspaceState` (`IWorkspaceStateService`) and read/written through it. + * Bound at Workspace scope. + */ + import { Disposable } from '#/_base/di/lifecycle'; +import { LifecycleScope } from '#/app/scopes'; +import { ScopeActivation, registerScopedService } from '#/_base/di/scope'; import { Emitter } from '#/_base/event'; -import { defineState } from '#/state/state'; +import { defineState } from '#/_base/state/stateRegistry'; +import { encodeWorkDirKey } from '#/_base/utils/workdir-slug'; import { IAtomicDocumentStore } from '#/persistence/interface/atomicDocumentStore'; import { IWorkspaceStateService } from '#/workspace/state/workspaceState'; import { IWorkspaceContext } from '#/workspace/workspaceContext/workspaceContext'; import { IWorkspaceTrust, type WorkspaceTrustChange } from './workspaceTrust'; -import { deleteWorkspaceTrust, readWorkspaceTrust, writeWorkspaceTrust } from './trustRecord'; + +const TRUST_SCOPE = 'workspace-trust'; + +interface TrustRecord { + readonly root: string; + readonly trustedAt: number; +} export const workspaceTrustTrustedKey = defineState( 'workspaceTrust.trusted', () => false, ); +// NOTE: stays Disposable — its own 'get' collides with the Fiber export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust { declare readonly _serviceBrand: undefined; readonly ready: Promise; private readonly root: string; + private readonly storeKey: string; private readonly changeEmitter = this._register(new Emitter()); readonly onDidChange = this.changeEmitter.event; @@ -27,8 +56,9 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust @IWorkspaceStateService private readonly states: IWorkspaceStateService, ) { super(); - this.states.contributeState(workspaceTrustTrustedKey); + this.states.register(workspaceTrustTrustedKey); this.root = workspace.cwd; + this.storeKey = encodeWorkDirKey(workspace.cwd); this.ready = this.initialize(); } @@ -51,19 +81,34 @@ export class WorkspaceTrustService extends Disposable implements IWorkspaceTrust async trust(): Promise { if (this.trusted) return; - await writeWorkspaceTrust(this.docs, this.root, Date.now()); + await this.docs.set(TRUST_SCOPE, this.storeKey, { + root: this.root, + trustedAt: Date.now(), + }); this.trusted = true; this.changeEmitter.fire({ trusted: true }); } async untrust(): Promise { if (!this.trusted) return; - await deleteWorkspaceTrust(this.docs, this.root); + await this.docs.delete(TRUST_SCOPE, this.storeKey); this.trusted = false; this.changeEmitter.fire({ trusted: false }); } private async initialize(): Promise { - this.trusted = await readWorkspaceTrust(this.docs, this.root); + try { + this.trusted = (await this.docs.get(TRUST_SCOPE, this.storeKey)) !== undefined; + } catch { + this.trusted = false; + } } } + +registerScopedService( + LifecycleScope.Workspace, + IWorkspaceTrust, + WorkspaceTrustService, + ScopeActivation.OnDemand, + 'workspaceTrust', +); diff --git a/packages/agent-core-v2/test/_base/di/child.test.ts b/packages/agent-core-v2/test/_base/di/child.test.ts index 5a13c7689..efdb838eb 100644 --- a/packages/agent-core-v2/test/_base/di/child.test.ts +++ b/packages/agent-core-v2/test/_base/di/child.test.ts @@ -214,64 +214,6 @@ describe('InstantiationService.createChild', () => { expect(events).toEqual(['disposed']); }); - it('repeated disposeAsync returns the in-flight teardown promise', async () => { - const events: string[] = []; - let releaseGate!: () => void; - const ix = new InstantiationService(new ServiceCollection()); - ix.anchorKernelEntry(() => { - events.push('finalizer'); - }, 'finalizer'); - ix.anchorKernelEntry(() => { - events.push('gate-entered'); - return new Promise((resolve) => { - releaseGate = resolve; - }); - }, 'gate'); - - const first = ix.disposeAsync(); - const second = ix.disposeAsync(); - let secondSettled = false; - void second.then(() => { - secondSettled = true; - }); - await new Promise((resolve) => setTimeout(resolve, 10)); - expect(events).toEqual(['gate-entered']); - expect(secondSettled).toBe(false); - releaseGate(); - await Promise.all([first, second]); - expect(events).toEqual(['gate-entered', 'finalizer']); - }); - - it('disposeAsync awaits asynchronous child container teardown', async () => { - const events: string[] = []; - let releaseChildGate!: () => void; - const parent = new InstantiationService(new ServiceCollection()); - const child = parent.createChild(new ServiceCollection()) as InstantiationService; - child.anchorKernelEntry(() => { - events.push('child-finalizer'); - }, 'child-finalizer'); - child.anchorKernelEntry(() => { - events.push('child-gate-entered'); - return new Promise((resolve) => { - releaseChildGate = resolve; - }); - }, 'child-gate'); - parent.anchorKernelEntry(() => { - events.push('parent-finalizer'); - }, 'parent-finalizer'); - - let settled = false; - const disposal = parent.disposeAsync().then(() => { - settled = true; - }); - await new Promise((resolve) => setTimeout(resolve, 10)); - expect(events).toEqual(['child-gate-entered', 'parent-finalizer']); - expect(settled).toBe(false); - releaseChildGate(); - await disposal; - expect(events).toEqual(['child-gate-entered', 'parent-finalizer', 'child-finalizer']); - }); - it('parent dispose propagates to children', () => { const events: string[] = []; interface IParentSvc { diff --git a/packages/agent-core-v2/test/_base/di/planSample.test.ts b/packages/agent-core-v2/test/_base/di/planSample.test.ts index 732a8c35c..896a626b8 100644 --- a/packages/agent-core-v2/test/_base/di/planSample.test.ts +++ b/packages/agent-core-v2/test/_base/di/planSample.test.ts @@ -1,3 +1,10 @@ +/** + * Plan-sample acceptance test — `plan/plan-domain-plugin.manifest.ts` as the + * API acceptance standard (Phase 3 验证项), exercised against the REAL kernel + * and the REAL domain collection tokens. Each section cites the sample line + * it proves; the unload chain asserts §3's teardown order end to end. + */ + import { describe, expect, it } from 'vitest'; import { collection, type CollectionView } from '#/_base/di/collection'; @@ -11,7 +18,7 @@ import { LifecycleScope } from '#/app/scopes'; import { ConfigSectionContribution } from '#/app/config/configSectionContributions'; import { AgentProfileContribution } from '#/app/agentProfileCatalog/agentProfileContribution'; import { AgentToolContribution } from '#/agent/toolRegistry/toolContribution'; -import { EventStateContribution } from '#/state/stateContribution'; +import { WireModelContribution } from '#/wire/wireContribution'; interface IAgentPlanService { readonly _serviceBrand: undefined; @@ -64,7 +71,7 @@ describe('Plan sample (plan-domain-plugin.manifest.ts) — API acceptance', () = constructor() { super(); - this.provide(EventStateContribution, { events: [] }); + this.provide(WireModelContribution, { models: [], ops: [] }); this.provide(IAgentPlanService, AgentPlanService, { activation: ScopeActivation.OnScopeCreated, }); @@ -112,7 +119,7 @@ describe('Plan sample (plan-domain-plugin.manifest.ts) — API acceptance', () = const toolView = (agent.instantiation as InstantiationService).fiberHost.collectionView(AgentToolContribution); expect(toolView.items).toHaveLength(1); expect(toolView.items[0]!.options.name).toBe('EnterPlanMode'); - const wireView = (agent.instantiation as InstantiationService).fiberHost.collectionView(EventStateContribution); + const wireView = (agent.instantiation as InstantiationService).fiberHost.collectionView(WireModelContribution); expect(wireView.items).toHaveLength(1); const tool = agent.instantiation.createInstance(EnterPlanModeTool); @@ -121,7 +128,7 @@ describe('Plan sample (plan-domain-plugin.manifest.ts) — API acceptance', () = featureHandle.dispose(); await app.instantiation.cascade.whenIdle(); await new Promise((resolve) => setTimeout(resolve, 0)); - expect((agent.instantiation as InstantiationService).fiberHost.collectionView(EventStateContribution).items).toHaveLength(0); + expect((agent.instantiation as InstantiationService).fiberHost.collectionView(WireModelContribution).items).toHaveLength(0); expect(toolView.items).toHaveLength(0); expect(seen).toEqual(['config:+defaultPlanMode', 'config:-defaultPlanMode']); expect(log).toEqual(['agent feature up']); diff --git a/packages/agent-core-v2/test/_base/di/scoped-register.test.ts b/packages/agent-core-v2/test/_base/di/scoped-register.test.ts index 8ffc03583..810954e0d 100644 --- a/packages/agent-core-v2/test/_base/di/scoped-register.test.ts +++ b/packages/agent-core-v2/test/_base/di/scoped-register.test.ts @@ -5,9 +5,7 @@ import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, _clearScopedRegistryForTests, - createAppScope, getScopedServiceDescriptors, - overrideScopedService, registerScopedService, } from '#/_base/di/scope'; @@ -117,66 +115,4 @@ describe('registerScopedService / getScopedServiceDescriptors', () => { expect(getScopedServiceDescriptors(LifecycleScope.App)[0]?.id).toBe(IDual); expect(getScopedServiceDescriptors(LifecycleScope.Session)[0]?.id).toBe(IDual); }); - - it('rejects a duplicate registration for the same scope and id', () => { - registerScopedService(LifecycleScope.App, IApp, AppSvc, ScopeActivation.OnDemand, 'first'); - - expect(() => - registerScopedService(LifecycleScope.App, IApp, AppSvc, ScopeActivation.OnDemand, 'second'), - ).toThrowError(/duplicate scoped service registration for 'scoped-app' in scope 'app'/); - expect(getScopedServiceDescriptors(LifecycleScope.App)).toHaveLength(1); - expect(getScopedServiceDescriptors(LifecycleScope.App)[0]?.domain).toBe('first'); - }); - - it('rejects a duplicate registration through an aliased id reference', () => { - const IAliasedApp = IApp; - registerScopedService(LifecycleScope.App, IApp, AppSvc); - - expect(() => registerScopedService(LifecycleScope.App, IAliasedApp, AppSvc)).toThrowError( - /duplicate scoped service registration/, - ); - expect(getScopedServiceDescriptors(LifecycleScope.App)).toHaveLength(1); - }); - - it('overrideScopedService replaces the existing registration in place', () => { - class OverrideAppSvc implements IApp { - tag = 'app' as const; - } - registerScopedService(LifecycleScope.App, IApp, AppSvc, ScopeActivation.OnDemand, 'original'); - overrideScopedService( - LifecycleScope.App, - IApp, - OverrideAppSvc, - ScopeActivation.OnScopeCreated, - 'override', - ); - - const entries = getScopedServiceDescriptors(LifecycleScope.App); - expect(entries).toHaveLength(1); - expect(entries[0]?.descriptor.ctor).toBe(OverrideAppSvc); - expect(entries[0]?.domain).toBe('override'); - expect(entries[0]?.activation).toBe(ScopeActivation.OnScopeCreated); - }); - - it('overrideScopedService resolves the override implementation in a live scope', () => { - class OverrideAppSvc implements IApp { - tag = 'app' as const; - } - registerScopedService(LifecycleScope.App, IApp, AppSvc); - overrideScopedService(LifecycleScope.App, IApp, OverrideAppSvc); - - const app = createAppScope(); - try { - expect(app.accessor.get(IApp)).toBeInstanceOf(OverrideAppSvc); - } finally { - app.dispose(); - } - }); - - it('overrideScopedService rejects an id with no existing registration', () => { - expect(() => - overrideScopedService(LifecycleScope.App, IApp, AppSvc, ScopeActivation.OnDemand, 'late'), - ).toThrowError(/overrideScopedService found no registration for 'scoped-app' in scope 'app'/); - expect(getScopedServiceDescriptors(LifecycleScope.App)).toHaveLength(0); - }); }); diff --git a/packages/agent-core-v2/test/_base/execEnv/environmentProbe.test.ts b/packages/agent-core-v2/test/_base/execEnv/environmentProbe.test.ts index c7f2b78d6..7cc4b7f22 100644 --- a/packages/agent-core-v2/test/_base/execEnv/environmentProbe.test.ts +++ b/packages/agent-core-v2/test/_base/execEnv/environmentProbe.test.ts @@ -1,3 +1,21 @@ +/** + * Host environment probe — MSYS2 bash detection. + * + * Pins the Windows shell probe against native MSYS2 toolchains: a git whose + * `git --exec-path` reports an `ucrt64` / `clang64` / `clangarm64` prefix + * (e.g. `C:/msys64/ucrt64/libexec/git-core`) must walk back to the MSYS2 root + * and resolve the shared bash at `usr\bin\bash.exe`, instead of failing to + * detect any shell. + * + * All tests expect `probeHostEnvironment()` to be a pure function of injected + * platform probes (no ambient state) so the same suite runs identically on + * macOS/Linux/Windows CI runners. + * + * Ported from `packages/kaos/test/environment.test.ts` (the MSYS2 cases added + * by the bash-detection fix); the v1 file carries the full POSIX / Git for + * Windows / Scoop shim matrix, which the vendored probe shares verbatim. + */ + import { describe, expect, it } from 'vitest'; import { diff --git a/packages/agent-core-v2/test/_base/execEnv/loginShellPath.test.ts b/packages/agent-core-v2/test/_base/execEnv/loginShellPath.test.ts index 0e31f392a..bf3d4a418 100644 --- a/packages/agent-core-v2/test/_base/execEnv/loginShellPath.test.ts +++ b/packages/agent-core-v2/test/_base/execEnv/loginShellPath.test.ts @@ -1,3 +1,28 @@ +/** + * Login-shell PATH enrichment. + * + * Reproduces the "Bash tool can't find local `gh`" report: when kimi-code is + * launched from a context that skipped the user's shell profile (GUI launcher, + * non-login parent shell), `process.env.PATH` misses entries like + * `/opt/homebrew/bin`, so every command spawned by the Bash tool inherits the + * impoverished PATH. + * + * `HostEnvironmentService` must probe the user's login shell (`$SHELL -l -c + * /usr/bin/env`, falling back to the OS account's login shell when $SHELL is + * unset or blank) once and append the missing PATH entries to `process.env.PATH` + * — without reordering or overriding what is already there. Probe failures (no + * resolvable shell, hung or broken profile) must leave PATH untouched. + * + * The probe/merge unit tests are pure (injected deps) and run on every + * platform. The end-to-end suite spawns a stub shell and is skipped on Windows: + * the problem is specific to POSIX login-shell profiles, and the probe must not + * run there. + * + * Ported from `packages/kaos/test/login-shell-path.test.ts`; the e2e block + * exercises `applyLoginShellPathFromNode()` (the v2 entry wired into + * `HostEnvironmentService`) instead of v1's `LocalKaos.create()`. + */ + import { chmod, mkdtemp, rm, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; diff --git a/packages/agent-core-v2/test/_base/execEnv/shellPathBridge.test.ts b/packages/agent-core-v2/test/_base/execEnv/shellPathBridge.test.ts deleted file mode 100644 index 28c0400bb..000000000 --- a/packages/agent-core-v2/test/_base/execEnv/shellPathBridge.test.ts +++ /dev/null @@ -1,260 +0,0 @@ -import { describe, expect, it, vi } from 'vitest'; - -import { - createShellPathBridge, - type ShellPathBridgeDeps, - type ShellPathBridgeEnv, -} from '#/_base/execEnv/shellPathBridge'; - -const WINDOWS_ENV: ShellPathBridgeEnv = { - osKind: 'Windows', - shellName: 'bash', - shellPath: 'C:\\Program Files\\Git\\bin\\bash.exe', -}; - -const POSIX_ENV: ShellPathBridgeEnv = { - osKind: 'Linux', - shellName: 'bash', - shellPath: '/bin/bash', -}; - -const BIN_CYGPATH = 'C:\\Program Files\\Git\\bin\\cygpath.exe'; -const USR_BIN_CYGPATH = 'C:\\Program Files\\Git\\usr\\bin\\cygpath.exe'; - -interface StubOpts { - readonly existingPaths?: readonly string[]; - readonly execFileResults?: Readonly>; - readonly execFileSync?: ShellPathBridgeDeps['execFileSync']; -} - -function stubDeps(opts: StubOpts = {}) { - const existing = new Set(opts.existingPaths ?? []); - const execFileSync = vi.fn( - opts.execFileSync ?? - ((file: string, args: readonly string[]): string => { - const result = opts.execFileResults?.[[file, ...args].join(' ')]; - if (result === undefined) throw new Error(`unexpected execFileSync: ${file}`); - return result; - }), - ); - const deps: ShellPathBridgeDeps = { - execFileSync, - isFile: (path: string) => existing.has(path), - }; - return { deps, execFileSync }; -} - -function cygpathKey(firstSegment: string): string { - return `${USR_BIN_CYGPATH} -w -C UTF8 -- /${firstSegment}`; -} - -describe('fromShellPath lexical drive forms', () => { - const cases: ReadonlyArray = [ - ['/c:/Users/foo', 'C:/Users/foo'], - ['/c:', 'C:/'], - ['/cygdrive/c/Users/foo', 'C:/Users/foo'], - ['/cygdrive/d', 'D:/'], - ['/c/Users/foo', 'C:/Users/foo'], - ['/C/Users/foo', 'C:/Users/foo'], - ['/c/', 'C:/'], - ['/c', 'C:/'], - ]; - - for (const [input, expected] of cases) { - it(`rewrites "${input}"`, () => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - expect(bridge.fromShellPath(input)).toBe(expected); - expect(execFileSync).not.toHaveBeenCalled(); - }); - } -}); - -describe('fromShellPath pass-through', () => { - it.each(['/dev/null', '/dev/pty0', '/proc/self/status', '/sys/kernel'])( - 'leaves virtual-fs path %s unchanged', - (input) => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - expect(bridge.fromShellPath(input)).toBe(input); - expect(execFileSync).not.toHaveBeenCalled(); - }, - ); - - it.each([ - '/', - '//server/share', - '//server/share/file.txt', - 'relative/path', - 'relative\\path', - 'file.txt', - 'C:\\Users\\foo', - 'C:/Users/foo', - '~/Documents', - ])('leaves %s unchanged without consulting cygpath', (input) => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - expect(bridge.fromShellPath(input)).toBe(input); - expect(execFileSync).not.toHaveBeenCalled(); - }); -}); - -describe('fromShellPath cygpath resolution', () => { - it('resolves a root-relative path through cygpath and caches per first segment', () => { - const { deps, execFileSync } = stubDeps({ - existingPaths: [USR_BIN_CYGPATH], - execFileResults: { - [cygpathKey('tmp')]: 'C:\\Users\\me\\AppData\\Local\\Temp\\\n', - }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/tmp/scratch/a.txt')).toBe( - 'C:/Users/me/AppData/Local/Temp/scratch/a.txt', - ); - expect(bridge.fromShellPath('/tmp/other')).toBe('C:/Users/me/AppData/Local/Temp/other'); - expect(bridge.fromShellPath('/tmp')).toBe('C:/Users/me/AppData/Local/Temp'); - expect(execFileSync).toHaveBeenCalledTimes(1); - expect(execFileSync).toHaveBeenCalledWith(USR_BIN_CYGPATH, [ - '-w', - '-C', - 'UTF8', - '--', - '/tmp', - ]); - }); - - it('folds dot segments before resolving the mount segment', () => { - const { deps, execFileSync } = stubDeps({ - existingPaths: [USR_BIN_CYGPATH], - execFileResults: { - [cygpathKey('tmp')]: 'C:\\Users\\me\\AppData\\Local\\Temp\n', - [cygpathKey('home')]: 'C:\\Program Files\\Git\\home\n', - }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/./tmp/note.txt')).toBe( - 'C:/Users/me/AppData/Local/Temp/note.txt', - ); - expect(bridge.fromShellPath('/../tmp/note.txt')).toBe( - 'C:/Users/me/AppData/Local/Temp/note.txt', - ); - expect(bridge.fromShellPath('/tmp/../home/x.txt')).toBe('C:/Program Files/Git/home/x.txt'); - expect(execFileSync).toHaveBeenCalledTimes(2); - }); - - it('folds dot segments before lexical drive translation', () => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/./c/Projects')).toBe('C:/Projects'); - expect(execFileSync).not.toHaveBeenCalled(); - }); - - it.each(['/.', '/..'])('normalizes %s to / without consulting cygpath', (input) => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath(input)).toBe('/'); - expect(execFileSync).not.toHaveBeenCalled(); - }); - - it('resolves a drive-root mount and keeps it absolute', () => { - const { deps, execFileSync } = stubDeps({ - existingPaths: [USR_BIN_CYGPATH], - execFileResults: { [cygpathKey('work')]: 'D:\\\n' }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/work/app')).toBe('D:/app'); - expect(bridge.fromShellPath('/work')).toBe('D:/'); - expect(execFileSync).toHaveBeenCalledTimes(1); - }); - - it('prefers cygpath.exe next to bash.exe when present', () => { - const key = `${BIN_CYGPATH} -w -C UTF8 -- /home`; - const { deps, execFileSync } = stubDeps({ - existingPaths: [BIN_CYGPATH, USR_BIN_CYGPATH], - execFileResults: { [key]: 'C:\\Users\n' }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/home/u/f.txt')).toBe('C:/Users/u/f.txt'); - expect(execFileSync).toHaveBeenCalledTimes(1); - expect(execFileSync).toHaveBeenCalledWith(BIN_CYGPATH, ['-w', '-C', 'UTF8', '--', '/home']); - }); - - it('passes through and retries on the next access when cygpath fails', () => { - const { deps, execFileSync } = stubDeps({ - existingPaths: [USR_BIN_CYGPATH], - execFileSync: () => { - throw new Error('cygpath exited 1'); - }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/tmp/x')).toBe('/tmp/x'); - expect(bridge.fromShellPath('/tmp/y')).toBe('/tmp/y'); - expect(execFileSync).toHaveBeenCalledTimes(2); - }); - - it('passes through and retries when cygpath output is not an absolute win32 path', () => { - const { deps, execFileSync } = stubDeps({ - existingPaths: [USR_BIN_CYGPATH], - execFileResults: { [cygpathKey('tmp')]: 'not a win32 path\n' }, - }); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/tmp/x')).toBe('/tmp/x'); - expect(bridge.fromShellPath('/tmp/y')).toBe('/tmp/y'); - expect(execFileSync).toHaveBeenCalledTimes(2); - }); - - it('passes through without spawning when cygpath.exe is missing', () => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - - expect(bridge.fromShellPath('/tmp/x')).toBe('/tmp/x'); - expect(bridge.fromShellPath('/home/u')).toBe('/home/u'); - expect(execFileSync).not.toHaveBeenCalled(); - }); -}); - -describe('identity outside win32 bash', () => { - it('is identity on posix', () => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge(POSIX_ENV, deps); - expect(bridge.fromShellPath('/c/Users/foo')).toBe('/c/Users/foo'); - expect(bridge.fromShellPath('/tmp/x')).toBe('/tmp/x'); - expect(bridge.toShellPath('C:\\Users\\foo')).toBe('C:\\Users\\foo'); - expect(execFileSync).not.toHaveBeenCalled(); - }); - - it('is identity on Windows without bash', () => { - const { deps, execFileSync } = stubDeps(); - const bridge = createShellPathBridge( - { osKind: 'Windows', shellName: 'sh', shellPath: 'C:\\sh.exe' }, - deps, - ); - expect(bridge.fromShellPath('/c/Users/foo')).toBe('/c/Users/foo'); - expect(bridge.toShellPath('C:\\Users\\foo')).toBe('C:\\Users\\foo'); - expect(execFileSync).not.toHaveBeenCalled(); - }); -}); - -describe('toShellPath', () => { - it.each([ - ['C:\\Users\\foo', '/c/Users/foo'], - ['C:/Users/foo', '/c/Users/foo'], - ['C:\\', '/c/'], - ['D:\\Projects', '/d/Projects'], - ['\\\\server\\share\\dir', '//server/share/dir'], - ['relative\\path', 'relative/path'], - ['already/posix', 'already/posix'], - ])('maps %s → %s', (input, expected) => { - const { deps } = stubDeps(); - const bridge = createShellPathBridge(WINDOWS_ENV, deps); - expect(bridge.toShellPath(input)).toBe(expected); - }); -}); diff --git a/packages/agent-core-v2/test/_base/lifecycle/ledger.test.ts b/packages/agent-core-v2/test/_base/lifecycle/ledger.test.ts index cadff8519..6e85c086d 100644 --- a/packages/agent-core-v2/test/_base/lifecycle/ledger.test.ts +++ b/packages/agent-core-v2/test/_base/lifecycle/ledger.test.ts @@ -187,6 +187,7 @@ describe('Ledger', () => { it('async iterator: a mid-iteration throw rolls back already-yielded disposers in reverse', async () => { const events: string[] = []; const ledger = new Ledger('test'); + // eslint-disable-next-line require-yield const body = async function* (): AsyncGenerator { yield () => { events.push('undo-1'); }; yield () => { events.push('undo-2'); }; diff --git a/packages/agent-core-v2/test/_base/log/stubs.ts b/packages/agent-core-v2/test/_base/log/stubs.ts index 52dda4f21..b7b8a3c46 100644 --- a/packages/agent-core-v2/test/_base/log/stubs.ts +++ b/packages/agent-core-v2/test/_base/log/stubs.ts @@ -1,3 +1,10 @@ +/** + * `log` test stubs — shared no-op `ILogService` / `ILogger` for unit tests. + * + * Lives under `test/` (not `src/`) so test-support code stays out of the + * production tree. Import from a relative path (`./stubs` or `../log/stubs`). + */ + import type { ServiceRegistration } from '#/_base/di/test'; import { ILogService } from '#/_base/log/log'; import type { ILogger } from '#/_base/log/log'; diff --git a/packages/agent-core-v2/test/_base/state/stateRegistry.test.ts b/packages/agent-core-v2/test/_base/state/stateRegistry.test.ts index 1def45ac4..8ff98d222 100644 --- a/packages/agent-core-v2/test/_base/state/stateRegistry.test.ts +++ b/packages/agent-core-v2/test/_base/state/stateRegistry.test.ts @@ -1,5 +1,4 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { z } from 'zod'; import { LifecycleScope } from '#/app/scopes'; import { ScopeActivation, @@ -8,8 +7,7 @@ import { } from '#/_base/di/scope'; import { createScopedTestHost, type ScopedTestHost } from '#/_base/di/test'; import { BugIndicatingError } from '#/_base/errors/errors'; -import { StateRegistry, type StateChange } from '#/_base/state/stateRegistry'; -import { defineState } from '#/state/state'; +import { defineState, StateRegistry, type StateChange } from '#/_base/state/stateRegistry'; import { IAppStateService } from '#/app/state/appState'; import { AppStateService } from '#/app/state/appStateService'; import { IWorkspaceStateService } from '#/workspace/state/workspaceState'; @@ -25,13 +23,13 @@ describe('StateRegistry', () => { it('returns the initial value after register', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); + registry.register(countKey); expect(registry.get(countKey)).toBe(0); }); it('reads back the value written by set', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); + registry.register(countKey); registry.set(countKey, 42); expect(registry.get(countKey)).toBe(42); }); @@ -39,8 +37,8 @@ describe('StateRegistry', () => { it('reports registered keys through has and entries', () => { const registry = new StateRegistry(); expect(registry.has(countKey)).toBe(false); - registry.contributeState(countKey); - registry.contributeState(nameKey); + registry.register(countKey); + registry.register(nameKey); expect(registry.has(countKey)).toBe(true); expect(registry.entries()).toEqual([ ['test.count', 0], @@ -50,54 +48,8 @@ describe('StateRegistry', () => { it('rejects duplicate registration', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); - expect(() => registry.contributeState(countKey)).toThrow(BugIndicatingError); - }); - - it('removes the key and value when its registration is disposed', () => { - const registry = new StateRegistry(); - const registration = registry.contributeState(countKey); - registry.set(countKey, 42); - - registration.dispose(); - - expect(registry.has(countKey)).toBe(false); - expect(registry.entries()).toEqual([]); - expect(() => registry.get(countKey)).toThrow(BugIndicatingError); - expect(() => registry.set(countKey, 1)).toThrow(BugIndicatingError); - }); - - it('re-registers with the initial value and ignores stale disposal', () => { - const registry = new StateRegistry(); - const first = registry.contributeState(countKey); - registry.set(countKey, 42); - first.dispose(); - - const second = registry.contributeState(countKey); - expect(registry.get(countKey)).toBe(0); - - first.dispose(); - expect(registry.has(countKey)).toBe(true); - second.dispose(); - expect(registry.has(countKey)).toBe(false); - }); - - it('isolates listeners between registrations', () => { - const registry = new StateRegistry(); - const first = registry.contributeState(countKey); - const oldSeen: number[] = []; - registry.onDidChange(countKey)((value) => oldSeen.push(value)); - registry.set(countKey, 1); - first.dispose(); - - const second = registry.contributeState(countKey); - const newSeen: number[] = []; - registry.onDidChange(countKey)((value) => newSeen.push(value)); - registry.set(countKey, 2); - - expect(oldSeen).toEqual([1]); - expect(newSeen).toEqual([2]); - second.dispose(); + registry.register(countKey); + expect(() => registry.register(countKey)).toThrow(BugIndicatingError); }); it('rejects get and set on an unregistered key', () => { @@ -108,8 +60,8 @@ describe('StateRegistry', () => { it('notifies onDidChange only for the key that was set', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); - registry.contributeState(nameKey); + registry.register(countKey); + registry.register(nameKey); const seen: number[] = []; registry.onDidChange(countKey)((value) => seen.push(value)); registry.set(nameKey, 'bob'); @@ -120,8 +72,8 @@ describe('StateRegistry', () => { it('notifies onDidChangeAny for every set', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); - registry.contributeState(nameKey); + registry.register(countKey); + registry.register(nameKey); const seen: StateChange[] = []; registry.onDidChangeAny((change) => seen.push(change)); registry.set(countKey, 1); @@ -134,7 +86,7 @@ describe('StateRegistry', () => { it('silences change events after dispose', () => { const registry = new StateRegistry(); - registry.contributeState(countKey); + registry.register(countKey); const seen: StateChange[] = []; registry.onDidChangeAny((change) => seen.push(change)); registry.dispose(); @@ -143,16 +95,6 @@ describe('StateRegistry', () => { expect(registry.get(countKey)).toBe(1); }); - it('excludes snapshotExcluded keys from snapshot but keeps them in entries', () => { - const hiddenKey = defineState('test.hidden', () => ({ big: true })); - const registry = new StateRegistry(); - registry.contributeState({ ...hiddenKey, snapshotExcluded: true }); - registry.contributeState(defineState('test.visible', () => 1)); - expect(registry.entries().map(([name]) => name)).toEqual(['test.hidden', 'test.visible']); - expect(registry.snapshot()).toEqual({ 'test.visible': 1 }); - expect(registry.get(hiddenKey)).toEqual({ big: true }); - }); - it('snapshots Maps as plain objects and Sets as arrays', () => { const richKey = defineState('test.rich', () => ({ map: new Map([['a', 1]]), @@ -161,7 +103,7 @@ describe('StateRegistry', () => { flag: true, })); const registry = new StateRegistry(); - registry.contributeState(richKey); + registry.register(richKey); expect(registry.snapshot()).toEqual({ 'test.rich': { map: { a: 1 }, set: ['x', 'y'], list: [1, 2], flag: true }, }); @@ -171,7 +113,7 @@ describe('StateRegistry', () => { const id = { id: 1 }; const pairKey = defineState('test.pairs', () => new Map([[id, 'one']])); const registry = new StateRegistry(); - registry.contributeState(pairKey); + registry.register(pairKey); expect(registry.snapshot()).toEqual({ 'test.pairs': [[{ id: 1 }, 'one']] }); }); @@ -182,7 +124,7 @@ describe('StateRegistry', () => { return obj; }); const registry = new StateRegistry(); - registry.contributeState(trickyKey); + registry.register(trickyKey); expect(registry.snapshot()).toEqual({ 'test.tricky': { value: 2, self: '(circular)' }, }); @@ -192,7 +134,7 @@ describe('StateRegistry', () => { const shared = { v: 1 }; const sharedKey = defineState('test.shared', () => ({ a: shared, b: shared })); const registry = new StateRegistry(); - registry.contributeState(sharedKey); + registry.register(sharedKey); expect(registry.snapshot()).toEqual({ 'test.shared': { a: { v: 1 }, b: { v: 1 } } }); }); @@ -208,7 +150,7 @@ describe('StateRegistry', () => { nullProto: Object.assign(Object.create(null) as Record, { v: 1 }), })); const registry = new StateRegistry(); - registry.contributeState(mixedKey); + registry.register(mixedKey); expect(registry.snapshot()).toEqual({ 'test.mixed': { plain: { nested: [1, { ok: true }] }, @@ -233,7 +175,7 @@ describe('state services (scoped)', () => { 'state', ); registerScopedService( - LifecycleScope.App, + LifecycleScope.Workspace, IWorkspaceStateService, WorkspaceStateService, ScopeActivation.OnScopeCreated, @@ -259,7 +201,7 @@ describe('state services (scoped)', () => { afterEach(() => host.dispose()); function createChain() { - const workspace = host.app; + const workspace = host.child(LifecycleScope.Workspace, 'w1'); const session = host.childOf(workspace, LifecycleScope.Session, 's1'); const agent = host.childOf(session, LifecycleScope.Agent, 'main'); return { workspace, session, agent }; @@ -280,7 +222,7 @@ describe('state services (scoped)', () => { const sessionKey = defineState('test.sessionOnly', () => 'seed'); const { workspace, session, agent } = createChain(); const sessionState = session.accessor.get(ISessionStateService); - sessionState.contributeState(sessionKey); + sessionState.register(sessionKey); sessionState.set(sessionKey, 'live'); expect(sessionState.get(sessionKey)).toBe('live'); expect(agent.accessor.get(IAgentStateService).has(sessionKey)).toBe(false); @@ -296,7 +238,7 @@ describe('state services (scoped)', () => { it('omits the parent link when a registry has no cascade parent', () => { const loneKey = defineState('test.lone', () => 0); const registry = new StateRegistry(); - registry.contributeState(loneKey); + registry.register(loneKey); expect(registry.inspect()).toEqual({ scope: 'unknown', state: { 'test.lone': 0 }, @@ -304,13 +246,17 @@ describe('state services (scoped)', () => { }); }); - it('cascades inspect from the agent tier to the session state', () => { + it('cascades inspect from the agent tier up to the app root', () => { + const appKey = defineState('test.appOnly', () => 'a'); + const workspaceKey = defineState('test.workspaceOnly', () => 'w'); const sessionKey = defineState('test.sessionCascade', () => 's'); const agentKey = defineState('test.agentOnly', () => 'g'); - const { session, agent } = createChain(); - session.accessor.get(ISessionStateService).contributeState(sessionKey); + host.app.accessor.get(IAppStateService).register(appKey); + const { workspace, session, agent } = createChain(); + workspace.accessor.get(IWorkspaceStateService).register(workspaceKey); + session.accessor.get(ISessionStateService).register(sessionKey); const agentState = agent.accessor.get(IAgentStateService); - agentState.contributeState(agentKey); + agentState.register(agentKey); expect(agentState.inspect()).toEqual({ scope: 'agent', @@ -318,57 +264,16 @@ describe('state services (scoped)', () => { parent: { scope: 'session', state: { 'test.sessionCascade': 's' }, - parent: undefined, + parent: { + scope: 'workspace', + state: { 'test.workspaceOnly': 'w' }, + parent: { + scope: 'app', + state: { 'test.appOnly': 'a' }, + parent: undefined, + }, + }, }, }); }); - - describe('replayable contribution boundary', () => { - const replayableKey = defineState('test.replayable', () => 0).replayable({ - schema: z.custom(), - }); - - it('rejects replayable keys on the base registry and non-agent scopes', () => { - expect(() => new StateRegistry().contributeState(replayableKey)).toThrow(BugIndicatingError); - expect(() => new AppStateService().contributeState(replayableKey)).toThrow(BugIndicatingError); - expect(() => new WorkspaceStateService().contributeState(replayableKey)).toThrow( - BugIndicatingError, - ); - expect(() => new SessionStateService().contributeState(replayableKey)).toThrow( - BugIndicatingError, - ); - }); - - it('accepts replayable keys on the agent scope and lists them', () => { - const agentState = new AgentStateService(); - agentState.contributeState(replayableKey); - expect(agentState.get(replayableKey)).toBe(0); - expect(agentState.replayableKeys().map((key) => key.name)).toEqual(['test.replayable']); - }); - - it('notifies replayable contributions synchronously', () => { - const agentState = new AgentStateService(); - const seen: string[] = []; - const subscription = agentState.onDidContributeReplayable((key) => { - seen.push(key.name); - }); - agentState.contributeState(replayableKey); - expect(seen).toEqual(['test.replayable']); - subscription.dispose(); - const otherKey = defineState('test.replayable.other', () => 0).replayable({ - schema: z.custom(), - }); - agentState.contributeState(otherKey); - expect(seen).toEqual(['test.replayable']); - }); - - it('drops a replayable key from the list when its contribution is disposed', () => { - const agentState = new AgentStateService(); - const registration = agentState.contributeState(replayableKey); - expect(agentState.replayableKeys()).toHaveLength(1); - registration.dispose(); - expect(agentState.replayableKeys()).toHaveLength(0); - expect(agentState.has(replayableKey)).toBe(false); - }); - }); }); diff --git a/packages/agent-core-v2/test/_base/text/encoding.test.ts b/packages/agent-core-v2/test/_base/text/encoding.test.ts index 7a7177683..1457b165a 100644 --- a/packages/agent-core-v2/test/_base/text/encoding.test.ts +++ b/packages/agent-core-v2/test/_base/text/encoding.test.ts @@ -1,7 +1,6 @@ import { describe, expect, it } from 'vitest'; import { - classifyTextSample, decodeUtfText, detectTextEncoding, ENCODING_DETECTION_SAMPLE_BYTES, @@ -47,6 +46,8 @@ describe('detectTextEncoding', () => { }); it('reports BOM-less UTF-16 with no zero bytes at all as utf-8 (known limitation)', () => { + // Pure CJK content has no zero bytes in UTF-16 — undetectable without + // statistical guessing, same as VS Code. expect(detectTextEncoding(utf16Le('你好世界')).encoding).toBe('utf-8'); }); @@ -58,7 +59,7 @@ describe('detectTextEncoding', () => { it('limits the zero-byte heuristic to the leading sample window', () => { const sample = Buffer.alloc(ENCODING_DETECTION_SAMPLE_BYTES + 2, 0x61); sample[ENCODING_DETECTION_SAMPLE_BYTES + 1] = 0x00; - expect(detectTextEncoding(sample)).toEqual({ encoding: 'utf-8', seemsBinary: true }); + expect(detectTextEncoding(sample)).toEqual({ encoding: 'utf-8', seemsBinary: false }); }); it('flags zero bytes at both parities as binary', () => { @@ -77,75 +78,6 @@ describe('detectTextEncoding', () => { }); }); -describe('classifyTextSample', () => { - it('classifies UTF-8 multibyte text (CJK, emoji) as utf-8 text', () => { - const sample = Buffer.from('2026-08-16 INFO 启动完成 ✅\n处理请求 🚀 成功\n'.repeat(20), 'utf8'); - expect(classifyTextSample(sample)).toEqual({ isBinary: false, encoding: 'utf-8' }); - }); - - it('classifies an empty sample as utf-8 text', () => { - expect(classifyTextSample(new Uint8Array())).toEqual({ isBinary: false, encoding: 'utf-8' }); - }); - - it('classifies samples carrying NUL bytes as binary', () => { - expect( - classifyTextSample(Buffer.from([0x61, 0x62, 0x63, 0x00, 0x64, 0x65, 0x66])).isBinary, - ).toBe(true); - expect(classifyTextSample(Buffer.from([0x00, 0x00, 0x61, 0x62])).isBinary).toBe(true); - }); - - it('classifies control-char-heavy samples over the threshold as binary', () => { - const sample = Buffer.concat([Buffer.alloc(40, 0x1b), Buffer.alloc(60, 0x61)]); - expect(classifyTextSample(sample).isBinary).toBe(true); - }); - - it('keeps ANSI-colored log lines under the control-char threshold as text', () => { - const esc = String.fromCodePoint(0x1b); - const sample = Buffer.from(`${esc}[32mINFO${esc}[0m 启动完成 ✅\n`.repeat(10), 'utf8'); - expect(classifyTextSample(sample)).toEqual({ isBinary: false, encoding: 'utf-8' }); - }); - - it('classifies invalid UTF-8 without UTF-16 features as binary', () => { - expect(classifyTextSample(Buffer.from([0xd6, 0xd0, 0xc4, 0xe3, 0x31, 0x32]))).toEqual({ - isBinary: true, - encoding: 'utf-8', - }); - }); - - it('tolerates a multi-byte sequence truncated at the sample tail', () => { - const sample = Buffer.concat([Buffer.from('日志记录\n', 'utf8'), Buffer.from([0xe4, 0xb8])]); - expect(classifyTextSample(sample)).toEqual({ isBinary: false, encoding: 'utf-8' }); - }); - - it('treats a NUL byte beyond the UTF-16 parity window as binary', () => { - const sample = Buffer.concat([ - Buffer.alloc(600, 0x61), - Buffer.from([0x00]), - Buffer.alloc(100, 0x62), - ]); - expect(classifyTextSample(sample).isBinary).toBe(true); - }); - - it('rejects an impossible UTF-8 lead byte at the sample tail', () => { - const sample = Buffer.concat([Buffer.from('plain ascii log line\n'), Buffer.from([0xff])]); - expect(classifyTextSample(sample).isBinary).toBe(true); - }); - - it('rejects a tail lead byte not followed by continuation bytes', () => { - const sample = Buffer.concat([Buffer.from('plain ascii log line\n'), Buffer.from([0xe4, 0x41])]); - expect(classifyTextSample(sample).isBinary).toBe(true); - }); - - it('classifies UTF-16 BOM and zero-byte parity samples as text with the right encoding', () => { - const le = Buffer.concat([Buffer.from([0xff, 0xfe]), utf16Le('hello 你好')]); - expect(classifyTextSample(le)).toEqual({ isBinary: false, encoding: 'utf-16le' }); - expect(classifyTextSample(utf16Be('hello world, plain ascii'))).toEqual({ - isBinary: false, - encoding: 'utf-16be', - }); - }); -}); - describe('decodeUtfText', () => { it('decodes UTF-16 LE/BE and strips the BOM', () => { const le = Buffer.concat([Buffer.from([0xff, 0xfe]), utf16Le('你好\nworld')]); diff --git a/packages/agent-core-v2/test/_base/utils/paths.test.ts b/packages/agent-core-v2/test/_base/utils/paths.test.ts index 1859ff0a3..1f73ebc59 100644 --- a/packages/agent-core-v2/test/_base/utils/paths.test.ts +++ b/packages/agent-core-v2/test/_base/utils/paths.test.ts @@ -1,10 +1,14 @@ -import { mkdtemp, mkdir, rm, stat } from 'node:fs/promises'; -import { tmpdir } from 'node:os'; -import nodePath, { win32 } from 'node:path'; +/** + * Scenario: recursive watches constrained to selected candidate subtrees. + * Responsibilities: candidate ancestry, scan-depth bounds, and excluded-entry + * probing. Wiring: pure path predicates with no external collaborators. + * Run: `pnpm --filter @moonshot-ai/agent-core-v2 exec vitest run + * test/_base/utils/paths.test.ts`. + */ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; +import { describe, expect, it } from 'vitest'; -import { canonicalWorkspaceRoot, findUpwardRoot, resolvePath, subtreeWatchFilter } from '#/_base/utils/paths'; +import { subtreeWatchFilter } from '#/_base/utils/paths'; describe('subtree watch filtering', () => { const root = '/repo'; @@ -101,116 +105,3 @@ describe('subtree watch filtering', () => { expect(ignored('/repo/.agents/skills/parent/child/runtime')).toBe(true); }); }); - -describe('findUpwardRoot', () => { - const noMarker = async () => false; - - describe('with host-default path semantics', () => { - let root: string; - - beforeEach(async () => { - root = await mkdtemp(nodePath.join(tmpdir(), 'upward-root-')); - }); - - afterEach(async () => { - await rm(root, { recursive: true, force: true }); - }); - - const hasMarker = async (markerPath: string): Promise => { - try { - await stat(markerPath); - return true; - } catch { - return false; - } - }; - - it('stops at the nearest ancestor holding the marker', async () => { - await mkdir(nodePath.join(root, '.git')); - const child = nodePath.join(root, 'src', 'pkg'); - await mkdir(child, { recursive: true }); - - const found = await findUpwardRoot(child, '.git', hasMarker); - - expect(found).toBe(root.replaceAll('\\', '/')); - }); - - it('falls back to the working directory when no ancestor holds the marker', async () => { - const child = nodePath.join(root, 'src', 'pkg'); - await mkdir(child, { recursive: true }); - - const found = await findUpwardRoot(child, '.git', hasMarker); - - expect(found).toBe(child.replaceAll('\\', '/')); - }); - }); - - it('keeps a Windows drive-root working directory in host form', async () => { - const found = await findUpwardRoot('E:\\', '.git', noMarker, win32); - - expect(found).toBe('E:/'); - }); - - it('keeps a Windows UNC working directory in host form', async () => { - const found = await findUpwardRoot('\\\\fs1\\share\\dir', '.git', noMarker, win32); - - expect(found).toBe('//fs1/share/dir'); - }); - - it('stops at the nearest Windows ancestor holding the marker', async () => { - const found = await findUpwardRoot( - 'E:\\repo\\src', - '.git', - async (markerPath) => markerPath === 'E:\\repo\\.git', - win32, - ); - - expect(found).toBe('E:/repo'); - }); -}); - -describe('resolvePath', () => { - it('resolves drive-letter absolute values without joining the base', () => { - expect(resolvePath('/repo', 'C:/tools')).toBe('C:/tools'); - expect(resolvePath('/repo', 'C:\\tools\\bin')).toBe('C:/tools/bin'); - }); - - it('resolves values against a Windows base with win32 semantics', () => { - expect(resolvePath('C:/repo', 'tools/mcp')).toBe('C:/repo/tools/mcp'); - expect(resolvePath('C:\\repo', '.\\tools')).toBe('C:/repo/tools'); - expect(resolvePath('C:/repo', 'D:/elsewhere')).toBe('D:/elsewhere'); - }); - - it('keeps UNC bases and values intact', () => { - expect(resolvePath('//server/share/repo', 'tools')).toBe('//server/share/repo/tools'); - expect(resolvePath('/repo', '//server/share/tools')).toBe('//server/share/tools'); - expect(resolvePath('\\\\server\\share\\repo', 'tools')).toBe('//server/share/repo/tools'); - }); - - it('keeps POSIX resolution identical to plain absolute/normalize semantics', () => { - expect(resolvePath('/repo', 'tools/../mcp')).toBe('/repo/mcp'); - expect(resolvePath('/repo', '/abs/path')).toBe('/abs/path'); - }); -}); - -describe('canonicalWorkspaceRoot', () => { - it('case-folds drive-letter spellings and strips trailing separators', () => { - expect(canonicalWorkspaceRoot('C:\\Users\\Foo\\Repo')).toBe('c:/users/foo/repo'); - expect(canonicalWorkspaceRoot('C:/Users/Foo/Repo/')).toBe('c:/users/foo/repo'); - }); - - it('keeps the UNC share slash and case-folds', () => { - expect(canonicalWorkspaceRoot('//server/share/repo')).toBe('//server/share/repo'); - expect(canonicalWorkspaceRoot('\\\\SERVER\\SHARE\\REPO')).toBe('//server/share/repo'); - }); - - it('resolves dot segments in Windows spellings', () => { - expect(canonicalWorkspaceRoot('C:/Users/Foo/../Foo/Repo')).toBe('c:/users/foo/repo'); - }); - - it('keeps POSIX roots untouched apart from trailing-slash and dot-segment cleanup', () => { - expect(canonicalWorkspaceRoot('/Repo/Sub')).toBe('/Repo/Sub'); - expect(canonicalWorkspaceRoot('/Repo/Sub/')).toBe('/Repo/Sub'); - expect(canonicalWorkspaceRoot('/Repo/Sub/../Other')).toBe('/Repo/Other'); - }); -}); diff --git a/packages/agent-core-v2/test/_base/utils/tokens.test.ts b/packages/agent-core-v2/test/_base/utils/tokens.test.ts index e9f4a882c..e29bed4cd 100644 --- a/packages/agent-core-v2/test/_base/utils/tokens.test.ts +++ b/packages/agent-core-v2/test/_base/utils/tokens.test.ts @@ -1,3 +1,11 @@ +/** + * Scenario: token estimation for rich content parts. + * Responsibilities: media parts contribute bounded non-zero estimates to + * content-part and whole-message estimates. Wiring: pure utility functions, no + * collaborators. Run with: + * `vitest run --config packages/agent-core-v2/vitest.config.ts test/_base/utils/tokens.test.ts`. + */ + import type { ContentPart } from '#/kosong/contract/message'; import { describe, expect, it } from 'vitest'; diff --git a/packages/agent-core-v2/test/agent/activityView/activityView.test.ts b/packages/agent-core-v2/test/agent/activityView/activityView.test.ts index ff95a03c5..1887d994e 100644 --- a/packages/agent-core-v2/test/agent/activityView/activityView.test.ts +++ b/packages/agent-core-v2/test/agent/activityView/activityView.test.ts @@ -1,56 +1,46 @@ +/** + * `AgentActivityView` — the folded read model: turn slice, lastTurn memory, + * and the background-work busy layer (seeded from task and compaction owners, + * folded from their lifecycle events). + */ + import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { SyncDescriptor } from '#/_base/di/descriptors'; import { DisposableStore, type IDisposable } from '#/_base/di/lifecycle'; import { TestInstantiationService } from '#/_base/di/test'; -import { IEventBus } from '#/app/event/eventBus'; -import type { Event2, Event2Class } from '#/app/event/event2'; +import { type DomainEvent, IEventBus } from '#/app/event/eventBus'; import { IAgentLoopService } from '#/agent/loop/loop'; -import { TurnStarted } from '#/agent/loop/turnEvents'; -import { TurnEnded, turnKey, type TurnModelState } from '#/agent/loop/turnOps'; -import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IAgentStateService } from '#/agent/state/agentState'; import { AgentStateService } from '#/agent/state/agentStateService'; import { IAgentTaskService } from '#/agent/task/task'; -import { TaskStarted, TaskTerminatedNotice } from '#/agent/task/taskOps'; import type { AgentTaskInfo } from '#/agent/task/types'; -import { - CompactionCancelled, - CompactionStarted, -} from '#/agent/fullCompaction/compactionOps'; import { AgentActivityView } from '#/agent/activityView/activityViewService'; import { IAgentActivityView, type AgentActivityState } from '#/agent/activityView/activityView'; -import { - PermissionApprovalRequested, - PermissionApprovalResolved, -} from '#/agent/toolApproval/toolApprovalService'; import { IAgentFullCompactionService } from '#/agent/fullCompaction/fullCompaction'; import type { FullCompactionTask } from '#/agent/fullCompaction/fullCompaction'; -import { OrderedHookSlot } from '#/hooks'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import { stubAgentContext } from '../agentContext/stubs'; +import { TurnModel, type TurnModelState } from '#/agent/loop/turnOps'; +import { IWireService } from '#/wire/wire'; class FakeBus { - private readonly byType = new Map void>>(); - private readonly all: Array<(e: Event2) => void> = []; - readonly published: Event2[] = []; + private readonly byType = new Map void>>(); + private readonly all: Array<(e: DomainEvent) => void> = []; + readonly published: DomainEvent[] = []; - publish(event: Event2): void { + publish(event: DomainEvent): void { this.published.push(event); for (const h of this.all) h(event); for (const h of this.byType.get(event.type) ?? []) h(event); } - subscribe(typeOrClass: unknown, handler?: unknown): IDisposable { - if (typeof typeOrClass === 'function' && !('type' in typeOrClass)) { - this.all.push(typeOrClass as (e: Event2) => void); + subscribe(type: unknown, handler?: unknown): IDisposable { + if (typeof type === 'function') { + this.all.push(type as (e: DomainEvent) => void); return { dispose: () => {} }; } - const type = - typeof typeOrClass === 'string' ? typeOrClass : (typeOrClass as Event2Class).type; - const list = this.byType.get(type) ?? []; - list.push(handler as (e: Event2) => void); - this.byType.set(type, list); + const list = this.byType.get(type as string) ?? []; + list.push(handler as (e: DomainEvent) => void); + this.byType.set(type as string, list); return { dispose: () => {} }; } } @@ -81,11 +71,13 @@ function harness( status: () => ({ state: 'idle', pendingTurnIds: [], hasPendingRequests: false }), } as unknown as IAgentLoopService; const tasks = { list: () => seedTasks } as unknown as IAgentTaskService; + const wireState: { lastEnded?: TurnModelState['lastEnded'] } = { lastEnded }; const restoreHooks: Array<() => Promise> = []; - const dispatcher = { - dispatch: async (event: Event2) => { - bus.publish(event); - }, + const wire = { + getModel: (model: unknown) => + model === TurnModel + ? { nextTurnId: 1, cancelledTurnIds: [], lastEnded: wireState.lastEnded } + : undefined, hooks: { onDidRestore: { register: (_id: string, fn: (ctx: undefined, next: () => Promise) => Promise) => { @@ -94,26 +86,17 @@ function harness( }, }, }, - } as unknown as IEventDispatcher; + } as unknown as IWireService; const restore = async (ended: TurnModelState['lastEnded']): Promise => { - agentState.set(turnKey, { nextTurnId: 1, cancelledTurnIds: [], lastEnded: ended }); + wireState.lastEnded = ended; for (const hook of restoreHooks) await hook(); }; const ix = disposables.add(new TestInstantiationService()); ix.stub(IEventBus, bus as unknown as IEventBus); ix.stub(IAgentLoopService, loop); ix.stub(IAgentTaskService, tasks); - ix.stub(IEventDispatcher, dispatcher); - const agentState = new AgentStateService(); - agentState.contributeState(turnKey); - agentState.set(turnKey, { nextTurnId: 1, cancelledTurnIds: [], lastEnded }); - ix.set(IAgentStateService, agentState); - ix.stub(IAgentScopeContext, { - _serviceBrand: undefined, - agentId: 'main', - agentContext: stubAgentContext('main', 1), - scope: (subKey?: string) => subKey ?? '', - }); + ix.stub(IWireService, wire); + ix.set(IAgentStateService, new AgentStateService()); ix.stub(IAgentFullCompactionService, { _serviceBrand: undefined, compacting, @@ -144,11 +127,11 @@ describe('AgentActivityView', () => { it('folds task.started / task.terminated into the background slice', () => { const { bus, view, updates } = harness(); - bus.publish(new TaskStarted({ agentId: 'main', info: makeTaskInfo('bash-1') })); + bus.publish({ type: 'task.started', info: makeTaskInfo('bash-1') }); expect(view.state().background).toEqual([{ kind: 'process', id: 'bash-1', since: 100 }]); expect(updates().at(-1)?.background).toHaveLength(1); - bus.publish(new TaskTerminatedNotice({ agentId: 'main', info: makeTaskInfo('bash-1') })); + bus.publish({ type: 'task.terminated', info: makeTaskInfo('bash-1') }); expect(view.state().background).toEqual([]); expect(updates().at(-1)?.background).toHaveLength(0); }); @@ -158,7 +141,7 @@ describe('AgentActivityView', () => { expect(view.state().background).toEqual([{ kind: 'process', id: 'bash-9', since: 100 }]); }); - it('seeds lastTurn from the wire turnKey when the view is built after restore', () => { + it('seeds lastTurn from the wire TurnModel when the view is built after restore', () => { const { view } = harness([], null, { turnId: 7, reason: 'failed', durationMs: 1234 }); expect(view.state().lastTurn).toMatchObject({ turnId: 7, reason: 'failed', durationMs: 1234 }); }); @@ -172,7 +155,7 @@ describe('AgentActivityView', () => { it('does not overwrite a live lastTurn when the restore hook runs', async () => { const { bus, view, restore } = harness([], null, { turnId: 7, reason: 'failed' }); - bus.publish(new TurnEnded({ agentId: 'main', turnId: 9, reason: 'completed' })); + bus.publish({ type: 'turn.ended', turnId: 9, reason: 'completed' }); await restore({ turnId: 7, reason: 'failed' }); expect(view.state().lastTurn).toMatchObject({ turnId: 9, reason: 'completed' }); }); @@ -185,12 +168,12 @@ describe('AgentActivityView', () => { it('folds full compaction into the background slice', () => { const { bus, view } = harness(); - bus.publish(new CompactionStarted({ agentId: 'main', trigger: 'manual' })); + bus.publish({ type: 'compaction.started', trigger: 'manual' }); expect(view.state().background).toEqual([ expect.objectContaining({ kind: 'compaction', id: 'full-compaction' }), ]); - bus.publish(new CompactionCancelled({ agentId: 'main' })); + bus.publish({ type: 'compaction.cancelled' }); expect(view.state().background).toEqual([]); }); @@ -212,10 +195,10 @@ describe('AgentActivityView', () => { it('folds turn boundaries into turn / lastTurn', () => { const { bus, view } = harness(); - bus.publish(new TurnStarted({ agentId: 'main', turnId: 1, origin: { kind: 'user' } })); + bus.publish({ type: 'turn.started', turnId: 1, origin: { kind: 'user' } }); expect(view.state().turn?.turnId).toBe(1); - bus.publish(new TurnEnded({ agentId: 'main', turnId: 1, reason: 'completed' })); + bus.publish({ type: 'turn.ended', turnId: 1, reason: 'completed' }); expect(view.state().turn).toBeUndefined(); expect(view.state().lastTurn).toMatchObject({ turnId: 1, reason: 'completed' }); }); @@ -223,70 +206,14 @@ describe('AgentActivityView', () => { it('clears the previous outcome when a new turn starts', () => { const { bus, view } = harness(); - bus.publish(new TurnStarted({ agentId: 'main', turnId: 1, origin: { kind: 'user' } })); - bus.publish(new TurnEnded({ agentId: 'main', turnId: 1, reason: 'cancelled' })); + bus.publish({ type: 'turn.started', turnId: 1, origin: { kind: 'user' } }); + bus.publish({ type: 'turn.ended', turnId: 1, reason: 'cancelled' }); expect(view.state().lastTurn).toMatchObject({ turnId: 1, reason: 'cancelled' }); - bus.publish(new TurnStarted({ agentId: 'main', turnId: 2, origin: { kind: 'user' } })); + bus.publish({ type: 'turn.started', turnId: 2, origin: { kind: 'user' } }); expect(view.state().lastTurn).toBeUndefined(); - bus.publish(new TurnEnded({ agentId: 'main', turnId: 2, reason: 'completed' })); + bus.publish({ type: 'turn.ended', turnId: 2, reason: 'completed' }); expect(view.state().lastTurn).toMatchObject({ turnId: 2, reason: 'completed' }); }); - - it('exposes the engine-minted interaction id as the approval id', () => { - const { bus, view } = harness(); - - bus.publish(new TurnStarted({ agentId: 'main', turnId: 1, origin: { kind: 'user' } })); - bus.publish( - new PermissionApprovalRequested({ agentId: 'main', - id: 'approval_1', - sessionId: 's', - turnId: 1, - toolCallId: 'tc-1', - toolName: 'Bash', - action: 'run', - toolInput: {}, - display: { kind: 'command', command: 'ls' }, - }), - ); - expect(view.state().turn?.pendingApprovals).toEqual([ - { approvalId: 'approval_1', toolCallId: 'tc-1', since: expect.any(Number) }, - ]); - - bus.publish( - new PermissionApprovalResolved({ agentId: 'main', - id: 'approval_1', - sessionId: 's', - turnId: 1, - toolCallId: 'tc-1', - toolName: 'Bash', - action: 'run', - toolInput: {}, - display: { kind: 'command', command: 'ls' }, - decision: 'approved', - }), - ); - expect(view.state().turn?.pendingApprovals).toEqual([]); - }); - - it('falls back to the tool call id when the approval event carries no interaction id', () => { - const { bus, view } = harness(); - - bus.publish(new TurnStarted({ agentId: 'main', turnId: 1, origin: { kind: 'user' } })); - bus.publish( - new PermissionApprovalRequested({ agentId: 'main', - sessionId: 's', - turnId: 1, - toolCallId: 'tc-1', - toolName: 'Bash', - action: 'run', - toolInput: {}, - display: { kind: 'command', command: 'ls' }, - }), - ); - expect(view.state().turn?.pendingApprovals).toEqual([ - { approvalId: 'tc-1', toolCallId: 'tc-1', since: expect.any(Number) }, - ]); - }); }); diff --git a/packages/agent-core-v2/test/agent/agentContext/stubs.ts b/packages/agent-core-v2/test/agent/agentContext/stubs.ts deleted file mode 100644 index 35cfa1f2d..000000000 --- a/packages/agent-core-v2/test/agent/agentContext/stubs.ts +++ /dev/null @@ -1,10 +0,0 @@ -import type { AgentContext } from '#/agent/agentContext/agentContext'; -import { makeAgentScopeContext } from '#/agent/scopeContext/scopeContext'; - -export function stubAgentContext(agentId: string, generation = 1): AgentContext { - return makeAgentScopeContext({ - agentId, - agentScope: `agents/${agentId}`, - generation, - }).agentContext; -} diff --git a/packages/agent-core-v2/test/agent/agentsMdReminder/agentsMdReminder.test.ts b/packages/agent-core-v2/test/agent/agentsMdReminder/agentsMdReminder.test.ts index 41be8b1d4..b9309eb3d 100644 --- a/packages/agent-core-v2/test/agent/agentsMdReminder/agentsMdReminder.test.ts +++ b/packages/agent-core-v2/test/agent/agentsMdReminder/agentsMdReminder.test.ts @@ -1,12 +1,18 @@ +/** + * Scenario: discover uninjected AGENTS.md files from canonical tool accesses and Bash targets. + * Responsibilities: seeding, once-only reminders, result delivery, probing, and path extraction. + * Wiring: real reminder, executor, parser, and host filesystem with telemetry/event stubs. + * Run: pnpm exec vitest run test/agent/agentsMdReminder/agentsMdReminder.test.ts + */ + import { mkdir, mkdtemp, rm, symlink, writeFile } from 'node:fs/promises'; import { tmpdir } from 'node:os'; -import { join, normalize, basename, dirname } from 'pathe'; +import { join, normalize } from 'pathe'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; import { DisposableStore } from '#/_base/di/lifecycle'; import { createServices, type TestInstantiationService } from '#/_base/di/test'; -import { Emitter } from '#/_base/event'; import { IBashParserService } from '#/app/bashParser/bashParser'; import { BashParserService } from '#/app/bashParser/bashParserService'; import { ITelemetryService } from '#/app/telemetry/telemetry'; @@ -14,11 +20,7 @@ import type { ToolCall } from '#/kosong/contract/message'; import { HostFileSystem } from '#/os/backends/node-local/hostFsService'; import { IHostEnvironment } from '#/os/interface/hostEnvironment'; import { IHostFileSystem, type HostFileStat } from '#/os/interface/hostFileSystem'; -import type { RuntimeLease } from '#/runtime/runtime'; -import { IAgentRuntimeService } from '#/agent/runtimeBinding/agentRuntime'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; -import { ISessionInstructionsProvider } from '#/session/sessionInstructions/instructionsProvider'; -import type { HostFsChange } from '#/os/interface/hostFsWatch'; import { ToolAccesses, type ToolAccesses as ToolAccessesType, @@ -40,28 +42,23 @@ import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IAgentScopeContext } from '#/agent/scopeContext/scopeContext'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; import { IAgentStateService } from '#/agent/state/agentState'; -import { profileKey } from '#/agent/profile/profileOps'; import { AgentStateService } from '#/agent/state/agentStateService'; import { IAgentLoopService } from '#/agent/loop/loop'; import { IAgentToolDedupeService } from '#/agent/toolDedupe/toolDedupe'; import { AgentToolDedupeService } from '#/agent/toolDedupe/toolDedupeService'; -import type { PromptOrigin } from '#/agent/contextMemory/types'; -import { IAgentLifecycleService } from '#/session/agentLifecycle/agentLifecycle'; -import { createReminderStub, lifecycleWithReminder } from '../../features/reminder/stubs'; import { OrderedHookSlot } from '#/hooks'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import type { ToolDidExecuteContext } from '#/agent/toolExecutor/toolHooks'; +import { IWireService } from '#/wire/wire'; +import type { + ResolvedToolExecutionHookContext, + ToolDidExecuteContext, +} from '#/agent/toolExecutor/toolHooks'; import { IAgentAgentsMdReminderService } from '#/agent/agentsMdReminder/agentsMdReminder'; -import { - AgentAgentsMdReminderService, - agentsMdReminderKnownKey, -} from '#/agent/agentsMdReminder/agentsMdReminderService'; +import { AgentAgentsMdReminderService } from '#/agent/agentsMdReminder/agentsMdReminderService'; import { extractBashTargetDirs } from '#/agent/agentsMdReminder/bashTargets'; import { recordingTelemetry, type TelemetryRecord } from '../../app/telemetry/stubs'; import { stubToolExecutorEvents, type ToolExecutorEventStubs } from '../toolExecutor/stubs'; import { stubLoopWithHooks } from '../loop/stubs'; import { registerLogServices } from '../../_base/log/stubs'; -import { stubAgentContext } from '../agentContext/stubs'; let disposables: DisposableStore; let homeDir: string; @@ -80,19 +77,12 @@ afterEach(async () => { await rm(workDir, { recursive: true, force: true }); }); -interface CapturedReminder { - readonly content: string; - readonly origin: PromptOrigin; -} - interface Harness { readonly ix: TestInstantiationService; readonly events: ToolExecutorEventStubs; readonly reminder: IAgentAgentsMdReminderService; - readonly dispatcher: IEventDispatcher; + readonly wire: IWireService; readonly telemetryEvents: TelemetryRecord[]; - readonly reminders: CapturedReminder[]; - readonly instructionsChange: Emitter; } function createHarness( @@ -110,9 +100,7 @@ function createHarness( } = {}, ): Harness { const telemetryEvents: TelemetryRecord[] = []; - const reminders: CapturedReminder[] = []; const events = stubToolExecutorEvents(); - const instructionsChange = disposables.add(new Emitter()); const ix = createServices(disposables, { additionalServices: (reg) => { if (options.withRealExecutor === true) { @@ -123,6 +111,11 @@ function createHarness( }); reg.define(IAgentToolRegistryService, AgentToolRegistryService); reg.define(IAgentToolExecutorService, AgentToolExecutorService); + reg.defineInstance(IAgentScopeContext, { + _serviceBrand: undefined, + agentId: 'main', + scope: (sub?: string): string => (sub ? `agents/main/${sub}` : 'agents/main'), + } satisfies IAgentScopeContext); reg.definePartialInstance(IFileSystemStorageService, { write: async () => {}, }); @@ -131,36 +124,19 @@ function createHarness( } else { reg.defineInstance(IAgentToolExecutorService, events.executor); } - reg.defineInstance(IAgentScopeContext, { - _serviceBrand: undefined, - agentId: 'main', - agentContext: stubAgentContext('main', 0), - scope: (sub?: string): string => (sub ? `agents/main/${sub}` : 'agents/main'), - } satisfies IAgentScopeContext); - const dispatcher: IEventDispatcher = { + const wire: IWireService = { _serviceBrand: undefined, hooks: { onDidRestore: new OrderedHookSlot() }, - dispatch: async () => {}, - } as unknown as IEventDispatcher; - reg.defineInstance(IEventDispatcher, dispatcher); + dispatch: () => {}, + seal: async () => {}, + restore: async () => {}, + flush: async () => {}, + getModel: () => + options.restoredProfile ?? { systemPrompt: '', agentsMdPaths: undefined }, + } as unknown as IWireService; + reg.defineInstance(IWireService, wire); reg.defineInstance(IBootstrapService, { homeDir } as unknown as IBootstrapService); - const agentState = new AgentStateService(); - agentState.contributeState(profileKey); - agentState.set(profileKey, { - thinkingLevel: 'off', - renderGeneration: 0, - systemPrompt: options.restoredProfile?.systemPrompt ?? '', - agentsMdPaths: options.restoredProfile?.agentsMdPaths, - }); - reg.defineInstance(IAgentStateService, agentState); - reg.defineInstance( - IAgentLifecycleService, - lifecycleWithReminder(createReminderStub({ - notify: (content, notification) => { - reminders.push({ content, origin: { kind: 'injection', ...notification } }); - }, - })), - ); + reg.defineInstance(IAgentStateService, new AgentStateService()); reg.defineInstance(ISessionContext, { _serviceBrand: undefined, sessionId: 'session-1', @@ -171,52 +147,12 @@ function createHarness( scope: (sub?: string): string => sub ? `sessions/workspace-1/session-1/${sub}` : 'sessions/workspace-1/session-1', } satisfies ISessionContext); - reg.defineInstance(ISessionInstructionsProvider, { - _serviceBrand: undefined, - ready: Promise.resolve(), - agentsMd: undefined, - agentsMdWarning: undefined, - agentsMdPaths: undefined, - onDidChange: instructionsChange.event, - } satisfies ISessionInstructionsProvider); - const hostFs = options.hostFs ?? new HostFileSystem(); - const hostEnvironment = { + reg.defineInstance(IHostFileSystem, options.hostFs ?? new HostFileSystem()); + reg.defineInstance(IHostEnvironment, { _serviceBrand: undefined, homeDir, pathClass: options.pathClass ?? 'posix', - } as unknown as IHostEnvironment; - reg.defineInstance(IHostFileSystem, hostFs); - reg.defineInstance(IHostEnvironment, hostEnvironment); - reg.defineInstance(IAgentRuntimeService, { - _serviceBrand: undefined, - onDidChange: () => ({ dispose: () => {} }), - isAvailable: () => true, - inspect() { return this.acquire().runtime; }, - acquire: (): RuntimeLease => ({ - runtime: { - identity: { workspaceId: 'workspace-1', runtimeId: 'local', generation: 'test' }, - capabilities: new Set(['fs', 'watch', 'process', 'terminal']), - environment: hostEnvironment, - path: { - separator: options.pathClass === 'win32' ? '\\' : '/', - delimiter: options.pathClass === 'win32' ? ';' : ':', - isAbsolute: (path: string) => path.startsWith('/') || /^[A-Za-z]:[\\\\]/.test(path), - join, - relative: (from: string, to: string) => normalize(to).replace(`${normalize(from)}/`, ''), - resolve: (...paths: readonly string[]) => normalize(join(...paths)), - basename: (path: string) => basename(path), - dirname: (path: string) => dirname(path), - }, - workspace: { mapRoots: (roots) => roots }, - fs: hostFs, - status: 'ready', - onDidChangeStatus: () => ({ dispose: () => {} }), - dispose: () => {}, - }, - track: (resource) => resource, - dispose: () => {}, - }), - } satisfies IAgentRuntimeService); + } as unknown as IHostEnvironment); reg.defineInstance(IBashParserService, new BashParserService()); reg.defineInstance( ITelemetryService, @@ -231,8 +167,8 @@ function createHarness( strict: true, }); const reminder = ix.get(IAgentAgentsMdReminderService); - const dispatcher = ix.get(IEventDispatcher); - return { ix, events, reminder, dispatcher, telemetryEvents, reminders, instructionsChange }; + const wire = ix.get(IWireService); + return { ix, events, reminder, wire, telemetryEvents }; } function didCtx( @@ -279,6 +215,23 @@ function testAccesses(name: string, args: unknown): ToolAccessesType | undefined return undefined; } +function willCtx(id: string, name: string, args: unknown): ResolvedToolExecutionHookContext { + const toolCall: ToolCall = { + type: 'function', + id, + name, + arguments: JSON.stringify(args), + }; + return { + turnId: 1, + signal: new AbortController().signal, + toolCall, + toolCalls: [toolCall], + args, + execution: { approvalRule: 'x', execute: async () => ({ output: '' }) }, + }; +} + async function fire(h: Harness, ctx: ToolDidExecuteContext): Promise { await h.events.didExecuteSlot.run(ctx); return ctx.result; @@ -293,10 +246,6 @@ function outputText(result: ExecutableToolResult): string { .join(''); } -function reminderText(h: Harness): string { - return h.reminders.map((entry) => entry.content).join('\n'); -} - async function writeAgentsMd(dir: string, content = 'instructions'): Promise { await mkdir(dir, { recursive: true }); const path = join(dir, 'AGENTS.md'); @@ -304,54 +253,6 @@ async function writeAgentsMd(dir: string, content = 'instructions'): Promise { - it('appends a path-announcement reminder when an injected AGENTS.md changes on disk', async () => { - const h = createHarness(); - const rootAgentsMd = await writeAgentsMd(workDir, 'root instructions'); - h.reminder.seedInjected([rootAgentsMd], workDir); - - h.instructionsChange.fire([{ path: rootAgentsMd, action: 'modified', kind: 'file' }]); - - expect(h.reminders).toHaveLength(1); - expect(h.reminders[0]?.origin).toEqual({ kind: 'injection', variant: 'agents_md_change' }); - expect(h.reminders[0]?.content).toContain(rootAgentsMd); - expect(h.reminders[0]?.content).toContain('stale'); - }); - - it('marks deleted AGENTS.md files in the announcement', async () => { - const h = createHarness(); - const rootAgentsMd = await writeAgentsMd(workDir, 'root instructions'); - h.reminder.seedInjected([rootAgentsMd], workDir); - - h.instructionsChange.fire([{ path: rootAgentsMd, action: 'deleted', kind: 'file' }]); - - expect(h.reminders).toHaveLength(1); - expect(h.reminders[0]?.content).toContain(`${rootAgentsMd} (deleted)`); - }); - - it('stays silent when the agent has not been seeded yet', async () => { - const h = createHarness(); - - h.instructionsChange.fire([ - { path: join(workDir, 'AGENTS.md'), action: 'modified', kind: 'file' }, - ]); - - expect(h.reminders).toHaveLength(0); - }); - - it('adds announced paths to the known set so discovery does not repeat them', async () => { - const h = createHarness(); - const rootAgentsMd = await writeAgentsMd(workDir, 'root instructions'); - h.reminder.seedInjected([], workDir); - - h.instructionsChange.fire([{ path: rootAgentsMd, action: 'created', kind: 'file' }]); - - expect(h.reminders).toHaveLength(1); - const known = h.ix.get(IAgentStateService).get(agentsMdReminderKnownKey); - expect(known.has(normalize(rootAgentsMd))).toBe(true); - }); -}); - describe('agentsMdReminder path-carrying tools', () => { it('appends a reminder listing the uninjected AGENTS.md when Read touches its directory', async () => { const h = createHarness(); @@ -362,14 +263,9 @@ describe('agentsMdReminder path-carrying tools', () => { const result = await fire(h, didCtx('Read', { path: join(subDir, 'src', 'index.ts') })); - expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(1); - expect(h.reminders[0]?.origin).toEqual({ kind: 'injection', variant: 'agents_md' }); - expect(h.reminders[0]?.content.startsWith('The path(s) touched by a recent tool call')).toBe( - true, - ); - expect(h.reminders[0]?.content).not.toContain(''); - const text = reminderText(h); + const text = outputText(result); + expect(text).toContain('original result'); + expect(text).toContain(''); expect(text).toContain(subAgentsMd); expect(text).not.toContain(rootAgentsMd); }); @@ -382,10 +278,8 @@ describe('agentsMdReminder path-carrying tools', () => { const first = await fire(h, didCtx('Read', { path: join(subDir, 'a.ts') })); const second = await fire(h, didCtx('Edit', { path: join(subDir, 'b.ts') })); - expect(outputText(first)).toBe('original result'); - expect(outputText(second)).toBe('original result'); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(first)).toContain(subAgentsMd); + expect(outputText(second)).not.toContain(''); }); it('marks an AGENTS.md known when read directly and never suggests it afterwards', async () => { @@ -394,12 +288,10 @@ describe('agentsMdReminder path-carrying tools', () => { const subAgentsMd = await writeAgentsMd(subDir); const direct = await fire(h, didCtx('Read', { path: subAgentsMd })); - expect(outputText(direct)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(direct)).not.toContain(''); const after = await fire(h, didCtx('Read', { path: join(subDir, 'src', 'index.ts') })); - expect(outputText(after)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(after)).not.toContain(subAgentsMd); }); it('discovers the .kimi-code/AGENTS.md variant alongside the plain one', async () => { @@ -411,8 +303,7 @@ describe('agentsMdReminder path-carrying tools', () => { const result = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(dotKimi); expect(text).toContain(plain); }); @@ -420,6 +311,7 @@ describe('agentsMdReminder path-carrying tools', () => { it('anchors at the nearest existing ancestor when Write targets a not-yet-created directory', async () => { const h = createHarness(); const rootAgentsMd = await writeAgentsMd(workDir, 'root instructions'); + // The root file was created after the bind injected nothing. h.reminder.seedInjected([], workDir); const result = await fire( @@ -427,8 +319,7 @@ describe('agentsMdReminder path-carrying tools', () => { didCtx('Write', { path: join(workDir, 'new-pkg', 'src', 'index.ts'), content: 'x' }), ); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(rootAgentsMd); + expect(outputText(result)).toContain(rootAgentsMd); }); it('does not remind for seeded paths on the injected chain', async () => { @@ -438,8 +329,7 @@ describe('agentsMdReminder path-carrying tools', () => { const result = await fire(h, didCtx('Glob', { pattern: '**/*.ts' })); - expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(result)).not.toContain(''); }); it('tracks the shown event through telemetry', async () => { @@ -466,8 +356,7 @@ describe('agentsMdReminder Bash coverage', () => { const result = await fire(h, didCtx('Bash', { command: 'ls packages/kap-server' })); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('rebases relative operands across a literal cd', async () => { @@ -476,8 +365,7 @@ describe('agentsMdReminder Bash coverage', () => { const result = await fire(h, didCtx('Bash', { command: 'cd packages && ls kap-server' })); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('extracts find roots and stops at the expression', async () => { @@ -489,8 +377,7 @@ describe('agentsMdReminder Bash coverage', () => { didCtx('Bash', { command: "find packages/kap-server -name '*.ts'" }), ); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('extracts quoted directory operands', async () => { @@ -499,8 +386,7 @@ describe('agentsMdReminder Bash coverage', () => { const result = await fire(h, didCtx('Bash', { command: 'ls "packages/kap-server"' })); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('probes an explicit cwd even when the command lists nothing', async () => { @@ -512,8 +398,7 @@ describe('agentsMdReminder Bash coverage', () => { didCtx('Bash', { command: 'git status', cwd: 'packages/kap-server' }), ); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('skips operands that are not statically resolvable', async () => { @@ -522,14 +407,13 @@ describe('agentsMdReminder Bash coverage', () => { for (const command of ['ls $DIR', 'ls *.ts', 'ls $(pwd)', 'echo packages/kap-server']) { const result = await fire(h, didCtx('Bash', { command })); - expect(outputText(result)).toBe('original result'); + expect(outputText(result)).not.toContain(''); } - expect(h.reminders).toHaveLength(0); }); }); describe('agentsMdReminder result shapes and edge cases', () => { - it('leaves ContentPart[] results untouched and enqueues the reminder', async () => { + it('prepends the reminder to the first text part of ContentPart[] outputs', async () => { const h = createHarness(); const subAgentsMd = await writeAgentsMd(join(workDir, 'packages', 'kap-server')); @@ -542,9 +426,10 @@ describe('agentsMdReminder result shapes and edge cases', () => { ), ); - expect(result.output).toEqual([{ type: 'text', text: 'part one' }]); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + expect(Array.isArray(result.output)).toBe(true); + expect(outputText(result).startsWith('')).toBe(true); + expect(outputText(result)).toContain('part one'); + expect(outputText(result)).toContain(subAgentsMd); }); it('does not mark an AGENTS.md known when the direct read failed', async () => { @@ -556,29 +441,33 @@ describe('agentsMdReminder result shapes and edge cases', () => { h, didCtx('Read', { path: agentsMdPath }, { result: { output: 'not found', isError: true } }), ); - expect(outputText(failed)).toBe('not found'); - expect(h.reminders).toHaveLength(0); + expect(outputText(failed)).not.toContain(''); await writeAgentsMd(subDir); const after = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(after)).toBe('original result'); - expect(reminderText(h)).toContain(agentsMdPath); + expect(outputText(after)).toContain(agentsMdPath); }); }); -describe('agentsMdReminder duplicate calls', () => { - it('reminds exactly once for two same-step calls touching the same directory', async () => { - const h = createHarness(); +describe('agentsMdReminder toolDedupe interplay', () => { + it('delivers the reminder through a same-step duplicate resolved by toolDedupe', async () => { + const h = createHarness({ withDedupe: true }); + h.ix.get(IAgentToolDedupeService); const subAgentsMd = await writeAgentsMd(join(workDir, 'packages', 'kap-server')); const args = { path: join(workDir, 'packages', 'kap-server', 'index.ts') }; - const first = await fire(h, didCtx('Read', args, { id: 'call-1' })); - const second = await fire(h, didCtx('Read', args, { id: 'call-2' })); + await h.events.fireBeforeExecute(willCtx('call-1', 'Read', args)); + const did1 = didCtx('Read', args, { id: 'call-1' }); + await h.events.didExecuteSlot.run(did1); + expect(outputText(did1.result)).toContain(subAgentsMd); - expect(outputText(first)).toBe('original result'); - expect(outputText(second)).toBe('original result'); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + const decision = await h.events.fireBeforeExecute(willCtx('call-2', 'Read', args)); + const did2 = didCtx('Read', args, { + id: 'call-2', + result: decision?.veto ?? { output: '' }, + }); + await h.events.didExecuteSlot.run(did2); + expect(outputText(did2.result)).toContain(subAgentsMd); }); it('leaves the vetoed placeholder untouched and reminds exactly once on the visible results', async () => { @@ -614,10 +503,10 @@ describe('agentsMdReminder duplicate calls', () => { expect(results).toHaveLength(2); for (const item of results) { - expect(outputText(item.result)).toBe('file contents'); + const text = outputText(item.result); + expect(text).toContain('file contents'); + expect(text).toContain(subAgentsMd); } - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); const shown = h.telemetryEvents.filter((e) => e.event === 'agents_md_reminder_shown'); expect(shown).toHaveLength(1); }); @@ -634,20 +523,19 @@ describe('agentsMdReminder lazy seeding after a restore', () => { didCtx('Read', { path: join(workDir, 'packages', 'kap-server', 'index.ts') }), ); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(subAgentsMd); expect(text).not.toContain(rootAgentsMd); }); it('treats the brand-home AGENTS.md as injected after a restore', async () => { const h = createHarness(); - await writeAgentsMd(homeDir, 'brand instructions'); + const brandAgentsMd = await writeAgentsMd(homeDir, 'brand instructions'); const result = await fire(h, didCtx('Read', { path: join(homeDir, 'notes.txt') })); expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(result)).not.toContain(brandAgentsMd); expect(h.telemetryEvents).toHaveLength(0); }); }); @@ -664,11 +552,10 @@ describe('agentsMdReminder persisted restore provenance', () => { }, }); - await h.dispatcher.hooks.onDidRestore.run({}); + await h.wire.hooks.onDidRestore.run({}); const result = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('recovers injected paths from a legacy restored prompt without path provenance', async () => { @@ -679,11 +566,10 @@ describe('agentsMdReminder persisted restore provenance', () => { }, }); - await h.dispatcher.hooks.onDidRestore.run({}); + await h.wire.hooks.onDidRestore.run({}); const result = await fire(h, didCtx('Read', { path: join(workDir, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(result)).not.toContain(''); }); }); @@ -695,8 +581,7 @@ describe('agentsMdReminder Bash operand hygiene', () => { const result = await fire(h, didCtx('Bash', { command: 'ls -w 80 packages/kap-server' })); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(subAgentsMd); expect(text).not.toContain(eighty); }); @@ -710,8 +595,7 @@ describe('agentsMdReminder Bash operand hygiene', () => { didCtx('Bash', { command: "find -L packages/kap-server -name '*.ts'" }), ); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); }); @@ -724,8 +608,7 @@ describe('agentsMdReminder probing boundaries', () => { const result = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(result)).not.toContain(''); }); it('still reminds when the triggering call ended in an error result', async () => { @@ -740,8 +623,7 @@ describe('agentsMdReminder probing boundaries', () => { }), ); - expect(outputText(result)).toBe('not found'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('marks an AGENTS.md known when it is written directly', async () => { @@ -751,12 +633,10 @@ describe('agentsMdReminder probing boundaries', () => { const agentsMdPath = normalize(join(subDir, 'AGENTS.md')); const written = await fire(h, didCtx('Write', { path: agentsMdPath, content: 'x' })); - expect(outputText(written)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(written)).not.toContain(''); const after = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(after)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(after)).not.toContain(agentsMdPath); }); it('reminds at most once for two parallel touches of the same directory', async () => { @@ -769,9 +649,10 @@ describe('agentsMdReminder probing boundaries', () => { fire(h, didCtx('Read', { path: join(subDir, 'b.ts') }, { id: 'call-b' })), ]); - expect(outputText(first)).toBe('original result'); - expect(outputText(second)).toBe('original result'); - expect(h.reminders).toHaveLength(1); + const reminders = [first, second].filter((result) => + outputText(result).includes(''), + ); + expect(reminders).toHaveLength(1); }); it('re-judges the project root at a nested repository', async () => { @@ -783,8 +664,7 @@ describe('agentsMdReminder probing boundaries', () => { const result = await fire(h, didCtx('Read', { path: join(nested, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(nestedAgentsMd); expect(text).not.toContain(rootAgentsMd); }); @@ -799,8 +679,7 @@ describe('agentsMdReminder probing boundaries', () => { try { const result = await fire(h, didCtx('Read', { path: join(leaf, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(leafAgentsMd); expect(text).not.toContain(outerAgentsMd); } finally { @@ -817,8 +696,7 @@ describe('agentsMdReminder probing boundaries', () => { try { const result = await fire(h, didCtx('Read', { path: join(workDir, 'link', 'index.ts') })); - expect(outputText(result)).toBe('original result'); - const text = reminderText(h); + const text = outputText(result); expect(text).toContain(normalize(join(workDir, 'link', 'AGENTS.md'))); expect(text).not.toContain(targetAgentsMd); } finally { @@ -839,7 +717,6 @@ describe('agentsMdReminder round-2 hardening', () => { ); expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); expect(h.telemetryEvents).toHaveLength(0); }); @@ -852,11 +729,9 @@ describe('agentsMdReminder round-2 hardening', () => { const result = await fire(h, didCtx('Bash', { command: 'true' })); expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); const listed = await fire(h, didCtx('Bash', { command: 'ls packages' })); - expect(outputText(listed)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(listed)).toContain(subAgentsMd); }); it('ignores a whitespace-only AGENTS.md just like the init-time load', async () => { @@ -867,8 +742,7 @@ describe('agentsMdReminder round-2 hardening', () => { const result = await fire(h, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); + expect(outputText(result)).not.toContain(''); }); it('keeps known-sets isolated between agents', async () => { @@ -880,12 +754,8 @@ describe('agentsMdReminder round-2 hardening', () => { const firstResult = await fire(first, didCtx('Read', { path: join(subDir, 'index.ts') })); const secondResult = await fire(second, didCtx('Read', { path: join(subDir, 'index.ts') })); - expect(outputText(firstResult)).toBe('original result'); - expect(outputText(secondResult)).toBe('original result'); - expect(first.reminders).toHaveLength(1); - expect(second.reminders).toHaveLength(1); - expect(reminderText(first)).toContain(subAgentsMd); - expect(reminderText(second)).toContain(subAgentsMd); + expect(outputText(firstResult)).toContain(subAgentsMd); + expect(outputText(secondResult)).toContain(subAgentsMd); }); it('releases the claim when attaching the reminder fails, so the next touch retries', async () => { @@ -902,16 +772,26 @@ describe('agentsMdReminder round-2 hardening', () => { const failed = await fire(h, didCtx('Read', { path: join(subDir, 'a.ts') })); expect(outputText(failed)).toBe('original result'); - expect(h.reminders).toHaveLength(0); shouldThrow = false; const retried = await fire(h, didCtx('Read', { path: join(subDir, 'b.ts') })); - expect(outputText(retried)).toBe('original result'); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(retried)).toContain(subAgentsMd); }); - it('leaves oversized results to the truncation pipeline and enqueues the reminder instead', async () => { + it('prepends the reminder so it survives head-only truncation', async () => { + const h = createHarness(); + const subAgentsMd = await writeAgentsMd(join(workDir, 'packages', 'kap-server')); + + const result = await fire( + h, + didCtx('Read', { path: join(workDir, 'packages', 'kap-server', 'index.ts') }), + ); + + expect(outputText(result).startsWith('')).toBe(true); + expect(outputText(result)).toContain(subAgentsMd); + }); + + it('survives the real executor pipeline with oversized results', async () => { const h = createHarness({ withRealExecutor: true }); const subAgentsMd = await writeAgentsMd(join(workDir, 'packages', 'kap-server')); @@ -947,10 +827,8 @@ describe('agentsMdReminder round-2 hardening', () => { expect(typeof output).toBe('string'); const text = output as string; expect(text).toContain('output_path:'); - expect(text).not.toContain(''); - expect(text).not.toContain(subAgentsMd); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + expect(text.indexOf('')).toBeLessThan(2_000); + expect(text).toContain(subAgentsMd); }); it('uses the resolved file access instead of reparsing the raw path', async () => { @@ -989,15 +867,13 @@ describe('agentsMdReminder round-2 hardening', () => { } expect(results).toHaveLength(1); - expect(outputText(results[0]!.result)).toBe('home file contents'); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(homeAgentsMd); + expect(outputText(results[0]!.result)).toContain(homeAgentsMd); }); it('does not probe or remind when permission vetoes an access-bearing call', async () => { const h = createHarness({ withRealExecutor: true }); const subDir = join(workDir, 'packages', 'kap-server'); - await writeAgentsMd(subDir); + const subAgentsMd = await writeAgentsMd(subDir); const hostFs = h.ix.get(IHostFileSystem); const stat = vi.spyOn(hostFs, 'stat'); const readText = vi.spyOn(hostFs, 'readText'); @@ -1039,7 +915,7 @@ describe('agentsMdReminder round-2 hardening', () => { expect(results).toHaveLength(1); expect(outputText(results[0]!.result)).toBe('permission denied'); - expect(h.reminders).toHaveLength(0); + expect(outputText(results[0]!.result)).not.toContain(subAgentsMd); expect(stat).not.toHaveBeenCalled(); expect(readText).not.toHaveBeenCalled(); expect( @@ -1129,7 +1005,7 @@ describe('agentsMdReminder cancellation outcomes', () => { const results = await pending; const queued = results.find((item) => item.toolCallId === 'call-queued-read'); expect(queued).toBeDefined(); - expect(h.reminders).toHaveLength(0); + expect(outputText(queued!.result)).not.toContain(''); expect( h.telemetryEvents.filter((event) => event.event === 'agents_md_reminder_shown'), ).toEqual([]); @@ -1151,9 +1027,7 @@ describe('agentsMdReminder cancellation outcomes', () => { )) { real.push(item); } - expect(outputText(real[0]!.result)).toBe('read result'); - expect(h.reminders).toHaveLength(1); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(real[0]!.result)).toContain(subAgentsMd); }); }); @@ -1167,8 +1041,7 @@ describe('agentsMdReminder Bash parse degradation', () => { didCtx('Bash', { command: "ls '", cwd: 'packages/kap-server' }), ); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(subAgentsMd); + expect(outputText(result)).toContain(subAgentsMd); }); it('skips entirely when an unparseable command has no explicit cwd', async () => { @@ -1178,7 +1051,6 @@ describe('agentsMdReminder Bash parse degradation', () => { const result = await fire(h, didCtx('Bash', { command: "ls '" })); expect(outputText(result)).toBe('original result'); - expect(h.reminders).toHaveLength(0); }); }); @@ -1222,8 +1094,7 @@ describe('agentsMdReminder Windows Bash paths', () => { const result = await fire(h, didCtx('Bash', args)); - expect(outputText(result)).toBe('original result'); - expect(reminderText(h)).toContain(agentsMdPath); + expect(outputText(result)).toContain(agentsMdPath); } }); }); diff --git a/packages/agent-core-v2/test/agent/blob/agentBlobService.test.ts b/packages/agent-core-v2/test/agent/blob/agentBlobService.test.ts index 1b6187b41..037a1bf4d 100644 --- a/packages/agent-core-v2/test/agent/blob/agentBlobService.test.ts +++ b/packages/agent-core-v2/test/agent/blob/agentBlobService.test.ts @@ -1,3 +1,21 @@ +/** + * Scenario: the agent blob service offloads large inline media (data URIs) into + * content-addressed blobs and loads them back on read. + * + * Responsibilities asserted: + * - sub-threshold data URIs pass through unchanged (and keep the same array ref) + * - large data URIs become `blobref:` URLs and are persisted under the agent scope + * - offload is non-mutating, idempotent, and handles every media container + * - load restores blobrefs, leaves other URLs alone, and substitutes a + * placeholder when the blob is missing + * - content-addressing deduplicates identical payloads and isolates per agent + * + * Wiring: real `BlobStoreService` over the in-memory storage backend, with the + * service resolved through the DI scope tree — no stubbed boundary, no real fs. + * + * Run: `pnpm test -- test/blob/agentBlobService.test.ts` + */ + import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import type { ContentPart } from '#/kosong/contract/message'; diff --git a/packages/agent-core-v2/test/agent/blob/byteLruCache.test.ts b/packages/agent-core-v2/test/agent/blob/byteLruCache.test.ts index 28cae218d..a4c380805 100644 --- a/packages/agent-core-v2/test/agent/blob/byteLruCache.test.ts +++ b/packages/agent-core-v2/test/agent/blob/byteLruCache.test.ts @@ -1,3 +1,14 @@ +/** + * Scenario: the byte-bounded LRU cache used by the agent blob service. + * + * Responsibilities asserted: hit returns the stored value, miss is undefined, + * least-recently-used eviction on overflow, recency refresh on get, oversize + * payloads are never cached, replacement re-accounts size, and multiple entries + * evict to make room. Pure data-structure tests — no DI, no IO. + * + * Run: `pnpm test -- test/blob/byteLruCache.test.ts` + */ + import { describe, expect, it } from 'vitest'; import { ByteLruCache } from '#/agent/blob/byteLruCache'; diff --git a/packages/agent-core-v2/test/agent/contextInjector/contextInjector.test.ts b/packages/agent-core-v2/test/agent/contextInjector/contextInjector.test.ts new file mode 100644 index 000000000..ea376e9e9 --- /dev/null +++ b/packages/agent-core-v2/test/agent/contextInjector/contextInjector.test.ts @@ -0,0 +1,329 @@ +/** + * Scenario: agent context injection position tracking and wire restoration. + * + * Exercises the real injector through its service contract with in-memory + * context, loop, reminder, event-bus, and wire collaborators. + * Run: `pnpm --filter @moonshot-ai/agent-core-v2 exec vitest run + * test/agent/contextInjector/contextInjector.test.ts`. + */ + +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; + +import { DisposableStore } from '#/_base/di/lifecycle'; +import { + createServices, + type TestInstantiationService, +} from '#/_base/di/test'; +import { IAgentContextInjectorService } from '#/agent/contextInjector/contextInjector'; +import { AgentContextInjectorService } from '#/agent/contextInjector/contextInjectorService'; +import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; +import type { ContextMessage } from '#/agent/contextMemory/types'; +import { IAgentLoopService } from '#/agent/loop/loop'; +import { IAgentProfileService } from '#/agent/profile/profile'; +import { IAgentStateService } from '#/agent/state/agentState'; +import { AgentStateService } from '#/agent/state/agentStateService'; +import { IAgentSystemReminderService } from '#/agent/systemReminder/systemReminder'; +import { AgentSystemReminderService } from '#/agent/systemReminder/systemReminderService'; +import { IEventBus } from '#/app/event/eventBus'; +import { IWireService } from '#/wire/wire'; +import { registerContextMemoryServices, type StubContextMemory } from '../contextMemory/stubs'; +import { + runWillBeginStepHooks, + type StubLoop, + stubLoopWithHooks, + stubWire, +} from '../loop/stubs'; + +function injector(ix: TestInstantiationService): IAgentContextInjectorService { + return ix.get(IAgentContextInjectorService); +} + +function userMessage(text: string): ContextMessage { + return { + role: 'user', + content: [{ type: 'text', text }], + toolCalls: [], + origin: { kind: 'user' }, + }; +} + +function compactionSummary(text: string): ContextMessage { + return { + role: 'user', + content: [{ type: 'text', text }], + toolCalls: [], + origin: { kind: 'compaction_summary' }, + }; +} + +function lastText(context: IAgentContextMemoryService): string | undefined { + const message = context.get().at(-1); + const part = message?.content[0]; + return part?.type === 'text' ? part.text : undefined; +} + +describe('AgentContextInjectorService', () => { + let disposables: DisposableStore; + let ix: TestInstantiationService; + let context: IAgentContextMemoryService; + let loop: StubLoop; + + beforeEach(() => { + disposables = new DisposableStore(); + loop = stubLoopWithHooks(); + ix = createServices(disposables, { + base: [registerContextMemoryServices], + strict: true, + additionalServices: (reg) => { + reg.defineInstance(IAgentLoopService, loop); + reg.defineInstance(IWireService, stubWire()); + reg.defineInstance(IAgentStateService, new AgentStateService()); + reg.define(IAgentSystemReminderService, AgentSystemReminderService); + reg.define(IAgentContextInjectorService, AgentContextInjectorService); + }, + }); + context = ix.get(IAgentContextMemoryService); + }); + + afterEach(() => { + disposables.dispose(); + }); + + async function runInjectionStep(): Promise { + await runWillBeginStepHooks(loop); + } + + function spliceContext( + start: number, + deleteCount: number, + inserted: readonly ContextMessage[], + ): void { + const backing = (context as StubContextMemory).messages as ContextMessage[]; + backing.splice(start, deleteCount, ...inserted); + ix.get(IEventBus).publish({ + type: 'context.spliced', + start, + deleteCount, + messages: [...inserted], + }); + } + + it('registers providers and appends injection messages with the provider variant', async () => { + const seen: Array = []; + + injector(ix).register('recording_test', ({ lastInjectedAt }) => { + seen.push(lastInjectedAt); + return 'recorded reminder'; + }); + + await runInjectionStep(); + + expect(seen).toEqual([null]); + expect(lastText(context)).toContain(''); + expect(lastText(context)).toContain('recorded reminder'); + expect(context.get().at(-1)?.origin).toEqual({ + kind: 'injection', + variant: 'recording_test', + }); + }); + + it('persists provider disclosure metadata on the injected message origin', async () => { + injector(ix).register('date_test', () => ({ + content: 'date reminder', + disclosure: { + kind: 'date', + renderGeneration: 4, + localDate: '2026-07-29', + timeZone: 'Asia/Shanghai', + }, + })); + + await runInjectionStep(); + + expect(context.get().at(-1)?.origin).toEqual({ + kind: 'injection', + variant: 'date_test', + disclosure: { + kind: 'date', + renderGeneration: 4, + localDate: '2026-07-29', + timeZone: 'Asia/Shanghai', + }, + }); + }); + + it('appends provider content parts verbatim without system-reminder wrapping', async () => { + injector(ix).register('media_test', () => [ + { type: 'text', text: 'caption' }, + { type: 'image_url', imageUrl: { url: 'https://example.com/a.png' } }, + ]); + + await runInjectionStep(); + + const message = context.get().at(-1); + expect(message?.content).toEqual([ + { type: 'text', text: 'caption' }, + { type: 'image_url', imageUrl: { url: 'https://example.com/a.png' } }, + ]); + expect(message?.origin).toEqual({ kind: 'injection', variant: 'media_test' }); + }); + + it('skips injection when the provider returns an empty content array', async () => { + injector(ix).register('empty_test', () => []); + + await runInjectionStep(); + + expect(context.get()).toHaveLength(0); + }); + + it('passes the previous injection index back to the provider', async () => { + const seen: Array = []; + + injector(ix).register('recording_test', ({ lastInjectedAt }) => { + seen.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder' : undefined; + }); + + await runInjectionStep(); + await runInjectionStep(); + + expect(seen).toEqual([null, 0]); + expect(context.get()).toHaveLength(1); + }); + + it('exposes all live injection positions alongside the newest one', async () => { + const seen: Array = []; + + injector(ix).register('recording_test', ({ injectedPositions, lastInjectedAt }) => { + seen.push(injectedPositions); + expect(lastInjectedAt).toBe(injectedPositions.at(-1) ?? null); + return seen.length <= 2 ? 'recorded reminder' : undefined; + }); + + await runInjectionStep(); + spliceContext(1, 0, [userMessage('between reminders')]); + await runInjectionStep(); + await runInjectionStep(); + + expect(seen).toEqual([[], [0], [0, 2]]); + }); + + it('falls back to the previous surviving copy when the newest injection is deleted', async () => { + const seen: Array = []; + + injector(ix).register('recording_test', ({ lastInjectedAt }) => { + seen.push(lastInjectedAt); + return seen.length <= 2 ? 'recorded reminder' : undefined; + }); + + await runInjectionStep(); + spliceContext(1, 0, [userMessage('between reminders')]); + await runInjectionStep(); + spliceContext(2, 1, []); + await runInjectionStep(); + + expect(seen).toEqual([null, 0, 0]); + expect(context.get().map((message) => message.origin?.kind)).toEqual([ + 'injection', + 'user', + ]); + }); + + it('resets every stored injection index after context clear', async () => { + const seenA: Array = []; + const seenB: Array = []; + + injector(ix).register('recording_a', ({ lastInjectedAt }) => { + seenA.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder A' : undefined; + }); + injector(ix).register('recording_b', ({ lastInjectedAt }) => { + seenB.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder B' : undefined; + }); + + await runInjectionStep(); + spliceContext(0, context.get().length, []); + await runInjectionStep(); + + expect(seenA).toEqual([null, null]); + expect(seenB).toEqual([null, null]); + expect(context.get().map((message) => message.origin)).toEqual([ + { kind: 'injection', variant: 'recording_a' }, + { kind: 'injection', variant: 'recording_b' }, + ]); + }); + + it('re-injects at the next step after compaction swallows the reminder', async () => { + const seen: Array = []; + + context.append(userMessage('before reminder')); + injector(ix).register('recording_test', ({ lastInjectedAt }) => { + seen.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder' : undefined; + }); + + await runInjectionStep(); + spliceContext( + 0, + 2, + [compactionSummary('Compacted summary.')], + ); + await runInjectionStep(); + + expect(seen).toEqual([null, null]); + expect(context.get().map((message) => message.origin)).toEqual([ + { kind: 'compaction_summary' }, + { kind: 'injection', variant: 'recording_test' }, + ]); + }); + + it('keeps every injection index aligned after compaction preserves injected messages', async () => { + const seenA: Array = []; + const seenB: Array = []; + + context.append( + userMessage('old request'), + userMessage('old follow-up'), + ); + injector(ix).register('recording_a', ({ lastInjectedAt }) => { + seenA.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder A' : undefined; + }); + injector(ix).register('recording_b', ({ lastInjectedAt }) => { + seenB.push(lastInjectedAt); + return lastInjectedAt === null ? 'recorded reminder B' : undefined; + }); + + await runInjectionStep(); + spliceContext(0, 2, [compactionSummary('Compacted summary.')]); + await runInjectionStep(); + + expect(seenA).toEqual([null, 1]); + expect(seenB).toEqual([null, 2]); + expect(context.get().map((message) => message.origin)).toEqual([ + { kind: 'compaction_summary' }, + { kind: 'injection', variant: 'recording_a' }, + { kind: 'injection', variant: 'recording_b' }, + ]); + }); + + it('re-arms per-turn providers when injectAfterCompaction runs', async () => { + const seen: boolean[] = []; + injector(ix).register('per_turn_test', ({ isNewTurn }) => { + seen.push(isNewTurn); + return isNewTurn ? 'per-turn reminder' : undefined; + }); + + await runInjectionStep(); + await runInjectionStep(); + spliceContext(0, 1, [compactionSummary('Compacted summary.')]); + await injector(ix).injectAfterCompaction(); + + expect(seen).toEqual([true, false, true]); + expect(context.get().map((message) => message.origin)).toEqual([ + { kind: 'compaction_summary' }, + { kind: 'injection', variant: 'per_turn_test' }, + ]); + }); +}); diff --git a/packages/agent-core-v2/test/agent/contextMemory/context.test.ts b/packages/agent-core-v2/test/agent/contextMemory/context.test.ts index 9e5860081..0b3b2ca20 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/context.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/context.test.ts @@ -1,4 +1,4 @@ -import type { Message, ToolCall } from '#/kosong/contract/message'; +import type { Message } from '#/kosong/contract/message'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { estimateTokens, estimateTokensForMessages } from '#/kosong/contract/tokens'; @@ -11,13 +11,10 @@ import { type TokenEstimate, } from '#/agent/contextMemory/compactionHandoff'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { - closeTrailingOpenToolExchange, - INHERITED_IN_FLIGHT_TOOL_OUTPUT, -} from '#/agent/contextMemory/openToolExchange'; import { IWireService } from '#/wire/wire'; import { IAgentContextMemoryService, + IAgentTokenCountingService, IAgentProfileService, } from '#/index'; @@ -26,14 +23,14 @@ import { createTestAgent, type TestAgentContext } from '../../harness'; describe('Agent context', () => { let ctx: TestAgentContext; let context: IAgentContextMemoryService; - let tokenCounting: TestAgentContext['tokenCounting']; + let tokenCounting: IAgentTokenCountingService; let profile: IAgentProfileService; let wire: IWireService; beforeEach(() => { ctx = createTestAgent(); context = ctx.get(IAgentContextMemoryService); - tokenCounting = ctx.tokenCounting; + tokenCounting = ctx.get(IAgentTokenCountingService); profile = ctx.get(IAgentProfileService); wire = ctx.get(IWireService); }); @@ -599,6 +596,8 @@ describe('Agent context', () => { const surviving = context.get(); expect(surviving.map((m) => m.role)).toEqual(['user', 'assistant']); + // The first exchange's anchor survives the cut, so the prefix reads its + // REAL measured size instead of a re-estimate. expect(tokenCounting.get()).toEqual({ size: 1_000, measured: 1_000, estimated: 0 }); }); @@ -673,7 +672,7 @@ describe('Agent context', () => { ]); }); - it('removes the prompt-owned image compression reminder when undoing its prompt', async () => { + it('removes a pre-anchor image compression reminder when undoing its prompt', async () => { profile.update({ activeToolNames: [] }); const caption = buildImageCompressionCaption({ original: { width: 3264, height: 666, byteLength: 344 * 1024, mimeType: 'image/png' }, @@ -687,14 +686,8 @@ describe('Agent context', () => { await ctx.untilTurnEnd(); expect(context.get()).toMatchObject([ - { - origin: { - kind: 'injection', - variant: 'image_compression', - ownerPromptId: expect.any(String), - }, - }, - { origin: { kind: 'user' }, id: expect.any(String) }, + { origin: { kind: 'injection', variant: 'image_compression' } }, + { origin: { kind: 'user' } }, { role: 'assistant' }, ]); @@ -770,6 +763,7 @@ describe('Agent context', () => { expect(zeroed.head).toHaveLength(0); expect(zeroed.tail).toHaveLength(messages.length); + // Sanity: the default estimator elides this much user text. expect(selectCompactionUserMessages(messages).elided).toBe(true); }); @@ -811,6 +805,8 @@ describe('Agent context', () => { }); expect(withMeasured.tokensAfter).toBeGreaterThan(500); + // Same kept messages; only the summary component differs — the + // measured 500 replaces the summary-text estimate. expect(withMeasured.tokensAfter - 500).toBe( withEstimate.tokensAfter - estimateTokens('summary'), ); @@ -842,32 +838,6 @@ describe('Agent context', () => { expect(withOverhead.messages).toEqual(withoutOverhead.messages); }); }); - - describe('legacy compaction layout', () => { - it('keeps the verbatim summary followed by the uncompacted tail', () => { - const history = [userMessage('old'), userMessage('tail')]; - const legacySummary: ContextMessage = { - role: 'assistant', - content: [{ type: 'text', text: 'legacy summary' }], - toolCalls: [], - origin: { kind: 'compaction_summary' }, - }; - const input = { - summary: 'legacy summary', - legacySummaryMessage: legacySummary, - compactedCount: 1, - tokensBefore: 100, - tokensAfter: 20, - legacyTail: true, - }; - - const shape = buildContextCompactionShape(history, input); - - expect(shape.messages[0]).toBe(legacySummary); - expect(shape.messages[1]).toBe(history[1]); - expect(shape.messages.map(textOf)).toEqual(['legacy summary', 'tail']); - }); - }); }); function userMessage(text: string, origin?: ContextMessage['origin']): ContextMessage { @@ -885,94 +855,3 @@ function textOf(message: Message): string { .map((part) => part.text) .join(''); } - -describe('closeTrailingOpenToolExchange', () => { - const user: ContextMessage = { - role: 'user', - content: [{ type: 'text', text: 'hi' }], - toolCalls: [], - }; - const readCall: ToolCall = { type: 'function', id: 'call_read', name: 'Read', arguments: '{}' }; - const agentCall: ToolCall = { type: 'function', id: 'call_agent', name: 'Agent', arguments: '{}' }; - - it('returns an empty seed for an empty history', () => { - expect(closeTrailingOpenToolExchange([])).toEqual([]); - }); - - it('keeps a history without tool calls unchanged', () => { - const history = [user]; - expect(closeTrailingOpenToolExchange(history)).toEqual(history); - }); - - it('keeps a fully answered trailing exchange unchanged', () => { - const history: ContextMessage[] = [ - user, - { role: 'assistant', content: [], toolCalls: [readCall] }, - { - role: 'tool', - toolCallId: 'call_read', - content: [{ type: 'text', text: 'contents' }], - toolCalls: [], - }, - ]; - expect(closeTrailingOpenToolExchange(history)).toEqual(history); - }); - - it('closes an unanswered trailing call with a synthetic in-flight result', () => { - const assistant: ContextMessage = { - role: 'assistant', - content: [{ type: 'text', text: 'delegating the follow-up' }], - toolCalls: [agentCall], - }; - const seed = closeTrailingOpenToolExchange([user, assistant]); - - expect(seed).toHaveLength(3); - expect(seed.slice(0, 2)).toEqual([user, assistant]); - expect(seed[2]).toEqual({ - role: 'tool', - toolCallId: 'call_agent', - content: [{ type: 'text', text: INHERITED_IN_FLIGHT_TOOL_OUTPUT }], - toolCalls: [], - }); - }); - - it('seals a partial assistant when closing an unanswered trailing call', () => { - const assistant: ContextMessage = { - role: 'assistant', - content: [{ type: 'text', text: 'delegating the follow-up' }], - toolCalls: [agentCall], - partial: true, - }; - const seed = closeTrailingOpenToolExchange([user, assistant]); - - expect(seed[1]).toMatchObject({ role: 'assistant', partial: undefined }); - expect(seed[2]).toMatchObject({ - role: 'tool', - toolCallId: 'call_agent', - content: [{ type: 'text', text: INHERITED_IN_FLIGHT_TOOL_OUTPUT }], - }); - }); - - it('fills only the unanswered calls of a partially answered parallel batch', () => { - const assistant: ContextMessage = { - role: 'assistant', - content: [], - toolCalls: [readCall, agentCall], - }; - const answered: ContextMessage = { - role: 'tool', - toolCallId: 'call_read', - content: [{ type: 'text', text: 'contents' }], - toolCalls: [], - }; - const seed = closeTrailingOpenToolExchange([user, assistant, answered]); - - expect(seed).toHaveLength(4); - expect(seed.slice(0, 3)).toEqual([user, assistant, answered]); - expect(seed[3]).toMatchObject({ - role: 'tool', - toolCallId: 'call_agent', - content: [{ type: 'text', text: INHERITED_IN_FLIGHT_TOOL_OUTPUT }], - }); - }); -}); diff --git a/packages/agent-core-v2/test/agent/contextMemory/contextTranscript.test.ts b/packages/agent-core-v2/test/agent/contextMemory/contextTranscript.test.ts index 9eb10056f..c96e90900 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/contextTranscript.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/contextTranscript.test.ts @@ -1,20 +1,18 @@ +/** + * Tests for `reduceContextTranscript` — the wire-transcript reducer used by the + * snapshot and messages endpoints. Mirrors v1 `reduceWireRecords` expectations: + * compaction keeps the prefix and appends a summary marker; undo removes the + * tail but stops at compaction summaries / clear floors; clear keeps the + * transcript but resets the folded view. + */ + import { describe, expect, it } from 'vitest'; -import { - applyContextCompactionRecord, - computeUndoCut, - isFullyUndoable, -} from '#/agent/contextMemory/contextOps'; import { reduceContextTranscript, type ContextTranscript, } from '#/agent/contextMemory/contextTranscript'; -import { - foldAppendMessage, - foldLoopEvent, - resetFold, - type LoopRecordedEvent, -} from '#/agent/contextMemory/loopEventFold'; +import type { LoopRecordedEvent } from '#/agent/contextMemory/loopEventFold'; import type { ContextMessage, PromptOrigin } from '#/agent/contextMemory/types'; import type { WireRecord } from '#/wire/record'; @@ -294,247 +292,3 @@ describe('reduceContextTranscript', () => { expect(result.foldedLength).toBe(4); }); }); - -describe('live fold parity', () => { - function foldLive(records: WireRecord[]): readonly ContextMessage[] { - let state: readonly ContextMessage[] = []; - for (const record of records) { - switch (record.type) { - case 'context.append_message': - state = foldAppendMessage(state, record['message'] as ContextMessage); - break; - case 'context.append_loop_event': - state = foldLoopEvent(state, record['event'] as LoopRecordedEvent); - break; - case 'context.apply_compaction': - state = applyContextCompactionRecord(state, record); - break; - case 'context.undo': { - const count = record['count'] as number; - const cut = computeUndoCut(state, count); - if (isFullyUndoable(cut, count)) state = resetFold(state.slice(0, cut.cutIndex)); - break; - } - case 'context.clear': - state = state.length === 0 ? state : resetFold([]); - break; - } - } - return state; - } - - function comparable(messages: readonly ContextMessage[]): unknown { - return messages.map((m) => ({ - role: m.role, - content: m.content, - toolCalls: m.toolCalls, - toolCallId: m.toolCallId, - isError: m.isError, - note: m.note, - })); - } - - it('matches the live folded view message-for-message on a plain stream', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - loopEvent({ type: 'step.begin', uuid: 's1' }), - loopEvent({ type: 'content.part', stepUuid: 's1', part: { type: 'text', text: 'a1' } }), - loopEvent({ - type: 'tool.call', - stepUuid: 's1', - toolCallId: 'c1', - name: 'Bash', - args: { command: 'echo hi' }, - }), - appendMessage(userMessage('inj', { kind: 'injection', variant: 'test' })), - loopEvent({ - type: 'tool.result', - toolCallId: 'c1', - result: { output: 'hi', isError: false, note: 'note' }, - }), - loopEvent({ type: 'step.end', uuid: 's1' }), - loopEvent({ type: 'step.begin', uuid: 's2' }), - loopEvent({ type: 'content.part', stepUuid: 's2', part: { type: 'think', think: '' } }), - loopEvent({ type: 'step.end', uuid: 's2' }), - loopEvent({ type: 'step.begin', uuid: 's3' }), - loopEvent({ type: 'step.begin', uuid: 's4' }), - loopEvent({ type: 'content.part', stepUuid: 's4', part: { type: 'text', text: 'recovered' } }), - loopEvent({ type: 'step.end', uuid: 's4' }), - appendMessage(userMessage('u2')), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(comparable(transcript.entries)).toEqual(comparable(live)); - expect(transcript.entries.map((m) => m.role)).toEqual([ - 'user', - 'assistant', - 'tool', - 'user', - 'assistant', - 'user', - ]); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('tracks the live context length across compaction', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - ...assistantStep('s1', 'a1'), - appendMessage(userMessage('u2')), - ...assistantStep('s2', 'a2'), - compaction('SUM', 4, 2), - appendMessage(userMessage('u3')), - ...assistantStep('s3', 'a3'), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(live).toHaveLength(5); - expect(transcript.foldedLength).toBe(live.length); - expect(live[2]!.origin).toEqual({ kind: 'compaction_summary' }); - }); - - it('settles a frame left open by a failed attempt when compaction lands mid-fold', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - ...assistantStep('s1', 'a1'), - loopEvent({ type: 'step.begin', uuid: 's2' }), - compaction('SUM', 3, 1), - ...assistantStep('s3', 'a3'), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(live.map((m) => m.role)).toEqual(['user', 'user', 'assistant']); - expect(texts(transcript)).toEqual(['u1', 'a1', 'SUM', 'a3']); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('closes a pending tool exchange when compaction lands mid-fold', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - loopEvent({ type: 'step.begin', uuid: 's2' }), - loopEvent({ type: 'tool.call', stepUuid: 's2', toolCallId: 'c1', name: 'Bash' }), - compaction('SUM', 2, 1), - ...assistantStep('s3', 'a3'), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(transcript.entries.map((m) => m.role)).toEqual([ - 'user', - 'assistant', - 'tool', - 'user', - 'assistant', - ]); - expect(transcript.entries[2]!.toolCallId).toBe('c1'); - expect(transcript.entries[2]!.isError).toBe(true); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('keeps legacy compaction recovery on the pre-settlement count', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - ...assistantStep('s1', 'a1'), - loopEvent({ type: 'step.begin', uuid: 's2' }), - compaction('SUM', 1), - ...assistantStep('s3', 'a3'), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(live.map((m) => m.role)).toEqual(['user', 'assistant', 'assistant', 'assistant']); - expect(live[2]!.partial).toBe(true); - expect(transcript.entries.map((m) => m.role)).toEqual([ - 'user', - 'assistant', - 'assistant', - 'user', - 'assistant', - ]); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('tracks the live context length across clear and undo', () => { - const records: WireRecord[] = [ - appendMessage(userMessage('u1')), - ...assistantStep('s1', 'a1'), - { type: 'context.clear' }, - appendMessage(userMessage('u2')), - ...assistantStep('s2', 'a2'), - appendMessage(userMessage('u3')), - ...assistantStep('s3', 'a3'), - undo(1), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(comparable(live)).toEqual(comparable(transcript.entries.slice(-2))); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('removes injections owned by every removed prompt on multi-turn undo, matching the live view', () => { - const records: WireRecord[] = [ - appendMessage( - userMessage('injA', { - kind: 'injection', - variant: 'image_compression', - ownerPromptId: 'p1', - }), - ), - appendMessage({ ...userMessage('u1', { kind: 'user' }), id: 'p1' }), - ...assistantStep('s1', 'a1'), - appendMessage( - userMessage('injB', { - kind: 'injection', - variant: 'image_compression', - ownerPromptId: 'p2', - }), - ), - appendMessage({ ...userMessage('u2', { kind: 'user' }), id: 'p2' }), - ...assistantStep('s2', 'a2'), - undo(2), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(comparable(transcript.entries)).toEqual(comparable(live)); - expect(transcript.entries).toHaveLength(0); - expect(transcript.foldedLength).toBe(live.length); - }); - - it('keeps the older prompt injection when the removed prompt reuses its id', () => { - const records: WireRecord[] = [ - appendMessage( - userMessage('injA', { - kind: 'injection', - variant: 'image_compression', - ownerPromptId: 'shared', - }), - ), - appendMessage({ ...userMessage('u1', { kind: 'user' }), id: 'shared' }), - ...assistantStep('s1', 'a1'), - appendMessage( - userMessage('injB', { - kind: 'injection', - variant: 'image_compression', - ownerPromptId: 'shared', - }), - ), - appendMessage({ ...userMessage('u2', { kind: 'user' }), id: 'shared' }), - ...assistantStep('s2', 'a2'), - undo(1), - ]; - const live = foldLive(records); - const transcript = reduceContextTranscript(records); - expect(texts(transcript)).toEqual(['injA', 'u1', 'a1']); - expect(comparable(transcript.entries)).toEqual(comparable(live)); - expect(transcript.foldedLength).toBe(3); - }); - - it('keeps injections not owned by any removed prompt across undo', () => { - const result = reduceContextTranscript([ - appendMessage(userMessage('note', { kind: 'injection', variant: 'test' })), - appendMessage(userMessage('u1')), - appendMessage(assistantMessage('a1')), - undo(1), - ]); - expect(texts(result)).toEqual(['note']); - expect(result.foldedLength).toBe(1); - }); -}); diff --git a/packages/agent-core-v2/test/agent/contextMemory/loopEventFold.test.ts b/packages/agent-core-v2/test/agent/contextMemory/loopEventFold.test.ts index 74bca6df3..25f9f73b3 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/loopEventFold.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/loopEventFold.test.ts @@ -1,34 +1,22 @@ -import { describe, expect, it } from 'vitest'; +import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { - foldAppendMessage, - foldLoopEvent, - type LoopRecordedEvent, -} from '#/agent/contextMemory/loopEventFold'; import type { ContextMessage } from '#/agent/contextMemory/types'; +import { IAgentContextMemoryService } from '#/index'; + +import { createTestAgent, type TestAgentContext } from '../../harness'; describe('loop-event fold parity', () => { - function appendAll( - state: readonly ContextMessage[], - messages: readonly ContextMessage[], - ): readonly ContextMessage[] { - let next = state; - for (const message of messages) { - next = foldAppendMessage(next, message); - } - return next; - } + let ctx: TestAgentContext; + let context: IAgentContextMemoryService; - function foldAll( - state: readonly ContextMessage[], - events: readonly LoopRecordedEvent[], - ): readonly ContextMessage[] { - let next = state; - for (const event of events) { - next = foldLoopEvent(next, event); - } - return next; - } + beforeEach(() => { + ctx = createTestAgent(); + context = ctx.get(IAgentContextMemoryService); + }); + + afterEach(async () => { + await ctx.dispose(); + }); function comparable(messages: readonly ContextMessage[]): unknown { return messages.map((m) => ({ @@ -42,86 +30,80 @@ describe('loop-event fold parity', () => { } it('folds a text + tool-call + tool-result step into the append_message shape', () => { - const baseline = comparable( - appendAll([], [ - { - role: 'assistant', - content: [{ type: 'text', text: 'I will call.' }], - toolCalls: [{ type: 'function', id: 'c1', name: 'Lookup', arguments: '{"q":"moon"}' }], - }, - { - role: 'tool', - content: [{ type: 'text', text: 'lookup result' }], - toolCalls: [], - toolCallId: 'c1', - isError: false, - }, - ]), + context.append( + { + role: 'assistant', + content: [{ type: 'text', text: 'I will call.' }], + toolCalls: [{ type: 'function', id: 'c1', name: 'Lookup', arguments: '{"q":"moon"}' }], + }, + { + role: 'tool', + content: [{ type: 'text', text: 'lookup result' }], + toolCalls: [], + toolCallId: 'c1', + isError: false, + }, ); + const baseline = comparable(context.get()); + context.clear(); - const folded = comparable( - foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'text', text: 'I will call.' }, - }, - { - type: 'tool.call', - stepUuid: 's1', - toolCallId: 'c1', - name: 'Lookup', - args: { q: 'moon' }, - }, - { - type: 'tool.result', - toolCallId: 'c1', - result: { output: 'lookup result', isError: false }, - }, - { type: 'step.end', uuid: 's1' }, - ]), - ); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'text', text: 'I will call.' }, + }); + context.appendLoopEvent({ + type: 'tool.call', + stepUuid: 's1', + toolCallId: 'c1', + name: 'Lookup', + args: { q: 'moon' }, + }); + context.appendLoopEvent({ + type: 'tool.result', + toolCallId: 'c1', + result: { output: 'lookup result', isError: false }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); + const folded = comparable(context.get()); expect(folded).toEqual(baseline); }); it('folds an errored tool result into the append_message shape', () => { - const baseline = comparable( - appendAll([], [ - { - role: 'assistant', - content: [], - toolCalls: [{ type: 'function', id: 'c2', name: 'Bash', arguments: '{}' }], - }, - { - role: 'tool', - content: [{ type: 'text', text: 'boom' }], - toolCalls: [], - toolCallId: 'c2', - isError: true, - }, - ]), + context.append( + { + role: 'assistant', + content: [], + toolCalls: [{ type: 'function', id: 'c2', name: 'Bash', arguments: '{}' }], + }, + { + role: 'tool', + content: [{ type: 'text', text: 'boom' }], + toolCalls: [], + toolCallId: 'c2', + isError: true, + }, ); + const baseline = comparable(context.get()); + context.clear(); - const folded = comparable( - foldAll([], [ - { type: 'step.begin', uuid: 's2' }, - { - type: 'tool.call', - stepUuid: 's2', - toolCallId: 'c2', - name: 'Bash', - args: {}, - }, - { - type: 'tool.result', - toolCallId: 'c2', - result: { output: 'boom', isError: true }, - }, - { type: 'step.end', uuid: 's2' }, - ]), - ); + context.appendLoopEvent({ type: 'step.begin', uuid: 's2' }); + context.appendLoopEvent({ + type: 'tool.call', + stepUuid: 's2', + toolCallId: 'c2', + name: 'Bash', + args: {}, + }); + context.appendLoopEvent({ + type: 'tool.result', + toolCallId: 'c2', + result: { output: 'boom', isError: true }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's2' }); + const folded = comparable(context.get()); expect(folded).toEqual(baseline); }); @@ -138,18 +120,16 @@ describe('loop-event fold parity', () => { } it('drops an empty partial assistant left by a failed attempt when the retry begins', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { type: 'step.begin', uuid: 's2' }, - { - type: 'content.part', - stepUuid: 's2', - part: { type: 'text', text: 'recovered' }, - }, - { type: 'step.end', uuid: 's2' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ type: 'step.begin', uuid: 's2' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's2', + part: { type: 'text', text: 'recovered' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's2' }); - expect(shapes(folded)).toEqual([ + expect(shapes(context.get())).toEqual([ { role: 'assistant', content: [{ type: 'text', text: 'recovered' }], @@ -162,24 +142,22 @@ describe('loop-event fold parity', () => { }); it('seals a failed attempt’s partial assistant and closes its tool exchange on the next step.begin', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'text', text: 'half' }, - }, - { - type: 'tool.call', - stepUuid: 's1', - toolCallId: 'c1', - name: 'Bash', - args: {}, - }, - { type: 'step.begin', uuid: 's2' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'text', text: 'half' }, + }); + context.appendLoopEvent({ + type: 'tool.call', + stepUuid: 's1', + toolCallId: 'c1', + name: 'Bash', + args: {}, + }); + context.appendLoopEvent({ type: 'step.begin', uuid: 's2' }); - expect(shapes(folded)).toEqual([ + expect(shapes(context.get())).toEqual([ { role: 'assistant', content: [{ type: 'text', text: 'half' }], @@ -208,94 +186,40 @@ describe('loop-event fold parity', () => { }); it('drops an assistant that produced no output at step.end', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(folded).toEqual([]); - }); - - it('keeps the open assistant untouched when step.end reports an interruption', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'text', text: 'partial' }, - }, - { type: 'step.end', uuid: 's1', finishReason: 'interrupted' }, - ]); - - expect(shapes(folded)).toEqual([ - { - role: 'assistant', - content: [{ type: 'text', text: 'partial' }], - toolCalls: [], - toolCallId: undefined, - isError: undefined, - partial: true, - }, - ]); - }); - - it('settles a failed step at the next step.begin as before', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { type: 'step.end', uuid: 's1', finishReason: 'error' }, - { type: 'step.begin', uuid: 's2' }, - { - type: 'content.part', - stepUuid: 's2', - part: { type: 'text', text: 'recovered' }, - }, - { type: 'step.end', uuid: 's2' }, - ]); - - expect(shapes(folded)).toEqual([ - { - role: 'assistant', - content: [{ type: 'text', text: 'recovered' }], - toolCalls: [], - toolCallId: undefined, - isError: undefined, - partial: undefined, - }, - ]); + expect(context.get()).toEqual([]); }); it('drops an assistant whose only recorded part is an empty thinking block at step.end', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: '' }, - }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: '' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(folded).toEqual([]); + expect(context.get()).toEqual([]); }); it('drops a vacuous partial assistant left by a failed attempt when the retry begins', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: ' ' }, - }, - { type: 'step.begin', uuid: 's2' }, - { - type: 'content.part', - stepUuid: 's2', - part: { type: 'text', text: 'recovered' }, - }, - { type: 'step.end', uuid: 's2' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: ' ' }, + }); + context.appendLoopEvent({ type: 'step.begin', uuid: 's2' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's2', + part: { type: 'text', text: 'recovered' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's2' }); - expect(shapes(folded)).toEqual([ + expect(shapes(context.get())).toEqual([ { role: 'assistant', content: [{ type: 'text', text: 'recovered' }], @@ -308,74 +232,66 @@ describe('loop-event fold parity', () => { }); it('seals a step whose thinking block has real content', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: 'real reasoning' }, - }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: 'real reasoning' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(folded.at(-1)?.content).toEqual([{ type: 'think', think: 'real reasoning' }]); + expect(context.get().at(-1)?.content).toEqual([{ type: 'think', think: 'real reasoning' }]); }); it('seals a step whose empty thinking block carries a provider signature', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: '', encrypted: 'sig' }, - }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: '', encrypted: 'sig' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(folded.at(-1)?.content).toEqual([{ type: 'think', think: '', encrypted: 'sig' }]); + expect(context.get().at(-1)?.content).toEqual([{ type: 'think', think: '', encrypted: 'sig' }]); }); it('seals a step that pairs an empty thinking block with real text', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: '' }, - }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'text', text: 'answer' }, - }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: '' }, + }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'text', text: 'answer' }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(folded.at(-1)?.content).toEqual([ + expect(context.get().at(-1)?.content).toEqual([ { type: 'think', think: '' }, { type: 'text', text: 'answer' }, ]); }); it('seals an assistant with tool calls even when its thinking block is empty', () => { - const folded = foldAll([], [ - { type: 'step.begin', uuid: 's1' }, - { - type: 'content.part', - stepUuid: 's1', - part: { type: 'think', think: '' }, - }, - { - type: 'tool.call', - stepUuid: 's1', - toolCallId: 'c1', - name: 'Lookup', - args: {}, - }, - { type: 'step.end', uuid: 's1' }, - ]); + context.appendLoopEvent({ type: 'step.begin', uuid: 's1' }); + context.appendLoopEvent({ + type: 'content.part', + stepUuid: 's1', + part: { type: 'think', think: '' }, + }); + context.appendLoopEvent({ + type: 'tool.call', + stepUuid: 's1', + toolCallId: 'c1', + name: 'Lookup', + args: {}, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's1' }); - expect(shapes(folded)).toEqual([ + expect(shapes(context.get())).toEqual([ { role: 'assistant', content: [{ type: 'think', think: '' }], @@ -396,46 +312,43 @@ describe('loop-event fold parity', () => { }); it('folds a tool-result note as structured model-only metadata', () => { - const baseline = comparable( - appendAll([], [ - { - role: 'assistant', - content: [], - toolCalls: [{ type: 'function', id: 'c3', name: 'Screenshot', arguments: '{}' }], - }, - { - role: 'tool', - content: [{ type: 'text', text: 'result text' }], - toolCalls: [], - toolCallId: 'c3', - isError: false, - note: 'Image compressed.', - }, - ]), + context.append( + { + role: 'assistant', + content: [], + toolCalls: [{ type: 'function', id: 'c3', name: 'Screenshot', arguments: '{}' }], + }, + { + role: 'tool', + content: [{ type: 'text', text: 'result text' }], + toolCalls: [], + toolCallId: 'c3', + isError: false, + note: 'Image compressed.', + }, ); + const baseline = comparable(context.get()); + context.clear(); - const folded = comparable( - foldAll([], [ - { type: 'step.begin', uuid: 's3' }, - { - type: 'tool.call', - stepUuid: 's3', - toolCallId: 'c3', - name: 'Screenshot', - args: {}, - }, - { - type: 'tool.result', - toolCallId: 'c3', - result: { - output: 'result text', - isError: false, - note: 'Image compressed.', - }, - }, - { type: 'step.end', uuid: 's3' }, - ]), - ); + context.appendLoopEvent({ type: 'step.begin', uuid: 's3' }); + context.appendLoopEvent({ + type: 'tool.call', + stepUuid: 's3', + toolCallId: 'c3', + name: 'Screenshot', + args: {}, + }); + context.appendLoopEvent({ + type: 'tool.result', + toolCallId: 'c3', + result: { + output: 'result text', + isError: false, + note: 'Image compressed.', + }, + }); + context.appendLoopEvent({ type: 'step.end', uuid: 's3' }); + const folded = comparable(context.get()); expect(folded).toEqual(baseline); }); diff --git a/packages/agent-core-v2/test/agent/contextMemory/message-history.test.ts b/packages/agent-core-v2/test/agent/contextMemory/message-history.test.ts index 53f652e4d..80f4ba41b 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/message-history.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/message-history.test.ts @@ -6,11 +6,10 @@ import { TestInstantiationService } from '#/_base/di/test'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import type { ContextMessage } from '#/agent/contextMemory/types'; import { AgentContextMemoryService } from '#/agent/contextMemory/contextMemoryService'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; import { IEventBus } from '#/app/event/eventBus'; import { EventBusService } from '#/app/event/eventBusService'; -import { registerTestAgentWire, registerTestEventDispatcher } from '../../wire/stubs'; +import { registerTestAgentWire } from '../../wire/stubs'; function textMessage(role: ContextMessage['role'], text: string): ContextMessage { return { @@ -26,22 +25,6 @@ function textOf(message: ContextMessage): string { .join(''); } -const noopTokenCounting: ISessionTokenCountingService = { - _serviceBrand: undefined, - strategy: 'measured+estimated', - get: () => ({ size: 0, measured: 0, estimated: 0 }), - measured: () => {}, - latestMeasured: () => 0, - statusSize: () => 0, - recordTruncation: () => {}, - rebase: () => {}, - requestSize: () => 0, - estimateText: () => 0, - estimateMessage: () => 0, - estimateMessages: () => 0, - estimateTools: () => 0, -}; - describe('message history (IAgentContextMemoryService)', () => { let disposables: DisposableStore; @@ -52,8 +35,6 @@ describe('message history (IAgentContextMemoryService)', () => { ix = disposables.add(new TestInstantiationService()); ix.set(IEventBus, new SyncDescriptor(EventBusService)); registerTestAgentWire(ix, 'wire/message-history', { eventBus: ix.get(IEventBus) }); - ix.set(ISessionTokenCountingService, noopTokenCounting); - registerTestEventDispatcher(ix); ix.set(IAgentContextMemoryService, new SyncDescriptor(AgentContextMemoryService)); }); afterEach(() => disposables.dispose()); diff --git a/packages/agent-core-v2/test/agent/contextMemory/splice-replay.test.ts b/packages/agent-core-v2/test/agent/contextMemory/splice-replay.test.ts index 0d9b03672..22915c6d1 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/splice-replay.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/splice-replay.test.ts @@ -1,3 +1,13 @@ +/** + * `AgentContextMemoryService` wire contract, exercised without the full agent + * harness (mirror of `test/goal/goal-wire.test.ts`): a `TestInstantiationService` + * + `InMemoryStorageService` + `AppendLogStore` + `WireService` + stub + * `IAgentBlobService`. Covers the context Ops' NEW-reference + flat-record + * shape, the live-only `context.spliced` event (silent on replay), and — + * load-bearing — the blob dehydrate-on-dispatch ↔ rehydrate-on-replay + * round-trip via `ContextModel.blobs`. + */ + import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { SyncDescriptor } from '#/_base/di/descriptors'; @@ -7,16 +17,13 @@ import { IAgentBlobService } from '#/agent/blob/agentBlobService'; import { IAgentContextMemoryService } from '#/agent/contextMemory/contextMemory'; import { AgentContextMemoryService } from '#/agent/contextMemory/contextMemoryService'; import { - ContextAppendLoopEvent, - ContextAppendMessage, - ContextApplyCompaction, - ContextClear, - ContextSpliced, - ContextUndo, -} from '#/agent/contextMemory/contextEvents'; -import { contextMemoryKey } from '#/agent/contextMemory/contextOps'; + ContextModel, + contextAppendMessage, + contextApplyCompaction, + contextClear, + contextUndo, +} from '#/agent/contextMemory/contextOps'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { ISessionTokenCountingService } from '#/session/tokenCounting/sessionTokenCounting'; import { IEventBus } from '#/app/event/eventBus'; import { EventBusService } from '#/app/event/eventBusService'; import type { ContentPart } from '#/kosong/contract/message'; @@ -24,18 +31,10 @@ import { AppendLogStore } from '#/persistence/backends/node-fs/appendLogStore'; import { InMemoryStorageService } from '#/persistence/backends/memory/inMemoryStorageService'; import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; -import type { DeepReadonly } from '#/state/state'; import { IWireService } from '#/wire/wire'; import { AGENT_WIRE_RECORD_KEY, type WireRecord } from '#/wire/record'; -import { - registerTestAgentWire, - registerTestEventDispatcher, - restoreTestEventDispatcher, - testWireScope, -} from '../../wire/stubs'; +import { registerTestAgentWire, restoreTestAgentWire, testWireScope } from '../../wire/stubs'; const SCOPE = 'wire'; const KEY = 'ctx-live'; @@ -128,12 +127,12 @@ function imageMessage(payload: string): ContextMessage { return { role: 'user', content: [part], toolCalls: [] }; } -function mediaUrl(message: DeepReadonly): string { +function mediaUrl(message: ContextMessage): string { const part = message.content[0] as unknown as { source: { url: string } }; return part.source.url; } -function textOf(message: DeepReadonly): string { +function textOf(message: ContextMessage): string { const part = message.content[0] as unknown as { text?: unknown }; if (typeof part.text !== 'string') throw new Error('expected text content'); return part.text; @@ -144,47 +143,25 @@ let blob: StubBlobService; interface Host { wire: IWireService; - dispatcher: IEventDispatcher; - agentState: IAgentStateService; svc: IAgentContextMemoryService; log: IAppendLogStore; eventBus: IEventBus; } -const noopTokenCounting: ISessionTokenCountingService = { - _serviceBrand: undefined, - strategy: 'measured+estimated', - get: () => ({ size: 0, measured: 0, estimated: 0 }), - measured: () => {}, - latestMeasured: () => 0, - statusSize: () => 0, - recordTruncation: () => {}, - rebase: () => {}, - requestSize: () => 0, - estimateText: () => 0, - estimateMessage: () => 0, - estimateMessages: () => 0, - estimateTools: () => 0, -}; - function buildHost(key: string): Host { const ix = disposables.add(new TestInstantiationService()); ix.stub(IFileSystemStorageService, new InMemoryStorageService()); ix.set(IAppendLogStore, new SyncDescriptor(AppendLogStore)); ix.stub(IAgentBlobService, blob); ix.set(IEventBus, new SyncDescriptor(EventBusService)); - ix.set(ISessionTokenCountingService, noopTokenCounting); ix.set(IAgentContextMemoryService, new SyncDescriptor(AgentContextMemoryService)); const wire = registerTestAgentWire(ix, testWireScope(SCOPE, key), { log: ix.get(IAppendLogStore), blob, eventBus: ix.get(IEventBus), }); - const dispatcher = registerTestEventDispatcher(ix); return { wire, - dispatcher, - agentState: ix.get(IAgentStateService), svc: ix.get(IAgentContextMemoryService), log: ix.get(IAppendLogStore), eventBus: ix.get(IEventBus), @@ -207,27 +184,29 @@ beforeEach(() => { afterEach(() => disposables.dispose()); describe('AgentContextMemoryService (wire-backed)', () => { - it('splice/append/undo/apply_compaction/clear/append_loop_event each update getState with a NEW reference and persist flat records', async () => { + it('splice/append/undo/apply_compaction/clear/append_loop_event each update getModel with a NEW reference and persist flat records', async () => { const host = buildHost(KEY); - const model = () => host.agentState.get(contextMemoryKey); + const model = () => host.wire.getModel(ContextModel) as readonly ContextMessage[]; - await host.dispatcher.dispatch(new ContextAppendMessage({ agentId: 'test-agent', message: userMessage('a') })); - await host.dispatcher.dispatch(new ContextAppendMessage({ agentId: 'test-agent', message: userMessage('b') })); + host.wire.dispatch( + contextAppendMessage({ message: userMessage('a') }), + contextAppendMessage({ message: userMessage('b') }), + ); expect(model()).toHaveLength(2); let prev = model(); - await host.dispatcher.dispatch(new ContextAppendMessage({ agentId: 'test-agent', message: userMessage('c') })); + host.wire.dispatch(contextAppendMessage({ message: userMessage('c') })); expect(model()).not.toBe(prev); expect(model()).toHaveLength(3); prev = model(); - await host.dispatcher.dispatch(new ContextUndo({ agentId: 'test-agent', count: 1 })); + host.wire.dispatch(contextUndo({ count: 1 })); expect(model()).not.toBe(prev); expect(model()).toHaveLength(2); prev = model(); - await host.dispatcher.dispatch( - new ContextApplyCompaction({ agentId: 'test-agent', summary: 'sum', compactedCount: 1, tokensBefore: 0, tokensAfter: 0 }), + host.wire.dispatch( + contextApplyCompaction({ summary: 'sum', compactedCount: 1, tokensBefore: 0, tokensAfter: 0 }), ); expect(model()).not.toBe(prev); expect(model()).toHaveLength(2); @@ -238,11 +217,11 @@ describe('AgentContextMemoryService (wire-backed)', () => { }); prev = model(); - await host.dispatcher.dispatch(new ContextClear({ agentId: 'test-agent' })); + host.wire.dispatch(contextClear({})); expect(model()).not.toBe(prev); expect(model()).toHaveLength(0); - await host.dispatcher.flush(); + await host.wire.flush(); const records = await readRecords(host.log); expect(records.every((record) => 'payload' in record === false)).toBe(true); expect(records.map((record) => record.type)).toEqual([ @@ -255,7 +234,7 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]); }); - it('folds v1 context.append_loop_event records into the contextMemoryKey on replay', async () => { + it('folds v1 context.append_loop_event records into the ContextModel on replay', async () => { const records: WireRecord[] = [ { type: 'context.append_message', message: userMessage('q') }, { type: 'context.append_loop_event', event: { type: 'step.begin', uuid: 's1', turnId: '0', step: 1 } }, @@ -296,14 +275,14 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]; const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); - const model = replay.agentState.get(contextMemoryKey); + const model = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(model.map((message) => message.role)).toEqual(['user', 'assistant', 'tool']); expect(model[1]!.content).toEqual([{ type: 'text', text: 'hello' }]); expect(model[1]!.partial).toBeUndefined(); @@ -329,14 +308,14 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]; const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); - const model = replay.agentState.get(contextMemoryKey); + const model = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(model.map(textOf)).toEqual(['model-facing summary', 'tail']); expect(model[0]).toMatchObject({ role: 'user', @@ -368,14 +347,14 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]; const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); - const model = replay.agentState.get(contextMemoryKey); + const model = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(model.map((message) => message.role)).toEqual(['user', 'user', 'user']); expect(model.map(textOf)).toEqual(['old user', 'recent user', 'model-facing summary']); expect(model[2]).toMatchObject({ @@ -398,14 +377,14 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]; const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); - const model = replay.agentState.get(contextMemoryKey); + const model = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(model.map(textOf)).toEqual(['old user', 'recent user', 'OLD SUMMARY']); expect(model[2]).toMatchObject({ role: 'user', @@ -431,14 +410,14 @@ describe('AgentContextMemoryService (wire-backed)', () => { ]; const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); - const model = replay.agentState.get(contextMemoryKey); + const model = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(model).toHaveLength(2); expect(model[0]).toEqual(legacySummary); expect(textOf(model[1]!)).toBe('tail'); @@ -449,10 +428,10 @@ describe('AgentContextMemoryService (wire-backed)', () => { const big = 'A'.repeat(200); const dataUri = `data:image/png;base64,${big}`; - await host.dispatcher.dispatch(new ContextAppendMessage({ agentId: 'test-agent', message: imageMessage(big) })); - await host.dispatcher.flush(); + host.wire.dispatch(contextAppendMessage({ message: imageMessage(big) })); + await host.wire.flush(); - const live = host.agentState.get(contextMemoryKey); + const live = host.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(live).toHaveLength(1); expect(mediaUrl(live[0]!)).toBe(dataUri); @@ -465,103 +444,45 @@ describe('AgentContextMemoryService (wire-backed)', () => { expect(mediaUrl(persisted)).not.toContain(big); const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); expect(blob.loadCalls).toBeGreaterThanOrEqual(1); - const rebuilt = replay.agentState.get(contextMemoryKey); + const rebuilt = replay.wire.getModel(ContextModel) as readonly ContextMessage[]; expect(rebuilt).toEqual(live); expect(mediaUrl(rebuilt[0]!)).toBe(dataUri); }); - it('settles an open step when blob rehydration replaces the folded context state', async () => { - const host = buildHost(KEY); - const big = 'A'.repeat(200); - - await host.dispatcher.dispatch( - new ContextAppendMessage({ agentId: 'test-agent', message: imageMessage(big) }), - ); - await host.dispatcher.dispatch( - new ContextAppendLoopEvent({ - agentId: 'test-agent', - event: { type: 'step.begin', uuid: 'interrupted' }, - }), - ); - await host.dispatcher.flush(); - const records = await readRecords(host.log); - - const replay = buildHost(REPLAY_KEY); - await restoreTestEventDispatcher( - replay.dispatcher, - replay.log, - testWireScope(SCOPE, REPLAY_KEY), - records, - ); - expect(blob.loadCalls).toBeGreaterThanOrEqual(1); - - await replay.dispatcher.dispatch( - new ContextAppendMessage({ agentId: 'test-agent', message: userMessage('retry') }), - ); - await replay.dispatcher.dispatch( - new ContextAppendLoopEvent({ - agentId: 'test-agent', - event: { type: 'step.begin', uuid: 'recovered' }, - }), - ); - await replay.dispatcher.dispatch( - new ContextAppendLoopEvent({ - agentId: 'test-agent', - event: { - type: 'content.part', - stepUuid: 'recovered', - part: { type: 'text', text: 'answer' }, - }, - }), - ); - await replay.dispatcher.dispatch( - new ContextAppendLoopEvent({ - agentId: 'test-agent', - event: { type: 'step.end', uuid: 'recovered' }, - }), - ); - - const rebuilt = replay.agentState.get(contextMemoryKey); - expect(rebuilt.map((message) => message.role)).toEqual(['user', 'user', 'assistant']); - expect(textOf(rebuilt[1]!)).toBe('retry'); - expect(textOf(rebuilt[2]!)).toBe('answer'); - expect(rebuilt.some((message) => message.partial === true)).toBe(false); - }); - it('publishes context.spliced on live dispatch and is silent on replay', async () => { const host = buildHost(KEY); const live: { start: number; deleteCount: number }[] = []; - disposables.add(host.eventBus.subscribe(ContextSpliced, (event) => { + disposables.add(host.eventBus.subscribe('context.spliced', (event) => { live.push({ start: event.start, deleteCount: event.deleteCount }); })); host.svc.append(userMessage('x')); host.svc.append(userMessage('y')); expect(live).toHaveLength(2); - await host.dispatcher.flush(); + await host.wire.flush(); const records = await readRecords(host.log); const replay = buildHost(REPLAY_KEY); const replayed: { start: number; deleteCount: number }[] = []; - disposables.add(replay.eventBus.subscribe(ContextSpliced, (event) => { + disposables.add(replay.eventBus.subscribe('context.spliced', (event) => { replayed.push({ start: event.start, deleteCount: event.deleteCount }); })); - await restoreTestEventDispatcher( - replay.dispatcher, + await restoreTestAgentWire( + replay.wire, replay.log, testWireScope(SCOPE, REPLAY_KEY), records, ); expect(replayed).toHaveLength(0); - expect(replay.agentState.get(contextMemoryKey)).toHaveLength(2); + expect(replay.wire.getModel(ContextModel) as readonly ContextMessage[]).toHaveLength(2); }); }); diff --git a/packages/agent-core-v2/test/agent/contextMemory/stubs.ts b/packages/agent-core-v2/test/agent/contextMemory/stubs.ts index b24a6339d..ba6aef562 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/stubs.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/stubs.ts @@ -1,3 +1,12 @@ +/** + * `contextMemory` test stubs — shared doubles for `IAgentContextMemoryService` and its + * collaborator (`IWireService`). + * + * Lives under `test/` (not `src/`) so test-support code stays out of the + * production tree. Import from a relative path (`./stubs` or + * `../contextMemory/stubs`). + */ + import type { ServiceRegistration } from '#/_base/di/test'; import { buildContextCompactionShape } from '#/agent/contextMemory/compactionHandoff'; import { @@ -6,15 +15,13 @@ import { type ContextCompactionResult, } from '#/agent/contextMemory/contextMemory'; import { computeUndoCut, type UndoCut } from '#/agent/contextMemory/contextOps'; -import { ContextSpliced } from '#/agent/contextMemory/contextEvents'; import type { LoopRecordedEvent } from '#/agent/contextMemory/loopEventFold'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { IEventBus, type ISessionEventBus } from '#/app/event/eventBus'; +import { IEventBus } from '#/app/event/eventBus'; import { EventBusService } from '#/app/event/eventBusService'; import { IWireService } from '#/wire/wire'; import { stubAgentWire } from '../../wire/stubs'; -import { stubAgentContext } from '../agentContext/stubs'; export interface StubContextMemory extends IAgentContextMemoryService { readonly messages: readonly ContextMessage[]; @@ -29,15 +36,7 @@ function publishSplice( tokens?: number; }, ): void { - if (eventBus === undefined) return; - const sessionBus = eventBus as Partial; - if (typeof sessionBus.activateAgent === 'function') { - const context = stubAgentContext('main', 1); - sessionBus.activateAgent(context); - sessionBus.publish?.(new ContextSpliced({ agentId: 'main', ...input }), context); - return; - } - eventBus.publish(new ContextSpliced({ agentId: 'main', ...input })); + eventBus?.publish({ type: 'context.spliced', ...input }); } export function stubContextMemory(eventBus?: IEventBus): StubContextMemory { @@ -54,7 +53,6 @@ export function stubContextMemory(eventBus?: IEventBus): StubContextMemory { publishSplice(eventBus, { start, deleteCount: 0, messages: [...inserted] }); }, appendLoopEvent: () => {}, - publishTrailingRemoval: () => false, clear: () => { const deleteCount = messages.length; if (deleteCount === 0) return; @@ -108,9 +106,6 @@ class StubContextMemoryService implements IAgentContextMemoryService { appendLoopEvent(event: LoopRecordedEvent): void { this.impl.appendLoopEvent(event); } - publishTrailingRemoval(previous: readonly ContextMessage[]): boolean { - return this.impl.publishTrailingRemoval(previous); - } undo(count: number): UndoCut { return this.impl.undo(count); } diff --git a/packages/agent-core-v2/test/agent/contextMemory/undoPrecheck.test.ts b/packages/agent-core-v2/test/agent/contextMemory/undoPrecheck.test.ts index 6c4af9c59..acbe72909 100644 --- a/packages/agent-core-v2/test/agent/contextMemory/undoPrecheck.test.ts +++ b/packages/agent-core-v2/test/agent/contextMemory/undoPrecheck.test.ts @@ -1,15 +1,11 @@ import { describe, expect, it } from 'vitest'; -import { castDraft } from 'immer'; - import { computeUndoCut, - contextMemoryKey, + contextUndo, isFullyUndoable, } from '#/agent/contextMemory/contextOps'; -import { ContextUndo } from '#/agent/contextMemory/contextEvents'; import type { ContextMessage } from '#/agent/contextMemory/types'; -import { expandedStateFolds, type FoldContext } from '#/state/state'; function text(value: string): { type: 'text'; text: string } { return { type: 'text', text: value }; @@ -102,20 +98,6 @@ describe('computeUndoCut', () => { }); describe('contextUndo op', () => { - const foldContext: FoldContext = { - silent: false, - checkpoint: () => {}, - clearCheckpoints: () => {}, - undoToCheckpoint: () => {}, - emit: () => {}, - }; - - function applyContextUndo(state: ContextMessage[], count: number): ContextMessage[] { - const fold = expandedStateFolds(contextMemoryKey).get(ContextUndo)!; - const result = fold(castDraft(state), new ContextUndo({ agentId: 'main', count }), foldContext); - return result === undefined ? state : result; - } - it('slices the history at the cut point, dropping post-cut injections too', () => { const state = [ user(USER_ORIGIN), @@ -124,20 +106,20 @@ describe('contextUndo op', () => { injection(), assistant(), ]; - const next = applyContextUndo(state, 1); + const next = contextUndo.apply(state, { count: 1 }); expect(next).toEqual([user(USER_ORIGIN), assistant()]); }); it('returns the same reference when not fully undoable', () => { const state = [user(USER_ORIGIN), compaction(), assistant()]; - expect(applyContextUndo(state, 1)).toBe(state); + expect(contextUndo.apply(state, { count: 1 })).toBe(state); }); it.each([0, 0.5, Number.MAX_SAFE_INTEGER + 1])( 'returns the same reference for invalid count %s', (count) => { const state = [user(USER_ORIGIN), assistant()]; - expect(applyContextUndo(state, count)).toBe(state); + expect(contextUndo.apply(state, { count })).toBe(state); }, ); }); diff --git a/packages/agent-core-v2/test/agent/contextProjector/contextProjector.bench.ts b/packages/agent-core-v2/test/agent/contextProjector/contextProjector.bench.ts index a111d3310..e8e37d4db 100644 --- a/packages/agent-core-v2/test/agent/contextProjector/contextProjector.bench.ts +++ b/packages/agent-core-v2/test/agent/contextProjector/contextProjector.bench.ts @@ -1,3 +1,16 @@ +/** + * Benchmark for the context projection rewrite (two-pass -> single-pass with + * slot backfill, and O(k²) -> O(k) adjacent user-prompt merging). + * + * `projectLegacy` below is the previous implementation, copied verbatim so the + * comparison stays runnable after the old code is gone. The "new" side goes + * through the real `AgentContextProjectorService`, so it measures exactly the + * projection path. + * + * Run: + * pnpm --filter @moonshot-ai/agent-core-v2 exec vitest bench test/contextProjector/projector.bench.ts + */ + import { bench, describe } from 'vitest'; import { SyncDescriptor } from '#/_base/di/descriptors'; @@ -25,6 +38,7 @@ const noopLogService: ILogService = { flush: () => Promise.resolve(), }; + function projectLegacy(history: readonly ContextMessage[]): Message[] { const openCalls = new Map(); const answers = new Map(); @@ -132,6 +146,7 @@ function stripContextMetadata(message: ContextMessage): Message { }; } + function makeExchangeHistory(exchanges: number, callsPerStep: number): ContextMessage[] { const history: ContextMessage[] = []; for (let i = 0; i < exchanges; i++) { @@ -185,6 +200,7 @@ function createProjector(disposables: DisposableStore): IAgentContextProjectorSe return ix.get(IAgentContextProjectorService); } + const disposables = new DisposableStore(); const projector = createProjector(disposables); diff --git a/packages/agent-core-v2/test/agent/contextProjector/projector-tool-exchanges.test.ts b/packages/agent-core-v2/test/agent/contextProjector/projector-tool-exchanges.test.ts index fc208f437..ad501f1c0 100644 --- a/packages/agent-core-v2/test/agent/contextProjector/projector-tool-exchanges.test.ts +++ b/packages/agent-core-v2/test/agent/contextProjector/projector-tool-exchanges.test.ts @@ -1,3 +1,12 @@ +/** + * Scenario: context projection rebuilds stored history into provider-valid messages. + * + * Responsibilities: validates tool-exchange repair, strict projection, and + * degraded/full-strip media projections through the public projector contract. + * Wiring: real AgentContextProjectorService with captured log and telemetry + * boundaries. Run: pnpm test -- test/agent/contextProjector/projector-tool-exchanges.test.ts + */ + import { afterEach, beforeEach, describe, expect, it } from 'vitest'; import { SyncDescriptor } from '#/_base/di/descriptors'; @@ -46,6 +55,7 @@ function repairPayloads(warnings: WarningCall[]): Record[] { .map((call) => call.payload as Record); } + const INTERRUPTED = 'Tool result is not available in the current context'; function user(text: string): ContextMessage { @@ -127,7 +137,7 @@ describe('projector tool-exchange normalization', () => { } function projectStrict(history: readonly ContextMessage[]): readonly Message[] { - return projector.project(history, { structure: 'strict' }); + return projector.projectStrict(history); } it('leaves a fully resolved exchange untouched', () => { @@ -646,7 +656,7 @@ describe('projector tool-exchange normalization', () => { }); }); - describe('project with media: degraded policy', () => { + describe('projectMediaDegraded', () => { function imageMessage(url: string): ContextMessage { return { role: 'user', @@ -657,16 +667,13 @@ describe('projector tool-exchange normalization', () => { } it('keeps the two most recent media parts and replaces older ones with markers', () => { - const projected = projector.project( - [ - imageMessage('data:image/png;base64,OLD1'), - user('middle'), - imageMessage('data:image/png;base64,OLD2'), - imageMessage('data:image/png;base64,KEEP1'), - imageMessage('data:image/png;base64,KEEP2'), - ], - { media: 'degraded' }, - ); + const projected = projector.projectMediaDegraded([ + imageMessage('data:image/png;base64,OLD1'), + user('middle'), + imageMessage('data:image/png;base64,OLD2'), + imageMessage('data:image/png;base64,KEEP1'), + imageMessage('data:image/png;base64,KEEP2'), + ]); const urls = projected .flatMap((message) => message.content) @@ -683,16 +690,16 @@ describe('projector tool-exchange normalization', () => { }); it('returns the projected messages untouched when media fits within keep-recent', () => { - const projected = projector.project( - [user('text'), imageMessage('data:image/png;base64,AAAA')], - { media: 'degraded' }, - ); + const projected = projector.projectMediaDegraded([ + user('text'), + imageMessage('data:image/png;base64,AAAA'), + ]); const allParts = projected.flatMap((message) => message.content); expect(allParts.some((part) => part.type === 'image_url')).toBe(true); }); }); - describe('project with media: stripped policy', () => { + describe('projectMediaStripped', () => { function imageMessage(url: string, id?: string): ContextMessage { return { role: 'user', @@ -702,15 +709,8 @@ describe('projector tool-exchange normalization', () => { }; } - function projectStripped( - history: readonly ContextMessage[], - snapshot = projector.captureMediaStripSnapshot(history), - ): readonly Message[] { - return projector.project(history, { media: { strip: snapshot } }); - } - it('replaces every media part with a text marker, keeping the surrounding text', () => { - const projected = projectStripped([ + const projected = projector.projectMediaStripped([ user('look at these'), imageMessage('data:image/png;base64,AAAA'), { @@ -742,7 +742,7 @@ describe('projector tool-exchange normalization', () => { }); it('returns the projected messages untouched when there is no media', () => { - const projected = projectStripped([user('just text')]); + const projected = projector.projectMediaStripped([user('just text')]); expect(projected).toEqual(project([user('just text')])); }); @@ -750,7 +750,7 @@ describe('projector tool-exchange normalization', () => { const rejected = imageMessage('data:image/png;base64,OLD', 'old-id'); const snapshot = projector.captureMediaStripSnapshot([rejected]); - const projected = projectStripped( + const projected = projector.projectMediaStripped( [rejected, imageMessage('data:image/png;base64,NEW', 'new-id')], snapshot, ); @@ -776,7 +776,7 @@ describe('projector tool-exchange normalization', () => { orphan, ]); - const projected = projectStripped( + const projected = projector.projectMediaStripped( [imageMessage(url, 'orphan-id')], snapshot, ); @@ -793,7 +793,7 @@ describe('projector tool-exchange normalization', () => { imageMessage('data:image/png;base64,SAME', 'same-id'), ]); - const projected = projectStripped( + const projected = projector.projectMediaStripped( [imageMessage('data:image/png;base64,SAME', 'same-id')], snapshot, ); @@ -809,7 +809,7 @@ describe('projector tool-exchange normalization', () => { const url = 'https://example.test/media/image.png'; const snapshot = projector.captureMediaStripSnapshot([imageMessage(url, 'old-id')]); - const projected = projectStripped( + const projected = projector.projectMediaStripped( [imageMessage(url, 'new-id')], snapshot, ); diff --git a/packages/agent-core-v2/test/features/dateChange/dateChangeInjection.test.ts b/packages/agent-core-v2/test/agent/dateChange/dateChangeInjection.test.ts similarity index 77% rename from packages/agent-core-v2/test/features/dateChange/dateChangeInjection.test.ts rename to packages/agent-core-v2/test/agent/dateChange/dateChangeInjection.test.ts index cd67f0312..ff52f3c73 100644 --- a/packages/agent-core-v2/test/features/dateChange/dateChangeInjection.test.ts +++ b/packages/agent-core-v2/test/agent/dateChange/dateChangeInjection.test.ts @@ -1,3 +1,14 @@ +/** + * Scenario: `date_change` context injection announces calendar-date changes. + * + * Exercises the real provider through the harness injector with `hostClock` + * stubbed at the host boundary: baselines come from typed reminder metadata, + * then the persisted rendered-date snapshot, then a runtime seed recorded on + * first observation for prompts that never disclose a date. Run: `pnpm --filter + * @moonshot-ai/agent-core-v2 exec vitest run + * test/agent/dateChange/dateChangeInjection.test.ts`. + */ + import { mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'pathe'; @@ -12,10 +23,6 @@ import { DEFAULT_AGENT_PROFILE_NAME, type EnvironmentDisclosureSnapshot, } from '#/app/agentProfileCatalog/agentProfileCatalog'; -import { - AgentDateChange, - DateChangeRuntime, -} from '#/features/dateChange/dateChangeAgentRuntime'; import { IHostClock } from '#/os/interface/hostClock'; import { ISessionContext } from '#/session/sessionContext/sessionContext'; @@ -26,7 +33,7 @@ import { InMemoryWireRecordPersistence, type TestAgentContext, } from '../../harness'; -import { runWillBeginStepHooks } from '../../agent/loop/stubs'; +import { runWillBeginStepHooks } from '../loop/stubs'; const TEST_TIME_ZONE = 'Asia/Shanghai'; const INITIAL_INSTANT = '2026-07-29T04:00:00.000Z'; @@ -100,20 +107,19 @@ function messageText(message: ContextMessage): string { .join(''); } -describe('dateChangeAgentRuntime', () => { +describe('AgentDateChangeService', () => { let ctx: TestAgentContext; let context: IAgentContextMemoryService; let clock: TestHostClock; let loop: IAgentLoopService; let profile: IAgentProfileService; - beforeEach(async () => { + beforeEach(() => { clock = testHostClock(INITIAL_INSTANT); ctx = createTestAgent(appService(IHostClock, clock)); context = ctx.get(IAgentContextMemoryService); loop = ctx.get(IAgentLoopService); profile = ctx.get(IAgentProfileService); - await ctx.restoreRuntimes(); }); afterEach(async () => { @@ -152,7 +158,9 @@ describe('dateChangeAgentRuntime', () => { const first = reminders[0]; expect(first).toBeDefined(); const text = messageText(first as ContextMessage); - expect(text).toContain('2026-07-29'); + expect(text).toContain("Today's date is now 2026-07-29"); + expect(text).toContain('stale'); + expect(text).toContain('DO NOT mention this to the user explicitly'); expect(first?.origin).toMatchObject({ kind: 'injection', variant: 'date_change', @@ -182,14 +190,18 @@ describe('dateChangeAgentRuntime', () => { let reminders = dateReminders(context); expect(reminders).toHaveLength(1); - expect(messageText(reminders[0] as ContextMessage)).toContain('2026-07-30'); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-30", + ); clock.set('2026-07-31T04:00:00.000Z'); await runWillBeginStepHooks(loop); reminders = dateReminders(context); expect(reminders).toHaveLength(2); - expect(messageText(reminders[1] as ContextMessage)).toContain('2026-07-31'); + expect(messageText(reminders[1] as ContextMessage)).toContain( + "Today's date is now 2026-07-31", + ); expect(reminders[1]?.origin).toMatchObject({ disclosure: { kind: 'date', @@ -221,16 +233,17 @@ describe('dateChangeAgentRuntime', () => { context = ctx.get(IAgentContextMemoryService); loop = ctx.get(IAgentLoopService); await ctx.restorePersisted(); - await ctx.restoreRuntimes(); await runWillBeginStepHooks(loop); const reminders = dateReminders(context); expect(reminders).toHaveLength(1); - expect(messageText(reminders[0] as ContextMessage)).toContain('2026-07-30'); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-30", + ); }); - it('discloses the current date after resuming a legacy profile without disclosure metadata', async () => { + it('seeds and announces after resuming a legacy profile without disclosure metadata', async () => { const persistence = new InMemoryWireRecordPersistence(); await ctx.dispose(); ctx = createTestAgent({ persistence }, appService(IHostClock, clock)); @@ -255,18 +268,17 @@ describe('dateChangeAgentRuntime', () => { context = ctx.get(IAgentContextMemoryService); loop = ctx.get(IAgentLoopService); await ctx.restorePersisted(); - await ctx.restoreRuntimes(); await runWillBeginStepHooks(loop); - const initial = dateReminders(context); - expect(initial).toHaveLength(1); - expect(messageText(initial[0] as ContextMessage)).toContain('2026-07-30'); + expect(dateReminders(context)).toHaveLength(0); clock.set('2026-07-31T04:00:00.000Z'); await runWillBeginStepHooks(loop); const reminders = dateReminders(context); - expect(reminders).toHaveLength(2); - expect(messageText(reminders[1] as ContextMessage)).toContain('2026-07-31'); + expect(reminders).toHaveLength(1); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-31", + ); }); it('announces a crossed midnight through a real bind rendered from the host clock', async () => { @@ -277,21 +289,20 @@ describe('dateChangeAgentRuntime', () => { context = ctx.get(IAgentContextMemoryService); loop = ctx.get(IAgentLoopService); profile = ctx.get(IAgentProfileService); - await ctx.restorePersisted(); await profile.bind({ profile: DEFAULT_AGENT_PROFILE_NAME, model: 'mock-model' }); await runWillBeginStepHooks(loop); - const initial = dateReminders(context); - expect(initial).toHaveLength(1); - expect(messageText(initial[0] as ContextMessage)).toContain('2026-07-29'); + expect(dateReminders(context)).toHaveLength(0); clock.set('2026-07-30T04:00:00.000Z'); await runWillBeginStepHooks(loop); const reminders = dateReminders(context); - expect(reminders).toHaveLength(2); - expect(messageText(reminders[1] as ContextMessage)).toContain('2026-07-30'); + expect(reminders).toHaveLength(1); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-30", + ); } finally { await rm(homeDir, { recursive: true, force: true }); } @@ -363,70 +374,31 @@ describe('dateChangeAgentRuntime', () => { expect(dateReminders(context)).toHaveLength(1); }); - it('re-discloses after undo removes the initial disclosure', async () => { + it('adopts today silently when the system prompt carries no date line', async () => { updateSystemPromptWithoutDate(profile, ctx.get(ISessionContext).cwd); - context.append({ - role: 'user', - content: [{ type: 'text', text: 'first turn' }], - toolCalls: [], - origin: { kind: 'user' }, - }); - await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(1); - expect(context.undo(1)).toMatchObject({ removedCount: 1 }); + await runWillBeginStepHooks(loop); + expect(dateReminders(context)).toHaveLength(0); - context.append({ - role: 'user', - content: [{ type: 'text', text: 'replacement turn' }], - toolCalls: [], - origin: { kind: 'user' }, - }); - - await runWillBeginStepHooks(loop); - - const reminders = dateReminders(context); - expect(reminders).toHaveLength(1); - expect(messageText(reminders[0] as ContextMessage)).toContain('2026-07-29'); + expect(context.get()).toHaveLength(0); }); - it('discloses the current date on the first step when the system prompt carries no date', async () => { - updateSystemPromptWithoutDate(profile, ctx.get(ISessionContext).cwd); - - await runWillBeginStepHooks(loop); - - const reminders = dateReminders(context); - expect(reminders).toHaveLength(1); - expect(messageText(reminders[0] as ContextMessage)).toContain('2026-07-29'); - expect(reminders[0]?.origin).toMatchObject({ - kind: 'injection', - variant: 'date_change', - disclosure: { - kind: 'date', - renderGeneration: 2, - localDate: '2026-07-29', - timeZone: TEST_TIME_ZONE, - }, - }); - - await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(1); - }); - - it('announces a crossed midnight after the initial disclosure', async () => { + it('announces a crossed midnight after the silent seed', async () => { updateSystemPromptWithoutDate(profile, ctx.get(ISessionContext).cwd); await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(1); + expect(dateReminders(context)).toHaveLength(0); clock.set('2026-07-30T04:00:00.000Z'); await runWillBeginStepHooks(loop); const reminders = dateReminders(context); - expect(reminders).toHaveLength(2); - expect(messageText(reminders[1] as ContextMessage)).toContain('2026-07-30'); + expect(reminders).toHaveLength(1); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-30", + ); await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(2); + expect(dateReminders(context)).toHaveLength(1); }); it('treats an empty snapshot cwd as unknown and uses the disclosed date as baseline', async () => { @@ -436,20 +408,24 @@ describe('dateChangeAgentRuntime', () => { const reminders = dateReminders(context); expect(reminders).toHaveLength(1); - expect(messageText(reminders[0] as ContextMessage)).toContain('2026-07-29'); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-29", + ); }); - it('discloses then announces when the snapshot cwd is empty and no date is disclosed', async () => { + it('seeds quietly then announces when the snapshot cwd is empty and no date is disclosed', async () => { updateSystemPromptWithoutDate(profile, ''); await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(1); + expect(dateReminders(context)).toHaveLength(0); clock.set('2026-07-30T04:00:00.000Z'); await runWillBeginStepHooks(loop); const reminders = dateReminders(context); - expect(reminders).toHaveLength(2); - expect(messageText(reminders[1] as ContextMessage)).toContain('2026-07-30'); + expect(reminders).toHaveLength(1); + expect(messageText(reminders[0] as ContextMessage)).toContain( + "Today's date is now 2026-07-30", + ); }); it('never injects when the snapshot belongs to a different cwd', async () => { @@ -467,19 +443,4 @@ describe('dateChangeAgentRuntime', () => { await runWillBeginStepHooks(loop); expect(dateReminders(context)).toHaveLength(0); }); - - it('keeps one provider registration across repeated runtime restore', async () => { - updateSystemPromptWithoutDate(profile, ctx.get(ISessionContext).cwd); - - expect(ctx.resolve(AgentDateChange)).toBeInstanceOf(DateChangeRuntime); - await runWillBeginStepHooks(loop); - expect(dateReminders(context)).toHaveLength(1); - - await ctx.restoreRuntimes(); - await ctx.restoreRuntimes(); - clock.set('2026-07-30T04:00:00.000Z'); - await runWillBeginStepHooks(loop); - - expect(dateReminders(context)).toHaveLength(2); - }); }); diff --git a/packages/agent-core-v2/test/features/externalHooks/runner-stub.ts b/packages/agent-core-v2/test/agent/externalHooks/runner-stub.ts similarity index 63% rename from packages/agent-core-v2/test/features/externalHooks/runner-stub.ts rename to packages/agent-core-v2/test/agent/externalHooks/runner-stub.ts index cc4599a52..f2052b52b 100644 --- a/packages/agent-core-v2/test/features/externalHooks/runner-stub.ts +++ b/packages/agent-core-v2/test/agent/externalHooks/runner-stub.ts @@ -1,7 +1,19 @@ +/** + * `externalHooks` test helper — build a real `IExternalHooksRunnerService` + * from a list of hook definitions. + * + * The runner is App-scoped in production; in tests we construct it directly + * (its constructor params are the App services it reads plus the host process + * service) with stub `IConfigService` / `IPluginService` / `IBootstrapService` + * and a real `HostProcessService`. This keeps the matching / dedupe / + * stdin-payload behavior under test identical to production while letting a + * test feed an arbitrary hook list. + */ + import { Event } from '#/_base/event'; -import { ExternalHooksRunnerService } from '#/features/externalHooks/app/externalHooksRunnerService'; -import { HOOKS_SECTION } from '#/features/externalHooks/configSection'; -import type { HookDef } from '#/features/externalHooks/internal/types'; +import { ExternalHooksRunnerService } from '#/app/externalHooksRunner/externalHooksRunnerService'; +import { HOOKS_SECTION } from '#/agent/externalHooks/configSection'; +import type { HookDef } from '#/agent/externalHooks/types'; import { IBootstrapService } from '#/app/bootstrap/bootstrap'; import { IConfigService } from '#/app/config/config'; import { IPluginService } from '#/app/plugin/plugin'; diff --git a/packages/agent-core-v2/test/features/externalHooks/runner.test.ts b/packages/agent-core-v2/test/agent/externalHooks/runner.test.ts similarity index 98% rename from packages/agent-core-v2/test/features/externalHooks/runner.test.ts rename to packages/agent-core-v2/test/agent/externalHooks/runner.test.ts index 58c029cff..853ff1076 100644 --- a/packages/agent-core-v2/test/features/externalHooks/runner.test.ts +++ b/packages/agent-core-v2/test/agent/externalHooks/runner.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it } from 'vitest'; -import { buildHookSpawnOptions, runHook } from '#/features/externalHooks/internal/runHook'; +import { buildHookSpawnOptions, runHook } from '#/agent/externalHooks/runner'; import { HostProcessService } from '#/os/backends/node-local/hostProcessService'; const hostProcess = new HostProcessService(); diff --git a/packages/agent-core-v2/test/agent/fullCompaction/compactionOps.test.ts b/packages/agent-core-v2/test/agent/fullCompaction/compactionOps.test.ts index 73e2a3992..167d5d656 100644 --- a/packages/agent-core-v2/test/agent/fullCompaction/compactionOps.test.ts +++ b/packages/agent-core-v2/test/agent/fullCompaction/compactionOps.test.ts @@ -6,70 +6,50 @@ import { TestInstantiationService } from '#/_base/di/test'; import { IEventBus } from '#/app/event/eventBus'; import { EventBusService } from '#/app/event/eventBusService'; import { - fullCompactionKey, - FullCompactionBegin, - FullCompactionCancel, - FullCompactionComplete, + CompactionModel, + fullCompactionBegin, + fullCompactionCancel, + fullCompactionComplete, } from '#/agent/fullCompaction/compactionOps'; import { AppendLogStore } from '#/persistence/backends/node-fs/appendLogStore'; import { InMemoryStorageService } from '#/persistence/backends/memory/inMemoryStorageService'; import { IAppendLogStore } from '#/persistence/interface/appendLogStore'; import { IFileSystemStorageService } from '#/persistence/interface/storage'; -import { IAgentStateService } from '#/agent/state/agentState'; -import { IEventDispatcher } from '#/state/eventDispatcher'; +import { IWireService } from '#/wire/wire'; import { AGENT_WIRE_RECORD_KEY, type WireRecord } from '#/wire/record'; -import { - registerTestAgentWire, - registerTestEventDispatcher, - restoreTestEventDispatcher, - testWireScope, -} from '../../wire/stubs'; +import { registerTestAgentWire, restoreTestAgentWire, testWireScope } from '../../wire/stubs'; const SCOPE = 'wire'; const KEY = 'full-compaction-test'; let disposables: DisposableStore; -let dispatcher: IEventDispatcher; -let agentState: IAgentStateService; +let wire: IWireService; let log: IAppendLogStore; -function buildHost(key: string): { - dispatcher: IEventDispatcher; - agentState: IAgentStateService; - log: IAppendLogStore; - eventBus: IEventBus; -} { +function buildHost(key: string): { wire: IWireService; log: IAppendLogStore; eventBus: IEventBus } { const ix = disposables.add(new TestInstantiationService()); ix.stub(IFileSystemStorageService, new InMemoryStorageService()); ix.set(IAppendLogStore, new SyncDescriptor(AppendLogStore)); ix.set(IEventBus, new SyncDescriptor(EventBusService)); - registerTestAgentWire(ix, testWireScope(SCOPE, key), { + const wire = registerTestAgentWire(ix, testWireScope(SCOPE, key), { log: ix.get(IAppendLogStore), eventBus: ix.get(IEventBus), }); - const dispatcher = registerTestEventDispatcher(ix); - ix.get(IAgentStateService).contributeState(fullCompactionKey); - return { - dispatcher, - agentState: ix.get(IAgentStateService), - log: ix.get(IAppendLogStore), - eventBus: ix.get(IEventBus), - }; + return { wire, log: ix.get(IAppendLogStore), eventBus: ix.get(IEventBus) }; } beforeEach(() => { disposables = new DisposableStore(); const host = buildHost(KEY); - dispatcher = host.dispatcher; - agentState = host.agentState; + wire = host.wire; log = host.log; }); afterEach(() => disposables.dispose()); async function readRecords(key = KEY): Promise { - await dispatcher.flush(); + await wire.flush(); const out: WireRecord[] = []; for await (const record of log.read(testWireScope(SCOPE, key), AGENT_WIRE_RECORD_KEY)) { out.push(record); @@ -79,18 +59,18 @@ async function readRecords(key = KEY): Promise { describe('fullCompaction ops (wire-backed)', () => { it('begin/complete/cancel drive the phase and persist flat records', async () => { - expect(agentState.get(fullCompactionKey).phase).toBe('idle'); + expect(wire.getModel(CompactionModel).phase).toBe('idle'); - void dispatcher.dispatch(new FullCompactionBegin({ agentId: 'test-agent', source: 'manual', instruction: 'keep facts' })); - expect(agentState.get(fullCompactionKey).phase).toBe('running'); + wire.dispatch(fullCompactionBegin({ source: 'manual', instruction: 'keep facts' })); + expect(wire.getModel(CompactionModel).phase).toBe('running'); - void dispatcher.dispatch(new FullCompactionComplete({ agentId: 'test-agent' })); - expect(agentState.get(fullCompactionKey).phase).toBe('idle'); + wire.dispatch(fullCompactionComplete({})); + expect(wire.getModel(CompactionModel).phase).toBe('idle'); - void dispatcher.dispatch(new FullCompactionBegin({ agentId: 'test-agent', source: 'auto' })); - expect(agentState.get(fullCompactionKey).phase).toBe('running'); - void dispatcher.dispatch(new FullCompactionCancel({ agentId: 'test-agent' })); - expect(agentState.get(fullCompactionKey).phase).toBe('idle'); + wire.dispatch(fullCompactionBegin({ source: 'auto' })); + expect(wire.getModel(CompactionModel).phase).toBe('running'); + wire.dispatch(fullCompactionCancel({})); + expect(wire.getModel(CompactionModel).phase).toBe('idle'); const records = await readRecords(); expect(records.map((record) => record.type)).toEqual([ @@ -107,28 +87,24 @@ describe('fullCompaction ops (wire-backed)', () => { instruction: 'keep facts', }), ); - expect(records[1]).toEqual({ - type: 'full_compaction.complete', - agentId: 'test-agent', - time: expect.any(Number), - }); + expect(records[1]).toEqual({ type: 'full_compaction.complete', time: expect.any(Number) }); }); - it('fold keeps the same reference on a no-op (state stays quiet)', () => { - void dispatcher.dispatch(new FullCompactionCancel({ agentId: 'test-agent' })); - const idle = agentState.get(fullCompactionKey); - void dispatcher.dispatch(new FullCompactionCancel({ agentId: 'test-agent' })); - expect(agentState.get(fullCompactionKey)).toBe(idle); + it('apply returns the same reference on a no-op (gate stays quiet)', () => { + wire.dispatch(fullCompactionCancel({})); + const idle = wire.getModel(CompactionModel); + wire.dispatch(fullCompactionCancel({})); + expect(wire.getModel(CompactionModel)).toBe(idle); - void dispatcher.dispatch(new FullCompactionBegin({ agentId: 'test-agent', source: 'manual' })); - const running = agentState.get(fullCompactionKey); - void dispatcher.dispatch(new FullCompactionBegin({ agentId: 'test-agent', source: 'auto' })); - expect(agentState.get(fullCompactionKey)).toBe(running); + wire.dispatch(fullCompactionBegin({ source: 'manual' })); + const running = wire.getModel(CompactionModel); + wire.dispatch(fullCompactionBegin({ source: 'auto' })); + expect(wire.getModel(CompactionModel)).toBe(running); }); it('replay rebuilds the phase silently', async () => { - void dispatcher.dispatch(new FullCompactionBegin({ agentId: 'test-agent', source: 'manual' })); - void dispatcher.dispatch(new FullCompactionComplete({ agentId: 'test-agent' })); + wire.dispatch(fullCompactionBegin({ source: 'manual' })); + wire.dispatch(fullCompactionComplete({})); const records = await readRecords(); const host = buildHost('full-compaction-replay'); @@ -136,30 +112,30 @@ describe('fullCompaction ops (wire-backed)', () => { host.eventBus.subscribe((e) => { emissions.push(e.type); }); - await restoreTestEventDispatcher( - host.dispatcher, + await restoreTestAgentWire( + host.wire, host.log, testWireScope(SCOPE, 'full-compaction-replay'), records, ); - expect(host.agentState.get(fullCompactionKey).phase).toBe('idle'); + expect(host.wire.getModel(CompactionModel).phase).toBe('idle'); expect(emissions).toEqual([]); const stranded = buildHost('full-compaction-stranded'); - await restoreTestEventDispatcher( - stranded.dispatcher, + await restoreTestAgentWire( + stranded.wire, stranded.log, testWireScope(SCOPE, 'full-compaction-stranded'), [{ type: 'full_compaction.begin', source: 'auto' }], ); - expect(stranded.agentState.get(fullCompactionKey).phase).toBe('running'); + expect(stranded.wire.getModel(CompactionModel).phase).toBe('running'); }); it('replays legacy complete payloads that carried accounting numbers', async () => { const host = buildHost('full-compaction-legacy-complete-replay'); - await restoreTestEventDispatcher( - host.dispatcher, + await restoreTestAgentWire( + host.wire, host.log, testWireScope(SCOPE, 'full-compaction-legacy-complete-replay'), [ @@ -168,6 +144,6 @@ describe('fullCompaction ops (wire-backed)', () => { ], ); - expect(host.agentState.get(fullCompactionKey).phase).toBe('idle'); + expect(host.wire.getModel(CompactionModel).phase).toBe('idle'); }); }); diff --git a/packages/agent-core-v2/test/agent/fullCompaction/fullCompaction.test.ts b/packages/agent-core-v2/test/agent/fullCompaction/fullCompaction.test.ts index 5861b13a2..69e844bbc 100644 --- a/packages/agent-core-v2/test/agent/fullCompaction/fullCompaction.test.ts +++ b/packages/agent-core-v2/test/agent/fullCompaction/fullCompaction.test.ts @@ -1,3 +1,15 @@ +/** + * Scenario: full compaction refreshes, retries, and resumes agent context under + * context-window pressure. + * + * Responsibilities: assert manual and automatic compaction outcomes, overflow + * recovery, resume compatibility, dynamic tool context handling, and emitted + * wire/telemetry effects. Wiring: testAgent harness with fake providers, + * filesystem sandboxes, real compaction services, and stubs at external model / + * telemetry boundaries. Run: + * ../../node_modules/.bin/vitest run test/fullCompaction/full.test.ts + */ + import { existsSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs'; import { tmpdir } from 'node:os'; import { join } from 'pathe'; @@ -18,19 +30,20 @@ import { DefaultCompactionStrategy, } from '#/agent/fullCompaction/strategy'; import { COMPACTION_SUMMARY_PREFIX } from '#/agent/contextMemory/compactionHandoff'; -import { makeHookRunner } from '../../features/externalHooks/runner-stub'; -import type { IExternalHooksRunnerService } from '#/features/externalHooks/app/externalHooksRunner'; +import { makeHookRunner } from '../externalHooks/runner-stub'; +import type { IExternalHooksRunnerService } from '#/app/externalHooksRunner/externalHooksRunner'; import { MASTER_ENV } from '#/app/flag/flagService'; import { estimateTokensForMessages } from '#/kosong/contract/tokens'; import { recordingTelemetry, type TelemetryRecord } from '../../app/telemetry/stubs'; import type { TestAgentContext, TestAgentOptions, TestAgentServiceOverride } from '../../harness'; -import { agentService, appServices, createCommandRunner, execEnvServices, hostEnvironmentServices, sessionServices, testAgent as createTestAgent } from '../../harness'; +import { agentService, appServices, createCommandRunner, execEnvServices, hostEnvironmentServices, sessionServices, testAgent } from '../../harness'; import { IAgentToolSelectAnnouncementsService } from '#/agent/toolSelect/toolSelectAnnouncements'; import { IAgentFullCompactionService, IModelOAuthTokens, IAgentProfileService, IAgentToolRegistryService, + ISessionTodoService, DYNAMIC_TOOL_SCHEMA_VARIANT, normalizeAgentProfile, type ExecutableTool, @@ -38,21 +51,13 @@ import { type ToolExecution, } from '#/index'; import { IAgentLoopService } from '#/agent/loop/loop'; -import { AgentTodo } from '#/features/todo/todoAgentRuntime'; -import { AgentGoal } from '#/features/goal/goalAgentRuntime'; +import { IAgentTokenCountingService } from '#/agent/tokenCounting/tokenCounting'; +import { IAgentGoalService } from '#/agent/goal/goal'; import { IAgentTelemetryContextService } from '#/app/telemetry/agentTelemetryContext'; import { HostFileSystem } from '#/os/backends/node-local/hostFsService'; type GenerateFn = NonNullable; -function testAgent( - ...inputs: readonly (TestAgentServiceOverride | TestAgentOptions)[] -): TestAgentContext { - const context = createTestAgent(...inputs); - void context.restoreRuntimes(); - return context; -} - const CATALOGUED_PROVIDER = { type: 'kimi', apiKey: 'test-key', @@ -77,7 +82,7 @@ const SNAPSHOT_VISIBLE_TOOLS = [ 'ExitPlanMode', ] as const; const LARGE_MCP_TOOL = 'mcp__srv__large'; -const EXACT_COMPACTION_PROFILE: ResolvedAgentProfile = normalizeAgentProfile({ +const EXACT_COMPACTION_REFRESH_PROFILE: ResolvedAgentProfile = normalizeAgentProfile({ name: 'exact-compaction-refresh', systemPrompt: (context) => [ @@ -267,10 +272,10 @@ describe('FullCompaction', () => { const candidate = event as { type?: unknown; event?: unknown }; return candidate.type === '[wire]' && candidate.event === 'full_compaction.complete'; }); - expect(completeEvent?.args).toEqual({ agentId: 'main', time: '